summaryrefslogtreecommitdiffstats
path: root/tqtinterface/qt4/src
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:17:53 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2011-07-10 15:17:53 -0500
commitdda8474928bd7276e1fad8fb7a601e7c83ff2bc2 (patch)
tree7f83910598b33b12730035f086df20b5a53ab99c /tqtinterface/qt4/src
parent6260b6178868c03aab1644bf93b0ef043654bdb0 (diff)
downloadexperimental-dda8474928bd7276e1fad8fb7a601e7c83ff2bc2.tar.gz
experimental-dda8474928bd7276e1fad8fb7a601e7c83ff2bc2.zip
Added TQt4 HEAD
Diffstat (limited to 'tqtinterface/qt4/src')
-rw-r--r--tqtinterface/qt4/src/.obj/README1
-rw-r--r--tqtinterface/qt4/src/.tmp/README1
-rw-r--r--tqtinterface/qt4/src/3rdparty/README17
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/README385
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/change.log217
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/coderules.doc118
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/filelist.doc210
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/install.doc1063
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcapimin.c280
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcapistd.c161
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jccoefct.c449
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jccolor.c459
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcdctmgr.c387
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jchuff.c909
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jchuff.h47
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcinit.c72
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcmainct.c293
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcmarker.c664
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcmaster.c590
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcomapi.c106
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.bcc48
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.cfg44
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.dj38
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.doc155
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.h47
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.mac43
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.manx43
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.mc652
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.sas43
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.st42
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.vc45
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.vms37
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.wat38
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcparam.c610
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcphuff.c833
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcprepct.c354
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jcsample.c519
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jctrans.c388
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdapimin.c395
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdapistd.c275
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdatadst.c151
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdatasrc.c212
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdcoefct.c736
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdcolor.c396
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdct.h176
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jddctmgr.c269
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdhuff.c651
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdhuff.h201
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdinput.c381
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdmainct.c512
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdmarker.c1360
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdmaster.c557
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdmerge.c400
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdphuff.c668
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdpostct.c290
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdsample.c478
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jdtrans.c143
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jerror.c252
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jerror.h291
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jfdctflt.c168
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jfdctfst.c224
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jfdctint.c283
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jidctflt.c242
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jidctfst.c368
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jidctint.c389
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jidctred.c398
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jinclude.h91
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jmemmgr.c1118
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jmemnobs.c109
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jmemsys.h198
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jmorecfg.h363
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jpegint.h392
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jpeglib.h1096
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jquant1.c856
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jquant2.c1310
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jutils.c179
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/jversion.h14
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/libjpeg.doc3006
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.ansi214
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.bcc285
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.cfg319
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.dj220
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.manx214
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.mc6249
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.mms218
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.sas252
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.unix228
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.vc210
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.vms142
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/makefile.wat233
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/structure.doc948
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/usage.doc562
-rw-r--r--tqtinterface/qt4/src/3rdparty/libjpeg/wizard.doc211
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/Changes867
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/LICENSE56
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/Makefile.am27
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/Makefile.in403
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/README25
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/README.autoconf195
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/README.config104
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/README.contrib79
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/README.dll41
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/README.examples43
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/README.packaging24
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/acinclude.m474
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/aclocal.m43806
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/libmng/autogen.sh34
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/libmng/config.guess1317
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/libmng/config.sub1411
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/libmng/configure6901
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/configure.in177
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/doc/Plan1.pngbin0 -> 9058 bytes
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/doc/Plan2.pngbin0 -> 8849 bytes
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/doc/doc.readme19
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/doc/libmng.txt1107
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/doc/man/jng.537
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/doc/man/libmng.31147
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/doc/man/mng.542
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/doc/rpm/libmng-1.0.4-rhconf.patch38
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/doc/rpm/libmng.spec97
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/libmng/install-sh251
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng.h2515
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_callback_xs.c1147
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_io.c8817
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_io.h295
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_prc.c2102
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_prc.h168
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_xs.c5119
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_chunks.h759
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_cms.c928
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_cms.h80
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_conf.h224
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_data.h768
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_display.c4699
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_display.h195
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_dither.c54
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_dither.h44
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_error.c271
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_error.h109
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_filter.c890
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_filter.h71
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_hlapi.c1814
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_jpeg.c1066
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_jpeg.h59
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_memory.h66
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_object_prc.c3828
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_object_prc.h432
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_objects.h509
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_pixels.c10845
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_pixels.h570
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_prop_xs.c2357
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_read.c696
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_read.h45
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_trace.c1174
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_trace.h1215
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_types.h497
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_write.c139
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_write.h43
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_zlib.c451
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/libmng_zlib.h62
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/ltmain.sh4988
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/makefiles/Makefile.am27
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/makefiles/README25
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/makefiles/acinclude.m474
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/makefiles/configure.in177
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.bcb3105
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.dj151
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.linux176
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.mingw160
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.unix66
-rw-r--r--tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.vcwin3296
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/libmng/missing198
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/libmng/mkinstalldirs40
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/ANNOUNCE29
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/CHANGES1184
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/INSTALL151
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/KNOWNBUG11
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/LICENSE102
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/README269
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/README.trolltech15
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/TODO24
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/Y2KINFO55
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/libpng/configure6
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/example.c804
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/libpng.33958
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/libpng.txt2905
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/libpngpf.3552
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/png.560
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/png.c805
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/png.h3289
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngasmrd.h11
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngbar.jpgbin0 -> 2498 bytes
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngbar.pngbin0 -> 2443 bytes
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngconf.h1364
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngerror.c301
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pnggccrd.c5397
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngget.c927
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngmem.c566
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngnow.pngbin0 -> 2062 bytes
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngpread.c1547
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngread.c1418
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngrio.c161
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngrtran.c4175
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngrutil.c3119
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngset.c1162
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngtest.c1541
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngtest.pngbin0 -> 5269 bytes
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngtrans.c640
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngvcrd.c3845
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngwio.c228
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngwrite.c1450
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngwtran.c563
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/pngwutil.c2694
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-shared.projbin0 -> 17031 bytes
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-shared.txt22
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-static.projbin0 -> 16706 bytes
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-static.txt22
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpf22
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpg25
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpr157
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.cpp29
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.readme.txt19
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpngstat.bpf22
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpngstat.bpr109
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib+libpng.bpg33
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpf20
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpg25
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpr147
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.cpp30
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlibstat.bpf20
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlibstat.bpr131
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/README.txt57
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/libpng.dsp439
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/libpng.dsw44
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/png.rc100
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/png32ms.def220
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/zlib.def45
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/zlib.dsp441
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/netware.txt6
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/projects/wince.txt6
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/SCOPTIONS.ppc7
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/descrip.mms52
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/libpng/scripts/libpng-config-body.in96
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/libpng/scripts/libpng-config-head.in21
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng.icc44
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng.pc.in11
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.32sunu224
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.64sunu224
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.acorn51
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.aix104
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.amiga48
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.atari51
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bc32151
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bd3276
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.beos199
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bor162
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.cygwin305
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.darwin205
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.dec185
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.dj255
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.freebsd48
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.gcc66
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.gcmmx249
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.hpgcc217
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.hpux202
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ibmc71
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.intel114
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.knr99
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.linux223
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.macosx197
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.mips83
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.msc86
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ne10bsd44
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ne12bsd44
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.netbsd44
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.openbsd72
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.os269
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sco201
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sggcc211
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sgi217
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.so9223
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.solaris220
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.std89
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sunos93
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.tc389
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.vcawin3294
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.vcwin3287
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.watcom109
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/makevms.com144
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/pngdef.pas795
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/pngos2.def241
-rw-r--r--tqtinterface/qt4/src/3rdparty/libpng/scripts/smakefile.ppc30
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/FT-license.txt28
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/FTL.TXT174
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/README17
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftglue.c349
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftglue.h162
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftxgdef.c1224
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftxgdef.h224
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftxgpos.c6196
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftxgpos.h838
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftxgsub.c4156
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftxgsub.h575
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftxopen.c1541
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftxopen.h317
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftxopenf.h163
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/ftxopentype.c14
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/otlbuffer.c235
-rw-r--r--tqtinterface/qt4/src/3rdparty/opentype/otlbuffer.h129
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/attach.c308
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/auth.c219
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/btree.c3579
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/btree.h156
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/btree_rb.c1488
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/build.c2157
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/config.h23
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/copy.c110
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/date.c873
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/delete.c393
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/expr.c1656
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/func.c646
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/hash.c356
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/hash.h109
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/insert.c919
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/main.c1136
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/opcodes.c138
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/opcodes.h136
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/os.c1818
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/os.h192
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/pager.c2220
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/pager.h107
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/parse.c4035
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/parse.h130
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/pragma.c699
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/printf.c855
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/random.c97
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/select.c2404
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/shell.c1350
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/sqlite.h834
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/sqliteInt.h1266
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/table.c203
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/tokenize.c679
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/trigger.c764
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/trolltech.patch39
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/update.c452
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/util.c1135
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/vacuum.c320
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/vdbe.c4885
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/vdbe.h112
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/vdbeInt.h303
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/vdbeaux.c1061
-rw-r--r--tqtinterface/qt4/src/3rdparty/sqlite/where.c1204
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/ChangeLog764
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/FAQ337
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/INDEX51
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/Makefile.in154
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/README126
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/adler32.c74
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/algorithm.txt209
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/compress.c79
-rwxr-xr-xtqtinterface/qt4/src/3rdparty/zlib/configure443
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/crc32.c333
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/crc32.h441
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/deflate.c1502
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/deflate.h325
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/example.c567
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/gzio.c1009
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/infback.c622
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/inffast.c305
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/inffast.h11
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/inffixed.h94
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/inflate.c1274
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/inflate.h117
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/inftrees.c328
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/inftrees.h55
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/minigzip.c322
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/projects/README.projects38
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/README.txt38
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/example.dsp278
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/minigzip.dsp278
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/zlib.dsp609
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/zlib.dsw59
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/trees.c1215
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/trees.h128
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/uncompr.c61
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/win32/DLL_FAQ.txt370
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.bor107
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.emx69
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.gcc141
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.msc126
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/win32/VisualC.txt3
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/win32/zlib.def60
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/win32/zlib1.rc39
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/zconf.h326
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/zconf.in.h326
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/zlib.3159
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/zlib.h1213
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/zutil.c319
-rw-r--r--tqtinterface/qt4/src/3rdparty/zlib/zutil.h263
-rw-r--r--tqtinterface/qt4/src/attic/README6
-rw-r--r--tqtinterface/qt4/src/attic/qtmultilineedit.cpp4236
-rw-r--r--tqtinterface/qt4/src/attic/qtmultilineedit.h363
-rw-r--r--tqtinterface/qt4/src/attic/qttableview.cpp2272
-rw-r--r--tqtinterface/qt4/src/attic/qttableview.h250
-rw-r--r--tqtinterface/qt4/src/canvas/qt_canvas.pri6
-rw-r--r--tqtinterface/qt4/src/canvas/tqcanvas.cpp5415
-rw-r--r--tqtinterface/qt4/src/canvas/tqcanvas.h818
-rw-r--r--tqtinterface/qt4/src/codecs/qt_codecs.pri48
-rw-r--r--tqtinterface/qt4/src/codecs/tqbig5codec.cpp11766
-rw-r--r--tqtinterface/qt4/src/codecs/tqbig5codec.h89
-rw-r--r--tqtinterface/qt4/src/codecs/tqeucjpcodec.cpp485
-rw-r--r--tqtinterface/qt4/src/codecs/tqeucjpcodec.h111
-rw-r--r--tqtinterface/qt4/src/codecs/tqeuckrcodec.cpp3486
-rw-r--r--tqtinterface/qt4/src/codecs/tqeuckrcodec.h100
-rw-r--r--tqtinterface/qt4/src/codecs/tqfontcncodec.cpp328
-rw-r--r--tqtinterface/qt4/src/codecs/tqfontcodecs_p.h384
-rw-r--r--tqtinterface/qt4/src/codecs/tqfonthkcodec.cpp160
-rw-r--r--tqtinterface/qt4/src/codecs/tqfontjpcodec.cpp223
-rw-r--r--tqtinterface/qt4/src/codecs/tqfontkrcodec.cpp121
-rw-r--r--tqtinterface/qt4/src/codecs/tqfontlaocodec.cpp152
-rw-r--r--tqtinterface/qt4/src/codecs/tqfonttwcodec.cpp162
-rw-r--r--tqtinterface/qt4/src/codecs/tqgb18030codec.cpp9381
-rw-r--r--tqtinterface/qt4/src/codecs/tqgb18030codec.h115
-rw-r--r--tqtinterface/qt4/src/codecs/tqgbkcodec.h47
-rw-r--r--tqtinterface/qt4/src/codecs/tqisciicodec.cpp240
-rw-r--r--tqtinterface/qt4/src/codecs/tqisciicodec_p.h33
-rw-r--r--tqtinterface/qt4/src/codecs/tqjiscodec.cpp706
-rw-r--r--tqtinterface/qt4/src/codecs/tqjiscodec.h111
-rw-r--r--tqtinterface/qt4/src/codecs/tqjpunicode.cpp10743
-rw-r--r--tqtinterface/qt4/src/codecs/tqjpunicode.h179
-rw-r--r--tqtinterface/qt4/src/codecs/tqrtlcodec.cpp617
-rw-r--r--tqtinterface/qt4/src/codecs/tqrtlcodec.h67
-rw-r--r--tqtinterface/qt4/src/codecs/tqsjiscodec.cpp382
-rw-r--r--tqtinterface/qt4/src/codecs/tqsjiscodec.h111
-rw-r--r--tqtinterface/qt4/src/codecs/tqtextcodec.cpp3122
-rw-r--r--tqtinterface/qt4/src/codecs/tqtextcodec.h134
-rw-r--r--tqtinterface/qt4/src/codecs/tqtextcodecfactory.cpp131
-rw-r--r--tqtinterface/qt4/src/codecs/tqtextcodecfactory.h59
-rw-r--r--tqtinterface/qt4/src/codecs/tqtextcodecinterface_p.h80
-rw-r--r--tqtinterface/qt4/src/codecs/tqtextcodecplugin.cpp186
-rw-r--r--tqtinterface/qt4/src/codecs/tqtextcodecplugin.h70
-rw-r--r--tqtinterface/qt4/src/codecs/tqtsciicodec.cpp528
-rw-r--r--tqtinterface/qt4/src/codecs/tqtsciicodec.h94
-rw-r--r--tqtinterface/qt4/src/codecs/tqutfcodec.cpp350
-rw-r--r--tqtinterface/qt4/src/codecs/tqutfcodec.h78
-rw-r--r--tqtinterface/qt4/src/compat/tqapp.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqarray.h27
-rw-r--r--tqtinterface/qt4/src/compat/tqbitarry.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqbttngrp.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqchkbox.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqclipbrd.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqcollect.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqcollection.h27
-rw-r--r--tqtinterface/qt4/src/compat/tqcombo.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqconnect.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqdatetm.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqdrawutl.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqdstream.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqfiledef.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqfiledlg.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqfileinf.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqfontinf.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqfontmet.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqgrpbox.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqintcach.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqiodev.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqlcdnum.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqlined.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqlist.h27
-rw-r--r--tqtinterface/qt4/src/compat/tqmenudta.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqmetaobj.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqmlined.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqmsgbox.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqmultilinedit.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqobjcoll.h26
-rw-r--r--tqtinterface/qt4/src/compat/tqobjdefs.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqpaintd.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqpaintdc.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqpdevmet.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqpmcache.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqpntarry.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqpopmenu.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqprndlg.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqprogbar.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqprogdlg.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqpsprn.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqpushbt.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqqueue.h27
-rw-r--r--tqtinterface/qt4/src/compat/tqradiobt.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqrangect.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqscrbar.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqsocknot.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqstack.h27
-rw-r--r--tqtinterface/qt4/src/compat/tqtabdlg.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqtstream.h25
-rw-r--r--tqtinterface/qt4/src/compat/tqvector.h27
-rw-r--r--tqtinterface/qt4/src/compat/tqwidcoll.h26
-rw-r--r--tqtinterface/qt4/src/compat/tqwindefs.h25
-rw-r--r--tqtinterface/qt4/src/dialogs/qt_dialogs.pri33
-rw-r--r--tqtinterface/qt4/src/dialogs/tqcolordialog.cpp1665
-rw-r--r--tqtinterface/qt4/src/dialogs/tqcolordialog.h93
-rw-r--r--tqtinterface/qt4/src/dialogs/tqdialog.cpp1183
-rw-r--r--tqtinterface/qt4/src/dialogs/tqdialog.h142
-rw-r--r--tqtinterface/qt4/src/dialogs/tqerrormessage.cpp270
-rw-r--r--tqtinterface/qt4/src/dialogs/tqerrormessage.h90
-rw-r--r--tqtinterface/qt4/src/dialogs/tqfiledialog.cpp6466
-rw-r--r--tqtinterface/qt4/src/dialogs/tqfiledialog.h350
-rw-r--r--tqtinterface/qt4/src/dialogs/tqfontdialog.cpp831
-rw-r--r--tqtinterface/qt4/src/dialogs/tqfontdialog.h113
-rw-r--r--tqtinterface/qt4/src/dialogs/tqinputdialog.cpp532
-rw-r--r--tqtinterface/qt4/src/dialogs/tqinputdialog.h108
-rw-r--r--tqtinterface/qt4/src/dialogs/tqmessagebox.cpp2605
-rw-r--r--tqtinterface/qt4/src/dialogs/tqmessagebox.h224
-rw-r--r--tqtinterface/qt4/src/dialogs/tqprintdialog.cpp1672
-rw-r--r--tqtinterface/qt4/src/dialogs/tqprintdialog.h104
-rw-r--r--tqtinterface/qt4/src/dialogs/tqprogressdialog.cpp826
-rw-r--r--tqtinterface/qt4/src/dialogs/tqprogressdialog.h142
-rw-r--r--tqtinterface/qt4/src/dialogs/tqsemimodal.h67
-rw-r--r--tqtinterface/qt4/src/dialogs/tqtabdialog.cpp1145
-rw-r--r--tqtinterface/qt4/src/dialogs/tqtabdialog.h147
-rw-r--r--tqtinterface/qt4/src/dialogs/tqwizard.cpp917
-rw-r--r--tqtinterface/qt4/src/dialogs/tqwizard.h143
-rw-r--r--tqtinterface/qt4/src/embedded/qt_embedded.pri192
-rw-r--r--tqtinterface/qt4/src/embedded/tqgfxdriverinterface_p.h74
-rw-r--r--tqtinterface/qt4/src/embedded/tqkbddriverinterface_p.h74
-rw-r--r--tqtinterface/qt4/src/embedded/tqmousedriverinterface_p.h74
-rw-r--r--tqtinterface/qt4/src/iconview/qt_iconview.pri6
-rw-r--r--tqtinterface/qt4/src/iconview/tqiconview.cpp6416
-rw-r--r--tqtinterface/qt4/src/iconview/tqiconview.h516
-rwxr-xr-xtqtinterface/qt4/src/kernel/makepsheader.pl93
-rw-r--r--tqtinterface/qt4/src/kernel/qpsprinter.ps805
-rw-r--r--tqtinterface/qt4/src/kernel/qt_compat.pri27
-rw-r--r--tqtinterface/qt4/src/kernel/qt_gfx.pri155
-rw-r--r--tqtinterface/qt4/src/kernel/qt_kernel.pri261
-rw-r--r--tqtinterface/qt4/src/kernel/qt_x11.pri20
-rw-r--r--tqtinterface/qt4/src/kernel/tq1xcompatibility.h49
-rw-r--r--tqtinterface/qt4/src/kernel/tqabstractlayout.cpp2108
-rw-r--r--tqtinterface/qt4/src/kernel/tqabstractlayout.h54
-rw-r--r--tqtinterface/qt4/src/kernel/tqaccel.cpp2098
-rw-r--r--tqtinterface/qt4/src/kernel/tqaccel.h238
-rw-r--r--tqtinterface/qt4/src/kernel/tqaccessible.cpp719
-rw-r--r--tqtinterface/qt4/src/kernel/tqaccessible.h295
-rw-r--r--tqtinterface/qt4/src/kernel/tqapplication.cpp5499
-rw-r--r--tqtinterface/qt4/src/kernel/tqapplication.cpp~5499
-rw-r--r--tqtinterface/qt4/src/kernel/tqapplication.h724
-rw-r--r--tqtinterface/qt4/src/kernel/tqapplication.h~724
-rw-r--r--tqtinterface/qt4/src/kernel/tqapplication_p.h95
-rw-r--r--tqtinterface/qt4/src/kernel/tqapplication_x11.cpp8984
-rw-r--r--tqtinterface/qt4/src/kernel/tqasyncimageio.cpp1316
-rw-r--r--tqtinterface/qt4/src/kernel/tqasyncimageio.h111
-rw-r--r--tqtinterface/qt4/src/kernel/tqasyncio.cpp360
-rw-r--r--tqtinterface/qt4/src/kernel/tqasyncio.h121
-rw-r--r--tqtinterface/qt4/src/kernel/tqbitmap.cpp435
-rw-r--r--tqtinterface/qt4/src/kernel/tqbitmap.h114
-rw-r--r--tqtinterface/qt4/src/kernel/tqbrush.h141
-rw-r--r--tqtinterface/qt4/src/kernel/tqclipboard.cpp754
-rw-r--r--tqtinterface/qt4/src/kernel/tqclipboard.h168
-rw-r--r--tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp2020
-rw-r--r--tqtinterface/qt4/src/kernel/tqcolor.cpp1174
-rw-r--r--tqtinterface/qt4/src/kernel/tqcolor.h348
-rw-r--r--tqtinterface/qt4/src/kernel/tqcolor_p.cpp802
-rw-r--r--tqtinterface/qt4/src/kernel/tqcolor_p.h66
-rw-r--r--tqtinterface/qt4/src/kernel/tqcolor_x11.cpp1336
-rw-r--r--tqtinterface/qt4/src/kernel/tqconnection.cpp94
-rw-r--r--tqtinterface/qt4/src/kernel/tqconnection.h78
-rw-r--r--tqtinterface/qt4/src/kernel/tqcursor.cpp292
-rw-r--r--tqtinterface/qt4/src/kernel/tqcursor.h188
-rw-r--r--tqtinterface/qt4/src/kernel/tqcursor_x11.cpp1013
-rw-r--r--tqtinterface/qt4/src/kernel/tqdesktopwidget.h141
-rw-r--r--tqtinterface/qt4/src/kernel/tqdesktopwidget_x11.cpp335
-rw-r--r--tqtinterface/qt4/src/kernel/tqdnd_x11.cpp1765
-rw-r--r--tqtinterface/qt4/src/kernel/tqdragobject.cpp3378
-rw-r--r--tqtinterface/qt4/src/kernel/tqdragobject.h508
-rw-r--r--tqtinterface/qt4/src/kernel/tqdrawutil.cpp957
-rw-r--r--tqtinterface/qt4/src/kernel/tqdrawutil.h128
-rw-r--r--tqtinterface/qt4/src/kernel/tqdropsite.cpp81
-rw-r--r--tqtinterface/qt4/src/kernel/tqdropsite.h59
-rw-r--r--tqtinterface/qt4/src/kernel/tqevent.cpp2708
-rw-r--r--tqtinterface/qt4/src/kernel/tqevent.h952
-rw-r--r--tqtinterface/qt4/src/kernel/tqeventloop.cpp394
-rw-r--r--tqtinterface/qt4/src/kernel/tqeventloop.h123
-rw-r--r--tqtinterface/qt4/src/kernel/tqeventloop_p.h150
-rw-r--r--tqtinterface/qt4/src/kernel/tqeventloop_unix.cpp587
-rw-r--r--tqtinterface/qt4/src/kernel/tqeventloop_x11.cpp417
-rw-r--r--tqtinterface/qt4/src/kernel/tqfocusdata.cpp141
-rw-r--r--tqtinterface/qt4/src/kernel/tqfocusdata.h70
-rw-r--r--tqtinterface/qt4/src/kernel/tqfont.cpp3376
-rw-r--r--tqtinterface/qt4/src/kernel/tqfont.h524
-rw-r--r--tqtinterface/qt4/src/kernel/tqfont_x11.cpp747
-rw-r--r--tqtinterface/qt4/src/kernel/tqfontdata_p.h278
-rw-r--r--tqtinterface/qt4/src/kernel/tqfontdatabase.cpp2505
-rw-r--r--tqtinterface/qt4/src/kernel/tqfontdatabase.h306
-rw-r--r--tqtinterface/qt4/src/kernel/tqfontdatabase_x11.cpp2008
-rw-r--r--tqtinterface/qt4/src/kernel/tqfontengine_p.h642
-rw-r--r--tqtinterface/qt4/src/kernel/tqfontengine_x11.cpp2752
-rw-r--r--tqtinterface/qt4/src/kernel/tqfontinfo.h111
-rw-r--r--tqtinterface/qt4/src/kernel/tqfontmetrics.h138
-rw-r--r--tqtinterface/qt4/src/kernel/tqgif.h61
-rw-r--r--tqtinterface/qt4/src/kernel/tqgplugin.cpp72
-rw-r--r--tqtinterface/qt4/src/kernel/tqgplugin.h146
-rw-r--r--tqtinterface/qt4/src/kernel/tqguardedptr.cpp226
-rw-r--r--tqtinterface/qt4/src/kernel/tqguardedptr.h145
-rw-r--r--tqtinterface/qt4/src/kernel/tqiconset.cpp949
-rw-r--r--tqtinterface/qt4/src/kernel/tqiconset.h132
-rw-r--r--tqtinterface/qt4/src/kernel/tqimage.cpp9526
-rw-r--r--tqtinterface/qt4/src/kernel/tqimage.h695
-rw-r--r--tqtinterface/qt4/src/kernel/tqimageformatinterface_p.h81
-rw-r--r--tqtinterface/qt4/src/kernel/tqimageformatplugin.cpp184
-rw-r--r--tqtinterface/qt4/src/kernel/tqimageformatplugin.h67
-rw-r--r--tqtinterface/qt4/src/kernel/tqinputcontext_p.h127
-rw-r--r--tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp535
-rw-r--r--tqtinterface/qt4/src/kernel/tqinternal.cpp785
-rw-r--r--tqtinterface/qt4/src/kernel/tqinternal_p.h213
-rw-r--r--tqtinterface/qt4/src/kernel/tqjpegio.cpp599
-rw-r--r--tqtinterface/qt4/src/kernel/tqjpegio.h52
-rw-r--r--tqtinterface/qt4/src/kernel/tqkeycode.h50
-rw-r--r--tqtinterface/qt4/src/kernel/tqkeysequence.cpp731
-rw-r--r--tqtinterface/qt4/src/kernel/tqkeysequence.h109
-rw-r--r--tqtinterface/qt4/src/kernel/tqlayout.cpp4056
-rw-r--r--tqtinterface/qt4/src/kernel/tqlayout.h1146
-rw-r--r--tqtinterface/qt4/src/kernel/tqlayoutengine.cpp322
-rw-r--r--tqtinterface/qt4/src/kernel/tqlayoutengine_p.h129
-rw-r--r--tqtinterface/qt4/src/kernel/tqlocalfs.cpp407
-rw-r--r--tqtinterface/qt4/src/kernel/tqlocalfs.h75
-rw-r--r--tqtinterface/qt4/src/kernel/tqlock.cpp297
-rw-r--r--tqtinterface/qt4/src/kernel/tqlock_p.h99
-rw-r--r--tqtinterface/qt4/src/kernel/tqmetaobject.cpp1792
-rw-r--r--tqtinterface/qt4/src/kernel/tqmetaobject.cpp~1792
-rw-r--r--tqtinterface/qt4/src/kernel/tqmetaobject.h404
-rw-r--r--tqtinterface/qt4/src/kernel/tqmetaobject.h~403
-rw-r--r--tqtinterface/qt4/src/kernel/tqmime.cpp1158
-rw-r--r--tqtinterface/qt4/src/kernel/tqmime.h312
-rw-r--r--tqtinterface/qt4/src/kernel/tqmngio.cpp464
-rw-r--r--tqtinterface/qt4/src/kernel/tqmngio.h53
-rw-r--r--tqtinterface/qt4/src/kernel/tqmotifdnd_x11.cpp978
-rw-r--r--tqtinterface/qt4/src/kernel/tqmovie.cpp1082
-rw-r--r--tqtinterface/qt4/src/kernel/tqmovie.h123
-rw-r--r--tqtinterface/qt4/src/kernel/tqnamespace.h1159
-rw-r--r--tqtinterface/qt4/src/kernel/tqnetworkprotocol.cpp1265
-rw-r--r--tqtinterface/qt4/src/kernel/tqnetworkprotocol.h246
-rw-r--r--tqtinterface/qt4/src/kernel/tqobject.cpp3666
-rw-r--r--tqtinterface/qt4/src/kernel/tqobject.h417
-rw-r--r--tqtinterface/qt4/src/kernel/tqobjectcleanuphandler.cpp172
-rw-r--r--tqtinterface/qt4/src/kernel/tqobjectcleanuphandler.h69
-rw-r--r--tqtinterface/qt4/src/kernel/tqobjectdefs.h277
-rw-r--r--tqtinterface/qt4/src/kernel/tqobjectdict.h66
-rw-r--r--tqtinterface/qt4/src/kernel/tqobjectlist.h92
-rw-r--r--tqtinterface/qt4/src/kernel/tqpaintdevice.h688
-rw-r--r--tqtinterface/qt4/src/kernel/tqpaintdevice_x11.cpp1746
-rw-r--r--tqtinterface/qt4/src/kernel/tqpaintdevicedefs.h48
-rw-r--r--tqtinterface/qt4/src/kernel/tqpaintdevicemetrics.cpp304
-rw-r--r--tqtinterface/qt4/src/kernel/tqpaintdevicemetrics.h181
-rw-r--r--tqtinterface/qt4/src/kernel/tqpainter.cpp5382
-rw-r--r--tqtinterface/qt4/src/kernel/tqpainter.cpp~5161
-rw-r--r--tqtinterface/qt4/src/kernel/tqpainter.h1019
-rw-r--r--tqtinterface/qt4/src/kernel/tqpainter.h~993
-rw-r--r--tqtinterface/qt4/src/kernel/tqpainter_p.h66
-rw-r--r--tqtinterface/qt4/src/kernel/tqpainter_x11.cpp3348
-rw-r--r--tqtinterface/qt4/src/kernel/tqpalette.cpp1348
-rw-r--r--tqtinterface/qt4/src/kernel/tqpalette.h295
-rw-r--r--tqtinterface/qt4/src/kernel/tqpen.h132
-rw-r--r--tqtinterface/qt4/src/kernel/tqpicture.cpp1235
-rw-r--r--tqtinterface/qt4/src/kernel/tqpicture.h144
-rw-r--r--tqtinterface/qt4/src/kernel/tqpixmap.cpp1882
-rw-r--r--tqtinterface/qt4/src/kernel/tqpixmap.h496
-rw-r--r--tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp2155
-rw-r--r--tqtinterface/qt4/src/kernel/tqpixmapcache.cpp336
-rw-r--r--tqtinterface/qt4/src/kernel/tqpixmapcache.h63
-rw-r--r--tqtinterface/qt4/src/kernel/tqpngio.cpp1250
-rw-r--r--tqtinterface/qt4/src/kernel/tqpngio.h107
-rw-r--r--tqtinterface/qt4/src/kernel/tqpoint.cpp448
-rw-r--r--tqtinterface/qt4/src/kernel/tqpoint.h253
-rw-r--r--tqtinterface/qt4/src/kernel/tqpointarray.cpp1311
-rw-r--r--tqtinterface/qt4/src/kernel/tqpointarray.h195
-rw-r--r--tqtinterface/qt4/src/kernel/tqpolygonscanner.cpp937
-rw-r--r--tqtinterface/qt4/src/kernel/tqpolygonscanner.h61
-rw-r--r--tqtinterface/qt4/src/kernel/tqprinter.cpp1198
-rwxr-xr-xtqtinterface/qt4/src/kernel/tqprinter.h335
-rw-r--r--tqtinterface/qt4/src/kernel/tqprinter_p.h59
-rw-r--r--tqtinterface/qt4/src/kernel/tqprinter_unix.cpp853
-rw-r--r--tqtinterface/qt4/src/kernel/tqprocess.cpp806
-rw-r--r--tqtinterface/qt4/src/kernel/tqprocess.h179
-rw-r--r--tqtinterface/qt4/src/kernel/tqprocess_unix.cpp1410
-rw-r--r--tqtinterface/qt4/src/kernel/tqpsprinter.cpp6595
-rw-r--r--tqtinterface/qt4/src/kernel/tqpsprinter_p.h98
-rw-r--r--tqtinterface/qt4/src/kernel/tqrect.cpp1010
-rw-r--r--tqtinterface/qt4/src/kernel/tqrect.h328
-rw-r--r--tqtinterface/qt4/src/kernel/tqregion.cpp398
-rw-r--r--tqtinterface/qt4/src/kernel/tqregion.h227
-rw-r--r--tqtinterface/qt4/src/kernel/tqregion_x11.cpp2908
-rw-r--r--tqtinterface/qt4/src/kernel/tqrichtext.cpp16615
-rw-r--r--tqtinterface/qt4/src/kernel/tqrichtext_p.cpp1283
-rw-r--r--tqtinterface/qt4/src/kernel/tqrichtext_p.h4300
-rw-r--r--tqtinterface/qt4/src/kernel/tqscriptengine.cpp1630
-rw-r--r--tqtinterface/qt4/src/kernel/tqscriptengine_p.h91
-rw-r--r--tqtinterface/qt4/src/kernel/tqscriptengine_x11.cpp3752
-rw-r--r--tqtinterface/qt4/src/kernel/tqsession.h47
-rw-r--r--tqtinterface/qt4/src/kernel/tqsessionmanager.h168
-rw-r--r--tqtinterface/qt4/src/kernel/tqsharedmemory_p.cpp169
-rw-r--r--tqtinterface/qt4/src/kernel/tqsharedmemory_p.h95
-rw-r--r--tqtinterface/qt4/src/kernel/tqsignal.cpp493
-rw-r--r--tqtinterface/qt4/src/kernel/tqsignal.h154
-rw-r--r--tqtinterface/qt4/src/kernel/tqsignalmapper.cpp183
-rw-r--r--tqtinterface/qt4/src/kernel/tqsignalmapper.h79
-rw-r--r--tqtinterface/qt4/src/kernel/tqsignalslotimp.h97
-rw-r--r--tqtinterface/qt4/src/kernel/tqsimplerichtext.cpp851
-rw-r--r--tqtinterface/qt4/src/kernel/tqsimplerichtext.h234
-rw-r--r--tqtinterface/qt4/src/kernel/tqsize.cpp437
-rw-r--r--tqtinterface/qt4/src/kernel/tqsize.h318
-rw-r--r--tqtinterface/qt4/src/kernel/tqsizegrip.cpp286
-rw-r--r--tqtinterface/qt4/src/kernel/tqsizegrip.h75
-rw-r--r--tqtinterface/qt4/src/kernel/tqsizepolicy.h194
-rw-r--r--tqtinterface/qt4/src/kernel/tqsocketnotifier.cpp270
-rw-r--r--tqtinterface/qt4/src/kernel/tqsocketnotifier.h114
-rw-r--r--tqtinterface/qt4/src/kernel/tqsound.cpp316
-rw-r--r--tqtinterface/qt4/src/kernel/tqsound.h126
-rw-r--r--tqtinterface/qt4/src/kernel/tqsound_x11.cpp284
-rw-r--r--tqtinterface/qt4/src/kernel/tqstyle.cpp2186
-rw-r--r--tqtinterface/qt4/src/kernel/tqstyle.h1278
-rw-r--r--tqtinterface/qt4/src/kernel/tqstylesheet.cpp1623
-rw-r--r--tqtinterface/qt4/src/kernel/tqstylesheet.h256
-rw-r--r--tqtinterface/qt4/src/kernel/tqt.h379
-rw-r--r--tqtinterface/qt4/src/kernel/tqt_pch.h57
-rw-r--r--tqtinterface/qt4/src/kernel/tqt_x11_p.h275
-rw-r--r--tqtinterface/qt4/src/kernel/tqtaddons_x11.cpp144
-rw-r--r--tqtinterface/qt4/src/kernel/tqtextengine.cpp1186
-rw-r--r--tqtinterface/qt4/src/kernel/tqtextengine_p.h467
-rw-r--r--tqtinterface/qt4/src/kernel/tqtextengine_unix.cpp127
-rw-r--r--tqtinterface/qt4/src/kernel/tqtextlayout.cpp818
-rw-r--r--tqtinterface/qt4/src/kernel/tqtextlayout_p.h300
-rw-r--r--tqtinterface/qt4/src/kernel/tqtglobaldefines.h502
-rw-r--r--tqtinterface/qt4/src/kernel/tqtglobalsettings.h7
-rw-r--r--tqtinterface/qt4/src/kernel/tqthread.cpp241
-rw-r--r--tqtinterface/qt4/src/kernel/tqthread.h130
-rw-r--r--tqtinterface/qt4/src/kernel/tqthread_unix.cpp474
-rw-r--r--tqtinterface/qt4/src/kernel/tqtimer.cpp350
-rw-r--r--tqtinterface/qt4/src/kernel/tqtimer.h92
-rw-r--r--tqtinterface/qt4/src/kernel/tqtranslator.cpp2438
-rw-r--r--tqtinterface/qt4/src/kernel/tqtranslator.h281
-rw-r--r--tqtinterface/qt4/src/kernel/tqucomextra.cpp177
-rw-r--r--tqtinterface/qt4/src/kernel/tqucomextra_p.h109
-rw-r--r--tqtinterface/qt4/src/kernel/tqurl.cpp1345
-rw-r--r--tqtinterface/qt4/src/kernel/tqurl.h130
-rw-r--r--tqtinterface/qt4/src/kernel/tqurlinfo.cpp761
-rw-r--r--tqtinterface/qt4/src/kernel/tqurlinfo.h144
-rw-r--r--tqtinterface/qt4/src/kernel/tqurloperator.cpp1226
-rw-r--r--tqtinterface/qt4/src/kernel/tqurloperator.h130
-rw-r--r--tqtinterface/qt4/src/kernel/tqvariant.cpp4972
-rw-r--r--tqtinterface/qt4/src/kernel/tqvariant.cpp.new4858
-rw-r--r--tqtinterface/qt4/src/kernel/tqvariant.h642
-rw-r--r--tqtinterface/qt4/src/kernel/tqvfbhdr.h71
-rw-r--r--tqtinterface/qt4/src/kernel/tqwidget.cpp8728
-rw-r--r--tqtinterface/qt4/src/kernel/tqwidget.h1547
-rw-r--r--tqtinterface/qt4/src/kernel/tqwidget_p.h64
-rw-r--r--tqtinterface/qt4/src/kernel/tqwidget_x11.cpp2980
-rw-r--r--tqtinterface/qt4/src/kernel/tqwidgetcreate_x11.cpp74
-rw-r--r--tqtinterface/qt4/src/kernel/tqwidgetintdict.h75
-rw-r--r--tqtinterface/qt4/src/kernel/tqwidgetlist.h67
-rw-r--r--tqtinterface/qt4/src/kernel/tqwindow.cpp39
-rw-r--r--tqtinterface/qt4/src/kernel/tqwindow.h46
-rw-r--r--tqtinterface/qt4/src/kernel/tqwindowdefs.h197
-rw-r--r--tqtinterface/qt4/src/kernel/tqwmatrix.cpp1204
-rw-r--r--tqtinterface/qt4/src/kernel/tqwmatrix.cpp~1204
-rw-r--r--tqtinterface/qt4/src/kernel/tqwmatrix.h194
-rw-r--r--tqtinterface/qt4/src/kernel/tqwmatrix.h~193
-rw-r--r--tqtinterface/qt4/src/libtqt.map50
-rw-r--r--tqtinterface/qt4/src/network/qt_network.pri23
-rw-r--r--tqtinterface/qt4/src/network/tqdns.cpp5294
-rw-r--r--tqtinterface/qt4/src/network/tqdns.h382
-rw-r--r--tqtinterface/qt4/src/network/tqftp.cpp2421
-rw-r--r--tqtinterface/qt4/src/network/tqftp.h204
-rw-r--r--tqtinterface/qt4/src/network/tqhostaddress.cpp459
-rw-r--r--tqtinterface/qt4/src/network/tqhostaddress.h131
-rw-r--r--tqtinterface/qt4/src/network/tqhttp.cpp2384
-rw-r--r--tqtinterface/qt4/src/network/tqhttp.h278
-rw-r--r--tqtinterface/qt4/src/network/tqnetwork.cpp71
-rw-r--r--tqtinterface/qt4/src/network/tqnetwork.h60
-rw-r--r--tqtinterface/qt4/src/network/tqserversocket.cpp297
-rw-r--r--tqtinterface/qt4/src/network/tqserversocket.h95
-rw-r--r--tqtinterface/qt4/src/network/tqsocket.cpp1668
-rw-r--r--tqtinterface/qt4/src/network/tqsocket.h174
-rw-r--r--tqtinterface/qt4/src/network/tqsocketdevice.cpp584
-rw-r--r--tqtinterface/qt4/src/network/tqsocketdevice.h185
-rw-r--r--tqtinterface/qt4/src/network/tqsocketdevice_unix.cpp1269
-rw-r--r--tqtinterface/qt4/src/opengl/qt_opengl.pri18
-rw-r--r--tqtinterface/qt4/src/opengl/tqgl.cpp2374
-rw-r--r--tqtinterface/qt4/src/opengl/tqgl.h542
-rw-r--r--tqtinterface/qt4/src/opengl/tqgl_x11.cpp1425
-rw-r--r--tqtinterface/qt4/src/opengl/tqgl_x11_p.h197
-rw-r--r--tqtinterface/qt4/src/opengl/tqglcolormap.cpp292
-rw-r--r--tqtinterface/qt4/src/opengl/tqglcolormap.h99
-rw-r--r--tqtinterface/qt4/src/qt.pro195
-rw-r--r--tqtinterface/qt4/src/qt_install.pri33
-rw-r--r--tqtinterface/qt4/src/qt_professional.pri96
-rw-r--r--tqtinterface/qt4/src/qtmain.pro18
-rw-r--r--tqtinterface/qt4/src/sql/README.module37
-rw-r--r--tqtinterface/qt4/src/sql/drivers/cache/tqsqlcachedresult.cpp259
-rw-r--r--tqtinterface/qt4/src/sql/drivers/cache/tqsqlcachedresult.h104
-rw-r--r--tqtinterface/qt4/src/sql/drivers/ibase/tqsql_ibase.cpp1078
-rw-r--r--tqtinterface/qt4/src/sql/drivers/ibase/tqsql_ibase.h117
-rw-r--r--tqtinterface/qt4/src/sql/drivers/mysql/tqsql_mysql.cpp775
-rw-r--r--tqtinterface/qt4/src/sql/drivers/mysql/tqsql_mysql.h131
-rw-r--r--tqtinterface/qt4/src/sql/drivers/odbc/tqsql_odbc.cpp2035
-rw-r--r--tqtinterface/qt4/src/sql/drivers/odbc/tqsql_odbc.h165
-rw-r--r--tqtinterface/qt4/src/sql/drivers/psql/tqsql_psql.cpp1117
-rw-r--r--tqtinterface/qt4/src/sql/drivers/psql/tqsql_psql.h131
-rw-r--r--tqtinterface/qt4/src/sql/drivers/sqlite/tqsql_sqlite.cpp513
-rw-r--r--tqtinterface/qt4/src/sql/drivers/sqlite/tqsql_sqlite.h90
-rw-r--r--tqtinterface/qt4/src/sql/qt_sql.pri254
-rw-r--r--tqtinterface/qt4/src/sql/tqdatabrowser.cpp1284
-rw-r--r--tqtinterface/qt4/src/sql/tqdatabrowser.h178
-rw-r--r--tqtinterface/qt4/src/sql/tqdatatable.cpp2322
-rw-r--r--tqtinterface/qt4/src/sql/tqdatatable.h245
-rw-r--r--tqtinterface/qt4/src/sql/tqdataview.cpp208
-rw-r--r--tqtinterface/qt4/src/sql/tqdataview.h91
-rw-r--r--tqtinterface/qt4/src/sql/tqeditorfactory.cpp192
-rw-r--r--tqtinterface/qt4/src/sql/tqeditorfactory.h76
-rw-r--r--tqtinterface/qt4/src/sql/tqsql.cpp114
-rw-r--r--tqtinterface/qt4/src/sql/tqsql.h100
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlcursor.cpp1549
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlcursor.h160
-rw-r--r--tqtinterface/qt4/src/sql/tqsqldatabase.cpp1332
-rw-r--r--tqtinterface/qt4/src/sql/tqsqldatabase.h156
-rw-r--r--tqtinterface/qt4/src/sql/tqsqldriver.cpp509
-rw-r--r--tqtinterface/qt4/src/sql/tqsqldriver.h126
-rw-r--r--tqtinterface/qt4/src/sql/tqsqldriverinterface_p.h85
-rw-r--r--tqtinterface/qt4/src/sql/tqsqldriverplugin.cpp161
-rw-r--r--tqtinterface/qt4/src/sql/tqsqldriverplugin.h73
-rw-r--r--tqtinterface/qt4/src/sql/tqsqleditorfactory.cpp221
-rw-r--r--tqtinterface/qt4/src/sql/tqsqleditorfactory.h77
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlerror.cpp228
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlerror.h93
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlextension_p.cpp169
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlextension_p.h148
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlfield.cpp563
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlfield.h154
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlform.cpp403
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlform.h109
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlindex.cpp301
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlindex.h99
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlmanager_p.cpp941
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlmanager_p.h163
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlpropertymap.cpp304
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlpropertymap.h78
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlquery.cpp1215
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlquery.h134
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlrecord.cpp774
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlrecord.h141
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlresult.cpp368
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlresult.h115
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlselectcursor.cpp249
-rw-r--r--tqtinterface/qt4/src/sql/tqsqlselectcursor.h104
-rw-r--r--tqtinterface/qt4/src/styles/qt_styles.pri140
-rw-r--r--tqtinterface/qt4/src/styles/tqcdestyle.cpp367
-rw-r--r--tqtinterface/qt4/src/styles/tqcdestyle.h86
-rw-r--r--tqtinterface/qt4/src/styles/tqcommonstyle.cpp2726
-rw-r--r--tqtinterface/qt4/src/styles/tqcommonstyle.h154
-rw-r--r--tqtinterface/qt4/src/styles/tqcompactstyle.cpp321
-rw-r--r--tqtinterface/qt4/src/styles/tqcompactstyle.h75
-rw-r--r--tqtinterface/qt4/src/styles/tqinterlacestyle.cpp805
-rw-r--r--tqtinterface/qt4/src/styles/tqinterlacestyle.h107
-rw-r--r--tqtinterface/qt4/src/styles/tqmotifplusstyle.cpp1586
-rw-r--r--tqtinterface/qt4/src/styles/tqmotifplusstyle.h124
-rw-r--r--tqtinterface/qt4/src/styles/tqmotifstyle.cpp2367
-rw-r--r--tqtinterface/qt4/src/styles/tqmotifstyle.h136
-rw-r--r--tqtinterface/qt4/src/styles/tqplatinumstyle.cpp1557
-rw-r--r--tqtinterface/qt4/src/styles/tqplatinumstyle.h117
-rw-r--r--tqtinterface/qt4/src/styles/tqsgistyle.cpp1470
-rw-r--r--tqtinterface/qt4/src/styles/tqsgistyle.h133
-rw-r--r--tqtinterface/qt4/src/styles/tqstylefactory.cpp268
-rw-r--r--tqtinterface/qt4/src/styles/tqstylefactory.h62
-rw-r--r--tqtinterface/qt4/src/styles/tqstyleinterface_p.h76
-rw-r--r--tqtinterface/qt4/src/styles/tqstyleplugin.cpp185
-rw-r--r--tqtinterface/qt4/src/styles/tqstyleplugin.h72
-rw-r--r--tqtinterface/qt4/src/styles/tqwindowsstyle.cpp2166
-rw-r--r--tqtinterface/qt4/src/styles/tqwindowsstyle.h134
-rw-r--r--tqtinterface/qt4/src/table/qt_table.pri6
-rw-r--r--tqtinterface/qt4/src/table/tqtable.cpp7375
-rw-r--r--tqtinterface/qt4/src/table/tqtable.h565
-rw-r--r--tqtinterface/qt4/src/tmp/README1
-rw-r--r--tqtinterface/qt4/src/tools/qfeatures.txt1314
-rw-r--r--tqtinterface/qt4/src/tools/qt_tools.pri150
-rw-r--r--tqtinterface/qt4/src/tools/tqasciicache.h125
-rw-r--r--tqtinterface/qt4/src/tools/tqasciidict.h123
-rw-r--r--tqtinterface/qt4/src/tools/tqbitarray.cpp670
-rw-r--r--tqtinterface/qt4/src/tools/tqbitarray.h204
-rw-r--r--tqtinterface/qt4/src/tools/tqbuffer.cpp503
-rw-r--r--tqtinterface/qt4/src/tools/tqbuffer.h220
-rw-r--r--tqtinterface/qt4/src/tools/tqbuffer.h~219
-rw-r--r--tqtinterface/qt4/src/tools/tqcache.h121
-rw-r--r--tqtinterface/qt4/src/tools/tqcleanuphandler.h130
-rw-r--r--tqtinterface/qt4/src/tools/tqcom_p.h344
-rw-r--r--tqtinterface/qt4/src/tools/tqcomlibrary.cpp538
-rw-r--r--tqtinterface/qt4/src/tools/tqcomlibrary_p.h82
-rw-r--r--tqtinterface/qt4/src/tools/tqcomponentfactory.cpp355
-rw-r--r--tqtinterface/qt4/src/tools/tqcomponentfactory_p.h76
-rw-r--r--tqtinterface/qt4/src/tools/tqconfig-dist.h11
-rw-r--r--tqtinterface/qt4/src/tools/tqconfig-large.h42
-rw-r--r--tqtinterface/qt4/src/tools/tqconfig-medium.h108
-rw-r--r--tqtinterface/qt4/src/tools/tqconfig-minimal.h97
-rw-r--r--tqtinterface/qt4/src/tools/tqconfig-small.h94
-rw-r--r--tqtinterface/qt4/src/tools/tqcriticalsection_p.cpp76
-rw-r--r--tqtinterface/qt4/src/tools/tqcriticalsection_p.h83
-rw-r--r--tqtinterface/qt4/src/tools/tqcstring.cpp4149
-rw-r--r--tqtinterface/qt4/src/tools/tqcstring.h792
-rw-r--r--tqtinterface/qt4/src/tools/tqdatastream.cpp1176
-rw-r--r--tqtinterface/qt4/src/tools/tqdatastream.h353
-rw-r--r--tqtinterface/qt4/src/tools/tqdatetime.cpp2606
-rw-r--r--tqtinterface/qt4/src/tools/tqdatetime.h374
-rw-r--r--tqtinterface/qt4/src/tools/tqdeepcopy.cpp168
-rw-r--r--tqtinterface/qt4/src/tools/tqdeepcopy.h80
-rw-r--r--tqtinterface/qt4/src/tools/tqdict.h123
-rw-r--r--tqtinterface/qt4/src/tools/tqdir.cpp1390
-rw-r--r--tqtinterface/qt4/src/tools/tqdir.h250
-rw-r--r--tqtinterface/qt4/src/tools/tqdir_p.h82
-rw-r--r--tqtinterface/qt4/src/tools/tqdir_unix.cpp302
-rw-r--r--tqtinterface/qt4/src/tools/tqfeatures.h984
-rw-r--r--tqtinterface/qt4/src/tools/tqfile.cpp783
-rw-r--r--tqtinterface/qt4/src/tools/tqfile.h209
-rw-r--r--tqtinterface/qt4/src/tools/tqfile_unix.cpp753
-rw-r--r--tqtinterface/qt4/src/tools/tqfiledefs_p.h67
-rw-r--r--tqtinterface/qt4/src/tools/tqfileinfo.cpp710
-rw-r--r--tqtinterface/qt4/src/tools/tqfileinfo.h157
-rw-r--r--tqtinterface/qt4/src/tools/tqfileinfo_unix.cpp370
-rw-r--r--tqtinterface/qt4/src/tools/tqgarray.cpp830
-rw-r--r--tqtinterface/qt4/src/tools/tqgarray.h134
-rw-r--r--tqtinterface/qt4/src/tools/tqgcache.cpp866
-rw-r--r--tqtinterface/qt4/src/tools/tqgcache.h131
-rw-r--r--tqtinterface/qt4/src/tools/tqgdict.cpp1151
-rw-r--r--tqtinterface/qt4/src/tools/tqgdict.h225
-rw-r--r--tqtinterface/qt4/src/tools/tqgeneric.h46
-rw-r--r--tqtinterface/qt4/src/tools/tqglist.cpp1267
-rw-r--r--tqtinterface/qt4/src/tools/tqglist.h271
-rw-r--r--tqtinterface/qt4/src/tools/tqglobal.cpp927
-rw-r--r--tqtinterface/qt4/src/tools/tqglobal.h1135
-rw-r--r--tqtinterface/qt4/src/tools/tqgpluginmanager.cpp550
-rw-r--r--tqtinterface/qt4/src/tools/tqgpluginmanager_p.h108
-rw-r--r--tqtinterface/qt4/src/tools/tqgvector.cpp598
-rw-r--r--tqtinterface/qt4/src/tools/tqgvector.h124
-rw-r--r--tqtinterface/qt4/src/tools/tqintcache.h124
-rw-r--r--tqtinterface/qt4/src/tools/tqintdict.h119
-rw-r--r--tqtinterface/qt4/src/tools/tqiodevice.cpp769
-rw-r--r--tqtinterface/qt4/src/tools/tqiodevice.h311
-rw-r--r--tqtinterface/qt4/src/tools/tqiodevice.h~310
-rw-r--r--tqtinterface/qt4/src/tools/tqlibrary.cpp442
-rw-r--r--tqtinterface/qt4/src/tools/tqlibrary.h86
-rw-r--r--tqtinterface/qt4/src/tools/tqlibrary_p.h84
-rw-r--r--tqtinterface/qt4/src/tools/tqlibrary_unix.cpp169
-rw-r--r--tqtinterface/qt4/src/tools/tqlocale.cpp6311
-rw-r--r--tqtinterface/qt4/src/tools/tqlocale.h494
-rw-r--r--tqtinterface/qt4/src/tools/tqlocale_p.h131
-rw-r--r--tqtinterface/qt4/src/tools/tqmap.cpp257
-rw-r--r--tqtinterface/qt4/src/tools/tqmap.h946
-rw-r--r--tqtinterface/qt4/src/tools/tqmemarray.h123
-rw-r--r--tqtinterface/qt4/src/tools/tqmutex.h114
-rw-r--r--tqtinterface/qt4/src/tools/tqmutex_p.h73
-rw-r--r--tqtinterface/qt4/src/tools/tqmutex_unix.cpp695
-rw-r--r--tqtinterface/qt4/src/tools/tqmutexpool.cpp155
-rw-r--r--tqtinterface/qt4/src/tools/tqmutexpool_p.h80
-rw-r--r--tqtinterface/qt4/src/tools/tqpair.h109
-rw-r--r--tqtinterface/qt4/src/tools/tqpluginmanager_p.h74
-rw-r--r--tqtinterface/qt4/src/tools/tqptrcollection.cpp183
-rw-r--r--tqtinterface/qt4/src/tools/tqptrcollection.h80
-rw-r--r--tqtinterface/qt4/src/tools/tqptrdict.h118
-rw-r--r--tqtinterface/qt4/src/tools/tqptrlist.h197
-rw-r--r--tqtinterface/qt4/src/tools/tqptrqueue.h94
-rw-r--r--tqtinterface/qt4/src/tools/tqptrstack.h94
-rw-r--r--tqtinterface/qt4/src/tools/tqptrvector.h119
-rw-r--r--tqtinterface/qt4/src/tools/tqregexp.cpp4050
-rw-r--r--tqtinterface/qt4/src/tools/tqregexp.h181
-rw-r--r--tqtinterface/qt4/src/tools/tqsemaphore.cpp255
-rw-r--r--tqtinterface/qt4/src/tools/tqsemaphore.h81
-rw-r--r--tqtinterface/qt4/src/tools/tqsettings.cpp2105
-rw-r--r--tqtinterface/qt4/src/tools/tqsettings.h159
-rw-r--r--tqtinterface/qt4/src/tools/tqsettings_p.h148
-rw-r--r--tqtinterface/qt4/src/tools/tqshared.h58
-rw-r--r--tqtinterface/qt4/src/tools/tqsortedlist.h63
-rw-r--r--tqtinterface/qt4/src/tools/tqstring.cpp8350
-rw-r--r--tqtinterface/qt4/src/tools/tqstring.h1684
-rw-r--r--tqtinterface/qt4/src/tools/tqstringlist.cpp534
-rw-r--r--tqtinterface/qt4/src/tools/tqstringlist.h116
-rw-r--r--tqtinterface/qt4/src/tools/tqstrlist.h175
-rw-r--r--tqtinterface/qt4/src/tools/tqstrvec.h85
-rw-r--r--tqtinterface/qt4/src/tools/tqtextstream.cpp2663
-rw-r--r--tqtinterface/qt4/src/tools/tqtextstream.h343
-rw-r--r--tqtinterface/qt4/src/tools/tqthreadinstance_p.h101
-rw-r--r--tqtinterface/qt4/src/tools/tqthreadstorage.h95
-rw-r--r--tqtinterface/qt4/src/tools/tqthreadstorage_unix.cpp349
-rw-r--r--tqtinterface/qt4/src/tools/tqtl.h325
-rw-r--r--tqtinterface/qt4/src/tools/tqucom.cpp547
-rw-r--r--tqtinterface/qt4/src/tools/tqucom_p.h470
-rw-r--r--tqtinterface/qt4/src/tools/tqunicodetables.cpp13240
-rw-r--r--tqtinterface/qt4/src/tools/tqunicodetables_p.h266
-rw-r--r--tqtinterface/qt4/src/tools/tquuid.cpp421
-rw-r--r--tqtinterface/qt4/src/tools/tquuid.h194
-rw-r--r--tqtinterface/qt4/src/tools/tqvaluelist.h671
-rw-r--r--tqtinterface/qt4/src/tools/tqvaluestack.h67
-rw-r--r--tqtinterface/qt4/src/tools/tqvaluevector.h577
-rw-r--r--tqtinterface/qt4/src/tools/tqwaitcondition.h79
-rw-r--r--tqtinterface/qt4/src/tools/tqwaitcondition_unix.cpp316
-rw-r--r--tqtinterface/qt4/src/tools/tqwinexport.cpp31
-rw-r--r--tqtinterface/qt4/src/tools/tqwinexport.h224
-rw-r--r--tqtinterface/qt4/src/tqmoc/README24
-rw-r--r--tqtinterface/qt4/src/tqmoc/tqmoc.l498
-rw-r--r--tqtinterface/qt4/src/tqmoc/tqmoc.pro65
-rw-r--r--tqtinterface/qt4/src/tqmoc/tqmoc.y3636
-rw-r--r--tqtinterface/qt4/src/tqmoc/tqmoc_lex.cpp3319
-rw-r--r--tqtinterface/qt4/src/tqmoc/tqmoc_yacc.cpp6463
-rw-r--r--tqtinterface/qt4/src/tqmoc/tqmoc_yacc.h185
-rw-r--r--tqtinterface/qt4/src/widgets/qt_widgets.pri139
-rw-r--r--tqtinterface/qt4/src/widgets/tqaction.cpp2145
-rw-r--r--tqtinterface/qt4/src/widgets/tqaction.h220
-rw-r--r--tqtinterface/qt4/src/widgets/tqbutton.cpp1016
-rw-r--r--tqtinterface/qt4/src/widgets/tqbutton.h235
-rw-r--r--tqtinterface/qt4/src/widgets/tqbuttongroup.cpp691
-rw-r--r--tqtinterface/qt4/src/widgets/tqbuttongroup.h122
-rw-r--r--tqtinterface/qt4/src/widgets/tqcheckbox.cpp368
-rw-r--r--tqtinterface/qt4/src/widgets/tqcheckbox.h97
-rw-r--r--tqtinterface/qt4/src/widgets/tqcombobox.cpp2318
-rw-r--r--tqtinterface/qt4/src/widgets/tqcombobox.h207
-rw-r--r--tqtinterface/qt4/src/widgets/tqdatetimeedit.cpp2845
-rw-r--r--tqtinterface/qt4/src/widgets/tqdatetimeedit.h299
-rw-r--r--tqtinterface/qt4/src/widgets/tqdial.cpp976
-rw-r--r--tqtinterface/qt4/src/widgets/tqdial.h154
-rw-r--r--tqtinterface/qt4/src/widgets/tqdialogbuttons.cpp456
-rw-r--r--tqtinterface/qt4/src/widgets/tqdialogbuttons_p.h119
-rw-r--r--tqtinterface/qt4/src/widgets/tqdockarea.cpp1340
-rw-r--r--tqtinterface/qt4/src/widgets/tqdockarea.h199
-rw-r--r--tqtinterface/qt4/src/widgets/tqdockwindow.cpp2126
-rw-r--r--tqtinterface/qt4/src/widgets/tqdockwindow.h238
-rw-r--r--tqtinterface/qt4/src/widgets/tqeffects.cpp677
-rw-r--r--tqtinterface/qt4/src/widgets/tqeffects_p.h81
-rw-r--r--tqtinterface/qt4/src/widgets/tqframe.cpp754
-rw-r--r--tqtinterface/qt4/src/widgets/tqframe.h172
-rw-r--r--tqtinterface/qt4/src/widgets/tqgrid.cpp137
-rw-r--r--tqtinterface/qt4/src/widgets/tqgrid.h78
-rw-r--r--tqtinterface/qt4/src/widgets/tqgridview.cpp374
-rw-r--r--tqtinterface/qt4/src/widgets/tqgridview.h140
-rw-r--r--tqtinterface/qt4/src/widgets/tqgroupbox.cpp989
-rw-r--r--tqtinterface/qt4/src/widgets/tqgroupbox.h168
-rw-r--r--tqtinterface/qt4/src/widgets/tqhbox.cpp145
-rw-r--r--tqtinterface/qt4/src/widgets/tqhbox.h77
-rw-r--r--tqtinterface/qt4/src/widgets/tqhbuttongroup.cpp94
-rw-r--r--tqtinterface/qt4/src/widgets/tqhbuttongroup.h68
-rw-r--r--tqtinterface/qt4/src/widgets/tqheader.cpp2049
-rw-r--r--tqtinterface/qt4/src/widgets/tqheader.h220
-rw-r--r--tqtinterface/qt4/src/widgets/tqhgroupbox.cpp93
-rw-r--r--tqtinterface/qt4/src/widgets/tqhgroupbox.h68
-rw-r--r--tqtinterface/qt4/src/widgets/tqlabel.cpp1194
-rw-r--r--tqtinterface/qt4/src/widgets/tqlabel.h177
-rw-r--r--tqtinterface/qt4/src/widgets/tqlcdnumber.cpp1170
-rw-r--r--tqtinterface/qt4/src/widgets/tqlcdnumber.h147
-rw-r--r--tqtinterface/qt4/src/widgets/tqlineedit.cpp2848
-rw-r--r--tqtinterface/qt4/src/widgets/tqlineedit.h234
-rw-r--r--tqtinterface/qt4/src/widgets/tqlistbox.cpp4701
-rw-r--r--tqtinterface/qt4/src/widgets/tqlistbox.h436
-rw-r--r--tqtinterface/qt4/src/widgets/tqlistview.cpp8194
-rw-r--r--tqtinterface/qt4/src/widgets/tqlistview.h610
-rw-r--r--tqtinterface/qt4/src/widgets/tqmainwindow.cpp2644
-rw-r--r--tqtinterface/qt4/src/widgets/tqmainwindow.h262
-rw-r--r--tqtinterface/qt4/src/widgets/tqmenubar.cpp1673
-rw-r--r--tqtinterface/qt4/src/widgets/tqmenubar.h206
-rw-r--r--tqtinterface/qt4/src/widgets/tqmenudata.cpp1606
-rw-r--r--tqtinterface/qt4/src/widgets/tqmenudata.h291
-rw-r--r--tqtinterface/qt4/src/widgets/tqmultilineedit.cpp541
-rw-r--r--tqtinterface/qt4/src/widgets/tqmultilineedit.h144
-rw-r--r--tqtinterface/qt4/src/widgets/tqpopupmenu.cpp2852
-rw-r--r--tqtinterface/qt4/src/widgets/tqpopupmenu.h201
-rw-r--r--tqtinterface/qt4/src/widgets/tqprogressbar.cpp408
-rw-r--r--tqtinterface/qt4/src/widgets/tqprogressbar.h150
-rw-r--r--tqtinterface/qt4/src/widgets/tqpushbutton.cpp760
-rw-r--r--tqtinterface/qt4/src/widgets/tqpushbutton.h150
-rw-r--r--tqtinterface/qt4/src/widgets/tqradiobutton.cpp362
-rw-r--r--tqtinterface/qt4/src/widgets/tqradiobutton.h92
-rw-r--r--tqtinterface/qt4/src/widgets/tqrangecontrol.cpp565
-rw-r--r--tqtinterface/qt4/src/widgets/tqrangecontrol.h195
-rw-r--r--tqtinterface/qt4/src/widgets/tqscrollbar.cpp1072
-rw-r--r--tqtinterface/qt4/src/widgets/tqscrollbar.h198
-rw-r--r--tqtinterface/qt4/src/widgets/tqscrollview.cpp2851
-rw-r--r--tqtinterface/qt4/src/widgets/tqscrollview.h270
-rw-r--r--tqtinterface/qt4/src/widgets/tqslider.cpp921
-rw-r--r--tqtinterface/qt4/src/widgets/tqslider.h200
-rw-r--r--tqtinterface/qt4/src/widgets/tqspinbox.cpp1116
-rw-r--r--tqtinterface/qt4/src/widgets/tqspinbox.h173
-rw-r--r--tqtinterface/qt4/src/widgets/tqspinwidget.cpp465
-rw-r--r--tqtinterface/qt4/src/widgets/tqsplashscreen.cpp271
-rw-r--r--tqtinterface/qt4/src/widgets/tqsplashscreen.h81
-rw-r--r--tqtinterface/qt4/src/widgets/tqsplitter.cpp1427
-rw-r--r--tqtinterface/qt4/src/widgets/tqsplitter.h170
-rw-r--r--tqtinterface/qt4/src/widgets/tqstatusbar.cpp526
-rw-r--r--tqtinterface/qt4/src/widgets/tqstatusbar.h97
-rw-r--r--tqtinterface/qt4/src/widgets/tqsyntaxhighlighter.cpp221
-rw-r--r--tqtinterface/qt4/src/widgets/tqsyntaxhighlighter.h81
-rw-r--r--tqtinterface/qt4/src/widgets/tqsyntaxhighlighter_p.h97
-rw-r--r--tqtinterface/qt4/src/widgets/tqtabbar.cpp1368
-rw-r--r--tqtinterface/qt4/src/widgets/tqtabbar.h187
-rw-r--r--tqtinterface/qt4/src/widgets/tqtabwidget.cpp1097
-rw-r--r--tqtinterface/qt4/src/widgets/tqtabwidget.h163
-rw-r--r--tqtinterface/qt4/src/widgets/tqtextbrowser.cpp555
-rw-r--r--tqtinterface/qt4/src/widgets/tqtextbrowser.h108
-rw-r--r--tqtinterface/qt4/src/widgets/tqtextedit.cpp7367
-rw-r--r--tqtinterface/qt4/src/widgets/tqtextedit.h617
-rw-r--r--tqtinterface/qt4/src/widgets/tqtextview.cpp103
-rw-r--r--tqtinterface/qt4/src/widgets/tqtextview.h75
-rw-r--r--tqtinterface/qt4/src/widgets/tqtitlebar.cpp671
-rw-r--r--tqtinterface/qt4/src/widgets/tqtitlebar_p.h140
-rw-r--r--tqtinterface/qt4/src/widgets/tqtoolbar.cpp818
-rw-r--r--tqtinterface/qt4/src/widgets/tqtoolbar.h118
-rw-r--r--tqtinterface/qt4/src/widgets/tqtoolbox.cpp663
-rw-r--r--tqtinterface/qt4/src/widgets/tqtoolbox.h161
-rw-r--r--tqtinterface/qt4/src/widgets/tqtoolbutton.cpp1041
-rw-r--r--tqtinterface/qt4/src/widgets/tqtoolbutton.h193
-rw-r--r--tqtinterface/qt4/src/widgets/tqtooltip.cpp1268
-rw-r--r--tqtinterface/qt4/src/widgets/tqtooltip.h150
-rw-r--r--tqtinterface/qt4/src/widgets/tqvalidator.cpp672
-rw-r--r--tqtinterface/qt4/src/widgets/tqvalidator.h173
-rw-r--r--tqtinterface/qt4/src/widgets/tqvbox.cpp71
-rw-r--r--tqtinterface/qt4/src/widgets/tqvbox.h66
-rw-r--r--tqtinterface/qt4/src/widgets/tqvbuttongroup.cpp92
-rw-r--r--tqtinterface/qt4/src/widgets/tqvbuttongroup.h70
-rw-r--r--tqtinterface/qt4/src/widgets/tqvgroupbox.cpp91
-rw-r--r--tqtinterface/qt4/src/widgets/tqvgroupbox.h69
-rw-r--r--tqtinterface/qt4/src/widgets/tqwhatsthis.cpp1004
-rw-r--r--tqtinterface/qt4/src/widgets/tqwhatsthis.h81
-rw-r--r--tqtinterface/qt4/src/widgets/tqwidgetinterface_p.h143
-rw-r--r--tqtinterface/qt4/src/widgets/tqwidgetplugin.cpp729
-rw-r--r--tqtinterface/qt4/src/widgets/tqwidgetplugin.h121
-rw-r--r--tqtinterface/qt4/src/widgets/tqwidgetresizehandler.cpp516
-rw-r--r--tqtinterface/qt4/src/widgets/tqwidgetresizehandler_p.h138
-rw-r--r--tqtinterface/qt4/src/widgets/tqwidgetstack.cpp1183
-rw-r--r--tqtinterface/qt4/src/widgets/tqwidgetstack.h235
-rw-r--r--tqtinterface/qt4/src/workspace/qt_workspace.pri6
-rw-r--r--tqtinterface/qt4/src/workspace/tqworkspace.cpp3033
-rw-r--r--tqtinterface/qt4/src/workspace/tqworkspace.h170
-rw-r--r--tqtinterface/qt4/src/xml/qt_xml.pri10
-rw-r--r--tqtinterface/qt4/src/xml/tqdom.cpp7092
-rw-r--r--tqtinterface/qt4/src/xml/tqdom.h678
-rw-r--r--tqtinterface/qt4/src/xml/tqsvgdevice.cpp1591
-rw-r--r--tqtinterface/qt4/src/xml/tqsvgdevice_p.h140
-rw-r--r--tqtinterface/qt4/src/xml/tqxml.cpp7635
-rw-r--r--tqtinterface/qt4/src/xml/tqxml.h531
1141 files changed, 830445 insertions, 0 deletions
diff --git a/tqtinterface/qt4/src/.obj/README b/tqtinterface/qt4/src/.obj/README
new file mode 100644
index 0000000..c24e158
--- /dev/null
+++ b/tqtinterface/qt4/src/.obj/README
@@ -0,0 +1 @@
+This directory tqcontains only generated object files.
diff --git a/tqtinterface/qt4/src/.tmp/README b/tqtinterface/qt4/src/.tmp/README
new file mode 100644
index 0000000..e4a8beb
--- /dev/null
+++ b/tqtinterface/qt4/src/.tmp/README
@@ -0,0 +1 @@
+This directory tqcontains only generated files.
diff --git a/tqtinterface/qt4/src/3rdparty/README b/tqtinterface/qt4/src/3rdparty/README
new file mode 100644
index 0000000..993b8db
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/README
@@ -0,0 +1,17 @@
+The libraries included here are the original packages, unpacked, and
+with their version number removed from the directory name (for version
+information, see the README files in the directories). The following
+have been removed:
+
+ libjpeg - some source files, images, Makefiles, manual pages
+ libpng/contrib - a collection of examples and test-suite
+ zlib/contrib - a collection of non-zlib code
+ zlib/amiga - zlib for a platform not supported by Qt
+ zlib/as400 - zlib for a platform not supported by Qt
+ zlib/msdos - zlib for a platform not supported by Qt
+ zlib/old - zlib for a platform not supported by Qt
+ zlib/qnx - zlib packaging
+ libmng/contrib - ?
+ libmng/Unix - ?
+
+Some patches are applied from time to time.
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/README b/tqtinterface/qt4/src/3rdparty/libjpeg/README
new file mode 100644
index 0000000..c3cd473
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/README
@@ -0,0 +1,385 @@
+The Independent JPEG Group's JPEG software
+==========================================
+
+README for release 6b of 27-Mar-1998
+====================================
+
+This distribution tqcontains the sixth public release of the Independent JPEG
+Group's free JPEG software. You are welcome to redistribute this software and
+to use it for any purpose, subject to the conditions under LEGAL ISSUES, below.
+
+Serious users of this software (particularly those incorporating it into
+larger programs) should contact IJG at jpeg-info@uunet.uu.net to be added to
+our electronic mailing list. Mailing list members are notified of updates
+and have a chance to participate in technical discussions, etc.
+
+This software is the work of Tom Lane, Philip Gladstone, Jim Boucher,
+Lee Crocker, Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi,
+Guido Vollbeding, Ge' Weijers, and other members of the Independent JPEG
+Group.
+
+IJG is not affiliated with the official ISO JPEG standards committee.
+
+
+DOCUMENTATION ROADMAP
+=====================
+
+This file tqcontains the following sections:
+
+OVERVIEW General description of JPEG and the IJG software.
+LEGAL ISSUES Copyright, lack of warranty, terms of distribution.
+REFERENCES Where to learn more about JPEG.
+ARCHIVE LOCATIONS Where to tqfind newer versions of this software.
+RELATED SOFTWARE Other stuff you should get.
+FILE FORMAT WARS Software *not* to get.
+TO DO Plans for future IJG releases.
+
+Other documentation files in the distribution are:
+
+User documentation:
+ install.doc How to configure and install the IJG software.
+ usage.doc Usage instructions for cjpeg, djpeg, jpegtran,
+ rdjpgcom, and wrjpgcom.
+ *.1 Unix-style man pages for programs (same info as usage.doc).
+ wizard.doc Advanced usage instructions for JPEG wizards only.
+ change.log Version-to-version change highlights.
+Programmer and internal documentation:
+ libjpeg.doc How to use the JPEG library in your own programs.
+ example.c Sample code for calling the JPEG library.
+ structure.doc Overview of the JPEG library's internal structure.
+ filelist.doc Road map of IJG files.
+ coderules.doc Coding style rules --- please read if you contribute code.
+
+Please read at least the files install.doc and usage.doc. Useful information
+can also be found in the JPEG FAQ (Frequently Asked Questions) article. See
+ARCHIVE LOCATIONS below to tqfind out where to obtain the FAQ article.
+
+If you want to understand how the JPEG code works, we suggest reading one or
+more of the REFERENCES, then looking at the documentation files (in roughly
+the order listed) before diving into the code.
+
+
+OVERVIEW
+========
+
+This package tqcontains C software to implement JPEG image compression and
+decompression. JPEG (pronounced "jay-peg") is a standardized compression
+method for full-color and gray-scale images. JPEG is intended for compressing
+"real-world" scenes; line drawings, cartoons and other non-realistic images
+are not its strong suit. JPEG is lossy, meaning that the output image is not
+exactly identical to the input image. Hence you must not use JPEG if you
+have to have identical output bits. However, on typical photographic images,
+very good compression levels can be obtained with no visible change, and
+remarkably high compression levels are possible if you can tolerate a
+low-quality image. For more details, see the references, or just experiment
+with various compression settings.
+
+This software implements JPEG baseline, extended-sequential, and progressive
+compression processes. Provision is made for supporting all variants of these
+processes, although some uncommon parameter settings aren't implemented yet.
+For legal reasons, we are not distributing code for the arithmetic-coding
+variants of JPEG; see LEGAL ISSUES. We have made no provision for supporting
+the hierarchical or lossless processes defined in the standard.
+
+We provide a set of library routines for reading and writing JPEG image files,
+plus two sample applications "cjpeg" and "djpeg", which use the library to
+perform conversion between JPEG and some other popular image file formats.
+The library is intended to be reused in other applications.
+
+In order to support file conversion and viewing software, we have included
+considerable functionality beyond the bare JPEG coding/decoding capability;
+for example, the color quantization modules are not strictly part of JPEG
+decoding, but they are essential for output to colormapped file formats or
+colormapped displays. These extra functions can be compiled out of the
+library if not required for a particular application. We have also included
+"jpegtran", a utility for lossless transcoding between different JPEG
+processes, and "rdjpgcom" and "wrjpgcom", two simple applications for
+inserting and extracting textual comments in JFIF files.
+
+The emphasis in designing this software has been on achieving portability and
+flexibility, while also making it fast enough to be useful. In particular,
+the software is not intended to be read as a tutorial on JPEG. (See the
+REFERENCES section for introductory material.) Rather, it is intended to
+be reliable, portable, industrial-strength code. We do not claim to have
+achieved that goal in every aspect of the software, but we strive for it.
+
+We welcome the use of this software as a component of commercial products.
+No royalty is required, but we do ask for an acknowledgement in product
+documentation, as described under LEGAL ISSUES.
+
+
+LEGAL ISSUES
+============
+
+In plain English:
+
+1. We don't promise that this software works. (But if you tqfind any bugs,
+ please let us know!)
+2. You can use this software for whatever you want. You don't have to pay us.
+3. You may not pretend that you wrote this software. If you use it in a
+ program, you must acknowledge somewhere in your documentation that
+ you've used the IJG code.
+
+In legalese:
+
+The authors make NO WARRANTY or representation, either express or implied,
+with respect to this software, its quality, accuracy, merchantability, or
+fitness for a particular purpose. This software is provided "AS IS", and you,
+its user, assume the entire risk as to its quality and accuracy.
+
+This software is copyright (C) 1991-1998, Thomas G. Lane.
+All Rights Reserved except as specified below.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+software (or portions thereof) for any purpose, without fee, subject to these
+conditions:
+(1) If any part of the source code for this software is distributed, then this
+README file must be included, with this copyright and no-warranty notice
+unaltered; and any additions, deletions, or changes to the original files
+must be clearly indicated in accompanying documentation.
+(2) If only executable code is distributed, then the accompanying
+documentation must state that "this software is based in part on the work of
+the Independent JPEG Group".
+(3) Permission for use of this software is granted only if the user accepts
+full responsibility for any undesirable consequences; the authors accept
+NO LIABILITY for damages of any kind.
+
+These conditions apply to any software derived from or based on the IJG code,
+not just to the unmodified library. If you use our work, you ought to
+acknowledge us.
+
+Permission is NOT granted for the use of any IJG author's name or company name
+in advertising or publicity relating to this software or products derived from
+it. This software may be referred to only as "the Independent JPEG Group's
+software".
+
+We specifically permit and encourage the use of this software as the basis of
+commercial products, provided that all warranty or liability claims are
+assumed by the product vendor.
+
+
+ansi2knr.c is included in this distribution by permission of L. Peter Deutsch,
+sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA.
+ansi2knr.c is NOT covered by the above copyright and conditions, but instead
+by the usual distribution terms of the Free Software Foundation; principally,
+that you must include source code if you redistribute it. (See the file
+ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part
+of any program generated from the IJG code, this does not limit you more than
+the foregoing paragraphs do.
+
+The Unix configuration script "configure" was produced with GNU Autoconf.
+It is copyright by the Free Software Foundation but is freely distributable.
+The same holds for its supporting scripts (config.guess, config.sub,
+ltconfig, ltmain.sh). Another support script, install-sh, is copyright
+by M.I.T. but is also freely distributable.
+
+It appears that the arithmetic coding option of the JPEG spec is covered by
+patents owned by IBM, AT&T, and Mitsubishi. Hence arithmetic coding cannot
+legally be used without obtaining one or more licenses. For this reason,
+support for arithmetic coding has been removed from the free JPEG software.
+(Since arithmetic coding provides only a marginal gain over the unpatented
+Huffman mode, it is unlikely that very many implementations will support it.)
+So far as we are aware, there are no patent restrictions on the remaining
+code.
+
+The IJG distribution formerly included code to read and write GIF files.
+To avoid entanglement with the Unisys LZW patent, GIF reading support has
+been removed altogether, and the GIF writer has been simplified to produce
+"uncompressed GIFs". This technique does not use the LZW algorithm; the
+resulting GIF files are larger than usual, but are readable by all standard
+GIF decoders.
+
+We are required to state that
+ "The Graphics Interchange Format(c) is the Copyright property of
+ CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ CompuServe Incorporated."
+
+
+REFERENCES
+==========
+
+We highly recommend reading one or more of these references before trying to
+understand the innards of the JPEG software.
+
+The best short technical introduction to the JPEG compression algorithm is
+ Wallace, Gregory K. "The JPEG Still Picture Compression Standard",
+ Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44.
+(Adjacent articles in that issue discuss MPEG motion picture compression,
+applications of JPEG, and related topics.) If you don't have the CACM issue
+handy, a PostScript file containing a revised version of Wallace's article is
+available at ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz. The file (actually
+a preprint for an article that appeared in IEEE Trans. Consumer Electronics)
+omits the sample images that appeared in CACM, but it includes corrections
+and some added material. Note: the Wallace article is copyright ACM and IEEE,
+and it may not be used for commercial purposes.
+
+A somewhat less technical, more leisurely introduction to JPEG can be found in
+"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by
+M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides
+good explanations and example C code for a multitude of compression methods
+including JPEG. It is an excellent source if you are comfortable reading C
+code but don't know much about data compression in general. The book's JPEG
+sample code is far from industrial-strength, but when you are ready to look
+at a full implementation, you've got one here...
+
+The best full description of JPEG is the textbook "JPEG Still Image Data
+Compression Standard" by William B. Pennebaker and Joan L. Mitchell, published
+by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. Price US$59.95, 638 pp.
+The book includes the complete text of the ISO JPEG standards (DIS 10918-1
+and draft DIS 10918-2). This is by far the most complete exposition of JPEG
+in existence, and we highly recommend it.
+
+The JPEG standard itself is not available electronically; you must order a
+paper copy through ISO or ITU. (Unless you feel a need to own a certified
+official copy, we recommend buying the Pennebaker and Mitchell book instead;
+it's much cheaper and includes a great deal of useful explanatory material.)
+In the USA, copies of the standard may be ordered from ANSI Sales at (212)
+642-4900, or from Global Engineering Documents at (800) 854-7179. (ANSI
+doesn't take credit card orders, but Global does.) It's not cheap: as of
+1992, ANSI was charging $95 for Part 1 and $47 for Part 2, plus 7%
+shipping/handling. The standard is divided into two parts, Part 1 being the
+actual specification, while Part 2 covers compliance testing methods. Part 1
+is titled "Digital Compression and Coding of Continuous-tone Still Images,
+Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS
+10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of
+Continuous-tone Still Images, Part 2: Compliance testing" and has document
+numbers ISO/IEC IS 10918-2, ITU-T T.83.
+
+Some extensions to the original JPEG standard are defined in JPEG Part 3,
+a newer ISO standard numbered ISO/IEC IS 10918-3 and ITU-T T.84. IJG
+currently does not support any Part 3 extensions.
+
+The JPEG standard does not specify all details of an interchangeable file
+format. For the omitted details we follow the "JFIF" conventions, revision
+1.02. A copy of the JFIF spec is available from:
+ Literature Department
+ C-Cube Microsystems, Inc.
+ 1778 McCarthy Blvd.
+ Milpitas, CA 95035
+ phone (408) 944-6300, fax (408) 944-6314
+A PostScript version of this document is available by FTP at
+ftp://ftp.uu.net/graphics/jpeg/jfif.ps.gz. There is also a plain text
+version at ftp://ftp.uu.net/graphics/jpeg/jfif.txt.gz, but it is missing
+the figures.
+
+The TIFF 6.0 file format specification can be obtained by FTP from
+ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme
+found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems.
+IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6).
+Instead, we recommend the JPEG design proposed by TIFF Technical Note #2
+(Compression tag 7). Copies of this Note can be obtained from ftp.sgi.com or
+from ftp://ftp.uu.net/graphics/jpeg/. It is expected that the next revision
+of the TIFF spec will tqreplace the 6.0 JPEG design with the Note's design.
+Although IJG's own code does not support TIFF/JPEG, the free libtiff library
+uses our library to implement TIFF/JPEG per the Note. libtiff is available
+from ftp://ftp.sgi.com/graphics/tiff/.
+
+
+ARCHIVE LOCATIONS
+=================
+
+The "official" archive site for this software is ftp.uu.net (Internet
+address 192.48.96.9). The most recent released version can always be found
+there in directory graphics/jpeg. This particular version will be archived
+as ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz. If you don't have
+direct Internet access, UUNET's archives are also available via UUCP; contact
+help@uunet.uu.net for information on retrieving files that way.
+
+Numerous Internet sites maintain copies of the UUNET files. However, only
+ftp.uu.net is guaranteed to have the latest official version.
+
+You can also obtain this software in DOS-compatible "zip" archive format from
+the SimTel archives (ftp://ftp.simtel.net/pub/simtelnet/msdos/graphics/), or
+on CompuServe in the Graphics Support forum (GO CIS:GRAPHSUP), library 12
+"JPEG Tools". Again, these versions may sometimes lag behind the ftp.uu.net
+release.
+
+The JPEG FAQ (Frequently Asked Questions) article is a useful source of
+general information about JPEG. It is updated constantly and therefore is
+not included in this distribution. The FAQ is posted every two weeks to
+Usenet newsgroups comp.graphics.misc, news.answers, and other groups.
+It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/
+and other news.answers archive sites, including the official news.answers
+archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/.
+If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu
+with body
+ send usenet/news.answers/jpeg-faq/part1
+ send usenet/news.answers/jpeg-faq/part2
+
+
+RELATED SOFTWARE
+================
+
+Numerous viewing and image manipulation programs now support JPEG. (Quite a
+few of them use this library to do so.) The JPEG FAQ described above lists
+some of the more popular free and shareware viewers, and tells where to
+obtain them on Internet.
+
+If you are on a Unix machine, we highly recommend Jef Poskanzer's free
+PBMPLUS software, which provides many useful operations on PPM-format image
+files. In particular, it can convert PPM images to and from a wide range of
+other formats, thus making cjpeg/djpeg considerably more useful. The latest
+version is distributed by the NetPBM group, and is available from numerous
+sites, notably ftp://wuarchive.wustl.edu/graphics/graphics/packages/NetPBM/.
+Unfortunately PBMPLUS/NETPBM is not nearly as portable as the IJG software is;
+you are likely to have difficulty making it work on any non-Unix machine.
+
+A different free JPEG implementation, written by the PVRG group at Stanford,
+is available from ftp://havefun.stanford.edu/pub/jpeg/. This program
+is designed for research and experimentation rather than production use;
+it is slower, harder to use, and less portable than the IJG code, but it
+is easier to read and modify. Also, the PVRG code supports lossless JPEG,
+which we do not. (On the other hand, it doesn't do progressive JPEG.)
+
+
+FILE FORMAT WARS
+================
+
+Some JPEG programs produce files that are not compatible with our library.
+The root of the problem is that the ISO JPEG committee failed to specify a
+concrete file format. Some vendors "filled in the blanks" on their own,
+creating proprietary formats that no one else could read. (For example, none
+of the early commercial JPEG implementations for the Macintosh were able to
+exchange compressed files.)
+
+The file format we have adopted is called JFIF (see REFERENCES). This format
+has been agreed to by a number of major commercial JPEG vendors, and it has
+become the de facto standard. JFIF is a minimal or "low end" representation.
+We recommend the use of TIFF/JPEG (TIFF revision 6.0 as modified by TIFF
+Technical Note #2) for "high end" applications that need to record a lot of
+additional data about an image. TIFF/JPEG is fairly new and not yet widely
+supported, unfortunately.
+
+The upcoming JPEG Part 3 standard defines a file format called SPIFF.
+SPIFF is interoperable with JFIF, in the sense that most JFIF decoders should
+be able to read the most common variant of SPIFF. SPIFF has some technical
+advantages over JFIF, but its major claim to fame is simply that it is an
+official standard rather than an informal one. At this point it is unclear
+whether SPIFF will supersede JFIF or whether JFIF will remain the de-facto
+standard. IJG intends to support SPIFF once the standard is frozen, but we
+have not decided whether it should become our default output format or not.
+(In any case, our decoder will remain capable of reading JFIF indefinitely.)
+
+Various proprietary file formats incorporating JPEG compression also exist.
+We have little or no sympathy for the existence of these formats. Indeed,
+one of the original reasons for developing this free software was to help
+force convergence on common, open format standards for JPEG files. Don't
+use a proprietary file format!
+
+
+TO DO
+=====
+
+The major thrust for v7 will probably be improvement of visual quality.
+The current method for scaling the quantization tables is known not to be
+very good at low Q values. We also intend to investigate block boundary
+smoothing, "poor man's variable quantization", and other means of improving
+quality-vs-file-size performance without sacrificing compatibility.
+
+In future versions, we are considering supporting some of the upcoming JPEG
+Part 3 extensions --- principally, variable quantization and the SPIFF file
+format.
+
+As always, speeding things up is of great interest.
+
+Please send bug reports, offers of help, etc. to jpeg-info@uunet.uu.net.
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/change.log b/tqtinterface/qt4/src/3rdparty/libjpeg/change.log
new file mode 100644
index 0000000..74102c0
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/change.log
@@ -0,0 +1,217 @@
+CHANGE LOG for Independent JPEG Group's JPEG software
+
+
+Version 6b 27-Mar-1998
+-----------------------
+
+jpegtran has new features for lossless image transformations (rotation
+and flipping) as well as "lossless" reduction to grayscale.
+
+jpegtran now copies comments by default; it has a -copy switch to enable
+copying all APPn blocks as well, or to suppress comments. (Formerly it
+always suppressed comments and APPn blocks.) jpegtran now also preserves
+JFIF version and resolution information.
+
+New decompressor library feature: COM and APPn markers found in the input
+file can be saved in memory for later use by the application. (Before,
+you had to code this up yourself with a custom marker processor.)
+
+There is an unused field "void * client_data" now in compress and decompress
+parameter structs; this may be useful in some applications.
+
+JFIF version number information is now saved by the decoder and accepted by
+the encoder. jpegtran uses this to copy the source file's version number,
+to ensure "jpegtran -copy all" won't create bogus files that contain JFXX
+extensions but claim to be version 1.01. Applications that generate their
+own JFXX extension markers also (finally) have a supported way to cause the
+encoder to emit JFIF version number 1.02.
+
+djpeg's trace mode reports JFIF 1.02 thumbnail images as such, rather
+than as unknown APP0 markers.
+
+In -verbose mode, djpeg and rdjpgcom will try to print the contents of
+APP12 markers as text. Some digital cameras store useful text information
+in APP12 markers.
+
+Handling of truncated data streams is more robust: blocks beyond the one in
+which the error occurs will be output as uniform gray, or left unchanged
+if decoding a progressive JPEG. The appearance no longer depends on the
+Huffman tables being used.
+
+Huffman tables are checked for validity much more carefully than before.
+
+To avoid the Unisys LZW patent, djpeg's GIF output capability has been
+changed to produce "uncompressed GIFs", and cjpeg's GIF input capability
+has been removed altogether. We're not happy about it either, but there
+seems to be no good alternative.
+
+The configure script now supports building libjpeg as a shared library
+on many flavors of Unix (all the ones that GNU libtool knows how to
+build shared libraries for). Use "./configure --enable-shared" to
+try this out.
+
+New jconfig file and makefiles for Microsoft Visual C++ and Developer Studio.
+Also, a jconfig file and a build script for Metrowerks CodeWarrior
+on Apple Macintosh. makefile.dj has been updated for DJGPP v2, and there
+are miscellaneous other minor improvements in the makefiles.
+
+jmemmac.c now knows how to create temporary files following Mac System 7
+conventions.
+
+djpeg's -map switch is now able to read raw-format PPM files reliably.
+
+cjpeg -progressive -restart no longer generates any unnecessary DRI markers.
+
+Multiple calls to jpeg_simple_progression for a single JPEG object
+no longer leak memory.
+
+
+Version 6a 7-Feb-96
+--------------------
+
+Library initialization sequence modified to detect version mismatches
+and struct field packing mismatches between library and calling application.
+This change requires applications to be recompiled, but does not require
+any application source code change.
+
+All routine declarations changed to the style "GLOBAL(type) name ...",
+that is, GLOBAL, LOCAL, METHODDEF, EXTERN are now macros taking the
+routine's return type as an argument. This makes it possible to add
+Microsoft-style linkage keywords to all the routines by changing just
+these macros. Note that any application code that was using these macros
+will have to be changed.
+
+DCT coefficient quantization tables are now stored in normal array order
+rather than zigzag order. Application code that calls jpeg_add_quant_table,
+or otherwise manipulates quantization tables directly, will need to be
+changed. If you need to make such code work with either older or newer
+versions of the library, a test like "#if JPEG_LIB_VERSION >= 61" is
+recommended.
+
+djpeg's trace capability now dumps DQT tables in natural order, not zigzag
+order. This allows the trace output to be made into a "-qtables" file
+more easily.
+
+New system-dependent memory manager module for use on Apple Macintosh.
+
+Fix bug in cjpeg's -smooth option: last one or two scanlines would be
+duplicates of the prior line unless the image height mod 16 was 1 or 2.
+
+Repair minor problems in VMS, BCC, MC6 makefiles.
+
+New configure script based on latest GNU Autoconf.
+
+Correct the list of include files needed by MetroWerks C for ccommand().
+
+Numerous small documentation updates.
+
+
+Version 6 2-Aug-95
+-------------------
+
+Progressive JPEG support: library can read and write full progressive JPEG
+files. A "buffered image" mode supports incremental decoding for on-the-fly
+display of progressive images. Simply recompiling an existing IJG-v5-based
+decoder with v6 should allow it to read progressive files, though of course
+without any special progressive display.
+
+New "jpegtran" application performs lossless transcoding between different
+JPEG formats; primarily, it can be used to convert baseline to progressive
+JPEG and vice versa. In support of jpegtran, the library now allows lossless
+reading and writing of JPEG files as DCT coefficient arrays. This ability
+may be of use in other applications.
+
+Notes for programmers:
+* We changed jpeg_start_decompress() to be able to suspend; this makes all
+decoding modes available to suspending-input applications. However,
+existing applications that use suspending input will need to be changed
+to check the return value from jpeg_start_decompress(). You don't need to
+do anything if you don't use a suspending data source.
+* We changed the interface to the virtual array routines: access_virt_array
+routines now take a count of the number of rows to access this time. The
+last parameter to request_virt_array routines is now interpreted as the
+maximum number of rows that may be accessed at once, but not necessarily
+the height of every access.
+
+
+Version 5b 15-Mar-95
+---------------------
+
+Correct bugs with grayscale images having v_samp_factor > 1.
+
+jpeg_write_raw_data() now supports output suspension.
+
+Correct bugs in "configure" script for case of compiling in
+a directory other than the one containing the source files.
+
+Repair bug in jquant1.c: sometimes didn't use as many colors as it could.
+
+Borland C makefile and jconfig file work under either MS-DOS or OS/2.
+
+Miscellaneous improvements to documentation.
+
+
+Version 5a 7-Dec-94
+--------------------
+
+Changed color conversion roundoff behavior so that grayscale values are
+represented exactly. (This causes test image files to change.)
+
+Make ordered dither use 16x16 instead of 4x4 pattern for a small quality
+improvement.
+
+New configure script based on latest GNU Autoconf.
+Fix configure script to handle CFLAGS correctly.
+Rename *.auto files to *.cfg, so that configure script still works if
+file names have been truncated for DOS.
+
+Fix bug in rdbmp.c: didn't allow for extra data between header and image.
+
+Modify rdppm.c/wrppm.c to handle 2-byte raw PPM/PGM formats for 12-bit data.
+
+Fix several bugs in rdrle.c.
+
+NEED_SHORT_EXTERNAL_NAMES option was broken.
+
+Revise jerror.h/jerror.c for more flexibility in message table.
+
+Repair oversight in jmemname.c NO_MKTEMP case: file could be there
+but unreadable.
+
+
+Version 5 24-Sep-94
+--------------------
+
+Version 5 represents a nearly complete redesign and rewrite of the IJG
+software. Major user-visible changes include:
+ * Automatic configuration simplifies installation for most Unix systems.
+ * A range of speed vs. image quality tradeoffs are supported.
+ This includes resizing of an image during decompression: scaling down
+ by a factor of 1/2, 1/4, or 1/8 is handled very efficiently.
+ * New programs rdjpgcom and wrjpgcom allow insertion and extraction
+ of text comments in a JPEG file.
+
+The application programmer's interface to the library has changed completely.
+Notable improvements include:
+ * We have eliminated the use of callback routines for handling the
+ uncompressed image data. The application now sees the library as a
+ set of routines that it calls to read or write image data on a
+ scanline-by-scanline basis.
+ * The application image data is represented in a conventional interleaved-
+ pixel format, rather than as a separate array for each color channel.
+ This can save a copying step in many programs.
+ * The handling of compressed data has been cleaned up: the application can
+ supply routines to source or sink the compressed data. It is possible to
+ suspend processing on source/sink buffer overrun, although this is not
+ supported in all operating modes.
+ * All static state has been eliminated from the library, so that multiple
+ instances of compression or decompression can be active concurrently.
+ * JPEG abbreviated datastream formats are supported, ie, quantization and
+ Huffman tables can be stored separately from the image data.
+ * And not only that, but the documentation of the library has improved
+ considerably!
+
+
+The last widely used release before the version 5 rewrite was version 4A of
+18-Feb-93. Change logs before that point have been discarded, since they
+are not of much interest after the rewrite.
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/coderules.doc b/tqtinterface/qt4/src/3rdparty/libjpeg/coderules.doc
new file mode 100644
index 0000000..0ab5d9b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/coderules.doc
@@ -0,0 +1,118 @@
+IJG JPEG LIBRARY: CODING RULES
+
+Copyright (C) 1991-1996, Thomas G. Lane.
+This file is part of the Independent JPEG Group's software.
+For conditions of distribution and use, see the accompanying README file.
+
+
+Since numerous people will be contributing code and bug fixes, it's important
+to establish a common coding style. The goal of using similar coding styles
+is much more important than the details of just what that style is.
+
+In general we follow the recommendations of "Recommended C Style and Coding
+Standards" revision 6.1 (Cannon et al. as modified by Spencer, Keppel and
+Brader). This document is available in the IJG FTP archive (see
+jpeg/doc/cstyle.ms.tbl.Z, or cstyle.txt.Z for those without nroff/tbl).
+
+Block comments should be laid out thusly:
+
+/*
+ * Block comments in this style.
+ */
+
+We indent statements in K&R style, e.g.,
+ if (test) {
+ then-part;
+ } else {
+ else-part;
+ }
+with two spaces per indentation level. (This indentation convention is
+handled automatically by GNU Emacs and many other text editors.)
+
+Multi-word names should be written in lower case with underscores, e.g.,
+multi_word_name (not multiWordName). Preprocessor symbols and enum constants
+are similar but upper case (MULTI_WORD_NAME). Names should be unique within
+the first fifteen characters. (On some older systems, global names must be
+unique within six characters. We accommodate this without cluttering the
+source code by using macros to substitute shorter names.)
+
+We use function prototypes everywhere; we rely on automatic source code
+transformation to feed prototype-less C compilers. Transformation is done
+by the simple and portable tool 'ansi2knr.c' (courtesy of Ghostscript).
+ansi2knr is not very bright, so it imposes a format requirement on function
+declarations: the function name MUST BEGIN IN COLUMN 1. Thus all functions
+should be written in the following style:
+
+LOCAL(int *)
+function_name (int a, char *b)
+{
+ code...
+}
+
+Note that each function definition must begin with GLOBAL(type), LOCAL(type),
+or METHODDEF(type). These macros expand to "static type" or just "type" as
+appropriate. They provide a readable indication of the routine's usage and
+can readily be changed for special needs. (For instance, special linkage
+keywords can be inserted for use in Windows DLLs.)
+
+ansi2knr does not transform method declarations (function pointers in
+structs). We handle these with a macro JMETHOD, defined as
+ #ifdef HAVE_PROTOTYPES
+ #define JMETHOD(type,methodname,arglist) type (*methodname) arglist
+ #else
+ #define JMETHOD(type,methodname,arglist) type (*methodname) ()
+ #endif
+which is used like this:
+ struct function_pointers {
+ JMETHOD(void, init_entropy_encoder, (int somearg, jparms *jp));
+ JMETHOD(void, term_entropy_encoder, (void));
+ };
+Note the set of parentheses surrounding the parameter list.
+
+A similar solution is used for forward and external function declarations
+(see the EXTERN and JPP macros).
+
+If the code is to work on non-ANSI compilers, we cannot rely on a prototype
+declaration to coerce actual parameters into the right types. Therefore, use
+explicit casts on actual parameters whenever the actual parameter type is not
+identical to the formal parameter. Beware of implicit conversions to "int".
+
+It seems there are some non-ANSI compilers in which the sizeof() operator
+is defined to return int, yet size_t is defined as long. Needless to say,
+this is brain-damaged. Always use the SIZEOF() macro in place of sizeof(),
+so that the result is guaranteed to be of type size_t.
+
+
+The JPEG library is intended to be used within larger programs. Furthermore,
+we want it to be reentrant so that it can be used by applications that process
+multiple images concurrently. The following rules support these requirements:
+
+1. Avoid direct use of file I/O, "malloc", error report printouts, etc;
+pass these through the common routines provided.
+
+2. Minimize global namespace pollution. Functions should be declared static
+wherever possible. (Note that our method-based calling conventions help this
+a lot: in many modules only the initialization function will ever need to be
+called directly, so only that function need be externally visible.) All
+global function names should begin with "jpeg_", and should have an
+abbreviated name (unique in the first six characters) substituted by macro
+when NEED_SHORT_EXTERNAL_NAMES is set.
+
+3. Don't use global variables; anything that must be used in another module
+should be in the common data structures.
+
+4. Don't use static variables except for read-only constant tables. Variables
+that should be private to a module can be placed into private structures (see
+the system architecture document, structure.doc).
+
+5. Source file names should begin with "j" for files that are part of the
+library proper; source files that are not part of the library, such as cjpeg.c
+and djpeg.c, do not begin with "j". Keep source file names to eight
+characters (plus ".c" or ".h", etc) to make life easy for MS-DOSers. Keep
+compression and decompression code in separate source files --- some
+applications may want only one half of the library.
+
+Note: these rules (particularly #4) are not followed religiously in the
+modules that are used in cjpeg/djpeg but are not part of the JPEG library
+proper. Those modules are not really intended to be used in other
+applications.
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/filelist.doc b/tqtinterface/qt4/src/3rdparty/libjpeg/filelist.doc
new file mode 100644
index 0000000..d6b3a36
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/filelist.doc
@@ -0,0 +1,210 @@
+IJG JPEG LIBRARY: FILE LIST
+
+Copyright (C) 1994-1998, Thomas G. Lane.
+This file is part of the Independent JPEG Group's software.
+For conditions of distribution and use, see the accompanying README file.
+
+
+Here is a road map to the files in the IJG JPEG distribution. The
+distribution includes the JPEG library proper, plus two application
+programs ("cjpeg" and "djpeg") which use the library to convert JPEG
+files to and from some other popular image formats. A third application
+"jpegtran" uses the library to do lossless conversion between different
+variants of JPEG. There are also two stand-alone applications,
+"rdjpgcom" and "wrjpgcom".
+
+
+THE JPEG LIBRARY
+================
+
+Include files:
+
+jpeglib.h JPEG library's exported data and function declarations.
+jconfig.h Configuration declarations. Note: this file is not present
+ in the distribution; it is generated during installation.
+jmorecfg.h Additional configuration declarations; need not be changed
+ for a standard installation.
+jerror.h Declares JPEG library's error and trace message codes.
+jinclude.h Central include file used by all IJG .c files to reference
+ system include files.
+jpegint.h JPEG library's internal data structures.
+jchuff.h Private declarations for Huffman encoder modules.
+jdhuff.h Private declarations for Huffman decoder modules.
+jdct.h Private declarations for forward & reverse DCT subsystems.
+jmemsys.h Private declarations for memory management subsystem.
+jversion.h Version information.
+
+Applications using the library should include jpeglib.h (which in turn
+includes jconfig.h and jmorecfg.h). Optionally, jerror.h may be included
+if the application needs to reference individual JPEG error codes. The
+other include files are intended for internal use and would not normally
+be included by an application program. (cjpeg/djpeg/etc do use jinclude.h,
+since its function is to improve portability of the whole IJG distribution.
+Most other applications will directly include the system include files they
+want, and hence won't need jinclude.h.)
+
+
+C source code files:
+
+These files contain most of the functions intended to be called directly by
+an application program:
+
+jcapimin.c Application program interface: core routines for compression.
+jcapistd.c Application program interface: standard compression.
+jdapimin.c Application program interface: core routines for decompression.
+jdapistd.c Application program interface: standard decompression.
+jcomapi.c Application program interface routines common to compression
+ and decompression.
+jcparam.c Compression parameter setting helper routines.
+jctrans.c API and library routines for transcoding compression.
+jdtrans.c API and library routines for transcoding decompression.
+
+Compression side of the library:
+
+jcinit.c Initialization: determines which other modules to use.
+jcmaster.c Master control: setup and inter-pass sequencing logic.
+jcmainct.c Main buffer controller (preprocessor => JPEG compressor).
+jcprepct.c Preprocessor buffer controller.
+jccoefct.c Buffer controller for DCT coefficient buffer.
+jccolor.c Color space conversion.
+jcsample.c Downsampling.
+jcdctmgr.c DCT manager (DCT implementation selection & control).
+jfdctint.c Forward DCT using slow-but-accurate integer method.
+jfdctfst.c Forward DCT using faster, less accurate integer method.
+jfdctflt.c Forward DCT using floating-point arithmetic.
+jchuff.c Huffman entropy coding for sequential JPEG.
+jcphuff.c Huffman entropy coding for progressive JPEG.
+jcmarker.c JPEG marker writing.
+jdatadst.c Data destination manager for stdio output.
+
+Decompression side of the library:
+
+jdmaster.c Master control: determines which other modules to use.
+jdinput.c Input controller: controls input processing modules.
+jdmainct.c Main buffer controller (JPEG decompressor => postprocessor).
+jdcoefct.c Buffer controller for DCT coefficient buffer.
+jdpostct.c Postprocessor buffer controller.
+jdmarker.c JPEG marker reading.
+jdhuff.c Huffman entropy decoding for sequential JPEG.
+jdphuff.c Huffman entropy decoding for progressive JPEG.
+jddctmgr.c IDCT manager (IDCT implementation selection & control).
+jidctint.c Inverse DCT using slow-but-accurate integer method.
+jidctfst.c Inverse DCT using faster, less accurate integer method.
+jidctflt.c Inverse DCT using floating-point arithmetic.
+jidctred.c Inverse DCTs with reduced-size outputs.
+jdsample.c Upsampling.
+jdcolor.c Color space conversion.
+jdmerge.c Merged upsampling/color conversion (faster, lower quality).
+jquant1.c One-pass color quantization using a fixed-spacing colormap.
+jquant2.c Two-pass color quantization using a custom-generated colormap.
+ Also handles one-pass quantization to an externally given map.
+jdatasrc.c Data source manager for stdio input.
+
+Support files for both compression and decompression:
+
+jerror.c Standard error handling routines (application tqreplaceable).
+jmemmgr.c System-independent (more or less) memory management code.
+jutils.c Miscellaneous utility routines.
+
+jmemmgr.c relies on a system-dependent memory management module. The IJG
+distribution includes the following implementations of the system-dependent
+module:
+
+jmemnobs.c "No backing store": assumes adequate virtual memory exists.
+jmemansi.c Makes temporary files with ANSI-standard routine tmpfile().
+jmemname.c Makes temporary files with program-generated file names.
+jmemdos.c Custom implementation for MS-DOS (16-bit environment only):
+ can use extended and expanded memory as well as temp files.
+jmemmac.c Custom implementation for Apple Macintosh.
+
+Exactly one of the system-dependent modules should be configured into an
+installed JPEG library (see install.doc for hints about which one to use).
+On unusual systems you may tqfind it worthwhile to make a special
+system-dependent memory manager.
+
+
+Non-C source code files:
+
+jmemdosa.asm 80x86 assembly code support for jmemdos.c; used only in
+ MS-DOS-specific configurations of the JPEG library.
+
+
+CJPEG/DJPEG/JPEGTRAN
+====================
+
+Include files:
+
+cdjpeg.h Declarations shared by cjpeg/djpeg/jpegtran modules.
+cderror.h Additional error and trace message codes for cjpeg et al.
+transupp.h Declarations for jpegtran support routines in transupp.c.
+
+C source code files:
+
+cjpeg.c Main program for cjpeg.
+djpeg.c Main program for djpeg.
+jpegtran.c Main program for jpegtran.
+cdjpeg.c Utility routines used by all three programs.
+rdcolmap.c Code to read a colormap file for djpeg's "-map" switch.
+rdswitch.c Code to process some of cjpeg's more complex switches.
+ Also used by jpegtran.
+transupp.c Support code for jpegtran: lossless image manipulations.
+
+Image file reader modules for cjpeg:
+
+rdbmp.c BMP file input.
+rdgif.c GIF file input (now just a stub).
+rdppm.c PPM/PGM file input.
+rdrle.c Utah RLE file input.
+rdtarga.c Targa file input.
+
+Image file writer modules for djpeg:
+
+wrbmp.c BMP file output.
+wrgif.c GIF file output (a mere shadow of its former self).
+wrppm.c PPM/PGM file output.
+wrrle.c Utah RLE file output.
+wrtarga.c Targa file output.
+
+
+RDJPGCOM/WRJPGCOM
+=================
+
+C source code files:
+
+rdjpgcom.c Stand-alone rdjpgcom application.
+wrjpgcom.c Stand-alone wrjpgcom application.
+
+These programs do not depend on the IJG library. They do use
+jconfig.h and jinclude.h, only to improve portability.
+
+
+ADDITIONAL FILES
+================
+
+Documentation (see README for a guide to the documentation files):
+
+README Master documentation file.
+*.doc Other documentation files.
+*.1 Documentation in Unix man page format.
+change.log Version-to-version change highlights.
+example.c Sample code for calling JPEG library.
+
+Configuration/installation files and programs (see install.doc for more info):
+
+configure Unix shell script to perform automatic configuration.
+ltconfig Support scripts for configure (from GNU libtool).
+ltmain.sh
+config.guess
+config.sub
+install-sh Install shell script for those Unix systems lacking one.
+ckconfig.c Program to generate jconfig.h on non-Unix systems.
+jconfig.doc Template for making jconfig.h by hand.
+makefile.* Sample makefiles for particular systems.
+jconfig.* Sample jconfig.h for particular systems.
+ansi2knr.c De-ANSIfier for pre-ANSI C compilers (courtesy of
+ L. Peter Deutsch and Aladdin Enterprises).
+
+Test files (see install.doc for test procedure):
+
+test*.* Source and comparison files for confidence test.
+ These are binary image files, NOT text files.
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/install.doc b/tqtinterface/qt4/src/3rdparty/libjpeg/install.doc
new file mode 100644
index 0000000..1bed300
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/install.doc
@@ -0,0 +1,1063 @@
+INSTALLATION INSTRUCTIONS for the Independent JPEG Group's JPEG software
+
+Copyright (C) 1991-1998, Thomas G. Lane.
+This file is part of the Independent JPEG Group's software.
+For conditions of distribution and use, see the accompanying README file.
+
+
+This file explains how to configure and install the IJG software. We have
+tried to make this software extremely portable and flexible, so that it can be
+adapted to almost any environment. The downside of this decision is that the
+installation process is complicated. We have provided shortcuts to simplify
+the task on common systems. But in any case, you will need at least a little
+familiarity with C programming and program build procedures for your system.
+
+If you are only using this software as part of a larger program, the larger
+program's installation procedure may take care of configuring the IJG code.
+For example, Ghostscript's installation script will configure the IJG code.
+You don't need to read this file if you just want to compile Ghostscript.
+
+If you are on a Unix machine, you may not need to read this file at all.
+Try doing
+ ./configure
+ make
+ make test
+If that doesn't complain, do
+ make install
+(better do "make -n install" first to see if the makefile will put the files
+where you want them). Read further if you run into snags or want to customize
+the code for your system.
+
+
+TABLE OF CONTENTS
+-----------------
+
+Before you start
+Configuring the software:
+ using the automatic "configure" script
+ using one of the supplied jconfig and makefile files
+ by hand
+Building the software
+Testing the software
+Installing the software
+Optional stuff
+Optimization
+Hints for specific systems
+
+
+BEFORE YOU START
+================
+
+Before installing the software you must unpack the distributed source code.
+Since you are reading this file, you have probably already succeeded in this
+task. However, there is a potential for error if you needed to convert the
+files to the local standard text file format (for example, if you are on
+MS-DOS you may have converted LF end-of-line to CR/LF). You must apply
+such conversion to all the files EXCEPT those whose names begin with "test".
+The test files contain binary data; if you change them in any way then the
+self-test will give bad results.
+
+Please check the last section of this file to see if there are hints for the
+specific machine or compiler you are using.
+
+
+CONFIGURING THE SOFTWARE
+========================
+
+To configure the IJG code for your system, you need to create two files:
+ * jconfig.h: tqcontains values for system-dependent #define symbols.
+ * Makefile: controls the compilation process.
+(On a non-Unix machine, you may create "project files" or some other
+substitute for a Makefile. jconfig.h is needed in any environment.)
+
+We provide three different ways to generate these files:
+ * On a Unix system, you can just run the "configure" script.
+ * We provide sample jconfig files and makefiles for popular machines;
+ if your machine matches one of the samples, just copy the right sample
+ files to jconfig.h and Makefile.
+ * If all else fails, read the instructions below and make your own files.
+
+
+Configuring the software using the automatic "configure" script
+---------------------------------------------------------------
+
+If you are on a Unix machine, you can just type
+ ./configure
+and let the configure script construct appropriate configuration files.
+If you're using "csh" on an old version of System V, you might need to type
+ sh configure
+instead to prevent csh from trying to execute configure itself.
+Expect configure to run for a few minutes, particularly on slower machines;
+it works by compiling a series of test programs.
+
+Configure was created with GNU Autoconf and it follows the usual conventions
+for GNU configure scripts. It makes a few assumptions that you may want to
+override. You can do this by providing optional switches to configure:
+
+* If you want to build libjpeg as a shared library, say
+ ./configure --enable-shared
+To get both shared and static libraries, say
+ ./configure --enable-shared --enable-static
+Note that these switches invoke GNU libtool to take care of system-dependent
+shared library building methods. If things don't work this way, please try
+running configure without either switch; that should build a static library
+without using libtool. If that works, your problem is probably with libtool
+not with the IJG code. libtool is fairly new and doesn't support all flavors
+of Unix yet. (You might be able to tqfind a newer version of libtool than the
+one included with libjpeg; see ftp.gnu.org. Report libtool problems to
+bug-libtool@gnu.org.)
+
+* Configure will use gcc (GNU C compiler) if it's available, otherwise cc.
+To force a particular compiler to be selected, use the CC option, for example
+ ./configure CC='cc'
+The same method can be used to include any unusual compiler switches.
+For example, on HP-UX you probably want to say
+ ./configure CC='cc -Aa'
+to get HP's compiler to run in ANSI mode.
+
+* The default CFLAGS setting is "-O" for non-gcc compilers, "-O2" for gcc.
+You can override this by saying, for example,
+ ./configure CFLAGS='-g'
+if you want to compile with debugging support.
+
+* Configure will set up the makefile so that "make install" will install files
+into /usr/local/bin, /usr/local/man, etc. You can specify an installation
+prefix other than "/usr/local" by giving configure the option "--prefix=PATH".
+
+* If you don't have a lot of swap space, you may need to enable the IJG
+software's internal virtual memory mechanism. To do this, give the option
+"--enable-maxmem=N" where N is the default maxmemory limit in megabytes.
+This is discussed in more detail under "Selecting a memory manager", below.
+You probably don't need to worry about this on reasonably-sized Unix machines,
+unless you plan to process very large images.
+
+Configure has some other features that are useful if you are cross-compiling
+or working in a network of multiple machine types; but if you need those
+features, you probably already know how to use them.
+
+
+Configuring the software using one of the supplied jconfig and makefile files
+-----------------------------------------------------------------------------
+
+If you have one of these systems, you can just use the provided configuration
+files:
+
+Makefile jconfig file System and/or compiler
+
+makefile.manx jconfig.manx Amiga, Manx Aztec C
+makefile.sas jconfig.sas Amiga, SAS C
+makeproj.mac jconfig.mac Apple Macintosh, Metrowerks CodeWarrior
+mak*jpeg.st jconfig.st Atari ST/STE/TT, Pure C or Turbo C
+makefile.bcc jconfig.bcc MS-DOS or OS/2, Borland C
+makefile.dj jconfig.dj MS-DOS, DJGPP (Delorie's port of GNU C)
+makefile.mc6 jconfig.mc6 MS-DOS, Microsoft C (16-bit only)
+makefile.wat jconfig.wat MS-DOS, OS/2, or Windows NT, Watcom C
+makefile.vc jconfig.vc Windows NT/95, MS Visual C++
+make*.ds jconfig.vc Windows NT/95, MS Developer Studio
+makefile.mms jconfig.vms Digital VMS, with MMS software
+makefile.vms jconfig.vms Digital VMS, without MMS software
+
+Copy the proper jconfig file to jconfig.h and the makefile to Makefile (or
+whatever your system uses as the standard makefile name). For more info see
+the appropriate system-specific hints section near the end of this file.
+
+
+Configuring the software by hand
+--------------------------------
+
+First, generate a jconfig.h file. If you are moderately familiar with C,
+the comments in jconfig.doc should be enough information to do this; just
+copy jconfig.doc to jconfig.h and edit it appropriately. Otherwise, you may
+prefer to use the ckconfig.c program. You will need to compile and execute
+ckconfig.c by hand --- we hope you know at least enough to do that.
+ckconfig.c may not compile the first try (in fact, the whole idea is for it
+to fail if anything is going to). If you get compile errors, fix them by
+editing ckconfig.c according to the directions given in ckconfig.c. Once
+you get it to run, it will write a suitable jconfig.h file, and will also
+print out some advice about which makefile to use.
+
+You may also want to look at the canned jconfig files, if there is one for a
+system similar to yours.
+
+Second, select a makefile and copy it to Makefile (or whatever your system
+uses as the standard makefile name). The most generic makefiles we provide
+are
+ makefile.ansi: if your C compiler supports function prototypes
+ makefile.unix: if not.
+(You have function prototypes if ckconfig.c put "#define HAVE_PROTOTYPES"
+in jconfig.h.) You may want to start from one of the other makefiles if
+there is one for a system similar to yours.
+
+Look over the selected Makefile and adjust options as needed. In particular
+you may want to change the CC and CFLAGS definitions. For instance, if you
+are using GCC, set CC=gcc. If you had to use any compiler switches to get
+ckconfig.c to work, make sure the same switches are in CFLAGS.
+
+If you are on a system that doesn't use makefiles, you'll need to set up
+project files (or whatever you do use) to compile all the source files and
+link them into executable files cjpeg, djpeg, jpegtran, rdjpgcom, and wrjpgcom.
+See the file lists in any of the makefiles to tqfind out which files go into
+each program. Note that the provided makefiles all make a "library" file
+libjpeg first, but you don't have to do that if you don't want to; the file
+lists identify which source files are actually needed for compression,
+decompression, or both. As a last resort, you can make a batch script that
+just compiles everything and links it all together; makefile.vms is an example
+of this (it's for VMS systems that have no make-like utility).
+
+Here are comments about some specific configuration decisions you'll
+need to make:
+
+Command line style
+------------------
+
+These programs can use a Unix-like command line style which supports
+redirection and piping, like this:
+ cjpeg inputfile >outputfile
+ cjpeg <inputfile >outputfile
+ source program | cjpeg >outputfile
+The simpler "two file" command line style is just
+ cjpeg inputfile outputfile
+You may prefer the two-file style, particularly if you don't have pipes.
+
+You MUST use two-file style on any system that doesn't cope well with binary
+data fed through stdin/stdout; this is true for some MS-DOS compilers, for
+example. If you're not on a Unix system, it's safest to assume you need
+two-file style. (But if your compiler provides either the Posix-standard
+fdopen() library routine or a Microsoft-compatible setmode() routine, you
+can safely use the Unix command line style, by defining USE_FDOPEN or
+USE_SETMODE respectively.)
+
+To use the two-file style, make jconfig.h say "#define TWO_FILE_COMMANDLINE".
+
+Selecting a memory manager
+--------------------------
+
+The IJG code is capable of working on images that are too big to fit in main
+memory; data is swapped out to temporary files as necessary. However, the
+code to do this is rather system-dependent. We provide five different
+memory managers:
+
+* jmemansi.c This version uses the ANSI-standard library routine tmpfile(),
+ which not all non-ANSI systems have. On some systems
+ tmpfile() may put the temporary file in a non-optimal
+ location; if you don't like what it does, use jmemname.c.
+
+* jmemname.c This version creates named temporary files. For anything
+ except a Unix machine, you'll need to configure the
+ select_file_name() routine appropriately; see the comments
+ near the head of jmemname.c. If you use this version, define
+ NEED_SIGNAL_CATCHER in jconfig.h to make sure the temp files
+ are removed if the program is aborted.
+
+* jmemnobs.c (That stands for No Backing Store :-).) This will compile on
+ almost any system, but it assumes you have enough main memory
+ or virtual memory to hold the biggest images you work with.
+
+* jmemdos.c This should be used with most 16-bit MS-DOS compilers.
+ See the system-specific notes about MS-DOS for more info.
+ IMPORTANT: if you use this, define USE_MSDOS_MEMMGR in
+ jconfig.h, and include the assembly file jmemdosa.asm in the
+ programs. The supplied makefiles and jconfig files for
+ 16-bit MS-DOS compilers already do both.
+
+* jmemmac.c Custom version for Apple Macintosh; see the system-specific
+ notes for Macintosh for more info.
+
+To use a particular memory manager, change the SYSDEPMEM variable in your
+makefile to equal the corresponding object file name (for example, jmemansi.o
+or jmemansi.obj for jmemansi.c).
+
+If you have plenty of (real or virtual) main memory, just use jmemnobs.c.
+"Plenty" means about ten bytes for every pixel in the largest images
+you plan to process, so a lot of systems don't meet this criterion.
+If yours doesn't, try jmemansi.c first. If that doesn't compile, you'll have
+to use jmemname.c; be sure to adjust select_file_name() for local conditions.
+You may also need to change unlink() to remove() in close_backing_store().
+
+Except with jmemnobs.c or jmemmac.c, you need to adjust the DEFAULT_MAX_MEM
+setting to a reasonable value for your system (either by adding a #define for
+DEFAULT_MAX_MEM to jconfig.h, or by adding a -D switch to the Makefile).
+This value limits the amount of data space the program will attempt to
+allocate. Code and static data space isn't counted, so the actual memory
+needs for cjpeg or djpeg are typically 100 to 150Kb more than the max-memory
+setting. Larger max-memory settings reduce the amount of I/O needed to
+process a large image, but too large a value can result in "insufficient
+memory" failures. On most Unix machines (and other systems with virtual
+memory), just set DEFAULT_MAX_MEM to several million and forget it. At the
+other end of the spectrum, for MS-DOS machines you probably can't go much
+above 300K to 400K. (On MS-DOS the value refers to conventional memory only.
+Extended/expanded memory is handled separately by jmemdos.c.)
+
+
+BUILDING THE SOFTWARE
+=====================
+
+Now you should be able to compile the software. Just say "make" (or
+whatever's necessary to start the compilation). Have a cup of coffee.
+
+Here are some things that could go wrong:
+
+If your compiler complains about undefined structures, you should be able to
+shut it up by putting "#define INCOMPLETE_TYPES_BROKEN" in jconfig.h.
+
+If you have trouble with missing system include files or inclusion of the
+wrong ones, read jinclude.h. This shouldn't happen if you used configure
+or ckconfig.c to set up jconfig.h.
+
+There are a fair number of routines that do not use all of their parameters;
+some compilers will issue warnings about this, which you can ignore. There
+are also a few configuration checks that may give "unreachable code" warnings.
+Any other warning deserves investigation.
+
+If you don't have a getenv() library routine, define NO_GETENV.
+
+Also see the system-specific hints, below.
+
+
+TESTING THE SOFTWARE
+====================
+
+As a quick test of functionality we've included a small sample image in
+several forms:
+ testorig.jpg Starting point for the djpeg tests.
+ testimg.ppm The output of djpeg testorig.jpg
+ testimg.bmp The output of djpeg -bmp -colors 256 testorig.jpg
+ testimg.jpg The output of cjpeg testimg.ppm
+ testprog.jpg Progressive-mode equivalent of testorig.jpg.
+ testimgp.jpg The output of cjpeg -progressive -optimize testimg.ppm
+(The first- and second-generation .jpg files aren't identical since JPEG is
+lossy.) If you can generate duplicates of the testimg* files then you
+probably have working programs.
+
+With most of the makefiles, "make test" will perform the necessary
+comparisons.
+
+If you're using a makefile that doesn't provide the test option, run djpeg
+and cjpeg by hand and compare the output files to testimg* with whatever
+binary file comparison tool you have. The files should be bit-for-bit
+identical.
+
+If the programs complain "MAX_ALLOC_CHUNK is wrong, please fix", then you
+need to reduce MAX_ALLOC_CHUNK to a value that fits in type size_t.
+Try adding "#define MAX_ALLOC_CHUNK 65520L" to jconfig.h. A less likely
+configuration error is "ALIGN_TYPE is wrong, please fix": defining ALIGN_TYPE
+as long should take care of that one.
+
+If the cjpeg test run fails with "Missing Huffman code table entry", it's a
+good bet that you needed to define RIGHT_SHIFT_IS_UNSIGNED. Go back to the
+configuration step and run ckconfig.c. (This is a good plan for any other
+test failure, too.)
+
+If you are using Unix (one-file) command line style on a non-Unix system,
+it's a good idea to check that binary I/O through stdin/stdout actually
+works. You should get the same results from "djpeg <testorig.jpg >out.ppm"
+as from "djpeg -outfile out.ppm testorig.jpg". Note that the makefiles all
+use the latter style and therefore do not exercise stdin/stdout! If this
+check fails, try recompiling with USE_SETMODE or USE_FDOPEN defined.
+If it still doesn't work, better use two-file style.
+
+If you chose a memory manager other than jmemnobs.c, you should test that
+temporary-file usage works. Try "djpeg -bmp -colors 256 -max 0 testorig.jpg"
+and make sure its output matches testimg.bmp. If you have any really large
+images handy, try compressing them with -optimize and/or decompressing with
+-colors 256 to make sure your DEFAULT_MAX_MEM setting is not too large.
+
+NOTE: this is far from an exhaustive test of the JPEG software; some modules,
+such as 1-pass color quantization, are not exercised at all. It's just a
+quick test to give you some confidence that you haven't missed something
+major.
+
+
+INSTALLING THE SOFTWARE
+=======================
+
+Once you're done with the above steps, you can install the software by
+copying the executable files (cjpeg, djpeg, jpegtran, rdjpgcom, and wrjpgcom)
+to wherever you normally install programs. On Unix systems, you'll also want
+to put the man pages (cjpeg.1, djpeg.1, jpegtran.1, rdjpgcom.1, wrjpgcom.1)
+in the man-page directory. The pre-fab makefiles don't support this step
+since there's such a wide variety of installation procedures on different
+systems.
+
+If you generated a Makefile with the "configure" script, you can just say
+ make install
+to install the programs and their man pages into the standard places.
+(You'll probably need to be root to do this.) We recommend first saying
+ make -n install
+to see where configure thought the files should go. You may need to edit
+the Makefile, particularly if your system's conventions for man page
+filenames don't match what configure expects.
+
+If you want to install the IJG library itself, for use in compiling other
+programs besides ours, then you need to put the four include files
+ jpeglib.h jerror.h jconfig.h jmorecfg.h
+into your include-file directory, and put the library file libjpeg.a
+(extension may vary depending on system) wherever library files go.
+If you generated a Makefile with "configure", it will do what it thinks
+is the right thing if you say
+ make install-lib
+
+
+OPTIONAL STUFF
+==============
+
+Progress monitor:
+
+If you like, you can #define PROGRESS_REPORT (in jconfig.h) to enable display
+of percent-done progress reports. The routine provided in cdjpeg.c merely
+prints percentages to stderr, but you can customize it to do something
+fancier.
+
+Utah RLE file format support:
+
+We distribute the software with support for RLE image files (Utah Raster
+Toolkit format) disabled, because the RLE support won't compile without the
+Utah library. If you have URT version 3.1 or later, you can enable RLE
+support as follows:
+ 1. #define RLE_SUPPORTED in jconfig.h.
+ 2. Add a -I option to CFLAGS in the Makefile for the directory
+ containing the URT .h files (typically the "include"
+ subdirectory of the URT distribution).
+ 3. Add -L... -lrle to LDLIBS in the Makefile, where ... specifies
+ the directory containing the URT "librle.a" file (typically the
+ "lib" subdirectory of the URT distribution).
+
+Support for 12-bit-deep pixel data:
+
+The JPEG standard allows either 8-bit or 12-bit data precision. (For color,
+this means 8 or 12 bits per channel, of course.) If you need to work with
+deeper than 8-bit data, you can compile the IJG code for 12-bit operation.
+To do so:
+ 1. In jmorecfg.h, define BITS_IN_JSAMPLE as 12 rather than 8.
+ 2. In jconfig.h, undefine BMP_SUPPORTED, RLE_SUPPORTED, and TARGA_SUPPORTED,
+ because the code for those formats doesn't handle 12-bit data and won't
+ even compile. (The PPM code does work, as explained below. The GIF
+ code works too; it scales 8-bit GIF data to and from 12-bit depth
+ automatically.)
+ 3. Compile. Don't expect "make test" to pass, since the supplied test
+ files are for 8-bit data.
+
+Currently, 12-bit support does not work on 16-bit-int machines.
+
+Note that a 12-bit version will not read 8-bit JPEG files, nor vice versa;
+so you'll want to keep around a regular 8-bit compilation as well.
+(Run-time selection of data depth, to allow a single copy that does both,
+is possible but would probably slow things down considerably; it's very low
+on our to-do list.)
+
+The PPM reader (rdppm.c) can read 12-bit data from either text-format or
+binary-format PPM and PGM files. Binary-format PPM/PGM files which have a
+maxval greater than 255 are assumed to use 2 bytes per sample, LSB first
+(little-endian order). As of early 1995, 2-byte binary format is not
+officially supported by the PBMPLUS library, but it is expected that a
+future release of PBMPLUS will support it. Note that the PPM reader will
+read files of any maxval regardless of the BITS_IN_JSAMPLE setting; incoming
+data is automatically rescaled to either maxval=255 or maxval=4095 as
+appropriate for the cjpeg bit depth.
+
+The PPM writer (wrppm.c) will normally write 2-byte binary PPM or PGM
+format, maxval 4095, when compiled with BITS_IN_JSAMPLE=12. Since this
+format is not yet widely supported, you can disable it by compiling wrppm.c
+with PPM_NORAWWORD defined; then the data is scaled down to 8 bits to make a
+standard 1-byte/sample PPM or PGM file. (Yes, this means still another copy
+of djpeg to keep around. But hopefully you won't need it for very long.
+Poskanzer's supposed to get that new PBMPLUS release out Real Soon Now.)
+
+Of course, if you are working with 12-bit data, you probably have it stored
+in some other, nonstandard format. In that case you'll probably want to
+write your own I/O modules to read and write your format.
+
+Note that a 12-bit version of cjpeg always runs in "-optimize" mode, in
+order to generate valid Huffman tables. This is necessary because our
+default Huffman tables only cover 8-bit data.
+
+Removing code:
+
+If you need to make a smaller version of the JPEG software, some optional
+functions can be removed at compile time. See the xxx_SUPPORTED #defines in
+jconfig.h and jmorecfg.h. If at all possible, we recommend that you leave in
+decoder support for all valid JPEG files, to ensure that you can read anyone's
+output. Taking out support for image file formats that you don't use is the
+most painless way to make the programs smaller. Another possibility is to
+remove some of the DCT methods: in particular, the "IFAST" method may not be
+enough faster than the others to be worth keeping on your machine. (If you
+do remove ISLOW or IFAST, be sure to redefine JDCT_DEFAULT or JDCT_FASTEST
+to a supported method, by adding a #define in jconfig.h.)
+
+
+OPTIMIZATION
+============
+
+Unless you own a Cray, you'll probably be interested in making the JPEG
+software go as fast as possible. This section covers some machine-dependent
+optimizations you may want to try. We suggest that before trying any of
+this, you first get the basic installation to pass the self-test step.
+Repeat the self-test after any optimization to make sure that you haven't
+broken anything.
+
+The integer DCT routines perform a lot of multiplications. These
+multiplications must yield 32-bit results, but none of their input values
+are more than 16 bits wide. On many machines, notably the 680x0 and 80x86
+CPUs, a 16x16=>32 bit multiply instruction is faster than a full 32x32=>32
+bit multiply. Unfortunately there is no portable way to specify such a
+multiplication in C, but some compilers can generate one when you use the
+right combination of casts. See the MULTIPLYxxx macro definitions in
+jdct.h. If your compiler makes "int" be 32 bits and "short" be 16 bits,
+defining SHORTxSHORT_32 is fairly likely to work. When experimenting with
+alternate definitions, be sure to test not only whether the code still works
+(use the self-test), but also whether it is actually faster --- on some
+compilers, alternate definitions may compute the right answer, yet be slower
+than the default. Timing cjpeg on a large PGM (grayscale) input file is the
+best way to check this, as the DCT will be the largest fraction of the runtime
+in that mode. (Note: some of the distributed compiler-specific jconfig files
+already contain #define switches to select appropriate MULTIPLYxxx
+definitions.)
+
+If your machine has sufficiently fast floating point hardware, you may tqfind
+that the float DCT method is faster than the integer DCT methods, even
+after tweaking the integer multiply macros. In that case you may want to
+make the float DCT be the default method. (The only objection to this is
+that float DCT results may vary slightly across machines.) To do that, add
+"#define JDCT_DEFAULT JDCT_FLOAT" to jconfig.h. Even if you don't change
+the default, you should redefine JDCT_FASTEST, which is the method selected
+by djpeg's -fast switch. Don't forget to update the documentation files
+(usage.doc and/or cjpeg.1, djpeg.1) to agree with what you've done.
+
+If access to "short" arrays is slow on your machine, it may be a win to
+define type JCOEF as int rather than short. This will cost a good deal of
+memory though, particularly in some multi-pass modes, so don't do it unless
+you have memory to burn and short is REALLY slow.
+
+If your compiler can compile function calls in-line, make sure the INLINE
+macro in jmorecfg.h is defined as the keyword that marks a function
+inline-able. Some compilers have a switch that tells the compiler to inline
+any function it thinks is profitable (e.g., -finline-functions for gcc).
+Enabling such a switch is likely to make the compiled code bigger but faster.
+
+In general, it's worth trying the maximum optimization level of your compiler,
+and experimenting with any optional optimizations such as loop unrolling.
+(Unfortunately, far too many compilers have optimizer bugs ... be prepared to
+back off if the code fails self-test.) If you do any experimentation along
+these lines, please report the optimal settings to jpeg-info@uunet.uu.net so
+we can mention them in future releases. Be sure to specify your machine and
+compiler version.
+
+
+HINTS FOR SPECIFIC SYSTEMS
+==========================
+
+We welcome reports on changes needed for systems not mentioned here. Submit
+'em to jpeg-info@uunet.uu.net. Also, if configure or ckconfig.c is wrong
+about how to configure the JPEG software for your system, please let us know.
+
+
+Acorn RISC OS:
+
+(Thanks to Simon Middleton for these hints on compiling with Desktop C.)
+After renaming the files according to Acorn conventions, take a copy of
+makefile.ansi, change all occurrences of 'libjpeg.a' to 'libjpeg.o' and
+change these definitions as indicated:
+
+CFLAGS= -throwback -IC: -Wn
+LDLIBS=C:o.Stubs
+SYSDEPMEM=jmemansi.o
+LN=Link
+AR=LibFile -c -o
+
+Also add a new line '.c.o:; $(cc) $< $(cflags) -c -o $@'. Remove the
+lines '$(RM) libjpeg.o' and '$(AR2) libjpeg.o' and the 'jconfig.h'
+dependency section.
+
+Copy jconfig.doc to jconfig.h. Edit jconfig.h to define TWO_FILE_COMMANDLINE
+and CHAR_IS_UNSIGNED.
+
+Run the makefile using !AMU not !Make. If you want to use the 'clean' and
+'test' makefile entries then you will have to fiddle with the syntax a bit
+and rename the test files.
+
+
+Amiga:
+
+SAS C 6.50 reportedly is too buggy to compile the IJG code properly.
+A patch to update to 6.51 is available from SAS or AmiNet FTP sites.
+
+The supplied config files are set up to use jmemname.c as the memory
+manager, with temporary files being created on the tqdevice named by
+"JPEGTMP:".
+
+
+Atari ST/STE/TT:
+
+Copy the project files makcjpeg.st, makdjpeg.st, maktjpeg.st, and makljpeg.st
+to cjpeg.prj, djpeg.prj, jpegtran.prj, and libjpeg.prj respectively. The
+project files should work as-is with Pure C. For Turbo C, change library
+filenames "pc..." to "tc..." in each project file. Note that libjpeg.prj
+selects jmemansi.c as the recommended memory manager. You'll probably want to
+adjust the DEFAULT_MAX_MEM setting --- you want it to be a couple hundred K
+less than your normal free memory. Put "#define DEFAULT_MAX_MEM nnnn" into
+jconfig.h to do this.
+
+To use the 68881/68882 coprocessor for the floating point DCT, add the
+compiler option "-8" to the project files and tqreplace pcfltlib.lib with
+pc881lib.lib in cjpeg.prj and djpeg.prj. Or if you don't have a
+coprocessor, you may prefer to remove the float DCT code by undefining
+DCT_FLOAT_SUPPORTED in jmorecfg.h (since without a coprocessor, the float
+code will be too slow to be useful). In that case, you can delete
+pcfltlib.lib from the project files.
+
+Note that you must make libjpeg.lib before making cjpeg.ttp, djpeg.ttp,
+or jpegtran.ttp. You'll have to perform the self-test by hand.
+
+We haven't bothered to include project files for rdjpgcom and wrjpgcom.
+Those source files should just be compiled by themselves; they don't
+depend on the JPEG library.
+
+There is a bug in some older versions of the Turbo C library which causes the
+space used by temporary files created with "tmpfile()" not to be freed after
+an abnormal program exit. If you check your disk afterwards, you will tqfind
+cluster chains that are allocated but not used by a file. This should not
+happen in cjpeg/djpeg/jpegtran, since we enable a signal catcher to explicitly
+close temp files before exiting. But if you use the JPEG library with your
+own code, be sure to supply a signal catcher, or else use a different
+system-dependent memory manager.
+
+
+Cray:
+
+Should you be so fortunate as to be running JPEG on a Cray YMP, there is a
+compiler bug in old versions of Cray's Standard C (prior to 3.1). If you
+still have an old compiler, you'll need to insert a line reading
+"#pragma novector" just before the loop
+ for (i = 1; i <= (int) htbl->bits[l]; i++)
+ huffsize[p++] = (char) l;
+in fix_huff_tbl (in V5beta1, line 204 of jchuff.c and line 176 of jdhuff.c).
+[This bug may or may not still occur with the current IJG code, but it's
+probably a dead issue anyway...]
+
+
+HP-UX:
+
+If you have HP-UX 7.05 or later with the "software development" C compiler,
+you should run the compiler in ANSI mode. If using the configure script,
+say
+ ./configure CC='cc -Aa'
+(or -Ae if you prefer). If configuring by hand, use makefile.ansi and add
+"-Aa" to the CFLAGS line in the makefile.
+
+If you have a pre-7.05 system, or if you are using the non-ANSI C compiler
+delivered with a minimum HP-UX system, then you must use makefile.unix
+(and do NOT add -Aa); or just run configure without the CC option.
+
+On HP 9000 series 800 machines, the HP C compiler is buggy in revisions prior
+to A.08.07. If you get complaints about "not a typedef name", you'll have to
+use makefile.unix, or run configure without the CC option.
+
+
+Macintosh, generic comments:
+
+The supplied user-interface files (cjpeg.c, djpeg.c, etc) are set up to
+provide a Unix-style command line interface. You can use this interface on
+the Mac by means of the ccommand() library routine provided by Metrowerks
+CodeWarrior or Think C. This is only appropriate for testing the library,
+however; to make a user-friendly equivalent of cjpeg/djpeg you'd really want
+to develop a Mac-style user interface. There isn't a complete example
+available at the moment, but there are some helpful starting points:
+1. Sam Bushell's free "To JPEG" applet provides drag-and-drop conversion to
+JPEG under System 7 and later. This only illustrates how to use the
+compression half of the library, but it does a very nice job of that part.
+The CodeWarrior source code is available from http://www.pobox.com/~jsam.
+2. Jim Brunner prepared a Mac-style user interface for both compression and
+decompression. Unfortunately, it hasn't been updated since IJG v4, and
+the library's API has changed considerably since then. Still it may be of
+some help, particularly as a guide to compiling the IJG code under Think C.
+Jim's code is available from the Info-Mac archives, at sumex-aim.stanford.edu
+or mirrors thereof; see file /info-mac/dev/src/jpeg-convert-c.hqx.
+
+jmemmac.c is the recommended memory manager back end for Macintosh. It uses
+NewPtr/DisposePtr instead of malloc/free, and has a Mac-specific
+implementation of jpeg_mem_available(). It also creates temporary files that
+follow Mac conventions. (That part of the code relies on System-7-or-later OS
+functions. See the comments in jmemmac.c if you need to run it on System 6.)
+NOTE that USE_MAC_MEMMGR must be defined in jconfig.h to use jmemmac.c.
+
+You can also use jmemnobs.c, if you don't care about handling images larger
+than available memory. If you use any memory manager back end other than
+jmemmac.c, we recommend replacing "malloc" and "free" by "NewPtr" and
+"DisposePtr", because Mac C libraries often have peculiar implementations of
+malloc/free. (For instance, free() may not return the freed space to the
+Mac Memory Manager. This is undesirable for the IJG code because jmemmgr.c
+already clumps space requests.)
+
+
+Macintosh, Metrowerks CodeWarrior:
+
+The Unix-command-line-style interface can be used by defining USE_CCOMMAND.
+You'll also need to define TWO_FILE_COMMANDLINE to avoid stdin/stdout.
+This means that when using the cjpeg/djpeg programs, you'll have to type the
+input and output file names in the "Arguments" text-edit box, rather than
+using the file radio buttons. (Perhaps USE_FDOPEN or USE_SETMODE would
+eliminate the problem, but I haven't heard from anyone who's tried it.)
+
+On 680x0 Macs, Metrowerks defines type "double" as a 10-byte IEEE extended
+float. jmemmgr.c won't like this: it wants sizeof(ALIGN_TYPE) to be a power
+of 2. Add "#define ALIGN_TYPE long" to jconfig.h to eliminate the complaint.
+
+The supplied configuration file jconfig.mac can be used for your jconfig.h;
+it includes all the recommended symbol definitions. If you have AppleScript
+installed, you can run the supplied script makeproj.mac to create CodeWarrior
+project files for the library and the testbed applications, then build the
+library and applications. (Thanks to Dan Sears and Don Agro for this nifty
+hack, which saves us from trying to maintain CodeWarrior project files as part
+of the IJG distribution...)
+
+
+Macintosh, Think C:
+
+The documentation in Jim Brunner's "JPEG Convert" source code (see above)
+includes detailed build instructions for Think C; it's probably somewhat
+out of date for the current release, but may be helpful.
+
+If you want to build the minimal command line version, proceed as follows.
+You'll have to prepare project files for the programs; we don't include any
+in the distribution since they are not text files. Use the file lists in
+any of the supplied makefiles as a guide. Also add the ANSI and Unix C
+libraries in a separate segment. You may need to divide the JPEG files into
+more than one segment; we recommend dividing compression and decompression
+modules. Define USE_CCOMMAND in jconfig.h so that the ccommand() routine is
+called. You must also define TWO_FILE_COMMANDLINE because stdin/stdout
+don't handle binary data correctly.
+
+On 680x0 Macs, Think C defines type "double" as a 12-byte IEEE extended float.
+jmemmgr.c won't like this: it wants sizeof(ALIGN_TYPE) to be a power of 2.
+Add "#define ALIGN_TYPE long" to jconfig.h to eliminate the complaint.
+
+jconfig.mac should work as a jconfig.h configuration file for Think C,
+but the makeproj.mac AppleScript script is specific to CodeWarrior. Sorry.
+
+
+MIPS R3000:
+
+MIPS's cc version 1.31 has a rather nasty optimization bug. Don't use -O
+if you have that compiler version. (Use "cc -V" to check the version.)
+Note that the R3000 chip is found in workstations from DEC and others.
+
+
+MS-DOS, generic comments for 16-bit compilers:
+
+The IJG code is designed to work well in 80x86 "small" or "medium" memory
+models (i.e., data pointers are 16 bits unless explicitly declared "far";
+code pointers can be either size). You may be able to use small model to
+compile cjpeg or djpeg by itself, but you will probably have to use medium
+model for any larger application. This won't make much difference in
+performance. You *will* take a noticeable performance hit if you use a
+large-data memory model, and you should avoid "huge" model if at all
+possible. Be sure that NEED_FAR_POINTERS is defined in jconfig.h if you use
+a small-data memory model; be sure it is NOT defined if you use a large-data
+model. (The supplied makefiles and jconfig files for Borland and Microsoft C
+compile in medium model and define NEED_FAR_POINTERS.)
+
+The DOS-specific memory manager, jmemdos.c, should be used if possible.
+It needs some assembly-code routines which are in jmemdosa.asm; make sure
+your makefile assembles that file and includes it in the library. If you
+don't have a suitable assembler, you can get pre-assembled object files for
+jmemdosa by FTP from ftp.uu.net:/graphics/jpeg/jdosaobj.zip. (DOS-oriented
+distributions of the IJG source code often include these object files.)
+
+When using jmemdos.c, jconfig.h must define USE_MSDOS_MEMMGR and must set
+MAX_ALLOC_CHUNK to less than 64K (65520L is a typical value). If your
+C library's far-heap malloc() can't allocate blocks that large, reduce
+MAX_ALLOC_CHUNK to whatever it can handle.
+
+If you can't use jmemdos.c for some reason --- for example, because you
+don't have an assembler to assemble jmemdosa.asm --- you'll have to fall
+back to jmemansi.c or jmemname.c. You'll probably still need to set
+MAX_ALLOC_CHUNK in jconfig.h, because most DOS C libraries won't malloc()
+more than 64K at a time. IMPORTANT: if you use jmemansi.c or jmemname.c,
+you will have to compile in a large-data memory model in order to get the
+right stdio library. Too bad.
+
+wrjpgcom needs to be compiled in large model, because it malloc()s a 64KB
+work area to hold the comment text. If your C library's malloc can't
+handle that, reduce MAX_COM_LENGTH as necessary in wrjpgcom.c.
+
+Most MS-DOS compilers treat stdin/stdout as text files, so you must use
+two-file command line style. But if your compiler has either fdopen() or
+setmode(), you can use one-file style if you like. To do this, define
+USE_SETMODE or USE_FDOPEN so that stdin/stdout will be set to binary mode.
+(USE_SETMODE seems to work with more DOS compilers than USE_FDOPEN.) You
+should test that I/O through stdin/stdout produces the same results as I/O
+to explicitly named files... the "make test" procedures in the supplied
+makefiles do NOT use stdin/stdout.
+
+
+MS-DOS, generic comments for 32-bit compilers:
+
+None of the above comments about memory models apply if you are using a
+32-bit flat-memory-space environment, such as DJGPP or Watcom C. (And you
+should use one if you have it, as performance will be much better than
+8086-compatible code!) For flat-memory-space compilers, do NOT define
+NEED_FAR_POINTERS, and do NOT use jmemdos.c. Use jmemnobs.c if the
+environment supplies adequate virtual memory, otherwise use jmemansi.c or
+jmemname.c.
+
+You'll still need to be careful about binary I/O through stdin/stdout.
+See the last paragraph of the previous section.
+
+
+MS-DOS, Borland C:
+
+Be sure to convert all the source files to DOS text format (CR/LF newlines).
+Although Borland C will often work OK with unmodified Unix (LF newlines)
+source files, sometimes it will give bogus compile errors.
+"Illegal character '#'" is the most common such error. (This is true with
+Borland C 3.1, but perhaps is fixed in newer releases.)
+
+If you want one-file command line style, just undefine TWO_FILE_COMMANDLINE.
+jconfig.bcc already includes #define USE_SETMODE to make this work.
+(fdopen does not work correctly.)
+
+
+MS-DOS, Microsoft C:
+
+makefile.mc6 works with Microsoft C, DOS Visual C++, etc. It should only
+be used if you want to build a 16-bit (small or medium memory model) program.
+
+If you want one-file command line style, just undefine TWO_FILE_COMMANDLINE.
+jconfig.mc6 already includes #define USE_SETMODE to make this work.
+(fdopen does not work correctly.)
+
+Note that this makefile assumes that the working copy of itself is called
+"makefile". If you want to call it something else, say "makefile.mak",
+be sure to adjust the dependency line that reads "$(RFILE) : makefile".
+Otherwise the make will fail because it doesn't know how to create "makefile".
+Worse, some releases of Microsoft's make utilities give an incorrect error
+message in this situation.
+
+Old versions of MS C fail with an "out of macro expansion space" error
+because they can't cope with the macro TRACEMS8 (defined in jerror.h).
+If this happens to you, the easiest solution is to change TRACEMS8 to
+expand to nothing. You'll lose the ability to dump out JPEG coefficient
+tables with djpeg -debug -debug, but at least you can compile.
+
+Original MS C 6.0 is very buggy; it compiles incorrect code unless you turn
+off optimization entirely (remove -O from CFLAGS). 6.00A is better, but it
+still generates bad code if you enable loop optimizations (-Ol or -Ox).
+
+MS C 8.0 crashes when compiling jquant1.c with optimization switch /Oo ...
+which is on by default. To work around this bug, compile that one file
+with /Oo-.
+
+
+Microsoft Windows (all versions), generic comments:
+
+Some Windows system include files define typedef boolean as "unsigned char".
+The IJG code also defines typedef boolean, but we make it "int" by default.
+This doesn't affect the IJG programs because we don't import those Windows
+include files. But if you use the JPEG library in your own program, and some
+of your program's files import one definition of boolean while some import the
+other, you can get all sorts of mysterious problems. A good preventive step
+is to make the IJG library use "unsigned char" for boolean. To do that,
+add something like this to your jconfig.h file:
+ /* Define "boolean" as unsigned char, not int, per Windows custom */
+ #ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
+ typedef unsigned char boolean;
+ #endif
+ #define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
+(This is already in jconfig.vc, by the way.)
+
+windef.h tqcontains the declarations
+ #define far
+ #define FAR far
+Since jmorecfg.h tries to define FAR as empty, you may get a compiler
+warning if you include both jpeglib.h and windef.h (which windows.h
+includes). To suppress the warning, you can put "#ifndef FAR"/"#endif"
+around the line "#define FAR" in jmorecfg.h.
+
+When using the library in a Windows application, you will almost certainly
+want to modify or tqreplace the error handler module jerror.c, since our
+default error handler does a couple of inappropriate things:
+ 1. it tries to write error and warning messages on stderr;
+ 2. in event of a fatal error, it exits by calling exit().
+
+A simple stopgap solution for problem 1 is to tqreplace the line
+ fprintf(stderr, "%s\n", buffer);
+(in output_message in jerror.c) with
+ MessageBox(GetActiveWindow(),buffer,"JPEG Error",MB_OK|MB_ICONERROR);
+It's highly recommended that you at least do that much, since otherwise
+error messages will disappear into nowhere. (Beginning with IJG v6b, this
+code is already present in jerror.c; just define USE_WINDOWS_MESSAGEBOX in
+jconfig.h to enable it.)
+
+The proper solution for problem 2 is to return control to your calling
+application after a library error. This can be done with the setjmp/longjmp
+technique discussed in libjpeg.doc and illustrated in example.c. (NOTE:
+some older Windows C compilers provide versions of setjmp/longjmp that
+don't actually work under Windows. You may need to use the Windows system
+functions Catch and Throw instead.)
+
+The recommended memory manager under Windows is jmemnobs.c; in other words,
+let Windows do any virtual memory management needed. You should NOT use
+jmemdos.c nor jmemdosa.asm under Windows.
+
+For Windows 3.1, we recommend compiling in medium or large memory model;
+for newer Windows versions, use a 32-bit flat memory model. (See the MS-DOS
+sections above for more info about memory models.) In the 16-bit memory
+models only, you'll need to put
+ #define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */
+into jconfig.h to limit allocation chunks to 64Kb. (Without that, you'd
+have to use huge memory model, which slows things down unnecessarily.)
+jmemnobs.c works without modification in large or flat memory models, but to
+use medium model, you need to modify its jpeg_get_large and jpeg_free_large
+routines to allocate far memory. In any case, you might like to tqreplace
+its calls to malloc and free with direct calls on Windows memory allocation
+functions.
+
+You may also want to modify jdatasrc.c and jdatadst.c to use Windows file
+operations rather than fread/fwrite. This is only necessary if your C
+compiler doesn't provide a competent implementation of C stdio functions.
+
+You might want to tweak the RGB_xxx macros in jmorecfg.h so that the library
+will accept or deliver color pixels in BGR sample order, not RGB; BGR order
+is usually more convenient under Windows. Note that this change will break
+the sample applications cjpeg/djpeg, but the library itself works fine.
+
+
+Many people want to convert the IJG library into a DLL. This is reasonably
+straightforward, but watch out for the following:
+
+ 1. Don't try to compile as a DLL in small or medium memory model; use
+large model, or even better, 32-bit flat model. Many places in the IJG code
+assume the address of a local variable is an ordinary (not FAR) pointer;
+that isn't true in a medium-model DLL.
+
+ 2. Microsoft C cannot pass file pointers between applications and DLLs.
+(See Microsoft Knowledge Base, PSS ID Number Q50336.) So jdatasrc.c and
+jdatadst.c don't work if you open a file in your application and then pass
+the pointer to the DLL. One workaround is to make jdatasrc.c/jdatadst.c
+part of your main application rather than part of the DLL.
+
+ 3. You'll probably need to modify the macros GLOBAL() and EXTERN() to
+attach suitable linkage keywords to the exported routine names. Similarly,
+you'll want to modify METHODDEF() and JMETHOD() to ensure function pointers
+are declared in a way that lets application routines be called back through
+the function pointers. These macros are in jmorecfg.h. Typical definitions
+for a 16-bit DLL are:
+ #define GLOBAL(type) type _far _pascal _loadds _export
+ #define EXTERN(type) extern type _far _pascal _loadds
+ #define METHODDEF(type) static type _far _pascal
+ #define JMETHOD(type,methodname,arglist) \
+ type (_far _pascal *methodname) arglist
+For a 32-bit DLL you may want something like
+ #define GLOBAL(type) __declspec(dllexport) type
+ #define EXTERN(type) extern __declspec(dllexport) type
+Although not all the GLOBAL routines are actually intended to be called by
+the application, the performance cost of making them all DLL entry points is
+negligible.
+
+The unmodified IJG library presents a very C-specific application interface,
+so the resulting DLL is only usable from C or C++ applications. There has
+been some talk of writing wrapper code that would present a simpler interface
+usable from other languages, such as Visual Basic. This is on our to-do list
+but hasn't been very high priority --- any volunteers out there?
+
+
+Microsoft Windows, Borland C:
+
+The provided jconfig.bcc should work OK in a 32-bit Windows environment,
+but you'll need to tweak it in a 16-bit environment (you'd need to define
+NEED_FAR_POINTERS and MAX_ALLOC_CHUNK). Beware that makefile.bcc will need
+alteration if you want to use it for Windows --- in particular, you should
+use jmemnobs.c not jmemdos.c under Windows.
+
+Borland C++ 4.5 fails with an internal compiler error when trying to compile
+jdmerge.c in 32-bit mode. If enough people complain, perhaps Borland will fix
+it. In the meantime, the simplest known workaround is to add a redundant
+definition of the variable range_limit in h2v1_merged_upsample(), at the head
+of the block that handles odd image width (about line 268 in v6 jdmerge.c):
+ /* If image width is odd, do the last output column separately */
+ if (cinfo->output_width & 1) {
+ register JSAMPLE * range_limit = cinfo->sample_range_limit; /* ADD THIS */
+ cb = GETJSAMPLE(*inptr1);
+Pretty bizarre, especially since the very similar routine h2v2_merged_upsample
+doesn't trigger the bug.
+Recent reports suggest that this bug does not occur with "bcc32a" (the
+Pentium-optimized version of the compiler).
+
+Another report from a user of Borland C 4.5 was that incorrect code (leading
+to a color shift in processed images) was produced if any of the following
+optimization switch combinations were used:
+ -Ot -Og
+ -Ot -Op
+ -Ot -Om
+So try backing off on optimization if you see such a problem. (Are there
+several different releases all numbered "4.5"??)
+
+
+Microsoft Windows, Microsoft Visual C++:
+
+jconfig.vc should work OK with any Microsoft compiler for a 32-bit memory
+model. makefile.vc is intended for command-line use. (If you are using
+the Developer Studio environment, you may prefer the DevStudio project
+files; see below.)
+
+Some users feel that it's easier to call the library from C++ code if you
+force VC++ to treat the library as C++ code, which you can do by renaming
+all the *.c files to *.cpp (and adjusting the makefile to match). This
+avoids the need to put extern "C" { ... } around #include "jpeglib.h" in
+your C++ application.
+
+
+Microsoft Windows, Microsoft Developer Studio:
+
+We include makefiles that should work as project files in DevStudio 4.2 or
+later. There is a library makefile that builds the IJG library as a static
+Win32 library, and an application makefile that builds the sample applications
+as Win32 console applications. (Even if you only want the library, we
+recommend building the applications so that you can run the self-test.)
+
+To use:
+1. Copy jconfig.vc to jconfig.h, makelib.ds to jpeg.mak, and
+ makeapps.ds to apps.mak. (Note that the renaming is critical!)
+2. Click on the .mak files to construct project workspaces.
+ (If you are using DevStudio more recent than 4.2, you'll probably
+ get a message saying that the makefiles are being updated.)
+3. Build the library project, then the applications project.
+4. Move the application .exe files from `app`\Release to an
+ appropriate location on your path.
+5. To perform the self-test, execute the command line
+ NMAKE /f makefile.vc test
+
+
+OS/2, Borland C++:
+
+Watch out for optimization bugs in older Borland compilers; you may need
+to back off the optimization switch settings. See the comments in
+makefile.bcc.
+
+
+SGI:
+
+On some SGI systems, you may need to set "AR2= ar -ts" in the Makefile.
+If you are using configure, you can do this by saying
+ ./configure RANLIB='ar -ts'
+This change is not needed on all SGIs. Use it only if the make fails at the
+stage of linking the completed programs.
+
+On the MIPS R4000 architecture (Indy, etc.), the compiler option "-mips2"
+reportedly speeds up the float DCT method substantially, enough to make it
+faster than the default int method (but still slower than the fast int
+method). If you use -mips2, you may want to alter the default DCT method to
+be float. To do this, put "#define JDCT_DEFAULT JDCT_FLOAT" in jconfig.h.
+
+
+VMS:
+
+On an Alpha/VMS system with MMS, be sure to use the "/Marco=Alpha=1"
+qualifier with MMS when building the JPEG package.
+
+VAX/VMS v5.5-1 may have problems with the test step of the build procedure
+reporting differences when it compares the original and test images. If the
+error points to the last block of the files, it is most likely bogus and may
+be safely ignored. It seems to be because the files are Stream_LF and
+Backup/Compare has difficulty with the (presumably) null padded files.
+This problem was not observed on VAX/VMS v6.1 or AXP/VMS v6.1.
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcapimin.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcapimin.c
new file mode 100644
index 0000000..0d27717
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcapimin.c
@@ -0,0 +1,280 @@
+/*
+ * jcapimin.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains application interface code for the compression half
+ * of the JPEG library. These are the "minimum" API routines that may be
+ * needed in either the normal full-compression case or the transcoding-only
+ * case.
+ *
+ * Most of the routines intended to be called directly by an application
+ * are in this file or in jcapistd.c. But also see jcparam.c for
+ * parameter-setup helper routines, jcomapi.c for routines shared by
+ * compression and decompression, and jctrans.c for the transcoding case.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Initialization of a JPEG compression object.
+ * The error manager must already be set up (in case memory manager fails).
+ */
+
+GLOBAL(void)
+jpeg_CreateCompress (j_compress_ptr cinfo, int version, size_t structsize)
+{
+ int i;
+
+ /* Guard against version mismatches between library and caller. */
+ cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
+ if (version != JPEG_LIB_VERSION)
+ ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
+ if (structsize != SIZEOF(struct jpeg_compress_struct))
+ ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
+ (int) SIZEOF(struct jpeg_compress_struct), (int) structsize);
+
+ /* For debugging purposes, we zero the whole master structure.
+ * But the application has already set the err pointer, and may have set
+ * client_data, so we have to save and restore those fields.
+ * Note: if application hasn't set client_data, tools like Purify may
+ * complain here.
+ */
+ {
+ struct jpeg_error_mgr * err = cinfo->err;
+ void * client_data = cinfo->client_data; /* ignore Purify complaint here */
+ MEMZERO(cinfo, SIZEOF(struct jpeg_compress_struct));
+ cinfo->err = err;
+ cinfo->client_data = client_data;
+ }
+ cinfo->is_decompressor = FALSE;
+
+ /* Initialize a memory manager instance for this object */
+ jinit_memory_mgr((j_common_ptr) cinfo);
+
+ /* Zero out pointers to permanent structures. */
+ cinfo->progress = NULL;
+ cinfo->dest = NULL;
+
+ cinfo->comp_info = NULL;
+
+ for (i = 0; i < NUM_TQUANT_TBLS; i++)
+ cinfo->quant_tbl_ptrs[i] = NULL;
+
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ cinfo->dc_huff_tbl_ptrs[i] = NULL;
+ cinfo->ac_huff_tbl_ptrs[i] = NULL;
+ }
+
+ cinfo->script_space = NULL;
+
+ cinfo->input_gamma = 1.0; /* in case application forgets */
+
+ /* OK, I'm ready */
+ cinfo->global_state = CSTATE_START;
+}
+
+
+/*
+ * Destruction of a JPEG compression object
+ */
+
+GLOBAL(void)
+jpeg_destroy_compress (j_compress_ptr cinfo)
+{
+ jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Abort processing of a JPEG compression operation,
+ * but don't destroy the object itself.
+ */
+
+GLOBAL(void)
+jpeg_abort_compress (j_compress_ptr cinfo)
+{
+ jpeg_abort((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Forcibly suppress or un-suppress all quantization and Huffman tables.
+ * Marks all currently defined tables as already written (if suppress)
+ * or not written (if !suppress). This will control whether they get emitted
+ * by a subsequent jpeg_start_compress call.
+ *
+ * This routine is exported for use by applications that want to produce
+ * abbreviated JPEG datastreams. It logically belongs in jcparam.c, but
+ * since it is called by jpeg_start_compress, we put it here --- otherwise
+ * jcparam.o would be linked whether the application used it or not.
+ */
+
+GLOBAL(void)
+jpeg_suppress_tables (j_compress_ptr cinfo, boolean suppress)
+{
+ int i;
+ JTQUANT_TBL * qtbl;
+ JHUFF_TBL * htbl;
+
+ for (i = 0; i < NUM_TQUANT_TBLS; i++) {
+ if ((qtbl = cinfo->quant_tbl_ptrs[i]) != NULL)
+ qtbl->sent_table = suppress;
+ }
+
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ if ((htbl = cinfo->dc_huff_tbl_ptrs[i]) != NULL)
+ htbl->sent_table = suppress;
+ if ((htbl = cinfo->ac_huff_tbl_ptrs[i]) != NULL)
+ htbl->sent_table = suppress;
+ }
+}
+
+
+/*
+ * Finish JPEG compression.
+ *
+ * If a multipass operating mode was selected, this may do a great deal of
+ * work including most of the actual output.
+ */
+
+GLOBAL(void)
+jpeg_finish_compress (j_compress_ptr cinfo)
+{
+ JDIMENSION iMCU_row;
+
+ if (cinfo->global_state == CSTATE_SCANNING ||
+ cinfo->global_state == CSTATE_RAW_OK) {
+ /* Terminate first pass */
+ if (cinfo->next_scanline < cinfo->image_height)
+ ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
+ (*cinfo->master->finish_pass) (cinfo);
+ } else if (cinfo->global_state != CSTATE_WRCOEFS)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ /* Perform any remaining passes */
+ while (! cinfo->master->is_last_pass) {
+ (*cinfo->master->prepare_for_pass) (cinfo);
+ for (iMCU_row = 0; iMCU_row < cinfo->total_iMCU_rows; iMCU_row++) {
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) iMCU_row;
+ cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+ /* We bypass the main controller and invoke coef controller directly;
+ * all work is being done from the coefficient buffer.
+ */
+ if (! (*cinfo->coef->compress_data) (cinfo, (JSAMPIMAGE) NULL))
+ ERREXIT(cinfo, JERR_CANT_SUSPEND);
+ }
+ (*cinfo->master->finish_pass) (cinfo);
+ }
+ /* Write EOI, do final cleanup */
+ (*cinfo->marker->write_file_trailer) (cinfo);
+ (*cinfo->dest->term_destination) (cinfo);
+ /* We can use jpeg_abort to release memory and reset global_state */
+ jpeg_abort((j_common_ptr) cinfo);
+}
+
+
+/*
+ * Write a special marker.
+ * This is only recommended for writing COM or APPn markers.
+ * Must be called after jpeg_start_compress() and before
+ * first call to jpeg_write_scanlines() or jpeg_write_raw_data().
+ */
+
+GLOBAL(void)
+jpeg_write_marker (j_compress_ptr cinfo, int marker,
+ const JOCTET *dataptr, unsigned int datalen)
+{
+ JTQT_METHOD(void, write_marker_byte, (j_compress_ptr info, int val));
+
+ if (cinfo->next_scanline != 0 ||
+ (cinfo->global_state != CSTATE_SCANNING &&
+ cinfo->global_state != CSTATE_RAW_OK &&
+ cinfo->global_state != CSTATE_WRCOEFS))
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
+ write_marker_byte = cinfo->marker->write_marker_byte; /* copy for speed */
+ while (datalen--) {
+ (*write_marker_byte) (cinfo, *dataptr);
+ dataptr++;
+ }
+}
+
+/* Same, but piecemeal. */
+
+GLOBAL(void)
+jpeg_write_m_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
+{
+ if (cinfo->next_scanline != 0 ||
+ (cinfo->global_state != CSTATE_SCANNING &&
+ cinfo->global_state != CSTATE_RAW_OK &&
+ cinfo->global_state != CSTATE_WRCOEFS))
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ (*cinfo->marker->write_marker_header) (cinfo, marker, datalen);
+}
+
+GLOBAL(void)
+jpeg_write_m_byte (j_compress_ptr cinfo, int val)
+{
+ (*cinfo->marker->write_marker_byte) (cinfo, val);
+}
+
+
+/*
+ * Alternate compression function: just write an abbreviated table file.
+ * Before calling this, all parameters and a data destination must be set up.
+ *
+ * To produce a pair of files containing abbreviated tables and abbreviated
+ * image data, one would proceed as follows:
+ *
+ * initialize JPEG object
+ * set JPEG parameters
+ * set destination to table file
+ * jpeg_write_tables(cinfo);
+ * set destination to image file
+ * jpeg_start_compress(cinfo, FALSE);
+ * write data...
+ * jpeg_finish_compress(cinfo);
+ *
+ * jpeg_write_tables has the side effect of marking all tables written
+ * (same as jpeg_suppress_tables(..., TRUE)). Thus a subsequent start_compress
+ * will not re-emit the tables unless it is passed write_all_tables=TRUE.
+ */
+
+GLOBAL(void)
+jpeg_write_tables (j_compress_ptr cinfo)
+{
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ /* (Re)initialize error mgr and destination modules */
+ (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+ (*cinfo->dest->init_destination) (cinfo);
+ /* Initialize the marker writer ... bit of a crock to do it here. */
+ jinit_marker_writer(cinfo);
+ /* Write them tables! */
+ (*cinfo->marker->write_tables_only) (cinfo);
+ /* And clean up. */
+ (*cinfo->dest->term_destination) (cinfo);
+ /*
+ * In library releases up through v6a, we called jpeg_abort() here to free
+ * any working memory allocated by the destination manager and marker
+ * writer. Some applications had a problem with that: they allocated space
+ * of their own from the library memory manager, and didn't want it to go
+ * away during write_tables. So now we do nothing. This will cause a
+ * memory leak if an app calls write_tables repeatedly without doing a full
+ * compression cycle or otherwise resetting the JPEG object. However, that
+ * seems less bad than unexpectedly freeing memory in the normal case.
+ * An app that prefers the old behavior can call jpeg_abort for itself after
+ * each call to jpeg_write_tables().
+ */
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcapistd.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcapistd.c
new file mode 100644
index 0000000..d15ae9e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcapistd.c
@@ -0,0 +1,161 @@
+/*
+ * jcapistd.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains application interface code for the compression half
+ * of the JPEG library. These are the "standard" API routines that are
+ * used in the normal full-compression case. They are not used by a
+ * transcoding-only application. Note that if an application links in
+ * jpeg_start_compress, it will end up linking in the entire compressor.
+ * We thus must separate this file from jcapimin.c to avoid linking the
+ * whole compression library into a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Compression initialization.
+ * Before calling this, all parameters and a data destination must be set up.
+ *
+ * We require a write_all_tables parameter as a failsafe check when writing
+ * multiple datastreams from the same compression object. Since prior runs
+ * will have left all the tables marked sent_table=TRUE, a subsequent run
+ * would emit an abbreviated stream (no tables) by default. This may be what
+ * is wanted, but for safety's sake it should not be the default behavior:
+ * programmers should have to make a deliberate choice to emit abbreviated
+ * images. Therefore the documentation and examples should encourage people
+ * to pass write_all_tables=TRUE; then it will take active thought to do the
+ * wrong thing.
+ */
+
+GLOBAL(void)
+jpeg_start_compress (j_compress_ptr cinfo, boolean write_all_tables)
+{
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ if (write_all_tables)
+ jpeg_suppress_tables(cinfo, FALSE); /* mark all tables to be written */
+
+ /* (Re)initialize error mgr and destination modules */
+ (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+ (*cinfo->dest->init_destination) (cinfo);
+ /* Perform master selection of active modules */
+ jinit_compress_master(cinfo);
+ /* Set up for the first pass */
+ (*cinfo->master->prepare_for_pass) (cinfo);
+ /* Ready for application to drive first pass through jpeg_write_scanlines
+ * or jpeg_write_raw_data.
+ */
+ cinfo->next_scanline = 0;
+ cinfo->global_state = (cinfo->raw_data_in ? CSTATE_RAW_OK : CSTATE_SCANNING);
+}
+
+
+/*
+ * Write some scanlines of data to the JPEG compressor.
+ *
+ * The return value will be the number of lines actually written.
+ * This should be less than the supplied num_lines only in case that
+ * the data destination module has requested suspension of the compressor,
+ * or if more than image_height scanlines are passed in.
+ *
+ * Note: we warn about excess calls to jpeg_write_scanlines() since
+ * this likely Q_SIGNALS an application programmer error. However,
+ * excess scanlines passed in the last valid call are *silently* ignored,
+ * so that the application need not adjust num_lines for end-of-image
+ * when using a multiple-scanline buffer.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_write_scanlines (j_compress_ptr cinfo, JSAMPARRAY scanlines,
+ JDIMENSION num_lines)
+{
+ JDIMENSION row_ctr, rows_left;
+
+ if (cinfo->global_state != CSTATE_SCANNING)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ if (cinfo->next_scanline >= cinfo->image_height)
+ WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) cinfo->next_scanline;
+ cinfo->progress->pass_limit = (long) cinfo->image_height;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+
+ /* Give master control module another chance if this is first call to
+ * jpeg_write_scanlines. This lets output of the frame/scan headers be
+ * delayed so that application can write COM, etc, markers between
+ * jpeg_start_compress and jpeg_write_scanlines.
+ */
+ if (cinfo->master->call_pass_startup)
+ (*cinfo->master->pass_startup) (cinfo);
+
+ /* Ignore any extra scanlines at bottom of image. */
+ rows_left = cinfo->image_height - cinfo->next_scanline;
+ if (num_lines > rows_left)
+ num_lines = rows_left;
+
+ row_ctr = 0;
+ (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, num_lines);
+ cinfo->next_scanline += row_ctr;
+ return row_ctr;
+}
+
+
+/*
+ * Alternate entry point to write raw data.
+ * Processes exactly one iMCU row per call, unless suspended.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_write_raw_data (j_compress_ptr cinfo, JSAMPIMAGE data,
+ JDIMENSION num_lines)
+{
+ JDIMENSION lines_per_iMCU_row;
+
+ if (cinfo->global_state != CSTATE_RAW_OK)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ if (cinfo->next_scanline >= cinfo->image_height) {
+ WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+ return 0;
+ }
+
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) cinfo->next_scanline;
+ cinfo->progress->pass_limit = (long) cinfo->image_height;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+
+ /* Give master control module another chance if this is first call to
+ * jpeg_write_raw_data. This lets output of the frame/scan headers be
+ * delayed so that application can write COM, etc, markers between
+ * jpeg_start_compress and jpeg_write_raw_data.
+ */
+ if (cinfo->master->call_pass_startup)
+ (*cinfo->master->pass_startup) (cinfo);
+
+ /* Verify that at least one iMCU row has been passed. */
+ lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE;
+ if (num_lines < lines_per_iMCU_row)
+ ERREXIT(cinfo, JERR_BUFFER_SIZE);
+
+ /* Directly compress the row. */
+ if (! (*cinfo->coef->compress_data) (cinfo, data)) {
+ /* If compressor did not consume the whole row, suspend processing. */
+ return 0;
+ }
+
+ /* OK, we processed one iMCU row. */
+ cinfo->next_scanline += lines_per_iMCU_row;
+ return lines_per_iMCU_row;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jccoefct.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jccoefct.c
new file mode 100644
index 0000000..8a322e6
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jccoefct.c
@@ -0,0 +1,449 @@
+/*
+ * jccoefct.c
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains the coefficient buffer controller for compression.
+ * This controller is the top level of the JPEG compressor proper.
+ * The coefficient buffer lies between forward-DCT and entropy encoding steps.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* We use a full-image coefficient buffer when doing Huffman optimization,
+ * and also for writing multiple-scan JPEG files. In all cases, the DCT
+ * step is run during the first pass, and subsequent passes need only read
+ * the buffered coefficients.
+ */
+#ifdef ENTROPY_OPT_SUPPORTED
+#define FULL_COEF_BUFFER_SUPPORTED
+#else
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+#define FULL_COEF_BUFFER_SUPPORTED
+#endif
+#endif
+
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_c_coef_controller pub; /* public fields */
+
+ JDIMENSION iMCU_row_num; /* iMCU row # within image */
+ JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
+ int MCU_vert_offset; /* counts MCU rows within iMCU row */
+ int MCU_rows_per_iMCU_row; /* number of such rows needed */
+
+ /* For single-pass compression, it's sufficient to buffer just one MCU
+ * (although this may prove a bit slow in practice). We allocate a
+ * workspace of C_MAX_BLOCKS_IN_MCU coefficient blocks, and reuse it for each
+ * MCU constructed and sent. (On 80x86, the workspace is FAR even though
+ * it's not really very big; this is to keep the module interfaces unchanged
+ * when a large coefficient buffer is necessary.)
+ * In multi-pass modes, this array points to the current MCU's blocks
+ * within the virtual arrays.
+ */
+ JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
+
+ /* In multi-pass modes, we need a virtual block array for each component. */
+ jvirt_barray_ptr whole_image[MAX_COMPONENTS];
+} my_coef_controller;
+
+typedef my_coef_controller * my_coef_ptr;
+
+
+/* Forward declarations */
+METHODDEF(boolean) compress_data
+ JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+METHODDEF(boolean) compress_first_pass
+ JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
+METHODDEF(boolean) compress_output
+ JPP((j_compress_ptr cinfo, JSAMPIMAGE input_buf));
+#endif
+
+
+LOCAL(void)
+start_iMCU_row (j_compress_ptr cinfo)
+/* Reset within-iMCU-row counters for a new row */
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ /* In an interleaved scan, an MCU row is the same as an iMCU row.
+ * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
+ * But at the bottom of the image, process only what's left.
+ */
+ if (cinfo->comps_in_scan > 1) {
+ coef->MCU_rows_per_iMCU_row = 1;
+ } else {
+ if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
+ else
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
+ }
+
+ coef->mcu_ctr = 0;
+ coef->MCU_vert_offset = 0;
+}
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ coef->iMCU_row_num = 0;
+ start_iMCU_row(cinfo);
+
+ switch (pass_mode) {
+ case JBUF_PASS_THRU:
+ if (coef->whole_image[0] != NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ coef->pub.compress_data = compress_data;
+ break;
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+ case JBUF_SAVE_AND_PASS:
+ if (coef->whole_image[0] == NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ coef->pub.compress_data = compress_first_pass;
+ break;
+ case JBUF_CRANK_DEST:
+ if (coef->whole_image[0] == NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ coef->pub.compress_data = compress_output;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ break;
+ }
+}
+
+
+/*
+ * Process some data in the single-pass case.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the image.
+ * Returns TRUE if the iMCU row is completed, FALSE if suspended.
+ *
+ * NB: input_buf tqcontains a plane for each component in image,
+ * which we index according to the component's SOF position.
+ */
+
+METHODDEF(boolean)
+compress_data (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION MCU_col_num; /* index of current MCU within row */
+ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ int blkn, bi, ci, yindex, yoffset, blockcnt;
+ JDIMENSION ypos, xpos;
+ jpeg_component_info *compptr;
+
+ /* Loop to write as much as one whole iMCU row */
+ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+ yoffset++) {
+ for (MCU_col_num = coef->mcu_ctr; MCU_col_num <= last_MCU_col;
+ MCU_col_num++) {
+ /* Determine where data comes from in input_buf and do the DCT thing.
+ * Each call on forward_DCT processes a horizontal row of DCT blocks
+ * as wide as an MCU; we rely on having allocated the MCU_buffer[] blocks
+ * sequentially. Dummy blocks at the right or bottom edge are filled in
+ * specially. The data in them does not matter for image reconstruction,
+ * so we fill them with values that will encode to the smallest amount of
+ * data, viz: all zeroes in the AC entries, DC entries equal to previous
+ * block's DC value. (Thanks to Thomas Kinsman for this idea.)
+ */
+ blkn = 0;
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
+ : compptr->last_col_width;
+ xpos = MCU_col_num * compptr->MCU_sample_width;
+ ypos = yoffset * DCTSIZE; /* ypos == (yoffset+yindex) * DCTSIZE */
+ for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+ if (coef->iMCU_row_num < last_iMCU_row ||
+ yoffset+yindex < compptr->last_row_height) {
+ (*cinfo->fdct->forward_DCT) (cinfo, compptr,
+ input_buf[compptr->component_index],
+ coef->MCU_buffer[blkn],
+ ypos, xpos, (JDIMENSION) blockcnt);
+ if (blockcnt < compptr->MCU_width) {
+ /* Create some dummy blocks at the right edge of the image. */
+ jzero_far((void FAR *) coef->MCU_buffer[blkn + blockcnt],
+ (compptr->MCU_width - blockcnt) * SIZEOF(JBLOCK));
+ for (bi = blockcnt; bi < compptr->MCU_width; bi++) {
+ coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn+bi-1][0][0];
+ }
+ }
+ } else {
+ /* Create a row of dummy blocks at the bottom of the image. */
+ jzero_far((void FAR *) coef->MCU_buffer[blkn],
+ compptr->MCU_width * SIZEOF(JBLOCK));
+ for (bi = 0; bi < compptr->MCU_width; bi++) {
+ coef->MCU_buffer[blkn+bi][0][0] = coef->MCU_buffer[blkn-1][0][0];
+ }
+ }
+ blkn += compptr->MCU_width;
+ ypos += DCTSIZE;
+ }
+ }
+ /* Try to write the MCU. In event of a suspension failure, we will
+ * re-DCT the MCU on restart (a bit inefficient, could be fixed...)
+ */
+ if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
+ /* Suspension forced; update state counters and exit */
+ coef->MCU_vert_offset = yoffset;
+ coef->mcu_ctr = MCU_col_num;
+ return FALSE;
+ }
+ }
+ /* Completed an MCU row, but perhaps not an iMCU row */
+ coef->mcu_ctr = 0;
+ }
+ /* Completed the iMCU row, advance counters for next one */
+ coef->iMCU_row_num++;
+ start_iMCU_row(cinfo);
+ return TRUE;
+}
+
+
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+
+/*
+ * Process some data in the first pass of a multi-pass case.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the image.
+ * This amount of data is read from the source buffer, DCT'd and quantized,
+ * and saved into the virtual arrays. We also generate suitable dummy blocks
+ * as needed at the right and lower edges. (The dummy blocks are constructed
+ * in the virtual arrays, which have been padded appropriately.) This makes
+ * it possible for subsequent passes not to worry about real vs. dummy blocks.
+ *
+ * We must also emit the data to the entropy encoder. This is conveniently
+ * done by calling compress_output() after we've loaded the current strip
+ * of the virtual arrays.
+ *
+ * NB: input_buf tqcontains a plane for each component in image. All
+ * components are DCT'd and loaded into the virtual arrays in this pass.
+ * However, it may be that only a subset of the components are emitted to
+ * the entropy encoder during this first pass; be careful about looking
+ * at the scan-dependent variables (MCU dimensions, etc).
+ */
+
+METHODDEF(boolean)
+compress_first_pass (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ JDIMENSION blocks_across, MCUs_across, MCUindex;
+ int bi, ci, h_samp_factor, block_row, block_rows, ndummy;
+ JCOEF lastDC;
+ jpeg_component_info *compptr;
+ JBLOCKARRAY buffer;
+ JBLOCKROW thisblockrow, lastblockrow;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Align the virtual buffer for this component. */
+ buffer = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[ci],
+ coef->iMCU_row_num * compptr->v_samp_factor,
+ (JDIMENSION) compptr->v_samp_factor, TRUE);
+ /* Count non-dummy DCT block rows in this iMCU row. */
+ if (coef->iMCU_row_num < last_iMCU_row)
+ block_rows = compptr->v_samp_factor;
+ else {
+ /* NB: can't use last_row_height here, since may not be set! */
+ block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+ if (block_rows == 0) block_rows = compptr->v_samp_factor;
+ }
+ blocks_across = compptr->width_in_blocks;
+ h_samp_factor = compptr->h_samp_factor;
+ /* Count number of dummy blocks to be added at the right margin. */
+ ndummy = (int) (blocks_across % h_samp_factor);
+ if (ndummy > 0)
+ ndummy = h_samp_factor - ndummy;
+ /* Perform DCT for all non-dummy blocks in this iMCU row. Each call
+ * on forward_DCT processes a complete horizontal row of DCT blocks.
+ */
+ for (block_row = 0; block_row < block_rows; block_row++) {
+ thisblockrow = buffer[block_row];
+ (*cinfo->fdct->forward_DCT) (cinfo, compptr,
+ input_buf[ci], thisblockrow,
+ (JDIMENSION) (block_row * DCTSIZE),
+ (JDIMENSION) 0, blocks_across);
+ if (ndummy > 0) {
+ /* Create dummy blocks at the right edge of the image. */
+ thisblockrow += blocks_across; /* => first dummy block */
+ jzero_far((void FAR *) thisblockrow, ndummy * SIZEOF(JBLOCK));
+ lastDC = thisblockrow[-1][0];
+ for (bi = 0; bi < ndummy; bi++) {
+ thisblockrow[bi][0] = lastDC;
+ }
+ }
+ }
+ /* If at end of image, create dummy block rows as needed.
+ * The tricky part here is that within each MCU, we want the DC values
+ * of the dummy blocks to match the last real block's DC value.
+ * This squeezes a few more bytes out of the resulting file...
+ */
+ if (coef->iMCU_row_num == last_iMCU_row) {
+ blocks_across += ndummy; /* include lower right corner */
+ MCUs_across = blocks_across / h_samp_factor;
+ for (block_row = block_rows; block_row < compptr->v_samp_factor;
+ block_row++) {
+ thisblockrow = buffer[block_row];
+ lastblockrow = buffer[block_row-1];
+ jzero_far((void FAR *) thisblockrow,
+ (size_t) (blocks_across * SIZEOF(JBLOCK)));
+ for (MCUindex = 0; MCUindex < MCUs_across; MCUindex++) {
+ lastDC = lastblockrow[h_samp_factor-1][0];
+ for (bi = 0; bi < h_samp_factor; bi++) {
+ thisblockrow[bi][0] = lastDC;
+ }
+ thisblockrow += h_samp_factor; /* advance to next MCU in row */
+ lastblockrow += h_samp_factor;
+ }
+ }
+ }
+ }
+ /* NB: compress_output will increment iMCU_row_num if successful.
+ * A suspension return will result in redoing all the work above next time.
+ */
+
+ /* Emit data to the entropy encoder, sharing code with subsequent passes */
+ return compress_output(cinfo, input_buf);
+}
+
+
+/*
+ * Process some data in subsequent passes of a multi-pass case.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the scan.
+ * The data is obtained from the virtual arrays and fed to the entropy coder.
+ * Returns TRUE if the iMCU row is completed, FALSE if suspended.
+ *
+ * NB: input_buf is ignored; it is likely to be a NULL pointer.
+ */
+
+METHODDEF(boolean)
+compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION MCU_col_num; /* index of current MCU within row */
+ int blkn, ci, xindex, yindex, yoffset;
+ JDIMENSION start_col;
+ JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
+ JBLOCKROW buffer_ptr;
+ jpeg_component_info *compptr;
+
+ /* Align the virtual buffers for the components used in this scan.
+ * NB: during first pass, this is safe only because the buffers will
+ * already be aligned properly, so jmemmgr.c won't need to do any I/O.
+ */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ buffer[ci] = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
+ coef->iMCU_row_num * compptr->v_samp_factor,
+ (JDIMENSION) compptr->v_samp_factor, FALSE);
+ }
+
+ /* Loop to process one whole iMCU row */
+ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+ yoffset++) {
+ for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
+ MCU_col_num++) {
+ /* Construct list of pointers to DCT blocks belonging to this MCU */
+ blkn = 0; /* index of current DCT block within MCU */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ start_col = MCU_col_num * compptr->MCU_width;
+ for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+ buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
+ for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
+ coef->MCU_buffer[blkn++] = buffer_ptr++;
+ }
+ }
+ }
+ /* Try to write the MCU. */
+ if (! (*cinfo->entropy->encode_mcu) (cinfo, coef->MCU_buffer)) {
+ /* Suspension forced; update state counters and exit */
+ coef->MCU_vert_offset = yoffset;
+ coef->mcu_ctr = MCU_col_num;
+ return FALSE;
+ }
+ }
+ /* Completed an MCU row, but perhaps not an iMCU row */
+ coef->mcu_ctr = 0;
+ }
+ /* Completed the iMCU row, advance counters for next one */
+ coef->iMCU_row_num++;
+ start_iMCU_row(cinfo);
+ return TRUE;
+}
+
+#endif /* FULL_COEF_BUFFER_SUPPORTED */
+
+
+/*
+ * Initialize coefficient buffer controller.
+ */
+
+GLOBAL(void)
+jinit_c_coef_controller (j_compress_ptr cinfo, boolean need_full_buffer)
+{
+ my_coef_ptr coef;
+
+ coef = (my_coef_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_coef_controller));
+ cinfo->coef = (struct jpeg_c_coef_controller *) coef;
+ coef->pub.start_pass = start_pass_coef;
+
+ /* Create the coefficient buffer. */
+ if (need_full_buffer) {
+#ifdef FULL_COEF_BUFFER_SUPPORTED
+ /* Allocate a full-image virtual array for each component, */
+ /* padded to a multiple of samp_factor DCT blocks in each direction. */
+ int ci;
+ jpeg_component_info *compptr;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
+ (JDIMENSION) jround_up((long) compptr->width_in_blocks,
+ (long) compptr->h_samp_factor),
+ (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+ (long) compptr->v_samp_factor),
+ (JDIMENSION) compptr->v_samp_factor);
+ }
+#else
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif
+ } else {
+ /* We only need a single-MCU buffer. */
+ JBLOCKROW buffer;
+ int i;
+
+ buffer = (JBLOCKROW)
+ (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+ for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
+ coef->MCU_buffer[i] = buffer + i;
+ }
+ coef->whole_image[0] = NULL; /* flag for no virtual arrays */
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jccolor.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jccolor.c
new file mode 100644
index 0000000..894df01
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jccolor.c
@@ -0,0 +1,459 @@
+/*
+ * jccolor.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains input colorspace conversion routines.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_color_converter pub; /* public fields */
+
+ /* Private state for RGB->YCC conversion */
+ INT32 * rgb_ycc_tab; /* => table for RGB to YCbCr conversion */
+} my_color_converter;
+
+typedef my_color_converter * my_cconvert_ptr;
+
+
+/**************** RGB -> YCbCr conversion: most common case **************/
+
+/*
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
+ * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE
+ * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE
+ * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
+ * Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,
+ * rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and
+ * negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)
+ * were not represented exactly. Now we sacrifice exact representation of
+ * maximum red and maximum blue in order to get exact grayscales.
+ *
+ * To avoid floating-point arithmetic, we represent the fractional constants
+ * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
+ * the products by 2^16, with appropriate rounding, to get the correct answer.
+ *
+ * For even more speed, we avoid doing any multiplications in the inner loop
+ * by precalculating the constants times R,G,B for all possible values.
+ * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
+ * for 12-bit samples it is still acceptable. It's not very reasonable for
+ * 16-bit samples, but if you want lossless storage you shouldn't be changing
+ * colorspace anyway.
+ * The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included
+ * in the tables to save adding them separately in the inner loop.
+ */
+
+#define SCALEBITS 16 /* speediest right-shift on some machines */
+#define CBCR_OFFSET ((INT32) CENTERJSAMPLE << SCALEBITS)
+#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
+#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
+
+/* We allocate one big table and divide it up into eight parts, instead of
+ * doing eight alloc_small requests. This lets us use a single table base
+ * address, which can be held in a register in the inner loops on many
+ * machines (more than can hold all eight addresses, anyway).
+ */
+
+#define R_Y_OFF 0 /* offset to R => Y section */
+#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */
+#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */
+#define R_CB_OFF (3*(MAXJSAMPLE+1))
+#define G_CB_OFF (4*(MAXJSAMPLE+1))
+#define B_CB_OFF (5*(MAXJSAMPLE+1))
+#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */
+#define G_CR_OFF (6*(MAXJSAMPLE+1))
+#define B_CR_OFF (7*(MAXJSAMPLE+1))
+#define TABLE_SIZE (8*(MAXJSAMPLE+1))
+
+
+/*
+ * Initialize for RGB->YCC colorspace conversion.
+ */
+
+METHODDEF(void)
+rgb_ycc_start (j_compress_ptr cinfo)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ INT32 * rgb_ycc_tab;
+ INT32 i;
+
+ /* Allocate and fill in the conversion tables. */
+ cconvert->rgb_ycc_tab = rgb_ycc_tab = (INT32 *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (TABLE_SIZE * SIZEOF(INT32)));
+
+ for (i = 0; i <= MAXJSAMPLE; i++) {
+ rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;
+ rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;
+ rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
+ rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;
+ rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;
+ /* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.
+ * This ensures that the maximum output will round to MAXJSAMPLE
+ * not MAXJSAMPLE+1, and thus that we don't have to range-limit.
+ */
+ rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
+/* B=>Cb and R=>Cr tables are the same
+ rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;
+*/
+ rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;
+ rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;
+ }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ *
+ * Note that we change from the application's interleaved-pixel format
+ * to our internal noninterleaved, one-plane-per-component format.
+ * The input buffer is therefore three times as wide as the output buffer.
+ *
+ * A starting row offset is provided only for the output buffer. The caller
+ * can easily adjust the passed input_buf value to accommodate any row
+ * offset required on that side.
+ */
+
+METHODDEF(void)
+rgb_ycc_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ register int r, g, b;
+ register INT32 * ctab = cconvert->rgb_ycc_tab;
+ register JSAMPROW inptr;
+ register JSAMPROW outptr0, outptr1, outptr2;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->image_width;
+
+ while (--num_rows >= 0) {
+ inptr = *input_buf++;
+ outptr0 = output_buf[0][output_row];
+ outptr1 = output_buf[1][output_row];
+ outptr2 = output_buf[2][output_row];
+ output_row++;
+ for (col = 0; col < num_cols; col++) {
+ r = GETJSAMPLE(inptr[RGB_RED]);
+ g = GETJSAMPLE(inptr[RGB_GREEN]);
+ b = GETJSAMPLE(inptr[RGB_BLUE]);
+ inptr += RGB_PIXELSIZE;
+ /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
+ * must be too; we do not need an explicit range-limiting operation.
+ * Hence the value being shifted is never negative, and we don't
+ * need the general RIGHT_SHIFT macro.
+ */
+ /* Y */
+ outptr0[col] = (JSAMPLE)
+ ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+ >> SCALEBITS);
+ /* Cb */
+ outptr1[col] = (JSAMPLE)
+ ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
+ >> SCALEBITS);
+ /* Cr */
+ outptr2[col] = (JSAMPLE)
+ ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
+ >> SCALEBITS);
+ }
+ }
+}
+
+
+/**************** Cases other than RGB -> YCbCr **************/
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles RGB->grayscale conversion, which is the same
+ * as the RGB->Y portion of RGB->YCbCr.
+ * We assume rgb_ycc_start has been called (we only use the Y tables).
+ */
+
+METHODDEF(void)
+rgb_gray_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ register int r, g, b;
+ register INT32 * ctab = cconvert->rgb_ycc_tab;
+ register JSAMPROW inptr;
+ register JSAMPROW outptr;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->image_width;
+
+ while (--num_rows >= 0) {
+ inptr = *input_buf++;
+ outptr = output_buf[0][output_row];
+ output_row++;
+ for (col = 0; col < num_cols; col++) {
+ r = GETJSAMPLE(inptr[RGB_RED]);
+ g = GETJSAMPLE(inptr[RGB_GREEN]);
+ b = GETJSAMPLE(inptr[RGB_BLUE]);
+ inptr += RGB_PIXELSIZE;
+ /* Y */
+ outptr[col] = (JSAMPLE)
+ ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+ >> SCALEBITS);
+ }
+ }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles Adobe-style CMYK->YCCK conversion,
+ * where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same
+ * conversion as above, while passing K (black) unchanged.
+ * We assume rgb_ycc_start has been called.
+ */
+
+METHODDEF(void)
+cmyk_ycck_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ register int r, g, b;
+ register INT32 * ctab = cconvert->rgb_ycc_tab;
+ register JSAMPROW inptr;
+ register JSAMPROW outptr0, outptr1, outptr2, outptr3;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->image_width;
+
+ while (--num_rows >= 0) {
+ inptr = *input_buf++;
+ outptr0 = output_buf[0][output_row];
+ outptr1 = output_buf[1][output_row];
+ outptr2 = output_buf[2][output_row];
+ outptr3 = output_buf[3][output_row];
+ output_row++;
+ for (col = 0; col < num_cols; col++) {
+ r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);
+ g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);
+ b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);
+ /* K passes through as-is */
+ outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */
+ inptr += 4;
+ /* If the inputs are 0..MAXJSAMPLE, the outputs of these equations
+ * must be too; we do not need an explicit range-limiting operation.
+ * Hence the value being shifted is never negative, and we don't
+ * need the general RIGHT_SHIFT macro.
+ */
+ /* Y */
+ outptr0[col] = (JSAMPLE)
+ ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
+ >> SCALEBITS);
+ /* Cb */
+ outptr1[col] = (JSAMPLE)
+ ((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])
+ >> SCALEBITS);
+ /* Cr */
+ outptr2[col] = (JSAMPLE)
+ ((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])
+ >> SCALEBITS);
+ }
+ }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles grayscale output with no conversion.
+ * The source can be either plain grayscale or YCbCr (since Y == gray).
+ */
+
+METHODDEF(void)
+grayscale_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ register JSAMPROW inptr;
+ register JSAMPROW outptr;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->image_width;
+ int instride = cinfo->input_components;
+
+ while (--num_rows >= 0) {
+ inptr = *input_buf++;
+ outptr = output_buf[0][output_row];
+ output_row++;
+ for (col = 0; col < num_cols; col++) {
+ outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */
+ inptr += instride;
+ }
+ }
+}
+
+
+/*
+ * Convert some rows of samples to the JPEG colorspace.
+ * This version handles multi-component colorspaces without conversion.
+ * We assume input_components == num_components.
+ */
+
+METHODDEF(void)
+null_convert (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows)
+{
+ register JSAMPROW inptr;
+ register JSAMPROW outptr;
+ register JDIMENSION col;
+ register int ci;
+ int nc = cinfo->num_components;
+ JDIMENSION num_cols = cinfo->image_width;
+
+ while (--num_rows >= 0) {
+ /* It seems fastest to make a separate pass for each component. */
+ for (ci = 0; ci < nc; ci++) {
+ inptr = *input_buf;
+ outptr = output_buf[ci][output_row];
+ for (col = 0; col < num_cols; col++) {
+ outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */
+ inptr += nc;
+ }
+ }
+ input_buf++;
+ output_row++;
+ }
+}
+
+
+/*
+ * Empty method for start_pass.
+ */
+
+METHODDEF(void)
+null_method (j_compress_ptr cinfo)
+{
+ /* no work needed */
+}
+
+
+/*
+ * Module initialization routine for input colorspace conversion.
+ */
+
+GLOBAL(void)
+jinit_color_converter (j_compress_ptr cinfo)
+{
+ my_cconvert_ptr cconvert;
+
+ cconvert = (my_cconvert_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_color_converter));
+ cinfo->cconvert = (struct jpeg_color_converter *) cconvert;
+ /* set start_pass to null method until we tqfind out differently */
+ cconvert->pub.start_pass = null_method;
+
+ /* Make sure input_components agrees with in_color_space */
+ switch (cinfo->in_color_space) {
+ case JCS_GRAYSCALE:
+ if (cinfo->input_components != 1)
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ break;
+
+ case JCS_RGB:
+#if RGB_PIXELSIZE != 3
+ if (cinfo->input_components != RGB_PIXELSIZE)
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ break;
+#endif /* else share code with YCbCr */
+
+ case JCS_YCbCr:
+ if (cinfo->input_components != 3)
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ break;
+
+ case JCS_CMYK:
+ case JCS_YCCK:
+ if (cinfo->input_components != 4)
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ break;
+
+ default: /* JCS_UNKNOWN can be anything */
+ if (cinfo->input_components < 1)
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ break;
+ }
+
+ /* Check num_components, set conversion method based on requested space */
+ switch (cinfo->jpeg_color_space) {
+ case JCS_GRAYSCALE:
+ if (cinfo->num_components != 1)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ if (cinfo->in_color_space == JCS_GRAYSCALE)
+ cconvert->pub.color_convert = grayscale_convert;
+ else if (cinfo->in_color_space == JCS_RGB) {
+ cconvert->pub.start_pass = rgb_ycc_start;
+ cconvert->pub.color_convert = rgb_gray_convert;
+ } else if (cinfo->in_color_space == JCS_YCbCr)
+ cconvert->pub.color_convert = grayscale_convert;
+ else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_RGB:
+ if (cinfo->num_components != 3)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ if (cinfo->in_color_space == JCS_RGB && RGB_PIXELSIZE == 3)
+ cconvert->pub.color_convert = null_convert;
+ else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_YCbCr:
+ if (cinfo->num_components != 3)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ if (cinfo->in_color_space == JCS_RGB) {
+ cconvert->pub.start_pass = rgb_ycc_start;
+ cconvert->pub.color_convert = rgb_ycc_convert;
+ } else if (cinfo->in_color_space == JCS_YCbCr)
+ cconvert->pub.color_convert = null_convert;
+ else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_CMYK:
+ if (cinfo->num_components != 4)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ if (cinfo->in_color_space == JCS_CMYK)
+ cconvert->pub.color_convert = null_convert;
+ else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_YCCK:
+ if (cinfo->num_components != 4)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ if (cinfo->in_color_space == JCS_CMYK) {
+ cconvert->pub.start_pass = rgb_ycc_start;
+ cconvert->pub.color_convert = cmyk_ycck_convert;
+ } else if (cinfo->in_color_space == JCS_YCCK)
+ cconvert->pub.color_convert = null_convert;
+ else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ default: /* allow null conversion of JCS_UNKNOWN */
+ if (cinfo->jpeg_color_space != cinfo->in_color_space ||
+ cinfo->num_components != cinfo->input_components)
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ cconvert->pub.color_convert = null_convert;
+ break;
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcdctmgr.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcdctmgr.c
new file mode 100644
index 0000000..e580797
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcdctmgr.c
@@ -0,0 +1,387 @@
+/*
+ * jcdctmgr.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains the forward-DCT management logic.
+ * This code selects a particular DCT implementation to be used,
+ * and it performs related housekeeping chores including coefficient
+ * quantization.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+
+/* Private subobject for this module */
+
+typedef struct {
+ struct jpeg_forward_dct pub; /* public fields */
+
+ /* Pointer to the DCT routine actually in use */
+ forward_DCT_method_ptr do_dct;
+
+ /* The actual post-DCT divisors --- not identical to the quant table
+ * entries, because of scaling (especially for an unnormalized DCT).
+ * Each table is given in normal array order.
+ */
+ DCTELEM * divisors[NUM_TQUANT_TBLS];
+
+#ifdef DCT_FLOAT_SUPPORTED
+ /* Same as above for the floating-point case. */
+ float_DCT_method_ptr do_float_dct;
+ FAST_FLOAT * float_divisors[NUM_TQUANT_TBLS];
+#endif
+} my_fdct_controller;
+
+typedef my_fdct_controller * my_fdct_ptr;
+
+
+/*
+ * Initialize for a processing pass.
+ * Verify that all referenced Q-tables are present, and set up
+ * the divisor table for each one.
+ * In the current implementation, DCT of all components is done during
+ * the first pass, even if only some components will be output in the
+ * first scan. Hence all components should be examined here.
+ */
+
+METHODDEF(void)
+start_pass_fdctmgr (j_compress_ptr cinfo)
+{
+ my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
+ int ci, qtblno, i;
+ jpeg_component_info *compptr;
+ JTQUANT_TBL * qtbl;
+ DCTELEM * dtbl;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ qtblno = compptr->quant_tbl_no;
+ /* Make sure specified quantization table is present */
+ if (qtblno < 0 || qtblno >= NUM_TQUANT_TBLS ||
+ cinfo->quant_tbl_ptrs[qtblno] == NULL)
+ ERREXIT1(cinfo, JERR_NO_TQUANT_TABLE, qtblno);
+ qtbl = cinfo->quant_tbl_ptrs[qtblno];
+ /* Compute divisors for this quant table */
+ /* We may do this more than once for same table, but it's not a big deal */
+ switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+ case JDCT_ISLOW:
+ /* For LL&M IDCT method, divisors are equal to raw quantization
+ * coefficients multiplied by 8 (to counteract scaling).
+ */
+ if (fdct->divisors[qtblno] == NULL) {
+ fdct->divisors[qtblno] = (DCTELEM *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ DCTSIZE2 * SIZEOF(DCTELEM));
+ }
+ dtbl = fdct->divisors[qtblno];
+ for (i = 0; i < DCTSIZE2; i++) {
+ dtbl[i] = ((DCTELEM) qtbl->quantval[i]) << 3;
+ }
+ break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+ case JDCT_IFAST:
+ {
+ /* For AA&N IDCT method, divisors are equal to quantization
+ * coefficients scaled by scalefactor[row]*scalefactor[col], where
+ * scalefactor[0] = 1
+ * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
+ * We apply a further scale factor of 8.
+ */
+#define CONST_BITS 14
+ static const INT16 aanscales[DCTSIZE2] = {
+ /* precomputed values scaled up by 14 bits */
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
+ 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
+ 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
+ 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
+ 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
+ };
+ SHIFT_TEMPS
+
+ if (fdct->divisors[qtblno] == NULL) {
+ fdct->divisors[qtblno] = (DCTELEM *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ DCTSIZE2 * SIZEOF(DCTELEM));
+ }
+ dtbl = fdct->divisors[qtblno];
+ for (i = 0; i < DCTSIZE2; i++) {
+ dtbl[i] = (DCTELEM)
+ DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
+ (INT32) aanscales[i]),
+ CONST_BITS-3);
+ }
+ }
+ break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ case JDCT_FLOAT:
+ {
+ /* For float AA&N IDCT method, divisors are equal to quantization
+ * coefficients scaled by scalefactor[row]*scalefactor[col], where
+ * scalefactor[0] = 1
+ * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
+ * We apply a further scale factor of 8.
+ * What's actually stored is 1/divisor so that the inner loop can
+ * use a multiplication rather than a division.
+ */
+ FAST_FLOAT * fdtbl;
+ int row, col;
+ static const double aanscalefactor[DCTSIZE] = {
+ 1.0, 1.387039845, 1.306562965, 1.175875602,
+ 1.0, 0.785694958, 0.541196100, 0.275899379
+ };
+
+ if (fdct->float_divisors[qtblno] == NULL) {
+ fdct->float_divisors[qtblno] = (FAST_FLOAT *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ DCTSIZE2 * SIZEOF(FAST_FLOAT));
+ }
+ fdtbl = fdct->float_divisors[qtblno];
+ i = 0;
+ for (row = 0; row < DCTSIZE; row++) {
+ for (col = 0; col < DCTSIZE; col++) {
+ fdtbl[i] = (FAST_FLOAT)
+ (1.0 / (((double) qtbl->quantval[i] *
+ aanscalefactor[row] * aanscalefactor[col] * 8.0)));
+ i++;
+ }
+ }
+ }
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+ }
+}
+
+
+/*
+ * Perform forward DCT on one or more blocks of a component.
+ *
+ * The input samples are taken from the sample_data[] array starting at
+ * position start_row/start_col, and moving to the right for any additional
+ * blocks. The quantized coefficients are returned in coef_blocks[].
+ */
+
+METHODDEF(void)
+forward_DCT (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
+ JDIMENSION start_row, JDIMENSION start_col,
+ JDIMENSION num_blocks)
+/* This version is used for integer DCT implementations. */
+{
+ /* This routine is heavily used, so it's worth coding it tightly. */
+ my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
+ forward_DCT_method_ptr do_dct = fdct->do_dct;
+ DCTELEM * divisors = fdct->divisors[compptr->quant_tbl_no];
+ DCTELEM workspace[DCTSIZE2]; /* work area for FDCT subroutine */
+ JDIMENSION bi;
+
+ sample_data += start_row; /* fold in the vertical offset once */
+
+ for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
+ /* Load data into workspace, applying unsigned->signed conversion */
+ { register DCTELEM *workspaceptr;
+ register JSAMPROW elemptr;
+ register int elemr;
+
+ workspaceptr = workspace;
+ for (elemr = 0; elemr < DCTSIZE; elemr++) {
+ elemptr = sample_data[elemr] + start_col;
+#if DCTSIZE == 8 /* unroll the inner loop */
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+#else
+ { register int elemc;
+ for (elemc = DCTSIZE; elemc > 0; elemc--) {
+ *workspaceptr++ = GETJSAMPLE(*elemptr++) - CENTERJSAMPLE;
+ }
+ }
+#endif
+ }
+ }
+
+ /* Perform the DCT */
+ (*do_dct) (workspace);
+
+ /* Quantize/descale the coefficients, and store into coef_blocks[] */
+ { register DCTELEM temp, qval;
+ register int i;
+ register JCOEFPTR output_ptr = coef_blocks[bi];
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ qval = divisors[i];
+ temp = workspace[i];
+ /* Divide the coefficient value by qval, ensuring proper rounding.
+ * Since C does not specify the direction of rounding for negative
+ * quotients, we have to force the dividend positive for portability.
+ *
+ * In most files, at least half of the output values will be zero
+ * (at default quantization settings, more like three-quarters...)
+ * so we should ensure that this case is fast. On many machines,
+ * a comparison is enough cheaper than a divide to make a special test
+ * a win. Since both inputs will be nonnegative, we need only test
+ * for a < b to discover whether a/b is 0.
+ * If your machine's division is fast enough, define FAST_DIVIDE.
+ */
+#ifdef FAST_DIVIDE
+#define DIVIDE_BY(a,b) a /= b
+#else
+#define DIVIDE_BY(a,b) if (a >= b) a /= b; else a = 0
+#endif
+ if (temp < 0) {
+ temp = -temp;
+ temp += qval>>1; /* for rounding */
+ DIVIDE_BY(temp, qval);
+ temp = -temp;
+ } else {
+ temp += qval>>1; /* for rounding */
+ DIVIDE_BY(temp, qval);
+ }
+ output_ptr[i] = (JCOEF) temp;
+ }
+ }
+ }
+}
+
+
+#ifdef DCT_FLOAT_SUPPORTED
+
+METHODDEF(void)
+forward_DCT_float (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
+ JDIMENSION start_row, JDIMENSION start_col,
+ JDIMENSION num_blocks)
+/* This version is used for floating-point DCT implementations. */
+{
+ /* This routine is heavily used, so it's worth coding it tightly. */
+ my_fdct_ptr fdct = (my_fdct_ptr) cinfo->fdct;
+ float_DCT_method_ptr do_dct = fdct->do_float_dct;
+ FAST_FLOAT * divisors = fdct->float_divisors[compptr->quant_tbl_no];
+ FAST_FLOAT workspace[DCTSIZE2]; /* work area for FDCT subroutine */
+ JDIMENSION bi;
+
+ sample_data += start_row; /* fold in the vertical offset once */
+
+ for (bi = 0; bi < num_blocks; bi++, start_col += DCTSIZE) {
+ /* Load data into workspace, applying unsigned->signed conversion */
+ { register FAST_FLOAT *workspaceptr;
+ register JSAMPROW elemptr;
+ register int elemr;
+
+ workspaceptr = workspace;
+ for (elemr = 0; elemr < DCTSIZE; elemr++) {
+ elemptr = sample_data[elemr] + start_col;
+#if DCTSIZE == 8 /* unroll the inner loop */
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ *workspaceptr++ = (FAST_FLOAT)(GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+#else
+ { register int elemc;
+ for (elemc = DCTSIZE; elemc > 0; elemc--) {
+ *workspaceptr++ = (FAST_FLOAT)
+ (GETJSAMPLE(*elemptr++) - CENTERJSAMPLE);
+ }
+ }
+#endif
+ }
+ }
+
+ /* Perform the DCT */
+ (*do_dct) (workspace);
+
+ /* Quantize/descale the coefficients, and store into coef_blocks[] */
+ { register FAST_FLOAT temp;
+ register int i;
+ register JCOEFPTR output_ptr = coef_blocks[bi];
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ /* Apply the quantization and scaling factor */
+ temp = workspace[i] * divisors[i];
+ /* Round to nearest integer.
+ * Since C does not specify the direction of rounding for negative
+ * quotients, we have to force the dividend positive for portability.
+ * The maximum coefficient size is +-16K (for 12-bit data), so this
+ * code should work for either 16-bit or 32-bit ints.
+ */
+ output_ptr[i] = (JCOEF) ((int) (temp + (FAST_FLOAT) 16384.5) - 16384);
+ }
+ }
+ }
+}
+
+#endif /* DCT_FLOAT_SUPPORTED */
+
+
+/*
+ * Initialize FDCT manager.
+ */
+
+GLOBAL(void)
+jinit_forward_dct (j_compress_ptr cinfo)
+{
+ my_fdct_ptr fdct;
+ int i;
+
+ fdct = (my_fdct_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_fdct_controller));
+ cinfo->fdct = (struct jpeg_forward_dct *) fdct;
+ fdct->pub.start_pass = start_pass_fdctmgr;
+
+ switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+ case JDCT_ISLOW:
+ fdct->pub.forward_DCT = forward_DCT;
+ fdct->do_dct = jpeg_fdct_islow;
+ break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+ case JDCT_IFAST:
+ fdct->pub.forward_DCT = forward_DCT;
+ fdct->do_dct = jpeg_fdct_ifast;
+ break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ case JDCT_FLOAT:
+ fdct->pub.forward_DCT = forward_DCT_float;
+ fdct->do_float_dct = jpeg_fdct_float;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+
+ /* Mark divisor tables unallocated */
+ for (i = 0; i < NUM_TQUANT_TBLS; i++) {
+ fdct->divisors[i] = NULL;
+#ifdef DCT_FLOAT_SUPPORTED
+ fdct->float_divisors[i] = NULL;
+#endif
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jchuff.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jchuff.c
new file mode 100644
index 0000000..82e2c31
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jchuff.c
@@ -0,0 +1,909 @@
+/*
+ * jchuff.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains Huffman entropy encoding routines.
+ *
+ * Much of the complexity here has to do with supporting output suspension.
+ * If the data destination module demands suspension, we want to be able to
+ * back up to the start of the current MCU. To do this, we copy state
+ * variables into local working storage, and update them back to the
+ * permanent JPEG objects only upon successful completion of an MCU.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jchuff.h" /* Declarations shared with jcphuff.c */
+
+
+/* Expanded entropy encoder object for Huffman encoding.
+ *
+ * The savable_state subrecord tqcontains fields that change within an MCU,
+ * but must not be updated permanently until we complete the MCU.
+ */
+
+typedef struct {
+ INT32 put_buffer; /* current bit-accumulation buffer */
+ int put_bits; /* # of bits now in it */
+ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+} savable_state;
+
+/* This macro is to work around compilers with missing or broken
+ * structure assignment. You'll need to fix this code if you have
+ * such a compiler and you change MAX_COMPS_IN_SCAN.
+ */
+
+#ifndef NO_STRUCT_ASSIGN
+#define ASSIGN_STATE(dest,src) ((dest) = (src))
+#else
+#if MAX_COMPS_IN_SCAN == 4
+#define ASSIGN_STATE(dest,src) \
+ ((dest).put_buffer = (src).put_buffer, \
+ (dest).put_bits = (src).put_bits, \
+ (dest).last_dc_val[0] = (src).last_dc_val[0], \
+ (dest).last_dc_val[1] = (src).last_dc_val[1], \
+ (dest).last_dc_val[2] = (src).last_dc_val[2], \
+ (dest).last_dc_val[3] = (src).last_dc_val[3])
+#endif
+#endif
+
+
+typedef struct {
+ struct jpeg_entropy_encoder pub; /* public fields */
+
+ savable_state saved; /* Bit buffer & DC state at start of MCU */
+
+ /* These fields are NOT loaded into local working state. */
+ unsigned int restarts_to_go; /* MCUs left in this restart interval */
+ int next_restart_num; /* next restart number to write (0-7) */
+
+ /* Pointers to derived tables (these workspaces have image lifespan) */
+ c_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
+ c_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
+
+#ifdef ENTROPY_OPT_SUPPORTED /* Statistics tables for optimization */
+ long * dc_count_ptrs[NUM_HUFF_TBLS];
+ long * ac_count_ptrs[NUM_HUFF_TBLS];
+#endif
+} huff_entropy_encoder;
+
+typedef huff_entropy_encoder * huff_entropy_ptr;
+
+/* Working state while writing an MCU.
+ * This struct tqcontains all the fields that are needed by subroutines.
+ */
+
+typedef struct {
+ JOCTET * next_output_byte; /* => next byte to write in buffer */
+ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
+ savable_state cur; /* Current bit buffer & DC state */
+ j_compress_ptr cinfo; /* dump_buffer needs access to this */
+} working_state;
+
+
+/* Forward declarations */
+METHODDEF(boolean) encode_mcu_huff JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(void) finish_pass_huff JPP((j_compress_ptr cinfo));
+#ifdef ENTROPY_OPT_SUPPORTED
+METHODDEF(boolean) encode_mcu_gather JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(void) finish_pass_gather JPP((j_compress_ptr cinfo));
+#endif
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ * If gather_statistics is TRUE, we do not output anything during the scan,
+ * just count the Huffman symbols used and generate Huffman code tables.
+ */
+
+METHODDEF(void)
+start_pass_huff (j_compress_ptr cinfo, boolean gather_statistics)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int ci, dctbl, actbl;
+ jpeg_component_info * compptr;
+
+ if (gather_statistics) {
+#ifdef ENTROPY_OPT_SUPPORTED
+ entropy->pub.encode_mcu = encode_mcu_gather;
+ entropy->pub.finish_pass = finish_pass_gather;
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ entropy->pub.encode_mcu = encode_mcu_huff;
+ entropy->pub.finish_pass = finish_pass_huff;
+ }
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ dctbl = compptr->dc_tbl_no;
+ actbl = compptr->ac_tbl_no;
+ if (gather_statistics) {
+#ifdef ENTROPY_OPT_SUPPORTED
+ /* Check for invalid table indexes */
+ /* (make_c_derived_tbl does this in the other path) */
+ if (dctbl < 0 || dctbl >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, dctbl);
+ if (actbl < 0 || actbl >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, actbl);
+ /* Allocate and zero the statistics tables */
+ /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
+ if (entropy->dc_count_ptrs[dctbl] == NULL)
+ entropy->dc_count_ptrs[dctbl] = (long *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ 257 * SIZEOF(long));
+ MEMZERO(entropy->dc_count_ptrs[dctbl], 257 * SIZEOF(long));
+ if (entropy->ac_count_ptrs[actbl] == NULL)
+ entropy->ac_count_ptrs[actbl] = (long *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ 257 * SIZEOF(long));
+ MEMZERO(entropy->ac_count_ptrs[actbl], 257 * SIZEOF(long));
+#endif
+ } else {
+ /* Compute derived values for Huffman tables */
+ /* We may do this more than once for a table, but it's not expensive */
+ jpeg_make_c_derived_tbl(cinfo, TRUE, dctbl,
+ & entropy->dc_derived_tbls[dctbl]);
+ jpeg_make_c_derived_tbl(cinfo, FALSE, actbl,
+ & entropy->ac_derived_tbls[actbl]);
+ }
+ /* Initialize DC predictions to 0 */
+ entropy->saved.last_dc_val[ci] = 0;
+ }
+
+ /* Initialize bit buffer to empty */
+ entropy->saved.put_buffer = 0;
+ entropy->saved.put_bits = 0;
+
+ /* Initialize restart stuff */
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num = 0;
+}
+
+
+/*
+ * Compute the derived values for a Huffman table.
+ * This routine also performs some validation checks on the table.
+ *
+ * Note this is also used by jcphuff.c.
+ */
+
+GLOBAL(void)
+jpeg_make_c_derived_tbl (j_compress_ptr cinfo, boolean isDC, int tblno,
+ c_derived_tbl ** pdtbl)
+{
+ JHUFF_TBL *htbl;
+ c_derived_tbl *dtbl;
+ int p, i, l, lastp, si, maxsymbol;
+ char huffsize[257];
+ unsigned int huffcode[257];
+ unsigned int code;
+
+ /* Note that huffsize[] and huffcode[] are filled in code-length order,
+ * paralleling the order of the symbols themselves in htbl->huffval[].
+ */
+
+ /* Find the input Huffman table */
+ if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+ htbl =
+ isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
+ if (htbl == NULL)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+
+ /* Allocate a workspace if we haven't already done so. */
+ if (*pdtbl == NULL)
+ *pdtbl = (c_derived_tbl *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(c_derived_tbl));
+ dtbl = *pdtbl;
+
+ /* Figure C.1: make table of Huffman code length for each symbol */
+
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ i = (int) htbl->bits[l];
+ if (i < 0 || p + i > 256) /* protect against table overrun */
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ while (i--)
+ huffsize[p++] = (char) l;
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ /* Figure C.2: generate the codes themselves */
+ /* We also validate that the counts represent a legal Huffman code tree. */
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p]) {
+ while (((int) huffsize[p]) == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ /* code is now 1 more than the last code used for codelength si; but
+ * it must still fit in si bits, since no code is allowed to be all ones.
+ */
+ if (((INT32) code) >= (((INT32) 1) << si))
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ code <<= 1;
+ si++;
+ }
+
+ /* Figure C.3: generate encoding tables */
+ /* These are code and size indexed by symbol value */
+
+ /* Set all codeless symbols to have code length 0;
+ * this lets us detect duplicate VAL entries here, and later
+ * allows emit_bits to detect any attempt to emit such symbols.
+ */
+ MEMZERO(dtbl->ehufsi, SIZEOF(dtbl->ehufsi));
+
+ /* This is also a convenient place to check for out-of-range
+ * and duplicated VAL entries. We allow 0..255 for AC symbols
+ * but only 0..15 for DC. (We could constrain them further
+ * based on data depth and mode, but this seems enough.)
+ */
+ maxsymbol = isDC ? 15 : 255;
+
+ for (p = 0; p < lastp; p++) {
+ i = htbl->huffval[p];
+ if (i < 0 || i > maxsymbol || dtbl->ehufsi[i])
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ dtbl->ehufco[i] = huffcode[p];
+ dtbl->ehufsi[i] = huffsize[p];
+ }
+}
+
+
+/* Outputting bytes to the file */
+
+/* Emit a byte, taking 'action' if must suspend. */
+#define emit_byte(state,val,action) \
+ { *(state)->next_output_byte++ = (JOCTET) (val); \
+ if (--(state)->free_in_buffer == 0) \
+ if (! dump_buffer(state)) \
+ { action; } }
+
+
+LOCAL(boolean)
+dump_buffer (working_state * state)
+/* Empty the output buffer; return TRUE if successful, FALSE if must suspend */
+{
+ struct jpeg_destination_mgr * dest = state->cinfo->dest;
+
+ if (! (*dest->empty_output_buffer) (state->cinfo))
+ return FALSE;
+ /* After a successful buffer dump, must reset buffer pointers */
+ state->next_output_byte = dest->next_output_byte;
+ state->free_in_buffer = dest->free_in_buffer;
+ return TRUE;
+}
+
+
+/* Outputting bits to the file */
+
+/* Only the right 24 bits of put_buffer are used; the valid bits are
+ * left-justified in this part. At most 16 bits can be passed to emit_bits
+ * in one call, and we never retain more than 7 bits in put_buffer
+ * between calls, so 24 bits are sufficient.
+ */
+
+INLINE
+LOCAL(boolean)
+emit_bits (working_state * state, unsigned int code, int size)
+/* Emit some bits; return TRUE if successful, FALSE if must suspend */
+{
+ /* This routine is heavily used, so it's worth coding tightly. */
+ register INT32 put_buffer = (INT32) code;
+ register int put_bits = state->cur.put_bits;
+
+ /* if size is 0, caller used an invalid Huffman table entry */
+ if (size == 0)
+ ERREXIT(state->cinfo, JERR_HUFF_MISSING_CODE);
+
+ put_buffer &= (((INT32) 1)<<size) - 1; /* tqmask off any extra bits in code */
+
+ put_bits += size; /* new number of bits in buffer */
+
+ put_buffer <<= 24 - put_bits; /* align incoming bits */
+
+ put_buffer |= state->cur.put_buffer; /* and merge with old buffer contents */
+
+ while (put_bits >= 8) {
+ int c = (int) ((put_buffer >> 16) & 0xFF);
+
+ emit_byte(state, c, return FALSE);
+ if (c == 0xFF) { /* need to stuff a zero byte? */
+ emit_byte(state, 0, return FALSE);
+ }
+ put_buffer <<= 8;
+ put_bits -= 8;
+ }
+
+ state->cur.put_buffer = put_buffer; /* update state variables */
+ state->cur.put_bits = put_bits;
+
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+flush_bits (working_state * state)
+{
+ if (! emit_bits(state, 0x7F, 7)) /* fill any partial byte with ones */
+ return FALSE;
+ state->cur.put_buffer = 0; /* and reset bit-buffer to empty */
+ state->cur.put_bits = 0;
+ return TRUE;
+}
+
+
+/* Encode a single block's worth of coefficients */
+
+LOCAL(boolean)
+encode_one_block (working_state * state, JCOEFPTR block, int last_dc_val,
+ c_derived_tbl *dctbl, c_derived_tbl *actbl)
+{
+ register int temp, temp2;
+ register int nbits;
+ register int k, r, i;
+
+ /* Encode the DC coefficient difference per section F.1.2.1 */
+
+ temp = temp2 = block[0] - last_dc_val;
+
+ if (temp < 0) {
+ temp = -temp; /* temp is abs value of input */
+ /* For a negative input, want temp2 = bitwise complement of abs(input) */
+ /* This code assumes we are on a two's complement machine */
+ temp2--;
+ }
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = 0;
+ while (temp) {
+ nbits++;
+ temp >>= 1;
+ }
+ /* Check for out-of-range coefficient values.
+ * Since we're encoding a difference, the range limit is twice as much.
+ */
+ if (nbits > MAX_COEF_BITS+1)
+ ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
+
+ /* Emit the Huffman-coded symbol for the number of bits */
+ if (! emit_bits(state, dctbl->ehufco[nbits], dctbl->ehufsi[nbits]))
+ return FALSE;
+
+ /* Emit that number of bits of the value, if positive, */
+ /* or the complement of its magnitude, if negative. */
+ if (nbits) /* emit_bits rejects calls with size 0 */
+ if (! emit_bits(state, (unsigned int) temp2, nbits))
+ return FALSE;
+
+ /* Encode the AC coefficients per section F.1.2.2 */
+
+ r = 0; /* r = run length of zeros */
+
+ for (k = 1; k < DCTSIZE2; k++) {
+ if ((temp = block[jpeg_natural_order[k]]) == 0) {
+ r++;
+ } else {
+ /* if run length > 15, must emit special run-length-16 codes (0xF0) */
+ while (r > 15) {
+ if (! emit_bits(state, actbl->ehufco[0xF0], actbl->ehufsi[0xF0]))
+ return FALSE;
+ r -= 16;
+ }
+
+ temp2 = temp;
+ if (temp < 0) {
+ temp = -temp; /* temp is abs value of input */
+ /* This code assumes we are on a two's complement machine */
+ temp2--;
+ }
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = 1; /* there must be at least one 1 bit */
+ while ((temp >>= 1))
+ nbits++;
+ /* Check for out-of-range coefficient values */
+ if (nbits > MAX_COEF_BITS)
+ ERREXIT(state->cinfo, JERR_BAD_DCT_COEF);
+
+ /* Emit Huffman symbol for run length / number of bits */
+ i = (r << 4) + nbits;
+ if (! emit_bits(state, actbl->ehufco[i], actbl->ehufsi[i]))
+ return FALSE;
+
+ /* Emit that number of bits of the value, if positive, */
+ /* or the complement of its magnitude, if negative. */
+ if (! emit_bits(state, (unsigned int) temp2, nbits))
+ return FALSE;
+
+ r = 0;
+ }
+ }
+
+ /* If the last coef(s) were zero, emit an end-of-block code */
+ if (r > 0)
+ if (! emit_bits(state, actbl->ehufco[0], actbl->ehufsi[0]))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Emit a restart marker & resynchronize predictions.
+ */
+
+LOCAL(boolean)
+emit_restart (working_state * state, int restart_num)
+{
+ int ci;
+
+ if (! flush_bits(state))
+ return FALSE;
+
+ emit_byte(state, 0xFF, return FALSE);
+ emit_byte(state, JPEG_RST0 + restart_num, return FALSE);
+
+ /* Re-initialize DC predictions to 0 */
+ for (ci = 0; ci < state->cinfo->comps_in_scan; ci++)
+ state->cur.last_dc_val[ci] = 0;
+
+ /* The restart counter is not updated until we successfully write the MCU. */
+
+ return TRUE;
+}
+
+
+/*
+ * Encode and output one MCU's worth of Huffman-compressed coefficients.
+ */
+
+METHODDEF(boolean)
+encode_mcu_huff (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ working_state state;
+ int blkn, ci;
+ jpeg_component_info * compptr;
+
+ /* Load up working state */
+ state.next_output_byte = cinfo->dest->next_output_byte;
+ state.free_in_buffer = cinfo->dest->free_in_buffer;
+ ASSIGN_STATE(state.cur, entropy->saved);
+ state.cinfo = cinfo;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! emit_restart(&state, entropy->next_restart_num))
+ return FALSE;
+ }
+
+ /* Encode the MCU data blocks */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+ if (! encode_one_block(&state,
+ MCU_data[blkn][0], state.cur.last_dc_val[ci],
+ entropy->dc_derived_tbls[compptr->dc_tbl_no],
+ entropy->ac_derived_tbls[compptr->ac_tbl_no]))
+ return FALSE;
+ /* Update last_dc_val */
+ state.cur.last_dc_val[ci] = MCU_data[blkn][0][0];
+ }
+
+ /* Completed MCU, so update state */
+ cinfo->dest->next_output_byte = state.next_output_byte;
+ cinfo->dest->free_in_buffer = state.free_in_buffer;
+ ASSIGN_STATE(entropy->saved, state.cur);
+
+ /* Update restart-interval state too */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Finish up at the end of a Huffman-compressed scan.
+ */
+
+METHODDEF(void)
+finish_pass_huff (j_compress_ptr cinfo)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ working_state state;
+
+ /* Load up working state ... flush_bits needs it */
+ state.next_output_byte = cinfo->dest->next_output_byte;
+ state.free_in_buffer = cinfo->dest->free_in_buffer;
+ ASSIGN_STATE(state.cur, entropy->saved);
+ state.cinfo = cinfo;
+
+ /* Flush out the last data */
+ if (! flush_bits(&state))
+ ERREXIT(cinfo, JERR_CANT_SUSPEND);
+
+ /* Update state */
+ cinfo->dest->next_output_byte = state.next_output_byte;
+ cinfo->dest->free_in_buffer = state.free_in_buffer;
+ ASSIGN_STATE(entropy->saved, state.cur);
+}
+
+
+/*
+ * Huffman coding optimization.
+ *
+ * We first scan the supplied data and count the number of uses of each symbol
+ * that is to be Huffman-coded. (This process MUST agree with the code above.)
+ * Then we build a Huffman coding tree for the observed counts.
+ * Symbols which are not needed at all for the particular image are not
+ * assigned any code, which saves space in the DHT marker as well as in
+ * the compressed data.
+ */
+
+#ifdef ENTROPY_OPT_SUPPORTED
+
+
+/* Process a single block's worth of coefficients */
+
+LOCAL(void)
+htest_one_block (j_compress_ptr cinfo, JCOEFPTR block, int last_dc_val,
+ long dc_counts[], long ac_counts[])
+{
+ register int temp;
+ register int nbits;
+ register int k, r;
+
+ /* Encode the DC coefficient difference per section F.1.2.1 */
+
+ temp = block[0] - last_dc_val;
+ if (temp < 0)
+ temp = -temp;
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = 0;
+ while (temp) {
+ nbits++;
+ temp >>= 1;
+ }
+ /* Check for out-of-range coefficient values.
+ * Since we're encoding a difference, the range limit is twice as much.
+ */
+ if (nbits > MAX_COEF_BITS+1)
+ ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+
+ /* Count the Huffman symbol for the number of bits */
+ dc_counts[nbits]++;
+
+ /* Encode the AC coefficients per section F.1.2.2 */
+
+ r = 0; /* r = run length of zeros */
+
+ for (k = 1; k < DCTSIZE2; k++) {
+ if ((temp = block[jpeg_natural_order[k]]) == 0) {
+ r++;
+ } else {
+ /* if run length > 15, must emit special run-length-16 codes (0xF0) */
+ while (r > 15) {
+ ac_counts[0xF0]++;
+ r -= 16;
+ }
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ if (temp < 0)
+ temp = -temp;
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = 1; /* there must be at least one 1 bit */
+ while ((temp >>= 1))
+ nbits++;
+ /* Check for out-of-range coefficient values */
+ if (nbits > MAX_COEF_BITS)
+ ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+
+ /* Count Huffman symbol for run length / number of bits */
+ ac_counts[(r << 4) + nbits]++;
+
+ r = 0;
+ }
+ }
+
+ /* If the last coef(s) were zero, emit an end-of-block code */
+ if (r > 0)
+ ac_counts[0]++;
+}
+
+
+/*
+ * Trial-encode one MCU's worth of Huffman-compressed coefficients.
+ * No data is actually output, so no suspension return is possible.
+ */
+
+METHODDEF(boolean)
+encode_mcu_gather (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int blkn, ci;
+ jpeg_component_info * compptr;
+
+ /* Take care of restart intervals if needed */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ /* Re-initialize DC predictions to 0 */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+ entropy->saved.last_dc_val[ci] = 0;
+ /* Update restart state */
+ entropy->restarts_to_go = cinfo->restart_interval;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+ htest_one_block(cinfo, MCU_data[blkn][0], entropy->saved.last_dc_val[ci],
+ entropy->dc_count_ptrs[compptr->dc_tbl_no],
+ entropy->ac_count_ptrs[compptr->ac_tbl_no]);
+ entropy->saved.last_dc_val[ci] = MCU_data[blkn][0][0];
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Generate the best Huffman code table for the given counts, fill htbl.
+ * Note this is also used by jcphuff.c.
+ *
+ * The JPEG standard requires that no symbol be assigned a codeword of all
+ * one bits (so that padding bits added at the end of a compressed segment
+ * can't look like a valid code). Because of the canonical ordering of
+ * codewords, this just means that there must be an unused slot in the
+ * longest codeword length category. Section K.2 of the JPEG spec suggests
+ * reserving such a slot by pretending that symbol 256 is a valid symbol
+ * with count 1. In theory that's not optimal; giving it count zero but
+ * including it in the symbol set anyway should give a better Huffman code.
+ * But the theoretically better code actually seems to come out worse in
+ * practice, because it produces more all-ones bytes (which incur stuffed
+ * zero bytes in the final file). In any case the difference is tiny.
+ *
+ * The JPEG standard requires Huffman codes to be no more than 16 bits long.
+ * If some symbols have a very small but nonzero probability, the Huffman tree
+ * must be adjusted to meet the code length restriction. We currently use
+ * the adjustment method suggested in JPEG section K.2. This method is *not*
+ * optimal; it may not choose the best possible limited-length code. But
+ * typically only very-low-frequency symbols will be given less-than-optimal
+ * lengths, so the code is almost optimal. Experimental comparisons against
+ * an optimal limited-length-code algorithm indicate that the difference is
+ * microscopic --- usually less than a hundredth of a percent of total size.
+ * So the extra complexity of an optimal algorithm doesn't seem worthwhile.
+ */
+
+GLOBAL(void)
+jpeg_gen_optimal_table (j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[])
+{
+#define MAX_CLEN 32 /* assumed maximum initial code length */
+ UINT8 bits[MAX_CLEN+1]; /* bits[k] = # of symbols with code length k */
+ int codesize[257]; /* codesize[k] = code length of symbol k */
+ int others[257]; /* next symbol in current branch of tree */
+ int c1, c2;
+ int p, i, j;
+ long v;
+
+ /* This algorithm is explained in section K.2 of the JPEG standard */
+
+ MEMZERO(bits, SIZEOF(bits));
+ MEMZERO(codesize, SIZEOF(codesize));
+ for (i = 0; i < 257; i++)
+ others[i] = -1; /* init links to empty */
+
+ freq[256] = 1; /* make sure 256 has a nonzero count */
+ /* Including the pseudo-symbol 256 in the Huffman procedure guarantees
+ * that no real symbol is given code-value of all ones, because 256
+ * will be placed last in the largest codeword category.
+ */
+
+ /* Huffman's basic algorithm to assign optimal code lengths to symbols */
+
+ for (;;) {
+ /* Find the smallest nonzero frequency, set c1 = its symbol */
+ /* In case of ties, take the larger symbol number */
+ c1 = -1;
+ v = 1000000000L;
+ for (i = 0; i <= 256; i++) {
+ if (freq[i] && freq[i] <= v) {
+ v = freq[i];
+ c1 = i;
+ }
+ }
+
+ /* Find the next smallest nonzero frequency, set c2 = its symbol */
+ /* In case of ties, take the larger symbol number */
+ c2 = -1;
+ v = 1000000000L;
+ for (i = 0; i <= 256; i++) {
+ if (freq[i] && freq[i] <= v && i != c1) {
+ v = freq[i];
+ c2 = i;
+ }
+ }
+
+ /* Done if we've merged everything into one frequency */
+ if (c2 < 0)
+ break;
+
+ /* Else merge the two counts/trees */
+ freq[c1] += freq[c2];
+ freq[c2] = 0;
+
+ /* Increment the codesize of everything in c1's tree branch */
+ codesize[c1]++;
+ while (others[c1] >= 0) {
+ c1 = others[c1];
+ codesize[c1]++;
+ }
+
+ others[c1] = c2; /* chain c2 onto c1's tree branch */
+
+ /* Increment the codesize of everything in c2's tree branch */
+ codesize[c2]++;
+ while (others[c2] >= 0) {
+ c2 = others[c2];
+ codesize[c2]++;
+ }
+ }
+
+ /* Now count the number of symbols of each code length */
+ for (i = 0; i <= 256; i++) {
+ if (codesize[i]) {
+ /* The JPEG standard seems to think that this can't happen, */
+ /* but I'm paranoid... */
+ if (codesize[i] > MAX_CLEN)
+ ERREXIT(cinfo, JERR_HUFF_CLEN_OVERFLOW);
+
+ bits[codesize[i]]++;
+ }
+ }
+
+ /* JPEG doesn't allow symbols with code lengths over 16 bits, so if the pure
+ * Huffman procedure assigned any such lengths, we must adjust the coding.
+ * Here is what the JPEG spec says about how this next bit works:
+ * Since symbols are paired for the longest Huffman code, the symbols are
+ * removed from this length category two at a time. The prefix for the pair
+ * (which is one bit shorter) is allocated to one of the pair; then,
+ * skipping the BITS entry for that prefix length, a code word from the next
+ * shortest nonzero BITS entry is converted into a prefix for two code words
+ * one bit longer.
+ */
+
+ for (i = MAX_CLEN; i > 16; i--) {
+ while (bits[i] > 0) {
+ j = i - 2; /* tqfind length of new prefix to be used */
+ while (bits[j] == 0)
+ j--;
+
+ bits[i] -= 2; /* remove two symbols */
+ bits[i-1]++; /* one goes in this length */
+ bits[j+1] += 2; /* two new symbols in this length */
+ bits[j]--; /* symbol of this length is now a prefix */
+ }
+ }
+
+ /* Remove the count for the pseudo-symbol 256 from the largest codelength */
+ while (bits[i] == 0) /* tqfind largest codelength still in use */
+ i--;
+ bits[i]--;
+
+ /* Return final symbol counts (only for lengths 0..16) */
+ MEMCOPY(htbl->bits, bits, SIZEOF(htbl->bits));
+
+ /* Return a list of the symbols sorted by code length */
+ /* It's not real clear to me why we don't need to consider the codelength
+ * changes made above, but the JPEG spec seems to think this works.
+ */
+ p = 0;
+ for (i = 1; i <= MAX_CLEN; i++) {
+ for (j = 0; j <= 255; j++) {
+ if (codesize[j] == i) {
+ htbl->huffval[p] = (UINT8) j;
+ p++;
+ }
+ }
+ }
+
+ /* Set sent_table FALSE so updated table will be written to JPEG file. */
+ htbl->sent_table = FALSE;
+}
+
+
+/*
+ * Finish up a statistics-gathering pass and create the new Huffman tables.
+ */
+
+METHODDEF(void)
+finish_pass_gather (j_compress_ptr cinfo)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int ci, dctbl, actbl;
+ jpeg_component_info * compptr;
+ JHUFF_TBL **htblptr;
+ boolean did_dc[NUM_HUFF_TBLS];
+ boolean did_ac[NUM_HUFF_TBLS];
+
+ /* It's important not to apply jpeg_gen_optimal_table more than once
+ * per table, because it clobbers the input frequency counts!
+ */
+ MEMZERO(did_dc, SIZEOF(did_dc));
+ MEMZERO(did_ac, SIZEOF(did_ac));
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ dctbl = compptr->dc_tbl_no;
+ actbl = compptr->ac_tbl_no;
+ if (! did_dc[dctbl]) {
+ htblptr = & cinfo->dc_huff_tbl_ptrs[dctbl];
+ if (*htblptr == NULL)
+ *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+ jpeg_gen_optimal_table(cinfo, *htblptr, entropy->dc_count_ptrs[dctbl]);
+ did_dc[dctbl] = TRUE;
+ }
+ if (! did_ac[actbl]) {
+ htblptr = & cinfo->ac_huff_tbl_ptrs[actbl];
+ if (*htblptr == NULL)
+ *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+ jpeg_gen_optimal_table(cinfo, *htblptr, entropy->ac_count_ptrs[actbl]);
+ did_ac[actbl] = TRUE;
+ }
+ }
+}
+
+
+#endif /* ENTROPY_OPT_SUPPORTED */
+
+
+/*
+ * Module initialization routine for Huffman entropy encoding.
+ */
+
+GLOBAL(void)
+jinit_huff_encoder (j_compress_ptr cinfo)
+{
+ huff_entropy_ptr entropy;
+ int i;
+
+ entropy = (huff_entropy_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(huff_entropy_encoder));
+ cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
+ entropy->pub.start_pass = start_pass_huff;
+
+ /* Mark tables unallocated */
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
+#ifdef ENTROPY_OPT_SUPPORTED
+ entropy->dc_count_ptrs[i] = entropy->ac_count_ptrs[i] = NULL;
+#endif
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jchuff.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jchuff.h
new file mode 100644
index 0000000..fea9064
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jchuff.h
@@ -0,0 +1,47 @@
+/*
+ * jchuff.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains declarations for Huffman entropy encoding routines
+ * that are shared between the sequential encoder (jchuff.c) and the
+ * progressive encoder (jcphuff.c). No other modules need to see these.
+ */
+
+/* The legal range of a DCT coefficient is
+ * -1024 .. +1023 for 8-bit data;
+ * -16384 .. +16383 for 12-bit data.
+ * Hence the magnitude should always fit in 10 or 14 bits respectively.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MAX_COEF_BITS 10
+#else
+#define MAX_COEF_BITS 14
+#endif
+
+/* Derived data constructed for each Huffman table */
+
+typedef struct {
+ unsigned int ehufco[256]; /* code for each symbol */
+ char ehufsi[256]; /* length of code for each symbol */
+ /* If no code has been allocated for a symbol S, ehufsi[S] tqcontains 0 */
+} c_derived_tbl;
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_make_c_derived_tbl jMkCDerived
+#define jpeg_gen_optimal_table jGenOptTbl
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+/* Expand a Huffman table definition into the derived format */
+EXTERN(void) jpeg_make_c_derived_tbl
+ JPP((j_compress_ptr cinfo, boolean isDC, int tblno,
+ c_derived_tbl ** pdtbl));
+
+/* Generate an optimal table definition given the specified counts */
+EXTERN(void) jpeg_gen_optimal_table
+ JPP((j_compress_ptr cinfo, JHUFF_TBL * htbl, long freq[]));
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcinit.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcinit.c
new file mode 100644
index 0000000..01985a4
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcinit.c
@@ -0,0 +1,72 @@
+/*
+ * jcinit.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains initialization logic for the JPEG compressor.
+ * This routine is in charge of selecting the modules to be executed and
+ * making an initialization call to each one.
+ *
+ * Logically, this code belongs in jcmaster.c. It's split out because
+ * linking this routine implies linking the entire compression library.
+ * For a transcoding-only application, we want to be able to use jcmaster.c
+ * without linking in the whole library.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Master selection of compression modules.
+ * This is done once at the start of processing an image. We determine
+ * which modules will be used and give them appropriate initialization calls.
+ */
+
+GLOBAL(void)
+jinit_compress_master (j_compress_ptr cinfo)
+{
+ /* Initialize master control (includes parameter checking/processing) */
+ jinit_c_master_control(cinfo, FALSE /* full compression */);
+
+ /* Preprocessing */
+ if (! cinfo->raw_data_in) {
+ jinit_color_converter(cinfo);
+ jinit_downsampler(cinfo);
+ jinit_c_prep_controller(cinfo, FALSE /* never need full buffer here */);
+ }
+ /* Forward DCT */
+ jinit_forward_dct(cinfo);
+ /* Entropy encoding: either Huffman or arithmetic coding. */
+ if (cinfo->arith_code) {
+ ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+ } else {
+ if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+ jinit_phuff_encoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else
+ jinit_huff_encoder(cinfo);
+ }
+
+ /* Need a full-image coefficient buffer in any multi-pass mode. */
+ jinit_c_coef_controller(cinfo,
+ (boolean) (cinfo->num_scans > 1 || cinfo->optimize_coding));
+ jinit_c_main_controller(cinfo, FALSE /* never need full buffer here */);
+
+ jinit_marker_writer(cinfo);
+
+ /* We can now tell the memory manager to allocate virtual arrays. */
+ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+ /* Write the datastream header (SOI) immediately.
+ * Frame and scan headers are postponed till later.
+ * This lets application insert special markers after the SOI.
+ */
+ (*cinfo->marker->write_file_header) (cinfo);
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcmainct.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcmainct.c
new file mode 100644
index 0000000..3fa3c7f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcmainct.c
@@ -0,0 +1,293 @@
+/*
+ * jcmainct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains the main buffer controller for compression.
+ * The main buffer lies between the pre-processor and the JPEG
+ * compressor proper; it holds downsampled data in the JPEG colorspace.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Note: currently, there is no operating mode in which a full-image buffer
+ * is needed at this step. If there were, that mode could not be used with
+ * "raw data" input, since this module is bypassed in that case. However,
+ * we've left the code here for possible use in special applications.
+ */
+#undef FULL_MAIN_BUFFER_SUPPORTED
+
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_c_main_controller pub; /* public fields */
+
+ JDIMENSION cur_iMCU_row; /* number of current iMCU row */
+ JDIMENSION rowgroup_ctr; /* counts row groups received in iMCU row */
+ boolean suspended; /* remember if we suspended output */
+ J_BUF_MODE pass_mode; /* current operating mode */
+
+ /* If using just a strip buffer, this points to the entire set of buffers
+ * (we allocate one for each component). In the full-image case, this
+ * points to the currently accessible strips of the virtual arrays.
+ */
+ JSAMPARRAY buffer[MAX_COMPONENTS];
+
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+ /* If using full-image storage, this array holds pointers to virtual-array
+ * control blocks for each component. Unused if not full-image storage.
+ */
+ jvirt_sarray_ptr whole_image[MAX_COMPONENTS];
+#endif
+} my_main_controller;
+
+typedef my_main_controller * my_main_ptr;
+
+
+/* Forward declarations */
+METHODDEF(void) process_data_simple_main
+ JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
+ JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+METHODDEF(void) process_data_buffer_main
+ JPP((j_compress_ptr cinfo, JSAMPARRAY input_buf,
+ JDIMENSION *in_row_ctr, JDIMENSION in_rows_avail));
+#endif
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_main (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+
+ /* Do nothing in raw-data mode. */
+ if (cinfo->raw_data_in)
+ return;
+
+ main->cur_iMCU_row = 0; /* initialize counters */
+ main->rowgroup_ctr = 0;
+ main->suspended = FALSE;
+ main->pass_mode = pass_mode; /* save mode for use by process_data */
+
+ switch (pass_mode) {
+ case JBUF_PASS_THRU:
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+ if (main->whole_image[0] != NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif
+ main->pub.process_data = process_data_simple_main;
+ break;
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+ case JBUF_SAVE_SOURCE:
+ case JBUF_CRANK_DEST:
+ case JBUF_SAVE_AND_PASS:
+ if (main->whole_image[0] == NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ main->pub.process_data = process_data_buffer_main;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ break;
+ }
+}
+
+
+/*
+ * Process some data.
+ * This routine handles the simple pass-through mode,
+ * where we have only a strip buffer.
+ */
+
+METHODDEF(void)
+process_data_simple_main (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail)
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+
+ while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
+ /* Read input data if we haven't filled the main buffer yet */
+ if (main->rowgroup_ctr < DCTSIZE)
+ (*cinfo->prep->pre_process_data) (cinfo,
+ input_buf, in_row_ctr, in_rows_avail,
+ main->buffer, &main->rowgroup_ctr,
+ (JDIMENSION) DCTSIZE);
+
+ /* If we don't have a full iMCU row buffered, return to application for
+ * more data. Note that preprocessor will always pad to fill the iMCU row
+ * at the bottom of the image.
+ */
+ if (main->rowgroup_ctr != DCTSIZE)
+ return;
+
+ /* Send the completed row to the compressor */
+ if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
+ /* If compressor did not consume the whole row, then we must need to
+ * suspend processing and return to the application. In this situation
+ * we pretend we didn't yet consume the last input row; otherwise, if
+ * it happened to be the last row of the image, the application would
+ * think we were done.
+ */
+ if (! main->suspended) {
+ (*in_row_ctr)--;
+ main->suspended = TRUE;
+ }
+ return;
+ }
+ /* We did finish the row. Undo our little suspension hack if a previous
+ * call suspended; then mark the main buffer empty.
+ */
+ if (main->suspended) {
+ (*in_row_ctr)++;
+ main->suspended = FALSE;
+ }
+ main->rowgroup_ctr = 0;
+ main->cur_iMCU_row++;
+ }
+}
+
+
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+
+/*
+ * Process some data.
+ * This routine handles all of the modes that use a full-size buffer.
+ */
+
+METHODDEF(void)
+process_data_buffer_main (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail)
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+ int ci;
+ jpeg_component_info *compptr;
+ boolean writing = (main->pass_mode != JBUF_CRANK_DEST);
+
+ while (main->cur_iMCU_row < cinfo->total_iMCU_rows) {
+ /* Realign the virtual buffers if at the start of an iMCU row. */
+ if (main->rowgroup_ctr == 0) {
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ main->buffer[ci] = (*cinfo->mem->access_virt_sarray)
+ ((j_common_ptr) cinfo, main->whole_image[ci],
+ main->cur_iMCU_row * (compptr->v_samp_factor * DCTSIZE),
+ (JDIMENSION) (compptr->v_samp_factor * DCTSIZE), writing);
+ }
+ /* In a read pass, pretend we just read some source data. */
+ if (! writing) {
+ *in_row_ctr += cinfo->max_v_samp_factor * DCTSIZE;
+ main->rowgroup_ctr = DCTSIZE;
+ }
+ }
+
+ /* If a write pass, read input data until the current iMCU row is full. */
+ /* Note: preprocessor will pad if necessary to fill the last iMCU row. */
+ if (writing) {
+ (*cinfo->prep->pre_process_data) (cinfo,
+ input_buf, in_row_ctr, in_rows_avail,
+ main->buffer, &main->rowgroup_ctr,
+ (JDIMENSION) DCTSIZE);
+ /* Return to application if we need more data to fill the iMCU row. */
+ if (main->rowgroup_ctr < DCTSIZE)
+ return;
+ }
+
+ /* Emit data, unless this is a sink-only pass. */
+ if (main->pass_mode != JBUF_SAVE_SOURCE) {
+ if (! (*cinfo->coef->compress_data) (cinfo, main->buffer)) {
+ /* If compressor did not consume the whole row, then we must need to
+ * suspend processing and return to the application. In this situation
+ * we pretend we didn't yet consume the last input row; otherwise, if
+ * it happened to be the last row of the image, the application would
+ * think we were done.
+ */
+ if (! main->suspended) {
+ (*in_row_ctr)--;
+ main->suspended = TRUE;
+ }
+ return;
+ }
+ /* We did finish the row. Undo our little suspension hack if a previous
+ * call suspended; then mark the main buffer empty.
+ */
+ if (main->suspended) {
+ (*in_row_ctr)++;
+ main->suspended = FALSE;
+ }
+ }
+
+ /* If get here, we are done with this iMCU row. Mark buffer empty. */
+ main->rowgroup_ctr = 0;
+ main->cur_iMCU_row++;
+ }
+}
+
+#endif /* FULL_MAIN_BUFFER_SUPPORTED */
+
+
+/*
+ * Initialize main buffer controller.
+ */
+
+GLOBAL(void)
+jinit_c_main_controller (j_compress_ptr cinfo, boolean need_full_buffer)
+{
+ my_main_ptr main;
+ int ci;
+ jpeg_component_info *compptr;
+
+ main = (my_main_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_main_controller));
+ cinfo->main = (struct jpeg_c_main_controller *) main;
+ main->pub.start_pass = start_pass_main;
+
+ /* We don't need to create a buffer in raw-data mode. */
+ if (cinfo->raw_data_in)
+ return;
+
+ /* Create the buffer. It holds downsampled data, so each component
+ * may be of a different size.
+ */
+ if (need_full_buffer) {
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+ /* Allocate a full-image virtual array for each component */
+ /* Note we pad the bottom to a multiple of the iMCU height */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ main->whole_image[ci] = (*cinfo->mem->request_virt_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
+ compptr->width_in_blocks * DCTSIZE,
+ (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+ (long) compptr->v_samp_factor) * DCTSIZE,
+ (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
+ }
+#else
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif
+ } else {
+#ifdef FULL_MAIN_BUFFER_SUPPORTED
+ main->whole_image[0] = NULL; /* flag for no virtual arrays */
+#endif
+ /* Allocate a strip buffer for each component */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ main->buffer[ci] = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ compptr->width_in_blocks * DCTSIZE,
+ (JDIMENSION) (compptr->v_samp_factor * DCTSIZE));
+ }
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcmarker.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcmarker.c
new file mode 100644
index 0000000..9a49c6c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcmarker.c
@@ -0,0 +1,664 @@
+/*
+ * jcmarker.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains routines to write JPEG datastream markers.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+typedef enum { /* JPEG marker codes */
+ M_SOF0 = 0xc0,
+ M_SOF1 = 0xc1,
+ M_SOF2 = 0xc2,
+ M_SOF3 = 0xc3,
+
+ M_SOF5 = 0xc5,
+ M_SOF6 = 0xc6,
+ M_SOF7 = 0xc7,
+
+ M_JPG = 0xc8,
+ M_SOF9 = 0xc9,
+ M_SOF10 = 0xca,
+ M_SOF11 = 0xcb,
+
+ M_SOF13 = 0xcd,
+ M_SOF14 = 0xce,
+ M_SOF15 = 0xcf,
+
+ M_DHT = 0xc4,
+
+ M_DAC = 0xcc,
+
+ M_RST0 = 0xd0,
+ M_RST1 = 0xd1,
+ M_RST2 = 0xd2,
+ M_RST3 = 0xd3,
+ M_RST4 = 0xd4,
+ M_RST5 = 0xd5,
+ M_RST6 = 0xd6,
+ M_RST7 = 0xd7,
+
+ M_SOI = 0xd8,
+ M_EOI = 0xd9,
+ M_SOS = 0xda,
+ M_DQT = 0xdb,
+ M_DNL = 0xdc,
+ M_DRI = 0xdd,
+ M_DHP = 0xde,
+ M_EXP = 0xdf,
+
+ M_APP0 = 0xe0,
+ M_APP1 = 0xe1,
+ M_APP2 = 0xe2,
+ M_APP3 = 0xe3,
+ M_APP4 = 0xe4,
+ M_APP5 = 0xe5,
+ M_APP6 = 0xe6,
+ M_APP7 = 0xe7,
+ M_APP8 = 0xe8,
+ M_APP9 = 0xe9,
+ M_APP10 = 0xea,
+ M_APP11 = 0xeb,
+ M_APP12 = 0xec,
+ M_APP13 = 0xed,
+ M_APP14 = 0xee,
+ M_APP15 = 0xef,
+
+ M_JPG0 = 0xf0,
+ M_JPG13 = 0xfd,
+ M_COM = 0xfe,
+
+ M_TEM = 0x01,
+
+ M_ERROR = 0x100
+} JPEG_MARKER;
+
+
+/* Private state */
+
+typedef struct {
+ struct jpeg_marker_writer pub; /* public fields */
+
+ unsigned int last_restart_interval; /* last DRI value emitted; 0 after SOI */
+} my_marker_writer;
+
+typedef my_marker_writer * my_marker_ptr;
+
+
+/*
+ * Basic output routines.
+ *
+ * Note that we do not support suspension while writing a marker.
+ * Therefore, an application using suspension must ensure that there is
+ * enough buffer space for the initial markers (typ. 600-700 bytes) before
+ * calling jpeg_start_compress, and enough space to write the trailing EOI
+ * (a few bytes) before calling jpeg_finish_compress. Multipass compression
+ * modes are not supported at all with suspension, so those two are the only
+ * points where markers will be written.
+ */
+
+LOCAL(void)
+emit_byte (j_compress_ptr cinfo, int val)
+/* Emit a byte */
+{
+ struct jpeg_destination_mgr * dest = cinfo->dest;
+
+ *(dest->next_output_byte)++ = (JOCTET) val;
+ if (--dest->free_in_buffer == 0) {
+ if (! (*dest->empty_output_buffer) (cinfo))
+ ERREXIT(cinfo, JERR_CANT_SUSPEND);
+ }
+}
+
+
+LOCAL(void)
+emit_marker (j_compress_ptr cinfo, JPEG_MARKER mark)
+/* Emit a marker code */
+{
+ emit_byte(cinfo, 0xFF);
+ emit_byte(cinfo, (int) mark);
+}
+
+
+LOCAL(void)
+emit_2bytes (j_compress_ptr cinfo, int value)
+/* Emit a 2-byte integer; these are always MSB first in JPEG files */
+{
+ emit_byte(cinfo, (value >> 8) & 0xFF);
+ emit_byte(cinfo, value & 0xFF);
+}
+
+
+/*
+ * Routines to write specific marker types.
+ */
+
+LOCAL(int)
+emit_dqt (j_compress_ptr cinfo, int index)
+/* Emit a DQT marker */
+/* Returns the precision used (0 = 8bits, 1 = 16bits) for baseline checking */
+{
+ JTQUANT_TBL * qtbl = cinfo->quant_tbl_ptrs[index];
+ int prec;
+ int i;
+
+ if (qtbl == NULL)
+ ERREXIT1(cinfo, JERR_NO_TQUANT_TABLE, index);
+
+ prec = 0;
+ for (i = 0; i < DCTSIZE2; i++) {
+ if (qtbl->quantval[i] > 255)
+ prec = 1;
+ }
+
+ if (! qtbl->sent_table) {
+ emit_marker(cinfo, M_DQT);
+
+ emit_2bytes(cinfo, prec ? DCTSIZE2*2 + 1 + 2 : DCTSIZE2 + 1 + 2);
+
+ emit_byte(cinfo, index + (prec<<4));
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ /* The table entries must be emitted in zigzag order. */
+ unsigned int qval = qtbl->quantval[jpeg_natural_order[i]];
+ if (prec)
+ emit_byte(cinfo, (int) (qval >> 8));
+ emit_byte(cinfo, (int) (qval & 0xFF));
+ }
+
+ qtbl->sent_table = TRUE;
+ }
+
+ return prec;
+}
+
+
+LOCAL(void)
+emit_dht (j_compress_ptr cinfo, int index, boolean is_ac)
+/* Emit a DHT marker */
+{
+ JHUFF_TBL * htbl;
+ int length, i;
+
+ if (is_ac) {
+ htbl = cinfo->ac_huff_tbl_ptrs[index];
+ index += 0x10; /* output index has AC bit set */
+ } else {
+ htbl = cinfo->dc_huff_tbl_ptrs[index];
+ }
+
+ if (htbl == NULL)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, index);
+
+ if (! htbl->sent_table) {
+ emit_marker(cinfo, M_DHT);
+
+ length = 0;
+ for (i = 1; i <= 16; i++)
+ length += htbl->bits[i];
+
+ emit_2bytes(cinfo, length + 2 + 1 + 16);
+ emit_byte(cinfo, index);
+
+ for (i = 1; i <= 16; i++)
+ emit_byte(cinfo, htbl->bits[i]);
+
+ for (i = 0; i < length; i++)
+ emit_byte(cinfo, htbl->huffval[i]);
+
+ htbl->sent_table = TRUE;
+ }
+}
+
+
+LOCAL(void)
+emit_dac (j_compress_ptr cinfo)
+/* Emit a DAC marker */
+/* Since the useful info is so small, we want to emit all the tables in */
+/* one DAC marker. Therefore this routine does its own scan of the table. */
+{
+#ifdef C_ARITH_CODING_SUPPORTED
+ char dc_in_use[NUM_ARITH_TBLS];
+ char ac_in_use[NUM_ARITH_TBLS];
+ int length, i;
+ jpeg_component_info *compptr;
+
+ for (i = 0; i < NUM_ARITH_TBLS; i++)
+ dc_in_use[i] = ac_in_use[i] = 0;
+
+ for (i = 0; i < cinfo->comps_in_scan; i++) {
+ compptr = cinfo->cur_comp_info[i];
+ dc_in_use[compptr->dc_tbl_no] = 1;
+ ac_in_use[compptr->ac_tbl_no] = 1;
+ }
+
+ length = 0;
+ for (i = 0; i < NUM_ARITH_TBLS; i++)
+ length += dc_in_use[i] + ac_in_use[i];
+
+ emit_marker(cinfo, M_DAC);
+
+ emit_2bytes(cinfo, length*2 + 2);
+
+ for (i = 0; i < NUM_ARITH_TBLS; i++) {
+ if (dc_in_use[i]) {
+ emit_byte(cinfo, i);
+ emit_byte(cinfo, cinfo->arith_dc_L[i] + (cinfo->arith_dc_U[i]<<4));
+ }
+ if (ac_in_use[i]) {
+ emit_byte(cinfo, i + 0x10);
+ emit_byte(cinfo, cinfo->arith_ac_K[i]);
+ }
+ }
+#endif /* C_ARITH_CODING_SUPPORTED */
+}
+
+
+LOCAL(void)
+emit_dri (j_compress_ptr cinfo)
+/* Emit a DRI marker */
+{
+ emit_marker(cinfo, M_DRI);
+
+ emit_2bytes(cinfo, 4); /* fixed length */
+
+ emit_2bytes(cinfo, (int) cinfo->restart_interval);
+}
+
+
+LOCAL(void)
+emit_sof (j_compress_ptr cinfo, JPEG_MARKER code)
+/* Emit a SOF marker */
+{
+ int ci;
+ jpeg_component_info *compptr;
+
+ emit_marker(cinfo, code);
+
+ emit_2bytes(cinfo, 3 * cinfo->num_components + 2 + 5 + 1); /* length */
+
+ /* Make sure image isn't bigger than SOF field can handle */
+ if ((long) cinfo->image_height > 65535L ||
+ (long) cinfo->image_width > 65535L)
+ ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) 65535);
+
+ emit_byte(cinfo, cinfo->data_precision);
+ emit_2bytes(cinfo, (int) cinfo->image_height);
+ emit_2bytes(cinfo, (int) cinfo->image_width);
+
+ emit_byte(cinfo, cinfo->num_components);
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ emit_byte(cinfo, compptr->component_id);
+ emit_byte(cinfo, (compptr->h_samp_factor << 4) + compptr->v_samp_factor);
+ emit_byte(cinfo, compptr->quant_tbl_no);
+ }
+}
+
+
+LOCAL(void)
+emit_sos (j_compress_ptr cinfo)
+/* Emit a SOS marker */
+{
+ int i, td, ta;
+ jpeg_component_info *compptr;
+
+ emit_marker(cinfo, M_SOS);
+
+ emit_2bytes(cinfo, 2 * cinfo->comps_in_scan + 2 + 1 + 3); /* length */
+
+ emit_byte(cinfo, cinfo->comps_in_scan);
+
+ for (i = 0; i < cinfo->comps_in_scan; i++) {
+ compptr = cinfo->cur_comp_info[i];
+ emit_byte(cinfo, compptr->component_id);
+ td = compptr->dc_tbl_no;
+ ta = compptr->ac_tbl_no;
+ if (cinfo->progressive_mode) {
+ /* Progressive mode: only DC or only AC tables are used in one scan;
+ * furthermore, Huffman coding of DC refinement uses no table at all.
+ * We emit 0 for unused field(s); this is recommended by the P&M text
+ * but does not seem to be specified in the standard.
+ */
+ if (cinfo->Ss == 0) {
+ ta = 0; /* DC scan */
+ if (cinfo->Ah != 0 && !cinfo->arith_code)
+ td = 0; /* no DC table either */
+ } else {
+ td = 0; /* AC scan */
+ }
+ }
+ emit_byte(cinfo, (td << 4) + ta);
+ }
+
+ emit_byte(cinfo, cinfo->Ss);
+ emit_byte(cinfo, cinfo->Se);
+ emit_byte(cinfo, (cinfo->Ah << 4) + cinfo->Al);
+}
+
+
+LOCAL(void)
+emit_jfif_app0 (j_compress_ptr cinfo)
+/* Emit a JFIF-compliant APP0 marker */
+{
+ /*
+ * Length of APP0 block (2 bytes)
+ * Block ID (4 bytes - ASCII "JFIF")
+ * Zero byte (1 byte to terminate the ID string)
+ * Version Major, Minor (2 bytes - major first)
+ * Units (1 byte - 0x00 = none, 0x01 = inch, 0x02 = cm)
+ * Xdpu (2 bytes - dots per unit horizontal)
+ * Ydpu (2 bytes - dots per unit vertical)
+ * Thumbnail X size (1 byte)
+ * Thumbnail Y size (1 byte)
+ */
+
+ emit_marker(cinfo, M_APP0);
+
+ emit_2bytes(cinfo, 2 + 4 + 1 + 2 + 1 + 2 + 2 + 1 + 1); /* length */
+
+ emit_byte(cinfo, 0x4A); /* Identifier: ASCII "JFIF" */
+ emit_byte(cinfo, 0x46);
+ emit_byte(cinfo, 0x49);
+ emit_byte(cinfo, 0x46);
+ emit_byte(cinfo, 0);
+ emit_byte(cinfo, cinfo->JFIF_major_version); /* Version fields */
+ emit_byte(cinfo, cinfo->JFIF_minor_version);
+ emit_byte(cinfo, cinfo->density_unit); /* Pixel size information */
+ emit_2bytes(cinfo, (int) cinfo->X_density);
+ emit_2bytes(cinfo, (int) cinfo->Y_density);
+ emit_byte(cinfo, 0); /* No thumbnail image */
+ emit_byte(cinfo, 0);
+}
+
+
+LOCAL(void)
+emit_adobe_app14 (j_compress_ptr cinfo)
+/* Emit an Adobe APP14 marker */
+{
+ /*
+ * Length of APP14 block (2 bytes)
+ * Block ID (5 bytes - ASCII "Adobe")
+ * Version Number (2 bytes - currently 100)
+ * Flags0 (2 bytes - currently 0)
+ * Flags1 (2 bytes - currently 0)
+ * Color transform (1 byte)
+ *
+ * Although Adobe TN 5116 mentions Version = 101, all the Adobe files
+ * now in circulation seem to use Version = 100, so that's what we write.
+ *
+ * We write the color transform byte as 1 if the JPEG color space is
+ * YCbCr, 2 if it's YCCK, 0 otherwise. Adobe's definition has to do with
+ * whether the encoder performed a transformation, which is pretty useless.
+ */
+
+ emit_marker(cinfo, M_APP14);
+
+ emit_2bytes(cinfo, 2 + 5 + 2 + 2 + 2 + 1); /* length */
+
+ emit_byte(cinfo, 0x41); /* Identifier: ASCII "Adobe" */
+ emit_byte(cinfo, 0x64);
+ emit_byte(cinfo, 0x6F);
+ emit_byte(cinfo, 0x62);
+ emit_byte(cinfo, 0x65);
+ emit_2bytes(cinfo, 100); /* Version */
+ emit_2bytes(cinfo, 0); /* Flags0 */
+ emit_2bytes(cinfo, 0); /* Flags1 */
+ switch (cinfo->jpeg_color_space) {
+ case JCS_YCbCr:
+ emit_byte(cinfo, 1); /* Color transform = 1 */
+ break;
+ case JCS_YCCK:
+ emit_byte(cinfo, 2); /* Color transform = 2 */
+ break;
+ default:
+ emit_byte(cinfo, 0); /* Color transform = 0 */
+ break;
+ }
+}
+
+
+/*
+ * These routines allow writing an arbitrary marker with parameters.
+ * The only intended use is to emit COM or APPn markers after calling
+ * write_file_header and before calling write_frame_header.
+ * Other uses are not guaranteed to produce desirable results.
+ * Counting the parameter bytes properly is the caller's responsibility.
+ */
+
+METHODDEF(void)
+write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
+/* Emit an arbitrary marker header */
+{
+ if (datalen > (unsigned int) 65533) /* safety check */
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ emit_marker(cinfo, (JPEG_MARKER) marker);
+
+ emit_2bytes(cinfo, (int) (datalen + 2)); /* total length */
+}
+
+METHODDEF(void)
+write_marker_byte (j_compress_ptr cinfo, int val)
+/* Emit one byte of marker parameters following write_marker_header */
+{
+ emit_byte(cinfo, val);
+}
+
+
+/*
+ * Write datastream header.
+ * This consists of an SOI and optional APPn markers.
+ * We recommend use of the JFIF marker, but not the Adobe marker,
+ * when using YCbCr or grayscale data. The JFIF marker should NOT
+ * be used for any other JPEG colorspace. The Adobe marker is helpful
+ * to distinguish RGB, CMYK, and YCCK colorspaces.
+ * Note that an application can write additional header markers after
+ * jpeg_start_compress returns.
+ */
+
+METHODDEF(void)
+write_file_header (j_compress_ptr cinfo)
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
+ emit_marker(cinfo, M_SOI); /* first the SOI */
+
+ /* SOI is defined to reset restart interval to 0 */
+ marker->last_restart_interval = 0;
+
+ if (cinfo->write_JFIF_header) /* next an optional JFIF APP0 */
+ emit_jfif_app0(cinfo);
+ if (cinfo->write_Adobe_marker) /* next an optional Adobe APP14 */
+ emit_adobe_app14(cinfo);
+}
+
+
+/*
+ * Write frame header.
+ * This consists of DQT and SOFn markers.
+ * Note that we do not emit the SOF until we have emitted the DQT(s).
+ * This avoids compatibility problems with incorrect implementations that
+ * try to error-check the quant table numbers as soon as they see the SOF.
+ */
+
+METHODDEF(void)
+write_frame_header (j_compress_ptr cinfo)
+{
+ int ci, prec;
+ boolean is_baseline;
+ jpeg_component_info *compptr;
+
+ /* Emit DQT for each quantization table.
+ * Note that emit_dqt() suppresses any duplicate tables.
+ */
+ prec = 0;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ prec += emit_dqt(cinfo, compptr->quant_tbl_no);
+ }
+ /* now prec is nonzero iff there are any 16-bit quant tables. */
+
+ /* Check for a non-baseline specification.
+ * Note we assume that Huffman table numbers won't be changed later.
+ */
+ if (cinfo->arith_code || cinfo->progressive_mode ||
+ cinfo->data_precision != 8) {
+ is_baseline = FALSE;
+ } else {
+ is_baseline = TRUE;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (compptr->dc_tbl_no > 1 || compptr->ac_tbl_no > 1)
+ is_baseline = FALSE;
+ }
+ if (prec && is_baseline) {
+ is_baseline = FALSE;
+ /* If it's baseline except for quantizer size, warn the user */
+ TRACEMS(cinfo, 0, JTRC_16BIT_TABLES);
+ }
+ }
+
+ /* Emit the proper SOF marker */
+ if (cinfo->arith_code) {
+ emit_sof(cinfo, M_SOF9); /* SOF code for arithmetic coding */
+ } else {
+ if (cinfo->progressive_mode)
+ emit_sof(cinfo, M_SOF2); /* SOF code for progressive Huffman */
+ else if (is_baseline)
+ emit_sof(cinfo, M_SOF0); /* SOF code for baseline implementation */
+ else
+ emit_sof(cinfo, M_SOF1); /* SOF code for non-baseline Huffman file */
+ }
+}
+
+
+/*
+ * Write scan header.
+ * This consists of DHT or DAC markers, optional DRI, and SOS.
+ * Compressed data will be written following the SOS.
+ */
+
+METHODDEF(void)
+write_scan_header (j_compress_ptr cinfo)
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+ int i;
+ jpeg_component_info *compptr;
+
+ if (cinfo->arith_code) {
+ /* Emit arith conditioning info. We may have some duplication
+ * if the file has multiple scans, but it's so small it's hardly
+ * worth worrying about.
+ */
+ emit_dac(cinfo);
+ } else {
+ /* Emit Huffman tables.
+ * Note that emit_dht() suppresses any duplicate tables.
+ */
+ for (i = 0; i < cinfo->comps_in_scan; i++) {
+ compptr = cinfo->cur_comp_info[i];
+ if (cinfo->progressive_mode) {
+ /* Progressive mode: only DC or only AC tables are used in one scan */
+ if (cinfo->Ss == 0) {
+ if (cinfo->Ah == 0) /* DC needs no table for refinement scan */
+ emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
+ } else {
+ emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
+ }
+ } else {
+ /* Sequential mode: need both DC and AC tables */
+ emit_dht(cinfo, compptr->dc_tbl_no, FALSE);
+ emit_dht(cinfo, compptr->ac_tbl_no, TRUE);
+ }
+ }
+ }
+
+ /* Emit DRI if required --- note that DRI value could change for each scan.
+ * We avoid wasting space with unnecessary DRIs, however.
+ */
+ if (cinfo->restart_interval != marker->last_restart_interval) {
+ emit_dri(cinfo);
+ marker->last_restart_interval = cinfo->restart_interval;
+ }
+
+ emit_sos(cinfo);
+}
+
+
+/*
+ * Write datastream trailer.
+ */
+
+METHODDEF(void)
+write_file_trailer (j_compress_ptr cinfo)
+{
+ emit_marker(cinfo, M_EOI);
+}
+
+
+/*
+ * Write an abbreviated table-specification datastream.
+ * This consists of SOI, DQT and DHT tables, and EOI.
+ * Any table that is defined and not marked sent_table = TRUE will be
+ * emitted. Note that all tables will be marked sent_table = TRUE at exit.
+ */
+
+METHODDEF(void)
+write_tables_only (j_compress_ptr cinfo)
+{
+ int i;
+
+ emit_marker(cinfo, M_SOI);
+
+ for (i = 0; i < NUM_TQUANT_TBLS; i++) {
+ if (cinfo->quant_tbl_ptrs[i] != NULL)
+ (void) emit_dqt(cinfo, i);
+ }
+
+ if (! cinfo->arith_code) {
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ if (cinfo->dc_huff_tbl_ptrs[i] != NULL)
+ emit_dht(cinfo, i, FALSE);
+ if (cinfo->ac_huff_tbl_ptrs[i] != NULL)
+ emit_dht(cinfo, i, TRUE);
+ }
+ }
+
+ emit_marker(cinfo, M_EOI);
+}
+
+
+/*
+ * Initialize the marker writer module.
+ */
+
+GLOBAL(void)
+jinit_marker_writer (j_compress_ptr cinfo)
+{
+ my_marker_ptr marker;
+
+ /* Create the subobject */
+ marker = (my_marker_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_marker_writer));
+ cinfo->marker = (struct jpeg_marker_writer *) marker;
+ /* Initialize method pointers */
+ marker->pub.write_file_header = write_file_header;
+ marker->pub.write_frame_header = write_frame_header;
+ marker->pub.write_scan_header = write_scan_header;
+ marker->pub.write_file_trailer = write_file_trailer;
+ marker->pub.write_tables_only = write_tables_only;
+ marker->pub.write_marker_header = write_marker_header;
+ marker->pub.write_marker_byte = write_marker_byte;
+ /* Initialize private state */
+ marker->last_restart_interval = 0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcmaster.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcmaster.c
new file mode 100644
index 0000000..914cb58
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcmaster.c
@@ -0,0 +1,590 @@
+/*
+ * jcmaster.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains master control logic for the JPEG compressor.
+ * These routines are concerned with parameter validation, initial setup,
+ * and inter-pass control (determining the number of passes and the work
+ * to be done in each pass).
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private state */
+
+typedef enum {
+ main_pass, /* input data, also do first output step */
+ huff_opt_pass, /* Huffman code optimization pass */
+ output_pass /* data output pass */
+} c_pass_type;
+
+typedef struct {
+ struct jpeg_comp_master pub; /* public fields */
+
+ c_pass_type pass_type; /* the type of the current pass */
+
+ int pass_number; /* # of passes completed */
+ int total_passes; /* total # of passes needed */
+
+ int scan_number; /* current index in scan_info[] */
+} my_comp_master;
+
+typedef my_comp_master * my_master_ptr;
+
+
+/*
+ * Support routines that do various essential calculations.
+ */
+
+LOCAL(void)
+initial_setup (j_compress_ptr cinfo)
+/* Do computations that are needed before master selection phase */
+{
+ int ci;
+ jpeg_component_info *compptr;
+ long samplesperrow;
+ JDIMENSION jd_samplesperrow;
+
+ /* Sanity check on image dimensions */
+ if (cinfo->image_height <= 0 || cinfo->image_width <= 0
+ || cinfo->num_components <= 0 || cinfo->input_components <= 0)
+ ERREXIT(cinfo, JERR_EMPTY_IMAGE);
+
+ /* Make sure image isn't bigger than I can handle */
+ if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
+ (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
+ ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
+
+ /* Width of an input scanline must be representable as JDIMENSION. */
+ samplesperrow = (long) cinfo->image_width * (long) cinfo->input_components;
+ jd_samplesperrow = (JDIMENSION) samplesperrow;
+ if ((long) jd_samplesperrow != samplesperrow)
+ ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+
+ /* For now, precision must match compiled-in value... */
+ if (cinfo->data_precision != BITS_IN_JSAMPLE)
+ ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
+
+ /* Check that number of components won't exceed internal array sizes */
+ if (cinfo->num_components > MAX_COMPONENTS)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+ MAX_COMPONENTS);
+
+ /* Compute maximum sampling factors; check factor validity */
+ cinfo->max_h_samp_factor = 1;
+ cinfo->max_v_samp_factor = 1;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
+ compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
+ ERREXIT(cinfo, JERR_BAD_SAMPLING);
+ cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
+ compptr->h_samp_factor);
+ cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
+ compptr->v_samp_factor);
+ }
+
+ /* Compute dimensions of components */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Fill in the correct component_index value; don't rely on application */
+ compptr->component_index = ci;
+ /* For compression, we never do DCT scaling. */
+ compptr->DCT_scaled_size = DCTSIZE;
+ /* Size in DCT blocks */
+ compptr->width_in_blocks = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
+ (long) (cinfo->max_h_samp_factor * DCTSIZE));
+ compptr->height_in_blocks = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
+ (long) (cinfo->max_v_samp_factor * DCTSIZE));
+ /* Size in samples */
+ compptr->downsampled_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
+ (long) cinfo->max_h_samp_factor);
+ compptr->downsampled_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
+ (long) cinfo->max_v_samp_factor);
+ /* Mark component needed (this flag isn't actually used for compression) */
+ compptr->component_needed = TRUE;
+ }
+
+ /* Compute number of fully interleaved MCU rows (number of times that
+ * main controller will call coefficient controller).
+ */
+ cinfo->total_iMCU_rows = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height,
+ (long) (cinfo->max_v_samp_factor*DCTSIZE));
+}
+
+
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+
+LOCAL(void)
+validate_script (j_compress_ptr cinfo)
+/* Verify that the scan script in cinfo->scan_info[] is valid; also
+ * determine whether it uses progressive JPEG, and set cinfo->progressive_mode.
+ */
+{
+ const jpeg_scan_info * scanptr;
+ int scanno, ncomps, ci, coefi, thisi;
+ int Ss, Se, Ah, Al;
+ boolean component_sent[MAX_COMPONENTS];
+#ifdef C_PROGRESSIVE_SUPPORTED
+ int * last_bitpos_ptr;
+ int last_bitpos[MAX_COMPONENTS][DCTSIZE2];
+ /* -1 until that coefficient has been seen; then last Al for it */
+#endif
+
+ if (cinfo->num_scans <= 0)
+ ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, 0);
+
+ /* For sequential JPEG, all scans must have Ss=0, Se=DCTSIZE2-1;
+ * for progressive JPEG, no scan can have this.
+ */
+ scanptr = cinfo->scan_info;
+ if (scanptr->Ss != 0 || scanptr->Se != DCTSIZE2-1) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+ cinfo->progressive_mode = TRUE;
+ last_bitpos_ptr = & last_bitpos[0][0];
+ for (ci = 0; ci < cinfo->num_components; ci++)
+ for (coefi = 0; coefi < DCTSIZE2; coefi++)
+ *last_bitpos_ptr++ = -1;
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ cinfo->progressive_mode = FALSE;
+ for (ci = 0; ci < cinfo->num_components; ci++)
+ component_sent[ci] = FALSE;
+ }
+
+ for (scanno = 1; scanno <= cinfo->num_scans; scanptr++, scanno++) {
+ /* Validate component indexes */
+ ncomps = scanptr->comps_in_scan;
+ if (ncomps <= 0 || ncomps > MAX_COMPS_IN_SCAN)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, ncomps, MAX_COMPS_IN_SCAN);
+ for (ci = 0; ci < ncomps; ci++) {
+ thisi = scanptr->component_index[ci];
+ if (thisi < 0 || thisi >= cinfo->num_components)
+ ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
+ /* Components must appear in SOF order within each scan */
+ if (ci > 0 && thisi <= scanptr->component_index[ci-1])
+ ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
+ }
+ /* Validate progression parameters */
+ Ss = scanptr->Ss;
+ Se = scanptr->Se;
+ Ah = scanptr->Ah;
+ Al = scanptr->Al;
+ if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+ /* The JPEG spec simply gives the ranges 0..13 for Ah and Al, but that
+ * seems wrong: the upper bound ought to depend on data precision.
+ * Perhaps they really meant 0..N+1 for N-bit precision.
+ * Here we allow 0..10 for 8-bit data; Al larger than 10 results in
+ * out-of-range reconstructed DC values during the first DC scan,
+ * which might cause problems for some decoders.
+ */
+#if BITS_IN_JSAMPLE == 8
+#define MAX_AH_AL 10
+#else
+#define MAX_AH_AL 13
+#endif
+ if (Ss < 0 || Ss >= DCTSIZE2 || Se < Ss || Se >= DCTSIZE2 ||
+ Ah < 0 || Ah > MAX_AH_AL || Al < 0 || Al > MAX_AH_AL)
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ if (Ss == 0) {
+ if (Se != 0) /* DC and AC together not OK */
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ } else {
+ if (ncomps != 1) /* AC scans must be for only one component */
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ }
+ for (ci = 0; ci < ncomps; ci++) {
+ last_bitpos_ptr = & last_bitpos[scanptr->component_index[ci]][0];
+ if (Ss != 0 && last_bitpos_ptr[0] < 0) /* AC without prior DC scan */
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ for (coefi = Ss; coefi <= Se; coefi++) {
+ if (last_bitpos_ptr[coefi] < 0) {
+ /* first scan of this coefficient */
+ if (Ah != 0)
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ } else {
+ /* not first scan */
+ if (Ah != last_bitpos_ptr[coefi] || Al != Ah-1)
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ }
+ last_bitpos_ptr[coefi] = Al;
+ }
+ }
+#endif
+ } else {
+ /* For sequential JPEG, all progression parameters must be these: */
+ if (Ss != 0 || Se != DCTSIZE2-1 || Ah != 0 || Al != 0)
+ ERREXIT1(cinfo, JERR_BAD_PROG_SCRIPT, scanno);
+ /* Make sure components are not sent twice */
+ for (ci = 0; ci < ncomps; ci++) {
+ thisi = scanptr->component_index[ci];
+ if (component_sent[thisi])
+ ERREXIT1(cinfo, JERR_BAD_SCAN_SCRIPT, scanno);
+ component_sent[thisi] = TRUE;
+ }
+ }
+ }
+
+ /* Now verify that everything got sent. */
+ if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+ /* For progressive mode, we only check that at least some DC data
+ * got sent for each component; the spec does not require that all bits
+ * of all coefficients be transmitted. Would it be wiser to enforce
+ * transmission of all coefficient bits??
+ */
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ if (last_bitpos[ci][0] < 0)
+ ERREXIT(cinfo, JERR_MISSING_DATA);
+ }
+#endif
+ } else {
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ if (! component_sent[ci])
+ ERREXIT(cinfo, JERR_MISSING_DATA);
+ }
+ }
+}
+
+#endif /* C_MULTISCAN_FILES_SUPPORTED */
+
+
+LOCAL(void)
+select_scan_parameters (j_compress_ptr cinfo)
+/* Set up the scan parameters for the current scan */
+{
+ int ci;
+
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+ if (cinfo->scan_info != NULL) {
+ /* Prepare for current scan --- the script is already validated */
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+ const jpeg_scan_info * scanptr = cinfo->scan_info + master->scan_number;
+
+ cinfo->comps_in_scan = scanptr->comps_in_scan;
+ for (ci = 0; ci < scanptr->comps_in_scan; ci++) {
+ cinfo->cur_comp_info[ci] =
+ &cinfo->comp_info[scanptr->component_index[ci]];
+ }
+ cinfo->Ss = scanptr->Ss;
+ cinfo->Se = scanptr->Se;
+ cinfo->Ah = scanptr->Ah;
+ cinfo->Al = scanptr->Al;
+ }
+ else
+#endif
+ {
+ /* Prepare for single sequential-JPEG scan containing all components */
+ if (cinfo->num_components > MAX_COMPS_IN_SCAN)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+ MAX_COMPS_IN_SCAN);
+ cinfo->comps_in_scan = cinfo->num_components;
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci];
+ }
+ cinfo->Ss = 0;
+ cinfo->Se = DCTSIZE2-1;
+ cinfo->Ah = 0;
+ cinfo->Al = 0;
+ }
+}
+
+
+LOCAL(void)
+per_scan_setup (j_compress_ptr cinfo)
+/* Do computations that are needed before processing a JPEG scan */
+/* cinfo->comps_in_scan and cinfo->cur_comp_info[] are already set */
+{
+ int ci, mcublks, tmp;
+ jpeg_component_info *compptr;
+
+ if (cinfo->comps_in_scan == 1) {
+
+ /* Noninterleaved (single-component) scan */
+ compptr = cinfo->cur_comp_info[0];
+
+ /* Overall image size in MCUs */
+ cinfo->MCUs_per_row = compptr->width_in_blocks;
+ cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
+
+ /* For noninterleaved scan, always one block per MCU */
+ compptr->MCU_width = 1;
+ compptr->MCU_height = 1;
+ compptr->MCU_blocks = 1;
+ compptr->MCU_sample_width = DCTSIZE;
+ compptr->last_col_width = 1;
+ /* For noninterleaved scans, it is convenient to define last_row_height
+ * as the number of block rows present in the last iMCU row.
+ */
+ tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+ if (tmp == 0) tmp = compptr->v_samp_factor;
+ compptr->last_row_height = tmp;
+
+ /* Prepare array describing MCU composition */
+ cinfo->blocks_in_MCU = 1;
+ cinfo->MCU_membership[0] = 0;
+
+ } else {
+
+ /* Interleaved (multi-component) scan */
+ if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
+ MAX_COMPS_IN_SCAN);
+
+ /* Overall image size in MCUs */
+ cinfo->MCUs_per_row = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width,
+ (long) (cinfo->max_h_samp_factor*DCTSIZE));
+ cinfo->MCU_rows_in_scan = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height,
+ (long) (cinfo->max_v_samp_factor*DCTSIZE));
+
+ cinfo->blocks_in_MCU = 0;
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* Sampling factors give # of blocks of component in each MCU */
+ compptr->MCU_width = compptr->h_samp_factor;
+ compptr->MCU_height = compptr->v_samp_factor;
+ compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
+ compptr->MCU_sample_width = compptr->MCU_width * DCTSIZE;
+ /* Figure number of non-dummy blocks in last MCU column & row */
+ tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
+ if (tmp == 0) tmp = compptr->MCU_width;
+ compptr->last_col_width = tmp;
+ tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
+ if (tmp == 0) tmp = compptr->MCU_height;
+ compptr->last_row_height = tmp;
+ /* Prepare array describing MCU composition */
+ mcublks = compptr->MCU_blocks;
+ if (cinfo->blocks_in_MCU + mcublks > C_MAX_BLOCKS_IN_MCU)
+ ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
+ while (mcublks-- > 0) {
+ cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
+ }
+ }
+
+ }
+
+ /* Convert restart specified in rows to actual MCU count. */
+ /* Note that count must fit in 16 bits, so we provide limiting. */
+ if (cinfo->restart_in_rows > 0) {
+ long nominal = (long) cinfo->restart_in_rows * (long) cinfo->MCUs_per_row;
+ cinfo->restart_interval = (unsigned int) MIN(nominal, 65535L);
+ }
+}
+
+
+/*
+ * Per-pass setup.
+ * This is called at the beginning of each pass. We determine which modules
+ * will be active during this pass and give them appropriate start_pass calls.
+ * We also set is_last_pass to indicate whether any more passes will be
+ * required.
+ */
+
+METHODDEF(void)
+prepare_for_pass (j_compress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+
+ switch (master->pass_type) {
+ case main_pass:
+ /* Initial pass: will collect input data, and do either Huffman
+ * optimization or data output for the first scan.
+ */
+ select_scan_parameters(cinfo);
+ per_scan_setup(cinfo);
+ if (! cinfo->raw_data_in) {
+ (*cinfo->cconvert->start_pass) (cinfo);
+ (*cinfo->downsample->start_pass) (cinfo);
+ (*cinfo->prep->start_pass) (cinfo, JBUF_PASS_THRU);
+ }
+ (*cinfo->fdct->start_pass) (cinfo);
+ (*cinfo->entropy->start_pass) (cinfo, cinfo->optimize_coding);
+ (*cinfo->coef->start_pass) (cinfo,
+ (master->total_passes > 1 ?
+ JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
+ (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
+ if (cinfo->optimize_coding) {
+ /* No immediate data output; postpone writing frame/scan headers */
+ master->pub.call_pass_startup = FALSE;
+ } else {
+ /* Will write frame/scan headers at first jpeg_write_scanlines call */
+ master->pub.call_pass_startup = TRUE;
+ }
+ break;
+#ifdef ENTROPY_OPT_SUPPORTED
+ case huff_opt_pass:
+ /* Do Huffman optimization for a scan after the first one. */
+ select_scan_parameters(cinfo);
+ per_scan_setup(cinfo);
+ if (cinfo->Ss != 0 || cinfo->Ah == 0 || cinfo->arith_code) {
+ (*cinfo->entropy->start_pass) (cinfo, TRUE);
+ (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
+ master->pub.call_pass_startup = FALSE;
+ break;
+ }
+ /* Special case: Huffman DC refinement scans need no Huffman table
+ * and therefore we can skip the optimization pass for them.
+ */
+ master->pass_type = output_pass;
+ master->pass_number++;
+ /*FALLTHROUGH*/
+#endif
+ case output_pass:
+ /* Do a data-output pass. */
+ /* We need not repeat per-scan setup if prior optimization pass did it. */
+ if (! cinfo->optimize_coding) {
+ select_scan_parameters(cinfo);
+ per_scan_setup(cinfo);
+ }
+ (*cinfo->entropy->start_pass) (cinfo, FALSE);
+ (*cinfo->coef->start_pass) (cinfo, JBUF_CRANK_DEST);
+ /* We emit frame/scan headers now */
+ if (master->scan_number == 0)
+ (*cinfo->marker->write_frame_header) (cinfo);
+ (*cinfo->marker->write_scan_header) (cinfo);
+ master->pub.call_pass_startup = FALSE;
+ break;
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ }
+
+ master->pub.is_last_pass = (master->pass_number == master->total_passes-1);
+
+ /* Set up progress monitor's pass info if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->completed_passes = master->pass_number;
+ cinfo->progress->total_passes = master->total_passes;
+ }
+}
+
+
+/*
+ * Special start-of-pass hook.
+ * This is called by jpeg_write_scanlines if call_pass_startup is TRUE.
+ * In single-pass processing, we need this hook because we don't want to
+ * write frame/scan headers during jpeg_start_compress; we want to let the
+ * application write COM markers etc. between jpeg_start_compress and the
+ * jpeg_write_scanlines loop.
+ * In multi-pass processing, this routine is not used.
+ */
+
+METHODDEF(void)
+pass_startup (j_compress_ptr cinfo)
+{
+ cinfo->master->call_pass_startup = FALSE; /* reset flag so call only once */
+
+ (*cinfo->marker->write_frame_header) (cinfo);
+ (*cinfo->marker->write_scan_header) (cinfo);
+}
+
+
+/*
+ * Finish up at end of pass.
+ */
+
+METHODDEF(void)
+finish_pass_master (j_compress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+
+ /* The entropy coder always needs an end-of-pass call,
+ * either to analyze statistics or to flush its output buffer.
+ */
+ (*cinfo->entropy->finish_pass) (cinfo);
+
+ /* Update state for next pass */
+ switch (master->pass_type) {
+ case main_pass:
+ /* next pass is either output of scan 0 (after optimization)
+ * or output of scan 1 (if no optimization).
+ */
+ master->pass_type = output_pass;
+ if (! cinfo->optimize_coding)
+ master->scan_number++;
+ break;
+ case huff_opt_pass:
+ /* next pass is always output of current scan */
+ master->pass_type = output_pass;
+ break;
+ case output_pass:
+ /* next pass is either optimization or output of next scan */
+ if (cinfo->optimize_coding)
+ master->pass_type = huff_opt_pass;
+ master->scan_number++;
+ break;
+ }
+
+ master->pass_number++;
+}
+
+
+/*
+ * Initialize master compression control.
+ */
+
+GLOBAL(void)
+jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only)
+{
+ my_master_ptr master;
+
+ master = (my_master_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_comp_master));
+ cinfo->master = (struct jpeg_comp_master *) master;
+ master->pub.prepare_for_pass = prepare_for_pass;
+ master->pub.pass_startup = pass_startup;
+ master->pub.finish_pass = finish_pass_master;
+ master->pub.is_last_pass = FALSE;
+
+ /* Validate parameters, determine derived values */
+ initial_setup(cinfo);
+
+ if (cinfo->scan_info != NULL) {
+#ifdef C_MULTISCAN_FILES_SUPPORTED
+ validate_script(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ cinfo->progressive_mode = FALSE;
+ cinfo->num_scans = 1;
+ }
+
+ if (cinfo->progressive_mode) /* TEMPORARY HACK ??? */
+ cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */
+
+ /* Initialize my private state */
+ if (transcode_only) {
+ /* no main pass in transcoding */
+ if (cinfo->optimize_coding)
+ master->pass_type = huff_opt_pass;
+ else
+ master->pass_type = output_pass;
+ } else {
+ /* for normal compression, first pass is always this type: */
+ master->pass_type = main_pass;
+ }
+ master->scan_number = 0;
+ master->pass_number = 0;
+ if (cinfo->optimize_coding)
+ master->total_passes = cinfo->num_scans * 2;
+ else
+ master->total_passes = cinfo->num_scans;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcomapi.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcomapi.c
new file mode 100644
index 0000000..fc4c6ce
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcomapi.c
@@ -0,0 +1,106 @@
+/*
+ * jcomapi.c
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains application interface routines that are used for both
+ * compression and decompression.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Abort processing of a JPEG compression or decompression operation,
+ * but don't destroy the object itself.
+ *
+ * For this, we merely clean up all the nonpermanent memory pools.
+ * Note that temp files (virtual arrays) are not allowed to belong to
+ * the permanent pool, so we will be able to close all temp files here.
+ * Closing a data source or destination, if necessary, is the application's
+ * responsibility.
+ */
+
+GLOBAL(void)
+jpeg_abort (j_common_ptr cinfo)
+{
+ int pool;
+
+ /* Do nothing if called on a not-initialized or destroyed JPEG object. */
+ if (cinfo->mem == NULL)
+ return;
+
+ /* Releasing pools in reverse order might help avoid fragmentation
+ * with some (brain-damaged) malloc libraries.
+ */
+ for (pool = JPOOL_NUMPOOLS-1; pool > JPOOL_PERMANENT; pool--) {
+ (*cinfo->mem->free_pool) (cinfo, pool);
+ }
+
+ /* Reset overall state for possible reuse of object */
+ if (cinfo->is_decompressor) {
+ cinfo->global_state = DSTATE_START;
+ /* Try to keep application from accessing now-deleted marker list.
+ * A bit kludgy to do it here, but this is the most central place.
+ */
+ ((j_decompress_ptr) cinfo)->marker_list = NULL;
+ } else {
+ cinfo->global_state = CSTATE_START;
+ }
+}
+
+
+/*
+ * Destruction of a JPEG object.
+ *
+ * Everything gets deallocated except the master jpeg_compress_struct itself
+ * and the error manager struct. Both of these are supplied by the application
+ * and must be freed, if necessary, by the application. (Often they are on
+ * the stack and so don't need to be freed anyway.)
+ * Closing a data source or destination, if necessary, is the application's
+ * responsibility.
+ */
+
+GLOBAL(void)
+jpeg_destroy (j_common_ptr cinfo)
+{
+ /* We need only tell the memory manager to release everything. */
+ /* NB: mem pointer is NULL if memory mgr failed to initialize. */
+ if (cinfo->mem != NULL)
+ (*cinfo->mem->self_destruct) (cinfo);
+ cinfo->mem = NULL; /* be safe if jpeg_destroy is called twice */
+ cinfo->global_state = 0; /* mark it destroyed */
+}
+
+
+/*
+ * Convenience routines for allocating quantization and Huffman tables.
+ * (Would jutils.c be a more reasonable place to put these?)
+ */
+
+GLOBAL(JTQUANT_TBL *)
+jpeg_alloc_quant_table (j_common_ptr cinfo)
+{
+ JTQUANT_TBL *tbl;
+
+ tbl = (JTQUANT_TBL *)
+ (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JTQUANT_TBL));
+ tbl->sent_table = FALSE; /* make sure this is false in any new table */
+ return tbl;
+}
+
+
+GLOBAL(JHUFF_TBL *)
+jpeg_alloc_huff_table (j_common_ptr cinfo)
+{
+ JHUFF_TBL *tbl;
+
+ tbl = (JHUFF_TBL *)
+ (*cinfo->mem->alloc_small) (cinfo, JPOOL_PERMANENT, SIZEOF(JHUFF_TBL));
+ tbl->sent_table = FALSE; /* make sure this is false in any new table */
+ return tbl;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.bcc b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.bcc
new file mode 100644
index 0000000..c6c53ff
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.bcc
@@ -0,0 +1,48 @@
+/* jconfig.bcc --- jconfig.h for Borland C (Turbo C) on MS-DOS or OS/2. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#ifdef __MSDOS__
+#define NEED_FAR_POINTERS /* for small or medium memory model */
+#endif
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN /* this assumes you have -w-stu in CFLAGS */
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#ifdef __MSDOS__
+#define USE_MSDOS_MEMMGR /* Define this if you use jmemdos.c */
+#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */
+#define USE_FMEM /* Borland has _fmemcpy() and _fmemset() */
+#endif
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#define TWO_FILE_COMMANDLINE
+#define USE_SETMODE /* Borland has setmode() */
+#ifdef __MSDOS__
+#define NEED_SIGNAL_CATCHER /* Define this if you use jmemdos.c */
+#endif
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.cfg b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.cfg
new file mode 100644
index 0000000..36a04fa
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.cfg
@@ -0,0 +1,44 @@
+/* jconfig.cfg --- source file edited by configure script */
+/* see jconfig.doc for explanations */
+
+#undef HAVE_PROTOTYPES
+#undef HAVE_UNSIGNED_CHAR
+#undef HAVE_UNSIGNED_SHORT
+#undef void
+#undef const
+#undef CHAR_IS_UNSIGNED
+#undef HAVE_STDDEF_H
+#undef HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS
+#undef NEED_SHORT_EXTERNAL_NAMES
+/* Define this if you get warnings about undefined structures. */
+#undef INCOMPLETE_TYPES_BROKEN
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+#undef INLINE
+/* These are for configuring the JPEG memory manager. */
+#undef DEFAULT_MAX_MEM
+#undef NO_MKTEMP
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#undef TWO_FILE_COMMANDLINE
+#undef NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+
+/* Define this if you want percent-done progress reports from cjpeg/djpeg. */
+#undef PROGRESS_REPORT
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.dj b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.dj
new file mode 100644
index 0000000..f759a9d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.dj
@@ -0,0 +1,38 @@
+/* jconfig.dj --- jconfig.h for DJGPP (Delorie's GNU C port) on MS-DOS. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS /* DJGPP uses flat 32-bit addressing */
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#undef TWO_FILE_COMMANDLINE /* optional */
+#define USE_SETMODE /* Needed to make one-file style work in DJGPP */
+#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.doc b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.doc
new file mode 100644
index 0000000..c18d1c0
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.doc
@@ -0,0 +1,155 @@
+/*
+ * jconfig.doc
+ *
+ * Copyright (C) 1991-1994, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file documents the configuration options that are required to
+ * customize the JPEG software for a particular system.
+ *
+ * The actual configuration options for a particular installation are stored
+ * in jconfig.h. On many machines, jconfig.h can be generated automatically
+ * or copied from one of the "canned" jconfig files that we supply. But if
+ * you need to generate a jconfig.h file by hand, this file tells you how.
+ *
+ * DO NOT EDIT THIS FILE --- IT WON'T ACCOMPLISH ANYTHING.
+ * EDIT A COPY NAMED JCONFIG.H.
+ */
+
+
+/*
+ * These symbols indicate the properties of your machine or compiler.
+ * #define the symbol if yes, #undef it if no.
+ */
+
+/* Does your compiler support function prototypes?
+ * (If not, you also need to use ansi2knr, see install.doc)
+ */
+#define HAVE_PROTOTYPES
+
+/* Does your compiler support the declaration "unsigned char" ?
+ * How about "unsigned short" ?
+ */
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+
+/* Define "void" as "char" if your compiler doesn't know about type void.
+ * NOTE: be sure to define void such that "void *" represents the most general
+ * pointer type, e.g., that returned by malloc().
+ */
+/* #define void char */
+
+/* Define "const" as empty if your compiler doesn't know the "const" keyword.
+ */
+/* #define const */
+
+/* Define this if an ordinary "char" type is unsigned.
+ * If you're not sure, leaving it undefined will work at some cost in speed.
+ * If you defined HAVE_UNSIGNED_CHAR then the speed difference is minimal.
+ */
+#undef CHAR_IS_UNSIGNED
+
+/* Define this if your system has an ANSI-conforming <stddef.h> file.
+ */
+#define HAVE_STDDEF_H
+
+/* Define this if your system has an ANSI-conforming <stdlib.h> file.
+ */
+#define HAVE_STDLIB_H
+
+/* Define this if your system does not have an ANSI/SysV <string.h>,
+ * but does have a BSD-style <strings.h>.
+ */
+#undef NEED_BSD_STRINGS
+
+/* Define this if your system does not provide typedef size_t in any of the
+ * ANSI-standard places (stddef.h, stdlib.h, or stdio.h), but places it in
+ * <sys/types.h> instead.
+ */
+#undef NEED_SYS_TYPES_H
+
+/* For 80x86 machines, you need to define NEED_FAR_POINTERS,
+ * unless you are using a large-data memory model or 80386 flat-memory mode.
+ * On less brain-damaged CPUs this symbol must not be defined.
+ * (Defining this symbol causes large data structures to be referenced through
+ * "far" pointers and to be allocated with a special version of malloc.)
+ */
+#undef NEED_FAR_POINTERS
+
+/* Define this if your linker needs global names to be unique in less
+ * than the first 15 characters.
+ */
+#undef NEED_SHORT_EXTERNAL_NAMES
+
+/* Although a real ANSI C compiler can deal perfectly well with pointers to
+ * unspecified structures (see "incomplete types" in the spec), a few pre-ANSI
+ * and pseudo-ANSI compilers get confused. To keep one of these bozos happy,
+ * define INCOMPLETE_TYPES_BROKEN. This is not recommended unless you
+ * actually get "missing structure definition" warnings or errors while
+ * compiling the JPEG code.
+ */
+#undef INCOMPLETE_TYPES_BROKEN
+
+
+/*
+ * The following options affect code selection within the JPEG library,
+ * but they don't need to be visible to applications using the library.
+ * To minimize application namespace pollution, the symbols won't be
+ * defined unless JPEG_INTERNALS has been defined.
+ */
+
+#ifdef JPEG_INTERNALS
+
+/* Define this if your compiler implements ">>" on signed values as a logical
+ * (unsigned) shift; leave it undefined if ">>" is a signed (arithmetic) shift,
+ * which is the normal and rational definition.
+ */
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+
+#endif /* JPEG_INTERNALS */
+
+
+/*
+ * The remaining options do not affect the JPEG library proper,
+ * but only the sample applications cjpeg/djpeg (see cjpeg.c, djpeg.c).
+ * Other applications can ignore these.
+ */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+/* These defines indicate which image (non-JPEG) file formats are allowed. */
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+/* Define this if you want to name both input and output files on the command
+ * line, rather than using stdout and optionally stdin. You MUST do this if
+ * your system can't cope with binary I/O to stdin/stdout. See comments at
+ * head of cjpeg.c or djpeg.c.
+ */
+#undef TWO_FILE_COMMANDLINE
+
+/* Define this if your system needs explicit cleanup of temporary files.
+ * This is crucial under MS-DOS, where the temporary "files" may be areas
+ * of extended memory; on most other systems it's not as important.
+ */
+#undef NEED_SIGNAL_CATCHER
+
+/* By default, we open image files with fopen(...,"rb") or fopen(...,"wb").
+ * This is necessary on systems that distinguish text files from binary files,
+ * and is harmless on most systems that don't. If you have one of the rare
+ * systems that complains about the "b" spec, define this symbol.
+ */
+#undef DONT_USE_B_MODE
+
+/* Define this if you want percent-done progress reports from cjpeg/djpeg.
+ */
+#undef PROGRESS_REPORT
+
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.h
new file mode 100644
index 0000000..3ba17c6
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.h
@@ -0,0 +1,47 @@
+/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+#if defined(_WIN32)
+/* Define "boolean" as unsigned char, not int, per Windows custom */
+#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
+typedef unsigned char boolean;
+#endif
+#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
+#endif
+
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#define TWO_FILE_COMMANDLINE /* optional */
+#define USE_SETMODE /* Microsoft has setmode() */
+#undef NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.mac b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.mac
new file mode 100644
index 0000000..0de3efe
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.mac
@@ -0,0 +1,43 @@
+/* jconfig.mac --- jconfig.h for CodeWarrior on Apple Macintosh */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#define USE_MAC_MEMMGR /* Define this if you use jmemmac.c */
+
+#define ALIGN_TYPE long /* Needed for 680x0 Macs */
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#define USE_CCOMMAND /* Command line reader for Macintosh */
+#define TWO_FILE_COMMANDLINE /* Binary I/O thru stdin/stdout doesn't work */
+
+#undef NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.manx b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.manx
new file mode 100644
index 0000000..6dd0d00
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.manx
@@ -0,0 +1,43 @@
+/* jconfig.manx --- jconfig.h for Amiga systems using Manx Aztec C ver 5.x. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#define TEMP_DIRECTORY "JPEGTMP:" /* recommended setting for Amiga */
+
+#define SHORTxSHORT_32 /* produces better DCT code with Aztec C */
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#define TWO_FILE_COMMANDLINE
+#define NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#define signal_catcher _abort /* hack for Aztec C naming requirements */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.mc6 b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.mc6
new file mode 100644
index 0000000..c55082d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.mc6
@@ -0,0 +1,52 @@
+/* jconfig.mc6 --- jconfig.h for Microsoft C on MS-DOS, version 6.00A & up. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#define NEED_FAR_POINTERS /* for small or medium memory model */
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#define USE_MSDOS_MEMMGR /* Define this if you use jmemdos.c */
+
+#define MAX_ALLOC_CHUNK 65520L /* Maximum request to malloc() */
+
+#define USE_FMEM /* Microsoft has _fmemcpy() and _fmemset() */
+
+#define NEED_FHEAPMIN /* far heap management routines are broken */
+
+#define SHORTxLCONST_32 /* enable compiler-specific DCT optimization */
+/* Note: the above define is known to improve the code with Microsoft C 6.00A.
+ * I do not know whether it is good for later compiler versions.
+ * Please report any info on this point to jpeg-info@uunet.uu.net.
+ */
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#define TWO_FILE_COMMANDLINE
+#define USE_SETMODE /* Microsoft has setmode() */
+#define NEED_SIGNAL_CATCHER /* Define this if you use jmemdos.c */
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.sas b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.sas
new file mode 100644
index 0000000..efdac22
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.sas
@@ -0,0 +1,43 @@
+/* jconfig.sas --- jconfig.h for Amiga systems using SAS C 6.0 and up. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#define TEMP_DIRECTORY "JPEGTMP:" /* recommended setting for Amiga */
+
+#define NO_MKTEMP /* SAS C doesn't have mktemp() */
+
+#define SHORTxSHORT_32 /* produces better DCT code with SAS C */
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#define TWO_FILE_COMMANDLINE
+#define NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.st b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.st
new file mode 100644
index 0000000..4421b7a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.st
@@ -0,0 +1,42 @@
+/* jconfig.st --- jconfig.h for Atari ST/STE/TT using Pure C or Turbo C. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS
+#undef NEED_SHORT_EXTERNAL_NAMES
+#define INCOMPLETE_TYPES_BROKEN /* suppress undefined-structure warnings */
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#define ALIGN_TYPE long /* apparently double is a weird size? */
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#define TWO_FILE_COMMANDLINE /* optional -- undef if you like Unix style */
+/* Note: if you undef TWO_FILE_COMMANDLINE, you may need to define
+ * USE_SETMODE. Some Atari compilers require it, some do not.
+ */
+#define NEED_SIGNAL_CATCHER /* needed if you use jmemname.c */
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.vc b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.vc
new file mode 100644
index 0000000..7e291c7
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.vc
@@ -0,0 +1,45 @@
+/* jconfig.vc --- jconfig.h for Microsoft Visual C++ on Windows 95 or NT. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS /* we presume a 32-bit flat memory model */
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+/* Define "boolean" as unsigned char, not int, per Windows custom */
+#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
+typedef unsigned char boolean;
+#endif
+#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
+
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#define TWO_FILE_COMMANDLINE /* optional */
+#define USE_SETMODE /* Microsoft has setmode() */
+#undef NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.vms b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.vms
new file mode 100644
index 0000000..55a6ffb
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.vms
@@ -0,0 +1,37 @@
+/* jconfig.vms --- jconfig.h for use on Digital VMS. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#undef CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#define TWO_FILE_COMMANDLINE /* Needed on VMS */
+#undef NEED_SIGNAL_CATCHER
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.wat b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.wat
new file mode 100644
index 0000000..6cc545b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jconfig.wat
@@ -0,0 +1,38 @@
+/* jconfig.wat --- jconfig.h for Watcom C/C++ on MS-DOS or OS/2. */
+/* see jconfig.doc for explanations */
+
+#define HAVE_PROTOTYPES
+#define HAVE_UNSIGNED_CHAR
+#define HAVE_UNSIGNED_SHORT
+/* #define void char */
+/* #define const */
+#define CHAR_IS_UNSIGNED
+#define HAVE_STDDEF_H
+#define HAVE_STDLIB_H
+#undef NEED_BSD_STRINGS
+#undef NEED_SYS_TYPES_H
+#undef NEED_FAR_POINTERS /* Watcom uses flat 32-bit addressing */
+#undef NEED_SHORT_EXTERNAL_NAMES
+#undef INCOMPLETE_TYPES_BROKEN
+
+#ifdef JPEG_INTERNALS
+
+#undef RIGHT_SHIFT_IS_UNSIGNED
+
+#endif /* JPEG_INTERNALS */
+
+#ifdef JPEG_CJPEG_DJPEG
+
+#define BMP_SUPPORTED /* BMP image file format */
+#define GIF_SUPPORTED /* GIF image file format */
+#define PPM_SUPPORTED /* PBMPLUS PPM/PGM image file format */
+#undef RLE_SUPPORTED /* Utah RLE image file format */
+#define TARGA_SUPPORTED /* Targa image file format */
+
+#undef TWO_FILE_COMMANDLINE /* optional */
+#define USE_SETMODE /* Needed to make one-file style work in Watcom */
+#undef NEED_SIGNAL_CATCHER /* Define this if you use jmemname.c */
+#undef DONT_USE_B_MODE
+#undef PROGRESS_REPORT /* optional */
+
+#endif /* JPEG_CJPEG_DJPEG */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcparam.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcparam.c
new file mode 100644
index 0000000..d5279f7
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcparam.c
@@ -0,0 +1,610 @@
+/*
+ * jcparam.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains optional default-setting code for the JPEG compressor.
+ * Applications do not have to use this file, but those that don't use it
+ * must know a lot more about the innards of the JPEG code.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Quantization table setup routines
+ */
+
+GLOBAL(void)
+jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
+ const unsigned int *basic_table,
+ int scale_factor, boolean force_baseline)
+/* Define a quantization table equal to the basic_table times
+ * a scale factor (given as a percentage).
+ * If force_baseline is TRUE, the computed quantization table entries
+ * are limited to 1..255 for JPEG baseline compatibility.
+ */
+{
+ JTQUANT_TBL ** qtblptr;
+ int i;
+ long temp;
+
+ /* Safety check to ensure start_compress not called yet. */
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ if (which_tbl < 0 || which_tbl >= NUM_TQUANT_TBLS)
+ ERREXIT1(cinfo, JERR_DTQT_INDEX, which_tbl);
+
+ qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
+
+ if (*qtblptr == NULL)
+ *qtblptr = jpeg_alloc_quant_table((j_common_ptr) cinfo);
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
+ /* limit the values to the valid range */
+ if (temp <= 0L) temp = 1L;
+ if (temp > 32767L) temp = 32767L; /* max quantizer needed for 12 bits */
+ if (force_baseline && temp > 255L)
+ temp = 255L; /* limit to baseline range if requested */
+ (*qtblptr)->quantval[i] = (UINT16) temp;
+ }
+
+ /* Initialize sent_table FALSE so table will be written to JPEG file. */
+ (*qtblptr)->sent_table = FALSE;
+}
+
+
+GLOBAL(void)
+jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
+ boolean force_baseline)
+/* Set or change the 'quality' (quantization) setting, using default tables
+ * and a straight percentage-scaling quality scale. In most cases it's better
+ * to use jpeg_set_quality (below); this entry point is provided for
+ * applications that insist on a linear percentage scaling.
+ */
+{
+ /* These are the sample quantization tables given in JPEG spec section K.1.
+ * The spec says that the values given produce "good" quality, and
+ * when divided by 2, "very good" quality.
+ */
+ static const unsigned int std_luminance_quant_tbl[DCTSIZE2] = {
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68, 109, 103, 77,
+ 24, 35, 55, 64, 81, 104, 113, 92,
+ 49, 64, 78, 87, 103, 121, 120, 101,
+ 72, 92, 95, 98, 112, 100, 103, 99
+ };
+ static const unsigned int std_chrominance_quant_tbl[DCTSIZE2] = {
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 66, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99
+ };
+
+ /* Set up two quantization tables using the specified scaling */
+ jpeg_add_quant_table(cinfo, 0, std_luminance_quant_tbl,
+ scale_factor, force_baseline);
+ jpeg_add_quant_table(cinfo, 1, std_chrominance_quant_tbl,
+ scale_factor, force_baseline);
+}
+
+
+GLOBAL(int)
+jpeg_quality_scaling (int quality)
+/* Convert a user-specified quality rating to a percentage scaling factor
+ * for an underlying quantization table, using our recommended scaling curve.
+ * The input 'quality' factor should be 0 (terrible) to 100 (very good).
+ */
+{
+ /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */
+ if (quality <= 0) quality = 1;
+ if (quality > 100) quality = 100;
+
+ /* The basic table is used as-is (scaling 100) for a quality of 50.
+ * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
+ * note that at Q=100 the scaling is 0, which will cause jpeg_add_quant_table
+ * to make all the table entries 1 (hence, minimum quantization loss).
+ * Qualities 1..50 are converted to scaling percentage 5000/Q.
+ */
+ if (quality < 50)
+ quality = 5000 / quality;
+ else
+ quality = 200 - quality*2;
+
+ return quality;
+}
+
+
+GLOBAL(void)
+jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
+/* Set or change the 'quality' (quantization) setting, using default tables.
+ * This is the standard quality-adjusting entry point for typical user
+ * interfaces; only those who want detailed control over quantization tables
+ * would use the preceding three routines directly.
+ */
+{
+ /* Convert user 0-100 rating to percentage scaling */
+ quality = jpeg_quality_scaling(quality);
+
+ /* Set up standard quality tables */
+ jpeg_set_linear_quality(cinfo, quality, force_baseline);
+}
+
+
+/*
+ * Huffman table setup routines
+ */
+
+LOCAL(void)
+add_huff_table (j_compress_ptr cinfo,
+ JHUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
+/* Define a Huffman table */
+{
+ int nsymbols, len;
+
+ if (*htblptr == NULL)
+ *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+
+ /* Copy the number-of-symbols-of-each-code-length counts */
+ MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
+
+ /* Validate the counts. We do this here mainly so we can copy the right
+ * number of symbols from the val[] array, without risking marching off
+ * the end of memory. jchuff.c will do a more thorough test later.
+ */
+ nsymbols = 0;
+ for (len = 1; len <= 16; len++)
+ nsymbols += bits[len];
+ if (nsymbols < 1 || nsymbols > 256)
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+
+ MEMCOPY((*htblptr)->huffval, val, nsymbols * SIZEOF(UINT8));
+
+ /* Initialize sent_table FALSE so table will be written to JPEG file. */
+ (*htblptr)->sent_table = FALSE;
+}
+
+
+LOCAL(void)
+std_huff_tables (j_compress_ptr cinfo)
+/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
+/* IMPORTANT: these are only valid for 8-bit data precision! */
+{
+ static const UINT8 bits_dc_luminance[17] =
+ { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
+ static const UINT8 val_dc_luminance[] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+ static const UINT8 bits_dc_chrominance[17] =
+ { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+ static const UINT8 val_dc_chrominance[] =
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+
+ static const UINT8 bits_ac_luminance[17] =
+ { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
+ static const UINT8 val_ac_luminance[] =
+ { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+ 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+ 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+ 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+ 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+ 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+ 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+ 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+ 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+ 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+ 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+ 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+ 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+ 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+ 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+ 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+ 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa };
+
+ static const UINT8 bits_ac_chrominance[17] =
+ { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
+ static const UINT8 val_ac_chrominance[] =
+ { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
+ 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
+ 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
+ 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
+ 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
+ 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
+ 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
+ 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
+ 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
+ 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
+ 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
+ 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
+ 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+ 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
+ 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
+ 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+ 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+ 0xf9, 0xfa };
+
+ add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
+ bits_dc_luminance, val_dc_luminance);
+ add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
+ bits_ac_luminance, val_ac_luminance);
+ add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
+ bits_dc_chrominance, val_dc_chrominance);
+ add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
+ bits_ac_chrominance, val_ac_chrominance);
+}
+
+
+/*
+ * Default parameter setup for compression.
+ *
+ * Applications that don't choose to use this routine must do their
+ * own setup of all these parameters. Alternately, you can call this
+ * to establish defaults and then alter parameters selectively. This
+ * is the recommended approach since, if we add any new parameters,
+ * your code will still work (they'll be set to reasonable defaults).
+ */
+
+GLOBAL(void)
+jpeg_set_defaults (j_compress_ptr cinfo)
+{
+ int i;
+
+ /* Safety check to ensure start_compress not called yet. */
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ /* Allocate comp_info array large enough for maximum component count.
+ * Array is made permanent in case application wants to compress
+ * multiple images at same param settings.
+ */
+ if (cinfo->comp_info == NULL)
+ cinfo->comp_info = (jpeg_component_info *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ MAX_COMPONENTS * SIZEOF(jpeg_component_info));
+
+ /* Initialize everything not dependent on the color space */
+
+ cinfo->data_precision = BITS_IN_JSAMPLE;
+ /* Set up two quantization tables using default quality of 75 */
+ jpeg_set_quality(cinfo, 75, TRUE);
+ /* Set up two Huffman tables */
+ std_huff_tables(cinfo);
+
+ /* Initialize default arithmetic coding conditioning */
+ for (i = 0; i < NUM_ARITH_TBLS; i++) {
+ cinfo->arith_dc_L[i] = 0;
+ cinfo->arith_dc_U[i] = 1;
+ cinfo->arith_ac_K[i] = 5;
+ }
+
+ /* Default is no multiple-scan output */
+ cinfo->scan_info = NULL;
+ cinfo->num_scans = 0;
+
+ /* Expect normal source image, not raw downsampled data */
+ cinfo->raw_data_in = FALSE;
+
+ /* Use Huffman coding, not arithmetic coding, by default */
+ cinfo->arith_code = FALSE;
+
+ /* By default, don't do extra passes to optimize entropy coding */
+ cinfo->optimize_coding = FALSE;
+ /* The standard Huffman tables are only valid for 8-bit data precision.
+ * If the precision is higher, force optimization on so that usable
+ * tables will be computed. This test can be removed if default tables
+ * are supplied that are valid for the desired precision.
+ */
+ if (cinfo->data_precision > 8)
+ cinfo->optimize_coding = TRUE;
+
+ /* By default, use the simpler non-cosited sampling tqalignment */
+ cinfo->CCIR601_sampling = FALSE;
+
+ /* No input smoothing */
+ cinfo->smoothing_factor = 0;
+
+ /* DCT algorithm preference */
+ cinfo->dct_method = JDCT_DEFAULT;
+
+ /* No restart markers */
+ cinfo->restart_interval = 0;
+ cinfo->restart_in_rows = 0;
+
+ /* Fill in default JFIF marker parameters. Note that whether the marker
+ * will actually be written is determined by jpeg_set_colorspace.
+ *
+ * By default, the library emits JFIF version code 1.01.
+ * An application that wants to emit JFIF 1.02 extension markers should set
+ * JFIF_minor_version to 2. We could probably get away with just defaulting
+ * to 1.02, but there may still be some decoders in use that will complain
+ * about that; saying 1.01 should minimize compatibility problems.
+ */
+ cinfo->JFIF_major_version = 1; /* Default JFIF version = 1.01 */
+ cinfo->JFIF_minor_version = 1;
+ cinfo->density_unit = 0; /* Pixel size is unknown by default */
+ cinfo->X_density = 1; /* Pixel aspect ratio is square by default */
+ cinfo->Y_density = 1;
+
+ /* Choose JPEG colorspace based on input space, set defaults accordingly */
+
+ jpeg_default_colorspace(cinfo);
+}
+
+
+/*
+ * Select an appropriate JPEG colorspace for in_color_space.
+ */
+
+GLOBAL(void)
+jpeg_default_colorspace (j_compress_ptr cinfo)
+{
+ switch (cinfo->in_color_space) {
+ case JCS_GRAYSCALE:
+ jpeg_set_colorspace(cinfo, JCS_GRAYSCALE);
+ break;
+ case JCS_RGB:
+ jpeg_set_colorspace(cinfo, JCS_YCbCr);
+ break;
+ case JCS_YCbCr:
+ jpeg_set_colorspace(cinfo, JCS_YCbCr);
+ break;
+ case JCS_CMYK:
+ jpeg_set_colorspace(cinfo, JCS_CMYK); /* By default, no translation */
+ break;
+ case JCS_YCCK:
+ jpeg_set_colorspace(cinfo, JCS_YCCK);
+ break;
+ case JCS_UNKNOWN:
+ jpeg_set_colorspace(cinfo, JCS_UNKNOWN);
+ break;
+ default:
+ ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);
+ }
+}
+
+
+/*
+ * Set the JPEG colorspace, and choose colorspace-dependent default values.
+ */
+
+GLOBAL(void)
+jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
+{
+ jpeg_component_info * compptr;
+ int ci;
+
+#define SET_COMP(index,id,hsamp,vsamp,quant,dctbl,actbl) \
+ (compptr = &cinfo->comp_info[index], \
+ compptr->component_id = (id), \
+ compptr->h_samp_factor = (hsamp), \
+ compptr->v_samp_factor = (vsamp), \
+ compptr->quant_tbl_no = (quant), \
+ compptr->dc_tbl_no = (dctbl), \
+ compptr->ac_tbl_no = (actbl) )
+
+ /* Safety check to ensure start_compress not called yet. */
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ /* For all colorspaces, we use Q and Huff tables 0 for luminance components,
+ * tables 1 for chrominance components.
+ */
+
+ cinfo->jpeg_color_space = colorspace;
+
+ cinfo->write_JFIF_header = FALSE; /* No marker for non-JFIF colorspaces */
+ cinfo->write_Adobe_marker = FALSE; /* write no Adobe marker by default */
+
+ switch (colorspace) {
+ case JCS_GRAYSCALE:
+ cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
+ cinfo->num_components = 1;
+ /* JFIF specifies component ID 1 */
+ SET_COMP(0, 1, 1,1, 0, 0,0);
+ break;
+ case JCS_RGB:
+ cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag RGB */
+ cinfo->num_components = 3;
+ SET_COMP(0, 0x52 /* 'R' */, 1,1, 0, 0,0);
+ SET_COMP(1, 0x47 /* 'G' */, 1,1, 0, 0,0);
+ SET_COMP(2, 0x42 /* 'B' */, 1,1, 0, 0,0);
+ break;
+ case JCS_YCbCr:
+ cinfo->write_JFIF_header = TRUE; /* Write a JFIF marker */
+ cinfo->num_components = 3;
+ /* JFIF specifies component IDs 1,2,3 */
+ /* We default to 2x2 subsamples of chrominance */
+ SET_COMP(0, 1, 2,2, 0, 0,0);
+ SET_COMP(1, 2, 1,1, 1, 1,1);
+ SET_COMP(2, 3, 1,1, 1, 1,1);
+ break;
+ case JCS_CMYK:
+ cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag CMYK */
+ cinfo->num_components = 4;
+ SET_COMP(0, 0x43 /* 'C' */, 1,1, 0, 0,0);
+ SET_COMP(1, 0x4D /* 'M' */, 1,1, 0, 0,0);
+ SET_COMP(2, 0x59 /* 'Y' */, 1,1, 0, 0,0);
+ SET_COMP(3, 0x4B /* 'K' */, 1,1, 0, 0,0);
+ break;
+ case JCS_YCCK:
+ cinfo->write_Adobe_marker = TRUE; /* write Adobe marker to flag YCCK */
+ cinfo->num_components = 4;
+ SET_COMP(0, 1, 2,2, 0, 0,0);
+ SET_COMP(1, 2, 1,1, 1, 1,1);
+ SET_COMP(2, 3, 1,1, 1, 1,1);
+ SET_COMP(3, 4, 2,2, 0, 0,0);
+ break;
+ case JCS_UNKNOWN:
+ cinfo->num_components = cinfo->input_components;
+ if (cinfo->num_components < 1 || cinfo->num_components > MAX_COMPONENTS)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+ MAX_COMPONENTS);
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ SET_COMP(ci, ci, 1,1, 0, 0,0);
+ }
+ break;
+ default:
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ }
+}
+
+
+#ifdef C_PROGRESSIVE_SUPPORTED
+
+LOCAL(jpeg_scan_info *)
+fill_a_scan (jpeg_scan_info * scanptr, int ci,
+ int Ss, int Se, int Ah, int Al)
+/* Support routine: generate one scan for specified component */
+{
+ scanptr->comps_in_scan = 1;
+ scanptr->component_index[0] = ci;
+ scanptr->Ss = Ss;
+ scanptr->Se = Se;
+ scanptr->Ah = Ah;
+ scanptr->Al = Al;
+ scanptr++;
+ return scanptr;
+}
+
+LOCAL(jpeg_scan_info *)
+fill_scans (jpeg_scan_info * scanptr, int ncomps,
+ int Ss, int Se, int Ah, int Al)
+/* Support routine: generate one scan for each component */
+{
+ int ci;
+
+ for (ci = 0; ci < ncomps; ci++) {
+ scanptr->comps_in_scan = 1;
+ scanptr->component_index[0] = ci;
+ scanptr->Ss = Ss;
+ scanptr->Se = Se;
+ scanptr->Ah = Ah;
+ scanptr->Al = Al;
+ scanptr++;
+ }
+ return scanptr;
+}
+
+LOCAL(jpeg_scan_info *)
+fill_dc_scans (jpeg_scan_info * scanptr, int ncomps, int Ah, int Al)
+/* Support routine: generate interleaved DC scan if possible, else N scans */
+{
+ int ci;
+
+ if (ncomps <= MAX_COMPS_IN_SCAN) {
+ /* Single interleaved DC scan */
+ scanptr->comps_in_scan = ncomps;
+ for (ci = 0; ci < ncomps; ci++)
+ scanptr->component_index[ci] = ci;
+ scanptr->Ss = scanptr->Se = 0;
+ scanptr->Ah = Ah;
+ scanptr->Al = Al;
+ scanptr++;
+ } else {
+ /* Noninterleaved DC scan for each component */
+ scanptr = fill_scans(scanptr, ncomps, 0, 0, Ah, Al);
+ }
+ return scanptr;
+}
+
+
+/*
+ * Create a recommended progressive-JPEG script.
+ * cinfo->num_components and cinfo->jpeg_color_space must be correct.
+ */
+
+GLOBAL(void)
+jpeg_simple_progression (j_compress_ptr cinfo)
+{
+ int ncomps = cinfo->num_components;
+ int nscans;
+ jpeg_scan_info * scanptr;
+
+ /* Safety check to ensure start_compress not called yet. */
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ /* Figure space needed for script. Calculation must match code below! */
+ if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
+ /* Custom script for YCbCr color images. */
+ nscans = 10;
+ } else {
+ /* All-purpose script for other color spaces. */
+ if (ncomps > MAX_COMPS_IN_SCAN)
+ nscans = 6 * ncomps; /* 2 DC + 4 AC scans per component */
+ else
+ nscans = 2 + 4 * ncomps; /* 2 DC scans; 4 AC scans per component */
+ }
+
+ /* Allocate space for script.
+ * We need to put it in the permanent pool in case the application performs
+ * multiple compressions without changing the settings. To avoid a memory
+ * leak if jpeg_simple_progression is called repeatedly for the same JPEG
+ * object, we try to re-use previously allocated space, and we allocate
+ * enough space to handle YCbCr even if initially asked for grayscale.
+ */
+ if (cinfo->script_space == NULL || cinfo->script_space_size < nscans) {
+ cinfo->script_space_size = MAX(nscans, 10);
+ cinfo->script_space = (jpeg_scan_info *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ cinfo->script_space_size * SIZEOF(jpeg_scan_info));
+ }
+ scanptr = cinfo->script_space;
+ cinfo->scan_info = scanptr;
+ cinfo->num_scans = nscans;
+
+ if (ncomps == 3 && cinfo->jpeg_color_space == JCS_YCbCr) {
+ /* Custom script for YCbCr color images. */
+ /* Initial DC scan */
+ scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
+ /* Initial AC scan: get some luma data out in a hurry */
+ scanptr = fill_a_scan(scanptr, 0, 1, 5, 0, 2);
+ /* Chroma data is too small to be worth expending many scans on */
+ scanptr = fill_a_scan(scanptr, 2, 1, 63, 0, 1);
+ scanptr = fill_a_scan(scanptr, 1, 1, 63, 0, 1);
+ /* Complete spectral selection for luma AC */
+ scanptr = fill_a_scan(scanptr, 0, 6, 63, 0, 2);
+ /* Refine next bit of luma AC */
+ scanptr = fill_a_scan(scanptr, 0, 1, 63, 2, 1);
+ /* Finish DC successive approximation */
+ scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
+ /* Finish AC successive approximation */
+ scanptr = fill_a_scan(scanptr, 2, 1, 63, 1, 0);
+ scanptr = fill_a_scan(scanptr, 1, 1, 63, 1, 0);
+ /* Luma bottom bit comes last since it's usually largest scan */
+ scanptr = fill_a_scan(scanptr, 0, 1, 63, 1, 0);
+ } else {
+ /* All-purpose script for other color spaces. */
+ /* Successive approximation first pass */
+ scanptr = fill_dc_scans(scanptr, ncomps, 0, 1);
+ scanptr = fill_scans(scanptr, ncomps, 1, 5, 0, 2);
+ scanptr = fill_scans(scanptr, ncomps, 6, 63, 0, 2);
+ /* Successive approximation second pass */
+ scanptr = fill_scans(scanptr, ncomps, 1, 63, 2, 1);
+ /* Successive approximation final pass */
+ scanptr = fill_dc_scans(scanptr, ncomps, 1, 0);
+ scanptr = fill_scans(scanptr, ncomps, 1, 63, 1, 0);
+ }
+}
+
+#endif /* C_PROGRESSIVE_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcphuff.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcphuff.c
new file mode 100644
index 0000000..efcf7f2
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcphuff.c
@@ -0,0 +1,833 @@
+/*
+ * jcphuff.c
+ *
+ * Copyright (C) 1995-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains Huffman entropy encoding routines for progressive JPEG.
+ *
+ * We do not support output suspension in this module, since the library
+ * currently does not allow multiple-scan files to be written with output
+ * suspension.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jchuff.h" /* Declarations shared with jchuff.c */
+
+#ifdef C_PROGRESSIVE_SUPPORTED
+
+/* Expanded entropy encoder object for progressive Huffman encoding. */
+
+typedef struct {
+ struct jpeg_entropy_encoder pub; /* public fields */
+
+ /* Mode flag: TRUE for optimization, FALSE for actual data output */
+ boolean gather_statistics;
+
+ /* Bit-level coding status.
+ * next_output_byte/free_in_buffer are local copies of cinfo->dest fields.
+ */
+ JOCTET * next_output_byte; /* => next byte to write in buffer */
+ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
+ INT32 put_buffer; /* current bit-accumulation buffer */
+ int put_bits; /* # of bits now in it */
+ j_compress_ptr cinfo; /* link to cinfo (needed for dump_buffer) */
+
+ /* Coding status for DC components */
+ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+
+ /* Coding status for AC components */
+ int ac_tbl_no; /* the table number of the single component */
+ unsigned int EOBRUN; /* run length of EOBs */
+ unsigned int BE; /* # of buffered correction bits before MCU */
+ char * bit_buffer; /* buffer for correction bits (1 per char) */
+ /* packing correction bits tightly would save some space but cost time... */
+
+ unsigned int restarts_to_go; /* MCUs left in this restart interval */
+ int next_restart_num; /* next restart number to write (0-7) */
+
+ /* Pointers to derived tables (these workspaces have image lifespan).
+ * Since any one scan codes only DC or only AC, we only need one set
+ * of tables, not one for DC and one for AC.
+ */
+ c_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
+
+ /* Statistics tables for optimization; again, one set is enough */
+ long * count_ptrs[NUM_HUFF_TBLS];
+} phuff_entropy_encoder;
+
+typedef phuff_entropy_encoder * phuff_entropy_ptr;
+
+/* MAX_CORR_BITS is the number of bits the AC refinement correction-bit
+ * buffer can hold. Larger sizes may slightly improve compression, but
+ * 1000 is already well into the realm of overkill.
+ * The minimum safe size is 64 bits.
+ */
+
+#define MAX_CORR_BITS 1000 /* Max # of correction bits I can buffer */
+
+/* IRIGHT_SHIFT is like RIGHT_SHIFT, but works on int rather than INT32.
+ * We assume that int right shift is unsigned if INT32 right shift is,
+ * which should be safe.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define ISHIFT_TEMPS int ishift_temp;
+#define IRIGHT_SHIFT(x,shft) \
+ ((ishift_temp = (x)) < 0 ? \
+ (ishift_temp >> (shft)) | ((~0) << (16-(shft))) : \
+ (ishift_temp >> (shft)))
+#else
+#define ISHIFT_TEMPS
+#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
+#endif
+
+/* Forward declarations */
+METHODDEF(boolean) encode_mcu_DC_first JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) encode_mcu_AC_first JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) encode_mcu_DC_refine JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) encode_mcu_AC_refine JPP((j_compress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(void) finish_pass_phuff JPP((j_compress_ptr cinfo));
+METHODDEF(void) finish_pass_gather_phuff JPP((j_compress_ptr cinfo));
+
+
+/*
+ * Initialize for a Huffman-compressed scan using progressive JPEG.
+ */
+
+METHODDEF(void)
+start_pass_phuff (j_compress_ptr cinfo, boolean gather_statistics)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ boolean is_DC_band;
+ int ci, tbl;
+ jpeg_component_info * compptr;
+
+ entropy->cinfo = cinfo;
+ entropy->gather_statistics = gather_statistics;
+
+ is_DC_band = (cinfo->Ss == 0);
+
+ /* We assume jcmaster.c already validated the scan parameters. */
+
+ /* Select execution routines */
+ if (cinfo->Ah == 0) {
+ if (is_DC_band)
+ entropy->pub.encode_mcu = encode_mcu_DC_first;
+ else
+ entropy->pub.encode_mcu = encode_mcu_AC_first;
+ } else {
+ if (is_DC_band)
+ entropy->pub.encode_mcu = encode_mcu_DC_refine;
+ else {
+ entropy->pub.encode_mcu = encode_mcu_AC_refine;
+ /* AC refinement needs a correction bit buffer */
+ if (entropy->bit_buffer == NULL)
+ entropy->bit_buffer = (char *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ MAX_CORR_BITS * SIZEOF(char));
+ }
+ }
+ if (gather_statistics)
+ entropy->pub.finish_pass = finish_pass_gather_phuff;
+ else
+ entropy->pub.finish_pass = finish_pass_phuff;
+
+ /* Only DC coefficients may be interleaved, so cinfo->comps_in_scan = 1
+ * for AC coefficients.
+ */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* Initialize DC predictions to 0 */
+ entropy->last_dc_val[ci] = 0;
+ /* Get table index */
+ if (is_DC_band) {
+ if (cinfo->Ah != 0) /* DC refinement needs no table */
+ continue;
+ tbl = compptr->dc_tbl_no;
+ } else {
+ entropy->ac_tbl_no = tbl = compptr->ac_tbl_no;
+ }
+ if (gather_statistics) {
+ /* Check for invalid table index */
+ /* (make_c_derived_tbl does this in the other path) */
+ if (tbl < 0 || tbl >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tbl);
+ /* Allocate and zero the statistics tables */
+ /* Note that jpeg_gen_optimal_table expects 257 entries in each table! */
+ if (entropy->count_ptrs[tbl] == NULL)
+ entropy->count_ptrs[tbl] = (long *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ 257 * SIZEOF(long));
+ MEMZERO(entropy->count_ptrs[tbl], 257 * SIZEOF(long));
+ } else {
+ /* Compute derived values for Huffman table */
+ /* We may do this more than once for a table, but it's not expensive */
+ jpeg_make_c_derived_tbl(cinfo, is_DC_band, tbl,
+ & entropy->derived_tbls[tbl]);
+ }
+ }
+
+ /* Initialize AC stuff */
+ entropy->EOBRUN = 0;
+ entropy->BE = 0;
+
+ /* Initialize bit buffer to empty */
+ entropy->put_buffer = 0;
+ entropy->put_bits = 0;
+
+ /* Initialize restart stuff */
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num = 0;
+}
+
+
+/* Outputting bytes to the file.
+ * NB: these must be called only when actually outputting,
+ * that is, entropy->gather_statistics == FALSE.
+ */
+
+/* Emit a byte */
+#define emit_byte(entropy,val) \
+ { *(entropy)->next_output_byte++ = (JOCTET) (val); \
+ if (--(entropy)->free_in_buffer == 0) \
+ dump_buffer(entropy); }
+
+
+LOCAL(void)
+dump_buffer (phuff_entropy_ptr entropy)
+/* Empty the output buffer; we do not support suspension in this module. */
+{
+ struct jpeg_destination_mgr * dest = entropy->cinfo->dest;
+
+ if (! (*dest->empty_output_buffer) (entropy->cinfo))
+ ERREXIT(entropy->cinfo, JERR_CANT_SUSPEND);
+ /* After a successful buffer dump, must reset buffer pointers */
+ entropy->next_output_byte = dest->next_output_byte;
+ entropy->free_in_buffer = dest->free_in_buffer;
+}
+
+
+/* Outputting bits to the file */
+
+/* Only the right 24 bits of put_buffer are used; the valid bits are
+ * left-justified in this part. At most 16 bits can be passed to emit_bits
+ * in one call, and we never retain more than 7 bits in put_buffer
+ * between calls, so 24 bits are sufficient.
+ */
+
+INLINE
+LOCAL(void)
+emit_bits (phuff_entropy_ptr entropy, unsigned int code, int size)
+/* Emit some bits, unless we are in gather mode */
+{
+ /* This routine is heavily used, so it's worth coding tightly. */
+ register INT32 put_buffer = (INT32) code;
+ register int put_bits = entropy->put_bits;
+
+ /* if size is 0, caller used an invalid Huffman table entry */
+ if (size == 0)
+ ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
+
+ if (entropy->gather_statistics)
+ return; /* do nothing if we're only getting stats */
+
+ put_buffer &= (((INT32) 1)<<size) - 1; /* tqmask off any extra bits in code */
+
+ put_bits += size; /* new number of bits in buffer */
+
+ put_buffer <<= 24 - put_bits; /* align incoming bits */
+
+ put_buffer |= entropy->put_buffer; /* and merge with old buffer contents */
+
+ while (put_bits >= 8) {
+ int c = (int) ((put_buffer >> 16) & 0xFF);
+
+ emit_byte(entropy, c);
+ if (c == 0xFF) { /* need to stuff a zero byte? */
+ emit_byte(entropy, 0);
+ }
+ put_buffer <<= 8;
+ put_bits -= 8;
+ }
+
+ entropy->put_buffer = put_buffer; /* update variables */
+ entropy->put_bits = put_bits;
+}
+
+
+LOCAL(void)
+flush_bits (phuff_entropy_ptr entropy)
+{
+ emit_bits(entropy, 0x7F, 7); /* fill any partial byte with ones */
+ entropy->put_buffer = 0; /* and reset bit-buffer to empty */
+ entropy->put_bits = 0;
+}
+
+
+/*
+ * Emit (or just count) a Huffman symbol.
+ */
+
+INLINE
+LOCAL(void)
+emit_symbol (phuff_entropy_ptr entropy, int tbl_no, int symbol)
+{
+ if (entropy->gather_statistics)
+ entropy->count_ptrs[tbl_no][symbol]++;
+ else {
+ c_derived_tbl * tbl = entropy->derived_tbls[tbl_no];
+ emit_bits(entropy, tbl->ehufco[symbol], tbl->ehufsi[symbol]);
+ }
+}
+
+
+/*
+ * Emit bits from a correction bit buffer.
+ */
+
+LOCAL(void)
+emit_buffered_bits (phuff_entropy_ptr entropy, char * bufstart,
+ unsigned int nbits)
+{
+ if (entropy->gather_statistics)
+ return; /* no real work */
+
+ while (nbits > 0) {
+ emit_bits(entropy, (unsigned int) (*bufstart), 1);
+ bufstart++;
+ nbits--;
+ }
+}
+
+
+/*
+ * Emit any pending EOBRUN symbol.
+ */
+
+LOCAL(void)
+emit_eobrun (phuff_entropy_ptr entropy)
+{
+ register int temp, nbits;
+
+ if (entropy->EOBRUN > 0) { /* if there is any pending EOBRUN */
+ temp = entropy->EOBRUN;
+ nbits = 0;
+ while ((temp >>= 1))
+ nbits++;
+ /* safety check: shouldn't happen given limited correction-bit buffer */
+ if (nbits > 14)
+ ERREXIT(entropy->cinfo, JERR_HUFF_MISSING_CODE);
+
+ emit_symbol(entropy, entropy->ac_tbl_no, nbits << 4);
+ if (nbits)
+ emit_bits(entropy, entropy->EOBRUN, nbits);
+
+ entropy->EOBRUN = 0;
+
+ /* Emit any buffered correction bits */
+ emit_buffered_bits(entropy, entropy->bit_buffer, entropy->BE);
+ entropy->BE = 0;
+ }
+}
+
+
+/*
+ * Emit a restart marker & resynchronize predictions.
+ */
+
+LOCAL(void)
+emit_restart (phuff_entropy_ptr entropy, int restart_num)
+{
+ int ci;
+
+ emit_eobrun(entropy);
+
+ if (! entropy->gather_statistics) {
+ flush_bits(entropy);
+ emit_byte(entropy, 0xFF);
+ emit_byte(entropy, JPEG_RST0 + restart_num);
+ }
+
+ if (entropy->cinfo->Ss == 0) {
+ /* Re-initialize DC predictions to 0 */
+ for (ci = 0; ci < entropy->cinfo->comps_in_scan; ci++)
+ entropy->last_dc_val[ci] = 0;
+ } else {
+ /* Re-initialize all AC-related fields to 0 */
+ entropy->EOBRUN = 0;
+ entropy->BE = 0;
+ }
+}
+
+
+/*
+ * MCU encoding for DC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+encode_mcu_DC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ register int temp, temp2;
+ register int nbits;
+ int blkn, ci;
+ int Al = cinfo->Al;
+ JBLOCKROW block;
+ jpeg_component_info * compptr;
+ ISHIFT_TEMPS
+
+ entropy->next_output_byte = cinfo->dest->next_output_byte;
+ entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval)
+ if (entropy->restarts_to_go == 0)
+ emit_restart(entropy, entropy->next_restart_num);
+
+ /* Encode the MCU data blocks */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+
+ /* Compute the DC value after the required point transform by Al.
+ * This is simply an arithmetic right shift.
+ */
+ temp2 = IRIGHT_SHIFT((int) ((*block)[0]), Al);
+
+ /* DC differences are figured on the point-transformed values. */
+ temp = temp2 - entropy->last_dc_val[ci];
+ entropy->last_dc_val[ci] = temp2;
+
+ /* Encode the DC coefficient difference per section G.1.2.1 */
+ temp2 = temp;
+ if (temp < 0) {
+ temp = -temp; /* temp is abs value of input */
+ /* For a negative input, want temp2 = bitwise complement of abs(input) */
+ /* This code assumes we are on a two's complement machine */
+ temp2--;
+ }
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = 0;
+ while (temp) {
+ nbits++;
+ temp >>= 1;
+ }
+ /* Check for out-of-range coefficient values.
+ * Since we're encoding a difference, the range limit is twice as much.
+ */
+ if (nbits > MAX_COEF_BITS+1)
+ ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+
+ /* Count/emit the Huffman-coded symbol for the number of bits */
+ emit_symbol(entropy, compptr->dc_tbl_no, nbits);
+
+ /* Emit that number of bits of the value, if positive, */
+ /* or the complement of its magnitude, if negative. */
+ if (nbits) /* emit_bits rejects calls with size 0 */
+ emit_bits(entropy, (unsigned int) temp2, nbits);
+ }
+
+ cinfo->dest->next_output_byte = entropy->next_output_byte;
+ cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+ /* Update restart-interval state too */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU encoding for AC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+encode_mcu_AC_first (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ register int temp, temp2;
+ register int nbits;
+ register int r, k;
+ int Se = cinfo->Se;
+ int Al = cinfo->Al;
+ JBLOCKROW block;
+
+ entropy->next_output_byte = cinfo->dest->next_output_byte;
+ entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval)
+ if (entropy->restarts_to_go == 0)
+ emit_restart(entropy, entropy->next_restart_num);
+
+ /* Encode the MCU data block */
+ block = MCU_data[0];
+
+ /* Encode the AC coefficients per section G.1.2.2, fig. G.3 */
+
+ r = 0; /* r = run length of zeros */
+
+ for (k = cinfo->Ss; k <= Se; k++) {
+ if ((temp = (*block)[jpeg_natural_order[k]]) == 0) {
+ r++;
+ continue;
+ }
+ /* We must apply the point transform by Al. For AC coefficients this
+ * is an integer division with rounding towards 0. To do this portably
+ * in C, we shift after obtaining the absolute value; so the code is
+ * interwoven with tqfinding the abs value (temp) and output bits (temp2).
+ */
+ if (temp < 0) {
+ temp = -temp; /* temp is abs value of input */
+ temp >>= Al; /* apply the point transform */
+ /* For a negative coef, want temp2 = bitwise complement of abs(coef) */
+ temp2 = ~temp;
+ } else {
+ temp >>= Al; /* apply the point transform */
+ temp2 = temp;
+ }
+ /* Watch out for case that nonzero coef is zero after point transform */
+ if (temp == 0) {
+ r++;
+ continue;
+ }
+
+ /* Emit any pending EOBRUN */
+ if (entropy->EOBRUN > 0)
+ emit_eobrun(entropy);
+ /* if run length > 15, must emit special run-length-16 codes (0xF0) */
+ while (r > 15) {
+ emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
+ r -= 16;
+ }
+
+ /* Find the number of bits needed for the magnitude of the coefficient */
+ nbits = 1; /* there must be at least one 1 bit */
+ while ((temp >>= 1))
+ nbits++;
+ /* Check for out-of-range coefficient values */
+ if (nbits > MAX_COEF_BITS)
+ ERREXIT(cinfo, JERR_BAD_DCT_COEF);
+
+ /* Count/emit Huffman symbol for run length / number of bits */
+ emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + nbits);
+
+ /* Emit that number of bits of the value, if positive, */
+ /* or the complement of its magnitude, if negative. */
+ emit_bits(entropy, (unsigned int) temp2, nbits);
+
+ r = 0; /* reset zero run length */
+ }
+
+ if (r > 0) { /* If there are trailing zeroes, */
+ entropy->EOBRUN++; /* count an EOB */
+ if (entropy->EOBRUN == 0x7FFF)
+ emit_eobrun(entropy); /* force it out to avoid overflow */
+ }
+
+ cinfo->dest->next_output_byte = entropy->next_output_byte;
+ cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+ /* Update restart-interval state too */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU encoding for DC successive approximation refinement scan.
+ * Note: we assume such scans can be multi-component, although the spec
+ * is not very clear on the point.
+ */
+
+METHODDEF(boolean)
+encode_mcu_DC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ register int temp;
+ int blkn;
+ int Al = cinfo->Al;
+ JBLOCKROW block;
+
+ entropy->next_output_byte = cinfo->dest->next_output_byte;
+ entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval)
+ if (entropy->restarts_to_go == 0)
+ emit_restart(entropy, entropy->next_restart_num);
+
+ /* Encode the MCU data blocks */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+
+ /* We simply emit the Al'th bit of the DC coefficient value. */
+ temp = (*block)[0];
+ emit_bits(entropy, (unsigned int) (temp >> Al), 1);
+ }
+
+ cinfo->dest->next_output_byte = entropy->next_output_byte;
+ cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+ /* Update restart-interval state too */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * MCU encoding for AC successive approximation refinement scan.
+ */
+
+METHODDEF(boolean)
+encode_mcu_AC_refine (j_compress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ register int temp;
+ register int r, k;
+ int EOB;
+ char *BR_buffer;
+ unsigned int BR;
+ int Se = cinfo->Se;
+ int Al = cinfo->Al;
+ JBLOCKROW block;
+ int absvalues[DCTSIZE2];
+
+ entropy->next_output_byte = cinfo->dest->next_output_byte;
+ entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+ /* Emit restart marker if needed */
+ if (cinfo->restart_interval)
+ if (entropy->restarts_to_go == 0)
+ emit_restart(entropy, entropy->next_restart_num);
+
+ /* Encode the MCU data block */
+ block = MCU_data[0];
+
+ /* It is convenient to make a pre-pass to determine the transformed
+ * coefficients' absolute values and the EOB position.
+ */
+ EOB = 0;
+ for (k = cinfo->Ss; k <= Se; k++) {
+ temp = (*block)[jpeg_natural_order[k]];
+ /* We must apply the point transform by Al. For AC coefficients this
+ * is an integer division with rounding towards 0. To do this portably
+ * in C, we shift after obtaining the absolute value.
+ */
+ if (temp < 0)
+ temp = -temp; /* temp is abs value of input */
+ temp >>= Al; /* apply the point transform */
+ absvalues[k] = temp; /* save abs value for main pass */
+ if (temp == 1)
+ EOB = k; /* EOB = index of last newly-nonzero coef */
+ }
+
+ /* Encode the AC coefficients per section G.1.2.3, fig. G.7 */
+
+ r = 0; /* r = run length of zeros */
+ BR = 0; /* BR = count of buffered bits added now */
+ BR_buffer = entropy->bit_buffer + entropy->BE; /* Append bits to buffer */
+
+ for (k = cinfo->Ss; k <= Se; k++) {
+ if ((temp = absvalues[k]) == 0) {
+ r++;
+ continue;
+ }
+
+ /* Emit any required ZRLs, but not if they can be folded into EOB */
+ while (r > 15 && k <= EOB) {
+ /* emit any pending EOBRUN and the BE correction bits */
+ emit_eobrun(entropy);
+ /* Emit ZRL */
+ emit_symbol(entropy, entropy->ac_tbl_no, 0xF0);
+ r -= 16;
+ /* Emit buffered correction bits that must be associated with ZRL */
+ emit_buffered_bits(entropy, BR_buffer, BR);
+ BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
+ BR = 0;
+ }
+
+ /* If the coef was previously nonzero, it only needs a correction bit.
+ * NOTE: a straight translation of the spec's figure G.7 would suggest
+ * that we also need to test r > 15. But if r > 15, we can only get here
+ * if k > EOB, which implies that this coefficient is not 1.
+ */
+ if (temp > 1) {
+ /* The correction bit is the next bit of the absolute value. */
+ BR_buffer[BR++] = (char) (temp & 1);
+ continue;
+ }
+
+ /* Emit any pending EOBRUN and the BE correction bits */
+ emit_eobrun(entropy);
+
+ /* Count/emit Huffman symbol for run length / number of bits */
+ emit_symbol(entropy, entropy->ac_tbl_no, (r << 4) + 1);
+
+ /* Emit output bit for newly-nonzero coef */
+ temp = ((*block)[jpeg_natural_order[k]] < 0) ? 0 : 1;
+ emit_bits(entropy, (unsigned int) temp, 1);
+
+ /* Emit buffered correction bits that must be associated with this code */
+ emit_buffered_bits(entropy, BR_buffer, BR);
+ BR_buffer = entropy->bit_buffer; /* BE bits are gone now */
+ BR = 0;
+ r = 0; /* reset zero run length */
+ }
+
+ if (r > 0 || BR > 0) { /* If there are trailing zeroes, */
+ entropy->EOBRUN++; /* count an EOB */
+ entropy->BE += BR; /* concat my correction bits to older ones */
+ /* We force out the EOB if we risk either:
+ * 1. overflow of the EOB counter;
+ * 2. overflow of the correction bit buffer during the next MCU.
+ */
+ if (entropy->EOBRUN == 0x7FFF || entropy->BE > (MAX_CORR_BITS-DCTSIZE2+1))
+ emit_eobrun(entropy);
+ }
+
+ cinfo->dest->next_output_byte = entropy->next_output_byte;
+ cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+
+ /* Update restart-interval state too */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0) {
+ entropy->restarts_to_go = cinfo->restart_interval;
+ entropy->next_restart_num++;
+ entropy->next_restart_num &= 7;
+ }
+ entropy->restarts_to_go--;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Finish up at the end of a Huffman-compressed progressive scan.
+ */
+
+METHODDEF(void)
+finish_pass_phuff (j_compress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+
+ entropy->next_output_byte = cinfo->dest->next_output_byte;
+ entropy->free_in_buffer = cinfo->dest->free_in_buffer;
+
+ /* Flush out any buffered data */
+ emit_eobrun(entropy);
+ flush_bits(entropy);
+
+ cinfo->dest->next_output_byte = entropy->next_output_byte;
+ cinfo->dest->free_in_buffer = entropy->free_in_buffer;
+}
+
+
+/*
+ * Finish up a statistics-gathering pass and create the new Huffman tables.
+ */
+
+METHODDEF(void)
+finish_pass_gather_phuff (j_compress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ boolean is_DC_band;
+ int ci, tbl;
+ jpeg_component_info * compptr;
+ JHUFF_TBL **htblptr;
+ boolean did[NUM_HUFF_TBLS];
+
+ /* Flush out buffered data (all we care about is counting the EOB symbol) */
+ emit_eobrun(entropy);
+
+ is_DC_band = (cinfo->Ss == 0);
+
+ /* It's important not to apply jpeg_gen_optimal_table more than once
+ * per table, because it clobbers the input frequency counts!
+ */
+ MEMZERO(did, SIZEOF(did));
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ if (is_DC_band) {
+ if (cinfo->Ah != 0) /* DC refinement needs no table */
+ continue;
+ tbl = compptr->dc_tbl_no;
+ } else {
+ tbl = compptr->ac_tbl_no;
+ }
+ if (! did[tbl]) {
+ if (is_DC_band)
+ htblptr = & cinfo->dc_huff_tbl_ptrs[tbl];
+ else
+ htblptr = & cinfo->ac_huff_tbl_ptrs[tbl];
+ if (*htblptr == NULL)
+ *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+ jpeg_gen_optimal_table(cinfo, *htblptr, entropy->count_ptrs[tbl]);
+ did[tbl] = TRUE;
+ }
+ }
+}
+
+
+/*
+ * Module initialization routine for progressive Huffman entropy encoding.
+ */
+
+GLOBAL(void)
+jinit_phuff_encoder (j_compress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy;
+ int i;
+
+ entropy = (phuff_entropy_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(phuff_entropy_encoder));
+ cinfo->entropy = (struct jpeg_entropy_encoder *) entropy;
+ entropy->pub.start_pass = start_pass_phuff;
+
+ /* Mark tables unallocated */
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ entropy->derived_tbls[i] = NULL;
+ entropy->count_ptrs[i] = NULL;
+ }
+ entropy->bit_buffer = NULL; /* needed only in AC refinement scan */
+}
+
+#endif /* C_PROGRESSIVE_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcprepct.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcprepct.c
new file mode 100644
index 0000000..37b551d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcprepct.c
@@ -0,0 +1,354 @@
+/*
+ * jcprepct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains the compression preprocessing controller.
+ * This controller manages the color conversion, downsampling,
+ * and edge expansion steps.
+ *
+ * Most of the complexity here is associated with buffering input rows
+ * as required by the downsampler. See the comments at the head of
+ * jcsample.c for the downsampler's needs.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* At present, jcsample.c can request context rows only for smoothing.
+ * In the future, we might also need context rows for CCIR601 sampling
+ * or other more-complex downsampling procedures. The code to support
+ * context rows should be compiled only if needed.
+ */
+#ifdef INPUT_SMOOTHING_SUPPORTED
+#define CONTEXT_ROWS_SUPPORTED
+#endif
+
+
+/*
+ * For the simple (no-context-row) case, we just need to buffer one
+ * row group's worth of pixels for the downsampling step. At the bottom of
+ * the image, we pad to a full row group by replicating the last pixel row.
+ * The downsampler's last output row is then replicated if needed to pad
+ * out to a full iMCU row.
+ *
+ * When providing context rows, we must buffer three row groups' worth of
+ * pixels. Three row groups are physically allocated, but the row pointer
+ * arrays are made five row groups high, with the extra pointers above and
+ * below "wrapping around" to point to the last and first real row groups.
+ * This allows the downsampler to access the proper context rows.
+ * At the top and bottom of the image, we create dummy context rows by
+ * copying the first or last real pixel row. This copying could be avoided
+ * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
+ * trouble on the compression side.
+ */
+
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_c_prep_controller pub; /* public fields */
+
+ /* Downsampling input buffer. This buffer holds color-converted data
+ * until we have enough to do a downsample step.
+ */
+ JSAMPARRAY color_buf[MAX_COMPONENTS];
+
+ JDIMENSION rows_to_go; /* counts rows remaining in source image */
+ int next_buf_row; /* index of next row to store in color_buf */
+
+#ifdef CONTEXT_ROWS_SUPPORTED /* only needed for context case */
+ int this_row_group; /* starting row index of group to process */
+ int next_buf_stop; /* downsample when we reach this index */
+#endif
+} my_prep_controller;
+
+typedef my_prep_controller * my_prep_ptr;
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+
+ if (pass_mode != JBUF_PASS_THRU)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+ /* Initialize total-height counter for detecting bottom of image */
+ prep->rows_to_go = cinfo->image_height;
+ /* Mark the conversion buffer empty */
+ prep->next_buf_row = 0;
+#ifdef CONTEXT_ROWS_SUPPORTED
+ /* Preset additional state variables for context mode.
+ * These aren't used in non-context mode, so we needn't test which mode.
+ */
+ prep->this_row_group = 0;
+ /* Set next_buf_stop to stop after two row groups have been read in. */
+ prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
+#endif
+}
+
+
+/*
+ * Expand an image vertically from height input_rows to height output_rows,
+ * by duplicating the bottom row.
+ */
+
+LOCAL(void)
+expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
+ int input_rows, int output_rows)
+{
+ register int row;
+
+ for (row = input_rows; row < output_rows; row++) {
+ jcopy_sample_rows(image_data, input_rows-1, image_data, row,
+ 1, num_cols);
+ }
+}
+
+
+/*
+ * Process some data in the simple no-context case.
+ *
+ * Preprocessor output data is counted in "row groups". A row group
+ * is defined to be v_samp_factor sample rows of each component.
+ * Downsampling will produce this much data from each max_v_samp_factor
+ * input rows.
+ */
+
+METHODDEF(void)
+pre_process_data (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail,
+ JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
+ JDIMENSION out_row_groups_avail)
+{
+ my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+ int numrows, ci;
+ JDIMENSION inrows;
+ jpeg_component_info * compptr;
+
+ while (*in_row_ctr < in_rows_avail &&
+ *out_row_group_ctr < out_row_groups_avail) {
+ /* Do color conversion to fill the conversion buffer. */
+ inrows = in_rows_avail - *in_row_ctr;
+ numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
+ numrows = (int) MIN((JDIMENSION) numrows, inrows);
+ (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
+ prep->color_buf,
+ (JDIMENSION) prep->next_buf_row,
+ numrows);
+ *in_row_ctr += numrows;
+ prep->next_buf_row += numrows;
+ prep->rows_to_go -= numrows;
+ /* If at bottom of image, pad to fill the conversion buffer. */
+ if (prep->rows_to_go == 0 &&
+ prep->next_buf_row < cinfo->max_v_samp_factor) {
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
+ prep->next_buf_row, cinfo->max_v_samp_factor);
+ }
+ prep->next_buf_row = cinfo->max_v_samp_factor;
+ }
+ /* If we've filled the conversion buffer, empty it. */
+ if (prep->next_buf_row == cinfo->max_v_samp_factor) {
+ (*cinfo->downsample->downsample) (cinfo,
+ prep->color_buf, (JDIMENSION) 0,
+ output_buf, *out_row_group_ctr);
+ prep->next_buf_row = 0;
+ (*out_row_group_ctr)++;
+ }
+ /* If at bottom of image, pad the output to a full iMCU height.
+ * Note we assume the caller is providing a one-iMCU-height output buffer!
+ */
+ if (prep->rows_to_go == 0 &&
+ *out_row_group_ctr < out_row_groups_avail) {
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ expand_bottom_edge(output_buf[ci],
+ compptr->width_in_blocks * DCTSIZE,
+ (int) (*out_row_group_ctr * compptr->v_samp_factor),
+ (int) (out_row_groups_avail * compptr->v_samp_factor));
+ }
+ *out_row_group_ctr = out_row_groups_avail;
+ break; /* can exit outer loop without test */
+ }
+ }
+}
+
+
+#ifdef CONTEXT_ROWS_SUPPORTED
+
+/*
+ * Process some data in the context case.
+ */
+
+METHODDEF(void)
+pre_process_context (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail,
+ JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
+ JDIMENSION out_row_groups_avail)
+{
+ my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+ int numrows, ci;
+ int buf_height = cinfo->max_v_samp_factor * 3;
+ JDIMENSION inrows;
+
+ while (*out_row_group_ctr < out_row_groups_avail) {
+ if (*in_row_ctr < in_rows_avail) {
+ /* Do color conversion to fill the conversion buffer. */
+ inrows = in_rows_avail - *in_row_ctr;
+ numrows = prep->next_buf_stop - prep->next_buf_row;
+ numrows = (int) MIN((JDIMENSION) numrows, inrows);
+ (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
+ prep->color_buf,
+ (JDIMENSION) prep->next_buf_row,
+ numrows);
+ /* Pad at top of image, if first time through */
+ if (prep->rows_to_go == cinfo->image_height) {
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ int row;
+ for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
+ jcopy_sample_rows(prep->color_buf[ci], 0,
+ prep->color_buf[ci], -row,
+ 1, cinfo->image_width);
+ }
+ }
+ }
+ *in_row_ctr += numrows;
+ prep->next_buf_row += numrows;
+ prep->rows_to_go -= numrows;
+ } else {
+ /* Return for more data, unless we are at the bottom of the image. */
+ if (prep->rows_to_go != 0)
+ break;
+ /* When at bottom of image, pad to fill the conversion buffer. */
+ if (prep->next_buf_row < prep->next_buf_stop) {
+ for (ci = 0; ci < cinfo->num_components; ci++) {
+ expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
+ prep->next_buf_row, prep->next_buf_stop);
+ }
+ prep->next_buf_row = prep->next_buf_stop;
+ }
+ }
+ /* If we've gotten enough data, downsample a row group. */
+ if (prep->next_buf_row == prep->next_buf_stop) {
+ (*cinfo->downsample->downsample) (cinfo,
+ prep->color_buf,
+ (JDIMENSION) prep->this_row_group,
+ output_buf, *out_row_group_ctr);
+ (*out_row_group_ctr)++;
+ /* Advance pointers with wraparound as necessary. */
+ prep->this_row_group += cinfo->max_v_samp_factor;
+ if (prep->this_row_group >= buf_height)
+ prep->this_row_group = 0;
+ if (prep->next_buf_row >= buf_height)
+ prep->next_buf_row = 0;
+ prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
+ }
+ }
+}
+
+
+/*
+ * Create the wrapped-around downsampling input buffer needed for context mode.
+ */
+
+LOCAL(void)
+create_context_buffer (j_compress_ptr cinfo)
+{
+ my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
+ int rgroup_height = cinfo->max_v_samp_factor;
+ int ci, i;
+ jpeg_component_info * compptr;
+ JSAMPARRAY true_buffer, fake_buffer;
+
+ /* Grab enough space for fake row pointers for all the components;
+ * we need five row groups' worth of pointers for each component.
+ */
+ fake_buffer = (JSAMPARRAY)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (cinfo->num_components * 5 * rgroup_height) *
+ SIZEOF(JSAMPROW));
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Allocate the actual buffer space (3 row groups) for this component.
+ * We make the buffer wide enough to allow the downsampler to edge-expand
+ * horizontally within the buffer, if it so chooses.
+ */
+ true_buffer = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
+ cinfo->max_h_samp_factor) / compptr->h_samp_factor),
+ (JDIMENSION) (3 * rgroup_height));
+ /* Copy true buffer row pointers into the middle of the fake row array */
+ MEMCOPY(fake_buffer + rgroup_height, true_buffer,
+ 3 * rgroup_height * SIZEOF(JSAMPROW));
+ /* Fill in the above and below wraparound pointers */
+ for (i = 0; i < rgroup_height; i++) {
+ fake_buffer[i] = true_buffer[2 * rgroup_height + i];
+ fake_buffer[4 * rgroup_height + i] = true_buffer[i];
+ }
+ prep->color_buf[ci] = fake_buffer + rgroup_height;
+ fake_buffer += 5 * rgroup_height; /* point to space for next component */
+ }
+}
+
+#endif /* CONTEXT_ROWS_SUPPORTED */
+
+
+/*
+ * Initialize preprocessing controller.
+ */
+
+GLOBAL(void)
+jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
+{
+ my_prep_ptr prep;
+ int ci;
+ jpeg_component_info * compptr;
+
+ if (need_full_buffer) /* safety check */
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+ prep = (my_prep_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_prep_controller));
+ cinfo->prep = (struct jpeg_c_prep_controller *) prep;
+ prep->pub.start_pass = start_pass_prep;
+
+ /* Allocate the color conversion buffer.
+ * We make the buffer wide enough to allow the downsampler to edge-expand
+ * horizontally within the buffer, if it so chooses.
+ */
+ if (cinfo->downsample->need_context_rows) {
+ /* Set up to provide context rows */
+#ifdef CONTEXT_ROWS_SUPPORTED
+ prep->pub.pre_process_data = pre_process_context;
+ create_context_buffer(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ /* No context, just make it tall enough for one row group */
+ prep->pub.pre_process_data = pre_process_data;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (JDIMENSION) (((long) compptr->width_in_blocks * DCTSIZE *
+ cinfo->max_h_samp_factor) / compptr->h_samp_factor),
+ (JDIMENSION) cinfo->max_v_samp_factor);
+ }
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jcsample.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jcsample.c
new file mode 100644
index 0000000..fe6e527
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jcsample.c
@@ -0,0 +1,519 @@
+/*
+ * jcsample.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains downsampling routines.
+ *
+ * Downsampling input data is counted in "row groups". A row group
+ * is defined to be max_v_samp_factor pixel rows of each component,
+ * from which the downsampler produces v_samp_factor sample rows.
+ * A single row group is processed in each call to the downsampler module.
+ *
+ * The downsampler is responsible for edge-expansion of its output data
+ * to fill an integral number of DCT blocks horizontally. The source buffer
+ * may be modified if it is helpful for this purpose (the source buffer is
+ * allocated wide enough to correspond to the desired output width).
+ * The caller (the prep controller) is responsible for vertical padding.
+ *
+ * The downsampler may request "context rows" by setting need_context_rows
+ * during startup. In this case, the input arrays will contain at least
+ * one row group's worth of pixels above and below the passed-in data;
+ * the caller will create dummy rows at image top and bottom by replicating
+ * the first or last real pixel row.
+ *
+ * An excellent reference for image resampling is
+ * Digital Image Warping, George Wolberg, 1990.
+ * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
+ *
+ * The downsampling algorithm used here is a simple average of the source
+ * pixels covered by the output pixel. The hi-falutin sampling literature
+ * refers to this as a "box filter". In general the characteristics of a box
+ * filter are not very good, but for the specific cases we normally use (1:1
+ * and 2:1 ratios) the box is equivalent to a "triangle filter" which is not
+ * nearly so bad. If you intend to use other sampling ratios, you'd be well
+ * advised to improve this code.
+ *
+ * A simple input-smoothing capability is provided. This is mainly intended
+ * for cleaning up color-dithered GIF input files (if you tqfind it inadequate,
+ * we suggest using an external filtering program such as pnmconvol). When
+ * enabled, each input pixel P is tqreplaced by a weighted sum of itself and its
+ * eight neighbors. P's weight is 1-8*SF and each neighbor's weight is SF,
+ * where SF = (smoothing_factor / 1024).
+ * Currently, smoothing is only supported for 2h2v sampling factors.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Pointer to routine to downsample a single component */
+typedef JTQT_METHOD(void, downsample1_ptr,
+ (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data));
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_downsampler pub; /* public fields */
+
+ /* Downsampling method pointers, one per component */
+ downsample1_ptr methods[MAX_COMPONENTS];
+} my_downsampler;
+
+typedef my_downsampler * my_downsample_ptr;
+
+
+/*
+ * Initialize for a downsampling pass.
+ */
+
+METHODDEF(void)
+start_pass_downsample (j_compress_ptr cinfo)
+{
+ /* no work for now */
+}
+
+
+/*
+ * Expand a component horizontally from width input_cols to width output_cols,
+ * by duplicating the rightmost samples.
+ */
+
+LOCAL(void)
+expand_right_edge (JSAMPARRAY image_data, int num_rows,
+ JDIMENSION input_cols, JDIMENSION output_cols)
+{
+ register JSAMPROW ptr;
+ register JSAMPLE pixval;
+ register int count;
+ int row;
+ int numcols = (int) (output_cols - input_cols);
+
+ if (numcols > 0) {
+ for (row = 0; row < num_rows; row++) {
+ ptr = image_data[row] + input_cols;
+ pixval = ptr[-1]; /* don't need GETJSAMPLE() here */
+ for (count = numcols; count > 0; count--)
+ *ptr++ = pixval;
+ }
+ }
+}
+
+
+/*
+ * Do downsampling for a whole row group (all components).
+ *
+ * In this version we simply downsample each component independently.
+ */
+
+METHODDEF(void)
+sep_downsample (j_compress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_index,
+ JSAMPIMAGE output_buf, JDIMENSION out_row_group_index)
+{
+ my_downsample_ptr downsample = (my_downsample_ptr) cinfo->downsample;
+ int ci;
+ jpeg_component_info * compptr;
+ JSAMPARRAY in_ptr, out_ptr;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ in_ptr = input_buf[ci] + in_row_index;
+ out_ptr = output_buf[ci] + (out_row_group_index * compptr->v_samp_factor);
+ (*downsample->methods[ci]) (cinfo, compptr, in_ptr, out_ptr);
+ }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * One row group is processed per call.
+ * This version handles arbitrary integral sampling ratios, without smoothing.
+ * Note that this version is not actually used for customary sampling ratios.
+ */
+
+METHODDEF(void)
+int_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ int inrow, outrow, h_expand, v_expand, numpix, numpix2, h, v;
+ JDIMENSION outcol, outcol_h; /* outcol_h == outcol*h_expand */
+ JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+ JSAMPROW inptr, outptr;
+ INT32 outvalue;
+
+ h_expand = cinfo->max_h_samp_factor / compptr->h_samp_factor;
+ v_expand = cinfo->max_v_samp_factor / compptr->v_samp_factor;
+ numpix = h_expand * v_expand;
+ numpix2 = numpix/2;
+
+ /* Expand input data enough to let all the output samples be generated
+ * by the standard loop. Special-casing padded output would be more
+ * efficient.
+ */
+ expand_right_edge(input_data, cinfo->max_v_samp_factor,
+ cinfo->image_width, output_cols * h_expand);
+
+ inrow = 0;
+ for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+ outptr = output_data[outrow];
+ for (outcol = 0, outcol_h = 0; outcol < output_cols;
+ outcol++, outcol_h += h_expand) {
+ outvalue = 0;
+ for (v = 0; v < v_expand; v++) {
+ inptr = input_data[inrow+v] + outcol_h;
+ for (h = 0; h < h_expand; h++) {
+ outvalue += (INT32) GETJSAMPLE(*inptr++);
+ }
+ }
+ *outptr++ = (JSAMPLE) ((outvalue + numpix2) / numpix);
+ }
+ inrow += v_expand;
+ }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the special case of a full-size component,
+ * without smoothing.
+ */
+
+METHODDEF(void)
+fullsize_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ /* Copy the data */
+ jcopy_sample_rows(input_data, 0, output_data, 0,
+ cinfo->max_v_samp_factor, cinfo->image_width);
+ /* Edge-expand */
+ expand_right_edge(output_data, cinfo->max_v_samp_factor,
+ cinfo->image_width, compptr->width_in_blocks * DCTSIZE);
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the common case of 2:1 horizontal and 1:1 vertical,
+ * without smoothing.
+ *
+ * A note about the "bias" calculations: when rounding fractional values to
+ * integer, we do not want to always round 0.5 up to the next integer.
+ * If we did that, we'd introduce a noticeable bias towards larger values.
+ * Instead, this code is arranged so that 0.5 will be rounded up or down at
+ * alternate pixel locations (a simple ordered dither pattern).
+ */
+
+METHODDEF(void)
+h2v1_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ int outrow;
+ JDIMENSION outcol;
+ JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+ register JSAMPROW inptr, outptr;
+ register int bias;
+
+ /* Expand input data enough to let all the output samples be generated
+ * by the standard loop. Special-casing padded output would be more
+ * efficient.
+ */
+ expand_right_edge(input_data, cinfo->max_v_samp_factor,
+ cinfo->image_width, output_cols * 2);
+
+ for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+ outptr = output_data[outrow];
+ inptr = input_data[outrow];
+ bias = 0; /* bias = 0,1,0,1,... for successive samples */
+ for (outcol = 0; outcol < output_cols; outcol++) {
+ *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr) + GETJSAMPLE(inptr[1])
+ + bias) >> 1);
+ bias ^= 1; /* 0=>1, 1=>0 */
+ inptr += 2;
+ }
+ }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
+ * without smoothing.
+ */
+
+METHODDEF(void)
+h2v2_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ int inrow, outrow;
+ JDIMENSION outcol;
+ JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+ register JSAMPROW inptr0, inptr1, outptr;
+ register int bias;
+
+ /* Expand input data enough to let all the output samples be generated
+ * by the standard loop. Special-casing padded output would be more
+ * efficient.
+ */
+ expand_right_edge(input_data, cinfo->max_v_samp_factor,
+ cinfo->image_width, output_cols * 2);
+
+ inrow = 0;
+ for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+ outptr = output_data[outrow];
+ inptr0 = input_data[inrow];
+ inptr1 = input_data[inrow+1];
+ bias = 1; /* bias = 1,2,1,2,... for successive samples */
+ for (outcol = 0; outcol < output_cols; outcol++) {
+ *outptr++ = (JSAMPLE) ((GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+ GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1])
+ + bias) >> 2);
+ bias ^= 3; /* 1=>2, 2=>1 */
+ inptr0 += 2; inptr1 += 2;
+ }
+ inrow += 2;
+ }
+}
+
+
+#ifdef INPUT_SMOOTHING_SUPPORTED
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the standard case of 2:1 horizontal and 2:1 vertical,
+ * with smoothing. One row of context is required.
+ */
+
+METHODDEF(void)
+h2v2_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ int inrow, outrow;
+ JDIMENSION colctr;
+ JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+ register JSAMPROW inptr0, inptr1, above_ptr, below_ptr, outptr;
+ INT32 membersum, neighsum, memberscale, neighscale;
+
+ /* Expand input data enough to let all the output samples be generated
+ * by the standard loop. Special-casing padded output would be more
+ * efficient.
+ */
+ expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
+ cinfo->image_width, output_cols * 2);
+
+ /* We don't bother to form the individual "smoothed" input pixel values;
+ * we can directly compute the output which is the average of the four
+ * smoothed values. Each of the four member pixels contributes a fraction
+ * (1-8*SF) to its own smoothed image and a fraction SF to each of the three
+ * other smoothed pixels, therefore a total fraction (1-5*SF)/4 to the final
+ * output. The four corner-adjacent neighbor pixels contribute a fraction
+ * SF to just one smoothed pixel, or SF/4 to the final output; while the
+ * eight edge-adjacent neighbors contribute SF to each of two smoothed
+ * pixels, or SF/2 overall. In order to use integer arithmetic, these
+ * factors are scaled by 2^16 = 65536.
+ * Also recall that SF = smoothing_factor / 1024.
+ */
+
+ memberscale = 16384 - cinfo->smoothing_factor * 80; /* scaled (1-5*SF)/4 */
+ neighscale = cinfo->smoothing_factor * 16; /* scaled SF/4 */
+
+ inrow = 0;
+ for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+ outptr = output_data[outrow];
+ inptr0 = input_data[inrow];
+ inptr1 = input_data[inrow+1];
+ above_ptr = input_data[inrow-1];
+ below_ptr = input_data[inrow+2];
+
+ /* Special case for first column: pretend column -1 is same as column 0 */
+ membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+ GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
+ neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
+ GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
+ GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[2]) +
+ GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[2]);
+ neighsum += neighsum;
+ neighsum += GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[2]) +
+ GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[2]);
+ membersum = membersum * memberscale + neighsum * neighscale;
+ *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+ inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
+
+ for (colctr = output_cols - 2; colctr > 0; colctr--) {
+ /* sum of pixels directly mapped to this output element */
+ membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+ GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
+ /* sum of edge-neighbor pixels */
+ neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
+ GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
+ GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[2]) +
+ GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[2]);
+ /* The edge-neighbors count twice as much as corner-neighbors */
+ neighsum += neighsum;
+ /* Add in the corner-neighbors */
+ neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[2]) +
+ GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[2]);
+ /* form final output scaled up by 2^16 */
+ membersum = membersum * memberscale + neighsum * neighscale;
+ /* round, descale and output it */
+ *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+ inptr0 += 2; inptr1 += 2; above_ptr += 2; below_ptr += 2;
+ }
+
+ /* Special case for last column */
+ membersum = GETJSAMPLE(*inptr0) + GETJSAMPLE(inptr0[1]) +
+ GETJSAMPLE(*inptr1) + GETJSAMPLE(inptr1[1]);
+ neighsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(above_ptr[1]) +
+ GETJSAMPLE(*below_ptr) + GETJSAMPLE(below_ptr[1]) +
+ GETJSAMPLE(inptr0[-1]) + GETJSAMPLE(inptr0[1]) +
+ GETJSAMPLE(inptr1[-1]) + GETJSAMPLE(inptr1[1]);
+ neighsum += neighsum;
+ neighsum += GETJSAMPLE(above_ptr[-1]) + GETJSAMPLE(above_ptr[1]) +
+ GETJSAMPLE(below_ptr[-1]) + GETJSAMPLE(below_ptr[1]);
+ membersum = membersum * memberscale + neighsum * neighscale;
+ *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
+
+ inrow += 2;
+ }
+}
+
+
+/*
+ * Downsample pixel values of a single component.
+ * This version handles the special case of a full-size component,
+ * with smoothing. One row of context is required.
+ */
+
+METHODDEF(void)
+fullsize_smooth_downsample (j_compress_ptr cinfo, jpeg_component_info *compptr,
+ JSAMPARRAY input_data, JSAMPARRAY output_data)
+{
+ int outrow;
+ JDIMENSION colctr;
+ JDIMENSION output_cols = compptr->width_in_blocks * DCTSIZE;
+ register JSAMPROW inptr, above_ptr, below_ptr, outptr;
+ INT32 membersum, neighsum, memberscale, neighscale;
+ int colsum, lastcolsum, nextcolsum;
+
+ /* Expand input data enough to let all the output samples be generated
+ * by the standard loop. Special-casing padded output would be more
+ * efficient.
+ */
+ expand_right_edge(input_data - 1, cinfo->max_v_samp_factor + 2,
+ cinfo->image_width, output_cols);
+
+ /* Each of the eight neighbor pixels contributes a fraction SF to the
+ * smoothed pixel, while the main pixel contributes (1-8*SF). In order
+ * to use integer arithmetic, these factors are multiplied by 2^16 = 65536.
+ * Also recall that SF = smoothing_factor / 1024.
+ */
+
+ memberscale = 65536L - cinfo->smoothing_factor * 512L; /* scaled 1-8*SF */
+ neighscale = cinfo->smoothing_factor * 64; /* scaled SF */
+
+ for (outrow = 0; outrow < compptr->v_samp_factor; outrow++) {
+ outptr = output_data[outrow];
+ inptr = input_data[outrow];
+ above_ptr = input_data[outrow-1];
+ below_ptr = input_data[outrow+1];
+
+ /* Special case for first column */
+ colsum = GETJSAMPLE(*above_ptr++) + GETJSAMPLE(*below_ptr++) +
+ GETJSAMPLE(*inptr);
+ membersum = GETJSAMPLE(*inptr++);
+ nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
+ GETJSAMPLE(*inptr);
+ neighsum = colsum + (colsum - membersum) + nextcolsum;
+ membersum = membersum * memberscale + neighsum * neighscale;
+ *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+ lastcolsum = colsum; colsum = nextcolsum;
+
+ for (colctr = output_cols - 2; colctr > 0; colctr--) {
+ membersum = GETJSAMPLE(*inptr++);
+ above_ptr++; below_ptr++;
+ nextcolsum = GETJSAMPLE(*above_ptr) + GETJSAMPLE(*below_ptr) +
+ GETJSAMPLE(*inptr);
+ neighsum = lastcolsum + (colsum - membersum) + nextcolsum;
+ membersum = membersum * memberscale + neighsum * neighscale;
+ *outptr++ = (JSAMPLE) ((membersum + 32768) >> 16);
+ lastcolsum = colsum; colsum = nextcolsum;
+ }
+
+ /* Special case for last column */
+ membersum = GETJSAMPLE(*inptr);
+ neighsum = lastcolsum + (colsum - membersum) + colsum;
+ membersum = membersum * memberscale + neighsum * neighscale;
+ *outptr = (JSAMPLE) ((membersum + 32768) >> 16);
+
+ }
+}
+
+#endif /* INPUT_SMOOTHING_SUPPORTED */
+
+
+/*
+ * Module initialization routine for downsampling.
+ * Note that we must select a routine for each component.
+ */
+
+GLOBAL(void)
+jinit_downsampler (j_compress_ptr cinfo)
+{
+ my_downsample_ptr downsample;
+ int ci;
+ jpeg_component_info * compptr;
+ boolean smoothok = TRUE;
+
+ downsample = (my_downsample_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_downsampler));
+ cinfo->downsample = (struct jpeg_downsampler *) downsample;
+ downsample->pub.start_pass = start_pass_downsample;
+ downsample->pub.downsample = sep_downsample;
+ downsample->pub.need_context_rows = FALSE;
+
+ if (cinfo->CCIR601_sampling)
+ ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
+
+ /* Verify we can handle the sampling factors, and set up method pointers */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (compptr->h_samp_factor == cinfo->max_h_samp_factor &&
+ compptr->v_samp_factor == cinfo->max_v_samp_factor) {
+#ifdef INPUT_SMOOTHING_SUPPORTED
+ if (cinfo->smoothing_factor) {
+ downsample->methods[ci] = fullsize_smooth_downsample;
+ downsample->pub.need_context_rows = TRUE;
+ } else
+#endif
+ downsample->methods[ci] = fullsize_downsample;
+ } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
+ compptr->v_samp_factor == cinfo->max_v_samp_factor) {
+ smoothok = FALSE;
+ downsample->methods[ci] = h2v1_downsample;
+ } else if (compptr->h_samp_factor * 2 == cinfo->max_h_samp_factor &&
+ compptr->v_samp_factor * 2 == cinfo->max_v_samp_factor) {
+#ifdef INPUT_SMOOTHING_SUPPORTED
+ if (cinfo->smoothing_factor) {
+ downsample->methods[ci] = h2v2_smooth_downsample;
+ downsample->pub.need_context_rows = TRUE;
+ } else
+#endif
+ downsample->methods[ci] = h2v2_downsample;
+ } else if ((cinfo->max_h_samp_factor % compptr->h_samp_factor) == 0 &&
+ (cinfo->max_v_samp_factor % compptr->v_samp_factor) == 0) {
+ smoothok = FALSE;
+ downsample->methods[ci] = int_downsample;
+ } else
+ ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
+ }
+
+#ifdef INPUT_SMOOTHING_SUPPORTED
+ if (cinfo->smoothing_factor && !smoothok)
+ TRACEMS(cinfo, 0, JTRC_SMOOTH_NOTIMPL);
+#endif
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jctrans.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jctrans.c
new file mode 100644
index 0000000..f0ced25
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jctrans.c
@@ -0,0 +1,388 @@
+/*
+ * jctrans.c
+ *
+ * Copyright (C) 1995-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains library routines for transcoding compression,
+ * that is, writing raw DCT coefficient arrays to an output JPEG file.
+ * The routines in jcapimin.c will also be needed by a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Forward declarations */
+LOCAL(void) transencode_master_selection
+ JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
+LOCAL(void) transencode_coef_controller
+ JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
+
+
+/*
+ * Compression initialization for writing raw-coefficient data.
+ * Before calling this, all parameters and a data destination must be set up.
+ * Call jpeg_finish_compress() to actually write the data.
+ *
+ * The number of passed virtual arrays must match cinfo->num_components.
+ * Note that the virtual arrays need not be filled or even realized at
+ * the time write_coefficients is called; indeed, if the virtual arrays
+ * were requested from this compression object's memory manager, they
+ * typically will be realized during this routine and filled afterwards.
+ */
+
+GLOBAL(void)
+jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
+{
+ if (cinfo->global_state != CSTATE_START)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ /* Mark all tables to be written */
+ jpeg_suppress_tables(cinfo, FALSE);
+ /* (Re)initialize error mgr and destination modules */
+ (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+ (*cinfo->dest->init_destination) (cinfo);
+ /* Perform master selection of active modules */
+ transencode_master_selection(cinfo, coef_arrays);
+ /* Wait for jpeg_finish_compress() call */
+ cinfo->next_scanline = 0; /* so jpeg_write_marker works */
+ cinfo->global_state = CSTATE_WRCOEFS;
+}
+
+
+/*
+ * Initialize the compression object with default parameters,
+ * then copy from the source object all parameters needed for lossless
+ * transcoding. Parameters that can be varied without loss (such as
+ * scan script and Huffman optimization) are left in their default states.
+ */
+
+GLOBAL(void)
+jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
+ j_compress_ptr dstinfo)
+{
+ JTQUANT_TBL ** qtblptr;
+ jpeg_component_info *incomp, *outcomp;
+ JTQUANT_TBL *c_quant, *slot_quant;
+ int tblno, ci, coefi;
+
+ /* Safety check to ensure start_compress not called yet. */
+ if (dstinfo->global_state != CSTATE_START)
+ ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
+ /* Copy fundamental image dimensions */
+ dstinfo->image_width = srcinfo->image_width;
+ dstinfo->image_height = srcinfo->image_height;
+ dstinfo->input_components = srcinfo->num_components;
+ dstinfo->in_color_space = srcinfo->jpeg_color_space;
+ /* Initialize all parameters to default values */
+ jpeg_set_defaults(dstinfo);
+ /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
+ * Fix it to get the right header markers for the image colorspace.
+ */
+ jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
+ dstinfo->data_precision = srcinfo->data_precision;
+ dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
+ /* Copy the source's quantization tables. */
+ for (tblno = 0; tblno < NUM_TQUANT_TBLS; tblno++) {
+ if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
+ qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
+ if (*qtblptr == NULL)
+ *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
+ MEMCOPY((*qtblptr)->quantval,
+ srcinfo->quant_tbl_ptrs[tblno]->quantval,
+ SIZEOF((*qtblptr)->quantval));
+ (*qtblptr)->sent_table = FALSE;
+ }
+ }
+ /* Copy the source's per-component info.
+ * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
+ */
+ dstinfo->num_components = srcinfo->num_components;
+ if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
+ ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
+ MAX_COMPONENTS);
+ for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
+ ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
+ outcomp->component_id = incomp->component_id;
+ outcomp->h_samp_factor = incomp->h_samp_factor;
+ outcomp->v_samp_factor = incomp->v_samp_factor;
+ outcomp->quant_tbl_no = incomp->quant_tbl_no;
+ /* Make sure saved quantization table for component matches the qtable
+ * slot. If not, the input file re-used this qtable slot.
+ * IJG encoder currently cannot duplicate this.
+ */
+ tblno = outcomp->quant_tbl_no;
+ if (tblno < 0 || tblno >= NUM_TQUANT_TBLS ||
+ srcinfo->quant_tbl_ptrs[tblno] == NULL)
+ ERREXIT1(dstinfo, JERR_NO_TQUANT_TABLE, tblno);
+ slot_quant = srcinfo->quant_tbl_ptrs[tblno];
+ c_quant = incomp->quant_table;
+ if (c_quant != NULL) {
+ for (coefi = 0; coefi < DCTSIZE2; coefi++) {
+ if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
+ ERREXIT1(dstinfo, JERR_MISMATCHED_TQUANT_TABLE, tblno);
+ }
+ }
+ /* Note: we do not copy the source's Huffman table assignments;
+ * instead we rely on jpeg_set_colorspace to have made a suitable choice.
+ */
+ }
+ /* Also copy JFIF version and resolution information, if available.
+ * Strictly speaking this isn't "critical" info, but it's nearly
+ * always appropriate to copy it if available. In particular,
+ * if the application chooses to copy JFIF 1.02 extension markers from
+ * the source file, we need to copy the version to make sure we don't
+ * emit a file that has 1.02 extensions but a claimed version of 1.01.
+ * We will *not*, however, copy version info from mislabeled "2.01" files.
+ */
+ if (srcinfo->saw_JFIF_marker) {
+ if (srcinfo->JFIF_major_version == 1) {
+ dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
+ dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
+ }
+ dstinfo->density_unit = srcinfo->density_unit;
+ dstinfo->X_density = srcinfo->X_density;
+ dstinfo->Y_density = srcinfo->Y_density;
+ }
+}
+
+
+/*
+ * Master selection of compression modules for transcoding.
+ * This substitutes for jcinit.c's initialization of the full compressor.
+ */
+
+LOCAL(void)
+transencode_master_selection (j_compress_ptr cinfo,
+ jvirt_barray_ptr * coef_arrays)
+{
+ /* Although we don't actually use input_components for transcoding,
+ * jcmaster.c's initial_setup will complain if input_components is 0.
+ */
+ cinfo->input_components = 1;
+ /* Initialize master control (includes parameter checking/processing) */
+ jinit_c_master_control(cinfo, TRUE /* transcode only */);
+
+ /* Entropy encoding: either Huffman or arithmetic coding. */
+ if (cinfo->arith_code) {
+ ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+ } else {
+ if (cinfo->progressive_mode) {
+#ifdef C_PROGRESSIVE_SUPPORTED
+ jinit_phuff_encoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else
+ jinit_huff_encoder(cinfo);
+ }
+
+ /* We need a special coefficient buffer controller. */
+ transencode_coef_controller(cinfo, coef_arrays);
+
+ jinit_marker_writer(cinfo);
+
+ /* We can now tell the memory manager to allocate virtual arrays. */
+ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+ /* Write the datastream header (SOI, JFIF) immediately.
+ * Frame and scan headers are postponed till later.
+ * This lets application insert special markers after the SOI.
+ */
+ (*cinfo->marker->write_file_header) (cinfo);
+}
+
+
+/*
+ * The rest of this file is a special implementation of the coefficient
+ * buffer controller. This is similar to jccoefct.c, but it handles only
+ * output from presupplied virtual arrays. Furthermore, we generate any
+ * dummy padding blocks on-the-fly rather than expecting them to be present
+ * in the arrays.
+ */
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_c_coef_controller pub; /* public fields */
+
+ JDIMENSION iMCU_row_num; /* iMCU row # within image */
+ JDIMENSION mcu_ctr; /* counts MCUs processed in current row */
+ int MCU_vert_offset; /* counts MCU rows within iMCU row */
+ int MCU_rows_per_iMCU_row; /* number of such rows needed */
+
+ /* Virtual block array for each component. */
+ jvirt_barray_ptr * whole_image;
+
+ /* Workspace for constructing dummy blocks at right/bottom edges. */
+ JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
+} my_coef_controller;
+
+typedef my_coef_controller * my_coef_ptr;
+
+
+LOCAL(void)
+start_iMCU_row (j_compress_ptr cinfo)
+/* Reset within-iMCU-row counters for a new row */
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ /* In an interleaved scan, an MCU row is the same as an iMCU row.
+ * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
+ * But at the bottom of the image, process only what's left.
+ */
+ if (cinfo->comps_in_scan > 1) {
+ coef->MCU_rows_per_iMCU_row = 1;
+ } else {
+ if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
+ else
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
+ }
+
+ coef->mcu_ctr = 0;
+ coef->MCU_vert_offset = 0;
+}
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ if (pass_mode != JBUF_CRANK_DEST)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+ coef->iMCU_row_num = 0;
+ start_iMCU_row(cinfo);
+}
+
+
+/*
+ * Process some data.
+ * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
+ * per call, ie, v_samp_factor block rows for each component in the scan.
+ * The data is obtained from the virtual arrays and fed to the entropy coder.
+ * Returns TRUE if the iMCU row is completed, FALSE if suspended.
+ *
+ * NB: input_buf is ignored; it is likely to be a NULL pointer.
+ */
+
+METHODDEF(boolean)
+compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION MCU_col_num; /* index of current MCU within row */
+ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ int blkn, ci, xindex, yindex, yoffset, blockcnt;
+ JDIMENSION start_col;
+ JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
+ JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
+ JBLOCKROW buffer_ptr;
+ jpeg_component_info *compptr;
+
+ /* Align the virtual buffers for the components used in this scan. */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ buffer[ci] = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
+ coef->iMCU_row_num * compptr->v_samp_factor,
+ (JDIMENSION) compptr->v_samp_factor, FALSE);
+ }
+
+ /* Loop to process one whole iMCU row */
+ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+ yoffset++) {
+ for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
+ MCU_col_num++) {
+ /* Construct list of pointers to DCT blocks belonging to this MCU */
+ blkn = 0; /* index of current DCT block within MCU */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ start_col = MCU_col_num * compptr->MCU_width;
+ blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
+ : compptr->last_col_width;
+ for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+ if (coef->iMCU_row_num < last_iMCU_row ||
+ yindex+yoffset < compptr->last_row_height) {
+ /* Fill in pointers to real blocks in this row */
+ buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
+ for (xindex = 0; xindex < blockcnt; xindex++)
+ MCU_buffer[blkn++] = buffer_ptr++;
+ } else {
+ /* At bottom of image, need a whole row of dummy blocks */
+ xindex = 0;
+ }
+ /* Fill in any dummy blocks needed in this row.
+ * Dummy blocks are filled in the same way as in jccoefct.c:
+ * all zeroes in the AC entries, DC entries equal to previous
+ * block's DC value. The init routine has already zeroed the
+ * AC entries, so we need only set the DC entries correctly.
+ */
+ for (; xindex < compptr->MCU_width; xindex++) {
+ MCU_buffer[blkn] = coef->dummy_buffer[blkn];
+ MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
+ blkn++;
+ }
+ }
+ }
+ /* Try to write the MCU. */
+ if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
+ /* Suspension forced; update state counters and exit */
+ coef->MCU_vert_offset = yoffset;
+ coef->mcu_ctr = MCU_col_num;
+ return FALSE;
+ }
+ }
+ /* Completed an MCU row, but perhaps not an iMCU row */
+ coef->mcu_ctr = 0;
+ }
+ /* Completed the iMCU row, advance counters for next one */
+ coef->iMCU_row_num++;
+ start_iMCU_row(cinfo);
+ return TRUE;
+}
+
+
+/*
+ * Initialize coefficient buffer controller.
+ *
+ * Each passed coefficient array must be the right size for that
+ * coefficient: width_in_blocks wide and height_in_blocks high,
+ * with unitheight at least v_samp_factor.
+ */
+
+LOCAL(void)
+transencode_coef_controller (j_compress_ptr cinfo,
+ jvirt_barray_ptr * coef_arrays)
+{
+ my_coef_ptr coef;
+ JBLOCKROW buffer;
+ int i;
+
+ coef = (my_coef_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_coef_controller));
+ cinfo->coef = (struct jpeg_c_coef_controller *) coef;
+ coef->pub.start_pass = start_pass_coef;
+ coef->pub.compress_data = compress_output;
+
+ /* Save pointer to virtual arrays */
+ coef->whole_image = coef_arrays;
+
+ /* Allocate and pre-zero space for dummy DCT blocks. */
+ buffer = (JBLOCKROW)
+ (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+ jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+ for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
+ coef->dummy_buffer[i] = buffer + i;
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdapimin.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdapimin.c
new file mode 100644
index 0000000..d734c4c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdapimin.c
@@ -0,0 +1,395 @@
+/*
+ * jdapimin.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains application interface code for the decompression half
+ * of the JPEG library. These are the "minimum" API routines that may be
+ * needed in either the normal full-decompression case or the
+ * transcoding-only case.
+ *
+ * Most of the routines intended to be called directly by an application
+ * are in this file or in jdapistd.c. But also see jcomapi.c for routines
+ * shared by compression and decompression, and jdtrans.c for the transcoding
+ * case.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * Initialization of a JPEG decompression object.
+ * The error manager must already be set up (in case memory manager fails).
+ */
+
+GLOBAL(void)
+jpeg_CreateDecompress (j_decompress_ptr cinfo, int version, size_t structsize)
+{
+ int i;
+
+ /* Guard against version mismatches between library and caller. */
+ cinfo->mem = NULL; /* so jpeg_destroy knows mem mgr not called */
+ if (version != JPEG_LIB_VERSION)
+ ERREXIT2(cinfo, JERR_BAD_LIB_VERSION, JPEG_LIB_VERSION, version);
+ if (structsize != SIZEOF(struct jpeg_decompress_struct))
+ ERREXIT2(cinfo, JERR_BAD_STRUCT_SIZE,
+ (int) SIZEOF(struct jpeg_decompress_struct), (int) structsize);
+
+ /* For debugging purposes, we zero the whole master structure.
+ * But the application has already set the err pointer, and may have set
+ * client_data, so we have to save and restore those fields.
+ * Note: if application hasn't set client_data, tools like Purify may
+ * complain here.
+ */
+ {
+ struct jpeg_error_mgr * err = cinfo->err;
+ void * client_data = cinfo->client_data; /* ignore Purify complaint here */
+ MEMZERO(cinfo, SIZEOF(struct jpeg_decompress_struct));
+ cinfo->err = err;
+ cinfo->client_data = client_data;
+ }
+ cinfo->is_decompressor = TRUE;
+
+ /* Initialize a memory manager instance for this object */
+ jinit_memory_mgr((j_common_ptr) cinfo);
+
+ /* Zero out pointers to permanent structures. */
+ cinfo->progress = NULL;
+ cinfo->src = NULL;
+
+ for (i = 0; i < NUM_TQUANT_TBLS; i++)
+ cinfo->quant_tbl_ptrs[i] = NULL;
+
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ cinfo->dc_huff_tbl_ptrs[i] = NULL;
+ cinfo->ac_huff_tbl_ptrs[i] = NULL;
+ }
+
+ /* Initialize marker processor so application can override methods
+ * for COM, APPn markers before calling jpeg_read_header.
+ */
+ cinfo->marker_list = NULL;
+ jinit_marker_reader(cinfo);
+
+ /* And initialize the overall input controller. */
+ jinit_input_controller(cinfo);
+
+ /* OK, I'm ready */
+ cinfo->global_state = DSTATE_START;
+}
+
+
+/*
+ * Destruction of a JPEG decompression object
+ */
+
+GLOBAL(void)
+jpeg_destroy_decompress (j_decompress_ptr cinfo)
+{
+ jpeg_destroy((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Abort processing of a JPEG decompression operation,
+ * but don't destroy the object itself.
+ */
+
+GLOBAL(void)
+jpeg_abort_decompress (j_decompress_ptr cinfo)
+{
+ jpeg_abort((j_common_ptr) cinfo); /* use common routine */
+}
+
+
+/*
+ * Set default decompression parameters.
+ */
+
+LOCAL(void)
+default_decompress_parms (j_decompress_ptr cinfo)
+{
+ /* Guess the input colorspace, and set output colorspace accordingly. */
+ /* (Wish JPEG committee had provided a real way to specify this...) */
+ /* Note application may override our guesses. */
+ switch (cinfo->num_components) {
+ case 1:
+ cinfo->jpeg_color_space = JCS_GRAYSCALE;
+ cinfo->out_color_space = JCS_GRAYSCALE;
+ break;
+
+ case 3:
+ if (cinfo->saw_JFIF_marker) {
+ cinfo->jpeg_color_space = JCS_YCbCr; /* JFIF implies YCbCr */
+ } else if (cinfo->saw_Adobe_marker) {
+ switch (cinfo->Adobe_transform) {
+ case 0:
+ cinfo->jpeg_color_space = JCS_RGB;
+ break;
+ case 1:
+ cinfo->jpeg_color_space = JCS_YCbCr;
+ break;
+ default:
+ WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
+ cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
+ break;
+ }
+ } else {
+ /* Saw no special markers, try to guess from the component IDs */
+ int cid0 = cinfo->comp_info[0].component_id;
+ int cid1 = cinfo->comp_info[1].component_id;
+ int cid2 = cinfo->comp_info[2].component_id;
+
+ if (cid0 == 1 && cid1 == 2 && cid2 == 3)
+ cinfo->jpeg_color_space = JCS_YCbCr; /* assume JFIF w/out marker */
+ else if (cid0 == 82 && cid1 == 71 && cid2 == 66)
+ cinfo->jpeg_color_space = JCS_RGB; /* ASCII 'R', 'G', 'B' */
+ else {
+ TRACEMS3(cinfo, 1, JTRC_UNKNOWN_IDS, cid0, cid1, cid2);
+ cinfo->jpeg_color_space = JCS_YCbCr; /* assume it's YCbCr */
+ }
+ }
+ /* Always guess RGB is proper output colorspace. */
+ cinfo->out_color_space = JCS_RGB;
+ break;
+
+ case 4:
+ if (cinfo->saw_Adobe_marker) {
+ switch (cinfo->Adobe_transform) {
+ case 0:
+ cinfo->jpeg_color_space = JCS_CMYK;
+ break;
+ case 2:
+ cinfo->jpeg_color_space = JCS_YCCK;
+ break;
+ default:
+ WARNMS1(cinfo, JWRN_ADOBE_XFORM, cinfo->Adobe_transform);
+ cinfo->jpeg_color_space = JCS_YCCK; /* assume it's YCCK */
+ break;
+ }
+ } else {
+ /* No special markers, assume straight CMYK. */
+ cinfo->jpeg_color_space = JCS_CMYK;
+ }
+ cinfo->out_color_space = JCS_CMYK;
+ break;
+
+ default:
+ cinfo->jpeg_color_space = JCS_UNKNOWN;
+ cinfo->out_color_space = JCS_UNKNOWN;
+ break;
+ }
+
+ /* Set defaults for other decompression parameters. */
+ cinfo->scale_num = 1; /* 1:1 scaling */
+ cinfo->scale_denom = 1;
+ cinfo->output_gamma = 1.0;
+ cinfo->buffered_image = FALSE;
+ cinfo->raw_data_out = FALSE;
+ cinfo->dct_method = JDCT_DEFAULT;
+ cinfo->do_fancy_upsampling = TRUE;
+ cinfo->do_block_smoothing = TRUE;
+ cinfo->quantize_colors = FALSE;
+ /* We set these in case application only sets quantize_colors. */
+ cinfo->dither_mode = JDITHER_FS;
+#ifdef TQUANT_2PASS_SUPPORTED
+ cinfo->two_pass_quantize = TRUE;
+#else
+ cinfo->two_pass_quantize = FALSE;
+#endif
+ cinfo->desired_number_of_colors = 256;
+ cinfo->colormap = NULL;
+ /* Initialize for no mode change in buffered-image mode. */
+ cinfo->enable_1pass_quant = FALSE;
+ cinfo->enable_external_quant = FALSE;
+ cinfo->enable_2pass_quant = FALSE;
+}
+
+
+/*
+ * Decompression startup: read start of JPEG datastream to see what's there.
+ * Need only initialize JPEG object and supply a data source before calling.
+ *
+ * This routine will read as far as the first SOS marker (ie, actual start of
+ * compressed data), and will save all tables and parameters in the JPEG
+ * object. It will also initialize the decompression parameters to default
+ * values, and finally return JPEG_HEADER_OK. On return, the application may
+ * adjust the decompression parameters and then call jpeg_start_decompress.
+ * (Or, if the application only wanted to determine the image parameters,
+ * the data need not be decompressed. In that case, call jpeg_abort or
+ * jpeg_destroy to release any temporary space.)
+ * If an abbreviated (tables only) datastream is presented, the routine will
+ * return JPEG_HEADER_TABLES_ONLY upon reaching EOI. The application may then
+ * re-use the JPEG object to read the abbreviated image datastream(s).
+ * It is unnecessary (but OK) to call jpeg_abort in this case.
+ * The JPEG_SUSPENDED return code only occurs if the data source module
+ * requests suspension of the decompressor. In this case the application
+ * should load more source data and then re-call jpeg_read_header to resume
+ * processing.
+ * If a non-suspending data source is used and require_image is TRUE, then the
+ * return code need not be inspected since only JPEG_HEADER_OK is possible.
+ *
+ * This routine is now just a front end to jpeg_consume_input, with some
+ * extra error checking.
+ */
+
+GLOBAL(int)
+jpeg_read_header (j_decompress_ptr cinfo, boolean require_image)
+{
+ int retcode;
+
+ if (cinfo->global_state != DSTATE_START &&
+ cinfo->global_state != DSTATE_INHEADER)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ retcode = jpeg_consume_input(cinfo);
+
+ switch (retcode) {
+ case JPEG_REACHED_SOS:
+ retcode = JPEG_HEADER_OK;
+ break;
+ case JPEG_REACHED_EOI:
+ if (require_image) /* Complain if application wanted an image */
+ ERREXIT(cinfo, JERR_NO_IMAGE);
+ /* Reset to start state; it would be safer to require the application to
+ * call jpeg_abort, but we can't change it now for compatibility reasons.
+ * A side effect is to free any temporary memory (there shouldn't be any).
+ */
+ jpeg_abort((j_common_ptr) cinfo); /* sets state = DSTATE_START */
+ retcode = JPEG_HEADER_TABLES_ONLY;
+ break;
+ case JPEG_SUSPENDED:
+ /* no work */
+ break;
+ }
+
+ return retcode;
+}
+
+
+/*
+ * Consume data in advance of what the decompressor requires.
+ * This can be called at any time once the decompressor object has
+ * been created and a data source has been set up.
+ *
+ * This routine is essentially a state machine that handles a couple
+ * of critical state-transition actions, namely initial setup and
+ * transition from header scanning to ready-for-start_decompress.
+ * All the actual input is done via the input controller's consume_input
+ * method.
+ */
+
+GLOBAL(int)
+jpeg_consume_input (j_decompress_ptr cinfo)
+{
+ int retcode = JPEG_SUSPENDED;
+
+ /* NB: every possible DSTATE value should be listed in this switch */
+ switch (cinfo->global_state) {
+ case DSTATE_START:
+ /* Start-of-datastream actions: reset appropriate modules */
+ (*cinfo->inputctl->reset_input_controller) (cinfo);
+ /* Initialize application's data source module */
+ (*cinfo->src->init_source) (cinfo);
+ cinfo->global_state = DSTATE_INHEADER;
+ /*FALLTHROUGH*/
+ case DSTATE_INHEADER:
+ retcode = (*cinfo->inputctl->consume_input) (cinfo);
+ if (retcode == JPEG_REACHED_SOS) { /* Found SOS, prepare to decompress */
+ /* Set up default parameters based on header data */
+ default_decompress_parms(cinfo);
+ /* Set global state: ready for start_decompress */
+ cinfo->global_state = DSTATE_READY;
+ }
+ break;
+ case DSTATE_READY:
+ /* Can't advance past first SOS until start_decompress is called */
+ retcode = JPEG_REACHED_SOS;
+ break;
+ case DSTATE_PRELOAD:
+ case DSTATE_PRESCAN:
+ case DSTATE_SCANNING:
+ case DSTATE_RAW_OK:
+ case DSTATE_BUFIMAGE:
+ case DSTATE_BUFPOST:
+ case DSTATE_STOPPING:
+ retcode = (*cinfo->inputctl->consume_input) (cinfo);
+ break;
+ default:
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ }
+ return retcode;
+}
+
+
+/*
+ * Have we finished reading the input file?
+ */
+
+GLOBAL(boolean)
+jpeg_input_complete (j_decompress_ptr cinfo)
+{
+ /* Check for valid jpeg object */
+ if (cinfo->global_state < DSTATE_START ||
+ cinfo->global_state > DSTATE_STOPPING)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ return cinfo->inputctl->eoi_reached;
+}
+
+
+/*
+ * Is there more than one scan?
+ */
+
+GLOBAL(boolean)
+jpeg_has_multiple_scans (j_decompress_ptr cinfo)
+{
+ /* Only valid after jpeg_read_header completes */
+ if (cinfo->global_state < DSTATE_READY ||
+ cinfo->global_state > DSTATE_STOPPING)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ return cinfo->inputctl->has_multiple_scans;
+}
+
+
+/*
+ * Finish JPEG decompression.
+ *
+ * This will normally just verify the file trailer and release temp storage.
+ *
+ * Returns FALSE if suspended. The return value need be inspected only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(boolean)
+jpeg_finish_decompress (j_decompress_ptr cinfo)
+{
+ if ((cinfo->global_state == DSTATE_SCANNING ||
+ cinfo->global_state == DSTATE_RAW_OK) && ! cinfo->buffered_image) {
+ /* Terminate final pass of non-buffered mode */
+ if (cinfo->output_scanline < cinfo->output_height)
+ ERREXIT(cinfo, JERR_TOO_LITTLE_DATA);
+ (*cinfo->master->finish_output_pass) (cinfo);
+ cinfo->global_state = DSTATE_STOPPING;
+ } else if (cinfo->global_state == DSTATE_BUFIMAGE) {
+ /* Finishing after a buffered-image operation */
+ cinfo->global_state = DSTATE_STOPPING;
+ } else if (cinfo->global_state != DSTATE_STOPPING) {
+ /* STOPPING = repeat call after a suspension, anything else is error */
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ }
+ /* Read until EOI */
+ while (! cinfo->inputctl->eoi_reached) {
+ if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
+ return FALSE; /* Suspend, come back later */
+ }
+ /* Do final cleanup */
+ (*cinfo->src->term_source) (cinfo);
+ /* We can use jpeg_abort to release memory and reset global_state */
+ jpeg_abort((j_common_ptr) cinfo);
+ return TRUE;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdapistd.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdapistd.c
new file mode 100644
index 0000000..fd29573
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdapistd.c
@@ -0,0 +1,275 @@
+/*
+ * jdapistd.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains application interface code for the decompression half
+ * of the JPEG library. These are the "standard" API routines that are
+ * used in the normal full-decompression case. They are not used by a
+ * transcoding-only application. Note that if an application links in
+ * jpeg_start_decompress, it will end up linking in the entire decompressor.
+ * We thus must separate this file from jdapimin.c to avoid linking the
+ * whole decompression library into a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Forward declarations */
+LOCAL(boolean) output_pass_setup JPP((j_decompress_ptr cinfo));
+
+
+/*
+ * Decompression initialization.
+ * jpeg_read_header must be completed before calling this.
+ *
+ * If a multipass operating mode was selected, this will do all but the
+ * last pass, and thus may take a great deal of time.
+ *
+ * Returns FALSE if suspended. The return value need be inspected only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(boolean)
+jpeg_start_decompress (j_decompress_ptr cinfo)
+{
+ if (cinfo->global_state == DSTATE_READY) {
+ /* First call: initialize master control, select active modules */
+ jinit_master_decompress(cinfo);
+ if (cinfo->buffered_image) {
+ /* No more work here; expecting jpeg_start_output next */
+ cinfo->global_state = DSTATE_BUFIMAGE;
+ return TRUE;
+ }
+ cinfo->global_state = DSTATE_PRELOAD;
+ }
+ if (cinfo->global_state == DSTATE_PRELOAD) {
+ /* If file has multiple scans, absorb them all into the coef buffer */
+ if (cinfo->inputctl->has_multiple_scans) {
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+ for (;;) {
+ int retcode;
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL)
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ /* Absorb some more input */
+ retcode = (*cinfo->inputctl->consume_input) (cinfo);
+ if (retcode == JPEG_SUSPENDED)
+ return FALSE;
+ if (retcode == JPEG_REACHED_EOI)
+ break;
+ /* Advance progress counter if appropriate */
+ if (cinfo->progress != NULL &&
+ (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
+ if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
+ /* jdmaster underestimated number of scans; ratchet up one scan */
+ cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
+ }
+ }
+ }
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+ }
+ cinfo->output_scan_number = cinfo->input_scan_number;
+ } else if (cinfo->global_state != DSTATE_PRESCAN)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ /* Perform any dummy output passes, and set up for the final pass */
+ return output_pass_setup(cinfo);
+}
+
+
+/*
+ * Set up for an output pass, and perform any dummy pass(es) needed.
+ * Common subroutine for jpeg_start_decompress and jpeg_start_output.
+ * Entry: global_state = DSTATE_PRESCAN only if previously suspended.
+ * Exit: If done, returns TRUE and sets global_state for proper output mode.
+ * If suspended, returns FALSE and sets global_state = DSTATE_PRESCAN.
+ */
+
+LOCAL(boolean)
+output_pass_setup (j_decompress_ptr cinfo)
+{
+ if (cinfo->global_state != DSTATE_PRESCAN) {
+ /* First call: do pass setup */
+ (*cinfo->master->prepare_for_output_pass) (cinfo);
+ cinfo->output_scanline = 0;
+ cinfo->global_state = DSTATE_PRESCAN;
+ }
+ /* Loop over any required dummy passes */
+ while (cinfo->master->is_dummy_pass) {
+#ifdef TQUANT_2PASS_SUPPORTED
+ /* Crank through the dummy pass */
+ while (cinfo->output_scanline < cinfo->output_height) {
+ JDIMENSION last_scanline;
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) cinfo->output_scanline;
+ cinfo->progress->pass_limit = (long) cinfo->output_height;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+ /* Process some data */
+ last_scanline = cinfo->output_scanline;
+ (*cinfo->main->process_data) (cinfo, (JSAMPARRAY) NULL,
+ &cinfo->output_scanline, (JDIMENSION) 0);
+ if (cinfo->output_scanline == last_scanline)
+ return FALSE; /* No progress made, must suspend */
+ }
+ /* Finish up dummy pass, and set up for another one */
+ (*cinfo->master->finish_output_pass) (cinfo);
+ (*cinfo->master->prepare_for_output_pass) (cinfo);
+ cinfo->output_scanline = 0;
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif /* TQUANT_2PASS_SUPPORTED */
+ }
+ /* Ready for application to drive output pass through
+ * jpeg_read_scanlines or jpeg_read_raw_data.
+ */
+ cinfo->global_state = cinfo->raw_data_out ? DSTATE_RAW_OK : DSTATE_SCANNING;
+ return TRUE;
+}
+
+
+/*
+ * Read some scanlines of data from the JPEG decompressor.
+ *
+ * The return value will be the number of lines actually read.
+ * This may be less than the number requested in several cases,
+ * including bottom of image, data source suspension, and operating
+ * modes that emit multiple scanlines at a time.
+ *
+ * Note: we warn about excess calls to jpeg_read_scanlines() since
+ * this likely Q_SIGNALS an application programmer error. However,
+ * an oversize buffer (max_lines > scanlines remaining) is not an error.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines,
+ JDIMENSION max_lines)
+{
+ JDIMENSION row_ctr;
+
+ if (cinfo->global_state != DSTATE_SCANNING)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ if (cinfo->output_scanline >= cinfo->output_height) {
+ WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+ return 0;
+ }
+
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) cinfo->output_scanline;
+ cinfo->progress->pass_limit = (long) cinfo->output_height;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+
+ /* Process some data */
+ row_ctr = 0;
+ (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, max_lines);
+ cinfo->output_scanline += row_ctr;
+ return row_ctr;
+}
+
+
+/*
+ * Alternate entry point to read raw data.
+ * Processes exactly one iMCU row per call, unless suspended.
+ */
+
+GLOBAL(JDIMENSION)
+jpeg_read_raw_data (j_decompress_ptr cinfo, JSAMPIMAGE data,
+ JDIMENSION max_lines)
+{
+ JDIMENSION lines_per_iMCU_row;
+
+ if (cinfo->global_state != DSTATE_RAW_OK)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ if (cinfo->output_scanline >= cinfo->output_height) {
+ WARNMS(cinfo, JWRN_TOO_MUCH_DATA);
+ return 0;
+ }
+
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->pass_counter = (long) cinfo->output_scanline;
+ cinfo->progress->pass_limit = (long) cinfo->output_height;
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ }
+
+ /* Verify that at least one iMCU row can be returned. */
+ lines_per_iMCU_row = cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size;
+ if (max_lines < lines_per_iMCU_row)
+ ERREXIT(cinfo, JERR_BUFFER_SIZE);
+
+ /* Decompress directly into user's buffer. */
+ if (! (*cinfo->coef->decompress_data) (cinfo, data))
+ return 0; /* suspension forced, can do nothing more */
+
+ /* OK, we processed one iMCU row. */
+ cinfo->output_scanline += lines_per_iMCU_row;
+ return lines_per_iMCU_row;
+}
+
+
+/* Additional entry points for buffered-image mode. */
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+
+/*
+ * Initialize for an output pass in buffered-image mode.
+ */
+
+GLOBAL(boolean)
+jpeg_start_output (j_decompress_ptr cinfo, int scan_number)
+{
+ if (cinfo->global_state != DSTATE_BUFIMAGE &&
+ cinfo->global_state != DSTATE_PRESCAN)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ /* Limit scan number to valid range */
+ if (scan_number <= 0)
+ scan_number = 1;
+ if (cinfo->inputctl->eoi_reached &&
+ scan_number > cinfo->input_scan_number)
+ scan_number = cinfo->input_scan_number;
+ cinfo->output_scan_number = scan_number;
+ /* Perform any dummy output passes, and set up for the real pass */
+ return output_pass_setup(cinfo);
+}
+
+
+/*
+ * Finish up after an output pass in buffered-image mode.
+ *
+ * Returns FALSE if suspended. The return value need be inspected only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(boolean)
+jpeg_finish_output (j_decompress_ptr cinfo)
+{
+ if ((cinfo->global_state == DSTATE_SCANNING ||
+ cinfo->global_state == DSTATE_RAW_OK) && cinfo->buffered_image) {
+ /* Terminate this pass. */
+ /* We do not require the whole pass to have been completed. */
+ (*cinfo->master->finish_output_pass) (cinfo);
+ cinfo->global_state = DSTATE_BUFPOST;
+ } else if (cinfo->global_state != DSTATE_BUFPOST) {
+ /* BUFPOST = repeat call after a suspension, anything else is error */
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ }
+ /* Read markers looking for SOS or EOI */
+ while (cinfo->input_scan_number <= cinfo->output_scan_number &&
+ ! cinfo->inputctl->eoi_reached) {
+ if ((*cinfo->inputctl->consume_input) (cinfo) == JPEG_SUSPENDED)
+ return FALSE; /* Suspend, come back later */
+ }
+ cinfo->global_state = DSTATE_BUFIMAGE;
+ return TRUE;
+}
+
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdatadst.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdatadst.c
new file mode 100644
index 0000000..a203331
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdatadst.c
@@ -0,0 +1,151 @@
+/*
+ * jdatadst.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains compression data destination routines for the case of
+ * emitting JPEG data to a file (or any stdio stream). While these routines
+ * are sufficient for most applications, some will want to use a different
+ * destination manager.
+ * IMPORTANT: we assume that fwrite() will correctly transcribe an array of
+ * JOCTETs into 8-bit-wide elements on external storage. If char is wider
+ * than 8 bits on your machine, you may need to do some tweaking.
+ */
+
+/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jerror.h"
+
+
+/* Expanded data destination object for stdio output */
+
+typedef struct {
+ struct jpeg_destination_mgr pub; /* public fields */
+
+ FILE * outfile; /* target stream */
+ JOCTET * buffer; /* start of buffer */
+} my_destination_mgr;
+
+typedef my_destination_mgr * my_dest_ptr;
+
+#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
+
+
+/*
+ * Initialize destination --- called by jpeg_start_compress
+ * before any data is actually written.
+ */
+
+METHODDEF(void)
+init_destination (j_compress_ptr cinfo)
+{
+ my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+
+ /* Allocate the output buffer --- it will be released when done with image */
+ dest->buffer = (JOCTET *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
+
+ dest->pub.next_output_byte = dest->buffer;
+ dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+}
+
+
+/*
+ * Empty the output buffer --- called whenever buffer fills up.
+ *
+ * In typical applications, this should write the entire output buffer
+ * (ignoring the current state of next_output_byte & free_in_buffer),
+ * reset the pointer & count to the start of the buffer, and return TRUE
+ * indicating that the buffer has been dumped.
+ *
+ * In applications that need to be able to suspend compression due to output
+ * overrun, a FALSE return indicates that the buffer cannot be emptied now.
+ * In this situation, the compressor will return to its caller (possibly with
+ * an indication that it has not accepted all the supplied scanlines). The
+ * application should resume compression after it has made more room in the
+ * output buffer. Note that there are substantial restrictions on the use of
+ * suspension --- see the documentation.
+ *
+ * When suspending, the compressor will back up to a convenient restart point
+ * (typically the start of the current MCU). next_output_byte & free_in_buffer
+ * indicate where the restart point will be if the current call returns FALSE.
+ * Data beyond this point will be regenerated after resumption, so do not
+ * write it out when emptying the buffer externally.
+ */
+
+METHODDEF(boolean)
+empty_output_buffer (j_compress_ptr cinfo)
+{
+ my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+
+ if (JFWRITE(dest->outfile, dest->buffer, OUTPUT_BUF_SIZE) !=
+ (size_t) OUTPUT_BUF_SIZE)
+ ERREXIT(cinfo, JERR_FILE_WRITE);
+
+ dest->pub.next_output_byte = dest->buffer;
+ dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
+
+ return TRUE;
+}
+
+
+/*
+ * Terminate destination --- called by jpeg_finish_compress
+ * after all data has been written. Usually needs to flush buffer.
+ *
+ * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
+ * application must deal with any cleanup that should happen even
+ * for error exit.
+ */
+
+METHODDEF(void)
+term_destination (j_compress_ptr cinfo)
+{
+ my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
+ size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
+
+ /* Write any data remaining in the buffer */
+ if (datacount > 0) {
+ if (JFWRITE(dest->outfile, dest->buffer, datacount) != datacount)
+ ERREXIT(cinfo, JERR_FILE_WRITE);
+ }
+ fflush(dest->outfile);
+ /* Make sure we wrote the output file OK */
+ if (ferror(dest->outfile))
+ ERREXIT(cinfo, JERR_FILE_WRITE);
+}
+
+
+/*
+ * Prepare for output to a stdio stream.
+ * The caller must have already opened the stream, and is responsible
+ * for closing it after finishing compression.
+ */
+
+GLOBAL(void)
+jpeg_stdio_dest (j_compress_ptr cinfo, FILE * outfile)
+{
+ my_dest_ptr dest;
+
+ /* The destination object is made permanent so that multiple JPEG images
+ * can be written to the same file without re-executing jpeg_stdio_dest.
+ * This makes it dangerous to use this manager and a different destination
+ * manager serially with the same JPEG object, because their private object
+ * sizes may be different. Caveat programmer.
+ */
+ if (cinfo->dest == NULL) { /* first time for this JPEG object? */
+ cinfo->dest = (struct jpeg_destination_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ SIZEOF(my_destination_mgr));
+ }
+
+ dest = (my_dest_ptr) cinfo->dest;
+ dest->pub.init_destination = init_destination;
+ dest->pub.empty_output_buffer = empty_output_buffer;
+ dest->pub.term_destination = term_destination;
+ dest->outfile = outfile;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdatasrc.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdatasrc.c
new file mode 100644
index 0000000..078f3fa
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdatasrc.c
@@ -0,0 +1,212 @@
+/*
+ * jdatasrc.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains decompression data source routines for the case of
+ * reading JPEG data from a file (or any stdio stream). While these routines
+ * are sufficient for most applications, some will want to use a different
+ * source manager.
+ * IMPORTANT: we assume that fread() will correctly transcribe an array of
+ * JOCTETs from 8-bit-wide elements on external storage. If char is wider
+ * than 8 bits on your machine, you may need to do some tweaking.
+ */
+
+/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jerror.h"
+
+
+/* Expanded data source object for stdio input */
+
+typedef struct {
+ struct jpeg_source_mgr pub; /* public fields */
+
+ FILE * infile; /* source stream */
+ JOCTET * buffer; /* start of buffer */
+ boolean start_of_file; /* have we gotten any data yet? */
+} my_source_mgr;
+
+typedef my_source_mgr * my_src_ptr;
+
+#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
+
+
+/*
+ * Initialize source --- called by jpeg_read_header
+ * before any data is actually read.
+ */
+
+METHODDEF(void)
+init_source (j_decompress_ptr cinfo)
+{
+ my_src_ptr src = (my_src_ptr) cinfo->src;
+
+ /* We reset the empty-input-file flag for each image,
+ * but we don't clear the input buffer.
+ * This is correct behavior for reading a series of images from one source.
+ */
+ src->start_of_file = TRUE;
+}
+
+
+/*
+ * Fill the input buffer --- called whenever buffer is emptied.
+ *
+ * In typical applications, this should read fresh data into the buffer
+ * (ignoring the current state of next_input_byte & bytes_in_buffer),
+ * reset the pointer & count to the start of the buffer, and return TRUE
+ * indicating that the buffer has been reloaded. It is not necessary to
+ * fill the buffer entirely, only to obtain at least one more byte.
+ *
+ * There is no such thing as an EOF return. If the end of the file has been
+ * reached, the routine has a choice of ERREXIT() or inserting fake data into
+ * the buffer. In most cases, generating a warning message and inserting a
+ * fake EOI marker is the best course of action --- this will allow the
+ * decompressor to output however much of the image is there. However,
+ * the resulting error message is misleading if the real problem is an empty
+ * input file, so we handle that case specially.
+ *
+ * In applications that need to be able to suspend compression due to input
+ * not being available yet, a FALSE return indicates that no more data can be
+ * obtained right now, but more may be forthcoming later. In this situation,
+ * the decompressor will return to its caller (with an indication of the
+ * number of scanlines it has read, if any). The application should resume
+ * decompression after it has loaded more data into the input buffer. Note
+ * that there are substantial restrictions on the use of suspension --- see
+ * the documentation.
+ *
+ * When suspending, the decompressor will back up to a convenient restart point
+ * (typically the start of the current MCU). next_input_byte & bytes_in_buffer
+ * indicate where the restart point will be if the current call returns FALSE.
+ * Data beyond this point must be rescanned after resumption, so move it to
+ * the front of the buffer rather than discarding it.
+ */
+
+METHODDEF(boolean)
+fill_input_buffer (j_decompress_ptr cinfo)
+{
+ my_src_ptr src = (my_src_ptr) cinfo->src;
+ size_t nbytes;
+
+ nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE);
+
+ if (nbytes <= 0) {
+ if (src->start_of_file) /* Treat empty input file as fatal error */
+ ERREXIT(cinfo, JERR_INPUT_EMPTY);
+ WARNMS(cinfo, JWRN_JPEG_EOF);
+ /* Insert a fake EOI marker */
+ src->buffer[0] = (JOCTET) 0xFF;
+ src->buffer[1] = (JOCTET) JPEG_EOI;
+ nbytes = 2;
+ }
+
+ src->pub.next_input_byte = src->buffer;
+ src->pub.bytes_in_buffer = nbytes;
+ src->start_of_file = FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Skip data --- used to skip over a potentially large amount of
+ * uninteresting data (such as an APPn marker).
+ *
+ * Writers of suspendable-input applications must note that skip_input_data
+ * is not granted the right to give a suspension return. If the skip extends
+ * beyond the data currently in the buffer, the buffer can be marked empty so
+ * that the next read will cause a fill_input_buffer call that can suspend.
+ * Arranging for additional bytes to be discarded before reloading the input
+ * buffer is the application writer's problem.
+ */
+
+METHODDEF(void)
+skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+{
+ my_src_ptr src = (my_src_ptr) cinfo->src;
+
+ /* Just a dumb implementation for now. Could use fseek() except
+ * it doesn't work on pipes. Not clear that being smart is worth
+ * any trouble anyway --- large skips are infrequent.
+ */
+ if (num_bytes > 0) {
+ while (num_bytes > (long) src->pub.bytes_in_buffer) {
+ num_bytes -= (long) src->pub.bytes_in_buffer;
+ (void) fill_input_buffer(cinfo);
+ /* note we assume that fill_input_buffer will never return FALSE,
+ * so suspension need not be handled.
+ */
+ }
+ src->pub.next_input_byte += (size_t) num_bytes;
+ src->pub.bytes_in_buffer -= (size_t) num_bytes;
+ }
+}
+
+
+/*
+ * An additional method that can be provided by data source modules is the
+ * resync_to_restart method for error recovery in the presence of RST markers.
+ * For the moment, this source module just uses the default resync method
+ * provided by the JPEG library. That method assumes that no backtracking
+ * is possible.
+ */
+
+
+/*
+ * Terminate source --- called by jpeg_finish_decompress
+ * after all data has been read. Often a no-op.
+ *
+ * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
+ * application must deal with any cleanup that should happen even
+ * for error exit.
+ */
+
+METHODDEF(void)
+term_source (j_decompress_ptr cinfo)
+{
+ /* no work necessary here */
+}
+
+
+/*
+ * Prepare for input from a stdio stream.
+ * The caller must have already opened the stream, and is responsible
+ * for closing it after finishing decompression.
+ */
+
+GLOBAL(void)
+jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile)
+{
+ my_src_ptr src;
+
+ /* The source object and input buffer are made permanent so that a series
+ * of JPEG images can be read from the same file by calling jpeg_stdio_src
+ * only before the first one. (If we discarded the buffer at the end of
+ * one image, we'd likely lose the start of the next one.)
+ * This makes it unsafe to use this manager and a different source
+ * manager serially with the same JPEG object. Caveat programmer.
+ */
+ if (cinfo->src == NULL) { /* first time for this JPEG object? */
+ cinfo->src = (struct jpeg_source_mgr *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ SIZEOF(my_source_mgr));
+ src = (my_src_ptr) cinfo->src;
+ src->buffer = (JOCTET *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ INPUT_BUF_SIZE * SIZEOF(JOCTET));
+ }
+
+ src = (my_src_ptr) cinfo->src;
+ src->pub.init_source = init_source;
+ src->pub.fill_input_buffer = fill_input_buffer;
+ src->pub.skip_input_data = skip_input_data;
+ src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
+ src->pub.term_source = term_source;
+ src->infile = infile;
+ src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
+ src->pub.next_input_byte = NULL; /* until buffer loaded */
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdcoefct.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdcoefct.c
new file mode 100644
index 0000000..978457d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdcoefct.c
@@ -0,0 +1,736 @@
+/*
+ * jdcoefct.c
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains the coefficient buffer controller for decompression.
+ * This controller is the top level of the JPEG decompressor proper.
+ * The coefficient buffer lies between entropy decoding and inverse-DCT steps.
+ *
+ * In buffered-image mode, this controller is the interface between
+ * input-oriented processing and output-oriented processing.
+ * Also, the input side (only) is used when reading a file for transcoding.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+/* Block smoothing is only applicable for progressive JPEG, so: */
+#ifndef D_PROGRESSIVE_SUPPORTED
+#undef BLOCK_SMOOTHING_SUPPORTED
+#endif
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_d_coef_controller pub; /* public fields */
+
+ /* These variables keep track of the current location of the input side. */
+ /* cinfo->input_iMCU_row is also used for this. */
+ JDIMENSION MCU_ctr; /* counts MCUs processed in current row */
+ int MCU_vert_offset; /* counts MCU rows within iMCU row */
+ int MCU_rows_per_iMCU_row; /* number of such rows needed */
+
+ /* The output side's location is represented by cinfo->output_iMCU_row. */
+
+ /* In single-pass modes, it's sufficient to buffer just one MCU.
+ * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
+ * and let the entropy decoder write into that workspace each time.
+ * (On 80x86, the workspace is FAR even though it's not really very big;
+ * this is to keep the module interfaces unchanged when a large coefficient
+ * buffer is necessary.)
+ * In multi-pass modes, this array points to the current MCU's blocks
+ * within the virtual arrays; it is used only by the input side.
+ */
+ JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+ /* In multi-pass modes, we need a virtual block array for each component. */
+ jvirt_barray_ptr whole_image[MAX_COMPONENTS];
+#endif
+
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+ /* When doing block smoothing, we latch coefficient Al values here */
+ int * coef_bits_latch;
+#define SAVED_COEFS 6 /* we save coef_bits[0..5] */
+#endif
+} my_coef_controller;
+
+typedef my_coef_controller * my_coef_ptr;
+
+/* Forward declarations */
+METHODDEF(int) decompress_onepass
+ JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+METHODDEF(int) decompress_data
+ JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
+#endif
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
+METHODDEF(int) decompress_smooth_data
+ JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
+#endif
+
+
+LOCAL(void)
+start_iMCU_row (j_decompress_ptr cinfo)
+/* Reset within-iMCU-row counters for a new row (input side) */
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ /* In an interleaved scan, an MCU row is the same as an iMCU row.
+ * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
+ * But at the bottom of the image, process only what's left.
+ */
+ if (cinfo->comps_in_scan > 1) {
+ coef->MCU_rows_per_iMCU_row = 1;
+ } else {
+ if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
+ else
+ coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
+ }
+
+ coef->MCU_ctr = 0;
+ coef->MCU_vert_offset = 0;
+}
+
+
+/*
+ * Initialize for an input processing pass.
+ */
+
+METHODDEF(void)
+start_input_pass (j_decompress_ptr cinfo)
+{
+ cinfo->input_iMCU_row = 0;
+ start_iMCU_row(cinfo);
+}
+
+
+/*
+ * Initialize for an output processing pass.
+ */
+
+METHODDEF(void)
+start_output_pass (j_decompress_ptr cinfo)
+{
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+
+ /* If multipass, check to see whether to use block smoothing on this pass */
+ if (coef->pub.coef_arrays != NULL) {
+ if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
+ coef->pub.decompress_data = decompress_smooth_data;
+ else
+ coef->pub.decompress_data = decompress_data;
+ }
+#endif
+ cinfo->output_iMCU_row = 0;
+}
+
+
+/*
+ * Decompress and return some data in the single-pass case.
+ * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
+ * Input and output must run in lockstep since we have only a one-MCU buffer.
+ * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
+ *
+ * NB: output_buf tqcontains a plane for each component in image,
+ * which we index according to the component's SOF position.
+ */
+
+METHODDEF(int)
+decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION MCU_col_num; /* index of current MCU within row */
+ JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ int blkn, ci, xindex, yindex, yoffset, useful_width;
+ JSAMPARRAY output_ptr;
+ JDIMENSION start_col, output_col;
+ jpeg_component_info *compptr;
+ inverse_DCT_method_ptr inverse_DCT;
+
+ /* Loop to process as much as one whole iMCU row */
+ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+ yoffset++) {
+ for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
+ MCU_col_num++) {
+ /* Try to fetch an MCU. Entropy decoder expects buffer to be zeroed. */
+ jzero_far((void FAR *) coef->MCU_buffer[0],
+ (size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
+ if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
+ /* Suspension forced; update state counters and exit */
+ coef->MCU_vert_offset = yoffset;
+ coef->MCU_ctr = MCU_col_num;
+ return JPEG_SUSPENDED;
+ }
+ /* Determine where data should go in output_buf and do the IDCT thing.
+ * We skip dummy blocks at the right and bottom edges (but blkn gets
+ * incremented past them!). Note the inner loop relies on having
+ * allocated the MCU_buffer[] blocks sequentially.
+ */
+ blkn = 0; /* index of current DCT block within MCU */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* Don't bother to IDCT an uninteresting component. */
+ if (! compptr->component_needed) {
+ blkn += compptr->MCU_blocks;
+ continue;
+ }
+ inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
+ useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
+ : compptr->last_col_width;
+ output_ptr = output_buf[compptr->component_index] +
+ yoffset * compptr->DCT_scaled_size;
+ start_col = MCU_col_num * compptr->MCU_sample_width;
+ for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+ if (cinfo->input_iMCU_row < last_iMCU_row ||
+ yoffset+yindex < compptr->last_row_height) {
+ output_col = start_col;
+ for (xindex = 0; xindex < useful_width; xindex++) {
+ (*inverse_DCT) (cinfo, compptr,
+ (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
+ output_ptr, output_col);
+ output_col += compptr->DCT_scaled_size;
+ }
+ }
+ blkn += compptr->MCU_width;
+ output_ptr += compptr->DCT_scaled_size;
+ }
+ }
+ }
+ /* Completed an MCU row, but perhaps not an iMCU row */
+ coef->MCU_ctr = 0;
+ }
+ /* Completed the iMCU row, advance counters for next one */
+ cinfo->output_iMCU_row++;
+ if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
+ start_iMCU_row(cinfo);
+ return JPEG_ROW_COMPLETED;
+ }
+ /* Completed the scan */
+ (*cinfo->inputctl->finish_input_pass) (cinfo);
+ return JPEG_SCAN_COMPLETED;
+}
+
+
+/*
+ * Dummy consume-input routine for single-pass operation.
+ */
+
+METHODDEF(int)
+dummy_consume_data (j_decompress_ptr cinfo)
+{
+ return JPEG_SUSPENDED; /* Always indicate nothing was done */
+}
+
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+
+/*
+ * Consume input data and store it in the full-image coefficient buffer.
+ * We read as much as one fully interleaved MCU row ("iMCU" row) per call,
+ * ie, v_samp_factor block rows for each component in the scan.
+ * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
+ */
+
+METHODDEF(int)
+consume_data (j_decompress_ptr cinfo)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION MCU_col_num; /* index of current MCU within row */
+ int blkn, ci, xindex, yindex, yoffset;
+ JDIMENSION start_col;
+ JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
+ JBLOCKROW buffer_ptr;
+ jpeg_component_info *compptr;
+
+ /* Align the virtual buffers for the components used in this scan. */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ buffer[ci] = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
+ cinfo->input_iMCU_row * compptr->v_samp_factor,
+ (JDIMENSION) compptr->v_samp_factor, TRUE);
+ /* Note: entropy decoder expects buffer to be zeroed,
+ * but this is handled automatically by the memory manager
+ * because we requested a pre-zeroed array.
+ */
+ }
+
+ /* Loop to process one whole iMCU row */
+ for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
+ yoffset++) {
+ for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
+ MCU_col_num++) {
+ /* Construct list of pointers to DCT blocks belonging to this MCU */
+ blkn = 0; /* index of current DCT block within MCU */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ start_col = MCU_col_num * compptr->MCU_width;
+ for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
+ buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
+ for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
+ coef->MCU_buffer[blkn++] = buffer_ptr++;
+ }
+ }
+ }
+ /* Try to fetch the MCU. */
+ if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
+ /* Suspension forced; update state counters and exit */
+ coef->MCU_vert_offset = yoffset;
+ coef->MCU_ctr = MCU_col_num;
+ return JPEG_SUSPENDED;
+ }
+ }
+ /* Completed an MCU row, but perhaps not an iMCU row */
+ coef->MCU_ctr = 0;
+ }
+ /* Completed the iMCU row, advance counters for next one */
+ if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
+ start_iMCU_row(cinfo);
+ return JPEG_ROW_COMPLETED;
+ }
+ /* Completed the scan */
+ (*cinfo->inputctl->finish_input_pass) (cinfo);
+ return JPEG_SCAN_COMPLETED;
+}
+
+
+/*
+ * Decompress and return some data in the multi-pass case.
+ * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
+ * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
+ *
+ * NB: output_buf tqcontains a plane for each component in image.
+ */
+
+METHODDEF(int)
+decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ JDIMENSION block_num;
+ int ci, block_row, block_rows;
+ JBLOCKARRAY buffer;
+ JBLOCKROW buffer_ptr;
+ JSAMPARRAY output_ptr;
+ JDIMENSION output_col;
+ jpeg_component_info *compptr;
+ inverse_DCT_method_ptr inverse_DCT;
+
+ /* Force some input to be done if we are getting ahead of the input. */
+ while (cinfo->input_scan_number < cinfo->output_scan_number ||
+ (cinfo->input_scan_number == cinfo->output_scan_number &&
+ cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
+ if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
+ return JPEG_SUSPENDED;
+ }
+
+ /* OK, output from the virtual arrays. */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Don't bother to IDCT an uninteresting component. */
+ if (! compptr->component_needed)
+ continue;
+ /* Align the virtual buffer for this component. */
+ buffer = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[ci],
+ cinfo->output_iMCU_row * compptr->v_samp_factor,
+ (JDIMENSION) compptr->v_samp_factor, FALSE);
+ /* Count non-dummy DCT block rows in this iMCU row. */
+ if (cinfo->output_iMCU_row < last_iMCU_row)
+ block_rows = compptr->v_samp_factor;
+ else {
+ /* NB: can't use last_row_height here; it is input-side-dependent! */
+ block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+ if (block_rows == 0) block_rows = compptr->v_samp_factor;
+ }
+ inverse_DCT = cinfo->idct->inverse_DCT[ci];
+ output_ptr = output_buf[ci];
+ /* Loop over all DCT blocks to be processed. */
+ for (block_row = 0; block_row < block_rows; block_row++) {
+ buffer_ptr = buffer[block_row];
+ output_col = 0;
+ for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
+ (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
+ output_ptr, output_col);
+ buffer_ptr++;
+ output_col += compptr->DCT_scaled_size;
+ }
+ output_ptr += compptr->DCT_scaled_size;
+ }
+ }
+
+ if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
+ return JPEG_ROW_COMPLETED;
+ return JPEG_SCAN_COMPLETED;
+}
+
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+
+
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+
+/*
+ * This code applies interblock smoothing as described by section K.8
+ * of the JPEG standard: the first 5 AC coefficients are estimated from
+ * the DC values of a DCT block and its 8 neighboring blocks.
+ * We apply smoothing only for progressive JPEG decoding, and only if
+ * the coefficients it can estimate are not yet known to full precision.
+ */
+
+/* Natural-order array positions of the first 5 zigzag-order coefficients */
+#define Q01_POS 1
+#define Q10_POS 8
+#define Q20_POS 16
+#define Q11_POS 9
+#define Q02_POS 2
+
+/*
+ * Determine whether block smoothing is applicable and safe.
+ * We also latch the current states of the coef_bits[] entries for the
+ * AC coefficients; otherwise, if the input side of the decompressor
+ * advances into a new scan, we might think the coefficients are known
+ * more accurately than they really are.
+ */
+
+LOCAL(boolean)
+smoothing_ok (j_decompress_ptr cinfo)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ boolean smoothing_useful = FALSE;
+ int ci, coefi;
+ jpeg_component_info *compptr;
+ JTQUANT_TBL * qtable;
+ int * coef_bits;
+ int * coef_bits_latch;
+
+ if (! cinfo->progressive_mode || cinfo->coef_bits == NULL)
+ return FALSE;
+
+ /* Allocate latch area if not already done */
+ if (coef->coef_bits_latch == NULL)
+ coef->coef_bits_latch = (int *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->num_components *
+ (SAVED_COEFS * SIZEOF(int)));
+ coef_bits_latch = coef->coef_bits_latch;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* All components' quantization values must already be latched. */
+ if ((qtable = compptr->quant_table) == NULL)
+ return FALSE;
+ /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
+ if (qtable->quantval[0] == 0 ||
+ qtable->quantval[Q01_POS] == 0 ||
+ qtable->quantval[Q10_POS] == 0 ||
+ qtable->quantval[Q20_POS] == 0 ||
+ qtable->quantval[Q11_POS] == 0 ||
+ qtable->quantval[Q02_POS] == 0)
+ return FALSE;
+ /* DC values must be at least partly known for all components. */
+ coef_bits = cinfo->coef_bits[ci];
+ if (coef_bits[0] < 0)
+ return FALSE;
+ /* Block smoothing is helpful if some AC coefficients remain inaccurate. */
+ for (coefi = 1; coefi <= 5; coefi++) {
+ coef_bits_latch[coefi] = coef_bits[coefi];
+ if (coef_bits[coefi] != 0)
+ smoothing_useful = TRUE;
+ }
+ coef_bits_latch += SAVED_COEFS;
+ }
+
+ return smoothing_useful;
+}
+
+
+/*
+ * Variant of decompress_data for use when doing block smoothing.
+ */
+
+METHODDEF(int)
+decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
+{
+ my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
+ JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
+ JDIMENSION block_num, last_block_column;
+ int ci, block_row, block_rows, access_rows;
+ JBLOCKARRAY buffer;
+ JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
+ JSAMPARRAY output_ptr;
+ JDIMENSION output_col;
+ jpeg_component_info *compptr;
+ inverse_DCT_method_ptr inverse_DCT;
+ boolean first_row, last_row;
+ JBLOCK workspace;
+ int *coef_bits;
+ JTQUANT_TBL *quanttbl;
+ INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
+ int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
+ int Al, pred;
+
+ /* Force some input to be done if we are getting ahead of the input. */
+ while (cinfo->input_scan_number <= cinfo->output_scan_number &&
+ ! cinfo->inputctl->eoi_reached) {
+ if (cinfo->input_scan_number == cinfo->output_scan_number) {
+ /* If input is working on current scan, we ordinarily want it to
+ * have completed the current row. But if input scan is DC,
+ * we want it to keep one row ahead so that next block row's DC
+ * values are up to date.
+ */
+ JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
+ if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta)
+ break;
+ }
+ if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
+ return JPEG_SUSPENDED;
+ }
+
+ /* OK, output from the virtual arrays. */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Don't bother to IDCT an uninteresting component. */
+ if (! compptr->component_needed)
+ continue;
+ /* Count non-dummy DCT block rows in this iMCU row. */
+ if (cinfo->output_iMCU_row < last_iMCU_row) {
+ block_rows = compptr->v_samp_factor;
+ access_rows = block_rows * 2; /* this and next iMCU row */
+ last_row = FALSE;
+ } else {
+ /* NB: can't use last_row_height here; it is input-side-dependent! */
+ block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+ if (block_rows == 0) block_rows = compptr->v_samp_factor;
+ access_rows = block_rows; /* this iMCU row only */
+ last_row = TRUE;
+ }
+ /* Align the virtual buffer for this component. */
+ if (cinfo->output_iMCU_row > 0) {
+ access_rows += compptr->v_samp_factor; /* prior iMCU row too */
+ buffer = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[ci],
+ (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
+ (JDIMENSION) access_rows, FALSE);
+ buffer += compptr->v_samp_factor; /* point to current iMCU row */
+ first_row = FALSE;
+ } else {
+ buffer = (*cinfo->mem->access_virt_barray)
+ ((j_common_ptr) cinfo, coef->whole_image[ci],
+ (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
+ first_row = TRUE;
+ }
+ /* Fetch component-dependent info */
+ coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
+ quanttbl = compptr->quant_table;
+ Q00 = quanttbl->quantval[0];
+ Q01 = quanttbl->quantval[Q01_POS];
+ Q10 = quanttbl->quantval[Q10_POS];
+ Q20 = quanttbl->quantval[Q20_POS];
+ Q11 = quanttbl->quantval[Q11_POS];
+ Q02 = quanttbl->quantval[Q02_POS];
+ inverse_DCT = cinfo->idct->inverse_DCT[ci];
+ output_ptr = output_buf[ci];
+ /* Loop over all DCT blocks to be processed. */
+ for (block_row = 0; block_row < block_rows; block_row++) {
+ buffer_ptr = buffer[block_row];
+ if (first_row && block_row == 0)
+ prev_block_row = buffer_ptr;
+ else
+ prev_block_row = buffer[block_row-1];
+ if (last_row && block_row == block_rows-1)
+ next_block_row = buffer_ptr;
+ else
+ next_block_row = buffer[block_row+1];
+ /* We fetch the surrounding DC values using a sliding-register approach.
+ * Initialize all nine here so as to do the right thing on narrow pics.
+ */
+ DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
+ DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
+ DC7 = DC8 = DC9 = (int) next_block_row[0][0];
+ output_col = 0;
+ last_block_column = compptr->width_in_blocks - 1;
+ for (block_num = 0; block_num <= last_block_column; block_num++) {
+ /* Fetch current DCT block into workspace so we can modify it. */
+ jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
+ /* Update DC values */
+ if (block_num < last_block_column) {
+ DC3 = (int) prev_block_row[1][0];
+ DC6 = (int) buffer_ptr[1][0];
+ DC9 = (int) next_block_row[1][0];
+ }
+ /* Compute coefficient estimates per K.8.
+ * An estimate is applied only if coefficient is still zero,
+ * and is not known to be fully accurate.
+ */
+ /* AC01 */
+ if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) {
+ num = 36 * Q00 * (DC4 - DC6);
+ if (num >= 0) {
+ pred = (int) (((Q01<<7) + num) / (Q01<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ } else {
+ pred = (int) (((Q01<<7) - num) / (Q01<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ pred = -pred;
+ }
+ workspace[1] = (JCOEF) pred;
+ }
+ /* AC10 */
+ if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) {
+ num = 36 * Q00 * (DC2 - DC8);
+ if (num >= 0) {
+ pred = (int) (((Q10<<7) + num) / (Q10<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ } else {
+ pred = (int) (((Q10<<7) - num) / (Q10<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ pred = -pred;
+ }
+ workspace[8] = (JCOEF) pred;
+ }
+ /* AC20 */
+ if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) {
+ num = 9 * Q00 * (DC2 + DC8 - 2*DC5);
+ if (num >= 0) {
+ pred = (int) (((Q20<<7) + num) / (Q20<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ } else {
+ pred = (int) (((Q20<<7) - num) / (Q20<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ pred = -pred;
+ }
+ workspace[16] = (JCOEF) pred;
+ }
+ /* AC11 */
+ if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) {
+ num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
+ if (num >= 0) {
+ pred = (int) (((Q11<<7) + num) / (Q11<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ } else {
+ pred = (int) (((Q11<<7) - num) / (Q11<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ pred = -pred;
+ }
+ workspace[9] = (JCOEF) pred;
+ }
+ /* AC02 */
+ if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) {
+ num = 9 * Q00 * (DC4 + DC6 - 2*DC5);
+ if (num >= 0) {
+ pred = (int) (((Q02<<7) + num) / (Q02<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ } else {
+ pred = (int) (((Q02<<7) - num) / (Q02<<8));
+ if (Al > 0 && pred >= (1<<Al))
+ pred = (1<<Al)-1;
+ pred = -pred;
+ }
+ workspace[2] = (JCOEF) pred;
+ }
+ /* OK, do the IDCT */
+ (*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace,
+ output_ptr, output_col);
+ /* Advance for next column */
+ DC1 = DC2; DC2 = DC3;
+ DC4 = DC5; DC5 = DC6;
+ DC7 = DC8; DC8 = DC9;
+ buffer_ptr++, prev_block_row++, next_block_row++;
+ output_col += compptr->DCT_scaled_size;
+ }
+ output_ptr += compptr->DCT_scaled_size;
+ }
+ }
+
+ if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
+ return JPEG_ROW_COMPLETED;
+ return JPEG_SCAN_COMPLETED;
+}
+
+#endif /* BLOCK_SMOOTHING_SUPPORTED */
+
+
+/*
+ * Initialize coefficient buffer controller.
+ */
+
+GLOBAL(void)
+jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
+{
+ my_coef_ptr coef;
+
+ coef = (my_coef_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_coef_controller));
+ cinfo->coef = (struct jpeg_d_coef_controller *) coef;
+ coef->pub.start_input_pass = start_input_pass;
+ coef->pub.start_output_pass = start_output_pass;
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+ coef->coef_bits_latch = NULL;
+#endif
+
+ /* Create the coefficient buffer. */
+ if (need_full_buffer) {
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+ /* Allocate a full-image virtual array for each component, */
+ /* padded to a multiple of samp_factor DCT blocks in each direction. */
+ /* Note we ask for a pre-zeroed array. */
+ int ci, access_rows;
+ jpeg_component_info *compptr;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ access_rows = compptr->v_samp_factor;
+#ifdef BLOCK_SMOOTHING_SUPPORTED
+ /* If block smoothing could be used, need a bigger window */
+ if (cinfo->progressive_mode)
+ access_rows *= 3;
+#endif
+ coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
+ (JDIMENSION) jround_up((long) compptr->width_in_blocks,
+ (long) compptr->h_samp_factor),
+ (JDIMENSION) jround_up((long) compptr->height_in_blocks,
+ (long) compptr->v_samp_factor),
+ (JDIMENSION) access_rows);
+ }
+ coef->pub.consume_data = consume_data;
+ coef->pub.decompress_data = decompress_data;
+ coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ /* We only need a single-MCU buffer. */
+ JBLOCKROW buffer;
+ int i;
+
+ buffer = (JBLOCKROW)
+ (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
+ for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
+ coef->MCU_buffer[i] = buffer + i;
+ }
+ coef->pub.consume_data = dummy_consume_data;
+ coef->pub.decompress_data = decompress_onepass;
+ coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdcolor.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdcolor.c
new file mode 100644
index 0000000..7a2e524
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdcolor.c
@@ -0,0 +1,396 @@
+/*
+ * jdcolor.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains output colorspace conversion routines.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_color_deconverter pub; /* public fields */
+
+ /* Private state for YCC->RGB conversion */
+ int * Cr_r_tab; /* => table for Cr to R conversion */
+ int * Cb_b_tab; /* => table for Cb to B conversion */
+ INT32 * Cr_g_tab; /* => table for Cr to G conversion */
+ INT32 * Cb_g_tab; /* => table for Cb to G conversion */
+} my_color_deconverter;
+
+typedef my_color_deconverter * my_cconvert_ptr;
+
+
+/**************** YCbCr -> RGB conversion: most common case **************/
+
+/*
+ * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
+ * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
+ * The conversion equations to be implemented are therefore
+ * R = Y + 1.40200 * Cr
+ * G = Y - 0.34414 * Cb - 0.71414 * Cr
+ * B = Y + 1.77200 * Cb
+ * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
+ * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
+ *
+ * To avoid floating-point arithmetic, we represent the fractional constants
+ * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
+ * the products by 2^16, with appropriate rounding, to get the correct answer.
+ * Notice that Y, being an integral input, does not contribute any fraction
+ * so it need not participate in the rounding.
+ *
+ * For even more speed, we avoid doing any multiplications in the inner loop
+ * by precalculating the constants times Cb and Cr for all possible values.
+ * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
+ * for 12-bit samples it is still acceptable. It's not very reasonable for
+ * 16-bit samples, but if you want lossless storage you shouldn't be changing
+ * colorspace anyway.
+ * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
+ * values for the G calculation are left scaled up, since we must add them
+ * together before rounding.
+ */
+
+#define SCALEBITS 16 /* speediest right-shift on some machines */
+#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
+#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
+
+
+/*
+ * Initialize tables for YCC->RGB colorspace conversion.
+ */
+
+LOCAL(void)
+build_ycc_rgb_table (j_decompress_ptr cinfo)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ int i;
+ INT32 x;
+ SHIFT_TEMPS
+
+ cconvert->Cr_r_tab = (int *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(int));
+ cconvert->Cb_b_tab = (int *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(int));
+ cconvert->Cr_g_tab = (INT32 *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(INT32));
+ cconvert->Cb_g_tab = (INT32 *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(INT32));
+
+ for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
+ /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
+ /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
+ /* Cr=>R value is nearest int to 1.40200 * x */
+ cconvert->Cr_r_tab[i] = (int)
+ RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
+ /* Cb=>B value is nearest int to 1.77200 * x */
+ cconvert->Cb_b_tab[i] = (int)
+ RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
+ /* Cr=>G value is scaled-up -0.71414 * x */
+ cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
+ /* Cb=>G value is scaled-up -0.34414 * x */
+ /* We also add in ONE_HALF so that need not do it in inner loop */
+ cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
+ }
+}
+
+
+/*
+ * Convert some rows of samples to the output colorspace.
+ *
+ * Note that we change from noninterleaved, one-plane-per-component format
+ * to interleaved-pixel format. The output buffer is therefore three times
+ * as wide as the input buffer.
+ * A starting row offset is provided only for the input buffer. The caller
+ * can easily adjust the passed output_buf value to accommodate any row
+ * offset required on that side.
+ */
+
+METHODDEF(void)
+ycc_rgb_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ register int y, cb, cr;
+ register JSAMPROW outptr;
+ register JSAMPROW inptr0, inptr1, inptr2;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->output_width;
+ /* copy these pointers into registers if possible */
+ register JSAMPLE * range_limit = cinfo->sample_range_limit;
+ register int * Crrtab = cconvert->Cr_r_tab;
+ register int * Cbbtab = cconvert->Cb_b_tab;
+ register INT32 * Crgtab = cconvert->Cr_g_tab;
+ register INT32 * Cbgtab = cconvert->Cb_g_tab;
+ SHIFT_TEMPS
+
+ while (--num_rows >= 0) {
+ inptr0 = input_buf[0][input_row];
+ inptr1 = input_buf[1][input_row];
+ inptr2 = input_buf[2][input_row];
+ input_row++;
+ outptr = *output_buf++;
+ for (col = 0; col < num_cols; col++) {
+ y = GETJSAMPLE(inptr0[col]);
+ cb = GETJSAMPLE(inptr1[col]);
+ cr = GETJSAMPLE(inptr2[col]);
+ /* Range-limiting is essential due to noise introduced by DCT losses. */
+ outptr[RGB_RED] = range_limit[y + Crrtab[cr]];
+ outptr[RGB_GREEN] = range_limit[y +
+ ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
+ SCALEBITS))];
+ outptr[RGB_BLUE] = range_limit[y + Cbbtab[cb]];
+ outptr += RGB_PIXELSIZE;
+ }
+ }
+}
+
+
+/**************** Cases other than YCbCr -> RGB **************/
+
+
+/*
+ * Color conversion for no colorspace change: just copy the data,
+ * converting from separate-planes to interleaved representation.
+ */
+
+METHODDEF(void)
+null_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ register JSAMPROW inptr, outptr;
+ register JDIMENSION count;
+ register int num_components = cinfo->num_components;
+ JDIMENSION num_cols = cinfo->output_width;
+ int ci;
+
+ while (--num_rows >= 0) {
+ for (ci = 0; ci < num_components; ci++) {
+ inptr = input_buf[ci][input_row];
+ outptr = output_buf[0] + ci;
+ for (count = num_cols; count > 0; count--) {
+ *outptr = *inptr++; /* needn't bother with GETJSAMPLE() here */
+ outptr += num_components;
+ }
+ }
+ input_row++;
+ output_buf++;
+ }
+}
+
+
+/*
+ * Color conversion for grayscale: just copy the data.
+ * This also works for YCbCr -> grayscale conversion, in which
+ * we just copy the Y (luminance) component and ignore chrominance.
+ */
+
+METHODDEF(void)
+grayscale_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
+ num_rows, cinfo->output_width);
+}
+
+
+/*
+ * Convert grayscale to RGB: just duplicate the graylevel three times.
+ * This is provided to support applications that don't want to cope
+ * with grayscale as a separate case.
+ */
+
+METHODDEF(void)
+gray_rgb_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ register JSAMPROW inptr, outptr;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->output_width;
+
+ while (--num_rows >= 0) {
+ inptr = input_buf[0][input_row++];
+ outptr = *output_buf++;
+ for (col = 0; col < num_cols; col++) {
+ /* We can dispense with GETJSAMPLE() here */
+ outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
+ outptr += RGB_PIXELSIZE;
+ }
+ }
+}
+
+
+/*
+ * Adobe-style YCCK->CMYK conversion.
+ * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
+ * conversion as above, while passing K (black) unchanged.
+ * We assume build_ycc_rgb_table has been called.
+ */
+
+METHODDEF(void)
+ycck_cmyk_convert (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
+ register int y, cb, cr;
+ register JSAMPROW outptr;
+ register JSAMPROW inptr0, inptr1, inptr2, inptr3;
+ register JDIMENSION col;
+ JDIMENSION num_cols = cinfo->output_width;
+ /* copy these pointers into registers if possible */
+ register JSAMPLE * range_limit = cinfo->sample_range_limit;
+ register int * Crrtab = cconvert->Cr_r_tab;
+ register int * Cbbtab = cconvert->Cb_b_tab;
+ register INT32 * Crgtab = cconvert->Cr_g_tab;
+ register INT32 * Cbgtab = cconvert->Cb_g_tab;
+ SHIFT_TEMPS
+
+ while (--num_rows >= 0) {
+ inptr0 = input_buf[0][input_row];
+ inptr1 = input_buf[1][input_row];
+ inptr2 = input_buf[2][input_row];
+ inptr3 = input_buf[3][input_row];
+ input_row++;
+ outptr = *output_buf++;
+ for (col = 0; col < num_cols; col++) {
+ y = GETJSAMPLE(inptr0[col]);
+ cb = GETJSAMPLE(inptr1[col]);
+ cr = GETJSAMPLE(inptr2[col]);
+ /* Range-limiting is essential due to noise introduced by DCT losses. */
+ outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */
+ outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */
+ ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
+ SCALEBITS)))];
+ outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */
+ /* K passes through unchanged */
+ outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */
+ outptr += 4;
+ }
+ }
+}
+
+
+/*
+ * Empty method for start_pass.
+ */
+
+METHODDEF(void)
+start_pass_dcolor (j_decompress_ptr cinfo)
+{
+ /* no work needed */
+}
+
+
+/*
+ * Module initialization routine for output colorspace conversion.
+ */
+
+GLOBAL(void)
+jinit_color_deconverter (j_decompress_ptr cinfo)
+{
+ my_cconvert_ptr cconvert;
+ int ci;
+
+ cconvert = (my_cconvert_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_color_deconverter));
+ cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
+ cconvert->pub.start_pass = start_pass_dcolor;
+
+ /* Make sure num_components agrees with jpeg_color_space */
+ switch (cinfo->jpeg_color_space) {
+ case JCS_GRAYSCALE:
+ if (cinfo->num_components != 1)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ break;
+
+ case JCS_RGB:
+ case JCS_YCbCr:
+ if (cinfo->num_components != 3)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ break;
+
+ case JCS_CMYK:
+ case JCS_YCCK:
+ if (cinfo->num_components != 4)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ break;
+
+ default: /* JCS_UNKNOWN can be anything */
+ if (cinfo->num_components < 1)
+ ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
+ break;
+ }
+
+ /* Set out_color_components and conversion method based on requested space.
+ * Also clear the component_needed flags for any unused components,
+ * so that earlier pipeline stages can avoid useless computation.
+ */
+
+ switch (cinfo->out_color_space) {
+ case JCS_GRAYSCALE:
+ cinfo->out_color_components = 1;
+ if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
+ cinfo->jpeg_color_space == JCS_YCbCr) {
+ cconvert->pub.color_convert = grayscale_convert;
+ /* For color->grayscale conversion, only the Y (0) component is needed */
+ for (ci = 1; ci < cinfo->num_components; ci++)
+ cinfo->comp_info[ci].component_needed = FALSE;
+ } else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_RGB:
+ cinfo->out_color_components = RGB_PIXELSIZE;
+ if (cinfo->jpeg_color_space == JCS_YCbCr) {
+ cconvert->pub.color_convert = ycc_rgb_convert;
+ build_ycc_rgb_table(cinfo);
+ } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
+ cconvert->pub.color_convert = gray_rgb_convert;
+ } else if (cinfo->jpeg_color_space == JCS_RGB && RGB_PIXELSIZE == 3) {
+ cconvert->pub.color_convert = null_convert;
+ } else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ case JCS_CMYK:
+ cinfo->out_color_components = 4;
+ if (cinfo->jpeg_color_space == JCS_YCCK) {
+ cconvert->pub.color_convert = ycck_cmyk_convert;
+ build_ycc_rgb_table(cinfo);
+ } else if (cinfo->jpeg_color_space == JCS_CMYK) {
+ cconvert->pub.color_convert = null_convert;
+ } else
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+
+ default:
+ /* Permit null conversion to same output space */
+ if (cinfo->out_color_space == cinfo->jpeg_color_space) {
+ cinfo->out_color_components = cinfo->num_components;
+ cconvert->pub.color_convert = null_convert;
+ } else /* unsupported non-null conversion */
+ ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
+ break;
+ }
+
+ if (cinfo->quantize_colors)
+ cinfo->output_components = 1; /* single colormapped output component */
+ else
+ cinfo->output_components = cinfo->out_color_components;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdct.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jdct.h
new file mode 100644
index 0000000..76cda5e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdct.h
@@ -0,0 +1,176 @@
+/*
+ * jdct.h
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This include file tqcontains common declarations for the forward and
+ * inverse DCT modules. These declarations are private to the DCT managers
+ * (jcdctmgr.c, jddctmgr.c) and the individual DCT algorithms.
+ * The individual DCT algorithms are kept in separate files to ease
+ * machine-dependent tuning (e.g., assembly coding).
+ */
+
+
+/*
+ * A forward DCT routine is given a pointer to a work area of type DCTELEM[];
+ * the DCT is to be performed in-place in that buffer. Type DCTELEM is int
+ * for 8-bit samples, INT32 for 12-bit samples. (NOTE: Floating-point DCT
+ * implementations use an array of type FAST_FLOAT, instead.)
+ * The DCT inputs are expected to be signed (range +-CENTERJSAMPLE).
+ * The DCT outputs are returned scaled up by a factor of 8; they therefore
+ * have a range of +-8K for 8-bit data, +-128K for 12-bit data. This
+ * convention improves accuracy in integer implementations and saves some
+ * work in floating-point ones.
+ * Quantization of the output coefficients is done by jcdctmgr.c.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+typedef int DCTELEM; /* 16 or 32 bits is fine */
+#else
+typedef INT32 DCTELEM; /* must have 32 bits */
+#endif
+
+typedef JTQT_METHOD(void, forward_DCT_method_ptr, (DCTELEM * data));
+typedef JTQT_METHOD(void, float_DCT_method_ptr, (FAST_FLOAT * data));
+
+
+/*
+ * An inverse DCT routine is given a pointer to the input JBLOCK and a pointer
+ * to an output sample array. The routine must dequantize the input data as
+ * well as perform the IDCT; for dequantization, it uses the multiplier table
+ * pointed to by compptr->dct_table. The output data is to be placed into the
+ * sample array starting at a specified column. (Any row offset needed will
+ * be applied to the array pointer before it is passed to the IDCT code.)
+ * Note that the number of samples emitted by the IDCT routine is
+ * DCT_scaled_size * DCT_scaled_size.
+ */
+
+/* typedef inverse_DCT_method_ptr is declared in jpegint.h */
+
+/*
+ * Each IDCT routine has its own ideas about the best dct_table element type.
+ */
+
+typedef MULTIPLIER ISLOW_MULT_TYPE; /* short or int, whichever is faster */
+#if BITS_IN_JSAMPLE == 8
+typedef MULTIPLIER IFAST_MULT_TYPE; /* 16 bits is OK, use short if faster */
+#define IFAST_SCALE_BITS 2 /* fractional bits in scale factors */
+#else
+typedef INT32 IFAST_MULT_TYPE; /* need 32 bits for scaled quantizers */
+#define IFAST_SCALE_BITS 13 /* fractional bits in scale factors */
+#endif
+typedef FAST_FLOAT FLOAT_MULT_TYPE; /* preferred floating type */
+
+
+/*
+ * Each IDCT routine is responsible for range-limiting its results and
+ * converting them to unsigned form (0..MAXJSAMPLE). The raw outputs could
+ * be quite far out of range if the input data is corrupt, so a bulletproof
+ * range-limiting step is required. We use a tqmask-and-table-lookup method
+ * to do the combined operations quickly. See the comments with
+ * prepare_range_limit_table (in jdmaster.c) for more info.
+ */
+
+#define IDCT_range_limit(cinfo) ((cinfo)->sample_range_limit + CENTERJSAMPLE)
+
+#define RANGE_MASK (MAXJSAMPLE * 4 + 3) /* 2 bits wider than legal samples */
+
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_fdct_islow jFDislow
+#define jpeg_fdct_ifast jFDifast
+#define jpeg_fdct_float jFDfloat
+#define jpeg_idct_islow jRDislow
+#define jpeg_idct_ifast jRDifast
+#define jpeg_idct_float jRDfloat
+#define jpeg_idct_4x4 jRD4x4
+#define jpeg_idct_2x2 jRD2x2
+#define jpeg_idct_1x1 jRD1x1
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+/* Extern declarations for the forward and inverse DCT routines. */
+
+EXTERN(void) jpeg_fdct_islow JPP((DCTELEM * data));
+EXTERN(void) jpeg_fdct_ifast JPP((DCTELEM * data));
+EXTERN(void) jpeg_fdct_float JPP((FAST_FLOAT * data));
+
+EXTERN(void) jpeg_idct_islow
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_ifast
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_float
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_4x4
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_2x2
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+EXTERN(void) jpeg_idct_1x1
+ JPP((j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block, JSAMPARRAY output_buf, JDIMENSION output_col));
+
+
+/*
+ * Macros for handling fixed-point arithmetic; these are used by many
+ * but not all of the DCT/IDCT modules.
+ *
+ * All values are expected to be of type INT32.
+ * Fractional constants are scaled left by CONST_BITS bits.
+ * CONST_BITS is defined within each module using these macros,
+ * and may differ from one module to the next.
+ */
+
+#define ONE ((INT32) 1)
+#define CONST_SCALE (ONE << CONST_BITS)
+
+/* Convert a positive real constant to an integer scaled by CONST_SCALE.
+ * Caution: some C compilers fail to reduce "FIX(constant)" at compile time,
+ * thus causing a lot of useless floating-point operations at run time.
+ */
+
+#define FIX(x) ((INT32) ((x) * CONST_SCALE + 0.5))
+
+/* Descale and correctly round an INT32 value that's scaled by N bits.
+ * We assume RIGHT_SHIFT rounds towards minus infinity, so adding
+ * the fudge factor is correct for either sign of X.
+ */
+
+#define DESCALE(x,n) RIGHT_SHIFT((x) + (ONE << ((n)-1)), n)
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * This macro is used only when the two inputs will actually be no more than
+ * 16 bits wide, so that a 16x16->32 bit multiply can be used instead of a
+ * full 32x32 multiply. This provides a useful speedup on many machines.
+ * Unfortunately there is no way to specify a 16x16->32 multiply portably
+ * in C, but some C compilers will do the right thing if you provide the
+ * correct combination of casts.
+ */
+
+#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
+#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT16) (const)))
+#endif
+#ifdef SHORTxLCONST_32 /* known to work with Microsoft C 6.0 */
+#define MULTIPLY16C16(var,const) (((INT16) (var)) * ((INT32) (const)))
+#endif
+
+#ifndef MULTIPLY16C16 /* default definition */
+#define MULTIPLY16C16(var,const) ((var) * (const))
+#endif
+
+/* Same except both inputs are variables. */
+
+#ifdef SHORTxSHORT_32 /* may work if 'int' is 32 bits */
+#define MULTIPLY16V16(var1,var2) (((INT16) (var1)) * ((INT16) (var2)))
+#endif
+
+#ifndef MULTIPLY16V16 /* default definition */
+#define MULTIPLY16V16(var1,var2) ((var1) * (var2))
+#endif
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jddctmgr.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jddctmgr.c
new file mode 100644
index 0000000..626ad6c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jddctmgr.c
@@ -0,0 +1,269 @@
+/*
+ * jddctmgr.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains the inverse-DCT management logic.
+ * This code selects a particular IDCT implementation to be used,
+ * and it performs related housekeeping chores. No code in this file
+ * is executed per IDCT step, only during output pass setup.
+ *
+ * Note that the IDCT routines are responsible for performing coefficient
+ * dequantization as well as the IDCT proper. This module sets up the
+ * dequantization multiplier table needed by the IDCT routine.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+
+/*
+ * The decompressor input side (jdinput.c) saves away the appropriate
+ * quantization table for each component at the start of the first scan
+ * involving that component. (This is necessary in order to correctly
+ * decode files that reuse Q-table Q_SLOTS.)
+ * When we are ready to make an output pass, the saved Q-table is converted
+ * to a multiplier table that will actually be used by the IDCT routine.
+ * The multiplier table contents are IDCT-method-dependent. To support
+ * application changes in IDCT method between scans, we can remake the
+ * multiplier tables if necessary.
+ * In buffered-image mode, the first output pass may occur before any data
+ * has been seen for some components, and thus before their Q-tables have
+ * been saved away. To handle this case, multiplier tables are preset
+ * to zeroes; the result of the IDCT will be a neutral gray level.
+ */
+
+
+/* Private subobject for this module */
+
+typedef struct {
+ struct jpeg_inverse_dct pub; /* public fields */
+
+ /* This array tqcontains the IDCT method code that each multiplier table
+ * is currently set up for, or -1 if it's not yet set up.
+ * The actual multiplier tables are pointed to by dct_table in the
+ * per-component comp_info structures.
+ */
+ int cur_method[MAX_COMPONENTS];
+} my_idct_controller;
+
+typedef my_idct_controller * my_idct_ptr;
+
+
+/* Allocated multiplier tables: big enough for any supported variant */
+
+typedef union {
+ ISLOW_MULT_TYPE islow_array[DCTSIZE2];
+#ifdef DCT_IFAST_SUPPORTED
+ IFAST_MULT_TYPE ifast_array[DCTSIZE2];
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ FLOAT_MULT_TYPE float_array[DCTSIZE2];
+#endif
+} multiplier_table;
+
+
+/* The current scaled-IDCT routines require ISLOW-style multiplier tables,
+ * so be sure to compile that code if either ISLOW or SCALING is requested.
+ */
+#ifdef DCT_ISLOW_SUPPORTED
+#define PROVIDE_ISLOW_TABLES
+#else
+#ifdef IDCT_SCALING_SUPPORTED
+#define PROVIDE_ISLOW_TABLES
+#endif
+#endif
+
+
+/*
+ * Prepare for an output pass.
+ * Here we select the proper IDCT routine for each component and build
+ * a matching multiplier table.
+ */
+
+METHODDEF(void)
+start_pass (j_decompress_ptr cinfo)
+{
+ my_idct_ptr idct = (my_idct_ptr) cinfo->idct;
+ int ci, i;
+ jpeg_component_info *compptr;
+ int method = 0;
+ inverse_DCT_method_ptr method_ptr = NULL;
+ JTQUANT_TBL * qtbl;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Select the proper IDCT routine for this component's scaling */
+ switch (compptr->DCT_scaled_size) {
+#ifdef IDCT_SCALING_SUPPORTED
+ case 1:
+ method_ptr = jpeg_idct_1x1;
+ method = JDCT_ISLOW; /* jidctred uses islow-style table */
+ break;
+ case 2:
+ method_ptr = jpeg_idct_2x2;
+ method = JDCT_ISLOW; /* jidctred uses islow-style table */
+ break;
+ case 4:
+ method_ptr = jpeg_idct_4x4;
+ method = JDCT_ISLOW; /* jidctred uses islow-style table */
+ break;
+#endif
+ case DCTSIZE:
+ switch (cinfo->dct_method) {
+#ifdef DCT_ISLOW_SUPPORTED
+ case JDCT_ISLOW:
+ method_ptr = jpeg_idct_islow;
+ method = JDCT_ISLOW;
+ break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+ case JDCT_IFAST:
+ method_ptr = jpeg_idct_ifast;
+ method = JDCT_IFAST;
+ break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ case JDCT_FLOAT:
+ method_ptr = jpeg_idct_float;
+ method = JDCT_FLOAT;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+ break;
+ default:
+ ERREXIT1(cinfo, JERR_BAD_DCTSIZE, compptr->DCT_scaled_size);
+ break;
+ }
+ idct->pub.inverse_DCT[ci] = method_ptr;
+ /* Create multiplier table from quant table.
+ * However, we can skip this if the component is uninteresting
+ * or if we already built the table. Also, if no quant table
+ * has yet been saved for the component, we leave the
+ * multiplier table all-zero; we'll be reading zeroes from the
+ * coefficient controller's buffer anyway.
+ */
+ if (! compptr->component_needed || idct->cur_method[ci] == method)
+ continue;
+ qtbl = compptr->quant_table;
+ if (qtbl == NULL) /* happens if no data yet for component */
+ continue;
+ idct->cur_method[ci] = method;
+ switch (method) {
+#ifdef PROVIDE_ISLOW_TABLES
+ case JDCT_ISLOW:
+ {
+ /* For LL&M IDCT method, multipliers are equal to raw quantization
+ * coefficients, but are stored as ints to ensure access efficiency.
+ */
+ ISLOW_MULT_TYPE * ismtbl = (ISLOW_MULT_TYPE *) compptr->dct_table;
+ for (i = 0; i < DCTSIZE2; i++) {
+ ismtbl[i] = (ISLOW_MULT_TYPE) qtbl->quantval[i];
+ }
+ }
+ break;
+#endif
+#ifdef DCT_IFAST_SUPPORTED
+ case JDCT_IFAST:
+ {
+ /* For AA&N IDCT method, multipliers are equal to quantization
+ * coefficients scaled by scalefactor[row]*scalefactor[col], where
+ * scalefactor[0] = 1
+ * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
+ * For integer operation, the multiplier table is to be scaled by
+ * IFAST_SCALE_BITS.
+ */
+ IFAST_MULT_TYPE * ifmtbl = (IFAST_MULT_TYPE *) compptr->dct_table;
+#define CONST_BITS 14
+ static const INT16 aanscales[DCTSIZE2] = {
+ /* precomputed values scaled up by 14 bits */
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270,
+ 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906,
+ 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315,
+ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520,
+ 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552,
+ 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446,
+ 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247
+ };
+ SHIFT_TEMPS
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ ifmtbl[i] = (IFAST_MULT_TYPE)
+ DESCALE(MULTIPLY16V16((INT32) qtbl->quantval[i],
+ (INT32) aanscales[i]),
+ CONST_BITS-IFAST_SCALE_BITS);
+ }
+ }
+ break;
+#endif
+#ifdef DCT_FLOAT_SUPPORTED
+ case JDCT_FLOAT:
+ {
+ /* For float AA&N IDCT method, multipliers are equal to quantization
+ * coefficients scaled by scalefactor[row]*scalefactor[col], where
+ * scalefactor[0] = 1
+ * scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7
+ */
+ FLOAT_MULT_TYPE * fmtbl = (FLOAT_MULT_TYPE *) compptr->dct_table;
+ int row, col;
+ static const double aanscalefactor[DCTSIZE] = {
+ 1.0, 1.387039845, 1.306562965, 1.175875602,
+ 1.0, 0.785694958, 0.541196100, 0.275899379
+ };
+
+ i = 0;
+ for (row = 0; row < DCTSIZE; row++) {
+ for (col = 0; col < DCTSIZE; col++) {
+ fmtbl[i] = (FLOAT_MULT_TYPE)
+ ((double) qtbl->quantval[i] *
+ aanscalefactor[row] * aanscalefactor[col]);
+ i++;
+ }
+ }
+ }
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+ }
+}
+
+
+/*
+ * Initialize IDCT manager.
+ */
+
+GLOBAL(void)
+jinit_inverse_dct (j_decompress_ptr cinfo)
+{
+ my_idct_ptr idct;
+ int ci;
+ jpeg_component_info *compptr;
+
+ idct = (my_idct_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_idct_controller));
+ cinfo->idct = (struct jpeg_inverse_dct *) idct;
+ idct->pub.start_pass = start_pass;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Allocate and pre-zero a multiplier table for each component */
+ compptr->dct_table =
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(multiplier_table));
+ MEMZERO(compptr->dct_table, SIZEOF(multiplier_table));
+ /* Mark multiplier table not yet set up for any method */
+ idct->cur_method[ci] = -1;
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdhuff.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdhuff.c
new file mode 100644
index 0000000..883e3a0
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdhuff.c
@@ -0,0 +1,651 @@
+/*
+ * jdhuff.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains Huffman entropy decoding routines.
+ *
+ * Much of the complexity here has to do with supporting input suspension.
+ * If the data source module demands suspension, we want to be able to back
+ * up to the start of the current MCU. To do this, we copy state variables
+ * into local working storage, and update them back to the permanent
+ * storage only upon successful completion of an MCU.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdhuff.h" /* Declarations shared with jdphuff.c */
+
+
+/*
+ * Expanded entropy decoder object for Huffman decoding.
+ *
+ * The savable_state subrecord tqcontains fields that change within an MCU,
+ * but must not be updated permanently until we complete the MCU.
+ */
+
+typedef struct {
+ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+} savable_state;
+
+/* This macro is to work around compilers with missing or broken
+ * structure assignment. You'll need to fix this code if you have
+ * such a compiler and you change MAX_COMPS_IN_SCAN.
+ */
+
+#ifndef NO_STRUCT_ASSIGN
+#define ASSIGN_STATE(dest,src) ((dest) = (src))
+#else
+#if MAX_COMPS_IN_SCAN == 4
+#define ASSIGN_STATE(dest,src) \
+ ((dest).last_dc_val[0] = (src).last_dc_val[0], \
+ (dest).last_dc_val[1] = (src).last_dc_val[1], \
+ (dest).last_dc_val[2] = (src).last_dc_val[2], \
+ (dest).last_dc_val[3] = (src).last_dc_val[3])
+#endif
+#endif
+
+
+typedef struct {
+ struct jpeg_entropy_decoder pub; /* public fields */
+
+ /* These fields are loaded into local variables at start of each MCU.
+ * In case of suspension, we exit WITHOUT updating them.
+ */
+ bitread_perm_state bitstate; /* Bit buffer at start of MCU */
+ savable_state saved; /* Other state at start of MCU */
+
+ /* These fields are NOT loaded into local working state. */
+ unsigned int restarts_to_go; /* MCUs left in this restart interval */
+
+ /* Pointers to derived tables (these workspaces have image lifespan) */
+ d_derived_tbl * dc_derived_tbls[NUM_HUFF_TBLS];
+ d_derived_tbl * ac_derived_tbls[NUM_HUFF_TBLS];
+
+ /* Precalculated info set up by start_pass for use in decode_mcu: */
+
+ /* Pointers to derived tables to be used for each block within an MCU */
+ d_derived_tbl * dc_cur_tbls[D_MAX_BLOCKS_IN_MCU];
+ d_derived_tbl * ac_cur_tbls[D_MAX_BLOCKS_IN_MCU];
+ /* Whether we care about the DC and AC coefficient values for each block */
+ boolean dc_needed[D_MAX_BLOCKS_IN_MCU];
+ boolean ac_needed[D_MAX_BLOCKS_IN_MCU];
+} huff_entropy_decoder;
+
+typedef huff_entropy_decoder * huff_entropy_ptr;
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ */
+
+METHODDEF(void)
+start_pass_huff_decoder (j_decompress_ptr cinfo)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int ci, blkn, dctbl, actbl;
+ jpeg_component_info * compptr;
+
+ /* Check that the scan parameters Ss, Se, Ah/Al are OK for sequential JPEG.
+ * This ought to be an error condition, but we make it a warning because
+ * there are some baseline files out there with all zeroes in these bytes.
+ */
+ if (cinfo->Ss != 0 || cinfo->Se != DCTSIZE2-1 ||
+ cinfo->Ah != 0 || cinfo->Al != 0)
+ WARNMS(cinfo, JWRN_NOT_SETQUENTIAL);
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ dctbl = compptr->dc_tbl_no;
+ actbl = compptr->ac_tbl_no;
+ /* Compute derived values for Huffman tables */
+ /* We may do this more than once for a table, but it's not expensive */
+ jpeg_make_d_derived_tbl(cinfo, TRUE, dctbl,
+ & entropy->dc_derived_tbls[dctbl]);
+ jpeg_make_d_derived_tbl(cinfo, FALSE, actbl,
+ & entropy->ac_derived_tbls[actbl]);
+ /* Initialize DC predictions to 0 */
+ entropy->saved.last_dc_val[ci] = 0;
+ }
+
+ /* Precalculate decoding info for each block in an MCU of this scan */
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+ /* Precalculate which table to use for each block */
+ entropy->dc_cur_tbls[blkn] = entropy->dc_derived_tbls[compptr->dc_tbl_no];
+ entropy->ac_cur_tbls[blkn] = entropy->ac_derived_tbls[compptr->ac_tbl_no];
+ /* Decide whether we really care about the coefficient values */
+ if (compptr->component_needed) {
+ entropy->dc_needed[blkn] = TRUE;
+ /* we don't need the ACs if producing a 1/8th-size image */
+ entropy->ac_needed[blkn] = (compptr->DCT_scaled_size > 1);
+ } else {
+ entropy->dc_needed[blkn] = entropy->ac_needed[blkn] = FALSE;
+ }
+ }
+
+ /* Initialize bitread state variables */
+ entropy->bitstate.bits_left = 0;
+ entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
+ entropy->pub.insufficient_data = FALSE;
+
+ /* Initialize restart counter */
+ entropy->restarts_to_go = cinfo->restart_interval;
+}
+
+
+/*
+ * Compute the derived values for a Huffman table.
+ * This routine also performs some validation checks on the table.
+ *
+ * Note this is also used by jdphuff.c.
+ */
+
+GLOBAL(void)
+jpeg_make_d_derived_tbl (j_decompress_ptr cinfo, boolean isDC, int tblno,
+ d_derived_tbl ** pdtbl)
+{
+ JHUFF_TBL *htbl;
+ d_derived_tbl *dtbl;
+ int p, i, l, si, numsymbols;
+ int lookbits, ctr;
+ char huffsize[257];
+ unsigned int huffcode[257];
+ unsigned int code;
+
+ /* Note that huffsize[] and huffcode[] are filled in code-length order,
+ * paralleling the order of the symbols themselves in htbl->huffval[].
+ */
+
+ /* Find the input Huffman table */
+ if (tblno < 0 || tblno >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+ htbl =
+ isDC ? cinfo->dc_huff_tbl_ptrs[tblno] : cinfo->ac_huff_tbl_ptrs[tblno];
+ if (htbl == NULL)
+ ERREXIT1(cinfo, JERR_NO_HUFF_TABLE, tblno);
+
+ /* Allocate a workspace if we haven't already done so. */
+ if (*pdtbl == NULL)
+ *pdtbl = (d_derived_tbl *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(d_derived_tbl));
+ dtbl = *pdtbl;
+ dtbl->pub = htbl; /* fill in back link */
+
+ /* Figure C.1: make table of Huffman code length for each symbol */
+
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ i = (int) htbl->bits[l];
+ if (i < 0 || p + i > 256) /* protect against table overrun */
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ while (i--)
+ huffsize[p++] = (char) l;
+ }
+ huffsize[p] = 0;
+ numsymbols = p;
+
+ /* Figure C.2: generate the codes themselves */
+ /* We also validate that the counts represent a legal Huffman code tree. */
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p]) {
+ while (((int) huffsize[p]) == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ /* code is now 1 more than the last code used for codelength si; but
+ * it must still fit in si bits, since no code is allowed to be all ones.
+ */
+ if (((INT32) code) >= (((INT32) 1) << si))
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ code <<= 1;
+ si++;
+ }
+
+ /* Figure F.15: generate decoding tables for bit-sequential decoding */
+
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ if (htbl->bits[l]) {
+ /* valoffset[l] = huffval[] index of 1st symbol of code length l,
+ * minus the minimum code of length l
+ */
+ dtbl->valoffset[l] = (INT32) p - (INT32) huffcode[p];
+ p += htbl->bits[l];
+ dtbl->maxcode[l] = huffcode[p-1]; /* maximum code of length l */
+ } else {
+ dtbl->maxcode[l] = -1; /* -1 if no codes of this length */
+ }
+ }
+ dtbl->maxcode[17] = 0xFFFFFL; /* ensures jpeg_huff_decode terminates */
+
+ /* Compute lookahead tables to speed up decoding.
+ * First we set all the table entries to 0, indicating "too long";
+ * then we iterate through the Huffman codes that are short enough and
+ * fill in all the entries that correspond to bit sequences starting
+ * with that code.
+ */
+
+ MEMZERO(dtbl->look_nbits, SIZEOF(dtbl->look_nbits));
+
+ p = 0;
+ for (l = 1; l <= HUFF_LOOKAHEAD; l++) {
+ for (i = 1; i <= (int) htbl->bits[l]; i++, p++) {
+ /* l = current code's length, p = its index in huffcode[] & huffval[]. */
+ /* Generate left-justified code followed by all possible bit sequences */
+ lookbits = huffcode[p] << (HUFF_LOOKAHEAD-l);
+ for (ctr = 1 << (HUFF_LOOKAHEAD-l); ctr > 0; ctr--) {
+ dtbl->look_nbits[lookbits] = l;
+ dtbl->look_sym[lookbits] = htbl->huffval[p];
+ lookbits++;
+ }
+ }
+ }
+
+ /* Validate symbols as being reasonable.
+ * For AC tables, we make no check, but accept all byte values 0..255.
+ * For DC tables, we require the symbols to be in range 0..15.
+ * (Tighter bounds could be applied depending on the data depth and mode,
+ * but this is sufficient to ensure safe decoding.)
+ */
+ if (isDC) {
+ for (i = 0; i < numsymbols; i++) {
+ int sym = htbl->huffval[i];
+ if (sym < 0 || sym > 15)
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+ }
+ }
+}
+
+
+/*
+ * Out-of-line code for bit fetching (shared with jdphuff.c).
+ * See jdhuff.h for info about usage.
+ * Note: current values of get_buffer and bits_left are passed as parameters,
+ * but are returned in the corresponding fields of the state struct.
+ *
+ * On most machines MIN_GET_BITS should be 25 to allow the full 32-bit width
+ * of get_buffer to be used. (On machines with wider words, an even larger
+ * buffer could be used.) However, on some machines 32-bit shifts are
+ * quite slow and take time proportional to the number of places shifted.
+ * (This is true with most PC compilers, for instance.) In this case it may
+ * be a win to set MIN_GET_BITS to the minimum value of 15. This reduces the
+ * average shift distance at the cost of more calls to jpeg_fill_bit_buffer.
+ */
+
+#ifdef SLOW_SHIFT_32
+#define MIN_GET_BITS 15 /* minimum allowable value */
+#else
+#define MIN_GET_BITS (BIT_BUF_SIZE-7)
+#endif
+
+
+GLOBAL(boolean)
+jpeg_fill_bit_buffer (bitread_working_state * state,
+ register bit_buf_type get_buffer, register int bits_left,
+ int nbits)
+/* Load up the bit buffer to a depth of at least nbits */
+{
+ /* Copy heavily used state fields into locals (hopefully registers) */
+ register const JOCTET * next_input_byte = state->next_input_byte;
+ register size_t bytes_in_buffer = state->bytes_in_buffer;
+ j_decompress_ptr cinfo = state->cinfo;
+
+ /* Attempt to load at least MIN_GET_BITS bits into get_buffer. */
+ /* (It is assumed that no request will be for more than that many bits.) */
+ /* We fail to do so only if we hit a marker or are forced to suspend. */
+
+ if (cinfo->unread_marker == 0) { /* cannot advance past a marker */
+ while (bits_left < MIN_GET_BITS) {
+ register int c;
+
+ /* Attempt to read a byte */
+ if (bytes_in_buffer == 0) {
+ if (! (*cinfo->src->fill_input_buffer) (cinfo))
+ return FALSE;
+ next_input_byte = cinfo->src->next_input_byte;
+ bytes_in_buffer = cinfo->src->bytes_in_buffer;
+ }
+ bytes_in_buffer--;
+ c = GETJOCTET(*next_input_byte++);
+
+ /* If it's 0xFF, check and discard stuffed zero byte */
+ if (c == 0xFF) {
+ /* Loop here to discard any padding FF's on terminating marker,
+ * so that we can save a valid unread_marker value. NOTE: we will
+ * accept multiple FF's followed by a 0 as meaning a single FF data
+ * byte. This data pattern is not valid according to the standard.
+ */
+ do {
+ if (bytes_in_buffer == 0) {
+ if (! (*cinfo->src->fill_input_buffer) (cinfo))
+ return FALSE;
+ next_input_byte = cinfo->src->next_input_byte;
+ bytes_in_buffer = cinfo->src->bytes_in_buffer;
+ }
+ bytes_in_buffer--;
+ c = GETJOCTET(*next_input_byte++);
+ } while (c == 0xFF);
+
+ if (c == 0) {
+ /* Found FF/00, which represents an FF data byte */
+ c = 0xFF;
+ } else {
+ /* Oops, it's actually a marker indicating end of compressed data.
+ * Save the marker code for later use.
+ * Fine point: it might appear that we should save the marker into
+ * bitread working state, not straight into permanent state. But
+ * once we have hit a marker, we cannot need to suspend within the
+ * current MCU, because we will read no more bytes from the data
+ * source. So it is OK to update permanent state right away.
+ */
+ cinfo->unread_marker = c;
+ /* See if we need to insert some fake zero bits. */
+ goto no_more_bytes;
+ }
+ }
+
+ /* OK, load c into get_buffer */
+ get_buffer = (get_buffer << 8) | c;
+ bits_left += 8;
+ } /* end while */
+ } else {
+ no_more_bytes:
+ /* We get here if we've read the marker that terminates the compressed
+ * data segment. There should be enough bits in the buffer register
+ * to satisfy the request; if so, no problem.
+ */
+ if (nbits > bits_left) {
+ /* Uh-oh. Report corrupted data to user and stuff zeroes into
+ * the data stream, so that we can produce some kind of image.
+ * We use a nonvolatile flag to ensure that only one warning message
+ * appears per data segment.
+ */
+ if (! cinfo->entropy->insufficient_data) {
+ WARNMS(cinfo, JWRN_HIT_MARKER);
+ cinfo->entropy->insufficient_data = TRUE;
+ }
+ /* Fill the buffer with zero bits */
+ get_buffer <<= MIN_GET_BITS - bits_left;
+ bits_left = MIN_GET_BITS;
+ }
+ }
+
+ /* Unload the local registers */
+ state->next_input_byte = next_input_byte;
+ state->bytes_in_buffer = bytes_in_buffer;
+ state->get_buffer = get_buffer;
+ state->bits_left = bits_left;
+
+ return TRUE;
+}
+
+
+/*
+ * Out-of-line code for Huffman code decoding.
+ * See jdhuff.h for info about usage.
+ */
+
+GLOBAL(int)
+jpeg_huff_decode (bitread_working_state * state,
+ register bit_buf_type get_buffer, register int bits_left,
+ d_derived_tbl * htbl, int min_bits)
+{
+ register int l = min_bits;
+ register INT32 code;
+
+ /* HUFF_DECODE has determined that the code is at least min_bits */
+ /* bits long, so fetch that many bits in one swoop. */
+
+ CHECK_BIT_BUFFER(*state, l, return -1);
+ code = GET_BITS(l);
+
+ /* Collect the rest of the Huffman code one bit at a time. */
+ /* This is per Figure F.16 in the JPEG spec. */
+
+ while (code > htbl->maxcode[l]) {
+ code <<= 1;
+ CHECK_BIT_BUFFER(*state, 1, return -1);
+ code |= GET_BITS(1);
+ l++;
+ }
+
+ /* Unload the local registers */
+ state->get_buffer = get_buffer;
+ state->bits_left = bits_left;
+
+ /* With garbage input we may reach the sentinel value l = 17. */
+
+ if (l > 16) {
+ WARNMS(state->cinfo, JWRN_HUFF_BAD_CODE);
+ return 0; /* fake a zero as the safest result */
+ }
+
+ return htbl->pub->huffval[ (int) (code + htbl->valoffset[l]) ];
+}
+
+
+/*
+ * Figure F.12: extend sign bit.
+ * On some machines, a shift and add will be faster than a table lookup.
+ */
+
+#ifdef AVOID_TABLES
+
+#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
+
+#else
+
+#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
+
+static const int extend_test[16] = /* entry n is 2**(n-1) */
+ { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
+
+static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
+ { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
+ ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
+ ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
+ ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
+
+#endif /* AVOID_TABLES */
+
+
+/*
+ * Check for a restart marker & resynchronize decoder.
+ * Returns FALSE if must suspend.
+ */
+
+LOCAL(boolean)
+process_restart (j_decompress_ptr cinfo)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int ci;
+
+ /* Throw away any unused bits remaining in bit buffer; */
+ /* include any full bytes in next_marker's count of discarded bytes */
+ cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
+ entropy->bitstate.bits_left = 0;
+
+ /* Advance past the RSTn marker */
+ if (! (*cinfo->marker->read_restart_marker) (cinfo))
+ return FALSE;
+
+ /* Re-initialize DC predictions to 0 */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+ entropy->saved.last_dc_val[ci] = 0;
+
+ /* Reset restart counter */
+ entropy->restarts_to_go = cinfo->restart_interval;
+
+ /* Reset out-of-data flag, unless read_restart_marker left us smack up
+ * against a marker. In that case we will end up treating the next data
+ * segment as empty, and we can avoid producing bogus output pixels by
+ * leaving the flag set.
+ */
+ if (cinfo->unread_marker == 0)
+ entropy->pub.insufficient_data = FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Decode and return one MCU's worth of Huffman-compressed coefficients.
+ * The coefficients are reordered from zigzag order into natural array order,
+ * but are not dequantized.
+ *
+ * The i'th block of the MCU is stored into the block pointed to by
+ * MCU_data[i]. WE ASSUME THIS AREA HAS BEEN ZEROED BY THE CALLER.
+ * (Wholesale zeroing is usually a little faster than retail...)
+ *
+ * Returns FALSE if data source requested suspension. In that case no
+ * changes have been made to permanent state. (Exception: some output
+ * coefficients may already have been assigned. This is harmless for
+ * this module, since we'll just re-assign them on the next call.)
+ */
+
+METHODDEF(boolean)
+decode_mcu (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ huff_entropy_ptr entropy = (huff_entropy_ptr) cinfo->entropy;
+ int blkn;
+ BITREAD_STATE_VARS;
+ savable_state state;
+
+ /* Process restart marker if needed; may have to suspend */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! process_restart(cinfo))
+ return FALSE;
+ }
+
+ /* If we've run out of data, just leave the MCU set to zeroes.
+ * This way, we return uniform gray for the remainder of the segment.
+ */
+ if (! entropy->pub.insufficient_data) {
+
+ /* Load up working state */
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+ ASSIGN_STATE(state, entropy->saved);
+
+ /* Outer loop handles each block in the MCU */
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ JBLOCKROW block = MCU_data[blkn];
+ d_derived_tbl * dctbl = entropy->dc_cur_tbls[blkn];
+ d_derived_tbl * actbl = entropy->ac_cur_tbls[blkn];
+ register int s, k, r;
+
+ /* Decode a single block's worth of coefficients */
+
+ /* Section F.2.2.1: decode the DC coefficient difference */
+ HUFF_DECODE(s, br_state, dctbl, return FALSE, label1);
+ if (s) {
+ CHECK_BIT_BUFFER(br_state, s, return FALSE);
+ r = GET_BITS(s);
+ s = HUFF_EXTEND(r, s);
+ }
+
+ if (entropy->dc_needed[blkn]) {
+ /* Convert DC difference to actual value, update last_dc_val */
+ int ci = cinfo->MCU_membership[blkn];
+ s += state.last_dc_val[ci];
+ state.last_dc_val[ci] = s;
+ /* Output the DC coefficient (assumes jpeg_natural_order[0] = 0) */
+ (*block)[0] = (JCOEF) s;
+ }
+
+ if (entropy->ac_needed[blkn]) {
+
+ /* Section F.2.2.2: decode the AC coefficients */
+ /* Since zeroes are skipped, output area must be cleared beforehand */
+ for (k = 1; k < DCTSIZE2; k++) {
+ HUFF_DECODE(s, br_state, actbl, return FALSE, label2);
+
+ r = s >> 4;
+ s &= 15;
+
+ if (s) {
+ k += r;
+ CHECK_BIT_BUFFER(br_state, s, return FALSE);
+ r = GET_BITS(s);
+ s = HUFF_EXTEND(r, s);
+ /* Output coefficient in natural (dezigzagged) order.
+ * Note: the extra entries in jpeg_natural_order[] will save us
+ * if k >= DCTSIZE2, which could happen if the data is corrupted.
+ */
+ (*block)[jpeg_natural_order[k]] = (JCOEF) s;
+ } else {
+ if (r != 15)
+ break;
+ k += 15;
+ }
+ }
+
+ } else {
+
+ /* Section F.2.2.2: decode the AC coefficients */
+ /* In this path we just discard the values */
+ for (k = 1; k < DCTSIZE2; k++) {
+ HUFF_DECODE(s, br_state, actbl, return FALSE, label3);
+
+ r = s >> 4;
+ s &= 15;
+
+ if (s) {
+ k += r;
+ CHECK_BIT_BUFFER(br_state, s, return FALSE);
+ DROP_BITS(s);
+ } else {
+ if (r != 15)
+ break;
+ k += 15;
+ }
+ }
+
+ }
+ }
+
+ /* Completed MCU, so update state */
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+ ASSIGN_STATE(entropy->saved, state);
+ }
+
+ /* Account for restart interval (no-op if not using restarts) */
+ entropy->restarts_to_go--;
+
+ return TRUE;
+}
+
+
+/*
+ * Module initialization routine for Huffman entropy decoding.
+ */
+
+GLOBAL(void)
+jinit_huff_decoder (j_decompress_ptr cinfo)
+{
+ huff_entropy_ptr entropy;
+ int i;
+
+ entropy = (huff_entropy_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(huff_entropy_decoder));
+ cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
+ entropy->pub.start_pass = start_pass_huff_decoder;
+ entropy->pub.decode_mcu = decode_mcu;
+
+ /* Mark tables unallocated */
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ entropy->dc_derived_tbls[i] = entropy->ac_derived_tbls[i] = NULL;
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdhuff.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jdhuff.h
new file mode 100644
index 0000000..9e59158
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdhuff.h
@@ -0,0 +1,201 @@
+/*
+ * jdhuff.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains declarations for Huffman entropy decoding routines
+ * that are shared between the sequential decoder (jdhuff.c) and the
+ * progressive decoder (jdphuff.c). No other modules need to see these.
+ */
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_make_d_derived_tbl jMkDDerived
+#define jpeg_fill_bit_buffer jFilBitBuf
+#define jpeg_huff_decode jHufDecode
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/* Derived data constructed for each Huffman table */
+
+#define HUFF_LOOKAHEAD 8 /* # of bits of lookahead */
+
+typedef struct {
+ /* Basic tables: (element [0] of each array is unused) */
+ INT32 maxcode[18]; /* largest code of length k (-1 if none) */
+ /* (maxcode[17] is a sentinel to ensure jpeg_huff_decode terminates) */
+ INT32 valoffset[17]; /* huffval[] offset for codes of length k */
+ /* valoffset[k] = huffval[] index of 1st symbol of code length k, less
+ * the smallest code of length k; so given a code of length k, the
+ * corresponding symbol is huffval[code + valoffset[k]]
+ */
+
+ /* Link to public Huffman table (needed only in jpeg_huff_decode) */
+ JHUFF_TBL *pub;
+
+ /* Lookahead tables: indexed by the next HUFF_LOOKAHEAD bits of
+ * the input data stream. If the next Huffman code is no more
+ * than HUFF_LOOKAHEAD bits long, we can obtain its length and
+ * the corresponding symbol directly from these tables.
+ */
+ int look_nbits[1<<HUFF_LOOKAHEAD]; /* # bits, or 0 if too long */
+ UINT8 look_sym[1<<HUFF_LOOKAHEAD]; /* symbol, or unused */
+} d_derived_tbl;
+
+/* Expand a Huffman table definition into the derived format */
+EXTERN(void) jpeg_make_d_derived_tbl
+ JPP((j_decompress_ptr cinfo, boolean isDC, int tblno,
+ d_derived_tbl ** pdtbl));
+
+
+/*
+ * Fetching the next N bits from the input stream is a time-critical operation
+ * for the Huffman decoders. We implement it with a combination of inline
+ * macros and out-of-line subroutines. Note that N (the number of bits
+ * demanded at one time) never exceeds 15 for JPEG use.
+ *
+ * We read source bytes into get_buffer and dole out bits as needed.
+ * If get_buffer already tqcontains enough bits, they are fetched in-line
+ * by the macros CHECK_BIT_BUFFER and GET_BITS. When there aren't enough
+ * bits, jpeg_fill_bit_buffer is called; it will attempt to fill get_buffer
+ * as full as possible (not just to the number of bits needed; this
+ * prefetching reduces the overhead cost of calling jpeg_fill_bit_buffer).
+ * Note that jpeg_fill_bit_buffer may return FALSE to indicate suspension.
+ * On TRUE return, jpeg_fill_bit_buffer guarantees that get_buffer tqcontains
+ * at least the requested number of bits --- dummy zeroes are inserted if
+ * necessary.
+ */
+
+typedef INT32 bit_buf_type; /* type of bit-extraction buffer */
+#define BIT_BUF_SIZE 32 /* size of buffer in bits */
+
+/* If long is > 32 bits on your machine, and shifting/masking longs is
+ * reasonably fast, making bit_buf_type be long and setting BIT_BUF_SIZE
+ * appropriately should be a win. Unfortunately we can't define the size
+ * with something like #define BIT_BUF_SIZE (sizeof(bit_buf_type)*8)
+ * because not all machines measure sizeof in 8-bit bytes.
+ */
+
+typedef struct { /* Bitreading state saved across MCUs */
+ bit_buf_type get_buffer; /* current bit-extraction buffer */
+ int bits_left; /* # of unused bits in it */
+} bitread_perm_state;
+
+typedef struct { /* Bitreading working state within an MCU */
+ /* Current data source location */
+ /* We need a copy, rather than munging the original, in case of suspension */
+ const JOCTET * next_input_byte; /* => next byte to read from source */
+ size_t bytes_in_buffer; /* # of bytes remaining in source buffer */
+ /* Bit input buffer --- note these values are kept in register variables,
+ * not in this struct, inside the inner loops.
+ */
+ bit_buf_type get_buffer; /* current bit-extraction buffer */
+ int bits_left; /* # of unused bits in it */
+ /* Pointer needed by jpeg_fill_bit_buffer. */
+ j_decompress_ptr cinfo; /* back link to decompress master record */
+} bitread_working_state;
+
+/* Macros to declare and load/save bitread local variables. */
+#define BITREAD_STATE_VARS \
+ register bit_buf_type get_buffer; \
+ register int bits_left; \
+ bitread_working_state br_state
+
+#define BITREAD_LOAD_STATE(cinfop,permstate) \
+ br_state.cinfo = cinfop; \
+ br_state.next_input_byte = cinfop->src->next_input_byte; \
+ br_state.bytes_in_buffer = cinfop->src->bytes_in_buffer; \
+ get_buffer = permstate.get_buffer; \
+ bits_left = permstate.bits_left;
+
+#define BITREAD_SAVE_STATE(cinfop,permstate) \
+ cinfop->src->next_input_byte = br_state.next_input_byte; \
+ cinfop->src->bytes_in_buffer = br_state.bytes_in_buffer; \
+ permstate.get_buffer = get_buffer; \
+ permstate.bits_left = bits_left
+
+/*
+ * These macros provide the in-line portion of bit fetching.
+ * Use CHECK_BIT_BUFFER to ensure there are N bits in get_buffer
+ * before using GET_BITS, PEEK_BITS, or DROP_BITS.
+ * The variables get_buffer and bits_left are assumed to be locals,
+ * but the state struct might not be (jpeg_huff_decode needs this).
+ * CHECK_BIT_BUFFER(state,n,action);
+ * Ensure there are N bits in get_buffer; if suspend, take action.
+ * val = GET_BITS(n);
+ * Fetch next N bits.
+ * val = PEEK_BITS(n);
+ * Fetch next N bits without removing them from the buffer.
+ * DROP_BITS(n);
+ * Discard next N bits.
+ * The value N should be a simple variable, not an expression, because it
+ * is evaluated multiple times.
+ */
+
+#define CHECK_BIT_BUFFER(state,nbits,action) \
+ { if (bits_left < (nbits)) { \
+ if (! jpeg_fill_bit_buffer(&(state),get_buffer,bits_left,nbits)) \
+ { action; } \
+ get_buffer = (state).get_buffer; bits_left = (state).bits_left; } }
+
+#define GET_BITS(nbits) \
+ (((int) (get_buffer >> (bits_left -= (nbits)))) & ((1<<(nbits))-1))
+
+#define PEEK_BITS(nbits) \
+ (((int) (get_buffer >> (bits_left - (nbits)))) & ((1<<(nbits))-1))
+
+#define DROP_BITS(nbits) \
+ (bits_left -= (nbits))
+
+/* Load up the bit buffer to a depth of at least nbits */
+EXTERN(boolean) jpeg_fill_bit_buffer
+ JPP((bitread_working_state * state, register bit_buf_type get_buffer,
+ register int bits_left, int nbits));
+
+
+/*
+ * Code for extracting next Huffman-coded symbol from input bit stream.
+ * Again, this is time-critical and we make the main paths be macros.
+ *
+ * We use a lookahead table to process codes of up to HUFF_LOOKAHEAD bits
+ * without looping. Usually, more than 95% of the Huffman codes will be 8
+ * or fewer bits long. The few overlength codes are handled with a loop,
+ * which need not be inline code.
+ *
+ * Notes about the HUFF_DECODE macro:
+ * 1. Near the end of the data segment, we may fail to get enough bits
+ * for a lookahead. In that case, we do it the hard way.
+ * 2. If the lookahead table tqcontains no entry, the next code must be
+ * more than HUFF_LOOKAHEAD bits long.
+ * 3. jpeg_huff_decode returns -1 if forced to suspend.
+ */
+
+#define HUFF_DECODE(result,state,htbl,failaction,slowlabel) \
+{ register int nb, look; \
+ if (bits_left < HUFF_LOOKAHEAD) { \
+ if (! jpeg_fill_bit_buffer(&state,get_buffer,bits_left, 0)) {failaction;} \
+ get_buffer = state.get_buffer; bits_left = state.bits_left; \
+ if (bits_left < HUFF_LOOKAHEAD) { \
+ nb = 1; goto slowlabel; \
+ } \
+ } \
+ look = PEEK_BITS(HUFF_LOOKAHEAD); \
+ if ((nb = htbl->look_nbits[look]) != 0) { \
+ DROP_BITS(nb); \
+ result = htbl->look_sym[look]; \
+ } else { \
+ nb = HUFF_LOOKAHEAD+1; \
+slowlabel: \
+ if ((result=jpeg_huff_decode(&state,get_buffer,bits_left,htbl,nb)) < 0) \
+ { failaction; } \
+ get_buffer = state.get_buffer; bits_left = state.bits_left; \
+ } \
+}
+
+/* Out-of-line case for Huffman code fetching */
+EXTERN(int) jpeg_huff_decode
+ JPP((bitread_working_state * state, register bit_buf_type get_buffer,
+ register int bits_left, d_derived_tbl * htbl, int min_bits));
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdinput.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdinput.c
new file mode 100644
index 0000000..c9050db
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdinput.c
@@ -0,0 +1,381 @@
+/*
+ * jdinput.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains input control logic for the JPEG decompressor.
+ * These routines are concerned with controlling the decompressor's input
+ * processing (marker reading and coefficient decoding). The actual input
+ * reading is done in jdmarker.c, jdhuff.c, and jdphuff.c.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private state */
+
+typedef struct {
+ struct jpeg_input_controller pub; /* public fields */
+
+ boolean inheaders; /* TRUE until first SOS is reached */
+} my_input_controller;
+
+typedef my_input_controller * my_inputctl_ptr;
+
+
+/* Forward declarations */
+METHODDEF(int) consume_markers JPP((j_decompress_ptr cinfo));
+
+
+/*
+ * Routines to calculate various quantities related to the size of the image.
+ */
+
+LOCAL(void)
+initial_setup (j_decompress_ptr cinfo)
+/* Called once, when first SOS marker is reached */
+{
+ int ci;
+ jpeg_component_info *compptr;
+
+ /* Make sure image isn't bigger than I can handle */
+ if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
+ (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
+ ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);
+
+ /* For now, precision must match compiled-in value... */
+ if (cinfo->data_precision != BITS_IN_JSAMPLE)
+ ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
+
+ /* Check that number of components won't exceed internal array sizes */
+ if (cinfo->num_components > MAX_COMPONENTS)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
+ MAX_COMPONENTS);
+
+ /* Compute maximum sampling factors; check factor validity */
+ cinfo->max_h_samp_factor = 1;
+ cinfo->max_v_samp_factor = 1;
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
+ compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
+ ERREXIT(cinfo, JERR_BAD_SAMPLING);
+ cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
+ compptr->h_samp_factor);
+ cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
+ compptr->v_samp_factor);
+ }
+
+ /* We initialize DCT_scaled_size and min_DCT_scaled_size to DCTSIZE.
+ * In the full decompressor, this will be overridden by jdmaster.c;
+ * but in the transcoder, jdmaster.c is not used, so we must do it here.
+ */
+ cinfo->min_DCT_scaled_size = DCTSIZE;
+
+ /* Compute dimensions of components */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ compptr->DCT_scaled_size = DCTSIZE;
+ /* Size in DCT blocks */
+ compptr->width_in_blocks = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
+ (long) (cinfo->max_h_samp_factor * DCTSIZE));
+ compptr->height_in_blocks = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
+ (long) (cinfo->max_v_samp_factor * DCTSIZE));
+ /* downsampled_width and downsampled_height will also be overridden by
+ * jdmaster.c if we are doing full decompression. The transcoder library
+ * doesn't use these values, but the calling application might.
+ */
+ /* Size in samples */
+ compptr->downsampled_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
+ (long) cinfo->max_h_samp_factor);
+ compptr->downsampled_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
+ (long) cinfo->max_v_samp_factor);
+ /* Mark component needed, until color conversion says otherwise */
+ compptr->component_needed = TRUE;
+ /* Mark no quantization table yet saved for component */
+ compptr->quant_table = NULL;
+ }
+
+ /* Compute number of fully interleaved MCU rows. */
+ cinfo->total_iMCU_rows = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height,
+ (long) (cinfo->max_v_samp_factor*DCTSIZE));
+
+ /* Decide whether file tqcontains multiple scans */
+ if (cinfo->comps_in_scan < cinfo->num_components || cinfo->progressive_mode)
+ cinfo->inputctl->has_multiple_scans = TRUE;
+ else
+ cinfo->inputctl->has_multiple_scans = FALSE;
+}
+
+
+LOCAL(void)
+per_scan_setup (j_decompress_ptr cinfo)
+/* Do computations that are needed before processing a JPEG scan */
+/* cinfo->comps_in_scan and cinfo->cur_comp_info[] were set from SOS marker */
+{
+ int ci, mcublks, tmp;
+ jpeg_component_info *compptr;
+
+ if (cinfo->comps_in_scan == 1) {
+
+ /* Noninterleaved (single-component) scan */
+ compptr = cinfo->cur_comp_info[0];
+
+ /* Overall image size in MCUs */
+ cinfo->MCUs_per_row = compptr->width_in_blocks;
+ cinfo->MCU_rows_in_scan = compptr->height_in_blocks;
+
+ /* For noninterleaved scan, always one block per MCU */
+ compptr->MCU_width = 1;
+ compptr->MCU_height = 1;
+ compptr->MCU_blocks = 1;
+ compptr->MCU_sample_width = compptr->DCT_scaled_size;
+ compptr->last_col_width = 1;
+ /* For noninterleaved scans, it is convenient to define last_row_height
+ * as the number of block rows present in the last iMCU row.
+ */
+ tmp = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
+ if (tmp == 0) tmp = compptr->v_samp_factor;
+ compptr->last_row_height = tmp;
+
+ /* Prepare array describing MCU composition */
+ cinfo->blocks_in_MCU = 1;
+ cinfo->MCU_membership[0] = 0;
+
+ } else {
+
+ /* Interleaved (multi-component) scan */
+ if (cinfo->comps_in_scan <= 0 || cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
+ ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->comps_in_scan,
+ MAX_COMPS_IN_SCAN);
+
+ /* Overall image size in MCUs */
+ cinfo->MCUs_per_row = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width,
+ (long) (cinfo->max_h_samp_factor*DCTSIZE));
+ cinfo->MCU_rows_in_scan = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height,
+ (long) (cinfo->max_v_samp_factor*DCTSIZE));
+
+ cinfo->blocks_in_MCU = 0;
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* Sampling factors give # of blocks of component in each MCU */
+ compptr->MCU_width = compptr->h_samp_factor;
+ compptr->MCU_height = compptr->v_samp_factor;
+ compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
+ compptr->MCU_sample_width = compptr->MCU_width * compptr->DCT_scaled_size;
+ /* Figure number of non-dummy blocks in last MCU column & row */
+ tmp = (int) (compptr->width_in_blocks % compptr->MCU_width);
+ if (tmp == 0) tmp = compptr->MCU_width;
+ compptr->last_col_width = tmp;
+ tmp = (int) (compptr->height_in_blocks % compptr->MCU_height);
+ if (tmp == 0) tmp = compptr->MCU_height;
+ compptr->last_row_height = tmp;
+ /* Prepare array describing MCU composition */
+ mcublks = compptr->MCU_blocks;
+ if (cinfo->blocks_in_MCU + mcublks > D_MAX_BLOCKS_IN_MCU)
+ ERREXIT(cinfo, JERR_BAD_MCU_SIZE);
+ while (mcublks-- > 0) {
+ cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
+ }
+ }
+
+ }
+}
+
+
+/*
+ * Save away a copy of the Q-table referenced by each component present
+ * in the current scan, unless already saved during a prior scan.
+ *
+ * In a multiple-scan JPEG file, the encoder could assign different components
+ * the same Q-table slot number, but change table definitions between scans
+ * so that each component uses a different Q-table. (The IJG encoder is not
+ * currently capable of doing this, but other encoders might.) Since we want
+ * to be able to dequantize all the components at the end of the file, this
+ * means that we have to save away the table actually used for each component.
+ * We do this by copying the table at the start of the first scan containing
+ * the component.
+ * The JPEG spec prohibits the encoder from changing the contents of a Q-table
+ * slot between scans of a component using that slot. If the encoder does so
+ * anyway, this decoder will simply use the Q-table values that were current
+ * at the start of the first scan for the component.
+ *
+ * The decompressor output side looks only at the saved quant tables,
+ * not at the current Q-table Q_SLOTS.
+ */
+
+LOCAL(void)
+latch_quant_tables (j_decompress_ptr cinfo)
+{
+ int ci, qtblno;
+ jpeg_component_info *compptr;
+ JTQUANT_TBL * qtbl;
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* No work if we already saved Q-table for this component */
+ if (compptr->quant_table != NULL)
+ continue;
+ /* Make sure specified quantization table is present */
+ qtblno = compptr->quant_tbl_no;
+ if (qtblno < 0 || qtblno >= NUM_TQUANT_TBLS ||
+ cinfo->quant_tbl_ptrs[qtblno] == NULL)
+ ERREXIT1(cinfo, JERR_NO_TQUANT_TABLE, qtblno);
+ /* OK, save away the quantization table */
+ qtbl = (JTQUANT_TBL *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(JTQUANT_TBL));
+ MEMCOPY(qtbl, cinfo->quant_tbl_ptrs[qtblno], SIZEOF(JTQUANT_TBL));
+ compptr->quant_table = qtbl;
+ }
+}
+
+
+/*
+ * Initialize the input modules to read a scan of compressed data.
+ * The first call to this is done by jdmaster.c after initializing
+ * the entire decompressor (during jpeg_start_decompress).
+ * Subsequent calls come from consume_markers, below.
+ */
+
+METHODDEF(void)
+start_input_pass (j_decompress_ptr cinfo)
+{
+ per_scan_setup(cinfo);
+ latch_quant_tables(cinfo);
+ (*cinfo->entropy->start_pass) (cinfo);
+ (*cinfo->coef->start_input_pass) (cinfo);
+ cinfo->inputctl->consume_input = cinfo->coef->consume_data;
+}
+
+
+/*
+ * Finish up after inputting a compressed-data scan.
+ * This is called by the coefficient controller after it's read all
+ * the expected data of the scan.
+ */
+
+METHODDEF(void)
+finish_input_pass (j_decompress_ptr cinfo)
+{
+ cinfo->inputctl->consume_input = consume_markers;
+}
+
+
+/*
+ * Read JPEG markers before, between, or after compressed-data scans.
+ * Change state as necessary when a new scan is reached.
+ * Return value is JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
+ *
+ * The consume_input method pointer points either here or to the
+ * coefficient controller's consume_data routine, depending on whether
+ * we are reading a compressed data segment or inter-segment markers.
+ */
+
+METHODDEF(int)
+consume_markers (j_decompress_ptr cinfo)
+{
+ my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
+ int val;
+
+ if (inputctl->pub.eoi_reached) /* After hitting EOI, read no further */
+ return JPEG_REACHED_EOI;
+
+ val = (*cinfo->marker->read_markers) (cinfo);
+
+ switch (val) {
+ case JPEG_REACHED_SOS: /* Found SOS */
+ if (inputctl->inheaders) { /* 1st SOS */
+ initial_setup(cinfo);
+ inputctl->inheaders = FALSE;
+ /* Note: start_input_pass must be called by jdmaster.c
+ * before any more input can be consumed. jdapimin.c is
+ * responsible for enforcing this sequencing.
+ */
+ } else { /* 2nd or later SOS marker */
+ if (! inputctl->pub.has_multiple_scans)
+ ERREXIT(cinfo, JERR_EOI_EXPECTED); /* Oops, I wasn't expecting this! */
+ start_input_pass(cinfo);
+ }
+ break;
+ case JPEG_REACHED_EOI: /* Found EOI */
+ inputctl->pub.eoi_reached = TRUE;
+ if (inputctl->inheaders) { /* Tables-only datastream, apparently */
+ if (cinfo->marker->saw_SOF)
+ ERREXIT(cinfo, JERR_SOF_NO_SOS);
+ } else {
+ /* Prevent infinite loop in coef ctlr's decompress_data routine
+ * if user set output_scan_number larger than number of scans.
+ */
+ if (cinfo->output_scan_number > cinfo->input_scan_number)
+ cinfo->output_scan_number = cinfo->input_scan_number;
+ }
+ break;
+ case JPEG_SUSPENDED:
+ break;
+ }
+
+ return val;
+}
+
+
+/*
+ * Reset state to begin a fresh datastream.
+ */
+
+METHODDEF(void)
+reset_input_controller (j_decompress_ptr cinfo)
+{
+ my_inputctl_ptr inputctl = (my_inputctl_ptr) cinfo->inputctl;
+
+ inputctl->pub.consume_input = consume_markers;
+ inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
+ inputctl->pub.eoi_reached = FALSE;
+ inputctl->inheaders = TRUE;
+ /* Reset other modules */
+ (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
+ (*cinfo->marker->reset_marker_reader) (cinfo);
+ /* Reset progression state -- would be cleaner if entropy decoder did this */
+ cinfo->coef_bits = NULL;
+}
+
+
+/*
+ * Initialize the input controller module.
+ * This is called only once, when the decompression object is created.
+ */
+
+GLOBAL(void)
+jinit_input_controller (j_decompress_ptr cinfo)
+{
+ my_inputctl_ptr inputctl;
+
+ /* Create subobject in permanent pool */
+ inputctl = (my_inputctl_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ SIZEOF(my_input_controller));
+ cinfo->inputctl = (struct jpeg_input_controller *) inputctl;
+ /* Initialize method pointers */
+ inputctl->pub.consume_input = consume_markers;
+ inputctl->pub.reset_input_controller = reset_input_controller;
+ inputctl->pub.start_input_pass = start_input_pass;
+ inputctl->pub.finish_input_pass = finish_input_pass;
+ /* Initialize state: can't use reset_input_controller since we don't
+ * want to try to reset other modules yet.
+ */
+ inputctl->pub.has_multiple_scans = FALSE; /* "unknown" would be better */
+ inputctl->pub.eoi_reached = FALSE;
+ inputctl->inheaders = TRUE;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdmainct.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdmainct.c
new file mode 100644
index 0000000..0cc0426
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdmainct.c
@@ -0,0 +1,512 @@
+/*
+ * jdmainct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains the main buffer controller for decompression.
+ * The main buffer lies between the JPEG decompressor proper and the
+ * post-processor; it holds downsampled data in the JPEG colorspace.
+ *
+ * Note that this code is bypassed in raw-data mode, since the application
+ * supplies the equivalent of the main buffer in that case.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * In the current system design, the main buffer need never be a full-image
+ * buffer; any full-height buffers will be found inside the coefficient or
+ * postprocessing controllers. Nonetheless, the main controller is not
+ * trivial. Its responsibility is to provide context rows for upsampling/
+ * rescaling, and doing this in an efficient fashion is a bit tricky.
+ *
+ * Postprocessor input data is counted in "row groups". A row group
+ * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
+ * sample rows of each component. (We require DCT_scaled_size values to be
+ * chosen such that these numbers are integers. In practice DCT_scaled_size
+ * values will likely be powers of two, so we actually have the stronger
+ * condition that DCT_scaled_size / min_DCT_scaled_size is an integer.)
+ * Upsampling will typically produce max_v_samp_factor pixel rows from each
+ * row group (times any additional scale factor that the upsampler is
+ * applying).
+ *
+ * The coefficient controller will deliver data to us one iMCU row at a time;
+ * each iMCU row tqcontains v_samp_factor * DCT_scaled_size sample rows, or
+ * exactly min_DCT_scaled_size row groups. (This amount of data corresponds
+ * to one row of MCUs when the image is fully interleaved.) Note that the
+ * number of sample rows varies across components, but the number of row
+ * groups does not. Some garbage sample rows may be included in the last iMCU
+ * row at the bottom of the image.
+ *
+ * Depending on the vertical scaling algorithm used, the upsampler may need
+ * access to the sample row(s) above and below its current input row group.
+ * The upsampler is required to set need_context_rows TRUE at global selection
+ * time if so. When need_context_rows is FALSE, this controller can simply
+ * obtain one iMCU row at a time from the coefficient controller and dole it
+ * out as row groups to the postprocessor.
+ *
+ * When need_context_rows is TRUE, this controller guarantees that the buffer
+ * passed to postprocessing tqcontains at least one row group's worth of samples
+ * above and below the row group(s) being processed. Note that the context
+ * rows "above" the first passed row group appear at negative row offsets in
+ * the passed buffer. At the top and bottom of the image, the required
+ * context rows are manufactured by duplicating the first or last real sample
+ * row; this avoids having special cases in the upsampling inner loops.
+ *
+ * The amount of context is fixed at one row group just because that's a
+ * convenient number for this controller to work with. The existing
+ * upsamplers really only need one sample row of context. An upsampler
+ * supporting arbitrary output rescaling might wish for more than one row
+ * group of context when shrinking the image; tough, we don't handle that.
+ * (This is justified by the assumption that downsizing will be handled mostly
+ * by adjusting the DCT_scaled_size values, so that the actual scale factor at
+ * the upsample step needn't be much less than one.)
+ *
+ * To provide the desired context, we have to retain the last two row groups
+ * of one iMCU row while reading in the next iMCU row. (The last row group
+ * can't be processed until we have another row group for its below-context,
+ * and so we have to save the next-to-last group too for its above-context.)
+ * We could do this most simply by copying data around in our buffer, but
+ * that'd be very slow. We can avoid copying any data by creating a rather
+ * strange pointer structure. Here's how it works. We allocate a workspace
+ * consisting of M+2 row groups (where M = min_DCT_scaled_size is the number
+ * of row groups per iMCU row). We create two sets of redundant pointers to
+ * the workspace. Labeling the physical row groups 0 to M+1, the synthesized
+ * pointer lists look like this:
+ * M+1 M-1
+ * master pointer --> 0 master pointer --> 0
+ * 1 1
+ * ... ...
+ * M-3 M-3
+ * M-2 M
+ * M-1 M+1
+ * M M-2
+ * M+1 M-1
+ * 0 0
+ * We read alternate iMCU rows using each master pointer; thus the last two
+ * row groups of the previous iMCU row remain un-overwritten in the workspace.
+ * The pointer lists are set up so that the required context rows appear to
+ * be adjacent to the proper places when we pass the pointer lists to the
+ * upsampler.
+ *
+ * The above pictures describe the normal state of the pointer lists.
+ * At top and bottom of the image, we diddle the pointer lists to duplicate
+ * the first or last sample row as necessary (this is cheaper than copying
+ * sample rows around).
+ *
+ * This scheme breaks down if M < 2, ie, min_DCT_scaled_size is 1. In that
+ * situation each iMCU row provides only one row group so the buffering logic
+ * must be different (eg, we must read two iMCU rows before we can emit the
+ * first row group). For now, we simply do not support providing context
+ * rows when min_DCT_scaled_size is 1. That combination seems unlikely to
+ * be worth providing --- if someone wants a 1/8th-size preview, they probably
+ * want it quick and dirty, so a context-free upsampler is sufficient.
+ */
+
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_d_main_controller pub; /* public fields */
+
+ /* Pointer to allocated workspace (M or M+2 row groups). */
+ JSAMPARRAY buffer[MAX_COMPONENTS];
+
+ boolean buffer_full; /* Have we gotten an iMCU row from decoder? */
+ JDIMENSION rowgroup_ctr; /* counts row groups output to postprocessor */
+
+ /* Remaining fields are only used in the context case. */
+
+ /* These are the master pointers to the funny-order pointer lists. */
+ JSAMPIMAGE xbuffer[2]; /* pointers to weird pointer lists */
+
+ int whichptr; /* indicates which pointer set is now in use */
+ int context_state; /* process_data state machine status */
+ JDIMENSION rowgroups_avail; /* row groups available to postprocessor */
+ JDIMENSION iMCU_row_ctr; /* counts iMCU rows to detect image top/bot */
+} my_main_controller;
+
+typedef my_main_controller * my_main_ptr;
+
+/* context_state values: */
+#define CTX_PREPARE_FOR_IMCU 0 /* need to prepare for MCU row */
+#define CTX_PROCESS_IMCU 1 /* feeding iMCU to postprocessor */
+#define CTX_POSTPONED_ROW 2 /* feeding postponed row group */
+
+
+/* Forward declarations */
+METHODDEF(void) process_data_simple_main
+ JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
+ JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
+METHODDEF(void) process_data_context_main
+ JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
+ JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
+#ifdef TQUANT_2PASS_SUPPORTED
+METHODDEF(void) process_data_crank_post
+ JPP((j_decompress_ptr cinfo, JSAMPARRAY output_buf,
+ JDIMENSION *out_row_ctr, JDIMENSION out_rows_avail));
+#endif
+
+
+LOCAL(void)
+alloc_funny_pointers (j_decompress_ptr cinfo)
+/* Allocate space for the funny pointer lists.
+ * This is done only once, not once per pass.
+ */
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+ int ci, rgroup;
+ int M = cinfo->min_DCT_scaled_size;
+ jpeg_component_info *compptr;
+ JSAMPARRAY xbuf;
+
+ /* Get top-level space for component array pointers.
+ * We alloc both arrays with one call to save a few cycles.
+ */
+ main->xbuffer[0] = (JSAMPIMAGE)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->num_components * 2 * SIZEOF(JSAMPARRAY));
+ main->xbuffer[1] = main->xbuffer[0] + cinfo->num_components;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+ cinfo->min_DCT_scaled_size; /* height of a row group of component */
+ /* Get space for pointer lists --- M+4 row groups in each list.
+ * We alloc both pointer lists with one call to save a few cycles.
+ */
+ xbuf = (JSAMPARRAY)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ 2 * (rgroup * (M + 4)) * SIZEOF(JSAMPROW));
+ xbuf += rgroup; /* want one row group at negative offsets */
+ main->xbuffer[0][ci] = xbuf;
+ xbuf += rgroup * (M + 4);
+ main->xbuffer[1][ci] = xbuf;
+ }
+}
+
+
+LOCAL(void)
+make_funny_pointers (j_decompress_ptr cinfo)
+/* Create the funny pointer lists discussed in the comments above.
+ * The actual workspace is already allocated (in main->buffer),
+ * and the space for the pointer lists is allocated too.
+ * This routine just fills in the curiously ordered lists.
+ * This will be repeated at the beginning of each pass.
+ */
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+ int ci, i, rgroup;
+ int M = cinfo->min_DCT_scaled_size;
+ jpeg_component_info *compptr;
+ JSAMPARRAY buf, xbuf0, xbuf1;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+ cinfo->min_DCT_scaled_size; /* height of a row group of component */
+ xbuf0 = main->xbuffer[0][ci];
+ xbuf1 = main->xbuffer[1][ci];
+ /* First copy the workspace pointers as-is */
+ buf = main->buffer[ci];
+ for (i = 0; i < rgroup * (M + 2); i++) {
+ xbuf0[i] = xbuf1[i] = buf[i];
+ }
+ /* In the second list, put the last four row groups in swapped order */
+ for (i = 0; i < rgroup * 2; i++) {
+ xbuf1[rgroup*(M-2) + i] = buf[rgroup*M + i];
+ xbuf1[rgroup*M + i] = buf[rgroup*(M-2) + i];
+ }
+ /* The wraparound pointers at top and bottom will be filled later
+ * (see set_wraparound_pointers, below). Initially we want the "above"
+ * pointers to duplicate the first actual data line. This only needs
+ * to happen in xbuffer[0].
+ */
+ for (i = 0; i < rgroup; i++) {
+ xbuf0[i - rgroup] = xbuf0[0];
+ }
+ }
+}
+
+
+LOCAL(void)
+set_wraparound_pointers (j_decompress_ptr cinfo)
+/* Set up the "wraparound" pointers at top and bottom of the pointer lists.
+ * This changes the pointer list state from top-of-image to the normal state.
+ */
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+ int ci, i, rgroup;
+ int M = cinfo->min_DCT_scaled_size;
+ jpeg_component_info *compptr;
+ JSAMPARRAY xbuf0, xbuf1;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+ cinfo->min_DCT_scaled_size; /* height of a row group of component */
+ xbuf0 = main->xbuffer[0][ci];
+ xbuf1 = main->xbuffer[1][ci];
+ for (i = 0; i < rgroup; i++) {
+ xbuf0[i - rgroup] = xbuf0[rgroup*(M+1) + i];
+ xbuf1[i - rgroup] = xbuf1[rgroup*(M+1) + i];
+ xbuf0[rgroup*(M+2) + i] = xbuf0[i];
+ xbuf1[rgroup*(M+2) + i] = xbuf1[i];
+ }
+ }
+}
+
+
+LOCAL(void)
+set_bottom_pointers (j_decompress_ptr cinfo)
+/* Change the pointer lists to duplicate the last sample row at the bottom
+ * of the image. whichptr indicates which xbuffer holds the final iMCU row.
+ * Also sets rowgroups_avail to indicate number of nondummy row groups in row.
+ */
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+ int ci, i, rgroup, iMCUheight, rows_left;
+ jpeg_component_info *compptr;
+ JSAMPARRAY xbuf;
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Count sample rows in one iMCU row and in one row group */
+ iMCUheight = compptr->v_samp_factor * compptr->DCT_scaled_size;
+ rgroup = iMCUheight / cinfo->min_DCT_scaled_size;
+ /* Count nondummy sample rows remaining for this component */
+ rows_left = (int) (compptr->downsampled_height % (JDIMENSION) iMCUheight);
+ if (rows_left == 0) rows_left = iMCUheight;
+ /* Count nondummy row groups. Should get same answer for each component,
+ * so we need only do it once.
+ */
+ if (ci == 0) {
+ main->rowgroups_avail = (JDIMENSION) ((rows_left-1) / rgroup + 1);
+ }
+ /* Duplicate the last real sample row rgroup*2 times; this pads out the
+ * last partial rowgroup and ensures at least one full rowgroup of context.
+ */
+ xbuf = main->xbuffer[main->whichptr][ci];
+ for (i = 0; i < rgroup * 2; i++) {
+ xbuf[rows_left + i] = xbuf[rows_left-1];
+ }
+ }
+}
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_main (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+
+ switch (pass_mode) {
+ case JBUF_PASS_THRU:
+ if (cinfo->upsample->need_context_rows) {
+ main->pub.process_data = process_data_context_main;
+ make_funny_pointers(cinfo); /* Create the xbuffer[] lists */
+ main->whichptr = 0; /* Read first iMCU row into xbuffer[0] */
+ main->context_state = CTX_PREPARE_FOR_IMCU;
+ main->iMCU_row_ctr = 0;
+ } else {
+ /* Simple case with no context needed */
+ main->pub.process_data = process_data_simple_main;
+ }
+ main->buffer_full = FALSE; /* Mark buffer empty */
+ main->rowgroup_ctr = 0;
+ break;
+#ifdef TQUANT_2PASS_SUPPORTED
+ case JBUF_CRANK_DEST:
+ /* For last pass of 2-pass quantization, just crank the postprocessor */
+ main->pub.process_data = process_data_crank_post;
+ break;
+#endif
+ default:
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ break;
+ }
+}
+
+
+/*
+ * Process some data.
+ * This handles the simple case where no context is required.
+ */
+
+METHODDEF(void)
+process_data_simple_main (j_decompress_ptr cinfo,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+ JDIMENSION rowgroups_avail;
+
+ /* Read input data if we haven't filled the main buffer yet */
+ if (! main->buffer_full) {
+ if (! (*cinfo->coef->decompress_data) (cinfo, main->buffer))
+ return; /* suspension forced, can do nothing more */
+ main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
+ }
+
+ /* There are always min_DCT_scaled_size row groups in an iMCU row. */
+ rowgroups_avail = (JDIMENSION) cinfo->min_DCT_scaled_size;
+ /* Note: at the bottom of the image, we may pass extra garbage row groups
+ * to the postprocessor. The postprocessor has to check for bottom
+ * of image anyway (at row resolution), so no point in us doing it too.
+ */
+
+ /* Feed the postprocessor */
+ (*cinfo->post->post_process_data) (cinfo, main->buffer,
+ &main->rowgroup_ctr, rowgroups_avail,
+ output_buf, out_row_ctr, out_rows_avail);
+
+ /* Has postprocessor consumed all the data yet? If so, mark buffer empty */
+ if (main->rowgroup_ctr >= rowgroups_avail) {
+ main->buffer_full = FALSE;
+ main->rowgroup_ctr = 0;
+ }
+}
+
+
+/*
+ * Process some data.
+ * This handles the case where context rows must be provided.
+ */
+
+METHODDEF(void)
+process_data_context_main (j_decompress_ptr cinfo,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_main_ptr main = (my_main_ptr) cinfo->main;
+
+ /* Read input data if we haven't filled the main buffer yet */
+ if (! main->buffer_full) {
+ if (! (*cinfo->coef->decompress_data) (cinfo,
+ main->xbuffer[main->whichptr]))
+ return; /* suspension forced, can do nothing more */
+ main->buffer_full = TRUE; /* OK, we have an iMCU row to work with */
+ main->iMCU_row_ctr++; /* count rows received */
+ }
+
+ /* Postprocessor typically will not swallow all the input data it is handed
+ * in one call (due to filling the output buffer first). Must be prepared
+ * to exit and restart. This switch lets us keep track of how far we got.
+ * Note that each case falls through to the next on successful completion.
+ */
+ switch (main->context_state) {
+ case CTX_POSTPONED_ROW:
+ /* Call postprocessor using previously set pointers for postponed row */
+ (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],
+ &main->rowgroup_ctr, main->rowgroups_avail,
+ output_buf, out_row_ctr, out_rows_avail);
+ if (main->rowgroup_ctr < main->rowgroups_avail)
+ return; /* Need to suspend */
+ main->context_state = CTX_PREPARE_FOR_IMCU;
+ if (*out_row_ctr >= out_rows_avail)
+ return; /* Postprocessor exactly filled output buf */
+ /*FALLTHROUGH*/
+ case CTX_PREPARE_FOR_IMCU:
+ /* Prepare to process first M-1 row groups of this iMCU row */
+ main->rowgroup_ctr = 0;
+ main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size - 1);
+ /* Check for bottom of image: if so, tweak pointers to "duplicate"
+ * the last sample row, and adjust rowgroups_avail to ignore padding rows.
+ */
+ if (main->iMCU_row_ctr == cinfo->total_iMCU_rows)
+ set_bottom_pointers(cinfo);
+ main->context_state = CTX_PROCESS_IMCU;
+ /*FALLTHROUGH*/
+ case CTX_PROCESS_IMCU:
+ /* Call postprocessor using previously set pointers */
+ (*cinfo->post->post_process_data) (cinfo, main->xbuffer[main->whichptr],
+ &main->rowgroup_ctr, main->rowgroups_avail,
+ output_buf, out_row_ctr, out_rows_avail);
+ if (main->rowgroup_ctr < main->rowgroups_avail)
+ return; /* Need to suspend */
+ /* After the first iMCU, change wraparound pointers to normal state */
+ if (main->iMCU_row_ctr == 1)
+ set_wraparound_pointers(cinfo);
+ /* Prepare to load new iMCU row using other xbuffer list */
+ main->whichptr ^= 1; /* 0=>1 or 1=>0 */
+ main->buffer_full = FALSE;
+ /* Still need to process last row group of this iMCU row, */
+ /* which is saved at index M+1 of the other xbuffer */
+ main->rowgroup_ctr = (JDIMENSION) (cinfo->min_DCT_scaled_size + 1);
+ main->rowgroups_avail = (JDIMENSION) (cinfo->min_DCT_scaled_size + 2);
+ main->context_state = CTX_POSTPONED_ROW;
+ }
+}
+
+
+/*
+ * Process some data.
+ * Final pass of two-pass quantization: just call the postprocessor.
+ * Source data will be the postprocessor controller's internal buffer.
+ */
+
+#ifdef TQUANT_2PASS_SUPPORTED
+
+METHODDEF(void)
+process_data_crank_post (j_decompress_ptr cinfo,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ (*cinfo->post->post_process_data) (cinfo, (JSAMPIMAGE) NULL,
+ (JDIMENSION *) NULL, (JDIMENSION) 0,
+ output_buf, out_row_ctr, out_rows_avail);
+}
+
+#endif /* TQUANT_2PASS_SUPPORTED */
+
+
+/*
+ * Initialize main buffer controller.
+ */
+
+GLOBAL(void)
+jinit_d_main_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
+{
+ my_main_ptr main;
+ int ci, rgroup, ngroups;
+ jpeg_component_info *compptr;
+
+ main = (my_main_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_main_controller));
+ cinfo->main = (struct jpeg_d_main_controller *) main;
+ main->pub.start_pass = start_pass_main;
+
+ if (need_full_buffer) /* shouldn't happen */
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+
+ /* Allocate the workspace.
+ * ngroups is the number of row groups we need.
+ */
+ if (cinfo->upsample->need_context_rows) {
+ if (cinfo->min_DCT_scaled_size < 2) /* unsupported, see comments above */
+ ERREXIT(cinfo, JERR_NOTIMPL);
+ alloc_funny_pointers(cinfo); /* Alloc space for xbuffer[] lists */
+ ngroups = cinfo->min_DCT_scaled_size + 2;
+ } else {
+ ngroups = cinfo->min_DCT_scaled_size;
+ }
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ rgroup = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+ cinfo->min_DCT_scaled_size; /* height of a row group of component */
+ main->buffer[ci] = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ compptr->width_in_blocks * compptr->DCT_scaled_size,
+ (JDIMENSION) (rgroup * ngroups));
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdmarker.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdmarker.c
new file mode 100644
index 0000000..2247b34
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdmarker.c
@@ -0,0 +1,1360 @@
+/*
+ * jdmarker.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains routines to decode JPEG datastream markers.
+ * Most of the complexity arises from our desire to support input
+ * suspension: if not all of the data for a marker is available,
+ * we must exit back to the application. On resumption, we reprocess
+ * the marker.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+typedef enum { /* JPEG marker codes */
+ M_SOF0 = 0xc0,
+ M_SOF1 = 0xc1,
+ M_SOF2 = 0xc2,
+ M_SOF3 = 0xc3,
+
+ M_SOF5 = 0xc5,
+ M_SOF6 = 0xc6,
+ M_SOF7 = 0xc7,
+
+ M_JPG = 0xc8,
+ M_SOF9 = 0xc9,
+ M_SOF10 = 0xca,
+ M_SOF11 = 0xcb,
+
+ M_SOF13 = 0xcd,
+ M_SOF14 = 0xce,
+ M_SOF15 = 0xcf,
+
+ M_DHT = 0xc4,
+
+ M_DAC = 0xcc,
+
+ M_RST0 = 0xd0,
+ M_RST1 = 0xd1,
+ M_RST2 = 0xd2,
+ M_RST3 = 0xd3,
+ M_RST4 = 0xd4,
+ M_RST5 = 0xd5,
+ M_RST6 = 0xd6,
+ M_RST7 = 0xd7,
+
+ M_SOI = 0xd8,
+ M_EOI = 0xd9,
+ M_SOS = 0xda,
+ M_DQT = 0xdb,
+ M_DNL = 0xdc,
+ M_DRI = 0xdd,
+ M_DHP = 0xde,
+ M_EXP = 0xdf,
+
+ M_APP0 = 0xe0,
+ M_APP1 = 0xe1,
+ M_APP2 = 0xe2,
+ M_APP3 = 0xe3,
+ M_APP4 = 0xe4,
+ M_APP5 = 0xe5,
+ M_APP6 = 0xe6,
+ M_APP7 = 0xe7,
+ M_APP8 = 0xe8,
+ M_APP9 = 0xe9,
+ M_APP10 = 0xea,
+ M_APP11 = 0xeb,
+ M_APP12 = 0xec,
+ M_APP13 = 0xed,
+ M_APP14 = 0xee,
+ M_APP15 = 0xef,
+
+ M_JPG0 = 0xf0,
+ M_JPG13 = 0xfd,
+ M_COM = 0xfe,
+
+ M_TEM = 0x01,
+
+ M_ERROR = 0x100
+} JPEG_MARKER;
+
+
+/* Private state */
+
+typedef struct {
+ struct jpeg_marker_reader pub; /* public fields */
+
+ /* Application-overridable marker processing methods */
+ jpeg_marker_parser_method process_COM;
+ jpeg_marker_parser_method process_APPn[16];
+
+ /* Limit on marker data length to save for each marker type */
+ unsigned int length_limit_COM;
+ unsigned int length_limit_APPn[16];
+
+ /* tqStatus of COM/APPn marker saving */
+ jpeg_saved_marker_ptr cur_marker; /* NULL if not processing a marker */
+ unsigned int bytes_read; /* data bytes read so far in marker */
+ /* Note: cur_marker is not linked into marker_list until it's all read. */
+} my_marker_reader;
+
+typedef my_marker_reader * my_marker_ptr;
+
+
+/*
+ * Macros for fetching data from the data source module.
+ *
+ * At all times, cinfo->src->next_input_byte and ->bytes_in_buffer reflect
+ * the current restart point; we update them only when we have reached a
+ * suitable place to restart if a suspension occurs.
+ */
+
+/* Declare and initialize local copies of input pointer/count */
+#define INPUT_VARS(cinfo) \
+ struct jpeg_source_mgr * datasrc = (cinfo)->src; \
+ const JOCTET * next_input_byte = datasrc->next_input_byte; \
+ size_t bytes_in_buffer = datasrc->bytes_in_buffer
+
+/* Unload the local copies --- do this only at a restart boundary */
+#define INPUT_SYNC(cinfo) \
+ ( datasrc->next_input_byte = next_input_byte, \
+ datasrc->bytes_in_buffer = bytes_in_buffer )
+
+/* Reload the local copies --- used only in MAKE_BYTE_AVAIL */
+#define INPUT_RELOAD(cinfo) \
+ ( next_input_byte = datasrc->next_input_byte, \
+ bytes_in_buffer = datasrc->bytes_in_buffer )
+
+/* Internal macro for INPUT_BYTE and INPUT_2BYTES: make a byte available.
+ * Note we do *not* do INPUT_SYNC before calling fill_input_buffer,
+ * but we must reload the local copies after a successful fill.
+ */
+#define MAKE_BYTE_AVAIL(cinfo,action) \
+ if (bytes_in_buffer == 0) { \
+ if (! (*datasrc->fill_input_buffer) (cinfo)) \
+ { action; } \
+ INPUT_RELOAD(cinfo); \
+ }
+
+/* Read a byte into variable V.
+ * If must suspend, take the specified action (typically "return FALSE").
+ */
+#define INPUT_BYTE(cinfo,V,action) \
+ MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
+ bytes_in_buffer--; \
+ V = GETJOCTET(*next_input_byte++); )
+
+/* As above, but read two bytes interpreted as an unsigned 16-bit integer.
+ * V should be declared unsigned int or perhaps INT32.
+ */
+#define INPUT_2BYTES(cinfo,V,action) \
+ MAKESTMT( MAKE_BYTE_AVAIL(cinfo,action); \
+ bytes_in_buffer--; \
+ V = ((unsigned int) GETJOCTET(*next_input_byte++)) << 8; \
+ MAKE_BYTE_AVAIL(cinfo,action); \
+ bytes_in_buffer--; \
+ V += GETJOCTET(*next_input_byte++); )
+
+
+/*
+ * Routines to process JPEG markers.
+ *
+ * Entry condition: JPEG marker itself has been read and its code saved
+ * in cinfo->unread_marker; input restart point is just after the marker.
+ *
+ * Exit: if return TRUE, have read and processed any parameters, and have
+ * updated the restart point to point after the parameters.
+ * If return FALSE, was forced to suspend before reaching end of
+ * marker parameters; restart point has not been moved. Same routine
+ * will be called again after application supplies more input data.
+ *
+ * This approach to suspension assumes that all of a marker's parameters
+ * can fit into a single input bufferload. This should hold for "normal"
+ * markers. Some COM/APPn markers might have large parameter segments
+ * that might not fit. If we are simply dropping such a marker, we use
+ * skip_input_data to get past it, and thereby put the problem on the
+ * source manager's shoulders. If we are saving the marker's contents
+ * into memory, we use a slightly different convention: when forced to
+ * suspend, the marker processor updates the restart point to the end of
+ * what it's consumed (ie, the end of the buffer) before returning FALSE.
+ * On resumption, cinfo->unread_marker still tqcontains the marker code,
+ * but the data source will point to the next chunk of marker data.
+ * The marker processor must retain internal state to deal with this.
+ *
+ * Note that we don't bother to avoid duplicate trace messages if a
+ * suspension occurs within marker parameters. Other side effects
+ * require more care.
+ */
+
+
+LOCAL(boolean)
+get_soi (j_decompress_ptr cinfo)
+/* Process an SOI marker */
+{
+ int i;
+
+ TRACEMS(cinfo, 1, JTRC_SOI);
+
+ if (cinfo->marker->saw_SOI)
+ ERREXIT(cinfo, JERR_SOI_DUPLICATE);
+
+ /* Reset all parameters that are defined to be reset by SOI */
+
+ for (i = 0; i < NUM_ARITH_TBLS; i++) {
+ cinfo->arith_dc_L[i] = 0;
+ cinfo->arith_dc_U[i] = 1;
+ cinfo->arith_ac_K[i] = 5;
+ }
+ cinfo->restart_interval = 0;
+
+ /* Set initial assumptions for colorspace etc */
+
+ cinfo->jpeg_color_space = JCS_UNKNOWN;
+ cinfo->CCIR601_sampling = FALSE; /* Assume non-CCIR sampling??? */
+
+ cinfo->saw_JFIF_marker = FALSE;
+ cinfo->JFIF_major_version = 1; /* set default JFIF APP0 values */
+ cinfo->JFIF_minor_version = 1;
+ cinfo->density_unit = 0;
+ cinfo->X_density = 1;
+ cinfo->Y_density = 1;
+ cinfo->saw_Adobe_marker = FALSE;
+ cinfo->Adobe_transform = 0;
+
+ cinfo->marker->saw_SOI = TRUE;
+
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+get_sof (j_decompress_ptr cinfo, boolean is_prog, boolean is_arith)
+/* Process a SOFn marker */
+{
+ INT32 length;
+ int c, ci;
+ jpeg_component_info * compptr;
+ INPUT_VARS(cinfo);
+
+ cinfo->progressive_mode = is_prog;
+ cinfo->arith_code = is_arith;
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+
+ INPUT_BYTE(cinfo, cinfo->data_precision, return FALSE);
+ INPUT_2BYTES(cinfo, cinfo->image_height, return FALSE);
+ INPUT_2BYTES(cinfo, cinfo->image_width, return FALSE);
+ INPUT_BYTE(cinfo, cinfo->num_components, return FALSE);
+
+ length -= 8;
+
+ TRACEMS4(cinfo, 1, JTRC_SOF, cinfo->unread_marker,
+ (int) cinfo->image_width, (int) cinfo->image_height,
+ cinfo->num_components);
+
+ if (cinfo->marker->saw_SOF)
+ ERREXIT(cinfo, JERR_SOF_DUPLICATE);
+
+ /* We don't support files in which the image height is initially specified */
+ /* as 0 and is later redefined by DNL. As long as we have to check that, */
+ /* might as well have a general sanity check. */
+ if (cinfo->image_height <= 0 || cinfo->image_width <= 0
+ || cinfo->num_components <= 0)
+ ERREXIT(cinfo, JERR_EMPTY_IMAGE);
+
+ if (length != (cinfo->num_components * 3))
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ if (cinfo->comp_info == NULL) /* do only once, even if suspend */
+ cinfo->comp_info = (jpeg_component_info *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->num_components * SIZEOF(jpeg_component_info));
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ compptr->component_index = ci;
+ INPUT_BYTE(cinfo, compptr->component_id, return FALSE);
+ INPUT_BYTE(cinfo, c, return FALSE);
+ compptr->h_samp_factor = (c >> 4) & 15;
+ compptr->v_samp_factor = (c ) & 15;
+ INPUT_BYTE(cinfo, compptr->quant_tbl_no, return FALSE);
+
+ TRACEMS4(cinfo, 1, JTRC_SOF_COMPONENT,
+ compptr->component_id, compptr->h_samp_factor,
+ compptr->v_samp_factor, compptr->quant_tbl_no);
+ }
+
+ cinfo->marker->saw_SOF = TRUE;
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+get_sos (j_decompress_ptr cinfo)
+/* Process a SOS marker */
+{
+ INT32 length;
+ int i, ci, n, c, cc;
+ jpeg_component_info * compptr;
+ INPUT_VARS(cinfo);
+
+ if (! cinfo->marker->saw_SOF)
+ ERREXIT(cinfo, JERR_SOS_NO_SOF);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+
+ INPUT_BYTE(cinfo, n, return FALSE); /* Number of components */
+
+ TRACEMS1(cinfo, 1, JTRC_SOS, n);
+
+ if (length != (n * 2 + 6) || n < 1 || n > MAX_COMPS_IN_SCAN)
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ cinfo->comps_in_scan = n;
+
+ /* Collect the component-spec parameters */
+
+ for (i = 0; i < n; i++) {
+ INPUT_BYTE(cinfo, cc, return FALSE);
+ INPUT_BYTE(cinfo, c, return FALSE);
+
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ if (cc == compptr->component_id)
+ goto id_found;
+ }
+
+ ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
+
+ id_found:
+
+ cinfo->cur_comp_info[i] = compptr;
+ compptr->dc_tbl_no = (c >> 4) & 15;
+ compptr->ac_tbl_no = (c ) & 15;
+
+ TRACEMS3(cinfo, 1, JTRC_SOS_COMPONENT, cc,
+ compptr->dc_tbl_no, compptr->ac_tbl_no);
+ }
+
+ /* Collect the additional scan parameters Ss, Se, Ah/Al. */
+ INPUT_BYTE(cinfo, c, return FALSE);
+ cinfo->Ss = c;
+ INPUT_BYTE(cinfo, c, return FALSE);
+ cinfo->Se = c;
+ INPUT_BYTE(cinfo, c, return FALSE);
+ cinfo->Ah = (c >> 4) & 15;
+ cinfo->Al = (c ) & 15;
+
+ TRACEMS4(cinfo, 1, JTRC_SOS_PARAMS, cinfo->Ss, cinfo->Se,
+ cinfo->Ah, cinfo->Al);
+
+ /* Prepare to scan data & restart markers */
+ cinfo->marker->next_restart_num = 0;
+
+ /* Count another SOS marker */
+ cinfo->input_scan_number++;
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+#ifdef D_ARITH_CODING_SUPPORTED
+
+LOCAL(boolean)
+get_dac (j_decompress_ptr cinfo)
+/* Process a DAC marker */
+{
+ INT32 length;
+ int index, val;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+
+ while (length > 0) {
+ INPUT_BYTE(cinfo, index, return FALSE);
+ INPUT_BYTE(cinfo, val, return FALSE);
+
+ length -= 2;
+
+ TRACEMS2(cinfo, 1, JTRC_DAC, index, val);
+
+ if (index < 0 || index >= (2*NUM_ARITH_TBLS))
+ ERREXIT1(cinfo, JERR_DAC_INDEX, index);
+
+ if (index >= NUM_ARITH_TBLS) { /* define AC table */
+ cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
+ } else { /* define DC table */
+ cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
+ cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
+ if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
+ ERREXIT1(cinfo, JERR_DAC_VALUE, val);
+ }
+ }
+
+ if (length != 0)
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+#else /* ! D_ARITH_CODING_SUPPORTED */
+
+#define get_dac(cinfo) skip_variable(cinfo)
+
+#endif /* D_ARITH_CODING_SUPPORTED */
+
+
+LOCAL(boolean)
+get_dht (j_decompress_ptr cinfo)
+/* Process a DHT marker */
+{
+ INT32 length;
+ UINT8 bits[17];
+ UINT8 huffval[256];
+ int i, index, count;
+ JHUFF_TBL **htblptr;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+
+ while (length > 16) {
+ INPUT_BYTE(cinfo, index, return FALSE);
+
+ TRACEMS1(cinfo, 1, JTRC_DHT, index);
+
+ bits[0] = 0;
+ count = 0;
+ for (i = 1; i <= 16; i++) {
+ INPUT_BYTE(cinfo, bits[i], return FALSE);
+ count += bits[i];
+ }
+
+ length -= 1 + 16;
+
+ TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
+ bits[1], bits[2], bits[3], bits[4],
+ bits[5], bits[6], bits[7], bits[8]);
+ TRACEMS8(cinfo, 2, JTRC_HUFFBITS,
+ bits[9], bits[10], bits[11], bits[12],
+ bits[13], bits[14], bits[15], bits[16]);
+
+ /* Here we just do minimal validation of the counts to avoid walking
+ * off the end of our table space. jdhuff.c will check more carefully.
+ */
+ if (count > 256 || ((INT32) count) > length)
+ ERREXIT(cinfo, JERR_BAD_HUFF_TABLE);
+
+ for (i = 0; i < count; i++)
+ INPUT_BYTE(cinfo, huffval[i], return FALSE);
+
+ length -= count;
+
+ if (index & 0x10) { /* AC table definition */
+ index -= 0x10;
+ htblptr = &cinfo->ac_huff_tbl_ptrs[index];
+ } else { /* DC table definition */
+ htblptr = &cinfo->dc_huff_tbl_ptrs[index];
+ }
+
+ if (index < 0 || index >= NUM_HUFF_TBLS)
+ ERREXIT1(cinfo, JERR_DHT_INDEX, index);
+
+ if (*htblptr == NULL)
+ *htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
+
+ MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
+ MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
+ }
+
+ if (length != 0)
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+get_dqt (j_decompress_ptr cinfo)
+/* Process a DQT marker */
+{
+ INT32 length;
+ int n, i, prec;
+ unsigned int tmp;
+ JTQUANT_TBL *quant_ptr;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+
+ while (length > 0) {
+ INPUT_BYTE(cinfo, n, return FALSE);
+ prec = n >> 4;
+ n &= 0x0F;
+
+ TRACEMS2(cinfo, 1, JTRC_DQT, n, prec);
+
+ if (n >= NUM_TQUANT_TBLS)
+ ERREXIT1(cinfo, JERR_DTQT_INDEX, n);
+
+ if (cinfo->quant_tbl_ptrs[n] == NULL)
+ cinfo->quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) cinfo);
+ quant_ptr = cinfo->quant_tbl_ptrs[n];
+
+ for (i = 0; i < DCTSIZE2; i++) {
+ if (prec)
+ INPUT_2BYTES(cinfo, tmp, return FALSE);
+ else
+ INPUT_BYTE(cinfo, tmp, return FALSE);
+ /* We convert the zigzag-order table to natural array order. */
+ quant_ptr->quantval[jpeg_natural_order[i]] = (UINT16) tmp;
+ }
+
+ if (cinfo->err->trace_level >= 2) {
+ for (i = 0; i < DCTSIZE2; i += 8) {
+ TRACEMS8(cinfo, 2, JTRC_TQUANTVALS,
+ quant_ptr->quantval[i], quant_ptr->quantval[i+1],
+ quant_ptr->quantval[i+2], quant_ptr->quantval[i+3],
+ quant_ptr->quantval[i+4], quant_ptr->quantval[i+5],
+ quant_ptr->quantval[i+6], quant_ptr->quantval[i+7]);
+ }
+ }
+
+ length -= DCTSIZE2+1;
+ if (prec) length -= DCTSIZE2;
+ }
+
+ if (length != 0)
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+get_dri (j_decompress_ptr cinfo)
+/* Process a DRI marker */
+{
+ INT32 length;
+ unsigned int tmp;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+
+ if (length != 4)
+ ERREXIT(cinfo, JERR_BAD_LENGTH);
+
+ INPUT_2BYTES(cinfo, tmp, return FALSE);
+
+ TRACEMS1(cinfo, 1, JTRC_DRI, tmp);
+
+ cinfo->restart_interval = tmp;
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+/*
+ * Routines for processing APPn and COM markers.
+ * These are either saved in memory or discarded, per application request.
+ * APP0 and APP14 are specially checked to see if they are
+ * JFIF and Adobe markers, respectively.
+ */
+
+#define APP0_DATA_LEN 14 /* Length of interesting data in APP0 */
+#define APP14_DATA_LEN 12 /* Length of interesting data in APP14 */
+#define APPN_DATA_LEN 14 /* Must be the largest of the above!! */
+
+
+LOCAL(void)
+examine_app0 (j_decompress_ptr cinfo, JOCTET FAR * data,
+ unsigned int datalen, INT32 remaining)
+/* Examine first few bytes from an APP0.
+ * Take appropriate action if it is a JFIF marker.
+ * datalen is # of bytes at data[], remaining is length of rest of marker data.
+ */
+{
+ INT32 totallen = (INT32) datalen + remaining;
+
+ if (datalen >= APP0_DATA_LEN &&
+ GETJOCTET(data[0]) == 0x4A &&
+ GETJOCTET(data[1]) == 0x46 &&
+ GETJOCTET(data[2]) == 0x49 &&
+ GETJOCTET(data[3]) == 0x46 &&
+ GETJOCTET(data[4]) == 0) {
+ /* Found JFIF APP0 marker: save info */
+ cinfo->saw_JFIF_marker = TRUE;
+ cinfo->JFIF_major_version = GETJOCTET(data[5]);
+ cinfo->JFIF_minor_version = GETJOCTET(data[6]);
+ cinfo->density_unit = GETJOCTET(data[7]);
+ cinfo->X_density = (GETJOCTET(data[8]) << 8) + GETJOCTET(data[9]);
+ cinfo->Y_density = (GETJOCTET(data[10]) << 8) + GETJOCTET(data[11]);
+ /* Check version.
+ * Major version must be 1, anything else Q_SIGNALS an incompatible change.
+ * (We used to treat this as an error, but now it's a nonfatal warning,
+ * because some bozo at Hijaak couldn't read the spec.)
+ * Minor version should be 0..2, but process anyway if newer.
+ */
+ if (cinfo->JFIF_major_version != 1)
+ WARNMS2(cinfo, JWRN_JFIF_MAJOR,
+ cinfo->JFIF_major_version, cinfo->JFIF_minor_version);
+ /* Generate trace messages */
+ TRACEMS5(cinfo, 1, JTRC_JFIF,
+ cinfo->JFIF_major_version, cinfo->JFIF_minor_version,
+ cinfo->X_density, cinfo->Y_density, cinfo->density_unit);
+ /* Validate thumbnail dimensions and issue appropriate messages */
+ if (GETJOCTET(data[12]) | GETJOCTET(data[13]))
+ TRACEMS2(cinfo, 1, JTRC_JFIF_THUMBNAIL,
+ GETJOCTET(data[12]), GETJOCTET(data[13]));
+ totallen -= APP0_DATA_LEN;
+ if (totallen !=
+ ((INT32)GETJOCTET(data[12]) * (INT32)GETJOCTET(data[13]) * (INT32) 3))
+ TRACEMS1(cinfo, 1, JTRC_JFIF_BADTHUMBNAILSIZE, (int) totallen);
+ } else if (datalen >= 6 &&
+ GETJOCTET(data[0]) == 0x4A &&
+ GETJOCTET(data[1]) == 0x46 &&
+ GETJOCTET(data[2]) == 0x58 &&
+ GETJOCTET(data[3]) == 0x58 &&
+ GETJOCTET(data[4]) == 0) {
+ /* Found JFIF "JFXX" extension APP0 marker */
+ /* The library doesn't actually do anything with these,
+ * but we try to produce a helpful trace message.
+ */
+ switch (GETJOCTET(data[5])) {
+ case 0x10:
+ TRACEMS1(cinfo, 1, JTRC_THUMB_JPEG, (int) totallen);
+ break;
+ case 0x11:
+ TRACEMS1(cinfo, 1, JTRC_THUMB_PALETTE, (int) totallen);
+ break;
+ case 0x13:
+ TRACEMS1(cinfo, 1, JTRC_THUMB_RGB, (int) totallen);
+ break;
+ default:
+ TRACEMS2(cinfo, 1, JTRC_JFIF_EXTENSION,
+ GETJOCTET(data[5]), (int) totallen);
+ break;
+ }
+ } else {
+ /* Start of APP0 does not match "JFIF" or "JFXX", or too short */
+ TRACEMS1(cinfo, 1, JTRC_APP0, (int) totallen);
+ }
+}
+
+
+LOCAL(void)
+examine_app14 (j_decompress_ptr cinfo, JOCTET FAR * data,
+ unsigned int datalen, INT32 remaining)
+/* Examine first few bytes from an APP14.
+ * Take appropriate action if it is an Adobe marker.
+ * datalen is # of bytes at data[], remaining is length of rest of marker data.
+ */
+{
+ unsigned int version, flags0, flags1, transform;
+
+ if (datalen >= APP14_DATA_LEN &&
+ GETJOCTET(data[0]) == 0x41 &&
+ GETJOCTET(data[1]) == 0x64 &&
+ GETJOCTET(data[2]) == 0x6F &&
+ GETJOCTET(data[3]) == 0x62 &&
+ GETJOCTET(data[4]) == 0x65) {
+ /* Found Adobe APP14 marker */
+ version = (GETJOCTET(data[5]) << 8) + GETJOCTET(data[6]);
+ flags0 = (GETJOCTET(data[7]) << 8) + GETJOCTET(data[8]);
+ flags1 = (GETJOCTET(data[9]) << 8) + GETJOCTET(data[10]);
+ transform = GETJOCTET(data[11]);
+ TRACEMS4(cinfo, 1, JTRC_ADOBE, version, flags0, flags1, transform);
+ cinfo->saw_Adobe_marker = TRUE;
+ cinfo->Adobe_transform = (UINT8) transform;
+ } else {
+ /* Start of APP14 does not match "Adobe", or too short */
+ TRACEMS1(cinfo, 1, JTRC_APP14, (int) (datalen + remaining));
+ }
+}
+
+
+METHODDEF(boolean)
+get_interesting_appn (j_decompress_ptr cinfo)
+/* Process an APP0 or APP14 marker without saving it */
+{
+ INT32 length;
+ JOCTET b[APPN_DATA_LEN];
+ unsigned int i, numtoread;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+
+ /* get the interesting part of the marker data */
+ if (length >= APPN_DATA_LEN)
+ numtoread = APPN_DATA_LEN;
+ else if (length > 0)
+ numtoread = (unsigned int) length;
+ else
+ numtoread = 0;
+ for (i = 0; i < numtoread; i++)
+ INPUT_BYTE(cinfo, b[i], return FALSE);
+ length -= numtoread;
+
+ /* process it */
+ switch (cinfo->unread_marker) {
+ case M_APP0:
+ examine_app0(cinfo, (JOCTET FAR *) b, numtoread, length);
+ break;
+ case M_APP14:
+ examine_app14(cinfo, (JOCTET FAR *) b, numtoread, length);
+ break;
+ default:
+ /* can't get here unless jpeg_save_markers chooses wrong processor */
+ ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
+ break;
+ }
+
+ /* skip any remaining data -- could be lots */
+ INPUT_SYNC(cinfo);
+ if (length > 0)
+ (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+ return TRUE;
+}
+
+
+#ifdef SAVE_MARKERS_SUPPORTED
+
+METHODDEF(boolean)
+save_marker (j_decompress_ptr cinfo)
+/* Save an APPn or COM marker into the marker list */
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+ jpeg_saved_marker_ptr cur_marker = marker->cur_marker;
+ unsigned int bytes_read, data_length;
+ JOCTET FAR * data;
+ INT32 length = 0;
+ INPUT_VARS(cinfo);
+
+ if (cur_marker == NULL) {
+ /* begin reading a marker */
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+ if (length >= 0) { /* watch out for bogus length word */
+ /* figure out how much we want to save */
+ unsigned int limit;
+ if (cinfo->unread_marker == (int) M_COM)
+ limit = marker->length_limit_COM;
+ else
+ limit = marker->length_limit_APPn[cinfo->unread_marker - (int) M_APP0];
+ if ((unsigned int) length < limit)
+ limit = (unsigned int) length;
+ /* allocate and initialize the marker item */
+ cur_marker = (jpeg_saved_marker_ptr)
+ (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(struct jpeg_marker_struct) + limit);
+ cur_marker->next = NULL;
+ cur_marker->marker = (UINT8) cinfo->unread_marker;
+ cur_marker->original_length = (unsigned int) length;
+ cur_marker->data_length = limit;
+ /* data area is just beyond the jpeg_marker_struct */
+ data = cur_marker->data = (JOCTET FAR *) (cur_marker + 1);
+ marker->cur_marker = cur_marker;
+ marker->bytes_read = 0;
+ bytes_read = 0;
+ data_length = limit;
+ } else {
+ /* deal with bogus length word */
+ bytes_read = data_length = 0;
+ data = NULL;
+ }
+ } else {
+ /* resume reading a marker */
+ bytes_read = marker->bytes_read;
+ data_length = cur_marker->data_length;
+ data = cur_marker->data + bytes_read;
+ }
+
+ while (bytes_read < data_length) {
+ INPUT_SYNC(cinfo); /* move the restart point to here */
+ marker->bytes_read = bytes_read;
+ /* If there's not at least one byte in buffer, suspend */
+ MAKE_BYTE_AVAIL(cinfo, return FALSE);
+ /* Copy bytes with reasonable rapidity */
+ while (bytes_read < data_length && bytes_in_buffer > 0) {
+ *data++ = *next_input_byte++;
+ bytes_in_buffer--;
+ bytes_read++;
+ }
+ }
+
+ /* Done reading what we want to read */
+ if (cur_marker != NULL) { /* will be NULL if bogus length word */
+ /* Add new marker to end of list */
+ if (cinfo->marker_list == NULL) {
+ cinfo->marker_list = cur_marker;
+ } else {
+ jpeg_saved_marker_ptr prev = cinfo->marker_list;
+ while (prev->next != NULL)
+ prev = prev->next;
+ prev->next = cur_marker;
+ }
+ /* Reset pointer & calc remaining data length */
+ data = cur_marker->data;
+ length = cur_marker->original_length - data_length;
+ }
+ /* Reset to initial state for next marker */
+ marker->cur_marker = NULL;
+
+ /* Process the marker if interesting; else just make a generic trace msg */
+ switch (cinfo->unread_marker) {
+ case M_APP0:
+ examine_app0(cinfo, data, data_length, length);
+ break;
+ case M_APP14:
+ examine_app14(cinfo, data, data_length, length);
+ break;
+ default:
+ TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker,
+ (int) (data_length + length));
+ break;
+ }
+
+ /* skip any remaining data -- could be lots */
+ INPUT_SYNC(cinfo); /* do before skip_input_data */
+ if (length > 0)
+ (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+ return TRUE;
+}
+
+#endif /* SAVE_MARKERS_SUPPORTED */
+
+
+METHODDEF(boolean)
+skip_variable (j_decompress_ptr cinfo)
+/* Skip over an unknown or uninteresting variable-length marker */
+{
+ INT32 length;
+ INPUT_VARS(cinfo);
+
+ INPUT_2BYTES(cinfo, length, return FALSE);
+ length -= 2;
+
+ TRACEMS2(cinfo, 1, JTRC_MISC_MARKER, cinfo->unread_marker, (int) length);
+
+ INPUT_SYNC(cinfo); /* do before skip_input_data */
+ if (length > 0)
+ (*cinfo->src->skip_input_data) (cinfo, (long) length);
+
+ return TRUE;
+}
+
+
+/*
+ * Find the next JPEG marker, save it in cinfo->unread_marker.
+ * Returns FALSE if had to suspend before reaching a marker;
+ * in that case cinfo->unread_marker is unchanged.
+ *
+ * Note that the result might not be a valid marker code,
+ * but it will never be 0 or FF.
+ */
+
+LOCAL(boolean)
+next_marker (j_decompress_ptr cinfo)
+{
+ int c;
+ INPUT_VARS(cinfo);
+
+ for (;;) {
+ INPUT_BYTE(cinfo, c, return FALSE);
+ /* Skip any non-FF bytes.
+ * This may look a bit inefficient, but it will not occur in a valid file.
+ * We sync after each discarded byte so that a suspending data source
+ * can discard the byte from its buffer.
+ */
+ while (c != 0xFF) {
+ cinfo->marker->discarded_bytes++;
+ INPUT_SYNC(cinfo);
+ INPUT_BYTE(cinfo, c, return FALSE);
+ }
+ /* This loop swallows any duplicate FF bytes. Extra FFs are legal as
+ * pad bytes, so don't count them in discarded_bytes. We assume there
+ * will not be so many consecutive FF bytes as to overflow a suspending
+ * data source's input buffer.
+ */
+ do {
+ INPUT_BYTE(cinfo, c, return FALSE);
+ } while (c == 0xFF);
+ if (c != 0)
+ break; /* found a valid marker, exit loop */
+ /* Reach here if we found a stuffed-zero data sequence (FF/00).
+ * Discard it and loop back to try again.
+ */
+ cinfo->marker->discarded_bytes += 2;
+ INPUT_SYNC(cinfo);
+ }
+
+ if (cinfo->marker->discarded_bytes != 0) {
+ WARNMS2(cinfo, JWRN_EXTRANEOUS_DATA, cinfo->marker->discarded_bytes, c);
+ cinfo->marker->discarded_bytes = 0;
+ }
+
+ cinfo->unread_marker = c;
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+LOCAL(boolean)
+first_marker (j_decompress_ptr cinfo)
+/* Like next_marker, but used to obtain the initial SOI marker. */
+/* For this marker, we do not allow preceding garbage or fill; otherwise,
+ * we might well scan an entire input file before realizing it ain't JPEG.
+ * If an application wants to process non-JFIF files, it must seek to the
+ * SOI before calling the JPEG library.
+ */
+{
+ int c, c2;
+ INPUT_VARS(cinfo);
+
+ INPUT_BYTE(cinfo, c, return FALSE);
+ INPUT_BYTE(cinfo, c2, return FALSE);
+ if (c != 0xFF || c2 != (int) M_SOI)
+ ERREXIT2(cinfo, JERR_NO_SOI, c, c2);
+
+ cinfo->unread_marker = c2;
+
+ INPUT_SYNC(cinfo);
+ return TRUE;
+}
+
+
+/*
+ * Read markers until SOS or EOI.
+ *
+ * Returns same codes as are defined for jpeg_consume_input:
+ * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
+ */
+
+METHODDEF(int)
+read_markers (j_decompress_ptr cinfo)
+{
+ /* Outer loop repeats once for each marker. */
+ for (;;) {
+ /* Collect the marker proper, unless we already did. */
+ /* NB: first_marker() enforces the requirement that SOI appear first. */
+ if (cinfo->unread_marker == 0) {
+ if (! cinfo->marker->saw_SOI) {
+ if (! first_marker(cinfo))
+ return JPEG_SUSPENDED;
+ } else {
+ if (! next_marker(cinfo))
+ return JPEG_SUSPENDED;
+ }
+ }
+ /* At this point cinfo->unread_marker tqcontains the marker code and the
+ * input point is just past the marker proper, but before any parameters.
+ * A suspension will cause us to return with this state still true.
+ */
+ switch (cinfo->unread_marker) {
+ case M_SOI:
+ if (! get_soi(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_SOF0: /* Baseline */
+ case M_SOF1: /* Extended sequential, Huffman */
+ if (! get_sof(cinfo, FALSE, FALSE))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_SOF2: /* Progressive, Huffman */
+ if (! get_sof(cinfo, TRUE, FALSE))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_SOF9: /* Extended sequential, arithmetic */
+ if (! get_sof(cinfo, FALSE, TRUE))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_SOF10: /* Progressive, arithmetic */
+ if (! get_sof(cinfo, TRUE, TRUE))
+ return JPEG_SUSPENDED;
+ break;
+
+ /* Currently unsupported SOFn types */
+ case M_SOF3: /* Lossless, Huffman */
+ case M_SOF5: /* Differential sequential, Huffman */
+ case M_SOF6: /* Differential progressive, Huffman */
+ case M_SOF7: /* Differential lossless, Huffman */
+ case M_JPG: /* Reserved for JPEG extensions */
+ case M_SOF11: /* Lossless, arithmetic */
+ case M_SOF13: /* Differential sequential, arithmetic */
+ case M_SOF14: /* Differential progressive, arithmetic */
+ case M_SOF15: /* Differential lossless, arithmetic */
+ ERREXIT1(cinfo, JERR_SOF_UNSUPPORTED, cinfo->unread_marker);
+ break;
+
+ case M_SOS:
+ if (! get_sos(cinfo))
+ return JPEG_SUSPENDED;
+ cinfo->unread_marker = 0; /* processed the marker */
+ return JPEG_REACHED_SOS;
+
+ case M_EOI:
+ TRACEMS(cinfo, 1, JTRC_EOI);
+ cinfo->unread_marker = 0; /* processed the marker */
+ return JPEG_REACHED_EOI;
+
+ case M_DAC:
+ if (! get_dac(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_DHT:
+ if (! get_dht(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_DQT:
+ if (! get_dqt(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_DRI:
+ if (! get_dri(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_APP0:
+ case M_APP1:
+ case M_APP2:
+ case M_APP3:
+ case M_APP4:
+ case M_APP5:
+ case M_APP6:
+ case M_APP7:
+ case M_APP8:
+ case M_APP9:
+ case M_APP10:
+ case M_APP11:
+ case M_APP12:
+ case M_APP13:
+ case M_APP14:
+ case M_APP15:
+ if (! (*((my_marker_ptr) cinfo->marker)->process_APPn[
+ cinfo->unread_marker - (int) M_APP0]) (cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_COM:
+ if (! (*((my_marker_ptr) cinfo->marker)->process_COM) (cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ case M_RST0: /* these are all parameterless */
+ case M_RST1:
+ case M_RST2:
+ case M_RST3:
+ case M_RST4:
+ case M_RST5:
+ case M_RST6:
+ case M_RST7:
+ case M_TEM:
+ TRACEMS1(cinfo, 1, JTRC_PARMLESS_MARKER, cinfo->unread_marker);
+ break;
+
+ case M_DNL: /* Ignore DNL ... perhaps the wrong thing */
+ if (! skip_variable(cinfo))
+ return JPEG_SUSPENDED;
+ break;
+
+ default: /* must be DHP, EXP, JPGn, or RESn */
+ /* For now, we treat the reserved markers as fatal errors since they are
+ * likely to be used to signal incompatible JPEG Part 3 extensions.
+ * Once the JPEG 3 version-number marker is well defined, this code
+ * ought to change!
+ */
+ ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, cinfo->unread_marker);
+ break;
+ }
+ /* Successfully processed marker, so reset state variable */
+ cinfo->unread_marker = 0;
+ } /* end loop */
+}
+
+
+/*
+ * Read a restart marker, which is expected to appear next in the datastream;
+ * if the marker is not there, take appropriate recovery action.
+ * Returns FALSE if suspension is required.
+ *
+ * This is called by the entropy decoder after it has read an appropriate
+ * number of MCUs. cinfo->unread_marker may be nonzero if the entropy decoder
+ * has already read a marker from the data source. Under normal conditions
+ * cinfo->unread_marker will be reset to 0 before returning; if not reset,
+ * it holds a marker which the decoder will be unable to read past.
+ */
+
+METHODDEF(boolean)
+read_restart_marker (j_decompress_ptr cinfo)
+{
+ /* Obtain a marker unless we already did. */
+ /* Note that next_marker will complain if it skips any data. */
+ if (cinfo->unread_marker == 0) {
+ if (! next_marker(cinfo))
+ return FALSE;
+ }
+
+ if (cinfo->unread_marker ==
+ ((int) M_RST0 + cinfo->marker->next_restart_num)) {
+ /* Normal case --- swallow the marker and let entropy decoder continue */
+ TRACEMS1(cinfo, 3, JTRC_RST, cinfo->marker->next_restart_num);
+ cinfo->unread_marker = 0;
+ } else {
+ /* Uh-oh, the restart markers have been messed up. */
+ /* Let the data source manager determine how to resync. */
+ if (! (*cinfo->src->resync_to_restart) (cinfo,
+ cinfo->marker->next_restart_num))
+ return FALSE;
+ }
+
+ /* Update next-restart state */
+ cinfo->marker->next_restart_num = (cinfo->marker->next_restart_num + 1) & 7;
+
+ return TRUE;
+}
+
+
+/*
+ * This is the default resync_to_restart method for data source managers
+ * to use if they don't have any better approach. Some data source managers
+ * may be able to back up, or may have additional knowledge about the data
+ * which permits a more intelligent recovery strategy; such managers would
+ * presumably supply their own resync method.
+ *
+ * read_restart_marker calls resync_to_restart if it tqfinds a marker other than
+ * the restart marker it was expecting. (This code is *not* used unless
+ * a nonzero restart interval has been declared.) cinfo->unread_marker is
+ * the marker code actually found (might be anything, except 0 or FF).
+ * The desired restart marker number (0..7) is passed as a parameter.
+ * This routine is supposed to apply whatever error recovery strategy seems
+ * appropriate in order to position the input stream to the next data segment.
+ * Note that cinfo->unread_marker is treated as a marker appearing before
+ * the current data-source input point; usually it should be reset to zero
+ * before returning.
+ * Returns FALSE if suspension is required.
+ *
+ * This implementation is substantially constrained by wanting to treat the
+ * input as a data stream; this means we can't back up. Therefore, we have
+ * only the following actions to work with:
+ * 1. Simply discard the marker and let the entropy decoder resume at next
+ * byte of file.
+ * 2. Read forward until we tqfind another marker, discarding intervening
+ * data. (In theory we could look ahead within the current bufferload,
+ * without having to discard data if we don't tqfind the desired marker.
+ * This idea is not implemented here, in part because it makes behavior
+ * dependent on buffer size and chance buffer-boundary positions.)
+ * 3. Leave the marker unread (by failing to zero cinfo->unread_marker).
+ * This will cause the entropy decoder to process an empty data segment,
+ * inserting dummy zeroes, and then we will reprocess the marker.
+ *
+ * #2 is appropriate if we think the desired marker lies ahead, while #3 is
+ * appropriate if the found marker is a future restart marker (indicating
+ * that we have missed the desired restart marker, probably because it got
+ * corrupted).
+ * We apply #2 or #3 if the found marker is a restart marker no more than
+ * two counts behind or ahead of the expected one. We also apply #2 if the
+ * found marker is not a legal JPEG marker code (it's certainly bogus data).
+ * If the found marker is a restart marker more than 2 counts away, we do #1
+ * (too much risk that the marker is erroneous; with luck we will be able to
+ * resync at some future point).
+ * For any valid non-restart JPEG marker, we apply #3. This keeps us from
+ * overrunning the end of a scan. An implementation limited to single-scan
+ * files might tqfind it better to apply #2 for markers other than EOI, since
+ * any other marker would have to be bogus data in that case.
+ */
+
+GLOBAL(boolean)
+jpeg_resync_to_restart (j_decompress_ptr cinfo, int desired)
+{
+ int marker = cinfo->unread_marker;
+ int action = 1;
+
+ /* Always put up a warning. */
+ WARNMS2(cinfo, JWRN_MUST_RESYNC, marker, desired);
+
+ /* Outer loop handles repeated decision after scanning forward. */
+ for (;;) {
+ if (marker < (int) M_SOF0)
+ action = 2; /* invalid marker */
+ else if (marker < (int) M_RST0 || marker > (int) M_RST7)
+ action = 3; /* valid non-restart marker */
+ else {
+ if (marker == ((int) M_RST0 + ((desired+1) & 7)) ||
+ marker == ((int) M_RST0 + ((desired+2) & 7)))
+ action = 3; /* one of the next two expected restarts */
+ else if (marker == ((int) M_RST0 + ((desired-1) & 7)) ||
+ marker == ((int) M_RST0 + ((desired-2) & 7)))
+ action = 2; /* a prior restart, so advance */
+ else
+ action = 1; /* desired restart or too far away */
+ }
+ TRACEMS2(cinfo, 4, JTRC_RECOVERY_ACTION, marker, action);
+ switch (action) {
+ case 1:
+ /* Discard marker and let entropy decoder resume processing. */
+ cinfo->unread_marker = 0;
+ return TRUE;
+ case 2:
+ /* Scan to the next marker, and repeat the decision loop. */
+ if (! next_marker(cinfo))
+ return FALSE;
+ marker = cinfo->unread_marker;
+ break;
+ case 3:
+ /* Return without advancing past this marker. */
+ /* Entropy decoder will be forced to process an empty segment. */
+ return TRUE;
+ }
+ } /* end loop */
+}
+
+
+/*
+ * Reset marker processing state to begin a fresh datastream.
+ */
+
+METHODDEF(void)
+reset_marker_reader (j_decompress_ptr cinfo)
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
+ cinfo->comp_info = NULL; /* until allocated by get_sof */
+ cinfo->input_scan_number = 0; /* no SOS seen yet */
+ cinfo->unread_marker = 0; /* no pending marker */
+ marker->pub.saw_SOI = FALSE; /* set internal state too */
+ marker->pub.saw_SOF = FALSE;
+ marker->pub.discarded_bytes = 0;
+ marker->cur_marker = NULL;
+}
+
+
+/*
+ * Initialize the marker reader module.
+ * This is called only once, when the decompression object is created.
+ */
+
+GLOBAL(void)
+jinit_marker_reader (j_decompress_ptr cinfo)
+{
+ my_marker_ptr marker;
+ int i;
+
+ /* Create subobject in permanent pool */
+ marker = (my_marker_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
+ SIZEOF(my_marker_reader));
+ cinfo->marker = (struct jpeg_marker_reader *) marker;
+ /* Initialize public method pointers */
+ marker->pub.reset_marker_reader = reset_marker_reader;
+ marker->pub.read_markers = read_markers;
+ marker->pub.read_restart_marker = read_restart_marker;
+ /* Initialize COM/APPn processing.
+ * By default, we examine and then discard APP0 and APP14,
+ * but simply discard COM and all other APPn.
+ */
+ marker->process_COM = skip_variable;
+ marker->length_limit_COM = 0;
+ for (i = 0; i < 16; i++) {
+ marker->process_APPn[i] = skip_variable;
+ marker->length_limit_APPn[i] = 0;
+ }
+ marker->process_APPn[0] = get_interesting_appn;
+ marker->process_APPn[14] = get_interesting_appn;
+ /* Reset marker processing state */
+ reset_marker_reader(cinfo);
+}
+
+
+/*
+ * Control saving of COM and APPn markers into marker_list.
+ */
+
+#ifdef SAVE_MARKERS_SUPPORTED
+
+GLOBAL(void)
+jpeg_save_markers (j_decompress_ptr cinfo, int marker_code,
+ unsigned int length_limit)
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+ long maxlength;
+ jpeg_marker_parser_method processor;
+
+ /* Length limit mustn't be larger than what we can allocate
+ * (should only be a concern in a 16-bit environment).
+ */
+ maxlength = cinfo->mem->max_alloc_chunk - SIZEOF(struct jpeg_marker_struct);
+ if (((long) length_limit) > maxlength)
+ length_limit = (unsigned int) maxlength;
+
+ /* Choose processor routine to use.
+ * APP0/APP14 have special requirements.
+ */
+ if (length_limit) {
+ processor = save_marker;
+ /* If saving APP0/APP14, save at least enough for our internal use. */
+ if (marker_code == (int) M_APP0 && length_limit < APP0_DATA_LEN)
+ length_limit = APP0_DATA_LEN;
+ else if (marker_code == (int) M_APP14 && length_limit < APP14_DATA_LEN)
+ length_limit = APP14_DATA_LEN;
+ } else {
+ processor = skip_variable;
+ /* If discarding APP0/APP14, use our regular on-the-fly processor. */
+ if (marker_code == (int) M_APP0 || marker_code == (int) M_APP14)
+ processor = get_interesting_appn;
+ }
+
+ if (marker_code == (int) M_COM) {
+ marker->process_COM = processor;
+ marker->length_limit_COM = length_limit;
+ } else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15) {
+ marker->process_APPn[marker_code - (int) M_APP0] = processor;
+ marker->length_limit_APPn[marker_code - (int) M_APP0] = length_limit;
+ } else
+ ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
+}
+
+#endif /* SAVE_MARKERS_SUPPORTED */
+
+
+/*
+ * Install a special processing method for COM or APPn markers.
+ */
+
+GLOBAL(void)
+jpeg_set_marker_processor (j_decompress_ptr cinfo, int marker_code,
+ jpeg_marker_parser_method routine)
+{
+ my_marker_ptr marker = (my_marker_ptr) cinfo->marker;
+
+ if (marker_code == (int) M_COM)
+ marker->process_COM = routine;
+ else if (marker_code >= (int) M_APP0 && marker_code <= (int) M_APP15)
+ marker->process_APPn[marker_code - (int) M_APP0] = routine;
+ else
+ ERREXIT1(cinfo, JERR_UNKNOWN_MARKER, marker_code);
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdmaster.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdmaster.c
new file mode 100644
index 0000000..1b9cfb0
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdmaster.c
@@ -0,0 +1,557 @@
+/*
+ * jdmaster.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains master control logic for the JPEG decompressor.
+ * These routines are concerned with selecting the modules to be executed
+ * and with determining the number of passes and the work to be done in each
+ * pass.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private state */
+
+typedef struct {
+ struct jpeg_decomp_master pub; /* public fields */
+
+ int pass_number; /* # of passes completed */
+
+ boolean using_merged_upsample; /* TRUE if using merged upsample/cconvert */
+
+ /* Saved references to initialized quantizer modules,
+ * in case we need to switch modes.
+ */
+ struct jpeg_color_quantizer * quantizer_1pass;
+ struct jpeg_color_quantizer * quantizer_2pass;
+} my_decomp_master;
+
+typedef my_decomp_master * my_master_ptr;
+
+
+/*
+ * Determine whether merged upsample/color conversion should be used.
+ * CRUCIAL: this must match the actual capabilities of jdmerge.c!
+ */
+
+LOCAL(boolean)
+use_merged_upsample (j_decompress_ptr cinfo)
+{
+#ifdef UPSAMPLE_MERGING_SUPPORTED
+ /* Merging is the equivalent of plain box-filter upsampling */
+ if (cinfo->do_fancy_upsampling || cinfo->CCIR601_sampling)
+ return FALSE;
+ /* jdmerge.c only supports YCC=>RGB color conversion */
+ if (cinfo->jpeg_color_space != JCS_YCbCr || cinfo->num_components != 3 ||
+ cinfo->out_color_space != JCS_RGB ||
+ cinfo->out_color_components != RGB_PIXELSIZE)
+ return FALSE;
+ /* and it only handles 2h1v or 2h2v sampling ratios */
+ if (cinfo->comp_info[0].h_samp_factor != 2 ||
+ cinfo->comp_info[1].h_samp_factor != 1 ||
+ cinfo->comp_info[2].h_samp_factor != 1 ||
+ cinfo->comp_info[0].v_samp_factor > 2 ||
+ cinfo->comp_info[1].v_samp_factor != 1 ||
+ cinfo->comp_info[2].v_samp_factor != 1)
+ return FALSE;
+ /* furthermore, it doesn't work if we've scaled the IDCTs differently */
+ if (cinfo->comp_info[0].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
+ cinfo->comp_info[1].DCT_scaled_size != cinfo->min_DCT_scaled_size ||
+ cinfo->comp_info[2].DCT_scaled_size != cinfo->min_DCT_scaled_size)
+ return FALSE;
+ /* ??? also need to test for upsample-time rescaling, when & if supported */
+ return TRUE; /* by golly, it'll work... */
+#else
+ return FALSE;
+#endif
+}
+
+
+/*
+ * Compute output image dimensions and related values.
+ * NOTE: this is exported for possible use by application.
+ * Hence it mustn't do anything that can't be done twice.
+ * Also note that it may be called before the master module is initialized!
+ */
+
+GLOBAL(void)
+jpeg_calc_output_dimensions (j_decompress_ptr cinfo)
+/* Do computations that are needed before master selection phase */
+{
+#ifdef IDCT_SCALING_SUPPORTED
+ int ci;
+ jpeg_component_info *compptr;
+#endif
+
+ /* Prevent application from calling me at wrong times */
+ if (cinfo->global_state != DSTATE_READY)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+#ifdef IDCT_SCALING_SUPPORTED
+
+ /* Compute actual output image dimensions and DCT scaling choices. */
+ if (cinfo->scale_num * 8 <= cinfo->scale_denom) {
+ /* Provide 1/8 scaling */
+ cinfo->output_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width, 8L);
+ cinfo->output_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height, 8L);
+ cinfo->min_DCT_scaled_size = 1;
+ } else if (cinfo->scale_num * 4 <= cinfo->scale_denom) {
+ /* Provide 1/4 scaling */
+ cinfo->output_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width, 4L);
+ cinfo->output_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height, 4L);
+ cinfo->min_DCT_scaled_size = 2;
+ } else if (cinfo->scale_num * 2 <= cinfo->scale_denom) {
+ /* Provide 1/2 scaling */
+ cinfo->output_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width, 2L);
+ cinfo->output_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height, 2L);
+ cinfo->min_DCT_scaled_size = 4;
+ } else {
+ /* Provide 1/1 scaling */
+ cinfo->output_width = cinfo->image_width;
+ cinfo->output_height = cinfo->image_height;
+ cinfo->min_DCT_scaled_size = DCTSIZE;
+ }
+ /* In selecting the actual DCT scaling for each component, we try to
+ * scale up the chroma components via IDCT scaling rather than upsampling.
+ * This saves time if the upsampler gets to use 1:1 scaling.
+ * Note this code assumes that the supported DCT scalings are powers of 2.
+ */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ int ssize = cinfo->min_DCT_scaled_size;
+ while (ssize < DCTSIZE &&
+ (compptr->h_samp_factor * ssize * 2 <=
+ cinfo->max_h_samp_factor * cinfo->min_DCT_scaled_size) &&
+ (compptr->v_samp_factor * ssize * 2 <=
+ cinfo->max_v_samp_factor * cinfo->min_DCT_scaled_size)) {
+ ssize = ssize * 2;
+ }
+ compptr->DCT_scaled_size = ssize;
+ }
+
+ /* Recompute downsampled dimensions of components;
+ * application needs to know these if using raw downsampled data.
+ */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Size in samples, after IDCT scaling */
+ compptr->downsampled_width = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_width *
+ (long) (compptr->h_samp_factor * compptr->DCT_scaled_size),
+ (long) (cinfo->max_h_samp_factor * DCTSIZE));
+ compptr->downsampled_height = (JDIMENSION)
+ jdiv_round_up((long) cinfo->image_height *
+ (long) (compptr->v_samp_factor * compptr->DCT_scaled_size),
+ (long) (cinfo->max_v_samp_factor * DCTSIZE));
+ }
+
+#else /* !IDCT_SCALING_SUPPORTED */
+
+ /* Hardwire it to "no scaling" */
+ cinfo->output_width = cinfo->image_width;
+ cinfo->output_height = cinfo->image_height;
+ /* jdinput.c has already initialized DCT_scaled_size to DCTSIZE,
+ * and has computed unscaled downsampled_width and downsampled_height.
+ */
+
+#endif /* IDCT_SCALING_SUPPORTED */
+
+ /* Report number of components in selected colorspace. */
+ /* Probably this should be in the color conversion module... */
+ switch (cinfo->out_color_space) {
+ case JCS_GRAYSCALE:
+ cinfo->out_color_components = 1;
+ break;
+ case JCS_RGB:
+#if RGB_PIXELSIZE != 3
+ cinfo->out_color_components = RGB_PIXELSIZE;
+ break;
+#endif /* else share code with YCbCr */
+ case JCS_YCbCr:
+ cinfo->out_color_components = 3;
+ break;
+ case JCS_CMYK:
+ case JCS_YCCK:
+ cinfo->out_color_components = 4;
+ break;
+ default: /* else must be same colorspace as in file */
+ cinfo->out_color_components = cinfo->num_components;
+ break;
+ }
+ cinfo->output_components = (cinfo->quantize_colors ? 1 :
+ cinfo->out_color_components);
+
+ /* See if upsampler will want to emit more than one row at a time */
+ if (use_merged_upsample(cinfo))
+ cinfo->rec_outbuf_height = cinfo->max_v_samp_factor;
+ else
+ cinfo->rec_outbuf_height = 1;
+}
+
+
+/*
+ * Several decompression processes need to range-limit values to the range
+ * 0..MAXJSAMPLE; the input value may fall somewhat outside this range
+ * due to noise introduced by quantization, roundoff error, etc. These
+ * processes are inner loops and need to be as fast as possible. On most
+ * machines, particularly CPUs with pipelines or instruction prefetch,
+ * a (subscript-check-less) C table lookup
+ * x = sample_range_limit[x];
+ * is faster than explicit tests
+ * if (x < 0) x = 0;
+ * else if (x > MAXJSAMPLE) x = MAXJSAMPLE;
+ * These processes all use a common table prepared by the routine below.
+ *
+ * For most steps we can mathematically guarantee that the initial value
+ * of x is within MAXJSAMPLE+1 of the legal range, so a table running from
+ * -(MAXJSAMPLE+1) to 2*MAXJSAMPLE+1 is sufficient. But for the initial
+ * limiting step (just after the IDCT), a wildly out-of-range value is
+ * possible if the input data is corrupt. To avoid any chance of indexing
+ * off the end of memory and getting a bad-pointer trap, we perform the
+ * post-IDCT limiting thus:
+ * x = range_limit[x & MASK];
+ * where MASK is 2 bits wider than legal sample data, ie 10 bits for 8-bit
+ * samples. Under normal circumstances this is more than enough range and
+ * a correct output will be generated; with bogus input data the tqmask will
+ * cause wraparound, and we will safely generate a bogus-but-in-range output.
+ * For the post-IDCT step, we want to convert the data from signed to unsigned
+ * representation by adding CENTERJSAMPLE at the same time that we limit it.
+ * So the post-IDCT limiting table ends up looking like this:
+ * CENTERJSAMPLE,CENTERJSAMPLE+1,...,MAXJSAMPLE,
+ * MAXJSAMPLE (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
+ * 0 (repeat 2*(MAXJSAMPLE+1)-CENTERJSAMPLE times),
+ * 0,1,...,CENTERJSAMPLE-1
+ * Negative inputs select values from the upper half of the table after
+ * masking.
+ *
+ * We can save some space by overlapping the start of the post-IDCT table
+ * with the simpler range limiting table. The post-IDCT table begins at
+ * sample_range_limit + CENTERJSAMPLE.
+ *
+ * Note that the table is allocated in near data space on PCs; it's small
+ * enough and used often enough to justify this.
+ */
+
+LOCAL(void)
+prepare_range_limit_table (j_decompress_ptr cinfo)
+/* Allocate and fill in the sample_range_limit table */
+{
+ JSAMPLE * table;
+ int i;
+
+ table = (JSAMPLE *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (5 * (MAXJSAMPLE+1) + CENTERJSAMPLE) * SIZEOF(JSAMPLE));
+ table += (MAXJSAMPLE+1); /* allow negative subscripts of simple table */
+ cinfo->sample_range_limit = table;
+ /* First segment of "simple" table: limit[x] = 0 for x < 0 */
+ MEMZERO(table - (MAXJSAMPLE+1), (MAXJSAMPLE+1) * SIZEOF(JSAMPLE));
+ /* Main part of "simple" table: limit[x] = x */
+ for (i = 0; i <= MAXJSAMPLE; i++)
+ table[i] = (JSAMPLE) i;
+ table += CENTERJSAMPLE; /* Point to where post-IDCT table starts */
+ /* End of simple table, rest of first half of post-IDCT table */
+ for (i = CENTERJSAMPLE; i < 2*(MAXJSAMPLE+1); i++)
+ table[i] = MAXJSAMPLE;
+ /* Second half of post-IDCT table */
+ MEMZERO(table + (2 * (MAXJSAMPLE+1)),
+ (2 * (MAXJSAMPLE+1) - CENTERJSAMPLE) * SIZEOF(JSAMPLE));
+ MEMCOPY(table + (4 * (MAXJSAMPLE+1) - CENTERJSAMPLE),
+ cinfo->sample_range_limit, CENTERJSAMPLE * SIZEOF(JSAMPLE));
+}
+
+
+/*
+ * Master selection of decompression modules.
+ * This is done once at jpeg_start_decompress time. We determine
+ * which modules will be used and give them appropriate initialization calls.
+ * We also initialize the decompressor input side to begin consuming data.
+ *
+ * Since jpeg_read_header has finished, we know what is in the SOF
+ * and (first) SOS markers. We also have all the application parameter
+ * settings.
+ */
+
+LOCAL(void)
+master_selection (j_decompress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+ boolean use_c_buffer;
+ long samplesperrow;
+ JDIMENSION jd_samplesperrow;
+
+ /* Initialize dimensions and other stuff */
+ jpeg_calc_output_dimensions(cinfo);
+ prepare_range_limit_table(cinfo);
+
+ /* Width of an output scanline must be representable as JDIMENSION. */
+ samplesperrow = (long) cinfo->output_width * (long) cinfo->out_color_components;
+ jd_samplesperrow = (JDIMENSION) samplesperrow;
+ if ((long) jd_samplesperrow != samplesperrow)
+ ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+
+ /* Initialize my private state */
+ master->pass_number = 0;
+ master->using_merged_upsample = use_merged_upsample(cinfo);
+
+ /* Color quantizer selection */
+ master->quantizer_1pass = NULL;
+ master->quantizer_2pass = NULL;
+ /* No mode changes if not using buffered-image mode. */
+ if (! cinfo->quantize_colors || ! cinfo->buffered_image) {
+ cinfo->enable_1pass_quant = FALSE;
+ cinfo->enable_external_quant = FALSE;
+ cinfo->enable_2pass_quant = FALSE;
+ }
+ if (cinfo->quantize_colors) {
+ if (cinfo->raw_data_out)
+ ERREXIT(cinfo, JERR_NOTIMPL);
+ /* 2-pass quantizer only works in 3-component color space. */
+ if (cinfo->out_color_components != 3) {
+ cinfo->enable_1pass_quant = TRUE;
+ cinfo->enable_external_quant = FALSE;
+ cinfo->enable_2pass_quant = FALSE;
+ cinfo->colormap = NULL;
+ } else if (cinfo->colormap != NULL) {
+ cinfo->enable_external_quant = TRUE;
+ } else if (cinfo->two_pass_quantize) {
+ cinfo->enable_2pass_quant = TRUE;
+ } else {
+ cinfo->enable_1pass_quant = TRUE;
+ }
+
+ if (cinfo->enable_1pass_quant) {
+#ifdef TQUANT_1PASS_SUPPORTED
+ jinit_1pass_quantizer(cinfo);
+ master->quantizer_1pass = cinfo->cquantize;
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ }
+
+ /* We use the 2-pass code to map to external colormaps. */
+ if (cinfo->enable_2pass_quant || cinfo->enable_external_quant) {
+#ifdef TQUANT_2PASS_SUPPORTED
+ jinit_2pass_quantizer(cinfo);
+ master->quantizer_2pass = cinfo->cquantize;
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ }
+ /* If both quantizers are initialized, the 2-pass one is left active;
+ * this is necessary for starting with quantization to an external map.
+ */
+ }
+
+ /* Post-processing: in particular, color conversion first */
+ if (! cinfo->raw_data_out) {
+ if (master->using_merged_upsample) {
+#ifdef UPSAMPLE_MERGING_SUPPORTED
+ jinit_merged_upsampler(cinfo); /* does color conversion too */
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else {
+ jinit_color_deconverter(cinfo);
+ jinit_upsampler(cinfo);
+ }
+ jinit_d_post_controller(cinfo, cinfo->enable_2pass_quant);
+ }
+ /* Inverse DCT */
+ jinit_inverse_dct(cinfo);
+ /* Entropy decoding: either Huffman or arithmetic coding. */
+ if (cinfo->arith_code) {
+ ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+ } else {
+ if (cinfo->progressive_mode) {
+#ifdef D_PROGRESSIVE_SUPPORTED
+ jinit_phuff_decoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else
+ jinit_huff_decoder(cinfo);
+ }
+
+ /* Initialize principal buffer controllers. */
+ use_c_buffer = cinfo->inputctl->has_multiple_scans || cinfo->buffered_image;
+ jinit_d_coef_controller(cinfo, use_c_buffer);
+
+ if (! cinfo->raw_data_out)
+ jinit_d_main_controller(cinfo, FALSE /* never need full buffer here */);
+
+ /* We can now tell the memory manager to allocate virtual arrays. */
+ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+ /* Initialize input side of decompressor to consume first scan. */
+ (*cinfo->inputctl->start_input_pass) (cinfo);
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+ /* If jpeg_start_decompress will read the whole file, initialize
+ * progress monitoring appropriately. The input step is counted
+ * as one pass.
+ */
+ if (cinfo->progress != NULL && ! cinfo->buffered_image &&
+ cinfo->inputctl->has_multiple_scans) {
+ int nscans;
+ /* Estimate number of scans to set pass_limit. */
+ if (cinfo->progressive_mode) {
+ /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
+ nscans = 2 + 3 * cinfo->num_components;
+ } else {
+ /* For a nonprogressive multiscan file, estimate 1 scan per component. */
+ nscans = cinfo->num_components;
+ }
+ cinfo->progress->pass_counter = 0L;
+ cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
+ cinfo->progress->completed_passes = 0;
+ cinfo->progress->total_passes = (cinfo->enable_2pass_quant ? 3 : 2);
+ /* Count the input pass as done */
+ master->pass_number++;
+ }
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+}
+
+
+/*
+ * Per-pass setup.
+ * This is called at the beginning of each output pass. We determine which
+ * modules will be active during this pass and give them appropriate
+ * start_pass calls. We also set is_dummy_pass to indicate whether this
+ * is a "real" output pass or a dummy pass for color quantization.
+ * (In the latter case, jdapistd.c will crank the pass to completion.)
+ */
+
+METHODDEF(void)
+prepare_for_output_pass (j_decompress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+
+ if (master->pub.is_dummy_pass) {
+#ifdef TQUANT_2PASS_SUPPORTED
+ /* Final pass of 2-pass quantization */
+ master->pub.is_dummy_pass = FALSE;
+ (*cinfo->cquantize->start_pass) (cinfo, FALSE);
+ (*cinfo->post->start_pass) (cinfo, JBUF_CRANK_DEST);
+ (*cinfo->main->start_pass) (cinfo, JBUF_CRANK_DEST);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif /* TQUANT_2PASS_SUPPORTED */
+ } else {
+ if (cinfo->quantize_colors && cinfo->colormap == NULL) {
+ /* Select new quantization method */
+ if (cinfo->two_pass_quantize && cinfo->enable_2pass_quant) {
+ cinfo->cquantize = master->quantizer_2pass;
+ master->pub.is_dummy_pass = TRUE;
+ } else if (cinfo->enable_1pass_quant) {
+ cinfo->cquantize = master->quantizer_1pass;
+ } else {
+ ERREXIT(cinfo, JERR_MODE_CHANGE);
+ }
+ }
+ (*cinfo->idct->start_pass) (cinfo);
+ (*cinfo->coef->start_output_pass) (cinfo);
+ if (! cinfo->raw_data_out) {
+ if (! master->using_merged_upsample)
+ (*cinfo->cconvert->start_pass) (cinfo);
+ (*cinfo->upsample->start_pass) (cinfo);
+ if (cinfo->quantize_colors)
+ (*cinfo->cquantize->start_pass) (cinfo, master->pub.is_dummy_pass);
+ (*cinfo->post->start_pass) (cinfo,
+ (master->pub.is_dummy_pass ? JBUF_SAVE_AND_PASS : JBUF_PASS_THRU));
+ (*cinfo->main->start_pass) (cinfo, JBUF_PASS_THRU);
+ }
+ }
+
+ /* Set up progress monitor's pass info if present */
+ if (cinfo->progress != NULL) {
+ cinfo->progress->completed_passes = master->pass_number;
+ cinfo->progress->total_passes = master->pass_number +
+ (master->pub.is_dummy_pass ? 2 : 1);
+ /* In buffered-image mode, we assume one more output pass if EOI not
+ * yet reached, but no more passes if EOI has been reached.
+ */
+ if (cinfo->buffered_image && ! cinfo->inputctl->eoi_reached) {
+ cinfo->progress->total_passes += (cinfo->enable_2pass_quant ? 2 : 1);
+ }
+ }
+}
+
+
+/*
+ * Finish up at end of an output pass.
+ */
+
+METHODDEF(void)
+finish_output_pass (j_decompress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+
+ if (cinfo->quantize_colors)
+ (*cinfo->cquantize->finish_pass) (cinfo);
+ master->pass_number++;
+}
+
+
+#ifdef D_MULTISCAN_FILES_SUPPORTED
+
+/*
+ * Switch to a new external colormap between output passes.
+ */
+
+GLOBAL(void)
+jpeg_new_colormap (j_decompress_ptr cinfo)
+{
+ my_master_ptr master = (my_master_ptr) cinfo->master;
+
+ /* Prevent application from calling me at wrong times */
+ if (cinfo->global_state != DSTATE_BUFIMAGE)
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+
+ if (cinfo->quantize_colors && cinfo->enable_external_quant &&
+ cinfo->colormap != NULL) {
+ /* Select 2-pass quantizer for external colormap use */
+ cinfo->cquantize = master->quantizer_2pass;
+ /* Notify quantizer of colormap change */
+ (*cinfo->cquantize->new_color_map) (cinfo);
+ master->pub.is_dummy_pass = FALSE; /* just in case */
+ } else
+ ERREXIT(cinfo, JERR_MODE_CHANGE);
+}
+
+#endif /* D_MULTISCAN_FILES_SUPPORTED */
+
+
+/*
+ * Initialize master decompression control and select active modules.
+ * This is performed at the start of jpeg_start_decompress.
+ */
+
+GLOBAL(void)
+jinit_master_decompress (j_decompress_ptr cinfo)
+{
+ my_master_ptr master;
+
+ master = (my_master_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_decomp_master));
+ cinfo->master = (struct jpeg_decomp_master *) master;
+ master->pub.prepare_for_output_pass = prepare_for_output_pass;
+ master->pub.finish_output_pass = finish_output_pass;
+
+ master->pub.is_dummy_pass = FALSE;
+
+ master_selection(cinfo);
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdmerge.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdmerge.c
new file mode 100644
index 0000000..7da0eb3
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdmerge.c
@@ -0,0 +1,400 @@
+/*
+ * jdmerge.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains code for merged upsampling/color conversion.
+ *
+ * This file combines functions from jdsample.c and jdcolor.c;
+ * read those files first to understand what's going on.
+ *
+ * When the chroma components are to be upsampled by simple replication
+ * (ie, box filtering), we can save some work in color conversion by
+ * calculating all the output pixels corresponding to a pair of chroma
+ * samples at one time. In the conversion equations
+ * R = Y + K1 * Cr
+ * G = Y + K2 * Cb + K3 * Cr
+ * B = Y + K4 * Cb
+ * only the Y term varies among the group of pixels corresponding to a pair
+ * of chroma samples, so the rest of the terms can be calculated just once.
+ * At typical sampling ratios, this eliminates half or three-quarters of the
+ * multiplications needed for color conversion.
+ *
+ * This file currently provides implementations for the following cases:
+ * YCbCr => RGB color conversion only.
+ * Sampling ratios of 2h1v or 2h2v.
+ * No scaling needed at upsample time.
+ * Corner-aligned (non-CCIR601) sampling tqalignment.
+ * Other special cases could be added, but in most applications these are
+ * the only common cases. (For uncommon cases we fall back on the more
+ * general code in jdsample.c and jdcolor.c.)
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+#ifdef UPSAMPLE_MERGING_SUPPORTED
+
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_upsampler pub; /* public fields */
+
+ /* Pointer to routine to do actual upsampling/conversion of one row group */
+ JTQT_METHOD(void, upmethod, (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf));
+
+ /* Private state for YCC->RGB conversion */
+ int * Cr_r_tab; /* => table for Cr to R conversion */
+ int * Cb_b_tab; /* => table for Cb to B conversion */
+ INT32 * Cr_g_tab; /* => table for Cr to G conversion */
+ INT32 * Cb_g_tab; /* => table for Cb to G conversion */
+
+ /* For 2:1 vertical sampling, we produce two output rows at a time.
+ * We need a "spare" row buffer to hold the second output row if the
+ * application provides just a one-row buffer; we also use the spare
+ * to discard the dummy last row if the image height is odd.
+ */
+ JSAMPROW spare_row;
+ boolean spare_full; /* T if spare buffer is occupied */
+
+ JDIMENSION out_row_width; /* samples per output row */
+ JDIMENSION rows_to_go; /* counts rows remaining in image */
+} my_upsampler;
+
+typedef my_upsampler * my_upsample_ptr;
+
+#define SCALEBITS 16 /* speediest right-shift on some machines */
+#define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
+#define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
+
+
+/*
+ * Initialize tables for YCC->RGB colorspace conversion.
+ * This is taken directly from jdcolor.c; see that file for more info.
+ */
+
+LOCAL(void)
+build_ycc_rgb_table (j_decompress_ptr cinfo)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ int i;
+ INT32 x;
+ SHIFT_TEMPS
+
+ upsample->Cr_r_tab = (int *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(int));
+ upsample->Cb_b_tab = (int *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(int));
+ upsample->Cr_g_tab = (INT32 *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(INT32));
+ upsample->Cb_g_tab = (INT32 *)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (MAXJSAMPLE+1) * SIZEOF(INT32));
+
+ for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
+ /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
+ /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
+ /* Cr=>R value is nearest int to 1.40200 * x */
+ upsample->Cr_r_tab[i] = (int)
+ RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
+ /* Cb=>B value is nearest int to 1.77200 * x */
+ upsample->Cb_b_tab[i] = (int)
+ RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
+ /* Cr=>G value is scaled-up -0.71414 * x */
+ upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
+ /* Cb=>G value is scaled-up -0.34414 * x */
+ /* We also add in ONE_HALF so that need not do it in inner loop */
+ upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
+ }
+}
+
+
+/*
+ * Initialize for an upsampling pass.
+ */
+
+METHODDEF(void)
+start_pass_merged_upsample (j_decompress_ptr cinfo)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+
+ /* Mark the spare buffer empty */
+ upsample->spare_full = FALSE;
+ /* Initialize total-height counter for detecting bottom of image */
+ upsample->rows_to_go = cinfo->output_height;
+}
+
+
+/*
+ * Control routine to do upsampling (and color conversion).
+ *
+ * The control routine just handles the row buffering considerations.
+ */
+
+METHODDEF(void)
+merged_2v_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+/* 2:1 vertical sampling case: may need a spare row. */
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ JSAMPROW work_ptrs[2];
+ JDIMENSION num_rows; /* number of rows returned to caller */
+
+ if (upsample->spare_full) {
+ /* If we have a spare row saved from a previous cycle, just return it. */
+ jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
+ 1, upsample->out_row_width);
+ num_rows = 1;
+ upsample->spare_full = FALSE;
+ } else {
+ /* Figure number of rows to return to caller. */
+ num_rows = 2;
+ /* Not more than the distance to the end of the image. */
+ if (num_rows > upsample->rows_to_go)
+ num_rows = upsample->rows_to_go;
+ /* And not more than what the client can accept: */
+ out_rows_avail -= *out_row_ctr;
+ if (num_rows > out_rows_avail)
+ num_rows = out_rows_avail;
+ /* Create output pointer array for upsampler. */
+ work_ptrs[0] = output_buf[*out_row_ctr];
+ if (num_rows > 1) {
+ work_ptrs[1] = output_buf[*out_row_ctr + 1];
+ } else {
+ work_ptrs[1] = upsample->spare_row;
+ upsample->spare_full = TRUE;
+ }
+ /* Now do the upsampling. */
+ (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
+ }
+
+ /* Adjust counts */
+ *out_row_ctr += num_rows;
+ upsample->rows_to_go -= num_rows;
+ /* When the buffer is emptied, declare this input row group consumed */
+ if (! upsample->spare_full)
+ (*in_row_group_ctr)++;
+}
+
+
+METHODDEF(void)
+merged_1v_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+/* 1:1 vertical sampling case: much easier, never need a spare row. */
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+
+ /* Just do the upsampling. */
+ (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
+ output_buf + *out_row_ctr);
+ /* Adjust counts */
+ (*out_row_ctr)++;
+ (*in_row_group_ctr)++;
+}
+
+
+/*
+ * These are the routines invoked by the control routines to do
+ * the actual upsampling/conversion. One row group is processed per call.
+ *
+ * Note: since we may be writing directly into application-supplied buffers,
+ * we have to be honest about the output width; we can't assume the buffer
+ * has been rounded up to an even width.
+ */
+
+
+/*
+ * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
+ */
+
+METHODDEF(void)
+h2v1_merged_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ register int y, cred, cgreen, cblue;
+ int cb, cr;
+ register JSAMPROW outptr;
+ JSAMPROW inptr0, inptr1, inptr2;
+ JDIMENSION col;
+ /* copy these pointers into registers if possible */
+ register JSAMPLE * range_limit = cinfo->sample_range_limit;
+ int * Crrtab = upsample->Cr_r_tab;
+ int * Cbbtab = upsample->Cb_b_tab;
+ INT32 * Crgtab = upsample->Cr_g_tab;
+ INT32 * Cbgtab = upsample->Cb_g_tab;
+ SHIFT_TEMPS
+
+ inptr0 = input_buf[0][in_row_group_ctr];
+ inptr1 = input_buf[1][in_row_group_ctr];
+ inptr2 = input_buf[2][in_row_group_ctr];
+ outptr = output_buf[0];
+ /* Loop for each pair of output pixels */
+ for (col = cinfo->output_width >> 1; col > 0; col--) {
+ /* Do the chroma part of the calculation */
+ cb = GETJSAMPLE(*inptr1++);
+ cr = GETJSAMPLE(*inptr2++);
+ cred = Crrtab[cr];
+ cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+ cblue = Cbbtab[cb];
+ /* Fetch 2 Y values and emit 2 pixels */
+ y = GETJSAMPLE(*inptr0++);
+ outptr[RGB_RED] = range_limit[y + cred];
+ outptr[RGB_GREEN] = range_limit[y + cgreen];
+ outptr[RGB_BLUE] = range_limit[y + cblue];
+ outptr += RGB_PIXELSIZE;
+ y = GETJSAMPLE(*inptr0++);
+ outptr[RGB_RED] = range_limit[y + cred];
+ outptr[RGB_GREEN] = range_limit[y + cgreen];
+ outptr[RGB_BLUE] = range_limit[y + cblue];
+ outptr += RGB_PIXELSIZE;
+ }
+ /* If image width is odd, do the last output column separately */
+ if (cinfo->output_width & 1) {
+ cb = GETJSAMPLE(*inptr1);
+ cr = GETJSAMPLE(*inptr2);
+ cred = Crrtab[cr];
+ cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+ cblue = Cbbtab[cb];
+ y = GETJSAMPLE(*inptr0);
+ outptr[RGB_RED] = range_limit[y + cred];
+ outptr[RGB_GREEN] = range_limit[y + cgreen];
+ outptr[RGB_BLUE] = range_limit[y + cblue];
+ }
+}
+
+
+/*
+ * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
+ */
+
+METHODDEF(void)
+h2v2_merged_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
+ JSAMPARRAY output_buf)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ register int y, cred, cgreen, cblue;
+ int cb, cr;
+ register JSAMPROW outptr0, outptr1;
+ JSAMPROW inptr00, inptr01, inptr1, inptr2;
+ JDIMENSION col;
+ /* copy these pointers into registers if possible */
+ register JSAMPLE * range_limit = cinfo->sample_range_limit;
+ int * Crrtab = upsample->Cr_r_tab;
+ int * Cbbtab = upsample->Cb_b_tab;
+ INT32 * Crgtab = upsample->Cr_g_tab;
+ INT32 * Cbgtab = upsample->Cb_g_tab;
+ SHIFT_TEMPS
+
+ inptr00 = input_buf[0][in_row_group_ctr*2];
+ inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
+ inptr1 = input_buf[1][in_row_group_ctr];
+ inptr2 = input_buf[2][in_row_group_ctr];
+ outptr0 = output_buf[0];
+ outptr1 = output_buf[1];
+ /* Loop for each group of output pixels */
+ for (col = cinfo->output_width >> 1; col > 0; col--) {
+ /* Do the chroma part of the calculation */
+ cb = GETJSAMPLE(*inptr1++);
+ cr = GETJSAMPLE(*inptr2++);
+ cred = Crrtab[cr];
+ cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+ cblue = Cbbtab[cb];
+ /* Fetch 4 Y values and emit 4 pixels */
+ y = GETJSAMPLE(*inptr00++);
+ outptr0[RGB_RED] = range_limit[y + cred];
+ outptr0[RGB_GREEN] = range_limit[y + cgreen];
+ outptr0[RGB_BLUE] = range_limit[y + cblue];
+ outptr0 += RGB_PIXELSIZE;
+ y = GETJSAMPLE(*inptr00++);
+ outptr0[RGB_RED] = range_limit[y + cred];
+ outptr0[RGB_GREEN] = range_limit[y + cgreen];
+ outptr0[RGB_BLUE] = range_limit[y + cblue];
+ outptr0 += RGB_PIXELSIZE;
+ y = GETJSAMPLE(*inptr01++);
+ outptr1[RGB_RED] = range_limit[y + cred];
+ outptr1[RGB_GREEN] = range_limit[y + cgreen];
+ outptr1[RGB_BLUE] = range_limit[y + cblue];
+ outptr1 += RGB_PIXELSIZE;
+ y = GETJSAMPLE(*inptr01++);
+ outptr1[RGB_RED] = range_limit[y + cred];
+ outptr1[RGB_GREEN] = range_limit[y + cgreen];
+ outptr1[RGB_BLUE] = range_limit[y + cblue];
+ outptr1 += RGB_PIXELSIZE;
+ }
+ /* If image width is odd, do the last output column separately */
+ if (cinfo->output_width & 1) {
+ cb = GETJSAMPLE(*inptr1);
+ cr = GETJSAMPLE(*inptr2);
+ cred = Crrtab[cr];
+ cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
+ cblue = Cbbtab[cb];
+ y = GETJSAMPLE(*inptr00);
+ outptr0[RGB_RED] = range_limit[y + cred];
+ outptr0[RGB_GREEN] = range_limit[y + cgreen];
+ outptr0[RGB_BLUE] = range_limit[y + cblue];
+ y = GETJSAMPLE(*inptr01);
+ outptr1[RGB_RED] = range_limit[y + cred];
+ outptr1[RGB_GREEN] = range_limit[y + cgreen];
+ outptr1[RGB_BLUE] = range_limit[y + cblue];
+ }
+}
+
+
+/*
+ * Module initialization routine for merged upsampling/color conversion.
+ *
+ * NB: this is called under the conditions determined by use_merged_upsample()
+ * in jdmaster.c. That routine MUST correspond to the actual capabilities
+ * of this module; no safety checks are made here.
+ */
+
+GLOBAL(void)
+jinit_merged_upsampler (j_decompress_ptr cinfo)
+{
+ my_upsample_ptr upsample;
+
+ upsample = (my_upsample_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_upsampler));
+ cinfo->upsample = (struct jpeg_upsampler *) upsample;
+ upsample->pub.start_pass = start_pass_merged_upsample;
+ upsample->pub.need_context_rows = FALSE;
+
+ upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
+
+ if (cinfo->max_v_samp_factor == 2) {
+ upsample->pub.upsample = merged_2v_upsample;
+ upsample->upmethod = h2v2_merged_upsample;
+ /* Allocate a spare row buffer */
+ upsample->spare_row = (JSAMPROW)
+ (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
+ } else {
+ upsample->pub.upsample = merged_1v_upsample;
+ upsample->upmethod = h2v1_merged_upsample;
+ /* No spare row needed */
+ upsample->spare_row = NULL;
+ }
+
+ build_ycc_rgb_table(cinfo);
+}
+
+#endif /* UPSAMPLE_MERGING_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdphuff.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdphuff.c
new file mode 100644
index 0000000..20486f0
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdphuff.c
@@ -0,0 +1,668 @@
+/*
+ * jdphuff.c
+ *
+ * Copyright (C) 1995-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains Huffman entropy decoding routines for progressive JPEG.
+ *
+ * Much of the complexity here has to do with supporting input suspension.
+ * If the data source module demands suspension, we want to be able to back
+ * up to the start of the current MCU. To do this, we copy state variables
+ * into local working storage, and update them back to the permanent
+ * storage only upon successful completion of an MCU.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdhuff.h" /* Declarations shared with jdhuff.c */
+
+
+#ifdef D_PROGRESSIVE_SUPPORTED
+
+/*
+ * Expanded entropy decoder object for progressive Huffman decoding.
+ *
+ * The savable_state subrecord tqcontains fields that change within an MCU,
+ * but must not be updated permanently until we complete the MCU.
+ */
+
+typedef struct {
+ unsigned int EOBRUN; /* remaining EOBs in EOBRUN */
+ int last_dc_val[MAX_COMPS_IN_SCAN]; /* last DC coef for each component */
+} savable_state;
+
+/* This macro is to work around compilers with missing or broken
+ * structure assignment. You'll need to fix this code if you have
+ * such a compiler and you change MAX_COMPS_IN_SCAN.
+ */
+
+#ifndef NO_STRUCT_ASSIGN
+#define ASSIGN_STATE(dest,src) ((dest) = (src))
+#else
+#if MAX_COMPS_IN_SCAN == 4
+#define ASSIGN_STATE(dest,src) \
+ ((dest).EOBRUN = (src).EOBRUN, \
+ (dest).last_dc_val[0] = (src).last_dc_val[0], \
+ (dest).last_dc_val[1] = (src).last_dc_val[1], \
+ (dest).last_dc_val[2] = (src).last_dc_val[2], \
+ (dest).last_dc_val[3] = (src).last_dc_val[3])
+#endif
+#endif
+
+
+typedef struct {
+ struct jpeg_entropy_decoder pub; /* public fields */
+
+ /* These fields are loaded into local variables at start of each MCU.
+ * In case of suspension, we exit WITHOUT updating them.
+ */
+ bitread_perm_state bitstate; /* Bit buffer at start of MCU */
+ savable_state saved; /* Other state at start of MCU */
+
+ /* These fields are NOT loaded into local working state. */
+ unsigned int restarts_to_go; /* MCUs left in this restart interval */
+
+ /* Pointers to derived tables (these workspaces have image lifespan) */
+ d_derived_tbl * derived_tbls[NUM_HUFF_TBLS];
+
+ d_derived_tbl * ac_derived_tbl; /* active table during an AC scan */
+} phuff_entropy_decoder;
+
+typedef phuff_entropy_decoder * phuff_entropy_ptr;
+
+/* Forward declarations */
+METHODDEF(boolean) decode_mcu_DC_first JPP((j_decompress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) decode_mcu_AC_first JPP((j_decompress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) decode_mcu_DC_refine JPP((j_decompress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+METHODDEF(boolean) decode_mcu_AC_refine JPP((j_decompress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+
+
+/*
+ * Initialize for a Huffman-compressed scan.
+ */
+
+METHODDEF(void)
+start_pass_phuff_decoder (j_decompress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ boolean is_DC_band, bad;
+ int ci, coefi, tbl;
+ int *coef_bit_ptr;
+ jpeg_component_info * compptr;
+
+ is_DC_band = (cinfo->Ss == 0);
+
+ /* Validate scan parameters */
+ bad = FALSE;
+ if (is_DC_band) {
+ if (cinfo->Se != 0)
+ bad = TRUE;
+ } else {
+ /* need not check Ss/Se < 0 since they came from unsigned bytes */
+ if (cinfo->Ss > cinfo->Se || cinfo->Se >= DCTSIZE2)
+ bad = TRUE;
+ /* AC scans may have only one component */
+ if (cinfo->comps_in_scan != 1)
+ bad = TRUE;
+ }
+ if (cinfo->Ah != 0) {
+ /* Successive approximation refinement scan: must have Al = Ah-1. */
+ if (cinfo->Al != cinfo->Ah-1)
+ bad = TRUE;
+ }
+ if (cinfo->Al > 13) /* need not check for < 0 */
+ bad = TRUE;
+ /* Arguably the maximum Al value should be less than 13 for 8-bit precision,
+ * but the spec doesn't say so, and we try to be liberal about what we
+ * accept. Note: large Al values could result in out-of-range DC
+ * coefficients during early scans, leading to bizarre displays due to
+ * overflows in the IDCT math. But we won't crash.
+ */
+ if (bad)
+ ERREXIT4(cinfo, JERR_BAD_PROGRESSION,
+ cinfo->Ss, cinfo->Se, cinfo->Ah, cinfo->Al);
+ /* Update progression status, and verify that scan order is legal.
+ * Note that inter-scan inconsistencies are treated as warnings
+ * not fatal errors ... not clear if this is right way to behave.
+ */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ int cindex = cinfo->cur_comp_info[ci]->component_index;
+ coef_bit_ptr = & cinfo->coef_bits[cindex][0];
+ if (!is_DC_band && coef_bit_ptr[0] < 0) /* AC without prior DC scan */
+ WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, 0);
+ for (coefi = cinfo->Ss; coefi <= cinfo->Se; coefi++) {
+ int expected = (coef_bit_ptr[coefi] < 0) ? 0 : coef_bit_ptr[coefi];
+ if (cinfo->Ah != expected)
+ WARNMS2(cinfo, JWRN_BOGUS_PROGRESSION, cindex, coefi);
+ coef_bit_ptr[coefi] = cinfo->Al;
+ }
+ }
+
+ /* Select MCU decoding routine */
+ if (cinfo->Ah == 0) {
+ if (is_DC_band)
+ entropy->pub.decode_mcu = decode_mcu_DC_first;
+ else
+ entropy->pub.decode_mcu = decode_mcu_AC_first;
+ } else {
+ if (is_DC_band)
+ entropy->pub.decode_mcu = decode_mcu_DC_refine;
+ else
+ entropy->pub.decode_mcu = decode_mcu_AC_refine;
+ }
+
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
+ compptr = cinfo->cur_comp_info[ci];
+ /* Make sure requested tables are present, and compute derived tables.
+ * We may build same derived table more than once, but it's not expensive.
+ */
+ if (is_DC_band) {
+ if (cinfo->Ah == 0) { /* DC refinement needs no table */
+ tbl = compptr->dc_tbl_no;
+ jpeg_make_d_derived_tbl(cinfo, TRUE, tbl,
+ & entropy->derived_tbls[tbl]);
+ }
+ } else {
+ tbl = compptr->ac_tbl_no;
+ jpeg_make_d_derived_tbl(cinfo, FALSE, tbl,
+ & entropy->derived_tbls[tbl]);
+ /* remember the single active table */
+ entropy->ac_derived_tbl = entropy->derived_tbls[tbl];
+ }
+ /* Initialize DC predictions to 0 */
+ entropy->saved.last_dc_val[ci] = 0;
+ }
+
+ /* Initialize bitread state variables */
+ entropy->bitstate.bits_left = 0;
+ entropy->bitstate.get_buffer = 0; /* unnecessary, but keeps Purify quiet */
+ entropy->pub.insufficient_data = FALSE;
+
+ /* Initialize private state variables */
+ entropy->saved.EOBRUN = 0;
+
+ /* Initialize restart counter */
+ entropy->restarts_to_go = cinfo->restart_interval;
+}
+
+
+/*
+ * Figure F.12: extend sign bit.
+ * On some machines, a shift and add will be faster than a table lookup.
+ */
+
+#ifdef AVOID_TABLES
+
+#define HUFF_EXTEND(x,s) ((x) < (1<<((s)-1)) ? (x) + (((-1)<<(s)) + 1) : (x))
+
+#else
+
+#define HUFF_EXTEND(x,s) ((x) < extend_test[s] ? (x) + extend_offset[s] : (x))
+
+static const int extend_test[16] = /* entry n is 2**(n-1) */
+ { 0, 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000 };
+
+static const int extend_offset[16] = /* entry n is (-1 << n) + 1 */
+ { 0, ((-1)<<1) + 1, ((-1)<<2) + 1, ((-1)<<3) + 1, ((-1)<<4) + 1,
+ ((-1)<<5) + 1, ((-1)<<6) + 1, ((-1)<<7) + 1, ((-1)<<8) + 1,
+ ((-1)<<9) + 1, ((-1)<<10) + 1, ((-1)<<11) + 1, ((-1)<<12) + 1,
+ ((-1)<<13) + 1, ((-1)<<14) + 1, ((-1)<<15) + 1 };
+
+#endif /* AVOID_TABLES */
+
+
+/*
+ * Check for a restart marker & resynchronize decoder.
+ * Returns FALSE if must suspend.
+ */
+
+LOCAL(boolean)
+process_restart (j_decompress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ int ci;
+
+ /* Throw away any unused bits remaining in bit buffer; */
+ /* include any full bytes in next_marker's count of discarded bytes */
+ cinfo->marker->discarded_bytes += entropy->bitstate.bits_left / 8;
+ entropy->bitstate.bits_left = 0;
+
+ /* Advance past the RSTn marker */
+ if (! (*cinfo->marker->read_restart_marker) (cinfo))
+ return FALSE;
+
+ /* Re-initialize DC predictions to 0 */
+ for (ci = 0; ci < cinfo->comps_in_scan; ci++)
+ entropy->saved.last_dc_val[ci] = 0;
+ /* Re-init EOB run count, too */
+ entropy->saved.EOBRUN = 0;
+
+ /* Reset restart counter */
+ entropy->restarts_to_go = cinfo->restart_interval;
+
+ /* Reset out-of-data flag, unless read_restart_marker left us smack up
+ * against a marker. In that case we will end up treating the next data
+ * segment as empty, and we can avoid producing bogus output pixels by
+ * leaving the flag set.
+ */
+ if (cinfo->unread_marker == 0)
+ entropy->pub.insufficient_data = FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * Huffman MCU decoding.
+ * Each of these routines decodes and returns one MCU's worth of
+ * Huffman-compressed coefficients.
+ * The coefficients are reordered from zigzag order into natural array order,
+ * but are not dequantized.
+ *
+ * The i'th block of the MCU is stored into the block pointed to by
+ * MCU_data[i]. WE ASSUME THIS AREA IS INITIALLY ZEROED BY THE CALLER.
+ *
+ * We return FALSE if data source requested suspension. In that case no
+ * changes have been made to permanent state. (Exception: some output
+ * coefficients may already have been assigned. This is harmless for
+ * spectral selection, since we'll just re-assign them on the next call.
+ * Successive approximation AC refinement has to be more careful, however.)
+ */
+
+/*
+ * MCU decoding for DC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+decode_mcu_DC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ int Al = cinfo->Al;
+ register int s, r;
+ int blkn, ci;
+ JBLOCKROW block;
+ BITREAD_STATE_VARS;
+ savable_state state;
+ d_derived_tbl * tbl;
+ jpeg_component_info * compptr;
+
+ /* Process restart marker if needed; may have to suspend */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! process_restart(cinfo))
+ return FALSE;
+ }
+
+ /* If we've run out of data, just leave the MCU set to zeroes.
+ * This way, we return uniform gray for the remainder of the segment.
+ */
+ if (! entropy->pub.insufficient_data) {
+
+ /* Load up working state */
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+ ASSIGN_STATE(state, entropy->saved);
+
+ /* Outer loop handles each block in the MCU */
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+ ci = cinfo->MCU_membership[blkn];
+ compptr = cinfo->cur_comp_info[ci];
+ tbl = entropy->derived_tbls[compptr->dc_tbl_no];
+
+ /* Decode a single block's worth of coefficients */
+
+ /* Section F.2.2.1: decode the DC coefficient difference */
+ HUFF_DECODE(s, br_state, tbl, return FALSE, label1);
+ if (s) {
+ CHECK_BIT_BUFFER(br_state, s, return FALSE);
+ r = GET_BITS(s);
+ s = HUFF_EXTEND(r, s);
+ }
+
+ /* Convert DC difference to actual value, update last_dc_val */
+ s += state.last_dc_val[ci];
+ state.last_dc_val[ci] = s;
+ /* Scale and output the coefficient (assumes jpeg_natural_order[0]=0) */
+ (*block)[0] = (JCOEF) (s << Al);
+ }
+
+ /* Completed MCU, so update state */
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+ ASSIGN_STATE(entropy->saved, state);
+ }
+
+ /* Account for restart interval (no-op if not using restarts) */
+ entropy->restarts_to_go--;
+
+ return TRUE;
+}
+
+
+/*
+ * MCU decoding for AC initial scan (either spectral selection,
+ * or first pass of successive approximation).
+ */
+
+METHODDEF(boolean)
+decode_mcu_AC_first (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ int Se = cinfo->Se;
+ int Al = cinfo->Al;
+ register int s, k, r;
+ unsigned int EOBRUN;
+ JBLOCKROW block;
+ BITREAD_STATE_VARS;
+ d_derived_tbl * tbl;
+
+ /* Process restart marker if needed; may have to suspend */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! process_restart(cinfo))
+ return FALSE;
+ }
+
+ /* If we've run out of data, just leave the MCU set to zeroes.
+ * This way, we return uniform gray for the remainder of the segment.
+ */
+ if (! entropy->pub.insufficient_data) {
+
+ /* Load up working state.
+ * We can avoid loading/saving bitread state if in an EOB run.
+ */
+ EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
+
+ /* There is always only one block per MCU */
+
+ if (EOBRUN > 0) /* if it's a band of zeroes... */
+ EOBRUN--; /* ...process it now (we do nothing) */
+ else {
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+ block = MCU_data[0];
+ tbl = entropy->ac_derived_tbl;
+
+ for (k = cinfo->Ss; k <= Se; k++) {
+ HUFF_DECODE(s, br_state, tbl, return FALSE, label2);
+ r = s >> 4;
+ s &= 15;
+ if (s) {
+ k += r;
+ CHECK_BIT_BUFFER(br_state, s, return FALSE);
+ r = GET_BITS(s);
+ s = HUFF_EXTEND(r, s);
+ /* Scale and output coefficient in natural (dezigzagged) order */
+ (*block)[jpeg_natural_order[k]] = (JCOEF) (s << Al);
+ } else {
+ if (r == 15) { /* ZRL */
+ k += 15; /* skip 15 zeroes in band */
+ } else { /* EOBr, run length is 2^r + appended bits */
+ EOBRUN = 1 << r;
+ if (r) { /* EOBr, r > 0 */
+ CHECK_BIT_BUFFER(br_state, r, return FALSE);
+ r = GET_BITS(r);
+ EOBRUN += r;
+ }
+ EOBRUN--; /* this band is processed at this moment */
+ break; /* force end-of-band */
+ }
+ }
+ }
+
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+ }
+
+ /* Completed MCU, so update state */
+ entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
+ }
+
+ /* Account for restart interval (no-op if not using restarts) */
+ entropy->restarts_to_go--;
+
+ return TRUE;
+}
+
+
+/*
+ * MCU decoding for DC successive approximation refinement scan.
+ * Note: we assume such scans can be multi-component, although the spec
+ * is not very clear on the point.
+ */
+
+METHODDEF(boolean)
+decode_mcu_DC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
+ int blkn;
+ JBLOCKROW block;
+ BITREAD_STATE_VARS;
+
+ /* Process restart marker if needed; may have to suspend */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! process_restart(cinfo))
+ return FALSE;
+ }
+
+ /* Not worth the cycles to check insufficient_data here,
+ * since we will not change the data anyway if we read zeroes.
+ */
+
+ /* Load up working state */
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+
+ /* Outer loop handles each block in the MCU */
+
+ for (blkn = 0; blkn < cinfo->blocks_in_MCU; blkn++) {
+ block = MCU_data[blkn];
+
+ /* Encoded data is simply the next bit of the two's-complement DC value */
+ CHECK_BIT_BUFFER(br_state, 1, return FALSE);
+ if (GET_BITS(1))
+ (*block)[0] |= p1;
+ /* Note: since we use |=, repeating the assignment later is safe */
+ }
+
+ /* Completed MCU, so update state */
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+
+ /* Account for restart interval (no-op if not using restarts) */
+ entropy->restarts_to_go--;
+
+ return TRUE;
+}
+
+
+/*
+ * MCU decoding for AC successive approximation refinement scan.
+ */
+
+METHODDEF(boolean)
+decode_mcu_AC_refine (j_decompress_ptr cinfo, JBLOCKROW *MCU_data)
+{
+ phuff_entropy_ptr entropy = (phuff_entropy_ptr) cinfo->entropy;
+ int Se = cinfo->Se;
+ int p1 = 1 << cinfo->Al; /* 1 in the bit position being coded */
+ int m1 = (-1) << cinfo->Al; /* -1 in the bit position being coded */
+ register int s, k, r;
+ unsigned int EOBRUN;
+ JBLOCKROW block;
+ JCOEFPTR thiscoef;
+ BITREAD_STATE_VARS;
+ d_derived_tbl * tbl;
+ int num_newnz;
+ int newnz_pos[DCTSIZE2];
+
+ /* Process restart marker if needed; may have to suspend */
+ if (cinfo->restart_interval) {
+ if (entropy->restarts_to_go == 0)
+ if (! process_restart(cinfo))
+ return FALSE;
+ }
+
+ /* If we've run out of data, don't modify the MCU.
+ */
+ if (! entropy->pub.insufficient_data) {
+
+ /* Load up working state */
+ BITREAD_LOAD_STATE(cinfo,entropy->bitstate);
+ EOBRUN = entropy->saved.EOBRUN; /* only part of saved state we need */
+
+ /* There is always only one block per MCU */
+ block = MCU_data[0];
+ tbl = entropy->ac_derived_tbl;
+
+ /* If we are forced to suspend, we must undo the assignments to any newly
+ * nonzero coefficients in the block, because otherwise we'd get confused
+ * next time about which coefficients were already nonzero.
+ * But we need not undo addition of bits to already-nonzero coefficients;
+ * instead, we can test the current bit to see if we already did it.
+ */
+ num_newnz = 0;
+
+ /* initialize coefficient loop counter to start of band */
+ k = cinfo->Ss;
+
+ if (EOBRUN == 0) {
+ for (; k <= Se; k++) {
+ HUFF_DECODE(s, br_state, tbl, goto undoit, label3);
+ r = s >> 4;
+ s &= 15;
+ if (s) {
+ if (s != 1) /* size of new coef should always be 1 */
+ WARNMS(cinfo, JWRN_HUFF_BAD_CODE);
+ CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+ if (GET_BITS(1))
+ s = p1; /* newly nonzero coef is positive */
+ else
+ s = m1; /* newly nonzero coef is negative */
+ } else {
+ if (r != 15) {
+ EOBRUN = 1 << r; /* EOBr, run length is 2^r + appended bits */
+ if (r) {
+ CHECK_BIT_BUFFER(br_state, r, goto undoit);
+ r = GET_BITS(r);
+ EOBRUN += r;
+ }
+ break; /* rest of block is handled by EOB logic */
+ }
+ /* note s = 0 for processing ZRL */
+ }
+ /* Advance over already-nonzero coefs and r still-zero coefs,
+ * appending correction bits to the nonzeroes. A correction bit is 1
+ * if the absolute value of the coefficient must be increased.
+ */
+ do {
+ thiscoef = *block + jpeg_natural_order[k];
+ if (*thiscoef != 0) {
+ CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+ if (GET_BITS(1)) {
+ if ((*thiscoef & p1) == 0) { /* do nothing if already set it */
+ if (*thiscoef >= 0)
+ *thiscoef += p1;
+ else
+ *thiscoef += m1;
+ }
+ }
+ } else {
+ if (--r < 0)
+ break; /* reached target zero coefficient */
+ }
+ k++;
+ } while (k <= Se);
+ if (s) {
+ int pos = jpeg_natural_order[k];
+ /* Output newly nonzero coefficient */
+ (*block)[pos] = (JCOEF) s;
+ /* Remember its position in case we have to suspend */
+ newnz_pos[num_newnz++] = pos;
+ }
+ }
+ }
+
+ if (EOBRUN > 0) {
+ /* Scan any remaining coefficient positions after the end-of-band
+ * (the last newly nonzero coefficient, if any). Append a correction
+ * bit to each already-nonzero coefficient. A correction bit is 1
+ * if the absolute value of the coefficient must be increased.
+ */
+ for (; k <= Se; k++) {
+ thiscoef = *block + jpeg_natural_order[k];
+ if (*thiscoef != 0) {
+ CHECK_BIT_BUFFER(br_state, 1, goto undoit);
+ if (GET_BITS(1)) {
+ if ((*thiscoef & p1) == 0) { /* do nothing if already changed it */
+ if (*thiscoef >= 0)
+ *thiscoef += p1;
+ else
+ *thiscoef += m1;
+ }
+ }
+ }
+ }
+ /* Count one block completed in EOB run */
+ EOBRUN--;
+ }
+
+ /* Completed MCU, so update state */
+ BITREAD_SAVE_STATE(cinfo,entropy->bitstate);
+ entropy->saved.EOBRUN = EOBRUN; /* only part of saved state we need */
+ }
+
+ /* Account for restart interval (no-op if not using restarts) */
+ entropy->restarts_to_go--;
+
+ return TRUE;
+
+undoit:
+ /* Re-zero any output coefficients that we made newly nonzero */
+ while (num_newnz > 0)
+ (*block)[newnz_pos[--num_newnz]] = 0;
+
+ return FALSE;
+}
+
+
+/*
+ * Module initialization routine for progressive Huffman entropy decoding.
+ */
+
+GLOBAL(void)
+jinit_phuff_decoder (j_decompress_ptr cinfo)
+{
+ phuff_entropy_ptr entropy;
+ int *coef_bit_ptr;
+ int ci, i;
+
+ entropy = (phuff_entropy_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(phuff_entropy_decoder));
+ cinfo->entropy = (struct jpeg_entropy_decoder *) entropy;
+ entropy->pub.start_pass = start_pass_phuff_decoder;
+
+ /* Mark derived tables unallocated */
+ for (i = 0; i < NUM_HUFF_TBLS; i++) {
+ entropy->derived_tbls[i] = NULL;
+ }
+
+ /* Create progression status table */
+ cinfo->coef_bits = (int (*)[DCTSIZE2])
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->num_components*DCTSIZE2*SIZEOF(int));
+ coef_bit_ptr = & cinfo->coef_bits[0][0];
+ for (ci = 0; ci < cinfo->num_components; ci++)
+ for (i = 0; i < DCTSIZE2; i++)
+ *coef_bit_ptr++ = -1;
+}
+
+#endif /* D_PROGRESSIVE_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdpostct.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdpostct.c
new file mode 100644
index 0000000..dc7a42c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdpostct.c
@@ -0,0 +1,290 @@
+/*
+ * jdpostct.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains the decompression postprocessing controller.
+ * This controller manages the upsampling, color conversion, and color
+ * quantization/reduction steps; specifically, it controls the buffering
+ * between upsample/color conversion and color quantization/reduction.
+ *
+ * If no color quantization/reduction is required, then this module has no
+ * work to do, and it just hands off to the upsample/color conversion code.
+ * An integrated upsample/convert/quantize process would tqreplace this module
+ * entirely.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Private buffer controller object */
+
+typedef struct {
+ struct jpeg_d_post_controller pub; /* public fields */
+
+ /* Color quantization source buffer: this holds output data from
+ * the upsample/color conversion step to be passed to the quantizer.
+ * For two-pass color quantization, we need a full-image buffer;
+ * for one-pass operation, a strip buffer is sufficient.
+ */
+ jvirt_sarray_ptr whole_image; /* virtual array, or NULL if one-pass */
+ JSAMPARRAY buffer; /* strip buffer, or current strip of virtual */
+ JDIMENSION strip_height; /* buffer size in rows */
+ /* for two-pass mode only: */
+ JDIMENSION starting_row; /* row # of first row in current strip */
+ JDIMENSION next_row; /* index of next row to fill/empty in strip */
+} my_post_controller;
+
+typedef my_post_controller * my_post_ptr;
+
+
+/* Forward declarations */
+METHODDEF(void) post_process_1pass
+ JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+#ifdef TQUANT_2PASS_SUPPORTED
+METHODDEF(void) post_process_prepass
+ JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+METHODDEF(void) post_process_2pass
+ JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+#endif
+
+
+/*
+ * Initialize for a processing pass.
+ */
+
+METHODDEF(void)
+start_pass_dpost (j_decompress_ptr cinfo, J_BUF_MODE pass_mode)
+{
+ my_post_ptr post = (my_post_ptr) cinfo->post;
+
+ switch (pass_mode) {
+ case JBUF_PASS_THRU:
+ if (cinfo->quantize_colors) {
+ /* Single-pass processing with color quantization. */
+ post->pub.post_process_data = post_process_1pass;
+ /* We could be doing buffered-image output before starting a 2-pass
+ * color quantization; in that case, jinit_d_post_controller did not
+ * allocate a strip buffer. Use the virtual-array buffer as workspace.
+ */
+ if (post->buffer == NULL) {
+ post->buffer = (*cinfo->mem->access_virt_sarray)
+ ((j_common_ptr) cinfo, post->whole_image,
+ (JDIMENSION) 0, post->strip_height, TRUE);
+ }
+ } else {
+ /* For single-pass processing without color quantization,
+ * I have no work to do; just call the upsampler directly.
+ */
+ post->pub.post_process_data = cinfo->upsample->upsample;
+ }
+ break;
+#ifdef TQUANT_2PASS_SUPPORTED
+ case JBUF_SAVE_AND_PASS:
+ /* First pass of 2-pass quantization */
+ if (post->whole_image == NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ post->pub.post_process_data = post_process_prepass;
+ break;
+ case JBUF_CRANK_DEST:
+ /* Second pass of 2-pass quantization */
+ if (post->whole_image == NULL)
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ post->pub.post_process_data = post_process_2pass;
+ break;
+#endif /* TQUANT_2PASS_SUPPORTED */
+ default:
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+ break;
+ }
+ post->starting_row = post->next_row = 0;
+}
+
+
+/*
+ * Process some data in the one-pass (strip buffer) case.
+ * This is used for color precision reduction as well as one-pass quantization.
+ */
+
+METHODDEF(void)
+post_process_1pass (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_post_ptr post = (my_post_ptr) cinfo->post;
+ JDIMENSION num_rows, max_rows;
+
+ /* Fill the buffer, but not more than what we can dump out in one go. */
+ /* Note we rely on the upsampler to detect bottom of image. */
+ max_rows = out_rows_avail - *out_row_ctr;
+ if (max_rows > post->strip_height)
+ max_rows = post->strip_height;
+ num_rows = 0;
+ (*cinfo->upsample->upsample) (cinfo,
+ input_buf, in_row_group_ctr, in_row_groups_avail,
+ post->buffer, &num_rows, max_rows);
+ /* Quantize and emit data. */
+ (*cinfo->cquantize->color_quantize) (cinfo,
+ post->buffer, output_buf + *out_row_ctr, (int) num_rows);
+ *out_row_ctr += num_rows;
+}
+
+
+#ifdef TQUANT_2PASS_SUPPORTED
+
+/*
+ * Process some data in the first pass of 2-pass quantization.
+ */
+
+METHODDEF(void)
+post_process_prepass (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_post_ptr post = (my_post_ptr) cinfo->post;
+ JDIMENSION old_next_row, num_rows;
+
+ /* Reposition virtual buffer if at start of strip. */
+ if (post->next_row == 0) {
+ post->buffer = (*cinfo->mem->access_virt_sarray)
+ ((j_common_ptr) cinfo, post->whole_image,
+ post->starting_row, post->strip_height, TRUE);
+ }
+
+ /* Upsample some data (up to a strip height's worth). */
+ old_next_row = post->next_row;
+ (*cinfo->upsample->upsample) (cinfo,
+ input_buf, in_row_group_ctr, in_row_groups_avail,
+ post->buffer, &post->next_row, post->strip_height);
+
+ /* Allow quantizer to scan new data. No data is emitted, */
+ /* but we advance out_row_ctr so outer loop can tell when we're done. */
+ if (post->next_row > old_next_row) {
+ num_rows = post->next_row - old_next_row;
+ (*cinfo->cquantize->color_quantize) (cinfo, post->buffer + old_next_row,
+ (JSAMPARRAY) NULL, (int) num_rows);
+ *out_row_ctr += num_rows;
+ }
+
+ /* Advance if we filled the strip. */
+ if (post->next_row >= post->strip_height) {
+ post->starting_row += post->strip_height;
+ post->next_row = 0;
+ }
+}
+
+
+/*
+ * Process some data in the second pass of 2-pass quantization.
+ */
+
+METHODDEF(void)
+post_process_2pass (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_post_ptr post = (my_post_ptr) cinfo->post;
+ JDIMENSION num_rows, max_rows;
+
+ /* Reposition virtual buffer if at start of strip. */
+ if (post->next_row == 0) {
+ post->buffer = (*cinfo->mem->access_virt_sarray)
+ ((j_common_ptr) cinfo, post->whole_image,
+ post->starting_row, post->strip_height, FALSE);
+ }
+
+ /* Determine number of rows to emit. */
+ num_rows = post->strip_height - post->next_row; /* available in strip */
+ max_rows = out_rows_avail - *out_row_ctr; /* available in output area */
+ if (num_rows > max_rows)
+ num_rows = max_rows;
+ /* We have to check bottom of image here, can't depend on upsampler. */
+ max_rows = cinfo->output_height - post->starting_row;
+ if (num_rows > max_rows)
+ num_rows = max_rows;
+
+ /* Quantize and emit data. */
+ (*cinfo->cquantize->color_quantize) (cinfo,
+ post->buffer + post->next_row, output_buf + *out_row_ctr,
+ (int) num_rows);
+ *out_row_ctr += num_rows;
+
+ /* Advance if we filled the strip. */
+ post->next_row += num_rows;
+ if (post->next_row >= post->strip_height) {
+ post->starting_row += post->strip_height;
+ post->next_row = 0;
+ }
+}
+
+#endif /* TQUANT_2PASS_SUPPORTED */
+
+
+/*
+ * Initialize postprocessing controller.
+ */
+
+GLOBAL(void)
+jinit_d_post_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
+{
+ my_post_ptr post;
+
+ post = (my_post_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_post_controller));
+ cinfo->post = (struct jpeg_d_post_controller *) post;
+ post->pub.start_pass = start_pass_dpost;
+ post->whole_image = NULL; /* flag for no virtual arrays */
+ post->buffer = NULL; /* flag for no strip buffer */
+
+ /* Create the quantization buffer, if needed */
+ if (cinfo->quantize_colors) {
+ /* The buffer strip height is max_v_samp_factor, which is typically
+ * an efficient number of rows for upsampling to return.
+ * (In the presence of output rescaling, we might want to be smarter?)
+ */
+ post->strip_height = (JDIMENSION) cinfo->max_v_samp_factor;
+ if (need_full_buffer) {
+ /* Two-pass color quantization: need full-image storage. */
+ /* We round up the number of rows to a multiple of the strip height. */
+#ifdef TQUANT_2PASS_SUPPORTED
+ post->whole_image = (*cinfo->mem->request_virt_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
+ cinfo->output_width * cinfo->out_color_components,
+ (JDIMENSION) jround_up((long) cinfo->output_height,
+ (long) post->strip_height),
+ post->strip_height);
+#else
+ ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
+#endif /* TQUANT_2PASS_SUPPORTED */
+ } else {
+ /* One-pass color quantization: just make a strip buffer. */
+ post->buffer = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ cinfo->output_width * cinfo->out_color_components,
+ post->strip_height);
+ }
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdsample.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdsample.c
new file mode 100644
index 0000000..5d9f60e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdsample.c
@@ -0,0 +1,478 @@
+/*
+ * jdsample.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains upsampling routines.
+ *
+ * Upsampling input data is counted in "row groups". A row group
+ * is defined to be (v_samp_factor * DCT_scaled_size / min_DCT_scaled_size)
+ * sample rows of each component. Upsampling will normally produce
+ * max_v_samp_factor pixel rows from each row group (but this could vary
+ * if the upsampler is applying a scale factor of its own).
+ *
+ * An excellent reference for image resampling is
+ * Digital Image Warping, George Wolberg, 1990.
+ * Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Pointer to routine to upsample a single component */
+typedef JTQT_METHOD(void, upsample1_ptr,
+ (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_upsampler pub; /* public fields */
+
+ /* Color conversion buffer. When using separate upsampling and color
+ * conversion steps, this buffer holds one upsampled row group until it
+ * has been color converted and output.
+ * Note: we do not allocate any storage for component(s) which are full-size,
+ * ie do not need rescaling. The corresponding entry of color_buf[] is
+ * simply set to point to the input data array, thereby avoiding copying.
+ */
+ JSAMPARRAY color_buf[MAX_COMPONENTS];
+
+ /* Per-component upsampling method pointers */
+ upsample1_ptr methods[MAX_COMPONENTS];
+
+ int next_row_out; /* counts rows emitted from color_buf */
+ JDIMENSION rows_to_go; /* counts rows remaining in image */
+
+ /* Height of an input row group for each component. */
+ int rowgroup_height[MAX_COMPONENTS];
+
+ /* These arrays save pixel expansion factors so that int_expand need not
+ * recompute them each time. They are unused for other upsampling methods.
+ */
+ UINT8 h_expand[MAX_COMPONENTS];
+ UINT8 v_expand[MAX_COMPONENTS];
+} my_upsampler;
+
+typedef my_upsampler * my_upsample_ptr;
+
+
+/*
+ * Initialize for an upsampling pass.
+ */
+
+METHODDEF(void)
+start_pass_upsample (j_decompress_ptr cinfo)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+
+ /* Mark the conversion buffer empty */
+ upsample->next_row_out = cinfo->max_v_samp_factor;
+ /* Initialize total-height counter for detecting bottom of image */
+ upsample->rows_to_go = cinfo->output_height;
+}
+
+
+/*
+ * Control routine to do upsampling (and color conversion).
+ *
+ * In this version we upsample each component independently.
+ * We upsample one row group into the conversion buffer, then apply
+ * color conversion a row at a time.
+ */
+
+METHODDEF(void)
+sep_upsample (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ int ci;
+ jpeg_component_info * compptr;
+ JDIMENSION num_rows;
+
+ /* Fill the conversion buffer, if it's empty */
+ if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Invoke per-component upsample method. Notice we pass a POINTER
+ * to color_buf[ci], so that fullsize_upsample can change it.
+ */
+ (*upsample->methods[ci]) (cinfo, compptr,
+ input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
+ upsample->color_buf + ci);
+ }
+ upsample->next_row_out = 0;
+ }
+
+ /* Color-convert and emit rows */
+
+ /* How many we have in the buffer: */
+ num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
+ /* Not more than the distance to the end of the image. Need this test
+ * in case the image height is not a multiple of max_v_samp_factor:
+ */
+ if (num_rows > upsample->rows_to_go)
+ num_rows = upsample->rows_to_go;
+ /* And not more than what the client can accept: */
+ out_rows_avail -= *out_row_ctr;
+ if (num_rows > out_rows_avail)
+ num_rows = out_rows_avail;
+
+ (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
+ (JDIMENSION) upsample->next_row_out,
+ output_buf + *out_row_ctr,
+ (int) num_rows);
+
+ /* Adjust counts */
+ *out_row_ctr += num_rows;
+ upsample->rows_to_go -= num_rows;
+ upsample->next_row_out += num_rows;
+ /* When the buffer is emptied, declare this input row group consumed */
+ if (upsample->next_row_out >= cinfo->max_v_samp_factor)
+ (*in_row_group_ctr)++;
+}
+
+
+/*
+ * These are the routines invoked by sep_upsample to upsample pixel values
+ * of a single component. One row group is processed per call.
+ */
+
+
+/*
+ * For full-size components, we just make color_buf[ci] point at the
+ * input buffer, and thus avoid copying any data. Note that this is
+ * safe only because sep_upsample doesn't declare the input row group
+ * "consumed" until we are done color converting and emitting it.
+ */
+
+METHODDEF(void)
+fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ *output_data_ptr = input_data;
+}
+
+
+/*
+ * This is a no-op version used for "uninteresting" components.
+ * These components will not be referenced by color conversion.
+ */
+
+METHODDEF(void)
+noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ *output_data_ptr = NULL; /* safety check */
+}
+
+
+/*
+ * This version handles any integral sampling ratios.
+ * This is not used for typical JPEG files, so it need not be fast.
+ * Nor, for that matter, is it particularly accurate: the algorithm is
+ * simple replication of the input pixel onto the corresponding output
+ * pixels. The hi-falutin sampling literature refers to this as a
+ * "box filter". A box filter tends to introduce visible artifacts,
+ * so if you are actually going to use 3:1 or 4:1 sampling ratios
+ * you would be well advised to improve this code.
+ */
+
+METHODDEF(void)
+int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
+ JSAMPARRAY output_data = *output_data_ptr;
+ register JSAMPROW inptr, outptr;
+ register JSAMPLE invalue;
+ register int h;
+ JSAMPROW outend;
+ int h_expand, v_expand;
+ int inrow, outrow;
+
+ h_expand = upsample->h_expand[compptr->component_index];
+ v_expand = upsample->v_expand[compptr->component_index];
+
+ inrow = outrow = 0;
+ while (outrow < cinfo->max_v_samp_factor) {
+ /* Generate one output row with proper horizontal expansion */
+ inptr = input_data[inrow];
+ outptr = output_data[outrow];
+ outend = outptr + cinfo->output_width;
+ while (outptr < outend) {
+ invalue = *inptr++; /* don't need GETJSAMPLE() here */
+ for (h = h_expand; h > 0; h--) {
+ *outptr++ = invalue;
+ }
+ }
+ /* Generate any additional output rows by duplicating the first one */
+ if (v_expand > 1) {
+ jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
+ v_expand-1, cinfo->output_width);
+ }
+ inrow++;
+ outrow += v_expand;
+ }
+}
+
+
+/*
+ * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
+ * It's still a box filter.
+ */
+
+METHODDEF(void)
+h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ JSAMPARRAY output_data = *output_data_ptr;
+ register JSAMPROW inptr, outptr;
+ register JSAMPLE invalue;
+ JSAMPROW outend;
+ int inrow;
+
+ for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
+ inptr = input_data[inrow];
+ outptr = output_data[inrow];
+ outend = outptr + cinfo->output_width;
+ while (outptr < outend) {
+ invalue = *inptr++; /* don't need GETJSAMPLE() here */
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ }
+ }
+}
+
+
+/*
+ * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
+ * It's still a box filter.
+ */
+
+METHODDEF(void)
+h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ JSAMPARRAY output_data = *output_data_ptr;
+ register JSAMPROW inptr, outptr;
+ register JSAMPLE invalue;
+ JSAMPROW outend;
+ int inrow, outrow;
+
+ inrow = outrow = 0;
+ while (outrow < cinfo->max_v_samp_factor) {
+ inptr = input_data[inrow];
+ outptr = output_data[outrow];
+ outend = outptr + cinfo->output_width;
+ while (outptr < outend) {
+ invalue = *inptr++; /* don't need GETJSAMPLE() here */
+ *outptr++ = invalue;
+ *outptr++ = invalue;
+ }
+ jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
+ 1, cinfo->output_width);
+ inrow++;
+ outrow += 2;
+ }
+}
+
+
+/*
+ * Fancy processing for the common case of 2:1 horizontal and 1:1 vertical.
+ *
+ * The upsampling algorithm is linear interpolation between pixel centers,
+ * also known as a "triangle filter". This is a good compromise between
+ * speed and visual quality. The centers of the output pixels are 1/4 and 3/4
+ * of the way between input pixel centers.
+ *
+ * A note about the "bias" calculations: when rounding fractional values to
+ * integer, we do not want to always round 0.5 up to the next integer.
+ * If we did that, we'd introduce a noticeable bias towards larger values.
+ * Instead, this code is arranged so that 0.5 will be rounded up or down at
+ * alternate pixel locations (a simple ordered dither pattern).
+ */
+
+METHODDEF(void)
+h2v1_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ JSAMPARRAY output_data = *output_data_ptr;
+ register JSAMPROW inptr, outptr;
+ register int invalue;
+ register JDIMENSION colctr;
+ int inrow;
+
+ for (inrow = 0; inrow < cinfo->max_v_samp_factor; inrow++) {
+ inptr = input_data[inrow];
+ outptr = output_data[inrow];
+ /* Special case for first column */
+ invalue = GETJSAMPLE(*inptr++);
+ *outptr++ = (JSAMPLE) invalue;
+ *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(*inptr) + 2) >> 2);
+
+ for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
+ /* General case: 3/4 * nearer pixel + 1/4 * further pixel */
+ invalue = GETJSAMPLE(*inptr++) * 3;
+ *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(inptr[-2]) + 1) >> 2);
+ *outptr++ = (JSAMPLE) ((invalue + GETJSAMPLE(*inptr) + 2) >> 2);
+ }
+
+ /* Special case for last column */
+ invalue = GETJSAMPLE(*inptr);
+ *outptr++ = (JSAMPLE) ((invalue * 3 + GETJSAMPLE(inptr[-1]) + 1) >> 2);
+ *outptr++ = (JSAMPLE) invalue;
+ }
+}
+
+
+/*
+ * Fancy processing for the common case of 2:1 horizontal and 2:1 vertical.
+ * Again a triangle filter; see comments for h2v1 case, above.
+ *
+ * It is OK for us to reference the adjacent input rows because we demanded
+ * context from the main buffer controller (see initialization code).
+ */
+
+METHODDEF(void)
+h2v2_fancy_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
+{
+ JSAMPARRAY output_data = *output_data_ptr;
+ register JSAMPROW inptr0, inptr1, outptr;
+#if BITS_IN_JSAMPLE == 8
+ register int thiscolsum, lastcolsum, nextcolsum;
+#else
+ register INT32 thiscolsum, lastcolsum, nextcolsum;
+#endif
+ register JDIMENSION colctr;
+ int inrow, outrow, v;
+
+ inrow = outrow = 0;
+ while (outrow < cinfo->max_v_samp_factor) {
+ for (v = 0; v < 2; v++) {
+ /* inptr0 points to nearest input row, inptr1 points to next nearest */
+ inptr0 = input_data[inrow];
+ if (v == 0) /* next nearest is row above */
+ inptr1 = input_data[inrow-1];
+ else /* next nearest is row below */
+ inptr1 = input_data[inrow+1];
+ outptr = output_data[outrow++];
+
+ /* Special case for first column */
+ thiscolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+ nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+ *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 8) >> 4);
+ *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
+ lastcolsum = thiscolsum; thiscolsum = nextcolsum;
+
+ for (colctr = compptr->downsampled_width - 2; colctr > 0; colctr--) {
+ /* General case: 3/4 * nearer pixel + 1/4 * further pixel in each */
+ /* dimension, thus 9/16, 3/16, 3/16, 1/16 overall */
+ nextcolsum = GETJSAMPLE(*inptr0++) * 3 + GETJSAMPLE(*inptr1++);
+ *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
+ *outptr++ = (JSAMPLE) ((thiscolsum * 3 + nextcolsum + 7) >> 4);
+ lastcolsum = thiscolsum; thiscolsum = nextcolsum;
+ }
+
+ /* Special case for last column */
+ *outptr++ = (JSAMPLE) ((thiscolsum * 3 + lastcolsum + 8) >> 4);
+ *outptr++ = (JSAMPLE) ((thiscolsum * 4 + 7) >> 4);
+ }
+ inrow++;
+ }
+}
+
+
+/*
+ * Module initialization routine for upsampling.
+ */
+
+GLOBAL(void)
+jinit_upsampler (j_decompress_ptr cinfo)
+{
+ my_upsample_ptr upsample;
+ int ci;
+ jpeg_component_info * compptr;
+ boolean need_buffer, do_fancy;
+ int h_in_group, v_in_group, h_out_group, v_out_group;
+
+ upsample = (my_upsample_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_upsampler));
+ cinfo->upsample = (struct jpeg_upsampler *) upsample;
+ upsample->pub.start_pass = start_pass_upsample;
+ upsample->pub.upsample = sep_upsample;
+ upsample->pub.need_context_rows = FALSE; /* until we tqfind out differently */
+
+ if (cinfo->CCIR601_sampling) /* this isn't supported */
+ ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
+
+ /* jdmainct.c doesn't support context rows when min_DCT_scaled_size = 1,
+ * so don't ask for it.
+ */
+ do_fancy = cinfo->do_fancy_upsampling && cinfo->min_DCT_scaled_size > 1;
+
+ /* Verify we can handle the sampling factors, select per-component methods,
+ * and create storage as needed.
+ */
+ for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
+ ci++, compptr++) {
+ /* Compute size of an "input group" after IDCT scaling. This many samples
+ * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
+ */
+ h_in_group = (compptr->h_samp_factor * compptr->DCT_scaled_size) /
+ cinfo->min_DCT_scaled_size;
+ v_in_group = (compptr->v_samp_factor * compptr->DCT_scaled_size) /
+ cinfo->min_DCT_scaled_size;
+ h_out_group = cinfo->max_h_samp_factor;
+ v_out_group = cinfo->max_v_samp_factor;
+ upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
+ need_buffer = TRUE;
+ if (! compptr->component_needed) {
+ /* Don't bother to upsample an uninteresting component. */
+ upsample->methods[ci] = noop_upsample;
+ need_buffer = FALSE;
+ } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
+ /* Fullsize components can be processed without any work. */
+ upsample->methods[ci] = fullsize_upsample;
+ need_buffer = FALSE;
+ } else if (h_in_group * 2 == h_out_group &&
+ v_in_group == v_out_group) {
+ /* Special cases for 2h1v upsampling */
+ if (do_fancy && compptr->downsampled_width > 2)
+ upsample->methods[ci] = h2v1_fancy_upsample;
+ else
+ upsample->methods[ci] = h2v1_upsample;
+ } else if (h_in_group * 2 == h_out_group &&
+ v_in_group * 2 == v_out_group) {
+ /* Special cases for 2h2v upsampling */
+ if (do_fancy && compptr->downsampled_width > 2) {
+ upsample->methods[ci] = h2v2_fancy_upsample;
+ upsample->pub.need_context_rows = TRUE;
+ } else
+ upsample->methods[ci] = h2v2_upsample;
+ } else if ((h_out_group % h_in_group) == 0 &&
+ (v_out_group % v_in_group) == 0) {
+ /* Generic integral-factors upsampling method */
+ upsample->methods[ci] = int_upsample;
+ upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
+ upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
+ } else
+ ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
+ if (need_buffer) {
+ upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (JDIMENSION) jround_up((long) cinfo->output_width,
+ (long) cinfo->max_h_samp_factor),
+ (JDIMENSION) cinfo->max_v_samp_factor);
+ }
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jdtrans.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jdtrans.c
new file mode 100644
index 0000000..ed97448
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jdtrans.c
@@ -0,0 +1,143 @@
+/*
+ * jdtrans.c
+ *
+ * Copyright (C) 1995-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains library routines for transcoding decompression,
+ * that is, reading raw DCT coefficient arrays from an input JPEG file.
+ * The routines in jdapimin.c will also be needed by a transcoder.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/* Forward declarations */
+LOCAL(void) transdecode_master_selection JPP((j_decompress_ptr cinfo));
+
+
+/*
+ * Read the coefficient arrays from a JPEG file.
+ * jpeg_read_header must be completed before calling this.
+ *
+ * The entire image is read into a set of virtual coefficient-block arrays,
+ * one per component. The return value is a pointer to the array of
+ * virtual-array descriptors. These can be manipulated directly via the
+ * JPEG memory manager, or handed off to jpeg_write_coefficients().
+ * To release the memory occupied by the virtual arrays, call
+ * jpeg_finish_decompress() when done with the data.
+ *
+ * An alternative usage is to simply obtain access to the coefficient arrays
+ * during a buffered-image-mode decompression operation. This is allowed
+ * after any jpeg_finish_output() call. The arrays can be accessed until
+ * jpeg_finish_decompress() is called. (Note that any call to the library
+ * may reposition the arrays, so don't rely on access_virt_barray() results
+ * to stay valid across library calls.)
+ *
+ * Returns NULL if suspended. This case need be checked only if
+ * a suspending data source is used.
+ */
+
+GLOBAL(jvirt_barray_ptr *)
+jpeg_read_coefficients (j_decompress_ptr cinfo)
+{
+ if (cinfo->global_state == DSTATE_READY) {
+ /* First call: initialize active modules */
+ transdecode_master_selection(cinfo);
+ cinfo->global_state = DSTATE_RDCOEFS;
+ }
+ if (cinfo->global_state == DSTATE_RDCOEFS) {
+ /* Absorb whole file into the coef buffer */
+ for (;;) {
+ int retcode;
+ /* Call progress monitor hook if present */
+ if (cinfo->progress != NULL)
+ (*cinfo->progress->progress_monitor) ((j_common_ptr) cinfo);
+ /* Absorb some more input */
+ retcode = (*cinfo->inputctl->consume_input) (cinfo);
+ if (retcode == JPEG_SUSPENDED)
+ return NULL;
+ if (retcode == JPEG_REACHED_EOI)
+ break;
+ /* Advance progress counter if appropriate */
+ if (cinfo->progress != NULL &&
+ (retcode == JPEG_ROW_COMPLETED || retcode == JPEG_REACHED_SOS)) {
+ if (++cinfo->progress->pass_counter >= cinfo->progress->pass_limit) {
+ /* startup underestimated number of scans; ratchet up one scan */
+ cinfo->progress->pass_limit += (long) cinfo->total_iMCU_rows;
+ }
+ }
+ }
+ /* Set state so that jpeg_finish_decompress does the right thing */
+ cinfo->global_state = DSTATE_STOPPING;
+ }
+ /* At this point we should be in state DSTATE_STOPPING if being used
+ * standalone, or in state DSTATE_BUFIMAGE if being invoked to get access
+ * to the coefficients during a full buffered-image-mode decompression.
+ */
+ if ((cinfo->global_state == DSTATE_STOPPING ||
+ cinfo->global_state == DSTATE_BUFIMAGE) && cinfo->buffered_image) {
+ return cinfo->coef->coef_arrays;
+ }
+ /* Oops, improper usage */
+ ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
+ return NULL; /* keep compiler happy */
+}
+
+
+/*
+ * Master selection of decompression modules for transcoding.
+ * This substitutes for jdmaster.c's initialization of the full decompressor.
+ */
+
+LOCAL(void)
+transdecode_master_selection (j_decompress_ptr cinfo)
+{
+ /* This is effectively a buffered-image operation. */
+ cinfo->buffered_image = TRUE;
+
+ /* Entropy decoding: either Huffman or arithmetic coding. */
+ if (cinfo->arith_code) {
+ ERREXIT(cinfo, JERR_ARITH_NOTIMPL);
+ } else {
+ if (cinfo->progressive_mode) {
+#ifdef D_PROGRESSIVE_SUPPORTED
+ jinit_phuff_decoder(cinfo);
+#else
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+#endif
+ } else
+ jinit_huff_decoder(cinfo);
+ }
+
+ /* Always get a full-image coefficient buffer. */
+ jinit_d_coef_controller(cinfo, TRUE);
+
+ /* We can now tell the memory manager to allocate virtual arrays. */
+ (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
+
+ /* Initialize input side of decompressor to consume first scan. */
+ (*cinfo->inputctl->start_input_pass) (cinfo);
+
+ /* Initialize progress monitoring. */
+ if (cinfo->progress != NULL) {
+ int nscans;
+ /* Estimate number of scans to set pass_limit. */
+ if (cinfo->progressive_mode) {
+ /* Arbitrarily estimate 2 interleaved DC scans + 3 AC scans/component. */
+ nscans = 2 + 3 * cinfo->num_components;
+ } else if (cinfo->inputctl->has_multiple_scans) {
+ /* For a nonprogressive multiscan file, estimate 1 scan per component. */
+ nscans = cinfo->num_components;
+ } else {
+ nscans = 1;
+ }
+ cinfo->progress->pass_counter = 0L;
+ cinfo->progress->pass_limit = (long) cinfo->total_iMCU_rows * nscans;
+ cinfo->progress->completed_passes = 0;
+ cinfo->progress->total_passes = 1;
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jerror.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jerror.c
new file mode 100644
index 0000000..b70c1f4
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jerror.c
@@ -0,0 +1,252 @@
+/*
+ * jerror.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains simple error-reporting and trace-message routines.
+ * These are suitable for Unix-like systems and others where writing to
+ * stderr is the right thing to do. Many applications will want to tqreplace
+ * some or all of these routines.
+ *
+ * If you define USE_WINDOWS_MESSAGEBOX in jconfig.h or in the makefile,
+ * you get a Windows-specific hack to display error messages in a dialog box.
+ * It ain't much, but it beats dropping error messages into the bit bucket,
+ * which is what happens to output to stderr under most Windows C compilers.
+ *
+ * These routines are used by both the compression and decompression code.
+ */
+
+/* this is not a core library module, so it doesn't define JPEG_INTERNALS */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jversion.h"
+#include "jerror.h"
+
+#ifdef USE_WINDOWS_MESSAGEBOX
+#include <windows.h>
+#endif
+
+#ifndef EXIT_FAILURE /* define exit() codes if not provided */
+#define EXIT_FAILURE 1
+#endif
+
+
+/*
+ * Create the message string table.
+ * We do this from the master message list in jerror.h by re-reading
+ * jerror.h with a suitable definition for macro JMESSAGE.
+ * The message table is made an external symbol just in case any applications
+ * want to refer to it directly.
+ */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_std_message_table jMsgTable
+#endif
+
+#define JMESSAGE(code,string) string ,
+
+const char * const jpeg_std_message_table[] = {
+#include "jerror.h"
+ NULL
+};
+
+
+/*
+ * Error exit handler: must not return to caller.
+ *
+ * Applications may override this if they want to get control back after
+ * an error. Typically one would longjmp somewhere instead of exiting.
+ * The setjmp buffer can be made a private field within an expanded error
+ * handler object. Note that the info needed to generate an error message
+ * is stored in the error object, so you can generate the message now or
+ * later, at your convenience.
+ * You should make sure that the JPEG object is cleaned up (with jpeg_abort
+ * or jpeg_destroy) at some point.
+ */
+
+METHODDEF(void)
+error_exit (j_common_ptr cinfo)
+{
+ /* Always display the message */
+ (*cinfo->err->output_message) (cinfo);
+
+ /* Let the memory manager delete any temp files before we die */
+ jpeg_destroy(cinfo);
+
+ exit(EXIT_FAILURE);
+}
+
+
+/*
+ * Actual output of an error or trace message.
+ * Applications may override this method to send JPEG messages somewhere
+ * other than stderr.
+ *
+ * On Windows, printing to stderr is generally completely useless,
+ * so we provide optional code to produce an error-dialog popup.
+ * Most Windows applications will still prefer to override this routine,
+ * but if they don't, it'll do something at least marginally useful.
+ *
+ * NOTE: to use the library in an environment that doesn't support the
+ * C stdio library, you may have to delete the call to fprintf() entirely,
+ * not just not use this routine.
+ */
+
+METHODDEF(void)
+output_message (j_common_ptr cinfo)
+{
+ char buffer[JMSG_LENGTH_MAX];
+
+ /* Create the message */
+ (*cinfo->err->format_message) (cinfo, buffer);
+
+#ifdef USE_WINDOWS_MESSAGEBOX
+ /* Display it in a message dialog box */
+ MessageBox(GetActiveWindow(), buffer, "JPEG Library Error",
+ MB_OK | MB_ICONERROR);
+#else
+ /* Send it to stderr, adding a newline */
+ fprintf(stderr, "%s\n", buffer);
+#endif
+}
+
+
+/*
+ * Decide whether to emit a trace or warning message.
+ * msg_level is one of:
+ * -1: recoverable corrupt-data warning, may want to abort.
+ * 0: important advisory messages (always display to user).
+ * 1: first level of tracing detail.
+ * 2,3,...: successively more detailed tracing messages.
+ * An application might override this method if it wanted to abort on warnings
+ * or change the policy about which messages to display.
+ */
+
+METHODDEF(void)
+emit_message (j_common_ptr cinfo, int msg_level)
+{
+ struct jpeg_error_mgr * err = cinfo->err;
+
+ if (msg_level < 0) {
+ /* It's a warning message. Since corrupt files may generate many warnings,
+ * the policy implemented here is to show only the first warning,
+ * unless trace_level >= 3.
+ */
+ if (err->num_warnings == 0 || err->trace_level >= 3)
+ (*err->output_message) (cinfo);
+ /* Always count warnings in num_warnings. */
+ err->num_warnings++;
+ } else {
+ /* It's a trace message. Show it if trace_level >= msg_level. */
+ if (err->trace_level >= msg_level)
+ (*err->output_message) (cinfo);
+ }
+}
+
+
+/*
+ * Format a message string for the most recent JPEG error or message.
+ * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX
+ * characters. Note that no '\n' character is added to the string.
+ * Few applications should need to override this method.
+ */
+
+METHODDEF(void)
+format_message (j_common_ptr cinfo, char * buffer)
+{
+ struct jpeg_error_mgr * err = cinfo->err;
+ int msg_code = err->msg_code;
+ const char * msgtext = NULL;
+ const char * msgptr;
+ char ch;
+ boolean isstring;
+
+ /* Look up message string in proper table */
+ if (msg_code > 0 && msg_code <= err->last_jpeg_message) {
+ msgtext = err->jpeg_message_table[msg_code];
+ } else if (err->addon_message_table != NULL &&
+ msg_code >= err->first_addon_message &&
+ msg_code <= err->last_addon_message) {
+ msgtext = err->addon_message_table[msg_code - err->first_addon_message];
+ }
+
+ /* Defend against bogus message number */
+ if (msgtext == NULL) {
+ err->msg_parm.i[0] = msg_code;
+ msgtext = err->jpeg_message_table[0];
+ }
+
+ /* Check for string parameter, as indicated by %s in the message text */
+ isstring = FALSE;
+ msgptr = msgtext;
+ while ((ch = *msgptr++) != '\0') {
+ if (ch == '%') {
+ if (*msgptr == 's') isstring = TRUE;
+ break;
+ }
+ }
+
+ /* Format the message into the passed buffer */
+ if (isstring)
+ sprintf(buffer, msgtext, err->msg_parm.s);
+ else
+ sprintf(buffer, msgtext,
+ err->msg_parm.i[0], err->msg_parm.i[1],
+ err->msg_parm.i[2], err->msg_parm.i[3],
+ err->msg_parm.i[4], err->msg_parm.i[5],
+ err->msg_parm.i[6], err->msg_parm.i[7]);
+}
+
+
+/*
+ * Reset error state variables at start of a new image.
+ * This is called during compression startup to reset trace/error
+ * processing to default state, without losing any application-specific
+ * method pointers. An application might possibly want to override
+ * this method if it has additional error processing state.
+ */
+
+METHODDEF(void)
+reset_error_mgr (j_common_ptr cinfo)
+{
+ cinfo->err->num_warnings = 0;
+ /* trace_level is not reset since it is an application-supplied parameter */
+ cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */
+}
+
+
+/*
+ * Fill in the standard error-handling methods in a jpeg_error_mgr object.
+ * Typical call is:
+ * struct jpeg_compress_struct cinfo;
+ * struct jpeg_error_mgr err;
+ *
+ * cinfo.err = jpeg_std_error(&err);
+ * after which the application may override some of the methods.
+ */
+
+GLOBAL(struct jpeg_error_mgr *)
+jpeg_std_error (struct jpeg_error_mgr * err)
+{
+ err->error_exit = error_exit;
+ err->emit_message = emit_message;
+ err->output_message = output_message;
+ err->format_message = format_message;
+ err->reset_error_mgr = reset_error_mgr;
+
+ err->trace_level = 0; /* default = no tracing */
+ err->num_warnings = 0; /* no warnings emitted yet */
+ err->msg_code = 0; /* may be useful as a flag for "no error" */
+
+ /* Initialize message table pointers */
+ err->jpeg_message_table = jpeg_std_message_table;
+ err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1;
+
+ err->addon_message_table = NULL;
+ err->first_addon_message = 0; /* for safety */
+ err->last_addon_message = 0;
+
+ return err;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jerror.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jerror.h
new file mode 100644
index 0000000..0060d2b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jerror.h
@@ -0,0 +1,291 @@
+/*
+ * jerror.h
+ *
+ * Copyright (C) 1994-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file defines the error and message codes for the JPEG library.
+ * Edit this file to add new codes, or to translate the message strings to
+ * some other language.
+ * A set of error-reporting macros are defined too. Some applications using
+ * the JPEG library may wish to include this file to get the error codes
+ * and/or the macros.
+ */
+
+/*
+ * To define the enum list of message codes, include this file without
+ * defining macro JMESSAGE. To create a message string table, include it
+ * again with a suitable JMESSAGE definition (see jerror.c for an example).
+ */
+#ifndef JMESSAGE
+#ifndef JERROR_H
+/* First time through, define the enum list */
+#define JMAKE_ENUM_LIST
+#else
+/* Repeated inclusions of this file are no-ops unless JMESSAGE is defined */
+#define JMESSAGE(code,string)
+#endif /* JERROR_H */
+#endif /* JMESSAGE */
+
+#ifdef JMAKE_ENUM_LIST
+
+typedef enum {
+
+#define JMESSAGE(code,string) code ,
+
+#endif /* JMAKE_ENUM_LIST */
+
+JMESSAGE(JMSG_NOMESSAGE, "Bogus message code %d") /* Must be first entry! */
+
+/* For maintenance convenience, list is alphabetical by message code name */
+JMESSAGE(JERR_ARITH_NOTIMPL,
+ "Sorry, there are legal restrictions on arithmetic coding")
+JMESSAGE(JERR_BAD_ALIGN_TYPE, "ALIGN_TYPE is wrong, please fix")
+JMESSAGE(JERR_BAD_ALLOC_CHUNK, "MAX_ALLOC_CHUNK is wrong, please fix")
+JMESSAGE(JERR_BAD_BUFFER_MODE, "Bogus buffer control mode")
+JMESSAGE(JERR_BAD_COMPONENT_ID, "Invalid component ID %d in SOS")
+JMESSAGE(JERR_BAD_DCT_COEF, "DCT coefficient out of range")
+JMESSAGE(JERR_BAD_DCTSIZE, "IDCT output block size %d not supported")
+JMESSAGE(JERR_BAD_HUFF_TABLE, "Bogus Huffman table definition")
+JMESSAGE(JERR_BAD_IN_COLORSPACE, "Bogus input colorspace")
+JMESSAGE(JERR_BAD_J_COLORSPACE, "Bogus JPEG colorspace")
+JMESSAGE(JERR_BAD_LENGTH, "Bogus marker length")
+JMESSAGE(JERR_BAD_LIB_VERSION,
+ "Wrong JPEG library version: library is %d, caller expects %d")
+JMESSAGE(JERR_BAD_MCU_SIZE, "Sampling factors too large for interleaved scan")
+JMESSAGE(JERR_BAD_POOL_ID, "Invalid memory pool code %d")
+JMESSAGE(JERR_BAD_PRECISION, "Unsupported JPEG data precision %d")
+JMESSAGE(JERR_BAD_PROGRESSION,
+ "Invalid progressive parameters Ss=%d Se=%d Ah=%d Al=%d")
+JMESSAGE(JERR_BAD_PROG_SCRIPT,
+ "Invalid progressive parameters at scan script entry %d")
+JMESSAGE(JERR_BAD_SAMPLING, "Bogus sampling factors")
+JMESSAGE(JERR_BAD_SCAN_SCRIPT, "Invalid scan script at entry %d")
+JMESSAGE(JERR_BAD_STATE, "Improper call to JPEG library in state %d")
+JMESSAGE(JERR_BAD_STRUCT_SIZE,
+ "JPEG parameter struct mismatch: library thinks size is %u, caller expects %u")
+JMESSAGE(JERR_BAD_VIRTUAL_ACCESS, "Bogus virtual array access")
+JMESSAGE(JERR_BUFFER_SIZE, "Buffer passed to JPEG library is too small")
+JMESSAGE(JERR_CANT_SUSPEND, "Suspension not allowed here")
+JMESSAGE(JERR_CCIR601_NOTIMPL, "CCIR601 sampling not implemented yet")
+JMESSAGE(JERR_COMPONENT_COUNT, "Too many color components: %d, max %d")
+JMESSAGE(JERR_CONVERSION_NOTIMPL, "Unsupported color conversion request")
+JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
+JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
+JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
+JMESSAGE(JERR_DTQT_INDEX, "Bogus DQT index %d")
+JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
+JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
+JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")
+JMESSAGE(JERR_EOI_EXPECTED, "Didn't expect more than one scan")
+JMESSAGE(JERR_FILE_READ, "Input file read error")
+JMESSAGE(JERR_FILE_WRITE, "Output file write error --- out of disk space?")
+JMESSAGE(JERR_FRACT_SAMPLE_NOTIMPL, "Fractional sampling not implemented yet")
+JMESSAGE(JERR_HUFF_CLEN_OVERFLOW, "Huffman code size table overflow")
+JMESSAGE(JERR_HUFF_MISSING_CODE, "Missing Huffman code table entry")
+JMESSAGE(JERR_IMAGE_TOO_BIG, "Maximum supported image dimension is %u pixels")
+JMESSAGE(JERR_INPUT_EMPTY, "Empty input file")
+JMESSAGE(JERR_INPUT_EOF, "Premature end of input file")
+JMESSAGE(JERR_MISMATCHED_TQUANT_TABLE,
+ "Cannot transcode due to multiple use of quantization table %d")
+JMESSAGE(JERR_MISSING_DATA, "Scan script does not transmit all data")
+JMESSAGE(JERR_MODE_CHANGE, "Invalid color quantization mode change")
+JMESSAGE(JERR_NOTIMPL, "Not implemented yet")
+JMESSAGE(JERR_NOT_COMPILED, "Requested feature was omitted at compile time")
+JMESSAGE(JERR_NO_BACKING_STORE, "Backing store not supported")
+JMESSAGE(JERR_NO_HUFF_TABLE, "Huffman table 0x%02x was not defined")
+JMESSAGE(JERR_NO_IMAGE, "JPEG datastream tqcontains no image")
+JMESSAGE(JERR_NO_TQUANT_TABLE, "Quantization table 0x%02x was not defined")
+JMESSAGE(JERR_NO_SOI, "Not a JPEG file: starts with 0x%02x 0x%02x")
+JMESSAGE(JERR_OUT_OF_MEMORY, "Insufficient memory (case %d)")
+JMESSAGE(JERR_TQUANT_COMPONENTS,
+ "Cannot quantize more than %d color components")
+JMESSAGE(JERR_TQUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
+JMESSAGE(JERR_TQUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
+JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
+JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
+JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
+JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
+JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
+JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
+JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
+JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")
+JMESSAGE(JERR_TFILE_WRITE,
+ "Write failed on temporary file --- out of disk space?")
+JMESSAGE(JERR_TOO_LITTLE_DATA, "Application transferred too few scanlines")
+JMESSAGE(JERR_UNKNOWN_MARKER, "Unsupported marker type 0x%02x")
+JMESSAGE(JERR_VIRTUAL_BUG, "Virtual array controller messed up")
+JMESSAGE(JERR_WIDTH_OVERFLOW, "Image too wide for this implementation")
+JMESSAGE(JERR_XMS_READ, "Read from XMS failed")
+JMESSAGE(JERR_XMS_WRITE, "Write to XMS failed")
+JMESSAGE(JMSG_COPYRIGHT, JCOPYRIGHT)
+JMESSAGE(JMSG_VERSION, JVERSION)
+JMESSAGE(JTRC_16BIT_TABLES,
+ "Caution: quantization tables are too coarse for baseline JPEG")
+JMESSAGE(JTRC_ADOBE,
+ "Adobe APP14 marker: version %d, flags 0x%04x 0x%04x, transform %d")
+JMESSAGE(JTRC_APP0, "Unknown APP0 marker (not JFIF), length %u")
+JMESSAGE(JTRC_APP14, "Unknown APP14 marker (not Adobe), length %u")
+JMESSAGE(JTRC_DAC, "Define Arithmetic Table 0x%02x: 0x%02x")
+JMESSAGE(JTRC_DHT, "Define Huffman Table 0x%02x")
+JMESSAGE(JTRC_DQT, "Define Quantization Table %d precision %d")
+JMESSAGE(JTRC_DRI, "Define Restart Interval %u")
+JMESSAGE(JTRC_EMS_CLOSE, "Freed EMS handle %u")
+JMESSAGE(JTRC_EMS_OPEN, "Obtained EMS handle %u")
+JMESSAGE(JTRC_EOI, "End Of Image")
+JMESSAGE(JTRC_HUFFBITS, " %3d %3d %3d %3d %3d %3d %3d %3d")
+JMESSAGE(JTRC_JFIF, "JFIF APP0 marker: version %d.%02d, density %dx%d %d")
+JMESSAGE(JTRC_JFIF_BADTHUMBNAILSIZE,
+ "Warning: thumbnail image size does not match data length %u")
+JMESSAGE(JTRC_JFIF_EXTENSION,
+ "JFIF extension marker: type 0x%02x, length %u")
+JMESSAGE(JTRC_JFIF_THUMBNAIL, " with %d x %d thumbnail image")
+JMESSAGE(JTRC_MISC_MARKER, "Miscellaneous marker 0x%02x, length %u")
+JMESSAGE(JTRC_PARMLESS_MARKER, "Unexpected marker 0x%02x")
+JMESSAGE(JTRC_TQUANTVALS, " %4u %4u %4u %4u %4u %4u %4u %4u")
+JMESSAGE(JTRC_TQUANT_3_NCOLORS, "Quantizing to %d = %d*%d*%d colors")
+JMESSAGE(JTRC_TQUANT_NCOLORS, "Quantizing to %d colors")
+JMESSAGE(JTRC_TQUANT_SELECTED, "Selected %d colors for quantization")
+JMESSAGE(JTRC_RECOVERY_ACTION, "At marker 0x%02x, recovery action %d")
+JMESSAGE(JTRC_RST, "RST%d")
+JMESSAGE(JTRC_SMOOTH_NOTIMPL,
+ "Smoothing not supported with nonstandard sampling ratios")
+JMESSAGE(JTRC_SOF, "Start Of Frame 0x%02x: width=%u, height=%u, components=%d")
+JMESSAGE(JTRC_SOF_COMPONENT, " Component %d: %dhx%dv q=%d")
+JMESSAGE(JTRC_SOI, "Start of Image")
+JMESSAGE(JTRC_SOS, "Start Of Scan: %d components")
+JMESSAGE(JTRC_SOS_COMPONENT, " Component %d: dc=%d ac=%d")
+JMESSAGE(JTRC_SOS_PARAMS, " Ss=%d, Se=%d, Ah=%d, Al=%d")
+JMESSAGE(JTRC_TFILE_CLOSE, "Closed temporary file %s")
+JMESSAGE(JTRC_TFILE_OPEN, "Opened temporary file %s")
+JMESSAGE(JTRC_THUMB_JPEG,
+ "JFIF extension marker: JPEG-compressed thumbnail image, length %u")
+JMESSAGE(JTRC_THUMB_PALETTE,
+ "JFIF extension marker: palette thumbnail image, length %u")
+JMESSAGE(JTRC_THUMB_RGB,
+ "JFIF extension marker: RGB thumbnail image, length %u")
+JMESSAGE(JTRC_UNKNOWN_IDS,
+ "Unrecognized component IDs %d %d %d, assuming YCbCr")
+JMESSAGE(JTRC_XMS_CLOSE, "Freed XMS handle %u")
+JMESSAGE(JTRC_XMS_OPEN, "Obtained XMS handle %u")
+JMESSAGE(JWRN_ADOBE_XFORM, "Unknown Adobe color transform code %d")
+JMESSAGE(JWRN_BOGUS_PROGRESSION,
+ "Inconsistent progression sequence for component %d coefficient %d")
+JMESSAGE(JWRN_EXTRANEOUS_DATA,
+ "Corrupt JPEG data: %u extraneous bytes before marker 0x%02x")
+JMESSAGE(JWRN_HIT_MARKER, "Corrupt JPEG data: premature end of data segment")
+JMESSAGE(JWRN_HUFF_BAD_CODE, "Corrupt JPEG data: bad Huffman code")
+JMESSAGE(JWRN_JFIF_MAJOR, "Warning: unknown JFIF revision number %d.%02d")
+JMESSAGE(JWRN_JPEG_EOF, "Premature end of JPEG file")
+JMESSAGE(JWRN_MUST_RESYNC,
+ "Corrupt JPEG data: found marker 0x%02x instead of RST%d")
+JMESSAGE(JWRN_NOT_SETQUENTIAL, "Invalid SOS parameters for sequential JPEG")
+JMESSAGE(JWRN_TOO_MUCH_DATA, "Application transferred too many scanlines")
+
+#ifdef JMAKE_ENUM_LIST
+
+ JMSG_LASTMSGCODE
+} J_MESSAGE_CODE;
+
+#undef JMAKE_ENUM_LIST
+#endif /* JMAKE_ENUM_LIST */
+
+/* Zap JMESSAGE macro so that future re-inclusions do nothing by default */
+#undef JMESSAGE
+
+
+#ifndef JERROR_H
+#define JERROR_H
+
+/* Macros to simplify using the error and trace message stuff */
+/* The first parameter is either type of cinfo pointer */
+
+/* Fatal errors (print message and exit) */
+#define ERREXIT(cinfo,code) \
+ ((cinfo)->err->msg_code = (code), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT1(cinfo,code,p1) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT2(cinfo,code,p1,p2) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT3(cinfo,code,p1,p2,p3) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (cinfo)->err->msg_parm.i[2] = (p3), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXIT4(cinfo,code,p1,p2,p3,p4) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (cinfo)->err->msg_parm.i[2] = (p3), \
+ (cinfo)->err->msg_parm.i[3] = (p4), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+#define ERREXITS(cinfo,code,str) \
+ ((cinfo)->err->msg_code = (code), \
+ strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
+ (*(cinfo)->err->error_exit) ((j_common_ptr) (cinfo)))
+
+#define MAKESTMT(stuff) do { stuff } while (0)
+
+/* Nonfatal errors (we can keep going, but the data is probably corrupt) */
+#define WARNMS(cinfo,code) \
+ ((cinfo)->err->msg_code = (code), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+#define WARNMS1(cinfo,code,p1) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+#define WARNMS2(cinfo,code,p1,p2) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), -1))
+
+/* Informational/debugging messages */
+#define TRACEMS(cinfo,lvl,code) \
+ ((cinfo)->err->msg_code = (code), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS1(cinfo,lvl,code,p1) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS2(cinfo,lvl,code,p1,p2) \
+ ((cinfo)->err->msg_code = (code), \
+ (cinfo)->err->msg_parm.i[0] = (p1), \
+ (cinfo)->err->msg_parm.i[1] = (p2), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+#define TRACEMS3(cinfo,lvl,code,p1,p2,p3) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS4(cinfo,lvl,code,p1,p2,p3,p4) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS5(cinfo,lvl,code,p1,p2,p3,p4,p5) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+ _mp[4] = (p5); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMS8(cinfo,lvl,code,p1,p2,p3,p4,p5,p6,p7,p8) \
+ MAKESTMT(int * _mp = (cinfo)->err->msg_parm.i; \
+ _mp[0] = (p1); _mp[1] = (p2); _mp[2] = (p3); _mp[3] = (p4); \
+ _mp[4] = (p5); _mp[5] = (p6); _mp[6] = (p7); _mp[7] = (p8); \
+ (cinfo)->err->msg_code = (code); \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)); )
+#define TRACEMSS(cinfo,lvl,code,str) \
+ ((cinfo)->err->msg_code = (code), \
+ strncpy((cinfo)->err->msg_parm.s, (str), JMSG_STR_PARM_MAX), \
+ (*(cinfo)->err->emit_message) ((j_common_ptr) (cinfo), (lvl)))
+
+#endif /* JERROR_H */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jfdctflt.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jfdctflt.c
new file mode 100644
index 0000000..70519db
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jfdctflt.c
@@ -0,0 +1,168 @@
+/*
+ * jfdctflt.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains a floating-point implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * This implementation should be more accurate than either of the integer
+ * DCT implementations. However, it may not give the same results on all
+ * machines because of differences in roundoff behavior. Speed will depend
+ * on the hardware's floating point capacity.
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column. Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README). The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs. These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries. The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with a fixed-point
+ * implementation, accuracy is lost due to imprecise representation of the
+ * scaled quantization values. However, that problem does not arise if
+ * we use floating point arithmetic.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_FLOAT_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+jpeg_fdct_float (FAST_FLOAT * data)
+{
+ FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
+ FAST_FLOAT z1, z2, z3, z4, z5, z11, z13;
+ FAST_FLOAT *dataptr;
+ int ctr;
+
+ /* Pass 1: process rows. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[0] + dataptr[7];
+ tmp7 = dataptr[0] - dataptr[7];
+ tmp1 = dataptr[1] + dataptr[6];
+ tmp6 = dataptr[1] - dataptr[6];
+ tmp2 = dataptr[2] + dataptr[5];
+ tmp5 = dataptr[2] - dataptr[5];
+ tmp3 = dataptr[3] + dataptr[4];
+ tmp4 = dataptr[3] - dataptr[4];
+
+ /* Even part */
+
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[0] = tmp10 + tmp11; /* phase 3 */
+ dataptr[4] = tmp10 - tmp11;
+
+ z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
+ dataptr[2] = tmp13 + z1; /* phase 5 */
+ dataptr[6] = tmp13 - z1;
+
+ /* Odd part */
+
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
+ z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
+ z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
+ z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ dataptr[5] = z13 + z2; /* phase 6 */
+ dataptr[3] = z13 - z2;
+ dataptr[1] = z11 + z4;
+ dataptr[7] = z11 - z4;
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ }
+
+ /* Pass 2: process columns. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+ tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+ tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+ tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+ tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+ tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+ tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+ tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+
+ /* Even part */
+
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
+ dataptr[DCTSIZE*4] = tmp10 - tmp11;
+
+ z1 = (tmp12 + tmp13) * ((FAST_FLOAT) 0.707106781); /* c4 */
+ dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
+ dataptr[DCTSIZE*6] = tmp13 - z1;
+
+ /* Odd part */
+
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = (tmp10 - tmp12) * ((FAST_FLOAT) 0.382683433); /* c6 */
+ z2 = ((FAST_FLOAT) 0.541196100) * tmp10 + z5; /* c2-c6 */
+ z4 = ((FAST_FLOAT) 1.306562965) * tmp12 + z5; /* c2+c6 */
+ z3 = tmp11 * ((FAST_FLOAT) 0.707106781); /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
+ dataptr[DCTSIZE*3] = z13 - z2;
+ dataptr[DCTSIZE*1] = z11 + z4;
+ dataptr[DCTSIZE*7] = z11 - z4;
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
+
+#endif /* DCT_FLOAT_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jfdctfst.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jfdctfst.c
new file mode 100644
index 0000000..56ae898
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jfdctfst.c
@@ -0,0 +1,224 @@
+/*
+ * jfdctfst.c
+ *
+ * Copyright (C) 1994-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains a fast, not so accurate integer implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column. Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README). The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs. These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries. The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with fixed-point math,
+ * accuracy is lost due to imprecise representation of the scaled
+ * quantization values. The smaller the quantization table entry, the less
+ * precise the scaled value, so this implementation does worse with high-
+ * quality-setting files than with low-quality ones.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_IFAST_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Scaling decisions are generally the same as in the LL&M algorithm;
+ * see jfdctint.c for more details. However, we choose to descale
+ * (right shift) multiplication products as soon as they are formed,
+ * rather than carrying additional fractional bits into subsequent additions.
+ * This compromises accuracy slightly, but it lets us save a few shifts.
+ * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
+ * everywhere except in the multiplications proper; this saves a good deal
+ * of work on 16-bit-int machines.
+ *
+ * Again to save a few shifts, the intermediate results between pass 1 and
+ * pass 2 are not upscaled, but are represented only to integral precision.
+ *
+ * A final compromise is to represent the multiplicative constants to only
+ * 8 fractional bits, rather than 13. This saves some shifting work on some
+ * machines, and may also reduce the cost of multiplication (since there
+ * are fewer one-bits in the constants).
+ */
+
+#define CONST_BITS 8
+
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 8
+#define FIX_0_382683433 ((INT32) 98) /* FIX(0.382683433) */
+#define FIX_0_541196100 ((INT32) 139) /* FIX(0.541196100) */
+#define FIX_0_707106781 ((INT32) 181) /* FIX(0.707106781) */
+#define FIX_1_306562965 ((INT32) 334) /* FIX(1.306562965) */
+#else
+#define FIX_0_382683433 FIX(0.382683433)
+#define FIX_0_541196100 FIX(0.541196100)
+#define FIX_0_707106781 FIX(0.707106781)
+#define FIX_1_306562965 FIX(1.306562965)
+#endif
+
+
+/* We can gain a little more speed, with a further compromise in accuracy,
+ * by omitting the addition in a descaling shift. This yields an incorrectly
+ * rounded result half the time...
+ */
+
+#ifndef USE_ACCURATE_ROUNDING
+#undef DESCALE
+#define DESCALE(x,n) RIGHT_SHIFT(x, n)
+#endif
+
+
+/* Multiply a DCTELEM variable by an INT32 constant, and immediately
+ * descale to yield a DCTELEM result.
+ */
+
+#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+jpeg_fdct_ifast (DCTELEM * data)
+{
+ DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ DCTELEM tmp10, tmp11, tmp12, tmp13;
+ DCTELEM z1, z2, z3, z4, z5, z11, z13;
+ DCTELEM *dataptr;
+ int ctr;
+ SHIFT_TEMPS
+
+ /* Pass 1: process rows. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[0] + dataptr[7];
+ tmp7 = dataptr[0] - dataptr[7];
+ tmp1 = dataptr[1] + dataptr[6];
+ tmp6 = dataptr[1] - dataptr[6];
+ tmp2 = dataptr[2] + dataptr[5];
+ tmp5 = dataptr[2] - dataptr[5];
+ tmp3 = dataptr[3] + dataptr[4];
+ tmp4 = dataptr[3] - dataptr[4];
+
+ /* Even part */
+
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[0] = tmp10 + tmp11; /* phase 3 */
+ dataptr[4] = tmp10 - tmp11;
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
+ dataptr[2] = tmp13 + z1; /* phase 5 */
+ dataptr[6] = tmp13 - z1;
+
+ /* Odd part */
+
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
+ z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
+ z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
+ z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ dataptr[5] = z13 + z2; /* phase 6 */
+ dataptr[3] = z13 - z2;
+ dataptr[1] = z11 + z4;
+ dataptr[7] = z11 - z4;
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ }
+
+ /* Pass 2: process columns. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+ tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+ tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+ tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+ tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+ tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+ tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+ tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+
+ /* Even part */
+
+ tmp10 = tmp0 + tmp3; /* phase 2 */
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[DCTSIZE*0] = tmp10 + tmp11; /* phase 3 */
+ dataptr[DCTSIZE*4] = tmp10 - tmp11;
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_707106781); /* c4 */
+ dataptr[DCTSIZE*2] = tmp13 + z1; /* phase 5 */
+ dataptr[DCTSIZE*6] = tmp13 - z1;
+
+ /* Odd part */
+
+ tmp10 = tmp4 + tmp5; /* phase 2 */
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ /* The rotator is modified from fig 4-8 to avoid extra negations. */
+ z5 = MULTIPLY(tmp10 - tmp12, FIX_0_382683433); /* c6 */
+ z2 = MULTIPLY(tmp10, FIX_0_541196100) + z5; /* c2-c6 */
+ z4 = MULTIPLY(tmp12, FIX_1_306562965) + z5; /* c2+c6 */
+ z3 = MULTIPLY(tmp11, FIX_0_707106781); /* c4 */
+
+ z11 = tmp7 + z3; /* phase 5 */
+ z13 = tmp7 - z3;
+
+ dataptr[DCTSIZE*5] = z13 + z2; /* phase 6 */
+ dataptr[DCTSIZE*3] = z13 - z2;
+ dataptr[DCTSIZE*1] = z11 + z4;
+ dataptr[DCTSIZE*7] = z11 - z4;
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
+
+#endif /* DCT_IFAST_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jfdctint.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jfdctint.c
new file mode 100644
index 0000000..38bb0c3
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jfdctint.c
@@ -0,0 +1,283 @@
+/*
+ * jfdctint.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains a slow-but-accurate integer implementation of the
+ * forward DCT (Discrete Cosine Transform).
+ *
+ * A 2-D DCT can be done by 1-D DCT on each row followed by 1-D DCT
+ * on each column. Direct algorithms are also available, but they are
+ * much more complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on an algorithm described in
+ * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
+ * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
+ * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
+ * The primary algorithm described there uses 11 multiplies and 29 adds.
+ * We use their alternate method with 12 multiplies and 32 adds.
+ * The advantage of this method is that no data path tqcontains more than one
+ * multiplication; this allows a very simple and accurate implementation in
+ * scaled fixed-point arithmetic, with a minimal number of shifts.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_ISLOW_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/*
+ * The poop on this scaling stuff is as follows:
+ *
+ * Each 1-D DCT step produces outputs which are a factor of sqrt(N)
+ * larger than the true DCT outputs. The final outputs are therefore
+ * a factor of N larger than desired; since N=8 this can be cured by
+ * a simple right shift at the end of the algorithm. The advantage of
+ * this arrangement is that we save two multiplications per 1-D DCT,
+ * because the y0 and y4 outputs need not be divided by sqrt(N).
+ * In the IJG code, this factor of 8 is removed by the quantization step
+ * (in jcdctmgr.c), NOT in this module.
+ *
+ * We have to do addition and subtraction of the integer inputs, which
+ * is no problem, and multiplication by fractional constants, which is
+ * a problem to do in integer arithmetic. We multiply all the constants
+ * by CONST_SCALE and convert them to integer constants (thus retaining
+ * CONST_BITS bits of precision in the constants). After doing a
+ * multiplication we have to divide the product by CONST_SCALE, with proper
+ * rounding, to produce the correct output. This division can be done
+ * cheaply as a right shift of CONST_BITS bits. We postpone shifting
+ * as long as possible so that partial sums can be added together with
+ * full fractional precision.
+ *
+ * The outputs of the first pass are scaled up by PASS1_BITS bits so that
+ * they are represented to better-than-integral precision. These outputs
+ * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
+ * with the recommended scaling. (For 12-bit sample data, the intermediate
+ * array is INT32 anyway.)
+ *
+ * To avoid overflow of the 32-bit intermediate results in pass 2, we must
+ * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
+ * shows that the values given below are the most effective.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS 13
+#define PASS1_BITS 2
+#else
+#define CONST_BITS 13
+#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 13
+#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
+#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
+#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
+#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
+#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
+#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
+#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
+#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
+#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
+#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
+#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
+#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
+#else
+#define FIX_0_298631336 FIX(0.298631336)
+#define FIX_0_390180644 FIX(0.390180644)
+#define FIX_0_541196100 FIX(0.541196100)
+#define FIX_0_765366865 FIX(0.765366865)
+#define FIX_0_899976223 FIX(0.899976223)
+#define FIX_1_175875602 FIX(1.175875602)
+#define FIX_1_501321110 FIX(1.501321110)
+#define FIX_1_847759065 FIX(1.847759065)
+#define FIX_1_961570560 FIX(1.961570560)
+#define FIX_2_053119869 FIX(2.053119869)
+#define FIX_2_562915447 FIX(2.562915447)
+#define FIX_3_072711026 FIX(3.072711026)
+#endif
+
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
+ * For 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
+#else
+#define MULTIPLY(var,const) ((var) * (const))
+#endif
+
+
+/*
+ * Perform the forward DCT on one block of samples.
+ */
+
+GLOBAL(void)
+jpeg_fdct_islow (DCTELEM * data)
+{
+ INT32 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ INT32 tmp10, tmp11, tmp12, tmp13;
+ INT32 z1, z2, z3, z4, z5;
+ DCTELEM *dataptr;
+ int ctr;
+ SHIFT_TEMPS
+
+ /* Pass 1: process rows. */
+ /* Note results are scaled up by sqrt(8) compared to a true DCT; */
+ /* furthermore, we scale the results by 2**PASS1_BITS. */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[0] + dataptr[7];
+ tmp7 = dataptr[0] - dataptr[7];
+ tmp1 = dataptr[1] + dataptr[6];
+ tmp6 = dataptr[1] - dataptr[6];
+ tmp2 = dataptr[2] + dataptr[5];
+ tmp5 = dataptr[2] - dataptr[5];
+ tmp3 = dataptr[3] + dataptr[4];
+ tmp4 = dataptr[3] - dataptr[4];
+
+ /* Even part per LL&M figure 1 --- note that published figure is faulty;
+ * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+ */
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[0] = (DCTELEM) ((tmp10 + tmp11) << PASS1_BITS);
+ dataptr[4] = (DCTELEM) ((tmp10 - tmp11) << PASS1_BITS);
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+ dataptr[2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+ CONST_BITS-PASS1_BITS);
+ dataptr[6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+ CONST_BITS-PASS1_BITS);
+
+ /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
+ * cK represents cos(K*pi/16).
+ * i0..i3 in the paper are tmp4..tmp7 here.
+ */
+
+ z1 = tmp4 + tmp7;
+ z2 = tmp5 + tmp6;
+ z3 = tmp4 + tmp6;
+ z4 = tmp5 + tmp7;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+
+ tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ dataptr[7] = (DCTELEM) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);
+ dataptr[5] = (DCTELEM) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);
+ dataptr[3] = (DCTELEM) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);
+ dataptr[1] = (DCTELEM) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);
+
+ dataptr += DCTSIZE; /* advance pointer to next row */
+ }
+
+ /* Pass 2: process columns.
+ * We remove the PASS1_BITS scaling, but leave the results scaled up
+ * by an overall factor of 8.
+ */
+
+ dataptr = data;
+ for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {
+ tmp0 = dataptr[DCTSIZE*0] + dataptr[DCTSIZE*7];
+ tmp7 = dataptr[DCTSIZE*0] - dataptr[DCTSIZE*7];
+ tmp1 = dataptr[DCTSIZE*1] + dataptr[DCTSIZE*6];
+ tmp6 = dataptr[DCTSIZE*1] - dataptr[DCTSIZE*6];
+ tmp2 = dataptr[DCTSIZE*2] + dataptr[DCTSIZE*5];
+ tmp5 = dataptr[DCTSIZE*2] - dataptr[DCTSIZE*5];
+ tmp3 = dataptr[DCTSIZE*3] + dataptr[DCTSIZE*4];
+ tmp4 = dataptr[DCTSIZE*3] - dataptr[DCTSIZE*4];
+
+ /* Even part per LL&M figure 1 --- note that published figure is faulty;
+ * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".
+ */
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ dataptr[DCTSIZE*0] = (DCTELEM) DESCALE(tmp10 + tmp11, PASS1_BITS);
+ dataptr[DCTSIZE*4] = (DCTELEM) DESCALE(tmp10 - tmp11, PASS1_BITS);
+
+ z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);
+ dataptr[DCTSIZE*2] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),
+ CONST_BITS+PASS1_BITS);
+ dataptr[DCTSIZE*6] = (DCTELEM) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),
+ CONST_BITS+PASS1_BITS);
+
+ /* Odd part per figure 8 --- note paper omits factor of sqrt(2).
+ * cK represents cos(K*pi/16).
+ * i0..i3 in the paper are tmp4..tmp7 here.
+ */
+
+ z1 = tmp4 + tmp7;
+ z2 = tmp5 + tmp6;
+ z3 = tmp4 + tmp6;
+ z4 = tmp5 + tmp7;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+
+ tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ dataptr[DCTSIZE*7] = (DCTELEM) DESCALE(tmp4 + z1 + z3,
+ CONST_BITS+PASS1_BITS);
+ dataptr[DCTSIZE*5] = (DCTELEM) DESCALE(tmp5 + z2 + z4,
+ CONST_BITS+PASS1_BITS);
+ dataptr[DCTSIZE*3] = (DCTELEM) DESCALE(tmp6 + z2 + z3,
+ CONST_BITS+PASS1_BITS);
+ dataptr[DCTSIZE*1] = (DCTELEM) DESCALE(tmp7 + z1 + z4,
+ CONST_BITS+PASS1_BITS);
+
+ dataptr++; /* advance pointer to next column */
+ }
+}
+
+#endif /* DCT_ISLOW_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jidctflt.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jidctflt.c
new file mode 100644
index 0000000..f308445
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jidctflt.c
@@ -0,0 +1,242 @@
+/*
+ * jidctflt.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains a floating-point implementation of the
+ * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
+ * must also perform dequantization of the input coefficients.
+ *
+ * This implementation should be more accurate than either of the integer
+ * IDCT implementations. However, it may not give the same results on all
+ * machines because of differences in roundoff behavior. Speed will depend
+ * on the hardware's floating point capacity.
+ *
+ * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
+ * on each row (or vice versa, but it's more convenient to emit a row at
+ * a time). Direct algorithms are also available, but they are much more
+ * complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README). The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs. These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries. The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with a fixed-point
+ * implementation, accuracy is lost due to imprecise representation of the
+ * scaled quantization values. However, that problem does not arise if
+ * we use floating point arithmetic.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_FLOAT_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce a float result.
+ */
+
+#define DETQUANTIZE(coef,quantval) (((FAST_FLOAT) (coef)) * (quantval))
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ */
+
+GLOBAL(void)
+jpeg_idct_float (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ FAST_FLOAT tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ FAST_FLOAT tmp10, tmp11, tmp12, tmp13;
+ FAST_FLOAT z5, z10, z11, z12, z13;
+ JCOEFPTR inptr;
+ FLOAT_MULT_TYPE * quantptr;
+ FAST_FLOAT * wsptr;
+ JSAMPROW outptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ int ctr;
+ FAST_FLOAT workspace[DCTSIZE2]; /* buffers data between passes */
+ SHIFT_TEMPS
+
+ /* Pass 1: process columns from input, store into work array. */
+
+ inptr = coef_block;
+ quantptr = (FLOAT_MULT_TYPE *) compptr->dct_table;
+ wsptr = workspace;
+ for (ctr = DCTSIZE; ctr > 0; ctr--) {
+ /* Due to quantization, we will usually tqfind that many of the input
+ * coefficients are zero, especially the AC terms. We can exploit this
+ * by short-circuiting the IDCT calculation for any column in which all
+ * the AC terms are zero. In that case each output is equal to the
+ * DC coefficient (with scale factor as needed).
+ * With typical images and quantization tables, half or more of the
+ * column DCT calculations can be simplified this way.
+ */
+
+ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+ inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+ inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+ inptr[DCTSIZE*7] == 0) {
+ /* AC terms all zero */
+ FAST_FLOAT dcval = DETQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+
+ wsptr[DCTSIZE*0] = dcval;
+ wsptr[DCTSIZE*1] = dcval;
+ wsptr[DCTSIZE*2] = dcval;
+ wsptr[DCTSIZE*3] = dcval;
+ wsptr[DCTSIZE*4] = dcval;
+ wsptr[DCTSIZE*5] = dcval;
+ wsptr[DCTSIZE*6] = dcval;
+ wsptr[DCTSIZE*7] = dcval;
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ continue;
+ }
+
+ /* Even part */
+
+ tmp0 = DETQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+ tmp1 = DETQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+ tmp2 = DETQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
+ tmp3 = DETQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+ tmp10 = tmp0 + tmp2; /* phase 3 */
+ tmp11 = tmp0 - tmp2;
+
+ tmp13 = tmp1 + tmp3; /* phases 5-3 */
+ tmp12 = (tmp1 - tmp3) * ((FAST_FLOAT) 1.414213562) - tmp13; /* 2*c4 */
+
+ tmp0 = tmp10 + tmp13; /* phase 2 */
+ tmp3 = tmp10 - tmp13;
+ tmp1 = tmp11 + tmp12;
+ tmp2 = tmp11 - tmp12;
+
+ /* Odd part */
+
+ tmp4 = DETQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+ tmp5 = DETQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+ tmp6 = DETQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+ tmp7 = DETQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+
+ z13 = tmp6 + tmp5; /* phase 6 */
+ z10 = tmp6 - tmp5;
+ z11 = tmp4 + tmp7;
+ z12 = tmp4 - tmp7;
+
+ tmp7 = z11 + z13; /* phase 5 */
+ tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562); /* 2*c4 */
+
+ z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
+ tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
+ tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
+
+ tmp6 = tmp12 - tmp7; /* phase 2 */
+ tmp5 = tmp11 - tmp6;
+ tmp4 = tmp10 + tmp5;
+
+ wsptr[DCTSIZE*0] = tmp0 + tmp7;
+ wsptr[DCTSIZE*7] = tmp0 - tmp7;
+ wsptr[DCTSIZE*1] = tmp1 + tmp6;
+ wsptr[DCTSIZE*6] = tmp1 - tmp6;
+ wsptr[DCTSIZE*2] = tmp2 + tmp5;
+ wsptr[DCTSIZE*5] = tmp2 - tmp5;
+ wsptr[DCTSIZE*4] = tmp3 + tmp4;
+ wsptr[DCTSIZE*3] = tmp3 - tmp4;
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ }
+
+ /* Pass 2: process rows from work array, store into output array. */
+ /* Note that we must descale the results by a factor of 8 == 2**3. */
+
+ wsptr = workspace;
+ for (ctr = 0; ctr < DCTSIZE; ctr++) {
+ outptr = output_buf[ctr] + output_col;
+ /* Rows of zeroes can be exploited in the same way as we did with columns.
+ * However, the column calculation has created many nonzero AC terms, so
+ * the simplification applies less often (typically 5% to 10% of the time).
+ * And testing floats for zero is relatively expensive, so we don't bother.
+ */
+
+ /* Even part */
+
+ tmp10 = wsptr[0] + wsptr[4];
+ tmp11 = wsptr[0] - wsptr[4];
+
+ tmp13 = wsptr[2] + wsptr[6];
+ tmp12 = (wsptr[2] - wsptr[6]) * ((FAST_FLOAT) 1.414213562) - tmp13;
+
+ tmp0 = tmp10 + tmp13;
+ tmp3 = tmp10 - tmp13;
+ tmp1 = tmp11 + tmp12;
+ tmp2 = tmp11 - tmp12;
+
+ /* Odd part */
+
+ z13 = wsptr[5] + wsptr[3];
+ z10 = wsptr[5] - wsptr[3];
+ z11 = wsptr[1] + wsptr[7];
+ z12 = wsptr[1] - wsptr[7];
+
+ tmp7 = z11 + z13;
+ tmp11 = (z11 - z13) * ((FAST_FLOAT) 1.414213562);
+
+ z5 = (z10 + z12) * ((FAST_FLOAT) 1.847759065); /* 2*c2 */
+ tmp10 = ((FAST_FLOAT) 1.082392200) * z12 - z5; /* 2*(c2-c6) */
+ tmp12 = ((FAST_FLOAT) -2.613125930) * z10 + z5; /* -2*(c2+c6) */
+
+ tmp6 = tmp12 - tmp7;
+ tmp5 = tmp11 - tmp6;
+ tmp4 = tmp10 + tmp5;
+
+ /* Final output stage: scale down by a factor of 8 and range-limit */
+
+ outptr[0] = range_limit[(int) DESCALE((INT32) (tmp0 + tmp7), 3)
+ & RANGE_MASK];
+ outptr[7] = range_limit[(int) DESCALE((INT32) (tmp0 - tmp7), 3)
+ & RANGE_MASK];
+ outptr[1] = range_limit[(int) DESCALE((INT32) (tmp1 + tmp6), 3)
+ & RANGE_MASK];
+ outptr[6] = range_limit[(int) DESCALE((INT32) (tmp1 - tmp6), 3)
+ & RANGE_MASK];
+ outptr[2] = range_limit[(int) DESCALE((INT32) (tmp2 + tmp5), 3)
+ & RANGE_MASK];
+ outptr[5] = range_limit[(int) DESCALE((INT32) (tmp2 - tmp5), 3)
+ & RANGE_MASK];
+ outptr[4] = range_limit[(int) DESCALE((INT32) (tmp3 + tmp4), 3)
+ & RANGE_MASK];
+ outptr[3] = range_limit[(int) DESCALE((INT32) (tmp3 - tmp4), 3)
+ & RANGE_MASK];
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+#endif /* DCT_FLOAT_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jidctfst.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jidctfst.c
new file mode 100644
index 0000000..730c8d4
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jidctfst.c
@@ -0,0 +1,368 @@
+/*
+ * jidctfst.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains a fast, not so accurate integer implementation of the
+ * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
+ * must also perform dequantization of the input coefficients.
+ *
+ * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
+ * on each row (or vice versa, but it's more convenient to emit a row at
+ * a time). Direct algorithms are also available, but they are much more
+ * complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on Arai, Agui, and Nakajima's algorithm for
+ * scaled DCT. Their original paper (Trans. IEICE E-71(11):1095) is in
+ * Japanese, but the algorithm is described in the Pennebaker & Mitchell
+ * JPEG textbook (see REFERENCES section in file README). The following code
+ * is based directly on figure 4-8 in P&M.
+ * While an 8-point DCT cannot be done in less than 11 multiplies, it is
+ * possible to arrange the computation so that many of the multiplies are
+ * simple scalings of the final outputs. These multiplies can then be
+ * folded into the multiplications or divisions by the JPEG quantization
+ * table entries. The AA&N method leaves only 5 multiplies and 29 adds
+ * to be done in the DCT itself.
+ * The primary disadvantage of this method is that with fixed-point math,
+ * accuracy is lost due to imprecise representation of the scaled
+ * quantization values. The smaller the quantization table entry, the less
+ * precise the scaled value, so this implementation does worse with high-
+ * quality-setting files than with low-quality ones.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_IFAST_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Scaling decisions are generally the same as in the LL&M algorithm;
+ * see jidctint.c for more details. However, we choose to descale
+ * (right shift) multiplication products as soon as they are formed,
+ * rather than carrying additional fractional bits into subsequent additions.
+ * This compromises accuracy slightly, but it lets us save a few shifts.
+ * More importantly, 16-bit arithmetic is then adequate (for 8-bit samples)
+ * everywhere except in the multiplications proper; this saves a good deal
+ * of work on 16-bit-int machines.
+ *
+ * The dequantized coefficients are not integers because the AA&N scaling
+ * factors have been incorporated. We represent them scaled up by PASS1_BITS,
+ * so that the first and second IDCT rounds have the same input scaling.
+ * For 8-bit JSAMPLEs, we choose IFAST_SCALE_BITS = PASS1_BITS so as to
+ * avoid a descaling shift; this compromises accuracy rather drastically
+ * for small quantization table entries, but it saves a lot of shifts.
+ * For 12-bit JSAMPLEs, there's no hope of using 16x16 multiplies anyway,
+ * so we use a much larger scaling factor to preserve accuracy.
+ *
+ * A final compromise is to represent the multiplicative constants to only
+ * 8 fractional bits, rather than 13. This saves some shifting work on some
+ * machines, and may also reduce the cost of multiplication (since there
+ * are fewer one-bits in the constants).
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS 8
+#define PASS1_BITS 2
+#else
+#define CONST_BITS 8
+#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 8
+#define FIX_1_082392200 ((INT32) 277) /* FIX(1.082392200) */
+#define FIX_1_414213562 ((INT32) 362) /* FIX(1.414213562) */
+#define FIX_1_847759065 ((INT32) 473) /* FIX(1.847759065) */
+#define FIX_2_613125930 ((INT32) 669) /* FIX(2.613125930) */
+#else
+#define FIX_1_082392200 FIX(1.082392200)
+#define FIX_1_414213562 FIX(1.414213562)
+#define FIX_1_847759065 FIX(1.847759065)
+#define FIX_2_613125930 FIX(2.613125930)
+#endif
+
+
+/* We can gain a little more speed, with a further compromise in accuracy,
+ * by omitting the addition in a descaling shift. This yields an incorrectly
+ * rounded result half the time...
+ */
+
+#ifndef USE_ACCURATE_ROUNDING
+#undef DESCALE
+#define DESCALE(x,n) RIGHT_SHIFT(x, n)
+#endif
+
+
+/* Multiply a DCTELEM variable by an INT32 constant, and immediately
+ * descale to yield a DCTELEM result.
+ */
+
+#define MULTIPLY(var,const) ((DCTELEM) DESCALE((var) * (const), CONST_BITS))
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce a DCTELEM result. For 8-bit data a 16x16->16
+ * multiplication will do. For 12-bit data, the multiplier table is
+ * declared INT32, so a 32-bit multiply will be used.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define DETQUANTIZE(coef,quantval) (((IFAST_MULT_TYPE) (coef)) * (quantval))
+#else
+#define DETQUANTIZE(coef,quantval) \
+ DESCALE((coef)*(quantval), IFAST_SCALE_BITS-PASS1_BITS)
+#endif
+
+
+/* Like DESCALE, but applies to a DCTELEM and produces an int.
+ * We assume that int right shift is unsigned if INT32 right shift is.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define ISHIFT_TEMPS DCTELEM ishift_temp;
+#if BITS_IN_JSAMPLE == 8
+#define DCTELEMBITS 16 /* DCTELEM may be 16 or 32 bits */
+#else
+#define DCTELEMBITS 32 /* DCTELEM must be 32 bits */
+#endif
+#define IRIGHT_SHIFT(x,shft) \
+ ((ishift_temp = (x)) < 0 ? \
+ (ishift_temp >> (shft)) | ((~((DCTELEM) 0)) << (DCTELEMBITS-(shft))) : \
+ (ishift_temp >> (shft)))
+#else
+#define ISHIFT_TEMPS
+#define IRIGHT_SHIFT(x,shft) ((x) >> (shft))
+#endif
+
+#ifdef USE_ACCURATE_ROUNDING
+#define IDESCALE(x,n) ((int) IRIGHT_SHIFT((x) + (1 << ((n)-1)), n))
+#else
+#define IDESCALE(x,n) ((int) IRIGHT_SHIFT(x, n))
+#endif
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ */
+
+GLOBAL(void)
+jpeg_idct_ifast (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ DCTELEM tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ DCTELEM tmp10, tmp11, tmp12, tmp13;
+ DCTELEM z5, z10, z11, z12, z13;
+ JCOEFPTR inptr;
+ IFAST_MULT_TYPE * quantptr;
+ int * wsptr;
+ JSAMPROW outptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ int ctr;
+ int workspace[DCTSIZE2]; /* buffers data between passes */
+ SHIFT_TEMPS /* for DESCALE */
+ ISHIFT_TEMPS /* for IDESCALE */
+
+ /* Pass 1: process columns from input, store into work array. */
+
+ inptr = coef_block;
+ quantptr = (IFAST_MULT_TYPE *) compptr->dct_table;
+ wsptr = workspace;
+ for (ctr = DCTSIZE; ctr > 0; ctr--) {
+ /* Due to quantization, we will usually tqfind that many of the input
+ * coefficients are zero, especially the AC terms. We can exploit this
+ * by short-circuiting the IDCT calculation for any column in which all
+ * the AC terms are zero. In that case each output is equal to the
+ * DC coefficient (with scale factor as needed).
+ * With typical images and quantization tables, half or more of the
+ * column DCT calculations can be simplified this way.
+ */
+
+ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+ inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+ inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+ inptr[DCTSIZE*7] == 0) {
+ /* AC terms all zero */
+ int dcval = (int) DETQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+
+ wsptr[DCTSIZE*0] = dcval;
+ wsptr[DCTSIZE*1] = dcval;
+ wsptr[DCTSIZE*2] = dcval;
+ wsptr[DCTSIZE*3] = dcval;
+ wsptr[DCTSIZE*4] = dcval;
+ wsptr[DCTSIZE*5] = dcval;
+ wsptr[DCTSIZE*6] = dcval;
+ wsptr[DCTSIZE*7] = dcval;
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ continue;
+ }
+
+ /* Even part */
+
+ tmp0 = DETQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+ tmp1 = DETQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+ tmp2 = DETQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
+ tmp3 = DETQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+ tmp10 = tmp0 + tmp2; /* phase 3 */
+ tmp11 = tmp0 - tmp2;
+
+ tmp13 = tmp1 + tmp3; /* phases 5-3 */
+ tmp12 = MULTIPLY(tmp1 - tmp3, FIX_1_414213562) - tmp13; /* 2*c4 */
+
+ tmp0 = tmp10 + tmp13; /* phase 2 */
+ tmp3 = tmp10 - tmp13;
+ tmp1 = tmp11 + tmp12;
+ tmp2 = tmp11 - tmp12;
+
+ /* Odd part */
+
+ tmp4 = DETQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+ tmp5 = DETQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+ tmp6 = DETQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+ tmp7 = DETQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+
+ z13 = tmp6 + tmp5; /* phase 6 */
+ z10 = tmp6 - tmp5;
+ z11 = tmp4 + tmp7;
+ z12 = tmp4 - tmp7;
+
+ tmp7 = z11 + z13; /* phase 5 */
+ tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
+
+ z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
+ tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
+ tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
+
+ tmp6 = tmp12 - tmp7; /* phase 2 */
+ tmp5 = tmp11 - tmp6;
+ tmp4 = tmp10 + tmp5;
+
+ wsptr[DCTSIZE*0] = (int) (tmp0 + tmp7);
+ wsptr[DCTSIZE*7] = (int) (tmp0 - tmp7);
+ wsptr[DCTSIZE*1] = (int) (tmp1 + tmp6);
+ wsptr[DCTSIZE*6] = (int) (tmp1 - tmp6);
+ wsptr[DCTSIZE*2] = (int) (tmp2 + tmp5);
+ wsptr[DCTSIZE*5] = (int) (tmp2 - tmp5);
+ wsptr[DCTSIZE*4] = (int) (tmp3 + tmp4);
+ wsptr[DCTSIZE*3] = (int) (tmp3 - tmp4);
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ }
+
+ /* Pass 2: process rows from work array, store into output array. */
+ /* Note that we must descale the results by a factor of 8 == 2**3, */
+ /* and also undo the PASS1_BITS scaling. */
+
+ wsptr = workspace;
+ for (ctr = 0; ctr < DCTSIZE; ctr++) {
+ outptr = output_buf[ctr] + output_col;
+ /* Rows of zeroes can be exploited in the same way as we did with columns.
+ * However, the column calculation has created many nonzero AC terms, so
+ * the simplification applies less often (typically 5% to 10% of the time).
+ * On machines with very fast multiplication, it's possible that the
+ * test takes more time than it's worth. In that case this section
+ * may be commented out.
+ */
+
+#ifndef NO_ZERO_ROW_TEST
+ if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
+ wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
+ /* AC terms all zero */
+ JSAMPLE dcval = range_limit[IDESCALE(wsptr[0], PASS1_BITS+3)
+ & RANGE_MASK];
+
+ outptr[0] = dcval;
+ outptr[1] = dcval;
+ outptr[2] = dcval;
+ outptr[3] = dcval;
+ outptr[4] = dcval;
+ outptr[5] = dcval;
+ outptr[6] = dcval;
+ outptr[7] = dcval;
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ continue;
+ }
+#endif
+
+ /* Even part */
+
+ tmp10 = ((DCTELEM) wsptr[0] + (DCTELEM) wsptr[4]);
+ tmp11 = ((DCTELEM) wsptr[0] - (DCTELEM) wsptr[4]);
+
+ tmp13 = ((DCTELEM) wsptr[2] + (DCTELEM) wsptr[6]);
+ tmp12 = MULTIPLY((DCTELEM) wsptr[2] - (DCTELEM) wsptr[6], FIX_1_414213562)
+ - tmp13;
+
+ tmp0 = tmp10 + tmp13;
+ tmp3 = tmp10 - tmp13;
+ tmp1 = tmp11 + tmp12;
+ tmp2 = tmp11 - tmp12;
+
+ /* Odd part */
+
+ z13 = (DCTELEM) wsptr[5] + (DCTELEM) wsptr[3];
+ z10 = (DCTELEM) wsptr[5] - (DCTELEM) wsptr[3];
+ z11 = (DCTELEM) wsptr[1] + (DCTELEM) wsptr[7];
+ z12 = (DCTELEM) wsptr[1] - (DCTELEM) wsptr[7];
+
+ tmp7 = z11 + z13; /* phase 5 */
+ tmp11 = MULTIPLY(z11 - z13, FIX_1_414213562); /* 2*c4 */
+
+ z5 = MULTIPLY(z10 + z12, FIX_1_847759065); /* 2*c2 */
+ tmp10 = MULTIPLY(z12, FIX_1_082392200) - z5; /* 2*(c2-c6) */
+ tmp12 = MULTIPLY(z10, - FIX_2_613125930) + z5; /* -2*(c2+c6) */
+
+ tmp6 = tmp12 - tmp7; /* phase 2 */
+ tmp5 = tmp11 - tmp6;
+ tmp4 = tmp10 + tmp5;
+
+ /* Final output stage: scale down by a factor of 8 and range-limit */
+
+ outptr[0] = range_limit[IDESCALE(tmp0 + tmp7, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[7] = range_limit[IDESCALE(tmp0 - tmp7, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[1] = range_limit[IDESCALE(tmp1 + tmp6, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[6] = range_limit[IDESCALE(tmp1 - tmp6, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[2] = range_limit[IDESCALE(tmp2 + tmp5, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[5] = range_limit[IDESCALE(tmp2 - tmp5, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[4] = range_limit[IDESCALE(tmp3 + tmp4, PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[3] = range_limit[IDESCALE(tmp3 - tmp4, PASS1_BITS+3)
+ & RANGE_MASK];
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+#endif /* DCT_IFAST_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jidctint.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jidctint.c
new file mode 100644
index 0000000..35302e0
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jidctint.c
@@ -0,0 +1,389 @@
+/*
+ * jidctint.c
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains a slow-but-accurate integer implementation of the
+ * inverse DCT (Discrete Cosine Transform). In the IJG code, this routine
+ * must also perform dequantization of the input coefficients.
+ *
+ * A 2-D IDCT can be done by 1-D IDCT on each column followed by 1-D IDCT
+ * on each row (or vice versa, but it's more convenient to emit a row at
+ * a time). Direct algorithms are also available, but they are much more
+ * complex and seem not to be any faster when reduced to code.
+ *
+ * This implementation is based on an algorithm described in
+ * C. Loeffler, A. Ligtenberg and G. Moschytz, "Practical Fast 1-D DCT
+ * Algorithms with 11 Multiplications", Proc. Int'l. Conf. on Acoustics,
+ * Speech, and Signal Processing 1989 (ICASSP '89), pp. 988-991.
+ * The primary algorithm described there uses 11 multiplies and 29 adds.
+ * We use their alternate method with 12 multiplies and 32 adds.
+ * The advantage of this method is that no data path tqcontains more than one
+ * multiplication; this allows a very simple and accurate implementation in
+ * scaled fixed-point arithmetic, with a minimal number of shifts.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef DCT_ISLOW_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/*
+ * The poop on this scaling stuff is as follows:
+ *
+ * Each 1-D IDCT step produces outputs which are a factor of sqrt(N)
+ * larger than the true IDCT outputs. The final outputs are therefore
+ * a factor of N larger than desired; since N=8 this can be cured by
+ * a simple right shift at the end of the algorithm. The advantage of
+ * this arrangement is that we save two multiplications per 1-D IDCT,
+ * because the y0 and y4 inputs need not be divided by sqrt(N).
+ *
+ * We have to do addition and subtraction of the integer inputs, which
+ * is no problem, and multiplication by fractional constants, which is
+ * a problem to do in integer arithmetic. We multiply all the constants
+ * by CONST_SCALE and convert them to integer constants (thus retaining
+ * CONST_BITS bits of precision in the constants). After doing a
+ * multiplication we have to divide the product by CONST_SCALE, with proper
+ * rounding, to produce the correct output. This division can be done
+ * cheaply as a right shift of CONST_BITS bits. We postpone shifting
+ * as long as possible so that partial sums can be added together with
+ * full fractional precision.
+ *
+ * The outputs of the first pass are scaled up by PASS1_BITS bits so that
+ * they are represented to better-than-integral precision. These outputs
+ * require BITS_IN_JSAMPLE + PASS1_BITS + 3 bits; this fits in a 16-bit word
+ * with the recommended scaling. (To scale up 12-bit sample data further, an
+ * intermediate INT32 array would be needed.)
+ *
+ * To avoid overflow of the 32-bit intermediate results in pass 2, we must
+ * have BITS_IN_JSAMPLE + CONST_BITS + PASS1_BITS <= 26. Error analysis
+ * shows that the values given below are the most effective.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS 13
+#define PASS1_BITS 2
+#else
+#define CONST_BITS 13
+#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 13
+#define FIX_0_298631336 ((INT32) 2446) /* FIX(0.298631336) */
+#define FIX_0_390180644 ((INT32) 3196) /* FIX(0.390180644) */
+#define FIX_0_541196100 ((INT32) 4433) /* FIX(0.541196100) */
+#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
+#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
+#define FIX_1_175875602 ((INT32) 9633) /* FIX(1.175875602) */
+#define FIX_1_501321110 ((INT32) 12299) /* FIX(1.501321110) */
+#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
+#define FIX_1_961570560 ((INT32) 16069) /* FIX(1.961570560) */
+#define FIX_2_053119869 ((INT32) 16819) /* FIX(2.053119869) */
+#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
+#define FIX_3_072711026 ((INT32) 25172) /* FIX(3.072711026) */
+#else
+#define FIX_0_298631336 FIX(0.298631336)
+#define FIX_0_390180644 FIX(0.390180644)
+#define FIX_0_541196100 FIX(0.541196100)
+#define FIX_0_765366865 FIX(0.765366865)
+#define FIX_0_899976223 FIX(0.899976223)
+#define FIX_1_175875602 FIX(1.175875602)
+#define FIX_1_501321110 FIX(1.501321110)
+#define FIX_1_847759065 FIX(1.847759065)
+#define FIX_1_961570560 FIX(1.961570560)
+#define FIX_2_053119869 FIX(2.053119869)
+#define FIX_2_562915447 FIX(2.562915447)
+#define FIX_3_072711026 FIX(3.072711026)
+#endif
+
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
+ * For 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
+#else
+#define MULTIPLY(var,const) ((var) * (const))
+#endif
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce an int result. In this module, both inputs and result
+ * are 16 bits or less, so either int or short multiply will work.
+ */
+
+#define DETQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients.
+ */
+
+GLOBAL(void)
+jpeg_idct_islow (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ INT32 tmp0, tmp1, tmp2, tmp3;
+ INT32 tmp10, tmp11, tmp12, tmp13;
+ INT32 z1, z2, z3, z4, z5;
+ JCOEFPTR inptr;
+ ISLOW_MULT_TYPE * quantptr;
+ int * wsptr;
+ JSAMPROW outptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ int ctr;
+ int workspace[DCTSIZE2]; /* buffers data between passes */
+ SHIFT_TEMPS
+
+ /* Pass 1: process columns from input, store into work array. */
+ /* Note results are scaled up by sqrt(8) compared to a true IDCT; */
+ /* furthermore, we scale the results by 2**PASS1_BITS. */
+
+ inptr = coef_block;
+ quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+ wsptr = workspace;
+ for (ctr = DCTSIZE; ctr > 0; ctr--) {
+ /* Due to quantization, we will usually tqfind that many of the input
+ * coefficients are zero, especially the AC terms. We can exploit this
+ * by short-circuiting the IDCT calculation for any column in which all
+ * the AC terms are zero. In that case each output is equal to the
+ * DC coefficient (with scale factor as needed).
+ * With typical images and quantization tables, half or more of the
+ * column DCT calculations can be simplified this way.
+ */
+
+ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+ inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*4] == 0 &&
+ inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*6] == 0 &&
+ inptr[DCTSIZE*7] == 0) {
+ /* AC terms all zero */
+ int dcval = DETQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
+
+ wsptr[DCTSIZE*0] = dcval;
+ wsptr[DCTSIZE*1] = dcval;
+ wsptr[DCTSIZE*2] = dcval;
+ wsptr[DCTSIZE*3] = dcval;
+ wsptr[DCTSIZE*4] = dcval;
+ wsptr[DCTSIZE*5] = dcval;
+ wsptr[DCTSIZE*6] = dcval;
+ wsptr[DCTSIZE*7] = dcval;
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ continue;
+ }
+
+ /* Even part: reverse the even part of the forward DCT. */
+ /* The rotator is sqrt(2)*c(-6). */
+
+ z2 = DETQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+ z3 = DETQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+ z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
+
+ z2 = DETQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+ z3 = DETQUANTIZE(inptr[DCTSIZE*4], quantptr[DCTSIZE*4]);
+
+ tmp0 = (z2 + z3) << CONST_BITS;
+ tmp1 = (z2 - z3) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ /* Odd part per figure 8; the matrix is unitary and hence its
+ * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
+ */
+
+ tmp0 = DETQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+ tmp1 = DETQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+ tmp2 = DETQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+ tmp3 = DETQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+
+ z1 = tmp0 + tmp3;
+ z2 = tmp1 + tmp2;
+ z3 = tmp0 + tmp2;
+ z4 = tmp1 + tmp3;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+
+ tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+
+ /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+
+ wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp3, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*7] = (int) DESCALE(tmp10 - tmp3, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*1] = (int) DESCALE(tmp11 + tmp2, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*6] = (int) DESCALE(tmp11 - tmp2, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 + tmp1, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*5] = (int) DESCALE(tmp12 - tmp1, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*3] = (int) DESCALE(tmp13 + tmp0, CONST_BITS-PASS1_BITS);
+ wsptr[DCTSIZE*4] = (int) DESCALE(tmp13 - tmp0, CONST_BITS-PASS1_BITS);
+
+ inptr++; /* advance pointers to next column */
+ quantptr++;
+ wsptr++;
+ }
+
+ /* Pass 2: process rows from work array, store into output array. */
+ /* Note that we must descale the results by a factor of 8 == 2**3, */
+ /* and also undo the PASS1_BITS scaling. */
+
+ wsptr = workspace;
+ for (ctr = 0; ctr < DCTSIZE; ctr++) {
+ outptr = output_buf[ctr] + output_col;
+ /* Rows of zeroes can be exploited in the same way as we did with columns.
+ * However, the column calculation has created many nonzero AC terms, so
+ * the simplification applies less often (typically 5% to 10% of the time).
+ * On machines with very fast multiplication, it's possible that the
+ * test takes more time than it's worth. In that case this section
+ * may be commented out.
+ */
+
+#ifndef NO_ZERO_ROW_TEST
+ if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 && wsptr[4] == 0 &&
+ wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
+ /* AC terms all zero */
+ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
+ & RANGE_MASK];
+
+ outptr[0] = dcval;
+ outptr[1] = dcval;
+ outptr[2] = dcval;
+ outptr[3] = dcval;
+ outptr[4] = dcval;
+ outptr[5] = dcval;
+ outptr[6] = dcval;
+ outptr[7] = dcval;
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ continue;
+ }
+#endif
+
+ /* Even part: reverse the even part of the forward DCT. */
+ /* The rotator is sqrt(2)*c(-6). */
+
+ z2 = (INT32) wsptr[2];
+ z3 = (INT32) wsptr[6];
+
+ z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
+ tmp2 = z1 + MULTIPLY(z3, - FIX_1_847759065);
+ tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
+
+ tmp0 = ((INT32) wsptr[0] + (INT32) wsptr[4]) << CONST_BITS;
+ tmp1 = ((INT32) wsptr[0] - (INT32) wsptr[4]) << CONST_BITS;
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ /* Odd part per figure 8; the matrix is unitary and hence its
+ * transpose is its inverse. i0..i3 are y7,y5,y3,y1 respectively.
+ */
+
+ tmp0 = (INT32) wsptr[7];
+ tmp1 = (INT32) wsptr[5];
+ tmp2 = (INT32) wsptr[3];
+ tmp3 = (INT32) wsptr[1];
+
+ z1 = tmp0 + tmp3;
+ z2 = tmp1 + tmp2;
+ z3 = tmp0 + tmp2;
+ z4 = tmp1 + tmp3;
+ z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */
+
+ tmp0 = MULTIPLY(tmp0, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */
+ tmp1 = MULTIPLY(tmp1, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */
+ tmp2 = MULTIPLY(tmp2, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */
+ tmp3 = MULTIPLY(tmp3, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */
+ z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */
+ z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */
+ z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */
+ z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */
+
+ z3 += z5;
+ z4 += z5;
+
+ tmp0 += z1 + z3;
+ tmp1 += z2 + z4;
+ tmp2 += z2 + z3;
+ tmp3 += z1 + z4;
+
+ /* Final output stage: inputs are tmp10..tmp13, tmp0..tmp3 */
+
+ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp3,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[7] = range_limit[(int) DESCALE(tmp10 - tmp3,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[1] = range_limit[(int) DESCALE(tmp11 + tmp2,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[6] = range_limit[(int) DESCALE(tmp11 - tmp2,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[2] = range_limit[(int) DESCALE(tmp12 + tmp1,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[5] = range_limit[(int) DESCALE(tmp12 - tmp1,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[3] = range_limit[(int) DESCALE(tmp13 + tmp0,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+ outptr[4] = range_limit[(int) DESCALE(tmp13 - tmp0,
+ CONST_BITS+PASS1_BITS+3)
+ & RANGE_MASK];
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+#endif /* DCT_ISLOW_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jidctred.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jidctred.c
new file mode 100644
index 0000000..6461bb3
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jidctred.c
@@ -0,0 +1,398 @@
+/*
+ * jidctred.c
+ *
+ * Copyright (C) 1994-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains inverse-DCT routines that produce reduced-size output:
+ * either 4x4, 2x2, or 1x1 pixels from an 8x8 DCT block.
+ *
+ * The implementation is based on the Loeffler, Ligtenberg and Moschytz (LL&M)
+ * algorithm used in jidctint.c. We simply tqreplace each 8-to-8 1-D IDCT step
+ * with an 8-to-4 step that produces the four averages of two adjacent outputs
+ * (or an 8-to-2 step producing two averages of four outputs, for 2x2 output).
+ * These steps were derived by computing the corresponding values at the end
+ * of the normal LL&M code, then simplifying as much as possible.
+ *
+ * 1x1 is trivial: just take the DC coefficient divided by 8.
+ *
+ * See jidctint.c for additional comments.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jdct.h" /* Private declarations for DCT subsystem */
+
+#ifdef IDCT_SCALING_SUPPORTED
+
+
+/*
+ * This module is specialized to the case DCTSIZE = 8.
+ */
+
+#if DCTSIZE != 8
+ Sorry, this code only copes with 8x8 DCTs. /* deliberate syntax err */
+#endif
+
+
+/* Scaling is the same as in jidctint.c. */
+
+#if BITS_IN_JSAMPLE == 8
+#define CONST_BITS 13
+#define PASS1_BITS 2
+#else
+#define CONST_BITS 13
+#define PASS1_BITS 1 /* lose a little precision to avoid overflow */
+#endif
+
+/* Some C compilers fail to reduce "FIX(constant)" at compile time, thus
+ * causing a lot of useless floating-point operations at run time.
+ * To get around this we use the following pre-calculated constants.
+ * If you change CONST_BITS you may want to add appropriate values.
+ * (With a reasonable C compiler, you can just rely on the FIX() macro...)
+ */
+
+#if CONST_BITS == 13
+#define FIX_0_211164243 ((INT32) 1730) /* FIX(0.211164243) */
+#define FIX_0_509795579 ((INT32) 4176) /* FIX(0.509795579) */
+#define FIX_0_601344887 ((INT32) 4926) /* FIX(0.601344887) */
+#define FIX_0_720959822 ((INT32) 5906) /* FIX(0.720959822) */
+#define FIX_0_765366865 ((INT32) 6270) /* FIX(0.765366865) */
+#define FIX_0_850430095 ((INT32) 6967) /* FIX(0.850430095) */
+#define FIX_0_899976223 ((INT32) 7373) /* FIX(0.899976223) */
+#define FIX_1_061594337 ((INT32) 8697) /* FIX(1.061594337) */
+#define FIX_1_272758580 ((INT32) 10426) /* FIX(1.272758580) */
+#define FIX_1_451774981 ((INT32) 11893) /* FIX(1.451774981) */
+#define FIX_1_847759065 ((INT32) 15137) /* FIX(1.847759065) */
+#define FIX_2_172734803 ((INT32) 17799) /* FIX(2.172734803) */
+#define FIX_2_562915447 ((INT32) 20995) /* FIX(2.562915447) */
+#define FIX_3_624509785 ((INT32) 29692) /* FIX(3.624509785) */
+#else
+#define FIX_0_211164243 FIX(0.211164243)
+#define FIX_0_509795579 FIX(0.509795579)
+#define FIX_0_601344887 FIX(0.601344887)
+#define FIX_0_720959822 FIX(0.720959822)
+#define FIX_0_765366865 FIX(0.765366865)
+#define FIX_0_850430095 FIX(0.850430095)
+#define FIX_0_899976223 FIX(0.899976223)
+#define FIX_1_061594337 FIX(1.061594337)
+#define FIX_1_272758580 FIX(1.272758580)
+#define FIX_1_451774981 FIX(1.451774981)
+#define FIX_1_847759065 FIX(1.847759065)
+#define FIX_2_172734803 FIX(2.172734803)
+#define FIX_2_562915447 FIX(2.562915447)
+#define FIX_3_624509785 FIX(3.624509785)
+#endif
+
+
+/* Multiply an INT32 variable by an INT32 constant to yield an INT32 result.
+ * For 8-bit samples with the recommended scaling, all the variable
+ * and constant values involved are no more than 16 bits wide, so a
+ * 16x16->32 bit multiply can be used instead of a full 32x32 multiply.
+ * For 12-bit samples, a full 32-bit multiplication will be needed.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+#define MULTIPLY(var,const) MULTIPLY16C16(var,const)
+#else
+#define MULTIPLY(var,const) ((var) * (const))
+#endif
+
+
+/* Dequantize a coefficient by multiplying it by the multiplier-table
+ * entry; produce an int result. In this module, both inputs and result
+ * are 16 bits or less, so either int or short multiply will work.
+ */
+
+#define DETQUANTIZE(coef,quantval) (((ISLOW_MULT_TYPE) (coef)) * (quantval))
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients,
+ * producing a reduced-size 4x4 output block.
+ */
+
+GLOBAL(void)
+jpeg_idct_4x4 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ INT32 tmp0, tmp2, tmp10, tmp12;
+ INT32 z1, z2, z3, z4;
+ JCOEFPTR inptr;
+ ISLOW_MULT_TYPE * quantptr;
+ int * wsptr;
+ JSAMPROW outptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ int ctr;
+ int workspace[DCTSIZE*4]; /* buffers data between passes */
+ SHIFT_TEMPS
+
+ /* Pass 1: process columns from input, store into work array. */
+
+ inptr = coef_block;
+ quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+ wsptr = workspace;
+ for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
+ /* Don't bother to process column 4, because second pass won't use it */
+ if (ctr == DCTSIZE-4)
+ continue;
+ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*2] == 0 &&
+ inptr[DCTSIZE*3] == 0 && inptr[DCTSIZE*5] == 0 &&
+ inptr[DCTSIZE*6] == 0 && inptr[DCTSIZE*7] == 0) {
+ /* AC terms all zero; we need not examine term 4 for 4x4 output */
+ int dcval = DETQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
+
+ wsptr[DCTSIZE*0] = dcval;
+ wsptr[DCTSIZE*1] = dcval;
+ wsptr[DCTSIZE*2] = dcval;
+ wsptr[DCTSIZE*3] = dcval;
+
+ continue;
+ }
+
+ /* Even part */
+
+ tmp0 = DETQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+ tmp0 <<= (CONST_BITS+1);
+
+ z2 = DETQUANTIZE(inptr[DCTSIZE*2], quantptr[DCTSIZE*2]);
+ z3 = DETQUANTIZE(inptr[DCTSIZE*6], quantptr[DCTSIZE*6]);
+
+ tmp2 = MULTIPLY(z2, FIX_1_847759065) + MULTIPLY(z3, - FIX_0_765366865);
+
+ tmp10 = tmp0 + tmp2;
+ tmp12 = tmp0 - tmp2;
+
+ /* Odd part */
+
+ z1 = DETQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+ z2 = DETQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+ z3 = DETQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+ z4 = DETQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+
+ tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
+ + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
+ + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
+ + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
+
+ tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
+ + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
+ + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
+ + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
+
+ /* Final output stage */
+
+ wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp2, CONST_BITS-PASS1_BITS+1);
+ wsptr[DCTSIZE*3] = (int) DESCALE(tmp10 - tmp2, CONST_BITS-PASS1_BITS+1);
+ wsptr[DCTSIZE*1] = (int) DESCALE(tmp12 + tmp0, CONST_BITS-PASS1_BITS+1);
+ wsptr[DCTSIZE*2] = (int) DESCALE(tmp12 - tmp0, CONST_BITS-PASS1_BITS+1);
+ }
+
+ /* Pass 2: process 4 rows from work array, store into output array. */
+
+ wsptr = workspace;
+ for (ctr = 0; ctr < 4; ctr++) {
+ outptr = output_buf[ctr] + output_col;
+ /* It's not clear whether a zero row test is worthwhile here ... */
+
+#ifndef NO_ZERO_ROW_TEST
+ if (wsptr[1] == 0 && wsptr[2] == 0 && wsptr[3] == 0 &&
+ wsptr[5] == 0 && wsptr[6] == 0 && wsptr[7] == 0) {
+ /* AC terms all zero */
+ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
+ & RANGE_MASK];
+
+ outptr[0] = dcval;
+ outptr[1] = dcval;
+ outptr[2] = dcval;
+ outptr[3] = dcval;
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ continue;
+ }
+#endif
+
+ /* Even part */
+
+ tmp0 = ((INT32) wsptr[0]) << (CONST_BITS+1);
+
+ tmp2 = MULTIPLY((INT32) wsptr[2], FIX_1_847759065)
+ + MULTIPLY((INT32) wsptr[6], - FIX_0_765366865);
+
+ tmp10 = tmp0 + tmp2;
+ tmp12 = tmp0 - tmp2;
+
+ /* Odd part */
+
+ z1 = (INT32) wsptr[7];
+ z2 = (INT32) wsptr[5];
+ z3 = (INT32) wsptr[3];
+ z4 = (INT32) wsptr[1];
+
+ tmp0 = MULTIPLY(z1, - FIX_0_211164243) /* sqrt(2) * (c3-c1) */
+ + MULTIPLY(z2, FIX_1_451774981) /* sqrt(2) * (c3+c7) */
+ + MULTIPLY(z3, - FIX_2_172734803) /* sqrt(2) * (-c1-c5) */
+ + MULTIPLY(z4, FIX_1_061594337); /* sqrt(2) * (c5+c7) */
+
+ tmp2 = MULTIPLY(z1, - FIX_0_509795579) /* sqrt(2) * (c7-c5) */
+ + MULTIPLY(z2, - FIX_0_601344887) /* sqrt(2) * (c5-c1) */
+ + MULTIPLY(z3, FIX_0_899976223) /* sqrt(2) * (c3-c7) */
+ + MULTIPLY(z4, FIX_2_562915447); /* sqrt(2) * (c1+c3) */
+
+ /* Final output stage */
+
+ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp2,
+ CONST_BITS+PASS1_BITS+3+1)
+ & RANGE_MASK];
+ outptr[3] = range_limit[(int) DESCALE(tmp10 - tmp2,
+ CONST_BITS+PASS1_BITS+3+1)
+ & RANGE_MASK];
+ outptr[1] = range_limit[(int) DESCALE(tmp12 + tmp0,
+ CONST_BITS+PASS1_BITS+3+1)
+ & RANGE_MASK];
+ outptr[2] = range_limit[(int) DESCALE(tmp12 - tmp0,
+ CONST_BITS+PASS1_BITS+3+1)
+ & RANGE_MASK];
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients,
+ * producing a reduced-size 2x2 output block.
+ */
+
+GLOBAL(void)
+jpeg_idct_2x2 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ INT32 tmp0, tmp10, z1;
+ JCOEFPTR inptr;
+ ISLOW_MULT_TYPE * quantptr;
+ int * wsptr;
+ JSAMPROW outptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ int ctr;
+ int workspace[DCTSIZE*2]; /* buffers data between passes */
+ SHIFT_TEMPS
+
+ /* Pass 1: process columns from input, store into work array. */
+
+ inptr = coef_block;
+ quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+ wsptr = workspace;
+ for (ctr = DCTSIZE; ctr > 0; inptr++, quantptr++, wsptr++, ctr--) {
+ /* Don't bother to process columns 2,4,6 */
+ if (ctr == DCTSIZE-2 || ctr == DCTSIZE-4 || ctr == DCTSIZE-6)
+ continue;
+ if (inptr[DCTSIZE*1] == 0 && inptr[DCTSIZE*3] == 0 &&
+ inptr[DCTSIZE*5] == 0 && inptr[DCTSIZE*7] == 0) {
+ /* AC terms all zero; we need not examine terms 2,4,6 for 2x2 output */
+ int dcval = DETQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]) << PASS1_BITS;
+
+ wsptr[DCTSIZE*0] = dcval;
+ wsptr[DCTSIZE*1] = dcval;
+
+ continue;
+ }
+
+ /* Even part */
+
+ z1 = DETQUANTIZE(inptr[DCTSIZE*0], quantptr[DCTSIZE*0]);
+ tmp10 = z1 << (CONST_BITS+2);
+
+ /* Odd part */
+
+ z1 = DETQUANTIZE(inptr[DCTSIZE*7], quantptr[DCTSIZE*7]);
+ tmp0 = MULTIPLY(z1, - FIX_0_720959822); /* sqrt(2) * (c7-c5+c3-c1) */
+ z1 = DETQUANTIZE(inptr[DCTSIZE*5], quantptr[DCTSIZE*5]);
+ tmp0 += MULTIPLY(z1, FIX_0_850430095); /* sqrt(2) * (-c1+c3+c5+c7) */
+ z1 = DETQUANTIZE(inptr[DCTSIZE*3], quantptr[DCTSIZE*3]);
+ tmp0 += MULTIPLY(z1, - FIX_1_272758580); /* sqrt(2) * (-c1+c3-c5-c7) */
+ z1 = DETQUANTIZE(inptr[DCTSIZE*1], quantptr[DCTSIZE*1]);
+ tmp0 += MULTIPLY(z1, FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
+
+ /* Final output stage */
+
+ wsptr[DCTSIZE*0] = (int) DESCALE(tmp10 + tmp0, CONST_BITS-PASS1_BITS+2);
+ wsptr[DCTSIZE*1] = (int) DESCALE(tmp10 - tmp0, CONST_BITS-PASS1_BITS+2);
+ }
+
+ /* Pass 2: process 2 rows from work array, store into output array. */
+
+ wsptr = workspace;
+ for (ctr = 0; ctr < 2; ctr++) {
+ outptr = output_buf[ctr] + output_col;
+ /* It's not clear whether a zero row test is worthwhile here ... */
+
+#ifndef NO_ZERO_ROW_TEST
+ if (wsptr[1] == 0 && wsptr[3] == 0 && wsptr[5] == 0 && wsptr[7] == 0) {
+ /* AC terms all zero */
+ JSAMPLE dcval = range_limit[(int) DESCALE((INT32) wsptr[0], PASS1_BITS+3)
+ & RANGE_MASK];
+
+ outptr[0] = dcval;
+ outptr[1] = dcval;
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ continue;
+ }
+#endif
+
+ /* Even part */
+
+ tmp10 = ((INT32) wsptr[0]) << (CONST_BITS+2);
+
+ /* Odd part */
+
+ tmp0 = MULTIPLY((INT32) wsptr[7], - FIX_0_720959822) /* sqrt(2) * (c7-c5+c3-c1) */
+ + MULTIPLY((INT32) wsptr[5], FIX_0_850430095) /* sqrt(2) * (-c1+c3+c5+c7) */
+ + MULTIPLY((INT32) wsptr[3], - FIX_1_272758580) /* sqrt(2) * (-c1+c3-c5-c7) */
+ + MULTIPLY((INT32) wsptr[1], FIX_3_624509785); /* sqrt(2) * (c1+c3+c5+c7) */
+
+ /* Final output stage */
+
+ outptr[0] = range_limit[(int) DESCALE(tmp10 + tmp0,
+ CONST_BITS+PASS1_BITS+3+2)
+ & RANGE_MASK];
+ outptr[1] = range_limit[(int) DESCALE(tmp10 - tmp0,
+ CONST_BITS+PASS1_BITS+3+2)
+ & RANGE_MASK];
+
+ wsptr += DCTSIZE; /* advance pointer to next row */
+ }
+}
+
+
+/*
+ * Perform dequantization and inverse DCT on one block of coefficients,
+ * producing a reduced-size 1x1 output block.
+ */
+
+GLOBAL(void)
+jpeg_idct_1x1 (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col)
+{
+ int dcval;
+ ISLOW_MULT_TYPE * quantptr;
+ JSAMPLE *range_limit = IDCT_range_limit(cinfo);
+ SHIFT_TEMPS
+
+ /* We hardly need an inverse DCT routine for this: just take the
+ * average pixel value, which is one-eighth of the DC coefficient.
+ */
+ quantptr = (ISLOW_MULT_TYPE *) compptr->dct_table;
+ dcval = DETQUANTIZE(coef_block[0], quantptr[0]);
+ dcval = (int) DESCALE((INT32) dcval, 3);
+
+ output_buf[0][output_col] = range_limit[dcval & RANGE_MASK];
+}
+
+#endif /* IDCT_SCALING_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jinclude.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jinclude.h
new file mode 100644
index 0000000..768b287
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jinclude.h
@@ -0,0 +1,91 @@
+/*
+ * jinclude.h
+ *
+ * Copyright (C) 1991-1994, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file exists to provide a single place to fix any problems with
+ * including the wrong system include files. (Common problems are taken
+ * care of by the standard jconfig symbols, but on really weird systems
+ * you may have to edit this file.)
+ *
+ * NOTE: this file is NOT intended to be included by applications using the
+ * JPEG library. Most applications need only include jpeglib.h.
+ */
+
+
+/* Include auto-config file to tqfind out which system include files we need. */
+
+#include "jconfig.h" /* auto configuration options */
+#define JCONFIG_INCLUDED /* so that jpeglib.h doesn't do it again */
+
+/*
+ * We need the NULL macro and size_t typedef.
+ * On an ANSI-conforming system it is sufficient to include <stddef.h>.
+ * Otherwise, we get them from <stdlib.h> or <stdio.h>; we may have to
+ * pull in <sys/types.h> as well.
+ * Note that the core JPEG library does not require <stdio.h>;
+ * only the default error handler and data source/destination modules do.
+ * But we must pull it in because of the references to FILE in jpeglib.h.
+ * You can remove those references if you want to compile without <stdio.h>.
+ */
+
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#ifdef NEED_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
+#include <stdio.h>
+
+/*
+ * We need memory copying and zeroing functions, plus strncpy().
+ * ANSI and System V implementations declare these in <string.h>.
+ * BSD doesn't have the mem() functions, but it does have bcopy()/bzero().
+ * Some systems may declare memset and memcpy in <memory.h>.
+ *
+ * NOTE: we assume the size parameters to these functions are of type size_t.
+ * Change the casts in these macros if not!
+ */
+
+#ifdef NEED_BSD_STRINGS
+
+#include <strings.h>
+#define MEMZERO(target,size) bzero((void *)(target), (size_t)(size))
+#define MEMCOPY(dest,src,size) bcopy((const void *)(src), (void *)(dest), (size_t)(size))
+
+#else /* not BSD, assume ANSI/SysV string lib */
+
+#include <string.h>
+#define MEMZERO(target,size) memset((void *)(target), 0, (size_t)(size))
+#define MEMCOPY(dest,src,size) memcpy((void *)(dest), (const void *)(src), (size_t)(size))
+
+#endif
+
+/*
+ * In ANSI C, and indeed any rational implementation, size_t is also the
+ * type returned by sizeof(). However, it seems there are some irrational
+ * implementations out there, in which sizeof() returns an int even though
+ * size_t is defined as long or unsigned long. To ensure consistent results
+ * we always use this SIZEOF() macro in place of using sizeof() directly.
+ */
+
+#define SIZEOF(object) ((size_t) sizeof(object))
+
+/*
+ * The modules that use fread() and fwrite() always invoke them through
+ * these macros. On some systems you may need to twiddle the argument casts.
+ * CAUTION: argument order is different from underlying functions!
+ */
+
+#define JFREAD(file,buf,sizeofbuf) \
+ ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
+#define JFWRITE(file,buf,sizeofbuf) \
+ ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file)))
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jmemmgr.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jmemmgr.c
new file mode 100644
index 0000000..e36c050
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jmemmgr.c
@@ -0,0 +1,1118 @@
+/*
+ * jmemmgr.c
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains the JPEG system-independent memory management
+ * routines. This code is usable across a wide variety of machines; most
+ * of the system dependencies have been isolated in a separate file.
+ * The major functions provided here are:
+ * * pool-based allocation and freeing of memory;
+ * * policy decisions about how to divide available memory among the
+ * virtual arrays;
+ * * control logic for swapping virtual arrays between main memory and
+ * backing storage.
+ * The separate system-dependent file provides the actual backing-storage
+ * access code, and it tqcontains the policy decision about how much total
+ * main memory to use.
+ * This file is system-dependent in the sense that some of its functions
+ * are unnecessary in some systems. For example, if there is enough virtual
+ * memory so that backing storage will never be used, much of the virtual
+ * array control logic could be removed. (Of course, if you have that much
+ * memory then you shouldn't care about a little bit of unused code...)
+ */
+
+#define JPEG_INTERNALS
+#define AM_MEMORY_MANAGER /* we define jvirt_Xarray_control structs */
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jmemsys.h" /* import the system-dependent declarations */
+
+#ifndef NO_GETENV
+#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare getenv() */
+extern char * getenv JPP((const char * name));
+#endif
+#endif
+
+
+/*
+ * Some important notes:
+ * The allocation routines provided here must never return NULL.
+ * They should exit to error_exit if unsuccessful.
+ *
+ * It's not a good idea to try to merge the sarray and barray routines,
+ * even though they are textually almost the same, because samples are
+ * usually stored as bytes while coefficients are shorts or ints. Thus,
+ * in machines where byte pointers have a different representation from
+ * word pointers, the resulting machine code could not be the same.
+ */
+
+
+/*
+ * Many machines require storage tqalignment: longs must start on 4-byte
+ * boundaries, doubles on 8-byte boundaries, etc. On such machines, malloc()
+ * always returns pointers that are multiples of the worst-case tqalignment
+ * requirement, and we had better do so too.
+ * There isn't any really portable way to determine the worst-case tqalignment
+ * requirement. This module assumes that the tqalignment requirement is
+ * multiples of sizeof(ALIGN_TYPE).
+ * By default, we define ALIGN_TYPE as double. This is necessary on some
+ * workstations (where doubles really do need 8-byte tqalignment) and will work
+ * fine on nearly everything. If your machine has lesser tqalignment needs,
+ * you can save a few bytes by making ALIGN_TYPE smaller.
+ * The only place I know of where this will NOT work is certain Macintosh
+ * 680x0 compilers that define double as a 10-byte IEEE extended float.
+ * Doing 10-byte tqalignment is counterproductive because longwords won't be
+ * aligned well. Put "#define ALIGN_TYPE long" in jconfig.h if you have
+ * such a compiler.
+ */
+
+#ifndef ALIGN_TYPE /* so can override from jconfig.h */
+#define ALIGN_TYPE double
+#endif
+
+
+/*
+ * We allocate objects from "pools", where each pool is gotten with a single
+ * request to jpeg_get_small() or jpeg_get_large(). There is no per-object
+ * overhead within a pool, except for tqalignment padding. Each pool has a
+ * header with a link to the next pool of the same class.
+ * Small and large pool headers are identical except that the latter's
+ * link pointer must be FAR on 80x86 machines.
+ * Notice that the "real" header fields are union'ed with a dummy ALIGN_TYPE
+ * field. This forces the compiler to make SIZEOF(small_pool_hdr) a multiple
+ * of the tqalignment requirement of ALIGN_TYPE.
+ */
+
+typedef union small_pool_struct * small_pool_ptr;
+
+typedef union small_pool_struct {
+ struct {
+ small_pool_ptr next; /* next in list of pools */
+ size_t bytes_used; /* how many bytes already used within pool */
+ size_t bytes_left; /* bytes still available in this pool */
+ } hdr;
+ ALIGN_TYPE dummy; /* included in union to ensure tqalignment */
+} small_pool_hdr;
+
+typedef union large_pool_struct FAR * large_pool_ptr;
+
+typedef union large_pool_struct {
+ struct {
+ large_pool_ptr next; /* next in list of pools */
+ size_t bytes_used; /* how many bytes already used within pool */
+ size_t bytes_left; /* bytes still available in this pool */
+ } hdr;
+ ALIGN_TYPE dummy; /* included in union to ensure tqalignment */
+} large_pool_hdr;
+
+
+/*
+ * Here is the full definition of a memory manager object.
+ */
+
+typedef struct {
+ struct jpeg_memory_mgr pub; /* public fields */
+
+ /* Each pool identifier (lifetime class) names a linked list of pools. */
+ small_pool_ptr small_list[JPOOL_NUMPOOLS];
+ large_pool_ptr large_list[JPOOL_NUMPOOLS];
+
+ /* Since we only have one lifetime class of virtual arrays, only one
+ * linked list is necessary (for each datatype). Note that the virtual
+ * array control blocks being linked together are actually stored somewhere
+ * in the small-pool list.
+ */
+ jvirt_sarray_ptr virt_sarray_list;
+ jvirt_barray_ptr virt_barray_list;
+
+ /* This counts total space obtained from jpeg_get_small/large */
+ long total_space_allocated;
+
+ /* alloc_sarray and alloc_barray set this value for use by virtual
+ * array routines.
+ */
+ JDIMENSION last_rowsperchunk; /* from most recent alloc_sarray/barray */
+} my_memory_mgr;
+
+typedef my_memory_mgr * my_mem_ptr;
+
+
+/*
+ * The control blocks for virtual arrays.
+ * Note that these blocks are allocated in the "small" pool area.
+ * System-dependent info for the associated backing store (if any) is hidden
+ * inside the backing_store_info struct.
+ */
+
+struct jvirt_sarray_control {
+ JSAMPARRAY mem_buffer; /* => the in-memory buffer */
+ JDIMENSION rows_in_array; /* total virtual array height */
+ JDIMENSION samplesperrow; /* width of array (and of memory buffer) */
+ JDIMENSION maxaccess; /* max rows accessed by access_virt_sarray */
+ JDIMENSION rows_in_mem; /* height of memory buffer */
+ JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
+ JDIMENSION cur_start_row; /* first logical row # in the buffer */
+ JDIMENSION first_undef_row; /* row # of first uninitialized row */
+ boolean pre_zero; /* pre-zero mode requested? */
+ boolean dirty; /* do current buffer contents need written? */
+ boolean b_s_open; /* is backing-store data valid? */
+ jvirt_sarray_ptr next; /* link to next virtual sarray control block */
+ backing_store_info b_s_info; /* System-dependent control info */
+};
+
+struct jvirt_barray_control {
+ JBLOCKARRAY mem_buffer; /* => the in-memory buffer */
+ JDIMENSION rows_in_array; /* total virtual array height */
+ JDIMENSION blocksperrow; /* width of array (and of memory buffer) */
+ JDIMENSION maxaccess; /* max rows accessed by access_virt_barray */
+ JDIMENSION rows_in_mem; /* height of memory buffer */
+ JDIMENSION rowsperchunk; /* allocation chunk size in mem_buffer */
+ JDIMENSION cur_start_row; /* first logical row # in the buffer */
+ JDIMENSION first_undef_row; /* row # of first uninitialized row */
+ boolean pre_zero; /* pre-zero mode requested? */
+ boolean dirty; /* do current buffer contents need written? */
+ boolean b_s_open; /* is backing-store data valid? */
+ jvirt_barray_ptr next; /* link to next virtual barray control block */
+ backing_store_info b_s_info; /* System-dependent control info */
+};
+
+
+#ifdef MEM_STATS /* optional extra stuff for statistics */
+
+LOCAL(void)
+print_mem_stats (j_common_ptr cinfo, int pool_id)
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ small_pool_ptr shdr_ptr;
+ large_pool_ptr lhdr_ptr;
+
+ /* Since this is only a debugging stub, we can cheat a little by using
+ * fprintf directly rather than going through the trace message code.
+ * This is helpful because message parm array can't handle longs.
+ */
+ fprintf(stderr, "Freeing pool %d, total space = %ld\n",
+ pool_id, mem->total_space_allocated);
+
+ for (lhdr_ptr = mem->large_list[pool_id]; lhdr_ptr != NULL;
+ lhdr_ptr = lhdr_ptr->hdr.next) {
+ fprintf(stderr, " Large chunk used %ld\n",
+ (long) lhdr_ptr->hdr.bytes_used);
+ }
+
+ for (shdr_ptr = mem->small_list[pool_id]; shdr_ptr != NULL;
+ shdr_ptr = shdr_ptr->hdr.next) {
+ fprintf(stderr, " Small chunk used %ld free %ld\n",
+ (long) shdr_ptr->hdr.bytes_used,
+ (long) shdr_ptr->hdr.bytes_left);
+ }
+}
+
+#endif /* MEM_STATS */
+
+
+LOCAL(void)
+out_of_memory (j_common_ptr cinfo, int which)
+/* Report an out-of-memory error and stop execution */
+/* If we compiled MEM_STATS support, report alloc requests before dying */
+{
+#ifdef MEM_STATS
+ cinfo->err->trace_level = 2; /* force self_destruct to report stats */
+#endif
+ ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, which);
+}
+
+
+/*
+ * Allocation of "small" objects.
+ *
+ * For these, we use pooled storage. When a new pool must be created,
+ * we try to get enough space for the current request plus a "slop" factor,
+ * where the slop will be the amount of leftover space in the new pool.
+ * The speed vs. space tradeoff is largely determined by the slop values.
+ * A different slop value is provided for each pool class (lifetime),
+ * and we also distinguish the first pool of a class from later ones.
+ * NOTE: the values given work fairly well on both 16- and 32-bit-int
+ * machines, but may be too small if longs are 64 bits or more.
+ */
+
+static const size_t first_pool_slop[JPOOL_NUMPOOLS] =
+{
+ 1600, /* first PERMANENT pool */
+ 16000 /* first IMAGE pool */
+};
+
+static const size_t extra_pool_slop[JPOOL_NUMPOOLS] =
+{
+ 0, /* additional PERMANENT pools */
+ 5000 /* additional IMAGE pools */
+};
+
+#define MIN_SLOP 50 /* greater than 0 to avoid futile looping */
+
+
+METHODDEF(void *)
+alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
+/* Allocate a "small" object */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ small_pool_ptr hdr_ptr, prev_hdr_ptr;
+ char * data_ptr;
+ size_t odd_bytes, min_request, slop;
+
+ /* Check for unsatisfiable request (do now to ensure no overflow below) */
+ if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
+ out_of_memory(cinfo, 1); /* request exceeds malloc's ability */
+
+ /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
+ odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
+ if (odd_bytes > 0)
+ sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
+
+ /* See if space is available in any existing pool */
+ if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
+ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
+ prev_hdr_ptr = NULL;
+ hdr_ptr = mem->small_list[pool_id];
+ while (hdr_ptr != NULL) {
+ if (hdr_ptr->hdr.bytes_left >= sizeofobject)
+ break; /* found pool with enough space */
+ prev_hdr_ptr = hdr_ptr;
+ hdr_ptr = hdr_ptr->hdr.next;
+ }
+
+ /* Time to make a new pool? */
+ if (hdr_ptr == NULL) {
+ /* min_request is what we need now, slop is what will be leftover */
+ min_request = sizeofobject + SIZEOF(small_pool_hdr);
+ if (prev_hdr_ptr == NULL) /* first pool in class? */
+ slop = first_pool_slop[pool_id];
+ else
+ slop = extra_pool_slop[pool_id];
+ /* Don't ask for more than MAX_ALLOC_CHUNK */
+ if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
+ slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
+ /* Try to get space, if fail reduce slop and try again */
+ for (;;) {
+ hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
+ if (hdr_ptr != NULL)
+ break;
+ slop /= 2;
+ if (slop < MIN_SLOP) /* give up when it gets real small */
+ out_of_memory(cinfo, 2); /* jpeg_get_small failed */
+ }
+ mem->total_space_allocated += min_request + slop;
+ /* Success, initialize the new pool header and add to end of list */
+ hdr_ptr->hdr.next = NULL;
+ hdr_ptr->hdr.bytes_used = 0;
+ hdr_ptr->hdr.bytes_left = sizeofobject + slop;
+ if (prev_hdr_ptr == NULL) /* first pool in class? */
+ mem->small_list[pool_id] = hdr_ptr;
+ else
+ prev_hdr_ptr->hdr.next = hdr_ptr;
+ }
+
+ /* OK, allocate the object from the current pool */
+ data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
+ data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
+ hdr_ptr->hdr.bytes_used += sizeofobject;
+ hdr_ptr->hdr.bytes_left -= sizeofobject;
+
+ return (void *) data_ptr;
+}
+
+
+/*
+ * Allocation of "large" objects.
+ *
+ * The external semantics of these are the same as "small" objects,
+ * except that FAR pointers are used on 80x86. However the pool
+ * management heuristics are quite different. We assume that each
+ * request is large enough that it may as well be passed directly to
+ * jpeg_get_large; the pool management just links everything together
+ * so that we can free it all on demand.
+ * Note: the major use of "large" objects is in JSAMPARRAY and JBLOCKARRAY
+ * structures. The routines that create these structures (see below)
+ * deliberately bunch rows together to ensure a large request size.
+ */
+
+METHODDEF(void FAR *)
+alloc_large (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
+/* Allocate a "large" object */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ large_pool_ptr hdr_ptr;
+ size_t odd_bytes;
+
+ /* Check for unsatisfiable request (do now to ensure no overflow below) */
+ if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)))
+ out_of_memory(cinfo, 3); /* request exceeds malloc's ability */
+
+ /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
+ odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
+ if (odd_bytes > 0)
+ sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;
+
+ /* Always make a new pool */
+ if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
+ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
+
+ hdr_ptr = (large_pool_ptr) jpeg_get_large(cinfo, sizeofobject +
+ SIZEOF(large_pool_hdr));
+ if (hdr_ptr == NULL)
+ out_of_memory(cinfo, 4); /* jpeg_get_large failed */
+ mem->total_space_allocated += sizeofobject + SIZEOF(large_pool_hdr);
+
+ /* Success, initialize the new pool header and add to list */
+ hdr_ptr->hdr.next = mem->large_list[pool_id];
+ /* We maintain space counts in each pool header for statistical purposes,
+ * even though they are not needed for allocation.
+ */
+ hdr_ptr->hdr.bytes_used = sizeofobject;
+ hdr_ptr->hdr.bytes_left = 0;
+ mem->large_list[pool_id] = hdr_ptr;
+
+ return (void FAR *) (hdr_ptr + 1); /* point to first data byte in pool */
+}
+
+
+/*
+ * Creation of 2-D sample arrays.
+ * The pointers are in near heap, the samples themselves in FAR heap.
+ *
+ * To minimize allocation overhead and to allow I/O of large contiguous
+ * blocks, we allocate the sample rows in groups of as many rows as possible
+ * without exceeding MAX_ALLOC_CHUNK total bytes per allocation request.
+ * NB: the virtual array control routines, later in this file, know about
+ * this chunking of rows. The rowsperchunk value is left in the mem manager
+ * object so that it can be saved away if this sarray is the workspace for
+ * a virtual array.
+ */
+
+METHODDEF(JSAMPARRAY)
+alloc_sarray (j_common_ptr cinfo, int pool_id,
+ JDIMENSION samplesperrow, JDIMENSION numrows)
+/* Allocate a 2-D sample array */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ JSAMPARRAY result;
+ JSAMPROW workspace;
+ JDIMENSION rowsperchunk, currow, i;
+ long ltemp;
+
+ /* Calculate max # of rows allowed in one allocation chunk */
+ ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
+ ((long) samplesperrow * SIZEOF(JSAMPLE));
+ if (ltemp <= 0)
+ ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+ if (ltemp < (long) numrows)
+ rowsperchunk = (JDIMENSION) ltemp;
+ else
+ rowsperchunk = numrows;
+ mem->last_rowsperchunk = rowsperchunk;
+
+ /* Get space for row pointers (small object) */
+ result = (JSAMPARRAY) alloc_small(cinfo, pool_id,
+ (size_t) (numrows * SIZEOF(JSAMPROW)));
+
+ /* Get the rows themselves (large objects) */
+ currow = 0;
+ while (currow < numrows) {
+ rowsperchunk = MIN(rowsperchunk, numrows - currow);
+ workspace = (JSAMPROW) alloc_large(cinfo, pool_id,
+ (size_t) ((size_t) rowsperchunk * (size_t) samplesperrow
+ * SIZEOF(JSAMPLE)));
+ for (i = rowsperchunk; i > 0; i--) {
+ result[currow++] = workspace;
+ workspace += samplesperrow;
+ }
+ }
+
+ return result;
+}
+
+
+/*
+ * Creation of 2-D coefficient-block arrays.
+ * This is essentially the same as the code for sample arrays, above.
+ */
+
+METHODDEF(JBLOCKARRAY)
+alloc_barray (j_common_ptr cinfo, int pool_id,
+ JDIMENSION blocksperrow, JDIMENSION numrows)
+/* Allocate a 2-D coefficient-block array */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ JBLOCKARRAY result;
+ JBLOCKROW workspace;
+ JDIMENSION rowsperchunk, currow, i;
+ long ltemp;
+
+ /* Calculate max # of rows allowed in one allocation chunk */
+ ltemp = (MAX_ALLOC_CHUNK-SIZEOF(large_pool_hdr)) /
+ ((long) blocksperrow * SIZEOF(JBLOCK));
+ if (ltemp <= 0)
+ ERREXIT(cinfo, JERR_WIDTH_OVERFLOW);
+ if (ltemp < (long) numrows)
+ rowsperchunk = (JDIMENSION) ltemp;
+ else
+ rowsperchunk = numrows;
+ mem->last_rowsperchunk = rowsperchunk;
+
+ /* Get space for row pointers (small object) */
+ result = (JBLOCKARRAY) alloc_small(cinfo, pool_id,
+ (size_t) (numrows * SIZEOF(JBLOCKROW)));
+
+ /* Get the rows themselves (large objects) */
+ currow = 0;
+ while (currow < numrows) {
+ rowsperchunk = MIN(rowsperchunk, numrows - currow);
+ workspace = (JBLOCKROW) alloc_large(cinfo, pool_id,
+ (size_t) ((size_t) rowsperchunk * (size_t) blocksperrow
+ * SIZEOF(JBLOCK)));
+ for (i = rowsperchunk; i > 0; i--) {
+ result[currow++] = workspace;
+ workspace += blocksperrow;
+ }
+ }
+
+ return result;
+}
+
+
+/*
+ * About virtual array management:
+ *
+ * The above "normal" array routines are only used to allocate strip buffers
+ * (as wide as the image, but just a few rows high). Full-image-sized buffers
+ * are handled as "virtual" arrays. The array is still accessed a strip at a
+ * time, but the memory manager must save the whole array for repeated
+ * accesses. The intended implementation is that there is a strip buffer in
+ * memory (as high as is possible given the desired memory limit), plus a
+ * backing file that holds the rest of the array.
+ *
+ * The request_virt_array routines are told the total size of the image and
+ * the maximum number of rows that will be accessed at once. The in-memory
+ * buffer must be at least as large as the maxaccess value.
+ *
+ * The request routines create control blocks but not the in-memory buffers.
+ * That is postponed until realize_virt_arrays is called. At that time the
+ * total amount of space needed is known (approximately, anyway), so free
+ * memory can be divided up fairly.
+ *
+ * The access_virt_array routines are responsible for making a specific strip
+ * area accessible (after reading or writing the backing file, if necessary).
+ * Note that the access routines are told whether the caller intends to modify
+ * the accessed strip; during a read-only pass this saves having to rewrite
+ * data to disk. The access routines are also responsible for pre-zeroing
+ * any newly accessed rows, if pre-zeroing was requested.
+ *
+ * In current usage, the access requests are usually for nonoverlapping
+ * strips; that is, successive access start_row numbers differ by exactly
+ * num_rows = maxaccess. This means we can get good performance with simple
+ * buffer dump/reload logic, by making the in-memory buffer be a multiple
+ * of the access height; then there will never be accesses across bufferload
+ * boundaries. The code will still work with overlapping access requests,
+ * but it doesn't handle bufferload overlaps very efficiently.
+ */
+
+
+METHODDEF(jvirt_sarray_ptr)
+request_virt_sarray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
+ JDIMENSION samplesperrow, JDIMENSION numrows,
+ JDIMENSION maxaccess)
+/* Request a virtual 2-D sample array */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ jvirt_sarray_ptr result;
+
+ /* Only IMAGE-lifetime virtual arrays are currently supported */
+ if (pool_id != JPOOL_IMAGE)
+ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
+
+ /* get control block */
+ result = (jvirt_sarray_ptr) alloc_small(cinfo, pool_id,
+ SIZEOF(struct jvirt_sarray_control));
+
+ result->mem_buffer = NULL; /* marks array not yet realized */
+ result->rows_in_array = numrows;
+ result->samplesperrow = samplesperrow;
+ result->maxaccess = maxaccess;
+ result->pre_zero = pre_zero;
+ result->b_s_open = FALSE; /* no associated backing-store object */
+ result->next = mem->virt_sarray_list; /* add to list of virtual arrays */
+ mem->virt_sarray_list = result;
+
+ return result;
+}
+
+
+METHODDEF(jvirt_barray_ptr)
+request_virt_barray (j_common_ptr cinfo, int pool_id, boolean pre_zero,
+ JDIMENSION blocksperrow, JDIMENSION numrows,
+ JDIMENSION maxaccess)
+/* Request a virtual 2-D coefficient-block array */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ jvirt_barray_ptr result;
+
+ /* Only IMAGE-lifetime virtual arrays are currently supported */
+ if (pool_id != JPOOL_IMAGE)
+ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
+
+ /* get control block */
+ result = (jvirt_barray_ptr) alloc_small(cinfo, pool_id,
+ SIZEOF(struct jvirt_barray_control));
+
+ result->mem_buffer = NULL; /* marks array not yet realized */
+ result->rows_in_array = numrows;
+ result->blocksperrow = blocksperrow;
+ result->maxaccess = maxaccess;
+ result->pre_zero = pre_zero;
+ result->b_s_open = FALSE; /* no associated backing-store object */
+ result->next = mem->virt_barray_list; /* add to list of virtual arrays */
+ mem->virt_barray_list = result;
+
+ return result;
+}
+
+
+METHODDEF(void)
+realize_virt_arrays (j_common_ptr cinfo)
+/* Allocate the in-memory buffers for any unrealized virtual arrays */
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ long space_per_minheight, maximum_space, avail_mem;
+ long minheights, max_minheights;
+ jvirt_sarray_ptr sptr;
+ jvirt_barray_ptr bptr;
+
+ /* Compute the minimum space needed (maxaccess rows in each buffer)
+ * and the maximum space needed (full image height in each buffer).
+ * These may be of use to the system-dependent jpeg_mem_available routine.
+ */
+ space_per_minheight = 0;
+ maximum_space = 0;
+ for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
+ if (sptr->mem_buffer == NULL) { /* if not realized yet */
+ space_per_minheight += (long) sptr->maxaccess *
+ (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
+ maximum_space += (long) sptr->rows_in_array *
+ (long) sptr->samplesperrow * SIZEOF(JSAMPLE);
+ }
+ }
+ for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
+ if (bptr->mem_buffer == NULL) { /* if not realized yet */
+ space_per_minheight += (long) bptr->maxaccess *
+ (long) bptr->blocksperrow * SIZEOF(JBLOCK);
+ maximum_space += (long) bptr->rows_in_array *
+ (long) bptr->blocksperrow * SIZEOF(JBLOCK);
+ }
+ }
+
+ if (space_per_minheight <= 0)
+ return; /* no unrealized arrays, no work */
+
+ /* Determine amount of memory to actually use; this is system-dependent. */
+ avail_mem = jpeg_mem_available(cinfo, space_per_minheight, maximum_space,
+ mem->total_space_allocated);
+
+ /* If the maximum space needed is available, make all the buffers full
+ * height; otherwise parcel it out with the same number of minheights
+ * in each buffer.
+ */
+ if (avail_mem >= maximum_space)
+ max_minheights = 1000000000L;
+ else {
+ max_minheights = avail_mem / space_per_minheight;
+ /* If there doesn't seem to be enough space, try to get the minimum
+ * anyway. This allows a "stub" implementation of jpeg_mem_available().
+ */
+ if (max_minheights <= 0)
+ max_minheights = 1;
+ }
+
+ /* Allocate the in-memory buffers and initialize backing store as needed. */
+
+ for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
+ if (sptr->mem_buffer == NULL) { /* if not realized yet */
+ minheights = ((long) sptr->rows_in_array - 1L) / sptr->maxaccess + 1L;
+ if (minheights <= max_minheights) {
+ /* This buffer fits in memory */
+ sptr->rows_in_mem = sptr->rows_in_array;
+ } else {
+ /* It doesn't fit in memory, create backing store. */
+ sptr->rows_in_mem = (JDIMENSION) (max_minheights * sptr->maxaccess);
+ jpeg_open_backing_store(cinfo, & sptr->b_s_info,
+ (long) sptr->rows_in_array *
+ (long) sptr->samplesperrow *
+ (long) SIZEOF(JSAMPLE));
+ sptr->b_s_open = TRUE;
+ }
+ sptr->mem_buffer = alloc_sarray(cinfo, JPOOL_IMAGE,
+ sptr->samplesperrow, sptr->rows_in_mem);
+ sptr->rowsperchunk = mem->last_rowsperchunk;
+ sptr->cur_start_row = 0;
+ sptr->first_undef_row = 0;
+ sptr->dirty = FALSE;
+ }
+ }
+
+ for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
+ if (bptr->mem_buffer == NULL) { /* if not realized yet */
+ minheights = ((long) bptr->rows_in_array - 1L) / bptr->maxaccess + 1L;
+ if (minheights <= max_minheights) {
+ /* This buffer fits in memory */
+ bptr->rows_in_mem = bptr->rows_in_array;
+ } else {
+ /* It doesn't fit in memory, create backing store. */
+ bptr->rows_in_mem = (JDIMENSION) (max_minheights * bptr->maxaccess);
+ jpeg_open_backing_store(cinfo, & bptr->b_s_info,
+ (long) bptr->rows_in_array *
+ (long) bptr->blocksperrow *
+ (long) SIZEOF(JBLOCK));
+ bptr->b_s_open = TRUE;
+ }
+ bptr->mem_buffer = alloc_barray(cinfo, JPOOL_IMAGE,
+ bptr->blocksperrow, bptr->rows_in_mem);
+ bptr->rowsperchunk = mem->last_rowsperchunk;
+ bptr->cur_start_row = 0;
+ bptr->first_undef_row = 0;
+ bptr->dirty = FALSE;
+ }
+ }
+}
+
+
+LOCAL(void)
+do_sarray_io (j_common_ptr cinfo, jvirt_sarray_ptr ptr, boolean writing)
+/* Do backing store read or write of a virtual sample array */
+{
+ long bytesperrow, file_offset, byte_count, rows, thisrow, i;
+
+ bytesperrow = (long) ptr->samplesperrow * SIZEOF(JSAMPLE);
+ file_offset = ptr->cur_start_row * bytesperrow;
+ /* Loop to read or write each allocation chunk in mem_buffer */
+ for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
+ /* One chunk, but check for short chunk at end of buffer */
+ rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
+ /* Transfer no more than is currently defined */
+ thisrow = (long) ptr->cur_start_row + i;
+ rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
+ /* Transfer no more than fits in file */
+ rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
+ if (rows <= 0) /* this chunk might be past end of file! */
+ break;
+ byte_count = rows * bytesperrow;
+ if (writing)
+ (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
+ (void FAR *) ptr->mem_buffer[i],
+ file_offset, byte_count);
+ else
+ (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
+ (void FAR *) ptr->mem_buffer[i],
+ file_offset, byte_count);
+ file_offset += byte_count;
+ }
+}
+
+
+LOCAL(void)
+do_barray_io (j_common_ptr cinfo, jvirt_barray_ptr ptr, boolean writing)
+/* Do backing store read or write of a virtual coefficient-block array */
+{
+ long bytesperrow, file_offset, byte_count, rows, thisrow, i;
+
+ bytesperrow = (long) ptr->blocksperrow * SIZEOF(JBLOCK);
+ file_offset = ptr->cur_start_row * bytesperrow;
+ /* Loop to read or write each allocation chunk in mem_buffer */
+ for (i = 0; i < (long) ptr->rows_in_mem; i += ptr->rowsperchunk) {
+ /* One chunk, but check for short chunk at end of buffer */
+ rows = MIN((long) ptr->rowsperchunk, (long) ptr->rows_in_mem - i);
+ /* Transfer no more than is currently defined */
+ thisrow = (long) ptr->cur_start_row + i;
+ rows = MIN(rows, (long) ptr->first_undef_row - thisrow);
+ /* Transfer no more than fits in file */
+ rows = MIN(rows, (long) ptr->rows_in_array - thisrow);
+ if (rows <= 0) /* this chunk might be past end of file! */
+ break;
+ byte_count = rows * bytesperrow;
+ if (writing)
+ (*ptr->b_s_info.write_backing_store) (cinfo, & ptr->b_s_info,
+ (void FAR *) ptr->mem_buffer[i],
+ file_offset, byte_count);
+ else
+ (*ptr->b_s_info.read_backing_store) (cinfo, & ptr->b_s_info,
+ (void FAR *) ptr->mem_buffer[i],
+ file_offset, byte_count);
+ file_offset += byte_count;
+ }
+}
+
+
+METHODDEF(JSAMPARRAY)
+access_virt_sarray (j_common_ptr cinfo, jvirt_sarray_ptr ptr,
+ JDIMENSION start_row, JDIMENSION num_rows,
+ boolean writable)
+/* Access the part of a virtual sample array starting at start_row */
+/* and extending for num_rows rows. writable is true if */
+/* caller intends to modify the accessed area. */
+{
+ JDIMENSION end_row = start_row + num_rows;
+ JDIMENSION undef_row;
+
+ /* debugging check */
+ if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
+ ptr->mem_buffer == NULL)
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+
+ /* Make the desired part of the virtual array accessible */
+ if (start_row < ptr->cur_start_row ||
+ end_row > ptr->cur_start_row+ptr->rows_in_mem) {
+ if (! ptr->b_s_open)
+ ERREXIT(cinfo, JERR_VIRTUAL_BUG);
+ /* Flush old buffer contents if necessary */
+ if (ptr->dirty) {
+ do_sarray_io(cinfo, ptr, TRUE);
+ ptr->dirty = FALSE;
+ }
+ /* Decide what part of virtual array to access.
+ * Algorithm: if target address > current window, assume forward scan,
+ * load starting at target address. If target address < current window,
+ * assume backward scan, load so that target area is top of window.
+ * Note that when switching from forward write to forward read, will have
+ * start_row = 0, so the limiting case applies and we load from 0 anyway.
+ */
+ if (start_row > ptr->cur_start_row) {
+ ptr->cur_start_row = start_row;
+ } else {
+ /* use long arithmetic here to avoid overflow & unsigned problems */
+ long ltemp;
+
+ ltemp = (long) end_row - (long) ptr->rows_in_mem;
+ if (ltemp < 0)
+ ltemp = 0; /* don't fall off front end of file */
+ ptr->cur_start_row = (JDIMENSION) ltemp;
+ }
+ /* Read in the selected part of the array.
+ * During the initial write pass, we will do no actual read
+ * because the selected part is all undefined.
+ */
+ do_sarray_io(cinfo, ptr, FALSE);
+ }
+ /* Ensure the accessed part of the array is defined; prezero if needed.
+ * To improve locality of access, we only prezero the part of the array
+ * that the caller is about to access, not the entire in-memory array.
+ */
+ if (ptr->first_undef_row < end_row) {
+ if (ptr->first_undef_row < start_row) {
+ if (writable) /* writer skipped over a section of array */
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+ undef_row = start_row; /* but reader is allowed to read ahead */
+ } else {
+ undef_row = ptr->first_undef_row;
+ }
+ if (writable)
+ ptr->first_undef_row = end_row;
+ if (ptr->pre_zero) {
+ size_t bytesperrow = (size_t) ptr->samplesperrow * SIZEOF(JSAMPLE);
+ undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
+ end_row -= ptr->cur_start_row;
+ while (undef_row < end_row) {
+ jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
+ undef_row++;
+ }
+ } else {
+ if (! writable) /* reader looking at undefined data */
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+ }
+ }
+ /* Flag the buffer dirty if caller will write in it */
+ if (writable)
+ ptr->dirty = TRUE;
+ /* Return address of proper part of the buffer */
+ return ptr->mem_buffer + (start_row - ptr->cur_start_row);
+}
+
+
+METHODDEF(JBLOCKARRAY)
+access_virt_barray (j_common_ptr cinfo, jvirt_barray_ptr ptr,
+ JDIMENSION start_row, JDIMENSION num_rows,
+ boolean writable)
+/* Access the part of a virtual block array starting at start_row */
+/* and extending for num_rows rows. writable is true if */
+/* caller intends to modify the accessed area. */
+{
+ JDIMENSION end_row = start_row + num_rows;
+ JDIMENSION undef_row;
+
+ /* debugging check */
+ if (end_row > ptr->rows_in_array || num_rows > ptr->maxaccess ||
+ ptr->mem_buffer == NULL)
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+
+ /* Make the desired part of the virtual array accessible */
+ if (start_row < ptr->cur_start_row ||
+ end_row > ptr->cur_start_row+ptr->rows_in_mem) {
+ if (! ptr->b_s_open)
+ ERREXIT(cinfo, JERR_VIRTUAL_BUG);
+ /* Flush old buffer contents if necessary */
+ if (ptr->dirty) {
+ do_barray_io(cinfo, ptr, TRUE);
+ ptr->dirty = FALSE;
+ }
+ /* Decide what part of virtual array to access.
+ * Algorithm: if target address > current window, assume forward scan,
+ * load starting at target address. If target address < current window,
+ * assume backward scan, load so that target area is top of window.
+ * Note that when switching from forward write to forward read, will have
+ * start_row = 0, so the limiting case applies and we load from 0 anyway.
+ */
+ if (start_row > ptr->cur_start_row) {
+ ptr->cur_start_row = start_row;
+ } else {
+ /* use long arithmetic here to avoid overflow & unsigned problems */
+ long ltemp;
+
+ ltemp = (long) end_row - (long) ptr->rows_in_mem;
+ if (ltemp < 0)
+ ltemp = 0; /* don't fall off front end of file */
+ ptr->cur_start_row = (JDIMENSION) ltemp;
+ }
+ /* Read in the selected part of the array.
+ * During the initial write pass, we will do no actual read
+ * because the selected part is all undefined.
+ */
+ do_barray_io(cinfo, ptr, FALSE);
+ }
+ /* Ensure the accessed part of the array is defined; prezero if needed.
+ * To improve locality of access, we only prezero the part of the array
+ * that the caller is about to access, not the entire in-memory array.
+ */
+ if (ptr->first_undef_row < end_row) {
+ if (ptr->first_undef_row < start_row) {
+ if (writable) /* writer skipped over a section of array */
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+ undef_row = start_row; /* but reader is allowed to read ahead */
+ } else {
+ undef_row = ptr->first_undef_row;
+ }
+ if (writable)
+ ptr->first_undef_row = end_row;
+ if (ptr->pre_zero) {
+ size_t bytesperrow = (size_t) ptr->blocksperrow * SIZEOF(JBLOCK);
+ undef_row -= ptr->cur_start_row; /* make indexes relative to buffer */
+ end_row -= ptr->cur_start_row;
+ while (undef_row < end_row) {
+ jzero_far((void FAR *) ptr->mem_buffer[undef_row], bytesperrow);
+ undef_row++;
+ }
+ } else {
+ if (! writable) /* reader looking at undefined data */
+ ERREXIT(cinfo, JERR_BAD_VIRTUAL_ACCESS);
+ }
+ }
+ /* Flag the buffer dirty if caller will write in it */
+ if (writable)
+ ptr->dirty = TRUE;
+ /* Return address of proper part of the buffer */
+ return ptr->mem_buffer + (start_row - ptr->cur_start_row);
+}
+
+
+/*
+ * Release all objects belonging to a specified pool.
+ */
+
+METHODDEF(void)
+free_pool (j_common_ptr cinfo, int pool_id)
+{
+ my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
+ small_pool_ptr shdr_ptr;
+ large_pool_ptr lhdr_ptr;
+ size_t space_freed;
+
+ if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
+ ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id); /* safety check */
+
+#ifdef MEM_STATS
+ if (cinfo->err->trace_level > 1)
+ print_mem_stats(cinfo, pool_id); /* print pool's memory usage statistics */
+#endif
+
+ /* If freeing IMAGE pool, close any virtual arrays first */
+ if (pool_id == JPOOL_IMAGE) {
+ jvirt_sarray_ptr sptr;
+ jvirt_barray_ptr bptr;
+
+ for (sptr = mem->virt_sarray_list; sptr != NULL; sptr = sptr->next) {
+ if (sptr->b_s_open) { /* there may be no backing store */
+ sptr->b_s_open = FALSE; /* prevent recursive close if error */
+ (*sptr->b_s_info.close_backing_store) (cinfo, & sptr->b_s_info);
+ }
+ }
+ mem->virt_sarray_list = NULL;
+ for (bptr = mem->virt_barray_list; bptr != NULL; bptr = bptr->next) {
+ if (bptr->b_s_open) { /* there may be no backing store */
+ bptr->b_s_open = FALSE; /* prevent recursive close if error */
+ (*bptr->b_s_info.close_backing_store) (cinfo, & bptr->b_s_info);
+ }
+ }
+ mem->virt_barray_list = NULL;
+ }
+
+ /* Release large objects */
+ lhdr_ptr = mem->large_list[pool_id];
+ mem->large_list[pool_id] = NULL;
+
+ while (lhdr_ptr != NULL) {
+ large_pool_ptr next_lhdr_ptr = lhdr_ptr->hdr.next;
+ space_freed = lhdr_ptr->hdr.bytes_used +
+ lhdr_ptr->hdr.bytes_left +
+ SIZEOF(large_pool_hdr);
+ jpeg_free_large(cinfo, (void FAR *) lhdr_ptr, space_freed);
+ mem->total_space_allocated -= space_freed;
+ lhdr_ptr = next_lhdr_ptr;
+ }
+
+ /* Release small objects */
+ shdr_ptr = mem->small_list[pool_id];
+ mem->small_list[pool_id] = NULL;
+
+ while (shdr_ptr != NULL) {
+ small_pool_ptr next_shdr_ptr = shdr_ptr->hdr.next;
+ space_freed = shdr_ptr->hdr.bytes_used +
+ shdr_ptr->hdr.bytes_left +
+ SIZEOF(small_pool_hdr);
+ jpeg_free_small(cinfo, (void *) shdr_ptr, space_freed);
+ mem->total_space_allocated -= space_freed;
+ shdr_ptr = next_shdr_ptr;
+ }
+}
+
+
+/*
+ * Close up shop entirely.
+ * Note that this cannot be called unless cinfo->mem is non-NULL.
+ */
+
+METHODDEF(void)
+self_destruct (j_common_ptr cinfo)
+{
+ int pool;
+
+ /* Close all backing store, release all memory.
+ * Releasing pools in reverse order might help avoid fragmentation
+ * with some (brain-damaged) malloc libraries.
+ */
+ for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
+ free_pool(cinfo, pool);
+ }
+
+ /* Release the memory manager control block too. */
+ jpeg_free_small(cinfo, (void *) cinfo->mem, SIZEOF(my_memory_mgr));
+ cinfo->mem = NULL; /* ensures I will be called only once */
+
+ jpeg_mem_term(cinfo); /* system-dependent cleanup */
+}
+
+
+/*
+ * Memory manager initialization.
+ * When this is called, only the error manager pointer is valid in cinfo!
+ */
+
+GLOBAL(void)
+jinit_memory_mgr (j_common_ptr cinfo)
+{
+ my_mem_ptr mem;
+ long max_to_use;
+ int pool;
+ size_t test_mac;
+
+ cinfo->mem = NULL; /* for safety if init fails */
+
+ /* Check for configuration errors.
+ * SIZEOF(ALIGN_TYPE) should be a power of 2; otherwise, it probably
+ * doesn't reflect any real hardware tqalignment requirement.
+ * The test is a little tricky: for X>0, X and X-1 have no one-bits
+ * in common if and only if X is a power of 2, ie has only one one-bit.
+ * Some compilers may give an "unreachable code" warning here; ignore it.
+ */
+ if ((SIZEOF(ALIGN_TYPE) & (SIZEOF(ALIGN_TYPE)-1)) != 0)
+ ERREXIT(cinfo, JERR_BAD_ALIGN_TYPE);
+ /* MAX_ALLOC_CHUNK must be representable as type size_t, and must be
+ * a multiple of SIZEOF(ALIGN_TYPE).
+ * Again, an "unreachable code" warning may be ignored here.
+ * But a "constant too large" warning means you need to fix MAX_ALLOC_CHUNK.
+ */
+ test_mac = (size_t) MAX_ALLOC_CHUNK;
+ if ((long) test_mac != MAX_ALLOC_CHUNK ||
+ (MAX_ALLOC_CHUNK % SIZEOF(ALIGN_TYPE)) != 0)
+ ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
+
+ max_to_use = jpeg_mem_init(cinfo); /* system-dependent initialization */
+
+ /* Attempt to allocate memory manager's control block */
+ mem = (my_mem_ptr) jpeg_get_small(cinfo, SIZEOF(my_memory_mgr));
+
+ if (mem == NULL) {
+ jpeg_mem_term(cinfo); /* system-dependent cleanup */
+ ERREXIT1(cinfo, JERR_OUT_OF_MEMORY, 0);
+ }
+
+ /* OK, fill in the method pointers */
+ mem->pub.alloc_small = alloc_small;
+ mem->pub.alloc_large = alloc_large;
+ mem->pub.alloc_sarray = alloc_sarray;
+ mem->pub.alloc_barray = alloc_barray;
+ mem->pub.request_virt_sarray = request_virt_sarray;
+ mem->pub.request_virt_barray = request_virt_barray;
+ mem->pub.realize_virt_arrays = realize_virt_arrays;
+ mem->pub.access_virt_sarray = access_virt_sarray;
+ mem->pub.access_virt_barray = access_virt_barray;
+ mem->pub.free_pool = free_pool;
+ mem->pub.self_destruct = self_destruct;
+
+ /* Make MAX_ALLOC_CHUNK accessible to other modules */
+ mem->pub.max_alloc_chunk = MAX_ALLOC_CHUNK;
+
+ /* Initialize working state */
+ mem->pub.max_memory_to_use = max_to_use;
+
+ for (pool = JPOOL_NUMPOOLS-1; pool >= JPOOL_PERMANENT; pool--) {
+ mem->small_list[pool] = NULL;
+ mem->large_list[pool] = NULL;
+ }
+ mem->virt_sarray_list = NULL;
+ mem->virt_barray_list = NULL;
+
+ mem->total_space_allocated = SIZEOF(my_memory_mgr);
+
+ /* Declare ourselves open for business */
+ cinfo->mem = & mem->pub;
+
+ /* Check for an environment variable JPEGMEM; if found, override the
+ * default max_memory setting from jpeg_mem_init. Note that the
+ * surrounding application may again override this value.
+ * If your system doesn't support getenv(), define NO_GETENV to disable
+ * this feature.
+ */
+#ifndef NO_GETENV
+ { char * memenv;
+
+ if ((memenv = getenv("JPEGMEM")) != NULL) {
+ char ch = 'x';
+
+ if (sscanf(memenv, "%ld%c", &max_to_use, &ch) > 0) {
+ if (ch == 'm' || ch == 'M')
+ max_to_use *= 1000L;
+ mem->pub.max_memory_to_use = max_to_use * 1000L;
+ }
+ }
+ }
+#endif
+
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jmemnobs.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jmemnobs.c
new file mode 100644
index 0000000..eb8c337
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jmemnobs.c
@@ -0,0 +1,109 @@
+/*
+ * jmemnobs.c
+ *
+ * Copyright (C) 1992-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file provides a really simple implementation of the system-
+ * dependent portion of the JPEG memory manager. This implementation
+ * assumes that no backing-store files are needed: all required space
+ * can be obtained from malloc().
+ * This is very portable in the sense that it'll compile on almost anything,
+ * but you'd better have lots of main memory (or virtual memory) if you want
+ * to process big images.
+ * Note that the max_memory_to_use option is ignored by this implementation.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+#include "jmemsys.h" /* import the system-dependent declarations */
+
+#ifndef HAVE_STDLIB_H /* <stdlib.h> should declare malloc(),free() */
+extern void * malloc JPP((size_t size));
+extern void free JPP((void *ptr));
+#endif
+
+
+/*
+ * Memory allocation and freeing are controlled by the regular library
+ * routines malloc() and free().
+ */
+
+GLOBAL(void *)
+jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
+{
+ return (void *) malloc(sizeofobject);
+}
+
+GLOBAL(void)
+jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
+{
+ free(object);
+}
+
+
+/*
+ * "Large" objects are treated the same as "small" ones.
+ * NB: although we include FAR keywords in the routine declarations,
+ * this file won't actually work in 80x86 small/medium model; at least,
+ * you probably won't be able to process useful-size images in only 64KB.
+ */
+
+GLOBAL(void FAR *)
+jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
+{
+ return (void FAR *) malloc(sizeofobject);
+}
+
+GLOBAL(void)
+jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
+{
+ free(object);
+}
+
+
+/*
+ * This routine computes the total memory space available for allocation.
+ * Here we always say, "we got all you want bud!"
+ */
+
+GLOBAL(long)
+jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
+ long max_bytes_needed, long already_allocated)
+{
+ return max_bytes_needed;
+}
+
+
+/*
+ * Backing store (temporary file) management.
+ * Since jpeg_mem_available always promised the moon,
+ * this should never be called and we can just error out.
+ */
+
+GLOBAL(void)
+jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
+ long total_bytes_needed)
+{
+ ERREXIT(cinfo, JERR_NO_BACKING_STORE);
+}
+
+
+/*
+ * These routines take care of any system-dependent initialization and
+ * cleanup required. Here, there isn't any.
+ */
+
+GLOBAL(long)
+jpeg_mem_init (j_common_ptr cinfo)
+{
+ return 0; /* just set max_memory_to_use to 0 */
+}
+
+GLOBAL(void)
+jpeg_mem_term (j_common_ptr cinfo)
+{
+ /* no work */
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jmemsys.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jmemsys.h
new file mode 100644
index 0000000..86564bd
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jmemsys.h
@@ -0,0 +1,198 @@
+/*
+ * jmemsys.h
+ *
+ * Copyright (C) 1992-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This include file defines the interface between the system-independent
+ * and system-dependent portions of the JPEG memory manager. No other
+ * modules need include it. (The system-independent portion is jmemmgr.c;
+ * there are several different versions of the system-dependent portion.)
+ *
+ * This file works as-is for the system-dependent memory managers supplied
+ * in the IJG distribution. You may need to modify it if you write a
+ * custom memory manager. If system-dependent changes are needed in
+ * this file, the best method is to #ifdef them based on a configuration
+ * symbol supplied in jconfig.h, as we have done with USE_MSDOS_MEMMGR
+ * and USE_MAC_MEMMGR.
+ */
+
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_get_small jGetSmall
+#define jpeg_free_small jFreeSmall
+#define jpeg_get_large jGetLarge
+#define jpeg_free_large jFreeLarge
+#define jpeg_mem_available jMemAvail
+#define jpeg_open_backing_store jOpenBackStore
+#define jpeg_mem_init jMemInit
+#define jpeg_mem_term jMemTerm
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/*
+ * These two functions are used to allocate and release small chunks of
+ * memory. (Typically the total amount requested through jpeg_get_small is
+ * no more than 20K or so; this will be requested in chunks of a few K each.)
+ * Behavior should be the same as for the standard library functions malloc
+ * and free; in particular, jpeg_get_small must return NULL on failure.
+ * On most systems, these ARE malloc and free. jpeg_free_small is passed the
+ * size of the object being freed, just in case it's needed.
+ * On an 80x86 machine using small-data memory model, these manage near heap.
+ */
+
+EXTERN(void *) jpeg_get_small JPP((j_common_ptr cinfo, size_t sizeofobject));
+EXTERN(void) jpeg_free_small JPP((j_common_ptr cinfo, void * object,
+ size_t sizeofobject));
+
+/*
+ * These two functions are used to allocate and release large chunks of
+ * memory (up to the total free space designated by jpeg_mem_available).
+ * The interface is the same as above, except that on an 80x86 machine,
+ * far pointers are used. On most other machines these are identical to
+ * the jpeg_get/free_small routines; but we keep them separate anyway,
+ * in case a different allocation strategy is desirable for large chunks.
+ */
+
+EXTERN(void FAR *) jpeg_get_large JPP((j_common_ptr cinfo,
+ size_t sizeofobject));
+EXTERN(void) jpeg_free_large JPP((j_common_ptr cinfo, void FAR * object,
+ size_t sizeofobject));
+
+/*
+ * The macro MAX_ALLOC_CHUNK designates the maximum number of bytes that may
+ * be requested in a single call to jpeg_get_large (and jpeg_get_small for that
+ * matter, but that case should never come into play). This macro is needed
+ * to model the 64Kb-segment-size limit of far addressing on 80x86 machines.
+ * On those machines, we expect that jconfig.h will provide a proper value.
+ * On machines with 32-bit flat address spaces, any large constant may be used.
+ *
+ * NB: jmemmgr.c expects that MAX_ALLOC_CHUNK will be representable as type
+ * size_t and will be a multiple of sizeof(align_type).
+ */
+
+#ifndef MAX_ALLOC_CHUNK /* may be overridden in jconfig.h */
+#define MAX_ALLOC_CHUNK 1000000000L
+#endif
+
+/*
+ * This routine computes the total space still available for allocation by
+ * jpeg_get_large. If more space than this is needed, backing store will be
+ * used. NOTE: any memory already allocated must not be counted.
+ *
+ * There is a minimum space requirement, corresponding to the minimum
+ * feasible buffer sizes; jmemmgr.c will request that much space even if
+ * jpeg_mem_available returns zero. The maximum space needed, enough to hold
+ * all working storage in memory, is also passed in case it is useful.
+ * Finally, the total space already allocated is passed. If no better
+ * method is available, cinfo->mem->max_memory_to_use - already_allocated
+ * is often a suitable calculation.
+ *
+ * It is OK for jpeg_mem_available to underestimate the space available
+ * (that'll just lead to more backing-store access than is really necessary).
+ * However, an overestimate will lead to failure. Hence it's wise to subtract
+ * a slop factor from the true available space. 5% should be enough.
+ *
+ * On machines with lots of virtual memory, any large constant may be returned.
+ * Conversely, zero may be returned to always use the minimum amount of memory.
+ */
+
+EXTERN(long) jpeg_mem_available JPP((j_common_ptr cinfo,
+ long min_bytes_needed,
+ long max_bytes_needed,
+ long already_allocated));
+
+
+/*
+ * This structure holds whatever state is needed to access a single
+ * backing-store object. The read/write/close method pointers are called
+ * by jmemmgr.c to manipulate the backing-store object; all other fields
+ * are private to the system-dependent backing store routines.
+ */
+
+#define TEMP_NAME_LENGTH 64 /* max length of a temporary file's name */
+
+
+#ifdef USE_MSDOS_MEMMGR /* DOS-specific junk */
+
+typedef unsigned short XMSH; /* type of extended-memory handles */
+typedef unsigned short EMSH; /* type of expanded-memory handles */
+
+typedef union {
+ short file_handle; /* DOS file handle if it's a temp file */
+ XMSH xms_handle; /* handle if it's a chunk of XMS */
+ EMSH ems_handle; /* handle if it's a chunk of EMS */
+} handle_union;
+
+#endif /* USE_MSDOS_MEMMGR */
+
+#ifdef USE_MAC_MEMMGR /* Mac-specific junk */
+#include <Files.h>
+#endif /* USE_MAC_MEMMGR */
+
+
+typedef struct backing_store_struct * backing_store_ptr;
+
+typedef struct backing_store_struct {
+ /* Methods for reading/writing/closing this backing-store object */
+ JTQT_METHOD(void, read_backing_store, (j_common_ptr cinfo,
+ backing_store_ptr info,
+ void FAR * buffer_address,
+ long file_offset, long byte_count));
+ JTQT_METHOD(void, write_backing_store, (j_common_ptr cinfo,
+ backing_store_ptr info,
+ void FAR * buffer_address,
+ long file_offset, long byte_count));
+ JTQT_METHOD(void, close_backing_store, (j_common_ptr cinfo,
+ backing_store_ptr info));
+
+ /* Private fields for system-dependent backing-store management */
+#ifdef USE_MSDOS_MEMMGR
+ /* For the MS-DOS manager (jmemdos.c), we need: */
+ handle_union handle; /* reference to backing-store storage object */
+ char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
+#else
+#ifdef USE_MAC_MEMMGR
+ /* For the Mac manager (jmemmac.c), we need: */
+ short temp_file; /* file reference number to temp file */
+ FSSpec tempSpec; /* the FSSpec for the temp file */
+ char temp_name[TEMP_NAME_LENGTH]; /* name if it's a file */
+#else
+ /* For a typical implementation with temp files, we need: */
+ FILE * temp_file; /* stdio reference to temp file */
+ char temp_name[TEMP_NAME_LENGTH]; /* name of temp file */
+#endif
+#endif
+} backing_store_info;
+
+
+/*
+ * Initial opening of a backing-store object. This must fill in the
+ * read/write/close pointers in the object. The read/write routines
+ * may take an error exit if the specified maximum file size is exceeded.
+ * (If jpeg_mem_available always returns a large value, this routine can
+ * just take an error exit.)
+ */
+
+EXTERN(void) jpeg_open_backing_store JPP((j_common_ptr cinfo,
+ backing_store_ptr info,
+ long total_bytes_needed));
+
+
+/*
+ * These routines take care of any system-dependent initialization and
+ * cleanup required. jpeg_mem_init will be called before anything is
+ * allocated (and, therefore, nothing in cinfo is of use except the error
+ * manager pointer). It should return a suitable default value for
+ * max_memory_to_use; this may subsequently be overridden by the surrounding
+ * application. (Note that max_memory_to_use is only important if
+ * jpeg_mem_available chooses to consult it ... no one else will.)
+ * jpeg_mem_term may assume that all requested memory has been freed and that
+ * all opened backing-store objects have been closed.
+ */
+
+EXTERN(long) jpeg_mem_init JPP((j_common_ptr cinfo));
+EXTERN(void) jpeg_mem_term JPP((j_common_ptr cinfo));
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jmorecfg.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jmorecfg.h
new file mode 100644
index 0000000..dedab7f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jmorecfg.h
@@ -0,0 +1,363 @@
+/*
+ * jmorecfg.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains additional configuration options that customize the
+ * JPEG software for special applications or support machine-dependent
+ * optimizations. Most users will not need to touch this file.
+ */
+
+
+/*
+ * Define BITS_IN_JSAMPLE as either
+ * 8 for 8-bit sample values (the usual setting)
+ * 12 for 12-bit sample values
+ * Only 8 and 12 are legal data precisions for lossy JPEG according to the
+ * JPEG standard, and the IJG code does not support anything else!
+ * We do not support run-time selection of data precision, sorry.
+ */
+
+#define BITS_IN_JSAMPLE 8 /* use 8 or 12 */
+
+
+/*
+ * Maximum number of components (color channels) allowed in JPEG image.
+ * To meet the letter of the JPEG spec, set this to 255. However, darn
+ * few applications need more than 4 channels (maybe 5 for CMYK + alpha
+ * tqmask). We recommend 10 as a reasonable compromise; use 4 if you are
+ * really short on memory. (Each allowed component costs a hundred or so
+ * bytes of storage, whether actually used in an image or not.)
+ */
+
+#define MAX_COMPONENTS 10 /* maximum number of image components */
+
+
+/*
+ * Basic data types.
+ * You may need to change these if you have a machine with unusual data
+ * type sizes; for example, "char" not 8 bits, "short" not 16 bits,
+ * or "long" not 32 bits. We don't care whether "int" is 16 or 32 bits,
+ * but it had better be at least 16.
+ */
+
+/* Representation of a single sample (pixel element value).
+ * We frequently allocate large arrays of these, so it's important to keep
+ * them small. But if you have memory to burn and access to char or short
+ * arrays is very slow on your hardware, you might want to change these.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+/* JSAMPLE should be the smallest type that will hold the values 0..255.
+ * You can use a signed char by having GETJSAMPLE tqmask it with 0xFF.
+ */
+
+#ifdef HAVE_UNSIGNED_CHAR
+
+typedef unsigned char JSAMPLE;
+#define GETJSAMPLE(value) ((int) (value))
+
+#else /* not HAVE_UNSIGNED_CHAR */
+
+typedef char JSAMPLE;
+#ifdef CHAR_IS_UNSIGNED
+#define GETJSAMPLE(value) ((int) (value))
+#else
+#define GETJSAMPLE(value) ((int) (value) & 0xFF)
+#endif /* CHAR_IS_UNSIGNED */
+
+#endif /* HAVE_UNSIGNED_CHAR */
+
+#define MAXJSAMPLE 255
+#define CENTERJSAMPLE 128
+
+#endif /* BITS_IN_JSAMPLE == 8 */
+
+
+#if BITS_IN_JSAMPLE == 12
+/* JSAMPLE should be the smallest type that will hold the values 0..4095.
+ * On nearly all machines "short" will do nicely.
+ */
+
+typedef short JSAMPLE;
+#define GETJSAMPLE(value) ((int) (value))
+
+#define MAXJSAMPLE 4095
+#define CENTERJSAMPLE 2048
+
+#endif /* BITS_IN_JSAMPLE == 12 */
+
+
+/* Representation of a DCT frequency coefficient.
+ * This should be a signed value of at least 16 bits; "short" is usually OK.
+ * Again, we allocate large arrays of these, but you can change to int
+ * if you have memory to burn and "short" is really slow.
+ */
+
+typedef short JCOEF;
+
+
+/* Compressed datastreams are represented as arrays of JOCTET.
+ * These must be EXACTLY 8 bits wide, at least once they are written to
+ * external storage. Note that when using the stdio data source/destination
+ * managers, this is also the data type passed to fread/fwrite.
+ */
+
+#ifdef HAVE_UNSIGNED_CHAR
+
+typedef unsigned char JOCTET;
+#define GETJOCTET(value) (value)
+
+#else /* not HAVE_UNSIGNED_CHAR */
+
+typedef char JOCTET;
+#ifdef CHAR_IS_UNSIGNED
+#define GETJOCTET(value) (value)
+#else
+#define GETJOCTET(value) ((value) & 0xFF)
+#endif /* CHAR_IS_UNSIGNED */
+
+#endif /* HAVE_UNSIGNED_CHAR */
+
+
+/* These typedefs are used for various table entries and so forth.
+ * They must be at least as wide as specified; but making them too big
+ * won't cost a huge amount of memory, so we don't provide special
+ * extraction code like we did for JSAMPLE. (In other words, these
+ * typedefs live at a different point on the speed/space tradeoff curve.)
+ */
+
+/* UINT8 must hold at least the values 0..255. */
+
+#ifdef HAVE_UNSIGNED_CHAR
+typedef unsigned char UINT8;
+#else /* not HAVE_UNSIGNED_CHAR */
+#ifdef CHAR_IS_UNSIGNED
+typedef char UINT8;
+#else /* not CHAR_IS_UNSIGNED */
+typedef short UINT8;
+#endif /* CHAR_IS_UNSIGNED */
+#endif /* HAVE_UNSIGNED_CHAR */
+
+/* UINT16 must hold at least the values 0..65535. */
+
+#ifdef HAVE_UNSIGNED_SHORT
+typedef unsigned short UINT16;
+#else /* not HAVE_UNSIGNED_SHORT */
+typedef unsigned int UINT16;
+#endif /* HAVE_UNSIGNED_SHORT */
+
+/* INT16 must hold at least the values -32768..32767. */
+
+#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
+typedef short INT16;
+#endif
+
+/* INT32 must hold at least signed 32-bit values. */
+
+#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
+typedef long INT32;
+#endif
+
+/* Datatype used for image dimensions. The JPEG standard only supports
+ * images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
+ * "unsigned int" is sufficient on all machines. However, if you need to
+ * handle larger images and you don't mind deviating from the spec, you
+ * can change this datatype.
+ */
+
+typedef unsigned int JDIMENSION;
+
+#define JPEG_MAX_DIMENSION 65500L /* a tad under 64K to prevent overflows */
+
+
+/* These macros are used in all function definitions and extern declarations.
+ * You could modify them if you need to change function linkage conventions;
+ * in particular, you'll need to do that to make the library a Windows DLL.
+ * Another application is to make all functions global for use with debuggers
+ * or code profilers that require it.
+ */
+
+/* a function called through method pointers: */
+#define METHODDEF(type) static type
+/* a function used only in its module: */
+#define LOCAL(type) static type
+/* a function referenced thru EXTERNs: */
+#define GLOBAL(type) type
+/* a reference to a GLOBAL function: */
+#define EXTERN(type) extern type
+
+
+/* This macro is used to declare a "method", that is, a function pointer.
+ * We want to supply prototype parameters if the compiler can cope.
+ * Note that the arglist parameter must be parenthesized!
+ * Again, you can customize this if you need special linkage keywords.
+ */
+
+#ifdef HAVE_PROTOTYPES
+#define JTQT_METHOD(type,methodname,arglist) type (*methodname) arglist
+#else
+#define JTQT_METHOD(type,methodname,arglist) type (*methodname) ()
+#endif
+
+
+/* Here is the pseudo-keyword for declaring pointers that must be "far"
+ * on 80x86 machines. Most of the specialized coding for 80x86 is handled
+ * by just saying "FAR *" where such a pointer is needed. In a few places
+ * explicit coding is needed; see uses of the NEED_FAR_POINTERS symbol.
+ */
+
+#ifdef NEED_FAR_POINTERS
+#define FAR far
+#else
+#define FAR
+#endif
+
+
+/*
+ * On a few systems, type boolean and/or its values FALSE, TRUE may appear
+ * in standard header files. Or you may have conflicts with application-
+ * specific header files that you want to include together with these files.
+ * Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
+ */
+
+#ifndef HAVE_BOOLEAN
+typedef int boolean;
+#endif
+#ifndef FALSE /* in case these macros already exist */
+#define FALSE 0 /* values of boolean */
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+
+/*
+ * The remaining options affect code selection within the JPEG library,
+ * but they don't need to be visible to most applications using the library.
+ * To minimize application namespace pollution, the symbols won't be
+ * defined unless JPEG_INTERNALS or JPEG_INTERNAL_OPTIONS has been defined.
+ */
+
+#ifdef JPEG_INTERNALS
+#define JPEG_INTERNAL_OPTIONS
+#endif
+
+#ifdef JPEG_INTERNAL_OPTIONS
+
+
+/*
+ * These defines indicate whether to include various optional functions.
+ * Undefining some of these symbols will produce a smaller but less capable
+ * library. Note that you can leave certain source files out of the
+ * compilation/linking process if you've #undef'd the corresponding symbols.
+ * (You may HAVE to do that if your compiler doesn't like null source files.)
+ */
+
+/* Arithmetic coding is unsupported for legal reasons. Complaints to IBM. */
+
+/* Capability options common to encoder and decoder: */
+
+#define DCT_ISLOW_SUPPORTED /* slow but accurate integer algorithm */
+#define DCT_IFAST_SUPPORTED /* faster, less accurate integer method */
+#define DCT_FLOAT_SUPPORTED /* floating-point: accurate, fast on fast HW */
+
+/* Encoder capability options: */
+
+#undef C_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
+#define C_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define C_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
+#define ENTROPY_OPT_SUPPORTED /* Optimization of entropy coding parms? */
+/* Note: if you selected 12-bit data precision, it is dangerous to turn off
+ * ENTROPY_OPT_SUPPORTED. The standard Huffman tables are only good for 8-bit
+ * precision, so jchuff.c normally uses entropy optimization to compute
+ * usable tables for higher precision. If you don't want to do optimization,
+ * you'll have to supply different default Huffman tables.
+ * The exact same statements apply for progressive JPEG: the default tables
+ * don't work for progressive mode. (This may get fixed, however.)
+ */
+#define INPUT_SMOOTHING_SUPPORTED /* Input image smoothing option? */
+
+/* Decoder capability options: */
+
+#undef D_ARITH_CODING_SUPPORTED /* Arithmetic coding back end? */
+#define D_MULTISCAN_FILES_SUPPORTED /* Multiple-scan JPEG files? */
+#define D_PROGRESSIVE_SUPPORTED /* Progressive JPEG? (Requires MULTISCAN)*/
+#define SAVE_MARKERS_SUPPORTED /* jpeg_save_markers() needed? */
+#define BLOCK_SMOOTHING_SUPPORTED /* Block smoothing? (Progressive only) */
+#define IDCT_SCALING_SUPPORTED /* Output rescaling via IDCT? */
+#undef UPSAMPLE_SCALING_SUPPORTED /* Output rescaling at upsample stage? */
+#define UPSAMPLE_MERGING_SUPPORTED /* Fast path for sloppy upsampling? */
+#define TQUANT_1PASS_SUPPORTED /* 1-pass color quantization? */
+#define TQUANT_2PASS_SUPPORTED /* 2-pass color quantization? */
+
+/* more capability options later, no doubt */
+
+
+/*
+ * Ordering of RGB data in scanlines passed to or from the application.
+ * If your application wants to deal with data in the order B,G,R, just
+ * change these macros. You can also deal with formats such as R,G,B,X
+ * (one extra byte per pixel) by changing RGB_PIXELSIZE. Note that changing
+ * the offsets will also change the order in which colormap data is organized.
+ * RESTRICTIONS:
+ * 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
+ * 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
+ * useful if you are using JPEG color spaces other than YCbCr or grayscale.
+ * 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
+ * is not 3 (they don't understand about dummy color components!). So you
+ * can't use color quantization if you change that value.
+ */
+
+#define RGB_RED 0 /* Offset of Red in an RGB scanline element */
+#define RGB_GREEN 1 /* Offset of Green */
+#define RGB_BLUE 2 /* Offset of Blue */
+#define RGB_PIXELSIZE 3 /* JSAMPLEs per RGB scanline element */
+
+
+/* Definitions for speed-related optimizations. */
+
+
+/* If your compiler supports inline functions, define INLINE
+ * as the inline keyword; otherwise define it as empty.
+ */
+
+#ifndef INLINE
+#ifdef __GNUC__ /* for instance, GNU C knows about inline */
+#define INLINE __inline__
+#endif
+#ifndef INLINE
+#define INLINE /* default is to define it as empty */
+#endif
+#endif
+
+
+/* On some machines (notably 68000 series) "int" is 32 bits, but multiplying
+ * two 16-bit shorts is faster than multiplying two ints. Define MULTIPLIER
+ * as short on such a machine. MULTIPLIER must be at least 16 bits wide.
+ */
+
+#ifndef MULTIPLIER
+#define MULTIPLIER int /* type for fastest integer multiply */
+#endif
+
+
+/* FAST_FLOAT should be either float or double, whichever is done faster
+ * by your compiler. (Note that this type is only used in the floating point
+ * DCT routines, so it only matters if you've defined DCT_FLOAT_SUPPORTED.)
+ * Typically, float is faster in ANSI C compilers, while double is faster in
+ * pre-ANSI compilers (because they insist on converting to double anyway).
+ * The code below therefore chooses float if we have ANSI-style prototypes.
+ */
+
+#ifndef FAST_FLOAT
+#ifdef HAVE_PROTOTYPES
+#define FAST_FLOAT float
+#else
+#define FAST_FLOAT double
+#endif
+#endif
+
+#endif /* JPEG_INTERNAL_OPTIONS */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jpegint.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jpegint.h
new file mode 100644
index 0000000..9d00c59
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jpegint.h
@@ -0,0 +1,392 @@
+/*
+ * jpegint.h
+ *
+ * Copyright (C) 1991-1997, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file provides common declarations for the various JPEG modules.
+ * These declarations are considered internal to the JPEG library; most
+ * applications using the library shouldn't need to include this file.
+ */
+
+
+/* Declarations for both compression & decompression */
+
+typedef enum { /* Operating modes for buffer controllers */
+ JBUF_PASS_THRU, /* Plain stripwise operation */
+ /* Remaining modes require a full-image buffer to have been created */
+ JBUF_SAVE_SOURCE, /* Run source subobject only, save output */
+ JBUF_CRANK_DEST, /* Run dest subobject only, using saved data */
+ JBUF_SAVE_AND_PASS /* Run both subobjects, save output */
+} J_BUF_MODE;
+
+/* Values of global_state field (jdapi.c has some dependencies on ordering!) */
+#define CSTATE_START 100 /* after create_compress */
+#define CSTATE_SCANNING 101 /* start_compress done, write_scanlines OK */
+#define CSTATE_RAW_OK 102 /* start_compress done, write_raw_data OK */
+#define CSTATE_WRCOEFS 103 /* jpeg_write_coefficients done */
+#define DSTATE_START 200 /* after create_decompress */
+#define DSTATE_INHEADER 201 /* reading header markers, no SOS yet */
+#define DSTATE_READY 202 /* found SOS, ready for start_decompress */
+#define DSTATE_PRELOAD 203 /* reading multiscan file in start_decompress*/
+#define DSTATE_PRESCAN 204 /* performing dummy pass for 2-pass quant */
+#define DSTATE_SCANNING 205 /* start_decompress done, read_scanlines OK */
+#define DSTATE_RAW_OK 206 /* start_decompress done, read_raw_data OK */
+#define DSTATE_BUFIMAGE 207 /* expecting jpeg_start_output */
+#define DSTATE_BUFPOST 208 /* looking for SOS/EOI in jpeg_finish_output */
+#define DSTATE_RDCOEFS 209 /* reading file in jpeg_read_coefficients */
+#define DSTATE_STOPPING 210 /* looking for EOI in jpeg_finish_decompress */
+
+
+/* Declarations for compression modules */
+
+/* Master control module */
+struct jpeg_comp_master {
+ JTQT_METHOD(void, prepare_for_pass, (j_compress_ptr cinfo));
+ JTQT_METHOD(void, pass_startup, (j_compress_ptr cinfo));
+ JTQT_METHOD(void, finish_pass, (j_compress_ptr cinfo));
+
+ /* State variables made visible to other modules */
+ boolean call_pass_startup; /* True if pass_startup must be called */
+ boolean is_last_pass; /* True during last pass */
+};
+
+/* Main buffer control (downsampled-data buffer) */
+struct jpeg_c_main_controller {
+ JTQT_METHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
+ JTQT_METHOD(void, process_data, (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail));
+};
+
+/* Compression preprocessing (downsampling input buffer control) */
+struct jpeg_c_prep_controller {
+ JTQT_METHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
+ JTQT_METHOD(void, pre_process_data, (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf,
+ JDIMENSION *in_row_ctr,
+ JDIMENSION in_rows_avail,
+ JSAMPIMAGE output_buf,
+ JDIMENSION *out_row_group_ctr,
+ JDIMENSION out_row_groups_avail));
+};
+
+/* Coefficient buffer control */
+struct jpeg_c_coef_controller {
+ JTQT_METHOD(void, start_pass, (j_compress_ptr cinfo, J_BUF_MODE pass_mode));
+ JTQT_METHOD(boolean, compress_data, (j_compress_ptr cinfo,
+ JSAMPIMAGE input_buf));
+};
+
+/* Colorspace conversion */
+struct jpeg_color_converter {
+ JTQT_METHOD(void, start_pass, (j_compress_ptr cinfo));
+ JTQT_METHOD(void, color_convert, (j_compress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPIMAGE output_buf,
+ JDIMENSION output_row, int num_rows));
+};
+
+/* Downsampling */
+struct jpeg_downsampler {
+ JTQT_METHOD(void, start_pass, (j_compress_ptr cinfo));
+ JTQT_METHOD(void, downsample, (j_compress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION in_row_index,
+ JSAMPIMAGE output_buf,
+ JDIMENSION out_row_group_index));
+
+ boolean need_context_rows; /* TRUE if need rows above & below */
+};
+
+/* Forward DCT (also controls coefficient quantization) */
+struct jpeg_forward_dct {
+ JTQT_METHOD(void, start_pass, (j_compress_ptr cinfo));
+ /* perhaps this should be an array??? */
+ JTQT_METHOD(void, forward_DCT, (j_compress_ptr cinfo,
+ jpeg_component_info * compptr,
+ JSAMPARRAY sample_data, JBLOCKROW coef_blocks,
+ JDIMENSION start_row, JDIMENSION start_col,
+ JDIMENSION num_blocks));
+};
+
+/* Entropy encoding */
+struct jpeg_entropy_encoder {
+ JTQT_METHOD(void, start_pass, (j_compress_ptr cinfo, boolean gather_statistics));
+ JTQT_METHOD(boolean, encode_mcu, (j_compress_ptr cinfo, JBLOCKROW *MCU_data));
+ JTQT_METHOD(void, finish_pass, (j_compress_ptr cinfo));
+};
+
+/* Marker writing */
+struct jpeg_marker_writer {
+ JTQT_METHOD(void, write_file_header, (j_compress_ptr cinfo));
+ JTQT_METHOD(void, write_frame_header, (j_compress_ptr cinfo));
+ JTQT_METHOD(void, write_scan_header, (j_compress_ptr cinfo));
+ JTQT_METHOD(void, write_file_trailer, (j_compress_ptr cinfo));
+ JTQT_METHOD(void, write_tables_only, (j_compress_ptr cinfo));
+ /* These routines are exported to allow insertion of extra markers */
+ /* Probably only COM and APPn markers should be written this way */
+ JTQT_METHOD(void, write_marker_header, (j_compress_ptr cinfo, int marker,
+ unsigned int datalen));
+ JTQT_METHOD(void, write_marker_byte, (j_compress_ptr cinfo, int val));
+};
+
+
+/* Declarations for decompression modules */
+
+/* Master control module */
+struct jpeg_decomp_master {
+ JTQT_METHOD(void, prepare_for_output_pass, (j_decompress_ptr cinfo));
+ JTQT_METHOD(void, finish_output_pass, (j_decompress_ptr cinfo));
+
+ /* State variables made visible to other modules */
+ boolean is_dummy_pass; /* True during 1st pass for 2-pass quant */
+};
+
+/* Input control module */
+struct jpeg_input_controller {
+ JTQT_METHOD(int, consume_input, (j_decompress_ptr cinfo));
+ JTQT_METHOD(void, reset_input_controller, (j_decompress_ptr cinfo));
+ JTQT_METHOD(void, start_input_pass, (j_decompress_ptr cinfo));
+ JTQT_METHOD(void, finish_input_pass, (j_decompress_ptr cinfo));
+
+ /* State variables made visible to other modules */
+ boolean has_multiple_scans; /* True if file has multiple scans */
+ boolean eoi_reached; /* True when EOI has been consumed */
+};
+
+/* Main buffer control (downsampled-data buffer) */
+struct jpeg_d_main_controller {
+ JTQT_METHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
+ JTQT_METHOD(void, process_data, (j_decompress_ptr cinfo,
+ JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+};
+
+/* Coefficient buffer control */
+struct jpeg_d_coef_controller {
+ JTQT_METHOD(void, start_input_pass, (j_decompress_ptr cinfo));
+ JTQT_METHOD(int, consume_data, (j_decompress_ptr cinfo));
+ JTQT_METHOD(void, start_output_pass, (j_decompress_ptr cinfo));
+ JTQT_METHOD(int, decompress_data, (j_decompress_ptr cinfo,
+ JSAMPIMAGE output_buf));
+ /* Pointer to array of coefficient virtual arrays, or NULL if none */
+ jvirt_barray_ptr *coef_arrays;
+};
+
+/* Decompression postprocessing (color quantization buffer control) */
+struct jpeg_d_post_controller {
+ JTQT_METHOD(void, start_pass, (j_decompress_ptr cinfo, J_BUF_MODE pass_mode));
+ JTQT_METHOD(void, post_process_data, (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf,
+ JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf,
+ JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+};
+
+/* Marker reading & parsing */
+struct jpeg_marker_reader {
+ JTQT_METHOD(void, reset_marker_reader, (j_decompress_ptr cinfo));
+ /* Read markers until SOS or EOI.
+ * Returns same codes as are defined for jpeg_consume_input:
+ * JPEG_SUSPENDED, JPEG_REACHED_SOS, or JPEG_REACHED_EOI.
+ */
+ JTQT_METHOD(int, read_markers, (j_decompress_ptr cinfo));
+ /* Read a restart marker --- exported for use by entropy decoder only */
+ jpeg_marker_parser_method read_restart_marker;
+
+ /* State of marker reader --- nominally internal, but applications
+ * supplying COM or APPn handlers might like to know the state.
+ */
+ boolean saw_SOI; /* found SOI? */
+ boolean saw_SOF; /* found SOF? */
+ int next_restart_num; /* next restart number expected (0-7) */
+ unsigned int discarded_bytes; /* # of bytes skipped looking for a marker */
+};
+
+/* Entropy decoding */
+struct jpeg_entropy_decoder {
+ JTQT_METHOD(void, start_pass, (j_decompress_ptr cinfo));
+ JTQT_METHOD(boolean, decode_mcu, (j_decompress_ptr cinfo,
+ JBLOCKROW *MCU_data));
+
+ /* This is here to share code between baseline and progressive decoders; */
+ /* other modules probably should not use it */
+ boolean insufficient_data; /* set TRUE after emitting warning */
+};
+
+/* Inverse DCT (also performs dequantization) */
+typedef JTQT_METHOD(void, inverse_DCT_method_ptr,
+ (j_decompress_ptr cinfo, jpeg_component_info * compptr,
+ JCOEFPTR coef_block,
+ JSAMPARRAY output_buf, JDIMENSION output_col));
+
+struct jpeg_inverse_dct {
+ JTQT_METHOD(void, start_pass, (j_decompress_ptr cinfo));
+ /* It is useful to allow each component to have a separate IDCT method. */
+ inverse_DCT_method_ptr inverse_DCT[MAX_COMPONENTS];
+};
+
+/* Upsampling (note that upsampler must also call color converter) */
+struct jpeg_upsampler {
+ JTQT_METHOD(void, start_pass, (j_decompress_ptr cinfo));
+ JTQT_METHOD(void, upsample, (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf,
+ JDIMENSION *in_row_group_ctr,
+ JDIMENSION in_row_groups_avail,
+ JSAMPARRAY output_buf,
+ JDIMENSION *out_row_ctr,
+ JDIMENSION out_rows_avail));
+
+ boolean need_context_rows; /* TRUE if need rows above & below */
+};
+
+/* Colorspace conversion */
+struct jpeg_color_deconverter {
+ JTQT_METHOD(void, start_pass, (j_decompress_ptr cinfo));
+ JTQT_METHOD(void, color_convert, (j_decompress_ptr cinfo,
+ JSAMPIMAGE input_buf, JDIMENSION input_row,
+ JSAMPARRAY output_buf, int num_rows));
+};
+
+/* Color quantization or color precision reduction */
+struct jpeg_color_quantizer {
+ JTQT_METHOD(void, start_pass, (j_decompress_ptr cinfo, boolean is_pre_scan));
+ JTQT_METHOD(void, color_quantize, (j_decompress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPARRAY output_buf,
+ int num_rows));
+ JTQT_METHOD(void, finish_pass, (j_decompress_ptr cinfo));
+ JTQT_METHOD(void, new_color_map, (j_decompress_ptr cinfo));
+};
+
+
+/* Miscellaneous useful macros */
+
+#undef MAX
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+#undef MIN
+#define MIN(a,b) ((a) < (b) ? (a) : (b))
+
+
+/* We assume that right shift corresponds to signed division by 2 with
+ * rounding towards minus infinity. This is correct for typical "arithmetic
+ * shift" instructions that shift in copies of the sign bit. But some
+ * C compilers implement >> with an unsigned shift. For these machines you
+ * must define RIGHT_SHIFT_IS_UNSIGNED.
+ * RIGHT_SHIFT provides a proper signed right shift of an INT32 quantity.
+ * It is only applied with constant shift counts. SHIFT_TEMPS must be
+ * included in the variables of any routine using RIGHT_SHIFT.
+ */
+
+#ifdef RIGHT_SHIFT_IS_UNSIGNED
+#define SHIFT_TEMPS INT32 shift_temp;
+#define RIGHT_SHIFT(x,shft) \
+ ((shift_temp = (x)) < 0 ? \
+ (shift_temp >> (shft)) | ((~((INT32) 0)) << (32-(shft))) : \
+ (shift_temp >> (shft)))
+#else
+#define SHIFT_TEMPS
+#define RIGHT_SHIFT(x,shft) ((x) >> (shft))
+#endif
+
+
+/* Short forms of external names for systems with brain-damaged linkers. */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jinit_compress_master jICompress
+#define jinit_c_master_control jICMaster
+#define jinit_c_main_controller jICMainC
+#define jinit_c_prep_controller jICPrepC
+#define jinit_c_coef_controller jICCoefC
+#define jinit_color_converter jICColor
+#define jinit_downsampler jIDownsampler
+#define jinit_forward_dct jIFDCT
+#define jinit_huff_encoder jIHEncoder
+#define jinit_phuff_encoder jIPHEncoder
+#define jinit_marker_writer jIMWriter
+#define jinit_master_decompress jIDMaster
+#define jinit_d_main_controller jIDMainC
+#define jinit_d_coef_controller jIDCoefC
+#define jinit_d_post_controller jIDPostC
+#define jinit_input_controller jIInCtlr
+#define jinit_marker_reader jIMReader
+#define jinit_huff_decoder jIHDecoder
+#define jinit_phuff_decoder jIPHDecoder
+#define jinit_inverse_dct jIIDCT
+#define jinit_upsampler jIUpsampler
+#define jinit_color_deconverter jIDColor
+#define jinit_1pass_quantizer jI1Quant
+#define jinit_2pass_quantizer jI2Quant
+#define jinit_merged_upsampler jIMUpsampler
+#define jinit_memory_mgr jIMemMgr
+#define jdiv_round_up jDivRound
+#define jround_up jRound
+#define jcopy_sample_rows jCopySamples
+#define jcopy_block_row jCopyBlocks
+#define jzero_far jZeroFar
+#define jpeg_zigzag_order jZIGTable
+#define jpeg_natural_order jZAGTable
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/* Compression module initialization routines */
+EXTERN(void) jinit_compress_master JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_c_master_control JPP((j_compress_ptr cinfo,
+ boolean transcode_only));
+EXTERN(void) jinit_c_main_controller JPP((j_compress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_c_prep_controller JPP((j_compress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_c_coef_controller JPP((j_compress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_color_converter JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_downsampler JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_forward_dct JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_huff_encoder JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_phuff_encoder JPP((j_compress_ptr cinfo));
+EXTERN(void) jinit_marker_writer JPP((j_compress_ptr cinfo));
+/* Decompression module initialization routines */
+EXTERN(void) jinit_master_decompress JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_d_main_controller JPP((j_decompress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_d_coef_controller JPP((j_decompress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_d_post_controller JPP((j_decompress_ptr cinfo,
+ boolean need_full_buffer));
+EXTERN(void) jinit_input_controller JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_marker_reader JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_huff_decoder JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_phuff_decoder JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_inverse_dct JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_upsampler JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_color_deconverter JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_1pass_quantizer JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_2pass_quantizer JPP((j_decompress_ptr cinfo));
+EXTERN(void) jinit_merged_upsampler JPP((j_decompress_ptr cinfo));
+/* Memory manager initialization */
+EXTERN(void) jinit_memory_mgr JPP((j_common_ptr cinfo));
+
+/* Utility routines in jutils.c */
+EXTERN(long) jdiv_round_up JPP((long a, long b));
+EXTERN(long) jround_up JPP((long a, long b));
+EXTERN(void) jcopy_sample_rows JPP((JSAMPARRAY input_array, int source_row,
+ JSAMPARRAY output_array, int dest_row,
+ int num_rows, JDIMENSION num_cols));
+EXTERN(void) jcopy_block_row JPP((JBLOCKROW input_row, JBLOCKROW output_row,
+ JDIMENSION num_blocks));
+EXTERN(void) jzero_far JPP((void FAR * target, size_t bytestozero));
+/* Constant tables in jutils.c */
+#if 0 /* This table is not actually needed in v6a */
+extern const int jpeg_zigzag_order[]; /* natural coef order to zigzag order */
+#endif
+extern const int jpeg_natural_order[]; /* zigzag coef order to natural order */
+
+/* Suppress undefined-structure complaints if necessary. */
+
+#ifdef INCOMPLETE_TYPES_BROKEN
+#ifndef AM_MEMORY_MANAGER /* only jmemmgr.c defines these */
+struct jvirt_sarray_control { long dummy; };
+struct jvirt_barray_control { long dummy; };
+#endif
+#endif /* INCOMPLETE_TYPES_BROKEN */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jpeglib.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jpeglib.h
new file mode 100644
index 0000000..dfb10f8
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jpeglib.h
@@ -0,0 +1,1096 @@
+/*
+ * jpeglib.h
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file defines the application interface for the JPEG library.
+ * Most applications using the library need only include this file,
+ * and perhaps jerror.h if they want to know the exact error codes.
+ */
+
+#ifndef JPEGLIB_H
+#define JPEGLIB_H
+
+/*
+ * First we include the configuration files that record how this
+ * installation of the JPEG library is set up. jconfig.h can be
+ * generated automatically for many systems. jmorecfg.h tqcontains
+ * manual configuration options that most people need not worry about.
+ */
+
+#ifndef JCONFIG_INCLUDED /* in case jinclude.h already did */
+#include "jconfig.h" /* widely used configuration options */
+#endif
+#include "jmorecfg.h" /* seldom changed options */
+
+
+/* Version ID for the JPEG library.
+ * Might be useful for tests like "#if JPEG_LIB_VERSION >= 60".
+ */
+
+#define JPEG_LIB_VERSION 62 /* Version 6b */
+
+
+/* Various constants determining the sizes of things.
+ * All of these are specified by the JPEG standard, so don't change them
+ * if you want to be compatible.
+ */
+
+#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
+#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
+#define NUM_TQUANT_TBLS 4 /* Quantization tables are numbered 0..3 */
+#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */
+#define NUM_ARITH_TBLS 16 /* Arith-coding tables are numbered 0..15 */
+#define MAX_COMPS_IN_SCAN 4 /* JPEG limit on # of components in one scan */
+#define MAX_SAMP_FACTOR 4 /* JPEG limit on sampling factors */
+/* Unfortunately, some bozo at Adobe saw no reason to be bound by the standard;
+ * the PostScript DCT filter can emit files with many more than 10 blocks/MCU.
+ * If you happen to run across such a file, you can up D_MAX_BLOCKS_IN_MCU
+ * to handle it. We even let you do this from the jconfig.h file. However,
+ * we strongly discourage changing C_MAX_BLOCKS_IN_MCU; just because Adobe
+ * sometimes emits noncompliant files doesn't mean you should too.
+ */
+#define C_MAX_BLOCKS_IN_MCU 10 /* compressor's limit on blocks per MCU */
+#ifndef D_MAX_BLOCKS_IN_MCU
+#define D_MAX_BLOCKS_IN_MCU 10 /* decompressor's limit on blocks per MCU */
+#endif
+
+
+/* Data structures for images (arrays of samples and of DCT coefficients).
+ * On 80x86 machines, the image arrays are too big for near pointers,
+ * but the pointer arrays can fit in near memory.
+ */
+
+typedef JSAMPLE FAR *JSAMPROW; /* ptr to one image row of pixel samples. */
+typedef JSAMPROW *JSAMPARRAY; /* ptr to some rows (a 2-D sample array) */
+typedef JSAMPARRAY *JSAMPIMAGE; /* a 3-D sample array: top index is color */
+
+typedef JCOEF JBLOCK[DCTSIZE2]; /* one block of coefficients */
+typedef JBLOCK FAR *JBLOCKROW; /* pointer to one row of coefficient blocks */
+typedef JBLOCKROW *JBLOCKARRAY; /* a 2-D array of coefficient blocks */
+typedef JBLOCKARRAY *JBLOCKIMAGE; /* a 3-D array of coefficient blocks */
+
+typedef JCOEF FAR *JCOEFPTR; /* useful in a couple of places */
+
+
+/* Types for JPEG compression parameters and working tables. */
+
+
+/* DCT coefficient quantization tables. */
+
+typedef struct {
+ /* This array gives the coefficient quantizers in natural array order
+ * (not the zigzag order in which they are stored in a JPEG DQT marker).
+ * CAUTION: IJG versions prior to v6a kept this array in zigzag order.
+ */
+ UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */
+ /* This field is used only during compression. It's initialized FALSE when
+ * the table is created, and set TRUE when it's been output to the file.
+ * You could suppress output of a table by setting this to TRUE.
+ * (See jpeg_suppress_tables for an example.)
+ */
+ boolean sent_table; /* TRUE when table has been output */
+} JTQUANT_TBL;
+
+
+/* Huffman coding tables. */
+
+typedef struct {
+ /* These two fields directly represent the contents of a JPEG DHT marker */
+ UINT8 bits[17]; /* bits[k] = # of symbols with codes of */
+ /* length k bits; bits[0] is unused */
+ UINT8 huffval[256]; /* The symbols, in order of incr code length */
+ /* This field is used only during compression. It's initialized FALSE when
+ * the table is created, and set TRUE when it's been output to the file.
+ * You could suppress output of a table by setting this to TRUE.
+ * (See jpeg_suppress_tables for an example.)
+ */
+ boolean sent_table; /* TRUE when table has been output */
+} JHUFF_TBL;
+
+
+/* Basic info about one component (color channel). */
+
+typedef struct {
+ /* These values are fixed over the whole image. */
+ /* For compression, they must be supplied by parameter setup; */
+ /* for decompression, they are read from the SOF marker. */
+ int component_id; /* identifier for this component (0..255) */
+ int component_index; /* its index in SOF or cinfo->comp_info[] */
+ int h_samp_factor; /* horizontal sampling factor (1..4) */
+ int v_samp_factor; /* vertical sampling factor (1..4) */
+ int quant_tbl_no; /* quantization table selector (0..3) */
+ /* These values may vary between scans. */
+ /* For compression, they must be supplied by parameter setup; */
+ /* for decompression, they are read from the SOS marker. */
+ /* The decompressor output side may not use these variables. */
+ int dc_tbl_no; /* DC entropy table selector (0..3) */
+ int ac_tbl_no; /* AC entropy table selector (0..3) */
+
+ /* Remaining fields should be treated as private by applications. */
+
+ /* These values are computed during compression or decompression startup: */
+ /* Component's size in DCT blocks.
+ * Any dummy blocks added to complete an MCU are not counted; therefore
+ * these values do not depend on whether a scan is interleaved or not.
+ */
+ JDIMENSION width_in_blocks;
+ JDIMENSION height_in_blocks;
+ /* Size of a DCT block in samples. Always DCTSIZE for compression.
+ * For decompression this is the size of the output from one DCT block,
+ * reflecting any scaling we choose to apply during the IDCT step.
+ * Values of 1,2,4,8 are likely to be supported. Note that different
+ * components may receive different IDCT scalings.
+ */
+ int DCT_scaled_size;
+ /* The downsampled dimensions are the component's actual, unpadded number
+ * of samples at the main buffer (preprocessing/compression interface), thus
+ * downsampled_width = ceil(image_width * Hi/Hmax)
+ * and similarly for height. For decompression, IDCT scaling is included, so
+ * downsampled_width = ceil(image_width * Hi/Hmax * DCT_scaled_size/DCTSIZE)
+ */
+ JDIMENSION downsampled_width; /* actual width in samples */
+ JDIMENSION downsampled_height; /* actual height in samples */
+ /* This flag is used only for decompression. In cases where some of the
+ * components will be ignored (eg grayscale output from YCbCr image),
+ * we can skip most computations for the unused components.
+ */
+ boolean component_needed; /* do we need the value of this component? */
+
+ /* These values are computed before starting a scan of the component. */
+ /* The decompressor output side may not use these variables. */
+ int MCU_width; /* number of blocks per MCU, horizontally */
+ int MCU_height; /* number of blocks per MCU, vertically */
+ int MCU_blocks; /* MCU_width * MCU_height */
+ int MCU_sample_width; /* MCU width in samples, MCU_width*DCT_scaled_size */
+ int last_col_width; /* # of non-dummy blocks across in last MCU */
+ int last_row_height; /* # of non-dummy blocks down in last MCU */
+
+ /* Saved quantization table for component; NULL if none yet saved.
+ * See jdinput.c comments about the need for this information.
+ * This field is currently used only for decompression.
+ */
+ JTQUANT_TBL * quant_table;
+
+ /* Private per-component storage for DCT or IDCT subsystem. */
+ void * dct_table;
+} jpeg_component_info;
+
+
+/* The script for encoding a multiple-scan file is an array of these: */
+
+typedef struct {
+ int comps_in_scan; /* number of components encoded in this scan */
+ int component_index[MAX_COMPS_IN_SCAN]; /* their SOF/comp_info[] indexes */
+ int Ss, Se; /* progressive JPEG spectral selection parms */
+ int Ah, Al; /* progressive JPEG successive approx. parms */
+} jpeg_scan_info;
+
+/* The decompressor can save APPn and COM markers in a list of these: */
+
+typedef struct jpeg_marker_struct FAR * jpeg_saved_marker_ptr;
+
+struct jpeg_marker_struct {
+ jpeg_saved_marker_ptr next; /* next in list, or NULL */
+ UINT8 marker; /* marker code: JPEG_COM, or JPEG_APP0+n */
+ unsigned int original_length; /* # bytes of data in the file */
+ unsigned int data_length; /* # bytes of data saved at data[] */
+ JOCTET FAR * data; /* the data contained in the marker */
+ /* the marker length word is not counted in data_length or original_length */
+};
+
+/* Known color spaces. */
+
+typedef enum {
+ JCS_UNKNOWN, /* error/unspecified */
+ JCS_GRAYSCALE, /* monochrome */
+ JCS_RGB, /* red/green/blue */
+ JCS_YCbCr, /* Y/Cb/Cr (also known as YUV) */
+ JCS_CMYK, /* C/M/Y/K */
+ JCS_YCCK /* Y/Cb/Cr/K */
+} J_COLOR_SPACE;
+
+/* DCT/IDCT algorithm options. */
+
+typedef enum {
+ JDCT_ISLOW, /* slow but accurate integer algorithm */
+ JDCT_IFAST, /* faster, less accurate integer method */
+ JDCT_FLOAT /* floating-point: accurate, fast on fast HW */
+} J_DCT_METHOD;
+
+#ifndef JDCT_DEFAULT /* may be overridden in jconfig.h */
+#define JDCT_DEFAULT JDCT_ISLOW
+#endif
+#ifndef JDCT_FASTEST /* may be overridden in jconfig.h */
+#define JDCT_FASTEST JDCT_IFAST
+#endif
+
+/* Dithering options for decompression. */
+
+typedef enum {
+ JDITHER_NONE, /* no dithering */
+ JDITHER_ORDERED, /* simple ordered dither */
+ JDITHER_FS /* Floyd-Steinberg error diffusion dither */
+} J_DITHER_MODE;
+
+
+/* Common fields between JPEG compression and decompression master structs. */
+
+#define jpeg_common_fields \
+ struct jpeg_error_mgr * err; /* Error handler module */\
+ struct jpeg_memory_mgr * mem; /* Memory manager module */\
+ struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
+ void * client_data; /* Available for use by application */\
+ boolean is_decompressor; /* So common code can tell which is which */\
+ int global_state /* For checking call sequence validity */
+
+/* Routines that are to be used by both halves of the library are declared
+ * to receive a pointer to this structure. There are no actual instances of
+ * jpeg_common_struct, only of jpeg_compress_struct and jpeg_decompress_struct.
+ */
+struct jpeg_common_struct {
+ jpeg_common_fields; /* Fields common to both master struct types */
+ /* Additional fields follow in an actual jpeg_compress_struct or
+ * jpeg_decompress_struct. All three structs must agree on these
+ * initial fields! (This would be a lot cleaner in C++.)
+ */
+};
+
+typedef struct jpeg_common_struct * j_common_ptr;
+typedef struct jpeg_compress_struct * j_compress_ptr;
+typedef struct jpeg_decompress_struct * j_decompress_ptr;
+
+
+/* Master record for a compression instance */
+
+struct jpeg_compress_struct {
+ jpeg_common_fields; /* Fields shared with jpeg_decompress_struct */
+
+ /* Destination for compressed data */
+ struct jpeg_destination_mgr * dest;
+
+ /* Description of source image --- these fields must be filled in by
+ * outer application before starting compression. in_color_space must
+ * be correct before you can even call jpeg_set_defaults().
+ */
+
+ JDIMENSION image_width; /* input image width */
+ JDIMENSION image_height; /* input image height */
+ int input_components; /* # of color components in input image */
+ J_COLOR_SPACE in_color_space; /* colorspace of input image */
+
+ double input_gamma; /* image gamma of input image */
+
+ /* Compression parameters --- these fields must be set before calling
+ * jpeg_start_compress(). We recommend calling jpeg_set_defaults() to
+ * initialize everything to reasonable defaults, then changing anything
+ * the application specifically wants to change. That way you won't get
+ * burnt when new parameters are added. Also note that there are several
+ * helper routines to simplify changing parameters.
+ */
+
+ int data_precision; /* bits of precision in image data */
+
+ int num_components; /* # of color components in JPEG image */
+ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
+
+ jpeg_component_info * comp_info;
+ /* comp_info[i] describes component that appears i'th in SOF */
+
+ JTQUANT_TBL * quant_tbl_ptrs[NUM_TQUANT_TBLS];
+ /* ptrs to coefficient quantization tables, or NULL if not defined */
+
+ JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ /* ptrs to Huffman coding tables, or NULL if not defined */
+
+ UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+ int num_scans; /* # of entries in scan_info array */
+ const jpeg_scan_info * scan_info; /* script for multi-scan file, or NULL */
+ /* The default value of scan_info is NULL, which causes a single-scan
+ * sequential JPEG file to be emitted. To create a multi-scan file,
+ * set num_scans and scan_info to point to an array of scan definitions.
+ */
+
+ boolean raw_data_in; /* TRUE=caller supplies downsampled data */
+ boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
+ boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
+ boolean CCIR601_sampling; /* TRUE=first samples are cosited */
+ int smoothing_factor; /* 1..100, or 0 for no input smoothing */
+ J_DCT_METHOD dct_method; /* DCT algorithm selector */
+
+ /* The restart interval can be specified in absolute MCUs by setting
+ * restart_interval, or in MCU rows by setting restart_in_rows
+ * (in which case the correct restart_interval will be figured
+ * for each scan).
+ */
+ unsigned int restart_interval; /* MCUs per restart, or 0 for no restart */
+ int restart_in_rows; /* if > 0, MCU rows per restart interval */
+
+ /* Parameters controlling emission of special markers. */
+
+ boolean write_JFIF_header; /* should a JFIF marker be written? */
+ UINT8 JFIF_major_version; /* What to write for the JFIF version number */
+ UINT8 JFIF_minor_version;
+ /* These three values are not used by the JPEG code, merely copied */
+ /* into the JFIF APP0 marker. density_unit can be 0 for unknown, */
+ /* 1 for dots/inch, or 2 for dots/cm. Note that the pixel aspect */
+ /* ratio is defined by X_density/Y_density even when density_unit=0. */
+ UINT8 density_unit; /* JFIF code for pixel size units */
+ UINT16 X_density; /* Horizontal pixel density */
+ UINT16 Y_density; /* Vertical pixel density */
+ boolean write_Adobe_marker; /* should an Adobe marker be written? */
+
+ /* State variable: index of next scanline to be written to
+ * jpeg_write_scanlines(). Application may use this to control its
+ * processing loop, e.g., "while (next_scanline < image_height)".
+ */
+
+ JDIMENSION next_scanline; /* 0 .. image_height-1 */
+
+ /* Remaining fields are known throughout compressor, but generally
+ * should not be touched by a surrounding application.
+ */
+
+ /*
+ * These fields are computed during compression startup
+ */
+ boolean progressive_mode; /* TRUE if scan script uses progressive mode */
+ int max_h_samp_factor; /* largest h_samp_factor */
+ int max_v_samp_factor; /* largest v_samp_factor */
+
+ JDIMENSION total_iMCU_rows; /* # of iMCU rows to be input to coef ctlr */
+ /* The coefficient controller receives data in units of MCU rows as defined
+ * for fully interleaved scans (whether the JPEG file is interleaved or not).
+ * There are v_samp_factor * DCTSIZE sample rows of each component in an
+ * "iMCU" (interleaved MCU) row.
+ */
+
+ /*
+ * These fields are valid during any one scan.
+ * They describe the components and MCUs actually appearing in the scan.
+ */
+ int comps_in_scan; /* # of JPEG components in this scan */
+ jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
+ /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+ JDIMENSION MCUs_per_row; /* # of MCUs across the image */
+ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
+
+ int blocks_in_MCU; /* # of DCT blocks per MCU */
+ int MCU_membership[C_MAX_BLOCKS_IN_MCU];
+ /* MCU_membership[i] is index in cur_comp_info of component owning */
+ /* i'th block in an MCU */
+
+ int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
+
+ /*
+ * Links to compression subobjects (methods and private variables of modules)
+ */
+ struct jpeg_comp_master * master;
+ struct jpeg_c_main_controller * main;
+ struct jpeg_c_prep_controller * prep;
+ struct jpeg_c_coef_controller * coef;
+ struct jpeg_marker_writer * marker;
+ struct jpeg_color_converter * cconvert;
+ struct jpeg_downsampler * downsample;
+ struct jpeg_forward_dct * fdct;
+ struct jpeg_entropy_encoder * entropy;
+ jpeg_scan_info * script_space; /* workspace for jpeg_simple_progression */
+ int script_space_size;
+};
+
+
+/* Master record for a decompression instance */
+
+struct jpeg_decompress_struct {
+ jpeg_common_fields; /* Fields shared with jpeg_compress_struct */
+
+ /* Source of compressed data */
+ struct jpeg_source_mgr * src;
+
+ /* Basic description of image --- filled in by jpeg_read_header(). */
+ /* Application may inspect these values to decide how to process image. */
+
+ JDIMENSION image_width; /* nominal image width (from SOF marker) */
+ JDIMENSION image_height; /* nominal image height */
+ int num_components; /* # of color components in JPEG image */
+ J_COLOR_SPACE jpeg_color_space; /* colorspace of JPEG image */
+
+ /* Decompression processing parameters --- these fields must be set before
+ * calling jpeg_start_decompress(). Note that jpeg_read_header() initializes
+ * them to default values.
+ */
+
+ J_COLOR_SPACE out_color_space; /* colorspace for output */
+
+ unsigned int scale_num, scale_denom; /* fraction by which to scale image */
+
+ double output_gamma; /* image gamma wanted in output */
+
+ boolean buffered_image; /* TRUE=multiple output passes */
+ boolean raw_data_out; /* TRUE=downsampled data wanted */
+
+ J_DCT_METHOD dct_method; /* IDCT algorithm selector */
+ boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */
+ boolean do_block_smoothing; /* TRUE=apply interblock smoothing */
+
+ boolean quantize_colors; /* TRUE=colormapped output wanted */
+ /* the following are ignored if not quantize_colors: */
+ J_DITHER_MODE dither_mode; /* type of color dithering to use */
+ boolean two_pass_quantize; /* TRUE=use two-pass color quantization */
+ int desired_number_of_colors; /* max # colors to use in created colormap */
+ /* these are significant only in buffered-image mode: */
+ boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */
+ boolean enable_external_quant;/* enable future use of external colormap */
+ boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */
+
+ /* Description of actual output image that will be returned to application.
+ * These fields are computed by jpeg_start_decompress().
+ * You can also use jpeg_calc_output_dimensions() to determine these values
+ * in advance of calling jpeg_start_decompress().
+ */
+
+ JDIMENSION output_width; /* scaled image width */
+ JDIMENSION output_height; /* scaled image height */
+ int out_color_components; /* # of color components in out_color_space */
+ int output_components; /* # of color components returned */
+ /* output_components is 1 (a colormap index) when quantizing colors;
+ * otherwise it equals out_color_components.
+ */
+ int rec_outbuf_height; /* min recommended height of scanline buffer */
+ /* If the buffer passed to jpeg_read_scanlines() is less than this many rows
+ * high, space and time will be wasted due to unnecessary data copying.
+ * Usually rec_outbuf_height will be 1 or 2, at most 4.
+ */
+
+ /* When quantizing colors, the output colormap is described by these fields.
+ * The application can supply a colormap by setting colormap non-NULL before
+ * calling jpeg_start_decompress; otherwise a colormap is created during
+ * jpeg_start_decompress or jpeg_start_output.
+ * The map has out_color_components rows and actual_number_of_colors columns.
+ */
+ int actual_number_of_colors; /* number of entries in use */
+ JSAMPARRAY colormap; /* The color map as a 2-D pixel array */
+
+ /* State variables: these variables indicate the progress of decompression.
+ * The application may examine these but must not modify them.
+ */
+
+ /* Row index of next scanline to be read from jpeg_read_scanlines().
+ * Application may use this to control its processing loop, e.g.,
+ * "while (output_scanline < output_height)".
+ */
+ JDIMENSION output_scanline; /* 0 .. output_height-1 */
+
+ /* Current input scan number and number of iMCU rows completed in scan.
+ * These indicate the progress of the decompressor input side.
+ */
+ int input_scan_number; /* Number of SOS markers seen so far */
+ JDIMENSION input_iMCU_row; /* Number of iMCU rows completed */
+
+ /* The "output scan number" is the notional scan being displayed by the
+ * output side. The decompressor will not allow output scan/row number
+ * to get ahead of input scan/row, but it can fall arbitrarily far behind.
+ */
+ int output_scan_number; /* Nominal scan number being displayed */
+ JDIMENSION output_iMCU_row; /* Number of iMCU rows read */
+
+ /* Current progression status. coef_bits[c][i] indicates the precision
+ * with which component c's DCT coefficient i (in zigzag order) is known.
+ * It is -1 when no data has yet been received, otherwise it is the point
+ * transform (shift) value for the most recent scan of the coefficient
+ * (thus, 0 at completion of the progression).
+ * This pointer is NULL when reading a non-progressive file.
+ */
+ int (*coef_bits)[DCTSIZE2]; /* -1 or current Al value for each coef */
+
+ /* Internal JPEG parameters --- the application usually need not look at
+ * these fields. Note that the decompressor output side may not use
+ * any parameters that can change between scans.
+ */
+
+ /* Quantization and Huffman tables are carried forward across input
+ * datastreams when processing abbreviated JPEG datastreams.
+ */
+
+ JTQUANT_TBL * quant_tbl_ptrs[NUM_TQUANT_TBLS];
+ /* ptrs to coefficient quantization tables, or NULL if not defined */
+
+ JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS];
+ /* ptrs to Huffman coding tables, or NULL if not defined */
+
+ /* These parameters are never carried across datastreams, since they
+ * are given in SOF/SOS markers or defined to be reset by SOI.
+ */
+
+ int data_precision; /* bits of precision in image data */
+
+ jpeg_component_info * comp_info;
+ /* comp_info[i] describes component that appears i'th in SOF */
+
+ boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */
+ boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
+
+ UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
+ UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
+ UINT8 arith_ac_K[NUM_ARITH_TBLS]; /* Kx values for AC arith-coding tables */
+
+ unsigned int restart_interval; /* MCUs per restart interval, or 0 for no restart */
+
+ /* These fields record data obtained from optional markers recognized by
+ * the JPEG library.
+ */
+ boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */
+ /* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
+ UINT8 JFIF_major_version; /* JFIF version number */
+ UINT8 JFIF_minor_version;
+ UINT8 density_unit; /* JFIF code for pixel size units */
+ UINT16 X_density; /* Horizontal pixel density */
+ UINT16 Y_density; /* Vertical pixel density */
+ boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */
+ UINT8 Adobe_transform; /* Color transform code from Adobe marker */
+
+ boolean CCIR601_sampling; /* TRUE=first samples are cosited */
+
+ /* Aside from the specific data retained from APPn markers known to the
+ * library, the uninterpreted contents of any or all APPn and COM markers
+ * can be saved in a list for examination by the application.
+ */
+ jpeg_saved_marker_ptr marker_list; /* Head of list of saved markers */
+
+ /* Remaining fields are known throughout decompressor, but generally
+ * should not be touched by a surrounding application.
+ */
+
+ /*
+ * These fields are computed during decompression startup
+ */
+ int max_h_samp_factor; /* largest h_samp_factor */
+ int max_v_samp_factor; /* largest v_samp_factor */
+
+ int min_DCT_scaled_size; /* smallest DCT_scaled_size of any component */
+
+ JDIMENSION total_iMCU_rows; /* # of iMCU rows in image */
+ /* The coefficient controller's input and output progress is measured in
+ * units of "iMCU" (interleaved MCU) rows. These are the same as MCU rows
+ * in fully interleaved JPEG scans, but are used whether the scan is
+ * interleaved or not. We define an iMCU row as v_samp_factor DCT block
+ * rows of each component. Therefore, the IDCT output tqcontains
+ * v_samp_factor*DCT_scaled_size sample rows of a component per iMCU row.
+ */
+
+ JSAMPLE * sample_range_limit; /* table for fast range-limiting */
+
+ /*
+ * These fields are valid during any one scan.
+ * They describe the components and MCUs actually appearing in the scan.
+ * Note that the decompressor output side must not use these fields.
+ */
+ int comps_in_scan; /* # of JPEG components in this scan */
+ jpeg_component_info * cur_comp_info[MAX_COMPS_IN_SCAN];
+ /* *cur_comp_info[i] describes component that appears i'th in SOS */
+
+ JDIMENSION MCUs_per_row; /* # of MCUs across the image */
+ JDIMENSION MCU_rows_in_scan; /* # of MCU rows in the image */
+
+ int blocks_in_MCU; /* # of DCT blocks per MCU */
+ int MCU_membership[D_MAX_BLOCKS_IN_MCU];
+ /* MCU_membership[i] is index in cur_comp_info of component owning */
+ /* i'th block in an MCU */
+
+ int Ss, Se, Ah, Al; /* progressive JPEG parameters for scan */
+
+ /* This field is shared between entropy decoder and marker parser.
+ * It is either zero or the code of a JPEG marker that has been
+ * read from the data source, but has not yet been processed.
+ */
+ int unread_marker;
+
+ /*
+ * Links to decompression subobjects (methods, private variables of modules)
+ */
+ struct jpeg_decomp_master * master;
+ struct jpeg_d_main_controller * main;
+ struct jpeg_d_coef_controller * coef;
+ struct jpeg_d_post_controller * post;
+ struct jpeg_input_controller * inputctl;
+ struct jpeg_marker_reader * marker;
+ struct jpeg_entropy_decoder * entropy;
+ struct jpeg_inverse_dct * idct;
+ struct jpeg_upsampler * upsample;
+ struct jpeg_color_deconverter * cconvert;
+ struct jpeg_color_quantizer * cquantize;
+};
+
+
+/* "Object" declarations for JPEG modules that may be supplied or called
+ * directly by the surrounding application.
+ * As with all objects in the JPEG library, these structs only define the
+ * publicly visible methods and state variables of a module. Additional
+ * private fields may exist after the public ones.
+ */
+
+
+/* Error handler object */
+
+struct jpeg_error_mgr {
+ /* Error exit handler: does not return to caller */
+ JTQT_METHOD(void, error_exit, (j_common_ptr cinfo));
+ /* Conditionally emit a trace or warning message */
+ JTQT_METHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
+ /* Routine that actually outputs a trace or error message */
+ JTQT_METHOD(void, output_message, (j_common_ptr cinfo));
+ /* Format a message string for the most recent JPEG error or message */
+ JTQT_METHOD(void, format_message, (j_common_ptr cinfo, char * buffer));
+#define JMSG_LENGTH_MAX 200 /* recommended size of format_message buffer */
+ /* Reset error state variables at start of a new image */
+ JTQT_METHOD(void, reset_error_mgr, (j_common_ptr cinfo));
+
+ /* The message ID code and any parameters are saved here.
+ * A message can have one string parameter or up to 8 int parameters.
+ */
+ int msg_code;
+#define JMSG_STR_PARM_MAX 80
+ union {
+ int i[8];
+ char s[JMSG_STR_PARM_MAX];
+ } msg_parm;
+
+ /* Standard state variables for error facility */
+
+ int trace_level; /* max msg_level that will be displayed */
+
+ /* For recoverable corrupt-data errors, we emit a warning message,
+ * but keep going unless emit_message chooses to abort. emit_message
+ * should count warnings in num_warnings. The surrounding application
+ * can check for bad data by seeing if num_warnings is nonzero at the
+ * end of processing.
+ */
+ long num_warnings; /* number of corrupt-data warnings */
+
+ /* These fields point to the table(s) of error message strings.
+ * An application can change the table pointer to switch to a different
+ * message list (typically, to change the language in which errors are
+ * reported). Some applications may wish to add additional error codes
+ * that will be handled by the JPEG library error mechanism; the second
+ * table pointer is used for this purpose.
+ *
+ * First table includes all errors generated by JPEG library itself.
+ * Error code 0 is reserved for a "no such error string" message.
+ */
+ const char * const * jpeg_message_table; /* Library errors */
+ int last_jpeg_message; /* Table tqcontains strings 0..last_jpeg_message */
+ /* Second table can be added by application (see cjpeg/djpeg for example).
+ * It tqcontains strings numbered first_addon_message..last_addon_message.
+ */
+ const char * const * addon_message_table; /* Non-library errors */
+ int first_addon_message; /* code for first string in addon table */
+ int last_addon_message; /* code for last string in addon table */
+};
+
+
+/* Progress monitor object */
+
+struct jpeg_progress_mgr {
+ JTQT_METHOD(void, progress_monitor, (j_common_ptr cinfo));
+
+ long pass_counter; /* work units completed in this pass */
+ long pass_limit; /* total number of work units in this pass */
+ int completed_passes; /* passes completed so far */
+ int total_passes; /* total number of passes expected */
+};
+
+
+/* Data destination object for compression */
+
+struct jpeg_destination_mgr {
+ JOCTET * next_output_byte; /* => next byte to write in buffer */
+ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
+
+ JTQT_METHOD(void, init_destination, (j_compress_ptr cinfo));
+ JTQT_METHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo));
+ JTQT_METHOD(void, term_destination, (j_compress_ptr cinfo));
+};
+
+
+/* Data source object for decompression */
+
+struct jpeg_source_mgr {
+ const JOCTET * next_input_byte; /* => next byte to read from buffer */
+ size_t bytes_in_buffer; /* # of bytes remaining in buffer */
+
+ JTQT_METHOD(void, init_source, (j_decompress_ptr cinfo));
+ JTQT_METHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo));
+ JTQT_METHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes));
+ JTQT_METHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
+ JTQT_METHOD(void, term_source, (j_decompress_ptr cinfo));
+};
+
+
+/* Memory manager object.
+ * Allocates "small" objects (a few K total), "large" objects (tens of K),
+ * and "really big" objects (virtual arrays with backing store if needed).
+ * The memory manager does not allow individual objects to be freed; rather,
+ * each created object is assigned to a pool, and whole pools can be freed
+ * at once. This is faster and more convenient than remembering exactly what
+ * to free, especially where malloc()/free() are not too speedy.
+ * NB: alloc routines never return NULL. They exit to error_exit if not
+ * successful.
+ */
+
+#define JPOOL_PERMANENT 0 /* lasts until master record is destroyed */
+#define JPOOL_IMAGE 1 /* lasts until done with image/datastream */
+#define JPOOL_NUMPOOLS 2
+
+typedef struct jvirt_sarray_control * jvirt_sarray_ptr;
+typedef struct jvirt_barray_control * jvirt_barray_ptr;
+
+
+struct jpeg_memory_mgr {
+ /* Method pointers */
+ JTQT_METHOD(void *, alloc_small, (j_common_ptr cinfo, int pool_id,
+ size_t sizeofobject));
+ JTQT_METHOD(void FAR *, alloc_large, (j_common_ptr cinfo, int pool_id,
+ size_t sizeofobject));
+ JTQT_METHOD(JSAMPARRAY, alloc_sarray, (j_common_ptr cinfo, int pool_id,
+ JDIMENSION samplesperrow,
+ JDIMENSION numrows));
+ JTQT_METHOD(JBLOCKARRAY, alloc_barray, (j_common_ptr cinfo, int pool_id,
+ JDIMENSION blocksperrow,
+ JDIMENSION numrows));
+ JTQT_METHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo,
+ int pool_id,
+ boolean pre_zero,
+ JDIMENSION samplesperrow,
+ JDIMENSION numrows,
+ JDIMENSION maxaccess));
+ JTQT_METHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
+ int pool_id,
+ boolean pre_zero,
+ JDIMENSION blocksperrow,
+ JDIMENSION numrows,
+ JDIMENSION maxaccess));
+ JTQT_METHOD(void, realize_virt_arrays, (j_common_ptr cinfo));
+ JTQT_METHOD(JSAMPARRAY, access_virt_sarray, (j_common_ptr cinfo,
+ jvirt_sarray_ptr ptr,
+ JDIMENSION start_row,
+ JDIMENSION num_rows,
+ boolean writable));
+ JTQT_METHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo,
+ jvirt_barray_ptr ptr,
+ JDIMENSION start_row,
+ JDIMENSION num_rows,
+ boolean writable));
+ JTQT_METHOD(void, free_pool, (j_common_ptr cinfo, int pool_id));
+ JTQT_METHOD(void, self_destruct, (j_common_ptr cinfo));
+
+ /* Limit on memory allocation for this JPEG object. (Note that this is
+ * merely advisory, not a guaranteed maximum; it only affects the space
+ * used for virtual-array buffers.) May be changed by outer application
+ * after creating the JPEG object.
+ */
+ long max_memory_to_use;
+
+ /* Maximum allocation request accepted by alloc_large. */
+ long max_alloc_chunk;
+};
+
+
+/* Routine signature for application-supplied marker processing methods.
+ * Need not pass marker code since it is stored in cinfo->unread_marker.
+ */
+typedef JTQT_METHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
+
+
+/* Declarations for routines called by application.
+ * The JPP macro hides prototype parameters from compilers that can't cope.
+ * Note JPP requires double parentheses.
+ */
+
+#ifdef HAVE_PROTOTYPES
+#define JPP(arglist) arglist
+#else
+#define JPP(arglist) ()
+#endif
+
+
+/* Short forms of external names for systems with brain-damaged linkers.
+ * We shorten external names to be unique in the first six letters, which
+ * is good enough for all known systems.
+ * (If your compiler itself needs names to be unique in less than 15
+ * characters, you are out of luck. Get a better compiler.)
+ */
+
+#ifdef NEED_SHORT_EXTERNAL_NAMES
+#define jpeg_std_error jStdError
+#define jpeg_CreateCompress jCreaCompress
+#define jpeg_CreateDecompress jCreaDecompress
+#define jpeg_destroy_compress jDestCompress
+#define jpeg_destroy_decompress jDestDecompress
+#define jpeg_stdio_dest jStdDest
+#define jpeg_stdio_src jStdSrc
+#define jpeg_set_defaults jSetDefaults
+#define jpeg_set_colorspace jSetColorspace
+#define jpeg_default_colorspace jDefColorspace
+#define jpeg_set_quality jSetQuality
+#define jpeg_set_linear_quality jSetLQuality
+#define jpeg_add_quant_table jAddQuantTable
+#define jpeg_quality_scaling jQualityScaling
+#define jpeg_simple_progression jSimProgress
+#define jpeg_suppress_tables jSuppressTables
+#define jpeg_alloc_quant_table jAlcTQTable
+#define jpeg_alloc_huff_table jAlcHTable
+#define jpeg_start_compress jStrtCompress
+#define jpeg_write_scanlines jWrtScanlines
+#define jpeg_finish_compress jFinCompress
+#define jpeg_write_raw_data jWrtRawData
+#define jpeg_write_marker jWrtMarker
+#define jpeg_write_m_header jWrtMHeader
+#define jpeg_write_m_byte jWrtMByte
+#define jpeg_write_tables jWrtTables
+#define jpeg_read_header jReadHeader
+#define jpeg_start_decompress jStrtDecompress
+#define jpeg_read_scanlines jReadScanlines
+#define jpeg_finish_decompress jFinDecompress
+#define jpeg_read_raw_data jReadRawData
+#define jpeg_has_multiple_scans jHasMultScn
+#define jpeg_start_output jStrtOutput
+#define jpeg_finish_output jFinOutput
+#define jpeg_input_complete jInComplete
+#define jpeg_new_colormap jNewCMap
+#define jpeg_consume_input jConsumeInput
+#define jpeg_calc_output_dimensions jCalcDimensions
+#define jpeg_save_markers jSaveMarkers
+#define jpeg_set_marker_processor jSetMarker
+#define jpeg_read_coefficients jReadCoefs
+#define jpeg_write_coefficients jWrtCoefs
+#define jpeg_copy_critical_parameters jCopyCrit
+#define jpeg_abort_compress jAbrtCompress
+#define jpeg_abort_decompress jAbrtDecompress
+#define jpeg_abort jAbort
+#define jpeg_destroy jDestroy
+#define jpeg_resync_to_restart jResyncRestart
+#endif /* NEED_SHORT_EXTERNAL_NAMES */
+
+
+/* Default error-management setup */
+EXTERN(struct jpeg_error_mgr *) jpeg_std_error
+ JPP((struct jpeg_error_mgr * err));
+
+/* Initialization of JPEG compression objects.
+ * jpeg_create_compress() and jpeg_create_decompress() are the exported
+ * names that applications should call. These expand to calls on
+ * jpeg_CreateCompress and jpeg_CreateDecompress with additional information
+ * passed for version mismatch checking.
+ * NB: you must set up the error-manager BEFORE calling jpeg_create_xxx.
+ */
+#define jpeg_create_compress(cinfo) \
+ jpeg_CreateCompress((cinfo), JPEG_LIB_VERSION, \
+ (size_t) sizeof(struct jpeg_compress_struct))
+#define jpeg_create_decompress(cinfo) \
+ jpeg_CreateDecompress((cinfo), JPEG_LIB_VERSION, \
+ (size_t) sizeof(struct jpeg_decompress_struct))
+EXTERN(void) jpeg_CreateCompress JPP((j_compress_ptr cinfo,
+ int version, size_t structsize));
+EXTERN(void) jpeg_CreateDecompress JPP((j_decompress_ptr cinfo,
+ int version, size_t structsize));
+/* Destruction of JPEG compression objects */
+EXTERN(void) jpeg_destroy_compress JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_destroy_decompress JPP((j_decompress_ptr cinfo));
+
+/* Standard data source and destination managers: stdio streams. */
+/* Caller is responsible for opening the file before and closing after. */
+EXTERN(void) jpeg_stdio_dest JPP((j_compress_ptr cinfo, FILE * outfile));
+EXTERN(void) jpeg_stdio_src JPP((j_decompress_ptr cinfo, FILE * infile));
+
+/* Default parameter setup for compression */
+EXTERN(void) jpeg_set_defaults JPP((j_compress_ptr cinfo));
+/* Compression parameter setup aids */
+EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo,
+ J_COLOR_SPACE colorspace));
+EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
+ boolean force_baseline));
+EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
+ int scale_factor,
+ boolean force_baseline));
+EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
+ const unsigned int *basic_table,
+ int scale_factor,
+ boolean force_baseline));
+EXTERN(int) jpeg_quality_scaling JPP((int quality));
+EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
+ boolean suppress));
+EXTERN(JTQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
+EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
+
+/* Main entry points for compression */
+EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
+ boolean write_all_tables));
+EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
+ JSAMPARRAY scanlines,
+ JDIMENSION num_lines));
+EXTERN(void) jpeg_finish_compress JPP((j_compress_ptr cinfo));
+
+/* Replaces jpeg_write_scanlines when writing raw downsampled data. */
+EXTERN(JDIMENSION) jpeg_write_raw_data JPP((j_compress_ptr cinfo,
+ JSAMPIMAGE data,
+ JDIMENSION num_lines));
+
+/* Write a special marker. See libjpeg.doc concerning safe usage. */
+EXTERN(void) jpeg_write_marker
+ JPP((j_compress_ptr cinfo, int marker,
+ const JOCTET * dataptr, unsigned int datalen));
+/* Same, but piecemeal. */
+EXTERN(void) jpeg_write_m_header
+ JPP((j_compress_ptr cinfo, int marker, unsigned int datalen));
+EXTERN(void) jpeg_write_m_byte
+ JPP((j_compress_ptr cinfo, int val));
+
+/* Alternate compression function: just write an abbreviated table file */
+EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
+
+/* Decompression startup: read start of JPEG datastream to see what's there */
+EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
+ boolean require_image));
+/* Return value is one of: */
+#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */
+#define JPEG_HEADER_OK 1 /* Found valid image datastream */
+#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */
+/* If you pass require_image = TRUE (normal case), you need not check for
+ * a TABLES_ONLY return code; an abbreviated file will cause an error exit.
+ * JPEG_SUSPENDED is only possible if you use a data source module that can
+ * give a suspension return (the stdio source module doesn't).
+ */
+
+/* Main entry points for decompression */
+EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
+EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
+ JSAMPARRAY scanlines,
+ JDIMENSION max_lines));
+EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
+
+/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
+EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
+ JSAMPIMAGE data,
+ JDIMENSION max_lines));
+
+/* Additional entry points for buffered-image mode. */
+EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
+EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
+ int scan_number));
+EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
+EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
+EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo));
+EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
+/* Return value is one of: */
+/* #define JPEG_SUSPENDED 0 Suspended due to lack of input data */
+#define JPEG_REACHED_SOS 1 /* Reached start of new scan */
+#define JPEG_REACHED_EOI 2 /* Reached end of image */
+#define JPEG_ROW_COMPLETED 3 /* Completed one iMCU row */
+#define JPEG_SCAN_COMPLETED 4 /* Completed last iMCU row of a scan */
+
+/* Precalculate output dimensions for current decompression parameters. */
+EXTERN(void) jpeg_calc_output_dimensions JPP((j_decompress_ptr cinfo));
+
+/* Control saving of COM and APPn markers into marker_list. */
+EXTERN(void) jpeg_save_markers
+ JPP((j_decompress_ptr cinfo, int marker_code,
+ unsigned int length_limit));
+
+/* Install a special processing method for COM or APPn markers. */
+EXTERN(void) jpeg_set_marker_processor
+ JPP((j_decompress_ptr cinfo, int marker_code,
+ jpeg_marker_parser_method routine));
+
+/* Read or write raw DCT coefficients --- useful for lossless transcoding. */
+EXTERN(jvirt_barray_ptr *) jpeg_read_coefficients JPP((j_decompress_ptr cinfo));
+EXTERN(void) jpeg_write_coefficients JPP((j_compress_ptr cinfo,
+ jvirt_barray_ptr * coef_arrays));
+EXTERN(void) jpeg_copy_critical_parameters JPP((j_decompress_ptr srcinfo,
+ j_compress_ptr dstinfo));
+
+/* If you choose to abort compression or decompression before completing
+ * jpeg_finish_(de)compress, then you need to clean up to release memory,
+ * temporary files, etc. You can just call jpeg_destroy_(de)compress
+ * if you're done with the JPEG object, but if you want to clean it up and
+ * reuse it, call this:
+ */
+EXTERN(void) jpeg_abort_compress JPP((j_compress_ptr cinfo));
+EXTERN(void) jpeg_abort_decompress JPP((j_decompress_ptr cinfo));
+
+/* Generic versions of jpeg_abort and jpeg_destroy that work on either
+ * flavor of JPEG object. These may be more convenient in some places.
+ */
+EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
+EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
+
+/* Default restart-marker-resync procedure for use by data source modules */
+EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
+ int desired));
+
+
+/* These marker codes are exported since applications and data source modules
+ * are likely to want to use them.
+ */
+
+#define JPEG_RST0 0xD0 /* RST0 marker code */
+#define JPEG_EOI 0xD9 /* EOI marker code */
+#define JPEG_APP0 0xE0 /* APP0 marker code */
+#define JPEG_COM 0xFE /* COM marker code */
+
+
+/* If we have a brain-damaged compiler that emits warnings (or worse, errors)
+ * for structure definitions that are never filled in, keep it quiet by
+ * supplying dummy definitions for the various substructures.
+ */
+
+#ifdef INCOMPLETE_TYPES_BROKEN
+#ifndef JPEG_INTERNALS /* will be defined in jpegint.h */
+struct jvirt_sarray_control { long dummy; };
+struct jvirt_barray_control { long dummy; };
+struct jpeg_comp_master { long dummy; };
+struct jpeg_c_main_controller { long dummy; };
+struct jpeg_c_prep_controller { long dummy; };
+struct jpeg_c_coef_controller { long dummy; };
+struct jpeg_marker_writer { long dummy; };
+struct jpeg_color_converter { long dummy; };
+struct jpeg_downsampler { long dummy; };
+struct jpeg_forward_dct { long dummy; };
+struct jpeg_entropy_encoder { long dummy; };
+struct jpeg_decomp_master { long dummy; };
+struct jpeg_d_main_controller { long dummy; };
+struct jpeg_d_coef_controller { long dummy; };
+struct jpeg_d_post_controller { long dummy; };
+struct jpeg_input_controller { long dummy; };
+struct jpeg_marker_reader { long dummy; };
+struct jpeg_entropy_decoder { long dummy; };
+struct jpeg_inverse_dct { long dummy; };
+struct jpeg_upsampler { long dummy; };
+struct jpeg_color_deconverter { long dummy; };
+struct jpeg_color_quantizer { long dummy; };
+#endif /* JPEG_INTERNALS */
+#endif /* INCOMPLETE_TYPES_BROKEN */
+
+
+/*
+ * The JPEG library modules define JPEG_INTERNALS before including this file.
+ * The internal structure declarations are read only when that is true.
+ * Applications using the library should not include jpegint.h, but may wish
+ * to include jerror.h.
+ */
+
+#ifdef JPEG_INTERNALS
+#include "jpegint.h" /* fetch private declarations */
+#include "jerror.h" /* fetch error codes too */
+#endif
+
+#endif /* JPEGLIB_H */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jquant1.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jquant1.c
new file mode 100644
index 0000000..32206ab
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jquant1.c
@@ -0,0 +1,856 @@
+/*
+ * jquant1.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains 1-pass color quantization (color mapping) routines.
+ * These routines provide mapping to a fixed color map using equally spaced
+ * color values. Optional Floyd-Steinberg or ordered dithering is available.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+#ifdef TQUANT_1PASS_SUPPORTED
+
+
+/*
+ * The main purpose of 1-pass quantization is to provide a fast, if not very
+ * high quality, colormapped output capability. A 2-pass quantizer usually
+ * gives better visual quality; however, for quantized grayscale output this
+ * quantizer is perfectly adequate. Dithering is highly recommended with this
+ * quantizer, though you can turn it off if you really want to.
+ *
+ * In 1-pass quantization the colormap must be chosen in advance of seeing the
+ * image. We use a map consisting of all combinations of Ncolors[i] color
+ * values for the i'th component. The Ncolors[] values are chosen so that
+ * their product, the total number of colors, is no more than that requested.
+ * (In most cases, the product will be somewhat less.)
+ *
+ * Since the colormap is orthogonal, the representative value for each color
+ * component can be determined without considering the other components;
+ * then these indexes can be combined into a colormap index by a standard
+ * N-dimensional-array-subscript calculation. Most of the arithmetic involved
+ * can be precalculated and stored in the lookup table colorindex[].
+ * colorindex[i][j] maps pixel value j in component i to the nearest
+ * representative value (grid plane) for that component; this index is
+ * multiplied by the array stride for component i, so that the
+ * index of the colormap entry closest to a given pixel value is just
+ * sum( colorindex[component-number][pixel-component-value] )
+ * Aside from being fast, this scheme allows for variable spacing between
+ * representative values with no additional lookup cost.
+ *
+ * If gamma correction has been applied in color conversion, it might be wise
+ * to adjust the color grid spacing so that the representative colors are
+ * equidistant in linear space. At this writing, gamma correction is not
+ * implemented by jdcolor, so nothing is done here.
+ */
+
+
+/* Declarations for ordered dithering.
+ *
+ * We use a standard 16x16 ordered dither array. The basic concept of ordered
+ * dithering is described in many references, for instance Dale Schumacher's
+ * chapter II.2 of Graphics Gems II (James Arvo, ed. Academic Press, 1991).
+ * In place of Schumacher's comparisons against a "threshold" value, we add a
+ * "dither" value to the input pixel and then round the result to the nearest
+ * output value. The dither value is equivalent to (0.5 - threshold) times
+ * the distance between output values. For ordered dithering, we assume that
+ * the output colors are equally spaced; if not, results will probably be
+ * worse, since the dither may be too much or too little at a given point.
+ *
+ * The normal calculation would be to form pixel value + dither, range-limit
+ * this to 0..MAXJSAMPLE, and then index into the colorindex table as usual.
+ * We can skip the separate range-limiting step by extending the colorindex
+ * table in both directions.
+ */
+
+#define ODITHER_SIZE 16 /* dimension of dither matrix */
+/* NB: if ODITHER_SIZE is not a power of 2, ODITHER_MASK uses will break */
+#define ODITHER_CELLS (ODITHER_SIZE*ODITHER_SIZE) /* # cells in matrix */
+#define ODITHER_MASK (ODITHER_SIZE-1) /* tqmask for wrapping around counters */
+
+typedef int ODITHER_MATRIX[ODITHER_SIZE][ODITHER_SIZE];
+typedef int (*ODITHER_MATRIX_PTR)[ODITHER_SIZE];
+
+static const UINT8 base_dither_matrix[ODITHER_SIZE][ODITHER_SIZE] = {
+ /* Bayer's order-4 dither array. Generated by the code given in
+ * Stephen Hawley's article "Ordered Dithering" in Graphics Gems I.
+ * The values in this array must range from 0 to ODITHER_CELLS-1.
+ */
+ { 0,192, 48,240, 12,204, 60,252, 3,195, 51,243, 15,207, 63,255 },
+ { 128, 64,176,112,140, 76,188,124,131, 67,179,115,143, 79,191,127 },
+ { 32,224, 16,208, 44,236, 28,220, 35,227, 19,211, 47,239, 31,223 },
+ { 160, 96,144, 80,172,108,156, 92,163, 99,147, 83,175,111,159, 95 },
+ { 8,200, 56,248, 4,196, 52,244, 11,203, 59,251, 7,199, 55,247 },
+ { 136, 72,184,120,132, 68,180,116,139, 75,187,123,135, 71,183,119 },
+ { 40,232, 24,216, 36,228, 20,212, 43,235, 27,219, 39,231, 23,215 },
+ { 168,104,152, 88,164,100,148, 84,171,107,155, 91,167,103,151, 87 },
+ { 2,194, 50,242, 14,206, 62,254, 1,193, 49,241, 13,205, 61,253 },
+ { 130, 66,178,114,142, 78,190,126,129, 65,177,113,141, 77,189,125 },
+ { 34,226, 18,210, 46,238, 30,222, 33,225, 17,209, 45,237, 29,221 },
+ { 162, 98,146, 82,174,110,158, 94,161, 97,145, 81,173,109,157, 93 },
+ { 10,202, 58,250, 6,198, 54,246, 9,201, 57,249, 5,197, 53,245 },
+ { 138, 74,186,122,134, 70,182,118,137, 73,185,121,133, 69,181,117 },
+ { 42,234, 26,218, 38,230, 22,214, 41,233, 25,217, 37,229, 21,213 },
+ { 170,106,154, 90,166,102,150, 86,169,105,153, 89,165,101,149, 85 }
+};
+
+
+/* Declarations for Floyd-Steinberg dithering.
+ *
+ * Errors are accumulated into the array fserrors[], at a resolution of
+ * 1/16th of a pixel count. The error at a given pixel is propagated
+ * to its not-yet-processed neighbors using the standard F-S fractions,
+ * ... (here) 7/16
+ * 3/16 5/16 1/16
+ * We work left-to-right on even rows, right-to-left on odd rows.
+ *
+ * We can get away with a single array (holding one row's worth of errors)
+ * by using it to store the current row's errors at pixel columns not yet
+ * processed, but the next row's errors at columns already processed. We
+ * need only a few extra variables to hold the errors immediately around the
+ * current column. (If we are lucky, those variables are in registers, but
+ * even if not, they're probably cheaper to access than array elements are.)
+ *
+ * The fserrors[] array is indexed [component#][position].
+ * We provide (#columns + 2) entries per component; the extra entry at each
+ * end saves us from special-casing the first and last pixels.
+ *
+ * Note: on a wide image, we might not have enough room in a PC's near data
+ * segment to hold the error array; so it is allocated with alloc_large.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+typedef INT16 FSERROR; /* 16 bits should be enough */
+typedef int LOCFSERROR; /* use 'int' for calculation temps */
+#else
+typedef INT32 FSERROR; /* may need more than 16 bits */
+typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */
+#endif
+
+typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
+
+
+/* Private subobject */
+
+#define MAX_TQ_COMPS 4 /* max components I can handle */
+
+typedef struct {
+ struct jpeg_color_quantizer pub; /* public fields */
+
+ /* Initially allocated colormap is saved here */
+ JSAMPARRAY sv_colormap; /* The color map as a 2-D pixel array */
+ int sv_actual; /* number of entries in use */
+
+ JSAMPARRAY colorindex; /* Precomputed mapping for speed */
+ /* colorindex[i][j] = index of color closest to pixel value j in component i,
+ * premultiplied as described above. Since colormap indexes must fit into
+ * JSAMPLEs, the entries of this array will too.
+ */
+ boolean is_padded; /* is the colorindex padded for odither? */
+
+ int Ncolors[MAX_TQ_COMPS]; /* # of values alloced to each component */
+
+ /* Variables for ordered dithering */
+ int row_index; /* cur row's vertical index in dither matrix */
+ ODITHER_MATRIX_PTR odither[MAX_TQ_COMPS]; /* one dither array per component */
+
+ /* Variables for Floyd-Steinberg dithering */
+ FSERRPTR fserrors[MAX_TQ_COMPS]; /* accumulated errors */
+ boolean on_odd_row; /* flag to remember which row we are on */
+} my_cquantizer;
+
+typedef my_cquantizer * my_cquantize_ptr;
+
+
+/*
+ * Policy-making subroutines for create_colormap and create_colorindex.
+ * These routines determine the colormap to be used. The rest of the module
+ * only assumes that the colormap is orthogonal.
+ *
+ * * select_ncolors decides how to divvy up the available colors
+ * among the components.
+ * * output_value defines the set of representative values for a component.
+ * * largest_input_value defines the mapping from input values to
+ * representative values for a component.
+ * Note that the latter two routines may impose different policies for
+ * different components, though this is not currently done.
+ */
+
+
+LOCAL(int)
+select_ncolors (j_decompress_ptr cinfo, int Ncolors[])
+/* Determine allocation of desired colors to components, */
+/* and fill in Ncolors[] array to indicate choice. */
+/* Return value is total number of colors (product of Ncolors[] values). */
+{
+ int nc = cinfo->out_color_components; /* number of color components */
+ int max_colors = cinfo->desired_number_of_colors;
+ int total_colors, iroot, i, j;
+ boolean changed;
+ long temp;
+ static const int RGB_order[3] = { RGB_GREEN, RGB_RED, RGB_BLUE };
+
+ /* We can allocate at least the nc'th root of max_colors per component. */
+ /* Compute floor(nc'th root of max_colors). */
+ iroot = 1;
+ do {
+ iroot++;
+ temp = iroot; /* set temp = iroot ** nc */
+ for (i = 1; i < nc; i++)
+ temp *= iroot;
+ } while (temp <= (long) max_colors); /* repeat till iroot exceeds root */
+ iroot--; /* now iroot = floor(root) */
+
+ /* Must have at least 2 color values per component */
+ if (iroot < 2)
+ ERREXIT1(cinfo, JERR_TQUANT_FEW_COLORS, (int) temp);
+
+ /* Initialize to iroot color values for each component */
+ total_colors = 1;
+ for (i = 0; i < nc; i++) {
+ Ncolors[i] = iroot;
+ total_colors *= iroot;
+ }
+ /* We may be able to increment the count for one or more components without
+ * exceeding max_colors, though we know not all can be incremented.
+ * Sometimes, the first component can be incremented more than once!
+ * (Example: for 16 colors, we start at 2*2*2, go to 3*2*2, then 4*2*2.)
+ * In RGB colorspace, try to increment G first, then R, then B.
+ */
+ do {
+ changed = FALSE;
+ for (i = 0; i < nc; i++) {
+ j = (cinfo->out_color_space == JCS_RGB ? RGB_order[i] : i);
+ /* calculate new total_colors if Ncolors[j] is incremented */
+ temp = total_colors / Ncolors[j];
+ temp *= Ncolors[j]+1; /* done in long arith to avoid oflo */
+ if (temp > (long) max_colors)
+ break; /* won't fit, done with this pass */
+ Ncolors[j]++; /* OK, apply the increment */
+ total_colors = (int) temp;
+ changed = TRUE;
+ }
+ } while (changed);
+
+ return total_colors;
+}
+
+
+LOCAL(int)
+output_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
+/* Return j'th output value, where j will range from 0 to maxj */
+/* The output values must fall in 0..MAXJSAMPLE in increasing order */
+{
+ /* We always provide values 0 and MAXJSAMPLE for each component;
+ * any additional values are equally spaced between these limits.
+ * (Forcing the upper and lower values to the limits ensures that
+ * dithering can't produce a color outside the selected gamut.)
+ */
+ return (int) (((INT32) j * MAXJSAMPLE + maxj/2) / maxj);
+}
+
+
+LOCAL(int)
+largest_input_value (j_decompress_ptr cinfo, int ci, int j, int maxj)
+/* Return largest input value that should map to j'th output value */
+/* Must have largest(j=0) >= 0, and largest(j=maxj) >= MAXJSAMPLE */
+{
+ /* Breakpoints are halfway between values returned by output_value */
+ return (int) (((INT32) (2*j + 1) * MAXJSAMPLE + maxj) / (2*maxj));
+}
+
+
+/*
+ * Create the colormap.
+ */
+
+LOCAL(void)
+create_colormap (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ JSAMPARRAY colormap; /* Created colormap */
+ int total_colors; /* Number of distinct output colors */
+ int i,j,k, nci, blksize, blkdist, ptr, val;
+
+ /* Select number of colors for each component */
+ total_colors = select_ncolors(cinfo, cquantize->Ncolors);
+
+ /* Report selected color counts */
+ if (cinfo->out_color_components == 3)
+ TRACEMS4(cinfo, 1, JTRC_TQUANT_3_NCOLORS,
+ total_colors, cquantize->Ncolors[0],
+ cquantize->Ncolors[1], cquantize->Ncolors[2]);
+ else
+ TRACEMS1(cinfo, 1, JTRC_TQUANT_NCOLORS, total_colors);
+
+ /* Allocate and fill in the colormap. */
+ /* The colors are ordered in the map in standard row-major order, */
+ /* i.e. rightmost (highest-indexed) color changes most rapidly. */
+
+ colormap = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (JDIMENSION) total_colors, (JDIMENSION) cinfo->out_color_components);
+
+ /* blksize is number of adjacent repeated entries for a component */
+ /* blkdist is distance between groups of identical entries for a component */
+ blkdist = total_colors;
+
+ for (i = 0; i < cinfo->out_color_components; i++) {
+ /* fill in colormap entries for i'th color component */
+ nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
+ blksize = blkdist / nci;
+ for (j = 0; j < nci; j++) {
+ /* Compute j'th output value (out of nci) for component */
+ val = output_value(cinfo, i, j, nci-1);
+ /* Fill in all colormap entries that have this value of this component */
+ for (ptr = j * blksize; ptr < total_colors; ptr += blkdist) {
+ /* fill in blksize entries beginning at ptr */
+ for (k = 0; k < blksize; k++)
+ colormap[i][ptr+k] = (JSAMPLE) val;
+ }
+ }
+ blkdist = blksize; /* blksize of this color is blkdist of next */
+ }
+
+ /* Save the colormap in private storage,
+ * where it will survive color quantization mode changes.
+ */
+ cquantize->sv_colormap = colormap;
+ cquantize->sv_actual = total_colors;
+}
+
+
+/*
+ * Create the color index table.
+ */
+
+LOCAL(void)
+create_colorindex (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ JSAMPROW indexptr;
+ int i,j,k, nci, blksize, val, pad;
+
+ /* For ordered dither, we pad the color index tables by MAXJSAMPLE in
+ * each direction (input index values can be -MAXJSAMPLE .. 2*MAXJSAMPLE).
+ * This is not necessary in the other dithering modes. However, we
+ * flag whether it was done in case user changes dithering mode.
+ */
+ if (cinfo->dither_mode == JDITHER_ORDERED) {
+ pad = MAXJSAMPLE*2;
+ cquantize->is_padded = TRUE;
+ } else {
+ pad = 0;
+ cquantize->is_padded = FALSE;
+ }
+
+ cquantize->colorindex = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (JDIMENSION) (MAXJSAMPLE+1 + pad),
+ (JDIMENSION) cinfo->out_color_components);
+
+ /* blksize is number of adjacent repeated entries for a component */
+ blksize = cquantize->sv_actual;
+
+ for (i = 0; i < cinfo->out_color_components; i++) {
+ /* fill in colorindex entries for i'th color component */
+ nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
+ blksize = blksize / nci;
+
+ /* adjust colorindex pointers to provide padding at negative indexes. */
+ if (pad)
+ cquantize->colorindex[i] += MAXJSAMPLE;
+
+ /* in loop, val = index of current output value, */
+ /* and k = largest j that maps to current val */
+ indexptr = cquantize->colorindex[i];
+ val = 0;
+ k = largest_input_value(cinfo, i, 0, nci-1);
+ for (j = 0; j <= MAXJSAMPLE; j++) {
+ while (j > k) /* advance val if past boundary */
+ k = largest_input_value(cinfo, i, ++val, nci-1);
+ /* premultiply so that no multiplication needed in main processing */
+ indexptr[j] = (JSAMPLE) (val * blksize);
+ }
+ /* Pad at both ends if necessary */
+ if (pad)
+ for (j = 1; j <= MAXJSAMPLE; j++) {
+ indexptr[-j] = indexptr[0];
+ indexptr[MAXJSAMPLE+j] = indexptr[MAXJSAMPLE];
+ }
+ }
+}
+
+
+/*
+ * Create an ordered-dither array for a component having ncolors
+ * distinct output values.
+ */
+
+LOCAL(ODITHER_MATRIX_PTR)
+make_odither_array (j_decompress_ptr cinfo, int ncolors)
+{
+ ODITHER_MATRIX_PTR odither;
+ int j,k;
+ INT32 num,den;
+
+ odither = (ODITHER_MATRIX_PTR)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(ODITHER_MATRIX));
+ /* The inter-value distance for this color is MAXJSAMPLE/(ncolors-1).
+ * Hence the dither value for the matrix cell with fill order f
+ * (f=0..N-1) should be (N-1-2*f)/(2*N) * MAXJSAMPLE/(ncolors-1).
+ * On 16-bit-int machine, be careful to avoid overflow.
+ */
+ den = 2 * ODITHER_CELLS * ((INT32) (ncolors - 1));
+ for (j = 0; j < ODITHER_SIZE; j++) {
+ for (k = 0; k < ODITHER_SIZE; k++) {
+ num = ((INT32) (ODITHER_CELLS-1 - 2*((int)base_dither_matrix[j][k])))
+ * MAXJSAMPLE;
+ /* Ensure round towards zero despite C's lack of consistency
+ * about rounding negative values in integer division...
+ */
+ odither[j][k] = (int) (num<0 ? -((-num)/den) : num/den);
+ }
+ }
+ return odither;
+}
+
+
+/*
+ * Create the ordered-dither tables.
+ * Components having the same number of representative colors may
+ * share a dither table.
+ */
+
+LOCAL(void)
+create_odither_tables (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ ODITHER_MATRIX_PTR odither;
+ int i, j, nci;
+
+ for (i = 0; i < cinfo->out_color_components; i++) {
+ nci = cquantize->Ncolors[i]; /* # of distinct values for this color */
+ odither = NULL; /* search for matching prior component */
+ for (j = 0; j < i; j++) {
+ if (nci == cquantize->Ncolors[j]) {
+ odither = cquantize->odither[j];
+ break;
+ }
+ }
+ if (odither == NULL) /* need a new table? */
+ odither = make_odither_array(cinfo, nci);
+ cquantize->odither[i] = odither;
+ }
+}
+
+
+/*
+ * Map some rows of pixels to the output colormapped representation.
+ */
+
+METHODDEF(void)
+color_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+/* General case, no dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ JSAMPARRAY colorindex = cquantize->colorindex;
+ register int pixcode, ci;
+ register JSAMPROW ptrin, ptrout;
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+ register int nc = cinfo->out_color_components;
+
+ for (row = 0; row < num_rows; row++) {
+ ptrin = input_buf[row];
+ ptrout = output_buf[row];
+ for (col = width; col > 0; col--) {
+ pixcode = 0;
+ for (ci = 0; ci < nc; ci++) {
+ pixcode += GETJSAMPLE(colorindex[ci][GETJSAMPLE(*ptrin++)]);
+ }
+ *ptrout++ = (JSAMPLE) pixcode;
+ }
+ }
+}
+
+
+METHODDEF(void)
+color_quantize3 (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+/* Fast path for out_color_components==3, no dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ register int pixcode;
+ register JSAMPROW ptrin, ptrout;
+ JSAMPROW colorindex0 = cquantize->colorindex[0];
+ JSAMPROW colorindex1 = cquantize->colorindex[1];
+ JSAMPROW colorindex2 = cquantize->colorindex[2];
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+
+ for (row = 0; row < num_rows; row++) {
+ ptrin = input_buf[row];
+ ptrout = output_buf[row];
+ for (col = width; col > 0; col--) {
+ pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*ptrin++)]);
+ pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*ptrin++)]);
+ pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*ptrin++)]);
+ *ptrout++ = (JSAMPLE) pixcode;
+ }
+ }
+}
+
+
+METHODDEF(void)
+quantize_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+/* General case, with ordered dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ register JSAMPROW input_ptr;
+ register JSAMPROW output_ptr;
+ JSAMPROW colorindex_ci;
+ int * dither; /* points to active row of dither matrix */
+ int row_index, col_index; /* current indexes into dither matrix */
+ int nc = cinfo->out_color_components;
+ int ci;
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+
+ for (row = 0; row < num_rows; row++) {
+ /* Initialize output values to 0 so can process components separately */
+ jzero_far((void FAR *) output_buf[row],
+ (size_t) (width * SIZEOF(JSAMPLE)));
+ row_index = cquantize->row_index;
+ for (ci = 0; ci < nc; ci++) {
+ input_ptr = input_buf[row] + ci;
+ output_ptr = output_buf[row];
+ colorindex_ci = cquantize->colorindex[ci];
+ dither = cquantize->odither[ci][row_index];
+ col_index = 0;
+
+ for (col = width; col > 0; col--) {
+ /* Form pixel value + dither, range-limit to 0..MAXJSAMPLE,
+ * select output value, accumulate into output code for this pixel.
+ * Range-limiting need not be done explicitly, as we have extended
+ * the colorindex table to produce the right answers for out-of-range
+ * inputs. The maximum dither is +- MAXJSAMPLE; this sets the
+ * required amount of padding.
+ */
+ *output_ptr += colorindex_ci[GETJSAMPLE(*input_ptr)+dither[col_index]];
+ input_ptr += nc;
+ output_ptr++;
+ col_index = (col_index + 1) & ODITHER_MASK;
+ }
+ }
+ /* Advance row index for next row */
+ row_index = (row_index + 1) & ODITHER_MASK;
+ cquantize->row_index = row_index;
+ }
+}
+
+
+METHODDEF(void)
+quantize3_ord_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+/* Fast path for out_color_components==3, with ordered dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ register int pixcode;
+ register JSAMPROW input_ptr;
+ register JSAMPROW output_ptr;
+ JSAMPROW colorindex0 = cquantize->colorindex[0];
+ JSAMPROW colorindex1 = cquantize->colorindex[1];
+ JSAMPROW colorindex2 = cquantize->colorindex[2];
+ int * dither0; /* points to active row of dither matrix */
+ int * dither1;
+ int * dither2;
+ int row_index, col_index; /* current indexes into dither matrix */
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+
+ for (row = 0; row < num_rows; row++) {
+ row_index = cquantize->row_index;
+ input_ptr = input_buf[row];
+ output_ptr = output_buf[row];
+ dither0 = cquantize->odither[0][row_index];
+ dither1 = cquantize->odither[1][row_index];
+ dither2 = cquantize->odither[2][row_index];
+ col_index = 0;
+
+ for (col = width; col > 0; col--) {
+ pixcode = GETJSAMPLE(colorindex0[GETJSAMPLE(*input_ptr++) +
+ dither0[col_index]]);
+ pixcode += GETJSAMPLE(colorindex1[GETJSAMPLE(*input_ptr++) +
+ dither1[col_index]]);
+ pixcode += GETJSAMPLE(colorindex2[GETJSAMPLE(*input_ptr++) +
+ dither2[col_index]]);
+ *output_ptr++ = (JSAMPLE) pixcode;
+ col_index = (col_index + 1) & ODITHER_MASK;
+ }
+ row_index = (row_index + 1) & ODITHER_MASK;
+ cquantize->row_index = row_index;
+ }
+}
+
+
+METHODDEF(void)
+quantize_fs_dither (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+/* General case, with Floyd-Steinberg dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ register LOCFSERROR cur; /* current error or pixel value */
+ LOCFSERROR belowerr; /* error for pixel below cur */
+ LOCFSERROR bpreverr; /* error for below/prev col */
+ LOCFSERROR bnexterr; /* error for below/next col */
+ LOCFSERROR delta;
+ register FSERRPTR errorptr; /* => fserrors[] at column before current */
+ register JSAMPROW input_ptr;
+ register JSAMPROW output_ptr;
+ JSAMPROW colorindex_ci;
+ JSAMPROW colormap_ci;
+ int pixcode;
+ int nc = cinfo->out_color_components;
+ int dir; /* 1 for left-to-right, -1 for right-to-left */
+ int dirnc; /* dir * nc */
+ int ci;
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+ JSAMPLE *range_limit = cinfo->sample_range_limit;
+ SHIFT_TEMPS
+
+ for (row = 0; row < num_rows; row++) {
+ /* Initialize output values to 0 so can process components separately */
+ jzero_far((void FAR *) output_buf[row],
+ (size_t) (width * SIZEOF(JSAMPLE)));
+ for (ci = 0; ci < nc; ci++) {
+ input_ptr = input_buf[row] + ci;
+ output_ptr = output_buf[row];
+ if (cquantize->on_odd_row) {
+ /* work right to left in this row */
+ input_ptr += (width-1) * nc; /* so point to rightmost pixel */
+ output_ptr += width-1;
+ dir = -1;
+ dirnc = -nc;
+ errorptr = cquantize->fserrors[ci] + (width+1); /* => entry after last column */
+ } else {
+ /* work left to right in this row */
+ dir = 1;
+ dirnc = nc;
+ errorptr = cquantize->fserrors[ci]; /* => entry before first column */
+ }
+ colorindex_ci = cquantize->colorindex[ci];
+ colormap_ci = cquantize->sv_colormap[ci];
+ /* Preset error values: no error propagated to first pixel from left */
+ cur = 0;
+ /* and no error propagated to row below yet */
+ belowerr = bpreverr = 0;
+
+ for (col = width; col > 0; col--) {
+ /* cur holds the error propagated from the previous pixel on the
+ * current line. Add the error propagated from the previous line
+ * to form the complete error correction term for this pixel, and
+ * round the error term (which is expressed * 16) to an integer.
+ * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
+ * for either sign of the error value.
+ * Note: errorptr points to *previous* column's array entry.
+ */
+ cur = RIGHT_SHIFT(cur + errorptr[dir] + 8, 4);
+ /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
+ * The maximum error is +- MAXJSAMPLE; this sets the required size
+ * of the range_limit array.
+ */
+ cur += GETJSAMPLE(*input_ptr);
+ cur = GETJSAMPLE(range_limit[cur]);
+ /* Select output value, accumulate into output code for this pixel */
+ pixcode = GETJSAMPLE(colorindex_ci[cur]);
+ *output_ptr += (JSAMPLE) pixcode;
+ /* Compute actual representation error at this pixel */
+ /* Note: we can do this even though we don't have the final */
+ /* pixel code, because the colormap is orthogonal. */
+ cur -= GETJSAMPLE(colormap_ci[pixcode]);
+ /* Compute error fractions to be propagated to adjacent pixels.
+ * Add these into the running sums, and simultaneously shift the
+ * next-line error sums left by 1 column.
+ */
+ bnexterr = cur;
+ delta = cur * 2;
+ cur += delta; /* form error * 3 */
+ errorptr[0] = (FSERROR) (bpreverr + cur);
+ cur += delta; /* form error * 5 */
+ bpreverr = belowerr + cur;
+ belowerr = bnexterr;
+ cur += delta; /* form error * 7 */
+ /* At this point cur tqcontains the 7/16 error value to be propagated
+ * to the next pixel on the current line, and all the errors for the
+ * next line have been shifted over. We are therefore ready to move on.
+ */
+ input_ptr += dirnc; /* advance input ptr to next column */
+ output_ptr += dir; /* advance output ptr to next column */
+ errorptr += dir; /* advance errorptr to current column */
+ }
+ /* Post-loop cleanup: we must unload the final error value into the
+ * final fserrors[] entry. Note we need not unload belowerr because
+ * it is for the dummy column before or after the actual array.
+ */
+ errorptr[0] = (FSERROR) bpreverr; /* unload prev err into array */
+ }
+ cquantize->on_odd_row = (cquantize->on_odd_row ? FALSE : TRUE);
+ }
+}
+
+
+/*
+ * Allocate workspace for Floyd-Steinberg errors.
+ */
+
+LOCAL(void)
+alloc_fs_workspace (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ size_t arraysize;
+ int i;
+
+ arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
+ for (i = 0; i < cinfo->out_color_components; i++) {
+ cquantize->fserrors[i] = (FSERRPTR)
+ (*cinfo->mem->alloc_large)((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
+ }
+}
+
+
+/*
+ * Initialize for one-pass color quantization.
+ */
+
+METHODDEF(void)
+start_pass_1_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ size_t arraysize;
+ int i;
+
+ /* Install my colormap. */
+ cinfo->colormap = cquantize->sv_colormap;
+ cinfo->actual_number_of_colors = cquantize->sv_actual;
+
+ /* Initialize for desired dithering mode. */
+ switch (cinfo->dither_mode) {
+ case JDITHER_NONE:
+ if (cinfo->out_color_components == 3)
+ cquantize->pub.color_quantize = color_quantize3;
+ else
+ cquantize->pub.color_quantize = color_quantize;
+ break;
+ case JDITHER_ORDERED:
+ if (cinfo->out_color_components == 3)
+ cquantize->pub.color_quantize = quantize3_ord_dither;
+ else
+ cquantize->pub.color_quantize = quantize_ord_dither;
+ cquantize->row_index = 0; /* initialize state for ordered dither */
+ /* If user changed to ordered dither from another mode,
+ * we must recreate the color index table with padding.
+ * This will cost extra space, but probably isn't very likely.
+ */
+ if (! cquantize->is_padded)
+ create_colorindex(cinfo);
+ /* Create ordered-dither tables if we didn't already. */
+ if (cquantize->odither[0] == NULL)
+ create_odither_tables(cinfo);
+ break;
+ case JDITHER_FS:
+ cquantize->pub.color_quantize = quantize_fs_dither;
+ cquantize->on_odd_row = FALSE; /* initialize state for F-S dither */
+ /* Allocate Floyd-Steinberg workspace if didn't already. */
+ if (cquantize->fserrors[0] == NULL)
+ alloc_fs_workspace(cinfo);
+ /* Initialize the propagated errors to zero. */
+ arraysize = (size_t) ((cinfo->output_width + 2) * SIZEOF(FSERROR));
+ for (i = 0; i < cinfo->out_color_components; i++)
+ jzero_far((void FAR *) cquantize->fserrors[i], arraysize);
+ break;
+ default:
+ ERREXIT(cinfo, JERR_NOT_COMPILED);
+ break;
+ }
+}
+
+
+/*
+ * Finish up at the end of the pass.
+ */
+
+METHODDEF(void)
+finish_pass_1_quant (j_decompress_ptr cinfo)
+{
+ /* no work in 1-pass case */
+}
+
+
+/*
+ * Switch to a new external colormap between output passes.
+ * Shouldn't get to this module!
+ */
+
+METHODDEF(void)
+new_color_map_1_quant (j_decompress_ptr cinfo)
+{
+ ERREXIT(cinfo, JERR_MODE_CHANGE);
+}
+
+
+/*
+ * Module initialization routine for 1-pass color quantization.
+ */
+
+GLOBAL(void)
+jinit_1pass_quantizer (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize;
+
+ cquantize = (my_cquantize_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_cquantizer));
+ cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
+ cquantize->pub.start_pass = start_pass_1_quant;
+ cquantize->pub.finish_pass = finish_pass_1_quant;
+ cquantize->pub.new_color_map = new_color_map_1_quant;
+ cquantize->fserrors[0] = NULL; /* Flag FS workspace not allocated */
+ cquantize->odither[0] = NULL; /* Also flag odither arrays not allocated */
+
+ /* Make sure my internal arrays won't overflow */
+ if (cinfo->out_color_components > MAX_TQ_COMPS)
+ ERREXIT1(cinfo, JERR_TQUANT_COMPONENTS, MAX_TQ_COMPS);
+ /* Make sure colormap indexes can be represented by JSAMPLEs */
+ if (cinfo->desired_number_of_colors > (MAXJSAMPLE+1))
+ ERREXIT1(cinfo, JERR_TQUANT_MANY_COLORS, MAXJSAMPLE+1);
+
+ /* Create the colormap and color index table. */
+ create_colormap(cinfo);
+ create_colorindex(cinfo);
+
+ /* Allocate Floyd-Steinberg workspace now if requested.
+ * We do this now since it is FAR storage and may affect the memory
+ * manager's space calculations. If the user changes to FS dither
+ * mode in a later pass, we will allocate the space then, and will
+ * possibly overrun the max_memory_to_use setting.
+ */
+ if (cinfo->dither_mode == JDITHER_FS)
+ alloc_fs_workspace(cinfo);
+}
+
+#endif /* TQUANT_1PASS_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jquant2.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jquant2.c
new file mode 100644
index 0000000..ccd6986
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jquant2.c
@@ -0,0 +1,1310 @@
+/*
+ * jquant2.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains 2-pass color quantization (color mapping) routines.
+ * These routines provide selection of a custom color map for an image,
+ * followed by mapping of the image to that color map, with optional
+ * Floyd-Steinberg dithering.
+ * It is also possible to use just the second pass to map to an arbitrary
+ * externally-given color map.
+ *
+ * Note: ordered dithering is not supported, since there isn't any fast
+ * way to compute intercolor distances; it's unclear that ordered dither's
+ * fundamental assumptions even hold with an irregularly spaced color map.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+#ifdef TQUANT_2PASS_SUPPORTED
+
+
+/*
+ * This module implements the well-known Heckbert paradigm for color
+ * quantization. Most of the ideas used here can be traced back to
+ * Heckbert's seminal paper
+ * Heckbert, Paul. "Color Image Quantization for Frame Buffer Display",
+ * Proc. SIGGRAPH '82, Computer Graphics v.16 #3 (July 1982), pp 297-304.
+ *
+ * In the first pass over the image, we accumulate a histogram showing the
+ * usage count of each possible color. To keep the histogram to a reasonable
+ * size, we reduce the precision of the input; typical practice is to retain
+ * 5 or 6 bits per color, so that 8 or 4 different input values are counted
+ * in the same histogram cell.
+ *
+ * Next, the color-selection step begins with a box representing the whole
+ * color space, and repeatedly splits the "largest" remaining box until we
+ * have as many boxes as desired colors. Then the mean color in each
+ * remaining box becomes one of the possible output colors.
+ *
+ * The second pass over the image maps each input pixel to the closest output
+ * color (optionally after applying a Floyd-Steinberg dithering correction).
+ * This mapping is logically trivial, but making it go fast enough requires
+ * considerable care.
+ *
+ * Heckbert-style quantizers vary a good deal in their policies for choosing
+ * the "largest" box and deciding where to cut it. The particular policies
+ * used here have proved out well in experimental comparisons, but better ones
+ * may yet be found.
+ *
+ * In earlier versions of the IJG code, this module quantized in YCbCr color
+ * space, processing the raw upsampled data without a color conversion step.
+ * This allowed the color conversion math to be done only once per colormap
+ * entry, not once per pixel. However, that optimization precluded other
+ * useful optimizations (such as merging color conversion with upsampling)
+ * and it also interfered with desired capabilities such as quantizing to an
+ * externally-supplied colormap. We have therefore abandoned that approach.
+ * The present code works in the post-conversion color space, typically RGB.
+ *
+ * To improve the visual quality of the results, we actually work in scaled
+ * RGB space, giving G distances more weight than R, and R in turn more than
+ * B. To do everything in integer math, we must use integer scale factors.
+ * The 2/3/1 scale factors used here correspond loosely to the relative
+ * weights of the colors in the NTSC grayscale equation.
+ * If you want to use this code to quantize a non-RGB color space, you'll
+ * probably need to change these scale factors.
+ */
+
+#define R_SCALE 2 /* scale R distances by this much */
+#define G_SCALE 3 /* scale G distances by this much */
+#define B_SCALE 1 /* and B by this much */
+
+/* Relabel R/G/B as components 0/1/2, respecting the RGB ordering defined
+ * in jmorecfg.h. As the code stands, it will do the right thing for R,G,B
+ * and B,G,R orders. If you define some other weird order in jmorecfg.h,
+ * you'll get compile errors until you extend this logic. In that case
+ * you'll probably want to tweak the histogram sizes too.
+ */
+
+#if RGB_RED == 0
+#define C0_SCALE R_SCALE
+#endif
+#if RGB_BLUE == 0
+#define C0_SCALE B_SCALE
+#endif
+#if RGB_GREEN == 1
+#define C1_SCALE G_SCALE
+#endif
+#if RGB_RED == 2
+#define C2_SCALE R_SCALE
+#endif
+#if RGB_BLUE == 2
+#define C2_SCALE B_SCALE
+#endif
+
+
+/*
+ * First we have the histogram data structure and routines for creating it.
+ *
+ * The number of bits of precision can be adjusted by changing these symbols.
+ * We recommend keeping 6 bits for G and 5 each for R and B.
+ * If you have plenty of memory and cycles, 6 bits all around gives marginally
+ * better results; if you are short of memory, 5 bits all around will save
+ * some space but degrade the results.
+ * To maintain a fully accurate histogram, we'd need to allocate a "long"
+ * (preferably unsigned long) for each cell. In practice this is overkill;
+ * we can get by with 16 bits per cell. Few of the cell counts will overflow,
+ * and clamping those that do overflow to the maximum value will give close-
+ * enough results. This reduces the recommended histogram size from 256Kb
+ * to 128Kb, which is a useful savings on PC-class machines.
+ * (In the second pass the histogram space is re-used for pixel mapping data;
+ * in that capacity, each cell must be able to store zero to the number of
+ * desired colors. 16 bits/cell is plenty for that too.)
+ * Since the JPEG code is intended to run in small memory model on 80x86
+ * machines, we can't just allocate the histogram in one chunk. Instead
+ * of a true 3-D array, we use a row of pointers to 2-D arrays. Each
+ * pointer corresponds to a C0 value (typically 2^5 = 32 pointers) and
+ * each 2-D array has 2^6*2^5 = 2048 or 2^6*2^6 = 4096 entries. Note that
+ * on 80x86 machines, the pointer row is in near memory but the actual
+ * arrays are in far memory (same arrangement as we use for image arrays).
+ */
+
+#define MAXNUMCOLORS (MAXJSAMPLE+1) /* maximum size of colormap */
+
+/* These will do the right thing for either R,G,B or B,G,R color order,
+ * but you may not like the results for other color orders.
+ */
+#define HIST_C0_BITS 5 /* bits of precision in R/B histogram */
+#define HIST_C1_BITS 6 /* bits of precision in G histogram */
+#define HIST_C2_BITS 5 /* bits of precision in B/R histogram */
+
+/* Number of elements along histogram axes. */
+#define HIST_C0_ELEMS (1<<HIST_C0_BITS)
+#define HIST_C1_ELEMS (1<<HIST_C1_BITS)
+#define HIST_C2_ELEMS (1<<HIST_C2_BITS)
+
+/* These are the amounts to shift an input value to get a histogram index. */
+#define C0_SHIFT (BITS_IN_JSAMPLE-HIST_C0_BITS)
+#define C1_SHIFT (BITS_IN_JSAMPLE-HIST_C1_BITS)
+#define C2_SHIFT (BITS_IN_JSAMPLE-HIST_C2_BITS)
+
+
+typedef UINT16 histcell; /* histogram cell; prefer an unsigned type */
+
+typedef histcell FAR * histptr; /* for pointers to histogram cells */
+
+typedef histcell hist1d[HIST_C2_ELEMS]; /* typedefs for the array */
+typedef hist1d FAR * hist2d; /* type for the 2nd-level pointers */
+typedef hist2d * hist3d; /* type for top-level pointer */
+
+
+/* Declarations for Floyd-Steinberg dithering.
+ *
+ * Errors are accumulated into the array fserrors[], at a resolution of
+ * 1/16th of a pixel count. The error at a given pixel is propagated
+ * to its not-yet-processed neighbors using the standard F-S fractions,
+ * ... (here) 7/16
+ * 3/16 5/16 1/16
+ * We work left-to-right on even rows, right-to-left on odd rows.
+ *
+ * We can get away with a single array (holding one row's worth of errors)
+ * by using it to store the current row's errors at pixel columns not yet
+ * processed, but the next row's errors at columns already processed. We
+ * need only a few extra variables to hold the errors immediately around the
+ * current column. (If we are lucky, those variables are in registers, but
+ * even if not, they're probably cheaper to access than array elements are.)
+ *
+ * The fserrors[] array has (#columns + 2) entries; the extra entry at
+ * each end saves us from special-casing the first and last pixels.
+ * Each entry is three values long, one value for each color component.
+ *
+ * Note: on a wide image, we might not have enough room in a PC's near data
+ * segment to hold the error array; so it is allocated with alloc_large.
+ */
+
+#if BITS_IN_JSAMPLE == 8
+typedef INT16 FSERROR; /* 16 bits should be enough */
+typedef int LOCFSERROR; /* use 'int' for calculation temps */
+#else
+typedef INT32 FSERROR; /* may need more than 16 bits */
+typedef INT32 LOCFSERROR; /* be sure calculation temps are big enough */
+#endif
+
+typedef FSERROR FAR *FSERRPTR; /* pointer to error array (in FAR storage!) */
+
+
+/* Private subobject */
+
+typedef struct {
+ struct jpeg_color_quantizer pub; /* public fields */
+
+ /* Space for the eventually created colormap is stashed here */
+ JSAMPARRAY sv_colormap; /* colormap allocated at init time */
+ int desired; /* desired # of colors = size of colormap */
+
+ /* Variables for accumulating image statistics */
+ hist3d histogram; /* pointer to the histogram */
+
+ boolean needs_zeroed; /* TRUE if next pass must zero histogram */
+
+ /* Variables for Floyd-Steinberg dithering */
+ FSERRPTR fserrors; /* accumulated errors */
+ boolean on_odd_row; /* flag to remember which row we are on */
+ int * error_limiter; /* table for clamping the applied error */
+} my_cquantizer;
+
+typedef my_cquantizer * my_cquantize_ptr;
+
+
+/*
+ * Prescan some rows of pixels.
+ * In this module the prescan simply updates the histogram, which has been
+ * initialized to zeroes by start_pass.
+ * An output_buf parameter is required by the method signature, but no data
+ * is actually output (in fact the buffer controller is probably passing a
+ * NULL pointer).
+ */
+
+METHODDEF(void)
+prescan_quantize (j_decompress_ptr cinfo, JSAMPARRAY input_buf,
+ JSAMPARRAY output_buf, int num_rows)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ register JSAMPROW ptr;
+ register histptr histp;
+ register hist3d histogram = cquantize->histogram;
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+
+ for (row = 0; row < num_rows; row++) {
+ ptr = input_buf[row];
+ for (col = width; col > 0; col--) {
+ /* get pixel value and index into the histogram */
+ histp = & histogram[GETJSAMPLE(ptr[0]) >> C0_SHIFT]
+ [GETJSAMPLE(ptr[1]) >> C1_SHIFT]
+ [GETJSAMPLE(ptr[2]) >> C2_SHIFT];
+ /* increment, check for overflow and undo increment if so. */
+ if (++(*histp) <= 0)
+ (*histp)--;
+ ptr += 3;
+ }
+ }
+}
+
+
+/*
+ * Next we have the really interesting routines: selection of a colormap
+ * given the completed histogram.
+ * These routines work with a list of "boxes", each representing a rectangular
+ * subset of the input color space (to histogram precision).
+ */
+
+typedef struct {
+ /* The bounds of the box (inclusive); expressed as histogram indexes */
+ int c0min, c0max;
+ int c1min, c1max;
+ int c2min, c2max;
+ /* The volume (actually 2-norm) of the box */
+ INT32 volume;
+ /* The number of nonzero histogram cells within this box */
+ long colorcount;
+} box;
+
+typedef box * boxptr;
+
+
+LOCAL(boxptr)
+tqfind_biggest_color_pop (boxptr boxlist, int numboxes)
+/* Find the splittable box with the largest color population */
+/* Returns NULL if no splittable boxes remain */
+{
+ register boxptr boxp;
+ register int i;
+ register long maxc = 0;
+ boxptr which = NULL;
+
+ for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
+ if (boxp->colorcount > maxc && boxp->volume > 0) {
+ which = boxp;
+ maxc = boxp->colorcount;
+ }
+ }
+ return which;
+}
+
+
+LOCAL(boxptr)
+tqfind_biggest_volume (boxptr boxlist, int numboxes)
+/* Find the splittable box with the largest (scaled) volume */
+/* Returns NULL if no splittable boxes remain */
+{
+ register boxptr boxp;
+ register int i;
+ register INT32 maxv = 0;
+ boxptr which = NULL;
+
+ for (i = 0, boxp = boxlist; i < numboxes; i++, boxp++) {
+ if (boxp->volume > maxv) {
+ which = boxp;
+ maxv = boxp->volume;
+ }
+ }
+ return which;
+}
+
+
+LOCAL(void)
+update_box (j_decompress_ptr cinfo, boxptr boxp)
+/* Shrink the min/max bounds of a box to enclose only nonzero elements, */
+/* and recompute its volume and population */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ histptr histp;
+ int c0,c1,c2;
+ int c0min,c0max,c1min,c1max,c2min,c2max;
+ INT32 dist0,dist1,dist2;
+ long ccount;
+
+ c0min = boxp->c0min; c0max = boxp->c0max;
+ c1min = boxp->c1min; c1max = boxp->c1max;
+ c2min = boxp->c2min; c2max = boxp->c2max;
+
+ if (c0max > c0min)
+ for (c0 = c0min; c0 <= c0max; c0++)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c0min = c0min = c0;
+ goto have_c0min;
+ }
+ }
+ have_c0min:
+ if (c0max > c0min)
+ for (c0 = c0max; c0 >= c0min; c0--)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c0max = c0max = c0;
+ goto have_c0max;
+ }
+ }
+ have_c0max:
+ if (c1max > c1min)
+ for (c1 = c1min; c1 <= c1max; c1++)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c1min = c1min = c1;
+ goto have_c1min;
+ }
+ }
+ have_c1min:
+ if (c1max > c1min)
+ for (c1 = c1max; c1 >= c1min; c1--)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++)
+ if (*histp++ != 0) {
+ boxp->c1max = c1max = c1;
+ goto have_c1max;
+ }
+ }
+ have_c1max:
+ if (c2max > c2min)
+ for (c2 = c2min; c2 <= c2max; c2++)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1min][c2];
+ for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
+ if (*histp != 0) {
+ boxp->c2min = c2min = c2;
+ goto have_c2min;
+ }
+ }
+ have_c2min:
+ if (c2max > c2min)
+ for (c2 = c2max; c2 >= c2min; c2--)
+ for (c0 = c0min; c0 <= c0max; c0++) {
+ histp = & histogram[c0][c1min][c2];
+ for (c1 = c1min; c1 <= c1max; c1++, histp += HIST_C2_ELEMS)
+ if (*histp != 0) {
+ boxp->c2max = c2max = c2;
+ goto have_c2max;
+ }
+ }
+ have_c2max:
+
+ /* Update box volume.
+ * We use 2-norm rather than real volume here; this biases the method
+ * against making long narrow boxes, and it has the side benefit that
+ * a box is splittable iff norm > 0.
+ * Since the differences are expressed in histogram-cell units,
+ * we have to shift back to JSAMPLE units to get consistent distances;
+ * after which, we scale according to the selected distance scale factors.
+ */
+ dist0 = ((c0max - c0min) << C0_SHIFT) * C0_SCALE;
+ dist1 = ((c1max - c1min) << C1_SHIFT) * C1_SCALE;
+ dist2 = ((c2max - c2min) << C2_SHIFT) * C2_SCALE;
+ boxp->volume = dist0*dist0 + dist1*dist1 + dist2*dist2;
+
+ /* Now scan remaining volume of box and compute population */
+ ccount = 0;
+ for (c0 = c0min; c0 <= c0max; c0++)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++, histp++)
+ if (*histp != 0) {
+ ccount++;
+ }
+ }
+ boxp->colorcount = ccount;
+}
+
+
+LOCAL(int)
+median_cut (j_decompress_ptr cinfo, boxptr boxlist, int numboxes,
+ int desired_colors)
+/* Repeatedly select and split the largest box until we have enough boxes */
+{
+ int n,lb;
+ int c0,c1,c2,cmax;
+ register boxptr b1,b2;
+
+ while (numboxes < desired_colors) {
+ /* Select box to split.
+ * Current algorithm: by population for first half, then by volume.
+ */
+ if (numboxes*2 <= desired_colors) {
+ b1 = tqfind_biggest_color_pop(boxlist, numboxes);
+ } else {
+ b1 = tqfind_biggest_volume(boxlist, numboxes);
+ }
+ if (b1 == NULL) /* no splittable boxes left! */
+ break;
+ b2 = &boxlist[numboxes]; /* where new box will go */
+ /* Copy the color bounds to the new box. */
+ b2->c0max = b1->c0max; b2->c1max = b1->c1max; b2->c2max = b1->c2max;
+ b2->c0min = b1->c0min; b2->c1min = b1->c1min; b2->c2min = b1->c2min;
+ /* Choose which axis to split the box on.
+ * Current algorithm: longest scaled axis.
+ * See notes in update_box about scaling distances.
+ */
+ c0 = ((b1->c0max - b1->c0min) << C0_SHIFT) * C0_SCALE;
+ c1 = ((b1->c1max - b1->c1min) << C1_SHIFT) * C1_SCALE;
+ c2 = ((b1->c2max - b1->c2min) << C2_SHIFT) * C2_SCALE;
+ /* We want to break any ties in favor of green, then red, blue last.
+ * This code does the right thing for R,G,B or B,G,R color orders only.
+ */
+#if RGB_RED == 0
+ cmax = c1; n = 1;
+ if (c0 > cmax) { cmax = c0; n = 0; }
+ if (c2 > cmax) { n = 2; }
+#else
+ cmax = c1; n = 1;
+ if (c2 > cmax) { cmax = c2; n = 2; }
+ if (c0 > cmax) { n = 0; }
+#endif
+ /* Choose split point along selected axis, and update box bounds.
+ * Current algorithm: split at halfway point.
+ * (Since the box has been shrunk to minimum volume,
+ * any split will produce two nonempty subboxes.)
+ * Note that lb value is max for lower box, so must be < old max.
+ */
+ switch (n) {
+ case 0:
+ lb = (b1->c0max + b1->c0min) / 2;
+ b1->c0max = lb;
+ b2->c0min = lb+1;
+ break;
+ case 1:
+ lb = (b1->c1max + b1->c1min) / 2;
+ b1->c1max = lb;
+ b2->c1min = lb+1;
+ break;
+ case 2:
+ lb = (b1->c2max + b1->c2min) / 2;
+ b1->c2max = lb;
+ b2->c2min = lb+1;
+ break;
+ }
+ /* Update stats for boxes */
+ update_box(cinfo, b1);
+ update_box(cinfo, b2);
+ numboxes++;
+ }
+ return numboxes;
+}
+
+
+LOCAL(void)
+compute_color (j_decompress_ptr cinfo, boxptr boxp, int icolor)
+/* Compute representative color for a box, put it in colormap[icolor] */
+{
+ /* Current algorithm: mean weighted by pixels (not colors) */
+ /* Note it is important to get the rounding correct! */
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ histptr histp;
+ int c0,c1,c2;
+ int c0min,c0max,c1min,c1max,c2min,c2max;
+ long count;
+ long total = 0;
+ long c0total = 0;
+ long c1total = 0;
+ long c2total = 0;
+
+ c0min = boxp->c0min; c0max = boxp->c0max;
+ c1min = boxp->c1min; c1max = boxp->c1max;
+ c2min = boxp->c2min; c2max = boxp->c2max;
+
+ for (c0 = c0min; c0 <= c0max; c0++)
+ for (c1 = c1min; c1 <= c1max; c1++) {
+ histp = & histogram[c0][c1][c2min];
+ for (c2 = c2min; c2 <= c2max; c2++) {
+ if ((count = *histp++) != 0) {
+ total += count;
+ c0total += ((c0 << C0_SHIFT) + ((1<<C0_SHIFT)>>1)) * count;
+ c1total += ((c1 << C1_SHIFT) + ((1<<C1_SHIFT)>>1)) * count;
+ c2total += ((c2 << C2_SHIFT) + ((1<<C2_SHIFT)>>1)) * count;
+ }
+ }
+ }
+
+ cinfo->colormap[0][icolor] = (JSAMPLE) ((c0total + (total>>1)) / total);
+ cinfo->colormap[1][icolor] = (JSAMPLE) ((c1total + (total>>1)) / total);
+ cinfo->colormap[2][icolor] = (JSAMPLE) ((c2total + (total>>1)) / total);
+}
+
+
+LOCAL(void)
+select_colors (j_decompress_ptr cinfo, int desired_colors)
+/* Master routine for color selection */
+{
+ boxptr boxlist;
+ int numboxes;
+ int i;
+
+ /* Allocate workspace for box list */
+ boxlist = (boxptr) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, desired_colors * SIZEOF(box));
+ /* Initialize one box containing whole space */
+ numboxes = 1;
+ boxlist[0].c0min = 0;
+ boxlist[0].c0max = MAXJSAMPLE >> C0_SHIFT;
+ boxlist[0].c1min = 0;
+ boxlist[0].c1max = MAXJSAMPLE >> C1_SHIFT;
+ boxlist[0].c2min = 0;
+ boxlist[0].c2max = MAXJSAMPLE >> C2_SHIFT;
+ /* Shrink it to actually-used volume and set its statistics */
+ update_box(cinfo, & boxlist[0]);
+ /* Perform median-cut to produce final box list */
+ numboxes = median_cut(cinfo, boxlist, numboxes, desired_colors);
+ /* Compute the representative color for each box, fill colormap */
+ for (i = 0; i < numboxes; i++)
+ compute_color(cinfo, & boxlist[i], i);
+ cinfo->actual_number_of_colors = numboxes;
+ TRACEMS1(cinfo, 1, JTRC_TQUANT_SELECTED, numboxes);
+}
+
+
+/*
+ * These routines are concerned with the time-critical task of mapping input
+ * colors to the nearest color in the selected colormap.
+ *
+ * We re-use the histogram space as an "inverse color map", essentially a
+ * cache for the results of nearest-color searches. All colors within a
+ * histogram cell will be mapped to the same colormap entry, namely the one
+ * closest to the cell's center. This may not be quite the closest entry to
+ * the actual input color, but it's almost as good. A zero in the cache
+ * indicates we haven't found the nearest color for that cell yet; the array
+ * is cleared to zeroes before starting the mapping pass. When we tqfind the
+ * nearest color for a cell, its colormap index plus one is recorded in the
+ * cache for future use. The pass2 scanning routines call fill_inverse_cmap
+ * when they need to use an unfilled entry in the cache.
+ *
+ * Our method of efficiently tqfinding nearest colors is based on the "locally
+ * sorted search" idea described by Heckbert and on the incremental distance
+ * calculation described by Spencer W. Thomas in chapter III.1 of Graphics
+ * Gems II (James Arvo, ed. Academic Press, 1991). Thomas points out that
+ * the distances from a given colormap entry to each cell of the histogram can
+ * be computed quickly using an incremental method: the differences between
+ * distances to adjacent cells themselves differ by a constant. This allows a
+ * fairly fast implementation of the "brute force" approach of computing the
+ * distance from every colormap entry to every histogram cell. Unfortunately,
+ * it needs a work array to hold the best-distance-so-far for each histogram
+ * cell (because the inner loop has to be over cells, not colormap entries).
+ * The work array elements have to be INT32s, so the work array would need
+ * 256Kb at our recommended precision. This is not feasible in DOS machines.
+ *
+ * To get around these problems, we apply Thomas' method to compute the
+ * nearest colors for only the cells within a small subbox of the histogram.
+ * The work array need be only as big as the subbox, so the memory usage
+ * problem is solved. Furthermore, we need not fill subboxes that are never
+ * referenced in pass2; many images use only part of the color gamut, so a
+ * fair amount of work is saved. An additional advantage of this
+ * approach is that we can apply Heckbert's locality criterion to quickly
+ * eliminate colormap entries that are far away from the subbox; typically
+ * three-fourths of the colormap entries are rejected by Heckbert's criterion,
+ * and we need not compute their distances to individual cells in the subbox.
+ * The speed of this approach is heavily influenced by the subbox size: too
+ * small means too much overhead, too big loses because Heckbert's criterion
+ * can't eliminate as many colormap entries. Empirically the best subbox
+ * size seems to be about 1/512th of the histogram (1/8th in each direction).
+ *
+ * Thomas' article also describes a refined method which is asymptotically
+ * faster than the brute-force method, but it is also far more complex and
+ * cannot efficiently be applied to small subboxes. It is therefore not
+ * useful for programs intended to be portable to DOS machines. On machines
+ * with plenty of memory, filling the whole histogram in one shot with Thomas'
+ * refined method might be faster than the present code --- but then again,
+ * it might not be any faster, and it's certainly more complicated.
+ */
+
+
+/* log2(histogram cells in update box) for each axis; this can be adjusted */
+#define BOX_C0_LOG (HIST_C0_BITS-3)
+#define BOX_C1_LOG (HIST_C1_BITS-3)
+#define BOX_C2_LOG (HIST_C2_BITS-3)
+
+#define BOX_C0_ELEMS (1<<BOX_C0_LOG) /* # of hist cells in update box */
+#define BOX_C1_ELEMS (1<<BOX_C1_LOG)
+#define BOX_C2_ELEMS (1<<BOX_C2_LOG)
+
+#define BOX_C0_SHIFT (C0_SHIFT + BOX_C0_LOG)
+#define BOX_C1_SHIFT (C1_SHIFT + BOX_C1_LOG)
+#define BOX_C2_SHIFT (C2_SHIFT + BOX_C2_LOG)
+
+
+/*
+ * The next three routines implement inverse colormap filling. They could
+ * all be folded into one big routine, but splitting them up this way saves
+ * some stack space (the mindist[] and bestdist[] arrays need not coexist)
+ * and may allow some compilers to produce better code by registerizing more
+ * inner-loop variables.
+ */
+
+LOCAL(int)
+tqfind_nearby_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
+ JSAMPLE colorlist[])
+/* Locate the colormap entries close enough to an update box to be candidates
+ * for the nearest entry to some cell(s) in the update box. The update box
+ * is specified by the center coordinates of its first cell. The number of
+ * candidate colormap entries is returned, and their colormap indexes are
+ * placed in colorlist[].
+ * This routine uses Heckbert's "locally sorted search" criterion to select
+ * the colors that need further consideration.
+ */
+{
+ int numcolors = cinfo->actual_number_of_colors;
+ int maxc0, maxc1, maxc2;
+ int centerc0, centerc1, centerc2;
+ int i, x, ncolors;
+ INT32 minmaxdist, min_dist, max_dist, tdist;
+ INT32 mindist[MAXNUMCOLORS]; /* min distance to colormap entry i */
+
+ /* Compute true coordinates of update box's upper corner and center.
+ * Actually we compute the coordinates of the center of the upper-corner
+ * histogram cell, which are the upper bounds of the volume we care about.
+ * Note that since ">>" rounds down, the "center" values may be closer to
+ * min than to max; hence comparisons to them must be "<=", not "<".
+ */
+ maxc0 = minc0 + ((1 << BOX_C0_SHIFT) - (1 << C0_SHIFT));
+ centerc0 = (minc0 + maxc0) >> 1;
+ maxc1 = minc1 + ((1 << BOX_C1_SHIFT) - (1 << C1_SHIFT));
+ centerc1 = (minc1 + maxc1) >> 1;
+ maxc2 = minc2 + ((1 << BOX_C2_SHIFT) - (1 << C2_SHIFT));
+ centerc2 = (minc2 + maxc2) >> 1;
+
+ /* For each color in colormap, tqfind:
+ * 1. its minimum squared-distance to any point in the update box
+ * (zero if color is within update box);
+ * 2. its maximum squared-distance to any point in the update box.
+ * Both of these can be found by considering only the corners of the box.
+ * We save the minimum distance for each color in mindist[];
+ * only the smallest maximum distance is of interest.
+ */
+ minmaxdist = 0x7FFFFFFFL;
+
+ for (i = 0; i < numcolors; i++) {
+ /* We compute the squared-c0-distance term, then add in the other two. */
+ x = GETJSAMPLE(cinfo->colormap[0][i]);
+ if (x < minc0) {
+ tdist = (x - minc0) * C0_SCALE;
+ min_dist = tdist*tdist;
+ tdist = (x - maxc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ } else if (x > maxc0) {
+ tdist = (x - maxc0) * C0_SCALE;
+ min_dist = tdist*tdist;
+ tdist = (x - minc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ } else {
+ /* within cell range so no contribution to min_dist */
+ min_dist = 0;
+ if (x <= centerc0) {
+ tdist = (x - maxc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ } else {
+ tdist = (x - minc0) * C0_SCALE;
+ max_dist = tdist*tdist;
+ }
+ }
+
+ x = GETJSAMPLE(cinfo->colormap[1][i]);
+ if (x < minc1) {
+ tdist = (x - minc1) * C1_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - maxc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ } else if (x > maxc1) {
+ tdist = (x - maxc1) * C1_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - minc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ /* within cell range so no contribution to min_dist */
+ if (x <= centerc1) {
+ tdist = (x - maxc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ tdist = (x - minc1) * C1_SCALE;
+ max_dist += tdist*tdist;
+ }
+ }
+
+ x = GETJSAMPLE(cinfo->colormap[2][i]);
+ if (x < minc2) {
+ tdist = (x - minc2) * C2_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - maxc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ } else if (x > maxc2) {
+ tdist = (x - maxc2) * C2_SCALE;
+ min_dist += tdist*tdist;
+ tdist = (x - minc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ /* within cell range so no contribution to min_dist */
+ if (x <= centerc2) {
+ tdist = (x - maxc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ } else {
+ tdist = (x - minc2) * C2_SCALE;
+ max_dist += tdist*tdist;
+ }
+ }
+
+ mindist[i] = min_dist; /* save away the results */
+ if (max_dist < minmaxdist)
+ minmaxdist = max_dist;
+ }
+
+ /* Now we know that no cell in the update box is more than minmaxdist
+ * away from some colormap entry. Therefore, only colors that are
+ * within minmaxdist of some part of the box need be considered.
+ */
+ ncolors = 0;
+ for (i = 0; i < numcolors; i++) {
+ if (mindist[i] <= minmaxdist)
+ colorlist[ncolors++] = (JSAMPLE) i;
+ }
+ return ncolors;
+}
+
+
+LOCAL(void)
+tqfind_best_colors (j_decompress_ptr cinfo, int minc0, int minc1, int minc2,
+ int numcolors, JSAMPLE colorlist[], JSAMPLE bestcolor[])
+/* Find the closest colormap entry for each cell in the update box,
+ * given the list of candidate colors prepared by tqfind_nearby_colors.
+ * Return the indexes of the closest entries in the bestcolor[] array.
+ * This routine uses Thomas' incremental distance calculation method to
+ * tqfind the distance from a colormap entry to successive cells in the box.
+ */
+{
+ int ic0, ic1, ic2;
+ int i, icolor;
+ register INT32 * bptr; /* pointer into bestdist[] array */
+ JSAMPLE * cptr; /* pointer into bestcolor[] array */
+ INT32 dist0, dist1; /* initial distance values */
+ register INT32 dist2; /* current distance in inner loop */
+ INT32 xx0, xx1; /* distance increments */
+ register INT32 xx2;
+ INT32 inc0, inc1, inc2; /* initial values for increments */
+ /* This array holds the distance to the nearest-so-far color for each cell */
+ INT32 bestdist[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
+
+ /* Initialize best-distance for each cell of the update box */
+ bptr = bestdist;
+ for (i = BOX_C0_ELEMS*BOX_C1_ELEMS*BOX_C2_ELEMS-1; i >= 0; i--)
+ *bptr++ = 0x7FFFFFFFL;
+
+ /* For each color selected by tqfind_nearby_colors,
+ * compute its distance to the center of each cell in the box.
+ * If that's less than best-so-far, update best distance and color number.
+ */
+
+ /* Nominal steps between cell centers ("x" in Thomas article) */
+#define STEP_C0 ((1 << C0_SHIFT) * C0_SCALE)
+#define STEP_C1 ((1 << C1_SHIFT) * C1_SCALE)
+#define STEP_C2 ((1 << C2_SHIFT) * C2_SCALE)
+
+ for (i = 0; i < numcolors; i++) {
+ icolor = GETJSAMPLE(colorlist[i]);
+ /* Compute (square of) distance from minc0/c1/c2 to this color */
+ inc0 = (minc0 - GETJSAMPLE(cinfo->colormap[0][icolor])) * C0_SCALE;
+ dist0 = inc0*inc0;
+ inc1 = (minc1 - GETJSAMPLE(cinfo->colormap[1][icolor])) * C1_SCALE;
+ dist0 += inc1*inc1;
+ inc2 = (minc2 - GETJSAMPLE(cinfo->colormap[2][icolor])) * C2_SCALE;
+ dist0 += inc2*inc2;
+ /* Form the initial difference increments */
+ inc0 = inc0 * (2 * STEP_C0) + STEP_C0 * STEP_C0;
+ inc1 = inc1 * (2 * STEP_C1) + STEP_C1 * STEP_C1;
+ inc2 = inc2 * (2 * STEP_C2) + STEP_C2 * STEP_C2;
+ /* Now loop over all cells in box, updating distance per Thomas method */
+ bptr = bestdist;
+ cptr = bestcolor;
+ xx0 = inc0;
+ for (ic0 = BOX_C0_ELEMS-1; ic0 >= 0; ic0--) {
+ dist1 = dist0;
+ xx1 = inc1;
+ for (ic1 = BOX_C1_ELEMS-1; ic1 >= 0; ic1--) {
+ dist2 = dist1;
+ xx2 = inc2;
+ for (ic2 = BOX_C2_ELEMS-1; ic2 >= 0; ic2--) {
+ if (dist2 < *bptr) {
+ *bptr = dist2;
+ *cptr = (JSAMPLE) icolor;
+ }
+ dist2 += xx2;
+ xx2 += 2 * STEP_C2 * STEP_C2;
+ bptr++;
+ cptr++;
+ }
+ dist1 += xx1;
+ xx1 += 2 * STEP_C1 * STEP_C1;
+ }
+ dist0 += xx0;
+ xx0 += 2 * STEP_C0 * STEP_C0;
+ }
+ }
+}
+
+
+LOCAL(void)
+fill_inverse_cmap (j_decompress_ptr cinfo, int c0, int c1, int c2)
+/* Fill the inverse-colormap entries in the update box that tqcontains */
+/* histogram cell c0/c1/c2. (Only that one cell MUST be filled, but */
+/* we can fill as many others as we wish.) */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ int minc0, minc1, minc2; /* lower left corner of update box */
+ int ic0, ic1, ic2;
+ register JSAMPLE * cptr; /* pointer into bestcolor[] array */
+ register histptr cachep; /* pointer into main cache array */
+ /* This array lists the candidate colormap indexes. */
+ JSAMPLE colorlist[MAXNUMCOLORS];
+ int numcolors; /* number of candidate colors */
+ /* This array holds the actually closest colormap index for each cell. */
+ JSAMPLE bestcolor[BOX_C0_ELEMS * BOX_C1_ELEMS * BOX_C2_ELEMS];
+
+ /* Convert cell coordinates to update box ID */
+ c0 >>= BOX_C0_LOG;
+ c1 >>= BOX_C1_LOG;
+ c2 >>= BOX_C2_LOG;
+
+ /* Compute true coordinates of update box's origin corner.
+ * Actually we compute the coordinates of the center of the corner
+ * histogram cell, which are the lower bounds of the volume we care about.
+ */
+ minc0 = (c0 << BOX_C0_SHIFT) + ((1 << C0_SHIFT) >> 1);
+ minc1 = (c1 << BOX_C1_SHIFT) + ((1 << C1_SHIFT) >> 1);
+ minc2 = (c2 << BOX_C2_SHIFT) + ((1 << C2_SHIFT) >> 1);
+
+ /* Determine which colormap entries are close enough to be candidates
+ * for the nearest entry to some cell in the update box.
+ */
+ numcolors = tqfind_nearby_colors(cinfo, minc0, minc1, minc2, colorlist);
+
+ /* Determine the actually nearest colors. */
+ tqfind_best_colors(cinfo, minc0, minc1, minc2, numcolors, colorlist,
+ bestcolor);
+
+ /* Save the best color numbers (plus 1) in the main cache array */
+ c0 <<= BOX_C0_LOG; /* convert ID back to base cell indexes */
+ c1 <<= BOX_C1_LOG;
+ c2 <<= BOX_C2_LOG;
+ cptr = bestcolor;
+ for (ic0 = 0; ic0 < BOX_C0_ELEMS; ic0++) {
+ for (ic1 = 0; ic1 < BOX_C1_ELEMS; ic1++) {
+ cachep = & histogram[c0+ic0][c1+ic1][c2];
+ for (ic2 = 0; ic2 < BOX_C2_ELEMS; ic2++) {
+ *cachep++ = (histcell) (GETJSAMPLE(*cptr++) + 1);
+ }
+ }
+ }
+}
+
+
+/*
+ * Map some rows of pixels to the output colormapped representation.
+ */
+
+METHODDEF(void)
+pass2_no_dither (j_decompress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
+/* This version performs no dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ register JSAMPROW inptr, outptr;
+ register histptr cachep;
+ register int c0, c1, c2;
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+
+ for (row = 0; row < num_rows; row++) {
+ inptr = input_buf[row];
+ outptr = output_buf[row];
+ for (col = width; col > 0; col--) {
+ /* get pixel value and index into the cache */
+ c0 = GETJSAMPLE(*inptr++) >> C0_SHIFT;
+ c1 = GETJSAMPLE(*inptr++) >> C1_SHIFT;
+ c2 = GETJSAMPLE(*inptr++) >> C2_SHIFT;
+ cachep = & histogram[c0][c1][c2];
+ /* If we have not seen this color before, tqfind nearest colormap entry */
+ /* and update the cache */
+ if (*cachep == 0)
+ fill_inverse_cmap(cinfo, c0,c1,c2);
+ /* Now emit the colormap index for this cell */
+ *outptr++ = (JSAMPLE) (*cachep - 1);
+ }
+ }
+}
+
+
+METHODDEF(void)
+pass2_fs_dither (j_decompress_ptr cinfo,
+ JSAMPARRAY input_buf, JSAMPARRAY output_buf, int num_rows)
+/* This version performs Floyd-Steinberg dithering */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ register LOCFSERROR cur0, cur1, cur2; /* current error or pixel value */
+ LOCFSERROR belowerr0, belowerr1, belowerr2; /* error for pixel below cur */
+ LOCFSERROR bpreverr0, bpreverr1, bpreverr2; /* error for below/prev col */
+ register FSERRPTR errorptr; /* => fserrors[] at column before current */
+ JSAMPROW inptr; /* => current input pixel */
+ JSAMPROW outptr; /* => current output pixel */
+ histptr cachep;
+ int dir; /* +1 or -1 depending on direction */
+ int dir3; /* 3*dir, for advancing inptr & errorptr */
+ int row;
+ JDIMENSION col;
+ JDIMENSION width = cinfo->output_width;
+ JSAMPLE *range_limit = cinfo->sample_range_limit;
+ int *error_limit = cquantize->error_limiter;
+ JSAMPROW colormap0 = cinfo->colormap[0];
+ JSAMPROW colormap1 = cinfo->colormap[1];
+ JSAMPROW colormap2 = cinfo->colormap[2];
+ SHIFT_TEMPS
+
+ for (row = 0; row < num_rows; row++) {
+ inptr = input_buf[row];
+ outptr = output_buf[row];
+ if (cquantize->on_odd_row) {
+ /* work right to left in this row */
+ inptr += (width-1) * 3; /* so point to rightmost pixel */
+ outptr += width-1;
+ dir = -1;
+ dir3 = -3;
+ errorptr = cquantize->fserrors + (width+1)*3; /* => entry after last column */
+ cquantize->on_odd_row = FALSE; /* flip for next time */
+ } else {
+ /* work left to right in this row */
+ dir = 1;
+ dir3 = 3;
+ errorptr = cquantize->fserrors; /* => entry before first real column */
+ cquantize->on_odd_row = TRUE; /* flip for next time */
+ }
+ /* Preset error values: no error propagated to first pixel from left */
+ cur0 = cur1 = cur2 = 0;
+ /* and no error propagated to row below yet */
+ belowerr0 = belowerr1 = belowerr2 = 0;
+ bpreverr0 = bpreverr1 = bpreverr2 = 0;
+
+ for (col = width; col > 0; col--) {
+ /* curN holds the error propagated from the previous pixel on the
+ * current line. Add the error propagated from the previous line
+ * to form the complete error correction term for this pixel, and
+ * round the error term (which is expressed * 16) to an integer.
+ * RIGHT_SHIFT rounds towards minus infinity, so adding 8 is correct
+ * for either sign of the error value.
+ * Note: errorptr points to *previous* column's array entry.
+ */
+ cur0 = RIGHT_SHIFT(cur0 + errorptr[dir3+0] + 8, 4);
+ cur1 = RIGHT_SHIFT(cur1 + errorptr[dir3+1] + 8, 4);
+ cur2 = RIGHT_SHIFT(cur2 + errorptr[dir3+2] + 8, 4);
+ /* Limit the error using transfer function set by init_error_limit.
+ * See comments with init_error_limit for rationale.
+ */
+ cur0 = error_limit[cur0];
+ cur1 = error_limit[cur1];
+ cur2 = error_limit[cur2];
+ /* Form pixel value + error, and range-limit to 0..MAXJSAMPLE.
+ * The maximum error is +- MAXJSAMPLE (or less with error limiting);
+ * this sets the required size of the range_limit array.
+ */
+ cur0 += GETJSAMPLE(inptr[0]);
+ cur1 += GETJSAMPLE(inptr[1]);
+ cur2 += GETJSAMPLE(inptr[2]);
+ cur0 = GETJSAMPLE(range_limit[cur0]);
+ cur1 = GETJSAMPLE(range_limit[cur1]);
+ cur2 = GETJSAMPLE(range_limit[cur2]);
+ /* Index into the cache with adjusted pixel value */
+ cachep = & histogram[cur0>>C0_SHIFT][cur1>>C1_SHIFT][cur2>>C2_SHIFT];
+ /* If we have not seen this color before, tqfind nearest colormap */
+ /* entry and update the cache */
+ if (*cachep == 0)
+ fill_inverse_cmap(cinfo, cur0>>C0_SHIFT,cur1>>C1_SHIFT,cur2>>C2_SHIFT);
+ /* Now emit the colormap index for this cell */
+ { register int pixcode = *cachep - 1;
+ *outptr = (JSAMPLE) pixcode;
+ /* Compute representation error for this pixel */
+ cur0 -= GETJSAMPLE(colormap0[pixcode]);
+ cur1 -= GETJSAMPLE(colormap1[pixcode]);
+ cur2 -= GETJSAMPLE(colormap2[pixcode]);
+ }
+ /* Compute error fractions to be propagated to adjacent pixels.
+ * Add these into the running sums, and simultaneously shift the
+ * next-line error sums left by 1 column.
+ */
+ { register LOCFSERROR bnexterr, delta;
+
+ bnexterr = cur0; /* Process component 0 */
+ delta = cur0 * 2;
+ cur0 += delta; /* form error * 3 */
+ errorptr[0] = (FSERROR) (bpreverr0 + cur0);
+ cur0 += delta; /* form error * 5 */
+ bpreverr0 = belowerr0 + cur0;
+ belowerr0 = bnexterr;
+ cur0 += delta; /* form error * 7 */
+ bnexterr = cur1; /* Process component 1 */
+ delta = cur1 * 2;
+ cur1 += delta; /* form error * 3 */
+ errorptr[1] = (FSERROR) (bpreverr1 + cur1);
+ cur1 += delta; /* form error * 5 */
+ bpreverr1 = belowerr1 + cur1;
+ belowerr1 = bnexterr;
+ cur1 += delta; /* form error * 7 */
+ bnexterr = cur2; /* Process component 2 */
+ delta = cur2 * 2;
+ cur2 += delta; /* form error * 3 */
+ errorptr[2] = (FSERROR) (bpreverr2 + cur2);
+ cur2 += delta; /* form error * 5 */
+ bpreverr2 = belowerr2 + cur2;
+ belowerr2 = bnexterr;
+ cur2 += delta; /* form error * 7 */
+ }
+ /* At this point curN tqcontains the 7/16 error value to be propagated
+ * to the next pixel on the current line, and all the errors for the
+ * next line have been shifted over. We are therefore ready to move on.
+ */
+ inptr += dir3; /* Advance pixel pointers to next column */
+ outptr += dir;
+ errorptr += dir3; /* advance errorptr to current column */
+ }
+ /* Post-loop cleanup: we must unload the final error values into the
+ * final fserrors[] entry. Note we need not unload belowerrN because
+ * it is for the dummy column before or after the actual array.
+ */
+ errorptr[0] = (FSERROR) bpreverr0; /* unload prev errs into array */
+ errorptr[1] = (FSERROR) bpreverr1;
+ errorptr[2] = (FSERROR) bpreverr2;
+ }
+}
+
+
+/*
+ * Initialize the error-limiting transfer function (lookup table).
+ * The raw F-S error computation can potentially compute error values of up to
+ * +- MAXJSAMPLE. But we want the maximum correction applied to a pixel to be
+ * much less, otherwise obviously wrong pixels will be created. (Typical
+ * effects include weird fringes at color-area boundaries, isolated bright
+ * pixels in a dark area, etc.) The standard advice for avoiding this problem
+ * is to ensure that the "corners" of the color cube are allocated as output
+ * colors; then repeated errors in the same direction cannot cause cascading
+ * error buildup. However, that only prevents the error from getting
+ * completely out of hand; Aaron Giles reports that error limiting improves
+ * the results even with corner colors allocated.
+ * A simple clamping of the error values to about +- MAXJSAMPLE/8 works pretty
+ * well, but the smoother transfer function used below is even better. Thanks
+ * to Aaron Giles for this idea.
+ */
+
+LOCAL(void)
+init_error_limit (j_decompress_ptr cinfo)
+/* Allocate and fill in the error_limiter table */
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ int * table;
+ int in, out;
+
+ table = (int *) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, (MAXJSAMPLE*2+1) * SIZEOF(int));
+ table += MAXJSAMPLE; /* so can index -MAXJSAMPLE .. +MAXJSAMPLE */
+ cquantize->error_limiter = table;
+
+#define STEPSIZE ((MAXJSAMPLE+1)/16)
+ /* Map errors 1:1 up to +- MAXJSAMPLE/16 */
+ out = 0;
+ for (in = 0; in < STEPSIZE; in++, out++) {
+ table[in] = out; table[-in] = -out;
+ }
+ /* Map errors 1:2 up to +- 3*MAXJSAMPLE/16 */
+ for (; in < STEPSIZE*3; in++, out += (in&1) ? 0 : 1) {
+ table[in] = out; table[-in] = -out;
+ }
+ /* Clamp the rest to final out value (which is (MAXJSAMPLE+1)/8) */
+ for (; in <= MAXJSAMPLE; in++) {
+ table[in] = out; table[-in] = -out;
+ }
+#undef STEPSIZE
+}
+
+
+/*
+ * Finish up at the end of each pass.
+ */
+
+METHODDEF(void)
+finish_pass1 (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+
+ /* Select the representative colors and fill in cinfo->colormap */
+ cinfo->colormap = cquantize->sv_colormap;
+ select_colors(cinfo, cquantize->desired);
+ /* Force next pass to zero the color index table */
+ cquantize->needs_zeroed = TRUE;
+}
+
+
+METHODDEF(void)
+finish_pass2 (j_decompress_ptr cinfo)
+{
+ /* no work */
+}
+
+
+/*
+ * Initialize for each processing pass.
+ */
+
+METHODDEF(void)
+start_pass_2_quant (j_decompress_ptr cinfo, boolean is_pre_scan)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+ hist3d histogram = cquantize->histogram;
+ int i;
+
+ /* Only F-S dithering or no dithering is supported. */
+ /* If user asks for ordered dither, give him F-S. */
+ if (cinfo->dither_mode != JDITHER_NONE)
+ cinfo->dither_mode = JDITHER_FS;
+
+ if (is_pre_scan) {
+ /* Set up method pointers */
+ cquantize->pub.color_quantize = prescan_quantize;
+ cquantize->pub.finish_pass = finish_pass1;
+ cquantize->needs_zeroed = TRUE; /* Always zero histogram */
+ } else {
+ /* Set up method pointers */
+ if (cinfo->dither_mode == JDITHER_FS)
+ cquantize->pub.color_quantize = pass2_fs_dither;
+ else
+ cquantize->pub.color_quantize = pass2_no_dither;
+ cquantize->pub.finish_pass = finish_pass2;
+
+ /* Make sure color count is acceptable */
+ i = cinfo->actual_number_of_colors;
+ if (i < 1)
+ ERREXIT1(cinfo, JERR_TQUANT_FEW_COLORS, 1);
+ if (i > MAXNUMCOLORS)
+ ERREXIT1(cinfo, JERR_TQUANT_MANY_COLORS, MAXNUMCOLORS);
+
+ if (cinfo->dither_mode == JDITHER_FS) {
+ size_t arraysize = (size_t) ((cinfo->output_width + 2) *
+ (3 * SIZEOF(FSERROR)));
+ /* Allocate Floyd-Steinberg workspace if we didn't already. */
+ if (cquantize->fserrors == NULL)
+ cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, arraysize);
+ /* Initialize the propagated errors to zero. */
+ jzero_far((void FAR *) cquantize->fserrors, arraysize);
+ /* Make the error-limit table if we didn't already. */
+ if (cquantize->error_limiter == NULL)
+ init_error_limit(cinfo);
+ cquantize->on_odd_row = FALSE;
+ }
+
+ }
+ /* Zero the histogram or inverse color map, if necessary */
+ if (cquantize->needs_zeroed) {
+ for (i = 0; i < HIST_C0_ELEMS; i++) {
+ jzero_far((void FAR *) histogram[i],
+ HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
+ }
+ cquantize->needs_zeroed = FALSE;
+ }
+}
+
+
+/*
+ * Switch to a new external colormap between output passes.
+ */
+
+METHODDEF(void)
+new_color_map_2_quant (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize = (my_cquantize_ptr) cinfo->cquantize;
+
+ /* Reset the inverse color map */
+ cquantize->needs_zeroed = TRUE;
+}
+
+
+/*
+ * Module initialization routine for 2-pass color quantization.
+ */
+
+GLOBAL(void)
+jinit_2pass_quantizer (j_decompress_ptr cinfo)
+{
+ my_cquantize_ptr cquantize;
+ int i;
+
+ cquantize = (my_cquantize_ptr)
+ (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ SIZEOF(my_cquantizer));
+ cinfo->cquantize = (struct jpeg_color_quantizer *) cquantize;
+ cquantize->pub.start_pass = start_pass_2_quant;
+ cquantize->pub.new_color_map = new_color_map_2_quant;
+ cquantize->fserrors = NULL; /* flag optional arrays not allocated */
+ cquantize->error_limiter = NULL;
+
+ /* Make sure jdmaster didn't give me a case I can't handle */
+ if (cinfo->out_color_components != 3)
+ ERREXIT(cinfo, JERR_NOTIMPL);
+
+ /* Allocate the histogram/inverse colormap storage */
+ cquantize->histogram = (hist3d) (*cinfo->mem->alloc_small)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE, HIST_C0_ELEMS * SIZEOF(hist2d));
+ for (i = 0; i < HIST_C0_ELEMS; i++) {
+ cquantize->histogram[i] = (hist2d) (*cinfo->mem->alloc_large)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ HIST_C1_ELEMS*HIST_C2_ELEMS * SIZEOF(histcell));
+ }
+ cquantize->needs_zeroed = TRUE; /* histogram is garbage now */
+
+ /* Allocate storage for the completed colormap, if required.
+ * We do this now since it is FAR storage and may affect
+ * the memory manager's space calculations.
+ */
+ if (cinfo->enable_2pass_quant) {
+ /* Make sure color count is acceptable */
+ int desired = cinfo->desired_number_of_colors;
+ /* Lower bound on # of colors ... somewhat arbitrary as long as > 0 */
+ if (desired < 8)
+ ERREXIT1(cinfo, JERR_TQUANT_FEW_COLORS, 8);
+ /* Make sure colormap indexes can be represented by JSAMPLEs */
+ if (desired > MAXNUMCOLORS)
+ ERREXIT1(cinfo, JERR_TQUANT_MANY_COLORS, MAXNUMCOLORS);
+ cquantize->sv_colormap = (*cinfo->mem->alloc_sarray)
+ ((j_common_ptr) cinfo,JPOOL_IMAGE, (JDIMENSION) desired, (JDIMENSION) 3);
+ cquantize->desired = desired;
+ } else
+ cquantize->sv_colormap = NULL;
+
+ /* Only F-S dithering or no dithering is supported. */
+ /* If user asks for ordered dither, give him F-S. */
+ if (cinfo->dither_mode != JDITHER_NONE)
+ cinfo->dither_mode = JDITHER_FS;
+
+ /* Allocate Floyd-Steinberg workspace if necessary.
+ * This isn't really needed until pass 2, but again it is FAR storage.
+ * Although we will cope with a later change in dither_mode,
+ * we do not promise to honor max_memory_to_use if dither_mode changes.
+ */
+ if (cinfo->dither_mode == JDITHER_FS) {
+ cquantize->fserrors = (FSERRPTR) (*cinfo->mem->alloc_large)
+ ((j_common_ptr) cinfo, JPOOL_IMAGE,
+ (size_t) ((cinfo->output_width + 2) * (3 * SIZEOF(FSERROR))));
+ /* Might as well create the error-limiting table too. */
+ init_error_limit(cinfo);
+ }
+}
+
+#endif /* TQUANT_2PASS_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jutils.c b/tqtinterface/qt4/src/3rdparty/libjpeg/jutils.c
new file mode 100644
index 0000000..ad73ff3
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jutils.c
@@ -0,0 +1,179 @@
+/*
+ * jutils.c
+ *
+ * Copyright (C) 1991-1996, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains tables and miscellaneous utility routines needed
+ * for both compression and decompression.
+ * Note we prefix all global names with "j" to minimize conflicts with
+ * a surrounding application.
+ */
+
+#define JPEG_INTERNALS
+#include "jinclude.h"
+#include "jpeglib.h"
+
+
+/*
+ * jpeg_zigzag_order[i] is the zigzag-order position of the i'th element
+ * of a DCT block read in natural order (left to right, top to bottom).
+ */
+
+#if 0 /* This table is not actually needed in v6a */
+
+const int jpeg_zigzag_order[DCTSIZE2] = {
+ 0, 1, 5, 6, 14, 15, 27, 28,
+ 2, 4, 7, 13, 16, 26, 29, 42,
+ 3, 8, 12, 17, 25, 30, 41, 43,
+ 9, 11, 18, 24, 31, 40, 44, 53,
+ 10, 19, 23, 32, 39, 45, 52, 54,
+ 20, 22, 33, 38, 46, 51, 55, 60,
+ 21, 34, 37, 47, 50, 56, 59, 61,
+ 35, 36, 48, 49, 57, 58, 62, 63
+};
+
+#endif
+
+/*
+ * jpeg_natural_order[i] is the natural-order position of the i'th element
+ * of zigzag order.
+ *
+ * When reading corrupted data, the Huffman decoders could attempt
+ * to reference an entry beyond the end of this array (if the decoded
+ * zero run length reaches past the end of the block). To prevent
+ * wild stores without adding an inner-loop test, we put some extra
+ * "63"s after the real entries. This will cause the extra coefficient
+ * to be stored in location 63 of the block, not somewhere random.
+ * The worst case would be a run-length of 15, which means we need 16
+ * fake entries.
+ */
+
+const int jpeg_natural_order[DCTSIZE2+16] = {
+ 0, 1, 8, 16, 9, 2, 3, 10,
+ 17, 24, 32, 25, 18, 11, 4, 5,
+ 12, 19, 26, 33, 40, 48, 41, 34,
+ 27, 20, 13, 6, 7, 14, 21, 28,
+ 35, 42, 49, 56, 57, 50, 43, 36,
+ 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63, /* extra entries for safety in decoder */
+ 63, 63, 63, 63, 63, 63, 63, 63
+};
+
+
+/*
+ * Arithmetic utilities
+ */
+
+GLOBAL(long)
+jdiv_round_up (long a, long b)
+/* Compute a/b rounded up to next integer, ie, ceil(a/b) */
+/* Assumes a >= 0, b > 0 */
+{
+ return (a + b - 1L) / b;
+}
+
+
+GLOBAL(long)
+jround_up (long a, long b)
+/* Compute a rounded up to next multiple of b, ie, ceil(a/b)*b */
+/* Assumes a >= 0, b > 0 */
+{
+ a += b - 1L;
+ return a - (a % b);
+}
+
+
+/* On normal machines we can apply MEMCOPY() and MEMZERO() to sample arrays
+ * and coefficient-block arrays. This won't work on 80x86 because the arrays
+ * are FAR and we're assuming a small-pointer memory model. However, some
+ * DOS compilers provide far-pointer versions of memcpy() and memset() even
+ * in the small-model libraries. These will be used if USE_FMEM is defined.
+ * Otherwise, the routines below do it the hard way. (The performance cost
+ * is not all that great, because these routines aren't very heavily used.)
+ */
+
+#ifndef NEED_FAR_POINTERS /* normal case, same as regular macros */
+#define FMEMCOPY(dest,src,size) MEMCOPY(dest,src,size)
+#define FMEMZERO(target,size) MEMZERO(target,size)
+#else /* 80x86 case, define if we can */
+#ifdef USE_FMEM
+#define FMEMCOPY(dest,src,size) _fmemcpy((void FAR *)(dest), (const void FAR *)(src), (size_t)(size))
+#define FMEMZERO(target,size) _fmemset((void FAR *)(target), 0, (size_t)(size))
+#endif
+#endif
+
+
+GLOBAL(void)
+jcopy_sample_rows (JSAMPARRAY input_array, int source_row,
+ JSAMPARRAY output_array, int dest_row,
+ int num_rows, JDIMENSION num_cols)
+/* Copy some rows of samples from one place to another.
+ * num_rows rows are copied from input_array[source_row++]
+ * to output_array[dest_row++]; these areas may overlap for duplication.
+ * The source and destination arrays must be at least as wide as num_cols.
+ */
+{
+ register JSAMPROW inptr, outptr;
+#ifdef FMEMCOPY
+ register size_t count = (size_t) (num_cols * SIZEOF(JSAMPLE));
+#else
+ register JDIMENSION count;
+#endif
+ register int row;
+
+ input_array += source_row;
+ output_array += dest_row;
+
+ for (row = num_rows; row > 0; row--) {
+ inptr = *input_array++;
+ outptr = *output_array++;
+#ifdef FMEMCOPY
+ FMEMCOPY(outptr, inptr, count);
+#else
+ for (count = num_cols; count > 0; count--)
+ *outptr++ = *inptr++; /* needn't bother with GETJSAMPLE() here */
+#endif
+ }
+}
+
+
+GLOBAL(void)
+jcopy_block_row (JBLOCKROW input_row, JBLOCKROW output_row,
+ JDIMENSION num_blocks)
+/* Copy a row of coefficient blocks from one place to another. */
+{
+#ifdef FMEMCOPY
+ FMEMCOPY(output_row, input_row, num_blocks * (DCTSIZE2 * SIZEOF(JCOEF)));
+#else
+ register JCOEFPTR inptr, outptr;
+ register long count;
+
+ inptr = (JCOEFPTR) input_row;
+ outptr = (JCOEFPTR) output_row;
+ for (count = (long) num_blocks * DCTSIZE2; count > 0; count--) {
+ *outptr++ = *inptr++;
+ }
+#endif
+}
+
+
+GLOBAL(void)
+jzero_far (void FAR * target, size_t bytestozero)
+/* Zero out a chunk of FAR memory. */
+/* This might be sample-array data, block-array data, or alloc_large data. */
+{
+#ifdef FMEMZERO
+ FMEMZERO(target, bytestozero);
+#else
+ register char FAR * ptr = (char FAR *) target;
+ register size_t count;
+
+ for (count = bytestozero; count > 0; count--) {
+ *ptr++ = 0;
+ }
+#endif
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/jversion.h b/tqtinterface/qt4/src/3rdparty/libjpeg/jversion.h
new file mode 100644
index 0000000..3e7fc07
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/jversion.h
@@ -0,0 +1,14 @@
+/*
+ * jversion.h
+ *
+ * Copyright (C) 1991-1998, Thomas G. Lane.
+ * This file is part of the Independent JPEG Group's software.
+ * For conditions of distribution and use, see the accompanying README file.
+ *
+ * This file tqcontains software version identification.
+ */
+
+
+#define JVERSION "6b 27-Mar-1998"
+
+#define JCOPYRIGHT "Copyright (C) 1998, Thomas G. Lane"
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/libjpeg.doc b/tqtinterface/qt4/src/3rdparty/libjpeg/libjpeg.doc
new file mode 100644
index 0000000..499b83c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/libjpeg.doc
@@ -0,0 +1,3006 @@
+USING THE IJG JPEG LIBRARY
+
+Copyright (C) 1994-1998, Thomas G. Lane.
+This file is part of the Independent JPEG Group's software.
+For conditions of distribution and use, see the accompanying README file.
+
+
+This file describes how to use the IJG JPEG library within an application
+program. Read it if you want to write a program that uses the library.
+
+The file example.c provides heavily commented skeleton code for calling the
+JPEG library. Also see jpeglib.h (the include file to be used by application
+programs) for full details about data structures and function parameter lists.
+The library source code, of course, is the ultimate reference.
+
+Note that there have been *major* changes from the application interface
+presented by IJG version 4 and earlier versions. The old design had several
+inherent limitations, and it had accumulated a lot of cruft as we added
+features while trying to minimize application-interface changes. We have
+sacrificed backward compatibility in the version 5 rewrite, but we think the
+improvements justify this.
+
+
+TABLE OF CONTENTS
+-----------------
+
+Overview:
+ Functions provided by the library
+ Outline of typical usage
+Basic library usage:
+ Data formats
+ Compression details
+ Decompression details
+ Mechanics of usage: include files, linking, etc
+Advanced features:
+ Compression parameter selection
+ Decompression parameter selection
+ Special color spaces
+ Error handling
+ Compressed data handling (source and destination managers)
+ I/O suspension
+ Progressive JPEG support
+ Buffered-image mode
+ Abbreviated datastreams and multiple images
+ Special markers
+ Raw (downsampled) image data
+ Really raw data: DCT coefficients
+ Progress monitoring
+ Memory management
+ Memory usage
+ Library compile-time options
+ Portability considerations
+ Notes for MS-DOS implementors
+
+You should read at least the overview and basic usage sections before trying
+to program with the library. The sections on advanced features can be read
+if and when you need them.
+
+
+OVERVIEW
+========
+
+Functions provided by the library
+---------------------------------
+
+The IJG JPEG library provides C code to read and write JPEG-compressed image
+files. The surrounding application program receives or supplies image data a
+scanline at a time, using a straightforward uncompressed image format. All
+details of color conversion and other preprocessing/postprocessing can be
+handled by the library.
+
+The library includes a substantial amount of code that is not covered by the
+JPEG standard but is necessary for typical applications of JPEG. These
+functions preprocess the image before JPEG compression or postprocess it after
+decompression. They include colorspace conversion, downsampling/upsampling,
+and color quantization. The application indirectly selects use of this code
+by specifying the format in which it wishes to supply or receive image data.
+For example, if colormapped output is requested, then the decompression
+library automatically invokes color quantization.
+
+A wide range of quality vs. speed tradeoffs are possible in JPEG processing,
+and even more so in decompression postprocessing. The decompression library
+provides multiple implementations that cover most of the useful tradeoffs,
+ranging from very-high-quality down to fast-preview operation. On the
+compression side we have generally not provided low-quality choices, since
+compression is normally less time-critical. It should be understood that the
+low-quality modes may not meet the JPEG standard's accuracy requirements;
+nonetheless, they are useful for viewers.
+
+A word about functions *not* provided by the library. We handle a subset of
+the ISO JPEG standard; most baseline, extended-sequential, and progressive
+JPEG processes are supported. (Our subset includes all features now in common
+use.) Unsupported ISO options include:
+ * Hierarchical storage
+ * Lossless JPEG
+ * Arithmetic entropy coding (unsupported for legal reasons)
+ * DNL marker
+ * Nonintegral subsampling ratios
+We support both 8- and 12-bit data precision, but this is a compile-time
+choice rather than a run-time choice; hence it is difficult to use both
+precisions in a single application.
+
+By itself, the library handles only interchange JPEG datastreams --- in
+particular the widely used JFIF file format. The library can be used by
+surrounding code to process interchange or abbreviated JPEG datastreams that
+are embedded in more complex file formats. (For example, this library is
+used by the free LIBTIFF library to support JPEG compression in TIFF.)
+
+
+Outline of typical usage
+------------------------
+
+The rough outline of a JPEG compression operation is:
+
+ Allocate and initialize a JPEG compression object
+ Specify the destination for the compressed data (eg, a file)
+ Set parameters for compression, including image size & colorspace
+ jpeg_start_compress(...);
+ while (scan lines remain to be written)
+ jpeg_write_scanlines(...);
+ jpeg_finish_compress(...);
+ Release the JPEG compression object
+
+A JPEG compression object holds parameters and working state for the JPEG
+library. We make creation/destruction of the object separate from starting
+or finishing compression of an image; the same object can be re-used for a
+series of image compression operations. This makes it easy to re-use the
+same parameter settings for a sequence of images. Re-use of a JPEG object
+also has important implications for processing abbreviated JPEG datastreams,
+as discussed later.
+
+The image data to be compressed is supplied to jpeg_write_scanlines() from
+in-memory buffers. If the application is doing file-to-file compression,
+reading image data from the source file is the application's responsibility.
+The library emits compressed data by calling a "data destination manager",
+which typically will write the data into a file; but the application can
+provide its own destination manager to do something else.
+
+Similarly, the rough outline of a JPEG decompression operation is:
+
+ Allocate and initialize a JPEG decompression object
+ Specify the source of the compressed data (eg, a file)
+ Call jpeg_read_header() to obtain image info
+ Set parameters for decompression
+ jpeg_start_decompress(...);
+ while (scan lines remain to be read)
+ jpeg_read_scanlines(...);
+ jpeg_finish_decompress(...);
+ Release the JPEG decompression object
+
+This is comparable to the compression outline except that reading the
+datastream header is a separate step. This is helpful because information
+about the image's size, colorspace, etc is available when the application
+selects decompression parameters. For example, the application can choose an
+output scaling ratio that will fit the image into the available screen size.
+
+The decompression library obtains compressed data by calling a data source
+manager, which typically will read the data from a file; but other behaviors
+can be obtained with a custom source manager. Decompressed data is delivered
+into in-memory buffers passed to jpeg_read_scanlines().
+
+It is possible to abort an incomplete compression or decompression operation
+by calling jpeg_abort(); or, if you do not need to retain the JPEG object,
+simply release it by calling jpeg_destroy().
+
+JPEG compression and decompression objects are two separate struct types.
+However, they share some common fields, and certain routines such as
+jpeg_destroy() can work on either type of object.
+
+The JPEG library has no static variables: all state is in the compression
+or decompression object. Therefore it is possible to process multiple
+compression and decompression operations concurrently, using multiple JPEG
+objects.
+
+Both compression and decompression can be done in an incremental memory-to-
+memory fashion, if suitable source/destination managers are used. See the
+section on "I/O suspension" for more details.
+
+
+BASIC LIBRARY USAGE
+===================
+
+Data formats
+------------
+
+Before diving into procedural details, it is helpful to understand the
+image data format that the JPEG library expects or returns.
+
+The standard input image format is a rectangular array of pixels, with each
+pixel having the same number of "component" or "sample" values (color
+channels). You must specify how many components there are and the colorspace
+interpretation of the components. Most applications will use RGB data
+(three components per pixel) or grayscale data (one component per pixel).
+PLEASE NOTE THAT RGB DATA IS THREE SAMPLES PER PIXEL, GRAYSCALE ONLY ONE.
+A remarkable number of people manage to miss this, only to tqfind that their
+programs don't work with grayscale JPEG files.
+
+There is no provision for colormapped input. JPEG files are always full-color
+or full grayscale (or sometimes another colorspace such as CMYK). You can
+feed in a colormapped image by expanding it to full-color format. However
+JPEG often doesn't work very well with source data that has been colormapped,
+because of dithering noise. This is discussed in more detail in the JPEG FAQ
+and the other references mentioned in the README file.
+
+Pixels are stored by scanlines, with each scanline running from left to
+right. The component values for each pixel are adjacent in the row; for
+example, R,G,B,R,G,B,R,G,B,... for 24-bit RGB color. Each scanline is an
+array of data type JSAMPLE --- which is typically "unsigned char", unless
+you've changed jmorecfg.h. (You can also change the RGB pixel tqlayout, say
+to B,G,R order, by modifying jmorecfg.h. But see the restrictions listed in
+that file before doing so.)
+
+A 2-D array of pixels is formed by making a list of pointers to the starts of
+scanlines; so the scanlines need not be physically adjacent in memory. Even
+if you process just one scanline at a time, you must make a one-element
+pointer array to conform to this structure. Pointers to JSAMPLE rows are of
+type JSAMPROW, and the pointer to the pointer array is of type JSAMPARRAY.
+
+The library accepts or supplies one or more complete scanlines per call.
+It is not possible to process part of a row at a time. Scanlines are always
+processed top-to-bottom. You can process an entire image in one call if you
+have it all in memory, but usually it's simplest to process one scanline at
+a time.
+
+For best results, source data values should have the precision specified by
+BITS_IN_JSAMPLE (normally 8 bits). For instance, if you choose to compress
+data that's only 6 bits/channel, you should left-justify each value in a
+byte before passing it to the compressor. If you need to compress data
+that has more than 8 bits/channel, compile with BITS_IN_JSAMPLE = 12.
+(See "Library compile-time options", later.)
+
+
+The data format returned by the decompressor is the same in all details,
+except that colormapped output is supported. (Again, a JPEG file is never
+colormapped. But you can ask the decompressor to perform on-the-fly color
+quantization to deliver colormapped output.) If you request colormapped
+output then the returned data array tqcontains a single JSAMPLE per pixel;
+its value is an index into a color map. The color map is represented as
+a 2-D JSAMPARRAY in which each row holds the values of one color component,
+that is, colormap[i][j] is the value of the i'th color component for pixel
+value (map index) j. Note that since the colormap indexes are stored in
+JSAMPLEs, the maximum number of colors is limited by the size of JSAMPLE
+(ie, at most 256 colors for an 8-bit JPEG library).
+
+
+Compression details
+-------------------
+
+Here we revisit the JPEG compression outline given in the overview.
+
+1. Allocate and initialize a JPEG compression object.
+
+A JPEG compression object is a "struct jpeg_compress_struct". (It also has
+a bunch of subsidiary structures which are allocated via malloc(), but the
+application doesn't control those directly.) This struct can be just a local
+variable in the calling routine, if a single routine is going to execute the
+whole JPEG compression sequence. Otherwise it can be static or allocated
+from malloc().
+
+You will also need a structure representing a JPEG error handler. The part
+of this that the library cares about is a "struct jpeg_error_mgr". If you
+are providing your own error handler, you'll typically want to embed the
+jpeg_error_mgr struct in a larger structure; this is discussed later under
+"Error handling". For now we'll assume you are just using the default error
+handler. The default error handler will print JPEG error/warning messages
+on stderr, and it will call exit() if a fatal error occurs.
+
+You must initialize the error handler structure, store a pointer to it into
+the JPEG object's "err" field, and then call jpeg_create_compress() to
+initialize the rest of the JPEG object.
+
+Typical code for this step, if you are using the default error handler, is
+
+ struct jpeg_compress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ ...
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_compress(&cinfo);
+
+jpeg_create_compress allocates a small amount of memory, so it could fail
+if you are out of memory. In that case it will exit via the error handler;
+that's why the error handler must be initialized first.
+
+
+2. Specify the destination for the compressed data (eg, a file).
+
+As previously mentioned, the JPEG library delivers compressed data to a
+"data destination" module. The library includes one data destination
+module which knows how to write to a stdio stream. You can use your own
+destination module if you want to do something else, as discussed later.
+
+If you use the standard destination module, you must open the target stdio
+stream beforehand. Typical code for this step looks like:
+
+ FILE * outfile;
+ ...
+ if ((outfile = fopen(filename, "wb")) == NULL) {
+ fprintf(stderr, "can't open %s\n", filename);
+ exit(1);
+ }
+ jpeg_stdio_dest(&cinfo, outfile);
+
+where the last line invokes the standard destination module.
+
+WARNING: it is critical that the binary compressed data be delivered to the
+output file unchanged. On non-Unix systems the stdio library may perform
+newline translation or otherwise corrupt binary data. To suppress this
+behavior, you may need to use a "b" option to fopen (as shown above), or use
+setmode() or another routine to put the stdio stream in binary mode. See
+cjpeg.c and djpeg.c for code that has been found to work on many systems.
+
+You can select the data destination after setting other parameters (step 3),
+if that's more convenient. You may not change the destination between
+calling jpeg_start_compress() and jpeg_finish_compress().
+
+
+3. Set parameters for compression, including image size & colorspace.
+
+You must supply information about the source image by setting the following
+fields in the JPEG object (cinfo structure):
+
+ image_width Width of image, in pixels
+ image_height Height of image, in pixels
+ input_components Number of color channels (samples per pixel)
+ in_color_space Color space of source image
+
+The image dimensions are, hopefully, obvious. JPEG supports image dimensions
+of 1 to 64K pixels in either direction. The input color space is typically
+RGB or grayscale, and input_components is 3 or 1 accordingly. (See "Special
+color spaces", later, for more info.) The in_color_space field must be
+assigned one of the J_COLOR_SPACE enum constants, typically JCS_RGB or
+JCS_GRAYSCALE.
+
+JPEG has a large number of compression parameters that determine how the
+image is encoded. Most applications don't need or want to know about all
+these parameters. You can set all the parameters to reasonable defaults by
+calling jpeg_set_defaults(); then, if there are particular values you want
+to change, you can do so after that. The "Compression parameter selection"
+section tells about all the parameters.
+
+You must set in_color_space correctly before calling jpeg_set_defaults(),
+because the defaults depend on the source image colorspace. However the
+other three source image parameters need not be valid until you call
+jpeg_start_compress(). There's no harm in calling jpeg_set_defaults() more
+than once, if that happens to be convenient.
+
+Typical code for a 24-bit RGB source image is
+
+ cinfo.image_width = Width; /* image width and height, in pixels */
+ cinfo.image_height = Height;
+ cinfo.input_components = 3; /* # of color components per pixel */
+ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
+
+ jpeg_set_defaults(&cinfo);
+ /* Make optional parameter settings here */
+
+
+4. jpeg_start_compress(...);
+
+After you have established the data destination and set all the necessary
+source image info and other parameters, call jpeg_start_compress() to begin
+a compression cycle. This will initialize internal state, allocate working
+storage, and emit the first few bytes of the JPEG datastream header.
+
+Typical code:
+
+ jpeg_start_compress(&cinfo, TRUE);
+
+The "TRUE" parameter ensures that a complete JPEG interchange datastream
+will be written. This is appropriate in most cases. If you think you might
+want to use an abbreviated datastream, read the section on abbreviated
+datastreams, below.
+
+Once you have called jpeg_start_compress(), you may not alter any JPEG
+parameters or other fields of the JPEG object until you have completed
+the compression cycle.
+
+
+5. while (scan lines remain to be written)
+ jpeg_write_scanlines(...);
+
+Now write all the required image data by calling jpeg_write_scanlines()
+one or more times. You can pass one or more scanlines in each call, up
+to the total image height. In most applications it is convenient to pass
+just one or a few scanlines at a time. The expected format for the passed
+data is discussed under "Data formats", above.
+
+Image data should be written in top-to-bottom scanline order. The JPEG spec
+tqcontains some weasel wording about how top and bottom are application-defined
+terms (a curious interpretation of the English language...) but if you want
+your files to be compatible with everyone else's, you WILL use top-to-bottom
+order. If the source data must be read in bottom-to-top order, you can use
+the JPEG library's virtual array mechanism to invert the data efficiently.
+Examples of this can be found in the sample application cjpeg.
+
+The library maintains a count of the number of scanlines written so far
+in the next_scanline field of the JPEG object. Usually you can just use
+this variable as the loop counter, so that the loop test looks like
+"while (cinfo.next_scanline < cinfo.image_height)".
+
+Code for this step depends heavily on the way that you store the source data.
+example.c shows the following code for the case of a full-size 2-D source
+array containing 3-byte RGB pixels:
+
+ JSAMPROW row_pointer[1]; /* pointer to a single row */
+ int row_stride; /* physical row width in buffer */
+
+ row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */
+
+ while (cinfo.next_scanline < cinfo.image_height) {
+ row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
+ jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+
+jpeg_write_scanlines() returns the number of scanlines actually written.
+This will normally be equal to the number passed in, so you can usually
+ignore the return value. It is different in just two cases:
+ * If you try to write more scanlines than the declared image height,
+ the additional scanlines are ignored.
+ * If you use a suspending data destination manager, output buffer overrun
+ will cause the compressor to return before accepting all the passed lines.
+ This feature is discussed under "I/O suspension", below. The normal
+ stdio destination manager will NOT cause this to happen.
+In any case, the return value is the same as the change in the value of
+next_scanline.
+
+
+6. jpeg_finish_compress(...);
+
+After all the image data has been written, call jpeg_finish_compress() to
+complete the compression cycle. This step is ESSENTIAL to ensure that the
+last bufferload of data is written to the data destination.
+jpeg_finish_compress() also releases working memory associated with the JPEG
+object.
+
+Typical code:
+
+ jpeg_finish_compress(&cinfo);
+
+If using the stdio destination manager, don't forget to close the output
+stdio stream (if necessary) afterwards.
+
+If you have requested a multi-pass operating mode, such as Huffman code
+optimization, jpeg_finish_compress() will perform the additional passes using
+data buffered by the first pass. In this case jpeg_finish_compress() may take
+quite a while to complete. With the default compression parameters, this will
+not happen.
+
+It is an error to call jpeg_finish_compress() before writing the necessary
+total number of scanlines. If you wish to abort compression, call
+jpeg_abort() as discussed below.
+
+After completing a compression cycle, you may dispose of the JPEG object
+as discussed next, or you may use it to compress another image. In that case
+return to step 2, 3, or 4 as appropriate. If you do not change the
+destination manager, the new datastream will be written to the same target.
+If you do not change any JPEG parameters, the new datastream will be written
+with the same parameters as before. Note that you can change the input image
+dimensions freely between cycles, but if you change the input colorspace, you
+should call jpeg_set_defaults() to adjust for the new colorspace; and then
+you'll need to repeat all of step 3.
+
+
+7. Release the JPEG compression object.
+
+When you are done with a JPEG compression object, destroy it by calling
+jpeg_destroy_compress(). This will free all subsidiary memory (regardless of
+the previous state of the object). Or you can call jpeg_destroy(), which
+works for either compression or decompression objects --- this may be more
+convenient if you are sharing code between compression and decompression
+cases. (Actually, these routines are equivalent except for the declared type
+of the passed pointer. To avoid gripes from ANSI C compilers, jpeg_destroy()
+should be passed a j_common_ptr.)
+
+If you allocated the jpeg_compress_struct structure from malloc(), freeing
+it is your responsibility --- jpeg_destroy() won't. Ditto for the error
+handler structure.
+
+Typical code:
+
+ jpeg_destroy_compress(&cinfo);
+
+
+8. Aborting.
+
+If you decide to abort a compression cycle before finishing, you can clean up
+in either of two ways:
+
+* If you don't need the JPEG object any more, just call
+ jpeg_destroy_compress() or jpeg_destroy() to release memory. This is
+ legitimate at any point after calling jpeg_create_compress() --- in fact,
+ it's safe even if jpeg_create_compress() fails.
+
+* If you want to re-use the JPEG object, call jpeg_abort_compress(), or call
+ jpeg_abort() which works on both compression and decompression objects.
+ This will return the object to an idle state, releasing any working memory.
+ jpeg_abort() is allowed at any time after successful object creation.
+
+Note that cleaning up the data destination, if required, is your
+responsibility; neither of these routines will call term_destination().
+(See "Compressed data handling", below, for more about that.)
+
+jpeg_destroy() and jpeg_abort() are the only safe calls to make on a JPEG
+object that has reported an error by calling error_exit (see "Error handling"
+for more info). The internal state of such an object is likely to be out of
+whack. Either of these two routines will return the object to a known state.
+
+
+Decompression details
+---------------------
+
+Here we revisit the JPEG decompression outline given in the overview.
+
+1. Allocate and initialize a JPEG decompression object.
+
+This is just like initialization for compression, as discussed above,
+except that the object is a "struct jpeg_decompress_struct" and you
+call jpeg_create_decompress(). Error handling is exactly the same.
+
+Typical code:
+
+ struct jpeg_decompress_struct cinfo;
+ struct jpeg_error_mgr jerr;
+ ...
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&cinfo);
+
+(Both here and in the IJG code, we usually use variable name "cinfo" for
+both compression and decompression objects.)
+
+
+2. Specify the source of the compressed data (eg, a file).
+
+As previously mentioned, the JPEG library reads compressed data from a "data
+source" module. The library includes one data source module which knows how
+to read from a stdio stream. You can use your own source module if you want
+to do something else, as discussed later.
+
+If you use the standard source module, you must open the source stdio stream
+beforehand. Typical code for this step looks like:
+
+ FILE * infile;
+ ...
+ if ((infile = fopen(filename, "rb")) == NULL) {
+ fprintf(stderr, "can't open %s\n", filename);
+ exit(1);
+ }
+ jpeg_stdio_src(&cinfo, infile);
+
+where the last line invokes the standard source module.
+
+WARNING: it is critical that the binary compressed data be read unchanged.
+On non-Unix systems the stdio library may perform newline translation or
+otherwise corrupt binary data. To suppress this behavior, you may need to use
+a "b" option to fopen (as shown above), or use setmode() or another routine to
+put the stdio stream in binary mode. See cjpeg.c and djpeg.c for code that
+has been found to work on many systems.
+
+You may not change the data source between calling jpeg_read_header() and
+jpeg_finish_decompress(). If you wish to read a series of JPEG images from
+a single source file, you should repeat the jpeg_read_header() to
+jpeg_finish_decompress() sequence without reinitializing either the JPEG
+object or the data source module; this prevents buffered input data from
+being discarded.
+
+
+3. Call jpeg_read_header() to obtain image info.
+
+Typical code for this step is just
+
+ jpeg_read_header(&cinfo, TRUE);
+
+This will read the source datastream header markers, up to the beginning
+of the compressed data proper. On return, the image dimensions and other
+info have been stored in the JPEG object. The application may wish to
+consult this information before selecting decompression parameters.
+
+More complex code is necessary if
+ * A suspending data source is used --- in that case jpeg_read_header()
+ may return before it has read all the header data. See "I/O suspension",
+ below. The normal stdio source manager will NOT cause this to happen.
+ * Abbreviated JPEG files are to be processed --- see the section on
+ abbreviated datastreams. Standard applications that deal only in
+ interchange JPEG files need not be concerned with this case either.
+
+It is permissible to stop at this point if you just wanted to tqfind out the
+image dimensions and other header info for a JPEG file. In that case,
+call jpeg_destroy() when you are done with the JPEG object, or call
+jpeg_abort() to return it to an idle state before selecting a new data
+source and reading another header.
+
+
+4. Set parameters for decompression.
+
+jpeg_read_header() sets appropriate default decompression parameters based on
+the properties of the image (in particular, its colorspace). However, you
+may well want to alter these defaults before beginning the decompression.
+For example, the default is to produce full color output from a color file.
+If you want colormapped output you must ask for it. Other options allow the
+returned image to be scaled and allow various speed/quality tradeoffs to be
+selected. "Decompression parameter selection", below, gives details.
+
+If the defaults are appropriate, nothing need be done at this step.
+
+Note that all default values are set by each call to jpeg_read_header().
+If you reuse a decompression object, you cannot expect your parameter
+settings to be preserved across cycles, as you can for compression.
+You must set desired parameter values each time.
+
+
+5. jpeg_start_decompress(...);
+
+Once the parameter values are satisfactory, call jpeg_start_decompress() to
+begin decompression. This will initialize internal state, allocate working
+memory, and prepare for returning data.
+
+Typical code is just
+
+ jpeg_start_decompress(&cinfo);
+
+If you have requested a multi-pass operating mode, such as 2-pass color
+quantization, jpeg_start_decompress() will do everything needed before data
+output can begin. In this case jpeg_start_decompress() may take quite a while
+to complete. With a single-scan (non progressive) JPEG file and default
+decompression parameters, this will not happen; jpeg_start_decompress() will
+return quickly.
+
+After this call, the final output image dimensions, including any requested
+scaling, are available in the JPEG object; so is the selected colormap, if
+colormapped output has been requested. Useful fields include
+
+ output_width image width and height, as scaled
+ output_height
+ out_color_components # of color components in out_color_space
+ output_components # of color components returned per pixel
+ colormap the selected colormap, if any
+ actual_number_of_colors number of entries in colormap
+
+output_components is 1 (a colormap index) when quantizing colors; otherwise it
+equals out_color_components. It is the number of JSAMPLE values that will be
+emitted per pixel in the output arrays.
+
+Typically you will need to allocate data buffers to hold the incoming image.
+You will need output_width * output_components JSAMPLEs per scanline in your
+output buffer, and a total of output_height scanlines will be returned.
+
+Note: if you are using the JPEG library's internal memory manager to allocate
+data buffers (as djpeg does), then the manager's protocol requires that you
+request large buffers *before* calling jpeg_start_decompress(). This is a
+little tricky since the output_XXX fields are not normally valid then. You
+can make them valid by calling jpeg_calc_output_dimensions() after setting the
+relevant parameters (scaling, output color space, and quantization flag).
+
+
+6. while (scan lines remain to be read)
+ jpeg_read_scanlines(...);
+
+Now you can read the decompressed image data by calling jpeg_read_scanlines()
+one or more times. At each call, you pass in the maximum number of scanlines
+to be read (ie, the height of your working buffer); jpeg_read_scanlines()
+will return up to that many lines. The return value is the number of lines
+actually read. The format of the returned data is discussed under "Data
+formats", above. Don't forget that grayscale and color JPEGs will return
+different data formats!
+
+Image data is returned in top-to-bottom scanline order. If you must write
+out the image in bottom-to-top order, you can use the JPEG library's virtual
+array mechanism to invert the data efficiently. Examples of this can be
+found in the sample application djpeg.
+
+The library maintains a count of the number of scanlines returned so far
+in the output_scanline field of the JPEG object. Usually you can just use
+this variable as the loop counter, so that the loop test looks like
+"while (cinfo.output_scanline < cinfo.output_height)". (Note that the test
+should NOT be against image_height, unless you never use scaling. The
+image_height field is the height of the original unscaled image.)
+The return value always equals the change in the value of output_scanline.
+
+If you don't use a suspending data source, it is safe to assume that
+jpeg_read_scanlines() reads at least one scanline per call, until the
+bottom of the image has been reached.
+
+If you use a buffer larger than one scanline, it is NOT safe to assume that
+jpeg_read_scanlines() fills it. (The current implementation returns only a
+few scanlines per call, no matter how large a buffer you pass.) So you must
+always provide a loop that calls jpeg_read_scanlines() repeatedly until the
+whole image has been read.
+
+
+7. jpeg_finish_decompress(...);
+
+After all the image data has been read, call jpeg_finish_decompress() to
+complete the decompression cycle. This causes working memory associated
+with the JPEG object to be released.
+
+Typical code:
+
+ jpeg_finish_decompress(&cinfo);
+
+If using the stdio source manager, don't forget to close the source stdio
+stream if necessary.
+
+It is an error to call jpeg_finish_decompress() before reading the correct
+total number of scanlines. If you wish to abort decompression, call
+jpeg_abort() as discussed below.
+
+After completing a decompression cycle, you may dispose of the JPEG object as
+discussed next, or you may use it to decompress another image. In that case
+return to step 2 or 3 as appropriate. If you do not change the source
+manager, the next image will be read from the same source.
+
+
+8. Release the JPEG decompression object.
+
+When you are done with a JPEG decompression object, destroy it by calling
+jpeg_destroy_decompress() or jpeg_destroy(). The previous discussion of
+destroying compression objects applies here too.
+
+Typical code:
+
+ jpeg_destroy_decompress(&cinfo);
+
+
+9. Aborting.
+
+You can abort a decompression cycle by calling jpeg_destroy_decompress() or
+jpeg_destroy() if you don't need the JPEG object any more, or
+jpeg_abort_decompress() or jpeg_abort() if you want to reuse the object.
+The previous discussion of aborting compression cycles applies here too.
+
+
+Mechanics of usage: include files, linking, etc
+-----------------------------------------------
+
+Applications using the JPEG library should include the header file jpeglib.h
+to obtain declarations of data types and routines. Before including
+jpeglib.h, include system headers that define at least the typedefs FILE and
+size_t. On ANSI-conforming systems, including <stdio.h> is sufficient; on
+older Unix systems, you may need <sys/types.h> to define size_t.
+
+If the application needs to refer to individual JPEG library error codes, also
+include jerror.h to define those symbols.
+
+jpeglib.h indirectly includes the files jconfig.h and jmorecfg.h. If you are
+installing the JPEG header files in a system directory, you will want to
+install all four files: jpeglib.h, jerror.h, jconfig.h, jmorecfg.h.
+
+The most convenient way to include the JPEG code into your executable program
+is to prepare a library file ("libjpeg.a", or a corresponding name on non-Unix
+machines) and reference it at your link step. If you use only half of the
+library (only compression or only decompression), only that much code will be
+included from the library, unless your linker is hopelessly brain-damaged.
+The supplied makefiles build libjpeg.a automatically (see install.doc).
+
+While you can build the JPEG library as a shared library if the whim strikes
+you, we don't really recommend it. The trouble with shared libraries is that
+at some point you'll probably try to substitute a new version of the library
+without recompiling the calling applications. That generally doesn't work
+because the parameter struct declarations usually change with each new
+version. In other words, the library's API is *not* guaranteed binary
+compatible across versions; we only try to ensure source-code compatibility.
+(In hindsight, it might have been smarter to hide the parameter structs from
+applications and introduce a ton of access functions instead. Too late now,
+however.)
+
+On some systems your application may need to set up a signal handler to ensure
+that temporary files are deleted if the program is interrupted. This is most
+critical if you are on MS-DOS and use the jmemdos.c memory manager back end;
+it will try to grab extended memory for temp files, and that space will NOT be
+freed automatically. See cjpeg.c or djpeg.c for an example signal handler.
+
+It may be worth pointing out that the core JPEG library does not actually
+require the stdio library: only the default source/destination managers and
+error handler need it. You can use the library in a stdio-less environment
+if you tqreplace those modules and use jmemnobs.c (or another memory manager of
+your own devising). More info about the minimum system library requirements
+may be found in jinclude.h.
+
+
+ADVANCED FEATURES
+=================
+
+Compression parameter selection
+-------------------------------
+
+This section describes all the optional parameters you can set for JPEG
+compression, as well as the "helper" routines provided to assist in this
+task. Proper setting of some parameters requires detailed understanding
+of the JPEG standard; if you don't know what a parameter is for, it's best
+not to mess with it! See REFERENCES in the README file for pointers to
+more info about JPEG.
+
+It's a good idea to call jpeg_set_defaults() first, even if you plan to set
+all the parameters; that way your code is more likely to work with future JPEG
+libraries that have additional parameters. For the same reason, we recommend
+you use a helper routine where one is provided, in preference to twiddling
+cinfo fields directly.
+
+The helper routines are:
+
+jpeg_set_defaults (j_compress_ptr cinfo)
+ This routine sets all JPEG parameters to reasonable defaults, using
+ only the input image's color space (field in_color_space, which must
+ already be set in cinfo). Many applications will only need to use
+ this routine and perhaps jpeg_set_quality().
+
+jpeg_set_colorspace (j_compress_ptr cinfo, J_COLOR_SPACE colorspace)
+ Sets the JPEG file's colorspace (field jpeg_color_space) as specified,
+ and sets other color-space-dependent parameters appropriately. See
+ "Special color spaces", below, before using this. A large number of
+ parameters, including all per-component parameters, are set by this
+ routine; if you want to twiddle individual parameters you should call
+ jpeg_set_colorspace() before rather than after.
+
+jpeg_default_colorspace (j_compress_ptr cinfo)
+ Selects an appropriate JPEG colorspace based on cinfo->in_color_space,
+ and calls jpeg_set_colorspace(). This is actually a subroutine of
+ jpeg_set_defaults(). It's broken out in case you want to change
+ just the colorspace-dependent JPEG parameters.
+
+jpeg_set_quality (j_compress_ptr cinfo, int quality, boolean force_baseline)
+ Constructs JPEG quantization tables appropriate for the indicated
+ quality setting. The quality value is expressed on the 0..100 scale
+ recommended by IJG (cjpeg's "-quality" switch uses this routine).
+ Note that the exact mapping from quality values to tables may change
+ in future IJG releases as more is learned about DCT quantization.
+ If the force_baseline parameter is TRUE, then the quantization table
+ entries are constrained to the range 1..255 for full JPEG baseline
+ compatibility. In the current implementation, this only makes a
+ difference for quality settings below 25, and it effectively prevents
+ very small/low quality files from being generated. The IJG decoder
+ is capable of reading the non-baseline files generated at low quality
+ settings when force_baseline is FALSE, but other decoders may not be.
+
+jpeg_set_linear_quality (j_compress_ptr cinfo, int scale_factor,
+ boolean force_baseline)
+ Same as jpeg_set_quality() except that the generated tables are the
+ sample tables given in the JPEC spec section K.1, multiplied by the
+ specified scale factor (which is expressed as a percentage; thus
+ scale_factor = 100 reproduces the spec's tables). Note that larger
+ scale factors give lower quality. This entry point is useful for
+ conforming to the Adobe PostScript DCT conventions, but we do not
+ recommend linear scaling as a user-visible quality scale otherwise.
+ force_baseline again constrains the computed table entries to 1..255.
+
+int jpeg_quality_scaling (int quality)
+ Converts a value on the IJG-recommended quality scale to a linear
+ scaling percentage. Note that this routine may change or go away
+ in future releases --- IJG may choose to adopt a scaling method that
+ can't be expressed as a simple scalar multiplier, in which case the
+ premise of this routine collapses. Caveat user.
+
+jpeg_add_quant_table (j_compress_ptr cinfo, int which_tbl,
+ const unsigned int *basic_table,
+ int scale_factor, boolean force_baseline)
+ Allows an arbitrary quantization table to be created. which_tbl
+ indicates which table slot to fill. basic_table points to an array
+ of 64 unsigned ints given in normal array order. These values are
+ multiplied by scale_factor/100 and then clamped to the range 1..65535
+ (or to 1..255 if force_baseline is TRUE).
+ CAUTION: prior to library version 6a, jpeg_add_quant_table expected
+ the basic table to be given in JPEG zigzag order. If you need to
+ write code that works with either older or newer versions of this
+ routine, you must check the library version number. Something like
+ "#if JPEG_LIB_VERSION >= 61" is the right test.
+
+jpeg_simple_progression (j_compress_ptr cinfo)
+ Generates a default scan script for writing a progressive-JPEG file.
+ This is the recommended method of creating a progressive file,
+ unless you want to make a custom scan sequence. You must ensure that
+ the JPEG color space is set correctly before calling this routine.
+
+
+Compression parameters (cinfo fields) include:
+
+J_DCT_METHOD dct_method
+ Selects the algorithm used for the DCT step. Choices are:
+ JDCT_ISLOW: slow but accurate integer algorithm
+ JDCT_IFAST: faster, less accurate integer method
+ JDCT_FLOAT: floating-point method
+ JDCT_DEFAULT: default method (normally JDCT_ISLOW)
+ JDCT_FASTEST: fastest method (normally JDCT_IFAST)
+ The FLOAT method is very slightly more accurate than the ISLOW method,
+ but may give different results on different machines due to varying
+ roundoff behavior. The integer methods should give the same results
+ on all machines. On machines with sufficiently fast FP hardware, the
+ floating-point method may also be the fastest. The IFAST method is
+ considerably less accurate than the other two; its use is not
+ recommended if high quality is a concern. JDCT_DEFAULT and
+ JDCT_FASTEST are macros configurable by each installation.
+
+J_COLOR_SPACE jpeg_color_space
+int num_components
+ The JPEG color space and corresponding number of components; see
+ "Special color spaces", below, for more info. We recommend using
+ jpeg_set_color_space() if you want to change these.
+
+boolean optimize_coding
+ TRUE causes the compressor to compute optimal Huffman coding tables
+ for the image. This requires an extra pass over the data and
+ therefore costs a good deal of space and time. The default is
+ FALSE, which tells the compressor to use the supplied or default
+ Huffman tables. In most cases optimal tables save only a few percent
+ of file size compared to the default tables. Note that when this is
+ TRUE, you need not supply Huffman tables at all, and any you do
+ supply will be overwritten.
+
+unsigned int restart_interval
+int restart_in_rows
+ To emit restart markers in the JPEG file, set one of these nonzero.
+ Set restart_interval to specify the exact interval in MCU blocks.
+ Set restart_in_rows to specify the interval in MCU rows. (If
+ restart_in_rows is not 0, then restart_interval is set after the
+ image width in MCUs is computed.) Defaults are zero (no restarts).
+ One restart marker per MCU row is often a good choice.
+ NOTE: the overhead of restart markers is higher in grayscale JPEG
+ files than in color files, and MUCH higher in progressive JPEGs.
+ If you use restarts, you may want to use larger intervals in those
+ cases.
+
+const jpeg_scan_info * scan_info
+int num_scans
+ By default, scan_info is NULL; this causes the compressor to write a
+ single-scan sequential JPEG file. If not NULL, scan_info points to
+ an array of scan definition records of length num_scans. The
+ compressor will then write a JPEG file having one scan for each scan
+ definition record. This is used to generate noninterleaved or
+ progressive JPEG files. The library checks that the scan array
+ defines a valid JPEG scan sequence. (jpeg_simple_progression creates
+ a suitable scan definition array for progressive JPEG.) This is
+ discussed further under "Progressive JPEG support".
+
+int smoothing_factor
+ If non-zero, the input image is smoothed; the value should be 1 for
+ minimal smoothing to 100 for maximum smoothing. Consult jcsample.c
+ for details of the smoothing algorithm. The default is zero.
+
+boolean write_JFIF_header
+ If TRUE, a JFIF APP0 marker is emitted. jpeg_set_defaults() and
+ jpeg_set_colorspace() set this TRUE if a JFIF-legal JPEG color space
+ (ie, YCbCr or grayscale) is selected, otherwise FALSE.
+
+UINT8 JFIF_major_version
+UINT8 JFIF_minor_version
+ The version number to be written into the JFIF marker.
+ jpeg_set_defaults() initializes the version to 1.01 (major=minor=1).
+ You should set it to 1.02 (major=1, minor=2) if you plan to write
+ any JFIF 1.02 extension markers.
+
+UINT8 density_unit
+UINT16 X_density
+UINT16 Y_density
+ The resolution information to be written into the JFIF marker;
+ not used otherwise. density_unit may be 0 for unknown,
+ 1 for dots/inch, or 2 for dots/cm. The default values are 0,1,1
+ indicating square pixels of unknown size.
+
+boolean write_Adobe_marker
+ If TRUE, an Adobe APP14 marker is emitted. jpeg_set_defaults() and
+ jpeg_set_colorspace() set this TRUE if JPEG color space RGB, CMYK,
+ or YCCK is selected, otherwise FALSE. It is generally a bad idea
+ to set both write_JFIF_header and write_Adobe_marker. In fact,
+ you probably shouldn't change the default settings at all --- the
+ default behavior ensures that the JPEG file's color space can be
+ recognized by the decoder.
+
+JQUANT_TBL * quant_tbl_ptrs[NUM_QUANT_TBLS]
+ Pointers to coefficient quantization tables, one per table slot,
+ or NULL if no table is defined for a slot. Usually these should
+ be set via one of the above helper routines; jpeg_add_quant_table()
+ is general enough to define any quantization table. The other
+ routines will set up table slot 0 for luminance quality and table
+ slot 1 for chrominance.
+
+JHUFF_TBL * dc_huff_tbl_ptrs[NUM_HUFF_TBLS]
+JHUFF_TBL * ac_huff_tbl_ptrs[NUM_HUFF_TBLS]
+ Pointers to Huffman coding tables, one per table slot, or NULL if
+ no table is defined for a slot. Slots 0 and 1 are filled with the
+ JPEG sample tables by jpeg_set_defaults(). If you need to allocate
+ more table structures, jpeg_alloc_huff_table() may be used.
+ Note that optimal Huffman tables can be computed for an image
+ by setting optimize_coding, as discussed above; there's seldom
+ any need to mess with providing your own Huffman tables.
+
+There are some additional cinfo fields which are not documented here
+because you currently can't change them; for example, you can't set
+arith_code TRUE because arithmetic coding is unsupported.
+
+
+Per-component parameters are stored in the struct cinfo.comp_info[i] for
+component number i. Note that components here refer to components of the
+JPEG color space, *not* the source image color space. A suitably large
+comp_info[] array is allocated by jpeg_set_defaults(); if you choose not
+to use that routine, it's up to you to allocate the array.
+
+int component_id
+ The one-byte identifier code to be recorded in the JPEG file for
+ this component. For the standard color spaces, we recommend you
+ leave the default values alone.
+
+int h_samp_factor
+int v_samp_factor
+ Horizontal and vertical sampling factors for the component; must
+ be 1..4 according to the JPEG standard. Note that larger sampling
+ factors indicate a higher-resolution component; many people tqfind
+ this behavior quite unintuitive. The default values are 2,2 for
+ luminance components and 1,1 for chrominance components, except
+ for grayscale where 1,1 is used.
+
+int quant_tbl_no
+ Quantization table number for component. The default value is
+ 0 for luminance components and 1 for chrominance components.
+
+int dc_tbl_no
+int ac_tbl_no
+ DC and AC entropy coding table numbers. The default values are
+ 0 for luminance components and 1 for chrominance components.
+
+int component_index
+ Must equal the component's index in comp_info[]. (Beginning in
+ release v6, the compressor library will fill this in automatically;
+ you don't have to.)
+
+
+Decompression parameter selection
+---------------------------------
+
+Decompression parameter selection is somewhat simpler than compression
+parameter selection, since all of the JPEG internal parameters are
+recorded in the source file and need not be supplied by the application.
+(Unless you are working with abbreviated files, in which case see
+"Abbreviated datastreams", below.) Decompression parameters control
+the postprocessing done on the image to deliver it in a format suitable
+for the application's use. Many of the parameters control speed/quality
+tradeoffs, in which faster decompression may be obtained at the price of
+a poorer-quality image. The defaults select the highest quality (slowest)
+processing.
+
+The following fields in the JPEG object are set by jpeg_read_header() and
+may be useful to the application in choosing decompression parameters:
+
+JDIMENSION image_width Width and height of image
+JDIMENSION image_height
+int num_components Number of color components
+J_COLOR_SPACE jpeg_color_space Colorspace of image
+boolean saw_JFIF_marker TRUE if a JFIF APP0 marker was seen
+ UINT8 JFIF_major_version Version information from JFIF marker
+ UINT8 JFIF_minor_version
+ UINT8 density_unit Resolution data from JFIF marker
+ UINT16 X_density
+ UINT16 Y_density
+boolean saw_Adobe_marker TRUE if an Adobe APP14 marker was seen
+ UINT8 Adobe_transform Color transform code from Adobe marker
+
+The JPEG color space, unfortunately, is something of a guess since the JPEG
+standard proper does not provide a way to record it. In practice most files
+adhere to the JFIF or Adobe conventions, and the decoder will recognize these
+correctly. See "Special color spaces", below, for more info.
+
+
+The decompression parameters that determine the basic properties of the
+returned image are:
+
+J_COLOR_SPACE out_color_space
+ Output color space. jpeg_read_header() sets an appropriate default
+ based on jpeg_color_space; typically it will be RGB or grayscale.
+ The application can change this field to request output in a different
+ colorspace. For example, set it to JCS_GRAYSCALE to get grayscale
+ output from a color file. (This is useful for previewing: grayscale
+ output is faster than full color since the color components need not
+ be processed.) Note that not all possible color space transforms are
+ currently implemented; you may need to extend jdcolor.c if you want an
+ unusual conversion.
+
+unsigned int scale_num, scale_denom
+ Scale the image by the fraction scale_num/scale_denom. Default is
+ 1/1, or no scaling. Currently, the only supported scaling ratios
+ are 1/1, 1/2, 1/4, and 1/8. (The library design allows for arbitrary
+ scaling ratios but this is not likely to be implemented any time soon.)
+ Smaller scaling ratios permit significantly faster decoding since
+ fewer pixels need be processed and a simpler IDCT method can be used.
+
+boolean quantize_colors
+ If set TRUE, colormapped output will be delivered. Default is FALSE,
+ meaning that full-color output will be delivered.
+
+The next three parameters are relevant only if quantize_colors is TRUE.
+
+int desired_number_of_colors
+ Maximum number of colors to use in generating a library-supplied color
+ map (the actual number of colors is returned in a different field).
+ Default 256. Ignored when the application supplies its own color map.
+
+boolean two_pass_quantize
+ If TRUE, an extra pass over the image is made to select a custom color
+ map for the image. This usually looks a lot better than the one-size-
+ fits-all colormap that is used otherwise. Default is TRUE. Ignored
+ when the application supplies its own color map.
+
+J_DITHER_MODE dither_mode
+ Selects color dithering method. Supported values are:
+ JDITHER_NONE no dithering: fast, very low quality
+ JDITHER_ORDERED ordered dither: moderate speed and quality
+ JDITHER_FS Floyd-Steinberg dither: slow, high quality
+ Default is JDITHER_FS. (At present, ordered dither is implemented
+ only in the single-pass, standard-colormap case. If you ask for
+ ordered dither when two_pass_quantize is TRUE or when you supply
+ an external color map, you'll get F-S dithering.)
+
+When quantize_colors is TRUE, the target color map is described by the next
+two fields. colormap is set to NULL by jpeg_read_header(). The application
+can supply a color map by setting colormap non-NULL and setting
+actual_number_of_colors to the map size. Otherwise, jpeg_start_decompress()
+selects a suitable color map and sets these two fields itself.
+[Implementation restriction: at present, an externally supplied colormap is
+only accepted for 3-component output color spaces.]
+
+JSAMPARRAY colormap
+ The color map, represented as a 2-D pixel array of out_color_components
+ rows and actual_number_of_colors columns. Ignored if not quantizing.
+ CAUTION: if the JPEG library creates its own colormap, the storage
+ pointed to by this field is released by jpeg_finish_decompress().
+ Copy the colormap somewhere else first, if you want to save it.
+
+int actual_number_of_colors
+ The number of colors in the color map.
+
+Additional decompression parameters that the application may set include:
+
+J_DCT_METHOD dct_method
+ Selects the algorithm used for the DCT step. Choices are the same
+ as described above for compression.
+
+boolean do_fancy_upsampling
+ If TRUE, do careful upsampling of chroma components. If FALSE,
+ a faster but sloppier method is used. Default is TRUE. The visual
+ impact of the sloppier method is often very small.
+
+boolean do_block_smoothing
+ If TRUE, interblock smoothing is applied in early stages of decoding
+ progressive JPEG files; if FALSE, not. Default is TRUE. Early
+ progression stages look "fuzzy" with smoothing, "blocky" without.
+ In any case, block smoothing ceases to be applied after the first few
+ AC coefficients are known to full accuracy, so it is relevant only
+ when using buffered-image mode for progressive images.
+
+boolean enable_1pass_quant
+boolean enable_external_quant
+boolean enable_2pass_quant
+ These are significant only in buffered-image mode, which is
+ described in its own section below.
+
+
+The output image dimensions are given by the following fields. These are
+computed from the source image dimensions and the decompression parameters
+by jpeg_start_decompress(). You can also call jpeg_calc_output_dimensions()
+to obtain the values that will result from the current parameter settings.
+This can be useful if you are trying to pick a scaling ratio that will get
+close to a desired target size. It's also important if you are using the
+JPEG library's memory manager to allocate output buffer space, because you
+are supposed to request such buffers *before* jpeg_start_decompress().
+
+JDIMENSION output_width Actual dimensions of output image.
+JDIMENSION output_height
+int out_color_components Number of color components in out_color_space.
+int output_components Number of color components returned.
+int rec_outbuf_height Recommended height of scanline buffer.
+
+When quantizing colors, output_components is 1, indicating a single color map
+index per pixel. Otherwise it equals out_color_components. The output arrays
+are required to be output_width * output_components JSAMPLEs wide.
+
+rec_outbuf_height is the recommended minimum height (in scanlines) of the
+buffer passed to jpeg_read_scanlines(). If the buffer is smaller, the
+library will still work, but time will be wasted due to unnecessary data
+copying. In high-quality modes, rec_outbuf_height is always 1, but some
+faster, lower-quality modes set it to larger values (typically 2 to 4).
+If you are going to ask for a high-speed processing mode, you may as well
+go to the trouble of honoring rec_outbuf_height so as to avoid data copying.
+(An output buffer larger than rec_outbuf_height lines is OK, but won't
+provide any material speed improvement over that height.)
+
+
+Special color spaces
+--------------------
+
+The JPEG standard itself is "color blind" and doesn't specify any particular
+color space. It is customary to convert color data to a luminance/chrominance
+color space before compressing, since this permits greater compression. The
+existing de-facto JPEG file format standards specify YCbCr or grayscale data
+(JFIF), or grayscale, RGB, YCbCr, CMYK, or YCCK (Adobe). For special
+applications such as multispectral images, other color spaces can be used,
+but it must be understood that such files will be unportable.
+
+The JPEG library can handle the most common colorspace conversions (namely
+RGB <=> YCbCr and CMYK <=> YCCK). It can also deal with data of an unknown
+color space, passing it through without conversion. If you deal extensively
+with an unusual color space, you can easily extend the library to understand
+additional color spaces and perform appropriate conversions.
+
+For compression, the source data's color space is specified by field
+in_color_space. This is transformed to the JPEG file's color space given
+by jpeg_color_space. jpeg_set_defaults() chooses a reasonable JPEG color
+space depending on in_color_space, but you can override this by calling
+jpeg_set_colorspace(). Of course you must select a supported transformation.
+jccolor.c currently supports the following transformations:
+ RGB => YCbCr
+ RGB => GRAYSCALE
+ YCbCr => GRAYSCALE
+ CMYK => YCCK
+plus the null transforms: GRAYSCALE => GRAYSCALE, RGB => RGB,
+YCbCr => YCbCr, CMYK => CMYK, YCCK => YCCK, and UNKNOWN => UNKNOWN.
+
+The de-facto file format standards (JFIF and Adobe) specify APPn markers that
+indicate the color space of the JPEG file. It is important to ensure that
+these are written correctly, or omitted if the JPEG file's color space is not
+one of the ones supported by the de-facto standards. jpeg_set_colorspace()
+will set the compression parameters to include or omit the APPn markers
+properly, so long as it is told the truth about the JPEG color space.
+For example, if you are writing some random 3-component color space without
+conversion, don't try to fake out the library by setting in_color_space and
+jpeg_color_space to JCS_YCbCr; use JCS_UNKNOWN. You may want to write an
+APPn marker of your own devising to identify the colorspace --- see "Special
+markers", below.
+
+When told that the color space is UNKNOWN, the library will default to using
+luminance-quality compression parameters for all color components. You may
+well want to change these parameters. See the source code for
+jpeg_set_colorspace(), in jcparam.c, for details.
+
+For decompression, the JPEG file's color space is given in jpeg_color_space,
+and this is transformed to the output color space out_color_space.
+jpeg_read_header's setting of jpeg_color_space can be relied on if the file
+conforms to JFIF or Adobe conventions, but otherwise it is no better than a
+guess. If you know the JPEG file's color space for certain, you can override
+jpeg_read_header's guess by setting jpeg_color_space. jpeg_read_header also
+selects a default output color space based on (its guess of) jpeg_color_space;
+set out_color_space to override this. Again, you must select a supported
+transformation. jdcolor.c currently supports
+ YCbCr => GRAYSCALE
+ YCbCr => RGB
+ GRAYSCALE => RGB
+ YCCK => CMYK
+as well as the null transforms. (Since GRAYSCALE=>RGB is provided, an
+application can force grayscale JPEGs to look like color JPEGs if it only
+wants to handle one case.)
+
+The two-pass color quantizer, jquant2.c, is specialized to handle RGB data
+(it weights distances appropriately for RGB colors). You'll need to modify
+the code if you want to use it for non-RGB output color spaces. Note that
+jquant2.c is used to map to an application-supplied colormap as well as for
+the normal two-pass colormap selection process.
+
+CAUTION: it appears that Adobe Photoshop writes inverted data in CMYK JPEG
+files: 0 represents 100% ink coverage, rather than 0% ink as you'd expect.
+This is arguably a bug in Photoshop, but if you need to work with Photoshop
+CMYK files, you will have to deal with it in your application. We cannot
+"fix" this in the library by inverting the data during the CMYK<=>YCCK
+transform, because that would break other applications, notably Ghostscript.
+Photoshop versions prior to 3.0 write EPS files containing JPEG-encoded CMYK
+data in the same inverted-YCCK representation used in bare JPEG files, but
+the surrounding PostScript code performs an inversion using the PS image
+operator. I am told that Photoshop 3.0 will write uninverted YCCK in
+EPS/JPEG files, and will omit the PS-level inversion. (But the data
+polarity used in bare JPEG files will not change in 3.0.) In either case,
+the JPEG library must not invert the data itself, or else Ghostscript would
+read these EPS files incorrectly.
+
+
+Error handling
+--------------
+
+When the default error handler is used, any error detected inside the JPEG
+routines will cause a message to be printed on stderr, followed by exit().
+You can supply your own error handling routines to override this behavior
+and to control the treatment of nonfatal warnings and trace/debug messages.
+The file example.c illustrates the most common case, which is to have the
+application regain control after an error rather than exiting.
+
+The JPEG library never writes any message directly; it always goes through
+the error handling routines. Three classes of messages are recognized:
+ * Fatal errors: the library cannot continue.
+ * Warnings: the library can continue, but the data is corrupt, and a
+ damaged output image is likely to result.
+ * Trace/informational messages. These come with a trace level indicating
+ the importance of the message; you can control the verbosity of the
+ program by adjusting the maximum trace level that will be displayed.
+
+You may, if you wish, simply tqreplace the entire JPEG error handling module
+(jerror.c) with your own code. However, you can avoid code duplication by
+only replacing some of the routines depending on the behavior you need.
+This is accomplished by calling jpeg_std_error() as usual, but then overriding
+some of the method pointers in the jpeg_error_mgr struct, as illustrated by
+example.c.
+
+All of the error handling routines will receive a pointer to the JPEG object
+(a j_common_ptr which points to either a jpeg_compress_struct or a
+jpeg_decompress_struct; if you need to tell which, test the is_decompressor
+field). This struct includes a pointer to the error manager struct in its
+"err" field. Frequently, custom error handler routines will need to access
+additional data which is not known to the JPEG library or the standard error
+handler. The most convenient way to do this is to embed either the JPEG
+object or the jpeg_error_mgr struct in a larger structure that tqcontains
+additional fields; then casting the passed pointer provides access to the
+additional fields. Again, see example.c for one way to do it. (Beginning
+with IJG version 6b, there is also a void pointer "client_data" in each
+JPEG object, which the application can also use to tqfind related data.
+The library does not touch client_data at all.)
+
+The individual methods that you might wish to override are:
+
+error_exit (j_common_ptr cinfo)
+ Receives control for a fatal error. Information sufficient to
+ generate the error message has been stored in cinfo->err; call
+ output_message to display it. Control must NOT return to the caller;
+ generally this routine will exit() or longjmp() somewhere.
+ Typically you would override this routine to get rid of the exit()
+ default behavior. Note that if you continue processing, you should
+ clean up the JPEG object with jpeg_abort() or jpeg_destroy().
+
+output_message (j_common_ptr cinfo)
+ Actual output of any JPEG message. Override this to send messages
+ somewhere other than stderr. Note that this method does not know
+ how to generate a message, only where to send it.
+
+format_message (j_common_ptr cinfo, char * buffer)
+ Constructs a readable error message string based on the error info
+ stored in cinfo->err. This method is called by output_message. Few
+ applications should need to override this method. One possible
+ reason for doing so is to implement dynamic switching of error message
+ language.
+
+emit_message (j_common_ptr cinfo, int msg_level)
+ Decide whether or not to emit a warning or trace message; if so,
+ calls output_message. The main reason for overriding this method
+ would be to abort on warnings. msg_level is -1 for warnings,
+ 0 and up for trace messages.
+
+Only error_exit() and emit_message() are called from the rest of the JPEG
+library; the other two are internal to the error handler.
+
+The actual message texts are stored in an array of strings which is pointed to
+by the field err->jpeg_message_table. The messages are numbered from 0 to
+err->last_jpeg_message, and it is these code numbers that are used in the
+JPEG library code. You could tqreplace the message texts (for instance, with
+messages in French or German) by changing the message table pointer. See
+jerror.h for the default texts. CAUTION: this table will almost certainly
+change or grow from one library version to the next.
+
+It may be useful for an application to add its own message texts that are
+handled by the same mechanism. The error handler supports a second "add-on"
+message table for this purpose. To define an addon table, set the pointer
+err->addon_message_table and the message numbers err->first_addon_message and
+err->last_addon_message. If you number the addon messages beginning at 1000
+or so, you won't have to worry about conflicts with the library's built-in
+messages. See the sample applications cjpeg/djpeg for an example of using
+addon messages (the addon messages are defined in cderror.h).
+
+Actual invocation of the error handler is done via macros defined in jerror.h:
+ ERREXITn(...) for fatal errors
+ WARNMSn(...) for corrupt-data warnings
+ TRACEMSn(...) for trace and informational messages.
+These macros store the message code and any additional parameters into the
+error handler struct, then invoke the error_exit() or emit_message() method.
+The variants of each macro are for varying numbers of additional parameters.
+The additional parameters are inserted into the generated message using
+standard printf() format codes.
+
+See jerror.h and jerror.c for further details.
+
+
+Compressed data handling (source and destination managers)
+----------------------------------------------------------
+
+The JPEG compression library sends its compressed data to a "destination
+manager" module. The default destination manager just writes the data to a
+stdio stream, but you can provide your own manager to do something else.
+Similarly, the decompression library calls a "source manager" to obtain the
+compressed data; you can provide your own source manager if you want the data
+to come from somewhere other than a stdio stream.
+
+In both cases, compressed data is processed a bufferload at a time: the
+destination or source manager provides a work buffer, and the library invokes
+the manager only when the buffer is filled or emptied. (You could define a
+one-character buffer to force the manager to be invoked for each byte, but
+that would be rather inefficient.) The buffer's size and location are
+controlled by the manager, not by the library. For example, if you desired to
+decompress a JPEG datastream that was all in memory, you could just make the
+buffer pointer and length point to the original data in memory. Then the
+buffer-reload procedure would be invoked only if the decompressor ran off the
+end of the datastream, which would indicate an erroneous datastream.
+
+The work buffer is defined as an array of datatype JOCTET, which is generally
+"char" or "unsigned char". On a machine where char is not exactly 8 bits
+wide, you must define JOCTET as a wider data type and then modify the data
+source and destination modules to transcribe the work arrays into 8-bit units
+on external storage.
+
+A data destination manager struct tqcontains a pointer and count defining the
+next byte to write in the work buffer and the remaining free space:
+
+ JOCTET * next_output_byte; /* => next byte to write in buffer */
+ size_t free_in_buffer; /* # of byte spaces remaining in buffer */
+
+The library increments the pointer and decrements the count until the buffer
+is filled. The manager's empty_output_buffer method must reset the pointer
+and count. The manager is expected to remember the buffer's starting address
+and total size in private fields not visible to the library.
+
+A data destination manager provides three methods:
+
+init_destination (j_compress_ptr cinfo)
+ Initialize destination. This is called by jpeg_start_compress()
+ before any data is actually written. It must initialize
+ next_output_byte and free_in_buffer. free_in_buffer must be
+ initialized to a positive value.
+
+empty_output_buffer (j_compress_ptr cinfo)
+ This is called whenever the buffer has filled (free_in_buffer
+ reaches zero). In typical applications, it should write out the
+ *entire* buffer (use the saved start address and buffer length;
+ ignore the current state of next_output_byte and free_in_buffer).
+ Then reset the pointer & count to the start of the buffer, and
+ return TRUE indicating that the buffer has been dumped.
+ free_in_buffer must be set to a positive value when TRUE is
+ returned. A FALSE return should only be used when I/O suspension is
+ desired (this operating mode is discussed in the next section).
+
+term_destination (j_compress_ptr cinfo)
+ Terminate destination --- called by jpeg_finish_compress() after all
+ data has been written. In most applications, this must flush any
+ data remaining in the buffer. Use either next_output_byte or
+ free_in_buffer to determine how much data is in the buffer.
+
+term_destination() is NOT called by jpeg_abort() or jpeg_destroy(). If you
+want the destination manager to be cleaned up during an abort, you must do it
+yourself.
+
+You will also need code to create a jpeg_destination_mgr struct, fill in its
+method pointers, and insert a pointer to the struct into the "dest" field of
+the JPEG compression object. This can be done in-line in your setup code if
+you like, but it's probably cleaner to provide a separate routine similar to
+the jpeg_stdio_dest() routine of the supplied destination manager.
+
+Decompression source managers follow a parallel design, but with some
+additional frammishes. The source manager struct tqcontains a pointer and count
+defining the next byte to read from the work buffer and the number of bytes
+remaining:
+
+ const JOCTET * next_input_byte; /* => next byte to read from buffer */
+ size_t bytes_in_buffer; /* # of bytes remaining in buffer */
+
+The library increments the pointer and decrements the count until the buffer
+is emptied. The manager's fill_input_buffer method must reset the pointer and
+count. In most applications, the manager must remember the buffer's starting
+address and total size in private fields not visible to the library.
+
+A data source manager provides five methods:
+
+init_source (j_decompress_ptr cinfo)
+ Initialize source. This is called by jpeg_read_header() before any
+ data is actually read. Unlike init_destination(), it may leave
+ bytes_in_buffer set to 0 (in which case a fill_input_buffer() call
+ will occur immediately).
+
+fill_input_buffer (j_decompress_ptr cinfo)
+ This is called whenever bytes_in_buffer has reached zero and more
+ data is wanted. In typical applications, it should read fresh data
+ into the buffer (ignoring the current state of next_input_byte and
+ bytes_in_buffer), reset the pointer & count to the start of the
+ buffer, and return TRUE indicating that the buffer has been reloaded.
+ It is not necessary to fill the buffer entirely, only to obtain at
+ least one more byte. bytes_in_buffer MUST be set to a positive value
+ if TRUE is returned. A FALSE return should only be used when I/O
+ suspension is desired (this mode is discussed in the next section).
+
+skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+ Skip num_bytes worth of data. The buffer pointer and count should
+ be advanced over num_bytes input bytes, refilling the buffer as
+ needed. This is used to skip over a potentially large amount of
+ uninteresting data (such as an APPn marker). In some applications
+ it may be possible to optimize away the reading of the skipped data,
+ but it's not clear that being smart is worth much trouble; large
+ skips are uncommon. bytes_in_buffer may be zero on return.
+ A zero or negative skip count should be treated as a no-op.
+
+resync_to_restart (j_decompress_ptr cinfo, int desired)
+ This routine is called only when the decompressor has failed to tqfind
+ a restart (RSTn) marker where one is expected. Its mission is to
+ tqfind a suitable point for resuming decompression. For most
+ applications, we recommend that you just use the default resync
+ procedure, jpeg_resync_to_restart(). However, if you are able to back
+ up in the input data stream, or if you have a-priori knowledge about
+ the likely location of restart markers, you may be able to do better.
+ Read the read_restart_marker() and jpeg_resync_to_restart() routines
+ in jdmarker.c if you think you'd like to implement your own resync
+ procedure.
+
+term_source (j_decompress_ptr cinfo)
+ Terminate source --- called by jpeg_finish_decompress() after all
+ data has been read. Often a no-op.
+
+For both fill_input_buffer() and skip_input_data(), there is no such thing
+as an EOF return. If the end of the file has been reached, the routine has
+a choice of exiting via ERREXIT() or inserting fake data into the buffer.
+In most cases, generating a warning message and inserting a fake EOI marker
+is the best course of action --- this will allow the decompressor to output
+however much of the image is there. In pathological cases, the decompressor
+may swallow the EOI and again demand data ... just keep feeding it fake EOIs.
+jdatasrc.c illustrates the recommended error recovery behavior.
+
+term_source() is NOT called by jpeg_abort() or jpeg_destroy(). If you want
+the source manager to be cleaned up during an abort, you must do it yourself.
+
+You will also need code to create a jpeg_source_mgr struct, fill in its method
+pointers, and insert a pointer to the struct into the "src" field of the JPEG
+decompression object. This can be done in-line in your setup code if you
+like, but it's probably cleaner to provide a separate routine similar to the
+jpeg_stdio_src() routine of the supplied source manager.
+
+For more information, consult the stdio source and destination managers
+in jdatasrc.c and jdatadst.c.
+
+
+I/O suspension
+--------------
+
+Some applications need to use the JPEG library as an incremental memory-to-
+memory filter: when the compressed data buffer is filled or emptied, they want
+control to return to the outer loop, rather than expecting that the buffer can
+be emptied or reloaded within the data source/destination manager subroutine.
+The library supports this need by providing an "I/O suspension" mode, which we
+describe in this section.
+
+The I/O suspension mode is not a panacea: nothing is guaranteed about the
+maximum amount of time spent in any one call to the library, so it will not
+eliminate response-time problems in single-threaded applications. If you
+need guaranteed response time, we suggest you "bite the bullet" and implement
+a real multi-tasking capability.
+
+To use I/O suspension, cooperation is needed between the calling application
+and the data source or destination manager; you will always need a custom
+source/destination manager. (Please read the previous section if you haven't
+already.) The basic idea is that the empty_output_buffer() or
+fill_input_buffer() routine is a no-op, merely returning FALSE to indicate
+that it has done nothing. Upon seeing this, the JPEG library suspends
+operation and returns to its caller. The surrounding application is
+responsible for emptying or refilling the work buffer before calling the
+JPEG library again.
+
+Compression suspension:
+
+For compression suspension, use an empty_output_buffer() routine that returns
+FALSE; typically it will not do anything else. This will cause the
+compressor to return to the caller of jpeg_write_scanlines(), with the return
+value indicating that not all the supplied scanlines have been accepted.
+The application must make more room in the output buffer, adjust the output
+buffer pointer/count appropriately, and then call jpeg_write_scanlines()
+again, pointing to the first unconsumed scanline.
+
+When forced to suspend, the compressor will backtrack to a convenient stopping
+point (usually the start of the current MCU); it will regenerate some output
+data when restarted. Therefore, although empty_output_buffer() is only
+called when the buffer is filled, you should NOT write out the entire buffer
+after a suspension. Write only the data up to the current position of
+next_output_byte/free_in_buffer. The data beyond that point will be
+regenerated after resumption.
+
+Because of the backtracking behavior, a good-size output buffer is essential
+for efficiency; you don't want the compressor to suspend often. (In fact, an
+overly small buffer could lead to infinite looping, if a single MCU required
+more data than would fit in the buffer.) We recommend a buffer of at least
+several Kbytes. You may want to insert explicit code to ensure that you don't
+call jpeg_write_scanlines() unless there is a reasonable amount of space in
+the output buffer; in other words, flush the buffer before trying to compress
+more data.
+
+The compressor does not allow suspension while it is trying to write JPEG
+markers at the beginning and end of the file. This means that:
+ * At the beginning of a compression operation, there must be enough free
+ space in the output buffer to hold the header markers (typically 600 or
+ so bytes). The recommended buffer size is bigger than this anyway, so
+ this is not a problem as long as you start with an empty buffer. However,
+ this restriction might catch you if you insert large special markers, such
+ as a JFIF thumbnail image, without flushing the buffer afterwards.
+ * When you call jpeg_finish_compress(), there must be enough space in the
+ output buffer to emit any buffered data and the final EOI marker. In the
+ current implementation, half a dozen bytes should suffice for this, but
+ for safety's sake we recommend ensuring that at least 100 bytes are free
+ before calling jpeg_finish_compress().
+
+A more significant restriction is that jpeg_finish_compress() cannot suspend.
+This means you cannot use suspension with multi-pass operating modes, namely
+Huffman code optimization and multiple-scan output. Those modes write the
+whole file during jpeg_finish_compress(), which will certainly result in
+buffer overrun. (Note that this restriction applies only to compression,
+not decompression. The decompressor supports input suspension in all of its
+operating modes.)
+
+Decompression suspension:
+
+For decompression suspension, use a fill_input_buffer() routine that simply
+returns FALSE (except perhaps during error recovery, as discussed below).
+This will cause the decompressor to return to its caller with an indication
+that suspension has occurred. This can happen at four places:
+ * jpeg_read_header(): will return JPEG_SUSPENDED.
+ * jpeg_start_decompress(): will return FALSE, rather than its usual TRUE.
+ * jpeg_read_scanlines(): will return the number of scanlines already
+ completed (possibly 0).
+ * jpeg_finish_decompress(): will return FALSE, rather than its usual TRUE.
+The surrounding application must recognize these cases, load more data into
+the input buffer, and repeat the call. In the case of jpeg_read_scanlines(),
+increment the passed pointers past any scanlines successfully read.
+
+Just as with compression, the decompressor will typically backtrack to a
+convenient restart point before suspending. When fill_input_buffer() is
+called, next_input_byte/bytes_in_buffer point to the current restart point,
+which is where the decompressor will backtrack to if FALSE is returned.
+The data beyond that position must NOT be discarded if you suspend; it needs
+to be re-read upon resumption. In most implementations, you'll need to shift
+this data down to the start of your work buffer and then load more data after
+it. Again, this behavior means that a several-Kbyte work buffer is essential
+for decent performance; furthermore, you should load a reasonable amount of
+new data before resuming decompression. (If you loaded, say, only one new
+byte each time around, you could waste a LOT of cycles.)
+
+The skip_input_data() source manager routine requires special care in a
+suspension scenario. This routine is NOT granted the ability to suspend the
+decompressor; it can decrement bytes_in_buffer to zero, but no more. If the
+requested skip distance exceeds the amount of data currently in the input
+buffer, then skip_input_data() must set bytes_in_buffer to zero and record the
+additional skip distance somewhere else. The decompressor will immediately
+call fill_input_buffer(), which should return FALSE, which will cause a
+suspension return. The surrounding application must then arrange to discard
+the recorded number of bytes before it resumes loading the input buffer.
+(Yes, this design is rather baroque, but it avoids complexity in the far more
+common case where a non-suspending source manager is used.)
+
+If the input data has been exhausted, we recommend that you emit a warning
+and insert dummy EOI markers just as a non-suspending data source manager
+would do. This can be handled either in the surrounding application logic or
+within fill_input_buffer(); the latter is probably more efficient. If
+fill_input_buffer() knows that no more data is available, it can set the
+pointer/count to point to a dummy EOI marker and then return TRUE just as
+though it had read more data in a non-suspending situation.
+
+The decompressor does not attempt to suspend within standard JPEG markers;
+instead it will backtrack to the start of the marker and reprocess the whole
+marker next time. Hence the input buffer must be large enough to hold the
+longest standard marker in the file. Standard JPEG markers should normally
+not exceed a few hundred bytes each (DHT tables are typically the longest).
+We recommend at least a 2K buffer for performance reasons, which is much
+larger than any correct marker is likely to be. For robustness against
+damaged marker length counts, you may wish to insert a test in your
+application for the case that the input buffer is completely full and yet
+the decoder has suspended without consuming any data --- otherwise, if this
+situation did occur, it would lead to an endless loop. (The library can't
+provide this test since it has no idea whether "the buffer is full", or
+even whether there is a fixed-size input buffer.)
+
+The input buffer would need to be 64K to allow for arbitrary COM or APPn
+markers, but these are handled specially: they are either saved into allocated
+memory, or skipped over by calling skip_input_data(). In the former case,
+suspension is handled correctly, and in the latter case, the problem of
+buffer overrun is placed on skip_input_data's shoulders, as explained above.
+Note that if you provide your own marker handling routine for large markers,
+you should consider how to deal with buffer overflow.
+
+Multiple-buffer management:
+
+In some applications it is desirable to store the compressed data in a linked
+list of buffer areas, so as to avoid data copying. This can be handled by
+having empty_output_buffer() or fill_input_buffer() set the pointer and count
+to reference the next available buffer; FALSE is returned only if no more
+buffers are available. Although seemingly straightforward, there is a
+pitfall in this approach: the backtrack that occurs when FALSE is returned
+could back up into an earlier buffer. For example, when fill_input_buffer()
+is called, the current pointer & count indicate the backtrack restart point.
+Since fill_input_buffer() will set the pointer and count to refer to a new
+buffer, the restart position must be saved somewhere else. Suppose a second
+call to fill_input_buffer() occurs in the same library call, and no
+additional input data is available, so fill_input_buffer must return FALSE.
+If the JPEG library has not moved the pointer/count forward in the current
+buffer, then *the correct restart point is the saved position in the prior
+buffer*. Prior buffers may be discarded only after the library establishes
+a restart point within a later buffer. Similar remarks apply for output into
+a chain of buffers.
+
+The library will never attempt to backtrack over a skip_input_data() call,
+so any skipped data can be permanently discarded. You still have to deal
+with the case of skipping not-yet-received data, however.
+
+It's much simpler to use only a single buffer; when fill_input_buffer() is
+called, move any unconsumed data (beyond the current pointer/count) down to
+the beginning of this buffer and then load new data into the remaining buffer
+space. This approach requires a little more data copying but is far easier
+to get right.
+
+
+Progressive JPEG support
+------------------------
+
+Progressive JPEG rearranges the stored data into a series of scans of
+increasing quality. In situations where a JPEG file is transmitted across a
+slow communications link, a decoder can generate a low-quality image very
+quickly from the first scan, then gradually improve the displayed quality as
+more scans are received. The final image after all scans are complete is
+identical to that of a regular (sequential) JPEG file of the same quality
+setting. Progressive JPEG files are often slightly smaller than equivalent
+sequential JPEG files, but the possibility of incremental display is the main
+reason for using progressive JPEG.
+
+The IJG encoder library generates progressive JPEG files when given a
+suitable "scan script" defining how to divide the data into scans.
+Creation of progressive JPEG files is otherwise transtqparent to the encoder.
+Progressive JPEG files can also be read transparently by the decoder library.
+If the decoding application simply uses the library as defined above, it
+will receive a final decoded image without any indication that the file was
+progressive. Of course, this approach does not allow incremental display.
+To perform incremental display, an application needs to use the decoder
+library's "buffered-image" mode, in which it receives a decoded image
+multiple times.
+
+Each displayed scan requires about as much work to decode as a full JPEG
+image of the same size, so the decoder must be fairly fast in relation to the
+data transmission rate in order to make incremental display useful. However,
+it is possible to skip displaying the image and simply add the incoming bits
+to the decoder's coefficient buffer. This is fast because only Huffman
+decoding need be done, not IDCT, upsampling, colorspace conversion, etc.
+The IJG decoder library allows the application to switch dynamically between
+displaying the image and simply absorbing the incoming bits. A properly
+coded application can automatically adapt the number of display passes to
+suit the time available as the image is received. Also, a final
+higher-quality display cycle can be performed from the buffered data after
+the end of the file is reached.
+
+Progressive compression:
+
+To create a progressive JPEG file (or a multiple-scan sequential JPEG file),
+set the scan_info cinfo field to point to an array of scan descriptors, and
+perform compression as usual. Instead of constructing your own scan list,
+you can call the jpeg_simple_progression() helper routine to create a
+recommended progression sequence; this method should be used by all
+applications that don't want to get involved in the nitty-gritty of
+progressive scan sequence design. (If you want to provide user control of
+scan sequences, you may wish to borrow the scan script reading code found
+in rdswitch.c, so that you can read scan script files just like cjpeg's.)
+When scan_info is not NULL, the compression library will store DCT'd data
+into a buffer array as jpeg_write_scanlines() is called, and will emit all
+the requested scans during jpeg_finish_compress(). This implies that
+multiple-scan output cannot be created with a suspending data destination
+manager, since jpeg_finish_compress() does not support suspension. We
+should also note that the compressor currently forces Huffman optimization
+mode when creating a progressive JPEG file, because the default Huffman
+tables are unsuitable for progressive files.
+
+Progressive decompression:
+
+When buffered-image mode is not used, the decoder library will read all of
+a multi-scan file during jpeg_start_decompress(), so that it can provide a
+final decoded image. (Here "multi-scan" means either progressive or
+multi-scan sequential.) This makes multi-scan files transtqparent to the
+decoding application. However, existing applications that used suspending
+input with version 5 of the IJG library will need to be modified to check
+for a suspension return from jpeg_start_decompress().
+
+To perform incremental display, an application must use the library's
+buffered-image mode. This is described in the next section.
+
+
+Buffered-image mode
+-------------------
+
+In buffered-image mode, the library stores the partially decoded image in a
+coefficient buffer, from which it can be read out as many times as desired.
+This mode is typically used for incremental display of progressive JPEG files,
+but it can be used with any JPEG file. Each scan of a progressive JPEG file
+adds more data (more detail) to the buffered image. The application can
+display in lockstep with the source file (one display pass per input scan),
+or it can allow input processing to outrun display processing. By making
+input and display processing run independently, it is possible for the
+application to adapt progressive display to a wide range of data transmission
+rates.
+
+The basic control flow for buffered-image decoding is
+
+ jpeg_create_decompress()
+ set data source
+ jpeg_read_header()
+ set overall decompression parameters
+ cinfo.buffered_image = TRUE; /* select buffered-image mode */
+ jpeg_start_decompress()
+ for (each output pass) {
+ adjust output decompression parameters if required
+ jpeg_start_output() /* start a new output pass */
+ for (all scanlines in image) {
+ jpeg_read_scanlines()
+ display scanlines
+ }
+ jpeg_finish_output() /* terminate output pass */
+ }
+ jpeg_finish_decompress()
+ jpeg_destroy_decompress()
+
+This differs from ordinary unbuffered decoding in that there is an additional
+level of looping. The application can choose how many output passes to make
+and how to display each pass.
+
+The simplest approach to displaying progressive images is to do one display
+pass for each scan appearing in the input file. In this case the outer loop
+condition is typically
+ while (! jpeg_input_complete(&cinfo))
+and the start-output call should read
+ jpeg_start_output(&cinfo, cinfo.input_scan_number);
+The second parameter to jpeg_start_output() indicates which scan of the input
+file is to be displayed; the scans are numbered starting at 1 for this
+purpose. (You can use a loop counter starting at 1 if you like, but using
+the library's input scan counter is easier.) The library automatically reads
+data as necessary to complete each requested scan, and jpeg_finish_output()
+advances to the next scan or end-of-image marker (hence input_scan_number
+will be incremented by the time control arrives back at jpeg_start_output()).
+With this technique, data is read from the input file only as needed, and
+input and output processing run in lockstep.
+
+After reading the final scan and reaching the end of the input file, the
+buffered image remains available; it can be read additional times by
+repeating the jpeg_start_output()/jpeg_read_scanlines()/jpeg_finish_output()
+sequence. For example, a useful technique is to use fast one-pass color
+quantization for display passes made while the image is arriving, followed by
+a final display pass using two-pass quantization for highest quality. This
+is done by changing the library parameters before the final output pass.
+Changing parameters between passes is discussed in detail below.
+
+In general the last scan of a progressive file cannot be recognized as such
+until after it is read, so a post-input display pass is the best approach if
+you want special processing in the final pass.
+
+When done with the image, be sure to call jpeg_finish_decompress() to release
+the buffered image (or just use jpeg_destroy_decompress()).
+
+If input data arrives faster than it can be displayed, the application can
+cause the library to decode input data in advance of what's needed to produce
+output. This is done by calling the routine jpeg_consume_input().
+The return value is one of the following:
+ JPEG_REACHED_SOS: reached an SOS marker (the start of a new scan)
+ JPEG_REACHED_EOI: reached the EOI marker (end of image)
+ JPEG_ROW_COMPLETED: completed reading one MCU row of compressed data
+ JPEG_SCAN_COMPLETED: completed reading last MCU row of current scan
+ JPEG_SUSPENDED: suspended before completing any of the above
+(JPEG_SUSPENDED can occur only if a suspending data source is used.) This
+routine can be called at any time after initializing the JPEG object. It
+reads some additional data and returns when one of the indicated significant
+events occurs. (If called after the EOI marker is reached, it will
+immediately return JPEG_REACHED_EOI without attempting to read more data.)
+
+The library's output processing will automatically call jpeg_consume_input()
+whenever the output processing overtakes the input; thus, simple lockstep
+display requires no direct calls to jpeg_consume_input(). But by adding
+calls to jpeg_consume_input(), you can absorb data in advance of what is
+being displayed. This has two benefits:
+ * You can limit buildup of unprocessed data in your input buffer.
+ * You can eliminate extra display passes by paying attention to the
+ state of the library's input processing.
+
+The first of these benefits only requires interspersing calls to
+jpeg_consume_input() with your display operations and any other processing
+you may be doing. To avoid wasting cycles due to backtracking, it's best to
+call jpeg_consume_input() only after a hundred or so new bytes have arrived.
+This is discussed further under "I/O suspension", above. (Note: the JPEG
+library currently is not thread-safe. You must not call jpeg_consume_input()
+from one thread of control if a different library routine is working on the
+same JPEG object in another thread.)
+
+When input arrives fast enough that more than one new scan is available
+before you start a new output pass, you may as well skip the output pass
+corresponding to the completed scan. This occurs for free if you pass
+cinfo.input_scan_number as the target scan number to jpeg_start_output().
+The input_scan_number field is simply the index of the scan currently being
+consumed by the input processor. You can ensure that this is up-to-date by
+emptying the input buffer just before calling jpeg_start_output(): call
+jpeg_consume_input() repeatedly until it returns JPEG_SUSPENDED or
+JPEG_REACHED_EOI.
+
+The target scan number passed to jpeg_start_output() is saved in the
+cinfo.output_scan_number field. The library's output processing calls
+jpeg_consume_input() whenever the current input scan number and row within
+that scan is less than or equal to the current output scan number and row.
+Thus, input processing can "get ahead" of the output processing but is not
+allowed to "fall behind". You can achieve several different effects by
+manipulating this interlock rule. For example, if you pass a target scan
+number greater than the current input scan number, the output processor will
+wait until that scan starts to arrive before producing any output. (To avoid
+an infinite loop, the target scan number is automatically reset to the last
+scan number when the end of image is reached. Thus, if you specify a large
+target scan number, the library will just absorb the entire input file and
+then perform an output pass. This is effectively the same as what
+jpeg_start_decompress() does when you don't select buffered-image mode.)
+When you pass a target scan number equal to the current input scan number,
+the image is displayed no faster than the current input scan arrives. The
+final possibility is to pass a target scan number less than the current input
+scan number; this disables the input/output interlock and causes the output
+processor to simply display whatever it tqfinds in the image buffer, without
+waiting for input. (However, the library will not accept a target scan
+number less than one, so you can't avoid waiting for the first scan.)
+
+When data is arriving faster than the output display processing can advance
+through the image, jpeg_consume_input() will store data into the buffered
+image beyond the point at which the output processing is reading data out
+again. If the input arrives fast enough, it may "wrap around" the buffer to
+the point where the input is more than one whole scan ahead of the output.
+If the output processing simply proceeds through its display pass without
+paying attention to the input, the effect seen on-screen is that the lower
+part of the image is one or more scans better in quality than the upper part.
+Then, when the next output scan is started, you have a choice of what target
+scan number to use. The recommended choice is to use the current input scan
+number at that time, which implies that you've skipped the output scans
+corresponding to the input scans that were completed while you processed the
+previous output scan. In this way, the decoder automatically adapts its
+speed to the arriving data, by skipping output scans as necessary to keep up
+with the arriving data.
+
+When using this strategy, you'll want to be sure that you perform a final
+output pass after receiving all the data; otherwise your last display may not
+be full quality across the whole screen. So the right outer loop logic is
+something like this:
+ do {
+ absorb any waiting input by calling jpeg_consume_input()
+ final_pass = jpeg_input_complete(&cinfo);
+ adjust output decompression parameters if required
+ jpeg_start_output(&cinfo, cinfo.input_scan_number);
+ ...
+ jpeg_finish_output()
+ } while (! final_pass);
+rather than quitting as soon as jpeg_input_complete() returns TRUE. This
+arrangement makes it simple to use higher-quality decoding parameters
+for the final pass. But if you don't want to use special parameters for
+the final pass, the right loop logic is like this:
+ for (;;) {
+ absorb any waiting input by calling jpeg_consume_input()
+ jpeg_start_output(&cinfo, cinfo.input_scan_number);
+ ...
+ jpeg_finish_output()
+ if (jpeg_input_complete(&cinfo) &&
+ cinfo.input_scan_number == cinfo.output_scan_number)
+ break;
+ }
+In this case you don't need to know in advance whether an output pass is to
+be the last one, so it's not necessary to have reached EOF before starting
+the final output pass; rather, what you want to test is whether the output
+pass was performed in sync with the final input scan. This form of the loop
+will avoid an extra output pass whenever the decoder is able (or nearly able)
+to keep up with the incoming data.
+
+When the data transmission speed is high, you might begin a display pass,
+then tqfind that much or all of the file has arrived before you can complete
+the pass. (You can detect this by noting the JPEG_REACHED_EOI return code
+from jpeg_consume_input(), or equivalently by testing jpeg_input_complete().)
+In this situation you may wish to abort the current display pass and start a
+new one using the newly arrived information. To do so, just call
+jpeg_finish_output() and then start a new pass with jpeg_start_output().
+
+A variant strategy is to abort and restart display if more than one complete
+scan arrives during an output pass; this can be detected by noting
+JPEG_REACHED_SOS returns and/or examining cinfo.input_scan_number. This
+idea should be employed with caution, however, since the display process
+might never get to the bottom of the image before being aborted, resulting
+in the lower part of the screen being several passes worse than the upper.
+In most cases it's probably best to abort an output pass only if the whole
+file has arrived and you want to begin the final output pass immediately.
+
+When receiving data across a communication link, we recommend always using
+the current input scan number for the output target scan number; if a
+higher-quality final pass is to be done, it should be started (aborting any
+incomplete output pass) as soon as the end of file is received. However,
+many other strategies are possible. For example, the application can examine
+the parameters of the current input scan and decide whether to display it or
+not. If the scan tqcontains only chroma data, one might choose not to use it
+as the target scan, expecting that the scan will be small and will arrive
+quickly. To skip to the next scan, call jpeg_consume_input() until it
+returns JPEG_REACHED_SOS or JPEG_REACHED_EOI. Or just use the next higher
+number as the target scan for jpeg_start_output(); but that method doesn't
+let you inspect the next scan's parameters before deciding to display it.
+
+
+In buffered-image mode, jpeg_start_decompress() never performs input and
+thus never suspends. An application that uses input suspension with
+buffered-image mode must be prepared for suspension returns from these
+routines:
+* jpeg_start_output() performs input only if you request 2-pass quantization
+ and the target scan isn't fully read yet. (This is discussed below.)
+* jpeg_read_scanlines(), as always, returns the number of scanlines that it
+ was able to produce before suspending.
+* jpeg_finish_output() will read any markers following the target scan,
+ up to the end of the file or the SOS marker that begins another scan.
+ (But it reads no input if jpeg_consume_input() has already reached the
+ end of the file or a SOS marker beyond the target output scan.)
+* jpeg_finish_decompress() will read until the end of file, and thus can
+ suspend if the end hasn't already been reached (as can be tested by
+ calling jpeg_input_complete()).
+jpeg_start_output(), jpeg_finish_output(), and jpeg_finish_decompress()
+all return TRUE if they completed their tasks, FALSE if they had to suspend.
+In the event of a FALSE return, the application must load more input data
+and repeat the call. Applications that use non-suspending data sources need
+not check the return values of these three routines.
+
+
+It is possible to change decoding parameters between output passes in the
+buffered-image mode. The decoder library currently supports only very
+limited changes of parameters. ONLY THE FOLLOWING parameter changes are
+allowed after jpeg_start_decompress() is called:
+* dct_method can be changed before each call to jpeg_start_output().
+ For example, one could use a fast DCT method for early scans, changing
+ to a higher quality method for the final scan.
+* dither_mode can be changed before each call to jpeg_start_output();
+ of course this has no impact if not using color quantization. Typically
+ one would use ordered dither for initial passes, then switch to
+ Floyd-Steinberg dither for the final pass. Caution: changing dither mode
+ can cause more memory to be allocated by the library. Although the amount
+ of memory involved is not large (a scanline or so), it may cause the
+ initial max_memory_to_use specification to be exceeded, which in the worst
+ case would result in an out-of-memory failure.
+* do_block_smoothing can be changed before each call to jpeg_start_output().
+ This setting is relevant only when decoding a progressive JPEG image.
+ During the first DC-only scan, block smoothing provides a very "fuzzy" look
+ instead of the very "blocky" look seen without it; which is better seems a
+ matter of personal taste. But block smoothing is nearly always a win
+ during later stages, especially when decoding a successive-approximation
+ image: smoothing helps to hide the slight blockiness that otherwise shows
+ up on smooth gradients until the lowest coefficient bits are sent.
+* Color quantization mode can be changed under the rules described below.
+ You *cannot* change between full-color and quantized output (because that
+ would alter the required I/O buffer sizes), but you can change which
+ quantization method is used.
+
+When generating color-quantized output, changing quantization method is a
+very useful way of switching between high-speed and high-quality display.
+The library allows you to change among its three quantization methods:
+1. Single-pass quantization to a fixed color cube.
+ Selected by cinfo.two_pass_quantize = FALSE and cinfo.colormap = NULL.
+2. Single-pass quantization to an application-supplied colormap.
+ Selected by setting cinfo.colormap to point to the colormap (the value of
+ two_pass_quantize is ignored); also set cinfo.actual_number_of_colors.
+3. Two-pass quantization to a colormap chosen specifically for the image.
+ Selected by cinfo.two_pass_quantize = TRUE and cinfo.colormap = NULL.
+ (This is the default setting selected by jpeg_read_header, but it is
+ probably NOT what you want for the first pass of progressive display!)
+These methods offer successively better quality and lesser speed. However,
+only the first method is available for quantizing in non-RGB color spaces.
+
+IMPORTANT: because the different quantizer methods have very different
+working-storage requirements, the library requires you to indicate which
+one(s) you intend to use before you call jpeg_start_decompress(). (If we did
+not require this, the max_memory_to_use setting would be a complete fiction.)
+You do this by setting one or more of these three cinfo fields to TRUE:
+ enable_1pass_quant Fixed color cube colormap
+ enable_external_quant Externally-supplied colormap
+ enable_2pass_quant Two-pass custom colormap
+All three are initialized FALSE by jpeg_read_header(). But
+jpeg_start_decompress() automatically sets TRUE the one selected by the
+current two_pass_quantize and colormap settings, so you only need to set the
+enable flags for any other quantization methods you plan to change to later.
+
+After setting the enable flags correctly at jpeg_start_decompress() time, you
+can change to any enabled quantization method by setting two_pass_quantize
+and colormap properly just before calling jpeg_start_output(). The following
+special rules apply:
+1. You must explicitly set cinfo.colormap to NULL when switching to 1-pass
+ or 2-pass mode from a different mode, or when you want the 2-pass
+ quantizer to be re-run to generate a new colormap.
+2. To switch to an external colormap, or to change to a different external
+ colormap than was used on the prior pass, you must call
+ jpeg_new_colormap() after setting cinfo.colormap.
+NOTE: if you want to use the same colormap as was used in the prior pass,
+you should not do either of these things. This will save some nontrivial
+switchover costs.
+(These requirements exist because cinfo.colormap will always be non-NULL
+after completing a prior output pass, since both the 1-pass and 2-pass
+quantizers set it to point to their output colormaps. Thus you have to
+do one of these two things to notify the library that something has changed.
+Yup, it's a bit klugy, but it's necessary to do it this way for backwards
+compatibility.)
+
+Note that in buffered-image mode, the library generates any requested colormap
+during jpeg_start_output(), not during jpeg_start_decompress().
+
+When using two-pass quantization, jpeg_start_output() makes a pass over the
+buffered image to determine the optimum color map; it therefore may take a
+significant amount of time, whereas ordinarily it does little work. The
+progress monitor hook is called during this pass, if defined. It is also
+important to realize that if the specified target scan number is greater than
+or equal to the current input scan number, jpeg_start_output() will attempt
+to consume input as it makes this pass. If you use a suspending data source,
+you need to check for a FALSE return from jpeg_start_output() under these
+conditions. The combination of 2-pass quantization and a not-yet-fully-read
+target scan is the only case in which jpeg_start_output() will consume input.
+
+
+Application authors who support buffered-image mode may be tempted to use it
+for all JPEG images, even single-scan ones. This will work, but it is
+inefficient: there is no need to create an image-sized coefficient buffer for
+single-scan images. Requesting buffered-image mode for such an image wastes
+memory. Worse, it can cost time on large images, since the buffered data has
+to be swapped out or written to a temporary file. If you are concerned about
+maximum performance on baseline JPEG files, you should use buffered-image
+mode only when the incoming file actually has multiple scans. This can be
+tested by calling jpeg_has_multiple_scans(), which will return a correct
+result at any time after jpeg_read_header() completes.
+
+It is also worth noting that when you use jpeg_consume_input() to let input
+processing get ahead of output processing, the resulting pattern of access to
+the coefficient buffer is quite nonsequential. It's best to use the memory
+manager jmemnobs.c if you can (ie, if you have enough real or virtual main
+memory). If not, at least make sure that max_memory_to_use is set as high as
+possible. If the JPEG memory manager has to use a temporary file, you will
+probably see a lot of disk traffic and poor performance. (This could be
+improved with additional work on the memory manager, but we haven't gotten
+around to it yet.)
+
+In some applications it may be convenient to use jpeg_consume_input() for all
+input processing, including reading the initial markers; that is, you may
+wish to call jpeg_consume_input() instead of jpeg_read_header() during
+startup. This works, but note that you must check for JPEG_REACHED_SOS and
+JPEG_REACHED_EOI return codes as the equivalent of jpeg_read_header's codes.
+Once the first SOS marker has been reached, you must call
+jpeg_start_decompress() before jpeg_consume_input() will consume more input;
+it'll just keep returning JPEG_REACHED_SOS until you do. If you read a
+tables-only file this way, jpeg_consume_input() will return JPEG_REACHED_EOI
+without ever returning JPEG_REACHED_SOS; be sure to check for this case.
+If this happens, the decompressor will not read any more input until you call
+jpeg_abort() to reset it. It is OK to call jpeg_consume_input() even when not
+using buffered-image mode, but in that case it's basically a no-op after the
+initial markers have been read: it will just return JPEG_SUSPENDED.
+
+
+Abbreviated datastreams and multiple images
+-------------------------------------------
+
+A JPEG compression or decompression object can be reused to process multiple
+images. This saves a small amount of time per image by eliminating the
+"create" and "destroy" operations, but that isn't the real purpose of the
+feature. Rather, reuse of an object provides support for abbreviated JPEG
+datastreams. Object reuse can also simplify processing a series of images in
+a single input or output file. This section explains these features.
+
+A JPEG file normally tqcontains several hundred bytes worth of quantization
+and Huffman tables. In a situation where many images will be stored or
+transmitted with identical tables, this may represent an annoying overhead.
+The JPEG standard therefore permits tables to be omitted. The standard
+defines three classes of JPEG datastreams:
+ * "Interchange" datastreams contain an image and all tables needed to decode
+ the image. These are the usual kind of JPEG file.
+ * "Abbreviated image" datastreams contain an image, but are missing some or
+ all of the tables needed to decode that image.
+ * "Abbreviated table specification" (henceforth "tables-only") datastreams
+ contain only table specifications.
+To decode an abbreviated image, it is necessary to load the missing table(s)
+into the decoder beforehand. This can be accomplished by reading a separate
+tables-only file. A variant scheme uses a series of images in which the first
+image is an interchange (complete) datastream, while subsequent ones are
+abbreviated and rely on the tables loaded by the first image. It is assumed
+that once the decoder has read a table, it will remember that table until a
+new definition for the same table number is encountered.
+
+It is the application designer's responsibility to figure out how to associate
+the correct tables with an abbreviated image. While abbreviated datastreams
+can be useful in a closed environment, their use is strongly discouraged in
+any situation where data exchange with other applications might be needed.
+Caveat designer.
+
+The JPEG library provides support for reading and writing any combination of
+tables-only datastreams and abbreviated images. In both compression and
+decompression objects, a quantization or Huffman table will be retained for
+the lifetime of the object, unless it is overwritten by a new table definition.
+
+
+To create abbreviated image datastreams, it is only necessary to tell the
+compressor not to emit some or all of the tables it is using. Each
+quantization and Huffman table struct tqcontains a boolean field "sent_table",
+which normally is initialized to FALSE. For each table used by the image, the
+header-writing process emits the table and sets sent_table = TRUE unless it is
+already TRUE. (In normal usage, this prevents outputting the same table
+definition multiple times, as would otherwise occur because the chroma
+components typically share tables.) Thus, setting this field to TRUE before
+calling jpeg_start_compress() will prevent the table from being written at
+all.
+
+If you want to create a "pure" abbreviated image file containing no tables,
+just call "jpeg_suppress_tables(&cinfo, TRUE)" after constructing all the
+tables. If you want to emit some but not all tables, you'll need to set the
+individual sent_table fields directly.
+
+To create an abbreviated image, you must also call jpeg_start_compress()
+with a second parameter of FALSE, not TRUE. Otherwise jpeg_start_compress()
+will force all the sent_table fields to FALSE. (This is a safety feature to
+prevent abbreviated images from being created accidentally.)
+
+To create a tables-only file, perform the same parameter setup that you
+normally would, but instead of calling jpeg_start_compress() and so on, call
+jpeg_write_tables(&cinfo). This will write an abbreviated datastream
+containing only SOI, DQT and/or DHT markers, and EOI. All the quantization
+and Huffman tables that are currently defined in the compression object will
+be emitted unless their sent_tables flag is already TRUE, and then all the
+sent_tables flags will be set TRUE.
+
+A sure-fire way to create matching tables-only and abbreviated image files
+is to proceed as follows:
+
+ create JPEG compression object
+ set JPEG parameters
+ set destination to tables-only file
+ jpeg_write_tables(&cinfo);
+ set destination to image file
+ jpeg_start_compress(&cinfo, FALSE);
+ write data...
+ jpeg_finish_compress(&cinfo);
+
+Since the JPEG parameters are not altered between writing the table file and
+the abbreviated image file, the same tables are sure to be used. Of course,
+you can repeat the jpeg_start_compress() ... jpeg_finish_compress() sequence
+many times to produce many abbreviated image files matching the table file.
+
+You cannot suppress output of the computed Huffman tables when Huffman
+optimization is selected. (If you could, there'd be no way to decode the
+image...) Generally, you don't want to set optimize_coding = TRUE when
+you are trying to produce abbreviated files.
+
+In some cases you might want to compress an image using tables which are
+not stored in the application, but are defined in an interchange or
+tables-only file readable by the application. This can be done by setting up
+a JPEG decompression object to read the specification file, then copying the
+tables into your compression object. See jpeg_copy_critical_parameters()
+for an example of copying quantization tables.
+
+
+To read abbreviated image files, you simply need to load the proper tables
+into the decompression object before trying to read the abbreviated image.
+If the proper tables are stored in the application program, you can just
+allocate the table structs and fill in their contents directly. For example,
+to load a fixed quantization table into table slot "n":
+
+ if (cinfo.quant_tbl_ptrs[n] == NULL)
+ cinfo.quant_tbl_ptrs[n] = jpeg_alloc_quant_table((j_common_ptr) &cinfo);
+ quant_ptr = cinfo.quant_tbl_ptrs[n]; /* quant_ptr is JQUANT_TBL* */
+ for (i = 0; i < 64; i++) {
+ /* Qtable[] is desired quantization table, in natural array order */
+ quant_ptr->quantval[i] = Qtable[i];
+ }
+
+Code to load a fixed Huffman table is typically (for AC table "n"):
+
+ if (cinfo.ac_huff_tbl_ptrs[n] == NULL)
+ cinfo.ac_huff_tbl_ptrs[n] = jpeg_alloc_huff_table((j_common_ptr) &cinfo);
+ huff_ptr = cinfo.ac_huff_tbl_ptrs[n]; /* huff_ptr is JHUFF_TBL* */
+ for (i = 1; i <= 16; i++) {
+ /* counts[i] is number of Huffman codes of length i bits, i=1..16 */
+ huff_ptr->bits[i] = counts[i];
+ }
+ for (i = 0; i < 256; i++) {
+ /* symbols[] is the list of Huffman symbols, in code-length order */
+ huff_ptr->huffval[i] = symbols[i];
+ }
+
+(Note that trying to set cinfo.quant_tbl_ptrs[n] to point directly at a
+constant JQUANT_TBL object is not safe. If the incoming file happened to
+contain a quantization table definition, your master table would get
+overwritten! Instead allocate a working table copy and copy the master table
+into it, as illustrated above. Ditto for Huffman tables, of course.)
+
+You might want to read the tables from a tables-only file, rather than
+hard-wiring them into your application. The jpeg_read_header() call is
+sufficient to read a tables-only file. You must pass a second parameter of
+FALSE to indicate that you do not require an image to be present. Thus, the
+typical scenario is
+
+ create JPEG decompression object
+ set source to tables-only file
+ jpeg_read_header(&cinfo, FALSE);
+ set source to abbreviated image file
+ jpeg_read_header(&cinfo, TRUE);
+ set decompression parameters
+ jpeg_start_decompress(&cinfo);
+ read data...
+ jpeg_finish_decompress(&cinfo);
+
+In some cases, you may want to read a file without knowing whether it tqcontains
+an image or just tables. In that case, pass FALSE and check the return value
+from jpeg_read_header(): it will be JPEG_HEADER_OK if an image was found,
+JPEG_HEADER_TABLES_ONLY if only tables were found. (A third return value,
+JPEG_SUSPENDED, is possible when using a suspending data source manager.)
+Note that jpeg_read_header() will not complain if you read an abbreviated
+image for which you haven't loaded the missing tables; the missing-table check
+occurs later, in jpeg_start_decompress().
+
+
+It is possible to read a series of images from a single source file by
+repeating the jpeg_read_header() ... jpeg_finish_decompress() sequence,
+without releasing/recreating the JPEG object or the data source module.
+(If you did reinitialize, any partial bufferload left in the data source
+buffer at the end of one image would be discarded, causing you to lose the
+start of the next image.) When you use this method, stored tables are
+automatically carried forward, so some of the images can be abbreviated images
+that depend on tables from earlier images.
+
+If you intend to write a series of images into a single destination file,
+you might want to make a specialized data destination module that doesn't
+flush the output buffer at term_destination() time. This would speed things
+up by some trifling amount. Of course, you'd need to remember to flush the
+buffer after the last image. You can make the later images be abbreviated
+ones by passing FALSE to jpeg_start_compress().
+
+
+Special markers
+---------------
+
+Some applications may need to insert or extract special data in the JPEG
+datastream. The JPEG standard provides marker types "COM" (comment) and
+"APP0" through "APP15" (application) to hold application-specific data.
+Unfortunately, the use of these markers is not specified by the standard.
+COM markers are fairly widely used to hold user-supplied text. The JFIF file
+format spec uses APP0 markers with specified initial strings to hold certain
+data. Adobe applications use APP14 markers beginning with the string "Adobe"
+for miscellaneous data. Other APPn markers are rarely seen, but might
+contain almost anything.
+
+If you wish to store user-supplied text, we recommend you use COM markers
+and place readable 7-bit ASCII text in them. Newline conventions are not
+standardized --- expect to tqfind LF (Unix style), CR/LF (DOS style), or CR
+(Mac style). A robust COM reader should be able to cope with random binary
+garbage, including nulls, since some applications generate COM markers
+containing non-ASCII junk. (But yours should not be one of them.)
+
+For program-supplied data, use an APPn marker, and be sure to begin it with an
+identifying string so that you can tell whether the marker is actually yours.
+It's probably best to avoid using APP0 or APP14 for any private markers.
+(NOTE: the upcoming SPIFF standard will use APP8 markers; we recommend you
+not use APP8 markers for any private purposes, either.)
+
+Keep in mind that at most 65533 bytes can be put into one marker, but you
+can have as many markers as you like.
+
+By default, the IJG compression library will write a JFIF APP0 marker if the
+selected JPEG colorspace is grayscale or YCbCr, or an Adobe APP14 marker if
+the selected colorspace is RGB, CMYK, or YCCK. You can disable this, but
+we don't recommend it. The decompression library will recognize JFIF and
+Adobe markers and will set the JPEG colorspace properly when one is found.
+
+
+You can write special markers immediately following the datastream header by
+calling jpeg_write_marker() after jpeg_start_compress() and before the first
+call to jpeg_write_scanlines(). When you do this, the markers appear after
+the SOI and the JFIF APP0 and Adobe APP14 markers (if written), but before
+all else. Specify the marker type parameter as "JPEG_COM" for COM or
+"JPEG_APP0 + n" for APPn. (Actually, jpeg_write_marker will let you write
+any marker type, but we don't recommend writing any other kinds of marker.)
+For example, to write a user comment string pointed to by comment_text:
+ jpeg_write_marker(cinfo, JPEG_COM, comment_text, strlen(comment_text));
+
+If it's not convenient to store all the marker data in memory at once,
+you can instead call jpeg_write_m_header() followed by multiple calls to
+jpeg_write_m_byte(). If you do it this way, it's your responsibility to
+call jpeg_write_m_byte() exactly the number of times given in the length
+parameter to jpeg_write_m_header(). (This method lets you empty the
+output buffer partway through a marker, which might be important when
+using a suspending data destination module. In any case, if you are using
+a suspending destination, you should flush its buffer after inserting
+any special markers. See "I/O suspension".)
+
+Or, if you prefer to synthesize the marker byte sequence yourself,
+you can just cram it straight into the data destination module.
+
+If you are writing JFIF 1.02 extension markers (thumbnail images), don't
+forget to set cinfo.JFIF_minor_version = 2 so that the encoder will write the
+correct JFIF version number in the JFIF header marker. The library's default
+is to write version 1.01, but that's wrong if you insert any 1.02 extension
+markers. (We could probably get away with just defaulting to 1.02, but there
+used to be broken decoders that would complain about unknown minor version
+numbers. To reduce compatibility risks it's safest not to write 1.02 unless
+you are actually using 1.02 extensions.)
+
+
+When reading, two methods of handling special markers are available:
+1. You can ask the library to save the contents of COM and/or APPn markers
+into memory, and then examine them at your leisure afterwards.
+2. You can supply your own routine to process COM and/or APPn markers
+on-the-fly as they are read.
+The first method is simpler to use, especially if you are using a suspending
+data source; writing a marker processor that copes with input suspension is
+not easy (consider what happens if the marker is longer than your available
+input buffer). However, the second method conserves memory since the marker
+data need not be kept around after it's been processed.
+
+For either method, you'd normally set up marker handling after creating a
+decompression object and before calling jpeg_read_header(), because the
+markers of interest will typically be near the head of the file and so will
+be scanned by jpeg_read_header. Once you've established a marker handling
+method, it will be used for the life of that decompression object
+(potentially many datastreams), unless you change it. Marker handling is
+determined separately for COM markers and for each APPn marker code.
+
+
+To save the contents of special markers in memory, call
+ jpeg_save_markers(cinfo, marker_code, length_limit)
+where marker_code is the marker type to save, JPEG_COM or JPEG_APP0+n.
+(To arrange to save all the special marker types, you need to call this
+routine 17 times, for COM and APP0-APP15.) If the incoming marker is longer
+than length_limit data bytes, only length_limit bytes will be saved; this
+parameter allows you to avoid chewing up memory when you only need to see the
+first few bytes of a potentially large marker. If you want to save all the
+data, set length_limit to 0xFFFF; that is enough since marker lengths are only
+16 bits. As a special case, setting length_limit to 0 prevents that marker
+type from being saved at all. (That is the default behavior, in fact.)
+
+After jpeg_read_header() completes, you can examine the special markers by
+following the cinfo->marker_list pointer chain. All the special markers in
+the file appear in this list, in order of their occurrence in the file (but
+omitting any markers of types you didn't ask for). Both the original data
+length and the saved data length are recorded for each list entry; the latter
+will not exceed length_limit for the particular marker type. Note that these
+lengths exclude the marker length word, whereas the stored representation
+within the JPEG file includes it. (Hence the maximum data length is really
+only 65533.)
+
+It is possible that additional special markers appear in the file beyond the
+SOS marker at which jpeg_read_header stops; if so, the marker list will be
+extended during reading of the rest of the file. This is not expected to be
+common, however. If you are short on memory you may want to reset the length
+limit to zero for all marker types after finishing jpeg_read_header, to
+ensure that the max_memory_to_use setting cannot be exceeded due to addition
+of later markers.
+
+The marker list remains stored until you call jpeg_finish_decompress or
+jpeg_abort, at which point the memory is freed and the list is set to empty.
+(jpeg_destroy also releases the storage, of course.)
+
+Note that the library is internally interested in APP0 and APP14 markers;
+if you try to set a small nonzero length limit on these types, the library
+will silently force the length up to the minimum it wants. (But you can set
+a zero length limit to prevent them from being saved at all.) Also, in a
+16-bit environment, the maximum length limit may be constrained to less than
+65533 by malloc() limitations. It is therefore best not to assume that the
+effective length limit is exactly what you set it to be.
+
+
+If you want to supply your own marker-reading routine, you do it by calling
+jpeg_set_marker_processor(). A marker processor routine must have the
+signature
+ boolean jpeg_marker_parser_method (j_decompress_ptr cinfo)
+Although the marker code is not explicitly passed, the routine can tqfind it
+in cinfo->unread_marker. At the time of call, the marker proper has been
+read from the data source module. The processor routine is responsible for
+reading the marker length word and the remaining parameter bytes, if any.
+Return TRUE to indicate success. (FALSE should be returned only if you are
+using a suspending data source and it tells you to suspend. See the standard
+marker processors in jdmarker.c for appropriate coding methods if you need to
+use a suspending data source.)
+
+If you override the default APP0 or APP14 processors, it is up to you to
+recognize JFIF and Adobe markers if you want colorspace recognition to occur
+properly. We recommend copying and extending the default processors if you
+want to do that. (A better idea is to save these marker types for later
+examination by calling jpeg_save_markers(); that method doesn't interfere
+with the library's own processing of these markers.)
+
+jpeg_set_marker_processor() and jpeg_save_markers() are mutually exclusive
+--- if you call one it overrides any previous call to the other, for the
+particular marker type specified.
+
+A simple example of an external COM processor can be found in djpeg.c.
+Also, see jpegtran.c for an example of using jpeg_save_markers.
+
+
+Raw (downsampled) image data
+----------------------------
+
+Some applications need to supply already-downsampled image data to the JPEG
+compressor, or to receive raw downsampled data from the decompressor. The
+library supports this requirement by allowing the application to write or
+read raw data, bypassing the normal preprocessing or postprocessing steps.
+The interface is different from the standard one and is somewhat harder to
+use. If your interest is merely in bypassing color conversion, we recommend
+that you use the standard interface and simply set jpeg_color_space =
+in_color_space (or jpeg_color_space = out_color_space for decompression).
+The mechanism described in this section is necessary only to supply or
+receive downsampled image data, in which not all components have the same
+dimensions.
+
+
+To compress raw data, you must supply the data in the colorspace to be used
+in the JPEG file (please read the earlier section on Special color spaces)
+and downsampled to the sampling factors specified in the JPEG parameters.
+You must supply the data in the format used internally by the JPEG library,
+namely a JSAMPIMAGE array. This is an array of pointers to two-dimensional
+arrays, each of type JSAMPARRAY. Each 2-D array holds the values for one
+color component. This structure is necessary since the components are of
+different sizes. If the image dimensions are not a multiple of the MCU size,
+you must also pad the data correctly (usually, this is done by replicating
+the last column and/or row). The data must be padded to a multiple of a DCT
+block in each component: that is, each downsampled row must contain a
+multiple of 8 valid samples, and there must be a multiple of 8 sample rows
+for each component. (For applications such as conversion of digital TV
+images, the standard image size is usually a multiple of the DCT block size,
+so that no padding need actually be done.)
+
+The procedure for compression of raw data is basically the same as normal
+compression, except that you call jpeg_write_raw_data() in place of
+jpeg_write_scanlines(). Before calling jpeg_start_compress(), you must do
+the following:
+ * Set cinfo->raw_data_in to TRUE. (It is set FALSE by jpeg_set_defaults().)
+ This notifies the library that you will be supplying raw data.
+ * Ensure jpeg_color_space is correct --- an explicit jpeg_set_colorspace()
+ call is a good idea. Note that since color conversion is bypassed,
+ in_color_space is ignored, except that jpeg_set_defaults() uses it to
+ choose the default jpeg_color_space setting.
+ * Ensure the sampling factors, cinfo->comp_info[i].h_samp_factor and
+ cinfo->comp_info[i].v_samp_factor, are correct. Since these indicate the
+ dimensions of the data you are supplying, it's wise to set them
+ explicitly, rather than assuming the library's defaults are what you want.
+
+To pass raw data to the library, call jpeg_write_raw_data() in place of
+jpeg_write_scanlines(). The two routines work similarly except that
+jpeg_write_raw_data takes a JSAMPIMAGE data array rather than JSAMPARRAY.
+The scanlines count passed to and returned from jpeg_write_raw_data is
+measured in terms of the component with the largest v_samp_factor.
+
+jpeg_write_raw_data() processes one MCU row per call, which is to say
+v_samp_factor*DCTSIZE sample rows of each component. The passed num_lines
+value must be at least max_v_samp_factor*DCTSIZE, and the return value will
+be exactly that amount (or possibly some multiple of that amount, in future
+library versions). This is true even on the last call at the bottom of the
+image; don't forget to pad your data as necessary.
+
+The required dimensions of the supplied data can be computed for each
+component as
+ cinfo->comp_info[i].width_in_blocks*DCTSIZE samples per row
+ cinfo->comp_info[i].height_in_blocks*DCTSIZE rows in image
+after jpeg_start_compress() has initialized those fields. If the valid data
+is smaller than this, it must be padded appropriately. For some sampling
+factors and image sizes, additional dummy DCT blocks are inserted to make
+the image a multiple of the MCU dimensions. The library creates such dummy
+blocks itself; it does not read them from your supplied data. Therefore you
+need never pad by more than DCTSIZE samples. An example may help here.
+Assume 2h2v downsampling of YCbCr data, that is
+ cinfo->comp_info[0].h_samp_factor = 2 for Y
+ cinfo->comp_info[0].v_samp_factor = 2
+ cinfo->comp_info[1].h_samp_factor = 1 for Cb
+ cinfo->comp_info[1].v_samp_factor = 1
+ cinfo->comp_info[2].h_samp_factor = 1 for Cr
+ cinfo->comp_info[2].v_samp_factor = 1
+and suppose that the nominal image dimensions (cinfo->image_width and
+cinfo->image_height) are 101x101 pixels. Then jpeg_start_compress() will
+compute downsampled_width = 101 and width_in_blocks = 13 for Y,
+downsampled_width = 51 and width_in_blocks = 7 for Cb and Cr (and the same
+for the height fields). You must pad the Y data to at least 13*8 = 104
+columns and rows, the Cb/Cr data to at least 7*8 = 56 columns and rows. The
+MCU height is max_v_samp_factor = 2 DCT rows so you must pass at least 16
+scanlines on each call to jpeg_write_raw_data(), which is to say 16 actual
+sample rows of Y and 8 each of Cb and Cr. A total of 7 MCU rows are needed,
+so you must pass a total of 7*16 = 112 "scanlines". The last DCT block row
+of Y data is dummy, so it doesn't matter what you pass for it in the data
+arrays, but the scanlines count must total up to 112 so that all of the Cb
+and Cr data gets passed.
+
+Output suspension is supported with raw-data compression: if the data
+destination module suspends, jpeg_write_raw_data() will return 0.
+In this case the same data rows must be passed again on the next call.
+
+
+Decompression with raw data output implies bypassing all postprocessing:
+you cannot ask for rescaling or color quantization, for instance. More
+seriously, you must deal with the color space and sampling factors present in
+the incoming file. If your application only handles, say, 2h1v YCbCr data,
+you must check for and fail on other color spaces or other sampling factors.
+The library will not convert to a different color space for you.
+
+To obtain raw data output, set cinfo->raw_data_out = TRUE before
+jpeg_start_decompress() (it is set FALSE by jpeg_read_header()). Be sure to
+verify that the color space and sampling factors are ones you can handle.
+Then call jpeg_read_raw_data() in place of jpeg_read_scanlines(). The
+decompression process is otherwise the same as usual.
+
+jpeg_read_raw_data() returns one MCU row per call, and thus you must pass a
+buffer of at least max_v_samp_factor*DCTSIZE scanlines (scanline counting is
+the same as for raw-data compression). The buffer you pass must be large
+enough to hold the actual data plus padding to DCT-block boundaries. As with
+compression, any entirely dummy DCT blocks are not processed so you need not
+allocate space for them, but the total scanline count includes them. The
+above example of computing buffer dimensions for raw-data compression is
+equally valid for decompression.
+
+Input suspension is supported with raw-data decompression: if the data source
+module suspends, jpeg_read_raw_data() will return 0. You can also use
+buffered-image mode to read raw data in multiple passes.
+
+
+Really raw data: DCT coefficients
+---------------------------------
+
+It is possible to read or write the contents of a JPEG file as raw DCT
+coefficients. This facility is mainly intended for use in lossless
+transcoding between different JPEG file formats. Other possible applications
+include lossless cropping of a JPEG image, lossless reassembly of a
+multi-strip or multi-tile TIFF/JPEG file into a single JPEG datastream, etc.
+
+To read the contents of a JPEG file as DCT coefficients, open the file and do
+jpeg_read_header() as usual. But instead of calling jpeg_start_decompress()
+and jpeg_read_scanlines(), call jpeg_read_coefficients(). This will read the
+entire image into a set of virtual coefficient-block arrays, one array per
+component. The return value is a pointer to an array of virtual-array
+descriptors. Each virtual array can be accessed directly using the JPEG
+memory manager's access_virt_barray method (see Memory management, below,
+and also read structure.doc's discussion of virtual array handling). Or,
+for simple transcoding to a different JPEG file format, the array list can
+just be handed directly to jpeg_write_coefficients().
+
+Each block in the block arrays tqcontains quantized coefficient values in
+normal array order (not JPEG zigzag order). The block arrays contain only
+DCT blocks containing real data; any entirely-dummy blocks added to fill out
+interleaved MCUs at the right or bottom edges of the image are discarded
+during reading and are not stored in the block arrays. (The size of each
+block array can be determined from the width_in_blocks and height_in_blocks
+fields of the component's comp_info entry.) This is also the data format
+expected by jpeg_write_coefficients().
+
+When you are done using the virtual arrays, call jpeg_finish_decompress()
+to release the array storage and return the decompression object to an idle
+state; or just call jpeg_destroy() if you don't need to reuse the object.
+
+If you use a suspending data source, jpeg_read_coefficients() will return
+NULL if it is forced to suspend; a non-NULL return value indicates successful
+completion. You need not test for a NULL return value when using a
+non-suspending data source.
+
+It is also possible to call jpeg_read_coefficients() to obtain access to the
+decoder's coefficient arrays during a normal decode cycle in buffered-image
+mode. This frammish might be useful for progressively displaying an incoming
+image and then re-encoding it without loss. To do this, decode in buffered-
+image mode as discussed previously, then call jpeg_read_coefficients() after
+the last jpeg_finish_output() call. The arrays will be available for your use
+until you call jpeg_finish_decompress().
+
+
+To write the contents of a JPEG file as DCT coefficients, you must provide
+the DCT coefficients stored in virtual block arrays. You can either pass
+block arrays read from an input JPEG file by jpeg_read_coefficients(), or
+allocate virtual arrays from the JPEG compression object and fill them
+yourself. In either case, jpeg_write_coefficients() is substituted for
+jpeg_start_compress() and jpeg_write_scanlines(). Thus the sequence is
+ * Create compression object
+ * Set all compression parameters as necessary
+ * Request virtual arrays if needed
+ * jpeg_write_coefficients()
+ * jpeg_finish_compress()
+ * Destroy or re-use compression object
+jpeg_write_coefficients() is passed a pointer to an array of virtual block
+array descriptors; the number of arrays is equal to cinfo.num_components.
+
+The virtual arrays need only have been requested, not realized, before
+jpeg_write_coefficients() is called. A side-effect of
+jpeg_write_coefficients() is to realize any virtual arrays that have been
+requested from the compression object's memory manager. Thus, when obtaining
+the virtual arrays from the compression object, you should fill the arrays
+after calling jpeg_write_coefficients(). The data is actually written out
+when you call jpeg_finish_compress(); jpeg_write_coefficients() only writes
+the file header.
+
+When writing raw DCT coefficients, it is crucial that the JPEG quantization
+tables and sampling factors match the way the data was encoded, or the
+resulting file will be invalid. For transcoding from an existing JPEG file,
+we recommend using jpeg_copy_critical_parameters(). This routine initializes
+all the compression parameters to default values (like jpeg_set_defaults()),
+then copies the critical information from a source decompression object.
+The decompression object should have just been used to read the entire
+JPEG input file --- that is, it should be awaiting jpeg_finish_decompress().
+
+jpeg_write_coefficients() marks all tables stored in the compression object
+as needing to be written to the output file (thus, it acts like
+jpeg_start_compress(cinfo, TRUE)). This is for safety's sake, to avoid
+emitting abbreviated JPEG files by accident. If you really want to emit an
+abbreviated JPEG file, call jpeg_suppress_tables(), or set the tables'
+individual sent_table flags, between calling jpeg_write_coefficients() and
+jpeg_finish_compress().
+
+
+Progress monitoring
+-------------------
+
+Some applications may need to regain control from the JPEG library every so
+often. The typical use of this feature is to produce a percent-done bar or
+other progress display. (For a simple example, see cjpeg.c or djpeg.c.)
+Although you do get control back frequently during the data-transferring pass
+(the jpeg_read_scanlines or jpeg_write_scanlines loop), any additional passes
+will occur inside jpeg_finish_compress or jpeg_start_decompress; those
+routines may take a long time to execute, and you don't get control back
+until they are done.
+
+You can define a progress-monitor routine which will be called periodically
+by the library. No guarantees are made about how often this call will occur,
+so we don't recommend you use it for mouse tracking or anything like that.
+At present, a call will occur once per MCU row, scanline, or sample row
+group, whichever unit is convenient for the current processing mode; so the
+wider the image, the longer the time between calls. During the data
+transferring pass, only one call occurs per call of jpeg_read_scanlines or
+jpeg_write_scanlines, so don't pass a large number of scanlines at once if
+you want fine resolution in the progress count. (If you really need to use
+the callback mechanism for time-critical tasks like mouse tracking, you could
+insert additional calls inside some of the library's inner loops.)
+
+To establish a progress-monitor callback, create a struct jpeg_progress_mgr,
+fill in its progress_monitor field with a pointer to your callback routine,
+and set cinfo->progress to point to the struct. The callback will be called
+whenever cinfo->progress is non-NULL. (This pointer is set to NULL by
+jpeg_create_compress or jpeg_create_decompress; the library will not change
+it thereafter. So if you allocate dynamic storage for the progress struct,
+make sure it will live as long as the JPEG object does. Allocating from the
+JPEG memory manager with lifetime JPOOL_PERMANENT will work nicely.) You
+can use the same callback routine for both compression and decompression.
+
+The jpeg_progress_mgr struct tqcontains four fields which are set by the library:
+ long pass_counter; /* work units completed in this pass */
+ long pass_limit; /* total number of work units in this pass */
+ int completed_passes; /* passes completed so far */
+ int total_passes; /* total number of passes expected */
+During any one pass, pass_counter increases from 0 up to (not including)
+pass_limit; the step size is usually but not necessarily 1. The pass_limit
+value may change from one pass to another. The expected total number of
+passes is in total_passes, and the number of passes already completed is in
+completed_passes. Thus the fraction of work completed may be estimated as
+ completed_passes + (pass_counter/pass_limit)
+ --------------------------------------------
+ total_passes
+ignoring the fact that the passes may not be equal amounts of work.
+
+When decompressing, pass_limit can even change within a pass, because it
+depends on the number of scans in the JPEG file, which isn't always known in
+advance. The computed fraction-of-work-done may jump suddenly (if the library
+discovers it has overestimated the number of scans) or even decrease (in the
+opposite case). It is not wise to put great faith in the work estimate.
+
+When using the decompressor's buffered-image mode, the progress monitor work
+estimate is likely to be completely unhelpful, because the library has no way
+to know how many output passes will be demanded of it. Currently, the library
+sets total_passes based on the assumption that there will be one more output
+pass if the input file end hasn't yet been read (jpeg_input_complete() isn't
+TRUE), but no more output passes if the file end has been reached when the
+output pass is started. This means that total_passes will rise as additional
+output passes are requested. If you have a way of determining the input file
+size, estimating progress based on the fraction of the file that's been read
+will probably be more useful than using the library's value.
+
+
+Memory management
+-----------------
+
+This section covers some key facts about the JPEG library's built-in memory
+manager. For more info, please read structure.doc's section about the memory
+manager, and consult the source code if necessary.
+
+All memory and temporary file allocation within the library is done via the
+memory manager. If necessary, you can tqreplace the "back end" of the memory
+manager to control allocation yourself (for example, if you don't want the
+library to use malloc() and free() for some reason).
+
+Some data is allocated "permanently" and will not be freed until the JPEG
+object is destroyed. Most data is allocated "per image" and is freed by
+jpeg_finish_compress, jpeg_finish_decompress, or jpeg_abort. You can call the
+memory manager yourself to allocate structures that will automatically be
+freed at these times. Typical code for this is
+ ptr = (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, size);
+Use JPOOL_PERMANENT to get storage that lasts as long as the JPEG object.
+Use alloc_large instead of alloc_small for anything bigger than a few Kbytes.
+There are also alloc_sarray and alloc_barray routines that automatically
+build 2-D sample or block arrays.
+
+The library's minimum space requirements to process an image depend on the
+image's width, but not on its height, because the library ordinarily works
+with "strip" buffers that are as wide as the image but just a few rows high.
+Some operating modes (eg, two-pass color quantization) require full-image
+buffers. Such buffers are treated as "virtual arrays": only the current strip
+need be in memory, and the rest can be swapped out to a temporary file.
+
+If you use the simplest memory manager back end (jmemnobs.c), then no
+temporary files are used; virtual arrays are simply malloc()'d. Images bigger
+than memory can be processed only if your system supports virtual memory.
+The other memory manager back ends support temporary files of various flavors
+and thus work in machines without virtual memory. They may also be useful on
+Unix machines if you need to process images that exceed available swap space.
+
+When using temporary files, the library will make the in-memory buffers for
+its virtual arrays just big enough to stay within a "maximum memory" setting.
+Your application can set this limit by setting cinfo->mem->max_memory_to_use
+after creating the JPEG object. (Of course, there is still a minimum size for
+the buffers, so the max-memory setting is effective only if it is bigger than
+the minimum space needed.) If you allocate any large structures yourself, you
+must allocate them before jpeg_start_compress() or jpeg_start_decompress() in
+order to have them counted against the max memory limit. Also keep in mind
+that space allocated with alloc_small() is ignored, on the assumption that
+it's too small to be worth worrying about; so a reasonable safety margin
+should be left when setting max_memory_to_use.
+
+If you use the jmemname.c or jmemdos.c memory manager back end, it is
+important to clean up the JPEG object properly to ensure that the temporary
+files get deleted. (This is especially crucial with jmemdos.c, where the
+"temporary files" may be extended-memory segments; if they are not freed,
+DOS will require a reboot to recover the memory.) Thus, with these memory
+managers, it's a good idea to provide a signal handler that will trap any
+early exit from your program. The handler should call either jpeg_abort()
+or jpeg_destroy() for any active JPEG objects. A handler is not needed with
+jmemnobs.c, and shouldn't be necessary with jmemansi.c or jmemmac.c either,
+since the C library is supposed to take care of deleting files made with
+tmpfile().
+
+
+Memory usage
+------------
+
+Working memory requirements while performing compression or decompression
+depend on image dimensions, image characteristics (such as colorspace and
+JPEG process), and operating mode (application-selected options).
+
+As of v6b, the decompressor requires:
+ 1. About 24K in more-or-less-fixed-size data. This varies a bit depending
+ on operating mode and image characteristics (particularly color vs.
+ grayscale), but it doesn't depend on image dimensions.
+ 2. Strip buffers (of size proportional to the image width) for IDCT and
+ upsampling results. The worst case for commonly used sampling factors
+ is about 34 bytes * width in pixels for a color image. A grayscale image
+ only needs about 8 bytes per pixel column.
+ 3. A full-image DCT coefficient buffer is needed to decode a multi-scan JPEG
+ file (including progressive JPEGs), or whenever you select buffered-image
+ mode. This takes 2 bytes/coefficient. At typical 2x2 sampling, that's
+ 3 bytes per pixel for a color image. Worst case (1x1 sampling) requires
+ 6 bytes/pixel. For grayscale, figure 2 bytes/pixel.
+ 4. To perform 2-pass color quantization, the decompressor also needs a
+ 128K color lookup table and a full-image pixel buffer (3 bytes/pixel).
+This does not count any memory allocated by the application, such as a
+buffer to hold the final output image.
+
+The above figures are valid for 8-bit JPEG data precision and a machine with
+32-bit ints. For 12-bit JPEG data, double the size of the strip buffers and
+quantization pixel buffer. The "fixed-size" data will be somewhat smaller
+with 16-bit ints, larger with 64-bit ints. Also, CMYK or other unusual
+color spaces will require different amounts of space.
+
+The full-image coefficient and pixel buffers, if needed at all, do not
+have to be fully RAM resident; you can have the library use temporary
+files instead when the total memory usage would exceed a limit you set.
+(But if your OS supports virtual memory, it's probably better to just use
+jmemnobs and let the OS do the swapping.)
+
+The compressor's memory requirements are similar, except that it has no need
+for color quantization. Also, it needs a full-image DCT coefficient buffer
+if Huffman-table optimization is asked for, even if progressive mode is not
+requested.
+
+If you need more detailed information about memory usage in a particular
+situation, you can enable the MEM_STATS code in jmemmgr.c.
+
+
+Library compile-time options
+----------------------------
+
+A number of compile-time options are available by modifying jmorecfg.h.
+
+The JPEG standard provides for both the baseline 8-bit DCT process and
+a 12-bit DCT process. The IJG code supports 12-bit lossy JPEG if you define
+BITS_IN_JSAMPLE as 12 rather than 8. Note that this causes JSAMPLE to be
+larger than a char, so it affects the surrounding application's image data.
+The sample applications cjpeg and djpeg can support 12-bit mode only for PPM
+and GIF file formats; you must disable the other file formats to compile a
+12-bit cjpeg or djpeg. (install.doc has more information about that.)
+At present, a 12-bit library can handle *only* 12-bit images, not both
+precisions. (If you need to include both 8- and 12-bit libraries in a single
+application, you could probably do it by defining NEED_SHORT_EXTERNAL_NAMES
+for just one of the copies. You'd have to access the 8-bit and 12-bit copies
+from separate application source files. This is untested ... if you try it,
+we'd like to hear whether it works!)
+
+Note that a 12-bit library always compresses in Huffman optimization mode,
+in order to generate valid Huffman tables. This is necessary because our
+default Huffman tables only cover 8-bit data. If you need to output 12-bit
+files in one pass, you'll have to supply suitable default Huffman tables.
+You may also want to supply your own DCT quantization tables; the existing
+quality-scaling code has been developed for 8-bit use, and probably doesn't
+generate especially good tables for 12-bit.
+
+The maximum number of components (color channels) in the image is determined
+by MAX_COMPONENTS. The JPEG standard allows up to 255 components, but we
+expect that few applications will need more than four or so.
+
+On machines with unusual data type sizes, you may be able to improve
+performance or reduce memory space by tweaking the various typedefs in
+jmorecfg.h. In particular, on some RISC CPUs, access to arrays of "short"s
+is quite slow; consider trading memory for speed by making JCOEF, INT16, and
+UINT16 be "int" or "unsigned int". UINT8 is also a candidate to become int.
+You probably don't want to make JSAMPLE be int unless you have lots of memory
+to burn.
+
+You can reduce the size of the library by compiling out various optional
+functions. To do this, undefine xxx_SUPPORTED symbols as necessary.
+
+You can also save a few K by not having text error messages in the library;
+the standard error message table occupies about 5Kb. This is particularly
+reasonable for embedded applications where there's no good way to display
+a message anyway. To do this, remove the creation of the message table
+(jpeg_std_message_table[]) from jerror.c, and alter format_message to do
+something reasonable without it. You could output the numeric value of the
+message code number, for example. If you do this, you can also save a couple
+more K by modifying the TRACEMSn() macros in jerror.h to expand to nothing;
+you don't need trace capability anyway, right?
+
+
+Portability considerations
+--------------------------
+
+The JPEG library has been written to be extremely portable; the sample
+applications cjpeg and djpeg are slightly less so. This section summarizes
+the design goals in this area. (If you encounter any bugs that cause the
+library to be less portable than is claimed here, we'd appreciate hearing
+about them.)
+
+The code works fine on ANSI C, C++, and pre-ANSI C compilers, using any of
+the popular system include file setups, and some not-so-popular ones too.
+See install.doc for configuration procedures.
+
+The code is not dependent on the exact sizes of the C data types. As
+distributed, we make the assumptions that
+ char is at least 8 bits wide
+ short is at least 16 bits wide
+ int is at least 16 bits wide
+ long is at least 32 bits wide
+(These are the minimum requirements of the ANSI C standard.) Wider types will
+work fine, although memory may be used inefficiently if char is much larger
+than 8 bits or short is much bigger than 16 bits. The code should work
+equally well with 16- or 32-bit ints.
+
+In a system where these assumptions are not met, you may be able to make the
+code work by modifying the typedefs in jmorecfg.h. However, you will probably
+have difficulty if int is less than 16 bits wide, since references to plain
+int abound in the code.
+
+char can be either signed or unsigned, although the code runs faster if an
+unsigned char type is available. If char is wider than 8 bits, you will need
+to redefine JOCTET and/or provide custom data source/destination managers so
+that JOCTET represents exactly 8 bits of data on external storage.
+
+The JPEG library proper does not assume ASCII representation of characters.
+But some of the image file I/O modules in cjpeg/djpeg do have ASCII
+dependencies in file-header manipulation; so does cjpeg's select_file_type()
+routine.
+
+The JPEG library does not rely heavily on the C library. In particular, C
+stdio is used only by the data source/destination modules and the error
+handler, all of which are application-tqreplaceable. (cjpeg/djpeg are more
+heavily dependent on stdio.) malloc and free are called only from the memory
+manager "back end" module, so you can use a different memory allocator by
+replacing that one file.
+
+The code generally assumes that C names must be unique in the first 15
+characters. However, global function names can be made unique in the
+first 6 characters by defining NEED_SHORT_EXTERNAL_NAMES.
+
+More info about porting the code may be gleaned by reading jconfig.doc,
+jmorecfg.h, and jinclude.h.
+
+
+Notes for MS-DOS implementors
+-----------------------------
+
+The IJG code is designed to work efficiently in 80x86 "small" or "medium"
+memory models (i.e., data pointers are 16 bits unless explicitly declared
+"far"; code pointers can be either size). You may be able to use small
+model to compile cjpeg or djpeg by itself, but you will probably have to use
+medium model for any larger application. This won't make much difference in
+performance. You *will* take a noticeable performance hit if you use a
+large-data memory model (perhaps 10%-25%), and you should avoid "huge" model
+if at all possible.
+
+The JPEG library typically needs 2Kb-3Kb of stack space. It will also
+malloc about 20K-30K of near heap space while executing (and lots of far
+heap, but that doesn't count in this calculation). This figure will vary
+depending on selected operating mode, and to a lesser extent on image size.
+There is also about 5Kb-6Kb of constant data which will be allocated in the
+near data segment (about 4Kb of this is the error message table).
+Thus you have perhaps 20K available for other modules' static data and near
+heap space before you need to go to a larger memory model. The C library's
+static data will account for several K of this, but that still leaves a good
+deal for your needs. (If you are tight on space, you could reduce the sizes
+of the I/O buffers allocated by jdatasrc.c and jdatadst.c, say from 4K to
+1K. Another possibility is to move the error message table to far memory;
+this should be doable with only localized hacking on jerror.c.)
+
+About 2K of the near heap space is "permanent" memory that will not be
+released until you destroy the JPEG object. This is only an issue if you
+save a JPEG object between compression or decompression operations.
+
+Far data space may also be a tight resource when you are dealing with large
+images. The most memory-intensive case is decompression with two-pass color
+quantization, or single-pass quantization to an externally supplied color
+map. This requires a 128Kb color lookup table plus strip buffers amounting
+to about 40 bytes per column for typical sampling ratios (eg, about 25600
+bytes for a 640-pixel-wide image). You may not be able to process wide
+images if you have large data structures of your own.
+
+Of course, all of these concerns vanish if you use a 32-bit flat-memory-model
+compiler, such as DJGPP or Watcom C. We highly recommend flat model if you
+can use it; the JPEG library is significantly faster in flat model.
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.ansi b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.ansi
new file mode 100644
index 0000000..8291913
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.ansi
@@ -0,0 +1,214 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is suitable for Unix-like systems with ANSI-capable compilers.
+# If you have a non-ANSI compiler, makefile.unix is a better starting point.
+
+# Read installation instructions before saying "make" !!
+
+# The name of your C compiler:
+CC= cc
+
+# You may need to adjust these cc options:
+CFLAGS= -O
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via -D switches here.
+
+# Link-time cc options:
+LDFLAGS=
+
+# To link any special libraries, add the necessary -l commands here.
+LDLIBS=
+
+# Put here the object file name for the correct system-dependent memory
+# manager file. For Unix this is usually jmemnobs.o, but you may want
+# to use jmemansi.o or jmemname.o if you have limited swap space.
+SYSDEPMEM= jmemnobs.o
+
+# miscellaneous OS-dependent stuff
+# linker
+LN= $(CC)
+# file deletion command
+RM= rm -f
+# library (.a) file creation command
+AR= ar rc
+# second step in .a creation (use "touch" if not needed)
+AR2= ranlib
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \
+ jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \
+ jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \
+ jfdctint.o
+# decompression library object files
+DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdatasrc.o jdmaster.o \
+ jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \
+ jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \
+ jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o
+# These objectfiles are included in libjpeg.a
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \
+ cdjpeg.o
+DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
+ cdjpeg.o
+TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o
+
+
+all: libjpeg.a cjpeg djpeg jpegtran rdjpgcom wrjpgcom
+
+libjpeg.a: $(LIBOBJECTS)
+ $(RM) libjpeg.a
+ $(AR) libjpeg.a $(LIBOBJECTS)
+ $(AR2) libjpeg.a
+
+cjpeg: $(COBJECTS) libjpeg.a
+ $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.a $(LDLIBS)
+
+djpeg: $(DOBJECTS) libjpeg.a
+ $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.a $(LDLIBS)
+
+jpegtran: $(TROBJECTS) libjpeg.a
+ $(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.a $(LDLIBS)
+
+rdjpgcom: rdjpgcom.o
+ $(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.o $(LDLIBS)
+
+wrjpgcom: wrjpgcom.o
+ $(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.o $(LDLIBS)
+
+jconfig.h: jconfig.doc
+ echo You must prepare a system-dependent jconfig.h file.
+ echo Please read the installation directions in install.doc.
+ exit 1
+
+clean:
+ $(RM) *.o cjpeg djpeg jpegtran libjpeg.a rdjpgcom wrjpgcom
+ $(RM) core testout*
+
+test: cjpeg djpeg jpegtran
+ $(RM) testout*
+ ./djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+ ./djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+ ./cjpeg -dct int -outfile testout.jpg testimg.ppm
+ ./djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+ ./cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+ ./jpegtran -outfile testoutt.jpg testprog.jpg
+ cmp testimg.ppm testout.ppm
+ cmp testimg.bmp testout.bmp
+ cmp testimg.jpg testout.jpg
+ cmp testimg.ppm testoutp.ppm
+ cmp testimgp.jpg testoutp.jpg
+ cmp testorig.jpg testoutt.jpg
+
+
+jcapimin.o: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.o: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.o: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.o: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.o: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.o: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.o: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.o: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.o: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.o: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.o: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.o: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.o: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.o: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.o: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.o: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.o: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.o: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.o: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.o: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.o: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.o: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.o: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.o: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.o: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.o: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.o: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.o: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.o: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.o: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.o: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.o: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.o: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.o: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.o: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.o: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.bcc b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.bcc
new file mode 100644
index 0000000..a1cfcde
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.bcc
@@ -0,0 +1,285 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is suitable for Borland C on MS-DOS or OS/2.
+# It works with Borland C++ for DOS, revision 3.0 or later,
+# and has been tested with Borland C++ for OS/2.
+# Watch out for optimization bugs in the OS/2 compilers --- see notes below!
+# Thanks to Tom Wright and Ge' Weijers (original DOS) and
+# Ken Porter (OS/2) for this file.
+
+# Read installation instructions before saying "make" !!
+
+# Are we under DOS or OS/2?
+!if !$d(DOS) && !$d(OS2)
+!if $d(__OS2__)
+OS2=1
+!else
+DOS=1
+!endif
+!endif
+
+# The name of your C compiler:
+CC= bcc
+
+# You may need to adjust these cc options:
+!if $d(DOS)
+CFLAGS= -O2 -mm -w-par -w-stu -w-ccc -w-rch
+!else
+CFLAGS= -O1 -w-par -w-stu -w-ccc -w-rch
+!endif
+# -O2 enables full code optimization (for pre-3.0 Borland C++, use -O -G -Z).
+# -O2 is buggy in Borland OS/2 C++ revision 2.0, so use -O1 there for now.
+# If you have Borland OS/2 C++ revision 1.0, use -O or no optimization at all.
+# -mm selects medium memory model (near data, far code pointers; DOS only!)
+# -w-par suppresses warnings about unused function parameters
+# -w-stu suppresses warnings about incomplete structures
+# -w-ccc suppresses warnings about compile-time-constant conditions
+# -w-rch suppresses warnings about unreachable code
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via -D switches here.
+
+# Link-time cc options:
+!if $d(DOS)
+LDFLAGS= -mm
+# memory model option here must match CFLAGS!
+!else
+LDFLAGS=
+# -lai full-screen app
+# -lc case-significant link
+!endif
+
+# Put here the object file name for the correct system-dependent memory
+# manager file.
+# For DOS, we recommend jmemdos.c and jmemdosa.asm.
+# For OS/2, we recommend jmemnobs.c (flat memory!)
+# SYSDEPMEMLIB must list the same files with "+" signs for the librarian.
+!if $d(DOS)
+SYSDEPMEM= jmemdos.obj jmemdosa.obj
+SYSDEPMEMLIB= +jmemdos.obj +jmemdosa.obj
+!else
+SYSDEPMEM= jmemnobs.obj
+SYSDEPMEMLIB= +jmemnobs.obj
+!endif
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj \
+ jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj \
+ jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj \
+ jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj
+# decompression library object files
+DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj \
+ jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj \
+ jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj \
+ jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj \
+ jquant1.obj jquant2.obj jdmerge.obj
+# These objectfiles are included in libjpeg.lib
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj \
+ rdswitch.obj cdjpeg.obj
+DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \
+ rdcolmap.obj cdjpeg.obj
+TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj
+
+
+all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe
+
+libjpeg.lib: $(LIBOBJECTS)
+ - del libjpeg.lib
+ tlib libjpeg.lib /E /C @&&|
++jcapimin.obj +jcapistd.obj +jctrans.obj +jcparam.obj +jdatadst.obj &
++jcinit.obj +jcmaster.obj +jcmarker.obj +jcmainct.obj +jcprepct.obj &
++jccoefct.obj +jccolor.obj +jcsample.obj +jchuff.obj +jcphuff.obj &
++jcdctmgr.obj +jfdctfst.obj +jfdctflt.obj +jfdctint.obj +jdapimin.obj &
++jdapistd.obj +jdtrans.obj +jdatasrc.obj +jdmaster.obj +jdinput.obj &
++jdmarker.obj +jdhuff.obj +jdphuff.obj +jdmainct.obj +jdcoefct.obj &
++jdpostct.obj +jddctmgr.obj +jidctfst.obj +jidctflt.obj +jidctint.obj &
++jidctred.obj +jdsample.obj +jdcolor.obj +jquant1.obj +jquant2.obj &
++jdmerge.obj +jcomapi.obj +jutils.obj +jerror.obj +jmemmgr.obj &
+$(SYSDEPMEMLIB)
+|
+
+cjpeg.exe: $(COBJECTS) libjpeg.lib
+ $(CC) $(LDFLAGS) -ecjpeg.exe $(COBJECTS) libjpeg.lib
+
+djpeg.exe: $(DOBJECTS) libjpeg.lib
+ $(CC) $(LDFLAGS) -edjpeg.exe $(DOBJECTS) libjpeg.lib
+
+jpegtran.exe: $(TROBJECTS) libjpeg.lib
+ $(CC) $(LDFLAGS) -ejpegtran.exe $(TROBJECTS) libjpeg.lib
+
+rdjpgcom.exe: rdjpgcom.c
+!if $d(DOS)
+ $(CC) -ms -O rdjpgcom.c
+!else
+ $(CC) $(CFLAGS) rdjpgcom.c
+!endif
+
+# On DOS, wrjpgcom needs large model so it can malloc a 64K chunk
+wrjpgcom.exe: wrjpgcom.c
+!if $d(DOS)
+ $(CC) -ml -O wrjpgcom.c
+!else
+ $(CC) $(CFLAGS) wrjpgcom.c
+!endif
+
+# This "{}" syntax allows Borland Make to "batch" source files.
+# In this way, each run of the compiler can build many modules.
+.c.obj:
+ $(CC) $(CFLAGS) -c{ $<}
+
+jconfig.h: jconfig.doc
+ echo You must prepare a system-dependent jconfig.h file.
+ echo Please read the installation directions in install.doc.
+ exit 1
+
+clean:
+ - del *.obj
+ - del libjpeg.lib
+ - del cjpeg.exe
+ - del djpeg.exe
+ - del jpegtran.exe
+ - del rdjpgcom.exe
+ - del wrjpgcom.exe
+ - del testout*.*
+
+test: cjpeg.exe djpeg.exe jpegtran.exe
+ - del testout*.*
+ djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+ djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+ cjpeg -dct int -outfile testout.jpg testimg.ppm
+ djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+ cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+ jpegtran -outfile testoutt.jpg testprog.jpg
+!if $d(DOS)
+ fc /b testimg.ppm testout.ppm
+ fc /b testimg.bmp testout.bmp
+ fc /b testimg.jpg testout.jpg
+ fc /b testimg.ppm testoutp.ppm
+ fc /b testimgp.jpg testoutp.jpg
+ fc /b testorig.jpg testoutt.jpg
+!else
+ echo n > n.tmp
+ comp testimg.ppm testout.ppm < n.tmp
+ comp testimg.bmp testout.bmp < n.tmp
+ comp testimg.jpg testout.jpg < n.tmp
+ comp testimg.ppm testoutp.ppm < n.tmp
+ comp testimgp.jpg testoutp.jpg < n.tmp
+ comp testorig.jpg testoutt.jpg < n.tmp
+ del n.tmp
+!endif
+
+
+jcapimin.obj: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.obj: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.obj: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.obj: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.obj: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.obj: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.obj: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.obj: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.obj: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.obj: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.obj: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.obj: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.obj: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.obj: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.obj: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.obj: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.obj: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.obj: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.obj: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.obj: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.obj: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.obj: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.obj: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.obj: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.obj: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.obj: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.obj: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.obj: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.obj: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.obj: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.obj: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.obj: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.obj: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.obj: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.obj: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.obj: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.obj: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.obj: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.obj: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.obj: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.obj: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.obj: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.obj: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.obj: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.obj: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.obj: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.obj: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.obj: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.obj: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.obj: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.obj: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.obj: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+jmemdosa.obj: jmemdosa.asm
+ tasm /mx jmemdosa.asm
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.cfg b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.cfg
new file mode 100644
index 0000000..f25e42e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.cfg
@@ -0,0 +1,319 @@
+# Makefile for Independent JPEG Group's software
+
+# makefile.cfg is edited by configure to produce a custom Makefile.
+
+# Read installation instructions before saying "make" !!
+
+# For compiling with source and object files in different directories.
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+# Where to install the programs and man pages.
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = $(exec_prefix)/bin
+libdir = $(exec_prefix)/lib
+includedir = $(prefix)/include
+binprefix =
+manprefix =
+manext = 1
+mandir = $(prefix)/man/man$(manext)
+
+# The name of your C compiler:
+CC= @CC@
+
+# You may need to adjust these cc options:
+CFLAGS= @CFLAGS@ @CPPFLAGS@ @INCLUDEFLAGS@
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via -D switches here.
+# However, any special defines for ansi2knr.c may be included here:
+ANSI2KNRFLAGS= @ANSI2KNRFLAGS@
+
+# Link-time cc options:
+LDFLAGS= @LDFLAGS@
+
+# To link any special libraries, add the necessary -l commands here.
+LDLIBS= @LIBS@
+
+# If using GNU libtool, LIBTOOL references it; if not, LIBTOOL is empty.
+LIBTOOL = @LIBTOOL@
+# $(O) expands to "lo" if using libtool, plain "o" if not.
+# Similarly, $(A) expands to "la" or "a".
+O = @O@
+A = @A@
+
+# Library version ID; libtool uses this for the shared library version number.
+# Note: we suggest this match the macro of the same name in jpeglib.h.
+JPEG_LIB_VERSION = @JPEG_LIB_VERSION@
+
+# Put here the object file name for the correct system-dependent memory
+# manager file. For Unix this is usually jmemnobs.o, but you may want
+# to use jmemansi.o or jmemname.o if you have limited swap space.
+SYSDEPMEM= @MEMORYMGR@
+
+# miscellaneous OS-dependent stuff
+SHELL= /bin/sh
+# linker
+LN= @LN@
+# file deletion command
+RM= rm -f
+# directory creation command
+MKDIR= mkdir
+# library (.a) file creation command
+AR= ar rc
+# second step in .a creation (use "touch" if not needed)
+AR2= @RANLIB@
+# installation program
+INSTALL= @INSTALL@
+INSTALL_PROGRAM= @INSTALL_PROGRAM@
+INSTALL_LIB= @INSTALL_LIB@
+INSTALL_DATA= @INSTALL_DATA@
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.$(O) jutils.$(O) jerror.$(O) jmemmgr.$(O) $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.$(O) jcapistd.$(O) jctrans.$(O) jcparam.$(O) \
+ jdatadst.$(O) jcinit.$(O) jcmaster.$(O) jcmarker.$(O) jcmainct.$(O) \
+ jcprepct.$(O) jccoefct.$(O) jccolor.$(O) jcsample.$(O) jchuff.$(O) \
+ jcphuff.$(O) jcdctmgr.$(O) jfdctfst.$(O) jfdctflt.$(O) \
+ jfdctint.$(O)
+# decompression library object files
+DLIBOBJECTS= jdapimin.$(O) jdapistd.$(O) jdtrans.$(O) jdatasrc.$(O) \
+ jdmaster.$(O) jdinput.$(O) jdmarker.$(O) jdhuff.$(O) jdphuff.$(O) \
+ jdmainct.$(O) jdcoefct.$(O) jdpostct.$(O) jddctmgr.$(O) \
+ jidctfst.$(O) jidctflt.$(O) jidctint.$(O) jidctred.$(O) \
+ jdsample.$(O) jdcolor.$(O) jquant1.$(O) jquant2.$(O) jdmerge.$(O)
+# These objectfiles are included in libjpeg.a
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.$(O) rdppm.$(O) rdgif.$(O) rdtarga.$(O) rdrle.$(O) \
+ rdbmp.$(O) rdswitch.$(O) cdjpeg.$(O)
+DOBJECTS= djpeg.$(O) wrppm.$(O) wrgif.$(O) wrtarga.$(O) wrrle.$(O) \
+ wrbmp.$(O) rdcolmap.$(O) cdjpeg.$(O)
+TROBJECTS= jpegtran.$(O) rdswitch.$(O) cdjpeg.$(O) transupp.$(O)
+
+
+all: @A2K_DEPS@ libjpeg.$(A) cjpeg djpeg jpegtran rdjpgcom wrjpgcom
+
+# Special compilation rules to support ansi2knr and libtool.
+.SUFFIXES: .lo .la
+
+# How to compile with libtool.
+@COM_LT@.c.lo:
+@COM_LT@ $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c $(srcdir)/$*.c
+
+# How to use ansi2knr, when not using libtool.
+@COM_A2K@.c.o:
+@COM_A2K@ ./ansi2knr $(srcdir)/$*.c knr/$*.c
+@COM_A2K@ $(CC) $(CFLAGS) -c knr/$*.c
+@COM_A2K@ $(RM) knr/$*.c
+
+# How to use ansi2knr AND libtool.
+@COM_A2K@.c.lo:
+@COM_A2K@ ./ansi2knr $(srcdir)/$*.c knr/$*.c
+@COM_A2K@ $(LIBTOOL) --mode=compile $(CC) $(CFLAGS) -c knr/$*.c
+@COM_A2K@ $(RM) knr/$*.c
+
+ansi2knr: ansi2knr.c
+ $(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr $(srcdir)/ansi2knr.c
+ $(MKDIR) knr
+
+# the library:
+
+# without libtool:
+libjpeg.a: @A2K_DEPS@ $(LIBOBJECTS)
+ $(RM) libjpeg.a
+ $(AR) libjpeg.a $(LIBOBJECTS)
+ $(AR2) libjpeg.a
+
+# with libtool:
+libjpeg.la: @A2K_DEPS@ $(LIBOBJECTS)
+ $(LIBTOOL) --mode=link $(CC) -o libjpeg.la $(LIBOBJECTS) \
+ -rpath $(libdir) -version-info $(JPEG_LIB_VERSION)
+
+# sample programs:
+
+cjpeg: $(COBJECTS) libjpeg.$(A)
+ $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.$(A) $(LDLIBS)
+
+djpeg: $(DOBJECTS) libjpeg.$(A)
+ $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.$(A) $(LDLIBS)
+
+jpegtran: $(TROBJECTS) libjpeg.$(A)
+ $(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.$(A) $(LDLIBS)
+
+rdjpgcom: rdjpgcom.$(O)
+ $(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.$(O) $(LDLIBS)
+
+wrjpgcom: wrjpgcom.$(O)
+ $(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.$(O) $(LDLIBS)
+
+# Installation rules:
+
+install: cjpeg djpeg jpegtran rdjpgcom wrjpgcom @FORCE_INSTALL_LIB@
+ $(INSTALL_PROGRAM) cjpeg $(bindir)/$(binprefix)cjpeg
+ $(INSTALL_PROGRAM) djpeg $(bindir)/$(binprefix)djpeg
+ $(INSTALL_PROGRAM) jpegtran $(bindir)/$(binprefix)jpegtran
+ $(INSTALL_PROGRAM) rdjpgcom $(bindir)/$(binprefix)rdjpgcom
+ $(INSTALL_PROGRAM) wrjpgcom $(bindir)/$(binprefix)wrjpgcom
+ $(INSTALL_DATA) $(srcdir)/cjpeg.1 $(mandir)/$(manprefix)cjpeg.$(manext)
+ $(INSTALL_DATA) $(srcdir)/djpeg.1 $(mandir)/$(manprefix)djpeg.$(manext)
+ $(INSTALL_DATA) $(srcdir)/jpegtran.1 $(mandir)/$(manprefix)jpegtran.$(manext)
+ $(INSTALL_DATA) $(srcdir)/rdjpgcom.1 $(mandir)/$(manprefix)rdjpgcom.$(manext)
+ $(INSTALL_DATA) $(srcdir)/wrjpgcom.1 $(mandir)/$(manprefix)wrjpgcom.$(manext)
+
+install-lib: libjpeg.$(A) install-headers
+ $(INSTALL_LIB) libjpeg.$(A) $(libdir)/$(binprefix)libjpeg.$(A)
+
+install-headers: jconfig.h
+ $(INSTALL_DATA) jconfig.h $(includedir)/jconfig.h
+ $(INSTALL_DATA) $(srcdir)/jpeglib.h $(includedir)/jpeglib.h
+ $(INSTALL_DATA) $(srcdir)/jmorecfg.h $(includedir)/jmorecfg.h
+ $(INSTALL_DATA) $(srcdir)/jerror.h $(includedir)/jerror.h
+
+clean:
+ $(RM) *.o *.lo libjpeg.a libjpeg.la
+ $(RM) cjpeg djpeg jpegtran rdjpgcom wrjpgcom
+ $(RM) ansi2knr core testout* config.log config.status
+ $(RM) -r knr .libs _libs
+
+distclean: clean
+ $(RM) Makefile jconfig.h libtool config.cache
+
+test: cjpeg djpeg jpegtran
+ $(RM) testout*
+ ./djpeg -dct int -ppm -outfile testout.ppm $(srcdir)/testorig.jpg
+ ./djpeg -dct int -bmp -colors 256 -outfile testout.bmp $(srcdir)/testorig.jpg
+ ./cjpeg -dct int -outfile testout.jpg $(srcdir)/testimg.ppm
+ ./djpeg -dct int -ppm -outfile testoutp.ppm $(srcdir)/testprog.jpg
+ ./cjpeg -dct int -progressive -opt -outfile testoutp.jpg $(srcdir)/testimg.ppm
+ ./jpegtran -outfile testoutt.jpg $(srcdir)/testprog.jpg
+ cmp $(srcdir)/testimg.ppm testout.ppm
+ cmp $(srcdir)/testimg.bmp testout.bmp
+ cmp $(srcdir)/testimg.jpg testout.jpg
+ cmp $(srcdir)/testimg.ppm testoutp.ppm
+ cmp $(srcdir)/testimgp.jpg testoutp.jpg
+ cmp $(srcdir)/testorig.jpg testoutt.jpg
+
+check: test
+
+# Mistake catcher:
+
+jconfig.h: jconfig.doc
+ echo You must prepare a system-dependent jconfig.h file.
+ echo Please read the installation directions in install.doc.
+ exit 1
+
+# GNU Make likes to know which target names are not really files to be made:
+.PHONY: all install install-lib install-headers clean distclean test check
+
+
+jcapimin.$(O): jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.$(O): jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.$(O): jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.$(O): jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.$(O): jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.$(O): jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.$(O): jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.$(O): jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.$(O): jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.$(O): jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.$(O): jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.$(O): jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.$(O): jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.$(O): jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.$(O): jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.$(O): jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.$(O): jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.$(O): jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.$(O): jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.$(O): jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.$(O): jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.$(O): jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.$(O): jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.$(O): jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.$(O): jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.$(O): jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.$(O): jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.$(O): jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.$(O): jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.$(O): jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.$(O): jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.$(O): jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.$(O): jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.$(O): jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.$(O): jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.$(O): jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.$(O): jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.$(O): jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.$(O): jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.$(O): jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.$(O): jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.$(O): jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.$(O): jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.$(O): jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.$(O): jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.$(O): jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.$(O): jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.$(O): jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.$(O): jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.$(O): jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.$(O): cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.$(O): djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.$(O): jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.$(O): rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.$(O): wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.$(O): cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.$(O): rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.$(O): rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.$(O): transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.$(O): rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.$(O): wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.$(O): rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.$(O): wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.$(O): rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.$(O): wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.$(O): rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.$(O): wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.$(O): rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.$(O): wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.dj b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.dj
new file mode 100644
index 0000000..f766d25
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.dj
@@ -0,0 +1,220 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is for DJGPP (Delorie's GNU C port on MS-DOS), v2.0 or later.
+# Thanks to Frank J. Donahoe for this version.
+
+# Read installation instructions before saying "make" !!
+
+# The name of your C compiler:
+CC= gcc
+
+# You may need to adjust these cc options:
+CFLAGS= -O2 -Wall -I.
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via -D switches here.
+
+# Link-time cc options:
+LDFLAGS= -s
+
+# To link any special libraries, add the necessary -l commands here.
+LDLIBS=
+
+# Put here the object file name for the correct system-dependent memory
+# manager file. For DJGPP this is usually jmemnobs.o, but you could
+# use jmemname.o if you want to use named temp files instead of swap space.
+SYSDEPMEM= jmemnobs.o
+
+# miscellaneous OS-dependent stuff
+# linker
+LN= $(CC)
+# file deletion command
+RM= del
+# library (.a) file creation command
+AR= ar rc
+# second step in .a creation (use "touch" if not needed)
+AR2= ranlib
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \
+ jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \
+ jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \
+ jfdctint.o
+# decompression library object files
+DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdatasrc.o jdmaster.o \
+ jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \
+ jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \
+ jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o
+# These objectfiles are included in libjpeg.a
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \
+ cdjpeg.o
+DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
+ cdjpeg.o
+TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o
+
+
+all: libjpeg.a cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe
+
+libjpeg.a: $(LIBOBJECTS)
+ $(RM) libjpeg.a
+ $(AR) libjpeg.a $(LIBOBJECTS)
+ $(AR2) libjpeg.a
+
+cjpeg.exe: $(COBJECTS) libjpeg.a
+ $(LN) $(LDFLAGS) -o cjpeg.exe $(COBJECTS) libjpeg.a $(LDLIBS)
+
+djpeg.exe: $(DOBJECTS) libjpeg.a
+ $(LN) $(LDFLAGS) -o djpeg.exe $(DOBJECTS) libjpeg.a $(LDLIBS)
+
+jpegtran.exe: $(TROBJECTS) libjpeg.a
+ $(LN) $(LDFLAGS) -o jpegtran.exe $(TROBJECTS) libjpeg.a $(LDLIBS)
+
+rdjpgcom.exe: rdjpgcom.o
+ $(LN) $(LDFLAGS) -o rdjpgcom.exe rdjpgcom.o $(LDLIBS)
+
+wrjpgcom.exe: wrjpgcom.o
+ $(LN) $(LDFLAGS) -o wrjpgcom.exe wrjpgcom.o $(LDLIBS)
+
+jconfig.h: jconfig.doc
+ echo You must prepare a system-dependent jconfig.h file.
+ echo Please read the installation directions in install.doc.
+ exit 1
+
+clean:
+ $(RM) *.o
+ $(RM) cjpeg.exe
+ $(RM) djpeg.exe
+ $(RM) jpegtran.exe
+ $(RM) rdjpgcom.exe
+ $(RM) wrjpgcom.exe
+ $(RM) libjpeg.a
+ $(RM) testout*.*
+
+test: cjpeg.exe djpeg.exe jpegtran.exe
+ $(RM) testout*.*
+ ./djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+ ./djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+ ./cjpeg -dct int -outfile testout.jpg testimg.ppm
+ ./djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+ ./cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+ ./jpegtran -outfile testoutt.jpg testprog.jpg
+ fc /b testimg.ppm testout.ppm
+ fc /b testimg.bmp testout.bmp
+ fc /b testimg.jpg testout.jpg
+ fc /b testimg.ppm testoutp.ppm
+ fc /b testimgp.jpg testoutp.jpg
+ fc /b testorig.jpg testoutt.jpg
+
+
+jcapimin.o: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.o: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.o: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.o: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.o: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.o: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.o: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.o: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.o: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.o: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.o: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.o: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.o: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.o: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.o: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.o: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.o: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.o: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.o: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.o: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.o: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.o: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.o: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.o: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.o: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.o: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.o: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.o: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.o: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.o: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.o: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.o: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.o: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.o: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.o: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.o: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.manx b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.manx
new file mode 100644
index 0000000..4cb42d1
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.manx
@@ -0,0 +1,214 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is for Amiga systems using Manx Aztec C ver 5.x.
+# Thanks to D.J. James (djjames@cup.portal.com) for this version.
+
+# Read installation instructions before saying "make" !!
+
+# The name of your C compiler:
+CC= cc
+
+# You may need to adjust these cc options:
+# Uncomment for generic 68000 code (will work on any Amiga)
+ARCHFLAGS= -sn
+
+# Uncomment for 68020/68030 code (faster, but won't run on 68000 CPU)
+#ARCHFLAGS= -c2
+
+CFLAGS= -MC -MD $(ARCHFLAGS) -spfam -r4
+
+# Link-time cc options:
+LDFLAGS= -g
+
+# To link any special libraries, add the necessary -l commands here.
+LDLIBS= -lml -lcl
+
+# Put here the object file name for the correct system-dependent memory
+# manager file. For Amiga we recommend jmemname.o.
+SYSDEPMEM= jmemname.o
+
+# miscellaneous OS-dependent stuff
+# linker
+LN= ln
+# file deletion command
+RM= delete quiet
+# library (.lib) file creation command
+AR= lb
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \
+ jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \
+ jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \
+ jfdctint.o
+# decompression library object files
+DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdatasrc.o jdmaster.o \
+ jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \
+ jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \
+ jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o
+# These objectfiles are included in libjpeg.lib
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \
+ cdjpeg.o
+DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
+ cdjpeg.o
+TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o
+
+
+all: libjpeg.lib cjpeg djpeg jpegtran rdjpgcom wrjpgcom
+
+libjpeg.lib: $(LIBOBJECTS)
+ -$(RM) libjpeg.lib
+ $(AR) libjpeg.lib $(LIBOBJECTS)
+
+cjpeg: $(COBJECTS) libjpeg.lib
+ $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.lib $(LDLIBS)
+
+djpeg: $(DOBJECTS) libjpeg.lib
+ $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.lib $(LDLIBS)
+
+jpegtran: $(TROBJECTS) libjpeg.lib
+ $(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.lib $(LDLIBS)
+
+rdjpgcom: rdjpgcom.o
+ $(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.o $(LDLIBS)
+
+wrjpgcom: wrjpgcom.o
+ $(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.o $(LDLIBS)
+
+jconfig.h: jconfig.doc
+ echo You must prepare a system-dependent jconfig.h file.
+ echo Please read the installation directions in install.doc.
+ exit 1
+
+clean:
+ -$(RM) *.o cjpeg djpeg jpegtran libjpeg.lib rdjpgcom wrjpgcom
+ -$(RM) core testout*.*
+
+test: cjpeg djpeg jpegtran
+ -$(RM) testout*.*
+ djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+ djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+ cjpeg -dct int -outfile testout.jpg testimg.ppm
+ djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+ cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+ jpegtran -outfile testoutt.jpg testprog.jpg
+ cmp testimg.ppm testout.ppm
+ cmp testimg.bmp testout.bmp
+ cmp testimg.jpg testout.jpg
+ cmp testimg.ppm testoutp.ppm
+ cmp testimgp.jpg testoutp.jpg
+ cmp testorig.jpg testoutt.jpg
+
+
+jcapimin.o: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.o: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.o: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.o: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.o: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.o: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.o: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.o: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.o: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.o: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.o: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.o: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.o: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.o: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.o: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.o: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.o: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.o: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.o: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.o: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.o: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.o: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.o: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.o: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.o: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.o: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.o: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.o: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.o: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.o: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.o: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.o: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.o: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.o: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.o: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.o: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.mc6 b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.mc6
new file mode 100644
index 0000000..6aff054
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.mc6
@@ -0,0 +1,249 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is for Microsoft C for MS-DOS, version 6.00A and up.
+# Use NMAKE, not Microsoft's brain-damaged MAKE.
+# Thanks to Alan Wright and Chris Turner of Olivetti Research Ltd.
+
+# Read installation instructions before saying "nmake" !!
+
+# You may need to adjust these compiler options:
+CFLAGS = -AM -Oecigt -Gs -W3
+# -AM medium memory model (or use -AS for small model, if you remove features)
+# -Oecigt -Gs maximum safe optimisation (-Ol has bugs in MSC 6.00A)
+# -W3 warning level 3
+# You might also want to add -G2 if you have an 80286, etc.
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via -D switches here.
+
+# Jan-Herman Buining suggests the following switches for MS C 8.0 and a 486:
+# CFLAGS = /AM /f- /FPi87 /G3 /Gs /Gy /Ob1 /Oc /Oe /Og /Oi /Ol /On /Oo /Ot \
+# /OV4 /W3
+# except for jquant1.c, which must be compiled with /Oo- to avoid a compiler
+# crash.
+
+# Ingar Steinsland suggests the following switches when building
+# a 16-bit Windows DLL:
+# CFLAGS = -ALw -Gsw -Zpe -W3 -O2 -Zi -Zd
+
+# Put here the object file name for the correct system-dependent memory
+# manager file. For DOS, we recommend jmemdos.c and jmemdosa.asm.
+# (But not for Windows; see install.doc if you use this makefile for Windows.)
+SYSDEPMEM= jmemdos.obj jmemdosa.obj
+# SYSDEPMEMLIB must list the same files with "+" signs for the librarian.
+SYSDEPMEMLIB= +jmemdos.obj +jmemdosa.obj
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj \
+ jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj \
+ jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj \
+ jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj
+# decompression library object files
+DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj \
+ jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj \
+ jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj \
+ jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj \
+ jquant1.obj jquant2.obj jdmerge.obj
+# These objectfiles are included in libjpeg.lib
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj \
+ rdswitch.obj cdjpeg.obj
+DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \
+ rdcolmap.obj cdjpeg.obj
+TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj
+
+# need linker response file because file list > 128 chars
+RFILE = libjpeg.ans
+
+
+all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe
+
+libjpeg.lib: $(LIBOBJECTS) $(RFILE)
+ del libjpeg.lib
+ lib @$(RFILE)
+
+# linker response file for building libjpeg.lib
+$(RFILE) : makefile
+ del $(RFILE)
+ echo libjpeg.lib >$(RFILE)
+# silly want-to-create-it prompt:
+ echo y >>$(RFILE)
+ echo +jcapimin.obj +jcapistd.obj +jctrans.obj +jcparam.obj & >>$(RFILE)
+ echo +jdatadst.obj +jcinit.obj +jcmaster.obj +jcmarker.obj & >>$(RFILE)
+ echo +jcmainct.obj +jcprepct.obj +jccoefct.obj & >>$(RFILE)
+ echo +jccolor.obj +jcsample.obj +jchuff.obj +jcphuff.obj & >>$(RFILE)
+ echo +jcdctmgr.obj +jfdctfst.obj +jfdctflt.obj & >>$(RFILE)
+ echo +jfdctint.obj +jdapimin.obj +jdapistd.obj & >>$(RFILE)
+ echo +jdtrans.obj +jdatasrc.obj +jdmaster.obj +jdinput.obj & >>$(RFILE)
+ echo +jdmarker.obj +jdhuff.obj +jdphuff.obj +jdmainct.obj & >>$(RFILE)
+ echo +jdcoefct.obj +jdpostct.obj +jddctmgr.obj & >>$(RFILE)
+ echo +jidctfst.obj +jidctflt.obj +jidctint.obj & >>$(RFILE)
+ echo +jidctred.obj +jdsample.obj +jdcolor.obj +jquant1.obj & >>$(RFILE)
+ echo +jquant2.obj +jdmerge.obj +jcomapi.obj +jutils.obj & >>$(RFILE)
+ echo +jerror.obj +jmemmgr.obj & >>$(RFILE)
+ echo $(SYSDEPMEMLIB) ; >>$(RFILE)
+
+cjpeg.exe: $(COBJECTS) libjpeg.lib
+ echo $(COBJECTS) >cjpeg.lst
+ link /STACK:4096 /EXEPACK @cjpeg.lst, cjpeg.exe, , libjpeg.lib, ;
+ del cjpeg.lst
+
+djpeg.exe: $(DOBJECTS) libjpeg.lib
+ echo $(DOBJECTS) >djpeg.lst
+ link /STACK:4096 /EXEPACK @djpeg.lst, djpeg.exe, , libjpeg.lib, ;
+ del djpeg.lst
+
+jpegtran.exe: $(TROBJECTS) libjpeg.lib
+ link /STACK:4096 /EXEPACK $(TROBJECTS), jpegtran.exe, , libjpeg.lib, ;
+
+rdjpgcom.exe: rdjpgcom.c
+ $(CC) -AS -O -W3 rdjpgcom.c
+
+# wrjpgcom needs large model so it can malloc a 64K chunk
+wrjpgcom.exe: wrjpgcom.c
+ $(CC) -AL -O -W3 wrjpgcom.c
+
+jconfig.h: jconfig.doc
+ echo You must prepare a system-dependent jconfig.h file.
+ echo Please read the installation directions in install.doc.
+ exit 1
+
+clean:
+ del *.obj
+ del libjpeg.lib
+ del cjpeg.exe
+ del djpeg.exe
+ del jpegtran.exe
+ del rdjpgcom.exe
+ del wrjpgcom.exe
+ del testout*.*
+
+test: cjpeg.exe djpeg.exe jpegtran.exe
+ del testout*.*
+ djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+ djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+ cjpeg -dct int -outfile testout.jpg testimg.ppm
+ djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+ cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+ jpegtran -outfile testoutt.jpg testprog.jpg
+ fc /b testimg.ppm testout.ppm
+ fc /b testimg.bmp testout.bmp
+ fc /b testimg.jpg testout.jpg
+ fc /b testimg.ppm testoutp.ppm
+ fc /b testimgp.jpg testoutp.jpg
+ fc /b testorig.jpg testoutt.jpg
+
+
+jcapimin.obj: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.obj: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.obj: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.obj: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.obj: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.obj: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.obj: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.obj: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.obj: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.obj: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.obj: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.obj: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.obj: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.obj: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.obj: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.obj: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.obj: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.obj: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.obj: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.obj: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.obj: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.obj: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.obj: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.obj: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.obj: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.obj: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.obj: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.obj: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.obj: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.obj: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.obj: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.obj: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.obj: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.obj: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.obj: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.obj: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.obj: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.obj: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.obj: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.obj: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.obj: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.obj: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.obj: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.obj: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.obj: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.obj: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.obj: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.obj: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.obj: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.obj: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.obj: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.obj: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+jmemdosa.obj : jmemdosa.asm
+ masm /mx $*;
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.mms b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.mms
new file mode 100644
index 0000000..cf130e5
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.mms
@@ -0,0 +1,218 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is for use with MMS on Digital VMS systems.
+# Thanks to Rick Dyson (dyson@iowasp.physics.uiowa.edu)
+# and Tim Bell (tbell@netcom.com) for their help.
+
+# Read installation instructions before saying "MMS" !!
+
+# You may need to adjust these cc options:
+CFLAGS= $(CFLAGS) /NoDebug /Optimize
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via /Define switches here.
+.ifdef ALPHA
+OPT=
+.else
+OPT= ,Sys$Disk:[]MAKVMS.OPT/Option
+.endif
+
+# Put here the object file name for the correct system-dependent memory
+# manager file. For Unix this is usually jmemnobs.o, but you may want
+# to use jmemansi.o or jmemname.o if you have limited swap space.
+SYSDEPMEM= jmemnobs.obj
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj \
+ jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj \
+ jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj \
+ jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj
+# decompression library object files
+DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj \
+ jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj \
+ jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj \
+ jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj \
+ jquant1.obj jquant2.obj jdmerge.obj
+# These objectfiles are included in libjpeg.olb
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj \
+ rdswitch.obj cdjpeg.obj
+DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \
+ rdcolmap.obj cdjpeg.obj
+TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj
+# objectfile lists with commas --- what a crock
+COBJLIST= cjpeg.obj,rdppm.obj,rdgif.obj,rdtarga.obj,rdrle.obj,rdbmp.obj,\
+ rdswitch.obj,cdjpeg.obj
+DOBJLIST= djpeg.obj,wrppm.obj,wrgif.obj,wrtarga.obj,wrrle.obj,wrbmp.obj,\
+ rdcolmap.obj,cdjpeg.obj
+TROBJLIST= jpegtran.obj,rdswitch.obj,cdjpeg.obj,transupp.obj
+LIBOBJLIST= jcapimin.obj,jcapistd.obj,jctrans.obj,jcparam.obj,jdatadst.obj,\
+ jcinit.obj,jcmaster.obj,jcmarker.obj,jcmainct.obj,jcprepct.obj,\
+ jccoefct.obj,jccolor.obj,jcsample.obj,jchuff.obj,jcphuff.obj,\
+ jcdctmgr.obj,jfdctfst.obj,jfdctflt.obj,jfdctint.obj,jdapimin.obj,\
+ jdapistd.obj,jdtrans.obj,jdatasrc.obj,jdmaster.obj,jdinput.obj,\
+ jdmarker.obj,jdhuff.obj,jdphuff.obj,jdmainct.obj,jdcoefct.obj,\
+ jdpostct.obj,jddctmgr.obj,jidctfst.obj,jidctflt.obj,jidctint.obj,\
+ jidctred.obj,jdsample.obj,jdcolor.obj,jquant1.obj,jquant2.obj,\
+ jdmerge.obj,jcomapi.obj,jutils.obj,jerror.obj,jmemmgr.obj,$(SYSDEPMEM)
+
+
+.first
+ @- Define /NoLog Sys Sys$Library
+
+ALL : libjpeg.olb cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe
+ @ Continue
+
+libjpeg.olb : $(LIBOBJECTS)
+ Library /Create libjpeg.olb $(LIBOBJLIST)
+
+cjpeg.exe : $(COBJECTS) libjpeg.olb
+ $(LINK) $(LFLAGS) /Executable = cjpeg.exe $(COBJLIST),libjpeg.olb/Library$(OPT)
+
+djpeg.exe : $(DOBJECTS) libjpeg.olb
+ $(LINK) $(LFLAGS) /Executable = djpeg.exe $(DOBJLIST),libjpeg.olb/Library$(OPT)
+
+jpegtran.exe : $(TROBJECTS) libjpeg.olb
+ $(LINK) $(LFLAGS) /Executable = jpegtran.exe $(TROBJLIST),libjpeg.olb/Library$(OPT)
+
+rdjpgcom.exe : rdjpgcom.obj
+ $(LINK) $(LFLAGS) /Executable = rdjpgcom.exe rdjpgcom.obj$(OPT)
+
+wrjpgcom.exe : wrjpgcom.obj
+ $(LINK) $(LFLAGS) /Executable = wrjpgcom.exe wrjpgcom.obj$(OPT)
+
+jconfig.h : jconfig.vms
+ @- Copy jconfig.vms jconfig.h
+
+clean :
+ @- Set Protection = Owner:RWED *.*;-1
+ @- Set Protection = Owner:RWED *.OBJ
+ - Purge /NoLog /NoConfirm *.*
+ - Delete /NoLog /NoConfirm *.OBJ;
+
+test : cjpeg.exe djpeg.exe jpegtran.exe
+ mcr sys$disk:[]djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+ mcr sys$disk:[]djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+ mcr sys$disk:[]cjpeg -dct int -outfile testout.jpg testimg.ppm
+ mcr sys$disk:[]djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+ mcr sys$disk:[]cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+ mcr sys$disk:[]jpegtran -outfile testoutt.jpg testprog.jpg
+ - Backup /Compare/Log testimg.ppm testout.ppm
+ - Backup /Compare/Log testimg.bmp testout.bmp
+ - Backup /Compare/Log testimg.jpg testout.jpg
+ - Backup /Compare/Log testimg.ppm testoutp.ppm
+ - Backup /Compare/Log testimgp.jpg testoutp.jpg
+ - Backup /Compare/Log testorig.jpg testoutt.jpg
+
+
+jcapimin.obj : jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.obj : jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.obj : jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.obj : jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.obj : jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.obj : jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.obj : jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.obj : jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.obj : jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.obj : jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.obj : jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.obj : jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.obj : jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.obj : jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.obj : jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.obj : jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.obj : jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.obj : jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.obj : jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.obj : jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.obj : jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.obj : jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.obj : jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.obj : jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.obj : jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.obj : jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.obj : jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.obj : jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.obj : jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.obj : jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.obj : jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.obj : jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.obj : jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.obj : jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.obj : jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.obj : jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.obj : jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.obj : jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.obj : jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.obj : jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.obj : jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.obj : jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.obj : jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.obj : jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.obj : jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.obj : jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.obj : jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.obj : jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.obj : jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.obj : jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.obj : cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.obj : djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.obj : jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.obj : rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.obj : wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.obj : cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.obj : rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.obj : rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.obj : transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.obj : rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.obj : wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.obj : rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.obj : wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.obj : rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.obj : wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.obj : rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.obj : wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.obj : rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.obj : wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.sas b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.sas
new file mode 100644
index 0000000..f296faf
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.sas
@@ -0,0 +1,252 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is for Amiga systems using SAS C 6.0 and up.
+# Thanks to Ed Hanway, Mark Rinfret, and Jim Zepeda.
+
+# Read installation instructions before saying "make" !!
+
+# The name of your C compiler:
+CC= sc
+
+# You may need to adjust these cc options:
+# Uncomment the following lines for generic 680x0 version
+ARCHFLAGS= cpu=any
+SUFFIX=
+
+# Uncomment the following lines for 68030-only version
+#ARCHFLAGS= cpu=68030
+#SUFFIX=.030
+
+CFLAGS= nostackcheck data=near parms=register optimize $(ARCHFLAGS) \
+ ignore=104 ignore=304 ignore=306
+# ignore=104 disables warnings for mismatched const qualifiers
+# ignore=304 disables warnings for variables being optimized out
+# ignore=306 disables warnings for the inlining of functions
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via define switches here.
+
+# Link-time cc options:
+LDFLAGS= SC SD ND BATCH
+
+# To link any special libraries, add the necessary commands here.
+LDLIBS= LIB:scm.lib LIB:sc.lib
+
+# Put here the object file name for the correct system-dependent memory
+# manager file. For Amiga we recommend jmemname.o.
+SYSDEPMEM= jmemname.o
+
+# miscellaneous OS-dependent stuff
+# linker
+LN= slink
+# file deletion command
+RM= delete quiet
+# library (.lib) file creation command
+AR= oml
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \
+ jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \
+ jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \
+ jfdctint.o
+# decompression library object files
+DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdatasrc.o jdmaster.o \
+ jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \
+ jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \
+ jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o
+# These objectfiles are included in libjpeg.lib
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \
+ cdjpeg.o
+DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
+ cdjpeg.o
+TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o
+
+
+all: libjpeg.lib cjpeg$(SUFFIX) djpeg$(SUFFIX) jpegtran$(SUFFIX) rdjpgcom$(SUFFIX) wrjpgcom$(SUFFIX)
+
+# note: do several AR steps to avoid command line length limitations
+
+libjpeg.lib: $(LIBOBJECTS)
+ -$(RM) libjpeg.lib
+ $(AR) libjpeg.lib r $(CLIBOBJECTS)
+ $(AR) libjpeg.lib r $(DLIBOBJECTS)
+ $(AR) libjpeg.lib r $(COMOBJECTS)
+
+cjpeg$(SUFFIX): $(COBJECTS) libjpeg.lib
+ $(LN) <WITH <
+$(LDFLAGS)
+TO cjpeg$(SUFFIX)
+FROM LIB:c.o $(COBJECTS)
+LIB libjpeg.lib $(LDLIBS)
+<
+
+djpeg$(SUFFIX): $(DOBJECTS) libjpeg.lib
+ $(LN) <WITH <
+$(LDFLAGS)
+TO djpeg$(SUFFIX)
+FROM LIB:c.o $(DOBJECTS)
+LIB libjpeg.lib $(LDLIBS)
+<
+
+jpegtran$(SUFFIX): $(TROBJECTS) libjpeg.lib
+ $(LN) <WITH <
+$(LDFLAGS)
+TO jpegtran$(SUFFIX)
+FROM LIB:c.o $(TROBJECTS)
+LIB libjpeg.lib $(LDLIBS)
+<
+
+rdjpgcom$(SUFFIX): rdjpgcom.o
+ $(LN) <WITH <
+$(LDFLAGS)
+TO rdjpgcom$(SUFFIX)
+FROM LIB:c.o rdjpgcom.o
+LIB $(LDLIBS)
+<
+
+wrjpgcom$(SUFFIX): wrjpgcom.o
+ $(LN) <WITH <
+$(LDFLAGS)
+TO wrjpgcom$(SUFFIX)
+FROM LIB:c.o wrjpgcom.o
+LIB $(LDLIBS)
+<
+
+jconfig.h: jconfig.doc
+ echo You must prepare a system-dependent jconfig.h file.
+ echo Please read the installation directions in install.doc.
+ exit 1
+
+clean:
+ -$(RM) *.o cjpeg djpeg jpegtran cjpeg.030 djpeg.030 jpegtran.030
+ -$(RM) rdjpgcom wrjpgcom rdjpgcom.030 wrjpgcom.030
+ -$(RM) libjpeg.lib core testout*.*
+
+test: cjpeg djpeg jpegtran
+ -$(RM) testout*.*
+ djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+ djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+ cjpeg -dct int -outfile testout.jpg testimg.ppm
+ djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+ cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+ jpegtran -outfile testoutt.jpg testprog.jpg
+ cmp testimg.ppm testout.ppm
+ cmp testimg.bmp testout.bmp
+ cmp testimg.jpg testout.jpg
+ cmp testimg.ppm testoutp.ppm
+ cmp testimgp.jpg testoutp.jpg
+ cmp testorig.jpg testoutt.jpg
+
+
+jcapimin.o: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.o: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.o: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.o: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.o: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.o: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.o: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.o: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.o: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.o: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.o: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.o: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.o: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.o: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.o: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.o: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.o: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.o: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.o: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.o: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.o: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.o: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.o: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.o: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.o: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.o: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.o: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.o: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.o: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.o: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.o: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.o: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.o: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.o: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.o: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.o: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.unix b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.unix
new file mode 100644
index 0000000..00455ab
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.unix
@@ -0,0 +1,228 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is suitable for Unix-like systems with non-ANSI compilers.
+# If you have an ANSI compiler, makefile.ansi is a better starting point.
+
+# Read installation instructions before saying "make" !!
+
+# The name of your C compiler:
+CC= cc
+
+# You may need to adjust these cc options:
+CFLAGS= -O
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via -D switches here.
+# However, any special defines for ansi2knr.c may be included here:
+ANSI2KNRFLAGS=
+
+# Link-time cc options:
+LDFLAGS=
+
+# To link any special libraries, add the necessary -l commands here.
+LDLIBS=
+
+# Put here the object file name for the correct system-dependent memory
+# manager file. For Unix this is usually jmemnobs.o, but you may want
+# to use jmemansi.o or jmemname.o if you have limited swap space.
+SYSDEPMEM= jmemnobs.o
+
+# miscellaneous OS-dependent stuff
+# linker
+LN= $(CC)
+# file deletion command
+RM= rm -f
+# file rename command
+MV= mv
+# library (.a) file creation command
+AR= ar rc
+# second step in .a creation (use "touch" if not needed)
+AR2= ranlib
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \
+ jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \
+ jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \
+ jfdctint.o
+# decompression library object files
+DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdatasrc.o jdmaster.o \
+ jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \
+ jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \
+ jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o
+# These objectfiles are included in libjpeg.a
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.o rdppm.o rdgif.o rdtarga.o rdrle.o rdbmp.o rdswitch.o \
+ cdjpeg.o
+DOBJECTS= djpeg.o wrppm.o wrgif.o wrtarga.o wrrle.o wrbmp.o rdcolmap.o \
+ cdjpeg.o
+TROBJECTS= jpegtran.o rdswitch.o cdjpeg.o transupp.o
+
+
+all: ansi2knr libjpeg.a cjpeg djpeg jpegtran rdjpgcom wrjpgcom
+
+# This rule causes ansi2knr to be invoked.
+.c.o:
+ ./ansi2knr $*.c T$*.c
+ $(CC) $(CFLAGS) -c T$*.c
+ $(RM) T$*.c $*.o
+ $(MV) T$*.o $*.o
+
+ansi2knr: ansi2knr.c
+ $(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr ansi2knr.c
+
+libjpeg.a: ansi2knr $(LIBOBJECTS)
+ $(RM) libjpeg.a
+ $(AR) libjpeg.a $(LIBOBJECTS)
+ $(AR2) libjpeg.a
+
+cjpeg: ansi2knr $(COBJECTS) libjpeg.a
+ $(LN) $(LDFLAGS) -o cjpeg $(COBJECTS) libjpeg.a $(LDLIBS)
+
+djpeg: ansi2knr $(DOBJECTS) libjpeg.a
+ $(LN) $(LDFLAGS) -o djpeg $(DOBJECTS) libjpeg.a $(LDLIBS)
+
+jpegtran: ansi2knr $(TROBJECTS) libjpeg.a
+ $(LN) $(LDFLAGS) -o jpegtran $(TROBJECTS) libjpeg.a $(LDLIBS)
+
+rdjpgcom: rdjpgcom.o
+ $(LN) $(LDFLAGS) -o rdjpgcom rdjpgcom.o $(LDLIBS)
+
+wrjpgcom: wrjpgcom.o
+ $(LN) $(LDFLAGS) -o wrjpgcom wrjpgcom.o $(LDLIBS)
+
+jconfig.h: jconfig.doc
+ echo You must prepare a system-dependent jconfig.h file.
+ echo Please read the installation directions in install.doc.
+ exit 1
+
+clean:
+ $(RM) *.o cjpeg djpeg jpegtran libjpeg.a rdjpgcom wrjpgcom
+ $(RM) ansi2knr core testout*
+
+test: cjpeg djpeg jpegtran
+ $(RM) testout*
+ ./djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+ ./djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+ ./cjpeg -dct int -outfile testout.jpg testimg.ppm
+ ./djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+ ./cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+ ./jpegtran -outfile testoutt.jpg testprog.jpg
+ cmp testimg.ppm testout.ppm
+ cmp testimg.bmp testout.bmp
+ cmp testimg.jpg testout.jpg
+ cmp testimg.ppm testoutp.ppm
+ cmp testimgp.jpg testoutp.jpg
+ cmp testorig.jpg testoutt.jpg
+
+
+jcapimin.o: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.o: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.o: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.o: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.o: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.o: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.o: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.o: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.o: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.o: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.o: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.o: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.o: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.o: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.o: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.o: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.o: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.o: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.o: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.o: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.o: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.o: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.o: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.o: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.o: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.o: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.o: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.o: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.o: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.o: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.o: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.o: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.o: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.o: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.o: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.o: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.o: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.o: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.o: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.o: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.o: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.o: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.o: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.o: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.o: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.o: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.o: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.o: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.o: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.o: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.o: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.o: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.o: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.o: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.o: wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.o: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.o: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.o: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.o: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.o: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.o: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.o: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.o: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.o: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.o: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.o: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.o: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.o: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.o: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.vc b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.vc
new file mode 100644
index 0000000..16281fd
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.vc
@@ -0,0 +1,210 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is for Microsoft Visual C++ on Windows NT (and 95?).
+# It builds the IJG library as a statically linkable library (.LIB),
+# and builds the sample applications as console-mode apps.
+# Thanks to Xingong Chang, Raymond Everly and others.
+
+# Read installation instructions before saying "nmake" !!
+# To build an optimized library without debug info, say "nmake nodebug=1".
+
+# Pull in standard variable definitions
+!include <win32.mak>
+
+# You may want to adjust these compiler options:
+CFLAGS= $(cflags) $(cdebug) $(cvars) -I.
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via -D switches here.
+
+# Link-time options:
+LDFLAGS= $(ldebug) $(conlflags)
+
+# To link any special libraries, add the necessary commands here.
+LDLIBS= $(conlibs)
+
+# Put here the object file name for the correct system-dependent memory
+# manager file. For NT we suggest jmemnobs.obj, which expects the OS to
+# provide adequate virtual memory.
+SYSDEPMEM= jmemnobs.obj
+
+# miscellaneous OS-dependent stuff
+# file deletion command
+RM= del
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c \
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c \
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c \
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c \
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c \
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c \
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c \
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c \
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c \
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h \
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 \
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc \
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc \
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds \
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st \
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms \
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat \
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas \
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg \
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) \
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj \
+ jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj \
+ jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj \
+ jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj
+# decompression library object files
+DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj \
+ jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj \
+ jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj \
+ jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj \
+ jquant1.obj jquant2.obj jdmerge.obj
+# These objectfiles are included in libjpeg.lib
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj \
+ rdswitch.obj cdjpeg.obj
+DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj \
+ rdcolmap.obj cdjpeg.obj
+TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj
+
+# Template command for compiling .c to .obj
+.c.obj:
+ $(cc) $(CFLAGS) $*.c
+
+
+all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe
+
+libjpeg.lib: $(LIBOBJECTS)
+ lib -out:libjpeg.lib $(LIBOBJECTS)
+
+cjpeg.exe: $(COBJECTS) libjpeg.lib
+ $(link) $(LDFLAGS) -out:cjpeg.exe $(COBJECTS) libjpeg.lib $(LDLIBS)
+
+djpeg.exe: $(DOBJECTS) libjpeg.lib
+ $(link) $(LDFLAGS) -out:djpeg.exe $(DOBJECTS) libjpeg.lib $(LDLIBS)
+
+jpegtran.exe: $(TROBJECTS) libjpeg.lib
+ $(link) $(LDFLAGS) -out:jpegtran.exe $(TROBJECTS) libjpeg.lib $(LDLIBS)
+
+rdjpgcom.exe: rdjpgcom.obj
+ $(link) $(LDFLAGS) -out:rdjpgcom.exe rdjpgcom.obj $(LDLIBS)
+
+wrjpgcom.exe: wrjpgcom.obj
+ $(link) $(LDFLAGS) -out:wrjpgcom.exe wrjpgcom.obj $(LDLIBS)
+
+
+clean:
+ $(RM) *.obj *.exe libjpeg.lib
+ $(RM) testout*
+
+test: cjpeg.exe djpeg.exe jpegtran.exe
+ $(RM) testout*
+ .\djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+ .\djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+ .\cjpeg -dct int -outfile testout.jpg testimg.ppm
+ .\djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+ .\cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+ .\jpegtran -outfile testoutt.jpg testprog.jpg
+ fc /b testimg.ppm testout.ppm
+ fc /b testimg.bmp testout.bmp
+ fc /b testimg.jpg testout.jpg
+ fc /b testimg.ppm testoutp.ppm
+ fc /b testimgp.jpg testoutp.jpg
+ fc /b testorig.jpg testoutt.jpg
+
+
+jcapimin.obj: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.obj: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.obj: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.obj: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.obj: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.obj: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.obj: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.obj: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.obj: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.obj: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.obj: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.obj: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.obj: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.obj: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.obj: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.obj: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.obj: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.obj: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.obj: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.obj: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.obj: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.obj: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.obj: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.obj: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.obj: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.obj: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.obj: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.obj: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.obj: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.obj: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.obj: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.obj: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.obj: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.obj: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.obj: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.obj: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.obj: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.obj: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.obj: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.obj: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.obj: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.obj: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.obj: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.obj: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.obj: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.obj: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.obj: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.obj: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.obj: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.obj: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.obj: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.obj: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.vms b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.vms
new file mode 100644
index 0000000..a42358d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.vms
@@ -0,0 +1,142 @@
+$! Makefile for Independent JPEG Group's software
+$!
+$! This is a command procedure for Digital VMS systems that do not have MMS.
+$! It builds the JPEG software by brute force, recompiling everything whether
+$! or not it is necessary. It then runs the basic self-test.
+$! Thanks to Rick Dyson (dyson@iowasp.physics.uiowa.edu)
+$! and Tim Bell (tbell@netcom.com) for their help.
+$!
+$! Read installation instructions before running this!!
+$!
+$ If F$Mode () .eqs. "INTERACTIVE"
+$ Then
+$ VERIFY = F$Verify (0)
+$ Else
+$ VERIFY = F$Verify (1)
+$ EndIf
+$ On Control_Y Then GoTo End
+$ On Error Then GoTo End
+$
+$ If F$GetSyi ("HW_MODEL") .gt. 1023
+$ Then
+$ OPT = ""
+$ Else
+$ OPT = ",Sys$Disk:[]makvms.opt/Option"
+$ EndIf
+$
+$ DoCompile := CC /NoDebug /Optimize /NoList
+$!
+$ DoCompile jcapimin.c
+$ DoCompile jcapistd.c
+$ DoCompile jctrans.c
+$ DoCompile jcparam.c
+$ DoCompile jdatadst.c
+$ DoCompile jcinit.c
+$ DoCompile jcmaster.c
+$ DoCompile jcmarker.c
+$ DoCompile jcmainct.c
+$ DoCompile jcprepct.c
+$ DoCompile jccoefct.c
+$ DoCompile jccolor.c
+$ DoCompile jcsample.c
+$ DoCompile jchuff.c
+$ DoCompile jcphuff.c
+$ DoCompile jcdctmgr.c
+$ DoCompile jfdctfst.c
+$ DoCompile jfdctflt.c
+$ DoCompile jfdctint.c
+$ DoCompile jdapimin.c
+$ DoCompile jdapistd.c
+$ DoCompile jdtrans.c
+$ DoCompile jdatasrc.c
+$ DoCompile jdmaster.c
+$ DoCompile jdinput.c
+$ DoCompile jdmarker.c
+$ DoCompile jdhuff.c
+$ DoCompile jdphuff.c
+$ DoCompile jdmainct.c
+$ DoCompile jdcoefct.c
+$ DoCompile jdpostct.c
+$ DoCompile jddctmgr.c
+$ DoCompile jidctfst.c
+$ DoCompile jidctflt.c
+$ DoCompile jidctint.c
+$ DoCompile jidctred.c
+$ DoCompile jdsample.c
+$ DoCompile jdcolor.c
+$ DoCompile jquant1.c
+$ DoCompile jquant2.c
+$ DoCompile jdmerge.c
+$ DoCompile jcomapi.c
+$ DoCompile jutils.c
+$ DoCompile jerror.c
+$ DoCompile jmemmgr.c
+$ DoCompile jmemnobs.c
+$!
+$ Library /Create libjpeg.olb jcapimin.obj,jcapistd.obj,jctrans.obj, -
+ jcparam.obj,jdatadst.obj,jcinit.obj,jcmaster.obj,jcmarker.obj, -
+ jcmainct.obj,jcprepct.obj,jccoefct.obj,jccolor.obj,jcsample.obj, -
+ jchuff.obj,jcphuff.obj,jcdctmgr.obj,jfdctfst.obj,jfdctflt.obj, -
+ jfdctint.obj,jdapimin.obj,jdapistd.obj,jdtrans.obj,jdatasrc.obj, -
+ jdmaster.obj,jdinput.obj,jdmarker.obj,jdhuff.obj,jdphuff.obj, -
+ jdmainct.obj,jdcoefct.obj,jdpostct.obj,jddctmgr.obj,jidctfst.obj, -
+ jidctflt.obj,jidctint.obj,jidctred.obj,jdsample.obj,jdcolor.obj, -
+ jquant1.obj,jquant2.obj,jdmerge.obj,jcomapi.obj,jutils.obj, -
+ jerror.obj,jmemmgr.obj,jmemnobs.obj
+$!
+$ DoCompile cjpeg.c
+$ DoCompile rdppm.c
+$ DoCompile rdgif.c
+$ DoCompile rdtarga.c
+$ DoCompile rdrle.c
+$ DoCompile rdbmp.c
+$ DoCompile rdswitch.c
+$ DoCompile cdjpeg.c
+$!
+$ Link /NoMap /Executable = cjpeg.exe cjpeg.obj,rdppm.obj,rdgif.obj, -
+ rdtarga.obj,rdrle.obj,rdbmp.obj,rdswitch.obj,cdjpeg.obj,libjpeg.olb/Library'OPT'
+$!
+$ DoCompile djpeg.c
+$ DoCompile wrppm.c
+$ DoCompile wrgif.c
+$ DoCompile wrtarga.c
+$ DoCompile wrrle.c
+$ DoCompile wrbmp.c
+$ DoCompile rdcolmap.c
+$ DoCompile cdjpeg.c
+$!
+$ Link /NoMap /Executable = djpeg.exe djpeg.obj,wrppm.obj,wrgif.obj, -
+ wrtarga.obj,wrrle.obj,wrbmp.obj,rdcolmap.obj,cdjpeg.obj,libjpeg.olb/Library'OPT'
+$!
+$ DoCompile jpegtran.c
+$ DoCompile rdswitch.c
+$ DoCompile cdjpeg.c
+$ DoCompile transupp.c
+$!
+$ Link /NoMap /Executable = jpegtran.exe jpegtran.obj,rdswitch.obj, -
+ cdjpeg.obj,transupp.obj,libjpeg.olb/Library'OPT'
+$!
+$ DoCompile rdjpgcom.c
+$ Link /NoMap /Executable = rdjpgcom.exe rdjpgcom.obj'OPT'
+$!
+$ DoCompile wrjpgcom.c
+$ Link /NoMap /Executable = wrjpgcom.exe wrjpgcom.obj'OPT'
+$!
+$! Run the self-test
+$!
+$ mcr sys$disk:[]djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+$ mcr sys$disk:[]djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+$ mcr sys$disk:[]cjpeg -dct int -outfile testout.jpg testimg.ppm
+$ mcr sys$disk:[]djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+$ mcr sys$disk:[]cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+$ mcr sys$disk:[]jpegtran -outfile testoutt.jpg testprog.jpg
+$ Backup /Compare/Log testimg.ppm testout.ppm
+$ Backup /Compare/Log testimg.bmp testout.bmp
+$ Backup /Compare/Log testimg.jpg testout.jpg
+$ Backup /Compare/Log testimg.ppm testoutp.ppm
+$ Backup /Compare/Log testimgp.jpg testoutp.jpg
+$ Backup /Compare/Log testorig.jpg testoutt.jpg
+$!
+$End:
+$ If Verify Then Set Verify
+$ Exit
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.wat b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.wat
new file mode 100644
index 0000000..d953e46
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/makefile.wat
@@ -0,0 +1,233 @@
+# Makefile for Independent JPEG Group's software
+
+# This makefile is suitable for Watcom C/C++ 10.0 on MS-DOS (using
+# dos4g extender), OS/2, and Windows NT console mode.
+# Thanks to Janos Haide, jhaide@btrvtech.com.
+
+# Read installation instructions before saying "wmake" !!
+
+# Uncomment line for desired system
+SYSTEM=DOS
+#SYSTEM=OS2
+#SYSTEM=NT
+
+# The name of your C compiler:
+CC= wcl386
+
+# You may need to adjust these cc options:
+CFLAGS= -4r -ort -wx -zq -bt=$(SYSTEM)
+# Caution: avoid -ol or -ox; these generate bad code with 10.0 or 10.0a.
+# Generally, we recommend defining any configuration symbols in jconfig.h,
+# NOT via -D switches here.
+
+# Link-time cc options:
+!ifeq SYSTEM DOS
+LDFLAGS= -zq -l=dos4g
+!else ifeq SYSTEM OS2
+LDFLAGS= -zq -l=os2v2
+!else ifeq SYSTEM NT
+LDFLAGS= -zq -l=nt
+!endif
+
+# Put here the object file name for the correct system-dependent memory
+# manager file. jmemnobs should work fine for dos4g or OS/2 environment.
+SYSDEPMEM= jmemnobs.obj
+
+# End of configurable options.
+
+
+# source files: JPEG library proper
+LIBSOURCES= jcapimin.c jcapistd.c jccoefct.c jccolor.c jcdctmgr.c jchuff.c &
+ jcinit.c jcmainct.c jcmarker.c jcmaster.c jcomapi.c jcparam.c &
+ jcphuff.c jcprepct.c jcsample.c jctrans.c jdapimin.c jdapistd.c &
+ jdatadst.c jdatasrc.c jdcoefct.c jdcolor.c jddctmgr.c jdhuff.c &
+ jdinput.c jdmainct.c jdmarker.c jdmaster.c jdmerge.c jdphuff.c &
+ jdpostct.c jdsample.c jdtrans.c jerror.c jfdctflt.c jfdctfst.c &
+ jfdctint.c jidctflt.c jidctfst.c jidctint.c jidctred.c jquant1.c &
+ jquant2.c jutils.c jmemmgr.c
+# memmgr back ends: compile only one of these into a working library
+SYSDEPSOURCES= jmemansi.c jmemname.c jmemnobs.c jmemdos.c jmemmac.c
+# source files: cjpeg/djpeg/jpegtran applications, also rdjpgcom/wrjpgcom
+APPSOURCES= cjpeg.c djpeg.c jpegtran.c rdjpgcom.c wrjpgcom.c cdjpeg.c &
+ rdcolmap.c rdswitch.c transupp.c rdppm.c wrppm.c rdgif.c wrgif.c &
+ rdtarga.c wrtarga.c rdbmp.c wrbmp.c rdrle.c wrrle.c
+SOURCES= $(LIBSOURCES) $(SYSDEPSOURCES) $(APPSOURCES)
+# files included by source files
+INCLUDES= jchuff.h jdhuff.h jdct.h jerror.h jinclude.h jmemsys.h jmorecfg.h &
+ jpegint.h jpeglib.h jversion.h cdjpeg.h cderror.h transupp.h
+# documentation, test, and support files
+DOCS= README install.doc usage.doc cjpeg.1 djpeg.1 jpegtran.1 rdjpgcom.1 &
+ wrjpgcom.1 wizard.doc example.c libjpeg.doc structure.doc &
+ coderules.doc filelist.doc change.log
+MKFILES= configure makefile.cfg makefile.ansi makefile.unix makefile.bcc &
+ makefile.mc6 makefile.dj makefile.wat makefile.vc makelib.ds &
+ makeapps.ds makeproj.mac makcjpeg.st makdjpeg.st makljpeg.st &
+ maktjpeg.st makefile.manx makefile.sas makefile.mms makefile.vms &
+ makvms.opt
+CONFIGFILES= jconfig.cfg jconfig.bcc jconfig.mc6 jconfig.dj jconfig.wat &
+ jconfig.vc jconfig.mac jconfig.st jconfig.manx jconfig.sas &
+ jconfig.vms
+CONFIGUREFILES= config.guess config.sub install-sh ltconfig ltmain.sh
+OTHERFILES= jconfig.doc ckconfig.c ansi2knr.c ansi2knr.1 jmemdosa.asm
+TESTFILES= testorig.jpg testimg.ppm testimg.bmp testimg.jpg testprog.jpg &
+ testimgp.jpg
+DISTFILES= $(DOCS) $(MKFILES) $(CONFIGFILES) $(SOURCES) $(INCLUDES) &
+ $(CONFIGUREFILES) $(OTHERFILES) $(TESTFILES)
+# library object files common to compression and decompression
+COMOBJECTS= jcomapi.obj jutils.obj jerror.obj jmemmgr.obj $(SYSDEPMEM)
+# compression library object files
+CLIBOBJECTS= jcapimin.obj jcapistd.obj jctrans.obj jcparam.obj jdatadst.obj &
+ jcinit.obj jcmaster.obj jcmarker.obj jcmainct.obj jcprepct.obj &
+ jccoefct.obj jccolor.obj jcsample.obj jchuff.obj jcphuff.obj &
+ jcdctmgr.obj jfdctfst.obj jfdctflt.obj jfdctint.obj
+# decompression library object files
+DLIBOBJECTS= jdapimin.obj jdapistd.obj jdtrans.obj jdatasrc.obj &
+ jdmaster.obj jdinput.obj jdmarker.obj jdhuff.obj jdphuff.obj &
+ jdmainct.obj jdcoefct.obj jdpostct.obj jddctmgr.obj jidctfst.obj &
+ jidctflt.obj jidctint.obj jidctred.obj jdsample.obj jdcolor.obj &
+ jquant1.obj jquant2.obj jdmerge.obj
+# These objectfiles are included in libjpeg.lib
+LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
+# object files for sample applications (excluding library files)
+COBJECTS= cjpeg.obj rdppm.obj rdgif.obj rdtarga.obj rdrle.obj rdbmp.obj &
+ rdswitch.obj cdjpeg.obj
+DOBJECTS= djpeg.obj wrppm.obj wrgif.obj wrtarga.obj wrrle.obj wrbmp.obj &
+ rdcolmap.obj cdjpeg.obj
+TROBJECTS= jpegtran.obj rdswitch.obj cdjpeg.obj transupp.obj
+
+
+all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe rdjpgcom.exe wrjpgcom.exe
+
+libjpeg.lib: $(LIBOBJECTS)
+ - del libjpeg.lib
+ * wlib -n libjpeg.lib $(LIBOBJECTS)
+
+cjpeg.exe: $(COBJECTS) libjpeg.lib
+ $(CC) $(LDFLAGS) $(COBJECTS) libjpeg.lib
+
+djpeg.exe: $(DOBJECTS) libjpeg.lib
+ $(CC) $(LDFLAGS) $(DOBJECTS) libjpeg.lib
+
+jpegtran.exe: $(TROBJECTS) libjpeg.lib
+ $(CC) $(LDFLAGS) $(TROBJECTS) libjpeg.lib
+
+rdjpgcom.exe: rdjpgcom.c
+ $(CC) $(CFLAGS) $(LDFLAGS) rdjpgcom.c
+
+wrjpgcom.exe: wrjpgcom.c
+ $(CC) $(CFLAGS) $(LDFLAGS) wrjpgcom.c
+
+.c.obj:
+ $(CC) $(CFLAGS) -c $<
+
+jconfig.h: jconfig.doc
+ echo You must prepare a system-dependent jconfig.h file.
+ echo Please read the installation directions in install.doc.
+ exit 1
+
+clean: .SYMBOLIC
+ - del *.obj
+ - del libjpeg.lib
+ - del cjpeg.exe
+ - del djpeg.exe
+ - del jpegtran.exe
+ - del rdjpgcom.exe
+ - del wrjpgcom.exe
+ - del testout*.*
+
+test: cjpeg.exe djpeg.exe jpegtran.exe .SYMBOLIC
+ - del testout*.*
+ djpeg -dct int -ppm -outfile testout.ppm testorig.jpg
+ djpeg -dct int -bmp -colors 256 -outfile testout.bmp testorig.jpg
+ cjpeg -dct int -outfile testout.jpg testimg.ppm
+ djpeg -dct int -ppm -outfile testoutp.ppm testprog.jpg
+ cjpeg -dct int -progressive -opt -outfile testoutp.jpg testimg.ppm
+ jpegtran -outfile testoutt.jpg testprog.jpg
+!ifeq SYSTEM DOS
+ fc /b testimg.ppm testout.ppm
+ fc /b testimg.bmp testout.bmp
+ fc /b testimg.jpg testout.jpg
+ fc /b testimg.ppm testoutp.ppm
+ fc /b testimgp.jpg testoutp.jpg
+ fc /b testorig.jpg testoutt.jpg
+!else
+ echo n > n.tmp
+ comp testimg.ppm testout.ppm < n.tmp
+ comp testimg.bmp testout.bmp < n.tmp
+ comp testimg.jpg testout.jpg < n.tmp
+ comp testimg.ppm testoutp.ppm < n.tmp
+ comp testimgp.jpg testoutp.jpg < n.tmp
+ comp testorig.jpg testoutt.jpg < n.tmp
+ del n.tmp
+!endif
+
+
+jcapimin.obj: jcapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcapistd.obj: jcapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccoefct.obj: jccoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jccolor.obj: jccolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcdctmgr.obj: jcdctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jchuff.obj: jchuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcinit.obj: jcinit.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmainct.obj: jcmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmarker.obj: jcmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcmaster.obj: jcmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcomapi.obj: jcomapi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcparam.obj: jcparam.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcphuff.obj: jcphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jchuff.h
+jcprepct.obj: jcprepct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jcsample.obj: jcsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jctrans.obj: jctrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapimin.obj: jdapimin.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdapistd.obj: jdapistd.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdatadst.obj: jdatadst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdatasrc.obj: jdatasrc.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h
+jdcoefct.obj: jdcoefct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdcolor.obj: jdcolor.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jddctmgr.obj: jddctmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jdhuff.obj: jdhuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdinput.obj: jdinput.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmainct.obj: jdmainct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmarker.obj: jdmarker.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmaster.obj: jdmaster.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdmerge.obj: jdmerge.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdphuff.obj: jdphuff.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdhuff.h
+jdpostct.obj: jdpostct.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdsample.obj: jdsample.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jdtrans.obj: jdtrans.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jerror.obj: jerror.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jversion.h jerror.h
+jfdctflt.obj: jfdctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctfst.obj: jfdctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jfdctint.obj: jfdctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctflt.obj: jidctflt.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctfst.obj: jidctfst.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctint.obj: jidctint.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jidctred.obj: jidctred.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jdct.h
+jquant1.obj: jquant1.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jquant2.obj: jquant2.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jutils.obj: jutils.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h
+jmemmgr.obj: jmemmgr.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemansi.obj: jmemansi.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemname.obj: jmemname.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemnobs.obj: jmemnobs.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemdos.obj: jmemdos.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+jmemmac.obj: jmemmac.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h jmemsys.h
+cjpeg.obj: cjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+djpeg.obj: djpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h jversion.h
+jpegtran.obj: jpegtran.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h transupp.h jversion.h
+rdjpgcom.obj: rdjpgcom.c jinclude.h jconfig.h
+wrjpgcom.obj: wrjpgcom.c jinclude.h jconfig.h
+cdjpeg.obj: cdjpeg.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdcolmap.obj: rdcolmap.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdswitch.obj: rdswitch.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+transupp.obj: transupp.c jinclude.h jconfig.h jpeglib.h jmorecfg.h jpegint.h jerror.h transupp.h
+rdppm.obj: rdppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrppm.obj: wrppm.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdgif.obj: rdgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrgif.obj: wrgif.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdtarga.obj: rdtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrtarga.obj: wrtarga.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdbmp.obj: rdbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrbmp.obj: wrbmp.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+rdrle.obj: rdrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
+wrrle.obj: wrrle.c cdjpeg.h jinclude.h jconfig.h jpeglib.h jmorecfg.h jerror.h cderror.h
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/structure.doc b/tqtinterface/qt4/src/3rdparty/libjpeg/structure.doc
new file mode 100644
index 0000000..2d60c87
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/structure.doc
@@ -0,0 +1,948 @@
+IJG JPEG LIBRARY: SYSTEM ARCHITECTURE
+
+Copyright (C) 1991-1995, Thomas G. Lane.
+This file is part of the Independent JPEG Group's software.
+For conditions of distribution and use, see the accompanying README file.
+
+
+This file provides an overview of the architecture of the IJG JPEG software;
+that is, the functions of the various modules in the system and the interfaces
+between modules. For more precise details about any data structure or calling
+convention, see the include files and comments in the source code.
+
+We assume that the reader is already somewhat familiar with the JPEG standard.
+The README file includes references for learning about JPEG. The file
+libjpeg.doc describes the library from the viewpoint of an application
+programmer using the library; it's best to read that file before this one.
+Also, the file coderules.doc describes the coding style conventions we use.
+
+In this document, JPEG-specific terminology follows the JPEG standard:
+ A "component" means a color channel, e.g., Red or Luminance.
+ A "sample" is a single component value (i.e., one number in the image data).
+ A "coefficient" is a frequency coefficient (a DCT transform output number).
+ A "block" is an 8x8 group of samples or coefficients.
+ An "MCU" (minimum coded unit) is an interleaved set of blocks of size
+ determined by the sampling factors, or a single block in a
+ noninterleaved scan.
+We do not use the terms "pixel" and "sample" interchangeably. When we say
+pixel, we mean an element of the full-size image, while a sample is an element
+of the downsampled image. Thus the number of samples may vary across
+components while the number of pixels does not. (This terminology is not used
+rigorously throughout the code, but it is used in places where confusion would
+otherwise result.)
+
+
+*** System features ***
+
+The IJG distribution tqcontains two parts:
+ * A subroutine library for JPEG compression and decompression.
+ * cjpeg/djpeg, two sample applications that use the library to transform
+ JFIF JPEG files to and from several other image formats.
+cjpeg/djpeg are of no great intellectual complexity: they merely add a simple
+command-line user interface and I/O routines for several uncompressed image
+formats. This document concentrates on the library itself.
+
+We desire the library to be capable of supporting all JPEG baseline, extended
+sequential, and progressive DCT processes. Hierarchical processes are not
+supported.
+
+The library does not support the lossless (spatial) JPEG process. Lossless
+JPEG shares little or no code with lossy JPEG, and would normally be used
+without the extensive pre- and post-processing provided by this library.
+We feel that lossless JPEG is better handled by a separate library.
+
+Within these limits, any set of compression parameters allowed by the JPEG
+spec should be readable for decompression. (We can be more restrictive about
+what formats we can generate.) Although the system design allows for all
+parameter values, some uncommon settings are not yet implemented and may
+never be; nonintegral sampling ratios are the prime example. Furthermore,
+we treat 8-bit vs. 12-bit data precision as a compile-time switch, not a
+run-time option, because most machines can store 8-bit pixels much more
+compactly than 12-bit.
+
+For legal reasons, JPEG arithmetic coding is not currently supported, but
+extending the library to include it would be straightforward.
+
+By itself, the library handles only interchange JPEG datastreams --- in
+particular the widely used JFIF file format. The library can be used by
+surrounding code to process interchange or abbreviated JPEG datastreams that
+are embedded in more complex file formats. (For example, libtiff uses this
+library to implement JPEG compression within the TIFF file format.)
+
+The library includes a substantial amount of code that is not covered by the
+JPEG standard but is necessary for typical applications of JPEG. These
+functions preprocess the image before JPEG compression or postprocess it after
+decompression. They include colorspace conversion, downsampling/upsampling,
+and color quantization. This code can be omitted if not needed.
+
+A wide range of quality vs. speed tradeoffs are possible in JPEG processing,
+and even more so in decompression postprocessing. The decompression library
+provides multiple implementations that cover most of the useful tradeoffs,
+ranging from very-high-quality down to fast-preview operation. On the
+compression side we have generally not provided low-quality choices, since
+compression is normally less time-critical. It should be understood that the
+low-quality modes may not meet the JPEG standard's accuracy requirements;
+nonetheless, they are useful for viewers.
+
+
+*** Portability issues ***
+
+Portability is an essential requirement for the library. The key portability
+issues that show up at the level of system architecture are:
+
+1. Memory usage. We want the code to be able to run on PC-class machines
+with limited memory. Images should therefore be processed sequentially (in
+strips), to avoid holding the whole image in memory at once. Where a
+full-image buffer is necessary, we should be able to use either virtual memory
+or temporary files.
+
+2. Near/far pointer distinction. To run efficiently on 80x86 machines, the
+code should distinguish "small" objects (kept in near data space) from
+"large" ones (kept in far data space). This is an annoying restriction, but
+fortunately it does not impact code quality for less brain-damaged machines,
+and the source code clutter turns out to be minimal with sufficient use of
+pointer typedefs.
+
+3. Data precision. We assume that "char" is at least 8 bits, "short" and
+"int" at least 16, "long" at least 32. The code will work fine with larger
+data sizes, although memory may be used inefficiently in some cases. However,
+the JPEG compressed datastream must ultimately appear on external storage as a
+sequence of 8-bit bytes if it is to conform to the standard. This may pose a
+problem on machines where char is wider than 8 bits. The library represents
+compressed data as an array of values of typedef JOCTET. If no data type
+exactly 8 bits wide is available, custom data source and data destination
+modules must be written to unpack and pack the chosen JOCTET datatype into
+8-bit external representation.
+
+
+*** System overview ***
+
+The compressor and decompressor are each divided into two main sections:
+the JPEG compressor or decompressor proper, and the preprocessing or
+postprocessing functions. The interface between these two sections is the
+image data that the official JPEG spec regards as its input or output: this
+data is in the colorspace to be used for compression, and it is downsampled
+to the sampling factors to be used. The preprocessing and postprocessing
+steps are responsible for converting a normal image representation to or from
+this form. (Those few applications that want to deal with YCbCr downsampled
+data can skip the preprocessing or postprocessing step.)
+
+Looking more closely, the compressor library tqcontains the following main
+elements:
+
+ Preprocessing:
+ * Color space conversion (e.g., RGB to YCbCr).
+ * Edge expansion and downsampling. Optionally, this step can do simple
+ smoothing --- this is often helpful for low-quality source data.
+ JPEG proper:
+ * MCU assembly, DCT, quantization.
+ * Entropy coding (sequential or progressive, Huffman or arithmetic).
+
+In addition to these modules we need overall control, marker generation,
+and support code (memory management & error handling). There is also a
+module responsible for physically writing the output data --- typically
+this is just an interface to fwrite(), but some applications may need to
+do something else with the data.
+
+The decompressor library tqcontains the following main elements:
+
+ JPEG proper:
+ * Entropy decoding (sequential or progressive, Huffman or arithmetic).
+ * Dequantization, inverse DCT, MCU disassembly.
+ Postprocessing:
+ * Upsampling. Optionally, this step may be able to do more general
+ rescaling of the image.
+ * Color space conversion (e.g., YCbCr to RGB). This step may also
+ provide gamma adjustment [ currently it does not ].
+ * Optional color quantization (e.g., reduction to 256 colors).
+ * Optional color precision reduction (e.g., 24-bit to 15-bit color).
+ [This feature is not currently implemented.]
+
+We also need overall control, marker parsing, and a data source module.
+The support code (memory management & error handling) can be shared with
+the compression half of the library.
+
+There may be several implementations of each of these elements, particularly
+in the decompressor, where a wide range of speed/quality tradeoffs is very
+useful. It must be understood that some of the best speedups involve
+merging adjacent steps in the pipeline. For example, upsampling, color space
+conversion, and color quantization might all be done at once when using a
+low-quality ordered-dither technique. The system architecture is designed to
+allow such merging where appropriate.
+
+
+Note: it is convenient to regard edge expansion (padding to block boundaries)
+as a preprocessing/postprocessing function, even though the JPEG spec includes
+it in compression/decompression. We do this because downsampling/upsampling
+can be simplified a little if they work on padded data: it's not necessary to
+have special cases at the right and bottom edges. Therefore the interface
+buffer is always an integral number of blocks wide and high, and we expect
+compression preprocessing to pad the source data properly. Padding will occur
+only to the next block (8-sample) boundary. In an interleaved-scan situation,
+additional dummy blocks may be used to fill out MCUs, but the MCU assembly and
+disassembly logic will create or discard these blocks internally. (This is
+advantageous for speed reasons, since we avoid DCTing the dummy blocks.
+It also permits a small reduction in file size, because the compressor can
+choose dummy block contents so as to minimize their size in compressed form.
+Finally, it makes the interface buffer specification independent of whether
+the file is actually interleaved or not.) Applications that wish to deal
+directly with the downsampled data must provide similar buffering and padding
+for odd-sized images.
+
+
+*** Poor man's object-oriented programming ***
+
+It should be clear by now that we have a lot of quasi-independent processing
+steps, many of which have several possible behaviors. To avoid cluttering the
+code with lots of switch statements, we use a simple form of object-style
+programming to separate out the different possibilities.
+
+For example, two different color quantization algorithms could be implemented
+as two separate modules that present the same external interface; at runtime,
+the calling code will access the proper module indirectly through an "object".
+
+We can get the limited features we need while staying within portable C.
+The basic tool is a function pointer. An "object" is just a struct
+containing one or more function pointer fields, each of which corresponds to
+a method name in real object-oriented languages. During initialization we
+fill in the function pointers with references to whichever module we have
+determined we need to use in this run. Then invocation of the module is done
+by indirecting through a function pointer; on most machines this is no more
+expensive than a switch statement, which would be the only other way of
+making the required run-time choice. The really significant benefit, of
+course, is keeping the source code clean and well structured.
+
+We can also arrange to have private storage that varies between different
+implementations of the same kind of object. We do this by making all the
+module-specific object structs be separately allocated entities, which will
+be accessed via pointers in the master compression or decompression struct.
+The "public" fields or methods for a given kind of object are specified by
+a commonly known struct. But a module's initialization code can allocate
+a larger struct that tqcontains the common struct as its first member, plus
+additional private fields. With appropriate pointer casting, the module's
+internal functions can access these private fields. (For a simple example,
+see jdatadst.c, which implements the external interface specified by struct
+jpeg_destination_mgr, but adds extra fields.)
+
+(Of course this would all be a lot easier if we were using C++, but we are
+not yet prepared to assume that everyone has a C++ compiler.)
+
+An important benefit of this scheme is that it is easy to provide multiple
+versions of any method, each tuned to a particular case. While a lot of
+precalculation might be done to select an optimal implementation of a method,
+the cost per invocation is constant. For example, the upsampling step might
+have a "generic" method, plus one or more "hardwired" methods for the most
+popular sampling factors; the hardwired methods would be faster because they'd
+use straight-line code instead of for-loops. The cost to determine which
+method to use is paid only once, at startup, and the selection criteria are
+hidden from the callers of the method.
+
+This plan differs a little bit from usual object-oriented structures, in that
+only one instance of each object class will exist during execution. The
+reason for having the class structure is that on different runs we may create
+different instances (choose to execute different modules). You can think of
+the term "method" as denoting the common interface presented by a particular
+set of interchangeable functions, and "object" as denoting a group of related
+methods, or the total shared interface behavior of a group of modules.
+
+
+*** Overall control structure ***
+
+We previously mentioned the need for overall control logic in the compression
+and decompression libraries. In IJG implementations prior to v5, overall
+control was mostly provided by "pipeline control" modules, which proved to be
+large, unwieldy, and hard to understand. To improve the situation, the
+control logic has been subdivided into multiple modules. The control modules
+consist of:
+
+1. Master control for module selection and initialization. This has two
+responsibilities:
+
+ 1A. Startup initialization at the beginning of image processing.
+ The individual processing modules to be used in this run are selected
+ and given initialization calls.
+
+ 1B. Per-pass control. This determines how many passes will be performed
+ and calls each active processing module to configure itself
+ appropriately at the beginning of each pass. End-of-pass processing,
+ where necessary, is also invoked from the master control module.
+
+ Method selection is partially distributed, in that a particular processing
+ module may contain several possible implementations of a particular method,
+ which it will select among when given its initialization call. The master
+ control code need only be concerned with decisions that affect more than
+ one module.
+
+2. Data buffering control. A separate control module exists for each
+ inter-processing-step data buffer. This module is responsible for
+ invoking the processing steps that write or read that data buffer.
+
+Each buffer controller sees the world as follows:
+
+input data => processing step A => buffer => processing step B => output data
+ | | |
+ ------------------ controller ------------------
+
+The controller knows the dataflow requirements of steps A and B: how much data
+they want to accept in one chunk and how much they output in one chunk. Its
+function is to manage its buffer and call A and B at the proper times.
+
+A data buffer control module may itself be viewed as a processing step by a
+higher-level control module; thus the control modules form a binary tree with
+elementary processing steps at the leaves of the tree.
+
+The control modules are objects. A considerable amount of flexibility can
+be had by replacing implementations of a control module. For example:
+* Merging of adjacent steps in the pipeline is done by replacing a control
+ module and its pair of processing-step modules with a single processing-
+ step module. (Hence the possible merges are determined by the tree of
+ control modules.)
+* In some processing modes, a given interstep buffer need only be a "strip"
+ buffer large enough to accommodate the desired data chunk sizes. In other
+ modes, a full-image buffer is needed and several passes are required.
+ The control module determines which kind of buffer is used and manipulates
+ virtual array buffers as needed. One or both processing steps may be
+ unaware of the multi-pass behavior.
+
+In theory, we might be able to make all of the data buffer controllers
+interchangeable and provide just one set of implementations for all. In
+practice, each one tqcontains considerable special-case processing for its
+particular job. The buffer controller concept should be regarded as an
+overall system structuring principle, not as a complete description of the
+task performed by any one controller.
+
+
+*** Compression object structure ***
+
+Here is a sketch of the logical structure of the JPEG compression library:
+
+ |-- Colorspace conversion
+ |-- Preprocessing controller --|
+ | |-- Downsampling
+Main controller --|
+ | |-- Forward DCT, quantize
+ |-- Coefficient controller --|
+ |-- Entropy encoding
+
+This sketch also describes the flow of control (subroutine calls) during
+typical image data processing. Each of the components shown in the diagram is
+an "object" which may have several different implementations available. One
+or more source code files contain the actual implementation(s) of each object.
+
+The objects shown above are:
+
+* Main controller: buffer controller for the subsampled-data buffer, which
+ holds the preprocessed input data. This controller invokes preprocessing to
+ fill the subsampled-data buffer, and JPEG compression to empty it. There is
+ usually no need for a full-image buffer here; a strip buffer is adequate.
+
+* Preprocessing controller: buffer controller for the downsampling input data
+ buffer, which lies between colorspace conversion and downsampling. Note
+ that a unified conversion/downsampling module would probably tqreplace this
+ controller entirely.
+
+* Colorspace conversion: converts application image data into the desired
+ JPEG color space; also changes the data from pixel-interleaved tqlayout to
+ separate component planes. Processes one pixel row at a time.
+
+* Downsampling: performs reduction of chroma components as required.
+ Optionally may perform pixel-level smoothing as well. Processes a "row
+ group" at a time, where a row group is defined as Vmax pixel rows of each
+ component before downsampling, and Vk sample rows afterwards (remember Vk
+ differs across components). Some downsampling or smoothing algorithms may
+ require context rows above and below the current row group; the
+ preprocessing controller is responsible for supplying these rows via proper
+ buffering. The downsampler is responsible for edge expansion at the right
+ edge (i.e., extending each sample row to a multiple of 8 samples); but the
+ preprocessing controller is responsible for vertical edge expansion (i.e.,
+ duplicating the bottom sample row as needed to make a multiple of 8 rows).
+
+* Coefficient controller: buffer controller for the DCT-coefficient data.
+ This controller handles MCU assembly, including insertion of dummy DCT
+ blocks when needed at the right or bottom edge. When performing
+ Huffman-code optimization or emitting a multiscan JPEG file, this
+ controller is responsible for buffering the full image. The equivalent of
+ one fully interleaved MCU row of subsampled data is processed per call,
+ even when the JPEG file is noninterleaved.
+
+* Forward DCT and quantization: Perform DCT, quantize, and emit coefficients.
+ Works on one or more DCT blocks at a time. (Note: the coefficients are now
+ emitted in normal array order, which the entropy encoder is expected to
+ convert to zigzag order as necessary. Prior versions of the IJG code did
+ the conversion to zigzag order within the quantization step.)
+
+* Entropy encoding: Perform Huffman or arithmetic entropy coding and emit the
+ coded data to the data destination module. Works on one MCU per call.
+ For progressive JPEG, the same DCT blocks are fed to the entropy coder
+ during each pass, and the coder must emit the appropriate subset of
+ coefficients.
+
+In addition to the above objects, the compression library includes these
+objects:
+
+* Master control: determines the number of passes required, controls overall
+ and per-pass initialization of the other modules.
+
+* Marker writing: generates JPEG markers (except for RSTn, which is emitted
+ by the entropy encoder when needed).
+
+* Data destination manager: writes the output JPEG datastream to its final
+ destination (e.g., a file). The destination manager supplied with the
+ library knows how to write to a stdio stream; for other behaviors, the
+ surrounding application may provide its own destination manager.
+
+* Memory manager: allocates and releases memory, controls virtual arrays
+ (with backing store management, where required).
+
+* Error handler: performs formatting and output of error and trace messages;
+ determines handling of nonfatal errors. The surrounding application may
+ override some or all of this object's methods to change error handling.
+
+* Progress monitor: supports output of "percent-done" progress reports.
+ This object represents an optional callback to the surrounding application:
+ if wanted, it must be supplied by the application.
+
+The error handler, destination manager, and progress monitor objects are
+defined as separate objects in order to simplify application-specific
+customization of the JPEG library. A surrounding application may override
+individual methods or supply its own all-new implementation of one of these
+objects. The object interfaces for these objects are therefore treated as
+part of the application interface of the library, whereas the other objects
+are internal to the library.
+
+The error handler and memory manager are shared by JPEG compression and
+decompression; the progress monitor, if used, may be shared as well.
+
+
+*** Decompression object structure ***
+
+Here is a sketch of the logical structure of the JPEG decompression library:
+
+ |-- Entropy decoding
+ |-- Coefficient controller --|
+ | |-- Dequantize, Inverse DCT
+Main controller --|
+ | |-- Upsampling
+ |-- Postprocessing controller --| |-- Colorspace conversion
+ |-- Color quantization
+ |-- Color precision reduction
+
+As before, this diagram also represents typical control flow. The objects
+shown are:
+
+* Main controller: buffer controller for the subsampled-data buffer, which
+ holds the output of JPEG decompression proper. This controller's primary
+ task is to feed the postprocessing procedure. Some upsampling algorithms
+ may require context rows above and below the current row group; when this
+ is true, the main controller is responsible for managing its buffer so as
+ to make context rows available. In the current design, the main buffer is
+ always a strip buffer; a full-image buffer is never required.
+
+* Coefficient controller: buffer controller for the DCT-coefficient data.
+ This controller handles MCU disassembly, including deletion of any dummy
+ DCT blocks at the right or bottom edge. When reading a multiscan JPEG
+ file, this controller is responsible for buffering the full image.
+ (Buffering DCT coefficients, rather than samples, is necessary to support
+ progressive JPEG.) The equivalent of one fully interleaved MCU row of
+ subsampled data is processed per call, even when the source JPEG file is
+ noninterleaved.
+
+* Entropy decoding: Read coded data from the data source module and perform
+ Huffman or arithmetic entropy decoding. Works on one MCU per call.
+ For progressive JPEG decoding, the coefficient controller supplies the prior
+ coefficients of each MCU (initially all zeroes), which the entropy decoder
+ modifies in each scan.
+
+* Dequantization and inverse DCT: like it says. Note that the coefficients
+ buffered by the coefficient controller have NOT been dequantized; we
+ merge dequantization and inverse DCT into a single step for speed reasons.
+ When scaled-down output is asked for, simplified DCT algorithms may be used
+ that emit only 1x1, 2x2, or 4x4 samples per DCT block, not the full 8x8.
+ Works on one DCT block at a time.
+
+* Postprocessing controller: buffer controller for the color quantization
+ input buffer, when quantization is in use. (Without quantization, this
+ controller just calls the upsampler.) For two-pass quantization, this
+ controller is responsible for buffering the full-image data.
+
+* Upsampling: restores chroma components to full size. (May support more
+ general output rescaling, too. Note that if undersized DCT outputs have
+ been emitted by the DCT module, this module must adjust so that properly
+ sized outputs are created.) Works on one row group at a time. This module
+ also calls the color conversion module, so its top level is effectively a
+ buffer controller for the upsampling->color conversion buffer. However, in
+ all but the highest-quality operating modes, upsampling and color
+ conversion are likely to be merged into a single step.
+
+* Colorspace conversion: convert from JPEG color space to output color space,
+ and change data tqlayout from separate component planes to pixel-interleaved.
+ Works on one pixel row at a time.
+
+* Color quantization: reduce the data to colormapped form, using either an
+ externally specified colormap or an internally generated one. This module
+ is not used for full-color output. Works on one pixel row at a time; may
+ require two passes to generate a color map. Note that the output will
+ always be a single component representing colormap indexes. In the current
+ design, the output values are JSAMPLEs, so an 8-bit compilation cannot
+ quantize to more than 256 colors. This is unlikely to be a problem in
+ practice.
+
+* Color reduction: this module handles color precision reduction, e.g.,
+ generating 15-bit color (5 bits/primary) from JPEG's 24-bit output.
+ Not quite clear yet how this should be handled... should we merge it with
+ colorspace conversion???
+
+Note that some high-speed operating modes might condense the entire
+postprocessing sequence to a single module (upsample, color convert, and
+quantize in one step).
+
+In addition to the above objects, the decompression library includes these
+objects:
+
+* Master control: determines the number of passes required, controls overall
+ and per-pass initialization of the other modules. This is subdivided into
+ input and output control: jdinput.c controls only input-side processing,
+ while jdmaster.c handles overall initialization and output-side control.
+
+* Marker reading: decodes JPEG markers (except for RSTn).
+
+* Data source manager: supplies the input JPEG datastream. The source
+ manager supplied with the library knows how to read from a stdio stream;
+ for other behaviors, the surrounding application may provide its own source
+ manager.
+
+* Memory manager: same as for compression library.
+
+* Error handler: same as for compression library.
+
+* Progress monitor: same as for compression library.
+
+As with compression, the data source manager, error handler, and progress
+monitor are candidates for tqreplacement by a surrounding application.
+
+
+*** Decompression input and output separation ***
+
+To support efficient incremental display of progressive JPEG files, the
+decompressor is divided into two sections that can run independently:
+
+1. Data input includes marker parsing, entropy decoding, and input into the
+ coefficient controller's DCT coefficient buffer. Note that this
+ processing is relatively cheap and fast.
+
+2. Data output reads from the DCT coefficient buffer and performs the IDCT
+ and all postprocessing steps.
+
+For a progressive JPEG file, the data input processing is allowed to get
+arbitrarily far ahead of the data output processing. (This occurs only
+if the application calls jpeg_consume_input(); otherwise input and output
+run in lockstep, since the input section is called only when the output
+section needs more data.) In this way the application can avoid making
+extra display passes when data is arriving faster than the display pass
+can run. Furthermore, it is possible to abort an output pass without
+losing anything, since the coefficient buffer is read-only as far as the
+output section is concerned. See libjpeg.doc for more detail.
+
+A full-image coefficient array is only created if the JPEG file has multiple
+scans (or if the application specifies buffered-image mode anyway). When
+reading a single-scan file, the coefficient controller normally creates only
+a one-MCU buffer, so input and output processing must run in lockstep in this
+case. jpeg_consume_input() is effectively a no-op in this situation.
+
+The main impact of dividing the decompressor in this fashion is that we must
+be very careful with shared variables in the cinfo data structure. Each
+variable that can change during the course of decompression must be
+classified as belonging to data input or data output, and each section must
+look only at its own variables. For example, the data output section may not
+depend on any of the variables that describe the current scan in the JPEG
+file, because these may change as the data input section advances into a new
+scan.
+
+The progress monitor is (somewhat arbitrarily) defined to treat input of the
+file as one pass when buffered-image mode is not used, and to ignore data
+input work completely when buffered-image mode is used. Note that the
+library has no reliable way to predict the number of passes when dealing
+with a progressive JPEG file, nor can it predict the number of output passes
+in buffered-image mode. So the work estimate is inherently bogus anyway.
+
+No comparable division is currently made in the compression library, because
+there isn't any real need for it.
+
+
+*** Data formats ***
+
+Arrays of pixel sample values use the following data structure:
+
+ typedef something JSAMPLE; a pixel component value, 0..MAXJSAMPLE
+ typedef JSAMPLE *JSAMPROW; ptr to a row of samples
+ typedef JSAMPROW *JSAMPARRAY; ptr to a list of rows
+ typedef JSAMPARRAY *JSAMPIMAGE; ptr to a list of color-component arrays
+
+The basic element type JSAMPLE will typically be one of unsigned char,
+(signed) char, or short. Short will be used if samples wider than 8 bits are
+to be supported (this is a compile-time option). Otherwise, unsigned char is
+used if possible. If the compiler only supports signed chars, then it is
+necessary to tqmask off the value when reading. Thus, all reads of JSAMPLE
+values must be coded as "GETJSAMPLE(value)", where the macro will be defined
+as "((value) & 0xFF)" on signed-char machines and "((int) (value))" elsewhere.
+
+With these conventions, JSAMPLE values can be assumed to be >= 0. This helps
+simplify correct rounding during downsampling, etc. The JPEG standard's
+specification that sample values run from -128..127 is accommodated by
+subtracting 128 just as the sample value is copied into the source array for
+the DCT step (this will be an array of signed ints). Similarly, during
+decompression the output of the IDCT step will be immediately shifted back to
+0..255. (NB: different values are required when 12-bit samples are in use.
+The code is written in terms of MAXJSAMPLE and CENTERJSAMPLE, which will be
+defined as 255 and 128 respectively in an 8-bit implementation, and as 4095
+and 2048 in a 12-bit implementation.)
+
+We use a pointer per row, rather than a two-dimensional JSAMPLE array. This
+choice costs only a small amount of memory and has several benefits:
+* Code using the data structure doesn't need to know the allocated width of
+ the rows. This simplifies edge expansion/compression, since we can work
+ in an array that's wider than the logical picture width.
+* Indexing doesn't require multiplication; this is a performance win on many
+ machines.
+* Arrays with more than 64K total elements can be supported even on machines
+ where malloc() cannot allocate chunks larger than 64K.
+* The rows forming a component array may be allocated at different times
+ without extra copying. This trick allows some speedups in smoothing steps
+ that need access to the previous and next rows.
+
+Note that each color component is stored in a separate array; we don't use the
+traditional tqlayout in which the components of a pixel are stored together.
+This simplifies coding of modules that work on each component independently,
+because they don't need to know how many components there are. Furthermore,
+we can read or write each component to a temporary file independently, which
+is helpful when dealing with noninterleaved JPEG files.
+
+In general, a specific sample value is accessed by code such as
+ GETJSAMPLE(image[colorcomponent][row][col])
+where col is measured from the image left edge, but row is measured from the
+first sample row currently in memory. Either of the first two indexings can
+be precomputed by copying the relevant pointer.
+
+
+Since most image-processing applications prefer to work on images in which
+the components of a pixel are stored together, the data passed to or from the
+surrounding application uses the traditional convention: a single pixel is
+represented by N consecutive JSAMPLE values, and an image row is an array of
+(# of color components)*(image width) JSAMPLEs. One or more rows of data can
+be represented by a pointer of type JSAMPARRAY in this scheme. This scheme is
+converted to component-wise storage inside the JPEG library. (Applications
+that want to skip JPEG preprocessing or postprocessing will have to contend
+with component-wise storage.)
+
+
+Arrays of DCT-coefficient values use the following data structure:
+
+ typedef short JCOEF; a 16-bit signed integer
+ typedef JCOEF JBLOCK[DCTSIZE2]; an 8x8 block of coefficients
+ typedef JBLOCK *JBLOCKROW; ptr to one horizontal row of 8x8 blocks
+ typedef JBLOCKROW *JBLOCKARRAY; ptr to a list of such rows
+ typedef JBLOCKARRAY *JBLOCKIMAGE; ptr to a list of color component arrays
+
+The underlying type is at least a 16-bit signed integer; while "short" is big
+enough on all machines of interest, on some machines it is preferable to use
+"int" for speed reasons, despite the storage cost. Coefficients are grouped
+into 8x8 blocks (but we always use #defines DCTSIZE and DCTSIZE2 rather than
+"8" and "64").
+
+The contents of a coefficient block may be in either "natural" or zigzagged
+order, and may be true values or divided by the quantization coefficients,
+depending on where the block is in the processing pipeline. In the current
+library, coefficient blocks are kept in natural order everywhere; the entropy
+codecs zigzag or dezigzag the data as it is written or read. The blocks
+contain quantized coefficients everywhere outside the DCT/IDCT subsystems.
+(This latter decision may need to be revisited to support variable
+quantization a la JPEG Part 3.)
+
+Notice that the allocation unit is now a row of 8x8 blocks, corresponding to
+eight rows of samples. Otherwise the structure is much the same as for
+samples, and for the same reasons.
+
+On machines where malloc() can't handle a request bigger than 64Kb, this data
+structure limits us to rows of less than 512 JBLOCKs, or a picture width of
+4000+ pixels. This seems an acceptable restriction.
+
+
+On 80x86 machines, the bottom-level pointer types (JSAMPROW and JBLOCKROW)
+must be declared as "far" pointers, but the upper levels can be "near"
+(implying that the pointer lists are allocated in the DS segment).
+We use a #define symbol FAR, which expands to the "far" keyword when
+compiling on 80x86 machines and to nothing elsewhere.
+
+
+*** Suspendable processing ***
+
+In some applications it is desirable to use the JPEG library as an
+incremental, memory-to-memory filter. In this situation the data source or
+destination may be a limited-size buffer, and we can't rely on being able to
+empty or refill the buffer at arbitrary times. Instead the application would
+like to have control return from the library at buffer overflow/underrun, and
+then resume compression or decompression at a later time.
+
+This scenario is supported for simple cases. (For anything more complex, we
+recommend that the application "bite the bullet" and develop real multitasking
+capability.) The libjpeg.doc file goes into more detail about the usage and
+limitations of this capability; here we address the implications for library
+structure.
+
+The essence of the problem is that the entropy codec (coder or decoder) must
+be prepared to stop at arbitrary times. In turn, the controllers that call
+the entropy codec must be able to stop before having produced or consumed all
+the data that they normally would handle in one call. That part is reasonably
+straightforward: we make the controller call interfaces include "progress
+counters" which indicate the number of data chunks successfully processed, and
+we require callers to test the counter rather than just assume all of the data
+was processed.
+
+Rather than trying to restart at an arbitrary point, the current Huffman
+codecs are designed to restart at the beginning of the current MCU after a
+suspension due to buffer overflow/underrun. At the start of each call, the
+codec's internal state is loaded from permanent storage (in the JPEG object
+structures) into local variables. On successful completion of the MCU, the
+permanent state is updated. (This copying is not very expensive, and may even
+lead to *improved* performance if the local variables can be registerized.)
+If a suspension occurs, the codec simply returns without updating the state,
+thus effectively reverting to the start of the MCU. Note that this implies
+leaving some data unprocessed in the source/destination buffer (ie, the
+compressed partial MCU). The data source/destination module interfaces are
+specified so as to make this possible. This also implies that the data buffer
+must be large enough to hold a worst-case compressed MCU; a couple thousand
+bytes should be enough.
+
+In a successive-approximation AC refinement scan, the progressive Huffman
+decoder has to be able to undo assignments of newly nonzero coefficients if it
+suspends before the MCU is complete, since decoding requires distinguishing
+previously-zero and previously-nonzero coefficients. This is a bit tedious
+but probably won't have much effect on performance. Other variants of Huffman
+decoding need not worry about this, since they will just store the same values
+again if forced to repeat the MCU.
+
+This approach would probably not work for an arithmetic codec, since its
+modifiable state is quite large and couldn't be copied cheaply. Instead it
+would have to suspend and resume exactly at the point of the buffer end.
+
+The JPEG marker reader is designed to cope with suspension at an arbitrary
+point. It does so by backing up to the start of the marker parameter segment,
+so the data buffer must be big enough to hold the largest marker of interest.
+Again, a couple KB should be adequate. (A special "skip" convention is used
+to bypass COM and APPn markers, so these can be larger than the buffer size
+without causing problems; otherwise a 64K buffer would be needed in the worst
+case.)
+
+The JPEG marker writer currently does *not* cope with suspension. I feel that
+this is not necessary; it is much easier simply to require the application to
+ensure there is enough buffer space before starting. (An empty 2K buffer is
+more than sufficient for the header markers; and ensuring there are a dozen or
+two bytes available before calling jpeg_finish_compress() will suffice for the
+trailer.) This would not work for writing multi-scan JPEG files, but
+we simply do not intend to support that capability with suspension.
+
+
+*** Memory manager services ***
+
+The JPEG library's memory manager controls allocation and deallocation of
+memory, and it manages large "virtual" data arrays on machines where the
+operating system does not provide virtual memory. Note that the same
+memory manager serves both compression and decompression operations.
+
+In all cases, allocated objects are tied to a particular compression or
+decompression master record, and they will be released when that master
+record is destroyed.
+
+The memory manager does not provide explicit deallocation of objects.
+Instead, objects are created in "pools" of free storage, and a whole pool
+can be freed at once. This approach helps prevent storage-leak bugs, and
+it speeds up operations whenever malloc/free are slow (as they often are).
+The pools can be regarded as lifetime identifiers for objects. Two
+pools/lifetimes are defined:
+ * JPOOL_PERMANENT lasts until master record is destroyed
+ * JPOOL_IMAGE lasts until done with image (JPEG datastream)
+Permanent lifetime is used for parameters and tables that should be carried
+across from one datastream to another; this includes all application-visible
+parameters. Image lifetime is used for everything else. (A third lifetime,
+JPOOL_PASS = one processing pass, was originally planned. However it was
+dropped as not being worthwhile. The actual usage patterns are such that the
+peak memory usage would be about the same anyway; and having per-pass storage
+substantially complicates the virtual memory allocation rules --- see below.)
+
+The memory manager deals with three kinds of object:
+1. "Small" objects. Typically these require no more than 10K-20K total.
+2. "Large" objects. These may require tens to hundreds of K depending on
+ image size. Semantically they behave the same as small objects, but we
+ distinguish them for two reasons:
+ * On MS-DOS machines, large objects are referenced by FAR pointers,
+ small objects by NEAR pointers.
+ * Pool allocation heuristics may differ for large and small objects.
+ Note that individual "large" objects cannot exceed the size allowed by
+ type size_t, which may be 64K or less on some machines.
+3. "Virtual" objects. These are large 2-D arrays of JSAMPLEs or JBLOCKs
+ (typically large enough for the entire image being processed). The
+ memory manager provides stripwise access to these arrays. On machines
+ without virtual memory, the rest of the array may be swapped out to a
+ temporary file.
+
+(Note: JSAMPARRAY and JBLOCKARRAY data structures are a combination of large
+objects for the data proper and small objects for the row pointers. For
+convenience and speed, the memory manager provides single routines to create
+these structures. Similarly, virtual arrays include a small control block
+and a JSAMPARRAY or JBLOCKARRAY working buffer, all created with one call.)
+
+In the present implementation, virtual arrays are only permitted to have image
+lifespan. (Permanent lifespan would not be reasonable, and pass lifespan is
+not very useful since a virtual array's raison d'etre is to store data for
+multiple passes through the image.) We also expect that only "small" objects
+will be given permanent lifespan, though this restriction is not required by
+the memory manager.
+
+In a non-virtual-memory machine, some performance benefit can be gained by
+making the in-memory buffers for virtual arrays be as large as possible.
+(For small images, the buffers might fit entirely in memory, so blind
+swapping would be very wasteful.) The memory manager will adjust the height
+of the buffers to fit within a prespecified maximum memory usage. In order
+to do this in a reasonably optimal fashion, the manager needs to allocate all
+of the virtual arrays at once. Therefore, there isn't a one-step allocation
+routine for virtual arrays; instead, there is a "request" routine that simply
+allocates the control block, and a "realize" routine (called just once) that
+determines space allocation and creates all of the actual buffers. The
+realize routine must allow for space occupied by non-virtual large objects.
+(We don't bother to factor in the space needed for small objects, on the
+grounds that it isn't worth the trouble.)
+
+To support all this, we establish the following protocol for doing business
+with the memory manager:
+ 1. Modules must request virtual arrays (which may have only image lifespan)
+ during the initial setup phase, i.e., in their jinit_xxx routines.
+ 2. All "large" objects (including JSAMPARRAYs and JBLOCKARRAYs) must also be
+ allocated during initial setup.
+ 3. realize_virt_arrays will be called at the completion of initial setup.
+ The above conventions ensure that sufficient information is available
+ for it to choose a good size for virtual array buffers.
+Small objects of any lifespan may be allocated at any time. We expect that
+the total space used for small objects will be small enough to be negligible
+in the realize_virt_arrays computation.
+
+In a virtual-memory machine, we simply pretend that the available space is
+infinite, thus causing realize_virt_arrays to decide that it can allocate all
+the virtual arrays as full-size in-memory buffers. The overhead of the
+virtual-array access protocol is very small when no swapping occurs.
+
+A virtual array can be specified to be "pre-zeroed"; when this flag is set,
+never-yet-written sections of the array are set to zero before being made
+available to the caller. If this flag is not set, never-written sections
+of the array contain garbage. (This feature exists primarily because the
+equivalent logic would otherwise be needed in jdcoefct.c for progressive
+JPEG mode; we may as well make it available for possible other uses.)
+
+The first write pass on a virtual array is required to occur in top-to-bottom
+order; read passes, as well as any write passes after the first one, may
+access the array in any order. This restriction exists partly to simplify
+the virtual array control logic, and partly because some file systems may not
+support seeking beyond the current end-of-file in a temporary file. The main
+implication of this restriction is that rearrangement of rows (such as
+converting top-to-bottom data order to bottom-to-top) must be handled while
+reading data out of the virtual array, not while putting it in.
+
+
+*** Memory manager internal structure ***
+
+To isolate system dependencies as much as possible, we have broken the
+memory manager into two parts. There is a reasonably system-independent
+"front end" (jmemmgr.c) and a "back end" that tqcontains only the code
+likely to change across systems. All of the memory management methods
+outlined above are implemented by the front end. The back end provides
+the following routines for use by the front end (none of these routines
+are known to the rest of the JPEG code):
+
+jpeg_mem_init, jpeg_mem_term system-dependent initialization/shutdown
+
+jpeg_get_small, jpeg_free_small interface to malloc and free library routines
+ (or their equivalents)
+
+jpeg_get_large, jpeg_free_large interface to FAR malloc/free in MSDOS machines;
+ else usually the same as
+ jpeg_get_small/jpeg_free_small
+
+jpeg_mem_available estimate available memory
+
+jpeg_open_backing_store create a backing-store object
+
+read_backing_store, manipulate a backing-store object
+write_backing_store,
+close_backing_store
+
+On some systems there will be more than one type of backing-store object
+(specifically, in MS-DOS a backing store file might be an area of extended
+memory as well as a disk file). jpeg_open_backing_store is responsible for
+choosing how to implement a given object. The read/write/close routines
+are method pointers in the structure that describes a given object; this
+lets them be different for different object types.
+
+It may be necessary to ensure that backing store objects are explicitly
+released upon abnormal program termination. For example, MS-DOS won't free
+extended memory by itself. To support this, we will expect the main program
+or surrounding application to arrange to call self_destruct (typically via
+jpeg_destroy) upon abnormal termination. This may require a SIGINT signal
+handler or equivalent. We don't want to have the back end module install its
+own signal handler, because that would pre-empt the surrounding application's
+ability to control signal handling.
+
+The IJG distribution includes several memory manager back end implementations.
+Usually the same back end should be suitable for all applications on a given
+system, but it is possible for an application to supply its own back end at
+need.
+
+
+*** Implications of DNL marker ***
+
+Some JPEG files may use a DNL marker to postpone definition of the image
+height (this would be useful for a fax-like scanner's output, for instance).
+In these files the SOF marker claims the image height is 0, and you only
+tqfind out the true image height at the end of the first scan.
+
+We could read these files as follows:
+1. Upon seeing zero image height, tqreplace it by 65535 (the maximum allowed).
+2. When the DNL is found, update the image height in the global image
+ descriptor.
+This implies that control modules must avoid making copies of the image
+height, and must re-test for termination after each MCU row. This would
+be easy enough to do.
+
+In cases where image-size data structures are allocated, this approach will
+result in very inefficient use of virtual memory or much-larger-than-necessary
+temporary files. This seems acceptable for something that probably won't be a
+mainstream usage. People might have to forgo use of memory-hogging options
+(such as two-pass color quantization or noninterleaved JPEG files) if they
+want efficient conversion of such files. (One could improve efficiency by
+demanding a user-supplied upper bound for the height, less than 65536; in most
+cases it could be much less.)
+
+The standard also permits the SOF marker to overestimate the image height,
+with a DNL to give the true, smaller height at the end of the first scan.
+This would solve the space problems if the overestimate wasn't too great.
+However, it implies that you don't even know whether DNL will be used.
+
+This leads to a couple of very serious objections:
+1. Testing for a DNL marker must occur in the inner loop of the decompressor's
+ Huffman decoder; this implies a speed penalty whether the feature is used
+ or not.
+2. There is no way to hide the last-minute change in image height from an
+ application using the decoder. Thus *every* application using the IJG
+ library would suffer a complexity penalty whether it cared about DNL or
+ not.
+We currently do not support DNL because of these problems.
+
+A different approach is to insist that DNL-using files be preprocessed by a
+separate program that reads ahead to the DNL, then goes back and fixes the SOF
+marker. This is a much simpler solution and is probably far more efficient.
+Even if one wants piped input, buffering the first scan of the JPEG file needs
+a lot smaller temp file than is implied by the maximum-height method. For
+this approach we'd simply treat DNL as a no-op in the decompressor (at most,
+check that it matches the SOF image height).
+
+We will not worry about making the compressor capable of outputting DNL.
+Something similar to the first scheme above could be applied if anyone ever
+wants to make that work.
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/usage.doc b/tqtinterface/qt4/src/3rdparty/libjpeg/usage.doc
new file mode 100644
index 0000000..d3d63a6
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/usage.doc
@@ -0,0 +1,562 @@
+USAGE instructions for the Independent JPEG Group's JPEG software
+=================================================================
+
+This file describes usage of the JPEG conversion programs cjpeg and djpeg,
+as well as the utility programs jpegtran, rdjpgcom and wrjpgcom. (See
+the other documentation files if you wish to use the JPEG library within
+your own programs.)
+
+If you are on a Unix machine you may prefer to read the Unix-style manual
+pages in files cjpeg.1, djpeg.1, jpegtran.1, rdjpgcom.1, wrjpgcom.1.
+
+
+INTRODUCTION
+
+These programs implement JPEG image compression and decompression. JPEG
+(pronounced "jay-peg") is a standardized compression method for full-color
+and gray-scale images. JPEG is designed to handle "real-world" scenes,
+for example scanned photographs. Cartoons, line drawings, and other
+non-realistic images are not JPEG's strong suit; on that sort of material
+you may get poor image quality and/or little compression.
+
+JPEG is lossy, meaning that the output image is not necessarily identical to
+the input image. Hence you should not use JPEG if you have to have identical
+output bits. However, on typical real-world images, very good compression
+levels can be obtained with no visible change, and amazingly high compression
+is possible if you can tolerate a low-quality image. You can trade off image
+quality against file size by adjusting the compressor's "quality" setting.
+
+
+GENERAL USAGE
+
+We provide two programs, cjpeg to compress an image file into JPEG format,
+and djpeg to decompress a JPEG file back into a conventional image format.
+
+On Unix-like systems, you say:
+ cjpeg [switches] [imagefile] >jpegfile
+or
+ djpeg [switches] [jpegfile] >imagefile
+The programs read the specified input file, or standard input if none is
+named. They always write to standard output (with trace/error messages to
+standard error). These conventions are handy for piping images between
+programs.
+
+On most non-Unix systems, you say:
+ cjpeg [switches] imagefile jpegfile
+or
+ djpeg [switches] jpegfile imagefile
+i.e., both the input and output files are named on the command line. This
+style is a little more foolproof, and it loses no functionality if you don't
+have pipes. (You can get this style on Unix too, if you prefer, by defining
+TWO_FILE_COMMANDLINE when you compile the programs; see install.doc.)
+
+You can also say:
+ cjpeg [switches] -outfile jpegfile imagefile
+or
+ djpeg [switches] -outfile imagefile jpegfile
+This syntax works on all systems, so it is useful for scripts.
+
+The currently supported image file formats are: PPM (PBMPLUS color format),
+PGM (PBMPLUS gray-scale format), BMP, Targa, and RLE (Utah Raster Toolkit
+format). (RLE is supported only if the URT library is available.)
+cjpeg recognizes the input image format automatically, with the exception
+of some Targa-format files. You have to tell djpeg which format to generate.
+
+JPEG files are in the defacto standard JFIF file format. There are other,
+less widely used JPEG-based file formats, but we don't support them.
+
+All switch names may be abbreviated; for example, -grayscale may be written
+-gray or -gr. Most of the "basic" switches can be abbreviated to as little as
+one letter. Upper and lower case are equivalent (-BMP is the same as -bmp).
+British spellings are also accepted (e.g., -greyscale), though for brevity
+these are not mentioned below.
+
+
+CJPEG DETAILS
+
+The basic command line switches for cjpeg are:
+
+ -quality N Scale quantization tables to adjust image quality.
+ Quality is 0 (worst) to 100 (best); default is 75.
+ (See below for more info.)
+
+ -grayscale Create monochrome JPEG file from color input.
+ Be sure to use this switch when compressing a grayscale
+ BMP file, because cjpeg isn't bright enough to notice
+ whether a BMP file uses only shades of gray. By
+ saying -grayscale, you'll get a smaller JPEG file that
+ takes less time to process.
+
+ -optimize Perform optimization of entropy encoding parameters.
+ Without this, default encoding parameters are used.
+ -optimize usually makes the JPEG file a little smaller,
+ but cjpeg runs somewhat slower and needs much more
+ memory. Image quality and speed of decompression are
+ unaffected by -optimize.
+
+ -progressive Create progressive JPEG file (see below).
+
+ -targa Input file is Targa format. Targa files that contain
+ an "identification" field will not be automatically
+ recognized by cjpeg; for such files you must specify
+ -targa to make cjpeg treat the input as Targa format.
+ For most Targa files, you won't need this switch.
+
+The -quality switch lets you trade off compressed file size against quality of
+the reconstructed image: the higher the quality setting, the larger the JPEG
+file, and the closer the output image will be to the original input. Normally
+you want to use the lowest quality setting (smallest file) that decompresses
+into something visually indistinguishable from the original image. For this
+purpose the quality setting should be between 50 and 95; the default of 75 is
+often about right. If you see defects at -quality 75, then go up 5 or 10
+counts at a time until you are happy with the output image. (The optimal
+setting will vary from one image to another.)
+
+-quality 100 will generate a quantization table of all 1's, minimizing loss
+in the quantization step (but there is still information loss in subsampling,
+as well as roundoff error). This setting is mainly of interest for
+experimental purposes. Quality values above about 95 are NOT recommended for
+normal use; the compressed file size goes up dramatically for hardly any gain
+in output image quality.
+
+In the other direction, quality values below 50 will produce very small files
+of low image quality. Settings around 5 to 10 might be useful in preparing an
+index of a large image library, for example. Try -quality 2 (or so) for some
+amusing Cubist effects. (Note: quality values below about 25 generate 2-byte
+quantization tables, which are considered optional in the JPEG standard.
+cjpeg emits a warning message when you give such a quality value, because some
+other JPEG programs may be unable to decode the resulting file. Use -baseline
+if you need to ensure compatibility at low quality values.)
+
+The -progressive switch creates a "progressive JPEG" file. In this type of
+JPEG file, the data is stored in multiple scans of increasing quality. If the
+file is being transmitted over a slow communications link, the decoder can use
+the first scan to display a low-quality image very quickly, and can then
+improve the display with each subsequent scan. The final image is exactly
+equivalent to a standard JPEG file of the same quality setting, and the total
+file size is about the same --- often a little smaller. CAUTION: progressive
+JPEG is not yet widely implemented, so many decoders will be unable to view a
+progressive JPEG file at all.
+
+Switches for advanced users:
+
+ -dct int Use integer DCT method (default).
+ -dct fast Use fast integer DCT (less accurate).
+ -dct float Use floating-point DCT method.
+ The float method is very slightly more accurate than
+ the int method, but is much slower unless your machine
+ has very fast floating-point hardware. Also note that
+ results of the floating-point method may vary slightly
+ across machines, while the integer methods should give
+ the same results everywhere. The fast integer method
+ is much less accurate than the other two.
+
+ -restart N Emit a JPEG restart marker every N MCU rows, or every
+ N MCU blocks if "B" is attached to the number.
+ -restart 0 (the default) means no restart markers.
+
+ -smooth N Smooth the input image to eliminate dithering noise.
+ N, ranging from 1 to 100, indicates the strength of
+ smoothing. 0 (the default) means no smoothing.
+
+ -maxmemory N Set limit for amount of memory to use in processing
+ large images. Value is in thousands of bytes, or
+ millions of bytes if "M" is attached to the number.
+ For example, -max 4m selects 4000000 bytes. If more
+ space is needed, temporary files will be used.
+
+ -verbose Enable debug printout. More -v's give more printout.
+ or -debug Also, version information is printed at startup.
+
+The -restart option inserts extra markers that allow a JPEG decoder to
+resynchronize after a transmission error. Without restart markers, any damage
+to a compressed file will usually ruin the image from the point of the error
+to the end of the image; with restart markers, the damage is usually confined
+to the portion of the image up to the next restart marker. Of course, the
+restart markers occupy extra space. We recommend -restart 1 for images that
+will be transmitted across unreliable networks such as Usenet.
+
+The -smooth option filters the input to eliminate fine-scale noise. This is
+often useful when converting dithered images to JPEG: a moderate smoothing
+factor of 10 to 50 gets rid of dithering patterns in the input file, resulting
+in a smaller JPEG file and a better-looking image. Too large a smoothing
+factor will visibly blur the image, however.
+
+Switches for wizards:
+
+ -baseline Force baseline-compatible quantization tables to be
+ generated. This clamps quantization values to 8 bits
+ even at low quality settings. (This switch is poorly
+ named, since it does not ensure that the output is
+ actually baseline JPEG. For example, you can use
+ -baseline and -progressive together.)
+
+ -qtables file Use the quantization tables given in the specified
+ text file.
+
+ -qQ_SLOTS N[,...] Select which quantization table to use for each color
+ component.
+
+ -sample HxV[,...] Set JPEG sampling factors for each color component.
+
+ -scans file Use the scan script given in the specified text file.
+
+The "wizard" switches are intended for experimentation with JPEG. If you
+don't know what you are doing, DON'T USE THEM. These switches are documented
+further in the file wizard.doc.
+
+
+DJPEG DETAILS
+
+The basic command line switches for djpeg are:
+
+ -colors N Reduce image to at most N colors. This reduces the
+ or -quantize N number of colors used in the output image, so that it
+ can be displayed on a colormapped display or stored in
+ a colormapped file format. For example, if you have
+ an 8-bit display, you'd need to reduce to 256 or fewer
+ colors. (-colors is the recommended name, -quantize
+ is provided only for backwards compatibility.)
+
+ -fast Select recommended processing options for fast, low
+ quality output. (The default options are chosen for
+ highest quality output.) Currently, this is equivalent
+ to "-dct fast -nosmooth -onepass -dither ordered".
+
+ -grayscale Force gray-scale output even if JPEG file is color.
+ Useful for viewing on monochrome displays; also,
+ djpeg runs noticeably faster in this mode.
+
+ -scale M/N Scale the output image by a factor M/N. Currently
+ the scale factor must be 1/1, 1/2, 1/4, or 1/8.
+ Scaling is handy if the image is larger than your
+ screen; also, djpeg runs much faster when scaling
+ down the output.
+
+ -bmp Select BMP output format (Windows flavor). 8-bit
+ colormapped format is emitted if -colors or -grayscale
+ is specified, or if the JPEG file is gray-scale;
+ otherwise, 24-bit full-color format is emitted.
+
+ -gif Select GIF output format. Since GIF does not support
+ more than 256 colors, -colors 256 is assumed (unless
+ you specify a smaller number of colors). If you
+ specify -fast, the default number of colors is 216.
+
+ -os2 Select BMP output format (OS/2 1.x flavor). 8-bit
+ colormapped format is emitted if -colors or -grayscale
+ is specified, or if the JPEG file is gray-scale;
+ otherwise, 24-bit full-color format is emitted.
+
+ -pnm Select PBMPLUS (PPM/PGM) output format (this is the
+ default format). PGM is emitted if the JPEG file is
+ gray-scale or if -grayscale is specified; otherwise
+ PPM is emitted.
+
+ -rle Select RLE output format. (Requires URT library.)
+
+ -targa Select Targa output format. Gray-scale format is
+ emitted if the JPEG file is gray-scale or if
+ -grayscale is specified; otherwise, colormapped format
+ is emitted if -colors is specified; otherwise, 24-bit
+ full-color format is emitted.
+
+Switches for advanced users:
+
+ -dct int Use integer DCT method (default).
+ -dct fast Use fast integer DCT (less accurate).
+ -dct float Use floating-point DCT method.
+ The float method is very slightly more accurate than
+ the int method, but is much slower unless your machine
+ has very fast floating-point hardware. Also note that
+ results of the floating-point method may vary slightly
+ across machines, while the integer methods should give
+ the same results everywhere. The fast integer method
+ is much less accurate than the other two.
+
+ -dither fs Use Floyd-Steinberg dithering in color quantization.
+ -dither ordered Use ordered dithering in color quantization.
+ -dither none Do not use dithering in color quantization.
+ By default, Floyd-Steinberg dithering is applied when
+ quantizing colors; this is slow but usually produces
+ the best results. Ordered dither is a compromise
+ between speed and quality; no dithering is fast but
+ usually looks awful. Note that these switches have
+ no effect unless color quantization is being done.
+ Ordered dither is only available in -onepass mode.
+
+ -map FILE Quantize to the colors used in the specified image
+ file. This is useful for producing multiple files
+ with identical color maps, or for forcing a predefined
+ set of colors to be used. The FILE must be a GIF
+ or PPM file. This option overrides -colors and
+ -onepass.
+
+ -nosmooth Use a faster, lower-quality upsampling routine.
+
+ -onepass Use one-pass instead of two-pass color quantization.
+ The one-pass method is faster and needs less memory,
+ but it produces a lower-quality image. -onepass is
+ ignored unless you also say -colors N. Also,
+ the one-pass method is always used for gray-scale
+ output (the two-pass method is no improvement then).
+
+ -maxmemory N Set limit for amount of memory to use in processing
+ large images. Value is in thousands of bytes, or
+ millions of bytes if "M" is attached to the number.
+ For example, -max 4m selects 4000000 bytes. If more
+ space is needed, temporary files will be used.
+
+ -verbose Enable debug printout. More -v's give more printout.
+ or -debug Also, version information is printed at startup.
+
+
+HINTS FOR CJPEG
+
+Color GIF files are not the ideal input for JPEG; JPEG is really intended for
+compressing full-color (24-bit) images. In particular, don't try to convert
+cartoons, line drawings, and other images that have only a few distinct
+colors. GIF works great on these, JPEG does not. If you want to convert a
+GIF to JPEG, you should experiment with cjpeg's -quality and -smooth options
+to get a satisfactory conversion. -smooth 10 or so is often helpful.
+
+Avoid running an image through a series of JPEG compression/decompression
+cycles. Image quality loss will accumulate; after ten or so cycles the image
+may be noticeably worse than it was after one cycle. It's best to use a
+lossless format while manipulating an image, then convert to JPEG format when
+you are ready to file the image away.
+
+The -optimize option to cjpeg is worth using when you are making a "final"
+version for posting or archiving. It's also a win when you are using low
+quality settings to make very small JPEG files; the percentage improvement
+is often a lot more than it is on larger files. (At present, -optimize
+mode is always selected when generating progressive JPEG files.)
+
+GIF input files are no longer supported, to avoid the Unisys LZW patent.
+Use a Unisys-licensed program if you need to read a GIF file. (Conversion
+of GIF files to JPEG is usually a bad idea anyway.)
+
+
+HINTS FOR DJPEG
+
+To get a quick preview of an image, use the -grayscale and/or -scale switches.
+"-grayscale -scale 1/8" is the fastest case.
+
+Several options are available that trade off image quality to gain speed.
+"-fast" turns on the recommended settings.
+
+"-dct fast" and/or "-nosmooth" gain speed at a small sacrifice in quality.
+When producing a color-quantized image, "-onepass -dither ordered" is fast but
+much lower quality than the default behavior. "-dither none" may give
+acceptable results in two-pass mode, but is seldom tolerable in one-pass mode.
+
+If you are fortunate enough to have very fast floating point hardware,
+"-dct float" may be even faster than "-dct fast". But on most machines
+"-dct float" is slower than "-dct int"; in this case it is not worth using,
+because its theoretical accuracy advantage is too small to be significant
+in practice.
+
+Two-pass color quantization requires a good deal of memory; on MS-DOS machines
+it may run out of memory even with -maxmemory 0. In that case you can still
+decompress, with some loss of image quality, by specifying -onepass for
+one-pass quantization.
+
+To avoid the Unisys LZW patent, djpeg produces uncompressed GIF files. These
+are larger than they should be, but are readable by standard GIF decoders.
+
+
+HINTS FOR BOTH PROGRAMS
+
+If more space is needed than will fit in the available main memory (as
+determined by -maxmemory), temporary files will be used. (MS-DOS versions
+will try to get extended or expanded memory first.) The temporary files are
+often rather large: in typical cases they occupy three bytes per pixel, for
+example 3*800*600 = 1.44Mb for an 800x600 image. If you don't have enough
+free disk space, leave out -progressive and -optimize (for cjpeg) or specify
+-onepass (for djpeg).
+
+On MS-DOS, the temporary files are created in the directory named by the TMP
+or TEMP environment variable, or in the current directory if neither of those
+exist. Amiga implementations put the temp files in the directory named by
+JPEGTMP:, so be sure to assign JPEGTMP: to a disk partition with adequate free
+space.
+
+The default memory usage limit (-maxmemory) is set when the software is
+compiled. If you get an "insufficient memory" error, try specifying a smaller
+-maxmemory value, even -maxmemory 0 to use the absolute minimum space. You
+may want to recompile with a smaller default value if this happens often.
+
+On machines that have "environment" variables, you can define the environment
+variable JPEGMEM to set the default memory limit. The value is specified as
+described for the -maxmemory switch. JPEGMEM overrides the default value
+specified when the program was compiled, and itself is overridden by an
+explicit -maxmemory switch.
+
+On MS-DOS machines, -maxmemory is the amount of main (conventional) memory to
+use. (Extended or expanded memory is also used if available.) Most
+DOS-specific versions of this software do their own memory space estimation
+and do not need you to specify -maxmemory.
+
+
+JPEGTRAN
+
+jpegtran performs various useful transformations of JPEG files.
+It can translate the coded representation from one variant of JPEG to another,
+for example from baseline JPEG to progressive JPEG or vice versa. It can also
+perform some rearrangements of the image data, for example turning an image
+from landscape to portrait format by rotation.
+
+jpegtran works by rearranging the compressed data (DCT coefficients), without
+ever fully decoding the image. Therefore, its transformations are lossless:
+there is no image degradation at all, which would not be true if you used
+djpeg followed by cjpeg to accomplish the same conversion. But by the same
+token, jpegtran cannot perform lossy operations such as changing the image
+quality.
+
+jpegtran uses a command line syntax similar to cjpeg or djpeg.
+On Unix-like systems, you say:
+ jpegtran [switches] [inputfile] >outputfile
+On most non-Unix systems, you say:
+ jpegtran [switches] inputfile outputfile
+where both the input and output files are JPEG files.
+
+To specify the coded JPEG representation used in the output file,
+jpegtran accepts a subset of the switches recognized by cjpeg:
+ -optimize Perform optimization of entropy encoding parameters.
+ -progressive Create progressive JPEG file.
+ -restart N Emit a JPEG restart marker every N MCU rows, or every
+ N MCU blocks if "B" is attached to the number.
+ -scans file Use the scan script given in the specified text file.
+See the previous discussion of cjpeg for more details about these switches.
+If you specify none of these switches, you get a plain baseline-JPEG output
+file. The quality setting and so forth are determined by the input file.
+
+The image can be losslessly transformed by giving one of these switches:
+ -flip horizontal Mirror image horizontally (left-right).
+ -flip vertical Mirror image vertically (top-bottom).
+ -rotate 90 Rotate image 90 degrees clockwise.
+ -rotate 180 Rotate image 180 degrees.
+ -rotate 270 Rotate image 270 degrees clockwise (or 90 ccw).
+ -transpose Transpose image (across UL-to-LR axis).
+ -transverse Transverse transpose (across UR-to-LL axis).
+
+The transpose transformation has no restrictions regarding image dimensions.
+The other transformations operate rather oddly if the image dimensions are not
+a multiple of the iMCU size (usually 8 or 16 pixels), because they can only
+transform complete blocks of DCT coefficient data in the desired way.
+
+jpegtran's default behavior when transforming an odd-size image is designed
+to preserve exact reversibility and mathematical consistency of the
+transformation set. As stated, transpose is able to flip the entire image
+area. Horizontal mirroring leaves any partial iMCU column at the right edge
+untouched, but is able to flip all rows of the image. Similarly, vertical
+mirroring leaves any partial iMCU row at the bottom edge untouched, but is
+able to flip all columns. The other transforms can be built up as sequences
+of transpose and flip operations; for consistency, their actions on edge
+pixels are defined to be the same as the end result of the corresponding
+transpose-and-flip sequence.
+
+For practical use, you may prefer to discard any untransformable edge pixels
+rather than having a strange-looking strip along the right and/or bottom edges
+of a transformed image. To do this, add the -trim switch:
+ -trim Drop non-transformable edge blocks.
+Obviously, a transformation with -trim is not reversible, so strictly speaking
+jpegtran with this switch is not lossless. Also, the expected mathematical
+equivalences between the transformations no longer hold. For example,
+"-rot 270 -trim" trims only the bottom edge, but "-rot 90 -trim" followed by
+"-rot 180 -trim" trims both edges.
+
+Another not-strictly-lossless transformation switch is:
+ -grayscale Force grayscale output.
+This option discards the chrominance channels if the input image is YCbCr
+(ie, a standard color JPEG), resulting in a grayscale JPEG file. The
+luminance channel is preserved exactly, so this is a better method of reducing
+to grayscale than decompression, conversion, and recompression. This switch
+is particularly handy for fixing a monochrome picture that was mistakenly
+encoded as a color JPEG. (In such a case, the space savings from getting rid
+of the near-empty chroma channels won't be large; but the decoding time for
+a grayscale JPEG is substantially less than that for a color JPEG.)
+
+jpegtran also recognizes these switches that control what to do with "extra"
+markers, such as comment blocks:
+ -copy none Copy no extra markers from source file. This setting
+ suppresses all comments and other excess baggage
+ present in the source file.
+ -copy comments Copy only comment markers. This setting copies
+ comments from the source file, but discards
+ any other inessential data.
+ -copy all Copy all extra markers. This setting preserves
+ miscellaneous markers found in the source file, such
+ as JFIF thumbnails and Photoshop settings. In some
+ files these extra markers can be sizable.
+The default behavior is -copy comments. (Note: in IJG releases v6 and v6a,
+jpegtran always did the equivalent of -copy none.)
+
+Additional switches recognized by jpegtran are:
+ -outfile filename
+ -maxmemory N
+ -verbose
+ -debug
+These work the same as in cjpeg or djpeg.
+
+
+THE COMMENT UTILITIES
+
+The JPEG standard allows "comment" (COM) blocks to occur within a JPEG file.
+Although the standard doesn't actually define what COM blocks are for, they
+are widely used to hold user-supplied text strings. This lets you add
+annotations, titles, index terms, etc to your JPEG files, and later retrieve
+them as text. COM blocks do not interfere with the image stored in the JPEG
+file. The maximum size of a COM block is 64K, but you can have as many of
+them as you like in one JPEG file.
+
+We provide two utility programs to display COM block contents and add COM
+blocks to a JPEG file.
+
+rdjpgcom searches a JPEG file and prints the contents of any COM blocks on
+standard output. The command line syntax is
+ rdjpgcom [-verbose] [inputfilename]
+The switch "-verbose" (or just "-v") causes rdjpgcom to also display the JPEG
+image dimensions. If you omit the input file name from the command line,
+the JPEG file is read from standard input. (This may not work on some
+operating systems, if binary data can't be read from stdin.)
+
+wrjpgcom adds a COM block, containing text you provide, to a JPEG file.
+Ordinarily, the COM block is added after any existing COM blocks, but you
+can delete the old COM blocks if you wish. wrjpgcom produces a new JPEG
+file; it does not modify the input file. DO NOT try to overwrite the input
+file by directing wrjpgcom's output back into it; on most systems this will
+just destroy your file.
+
+The command line syntax for wrjpgcom is similar to cjpeg's. On Unix-like
+systems, it is
+ wrjpgcom [switches] [inputfilename]
+The output file is written to standard output. The input file comes from
+the named file, or from standard input if no input file is named.
+
+On most non-Unix systems, the syntax is
+ wrjpgcom [switches] inputfilename outputfilename
+where both input and output file names must be given explicitly.
+
+wrjpgcom understands three switches:
+ -tqreplace Delete any existing COM blocks from the file.
+ -comment "Comment text" Supply new COM text on command line.
+ -cfile name Read text for new COM block from named file.
+(Switch names can be abbreviated.) If you have only one line of comment text
+to add, you can provide it on the command line with -comment. The comment
+text must be surrounded with quotes so that it is treated as a single
+argument. Longer comments can be read from a text file.
+
+If you give neither -comment nor -cfile, then wrjpgcom will read the comment
+text from standard input. (In this case an input image file name MUST be
+supplied, so that the source JPEG file comes from somewhere else.) You can
+enter multiple lines, up to 64KB worth. Type an end-of-file indicator
+(usually control-D or control-Z) to terminate the comment text entry.
+
+wrjpgcom will not add a COM block if the provided comment string is empty.
+Therefore -tqreplace -comment "" can be used to delete all COM blocks from a
+file.
+
+These utility programs do not depend on the IJG JPEG library. In
+particular, the source code for rdjpgcom is intended as an illustration of
+the minimum amount of code required to parse a JPEG file header correctly.
diff --git a/tqtinterface/qt4/src/3rdparty/libjpeg/wizard.doc b/tqtinterface/qt4/src/3rdparty/libjpeg/wizard.doc
new file mode 100644
index 0000000..fe50abb
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libjpeg/wizard.doc
@@ -0,0 +1,211 @@
+Advanced usage instructions for the Independent JPEG Group's JPEG software
+==========================================================================
+
+This file describes cjpeg's "switches for wizards".
+
+The "wizard" switches are intended for experimentation with JPEG by persons
+who are reasonably knowledgeable about the JPEG standard. If you don't know
+what you are doing, DON'T USE THESE SWITCHES. You'll likely produce files
+with worse image quality and/or poorer compression than you'd get from the
+default settings. Furthermore, these switches must be used with caution
+when making files intended for general use, because not all JPEG decoders
+will support unusual JPEG parameter settings.
+
+
+Quantization Table Adjustment
+-----------------------------
+
+Ordinarily, cjpeg starts with a default set of tables (the same ones given
+as examples in the JPEG standard) and scales them up or down according to
+the -quality setting. The details of the scaling algorithm can be found in
+jcparam.c. At very low quality settings, some quantization table entries
+can get scaled up to values exceeding 255. Although 2-byte quantization
+values are supported by the IJG software, this feature is not in baseline
+JPEG and is not supported by all implementations. If you need to ensure
+wide compatibility of low-quality files, you can constrain the scaled
+quantization values to no more than 255 by giving the -baseline switch.
+Note that use of -baseline will result in poorer quality for the same file
+size, since more bits than necessary are expended on higher AC coefficients.
+
+You can substitute a different set of quantization values by using the
+-qtables switch:
+
+ -qtables file Use the quantization tables given in the named file.
+
+The specified file should be a text file containing decimal quantization
+values. The file should contain one to four tables, each of 64 elements.
+The tables are implicitly numbered 0,1,etc. in order of appearance. Table
+entries appear in normal array order (NOT in the zigzag order in which they
+will be stored in the JPEG file).
+
+Quantization table files are free format, in that arbitrary whitespace can
+appear between numbers. Also, comments can be included: a comment starts
+with '#' and extends to the end of the line. Here is an example file that
+duplicates the default quantization tables:
+
+ # Quantization tables given in JPEG spec, section K.1
+
+ # This is table 0 (the luminance table):
+ 16 11 10 16 24 40 51 61
+ 12 12 14 19 26 58 60 55
+ 14 13 16 24 40 57 69 56
+ 14 17 22 29 51 87 80 62
+ 18 22 37 56 68 109 103 77
+ 24 35 55 64 81 104 113 92
+ 49 64 78 87 103 121 120 101
+ 72 92 95 98 112 100 103 99
+
+ # This is table 1 (the chrominance table):
+ 17 18 24 47 99 99 99 99
+ 18 21 26 66 99 99 99 99
+ 24 26 56 99 99 99 99 99
+ 47 66 99 99 99 99 99 99
+ 99 99 99 99 99 99 99 99
+ 99 99 99 99 99 99 99 99
+ 99 99 99 99 99 99 99 99
+ 99 99 99 99 99 99 99 99
+
+If the -qtables switch is used without -quality, then the specified tables
+are used exactly as-is. If both -qtables and -quality are used, then the
+tables taken from the file are scaled in the same fashion that the default
+tables would be scaled for that quality setting. If -baseline appears, then
+the quantization values are constrained to the range 1-255.
+
+By default, cjpeg will use quantization table 0 for luminance components and
+table 1 for chrominance components. To override this choice, use the -qQ_SLOTS
+switch:
+
+ -qQ_SLOTS N[,...] Select which quantization table to use for
+ each color component.
+
+The -qQ_SLOTS switch specifies a quantization table number for each color
+component, in the order in which the components appear in the JPEG SOF marker.
+For example, to create a separate table for each of Y,Cb,Cr, you could
+provide a -qtables file that defines three quantization tables and say
+"-qQ_SLOTS 0,1,2". If -qQ_SLOTS gives fewer table numbers than there are color
+components, then the last table number is repeated as necessary.
+
+
+Sampling Factor Adjustment
+--------------------------
+
+By default, cjpeg uses 2:1 horizontal and vertical downsampling when
+compressing YCbCr data, and no downsampling for all other color spaces.
+You can override this default with the -sample switch:
+
+ -sample HxV[,...] Set JPEG sampling factors for each color
+ component.
+
+The -sample switch specifies the JPEG sampling factors for each color
+component, in the order in which they appear in the JPEG SOF marker.
+If you specify fewer HxV pairs than there are components, the remaining
+components are set to 1x1 sampling. For example, the default YCbCr setting
+is equivalent to "-sample 2x2,1x1,1x1", which can be abbreviated to
+"-sample 2x2".
+
+There are still some JPEG decoders in existence that support only 2x1
+sampling (also called 4:2:2 sampling). Compatibility with such decoders can
+be achieved by specifying "-sample 2x1". This is not recommended unless
+really necessary, since it increases file size and encoding/decoding time
+with very little quality gain.
+
+
+Multiple Scan / Progression Control
+-----------------------------------
+
+By default, cjpeg emits a single-scan sequential JPEG file. The
+-progressive switch generates a progressive JPEG file using a default series
+of progression parameters. You can create multiple-scan sequential JPEG
+files or progressive JPEG files with custom progression parameters by using
+the -scans switch:
+
+ -scans file Use the scan sequence given in the named file.
+
+The specified file should be a text file containing a "scan script".
+The script specifies the contents and ordering of the scans to be emitted.
+Each entry in the script defines one scan. A scan definition specifies
+the components to be included in the scan, and for progressive JPEG it also
+specifies the progression parameters Ss,Se,Ah,Al for the scan. Scan
+definitions are separated by semicolons (';'). A semicolon after the last
+scan definition is optional.
+
+Each scan definition tqcontains one to four component indexes, optionally
+followed by a colon (':') and the four progressive-JPEG parameters. The
+component indexes denote which color component(s) are to be transmitted in
+the scan. Components are numbered in the order in which they appear in the
+JPEG SOF marker, with the first component being numbered 0. (Note that these
+indexes are not the "component ID" codes assigned to the components, just
+positional indexes.)
+
+The progression parameters for each scan are:
+ Ss Zigzag index of first coefficient included in scan
+ Se Zigzag index of last coefficient included in scan
+ Ah Zero for first scan of a coefficient, else Al of prior scan
+ Al Successive approximation low bit position for scan
+If the progression parameters are omitted, the values 0,63,0,0 are used,
+producing a sequential JPEG file. cjpeg automatically determines whether
+the script represents a progressive or sequential file, by observing whether
+Ss and Se values other than 0 and 63 appear. (The -progressive switch is
+not needed to specify this; in fact, it is ignored when -scans appears.)
+The scan script must meet the JPEG restrictions on progression sequences.
+(cjpeg checks that the spec's requirements are obeyed.)
+
+Scan script files are free format, in that arbitrary whitespace can appear
+between numbers and around punctuation. Also, comments can be included: a
+comment starts with '#' and extends to the end of the line. For additional
+legibility, commas or dashes can be placed between values. (Actually, any
+single punctuation character other than ':' or ';' can be inserted.) For
+example, the following two scan definitions are equivalent:
+ 0 1 2: 0 63 0 0;
+ 0,1,2 : 0-63, 0,0 ;
+
+Here is an example of a scan script that generates a partially interleaved
+sequential JPEG file:
+
+ 0; # Y only in first scan
+ 1 2; # Cb and Cr in second scan
+
+Here is an example of a progressive scan script using only spectral selection
+(no successive approximation):
+
+ # Interleaved DC scan for Y,Cb,Cr:
+ 0,1,2: 0-0, 0, 0 ;
+ # AC scans:
+ 0: 1-2, 0, 0 ; # First two Y AC coefficients
+ 0: 3-5, 0, 0 ; # Three more
+ 1: 1-63, 0, 0 ; # All AC coefficients for Cb
+ 2: 1-63, 0, 0 ; # All AC coefficients for Cr
+ 0: 6-9, 0, 0 ; # More Y coefficients
+ 0: 10-63, 0, 0 ; # Remaining Y coefficients
+
+Here is an example of a successive-approximation script. This is equivalent
+to the default script used by "cjpeg -progressive" for YCbCr images:
+
+ # Initial DC scan for Y,Cb,Cr (lowest bit not sent)
+ 0,1,2: 0-0, 0, 1 ;
+ # First AC scan: send first 5 Y AC coefficients, minus 2 lowest bits:
+ 0: 1-5, 0, 2 ;
+ # Send all Cr,Cb AC coefficients, minus lowest bit:
+ # (chroma data is usually too small to be worth subdividing further;
+ # but note we send Cr first since eye is least sensitive to Cb)
+ 2: 1-63, 0, 1 ;
+ 1: 1-63, 0, 1 ;
+ # Send remaining Y AC coefficients, minus 2 lowest bits:
+ 0: 6-63, 0, 2 ;
+ # Send next-to-lowest bit of all Y AC coefficients:
+ 0: 1-63, 2, 1 ;
+ # At this point we've sent all but the lowest bit of all coefficients.
+ # Send lowest bit of DC coefficients
+ 0,1,2: 0-0, 1, 0 ;
+ # Send lowest bit of AC coefficients
+ 2: 1-63, 1, 0 ;
+ 1: 1-63, 1, 0 ;
+ # Y AC lowest bit scan is last; it's usually the largest scan
+ 0: 1-63, 1, 0 ;
+
+It may be worth pointing out that this script is tuned for quality settings
+of around 50 to 75. For lower quality settings, you'd probably want to use
+a script with fewer stages of successive approximation (otherwise the
+initial scans will be really bad). For higher quality settings, you might
+want to use more stages of successive approximation (so that the initial
+scans are not too large).
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/Changes b/tqtinterface/qt4/src/3rdparty/libmng/Changes
new file mode 100644
index 0000000..3123607
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/Changes
@@ -0,0 +1,867 @@
+-----------------------------------------------------------
+
+1.0.4 (Jun 23rd 2002)
+---------------------
+
+in short:
+
+Just some small fixes
+Standard dll now compiled with zlib 1.1.4 and lcms 1.0.8
+
+-------------------
+
+bugfixes:
+- B495442 - invalid returnvalue in mng_get_suspensionmode
+- B495443 - incorrect suspend check in read_databuffer
+- B526138 - returned IJGSRC6B calling convention to default for MSVC
+- B558212 - off by one error
+- B557677 - can't tqfind lcms.h
+
+core:
+- fixed possible compile-problem in cleanup_rowproc
+- MNG subimage alpha composite wrong for rgba8 images
+
+samples:
+
+contrib:
+
+doc:
+
+makefiles:
+- fixed check for lcms.h in configure.in
+
+autoconf:
+
+-----------------------------------------------------------
+
+1.0.3 (Sep 18th 2001)
+---------------------
+
+in short:
+
+Small cosmetic changes. Cleaning up the contributions.
+New makefile for mingw32, and new fbcon example.
+Major thanks to Greg for helping out with the *nix stuff!
+Note that there's also a separate download for ASM programmers now.
+Check http://www.libmng.com for details (download/ports&packages page).
+
+It may be a while for the next release. I'm "off duty" for the next 8 or
+so months...
+
+Gerard
+
+-------------------
+
+bugfixes:
+- B459058 - wrong include for lcms headers
+
+core:
+- changed inclusion of lcms.h header for Linux platforms (suggested by Greg)
+- added get function for last processed BACK chunk
+
+samples:
+- tqreplaced the gtk & sdl viewer apps with updates by Greg Roelofs
+
+contrib:
+
+doc:
+
+makefiles:
+- changed makefile.linux & makefile.unix as suggested by Greg Roelofs
+ (makefile.linux now compiles with lcms by default)
+- added makefile.mingw for mingw32 by Benoit Blanchon (thanks Mate!)
+
+autoconf:
+
+-----------------------------------------------------------
+
+1.0.2 (Jul 7th 2001)
+--------------------
+
+in short:
+
+Another maintenance release with a few added extra's.
+
+-------------------
+
+bugfixes:
+- B421427 - writes wrong format in bKGD and tRNS
+- B434583 - compiler-warning if MNG_STORE_CHUNKS undefined
+
+core:
+- added optimization option for MNG-video playback
+- added processterm callback
+- added late binding errorcode (not used internally)
+- fixed memory-leak with delta-images (Thanks Michael!)
+- added option to turn off progressive refresh for large images
+
+samples:
+
+contrib:
+
+doc:
+
+makefiles:
+
+autoconf:
+
+-----------------------------------------------------------
+
+1.0.1 (May 2nd 2001)
+--------------------
+
+in short:
+
+Maintenance release.
+Fixed several memory-leaks with the help of Gregg Kelly, added/fixed some CMS
+handling, exported JPEG functions from standard DLL, and some other minor fixes.
+
+The CMS fix now makes libmng automagically work in MNG_FULL_CMS mode as a
+sRGB compliant system. YOU WILL NEED TO CHANGE THIS IF YOU ARE NOT ON AN sRGB
+COMPLIANT SYSTEM AND WANT TO USE CMS!!!!
+(look in libmng.h for the proper function-calls)
+
+-------------------
+
+bugfixes:
+
+core:
+- added MEND processing callback
+- fixed first FRAM_MODE=4 timing problem
+- added handle status-copy function (use with care)
+- exported JPEG functions from standard DLL
+- added BGRA8 canvas with premultiplied alpha (contrib by Gregg Kelly)
+- fixed problem with display_reset/display_resume (Thanks Gregg!)
+- fixed several memory-leaks (Thanks Gregg!)
+- fixed reset_rundata to drop all objects (Thanks again, Gregg!)
+- fixed problem with cms profile being created multiple times when both
+ iCCP & cHRM/gAMA are present (And again... Gregg)
+- moved mng_clear_cms to libmng_cms
+- added "default" sRGB generation (Thanks Marti!)
+
+samples:
+
+contrib:
+
+doc:
+
+makefiles:
+
+autoconf:
+
+-----------------------------------------------------------
+
+1.0.0 (Feb 6th 2001)
+--------------------
+
+in short:
+
+First public release. Finally(!)
+
+This is the 0.9.5 CVS version, which will never be released, because I feel it
+is now ready for a public release. So apart from the version-numbers here and
+there, all other changes are listed under 0.9.5.
+
+This library will work with every MNG/JNG known and available to me. Note that
+there are still parts that need to be coded, and that MNG support is around
+90-95% (JNG at 100%). It is however compliant with the latest and greatest
+MNG 1.0 specification.
+
+I hope to dedicate a bit more time this year to finish up full support and fill
+in the remaining blanks. But this is coming out of my spare time. And extra
+help is always appreciated.
+
+Please enjoy!
+
+Gerard
+
+-----------------------------------------------------------
+
+0.9.5 (no release)
+------------------
+
+in short:
+
+intermediate CVS
+
+-------------------
+
+bugfixes:
+B129681 - fixed compiler warnings SGI/Irix (thanks Dimitri)
+
+core:
+- fixed compiler-warnings Mozilla (thanks Tim)
+- fixed timing-problem with switching framing_modes
+- fixed some small compiler warnings (thanks Nikki)
+
+samples:
+
+contrib:
+- fixed library-paths for MSVC DLL project (thanks Chad)
+
+doc:
+
+makefiles:
+- added makefile for DJGPP (thanks Silvio)
+
+autoconf:
+
+-----------------------------------------------------------
+
+0.9.4 (Jan 19th 2001)
+----------------------
+
+in short:
+
+Now that the MNG spec is at 1.0, this should be the last beta. There's a few
+small changes to make it inline with the spec, and a couple of bug-fixes.
+This is a serious release-candidate for libmng-1.0!!
+Please... test test test test!!
+
+-------------------
+
+bugfixes:
+B123314 - fixed number of TERM related problems
+B123322 - fixed unwanted repetition in mng_readdisplay()
+B123443 - fixed by Ralph
+B124910 - fixed definition for WIN32_LEAN_AND_MEAN (thanks Chad)
+B125750 - fixed by Ralph
+B125756 - fixed mixup of data- & function-pointers (thanks Dimitri)
+B127517 - changed inclusion of the lcms header file for non-windows platforms
+
+core:
+- version numbers
+- fixed possible loop in display_resume() (Thanks Vova!)
+- fixed unwanted repetition in mng_readdisplay()
+- changed inclusion of the lcms header file for non-windows platforms
+- changed IHDR filter_method check for PNGs
+- moved restore of object 0 to libmng_display
+- added restore of object 0 to TERM processing (B123314)
+- fixed TERM delay processing (B123314)
+- fixed TERM end processing when count = 0 (B123314)
+- changed callback convention for MSVC (Thanks Chad)
+- fixed mixup of data- & function-pointers (thanks Dimitri)
+- added support for "nEED MNG-1.0"
+- added errorcode for MAGN methods
+- added errorchecking for MAGN methods
+- removed "old" MAGN methods 3 & 4
+- added "new" MAGN methods 3, 4 & 5
+- removed test filter-methods 1 & 65
+- set default level-set for filtertype=64 to all zeroes
+
+samples:
+
+contrib:
+- added GTK mng-view example by Vova Babin
+- added MSVC MNGview sample by Nikolaus Brennig
+- updated Jason Summer's mngplg to version 0.9.2
+ (that's mngplg-0.9.2 based on libmng-0.9.3 !!!)
+- rearranged contrib directory slightly
+- added MSVC project to build libmng.dll by Chad Austin
+
+doc:
+- added README.dll
+- added README.config
+
+makefiles:
+- added a makefile for MS Visual C++ (Thanks to Atsushi Matsuda)
+
+autoconf:
+- fixed configure.in for lcms (FreeBSD port by Mikhail Teterin)
+- by default configure includes CMS support if lcms is present
+
+-----------------------------------------------------------
+
+0.9.3 (October 29th 2000)
+-------------------------
+
+in short:
+
+Another beta release. The number of changes in the MNG specification have
+resulted in a lot of new code and some changed code. At the same time I saw
+no need to withhold some new functionality as it was pretty clear there was
+going to be another beta-round. If things go well, I'm going to try to release
+libmng 1.0.0 very shortly after this one.
+
+Many thanks to a lot of people for helping out, sending contributions, making
+suggestions and testing this little baby. This would get nowhere without YOU!!!
+
+- fixed bug 111300/117103
+- added workaround for faulty PhotoShop iCCP chunk
+- added MAGN/JDAA chunks
+- added support for new filter_types
+- added PNG/MNG spec version indicators
+- added BCB mngview contribution by Andy Protano
+- added BCB mngdump; a GUI-based MNG dumping utility (Andy Protano)
+- implemented support for nEED "draft nn"
+- implemented app-defined support for bKGD for PNG images
+- removed trace-options from default SO/DLL builds (!!!)
+- raised initial maximum canvas size to 10000x10000 (!!!)
+ (an App that wants to protect from overly large images should call
+ mng_set_maxcanvassize() with appropriate values)
+- fixed other assorted stuff
+
+-------------------
+
+bugfixes:
+B111300 - fixup for improved portability
+B117103 - fixed compilation errors on *nix with lcms (thanks Ralph!)
+
+core:
+- fixed compiler-warnings from Mozilla
+- added check for simplicity-bits in MHDR
+- added workaround for faulty PhotoShop iCCP chunk
+- fixed app-supplied background restore
+- fixed TERM processing delay of 0 msecs
+- fixed write-code for zTXt & iTXt
+- fixed read-code for iTXt
+- added MAGN chunk
+- fixed sRGB precedence for gamma_only corection
+- added support for new filter_types
+- fixed problem with no refresh after TERM
+- fixed DEFI behavior
+- fixed inclusion parameters to make the external libs work together
+- added export of zlib functions from windows dll
+- fixed timing & refresh behavior for single PNG/JNG
+- removed trace-options from default SO/DLL builds (!!!)
+- fixed MAGN rounding errors (thanks Matthias!)
+- fixed small timing problem when FRAM delay = 0
+- fixed simplicity-check in compliance with draft 81/0.98a
+- fixed alpha-blending for all alpha-canvasstyles
+- added support for alpha-depth prediction
+- fixed processing of unknown critical chunks
+- removed test-MaGN
+- added PNG/MNG spec version indicators
+- implemented support for nEED
+- added support for JDAA
+- added functions to retrieve PNG/JNG specific header-info
+- added optional support for bKGD for PNG images
+- raised initial maximum canvas size to 10000x10000
+- added support for delta-JNG
+- added callback to process non-critical unknown chunks
+- fixed support for delta-images during read() / display()
+- added closestream() processing for mng_cleanup()
+- fixed delta-processing behavior
+- added storage for pixel-/alpha-sampledepth for delta's
+- implemented delayed delta-processing
+- fixed putchunk_plte() to set bEmpty parameter (thanks Ben!)
+- added errorcode for delayed delta-processing
+- added get/set for bKGD preference setting
+- added get function for interlace/progressive display
+- fixed bug in empty PLTE handling
+- fixed seperate read() & display() processing
+- fixed tRNS processing for gray-image < 8-bits
+
+samples:
+- added BCB mngview contribution by Andy Protano
+
+contrib:
+- added BCB mngdump; a GUI-based MNG dumping utility (Andy Protano)
+
+doc:
+- updated RPM spec-file by MATSUURA Takanori
+- updated README.contrib
+
+makefiles:
+- fixed some stuff in automake/autoconf/libtool
+- fixed auto* for bug B117103
+
+-----------------------------------------------------------
+
+0.9.2 (August 7th 2000)
+-----------------------
+
+in short:
+
+Third beta release! Last one???
+
+!!IMPORTANT!! All file-names are now prefixed with "libmng_" !!IMPORTANT!!
+
+Many thanks to Albert Chin-A-Young for his contribution of the
+autoconf/automake/libtool stuff and to Ralph Giles for helping me
+put it in the right places.
+
+There's a special README.autoconf so please read it!
+
+- fixed bug 110320/110546/110547/111096
+- added several status retrieval functions
+- fixed other small bugs in display processing
+- fixed number of small problems and documentation typos
+- added autoconf/automake/libtool
+- added latest MNG plugin (0.9.0) by Jason Summers
+
+-------------------
+
+bugfixes:
+B110320 - fixed GCC warning about mix-sized pointer math
+B110546 - fixed for improperly returning UNEXPECTEDEOF
+B110547 - fixed bug in interlace code
+B111096 - fixed large-buffer read-suspension
+
+core:
+- version numbers
+- fixed small bugs in display processing
+- removed Nextbackxxx fields (no longer used)
+- fixed problem with trace-functions improperly wrapped
+- put specific code in add_chunk() inside MNG_SUPPORT_WRITE wrapper
+- fixed documentation typos
+- fixed wrapping of suspension parameters
+- added status_xxxx functions
+- added trace-codes/-strings for status_xxxxx functions
+- changed file-prefixes
+- added function to set simplicity field
+- added trace-code/-string for updatemngsimplicity
+- fixed putchunk_unknown() function
+
+samples:
+
+contrib:
+- added latest MNG plugin (0.9.0) by Jason Summers
+
+doc:
+- version numbers
+- added autoconf readme
+- version numbers in RPM stuff
+
+makefiles:
+- fixed for new file-prefix
+- added autoconf/automake/libtool
+
+-----------------------------------------------------------
+
+0.9.1 (July 26th 2000)
+----------------------
+
+in short:
+
+Second beta release.
+
+Given the enormous amount of bug-reports (not ;-), this will most likely
+be one of the last betas. If things remain upright, the first public release
+(1.0.0) is fairly eminent in the weeks to come...
+
+- added SDL mng player by Ralph Giles to contributions
+- fixed timing and added internal buffering for I/O-suspension scenarios
+- added get routines for internal display-state variables (frame/layer/playtime)
+- changed read-processing for improved I/O-suspension (internal buffering)
+- fixed several problems with create- & write-support
+- added a load of documentation
+- lots of small stuff
+
+-------------------
+
+bugfixes:
+
+core:
+- fixed mandatory BACK color to be opaque
+- changed mng_display_resume to allow to be called after a suspension
+ return with MNG_NEEDMOREDATA
+- changed comments to indicate modified behavior for timer & suspension breaks
+- added variables for go_xxxx processing
+- implemented support for freeze/reset/resume & go_xxxx
+- added trace-codes/-strings for special display processing
+- added variables for improved timing support
+- added support for improved timing
+- added get routines for internal display variables
+- added get/set routines for suspensionmode variable
+- added trace-code/-string for get/set suspensionmode
+- added trace-codes/-strings for get/set display variables
+- added support for improved I/O-suspension
+- changed read-processing for improved I/O-suspension
+- added trace-code/-string for read_databuffer (I/O-suspension)
+- added suspendbuffer constants
+- changed EOF processing behavior
+- fixed TERM delay processing
+- changed pre-draft48 frame_mode=3 to frame_mode=1
+- added callbacks for SAVE/SEEK processing
+- added trace-codes/-strings for SAVE/SEEK callbacks
+- added variable for NEEDSECTIONWAIT breaks
+- added trace-codes/-strings for get/set sectionbreaks
+- added NEEDSECTIONWAIT error-code/-string
+- added macro + routine to set returncode without calling error callback
+- added trace-code/-string for special error routine
+- changed default readbuffer size from 1024 to 4200
+- added variable for freeze & reset processing
+- fixed storage of images during mng_read()
+- fixed support for mng_display() after mng_read()
+- added error cleanup processing
+- fixed support for mng_display_reset()
+- fixed suspension-buffering for 32K+ chunks
+- added function to set frame-/layer-count & playtime
+- added trace-code/-string for updatemngheader
+- added error-code/-string for updatemngheader if not a MNG
+- fixed creation-code
+- fixed writing of signature
+- fixed several chunk-writing routines
+
+samples:
+- fixed the libmng.pas module in line with libmng.h
+
+contrib:
+- added the SDL based mngplay viewer by Ralph Giles
+
+doc:
+- extended the RPM contribution by MATSUURA Takanori
+- added libmng.txt, a full description of the library and its usage
+- added man-pages for mng(5), jng(5) and libmng(3)
+
+makefiles:
+
+-----------------------------------------------------------
+
+0.9.0 (June 30th 2000)
+----------------------
+
+in short:
+
+This is the first beta!!! Yippee!!!
+
+Thanks to all the people who helped to guide me in the right direction.
+You know who you are!
+
+A special thanks to the guys with early implementations, who stood by and
+put up with my whims :-)
+
+changes over 0.5.3:
+
+- updated mngplg to 0.4.1 (the latest & greatest)
+- changed refresh parameters to 'x,y,width,height'
+
+-----------------------------------------------------------
+
+0.5.3 (never released)
+----------------------
+
+in short:
+
+This is a working version only; the next release will be 0.9.0 (first Beta!)
+
+There are a few incompatible changes with previous versions. The userdata
+variable has been changed from mng_uint32 to mng_ptr to accomodate 64-bit
+systems. For the same reason memory allocation size parameters have been
+changed to a mng_size_t type which is a typedef of size_t.
+
+Thanks to Aleks Jakulin for helping to iron out some 64-bit platform issues!
+
+- implemented the update-region parameters of the refresh callback
+- added support for most common delta-image options
+- added an animation-speed modifier
+- added an image-level parameter for the processtext callback
+- updated mngplg to 0.4.0 (supports JNG, full CMS, and other enhancements!)
+- fixed a lot of small things
+- added support for PPLT chunk
+- fixed to support 64-bit platforms
+
+-------------------
+
+bugfixes:
+
+core:
+- added processing of color-info on delta-image
+- fixed handling of empty SAVE chunk
+- fixed display of stored JNG images
+- fixed problem with BASI-IEND as object 0
+- changed the version parameters (obviously)
+- added update-region parms for refresh calback
+- added Needrefresh parameter
+- added initialization of update-region for refresh
+- added initialization of Needrefresh parameter
+- changed progressive-display processing
+- added tracecodes for tracing JPEG progression
+- added tracing of JPEG calls
+- added Deltaimmediate parm for faster delta-processing
+- added extra checks for delta-images
+- many changes to support delta-images
+- optimized some store_xxx routines
+- fixed some small things (as precaution)
+- fixed possible trouble if IEND display-processing got broken up
+- fixed nasty bug with embedded PNG after delta-image
+- added processing of PLTE & tRNS for delta-images
+- added processing of PLTE/tRNS & color-info for delta-images in the
+ ani_objects chain
+- fixed problem with color-correction for stored images
+- added get/set for speedtype to facilitate testing
+- added trace-codes & -strings for get/set speedtype
+- added speed-modifier to timing routine
+- added get-routine of imagelevel for processtext callback
+- added trace-code & -string for get imagelevel
+- added administration of imagelevel parameter
+- added support for PPLT chunk
+- added trace-codes & -strings for PPLT chunk processing
+- fixed problem with incorrect gamma-correction
+- fixed inclusion of IJG read/write code
+- fixed problem with 16-bit GA format
+- fixed problem with cheap transparency for 4-bit gray
+- fixed display_xxxx routines for interlaced images
+- added precaution against faulty iCCP chunks from PS
+- changed userdata variable to mng_ptr
+- added typedef for mng_size_t
+- changed size parameter for memory allocation to mng_size_t
+- fixed compiler-warning for non-initialized iB variable
+- changed definition for 32-bit ints (64-bit platforms)
+- changed definition for mng_handle (64-bit platforms)
+- swapped refresh parameters
+- fixed initialization routine for new mng_handle type
+- added inclusion of stdlib.h for abs()
+- fixed some 64-bit warnings
+- fixed incompatible return-types
+
+samples:
+
+contrib:
+- updated mngplg to 0.3.0 (supports JNG & full color-correction!)
+- updated mngplg to 0.4.0 (Jason is picking up the pace ;-)
+
+doc:
+- added rpm directory with rpm spec-file (contributed by MATSUURA Takanori)
+
+makefiles:
+- changed makefile.linux to reflect versionnr for shared-lib
+- changed makefile.linux to depend on mng_conf.h & mng_types.h
+
+-----------------------------------------------------------
+
+0.5.2 (June 10th 2000)
+----------------------
+
+in short:
+
+This is the third release for developers
+Another milestone since JNG is now fully supported
+The next release will most likely be numbered 0.9.0 as the first Beta!!
+
+Fixed bug 106017 & 106019
+Added many constants regarding chunk-property values
+Implemented full JNG support
+Added all the error- & trace-strings
+Added get/set routines for default ZLIB/IJG parameters
+Added a generic makefile for Unix platforms (contributed by Tim Rowley)
+Added canvasstyle for separate RGB + A canvas (eg. mozilla-style)
+Separated configuration-options into a separate file: "mng_conf.h"
+Fixed stuff for generic Unix compilation (contributed by Tim Rowley)
+Upgraded to lcms1.0.6 (now supports 16-bit endian-peculiarities)
+Added a makefile for Linux ELF & fixed some code-issues to go along with gcc
+Added support for suspended input-buffer processing
+Implemented the display-routines for RGBA/ARGB/BGRA/ABGR canvasstyles
+Implemented the application background-restore functionality
+Fixed & tested the mngtree Unix-sample (runs on Linux-RH6.2 with libmng.so)
+Upgraded mngplg to v0.2.2 (based on the latest code including JNG)
+Fixed a lot of other assorted stuff
+
+-------------------
+
+bugfixes:
+B003(106017) - fixed problem with <mem.h> being proprietary to BCB
+B004(106019) - fixed problem when MNG_SUPPORT_WRITE not defined
+
+core:
+- bumped version-numbers up to 0.5.2 (yeah, really)
+- fixed support for IJGSRC6B
+- cleaned up some code regarding mixed support-options
+- complemented constants for chunk-property values
+- fixed MNG_UINT_pHYg value
+- implemented JNG support
+- fixed problem with DEFI clipping
+- added error telltale strings & support
+- added trace telltale strings & support
+- added support for global color-chunks inside TERM/LOOP
+- added support for global PLTE,tRNS,bKGD inside TERM/LOOP
+- added default IJG compression parameters and such
+- moved init of default zlib parms to "mng_hlapi.c"
+- added init of default IJG parms
+- added support for get/set of zlib/IJG default parms
+- added tracestrings for global animation color-chunks
+- added tracestrings for get/set of default ZLIB/IJG parms
+- added tracestrings for global PLTE,tRNS,bKGD
+- added framenr/layernr/playtime to object header
+- added initialization of framenr/layernr/playtime
+- changed ani_create calls not returning object pointer
+- create ani objects always (not just inside TERM/LOOP)
+- fixed inconsistancy with freeing global iCCP profile
+- fixed minor bugs 16-bit pixel-handling
+- added object promotion routine (PROM handling)
+- added trace-codes & -strings for image-object promotion
+- added trace-codes & -strings for delta-image processing
+- added error-codes & -strings for delta-image processing
+- added support for delta-image processing
+- added ani-object routines for delta-image processing
+- added delta-image fields
+- added compression/filter/interlace fields to object-buffer for
+ delta-image processing
+- added delta-image row-processing routines
+- fixed up punctuation in several files (contributed by Tim Rowley)
+- removed useless definition in "mng_chunks.h" (contributed by Tim Rowley)
+- fixed pointer confusion in "mng_display.c" (contributed by Tim Rowley)
+- fixed inclusion for memcpy (contributed by Tim Rowley)
+- added mng_int32p (contributed by Tim Rowley)
+- added internal delta-image processing callbacks
+- separated configuration-options into "mng_conf.h"
+- changed to most likely configuration
+- added RGB8_A8 canvasstyle
+- added getalphaline callback for RGB8_A8 canvasstyle
+- fixed some makeup for Linux gcc compile
+- implemented app bkgd restore routines
+- implemented RGBA8, ARGB8, BGRA8 & ABGR8 display routines
+- added support for RGB8_A8 canvasstyle
+- added support for suspended input-buffer processing
+- added mng_read_resume HLAPI function to support read-suspension
+- fixed timer-handling to run with Mozilla (Tim Rowley)
+- fixed alpha-handling for alpha canvasstyles
+- fixed some compilation-warnings (contrib Jason Morris)
+
+samples:
+- fixed mngview(delphi) to work with the new core
+- synchronized libmng.pas(delphi) with the new libmng.h header
+- removed the error- & trace-strings from libmng.pas(delphi)
+- fixed mngtree(Unix) to compile on Linux (runs with libmng.so)
+- added makefile.linux for mngtree(Unix) (tested on RedHat6.2)
+
+contrib:
+- updated mngplg to 0.2.2 (based on latest code; supports JNG!)
+
+doc:
+- this file obviously
+- added Tim Rowley as contributing author
+- changed the examples.readme doc
+- updated the design-schematics in line with the current code
+
+makefiles:
+- changed the directory to "makefiles" to avoid name-conflicts
+- added generic Unix makefile (thanks to Tim Rowley)
+- added Linux ELF makefile (tested on RedHat6.2)
+
+-----------------------------------------------------------
+
+0.5.1 May 16th 2000
+-------------------
+
+in short:
+
+This is the second release for developers
+It's a bit of a milestone since all the chunk functionality is in place and
+functioning (read, examine, create & write)
+This version is incompatible with 0.5.0 since some of the callback prototypes
+have changed (should be the last time that happens!)
+There are a few more samples and even a real contribution!
+
+Fixed bug 105795 & 105797
+Fixed a mis-tqalignment in animation-timing
+Added chunk-access functions
+Finished all chunk-storage routine-bits
+Finished all chunk-write routines
+Changed the callback prototypes to allow error-reporting back to the library
+Fixed some routines to allow for callback error-reporting
+Added version-control functions & constants
+Added two functions to set display- & sRGB-profile from memory
+Moved CRC table to dynamic structure (for improved thread-safety)
+Added SAVE & SEEK save&restore functionality
+Finished the application-based CMS-callbacks
+Fixed a few BCB specifics
+Changed the Win32 DLL and samples to use __stdcall
+Did some more assorted little changes
+Added 2 BCB samples
+Added 1 Unix sample
+Added the MNG plugin by Jason Summers in the contrib section
+Changed some documents to reflect these changes
+
+-------------------
+
+bugfixes:
+B001(105795) - fixed wrong lcms call & memory-leak for gammatables
+B002(105797) - fixed problem with missing sRGB profile
+
+core:
+- changed chunk iteration function
+- added chunk access functions
+- added version control constants & functions
+- changed strict-ANSI stuff
+- added set_outputprofile2 & set_srgbprofile2
+- added empty-chunk put-routines
+- added version_dll & VERSION_DLL (for consistency)
+- added version control explanatory text & samples
+- added iteratechunk callback definition
+- improved definitions for DLL support
+- added 8-bit palette definition
+- added general array definitions
+- added MNG_NULL definition
+- changed most callback prototypes to allow the app
+ to report errors during callback processing
+- added CRC table to main structure (for thread-safety)
+- added iPLTEentries for checking hIST-length
+- changed palette definition to exported palette-type
+- removed frozen indicator
+- added create/write indicators
+- added eMNGma hack (will be removed in 1.0.0 !!!)
+- added TERM animation object pointer (easier reference)
+- added saved-data structure for SAVE/SEEK processing
+- added some errorcodes
+- added application errorcodes (used with callbacks)
+- moved chunk-access errorcodes to severity 5
+- added chunk-access function trace-codes
+- changed trace to macro for callback error-reporting
+- added save_state & restore_state trace-codes
+- put in some extra comments
+- fixed tqlayout for sBIT, PPLT
+- changed write callback definition
+- fixed tqlayout for PPLT again (missed deltatype ?!?)
+- cleaned up left-over teststuff in the BACK chunk routine
+- changed CRC initialization to use dynamic structure
+ (wasn't thread-safe the old way !)
+- filled in many missing sequence&length checks
+- filled in many missing chunk-store snippets
+- added checks for running animations
+- filled remaining write routines
+- fixed read_pplt with regard to deltatype
+- added callback error-reporting support
+- added pre-draft48 support (short MHDR, frame_mode, LOOP)
+- fixed chunk-storage bit in several routines
+- supplemented the SAVE & SEEK display processing
+- added init of iPLTEcount
+- changed calling-convention definition
+- changed status-handling of display-routines
+- added versioning-control routines
+- filled the write routine
+- fixed frame_delay mistqalignment
+- added sanity check for frozen status
+- changed display_mend to reset state to initial or SAVE
+- added save_state and restore_state for SAVE/SEEK/TERM
+ processing
+- added process_save & process_seek routines
+- changed and filled iterate-chunk function
+- added getchunk functions
+- added putchunk functions
+- added empty-chunk put-routines
+- filled application-based color-management routines
+- added creatememprofile
+- filled the deflatedata routine
+- added cleanup of saved-data (SAVE/SEEK processing)
+- moved the actual write_graphic functionality from mng_hlapi.c
+ to it's appropriate function in the mng_write.c module
+- moved standard header includes into mng_types.h
+ (stdlib/mem for mem-mngmt & math for fp gamma-calc)
+- added getimgdata & putimgdata functions
+
+samples:
+- fixed mngview(delphi) to work with the new core
+- synchronized libmng.pas(delphi) with the new libmng.h header
+- added mngtree(bcb) sample
+- added bogus(bcb) sample
+- added mngtree(unix) sample
+
+contrib:
+- added mngplg 0.1.0 / a MNG plugin for Win32 by Jason Summers
+
+doc:
+- added this changes.readme file
+- changed the samples.readme doc accordingly
+- changed the contrib.readme doc accordingly
+
+-----------------------------------------------------------
+
+0.5.0 May 1st 2000
+------------------
+
+in short:
+
+This is the first developers release.
+It's roughly about 60% done.
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/LICENSE b/tqtinterface/qt4/src/3rdparty/libmng/LICENSE
new file mode 100644
index 0000000..bae3a82
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/LICENSE
@@ -0,0 +1,56 @@
+/* ************************************************************************** */
+/* * * */
+/* * COPYRIGHT NOTICE: * */
+/* * * */
+/* * Copyright (c) 2000 Gerard Juyn (gerard@libmng.com) * */
+/* * [You may insert additional notices after this sentence if you modify * */
+/* * this source] * */
+/* * * */
+/* * For the purposes of this copyright and license, "Contributing Authors" * */
+/* * is defined as the following set of individuals: * */
+/* * * */
+/* * Gerard Juyn * */
+/* * * */
+/* * The MNG Library is supplied "AS IS". The Contributing Authors * */
+/* * disclaim all warranties, expressed or implied, including, without * */
+/* * limitation, the warranties of merchantability and of fitness for any * */
+/* * purpose. The Contributing Authors assume no liability for direct, * */
+/* * indirect, incidental, special, exemplary, or consequential damages, * */
+/* * which may result from the use of the MNG Library, even if advised of * */
+/* * the possibility of such damage. * */
+/* * * */
+/* * Permission is hereby granted to use, copy, modify, and distribute this * */
+/* * source code, or portions hereof, for any purpose, without fee, subject * */
+/* * to the following restrictions: * */
+/* * * */
+/* * 1. The origin of this source code must not be misrepresented; * */
+/* * you must not claim that you wrote the original software. * */
+/* * * */
+/* * 2. Altered versions must be plainly marked as such and must not be * */
+/* * misrepresented as being the original source. * */
+/* * * */
+/* * 3. This Copyright notice may not be removed or altered from any source * */
+/* * or altered source distribution. * */
+/* * * */
+/* * The Contributing Authors specifically permit, without fee, and * */
+/* * encourage the use of this source code as a component to supporting * */
+/* * the MNG and JNG file format in commercial products. If you use this * */
+/* * source code in a product, acknowledgment would be highly appreciated. * */
+/* * * */
+/* ************************************************************************** */
+/* * * */
+/* * Parts of this software have been adapted from the libpng package. * */
+/* * Although this library supports all features from the PNG specification * */
+/* * (as MNG descends from it) it does not require the libpng package. * */
+/* * It does require the zlib library and optionally the IJG jpeg library, * */
+/* * and/or the "little-cms" library by Marti Maria (depending on the * */
+/* * inclusion of support for JNG and Full-Color-Management respectively. * */
+/* * * */
+/* * This library's function is primarily to read and display MNG * */
+/* * animations. It is not meant as a full-featured image-editing * */
+/* * component! It does however offer creation and editing functionality * */
+/* * at the chunk level. * */
+/* * (future modifications may include some more support for creation * */
+/* * and or editing) * */
+/* * * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/Makefile.am b/tqtinterface/qt4/src/3rdparty/libmng/Makefile.am
new file mode 100644
index 0000000..2bdd30c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/Makefile.am
@@ -0,0 +1,27 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = 1.3 foreign no-dependencies
+
+# include the app subdirectories in the distribution
+EXTRA_DIST = makefiles doc contrib Unix
+
+
+# libmng release @VERSION@
+libmng_la_LDFLAGS = -version-info 1:0:0
+
+lib_LTLIBRARIES = libmng.la
+
+include_HEADERS = libmng.h libmng_conf.h libmng_types.h
+noinst_HEADERS = libmng_chunk_io.h libmng_chunk_prc.h libmng_chunks.h \
+ libmng_cms.h libmng_data.h libmng_display.h libmng_dither.h \
+ libmng_error.h libmng_filter.h libmng_jpeg.h libmng_memory.h \
+ libmng_object_prc.h libmng_objects.h libmng_pixels.h \
+ libmng_read.h libmng_trace.h libmng_write.h libmng_zlib.h
+
+libmng_la_SOURCES = libmng_callback_xs.c libmng_chunk_io.c \
+ libmng_chunk_prc.c libmng_chunk_xs.c libmng_cms.c \
+ libmng_display.c libmng_dither.c libmng_error.c \
+ libmng_filter.c libmng_hlapi.c libmng_jpeg.c \
+ libmng_object_prc.c libmng_pixels.c libmng_prop_xs.c \
+ libmng_read.c libmng_trace.c libmng_write.c libmng_zlib.c
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/Makefile.in b/tqtinterface/qt4/src/3rdparty/libmng/Makefile.in
new file mode 100644
index 0000000..4d72bb9
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/Makefile.in
@@ -0,0 +1,403 @@
+# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CC = @CC@
+CPP = @CPP@
+DLLTOOL = @DLLTOOL@
+ECHO = @ECHO@
+EXEEXT = @EXEEXT@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+STRIP = @STRIP@
+U = @U@
+VERSION = @VERSION@
+
+AUTOMAKE_OPTIONS = 1.3 foreign no-dependencies
+
+# include the app subdirectories in the distribution
+EXTRA_DIST = makefiles doc contrib Unix
+
+# libmng release @VERSION@
+libmng_la_LDFLAGS = -version-info 1:0:0
+
+lib_LTLIBRARIES = libmng.la
+
+include_HEADERS = libmng.h libmng_conf.h libmng_types.h
+noinst_HEADERS = libmng_chunk_io.h libmng_chunk_prc.h libmng_chunks.h \
+ libmng_cms.h libmng_data.h libmng_display.h libmng_dither.h \
+ libmng_error.h libmng_filter.h libmng_jpeg.h libmng_memory.h \
+ libmng_object_prc.h libmng_objects.h libmng_pixels.h \
+ libmng_read.h libmng_trace.h libmng_write.h libmng_zlib.h
+
+
+libmng_la_SOURCES = libmng_callback_xs.c libmng_chunk_io.c \
+ libmng_chunk_prc.c libmng_chunk_xs.c libmng_cms.c \
+ libmng_display.c libmng_dither.c libmng_error.c \
+ libmng_filter.c libmng_hlapi.c libmng_jpeg.c \
+ libmng_object_prc.c libmng_pixels.c libmng_prop_xs.c \
+ libmng_read.c libmng_trace.c libmng_write.c libmng_zlib.c
+
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libmng_la_LIBADD =
+libmng_la_OBJECTS = libmng_callback_xs.lo libmng_chunk_io.lo \
+libmng_chunk_prc.lo libmng_chunk_xs.lo libmng_cms.lo libmng_display.lo \
+libmng_dither.lo libmng_error.lo libmng_filter.lo libmng_hlapi.lo \
+libmng_jpeg.lo libmng_object_prc.lo libmng_pixels.lo libmng_prop_xs.lo \
+libmng_read.lo libmng_trace.lo libmng_write.lo libmng_zlib.lo
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(include_HEADERS) $(noinst_HEADERS)
+
+DIST_COMMON = README Makefile.am Makefile.in acinclude.m4 aclocal.m4 \
+config.guess config.sub configure configure.in install-sh ltmain.sh \
+missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+SOURCES = $(libmng_la_SOURCES)
+OBJECTS = $(libmng_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .obj .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libmng.la: $(libmng_la_OBJECTS) $(libmng_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libmng_la_LDFLAGS) $(libmng_la_OBJECTS) $(libmng_la_LIBADD) $(LIBS)
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-am
+
+install-data-am: install-includeHEADERS
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \
+ clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+ -rm -f config.status
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool uninstall-includeHEADERS \
+install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/README b/tqtinterface/qt4/src/3rdparty/libmng/README
new file mode 100644
index 0000000..0376e12
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/README
@@ -0,0 +1,25 @@
+libmng 1.0.4
+------------
+
+Fourth maintenance release!
+
+Small bug fixes.
+The standard DLL now compiled with zlib 1.1.4 and lcms 1.0.8!
+
+Gerard
+
+
+For more information please visit:
+
+The official libmng web-site:
+ http://www.libmng.com
+
+Libmng's community on SourceForge:
+ https://sourceforge.net/project/?group_id=5635
+
+The official MNG homepage:
+ http://www.libpng.org/pub/mng
+
+The official PNG homepage:
+ http://www.libpng.org/pub/png
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/README.autoconf b/tqtinterface/qt4/src/3rdparty/libmng/README.autoconf
new file mode 100644
index 0000000..abda828
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/README.autoconf
@@ -0,0 +1,195 @@
+Configuration from CVS
+======================
+
+If you're using source checked out from CVS, rather than a source
+distribution tarball, please be aware that you can use ./autogen.sh in
+place of ./configure below.
+
+Because this is a cross-platform project, the source templates for
+the autoconf scripts are sequestered in the 'makefiles' directory.
+Running './autogen.sh' will copy them into their conventional places at
+the lop level. If you already see the files there, you don't need to
+worry about this step.
+
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+tqcontains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source code directory by typing `make clean'. To also remove the
+ files that `configure' created (so you can compile the package for
+ a different kind of computer), type `make distclean'. There is
+ also a `make maintainer-clean' target, but that is intended mainly
+ for the package's developers. If you use it, you may have to get
+ all sorts of other programs in order to regenerate files that came
+ with the distribution.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+ You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory. To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'. `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script. `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+ If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory. After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ In addition, if you use an unusual directory tqlayout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files. Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+tqfind the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Use and save the results of the tests in FILE instead of
+ `./config.cache'. Set FILE to `/dev/null' to disable caching, for
+ debugging `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made. To
+ suppress all normal output, redirect it to `/dev/null' (any error
+ messages will still be shown).
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/README.config b/tqtinterface/qt4/src/3rdparty/libmng/README.config
new file mode 100644
index 0000000..d5cd454
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/README.config
@@ -0,0 +1,104 @@
+Configuration options in libmng
+===============================
+
+The library is fairly configurable through the use of a number of defines.
+Please note however that certain defines are for internal use only.
+The following list gives a summary of options that can be used externally to
+define the functionality of the library:
+
+========================================
+
+#define MNG_BUILD_DLL
+
+This is used to indicate that a "standard" DLL should result from compiling
+the library. Please note the remarks in README.dll if you intend to work
+with the library as a DLL. The purpose of this option is to ensure that
+DLL builds have the same set of functions.
+
+#define MNG_BUILD_SO
+
+This is used to indicate that a "standard" shared library (SO) should result
+from a compilation. The purpose of this option is to ensure that all
+shared libraries generated this way will have the same set of functions.
+
+#define MNG_USE_DLL / #define MNG_USE_SO
+
+These should be used when including the library header in the compilation
+of an application to indicate that the compiler/linker must take the
+necessary steps to make the binary executable to use the standard DLL
+or shared library (SO).
+
+#define MNG_SKIP_ZLIB / #define MNG_SKIP_LCMS / #define MNG_SKIP_IJG6B
+
+Use these in conjunction with MNG_USE_DLL / MNG_USE_SO. This is useful if
+you only need the external definitions of the MNG library and not the others,
+which will speed up the compilation process.
+
+#define MNG_SUPPORT_FULL / #define MNG_SUPPORT_LC / #define MNG_SUPPORT_VLC
+
+These can be used to indicate the level of MNG spec compliance required.
+Currently only full MNG compliance is supported.
+
+#define MNG_SUPPORT_IJG6B
+
+This can be used to indicate if JNG support is required. This option will
+include the IJG JPEG-library. Note that MNG_SUPPORT_FULL will automatically
+set this option. Use this only if you need JNG support with MNG-(V)LC.
+
+#define MNG_FULL_CMS / #define MNG_GAMMA_ONLY / #define MNG_NO_CMS /
+#define MNG_APP_CMS
+
+These indicate the color-correction support level of the library.
+If you are on a platform that supports lcms (Little CMS by Marti Maria Saguar)
+then it is highly recommended to define MNG_FULL_CMS.
+If your platform has it's own CMS then select MNG_APP_CMS and be sure to
+include the appropriate callbacks in your app.
+In all other cases it is recommended to define MNG_GAMMA_ONLY.
+
+#define MNG_SUPPORT_READ / #define MNG_SUPPORT_WRITE /
+#define MNG_SUPPORT_DISPLAY
+
+These indicate the high-level support for reading, writing and/or
+displaying files. Note that in order to display a file, you'll need to read
+it first. (yes, really!)
+
+#define MNG_STORE_CHUNKS
+
+This indicates that the library should store chunk-information when reading
+a file. This information can then be processed through the
+MNG_ITERATE_CHUNKS() function. Note that you must specify this option if
+you want to create and write a new file.
+
+#define MNG_ACCESS_CHUNKS
+
+This is used to indicate that the app may need access to internally stored
+chunk information. MNG_STORE_CHUNKS must be defined as well for this option
+to function properly.
+
+#define MNG_INTERNAL_MEMMNGMT
+
+You can use this to have the library handle it's own memory allocation and
+deallocation through the "standard" memory functions. This option is turned
+off by default, which means your app must define the memory callbacks.
+
+#define MNG_ERROR_TELLTALE
+
+Set this on to allow human-readable error-messages to be included in the
+library and the error function and callback.
+
+#define MNG_BIGENDIAN_SUPPORTED
+
+This option should be used to indicate the hardware is based on big endian
+integers.
+
+#define MNG_SUPPORT_TRACE / #define MNG_TRACE_TELLTALE
+
+These two can be used when debugging an app. You'll need to have the trace
+callback setup also. This allows for a rather thorough investigation of the
+libraries function paths.
+
+========================================
+
+Any other optional defines you may encounter are for internal use only.
+please do not specify them externally. In case of doubt, consult the
+support email lists. More info can be found on http://www.libmng.com
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/README.contrib b/tqtinterface/qt4/src/3rdparty/libmng/README.contrib
new file mode 100644
index 0000000..f5967b2
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/README.contrib
@@ -0,0 +1,79 @@
+The contrib directory tqcontains contributions made by fellow enthousiasts.
+(Check the web-sites for the latest versions)
+
+----------------------------------------------------------------------
+
+mngplg - A Netscape plugin for MNG - by Jason Summers
+
+http://pobox.com/~jason1/imaging/mngplg/
+
+The very first contribution, and what a start!
+GIF look out, MNG is on the prowl and ready to swat you like a fly!
+
+----------------------------------------------------------------------
+
+mngplay - An SDL based MNG viewer - by Ralph Giles
+
+http://snow.ashlu.bc.ca/~giles/mng/
+
+Another nice contribution. View MNG files on practically any platform
+with this standalone viewer.
+Source-code only; Requires SDL library and libmng.so
+
+(Modified by Greg Roelofs)
+
+----------------------------------------------------------------------
+
+mngview - A BCB port of the Delphi sample - by Andy Protano
+
+I have added this nice little port to the BCB samples directory.
+It adds a nifty progressbar while reading a file. Excellent work!
+Requires libmng.dll
+(note: this is in the BCB samples directory)
+
+----------------------------------------------------------------------
+
+mngdump - A BCB GUI-based dump utility - by Andy Protano
+
+Andy has sent me this fully functional MNG dump utility, that gives
+detailed information of the contents of any MNG file.
+Requires libmng.dll
+
+----------------------------------------------------------------------
+
+mng-view - A GTK-based MNG viewer - by Vova Babin
+
+Vova has been hacking away with the libmng code and has come up with
+this nice little sample how to write a MNG viewer using GTK.
+Thanks mate!
+Source-code only
+Requires GTK+ (1.2 or higher) and libmng (0.9.2 or higher)
+
+(Modified by Greg Roelofs)
+
+----------------------------------------------------------------------
+
+mngview - Another MNG viewer; this one for MSVC - by Nicholaus Brennig
+
+A welcome contribution from Nicholaus. Author of SlowView. A very nice
+image-handling utility for Windows. A welcome contribution since there
+have been numerous questions about linking libmng with MSVC.
+Well, look no further. Here it is!
+
+----------------------------------------------------------------------
+
+MSVC libmng project - A MSVC project to build libmng.dll - by Chad Austin
+
+Chad has contributed some project-files that you could use to build
+libmng.dll with MSVC. Please be sure to read the README file included.
+
+----------------------------------------------------------------------
+
+fbmngplay - A simple fbcon based mng player - by Stefan Reinauer
+
+Stefan has contributed this little example, based on Ralph's
+SDL player. It uses the kernel framebuffer tqdevice to display mng
+animations through the libmng interface.
+(currently for 16-bit buffers only)
+
+----------------------------------------------------------------------
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/README.dll b/tqtinterface/qt4/src/3rdparty/libmng/README.dll
new file mode 100644
index 0000000..5ae06c9
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/README.dll
@@ -0,0 +1,41 @@
+Standard Windows DLL
+====================
+
+The DLL provided in the BCB/win32dll directory is meant as the sole candidate
+for distributions, based on libmng.dll, that install the DLL into the public
+Windows system-directory. The outline herein defines the requirements to
+which such a distribution must comply. If you cannot comply with these
+requirements please install the dll in the same directory as your application
+and NOT in the Windows system-directory!!!
+
+
+1) Only the DLL already assembled in the libmng distribution may be used for
+ other distributions!
+
+2) Only stable public releases are eligible for distribution! A public release
+ is one where the y-value of the x.y.z version-code is an even number.
+ Eg. 1.0.0, 1.2.1, 2.4.7, etc.
+
+3) The installation program MUST store the DLL in the Windows system-directory!
+ Eg. C:\WinNT\System32, C:\Windows98\System
+ (Note: InstallShield users can use the <SYSDIR> variable)
+
+3) The installation program MUST flag the file as a shared library!
+
+4) The installation program MUST NOT install the DLL if a newer version
+ already exists in the Windows system-directory! The standard DLL provided
+ tqcontains the Windows-default version-numbering system. PLEASE USE IT!!
+ DO NOT rely on the date or size of the files.
+
+5) An uninstall procedure MAY NOT remove the DLL if other applications are
+ still linked to it! Proper handling as a shared library is imperitive.
+
+6) TEST IT, TEST IT, TEST IT!!! (I just can't stress this enough)
+ If you don't have enough time, let someone else test it BEFORE you
+ distribute!
+
+
+The penalty for violating these rules is inclusion of your name in the list
+of endangered but useless species (just below the GIF entry!), and on my
+blacklist. YOU HAVE BEEN FOREWARNED!
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/README.examples b/tqtinterface/qt4/src/3rdparty/libmng/README.examples
new file mode 100644
index 0000000..66dc5cb
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/README.examples
@@ -0,0 +1,43 @@
+The samples are in platform-specific directories.
+
+!!! contributions are very welcome !!!
+
+
+bcb - Borland C++ Builder (3.0)
+-------------------------------
+
+win32dll - sample project to create a Windows dll. Requires zlib1.1.3,
+ IJG jpgsrc6b and lcms1.0.6. The directories containing these
+ libraries must be at the same level as the libmng directory.
+ So if you're in the directory with this file and the libmng
+ sources, they should be in ..\zlib , ..\jpgsrc6b and ..\lcms
+ respectively.
+
+!!! To run the other Win32 samples you need to copy the libmng.dll
+ file from here into the sample's directory !!!
+
+mngtree - sample project to create a little command-line tool that dumps
+ the chunk-structure of a given file onto stdout.
+
+bogus - a completely bogus example on how to create a perfectly valid
+ (though slightly biased) MNG.
+
+mngview - port of the Delphi mngview sample. contributed by Andy Protano.
+ see also README.contrib
+
+
+delphi - Borland Delphi (3.0+)
+------------------------------
+
+mngview - sample project for a simple mng-viewer. The general unit in
+ the delphi directory was translated from libmng.h It can be
+ used in other projects to access libmng.dll created with the
+ win32dll example above.
+
+
+unix - Unix
+-----------
+
+mngtree - basically a copy of the BCB sample. It includes a makefile for
+ Linux and it's been tested on RedHat6.2
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/README.packaging b/tqtinterface/qt4/src/3rdparty/libmng/README.packaging
new file mode 100644
index 0000000..da0db3e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/README.packaging
@@ -0,0 +1,24 @@
+Packaging Libmng for distribution
+---------------------------------
+
+These are some notes for those building binaries for distribution.
+
+We're interested to hear about anywhere libmng is helpful, so let us
+know if you're including it with your application or OS. Also, if your
+build is publicly accessible, we'd be happy to link to it from
+the libmng site.
+
+However, We respectfully request that you *not* distribute binaries as a
+shared library (DLL) with any of the major features disabled. While
+there is support for this in terms of #ifdef directives (in
+libmng_conf.h) and autoconf switches they are intended for embedded
+application and testing. The default compilation options support the
+full MNG specification, and we wish to avoid the confusion among
+general users that partial support would engender.
+
+
+Platform specific notes:
+
+We have a basic .spec file for generating rpms. Send us a note if you'd
+like to clean it up.
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/acinclude.m4 b/tqtinterface/qt4/src/3rdparty/libmng/acinclude.m4
new file mode 100644
index 0000000..60506df
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/acinclude.m4
@@ -0,0 +1,74 @@
+#serial 12
+
+dnl By default, many hosts won't let programs access large files;
+dnl one must use special compiler options to get large-file access to work.
+dnl For more details about this brain damage please see:
+dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
+
+dnl Written by Paul Eggert <eggert@twinsun.com>.
+
+dnl Internal subroutine of AC_SYS_LARGEFILE.
+dnl AC_SYS_LARGEFILE_TEST_INCLUDES
+AC_DEFUN(AC_SYS_LARGEFILE_TEST_INCLUDES,
+ [[#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+ ]])
+
+dnl Internal subroutine of AC_SYS_LARGEFILE.
+dnl AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, CACHE-VAR, COMMENT, INCLUDES, FUNCTION-BODY)
+AC_DEFUN(AC_SYS_LARGEFILE_MACRO_VALUE,
+ [AC_CACHE_CHECK([for $1 value needed for large files], $3,
+ [$3=no
+ AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES
+$5
+ ,
+ [$6],
+ ,
+ [AC_TRY_COMPILE([#define $1 $2]
+AC_SYS_LARGEFILE_TEST_INCLUDES
+$5
+ ,
+ [$6],
+ [$3=$2])])])
+ if test "[$]$3" != no; then
+ AC_DEFINE_UNQUOTED([$1], [$]$3, [$4])
+ fi])
+
+AC_DEFUN(AC_SYS_LARGEFILE,
+ [AC_ARG_ENABLE(largefile,
+ [ --disable-largefile omit support for large files])
+ if test "$enable_largefile" != no; then
+
+ AC_CACHE_CHECK([for special C compiler options needed for large files],
+ ac_cv_sys_largefile_CC,
+ [ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, , ,
+ [ac_save_CC="$CC"
+ CC="$CC -n32"
+ AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, ,
+ ac_cv_sys_largefile_CC=' -n32')
+ CC="$ac_save_CC"])
+ fi])
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC="$CC$ac_cv_sys_largefile_CC"
+ fi
+
+ AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64,
+ ac_cv_sys_file_offset_bits,
+ [Number of bits in a file offset, on hosts where this is settable.])
+ AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, 1,
+ ac_cv_sys_largefile_source,
+ [Define to make ftello visible on some hosts (e.g. HP-UX 10.20).],
+ [#include <stdio.h>], [return !ftello;])
+ AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1,
+ ac_cv_sys_large_files,
+ [Define for large files, on AIX-style hosts.])
+ AC_SYS_LARGEFILE_MACRO_VALUE(_XOPEN_SOURCE, 500,
+ ac_cv_sys_xopen_source,
+ [Define to make ftello visible on some hosts (e.g. glibc 2.1.3).],
+ [#include <stdio.h>], [return !ftello;])
+ fi
+ ])
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/aclocal.m4 b/tqtinterface/qt4/src/3rdparty/libmng/aclocal.m4
new file mode 100644
index 0000000..bf03601
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/aclocal.m4
@@ -0,0 +1,3806 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4-p5
+
+dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+#serial 12
+
+dnl By default, many hosts won't let programs access large files;
+dnl one must use special compiler options to get large-file access to work.
+dnl For more details about this brain damage please see:
+dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
+
+dnl Written by Paul Eggert <eggert@twinsun.com>.
+
+dnl Internal subroutine of AC_SYS_LARGEFILE.
+dnl AC_SYS_LARGEFILE_TEST_INCLUDES
+AC_DEFUN(AC_SYS_LARGEFILE_TEST_INCLUDES,
+ [[#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+ ]])
+
+dnl Internal subroutine of AC_SYS_LARGEFILE.
+dnl AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, CACHE-VAR, COMMENT, INCLUDES, FUNCTION-BODY)
+AC_DEFUN(AC_SYS_LARGEFILE_MACRO_VALUE,
+ [AC_CACHE_CHECK([for $1 value needed for large files], $3,
+ [$3=no
+ AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES
+$5
+ ,
+ [$6],
+ ,
+ [AC_TRY_COMPILE([#define $1 $2]
+AC_SYS_LARGEFILE_TEST_INCLUDES
+$5
+ ,
+ [$6],
+ [$3=$2])])])
+ if test "[$]$3" != no; then
+ AC_DEFINE_UNQUOTED([$1], [$]$3, [$4])
+ fi])
+
+AC_DEFUN(AC_SYS_LARGEFILE,
+ [AC_ARG_ENABLE(largefile,
+ [ --disable-largefile omit support for large files])
+ if test "$enable_largefile" != no; then
+
+ AC_CACHE_CHECK([for special C compiler options needed for large files],
+ ac_cv_sys_largefile_CC,
+ [ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, , ,
+ [ac_save_CC="$CC"
+ CC="$CC -n32"
+ AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, ,
+ ac_cv_sys_largefile_CC=' -n32')
+ CC="$ac_save_CC"])
+ fi])
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC="$CC$ac_cv_sys_largefile_CC"
+ fi
+
+ AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64,
+ ac_cv_sys_file_offset_bits,
+ [Number of bits in a file offset, on hosts where this is settable.])
+ AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, 1,
+ ac_cv_sys_largefile_source,
+ [Define to make ftello visible on some hosts (e.g. HP-UX 10.20).],
+ [#include <stdio.h>], [return !ftello;])
+ AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1,
+ ac_cv_sys_large_files,
+ [Define for large files, on AIX-style hosts.])
+ AC_SYS_LARGEFILE_MACRO_VALUE(_XOPEN_SOURCE, 500,
+ ac_cv_sys_xopen_source,
+ [Define to make ftello visible on some hosts (e.g. glibc 2.1.3).],
+ [#include <stdio.h>], [return !ftello;])
+ fi
+ ])
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN([AM_MISSING_PROG],
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# isc-posix.m4 serial 1 (gettext-0.10.40)
+dnl Copyright (C) 1995-2002 Free Software Foundation, Inc.
+dnl This file is free software, distributed under the terms of the GNU
+dnl General Public License. As a special exception to the GNU General
+dnl Public License, this file may be distributed as part of a program
+dnl that tqcontains a configuration script generated by Autoconf, under
+dnl the same distribution terms as the rest of that program.
+
+# This test tqreplaces the one in autoconf.
+# Currently this macro should have the same name as the autoconf macro
+# because gettext's gettext.m4 (distributed in the automake package)
+# still uses it. Otherwise, the use in gettext.m4 makes autoheader
+# give these diagnostics:
+# configure.in:556: AC_TRY_COMPILE was called before AC_ISC_POSIX
+# configure.in:556: AC_TRY_RUN was called before AC_ISC_POSIX
+
+undefine([AC_ISC_POSIX])
+
+AC_DEFUN([AC_ISC_POSIX],
+ [
+ dnl This test tqreplaces the obsolescent AC_ISC_POSIX kludge.
+ AC_CHECK_LIB(cposix, strerror, [LIBS="$LIBS -lcposix"])
+ ]
+)
+
+
+# serial 1
+
+AC_DEFUN([AM_C_PROTOTYPES],
+[AC_REQUIRE([AM_PROG_CC_STDC])
+AC_REQUIRE([AC_PROG_CPP])
+AC_MSG_CHECKING([for function prototypes])
+if test "$am_cv_prog_cc_stdc" != no; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(PROTOTYPES,1,[Define if compiler has function prototypes])
+ U= ANSI2KNR=
+else
+ AC_MSG_RESULT(no)
+ U=_ ANSI2KNR=./ansi2knr
+ # Ensure some checks needed by ansi2knr itself.
+ AC_HEADER_STDC
+ AC_CHECK_HEADERS(string.h)
+fi
+AC_SUBST(U)dnl
+AC_SUBST(ANSI2KNR)dnl
+])
+
+
+# serial 1
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so. This macro tries various
+# options that select ANSI C on some system or another. It considers the
+# compiler to be in ANSI C mode if it handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{am_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+AC_DEFUN([AM_PROG_CC_STDC],
+[AC_REQUIRE([AC_PROG_CC])
+AC_BEFORE([$0], [AC_C_INLINE])
+AC_BEFORE([$0], [AC_C_CONST])
+dnl Force this before AC_PROG_CPP. Some cpp's, eg on HPUX, require
+dnl a magic option to avoid problems with ANSI preprocessor commands
+dnl like #elif.
+dnl FIXME: can't do this because then AC_AIX won't work due to a
+dnl circular dependency.
+dnl AC_BEFORE([$0], [AC_PROG_CPP])
+AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(am_cv_prog_cc_stdc,
+[am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ AC_TRY_COMPILE(
+[#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+], [
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+],
+[am_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CC="$ac_save_CC"
+])
+if test -z "$am_cv_prog_cc_stdc"; then
+ AC_MSG_RESULT([none needed])
+else
+ AC_MSG_RESULT($am_cv_prog_cc_stdc)
+fi
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+])
+
+# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*-
+
+# serial 46 AC_PROG_LIBTOOL
+
+AC_DEFUN([AC_PROG_LIBTOOL],
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Prevent multiple expansion
+define([AC_PROG_LIBTOOL], [])
+])
+
+AC_DEFUN([AC_LIBTOOL_SETUP],
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl
+AC_REQUIRE([AC_OBJEXT])dnl
+AC_REQUIRE([AC_EXEEXT])dnl
+dnl
+
+_LT_AC_PROG_ECHO_BACKSLASH
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ AC_PATH_MAGIC
+ fi
+ ;;
+esac
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(STRIP, strip, :)
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no)
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+enable_win32_dll=yes, enable_win32_dll=no)
+
+AC_ARG_ENABLE(libtool-lock,
+ [ --disable-libtool-lock avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_LANG_SAVE
+ AC_LANG_C
+ AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+ AC_LANG_RESTORE])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw* | *-*-pw32*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one
+ AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain,
+ [AC_TRY_LINK([],
+ [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*);
+ DllMain (0, 0, 0);],
+ [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])])
+
+ case $host/$CC in
+ *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*)
+ # old mingw systems require "-dll" to link a DLL, while more recent ones
+ # require "-mdll"
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -mdll"
+ AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch,
+ [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])])
+ CFLAGS="$SAVE_CFLAGS" ;;
+ *-*-cygwin* | *-*-pw32*)
+ # cygwin systems need to pass --dll to the linker, and not link
+ # crt.o which will require a WinMain@16 definition.
+ lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;;
+ esac
+ ;;
+ ])
+esac
+
+_LT_AC_LTCONFIG_HACK
+
+])
+
+# AC_LIBTOOL_HEADER_ASSERT
+# ------------------------
+AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT],
+[AC_CACHE_CHECK([whether $CC supports assert without backlinking],
+ [lt_cv_func_assert_works],
+ [case $host in
+ *-*-solaris*)
+ if test "$GCC" = yes && test "$with_gnu_ld" != yes; then
+ case `$CC --version 2>/dev/null` in
+ [[12]].*) lt_cv_func_assert_works=no ;;
+ *) lt_cv_func_assert_works=yes ;;
+ esac
+ fi
+ ;;
+ esac])
+
+if test "x$lt_cv_func_assert_works" = xyes; then
+ AC_CHECK_HEADERS(assert.h)
+fi
+])# AC_LIBTOOL_HEADER_ASSERT
+
+# _LT_AC_CHECK_DLFCN
+# --------------------
+AC_DEFUN([_LT_AC_CHECK_DLFCN],
+[AC_CHECK_HEADERS(dlfcn.h)
+])# _LT_AC_CHECK_DLFCN
+
+# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+# ---------------------------------
+AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE],
+[AC_REQUIRE([AC_CANONICAL_HOST])
+AC_REQUIRE([AC_PROG_NM])
+AC_REQUIRE([AC_OBJEXT])
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[[BCDT]]'
+ ;;
+cygwin* | mingw* | pw32*)
+ symcode='[[ABCDGISTW]]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ ;;
+irix*)
+ symcode='[[BCDEGRST]]'
+ ;;
+solaris* | sysv5*)
+ symcode='[[BDT]]'
+ ;;
+sysv4)
+ symcode='[[DFNSTU]]'
+ ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $host_os in
+mingw*)
+ opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[[ABCDGISTW]]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Write the raw and C identifiers.
+lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+ rm -f conftest*
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext'
+
+ cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr address;
+}
+lt_preloaded_symbols[[]] =
+{
+EOF
+ sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext
+ cat <<\EOF >> conftest.$ac_ext
+ {0, (lt_ptr) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ pipe_works=yes
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+ else
+ echo "cannot tqfind nm_test_func in $nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot tqfind nm_test_var in $nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+ else
+ echo "$progname: failed program was:" >&AC_FD_CC
+ cat conftest.$ac_ext >&5
+ fi
+ rm -f conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+global_symbol_pipe="$lt_cv_sys_global_symbol_pipe"
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ global_symbol_to_cdecl=
+ global_symbol_to_c_name_address=
+else
+ global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl"
+ global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address"
+fi
+if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
+then
+ AC_MSG_RESULT(failed)
+else
+ AC_MSG_RESULT(ok)
+fi
+]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE
+
+# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+# ---------------------------------
+AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR],
+[# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) lt_cv_sys_path_separator=';' ;;
+ *) lt_cv_sys_path_separator=':' ;;
+ esac
+ PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+
+# _LT_AC_PROG_ECHO_BACKSLASH
+# --------------------------
+# Add some code to the start of the generated configure script which
+# will tqfind an echo command which doesn't interpret backslashes.
+AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH],
+[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+ [AC_DIVERT_PUSH(NOTICE)])
+_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+ ;;
+esac
+
+echo=${ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X[$]1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# tqfind a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+ then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't tqfind a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+ else
+ # Try using printf.
+ echo='printf %s\n'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL [$]0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$CONFIG_SHELL [$]0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "[$]0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+ ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(ECHO)
+AC_DIVERT_POP
+])# _LT_AC_PROG_ECHO_BACKSLASH
+
+# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ------------------------------------------------------------------
+AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF],
+[if test "$cross_compiling" = yes; then :
+ [$4]
+else
+ AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ tqfind out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+
+ exit (status);
+}]
+EOF
+ if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) $1 ;;
+ x$lt_dlneed_uscore) $2 ;;
+ x$lt_unknown|x*) $3 ;;
+ esac
+ else :
+ # compilation failed
+ $3
+ fi
+fi
+rm -fr conftest*
+])# _LT_AC_TRY_DLOPEN_SELF
+
+# AC_LIBTOOL_DLOPEN_SELF
+# -------------------
+AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF],
+[if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ *)
+ AC_CHECK_FUNC([shl_load],
+ [lt_cv_dlopen="shl_load"],
+ [AC_CHECK_LIB([dld], [shl_load],
+ [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"],
+ [AC_CHECK_FUNC([dlopen],
+ [lt_cv_dlopen="dlopen"],
+ [AC_CHECK_LIB([dl], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+ [AC_CHECK_LIB([svld], [dlopen],
+ [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+ [AC_CHECK_LIB([dld], [dld_link],
+ [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"])
+ ])
+ ])
+ ])
+ ])
+ ])
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ AC_CACHE_CHECK([whether a program can dlopen itself],
+ lt_cv_dlopen_self, [dnl
+ _LT_AC_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+ lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+ ])
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ LDFLAGS="$LDFLAGS $link_static_flag"
+ AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+ lt_cv_dlopen_self_static, [dnl
+ _LT_AC_TRY_DLOPEN_SELF(
+ lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+ lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross)
+ ])
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+])# AC_LIBTOOL_DLOPEN_SELF
+
+AC_DEFUN([_LT_AC_LTCONFIG_HACK],
+[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([[\\"\\`$\\\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([[\\"\\`\\\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+need_locks="$enable_libtool_lock"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+if test x"$host" != x"$build"; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case $host_os in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+ ;;
+ *)
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="[$]2"
+
+AC_MSG_CHECKING([for objdir])
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+AC_MSG_RESULT($objdir)
+
+
+AC_ARG_WITH(pic,
+[ --with-pic try to use only PIC/non-PIC objects [default=use both]],
+pic_mode="$withval", pic_mode=default)
+test -z "$pic_mode" && pic_mode=default
+
+# We assume here that the value for lt_cv_prog_cc_pic will not be cached
+# in isolation, and that seeing it set (from the cache) indicates that
+# the associated values are set (in the cache) correctly too.
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+AC_CACHE_VAL(lt_cv_prog_cc_pic,
+[ lt_cv_prog_cc_pic=
+ lt_cv_prog_cc_shlib=
+ lt_cv_prog_cc_wl=
+ lt_cv_prog_cc_static=
+ lt_cv_prog_cc_no_builtin=
+ lt_cv_prog_cc_can_build_shared=$can_build_shared
+
+ if test "$GCC" = yes; then
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-static'
+
+ case $host_os in
+ aix*)
+ # Below there is a dirty hack to force normal static linking with -ldl
+ # The problem is because libdl dynamically linked with both libc and
+ # libC (AIX C++ library), which obviously doesn't included in libraries
+ # list by gcc. This cause undefined symbols with -static flags.
+ # This hack allows C programs to be linked with "-static -ldl", but
+ # not sure about C++ programs.
+ lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC"
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_cv_prog_cc_pic='-fno-common'
+ ;;
+ cygwin* | mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_cv_prog_cc_pic='-DDLL_EXPORT'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_cv_prog_cc_pic=-Kconform_pic
+ fi
+ ;;
+ *)
+ lt_cv_prog_cc_pic='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for PIC flags for the system compiler.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ lt_cv_prog_cc_wl='-Wl,'
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_cv_prog_cc_static='-Bstatic'
+ else
+ lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ # Is there a better lt_cv_prog_cc_static that works with the bundled CC?
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive"
+ lt_cv_prog_cc_pic='+Z'
+ ;;
+
+ irix5* | irix6*)
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ cygwin* | mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_cv_prog_cc_pic='-DDLL_EXPORT'
+ ;;
+
+ newsos6)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ # All OSF/1 code is PIC.
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ lt_cv_prog_cc_pic='-Kpic'
+ lt_cv_prog_cc_static='-dn'
+ lt_cv_prog_cc_shlib='-belf'
+ ;;
+
+ solaris*)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ lt_cv_prog_cc_wl='-Wl,'
+ ;;
+
+ sunos4*)
+ lt_cv_prog_cc_pic='-PIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ lt_cv_prog_cc_wl='-Qoption ld '
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ if test "x$host_vendor" = xsni; then
+ lt_cv_prog_cc_wl='-LD'
+ else
+ lt_cv_prog_cc_wl='-Wl,'
+ fi
+ ;;
+
+ uts4*)
+ lt_cv_prog_cc_pic='-pic'
+ lt_cv_prog_cc_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_cv_prog_cc_pic='-Kconform_pic'
+ lt_cv_prog_cc_static='-Bstatic'
+ fi
+ ;;
+
+ *)
+ lt_cv_prog_cc_can_build_shared=no
+ ;;
+ esac
+ fi
+])
+if test -z "$lt_cv_prog_cc_pic"; then
+ AC_MSG_RESULT([none])
+else
+ AC_MSG_RESULT([$lt_cv_prog_cc_pic])
+
+ # Check to make sure the pic_flag actually works.
+ AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works])
+ AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
+ AC_TRY_COMPILE([], [], [dnl
+ case $host_os in
+ hpux9* | hpux10* | hpux11*)
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then
+ # they create non-PIC objects. So, if there were any warnings, we
+ # assume that PIC is not supported.
+ if test -s conftest.err; then
+ lt_cv_prog_cc_pic_works=no
+ else
+ lt_cv_prog_cc_pic_works=yes
+ fi
+ ;;
+ *)
+ lt_cv_prog_cc_pic_works=yes
+ ;;
+ esac
+ ], [dnl
+ lt_cv_prog_cc_pic_works=no
+ ])
+ CFLAGS="$save_CFLAGS"
+ ])
+
+ if test "X$lt_cv_prog_cc_pic_works" = Xno; then
+ lt_cv_prog_cc_pic=
+ lt_cv_prog_cc_can_build_shared=no
+ else
+ lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
+ fi
+
+ AC_MSG_RESULT([$lt_cv_prog_cc_pic_works])
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$lt_cv_prog_cc_shlib"; then
+ AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries])
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[[ ]]$lt_cv_prog_cc_shlib[[ ]]" >/dev/null; then :
+ else
+ AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure])
+ lt_cv_prog_cc_can_build_shared=no
+ fi
+fi
+
+AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works])
+AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl
+ lt_cv_prog_cc_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
+ AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes])
+ LDFLAGS="$save_LDFLAGS"
+])
+
+# Belt *and* braces to stop my trousers falling down:
+test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
+AC_MSG_RESULT([$lt_cv_prog_cc_static_works])
+
+pic_flag="$lt_cv_prog_cc_pic"
+special_shlib_compile_flags="$lt_cv_prog_cc_shlib"
+wl="$lt_cv_prog_cc_wl"
+link_static_flag="$lt_cv_prog_cc_static"
+no_builtin_flag="$lt_cv_prog_cc_no_builtin"
+can_build_shared="$lt_cv_prog_cc_can_build_shared"
+
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext])
+AC_CACHE_VAL([lt_cv_compiler_c_o], [
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+echo "int some_variable = 0;" > conftest.$ac_ext
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory. Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+compiler_c_o=no
+if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+ lt_cv_compiler_c_o=no
+ else
+ lt_cv_compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat out/conftest.err 1>&AC_FD_CC
+ lt_cv_compiler_c_o=no
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+])
+compiler_c_o=$lt_cv_compiler_c_o
+AC_MSG_RESULT([$compiler_c_o])
+
+if test x"$compiler_c_o" = x"yes"; then
+ # Check to see if we can write to a .lo
+ AC_MSG_CHECKING([if $compiler supports -c -o file.lo])
+ AC_CACHE_VAL([lt_cv_compiler_o_lo], [
+ lt_cv_compiler_o_lo=no
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -c -o conftest.lo"
+ save_objext="$ac_objext"
+ ac_objext=lo
+ AC_TRY_COMPILE([], [int some_variable = 0;], [dnl
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ lt_cv_compiler_o_lo=no
+ else
+ lt_cv_compiler_o_lo=yes
+ fi
+ ])
+ ac_objext="$save_objext"
+ CFLAGS="$save_CFLAGS"
+ ])
+ compiler_o_lo=$lt_cv_compiler_o_lo
+ AC_MSG_RESULT([$compiler_o_lo])
+else
+ compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ AC_MSG_CHECKING([if we can lock with hard links])
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ AC_MSG_RESULT([$hard_links])
+ if test "$hard_links" = no; then
+ AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe])
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+if test "$GCC" = yes; then
+ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+ AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions])
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
+ compiler_rtti_exceptions=no
+ AC_TRY_COMPILE([], [int some_variable = 0;], [dnl
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ compiler_rtti_exceptions=no
+ else
+ compiler_rtti_exceptions=yes
+ fi
+ ])
+ CFLAGS="$save_CFLAGS"
+ AC_MSG_RESULT([$compiler_rtti_exceptions])
+
+ if test "$compiler_rtti_exceptions" = "yes"; then
+ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+ else
+ no_builtin_flag=' -fno-builtin'
+ fi
+fi
+
+# See if the linker supports building shared libraries.
+AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries])
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+old_archive_from_expsyms_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_into_libs=no
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+link_all_deplibs=unknown
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that tqcontains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced. Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+extract_expsyms_cmds=
+
+case $host_os in
+cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ # On AIX, the GNU linker is very broken
+ # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available.
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can use
+ # them.
+ ld_shlibs=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+
+ extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
+ sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~
+ test -f $output_objdir/impgen.exe || (cd $output_objdir && \
+ if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
+ else $CC -o impgen impgen.c ; fi)~
+ $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
+
+ old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
+
+ # cygwin and mingw dlls have different entry points and sets of symbols
+ # to exclude.
+ # FIXME: what about values for MSVC?
+ dll_entry=__cygwin_dll_entry@12
+ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
+ case $host_os in
+ mingw*)
+ # mingw values
+ dll_entry=_DllMainCRTStartup@12
+ dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
+ ;;
+ esac
+
+ # mingw and cygwin differ, and it's simplest to just exclude the union
+ # of the two symbol sets.
+ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one (in ltdll.c)
+ if test "x$lt_cv_need_dllmain" = "xyes"; then
+ ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext "
+ ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~
+ test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
+ else
+ ltdll_obj=
+ ltdll_cmds=
+ fi
+
+ # Extract the symbol export list from an `--export-all' def file,
+ # then regenerate the def file from the symbol export list, so that
+ # the compiled dll only exports the symbol export list.
+ # Be careful not to strip the DATA tag left be newer dlltools.
+ export_symbols_cmds="$ltdll_cmds"'
+ $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
+ sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
+
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is.
+ # If DATA tags from a recent dlltool are present, honour them!
+ archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname-def;
+ else
+ echo EXPORTS > $output_objdir/$soname-def;
+ _lt_hint=1;
+ cat $export_symbols | while read symbol; do
+ set dummy \$symbol;
+ case \[$]# in
+ 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
+ *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;;
+ esac;
+ _lt_hint=`expr 1 + \$_lt_hint`;
+ done;
+ fi~
+ '"$ltdll_cmds"'
+ $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
+ $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
+ $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris* | sysv5*)
+ if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+ elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = yes; then
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ case $host_os in
+ cygwin* | mingw* | pw32*)
+ # dlltool doesn't understand --whole-archive et. al.
+ whole_archive_flag_spec=
+ ;;
+ *)
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ ;;
+ esac
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ hardcode_direct=yes
+ archive_cmds=''
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[[012]]|aix4.[[012]].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ hardcode_direct=yes
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to tqfind uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ esac
+
+ shared_flag='-shared'
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ shared_flag='${wl}-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ # It seems that -bexpall can do strange things, so it is better to
+ # generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
+ archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ else
+ hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib'
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='${wl}-berok'
+ # This is a bit strange, but is similar to how AIX traditionally builds
+ # it's shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ ;;
+
+ darwin* | rhapsody*)
+ case "$host_os" in
+ rhapsody* | darwin1.[[012]])
+ allow_undefined_flag='-undefined suppress'
+ ;;
+ *) # Darwin 1.3 on
+ allow_undefined_flag='-flat_namespace -undefined suppress'
+ ;;
+ esac
+ # FIXME: Relying on posixy $() will cause problems for
+ # cross-compilation, but unfortunately the echo tests do not
+ # yet detect zsh echo's removal of \ escapes.
+ archive_cmds='$nonopt $(test "x$module" = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
+ # We need to add '_' to the symbols in $export_symbols first
+ #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ whole_archive_flag_spec='-all_load $convenience'
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ case $host_os in
+ hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
+ *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
+ esac
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_minus_L=yes # Not in the search PATH, but as the default
+ # location of the library.
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case "$host_os" in
+ openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+ #Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ ;;
+
+ solaris*)
+ # gcc --version < 3.0 without binutils cannot create self contained
+ # shared libraries reliably, requiring libgcc.a to resolve some of
+ # the object symbols generated in some cases. Libraries that use
+ # assert need libgcc.a to resolve __eprintf, for example. Linking
+ # a copy of libgcc.a into every shared library to guarantee resolving
+ # such symbols causes other problems: According to Tim Van Holder
+ # <tim.van.holder@pandora.be>, C++ libraries end up with a separate
+ # (to the application) exception stack for one thing.
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ case `$CC --version 2>/dev/null` in
+ [[12]].*)
+ cat <<EOF 1>&2
+
+*** Warning: Releases of GCC earlier than version 3.0 cannot reliably
+*** create self contained shared libraries on Solaris systems, without
+*** introducing a dependency on libgcc.a. Therefore, libtool is disabling
+*** -no-undefined support, which will at least allow you to build shared
+*** libraries. However, you may tqfind that when you link such libraries
+*** into an application without using GCC, you have to manually add
+*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to
+*** upgrade to a newer version of GCC. Another option is to rebuild your
+*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer.
+
+EOF
+ no_undefined_flag=
+ ;;
+ esac
+ fi
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+ *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ if test "x$host_vendor" = xsno; then
+ archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ else
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv5*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ hardcode_libdir_flag_spec=
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4.2uw2*)
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ hardcode_runpath_var=yes
+ runpath_var=LD_RUN_PATH
+ ;;
+
+ sysv5uw7* | unixware7*)
+ no_undefined_flag='${wl}-z ${wl}text'
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+AC_MSG_RESULT([$ld_shlibs])
+test "$ld_shlibs" = no && can_build_shared=no
+
+# Check hardcoding attributes.
+AC_MSG_CHECKING([how to hardcode library paths into programs])
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$hardcode_shlibpath_var" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+AC_MSG_RESULT([$hardcode_action])
+
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+# PORTME Fill in your ld.so characteristics
+AC_MSG_CHECKING([dynamic linker characteristics])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so$major'
+ ;;
+
+aix4* | aix5*)
+ version_type=linux
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[[01]] | aix4.[[01]].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can
+ # not hardcode correct soname into executable. Probably we can
+ # add versioning support to collect2, so additional links can
+ # be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}.so$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}.so'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi4*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ export_dynamic_flag_spec=-rdynamic
+ # the default ld.so.conf also tqcontains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32*)
+ version_type=windows
+ need_version=no
+ need_lib_prefix=no
+ case $GCC,$host_os in
+ yes,cygwin*)
+ library_names_spec='$libname.dll.a'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
+ postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog .libs/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $rm \$dlpath'
+ ;;
+ yes,mingw*)
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
+ ;;
+ yes,pw32*)
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+ ;;
+ *)
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ # FIXME: Relying on posixy $() will cause problems for
+ # cross-compilation, but unfortunately the echo tests do not
+ # yet detect zsh echo's removal of \ escapes.
+ library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)'
+ soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ *)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+ soname_spec='${libname}${release}.sl$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5* | irix6*)
+ version_type=irix
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
+ case $host_os in
+ irix5*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+openbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case "$host_os" in
+ openbsd2.[[89]] | openbsd2.[[89]].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ need_lib_prefix=no
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_version=no
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+ soname_spec='$libname.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+AC_MSG_CHECKING([if libtool supports shared libraries])
+AC_MSG_RESULT([$can_build_shared])
+
+AC_MSG_CHECKING([whether to build shared libraries])
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+esac
+AC_MSG_RESULT([$enable_shared])
+
+AC_MSG_CHECKING([whether to build static libraries])
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+AC_MSG_RESULT([$enable_static])
+
+if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+AC_LIBTOOL_DLOPEN_SELF
+
+if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+ AC_CACHE_VAL([lt_cv_archive_cmds_need_lc],
+ [$rm conftest*
+ echo 'static int dummy;' > conftest.$ac_ext
+
+ if AC_TRY_EVAL(ac_compile); then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_cv_prog_cc_wl
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1)
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi])
+ AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc])
+ ;;
+ esac
+fi
+need_lc=${lt_cv_archive_cmds_need_lc-yes}
+
+# The second clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+ :
+else
+ # If there is no Makefile yet, we rely on a make rule to execute
+ # `config.status --recheck' to rerun these tests and create the
+ # libtool script then.
+ test -f Makefile && make "$ltmain"
+fi
+
+if test -f "$ltmain"; then
+ trap "$rm \"${ofile}T\"; exit 1" 1 2 15
+ $rm -f "${ofile}T"
+
+ echo creating $ofile
+
+ # Now quote all the things that may contain metacharacters while being
+ # careful not to overquote the AC_SUBSTed values. We take copies of the
+ # variables and quote the copies for generation of the libtool script.
+ for var in echo old_CC old_CFLAGS \
+ AR AR_FLAGS CC LD LN_S NM SHELL \
+ reload_flag reload_cmds wl \
+ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+ library_names_spec soname_spec \
+ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \
+ postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \
+ old_striplib striplib file_magic_cmd export_symbols_cmds \
+ deplibs_check_method allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+ global_symbol_to_c_name_address \
+ hardcode_libdir_flag_spec hardcode_libdir_separator \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+ case $var in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+ extract_expsyms_cmds | old_archive_from_expsyms_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ cat <<__EOF__ > "${ofile}T"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996-2000 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that tqcontains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$need_lc
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# The default C compiler.
+CC=$lt_CC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that tqcontains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_pic_flag
+pic_mode=$pic_mode
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$lt_compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker tqfinds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+ case $host_os in
+ aix3*)
+ cat <<\EOF >> "${ofile}T"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2*)
+ cat <<'EOF' >> "${ofile}T"
+ # This is a source program that is used to create dlls on Windows
+ # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+ # This is a source program that is used to create import libraries
+ # on Windows for dlls which lack them. Don't remove nor modify the
+ # starting and closing comments
+# /* impgen.c starts here */
+# /* Copyright (C) 1999-2000 Free Software Foundation, Inc.
+#
+# This file is part of GNU libtool.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# */
+#
+# #include <stdio.h> /* for printf() */
+# #include <unistd.h> /* for open(), lseek(), read() */
+# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
+# #include <string.h> /* for strdup() */
+#
+# /* O_BINARY isn't required (or even defined sometimes) under Unix */
+# #ifndef O_BINARY
+# #define O_BINARY 0
+# #endif
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[2];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 2);
+# return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[4];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 4);
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+# void *ptr;
+# {
+# unsigned char *b = ptr;
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+# int argc;
+# char *argv[];
+# {
+# int dll;
+# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+# unsigned long export_rva, export_size, nsections, secptr, expptr;
+# unsigned long name_rvas, nexp;
+# unsigned char *expdata, *erva;
+# char *filename, *dll_name;
+#
+# filename = argv[1];
+#
+# dll = open(filename, O_RDONLY|O_BINARY);
+# if (dll < 1)
+# return 1;
+#
+# dll_name = filename;
+#
+# for (i=0; filename[i]; i++)
+# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+# dll_name = filename + i +1;
+#
+# pe_header_offset = pe_get32 (dll, 0x3c);
+# opthdr_ofs = pe_header_offset + 4 + 20;
+# num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+# if (num_entries < 1) /* no exports */
+# return 1;
+#
+# export_rva = pe_get32 (dll, opthdr_ofs + 96);
+# export_size = pe_get32 (dll, opthdr_ofs + 100);
+# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+# secptr = (pe_header_offset + 4 + 20 +
+# pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+# expptr = 0;
+# for (i = 0; i < nsections; i++)
+# {
+# char sname[8];
+# unsigned long secptr1 = secptr + 40 * i;
+# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# lseek(dll, secptr1, SEEK_SET);
+# read(dll, sname, 8);
+# if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# {
+# expptr = fptr + (export_rva - vaddr);
+# if (export_rva + export_size > vaddr + vsize)
+# export_size = vsize - (export_rva - vaddr);
+# break;
+# }
+# }
+#
+# expdata = (unsigned char*)malloc(export_size);
+# lseek (dll, expptr, SEEK_SET);
+# read (dll, expdata, export_size);
+# erva = expdata - export_rva;
+#
+# nexp = pe_as32 (expdata+24);
+# name_rvas = pe_as32 (expdata+32);
+#
+# printf ("EXPORTS\n");
+# for (i = 0; i<nexp; i++)
+# {
+# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+# }
+#
+# return 0;
+# }
+# /* impgen.c ends here */
+
+EOF
+ ;;
+ esac
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if tqfinds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1)
+
+ mv -f "${ofile}T" "$ofile" || \
+ (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
+ chmod +x "$ofile"
+fi
+
+])# _LT_AC_LTCONFIG_HACK
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_SHARED],
+[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN([AC_DISABLE_SHARED],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_STATIC],
+[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN([AC_DISABLE_STATIC],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN([AC_ENABLE_FAST_INSTALL],
+[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN([AC_DISABLE_FAST_INSTALL],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_LIBTOOL_PICMODE - implement the --with-pic flag
+# Usage: AC_LIBTOOL_PICMODE[(MODE)]
+# Where MODE is either `yes' or `no'. If omitted, it defaults to
+# `both'.
+AC_DEFUN([AC_LIBTOOL_PICMODE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+pic_mode=ifelse($#,1,$1,default)])
+
+
+# AC_PATH_TOOL_PREFIX - tqfind a file program which can recognise shared library
+AC_DEFUN([AC_PATH_TOOL_PREFIX],
+[AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word. This closes a longstanding sh security hole.
+ ac_dummy="ifelse([$2], , $PATH, [$2])"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$1; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ AC_MSG_RESULT($MAGIC_CMD)
+else
+ AC_MSG_RESULT(no)
+fi
+])
+
+
+# AC_PATH_MAGIC - tqfind a file program which can recognise a shared library
+AC_DEFUN([AC_PATH_MAGIC],
+[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl
+AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH)
+ else
+ MAGIC_CMD=:
+ fi
+fi
+])
+
+
+# AC_PROG_LD - tqfind the path to the GNU or non-GNU linker
+AC_DEFUN([AC_PROG_LD],
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [[\\/]]* | [[A-Za-z]]:[[\\/]]*)
+ re_direlt='/[[^/]][[^/]]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+# AC_PROG_LD_GNU -
+AC_DEFUN([AC_PROG_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ lt_cv_prog_gnu_ld=yes
+else
+ lt_cv_prog_gnu_ld=no
+fi])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])
+
+# AC_PROG_LD_RELOAD_FLAG - tqfind reload flag for linker
+# -- PORTME Some linkers may need a different reload flag.
+AC_DEFUN([AC_PROG_LD_RELOAD_FLAG],
+[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag,
+[lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+])
+
+# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies
+# -- PORTME fill in with the dynamic library characteristics
+AC_DEFUN([AC_DEPLIBS_CHECK_METHOD],
+[AC_CACHE_CHECK([how to recognise dependant libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin* | mingw* | pw32*)
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.[[012]])
+ lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1`
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ ;;
+
+freebsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20*|hpux11*)
+ lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+
+irix5* | irix6*)
+ case $host_os in
+ irix5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1"
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ case $host_cpu in
+ alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | s390* )
+ lt_cv_deplibs_check_method=pass_all ;;
+ *)
+ # glibc up to 2.1.1 does not perform some relocations on ARM
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+openbsd*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object'
+ else
+ lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+sysv5uw[[78]]* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ esac
+ ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+])
+
+
+# AC_PROG_NM - tqfind the path to a BSD-compatible name lister
+AC_DEFUN([AC_PROG_NM],
+[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl
+AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(lt_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/${ac_tool_prefix}nm
+ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ else
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to tqfind one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi])
+NM="$lt_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN([AC_CHECK_LIBM],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, main, LIBM="-lm")
+ ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments. Note that LIBLTDL and INCLTDL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
+# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
+# with '${top_builddir}/' and INCLTDL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!). If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN([AC_LIBLTDL_CONVENIENCE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case $enable_ltdl_convenience in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+ INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
+# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!). If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN([AC_LIBLTDL_INSTALLABLE],
+[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, main,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+ INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ INCLTDL=
+ fi
+])
+
+# old names
+AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL])
+AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+AC_DEFUN([AM_PROG_LD], [AC_PROG_LD])
+AC_DEFUN([AM_PROG_NM], [AC_PROG_NM])
+
+# This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/autogen.sh b/tqtinterface/qt4/src/3rdparty/libmng/autogen.sh
new file mode 100755
index 0000000..0ed4a8b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/autogen.sh
@@ -0,0 +1,34 @@
+# autogen.sh
+#
+# invoke the auto* tools to create the configureation system
+
+# move out configure.in
+if ! test -f configure.in; then
+ echo "copying out configure.in"
+ ln -s makefiles/configure.in
+fi
+
+# move out the macros and run aclocal
+if ! test -f acinclude.m4; then
+ echo "copying configure macros"
+ ln -s makefiles/acinclude.m4 .
+fi
+aclocal
+
+# build the configure script
+autoconf
+
+# set up libtool
+libtoolize --force
+
+# copy up our Makefile template and invoke automake
+if ! test -f Makefile.am; then
+ echo "copying automake template"
+ ln -s makefiles/Makefile.am .
+fi
+automake --foreign --add-missing
+
+# and finally invoke our new configure
+./configure $*
+
+# end
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/config.guess b/tqtinterface/qt4/src/3rdparty/libmng/config.guess
new file mode 100755
index 0000000..8147635
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/config.guess
@@ -0,0 +1,1317 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+
+timestamp='2001-09-04'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that tqcontains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# Please send patches to <config-patches@gnu.org>.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+
+dummy=dummy-$$
+trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script.
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+set_cc_for_build='case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int dummy(){}" > $dummy.c ;
+ for c in cc gcc c89 ; do
+ ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 ;
+ if test $? = 0 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ rm -f $dummy.c $dummy.o $dummy.rel ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac'
+
+# This is needed to tqfind uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # Netbsd (nbsd) targets should (where applicable) match one or
+ # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ # Determine the machine/vendor (is the vendor relevant).
+ case "${UNAME_MACHINE}" in
+ amiga) machine=m68k-unknown ;;
+ arm32) machine=arm-unknown ;;
+ atari*) machine=m68k-atari ;;
+ sun3*) machine=m68k-sun ;;
+ mac68k) machine=m68k-apple ;;
+ macppc) machine=powerpc-apple ;;
+ hp3[0-9][05]) machine=m68k-hp ;;
+ ibmrt|romp-ibm) machine=romp-ibm ;;
+ *) machine=${UNAME_MACHINE}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE}" in
+ i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep __ELF__ >/dev/null
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # The OS release
+ release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # tqcontains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}"
+ exit 0 ;;
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >$dummy.s
+ .data
+\$Lformat:
+ .byte 37,100,45,37,120,10,0 # "%d-%x\n"
+
+ .text
+ .globl main
+ .align 4
+ .ent main
+main:
+ .frame \$30,16,\$26,0
+ ldgp \$29,0(\$27)
+ .prologue 1
+ .long 0x47e03d80 # implver \$0
+ lda \$2,-1
+ .long 0x47e20c21 # atqmask \$2,\$1
+ lda \$16,\$Lformat
+ mov \$0,\$17
+ not \$1,\$18
+ jsr \$26,printf
+ ldgp \$29,0(\$26)
+ mov 0,\$16
+ jsr \$26,exit
+ .end main
+EOF
+ eval $set_cc_for_build
+ $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ case `./$dummy` in
+ 0-0)
+ UNAME_MACHINE="alpha"
+ ;;
+ 1-0)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 1-1)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 1-101)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 2-303)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ 2-307)
+ UNAME_MACHINE="alphaev67"
+ ;;
+ 2-1307)
+ UNAME_MACHINE="alphaev68"
+ ;;
+ esac
+ fi
+ rm -f $dummy.s $dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ exit 0 ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit 0;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:NetBSD:*)
+ echo `uname -p`-unknown-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit 0 ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit 0 ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit 0 ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy \
+ && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:[45])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ case "${HPUX_REV}" in
+ 11.[0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ esac ;;
+ esac
+ fi ;;
+ esac
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
+ if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi
+ rm -f $dummy.c $dummy
+ fi ;;
+ esac
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ hppa*:OpenBSD:*:*)
+ echo hppa-unknown-openbsd
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3D:*:*:*)
+ echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit 0 ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit 0 ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i386-pc-interix
+ exit 0 ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit 0 ;;
+ arm*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux
+ exit 0 ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ mips:Linux:*:*)
+ case `sed -n '/^byte/s/^.*: \(.*\) endian/\1/p' < /proc/cpuinfo` in
+ big) echo mips-unknown-linux-gnu && exit 0 ;;
+ little) echo mipsel-unknown-linux-gnu && exit 0 ;;
+ esac
+ ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-gnu
+ exit 0 ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-gnu
+ exit 0 ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+ if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ exit 0 ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-gnu ;;
+ PA8*) echo hppa2.0-unknown-linux-gnu ;;
+ *) echo hppa-unknown-linux-gnu ;;
+ esac
+ exit 0 ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-gnu
+ exit 0 ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux
+ exit 0 ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ exit 0 ;;
+ x86_64:Linux:*:*)
+ echo x86_64-unknown-linux-gnu
+ exit 0 ;;
+ i*86:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us. cd to the root directory to prevent
+ # problems with other programs or directories called `ld' in the path.
+ ld_supported_targets=`cd /; ld --help 2>&1 \
+ | sed -ne '/supported targets:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported targets: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_targets" in
+ elf32-i386)
+ TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+ ;;
+ a.out-i386-linux)
+ echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+ exit 0 ;;
+ coff-i386)
+ echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+ exit 0 ;;
+ "")
+ # Either a pre-BFD a.out linker (linux-gnuoldld) or
+ # one that does not give us useful --help.
+ echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+ exit 0 ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ eval $set_cc_for_build
+ cat >$dummy.c <<EOF
+#include <features.h>
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-pc-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-pc-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-pc-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm -f $dummy.c $dummy && exit 0
+ rm -f $dummy.c $dummy
+ test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+ ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit 0 ;;
+ i*86:*:5:[78]*)
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit 0 ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit 0 ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit 0 ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit 0 ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit 0 ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit 0 ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit 0 ;;
+ *:Darwin:*:*)
+ echo `uname -p`-apple-darwin${UNAME_RELEASE}
+ exit 0 ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ if test "${UNAME_MACHINE}" = "x86pc"; then
+ UNAME_MACHINE=pc
+ fi
+ echo `uname -p`-${UNAME_MACHINE}-nto-qnx
+ exit 0 ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit 0 ;;
+ NSR-[KW]:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit 0 ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit 0 ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit 0 ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit 0 ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit 0 ;;
+ i*86:OS/2:*:*)
+ # If we were able to tqfind `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit 0 ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit 0 ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit 0 ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit 0 ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit 0 ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit 0 ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit 0 ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit 0 ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ if (version < 4)
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ else
+ printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+# include <sys/param.h>
+# if defined (BSD)
+# if BSD == 43
+ printf ("vax-dec-bsd4.3\n"); exit (0);
+# else
+# if BSD == 199006
+ printf ("vax-dec-bsd4.3reno\n"); exit (0);
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# endif
+# else
+ printf ("vax-dec-bsd\n"); exit (0);
+# endif
+# else
+ printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm -f $dummy.c $dummy && exit 0
+rm -f $dummy.c $dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/config.sub b/tqtinterface/qt4/src/3rdparty/libmng/config.sub
new file mode 100755
index 0000000..8140cbd
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/config.sub
@@ -0,0 +1,1411 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+
+timestamp='2001-09-07'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that tqcontains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit 0 ;;
+ --version | -v )
+ echo "$version" ; exit 0 ;;
+ --help | --h* | -h )
+ echo "$usage"; exit 0 ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit 0;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis)
+ os=
+ basic_machine=$1
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+ | c4x | clipper \
+ | d10v | d30v | dsp16xx \
+ | fr30 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | i370 | i860 | i960 | ia64 \
+ | m32r | m68000 | m68k | m88k | mcore \
+ | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
+ | mips64vr4100 | mips64vr4100el | mips64vr4300 \
+ | mips64vr4300el | mips64vr5000 | mips64vr5000el \
+ | mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
+ | mipsisa32 \
+ | mn10200 | mn10300 \
+ | ns16k | ns32k \
+ | openrisc \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+ | pyramid \
+ | s390 | s390x \
+ | sh | sh[34] | sh[34]eb | shbe | shle \
+ | sparc | sparc64 | sparclet | sparclite | sparcv9 | sparcv9b \
+ | stormy16 | strongarm \
+ | tahoe | thumb | tic80 | tron \
+ | v850 \
+ | we32k \
+ | x86 | xscale \
+ | z8k)
+ basic_machine=$basic_machine-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12)
+ # Motorola 68HC11/12.
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alphapca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armv*-* \
+ | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c54x-* \
+ | clipper-* | cray2-* | cydra-* \
+ | d10v-* | d30v-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fr30-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | m32r-* \
+ | m68000-* | m680[01234]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | mcore-* \
+ | mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
+ | mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
+ | mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+ | pyramid-* \
+ | romp-* | rs6000-* \
+ | s390-* | s390x-* \
+ | sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* \
+ | sparc-* | sparc64-* | sparc86x-* | sparclite-* \
+ | sparcv9-* | sparcv9b-* | stormy16-* | strongarm-* | sv1-* \
+ | t3e-* | tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
+ | v850-* | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xmp-* | xps100-* | xscale-* \
+ | ymp-* \
+ | z8k-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [cjt]90)
+ basic_machine=${basic_machine}-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ mmix*)
+ basic_machine=mmix-knuth
+ os=-mmixware
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5 | k5 | k6 | nexgen)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2)
+ basic_machine=i686-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sparclite-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=t3e-cray
+ os=-unicos
+ ;;
+ tic54x | c54x*)
+ basic_machine=tic54x-unknown
+ os=-coff
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ windows32)
+ basic_machine=i386-pc
+ os=-windows32-msvcrt
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh3 | sh4 | sh3eb | sh4eb)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv9 | sparcv9b)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ c4x*)
+ basic_machine=c4x-none
+ os=-coff
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* \
+ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto*)
+ os=-nto-qnx
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/configure b/tqtinterface/qt4/src/3rdparty/libmng/configure
new file mode 100755
index 0000000..650701a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/configure
@@ -0,0 +1,6901 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+
+# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) lt_cv_sys_path_separator=';' ;;
+ *) lt_cv_sys_path_separator=':' ;;
+ esac
+ PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$ECHO in
+X*--fallback-echo)
+ # Remove one level of quotation (which was required for Make).
+ ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','`
+ ;;
+esac
+
+echo=${ECHO-echo}
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+
+EOF
+ exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+if test -z "$ECHO"; then
+if test "X${echo_test_string+set}" != Xset; then
+# tqfind a string as large as possible, as long as the shell can cope with it
+ for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+ # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+ if (echo_test_string="`eval $cmd`") 2>/dev/null &&
+ echo_test_string="`eval $cmd`" &&
+ (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null
+ then
+ break
+ fi
+ done
+fi
+
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ :
+else
+ # The Solaris, AIX, and Digital Unix default echo programs unquote
+ # backslashes. This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ #
+ # So, first we look for a working echo in the user's PATH.
+
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for dir in $PATH /usr/ucb; do
+ if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+ test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test "X$echo" = Xecho; then
+ # We didn't tqfind a better echo, so look for alternatives.
+ if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # This shell has a builtin print -r that does the trick.
+ echo='print -r'
+ elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) &&
+ test "X$CONFIG_SHELL" != X/bin/ksh; then
+ # If we have ksh, try running configure again with it.
+ ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+ export ORIGINAL_CONFIG_SHELL
+ CONFIG_SHELL=/bin/ksh
+ export CONFIG_SHELL
+ exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+ else
+ # Try using printf.
+ echo='printf %s\n'
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t' &&
+ echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ # Cool, printf works
+ :
+ elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+ export CONFIG_SHELL
+ SHELL="$CONFIG_SHELL"
+ export SHELL
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+ test "X$echo_testing_string" = 'X\t' &&
+ echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+ test "X$echo_testing_string" = "X$echo_test_string"; then
+ echo="$CONFIG_SHELL $0 --fallback-echo"
+ else
+ # maybe with a smaller string...
+ prev=:
+
+ for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+ if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null
+ then
+ break
+ fi
+ prev="$cmd"
+ done
+
+ if test "$prev" != 'sed 50q "$0"'; then
+ echo_test_string=`eval $prev`
+ export echo_test_string
+ exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+ else
+ # Oops. We lost completely, so just stick with echo.
+ echo=echo
+ fi
+ fi
+ fi
+ fi
+fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+ECHO=$echo
+if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+ ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+ac_help="$ac_help
+ --disable-libtool-lock avoid locking (might break parallel builds)"
+ac_help="$ac_help
+ --with-pic try to use only PIC/non-PIC objects [default=use both]"
+ac_help="$ac_help
+ --disable-largefile omit support for large files"
+ac_help="$ac_help
+ --disable-read remove read support from library"
+ac_help="$ac_help
+ --disable-write remove write support from library"
+ac_help="$ac_help
+ --disable-display remove display support from library"
+ac_help="$ac_help
+ --disable-chunks remove support for chunk access"
+ac_help="$ac_help
+ --disable-storechunks remove support for access of previous chunks"
+ac_help="$ac_help
+ --enable-trace include support for debug tracing callbacks"
+ac_help="$ac_help
+ --with-zlib[=DIR] use zlib include/library files in DIR"
+ac_help="$ac_help
+ --with-jpeg[=DIR] use jpeg include/library files in DIR"
+ac_help="$ac_help
+ --with-lcms[=DIR] use lcms include/library files in DIR"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR tqfind the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file tqcontains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it tqcontains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to tqfind out if srcdir is correct.
+ac_unique_file=libmng.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its tqparent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not tqfind sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not tqfind sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not tqfind install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:748: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:801: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:858: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=libmng
+
+VERSION=1.0.4
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:904: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:917: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:930: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:943: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:956: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:976: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1006: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1057: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:1089: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 1100 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:1105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:1131: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:1136: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1145: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1164: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+
+ echo $ac_n "checking for strerror in -lcposix""... $ac_c" 1>&6
+echo "configure:1197: checking for strerror in -lcposix" >&5
+ac_lib_var=`echo cposix'_'strerror | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcposix $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1205 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char strerror();
+
+int main() {
+strerror()
+; return 0; }
+EOF
+if { (eval echo configure:1216: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lcposix"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+
+
+echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&6
+echo "configure:1242: checking for ${CC-cc} option to accept ANSI C" >&5
+if eval "test \"`echo '$''{'am_cv_prog_cc_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ am_cv_prog_cc_stdc=no
+ac_save_CC="$CC"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX -Aa -D_HPUX_SOURCE
+# SVR4 -Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ cat > conftest.$ac_ext <<EOF
+#line 1258 "configure"
+#include "confdefs.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+
+int main() {
+
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+
+; return 0; }
+EOF
+if { (eval echo configure:1295: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ am_cv_prog_cc_stdc="$ac_arg"; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+CC="$ac_save_CC"
+
+fi
+
+if test -z "$am_cv_prog_cc_stdc"; then
+ echo "$ac_t""none needed" 1>&6
+else
+ echo "$ac_t""$am_cv_prog_cc_stdc" 1>&6
+fi
+case "x$am_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $am_cv_prog_cc_stdc" ;;
+esac
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1319: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1334 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1340: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1351 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1357: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1368 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1374: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+
+
+echo $ac_n "checking for function prototypes""... $ac_c" 1>&6
+echo "configure:1401: checking for function prototypes" >&5
+if test "$am_cv_prog_cc_stdc" != no; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define PROTOTYPES 1
+EOF
+
+ U= ANSI2KNR=
+else
+ echo "$ac_t""no" 1>&6
+ U=_ ANSI2KNR=./ansi2knr
+ # Ensure some checks needed by ansi2knr itself.
+ echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1414: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1419 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1427: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1444 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1462 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1483 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1494: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+ for ac_hdr in string.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1521: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1526 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1531: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+fi
+
+if test "x$U" != "x"; then
+ { echo "configure: error: Compiler not ANSI compliant" 1>&2; exit 1; }
+fi
+# Find the correct PATH separator. Usually this is `:', but
+# DJGPP uses `;' like DOS.
+if test "X${PATH_SEPARATOR+set}" != Xset; then
+ UNAME=${UNAME-`uname 2>/dev/null`}
+ case X$UNAME in
+ *-DOS) lt_cv_sys_path_separator=';' ;;
+ *) lt_cv_sys_path_separator=':' ;;
+ esac
+ PATH_SEPARATOR=$lt_cv_sys_path_separator
+fi
+
+echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6
+echo "configure:1574: checking for Cygwin environment" >&5
+if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1579 "configure"
+#include "confdefs.h"
+
+int main() {
+
+#ifndef __CYGWIN__
+#define __CYGWIN__ __CYGWIN32__
+#endif
+return __CYGWIN__;
+; return 0; }
+EOF
+if { (eval echo configure:1590: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_cygwin=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_cygwin=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_cygwin" 1>&6
+CYGWIN=
+test "$ac_cv_cygwin" = yes && CYGWIN=yes
+echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6
+echo "configure:1607: checking for mingw32 environment" >&5
+if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1612 "configure"
+#include "confdefs.h"
+
+int main() {
+return __MINGW32__;
+; return 0; }
+EOF
+if { (eval echo configure:1619: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_mingw32=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_mingw32=no
+fi
+rm -f conftest*
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_mingw32" 1>&6
+MINGW32=
+test "$ac_cv_mingw32" = yes && MINGW32=yes
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case $enableval in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1711: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:1732: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1761: checking for ld used by GCC" >&5
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1791: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1794: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1829: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ lt_cv_prog_gnu_ld=yes
+else
+ lt_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6
+echo "configure:1846: checking for $LD option to reload object files" >&5
+if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+
+echo "$ac_t""$lt_cv_ld_reload_flag" 1>&6
+reload_flag=$lt_cv_ld_reload_flag
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1858: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm=$ac_dir/${ac_tool_prefix}nm
+ if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ else
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to tqfind one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm
+fi
+fi
+
+NM="$lt_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1896: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking how to recognise dependant libraries""... $ac_c" 1>&6
+echo "configure:1917: checking how to recognise dependant libraries" >&5
+if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given egrep regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix4* | aix5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi4*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin* | mingw* | pw32*)
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ case "$host_os" in
+ rhapsody* | darwin1.[012])
+ lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1`
+ ;;
+ *) # Darwin 1.3 on
+ lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib'
+ ;;
+ esac
+ ;;
+
+freebsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20*|hpux11*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+
+irix5* | irix6*)
+ case $host_os in
+ irix5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1"
+ ;;
+ *)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1"
+ ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*`
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ case $host_cpu in
+ alpha* | hppa* | i*86 | powerpc* | sparc* | ia64* | s390* )
+ lt_cv_deplibs_check_method=pass_all ;;
+ *)
+ # glibc up to 2.1.1 does not perform some relocations on ARM
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;;
+ esac
+ lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so`
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+openbsd*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object'
+ else
+ lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ # this will be overridden with pass_all, but let us keep it just in case
+ lt_cv_deplibs_check_method='file_magic COFF format alpha shared library'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sco3.2v5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+
+sysv5uw[78]* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ esac
+ ;;
+esac
+
+fi
+
+echo "$ac_t""$lt_cv_deplibs_check_method" 1>&6
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+
+echo $ac_n "checking for object suffix""... $ac_c" 1>&6
+echo "configure:2100: checking for object suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftest*
+echo 'int i = 1;' > conftest.$ac_ext
+if { (eval echo configure:2106: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ for ac_file in conftest.*; do
+ case $ac_file in
+ *.c) ;;
+ *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;;
+ esac
+ done
+else
+ { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; }
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_objext" 1>&6
+OBJEXT=$ac_cv_objext
+ac_objext=$ac_cv_objext
+
+
+
+echo $ac_n "checking for executable suffix""... $ac_c" 1>&6
+echo "configure:2126: checking for executable suffix" >&5
+if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$CYGWIN" = yes || test "$MINGW32" = yes; then
+ ac_cv_exeext=.exe
+else
+ rm -f conftest*
+ echo 'int main () { return 0; }' > conftest.$ac_ext
+ ac_cv_exeext=
+ if { (eval echo configure:2136: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then
+ for file in conftest.*; do
+ case $file in
+ *.c | *.o | *.obj) ;;
+ *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;;
+ esac
+ done
+ else
+ { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; }
+ fi
+ rm -f conftest*
+ test x"${ac_cv_exeext}" = x && ac_cv_exeext=no
+fi
+fi
+
+EXEEXT=""
+test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext}
+echo "$ac_t""${ac_cv_exeext}" 1>&6
+ac_exeext=$EXEEXT
+
+if test $host != $build; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output""... $ac_c" 1>&6
+echo "configure:2167: checking command to parse $NM output" >&5
+if eval "test \"`echo '$''{'lt_cv_sys_global_symbol_pipe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*) # Its linker distinguishes data from code symbols
+ lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+ lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'"
+ ;;
+irix*)
+ symcode='[BCDEGRST]'
+ ;;
+solaris* | sysv5*)
+ symcode='[BDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $host_os in
+mingw*)
+ opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Write the raw and C identifiers.
+lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+ rm -f conftest*
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+ if { (eval echo configure:2247: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { (eval echo configure:2250: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext'
+
+ cat <<EOF >> conftest.$ac_ext
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext
+ cat <<\EOF >> conftest.$ac_ext
+ {0, (lt_ptr) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo configure:2301: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ pipe_works=yes
+ fi
+ LIBS="$save_LIBS"
+ CFLAGS="$save_CFLAGS"
+ else
+ echo "cannot tqfind nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot tqfind nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -f conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+global_symbol_pipe="$lt_cv_sys_global_symbol_pipe"
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ global_symbol_to_cdecl=
+ global_symbol_to_c_name_address=
+else
+ global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl"
+ global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address"
+fi
+if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address";
+then
+ echo "$ac_t""failed" 1>&6
+else
+ echo "$ac_t""ok" 1>&6
+fi
+
+for ac_hdr in dlfcn.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2350: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2355 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2360: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+
+
+# Only perform the check for file, if the check method requires it
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6
+echo "configure:2395: checking for ${ac_tool_prefix}file" >&5
+if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$ac_t""$MAGIC_CMD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ echo $ac_n "checking for file""... $ac_c" 1>&6
+echo "configure:2457: checking for file" >&5
+if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ case $MAGIC_CMD in
+ /*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+ ?:/*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path.
+ ;;
+ *)
+ ac_save_MAGIC_CMD="$MAGIC_CMD"
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="/usr/bin:$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`"
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ egrep "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ MAGIC_CMD="$ac_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ echo "$ac_t""$MAGIC_CMD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2528: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_RANLIB"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2560: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ RANLIB=":"
+fi
+fi
+
+# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2595: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+ echo "$ac_t""$STRIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+if test -z "$ac_cv_prog_STRIP"; then
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2627: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_STRIP="strip"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":"
+fi
+fi
+STRIP="$ac_cv_prog_STRIP"
+if test -n "$STRIP"; then
+ echo "$ac_t""$STRIP" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+ STRIP=":"
+fi
+fi
+
+
+enable_dlopen=no
+enable_win32_dll=no
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ :
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 2676 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:2677: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:2698: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ cat > conftest.$ac_ext <<EOF
+#line 2711 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:2718: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+ ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Constants:
+rm="rm -f"
+
+# Global variables:
+default_ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except M$VC,
+# which needs '.lib').
+libext=a
+ltmain="$ac_aux_dir/ltmain.sh"
+ofile="$default_ofile"
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+need_locks="$enable_libtool_lock"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$AS" && AS=as
+test -z "$CC" && CC=cc
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+test -z "$LD" && LD=ld
+test -z "$LN_S" && LN_S="ln -s"
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+test -z "$NM" && NM=nm
+test -z "$OBJDUMP" && OBJDUMP=objdump
+test -z "$RANLIB" && RANLIB=:
+test -z "$STRIP" && STRIP=:
+test -z "$ac_objext" && ac_objext=o
+
+if test x"$host" != x"$build"; then
+ ac_tool_prefix=${host_alias}-
+else
+ ac_tool_prefix=
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case $host_os in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds"
+ ;;
+ *)
+ old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for objdir""... $ac_c" 1>&6
+echo "configure:2838: checking for objdir" >&5
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t""$objdir" 1>&6
+
+
+# Check whether --with-pic or --without-pic was given.
+if test "${with_pic+set}" = set; then
+ withval="$with_pic"
+ pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+test -z "$pic_mode" && pic_mode=default
+
+# We assume here that the value for lt_cv_prog_cc_pic will not be cached
+# in isolation, and that seeing it set (from the cache) indicates that
+# the associated values are set (in the cache) correctly too.
+echo $ac_n "checking for $compiler option to produce PIC""... $ac_c" 1>&6
+echo "configure:2865: checking for $compiler option to produce PIC" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_cc_pic'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_prog_cc_pic=
+ lt_cv_prog_cc_shlib=
+ lt_cv_prog_cc_wl=
+ lt_cv_prog_cc_static=
+ lt_cv_prog_cc_no_builtin=
+ lt_cv_prog_cc_can_build_shared=$can_build_shared
+
+ if test "$GCC" = yes; then
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-static'
+
+ case $host_os in
+ aix*)
+ # Below there is a dirty hack to force normal static linking with -ldl
+ # The problem is because libdl dynamically linked with both libc and
+ # libC (AIX C++ library), which obviously doesn't included in libraries
+ # list by gcc. This cause undefined symbols with -static flags.
+ # This hack allows C programs to be linked with "-static -ldl", but
+ # not sure about C++ programs.
+ lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC"
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ beos* | irix5* | irix6* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_cv_prog_cc_pic='-fno-common'
+ ;;
+ cygwin* | mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_cv_prog_cc_pic='-DDLL_EXPORT'
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_cv_prog_cc_pic=-Kconform_pic
+ fi
+ ;;
+ *)
+ lt_cv_prog_cc_pic='-fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for PIC flags for the system compiler.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ lt_cv_prog_cc_wl='-Wl,'
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_cv_prog_cc_static='-Bstatic'
+ else
+ lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ # Is there a better lt_cv_prog_cc_static that works with the bundled CC?
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive"
+ lt_cv_prog_cc_pic='+Z'
+ ;;
+
+ irix5* | irix6*)
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ cygwin* | mingw* | pw32* | os2*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_cv_prog_cc_pic='-DDLL_EXPORT'
+ ;;
+
+ newsos6)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ # All OSF/1 code is PIC.
+ lt_cv_prog_cc_wl='-Wl,'
+ lt_cv_prog_cc_static='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ lt_cv_prog_cc_pic='-Kpic'
+ lt_cv_prog_cc_static='-dn'
+ lt_cv_prog_cc_shlib='-belf'
+ ;;
+
+ solaris*)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ lt_cv_prog_cc_wl='-Wl,'
+ ;;
+
+ sunos4*)
+ lt_cv_prog_cc_pic='-PIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ lt_cv_prog_cc_wl='-Qoption ld '
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ lt_cv_prog_cc_pic='-KPIC'
+ lt_cv_prog_cc_static='-Bstatic'
+ if test "x$host_vendor" = xsni; then
+ lt_cv_prog_cc_wl='-LD'
+ else
+ lt_cv_prog_cc_wl='-Wl,'
+ fi
+ ;;
+
+ uts4*)
+ lt_cv_prog_cc_pic='-pic'
+ lt_cv_prog_cc_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_cv_prog_cc_pic='-Kconform_pic'
+ lt_cv_prog_cc_static='-Bstatic'
+ fi
+ ;;
+
+ *)
+ lt_cv_prog_cc_can_build_shared=no
+ ;;
+ esac
+ fi
+
+fi
+
+if test -z "$lt_cv_prog_cc_pic"; then
+ echo "$ac_t""none" 1>&6
+else
+ echo "$ac_t""$lt_cv_prog_cc_pic" 1>&6
+
+ # Check to make sure the pic_flag actually works.
+ echo $ac_n "checking if $compiler PIC flag $lt_cv_prog_cc_pic works""... $ac_c" 1>&6
+echo "configure:3017: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5
+ if eval "test \"`echo '$''{'lt_cv_prog_cc_pic_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC"
+ cat > conftest.$ac_ext <<EOF
+#line 3024 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3031: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ case $host_os in
+ hpux9* | hpux10* | hpux11*)
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then
+ # they create non-PIC objects. So, if there were any warnings, we
+ # assume that PIC is not supported.
+ if test -s conftest.err; then
+ lt_cv_prog_cc_pic_works=no
+ else
+ lt_cv_prog_cc_pic_works=yes
+ fi
+ ;;
+ *)
+ lt_cv_prog_cc_pic_works=yes
+ ;;
+ esac
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_prog_cc_pic_works=no
+
+fi
+rm -f conftest*
+ CFLAGS="$save_CFLAGS"
+
+fi
+
+
+ if test "X$lt_cv_prog_cc_pic_works" = Xno; then
+ lt_cv_prog_cc_pic=
+ lt_cv_prog_cc_can_build_shared=no
+ else
+ lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic"
+ fi
+
+ echo "$ac_t""$lt_cv_prog_cc_pic_works" 1>&6
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$lt_cv_prog_cc_shlib"; then
+ echo "configure: warning: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" 1>&2
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]" >/dev/null; then :
+ else
+ echo "configure: warning: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" 1>&2
+ lt_cv_prog_cc_can_build_shared=no
+ fi
+fi
+
+echo $ac_n "checking if $compiler static flag $lt_cv_prog_cc_static works""... $ac_c" 1>&6
+echo "configure:3083: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5
+if eval "test \"`echo '$''{'lt_cv_prog_cc_static_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ lt_cv_prog_cc_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static"
+ cat > conftest.$ac_ext <<EOF
+#line 3091 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:3098: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_prog_cc_static_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+
+
+# Belt *and* braces to stop my trousers falling down:
+test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static=
+echo "$ac_t""$lt_cv_prog_cc_static_works" 1>&6
+
+pic_flag="$lt_cv_prog_cc_pic"
+special_shlib_compile_flags="$lt_cv_prog_cc_shlib"
+wl="$lt_cv_prog_cc_wl"
+link_static_flag="$lt_cv_prog_cc_static"
+no_builtin_flag="$lt_cv_prog_cc_no_builtin"
+can_build_shared="$lt_cv_prog_cc_can_build_shared"
+
+
+# Check to see if options -o and -c are simultaneously supported by compiler
+echo $ac_n "checking if $compiler supports -c -o file.$ac_objext""... $ac_c" 1>&6
+echo "configure:3125: checking if $compiler supports -c -o file.$ac_objext" >&5
+if eval "test \"`echo '$''{'lt_cv_compiler_c_o'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+$rm -r conftest 2>/dev/null
+mkdir conftest
+cd conftest
+echo "int some_variable = 0;" > conftest.$ac_ext
+mkdir out
+# According to Tom Tromey, Ian Lance Taylor reported there are C compilers
+# that will create temporary files in the current directory regardless of
+# the output directory. Thus, making CWD read-only will cause this test
+# to fail, enabling locking or at least warning the user not to do parallel
+# builds.
+chmod -w .
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -o out/conftest2.$ac_objext"
+compiler_c_o=no
+if { (eval echo configure:3144: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s out/conftest.err; then
+ lt_cv_compiler_c_o=no
+ else
+ lt_cv_compiler_c_o=yes
+ fi
+else
+ # Append any errors to the config.log.
+ cat out/conftest.err 1>&5
+ lt_cv_compiler_c_o=no
+fi
+CFLAGS="$save_CFLAGS"
+chmod u+w .
+$rm conftest* out/*
+rmdir out
+cd ..
+rmdir conftest
+$rm -r conftest 2>/dev/null
+
+fi
+
+compiler_c_o=$lt_cv_compiler_c_o
+echo "$ac_t""$compiler_c_o" 1>&6
+
+if test x"$compiler_c_o" = x"yes"; then
+ # Check to see if we can write to a .lo
+ echo $ac_n "checking if $compiler supports -c -o file.lo""... $ac_c" 1>&6
+echo "configure:3173: checking if $compiler supports -c -o file.lo" >&5
+ if eval "test \"`echo '$''{'lt_cv_compiler_o_lo'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ lt_cv_compiler_o_lo=no
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -c -o conftest.lo"
+ save_objext="$ac_objext"
+ ac_objext=lo
+ cat > conftest.$ac_ext <<EOF
+#line 3184 "configure"
+#include "confdefs.h"
+
+int main() {
+int some_variable = 0;
+; return 0; }
+EOF
+if { (eval echo configure:3191: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ lt_cv_compiler_o_lo=no
+ else
+ lt_cv_compiler_o_lo=yes
+ fi
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ ac_objext="$save_objext"
+ CFLAGS="$save_CFLAGS"
+
+fi
+
+ compiler_o_lo=$lt_cv_compiler_o_lo
+ echo "$ac_t""$compiler_o_lo" 1>&6
+else
+ compiler_o_lo=no
+fi
+
+# Check to see if we can do hard links to lock some files if needed
+hard_links="nottested"
+if test "$compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ echo $ac_n "checking if we can lock with hard links""... $ac_c" 1>&6
+echo "configure:3222: checking if we can lock with hard links" >&5
+ hard_links=yes
+ $rm conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ echo "$ac_t""$hard_links" 1>&6
+ if test "$hard_links" = no; then
+ echo "configure: warning: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" 1>&2
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+if test "$GCC" = yes; then
+ # Check to see if options -fno-rtti -fno-exceptions are supported by compiler
+ echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions""... $ac_c" 1>&6
+echo "configure:3241: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext"
+ compiler_rtti_exceptions=no
+ cat > conftest.$ac_ext <<EOF
+#line 3247 "configure"
+#include "confdefs.h"
+
+int main() {
+int some_variable = 0;
+; return 0; }
+EOF
+if { (eval echo configure:3254: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ compiler_rtti_exceptions=no
+ else
+ compiler_rtti_exceptions=yes
+ fi
+
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ CFLAGS="$save_CFLAGS"
+ echo "$ac_t""$compiler_rtti_exceptions" 1>&6
+
+ if test "$compiler_rtti_exceptions" = "yes"; then
+ no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions'
+ else
+ no_builtin_flag=' -fno-builtin'
+ fi
+fi
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries""... $ac_c" 1>&6
+echo "configure:3281: checking whether the linker ($LD) supports shared libraries" >&5
+
+allow_undefined_flag=
+no_undefined_flag=
+need_lib_prefix=unknown
+need_version=unknown
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+archive_cmds=
+archive_expsym_cmds=
+old_archive_from_new_cmds=
+old_archive_from_expsyms_cmds=
+export_dynamic_flag_spec=
+whole_archive_flag_spec=
+thread_safe_flag_spec=
+hardcode_into_libs=no
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+link_all_deplibs=unknown
+always_export_symbols=no
+export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols'
+# include_expsyms should be a list of space-separated symbols to be *always*
+# included in the symbol list
+include_expsyms=
+# exclude_expsyms can be an egrep regular expression of symbols to exclude
+# it will be wrapped by ` (' and `)$', so one must not match beginning or
+# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+# as well as any symbol that tqcontains `d'.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+# platforms (ab)use it in PIC code, but their linkers get confused if
+# the symbol is explicitly referenced. Since portable code cannot
+# rely on this symbol name, it's probably fine to never include it in
+# preloaded symbol tables.
+extract_expsyms_cmds=
+
+case $host_os in
+cygwin* | mingw* | pw32*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+openbsd*)
+ with_gnu_ld=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix3* | aix4* | aix5*)
+ # On AIX, the GNU linker is very broken
+ # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available.
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+EOF
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+
+ # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
+ # that the semantics of dynamic libraries on AmigaOS, at least up
+ # to version 4, is to share data among multiple programs linked
+ # with the same dynamic library. Since this doesn't match the
+ # behavior of shared libraries on other platforms, we can use
+ # them.
+ ld_shlibs=no
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+
+ extract_expsyms_cmds='test -f $output_objdir/impgen.c || \
+ sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~
+ test -f $output_objdir/impgen.exe || (cd $output_objdir && \
+ if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \
+ else $CC -o impgen impgen.c ; fi)~
+ $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def'
+
+ old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib'
+
+ # cygwin and mingw dlls have different entry points and sets of symbols
+ # to exclude.
+ # FIXME: what about values for MSVC?
+ dll_entry=__cygwin_dll_entry@12
+ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~
+ case $host_os in
+ mingw*)
+ # mingw values
+ dll_entry=_DllMainCRTStartup@12
+ dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~
+ ;;
+ esac
+
+ # mingw and cygwin differ, and it's simplest to just exclude the union
+ # of the two symbol sets.
+ dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12
+
+ # recent cygwin and mingw systems supply a stub DllMain which the user
+ # can override, but on older systems we have to supply one (in ltdll.c)
+ if test "x$lt_cv_need_dllmain" = "xyes"; then
+ ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext "
+ ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~
+ test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~'
+ else
+ ltdll_obj=
+ ltdll_cmds=
+ fi
+
+ # Extract the symbol export list from an `--export-all' def file,
+ # then regenerate the def file from the symbol export list, so that
+ # the compiled dll only exports the symbol export list.
+ # Be careful not to strip the DATA tag left be newer dlltools.
+ export_symbols_cmds="$ltdll_cmds"'
+ $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~
+ sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols'
+
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is.
+ # If DATA tags from a recent dlltool are present, honour them!
+ archive_expsym_cmds='if test "x`head -1 $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname-def;
+ else
+ echo EXPORTS > $output_objdir/$soname-def;
+ _lt_hint=1;
+ cat $export_symbols | while read symbol; do
+ set dummy \$symbol;
+ case \$# in
+ 2) echo " \$2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;;
+ *) echo " \$2 @ \$_lt_hint \$3 ; " >> $output_objdir/$soname-def;;
+ esac;
+ _lt_hint=`expr 1 + \$_lt_hint`;
+ done;
+ fi~
+ '"$ltdll_cmds"'
+ $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~
+ $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~
+ $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~
+ $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags'
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris* | sysv5*)
+ if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+EOF
+ elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = yes; then
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ case $host_os in
+ cygwin* | mingw* | pw32*)
+ # dlltool doesn't understand --whole-archive et. al.
+ whole_archive_flag_spec=
+ ;;
+ *)
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ ;;
+ esac
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4* | aix5*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix5*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ hardcode_direct=yes
+ archive_cmds=''
+ hardcode_libdir_separator=':'
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" && \
+ strings "$collect2name" | grep resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ hardcode_direct=yes
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to tqfind uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ esac
+
+ shared_flag='-shared'
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ shared_flag='${wl}-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ # It seems that -bexpall can do strange things, so it is better to
+ # generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib'
+ archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"
+ else
+ hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib'
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='${wl}-berok'
+ # This is a bit strange, but is similar to how AIX traditionally builds
+ # it's shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ # see comment about different semantics on the GNU ld section
+ ld_shlibs=no
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ ;;
+
+ darwin* | rhapsody*)
+ case "$host_os" in
+ rhapsody* | darwin1.[012])
+ allow_undefined_flag='-undefined suppress'
+ ;;
+ *) # Darwin 1.3 on
+ allow_undefined_flag='-flat_namespace -undefined suppress'
+ ;;
+ esac
+ # FIXME: Relying on posixy $() will cause problems for
+ # cross-compilation, but unfortunately the echo tests do not
+ # yet detect zsh echo's removal of \ escapes.
+ archive_cmds='$nonopt $(test "x$module" = xyes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib $libobjs $deplibs$linker_flags -install_name $rpath/$soname $verstring'
+ # We need to add '_' to the symbols in $export_symbols first
+ #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ whole_archive_flag_spec='-all_load $convenience'
+ ;;
+
+ freebsd1*)
+ ld_shlibs=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ case $host_os in
+ hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;;
+ *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;;
+ esac
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_minus_L=yes # Not in the search PATH, but as the default
+ # location of the library.
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case "$host_os" in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~
+ $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp'
+
+ #Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ hardcode_libdir_separator=:
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ ;;
+
+ solaris*)
+ # gcc --version < 3.0 without binutils cannot create self contained
+ # shared libraries reliably, requiring libgcc.a to resolve some of
+ # the object symbols generated in some cases. Libraries that use
+ # assert need libgcc.a to resolve __eprintf, for example. Linking
+ # a copy of libgcc.a into every shared library to guarantee resolving
+ # such symbols causes other problems: According to Tim Van Holder
+ # <tim.van.holder@pandora.be>, C++ libraries end up with a separate
+ # (to the application) exception stack for one thing.
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ case `$CC --version 2>/dev/null` in
+ [12].*)
+ cat <<EOF 1>&2
+
+*** Warning: Releases of GCC earlier than version 3.0 cannot reliably
+*** create self contained shared libraries on Solaris systems, without
+*** introducing a dependency on libgcc.a. Therefore, libtool is disabling
+*** -no-undefined support, which will at least allow you to build shared
+*** libraries. However, you may tqfind that when you link such libraries
+*** into an application without using GCC, you have to manually add
+*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to
+*** upgrade to a newer version of GCC. Another option is to rebuild your
+*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer.
+
+EOF
+ no_undefined_flag=
+ ;;
+ esac
+ fi
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *) # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ if test "x$host_vendor" = xsno; then
+ archive_cmds='$LD -G -Bsymbolic -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ else
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv5*)
+ no_undefined_flag=' -z text'
+ # $CC -shared without GNU ld will not create a library from C++
+ # object files and a static libstdc++, better avoid it by now
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp'
+ hardcode_libdir_flag_spec=
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4.2uw2*)
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ hardcode_runpath_var=yes
+ runpath_var=LD_RUN_PATH
+ ;;
+
+ sysv5uw7* | unixware7*)
+ no_undefined_flag='${wl}-z ${wl}text'
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+fi
+echo "$ac_t""$ld_shlibs" 1>&6
+test "$ld_shlibs" = no && can_build_shared=no
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs""... $ac_c" 1>&6
+echo "configure:3965: checking how to hardcode library paths into programs" >&5
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$hardcode_shlibpath_var" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+echo "$ac_t""$hardcode_action" 1>&6
+
+striplib=
+old_striplib=
+echo $ac_n "checking whether stripping libraries is possible""... $ac_c" 1>&6
+echo "configure:3993: checking whether stripping libraries is possible" >&5
+if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+# PORTME Fill in your ld.so characteristics
+echo $ac_n "checking dynamic linker characteristics""... $ac_c" 1>&6
+echo "configure:4007: checking dynamic linker characteristics" >&5
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so$major'
+ ;;
+
+aix4* | aix5*)
+ version_type=linux
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can
+ # not hardcode correct soname into executable. Probably we can
+ # add versioning support to collect2, so additional links can
+ # be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}.so$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+beos*)
+ library_names_spec='${libname}.so'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi4*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ export_dynamic_flag_spec=-rdynamic
+ # the default ld.so.conf also tqcontains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32*)
+ version_type=windows
+ need_version=no
+ need_lib_prefix=no
+ case $GCC,$host_os in
+ yes,cygwin*)
+ library_names_spec='$libname.dll.a'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+ postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog .libs/$dlname \$dldir/$dlname'
+ postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $rm \$dlpath'
+ ;;
+ yes,mingw*)
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll'
+ sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g"`
+ ;;
+ yes,pw32*)
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/./-/g'`${versuffix}.dll'
+ ;;
+ *)
+ library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ # FIXME: Relying on posixy $() will cause problems for
+ # cross-compilation, but unfortunately the echo tests do not
+ # yet detect zsh echo's removal of \ escapes.
+ library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)'
+ soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ ;;
+
+freebsd1*)
+ dynamic_linker=no
+ ;;
+
+freebsd*)
+ objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout`
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ *)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl'
+ soname_spec='${libname}${release}.sl$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5* | irix6*)
+ version_type=irix
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so'
+ case $host_os in
+ irix5*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so'
+ soname_spec='${libname}${release}.so$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+openbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case "$host_os" in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ need_lib_prefix=no
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_version=no
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so$major'
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so'
+ soname_spec='${libname}${release}.so$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so'
+ soname_spec='$libname.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$ac_t""$dynamic_linker" 1>&6
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo $ac_n "checking if libtool supports shared libraries""... $ac_c" 1>&6
+echo "configure:4404: checking if libtool supports shared libraries" >&5
+echo "$ac_t""$can_build_shared" 1>&6
+
+echo $ac_n "checking whether to build shared libraries""... $ac_c" 1>&6
+echo "configure:4408: checking whether to build shared libraries" >&5
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+aix4*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+esac
+echo "$ac_t""$enable_shared" 1>&6
+
+echo $ac_n "checking whether to build static libraries""... $ac_c" 1>&6
+echo "configure:4431: checking whether to build static libraries" >&5
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+echo "$ac_t""$enable_static" 1>&6
+
+if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ cygwin* | mingw* | pw32*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ *)
+ echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "configure:4472: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4477 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shl_load(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4500: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "configure:4518: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4526 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo configure:4537: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "configure:4556: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 4561 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlopen(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:4584: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:4602: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4610 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:4621: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen in -lsvld""... $ac_c" 1>&6
+echo "configure:4640: checking for dlopen in -lsvld" >&5
+ac_lib_var=`echo svld'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lsvld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4648 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:4659: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "configure:4678: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 4686 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo configure:4697: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6
+echo "configure:4753: checking whether a program can dlopen itself" >&5
+if eval "test \"`echo '$''{'lt_cv_dlopen_self'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+#line 4763 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ tqfind out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+
+ exit (status);
+}
+EOF
+ if { (eval echo configure:4824: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_unknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self" 1>&6
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ LDFLAGS="$LDFLAGS $link_static_flag"
+ echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6
+echo "configure:4847: checking whether a statically linked program can dlopen itself" >&5
+if eval "test \"`echo '$''{'lt_cv_dlopen_self_static'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<EOF
+#line 4857 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ tqfind out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" void exit (int);
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ /* dlclose (self); */
+ }
+
+ exit (status);
+}
+EOF
+ if { (eval echo configure:4918: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+
+echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ echo $ac_n "checking whether -lc should be explicitly linked in""... $ac_c" 1>&6
+echo "configure:4967: checking whether -lc should be explicitly linked in" >&5
+ if eval "test \"`echo '$''{'lt_cv_archive_cmds_need_lc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ $rm conftest*
+ echo 'static int dummy;' > conftest.$ac_ext
+
+ if { (eval echo configure:4974: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_cv_prog_cc_wl
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { (eval echo configure:4987: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\") 1>&5; (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+fi
+
+ echo "$ac_t""$lt_cv_archive_cmds_need_lc" 1>&6
+ ;;
+ esac
+fi
+need_lc=${lt_cv_archive_cmds_need_lc-yes}
+
+# The second clause should only fire when bootstrapping the
+# libtool distribution, otherwise you forgot to ship ltmain.sh
+# with your package, and you will get complaints that there are
+# no rules to generate ltmain.sh.
+if test -f "$ltmain"; then
+ :
+else
+ # If there is no Makefile yet, we rely on a make rule to execute
+ # `config.status --recheck' to rerun these tests and create the
+ # libtool script then.
+ test -f Makefile && make "$ltmain"
+fi
+
+if test -f "$ltmain"; then
+ trap "$rm \"${ofile}T\"; exit 1" 1 2 15
+ $rm -f "${ofile}T"
+
+ echo creating $ofile
+
+ # Now quote all the things that may contain metacharacters while being
+ # careful not to overquote the AC_SUBSTed values. We take copies of the
+ # variables and quote the copies for generation of the libtool script.
+ for var in echo old_CC old_CFLAGS \
+ AR AR_FLAGS CC LD LN_S NM SHELL \
+ reload_flag reload_cmds wl \
+ pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ thread_safe_flag_spec whole_archive_flag_spec libname_spec \
+ library_names_spec soname_spec \
+ RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \
+ postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \
+ old_striplib striplib file_magic_cmd export_symbols_cmds \
+ deplibs_check_method allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \
+ global_symbol_to_c_name_address \
+ hardcode_libdir_flag_spec hardcode_libdir_separator \
+ sys_lib_search_path_spec sys_lib_dlsearch_path_spec \
+ compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do
+
+ case $var in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | \
+ export_symbols_cmds | archive_cmds | archive_expsym_cmds | \
+ extract_expsyms_cmds | old_archive_from_expsyms_cmds | \
+ postinstall_cmds | postuninstall_cmds | \
+ finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec)
+ # Double-quote double-evaled strings.
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\""
+ ;;
+ *)
+ eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\""
+ ;;
+ esac
+ done
+
+ cat <<__EOF__ > "${ofile}T"
+#! $SHELL
+
+# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP)
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996-2000 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that tqcontains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$need_lc
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+
+# An echo program that does not interpret backslashes.
+echo=$lt_echo
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# The default C compiler.
+CC=$lt_CC
+
+# Is the compiler the GNU C compiler?
+with_gcc=$GCC
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Whether we need hard or soft links.
+LN_S=$lt_LN_S
+
+# A BSD-compatible nm program.
+NM=$lt_NM
+
+# A symbol stripping program
+STRIP=$STRIP
+
+# Used to examine libraries when file_magic_cmd begins "file"
+MAGIC_CMD=$MAGIC_CMD
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="$DLLTOOL"
+
+# Used on cygwin: object dumper.
+OBJDUMP="$OBJDUMP"
+
+# Used on cygwin: assembler.
+AS="$AS"
+
+# The name of the directory that tqcontains temporary libtool files.
+objdir=$objdir
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# How to pass a linker flag through the compiler.
+wl=$lt_wl
+
+# Object file suffix (normally "o").
+objext="$ac_objext"
+
+# Old archive suffix (normally "a").
+libext="$libext"
+
+# Executable file suffix (normally "").
+exeext="$exeext"
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_pic_flag
+pic_mode=$pic_mode
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_compiler_c_o
+
+# Can we write directly to a .lo ?
+compiler_o_lo=$lt_compiler_o_lo
+
+# Must we lock files when doing compilation ?
+need_locks=$lt_need_locks
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_link_static_flag
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_no_builtin_flag
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=$lt_thread_safe_flag_spec
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker tqfinds with -lNAME.
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Commands used to build and install an old-style archive.
+RANLIB=$lt_RANLIB
+old_archive_cmds=$lt_old_archive_cmds
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build and install a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+postinstall_cmds=$lt_postinstall_cmds
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=$lt_file_magic_cmd
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=$lt_finish_eval
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl=$lt_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair
+global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at relink time.
+variables_saved_for_relink="$variables_saved_for_relink"
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path="$fix_srcfile_path"
+
+# Set to yes if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# ### END LIBTOOL CONFIG
+
+__EOF__
+
+ case $host_os in
+ aix3*)
+ cat <<\EOF >> "${ofile}T"
+
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+EOF
+ ;;
+ esac
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2*)
+ cat <<'EOF' >> "${ofile}T"
+ # This is a source program that is used to create dlls on Windows
+ # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+ # This is a source program that is used to create import libraries
+ # on Windows for dlls which lack them. Don't remove nor modify the
+ # starting and closing comments
+# /* impgen.c starts here */
+# /* Copyright (C) 1999-2000 Free Software Foundation, Inc.
+#
+# This file is part of GNU libtool.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# */
+#
+# #include <stdio.h> /* for printf() */
+# #include <unistd.h> /* for open(), lseek(), read() */
+# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
+# #include <string.h> /* for strdup() */
+#
+# /* O_BINARY isn't required (or even defined sometimes) under Unix */
+# #ifndef O_BINARY
+# #define O_BINARY 0
+# #endif
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[2];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 2);
+# return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[4];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 4);
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+# void *ptr;
+# {
+# unsigned char *b = ptr;
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+# int argc;
+# char *argv[];
+# {
+# int dll;
+# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+# unsigned long export_rva, export_size, nsections, secptr, expptr;
+# unsigned long name_rvas, nexp;
+# unsigned char *expdata, *erva;
+# char *filename, *dll_name;
+#
+# filename = argv[1];
+#
+# dll = open(filename, O_RDONLY|O_BINARY);
+# if (dll < 1)
+# return 1;
+#
+# dll_name = filename;
+#
+# for (i=0; filename[i]; i++)
+# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+# dll_name = filename + i +1;
+#
+# pe_header_offset = pe_get32 (dll, 0x3c);
+# opthdr_ofs = pe_header_offset + 4 + 20;
+# num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+# if (num_entries < 1) /* no exports */
+# return 1;
+#
+# export_rva = pe_get32 (dll, opthdr_ofs + 96);
+# export_size = pe_get32 (dll, opthdr_ofs + 100);
+# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+# secptr = (pe_header_offset + 4 + 20 +
+# pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+# expptr = 0;
+# for (i = 0; i < nsections; i++)
+# {
+# char sname[8];
+# unsigned long secptr1 = secptr + 40 * i;
+# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# lseek(dll, secptr1, SEEK_SET);
+# read(dll, sname, 8);
+# if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# {
+# expptr = fptr + (export_rva - vaddr);
+# if (export_rva + export_size > vaddr + vsize)
+# export_size = vsize - (export_rva - vaddr);
+# break;
+# }
+# }
+#
+# expdata = (unsigned char*)malloc(export_size);
+# lseek (dll, expptr, SEEK_SET);
+# read (dll, expdata, export_size);
+# erva = expdata - export_rva;
+#
+# nexp = pe_as32 (expdata+24);
+# name_rvas = pe_as32 (expdata+32);
+#
+# printf ("EXPORTS\n");
+# for (i = 0; i<nexp; i++)
+# {
+# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+# }
+#
+# return 0;
+# }
+# /* impgen.c ends here */
+
+EOF
+ ;;
+ esac
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if tqfinds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '$q' "$ltmain" >> "${ofile}T" || (rm -f "${ofile}T"; exit 1)
+
+ mv -f "${ofile}T" "$ofile" || \
+ (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T")
+ chmod +x "$ofile"
+fi
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Prevent multiple expansion
+
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:5580: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+
+# Check whether --enable-largefile or --disable-largefile was given.
+if test "${enable_largefile+set}" = set; then
+ enableval="$enable_largefile"
+ :
+fi
+
+ if test "$enable_largefile" != no; then
+
+ echo $ac_n "checking for special C compiler options needed for large files""... $ac_c" 1>&6
+echo "configure:5642: checking for special C compiler options needed for large files" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_largefile_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ cat > conftest.$ac_ext <<EOF
+#line 5651 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:5660: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_save_CC="$CC"
+ CC="$CC -n32"
+ cat > conftest.$ac_ext <<EOF
+#line 5669 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:5678: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_sys_largefile_CC=' -n32'
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+ CC="$ac_save_CC"
+fi
+rm -f conftest*
+ fi
+fi
+
+echo "$ac_t""$ac_cv_sys_largefile_CC" 1>&6
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC="$CC$ac_cv_sys_largefile_CC"
+ fi
+
+ echo $ac_n "checking for _FILE_OFFSET_BITS value needed for large files""... $ac_c" 1>&6
+echo "configure:5698: checking for _FILE_OFFSET_BITS value needed for large files" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_file_offset_bits'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_file_offset_bits=no
+ cat > conftest.$ac_ext <<EOF
+#line 5704 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+
+
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:5715: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ cat > conftest.$ac_ext <<EOF
+#line 5722 "configure"
+#include "confdefs.h"
+#define _FILE_OFFSET_BITS 64
+#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+
+
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:5734: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_sys_file_offset_bits=64
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_sys_file_offset_bits" 1>&6
+ if test "$ac_cv_sys_file_offset_bits" != no; then
+ cat >> confdefs.h <<EOF
+#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits
+EOF
+
+ fi
+ echo $ac_n "checking for _LARGEFILE_SOURCE value needed for large files""... $ac_c" 1>&6
+echo "configure:5754: checking for _LARGEFILE_SOURCE value needed for large files" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_largefile_source'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_largefile_source=no
+ cat > conftest.$ac_ext <<EOF
+#line 5760 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+
+#include <stdio.h>
+
+int main() {
+return !ftello;
+; return 0; }
+EOF
+if { (eval echo configure:5771: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ cat > conftest.$ac_ext <<EOF
+#line 5778 "configure"
+#include "confdefs.h"
+#define _LARGEFILE_SOURCE 1
+#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+
+#include <stdio.h>
+
+int main() {
+return !ftello;
+; return 0; }
+EOF
+if { (eval echo configure:5790: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_sys_largefile_source=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_sys_largefile_source" 1>&6
+ if test "$ac_cv_sys_largefile_source" != no; then
+ cat >> confdefs.h <<EOF
+#define _LARGEFILE_SOURCE $ac_cv_sys_largefile_source
+EOF
+
+ fi
+ echo $ac_n "checking for _LARGE_FILES value needed for large files""... $ac_c" 1>&6
+echo "configure:5810: checking for _LARGE_FILES value needed for large files" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_large_files'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_large_files=no
+ cat > conftest.$ac_ext <<EOF
+#line 5816 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+
+
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:5827: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ cat > conftest.$ac_ext <<EOF
+#line 5834 "configure"
+#include "confdefs.h"
+#define _LARGE_FILES 1
+#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+
+
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:5846: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_sys_large_files=1
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_sys_large_files" 1>&6
+ if test "$ac_cv_sys_large_files" != no; then
+ cat >> confdefs.h <<EOF
+#define _LARGE_FILES $ac_cv_sys_large_files
+EOF
+
+ fi
+ echo $ac_n "checking for _XOPEN_SOURCE value needed for large files""... $ac_c" 1>&6
+echo "configure:5866: checking for _XOPEN_SOURCE value needed for large files" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_xopen_source'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_xopen_source=no
+ cat > conftest.$ac_ext <<EOF
+#line 5872 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+
+#include <stdio.h>
+
+int main() {
+return !ftello;
+; return 0; }
+EOF
+if { (eval echo configure:5883: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ cat > conftest.$ac_ext <<EOF
+#line 5890 "configure"
+#include "confdefs.h"
+#define _XOPEN_SOURCE 500
+#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+
+#include <stdio.h>
+
+int main() {
+return !ftello;
+; return 0; }
+EOF
+if { (eval echo configure:5902: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_sys_xopen_source=500
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_sys_xopen_source" 1>&6
+ if test "$ac_cv_sys_xopen_source" != no; then
+ cat >> confdefs.h <<EOF
+#define _XOPEN_SOURCE $ac_cv_sys_xopen_source
+EOF
+
+ fi
+ fi
+
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:5925: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5930 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:5938: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 5955 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 5973 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 5994 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:6005: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:6030: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6035 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:6084: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+
+echo $ac_n "checking for pow""... $ac_c" 1>&6
+echo "configure:6106: checking for pow" >&5
+if eval "test \"`echo '$''{'ac_cv_func_pow'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6111 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char pow(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char pow();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_pow) || defined (__stub___pow)
+choke me
+#else
+pow();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:6134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_pow=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_pow=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'pow`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for pow in -lm""... $ac_c" 1>&6
+echo "configure:6152: checking for pow in -lm" >&5
+ac_lib_var=`echo m'_'pow | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6160 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char pow();
+
+int main() {
+pow()
+; return 0; }
+EOF
+if { (eval echo configure:6171: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lm"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+
+
+
+cat >> confdefs.h <<\EOF
+#define MNG_SUPPORT_FULL 1
+EOF
+
+
+# Check whether --enable-read or --disable-read was given.
+if test "${enable_read+set}" = set; then
+ enableval="$enable_read"
+ :
+fi
+
+if test "x$enable_read" != "xno"; then
+ cat >> confdefs.h <<\EOF
+#define MNG_SUPPORT_READ 1
+EOF
+
+fi
+
+# Check whether --enable-write or --disable-write was given.
+if test "${enable_write+set}" = set; then
+ enableval="$enable_write"
+ :
+fi
+
+if test "x$enable_write" != "xno"; then
+ cat >> confdefs.h <<\EOF
+#define MNG_SUPPORT_WRITE 1
+EOF
+
+fi
+
+# Check whether --enable-display or --disable-display was given.
+if test "${enable_display+set}" = set; then
+ enableval="$enable_display"
+ :
+fi
+
+if test "x$enable_display" != "xno"; then
+ cat >> confdefs.h <<\EOF
+#define MNG_SUPPORT_DISPLAY 1
+EOF
+
+fi
+
+# Check whether --enable-chunks or --disable-chunks was given.
+if test "${enable_chunks+set}" = set; then
+ enableval="$enable_chunks"
+ :
+fi
+
+if test "x$enable_chunks" != "xno"; then
+ cat >> confdefs.h <<\EOF
+#define MNG_ACCESS_CHUNKS 1
+EOF
+
+fi
+
+# Check whether --enable-storechunks or --disable-storechunks was given.
+if test "${enable_storechunks+set}" = set; then
+ enableval="$enable_storechunks"
+
+if test "x$enable_storechunks" != "xno"; then
+ cat >> confdefs.h <<\EOF
+#define MNG_STORE_CHUNKS 1
+EOF
+
+fi
+
+fi
+
+
+# Check whether --enable-trace or --disable-trace was given.
+if test "${enable_trace+set}" = set; then
+ enableval="$enable_trace"
+
+if test "x$enable_trace" = "xyes"; then
+ cat >> confdefs.h <<\EOF
+#define MNG_SUPPORT_TRACE 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define MNG_TRACE_TELLTALE 1
+EOF
+
+fi
+
+fi
+
+
+cat >> confdefs.h <<\EOF
+#define MNG_ERROR_TELLTALE 1
+EOF
+
+
+
+# Check whether --with-zlib or --without-zlib was given.
+if test "${with_zlib+set}" = set; then
+ withval="$with_zlib"
+
+ if test -d "$withval"; then
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ fi
+
+fi
+
+ac_safe=`echo "zlib.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for zlib.h""... $ac_c" 1>&6
+echo "configure:6304: checking for zlib.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6309 "configure"
+#include "confdefs.h"
+#include <zlib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6314: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for gzread in -lz""... $ac_c" 1>&6
+echo "configure:6331: checking for gzread in -lz" >&5
+ac_lib_var=`echo z'_'gzread | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lz $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6339 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char gzread();
+
+int main() {
+gzread()
+; return 0; }
+EOF
+if { (eval echo configure:6350: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_lib=HAVE_LIB`echo z | sed -e 's/^a-zA-Z0-9_/_/g' \
+ -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_lib 1
+EOF
+
+ LIBS="-lz $LIBS"
+
+else
+ echo "$ac_t""no" 1>&6
+{ echo "configure: error: zlib library not found" 1>&2; exit 1; }
+fi
+
+else
+ echo "$ac_t""no" 1>&6
+{ echo "configure: error: zlib header not found" 1>&2; exit 1; }
+
+fi
+
+
+# Check whether --with-jpeg or --without-jpeg was given.
+if test "${with_jpeg+set}" = set; then
+ withval="$with_jpeg"
+ with_jpeg=$withval
+else
+ with_jpeg=_auto
+fi
+
+
+ if test "x$with_jpeg" != "xno" -a "x$with_jpeg" != "xyes" -a \
+ "x$with_jpeg" != "x_auto"; then
+ # Save in case test with directory specified fails
+ _cppflags=${CPPFLAGS}
+ _ldflags=${LDFLAGS}
+ _restore=1
+
+ CPPFLAGS="${CPPFLAGS} -I$withval/include"
+ LDFLAGS="${LDFLAGS} -L$withval/lib"
+ else
+ _restore=0
+ fi
+
+ if test "x$with_jpeg" != "xno"; then
+ ac_safe=`echo "jpeglib.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for jpeglib.h""... $ac_c" 1>&6
+echo "configure:6410: checking for jpeglib.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6415 "configure"
+#include "confdefs.h"
+#include <jpeglib.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6420: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ echo $ac_n "checking for jpeg_read_header in -ljpeg""... $ac_c" 1>&6
+echo "configure:6437: checking for jpeg_read_header in -ljpeg" >&5
+ac_lib_var=`echo jpeg'_'jpeg_read_header | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ljpeg $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6445 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char jpeg_read_header();
+
+int main() {
+jpeg_read_header()
+; return 0; }
+EOF
+if { (eval echo configure:6456: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ LIBS="$LIBS -ljpeg"
+ cat >> confdefs.h <<\EOF
+#define HAVE_LIBJPEG 1
+EOF
+
+ _restore=0
+
+else
+ echo "$ac_t""no" 1>&6
+echo "configure: warning: jpeg library not found" 1>&2
+fi
+
+else
+ echo "$ac_t""no" 1>&6
+echo "configure: warning: jpeg header not found" 1>&2
+
+fi
+
+ fi
+
+ test $_restore -eq 1 && CPPFLAGS=$_cppflags LDFLAGS=$_ldflags
+
+# Check whether --with-lcms or --without-lcms was given.
+if test "${with_lcms+set}" = set; then
+ withval="$with_lcms"
+ with_lcms=$withval
+else
+ with_lcms=_auto
+fi
+
+
+ if test "x$with_lcms" != "xno" -a "x$with_lcms" != "xyes" -a \
+ "x$with_lcms" != "x_auto"; then
+ # Save in case test with directory specified fails
+ _cppflags=$CPPFLAGS
+ _ldflags=$LDFLAGS
+ _restore=1
+
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ else
+ _restore=0
+ fi
+
+ if test "x$with_lcms" != "xno"; then
+ ac_safe=`echo "lcms.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for lcms.h""... $ac_c" 1>&6
+echo "configure:6519: checking for lcms.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 6524 "configure"
+#include "confdefs.h"
+#include <lcms.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:6529: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ have_lcms=yes
+ echo $ac_n "checking for cmsCreateRGBProfile in -llcms""... $ac_c" 1>&6
+echo "configure:6548: checking for cmsCreateRGBProfile in -llcms" >&5
+ac_lib_var=`echo lcms'_'cmsCreateRGBProfile | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-llcms $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 6556 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char cmsCreateRGBProfile();
+
+int main() {
+cmsCreateRGBProfile()
+; return 0; }
+EOF
+if { (eval echo configure:6567: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+
+ LIBS="$LIBS -llcms"
+ cat >> confdefs.h <<\EOF
+#define HAVE_LIBLCMS 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define MNG_FULL_CMS 1
+EOF
+
+ _restore=0
+ have_lcms=yes
+
+else
+ echo "$ac_t""no" 1>&6
+
+ have_lcms=no
+
+fi
+
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test "x$with_lcms" != "x_auto" -a "x$have_lcms" != "xyes"; then
+ echo "configure: warning: lcms not found... disabling CMS support" 1>&2
+ fi
+ fi
+
+ test $_restore -eq 1 && CPPFLAGS=$_cppflags LDFLAGS=$_ldflags
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it tqcontains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@U@%$U%g
+s%@ANSI2KNR@%$ANSI2KNR%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@LN_S@%$LN_S%g
+s%@OBJEXT@%$OBJEXT%g
+s%@EXEEXT@%$EXEEXT%g
+s%@ECHO@%$ECHO%g
+s%@RANLIB@%$RANLIB%g
+s%@STRIP@%$STRIP%g
+s%@LIBTOOL@%$LIBTOOL%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/configure.in b/tqtinterface/qt4/src/3rdparty/libmng/configure.in
new file mode 100644
index 0000000..511b363
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/configure.in
@@ -0,0 +1,177 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(libmng.h)
+
+dnl this call will define PACKAGE and VERSION
+dnl please use this as the primary reference for the version number
+AM_INIT_AUTOMAKE(libmng, 1.0.4)
+
+dnl pass the version string on the the makefiles
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_ISC_POSIX
+AM_C_PROTOTYPES
+if test "x$U" != "x"; then
+ AC_MSG_ERROR(Compiler not ANSI compliant)
+fi
+AM_PROG_LIBTOOL
+AC_PROG_INSTALL
+
+dnl support for files >2GB
+AC_SYS_LARGEFILE
+
+dnl Check for required header files
+AC_HEADER_STDC
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+
+dnl need pow and fabs
+AC_CHECK_FUNC(pow, , AC_CHECK_LIB(m, pow, LIBS="$LIBS -lm"))
+
+
+dnl what functionality we want to add (read, write, display).
+dnl all on by default. see libmng_conf.h for full descriptions
+
+dnl we only support the full mng spec for not (no LC or VLC)
+AC_DEFINE(MNG_SUPPORT_FULL)
+
+dnl remove support in library to read images?
+AC_ARG_ENABLE(read,
+[ --disable-read remove read support from library])
+if test "x$enable_read" != "xno"; then
+ AC_DEFINE(MNG_SUPPORT_READ)
+fi
+
+dnl remove support in library to write images?
+AC_ARG_ENABLE(write,
+[ --disable-write remove write support from library])
+if test "x$enable_write" != "xno"; then
+ AC_DEFINE(MNG_SUPPORT_WRITE)
+fi
+
+dnl remove support in library to display images?
+AC_ARG_ENABLE(display,
+[ --disable-display remove display support from library])
+if test "x$enable_display" != "xno"; then
+ AC_DEFINE(MNG_SUPPORT_DISPLAY)
+fi
+
+dnl remove support in library to access chunks?
+AC_ARG_ENABLE(chunks,
+[ --disable-chunks remove support for chunk access])
+if test "x$enable_chunks" != "xno"; then
+ AC_DEFINE(MNG_ACCESS_CHUNKS)
+fi
+
+dnl disable support for accessing chunks that have been previously read?
+AC_ARG_ENABLE(storechunks,
+[ --disable-storechunks remove support for access of previous chunks],[
+if test "x$enable_storechunks" != "xno"; then
+ AC_DEFINE(MNG_STORE_CHUNKS)
+fi
+])
+
+dnl enable support for debug tracing callbacks and messages?
+AC_ARG_ENABLE(trace,
+[ --enable-trace include support for debug tracing callbacks],[
+if test "x$enable_trace" = "xyes"; then
+ AC_DEFINE(MNG_SUPPORT_TRACE)
+ AC_DEFINE(MNG_TRACE_TELLTALE)
+fi
+])
+
+dnl verbose error text
+dnl this should always be on
+AC_DEFINE(MNG_ERROR_TELLTALE)
+
+
+dnl libz is required.
+AC_ARG_WITH(zlib,
+[ --with-zlib[=DIR] use zlib include/library files in DIR],[
+ if test -d "$withval"; then
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ fi
+])
+AC_CHECK_HEADER(zlib.h,
+ AC_CHECK_LIB(z, gzread, , AC_MSG_ERROR(zlib library not found)),
+ AC_MSG_ERROR(zlib header not found)
+)
+
+dnl check for jpeg library
+AC_ARG_WITH(jpeg,
+[ --with-jpeg[=DIR] use jpeg include/library files in DIR],
+[with_jpeg=$withval],[with_jpeg=_auto])
+
+ if test "x$with_jpeg" != "xno" -a "x$with_jpeg" != "xyes" -a \
+ "x$with_jpeg" != "x_auto"; then
+ # Save in case test with directory specified fails
+ _cppflags=${CPPFLAGS}
+ _ldflags=${LDFLAGS}
+ _restore=1
+
+ CPPFLAGS="${CPPFLAGS} -I$withval/include"
+ LDFLAGS="${LDFLAGS} -L$withval/lib"
+ else
+ _restore=0
+ fi
+
+ if test "x$with_jpeg" != "xno"; then
+ AC_CHECK_HEADER(jpeglib.h,
+ AC_CHECK_LIB(jpeg, jpeg_read_header, [
+ LIBS="$LIBS -ljpeg"
+ AC_DEFINE(HAVE_LIBJPEG)
+ _restore=0
+ ],
+ AC_MSG_WARN(jpeg library not found)),
+ AC_MSG_WARN(jpeg header not found)
+ )
+ fi
+
+ test $_restore -eq 1 && CPPFLAGS=$_cppflags LDFLAGS=$_ldflags
+
+dnl check for lcms library
+AC_ARG_WITH(lcms,
+[ --with-lcms[=DIR] use lcms include/library files in DIR],
+[with_lcms=$withval],[with_lcms=_auto])
+
+ if test "x$with_lcms" != "xno" -a "x$with_lcms" != "xyes" -a \
+ "x$with_lcms" != "x_auto"; then
+ # Save in case test with directory specified fails
+ _cppflags=$CPPFLAGS
+ _ldflags=$LDFLAGS
+ _restore=1
+
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ else
+ _restore=0
+ fi
+
+ if test "x$with_lcms" != "xno"; then
+ AC_CHECK_HEADER(lcms.h, [
+ have_lcms=yes
+ AC_CHECK_LIB(lcms, cmsCreateRGBProfile, [
+ LIBS="$LIBS -llcms"
+ AC_DEFINE(HAVE_LIBLCMS)
+ dnl for now this implies MNG_INCLUDE_LCMS in the headers:
+ AC_DEFINE(MNG_FULL_CMS)
+ _restore=0
+ have_lcms=yes
+ ],[
+ have_lcms=no
+ ])
+ ])
+ dnl give feedback only if the user asked specifically for lcms
+ if test "x$with_lcms" != "x_auto" -a "x$have_lcms" != "xyes"; then
+ AC_MSG_WARN([lcms not found... disabling CMS support])
+ fi
+ fi
+
+ test $_restore -eq 1 && CPPFLAGS=$_cppflags LDFLAGS=$_ldflags
+
+AC_OUTPUT(Makefile)
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/doc/Plan1.png b/tqtinterface/qt4/src/3rdparty/libmng/doc/Plan1.png
new file mode 100644
index 0000000..ced5517
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/doc/Plan1.png
Binary files differ
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/doc/Plan2.png b/tqtinterface/qt4/src/3rdparty/libmng/doc/Plan2.png
new file mode 100644
index 0000000..3619ea6
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/doc/Plan2.png
Binary files differ
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/doc/doc.readme b/tqtinterface/qt4/src/3rdparty/libmng/doc/doc.readme
new file mode 100644
index 0000000..d043a4c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/doc/doc.readme
@@ -0,0 +1,19 @@
+This directory hosts the documentation for libmng.
+
+You will tqfind a lot of useful info on the web-site:
+http://www.libmng.com
+
+Man-pages are in the man sub-directory
+
+RPM specification files are in the RPM sub-directory
+
+Files in this directory:
+
+- libmng.txt
+
+Description of the library proper and its usage
+
+- Plan1.png & Plan2.png
+
+Visual representation of the functional and technical
+design of the library (in PNG format of course!)
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/doc/libmng.txt b/tqtinterface/qt4/src/3rdparty/libmng/doc/libmng.txt
new file mode 100644
index 0000000..5194ef3
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/doc/libmng.txt
@@ -0,0 +1,1107 @@
+libmng - Multiple-image Network Graphics (MNG) Reference Library 1.0.4
+
+DESCRIPTION
+The libmng library supports decoding, displaying, encoding, and various
+other manipulations of the Multiple-image Network Graphics (MNG) format
+image files. It uses the zlib compression library, and optionally the
+JPEG library by the Independant JPEG Group (IJG) and/or
+lcms (little cms), a color-management library by Marti Maria Saguer.
+
+
+I. Introduction
+
+This file describes how to use and modify the MNG reference library
+(known as libmng) for your own use. There are seven sections to this
+file: introduction, callbacks, housekeeping, reading, displaying,
+writing, and modification and configuration notes for various special
+platforms. We assume that libmng is already installed; see the
+INSTALL.README file for instructions on how to install libmng.
+
+Libmng was written to support and promote the MNG specification.
+
+The latest MNG specification (currently 1.0) is available at
+ http://www.libpng.org/pub/mng
+
+Other information about MNG can be found at the MNG home page at
+ http://www.libpng.org/pub/mng
+
+The latest version of libmng can be found at its own homepage at
+ http://www.libmng.com
+
+In most cases the library will not need to be changed.
+For standardization purposes the library tqcontains both a Windows DLL
+and a makefile for building a shared library (SO). The library is
+written in C, but an interface for Borland Delphi is also available.
+
+Libmng has been designed to handle multiple sessions at one time,
+to be easily modifiable, to be portable to the vast majority of
+machines (ANSI, K&R, 32-, and 64-bit) available, and to be easy
+to use.
+
+Libmng uses zlib for its compression and decompression of MNG files.
+Further information about zlib, and the latest version of zlib, can be
+found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
+The zlib compression utility is a general purpose utility that is
+useful for more than MNG/PNG files, and can be used without libmng.
+See the documentation delivered with zlib for more details.
+
+Libmng optionally uses the JPEG library by the Independant JPEG Group
+(IJG). This library is used for the JNG sub-format, which is part of
+the MNG specification, and allows for inclusion of JPEG decoded and
+thus highly compressed (photographic) images.
+Further information about the IJG JPEG library and the latest sources
+can be found at <http://www.ijg.org>.
+
+Libmng can also optionally use the lcms (little CMS) library by
+Marti Maria Saguer. This library provides an excellent color-management
+system (CMS), which gives libmng the ability to provide full
+color-correction for images with the proper color-information encoded.
+Further information and the latest sources can be found at
+<http://www.littlecms.com/>.
+
+Libmng is thread safe, provided the threads are using different
+handles as returned by the initialization call.
+Each thread should have its own handle and thus its own image.
+Libmng does not protect itself against two threads using the
+same instance of a handle.
+
+The libmng.h header file is the single reference needed for programming
+with libmng:
+
+#include <libmng.h>
+
+
+II. Callbacks
+
+Libmng makes extensive use of callback functions. This is meant to
+keep the library as platform-independant and flexible as possible.
+Actually, the first call you will make to the library, already tqcontains
+three parameters you can use to provide callback entry-points.
+
+Most functions must return a mng_bool (boolean). Returning MNG_FALSE
+indicates the library the callback failed in some way and the library
+will immediately return from whatever it was doing back to the
+application. Returning MNG_TRUE indicates there were no problems and
+processing can continue.
+
+Let's step through each of the possible callbacks. The sections on
+reading, displaying and writing will also explain which callbacks are
+needed when and where.
+
+- mng_ptr mng_memalloc (mng_size_t iLen)
+
+A very basic function which the library uses to allocate a memory-block
+with the given size. A typical implementation would be:
+
+ mng_ptr my_alloc (mng_size_t iLen) {
+ return calloc (1, iSize);
+ }
+
+Note that the library requires you to zero-out the memory-block!!!
+
+- void mng_memfree (mng_ptr pPtr,
+ mng_size_t iLen)
+
+Counterpart of the previous function. Typically:
+
+ void my_free (mng_ptr pPtr, mng_size_t iLen) {
+ free (pPtr);
+ }
+
+- mng_bool mng_openstream (mng_handle hHandle)
+- mng_bool mng_closestream (mng_handle hHandle)
+
+These are called by the library just before it starts to process
+(either read or write) a file and just after the processing stops.
+This is the recommended place to do I/O initialization & finalization.
+Whether you do or not, is up to you. The library does not put any
+meaning into the calls. They are simply provided for your convenience.
+
+- mng_bool mng_readdata (mng_handle hHandle,
+ mng_ptr pBuf,
+ mng_uint32 iBuflen,
+ mng_uint32p pRead)
+
+This function is called when the library needs some more input while
+reading an image. The reading process supports two modes:
+Suspension-mode (SMOD) and non-suspension-mode (NSMOD).
+See mng_set_suspensionmode() for a more detailed description.
+
+In NSMOD, the library requires you to return exactly the amount of bytes
+requested (= iBuflen). Any lesser amount indicates the input file
+is exhausted and the library will return a MNG_UNEXPECTEDEOF errorcode.
+
+In SMOD, you may return a smaller amount of bytes than requested.
+This tells the library it should temporarily wait for more input to
+arrive. The lib will return with MNG_NEEDMOREDATA, and will expect a
+call to mng_read_resume() or mng_display_resume() next, as soon as
+more input-data has arrived.
+
+For NSMOD this function could be as simple as:
+
+ mng_bool my_read (mng_handle hHandle,
+ mng_ptr pBuf,
+ mng_uint32 iBuflen,
+ mng_uint32p pRead) {
+ *pRead = fread (pBuf, 1, iBuflen, myfile);
+ return MNG_TRUE;
+ }
+
+- mng_bool mng_writedata (mng_handle hHandle,
+ mng_ptr pBuf,
+ mng_uint32 iBuflen,
+ mng_uint32p pWritten)
+
+This function is called during the mng_write() function to actually
+output data to the file. There is no suspension-mode during write,
+so the application must return the exact number of bytes the library
+requests to be written.
+
+A typical implementation could be:
+
+ mng_bool my_write (mng_handle hHandle,
+ mng_ptr pBuf,
+ mng_uint32 iBuflen,
+ mng_uint32p pWritten) {
+ *pWritten = fwrite (pBuf, 1, iBuflen, myfile);
+ return MNG_TRUE;
+ }
+
+- mng_bool mng_errorproc (mng_handle hHandle,
+ mng_int32 iErrorcode,
+ mng_int8 iSeverity,
+ mng_chunkid iChunkname,
+ mng_uint32 iChunkseq,
+ mng_int32 iExtra1,
+ mng_int32 iExtra2,
+ mng_pchar zErrortext)
+
+This function is called whenever an error is detected inside the
+library. This may be caused by invalid input, callbacks indicating
+failure, or wrongfully calling functions out of place.
+
+If you do not provide this callback the library will still return
+an errorcode from the called function, and the mng_getlasterror()
+function can be used to retrieve the other parameters.
+
+This function is currently only provided for convenience, but may
+at some point be used to indicate certain errors may be acceptable,
+and processing should continue.
+
+- mng_bool mng_traceproc (mng_handle hHandle,
+ mng_int32 iFuncnr,
+ mng_int32 iFuncseq,
+ mng_pchar zFuncname)
+
+This function is provided to allow a functional analysis of the
+library. This may be useful if you encounter certain errors and
+cannot determine what the problem is.
+
+Almost all functions inside the library will activate this
+callback with an appropriate function-name at the start and end
+of the function. Please note that large images may generate an
+enormous amount of calls.
+
+- mng_bool mng_processheader (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight)
+
+This function is called once the header information of an input-
+image has been processed. At this point the image dimensions are
+available and also some other properties depending on the type
+of the image. Eg. for a MNG the frame-/layercount, playtime &
+simplicity fields are known.
+
+The primary purpose of this callback is to inform the application
+of the size of the image, and for the application to initialize
+the drawing canvas to be used by the library. This is also a good
+point to set the canvas-style. Eg. mng_set_canvasstyle().
+
+- mng_bool mng_processtext (mng_handle hHandle,
+ mng_uint8 iType,
+ mng_pchar zKeyword,
+ mng_pchar zText,
+ mng_pchar zLanguage,
+ mng_pchar zTranslation)
+
+This callback is activated for each textual chunk in the input-
+image. These are tEXt, zTXt & iTXt. It may be used to retain
+specific comments for presentation to the user.
+
+- mng_bool mng_processsave (mng_handle hHandle)
+- mng_bool mng_processseek (mng_handle hHandle,
+ mng_pchar zName)
+
+The purpose of these callbacks is to signal the processing of the
+SAVE & SEEK chunks in a MNG input-file. This may be used in the
+future to specify some special processing. At the moment these
+functions are only provided as a signal.
+
+- mng_ptr mng_getcanvasline (mng_handle hHandle,
+ mng_uint32 iLinenr)
+- mng_ptr mng_getbkgdline (mng_handle hHandle,
+ mng_uint32 iLinenr)
+- mng_ptr mng_getalphaline (mng_handle hHandle,
+ mng_uint32 iLinenr)
+
+These callbacks are used to access the drawing canvas, background
+canvas and an optional separate alpha-channel canvas. The latter is
+used only with the MNG_CANVAS_RGB8_A8 canvas-style.
+
+If the getbkgdline() callback is not supplied the library will
+composite full or partially transtqparent pixels in the image against
+a specified background color. See mng_set_bgcolor() for more details.
+If a chosen canvas-style includes an alpha-channel, this callback
+is very likely not needed.
+
+The application is responsible for returning a pointer to a line of
+pixels, which should be in the exact format as defined by the call
+to mng_set_canvasstyle() and mng_set_bkgdstyle(), without gaps between
+the representation of each pixel.
+
+- mng_bool mng_refresh (mng_handle hHandle,
+ mng_uint32 iX,
+ mng_uint32 iY,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight)
+
+This callback is called when the library has drawn a complete frame
+onto the drawing canvas, and it is ready to be displayed.
+The application is responsible for transferring the drawing canvas
+from memory onto the actual output tqdevice.
+
+- mng_uint32 mng_gettickcount (mng_handle hHandle)
+
+This function should return the number of milliseconds on some internal
+clock. The entire animation timing depends heavily on this function,
+1and the number returned should be as accurate as possible.
+
+- mng_bool mng_settimer (mng_handle hHandle,
+ mng_uint32 iMsecs)
+
+This callback is activated every time the library requires a "pause".
+Note that the function itself should NOT execute the wait. It should
+simply store the time-field and allow the library to return. Libmng
+will return with the MNG_NEEDTIMERWAIT code, indicating the callback
+was called and it is now time to execute the pause.
+
+After the indicated number of milliseconds have elapsed, the application
+should call mng_display_resume(), to resume the animation as planned.
+
+This method allows for both a real timer or a simple wait command in the
+application. Whichever method you select, both the gettickcount() and
+settimer() callbacks are crucial for proper animation timing.
+
+- mng_bool mng_processgamma (mng_handle hHandle,
+ mng_uint32 iGamma)
+- mng_bool mng_processchroma (mng_handle hHandle,
+ mng_uint32 iWhitepointx,
+ mng_uint32 iWhitepointy,
+ mng_uint32 iRedx,
+ mng_uint32 iRedy,
+ mng_uint32 iGreenx,
+ mng_uint32 iGreeny,
+ mng_uint32 iBluex,
+ mng_uint32 iBluey)
+- mng_bool mng_processsrgb (mng_handle hHandle,
+ mng_uint8 iRenderingintent)
+- mng_bool mng_processiccp (mng_handle hHandle,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile)
+- mng_bool mng_processarow (mng_handle hHandle,
+ mng_uint32 iRowsamples,
+ mng_bool bIsRGBA16,
+ mng_ptr pRow)
+
+These callbacks are only required when you selected the MNG_APP_CMS
+directive during compilation of the library. See the configuration
+section for more details.
+
+- mng_bool mng_iteratechunk (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_chunkid iChunkid,
+ mng_uint32 iChunkseq)
+
+This callback is only used for the mng_iterate_chunks() function.
+It is called exactly once for each chunk stored.
+
+
+III. Housekeeping
+
+
+> Memory management
+
+The library can use internal memory allocation/deallocation or use
+provided callbacks for its memory management. The choice is made at
+compilation time. See the section on customization for details.
+
+If internal management has been selected, the memory callback functions
+need not be supplied. Even if you do supply them they will not be used.
+The actual code used is similar to the code discussed in the callback
+section:
+
+ pPtr = calloc (1, iSize);
+
+ free (pPtr);
+
+If your compiler does not support these functions, or you wish to monitor
+the library's use of memory for certain reasons, you can choose to
+compile the library with external memory management. In this case the
+memory callback functions MUST be supplied, and should function as if the
+above code was used.
+
+
+> Initialization
+
+The basic initialization of the library is short and swift:
+
+ myhandle = mng_initialize (myuserdata, my_alloc,
+ my_free, MNG_NULL);
+ if (myhandle == MNG_NULL)
+ /* process error */;
+
+The first field is an application-only parameter. It is saved in
+libmng's internal structures and available at all times through the
+mng_get_userdata() function. This is especially handy in callback functions
+if your program may be handling multiple files at the same time.
+
+The second and third field supply the library with the memory callback
+1function entry-points. These are described in more detail in the callback
+section and the previous paragraph.
+
+The fourth and last field may be used to supply the library with the
+entry-point of a trace callback function. For regular use you will not
+need this!
+
+The function returns a handle which will be your ticket to MNG-heaven.
+All other functions rely on this handle. It is the single fixed unique
+reference-point between your application and the library.
+
+You should call the initialization function for each image you wish to
+process simultaneously. If you are processing images consecutively, you can
+reset the internal status of the library with the mng_reset() function.
+This function will clear all internal state variables, free any stored
+chunks and/or objects, etc, etc. Your callbacks and other external parameters
+will be retained.
+
+After you successfully received the handle it is time to set the required
+callbacks. The sections on reading, displaying & writing indicate which
+callbacks are required and which are optional.
+To set the callbacks simply do:
+
+ myretcode = mng_setcb_xxxxxx (myhandle, my_xxxxxx);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+Naturally you'd tqreplace the x's with the name of the callback.
+
+
+> Cleanup
+
+Once you've gotten hold of that precious mng_handle, you should always,
+and I mean always, call the cleanup function when you're done.
+Just do:
+
+ mng_cleanup (myhandle);
+
+And you're done. There shouldn't be an ounce of memory spilled after
+that call.
+
+Note that if you would like to process multiple files consecutively
+you do not need to do mng_cleanup() / mng_initialize() between each file
+but simply
+
+ myretcode = mng_reset (myhandle);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+will suffice. Saves some time and effort, that.
+
+
+> Error handling
+
+From the examples in the previous paragraphs you may have noticed a
+meticulous scheme for error handling. And yes, that's exactly what it is.
+Practically each call simply returns an errorcode, indicating success,
+eg. MNG_NOERROR or failure, anything else but MNG_NEEDMOREDATA and
+MNG_NEEDTIMERWAIT. These latter two will be discussed in more detail in
+their respective fields of interest: the reading section and displaying
+section respectively.
+
+It is the application's responsibility to check the returncode after
+each call. You can call mng_getlasterror() to receive the details of
+the last detected error. This even includes a discriptive error-message
+if you enabled that option during compilation of the library.
+
+Note that after receiving an error it is still possible to call the
+library, but it's also very likely that any following call will fail.
+The only functions deemed to work will be mng_reset() and mng_cleanup().
+Yes, if you abort your program after an error, you should still call
+mng_cleanup().
+
+
+IV. Reading
+
+Reading a MNG, JNG or PNG is fairly easy. It depends slightly on your
+ultimate goal how certain specifics are to be handled, but the basics
+are similar in all cases.
+
+For the read functioins to work you must have compiled the library with
+the MNG_READ_SUPPRT directive. The standard DLL and Shared Library
+have this on by default!
+
+
+> Setup
+
+Naturally you must have initialized the library and be the owner of
+a mng_handle. The following callbacks are essential:
+
+ mng_openstream, mng_readdata, mng_closestream
+
+You may optionally define:
+
+ mng_errorproc, mng_traceproc
+ mng_processheader, mng_processtext
+ mng_processsave, mng_processseek
+
+The reading bit will also fail if you are already creating or
+displaying a file. Seems a bit obvious, but I thought I'd mention it,
+just in case.
+
+
+> To suspend or not to suspend
+
+There is one choice you need to make before calling the read function.
+Are you in need of suspension-mode or not?
+
+If you're reading from a disk you most certainly do not need
+suspension-mode. Even the oldest and slowest of disks will be fast
+enough for straight reading.
+
+However, if your input comes from a really slow tqdevice, such as a
+dialup-line or the likes, you may opt for suspension-mode. This is done
+by calling
+
+ myretcode = mng_set_suspensionmode (myhandle,
+ MNG_TRUE);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+Suspension-mode will force the library to use special buffering on the
+input. This allows your application to receive data of arbitrarily length
+and return this in the mng_readdata() callback, without disturbing the
+chunk processing routines of the library.
+
+Suspension-mode does require a little extra care in the main logic of the
+1application. The read function may return with MNG_NEEDMOREDATA when the
+mng_readdata() callback returns less data then it needs to process the
+next chunk. This indicates the application to wait for more data to arrive
+and then resume processing by calling mng_read_resume().
+
+
+> The read HLAPI
+
+The actual reading is just plain simple. Since all I/O is done
+1outside the library through the callbacks, the library can focus on
+its real task. Understanding, checking and labelling the input data!
+
+All you really need to do is this:
+
+ myretcode = mng_read (myhandle);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+Of course, if you're on suspension-mode the code is a little more
+complicated:
+
+ myretcode = mng_read (myhandle);
+
+ while (myretcode == MNG_NEEDMOREDATA) {
+ /* wait for input-data to arrive */
+ myretcode = mng_read_resume (myhandle);
+ }
+
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+This is rather crude and more sophisticated programming methods may
+dictate another approach. Whatever method you decide on, it should
+act as if the above code was in its place.
+
+There is also the mng_readdisplay() function, but this is discussed
+in the displaying section. It functions pretty much as the mng_read()
+function, but also immediately starts displaying the image.
+mng_read_resume() should be tqreplaced by mng_display_resume() in that
+case!
+
+
+> What happens inside
+
+What actually happens inside the library depends on the configuration
+options set during the compilation of the library.
+
+Basically the library will first read the 8-byte file header, to determine
+its validity and the type of image it is about to process. Then it will
+repeatedly read a 4-byte chunk-length and then the remainder of the chunk
+until it either reaches EOF (indicated by the mng_readdata() callback) or
+implicitly decides EOF as it processed the logically last chunk of the
+image.
+
+Applications that require strict conformity and do not allow superfluous
+data after the ending chunk, will need to perform this check in their
+mng_closestream() callback.
+
+Each chunk is then checked on CRC, after which it is handed over to the
+appropriate chunk processing routine. These routines will disect the
+chunk, check the validity of its contents, check its position with respect
+to other chunks, etc, etc.
+
+If everything checks out, the chunk is further processed as follows:
+
+If display support has been selected during compilation, certain pre-display
+initialization will take place.
+
+If chunk-storage support has been selected during compilation, the chunks
+data may be stored in a special internal structure and held for future
+reference.
+
+
+> Storing and accessing chunks
+
+One of the compilation options activates support for chunk storage.
+This option may be useful if you want to examine an image. The directive
+is MNG_STORE_CHUNKS. You must also turn on the MNG_ACCESS_CHUNKS
+directive.
+
+The actual storage facility can be turned on or off with the
+mng_set_storechunks() function. If set to MNG_TRUE, chunks will be
+stored as they are read.
+
+At any point you can then call the mng_iterate_chunks() function
+to iterate through the current list of chunks. This function requires
+a callback which is called for each chunk and receives a specific
+chunk-handle. This chunk-handle can be used to call the appropriate
+mng_getchunk_xxxx() function, to access the chunks properties.
+
+A typical implementation may look like this:
+
+ mng_bool my_iteratechunk (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_chunkid iChunkid,
+ mng_uint32 iChunkseq) {
+ switch (iChunkid) {
+ case MNG_UINT_MHDR : { /* process MHDR */;
+ break; }
+ case MNG_UINT_FRAM : { /* process FRAM */;
+ break; }
+
+ ...etc...
+
+ case MNG_UINT_HUH : { /* unknown chunk */;
+ break; }
+ default : { /* duh; forgot one */; }
+ }
+
+ return MNG_TRUE; /* keep'm coming */
+ }
+
+To get to the actual chunk fields of lets say a SHOW chunk you would do:
+
+ mng_bool isempty;
+ mng_uint16 firstid, lastid;
+ mng_uint8 showmode;
+
+ myretcode mng_getchunk_show (hHandle, hChunk,
+ isempty, firstid,
+ lastid, showmode);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+
+V. Displaying
+
+
+> Setup
+
+Assuming you have initialized the library and are the owner of
+a mng_handle. The following callbacks are essential:
+
+ mng_getcanvasline, mng_refresh
+ mng_gettickcount, mng_settimer
+
+If you wish to use an application supplied background you must supply:
+
+ mng_getbkgdline
+
+If you wish to use the MNG_CANVAS_RGB8_A8 canvas style you must supply:
+
+ mng_getalphaline
+
+You may optionally define:
+
+ mng_errorproc, mng_traceproc
+ mng_processheader, mng_processtext
+ mng_processsave, mng_processseek
+
+Note that the mng_processheader() callback is optional but will
+be quite significant for proper operation!
+
+Displaying an image will fail if you are creating a file or already
+displaying one. Yes, you can't display it twice!
+
+
+> A word on canvas styles
+
+The canvas style describes how your drawing canvas is made up.
+You must set this before the library actually starts drawing, so
+the mng_processheader() callback is a pretty good place for it.
+
+Currently only 8-bit RGB canvas styles are supported, either with
+or without an alpha channel.
+
+If you like to do alpha composition yourself you can select one of
+the canvas styles that include an alpha channel. You can even have
+a separate alpha canvas by selecting the MNG_CANVAS_RGB8_A8 style.
+
+All styles require a compact model. Eg. MNG_CANVAS_BGR8 requires
+your canvas lines in bgrbgrbgr... storage, where each letter
+represents an 8-bit value of the corresponding color, and each
+threesome makes up the values of one(1) pixel.
+
+The library processes a line at a time, so the canvas lines do not
+actually need to be consecutive in memory.
+
+
+> Alpha composition and application backgrounds
+
+All Network Graphics can be partially transtqparent. This requires
+special processing if you need to display an image against some
+background. Note that the MNG header (MHDR chunk) tqcontains a
+simplicity field indicating whether transparency information in
+the file is critical or not. This only applies to embedded images,
+which means the full image-frame of the MNG may still contain fully
+transtqparent pixels!
+
+Depending on your needs you can supply a single background color,
+a background canvas or tell the library to return the alpha-channel
+and do alpha composition yourself.
+
+This is different from the BACK chunk in a MNG, or the bKGD chunk
+in an (embedded) PNG or JNG. The BACK chunk indicates an optional or
+mandatory background color and/or image. The bKGD chunk only indicates
+an optional background color. These chunks indicate the Authors
+preferences. They may be absent in which case you need to supply
+some sort of background yourself.
+
+> Composing against a background color
+
+This is the easiest method. Call the mng_set_bgcolor() function to
+set the values of the red, green and blue component of your preferred
+background color.
+
+Use one of the canvas styles that do not have an alpha-channel, and
+which matches your output requirements.
+
+> Composing against a background canvas
+
+This is somewhat more complicated. You will need to set the
+mng_getbkgdline() callback. This will be called whenever the library
+needs to compose a partially transtqparent line.
+
+This canvas must hold the background against which the image should
+be composed. Its size must match exactly with the image dimensions
+and thus the drawing canvas!
+
+Use one of the canvas styles that do not have an alpha-channel, and
+which matches your output requirements. The canvas style of the
+background canvas may even differ from the drawing canvas. The library's
+composing will still function properly.
+
+> Composing within the application
+
+If you have the option in your application to draw a (partially)
+transtqparent canvas to the output tqdevice, this option is preferred.
+
+Select one of the canvas styles that do have an alpha-channel.
+The library will now supply the appropriate alpha information,
+allowing the application to compose the image as it sees fit.
+
+
+> Color information and CMS
+
+Network Graphics may, and usually will, contain color-correction
+information. This information is intended to compensate for the
+difference in recording and display tqdevices used.
+
+This document does not address the specifics of color-management.
+See the PNG specification for a more detailed description.
+
+> Using little cms by Marti Maria Saguer
+
+This is the easiest method, providing you can compile the lcms package.
+Select the MNG_FULL_CMS directive during compilation, and sit back and
+relax. The library will take care of all color-correction for you.
+
+> Using an OS- or application-supplied CMS
+
+If you are so lucky to have access to CMS functionality from within
+your application, you may instruct the library to leave color-correction
+to you.
+
+Select the MNG_APP_CMS directive during compilation of the library.
+You MUST also set the following callbacks:
+
+ mng_processgamma, mng_processchroma,
+ mng_processsrgb, mng_processiccp and
+ mng_processarow
+
+The last callback is called when the library needs you to correct
+an arbitrary line of pixels. The other callbacks are called when
+the corresponding color-information is encountered in the file.
+You must store this information somewhere for use in the
+mng_processarow() callback.
+
+> Using gamma-only correction
+
+This isn't a preferred method, but it's better than no correction
+at all. Gamma-only correction will at least compensate for
+gamma-differences between the original recorder and your output tqdevice.
+
+Select the MNG_GAMMA_ONLY directive during compilation
+of the library. Your compiler MUST support fp operations.
+
+> No color correction
+
+Ouch. This is really bad. This is the least preferred method,
+but may be necessary if your system cannot use lcms, doesn't
+have its own CMS, and does not allow fp operations, ruling out
+the gamma-only option.
+
+Select the MNG_NO_CMS directive during compilation.
+Images will definitely not be displayed as seen by the Author!!!
+
+
+> Animations and timing
+
+Animations require some form of timing support. The library relies
+on two callbacks for this purpose. The mng_gettickcount() and
+mng_settimer() callbacks. mng_gettickcount() is used to determine
+the passing of time in milliseconds since the beginning of the
+animation. This is also used to compensate during suspension-mode
+if you are using the mng_readdisplay() function to read & display
+the file simultaneously.
+
+The callback may return an arbitrary number of milliseconds, but
+this number must increase proportionaly between calls. Most modern
+systems will have some tickcount() function which derives its
+input from an internal clock. The value returned from this function
+is more than adequate for libmng.
+
+The mng_settimer() callback is called when the library determines
+a little "pause" is required before rendering another frame of the
+animation. The pause interval is also expressed in milliseconds.
+Your application should store this value and return immediately.
+The library will then make appropriate arrangements to store its
+internal state and returns to your application with the
+MNG_NEEDTIMERWAIT code.
+
+At that point you should suspend processing and wait the given
+interval. Please use your OS features for this. Do not engage some
+sort of loop. That is real bad programming practice. Most modern
+systems will have some timing functions. A simple wait() function
+may suffice, but this may prevent your applications main-task from
+running, and possibly prevent the actual update of your output tqdevice.
+
+
+> The mng_refresh() callback
+
+The mng_refresh() callback is called whenever the library has
+"finished" drawing a new frame onto your canvas, and just before it
+will call the mng_settimer() callback.
+
+This allows you to perform some actions necessary to "refresh" the
+canvas onto your output tqdevice. Please do NOT suspend processing
+inside this callback. This must be handled after the mng_settimer()
+callback!
+
+
+> Displaying while reading
+
+This method is preferred if you are reading from a slow input tqdevice
+(such as a dialup-line) and you wish to start displaying something
+as quickly as possible. This functionality is provided mainly for
+browser-type applications but may be appropriate for other
+applications as well.
+
+The method is usually used in unison with the suspension-mode of
+the read module. A typical implementation would look like this:
+
+ /* initiale library and set required callbacks */
+
+ /* activate suspension-mode */
+ myretcode = mng_set_suspensionmode (myhandle,
+ MNG_TRUE);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+ myretcode = mng_readdisplay (myhandle);
+
+ while ((myretcode == MNG_NEEDMOREDATA) ||
+ (myretcode == MNG_NEEDTIMERWAIT)) {
+ if (myretcode == MNG_NEEDMOREDATA)
+ /* wait for more input-data */;
+ else
+ /* wait for timer interval */;
+
+ myretcode = mng_display_resume (myhandle);
+ }
+
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+More advanced programming methods may require a different approach,
+but the final result should function as in the code above.
+
+
+> Displaying after reading
+
+This method is used to display a file that was previously read.
+It is primarily meant for viewers with direct file access, such as
+1a local harddisk.
+
+Once you have successfully read the file, all you need to do is:
+
+ myretcode = mng_display (myhandle);
+
+ while (myretcode == MNG_NEEDTIMERWAIT) {
+ /* wait for timer interval */;
+ myretcode = mng_display_resume (myhandle);
+ }
+
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+Again, more advanced programming methods may require a different
+approach, but the final result should function as in the code above.
+
+
+> Display manipulation
+
+Several HLAPI functions are provided to allow a user to manipulate
+the normal flow of an animation.
+
+- mng_display_freeze (mng_handle hHandle)
+
+This will "freeze" the animation in place.
+
+- mng_display_resume (mng_handle hHandle)
+
+This function can be used to resume a frozen animation, or to force
+the library to advance the animation to the next frame.
+
+- mng_display_reset (mng_handle hHandle)
+
+This function will "reset" the animation into its pristine state.
+Calling mng_display_resume() afterwards will restart the animation
+from the first frame.
+
+- mng_display_golayer (mng_handle hHandle,
+ mng_uint32 iLayer)
+- mng_display_goframe (mng_handle hHandle,
+ mng_uint32 iFrame)
+- mng_display_goplaytime (mng_handle hHandle,
+ mng_uint32 iPlaytime)
+
+These three functions can be used to "jump" to a specific layer, frame
+or timeslot in the animation. You must "freeze" the animation before
+using any of these functions.
+
+All above functions may only be called during a timer interval!
+It is the applications responsibility to cleanup any resources with
+respect to the timer wait.
+
+
+VI. Writing
+
+The main focus of the library lies in its displaying capabilites.
+But it does offer writing support as well.
+You can create and write a file, or you can write a file you
+have previously read, providing the storage of chunks was enabled
+and active.
+
+For this to work you must have compiled the library with the
+MNG_WRITE_SUPPO1RT and MNG_ACCESS_CHUNKS directives. The standard DLL and
+Shared Library have this on by default!
+
+
+> Setup
+
+As always you must have initialized the library and be the owner of
+a mng_handle. The following callbacks are essential:
+
+ mng_openstream, mng_writedata, mng_closestream
+
+You can optionally define:
+
+ mng_errorproc, mng_traceproc
+
+The creation and writing functions will fail if you are in the middle
+of reading, creating or writing a file.
+
+
+> Creating a new file
+
+To start a new file the library must be in its initial state.
+First you need to tell the library your intentions:
+
+ myretcode = mng_create (myhandle);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+After that you start adding the appropriate chunks:
+
+ myretcode = mng_putchunk_mhdr (myhandle, ...);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+And so on, and so forth. Note that the library will automatically signal
+the logical end of the file by the ending chunk. Also the first chunk
+will indicate the library the filetype (eg. PNG, JNG or MNG) and force
+the proper signature when writing the file.
+
+The code above can be simplified, as you can always get the last errorcode
+by using the mng_getlasterror() function:
+
+ if ( (mng_putchunk_xxxx (myhandle, ...)) or
+ (mng_putchunk_xxxx (myhandle, ...)) or
+ ...etc... )
+ /* process error */;
+
+Please note that you must have a pretty good understanding of the chunk
+specification. Unlike the read functions, there are virtually no checks,
+so it is quite possible to write completely wrong files.
+It is a good practice to read back your file into the library to verify
+its integrity.
+
+Once you've got all the chunks added, all you do is:
+
+ myretcode mng_write (myhandle);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+And presto. You're done. The real work is of course carried out in
+your callbacks. Note that this is a single operation as opposed to
+the read & display functions that may return with MNG_NEEDMOREDATA
+and/or MNG_NEEDTIMERWAIT. The write function just does the job, and
+only returns after it's finished or if it encounters some
+unrecoverable error.
+
+
+> Writing a previously read file
+
+If you have already successfully read a file, you can use the library to
+write it out as a copy or something. You MUST have compiled the library
+with the MNG_STORE_CHUNKS directive, and you must have done
+mng_set_storechunks (myhandle, MNG_TRUE).
+
+This doesn't require the MNG_ACCESS_CHUNKS directive, unless you want
+to fiddle with the chunks as well.
+
+Again all you need to do is:
+
+ myretcode mng_write (myhandle);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+
+VII. Modifying/Customizing libmng:
+
+to do
+
+> Compilation directives
+
+to do
+
+> Platform dependant modification
+
+to do
+
+
+References :
+
+libmng :
+ http://www.libmng.com
+
+zlib :
+ http://www.info-zip.org/pub/infozip/zlib/
+
+IJG JPEG library :
+ http://www.ijg.org
+
+lcms (little CMS) by Marti Maria Saguer :
+ http://www.littlecms.com/
+
+MNG specification:
+ http://www.libpng.org/pub/mng
+
+
+In the case of any inconsistency between the MNG specification
+and this library, the specification takes precedence.
+
+
+The contributing authors would like to thank all those who helped
+with testing, bug fixes, and patience. This wouldn't have been
+possible without all of you!!!
+
+
+COPYRIGHT NOTICE:
+
+Copyright (c) 2000,2001 Gerard Juyn
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Gerard Juyn
+
+The MNG Library is supplied "AS IS". The Contributing Authors
+disclaim all warranties, expressed or implied, including, without
+limitation, the warranties of merchantability and of fitness for any
+purpose. The Contributing Authors assume no liability for direct,
+indirect, incidental, special, exemplary, or consequential damages,
+which may result from the use of the MNG Library, even if advised of
+the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented;
+you must not claim that you wrote the original software.
+
+2. Altered versions must be plainly marked as such and must not be
+misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any source
+or altered source distribution.
+
+The Contributing Authors specifically permit, without fee, and
+encourage the use of this source code as a component to supporting
+the MNG and JNG file format in commercial products. If you use this
+source code in a product, acknowledgment would be highly appreciated.
+
+
+Remarks :
+
+Parts of this software have been adapted from the libpng library.
+Although this library supports all features from the PNG specification
+(as MNG descends from it) it does not require the libpng library.
+It does require the zlib library and optionally the IJG JPEG library,
+and/or the "little-cms" library by Marti Maria Saguer (depending on the
+inclusion of support for JNG and Full-Color-Management respectively.
+
+This library's function is primarily to read and display MNG
+animations. It is not meant as a full-featured image-editing
+component! It does however offer creation and editing functionality
+at the chunk level. (future modifications may include some more
+support for creation and or editing)
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/doc/man/jng.5 b/tqtinterface/qt4/src/3rdparty/libmng/doc/man/jng.5
new file mode 100644
index 0000000..6b57bfc
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/doc/man/jng.5
@@ -0,0 +1,37 @@
+.TH JNG 5 "July 26, 2000"
+.SH NAME
+jng \- JPEG Network Graphics (JNG) sub-format
+.SH DESCRIPTION
+JNG (JPEG Network Graphics) is a sub-format of the MNG (Multiple-image
+Network Graphics) format. As with MNG it extends on the features of the
+popular PNG (Portable Network Graphics) image-format.
+.br
+
+This sub-format was designed to support a lossy compression-method.
+It is based completely on the JPEG specification. It adds the high-compression
+ratios of JPEG for photographic images.
+
+As a member of the Network Graphics family, JNG was deemed adequate as a
+stand-alone format as it extends the JPEG format with color-correction and
+transparency features.
+
+.SH "SEE ALSO"
+.IR png(5), mng(5), libmng(3)
+.LP
+MNG 0.97 draft 70, Februari 2000:
+.IP
+http://www.libpng.org/pub/mng
+
+.SH AUTHORS
+This man page: Gerard Juyn
+.LP
+Multiple-image Network Graphics (MNG) Specification Version 0.97 (Februari 27, 2000):
+Glenn Randers-Pehrson and others (png-list@ccrc.wustl.edu).
+.LP
+
+.SH COPYRIGHT NOTICE
+The MNG-0.97 specification is copyright (c) 1998,1999,2000 Glenn Randers-Pehrson.
+See the specification for conditions of use and distribution.
+.LP
+.\" end of man page
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/doc/man/libmng.3 b/tqtinterface/qt4/src/3rdparty/libmng/doc/man/libmng.3
new file mode 100644
index 0000000..37bde5f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/doc/man/libmng.3
@@ -0,0 +1,1147 @@
+.TH LIBMNG 3 "June 23rd, 2002"
+.SH NAME
+libmng \- Multiple-image Network Graphics (MNG) Reference Library 1.0.4
+.SH SYNOPSIS
+\fI\fB
+
+\fB#include <libmng.h>\fP
+
+
+.SH DESCRIPTION
+The
+.I libmng
+library supports decoding, displaying, encoding, and various other
+manipulations of the Multiple-image Network Graphics (MNG) format
+image files. It uses the
+.IR zlib(3)
+compression library, and optionally the JPEG library by the Independant
+JPEG Group (IJG) and/or lcms (little cms), a color-management library
+by Marti Maria Saguer.
+
+
+.SH I. Introduction
+
+This file describes how to use and modify the MNG reference library
+(known as libmng) for your own use. There are seven sections to this
+file: introduction, callbacks, housekeeping, reading, displaying,
+writing, and modification and configuration notes for various special
+platforms. We assume that libmng is already installed; see the
+INSTALL.README file for instructions on how to install libmng.
+
+Libmng was written to support and promote the MNG specification.
+
+The MNG-1.0 specification should be shortly available at
+<http://www.libpng.org/pub/mng>.
+
+Other information about MNG can be found at the MNG home page,
+<http://www.libpng.org/pub/mng>.
+The latest version of libmng can be found at its own homepage at
+<http://www.libmng.com>.
+
+In most cases the library will not need to be changed.
+For standardization purposes the library tqcontains both a Windows DLL
+and a makefile for building a shared library (SO). The library is
+written in C, but an interface for Borland Delphi is also available.
+
+Libmng has been designed to handle multiple sessions at one time,
+to be easily modifiable, to be portable to the vast majority of
+machines (ANSI, K&R, 32-, and 64-bit) available, and to be easy
+to use.
+
+Libmng uses zlib for its compression and decompression of MNG files.
+Further information about zlib, and the latest version of zlib, can be
+found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
+The zlib compression utility is a general purpose utility that is
+useful for more than MNG/PNG files, and can be used without libmng.
+See the documentation delivered with zlib for more details.
+
+Libmng optionally uses the JPEG library by the Independant JPEG Group
+(IJG). This library is used for the JNG sub-format, which is part of
+the MNG specification, and allows for inclusion of JPEG decoded and
+thus highly compressed (photographic) images.
+Further information about the IJG JPEG library and the latest sources
+can be found at <http://www.ijg.org>.
+
+Libmng can also optionally use the lcms (little CMS) library by
+Marti Maria Saguer. This library provides an excellent color-management
+system (CMS), which gives libmng the ability to provide full
+color-correction for images with the proper color-information encoded.
+Further information and the latest sources can be found at
+<http://www.littlecms.com/>.
+
+Libmng is thread safe, provided the threads are using different
+handles as returned by the initialization call.
+Each thread should have its own handle and thus its own image.
+Libmng does not protect itself against two threads using the
+same instance of a handle.
+
+The libmng.h header file is the single reference needed for programming
+with libmng:
+
+#include <libmng.h>
+
+
+.SH II. Callbacks
+
+Libmng makes extensive use of callback functions. This is meant to
+keep the library as platform-independant and flexible as possible.
+Actually, the first call you will make to the library, already tqcontains
+three parameters you can use to provide callback entry-points.
+
+Most functions must return a mng_bool (boolean). Returning MNG_FALSE
+indicates the library the callback failed in some way and the library
+will immediately return from whatever it was doing back to the
+application. Returning MNG_TRUE indicates there were no problems and
+processing can continue.
+
+Let's step through each of the possible callbacks. The sections on
+reading, displaying and writing will also explain which callbacks are
+needed when and where.
+
+\- mng_ptr mng_memalloc (mng_size_t iLen)
+
+A very basic function which the library uses to allocate a memory-block
+with the given size. A typical implementation would be:
+
+ mng_ptr my_alloc (mng_size_t iLen) {
+ return calloc (1, iSize);
+ }
+
+Note that the library requires you to zero-out the memory-block!!!
+
+\- void mng_memfree (mng_ptr pPtr,
+ mng_size_t iLen)
+
+Counterpart of the previous function. Typically:
+
+ void my_free (mng_ptr pPtr, mng_size_t iLen) {
+ free (pPtr);
+ }
+
+\- mng_bool mng_openstream (mng_handle hHandle)
+
+\- mng_bool mng_closestream (mng_handle hHandle)
+
+These are called by the library just before it starts to process
+(either read or write) a file and just after the processing stops.
+This is the recommended place to do I/O initialization & finalization.
+Whether you do or not, is up to you. The library does not put any
+meaning into the calls. They are simply provided for your convenience.
+
+\- mng_bool mng_readdata (mng_handle hHandle,
+ mng_ptr pBuf,
+ mng_uint32 iBuflen,
+ mng_uint32p pRead)
+
+This function is called when the library needs some more input while
+reading an image. The reading process supports two modes:
+Suspension-mode (SMOD) and non-suspension-mode (NSMOD).
+See mng_set_suspensionmode() for a more detailed description.
+
+In NSMOD, the library requires you to return exactly the amount of bytes
+requested (= iBuflen). Any lesser amount indicates the input file
+is exhausted and the library will return a MNG_UNEXPECTEDEOF errorcode.
+
+In SMOD, you may return a smaller amount of bytes than requested.
+This tells the library it should temporarily wait for more input to
+arrive. The lib will return with MNG_NEEDMOREDATA, and will expect a
+call to mng_read_resume() or mng_display_resume() next, as soon as
+more input-data has arrived.
+
+For NSMOD this function could be as simple as:
+
+ mng_bool my_read (mng_handle hHandle,
+ mng_ptr pBuf,
+ mng_uint32 iBuflen,
+ mng_uint32p pRead) {
+ *pRead = fread (pBuf, 1, iBuflen, myfile);
+ return MNG_TRUE;
+ }
+
+\- mng_bool mng_writedata (mng_handle hHandle,
+ mng_ptr pBuf,
+ mng_uint32 iBuflen,
+ mng_uint32p pWritten)
+
+This function is called during the mng_write() function to actually
+output data to the file. There is no suspension-mode during write,
+so the application must return the exact number of bytes the library
+requests to be written.
+
+A typical implementation could be:
+
+ mng_bool my_write (mng_handle hHandle,
+ mng_ptr pBuf,
+ mng_uint32 iBuflen,
+ mng_uint32p pWritten) {
+ *pWritten = fwrite (pBuf, 1, iBuflen, myfile);
+ return MNG_TRUE;
+ }
+
+\- mng_bool mng_errorproc (mng_handle hHandle,
+ mng_int32 iErrorcode,
+ mng_int8 iSeverity,
+ mng_chunkid iChunkname,
+ mng_uint32 iChunkseq,
+ mng_int32 iExtra1,
+ mng_int32 iExtra2,
+ mng_pchar zErrortext)
+
+This function is called whenever an error is detected inside the
+library. This may be caused by invalid input, callbacks indicating
+failure, or wrongfully calling functions out of place.
+
+If you do not provide this callback the library will still return
+an errorcode from the called function, and the mng_getlasterror()
+function can be used to retrieve the other parameters.
+
+This function is currently only provided for convenience, but may
+at some point be used to indicate certain errors may be acceptable,
+and processing should continue.
+
+\- mng_bool mng_traceproc (mng_handle hHandle,
+ mng_int32 iFuncnr,
+ mng_int32 iFuncseq,
+ mng_pchar zFuncname)
+
+This function is provided to allow a functional analysis of the
+library. This may be useful if you encounter certain errors and
+cannot determine what the problem is.
+
+Almost all functions inside the library will activate this
+callback with an appropriate function-name at the start and end
+of the function. Please note that large images may generate an
+enormous amount of calls.
+
+\- mng_bool mng_processheader (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight)
+
+This function is called once the header information of an input-
+image has been processed. At this point the image dimensions are
+available and also some other properties depending on the type
+of the image. Eg. for a MNG the frame-/layercount, playtime &
+simplicity fields are known.
+
+The primary purpose of this callback is to inform the application
+of the size of the image, and for the application to initialize
+the drawing canvas to be used by the library. This is also a good
+point to set the canvas-style. Eg. mng_set_canvasstyle().
+
+\- mng_bool mng_processtext (mng_handle hHandle,
+ mng_uint8 iType,
+ mng_pchar zKeyword,
+ mng_pchar zText,
+ mng_pchar zLanguage,
+ mng_pchar zTranslation)
+
+This callback is activated for each textual chunk in the input-
+image. These are tEXt, zTXt & iTXt. It may be used to retain
+specific comments for presentation to the user.
+
+\- mng_bool mng_processsave (mng_handle hHandle)
+
+\- mng_bool mng_processseek (mng_handle hHandle,
+ mng_pchar zName)
+
+The purpose of these callbacks is to signal the processing of the
+SAVE & SEEK chunks in a MNG input-file. This may be used in the
+future to specify some special processing. At the moment these
+functions are only provided as a signal.
+
+\- mng_ptr mng_getcanvasline (mng_handle hHandle,
+ mng_uint32 iLinenr)
+
+\- mng_ptr mng_getbkgdline (mng_handle hHandle,
+ mng_uint32 iLinenr)
+
+\- mng_ptr mng_getalphaline (mng_handle hHandle,
+ mng_uint32 iLinenr)
+
+These callbacks are used to access the drawing canvas, background
+canvas and an optional separate alpha-channel canvas. The latter is
+used only with the MNG_CANVAS_RGB8_A8 canvas-style.
+
+If the getbkgdline() callback is not supplied the library will
+composite full or partially transtqparent pixels in the image against
+a specified background color. See mng_set_bgcolor() for more details.
+If a chosen canvas-style includes an alpha-channel, this callback
+is very likely not needed.
+
+The application is responsible for returning a pointer to a line of
+pixels, which should be in the exact format as defined by the call
+to mng_set_canvasstyle() and mng_set_bkgdstyle(), without gaps between
+the representation of each pixel.
+
+\- mng_bool mng_refresh (mng_handle hHandle,
+ mng_uint32 iX,
+ mng_uint32 iY,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight)
+
+This callback is called when the library has drawn a complete frame
+onto the drawing canvas, and it is ready to be displayed.
+The application is responsible for transferring the drawing canvas
+from memory onto the actual output tqdevice.
+
+\- mng_uint32 mng_gettickcount (mng_handle hHandle)
+
+This function should return the number of milliseconds on some internal
+clock. The entire animation timing depends heavily on this function,
+1and the number returned should be as accurate as possible.
+
+\- mng_bool mng_settimer (mng_handle hHandle,
+ mng_uint32 iMsecs)
+
+This callback is activated every time the library requires a "pause".
+Note that the function itself should NOT execute the wait. It should
+simply store the time-field and allow the library to return. Libmng
+will return with the MNG_NEEDTIMERWAIT code, indicating the callback
+was called and it is now time to execute the pause.
+
+After the indicated number of milliseconds have elapsed, the application
+should call mng_display_resume(), to resume the animation as planned.
+
+This method allows for both a real timer or a simple wait command in the
+application. Whichever method you select, both the gettickcount() and
+settimer() callbacks are crucial for proper animation timing.
+
+\- mng_bool mng_processgamma (mng_handle hHandle,
+ mng_uint32 iGamma)
+
+\- mng_bool mng_processchroma (mng_handle hHandle,
+ mng_uint32 iWhitepointx,
+ mng_uint32 iWhitepointy,
+ mng_uint32 iRedx,
+ mng_uint32 iRedy,
+ mng_uint32 iGreenx,
+ mng_uint32 iGreeny,
+ mng_uint32 iBluex,
+ mng_uint32 iBluey)
+
+\- mng_bool mng_processsrgb (mng_handle hHandle,
+ mng_uint8 iRenderingintent)
+
+\- mng_bool mng_processiccp (mng_handle hHandle,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile)
+
+\- mng_bool mng_processarow (mng_handle hHandle,
+ mng_uint32 iRowsamples,
+ mng_bool bIsRGBA16,
+ mng_ptr pRow)
+
+These callbacks are only required when you selected the MNG_APP_CMS
+directive during compilation of the library. See the configuration
+section for more details.
+
+\- mng_bool mng_iteratechunk (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_chunkid iChunkid,
+ mng_uint32 iChunkseq)
+
+This callback is only used for the mng_iterate_chunks() function.
+It is called exactly once for each chunk stored.
+
+
+.SH III. Housekeeping
+
+
+.SS Memory management
+
+The library can use internal memory allocation/deallocation or use
+provided callbacks for its memory management. The choice is made at
+compilation time. See the section on customization for details.
+
+If internal management has been selected, the memory callback functions
+need not be supplied. Even if you do supply them they will not be used.
+The actual code used is similar to the code discussed in the callback
+section:
+
+ pPtr = calloc (1, iSize);
+
+ free (pPtr);
+
+If your compiler does not support these functions, or you wish to monitor
+the library's use of memory for certain reasons, you can choose to
+compile the library with external memory management. In this case the
+memory callback functions MUST be supplied, and should function as if the
+above code was used.
+
+
+.SS Initialization
+
+The basic initialization of the library is short and swift:
+
+ myhandle = mng_initialize (myuserdata, my_alloc,
+ my_free, MNG_NULL);
+ if (myhandle == MNG_NULL)
+ /* process error */;
+
+The first field is an application-only parameter. It is saved in
+libmng's internal structures and available at all times through the
+mng_get_userdata() function. This is especially handy in callback functions
+if your program may be handling multiple files at the same time.
+
+The second and third field supply the library with the memory callback
+1function entry-points. These are described in more detail in the callback
+section and the previous paragraph.
+
+The fourth and last field may be used to supply the library with the
+entry-point of a trace callback function. For regular use you will not
+need this!
+
+The function returns a handle which will be your ticket to MNG-heaven.
+All other functions rely on this handle. It is the single fixed unique
+reference-point between your application and the library.
+
+You should call the initialization function for each image you wish to
+process simultaneously. If you are processing images consecutively, you can
+reset the internal status of the library with the mng_reset() function.
+This function will clear all internal state variables, free any stored
+chunks and/or objects, etc, etc. Your callbacks and other external parameters
+will be retained.
+
+After you successfully received the handle it is time to set the required
+callbacks. The sections on reading, displaying & writing indicate which
+callbacks are required and which are optional.
+To set the callbacks simply do:
+
+ myretcode = mng_setcb_xxxxxx (myhandle, my_xxxxxx);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+Naturally you'd tqreplace the x's with the name of the callback.
+
+
+.SS Cleanup
+
+Once you've gotten hold of that precious mng_handle, you should always,
+and I mean always, call the cleanup function when you're done.
+Just do:
+
+ mng_cleanup (myhandle);
+
+And you're done. There shouldn't be an ounce of memory spilled after
+that call.
+
+Note that if you would like to process multiple files consecutively
+you do not need to do mng_cleanup() / mng_initialize() between each file
+but simply
+
+ myretcode = mng_reset (myhandle);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+will suffice. Saves some time and effort, that.
+
+
+.SS Error handling
+
+From the examples in the previous paragraphs you may have noticed a
+meticulous scheme for error handling. And yes, that's exactly what it is.
+Practically each call simply returns an errorcode, indicating success,
+eg. MNG_NOERROR or failure, anything else but MNG_NEEDMOREDATA and
+MNG_NEEDTIMERWAIT. These latter two will be discussed in more detail in
+their respective fields of interest: the reading section and displaying
+section respectively.
+
+It is the application's responsibility to check the returncode after
+each call. You can call mng_getlasterror() to receive the details of
+the last detected error. This even includes a discriptive error-message
+if you enabled that option during compilation of the library.
+
+Note that after receiving an error it is still possible to call the
+library, but it's also very likely that any following call will fail.
+The only functions deemed to work will be mng_reset() and mng_cleanup().
+Yes, if you abort your program after an error, you should still call
+mng_cleanup().
+
+
+.SH IV. Reading
+
+Reading a MNG, JNG or PNG is fairly easy. It depends slightly on your
+ultimate goal how certain specifics are to be handled, but the basics
+are similar in all cases.
+
+For the read functioins to work you must have compiled the library with
+the MNG_READ_SUPPRT directive. The standard DLL and Shared Library
+have this on by default!
+
+
+.SS Setup
+
+Naturally you must have initialized the library and be the owner of
+a mng_handle. The following callbacks are essential:
+
+ mng_openstream, mng_readdata, mng_closestream
+
+You may optionally define:
+
+ mng_errorproc, mng_traceproc
+ mng_processheader, mng_processtext
+ mng_processsave, mng_processseek
+
+The reading bit will also fail if you are already creating or
+displaying a file. Seems a bit obvious, but I thought I'd mention it,
+just in case.
+
+
+.SS To suspend or not to suspend
+
+There is one choice you need to make before calling the read function.
+Are you in need of suspension-mode or not?
+
+If you're reading from a disk you most certainly do not need
+suspension-mode. Even the oldest and slowest of disks will be fast
+enough for straight reading.
+
+However, if your input comes from a really slow tqdevice, such as a
+dialup-line or the likes, you may opt for suspension-mode. This is done
+by calling
+
+ myretcode = mng_set_suspensionmode (myhandle,
+ MNG_TRUE);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+Suspension-mode will force the library to use special buffering on the
+input. This allows your application to receive data of arbitrarily length
+and return this in the mng_readdata() callback, without disturbing the
+chunk processing routines of the library.
+
+Suspension-mode does require a little extra care in the main logic of the
+1application. The read function may return with MNG_NEEDMOREDATA when the
+mng_readdata() callback returns less data then it needs to process the
+next chunk. This indicates the application to wait for more data to arrive
+and then resume processing by calling mng_read_resume().
+
+
+.SS The read HLAPI
+
+The actual reading is just plain simple. Since all I/O is done
+1outside the library through the callbacks, the library can focus on
+its real task. Understanding, checking and labelling the input data!
+
+All you really need to do is this:
+
+ myretcode = mng_read (myhandle);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+Of course, if you're on suspension-mode the code is a little more
+complicated:
+
+ myretcode = mng_read (myhandle);
+
+ while (myretcode == MNG_NEEDMOREDATA) {
+ /* wait for input-data to arrive */
+ myretcode = mng_read_resume (myhandle);
+ }
+
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+This is rather crude and more sophisticated programming methods may
+dictate another approach. Whatever method you decide on, it should
+act as if the above code was in its place.
+
+There is also the mng_readdisplay() function, but this is discussed
+in the displaying section. It functions pretty much as the mng_read()
+function, but also immediately starts displaying the image.
+mng_read_resume() should be tqreplaced by mng_display_resume() in that
+case!
+
+
+.SS What happens inside
+
+What actually happens inside the library depends on the configuration
+options set during the compilation of the library.
+
+Basically the library will first read the 8-byte file header, to determine
+its validity and the type of image it is about to process. Then it will
+repeatedly read a 4-byte chunk-length and then the remainder of the chunk
+until it either reaches EOF (indicated by the mng_readdata() callback) or
+implicitly decides EOF as it processed the logically last chunk of the
+image.
+
+Applications that require strict conformity and do not allow superfluous
+data after the ending chunk, will need to perform this check in their
+mng_closestream() callback.
+
+Each chunk is then checked on CRC, after which it is handed over to the
+appropriate chunk processing routine. These routines will disect the
+chunk, check the validity of its contents, check its position with respect
+to other chunks, etc, etc.
+
+If everything checks out, the chunk is further processed as follows:
+
+If display support has been selected during compilation, certain pre-display
+initialization will take place.
+
+If chunk-storage support has been selected during compilation, the chunks
+data may be stored in a special internal structure and held for future
+reference.
+
+
+.SS Storing and accessing chunks
+
+One of the compilation options activates support for chunk storage.
+This option may be useful if you want to examine an image. The directive
+is MNG_STORE_CHUNKS. You must also turn on the MNG_ACCESS_CHUNKS
+directive.
+
+The actual storage facility can be turned on or off with the
+mng_set_storechunks() function. If set to MNG_TRUE, chunks will be
+stored as they are read.
+
+At any point you can then call the mng_iterate_chunks() function
+to iterate through the current list of chunks. This function requires
+a callback which is called for each chunk and receives a specific
+chunk-handle. This chunk-handle can be used to call the appropriate
+mng_getchunk_xxxx() function, to access the chunks properties.
+
+A typical implementation may look like this:
+
+ mng_bool my_iteratechunk (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_chunkid iChunkid,
+ mng_uint32 iChunkseq) {
+ switch (iChunkid) {
+ case MNG_UINT_MHDR : { /* process MHDR */;
+ break; }
+ case MNG_UINT_FRAM : { /* process FRAM */;
+ break; }
+
+ ...etc...
+
+ case MNG_UINT_HUH : { /* unknown chunk */;
+ break; }
+ default : { /* duh; forgot one */; }
+ }
+
+ return MNG_TRUE; /* keep'm coming */
+ }
+
+To get to the actual chunk fields of lets say a SHOW chunk you would do:
+
+ mng_bool isempty;
+ mng_uint16 firstid, lastid;
+ mng_uint8 showmode;
+
+ myretcode mng_getchunk_show (hHandle, hChunk,
+ isempty, firstid,
+ lastid, showmode);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+
+.SH V. Displaying
+
+
+.SS Setup
+
+Assuming you have initialized the library and are the owner of
+a mng_handle. The following callbacks are essential:
+
+ mng_getcanvasline, mng_refresh
+ mng_gettickcount, mng_settimer
+
+If you wish to use an application supplied background you must supply:
+
+ mng_getbkgdline
+
+If you wish to use the MNG_CANVAS_RGB8_A8 canvas style you must supply:
+
+ mng_getalphaline
+
+You may optionally define:
+
+ mng_errorproc, mng_traceproc
+ mng_processheader, mng_processtext
+ mng_processsave, mng_processseek
+
+Note that the mng_processheader() callback is optional but will
+be quite significant for proper operation!
+
+Displaying an image will fail if you are creating a file or already
+displaying one. Yes, you can't display it twice!
+
+
+.SS A word on canvas styles
+
+The canvas style describes how your drawing canvas is made up.
+You must set this before the library actually starts drawing, so
+the mng_processheader() callback is a pretty good place for it.
+
+Currently only 8-bit RGB canvas styles are supported, either with
+or without an alpha channel.
+
+If you like to do alpha composition yourself you can select one of
+the canvas styles that include an alpha channel. You can even have
+a separate alpha canvas by selecting the MNG_CANVAS_RGB8_A8 style.
+
+All styles require a compact model. Eg. MNG_CANVAS_BGR8 requires
+your canvas lines in bgrbgrbgr... storage, where each letter
+represents an 8-bit value of the corresponding color, and each
+threesome makes up the values of one(1) pixel.
+
+The library processes a line at a time, so the canvas lines do not
+actually need to be consecutive in memory.
+
+
+.SS Alpha composition and application backgrounds
+
+All Network Graphics can be partially transtqparent. This requires
+special processing if you need to display an image against some
+background. Note that the MNG header (MHDR chunk) tqcontains a
+simplicity field indicating whether transparency information in
+the file is critical or not. This only applies to embedded images,
+which means the full image-frame of the MNG may still contain fully
+transtqparent pixels!
+
+Depending on your needs you can supply a single background color,
+a background canvas or tell the library to return the alpha-channel
+and do alpha composition yourself.
+
+This is different from the BACK chunk in a MNG, or the bKGD chunk
+in an (embedded) PNG or JNG. The BACK chunk indicates an optional or
+mandatory background color and/or image. The bKGD chunk only indicates
+an optional background color. These chunks indicate the Authors
+preferences. They may be absent in which case you need to supply
+some sort of background yourself.
+
+.SS Composing against a background color
+
+This is the easiest method. Call the mng_set_bgcolor() function to
+set the values of the red, green and blue component of your preferred
+background color.
+
+Use one of the canvas styles that do not have an alpha-channel, and
+which matches your output requirements.
+
+.SS Composing against a background canvas
+
+This is somewhat more complicated. You will need to set the
+mng_getbkgdline() callback. This will be called whenever the library
+needs to compose a partially transtqparent line.
+
+This canvas must hold the background against which the image should
+be composed. Its size must match exactly with the image dimensions
+and thus the drawing canvas!
+
+Use one of the canvas styles that do not have an alpha-channel, and
+which matches your output requirements. The canvas style of the
+background canvas may even differ from the drawing canvas. The library's
+composing will still function properly.
+
+.SS Composing within the application
+
+If you have the option in your application to draw a (partially)
+transtqparent canvas to the output tqdevice, this option is preferred.
+
+Select one of the canvas styles that do have an alpha-channel.
+The library will now supply the appropriate alpha information,
+allowing the application to compose the image as it sees fit.
+
+
+.SS Color information and CMS
+
+Network Graphics may, and usually will, contain color-correction
+information. This information is intended to compensate for the
+difference in recording and display tqdevices used.
+
+This document does not address the specifics of color-management.
+See the PNG specification for a more detailed description.
+
+.SS Using little cms by Marti Maria Saguer
+
+This is the easiest method, providing you can compile the lcms package.
+Select the MNG_FULL_CMS directive during compilation, and sit back and
+relax. The library will take care of all color-correction for you.
+
+.SS Using an OS- or application-supplied CMS
+
+If you are so lucky to have access to CMS functionality from within
+your application, you may instruct the library to leave color-correction
+to you.
+
+Select the MNG_APP_CMS directive during compilation of the library.
+You MUST also set the following callbacks:
+
+ mng_processgamma, mng_processchroma,
+ mng_processsrgb, mng_processiccp and
+ mng_processarow
+
+The last callback is called when the library needs you to correct
+an arbitrary line of pixels. The other callbacks are called when
+the corresponding color-information is encountered in the file.
+You must store this information somewhere for use in the
+mng_processarow() callback.
+
+.SS Using gamma-only correction
+
+This isn't a preferred method, but it's better than no correction
+at all. Gamma-only correction will at least compensate for
+gamma-differences between the original recorder and your output tqdevice.
+
+Select the MNG_GAMMA_ONLY directive during compilation
+of the library. Your compiler MUST support fp operations.
+
+.SS No color correction
+
+Ouch. This is really bad. This is the least preferred method,
+but may be necessary if your system cannot use lcms, doesn't
+have its own CMS, and does not allow fp operations, ruling out
+the gamma-only option.
+
+Select the MNG_NO_CMS directive during compilation.
+Images will definitely not be displayed as seen by the Author!!!
+
+
+.SS Animations and timing
+
+Animations require some form of timing support. The library relies
+on two callbacks for this purpose. The mng_gettickcount() and
+mng_settimer() callbacks. mng_gettickcount() is used to determine
+the passing of time in milliseconds since the beginning of the
+animation. This is also used to compensate during suspension-mode
+if you are using the mng_readdisplay() function to read & display
+the file simultaneously.
+
+The callback may return an arbitrary number of milliseconds, but
+this number must increase proportionaly between calls. Most modern
+systems will have some tickcount() function which derives its
+input from an internal clock. The value returned from this function
+is more than adequate for libmng.
+
+The mng_settimer() callback is called when the library determines
+a little "pause" is required before rendering another frame of the
+animation. The pause interval is also expressed in milliseconds.
+Your application should store this value and return immediately.
+The library will then make appropriate arrangements to store its
+internal state and returns to your application with the
+MNG_NEEDTIMERWAIT code.
+
+At that point you should suspend processing and wait the given
+interval. Please use your OS features for this. Do not engage some
+sort of loop. That is real bad programming practice. Most modern
+systems will have some timing functions. A simple wait() function
+may suffice, but this may prevent your applications main-task from
+running, and possibly prevent the actual update of your output tqdevice.
+
+
+.SS The mng_refresh() callback
+
+The mng_refresh() callback is called whenever the library has
+"finished" drawing a new frame onto your canvas, and just before it
+will call the mng_settimer() callback.
+
+This allows you to perform some actions necessary to "refresh" the
+canvas onto your output tqdevice. Please do NOT suspend processing
+inside this callback. This must be handled after the mng_settimer()
+callback!
+
+
+.SS Displaying while reading
+
+This method is preferred if you are reading from a slow input tqdevice
+(such as a dialup-line) and you wish to start displaying something
+as quickly as possible. This functionality is provided mainly for
+browser-type applications but may be appropriate for other
+applications as well.
+
+The method is usually used in unison with the suspension-mode of
+the read module. A typical implementation would look like this:
+
+ /* initiale library and set required callbacks */
+
+ /* activate suspension-mode */
+ myretcode = mng_set_suspensionmode (myhandle,
+ MNG_TRUE);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+ myretcode = mng_readdisplay (myhandle);
+
+ while ((myretcode == MNG_NEEDMOREDATA) ||
+ (myretcode == MNG_NEEDTIMERWAIT)) {
+ if (myretcode == MNG_NEEDMOREDATA)
+ /* wait for more input-data */;
+ else
+ /* wait for timer interval */;
+
+ myretcode = mng_display_resume (myhandle);
+ }
+
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+More advanced programming methods may require a different approach,
+but the final result should function as in the code above.
+
+
+.SS Displaying after reading
+
+This method is used to display a file that was previously read.
+It is primarily meant for viewers with direct file access, such as
+1a local harddisk.
+
+Once you have successfully read the file, all you need to do is:
+
+ myretcode = mng_display (myhandle);
+
+ while (myretcode == MNG_NEEDTIMERWAIT) {
+ /* wait for timer interval */;
+ myretcode = mng_display_resume (myhandle);
+ }
+
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+Again, more advanced programming methods may require a different
+approach, but the final result should function as in the code above.
+
+
+.SS Display manipulation
+
+Several HLAPI functions are provided to allow a user to manipulate
+the normal flow of an animation.
+
+\- mng_display_freeze (mng_handle hHandle)
+
+This will "freeze" the animation in place.
+
+\- mng_display_resume (mng_handle hHandle)
+
+This function can be used to resume a frozen animation, or to force
+the library to advance the animation to the next frame.
+
+\- mng_display_reset (mng_handle hHandle)
+
+This function will "reset" the animation into its pristine state.
+Calling mng_display_resume() afterwards will restart the animation
+from the first frame.
+
+\- mng_display_golayer (mng_handle hHandle,
+ mng_uint32 iLayer)
+
+\- mng_display_goframe (mng_handle hHandle,
+ mng_uint32 iFrame)
+
+\- mng_display_goplaytime (mng_handle hHandle,
+ mng_uint32 iPlaytime)
+
+These three functions can be used to "jump" to a specific layer, frame
+or timeslot in the animation. You must "freeze" the animation before
+using any of these functions.
+
+All above functions may only be called during a timer interval!
+It is the applications responsibility to cleanup any resources with
+respect to the timer wait.
+
+
+.SH VI. Writing
+
+The main focus of the library lies in its displaying capabilites.
+But it does offer writing support as well.
+You can create and write a file, or you can write a file you
+have previously read, providing the storage of chunks was enabled
+and active.
+
+For this to work you must have compiled the library with the
+MNG_WRITE_SUPPO1RT and MNG_ACCESS_CHUNKS directives. The standard DLL and
+Shared Library have this on by default!
+
+
+.SS Setup
+
+As always you must have initialized the library and be the owner of
+a mng_handle. The following callbacks are essential:
+
+ mng_openstream, mng_writedata, mng_closestream
+
+You can optionally define:
+
+ mng_errorproc, mng_traceproc
+
+The creation and writing functions will fail if you are in the middle
+of reading, creating or writing a file.
+
+
+.SS Creating a new file
+
+To start a new file the library must be in its initial state.
+First you need to tell the library your intentions:
+
+ myretcode = mng_create (myhandle);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+After that you start adding the appropriate chunks:
+
+ myretcode = mng_put1chunk_mhdr (myhandle, ...);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+And so on, and so forth. Note that the library will automatically signal
+the logical end of the file by the ending chunk. Also the first chunk
+will indicate the library the filetype (eg. PNG, JNG or MNG) and force
+the proper signature when writing the file.
+
+The code above can be simplified, as you can always get the last errorcode
+by using the mng_getlasterror() function:
+
+ if ( (mng_putchunk_xxxx (myhandle, ...)) or
+ (mng_putchunk_xxxx (myhandle, ...)) or
+ ...etc... )
+ /* process error */;
+
+Please note that you must have a pretty good understanding of the chunk
+specification. Unlike the read functions, there are virtually no checks,
+so it is quite possible to write completely wrong files.
+It is a good practice to read back your file into the library to verify
+its integrity.
+
+Once you've got all the chunks added, all you do is:
+
+ myretcode mng_write (myhandle);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+And presto. You're done. The real work is of course carried out in
+your callbacks. Note that this is a single operation as opposed to
+the read & display functions that may return with MNG_NEEDMOREDATA
+and/or MNG_NEEDTIMERWAIT. The write function just does the job, and
+only returns after it's finished or if it encounters some
+unrecoverable error.
+
+
+.SS Writing a previously read file
+
+If you have already successfully read a file, you can use the library to
+write it out as a copy or something. You MUST have compiled the library
+with the MNG_STORE_CHUNKS directive, and you must have done
+mng_set_storechunks (myhandle, MNG_TRUE).
+
+This doesn't require the MNG_ACCESS_CHUNKS directive, unless you want
+to fiddle with the chunks as well.
+
+Again all you need to do is:
+
+ myretcode mng_write (myhandle);
+ if (myretcode != MNG_NOERROR)
+ /* process error */;
+
+
+.SH VII. Modifying/Customizing libmng:
+
+not finished yet
+
+.SS Compilation directives
+
+not finished yet
+
+.SS Platform dependant modification
+
+not finished yet
+
+.SH "SEE ALSO"
+.IR mng(5), jng(5), png(5), libpng(3)
+
+.LP
+libmng :
+.IP
+.br
+http://www.libmng.com
+
+.LP
+zlib :
+.IP
+.br
+http://www.info-zip.org/pub/infozip/zlib/
+
+.LP
+IJG JPEG library :
+.IP
+.br
+http://www.ijg.org
+
+.LP
+lcms (little CMS) by Marti Maria Saguer :
+.IP
+.br
+http://www.littlecms.com/
+
+.LP
+MNG specification:
+.IP
+.br
+http://www.libpng.org/pub/mng
+
+.LP
+In the case of any inconsistency between the MNG specification
+and this library, the specification takes precedence.
+
+
+.SH AUTHORS
+This man page: Gerard Juyn
+<gerard@libmng.com>
+
+The contributing authors would like to thank all those who helped
+with testing, bug fixes, and patience. This wouldn't have been
+possible without all of you!!!
+
+
+.SH COPYRIGHT NOTICE:
+
+Copyright (c) 2000 Gerard Juyn
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Gerard Juyn
+ Tim Rowley
+
+The MNG Library is supplied "AS IS". The Contributing Authors
+disclaim all warranties, expressed or implied, including, without
+limitation, the warranties of merchantability and of fitness for any
+purpose. The Contributing Authors assume no liability for direct,
+indirect, incidental, special, exemplary, or consequential damages,
+which may result from the use of the MNG Library, even if advised of
+the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented;
+you must not claim that you wrote the original software.
+
+2. Altered versions must be plainly marked as such and must not be
+misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any source
+or altered source distribution.
+
+The Contributing Authors specifically permit, without fee, and
+encourage the use of this source code as a component to supporting
+the MNG and JNG file format in commercial products. If you use this
+source code in a product, acknowledgment would be highly appreciated.
+
+.SH Remarks
+
+Parts of this software have been adapted from the libpng library.
+Although this library supports all features from the PNG specification
+(as MNG descends from it) it does not require the libpng library.
+It does require the zlib library and optionally the IJG JPEG library,
+and/or the "little-cms" library by Marti Maria Saguer (depending on the
+inclusion of support for JNG and Full-Color-Management respectively.
+
+This library's function is primarily to read and display MNG
+animations. It is not meant as a full-featured image-editing
+component! It does however offer creation and editing functionality
+at the chunk level. (future modifications may include some more
+support for creation and or editing)
+
+.\" end of man page
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/doc/man/mng.5 b/tqtinterface/qt4/src/3rdparty/libmng/doc/man/mng.5
new file mode 100644
index 0000000..e020614
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/doc/man/mng.5
@@ -0,0 +1,42 @@
+.TH MNG 5 "July 25, 2000"
+.SH NAME
+mng \- Multiple-image Network Graphics (MNG) format
+.SH DESCRIPTION
+MNG (Multiple-image Network Graphics) is the animation extension of the
+popular PNG image-format. PNG (Portable Network Graphics) is an
+extensible file format for the lossless, portable, well-compressed
+storage of raster images.
+.br
+
+MNG has advanced animation features which make it very useful as a full
+tqreplacement for GIF animations. These features allow animations that
+are impossible with GIF or result in much smaller files as GIF.
+
+As MNG builds on the same structure as PNG, it is robust, extensible and
+free of patents. It retains the same clever file integrity checks as in PNG.
+
+MNG also embraces the lossy JPEG image-format in a sub-format named JNG,
+which allows for alpha-transparency and color-correction on highly
+compressed (photographic) images.
+
+.SH "SEE ALSO"
+.IR png(5), jng(5), libmng(3), libpng(3), zlib(3), deflate(5),
+.IR zlib(5), jpeg(5)
+.LP
+MNG 0.97 draft 70, Februari 2000:
+.IP
+.br
+http://www.libpng.org/pub/mng
+.SH AUTHORS
+This man page: Gerard Juyn
+.LP
+Multiple-image Network Graphics (MNG) Specification Version 0.97 (Februari 27, 2000):
+Glenn Randers-Pehrson and others (png-list@ccrc.wustl.edu).
+.LP
+
+.SH COPYRIGHT NOTICE
+The MNG-0.97 specification is copyright (c) 1998,1999,2000 Glenn Randers-Pehrson.
+See the specification for conditions of use and distribution.
+.LP
+.\" end of man page
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/doc/rpm/libmng-1.0.4-rhconf.patch b/tqtinterface/qt4/src/3rdparty/libmng/doc/rpm/libmng-1.0.4-rhconf.patch
new file mode 100644
index 0000000..a73b79d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/doc/rpm/libmng-1.0.4-rhconf.patch
@@ -0,0 +1,38 @@
+--- libmng/makefiles/makefile.linux.orig Sat Jul 1 15:10:35 2000
++++ libmng/makefiles/makefile.linux Sat Jul 1 15:14:52 2000
+@@ -13,19 +13,19 @@
+ OPTIONS = -DMNG_BUILD_SO
+
+ # where "make install" puts libmng.a,libmng.so*,libmng.h,libmng_conf.h,libmng_types.h
+-prefix=/usr/local
++prefix=/usr
+
+ # Where the zlib library and include files are located
+-ZLIBLIB=../zlib
+-ZLIBINC=../zlib
++ZLIBLIB=/usr/lib
++ZLIBINC=/usr/include
+
+ # Where the jpeg library and include files are located
+-JPEGLIB=../jpgsrc
+-JPEGINC=../jpgsrc
++JPEGLIB=/usr/lib
++JPEGINC=/usr/include
+
+ # Where the lcms library and include files are located
+-LCMSLIB=../lcms/lib
+-LCMSINC=../lcms/source
++LCMSLIB=/usr/lib
++LCMSINC=/usr/include
+
+ ALIGN=
+ # for i386:
+@@ -37,7 +37,7 @@
+
+ # for pgcc version 2.95.1, -O3 is buggy; don't use it.
+
+-CFLAGS=-I$(ZLIBINC) -I$(JPEGINC) -I$(LCMSINC) -Wall -O3 -funroll-loops \
++CFLAGS=-I$(ZLIBINC) -I$(JPEGINC) -I$(LCMSINC) -Wall $(RPM_OPT_FLAGS) \
+ $(OPTIONS) $(ALIGN) # $(WARNMORE) -g
+ LDFLAGS=-L. -Wl,-rpath,. \
+ -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/doc/rpm/libmng.spec b/tqtinterface/qt4/src/3rdparty/libmng/doc/rpm/libmng.spec
new file mode 100644
index 0000000..2e49d52
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/doc/rpm/libmng.spec
@@ -0,0 +1,97 @@
+Summary: A library of functions for manipulating MNG format files.
+Name: libmng
+Version: 1.0.4
+Release: 2.1
+Copyright: AS IS
+Group: System Environment/Libraries
+Source0: libmng-%{PACKAGE_VERSION}.tar.gz
+Patch: libmng-%{PACKAGE_VERSION}-rhconf.patch
+URL: http://www.libmng.com/
+BuildRoot: /var/tmp/libmng-root
+BuildPrereq: libjpeg-devel, zlib-devel, lcms-devel
+
+%description
+libmng - library for reading, writing, displaying and examing
+Multiple-Image Network Graphics. MNG is the animation extension to the
+popular PNG image-format.
+
+%package devel
+Summary: Development tools for programs to manipulate MNG format files.
+Group: Development/Libraries
+Requires: libmng = %{PACKAGE_VERSION}
+%description devel
+The libmng-devel package tqcontains the header files and static
+libraries necessary for developing programs using the MNG
+(Multiple-Image Network Graphics) library.
+
+If you want to develop programs which will manipulate MNG image format
+files, you should install libmng-devel. You'll also need to install
+the libmng package.
+
+%changelog
+* Sun Jun 23 2002 Gerard Juyn <gerard@libmng.com>
+- updated to 1.0.4
+
+* Mon Sep 18 2001 Gerard Juyn <gerard@libmng.com>
+- updated to 1.0.3
+
+* Sat Jul 7 2001 Gerard Juyn <gerard@libmng.com>
+- updated to 1.0.2
+
+* Wed May 2 2001 Gerard Juyn <gerard@libmng.com>
+- updated to 1.0.1
+
+* Mon Feb 5 2001 Gerard Juyn <gerard@libmng.com>
+- updated to 1.0.0
+
+* Fri Jan 19 2001 Gerard Juyn <gerard@libmng.com>
+- updated to 0.9.4
+
+* Sat Oct 28 2000 Gerard Juyn <gerard@libmng.com>
+- updated to 0.9.3
+
+* Tue Aug 15 2000 MATSUURA Takanori <t-matsuu@protein.osaka-u.ac.jp>
+- based on libmng-0.9.2/doc/rpm/libmng.spec
+- use %%configure and %%makeinstall
+
+* Sat Aug 5 2000 Gerard Juyn <gerard@libmng.com>
+- updated to 0.9.2
+
+* Wed Jul 26 2000 Gerard Juyn <gerard@libmng.com>
+- updated to 0.9.1
+
+* Sat Jul 1 2000 MATSUURA Takanori <t-matsuu@protein.osaka-u.ac.jp>
+- updated to 0.9.0
+
+* Sat Jun 24 2000 MATSUURA Takanori <t-matsuu@protein.osaka-u.ac.jp>
+- 1st release for RPM
+
+%prep
+%setup
+%configure
+
+%build
+make
+
+%install
+rm -rf $RPM_BUILD_ROOT
+%makeinstall
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root)
+%doc CHANGES LICENSE README doc
+/usr/lib/libmng.so.*
+
+%files devel
+%defattr(-,root,root)
+/usr/include/*
+/usr/lib/libmng.a
+/usr/lib/libmng.so
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/install-sh b/tqtinterface/qt4/src/3rdparty/libmng/install-sh
new file mode 100755
index 0000000..81d9b2c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/install-sh
@@ -0,0 +1,251 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5 (mit/util/scripts/install.sh).
+#
+# Copyright 1991 by the Massachusetts Institute of Technology
+#
+# Permission to use, copy, modify, distribute, and sell this software and its
+# documentation for any purpose is hereby granted without fee, provided that
+# the above copyright notice appear in all copies and that both that
+# copyright notice and this permission notice appear in supporting
+# documentation, and that the name of M.I.T. not be used in advertising or
+# publicity pertaining to distribution of the software without specific,
+# written prior permission. M.I.T. makes no representations about the
+# suitability of this software for any purpose. It is provided "as is"
+# without express or implied warranty.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch. It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+transformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ chmodcmd=""
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) tqcontains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng.h
new file mode 100644
index 0000000..2ebfce8
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng.h
@@ -0,0 +1,2515 @@
+/* ************************************************************************** */
+/* * * */
+/* * COPYRIGHT NOTICE: * */
+/* * * */
+/* * Copyright (c) 2000-2002 Gerard Juyn (gerard@libmng.com) * */
+/* * [You may insert additional notices after this sentence if you modify * */
+/* * this source] * */
+/* * * */
+/* * For the purposes of this copyright and license, "Contributing Authors" * */
+/* * is defined as the following set of individuals: * */
+/* * * */
+/* * Gerard Juyn (gerard@libmng.com) * */
+/* * * */
+/* * The MNG Library is supplied "AS IS". The Contributing Authors * */
+/* * disclaim all warranties, expressed or implied, including, without * */
+/* * limitation, the warranties of merchantability and of fitness for any * */
+/* * purpose. The Contributing Authors assume no liability for direct, * */
+/* * indirect, incidental, special, exemplary, or consequential damages, * */
+/* * which may result from the use of the MNG Library, even if advised of * */
+/* * the possibility of such damage. * */
+/* * * */
+/* * Permission is hereby granted to use, copy, modify, and distribute this * */
+/* * source code, or portions hereof, for any purpose, without fee, subject * */
+/* * to the following restrictions: * */
+/* * * */
+/* * 1. The origin of this source code must not be misrepresented; * */
+/* * you must not claim that you wrote the original software. * */
+/* * * */
+/* * 2. Altered versions must be plainly marked as such and must not be * */
+/* * misrepresented as being the original source. * */
+/* * * */
+/* * 3. This Copyright notice may not be removed or altered from any source * */
+/* * or altered source distribution. * */
+/* * * */
+/* * The Contributing Authors specifically permit, without fee, and * */
+/* * encourage the use of this source code as a component to supporting * */
+/* * the MNG and JNG file format in commercial products. If you use this * */
+/* * source code in a product, acknowledgment would be highly appreciated. * */
+/* * * */
+/* ************************************************************************** */
+/* * * */
+/* * Parts of this software have been adapted from the libpng package. * */
+/* * Although this library supports all features from the PNG specification * */
+/* * (as MNG descends from it) it does not require the libpng package. * */
+/* * It does require the zlib library and optionally the IJG jpeg library, * */
+/* * and/or the "little-cms" library by Marti Maria (depending on the * */
+/* * inclusion of support for JNG and Full-Color-Management respectively. * */
+/* * * */
+/* * This library's function is primarily to read and display MNG * */
+/* * animations. It is not meant as a full-featured image-editing * */
+/* * component! It does however offer creation and editing functionality * */
+/* * at the chunk level. * */
+/* * (future modifications may include some more support for creation * */
+/* * and or editing) * */
+/* * * */
+/* ************************************************************************** */
+
+/* ************************************************************************** */
+/* * * */
+/* * Version numbering * */
+/* * * */
+/* * X.Y.Z : X = release (0 = initial build) * */
+/* * Y = major version (uneven = test; even = production) * */
+/* * Z = minor version (bugfixes; 2 is older than 10) * */
+/* * * */
+/* * production versions only appear when a test-version is extensively * */
+/* * tested and found stable or for intermediate bug-fixes (recognized by * */
+/* * a change in the Z number) * */
+/* * * */
+/* * x.1.x = test version * */
+/* * x.2.x = production version * */
+/* * x.3.x = test version * */
+/* * x.4.x = production version * */
+/* * etc. * */
+/* * * */
+/* ************************************************************************** */
+/* * * */
+/* * Identifier naming conventions throughout this library * */
+/* * * */
+/* * iXxxx = an integer * */
+/* * dXxxx = a float * */
+/* * pXxxx = a pointer * */
+/* * bXxxx = a boolean * */
+/* * eXxxx = an enumeration * */
+/* * hXxxx = a handle * */
+/* * zXxxx = a zero-terminated string (pchar) * */
+/* * fXxxx = a pointer to a function (callback) * */
+/* * aXxxx = an array * */
+/* * sXxxx = a structure * */
+/* * * */
+/* * Macros & defines are in all uppercase. * */
+/* * Functions & typedefs in all lowercase. * */
+/* * Exported stuff is prefixed with MNG_ or mng_ respectively. * */
+/* * * */
+/* * (I may have missed a couple; don't hesitate to let me know!) * */
+/* * * */
+/* ************************************************************************** */
+
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng.h copyright (c) 2000-2002 G.Juyn * */
+/* * version : 1.0.4 * */
+/* * * */
+/* * purpose : main application interface * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : The main application interface. An application should not * */
+/* * need access to any of the other modules! * */
+/* * * */
+/* * changes : 0.5.1 - 05/06/2000 - G.Juyn * */
+/* * - changed chunk iteration function * */
+/* * 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - added chunk access functions * */
+/* * - added version control constants & functions * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added set_outputprofile2 & set_srgbprofile2 * */
+/* * - added empty-chunk put-routines * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - added version_dll & VERSION_DLL (for consistency) * */
+/* * - added version control explanatory text & samples * */
+/* * 0.5.1 - 05/15/2000 - G.Juyn * */
+/* * - added getimgdata & putimgdata functions * */
+/* * * */
+/* * 0.5.2 - 05/16/2000 - G.Juyn * */
+/* * - changed the version parameters (obviously) * */
+/* * 0.5.2 - 05/18/2000 - G.Juyn * */
+/* * - complimented constants for chunk-property values * */
+/* * 0.5.2 - 05/23/2000 - G.Juyn * */
+/* * - fixed MNG_UINT_pHYg value * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - added support for get/set default zlib/IJG parms * */
+/* * 0.5.2 - 06/02/2000 - G.Juyn * */
+/* * - added MNG_BIGENDIAN_SUPPORT (contributed by Tim Rowley) * */
+/* * - separated configuration-options into "mng_conf.h" * */
+/* * - added RGB8_A8 canvasstyle * */
+/* * - added getalphaline callback for RGB8_A8 canvasstyle * */
+/* * 0.5.2 - 06/06/2000 - G.Juyn * */
+/* * - moved errorcodes from "mng_error.h" * */
+/* * - added mng_read_resume function to support * */
+/* * read-suspension * */
+/* * * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - changed the version parameters (obviously) * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added get/set for speedtype to facilitate testing * */
+/* * - added get for imagelevel during processtext callback * */
+/* * 0.5.3 - 06/24/2000 - G.Juyn * */
+/* * - fixed inclusion of IJG read/write code * */
+/* * 0.5.3 - 06/26/2000 - G.Juyn * */
+/* * - changed userdata variable to mng_ptr * */
+/* * * */
+/* * 0.9.0 - 06/30/2000 - G.Juyn * */
+/* * - changed refresh parameters to 'x,y,width,height' * */
+/* * * */
+/* * 0.9.1 - 07/06/2000 - G.Juyn * */
+/* * - added MNG_NEEDTIMERWAIT errorcode * */
+/* * - changed comments to indicate modified behavior for * */
+/* * timer & suspension breaks * */
+/* * 0.9.1 - 07/08/2000 - G.Juyn * */
+/* * - added get routines for internal display variables * */
+/* * - added get/set routines for suspensionmode variable * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - added callbacks for SAVE/SEEK processing * */
+/* * - added get/set routines for sectionbreak variable * */
+/* * - added NEEDSECTIONWAIT errorcode * */
+/* * 0.9.1 - 07/19/2000 - G.Juyn * */
+/* * - added function to set frame-/layer-count & playtime * */
+/* * - added errorcode for updatemngheader if not a MNG * */
+/* * * */
+/* * 0.9.2 - 07/31/2000 - G.Juyn * */
+/* * - fixed problem with trace-functions improperly wrapped * */
+/* * - added status_xxxx functions * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * - added function to set simplicity field * */
+/* * * */
+/* * 0.9.3 - 08/09/2000 - G.Juyn * */
+/* * - added check for simplicity-bits in MHDR * */
+/* * 0.9.3 - 08/12/2000 - G.Juyn * */
+/* * - added workaround for faulty PhotoShop iCCP chunk * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * 0.9.3 - 10/10/2000 - G.Juyn * */
+/* * - added support for alpha-depth prediction * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - fixed processing of unknown critical chunks * */
+/* * - removed test-MaGN * */
+/* * - added PNG/MNG spec version indicators * */
+/* * - added support for nEED * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added functions to retrieve PNG/JNG specific header-info * */
+/* * - added JDAA chunk * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - added callback to process non-critical unknown chunks * */
+/* * 0.9.3 - 10/20/2000 - G.Juyn * */
+/* * - added errocode for delayed delta-processing * */
+/* * - added get/set for bKGD preference setting * */
+/* * 0.9.3 - 10/21/2000 - G.Juyn * */
+/* * - added get function for interlace/progressive display * */
+/* * * */
+/* * 0.9.4 - 01/18/2001 - G.Juyn * */
+/* * - added errorcode for MAGN methods * */
+/* * - removed test filter-methods 1 & 65 * */
+/* * * */
+/* * 1.0.0 - 02/05/2001 - G.Juyn * */
+/* * - version numbers (obviously) * */
+/* * * */
+/* * 1.0.1 - 02/08/2001 - G.Juyn * */
+/* * - added MEND processing callback * */
+/* * 1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly) * */
+/* * - added BGRA8 canvas with premultiplied alpha * */
+/* * 1.0.1 - 05/02/2001 - G.Juyn * */
+/* * - added "default" sRGB generation (Thanks Marti!) * */
+/* * * */
+/* * 1.0.2 - 06/23/2001 - G.Juyn * */
+/* * - added optimization option for MNG-video playback * */
+/* * - added processterm callback * */
+/* * 1.0.2 - 06/25/2001 - G.Juyn * */
+/* * - added late binding errorcode (not used internally) * */
+/* * - added option to turn off progressive refresh * */
+/* * * */
+/* * 1.0.3 - 08/06/2001 - G.Juyn * */
+/* * - added get function for last processed BACK chunk * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_h_
+#define _libmng_h_
+
+/* ************************************************************************** */
+
+#include "libmng_conf.h" /* user-specific configuration options */
+
+/* ************************************************************************** */
+
+#define MNG_CHECK_BAD_ICCP /* let's catch that sucker !!! */
+
+#ifdef MNG_SUPPORT_READ /* dependencies based on user-configuration */
+#define MNG_INCLUDE_READ_PROCS
+#endif
+
+#ifdef MNG_SUPPORT_WRITE
+#define MNG_INCLUDE_WRITE_PROCS
+#endif
+
+#ifdef MNG_SUPPORT_DISPLAY
+#define MNG_INCLUDE_FILTERS
+#define MNG_INCLUDE_INTERLACE
+#define MNG_INCLUDE_OBJECTS
+#define MNG_INCLUDE_DISPLAY_PROCS
+#define MNG_INCLUDE_TIMING_PROCS
+#define MNG_INCLUDE_ZLIB
+#endif
+
+#ifdef MNG_STORE_CHUNKS
+#define MNG_INCLUDE_ZLIB
+#endif
+
+#ifdef MNG_SUPPORT_IJG6B
+#define MNG_INCLUDE_JNG
+#define MNG_INCLUDE_IJG6B
+#define MNG_USE_SETJMP
+#endif
+
+#ifdef MNG_INCLUDE_JNG
+#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_ACCESS_CHUNKS)
+#define MNG_INCLUDE_JNG_READ
+#endif
+#if defined(MNG_SUPPORT_WRITE) || defined(MNG_ACCESS_CHUNKS)
+#define MNG_INCLUDE_JNG_WRITE
+#endif
+#endif
+
+#ifdef MNG_FULL_CMS
+#define MNG_INCLUDE_LCMS
+#endif
+
+#ifdef MNG_AUTO_DITHER
+#define MNG_INCLUDE_DITHERING
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+#define MNG_INCLUDE_TRACE_PROCS
+#ifdef MNG_TRACE_TELLTALE
+#define MNG_INCLUDE_TRACE_STRINGS
+#endif
+#endif
+
+#ifdef MNG_ERROR_TELLTALE
+#define MNG_INCLUDE_ERROR_STRINGS
+#endif
+
+/* ************************************************************************** */
+
+#include "libmng_types.h" /* platform-specific definitions
+ and other assorted stuff */
+
+/* ************************************************************************** */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Versioning control * */
+/* * * */
+/* * version_so and version_dll will NOT reflect version_major; * */
+/* * these will only change for binary incompatible changes (which will * */
+/* * hopefully never occur) * */
+/* * note: they will be set to 1 on the first public release !!! * */
+/* * * */
+/* * first public release: * */
+/* * #define MNG_VERSION_TEXT "1.0.0" * */
+/* * #define MNG_VERSION_SO 1 eg. libmng.so.1 * */
+/* * #define MNG_VERSION_DLL 1 eg. libmng.dll * */
+/* * #define MNG_VERSION_MAJOR 1 * */
+/* * #define MNG_VERSION_MINOR 0 * */
+/* * #define MNG_VERSION_RELEASE 0 * */
+/* * * */
+/* * bug fix & cosmetics : * */
+/* * #define MNG_VERSION_TEXT "1.0.1" * */
+/* * #define MNG_VERSION_SO 1 eg. libmng.so.1 * */
+/* * #define MNG_VERSION_DLL 1 eg. libmng.dll * */
+/* * #define MNG_VERSION_MAJOR 1 * */
+/* * #define MNG_VERSION_MINOR 0 * */
+/* * #define MNG_VERSION_RELEASE 1 * */
+/* * * */
+/* * feature change : * */
+/* * #define MNG_VERSION_TEXT "1.2.0" * */
+/* * #define MNG_VERSION_SO 1 eg. libmng.so.1 * */
+/* * #define MNG_VERSION_DLL 1 eg. libmng.dll * */
+/* * #define MNG_VERSION_MAJOR 1 * */
+/* * #define MNG_VERSION_MINOR 2 * */
+/* * #define MNG_VERSION_RELEASE 0 * */
+/* * * */
+/* * major rewrite (still binary compatible) : * */
+/* * #define MNG_VERSION_TEXT "2.0.0" * */
+/* * #define MNG_VERSION_SO 1 eg. libmng.so.1 * */
+/* * #define MNG_VERSION_DLL 1 eg. libmng.dll * */
+/* * #define MNG_VERSION_MAJOR 2 * */
+/* * #define MNG_VERSION_MINOR 0 * */
+/* * #define MNG_VERSION_RELEASE 0 * */
+/* * * */
+/* * binary incompatible change: * */
+/* * #define MNG_VERSION_TEXT "13.0.0" * */
+/* * #define MNG_VERSION_SO 2 eg. libmng.so.2 * */
+/* * #define MNG_VERSION_DLL 2 eg. libmng2.dll * */
+/* * #define MNG_VERSION_MAJOR 13 * */
+/* * #define MNG_VERSION_MINOR 0 * */
+/* * #define MNG_VERSION_RELEASE 0 * */
+/* * * */
+/* * note that version_so & version_dll will always remain equal so it * */
+/* * doesn't matter which one is called to do version-checking; they are * */
+/* * just provided for their target platform * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_VERSION_TEXT "1.0.4"
+#define MNG_VERSION_SO 1 /* eg. libmng.so.1 */
+#define MNG_VERSION_DLL 1 /* but: libmng.dll (!) */
+#define MNG_VERSION_MAJOR 1
+#define MNG_VERSION_MINOR 0
+#define MNG_VERSION_RELEASE 4
+
+MNG_EXT mng_pchar MNG_DECL mng_version_text (void);
+MNG_EXT mng_uint8 MNG_DECL mng_version_so (void);
+MNG_EXT mng_uint8 MNG_DECL mng_version_dll (void);
+MNG_EXT mng_uint8 MNG_DECL mng_version_major (void);
+MNG_EXT mng_uint8 MNG_DECL mng_version_minor (void);
+MNG_EXT mng_uint8 MNG_DECL mng_version_release (void);
+
+/* ************************************************************************** */
+/* * * */
+/* * MNG/PNG specification level conformance * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_PNG_VERSION "1.2"
+#define MNG_PNG_VERSION_MAJ 1
+#define MNG_PNG_VERSION_MIN 2
+
+#define MNG_MNG_VERSION "1.0"
+#define MNG_MNG_VERSION_MAJ 1
+#define MNG_MNG_VERSION_MIN 0
+#define MNG_MNG_DRAFT 99 /* deprecated;
+ only used for nEED "MNG DRAFT nn" */
+
+/* ************************************************************************** */
+/* * * */
+/* * High-level application functions * */
+/* * * */
+/* ************************************************************************** */
+
+/* library initialization function */
+/* must be the first called before anything can be done at all */
+/* initializes internal datastructure(s) */
+MNG_EXT mng_handle MNG_DECL mng_initialize (mng_ptr pUserdata,
+ mng_memalloc fMemalloc,
+ mng_memfree fMemfree,
+ mng_traceproc fTraceproc);
+
+/* library reset function */
+/* can be used to re-initialize the library, so another image can be
+ processed. there's absolutely no harm in calling it, even when it's not
+ really necessary */
+MNG_EXT mng_retcode MNG_DECL mng_reset (mng_handle hHandle);
+
+/* library cleanup function */
+/* must be the last called to clean up internal datastructure(s) */
+MNG_EXT mng_retcode MNG_DECL mng_cleanup (mng_handle* hHandle);
+
+/* high-level read functions */
+/* use mng_read if you simply want to read a Network Graphic */
+/* mng_read_resume is used in I/O-read-suspension scenarios, where the
+ "readdata" callback may return FALSE & length=0 indicating it's buffer is
+ depleted or too short to supply the required bytes, and the buffer needs
+ to be refilled; libmng will return the errorcode MNG_NEEDMOREDATA telling
+ the app to refill it's read-buffer after which it must call mng_read_resume
+ (or mng_display_resume if it also displaying the image simultaneously) */
+#ifdef MNG_SUPPORT_READ
+MNG_EXT mng_retcode MNG_DECL mng_read (mng_handle hHandle);
+MNG_EXT mng_retcode MNG_DECL mng_read_resume (mng_handle hHandle);
+#endif
+
+/* high-level write & create functions */
+/* use this if you want to write a previously read Network Graphic or
+ if you want to create a new graphic and write it */
+/* to write a previously read graphic you must have defined MNG_STORE_CHUNKS */
+/* to create a new graphic you'll also need access to the chunks
+ (eg. #define MNG_ACCESS_CHUNKS !) */
+#ifdef MNG_SUPPORT_WRITE
+MNG_EXT mng_retcode MNG_DECL mng_write (mng_handle hHandle);
+MNG_EXT mng_retcode MNG_DECL mng_create (mng_handle hHandle);
+#endif
+
+/* high-level display functions */
+/* use these to display a previously read or created graphic or
+ to read & display a graphic simultaneously */
+/* mng_display_resume should be called after a timer-interval
+ expires that was set through the settimer-callback, after a
+ read suspension-break, or, to resume an animation after a call
+ to mng_display_freeze/mng_display_reset */
+/* mng_display_freeze thru mng_display_gotime can be used to influence
+ the display of an image, BUT ONLY if it has been completely read! */
+#ifdef MNG_SUPPORT_DISPLAY
+#ifdef MNG_SUPPORT_READ
+MNG_EXT mng_retcode MNG_DECL mng_readdisplay (mng_handle hHandle);
+#endif
+MNG_EXT mng_retcode MNG_DECL mng_display (mng_handle hHandle);
+MNG_EXT mng_retcode MNG_DECL mng_display_resume (mng_handle hHandle);
+MNG_EXT mng_retcode MNG_DECL mng_display_freeze (mng_handle hHandle);
+MNG_EXT mng_retcode MNG_DECL mng_display_reset (mng_handle hHandle);
+MNG_EXT mng_retcode MNG_DECL mng_display_goframe (mng_handle hHandle,
+ mng_uint32 iFramenr);
+MNG_EXT mng_retcode MNG_DECL mng_display_golayer (mng_handle hHandle,
+ mng_uint32 iLayernr);
+MNG_EXT mng_retcode MNG_DECL mng_display_gotime (mng_handle hHandle,
+ mng_uint32 iPlaytime);
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* error reporting function */
+/* use this if you need more detailed info on the last error */
+/* iExtra1 & iExtra2 may contain errorcodes from zlib, jpeg, etc... */
+/* zErrortext will only be filled if you #define MNG_ERROR_TELLTALE */
+MNG_EXT mng_retcode MNG_DECL mng_getlasterror (mng_handle hHandle,
+ mng_int8* iSeverity,
+ mng_chunkid* iChunkname,
+ mng_uint32* iChunkseq,
+ mng_int32* iExtra1,
+ mng_int32* iExtra2,
+ mng_pchar* zErrortext);
+
+/* ************************************************************************** */
+/* * * */
+/* * Callback set functions * */
+/* * * */
+/* ************************************************************************** */
+
+/* memory callbacks */
+/* called to allocate and release internal datastructures */
+#ifndef MNG_INTERNAL_MEMMNGMT
+MNG_EXT mng_retcode MNG_DECL mng_setcb_memalloc (mng_handle hHandle,
+ mng_memalloc fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_memfree (mng_handle hHandle,
+ mng_memfree fProc);
+#endif /* MNG_INTERNAL_MEMMNGMT */
+
+/* open- & close-stream callbacks */
+/* called to open & close streams for input or output */
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+MNG_EXT mng_retcode MNG_DECL mng_setcb_openstream (mng_handle hHandle,
+ mng_openstream fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_closestream (mng_handle hHandle,
+ mng_closestream fProc);
+#endif
+
+/* read callback */
+/* called to get data from the inputstream */
+#ifdef MNG_SUPPORT_READ
+MNG_EXT mng_retcode MNG_DECL mng_setcb_readdata (mng_handle hHandle,
+ mng_readdata fProc);
+#endif
+
+/* write callback */
+/* called to put data into the outputstream */
+#ifdef MNG_SUPPORT_WRITE
+MNG_EXT mng_retcode MNG_DECL mng_setcb_writedata (mng_handle hHandle,
+ mng_writedata fProc);
+#endif
+
+/* error callback */
+/* called when an error occurs */
+/* the application can determine if the error is recoverable,
+ and may inform the library by setting specific returncodes */
+MNG_EXT mng_retcode MNG_DECL mng_setcb_errorproc (mng_handle hHandle,
+ mng_errorproc fProc);
+
+/* trace callback */
+/* called to show the currently executing function */
+#ifdef MNG_SUPPORT_TRACE
+MNG_EXT mng_retcode MNG_DECL mng_setcb_traceproc (mng_handle hHandle,
+ mng_traceproc fProc);
+#endif
+
+/* callbacks for read processing */
+/* processheader is called when all header information has been gathered
+ from the inputstream */
+/* processtext is called for every tEXt, zTXt and iTXt chunk in the
+ inputstream (iType=0 for tEXt, 1 for zTXt and 2 for iTXt);
+ you can call get_imagelevel to check at what nesting-level the chunk is
+ encountered (eg. tEXt inside an embedded image inside a MNG -> level == 2;
+ in most other case -> level == 1) */
+/* processsave & processseek are called for SAVE/SEEK chunks */
+/* processneed is called for the nEED chunk; you should specify a callback
+ for this as the default behavior will be to abort processing */
+/* processunknown is called after reading each non-critical unknown chunk */
+#ifdef MNG_SUPPORT_READ
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processheader (mng_handle hHandle,
+ mng_processheader fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processtext (mng_handle hHandle,
+ mng_processtext fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processsave (mng_handle hHandle,
+ mng_processsave fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processseek (mng_handle hHandle,
+ mng_processseek fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processneed (mng_handle hHandle,
+ mng_processneed fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processmend (mng_handle hHandle,
+ mng_processmend fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processunknown(mng_handle hHandle,
+ mng_processunknown fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processterm (mng_handle hHandle,
+ mng_processterm fProc);
+#endif
+
+/* callbacks for display processing */
+/* getcanvasline is called to get an access-pointer to a line on the
+ drawing-canvas */
+/* getbkgdline is called to get an access-pointer to a line from the
+ background-canvas */
+/* refresh is called to inform the GUI to redraw the current canvas onto
+ it's output tqdevice (eg. in Win32 this would mean sending an
+ tqinvalidate message for the specified region */
+/* NOTE that the update-region is specified as x,y,width,height; eg. the
+ tqinvalidate message for Windows requires left,top,right,bottom parameters
+ where the bottom-right is exclusive of the region!!
+ to get these correctly is as simple as:
+ left = x;
+ top = y;
+ right = x + width;
+ bottom = y + height;
+ if your implementation requires inclusive points, simply subtract 1 from
+ both the right & bottom values calculated above.
+ */
+#ifdef MNG_SUPPORT_DISPLAY
+MNG_EXT mng_retcode MNG_DECL mng_setcb_getcanvasline (mng_handle hHandle,
+ mng_getcanvasline fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_getbkgdline (mng_handle hHandle,
+ mng_getbkgdline fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_getalphaline (mng_handle hHandle,
+ mng_getalphaline fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_refresh (mng_handle hHandle,
+ mng_refresh fProc);
+
+/* timing callbacks */
+/* gettickcount is called to get the system tickcount (milliseconds);
+ this is used to determine the remaining interval between frames */
+/* settimer is called to inform the application that it should set a timer;
+ when the timer is triggered the app must call mng_display_resume */
+MNG_EXT mng_retcode MNG_DECL mng_setcb_gettickcount (mng_handle hHandle,
+ mng_gettickcount fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_settimer (mng_handle hHandle,
+ mng_settimer fProc);
+
+/* color management callbacks */
+/* called to transmit color management information to the application */
+/* these are only used when you #define MNG_APP_CMS */
+#ifdef MNG_APP_CMS
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processgamma (mng_handle hHandle,
+ mng_processgamma fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processchroma (mng_handle hHandle,
+ mng_processchroma fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processsrgb (mng_handle hHandle,
+ mng_processsrgb fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processiccp (mng_handle hHandle,
+ mng_processiccp fProc);
+MNG_EXT mng_retcode MNG_DECL mng_setcb_processarow (mng_handle hHandle,
+ mng_processarow fProc);
+#endif /* MNG_APP_CMS */
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+/* * * */
+/* * Callback get functions * */
+/* * * */
+/* ************************************************************************** */
+
+/* see _setcb_ */
+#ifndef MNG_INTERNAL_MEMMNGMT
+MNG_EXT mng_memalloc MNG_DECL mng_getcb_memalloc (mng_handle hHandle);
+MNG_EXT mng_memfree MNG_DECL mng_getcb_memfree (mng_handle hHandle);
+#endif
+
+/* see _setcb_ */
+#if defined(MNG_SUPPORT_READ) || defined(MNG_WRITE_SUPPORT)
+MNG_EXT mng_openstream MNG_DECL mng_getcb_openstream (mng_handle hHandle);
+MNG_EXT mng_closestream MNG_DECL mng_getcb_closestream (mng_handle hHandle);
+#endif
+
+/* see _setcb_ */
+#ifdef MNG_SUPPORT_READ
+MNG_EXT mng_readdata MNG_DECL mng_getcb_readdata (mng_handle hHandle);
+#endif
+
+/* see _setcb_ */
+#ifdef MNG_SUPPORT_WRITE
+MNG_EXT mng_writedata MNG_DECL mng_getcb_writedata (mng_handle hHandle);
+#endif
+
+/* see _setcb_ */
+MNG_EXT mng_errorproc MNG_DECL mng_getcb_errorproc (mng_handle hHandle);
+
+/* see _setcb_ */
+#ifdef MNG_SUPPORT_TRACE
+MNG_EXT mng_traceproc MNG_DECL mng_getcb_traceproc (mng_handle hHandle);
+#endif
+
+/* see _setcb_ */
+#ifdef MNG_SUPPORT_READ
+MNG_EXT mng_processheader MNG_DECL mng_getcb_processheader (mng_handle hHandle);
+MNG_EXT mng_processtext MNG_DECL mng_getcb_processtext (mng_handle hHandle);
+MNG_EXT mng_processsave MNG_DECL mng_getcb_processsave (mng_handle hHandle);
+MNG_EXT mng_processseek MNG_DECL mng_getcb_processseek (mng_handle hHandle);
+MNG_EXT mng_processneed MNG_DECL mng_getcb_processneed (mng_handle hHandle);
+MNG_EXT mng_processunknown MNG_DECL mng_getcb_processunknown (mng_handle hHandle);
+MNG_EXT mng_processterm MNG_DECL mng_getcb_processterm (mng_handle hHandle);
+#endif
+
+/* see _setcb_ */
+#ifdef MNG_SUPPORT_DISPLAY
+MNG_EXT mng_getcanvasline MNG_DECL mng_getcb_getcanvasline (mng_handle hHandle);
+MNG_EXT mng_getbkgdline MNG_DECL mng_getcb_getbkgdline (mng_handle hHandle);
+MNG_EXT mng_getalphaline MNG_DECL mng_getcb_getalphaline (mng_handle hHandle);
+MNG_EXT mng_refresh MNG_DECL mng_getcb_refresh (mng_handle hHandle);
+
+/* see _setcb_ */
+MNG_EXT mng_gettickcount MNG_DECL mng_getcb_gettickcount (mng_handle hHandle);
+MNG_EXT mng_settimer MNG_DECL mng_getcb_settimer (mng_handle hHandle);
+
+/* see _setcb_ */
+#ifdef MNG_APP_CMS
+MNG_EXT mng_processgamma MNG_DECL mng_getcb_processgamma (mng_handle hHandle);
+MNG_EXT mng_processchroma MNG_DECL mng_getcb_processchroma (mng_handle hHandle);
+MNG_EXT mng_processsrgb MNG_DECL mng_getcb_processsrgb (mng_handle hHandle);
+MNG_EXT mng_processiccp MNG_DECL mng_getcb_processiccp (mng_handle hHandle);
+MNG_EXT mng_processarow MNG_DECL mng_getcb_processarow (mng_handle hHandle);
+#endif /* MNG_APP_CMS */
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+/* * * */
+/* * Property set functions * */
+/* * * */
+/* ************************************************************************** */
+
+/* Application data pointer */
+/* provided for application use; not used by the library */
+MNG_EXT mng_retcode MNG_DECL mng_set_userdata (mng_handle hHandle,
+ mng_ptr pUserdata);
+
+/* The style of the drawing- & background-canvas */
+/* only used for displaying images */
+/* both are initially set to 24-bit RGB (eg. 8-bit per channel) */
+MNG_EXT mng_retcode MNG_DECL mng_set_canvasstyle (mng_handle hHandle,
+ mng_uint32 iStyle);
+MNG_EXT mng_retcode MNG_DECL mng_set_bkgdstyle (mng_handle hHandle,
+ mng_uint32 iStyle);
+
+/* The default background color */
+/* only used if the getbkgdline callback is not defined */
+/* for initially painting the canvas and restoring (part of) the background */
+MNG_EXT mng_retcode MNG_DECL mng_set_bgcolor (mng_handle hHandle,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue);
+
+/* Indicates preferred use of the bKGD chunk for PNG images */
+MNG_EXT mng_retcode MNG_DECL mng_set_usebkgd (mng_handle hHandle,
+ mng_bool bUseBKGD);
+
+/* Indicates storage of read chunks */
+/* only useful if you #define mng_store_chunks */
+/* can be used to dynamically change storage management */
+MNG_EXT mng_retcode MNG_DECL mng_set_storechunks (mng_handle hHandle,
+ mng_bool bStorechunks);
+
+/* Indicates breaks requested when processing SAVE/SEEK */
+/* set this to let the app handle section breaks; the library will return
+ MNG_NEEDSECTIONWAIT return-codes for each SEEK chunk */
+MNG_EXT mng_retcode MNG_DECL mng_set_sectionbreaks (mng_handle hHandle,
+ mng_bool bSectionbreaks);
+
+/* Indicates storage of playback info (ON by default!) */
+/* can be used to turn off caching of playback info; this is useful to
+ specifically optimize MNG-video playback; note that if caching is turned off
+ LOOP chunks will be flagged as errors! TERM chunks will be ignored and only
+ passed to the processterm() callback if it is defined by the app; also, this
+ feature can only be used with mng_readdisplay(); mng_read(),
+ mng_display_reset() and mng_display_goxxxx() will return an error;
+ once this option is turned off it can't be turned on for the same stream!!! */
+MNG_EXT mng_retcode MNG_DECL mng_set_cacheplayback (mng_handle hHandle,
+ mng_bool bCacheplayback);
+
+/* Indicates automatic progressive refreshes for large images (ON by default!) */
+/* turn this off if you do not want intermittent painting while a large image
+ is being read. useful if the input-stream comes from a fast medium, such
+ as a local harddisk */
+MNG_EXT mng_retcode MNG_DECL mng_set_doprogressive (mng_handle hHandle,
+ mng_bool bDoProgressive);
+
+/* Color-management necessaries */
+/*
+ *************************************************************************
+ !!!!!!!! THIS BIT IS IMPORTANT !!!!!!!!!
+ *************************************************************************
+
+ If you have defined MNG_FULL_CMS (and are using lcms), you will have to
+ think hard about the following routines.
+
+ lcms requires 2 profiles to work off the differences in the input-image
+ and the output-tqdevice. The ICC profile for the input-image will be
+ embedded within it to reflect its color-characteristics, but the output
+ profile depends on the output-tqdevice, which is something only *YOU* know
+ about. sRGB (standard RGB) is common for x86 compatible environments
+ (eg. Windows, Linux and some others)
+
+ If you are compiling for a sRGB compliant system you probably won't have
+ to do anything special. (unless you want to ofcourse)
+
+ If you are compiling for a non-sRGB compliant system
+ (eg. SGI, Mac, Next, others...)
+ you *MUST* define a proper ICC profile for the generic output-tqdevice
+ associated with that platform.
+
+ In either event, you may also want to offer an option to your users to
+ set the profile manually, or, if you know how, set it from a
+ system-defined default.
+
+ TO RECAP: for sRGB systems (Windows, Linux) no action required!
+ for non-sRGB systems (SGI, Mac, Next) ACTION RETQUIRED!
+
+ Please visit http://www.srgb.com, http://www.color.org and
+ http://www.littlecms.com for more info.
+
+ *************************************************************************
+ !!!!!!!! THIS BIT IS IMPORTANT !!!!!!!!!
+ *************************************************************************
+*/
+/* mng_set_srgb tells libmng if it's running on a sRGB compliant system or not
+ the default is already set to MNG_TRUE */
+/* mng_set_outputprofile, mng_set_outputprofile2, mng_set_outputsrgb
+ are used to set the default profile describing the output-tqdevice
+ by default it is already initialized with an sRGB profile */
+/* mng_set_srgbprofile, mng_set_srgbprofile2, mng_set_srgbimplicit
+ are used to set the default profile describing a standard sRGB tqdevice
+ this is used when the input-image is tagged only as being sRGB, but the
+ output-tqdevice is defined as not being sRGB compliant
+ by default it is already initialized with a standard sRGB profile */
+#if defined(MNG_SUPPORT_DISPLAY)
+MNG_EXT mng_retcode MNG_DECL mng_set_srgb (mng_handle hHandle,
+ mng_bool bIssRGB);
+MNG_EXT mng_retcode MNG_DECL mng_set_outputprofile (mng_handle hHandle,
+ mng_pchar zFilename);
+MNG_EXT mng_retcode MNG_DECL mng_set_outputprofile2 (mng_handle hHandle,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile);
+MNG_EXT mng_retcode MNG_DECL mng_set_outputsrgb (mng_handle hHandle);
+MNG_EXT mng_retcode MNG_DECL mng_set_srgbprofile (mng_handle hHandle,
+ mng_pchar zFilename);
+MNG_EXT mng_retcode MNG_DECL mng_set_srgbprofile2 (mng_handle hHandle,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile);
+MNG_EXT mng_retcode MNG_DECL mng_set_srgbimplicit (mng_handle hHandle);
+#endif
+
+/* Gamma settings */
+/* only used if you #define MNG_FULL_CMS or #define MNG_GAMMA_ONLY */
+/* ... blabla (explain gamma processing a little; eg. formula & stuff) ... */
+MNG_EXT mng_retcode MNG_DECL mng_set_viewgamma (mng_handle hHandle,
+ mng_float dGamma);
+MNG_EXT mng_retcode MNG_DECL mng_set_displaygamma (mng_handle hHandle,
+ mng_float dGamma);
+MNG_EXT mng_retcode MNG_DECL mng_set_dfltimggamma (mng_handle hHandle,
+ mng_float dGamma);
+MNG_EXT mng_retcode MNG_DECL mng_set_viewgammaint (mng_handle hHandle,
+ mng_uint32 iGamma);
+MNG_EXT mng_retcode MNG_DECL mng_set_displaygammaint (mng_handle hHandle,
+ mng_uint32 iGamma);
+MNG_EXT mng_retcode MNG_DECL mng_set_dfltimggammaint (mng_handle hHandle,
+ mng_uint32 iGamma);
+
+/* Ultimate clipping size */
+/* used to limit extreme graphics from overloading the system */
+/* if a graphic exceeds these limits a warning is issued, which can
+ be ignored by the app (using the errorproc callback). in that case
+ the library will use these settings to clip the input graphic, and
+ the app's canvas must account for this */
+MNG_EXT mng_retcode MNG_DECL mng_set_maxcanvaswidth (mng_handle hHandle,
+ mng_uint32 iMaxwidth);
+MNG_EXT mng_retcode MNG_DECL mng_set_maxcanvasheight (mng_handle hHandle,
+ mng_uint32 iMaxheight);
+MNG_EXT mng_retcode MNG_DECL mng_set_maxcanvassize (mng_handle hHandle,
+ mng_uint32 iMaxwidth,
+ mng_uint32 iMaxheight);
+
+/* ZLIB default compression parameters */
+/* these are used when writing out chunks */
+/* they are also used when compressing PNG image-data or JNG alpha-data;
+ in this case you can set them just before calling mng_putimgdata_ihdr */
+/* set to your liking; usually the defaults will suffice though! */
+/* check the documentation for ZLIB for details on these parameters */
+#ifdef MNG_INCLUDE_ZLIB
+MNG_EXT mng_retcode MNG_DECL mng_set_zlib_level (mng_handle hHandle,
+ mng_int32 iZlevel);
+MNG_EXT mng_retcode MNG_DECL mng_set_zlib_method (mng_handle hHandle,
+ mng_int32 iZmethod);
+MNG_EXT mng_retcode MNG_DECL mng_set_zlib_windowbits (mng_handle hHandle,
+ mng_int32 iZwindowbits);
+MNG_EXT mng_retcode MNG_DECL mng_set_zlib_memlevel (mng_handle hHandle,
+ mng_int32 iZmemlevel);
+MNG_EXT mng_retcode MNG_DECL mng_set_zlib_strategy (mng_handle hHandle,
+ mng_int32 iZstrategy);
+
+MNG_EXT mng_retcode MNG_DECL mng_set_zlib_maxidat (mng_handle hHandle,
+ mng_uint32 iMaxIDAT);
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* JNG default compression parameters (based on IJG code) */
+/* these are used when compressing JNG image-data; so you can set them
+ just before calling mng_putimgdata_jhdr */
+/* set to your liking; usually the defaults will suffice though! */
+/* check the documentation for IJGSRC6B for details on these parameters */
+#ifdef MNG_INCLUDE_JNG
+#ifdef MNG_INCLUDE_IJG6B
+MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_dctmethod (mng_handle hHandle,
+ mngjpeg_dctmethod eJPEGdctmethod);
+#endif
+MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_quality (mng_handle hHandle,
+ mng_int32 iJPEGquality);
+MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_smoothing (mng_handle hHandle,
+ mng_int32 iJPEGsmoothing);
+MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_progressive(mng_handle hHandle,
+ mng_bool bJPEGprogressive);
+MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_optimized (mng_handle hHandle,
+ mng_bool bJPEGoptimized);
+
+MNG_EXT mng_retcode MNG_DECL mng_set_jpeg_maxjdat (mng_handle hHandle,
+ mng_uint32 iMaxJDAT);
+#endif /* MNG_INCLUDE_JNG */
+
+/* Suspension-mode setting */
+/* use this to activate the internal suspension-buffer to improve
+ read-suspension processing */
+/* TODO: write-suspension ??? */
+#if defined(MNG_SUPPORT_READ)
+MNG_EXT mng_retcode MNG_DECL mng_set_suspensionmode (mng_handle hHandle,
+ mng_bool bSuspensionmode);
+#endif
+
+/* Speed setting */
+/* use this to influence the display-speed of animations */
+#if defined(MNG_SUPPORT_DISPLAY)
+MNG_EXT mng_retcode MNG_DECL mng_set_speed (mng_handle hHandle,
+ mng_speedtype iSpeed);
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Property get functions * */
+/* * * */
+/* ************************************************************************** */
+
+/* see _set_ */
+MNG_EXT mng_ptr MNG_DECL mng_get_userdata (mng_handle hHandle);
+
+/* Network Graphic header details */
+/* these get filled once the graphics header is processed,
+ so they are available in the processheader callback; before that
+ they are zeroed out and imagetype is set to it_unknown */
+/* this might be a good point for the app to initialize the drawing-canvas! */
+/* note that some fields are only set for the first(!) header-chunk:
+ MNG/MHDR (imagetype = mng_it_mng) - ticks thru simplicity
+ PNG/IHDR (imagetype = mng_it_png) - bitdepth thru interlace
+ JNG/JHDR (imagetype = mng_it_jng) - bitdepth thru compression &
+ interlace thru alphainterlace */
+MNG_EXT mng_imgtype MNG_DECL mng_get_sigtype (mng_handle hHandle);
+MNG_EXT mng_imgtype MNG_DECL mng_get_imagetype (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_imagewidth (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_imageheight (mng_handle hHandle);
+
+MNG_EXT mng_uint32 MNG_DECL mng_get_ticks (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_framecount (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_layercount (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_playtime (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_simplicity (mng_handle hHandle);
+
+MNG_EXT mng_uint8 MNG_DECL mng_get_bitdepth (mng_handle hHandle);
+MNG_EXT mng_uint8 MNG_DECL mng_get_colortype (mng_handle hHandle);
+MNG_EXT mng_uint8 MNG_DECL mng_get_compression (mng_handle hHandle);
+MNG_EXT mng_uint8 MNG_DECL mng_get_filter (mng_handle hHandle);
+MNG_EXT mng_uint8 MNG_DECL mng_get_interlace (mng_handle hHandle);
+MNG_EXT mng_uint8 MNG_DECL mng_get_alphabitdepth (mng_handle hHandle);
+MNG_EXT mng_uint8 MNG_DECL mng_get_alphacompression(mng_handle hHandle);
+MNG_EXT mng_uint8 MNG_DECL mng_get_alphafilter (mng_handle hHandle);
+MNG_EXT mng_uint8 MNG_DECL mng_get_alphainterlace (mng_handle hHandle);
+
+/* indicates the predicted alpha-depth required to properly display the image */
+/* gets set once the graphics header is processed and is available in the
+ processheader callback for any type of input-image (PNG, JNG or MNG) */
+/* possible values are 0,1,2,4,8,16
+ 0 = no transparency required
+ 1 = on/off transparency required (alpha-values are 0 or 2^bit_depth-1)
+ 2+ = semi-transparency required (values will be scaled to the bitdepth of the
+ canvasstyle supplied by the application) */
+MNG_EXT mng_uint8 MNG_DECL mng_get_alphadepth (mng_handle hHandle);
+
+/* defines whether a refresh() callback is called for an interlace pass (PNG)
+ or progressive scan (JNG) */
+/* returns the interlace pass number for PNG or a fabricated pass number for JNG;
+ returns 0 in all other cases */
+/* only useful if the image_type = mng_it_png or mng_it_jng and if the image
+ is actually interlaced (PNG) or progressive (JNG) */
+MNG_EXT mng_uint8 MNG_DECL mng_get_refreshpass (mng_handle hHandle);
+
+/* see _set_ */
+MNG_EXT mng_uint32 MNG_DECL mng_get_canvasstyle (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_bkgdstyle (mng_handle hHandle);
+
+/* see _set_ */
+MNG_EXT mng_retcode MNG_DECL mng_get_bgcolor (mng_handle hHandle,
+ mng_uint16* iRed,
+ mng_uint16* iGreen,
+ mng_uint16* iBlue);
+
+/* see _set_ */
+MNG_EXT mng_bool MNG_DECL mng_get_usebkgd (mng_handle hHandle);
+
+/* see _set_ */
+MNG_EXT mng_bool MNG_DECL mng_get_storechunks (mng_handle hHandle);
+
+/* see _set_ */
+MNG_EXT mng_bool MNG_DECL mng_get_sectionbreaks (mng_handle hHandle);
+
+/* see _set_ */
+MNG_EXT mng_bool MNG_DECL mng_get_cacheplayback (mng_handle hHandle);
+
+/* see _set_ */
+MNG_EXT mng_bool MNG_DECL mng_get_doprogressive (mng_handle hHandle);
+
+/* see _set_ */
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_FULL_CMS)
+MNG_EXT mng_bool MNG_DECL mng_get_srgb (mng_handle hHandle);
+#endif
+
+/* see _set_ */
+MNG_EXT mng_float MNG_DECL mng_get_viewgamma (mng_handle hHandle);
+MNG_EXT mng_float MNG_DECL mng_get_displaygamma (mng_handle hHandle);
+MNG_EXT mng_float MNG_DECL mng_get_dfltimggamma (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_viewgammaint (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_displaygammaint (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_dfltimggammaint (mng_handle hHandle);
+
+/* see _set_ */
+MNG_EXT mng_uint32 MNG_DECL mng_get_maxcanvaswidth (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_maxcanvasheight (mng_handle hHandle);
+
+/* see _set_ */
+#ifdef MNG_INCLUDE_ZLIB
+MNG_EXT mng_int32 MNG_DECL mng_get_zlib_level (mng_handle hHandle);
+MNG_EXT mng_int32 MNG_DECL mng_get_zlib_method (mng_handle hHandle);
+MNG_EXT mng_int32 MNG_DECL mng_get_zlib_windowbits (mng_handle hHandle);
+MNG_EXT mng_int32 MNG_DECL mng_get_zlib_memlevel (mng_handle hHandle);
+MNG_EXT mng_int32 MNG_DECL mng_get_zlib_strategy (mng_handle hHandle);
+
+MNG_EXT mng_uint32 MNG_DECL mng_get_zlib_maxidat (mng_handle hHandle);
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* see _set_ */
+#ifdef MNG_INCLUDE_JNG
+#ifdef MNG_INCLUDE_IJG6B
+MNG_EXT mngjpeg_dctmethod
+ MNG_DECL mng_get_jpeg_dctmethod (mng_handle hHandle);
+#endif
+MNG_EXT mng_int32 MNG_DECL mng_get_jpeg_quality (mng_handle hHandle);
+MNG_EXT mng_int32 MNG_DECL mng_get_jpeg_smoothing (mng_handle hHandle);
+MNG_EXT mng_bool MNG_DECL mng_get_jpeg_progressive(mng_handle hHandle);
+MNG_EXT mng_bool MNG_DECL mng_get_jpeg_optimized (mng_handle hHandle);
+
+MNG_EXT mng_uint32 MNG_DECL mng_get_jpeg_maxjdat (mng_handle hHandle);
+#endif /* MNG_INCLUDE_JNG */
+
+/* see _set_ */
+#if defined(MNG_SUPPORT_READ)
+MNG_EXT mng_bool MNG_DECL mng_get_suspensionmode (mng_handle hHandle);
+#endif
+
+/* see _set_ */
+#if defined(MNG_SUPPORT_DISPLAY)
+MNG_EXT mng_speedtype
+ MNG_DECL mng_get_speed (mng_handle hHandle);
+#endif
+
+/* Image-level */
+/* this can be used inside the processtext callback to determine the level of
+ text of the image being processed; the value 1 is returned for top-level
+ texts, and the value 2 for a text inside an embedded image inside a MNG */
+MNG_EXT mng_uint32 MNG_DECL mng_get_imagelevel (mng_handle hHandle);
+
+/* BACK info */
+/* can be used to retrieve the color & mandatory values for the last processed
+ BACK chunk of a MNG (will fail for other image-types);
+ if no BACK chunk was processed yet, it will return all zeroes */
+MNG_EXT mng_retcode MNG_DECL mng_get_lastbackchunk (mng_handle hHandle,
+ mng_uint16* iRed,
+ mng_uint16* iGreen,
+ mng_uint16* iBlue,
+ mng_uint8* iMandatory);
+
+/* Display status variables */
+/* these get filled & updated during display processing */
+/* starttime is the tickcount at the start of displaying the animation */
+/* runtime is the actual number of millisecs since the start of the animation */
+/* currentframe, currentlayer & currentplaytime indicate the current
+ frame/layer/playtime(msecs) in the animation (these keep increasing;
+ even after the animation loops back to the TERM chunk) */
+#if defined(MNG_SUPPORT_DISPLAY)
+MNG_EXT mng_uint32 MNG_DECL mng_get_starttime (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_runtime (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_currentframe (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_currentlayer (mng_handle hHandle);
+MNG_EXT mng_uint32 MNG_DECL mng_get_currentplaytime (mng_handle hHandle);
+#endif
+
+/* tqStatus variables */
+/* these indicate the internal state of the library */
+/* most indicate exactly what you would expect:
+ status_error returns MNG_TRUE if the last function call returned an errorcode
+ status_reading returns MNG_TRUE if the library is (still) reading an image
+ status_suspendbreak returns MNG_TRUE if the library has suspended for "I/O"
+ status_creating returns MNG_TRUE if the library is in the middle of creating an image
+ status_writing returns MNG_TRUE if the library is in the middle of writing an image
+ status_displaying returns MNG_TRUE if the library is displaying an image
+ status_running returns MNG_TRUE if display processing is active (eg. not frozen or reset)
+ status_timerbreak returns MNG_TRUE if the library has suspended for a "timer-break" */
+/* eg. mng_readdisplay() will turn the reading, displaying and running status on;
+ when EOF is reached the reading status will be turned off */
+MNG_EXT mng_bool MNG_DECL mng_status_error (mng_handle hHandle);
+#ifdef MNG_SUPPORT_READ
+MNG_EXT mng_bool MNG_DECL mng_status_reading (mng_handle hHandle);
+MNG_EXT mng_bool MNG_DECL mng_status_suspendbreak (mng_handle hHandle);
+#endif
+#ifdef MNG_SUPPORT_WRITE
+MNG_EXT mng_bool MNG_DECL mng_status_creating (mng_handle hHandle);
+MNG_EXT mng_bool MNG_DECL mng_status_writing (mng_handle hHandle);
+#endif
+#ifdef MNG_SUPPORT_DISPLAY
+MNG_EXT mng_bool MNG_DECL mng_status_displaying (mng_handle hHandle);
+MNG_EXT mng_bool MNG_DECL mng_status_running (mng_handle hHandle);
+MNG_EXT mng_bool MNG_DECL mng_status_timerbreak (mng_handle hHandle);
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Chunk access functions * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_ACCESS_CHUNKS
+
+/* ************************************************************************** */
+
+/* use this to iterate the stored chunks */
+/* requires MNG_ACCESS_CHUNKS & MNG_STORE_CHUNKS */
+/* starts from the supplied chunk-index-nr; the first chunk has index 0!! */
+MNG_EXT mng_retcode MNG_DECL mng_iterate_chunks (mng_handle hHandle,
+ mng_uint32 iChunkseq,
+ mng_iteratechunk fProc);
+
+/* ************************************************************************** */
+
+/* use these to get chunk data from within the callback in iterate_chunks */
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_ihdr (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iWidth,
+ mng_uint32 *iHeight,
+ mng_uint8 *iBitdepth,
+ mng_uint8 *iColortype,
+ mng_uint8 *iCompression,
+ mng_uint8 *iFilter,
+ mng_uint8 *iInterlace);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_plte (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iCount,
+ mng_palette8 *aPalette);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_idat (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iRawlen,
+ mng_ptr *pRawdata);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_trns (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_bool *bGlobal,
+ mng_uint8 *iType,
+ mng_uint32 *iCount,
+ mng_uint8arr *aAlphas,
+ mng_uint16 *iGray,
+ mng_uint16 *iRed,
+ mng_uint16 *iGreen,
+ mng_uint16 *iBlue,
+ mng_uint32 *iRawlen,
+ mng_uint8arr *aRawdata);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_gama (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iGamma);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_chrm (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iWhitepointx,
+ mng_uint32 *iWhitepointy,
+ mng_uint32 *iRedx,
+ mng_uint32 *iRedy,
+ mng_uint32 *iGreenx,
+ mng_uint32 *iGreeny,
+ mng_uint32 *iBluex,
+ mng_uint32 *iBluey);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_srgb (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iRenderingintent);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_iccp (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName,
+ mng_uint8 *iCompression,
+ mng_uint32 *iProfilesize,
+ mng_ptr *pProfile);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_text (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iKeywordsize,
+ mng_pchar *zKeyword,
+ mng_uint32 *iTextsize,
+ mng_pchar *zText);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_ztxt (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iKeywordsize,
+ mng_pchar *zKeyword,
+ mng_uint8 *iCompression,
+ mng_uint32 *iTextsize,
+ mng_pchar *zText);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_itxt (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iKeywordsize,
+ mng_pchar *zKeyword,
+ mng_uint8 *iCompressionflag,
+ mng_uint8 *iCompressionmethod,
+ mng_uint32 *iLanguagesize,
+ mng_pchar *zLanguage,
+ mng_uint32 *iTranslationsize,
+ mng_pchar *zTranslation,
+ mng_uint32 *iTextsize,
+ mng_pchar *zText);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_bkgd (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iType,
+ mng_uint8 *iIndex,
+ mng_uint16 *iGray,
+ mng_uint16 *iRed,
+ mng_uint16 *iGreen,
+ mng_uint16 *iBlue);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_phys (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iSizex,
+ mng_uint32 *iSizey,
+ mng_uint8 *iUnit);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_sbit (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iType,
+ mng_uint8arr4 *aBits);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_splt (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName,
+ mng_uint8 *iSampledepth,
+ mng_uint32 *iEntrycount,
+ mng_ptr *pEntries);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_hist (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iEntrycount,
+ mng_uint16arr *aEntries);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_time (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iYear,
+ mng_uint8 *iMonth,
+ mng_uint8 *iDay,
+ mng_uint8 *iHour,
+ mng_uint8 *iMinute,
+ mng_uint8 *iSecond);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_mhdr (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iWidth,
+ mng_uint32 *iHeight,
+ mng_uint32 *iTicks,
+ mng_uint32 *iLayercount,
+ mng_uint32 *iFramecount,
+ mng_uint32 *iPlaytime,
+ mng_uint32 *iSimplicity);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_loop (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint8 *iLevel,
+ mng_uint32 *iRepeat,
+ mng_uint8 *iTermination,
+ mng_uint32 *iItermin,
+ mng_uint32 *iItermax,
+ mng_uint32 *iCount,
+ mng_uint32p *pSignals);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_endl (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint8 *iLevel);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_defi (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iObjectid,
+ mng_uint8 *iDonotshow,
+ mng_uint8 *iConcrete,
+ mng_bool *bHasloca,
+ mng_int32 *iXlocation,
+ mng_int32 *iYlocation,
+ mng_bool *bHasclip,
+ mng_int32 *iLeftcb,
+ mng_int32 *iRightcb,
+ mng_int32 *iTopcb,
+ mng_int32 *iBottomcb);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_basi (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iWidth,
+ mng_uint32 *iHeight,
+ mng_uint8 *iBitdepth,
+ mng_uint8 *iColortype,
+ mng_uint8 *iCompression,
+ mng_uint8 *iFilter,
+ mng_uint8 *iInterlace,
+ mng_uint16 *iRed,
+ mng_uint16 *iGreen,
+ mng_uint16 *iBlue,
+ mng_uint16 *iAlpha,
+ mng_uint8 *iViewable);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_clon (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iSourceid,
+ mng_uint16 *iCloneid,
+ mng_uint8 *iClonetype,
+ mng_uint8 *iDonotshow,
+ mng_uint8 *iConcrete,
+ mng_bool *bHasloca,
+ mng_uint8 *iLocationtype,
+ mng_int32 *iLocationx,
+ mng_int32 *iLocationy);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_past (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iDestid,
+ mng_uint8 *iTargettype,
+ mng_int32 *iTargetx,
+ mng_int32 *iTargety,
+ mng_uint32 *iCount);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_past_src (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 iEntry,
+ mng_uint16 *iSourceid,
+ mng_uint8 *iComposition,
+ mng_uint8 *iOrientation,
+ mng_uint8 *iOffsettype,
+ mng_int32 *iOffsetx,
+ mng_int32 *iOffsety,
+ mng_uint8 *iBoundarytype,
+ mng_int32 *iBoundaryl,
+ mng_int32 *iBoundaryr,
+ mng_int32 *iBoundaryt,
+ mng_int32 *iBoundaryb);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_disc (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iCount,
+ mng_uint16p *pObjectids);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_back (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iRed,
+ mng_uint16 *iGreen,
+ mng_uint16 *iBlue,
+ mng_uint8 *iMandatory,
+ mng_uint16 *iImageid,
+ mng_uint8 *iTile);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_fram (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iMode,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName,
+ mng_uint8 *iChangedelay,
+ mng_uint8 *iChangetimeout,
+ mng_uint8 *iChangeclipping,
+ mng_uint8 *iChangesyncid,
+ mng_uint32 *iDelay,
+ mng_uint32 *iTimeout,
+ mng_uint8 *iBoundarytype,
+ mng_int32 *iBoundaryl,
+ mng_int32 *iBoundaryr,
+ mng_int32 *iBoundaryt,
+ mng_int32 *iBoundaryb,
+ mng_uint32 *iCount,
+ mng_uint32p *pSyncids);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_move (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iFirstid,
+ mng_uint16 *iLastid,
+ mng_uint8 *iMovetype,
+ mng_int32 *iMovex,
+ mng_int32 *iMovey);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_clip (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iFirstid,
+ mng_uint16 *iLastid,
+ mng_uint8 *iCliptype,
+ mng_int32 *iClipl,
+ mng_int32 *iClipr,
+ mng_int32 *iClipt,
+ mng_int32 *iClipb);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_show (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint16 *iFirstid,
+ mng_uint16 *iLastid,
+ mng_uint8 *iMode);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_term (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint8 *iTermaction,
+ mng_uint8 *iIteraction,
+ mng_uint32 *iDelay,
+ mng_uint32 *iItermax);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_save (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iOffsettype,
+ mng_uint32 *iCount);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_save_entry (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 iEntry,
+ mng_uint8 *iEntrytype,
+ mng_uint32arr2 *iOffset,
+ mng_uint32arr2 *iStarttime,
+ mng_uint32 *iLayernr,
+ mng_uint32 *iFramenr,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_seek (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_expi (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iSnapshotid,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_fpri (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint8 *iDeltatype,
+ mng_uint8 *iPriority);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_need (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iKeywordssize,
+ mng_pchar *zKeywords);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_phyg (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iSizex,
+ mng_uint32 *iSizey,
+ mng_uint8 *iUnit);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_jhdr (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iWidth,
+ mng_uint32 *iHeight,
+ mng_uint8 *iColortype,
+ mng_uint8 *iImagesampledepth,
+ mng_uint8 *iImagecompression,
+ mng_uint8 *iImageinterlace,
+ mng_uint8 *iAlphasampledepth,
+ mng_uint8 *iAlphacompression,
+ mng_uint8 *iAlphafilter,
+ mng_uint8 *iAlphainterlace);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_jdat (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iRawlen,
+ mng_ptr *pRawdata);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_jdaa (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iRawlen,
+ mng_ptr *pRawdata);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_dhdr (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iObjectid,
+ mng_uint8 *iImagetype,
+ mng_uint8 *iDeltatype,
+ mng_uint32 *iBlockwidth,
+ mng_uint32 *iBlockheight,
+ mng_uint32 *iBlockx,
+ mng_uint32 *iBlocky);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_prom (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint8 *iColortype,
+ mng_uint8 *iSampledepth,
+ mng_uint8 *iFilltype);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_pplt (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iCount);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_pplt_entry (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 iEntry,
+ mng_uint16 *iRed,
+ mng_uint16 *iGreen,
+ mng_uint16 *iBlue,
+ mng_uint16 *iAlpha,
+ mng_bool *bUsed);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_drop (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iCount,
+ mng_chunkidp *pChunknames);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_dbyk (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_chunkid *iChunkname,
+ mng_uint8 *iPolarity,
+ mng_uint32 *iKeywordssize,
+ mng_pchar *zKeywords);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_ordr (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iCount);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_ordr_entry (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 iEntry,
+ mng_chunkid *iChunkname,
+ mng_uint8 *iOrdertype);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_magn (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iFirstid,
+ mng_uint16 *iLastid,
+ mng_uint16 *iMethodX,
+ mng_uint16 *iMX,
+ mng_uint16 *iMY,
+ mng_uint16 *iML,
+ mng_uint16 *iMR,
+ mng_uint16 *iMT,
+ mng_uint16 *iMB,
+ mng_uint16 *iMethodY);
+
+MNG_EXT mng_retcode MNG_DECL mng_getchunk_unknown (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_chunkid *iChunkname,
+ mng_uint32 *iRawlen,
+ mng_ptr *pRawdata);
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_WRITE_PROCS
+
+/* use these to create new chunks at the end of the chunk-list */
+/* requires at least MNG_ACCESS_CHUNKS (MNG_SUPPORT_WRITE may be nice too) */
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_ihdr (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_plte (mng_handle hHandle,
+ mng_uint32 iCount,
+ mng_palette8 aPalette);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_idat (mng_handle hHandle,
+ mng_uint32 iRawlen,
+ mng_ptr pRawdata);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_iend (mng_handle hHandle);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_trns (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_bool bGlobal,
+ mng_uint8 iType,
+ mng_uint32 iCount,
+ mng_uint8arr aAlphas,
+ mng_uint16 iGray,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_uint32 iRawlen,
+ mng_uint8arr aRawdata);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_gama (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iGamma);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_chrm (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iWhitepointx,
+ mng_uint32 iWhitepointy,
+ mng_uint32 iRedx,
+ mng_uint32 iRedy,
+ mng_uint32 iGreenx,
+ mng_uint32 iGreeny,
+ mng_uint32 iBluex,
+ mng_uint32 iBluey);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_srgb (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint8 iRenderingintent);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_iccp (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iNamesize,
+ mng_pchar zName,
+ mng_uint8 iCompression,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_text (mng_handle hHandle,
+ mng_uint32 iKeywordsize,
+ mng_pchar zKeyword,
+ mng_uint32 iTextsize,
+ mng_pchar zText);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_ztxt (mng_handle hHandle,
+ mng_uint32 iKeywordsize,
+ mng_pchar zKeyword,
+ mng_uint8 iCompression,
+ mng_uint32 iTextsize,
+ mng_pchar zText);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_itxt (mng_handle hHandle,
+ mng_uint32 iKeywordsize,
+ mng_pchar zKeyword,
+ mng_uint8 iCompressionflag,
+ mng_uint8 iCompressionmethod,
+ mng_uint32 iLanguagesize,
+ mng_pchar zLanguage,
+ mng_uint32 iTranslationsize,
+ mng_pchar zTranslation,
+ mng_uint32 iTextsize,
+ mng_pchar zText);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_bkgd (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint8 iType,
+ mng_uint8 iIndex,
+ mng_uint16 iGray,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_phys (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iSizex,
+ mng_uint32 iSizey,
+ mng_uint8 iUnit);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_sbit (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint8 iType,
+ mng_uint8arr4 aBits);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_splt (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iNamesize,
+ mng_pchar zName,
+ mng_uint8 iSampledepth,
+ mng_uint32 iEntrycount,
+ mng_ptr pEntries);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_hist (mng_handle hHandle,
+ mng_uint32 iEntrycount,
+ mng_uint16arr aEntries);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_time (mng_handle hHandle,
+ mng_uint16 iYear,
+ mng_uint8 iMonth,
+ mng_uint8 iDay,
+ mng_uint8 iHour,
+ mng_uint8 iMinute,
+ mng_uint8 iSecond);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_mhdr (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint32 iTicks,
+ mng_uint32 iLayercount,
+ mng_uint32 iFramecount,
+ mng_uint32 iPlaytime,
+ mng_uint32 iSimplicity);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_mend (mng_handle hHandle);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_loop (mng_handle hHandle,
+ mng_uint8 iLevel,
+ mng_uint32 iRepeat,
+ mng_uint8 iTermination,
+ mng_uint32 iItermin,
+ mng_uint32 iItermax,
+ mng_uint32 iCount,
+ mng_uint32p pSignals);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_endl (mng_handle hHandle,
+ mng_uint8 iLevel);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_defi (mng_handle hHandle,
+ mng_uint16 iObjectid,
+ mng_uint8 iDonotshow,
+ mng_uint8 iConcrete,
+ mng_bool bHasloca,
+ mng_int32 iXlocation,
+ mng_int32 iYlocation,
+ mng_bool bHasclip,
+ mng_int32 iLeftcb,
+ mng_int32 iRightcb,
+ mng_int32 iTopcb,
+ mng_int32 iBottomcb);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_basi (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_uint16 iAlpha,
+ mng_uint8 iViewable);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_clon (mng_handle hHandle,
+ mng_uint16 iSourceid,
+ mng_uint16 iCloneid,
+ mng_uint8 iClonetype,
+ mng_uint8 iDonotshow,
+ mng_uint8 iConcrete,
+ mng_bool bHasloca,
+ mng_uint8 iLocationtype,
+ mng_int32 iLocationx,
+ mng_int32 iLocationy);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_past (mng_handle hHandle,
+ mng_uint16 iDestid,
+ mng_uint8 iTargettype,
+ mng_int32 iTargetx,
+ mng_int32 iTargety,
+ mng_uint32 iCount);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_past_src (mng_handle hHandle,
+ mng_uint32 iEntry,
+ mng_uint16 iSourceid,
+ mng_uint8 iComposition,
+ mng_uint8 iOrientation,
+ mng_uint8 iOffsettype,
+ mng_int32 iOffsetx,
+ mng_int32 iOffsety,
+ mng_uint8 iBoundarytype,
+ mng_int32 iBoundaryl,
+ mng_int32 iBoundaryr,
+ mng_int32 iBoundaryt,
+ mng_int32 iBoundaryb);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_disc (mng_handle hHandle,
+ mng_uint32 iCount,
+ mng_uint16p pObjectids);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_back (mng_handle hHandle,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_uint8 iMandatory,
+ mng_uint16 iImageid,
+ mng_uint8 iTile);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_fram (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint8 iMode,
+ mng_uint32 iNamesize,
+ mng_pchar zName,
+ mng_uint8 iChangedelay,
+ mng_uint8 iChangetimeout,
+ mng_uint8 iChangeclipping,
+ mng_uint8 iChangesyncid,
+ mng_uint32 iDelay,
+ mng_uint32 iTimeout,
+ mng_uint8 iBoundarytype,
+ mng_int32 iBoundaryl,
+ mng_int32 iBoundaryr,
+ mng_int32 iBoundaryt,
+ mng_int32 iBoundaryb,
+ mng_uint32 iCount,
+ mng_uint32p pSyncids);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_move (mng_handle hHandle,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iMovetype,
+ mng_int32 iMovex,
+ mng_int32 iMovey);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_clip (mng_handle hHandle,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_show (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iMode);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_term (mng_handle hHandle,
+ mng_uint8 iTermaction,
+ mng_uint8 iIteraction,
+ mng_uint32 iDelay,
+ mng_uint32 iItermax);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_save (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint8 iOffsettype,
+ mng_uint32 iCount);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_save_entry (mng_handle hHandle,
+ mng_uint32 iEntry,
+ mng_uint8 iEntrytype,
+ mng_uint32arr2 iOffset,
+ mng_uint32arr2 iStarttime,
+ mng_uint32 iLayernr,
+ mng_uint32 iFramenr,
+ mng_uint32 iNamesize,
+ mng_pchar zName);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_seek (mng_handle hHandle,
+ mng_uint32 iNamesize,
+ mng_pchar zName);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_expi (mng_handle hHandle,
+ mng_uint16 iSnapshotid,
+ mng_uint32 iNamesize,
+ mng_pchar zName);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_fpri (mng_handle hHandle,
+ mng_uint8 iDeltatype,
+ mng_uint8 iPriority);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_need (mng_handle hHandle,
+ mng_uint32 iKeywordssize,
+ mng_pchar zKeywords);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_phyg (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iSizex,
+ mng_uint32 iSizey,
+ mng_uint8 iUnit);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_jhdr (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iColortype,
+ mng_uint8 iImagesampledepth,
+ mng_uint8 iImagecompression,
+ mng_uint8 iImageinterlace,
+ mng_uint8 iAlphasampledepth,
+ mng_uint8 iAlphacompression,
+ mng_uint8 iAlphafilter,
+ mng_uint8 iAlphainterlace);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_jdat (mng_handle hHandle,
+ mng_uint32 iRawlen,
+ mng_ptr pRawdata);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_jdaa (mng_handle hHandle,
+ mng_uint32 iRawlen,
+ mng_ptr pRawdata);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_jsep (mng_handle hHandle);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_dhdr (mng_handle hHandle,
+ mng_uint16 iObjectid,
+ mng_uint8 iImagetype,
+ mng_uint8 iDeltatype,
+ mng_uint32 iBlockwidth,
+ mng_uint32 iBlockheight,
+ mng_uint32 iBlockx,
+ mng_uint32 iBlocky);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_prom (mng_handle hHandle,
+ mng_uint8 iColortype,
+ mng_uint8 iSampledepth,
+ mng_uint8 iFilltype);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_ipng (mng_handle hHandle);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_pplt (mng_handle hHandle,
+ mng_uint32 iCount);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_pplt_entry (mng_handle hHandle,
+ mng_uint32 iEntry,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_uint16 iAlpha,
+ mng_bool bUsed);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_jpng (mng_handle hHandle);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_drop (mng_handle hHandle,
+ mng_uint32 iCount,
+ mng_chunkidp pChunknames);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_dbyk (mng_handle hHandle,
+ mng_chunkid iChunkname,
+ mng_uint8 iPolarity,
+ mng_uint32 iKeywordssize,
+ mng_pchar zKeywords);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_ordr (mng_handle hHandle,
+ mng_uint32 iCount);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_ordr_entry (mng_handle hHandle,
+ mng_uint32 iEntry,
+ mng_chunkid iChunkname,
+ mng_uint8 iOrdertype);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_magn (mng_handle hHandle,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint16 iMethodX,
+ mng_uint16 iMX,
+ mng_uint16 iMY,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint16 iMT,
+ mng_uint16 iMB,
+ mng_uint16 iMethodY);
+
+MNG_EXT mng_retcode MNG_DECL mng_putchunk_unknown (mng_handle hHandle,
+ mng_chunkid iChunkname,
+ mng_uint32 iRawlen,
+ mng_ptr pRawdata);
+
+#endif /* MNG_INCLUDE_WRITE_PROCS */
+
+/* ************************************************************************** */
+
+/* use these functions to access the actual image-data in stored chunks,
+ as opposed to the IDAT/JDAT data */
+/* to get accurate pixel-data the canvasstyle should seriously reflect the
+ bitdepth/colortype combination of the preceding IHDR/JHDR/BASI/DHDR;
+ all input can be converted to rgb(a)8 (rgb(a)16 for 16-bit images), but
+ there are only limited conversions back (see below for putimgdata) */
+
+/* call this function if you want to extract the nth image from the list;
+ the first image is designated seqnr 0! */
+/* this function tqfinds the IHDR/JHDR/BASI/DHDR with the appropriate seqnr,
+ starting from the beginning of the chunk-list; this may tend to get a little
+ slow for animations with a large number of chunks for images near the end */
+/* supplying a seqnr past the last image in the animation will return with
+ an errorcode */
+MNG_EXT mng_retcode MNG_DECL mng_getimgdata_seq (mng_handle hHandle,
+ mng_uint32 iSeqnr,
+ mng_uint32 iCanvasstyle,
+ mng_getcanvasline fGetcanvasline);
+
+/* both the following functions will search forward to tqfind the first IDAT/JDAT,
+ and then traverse back to tqfind the start of the image (IHDR,JHDR,DHDR,BASI);
+ note that this is very fast compared to decoding the IDAT/JDAT, so there's
+ not really a need for optimization; either can be called from the
+ iterate_chunks callback when a IHDR/JHDR is encountered; for BASI/DHDR there
+ may not be real image-data so it's wisest to keep iterating till the IEND,
+ and then call either of these functions if necessary (remember the correct seqnr!) */
+
+/* call this function if you want to extract the image starting at or after the nth
+ position in the chunk-list; this number is returned in the iterate_chunks callback */
+MNG_EXT mng_retcode MNG_DECL mng_getimgdata_chunkseq (mng_handle hHandle,
+ mng_uint32 iSeqnr,
+ mng_uint32 iCanvasstyle,
+ mng_getcanvasline fGetcanvasline);
+
+/* call this function if you want to extract the image starting at or after the
+ indicated chunk; the handle of a chunk is returned in the iterate_chunks callback */
+MNG_EXT mng_retcode MNG_DECL mng_getimgdata_chunk (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 iCanvasstyle,
+ mng_getcanvasline fGetcanvasline);
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_WRITE_PROCS
+
+/* use the following functions to add image-data to the list of stored chunks */
+/* note that this only adds the IDAT or JDAT chunks and no others; you must call
+ one of these functions after you 'put' the initial chunks of the image and
+ before you 'put' the closing chunks */
+/* the canvasstyle should seriously reflect the bitdepth/colortype combination;
+ eg. bitdepth=16 would expect a 16-bit canvasstyle,
+ colortype=g or ga would expect a gray or gray+alpha style respectively
+ and so on, and so forth ...
+ (nb. the number of conversions will be extremely limited for the moment!) */
+
+MNG_EXT mng_retcode MNG_DECL mng_putimgdata_ihdr (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iColortype,
+ mng_uint8 iBitdepth,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace,
+ mng_uint32 iCanvasstyle,
+ mng_getcanvasline fGetcanvasline);
+
+MNG_EXT mng_retcode MNG_DECL mng_putimgdata_jhdr (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iColortype,
+ mng_uint8 iBitdepth,
+ mng_uint8 iCompression,
+ mng_uint8 iInterlace,
+ mng_uint8 iAlphaBitdepth,
+ mng_uint8 iAlphaCompression,
+ mng_uint8 iAlphaFilter,
+ mng_uint8 iAlphaInterlace,
+ mng_uint32 iCanvasstyle,
+ mng_getcanvasline fGetcanvasline);
+
+/* ************************************************************************** */
+
+/* use the following functions to set the framecount/layercount/playtime or
+ simplicity of an animation you are creating; this may be useful if these
+ variables are calculated during the creation-process */
+
+MNG_EXT mng_retcode MNG_DECL mng_updatemngheader (mng_handle hHandle,
+ mng_uint32 iFramecount,
+ mng_uint32 iLayercount,
+ mng_uint32 iPlaytime);
+
+MNG_EXT mng_retcode MNG_DECL mng_updatemngsimplicity (mng_handle hHandle,
+ mng_uint32 iSimplicity);
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_WRITE_PROCS */
+
+#endif /* MNG_ACCESS_CHUNKS */
+
+/* ************************************************************************** */
+/* * * */
+/* * Error-code structure * */
+/* * * */
+/* * 0b0000 00xx xxxx xxxx - basic errors; severity 9 (environment) * */
+/* * 0b0000 01xx xxxx xxxx - chunk errors; severity 9 (image induced) * */
+/* * 0b0000 10xx xxxx xxxx - severity 5 errors (application induced) * */
+/* * 0b0001 00xx xxxx xxxx - severity 2 warnings (recoverable) * */
+/* * 0b0010 00xx xxxx xxxx - severity 1 warnings (recoverable) * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_NOERROR (mng_retcode)0 /* er.. indicates all's well */
+
+#define MNG_OUTOFMEMORY (mng_retcode)1 /* oops, buy some megabytes! */
+#define MNG_INVALIDHANDLE (mng_retcode)2 /* call mng_initialize first */
+#define MNG_NOCALLBACK (mng_retcode)3 /* set the callbacks please */
+#define MNG_UNEXPECTEDEOF (mng_retcode)4 /* what'd ya do with the data? */
+#define MNG_ZLIBERROR (mng_retcode)5 /* zlib burped */
+#define MNG_JPEGERROR (mng_retcode)6 /* jpglib complained */
+#define MNG_LCMSERROR (mng_retcode)7 /* little cms stressed out */
+#define MNG_NOOUTPUTPROFILE (mng_retcode)8 /* no output-profile defined */
+#define MNG_NOSRGBPROFILE (mng_retcode)9 /* no sRGB-profile defined */
+#define MNG_BUFOVERFLOW (mng_retcode)10 /* zlib output-buffer overflow */
+#define MNG_FUNCTIONINVALID (mng_retcode)11 /* ay, totally inappropriate */
+#define MNG_OUTPUTERROR (mng_retcode)12 /* disk full ? */
+#define MNG_JPEGBUFTOOSMALL (mng_retcode)13 /* can't handle buffer overflow*/
+#define MNG_NEEDMOREDATA (mng_retcode)14 /* I'm hungry, give me more */
+#define MNG_NEEDTIMERWAIT (mng_retcode)15 /* Sleep a while then wake me */
+#define MNG_NEEDSECTIONWAIT (mng_retcode)16 /* just processed a SEEK */
+#define MNG_LOOPWITHCACHEOFF (mng_retcode)17 /* LOOP when playback info off */
+
+#define MNG_DLLNOTLOADED (mng_retcode)99 /* late binding failed */
+
+#define MNG_APPIOERROR (mng_retcode)901 /* application I/O error */
+#define MNG_APPTIMERERROR (mng_retcode)902 /* application timing error */
+#define MNG_APPCMSERROR (mng_retcode)903 /* application CMS error */
+#define MNG_APPMISCERROR (mng_retcode)904 /* application other error */
+#define MNG_APPTRACEABORT (mng_retcode)905 /* application aborts on trace */
+
+#define MNG_INTERNALERROR (mng_retcode)999 /* internal inconsistancy */
+
+#define MNG_INVALIDSIG (mng_retcode)1025 /* invalid graphics file */
+#define MNG_INVALIDCRC (mng_retcode)1027 /* crc check failed */
+#define MNG_INVALIDLENGTH (mng_retcode)1028 /* chunklength mystifies me */
+#define MNG_SETQUENCEERROR (mng_retcode)1029 /* invalid chunk sequence */
+#define MNG_CHUNKNOTALLOWED (mng_retcode)1030 /* completely out-of-place */
+#define MNG_MULTIPLEERROR (mng_retcode)1031 /* only one occurence allowed */
+#define MNG_PLTEMISSING (mng_retcode)1032 /* indexed-color requires PLTE */
+#define MNG_IDATMISSING (mng_retcode)1033 /* IHDR-block requires IDAT */
+#define MNG_CANNOTBEEMPTY (mng_retcode)1034 /* must contain some data */
+#define MNG_GLOBALLENGTHERR (mng_retcode)1035 /* global data incorrect */
+#define MNG_INVALIDBITDEPTH (mng_retcode)1036 /* bitdepth out-of-range */
+#define MNG_INVALIDCOLORTYPE (mng_retcode)1037 /* colortype out-of-range */
+#define MNG_INVALIDCOMPRESS (mng_retcode)1038 /* compression method invalid */
+#define MNG_INVALIDFILTER (mng_retcode)1039 /* filter method invalid */
+#define MNG_INVALIDINTERLACE (mng_retcode)1040 /* interlace method invalid */
+#define MNG_NOTENOUGHIDAT (mng_retcode)1041 /* ran out of compressed data */
+#define MNG_PLTEINDEXERROR (mng_retcode)1042 /* palette-index out-of-range */
+#define MNG_NULLNOTFOUND (mng_retcode)1043 /* couldn't tqfind null-separator*/
+#define MNG_KEYWORDNULL (mng_retcode)1044 /* keyword cannot be empty */
+#define MNG_OBJECTUNKNOWN (mng_retcode)1045 /* the object can't be found */
+#define MNG_OBJECTEXISTS (mng_retcode)1046 /* the object already exists */
+#define MNG_TOOMUCHIDAT (mng_retcode)1047 /* got too much compressed data*/
+#define MNG_INVSAMPLEDEPTH (mng_retcode)1048 /* sampledepth out-of-range */
+#define MNG_INVOFFSETSIZE (mng_retcode)1049 /* invalid offset-size */
+#define MNG_INVENTRYTYPE (mng_retcode)1050 /* invalid entry-type */
+#define MNG_ENDWITHNULL (mng_retcode)1051 /* may not end with NULL */
+#define MNG_INVIMAGETYPE (mng_retcode)1052 /* invalid image_type */
+#define MNG_INVDELTATYPE (mng_retcode)1053 /* invalid delta_type */
+#define MNG_INVALIDINDEX (mng_retcode)1054 /* index-value invalid */
+#define MNG_TOOMUCHJDAT (mng_retcode)1055 /* got too much compressed data*/
+#define MNG_JPEGPARMSERR (mng_retcode)1056 /* JHDR/JPEG parms do not match*/
+#define MNG_INVFILLTQT_METHOD (mng_retcode)1057 /* invalid fill_method */
+#define MNG_OBJNOTCONCRETE (mng_retcode)1058 /* object must be concrete */
+#define MNG_TARGETNOALPHA (mng_retcode)1059 /* object has no alpha-channel */
+#define MNG_MNGTOOCOMPLEX (mng_retcode)1060 /* can't handle complexity */
+#define MNG_UNKNOWNCRITICAL (mng_retcode)1061 /* unknown critical chunk found*/
+#define MNG_UNSUPPORTEDNEED (mng_retcode)1062 /* nEED requirement unsupported*/
+#define MNG_INVALIDDELTA (mng_retcode)1063 /* Delta operation illegal */
+#define MNG_INVALIDTQT_METHOD (mng_retcode)1064 /* invalid MAGN method */
+
+#define MNG_INVALIDCNVSTYLE (mng_retcode)2049 /* can't make anything of this */
+#define MNG_WRONGCHUNK (mng_retcode)2050 /* accessing the wrong chunk */
+#define MNG_INVALIDENTRYIX (mng_retcode)2051 /* accessing the wrong entry */
+#define MNG_NOHEADER (mng_retcode)2052 /* must have had header first */
+#define MNG_NOCORRCHUNK (mng_retcode)2053 /* can't tqfind tqparent chunk */
+#define MNG_NOMHDR (mng_retcode)2054 /* no MNG header available */
+
+#define MNG_IMAGETOOLARGE (mng_retcode)4097 /* input-image way too big */
+#define MNG_NOTANANIMATION (mng_retcode)4098 /* file not a MNG */
+#define MNG_FRAMENRTOOHIGH (mng_retcode)4099 /* frame-nr out-of-range */
+#define MNG_LAYERNRTOOHIGH (mng_retcode)4100 /* layer-nr out-of-range */
+#define MNG_PLAYTIMETOOHIGH (mng_retcode)4101 /* playtime out-of-range */
+#define MNG_FNNOTIMPLEMENTED (mng_retcode)4102 /* function not yet available */
+
+#define MNG_IMAGEFROZEN (mng_retcode)8193 /* stopped displaying */
+
+#define MNG_LCMS_NOHANDLE 1 /* LCMS returned NULL handle */
+#define MNG_LCMS_NOMEM 2 /* LCMS returned NULL gammatab */
+#define MNG_LCMS_NOTRANS 3 /* LCMS returned NULL transform*/
+
+/* ************************************************************************** */
+/* * * */
+/* * Canvas styles * */
+/* * * */
+/* * Note that the intentions are pretty darn good, but that the focus * */
+/* * is currently on 8-bit color support * */
+/* * * */
+/* * The RGB8_A8 style is defined for apps that require a separate * */
+/* * canvas for the color-planes and the alpha-plane (eg. mozilla) * */
+/* * This requires for the app to supply the "getalphaline" callback!!! * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_CANVAS_RGB8 0x00000000L
+#define MNG_CANVAS_RGBA8 0x00001000L
+#define MNG_CANVAS_ARGB8 0x00003000L
+#define MNG_CANVAS_RGB8_A8 0x00005000L
+#define MNG_CANVAS_BGR8 0x00000001L
+#define MNG_CANVAS_BGRA8 0x00001001L
+#define MNG_CANVAS_BGRA8PM 0x00009001L
+#define MNG_CANVAS_ABGR8 0x00003001L
+#define MNG_CANVAS_RGB16 0x00000100L /* not supported yet */
+#define MNG_CANVAS_RGBA16 0x00001100L /* not supported yet */
+#define MNG_CANVAS_ARGB16 0x00003100L /* not supported yet */
+#define MNG_CANVAS_BGR16 0x00000101L /* not supported yet */
+#define MNG_CANVAS_BGRA16 0x00001101L /* not supported yet */
+#define MNG_CANVAS_ABGR16 0x00003101L /* not supported yet */
+#define MNG_CANVAS_GRAY8 0x00000002L /* not supported yet */
+#define MNG_CANVAS_GRAY16 0x00000102L /* not supported yet */
+#define MNG_CANVAS_GRAYA8 0x00001002L /* not supported yet */
+#define MNG_CANVAS_GRAYA16 0x00001102L /* not supported yet */
+#define MNG_CANVAS_AGRAY8 0x00003002L /* not supported yet */
+#define MNG_CANVAS_AGRAY16 0x00003102L /* not supported yet */
+#define MNG_CANVAS_DX15 0x00000003L /* not supported yet */
+#define MNG_CANVAS_DX16 0x00000004L /* not supported yet */
+
+#define MNG_CANVAS_PIXELTYPE(C) (C & 0x000000FFL)
+#define MNG_CANVAS_BITDEPTH(C) (C & 0x00000100L)
+#define MNG_CANVAS_HASALPHA(C) (C & 0x00001000L)
+#define MNG_CANVAS_ALPHAFIRST(C) (C & 0x00002000L)
+#define MNG_CANVAS_ALPHASEPD(C) (C & 0x00004000L)
+#define MNG_CANVAS_ALPHAPM(C) (C & 0x00008000L)
+
+#define MNG_CANVAS_RGB(C) (MNG_CANVAS_PIXELTYPE (C) == 0)
+#define MNG_CANVAS_BGR(C) (MNG_CANVAS_PIXELTYPE (C) == 1)
+#define MNG_CANVAS_GRAY(C) (MNG_CANVAS_PIXELTYPE (C) == 2)
+#define MNG_CANVAS_DIRECTX15(C) (MNG_CANVAS_PIXELTYPE (C) == 3)
+#define MNG_CANVAS_DIRECTX16(C) (MNG_CANVAS_PIXELTYPE (C) == 4)
+#define MNG_CANVAS_8BIT(C) (!MNG_CANVAS_BITDEPTH (C))
+#define MNG_CANVAS_16BIT(C) (MNG_CANVAS_BITDEPTH (C))
+#define MNG_CANVAS_PIXELFIRST(C) (!MNG_CANVAS_ALPHAFIRST (C))
+
+/* ************************************************************************** */
+/* * * */
+/* * Chunk names (idea adapted from libpng 1.1.0 - png.h) * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_UINT_HUH 0x40404040L
+
+#define MNG_UINT_BACK 0x4241434bL
+#define MNG_UINT_BASI 0x42415349L
+#define MNG_UINT_CLIP 0x434c4950L
+#define MNG_UINT_CLON 0x434c4f4eL
+#define MNG_UINT_DBYK 0x4442594bL
+#define MNG_UINT_DEFI 0x44454649L
+#define MNG_UINT_DHDR 0x44484452L
+#define MNG_UINT_DISC 0x44495343L
+#define MNG_UINT_DROP 0x44524f50L
+#define MNG_UINT_ENDL 0x454e444cL
+#define MNG_UINT_FRAM 0x4652414dL
+#define MNG_UINT_IDAT 0x49444154L
+#define MNG_UINT_IEND 0x49454e44L
+#define MNG_UINT_IHDR 0x49484452L
+#define MNG_UINT_IJNG 0x494a4e47L
+#define MNG_UINT_IPNG 0x49504e47L
+#define MNG_UINT_JDAA 0x4a444141L
+#define MNG_UINT_JDAT 0x4a444154L
+#define MNG_UINT_JHDR 0x4a484452L
+#define MNG_UINT_JSEP 0x4a534550L
+#define MNG_UINT_JdAA 0x4a644141L
+#define MNG_UINT_LOOP 0x4c4f4f50L
+#define MNG_UINT_MAGN 0x4d41474eL
+#define MNG_UINT_MEND 0x4d454e44L
+#define MNG_UINT_MHDR 0x4d484452L
+#define MNG_UINT_MOVE 0x4d4f5645L
+#define MNG_UINT_ORDR 0x4f524452L
+#define MNG_UINT_PAST 0x50415354L
+#define MNG_UINT_PLTE 0x504c5445L
+#define MNG_UINT_PPLT 0x50504c54L
+#define MNG_UINT_PROM 0x50524f4dL
+#define MNG_UINT_SAVE 0x53415645L
+#define MNG_UINT_SEEK 0x5345454bL
+#define MNG_UINT_SHOW 0x53484f57L
+#define MNG_UINT_TERM 0x5445524dL
+#define MNG_UINT_bKGD 0x624b4744L
+#define MNG_UINT_cHRM 0x6348524dL
+#define MNG_UINT_eXPI 0x65585049L
+#define MNG_UINT_fPRI 0x66505249L
+#define MNG_UINT_gAMA 0x67414d41L
+#define MNG_UINT_hIST 0x68495354L
+#define MNG_UINT_iCCP 0x69434350L
+#define MNG_UINT_iTXt 0x69545874L
+#define MNG_UINT_nEED 0x6e454544L
+#define MNG_UINT_oFFs 0x6f464673L
+#define MNG_UINT_pCAL 0x7043414cL
+#define MNG_UINT_pHYg 0x70444167L
+#define MNG_UINT_pHYs 0x70485973L
+#define MNG_UINT_sBIT 0x73424954L
+#define MNG_UINT_sCAL 0x7343414cL
+#define MNG_UINT_sPLT 0x73504c54L
+#define MNG_UINT_sRGB 0x73524742L
+#define MNG_UINT_tEXt 0x74455874L
+#define MNG_UINT_tIME 0x74494d45L
+#define MNG_UINT_tRNS 0x74524e53L
+#define MNG_UINT_zTXt 0x7a545874L
+
+/* ************************************************************************** */
+/* * * */
+/* * Chunk property values * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_BITDEPTH_1 1 /* IHDR, BASI, JHDR, PROM */
+#define MNG_BITDEPTH_2 2
+#define MNG_BITDEPTH_4 4
+#define MNG_BITDEPTH_8 8 /* sPLT */
+#define MNG_BITDEPTH_16 16
+
+#define MNG_COLORTYPE_GRAY 0 /* IHDR, BASI, PROM */
+#define MNG_COLORTYPE_RGB 2
+#define MNG_COLORTYPE_INDEXED 3
+#define MNG_COLORTYPE_GRAYA 4
+#define MNG_COLORTYPE_RGBA 6
+
+#define MNG_COMPRESSION_DEFLATE 0 /* IHDR, zTXt, iTXt, iCCP,
+ BASI, JHDR */
+
+#define MNG_FILTER_ADAPTIVE 0 /* IHDR, BASI, JHDR */
+/* #define MNG_FILTER_NO_ADAPTIVE 1 */
+#define MNG_FILTER_NO_DIFFERING 0
+#define MNG_FILTER_DIFFERING 0x40
+/* #define MNG_FILTER_MASK (MNG_FILTER_NO_ADAPTIVE | MNG_FILTER_DIFFERING) */
+
+#define MNG_INTERLACE_NONE 0 /* IHDR, BASI, JHDR */
+#define MNG_INTERLACE_ADAM7 1
+
+#define MNG_FILTER_NONE 0 /* IDAT */
+#define MNG_FILTER_SUB 1
+#define MNG_FILTER_UP 2
+#define MNG_FILTER_AVERAGE 3
+#define MNG_FILTER_PAETH 4
+
+#define MNG_INTENT_PERCEPTUAL 0 /* sRGB */
+#define MNG_INTENT_RELATIVECOLORIMETRIC 1
+#define MNG_INTENT_SATURATION 2
+#define MNG_INTENT_ABSOLUTECOLORIMETRIC 3
+ /* tEXt, zTXt, iTXt */
+#define MNG_TEXT_TITLE "Title"
+#define MNG_TEXT_AUTHOR "Author"
+#define MNG_TEXT_DESCRIPTION "Description"
+#define MNG_TEXT_COPYRIGHT "Copyright"
+#define MNG_TEXT_CREATIONTIME "Creation Time"
+#define MNG_TEXT_SOFTWARE "Software"
+#define MNG_TEXT_DISCLAIMER "Disclaimer"
+#define MNG_TEXT_WARNING "Warning"
+#define MNG_TEXT_SOURCE "Source"
+#define MNG_TEXT_COMMENT "Comment"
+
+#define MNG_FLAG_UNCOMPRESSED 0 /* iTXt */
+#define MNG_FLAG_COMPRESSED 1
+
+#define MNG_UNIT_UNKNOWN 0 /* pHYs, pHYg */
+#define MNG_UNIT_METER 1
+ /* MHDR */
+#define MNG_SIMPLICITY_VALID 0x00000001
+#define MNG_SIMPLICITY_SIMPLEFEATURES 0x00000002
+#define MNG_SIMPLICITY_COMPLEXFEATURES 0x00000004
+#define MNG_SIMPLICITY_TRANSPARENCY 0x00000008
+#define MNG_SIMPLICITY_JNG 0x00000010
+#define MNG_SIMPLICITY_DELTAPNG 0x00000020
+
+#define MNG_TERMINATION_DECODER_NC 0 /* LOOP */
+#define MNG_TERMINATION_USER_NC 1
+#define MNG_TERMINATION_EXTERNAL_NC 2
+#define MNG_TERMINATION_DETERMINISTIC_NC 3
+#define MNG_TERMINATION_DECODER_C 4
+#define MNG_TERMINATION_USER_C 5
+#define MNG_TERMINATION_EXTERNAL_C 6
+#define MNG_TERMINATION_DETERMINISTIC_C 7
+
+#define MNG_DONOTSHOW_VISIBLE 0 /* DEFI */
+#define MNG_DONOTSHOW_NOTVISIBLE 1
+
+#define MNG_ABSTRACT 0 /* DEFI */
+#define MNG_CONCRETE 1
+
+#define MNG_NOTVIEWABLE 0 /* BASI */
+#define MNG_VIEWABLE 1
+
+#define MNG_FULL_CLONE 0 /* CLON */
+#define MNG_PARTIAL_CLONE 1
+#define MNG_RENUMBER 2
+
+#define MNG_CONCRETE_ASPARENT 0 /* CLON */
+#define MNG_CONCRETE_MAKEABSTRACT 1
+
+#define MNG_LOCATION_ABSOLUTE 0 /* CLON, MOVE */
+#define MNG_LOCATION_RELATIVE 1
+
+#define MNG_TARGET_ABSOLUTE 0 /* PAST */
+#define MNG_TARGET_RELATIVE_SAMEPAST 1
+#define MNG_TARGET_RELATIVE_PREVPAST 2
+
+#define MNG_COMPOSITE_OVER 0 /* PAST */
+#define MNG_COMPOSITE_REPLACE 1
+#define MNG_COMPOSITE_UNDER 2
+
+#define MNG_ORIENTATION_SAME 0 /* PAST */
+#define MNG_ORIENTATION_180DEG 2
+#define MNG_ORIENTATION_FLIPHORZ 4
+#define MNG_ORIENTATION_FLIPVERT 6
+#define MNG_ORIENTATION_TILED 8
+
+#define MNG_OFFSET_ABSOLUTE 0 /* PAST */
+#define MNG_OFFSET_RELATIVE 1
+
+#define MNG_BOUNDARY_ABSOLUTE 0 /* PAST, FRAM */
+#define MNG_BOUNDARY_RELATIVE 1
+
+#define MNG_BACKGROUNDCOLOR_MANDATORY 0x01 /* BACK */
+#define MNG_BACKGROUNDIMAGE_MANDATORY 0x02 /* BACK */
+
+#define MNG_BACKGROUNDIMAGE_NOTILE 0 /* BACK */
+#define MNG_BACKGROUNDIMAGE_TILE 1
+
+#define MNG_FRAMINGMODE_NOCHANGE 0 /* FRAM */
+#define MNG_FRAMINGMODE_1 1
+#define MNG_FRAMINGMODE_2 2
+#define MNG_FRAMINGMODE_3 3
+#define MNG_FRAMINGMODE_4 4
+
+#define MNG_CHANGEDELAY_NO 0 /* FRAM */
+#define MNG_CHANGEDELAY_NEXTSUBFRAME 1
+#define MNG_CHANGEDELAY_DEFAULT 2
+
+#define MNG_CHANGETIMOUT_NO 0 /* FRAM */
+#define MNG_CHANGETIMOUT_DETERMINISTIC_1 1
+#define MNG_CHANGETIMOUT_DETERMINISTIC_2 2
+#define MNG_CHANGETIMOUT_DECODER_1 3
+#define MNG_CHANGETIMOUT_DECODER_2 4
+#define MNG_CHANGETIMOUT_USER_1 5
+#define MNG_CHANGETIMOUT_USER_2 6
+#define MNG_CHANGETIMOUT_EXTERNAL_1 7
+#define MNG_CHANGETIMOUT_EXTERNAL_2 8
+
+#define MNG_CHANGECLIPPING_NO 0 /* FRAM */
+#define MNG_CHANGECLIPPING_NEXTSUBFRAME 1
+#define MNG_CHANGECLIPPING_DEFAULT 2
+
+#define MNG_CHANGESYNCID_NO 0 /* FRAM */
+#define MNG_CHANGESYNCID_NEXTSUBFRAME 1
+#define MNG_CHANGESYNCID_DEFAULT 2
+
+#define MNG_CLIPPING_ABSOLUTE 0 /* CLIP */
+#define MNG_CLIPPING_RELATIVE 1
+
+#define MNG_SHOWMODE_0 0 /* SHOW */
+#define MNG_SHOWMODE_1 1
+#define MNG_SHOWMODE_2 2
+#define MNG_SHOWMODE_3 3
+#define MNG_SHOWMODE_4 4
+#define MNG_SHOWMODE_5 5
+#define MNG_SHOWMODE_6 6
+#define MNG_SHOWMODE_7 7
+
+#define MNG_TERMACTION_LASTFRAME 0 /* TERM */
+#define MNG_TERMACTION_CLEAR 1
+#define MNG_TERMACTION_FIRSTFRAME 2
+#define MNG_TERMACTION_REPEAT 3
+
+#define MNG_ITERACTION_LASTFRAME 0 /* TERM */
+#define MNG_ITERACTION_CLEAR 1
+#define MNG_ITERACTION_FIRSTFRAME 2
+
+#define MNG_SAVEOFFSET_4BYTE 4 /* SAVE */
+#define MNG_SAVEOFFSET_8BYTE 8
+
+#define MNG_SAVEENTRY_SEGMENTFULL 0 /* SAVE */
+#define MNG_SAVEENTRY_SEGMENT 1
+#define MNG_SAVEENTRY_SUBFRAME 2
+#define MNG_SAVEENTRY_EXPORTEDIMAGE 3
+
+#define MNG_PRIORITY_ABSOLUTE 0 /* fPRI */
+#define MNG_PRIORITY_RELATIVE 1
+
+#ifdef MNG_INCLUDE_JNG
+#define MNG_COLORTYPE_JPEGGRAY 8 /* JHDR */
+#define MNG_COLORTYPE_JPEGCOLOR 10
+#define MNG_COLORTYPE_JPEGGRAYA 12
+#define MNG_COLORTYPE_JPEGCOLORA 14
+
+#define MNG_BITDEPTH_JPEG8 8 /* JHDR */
+#define MNG_BITDEPTH_JPEG12 12
+#define MNG_BITDEPTH_JPEG8AND12 20
+
+#define MNG_COMPRESSION_BASELINEJPEG 8 /* JHDR */
+
+#define MNG_INTERLACE_SETQUENTIAL 0 /* JHDR */
+#define MNG_INTERLACE_PROGRESSIVE 8
+#endif /* MNG_INCLUDE_JNG */
+
+#define MNG_IMAGETYPE_UNKNOWN 0 /* DHDR */
+#define MNG_IMAGETYPE_PNG 1
+#define MNG_IMAGETYPE_JNG 2
+
+#define MNG_DELTATYPE_REPLACE 0 /* DHDR */
+#define MNG_DELTATYPE_BLOCKPIXELADD 1
+#define MNG_DELTATYPE_BLOCKALPHAADD 2
+#define MNG_DELTATYPE_BLOCKCOLORADD 3
+#define MNG_DELTATYPE_BLOCKPIXELREPLACE 4
+#define MNG_DELTATYPE_BLOCKALPHAREPLACE 5
+#define MNG_DELTATYPE_BLOCKCOLORREPLACE 6
+#define MNG_DELTATYPE_NOCHANGE 7
+
+#define MNG_FILLMETHOD_LEFTBITREPLICATE 0 /* PROM */
+#define MNG_FILLMETHOD_ZEROFILL 1
+
+#define MNG_DELTATYPE_REPLACERGB 0 /* PPLT */
+#define MNG_DELTATYPE_DELTARGB 1
+#define MNG_DELTATYPE_REPLACEALPHA 2
+#define MNG_DELTATYPE_DELTAALPHA 3
+#define MNG_DELTATYPE_REPLACERGBA 4
+#define MNG_DELTATYPE_DELTARGBA 5
+
+#define MNG_POLARITY_ONLY 0 /* DBYK */
+#define MNG_POLARITY_ALLBUT 1
+
+/* ************************************************************************** */
+/* * * */
+/* * Processtext callback types * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_TYPE_TEXT 0
+#define MNG_TYPE_ZTXT 1
+#define MNG_TYPE_ITXT 2
+
+/* ************************************************************************** */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _libmng_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_callback_xs.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_callback_xs.c
new file mode 100644
index 0000000..690b3a8
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_callback_xs.c
@@ -0,0 +1,1147 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_callback_xs.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.2 * */
+/* * * */
+/* * purpose : callback get/set interface (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the callback get/set functions * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - fixed calling convention * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * * */
+/* * 0.5.2 - 05/31/2000 - G.Juyn * */
+/* * - fixed up punctuation (contribution by Tim Rowley) * */
+/* * 0.5.2 - 06/02/2000 - G.Juyn * */
+/* * - added getalphaline callback for RGB8_A8 canvasstyle * */
+/* * * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - added callbacks for SAVE/SEEK processing * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - added support for nEED * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - added callback to process non-critical unknown chunks * */
+/* * * */
+/* * 1.0.1 - 02/08/2001 - G.Juyn * */
+/* * - added MEND processing callback * */
+/* * * */
+/* * 1.0.2 - 06/23/2001 - G.Juyn * */
+/* * - added processterm callback * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Callback set functions * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_INTERNAL_MEMMNGMT
+mng_retcode MNG_DECL mng_setcb_memalloc (mng_handle hHandle,
+ mng_memalloc fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_MEMALLOC, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fMemalloc = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_MEMALLOC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INTERNAL_MEMMNGMT */
+
+/* ************************************************************************** */
+
+#ifndef MNG_INTERNAL_MEMMNGMT
+mng_retcode MNG_DECL mng_setcb_memfree (mng_handle hHandle,
+ mng_memfree fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_MEMFREE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fMemfree = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_MEMFREE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INTERNAL_MEMMNGMT */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+mng_retcode MNG_DECL mng_setcb_openstream (mng_handle hHandle,
+ mng_openstream fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_OPENSTREAM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fOpenstream = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_OPENSTREAM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+mng_retcode MNG_DECL mng_setcb_closestream (mng_handle hHandle,
+ mng_closestream fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_CLOSESTREAM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fClosestream = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_CLOSESTREAM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_setcb_readdata (mng_handle hHandle,
+ mng_readdata fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_READDATA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fReaddata = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_READDATA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_WRITE
+mng_retcode MNG_DECL mng_setcb_writedata (mng_handle hHandle,
+ mng_writedata fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_WRITEDATA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fWritedata = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_WRITEDATA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_WRITE */
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_setcb_errorproc (mng_handle hHandle,
+ mng_errorproc fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_ERRORPROC, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fErrorproc = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_ERRORPROC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_TRACE
+mng_retcode MNG_DECL mng_setcb_traceproc (mng_handle hHandle,
+ mng_traceproc fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_TRACEPROC, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fTraceproc = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_TRACEPROC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_TRACE */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_setcb_processheader (mng_handle hHandle,
+ mng_processheader fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSHEADER, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcessheader = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSHEADER, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_setcb_processtext (mng_handle hHandle,
+ mng_processtext fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSTEXT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcesstext = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSTEXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_setcb_processsave (mng_handle hHandle,
+ mng_processsave fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSAVE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcesssave = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSAVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_setcb_processseek (mng_handle hHandle,
+ mng_processseek fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSEEK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcessseek = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSEEK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_setcb_processneed (mng_handle hHandle,
+ mng_processneed fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSNEED, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcessneed = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSNEED, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_setcb_processmend (mng_handle hHandle,
+ mng_processmend fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSMEND, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcessmend = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSMEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_setcb_processunknown (mng_handle hHandle,
+ mng_processunknown fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSUNKNOWN, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcessunknown = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSUNKNOWN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_setcb_processterm (mng_handle hHandle,
+ mng_processterm fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSTERM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcessterm = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSTERM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_setcb_getcanvasline (mng_handle hHandle,
+ mng_getcanvasline fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETCANVASLINE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fGetcanvasline = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETCANVASLINE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_setcb_getbkgdline (mng_handle hHandle,
+ mng_getbkgdline fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETBKGDLINE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fGetbkgdline = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETBKGDLINE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_setcb_getalphaline (mng_handle hHandle,
+ mng_getalphaline fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETALPHALINE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fGetalphaline = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETALPHALINE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_setcb_refresh (mng_handle hHandle,
+ mng_refresh fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_REFRESH, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fRefresh = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_REFRESH, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_setcb_gettickcount (mng_handle hHandle,
+ mng_gettickcount fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETTICKCOUNT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fGettickcount = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_GETTICKCOUNT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_setcb_settimer (mng_handle hHandle,
+ mng_settimer fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_SETTIMER, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fSettimer = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_SETTIMER, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
+mng_retcode MNG_DECL mng_setcb_processgamma (mng_handle hHandle,
+ mng_processgamma fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSGAMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcessgamma = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSGAMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
+mng_retcode MNG_DECL mng_setcb_processchroma (mng_handle hHandle,
+ mng_processchroma fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSCHROMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcesschroma = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSCHROMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
+mng_retcode MNG_DECL mng_setcb_processsrgb (mng_handle hHandle,
+ mng_processsrgb fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSRGB, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcesssrgb = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSSRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
+mng_retcode MNG_DECL mng_setcb_processiccp (mng_handle hHandle,
+ mng_processiccp fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSICCP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcessiccp = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSICCP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
+mng_retcode MNG_DECL mng_setcb_processarow (mng_handle hHandle,
+ mng_processarow fProc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSAROW, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->fProcessarow = fProc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SETCB_PROCESSAROW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
+
+/* ************************************************************************** */
+/* * * */
+/* * Callback get functions * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_INTERNAL_MEMMNGMT
+mng_memalloc MNG_DECL mng_getcb_memalloc (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_MEMALLOC, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_MEMALLOC, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fMemalloc;
+}
+#endif /* MNG_INTERNAL_MEMMNGMT */
+
+/* ************************************************************************** */
+
+#ifndef MNG_INTERNAL_MEMMNGMT
+mng_memfree MNG_DECL mng_getcb_memfree (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_MEMFREE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_MEMFREE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fMemfree;
+}
+#endif /* MNG_INTERNAL_MEMMNGMT */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_readdata MNG_DECL mng_getcb_readdata (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_READDATA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_READDATA, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fReaddata;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+mng_openstream MNG_DECL mng_getcb_openstream (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_OPENSTREAM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_OPENSTREAM, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fOpenstream;
+}
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+mng_closestream MNG_DECL mng_getcb_closestream (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_CLOSESTREAM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_CLOSESTREAM, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fClosestream;
+}
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_WRITE
+mng_writedata MNG_DECL mng_getcb_writedata (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_WRITEDATA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_WRITEDATA, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fWritedata;
+}
+#endif /* MNG_SUPPORT_WRITE */
+
+/* ************************************************************************** */
+
+mng_errorproc MNG_DECL mng_getcb_errorproc (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_ERRORPROC, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_ERRORPROC, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fErrorproc;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_TRACE
+mng_traceproc MNG_DECL mng_getcb_traceproc (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_TRACEPROC, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_TRACEPROC, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fTraceproc;
+}
+#endif /* MNG_SUPPORT_TRACE */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_processheader MNG_DECL mng_getcb_processheader (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSHEADER, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSHEADER, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcessheader;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_processtext MNG_DECL mng_getcb_processtext (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSTEXT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSTEXT, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcesstext;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_processsave MNG_DECL mng_getcb_processsave (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSAVE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSAVE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcesssave;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_processseek MNG_DECL mng_getcb_processseek (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSEEK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSEEK, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcessseek;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_processneed MNG_DECL mng_getcb_processneed (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSNEED, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSNEED, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcessneed;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_processmend MNG_DECL mng_getcb_processmend (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSMEND, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSMEND, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcessmend;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_processunknown MNG_DECL mng_getcb_processunknown (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSUNKNOWN, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSUNKNOWN, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcessunknown;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_processterm MNG_DECL mng_getcb_processterm (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSTERM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSTERM, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcessterm;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_getcanvasline MNG_DECL mng_getcb_getcanvasline (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETCANVASLINE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETCANVASLINE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fGetcanvasline;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_getbkgdline MNG_DECL mng_getcb_getbkgdline (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETBKGDLINE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETBKGDLINE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fGetbkgdline;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_getalphaline MNG_DECL mng_getcb_getalphaline (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETALPHALINE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETALPHALINE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fGetalphaline;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_refresh MNG_DECL mng_getcb_refresh (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_REFRESH, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_REFRESH, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fRefresh;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_gettickcount MNG_DECL mng_getcb_gettickcount (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETTICKCOUNT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_GETTICKCOUNT, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fGettickcount;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_settimer MNG_DECL mng_getcb_settimer (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_SETTIMER, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_SETTIMER, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fSettimer;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
+mng_processgamma MNG_DECL mng_getcb_processgamma (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSGAMMA, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcessgamma;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
+mng_processchroma MNG_DECL mng_getcb_processchroma (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSCHROMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSCHROMA, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcesschroma;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
+mng_processsrgb MNG_DECL mng_getcb_processsrgb (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSRGB, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSSRGB, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcesssrgb;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
+mng_processiccp MNG_DECL mng_getcb_processiccp (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSICCP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSICCP, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcessiccp;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_APP_CMS)
+mng_processarow MNG_DECL mng_getcb_processarow (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSAROW, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GETCB_PROCESSAROW, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->fProcessarow;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_APP_CMS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_io.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_io.c
new file mode 100644
index 0000000..c7dc233
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_io.c
@@ -0,0 +1,8817 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_chunk_io.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.2 * */
+/* * * */
+/* * purpose : Chunk I/O routines (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of chunk input/output routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/01/2000 - G.Juyn * */
+/* * - cleaned up left-over teststuff in the BACK chunk routine * */
+/* * 0.5.1 - 05/04/2000 - G.Juyn * */
+/* * - changed CRC initialization to use dynamic structure * */
+/* * (wasn't thread-safe the old way !) * */
+/* * 0.5.1 - 05/06/2000 - G.Juyn * */
+/* * - filled in many missing sequence&length checks * */
+/* * - filled in many missing chunk-store snippets * */
+/* * 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - added checks for running animations * */
+/* * - filled some write routines * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/10/2000 - G.Juyn * */
+/* * - filled some more write routines * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - filled remaining write routines * */
+/* * - fixed read_pplt with regard to deltatype * */
+/* * - added callback error-reporting support * */
+/* * - added pre-draft48 support (short MHDR, frame_mode, LOOP) * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * - fixed chunk-storage bit in several routines * */
+/* * 0.5.1 - 05/13/2000 - G.Juyn * */
+/* * - added eMNGma hack (will be removed in 1.0.0 !!!) * */
+/* * - added TERM animation object pointer (easier reference) * */
+/* * - supplemented the SAVE & SEEK display processing * */
+/* * * */
+/* * 0.5.2 - 05/18/2000 - G.Juyn * */
+/* * - B004 - fixed problem with MNG_SUPPORT_WRITE not defined * */
+/* * also for MNG_SUPPORT_WRITE without MNG_INCLUDE_JNG * */
+/* * 0.5.2 - 05/19/2000 - G.Juyn * */
+/* * - cleaned up some code regarding mixed support * */
+/* * 0.5.2 - 05/20/2000 - G.Juyn * */
+/* * - implemented JNG support * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - added support for global color-chunks in animation * */
+/* * - added support for global PLTE,tRNS,bKGD in animation * */
+/* * - added support for SAVE & SEEK in animation * */
+/* * 0.5.2 - 05/29/2000 - G.Juyn * */
+/* * - changed ani_create calls not returning object pointer * */
+/* * - create ani objects always (not just inside TERM/LOOP) * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added support for delta-image processing * */
+/* * 0.5.2 - 05/31/2000 - G.Juyn * */
+/* * - fixed up punctuation (contributed by Tim Rowley) * */
+/* * 0.5.2 - 06/02/2000 - G.Juyn * */
+/* * - changed SWAP_ENDIAN to BIGENDIAN_SUPPORTED * */
+/* * 0.5.2 - 06/03/2000 - G.Juyn * */
+/* * - fixed makeup for Linux gcc compile * */
+/* * * */
+/* * 0.5.3 - 06/12/2000 - G.Juyn * */
+/* * - added processing of color-info on delta-image * */
+/* * 0.5.3 - 06/13/2000 - G.Juyn * */
+/* * - fixed handling of empty SAVE chunk * */
+/* * 0.5.3 - 06/17/2000 - G.Juyn * */
+/* * - changed to support delta-images * */
+/* * - added extra checks for delta-images * */
+/* * 0.5.3 - 06/20/2000 - G.Juyn * */
+/* * - fixed possible trouble if IEND display-process got * */
+/* * broken up * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added processing of PLTE & tRNS for delta-images * */
+/* * - added administration of imagelevel parameter * */
+/* * 0.5.3 - 06/22/2000 - G.Juyn * */
+/* * - implemented support for PPLT chunk * */
+/* * 0.5.3 - 06/26/2000 - G.Juyn * */
+/* * - added precaution against faulty iCCP chunks from PS * */
+/* * 0.5.3 - 06/29/2000 - G.Juyn * */
+/* * - fixed some 64-bit warnings * */
+/* * * */
+/* * 0.9.1 - 07/14/2000 - G.Juyn * */
+/* * - changed pre-draft48 frame_mode=3 to frame_mode=1 * */
+/* * 0.9.1 - 07/16/2000 - G.Juyn * */
+/* * - fixed storage of images during mng_read() * */
+/* * - fixed support for mng_display() after mng_read() * */
+/* * 0.9.1 - 07/19/2000 - G.Juyn * */
+/* * - fixed several chunk-writing routines * */
+/* * 0.9.1 - 07/24/2000 - G.Juyn * */
+/* * - fixed reading of still-images * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/07/2000 - G.Juyn * */
+/* * - B111300 - fixup for improved portability * */
+/* * 0.9.3 - 08/08/2000 - G.Juyn * */
+/* * - fixed compiler-warnings from Mozilla * */
+/* * 0.9.3 - 08/09/2000 - G.Juyn * */
+/* * - added check for simplicity-bits in MHDR * */
+/* * 0.9.3 - 08/12/2000 - G.Juyn * */
+/* * - fixed check for simplicity-bits in MHDR (JNG) * */
+/* * 0.9.3 - 08/12/2000 - G.Juyn * */
+/* * - added workaround for faulty PhotoShop iCCP chunk * */
+/* * 0.9.3 - 08/22/2000 - G.Juyn * */
+/* * - fixed write-code for zTXt & iTXt * */
+/* * - fixed read-code for iTXt * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * 0.9.3 - 09/10/2000 - G.Juyn * */
+/* * - fixed DEFI behavior * */
+/* * 0.9.3 - 10/02/2000 - G.Juyn * */
+/* * - fixed simplicity-check in compliance with draft 81/0.98a * */
+/* * 0.9.3 - 10/10/2000 - G.Juyn * */
+/* * - added support for alpha-depth prediction * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - added support for nEED * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added support for JDAA * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - fixed support for MAGN * */
+/* * - implemented nEED "xxxx" (where "xxxx" is a chunkid) * */
+/* * - added callback to process non-critical unknown chunks * */
+/* * - fixed support for bKGD * */
+/* * 0.9.3 - 10/23/2000 - G.Juyn * */
+/* * - fixed bug in empty PLTE handling * */
+/* * * */
+/* * 0.9.4 - 11/20/2000 - G.Juyn * */
+/* * - changed IHDR filter_method check for PNGs * */
+/* * 0.9.4 - 1/18/2001 - G.Juyn * */
+/* * - added errorchecking for MAGN methods * */
+/* * - removed test filter-methods 1 & 65 * */
+/* * * */
+/* * 0.9.5 - 1/25/2001 - G.Juyn * */
+/* * - fixed some small compiler warnings (thanks Nikki) * */
+/* * * */
+/* * 1.0.2 - 05/05/2000 - G.Juyn * */
+/* * - B421427 - writes wrong format in bKGD and tRNS * */
+/* * 1.0.2 - 06/20/2000 - G.Juyn * */
+/* * - B434583 - compiler-warning if MNG_STORE_CHUNKS undefined * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_objects.h"
+#include "libmng_object_prc.h"
+#include "libmng_chunks.h"
+#ifdef MNG_CHECK_BAD_ICCP
+#include "libmng_chunk_prc.h"
+#endif
+#include "libmng_memory.h"
+#include "libmng_display.h"
+#include "libmng_zlib.h"
+#include "libmng_pixels.h"
+#include "libmng_chunk_io.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * CRC - Cyclic Redundancy Check * */
+/* * * */
+/* * The code below is taken directly from the sample provided with the * */
+/* * PNG specification. * */
+/* * (it is only adapted to the library's internal data-definitions) * */
+/* * * */
+/* ************************************************************************** */
+
+/* Make the table for a fast CRC. */
+void make_crc_table (mng_datap pData)
+{
+ mng_uint32 iC;
+ mng_int32 iN, iK;
+
+ for (iN = 0; iN < 256; iN++)
+ {
+ iC = (mng_uint32) iN;
+
+ for (iK = 0; iK < 8; iK++)
+ {
+ if (iC & 1)
+ iC = 0xedb88320U ^ (iC >> 1);
+ else
+ iC = iC >> 1;
+ }
+
+ pData->aCRCtable [iN] = iC;
+ }
+
+ pData->bCRCcomputed = MNG_TRUE;
+}
+
+/* Update a running CRC with the bytes buf[0..len-1]--the CRC
+ should be initialized to all 1's, and the transmitted value
+ is the 1's complement of the final running CRC (see the
+ crc() routine below). */
+
+mng_uint32 update_crc (mng_datap pData,
+ mng_uint32 iCrc,
+ mng_uint8p pBuf,
+ mng_int32 iLen)
+{
+ mng_uint32 iC = iCrc;
+ mng_int32 iN;
+
+ if (!pData->bCRCcomputed)
+ make_crc_table (pData);
+
+ for (iN = 0; iN < iLen; iN++)
+ iC = pData->aCRCtable [(iC ^ pBuf [iN]) & 0xff] ^ (iC >> 8);
+
+ return iC;
+}
+
+/* Return the CRC of the bytes buf[0..len-1]. */
+mng_uint32 crc (mng_datap pData,
+ mng_uint8p pBuf,
+ mng_int32 iLen)
+{
+ return update_crc (pData, 0xffffffffU, pBuf, iLen) ^ 0xffffffffU;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Routines for swapping byte-order from and to graphic files * */
+/* * (This code is adapted from the libpng package) * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_BIGENDIAN_SUPPORTED
+
+/* ************************************************************************** */
+
+mng_uint32 mng_get_uint32 (mng_uint8p pBuf)
+{
+ mng_uint32 i = ((mng_uint32)(*pBuf) << 24) +
+ ((mng_uint32)(*(pBuf + 1)) << 16) +
+ ((mng_uint32)(*(pBuf + 2)) << 8) +
+ (mng_uint32)(*(pBuf + 3));
+ return (i);
+}
+
+/* ************************************************************************** */
+
+mng_int32 mng_get_int32 (mng_uint8p pBuf)
+{
+ mng_int32 i = ((mng_int32)(*pBuf) << 24) +
+ ((mng_int32)(*(pBuf + 1)) << 16) +
+ ((mng_int32)(*(pBuf + 2)) << 8) +
+ (mng_int32)(*(pBuf + 3));
+ return (i);
+}
+
+/* ************************************************************************** */
+
+mng_uint16 mng_get_uint16 (mng_uint8p pBuf)
+{
+ mng_uint16 i = (mng_uint16)(((mng_uint16)(*pBuf) << 8) +
+ (mng_uint16)(*(pBuf + 1)));
+ return (i);
+}
+
+/* ************************************************************************** */
+
+void mng_put_uint32 (mng_uint8p pBuf,
+ mng_uint32 i)
+{
+ *pBuf = (mng_uint8)((i >> 24) & 0xff);
+ *(pBuf+1) = (mng_uint8)((i >> 16) & 0xff);
+ *(pBuf+2) = (mng_uint8)((i >> 8) & 0xff);
+ *(pBuf+3) = (mng_uint8)(i & 0xff);
+}
+
+/* ************************************************************************** */
+
+void mng_put_int32 (mng_uint8p pBuf,
+ mng_int32 i)
+{
+ *pBuf = (mng_uint8)((i >> 24) & 0xff);
+ *(pBuf+1) = (mng_uint8)((i >> 16) & 0xff);
+ *(pBuf+2) = (mng_uint8)((i >> 8) & 0xff);
+ *(pBuf+3) = (mng_uint8)(i & 0xff);
+}
+
+/* ************************************************************************** */
+
+void mng_put_uint16 (mng_uint8p pBuf,
+ mng_uint16 i)
+{
+ *pBuf = (mng_uint8)((i >> 8) & 0xff);
+ *(pBuf+1) = (mng_uint8)(i & 0xff);
+}
+
+/* ************************************************************************** */
+
+#endif /* !MNG_BIGENDIAN_SUPPORTED */
+
+/* ************************************************************************** */
+/* * * */
+/* * Helper routines to simplify chunk-data extraction * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_READ_PROCS
+
+/* ************************************************************************** */
+
+mng_uint8p tqfind_null (mng_uint8p pIn)
+{
+ mng_uint8p pOut = pIn;
+
+ while (*pOut) /* the read_graphic routine has made sure there's */
+ pOut++; /* always at least 1 zero-byte in the buffer */
+
+ return pOut;
+}
+
+/* ************************************************************************** */
+
+mng_retcode inflate_buffer (mng_datap pData,
+ mng_uint8p pInbuf,
+ mng_uint32 iInsize,
+ mng_uint8p *pOutbuf,
+ mng_uint32 *iOutsize,
+ mng_uint32 *iRealsize)
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_START)
+#endif
+
+ if (iInsize) /* anything to do ? */
+ {
+ *iOutsize = iInsize * 3; /* estimate uncompressed size */
+ /* and allocate a temporary buffer */
+ MNG_ALLOC (pData, *pOutbuf, *iOutsize)
+
+ do
+ {
+ mngzlib_inflateinit (pData); /* initialize zlib */
+ /* let zlib know where to store the output */
+ pData->sZlib.next_out = *pOutbuf;
+ /* "size - 1" so we've got space for the
+ zero-termination of a possible string */
+ pData->sZlib.avail_out = *iOutsize - 1;
+ /* ok; let's inflate... */
+ iRetcode = mngzlib_inflatedata (pData, iInsize, pInbuf);
+ /* determine actual output size */
+ *iRealsize = (mng_uint32)pData->sZlib.total_out;
+
+ mngzlib_inflatefree (pData); /* zlib's done */
+
+ if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */
+ { /* then get some more */
+ MNG_FREEX (pData, *pOutbuf, *iOutsize)
+ *iOutsize = *iOutsize + iInsize;
+ MNG_ALLOC (pData, *pOutbuf, *iOutsize)
+ }
+ } /* repeat if we didn't have enough space */
+ while ((iRetcode == MNG_BUFOVERFLOW) &&
+ (*iOutsize < 20 * iInsize));
+
+ if (!iRetcode) /* if oke ? */
+ *((*pOutbuf) + *iRealsize) = 0; /* then put terminator zero */
+
+ }
+ else
+ {
+ *pOutbuf = 0; /* nothing to do; then there's no output */
+ *iOutsize = 0;
+ *iRealsize = 0;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_READ_PROCS */
+
+/* ************************************************************************** */
+/* * * */
+/* * Helper routines to simplify chunk writing * */
+/* * * */
+/* ************************************************************************** */
+/* B004 */
+#ifdef MNG_INCLUDE_WRITE_PROCS
+/* B004 */
+/* ************************************************************************** */
+
+mng_retcode deflate_buffer (mng_datap pData,
+ mng_uint8p pInbuf,
+ mng_uint32 iInsize,
+ mng_uint8p *pOutbuf,
+ mng_uint32 *iOutsize,
+ mng_uint32 *iRealsize)
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_START)
+#endif
+
+ if (iInsize) /* anything to do ? */
+ {
+ *iOutsize = (iInsize * 5) >> 2; /* estimate compressed size */
+ /* and allocate a temporary buffer */
+ MNG_ALLOC (pData, *pOutbuf, *iOutsize)
+
+ do
+ {
+ mngzlib_deflateinit (pData); /* initialize zlib */
+ /* let zlib know where to store the output */
+ pData->sZlib.next_out = *pOutbuf;
+ pData->sZlib.avail_out = *iOutsize;
+ /* ok; let's deflate... */
+ iRetcode = mngzlib_deflatedata (pData, iInsize, pInbuf);
+ /* determine actual output size */
+ *iRealsize = pData->sZlib.total_out;
+
+ mngzlib_deflatefree (pData); /* zlib's done */
+
+ if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */
+ { /* then get some more */
+ MNG_FREEX (pData, *pOutbuf, *iOutsize)
+ *iOutsize = *iOutsize + (iInsize >> 1);
+ MNG_ALLOC (pData, *pOutbuf, *iOutsize)
+ }
+ } /* repeat if we didn't have enough space */
+ while (iRetcode == MNG_BUFOVERFLOW);
+ }
+ else
+ {
+ *pOutbuf = 0; /* nothing to do; then there's no output */
+ *iOutsize = 0;
+ *iRealsize = 0;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+mng_retcode write_raw_chunk (mng_datap pData,
+ mng_chunkid iChunkname,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata)
+{
+ mng_uint32 iCrc;
+ mng_uint32 iWritten;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_START)
+#endif
+ /* temporary buffer ? */
+ if ((pRawdata != 0) && (pRawdata != pData->pWritebuf+8))
+ { /* store length & chunktype in default buffer */
+ mng_put_uint32 (pData->pWritebuf, iRawlen);
+ mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname);
+ /* calculate the crc */
+ iCrc = update_crc (pData, 0xffffffffL, pData->pWritebuf+4, 4);
+ iCrc = update_crc (pData, iCrc, pRawdata, iRawlen) ^ 0xffffffffL;
+ /* store crc in default buffer */
+ mng_put_uint32 (pData->pWritebuf+8, iCrc);
+ /* write the length & chunktype */
+ if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, 8, &iWritten))
+ MNG_ERROR (pData, MNG_APPIOERROR)
+
+ if (iWritten != 8) /* disk full ? */
+ MNG_ERROR (pData, MNG_OUTPUTERROR)
+ /* write the temporary buffer */
+ if (!pData->fWritedata ((mng_handle)pData, pRawdata, iRawlen, &iWritten))
+ MNG_ERROR (pData, MNG_APPIOERROR)
+
+ if (iWritten != iRawlen) /* disk full ? */
+ MNG_ERROR (pData, MNG_OUTPUTERROR)
+
+ /* write the crc */
+ if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf+8, 4, &iWritten))
+ MNG_ERROR (pData, MNG_APPIOERROR)
+
+ if (iWritten != 4) /* disk full ? */
+ MNG_ERROR (pData, MNG_OUTPUTERROR)
+
+ }
+ else
+ { /* prefix with length & chunktype */
+ mng_put_uint32 (pData->pWritebuf, iRawlen);
+ mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname);
+ /* calculate the crc */
+ iCrc = crc (pData, pData->pWritebuf+4, iRawlen + 4);
+ /* add it to the buffer */
+ mng_put_uint32 (pData->pWritebuf + iRawlen + 8, iCrc);
+ /* write it in a single pass */
+ if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 12, &iWritten))
+ MNG_ERROR (pData, MNG_APPIOERROR)
+
+ if (iWritten != iRawlen + 12) /* disk full ? */
+ MNG_ERROR (pData, MNG_OUTPUTERROR)
+
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* B004 */
+#endif /* MNG_INCLUDE_WRITE_PROCS */
+/* B004 */
+/* ************************************************************************** */
+/* * * */
+/* * chunk read functions * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_READ_PROCS
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_ihdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_START)
+#endif
+
+ if (iRawlen != 13) /* length oke ? */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ /* only allowed inside PNG or MNG */
+ if ((pData->eSigtype != mng_it_png) && (pData->eSigtype != mng_it_mng))
+ MNG_ERROR (pData, MNG_CHUNKNOTALLOWED)
+ /* sequence checks */
+ if ((pData->eSigtype == mng_it_png) && (pData->iChunkseq > 1))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ pData->bHasIHDR = MNG_TRUE; /* indicate IHDR is present */
+ /* and store interesting fields */
+ if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_NOCHANGE))
+ {
+ pData->iDatawidth = mng_get_uint32 (pRawdata);
+ pData->iDataheight = mng_get_uint32 (pRawdata+4);
+ }
+
+ pData->iBitdepth = *(pRawdata+8);
+ pData->iColortype = *(pRawdata+9);
+ pData->iCompression = *(pRawdata+10);
+ pData->iFilter = *(pRawdata+11);
+ pData->iInterlace = *(pRawdata+12);
+
+ if ((pData->iBitdepth != 1) && /* parameter validity checks */
+ (pData->iBitdepth != 2) &&
+ (pData->iBitdepth != 4) &&
+ (pData->iBitdepth != 8) &&
+ (pData->iBitdepth != 16) )
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH)
+
+ if ((pData->iColortype != MNG_COLORTYPE_GRAY ) &&
+ (pData->iColortype != MNG_COLORTYPE_RGB ) &&
+ (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
+ (pData->iColortype != MNG_COLORTYPE_GRAYA ) &&
+ (pData->iColortype != MNG_COLORTYPE_RGBA ) )
+ MNG_ERROR (pData, MNG_INVALIDCOLORTYPE)
+
+ if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8))
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH)
+
+ if (((pData->iColortype == MNG_COLORTYPE_RGB ) ||
+ (pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
+ (pData->iColortype == MNG_COLORTYPE_RGBA ) ) &&
+ (pData->iBitdepth < 8 ) )
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH)
+
+ if (pData->iCompression != MNG_COMPRESSION_DEFLATE)
+ MNG_ERROR (pData, MNG_INVALIDCOMPRESS)
+
+ if ((pData->eSigtype == mng_it_png) && (pData->iFilter))
+ MNG_ERROR (pData, MNG_INVALIDFILTER)
+ else
+ if (pData->iFilter & (~MNG_FILTER_DIFFERING))
+ MNG_ERROR (pData, MNG_INVALIDFILTER)
+
+ if ((pData->iInterlace != MNG_INTERLACE_NONE ) &&
+ (pData->iInterlace != MNG_INTERLACE_ADAM7) )
+ MNG_ERROR (pData, MNG_INVALIDINTERLACE)
+
+ if (pData->bHasDHDR) /* check the colortype for delta-images ! */
+ {
+ mng_imagedatap pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+
+ if (pData->iColortype != pBuf->iColortype)
+ {
+ if ( ( (pData->iColortype != MNG_COLORTYPE_INDEXED) ||
+ (pBuf->iColortype == MNG_COLORTYPE_GRAY ) ) &&
+ ( (pData->iColortype != MNG_COLORTYPE_GRAY ) ||
+ (pBuf->iColortype == MNG_COLORTYPE_INDEXED) ) )
+ MNG_ERROR (pData, MNG_INVALIDCOLORTYPE)
+ }
+ }
+
+ if (!pData->bHasheader) /* first chunk ? */
+ {
+ pData->bHasheader = MNG_TRUE; /* we've got a header */
+ pData->eImagetype = mng_it_png; /* then this must be a PNG */
+ pData->iWidth = pData->iDatawidth;
+ pData->iHeight = pData->iDataheight;
+ /* predict alpha-depth ! */
+ if ((pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
+ (pData->iColortype == MNG_COLORTYPE_RGBA ) )
+ pData->iAlphadepth = pData->iBitdepth;
+ else
+ if (pData->iColortype == MNG_COLORTYPE_INDEXED)
+ pData->iAlphadepth = 8; /* worst case scenario */
+ else
+ pData->iAlphadepth = 0;
+ /* fits on maximum canvas ? */
+ if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
+ MNG_WARNING (pData, MNG_IMAGETOOLARGE)
+
+ if (pData->fProcessheader) /* inform the app ? */
+ if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+ }
+
+ if (!pData->bHasDHDR)
+ pData->iImagelevel++; /* one level deeper */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode = process_display_ihdr (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the fields */
+ ((mng_ihdrp)*ppChunk)->iWidth = mng_get_uint32 (pRawdata);
+ ((mng_ihdrp)*ppChunk)->iHeight = mng_get_uint32 (pRawdata+4);
+ ((mng_ihdrp)*ppChunk)->iBitdepth = pData->iBitdepth;
+ ((mng_ihdrp)*ppChunk)->iColortype = pData->iColortype;
+ ((mng_ihdrp)*ppChunk)->iCompression = pData->iCompression;
+ ((mng_ihdrp)*ppChunk)->iFilter = pData->iFilter;
+ ((mng_ihdrp)*ppChunk)->iInterlace = pData->iInterlace;
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_plte)
+{
+#if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
+ mng_uint32 iX;
+ mng_uint8p pRawdata2;
+#endif
+#ifdef MNG_SUPPORT_DISPLAY
+ mng_uint32 iRawlen2;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PLTE, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIDAT) || (pData->bHasJHDR))
+#else
+ if (pData->bHasIDAT)
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* multiple PLTE only inside BASI */
+ if ((pData->bHasPLTE) && (!pData->bHasBASI))
+ MNG_ERROR (pData, MNG_MULTIPLEERROR)
+ /* length must be multiple of 3 */
+ if (((iRawlen % 3) != 0) || (iRawlen > 768))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+ { /* only allowed for indexed-color or
+ rgb(a)-color! */
+ if ((pData->iColortype != 2) && (pData->iColortype != 3) && (pData->iColortype != 6))
+ MNG_ERROR (pData, MNG_CHUNKNOTALLOWED)
+ /* empty only allowed if global present */
+ if ((iRawlen == 0) && (!pData->bHasglobalPLTE))
+ MNG_ERROR (pData, MNG_CANNOTBEEMPTY)
+ }
+ else
+ {
+ if (iRawlen == 0) /* cannot be empty as global! */
+ MNG_ERROR (pData, MNG_CANNOTBEEMPTY)
+ }
+
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+ pData->bHasPLTE = MNG_TRUE; /* got it! */
+ else
+ pData->bHasglobalPLTE = MNG_TRUE;
+
+ pData->iPLTEcount = iRawlen / 3;
+
+#ifdef MNG_SUPPORT_DISPLAY
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+ {
+ mng_imagep pImage;
+ mng_imagedatap pBuf;
+
+ if (pData->bHasDHDR) /* processing delta-image ? */
+ { /* store in object 0 !!! */
+ pImage = (mng_imagep)pData->pObjzero;
+ pBuf = pImage->pImgbuf;
+ pBuf->bHasPLTE = MNG_TRUE; /* it's definitely got a PLTE now */
+ pBuf->iPLTEcount = iRawlen / 3; /* this is the exact length */
+ pRawdata2 = pRawdata; /* copy the entries */
+
+ for (iX = 0; iX < iRawlen / 3; iX++)
+ {
+ pBuf->aPLTEentries[iX].iRed = *pRawdata2;
+ pBuf->aPLTEentries[iX].iGreen = *(pRawdata2+1);
+ pBuf->aPLTEentries[iX].iBlue = *(pRawdata2+2);
+
+ pRawdata2 += 3;
+ }
+ }
+ else
+ { /* get the current object */
+ pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage) /* no object then dump it in obj 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf; /* address the object buffer */
+ pBuf->bHasPLTE = MNG_TRUE; /* and tell it it's got a PLTE now */
+
+ if (!iRawlen) /* if empty, inherit from global */
+ {
+ pBuf->iPLTEcount = pData->iGlobalPLTEcount;
+ MNG_COPY (pBuf->aPLTEentries, pData->aGlobalPLTEentries,
+ sizeof (pBuf->aPLTEentries))
+
+ if (pData->bHasglobalTRNS) /* also copy global tRNS ? */
+ { /* indicate tRNS available */
+ pBuf->bHasTRNS = MNG_TRUE;
+
+ iRawlen2 = pData->iGlobalTRNSrawlen;
+ pRawdata2 = (mng_uint8p)(pData->aGlobalTRNSrawdata);
+ /* global length oke ? */
+ if ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount))
+ MNG_ERROR (pData, MNG_GLOBALLENGTHERR)
+ /* copy it */
+ pBuf->iTRNScount = iRawlen2;
+ MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2)
+ }
+ }
+ else
+ { /* store fields for future reference */
+ pBuf->iPLTEcount = iRawlen / 3;
+ pRawdata2 = pRawdata;
+
+ for (iX = 0; iX < pBuf->iPLTEcount; iX++)
+ {
+ pBuf->aPLTEentries[iX].iRed = *pRawdata2;
+ pBuf->aPLTEentries[iX].iGreen = *(pRawdata2+1);
+ pBuf->aPLTEentries[iX].iBlue = *(pRawdata2+2);
+
+ pRawdata2 += 3;
+ }
+ }
+ }
+ }
+ else /* store as global */
+ {
+ pData->iGlobalPLTEcount = iRawlen / 3;
+ pRawdata2 = pRawdata;
+
+ for (iX = 0; iX < pData->iGlobalPLTEcount; iX++)
+ {
+ pData->aGlobalPLTEentries[iX].iRed = *pRawdata2;
+ pData->aGlobalPLTEentries[iX].iGreen = *(pRawdata2+1);
+ pData->aGlobalPLTEentries[iX].iBlue = *(pRawdata2+2);
+
+ pRawdata2 += 3;
+ }
+
+ { /* create an animation object */
+ mng_retcode iRetcode = create_ani_plte (pData, pData->iGlobalPLTEcount,
+ pData->aGlobalPLTEentries);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_pltep)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+ ((mng_pltep)*ppChunk)->iEntrycount = iRawlen / 3;
+ pRawdata2 = pRawdata;
+
+ for (iX = 0; iX < ((mng_pltep)*ppChunk)->iEntrycount; iX++)
+ {
+ ((mng_pltep)*ppChunk)->aEntries[iX].iRed = *pRawdata2;
+ ((mng_pltep)*ppChunk)->aEntries[iX].iGreen = *(pRawdata2+1);
+ ((mng_pltep)*ppChunk)->aEntries[iX].iBlue = *(pRawdata2+2);
+
+ pRawdata2 += 3;
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PLTE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_idat)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_IDAT, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_JNG /* sequence checks */
+ if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasJHDR) &&
+ (pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (pData->bHasJSEP)
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+#endif
+ /* not allowed for for deltatype NO_CHANGE */
+ if ((pData->bHasDHDR) && ((pData->iDeltatype == MNG_DELTATYPE_NOCHANGE)))
+ MNG_ERROR (pData, MNG_CHUNKNOTALLOWED)
+ /* can only be empty in BASI-block! */
+ if ((iRawlen == 0) && (!pData->bHasBASI))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ /* indexed-color requires PLTE */
+ if ((pData->bHasIHDR) && (pData->iColortype == 3) && (!pData->bHasPLTE))
+ MNG_ERROR (pData, MNG_PLTEMISSING)
+
+ pData->bHasIDAT = MNG_TRUE; /* got some IDAT now, don't we */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ if (iRawlen)
+ { /* display processing */
+ mng_retcode iRetcode = process_display_idat (pData, iRawlen, pRawdata);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_idatp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+ ((mng_idatp)*ppChunk)->iDatasize = iRawlen;
+
+ if (iRawlen != 0) /* is there any data ? */
+ {
+ MNG_ALLOC (pData, ((mng_idatp)*ppChunk)->pData, iRawlen)
+ MNG_COPY (((mng_idatp)*ppChunk)->pData, pRawdata, iRawlen)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_IDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_iend)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_IEND, MNG_LC_START)
+#endif
+
+ if (iRawlen > 0) /* must not contain data! */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH);
+
+#ifdef MNG_INCLUDE_JNG /* sequence checks */
+ if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* IHDR-block requires IDAT */
+ if ((pData->bHasIHDR) && (!pData->bHasIDAT))
+ MNG_ERROR (pData, MNG_IDATMISSING)
+
+ pData->iImagelevel--; /* one level up */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ { /* create an animation object */
+ mng_retcode iRetcode = create_ani_image (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* display processing */
+ iRetcode = process_display_iend (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ if (!pData->bTimerset) /* reset only if not broken !!! */
+ {
+#endif
+ /* IEND Q_SIGNALS the end for most ... */
+ pData->bHasIHDR = MNG_FALSE;
+ pData->bHasBASI = MNG_FALSE;
+ pData->bHasDHDR = MNG_FALSE;
+#ifdef MNG_INCLUDE_JNG
+ pData->bHasJHDR = MNG_FALSE;
+ pData->bHasJSEP = MNG_FALSE;
+ pData->bHasJDAA = MNG_FALSE;
+ pData->bHasJDAT = MNG_FALSE;
+#endif
+ pData->bHasPLTE = MNG_FALSE;
+ pData->bHasTRNS = MNG_FALSE;
+ pData->bHasGAMA = MNG_FALSE;
+ pData->bHasCHRM = MNG_FALSE;
+ pData->bHasSRGB = MNG_FALSE;
+ pData->bHasICCP = MNG_FALSE;
+ pData->bHasBKGD = MNG_FALSE;
+ pData->bHasIDAT = MNG_FALSE;
+#ifdef MNG_SUPPORT_DISPLAY
+ }
+#endif
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_IEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_trns)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_TRNS, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIDAT) || (pData->bHasJHDR))
+#else
+ if (pData->bHasIDAT)
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* multiple tRNS only inside BASI */
+ if ((pData->bHasTRNS) && (!pData->bHasBASI))
+ MNG_ERROR (pData, MNG_MULTIPLEERROR)
+
+ if (iRawlen > 256) /* it just can't be bigger than that! */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+ { /* not allowed with full alpha-channel */
+ if ((pData->iColortype == 4) || (pData->iColortype == 6))
+ MNG_ERROR (pData, MNG_CHUNKNOTALLOWED)
+
+ if (iRawlen != 0) /* filled ? */
+ { /* length checks */
+ if ((pData->iColortype == 0) && (iRawlen != 2))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->iColortype == 2) && (iRawlen != 6))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ if (pData->iColortype == 3)
+ {
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_imagedatap pBuf;
+
+ if (!pImage) /* no object then check obj 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf; /* address object buffer */
+
+ if ((iRawlen == 0) || (iRawlen > pBuf->iPLTEcount))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+#endif
+ }
+ else /* if empty there must be global stuff! */
+ {
+ if (!pData->bHasglobalTRNS)
+ MNG_ERROR (pData, MNG_CANNOTBEEMPTY)
+ }
+ }
+
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+ pData->bHasTRNS = MNG_TRUE; /* indicate tRNS available */
+ else
+ pData->bHasglobalTRNS = MNG_TRUE;
+
+#ifdef MNG_SUPPORT_DISPLAY
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+ {
+ mng_imagep pImage;
+ mng_imagedatap pBuf;
+ mng_uint8p pRawdata2;
+ mng_uint32 iRawlen2;
+
+ if (pData->bHasDHDR) /* processing delta-image ? */
+ { /* store in object 0 !!! */
+ pImage = (mng_imagep)pData->pObjzero;
+ pBuf = pImage->pImgbuf; /* address object buffer */
+
+ switch (pData->iColortype) /* store fields for future reference */
+ {
+ case 0: { /* gray */
+ pBuf->iTRNSgray = mng_get_uint16 (pRawdata);
+ pBuf->iTRNSred = 0;
+ pBuf->iTRNSgreen = 0;
+ pBuf->iTRNSblue = 0;
+ pBuf->iTRNScount = 0;
+ break;
+ }
+ case 2: { /* rgb */
+ pBuf->iTRNSgray = 0;
+ pBuf->iTRNSred = mng_get_uint16 (pRawdata);
+ pBuf->iTRNSgreen = mng_get_uint16 (pRawdata+2);
+ pBuf->iTRNSblue = mng_get_uint16 (pRawdata+4);
+ pBuf->iTRNScount = 0;
+ break;
+ }
+ case 3: { /* indexed */
+ pBuf->iTRNSgray = 0;
+ pBuf->iTRNSred = 0;
+ pBuf->iTRNSgreen = 0;
+ pBuf->iTRNSblue = 0;
+ pBuf->iTRNScount = iRawlen;
+ MNG_COPY (pBuf->aTRNSentries, pRawdata, iRawlen)
+ break;
+ }
+ }
+
+ pBuf->bHasTRNS = MNG_TRUE; /* tell it it's got a tRNS now */
+ }
+ else
+ { /* address current object */
+ pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage) /* no object then dump it in obj 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf; /* address object buffer */
+ pBuf->bHasTRNS = MNG_TRUE; /* and tell it it's got a tRNS now */
+
+ if (iRawlen == 0) /* if empty, inherit from global */
+ {
+ iRawlen2 = pData->iGlobalTRNSrawlen;
+ pRawdata2 = (mng_ptr)(pData->aGlobalTRNSrawdata);
+ /* global length oke ? */
+ if ((pData->iColortype == 0) && (iRawlen2 != 2))
+ MNG_ERROR (pData, MNG_GLOBALLENGTHERR)
+
+ if ((pData->iColortype == 2) && (iRawlen2 != 6))
+ MNG_ERROR (pData, MNG_GLOBALLENGTHERR)
+
+ if ((pData->iColortype == 3) && ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount)))
+ MNG_ERROR (pData, MNG_GLOBALLENGTHERR)
+ }
+ else
+ {
+ iRawlen2 = iRawlen;
+ pRawdata2 = pRawdata;
+ }
+
+ switch (pData->iColortype) /* store fields for future reference */
+ {
+ case 0: { /* gray */
+ pBuf->iTRNSgray = mng_get_uint16 (pRawdata2);
+ pBuf->iTRNSred = 0;
+ pBuf->iTRNSgreen = 0;
+ pBuf->iTRNSblue = 0;
+ pBuf->iTRNScount = 0;
+ break;
+ }
+ case 2: { /* rgb */
+ pBuf->iTRNSgray = 0;
+ pBuf->iTRNSred = mng_get_uint16 (pRawdata2);
+ pBuf->iTRNSgreen = mng_get_uint16 (pRawdata2+2);
+ pBuf->iTRNSblue = mng_get_uint16 (pRawdata2+4);
+ pBuf->iTRNScount = 0;
+ break;
+ }
+ case 3: { /* indexed */
+ pBuf->iTRNSgray = 0;
+ pBuf->iTRNSred = 0;
+ pBuf->iTRNSgreen = 0;
+ pBuf->iTRNSblue = 0;
+ pBuf->iTRNScount = iRawlen2;
+ MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2)
+ break;
+ }
+ }
+ }
+ }
+ else /* store as global */
+ {
+ pData->iGlobalTRNSrawlen = iRawlen;
+ MNG_COPY (pData->aGlobalTRNSrawdata, pRawdata, iRawlen)
+
+ { /* create an animation object */
+ mng_retcode iRetcode = create_ani_trns (pData, pData->iGlobalTRNSrawlen,
+ pData->aGlobalTRNSrawdata);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+ { /* not global! */
+ ((mng_trnsp)*ppChunk)->bGlobal = MNG_FALSE;
+ ((mng_trnsp)*ppChunk)->iType = pData->iColortype;
+
+ if (iRawlen == 0) /* if empty, indicate so */
+ ((mng_trnsp)*ppChunk)->bEmpty = MNG_TRUE;
+ else
+ {
+ ((mng_trnsp)*ppChunk)->bEmpty = MNG_FALSE;
+
+ switch (pData->iColortype) /* store fields */
+ {
+ case 0: { /* gray */
+ ((mng_trnsp)*ppChunk)->iGray = mng_get_uint16 (pRawdata);
+ break;
+ }
+ case 2: { /* rgb */
+ ((mng_trnsp)*ppChunk)->iRed = mng_get_uint16 (pRawdata);
+ ((mng_trnsp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2);
+ ((mng_trnsp)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+4);
+ break;
+ }
+ case 3: { /* indexed */
+ ((mng_trnsp)*ppChunk)->iCount = iRawlen;
+ MNG_COPY (((mng_trnsp)*ppChunk)->aEntries, pRawdata, iRawlen)
+ break;
+ }
+ }
+ }
+ }
+ else /* it's global! */
+ {
+ ((mng_trnsp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+ ((mng_trnsp)*ppChunk)->bGlobal = MNG_TRUE;
+ ((mng_trnsp)*ppChunk)->iType = 0;
+ ((mng_trnsp)*ppChunk)->iRawlen = iRawlen;
+
+ MNG_COPY (((mng_trnsp)*ppChunk)->aRawdata, pRawdata, iRawlen)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_TRNS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_gama)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_GAMA, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
+#else
+ if ((pData->bHasIDAT) || (pData->bHasPLTE))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ { /* length must be exactly 4 */
+ if (iRawlen != 4)
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ else
+ { /* length must be empty or exactly 4 */
+ if ((iRawlen != 0) && (iRawlen != 4))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ pData->bHasGAMA = MNG_TRUE; /* indicate we've got it */
+ else
+ pData->bHasglobalGAMA = (mng_bool)(iRawlen != 0);
+
+#ifdef MNG_SUPPORT_DISPLAY
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ {
+ mng_imagep pImage;
+
+ if (pData->bHasDHDR) /* update delta image ? */
+ { /* store in object 0 ! */
+ pImage = (mng_imagep)pData->pObjzero;
+ /* store for color-processing routines */
+ pImage->pImgbuf->iGamma = mng_get_uint32 (pRawdata);
+ pImage->pImgbuf->bHasGAMA = MNG_TRUE;
+ }
+ else
+ {
+ pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage) /* no object then dump it in obj 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+ /* store for color-processing routines */
+ pImage->pImgbuf->iGamma = mng_get_uint32 (pRawdata);
+ pImage->pImgbuf->bHasGAMA = MNG_TRUE;
+ }
+ }
+ else
+ { /* store as global */
+ if (iRawlen != 0)
+ pData->iGlobalGamma = mng_get_uint32 (pRawdata);
+
+ { /* create an animation object */
+ mng_retcode iRetcode = create_ani_gama (pData, (mng_bool)(iRawlen == 0),
+ pData->iGlobalGamma);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_gamap)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen)
+ ((mng_gamap)*ppChunk)->iGamma = mng_get_uint32 (pRawdata);
+
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_GAMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_chrm)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_CHRM, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
+#else
+ if ((pData->bHasIDAT) || (pData->bHasPLTE))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ { /* length must be exactly 32 */
+ if (iRawlen != 32)
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ else
+ { /* length must be empty or exactly 32 */
+ if ((iRawlen != 0) && (iRawlen != 32))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ pData->bHasCHRM = MNG_TRUE; /* indicate we've got it */
+ else
+ pData->bHasglobalCHRM = (mng_bool)(iRawlen != 0);
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_uint32 iWhitepointx, iWhitepointy;
+ mng_uint32 iPrimaryredx, iPrimaryredy;
+ mng_uint32 iPrimarygreenx, iPrimarygreeny;
+ mng_uint32 iPrimarybluex, iPrimarybluey;
+
+ iWhitepointx = mng_get_uint32 (pRawdata);
+ iWhitepointy = mng_get_uint32 (pRawdata+4);
+ iPrimaryredx = mng_get_uint32 (pRawdata+8);
+ iPrimaryredy = mng_get_uint32 (pRawdata+12);
+ iPrimarygreenx = mng_get_uint32 (pRawdata+16);
+ iPrimarygreeny = mng_get_uint32 (pRawdata+20);
+ iPrimarybluex = mng_get_uint32 (pRawdata+24);
+ iPrimarybluey = mng_get_uint32 (pRawdata+28);
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ {
+ mng_imagep pImage;
+ mng_imagedatap pBuf;
+
+ if (pData->bHasDHDR) /* update delta image ? */
+ { /* store it in object 0 ! */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf; /* address object buffer */
+ pBuf->bHasCHRM = MNG_TRUE; /* and tell it it's got a CHRM now */
+ /* store for color-processing routines */
+ pBuf->iWhitepointx = iWhitepointx;
+ pBuf->iWhitepointy = iWhitepointy;
+ pBuf->iPrimaryredx = iPrimaryredx;
+ pBuf->iPrimaryredy = iPrimaryredy;
+ pBuf->iPrimarygreenx = iPrimarygreenx;
+ pBuf->iPrimarygreeny = iPrimarygreeny;
+ pBuf->iPrimarybluex = iPrimarybluex;
+ pBuf->iPrimarybluey = iPrimarybluey;
+ }
+ else
+ {
+ pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage) /* no object then dump it in obj 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf; /* address object buffer */
+ pBuf->bHasCHRM = MNG_TRUE; /* and tell it it's got a CHRM now */
+ /* store for color-processing routines */
+ pBuf->iWhitepointx = iWhitepointx;
+ pBuf->iWhitepointy = iWhitepointy;
+ pBuf->iPrimaryredx = iPrimaryredx;
+ pBuf->iPrimaryredy = iPrimaryredy;
+ pBuf->iPrimarygreenx = iPrimarygreenx;
+ pBuf->iPrimarygreeny = iPrimarygreeny;
+ pBuf->iPrimarybluex = iPrimarybluex;
+ pBuf->iPrimarybluey = iPrimarybluey;
+ }
+ }
+ else
+ { /* store as global */
+ if (iRawlen != 0)
+ {
+ pData->iGlobalWhitepointx = iWhitepointx;
+ pData->iGlobalWhitepointy = iWhitepointy;
+ pData->iGlobalPrimaryredx = iPrimaryredx;
+ pData->iGlobalPrimaryredy = iPrimaryredy;
+ pData->iGlobalPrimarygreenx = iPrimarygreenx;
+ pData->iGlobalPrimarygreeny = iPrimarygreeny;
+ pData->iGlobalPrimarybluex = iPrimarybluex;
+ pData->iGlobalPrimarybluey = iPrimarybluey;
+ }
+
+ { /* create an animation object */
+ mng_retcode iRetcode = create_ani_chrm (pData, (mng_bool)(iRawlen == 0),
+ iWhitepointx, iWhitepointy,
+ iPrimaryredx, iPrimaryredy,
+ iPrimarygreenx, iPrimarygreeny,
+ iPrimarybluex, iPrimarybluey);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_chrmp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen)
+ {
+ ((mng_chrmp)*ppChunk)->iWhitepointx = mng_get_uint32 (pRawdata);
+ ((mng_chrmp)*ppChunk)->iWhitepointy = mng_get_uint32 (pRawdata+4);
+ ((mng_chrmp)*ppChunk)->iRedx = mng_get_uint32 (pRawdata+8);
+ ((mng_chrmp)*ppChunk)->iRedy = mng_get_uint32 (pRawdata+12);
+ ((mng_chrmp)*ppChunk)->iGreenx = mng_get_uint32 (pRawdata+16);
+ ((mng_chrmp)*ppChunk)->iGreeny = mng_get_uint32 (pRawdata+20);
+ ((mng_chrmp)*ppChunk)->iBluex = mng_get_uint32 (pRawdata+24);
+ ((mng_chrmp)*ppChunk)->iBluey = mng_get_uint32 (pRawdata+28);
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_CHRM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_srgb)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SRGB, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
+#else
+ if ((pData->bHasIDAT) || (pData->bHasPLTE))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ { /* length must be exactly 1 */
+ if (iRawlen != 1)
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ else
+ { /* length must be empty or exactly 1 */
+ if ((iRawlen != 0) && (iRawlen != 1))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ pData->bHasSRGB = MNG_TRUE; /* indicate we've got it */
+ else
+ pData->bHasglobalSRGB = (mng_bool)(iRawlen != 0);
+
+#ifdef MNG_SUPPORT_DISPLAY
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ {
+ mng_imagep pImage;
+
+ if (pData->bHasDHDR) /* update delta image ? */
+ { /* store in object 0 ! */
+ pImage = (mng_imagep)pData->pObjzero;
+ /* store for color-processing routines */
+ pImage->pImgbuf->iRenderingintent = *pRawdata;
+ pImage->pImgbuf->bHasSRGB = MNG_TRUE;
+ }
+ else
+ {
+ pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage) /* no object then dump it in obj 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+ /* store for color-processing routines */
+ pImage->pImgbuf->iRenderingintent = *pRawdata;
+ pImage->pImgbuf->bHasSRGB = MNG_TRUE;
+ }
+ }
+ else
+ { /* store as global */
+ if (iRawlen != 0)
+ pData->iGlobalRendintent = *pRawdata;
+
+ { /* create an animation object */
+ mng_retcode iRetcode = create_ani_srgb (pData, (mng_bool)(iRawlen == 0),
+ pData->iGlobalRendintent);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_srgbp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen)
+ ((mng_srgbp)*ppChunk)->iRenderingintent = *pRawdata;
+
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_iccp)
+{
+ mng_retcode iRetcode;
+ mng_uint8p pTemp;
+ mng_uint32 iCompressedsize;
+ mng_uint32 iProfilesize;
+ mng_uint32 iBufsize = 0;
+ mng_uint8p pBuf = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_ICCP, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
+#else
+ if ((pData->bHasIDAT) || (pData->bHasPLTE))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ { /* length must be at least 2 */
+ if (iRawlen < 2)
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ else
+ { /* length must be empty or at least 2 */
+ if ((iRawlen != 0) && (iRawlen < 2))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+
+ pTemp = tqfind_null (pRawdata); /* tqfind null-separator */
+ /* not found inside input-data ? */
+ if ((pTemp - pRawdata) > (mng_int32)iRawlen)
+ MNG_ERROR (pData, MNG_NULLNOTFOUND)
+ /* determine size of compressed profile */
+ iCompressedsize = (mng_uint32)(iRawlen - (pTemp - pRawdata) - 2);
+ /* decompress the profile */
+ iRetcode = inflate_buffer (pData, pTemp+2, iCompressedsize,
+ &pBuf, &iBufsize, &iProfilesize);
+
+#ifdef MNG_CHECK_BAD_ICCP /* Check for bad iCCP chunk */
+ if ((iRetcode) && (!strncmp ((char *)pRawdata, "Photoshop ICC profile", 21)))
+ {
+ if (iRawlen == 2615) /* is it the sRGB profile ? */
+ {
+ mng_chunk_header chunk_srgb = {MNG_UINT_sRGB, init_srgb, free_srgb,
+ read_srgb, write_srgb, 0, 0};
+ /* pretend it's an sRGB chunk then ! */
+ iRetcode = read_srgb (pData, &chunk_srgb, 1, (mng_ptr)"0", ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ { /* don't forget to drop the temp buffer */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ return iRetcode;
+ }
+ }
+ }
+ else
+ {
+#endif /* MNG_CHECK_BAD_ICCP */
+
+ if (iRetcode) /* on error bail out */
+ { /* don't forget to drop the temp buffer */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ return iRetcode;
+ }
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ pData->bHasICCP = MNG_TRUE; /* indicate we've got it */
+ else
+ pData->bHasglobalICCP = (mng_bool)(iRawlen != 0);
+
+#ifdef MNG_SUPPORT_DISPLAY
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ {
+ mng_imagep pImage;
+
+ if (pData->bHasDHDR) /* update delta image ? */
+ { /* store in object 0 ! */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ if (pImage->pImgbuf->pProfile) /* profile existed ? */
+ MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize)
+ /* allocate a buffer & copy it */
+ MNG_ALLOC (pData, pImage->pImgbuf->pProfile, iProfilesize)
+ MNG_COPY (pImage->pImgbuf->pProfile, pBuf, iProfilesize)
+ /* store it's length as well */
+ pImage->pImgbuf->iProfilesize = iProfilesize;
+ pImage->pImgbuf->bHasICCP = MNG_TRUE;
+ }
+ else
+ {
+ pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage) /* no object then dump it in obj 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ if (pImage->pImgbuf->pProfile) /* profile existed ? */
+ MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize)
+ /* allocate a buffer & copy it */
+ MNG_ALLOC (pData, pImage->pImgbuf->pProfile, iProfilesize)
+ MNG_COPY (pImage->pImgbuf->pProfile, pBuf, iProfilesize)
+ /* store it's length as well */
+ pImage->pImgbuf->iProfilesize = iProfilesize;
+ pImage->pImgbuf->bHasICCP = MNG_TRUE;
+ }
+ }
+ else
+ { /* store as global */
+ if (iRawlen == 0) /* empty chunk ? */
+ {
+ if (pData->pGlobalProfile) /* did we have a global profile ? */
+ MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize)
+
+ pData->iGlobalProfilesize = 0; /* reset to null */
+ pData->pGlobalProfile = MNG_NULL;
+ }
+ else
+ { /* allocate a global buffer & copy it */
+ MNG_ALLOC (pData, pData->pGlobalProfile, iProfilesize)
+ MNG_COPY (pData->pGlobalProfile, pBuf, iProfilesize)
+ /* store it's length as well */
+ pData->iGlobalProfilesize = iProfilesize;
+ }
+
+ /* create an animation object */
+ iRetcode = create_ani_iccp (pData, (mng_bool)(iRawlen == 0),
+ pData->iGlobalProfilesize,
+ pData->pGlobalProfile);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ { /* don't forget to drop the temp buffer */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ return iRetcode;
+ }
+ /* store the fields */
+ ((mng_iccpp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen) /* not empty ? */
+ {
+ if (!pBuf) /* hasn't been unpuzzled it yet ? */
+ { /* tqfind null-separator */
+ pTemp = tqfind_null (pRawdata);
+ /* not found inside input-data ? */
+ if ((pTemp - pRawdata) > (mng_int32)iRawlen)
+ MNG_ERROR (pData, MNG_NULLNOTFOUND)
+ /* determine size of compressed profile */
+ iCompressedsize = iRawlen - (pTemp - pRawdata) - 2;
+ /* decompress the profile */
+ iRetcode = inflate_buffer (pData, pTemp+2, iCompressedsize,
+ &pBuf, &iBufsize, &iProfilesize);
+
+ if (iRetcode) /* on error bail out */
+ { /* don't forget to drop the temp buffer */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ return iRetcode;
+ }
+ }
+
+ ((mng_iccpp)*ppChunk)->iNamesize = (mng_uint32)(pTemp - pRawdata);
+
+ if (((mng_iccpp)*ppChunk)->iNamesize)
+ {
+ MNG_ALLOC (pData, ((mng_iccpp)*ppChunk)->zName,
+ ((mng_iccpp)*ppChunk)->iNamesize + 1)
+ MNG_COPY (((mng_iccpp)*ppChunk)->zName, pRawdata,
+ ((mng_iccpp)*ppChunk)->iNamesize)
+ }
+
+ ((mng_iccpp)*ppChunk)->iCompression = *(pTemp+1);
+ ((mng_iccpp)*ppChunk)->iProfilesize = iProfilesize;
+
+ MNG_ALLOC (pData, ((mng_iccpp)*ppChunk)->pProfile, iProfilesize)
+ MNG_COPY (((mng_iccpp)*ppChunk)->pProfile, pBuf, iProfilesize)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+ if (pBuf) /* free the temporary buffer */
+ MNG_FREEX (pData, pBuf, iBufsize)
+
+#ifdef MNG_CHECK_BAD_ICCP
+ }
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_ICCP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_text)
+{
+ mng_uint32 iKeywordlen, iTextlen;
+ mng_pchar zKeyword, zText;
+ mng_uint8p pTemp;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_TEXT, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen < 2) /* length must be at least 2 */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ pTemp = tqfind_null (pRawdata); /* tqfind the null separator */
+ /* not found inside input-data ? */
+ if ((pTemp - pRawdata) > (mng_int32)iRawlen)
+ MNG_ERROR (pData, MNG_NULLNOTFOUND)
+
+ if (pTemp == pRawdata) /* there must be at least 1 char for keyword */
+ MNG_ERROR (pData, MNG_KEYWORDNULL)
+
+ iKeywordlen = (mng_uint32)(pTemp - pRawdata);
+ iTextlen = iRawlen - iKeywordlen - 1;
+
+ if (pData->fProcesstext) /* inform the application ? */
+ {
+ mng_bool bOke;
+
+ MNG_ALLOC (pData, zKeyword, iKeywordlen + 1)
+ MNG_COPY (zKeyword, pRawdata, iKeywordlen)
+
+ MNG_ALLOCX (pData, zText, iTextlen + 1)
+
+ if (!zText) /* on error bail out */
+ {
+ MNG_FREEX (pData, zKeyword, iKeywordlen + 1)
+ MNG_ERROR (pData, MNG_OUTOFMEMORY)
+ }
+
+ if (iTextlen)
+ MNG_COPY (zText, pTemp+1, iTextlen)
+
+ bOke = pData->fProcesstext ((mng_handle)pData, MNG_TYPE_TEXT, zKeyword, zText, 0, 0);
+
+ MNG_FREEX (pData, zText, iTextlen + 1)
+ MNG_FREEX (pData, zKeyword, iKeywordlen + 1)
+
+ if (!bOke)
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+
+ }
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_textp)*ppChunk)->iKeywordsize = iKeywordlen;
+ ((mng_textp)*ppChunk)->iTextsize = iTextlen;
+
+ if (iKeywordlen)
+ {
+ MNG_ALLOC (pData, ((mng_textp)*ppChunk)->zKeyword, iKeywordlen+1)
+ MNG_COPY (((mng_textp)*ppChunk)->zKeyword, pRawdata, iKeywordlen)
+ }
+
+ if (iTextlen)
+ {
+ MNG_ALLOC (pData, ((mng_textp)*ppChunk)->zText, iTextlen+1)
+ MNG_COPY (((mng_textp)*ppChunk)->zText, pTemp+1, iTextlen)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_TEXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_ztxt)
+{
+ mng_retcode iRetcode;
+ mng_uint32 iKeywordlen, iTextlen;
+ mng_pchar zKeyword;
+ mng_uint8p pTemp;
+ mng_uint32 iCompressedsize;
+ mng_uint32 iBufsize;
+ mng_uint8p pBuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_ZTXT, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen < 3) /* length must be at least 3 */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ pTemp = tqfind_null (pRawdata); /* tqfind the null separator */
+ /* not found inside input-data ? */
+ if ((pTemp - pRawdata) > (mng_int32)iRawlen)
+ MNG_ERROR (pData, MNG_NULLNOTFOUND)
+
+ if (pTemp == pRawdata) /* there must be at least 1 char for keyword */
+ MNG_ERROR (pData, MNG_KEYWORDNULL)
+
+ if (*(pTemp+1) != 0) /* only deflate compression-method allowed */
+ MNG_ERROR (pData, MNG_INVALIDCOMPRESS)
+
+ iKeywordlen = (mng_uint32)(pTemp - pRawdata);
+ iCompressedsize = (mng_uint32)(iRawlen - iKeywordlen - 2);
+
+ zKeyword = 0; /* there's no keyword buffer yet */
+ pBuf = 0; /* or a temporary buffer ! */
+
+ if (pData->fProcesstext) /* inform the application ? */
+ { /* decompress the text */
+ iRetcode = inflate_buffer (pData, pTemp+2, iCompressedsize,
+ &pBuf, &iBufsize, &iTextlen);
+
+ if (iRetcode) /* on error bail out */
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ return iRetcode;
+ }
+
+ MNG_ALLOCX (pData, zKeyword, iKeywordlen+1)
+
+ if (!zKeyword) /* on error bail out */
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ MNG_ERROR (pData, MNG_OUTOFMEMORY);
+ }
+
+ MNG_COPY (zKeyword, pRawdata, iKeywordlen)
+
+ if (!pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ZTXT, zKeyword, (mng_pchar)pBuf, 0, 0))
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ MNG_FREEX (pData, zKeyword, iKeywordlen+1)
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+ }
+ }
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ MNG_FREEX (pData, zKeyword, iKeywordlen+1)
+ return iRetcode;
+ }
+ /* store the fields */
+ ((mng_ztxtp)*ppChunk)->iKeywordsize = iKeywordlen;
+ ((mng_ztxtp)*ppChunk)->iCompression = *(pTemp+1);
+
+ if ((!pBuf) && (iCompressedsize)) /* did we not get a text-buffer yet ? */
+ { /* decompress the text */
+ iRetcode = inflate_buffer (pData, pTemp+2, iCompressedsize,
+ &pBuf, &iBufsize, &iTextlen);
+
+ if (iRetcode) /* on error bail out */
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ MNG_FREEX (pData, zKeyword, iKeywordlen+1)
+ return iRetcode;
+ }
+ }
+
+ MNG_ALLOCX (pData, ((mng_ztxtp)*ppChunk)->zKeyword, iKeywordlen + 1)
+ /* on error bail out */
+ if (!((mng_ztxtp)*ppChunk)->zKeyword)
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ MNG_FREEX (pData, zKeyword, iKeywordlen+1)
+ MNG_ERROR (pData, MNG_OUTOFMEMORY);
+ }
+
+ MNG_COPY (((mng_ztxtp)*ppChunk)->zKeyword, pRawdata, iKeywordlen)
+
+ ((mng_ztxtp)*ppChunk)->iTextsize = iTextlen;
+
+ if (iCompressedsize)
+ {
+ MNG_ALLOCX (pData, ((mng_ztxtp)*ppChunk)->zText, iTextlen + 1)
+ /* on error bail out */
+ if (!((mng_ztxtp)*ppChunk)->zText)
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ MNG_FREEX (pData, zKeyword, iKeywordlen+1)
+ MNG_ERROR (pData, MNG_OUTOFMEMORY);
+ }
+
+ MNG_COPY (((mng_ztxtp)*ppChunk)->zText, pBuf, iTextlen)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+ MNG_FREEX (pData, pBuf, iBufsize) /* free the temporary buffers */
+ MNG_FREEX (pData, zKeyword, iKeywordlen+1)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_ZTXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_itxt)
+{
+ mng_retcode iRetcode;
+ mng_uint32 iKeywordlen, iTextlen, iLanguagelen, iTranslationlen;
+ mng_pchar zKeyword, zLanguage, zTranslation;
+ mng_uint8p pNull1, pNull2, pNull3;
+ mng_uint32 iCompressedsize;
+ mng_uint8 iCompressionflag;
+ mng_uint32 iBufsize;
+ mng_uint8p pBuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_ITXT, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen < 6) /* length must be at least 6 */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ pNull1 = tqfind_null (pRawdata); /* tqfind the null separators */
+ pNull2 = tqfind_null (pNull1+3);
+ pNull3 = tqfind_null (pNull2+1);
+ /* not found inside input-data ? */
+ if (((pNull1 - pRawdata) > (mng_int32)iRawlen) ||
+ ((pNull2 - pRawdata) > (mng_int32)iRawlen) ||
+ ((pNull3 - pRawdata) > (mng_int32)iRawlen) )
+ MNG_ERROR (pData, MNG_NULLNOTFOUND)
+
+ if (pNull1 == pRawdata) /* there must be at least 1 char for keyword */
+ MNG_ERROR (pData, MNG_KEYWORDNULL)
+ /* compression or not ? */
+ if ((*(pNull1+1) != 0) && (*(pNull1+1) != 1))
+ MNG_ERROR (pData, MNG_INVALIDCOMPRESS)
+
+ if (*(pNull1+2) != 0) /* only deflate compression-method allowed */
+ MNG_ERROR (pData, MNG_INVALIDCOMPRESS)
+
+ iKeywordlen = (mng_uint32)(pNull1 - pRawdata);
+ iLanguagelen = (mng_uint32)(pNull2 - pNull1 - 3);
+ iTranslationlen = (mng_uint32)(pNull3 - pNull2 - 1);
+ iCompressedsize = (mng_uint32)(iRawlen - iKeywordlen - iLanguagelen - iTranslationlen - 5);
+ iCompressionflag = *(pNull1+1);
+
+ zKeyword = 0; /* no buffers acquired yet */
+ zLanguage = 0;
+ zTranslation = 0;
+ pBuf = 0;
+ iTextlen = 0;
+
+ if (pData->fProcesstext) /* inform the application ? */
+ {
+ if (iCompressionflag) /* decompress the text ? */
+ {
+ iRetcode = inflate_buffer (pData, pNull3+1, iCompressedsize,
+ &pBuf, &iBufsize, &iTextlen);
+
+ if (iRetcode) /* on error bail out */
+ { /* don't forget to drop the temp buffer */
+ MNG_FREEX (pData, pBuf, iBufsize)
+ return iRetcode;
+ }
+ }
+ else
+ {
+ iTextlen = iCompressedsize;
+ iBufsize = iTextlen+1; /* plus 1 for terminator byte!!! */
+
+ MNG_ALLOCX (pData, pBuf, iBufsize);
+ MNG_COPY (pBuf, pNull3+1, iTextlen);
+ }
+
+ MNG_ALLOCX (pData, zKeyword, iKeywordlen + 1)
+ MNG_ALLOCX (pData, zLanguage, iLanguagelen + 1)
+ MNG_ALLOCX (pData, zTranslation, iTranslationlen + 1)
+ /* on error bail out */
+ if ((!zKeyword) || (!zLanguage) || (!zTranslation))
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, zTranslation, iTranslationlen + 1)
+ MNG_FREEX (pData, zLanguage, iLanguagelen + 1)
+ MNG_FREEX (pData, zKeyword, iKeywordlen + 1)
+ MNG_FREEX (pData, pBuf, iBufsize)
+ MNG_ERROR (pData, MNG_OUTOFMEMORY)
+ }
+
+ MNG_COPY (zKeyword, pRawdata, iKeywordlen)
+ MNG_COPY (zLanguage, pNull1+3, iLanguagelen)
+ MNG_COPY (zTranslation, pNull2+1, iTranslationlen)
+
+ if (!pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ITXT, zKeyword, (mng_pchar)pBuf,
+ zLanguage, zTranslation))
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, zTranslation, iTranslationlen + 1)
+ MNG_FREEX (pData, zLanguage, iLanguagelen + 1)
+ MNG_FREEX (pData, zKeyword, iKeywordlen + 1)
+ MNG_FREEX (pData, pBuf, iBufsize)
+
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+ }
+ }
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, zTranslation, iTranslationlen + 1)
+ MNG_FREEX (pData, zLanguage, iLanguagelen + 1)
+ MNG_FREEX (pData, zKeyword, iKeywordlen + 1)
+ MNG_FREEX (pData, pBuf, iBufsize)
+ return iRetcode;
+ }
+ /* store the fields */
+ ((mng_itxtp)*ppChunk)->iKeywordsize = iKeywordlen;
+ ((mng_itxtp)*ppChunk)->iLanguagesize = iLanguagelen;
+ ((mng_itxtp)*ppChunk)->iTranslationsize = iTranslationlen;
+ ((mng_itxtp)*ppChunk)->iCompressionflag = *(pNull1+1);
+ ((mng_itxtp)*ppChunk)->iCompressionmethod = *(pNull1+2);
+
+ if ((!pBuf) && (iCompressedsize)) /* did we not get a text-buffer yet ? */
+ {
+ if (iCompressionflag) /* decompress the text ? */
+ {
+ iRetcode = inflate_buffer (pData, pNull3+1, iCompressedsize,
+ &pBuf, &iBufsize, &iTextlen);
+
+ if (iRetcode) /* on error bail out */
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, zTranslation, iTranslationlen + 1)
+ MNG_FREEX (pData, zLanguage, iLanguagelen + 1)
+ MNG_FREEX (pData, zKeyword, iKeywordlen + 1)
+ MNG_FREEX (pData, pBuf, iBufsize)
+ return iRetcode;
+ }
+ }
+ else
+ {
+ iTextlen = iCompressedsize;
+ iBufsize = iTextlen+1; /* plus 1 for terminator byte!!! */
+
+ MNG_ALLOCX (pData, pBuf, iBufsize);
+ MNG_COPY (pBuf, pNull3+1, iTextlen);
+ }
+ }
+
+ MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zKeyword, iKeywordlen + 1)
+ MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zLanguage, iLanguagelen + 1)
+ MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zTranslation, iTranslationlen + 1)
+ /* on error bail out */
+ if ((!((mng_itxtp)*ppChunk)->zKeyword ) ||
+ (!((mng_itxtp)*ppChunk)->zLanguage ) ||
+ (!((mng_itxtp)*ppChunk)->zTranslation) )
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, zTranslation, iTranslationlen + 1)
+ MNG_FREEX (pData, zLanguage, iLanguagelen + 1)
+ MNG_FREEX (pData, zKeyword, iKeywordlen + 1)
+ MNG_FREEX (pData, pBuf, iBufsize)
+ MNG_ERROR (pData, MNG_OUTOFMEMORY)
+ }
+
+ MNG_COPY (((mng_itxtp)*ppChunk)->zKeyword, pRawdata, iKeywordlen)
+ MNG_COPY (((mng_itxtp)*ppChunk)->zLanguage, pNull1+3, iLanguagelen)
+ MNG_COPY (((mng_itxtp)*ppChunk)->zTranslation, pNull2+1, iTranslationlen)
+
+ ((mng_itxtp)*ppChunk)->iTextsize = iTextlen;
+
+ if (iTextlen)
+ {
+ MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zText, iTextlen + 1)
+
+ if (!((mng_itxtp)*ppChunk)->zText)
+ { /* don't forget to drop the temp buffers */
+ MNG_FREEX (pData, zTranslation, iTranslationlen + 1)
+ MNG_FREEX (pData, zLanguage, iLanguagelen + 1)
+ MNG_FREEX (pData, zKeyword, iKeywordlen + 1)
+ MNG_FREEX (pData, pBuf, iBufsize)
+ MNG_ERROR (pData, MNG_OUTOFMEMORY)
+ }
+
+ MNG_COPY (((mng_itxtp)*ppChunk)->zText, pBuf, iTextlen)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+ /* free the temporary buffers */
+ MNG_FREEX (pData, zTranslation, iTranslationlen + 1)
+ MNG_FREEX (pData, zLanguage, iLanguagelen + 1)
+ MNG_FREEX (pData, zKeyword, iKeywordlen + 1)
+ MNG_FREEX (pData, pBuf, iBufsize)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_ITXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_bkgd)
+{
+#ifdef MNG_SUPPORT_DISPLAY
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_imagedatap pBuf;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_BKGD, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
+#else
+ if (pData->bHasIDAT)
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen > 6) /* it just can't be bigger than that! */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_INCLUDE_JNG /* length checks */
+ if (pData->bHasJHDR)
+ {
+ if (((pData->iJHDRcolortype == 8) || (pData->iJHDRcolortype == 12)) && (iRawlen != 2))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if (((pData->iJHDRcolortype == 10) || (pData->iJHDRcolortype == 14)) && (iRawlen != 6))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ else
+#endif /* MNG_INCLUDE_JNG */
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+ {
+ if (((pData->iColortype == 0) || (pData->iColortype == 4)) && (iRawlen != 2))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if (((pData->iColortype == 2) || (pData->iColortype == 6)) && (iRawlen != 6))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->iColortype == 3) && (iRawlen != 1))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ else
+ {
+ if (iRawlen != 6) /* global is always 16-bit RGB ! */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ pData->bHasBKGD = MNG_TRUE; /* indicate bKGD available */
+ else
+ pData->bHasglobalBKGD = (mng_bool)(iRawlen != 0);
+
+#ifdef MNG_SUPPORT_DISPLAY
+ if (!pImage) /* if no object dump it in obj 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf; /* address object buffer */
+
+#ifdef MNG_INCLUDE_JNG
+ if (pData->bHasJHDR)
+ {
+ pBuf->bHasBKGD = MNG_TRUE; /* tell the object it's got bKGD now */
+
+ switch (pData->iJHDRcolortype) /* store fields for future reference */
+ {
+ case 8 : ; /* gray */
+ case 12 : { /* graya */
+ pBuf->iBKGDgray = mng_get_uint16 (pRawdata);
+ break;
+ }
+ case 10 : ; /* rgb */
+ case 14 : { /* rgba */
+ pBuf->iBKGDred = mng_get_uint16 (pRawdata);
+ pBuf->iBKGDgreen = mng_get_uint16 (pRawdata+2);
+ pBuf->iBKGDblue = mng_get_uint16 (pRawdata+4);
+ break;
+ }
+ }
+ }
+ else
+#endif /* MNG_INCLUDE_JNG */
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+ {
+ pBuf->bHasBKGD = MNG_TRUE; /* tell the object it's got bKGD now */
+
+ switch (pData->iColortype) /* store fields for future reference */
+ {
+ case 0 : ; /* gray */
+ case 4 : { /* graya */
+ pBuf->iBKGDgray = mng_get_uint16 (pRawdata);
+ break;
+ }
+ case 2 : ; /* rgb */
+ case 6 : { /* rgba */
+ pBuf->iBKGDred = mng_get_uint16 (pRawdata);
+ pBuf->iBKGDgreen = mng_get_uint16 (pRawdata+2);
+ pBuf->iBKGDblue = mng_get_uint16 (pRawdata+4);
+ break;
+ }
+ case 3 : { /* indexed */
+ pBuf->iBKGDindex = *pRawdata;
+ break;
+ }
+ }
+ }
+ else /* store as global */
+ {
+ if (iRawlen)
+ {
+ pData->iGlobalBKGDred = mng_get_uint16 (pRawdata);
+ pData->iGlobalBKGDgreen = mng_get_uint16 (pRawdata+2);
+ pData->iGlobalBKGDblue = mng_get_uint16 (pRawdata+4);
+ }
+
+ { /* create an animation object */
+ mng_retcode iRetcode = create_ani_bkgd (pData, pData->iGlobalBKGDred,
+ pData->iGlobalBKGDgreen,
+ pData->iGlobalBKGDblue);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_bkgdp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+ ((mng_bkgdp)*ppChunk)->iType = pData->iColortype;
+
+ if (iRawlen)
+ {
+ switch (iRawlen) /* guess from length */
+ {
+ case 1 : { /* indexed */
+ ((mng_bkgdp)*ppChunk)->iType = 3;
+ ((mng_bkgdp)*ppChunk)->iIndex = *pRawdata;
+ break;
+ }
+ case 2 : { /* gray */
+ ((mng_bkgdp)*ppChunk)->iType = 0;
+ ((mng_bkgdp)*ppChunk)->iGray = mng_get_uint16 (pRawdata);
+ break;
+ }
+ case 6 : { /* rgb */
+ ((mng_bkgdp)*ppChunk)->iType = 2;
+ ((mng_bkgdp)*ppChunk)->iRed = mng_get_uint16 (pRawdata);
+ ((mng_bkgdp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2);
+ ((mng_bkgdp)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+4);
+ break;
+ }
+ }
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_BKGD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_phys)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PHYS, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
+#else
+ if (pData->bHasIDAT)
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* it's 9 bytes or empty; no more, no less! */
+ if ((iRawlen != 9) && (iRawlen != 0))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_physp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen)
+ {
+ ((mng_physp)*ppChunk)->iSizex = mng_get_uint32 (pRawdata);
+ ((mng_physp)*ppChunk)->iSizey = mng_get_uint32 (pRawdata+4);
+ ((mng_physp)*ppChunk)->iUnit = *(pRawdata+8);
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PHYS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_sbit)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SBIT, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasPLTE) || (pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
+#else
+ if ((pData->bHasPLTE) || (pData->bHasIDAT))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen > 4) /* it just can't be bigger than that! */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_INCLUDE_JNG /* length checks */
+ if (pData->bHasJHDR)
+ {
+ if ((pData->iJHDRcolortype == 8) && (iRawlen != 1))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->iJHDRcolortype == 10) && (iRawlen != 3))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->iJHDRcolortype == 12) && (iRawlen != 2))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->iJHDRcolortype == 14) && (iRawlen != 4))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ else
+#endif /* MNG_INCLUDE_JNG */
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+ {
+ if ((pData->iColortype == 0) && (iRawlen != 1))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->iColortype == 2) && (iRawlen != 3))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->iColortype == 3) && (iRawlen != 3))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->iColortype == 4) && (iRawlen != 2))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((pData->iColortype == 6) && (iRawlen != 4))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ else
+ { /* global = empty or RGBA */
+ if ((iRawlen != 0) && (iRawlen != 4))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_sbitp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen)
+ {
+#ifdef MNG_INCLUDE_JNG
+ if (pData->bHasJHDR)
+ ((mng_sbitp)*ppChunk)->iType = pData->iJHDRcolortype;
+ else
+#endif
+ if (pData->bHasIHDR)
+ ((mng_sbitp)*ppChunk)->iType = pData->iColortype;
+ else /* global ! */
+ ((mng_sbitp)*ppChunk)->iType = 6;
+
+ if (iRawlen > 0)
+ ((mng_sbitp)*ppChunk)->aBits [0] = *pRawdata;
+ if (iRawlen > 1)
+ ((mng_sbitp)*ppChunk)->aBits [1] = *(pRawdata+1);
+ if (iRawlen > 2)
+ ((mng_sbitp)*ppChunk)->aBits [2] = *(pRawdata+2);
+ if (iRawlen > 3)
+ ((mng_sbitp)*ppChunk)->aBits [3] = *(pRawdata+3);
+
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SBIT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_splt)
+{
+ mng_uint8p pTemp;
+ mng_uint32 iNamelen;
+ mng_uint8 iSampledepth;
+ mng_uint32 iRemain;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SPLT, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (pData->bHasIDAT)
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen)
+ {
+ pTemp = tqfind_null (pRawdata); /* tqfind null-separator */
+ /* not found inside input-data ? */
+ if ((pTemp - pRawdata) > (mng_int32)iRawlen)
+ MNG_ERROR (pData, MNG_NULLNOTFOUND)
+
+ iNamelen = (mng_uint32)(pTemp - pRawdata);
+ iSampledepth = *(pTemp+1);
+ iRemain = (iRawlen - 2 - iNamelen);
+
+ if ((iSampledepth != 1) && (iSampledepth != 2))
+ MNG_ERROR (pData, MNG_INVSAMPLEDEPTH)
+ /* check remaining length */
+ if ( ((iSampledepth == 1) && (iRemain % 6 != 0)) ||
+ ((iSampledepth == 2) && (iRemain % 10 != 0)) )
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ }
+ else
+ {
+ pTemp = MNG_NULL;
+ iNamelen = 0;
+ iSampledepth = 0;
+ iRemain = 0;
+ }
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_spltp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen)
+ {
+ ((mng_spltp)*ppChunk)->iNamesize = iNamelen;
+ ((mng_spltp)*ppChunk)->iSampledepth = iSampledepth;
+
+ if (iSampledepth == 1)
+ ((mng_spltp)*ppChunk)->iEntrycount = iRemain / 6;
+ else
+ ((mng_spltp)*ppChunk)->iEntrycount = iRemain / 10;
+
+ if (iNamelen)
+ {
+ MNG_ALLOC (pData, ((mng_spltp)*ppChunk)->zName, iNamelen+1)
+ MNG_COPY (((mng_spltp)*ppChunk)->zName, pRawdata, iNamelen)
+ }
+
+ if (iRemain)
+ {
+ MNG_ALLOC (pData, ((mng_spltp)*ppChunk)->pEntries, iRemain)
+ MNG_COPY (((mng_spltp)*ppChunk)->pEntries, pTemp+2, iRemain)
+ }
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_hist)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_HIST, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) )
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if ((!pData->bHasPLTE) || (pData->bHasIDAT))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* length oke ? */
+ if ( ((iRawlen & 0x01) != 0) || ((iRawlen >> 1) != pData->iPLTEcount) )
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ {
+ mng_uint32 iX;
+ /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_histp)*ppChunk)->iEntrycount = iRawlen >> 1;
+
+ for (iX = 0; iX < (iRawlen >> 1); iX++)
+ {
+ ((mng_histp)*ppChunk)->aEntries [iX] = mng_get_uint16 (pRawdata);
+ pRawdata += 2;
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_HIST, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_time)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_TIME, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen != 7) /* length must be exactly 7 */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+/* if (pData->fProcesstime) */ /* inform the application ? */
+/* {
+
+ pData->fProcesstime ((mng_handle)pData, );
+ } */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_timep)*ppChunk)->iYear = mng_get_uint16 (pRawdata);
+ ((mng_timep)*ppChunk)->iMonth = *(pRawdata+2);
+ ((mng_timep)*ppChunk)->iDay = *(pRawdata+3);
+ ((mng_timep)*ppChunk)->iHour = *(pRawdata+4);
+ ((mng_timep)*ppChunk)->iMinute = *(pRawdata+5);
+ ((mng_timep)*ppChunk)->iSecond = *(pRawdata+6);
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_TIME, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_mhdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_MHDR, MNG_LC_START)
+#endif
+
+ if (pData->eSigtype != mng_it_mng) /* sequence checks */
+ MNG_ERROR (pData, MNG_CHUNKNOTALLOWED)
+
+ if (pData->bHasheader) /* can only be the first chunk! */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* correct length ? */
+ if ((iRawlen != 28) && (iRawlen != 12))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH);
+
+ pData->bHasMHDR = MNG_TRUE; /* oh boy, a real MNG */
+ pData->bHasheader = MNG_TRUE; /* we've got a header */
+ pData->eImagetype = mng_it_mng; /* fill header fields */
+ pData->iWidth = mng_get_uint32 (pRawdata);
+ pData->iHeight = mng_get_uint32 (pRawdata+4);
+ pData->iTicks = mng_get_uint32 (pRawdata+8);
+
+ if (iRawlen == 28) /* proper MHDR ? */
+ {
+ pData->iLayercount = mng_get_uint32 (pRawdata+12);
+ pData->iFramecount = mng_get_uint32 (pRawdata+16);
+ pData->iPlaytime = mng_get_uint32 (pRawdata+20);
+ pData->iSimplicity = mng_get_uint32 (pRawdata+24);
+
+ pData->bPreDraft48 = MNG_FALSE;
+ }
+ else /* probably pre-draft48 then */
+ {
+ pData->iLayercount = 0;
+ pData->iFramecount = 0;
+ pData->iPlaytime = 0;
+ pData->iSimplicity = 0;
+
+ pData->bPreDraft48 = MNG_TRUE;
+ }
+ /* predict alpha-depth */
+ if ((pData->iSimplicity & 0x00000001) == 0)
+ pData->iAlphadepth = 16; /* no indicators = assume the worst */
+ else
+ if ((pData->iSimplicity & 0x00000008) == 0)
+ pData->iAlphadepth = 0; /* no transparency at all */
+ else
+ if ((pData->iSimplicity & 0x00000140) == 0x00000040)
+ pData->iAlphadepth = 1; /* no semi-transparency guaranteed */
+ else
+ pData->iAlphadepth = 16; /* anything else = assume the worst */
+
+#ifdef MNG_INCLUDE_JNG /* can we handle the complexity ? */
+ if (pData->iSimplicity & 0x0000FC00)
+#else
+ if (pData->iSimplicity & 0x0000FC10)
+#endif
+ MNG_ERROR (pData, MNG_MNGTOOCOMPLEX)
+ /* fits on maximum canvas ? */
+ if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
+ MNG_WARNING (pData, MNG_IMAGETOOLARGE)
+
+ if (pData->fProcessheader) /* inform the app ? */
+ if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+
+ pData->iImagelevel++; /* one level deeper */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_mhdrp)*ppChunk)->iWidth = pData->iWidth;
+ ((mng_mhdrp)*ppChunk)->iHeight = pData->iHeight;
+ ((mng_mhdrp)*ppChunk)->iTicks = pData->iTicks;
+ ((mng_mhdrp)*ppChunk)->iLayercount = pData->iLayercount;
+ ((mng_mhdrp)*ppChunk)->iFramecount = pData->iFramecount;
+ ((mng_mhdrp)*ppChunk)->iPlaytime = pData->iPlaytime;
+ ((mng_mhdrp)*ppChunk)->iSimplicity = pData->iSimplicity;
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_MHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_mend)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_MEND, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen > 0) /* must not contain data! */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ { /* do something */
+ mng_retcode iRetcode = process_display_mend (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+ pData->bHasMHDR = MNG_FALSE; /* end of the line, bro! */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_MEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_loop)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_LOOP, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (!pData->bCacheplayback) /* must store playback info to work!! */
+ MNG_ERROR (pData, MNG_LOOPWITHCACHEOFF)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen >= 5) /* length checks */
+ {
+ if (iRawlen >= 6)
+ {
+ if ((iRawlen - 6) % 4 != 0)
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ }
+ else
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_uint8 iLevel;
+ mng_uint32 iRepeat;
+ mng_uint8 iTermination = 0;
+ mng_uint32 iItermin = 1;
+ mng_uint32 iItermax = 0x7fffffffL;
+ mng_retcode iRetcode;
+
+ pData->bHasLOOP = MNG_TRUE; /* indicate we're inside a loop */
+
+ iLevel = *pRawdata; /* determine the fields for processing */
+
+ if (pData->bPreDraft48)
+ {
+ iTermination = *(pRawdata+1);
+
+ iRepeat = mng_get_uint32 (pRawdata+2);
+ }
+ else
+ iRepeat = mng_get_uint32 (pRawdata+1);
+
+ if (iRawlen >= 6)
+ {
+ if (!pData->bPreDraft48)
+ iTermination = *(pRawdata+5);
+
+ if (iRawlen >= 10)
+ {
+ iItermin = mng_get_uint32 (pRawdata+6);
+
+ if (iRawlen >= 14)
+ {
+ iItermax = mng_get_uint32 (pRawdata+10);
+
+ /* TODO: process Q_SIGNALS */
+
+ }
+ }
+ }
+
+ /* create the LOOP ani-object */
+ iRetcode = create_ani_loop (pData, iLevel, iRepeat, iTermination,
+ iItermin, iItermax, 0, 0);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (iRawlen >= 5) /* store the fields */
+ {
+ ((mng_loopp)*ppChunk)->iLevel = *pRawdata;
+
+ if (pData->bPreDraft48)
+ {
+ ((mng_loopp)*ppChunk)->iTermination = *(pRawdata+1);
+ ((mng_loopp)*ppChunk)->iRepeat = mng_get_uint32 (pRawdata+2);
+ }
+ else
+ {
+ ((mng_loopp)*ppChunk)->iRepeat = mng_get_uint32 (pRawdata+1);
+ }
+
+ if (iRawlen >= 6)
+ {
+ if (!pData->bPreDraft48)
+ ((mng_loopp)*ppChunk)->iTermination = *(pRawdata+5);
+
+ if (iRawlen >= 10)
+ {
+ ((mng_loopp)*ppChunk)->iItermin = mng_get_uint32 (pRawdata+6);
+
+ if (iRawlen >= 14)
+ {
+ ((mng_loopp)*ppChunk)->iItermax = mng_get_uint32 (pRawdata+10);
+ ((mng_loopp)*ppChunk)->iCount = (iRawlen - 14) / 4;
+
+ if (((mng_loopp)*ppChunk)->iCount)
+ {
+ MNG_ALLOC (pData, ((mng_loopp)*ppChunk)->pSignals,
+ ((mng_loopp)*ppChunk)->iCount << 2)
+
+#ifndef MNG_BIGENDIAN_SUPPORTED
+ {
+ mng_uint32 iX;
+ mng_uint8p pIn = pRawdata + 14;
+ mng_uint32p pOut = (mng_uint32p)((mng_loopp)*ppChunk)->pSignals;
+
+ for (iX = 0; iX < ((mng_loopp)*ppChunk)->iCount; iX++)
+ {
+ *pOut++ = mng_get_uint32 (pIn);
+ pIn += 4;
+ }
+ }
+#else
+ MNG_COPY (((mng_loopp)*ppChunk)->pSignals, pRawdata + 14,
+ ((mng_loopp)*ppChunk)->iCount << 2)
+#endif /* !MNG_BIGENDIAN_SUPPORTED */
+ }
+ }
+ }
+ }
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_LOOP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_endl)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_ENDL, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen != 1) /* length must be exactly 1 */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ if (pData->bHasLOOP) /* are we really processing a loop ? */
+ {
+ mng_uint8 iLevel = *pRawdata; /* get the nest level */
+ /* create an ENDL animation object */
+ mng_retcode iRetcode = create_ani_endl (pData, iLevel);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ { /* process it */
+ mng_ani_endlp pENDL = (mng_ani_endlp)pData->pLastaniobj;
+
+ iRetcode = pENDL->sHeader.fProcess (pData, pENDL);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+ else
+ {
+
+ /* TODO: error abort ??? */
+
+ }
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_endlp)*ppChunk)->iLevel = *pRawdata;
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_ENDL, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_defi)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DEFI, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* check the length */
+ if ((iRawlen != 2) && (iRawlen != 3) && (iRawlen != 4) &&
+ (iRawlen != 12) && (iRawlen != 28))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode;
+
+ pData->iDEFIobjectid = mng_get_uint16 (pRawdata);
+
+ if (iRawlen > 2)
+ {
+ pData->bDEFIhasdonotshow = MNG_TRUE;
+ pData->iDEFIdonotshow = *(pRawdata+2);
+ }
+ else
+ {
+ pData->bDEFIhasdonotshow = MNG_FALSE;
+ pData->iDEFIdonotshow = 0;
+ }
+
+ if (iRawlen > 3)
+ {
+ pData->bDEFIhasconcrete = MNG_TRUE;
+ pData->iDEFIconcrete = *(pRawdata+3);
+ }
+ else
+ {
+ pData->bDEFIhasconcrete = MNG_FALSE;
+ pData->iDEFIconcrete = 0;
+ }
+
+ if (iRawlen > 4)
+ {
+ pData->bDEFIhasloca = MNG_TRUE;
+ pData->iDEFIlocax = mng_get_int32 (pRawdata+4);
+ pData->iDEFIlocay = mng_get_int32 (pRawdata+8);
+ }
+ else
+ {
+ pData->bDEFIhasloca = MNG_FALSE;
+ pData->iDEFIlocax = 0;
+ pData->iDEFIlocay = 0;
+ }
+
+ if (iRawlen > 12)
+ {
+ pData->bDEFIhasclip = MNG_TRUE;
+ pData->iDEFIclipl = mng_get_int32 (pRawdata+12);
+ pData->iDEFIclipr = mng_get_int32 (pRawdata+16);
+ pData->iDEFIclipt = mng_get_int32 (pRawdata+20);
+ pData->iDEFIclipb = mng_get_int32 (pRawdata+24);
+ }
+ else
+ {
+ pData->bDEFIhasclip = MNG_FALSE;
+ pData->iDEFIclipl = 0;
+ pData->iDEFIclipr = 0;
+ pData->iDEFIclipt = 0;
+ pData->iDEFIclipb = 0;
+ }
+ /* create an animation object */
+ iRetcode = create_ani_defi (pData);
+
+ if (!iRetcode) /* do display processing */
+ iRetcode = process_display_defi (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_defip)*ppChunk)->iObjectid = mng_get_uint16 (pRawdata);
+
+ if (iRawlen > 2)
+ {
+ ((mng_defip)*ppChunk)->bHasdonotshow = MNG_TRUE;
+ ((mng_defip)*ppChunk)->iDonotshow = *(pRawdata+2);
+ }
+ else
+ ((mng_defip)*ppChunk)->bHasdonotshow = MNG_FALSE;
+
+ if (iRawlen > 3)
+ {
+ ((mng_defip)*ppChunk)->bHasconcrete = MNG_TRUE;
+ ((mng_defip)*ppChunk)->iConcrete = *(pRawdata+3);
+ }
+ else
+ ((mng_defip)*ppChunk)->bHasconcrete = MNG_FALSE;
+
+ if (iRawlen > 4)
+ {
+ ((mng_defip)*ppChunk)->bHasloca = MNG_TRUE;
+ ((mng_defip)*ppChunk)->iXlocation = mng_get_int32 (pRawdata+4);
+ ((mng_defip)*ppChunk)->iYlocation = mng_get_int32 (pRawdata+8);
+ }
+ else
+ ((mng_defip)*ppChunk)->bHasloca = MNG_FALSE;
+
+ if (iRawlen > 12)
+ {
+ ((mng_defip)*ppChunk)->bHasclip = MNG_TRUE;
+ ((mng_defip)*ppChunk)->iLeftcb = mng_get_int32 (pRawdata+12);
+ ((mng_defip)*ppChunk)->iRightcb = mng_get_int32 (pRawdata+16);
+ ((mng_defip)*ppChunk)->iTopcb = mng_get_int32 (pRawdata+20);
+ ((mng_defip)*ppChunk)->iBottomcb = mng_get_int32 (pRawdata+24);
+ }
+ else
+ ((mng_defip)*ppChunk)->bHasclip = MNG_FALSE;
+
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DEFI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_basi)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_BASI, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* check the length */
+ if ((iRawlen != 13) && (iRawlen != 19) && (iRawlen != 21) && (iRawlen != 22))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ pData->bHasBASI = MNG_TRUE; /* inside a BASI-IEND block now */
+ /* store interesting fields */
+ pData->iDatawidth = mng_get_uint32 (pRawdata);
+ pData->iDataheight = mng_get_uint32 (pRawdata+4);
+ pData->iBitdepth = *(pRawdata+8);
+ pData->iColortype = *(pRawdata+9);
+ pData->iCompression = *(pRawdata+10);
+ pData->iFilter = *(pRawdata+11);
+ pData->iInterlace = *(pRawdata+12);
+
+ if ((pData->iBitdepth != 1) && /* parameter validity checks */
+ (pData->iBitdepth != 2) &&
+ (pData->iBitdepth != 4) &&
+ (pData->iBitdepth != 8) &&
+ (pData->iBitdepth != 16) )
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH)
+
+ if ((pData->iColortype != MNG_COLORTYPE_GRAY ) &&
+ (pData->iColortype != MNG_COLORTYPE_RGB ) &&
+ (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
+ (pData->iColortype != MNG_COLORTYPE_GRAYA ) &&
+ (pData->iColortype != MNG_COLORTYPE_RGBA ) )
+ MNG_ERROR (pData, MNG_INVALIDCOLORTYPE)
+
+ if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8))
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH)
+
+ if (((pData->iColortype == MNG_COLORTYPE_RGB ) ||
+ (pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
+ (pData->iColortype == MNG_COLORTYPE_RGBA ) ) &&
+ (pData->iBitdepth < 8 ) )
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH)
+
+ if (pData->iCompression != MNG_COMPRESSION_DEFLATE)
+ MNG_ERROR (pData, MNG_INVALIDCOMPRESS)
+
+ if (pData->iFilter & (~MNG_FILTER_DIFFERING))
+ MNG_ERROR (pData, MNG_INVALIDFILTER)
+
+ if ((pData->iInterlace != MNG_INTERLACE_NONE ) &&
+ (pData->iInterlace != MNG_INTERLACE_ADAM7) )
+ MNG_ERROR (pData, MNG_INVALIDINTERLACE)
+
+ pData->iImagelevel++; /* one level deeper */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_uint16 iRed = 0;
+ mng_uint16 iGreen = 0;
+ mng_uint16 iBlue = 0;
+ mng_bool bHasalpha = MNG_FALSE;
+ mng_uint16 iAlpha = 0xFFFF;
+ mng_uint8 iViewable = 0;
+ mng_retcode iRetcode;
+
+ if (iRawlen > 13) /* get remaining fields, if any */
+ {
+ iRed = mng_get_uint16 (pRawdata+13);
+ iGreen = mng_get_uint16 (pRawdata+15);
+ iBlue = mng_get_uint16 (pRawdata+17);
+ }
+
+ if (iRawlen > 19)
+ {
+ bHasalpha = MNG_TRUE;
+ iAlpha = mng_get_uint16 (pRawdata+19);
+ }
+
+ if (iRawlen > 21)
+ iViewable = *(pRawdata+21);
+ /* create an animation object */
+ iRetcode = create_ani_basi (pData, iRed, iGreen, iBlue,
+ bHasalpha, iAlpha, iViewable);
+
+ if (!iRetcode) /* display-processing... */
+ iRetcode = process_display_basi (pData, iRed, iGreen, iBlue,
+ bHasalpha, iAlpha, iViewable);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_basip)*ppChunk)->iWidth = mng_get_uint32 (pRawdata);
+ ((mng_basip)*ppChunk)->iHeight = mng_get_uint32 (pRawdata+4);
+ ((mng_basip)*ppChunk)->iBitdepth = *(pRawdata+8);
+ ((mng_basip)*ppChunk)->iColortype = *(pRawdata+9);
+ ((mng_basip)*ppChunk)->iCompression = *(pRawdata+10);
+ ((mng_basip)*ppChunk)->iFilter = *(pRawdata+11);
+ ((mng_basip)*ppChunk)->iInterlace = *(pRawdata+12);
+
+ if (iRawlen > 13)
+ {
+ ((mng_basip)*ppChunk)->iRed = mng_get_uint16 (pRawdata+13);
+ ((mng_basip)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+15);
+ ((mng_basip)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+17);
+ }
+
+ if (iRawlen > 19)
+ ((mng_basip)*ppChunk)->iAlpha = mng_get_uint16 (pRawdata+19);
+
+ if (iRawlen > 21)
+ ((mng_basip)*ppChunk)->iViewable = *(pRawdata+21);
+
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_BASI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_clon)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_CLON, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* check the length */
+ if ((iRawlen != 4) && (iRawlen != 5) && (iRawlen != 6) &&
+ (iRawlen != 7) && (iRawlen != 16))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_uint16 iSourceid, iCloneid;
+ mng_uint8 iClonetype = 0;
+ mng_bool bHasdonotshow = MNG_FALSE;
+ mng_uint8 iDonotshow = 0;
+ mng_uint8 iConcrete = 0;
+ mng_bool bHasloca = MNG_FALSE;
+ mng_uint8 iLocationtype = 0;
+ mng_int32 iLocationx = 0;
+ mng_int32 iLocationy = 0;
+ mng_retcode iRetcode;
+
+ iSourceid = mng_get_uint16 (pRawdata);
+ iCloneid = mng_get_uint16 (pRawdata+2);
+
+ if (iRawlen > 4)
+ iClonetype = *(pRawdata+4);
+
+ if (iRawlen > 5)
+ {
+ bHasdonotshow = MNG_TRUE;
+ iDonotshow = *(pRawdata+5);
+ }
+
+ if (iRawlen > 6)
+ iConcrete = *(pRawdata+6);
+
+ if (iRawlen > 7)
+ {
+ bHasloca = MNG_TRUE;
+ iLocationtype = *(pRawdata+7);
+ iLocationx = mng_get_int32 (pRawdata+8);
+ iLocationy = mng_get_int32 (pRawdata+12);
+ }
+
+ iRetcode = create_ani_clon (pData, iSourceid, iCloneid, iClonetype,
+ bHasdonotshow, iDonotshow, iConcrete,
+ bHasloca, iLocationtype, iLocationx, iLocationy);
+
+ if (!iRetcode) /* do display processing */
+ iRetcode = process_display_clon (pData, iSourceid, iCloneid, iClonetype,
+ bHasdonotshow, iDonotshow, iConcrete,
+ bHasloca, iLocationtype, iLocationx, iLocationy);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_clonp)*ppChunk)->iSourceid = mng_get_uint16 (pRawdata);
+ ((mng_clonp)*ppChunk)->iCloneid = mng_get_uint16 (pRawdata+2);
+
+ if (iRawlen > 4)
+ ((mng_clonp)*ppChunk)->iClonetype = *(pRawdata+4);
+
+ if (iRawlen > 5)
+ ((mng_clonp)*ppChunk)->iDonotshow = *(pRawdata+5);
+
+ if (iRawlen > 6)
+ ((mng_clonp)*ppChunk)->iConcrete = *(pRawdata+6);
+
+ if (iRawlen > 7)
+ {
+ ((mng_clonp)*ppChunk)->bHasloca = MNG_TRUE;
+ ((mng_clonp)*ppChunk)->iLocationtype = *(pRawdata+7);
+ ((mng_clonp)*ppChunk)->iLocationx = mng_get_int32 (pRawdata+8);
+ ((mng_clonp)*ppChunk)->iLocationy = mng_get_int32 (pRawdata+12);
+ }
+ else
+ {
+ ((mng_clonp)*ppChunk)->bHasloca = MNG_FALSE;
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_CLON, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_past)
+{
+#ifdef MNG_STORE_CHUNKS
+ mng_uint32 iCount;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PAST, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ /* check the length */
+ if ((iRawlen < 41) || (((iRawlen - 11) % 30) != 0))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_STORE_CHUNKS
+ iCount = ((iRawlen - 11) / 30); /* how many entries again */
+#endif
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ {
+ mng_uint32 iX;
+ mng_past_sourcep pSource;
+ /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_pastp)*ppChunk)->iDestid = mng_get_uint16 (pRawdata);
+ ((mng_pastp)*ppChunk)->iTargettype = *(pRawdata+2);
+ ((mng_pastp)*ppChunk)->iTargetx = mng_get_int32 (pRawdata+3);
+ ((mng_pastp)*ppChunk)->iTargety = mng_get_int32 (pRawdata+7);
+ ((mng_pastp)*ppChunk)->iCount = iCount;
+
+ pRawdata += 11;
+ /* get a buffer for all the source blocks */
+ MNG_ALLOC (pData, ((mng_pastp)*ppChunk)->pSources, (iCount * sizeof (mng_past_source)))
+
+ pSource = ((mng_pastp)*ppChunk)->pSources;
+
+ for (iX = 0; iX < iCount; iX++) /* now copy the source blocks */
+ {
+ pSource->iSourceid = mng_get_uint16 (pRawdata);
+ pSource->iComposition = *(pRawdata+2);
+ pSource->iOrientation = *(pRawdata+3);
+ pSource->iOffsettype = *(pRawdata+4);
+ pSource->iOffsetx = mng_get_int32 (pRawdata+5);
+ pSource->iOffsety = mng_get_int32 (pRawdata+9);
+ pSource->iBoundarytype = *(pRawdata+13);
+ pSource->iBoundaryl = mng_get_int32 (pRawdata+14);
+ pSource->iBoundaryr = mng_get_int32 (pRawdata+18);
+ pSource->iBoundaryt = mng_get_int32 (pRawdata+22);
+ pSource->iBoundaryb = mng_get_int32 (pRawdata+26);
+
+ pSource += sizeof (mng_past_source);
+ pRawdata += 30;
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PAST, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_disc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DISC, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if ((iRawlen % 2) != 0) /* check the length */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ { /* process it */
+ mng_retcode iRetcode = process_display_disc (pData, (iRawlen / 2),
+ (mng_uint16p)pRawdata);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_discp)*ppChunk)->iCount = iRawlen / 2;
+
+ MNG_ALLOC (pData, ((mng_discp)*ppChunk)->pObjectids, iRawlen)
+
+#ifndef MNG_BIGENDIAN_SUPPORTED
+ {
+ mng_uint32 iX;
+ mng_uint8p pIn = pRawdata;
+ mng_uint16p pOut = ((mng_discp)*ppChunk)->pObjectids;
+
+ for (iX = 0; iX < ((mng_discp)*ppChunk)->iCount; iX++)
+ {
+ *pOut++ = mng_get_uint16 (pIn);
+ pIn += 2;
+ }
+ }
+#else
+ MNG_COPY (((mng_discp)*ppChunk)->pObjectids, pRawdata, iRawlen)
+#endif /* !MNG_BIGENDIAN_SUPPORTED */
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DISC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_back)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_BACK, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* check the length */
+ if ((iRawlen != 6) && (iRawlen != 7) && (iRawlen != 9) && (iRawlen != 10))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode;
+ /* retrieve the fields */
+ pData->bHasBACK = MNG_TRUE;
+ pData->iBACKred = mng_get_uint16 (pRawdata);
+ pData->iBACKgreen = mng_get_uint16 (pRawdata+2);
+ pData->iBACKblue = mng_get_uint16 (pRawdata+4);
+
+ if (iRawlen > 6)
+ pData->iBACKmandatory = *(pRawdata+6);
+ else
+ pData->iBACKmandatory = 0;
+
+ if (iRawlen > 7)
+ pData->iBACKimageid = mng_get_uint16 (pRawdata+7);
+ else
+ pData->iBACKimageid = 0;
+
+ if (iRawlen > 9)
+ pData->iBACKtile = *(pRawdata+9);
+ else
+ pData->iBACKtile = 0;
+
+ iRetcode = create_ani_back (pData, pData->iBACKred, pData->iBACKgreen,
+ pData->iBACKblue, pData->iBACKmandatory,
+ pData->iBACKimageid, pData->iBACKtile);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_backp)*ppChunk)->iRed = mng_get_uint16 (pRawdata);
+ ((mng_backp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2);
+ ((mng_backp)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+4);
+
+ if (iRawlen > 6)
+ ((mng_backp)*ppChunk)->iMandatory = *(pRawdata+6);
+
+ if (iRawlen > 7)
+ ((mng_backp)*ppChunk)->iImageid = mng_get_uint16 (pRawdata+7);
+
+ if (iRawlen > 9)
+ ((mng_backp)*ppChunk)->iTile = *(pRawdata+9);
+
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_BACK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_fram)
+{
+ mng_uint8p pTemp;
+#ifdef MNG_STORE_CHUNKS
+ mng_uint32 iNamelen;
+#endif
+ mng_uint32 iRemain;
+ mng_uint32 iRequired = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_FRAM, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen <= 1) /* only framing-mode ? */
+ {
+#ifdef MNG_STORE_CHUNKS
+ iNamelen = 0; /* indicate so */
+#endif
+ iRemain = 0;
+ pTemp = MNG_NULL;
+ }
+ else
+ {
+ pTemp = tqfind_null (pRawdata+1); /* tqfind null-separator */
+ /* not found inside input-data ? */
+ if ((pTemp - pRawdata) > (mng_int32)iRawlen)
+ MNG_ERROR (pData, MNG_NULLNOTFOUND)
+
+#ifdef MNG_STORE_CHUNKS
+ iNamelen = (mng_uint32)((pTemp - pRawdata) - 1);
+#endif
+ iRemain = (mng_uint32)(iRawlen - (pTemp - pRawdata) - 1);
+ /* remains must be empty or at least 4 bytes */
+ if ((iRemain != 0) && (iRemain < 4))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if (iRemain)
+ {
+ iRequired = 4; /* calculate and check required remaining length */
+
+ if (*(pTemp+1)) { iRequired += 4; }
+ if (*(pTemp+2)) { iRequired += 4; }
+ if (*(pTemp+3)) { iRequired += 17; }
+
+ if (*(pTemp+4))
+ {
+ if ((iRemain - iRequired) % 4 != 0)
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ else
+ {
+ if (iRemain != iRequired)
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_uint8p pWork = pTemp;
+ mng_uint8 iFramemode = 0;
+ mng_uint8 iChangedelay = 0;
+ mng_uint32 iDelay = 0;
+ mng_uint8 iChangetimeout = 0;
+ mng_uint32 iTimeout = 0;
+ mng_uint8 iChangeclipping = 0;
+ mng_uint8 iCliptype = 0;
+ mng_int32 iClipl = 0;
+ mng_int32 iClipr = 0;
+ mng_int32 iClipt = 0;
+ mng_int32 iClipb = 0;
+ mng_retcode iRetcode;
+
+ if (iRawlen) /* any data specified ? */
+ {
+ if (*(pRawdata)) /* save the new framing mode ? */
+ {
+ iFramemode = *(pRawdata);
+
+ if (pData->bPreDraft48) /* old style input-stream ? */
+ {
+ switch (iFramemode)
+ {
+ case 0: { break; }
+ case 1: { iFramemode = 3; break; }
+ case 2: { iFramemode = 4; break; }
+ case 3: { iFramemode = 1; break; }
+ case 4: { iFramemode = 1; break; }
+ case 5: { iFramemode = 2; break; }
+ default: { iFramemode = 1; break; }
+ }
+ }
+ }
+
+ if (iRemain)
+ {
+ iChangedelay = *(pWork+1);
+ iChangetimeout = *(pWork+2);
+ iChangeclipping = *(pWork+3);
+ pWork += 5;
+
+ if (iChangedelay) /* delay changed ? */
+ {
+ iDelay = mng_get_uint32 (pWork);
+ pWork += 4;
+ }
+
+ if (iChangetimeout) /* timeout changed ? */
+ {
+ iTimeout = mng_get_uint32 (pWork);
+ pWork += 4;
+ }
+
+ if (iChangeclipping) /* clipping changed ? */
+ {
+ iCliptype = *pWork;
+ iClipl = mng_get_int32 (pWork+1);
+ iClipr = mng_get_int32 (pWork+5);
+ iClipt = mng_get_int32 (pWork+9);
+ iClipb = mng_get_int32 (pWork+13);
+ }
+ }
+ }
+
+ iRetcode = create_ani_fram (pData, iFramemode, iChangedelay, iDelay,
+ iChangetimeout, iTimeout,
+ iChangeclipping, iCliptype,
+ iClipl, iClipr, iClipt, iClipb);
+
+ if (!iRetcode) /* now go and do something */
+ iRetcode = process_display_fram (pData, iFramemode, iChangedelay, iDelay,
+ iChangetimeout, iTimeout,
+ iChangeclipping, iCliptype,
+ iClipl, iClipr, iClipt, iClipb);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_framp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen)
+ {
+ mng_uint8 iFramemode = *(pRawdata);
+
+ if (pData->bPreDraft48) /* old style input-stream ? */
+ {
+ switch (iFramemode)
+ {
+ case 1: { iFramemode = 3; break; }
+ case 2: { iFramemode = 4; break; }
+ case 3: { iFramemode = 5; break; } /* TODO: provision for mode=5 ??? */
+ case 4: { iFramemode = 1; break; }
+ case 5: { iFramemode = 2; break; }
+ default: { iFramemode = 1; break; }
+ }
+ }
+
+ ((mng_framp)*ppChunk)->iMode = iFramemode;
+ ((mng_framp)*ppChunk)->iNamesize = iNamelen;
+
+ if (iNamelen)
+ {
+ MNG_ALLOC (pData, ((mng_framp)*ppChunk)->zName, iNamelen+1)
+ MNG_COPY (((mng_framp)*ppChunk)->zName, pRawdata+1, iNamelen)
+ }
+
+ if (iRemain)
+ {
+ ((mng_framp)*ppChunk)->iChangedelay = *(pTemp+1);
+ ((mng_framp)*ppChunk)->iChangetimeout = *(pTemp+2);
+ ((mng_framp)*ppChunk)->iChangeclipping = *(pTemp+3);
+ ((mng_framp)*ppChunk)->iChangesyncid = *(pTemp+4);
+
+ pTemp += 5;
+
+ if (((mng_framp)*ppChunk)->iChangedelay)
+ {
+ ((mng_framp)*ppChunk)->iDelay = mng_get_uint32 (pTemp);
+ pTemp += 4;
+ }
+
+ if (((mng_framp)*ppChunk)->iChangetimeout)
+ {
+ ((mng_framp)*ppChunk)->iTimeout = mng_get_uint32 (pTemp);
+ pTemp += 4;
+ }
+
+ if (((mng_framp)*ppChunk)->iChangeclipping)
+ {
+ ((mng_framp)*ppChunk)->iBoundarytype = *pTemp;
+ ((mng_framp)*ppChunk)->iBoundaryl = mng_get_int32 (pTemp+1);
+ ((mng_framp)*ppChunk)->iBoundaryr = mng_get_int32 (pTemp+5);
+ ((mng_framp)*ppChunk)->iBoundaryt = mng_get_int32 (pTemp+9);
+ ((mng_framp)*ppChunk)->iBoundaryb = mng_get_int32 (pTemp+13);
+ pTemp += 17;
+ }
+
+ if (((mng_framp)*ppChunk)->iChangesyncid)
+ {
+ ((mng_framp)*ppChunk)->iCount = (iRemain - iRequired) / 4;
+
+ if (((mng_framp)*ppChunk)->iCount)
+ {
+ MNG_ALLOC (pData, ((mng_framp)*ppChunk)->pSyncids,
+ ((mng_framp)*ppChunk)->iCount * 4);
+
+#ifndef MNG_BIGENDIAN_SUPPORTED
+ {
+ mng_uint32 iX;
+ mng_uint32p pOut = ((mng_framp)*ppChunk)->pSyncids;
+
+ for (iX = 0; iX < ((mng_framp)*ppChunk)->iCount; iX++)
+ {
+ *pOut++ = mng_get_uint32 (pTemp);
+ pTemp += 4;
+ }
+ }
+#else
+ MNG_COPY (((mng_framp)*ppChunk)->pSyncids, pTemp,
+ ((mng_framp)*ppChunk)->iCount * 4)
+#endif /* !MNG_BIGENDIAN_SUPPORTED */
+ }
+ }
+ }
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_FRAM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_move)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_MOVE, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen != 13) /* check the length */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode;
+ /* create a MOVE animation object */
+ iRetcode = create_ani_move (pData, mng_get_uint16 (pRawdata),
+ mng_get_uint16 (pRawdata+2),
+ *(pRawdata+4),
+ mng_get_int32 (pRawdata+5),
+ mng_get_int32 (pRawdata+9));
+
+ if (!iRetcode) /* process the move */
+ iRetcode = process_display_move (pData,
+ mng_get_uint16 (pRawdata),
+ mng_get_uint16 (pRawdata+2),
+ *(pRawdata+4),
+ mng_get_int32 (pRawdata+5),
+ mng_get_int32 (pRawdata+9));
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_movep)*ppChunk)->iFirstid = mng_get_uint16 (pRawdata);
+ ((mng_movep)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2);
+ ((mng_movep)*ppChunk)->iMovetype = *(pRawdata+4);
+ ((mng_movep)*ppChunk)->iMovex = mng_get_int32 (pRawdata+5);
+ ((mng_movep)*ppChunk)->iMovey = mng_get_int32 (pRawdata+9);
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_MOVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_clip)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_CLIP, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen != 21) /* check the length */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode;
+ /* create a CLIP animation object */
+ iRetcode = create_ani_clip (pData, mng_get_uint16 (pRawdata),
+ mng_get_uint16 (pRawdata+2),
+ *(pRawdata+4),
+ mng_get_int32 (pRawdata+5),
+ mng_get_int32 (pRawdata+9),
+ mng_get_int32 (pRawdata+13),
+ mng_get_int32 (pRawdata+17));
+
+ if (!iRetcode) /* process the clipping */
+ iRetcode = process_display_clip (pData,
+ mng_get_uint16 (pRawdata),
+ mng_get_uint16 (pRawdata+2),
+ *(pRawdata+4),
+ mng_get_int32 (pRawdata+5),
+ mng_get_int32 (pRawdata+9),
+ mng_get_int32 (pRawdata+13),
+ mng_get_int32 (pRawdata+17));
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_clipp)*ppChunk)->iFirstid = mng_get_uint16 (pRawdata);
+ ((mng_clipp)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2);
+ ((mng_clipp)*ppChunk)->iCliptype = *(pRawdata+4);
+ ((mng_clipp)*ppChunk)->iClipl = mng_get_int32 (pRawdata+5);
+ ((mng_clipp)*ppChunk)->iClipr = mng_get_int32 (pRawdata+9);
+ ((mng_clipp)*ppChunk)->iClipt = mng_get_int32 (pRawdata+13);
+ ((mng_clipp)*ppChunk)->iClipb = mng_get_int32 (pRawdata+17);
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_CLIP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_show)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SHOW, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* check the length */
+ if ((iRawlen != 0) && (iRawlen != 2) && (iRawlen != 4) && (iRawlen != 5))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode;
+
+ if (iRawlen) /* determine parameters if any */
+ {
+ pData->iSHOWfromid = mng_get_uint16 (pRawdata);
+
+ if (iRawlen > 2)
+ pData->iSHOWtoid = mng_get_uint16 (pRawdata+2);
+ else
+ pData->iSHOWtoid = pData->iSHOWfromid;
+
+ if (iRawlen > 4)
+ pData->iSHOWmode = *(pRawdata+4);
+ else
+ pData->iSHOWmode = 0;
+ }
+ else /* use defaults then */
+ {
+ pData->iSHOWmode = 2;
+ pData->iSHOWfromid = 1;
+ pData->iSHOWtoid = 65535;
+ }
+ /* create a SHOW animation object */
+ iRetcode = create_ani_show (pData, pData->iSHOWfromid, pData->iSHOWtoid,
+ pData->iSHOWmode);
+
+ if (!iRetcode) /* go and do it! */
+ iRetcode = process_display_show (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_showp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen)
+ {
+ ((mng_showp)*ppChunk)->iFirstid = mng_get_uint16 (pRawdata);
+
+ if (iRawlen > 2)
+ ((mng_showp)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2);
+
+ if (iRawlen > 4)
+ ((mng_showp)*ppChunk)->iMode = *(pRawdata+4);
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SHOW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_term)
+{
+ mng_uint8 iTermaction;
+ mng_uint8 iIteraction = 0;
+ mng_uint32 iDelay = 0;
+ mng_uint32 iItermax = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_TERM, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (pData->bHasLOOP) /* no way, jose! */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (pData->bHasTERM) /* only 1 allowed! */
+ MNG_ERROR (pData, MNG_MULTIPLEERROR)
+ /* check the length */
+ if ((iRawlen != 1) && (iRawlen != 10))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ pData->bHasTERM = MNG_TRUE;
+ /* TODO: remove in 1.0.0 !!! */
+ if ((!pData->bHasSAVE) && (pData->iChunkseq > 2))
+ pData->bEMNGMAhack = MNG_TRUE;
+
+ iTermaction = *pRawdata; /* get the fields */
+
+ if (iRawlen > 1)
+ {
+ iIteraction = *(pRawdata+1);
+ iDelay = mng_get_uint32 (pRawdata+2);
+ iItermax = mng_get_uint32 (pRawdata+6);
+ }
+
+ if (pData->fProcessterm) /* inform the app ? */
+ if (!pData->fProcessterm (((mng_handle)pData), iTermaction, iIteraction,
+ iDelay, iItermax))
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ { /* create the TERM ani-object */
+ mng_retcode iRetcode = create_ani_term (pData, iTermaction, iIteraction,
+ iDelay, iItermax);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* save for future reference */
+ pData->pTermaniobj = pData->pLastaniobj;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_termp)*ppChunk)->iTermaction = iTermaction;
+ ((mng_termp)*ppChunk)->iIteraction = iIteraction;
+ ((mng_termp)*ppChunk)->iDelay = iDelay;
+ ((mng_termp)*ppChunk)->iItermax = iItermax;
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_TERM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_save)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SAVE, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) || (pData->bHasSAVE))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ pData->bHasSAVE = MNG_TRUE;
+
+ if (pData->fProcesssave) /* inform the application ? */
+ {
+ mng_bool bOke = pData->fProcesssave ((mng_handle)pData);
+
+ if (!bOke)
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+ }
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode;
+
+
+ /* TODO: something with the parameters */
+
+
+ /* create a SAVE animation object */
+ iRetcode = create_ani_save (pData);
+
+ if (!iRetcode) /* process it */
+ iRetcode = process_display_save (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_savep)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen) /* not empty ? */
+ {
+ mng_uint8 iOtype = *pRawdata;
+ mng_uint8 iEtype;
+ mng_uint32 iCount = 0;
+ mng_uint8p pTemp;
+ mng_uint8p pNull;
+ mng_uint32 iLen;
+ mng_uint32 iOffset[2];
+ mng_uint32 iStarttime[2];
+ mng_uint32 iFramenr;
+ mng_uint32 iLayernr;
+ mng_uint32 iX;
+ mng_save_entryp pEntry = MNG_NULL;
+ mng_uint32 iNamesize;
+
+ if ((iOtype != 4) && (iOtype != 8))
+ MNG_ERROR (pData, MNG_INVOFFSETSIZE);
+
+ ((mng_savep)*ppChunk)->iOffsettype = iOtype;
+
+ for (iX = 0; iX < 2; iX++) /* do this twice to get the count first ! */
+ {
+ pTemp = pRawdata + 1;
+ iLen = iRawlen - 1;
+
+ if (iX) /* second run ? */
+ {
+ MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_save_entry)))
+
+ ((mng_savep)*ppChunk)->iCount = iCount;
+ ((mng_savep)*ppChunk)->pEntries = pEntry;
+ }
+
+ while (iLen) /* anything left ? */
+ {
+ iEtype = *pTemp; /* entrytype */
+
+ if ((iEtype != 0) && (iEtype != 1) && (iEtype != 2) && (iEtype != 3))
+ MNG_ERROR (pData, MNG_INVENTRYTYPE);
+
+ pTemp++;
+
+ if (iEtype > 1)
+ {
+ iOffset [0] = 0;
+ iOffset [1] = 0;
+ iStarttime [0] = 0;
+ iStarttime [1] = 0;
+ iLayernr = 0;
+ iFramenr = 0;
+ }
+ else
+ {
+ if (iOtype == 4)
+ {
+ iOffset [0] = 0;
+ iOffset [1] = mng_get_uint32 (pTemp);
+
+ pTemp += 4;
+ }
+ else
+ {
+ iOffset [0] = mng_get_uint32 (pTemp);
+ iOffset [1] = mng_get_uint32 (pTemp+4);
+
+ pTemp += 8;
+ }
+
+ if (iEtype > 0)
+ {
+ iStarttime [0] = 0;
+ iStarttime [1] = 0;
+ iLayernr = 0;
+ iFramenr = 0;
+ }
+ else
+ {
+ if (iOtype == 4)
+ {
+ iStarttime [0] = 0;
+ iStarttime [1] = mng_get_uint32 (pTemp+0);
+ iLayernr = mng_get_uint32 (pTemp+4);
+ iFramenr = mng_get_uint32 (pTemp+8);
+
+ pTemp += 12;
+ }
+ else
+ {
+ iStarttime [0] = mng_get_uint32 (pTemp+0);
+ iStarttime [1] = mng_get_uint32 (pTemp+4);
+ iLayernr = mng_get_uint32 (pTemp+8);
+ iFramenr = mng_get_uint32 (pTemp+12);
+
+ pTemp += 16;
+ }
+ }
+ }
+
+ pNull = tqfind_null (pTemp); /* get the name length */
+
+ if ((pNull - pRawdata) > (mng_int32)iRawlen)
+ {
+ iNamesize = iLen; /* no null found; so end of SAVE */
+ iLen = 0;
+ }
+ else
+ {
+ iNamesize = pNull - pTemp; /* should be another entry */
+ iLen -= iNamesize;
+
+ if (!iLen) /* must not end with a null ! */
+ MNG_ERROR (pData, MNG_ENDWITHNULL)
+ }
+
+ if (!pEntry)
+ {
+ iCount++;
+ }
+ else
+ {
+ pEntry->iEntrytype = iEtype;
+ pEntry->iOffset [0] = iOffset [0];
+ pEntry->iOffset [1] = iOffset [1];
+ pEntry->iStarttime [0] = iStarttime [0];
+ pEntry->iStarttime [1] = iStarttime [1];
+ pEntry->iLayernr = iLayernr;
+ pEntry->iFramenr = iFramenr;
+ pEntry->iNamesize = iNamesize;
+
+ if (iNamesize)
+ {
+ MNG_ALLOC (pData, pEntry->zName, iNamesize+1)
+ MNG_COPY (pEntry->zName, pTemp, iNamesize)
+ }
+
+ pEntry++;
+ }
+
+ pTemp += iNamesize;
+ }
+ }
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SAVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_seek)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SEEK, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) || (!pData->bHasSAVE))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (pData->fProcessseek) /* inform the app ? */
+ {
+ mng_bool bOke;
+ mng_pchar zName;
+
+ MNG_ALLOC (pData, zName, iRawlen + 1)
+
+ if (iRawlen)
+ MNG_COPY (zName, pRawdata, iRawlen)
+
+ bOke = pData->fProcessseek ((mng_handle)pData, zName);
+
+ MNG_FREEX (pData, zName, iRawlen + 1)
+
+ if (!bOke)
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+ }
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode;
+
+
+ /* TODO: something with the name ??? */
+
+
+
+ /* create a SEEK animation object */
+ iRetcode = create_ani_seek (pData);
+
+ if (!iRetcode) /* process it */
+ iRetcode = process_display_seek (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_seekp)*ppChunk)->iNamesize = iRawlen;
+
+ if (iRawlen)
+ {
+ MNG_ALLOC (pData, ((mng_seekp)*ppChunk)->zName, iRawlen+1)
+ MNG_COPY (((mng_seekp)*ppChunk)->zName, pRawdata, iRawlen)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_SEEK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_expi)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_EXPI, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen < 3) /* check the length */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_expip)*ppChunk)->iSnapshotid = mng_get_uint16 (pRawdata);
+ ((mng_expip)*ppChunk)->iNamesize = iRawlen - 2;
+
+ if (((mng_expip)*ppChunk)->iNamesize)
+ {
+ MNG_ALLOC (pData, ((mng_expip)*ppChunk)->zName,
+ ((mng_expip)*ppChunk)->iNamesize + 1)
+ MNG_COPY (((mng_expip)*ppChunk)->zName, pRawdata+2,
+ ((mng_expip)*ppChunk)->iNamesize)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_EXPI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_fpri)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_FPRI, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen != 2) /* must be two bytes long */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_fprip)*ppChunk)->iDeltatype = *pRawdata;
+ ((mng_fprip)*ppChunk)->iPriority = *(pRawdata+1);
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_FPRI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+mng_bool CheckKeyword (mng_datap pData,
+ mng_uint8p pKeyword)
+{
+ mng_chunkid handled_chunks [] =
+ {
+ MNG_UINT_BACK,
+ MNG_UINT_BASI,
+ MNG_UINT_CLIP,
+ MNG_UINT_CLON,
+/* TODO: MNG_UINT_DBYK, */
+ MNG_UINT_DEFI,
+ MNG_UINT_DHDR,
+ MNG_UINT_DISC,
+/* TODO: MNG_UINT_DROP, */
+ MNG_UINT_ENDL,
+ MNG_UINT_FRAM,
+ MNG_UINT_IDAT,
+ MNG_UINT_IEND,
+ MNG_UINT_IHDR,
+ MNG_UINT_IJNG,
+ MNG_UINT_IPNG,
+#ifdef MNG_INCLUDE_JNG
+ MNG_UINT_JDAA,
+ MNG_UINT_JDAT,
+ MNG_UINT_JHDR,
+/* TODO: MNG_UINT_JSEP, */
+ MNG_UINT_JdAA,
+#endif
+ MNG_UINT_LOOP,
+ MNG_UINT_MAGN,
+ MNG_UINT_MEND,
+ MNG_UINT_MHDR,
+ MNG_UINT_MOVE,
+/* TODO: MNG_UINT_ORDR, */
+/* TODO: MNG_UINT_PAST, */
+ MNG_UINT_PLTE,
+ MNG_UINT_PPLT,
+ MNG_UINT_PROM,
+ MNG_UINT_SAVE,
+ MNG_UINT_SEEK,
+ MNG_UINT_SHOW,
+ MNG_UINT_TERM,
+ MNG_UINT_bKGD,
+ MNG_UINT_cHRM,
+/* TODO: MNG_UINT_eXPI, */
+/* TODO: MNG_UINT_fPRI, */
+ MNG_UINT_gAMA,
+/* TODO: MNG_UINT_hIST, */
+ MNG_UINT_iCCP,
+ MNG_UINT_iTXt,
+ MNG_UINT_nEED,
+/* TODO: MNG_UINT_oFFs, */
+/* TODO: MNG_UINT_pCAL, */
+/* TODO: MNG_UINT_pHYg, */
+/* TODO: MNG_UINT_pHYs, */
+/* TODO: MNG_UINT_sBIT, */
+/* TODO: MNG_UINT_sCAL, */
+/* TODO: MNG_UINT_sPLT, */
+ MNG_UINT_sRGB,
+ MNG_UINT_tEXt,
+ MNG_UINT_tIME,
+ MNG_UINT_tRNS,
+ MNG_UINT_zTXt,
+ };
+
+ mng_bool bOke = MNG_FALSE;
+
+ if (pData->fProcessneed) /* does the app handle it ? */
+ bOke = pData->fProcessneed ((mng_handle)pData, (mng_pchar)pKeyword);
+
+ if (!bOke)
+ { /* tqfind the keyword length */
+ mng_uint8p pNull = tqfind_null (pKeyword);
+
+ if (pNull - pKeyword == 4) /* test a chunk ? */
+ { /* get the chunk-id */
+ mng_chunkid iChunkid = (*pKeyword << 24) + (*(pKeyword+1) << 16) +
+ (*(pKeyword+2) << 8) + (*(pKeyword+3) );
+ /* binary search variables */
+ mng_int32 iTop, iLower, iUpper, iMiddle;
+ /* determine max index of table */
+ iTop = (sizeof (handled_chunks) / sizeof (handled_chunks [0])) - 1;
+
+ /* binary search; with 52 chunks, worst-case is 7 comparisons */
+ iLower = 0;
+ iMiddle = iTop >> 1;
+ iUpper = iTop;
+
+ do /* the binary search itself */
+ {
+ if (handled_chunks [iMiddle] < iChunkid)
+ iLower = iMiddle + 1;
+ else if (handled_chunks [iMiddle] > iChunkid)
+ iUpper = iMiddle - 1;
+ else
+ {
+ bOke = MNG_TRUE;
+ break;
+ }
+
+ iMiddle = (iLower + iUpper) >> 1;
+ }
+ while (iLower <= iUpper);
+ }
+ /* test draft ? */
+ if ((!bOke) && (pNull - pKeyword == 8) &&
+ (*pKeyword == 'd') && (*(pKeyword+1) == 'r') &&
+ (*(pKeyword+2) == 'a') && (*(pKeyword+3) == 'f') &&
+ (*(pKeyword+4) == 't') && (*(pKeyword+5) == ' '))
+ {
+ mng_uint32 iDraft;
+
+ iDraft = (*(pKeyword+6) - '0') * 10 + (*(pKeyword+7) - '0');
+ bOke = (mng_bool)(iDraft <= MNG_MNG_DRAFT);
+ }
+ /* test MNG 1.0 ? */
+ if ((!bOke) && (pNull - pKeyword == 7) &&
+ (*pKeyword == 'M') && (*(pKeyword+1) == 'N') &&
+ (*(pKeyword+2) == 'G') && (*(pKeyword+3) == '-') &&
+ (*(pKeyword+4) == '1') && (*(pKeyword+5) == '.') &&
+ (*(pKeyword+6) == '0'))
+ bOke = MNG_TRUE;
+
+ }
+
+ return bOke;
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_need)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_NEED, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen < 1) /* check the length */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ { /* let's check it */
+ mng_bool bOke = MNG_TRUE;
+ mng_pchar zKeywords;
+ mng_uint8p pNull, pTemp;
+
+ MNG_ALLOC (pData, zKeywords, iRawlen + 1)
+
+ if (iRawlen)
+ MNG_COPY (zKeywords, pRawdata, iRawlen)
+
+ pTemp = (mng_uint8p)zKeywords;
+ pNull = tqfind_null (pTemp);
+
+ while ((bOke) && (pNull < (mng_uint8p)zKeywords + iRawlen))
+ {
+ bOke = CheckKeyword (pData, pTemp);
+ pTemp = pNull + 1;
+ pNull = tqfind_null (pTemp);
+ }
+
+ if (bOke)
+ bOke = CheckKeyword (pData, pTemp);
+
+ MNG_FREEX (pData, zKeywords, iRawlen + 1)
+
+ if (!bOke)
+ MNG_ERROR (pData, MNG_UNSUPPORTEDNEED)
+ }
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_needp)*ppChunk)->iKeywordssize = iRawlen;
+
+ if (iRawlen)
+ {
+ MNG_ALLOC (pData, ((mng_needp)*ppChunk)->zKeywords, iRawlen+1)
+ MNG_COPY (((mng_needp)*ppChunk)->zKeywords, pRawdata, iRawlen)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_NEED, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_phyg)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PHYG, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* it's 9 bytes or empty; no more, no less! */
+ if ((iRawlen != 9) && (iRawlen != 0))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_phygp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+
+ if (iRawlen)
+ {
+ ((mng_phygp)*ppChunk)->iSizex = mng_get_uint32 (pRawdata);
+ ((mng_phygp)*ppChunk)->iSizey = mng_get_uint32 (pRawdata+4);
+ ((mng_phygp)*ppChunk)->iUnit = *(pRawdata+8);
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PHYG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+READ_CHUNK (read_jhdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_JHDR, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((pData->eSigtype != mng_it_jng) && (pData->eSigtype != mng_it_mng))
+ MNG_ERROR (pData, MNG_CHUNKNOTALLOWED)
+
+ if ((pData->eSigtype == mng_it_jng) && (pData->iChunkseq > 1))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen != 16) /* length oke ? */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+ /* inside a JHDR-IEND block now */
+ pData->bHasJHDR = MNG_TRUE;
+ /* and store interesting fields */
+ pData->iDatawidth = mng_get_uint32 (pRawdata);
+ pData->iDataheight = mng_get_uint32 (pRawdata+4);
+ pData->iJHDRcolortype = *(pRawdata+8);
+ pData->iJHDRimgbitdepth = *(pRawdata+9);
+ pData->iJHDRimgcompression = *(pRawdata+10);
+ pData->iJHDRimginterlace = *(pRawdata+11);
+ pData->iJHDRalphabitdepth = *(pRawdata+12);
+ pData->iJHDRalphacompression = *(pRawdata+13);
+ pData->iJHDRalphafilter = *(pRawdata+14);
+ pData->iJHDRalphainterlace = *(pRawdata+15);
+ /* parameter validity checks */
+ if ((pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAY ) &&
+ (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
+ (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
+ (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLORA) )
+ MNG_ERROR (pData, MNG_INVALIDCOLORTYPE)
+
+ if ((pData->iJHDRimgbitdepth != 8) &&
+ (pData->iJHDRimgbitdepth != 12) &&
+ (pData->iJHDRimgbitdepth != 20) )
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH)
+
+ if (pData->iJHDRimgcompression != MNG_COMPRESSION_BASELINEJPEG)
+ MNG_ERROR (pData, MNG_INVALIDCOMPRESS)
+
+ if ((pData->iJHDRimginterlace != MNG_INTERLACE_SETQUENTIAL ) &&
+ (pData->iJHDRimginterlace != MNG_INTERLACE_PROGRESSIVE) )
+ MNG_ERROR (pData, MNG_INVALIDINTERLACE)
+
+ if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
+ {
+ if ((pData->iJHDRalphabitdepth != 1) &&
+ (pData->iJHDRalphabitdepth != 2) &&
+ (pData->iJHDRalphabitdepth != 4) &&
+ (pData->iJHDRalphabitdepth != 8) &&
+ (pData->iJHDRalphabitdepth != 16) )
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH)
+
+ if ((pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE ) &&
+ (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG) )
+ MNG_ERROR (pData, MNG_INVALIDCOMPRESS)
+
+ if ((pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG) &&
+ (pData->iJHDRalphabitdepth != 8 ) )
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH)
+
+ if (pData->iJHDRalphafilter & (~MNG_FILTER_DIFFERING))
+ MNG_ERROR (pData, MNG_INVALIDFILTER)
+
+ if ((pData->iJHDRalphainterlace != MNG_INTERLACE_NONE ) &&
+ (pData->iJHDRalphainterlace != MNG_INTERLACE_ADAM7) )
+ MNG_ERROR (pData, MNG_INVALIDINTERLACE)
+
+ }
+ else
+ {
+ if (pData->iJHDRalphabitdepth != 0)
+ MNG_ERROR (pData, MNG_INVALIDBITDEPTH)
+
+ if (pData->iJHDRalphacompression != 0)
+ MNG_ERROR (pData, MNG_INVALIDCOMPRESS)
+
+ if (pData->iJHDRalphafilter != 0)
+ MNG_ERROR (pData, MNG_INVALIDFILTER)
+
+ if (pData->iJHDRalphainterlace != 0)
+ MNG_ERROR (pData, MNG_INVALIDINTERLACE)
+
+ }
+
+ if (!pData->bHasheader) /* first chunk ? */
+ {
+ pData->bHasheader = MNG_TRUE; /* we've got a header */
+ pData->eImagetype = mng_it_jng; /* then this must be a JNG */
+ pData->iWidth = mng_get_uint32 (pRawdata);
+ pData->iHeight = mng_get_uint32 (pRawdata+4);
+ /* predict alpha-depth ! */
+ if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
+ pData->iAlphadepth = pData->iJHDRalphabitdepth;
+ else
+ pData->iAlphadepth = 0;
+ /* fits on maximum canvas ? */
+ if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
+ MNG_WARNING (pData, MNG_IMAGETOOLARGE)
+
+ if (pData->fProcessheader) /* inform the app ? */
+ if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+
+ }
+
+ pData->iColortype = 0; /* fake grayscale for other routines */
+ pData->iImagelevel++; /* one level deeper */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode = process_display_jhdr (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_jhdrp)*ppChunk)->iWidth = mng_get_uint32 (pRawdata);
+ ((mng_jhdrp)*ppChunk)->iHeight = mng_get_uint32 (pRawdata+4);
+ ((mng_jhdrp)*ppChunk)->iColortype = *(pRawdata+8);
+ ((mng_jhdrp)*ppChunk)->iImagesampledepth = *(pRawdata+9);
+ ((mng_jhdrp)*ppChunk)->iImagecompression = *(pRawdata+10);
+ ((mng_jhdrp)*ppChunk)->iImageinterlace = *(pRawdata+11);
+ ((mng_jhdrp)*ppChunk)->iAlphasampledepth = *(pRawdata+12);
+ ((mng_jhdrp)*ppChunk)->iAlphacompression = *(pRawdata+13);
+ ((mng_jhdrp)*ppChunk)->iAlphafilter = *(pRawdata+14);
+ ((mng_jhdrp)*ppChunk)->iAlphainterlace = *(pRawdata+15);
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_JHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+#else
+#define read_jhdr 0
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+READ_CHUNK (read_jdaa)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_JDAA, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasJHDR) && (!pData->bHasDHDR))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (pData->bHasJSEP)
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG)
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen == 0) /* can never be empty */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ pData->bHasJDAA = MNG_TRUE; /* got some JDAA now, don't we */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ if (iRawlen)
+ { /* display processing for non-empty chunks */
+ mng_retcode iRetcode = process_display_jdaa (pData, iRawlen, pRawdata);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_jdaap)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+ ((mng_jdaap)*ppChunk)->iDatasize = iRawlen;
+
+ if (iRawlen != 0) /* is there any data ? */
+ {
+ MNG_ALLOC (pData, ((mng_jdaap)*ppChunk)->pData, iRawlen)
+ MNG_COPY (((mng_jdaap)*ppChunk)->pData, pRawdata, iRawlen)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_JDAA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+#else
+#define read_jdaa 0
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+READ_CHUNK (read_jdat)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_JDAT, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasJHDR) && (!pData->bHasDHDR))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen == 0) /* can never be empty */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ pData->bHasJDAT = MNG_TRUE; /* got some JDAT now, don't we */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ if (iRawlen)
+ { /* display processing for non-empty chunks */
+ mng_retcode iRetcode = process_display_jdat (pData, iRawlen, pRawdata);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_jdatp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+ ((mng_jdatp)*ppChunk)->iDatasize = iRawlen;
+
+ if (iRawlen != 0) /* is there any data ? */
+ {
+ MNG_ALLOC (pData, ((mng_jdatp)*ppChunk)->pData, iRawlen)
+ MNG_COPY (((mng_jdatp)*ppChunk)->pData, pRawdata, iRawlen)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_JDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+#else
+#define read_jdat 0
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+READ_CHUNK (read_jsep)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_JSEP, MNG_LC_START)
+#endif
+
+ if (!pData->bHasJHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen != 0) /* must be empty ! */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ pData->bHasJSEP = MNG_TRUE; /* indicate we've had the 8-/12-bit separator */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_JSEP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+#else
+#define read_jsep 0
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_dhdr)
+{
+ mng_uint8 iImagetype, iDeltatype;
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DHDR, MNG_LC_START)
+#endif
+
+ if (!pData->bHasMHDR) /* sequence checks */
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* check for valid length */
+ if ((iRawlen != 4) && (iRawlen != 12) && (iRawlen != 20))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ iImagetype = *(pRawdata+2); /* check fields for validity */
+ iDeltatype = *(pRawdata+3);
+
+ if (iImagetype > MNG_IMAGETYPE_JNG)
+ MNG_ERROR (pData, MNG_INVIMAGETYPE)
+
+ if (iDeltatype > MNG_DELTATYPE_NOCHANGE)
+ MNG_ERROR (pData, MNG_INVDELTATYPE)
+
+ if ((iDeltatype == MNG_DELTATYPE_REPLACE) && (iRawlen > 12))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((iDeltatype == MNG_DELTATYPE_NOCHANGE) && (iRawlen > 4))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ pData->bHasDHDR = MNG_TRUE; /* inside a DHDR-IEND block now */
+
+ pData->iImagelevel++; /* one level deeper */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_uint16 iObjectid = mng_get_uint16 (pRawdata);
+ mng_uint32 iBlockwidth = 0;
+ mng_uint32 iBlockheight = 0;
+ mng_uint32 iBlockx = 0;
+ mng_uint32 iBlocky = 0;
+ mng_retcode iRetcode;
+
+ if (iRawlen > 4)
+ {
+ iBlockwidth = mng_get_uint32 (pRawdata+4);
+ iBlockheight = mng_get_uint32 (pRawdata+8);
+ }
+
+ if (iRawlen > 12)
+ {
+ iBlockx = mng_get_uint32 (pRawdata+12);
+ iBlocky = mng_get_uint32 (pRawdata+16);
+ }
+
+ iRetcode = create_ani_dhdr (pData, iObjectid, iImagetype, iDeltatype,
+ iBlockwidth, iBlockheight, iBlockx, iBlocky);
+
+ if (!iRetcode) /* display processing ? */
+ iRetcode = process_display_dhdr (pData, iObjectid, iImagetype, iDeltatype,
+ iBlockwidth, iBlockheight, iBlockx, iBlocky);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_dhdrp)*ppChunk)->iObjectid = mng_get_uint16 (pRawdata);
+ ((mng_dhdrp)*ppChunk)->iImagetype = iImagetype;
+ ((mng_dhdrp)*ppChunk)->iDeltatype = iDeltatype;
+
+ if (iRawlen > 4)
+ {
+ ((mng_dhdrp)*ppChunk)->iBlockwidth = mng_get_uint32 (pRawdata+4);
+ ((mng_dhdrp)*ppChunk)->iBlockheight = mng_get_uint32 (pRawdata+8);
+ }
+
+ if (iRawlen > 12)
+ {
+ ((mng_dhdrp)*ppChunk)->iBlockx = mng_get_uint32 (pRawdata+12);
+ ((mng_dhdrp)*ppChunk)->iBlocky = mng_get_uint32 (pRawdata+16);
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_prom)
+{
+ mng_uint8 iColortype;
+ mng_uint8 iSampledepth;
+ mng_uint8 iFilltype;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PROM, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen != 3) /* gotta be exactly 3 bytes */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ iColortype = *pRawdata; /* check fields for validity */
+ iSampledepth = *(pRawdata+1);
+ iFilltype = *(pRawdata+2);
+
+ if ((iColortype != MNG_COLORTYPE_GRAY ) &&
+ (iColortype != MNG_COLORTYPE_RGB ) &&
+ (iColortype != MNG_COLORTYPE_INDEXED) &&
+ (iColortype != MNG_COLORTYPE_GRAYA ) &&
+ (iColortype != MNG_COLORTYPE_RGBA ) )
+ MNG_ERROR (pData, MNG_INVALIDCOLORTYPE)
+
+ if ((iSampledepth != MNG_BITDEPTH_1 ) &&
+ (iSampledepth != MNG_BITDEPTH_2 ) &&
+ (iSampledepth != MNG_BITDEPTH_4 ) &&
+ (iSampledepth != MNG_BITDEPTH_8 ) &&
+ (iSampledepth != MNG_BITDEPTH_16) )
+ MNG_ERROR (pData, MNG_INVSAMPLEDEPTH)
+
+ if ((iFilltype != MNG_FILLMETHOD_LEFTBITREPLICATE) &&
+ (iFilltype != MNG_FILLMETHOD_ZEROFILL ) )
+ MNG_ERROR (pData, MNG_INVFILLMETHOD)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode = create_ani_prom (pData, iSampledepth, iColortype, iFilltype);
+
+ if (!iRetcode) /* display processing ? */
+ iRetcode = process_display_prom (pData, iSampledepth,
+ iColortype, iFilltype);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_promp)*ppChunk)->iColortype = iColortype;
+ ((mng_promp)*ppChunk)->iSampledepth = iSampledepth;
+ ((mng_promp)*ppChunk)->iFilltype = iFilltype;
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PROM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_ipng)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_IPNG, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen != 0) /* gotta be empty */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode = create_ani_ipng (pData);
+
+ if (!iRetcode) /* process it */
+ iRetcode = process_display_ipng (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_IPNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_pplt)
+{
+ mng_uint8 iDeltatype;
+ mng_uint8p pTemp;
+ mng_uint32 iLen;
+ mng_uint8 iX, iM;
+ mng_uint32 iY;
+ mng_uint32 iMax;
+ mng_rgbpaltab aIndexentries;
+ mng_uint8arr aAlphaentries;
+ mng_uint8arr aUsedentries;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PPLT, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) && (!pData->bHasDHDR))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen < 1) /* must have at least 1 byte */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ iDeltatype = *pRawdata;
+ /* valid ? */
+ if (iDeltatype > MNG_DELTATYPE_DELTARGBA)
+ MNG_ERROR (pData, MNG_INVDELTATYPE)
+ /* must be indexed color ! */
+ if (pData->iColortype != MNG_COLORTYPE_INDEXED)
+ MNG_ERROR (pData, MNG_INVALIDCOLORTYPE)
+
+ pTemp = pRawdata + 1;
+ iLen = iRawlen - 1;
+ iMax = 0;
+
+ for (iY = 0; iY < 256; iY++) /* reset arrays */
+ {
+ aIndexentries [iY].iRed = 0;
+ aIndexentries [iY].iGreen = 0;
+ aIndexentries [iY].iBlue = 0;
+ aAlphaentries [iY] = 255;
+ aUsedentries [iY] = 0;
+ }
+
+ while (iLen) /* as long as there are entries left ... */
+ {
+ mng_uint32 iDiff;
+
+ if (iLen < 2)
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ iX = *pTemp; /* get start and end index */
+ iM = *(pTemp+1);
+
+ if (iM < iX)
+ MNG_ERROR (pData, MNG_INVALIDINDEX)
+
+ if ((mng_uint32)iM >= iMax) /* determine highest used index */
+ iMax = (mng_uint32)iM + 1;
+
+ pTemp += 2;
+ iLen -= 2;
+
+ if ((iDeltatype == MNG_DELTATYPE_REPLACERGB ) ||
+ (iDeltatype == MNG_DELTATYPE_DELTARGB ) )
+ iDiff = (iM - iX + 1) * 3;
+ else
+ if ((iDeltatype == MNG_DELTATYPE_REPLACEALPHA) ||
+ (iDeltatype == MNG_DELTATYPE_DELTAALPHA ) )
+ iDiff = (iM - iX + 1);
+ else
+ iDiff = (iM - iX + 1) * 4;
+
+ if (iLen < iDiff)
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if ((iDeltatype == MNG_DELTATYPE_REPLACERGB ) ||
+ (iDeltatype == MNG_DELTATYPE_DELTARGB ) )
+ {
+ for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
+ {
+ aIndexentries [iY].iRed = *pTemp;
+ aIndexentries [iY].iGreen = *(pTemp+1);
+ aIndexentries [iY].iBlue = *(pTemp+2);
+ aUsedentries [iY] = 1;
+
+ pTemp += 3;
+ iLen -= 3;
+ }
+ }
+ else
+ if ((iDeltatype == MNG_DELTATYPE_REPLACEALPHA) ||
+ (iDeltatype == MNG_DELTATYPE_DELTAALPHA ) )
+ {
+ for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
+ {
+ aAlphaentries [iY] = *pTemp;
+ aUsedentries [iY] = 1;
+
+ pTemp++;
+ iLen--;
+ }
+ }
+ else
+ {
+ for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
+ {
+ aIndexentries [iY].iRed = *pTemp;
+ aIndexentries [iY].iGreen = *(pTemp+1);
+ aIndexentries [iY].iBlue = *(pTemp+2);
+ aAlphaentries [iY] = *(pTemp+3);
+ aUsedentries [iY] = 1;
+
+ pTemp += 4;
+ iLen -= 4;
+ }
+ }
+ }
+
+ switch (pData->iBitdepth) /* check maximum allowed entries for bitdepth */
+ {
+ case MNG_BITDEPTH_1 : {
+ if (iMax > 2)
+ MNG_ERROR (pData, MNG_INVALIDINDEX)
+ break;
+ }
+ case MNG_BITDEPTH_2 : {
+ if (iMax > 4)
+ MNG_ERROR (pData, MNG_INVALIDINDEX)
+ break;
+ }
+ case MNG_BITDEPTH_4 : {
+ if (iMax > 16)
+ MNG_ERROR (pData, MNG_INVALIDINDEX)
+ break;
+ }
+ }
+
+#ifdef MNG_SUPPORT_DISPLAY
+ { /* create animation object */
+ mng_retcode iRetcode = create_ani_pplt (pData, iDeltatype, iMax,
+ aIndexentries, aAlphaentries,
+ aUsedentries);
+
+ if (!iRetcode) /* execute it now ? */
+ iRetcode = process_display_pplt (pData, iDeltatype, iMax, aIndexentries,
+ aAlphaentries, aUsedentries);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_ppltp)*ppChunk)->iDeltatype = iDeltatype;
+ ((mng_ppltp)*ppChunk)->iCount = iMax;
+
+ for (iY = 0; iY < 256; iY++)
+ {
+ ((mng_ppltp)*ppChunk)->aEntries [iY].iRed = aIndexentries [iY].iRed;
+ ((mng_ppltp)*ppChunk)->aEntries [iY].iGreen = aIndexentries [iY].iGreen;
+ ((mng_ppltp)*ppChunk)->aEntries [iY].iBlue = aIndexentries [iY].iBlue;
+ ((mng_ppltp)*ppChunk)->aEntries [iY].iAlpha = aAlphaentries [iY];
+ ((mng_ppltp)*ppChunk)->aEntries [iY].bUsed = (mng_bool)(aUsedentries [iY]);
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_PPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_ijng)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_IJNG, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen != 0) /* gotta be empty */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode = create_ani_ijng (pData);
+
+ if (!iRetcode) /* process it */
+ iRetcode = process_display_ijng (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_IJNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_drop)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DROP, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* check length */
+ if ((iRawlen < 4) || ((iRawlen % 4) != 0))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_dropp)*ppChunk)->iCount = iRawlen / 4;
+
+ if (iRawlen)
+ {
+ mng_uint32 iX;
+ mng_uint8p pTemp = pRawdata;
+ mng_uint32p pEntry;
+
+ MNG_ALLOC (pData, pEntry, iRawlen)
+
+ ((mng_dropp)*ppChunk)->pChunknames = (mng_ptr)pEntry;
+
+ for (iX = 0; iX < iRawlen / 4; iX++)
+ {
+ *pEntry = mng_get_uint32 (pTemp);
+
+ pTemp += 4;
+ pEntry++;
+ }
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DROP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_dbyk)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DBYK, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+
+ if (iRawlen < 6) /* must be at least 6 long */
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_dbykp)*ppChunk)->iChunkname = mng_get_uint32 (pRawdata);
+ ((mng_dbykp)*ppChunk)->iPolarity = *(pRawdata+4);
+ ((mng_dbykp)*ppChunk)->iKeywordssize = iRawlen - 5;
+
+ if (iRawlen > 5)
+ {
+ MNG_ALLOC (pData, ((mng_dbykp)*ppChunk)->zKeywords, iRawlen-4)
+ MNG_COPY (((mng_dbykp)*ppChunk)->zKeywords, pRawdata+5, iRawlen-5)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DBYK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_ordr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_ORDR, MNG_LC_START)
+#endif
+ /* sequence checks */
+ if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* check length */
+ if ((iRawlen < 5) || ((iRawlen % 5) != 0))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+
+
+ /* TODO: something !!! */
+
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_ordrp)*ppChunk)->iCount = iRawlen / 5;
+
+ if (iRawlen)
+ {
+ mng_uint32 iX;
+ mng_ordr_entryp pEntry;
+ mng_uint8p pTemp = pRawdata;
+
+ MNG_ALLOC (pData, pEntry, iRawlen)
+
+ ((mng_ordrp)*ppChunk)->pEntries = pEntry;
+
+ for (iX = 0; iX < iRawlen / 5; iX++)
+ {
+ pEntry->iChunkname = mng_get_uint32 (pTemp);
+ pEntry->iOrdertype = *(pTemp+4);
+
+ pTemp += 5;
+ pEntry++;
+ }
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_ORDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_magn)
+{
+ mng_uint16 iFirstid, iLastid;
+ mng_uint16 iMethodX, iMethodY;
+ mng_uint16 iMX, iMY, iML, iMR, iMT, iMB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_MAGN, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_SUPPORT_JNG
+ if ((!pData->bHasMHDR) || (pData->bHasIHDR) || (pData->bHasDHDR) || (pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) || (pData->bHasIHDR) || (pData->bHasDHDR))
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* check length */
+ if ((iRawlen > 20) || ((iRawlen & 0x01) != 0))
+ MNG_ERROR (pData, MNG_INVALIDLENGTH)
+
+ if (iRawlen > 0) /* get the fields */
+ iFirstid = mng_get_uint16 (pRawdata);
+ else
+ iFirstid = 0;
+
+ if (iRawlen > 2)
+ iLastid = mng_get_uint16 (pRawdata+2);
+ else
+ iLastid = iFirstid;
+
+ if (iRawlen > 4)
+ iMethodX = mng_get_uint16 (pRawdata+4);
+ else
+ iMethodX = 0;
+
+ if (iRawlen > 6)
+ iMX = mng_get_uint16 (pRawdata+6);
+ else
+ iMX = 1;
+
+ if (iRawlen > 8)
+ iMY = mng_get_uint16 (pRawdata+8);
+ else
+ iMY = iMX;
+
+ if (iRawlen > 10)
+ iML = mng_get_uint16 (pRawdata+10);
+ else
+ iML = iMX;
+
+ if (iRawlen > 12)
+ iMR = mng_get_uint16 (pRawdata+12);
+ else
+ iMR = iMX;
+
+ if (iRawlen > 14)
+ iMT = mng_get_uint16 (pRawdata+14);
+ else
+ iMT = iMY;
+
+ if (iRawlen > 16)
+ iMB = mng_get_uint16 (pRawdata+16);
+ else
+ iMB = iMY;
+
+ if (iRawlen > 18)
+ iMethodY = mng_get_uint16 (pRawdata+18);
+ else
+ iMethodY = iMethodX;
+ /* check field validity */
+ if ((iMethodX > 5) || (iMethodY > 5))
+ MNG_ERROR (pData, MNG_INVALIDMETHOD)
+
+#ifdef MNG_SUPPORT_DISPLAY
+ {
+ mng_retcode iRetcode;
+
+ iRetcode = create_ani_magn (pData, iFirstid, iLastid, iMethodX,
+ iMX, iMY, iML, iMR, iMT, iMB, iMethodY);
+
+ if (!iRetcode) /* display processing ? */
+ iRetcode = process_display_magn (pData, iFirstid, iLastid, iMethodX,
+ iMX, iMY, iML, iMR, iMT, iMB, iMethodY);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the fields */
+ ((mng_magnp)*ppChunk)->iFirstid = iFirstid;
+ ((mng_magnp)*ppChunk)->iLastid = iLastid;
+ ((mng_magnp)*ppChunk)->iMethodX = iMethodX;
+ ((mng_magnp)*ppChunk)->iMX = iMX;
+ ((mng_magnp)*ppChunk)->iMY = iMY;
+ ((mng_magnp)*ppChunk)->iML = iML;
+ ((mng_magnp)*ppChunk)->iMR = iMR;
+ ((mng_magnp)*ppChunk)->iMT = iMT;
+ ((mng_magnp)*ppChunk)->iMB = iMB;
+ ((mng_magnp)*ppChunk)->iMethodY = iMethodY;
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_MAGN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+READ_CHUNK (read_unknown)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_UNKNOWN, MNG_LC_START)
+#endif
+ /* sequence checks */
+#ifdef MNG_INCLUDE_JNG
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
+ (!pData->bHasBASI) && (!pData->bHasDHDR) )
+#endif
+ MNG_ERROR (pData, MNG_SETQUENCEERROR)
+ /* critical chunk ? */
+ if (((mng_uint32)pData->iChunkname & 0x20000000) == 0)
+ MNG_ERROR (pData, MNG_UNKNOWNCRITICAL)
+
+ if (pData->fProcessunknown) /* let the app handle it ? */
+ {
+ mng_bool bOke = pData->fProcessunknown ((mng_handle)pData, pData->iChunkname,
+ iRawlen, (mng_ptr)pRawdata);
+
+ if (!bOke)
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+ }
+
+#ifdef MNG_STORE_CHUNKS
+ if (pData->bStorechunks)
+ { /* initialize storage */
+ mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* store the length */
+ ((mng_chunk_headerp)*ppChunk)->iChunkname = pData->iChunkname;
+ ((mng_unknown_chunkp)*ppChunk)->iDatasize = iRawlen;
+
+ if (iRawlen == 0) /* any data at all ? */
+ ((mng_unknown_chunkp)*ppChunk)->pData = 0;
+ else
+ { /* then store it */
+ MNG_ALLOC (pData, ((mng_unknown_chunkp)*ppChunk)->pData, iRawlen)
+ MNG_COPY (((mng_unknown_chunkp)*ppChunk)->pData, pRawdata, iRawlen)
+ }
+ }
+#endif /* MNG_STORE_CHUNKS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_UNKNOWN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_READ_PROCS */
+
+/* ************************************************************************** */
+/* * * */
+/* * chunk write functions * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_WRITE_PROCS
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_ihdr)
+{
+ mng_ihdrp pIHDR;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_IHDR, MNG_LC_START)
+#endif
+
+ pIHDR = (mng_ihdrp)pChunk; /* address the proper chunk */
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 13;
+ /* fill the output buffer */
+ mng_put_uint32 (pRawdata, pIHDR->iWidth);
+ mng_put_uint32 (pRawdata+4, pIHDR->iHeight);
+
+ *(pRawdata+8) = pIHDR->iBitdepth;
+ *(pRawdata+9) = pIHDR->iColortype;
+ *(pRawdata+10) = pIHDR->iCompression;
+ *(pRawdata+11) = pIHDR->iFilter;
+ *(pRawdata+12) = pIHDR->iInterlace;
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pIHDR->sHeader.iChunkname, iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_IHDR, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_plte)
+{
+ mng_pltep pPLTE;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint8p pTemp;
+ mng_uint32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PLTE, MNG_LC_START)
+#endif
+
+ pPLTE = (mng_pltep)pChunk; /* address the proper chunk */
+
+ if (pPLTE->bEmpty) /* write empty chunk ? */
+ iRetcode = write_raw_chunk (pData, pPLTE->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pPLTE->iEntrycount * 3;
+ /* fill the output buffer */
+ pTemp = pRawdata;
+
+ for (iX = 0; iX < pPLTE->iEntrycount; iX++)
+ {
+ *pTemp = pPLTE->aEntries [iX].iRed;
+ *(pTemp+1) = pPLTE->aEntries [iX].iGreen;
+ *(pTemp+2) = pPLTE->aEntries [iX].iBlue;
+
+ pTemp += 3;
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pPLTE->sHeader.iChunkname, iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PLTE, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_idat)
+{
+ mng_idatp pIDAT;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_IDAT, MNG_LC_START)
+#endif
+
+ pIDAT = (mng_idatp)pChunk; /* address the proper chunk */
+
+ if (pIDAT->bEmpty) /* and write it */
+ iRetcode = write_raw_chunk (pData, pIDAT->sHeader.iChunkname, 0, 0);
+ else
+ iRetcode = write_raw_chunk (pData, pIDAT->sHeader.iChunkname,
+ pIDAT->iDatasize, pIDAT->pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_IDAT, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_iend)
+{
+ mng_iendp pIEND;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_IEND, MNG_LC_START)
+#endif
+
+ pIEND = (mng_iendp)pChunk; /* address the proper chunk */
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pIEND->sHeader.iChunkname, 0, 0);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_IEND, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_trns)
+{
+ mng_trnsp pTRNS;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint8p pTemp;
+ mng_uint32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_TRNS, MNG_LC_START)
+#endif
+
+ pTRNS = (mng_trnsp)pChunk; /* address the proper chunk */
+
+ if (pTRNS->bEmpty) /* write empty chunk ? */
+ iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname, 0, 0);
+ else
+ if (pTRNS->bGlobal) /* write global chunk ? */
+ iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname,
+ pTRNS->iRawlen, (mng_uint8p)pTRNS->aRawdata);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer */
+ iRawlen = 0; /* and default size */
+
+ switch (pTRNS->iType)
+ {
+ case 0: {
+ iRawlen = 2; /* fill the size & output buffer */
+ mng_put_uint16 (pRawdata, pTRNS->iGray);
+
+ break;
+ }
+ case 2: {
+ iRawlen = 6; /* fill the size & output buffer */
+ mng_put_uint16 (pRawdata, pTRNS->iRed);
+ mng_put_uint16 (pRawdata+2, pTRNS->iGreen);
+ mng_put_uint16 (pRawdata+4, pTRNS->iBlue);
+
+ break;
+ }
+ case 3: { /* init output buffer size */
+ iRawlen = pTRNS->iCount;
+
+ pTemp = pRawdata; /* fill the output buffer */
+
+ for (iX = 0; iX < pTRNS->iCount; iX++)
+ {
+ *pTemp = pTRNS->aEntries[iX];
+ pTemp++;
+ }
+
+ break;
+ }
+ }
+ /* write the chunk */
+ iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_TRNS, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_gama)
+{
+ mng_gamap pGAMA;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_GAMA, MNG_LC_START)
+#endif
+
+ pGAMA = (mng_gamap)pChunk; /* address the proper chunk */
+
+ if (pGAMA->bEmpty) /* write empty ? */
+ iRetcode = write_raw_chunk (pData, pGAMA->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 4;
+ /* fill the buffer */
+ mng_put_uint32 (pRawdata, pGAMA->iGamma);
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pGAMA->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_GAMA, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_chrm)
+{
+ mng_chrmp pCHRM;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_CHRM, MNG_LC_START)
+#endif
+
+ pCHRM = (mng_chrmp)pChunk; /* address the proper chunk */
+
+ if (pCHRM->bEmpty) /* write empty ? */
+ iRetcode = write_raw_chunk (pData, pCHRM->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 32;
+ /* fill the buffer */
+ mng_put_uint32 (pRawdata, pCHRM->iWhitepointx);
+ mng_put_uint32 (pRawdata+4, pCHRM->iWhitepointy);
+ mng_put_uint32 (pRawdata+8, pCHRM->iRedx);
+ mng_put_uint32 (pRawdata+12, pCHRM->iRedy);
+ mng_put_uint32 (pRawdata+16, pCHRM->iGreenx);
+ mng_put_uint32 (pRawdata+20, pCHRM->iGreeny);
+ mng_put_uint32 (pRawdata+24, pCHRM->iBluex);
+ mng_put_uint32 (pRawdata+28, pCHRM->iBluey);
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pCHRM->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_CHRM, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_srgb)
+{
+ mng_srgbp pSRGB;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SRGB, MNG_LC_START)
+#endif
+
+ pSRGB = (mng_srgbp)pChunk; /* address the proper chunk */
+
+ if (pSRGB->bEmpty) /* write empty ? */
+ iRetcode = write_raw_chunk (pData, pSRGB->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 1;
+ /* fill the buffer */
+ *pRawdata = pSRGB->iRenderingintent;
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pSRGB->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SRGB, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_iccp)
+{
+ mng_iccpp pICCP;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint8p pTemp;
+ mng_uint8p pBuf = 0;
+ mng_uint32 iBuflen;
+ mng_uint32 iReallen;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_ICCP, MNG_LC_START)
+#endif
+
+ pICCP = (mng_iccpp)pChunk; /* address the proper chunk */
+
+ if (pICCP->bEmpty) /* write empty ? */
+ iRetcode = write_raw_chunk (pData, pICCP->sHeader.iChunkname, 0, 0);
+ else
+ { /* compress the profile */
+ iRetcode = deflate_buffer (pData, pICCP->pProfile, pICCP->iProfilesize,
+ &pBuf, &iBuflen, &iReallen);
+
+ if (!iRetcode) /* still oke ? */
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pICCP->iNamesize + 2 + iReallen;
+ /* requires large buffer ? */
+ if (iRawlen > pData->iWritebufsize)
+ MNG_ALLOC (pData, pRawdata, iRawlen)
+
+ pTemp = pRawdata; /* fill the buffer */
+
+ if (pICCP->iNamesize)
+ {
+ MNG_COPY (pTemp, pICCP->zName, pICCP->iNamesize)
+ pTemp += pICCP->iNamesize;
+ }
+
+ *pTemp = 0;
+ *(pTemp+1) = pICCP->iCompression;
+ pTemp += 2;
+
+ if (iReallen)
+ MNG_COPY (pTemp, pBuf, iReallen)
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pICCP->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ /* drop the temp buffer ? */
+ if (iRawlen > pData->iWritebufsize)
+ MNG_FREEX (pData, pRawdata, iRawlen)
+
+ }
+
+ MNG_FREEX (pData, pBuf, iBuflen) /* always drop the extra buffer */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_ICCP, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_text)
+{
+ mng_textp pTEXT;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint8p pTemp;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_TEXT, MNG_LC_START)
+#endif
+
+ pTEXT = (mng_textp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pTEXT->iKeywordsize + 1 + pTEXT->iTextsize;
+ /* requires large buffer ? */
+ if (iRawlen > pData->iWritebufsize)
+ MNG_ALLOC (pData, pRawdata, iRawlen)
+
+ pTemp = pRawdata; /* fill the buffer */
+
+ if (pTEXT->iKeywordsize)
+ {
+ MNG_COPY (pTemp, pTEXT->zKeyword, pTEXT->iKeywordsize)
+ pTemp += pTEXT->iKeywordsize;
+ }
+
+ *pTemp = 0;
+ pTemp += 1;
+
+ if (pTEXT->iTextsize)
+ MNG_COPY (pTemp, pTEXT->zText, pTEXT->iTextsize)
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pTEXT->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+ if (iRawlen > pData->iWritebufsize) /* drop the temp buffer ? */
+ MNG_FREEX (pData, pRawdata, iRawlen)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_TEXT, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_ztxt)
+{
+ mng_ztxtp pZTXT;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint8p pTemp;
+ mng_uint8p pBuf = 0;
+ mng_uint32 iBuflen;
+ mng_uint32 iReallen;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_ZTXT, MNG_LC_START)
+#endif
+
+ pZTXT = (mng_ztxtp)pChunk; /* address the proper chunk */
+ /* compress the text */
+ iRetcode = deflate_buffer (pData, (mng_uint8p)pZTXT->zText, pZTXT->iTextsize,
+ &pBuf, &iBuflen, &iReallen);
+
+ if (!iRetcode) /* all ok ? */
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pZTXT->iKeywordsize + 2 + iReallen;
+ /* requires large buffer ? */
+ if (iRawlen > pData->iWritebufsize)
+ MNG_ALLOC (pData, pRawdata, iRawlen)
+
+ pTemp = pRawdata; /* fill the buffer */
+
+ if (pZTXT->iKeywordsize)
+ {
+ MNG_COPY (pTemp, pZTXT->zKeyword, pZTXT->iKeywordsize)
+ pTemp += pZTXT->iKeywordsize;
+ }
+
+ *pTemp = 0; /* terminator zero */
+ pTemp++;
+ *pTemp = 0; /* compression type */
+ pTemp++;
+
+ if (iReallen)
+ MNG_COPY (pTemp, pBuf, iReallen)
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pZTXT->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ /* drop the temp buffer ? */
+ if (iRawlen > pData->iWritebufsize)
+ MNG_FREEX (pData, pRawdata, iRawlen)
+
+ }
+
+ MNG_FREEX (pData, pBuf, iBuflen); /* always drop the compression buffer */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_ZTXT, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_itxt)
+{
+ mng_itxtp pITXT;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint8p pTemp;
+ mng_uint8p pBuf = 0;
+ mng_uint32 iBuflen;
+ mng_uint32 iReallen;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_ITXT, MNG_LC_START)
+#endif
+
+ pITXT = (mng_itxtp)pChunk; /* address the proper chunk */
+
+ if (pITXT->iCompressionflag) /* compress the text */
+ iRetcode = deflate_buffer (pData, (mng_uint8p)pITXT->zText, pITXT->iTextsize,
+ &pBuf, &iBuflen, &iReallen);
+ else
+ iRetcode = MNG_NOERROR;
+
+ if (!iRetcode) /* all ok ? */
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pITXT->iKeywordsize + pITXT->iLanguagesize +
+ pITXT->iTranslationsize + 5;
+
+ if (pITXT->iCompressionflag)
+ iRawlen = iRawlen + iReallen;
+ else
+ iRawlen = iRawlen + pITXT->iTextsize;
+ /* requires large buffer ? */
+ if (iRawlen > pData->iWritebufsize)
+ MNG_ALLOC (pData, pRawdata, iRawlen)
+
+ pTemp = pRawdata; /* fill the buffer */
+
+ if (pITXT->iKeywordsize)
+ {
+ MNG_COPY (pTemp, pITXT->zKeyword, pITXT->iKeywordsize)
+ pTemp += pITXT->iKeywordsize;
+ }
+
+ *pTemp = 0;
+ pTemp++;
+ *pTemp = pITXT->iCompressionflag;
+ pTemp++;
+ *pTemp = pITXT->iCompressionmethod;
+ pTemp++;
+
+ if (pITXT->iLanguagesize)
+ {
+ MNG_COPY (pTemp, pITXT->zLanguage, pITXT->iLanguagesize)
+ pTemp += pITXT->iLanguagesize;
+ }
+
+ *pTemp = 0;
+ pTemp++;
+
+ if (pITXT->iTranslationsize)
+ {
+ MNG_COPY (pTemp, pITXT->zTranslation, pITXT->iTranslationsize)
+ pTemp += pITXT->iTranslationsize;
+ }
+
+ *pTemp = 0;
+ pTemp++;
+
+ if (pITXT->iCompressionflag)
+ {
+ if (iReallen)
+ MNG_COPY (pTemp, pBuf, iReallen)
+ }
+ else
+ {
+ if (pITXT->iTextsize)
+ MNG_COPY (pTemp, pITXT->zText, pITXT->iTextsize)
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pITXT->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ /* drop the temp buffer ? */
+ if (iRawlen > pData->iWritebufsize)
+ MNG_FREEX (pData, pRawdata, iRawlen)
+
+ }
+
+ MNG_FREEX (pData, pBuf, iBuflen); /* always drop the compression buffer */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_ITXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_bkgd)
+{
+ mng_bkgdp pBKGD;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_BKGD, MNG_LC_START)
+#endif
+
+ pBKGD = (mng_bkgdp)pChunk; /* address the proper chunk */
+
+ if (pBKGD->bEmpty) /* write empty ? */
+ iRetcode = write_raw_chunk (pData, pBKGD->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 0; /* and default size */
+
+ switch (pBKGD->iType)
+ {
+ case 0: { /* gray */
+ iRawlen = 2; /* fill the size & output buffer */
+ mng_put_uint16 (pRawdata, pBKGD->iGray);
+
+ break;
+ }
+ case 2: { /* rgb */
+ iRawlen = 6; /* fill the size & output buffer */
+ mng_put_uint16 (pRawdata, pBKGD->iRed);
+ mng_put_uint16 (pRawdata+2, pBKGD->iGreen);
+ mng_put_uint16 (pRawdata+4, pBKGD->iBlue);
+
+ break;
+ }
+ case 3: { /* indexed */
+ iRawlen = 1; /* fill the size & output buffer */
+ *pRawdata = pBKGD->iIndex;
+
+ break;
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pBKGD->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_BKGD, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_phys)
+{
+ mng_physp pPHYS;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PHYS, MNG_LC_START)
+#endif
+
+ pPHYS = (mng_physp)pChunk; /* address the proper chunk */
+
+ if (pPHYS->bEmpty) /* write empty ? */
+ iRetcode = write_raw_chunk (pData, pPHYS->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 9;
+ /* fill the output buffer */
+ mng_put_uint32 (pRawdata, pPHYS->iSizex);
+ mng_put_uint32 (pRawdata+4, pPHYS->iSizey);
+
+ *(pRawdata+8) = pPHYS->iUnit;
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pPHYS->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PHYS, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_sbit)
+{
+ mng_sbitp pSBIT;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SBIT, MNG_LC_START)
+#endif
+
+ pSBIT = (mng_sbitp)pChunk; /* address the proper chunk */
+
+ if (pSBIT->bEmpty) /* write empty ? */
+ iRetcode = write_raw_chunk (pData, pSBIT->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 0; /* and default size */
+
+ switch (pSBIT->iType)
+ {
+ case 0: { /* gray */
+ iRawlen = 1; /* fill the size & output buffer */
+ *pRawdata = pSBIT->aBits[0];
+
+ break;
+ }
+ case 2: { /* rgb */
+ iRawlen = 3; /* fill the size & output buffer */
+ *pRawdata = pSBIT->aBits[0];
+ *(pRawdata+1) = pSBIT->aBits[1];
+ *(pRawdata+2) = pSBIT->aBits[2];
+
+ break;
+ }
+ case 3: { /* indexed */
+ iRawlen = 1; /* fill the size & output buffer */
+ *pRawdata = pSBIT->aBits[0];
+
+ break;
+ }
+ case 4: { /* gray + alpha */
+ iRawlen = 2; /* fill the size & output buffer */
+ *pRawdata = pSBIT->aBits[0];
+ *(pRawdata+1) = pSBIT->aBits[1];
+
+ break;
+ }
+ case 6: { /* rgb + alpha */
+ iRawlen = 4; /* fill the size & output buffer */
+ *pRawdata = pSBIT->aBits[0];
+ *(pRawdata+1) = pSBIT->aBits[1];
+ *(pRawdata+2) = pSBIT->aBits[2];
+ *(pRawdata+3) = pSBIT->aBits[3];
+
+ break;
+ }
+ case 10: { /* jpeg gray */
+ iRawlen = 1; /* fill the size & output buffer */
+ *pRawdata = pSBIT->aBits[0];
+
+ break;
+ }
+ case 12: { /* jpeg rgb */
+ iRawlen = 3; /* fill the size & output buffer */
+ *pRawdata = pSBIT->aBits[0];
+ *(pRawdata+1) = pSBIT->aBits[1];
+ *(pRawdata+2) = pSBIT->aBits[2];
+
+ break;
+ }
+ case 14: { /* jpeg gray + alpha */
+ iRawlen = 2; /* fill the size & output buffer */
+ *pRawdata = pSBIT->aBits[0];
+ *(pRawdata+1) = pSBIT->aBits[1];
+
+ break;
+ }
+ case 16: { /* jpeg rgb + alpha */
+ iRawlen = 4; /* fill the size & output buffer */
+ *pRawdata = pSBIT->aBits[0];
+ *(pRawdata+1) = pSBIT->aBits[1];
+ *(pRawdata+2) = pSBIT->aBits[2];
+ *(pRawdata+3) = pSBIT->aBits[3];
+
+ break;
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pSBIT->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SBIT, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_splt)
+{
+ mng_spltp pSPLT;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint32 iEntrieslen;
+ mng_uint8p pTemp;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SPLT, MNG_LC_START)
+#endif
+
+ pSPLT = (mng_spltp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iEntrieslen = ((pSPLT->iSampledepth >> 3) * 4 + 2) * pSPLT->iEntrycount;
+ iRawlen = pSPLT->iNamesize + 2 + iEntrieslen;
+ /* requires large buffer ? */
+ if (iRawlen > pData->iWritebufsize)
+ MNG_ALLOC (pData, pRawdata, iRawlen)
+
+ pTemp = pRawdata; /* fill the buffer */
+
+ if (pSPLT->iNamesize)
+ {
+ MNG_COPY (pTemp, pSPLT->zName, pSPLT->iNamesize)
+ pTemp += pSPLT->iNamesize;
+ }
+
+ *pTemp = 0;
+ *(pTemp+1) = pSPLT->iSampledepth;
+ pTemp += 2;
+
+ if (pSPLT->iEntrycount)
+ MNG_COPY (pTemp, pSPLT->pEntries, iEntrieslen)
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pSPLT->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+ if (iRawlen > pData->iWritebufsize) /* drop the temp buffer ? */
+ MNG_FREEX (pData, pRawdata, iRawlen)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SPLT, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_hist)
+{
+ mng_histp pHIST;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint8p pTemp;
+ mng_uint32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_HIST, MNG_LC_START)
+#endif
+
+ pHIST = (mng_histp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pHIST->iEntrycount << 1;
+
+ pTemp = pRawdata; /* fill the output buffer */
+
+ for (iX = 0; iX < pHIST->iEntrycount; iX++)
+ {
+ mng_put_uint16 (pTemp, pHIST->aEntries [iX]);
+ pTemp += 2;
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pHIST->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_HIST, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_time)
+{
+ mng_timep pTIME;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_TIME, MNG_LC_START)
+#endif
+
+ pTIME = (mng_timep)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 7;
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pTIME->iYear);
+
+ *(pRawdata+2) = pTIME->iMonth;
+ *(pRawdata+3) = pTIME->iDay;
+ *(pRawdata+4) = pTIME->iHour;
+ *(pRawdata+5) = pTIME->iMinute;
+ *(pRawdata+6) = pTIME->iSecond;
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pTIME->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_TIME, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_mhdr)
+{
+ mng_mhdrp pMHDR;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_MHDR, MNG_LC_START)
+#endif
+
+ pMHDR = (mng_mhdrp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 28;
+ /* fill the output buffer */
+ mng_put_uint32 (pRawdata, pMHDR->iWidth);
+ mng_put_uint32 (pRawdata+4, pMHDR->iHeight);
+ mng_put_uint32 (pRawdata+8, pMHDR->iTicks);
+ mng_put_uint32 (pRawdata+12, pMHDR->iLayercount);
+ mng_put_uint32 (pRawdata+16, pMHDR->iFramecount);
+ mng_put_uint32 (pRawdata+20, pMHDR->iPlaytime);
+ mng_put_uint32 (pRawdata+24, pMHDR->iSimplicity);
+
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pMHDR->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_MHDR, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_mend)
+{
+ mng_mendp pMEND;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_MEND, MNG_LC_START)
+#endif
+
+ pMEND = (mng_mendp)pChunk; /* address the proper chunk */
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pMEND->sHeader.iChunkname, 0, 0);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_MEND, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_loop)
+{
+ mng_loopp pLOOP;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint8p pTemp1;
+ mng_uint32p pTemp2;
+ mng_uint32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_LOOP, MNG_LC_START)
+#endif
+
+ pLOOP = (mng_loopp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 5;
+ /* fill the output buffer */
+ *pRawdata = pLOOP->iLevel;
+ mng_put_uint32 (pRawdata+1, pLOOP->iRepeat);
+
+ if (pLOOP->iTermination)
+ {
+ iRawlen++;
+ *(pRawdata+5) = pLOOP->iTermination;
+
+ if ((pLOOP->iCount) ||
+ (pLOOP->iItermin != 1) || (pLOOP->iItermax != 0x7FFFFFFFL))
+ {
+ iRawlen += 8;
+
+ mng_put_uint32 (pRawdata+6, pLOOP->iItermin);
+ mng_put_uint32 (pRawdata+10, pLOOP->iItermax);
+
+ if (pLOOP->iCount)
+ {
+ iRawlen += pLOOP->iCount * 4;
+
+ pTemp1 = pRawdata+14;
+ pTemp2 = pLOOP->pSignals;
+
+ for (iX = 0; iX < pLOOP->iCount; iX++)
+ {
+ mng_put_uint32 (pTemp1, *pTemp2);
+
+ pTemp1 += 4;
+ pTemp2++;
+ }
+ }
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pLOOP->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_LOOP, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_endl)
+{
+ mng_endlp pENDL;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_ENDL, MNG_LC_START)
+#endif
+
+ pENDL = (mng_endlp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 1;
+
+ *pRawdata = pENDL->iLevel; /* fill the output buffer */
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pENDL->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_ENDL, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_defi)
+{
+ mng_defip pDEFI;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_DEFI, MNG_LC_START)
+#endif
+
+ pDEFI = (mng_defip)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 2;
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pDEFI->iObjectid);
+
+ if ((pDEFI->iDonotshow) || (pDEFI->iConcrete) || (pDEFI->bHasloca) || (pDEFI->bHasclip))
+ {
+ iRawlen++;
+ *(pRawdata+2) = pDEFI->iDonotshow;
+
+ if ((pDEFI->iConcrete) || (pDEFI->bHasloca) || (pDEFI->bHasclip))
+ {
+ iRawlen++;
+ *(pRawdata+3) = pDEFI->iConcrete;
+
+ if ((pDEFI->bHasloca) || (pDEFI->bHasclip))
+ {
+ iRawlen += 8;
+
+ mng_put_uint32 (pRawdata+4, pDEFI->iXlocation);
+ mng_put_uint32 (pRawdata+8, pDEFI->iYlocation);
+
+ if (pDEFI->bHasclip)
+ {
+ iRawlen += 16;
+
+ mng_put_uint32 (pRawdata+12, pDEFI->iLeftcb);
+ mng_put_uint32 (pRawdata+16, pDEFI->iRightcb);
+ mng_put_uint32 (pRawdata+20, pDEFI->iTopcb);
+ mng_put_uint32 (pRawdata+24, pDEFI->iBottomcb);
+ }
+ }
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pDEFI->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_DEFI, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_basi)
+{
+ mng_basip pBASI;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_bool bOpaque;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_BASI, MNG_LC_START)
+#endif
+
+ pBASI = (mng_basip)pChunk; /* address the proper chunk */
+
+ if (pBASI->iBitdepth <= 8) /* determine opacity alpha-field */
+ bOpaque = (mng_bool)(pBASI->iAlpha == 0xFF);
+ else
+ bOpaque = (mng_bool)(pBASI->iAlpha == 0xFFFF);
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 13;
+ /* fill the output buffer */
+ mng_put_uint32 (pRawdata, pBASI->iWidth);
+ mng_put_uint32 (pRawdata+4, pBASI->iHeight);
+
+ *(pRawdata+8) = pBASI->iBitdepth;
+ *(pRawdata+9) = pBASI->iColortype;
+ *(pRawdata+10) = pBASI->iCompression;
+ *(pRawdata+11) = pBASI->iFilter;
+ *(pRawdata+12) = pBASI->iInterlace;
+
+ if ((pBASI->iRed) || (pBASI->iGreen) || (pBASI->iBlue) ||
+ (!bOpaque) || (pBASI->iViewable))
+ {
+ iRawlen += 6;
+ mng_put_uint16 (pRawdata+13, pBASI->iRed);
+ mng_put_uint16 (pRawdata+15, pBASI->iGreen);
+ mng_put_uint16 (pRawdata+17, pBASI->iBlue);
+
+ if ((!bOpaque) || (pBASI->iViewable))
+ {
+ iRawlen += 2;
+ mng_put_uint16 (pRawdata+19, pBASI->iAlpha);
+
+ if (pBASI->iViewable)
+ {
+ iRawlen++;
+ *(pRawdata+21) = pBASI->iViewable;
+ }
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pBASI->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_BASI, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_clon)
+{
+ mng_clonp pCLON;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_CLON, MNG_LC_START)
+#endif
+
+ pCLON = (mng_clonp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 4;
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pCLON->iSourceid);
+ mng_put_uint16 (pRawdata+2, pCLON->iCloneid);
+
+ if ((pCLON->iClonetype) || (pCLON->iDonotshow) || (pCLON->iConcrete) || (pCLON->bHasloca))
+ {
+ iRawlen++;
+ *(pRawdata+4) = pCLON->iClonetype;
+
+ if ((pCLON->iDonotshow) || (pCLON->iConcrete) || (pCLON->bHasloca))
+ {
+ iRawlen++;
+ *(pRawdata+5) = pCLON->iDonotshow;
+
+ if ((pCLON->iConcrete) || (pCLON->bHasloca))
+ {
+ iRawlen++;
+ *(pRawdata+6) = pCLON->iConcrete;
+
+ if (pCLON->bHasloca)
+ {
+ iRawlen += 9;
+ *(pRawdata+7) = pCLON->iLocationtype;
+ mng_put_int32 (pRawdata+8, pCLON->iLocationx);
+ mng_put_int32 (pRawdata+12, pCLON->iLocationy);
+ }
+ }
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pCLON->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_CLON, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_past)
+{
+ mng_pastp pPAST;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_past_sourcep pSource;
+ mng_uint32 iX;
+ mng_uint8p pTemp;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PAST, MNG_LC_START)
+#endif
+
+ pPAST = (mng_pastp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 11 + (30 * pPAST->iCount);
+ /* requires large buffer ? */
+ if (iRawlen > pData->iWritebufsize)
+ MNG_ALLOC (pData, pRawdata, iRawlen)
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pPAST->iDestid);
+
+ *(pRawdata+2) = pPAST->iTargettype;
+
+ mng_put_int32 (pRawdata+3, pPAST->iTargetx);
+ mng_put_int32 (pRawdata+7, pPAST->iTargety);
+
+ pTemp = pRawdata+11;
+ pSource = pPAST->pSources;
+
+ for (iX = 0; iX < pPAST->iCount; iX++)
+ {
+ mng_put_uint16 (pTemp, pSource->iSourceid);
+
+ *(pTemp+2) = pSource->iComposition;
+ *(pTemp+3) = pSource->iOrientation;
+ *(pTemp+4) = pSource->iOffsettype;
+
+ mng_put_int32 (pTemp+5, pSource->iOffsetx);
+ mng_put_int32 (pTemp+9, pSource->iOffsety);
+
+ *(pTemp+13) = pSource->iBoundarytype;
+
+ mng_put_int32 (pTemp+14, pSource->iBoundaryl);
+ mng_put_int32 (pTemp+18, pSource->iBoundaryr);
+ mng_put_int32 (pTemp+22, pSource->iBoundaryt);
+ mng_put_int32 (pTemp+26, pSource->iBoundaryb);
+
+ pSource++;
+ pTemp += 30;
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pPAST->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ /* free temporary buffer ? */
+ if (iRawlen > pData->iWritebufsize)
+ MNG_FREEX (pData, pRawdata, iRawlen)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PAST, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_disc)
+{
+ mng_discp pDISC;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint32 iX;
+ mng_uint8p pTemp1;
+ mng_uint16p pTemp2;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_DISC, MNG_LC_START)
+#endif
+
+ pDISC = (mng_discp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pDISC->iCount << 1;
+
+ pTemp1 = pRawdata; /* fill the output buffer */
+ pTemp2 = pDISC->pObjectids;
+
+ for (iX = 0; iX < pDISC->iCount; iX++)
+ {
+ mng_put_uint16 (pTemp1, *pTemp2);
+
+ pTemp2++;
+ pTemp1 += 2;
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pDISC->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_DISC, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_back)
+{
+ mng_backp pBACK;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_BACK, MNG_LC_START)
+#endif
+
+ pBACK = (mng_backp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 6;
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pBACK->iRed);
+ mng_put_uint16 (pRawdata+2, pBACK->iGreen);
+ mng_put_uint16 (pRawdata+4, pBACK->iBlue);
+
+ if ((pBACK->iMandatory) || (pBACK->iImageid) || (pBACK->iTile))
+ {
+ iRawlen++;
+ *(pRawdata+6) = pBACK->iMandatory;
+
+ if ((pBACK->iImageid) || (pBACK->iTile))
+ {
+ iRawlen += 2;
+ mng_put_uint16 (pRawdata+7, pBACK->iImageid);
+
+ if (pBACK->iTile)
+ {
+ iRawlen++;
+ *(pRawdata+9) = pBACK->iTile;
+ }
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pBACK->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_BACK, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_fram)
+{
+ mng_framp pFRAM;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint8p pTemp;
+ mng_uint32p pTemp2;
+ mng_uint32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_FRAM, MNG_LC_START)
+#endif
+
+ pFRAM = (mng_framp)pChunk; /* address the proper chunk */
+
+ if (pFRAM->bEmpty) /* empty ? */
+ iRetcode = write_raw_chunk (pData, pFRAM->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 1;
+ /* fill the output buffer */
+ *pRawdata = pFRAM->iMode;
+
+ if ((pFRAM->iNamesize ) ||
+ (pFRAM->iChangedelay ) || (pFRAM->iChangetimeout) ||
+ (pFRAM->iChangeclipping) || (pFRAM->iChangesyncid ) )
+ {
+ if (pFRAM->iNamesize)
+ MNG_COPY (pRawdata+1, pFRAM->zName, pFRAM->iNamesize)
+
+ iRawlen += pFRAM->iNamesize;
+ pTemp = pRawdata + pFRAM->iNamesize + 1;
+
+ if ((pFRAM->iChangedelay ) || (pFRAM->iChangetimeout) ||
+ (pFRAM->iChangeclipping) || (pFRAM->iChangesyncid ) )
+ {
+ *pTemp = 0;
+ *(pTemp+1) = pFRAM->iChangedelay;
+ *(pTemp+2) = pFRAM->iChangetimeout;
+ *(pTemp+3) = pFRAM->iChangeclipping;
+ *(pTemp+4) = pFRAM->iChangesyncid;
+
+ iRawlen += 5;
+ pTemp += 5;
+
+ if (pFRAM->iChangedelay)
+ {
+ mng_put_uint32 (pTemp, pFRAM->iDelay);
+ iRawlen += 4;
+ pTemp += 4;
+ }
+
+ if (pFRAM->iChangetimeout)
+ {
+ mng_put_uint32 (pTemp, pFRAM->iTimeout);
+ iRawlen += 4;
+ pTemp += 4;
+ }
+
+ if (pFRAM->iChangeclipping)
+ {
+ *pTemp = pFRAM->iBoundarytype;
+
+ mng_put_uint32 (pTemp+1, pFRAM->iBoundaryl);
+ mng_put_uint32 (pTemp+5, pFRAM->iBoundaryr);
+ mng_put_uint32 (pTemp+9, pFRAM->iBoundaryt);
+ mng_put_uint32 (pTemp+13, pFRAM->iBoundaryb);
+
+ iRawlen += 17;
+ pTemp += 17;
+ }
+
+ if (pFRAM->iChangesyncid)
+ {
+ iRawlen += pFRAM->iCount * 4;
+ pTemp2 = pFRAM->pSyncids;
+
+ for (iX = 0; iX < pFRAM->iCount; iX++)
+ {
+ mng_put_uint32 (pTemp, *pTemp2);
+
+ pTemp2++;
+ pTemp += 4;
+ }
+ }
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pFRAM->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_FRAM, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_move)
+{
+ mng_movep pMOVE;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_MOVE, MNG_LC_START)
+#endif
+
+ pMOVE = (mng_movep)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 13;
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pMOVE->iFirstid);
+ mng_put_uint16 (pRawdata+2, pMOVE->iLastid);
+
+ *(pRawdata+4) = pMOVE->iMovetype;
+
+ mng_put_int32 (pRawdata+5, pMOVE->iMovex);
+ mng_put_int32 (pRawdata+9, pMOVE->iMovey);
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pMOVE->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_MOVE, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_clip)
+{
+ mng_clipp pCLIP;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_CLIP, MNG_LC_START)
+#endif
+
+ pCLIP = (mng_clipp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 21;
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pCLIP->iFirstid);
+ mng_put_uint16 (pRawdata+2, pCLIP->iLastid);
+
+ *(pRawdata+4) = pCLIP->iCliptype;
+
+ mng_put_int32 (pRawdata+5, pCLIP->iClipl);
+ mng_put_int32 (pRawdata+9, pCLIP->iClipr);
+ mng_put_int32 (pRawdata+13, pCLIP->iClipt);
+ mng_put_int32 (pRawdata+17, pCLIP->iClipb);
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pCLIP->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_CLIP, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_show)
+{
+ mng_showp pSHOW;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SHOW, MNG_LC_START)
+#endif
+
+ pSHOW = (mng_showp)pChunk; /* address the proper chunk */
+
+ if (pSHOW->bEmpty) /* empty ? */
+ iRetcode = write_raw_chunk (pData, pSHOW->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 2;
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pSHOW->iFirstid);
+
+ if ((pSHOW->iLastid != pSHOW->iFirstid) || (pSHOW->iMode))
+ {
+ iRawlen += 2;
+ mng_put_uint16 (pRawdata+2, pSHOW->iLastid);
+
+ if (pSHOW->iMode)
+ {
+ iRawlen++;
+ *(pRawdata+4) = pSHOW->iMode;
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pSHOW->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SHOW, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_term)
+{
+ mng_termp pTERM;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_TERM, MNG_LC_START)
+#endif
+
+ pTERM = (mng_termp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 1;
+
+ *pRawdata = pTERM->iTermaction; /* fill the output buffer */
+
+ if (pTERM->iTermaction == 3)
+ {
+ iRawlen = 10;
+ *(pRawdata+1) = pTERM->iIteraction;
+
+ mng_put_uint32 (pRawdata+2, pTERM->iDelay);
+ mng_put_uint32 (pRawdata+6, pTERM->iItermax);
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pTERM->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_TERM, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_save)
+{
+ mng_savep pSAVE;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_save_entryp pEntry;
+ mng_uint32 iEntrysize;
+ mng_uint8p pTemp;
+ mng_uint32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SAVE, MNG_LC_START)
+#endif
+
+ pSAVE = (mng_savep)pChunk; /* address the proper chunk */
+
+ if (pSAVE->bEmpty) /* empty ? */
+ iRetcode = write_raw_chunk (pData, pSAVE->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 1;
+
+ *pRawdata = pSAVE->iOffsettype; /* fill the output buffer */
+
+ if (pSAVE->iOffsettype == 16)
+ iEntrysize = 25;
+ else
+ iEntrysize = 17;
+
+ pTemp = pRawdata+1;
+ pEntry = pSAVE->pEntries;
+
+ for (iX = 0; iX < pSAVE->iCount; iX++)
+ {
+ if (iX) /* put separator null-byte, except the first */
+ {
+ *pTemp = 0;
+ pTemp++;
+ iRawlen++;
+ }
+
+ iRawlen += iEntrysize + pEntry->iNamesize;
+ *pTemp = pEntry->iEntrytype;
+
+ if (pSAVE->iOffsettype == 16)
+ {
+ mng_put_uint32 (pTemp+1, pEntry->iOffset[0]);
+ mng_put_uint32 (pTemp+5, pEntry->iOffset[1]);
+ mng_put_uint32 (pTemp+9, pEntry->iStarttime[0]);
+ mng_put_uint32 (pTemp+13, pEntry->iStarttime[1]);
+ mng_put_uint32 (pTemp+17, pEntry->iLayernr);
+ mng_put_uint32 (pTemp+21, pEntry->iFramenr);
+
+ pTemp += 25;
+ }
+ else
+ {
+ mng_put_uint32 (pTemp+1, pEntry->iOffset[1]);
+ mng_put_uint32 (pTemp+5, pEntry->iStarttime[1]);
+ mng_put_uint32 (pTemp+9, pEntry->iLayernr);
+ mng_put_uint32 (pTemp+13, pEntry->iFramenr);
+
+ pTemp += 17;
+ }
+
+ if (pEntry->iNamesize)
+ {
+ MNG_COPY (pTemp, pEntry->zName, pEntry->iNamesize);
+ pTemp += pEntry->iNamesize;
+ }
+
+ pEntry++;
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pSAVE->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SAVE, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_seek)
+{
+ mng_seekp pSEEK;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SEEK, MNG_LC_START)
+#endif
+
+ pSEEK = (mng_seekp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pSEEK->iNamesize;
+
+ if (iRawlen) /* fill the output buffer */
+ MNG_COPY (pRawdata, pSEEK->zName, iRawlen)
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pSEEK->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_SEEK, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_expi)
+{
+ mng_expip pEXPI;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_EXPI, MNG_LC_START)
+#endif
+
+ pEXPI = (mng_expip)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 2 + pEXPI->iNamesize;
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pEXPI->iSnapshotid);
+
+ if (pEXPI->iNamesize)
+ MNG_COPY (pRawdata+2, pEXPI->zName, pEXPI->iNamesize)
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pEXPI->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_EXPI, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_fpri)
+{
+ mng_fprip pFPRI;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_FPRI, MNG_LC_START)
+#endif
+
+ pFPRI = (mng_fprip)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 2;
+
+ *pRawdata = pFPRI->iDeltatype; /* fill the output buffer */
+ *(pRawdata+1) = pFPRI->iPriority;
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pFPRI->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_FPRI, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_need)
+{
+ mng_needp pNEED;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_NEED, MNG_LC_START)
+#endif
+
+ pNEED = (mng_needp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pNEED->iKeywordssize;
+ /* fill the output buffer */
+ if (pNEED->iKeywordssize)
+ MNG_COPY (pRawdata, pNEED->zKeywords, pNEED->iKeywordssize)
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pNEED->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_NEED, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_phyg)
+{
+ mng_phygp pPHYG;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PHYG, MNG_LC_START)
+#endif
+
+ pPHYG = (mng_phygp)pChunk; /* address the proper chunk */
+
+ if (pPHYG->bEmpty) /* write empty ? */
+ iRetcode = write_raw_chunk (pData, pPHYG->sHeader.iChunkname, 0, 0);
+ else
+ {
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 9;
+ /* fill the output buffer */
+ mng_put_uint32 (pRawdata, pPHYG->iSizex);
+ mng_put_uint32 (pRawdata+4, pPHYG->iSizey);
+
+ *(pRawdata+8) = pPHYG->iUnit;
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pPHYG->sHeader.iChunkname,
+ iRawlen, pRawdata);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PHYG, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+/* B004 */
+#ifdef MNG_INCLUDE_JNG
+/* B004 */
+WRITE_CHUNK (write_jhdr)
+{
+ mng_jhdrp pJHDR;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_JHDR, MNG_LC_START)
+#endif
+
+ pJHDR = (mng_jhdrp)pChunk; /* address the proper chunk */
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 16;
+ /* fill the output buffer */
+ mng_put_uint32 (pRawdata, pJHDR->iWidth);
+ mng_put_uint32 (pRawdata+4, pJHDR->iHeight);
+
+ *(pRawdata+8) = pJHDR->iColortype;
+ *(pRawdata+9) = pJHDR->iImagesampledepth;
+ *(pRawdata+10) = pJHDR->iImagecompression;
+ *(pRawdata+11) = pJHDR->iImageinterlace;
+ *(pRawdata+12) = pJHDR->iAlphasampledepth;
+ *(pRawdata+13) = pJHDR->iAlphacompression;
+ *(pRawdata+14) = pJHDR->iAlphafilter;
+ *(pRawdata+15) = pJHDR->iAlphainterlace;
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pJHDR->sHeader.iChunkname, iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_JHDR, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+#else
+#define write_jhdr 0
+/* B004 */
+#endif /* MNG_INCLUDE_JNG */
+/* B004 */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+WRITE_CHUNK (write_jdaa)
+{
+ mng_jdatp pJDAA;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_JDAA, MNG_LC_START)
+#endif
+
+ pJDAA = (mng_jdaap)pChunk; /* address the proper chunk */
+
+ if (pJDAA->bEmpty) /* and write it */
+ iRetcode = write_raw_chunk (pData, pJDAA->sHeader.iChunkname, 0, 0);
+ else
+ iRetcode = write_raw_chunk (pData, pJDAA->sHeader.iChunkname,
+ pJDAA->iDatasize, pJDAA->pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_JDAA, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+#else
+#define write_jdaa 0
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+/* B004 */
+#ifdef MNG_INCLUDE_JNG
+/* B004 */
+WRITE_CHUNK (write_jdat)
+{
+ mng_jdatp pJDAT;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_JDAT, MNG_LC_START)
+#endif
+
+ pJDAT = (mng_jdatp)pChunk; /* address the proper chunk */
+
+ if (pJDAT->bEmpty) /* and write it */
+ iRetcode = write_raw_chunk (pData, pJDAT->sHeader.iChunkname, 0, 0);
+ else
+ iRetcode = write_raw_chunk (pData, pJDAT->sHeader.iChunkname,
+ pJDAT->iDatasize, pJDAT->pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_JDAT, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+#else
+#define write_jdat 0
+/* B004 */
+#endif /* MNG_INCLUDE_JNG */
+/* B004 */
+
+/* ************************************************************************** */
+
+/* B004 */
+#ifdef MNG_INCLUDE_JNG
+/* B004 */
+WRITE_CHUNK (write_jsep)
+{
+ mng_jsepp pJSEP;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_JSEP, MNG_LC_START)
+#endif
+
+ pJSEP = (mng_jsepp)pChunk; /* address the proper chunk */
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pJSEP->sHeader.iChunkname, 0, 0);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_JSEP, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+#else
+#define write_jsep 0
+/* B004 */
+#endif /* MNG_INCLUDE_JNG */
+/* B004 */
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_dhdr)
+{
+ mng_dhdrp pDHDR;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_DHDR, MNG_LC_START)
+#endif
+
+ pDHDR = (mng_dhdrp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 4;
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pDHDR->iObjectid);
+
+ *(pRawdata+2) = pDHDR->iImagetype;
+ *(pRawdata+3) = pDHDR->iDeltatype;
+
+ if (pDHDR->iDeltatype != 7)
+ {
+ iRawlen += 8;
+ mng_put_uint32 (pRawdata+4, pDHDR->iBlockwidth);
+ mng_put_uint32 (pRawdata+8, pDHDR->iBlockheight);
+
+ if (pDHDR->iDeltatype != 0)
+ {
+ iRawlen += 8;
+ mng_put_uint32 (pRawdata+12, pDHDR->iBlockx);
+ mng_put_uint32 (pRawdata+16, pDHDR->iBlocky);
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pDHDR->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_DHDR, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_prom)
+{
+ mng_promp pPROM;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PROM, MNG_LC_START)
+#endif
+
+ pPROM = (mng_promp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 3;
+
+ *pRawdata = pPROM->iColortype; /* fill the output buffer */
+ *(pRawdata+1) = pPROM->iSampledepth;
+ *(pRawdata+2) = pPROM->iFilltype;
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pPROM->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PROM, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_ipng)
+{
+ mng_ipngp pIPNG;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_IPNG, MNG_LC_START)
+#endif
+
+ pIPNG = (mng_ipngp)pChunk; /* address the proper chunk */
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pIPNG->sHeader.iChunkname, 0, 0);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_IPNG, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_pplt)
+{
+ mng_ppltp pPPLT;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_pplt_entryp pEntry;
+ mng_uint8p pTemp;
+ mng_uint32 iX;
+ mng_bool bHasgroup;
+ mng_uint8p pLastid = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PPLT, MNG_LC_START)
+#endif
+
+ pPPLT = (mng_ppltp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 1;
+
+ *pRawdata = pPPLT->iDeltatype; /* fill the output buffer */
+
+ pTemp = pRawdata+1;
+ bHasgroup = MNG_FALSE;
+
+ for (iX = 0; iX < pPPLT->iCount; iX++)
+ {
+ pEntry = &pPPLT->aEntries[iX];
+
+ if (pEntry->bUsed) /* valid entry ? */
+ {
+ if (!bHasgroup) /* start a new group ? */
+ {
+ bHasgroup = MNG_TRUE;
+ pLastid = pTemp+1;
+
+ *pTemp = (mng_uint8)iX;
+ *(pTemp+1) = 0;
+
+ pTemp += 2;
+ }
+
+ switch (pPPLT->iDeltatype) /* add group-entry depending on type */
+ {
+ case 0: ;
+ case 1: {
+ *pTemp = pEntry->iRed;
+ *(pTemp+1) = pEntry->iGreen;
+ *(pTemp+2) = pEntry->iBlue;
+
+ pTemp += 3;
+
+ break;
+ }
+
+ case 2: ;
+ case 3: {
+ *pTemp = pEntry->iAlpha;
+
+ pTemp++;
+
+ break;
+ }
+
+ case 4: ;
+ case 5: {
+ *pTemp = pEntry->iRed;
+ *(pTemp+1) = pEntry->iGreen;
+ *(pTemp+2) = pEntry->iBlue;
+ *(pTemp+3) = pEntry->iAlpha;
+
+ pTemp += 4;
+
+ break;
+ }
+
+ }
+ }
+ else
+ {
+ if (bHasgroup) /* finish off a group ? */
+ *pLastid = (mng_uint8)(iX-1);
+
+ bHasgroup = MNG_FALSE;
+ }
+ }
+
+ if (bHasgroup) /* last group unfinished ? */
+ *pLastid = (mng_uint8)(pPPLT->iCount-1);
+ /* write the output buffer */
+ iRetcode = write_raw_chunk (pData, pPPLT->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_PPLT, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_ijng)
+{
+ mng_ijngp pIJNG;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_IJNG, MNG_LC_START)
+#endif
+
+ pIJNG = (mng_ijngp)pChunk; /* address the proper chunk */
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pIJNG->sHeader.iChunkname, 0, 0);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_IJNG, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_drop)
+{
+ mng_dropp pDROP;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint32 iX;
+ mng_uint8p pTemp1;
+ mng_chunkidp pTemp2;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_DROP, MNG_LC_START)
+#endif
+
+ pDROP = (mng_dropp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pDROP->iCount << 2;
+
+ pTemp1 = pRawdata; /* fill the output buffer */
+ pTemp2 = pDROP->pChunknames;
+
+ for (iX = 0; iX < pDROP->iCount; iX++)
+ {
+ mng_put_uint32 (pTemp1, (mng_uint32)*pTemp2);
+
+ pTemp2++;
+ pTemp1 += 4;
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pDROP->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_DROP, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_dbyk)
+{
+ mng_dbykp pDBYK;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_DBYK, MNG_LC_START)
+#endif
+
+ pDBYK = (mng_dbykp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 5 + pDBYK->iKeywordssize;
+ /* fill the output buffer */
+ mng_put_uint32 (pRawdata, pDBYK->iChunkname);
+ *(pRawdata+4) = pDBYK->iPolarity;
+
+ if (pDBYK->iKeywordssize)
+ MNG_COPY (pRawdata+5, pDBYK->zKeywords, pDBYK->iKeywordssize)
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pDBYK->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_DBYK, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_ordr)
+{
+ mng_ordrp pORDR;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+ mng_uint8p pTemp;
+ mng_ordr_entryp pEntry;
+ mng_uint32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_ORDR, MNG_LC_START)
+#endif
+
+ pORDR = (mng_ordrp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = pORDR->iCount * 5;
+
+ pTemp = pRawdata; /* fill the output buffer */
+ pEntry = pORDR->pEntries;
+
+ for (iX = 0; iX < pORDR->iCount; iX++)
+ {
+ mng_put_uint32 (pTemp, pEntry->iChunkname);
+ *(pTemp+4) = pEntry->iOrdertype;
+ pTemp += 5;
+ pEntry++;
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pORDR->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_ORDR, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_magn)
+{
+ mng_magnp pMAGN;
+ mng_uint8p pRawdata;
+ mng_uint32 iRawlen;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_MAGN, MNG_LC_START)
+#endif
+
+ pMAGN = (mng_magnp)pChunk; /* address the proper chunk */
+
+ pRawdata = pData->pWritebuf+8; /* init output buffer & size */
+ iRawlen = 20;
+ /* fill the output buffer */
+ mng_put_uint16 (pRawdata, pMAGN->iFirstid);
+ mng_put_uint16 (pRawdata+2, pMAGN->iLastid);
+ mng_put_uint16 (pRawdata+4, pMAGN->iMethodX);
+ mng_put_uint16 (pRawdata+6, pMAGN->iMX);
+ mng_put_uint16 (pRawdata+8, pMAGN->iMY);
+ mng_put_uint16 (pRawdata+10, pMAGN->iML);
+ mng_put_uint16 (pRawdata+12, pMAGN->iMR);
+ mng_put_uint16 (pRawdata+14, pMAGN->iMT);
+ mng_put_uint16 (pRawdata+16, pMAGN->iMB);
+ mng_put_uint16 (pRawdata+18, pMAGN->iMethodY);
+ /* optimize length */
+ if (pMAGN->iMethodY == pMAGN->iMethodX)
+ {
+ iRawlen -= 2;
+
+ if (pMAGN->iMB == pMAGN->iMY)
+ {
+ iRawlen -= 2;
+
+ if (pMAGN->iMT == pMAGN->iMY)
+ {
+ iRawlen -= 2;
+
+ if (pMAGN->iMR == pMAGN->iMX)
+ {
+ iRawlen -= 2;
+
+ if (pMAGN->iML == pMAGN->iMX)
+ {
+ iRawlen -= 2;
+
+ if (pMAGN->iMY == pMAGN->iMX)
+ {
+ iRawlen -= 2;
+
+ if (pMAGN->iMX == 1)
+ {
+ iRawlen -= 2;
+
+ if (pMAGN->iMethodX == 0)
+ {
+ iRawlen -= 2;
+
+ if (pMAGN->iLastid == pMAGN->iFirstid)
+ {
+ iRawlen -= 2;
+
+ if (pMAGN->iFirstid == 0)
+ iRawlen = 0;
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pMAGN->sHeader.iChunkname,
+ iRawlen, pRawdata);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_MAGN, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+WRITE_CHUNK (write_unknown)
+{
+ mng_unknown_chunkp pUnknown;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_UNKNOWN, MNG_LC_START)
+#endif
+ /* address the proper chunk */
+ pUnknown = (mng_unknown_chunkp)pChunk;
+ /* and write it */
+ iRetcode = write_raw_chunk (pData, pUnknown->sHeader.iChunkname,
+ pUnknown->iDatasize, pUnknown->pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_UNKNOWN, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_WRITE_PROCS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
+
+
+
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_io.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_io.h
new file mode 100644
index 0000000..d905601
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_io.h
@@ -0,0 +1,295 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_chunk_io.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Chunk I/O routines (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the chunk input/output routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/04/2000 - G.Juyn * */
+/* * - changed CRC initializtion to use dynamic structure * */
+/* * (wasn't thread-safe the old way !) * */
+/* * 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed write routines definition * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added support for JDAA * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_chunk_io_h_
+#define _libmng_chunk_io_h_
+
+/* ************************************************************************** */
+
+mng_uint32 crc (mng_datap pData,
+ mng_uint8p buf,
+ mng_int32 len);
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_READ_PROCS
+
+#define READ_CHUNK(n) mng_retcode n (mng_datap pData, \
+ mng_chunkp pHeader, \
+ mng_uint32 iRawlen, \
+ mng_uint8p pRawdata, \
+ mng_chunkp* ppChunk)
+
+READ_CHUNK (read_ihdr) ;
+READ_CHUNK (read_plte) ;
+READ_CHUNK (read_idat) ;
+READ_CHUNK (read_iend) ;
+READ_CHUNK (read_trns) ;
+READ_CHUNK (read_gama) ;
+READ_CHUNK (read_chrm) ;
+READ_CHUNK (read_srgb) ;
+READ_CHUNK (read_iccp) ;
+READ_CHUNK (read_text) ;
+READ_CHUNK (read_ztxt) ;
+READ_CHUNK (read_itxt) ;
+READ_CHUNK (read_bkgd) ;
+READ_CHUNK (read_phys) ;
+READ_CHUNK (read_sbit) ;
+READ_CHUNK (read_splt) ;
+READ_CHUNK (read_hist) ;
+READ_CHUNK (read_time) ;
+READ_CHUNK (read_mhdr) ;
+READ_CHUNK (read_mend) ;
+READ_CHUNK (read_loop) ;
+READ_CHUNK (read_endl) ;
+READ_CHUNK (read_defi) ;
+READ_CHUNK (read_basi) ;
+READ_CHUNK (read_clon) ;
+READ_CHUNK (read_past) ;
+READ_CHUNK (read_disc) ;
+READ_CHUNK (read_back) ;
+READ_CHUNK (read_fram) ;
+READ_CHUNK (read_move) ;
+READ_CHUNK (read_clip) ;
+READ_CHUNK (read_show) ;
+READ_CHUNK (read_term) ;
+READ_CHUNK (read_save) ;
+READ_CHUNK (read_seek) ;
+READ_CHUNK (read_expi) ;
+READ_CHUNK (read_fpri) ;
+READ_CHUNK (read_phyg) ;
+READ_CHUNK (read_jhdr) ;
+READ_CHUNK (read_jdaa) ;
+READ_CHUNK (read_jdat) ;
+READ_CHUNK (read_jsep) ;
+READ_CHUNK (read_dhdr) ;
+READ_CHUNK (read_prom) ;
+READ_CHUNK (read_ipng) ;
+READ_CHUNK (read_pplt) ;
+READ_CHUNK (read_ijng) ;
+READ_CHUNK (read_drop) ;
+READ_CHUNK (read_dbyk) ;
+READ_CHUNK (read_ordr) ;
+READ_CHUNK (read_magn) ;
+READ_CHUNK (read_need) ;
+READ_CHUNK (read_unknown) ;
+
+/* ************************************************************************** */
+
+#else /* MNG_INCLUDE_READ_PROCS */
+#define read_ihdr 0
+#define read_plte 0
+#define read_idat 0
+#define read_iend 0
+#define read_trns 0
+#define read_gama 0
+#define read_chrm 0
+#define read_srgb 0
+#define read_iccp 0
+#define read_text 0
+#define read_ztxt 0
+#define read_itxt 0
+#define read_bkgd 0
+#define read_phys 0
+#define read_sbit 0
+#define read_splt 0
+#define read_hist 0
+#define read_time 0
+#define read_mhdr 0
+#define read_mend 0
+#define read_loop 0
+#define read_endl 0
+#define read_defi 0
+#define read_basi 0
+#define read_clon 0
+#define read_past 0
+#define read_disc 0
+#define read_back 0
+#define read_fram 0
+#define read_move 0
+#define read_clip 0
+#define read_show 0
+#define read_term 0
+#define read_save 0
+#define read_seek 0
+#define read_expi 0
+#define read_fpri 0
+#define read_phyg 0
+#define read_jhdr 0
+#define read_jdaa 0
+#define read_jdat 0
+#define read_jsep 0
+#define read_dhdr 0
+#define read_prom 0
+#define read_ipng 0
+#define read_pplt 0
+#define read_ijng 0
+#define read_drop 0
+#define read_dbyk 0
+#define read_ordr 0
+#define read_magn 0
+#define read_need 0
+#define read_unknown 0
+#endif /* MNG_INCLUDE_READ_PROCS */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_WRITE_PROCS
+
+#define WRITE_CHUNK(n) mng_retcode n (mng_datap pData, \
+ mng_chunkp pChunk)
+
+WRITE_CHUNK (write_ihdr) ;
+WRITE_CHUNK (write_plte) ;
+WRITE_CHUNK (write_idat) ;
+WRITE_CHUNK (write_iend) ;
+WRITE_CHUNK (write_trns) ;
+WRITE_CHUNK (write_gama) ;
+WRITE_CHUNK (write_chrm) ;
+WRITE_CHUNK (write_srgb) ;
+WRITE_CHUNK (write_iccp) ;
+WRITE_CHUNK (write_text) ;
+WRITE_CHUNK (write_ztxt) ;
+WRITE_CHUNK (write_itxt) ;
+WRITE_CHUNK (write_bkgd) ;
+WRITE_CHUNK (write_phys) ;
+WRITE_CHUNK (write_sbit) ;
+WRITE_CHUNK (write_splt) ;
+WRITE_CHUNK (write_hist) ;
+WRITE_CHUNK (write_time) ;
+WRITE_CHUNK (write_mhdr) ;
+WRITE_CHUNK (write_mend) ;
+WRITE_CHUNK (write_loop) ;
+WRITE_CHUNK (write_endl) ;
+WRITE_CHUNK (write_defi) ;
+WRITE_CHUNK (write_basi) ;
+WRITE_CHUNK (write_clon) ;
+WRITE_CHUNK (write_past) ;
+WRITE_CHUNK (write_disc) ;
+WRITE_CHUNK (write_back) ;
+WRITE_CHUNK (write_fram) ;
+WRITE_CHUNK (write_move) ;
+WRITE_CHUNK (write_clip) ;
+WRITE_CHUNK (write_show) ;
+WRITE_CHUNK (write_term) ;
+WRITE_CHUNK (write_save) ;
+WRITE_CHUNK (write_seek) ;
+WRITE_CHUNK (write_expi) ;
+WRITE_CHUNK (write_fpri) ;
+WRITE_CHUNK (write_phyg) ;
+WRITE_CHUNK (write_jhdr) ;
+WRITE_CHUNK (write_jdaa) ;
+WRITE_CHUNK (write_jdat) ;
+WRITE_CHUNK (write_jsep) ;
+WRITE_CHUNK (write_dhdr) ;
+WRITE_CHUNK (write_prom) ;
+WRITE_CHUNK (write_ipng) ;
+WRITE_CHUNK (write_pplt) ;
+WRITE_CHUNK (write_ijng) ;
+WRITE_CHUNK (write_drop) ;
+WRITE_CHUNK (write_dbyk) ;
+WRITE_CHUNK (write_ordr) ;
+WRITE_CHUNK (write_magn) ;
+WRITE_CHUNK (write_need) ;
+WRITE_CHUNK (write_unknown) ;
+
+/* ************************************************************************** */
+
+#else /* MNG_INCLUDE_WRITE_PROCS */
+#define write_ihdr 0
+#define write_plte 0
+#define write_idat 0
+#define write_iend 0
+#define write_trns 0
+#define write_gama 0
+#define write_chrm 0
+#define write_srgb 0
+#define write_iccp 0
+#define write_text 0
+#define write_ztxt 0
+#define write_itxt 0
+#define write_bkgd 0
+#define write_phys 0
+#define write_sbit 0
+#define write_splt 0
+#define write_hist 0
+#define write_time 0
+#define write_mhdr 0
+#define write_mend 0
+#define write_loop 0
+#define write_endl 0
+#define write_defi 0
+#define write_basi 0
+#define write_clon 0
+#define write_past 0
+#define write_disc 0
+#define write_back 0
+#define write_fram 0
+#define write_move 0
+#define write_clip 0
+#define write_show 0
+#define write_term 0
+#define write_save 0
+#define write_seek 0
+#define write_expi 0
+#define write_fpri 0
+#define write_phyg 0
+#define write_jhdr 0
+#define write_jdaa 0
+#define write_jdat 0
+#define write_jsep 0
+#define write_dhdr 0
+#define write_prom 0
+#define write_ipng 0
+#define write_pplt 0
+#define write_ijng 0
+#define write_drop 0
+#define write_dbyk 0
+#define write_ordr 0
+#define write_magn 0
+#define write_need 0
+#define write_unknown 0
+#endif /* MNG_INCLUDE_WRITE_PROCS */
+
+/* ************************************************************************** */
+
+#endif /* _libmng_chunk_io_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_prc.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_prc.c
new file mode 100644
index 0000000..f3c27f4
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_prc.c
@@ -0,0 +1,2102 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_chunk_prc.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Chunk initialization & cleanup (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the chunk initialization & cleanup * */
+/* * routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * * */
+/* * 0.9.1 - 07/19/2000 - G.Juyn * */
+/* * - fixed creation-code * */
+/* * * */
+/* * 0.9.2 - 07/31/2000 - G.Juyn * */
+/* * - put add_chunk() inside MNG_INCLUDE_WRITE_PROCS wrapper * */
+/* * 0.9.2 - 08/01/2000 - G.Juyn * */
+/* * - wrapper for add_chunk() changed * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added support for JDAA * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_memory.h"
+#include "libmng_chunks.h"
+#include "libmng_chunk_prc.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * General chunk routines * */
+/* * * */
+/* ************************************************************************** */
+
+void add_chunk (mng_datap pData,
+ mng_chunkp pChunk)
+{
+ if (!pData->pFirstchunk) /* list is still empty ? */
+ {
+ pData->pFirstchunk = pChunk; /* then this becomes the first */
+
+#ifdef MNG_SUPPORT_WRITE
+ pData->iFirstchunkadded = ((mng_chunk_headerp)pChunk)->iChunkname;
+#endif
+
+ if (((mng_chunk_headerp)pChunk)->iChunkname == MNG_UINT_IHDR)
+ pData->eImagetype = mng_it_png;
+ else
+#ifdef MNG_INCLUDE_JNG
+ if (((mng_chunk_headerp)pChunk)->iChunkname == MNG_UINT_JHDR)
+ pData->eImagetype = mng_it_jng;
+ else
+#endif
+ pData->eImagetype = mng_it_mng;
+
+ pData->eSigtype = pData->eImagetype;
+ }
+ else
+ { /* else we make appropriate links */
+ ((mng_chunk_headerp)pChunk)->pPrev = pData->pLastchunk;
+ ((mng_chunk_headerp)pData->pLastchunk)->pNext = pChunk;
+ }
+
+ pData->pLastchunk = pChunk; /* and it's always the last */
+
+ return;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Chunk specific initialization routines * */
+/* * * */
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_ihdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IHDR, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_ihdr))
+ ((mng_ihdrp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_plte)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PLTE, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_plte))
+ ((mng_pltep)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PLTE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_idat)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDAT, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_idat))
+ ((mng_idatp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_iend)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IEND, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_iend))
+ ((mng_iendp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_trns)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_TRNS, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_trns))
+ ((mng_trnsp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_TRNS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_gama)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GAMA, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_gama))
+ ((mng_gamap)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GAMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_chrm)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_CHRM, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_chrm))
+ ((mng_chrmp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_CHRM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_srgb)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SRGB, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_srgb))
+ ((mng_srgbp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_iccp)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ICCP, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_iccp))
+ ((mng_iccpp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ICCP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_text)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_TEXT, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_text))
+ ((mng_textp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_TEXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_ztxt)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ZTXT, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_ztxt))
+ ((mng_ztxtp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ZTXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_itxt)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ITXT, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_itxt))
+ ((mng_itxtp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ITXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_bkgd)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_BKGD, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_bkgd))
+ ((mng_bkgdp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_BKGD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_phys)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PHYS, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_phys))
+ ((mng_physp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PHYS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_sbit)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SBIT, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_sbit))
+ ((mng_sbitp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SBIT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_splt)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SPLT, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_splt))
+ ((mng_spltp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_hist)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_HIST, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_hist))
+ ((mng_histp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_HIST, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_time)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_TIME, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_time))
+ ((mng_timep)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_TIME, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_mhdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_MHDR, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_mhdr))
+ ((mng_mhdrp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_MHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_mend)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_MEND, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_mend))
+ ((mng_mendp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_MEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_loop)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_LOOP, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_loop))
+ ((mng_loopp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_LOOP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_endl)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ENDL, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_endl))
+ ((mng_endlp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ENDL, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_defi)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_DEFI, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_defi))
+ ((mng_defip)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_DEFI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_basi)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_BASI, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_basi))
+ ((mng_basip)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_BASI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_clon)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_CLON, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_clon))
+ ((mng_clonp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_CLON, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_past)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PAST, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_past))
+ ((mng_pastp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PAST, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_disc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_DISC, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_disc))
+ ((mng_discp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_DISC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_back)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_BACK, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_back))
+ ((mng_backp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_BACK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_fram)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FRAM, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_fram))
+ ((mng_framp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FRAM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_move)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_MOVE, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_move))
+ ((mng_movep)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_MOVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_clip)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_CLIP, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_clip))
+ ((mng_clipp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_CLIP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_show)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SHOW, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_show))
+ ((mng_showp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SHOW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_term)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_TERM, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_term))
+ ((mng_termp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_TERM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_save)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SAVE, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_save))
+ ((mng_savep)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SAVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_seek)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SEEK, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_seek))
+ ((mng_seekp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_SEEK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_expi)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_EXPI, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_expi))
+ ((mng_expip)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_EXPI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_fpri)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FPRI, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_fpri))
+ ((mng_fprip)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FPRI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_need)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_NEED, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_need))
+ ((mng_needp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_NEED, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_phyg)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PHYG, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_phyg))
+ ((mng_phygp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PHYG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+INIT_CHUNK_HDR (init_jhdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JHDR, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_jhdr))
+ ((mng_jhdrp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+INIT_CHUNK_HDR (init_jdaa)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JDAA, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_jdaa))
+ ((mng_jdaap)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JDAA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+INIT_CHUNK_HDR (init_jdat)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JDAT, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_jdat))
+ ((mng_jdatp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+INIT_CHUNK_HDR (init_jsep)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JSEP, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_jsep))
+ ((mng_jsepp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JSEP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_dhdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_DHDR, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_dhdr))
+ ((mng_dhdrp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_DHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_prom)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PROM, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_prom))
+ ((mng_promp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PROM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_ipng)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IPNG, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_ipng))
+ ((mng_ipngp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IPNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_pplt)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PPLT, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_pplt))
+ ((mng_ppltp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_PPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_ijng)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IJNG, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_ijng))
+ ((mng_ijngp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IJNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_drop)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_DROP, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_drop))
+ ((mng_dropp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_DROP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_dbyk)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_DBYK, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_dbyk))
+ ((mng_dbykp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_DBYK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_ordr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ORDR, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_ordr))
+ ((mng_ordrp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ORDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_magn)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_MAGN, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_magn))
+ ((mng_magnp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_MAGN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+INIT_CHUNK_HDR (init_unknown)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_UNKNOWN, MNG_LC_START)
+#endif
+
+ MNG_ALLOC (pData, *ppChunk, sizeof (mng_unknown_chunk))
+ ((mng_unknown_chunkp)*ppChunk)->sHeader = *((mng_chunk_headerp)pHeader);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_UNKNOWN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Chunk specific cleanup routines * */
+/* * * */
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_ihdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IHDR, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_ihdr))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_plte)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PLTE, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_plte))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PLTE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_idat)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IDAT, MNG_LC_START)
+#endif
+
+ if (((mng_idatp)pHeader)->iDatasize)
+ MNG_FREEX (pData, ((mng_idatp)pHeader)->pData,
+ ((mng_idatp)pHeader)->iDatasize)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_idat))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_iend)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IEND, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_iend))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_trns)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_TRNS, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_trns))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_TRNS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_gama)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_GAMA, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_gama))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_GAMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_chrm)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_CHRM, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_chrm))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_CHRM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_srgb)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SRGB, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_srgb))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_iccp)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ICCP, MNG_LC_START)
+#endif
+
+ if (((mng_iccpp)pHeader)->iNamesize)
+ MNG_FREEX (pData, ((mng_iccpp)pHeader)->zName,
+ ((mng_iccpp)pHeader)->iNamesize + 1)
+
+ if (((mng_iccpp)pHeader)->iProfilesize)
+ MNG_FREEX (pData, ((mng_iccpp)pHeader)->pProfile,
+ ((mng_iccpp)pHeader)->iProfilesize)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_iccp))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ICCP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_text)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_TEXT, MNG_LC_START)
+#endif
+
+ if (((mng_textp)pHeader)->iKeywordsize)
+ MNG_FREEX (pData, ((mng_textp)pHeader)->zKeyword,
+ ((mng_textp)pHeader)->iKeywordsize + 1)
+
+ if (((mng_textp)pHeader)->iTextsize)
+ MNG_FREEX (pData, ((mng_textp)pHeader)->zText,
+ ((mng_textp)pHeader)->iTextsize + 1)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_text))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_TEXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_ztxt)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ZTXT, MNG_LC_START)
+#endif
+
+ if (((mng_ztxtp)pHeader)->iKeywordsize)
+ MNG_FREEX (pData, ((mng_ztxtp)pHeader)->zKeyword,
+ ((mng_ztxtp)pHeader)->iKeywordsize + 1)
+
+ if (((mng_ztxtp)pHeader)->iTextsize)
+ MNG_FREEX (pData, ((mng_ztxtp)pHeader)->zText,
+ ((mng_ztxtp)pHeader)->iTextsize)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_ztxt))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ZTXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_itxt)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ITXT, MNG_LC_START)
+#endif
+
+ if (((mng_itxtp)pHeader)->iKeywordsize)
+ MNG_FREEX (pData, ((mng_itxtp)pHeader)->zKeyword,
+ ((mng_itxtp)pHeader)->iKeywordsize + 1)
+
+ if (((mng_itxtp)pHeader)->iLanguagesize)
+ MNG_FREEX (pData, ((mng_itxtp)pHeader)->zLanguage,
+ ((mng_itxtp)pHeader)->iLanguagesize + 1)
+
+ if (((mng_itxtp)pHeader)->iTranslationsize)
+ MNG_FREEX (pData, ((mng_itxtp)pHeader)->zTranslation,
+ ((mng_itxtp)pHeader)->iTranslationsize + 1)
+
+ if (((mng_itxtp)pHeader)->iTextsize)
+ MNG_FREEX (pData, ((mng_itxtp)pHeader)->zText,
+ ((mng_itxtp)pHeader)->iTextsize)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_itxt))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ITXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_bkgd)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_BKGD, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_bkgd))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_BKGD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_phys)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PHYS, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_phys))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PHYS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_sbit)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SBIT, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_sbit))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SBIT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_splt)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SPLT, MNG_LC_START)
+#endif
+
+ if (((mng_spltp)pHeader)->iNamesize)
+ MNG_FREEX (pData, ((mng_spltp)pHeader)->zName,
+ ((mng_spltp)pHeader)->iNamesize + 1)
+
+ if (((mng_spltp)pHeader)->iEntrycount)
+ MNG_FREEX (pData, ((mng_spltp)pHeader)->pEntries,
+ ((mng_spltp)pHeader)->iEntrycount *
+ (((mng_spltp)pHeader)->iSampledepth * 3 + sizeof (mng_uint16)) )
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_splt))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_hist)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_HIST, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_hist))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_HIST, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_time)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_TIME, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_time))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_TIME, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_mhdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_MHDR, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_mhdr))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_MHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_mend)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_MEND, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_mend))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_MEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_loop)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_LOOP, MNG_LC_START)
+#endif
+
+ if (((mng_loopp)pHeader)->iCount)
+ MNG_FREEX (pData, ((mng_loopp)pHeader)->pSignals,
+ ((mng_loopp)pHeader)->iCount * sizeof (mng_uint32) )
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_loop))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_LOOP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_endl)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ENDL, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_endl))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ENDL, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_defi)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_DEFI, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_defi))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_DEFI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_basi)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_BASI, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_basi))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_BASI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_clon)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_CLON, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_clon))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_CLON, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_past)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PAST, MNG_LC_START)
+#endif
+
+ if (((mng_pastp)pHeader)->iCount)
+ MNG_FREEX (pData, ((mng_pastp)pHeader)->pSources,
+ ((mng_pastp)pHeader)->iCount * sizeof (mng_past_source) )
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_past))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PAST, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_disc)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_DISC, MNG_LC_START)
+#endif
+
+ if (((mng_discp)pHeader)->iCount)
+ MNG_FREEX (pData, ((mng_discp)pHeader)->pObjectids,
+ ((mng_discp)pHeader)->iCount * sizeof (mng_uint16) )
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_disc))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_DISC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_back)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_BACK, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_back))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_BACK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_fram)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_FRAM, MNG_LC_START)
+#endif
+
+ if (((mng_framp)pHeader)->iNamesize)
+ MNG_FREEX (pData, ((mng_framp)pHeader)->zName,
+ ((mng_framp)pHeader)->iNamesize + 1)
+
+ if (((mng_framp)pHeader)->iCount)
+ MNG_FREEX (pData, ((mng_framp)pHeader)->pSyncids,
+ ((mng_framp)pHeader)->iCount * sizeof (mng_uint32) )
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_fram))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_FRAM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_move)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_MOVE, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_move))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_MOVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_clip)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_CLIP, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_clip))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_CLIP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_show)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SHOW, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_show))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SHOW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_term)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_TERM, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_term))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_TERM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_save)
+{
+ mng_save_entryp pEntry = ((mng_savep)pHeader)->pEntries;
+ mng_uint32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SAVE, MNG_LC_START)
+#endif
+
+ for (iX = 0; iX < ((mng_savep)pHeader)->iCount; iX++)
+ {
+ if (pEntry->iNamesize)
+ MNG_FREEX (pData, pEntry->zName, pEntry->iNamesize)
+
+ pEntry = pEntry + sizeof (mng_save_entry);
+ }
+
+ if (((mng_savep)pHeader)->iCount)
+ MNG_FREEX (pData, ((mng_savep)pHeader)->pEntries,
+ ((mng_savep)pHeader)->iCount * sizeof (mng_save_entry) )
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_save))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SAVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_seek)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SEEK, MNG_LC_START)
+#endif
+
+ if (((mng_seekp)pHeader)->iNamesize)
+ MNG_FREEX (pData, ((mng_seekp)pHeader)->zName,
+ ((mng_seekp)pHeader)->iNamesize + 1)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_seek))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_SEEK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_expi)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_EXPI, MNG_LC_START)
+#endif
+
+ if (((mng_expip)pHeader)->iNamesize)
+ MNG_FREEX (pData, ((mng_expip)pHeader)->zName,
+ ((mng_expip)pHeader)->iNamesize + 1)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_expi))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_EXPI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_fpri)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_FPRI, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_fpri))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_FPRI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_need)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_NEED, MNG_LC_START)
+#endif
+
+ if (((mng_needp)pHeader)->iKeywordssize)
+ MNG_FREEX (pData, ((mng_needp)pHeader)->zKeywords,
+ ((mng_needp)pHeader)->iKeywordssize + 1)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_need))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_NEED, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_phyg)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PHYG, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_phyg))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PHYG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+FREE_CHUNK_HDR (free_jhdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_JHDR, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_jhdr))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_JHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+FREE_CHUNK_HDR (free_jdaa)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_JDAA, MNG_LC_START)
+#endif
+
+ if (((mng_jdaap)pHeader)->iDatasize)
+ MNG_FREEX (pData, ((mng_jdaap)pHeader)->pData,
+ ((mng_jdaap)pHeader)->iDatasize)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_jdaa))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_JDAA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+FREE_CHUNK_HDR (free_jdat)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_JDAT, MNG_LC_START)
+#endif
+
+ if (((mng_jdatp)pHeader)->iDatasize)
+ MNG_FREEX (pData, ((mng_jdatp)pHeader)->pData,
+ ((mng_jdatp)pHeader)->iDatasize)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_jdat))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_JDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+FREE_CHUNK_HDR (free_jsep)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_JSEP, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_jsep))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_JSEP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_dhdr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_DHDR, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_dhdr))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_DHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_prom)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PROM, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_prom))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PROM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_ipng)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IPNG, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_ipng))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IPNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_pplt)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PPLT, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_pplt))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_PPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_ijng)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IJNG, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_ijng))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IJNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_drop)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_DROP, MNG_LC_START)
+#endif
+
+ if (((mng_dropp)pHeader)->iCount)
+ MNG_FREEX (pData, ((mng_dropp)pHeader)->pChunknames,
+ ((mng_dropp)pHeader)->iCount * sizeof (mng_chunkid) )
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_drop))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_DROP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_dbyk)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_DBYK, MNG_LC_START)
+#endif
+
+ if (((mng_dbykp)pHeader)->iKeywordssize)
+ MNG_FREEX (pData, ((mng_dbykp)pHeader)->zKeywords,
+ ((mng_dbykp)pHeader)->iKeywordssize)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_dbyk))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_DBYK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_ordr)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ORDR, MNG_LC_START)
+#endif
+
+ if (((mng_ordrp)pHeader)->iCount)
+ MNG_FREEX (pData, ((mng_ordrp)pHeader)->pEntries,
+ ((mng_ordrp)pHeader)->iCount * sizeof (mng_ordr_entry) )
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_ordr))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ORDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_magn)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_MAGN, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_magn))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_MAGN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+FREE_CHUNK_HDR (free_unknown)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_UNKNOWN, MNG_LC_START)
+#endif
+
+ if (((mng_unknown_chunkp)pHeader)->iDatasize)
+ MNG_FREEX (pData, ((mng_unknown_chunkp)pHeader)->pData,
+ ((mng_unknown_chunkp)pHeader)->iDatasize)
+
+ MNG_FREEX (pData, pHeader, sizeof (mng_unknown_chunk))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_UNKNOWN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_prc.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_prc.h
new file mode 100644
index 0000000..a1054d4
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_prc.h
@@ -0,0 +1,168 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_chunk_prc.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Chunk initialization & cleanup (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : definition of the chunk initialization & cleanup routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added support for JDAA * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_chunk_prc_h_
+#define _libmng_chunk_prc_h_
+
+/* ************************************************************************** */
+
+void add_chunk (mng_datap pData,
+ mng_chunkp pChunk);
+
+/* ************************************************************************** */
+
+#define INIT_CHUNK_HDR(n) mng_retcode n (mng_datap pData, \
+ mng_chunkp pHeader, \
+ mng_chunkp* ppChunk)
+
+INIT_CHUNK_HDR (init_ihdr) ;
+INIT_CHUNK_HDR (init_plte) ;
+INIT_CHUNK_HDR (init_idat) ;
+INIT_CHUNK_HDR (init_iend) ;
+INIT_CHUNK_HDR (init_trns) ;
+INIT_CHUNK_HDR (init_gama) ;
+INIT_CHUNK_HDR (init_chrm) ;
+INIT_CHUNK_HDR (init_srgb) ;
+INIT_CHUNK_HDR (init_iccp) ;
+INIT_CHUNK_HDR (init_text) ;
+INIT_CHUNK_HDR (init_ztxt) ;
+INIT_CHUNK_HDR (init_itxt) ;
+INIT_CHUNK_HDR (init_bkgd) ;
+INIT_CHUNK_HDR (init_phys) ;
+INIT_CHUNK_HDR (init_sbit) ;
+INIT_CHUNK_HDR (init_splt) ;
+INIT_CHUNK_HDR (init_hist) ;
+INIT_CHUNK_HDR (init_time) ;
+INIT_CHUNK_HDR (init_mhdr) ;
+INIT_CHUNK_HDR (init_mend) ;
+INIT_CHUNK_HDR (init_loop) ;
+INIT_CHUNK_HDR (init_endl) ;
+INIT_CHUNK_HDR (init_defi) ;
+INIT_CHUNK_HDR (init_basi) ;
+INIT_CHUNK_HDR (init_clon) ;
+INIT_CHUNK_HDR (init_past) ;
+INIT_CHUNK_HDR (init_disc) ;
+INIT_CHUNK_HDR (init_back) ;
+INIT_CHUNK_HDR (init_fram) ;
+INIT_CHUNK_HDR (init_move) ;
+INIT_CHUNK_HDR (init_clip) ;
+INIT_CHUNK_HDR (init_show) ;
+INIT_CHUNK_HDR (init_term) ;
+INIT_CHUNK_HDR (init_save) ;
+INIT_CHUNK_HDR (init_seek) ;
+INIT_CHUNK_HDR (init_expi) ;
+INIT_CHUNK_HDR (init_fpri) ;
+INIT_CHUNK_HDR (init_need) ;
+INIT_CHUNK_HDR (init_phyg) ;
+INIT_CHUNK_HDR (init_jhdr) ;
+INIT_CHUNK_HDR (init_jdaa) ;
+INIT_CHUNK_HDR (init_jdat) ;
+INIT_CHUNK_HDR (init_jsep) ;
+INIT_CHUNK_HDR (init_dhdr) ;
+INIT_CHUNK_HDR (init_prom) ;
+INIT_CHUNK_HDR (init_ipng) ;
+INIT_CHUNK_HDR (init_pplt) ;
+INIT_CHUNK_HDR (init_ijng) ;
+INIT_CHUNK_HDR (init_drop) ;
+INIT_CHUNK_HDR (init_dbyk) ;
+INIT_CHUNK_HDR (init_ordr) ;
+INIT_CHUNK_HDR (init_magn) ;
+INIT_CHUNK_HDR (init_unknown) ;
+
+/* ************************************************************************** */
+
+#define FREE_CHUNK_HDR(n) mng_retcode n (mng_datap pData, \
+ mng_chunkp pHeader)
+
+FREE_CHUNK_HDR (free_ihdr) ;
+FREE_CHUNK_HDR (free_plte) ;
+FREE_CHUNK_HDR (free_idat) ;
+FREE_CHUNK_HDR (free_iend) ;
+FREE_CHUNK_HDR (free_trns) ;
+FREE_CHUNK_HDR (free_gama) ;
+FREE_CHUNK_HDR (free_chrm) ;
+FREE_CHUNK_HDR (free_srgb) ;
+FREE_CHUNK_HDR (free_iccp) ;
+FREE_CHUNK_HDR (free_text) ;
+FREE_CHUNK_HDR (free_ztxt) ;
+FREE_CHUNK_HDR (free_itxt) ;
+FREE_CHUNK_HDR (free_bkgd) ;
+FREE_CHUNK_HDR (free_phys) ;
+FREE_CHUNK_HDR (free_sbit) ;
+FREE_CHUNK_HDR (free_splt) ;
+FREE_CHUNK_HDR (free_hist) ;
+FREE_CHUNK_HDR (free_time) ;
+FREE_CHUNK_HDR (free_mhdr) ;
+FREE_CHUNK_HDR (free_mend) ;
+FREE_CHUNK_HDR (free_loop) ;
+FREE_CHUNK_HDR (free_endl) ;
+FREE_CHUNK_HDR (free_defi) ;
+FREE_CHUNK_HDR (free_basi) ;
+FREE_CHUNK_HDR (free_clon) ;
+FREE_CHUNK_HDR (free_past) ;
+FREE_CHUNK_HDR (free_disc) ;
+FREE_CHUNK_HDR (free_back) ;
+FREE_CHUNK_HDR (free_fram) ;
+FREE_CHUNK_HDR (free_move) ;
+FREE_CHUNK_HDR (free_clip) ;
+FREE_CHUNK_HDR (free_show) ;
+FREE_CHUNK_HDR (free_term) ;
+FREE_CHUNK_HDR (free_save) ;
+FREE_CHUNK_HDR (free_seek) ;
+FREE_CHUNK_HDR (free_expi) ;
+FREE_CHUNK_HDR (free_fpri) ;
+FREE_CHUNK_HDR (free_need) ;
+FREE_CHUNK_HDR (free_phyg) ;
+FREE_CHUNK_HDR (free_jhdr) ;
+FREE_CHUNK_HDR (free_jdaa) ;
+FREE_CHUNK_HDR (free_jdat) ;
+FREE_CHUNK_HDR (free_jsep) ;
+FREE_CHUNK_HDR (free_dhdr) ;
+FREE_CHUNK_HDR (free_prom) ;
+FREE_CHUNK_HDR (free_ipng) ;
+FREE_CHUNK_HDR (free_pplt) ;
+FREE_CHUNK_HDR (free_ijng) ;
+FREE_CHUNK_HDR (free_drop) ;
+FREE_CHUNK_HDR (free_dbyk) ;
+FREE_CHUNK_HDR (free_ordr) ;
+FREE_CHUNK_HDR (free_magn) ;
+FREE_CHUNK_HDR (free_unknown) ;
+
+/* ************************************************************************** */
+
+#endif /* _libmng_chunk_prc_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_xs.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_xs.c
new file mode 100644
index 0000000..8ca3f47
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunk_xs.c
@@ -0,0 +1,5119 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_chunk_xs.c copyright (c) 2000 G. Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : chunk access functions (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the chunk access functions * */
+/* * * */
+/* * changes : 0.5.1 - 05/06/2000 - G.Juyn * */
+/* * - changed and filled iterate-chunk function * */
+/* * 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - fixed calling convention * */
+/* * - added getchunk functions * */
+/* * - added putchunk functions * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added empty-chunk put-routines * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * 0.5.1 - 05/15/2000 - G.Juyn * */
+/* * - added getimgdata & putimgdata functions * */
+/* * * */
+/* * 0.5.2 - 05/19/2000 - G.Juyn * */
+/* * - B004 - fixed problem with MNG_SUPPORT_WRITE not defined * */
+/* * also for MNG_SUPPORT_WRITE without MNG_INCLUDE_JNG * */
+/* * - Cleaned up some code regarding mixed support * */
+/* * * */
+/* * 0.9.1 - 07/19/2000 - G.Juyn * */
+/* * - fixed creation-code * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * - added function to set simplicity field * */
+/* * - fixed putchunk_unknown() function * */
+/* * * */
+/* * 0.9.3 - 08/07/2000 - G.Juyn * */
+/* * - B111300 - fixup for improved portability * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 10/20/2000 - G.Juyn * */
+/* * - fixed putchunk_plte() to set bEmpty parameter * */
+/* * * */
+/* * 0.9.5 - 1/25/2001 - G.Juyn * */
+/* * - fixed some small compiler warnings (thanks Nikki) * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_memory.h"
+#include "libmng_chunks.h"
+#include "libmng_chunk_prc.h"
+#include "libmng_chunk_io.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_ACCESS_CHUNKS
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_iterate_chunks (mng_handle hHandle,
+ mng_uint32 iChunkseq,
+ mng_iteratechunk fProc)
+{
+ mng_uint32 iSeq;
+ mng_chunkid iChunkname;
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_bool bCont;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_ITERATE_CHUNKS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+ iSeq = 0;
+ bCont = MNG_TRUE;
+ pChunk = pData->pFirstchunk; /* get the first chunk */
+ /* as long as there are some more */
+ while ((pChunk) && (bCont)) /* and the app didn't signal a stop */
+ {
+ if (iSeq >= iChunkseq) /* reached the first target ? */
+ { /* then call this and next ones back in... */
+ iChunkname = ((mng_chunk_headerp)pChunk)->iChunkname;
+ bCont = fProc (hHandle, (mng_handle)pChunk, iChunkname, iSeq);
+ }
+
+ iSeq++; /* next one */
+ pChunk = ((mng_chunk_headerp)pChunk)->pNext;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_ITERATE_CHUNKS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_ihdr (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iWidth,
+ mng_uint32 *iHeight,
+ mng_uint8 *iBitdepth,
+ mng_uint8 *iColortype,
+ mng_uint8 *iCompression,
+ mng_uint8 *iFilter,
+ mng_uint8 *iInterlace)
+{
+ mng_datap pData;
+ mng_ihdrp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_IHDR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_ihdrp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_IHDR)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iWidth = pChunk->iWidth; /* fill the fields */
+ *iHeight = pChunk->iHeight;
+ *iBitdepth = pChunk->iBitdepth;
+ *iColortype = pChunk->iColortype;
+ *iCompression = pChunk->iCompression;
+ *iFilter = pChunk->iFilter;
+ *iInterlace = pChunk->iInterlace;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_IHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_plte (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iCount,
+ mng_palette8 *aPalette)
+{
+ mng_datap pData;
+ mng_pltep pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PLTE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_pltep)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_PLTE)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iCount = pChunk->iEntrycount; /* fill the fields */
+
+ MNG_COPY (*aPalette, pChunk->aEntries, sizeof (mng_palette8))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PLTE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_idat (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iRawlen,
+ mng_ptr *pRawdata)
+{
+ mng_datap pData;
+ mng_idatp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_IDAT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_idatp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_IDAT)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iRawlen = pChunk->iDatasize; /* fill the fields */
+ *pRawdata = pChunk->pData;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_IDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_trns (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_bool *bGlobal,
+ mng_uint8 *iType,
+ mng_uint32 *iCount,
+ mng_uint8arr *aAlphas,
+ mng_uint16 *iGray,
+ mng_uint16 *iRed,
+ mng_uint16 *iGreen,
+ mng_uint16 *iBlue,
+ mng_uint32 *iRawlen,
+ mng_uint8arr *aRawdata)
+{
+ mng_datap pData;
+ mng_trnsp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TRNS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_trnsp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_tRNS)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *bGlobal = pChunk->bGlobal;
+ *iType = pChunk->iType;
+ *iCount = pChunk->iCount;
+ *iGray = pChunk->iGray;
+ *iRed = pChunk->iRed;
+ *iGreen = pChunk->iGreen;
+ *iBlue = pChunk->iBlue;
+ *iRawlen = pChunk->iRawlen;
+
+ MNG_COPY (*aAlphas, pChunk->aEntries, sizeof (mng_uint8arr))
+ MNG_COPY (*aRawdata, pChunk->aRawdata, sizeof (mng_uint8arr))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TRNS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_gama (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iGamma)
+{
+ mng_datap pData;
+ mng_gamap pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_GAMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_gamap)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_gAMA)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iGamma = pChunk->iGamma;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_GAMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_chrm (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iWhitepointx,
+ mng_uint32 *iWhitepointy,
+ mng_uint32 *iRedx,
+ mng_uint32 *iRedy,
+ mng_uint32 *iGreenx,
+ mng_uint32 *iGreeny,
+ mng_uint32 *iBluex,
+ mng_uint32 *iBluey)
+{
+ mng_datap pData;
+ mng_chrmp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CHRM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_chrmp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_cHRM)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iWhitepointx = pChunk->iWhitepointx;
+ *iWhitepointy = pChunk->iWhitepointy;
+ *iRedx = pChunk->iRedx;
+ *iRedy = pChunk->iRedy;
+ *iGreenx = pChunk->iGreenx;
+ *iGreeny = pChunk->iGreeny;
+ *iBluex = pChunk->iBluex;
+ *iBluey = pChunk->iBluey;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CHRM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_srgb (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iRenderingintent)
+{
+ mng_datap pData;
+ mng_srgbp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SRGB, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_srgbp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_sRGB)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iRenderingintent = pChunk->iRenderingintent;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_iccp (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName,
+ mng_uint8 *iCompression,
+ mng_uint32 *iProfilesize,
+ mng_ptr *pProfile)
+{
+ mng_datap pData;
+ mng_iccpp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ICCP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_iccpp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_iCCP)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iNamesize = pChunk->iNamesize;
+ *zName = pChunk->zName;
+ *iCompression = pChunk->iCompression;
+ *iProfilesize = pChunk->iProfilesize;
+ *pProfile = pChunk->pProfile;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ICCP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_text (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iKeywordsize,
+ mng_pchar *zKeyword,
+ mng_uint32 *iTextsize,
+ mng_pchar *zText)
+{
+ mng_datap pData;
+ mng_textp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TEXT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_textp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_tEXt)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+ /* fill the fields */
+ *iKeywordsize = pChunk->iKeywordsize;
+ *zKeyword = pChunk->zKeyword;
+ *iTextsize = pChunk->iTextsize;
+ *zText = pChunk->zText;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TEXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_ztxt (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iKeywordsize,
+ mng_pchar *zKeyword,
+ mng_uint8 *iCompression,
+ mng_uint32 *iTextsize,
+ mng_pchar *zText)
+{
+ mng_datap pData;
+ mng_ztxtp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ZTXT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_ztxtp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_zTXt)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+ /* fill the fields */
+ *iKeywordsize = pChunk->iKeywordsize;
+ *zKeyword = pChunk->zKeyword;
+ *iCompression = pChunk->iCompression;
+ *iTextsize = pChunk->iTextsize;
+ *zText = pChunk->zText;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ZTXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_itxt (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iKeywordsize,
+ mng_pchar *zKeyword,
+ mng_uint8 *iCompressionflag,
+ mng_uint8 *iCompressionmethod,
+ mng_uint32 *iLanguagesize,
+ mng_pchar *zLanguage,
+ mng_uint32 *iTranslationsize,
+ mng_pchar *zTranslation,
+ mng_uint32 *iTextsize,
+ mng_pchar *zText)
+{
+ mng_datap pData;
+ mng_itxtp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ITXT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_itxtp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_iTXt)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+ /* fill the fields */
+ *iKeywordsize = pChunk->iKeywordsize;
+ *zKeyword = pChunk->zKeyword;
+ *iCompressionflag = pChunk->iCompressionflag;
+ *iCompressionmethod = pChunk->iCompressionmethod;
+ *iLanguagesize = pChunk->iLanguagesize;
+ *zLanguage = pChunk->zLanguage;
+ *iTranslationsize = pChunk->iTranslationsize;
+ *zTranslation = pChunk->zTranslation;
+ *iTextsize = pChunk->iTextsize;
+ *zText = pChunk->zText;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ITXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_bkgd (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iType,
+ mng_uint8 *iIndex,
+ mng_uint16 *iGray,
+ mng_uint16 *iRed,
+ mng_uint16 *iGreen,
+ mng_uint16 *iBlue)
+{
+ mng_datap pData;
+ mng_bkgdp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BKGD, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_bkgdp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_bKGD)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iType = pChunk->iType;
+ *iIndex = pChunk->iIndex;
+ *iGray = pChunk->iGray;
+ *iRed = pChunk->iRed;
+ *iGreen = pChunk->iGreen;
+ *iBlue = pChunk->iBlue;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BKGD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_phys (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iSizex,
+ mng_uint32 *iSizey,
+ mng_uint8 *iUnit)
+{
+ mng_datap pData;
+ mng_physp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PHYS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_physp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_pHYs)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iSizex = pChunk->iSizex;
+ *iSizey = pChunk->iSizey;
+ *iUnit = pChunk->iUnit;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PHYS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_sbit (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iType,
+ mng_uint8arr4 *aBits)
+{
+ mng_datap pData;
+ mng_sbitp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SBIT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_sbitp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_sBIT)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty;
+ *iType = pChunk->iType;
+ (*aBits)[0] = pChunk->aBits[0];
+ (*aBits)[1] = pChunk->aBits[1];
+ (*aBits)[2] = pChunk->aBits[2];
+ (*aBits)[3] = pChunk->aBits[3];
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SBIT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_splt (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName,
+ mng_uint8 *iSampledepth,
+ mng_uint32 *iEntrycount,
+ mng_ptr *pEntries)
+{
+ mng_datap pData;
+ mng_spltp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SPLT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_spltp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_sPLT)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iNamesize = pChunk->iNamesize;
+ *zName = pChunk->zName;
+ *iSampledepth = pChunk->iSampledepth;
+ *iEntrycount = pChunk->iEntrycount;
+ *pEntries = pChunk->pEntries;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_hist (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iEntrycount,
+ mng_uint16arr *aEntries)
+{
+ mng_datap pData;
+ mng_histp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_HIST, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_histp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_hIST)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iEntrycount = pChunk->iEntrycount; /* fill the fields */
+
+ MNG_COPY (*aEntries, pChunk->aEntries, sizeof (mng_uint16arr))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_HIST, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_time (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iYear,
+ mng_uint8 *iMonth,
+ mng_uint8 *iDay,
+ mng_uint8 *iHour,
+ mng_uint8 *iMinute,
+ mng_uint8 *iSecond)
+{
+ mng_datap pData;
+ mng_timep pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TIME, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_timep)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_tIME)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iYear = pChunk->iYear; /* fill the fields */
+ *iMonth = pChunk->iMonth;
+ *iDay = pChunk->iDay;
+ *iHour = pChunk->iHour;
+ *iMinute = pChunk->iMinute;
+ *iSecond = pChunk->iSecond;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TIME, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_mhdr (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iWidth,
+ mng_uint32 *iHeight,
+ mng_uint32 *iTicks,
+ mng_uint32 *iLayercount,
+ mng_uint32 *iFramecount,
+ mng_uint32 *iPlaytime,
+ mng_uint32 *iSimplicity)
+{
+ mng_datap pData;
+ mng_mhdrp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MHDR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_mhdrp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iWidth = pChunk->iWidth; /* fill the fields */
+ *iHeight = pChunk->iHeight;
+ *iTicks = pChunk->iTicks;
+ *iLayercount = pChunk->iLayercount;
+ *iFramecount = pChunk->iFramecount;
+ *iPlaytime = pChunk->iPlaytime;
+ *iSimplicity = pChunk->iSimplicity;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_loop (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint8 *iLevel,
+ mng_uint32 *iRepeat,
+ mng_uint8 *iTermination,
+ mng_uint32 *iItermin,
+ mng_uint32 *iItermax,
+ mng_uint32 *iCount,
+ mng_uint32p *pSignals)
+{
+ mng_datap pData;
+ mng_loopp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_LOOP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_loopp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_LOOP)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iLevel = pChunk->iLevel; /* fill teh fields */
+ *iRepeat = pChunk->iRepeat;
+ *iTermination = pChunk->iTermination;
+ *iItermin = pChunk->iItermin;
+ *iItermax = pChunk->iItermax;
+ *iCount = pChunk->iCount;
+ *pSignals = pChunk->pSignals;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_LOOP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_endl (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint8 *iLevel)
+{
+ mng_datap pData;
+ mng_endlp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ENDL, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_endlp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_ENDL)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iLevel = pChunk->iLevel; /* fill the field */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ENDL, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_defi (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iObjectid,
+ mng_uint8 *iDonotshow,
+ mng_uint8 *iConcrete,
+ mng_bool *bHasloca,
+ mng_int32 *iXlocation,
+ mng_int32 *iYlocation,
+ mng_bool *bHasclip,
+ mng_int32 *iLeftcb,
+ mng_int32 *iRightcb,
+ mng_int32 *iTopcb,
+ mng_int32 *iBottomcb)
+{
+ mng_datap pData;
+ mng_defip pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DEFI, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_defip)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_DEFI)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iObjectid = pChunk->iObjectid; /* fill the fields */
+ *iDonotshow = pChunk->iDonotshow;
+ *iConcrete = pChunk->iConcrete;
+ *bHasloca = pChunk->bHasloca;
+ *iXlocation = pChunk->iXlocation;
+ *iYlocation = pChunk->iYlocation;
+ *bHasclip = pChunk->bHasclip;
+ *iLeftcb = pChunk->iLeftcb;
+ *iRightcb = pChunk->iRightcb;
+ *iTopcb = pChunk->iTopcb;
+ *iBottomcb = pChunk->iBottomcb;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DEFI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_basi (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iWidth,
+ mng_uint32 *iHeight,
+ mng_uint8 *iBitdepth,
+ mng_uint8 *iColortype,
+ mng_uint8 *iCompression,
+ mng_uint8 *iFilter,
+ mng_uint8 *iInterlace,
+ mng_uint16 *iRed,
+ mng_uint16 *iGreen,
+ mng_uint16 *iBlue,
+ mng_uint16 *iAlpha,
+ mng_uint8 *iViewable)
+{
+ mng_datap pData;
+ mng_basip pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BASI, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_basip)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_BASI)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iWidth = pChunk->iWidth; /* fill the fields */
+ *iHeight = pChunk->iHeight;
+ *iBitdepth = pChunk->iBitdepth;
+ *iColortype = pChunk->iColortype;
+ *iCompression = pChunk->iCompression;
+ *iFilter = pChunk->iFilter;
+ *iInterlace = pChunk->iInterlace;
+ *iRed = pChunk->iRed;
+ *iGreen = pChunk->iGreen;
+ *iBlue = pChunk->iBlue;
+ *iAlpha = pChunk->iAlpha;
+ *iViewable = pChunk->iViewable;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BASI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_clon (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iSourceid,
+ mng_uint16 *iCloneid,
+ mng_uint8 *iClonetype,
+ mng_uint8 *iDonotshow,
+ mng_uint8 *iConcrete,
+ mng_bool *bHasloca,
+ mng_uint8 *iLocationtype,
+ mng_int32 *iLocationx,
+ mng_int32 *iLocationy)
+{
+ mng_datap pData;
+ mng_clonp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CLON, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_clonp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_CLON)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iSourceid = pChunk->iSourceid; /* fill the fields */
+ *iCloneid = pChunk->iCloneid;
+ *iClonetype = pChunk->iClonetype;
+ *iDonotshow = pChunk->iDonotshow;
+ *iConcrete = pChunk->iConcrete;
+ *bHasloca = pChunk->bHasloca;
+ *iLocationtype = pChunk->iLocationtype;
+ *iLocationx = pChunk->iLocationx;
+ *iLocationy = pChunk->iLocationy;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CLON, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_past (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iDestid,
+ mng_uint8 *iTargettype,
+ mng_int32 *iTargetx,
+ mng_int32 *iTargety,
+ mng_uint32 *iCount)
+{
+ mng_datap pData;
+ mng_pastp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PAST, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_pastp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_PAST)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iDestid = pChunk->iDestid; /* fill the fields */
+ *iTargettype = pChunk->iTargettype;
+ *iTargetx = pChunk->iTargetx;
+ *iTargety = pChunk->iTargety;
+ *iCount = pChunk->iCount;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PAST, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_past_src (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 iEntry,
+ mng_uint16 *iSourceid,
+ mng_uint8 *iComposition,
+ mng_uint8 *iOrientation,
+ mng_uint8 *iOffsettype,
+ mng_int32 *iOffsetx,
+ mng_int32 *iOffsety,
+ mng_uint8 *iBoundarytype,
+ mng_int32 *iBoundaryl,
+ mng_int32 *iBoundaryr,
+ mng_int32 *iBoundaryt,
+ mng_int32 *iBoundaryb)
+{
+ mng_datap pData;
+ mng_pastp pChunk;
+ mng_past_sourcep pEntry;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PAST_SRC, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_pastp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_PAST)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ if (iEntry >= pChunk->iCount) /* valid index ? */
+ MNG_ERROR (pData, MNG_INVALIDENTRYIX)
+ /* address the entry */
+ pEntry = pChunk->pSources + iEntry;
+
+ *iSourceid = pEntry->iSourceid; /* fill the fields */
+ *iComposition = pEntry->iComposition;
+ *iOrientation = pEntry->iOrientation;
+ *iOffsettype = pEntry->iOffsettype;
+ *iOffsetx = pEntry->iOffsetx;
+ *iOffsety = pEntry->iOffsety;
+ *iBoundarytype = pEntry->iBoundarytype;
+ *iBoundaryl = pEntry->iBoundaryl;
+ *iBoundaryr = pEntry->iBoundaryr;
+ *iBoundaryt = pEntry->iBoundaryt;
+ *iBoundaryb = pEntry->iBoundaryb;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PAST_SRC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_disc (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iCount,
+ mng_uint16p *pObjectids)
+{
+ mng_datap pData;
+ mng_discp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DISC, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_discp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_DISC)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iCount = pChunk->iCount; /* fill the fields */
+ *pObjectids = pChunk->pObjectids;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DISC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_back (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iRed,
+ mng_uint16 *iGreen,
+ mng_uint16 *iBlue,
+ mng_uint8 *iMandatory,
+ mng_uint16 *iImageid,
+ mng_uint8 *iTile)
+{
+ mng_datap pData;
+ mng_backp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BACK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_backp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_BACK)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iRed = pChunk->iRed; /* fill the fields */
+ *iGreen = pChunk->iGreen;
+ *iBlue = pChunk->iBlue;
+ *iMandatory = pChunk->iMandatory;
+ *iImageid = pChunk->iImageid;
+ *iTile = pChunk->iTile;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_BACK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_fram (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iMode,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName,
+ mng_uint8 *iChangedelay,
+ mng_uint8 *iChangetimeout,
+ mng_uint8 *iChangeclipping,
+ mng_uint8 *iChangesyncid,
+ mng_uint32 *iDelay,
+ mng_uint32 *iTimeout,
+ mng_uint8 *iBoundarytype,
+ mng_int32 *iBoundaryl,
+ mng_int32 *iBoundaryr,
+ mng_int32 *iBoundaryt,
+ mng_int32 *iBoundaryb,
+ mng_uint32 *iCount,
+ mng_uint32p *pSyncids)
+{
+ mng_datap pData;
+ mng_framp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_FRAM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_framp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_FRAM)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iMode = pChunk->iMode;
+ *iNamesize = pChunk->iNamesize;
+ *zName = pChunk->zName;
+ *iChangedelay = pChunk->iChangedelay;
+ *iChangetimeout = pChunk->iChangetimeout;
+ *iChangeclipping = pChunk->iChangeclipping;
+ *iChangesyncid = pChunk->iChangesyncid;
+ *iDelay = pChunk->iDelay;
+ *iTimeout = pChunk->iTimeout;
+ *iBoundarytype = pChunk->iBoundarytype;
+ *iBoundaryl = pChunk->iBoundaryl;
+ *iBoundaryr = pChunk->iBoundaryr;
+ *iBoundaryt = pChunk->iBoundaryt;
+ *iBoundaryb = pChunk->iBoundaryb;
+ *iCount = pChunk->iCount;
+ *pSyncids = pChunk->pSyncids;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_FRAM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_move (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iFirstid,
+ mng_uint16 *iLastid,
+ mng_uint8 *iMovetype,
+ mng_int32 *iMovex,
+ mng_int32 *iMovey)
+{
+ mng_datap pData;
+ mng_movep pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MOVE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_movep)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_MOVE)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iFirstid = pChunk->iFirstid; /* fill the fields */
+ *iLastid = pChunk->iLastid;
+ *iMovetype = pChunk->iMovetype;
+ *iMovex = pChunk->iMovex;
+ *iMovey = pChunk->iMovey;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MOVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_clip (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iFirstid,
+ mng_uint16 *iLastid,
+ mng_uint8 *iCliptype,
+ mng_int32 *iClipl,
+ mng_int32 *iClipr,
+ mng_int32 *iClipt,
+ mng_int32 *iClipb)
+{
+ mng_datap pData;
+ mng_clipp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CLIP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_clipp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_CLIP)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iFirstid = pChunk->iFirstid; /* fill the fields */
+ *iLastid = pChunk->iLastid;
+ *iCliptype = pChunk->iCliptype;
+ *iClipl = pChunk->iClipl;
+ *iClipr = pChunk->iClipr;
+ *iClipt = pChunk->iClipt;
+ *iClipb = pChunk->iClipb;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_CLIP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_show (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint16 *iFirstid,
+ mng_uint16 *iLastid,
+ mng_uint8 *iMode)
+{
+ mng_datap pData;
+ mng_showp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SHOW, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_showp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_SHOW)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iFirstid = pChunk->iFirstid;
+ *iLastid = pChunk->iLastid;
+ *iMode = pChunk->iMode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SHOW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_term (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint8 *iTermaction,
+ mng_uint8 *iIteraction,
+ mng_uint32 *iDelay,
+ mng_uint32 *iItermax)
+{
+ mng_datap pData;
+ mng_termp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TERM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_termp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_TERM)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iTermaction = pChunk->iTermaction; /* fill the fields */
+ *iIteraction = pChunk->iIteraction;
+ *iDelay = pChunk->iDelay;
+ *iItermax = pChunk->iItermax;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_TERM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_save (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint8 *iOffsettype,
+ mng_uint32 *iCount)
+{
+ mng_datap pData;
+ mng_savep pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SAVE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_savep)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_SAVE)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iOffsettype = pChunk->iOffsettype;
+ *iCount = pChunk->iCount;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SAVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_save_entry (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 iEntry,
+ mng_uint8 *iEntrytype,
+ mng_uint32arr2 *iOffset,
+ mng_uint32arr2 *iStarttime,
+ mng_uint32 *iLayernr,
+ mng_uint32 *iFramenr,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName)
+{
+ mng_datap pData;
+ mng_savep pChunk;
+ mng_save_entryp pEntry;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SAVE_ENTRY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_savep)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_SAVE)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ if (iEntry >= pChunk->iCount) /* valid index ? */
+ MNG_ERROR (pData, MNG_INVALIDENTRYIX)
+
+ pEntry = pChunk->pEntries + iEntry; /* address the entry */
+ /* fill the fields */
+ *iEntrytype = pEntry->iEntrytype;
+ (*iOffset)[0] = pEntry->iOffset[0];
+ (*iOffset)[1] = pEntry->iOffset[1];
+ (*iStarttime)[0] = pEntry->iStarttime[0];
+ (*iStarttime)[1] = pEntry->iStarttime[1];
+ *iLayernr = pEntry->iLayernr;
+ *iFramenr = pEntry->iFramenr;
+ *iNamesize = pEntry->iNamesize;
+ *zName = pEntry->zName;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SAVE_ENTRY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_seek (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName)
+{
+ mng_datap pData;
+ mng_seekp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SEEK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_seekp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_SEEK)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iNamesize = pChunk->iNamesize; /* fill the fields */
+ *zName = pChunk->zName;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_SEEK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_expi (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iSnapshotid,
+ mng_uint32 *iNamesize,
+ mng_pchar *zName)
+{
+ mng_datap pData;
+ mng_expip pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_EXPI, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_expip)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_eXPI)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iSnapshotid = pChunk->iSnapshotid; /* fill the fields */
+ *iNamesize = pChunk->iNamesize;
+ *zName = pChunk->zName;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_EXPI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_fpri (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint8 *iDeltatype,
+ mng_uint8 *iPriority)
+{
+ mng_datap pData;
+ mng_fprip pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_FPRI, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_fprip)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_fPRI)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iDeltatype = pChunk->iDeltatype; /* fill the fields */
+ *iPriority = pChunk->iPriority;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_FPRI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_need (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iKeywordssize,
+ mng_pchar *zKeywords)
+{
+ mng_datap pData;
+ mng_needp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_NEED, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_needp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_nEED)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+ /* fill the fields */
+ *iKeywordssize = pChunk->iKeywordssize;
+ *zKeywords = pChunk->zKeywords;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_NEED, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_phyg (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_bool *bEmpty,
+ mng_uint32 *iSizex,
+ mng_uint32 *iSizey,
+ mng_uint8 *iUnit)
+{
+ mng_datap pData;
+ mng_phygp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PHYG, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_phygp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_pHYg)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *bEmpty = pChunk->bEmpty; /* fill the fields */
+ *iSizex = pChunk->iSizex;
+ *iSizey = pChunk->iSizey;
+ *iUnit = pChunk->iUnit;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PHYG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* B004 */
+#ifdef MNG_INCLUDE_JNG
+/* B004 */
+mng_retcode MNG_DECL mng_getchunk_jhdr (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iWidth,
+ mng_uint32 *iHeight,
+ mng_uint8 *iColortype,
+ mng_uint8 *iImagesampledepth,
+ mng_uint8 *iImagecompression,
+ mng_uint8 *iImageinterlace,
+ mng_uint8 *iAlphasampledepth,
+ mng_uint8 *iAlphacompression,
+ mng_uint8 *iAlphafilter,
+ mng_uint8 *iAlphainterlace)
+{
+ mng_datap pData;
+ mng_jhdrp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_JHDR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_jhdrp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_JHDR)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iWidth = pChunk->iWidth; /* fill the fields */
+ *iHeight = pChunk->iHeight;
+ *iColortype = pChunk->iColortype;
+ *iImagesampledepth = pChunk->iImagesampledepth;
+ *iImagecompression = pChunk->iImagecompression;
+ *iImageinterlace = pChunk->iImageinterlace;
+ *iAlphasampledepth = pChunk->iAlphasampledepth;
+ *iAlphacompression = pChunk->iAlphacompression;
+ *iAlphafilter = pChunk->iAlphafilter;
+ *iAlphainterlace = pChunk->iAlphainterlace;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_JHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+/* B004 */
+#endif /* MNG_INCLUDE_JNG */
+/* B004 */
+/* ************************************************************************** */
+/* B004 */
+#ifdef MNG_INCLUDE_JNG
+/* B004 */
+mng_retcode MNG_DECL mng_getchunk_jdat (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iRawlen,
+ mng_ptr *pRawdata)
+{
+ mng_datap pData;
+ mng_jdatp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_JDAT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_jdatp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_JDAT)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iRawlen = pChunk->iDatasize; /* fill the fields */
+ *pRawdata = pChunk->pData;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_JDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+/* B004 */
+#endif /* MNG_INCLUDE_JNG */
+/* B004 */
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_dhdr (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iObjectid,
+ mng_uint8 *iImagetype,
+ mng_uint8 *iDeltatype,
+ mng_uint32 *iBlockwidth,
+ mng_uint32 *iBlockheight,
+ mng_uint32 *iBlockx,
+ mng_uint32 *iBlocky)
+{
+ mng_datap pData;
+ mng_dhdrp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DHDR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_dhdrp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_DHDR)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iObjectid = pChunk->iObjectid; /* fill the fields */
+ *iImagetype = pChunk->iImagetype;
+ *iDeltatype = pChunk->iDeltatype;
+ *iBlockwidth = pChunk->iBlockwidth;
+ *iBlockheight = pChunk->iBlockheight;
+ *iBlockx = pChunk->iBlockx;
+ *iBlocky = pChunk->iBlocky;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_prom (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint8 *iColortype,
+ mng_uint8 *iSampledepth,
+ mng_uint8 *iFilltype)
+{
+ mng_datap pData;
+ mng_promp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PROM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_promp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_PROM)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iColortype = pChunk->iColortype; /* fill the fields */
+ *iSampledepth = pChunk->iSampledepth;
+ *iFilltype = pChunk->iFilltype;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PROM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_pplt (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iCount)
+{
+ mng_datap pData;
+ mng_ppltp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PPLT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_ppltp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_PPLT)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iCount = pChunk->iCount; /* fill the field */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_pplt_entry (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 iEntry,
+ mng_uint16 *iRed,
+ mng_uint16 *iGreen,
+ mng_uint16 *iBlue,
+ mng_uint16 *iAlpha,
+ mng_bool *bUsed)
+{
+ mng_datap pData;
+ mng_ppltp pChunk;
+ mng_pplt_entryp pEntry;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PPLT_ENTRY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_ppltp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_PPLT)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ if (iEntry >= pChunk->iCount) /* valid index ? */
+ MNG_ERROR (pData, MNG_INVALIDENTRYIX)
+
+ pEntry = &pChunk->aEntries[iEntry]; /* address the entry */
+
+ *iRed = pEntry->iRed; /* fill the fields */
+ *iGreen = pEntry->iGreen;
+ *iBlue = pEntry->iBlue;
+ *iAlpha = pEntry->iAlpha;
+ *bUsed = pEntry->bUsed;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_PPLT_ENTRY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_drop (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iCount,
+ mng_chunkidp *pChunknames)
+{
+ mng_datap pData;
+ mng_dropp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DROP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_dropp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_DROP)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iCount = pChunk->iCount; /* fill the fields */
+ *pChunknames = pChunk->pChunknames;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DROP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_dbyk (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_chunkid *iChunkname,
+ mng_uint8 *iPolarity,
+ mng_uint32 *iKeywordssize,
+ mng_pchar *zKeywords)
+{
+ mng_datap pData;
+ mng_dbykp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DBYK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_dbykp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_DBYK)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iChunkname = pChunk->iChunkname; /* fill the fields */
+ *iPolarity = pChunk->iPolarity;
+ *iKeywordssize = pChunk->iKeywordssize;
+ *zKeywords = pChunk->zKeywords;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_DBYK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_ordr (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 *iCount)
+{
+ mng_datap pData;
+ mng_ordrp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ORDR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_ordrp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_ORDR)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iCount = pChunk->iCount; /* fill the field */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ORDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_ordr_entry (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 iEntry,
+ mng_chunkid *iChunkname,
+ mng_uint8 *iOrdertype)
+{
+ mng_datap pData;
+ mng_ordrp pChunk;
+ mng_ordr_entryp pEntry;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ORDR_ENTRY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_ordrp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_ORDR)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ if (iEntry >= pChunk->iCount) /* valid index ? */
+ MNG_ERROR (pData, MNG_INVALIDENTRYIX)
+
+ pEntry = pChunk->pEntries + iEntry; /* address the proper entry */
+
+ *iChunkname = pEntry->iChunkname; /* fill the fields */
+ *iOrdertype = pEntry->iOrdertype;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_ORDR_ENTRY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_magn (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint16 *iFirstid,
+ mng_uint16 *iLastid,
+ mng_uint16 *iMethodX,
+ mng_uint16 *iMX,
+ mng_uint16 *iMY,
+ mng_uint16 *iML,
+ mng_uint16 *iMR,
+ mng_uint16 *iMT,
+ mng_uint16 *iMB,
+ mng_uint16 *iMethodY)
+{
+ mng_datap pData;
+ mng_magnp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MAGN, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_magnp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.iChunkname != MNG_UINT_MAGN)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+
+ *iFirstid = pChunk->iFirstid; /* fill the fields */
+ *iLastid = pChunk->iLastid;
+ *iMethodX = pChunk->iMethodX;
+ *iMX = pChunk->iMX;
+ *iMY = pChunk->iMY;
+ *iML = pChunk->iML;
+ *iMR = pChunk->iMR;
+ *iMT = pChunk->iMT;
+ *iMB = pChunk->iMB;
+ *iMethodY = pChunk->iMethodY;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_MAGN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getchunk_unknown (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_chunkid *iChunkname,
+ mng_uint32 *iRawlen,
+ mng_ptr *pRawdata)
+{
+ mng_datap pData;
+ mng_unknown_chunkp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_UNKNOWN, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+ pChunk = (mng_unknown_chunkp)hChunk; /* address the chunk */
+
+ if (pChunk->sHeader.fCreate != init_unknown)
+ MNG_ERROR (pData, MNG_WRONGCHUNK) /* ouch */
+ /* fill the fields */
+ *iChunkname = pChunk->sHeader.iChunkname;
+ *iRawlen = pChunk->iDatasize;
+ *pRawdata = pChunk->pData;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETCHUNK_UNKNOWN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+/* B004 */
+#ifdef MNG_INCLUDE_WRITE_PROCS
+/* B004 */
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_ihdr (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_IHDR, init_ihdr, free_ihdr, read_ihdr, write_ihdr, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IHDR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* create the chunk */
+ iRetcode = init_ihdr (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_ihdrp)pChunk)->iWidth = iWidth;
+ ((mng_ihdrp)pChunk)->iHeight = iHeight;
+ ((mng_ihdrp)pChunk)->iBitdepth = iBitdepth;
+ ((mng_ihdrp)pChunk)->iColortype = iColortype;
+ ((mng_ihdrp)pChunk)->iCompression = iCompression;
+ ((mng_ihdrp)pChunk)->iFilter = iFilter;
+ ((mng_ihdrp)pChunk)->iInterlace = iInterlace;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_plte (mng_handle hHandle,
+ mng_uint32 iCount,
+ mng_palette8 aPalette)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_PLTE, init_plte, free_plte, read_plte, write_plte, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PLTE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_plte (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_pltep)pChunk)->iEntrycount = iCount;
+ ((mng_pltep)pChunk)->bEmpty = (mng_bool)(iCount == 0);
+
+ MNG_COPY (((mng_pltep)pChunk)->aEntries, aPalette, sizeof (mng_palette8))
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PLTE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_idat (mng_handle hHandle,
+ mng_uint32 iRawlen,
+ mng_ptr pRawdata)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_IDAT, init_idat, free_idat, read_idat, write_idat, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IDAT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_idat (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_idatp)pChunk)->bEmpty = (mng_bool)(iRawlen == 0);
+ ((mng_idatp)pChunk)->iDatasize = iRawlen;
+
+ if (iRawlen)
+ {
+ MNG_ALLOC (pData, ((mng_idatp)pChunk)->pData, iRawlen)
+ MNG_COPY (((mng_idatp)pChunk)->pData, pRawdata, iRawlen)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_iend (mng_handle hHandle)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_IEND, init_iend, free_iend, read_iend, write_iend, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IEND, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_iend (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->iFirstchunkadded == MNG_UINT_IHDR) ||
+ (pData->iFirstchunkadded == MNG_UINT_JHDR) )
+#else
+ if (pData->iFirstchunkadded == MNG_UINT_IHDR)
+#endif
+ pData->bCreating = MNG_FALSE; /* should be last chunk !!! */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_trns (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_bool bGlobal,
+ mng_uint8 iType,
+ mng_uint32 iCount,
+ mng_uint8arr aAlphas,
+ mng_uint16 iGray,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_uint32 iRawlen,
+ mng_uint8arr aRawdata)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_tRNS, init_trns, free_trns, read_trns, write_trns, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TRNS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_trns (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_trnsp)pChunk)->bEmpty = bEmpty;
+ ((mng_trnsp)pChunk)->bGlobal = bGlobal;
+ ((mng_trnsp)pChunk)->iType = iType;
+ ((mng_trnsp)pChunk)->iCount = iCount;
+ ((mng_trnsp)pChunk)->iGray = iGray;
+ ((mng_trnsp)pChunk)->iRed = iRed;
+ ((mng_trnsp)pChunk)->iGreen = iGreen;
+ ((mng_trnsp)pChunk)->iBlue = iBlue;
+ ((mng_trnsp)pChunk)->iRawlen = iRawlen;
+
+ MNG_COPY (((mng_trnsp)pChunk)->aEntries, aAlphas, sizeof (mng_uint8arr))
+ MNG_COPY (((mng_trnsp)pChunk)->aRawdata, aRawdata, sizeof (mng_uint8arr))
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TRNS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_gama (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iGamma)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_gAMA, init_gama, free_gama, read_gama, write_gama, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_GAMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_gama (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_gamap)pChunk)->bEmpty = bEmpty;
+ ((mng_gamap)pChunk)->iGamma = iGamma;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_GAMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_chrm (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iWhitepointx,
+ mng_uint32 iWhitepointy,
+ mng_uint32 iRedx,
+ mng_uint32 iRedy,
+ mng_uint32 iGreenx,
+ mng_uint32 iGreeny,
+ mng_uint32 iBluex,
+ mng_uint32 iBluey)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_cHRM, init_chrm, free_chrm, read_chrm, write_chrm, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CHRM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_chrm (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_chrmp)pChunk)->bEmpty = bEmpty;
+ ((mng_chrmp)pChunk)->iWhitepointx = iWhitepointx;
+ ((mng_chrmp)pChunk)->iWhitepointy = iWhitepointy;
+ ((mng_chrmp)pChunk)->iRedx = iRedx;
+ ((mng_chrmp)pChunk)->iRedy = iRedy;
+ ((mng_chrmp)pChunk)->iGreenx = iGreenx;
+ ((mng_chrmp)pChunk)->iGreeny = iGreeny;
+ ((mng_chrmp)pChunk)->iBluex = iBluex;
+ ((mng_chrmp)pChunk)->iBluey = iBluey;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CHRM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_srgb (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint8 iRenderingintent)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_sRGB, init_srgb, free_srgb, read_srgb, write_srgb, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SRGB, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_srgb (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_srgbp)pChunk)->bEmpty = bEmpty;
+ ((mng_srgbp)pChunk)->iRenderingintent = iRenderingintent;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_iccp (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iNamesize,
+ mng_pchar zName,
+ mng_uint8 iCompression,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_iCCP, init_iccp, free_iccp, read_iccp, write_iccp, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ICCP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_iccp (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_iccpp)pChunk)->bEmpty = bEmpty;
+ ((mng_iccpp)pChunk)->iNamesize = iNamesize;
+ ((mng_iccpp)pChunk)->iCompression = iCompression;
+ ((mng_iccpp)pChunk)->iProfilesize = iProfilesize;
+
+ if (iNamesize)
+ {
+ MNG_ALLOC (pData, ((mng_iccpp)pChunk)->zName, iNamesize + 1)
+ MNG_COPY (((mng_iccpp)pChunk)->zName, zName, iNamesize)
+ }
+
+ if (iProfilesize)
+ {
+ MNG_ALLOC (pData, ((mng_iccpp)pChunk)->pProfile, iProfilesize)
+ MNG_COPY (((mng_iccpp)pChunk)->pProfile, pProfile, iProfilesize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ICCP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_text (mng_handle hHandle,
+ mng_uint32 iKeywordsize,
+ mng_pchar zKeyword,
+ mng_uint32 iTextsize,
+ mng_pchar zText)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_tEXt, init_text, free_text, read_text, write_text, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TEXT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_text (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_textp)pChunk)->iKeywordsize = iKeywordsize;
+ ((mng_textp)pChunk)->iTextsize = iTextsize;
+
+ if (iKeywordsize)
+ {
+ MNG_ALLOC (pData, ((mng_textp)pChunk)->zKeyword, iKeywordsize + 1)
+ MNG_COPY (((mng_textp)pChunk)->zKeyword, zKeyword, iKeywordsize)
+ }
+
+ if (iTextsize)
+ {
+ MNG_ALLOC (pData, ((mng_textp)pChunk)->zText, iTextsize + 1)
+ MNG_COPY (((mng_textp)pChunk)->zText, zText, iTextsize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TEXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_ztxt (mng_handle hHandle,
+ mng_uint32 iKeywordsize,
+ mng_pchar zKeyword,
+ mng_uint8 iCompression,
+ mng_uint32 iTextsize,
+ mng_pchar zText)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_zTXt, init_ztxt, free_ztxt, read_ztxt, write_ztxt, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ZTXT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_ztxt (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_ztxtp)pChunk)->iKeywordsize = iKeywordsize;
+ ((mng_ztxtp)pChunk)->iCompression = iCompression;
+ ((mng_ztxtp)pChunk)->iTextsize = iTextsize;
+
+ if (iKeywordsize)
+ {
+ MNG_ALLOC (pData, ((mng_ztxtp)pChunk)->zKeyword, iKeywordsize + 1)
+ MNG_COPY (((mng_ztxtp)pChunk)->zKeyword, zKeyword, iKeywordsize)
+ }
+
+ if (iTextsize)
+ {
+ MNG_ALLOC (pData, ((mng_ztxtp)pChunk)->zText, iTextsize + 1)
+ MNG_COPY (((mng_ztxtp)pChunk)->zText, zText, iTextsize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ZTXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_itxt (mng_handle hHandle,
+ mng_uint32 iKeywordsize,
+ mng_pchar zKeyword,
+ mng_uint8 iCompressionflag,
+ mng_uint8 iCompressionmethod,
+ mng_uint32 iLanguagesize,
+ mng_pchar zLanguage,
+ mng_uint32 iTranslationsize,
+ mng_pchar zTranslation,
+ mng_uint32 iTextsize,
+ mng_pchar zText)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_iTXt, init_itxt, free_itxt, read_itxt, write_itxt, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ITXT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_itxt (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_itxtp)pChunk)->iKeywordsize = iKeywordsize;
+ ((mng_itxtp)pChunk)->iCompressionflag = iCompressionflag;
+ ((mng_itxtp)pChunk)->iCompressionmethod = iCompressionmethod;
+ ((mng_itxtp)pChunk)->iLanguagesize = iLanguagesize;
+ ((mng_itxtp)pChunk)->iTranslationsize = iTranslationsize;
+ ((mng_itxtp)pChunk)->iTextsize = iTextsize;
+
+ if (iKeywordsize)
+ {
+ MNG_ALLOC (pData, ((mng_itxtp)pChunk)->zKeyword, iKeywordsize + 1)
+ MNG_COPY (((mng_itxtp)pChunk)->zKeyword, zKeyword, iKeywordsize)
+ }
+
+ if (iLanguagesize)
+ {
+ MNG_ALLOC (pData, ((mng_itxtp)pChunk)->zLanguage, iLanguagesize + 1)
+ MNG_COPY (((mng_itxtp)pChunk)->zLanguage, zLanguage, iLanguagesize)
+ }
+
+ if (iTranslationsize)
+ {
+ MNG_ALLOC (pData, ((mng_itxtp)pChunk)->zTranslation, iTranslationsize + 1)
+ MNG_COPY (((mng_itxtp)pChunk)->zTranslation, zTranslation, iTranslationsize)
+ }
+
+ if (iTextsize)
+ {
+ MNG_ALLOC (pData, ((mng_itxtp)pChunk)->zText, iTextsize + 1)
+ MNG_COPY (((mng_itxtp)pChunk)->zText, zText, iTextsize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ITXT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_bkgd (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint8 iType,
+ mng_uint8 iIndex,
+ mng_uint16 iGray,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_bKGD, init_bkgd, free_bkgd, read_bkgd, write_bkgd, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BKGD, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_bkgd (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_bkgdp)pChunk)->bEmpty = bEmpty;
+ ((mng_bkgdp)pChunk)->iType = iType;
+ ((mng_bkgdp)pChunk)->iIndex = iIndex;
+ ((mng_bkgdp)pChunk)->iGray = iGray;
+ ((mng_bkgdp)pChunk)->iRed = iRed;
+ ((mng_bkgdp)pChunk)->iGreen = iGreen;
+ ((mng_bkgdp)pChunk)->iBlue = iBlue;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BKGD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_phys (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iSizex,
+ mng_uint32 iSizey,
+ mng_uint8 iUnit)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_pHYs, init_phys, free_phys, read_phys, write_phys, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PHYS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_phys (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_physp)pChunk)->bEmpty = bEmpty;
+ ((mng_physp)pChunk)->iSizex = iSizex;
+ ((mng_physp)pChunk)->iSizey = iSizey;
+ ((mng_physp)pChunk)->iUnit = iUnit;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PHYS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_sbit (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint8 iType,
+ mng_uint8arr4 aBits)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_sBIT, init_sbit, free_sbit, read_sbit, write_sbit, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SBIT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_sbit (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_sbitp)pChunk)->bEmpty = bEmpty;
+ ((mng_sbitp)pChunk)->iType = iType;
+ ((mng_sbitp)pChunk)->aBits[0] = aBits[0];
+ ((mng_sbitp)pChunk)->aBits[1] = aBits[1];
+ ((mng_sbitp)pChunk)->aBits[2] = aBits[2];
+ ((mng_sbitp)pChunk)->aBits[3] = aBits[3];
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SBIT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_splt (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iNamesize,
+ mng_pchar zName,
+ mng_uint8 iSampledepth,
+ mng_uint32 iEntrycount,
+ mng_ptr pEntries)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_sPLT, init_splt, free_splt, read_splt, write_splt, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SPLT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_splt (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_spltp)pChunk)->bEmpty = bEmpty;
+ ((mng_spltp)pChunk)->iNamesize = iNamesize;
+ ((mng_spltp)pChunk)->iSampledepth = iSampledepth;
+ ((mng_spltp)pChunk)->iEntrycount = iEntrycount;
+
+ if (iNamesize)
+ {
+ MNG_ALLOC (pData, ((mng_spltp)pChunk)->zName, iNamesize + 1)
+ MNG_COPY (((mng_spltp)pChunk)->zName, zName, iNamesize)
+ }
+
+ if (iEntrycount)
+ {
+ mng_uint32 iSize = iEntrycount * ((iSampledepth >> 1) + 2);
+
+ MNG_ALLOC (pData, ((mng_spltp)pChunk)->pEntries, iSize)
+ MNG_COPY (((mng_spltp)pChunk)->pEntries, pEntries, iSize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_hist (mng_handle hHandle,
+ mng_uint32 iEntrycount,
+ mng_uint16arr aEntries)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_hIST, init_hist, free_hist, read_hist, write_hist, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_HIST, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_hist (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_histp)pChunk)->iEntrycount = iEntrycount;
+
+ MNG_COPY (((mng_histp)pChunk)->aEntries, aEntries, sizeof (mng_uint16arr))
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_HIST, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_time (mng_handle hHandle,
+ mng_uint16 iYear,
+ mng_uint8 iMonth,
+ mng_uint8 iDay,
+ mng_uint8 iHour,
+ mng_uint8 iMinute,
+ mng_uint8 iSecond)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_tIME, init_time, free_time, read_time, write_time, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TIME, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_time (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_timep)pChunk)->iYear = iYear;
+ ((mng_timep)pChunk)->iMonth = iMonth;
+ ((mng_timep)pChunk)->iDay = iDay;
+ ((mng_timep)pChunk)->iHour = iHour;
+ ((mng_timep)pChunk)->iMinute = iMinute;
+ ((mng_timep)pChunk)->iSecond = iSecond;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TIME, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_mhdr (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint32 iTicks,
+ mng_uint32 iLayercount,
+ mng_uint32 iFramecount,
+ mng_uint32 iPlaytime,
+ mng_uint32 iSimplicity)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_MHDR, init_mhdr, free_mhdr, read_mhdr, write_mhdr, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MHDR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* create the chunk */
+ iRetcode = init_mhdr (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_mhdrp)pChunk)->iWidth = iWidth;
+ ((mng_mhdrp)pChunk)->iHeight = iHeight;
+ ((mng_mhdrp)pChunk)->iTicks = iTicks;
+ ((mng_mhdrp)pChunk)->iLayercount = iLayercount;
+ ((mng_mhdrp)pChunk)->iFramecount = iFramecount;
+ ((mng_mhdrp)pChunk)->iPlaytime = iPlaytime;
+ ((mng_mhdrp)pChunk)->iSimplicity = iSimplicity;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_mend (mng_handle hHandle)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_MEND, init_mend, free_mend, read_mend, write_mend, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MEND, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_mend (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+ pData->bCreating = MNG_FALSE; /* should be last chunk !!! */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_loop (mng_handle hHandle,
+ mng_uint8 iLevel,
+ mng_uint32 iRepeat,
+ mng_uint8 iTermination,
+ mng_uint32 iItermin,
+ mng_uint32 iItermax,
+ mng_uint32 iCount,
+ mng_uint32p pSignals)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_LOOP, init_loop, free_loop, read_loop, write_loop, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_LOOP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_loop (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_loopp)pChunk)->iLevel = iLevel;
+ ((mng_loopp)pChunk)->iRepeat = iRepeat;
+ ((mng_loopp)pChunk)->iTermination = iTermination;
+ ((mng_loopp)pChunk)->iItermin = iItermin;
+ ((mng_loopp)pChunk)->iItermax = iItermax;
+ ((mng_loopp)pChunk)->iCount = iCount;
+ ((mng_loopp)pChunk)->pSignals = pSignals;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_LOOP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_endl (mng_handle hHandle,
+ mng_uint8 iLevel)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_ENDL, init_endl, free_endl, read_endl, write_endl, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ENDL, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_endl (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_endlp)pChunk)->iLevel = iLevel;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ENDL, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_defi (mng_handle hHandle,
+ mng_uint16 iObjectid,
+ mng_uint8 iDonotshow,
+ mng_uint8 iConcrete,
+ mng_bool bHasloca,
+ mng_int32 iXlocation,
+ mng_int32 iYlocation,
+ mng_bool bHasclip,
+ mng_int32 iLeftcb,
+ mng_int32 iRightcb,
+ mng_int32 iTopcb,
+ mng_int32 iBottomcb)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_DEFI, init_defi, free_defi, read_defi, write_defi, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DEFI, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_defi (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_defip)pChunk)->iObjectid = iObjectid;
+ ((mng_defip)pChunk)->iDonotshow = iDonotshow;
+ ((mng_defip)pChunk)->iConcrete = iConcrete;
+ ((mng_defip)pChunk)->bHasloca = bHasloca;
+ ((mng_defip)pChunk)->iXlocation = iXlocation;
+ ((mng_defip)pChunk)->iYlocation = iYlocation;
+ ((mng_defip)pChunk)->bHasclip = bHasclip;
+ ((mng_defip)pChunk)->iLeftcb = iLeftcb;
+ ((mng_defip)pChunk)->iRightcb = iRightcb;
+ ((mng_defip)pChunk)->iTopcb = iTopcb;
+ ((mng_defip)pChunk)->iBottomcb = iBottomcb;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DEFI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_basi (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_uint16 iAlpha,
+ mng_uint8 iViewable)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_BASI, init_basi, free_basi, read_basi, write_basi, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BASI, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_basi (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_basip)pChunk)->iWidth = iWidth;
+ ((mng_basip)pChunk)->iHeight = iHeight;
+ ((mng_basip)pChunk)->iBitdepth = iBitdepth;
+ ((mng_basip)pChunk)->iColortype = iColortype;
+ ((mng_basip)pChunk)->iCompression = iCompression;
+ ((mng_basip)pChunk)->iFilter = iFilter;
+ ((mng_basip)pChunk)->iInterlace = iInterlace;
+ ((mng_basip)pChunk)->iRed = iRed;
+ ((mng_basip)pChunk)->iGreen = iGreen;
+ ((mng_basip)pChunk)->iBlue = iBlue;
+ ((mng_basip)pChunk)->iAlpha = iAlpha;
+ ((mng_basip)pChunk)->iViewable = iViewable;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BASI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_clon (mng_handle hHandle,
+ mng_uint16 iSourceid,
+ mng_uint16 iCloneid,
+ mng_uint8 iClonetype,
+ mng_uint8 iDonotshow,
+ mng_uint8 iConcrete,
+ mng_bool bHasloca,
+ mng_uint8 iLocationtype,
+ mng_int32 iLocationx,
+ mng_int32 iLocationy)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_CLON, init_clon, free_clon, read_clon, write_clon, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CLON, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_clon (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_clonp)pChunk)->iSourceid = iSourceid;
+ ((mng_clonp)pChunk)->iCloneid = iCloneid;
+ ((mng_clonp)pChunk)->iClonetype = iClonetype;
+ ((mng_clonp)pChunk)->iDonotshow = iDonotshow;
+ ((mng_clonp)pChunk)->iConcrete = iConcrete;
+ ((mng_clonp)pChunk)->bHasloca = bHasloca;
+ ((mng_clonp)pChunk)->iLocationtype = iLocationtype;
+ ((mng_clonp)pChunk)->iLocationx = iLocationx;
+ ((mng_clonp)pChunk)->iLocationy = iLocationy;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CLON, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_past (mng_handle hHandle,
+ mng_uint16 iDestid,
+ mng_uint8 iTargettype,
+ mng_int32 iTargetx,
+ mng_int32 iTargety,
+ mng_uint32 iCount)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_PAST, init_past, free_past, read_past, write_past, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PAST, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_past (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_pastp)pChunk)->iDestid = iDestid;
+ ((mng_pastp)pChunk)->iTargettype = iTargettype;
+ ((mng_pastp)pChunk)->iTargetx = iTargetx;
+ ((mng_pastp)pChunk)->iTargety = iTargety;
+ ((mng_pastp)pChunk)->iCount = iCount;
+
+ if (iCount)
+ MNG_ALLOC (pData, ((mng_pastp)pChunk)->pSources, iCount * sizeof (mng_past_source))
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PAST, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_past_src (mng_handle hHandle,
+ mng_uint32 iEntry,
+ mng_uint16 iSourceid,
+ mng_uint8 iComposition,
+ mng_uint8 iOrientation,
+ mng_uint8 iOffsettype,
+ mng_int32 iOffsetx,
+ mng_int32 iOffsety,
+ mng_uint8 iBoundarytype,
+ mng_int32 iBoundaryl,
+ mng_int32 iBoundaryr,
+ mng_int32 iBoundaryt,
+ mng_int32 iBoundaryb)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_past_sourcep pEntry;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PAST_SRC, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+
+ pChunk = pData->pLastchunk; /* last one must have been PAST ! */
+
+ if (((mng_chunk_headerp)pChunk)->iChunkname != MNG_UINT_PAST)
+ MNG_ERROR (pData, MNG_NOCORRCHUNK)
+ /* index out of bounds ? */
+ if (iEntry >= ((mng_pastp)pChunk)->iCount)
+ MNG_ERROR (pData, MNG_INVALIDENTRYIX)
+ /* address proper entry */
+ pEntry = ((mng_pastp)pChunk)->pSources + iEntry;
+
+ pEntry->iSourceid = iSourceid; /* fill entry */
+ pEntry->iComposition = iComposition;
+ pEntry->iOrientation = iOrientation;
+ pEntry->iOffsettype = iOffsettype;
+ pEntry->iOffsetx = iOffsetx;
+ pEntry->iOffsety = iOffsety;
+ pEntry->iBoundarytype = iBoundarytype;
+ pEntry->iBoundaryl = iBoundaryl;
+ pEntry->iBoundaryr = iBoundaryr;
+ pEntry->iBoundaryt = iBoundaryt;
+ pEntry->iBoundaryb = iBoundaryb;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PAST_SRC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_disc (mng_handle hHandle,
+ mng_uint32 iCount,
+ mng_uint16p pObjectids)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_DISC, init_disc, free_disc, read_disc, write_disc, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DISC, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_disc (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_discp)pChunk)->iCount = iCount;
+
+ if (iCount)
+ {
+ mng_uint32 iSize = iCount * sizeof (mng_uint32);
+
+ MNG_ALLOC (pData, ((mng_discp)pChunk)->pObjectids, iSize);
+ MNG_COPY (((mng_discp)pChunk)->pObjectids, pObjectids, iSize);
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DISC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_back (mng_handle hHandle,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_uint8 iMandatory,
+ mng_uint16 iImageid,
+ mng_uint8 iTile)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_BACK, init_back, free_back, read_back, write_back, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BACK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_back (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_backp)pChunk)->iRed = iRed;
+ ((mng_backp)pChunk)->iGreen = iGreen;
+ ((mng_backp)pChunk)->iBlue = iBlue;
+ ((mng_backp)pChunk)->iMandatory = iMandatory;
+ ((mng_backp)pChunk)->iImageid = iImageid;
+ ((mng_backp)pChunk)->iTile = iTile;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_BACK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_fram (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint8 iMode,
+ mng_uint32 iNamesize,
+ mng_pchar zName,
+ mng_uint8 iChangedelay,
+ mng_uint8 iChangetimeout,
+ mng_uint8 iChangeclipping,
+ mng_uint8 iChangesyncid,
+ mng_uint32 iDelay,
+ mng_uint32 iTimeout,
+ mng_uint8 iBoundarytype,
+ mng_int32 iBoundaryl,
+ mng_int32 iBoundaryr,
+ mng_int32 iBoundaryt,
+ mng_int32 iBoundaryb,
+ mng_uint32 iCount,
+ mng_uint32p pSyncids)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_FRAM, init_fram, free_fram, read_fram, write_fram, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_FRAM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_fram (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_framp)pChunk)->bEmpty = bEmpty;
+ ((mng_framp)pChunk)->iMode = iMode;
+ ((mng_framp)pChunk)->iNamesize = iNamesize;
+ ((mng_framp)pChunk)->iChangedelay = iChangedelay;
+ ((mng_framp)pChunk)->iChangetimeout = iChangetimeout;
+ ((mng_framp)pChunk)->iChangeclipping = iChangeclipping;
+ ((mng_framp)pChunk)->iChangesyncid = iChangesyncid;
+ ((mng_framp)pChunk)->iDelay = iDelay;
+ ((mng_framp)pChunk)->iTimeout = iTimeout;
+ ((mng_framp)pChunk)->iBoundarytype = iBoundarytype;
+ ((mng_framp)pChunk)->iBoundaryl = iBoundaryl;
+ ((mng_framp)pChunk)->iBoundaryr = iBoundaryr;
+ ((mng_framp)pChunk)->iBoundaryt = iBoundaryt;
+ ((mng_framp)pChunk)->iBoundaryb = iBoundaryb;
+ ((mng_framp)pChunk)->iCount = iCount;
+
+ if (iNamesize)
+ {
+ MNG_ALLOC (pData, ((mng_framp)pChunk)->zName, iNamesize + 1)
+ MNG_COPY (((mng_framp)pChunk)->zName, zName, iNamesize)
+ }
+
+ if (iCount)
+ {
+ mng_uint32 iSize = iCount * sizeof (mng_uint32);
+
+ MNG_ALLOC (pData, ((mng_framp)pChunk)->pSyncids, iSize)
+ MNG_COPY (((mng_framp)pChunk)->pSyncids, pSyncids, iSize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_FRAM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_move (mng_handle hHandle,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iMovetype,
+ mng_int32 iMovex,
+ mng_int32 iMovey)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_MOVE, init_move, free_move, read_move, write_move, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MOVE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_move (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_movep)pChunk)->iFirstid = iFirstid;
+ ((mng_movep)pChunk)->iLastid = iLastid;
+ ((mng_movep)pChunk)->iMovetype = iMovetype;
+ ((mng_movep)pChunk)->iMovex = iMovex;
+ ((mng_movep)pChunk)->iMovey = iMovey;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MOVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_clip (mng_handle hHandle,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_CLIP, init_clip, free_clip, read_clip, write_clip, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CLIP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_clip (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_clipp)pChunk)->iFirstid = iFirstid;
+ ((mng_clipp)pChunk)->iLastid = iLastid;
+ ((mng_clipp)pChunk)->iCliptype = iCliptype;
+ ((mng_clipp)pChunk)->iClipl = iClipl;
+ ((mng_clipp)pChunk)->iClipr = iClipr;
+ ((mng_clipp)pChunk)->iClipt = iClipt;
+ ((mng_clipp)pChunk)->iClipb = iClipb;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_CLIP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_show (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iMode)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_SHOW, init_show, free_show, read_show, write_show, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SHOW, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_show (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_showp)pChunk)->bEmpty = bEmpty;
+ ((mng_showp)pChunk)->iFirstid = iFirstid;
+ ((mng_showp)pChunk)->iLastid = iLastid;
+ ((mng_showp)pChunk)->iMode = iMode;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SHOW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_term (mng_handle hHandle,
+ mng_uint8 iTermaction,
+ mng_uint8 iIteraction,
+ mng_uint32 iDelay,
+ mng_uint32 iItermax)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_TERM, init_term, free_term, read_term, write_term, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TERM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_term (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_termp)pChunk)->iTermaction = iTermaction;
+ ((mng_termp)pChunk)->iIteraction = iIteraction;
+ ((mng_termp)pChunk)->iDelay = iDelay;
+ ((mng_termp)pChunk)->iItermax = iItermax;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_TERM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_save (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint8 iOffsettype,
+ mng_uint32 iCount)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_SAVE, init_save, free_save, read_save, write_save, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SAVE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_save (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_savep)pChunk)->bEmpty = bEmpty;
+ ((mng_savep)pChunk)->iOffsettype = iOffsettype;
+ ((mng_savep)pChunk)->iCount = iCount;
+
+ if (iCount)
+ MNG_ALLOC (pData, ((mng_savep)pChunk)->pEntries, iCount * sizeof (mng_save_entry))
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SAVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_save_entry (mng_handle hHandle,
+ mng_uint32 iEntry,
+ mng_uint8 iEntrytype,
+ mng_uint32arr2 iOffset,
+ mng_uint32arr2 iStarttime,
+ mng_uint32 iLayernr,
+ mng_uint32 iFramenr,
+ mng_uint32 iNamesize,
+ mng_pchar zName)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_save_entryp pEntry;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SAVE_ENTRY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+
+ pChunk = pData->pLastchunk; /* last one must have been SAVE ! */
+
+ if (((mng_chunk_headerp)pChunk)->iChunkname != MNG_UINT_SAVE)
+ MNG_ERROR (pData, MNG_NOCORRCHUNK)
+ /* index out of bounds ? */
+ if (iEntry >= ((mng_savep)pChunk)->iCount)
+ MNG_ERROR (pData, MNG_INVALIDENTRYIX)
+ /* address proper entry */
+ pEntry = ((mng_savep)pChunk)->pEntries + iEntry;
+
+ pEntry->iEntrytype = iEntrytype; /* fill entry */
+ pEntry->iOffset[0] = iOffset[0];
+ pEntry->iOffset[1] = iOffset[1];
+ pEntry->iStarttime[0] = iStarttime[0];
+ pEntry->iStarttime[1] = iStarttime[1];
+ pEntry->iLayernr = iLayernr;
+ pEntry->iFramenr = iFramenr;
+ pEntry->iNamesize = iNamesize;
+
+ if (iNamesize)
+ {
+ MNG_ALLOC (pData, pEntry->zName, iNamesize + 1)
+ MNG_COPY (pEntry->zName, zName, iNamesize)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SAVE_ENTRY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_seek (mng_handle hHandle,
+ mng_uint32 iNamesize,
+ mng_pchar zName)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_SEEK, init_seek, free_seek, read_seek, write_seek, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SEEK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_seek (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_seekp)pChunk)->iNamesize = iNamesize;
+
+ if (iNamesize)
+ {
+ MNG_ALLOC (pData, ((mng_seekp)pChunk)->zName, iNamesize + 1)
+ MNG_COPY (((mng_seekp)pChunk)->zName, zName, iNamesize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_SEEK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_expi (mng_handle hHandle,
+ mng_uint16 iSnapshotid,
+ mng_uint32 iNamesize,
+ mng_pchar zName)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_eXPI, init_expi, free_expi, read_expi, write_expi, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_EXPI, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_expi (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_expip)pChunk)->iSnapshotid = iSnapshotid;
+ ((mng_expip)pChunk)->iNamesize = iNamesize;
+
+ if (iNamesize)
+ {
+ MNG_ALLOC (pData, ((mng_expip)pChunk)->zName, iNamesize + 1)
+ MNG_COPY (((mng_expip)pChunk)->zName, zName, iNamesize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_EXPI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_fpri (mng_handle hHandle,
+ mng_uint8 iDeltatype,
+ mng_uint8 iPriority)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_fPRI, init_fpri, free_fpri, read_fpri, write_fpri, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_FPRI, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_fpri (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_fprip)pChunk)->iDeltatype = iDeltatype;
+ ((mng_fprip)pChunk)->iPriority = iPriority;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_FPRI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_need (mng_handle hHandle,
+ mng_uint32 iKeywordssize,
+ mng_pchar zKeywords)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_nEED, init_need, free_need, read_need, write_need, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_NEED, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_need (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_needp)pChunk)->iKeywordssize = iKeywordssize;
+
+ if (iKeywordssize)
+ {
+ MNG_ALLOC (pData, ((mng_needp)pChunk)->zKeywords, iKeywordssize + 1)
+ MNG_COPY (((mng_needp)pChunk)->zKeywords, zKeywords, iKeywordssize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_NEED, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_phyg (mng_handle hHandle,
+ mng_bool bEmpty,
+ mng_uint32 iSizex,
+ mng_uint32 iSizey,
+ mng_uint8 iUnit)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_pHYg, init_phyg, free_phyg, read_phyg, write_phyg, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PHYG, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_phyg (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_phygp)pChunk)->bEmpty = bEmpty;
+ ((mng_phygp)pChunk)->iSizex = iSizex;
+ ((mng_phygp)pChunk)->iSizey = iSizey;
+ ((mng_phygp)pChunk)->iUnit = iUnit;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PHYG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* B004 */
+#ifdef MNG_INCLUDE_JNG
+/* B004 */
+mng_retcode MNG_DECL mng_putchunk_jhdr (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iColortype,
+ mng_uint8 iImagesampledepth,
+ mng_uint8 iImagecompression,
+ mng_uint8 iImageinterlace,
+ mng_uint8 iAlphasampledepth,
+ mng_uint8 iAlphacompression,
+ mng_uint8 iAlphafilter,
+ mng_uint8 iAlphainterlace)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_JHDR, init_jhdr, free_jhdr, read_jhdr, write_jhdr, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JHDR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* create the chunk */
+ iRetcode = init_jhdr (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_jhdrp)pChunk)->iWidth = iWidth;
+ ((mng_jhdrp)pChunk)->iHeight = iHeight;
+ ((mng_jhdrp)pChunk)->iColortype = iColortype;
+ ((mng_jhdrp)pChunk)->iImagesampledepth = iImagesampledepth;
+ ((mng_jhdrp)pChunk)->iImagecompression = iImagecompression;
+ ((mng_jhdrp)pChunk)->iImageinterlace = iImageinterlace;
+ ((mng_jhdrp)pChunk)->iAlphasampledepth = iAlphasampledepth;
+ ((mng_jhdrp)pChunk)->iAlphacompression = iAlphacompression;
+ ((mng_jhdrp)pChunk)->iAlphafilter = iAlphafilter;
+ ((mng_jhdrp)pChunk)->iAlphainterlace = iAlphainterlace;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+/* B004 */
+#endif /* MNG_INCLUDE_JNG */
+/* B004 */
+/* ************************************************************************** */
+/* B004 */
+#ifdef MNG_INCLUDE_JNG
+/* B004 */
+mng_retcode MNG_DECL mng_putchunk_jdat (mng_handle hHandle,
+ mng_uint32 iRawlen,
+ mng_ptr pRawdata)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_JDAT, init_jdat, free_jdat, read_jdat, write_jdat, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JDAT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR or JHDR first! */
+ if ((pData->iFirstchunkadded != MNG_UINT_MHDR) &&
+ (pData->iFirstchunkadded != MNG_UINT_JHDR) )
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_jdat (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_jdatp)pChunk)->iDatasize = iRawlen;
+
+ if (iRawlen)
+ {
+ MNG_ALLOC (pData, ((mng_jdatp)pChunk)->pData, iRawlen)
+ MNG_COPY (((mng_jdatp)pChunk)->pData, pRawdata, iRawlen)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+/* B004 */
+#endif /* MNG_INCLUDE_JNG */
+/* B004 */
+/* ************************************************************************** */
+/* B004 */
+#ifdef MNG_INCLUDE_JNG
+/* B004 */
+mng_retcode MNG_DECL mng_putchunk_jsep (mng_handle hHandle)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_JSEP, init_jsep, free_jsep, read_jsep, write_jsep, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JSEP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR or JHDR first! */
+ if ((pData->iFirstchunkadded != MNG_UINT_MHDR) &&
+ (pData->iFirstchunkadded != MNG_UINT_JHDR) )
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_jsep (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_JSEP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+/* B004 */
+#endif /* MNG_INCLUDE_JNG */
+/* B004 */
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_dhdr (mng_handle hHandle,
+ mng_uint16 iObjectid,
+ mng_uint8 iImagetype,
+ mng_uint8 iDeltatype,
+ mng_uint32 iBlockwidth,
+ mng_uint32 iBlockheight,
+ mng_uint32 iBlockx,
+ mng_uint32 iBlocky)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_DHDR, init_dhdr, free_dhdr, read_dhdr, write_dhdr, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DHDR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_dhdr (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_dhdrp)pChunk)->iObjectid = iObjectid;
+ ((mng_dhdrp)pChunk)->iImagetype = iImagetype;
+ ((mng_dhdrp)pChunk)->iDeltatype = iDeltatype;
+ ((mng_dhdrp)pChunk)->iBlockwidth = iBlockwidth;
+ ((mng_dhdrp)pChunk)->iBlockheight = iBlockheight;
+ ((mng_dhdrp)pChunk)->iBlockx = iBlockx;
+ ((mng_dhdrp)pChunk)->iBlocky = iBlocky;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_prom (mng_handle hHandle,
+ mng_uint8 iColortype,
+ mng_uint8 iSampledepth,
+ mng_uint8 iFilltype)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_PROM, init_prom, free_prom, read_prom, write_prom, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PROM, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_prom (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_promp)pChunk)->iColortype = iColortype;
+ ((mng_promp)pChunk)->iSampledepth = iSampledepth;
+ ((mng_promp)pChunk)->iFilltype = iFilltype;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PROM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_ipng (mng_handle hHandle)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_IPNG, init_ipng, free_ipng, read_ipng, write_ipng, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IPNG, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_ipng (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IPNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_pplt (mng_handle hHandle,
+ mng_uint32 iCount)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_PPLT, init_pplt, free_pplt, read_pplt, write_pplt, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PPLT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_pplt (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_ppltp)pChunk)->iCount = iCount;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_pplt_entry (mng_handle hHandle,
+ mng_uint32 iEntry,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_uint16 iAlpha,
+ mng_bool bUsed)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_pplt_entryp pEntry;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PPLT_ENTRY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+
+ pChunk = pData->pLastchunk; /* last one must have been PPLT ! */
+
+ if (((mng_chunk_headerp)pChunk)->iChunkname != MNG_UINT_PPLT)
+ MNG_ERROR (pData, MNG_NOCORRCHUNK)
+
+ /* index out of bounds ? */
+ if (iEntry >= ((mng_ppltp)pChunk)->iCount)
+ MNG_ERROR (pData, MNG_INVALIDENTRYIX)
+ /* address proper entry */
+ pEntry = (mng_pplt_entryp)(((mng_ppltp)pChunk)->aEntries) + iEntry;
+
+ pEntry->iRed = (mng_uint8)iRed; /* fill the entry */
+ pEntry->iGreen = (mng_uint8)iGreen;
+ pEntry->iBlue = (mng_uint8)iBlue;
+ pEntry->iAlpha = (mng_uint8)iAlpha;
+ pEntry->bUsed = bUsed;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_PPLT_ENTRY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_ijng (mng_handle hHandle)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_IJNG, init_ijng, free_ijng, read_ijng, write_ijng, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IJNG, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_ijng (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_IJNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_drop (mng_handle hHandle,
+ mng_uint32 iCount,
+ mng_chunkidp pChunknames)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_DROP, init_drop, free_drop, read_drop, write_drop, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DROP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_drop (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_dropp)pChunk)->iCount = iCount;
+
+ if (iCount)
+ {
+ mng_uint32 iSize = iCount * sizeof (mng_chunkid);
+
+ MNG_ALLOC (pData, ((mng_dropp)pChunk)->pChunknames, iSize)
+ MNG_COPY (((mng_dropp)pChunk)->pChunknames, pChunknames, iSize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DROP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_dbyk (mng_handle hHandle,
+ mng_chunkid iChunkname,
+ mng_uint8 iPolarity,
+ mng_uint32 iKeywordssize,
+ mng_pchar zKeywords)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_DBYK, init_dbyk, free_dbyk, read_dbyk, write_dbyk, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DBYK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_dbyk (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_dbykp)pChunk)->iChunkname = iChunkname;
+ ((mng_dbykp)pChunk)->iPolarity = iPolarity;
+ ((mng_dbykp)pChunk)->iKeywordssize = iKeywordssize;
+
+ if (iKeywordssize)
+ {
+ MNG_ALLOC (pData, ((mng_dbykp)pChunk)->zKeywords, iKeywordssize + 1)
+ MNG_COPY (((mng_dbykp)pChunk)->zKeywords, zKeywords, iKeywordssize)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_DBYK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_ordr (mng_handle hHandle,
+ mng_uint32 iCount)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_ORDR, init_ordr, free_ordr, read_ordr, write_ordr, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ORDR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_ordr (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_ordrp)pChunk)->iCount = iCount;
+
+ if (iCount)
+ MNG_ALLOC (pData, ((mng_ordrp)pChunk)->pEntries, iCount * sizeof (mng_ordr_entry))
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ORDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_ordr_entry (mng_handle hHandle,
+ mng_uint32 iEntry,
+ mng_chunkid iChunkname,
+ mng_uint8 iOrdertype)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_ordr_entryp pEntry;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ORDR_ENTRY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+
+ pChunk = pData->pLastchunk; /* last one must have been ORDR ! */
+
+ if (((mng_chunk_headerp)pChunk)->iChunkname != MNG_UINT_ORDR)
+ MNG_ERROR (pData, MNG_NOCORRCHUNK)
+ /* index out of bounds ? */
+ if (iEntry >= ((mng_ordrp)pChunk)->iCount)
+ MNG_ERROR (pData, MNG_INVALIDENTRYIX)
+ /* address proper entry */
+ pEntry = ((mng_ordrp)pChunk)->pEntries + iEntry;
+
+ pEntry->iChunkname = iChunkname; /* fill the entry */
+ pEntry->iOrdertype = iOrdertype;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_ORDR_ENTRY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_magn (mng_handle hHandle,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint16 iMethodX,
+ mng_uint16 iMX,
+ mng_uint16 iMY,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint16 iMT,
+ mng_uint16 iMB,
+ mng_uint16 iMethodY)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_MAGN, init_magn, free_magn, read_magn, write_magn, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MAGN, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a MHDR first! */
+ if (pData->iFirstchunkadded != MNG_UINT_MHDR)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_magn (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_magnp)pChunk)->iFirstid = iFirstid;
+ ((mng_magnp)pChunk)->iLastid = iLastid;
+ ((mng_magnp)pChunk)->iMethodX = iMethodX;
+ ((mng_magnp)pChunk)->iMX = iMX;
+ ((mng_magnp)pChunk)->iMY = iMY;
+ ((mng_magnp)pChunk)->iML = iML;
+ ((mng_magnp)pChunk)->iMR = iMR;
+ ((mng_magnp)pChunk)->iMT = iMT;
+ ((mng_magnp)pChunk)->iMB = iMB;
+ ((mng_magnp)pChunk)->iMethodY = iMethodY;
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_MAGN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putchunk_unknown (mng_handle hHandle,
+ mng_chunkid iChunkname,
+ mng_uint32 iRawlen,
+ mng_ptr pRawdata)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_chunk_header sChunkheader =
+ {MNG_UINT_HUH, init_unknown, free_unknown, read_unknown, write_unknown, 0, 0};
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_UNKNOWN, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must have had a header first! */
+ if (pData->iFirstchunkadded == 0)
+ MNG_ERROR (pData, MNG_NOHEADER)
+ /* create the chunk */
+ iRetcode = init_unknown (pData, &sChunkheader, &pChunk);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fill the chunk */
+ ((mng_unknown_chunkp)pChunk)->sHeader.iChunkname = iChunkname;
+ ((mng_unknown_chunkp)pChunk)->iDatasize = iRawlen;
+
+ if (iRawlen)
+ {
+ MNG_ALLOC (pData, ((mng_unknown_chunkp)pChunk)->pData, iRawlen)
+ MNG_COPY (((mng_unknown_chunkp)pChunk)->pData, pRawdata, iRawlen)
+ }
+
+ add_chunk (pData, pChunk); /* add it to the list */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTCHUNK_UNKNOWN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* B004 */
+#endif /* MNG_INCLUDE_WRITE_PROCS */
+/* B004 */
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getimgdata_seq (mng_handle hHandle,
+ mng_uint32 iSeqnr,
+ mng_uint32 iCanvasstyle,
+ mng_getcanvasline fGetcanvasline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_SEQ, MNG_LC_START)
+#endif
+
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_SEQ, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getimgdata_chunkseq (mng_handle hHandle,
+ mng_uint32 iSeqnr,
+ mng_uint32 iCanvasstyle,
+ mng_getcanvasline fGetcanvasline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_CHUNKSEQ, MNG_LC_START)
+#endif
+
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_CHUNKSEQ, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getimgdata_chunk (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_uint32 iCanvasstyle,
+ mng_getcanvasline fGetcanvasline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_CHUNK, MNG_LC_START)
+#endif
+
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETIMGDATA_CHUNK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+/* B004 */
+#ifdef MNG_INCLUDE_WRITE_PROCS
+/* B004 */
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putimgdata_ihdr (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iColortype,
+ mng_uint8 iBitdepth,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace,
+ mng_uint32 iCanvasstyle,
+ mng_getcanvasline fGetcanvasline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTIMGDATA_IHDR, MNG_LC_START)
+#endif
+
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTIMGDATA_IHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_putimgdata_jhdr (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iColortype,
+ mng_uint8 iBitdepth,
+ mng_uint8 iCompression,
+ mng_uint8 iInterlace,
+ mng_uint8 iAlphaBitdepth,
+ mng_uint8 iAlphaCompression,
+ mng_uint8 iAlphaFilter,
+ mng_uint8 iAlphaInterlace,
+ mng_uint32 iCanvasstyle,
+ mng_getcanvasline fGetcanvasline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTIMGDATA_JHDR, MNG_LC_START)
+#endif
+
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_PUTIMGDATA_JHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_updatemngheader (mng_handle hHandle,
+ mng_uint32 iFramecount,
+ mng_uint32 iLayercount,
+ mng_uint32 iPlaytime)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_UPDATEMNGHEADER, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must be a MNG animation! */
+ if ((pData->eImagetype != mng_it_mng) || (pData->iFirstchunkadded != MNG_UINT_MHDR))
+ MNG_ERROR (pData, MNG_NOMHDR)
+
+ pChunk = pData->pFirstchunk; /* get the first chunk */
+ /* and update the variables */
+ ((mng_mhdrp)pChunk)->iFramecount = iFramecount;
+ ((mng_mhdrp)pChunk)->iLayercount = iLayercount;
+ ((mng_mhdrp)pChunk)->iPlaytime = iPlaytime;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_UPDATEMNGHEADER, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_updatemngsimplicity (mng_handle hHandle,
+ mng_uint32 iSimplicity)
+{
+ mng_datap pData;
+ mng_chunkp pChunk;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_UPDATEMNGSIMPLICITY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = (mng_datap)hHandle; /* and make it addressable */
+
+ if (!pData->bCreating) /* aren't we creating a new file ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ /* must be a MNG animation! */
+ if ((pData->eImagetype != mng_it_mng) || (pData->iFirstchunkadded != MNG_UINT_MHDR))
+ MNG_ERROR (pData, MNG_NOMHDR)
+
+ pChunk = pData->pFirstchunk; /* get the first chunk */
+ /* and update the variable */
+ ((mng_mhdrp)pChunk)->iSimplicity = iSimplicity;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_UPDATEMNGSIMPLICITY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* B004 */
+#endif /* MNG_INCLUDE_WRITE_PROCS */
+/* B004 */
+/* ************************************************************************** */
+
+#endif /* MNG_ACCESS_CHUNKS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunks.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunks.h
new file mode 100644
index 0000000..81d4170
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_chunks.h
@@ -0,0 +1,759 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_chunks.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Chunk structures (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of known chunk structures * */
+/* * * */
+/* * changes : 0.5.1 - 05/04/2000 - G.Juyn * */
+/* * - put in some extra comments * */
+/* * 0.5.1 - 05/06/2000 - G.Juyn * */
+/* * - fixed tqlayout for sBIT, PPLT * */
+/* * 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed write callback definition * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - fixed tqlayout for PPLT again (missed deltatype ?!?) * */
+/* * * */
+/* * 0.5.2 - 05/31/2000 - G.Juyn * */
+/* * - removed useless definition (contributed by Tim Rowley) * */
+/* * 0.5.2 - 06/03/2000 - G.Juyn * */
+/* * - fixed makeup for Linux gcc compile * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/10/2000 - G.Juyn * */
+/* * - fixed DEFI behavior * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added JDAA chunk * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_chunks_h_
+#define _libmng_chunks_h_
+
+/* ************************************************************************** */
+
+#ifdef MNG_SWAP_ENDIAN
+#define PNG_SIG 0x474e5089L
+#define JNG_SIG 0x474e4a8bL
+#define MNG_SIG 0x474e4d8aL
+#define POST_SIG 0x0a1a0a0dL
+#else
+#define PNG_SIG 0x89504e47L
+#define JNG_SIG 0x8b4a4e47L
+#define MNG_SIG 0x8a4d4e47L
+#define POST_SIG 0x0d0a1a0aL
+#endif
+
+/* ************************************************************************** */
+
+typedef mng_retcode (*mng_createchunk) (mng_datap pData,
+ mng_chunkp pHeader,
+ mng_chunkp* ppChunk);
+
+typedef mng_retcode (*mng_cleanupchunk) (mng_datap pData,
+ mng_chunkp pHeader);
+
+typedef mng_retcode (*mng_readchunk) (mng_datap pData,
+ mng_chunkp pHeader,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata,
+ mng_chunkp* pChunk);
+
+typedef mng_retcode (*mng_writechunk) (mng_datap pData,
+ mng_chunkp pChunk);
+
+/* ************************************************************************** */
+
+typedef struct { /* generic header */
+ mng_chunkid iChunkname;
+ mng_createchunk fCreate;
+ mng_cleanupchunk fCleanup;
+ mng_readchunk fRead;
+ mng_writechunk fWrite;
+ mng_chunkp pNext; /* for double-linked list */
+ mng_chunkp pPrev;
+ } mng_chunk_header;
+typedef mng_chunk_header * mng_chunk_headerp;
+
+/* ************************************************************************** */
+
+typedef struct { /* IHDR */
+ mng_chunk_header sHeader;
+ mng_uint32 iWidth;
+ mng_uint32 iHeight;
+ mng_uint8 iBitdepth;
+ mng_uint8 iColortype;
+ mng_uint8 iCompression;
+ mng_uint8 iFilter;
+ mng_uint8 iInterlace;
+ } mng_ihdr;
+typedef mng_ihdr * mng_ihdrp;
+
+/* ************************************************************************** */
+
+typedef struct { /* PLTE */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint32 iEntrycount;
+ mng_rgbpaltab aEntries;
+ } mng_plte;
+typedef mng_plte * mng_pltep;
+
+/* ************************************************************************** */
+
+typedef struct { /* IDAT */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint32 iDatasize;
+ mng_ptr pData;
+ } mng_idat;
+typedef mng_idat * mng_idatp;
+
+/* ************************************************************************** */
+
+typedef struct { /* IEND */
+ mng_chunk_header sHeader;
+ } mng_iend;
+typedef mng_iend * mng_iendp;
+
+/* ************************************************************************** */
+
+typedef struct { /* tRNS */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_bool bGlobal;
+ mng_uint8 iType; /* colortype (0,2,3) */
+ mng_uint32 iCount;
+ mng_uint8arr aEntries;
+ mng_uint16 iGray;
+ mng_uint16 iRed;
+ mng_uint16 iGreen;
+ mng_uint16 iBlue;
+ mng_uint32 iRawlen;
+ mng_uint8arr aRawdata;
+ } mng_trns;
+typedef mng_trns * mng_trnsp;
+
+/* ************************************************************************** */
+
+typedef struct { /* gAMA */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint32 iGamma;
+ } mng_gama;
+typedef mng_gama * mng_gamap;
+
+/* ************************************************************************** */
+
+typedef struct { /* cHRM */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint32 iWhitepointx;
+ mng_uint32 iWhitepointy;
+ mng_uint32 iRedx;
+ mng_uint32 iRedy;
+ mng_uint32 iGreenx;
+ mng_uint32 iGreeny;
+ mng_uint32 iBluex;
+ mng_uint32 iBluey;
+ } mng_chrm;
+typedef mng_chrm * mng_chrmp;
+
+/* ************************************************************************** */
+
+typedef struct { /* sRGB */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint8 iRenderingintent;
+ } mng_srgb;
+typedef mng_srgb * mng_srgbp;
+
+/* ************************************************************************** */
+
+typedef struct { /* iCCP */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint32 iNamesize;
+ mng_pchar zName;
+ mng_uint8 iCompression;
+ mng_uint32 iProfilesize;
+ mng_ptr pProfile;
+ } mng_iccp;
+typedef mng_iccp * mng_iccpp;
+
+/* ************************************************************************** */
+
+typedef struct { /* tEXt */
+ mng_chunk_header sHeader;
+ mng_uint32 iKeywordsize;
+ mng_pchar zKeyword;
+ mng_uint32 iTextsize;
+ mng_pchar zText;
+ } mng_text;
+typedef mng_text * mng_textp;
+
+/* ************************************************************************** */
+
+typedef struct { /* zTXt */
+ mng_chunk_header sHeader;
+ mng_uint32 iKeywordsize;
+ mng_pchar zKeyword;
+ mng_uint8 iCompression;
+ mng_uint32 iTextsize;
+ mng_pchar zText;
+ } mng_ztxt;
+typedef mng_ztxt * mng_ztxtp;
+
+/* ************************************************************************** */
+
+typedef struct { /* iTXt */
+ mng_chunk_header sHeader;
+ mng_uint32 iKeywordsize;
+ mng_pchar zKeyword;
+ mng_uint8 iCompressionflag;
+ mng_uint8 iCompressionmethod;
+ mng_uint32 iLanguagesize;
+ mng_pchar zLanguage;
+ mng_uint32 iTranslationsize;
+ mng_pchar zTranslation;
+ mng_uint32 iTextsize;
+ mng_pchar zText;
+ } mng_itxt;
+typedef mng_itxt * mng_itxtp;
+
+/* ************************************************************************** */
+
+typedef struct { /* bKGD */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint8 iType; /* 3=indexed, 0=gray, 2=rgb */
+ mng_uint8 iIndex;
+ mng_uint16 iGray;
+ mng_uint16 iRed;
+ mng_uint16 iGreen;
+ mng_uint16 iBlue;
+ } mng_bkgd;
+typedef mng_bkgd * mng_bkgdp;
+
+/* ************************************************************************** */
+
+typedef struct { /* pHYs */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint32 iSizex;
+ mng_uint32 iSizey;
+ mng_uint8 iUnit;
+ } mng_phys;
+typedef mng_phys * mng_physp;
+
+/* ************************************************************************** */
+
+typedef struct { /* sBIT */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint8 iType; /* colortype (0,2,3,4,6,10,12,14,16) */
+ mng_uint8arr4 aBits;
+ } mng_sbit;
+typedef mng_sbit * mng_sbitp;
+
+/* ************************************************************************** */
+
+typedef struct { /* sPLT */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint32 iNamesize;
+ mng_pchar zName;
+ mng_uint8 iSampledepth;
+ mng_uint32 iEntrycount;
+ mng_ptr pEntries;
+ } mng_splt;
+typedef mng_splt * mng_spltp;
+
+/* ************************************************************************** */
+
+typedef struct { /* hIST */
+ mng_chunk_header sHeader;
+ mng_uint32 iEntrycount;
+ mng_uint16arr aEntries;
+ } mng_hist;
+typedef mng_hist * mng_histp;
+
+/* ************************************************************************** */
+
+typedef struct { /* tIME */
+ mng_chunk_header sHeader;
+ mng_uint16 iYear;
+ mng_uint8 iMonth;
+ mng_uint8 iDay;
+ mng_uint8 iHour;
+ mng_uint8 iMinute;
+ mng_uint8 iSecond;
+ } mng_time;
+typedef mng_time * mng_timep;
+
+/* ************************************************************************** */
+
+typedef struct { /* MHDR */
+ mng_chunk_header sHeader;
+ mng_uint32 iWidth;
+ mng_uint32 iHeight;
+ mng_uint32 iTicks;
+ mng_uint32 iLayercount;
+ mng_uint32 iFramecount;
+ mng_uint32 iPlaytime;
+ mng_uint32 iSimplicity;
+ } mng_mhdr;
+typedef mng_mhdr * mng_mhdrp;
+
+/* ************************************************************************** */
+
+typedef struct { /* MEND */
+ mng_chunk_header sHeader;
+ } mng_mend;
+typedef mng_mend * mng_mendp;
+
+/* ************************************************************************** */
+
+typedef struct { /* LOOP */
+ mng_chunk_header sHeader;
+ mng_uint8 iLevel;
+ mng_uint32 iRepeat;
+ mng_uint8 iTermination;
+ mng_uint32 iItermin;
+ mng_uint32 iItermax;
+ mng_uint32 iCount;
+ mng_uint32p pSignals;
+ } mng_loop;
+typedef mng_loop * mng_loopp;
+
+/* ************************************************************************** */
+
+typedef struct { /* ENDL */
+ mng_chunk_header sHeader;
+ mng_uint8 iLevel;
+ } mng_endl;
+typedef mng_endl * mng_endlp;
+
+/* ************************************************************************** */
+
+typedef struct { /* DEFI */
+ mng_chunk_header sHeader;
+ mng_uint16 iObjectid;
+ mng_bool bHasdonotshow;
+ mng_uint8 iDonotshow;
+ mng_bool bHasconcrete;
+ mng_uint8 iConcrete;
+ mng_bool bHasloca;
+ mng_int32 iXlocation;
+ mng_int32 iYlocation;
+ mng_bool bHasclip;
+ mng_int32 iLeftcb;
+ mng_int32 iRightcb;
+ mng_int32 iTopcb;
+ mng_int32 iBottomcb;
+ } mng_defi;
+typedef mng_defi * mng_defip;
+
+/* ************************************************************************** */
+
+typedef struct { /* BASI */
+ mng_chunk_header sHeader;
+ mng_uint32 iWidth;
+ mng_uint32 iHeight;
+ mng_uint8 iBitdepth;
+ mng_uint8 iColortype;
+ mng_uint8 iCompression;
+ mng_uint8 iFilter;
+ mng_uint8 iInterlace;
+ mng_uint16 iRed;
+ mng_uint16 iGreen;
+ mng_uint16 iBlue;
+ mng_uint16 iAlpha;
+ mng_uint8 iViewable;
+ } mng_basi;
+typedef mng_basi * mng_basip;
+
+/* ************************************************************************** */
+
+typedef struct { /* CLON */
+ mng_chunk_header sHeader;
+ mng_uint16 iSourceid;
+ mng_uint16 iCloneid;
+ mng_uint8 iClonetype;
+ mng_uint8 iDonotshow;
+ mng_uint8 iConcrete;
+ mng_bool bHasloca;
+ mng_uint8 iLocationtype;
+ mng_int32 iLocationx;
+ mng_int32 iLocationy;
+ } mng_clon;
+typedef mng_clon * mng_clonp;
+
+/* ************************************************************************** */
+
+typedef struct { /* PAST source */
+ mng_uint16 iSourceid;
+ mng_uint8 iComposition;
+ mng_uint8 iOrientation;
+ mng_uint8 iOffsettype;
+ mng_int32 iOffsetx;
+ mng_int32 iOffsety;
+ mng_uint8 iBoundarytype;
+ mng_int32 iBoundaryl;
+ mng_int32 iBoundaryr;
+ mng_int32 iBoundaryt;
+ mng_int32 iBoundaryb;
+ } mng_past_source;
+typedef mng_past_source * mng_past_sourcep;
+
+typedef struct { /* PAST */
+ mng_chunk_header sHeader;
+ mng_uint16 iDestid;
+ mng_uint8 iTargettype;
+ mng_int32 iTargetx;
+ mng_int32 iTargety;
+ mng_uint32 iCount;
+ mng_past_sourcep pSources;
+ } mng_past;
+typedef mng_past * mng_pastp;
+
+/* ************************************************************************** */
+
+typedef struct { /* DISC */
+ mng_chunk_header sHeader;
+ mng_uint32 iCount;
+ mng_uint16p pObjectids;
+ } mng_disc;
+typedef mng_disc * mng_discp;
+
+/* ************************************************************************** */
+
+typedef struct { /* BACK */
+ mng_chunk_header sHeader;
+ mng_uint16 iRed;
+ mng_uint16 iGreen;
+ mng_uint16 iBlue;
+ mng_uint8 iMandatory;
+ mng_uint16 iImageid;
+ mng_uint8 iTile;
+ } mng_back;
+typedef mng_back * mng_backp;
+
+/* ************************************************************************** */
+
+typedef struct { /* FRAM */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint8 iMode;
+ mng_uint32 iNamesize;
+ mng_pchar zName;
+ mng_uint8 iChangedelay;
+ mng_uint8 iChangetimeout;
+ mng_uint8 iChangeclipping;
+ mng_uint8 iChangesyncid;
+ mng_uint32 iDelay;
+ mng_uint32 iTimeout;
+ mng_uint8 iBoundarytype;
+ mng_int32 iBoundaryl;
+ mng_int32 iBoundaryr;
+ mng_int32 iBoundaryt;
+ mng_int32 iBoundaryb;
+ mng_uint32 iCount;
+ mng_uint32p pSyncids;
+ } mng_fram;
+typedef mng_fram * mng_framp;
+
+/* ************************************************************************** */
+
+typedef struct { /* MOVE */
+ mng_chunk_header sHeader;
+ mng_uint16 iFirstid;
+ mng_uint16 iLastid;
+ mng_uint8 iMovetype;
+ mng_int32 iMovex;
+ mng_int32 iMovey;
+ } mng_move;
+typedef mng_move * mng_movep;
+
+/* ************************************************************************** */
+
+typedef struct { /* CLIP */
+ mng_chunk_header sHeader;
+ mng_uint16 iFirstid;
+ mng_uint16 iLastid;
+ mng_uint8 iCliptype;
+ mng_int32 iClipl;
+ mng_int32 iClipr;
+ mng_int32 iClipt;
+ mng_int32 iClipb;
+ } mng_clip;
+typedef mng_clip * mng_clipp;
+
+/* ************************************************************************** */
+
+typedef struct { /* SHOW */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint16 iFirstid;
+ mng_uint16 iLastid;
+ mng_uint8 iMode;
+ } mng_show;
+typedef mng_show * mng_showp;
+
+/* ************************************************************************** */
+
+typedef struct { /* TERM */
+ mng_chunk_header sHeader;
+ mng_uint8 iTermaction;
+ mng_uint8 iIteraction;
+ mng_uint32 iDelay;
+ mng_uint32 iItermax;
+ } mng_term;
+typedef mng_term * mng_termp;
+
+/* ************************************************************************** */
+
+typedef struct { /* SAVE entry */
+ mng_uint8 iEntrytype;
+ mng_uint32arr2 iOffset; /* 0=MSI, 1=LSI */
+ mng_uint32arr2 iStarttime; /* 0=MSI, 1=LSI */
+ mng_uint32 iLayernr;
+ mng_uint32 iFramenr;
+ mng_uint32 iNamesize;
+ mng_pchar zName;
+ } mng_save_entry;
+typedef mng_save_entry * mng_save_entryp;
+
+typedef struct { /* SAVE */
+ mng_chunk_header sHeader;
+ mng_bool bEmpty;
+ mng_uint8 iOffsettype;
+ mng_uint32 iCount;
+ mng_save_entryp pEntries;
+ } mng_save;
+typedef mng_save * mng_savep;
+
+/* ************************************************************************** */
+
+typedef struct { /* SEEK */
+ mng_chunk_header sHeader;
+ mng_uint32 iNamesize;
+ mng_pchar zName;
+ } mng_seek;
+typedef mng_seek * mng_seekp;
+
+/* ************************************************************************** */
+
+typedef struct { /* eXPI */
+ mng_chunk_header sHeader;
+ mng_uint16 iSnapshotid;
+ mng_uint32 iNamesize;
+ mng_pchar zName;
+ } mng_expi;
+typedef mng_expi * mng_expip;
+
+/* ************************************************************************** */
+
+typedef struct { /* fPRI */
+ mng_chunk_header sHeader;
+ mng_uint8 iDeltatype;
+ mng_uint8 iPriority;
+ } mng_fpri;
+typedef mng_fpri * mng_fprip;
+
+/* ************************************************************************** */
+
+typedef struct { /* nEED */
+ mng_chunk_header sHeader;
+ mng_uint32 iKeywordssize;
+ mng_pchar zKeywords;
+ } mng_need;
+typedef mng_need * mng_needp;
+
+/* ************************************************************************** */
+
+typedef mng_phys mng_phyg; /* pHYg */
+typedef mng_phyg * mng_phygp;
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+
+typedef struct { /* JHDR */
+ mng_chunk_header sHeader;
+ mng_uint32 iWidth;
+ mng_uint32 iHeight;
+ mng_uint8 iColortype;
+ mng_uint8 iImagesampledepth;
+ mng_uint8 iImagecompression;
+ mng_uint8 iImageinterlace;
+ mng_uint8 iAlphasampledepth;
+ mng_uint8 iAlphacompression;
+ mng_uint8 iAlphafilter;
+ mng_uint8 iAlphainterlace;
+ } mng_jhdr;
+typedef mng_jhdr * mng_jhdrp;
+
+/* ************************************************************************** */
+
+typedef mng_idat mng_jdaa; /* JDAA */
+typedef mng_jdaa * mng_jdaap;
+
+/* ************************************************************************** */
+
+typedef mng_idat mng_jdat; /* JDAT */
+typedef mng_jdat * mng_jdatp;
+
+/* ************************************************************************** */
+
+typedef struct { /* JSEP */
+ mng_chunk_header sHeader;
+ } mng_jsep;
+typedef mng_jsep * mng_jsepp;
+
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+typedef struct { /* DHDR */
+ mng_chunk_header sHeader;
+ mng_uint16 iObjectid;
+ mng_uint8 iImagetype;
+ mng_uint8 iDeltatype;
+ mng_uint32 iBlockwidth;
+ mng_uint32 iBlockheight;
+ mng_uint32 iBlockx;
+ mng_uint32 iBlocky;
+ } mng_dhdr;
+typedef mng_dhdr * mng_dhdrp;
+
+/* ************************************************************************** */
+
+typedef struct { /* PROM */
+ mng_chunk_header sHeader;
+ mng_uint8 iColortype;
+ mng_uint8 iSampledepth;
+ mng_uint8 iFilltype;
+ } mng_prom;
+typedef mng_prom * mng_promp;
+
+/* ************************************************************************** */
+
+typedef struct { /* IPNG */
+ mng_chunk_header sHeader;
+ } mng_ipng;
+typedef mng_ipng *mng_ipngp;
+
+/* ************************************************************************** */
+
+typedef struct { /* PPLT entry */
+ mng_uint8 iRed;
+ mng_uint8 iGreen;
+ mng_uint8 iBlue;
+ mng_uint8 iAlpha;
+ mng_bool bUsed;
+ } mng_pplt_entry;
+typedef mng_pplt_entry * mng_pplt_entryp;
+
+typedef struct { /* PPLT */
+ mng_chunk_header sHeader;
+ mng_uint8 iDeltatype;
+ mng_uint32 iCount;
+ mng_pplt_entry aEntries [256];
+ } mng_pplt;
+typedef mng_pplt * mng_ppltp;
+
+/* ************************************************************************** */
+
+typedef struct { /* IJNG */
+ mng_chunk_header sHeader;
+ } mng_ijng;
+typedef mng_ijng *mng_ijngp;
+
+/* ************************************************************************** */
+
+typedef struct { /* DROP */
+ mng_chunk_header sHeader;
+ mng_uint32 iCount;
+ mng_chunkidp pChunknames;
+ } mng_drop;
+typedef mng_drop * mng_dropp;
+
+/* ************************************************************************** */
+
+typedef struct { /* DBYK */
+ mng_chunk_header sHeader;
+ mng_chunkid iChunkname;
+ mng_uint8 iPolarity;
+ mng_uint32 iKeywordssize;
+ mng_pchar zKeywords;
+ } mng_dbyk;
+typedef mng_dbyk * mng_dbykp;
+
+/* ************************************************************************** */
+
+typedef struct { /* ORDR entry */
+ mng_chunkid iChunkname;
+ mng_uint8 iOrdertype;
+ } mng_ordr_entry;
+typedef mng_ordr_entry * mng_ordr_entryp;
+
+typedef struct mng_ordr_struct { /* ORDR */
+ mng_chunk_header sHeader;
+ mng_uint32 iCount;
+ mng_ordr_entryp pEntries;
+ } mng_ordr;
+typedef mng_ordr * mng_ordrp;
+
+/* ************************************************************************** */
+
+typedef struct { /* MAGN */
+ mng_chunk_header sHeader;
+ mng_uint16 iFirstid;
+ mng_uint16 iLastid;
+ mng_uint16 iMethodX;
+ mng_uint16 iMX;
+ mng_uint16 iMY;
+ mng_uint16 iML;
+ mng_uint16 iMR;
+ mng_uint16 iMT;
+ mng_uint16 iMB;
+ mng_uint16 iMethodY;
+ } mng_magn;
+typedef mng_magn * mng_magnp;
+
+/* ************************************************************************** */
+
+typedef struct { /* unknown chunk */
+ mng_chunk_header sHeader;
+ mng_uint32 iDatasize;
+ mng_ptr pData;
+ } mng_unknown_chunk;
+typedef mng_unknown_chunk * mng_unknown_chunkp;
+
+/* ************************************************************************** */
+
+#endif /* _libmng_chunks_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_cms.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_cms.c
new file mode 100644
index 0000000..d072e37
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_cms.c
@@ -0,0 +1,928 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_cms.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.1 * */
+/* * * */
+/* * purpose : color management routines (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the color management routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/01/2000 - G.Juyn * */
+/* * - B001(105795) - fixed a typo and misconception about * */
+/* * freeing allocated gamma-table. (reported by Marti Maria) * */
+/* * 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/09/2000 - G.Juyn * */
+/* * - filled application-based color-management routines * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added creatememprofile * */
+/* * - added callback error-reporting support * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * * */
+/* * 0.5.2 - 06/10/2000 - G.Juyn * */
+/* * - fixed some compilation-warnings (contrib Jason Morris) * */
+/* * * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - fixed problem with color-correction for stored images * */
+/* * 0.5.3 - 06/23/2000 - G.Juyn * */
+/* * - fixed problem with incorrect gamma-correction * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/31/2000 - G.Juyn * */
+/* * - fixed sRGB precedence for gamma_only corection * */
+/* * * */
+/* * 0.9.4 - 12/16/2000 - G.Juyn * */
+/* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
+/* * * */
+/* * 1.0.1 - 03/31/2001 - G.Juyn * */
+/* * - ignore gamma=0 (see png-list for more info) * */
+/* * 1.0.1 - 04/25/2001 - G.Juyn (reported by Gregg Kelly) * */
+/* * - fixed problem with cms profile being created multiple * */
+/* * times when both iCCP & cHRM/gAMA are present * */
+/* * 1.0.1 - 04/25/2001 - G.Juyn * */
+/* * - moved mng_clear_cms to libmng_cms * */
+/* * 1.0.1 - 05/02/2001 - G.Juyn * */
+/* * - added "default" sRGB generation (Thanks Marti!) * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_objects.h"
+#include "libmng_cms.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_DISPLAY_PROCS
+
+/* ************************************************************************** */
+/* * * */
+/* * Little CMS helper routines * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_LCMS
+
+#define MNG_CMS_FLAGS 0
+
+/* ************************************************************************** */
+
+void mnglcms_initlibrary ()
+{
+ cmsErrorAction (LCMS_ERROR_IGNORE); /* LCMS should ignore errors! */
+}
+
+/* ************************************************************************** */
+
+mng_cmsprof mnglcms_createfileprofile (mng_pchar zFilename)
+{
+ return cmsOpenProfileFromFile (zFilename, "r");
+}
+
+/* ************************************************************************** */
+
+mng_cmsprof mnglcms_creatememprofile (mng_uint32 iProfilesize,
+ mng_ptr pProfile)
+{
+ return cmsOpenProfileFromMem (pProfile, iProfilesize);
+}
+
+/* ************************************************************************** */
+
+mng_cmsprof mnglcms_createsrgbprofile (void)
+{
+ cmsCIExyY D65;
+ cmsCIExyYTRIPLE Rec709Primaries = {
+ {0.6400, 0.3300, 1.0},
+ {0.3000, 0.6000, 1.0},
+ {0.1500, 0.0600, 1.0}
+ };
+ LPGAMMATABLE Gamma24[3];
+ mng_cmsprof hsRGB;
+
+ cmsWhitePointFromTemp(6504, &D65);
+ Gamma24[0] = Gamma24[1] = Gamma24[2] = cmsBuildGamma(256, 2.4);
+ hsRGB = cmsCreateRGBProfile(&D65, &Rec709Primaries, Gamma24);
+ cmsFreeGamma(Gamma24[0]);
+
+ return hsRGB;
+}
+
+/* ************************************************************************** */
+
+void mnglcms_freeprofile (mng_cmsprof hProf)
+{
+ cmsCloseProfile (hProf);
+ return;
+}
+
+/* ************************************************************************** */
+
+void mnglcms_freetransform (mng_cmstrans hTrans)
+{
+/* B001 start */
+ cmsDeleteTransform (hTrans);
+/* B001 end */
+ return;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_clear_cms (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLEAR_CMS, MNG_LC_START)
+#endif
+
+ if (pData->hTrans) /* transformation still active ? */
+ mnglcms_freetransform (pData->hTrans);
+
+ pData->hTrans = 0;
+
+ if (pData->hProf1) /* file profile still active ? */
+ mnglcms_freeprofile (pData->hProf1);
+
+ pData->hProf1 = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLEAR_CMS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_LCMS */
+
+/* ************************************************************************** */
+/* * * */
+/* * Color-management initialization & correction routines * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_LCMS
+
+mng_retcode init_full_cms (mng_datap pData)
+{
+ mng_cmsprof hProf;
+ mng_cmstrans hTrans;
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_imagedatap pBuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_START)
+#endif
+
+ if (!pImage) /* no current object? then use object 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf; /* address the buffer */
+
+ if ((pBuf->bHasICCP) || (pData->bHasglobalICCP))
+ {
+ if (!pData->hProf2) /* output profile not defined ? */
+ { /* then assume sRGB !! */
+ pData->hProf2 = mnglcms_createsrgbprofile ();
+
+ if (!pData->hProf2) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+ }
+
+ if (pBuf->bHasICCP) /* generate a profile handle */
+ hProf = cmsOpenProfileFromMem (pBuf->pProfile, pBuf->iProfilesize);
+ else
+ hProf = cmsOpenProfileFromMem (pData->pGlobalProfile, pData->iGlobalProfilesize);
+
+ pData->hProf1 = hProf; /* save for future use */
+
+ if (!hProf) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+
+ if (pData->bIsRGBA16) /* 16-bit intermediates ? */
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
+ pData->hProf2, TYPE_RGBA_16_SE,
+ INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
+ else
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
+ pData->hProf2, TYPE_RGBA_8,
+ INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
+
+ pData->hTrans = hTrans; /* save for future use */
+
+ if (!hTrans) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+ else
+ if ((pBuf->bHasSRGB) || (pData->bHasglobalSRGB))
+ {
+ mng_uint8 iIntent;
+
+ if (pData->bIssRGB) /* sRGB system ? */
+ return MNG_NOERROR; /* no conversion required */
+
+ if (!pData->hProf3) /* sRGB profile not defined ? */
+ { /* then create it implicitly !! */
+ pData->hProf3 = mnglcms_createsrgbprofile ();
+
+ if (!pData->hProf3) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+ }
+
+ hProf = pData->hProf3; /* convert from sRGB profile */
+
+ if (pBuf->bHasSRGB) /* determine rendering intent */
+ iIntent = pBuf->iRenderingintent;
+ else
+ iIntent = pData->iGlobalRendintent;
+
+ if (pData->bIsRGBA16) /* 16-bit intermediates ? */
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
+ pData->hProf2, TYPE_RGBA_16_SE,
+ iIntent, MNG_CMS_FLAGS);
+ else
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
+ pData->hProf2, TYPE_RGBA_8,
+ iIntent, MNG_CMS_FLAGS);
+
+ pData->hTrans = hTrans; /* save for future use */
+
+ if (!hTrans) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+ else
+ if ( ((pBuf->bHasCHRM) || (pData->bHasglobalCHRM)) &&
+ ( ((pBuf->bHasGAMA) && (pBuf->iGamma > 0)) ||
+ ((pData->bHasglobalGAMA) && (pData->iGlobalGamma > 0)) ))
+ {
+ mng_CIExyY sWhitepoint;
+ mng_CIExyYTRIPLE sPrimaries;
+ mng_gammatabp pGammatable[3];
+ mng_float dGamma;
+
+ if (!pData->hProf2) /* output profile not defined ? */
+ { /* then assume sRGB !! */
+ pData->hProf2 = mnglcms_createsrgbprofile ();
+
+ if (!pData->hProf2) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+ }
+
+ if (pBuf->bHasCHRM) /* local cHRM ? */
+ {
+ sWhitepoint.x = (mng_float)pBuf->iWhitepointx / 100000;
+ sWhitepoint.y = (mng_float)pBuf->iWhitepointy / 100000;
+ sPrimaries.Red.x = (mng_float)pBuf->iPrimaryredx / 100000;
+ sPrimaries.Red.y = (mng_float)pBuf->iPrimaryredy / 100000;
+ sPrimaries.Green.x = (mng_float)pBuf->iPrimarygreenx / 100000;
+ sPrimaries.Green.y = (mng_float)pBuf->iPrimarygreeny / 100000;
+ sPrimaries.Blue.x = (mng_float)pBuf->iPrimarybluex / 100000;
+ sPrimaries.Blue.y = (mng_float)pBuf->iPrimarybluey / 100000;
+ }
+ else
+ {
+ sWhitepoint.x = (mng_float)pData->iGlobalWhitepointx / 100000;
+ sWhitepoint.y = (mng_float)pData->iGlobalWhitepointy / 100000;
+ sPrimaries.Red.x = (mng_float)pData->iGlobalPrimaryredx / 100000;
+ sPrimaries.Red.y = (mng_float)pData->iGlobalPrimaryredy / 100000;
+ sPrimaries.Green.x = (mng_float)pData->iGlobalPrimarygreenx / 100000;
+ sPrimaries.Green.y = (mng_float)pData->iGlobalPrimarygreeny / 100000;
+ sPrimaries.Blue.x = (mng_float)pData->iGlobalPrimarybluex / 100000;
+ sPrimaries.Blue.y = (mng_float)pData->iGlobalPrimarybluey / 100000;
+ }
+
+ sWhitepoint.Y = /* Y component is always 1.0 */
+ sPrimaries.Red.Y =
+ sPrimaries.Green.Y =
+ sPrimaries.Blue.Y = 1.0;
+
+ if (pBuf->bHasGAMA) /* get the gamma value */
+ dGamma = (mng_float)pBuf->iGamma / 100000;
+ else
+ dGamma = (mng_float)pData->iGlobalGamma / 100000;
+
+/* dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma); ??? */
+ dGamma = pData->dViewgamma / dGamma;
+
+ pGammatable [0] = /* and build the lookup tables */
+ pGammatable [1] =
+ pGammatable [2] = cmsBuildGamma (256, dGamma);
+
+/* B001 start */
+ if (!pGammatable [0]) /* enough memory ? */
+/* B001 end */
+ MNG_ERRORL (pData, MNG_LCMS_NOMEM)
+ /* create the profile */
+ hProf = cmsCreateRGBProfile (&sWhitepoint, &sPrimaries, pGammatable);
+
+/* B001 start */
+ cmsFreeGamma (pGammatable [0]); /* free the temporary gamma tables ? */
+ /* yes! but just the one! */
+/* B001 end */
+
+ pData->hProf1 = hProf; /* save for future use */
+
+ if (!hProf) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+
+ if (pData->bIsRGBA16) /* 16-bit intermediates ? */
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
+ pData->hProf2, TYPE_RGBA_16_SE,
+ INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
+ else
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
+ pData->hProf2, TYPE_RGBA_8,
+ INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
+
+ pData->hTrans = hTrans; /* save for future use */
+
+ if (!hTrans) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS, MNG_LC_END)
+#endif
+
+ return init_gamma_only (pData); /* if we get here, we'll only do gamma */
+}
+#endif /* MNG_INCLUDE_LCMS */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_LCMS
+
+mng_retcode init_full_cms_object (mng_datap pData)
+{
+ mng_cmsprof hProf;
+ mng_cmstrans hTrans;
+ mng_imagedatap pBuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS_OBJ, MNG_LC_START)
+#endif
+ /* address the object-buffer */
+ pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+
+ if (pBuf->bHasICCP)
+ {
+ if (!pData->hProf2) /* output profile not defined ? */
+ { /* then assume sRGB !! */
+ pData->hProf2 = mnglcms_createsrgbprofile ();
+
+ if (!pData->hProf2) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+ }
+ /* generate a profile handle */
+ hProf = cmsOpenProfileFromMem (pBuf->pProfile, pBuf->iProfilesize);
+
+ pData->hProf1 = hProf; /* save for future use */
+
+ if (!hProf) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+
+ if (pData->bIsRGBA16) /* 16-bit intermediates ? */
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
+ pData->hProf2, TYPE_RGBA_16_SE,
+ INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
+ else
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
+ pData->hProf2, TYPE_RGBA_8,
+ INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
+
+ pData->hTrans = hTrans; /* save for future use */
+
+ if (!hTrans) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+ else
+ if (pBuf->bHasSRGB)
+ {
+ if (pData->bIssRGB) /* sRGB system ? */
+ return MNG_NOERROR; /* no conversion required */
+
+ if (!pData->hProf3) /* sRGB profile not defined ? */
+ { /* then create it implicitly !! */
+ pData->hProf3 = mnglcms_createsrgbprofile ();
+
+ if (!pData->hProf3) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+ }
+
+ hProf = pData->hProf3; /* convert from sRGB profile */
+
+ if (pData->bIsRGBA16) /* 16-bit intermediates ? */
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
+ pData->hProf2, TYPE_RGBA_16_SE,
+ pBuf->iRenderingintent, MNG_CMS_FLAGS);
+ else
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
+ pData->hProf2, TYPE_RGBA_8,
+ pBuf->iRenderingintent, MNG_CMS_FLAGS);
+
+ pData->hTrans = hTrans; /* save for future use */
+
+ if (!hTrans) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+ else
+ if ((pBuf->bHasCHRM) && (pBuf->bHasGAMA) && (pBuf->iGamma > 0))
+ {
+ mng_CIExyY sWhitepoint;
+ mng_CIExyYTRIPLE sPrimaries;
+ mng_gammatabp pGammatable[3];
+ mng_float dGamma;
+
+ if (!pData->hProf2) /* output profile not defined ? */
+ { /* then assume sRGB !! */
+ pData->hProf2 = mnglcms_createsrgbprofile ();
+
+ if (!pData->hProf2) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+ }
+
+ sWhitepoint.x = (mng_float)pBuf->iWhitepointx / 100000;
+ sWhitepoint.y = (mng_float)pBuf->iWhitepointy / 100000;
+ sPrimaries.Red.x = (mng_float)pBuf->iPrimaryredx / 100000;
+ sPrimaries.Red.y = (mng_float)pBuf->iPrimaryredy / 100000;
+ sPrimaries.Green.x = (mng_float)pBuf->iPrimarygreenx / 100000;
+ sPrimaries.Green.y = (mng_float)pBuf->iPrimarygreeny / 100000;
+ sPrimaries.Blue.x = (mng_float)pBuf->iPrimarybluex / 100000;
+ sPrimaries.Blue.y = (mng_float)pBuf->iPrimarybluey / 100000;
+
+ sWhitepoint.Y = /* Y component is always 1.0 */
+ sPrimaries.Red.Y =
+ sPrimaries.Green.Y =
+ sPrimaries.Blue.Y = 1.0;
+
+ dGamma = (mng_float)pBuf->iGamma / 100000;
+
+/* dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma); ??? */
+ dGamma = pData->dViewgamma / dGamma;
+
+ pGammatable [0] = /* and build the lookup tables */
+ pGammatable [1] =
+ pGammatable [2] = cmsBuildGamma (256, dGamma);
+
+/* B001 start */
+ if (!pGammatable [0]) /* enough memory ? */
+/* B001 end */
+ MNG_ERRORL (pData, MNG_LCMS_NOMEM)
+
+ /* create the profile */
+ hProf = cmsCreateRGBProfile (&sWhitepoint, &sPrimaries, pGammatable);
+
+/* B001 start */
+ cmsFreeGamma (pGammatable [0]); /* free the temporary gamma tables ? */
+ /* yes! but just the one! */
+/* B001 end */
+
+ pData->hProf1 = hProf; /* save for future use */
+
+ if (!hProf) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+
+ if (pData->bIsRGBA16) /* 16-bit intermediates ? */
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_16_SE,
+ pData->hProf2, TYPE_RGBA_16_SE,
+ INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
+ else
+ hTrans = cmsCreateTransform (hProf, TYPE_RGBA_8,
+ pData->hProf2, TYPE_RGBA_8,
+ INTENT_PERCEPTUAL, MNG_CMS_FLAGS);
+
+ pData->hTrans = hTrans; /* save for future use */
+
+ if (!hTrans) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOTRANS)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_full_cms;
+
+ return MNG_NOERROR; /* and done */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_FULL_CMS_OBJ, MNG_LC_END)
+#endif
+ /* if we get here, we'll only do gamma */
+ return init_gamma_only_object (pData);
+}
+#endif /* MNG_INCLUDE_LCMS */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_LCMS
+mng_retcode correct_full_cms (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CORRECT_FULL_CMS, MNG_LC_START)
+#endif
+
+ cmsDoTransform (pData->hTrans, pData->pRGBArow, pData->pRGBArow, pData->iRowsamples);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CORRECT_FULL_CMS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_LCMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS)
+mng_retcode init_gamma_only (mng_datap pData)
+{
+ mng_float dGamma;
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_imagedatap pBuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_START)
+#endif
+
+ if (!pImage) /* no current object? then use object 0 */
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf; /* address the buffer */
+
+ if (pBuf->bHasSRGB) /* get the gamma value */
+ dGamma = 0.45455;
+ else
+ if (pBuf->bHasGAMA)
+ dGamma = (mng_float)pBuf->iGamma / 100000;
+ else
+ if (pData->bHasglobalSRGB)
+ dGamma = 0.45455;
+ else
+ if (pData->bHasglobalGAMA)
+ dGamma = (mng_float)pData->iGlobalGamma / 100000;
+ else
+ dGamma = pData->dDfltimggamma;
+
+ if (dGamma > 0) /* ignore gamma=0 */
+ {
+ dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma);
+
+ if (dGamma != pData->dLastgamma) /* lookup table needs to be computed ? */
+ {
+ mng_int32 iX;
+
+ pData->aGammatab [0] = 0;
+
+ for (iX = 1; iX <= 255; iX++)
+ pData->aGammatab [iX] = (mng_uint8)(pow (iX / 255.0, dGamma) * 255 + 0.5);
+
+ pData->dLastgamma = dGamma; /* keep for next time */
+ }
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_gamma_only;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS)
+mng_retcode init_gamma_only_object (mng_datap pData)
+{
+ mng_float dGamma;
+ mng_imagedatap pBuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY_OBJ, MNG_LC_START)
+#endif
+ /* address the object-buffer */
+ pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+
+ if (pBuf->bHasSRGB) /* get the gamma value */
+ dGamma = 0.45455;
+ else
+ if (pBuf->bHasGAMA)
+ dGamma = (mng_float)pBuf->iGamma / 100000;
+ else
+ dGamma = pData->dDfltimggamma;
+
+ if (dGamma) /* lets not divide by zero, shall we... */
+ dGamma = pData->dViewgamma / (dGamma * pData->dDisplaygamma);
+
+ if (dGamma != pData->dLastgamma) /* lookup table needs to be computed ? */
+ {
+ mng_int32 iX;
+
+ pData->aGammatab [0] = 0;
+
+ for (iX = 1; iX <= 255; iX++)
+ pData->aGammatab [iX] = (mng_uint8)(pow (iX / 255.0, dGamma) * 255 + 0.5);
+
+ pData->dLastgamma = dGamma; /* keep for next time */
+ }
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_gamma_only;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GAMMA_ONLY_OBJ, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS */
+
+/* ************************************************************************** */
+
+#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS)
+mng_retcode correct_gamma_only (mng_datap pData)
+{
+ mng_uint8p pWork;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CORRECT_GAMMA_ONLY, MNG_LC_START)
+#endif
+
+ pWork = pData->pRGBArow; /* address intermediate row */
+
+ if (pData->bIsRGBA16) /* 16-bit intermediate row ? */
+ {
+
+
+ /* TODO: 16-bit precision gamma processing */
+ /* we'll just do the high-order byte for now */
+
+
+ /* convert all samples in the row */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* using the precalculated gamma lookup table */
+ *pWork = pData->aGammatab [*pWork];
+ *(pWork+2) = pData->aGammatab [*(pWork+2)];
+ *(pWork+4) = pData->aGammatab [*(pWork+4)];
+
+ pWork += 8;
+ }
+ }
+ else
+ { /* convert all samples in the row */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* using the precalculated gamma lookup table */
+ *pWork = pData->aGammatab [*pWork];
+ *(pWork+1) = pData->aGammatab [*(pWork+1)];
+ *(pWork+2) = pData->aGammatab [*(pWork+2)];
+
+ pWork += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CORRECT_GAMMA_ONLY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_GAMMA_ONLY || MNG_FULL_CMS */
+
+/* ************************************************************************** */
+
+#ifdef MNG_APP_CMS
+mng_retcode init_app_cms (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_START)
+#endif
+
+ if ( (pData->fProcessiccp) &&
+ ((pBuf->bHasICCP) || (pData->bHasglobalICCP)) )
+ {
+ mng_uint32 iProfilesize;
+ mng_ptr pProfile;
+
+ if (pBuf->bHasICCP) /* get the right profile */
+ {
+ iProfilesize = pBuf->iProfilesize;
+ pProfile = pBuf->pProfile;
+ }
+ else
+ {
+ iProfilesize = pData->iGlobalProfilesize;
+ pProfile = pData->pGlobalProfile;
+ }
+ /* inform the app */
+ if (!pData->fProcessiccp ((mng_handle)pData, iProfilesize, pProfile))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+ if ( (pData->fProcesssrgb) &&
+ ((pBuf->bHasSRGB) || (pData->bHasglobalSRGB)) )
+ {
+ mng_uint8 iIntent;
+
+ if (pBuf->bHasSRGB) /* determine rendering intent */
+ iIntent = pBuf->iRenderingintent;
+ else
+ iIntent = pData->iGlobalRendintent;
+ /* inform the app */
+ if (!pData->fProcesssrgb ((mng_handle)pData, iIntent))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+ if ( (pData->fProcesschroma) &&
+ ( ((pBuf->bHasCHRM) || (pData->bHasglobalCHRM)) ) )
+ {
+ mng_uint32 iWhitepointx, iWhitepointy;
+ mng_uint32 iPrimaryredx, iPrimaryredy;
+ mng_uint32 iPrimarygreenx, iPrimarygreeny;
+ mng_uint32 iPrimarybluex, iPrimarybluey;
+
+ if (pBuf->bHasCHRM) /* local cHRM ? */
+ {
+ iWhitepointx = pBuf->iWhitepointx;
+ iWhitepointy = pBuf->iWhitepointy;
+ iPrimaryredx = pBuf->iPrimaryredx;
+ iPrimaryredy = pBuf->iPrimaryredy;
+ iPrimarygreenx = pBuf->iPrimarygreenx;
+ iPrimarygreeny = pBuf->iPrimarygreeny;
+ iPrimarybluex = pBuf->iPrimarybluex;
+ iPrimarybluey = pBuf->iPrimarybluey;
+ }
+ else
+ {
+ iWhitepointx = pData->iGlobalWhitepointx;
+ iWhitepointy = pData->iGlobalWhitepointy;
+ iPrimaryredx = pData->iGlobalPrimaryredx;
+ iPrimaryredy = pData->iGlobalPrimaryredy;
+ iPrimarygreenx = pData->iGlobalPrimarygreenx;
+ iPrimarygreeny = pData->iGlobalPrimarygreeny;
+ iPrimarybluex = pData->iGlobalPrimarybluex;
+ iPrimarybluey = pData->iGlobalPrimarybluey;
+ }
+ /* inform the app */
+ if (!pData->fProcesschroma ((mng_handle)pData, iWhitepointx, iWhitepointy,
+ iPrimaryredx, iPrimaryredy,
+ iPrimarygreenx, iPrimarygreeny,
+ iPrimarybluex, iPrimarybluey))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+ if ( (pData->fProcessgamma) &&
+ ((pBuf->bHasGAMA) || (pData->bHasglobalGAMA)) )
+ {
+ mng_uint32 iGamma;
+
+ if (pBuf->bHasGAMA) /* get the gamma value */
+ iGamma = pBuf->iGamma;
+ else
+ iGamma = pData->iGlobalGamma;
+ /* inform the app */
+ if (!pData->fProcessgamma ((mng_handle)pData, iGamma))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_APP_CMS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#ifdef MNG_APP_CMS
+mng_retcode init_app_cms_object (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pCurrentobj)->pImgbuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_APP_CMS_OBJ, MNG_LC_START)
+#endif
+
+ if ((pData->fProcessiccp) && (pBuf->bHasICCP))
+ { /* inform the app */
+ if (!pData->fProcessiccp ((mng_handle)pData, pBuf->iProfilesize, pBuf->pProfile))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+ if ((pData->fProcesssrgb) && (pBuf->bHasSRGB))
+ { /* inform the app */
+ if (!pData->fProcesssrgb ((mng_handle)pData, pBuf->iRenderingintent))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+ if ((pData->fProcesschroma) && (pBuf->bHasCHRM))
+ { /* inform the app */
+ if (!pData->fProcesschroma ((mng_handle)pData, pBuf->iWhitepointx, pBuf->iWhitepointy,
+ pBuf->iPrimaryredx, pBuf->iPrimaryredy,
+ pBuf->iPrimarygreenx, pBuf->iPrimarygreeny,
+ pBuf->iPrimarybluex, pBuf->iPrimarybluey))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+ if ((pData->fProcessgamma) && (pBuf->bHasGAMA))
+ { /* inform the app */
+ if (!pData->fProcessgamma ((mng_handle)pData, pBuf->iGamma))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+ /* load color-correction routine */
+ pData->fCorrectrow = (mng_fptr)correct_app_cms;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_APP_CMS_OBJ, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#ifdef MNG_APP_CMS
+mng_retcode correct_app_cms (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CORRECT_APP_CMS, MNG_LC_START)
+#endif
+
+ if (pData->fProcessarow) /* let the app do something with our row */
+ if (!pData->fProcessarow ((mng_handle)pData, pData->iRowsamples,
+ pData->bIsRGBA16, pData->pRGBArow))
+ MNG_ERROR (pData, MNG_APPCMSERROR)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CORRECT_APP_CMS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_APP_CMS */
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_DISPLAY_PROCS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
+
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_cms.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_cms.h
new file mode 100644
index 0000000..02d6c33
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_cms.h
@@ -0,0 +1,80 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_cms.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.1 * */
+/* * * */
+/* * purpose : color management routines (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of color management routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added creatememprofile * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 1.0.1 - 04/25/2001 - G.Juyn * */
+/* * - moved mng_clear_cms to libmng_cms * */
+/* * 1.0.1 - 05/02/2001 - G.Juyn * */
+/* * - added "default" sRGB generation (Thanks Marti!) * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_cms_h_
+#define _libmng_cms_h_
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_LCMS
+void mnglcms_initlibrary (void);
+mng_cmsprof mnglcms_createfileprofile (mng_pchar zFilename);
+mng_cmsprof mnglcms_creatememprofile (mng_uint32 iProfilesize,
+ mng_ptr pProfile );
+mng_cmsprof mnglcms_createsrgbprofile (void);
+void mnglcms_freeprofile (mng_cmsprof hProf );
+void mnglcms_freetransform (mng_cmstrans hTrans );
+
+mng_retcode mng_clear_cms (mng_datap pData );
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_FULL_CMS
+mng_retcode init_full_cms (mng_datap pData);
+mng_retcode init_full_cms_object (mng_datap pData);
+mng_retcode correct_full_cms (mng_datap pData);
+#endif
+
+#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY)
+mng_retcode init_gamma_only (mng_datap pData);
+mng_retcode init_gamma_only_object (mng_datap pData);
+mng_retcode correct_gamma_only (mng_datap pData);
+#endif
+
+#ifdef MNG_APP_CMS
+mng_retcode init_app_cms (mng_datap pData);
+mng_retcode init_app_cms_object (mng_datap pData);
+mng_retcode correct_app_cms (mng_datap pData);
+#endif
+
+/* ************************************************************************** */
+
+#endif /* _libmng_cms_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_conf.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_conf.h
new file mode 100644
index 0000000..be2997a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_conf.h
@@ -0,0 +1,224 @@
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_conf.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.4 * */
+/* * * */
+/* * purpose : main configuration file * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : The configuration file. Change this to include/exclude * */
+/* * the options you want or do not want in libmng. * */
+/* * * */
+/* * changes : 0.5.2 - 06/02/2000 - G.Juyn * */
+/* * - separated configuration-options into this file * */
+/* * - changed to most likely configuration (?) * */
+/* * 0.5.2 - 06/03/2000 - G.Juyn * */
+/* * - changed options to create a standard so-library * */
+/* * with everything enabled * */
+/* * 0.5.2 - 06/04/2000 - G.Juyn * */
+/* * - changed options to create a standard win32-dll * */
+/* * with everything enabled * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/12/2000 - G.Juyn * */
+/* * - added workaround for faulty PhotoShop iCCP chunk * */
+/* * 0.9.3 - 09/16/2000 - G.Juyn * */
+/* * - removed trace-options from default SO/DLL builds * */
+/* * * */
+/* * 1.0.4 - 06/22/2002 - G.Juyn * */
+/* * - B526138 - returned IJGSRC6B calling convention to * */
+/* * default for MSVC * */
+/* * * */
+/* ************************************************************************** */
+
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_conf_h_
+#define _libmng_conf_h_
+
+/* ************************************************************************** */
+/* * * */
+/* * User-selectable compile-time options * */
+/* * * */
+/* ************************************************************************** */
+
+/* enable exactly one(1) of the MNG-(sub)set selectors */
+/* use this to select which (sub)set of the MNG specification you wish
+ to support */
+/* generally you'll want full support as the library provides it automatically
+ for you! if you're really strung on memory-requirements you can opt
+ to enable less support (but it's just NOT a good idea!) */
+/* NOTE that this isn't actually implemented yet */
+
+#if !defined(MNG_SUPPORT_FULL) && !defined(MNG_SUPPORT_LC) && !defined(MNG_SUPPORT_VLC)
+#define MNG_SUPPORT_FULL
+/* #define MNG_SUPPORT_LC */
+/* #define MNG_SUPPORT_VLC */
+#endif
+
+/* ************************************************************************** */
+
+/* enable JPEG support if required */
+/* use this to enable the JNG support routines */
+/* this requires an external jpeg package;
+ currently only IJG's jpgsrc6b is supported! */
+/* NOTE that the IJG code can be either 8- or 12-bit (eg. not both);
+ so choose the one you've defined in jconfig.h; if you don't know what
+ the heck I'm talking about, just leave it at 8-bit support (thank you!) */
+
+#ifdef MNG_SUPPORT_FULL /* full support includes JNG */
+#define MNG_SUPPORT_IJG6B
+#endif
+
+#ifndef MNG_SUPPORT_IJG6B
+#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
+#define MNG_SUPPORT_IJG6B
+#endif
+#endif
+
+#if defined(MNG_SUPPORT_IJG6B) && !defined(MNG_SUPPORT_JPEG8) && !defined(MNG_SUPPORT_JPEG12)
+#define MNG_SUPPORT_JPEG8
+/* #define MNG_SUPPORT_JPEG12 */
+#endif
+
+/* The following is required to export the IJG routines from the DLL in
+ the Windows-standard calling convention;
+ currently this only works for Borland C++ !!! */
+
+#if defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
+#if defined(MNG_SUPPORT_IJG6B) && defined(__BORLANDC__)
+#define MNG_DEFINE_JPEG_STDCALL
+#endif
+#endif
+
+/* ************************************************************************** */
+
+/* enable required high-level functions */
+/* use this to select the high-level functions you require */
+/* if you only need to display a MNG, disable write support! */
+/* if you only need to examine a MNG, disable write & display support! */
+/* if you only need to copy a MNG, disable display support! */
+/* if you only need to create a MNG, disable read & display support! */
+/* NOTE that turning all options off will be very unuseful! */
+
+#if !defined(MNG_SUPPORT_READ) && !defined(MNG_SUPPORT_WRITE) && !defined(MNG_SUPPORT_DISPLAY)
+#define MNG_SUPPORT_READ
+#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
+#define MNG_SUPPORT_WRITE
+#endif
+#define MNG_SUPPORT_DISPLAY
+#endif
+
+/* ************************************************************************** */
+
+/* enable chunk access functions */
+/* use this to select whether you need access to the individual chunks */
+/* useful if you want to examine a read MNG (you'll also need MNG_STORE_CHUNKS !)*/
+/* required if you need to create & write a new MNG! */
+
+#ifndef MNG_ACCESS_CHUNKS
+#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
+#define MNG_ACCESS_CHUNKS
+#endif
+#endif
+
+/* ************************************************************************** */
+
+/* enable exactly one of the color-management-functionality selectors */
+/* use this to select the level of automatic color support */
+/* MNG_FULL_CMS requires the lcms (little cms) external package ! */
+/* if you want your own app (or the OS) to handle color-management
+ select MNG_APP_CMS */
+
+#if !defined(MNG_FULL_CMS) && !defined(MNG_GAMMA_ONLY) && !defined(MNG_NO_CMS) && !defined(MNG_APP_CMS)
+#if defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
+#define MNG_FULL_CMS
+#else
+#define MNG_GAMMA_ONLY
+#endif
+/* #define MNG_NO_CMS */
+/* #define MNG_APP_CMS */
+#endif
+
+/* ************************************************************************** */
+
+/* enable automatic dithering */
+/* use this if you need dithering support to convert high-resolution
+ images to a low-resolution output-tqdevice */
+/* NOTE that this is not supported yet */
+
+/* #define MNG_AUTO_DITHER */
+
+/* ************************************************************************** */
+
+/* enable whether chunks should be stored for reference later */
+/* use this if you need to examine the chunks of a MNG you have read,
+ or (re-)write a MNG you have read */
+/* turn this off if you want to reduce memory-consumption */
+
+#ifndef MNG_STORE_CHUNKS
+#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
+#define MNG_STORE_CHUNKS
+#endif
+#endif
+
+/* ************************************************************************** */
+
+/* enable internal memory management (if your compiler supports it) */
+/* use this if your compiler supports the 'standard' memory functions
+ (calloc & free), and you want the library to use these functions and not
+ bother your app with memory-callbacks */
+
+/* #define MNG_INTERNAL_MEMMNGMT */
+
+/* ************************************************************************** */
+
+/* enable internal tracing-functionality (manual debugging purposes) */
+/* use this if you have trouble location bugs or problems */
+/* NOTE that you'll need to specify the trace callback function! */
+
+/* #define MNG_SUPPORT_TRACE */
+
+/* ************************************************************************** */
+
+/* enable extended error- and trace-telltaling */
+/* use this if you need explanatory messages with errors and/or tracing */
+
+#if !defined(MNG_ERROR_TELLTALE) && !defined(MNG_TRACE_TELLTALE)
+#if defined(MNG_BUILD_SO) || defined(MNG_USE_SO) || defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
+#define MNG_ERROR_TELLTALE
+#define MNG_TRACE_TELLTALE
+#endif
+#endif
+
+/* ************************************************************************** */
+
+/* enable big-endian support */
+/* enable this if you're on an architecture that supports big-endian reads
+ and writes that aren't word-aligned */
+/* according to reliable sources this only works for PowerPC (bigendian mode)
+ and 680x0 */
+
+/* #define MNG_BIGENDIAN_SUPPORTED */
+
+/* ************************************************************************** */
+/* * * */
+/* * End of user-selectable compile-time options * */
+/* * * */
+/* ************************************************************************** */
+
+#endif /* _libmng_conf_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_data.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_data.h
new file mode 100644
index 0000000..f4fc1c8
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_data.h
@@ -0,0 +1,768 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_data.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.2 * */
+/* * * */
+/* * purpose : main data structure definition * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the library main data structure * */
+/* * * */
+/* * changes : 0.5.1 - 05/04/2000 - G.Juyn * */
+/* * - added CRC table to main structure (for thread-safety) * */
+/* * 0.5.1 - 05/06/2000 - G.Juyn * */
+/* * - added iPLTEentries for checking hIST-length * */
+/* * 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed palette definition to exported palette-type * */
+/* * - removed frozen indicator * */
+/* * - added create/write indicators * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/13/2000 - G.Juyn * */
+/* * - added eMNGma hack (will be removed in 1.0.0 !!!) * */
+/* * - added TERM animation object pointer (easier reference) * */
+/* * - added saved-data structure for SAVE/SEEK processing * */
+/* * * */
+/* * 0.5.2 - 05/18/2000 - G.Juyn * */
+/* * - added fields for JNG support (IJG-based) * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - changed global tRNS definition * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added delta-image fields * */
+/* * 0.5.2 - 06/01/2000 - G.Juyn * */
+/* * - added internal delta-image processing callbacks * */
+/* * 0.5.2 - 06/02/2000 - G.Juyn * */
+/* * - changed SWAP_ENDIAN to BIGENDIAN_SUPPORTED * */
+/* * (contributed by Tim Rowley) * */
+/* * - added getalphaline callback for RGB8_A8 canvasstyle * */
+/* * 0.5.2 - 06/06/2000 - G.Juyn * */
+/* * - added parameter for delayed buffer-processing * */
+/* * * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - added update-region parms for refresh calback * */
+/* * - added Needrefresh parameter * */
+/* * 0.5.3 - 06/17/2000 - G.Juyn * */
+/* * - added Deltaimmediate parm for faster delta-processing * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added Speed parameter to facilitate testing * */
+/* * - added Imagelevel parameter for processtext callback * */
+/* * 0.5.3 - 06/26/2000 - G.Juyn * */
+/* * - changed userdata variable to mng_ptr * */
+/* * * */
+/* * 0.9.1 - 07/07/2000 - G.Juyn * */
+/* * - added variables for go_xxxx processing * */
+/* * 0.9.1 - 07/08/2000 - G.Juyn * */
+/* * - added variables for improved timing support * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - added callbacks for SAVE/SEEK processing * */
+/* * - added variable for NEEDSECTIONWAIT breaks * */
+/* * - added variable for freeze & reset processing * */
+/* * 0.9.1 - 07/17/2000 - G.Juyn * */
+/* * - fixed suspension-buffering for 32K+ chunks * */
+/* * * */
+/* * 0.9.2 - 07/29/2000 - G.Juyn * */
+/* * - removed Nextbackxxx fields (no longer used) * */
+/* * 0.9.2 - 07/31/2000 - G.Juyn * */
+/* * - fixed wrapping of suspension parameters * */
+/* * 0.9.2 - 08/04/2000 - G.Juyn * */
+/* * - B111096 - fixed large-buffer read-suspension * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * 0.9.3 - 09/10/2000 - G.Juyn * */
+/* * - fixed DEFI behavior * */
+/* * 0.9.3 - 10/10/2000 - G.Juyn * */
+/* * - added support for alpha-depth prediction * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - added support for nEED * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added optional support for bKGD for PNG images * */
+/* * - added support for JDAA * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - added callback to process non-critical unknown chunks * */
+/* * - fixed support for bKGD * */
+/* * 0.9.3 - 10/19/2000 - G.Juyn * */
+/* * - implemented delayed delta-processing * */
+/* * 0.9.4 - 12/16/2000 - G.Juyn * */
+/* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
+/* * * */
+/* * 1.0.1 - 02/08/2001 - G.Juyn * */
+/* * - added MEND processing callback * */
+/* * 1.0.1 - 02/13/2001 - G.Juyn * */
+/* * - fixed first FRAM_MODE=4 timing problem * */
+/* * * */
+/* * 1.0.2 - 06/23/2001 - G.Juyn * */
+/* * - added optimization option for MNG-video playback * */
+/* * - added processterm callback * */
+/* * 1.0.2 - 06/25/2001 - G.Juyn * */
+/* * - added option to turn off progressive refresh * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_data_h_
+#define _libmng_data_h_
+
+/* ************************************************************************** */
+
+#define MNG_MAGIC 0x52530a0aL
+
+/* ************************************************************************** */
+/* * * */
+/* * Internal structures * */
+/* * * */
+/* ************************************************************************** */
+
+typedef mng_palette8 mng_rgbpaltab;
+
+/* ************************************************************************** */
+/* * * */
+/* * The saved_data structure * */
+/* * * */
+/* * This tqcontains the saved data after a SAVE chunk has been processed. * */
+/* * The data is saved from the main data structure during SAVE processing, * */
+/* * and restored to the main data structure during SEEK processing. * */
+/* * * */
+/* ************************************************************************** */
+
+typedef struct mng_savedata_struct {
+
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ mng_bool bHasglobalPLTE; /* global PLTE chunk processed */
+ mng_bool bHasglobalTRNS; /* global tRNS chunk processed */
+ mng_bool bHasglobalGAMA; /* global gAMA chunk processed */
+ mng_bool bHasglobalCHRM; /* global cHRM chunk processed */
+ mng_bool bHasglobalSRGB; /* global sRGB chunk processed */
+ mng_bool bHasglobalICCP; /* global iCCP chunk processed */
+ mng_bool bHasglobalBKGD; /* global bKGD chunk processed */
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ mng_uint16 iBACKred; /* BACK fields */
+ mng_uint16 iBACKgreen;
+ mng_uint16 iBACKblue;
+ mng_uint8 iBACKmandatory;
+ mng_uint16 iBACKimageid;
+ mng_uint8 iBACKtile;
+
+ mng_uint8 iFRAMmode; /* FRAM fields (global) */
+ mng_uint32 iFRAMdelay;
+ mng_uint32 iFRAMtimeout;
+ mng_bool bFRAMclipping;
+ mng_int32 iFRAMclipl;
+ mng_int32 iFRAMclipr;
+ mng_int32 iFRAMclipt;
+ mng_int32 iFRAMclipb;
+
+ mng_uint32 iGlobalPLTEcount; /* global PLTE fields */
+ mng_rgbpaltab aGlobalPLTEentries;
+
+ mng_uint32 iGlobalTRNSrawlen; /* global tRNS fields */
+ mng_uint8arr aGlobalTRNSrawdata;
+
+ mng_uint32 iGlobalGamma; /* global gAMA fields */
+
+ mng_uint32 iGlobalWhitepointx; /* global cHRM fields */
+ mng_uint32 iGlobalWhitepointy;
+ mng_uint32 iGlobalPrimaryredx;
+ mng_uint32 iGlobalPrimaryredy;
+ mng_uint32 iGlobalPrimarygreenx;
+ mng_uint32 iGlobalPrimarygreeny;
+ mng_uint32 iGlobalPrimarybluex;
+ mng_uint32 iGlobalPrimarybluey;
+
+ mng_uint8 iGlobalRendintent; /* global sRGB fields */
+
+ mng_uint32 iGlobalProfilesize; /* global iCCP fields */
+ mng_ptr pGlobalProfile;
+
+ mng_uint16 iGlobalBKGDred; /* global bKGD fields */
+ mng_uint16 iGlobalBKGDgreen;
+ mng_uint16 iGlobalBKGDblue;
+#endif /* MNG_SUPPORT_DISPLAY */
+
+ } mng_savedata;
+
+typedef mng_savedata * mng_savedatap;
+
+/* ************************************************************************** */
+/* * * */
+/* * The main libmng data structure * */
+/* * * */
+/* * The handle used in all functions points to this structure which * */
+/* * tqcontains all volatile data necessary to process the network graphic. * */
+/* * * */
+/* ************************************************************************** */
+
+typedef struct mng_data_struct {
+
+ mng_uint32 iMagic; /* magic number to validate
+ a given handle */
+ mng_ptr pUserdata; /* application workdata */
+
+ mng_imgtype eSigtype; /* image information */
+ mng_imgtype eImagetype; /* initially zeroed */
+ mng_uint32 iWidth; /* filled after header is processed */
+ mng_uint32 iHeight;
+ mng_uint32 iTicks; /* these only after MHDR */
+ mng_uint32 iLayercount;
+ mng_uint32 iFramecount;
+ mng_uint32 iPlaytime;
+ mng_uint32 iSimplicity;
+ mng_uint8 iAlphadepth; /* indicates expected alpha-depth */
+
+ mng_uint32 iImagelevel; /* level an image inside a stream */
+
+ mng_uint32 iCanvasstyle; /* tqlayout of the drawing-canvas */
+ mng_uint32 iBkgdstyle; /* tqlayout of the background-canvas */
+
+ mng_int8 iMagnify; /* magnification factor (not used yet) */
+ mng_uint32 iOffsetx; /* x-offset for extremely large image */
+ mng_uint32 iOffsety; /* y-offset for extremely large image */
+ mng_uint32 iCanvaswidth; /* real canvas size */
+ mng_uint32 iCanvasheight; /* must be set by processheader callback */
+
+ mng_uint16 iBGred; /* default background color */
+ mng_uint16 iBGgreen; /* initially "black" */
+ mng_uint16 iBGblue;
+ mng_bool bUseBKGD; /* preferred use of bKGD for PNG */
+
+ mng_bool bIssRGB; /* indicates sRGB system */
+
+#ifdef MNG_FULL_CMS /* little CMS variables */
+ mng_cmsprof hProf1; /* image input profile */
+ mng_cmsprof hProf2; /* default output profile */
+ mng_cmsprof hProf3; /* default sRGB profile */
+ mng_cmstrans hTrans; /* current transformation handle */
+#endif
+
+ mng_float dViewgamma; /* gamma calculation variables */
+ mng_float dDisplaygamma; /* initially set for sRGB conditions */
+ mng_float dDfltimggamma;
+
+ mng_bool bStorechunks; /* switch for storing chunkdata */
+ mng_bool bSectionbreaks; /* indicate NEEDSECTIONWAIT breaks */
+ mng_bool bCacheplayback; /* switch to cache playback info */
+ mng_bool bDoProgressive; /* progressive refresh for large images */
+
+ mng_speedtype iSpeed; /* speed-modifier for animations */
+
+ mng_uint32 iMaxwidth; /* maximum canvas size */
+ mng_uint32 iMaxheight; /* initially set to 1024 x 1024 */
+
+ mng_int32 iErrorcode; /* error reporting fields */
+ mng_int8 iSeverity;
+ mng_int32 iErrorx1;
+ mng_int32 iErrorx2;
+ mng_pchar zErrortext;
+
+ mng_memalloc fMemalloc; /* callback pointers */
+ mng_memfree fMemfree; /* initially nulled */
+ mng_openstream fOpenstream;
+ mng_closestream fClosestream;
+ mng_readdata fReaddata;
+ mng_writedata fWritedata;
+ mng_errorproc fErrorproc;
+ mng_traceproc fTraceproc;
+ mng_processheader fProcessheader;
+ mng_processtext fProcesstext;
+ mng_processsave fProcesssave;
+ mng_processseek fProcessseek;
+ mng_processneed fProcessneed;
+ mng_processmend fProcessmend;
+ mng_processunknown fProcessunknown;
+ mng_processterm fProcessterm;
+ mng_getcanvasline fGetcanvasline;
+ mng_getbkgdline fGetbkgdline;
+ mng_getalphaline fGetalphaline;
+ mng_refresh fRefresh;
+ mng_gettickcount fGettickcount;
+ mng_settimer fSettimer;
+ mng_processgamma fProcessgamma;
+ mng_processchroma fProcesschroma;
+ mng_processsrgb fProcesssrgb;
+ mng_processiccp fProcessiccp;
+ mng_processarow fProcessarow;
+
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ mng_bool bPreDraft48; /* flags ancient style draft */
+
+ mng_chunkid iChunkname; /* read/write-state variables */
+ mng_uint32 iChunkseq;
+ mng_chunkp pFirstchunk; /* double-linked list of */
+ mng_chunkp pLastchunk; /* stored chunk-structures */
+
+ mng_bool bHasheader; /* first header chunk processed */
+ mng_bool bHasMHDR; /* inside a MHDR-MEND sequence */
+ mng_bool bHasIHDR; /* inside a IHDR-IEND sequence */
+ mng_bool bHasBASI; /* inside a BASI-IEND sequence */
+ mng_bool bHasDHDR; /* inside a DHDR-IEND sequence */
+#ifdef MNG_INCLUDE_JNG
+ mng_bool bHasJHDR; /* inside a JHDR-IEND sequence */
+ mng_bool bHasJSEP; /* passed the JSEP separator */
+ mng_bool bHasJDAA; /* at least 1 JDAA processed */
+ mng_bool bHasJDAT; /* at least 1 JDAT processed */
+#endif
+ mng_bool bHasPLTE; /* PLTE chunk processed */
+ mng_bool bHasTRNS; /* tRNS chunk processed */
+ mng_bool bHasGAMA; /* gAMA chunk processed */
+ mng_bool bHasCHRM; /* cHRM chunk processed */
+ mng_bool bHasSRGB; /* sRGB chunk processed */
+ mng_bool bHasICCP; /* iCCP chunk processed */
+ mng_bool bHasBKGD; /* bKGD chunk processed */
+ mng_bool bHasIDAT; /* at least 1 IDAT processed */
+
+ mng_bool bHasSAVE; /* SAVE chunk processed */
+ mng_bool bHasBACK; /* BACK chunk processed */
+ mng_bool bHasFRAM; /* FRAM chunk processed */
+ mng_bool bHasTERM; /* TERM chunk processed */
+ mng_bool bHasLOOP; /* at least 1 LOOP open */
+
+ mng_bool bHasglobalPLTE; /* global PLTE chunk processed */
+ mng_bool bHasglobalTRNS; /* global tRNS chunk processed */
+ mng_bool bHasglobalGAMA; /* global gAMA chunk processed */
+ mng_bool bHasglobalCHRM; /* global cHRM chunk processed */
+ mng_bool bHasglobalSRGB; /* global sRGB chunk processed */
+ mng_bool bHasglobalICCP; /* global iCCP chunk processed */
+ mng_bool bHasglobalBKGD; /* global bKGD chunk processed */
+
+ mng_uint32 iDatawidth; /* IHDR/BASI/DHDR fields */
+ mng_uint32 iDataheight; /* valid if inside IHDR-IEND, */
+ mng_uint8 iBitdepth; /* BASI-IEND or DHDR-IEND */
+ mng_uint8 iColortype;
+ mng_uint8 iCompression;
+ mng_uint8 iFilter;
+ mng_uint8 iInterlace;
+
+ mng_uint32 iPLTEcount; /* PLTE fields */
+
+ mng_bool bEMNGMAhack; /* TODO: to be removed in 1.0.0 !!! */
+
+#ifdef MNG_INCLUDE_JNG
+ mng_uint8 iJHDRcolortype; /* JHDR fields */
+ mng_uint8 iJHDRimgbitdepth; /* valid if inside JHDR-IEND */
+ mng_uint8 iJHDRimgcompression;
+ mng_uint8 iJHDRimginterlace;
+ mng_uint8 iJHDRalphabitdepth;
+ mng_uint8 iJHDRalphacompression;
+ mng_uint8 iJHDRalphafilter;
+ mng_uint8 iJHDRalphainterlace;
+#endif
+
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+#ifdef MNG_SUPPORT_READ
+ mng_bool bReading; /* read processing variables */
+ mng_bool bHavesig;
+ mng_bool bEOF;
+ mng_uint32 iReadbufsize;
+ mng_uint8p pReadbuf;
+
+ mng_uint32 iLargebufsize; /* temp for very large chunks */
+ mng_uint8p pLargebuf;
+
+ mng_uint32 iSuspendtime; /* tickcount at last suspension */
+ mng_bool bSuspended; /* input-reading has been suspended;
+ we're expecting a call to
+ mng_read_resume! */
+ mng_uint8 iSuspendpoint; /* indicates at which point the flow
+ was broken to suspend input-reading */
+
+ mng_bool bSuspensionmode; /* I/O-suspension variables */
+ mng_uint32 iSuspendbufsize;
+ mng_uint8p pSuspendbuf;
+ mng_uint8p pSuspendbufnext;
+ mng_uint32 iSuspendbufleft;
+ mng_uint32 iChunklen; /* chunk length */
+ mng_uint8p pReadbufnext; /* 32K+ suspension-processing */
+#endif /* MNG_SUPPORT_READ */
+
+#ifdef MNG_SUPPORT_WRITE
+ mng_bool bCreating; /* create/write processing variables */
+ mng_bool bWriting;
+ mng_chunkid iFirstchunkadded;
+ mng_uint32 iWritebufsize;
+ mng_uint8p pWritebuf;
+#endif
+
+#ifdef MNG_SUPPORT_DISPLAY
+ mng_bool bDisplaying; /* display-state variables */
+ mng_bool bFramedone;
+ mng_uint32 iFrameseq;
+ mng_uint32 iLayerseq;
+ mng_uint32 iFrametime; /* millisecs */
+
+ mng_uint32 iRequestframe; /* go_xxxx variables */
+ mng_uint32 iRequestlayer;
+ mng_uint32 iRequesttime;
+ mng_bool bSearching;
+
+ mng_bool bRestorebkgd; /* flags restore required before IDAT/JDAT */
+
+ mng_uint32 iRuntime; /* millisecs since start */
+ mng_uint32 iSynctime; /* tickcount at last framesync */
+ mng_uint32 iStarttime; /* tickcount at start */
+ mng_uint32 iEndtime; /* tickcount at end */
+ mng_bool bRunning; /* animation is active */
+ mng_bool bTimerset; /* the timer has been set;
+ we're expecting a call to
+ mng_display_resume! */
+ mng_uint8 iBreakpoint; /* indicates at which point the
+ flow was broken to run the timer */
+ mng_bool bSectionwait; /* indicates a section break */
+ mng_bool bFreezing; /* indicates app requested a freeze */
+ mng_bool bResetting; /* indicates app requested a reset */
+ mng_bool bNeedrefresh; /* indicates screen-refresh is needed */
+ mng_objectp pCurrentobj; /* current "object" */
+ mng_objectp pCurraniobj; /* current animation object
+ "to be"/"being" processed */
+ mng_objectp pTermaniobj; /* TERM animation object */
+ mng_uint32 iIterations; /* TERM/MEND iteration count */
+ mng_objectp pObjzero; /* "on-the-fly" image (object = 0) */
+ mng_objectp pLastclone; /* last clone */
+ mng_objectp pStoreobj; /* current store object for row routines */
+ mng_objectp pStorebuf; /* current store object-buffer for row routines */
+ mng_objectp pRetrieveobj; /* current retrieve object for row routines */
+ mng_savedatap pSavedata; /* pointer to saved data (after SAVE) */
+
+ mng_uint32 iUpdateleft; /* update region for refresh */
+ mng_uint32 iUpdateright;
+ mng_uint32 iUpdatetop;
+ mng_uint32 iUpdatebottom;
+
+ mng_int8 iPass; /* current interlacing pass;
+ negative value means no interlace */
+ mng_int32 iRow; /* current row counter */
+ mng_int32 iRowinc; /* row increment for this pass */
+ mng_int32 iCol; /* current starting column */
+ mng_int32 iColinc; /* column increment for this pass */
+ mng_int32 iRowsamples; /* nr. of samples in current workrow */
+ mng_int32 iSamplemul; /* needed to calculate rowsize */
+ mng_int32 iSampleofs; /* from rowsamples */
+ mng_int32 iSamplediv;
+ mng_int32 iRowsize; /* size of actual data in work row */
+ mng_int32 iRowmax; /* maximum size of data in work row */
+ mng_int32 iFilterofs; /* offset to filter-byte in work row */
+ mng_int32 iPixelofs; /* offset to pixel-bytes in work row */
+ mng_uint32 iLevel0; /* leveling variables */
+ mng_uint32 iLevel1;
+ mng_uint32 iLevel2;
+ mng_uint32 iLevel3;
+ mng_uint8p pWorkrow; /* working row of pixel-data */
+ mng_uint8p pPrevrow; /* previous row of pixel-data */
+ mng_uint8p pRGBArow; /* intermediate row of RGBA8 or RGBA16 data */
+ mng_bool bIsRGBA16; /* indicates intermediate row is RGBA16 */
+ mng_bool bIsOpaque; /* indicates intermediate row is fully opaque */
+ mng_int32 iFilterbpp; /* bpp index for filtering routines */
+
+ mng_int32 iSourcel; /* variables for showing objects */
+ mng_int32 iSourcer;
+ mng_int32 iSourcet;
+ mng_int32 iSourceb;
+ mng_int32 iDestl;
+ mng_int32 iDestr;
+ mng_int32 iDestt;
+ mng_int32 iDestb;
+
+ mng_objectp pFirstimgobj; /* double-linked list of */
+ mng_objectp pLastimgobj; /* image-object structures */
+ mng_objectp pFirstaniobj; /* double-linked list of */
+ mng_objectp pLastaniobj; /* animation-object structures */
+
+#if defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS)
+ mng_uint8 aGammatab[256]; /* precomputed gamma lookup table */
+ mng_float dLastgamma; /* last gamma used to compute table */
+#endif
+
+ mng_fptr fDisplayrow; /* internal callback to display an
+ uncompressed/unfiltered/
+ color-corrected row */
+ mng_fptr fRestbkgdrow; /* internal callback for restore-
+ background processing of a row */
+ mng_fptr fCorrectrow; /* internal callback to color-correct an
+ uncompressed/unfiltered row */
+ mng_fptr fRetrieverow; /* internal callback to retrieve an
+ uncompressed/unfiltered row of data */
+ mng_fptr fStorerow; /* internal callback to store an
+ uncompressed/unfiltered row of data */
+ mng_fptr fProcessrow; /* internal callback to process an
+ uncompressed row of data */
+ mng_fptr fDifferrow; /* internal callback to perform
+ added filter leveling and
+ differing on an unfiltered row */
+ mng_fptr fScalerow; /* internal callback to scale a
+ delta-row to the bitdepth of its target */
+ mng_fptr fDeltarow; /* internal callback to execute a
+ delta-row onto a target */
+ mng_fptr fInitrowproc; /* internal callback to initialize
+ the row processing */
+
+ mng_uint16 iDEFIobjectid; /* DEFI fields */
+ mng_bool bDEFIhasdonotshow;
+ mng_uint8 iDEFIdonotshow;
+ mng_bool bDEFIhasconcrete;
+ mng_uint8 iDEFIconcrete;
+ mng_bool bDEFIhasloca;
+ mng_int32 iDEFIlocax;
+ mng_int32 iDEFIlocay;
+ mng_bool bDEFIhasclip;
+ mng_int32 iDEFIclipl;
+ mng_int32 iDEFIclipr;
+ mng_int32 iDEFIclipt;
+ mng_int32 iDEFIclipb;
+
+ mng_uint16 iBACKred; /* BACK fields */
+ mng_uint16 iBACKgreen;
+ mng_uint16 iBACKblue;
+ mng_uint8 iBACKmandatory;
+ mng_uint16 iBACKimageid;
+ mng_uint8 iBACKtile;
+
+ mng_uint8 iFRAMmode; /* FRAM fields (global) */
+ mng_uint32 iFRAMdelay;
+ mng_uint32 iFRAMtimeout;
+ mng_bool bFRAMclipping;
+ mng_int32 iFRAMclipl;
+ mng_int32 iFRAMclipr;
+ mng_int32 iFRAMclipt;
+ mng_int32 iFRAMclipb;
+
+ mng_uint8 iFramemode; /* current subframe variables */
+ mng_uint32 iFramedelay;
+ mng_uint32 iFrametimeout;
+ mng_bool bFrameclipping;
+ mng_int32 iFrameclipl;
+ mng_int32 iFrameclipr;
+ mng_int32 iFrameclipt;
+ mng_int32 iFrameclipb;
+
+ mng_uint32 iNextdelay; /* delay for *after* next image */
+
+ mng_uint8 iSHOWmode; /* SAVE fields */
+ mng_uint16 iSHOWfromid;
+ mng_uint16 iSHOWtoid;
+ mng_uint16 iSHOWnextid;
+ mng_int16 iSHOWskip;
+
+ mng_uint32 iGlobalPLTEcount; /* global PLTE fields */
+ mng_rgbpaltab aGlobalPLTEentries;
+
+ mng_uint32 iGlobalTRNSrawlen; /* global tRNS fields */
+ mng_uint8arr aGlobalTRNSrawdata;
+
+ mng_uint32 iGlobalGamma; /* global gAMA fields */
+
+ mng_uint32 iGlobalWhitepointx; /* global cHRM fields */
+ mng_uint32 iGlobalWhitepointy;
+ mng_uint32 iGlobalPrimaryredx;
+ mng_uint32 iGlobalPrimaryredy;
+ mng_uint32 iGlobalPrimarygreenx;
+ mng_uint32 iGlobalPrimarygreeny;
+ mng_uint32 iGlobalPrimarybluex;
+ mng_uint32 iGlobalPrimarybluey;
+
+ mng_uint8 iGlobalRendintent; /* global sRGB fields */
+
+ mng_uint32 iGlobalProfilesize; /* global iCCP fields */
+ mng_ptr pGlobalProfile;
+
+ mng_uint16 iGlobalBKGDred; /* global bKGD fields */
+ mng_uint16 iGlobalBKGDgreen;
+ mng_uint16 iGlobalBKGDblue;
+
+ mng_ptr pDeltaImage; /* delta-image fields */
+ mng_uint8 iDeltaImagetype;
+ mng_uint8 iDeltatype;
+ mng_uint32 iDeltaBlockwidth;
+ mng_uint32 iDeltaBlockheight;
+ mng_uint32 iDeltaBlockx;
+ mng_uint32 iDeltaBlocky;
+ mng_bool bDeltaimmediate;
+
+ mng_fptr fDeltagetrow; /* internal delta-proc callbacks */
+ mng_fptr fDeltaaddrow;
+ mng_fptr fDeltatqreplacerow;
+ mng_fptr fDeltaputrow;
+
+ mng_uint16 iMAGNfromid;
+ mng_uint16 iMAGNtoid;
+#endif /* MNG_SUPPORT_DISPLAY */
+
+#ifdef MNG_INCLUDE_ZLIB
+ z_stream sZlib; /* zlib (de)compression variables */
+
+ mng_int32 iZlevel; /* zlib compression parameters */
+ mng_int32 iZmethod;
+ mng_int32 iZwindowbits;
+ mng_int32 iZmemlevel;
+ mng_int32 iZstrategy;
+
+ mng_uint32 iMaxIDAT; /* maximum size of IDAT data */
+
+ mng_bool bInflating; /* indicates "inflate" in progress */
+ mng_bool bDeflating; /* indicates "deflate" in progress */
+#endif /* MNG_INCLUDE_ZLIB */
+
+#ifdef MNG_INCLUDE_JNG
+ mngjpeg_dctmethod eJPEGdctmethod; /* IJG compression variables */
+ mng_int32 iJPEGquality;
+ mng_int32 iJPEGsmoothing;
+ mng_bool bJPEGcompressprogr;
+ mng_bool bJPEGcompressopt;
+
+ mng_uint32 iMaxJDAT; /* maximum size of JDAT/JDAA data */
+
+ mngjpeg_compp pJPEGcinfo; /* compression structure */
+ mngjpeg_errorp pJPEGcerr; /* error-manager compress */
+
+ mngjpeg_decompp pJPEGdinfo; /* decompression structure (JDAT) */
+ mngjpeg_errorp pJPEGderr; /* error-manager decompress (JDAT) */
+ mngjpeg_sourcep pJPEGdsrc; /* source-manager decompress (JDAT) */
+
+ mngjpeg_decompp pJPEGdinfo2; /* decompression structure (JDAA) */
+ mngjpeg_errorp pJPEGderr2; /* error-manager decompress (JDAA) */
+ mngjpeg_sourcep pJPEGdsrc2; /* source-manager decompress (JDAA) */
+
+ mng_uint8p pJPEGbuf; /* buffer for JPEG (de)compression (JDAT) */
+ mng_uint32 iJPEGbufmax; /* allocated space for buffer (JDAT) */
+ mng_uint8p pJPEGcurrent; /* current pointer into buffer (JDAT) */
+ mng_uint32 iJPEGbufremain; /* remaining bytes in buffer (JDAT) */
+ mng_uint32 iJPEGtoskip; /* bytes to skip on next input-block (JDAT) */
+
+ mng_uint8p pJPEGbuf2; /* buffer for JPEG (de)compression (JDAA) */
+ mng_uint32 iJPEGbufmax2; /* allocated space for buffer (JDAA) */
+ mng_uint8p pJPEGcurrent2; /* current pointer into buffer (JDAA) */
+ mng_uint32 iJPEGbufremain2; /* remaining bytes in buffer (JDAA) */
+ mng_uint32 iJPEGtoskip2; /* bytes to skip on next input-block (JDAA) */
+
+ mng_uint8p pJPEGrow; /* buffer for a JPEG row of samples (JDAT) */
+ mng_uint32 iJPEGrowlen;
+
+ mng_uint8p pJPEGrow2; /* buffer for a JPEG row of samples (JDAA) */
+ mng_uint32 iJPEGrowlen2;
+
+ mng_bool bJPEGcompress; /* indicates "compress" initialized */
+
+ mng_bool bJPEGdecompress; /* indicates "decompress" initialized (JDAT) */
+ mng_bool bJPEGhasheader; /* indicates "readheader" succeeded (JDAT) */
+ mng_bool bJPEGdecostarted; /* indicates "decompress" started (JDAT) */
+ mng_bool bJPEGscanstarted; /* indicates "first scan" started (JDAT) */
+ mng_bool bJPEGprogressive; /* indicates a progressive image (JDAT) */
+
+ mng_bool bJPEGdecompress2; /* indicates "decompress" initialized (JDAA) */
+ mng_bool bJPEGhasheader2; /* indicates "readheader" succeeded (JDAA) */
+ mng_bool bJPEGdecostarted2; /* indicates "decompress" started (JDAA) */
+ mng_bool bJPEGscanstarted2; /* indicates "first scan" started (JDAA) */
+ mng_bool bJPEGprogressive2; /* indicates a progressive image (JDAA) */
+
+ mng_fptr fStorerow2; /* internal callback to store an
+ uncompressed/unfiltered row of JPEG-data (JDAT) */
+
+ mng_fptr fStorerow3; /* internal callback to store an
+ uncompressed/unfiltered row of JPEG-data (JDAA) */
+
+ mng_uint32 iJPEGrow; /* row-number for current JPEG row */
+ mng_uint32 iJPEGalpharow; /* nr. of rows filled with alpha */
+ mng_uint32 iJPEGrgbrow; /* nr. of rows filled with 'color'-info */
+ mng_uint32 iJPEGdisprow; /* nr. of rows already displayed "on-the-fly" */
+
+#if defined(MNG_USE_SETJMP) && defined (MNG_INCLUDE_IJG6B)
+ jmp_buf sErrorbuf; /* setjmp/longjmp buffer (error-recovery) */
+#endif
+
+#endif /* MNG_INCLUDE_JNG */
+
+ mng_uint32 aCRCtable [256]; /* CRC prefab table */
+ mng_bool bCRCcomputed; /* "has been build" indicator */
+
+ } mng_data;
+
+typedef mng_data * mng_datap;
+
+/* ************************************************************************** */
+/* * * */
+/* * Internal Callback-Function prototypes * */
+/* * * */
+/* ************************************************************************** */
+
+typedef mng_retcode(*mng_displayrow) (mng_datap pData);
+typedef mng_retcode(*mng_restbkgdrow) (mng_datap pData);
+typedef mng_retcode(*mng_correctrow) (mng_datap pData);
+typedef mng_retcode(*mng_retrieverow) (mng_datap pData);
+typedef mng_retcode(*mng_storerow) (mng_datap pData);
+typedef mng_retcode(*mng_processrow) (mng_datap pData);
+typedef mng_retcode(*mng_initrowproc) (mng_datap pData);
+typedef mng_retcode(*mng_differrow) (mng_datap pData);
+typedef mng_retcode(*mng_scalerow) (mng_datap pData);
+typedef mng_retcode(*mng_deltarow) (mng_datap pData);
+
+typedef mng_retcode(*mng_magnify_x) (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p iSrcline,
+ mng_uint8p iDstline);
+typedef mng_retcode(*mng_magnify_y) (mng_datap pData,
+ mng_int32 iM,
+ mng_int32 iS,
+ mng_uint32 iWidth,
+ mng_uint8p iSrcline1,
+ mng_uint8p iSrcline2,
+ mng_uint8p iDstline);
+
+/* ************************************************************************** */
+/* * * */
+/* * Routines for swapping byte-order from and to graphic files * */
+/* * (This code is adapted from the libpng package) * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef MNG_BIGENDIAN_SUPPORTED
+mng_uint32 mng_get_uint32 (mng_uint8p pBuf);
+mng_int32 mng_get_int32 (mng_uint8p pBuf);
+mng_uint16 mng_get_uint16 (mng_uint8p pBuf);
+void mng_put_uint32 (mng_uint8p pBuf,
+ mng_uint32 i);
+void mng_put_int32 (mng_uint8p pBuf,
+ mng_int32 i);
+void mng_put_uint16 (mng_uint8p pBuf,
+ mng_uint16 i);
+#else /* MNG_BIGENDIAN_SUPPORTED */
+#define mng_get_uint32(P) *(mng_uint32p)(P)
+#define mng_get_int32(P) *(mng_int32p)(P)
+#define mng_get_uint16(P) *(mng_uint16p)(P)
+#define mng_put_uint32(P,I) *(mng_uint32p)(P) = (I)
+#define mng_put_int32(P,I) *(mng_int32p)(P) = (I)
+#define mng_put_uint16(P,I) *(mng_uint16p)(P) = (I)
+#endif /* MNG_BIGENDIAN_SUPPORTED */
+
+/* ************************************************************************** */
+/* * * */
+/* * Some handy(?) macro definitions * */
+/* * * */
+/* ************************************************************************** */
+
+#define MAX_COORD(a, b) (((a) > (b)) ? (a) : (b))
+#define MIN_COORD(a, b) (((a) < (b)) ? (a) : (b))
+
+/* ************************************************************************** */
+
+#endif /* _libmng_data_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_display.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_display.c
new file mode 100644
index 0000000..e82ec5d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_display.c
@@ -0,0 +1,4699 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_display.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.2 * */
+/* * * */
+/* * purpose : Display management (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the display management routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added callback error-reporting support * */
+/* * - fixed frame_delay mistqalignment * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - added sanity check for frozen status * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * 0.5.1 - 05/13/2000 - G.Juyn * */
+/* * - changed display_mend to reset state to initial or SAVE * */
+/* * - added eMNGma hack (will be removed in 1.0.0 !!!) * */
+/* * - added TERM animation object pointer (easier reference) * */
+/* * - added process_save & process_seek routines * */
+/* * 0.5.1 - 05/14/2000 - G.Juyn * */
+/* * - added save_state and restore_state for SAVE/SEEK/TERM * */
+/* * processing * */
+/* * * */
+/* * 0.5.2 - 05/20/2000 - G.Juyn * */
+/* * - added JNG support (JHDR/JDAT) * */
+/* * 0.5.2 - 05/23/2000 - G.Juyn * */
+/* * - fixed problem with DEFI clipping * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added delta-image support (DHDR,PROM,IPNG,IJNG) * */
+/* * 0.5.2 - 05/31/2000 - G.Juyn * */
+/* * - fixed pointer confusion (contributed by Tim Rowley) * */
+/* * 0.5.2 - 06/03/2000 - G.Juyn * */
+/* * - fixed makeup for Linux gcc compile * */
+/* * 0.5.2 - 06/05/2000 - G.Juyn * */
+/* * - added support for RGB8_A8 canvasstyle * */
+/* * 0.5.2 - 06/09/2000 - G.Juyn * */
+/* * - fixed timer-handling to run with Mozilla (Tim Rowley) * */
+/* * 0.5.2 - 06/10/2000 - G.Juyn * */
+/* * - fixed some compilation-warnings (contrib Jason Morris) * */
+/* * * */
+/* * 0.5.3 - 06/12/2000 - G.Juyn * */
+/* * - fixed display of stored JNG images * */
+/* * 0.5.3 - 06/13/2000 - G.Juyn * */
+/* * - fixed problem with BASI-IEND as object 0 * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - changed progressive-display processing * */
+/* * 0.5.3 - 06/17/2000 - G.Juyn * */
+/* * - changed delta-image processing * */
+/* * 0.5.3 - 06/20/2000 - G.Juyn * */
+/* * - fixed some minor stuff * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added speed-modifier to timing routine * */
+/* * 0.5.3 - 06/22/2000 - G.Juyn * */
+/* * - added support for PPLT chunk processing * */
+/* * 0.5.3 - 06/29/2000 - G.Juyn * */
+/* * - swapped refresh parameters * */
+/* * * */
+/* * 0.9.0 - 06/30/2000 - G.Juyn * */
+/* * - changed refresh parameters to 'x,y,width,height' * */
+/* * * */
+/* * 0.9.1 - 07/07/2000 - G.Juyn * */
+/* * - implemented support for freeze/reset/resume & go_xxxx * */
+/* * 0.9.1 - 07/08/2000 - G.Juyn * */
+/* * - added support for improved timing * */
+/* * 0.9.1 - 07/14/2000 - G.Juyn * */
+/* * - changed EOF processing behavior * */
+/* * - fixed TERM delay processing * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - fixed freeze & reset processing * */
+/* * 0.9.1 - 07/16/2000 - G.Juyn * */
+/* * - fixed storage of images during mng_read() * */
+/* * - fixed support for mng_display() after mng_read() * */
+/* * 0.9.1 - 07/24/2000 - G.Juyn * */
+/* * - fixed reading of still-images * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/07/2000 - G.Juyn * */
+/* * - B111300 - fixup for improved portability * */
+/* * 0.9.3 - 08/21/2000 - G.Juyn * */
+/* * - fixed TERM processing delay of 0 msecs * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/10/2000 - G.Juyn * */
+/* * - fixed problem with no refresh after TERM * */
+/* * - fixed DEFI behavior * */
+/* * 0.9.3 - 09/16/2000 - G.Juyn * */
+/* * - fixed timing & refresh behavior for single PNG/JNG * */
+/* * 0.9.3 - 09/19/2000 - G.Juyn * */
+/* * - refixed timing & refresh behavior for single PNG/JNG * */
+/* * 0.9.3 - 10/02/2000 - G.Juyn * */
+/* * - fixed timing again (this is getting boring...) * */
+/* * - refixed problem with no refresh after TERM * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added JDAA chunk * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - fixed support for bKGD * */
+/* * 0.9.3 - 10/18/2000 - G.Juyn * */
+/* * - fixed delta-processing behavior * */
+/* * 0.9.3 - 10/19/2000 - G.Juyn * */
+/* * - added storage for pixel-/alpha-sampledepth for delta's * */
+/* * 0.9.3 - 10/27/2000 - G.Juyn * */
+/* * - fixed seperate read() & display() processing * */
+/* * * */
+/* * 0.9.4 - 10/31/2000 - G.Juyn * */
+/* * - fixed possible loop in display_resume() (Thanks Vova!) * */
+/* * 0.9.4 - 11/20/2000 - G.Juyn * */
+/* * - fixed unwanted repetition in mng_readdisplay() * */
+/* * 0.9.4 - 11/24/2000 - G.Juyn * */
+/* * - moved restore of object 0 to libmng_display * */
+/* * - added restore of object 0 to TERM processing !!! * */
+/* * - fixed TERM delay processing * */
+/* * - fixed TERM end processing (count = 0) * */
+/* * 0.9.4 - 12/16/2000 - G.Juyn * */
+/* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
+/* * 0.9.4 - 1/18/2001 - G.Juyn * */
+/* * - removed test filter-methods 1 & 65 * */
+/* * - set default level-set for filtertype=64 to all zeroes * */
+/* * * */
+/* * 0.9.5 - 1/20/2001 - G.Juyn * */
+/* * - fixed compiler-warnings Mozilla (thanks Tim) * */
+/* * 0.9.5 - 1/23/2001 - G.Juyn * */
+/* * - fixed timing-problem with switching framing_modes * */
+/* * * */
+/* * 1.0.1 - 02/08/2001 - G.Juyn * */
+/* * - added MEND processing callback * */
+/* * 1.0.1 - 02/13/2001 - G.Juyn * */
+/* * - fixed first FRAM_MODE=4 timing problem * */
+/* * 1.0.1 - 04/21/2001 - G.Juyn * */
+/* * - fixed memory-leak for JNGs with alpha (Thanks Gregg!) * */
+/* * - added BGRA8 canvas with premultiplied alpha * */
+/* * * */
+/* * 1.0.2 - 06/25/2001 - G.Juyn * */
+/* * - fixed memory-leak with delta-images (Thanks Michael!) * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_objects.h"
+#include "libmng_object_prc.h"
+#include "libmng_memory.h"
+#include "libmng_zlib.h"
+#include "libmng_jpeg.h"
+#include "libmng_cms.h"
+#include "libmng_pixels.h"
+#include "libmng_display.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_DISPLAY_PROCS
+
+/* ************************************************************************** */
+
+mng_retcode set_delay (mng_datap pData,
+ mng_uint32 iInterval)
+{
+ if (!iInterval) /* at least 1 msec please! */
+ iInterval = 1;
+
+ if (!pData->fSettimer ((mng_handle)pData, iInterval))
+ MNG_ERROR (pData, MNG_APPTIMERERROR)
+
+ pData->bTimerset = MNG_TRUE; /* and indicate so */
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Progressive display refresh - does the call to the refresh callback * */
+/* * and sets the timer to allow the app to perform the actual refresh to * */
+/* * the screen (eg. process its main message-loop) * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode display_progressive_refresh (mng_datap pData,
+ mng_uint32 iInterval)
+{
+ if (!pData->bSearching) /* we mustn't be searching !!! */
+ {
+ if ((pData->bRunning) && /* let the app refresh first ? */
+ (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
+ {
+ if (!pData->fRefresh (((mng_handle)pData),
+ pData->iUpdateleft, pData->iUpdatetop,
+ pData->iUpdateright - pData->iUpdateleft,
+ pData->iUpdatebottom - pData->iUpdatetop))
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+
+ pData->iUpdateleft = 0; /* reset update-region */
+ pData->iUpdateright = 0;
+ pData->iUpdatetop = 0;
+ pData->iUpdatebottom = 0; /* reset refreshneeded indicator */
+ pData->bNeedrefresh = MNG_FALSE;
+ /* interval requested ? */
+ if ((!pData->bFreezing) && (iInterval))
+ { /* setup the timer */
+ mng_retcode iRetcode = set_delay (pData, iInterval);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+ }
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Generic display routines * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode interframe_delay (mng_datap pData)
+{
+ mng_uint32 iWaitfor = 0;
+ mng_uint32 iInterval;
+ mng_uint32 iRuninterval;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_START)
+#endif
+
+ if (!pData->bSearching) /* we mustn't be searching !!! */
+ {
+ if (pData->iFramedelay > 0) /* real delay ? */
+ {
+ if ((pData->bRunning) && /* let the app refresh first ? */
+ (pData->iUpdatetop < pData->iUpdatebottom) && (pData->iUpdateleft < pData->iUpdateright))
+ if (!pData->fRefresh (((mng_handle)pData),
+ pData->iUpdateleft, pData->iUpdatetop,
+ pData->iUpdateright - pData->iUpdateleft,
+ pData->iUpdatebottom - pData->iUpdatetop))
+ MNG_ERROR (pData, MNG_APPMISCERROR)
+
+ pData->iUpdateleft = 0; /* reset update-region */
+ pData->iUpdateright = 0;
+ pData->iUpdatetop = 0;
+ pData->iUpdatebottom = 0; /* reset refreshneeded indicator */
+ pData->bNeedrefresh = MNG_FALSE;
+ /* get current tickcount */
+ pData->iRuntime = pData->fGettickcount ((mng_handle)pData);
+ /* calculate interval since last sync-point */
+ if (pData->iRuntime < pData->iSynctime)
+ iRuninterval = pData->iRuntime + ~pData->iSynctime + 1;
+ else
+ iRuninterval = pData->iRuntime - pData->iSynctime;
+ /* calculate actual run-time */
+ if (pData->iRuntime < pData->iStarttime)
+ pData->iRuntime = pData->iRuntime + ~pData->iStarttime + 1;
+ else
+ pData->iRuntime = pData->iRuntime - pData->iStarttime;
+
+ if (pData->iTicks) /* what are we aiming for */
+ {
+ switch (pData->iSpeed) /* honor speed modifier */
+ {
+ case mng_st_fast :
+ {
+ iWaitfor = (mng_uint32)(( 500 * pData->iFramedelay) / pData->iTicks);
+ break;
+ }
+ case mng_st_slow :
+ {
+ iWaitfor = (mng_uint32)((3000 * pData->iFramedelay) / pData->iTicks);
+ break;
+ }
+ case mng_st_slowest :
+ {
+ iWaitfor = (mng_uint32)((8000 * pData->iFramedelay) / pData->iTicks);
+ break;
+ }
+ default :
+ {
+ iWaitfor = (mng_uint32)((1000 * pData->iFramedelay) / pData->iTicks);
+ }
+ }
+ }
+ else
+ {
+ if (pData->eImagetype == mng_it_mng)
+ iWaitfor = 1000;
+ else
+ iWaitfor = 1;
+ }
+
+ if (iWaitfor > iRuninterval) /* delay necessary ? */
+ iInterval = iWaitfor - iRuninterval;
+ else
+ iInterval = 1; /* force app to process messageloop */
+
+ if (pData->bRunning) /* set the timer ? */
+ {
+ iRetcode = set_delay (pData, iInterval);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+
+ if (pData->bRunning) /* increase frametime in advance */
+ pData->iFrametime = pData->iFrametime + iWaitfor;
+ /* setup for next delay */
+ pData->iFramedelay = pData->iNextdelay;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INTERFRAME_DELAY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+void set_display_routine (mng_datap pData)
+{ /* actively running ? */
+ if ((pData->bRunning) && (!pData->bFreezing))
+ {
+ switch (pData->iCanvasstyle) /* determine display routine */
+ {
+ case MNG_CANVAS_RGB8 : { pData->fDisplayrow = (mng_fptr)display_rgb8; break; }
+ case MNG_CANVAS_RGBA8 : { pData->fDisplayrow = (mng_fptr)display_rgba8; break; }
+ case MNG_CANVAS_ARGB8 : { pData->fDisplayrow = (mng_fptr)display_argb8; break; }
+ case MNG_CANVAS_RGB8_A8 : { pData->fDisplayrow = (mng_fptr)display_rgb8_a8; break; }
+ case MNG_CANVAS_BGR8 : { pData->fDisplayrow = (mng_fptr)display_bgr8; break; }
+ case MNG_CANVAS_BGRA8 : { pData->fDisplayrow = (mng_fptr)display_bgra8; break; }
+ case MNG_CANVAS_BGRA8PM : { pData->fDisplayrow = (mng_fptr)display_bgra8_pm; break; }
+ case MNG_CANVAS_ABGR8 : { pData->fDisplayrow = (mng_fptr)display_abgr8; break; }
+/* case MNG_CANVAS_RGB16 : { pData->fDisplayrow = (mng_fptr)display_rgb16; break; } */
+/* case MNG_CANVAS_RGBA16 : { pData->fDisplayrow = (mng_fptr)display_rgba16; break; } */
+/* case MNG_CANVAS_ARGB16 : { pData->fDisplayrow = (mng_fptr)display_argb16; break; } */
+/* case MNG_CANVAS_BGR16 : { pData->fDisplayrow = (mng_fptr)display_bgr16; break; } */
+/* case MNG_CANVAS_BGRA16 : { pData->fDisplayrow = (mng_fptr)display_bgra16; break; } */
+/* case MNG_CANVAS_ABGR16 : { pData->fDisplayrow = (mng_fptr)display_abgr16; break; } */
+/* case MNG_CANVAS_INDEX8 : { pData->fDisplayrow = (mng_fptr)display_index8; break; } */
+/* case MNG_CANVAS_INDEXA8 : { pData->fDisplayrow = (mng_fptr)display_indexa8; break; } */
+/* case MNG_CANVAS_AINDEX8 : { pData->fDisplayrow = (mng_fptr)display_aindex8; break; } */
+/* case MNG_CANVAS_GRAY8 : { pData->fDisplayrow = (mng_fptr)display_gray8; break; } */
+/* case MNG_CANVAS_GRAY16 : { pData->fDisplayrow = (mng_fptr)display_gray16; break; } */
+/* case MNG_CANVAS_GRAYA8 : { pData->fDisplayrow = (mng_fptr)display_graya8; break; } */
+/* case MNG_CANVAS_GRAYA16 : { pData->fDisplayrow = (mng_fptr)display_graya16; break; } */
+/* case MNG_CANVAS_AGRAY8 : { pData->fDisplayrow = (mng_fptr)display_agray8; break; } */
+/* case MNG_CANVAS_AGRAY16 : { pData->fDisplayrow = (mng_fptr)display_agray16; break; } */
+/* case MNG_CANVAS_DX15 : { pData->fDisplayrow = (mng_fptr)display_dx15; break; } */
+/* case MNG_CANVAS_DX16 : { pData->fDisplayrow = (mng_fptr)display_dx16; break; } */
+ }
+ }
+
+ return;
+}
+
+/* ************************************************************************** */
+
+mng_retcode load_bkgdlayer (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_START)
+#endif
+ /* actively running ? */
+ if ((pData->bRunning) && (!pData->bFreezing))
+ {
+ mng_int32 iY;
+ mng_retcode iRetcode; /* save values */
+ mng_int32 iDestl = pData->iDestl;
+ mng_int32 iDestr = pData->iDestr;
+ mng_int32 iDestt = pData->iDestt;
+ mng_int32 iDestb = pData->iDestb;
+ mng_int32 iSourcel = pData->iSourcel;
+ mng_int32 iSourcer = pData->iSourcer;
+ mng_int32 iSourcet = pData->iSourcet;
+ mng_int32 iSourceb = pData->iSourceb;
+ mng_int8 iPass = pData->iPass;
+ mng_int32 iRow = pData->iRow;
+ mng_int32 iRowinc = pData->iRowinc;
+ mng_int32 iCol = pData->iCol;
+ mng_int32 iColinc = pData->iColinc;
+ mng_int32 iRowsamples = pData->iRowsamples;
+ mng_int32 iRowsize = pData->iRowsize;
+ mng_bool bIsRGBA16 = pData->bIsRGBA16;
+ mng_bool bIsOpaque = pData->bIsOpaque;
+ mng_fptr fCorrectrow = pData->fCorrectrow;
+
+ pData->iDestl = 0; /* determine clipping region */
+ pData->iDestt = 0;
+ pData->iDestr = pData->iWidth;
+ pData->iDestb = pData->iHeight;
+
+ if (pData->bFrameclipping) /* frame clipping specified ? */
+ {
+ pData->iDestl = MAX_COORD (pData->iDestl, pData->iFrameclipl);
+ pData->iDestt = MAX_COORD (pData->iDestt, pData->iFrameclipt);
+ pData->iDestr = MIN_COORD (pData->iDestr, pData->iFrameclipr);
+ pData->iDestb = MIN_COORD (pData->iDestb, pData->iFrameclipb);
+ }
+ /* anything to clear ? */
+ if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
+ {
+ pData->iPass = -1; /* these are the object's dimensions now */
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iWidth;
+ pData->iRowsize = pData->iRowsamples << 2;
+ pData->bIsRGBA16 = MNG_FALSE; /* let's keep it simple ! */
+ pData->bIsOpaque = MNG_TRUE;
+
+ pData->iSourcel = 0; /* source relative to destination */
+ pData->iSourcer = pData->iDestr - pData->iDestl;
+ pData->iSourcet = 0;
+ pData->iSourceb = pData->iDestb - pData->iDestt;
+
+ set_display_routine (pData); /* determine display routine */
+ /* default restore using preset BG color */
+ pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bgcolor;
+
+ if (((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng)) &&
+ (pData->bUseBKGD))
+ { /* prefer bKGD in PNG/JNG */
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage)
+ pImage = (mng_imagep)pData->pObjzero;
+
+ if (pImage->pImgbuf->bHasBKGD)
+ pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bkgd;
+ }
+
+ if (pData->fGetbkgdline) /* background-canvas-access callback set ? */
+ {
+ switch (pData->iBkgdstyle)
+ {
+ case MNG_CANVAS_RGB8 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_rgb8; break; }
+ case MNG_CANVAS_BGR8 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bgr8; break; }
+ /* case MNG_CANVAS_RGB16 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_rgb16; break; } */
+ /* case MNG_CANVAS_BGR16 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_bgr16; break; } */
+ /* case MNG_CANVAS_INDEX8 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_index8; break; } */
+ /* case MNG_CANVAS_GRAY8 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_gray8; break; } */
+ /* case MNG_CANVAS_GRAY16 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_gray16; break; } */
+ /* case MNG_CANVAS_DX15 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_dx15; break; } */
+ /* case MNG_CANVAS_DX16 : { pData->fRestbkgdrow = (mng_fptr)restore_bkgd_dx16; break; } */
+ }
+ }
+
+ if (pData->bHasBACK)
+ { /* background image ? */
+ if ((pData->iBACKmandatory & 0x02) && (pData->iBACKimageid))
+ pData->fRestbkgdrow = (mng_fptr)restore_bkgd_backimage;
+ else /* background color ? */
+ if (pData->iBACKmandatory & 0x01)
+ pData->fRestbkgdrow = (mng_fptr)restore_bkgd_backcolor;
+
+ }
+
+ pData->fCorrectrow = MNG_NULL; /* default no color-correction */
+
+
+ /* TODO: determine color correction; this is tricky;
+ the BACK color is treated differently as the image;
+ it probably requires a rewrite of the logic here... */
+
+
+ /* get a temporary row-buffer */
+ MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize)
+
+ iY = pData->iDestt; /* this is where we start */
+ iRetcode = MNG_NOERROR; /* so far, so good */
+
+ while ((!iRetcode) && (iY < pData->iDestb))
+ { /* restore a background row */
+ iRetcode = ((mng_restbkgdrow)pData->fRestbkgdrow) (pData);
+ /* color correction ? */
+ if ((!iRetcode) && (pData->fCorrectrow))
+ iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
+
+ if (!iRetcode) /* so... display it */
+ iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
+
+ if (!iRetcode)
+ iRetcode = next_row (pData); /* adjust variables for next row */
+
+ iY++; /* and next line */
+ }
+ /* drop the temporary row-buffer */
+ MNG_FREE (pData, pData->pRGBArow, pData->iRowsize)
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+
+ pData->iDestl = iDestl; /* restore values */
+ pData->iDestr = iDestr;
+ pData->iDestt = iDestt;
+ pData->iDestb = iDestb;
+ pData->iSourcel = iSourcel;
+ pData->iSourcer = iSourcer;
+ pData->iSourcet = iSourcet;
+ pData->iSourceb = iSourceb;
+ pData->iPass = iPass;
+ pData->iRow = iRow;
+ pData->iRowinc = iRowinc;
+ pData->iCol = iCol;
+ pData->iColinc = iColinc;
+ pData->iRowsamples = iRowsamples;
+ pData->iRowsize = iRowsize;
+ pData->bIsRGBA16 = bIsRGBA16;
+ pData->bIsOpaque = bIsOpaque;
+ pData->fCorrectrow = fCorrectrow;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_LOAD_BKGDLAYER, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode clear_canvas (mng_datap pData)
+{
+ mng_int32 iY;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_START)
+#endif
+
+ pData->iDestl = 0; /* clipping region is full canvas! */
+ pData->iDestt = 0;
+ pData->iDestr = pData->iWidth;
+ pData->iDestb = pData->iHeight;
+
+ pData->iSourcel = 0; /* source is same as destination */
+ pData->iSourcer = pData->iWidth;
+ pData->iSourcet = 0;
+ pData->iSourceb = pData->iHeight;
+
+ pData->iPass = -1; /* these are the object's dimensions now */
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iWidth;
+ pData->iRowsize = pData->iRowsamples << 2;
+ pData->bIsRGBA16 = MNG_FALSE; /* let's keep it simple ! */
+ pData->bIsOpaque = MNG_TRUE;
+
+ set_display_routine (pData); /* determine display routine */
+ /* get a temporary row-buffer */
+ /* it's transtqparent black by default!! */
+ MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize)
+
+ iY = pData->iDestt; /* this is where we start */
+ iRetcode = MNG_NOERROR; /* so far, so good */
+
+ while ((!iRetcode) && (iY < pData->iDestb))
+ { /* clear a row then */
+ iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
+
+ if (!iRetcode)
+ iRetcode = next_row (pData); /* adjust variables for next row */
+
+ iY++; /* and next line */
+ }
+ /* drop the temporary row-buffer */
+ MNG_FREE (pData, pData->pRGBArow, pData->iRowsize)
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLEAR_CANVAS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode next_frame (mng_datap pData,
+ mng_uint8 iFramemode,
+ mng_uint8 iChangedelay,
+ mng_uint32 iDelay,
+ mng_uint8 iChangetimeout,
+ mng_uint32 iTimeout,
+ mng_uint8 iChangeclipping,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb)
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_START)
+#endif
+
+ if (!pData->iBreakpoint) /* no previous break here ? */
+ {
+ mng_uint8 iOldmode = pData->iFramemode;
+ /* interframe delay required ? */
+ if ((iOldmode == 2) || (iOldmode == 4))
+ {
+/* changed here because FRAM 1/3 will delay themselves before each image */
+ if ((pData->iFrameseq) && (iFramemode != 1) && (iFramemode != 3))
+ iRetcode = interframe_delay (pData);
+ else
+ pData->iFramedelay = pData->iNextdelay;
+ }
+ else
+ { /* delay before inserting background layer? */
+ if ((pData->bFramedone) && (iFramemode == 4))
+ iRetcode = interframe_delay (pData);
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* now we'll assume we're in the next frame! */
+ if (iFramemode) /* save the new framing mode ? */
+ {
+ pData->iFRAMmode = iFramemode;
+ pData->iFramemode = iFramemode;
+ }
+ else /* reload default */
+ pData->iFramemode = pData->iFRAMmode;
+
+ if (iChangedelay) /* delay changed ? */
+ {
+ pData->iNextdelay = iDelay; /* for *after* next subframe */
+
+ if ((iOldmode == 2) || (iOldmode == 4))
+/* pData->iFramedelay = iDelay; */
+ pData->iFramedelay = pData->iFRAMdelay;
+
+ if (iChangedelay == 2) /* also overall ? */
+ pData->iFRAMdelay = iDelay;
+ }
+ else
+ { /* reload default */
+ pData->iNextdelay = pData->iFRAMdelay;
+
+/* if ((iOldmode == 2) || (iOldmode == 4))
+ pData->iFramedelay = pData->iNextdelay; */
+ }
+
+ if (iChangetimeout) /* timeout changed ? */
+ { /* for next subframe */
+ pData->iFrametimeout = iTimeout;
+
+ if ((iChangetimeout == 2) || /* also overall ? */
+ (iChangetimeout == 4) ||
+ (iChangetimeout == 6) ||
+ (iChangetimeout == 8))
+ pData->iFRAMtimeout = iTimeout;
+ }
+ else /* reload default */
+ pData->iFrametimeout = pData->iFRAMtimeout;
+
+ if (iChangeclipping) /* clipping changed ? */
+ {
+ pData->bFrameclipping = MNG_TRUE;
+
+ if (!iCliptype) /* absolute ? */
+ {
+ pData->iFrameclipl = iClipl;
+ pData->iFrameclipr = iClipr;
+ pData->iFrameclipt = iClipt;
+ pData->iFrameclipb = iClipb;
+ }
+ else /* relative */
+ {
+ pData->iFrameclipl = pData->iFrameclipl + iClipl;
+ pData->iFrameclipr = pData->iFrameclipr + iClipr;
+ pData->iFrameclipt = pData->iFrameclipt + iClipt;
+ pData->iFrameclipb = pData->iFrameclipb + iClipb;
+ }
+
+ if (iChangeclipping == 2) /* also overall ? */
+ {
+ pData->bFRAMclipping = MNG_TRUE;
+
+ if (!iCliptype) /* absolute ? */
+ {
+ pData->iFRAMclipl = iClipl;
+ pData->iFRAMclipr = iClipr;
+ pData->iFRAMclipt = iClipt;
+ pData->iFRAMclipb = iClipb;
+ }
+ else /* relative */
+ {
+ pData->iFRAMclipl = pData->iFRAMclipl + iClipl;
+ pData->iFRAMclipr = pData->iFRAMclipr + iClipr;
+ pData->iFRAMclipt = pData->iFRAMclipt + iClipt;
+ pData->iFRAMclipb = pData->iFRAMclipb + iClipb;
+ }
+ }
+ }
+ else
+ { /* reload defaults */
+ pData->bFrameclipping = pData->bFRAMclipping;
+ pData->iFrameclipl = pData->iFRAMclipl;
+ pData->iFrameclipr = pData->iFRAMclipr;
+ pData->iFrameclipt = pData->iFRAMclipt;
+ pData->iFrameclipb = pData->iFRAMclipb;
+ }
+ }
+
+ if (!pData->bTimerset) /* timer still off ? */
+ {
+ if ((pData->iFramemode == 4) || /* insert background layer after a new frame */
+ (!pData->iLayerseq)) /* and certainly before the very first layer */
+ iRetcode = load_bkgdlayer (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if ((pData->bDisplaying) && (pData->bRunning))
+ {
+ pData->iFrameseq++; /* count the frame ! */
+ pData->bFramedone = MNG_TRUE; /* and indicate we've done one */
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_FRAME, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode next_layer (mng_datap pData)
+{
+ mng_imagep pImage;
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_START)
+#endif
+
+ if (!pData->iBreakpoint) /* no previous break here ? */
+ { /* interframe delay required ? */
+ if ((pData->eImagetype == mng_it_mng) && (pData->iLayerseq) &&
+ ((pData->iFramemode == 1) || (pData->iFramemode == 3)))
+ iRetcode = interframe_delay (pData);
+ else
+ pData->iFramedelay = pData->iNextdelay;
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ if (!pData->bTimerset) /* timer still off ? */
+ {
+ if (!pData->iLayerseq) /* restore background for the very first layer ? */
+ { /* wait till IDAT/JDAT for PNGs & JNGs !!! */
+ if ((pData->eImagetype == mng_it_png) || (pData->eImagetype == mng_it_jng))
+ pData->bRestorebkgd = MNG_TRUE;
+ else
+ { /* for MNG we do it right away */
+ iRetcode = load_bkgdlayer (pData);
+
+ if (pData->bRunning)
+ pData->iLayerseq++; /* and it counts as a layer then ! */
+ }
+ }
+ else
+ if (pData->iFramemode == 3) /* restore background for each layer ? */
+ iRetcode = load_bkgdlayer (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bHasDHDR) /* processing a delta-image ? */
+ pImage = (mng_imagep)pData->pDeltaImage;
+ else
+ pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage) /* not an active object ? */
+ pImage = (mng_imagep)pData->pObjzero;
+ /* determine display rectangle */
+ pData->iDestl = MAX_COORD ((mng_int32)0, pImage->iPosx);
+ pData->iDestt = MAX_COORD ((mng_int32)0, pImage->iPosy);
+ /* is it a valid buffer ? */
+ if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
+ {
+ pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
+ pImage->iPosx + (mng_int32)pImage->pImgbuf->iWidth );
+ pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
+ pImage->iPosy + (mng_int32)pImage->pImgbuf->iHeight);
+ }
+ else /* it's a single image ! */
+ {
+ pData->iDestr = MIN_COORD ((mng_int32)pData->iWidth,
+ (mng_int32)pData->iDatawidth );
+ pData->iDestb = MIN_COORD ((mng_int32)pData->iHeight,
+ (mng_int32)pData->iDataheight);
+ }
+
+ if (pData->bFrameclipping) /* frame clipping specified ? */
+ {
+ pData->iDestl = MAX_COORD (pData->iDestl, pData->iFrameclipl);
+ pData->iDestt = MAX_COORD (pData->iDestt, pData->iFrameclipt);
+ pData->iDestr = MIN_COORD (pData->iDestr, pData->iFrameclipr);
+ pData->iDestb = MIN_COORD (pData->iDestb, pData->iFrameclipb);
+ }
+
+ if (pImage->bClipped) /* is the image clipped itself ? */
+ {
+ pData->iDestl = MAX_COORD (pData->iDestl, pImage->iClipl);
+ pData->iDestt = MAX_COORD (pData->iDestt, pImage->iClipt);
+ pData->iDestr = MIN_COORD (pData->iDestr, pImage->iClipr);
+ pData->iDestb = MIN_COORD (pData->iDestb, pImage->iClipb);
+ }
+ /* determine source starting point */
+ pData->iSourcel = MAX_COORD ((mng_int32)0, pData->iDestl - pImage->iPosx);
+ pData->iSourcet = MAX_COORD ((mng_int32)0, pData->iDestt - pImage->iPosy);
+
+ if ((pImage->pImgbuf->iWidth) && (pImage->pImgbuf->iHeight))
+ { /* and maximum size */
+ pData->iSourcer = MIN_COORD ((mng_int32)pImage->pImgbuf->iWidth,
+ pData->iSourcel + pData->iDestr - pData->iDestl);
+ pData->iSourceb = MIN_COORD ((mng_int32)pImage->pImgbuf->iHeight,
+ pData->iSourcet + pData->iDestb - pData->iDestt);
+ }
+ else /* it's a single image ! */
+ {
+ pData->iSourcer = pData->iSourcel + pData->iDestr - pData->iDestl;
+ pData->iSourceb = pData->iSourcet + pData->iDestb - pData->iDestt;
+ }
+
+ if (pData->bRunning)
+ pData->iLayerseq++; /* count the layer ! */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_LAYER, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode display_image (mng_datap pData,
+ mng_imagep pImage,
+ mng_bool bLayeradvanced)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_START)
+#endif
+ /* actively running ? */
+ if ((pData->bRunning) && (!pData->bFreezing))
+ {
+ if ( (!pData->iBreakpoint) && /* needs magnification ? */
+ ( (pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY) ) )
+ {
+ iRetcode = magnify_imageobject (pData, pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+
+ pData->pRetrieveobj = pImage; /* so retrieve-row and color-correction can tqfind it */
+
+ if (!bLayeradvanced) /* need to advance the layer ? */
+ {
+ mng_imagep pSave = pData->pCurrentobj;
+ pData->pCurrentobj = pImage;
+ next_layer (pData); /* advance to next layer */
+ pData->pCurrentobj = pSave;
+ }
+ /* need to restore the background ? */
+ if ((!pData->bTimerset) && (pData->bRestorebkgd))
+ {
+ mng_imagep pSave = pData->pCurrentobj;
+ pData->pCurrentobj = pImage;
+ pData->bRestorebkgd = MNG_FALSE;
+ iRetcode = load_bkgdlayer (pData);
+ pData->pCurrentobj = pSave;
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bRunning)
+ pData->iLayerseq++; /* and it counts as a layer then ! */
+ }
+ /* actively running ? */
+ if ((pData->bRunning) && (!pData->bFreezing))
+ {
+ if (!pData->bTimerset) /* all systems still go ? */
+ {
+ pData->iBreakpoint = 0; /* let's make absolutely sure... */
+ /* anything to display ? */
+ if ((pData->iDestr >= pData->iDestl) && (pData->iDestb >= pData->iDestt))
+ {
+ mng_int32 iY;
+
+ set_display_routine (pData); /* determine display routine */
+ /* and image-buffer retrieval routine */
+ switch (pImage->pImgbuf->iColortype)
+ {
+ case 0 : { if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)retrieve_g16;
+ else
+ pData->fRetrieverow = (mng_fptr)retrieve_g8;
+
+ pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
+ break;
+ }
+
+ case 2 : { if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)retrieve_rgb16;
+ else
+ pData->fRetrieverow = (mng_fptr)retrieve_rgb8;
+
+ pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
+ break;
+ }
+
+
+ case 3 : { pData->fRetrieverow = (mng_fptr)retrieve_idx8;
+ pData->bIsOpaque = (mng_bool)(!pImage->pImgbuf->bHasTRNS);
+ break;
+ }
+
+
+ case 4 : { if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)retrieve_ga16;
+ else
+ pData->fRetrieverow = (mng_fptr)retrieve_ga8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+
+ case 6 : { if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)retrieve_rgba16;
+ else
+ pData->fRetrieverow = (mng_fptr)retrieve_rgba8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+ case 8 : { if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)retrieve_g16;
+ else
+ pData->fRetrieverow = (mng_fptr)retrieve_g8;
+
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+
+ case 10 : { if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)retrieve_rgb16;
+ else
+ pData->fRetrieverow = (mng_fptr)retrieve_rgb8;
+
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+
+
+ case 12 : { if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)retrieve_ga16;
+ else
+ pData->fRetrieverow = (mng_fptr)retrieve_ga8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+
+ case 14 : { if (pImage->pImgbuf->iBitdepth > 8)
+ pData->fRetrieverow = (mng_fptr)retrieve_rgba16;
+ else
+ pData->fRetrieverow = (mng_fptr)retrieve_rgba8;
+
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+
+ }
+
+ pData->iPass = -1; /* these are the object's dimensions now */
+ pData->iRow = pData->iSourcet;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pImage->pImgbuf->iWidth;
+ pData->iRowsize = pData->iRowsamples << 2;
+ pData->bIsRGBA16 = MNG_FALSE;
+ /* adjust for 16-bit object ? */
+ if (pImage->pImgbuf->iBitdepth > 8)
+ {
+ pData->bIsRGBA16 = MNG_TRUE;
+ pData->iRowsize = pData->iRowsamples << 3;
+ }
+
+ pData->fCorrectrow = MNG_NULL; /* default no color-correction */
+
+#ifdef MNG_NO_CMS
+ iRetcode = MNG_NOERROR;
+#else
+#if defined(MNG_FULL_CMS) /* determine color-management routine */
+ iRetcode = init_full_cms_object (pData);
+#elif defined(MNG_GAMMA_ONLY)
+ iRetcode = init_gamma_only_object (pData);
+#elif defined(MNG_APP_CMS)
+ iRetcode = init_app_cms_object (pData);
+#endif
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+#endif /* MNG_NO_CMS */
+ /* get a temporary row-buffer */
+ MNG_ALLOC (pData, pData->pRGBArow, pData->iRowsize)
+
+ iY = pData->iSourcet; /* this is where we start */
+
+ while ((!iRetcode) && (iY < pData->iSourceb))
+ { /* get a row */
+ iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
+ /* color correction ? */
+ if ((!iRetcode) && (pData->fCorrectrow))
+ iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
+
+ if (!iRetcode) /* so... display it */
+ iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
+
+ if (!iRetcode) /* adjust variables for next row */
+ iRetcode = next_row (pData);
+
+ iY++; /* and next line */
+ }
+ /* drop the temporary row-buffer */
+ MNG_FREE (pData, pData->pRGBArow, pData->iRowsize)
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#if defined(MNG_INCLUDE_LCMS) /* cleanup cms stuff */
+ iRetcode = mng_clear_cms (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+#endif
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_IMAGE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* whehehe, this is good ! */
+}
+
+/* ************************************************************************** */
+
+mng_retcode execute_delta_image (mng_datap pData,
+ mng_imagep pTarget,
+ mng_imagep pDelta)
+{
+ mng_imagedatap pBuftarget = pTarget->pImgbuf;
+ mng_imagedatap pBufdelta = pDelta->pImgbuf;
+ mng_uint32 iY;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_START)
+#endif
+ /* actively running ? */
+ if ((pData->bRunning) && (!pData->bFreezing))
+ {
+ if (pBufdelta->bHasPLTE) /* palette in delta ? */
+ {
+ mng_uint32 iX;
+ /* new palette larger than old one ? */
+ if ((!pBuftarget->bHasPLTE) || (pBuftarget->iPLTEcount < pBufdelta->iPLTEcount))
+ pBuftarget->iPLTEcount = pBufdelta->iPLTEcount;
+ /* it's definitely got a PLTE now */
+ pBuftarget->bHasPLTE = MNG_TRUE;
+
+ for (iX = 0; iX < pBufdelta->iPLTEcount; iX++)
+ {
+ pBuftarget->aPLTEentries[iX].iRed = pBufdelta->aPLTEentries[iX].iRed;
+ pBuftarget->aPLTEentries[iX].iGreen = pBufdelta->aPLTEentries[iX].iGreen;
+ pBuftarget->aPLTEentries[iX].iBlue = pBufdelta->aPLTEentries[iX].iBlue;
+ }
+ }
+
+ if (pBufdelta->bHasTRNS) /* cheap transparency in delta ? */
+ {
+ switch (pData->iColortype) /* drop it into the target */
+ {
+ case 0: { /* gray */
+ pBuftarget->iTRNSgray = pBufdelta->iTRNSgray;
+ pBuftarget->iTRNSred = 0;
+ pBuftarget->iTRNSgreen = 0;
+ pBuftarget->iTRNSblue = 0;
+ pBuftarget->iTRNScount = 0;
+ break;
+ }
+ case 2: { /* rgb */
+ pBuftarget->iTRNSgray = 0;
+ pBuftarget->iTRNSred = pBufdelta->iTRNSred;
+ pBuftarget->iTRNSgreen = pBufdelta->iTRNSgreen;
+ pBuftarget->iTRNSblue = pBufdelta->iTRNSblue;
+ pBuftarget->iTRNScount = 0;
+ break;
+ }
+ case 3: { /* indexed */
+ pBuftarget->iTRNSgray = 0;
+ pBuftarget->iTRNSred = 0;
+ pBuftarget->iTRNSgreen = 0;
+ pBuftarget->iTRNSblue = 0;
+ /* existing range smaller than new one ? */
+ if ((!pBuftarget->bHasTRNS) || (pBuftarget->iTRNScount < pBufdelta->iTRNScount))
+ pBuftarget->iTRNScount = pBufdelta->iTRNScount;
+
+ MNG_COPY (pBuftarget->aTRNSentries, pBufdelta->aTRNSentries, pBufdelta->iTRNScount)
+ break;
+ }
+ }
+
+ pBuftarget->bHasTRNS = MNG_TRUE; /* tell it it's got a tRNS now */
+ }
+
+ if (pBufdelta->bHasBKGD) /* bkgd in source ? */
+ { /* drop it onto the target */
+ pBuftarget->bHasBKGD = MNG_TRUE;
+ pBuftarget->iBKGDindex = pBufdelta->iBKGDindex;
+ pBuftarget->iBKGDgray = pBufdelta->iBKGDgray;
+ pBuftarget->iBKGDred = pBufdelta->iBKGDred;
+ pBuftarget->iBKGDgreen = pBufdelta->iBKGDgreen;
+ pBuftarget->iBKGDblue = pBufdelta->iBKGDblue;
+ }
+
+ if (pBufdelta->bHasGAMA) /* gamma in source ? */
+ {
+ pBuftarget->bHasGAMA = MNG_TRUE; /* drop it onto the target */
+ pBuftarget->iGamma = pBufdelta->iGamma;
+ }
+
+ if (pBufdelta->bHasCHRM) /* chroma in delta ? */
+ { /* drop it onto the target */
+ pBuftarget->bHasCHRM = MNG_TRUE;
+ pBuftarget->iWhitepointx = pBufdelta->iWhitepointx;
+ pBuftarget->iWhitepointy = pBufdelta->iWhitepointy;
+ pBuftarget->iPrimaryredx = pBufdelta->iPrimaryredx;
+ pBuftarget->iPrimaryredy = pBufdelta->iPrimaryredy;
+ pBuftarget->iPrimarygreenx = pBufdelta->iPrimarygreenx;
+ pBuftarget->iPrimarygreeny = pBufdelta->iPrimarygreeny;
+ pBuftarget->iPrimarybluex = pBufdelta->iPrimarybluex;
+ pBuftarget->iPrimarybluey = pBufdelta->iPrimarybluey;
+ }
+
+ if (pBufdelta->bHasSRGB) /* sRGB in delta ? */
+ { /* drop it onto the target */
+ pBuftarget->bHasSRGB = MNG_TRUE;
+ pBuftarget->iRenderingintent = pBufdelta->iRenderingintent;
+ }
+
+ if (pBufdelta->bHasICCP) /* ICC profile in delta ? */
+ {
+ pBuftarget->bHasICCP = MNG_TRUE; /* drop it onto the target */
+
+ if (pBuftarget->pProfile) /* profile existed ? */
+ MNG_FREEX (pData, pBuftarget->pProfile, pBuftarget->iProfilesize)
+ /* allocate a buffer & copy it */
+ MNG_ALLOC (pData, pBuftarget->pProfile, pBufdelta->iProfilesize)
+ MNG_COPY (pBuftarget->pProfile, pBufdelta->pProfile, pBufdelta->iProfilesize)
+ /* store it's length as well */
+ pBuftarget->iProfilesize = pBufdelta->iProfilesize;
+ }
+ /* need to execute delta pixels ? */
+ if ((!pData->bDeltaimmediate) && (pData->iDeltatype != MNG_DELTATYPE_NOCHANGE))
+ {
+ pData->fScalerow = MNG_NULL; /* not needed by default */
+
+ switch (pBuftarget->iBitdepth) /* determine scaling routine */
+ {
+
+
+ }
+
+ pData->fDeltarow = MNG_NULL; /* let's assume there's nothing to do */
+
+ switch (pBuftarget->iColortype) /* determine delta processing routine */
+ {
+ case 0 : ;
+ case 8 : { /* gray */
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
+ (pBufdelta->iColortype == 8))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 1 : { pData->fDeltarow = (mng_fptr)delta_g1_g1; break; }
+ case 2 : { pData->fDeltarow = (mng_fptr)delta_g2_g2; break; }
+ case 4 : { pData->fDeltarow = (mng_fptr)delta_g4_g4; break; }
+ case 8 : { pData->fDeltarow = (mng_fptr)delta_g8_g8; break; }
+ case 16 : { pData->fDeltarow = (mng_fptr)delta_g16_g16; break; }
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 2 : ;
+ case 10 : { /* rgb */
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)delta_rgb8_rgb8; break; }
+ case 16 : { pData->fDeltarow = (mng_fptr)delta_rgb16_rgb16; break; }
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 3 : { /* indexed; abuse gray routines */
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 1 : { pData->fDeltarow = (mng_fptr)delta_g1_g1; break; }
+ case 2 : { pData->fDeltarow = (mng_fptr)delta_g2_g2; break; }
+ case 4 : { pData->fDeltarow = (mng_fptr)delta_g4_g4; break; }
+ case 8 : { pData->fDeltarow = (mng_fptr)delta_g8_g8; break; }
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 4 : ;
+ case 12 : { /* gray + alpha */
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 4) || (pBufdelta->iColortype == 12))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)delta_ga8_ga8; break; }
+ case 16 : { pData->fDeltarow = (mng_fptr)delta_ga16_ga16; break; }
+ }
+ }
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3) ||
+ (pBufdelta->iColortype == 8))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)delta_ga8_g8; break; }
+ case 16 : { pData->fDeltarow = (mng_fptr)delta_ga16_g16; break; }
+ }
+ }
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)delta_ga8_a8; break; }
+ case 16 : { pData->fDeltarow = (mng_fptr)delta_ga16_a16; break; }
+ }
+ }
+ }
+
+ break;
+ }
+
+ case 6 : ;
+ case 14 : { /* rgb + alpha */
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 6) || (pBufdelta->iColortype == 14))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)delta_rgba8_rgba8; break; }
+ case 16 : { pData->fDeltarow = (mng_fptr)delta_rgba16_rgba16; break; }
+ }
+ }
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 2) || (pBufdelta->iColortype == 10))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)delta_rgba8_rgb8; break; }
+ case 16 : { pData->fDeltarow = (mng_fptr)delta_rgba16_rgb16; break; }
+ }
+ }
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ {
+ if ((pBufdelta->iColortype == 0) || (pBufdelta->iColortype == 3))
+ {
+ switch (pBuftarget->iBitdepth)
+ {
+ case 8 : { pData->fDeltarow = (mng_fptr)delta_rgba8_a8; break; }
+ case 16 : { pData->fDeltarow = (mng_fptr)delta_rgba16_a16; break; }
+ }
+ }
+ }
+
+ break;
+ }
+
+ }
+
+ if (pData->fDeltarow) /* do we need to take action ? */
+ {
+ pData->iPass = -1; /* setup row dimensions and stuff */
+ pData->iRow = pData->iDeltaBlocky;
+ pData->iRowinc = 1;
+ pData->iCol = pData->iDeltaBlockx;
+ pData->iColinc = 1;
+ pData->iRowsamples = pBufdelta->iWidth;
+ pData->iRowsize = pBuftarget->iRowsize;
+ /* indicate where to retrieve & where to store */
+ pData->pRetrieveobj = (mng_objectp)pDelta;
+ pData->pStoreobj = (mng_objectp)pTarget;
+
+ if (pData->pRGBArow) /* prevent duplicate allocation! */
+ MNG_FREE (pData, pData->pRGBArow, (pData->iDatawidth << 3))
+ /* get a temporary row-buffer */
+ MNG_ALLOC (pData, pData->pRGBArow, pBufdelta->iRowsize)
+
+ iY = 0; /* this is where we start */
+ iRetcode = MNG_NOERROR; /* still oke for now */
+
+ while ((!iRetcode) && (iY < pBufdelta->iHeight))
+ { /* get a row */
+ mng_uint8p pWork = pBufdelta->pImgdata + (iY * pBufdelta->iRowsize);
+
+ MNG_COPY (pData->pRGBArow, pWork, pBufdelta->iRowsize);
+
+ if (pData->fScalerow) /* scale it (if necessary) */
+ iRetcode = ((mng_scalerow)pData->fScalerow) (pData);
+
+ if (!iRetcode) /* and... execute it */
+ iRetcode = ((mng_deltarow)pData->fDeltarow) (pData);
+
+ if (!iRetcode) /* adjust variables for next row */
+ iRetcode = next_row (pData);
+
+ iY++; /* and next line */
+ }
+ /* drop the temporary row-buffer */
+ MNG_FREE (pData, pData->pRGBArow, pBufdelta->iRowsize)
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+ else
+ MNG_ERROR (pData, MNG_INVALIDDELTA)
+
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_EXECUTE_DELTA_IMAGE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode save_state (mng_datap pData)
+{
+ mng_savedatap pSave;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_START)
+#endif
+
+ if (pData->pSavedata) /* sanity check */
+ MNG_ERROR (pData, MNG_INTERNALERROR)
+ /* get a buffer for saving */
+ MNG_ALLOC (pData, pData->pSavedata, sizeof (mng_savedata))
+
+ pSave = pData->pSavedata; /* address it more directly */
+ /* and copy global data from the main struct */
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ pSave->bHasglobalPLTE = pData->bHasglobalPLTE;
+ pSave->bHasglobalTRNS = pData->bHasglobalTRNS;
+ pSave->bHasglobalGAMA = pData->bHasglobalGAMA;
+ pSave->bHasglobalCHRM = pData->bHasglobalCHRM;
+ pSave->bHasglobalSRGB = pData->bHasglobalSRGB;
+ pSave->bHasglobalICCP = pData->bHasglobalICCP;
+ pSave->bHasglobalBKGD = pData->bHasglobalBKGD;
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+ pSave->iBACKred = pData->iBACKred;
+ pSave->iBACKgreen = pData->iBACKgreen;
+ pSave->iBACKblue = pData->iBACKblue;
+ pSave->iBACKmandatory = pData->iBACKmandatory;
+ pSave->iBACKimageid = pData->iBACKimageid;
+ pSave->iBACKtile = pData->iBACKtile;
+
+ pSave->iFRAMmode = pData->iFRAMmode;
+ pSave->iFRAMdelay = pData->iFRAMdelay;
+ pSave->iFRAMtimeout = pData->iFRAMtimeout;
+ pSave->bFRAMclipping = pData->bFRAMclipping;
+ pSave->iFRAMclipl = pData->iFRAMclipl;
+ pSave->iFRAMclipr = pData->iFRAMclipr;
+ pSave->iFRAMclipt = pData->iFRAMclipt;
+ pSave->iFRAMclipb = pData->iFRAMclipb;
+
+ pSave->iGlobalPLTEcount = pData->iGlobalPLTEcount;
+
+ MNG_COPY (pSave->aGlobalPLTEentries, pData->aGlobalPLTEentries, sizeof (mng_rgbpaltab))
+
+ pSave->iGlobalTRNSrawlen = pData->iGlobalTRNSrawlen;
+ MNG_COPY (pSave->aGlobalTRNSrawdata, pData->aGlobalTRNSrawdata, 256)
+
+ pSave->iGlobalGamma = pData->iGlobalGamma;
+
+ pSave->iGlobalWhitepointx = pData->iGlobalWhitepointx;
+ pSave->iGlobalWhitepointy = pData->iGlobalWhitepointy;
+ pSave->iGlobalPrimaryredx = pData->iGlobalPrimaryredx;
+ pSave->iGlobalPrimaryredy = pData->iGlobalPrimaryredy;
+ pSave->iGlobalPrimarygreenx = pData->iGlobalPrimarygreenx;
+ pSave->iGlobalPrimarygreeny = pData->iGlobalPrimarygreeny;
+ pSave->iGlobalPrimarybluex = pData->iGlobalPrimarybluex;
+ pSave->iGlobalPrimarybluey = pData->iGlobalPrimarybluey;
+
+ pSave->iGlobalRendintent = pData->iGlobalRendintent;
+
+ pSave->iGlobalProfilesize = pData->iGlobalProfilesize;
+
+ if (pSave->iGlobalProfilesize) /* has a profile ? */
+ { /* then copy that ! */
+ MNG_ALLOC (pData, pSave->pGlobalProfile, pSave->iGlobalProfilesize)
+ MNG_COPY (pSave->pGlobalProfile, pData->pGlobalProfile, pSave->iGlobalProfilesize)
+ }
+
+ pSave->iGlobalBKGDred = pData->iGlobalBKGDred;
+ pSave->iGlobalBKGDgreen = pData->iGlobalBKGDgreen;
+ pSave->iGlobalBKGDblue = pData->iGlobalBKGDblue;
+
+ /* freeze current image objects */
+ pImage = (mng_imagep)pData->pFirstimgobj;
+
+ while (pImage)
+ { /* freeze the object AND it's buffer */
+ pImage->bFrozen = MNG_TRUE;
+ pImage->pImgbuf->bFrozen = MNG_TRUE;
+ /* neeeext */
+ pImage = (mng_imagep)pImage->sHeader.pNext;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_SAVE_STATE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mng_reset_objzero (mng_datap pData)
+{
+ mng_imagep pImage = (mng_imagep)pData->pObjzero;
+ mng_retcode iRetcode = reset_object_details (pData, pImage, 0, 0, 0,
+ 0, 0, 0, 0, MNG_TRUE);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pImage->bVisible = MNG_TRUE;
+ pImage->bViewable = MNG_TRUE;
+ pImage->iPosx = 0;
+ pImage->iPosy = 0;
+ pImage->bClipped = MNG_FALSE;
+ pImage->iClipl = 0;
+ pImage->iClipr = 0;
+ pImage->iClipt = 0;
+ pImage->iClipb = 0;
+ pImage->iMAGN_MethodX = 0;
+ pImage->iMAGN_MethodY = 0;
+ pImage->iMAGN_MX = 0;
+ pImage->iMAGN_MY = 0;
+ pImage->iMAGN_ML = 0;
+ pImage->iMAGN_MR = 0;
+ pImage->iMAGN_MT = 0;
+ pImage->iMAGN_MB = 0;
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode restore_state (mng_datap pData)
+{
+ mng_savedatap pSave;
+ mng_imagep pImage;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_START)
+#endif
+ /* restore object 0 status !!! */
+ iRetcode = mng_reset_objzero (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* fresh cycle; fake no frames done yet */
+ pData->bFramedone = MNG_FALSE;
+
+ if (pData->pSavedata) /* do we have a saved state ? */
+ {
+ pSave = pData->pSavedata; /* address it more directly */
+ /* and copy it back to the main struct */
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ pData->bHasglobalPLTE = pSave->bHasglobalPLTE;
+ pData->bHasglobalTRNS = pSave->bHasglobalTRNS;
+ pData->bHasglobalGAMA = pSave->bHasglobalGAMA;
+ pData->bHasglobalCHRM = pSave->bHasglobalCHRM;
+ pData->bHasglobalSRGB = pSave->bHasglobalSRGB;
+ pData->bHasglobalICCP = pSave->bHasglobalICCP;
+ pData->bHasglobalBKGD = pSave->bHasglobalBKGD;
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+ pData->iBACKred = pSave->iBACKred;
+ pData->iBACKgreen = pSave->iBACKgreen;
+ pData->iBACKblue = pSave->iBACKblue;
+ pData->iBACKmandatory = pSave->iBACKmandatory;
+ pData->iBACKimageid = pSave->iBACKimageid;
+ pData->iBACKtile = pSave->iBACKtile;
+
+ pData->iFRAMmode = pSave->iFRAMmode;
+ pData->iFRAMdelay = pSave->iFRAMdelay;
+ pData->iFRAMtimeout = pSave->iFRAMtimeout;
+ pData->bFRAMclipping = pSave->bFRAMclipping;
+ pData->iFRAMclipl = pSave->iFRAMclipl;
+ pData->iFRAMclipr = pSave->iFRAMclipr;
+ pData->iFRAMclipt = pSave->iFRAMclipt;
+ pData->iFRAMclipb = pSave->iFRAMclipb;
+ /* also the next subframe parms */
+ pData->iFramemode = pSave->iFRAMmode;
+ pData->iFramedelay = pSave->iFRAMdelay;
+ pData->iFrametimeout = pSave->iFRAMtimeout;
+ pData->bFrameclipping = pSave->bFRAMclipping;
+ pData->iFrameclipl = pSave->iFRAMclipl;
+ pData->iFrameclipr = pSave->iFRAMclipr;
+ pData->iFrameclipt = pSave->iFRAMclipt;
+ pData->iFrameclipb = pSave->iFRAMclipb;
+
+ pData->iNextdelay = pSave->iFRAMdelay;
+
+ pData->iGlobalPLTEcount = pSave->iGlobalPLTEcount;
+ MNG_COPY (pData->aGlobalPLTEentries, pSave->aGlobalPLTEentries, sizeof (mng_rgbpaltab))
+
+ pData->iGlobalTRNSrawlen = pSave->iGlobalTRNSrawlen;
+ MNG_COPY (pData->aGlobalTRNSrawdata, pSave->aGlobalTRNSrawdata, 256)
+
+ pData->iGlobalGamma = pSave->iGlobalGamma;
+
+ pData->iGlobalWhitepointx = pSave->iGlobalWhitepointx;
+ pData->iGlobalWhitepointy = pSave->iGlobalWhitepointy;
+ pData->iGlobalPrimaryredx = pSave->iGlobalPrimaryredx;
+ pData->iGlobalPrimaryredy = pSave->iGlobalPrimaryredy;
+ pData->iGlobalPrimarygreenx = pSave->iGlobalPrimarygreenx;
+ pData->iGlobalPrimarygreeny = pSave->iGlobalPrimarygreeny;
+ pData->iGlobalPrimarybluex = pSave->iGlobalPrimarybluex;
+ pData->iGlobalPrimarybluey = pSave->iGlobalPrimarybluey;
+
+ pData->iGlobalRendintent = pSave->iGlobalRendintent;
+
+ pData->iGlobalProfilesize = pSave->iGlobalProfilesize;
+
+ if (pData->iGlobalProfilesize) /* has a profile ? */
+ { /* then copy that ! */
+ MNG_ALLOC (pData, pData->pGlobalProfile, pData->iGlobalProfilesize)
+ MNG_COPY (pData->pGlobalProfile, pSave->pGlobalProfile, pData->iGlobalProfilesize)
+ }
+
+ pData->iGlobalBKGDred = pSave->iGlobalBKGDred;
+ pData->iGlobalBKGDgreen = pSave->iGlobalBKGDgreen;
+ pData->iGlobalBKGDblue = pSave->iGlobalBKGDblue;
+ }
+ else /* no saved-data; so reset the lot */
+ {
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ pData->bHasglobalPLTE = MNG_FALSE;
+ pData->bHasglobalTRNS = MNG_FALSE;
+ pData->bHasglobalGAMA = MNG_FALSE;
+ pData->bHasglobalCHRM = MNG_FALSE;
+ pData->bHasglobalSRGB = MNG_FALSE;
+ pData->bHasglobalICCP = MNG_FALSE;
+ pData->bHasglobalBKGD = MNG_FALSE;
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+ if (!pData->bEMNGMAhack) /* TODO: remove line in 1.0.0 !!! */
+ { /* TODO: remove line in 1.0.0 !!! */
+ pData->iBACKred = 0;
+ pData->iBACKgreen = 0;
+ pData->iBACKblue = 0;
+ pData->iBACKmandatory = 0;
+ pData->iBACKimageid = 0;
+ pData->iBACKtile = 0;
+ } /* TODO: remove line in 1.0.0 !!! */
+
+ pData->iFRAMmode = 1;
+ pData->iFRAMdelay = 1;
+ pData->iFRAMtimeout = 0x7fffffffl;
+ pData->bFRAMclipping = MNG_FALSE;
+ pData->iFRAMclipl = 0;
+ pData->iFRAMclipr = 0;
+ pData->iFRAMclipt = 0;
+ pData->iFRAMclipb = 0;
+ /* also the next subframe parms */
+ pData->iFramemode = 1;
+ pData->iFramedelay = 1;
+ pData->iFrametimeout = 0x7fffffffl;
+ pData->bFrameclipping = MNG_FALSE;
+ pData->iFrameclipl = 0;
+ pData->iFrameclipr = 0;
+ pData->iFrameclipt = 0;
+ pData->iFrameclipb = 0;
+
+ pData->iNextdelay = 1;
+
+ pData->iGlobalPLTEcount = 0;
+
+ pData->iGlobalTRNSrawlen = 0;
+
+ pData->iGlobalGamma = 0;
+
+ pData->iGlobalWhitepointx = 0;
+ pData->iGlobalWhitepointy = 0;
+ pData->iGlobalPrimaryredx = 0;
+ pData->iGlobalPrimaryredy = 0;
+ pData->iGlobalPrimarygreenx = 0;
+ pData->iGlobalPrimarygreeny = 0;
+ pData->iGlobalPrimarybluex = 0;
+ pData->iGlobalPrimarybluey = 0;
+
+ pData->iGlobalRendintent = 0;
+
+ if (pData->iGlobalProfilesize) /* free a previous profile ? */
+ MNG_FREE (pData, pData->pGlobalProfile, pData->iGlobalProfilesize)
+
+ pData->iGlobalProfilesize = 0;
+
+ pData->iGlobalBKGDred = 0;
+ pData->iGlobalBKGDgreen = 0;
+ pData->iGlobalBKGDblue = 0;
+ }
+
+ if (!pData->bEMNGMAhack) /* TODO: remove line in 1.0.0 !!! */
+ { /* TODO: remove line in 1.0.0 !!! */
+ /* drop un-frozen image objects */
+ pImage = (mng_imagep)pData->pFirstimgobj;
+
+ while (pImage)
+ { /* is it un-frozen ? */
+ if (!pImage->bFrozen)
+ {
+ mng_imagep pPrev = (mng_imagep)pImage->sHeader.pPrev;
+ mng_imagep pNext = (mng_imagep)pImage->sHeader.pNext;
+
+ if (pPrev) /* unlink it */
+ pPrev->sHeader.pNext = pNext;
+ else
+ pData->pFirstimgobj = pNext;
+
+ if (pNext)
+ pNext->sHeader.pPrev = pPrev;
+ else
+ pData->pLastimgobj = pPrev;
+
+ if (pImage->pImgbuf->bFrozen) /* buffer frozen ? */
+ {
+ if (pImage->pImgbuf->iRefcount <= 2)
+ MNG_ERROR (pData, MNG_INTERNALERROR)
+ /* decrease ref counter */
+ pImage->pImgbuf->iRefcount--;
+ /* just cleanup the object then */
+ MNG_FREEX (pData, pImage, sizeof (mng_image))
+ }
+ else
+ { /* free the image buffer */
+ iRetcode = free_imagedataobject (pData, pImage->pImgbuf);
+ /* and cleanup the object */
+ MNG_FREEX (pData, pImage, sizeof (mng_image))
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ pImage = pNext; /* this is the next */
+ }
+ else /* neeeext */
+ pImage = (mng_imagep)pImage->sHeader.pNext;
+
+ }
+ } /* TODO: remove line in 1.0.0 !!! */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_STATE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * General display processing routine * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode process_display (mng_datap pData)
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_START)
+#endif
+
+ if (!pData->iBreakpoint) /* not broken previously ? */
+ {
+ if ((pData->iRequestframe) || (pData->iRequestlayer) || (pData->iRequesttime))
+ {
+ pData->bSearching = MNG_TRUE; /* indicate we're searching */
+
+ iRetcode = clear_canvas (pData); /* make the canvas virgin black ?!? */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* let's start from the top, shall we */
+ pData->pCurraniobj = pData->pFirstaniobj;
+ }
+ }
+
+ do /* process the objects */
+ {
+ if (pData->bSearching) /* are we looking sor something ? */
+ {
+ if ((pData->iRequestframe) &&
+ (pData->iRequestframe < ((mng_object_headerp)pData->pCurraniobj)->iFramenr))
+ {
+ pData->iRequestframe = 0; /* found the frame ! */
+ pData->bSearching = MNG_FALSE;
+ }
+ else
+ if ((pData->iRequestlayer) &&
+ (pData->iRequestlayer < ((mng_object_headerp)pData->pCurraniobj)->iLayernr))
+ {
+ pData->iRequestlayer = 0; /* found the layer ! */
+ pData->bSearching = MNG_FALSE;
+ }
+ else
+ if ((pData->iRequesttime) &&
+ (pData->iRequesttime < ((mng_object_headerp)pData->pCurraniobj)->iPlaytime))
+ {
+ pData->iRequesttime = 0; /* found the playtime ! */
+ pData->bSearching = MNG_FALSE;
+ }
+ }
+ /* do we need to finish something first ? */
+ if ((pData->iBreakpoint) && (pData->iBreakpoint < 99))
+ {
+ switch (pData->iBreakpoint) /* return to broken display routine */
+ {
+ case 1 : { iRetcode = process_display_fram2 (pData); break; }
+ case 3 : ; /* same as 4 !!! */
+ case 4 : { iRetcode = process_display_show (pData); break; }
+ case 5 : { iRetcode = process_display_clon2 (pData); break; }
+ case 9 : { iRetcode = process_display_magn2 (pData); break; }
+ default : MNG_ERROR (pData, MNG_INTERNALERROR)
+ }
+ }
+ else
+ {
+ if (pData->pCurraniobj)
+ iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
+ }
+
+ if (!pData->bTimerset) /* reset breakpoint flag ? */
+ pData->iBreakpoint = 0;
+ /* can we advance to next object ? */
+ if ((!iRetcode) && (pData->pCurraniobj) &&
+ (!pData->bTimerset) && (!pData->bSectionwait))
+ {
+ pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
+ /* MEND processing to be done ? */
+ if ((pData->eImagetype == mng_it_mng) && (!pData->pCurraniobj))
+ iRetcode = process_display_mend (pData);
+
+ if (!pData->pCurraniobj) /* refresh after last image ? */
+ pData->bNeedrefresh = MNG_TRUE;
+ }
+ } /* until error or a break or no more objects */
+ while ((!iRetcode) && (pData->pCurraniobj) &&
+ (!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bFreezing));
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* refresh needed ? */
+ if ((!pData->bTimerset) && (pData->bNeedrefresh))
+ {
+ iRetcode = display_progressive_refresh (pData, 1);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ /* timer break ? */
+ if ((pData->bTimerset) && (!pData->iBreakpoint))
+ pData->iBreakpoint = 99;
+ else
+ if (!pData->bTimerset)
+ pData->iBreakpoint = 0; /* reset if no timer break */
+
+ if ((!pData->bTimerset) && (!pData->pCurraniobj))
+ pData->bRunning = MNG_FALSE; /* all done now ! */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Chunk display processing routines * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode process_display_ihdr (mng_datap pData)
+{ /* address the current "object" if any */
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_START)
+#endif
+
+ if (!pData->bHasDHDR)
+ {
+ pData->fInitrowproc = MNG_NULL; /* do nothing by default */
+ pData->fDisplayrow = MNG_NULL;
+ pData->fCorrectrow = MNG_NULL;
+ pData->fStorerow = MNG_NULL;
+ pData->fProcessrow = MNG_NULL;
+ pData->fDifferrow = MNG_NULL;
+ pData->pStoreobj = MNG_NULL;
+ }
+
+ if (!pData->iBreakpoint) /* not previously broken ? */
+ {
+ mng_retcode iRetcode = MNG_NOERROR;
+
+ if (pData->bHasDHDR) /* is a delta-image ? */
+ {
+ if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
+ iRetcode = reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_TRUE);
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iBitdepth;
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iBitdepth;
+
+ /* process immediatly if bitdepth & colortype are equal */
+ pData->bDeltaimmediate =
+ (mng_bool)((pData->iBitdepth == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
+ (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype) );
+ }
+ else
+ {
+ if (pImage) /* update object buffer ? */
+ iRetcode = reset_object_details (pData, pImage,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_TRUE);
+ else
+ iRetcode = reset_object_details (pData, (mng_imagep)pData->pObjzero,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_TRUE);
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ if (!pData->bHasDHDR)
+ {
+ if (pImage) /* real object ? */
+ pData->pStoreobj = pImage; /* tell the row routines */
+ else /* otherwise use object 0 */
+ pData->pStoreobj = pData->pObjzero;
+ /* display "on-the-fly" ? */
+ if ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
+ (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
+ ( (pData->eImagetype == mng_it_png ) ||
+ (((mng_imagep)pData->pStoreobj)->bVisible) ) )
+ {
+ next_layer (pData); /* that's a new layer then ! */
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 2;
+ else
+ {
+ pData->iBreakpoint = 0;
+ /* anything to display ? */
+ if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
+ set_display_routine (pData); /* then determine display routine */
+ }
+ }
+ }
+
+ if (!pData->bTimerset) /* no timer break ? */
+ {
+ switch (pData->iColortype) /* determine row initialization routine */
+ {
+ case 0 : { /* gray */
+ switch (pData->iBitdepth)
+ {
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g4_i;
+
+ break;
+ }
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 2 : { /* rgb */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgb8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgb8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgb16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgb16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 3 : { /* indexed */
+ switch (pData->iBitdepth)
+ {
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx4_i;
+
+ break;
+ }
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx8_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 4 : { /* gray+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_ga8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_ga8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_ga16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_ga16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 6 : { /* rgb+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgba8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgba8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgba16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgba16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ pData->iFilterofs = 0; /* determine filter characteristics */
+ pData->iLevel0 = 0; /* default levels */
+ pData->iLevel1 = 0;
+ pData->iLevel2 = 0;
+ pData->iLevel3 = 0;
+ /* leveling & differing ? */
+/* if (pData->iFilter & 0x40)
+ {
+ switch (pData->iColortype)
+ {
+ case 0 : {
+ if (pData->iBitdepth <= 8)
+ pData->iFilterofs = 1;
+ else
+ pData->iFilterofs = 2;
+
+ break;
+ }
+ case 2 : {
+ if (pData->iBitdepth <= 8)
+ pData->iFilterofs = 3;
+ else
+ pData->iFilterofs = 6;
+
+ break;
+ }
+ case 3 : {
+ pData->iFilterofs = 1;
+ break;
+ }
+ case 4 : {
+ if (pData->iBitdepth <= 8)
+ pData->iFilterofs = 2;
+ else
+ pData->iFilterofs = 4;
+
+ break;
+ }
+ case 6 : {
+ if (pData->iBitdepth <= 8)
+ pData->iPixelofs = 5;
+ else
+ pData->iFilterofs = 8;
+
+ break;
+ }
+ }
+ } */
+ /* no adaptive filtering ? */
+/* if (pData->iFilter & 0x01)
+ pData->iPixelofs = pData->iFilterofs;
+ else */
+ pData->iPixelofs = pData->iFilterofs + 1;
+
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_idat (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata)
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_START)
+#endif
+
+ if (pData->bRestorebkgd) /* need to restore the background ? */
+ {
+ pData->bRestorebkgd = MNG_FALSE;
+ iRetcode = load_bkgdlayer (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if ((pData->bDisplaying) && (pData->bRunning))
+ pData->iLayerseq++; /* and it counts as a layer then ! */
+ }
+
+ if (pData->fInitrowproc) /* need to initialize row processing? */
+ {
+ iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
+ pData->fInitrowproc = MNG_NULL; /* only call this once !!! */
+ }
+
+ if ((!iRetcode) && (!pData->bInflating))
+ /* initialize inflate */
+ iRetcode = mngzlib_inflateinit (pData);
+
+ if (!iRetcode) /* all ok? then inflate, my man */
+ iRetcode = mngzlib_inflaterows (pData, iRawlen, pRawdata);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_iend (mng_datap pData)
+{
+ mng_retcode iRetcode, iRetcode2;
+ mng_bool bDodisplay = MNG_FALSE;
+ mng_bool bMagnify = MNG_FALSE;
+ mng_bool bCleanup = (mng_bool)(pData->iBreakpoint != 0);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_JNG /* progressive+alpha JNG can be displayed now */
+ if ( (pData->bHasJHDR ) &&
+ ( (pData->bJPEGprogressive) || (pData->bJPEGprogressive2)) &&
+ ( (pData->eImagetype == mng_it_jng ) ||
+ (((mng_imagep)pData->pStoreobj)->bVisible) ) &&
+ ( (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) ) )
+ bDodisplay = MNG_TRUE;
+#endif
+
+ if ( (pData->pStoreobj) && /* on-the-fly magnification ? */
+ ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX) ||
+ (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY) ) )
+ bMagnify = MNG_TRUE;
+
+ if ((pData->bHasBASI) || /* was it a BASI stream */
+ (bDodisplay) || /* or should we display the JNG */
+ (bMagnify) || /* or should we magnify it */
+ /* or did we get broken here last time ? */
+ ((pData->iBreakpoint) && (pData->iBreakpoint != 8)))
+ {
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage) /* or was it object 0 ? */
+ pImage = (mng_imagep)pData->pObjzero;
+ /* display it now then ? */
+ if ((pImage->bVisible) && (pImage->bViewable))
+ { /* ok, so do it */
+ iRetcode = display_image (pData, pImage, bDodisplay);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 6;
+ }
+ }
+ else
+ if ((pData->bHasDHDR) || /* was it a DHDR stream */
+ (pData->iBreakpoint == 8)) /* or did we get broken here last time ? */
+ {
+ mng_imagep pImage = (mng_imagep)pData->pDeltaImage;
+
+ if (!pData->iBreakpoint)
+ { /* perform the delta operations needed */
+ iRetcode = execute_delta_image (pData, pImage, (mng_imagep)pData->pObjzero);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ /* display it now then ? */
+ if ((pImage->bVisible) && (pImage->bViewable))
+ { /* ok, so do it */
+ iRetcode = display_image (pData, pImage, MNG_FALSE);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 8;
+ }
+ }
+
+ if (!pData->bTimerset) /* can we continue ? */
+ {
+ pData->iBreakpoint = 0; /* clear this flag now ! */
+ /* cleanup object 0 */
+ reset_object_details (pData, (mng_imagep)pData->pObjzero,
+ 0, 0, 0, 0, 0, 0, 0, MNG_TRUE);
+
+ if (pData->bInflating) /* if we've been inflating */
+ { /* cleanup row-processing, */
+ iRetcode = cleanup_rowproc (pData);
+ /* also cleanup inflate! */
+ iRetcode2 = mngzlib_inflatefree (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ if (iRetcode2)
+ return iRetcode2;
+ }
+
+#ifdef MNG_INCLUDE_JNG
+ if (pData->bJPEGdecompress) /* if we've been decompressing JDAT */
+ { /* cleanup row-processing, */
+ iRetcode = cleanup_rowproc (pData);
+ /* also cleanup decompress! */
+ iRetcode2 = mngjpeg_decompressfree (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ if (iRetcode2)
+ return iRetcode2;
+ }
+
+ if (pData->bJPEGdecompress2) /* if we've been decompressing JDAA */
+ { /* cleanup row-processing, */
+ iRetcode = cleanup_rowproc (pData);
+ /* also cleanup decompress! */
+ iRetcode2 = mngjpeg_decompressfree2 (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ if (iRetcode2)
+ return iRetcode2;
+ }
+#endif
+
+ if (bCleanup) /* if we got broken last time we need to cleanup */
+ {
+ pData->bHasIHDR = MNG_FALSE; /* IEND Q_SIGNALS the end for most ... */
+ pData->bHasBASI = MNG_FALSE;
+ pData->bHasDHDR = MNG_FALSE;
+#ifdef MNG_INCLUDE_JNG
+ pData->bHasJHDR = MNG_FALSE;
+ pData->bHasJSEP = MNG_FALSE;
+ pData->bHasJDAA = MNG_FALSE;
+ pData->bHasJDAT = MNG_FALSE;
+#endif
+ pData->bHasPLTE = MNG_FALSE;
+ pData->bHasTRNS = MNG_FALSE;
+ pData->bHasGAMA = MNG_FALSE;
+ pData->bHasCHRM = MNG_FALSE;
+ pData->bHasSRGB = MNG_FALSE;
+ pData->bHasICCP = MNG_FALSE;
+ pData->bHasBKGD = MNG_FALSE;
+ pData->bHasIDAT = MNG_FALSE;
+ }
+ /* if the image was displayed on the fly, */
+ /* we'll have to make the app refresh */
+ if ((pData->eImagetype != mng_it_mng) && (pData->fDisplayrow))
+ pData->bNeedrefresh = MNG_TRUE;
+
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_mend (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_START)
+#endif
+ /* TERM processed ? */
+ if ((pData->bDisplaying) && (pData->bRunning) &&
+ (pData->bHasTERM) && (pData->pTermaniobj))
+ {
+ mng_retcode iRetcode;
+ mng_ani_termp pTERM;
+ /* get the right animation object ! */
+ pTERM = (mng_ani_termp)pData->pTermaniobj;
+
+ pData->iIterations++; /* increase iteration count */
+
+ switch (pTERM->iTermaction) /* determine what to do! */
+ {
+ case 0 : { /* show last frame indefinitly */
+ break; /* piece of cake, that is... */
+ }
+
+ case 1 : { /* cease displaying anything */
+ pData->bFrameclipping = MNG_FALSE;
+ load_bkgdlayer (pData);
+ break;
+ }
+
+ case 2 : { /* show first image after TERM */
+
+ /* TODO: something */
+
+ break;
+ }
+
+ case 3 : { /* repeat */
+ if ((pTERM->iItermax) && (pTERM->iItermax < 0x7FFFFFFF))
+ pTERM->iItermax--;
+
+ if (pTERM->iItermax) /* go back to TERM ? */
+ { /* restore to initial or SAVE state */
+ iRetcode = restore_state (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* notify the app ? */
+ if (pData->fProcessmend)
+ {
+ mng_bool bOke = pData->fProcessmend ((mng_handle)pData,
+ pData->iIterations,
+ pTERM->iItermax);
+ if (!bOke) /* stop here and now ? */
+ break;
+ }
+ /* restart from TERM chunk */
+ pData->pCurraniobj = pTERM;
+
+ if (pTERM->iDelay) /* set the delay (?) */
+ {
+ mng_uint32 iWaitfor = 1000;
+ /* what are we aiming for */
+ if (pData->iTicks)
+ { /* honor speed modifier */
+ switch (pData->iSpeed)
+ {
+ case mng_st_fast :
+ {
+ iWaitfor = (mng_uint32)(( 500 * pTERM->iDelay) / pData->iTicks);
+ break;
+ }
+ case mng_st_slow :
+ {
+ iWaitfor = (mng_uint32)((3000 * pTERM->iDelay) / pData->iTicks);
+ break;
+ }
+ case mng_st_slowest :
+ {
+ iWaitfor = (mng_uint32)((8000 * pTERM->iDelay) / pData->iTicks);
+ break;
+ }
+ default :
+ {
+ iWaitfor = (mng_uint32)((1000 * pTERM->iDelay) / pData->iTicks);
+ }
+ }
+ }
+
+ iRetcode = display_progressive_refresh (pData, iWaitfor);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+ else
+ {
+ switch (pTERM->iIteraction)
+ {
+ case 0 : { /* show last frame indefinitly */
+ break; /* piece of cake, that is... */
+ }
+
+ case 1 : { /* cease displaying anything */
+ pData->bFrameclipping = MNG_FALSE;
+ load_bkgdlayer (pData);
+ break;
+ }
+
+ case 2 : { /* show first image after TERM */
+
+ /* TODO: something */
+
+ break;
+ }
+
+ }
+ }
+
+ break;
+ }
+
+ }
+ }
+
+ if (!pData->pCurraniobj) /* always let the app refresh at the end ! */
+ pData->bNeedrefresh = MNG_TRUE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MEND, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_defi (mng_datap pData)
+{
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_START)
+#endif
+
+ if (!pData->iDEFIobjectid) /* object id=0 ? */
+ {
+ pImage = (mng_imagep)pData->pObjzero;
+
+ if (pData->bDEFIhasdonotshow)
+ pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
+
+ if (pData->bDEFIhasloca)
+ {
+ pImage->iPosx = pData->iDEFIlocax;
+ pImage->iPosy = pData->iDEFIlocay;
+ }
+
+ if (pData->bDEFIhasclip)
+ {
+ pImage->bClipped = pData->bDEFIhasclip;
+ pImage->iClipl = pData->iDEFIclipl;
+ pImage->iClipr = pData->iDEFIclipr;
+ pImage->iClipt = pData->iDEFIclipt;
+ pImage->iClipb = pData->iDEFIclipb;
+ }
+
+ pData->pCurrentobj = 0; /* not a real object ! */
+ }
+ else
+ { /* already exists ? */
+ pImage = (mng_imagep)tqfind_imageobject (pData, pData->iDEFIobjectid);
+
+ if (!pImage) /* if not; create new */
+ {
+ mng_retcode iRetcode = create_imageobject (pData, pData->iDEFIobjectid,
+ (mng_bool)(pData->iDEFIconcrete == 1),
+ (mng_bool)(pData->iDEFIdonotshow == 0),
+ MNG_FALSE, 0, 0, 0, 0, 0, 0, 0,
+ pData->iDEFIlocax, pData->iDEFIlocay,
+ pData->bDEFIhasclip,
+ pData->iDEFIclipl, pData->iDEFIclipr,
+ pData->iDEFIclipt, pData->iDEFIclipb,
+ &pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ else
+ { /* exists; then set new info */
+ if (pData->bDEFIhasdonotshow)
+ pImage->bVisible = (mng_bool)(pData->iDEFIdonotshow == 0);
+
+ pImage->bViewable = MNG_FALSE;
+
+ if (pData->bDEFIhasloca)
+ {
+ pImage->iPosx = pData->iDEFIlocax;
+ pImage->iPosy = pData->iDEFIlocay;
+ }
+
+ if (pData->bDEFIhasclip)
+ {
+ pImage->bClipped = pData->bDEFIhasclip;
+ pImage->iClipl = pData->iDEFIclipl;
+ pImage->iClipr = pData->iDEFIclipr;
+ pImage->iClipt = pData->iDEFIclipt;
+ pImage->iClipb = pData->iDEFIclipb;
+ }
+
+ if (pData->bDEFIhasconcrete)
+ pImage->pImgbuf->bConcrete = (mng_bool)(pData->iDEFIconcrete == 1);
+ }
+
+ pData->pCurrentobj = pImage; /* others may want to know this */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DEFI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_basi (mng_datap pData,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_bool bHasalpha,
+ mng_uint16 iAlpha,
+ mng_uint8 iViewable)
+{ /* address the current "object" if any */
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_uint8p pWork;
+ mng_uint32 iX;
+ mng_imagedatap pBuf;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_START)
+#endif
+
+ if (!pImage) /* or is it an "on-the-fly" image ? */
+ pImage = (mng_imagep)pData->pObjzero;
+ /* address the object-buffer */
+ pBuf = pImage->pImgbuf;
+
+ pData->fDisplayrow = MNG_NULL; /* do nothing by default */
+ pData->fCorrectrow = MNG_NULL;
+ pData->fStorerow = MNG_NULL;
+ pData->fProcessrow = MNG_NULL;
+ /* set parms now that they're known */
+ iRetcode = reset_object_details (pData, pImage, pData->iDatawidth,
+ pData->iDataheight, pData->iBitdepth,
+ pData->iColortype, pData->iCompression,
+ pData->iFilter, pData->iInterlace, MNG_FALSE);
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* save the viewable flag */
+ pImage->bViewable = (mng_bool)(iViewable == 1);
+ pBuf->bViewable = pImage->bViewable;
+ pData->pStoreobj = pImage; /* let row-routines know which object */
+
+ pWork = pBuf->pImgdata; /* fill the object-buffer with the specified
+ "color" sample */
+ switch (pData->iColortype) /* depending on color_type & bit_depth */
+ {
+ case 0 : { /* gray */
+ if (pData->iBitdepth == 16)
+ {
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+ {
+ mng_put_uint16 (pWork, iRed);
+ pWork += 2;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+ {
+ *pWork = (mng_uint8)iRed;
+ pWork++;
+ }
+ }
+ /* force tRNS ? */
+ if ((bHasalpha) && (!iAlpha))
+ {
+ pBuf->bHasTRNS = MNG_TRUE;
+ pBuf->iTRNSgray = iRed;
+ }
+
+ break;
+ }
+
+ case 2 : { /* rgb */
+ if (pData->iBitdepth == 16)
+ {
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+ {
+ mng_put_uint16 (pWork, iRed );
+ mng_put_uint16 (pWork+2, iGreen);
+ mng_put_uint16 (pWork+4, iBlue );
+ pWork += 6;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+ {
+ *pWork = (mng_uint8)iRed;
+ *(pWork+1) = (mng_uint8)iGreen;
+ *(pWork+2) = (mng_uint8)iBlue;
+ pWork += 3;
+ }
+ }
+ /* force tRNS ? */
+ if ((bHasalpha) && (!iAlpha))
+ {
+ pBuf->bHasTRNS = MNG_TRUE;
+ pBuf->iTRNSred = iRed;
+ pBuf->iTRNSgreen = iGreen;
+ pBuf->iTRNSblue = iBlue;
+ }
+
+ break;
+ }
+
+ case 3 : { /* indexed */
+ pBuf->bHasPLTE = MNG_TRUE;
+
+ switch (pData->iBitdepth)
+ {
+ case 1 : { pBuf->iPLTEcount = 2; break; }
+ case 2 : { pBuf->iPLTEcount = 4; break; }
+ case 4 : { pBuf->iPLTEcount = 16; break; }
+ case 8 : { pBuf->iPLTEcount = 256; break; }
+ default : { pBuf->iPLTEcount = 1; break; }
+ }
+
+ pBuf->aPLTEentries [0].iRed = (mng_uint8)iRed;
+ pBuf->aPLTEentries [0].iGreen = (mng_uint8)iGreen;
+ pBuf->aPLTEentries [0].iBlue = (mng_uint8)iBlue;
+
+ for (iX = 1; iX < pBuf->iPLTEcount; iX++)
+ {
+ pBuf->aPLTEentries [iX].iRed = 0;
+ pBuf->aPLTEentries [iX].iGreen = 0;
+ pBuf->aPLTEentries [iX].iBlue = 0;
+ }
+ /* force tRNS ? */
+ if ((bHasalpha) && (iAlpha < 255))
+ {
+ pBuf->bHasTRNS = MNG_TRUE;
+ pBuf->iTRNScount = 1;
+ pBuf->aTRNSentries [0] = (mng_uint8)iAlpha;
+ }
+
+ break;
+ }
+
+ case 4 : { /* gray+alpha */
+ if (pData->iBitdepth == 16)
+ {
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+ {
+ mng_put_uint16 (pWork, iRed);
+ mng_put_uint16 (pWork+2, iAlpha);
+ pWork += 4;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+ {
+ *pWork = (mng_uint8)iRed;
+ *(pWork+1) = (mng_uint8)iAlpha;
+ pWork += 2;
+ }
+ }
+
+ break;
+ }
+
+ case 6 : { /* rgb+alpha */
+ if (pData->iBitdepth == 16)
+ {
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+ {
+ mng_put_uint16 (pWork, iRed);
+ mng_put_uint16 (pWork+2, iGreen);
+ mng_put_uint16 (pWork+4, iBlue);
+ mng_put_uint16 (pWork+6, iAlpha);
+ pWork += 8;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iDatawidth * pData->iDataheight; iX++)
+ {
+ *pWork = (mng_uint8)iRed;
+ *(pWork+1) = (mng_uint8)iGreen;
+ *(pWork+2) = (mng_uint8)iBlue;
+ *(pWork+3) = (mng_uint8)iAlpha;
+ pWork += 4;
+ }
+ }
+
+ break;
+ }
+
+ }
+
+ switch (pData->iColortype) /* determine row initialization routine */
+ { /* just to accomodate IDAT if it arrives */
+ case 0 : { /* gray */
+ switch (pData->iBitdepth)
+ {
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g4_i;
+
+ break;
+ }
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 2 : { /* rgb */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgb8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgb8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgb16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgb16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 3 : { /* indexed */
+ switch (pData->iBitdepth)
+ {
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx4_i;
+
+ break;
+ }
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx8_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 4 : { /* gray+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_ga8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_ga8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_ga16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_ga16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 6 : { /* rgb+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgba8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgba8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgba16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgba16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ pData->iFilterofs = 0; /* determine filter characteristics */
+ pData->iLevel0 = 0; /* default levels */
+ pData->iLevel1 = 0;
+ pData->iLevel2 = 0;
+ pData->iLevel3 = 0;
+ /* leveling & differing ? */
+/* if (pData->iFilter & 0x40)
+ {
+ switch (pData->iColortype)
+ {
+ case 0 : {
+ if (pData->iBitdepth <= 8)
+ pData->iFilterofs = 1;
+ else
+ pData->iFilterofs = 2;
+
+ break;
+ }
+ case 2 : {
+ if (pData->iBitdepth <= 8)
+ pData->iFilterofs = 3;
+ else
+ pData->iFilterofs = 6;
+
+ break;
+ }
+ case 3 : {
+ pData->iFilterofs = 1;
+ break;
+ }
+ case 4 : {
+ if (pData->iBitdepth <= 8)
+ pData->iFilterofs = 2;
+ else
+ pData->iFilterofs = 4;
+
+ break;
+ }
+ case 6 : {
+ if (pData->iBitdepth <= 8)
+ pData->iPixelofs = 5;
+ else
+ pData->iFilterofs = 8;
+
+ break;
+ }
+ }
+ } */
+ /* no adaptive filtering ? */
+/* if (pData->iFilter & 0x01)
+ pData->iPixelofs = pData->iFilterofs;
+ else */
+ pData->iPixelofs = pData->iFilterofs + 1;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_BASI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_clon (mng_datap pData,
+ mng_uint16 iSourceid,
+ mng_uint16 iCloneid,
+ mng_uint8 iClonetype,
+ mng_bool bHasdonotshow,
+ mng_uint8 iDonotshow,
+ mng_uint8 iConcrete,
+ mng_bool bHasloca,
+ mng_uint8 iLocationtype,
+ mng_int32 iLocationx,
+ mng_int32 iLocationy)
+{
+ mng_imagep pSource, pClone;
+ mng_bool bVisible, bAbstract;
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START)
+#endif
+ /* locate the source object first */
+ pSource = tqfind_imageobject (pData, iSourceid);
+ /* check if the clone exists */
+ pClone = tqfind_imageobject (pData, iCloneid);
+
+ if (!pSource) /* source must exist ! */
+ MNG_ERROR (pData, MNG_OBJECTUNKNOWN);
+
+ if (pClone) /* clone must not exist ! */
+ MNG_ERROR (pData, MNG_OBJECTEXISTS);
+
+ if (bHasdonotshow) /* DoNotShow flag filled ? */
+ bVisible = (mng_bool)(iDonotshow == 0);
+ else
+ bVisible = pSource->bVisible;
+
+ bAbstract = (mng_bool)(iConcrete == 1);
+
+ switch (iClonetype) /* determine action to take */
+ {
+ case 0 : { /* full clone */
+ iRetcode = clone_imageobject (pData, iCloneid, MNG_FALSE,
+ bVisible, bAbstract, bHasloca,
+ iLocationtype, iLocationx, iLocationy,
+ pSource, &pClone);
+ break;
+ }
+
+ case 1 : { /* partial clone */
+ iRetcode = clone_imageobject (pData, iCloneid, MNG_TRUE,
+ bVisible, bAbstract, bHasloca,
+ iLocationtype, iLocationx, iLocationy,
+ pSource, &pClone);
+ break;
+ }
+
+ case 2 : { /* renumber object */
+ iRetcode = renum_imageobject (pData, pSource, iCloneid,
+ bVisible, bAbstract, bHasloca,
+ iLocationtype, iLocationx, iLocationy);
+ pClone = pSource;
+ break;
+ }
+
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ /* display on the fly ? */
+ if ((pClone->bViewable) && (pClone->bVisible))
+ {
+ pData->pLastclone = pClone; /* remember in case of timer break ! */
+ /* display it */
+ display_image (pData, pClone, MNG_FALSE);
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 5;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_clon2 (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_START)
+#endif
+ /* only called after timer break ! */
+ display_image (pData, (mng_imagep)pData->pLastclone, MNG_FALSE);
+ pData->iBreakpoint = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLON, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_disc (mng_datap pData,
+ mng_uint32 iCount,
+ mng_uint16p pIds)
+{
+ mng_uint32 iX;
+ mng_imagep pImage;
+ mng_uint32 iRetcode;
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_START)
+#endif
+
+ if (iCount) /* specific list ? */
+ {
+ mng_uint16p pWork = pIds;
+
+ for (iX = 0; iX < iCount; iX++) /* iterate the list */
+ {
+ pImage = tqfind_imageobject (pData, *pWork++);
+
+ if (pImage) /* found the object ? */
+ { /* then drop it */
+ iRetcode = free_imageobject (pData, pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+ }
+ else /* empty: drop all un-frozen objects */
+ {
+ mng_imagep pNext = (mng_imagep)pData->pFirstimgobj;
+
+ while (pNext) /* any left ? */
+ {
+ pImage = pNext;
+ pNext = pImage->sHeader.pNext;
+
+ if (!pImage->bFrozen) /* not frozen ? */
+ { /* then drop it */
+ iRetcode = free_imageobject (pData, pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DISC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_fram (mng_datap pData,
+ mng_uint8 iFramemode,
+ mng_uint8 iChangedelay,
+ mng_uint32 iDelay,
+ mng_uint8 iChangetimeout,
+ mng_uint32 iTimeout,
+ mng_uint8 iChangeclipping,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START)
+#endif
+ /* advance a frame then */
+ iRetcode = next_frame (pData, iFramemode, iChangedelay, iDelay,
+ iChangetimeout, iTimeout, iChangeclipping,
+ iCliptype, iClipl, iClipr, iClipt, iClipb);
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 1;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_fram2 (mng_datap pData)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_START)
+#endif
+ /* again; after the break */
+ iRetcode = next_frame (pData, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+ pData->iBreakpoint = 0; /* not again! */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_FRAM, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_move (mng_datap pData,
+ mng_uint16 iFromid,
+ mng_uint16 iToid,
+ mng_uint8 iMovetype,
+ mng_int32 iMovex,
+ mng_int32 iMovey)
+{
+ mng_uint16 iX;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_START)
+#endif
+ /* iterate the list */
+ for (iX = iFromid; iX <= iToid; iX++)
+ {
+ if (!iX) /* object id=0 ? */
+ pImage = (mng_imagep)pData->pObjzero;
+ else
+ pImage = tqfind_imageobject (pData, iX);
+
+ if (pImage) /* object exists ? */
+ {
+ switch (iMovetype)
+ {
+ case 0 : { /* absolute */
+ pImage->iPosx = iMovex;
+ pImage->iPosy = iMovey;
+ break;
+ }
+ case 1 : { /* relative */
+ pImage->iPosx = pImage->iPosx + iMovex;
+ pImage->iPosy = pImage->iPosy + iMovey;
+ break;
+ }
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MOVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_clip (mng_datap pData,
+ mng_uint16 iFromid,
+ mng_uint16 iToid,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb)
+{
+ mng_uint16 iX;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_START)
+#endif
+ /* iterate the list */
+ for (iX = iFromid; iX <= iToid; iX++)
+ {
+ if (!iX) /* object id=0 ? */
+ pImage = (mng_imagep)pData->pObjzero;
+ else
+ pImage = tqfind_imageobject (pData, iX);
+
+ if (pImage) /* object exists ? */
+ {
+ switch (iCliptype)
+ {
+ case 0 : { /* absolute */
+ pImage->bClipped = MNG_TRUE;
+ pImage->iClipl = iClipl;
+ pImage->iClipr = iClipr;
+ pImage->iClipt = iClipt;
+ pImage->iClipb = iClipb;
+ break;
+ }
+ case 1 : { /* relative */
+ pImage->bClipped = MNG_TRUE;
+ pImage->iClipl = pImage->iClipl + iClipl;
+ pImage->iClipr = pImage->iClipr + iClipr;
+ pImage->iClipt = pImage->iClipt + iClipt;
+ pImage->iClipb = pImage->iClipb + iClipb;
+ break;
+ }
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_CLIP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_show (mng_datap pData)
+{
+ mng_int16 iX, iS, iFrom, iTo;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_START)
+#endif
+
+ /* TODO: optimization for the cases where "abs (iTo - iFrom)" is rather high;
+ especially where ((iFrom==1) && (iTo==65535)); eg. an empty SHOW !!! */
+
+ if (pData->iBreakpoint == 3) /* previously broken during cycle-mode ? */
+ {
+ pImage = tqfind_imageobject (pData, pData->iSHOWnextid);
+
+ if (pImage) /* still there ? */
+ display_image (pData, pImage, MNG_FALSE);
+
+ pData->iBreakpoint = 0; /* let's not go through this again! */
+ }
+ else
+ {
+ if (pData->iBreakpoint) /* previously broken at other point ? */
+ { /* restore last parms */
+ iFrom = (mng_int16)pData->iSHOWfromid;
+ iTo = (mng_int16)pData->iSHOWtoid;
+ iX = (mng_int16)pData->iSHOWnextid;
+ iS = (mng_int16)pData->iSHOWskip;
+ }
+ else
+ { /* regular sequence ? */
+ if (pData->iSHOWtoid >= pData->iSHOWfromid)
+ iS = 1;
+ else /* reverse sequence ! */
+ iS = -1;
+
+ iFrom = (mng_int16)pData->iSHOWfromid;
+ iTo = (mng_int16)pData->iSHOWtoid;
+ iX = iFrom;
+
+ pData->iSHOWfromid = (mng_uint16)iFrom;
+ pData->iSHOWtoid = (mng_uint16)iTo;
+ pData->iSHOWskip = iS;
+ }
+ /* cycle mode ? */
+ if ((pData->iSHOWmode == 6) || (pData->iSHOWmode == 7))
+ {
+ mng_uint16 iTrigger = 0;
+ mng_uint16 iFound = 0;
+ mng_uint16 iPass = 0;
+ mng_imagep pFound = 0;
+
+ do
+ {
+ iPass++; /* lets prevent endless loops when there
+ are no potential candidates in the list! */
+
+ if (iS > 0) /* forward ? */
+ {
+ for (iX = iFrom; iX <= iTo; iX += iS)
+ {
+ pImage = tqfind_imageobject (pData, (mng_uint16)iX);
+
+ if (pImage) /* object exists ? */
+ {
+ if (iFound) /* already found a candidate ? */
+ pImage->bVisible = MNG_FALSE;
+ else
+ if (iTrigger) /* found the trigger ? */
+ {
+ pImage->bVisible = MNG_TRUE;
+ iFound = iX;
+ pFound = pImage;
+ }
+ else
+ if (pImage->bVisible) /* ok, this is the trigger */
+ {
+ pImage->bVisible = MNG_FALSE;
+ iTrigger = iX;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (iX = iFrom; iX >= iTo; iX += iS)
+ {
+ pImage = tqfind_imageobject (pData, (mng_uint16)iX);
+
+ if (pImage) /* object exists ? */
+ {
+ if (iFound) /* already found a candidate ? */
+ pImage->bVisible = MNG_FALSE;
+ else
+ if (iTrigger) /* found the trigger ? */
+ {
+ pImage->bVisible = MNG_TRUE;
+ iFound = iX;
+ pFound = pImage;
+ }
+ else
+ if (pImage->bVisible) /* ok, this is the trigger */
+ {
+ pImage->bVisible = MNG_FALSE;
+ iTrigger = iX;
+ }
+ }
+ }
+ }
+
+ if (!iTrigger) /* did not tqfind a trigger ? */
+ iTrigger = 1; /* then fake it so the first image
+ gets nominated */
+ } /* cycle back to beginning ? */
+ while ((iPass < 2) && (iTrigger) && (!iFound));
+
+ pData->iBreakpoint = 0; /* just a sanity precaution */
+ /* display it ? */
+ if ((pData->iSHOWmode == 6) && (pFound))
+ {
+ display_image (pData, pFound, MNG_FALSE);
+
+ if (pData->bTimerset) /* timer set ? */
+ {
+ pData->iBreakpoint = 3;
+ pData->iSHOWnextid = iFound; /* save it for after the break */
+ }
+ }
+ }
+ else
+ {
+ do
+ {
+ pImage = tqfind_imageobject (pData, iX);
+
+ if (pImage) /* object exists ? */
+ {
+ if (pData->iBreakpoint) /* did we get broken last time ? */
+ { /* could only happen in the display routine */
+ display_image (pData, pImage, MNG_FALSE);
+ pData->iBreakpoint = 0; /* only once inside this loop please ! */
+ }
+ else
+ {
+ switch (pData->iSHOWmode) /* do what ? */
+ {
+ case 0 : {
+ pImage->bVisible = MNG_TRUE;
+ display_image (pData, pImage, MNG_FALSE);
+ break;
+ }
+ case 1 : {
+ pImage->bVisible = MNG_FALSE;
+ break;
+ }
+ case 2 : {
+ if (pImage->bVisible)
+ display_image (pData, pImage, MNG_FALSE);
+ break;
+ }
+ case 3 : {
+ pImage->bVisible = MNG_TRUE;
+ break;
+ }
+ case 4 : {
+ pImage->bVisible = (mng_bool)(!pImage->bVisible);
+ if (pImage->bVisible)
+ display_image (pData, pImage, MNG_FALSE);
+ break;
+ }
+ case 5 : {
+ pImage->bVisible = (mng_bool)(!pImage->bVisible);
+ }
+ }
+ }
+ }
+
+ if (!pData->bTimerset) /* next ? */
+ iX += iS;
+
+ } /* continue ? */
+ while ((!pData->bTimerset) && (((iS > 0) && (iX <= iTo)) ||
+ ((iS < 0) && (iX >= iTo)) ));
+
+ if (pData->bTimerset) /* timer set ? */
+ {
+ pData->iBreakpoint = 4;
+ pData->iSHOWnextid = iX; /* save for next time */
+ }
+ else
+ pData->iBreakpoint = 0;
+
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SHOW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_save (mng_datap pData)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_START)
+#endif
+
+ iRetcode = save_state (pData); /* save the current state */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SAVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_seek (mng_datap pData)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_START)
+#endif
+
+ iRetcode = restore_state (pData); /* restore the initial or SAVE state */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_SEEK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_retcode process_display_jhdr (mng_datap pData)
+{ /* address the current "object" if any */
+ mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_START)
+#endif
+
+ if (!pData->bHasDHDR)
+ {
+ pData->fInitrowproc = MNG_NULL; /* do nothing by default */
+ pData->fDisplayrow = MNG_NULL;
+ pData->fCorrectrow = MNG_NULL;
+ pData->fStorerow = MNG_NULL;
+ pData->fProcessrow = MNG_NULL;
+ pData->fDifferrow = MNG_NULL;
+ pData->fStorerow2 = MNG_NULL;
+ pData->fStorerow3 = MNG_NULL;
+
+ pData->pStoreobj = MNG_NULL; /* initialize important work-parms */
+
+ pData->iJPEGrow = 0;
+ pData->iJPEGalpharow = 0;
+ pData->iJPEGrgbrow = 0;
+ pData->iRowmax = 0; /* so init_rowproc does the right thing ! */
+ }
+
+ if (!pData->iBreakpoint) /* not previously broken ? */
+ {
+ if (pData->bHasDHDR) /* delta-image ? */
+ {
+ if (pData->iDeltatype == MNG_DELTATYPE_REPLACE)
+ {
+ iRetcode = reset_object_details (pData, (mng_imagep)pData->pDeltaImage,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
+ pData->iJHDRalphacompression, pData->iJHDRalphafilter,
+ pData->iJHDRalphainterlace, MNG_TRUE);
+
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphabitdepth = pData->iJHDRalphabitdepth;
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRcompression = pData->iJHDRimgcompression;
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iJHDRinterlace = pData->iJHDRimginterlace;
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
+ }
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
+ else
+ if ((pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORADD ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKCOLORREPLACE) )
+ ((mng_imagep)pData->pDeltaImage)->pImgbuf->iPixelsampledepth = pData->iJHDRimgbitdepth;
+
+ }
+ else
+ {
+ if (pImage) /* update object buffer ? */
+ {
+ iRetcode = reset_object_details (pData, pImage,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
+ pData->iJHDRalphacompression, pData->iJHDRalphafilter,
+ pData->iJHDRalphainterlace, MNG_TRUE);
+
+ pImage->pImgbuf->iAlphabitdepth = pData->iJHDRalphabitdepth;
+ pImage->pImgbuf->iJHDRcompression = pData->iJHDRimgcompression;
+ pImage->pImgbuf->iJHDRinterlace = pData->iJHDRimginterlace;
+ pImage->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
+ }
+ else /* update object 0 */
+ {
+ iRetcode = reset_object_details (pData, (mng_imagep)pData->pObjzero,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iJHDRimgbitdepth, pData->iJHDRcolortype,
+ pData->iJHDRalphacompression, pData->iJHDRalphafilter,
+ pData->iJHDRalphainterlace, MNG_TRUE);
+
+ ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphabitdepth = pData->iJHDRalphabitdepth;
+ ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRcompression = pData->iJHDRimgcompression;
+ ((mng_imagep)pData->pObjzero)->pImgbuf->iJHDRinterlace = pData->iJHDRimginterlace;
+ ((mng_imagep)pData->pObjzero)->pImgbuf->iAlphasampledepth = pData->iJHDRalphabitdepth;
+ }
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ if (!pData->bHasDHDR)
+ { /* we're always storing a JPEG */
+ if (pImage) /* real object ? */
+ pData->pStoreobj = pImage; /* tell the row routines */
+ else /* otherwise use object 0 */
+ pData->pStoreobj = pData->pObjzero;
+ /* display "on-the-fly" ? */
+ if ( (((mng_imagep)pData->pStoreobj)->iMAGN_MethodX == 0) &&
+ (((mng_imagep)pData->pStoreobj)->iMAGN_MethodY == 0) &&
+ ( (pData->eImagetype == mng_it_jng ) ||
+ (((mng_imagep)pData->pStoreobj)->bVisible) ) )
+ {
+ next_layer (pData); /* that's a new layer then ! */
+
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 7;
+ else
+ {
+ pData->iBreakpoint = 0;
+ /* anything to display ? */
+ if ((pData->iDestr > pData->iDestl) && (pData->iDestb > pData->iDestt))
+ {
+ set_display_routine (pData); /* then determine display routine */
+ /* display from the object we store in */
+ pData->pRetrieveobj = pData->pStoreobj;
+ }
+ }
+ }
+ }
+
+ if (!pData->bTimerset) /* no timer break ? */
+ { /* default row initialization ! */
+ pData->fInitrowproc = (mng_fptr)init_rowproc;
+
+ if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_REPLACE))
+ { /* 8-bit JPEG ? */
+ if (pData->iJHDRimgbitdepth == 8)
+ { /* intermediate row is 8-bit deep */
+ pData->bIsRGBA16 = MNG_FALSE;
+ pData->iRowsamples = pData->iDatawidth;
+
+ switch (pData->iJHDRcolortype) /* determine pixel processing routines */
+ {
+ case MNG_COLORTYPE_JPEGGRAY :
+ {
+ pData->fStorerow2 = (mng_fptr)store_jpeg_g8;
+ pData->fRetrieverow = (mng_fptr)retrieve_g8;
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+ case MNG_COLORTYPE_JPEGCOLOR :
+ {
+ pData->fStorerow2 = (mng_fptr)store_jpeg_rgb8;
+ pData->fRetrieverow = (mng_fptr)retrieve_rgb8;
+ pData->bIsOpaque = MNG_TRUE;
+ break;
+ }
+ case MNG_COLORTYPE_JPEGGRAYA :
+ {
+ pData->fStorerow2 = (mng_fptr)store_jpeg_ga8;
+ pData->fRetrieverow = (mng_fptr)retrieve_ga8;
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+ case MNG_COLORTYPE_JPEGCOLORA :
+ {
+ pData->fStorerow2 = (mng_fptr)store_jpeg_rgba8;
+ pData->fRetrieverow = (mng_fptr)retrieve_rgba8;
+ pData->bIsOpaque = MNG_FALSE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+ /* TODO: 12-bit JPEG */
+ /* TODO: 8- + 12-bit JPEG (eg. type=20) */
+
+ }
+ /* possible IDAT alpha-channel ? */
+ if (pData->iJHDRalphacompression == MNG_COMPRESSION_DEFLATE)
+ {
+ /* determine alpha processing routine */
+ switch (pData->iJHDRalphabitdepth)
+ {
+ case 1 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a1_ni; break; }
+ case 2 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a2_ni; break; }
+ case 4 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a4_ni; break; }
+ case 8 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a8_ni; break; }
+ case 16 : { pData->fInitrowproc = (mng_fptr)init_jpeg_a16_ni; break; }
+ }
+ }
+ else /* possible JDAA alpha-channel ? */
+ if (pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG)
+ { /* 8-bit JPEG ? */
+ if (pData->iJHDRimgbitdepth == 8)
+ {
+ if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA)
+ pData->fStorerow3 = (mng_fptr)store_jpeg_g8_alpha;
+ else
+ if (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA)
+ pData->fStorerow3 = (mng_fptr)store_jpeg_rgb8_alpha;
+ }
+ else
+ {
+ /* TODO: 12-bit JPEG with 8-bit JDAA */
+ }
+ }
+ /* initialize JPEG library */
+ iRetcode = mngjpeg_initialize (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ else
+ { /* must be alpha add/tqreplace !! */
+ if ((pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAADD ) &&
+ (pData->iDeltatype != MNG_DELTATYPE_BLOCKALPHAREPLACE) )
+ MNG_ERROR (pData, MNG_INVDELTATYPE)
+ /* determine alpha processing routine */
+ switch (pData->iJHDRalphabitdepth)
+ {
+ case 1 : { pData->fInitrowproc = (mng_fptr)init_g1_ni; break; }
+ case 2 : { pData->fInitrowproc = (mng_fptr)init_g2_ni; break; }
+ case 4 : { pData->fInitrowproc = (mng_fptr)init_g4_ni; break; }
+ case 8 : { pData->fInitrowproc = (mng_fptr)init_g8_ni; break; }
+ case 16 : { pData->fInitrowproc = (mng_fptr)init_g16_ni; break; }
+ }
+ }
+
+ pData->iFilterofs = 0; /* determine filter characteristics */
+ pData->iLevel0 = 0; /* default levels */
+ pData->iLevel1 = 0;
+ pData->iLevel2 = 0;
+ pData->iLevel3 = 0;
+ /* leveling & differing ? */
+/* if (pData->iJHDRalphafilter & 0x40)
+ {
+ if (pData->iJHDRalphabitdepth <= 8)
+ pData->iFilterofs = 1;
+ else
+ pData->iFilterofs = 2;
+
+ } */
+ /* no adaptive filtering ? */
+/* if (pData->iJHDRalphafilter & 0x01)
+ pData->iPixelofs = pData->iFilterofs;
+ else */
+ pData->iPixelofs = pData->iFilterofs + 1;
+
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_retcode process_display_jdaa (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata)
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_START)
+#endif
+
+ if (!pData->bJPEGdecompress2) /* if we're not decompressing already */
+ {
+ if (pData->fInitrowproc) /* initialize row-processing? */
+ {
+ iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
+ pData->fInitrowproc = MNG_NULL; /* only call this once !!! */
+ }
+
+ if (!iRetcode) /* initialize decompress */
+ iRetcode = mngjpeg_decompressinit2 (pData);
+ }
+
+ if (!iRetcode) /* all ok? then decompress, my man */
+ iRetcode = mngjpeg_decompressdata2 (pData, iRawlen, pRawdata);
+
+ if (iRetcode)
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_retcode process_display_jdat (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata)
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_START)
+#endif
+
+ if (pData->bRestorebkgd) /* need to restore the background ? */
+ {
+ pData->bRestorebkgd = MNG_FALSE;
+ iRetcode = load_bkgdlayer (pData);
+
+ if ((pData->bDisplaying) && (pData->bRunning))
+ pData->iLayerseq++; /* and it counts as a layer then ! */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ if (!pData->bJPEGdecompress) /* if we're not decompressing already */
+ {
+ if (pData->fInitrowproc) /* initialize row-processing? */
+ {
+ iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
+ pData->fInitrowproc = MNG_NULL; /* only call this once !!! */
+ }
+
+ if (!iRetcode) /* initialize decompress */
+ iRetcode = mngjpeg_decompressinit (pData);
+ }
+
+ if (!iRetcode) /* all ok? then decompress, my man */
+ iRetcode = mngjpeg_decompressdata (pData, iRawlen, pRawdata);
+
+ if (iRetcode)
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_JDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+mng_retcode process_display_dhdr (mng_datap pData,
+ mng_uint16 iObjectid,
+ mng_uint8 iImagetype,
+ mng_uint8 iDeltatype,
+ mng_uint32 iBlockwidth,
+ mng_uint32 iBlockheight,
+ mng_uint32 iBlockx,
+ mng_uint32 iBlocky)
+{
+ mng_imagep pImage;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_START)
+#endif
+
+ pData->fInitrowproc = MNG_NULL; /* do nothing by default */
+ pData->fDisplayrow = MNG_NULL;
+ pData->fCorrectrow = MNG_NULL;
+ pData->fStorerow = MNG_NULL;
+ pData->fProcessrow = MNG_NULL;
+ pData->pStoreobj = MNG_NULL;
+
+ pData->fDeltagetrow = MNG_NULL;
+ pData->fDeltaaddrow = MNG_NULL;
+ pData->fDeltatqreplacerow = MNG_NULL;
+ pData->fDeltaputrow = MNG_NULL;
+
+ pImage = tqfind_imageobject (pData, iObjectid);
+
+ if (pImage) /* object exists ? */
+ {
+ if (pImage->pImgbuf->bConcrete) /* is it concrete ? */
+ { /* previous magnification to be done ? */
+ if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
+ {
+ iRetcode = magnify_imageobject (pData, pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ /* save delta fields */
+ pData->pDeltaImage = (mng_ptr)pImage;
+ pData->iDeltaImagetype = iImagetype;
+ pData->iDeltatype = iDeltatype;
+ pData->iDeltaBlockwidth = iBlockwidth;
+ pData->iDeltaBlockheight = iBlockheight;
+ pData->iDeltaBlockx = iBlockx;
+ pData->iDeltaBlocky = iBlocky;
+ /* restore target-object fields */
+ pData->iDatawidth = pImage->pImgbuf->iWidth;
+ pData->iDataheight = pImage->pImgbuf->iHeight;
+ pData->iBitdepth = pImage->pImgbuf->iBitdepth;
+ pData->iColortype = pImage->pImgbuf->iColortype;
+ pData->iCompression = pImage->pImgbuf->iCompression;
+ pData->iFilter = pImage->pImgbuf->iFilter;
+ pData->iInterlace = pImage->pImgbuf->iInterlace;
+
+#ifdef MNG_INCLUDE_JNG
+ pData->iJHDRimgbitdepth = pImage->pImgbuf->iBitdepth;
+ pData->iJHDRcolortype = pImage->pImgbuf->iColortype;
+ pData->iJHDRimgcompression = pImage->pImgbuf->iJHDRcompression;
+ pData->iJHDRimginterlace = pImage->pImgbuf->iJHDRinterlace;
+ pData->iJHDRalphacompression = pImage->pImgbuf->iCompression;
+ pData->iJHDRalphafilter = pImage->pImgbuf->iFilter;
+ pData->iJHDRalphainterlace = pImage->pImgbuf->iInterlace;
+ pData->iJHDRalphabitdepth = pImage->pImgbuf->iAlphabitdepth;
+#endif
+ /* block size specified ? */
+ if (iDeltatype != MNG_DELTATYPE_NOCHANGE)
+ {
+ pData->iDatawidth = iBlockwidth;
+ pData->iDataheight = iBlockheight;
+ }
+
+ switch (iDeltatype) /* determine nr of delta-channels */
+ {
+ case MNG_DELTATYPE_BLOCKALPHAADD : ;
+ case MNG_DELTATYPE_BLOCKALPHAREPLACE :
+ {
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA) )
+ {
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+ pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
+ }
+ else
+ if ((pData->iColortype == MNG_COLORTYPE_RGBA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
+ {
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+ pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
+ }
+#else
+ if (pData->iColortype == MNG_COLORTYPE_GRAYA)
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+ else
+ if (pData->iColortype == MNG_COLORTYPE_RGBA)
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+#endif
+ else /* target has no alpha; that sucks! */
+ MNG_ERROR (pData, MNG_TARGETNOALPHA)
+
+ break;
+ }
+
+ case MNG_DELTATYPE_BLOCKCOLORADD : ;
+ case MNG_DELTATYPE_BLOCKCOLORREPLACE :
+ {
+#ifdef MNG_INCLUDE_JNG
+ if ((pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA) )
+ {
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+ pData->iJHDRcolortype = MNG_COLORTYPE_JPEGGRAY;
+ }
+ else
+ if ((pData->iColortype == MNG_COLORTYPE_RGBA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
+ {
+ pData->iColortype = MNG_COLORTYPE_RGB;
+ pData->iJHDRcolortype = MNG_COLORTYPE_JPEGCOLOR;
+ }
+#else
+ if (pData->iColortype == MNG_COLORTYPE_GRAYA)
+ pData->iColortype = MNG_COLORTYPE_GRAY;
+ else
+ if (pData->iColortype == MNG_COLORTYPE_RGBA)
+ pData->iColortype = MNG_COLORTYPE_RGB;
+#endif
+ else /* target has no alpha; that sucks! */
+ MNG_ERROR (pData, MNG_TARGETNOALPHA)
+
+ break;
+ }
+
+ }
+ /* full image tqreplace ? */
+ if (iDeltatype == MNG_DELTATYPE_REPLACE)
+ {
+ iRetcode = reset_object_details (pData, pImage,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_FALSE);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pData->pStoreobj = pImage; /* and store straight into this object */
+ }
+ else
+ {
+ mng_imagedatap pBufzero, pBuf;
+ /* we store in object 0 and process it later */
+ pData->pStoreobj = pData->pObjzero;
+ /* make sure to initialize object 0 then */
+ iRetcode = reset_object_details (pData, (mng_imagep)pData->pObjzero,
+ pData->iDatawidth, pData->iDataheight,
+ pData->iBitdepth, pData->iColortype,
+ pData->iCompression, pData->iFilter,
+ pData->iInterlace, MNG_TRUE);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pBuf = pImage->pImgbuf; /* copy possible palette & cheap transparency */
+ pBufzero = ((mng_imagep)pData->pObjzero)->pImgbuf;
+
+ pBufzero->bHasPLTE = pBuf->bHasPLTE;
+ pBufzero->bHasTRNS = pBuf->bHasTRNS;
+
+ if (pBufzero->bHasPLTE) /* copy palette ? */
+ {
+ mng_uint32 iX;
+
+ pBufzero->iPLTEcount = pBuf->iPLTEcount;
+
+ for (iX = 0; iX < pBuf->iPLTEcount; iX++)
+ {
+ pBufzero->aPLTEentries [iX].iRed = pBuf->aPLTEentries [iX].iRed;
+ pBufzero->aPLTEentries [iX].iGreen = pBuf->aPLTEentries [iX].iGreen;
+ pBufzero->aPLTEentries [iX].iBlue = pBuf->aPLTEentries [iX].iBlue;
+ }
+ }
+
+ if (pBufzero->bHasTRNS) /* copy cheap transparency ? */
+ {
+ pBufzero->iTRNSgray = pBuf->iTRNSgray;
+ pBufzero->iTRNSred = pBuf->iTRNSred;
+ pBufzero->iTRNSgreen = pBuf->iTRNSgreen;
+ pBufzero->iTRNSblue = pBuf->iTRNSblue;
+ pBufzero->iTRNScount = pBuf->iTRNScount;
+
+ MNG_COPY (pBufzero->aTRNSentries, pBuf->aTRNSentries,
+ sizeof (pBufzero->aTRNSentries))
+ }
+ /* process immediatly if bitdepth & colortype are equal */
+ pData->bDeltaimmediate =
+ (mng_bool)((pData->bDisplaying) && (pData->bRunning) &&
+ (pData->iBitdepth == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iBitdepth ) &&
+ (pData->iColortype == ((mng_imagep)pData->pDeltaImage)->pImgbuf->iColortype) );
+ }
+
+ switch (pData->iColortype) /* determine row initialization routine */
+ {
+ case 0 : { /* gray */
+ switch (pData->iBitdepth)
+ {
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g4_i;
+
+ break;
+ }
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_g16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_g16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 2 : { /* rgb */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgb8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgb8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgb16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgb16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 3 : { /* indexed */
+ switch (pData->iBitdepth)
+ {
+ case 1 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx1_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx1_i;
+
+ break;
+ }
+ case 2 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx2_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx2_i;
+
+ break;
+ }
+ case 4 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx4_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx4_i;
+
+ break;
+ }
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_idx8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_idx8_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 4 : { /* gray+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_ga8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_ga8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_ga16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_ga16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ case 6 : { /* rgb+alpha */
+ switch (pData->iBitdepth)
+ {
+ case 8 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgba8_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgba8_i;
+
+ break;
+ }
+ case 16 : {
+ if (!pData->iInterlace)
+ pData->fInitrowproc = (mng_fptr)init_rgba16_ni;
+ else
+ pData->fInitrowproc = (mng_fptr)init_rgba16_i;
+
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ else
+ MNG_ERROR (pData, MNG_OBJNOTCONCRETE)
+
+ }
+ else
+ MNG_ERROR (pData, MNG_OBJECTUNKNOWN)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_DHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_prom (mng_datap pData,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iFilltype)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_START)
+#endif
+
+
+ /* TODO: everything */
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PROM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_ipng (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_START)
+#endif
+ /* indicate it for what it is now */
+ pData->iDeltaImagetype = MNG_IMAGETYPE_PNG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IPNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_ijng (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_START)
+#endif
+ /* indicate it for what it is now */
+ pData->iDeltaImagetype = MNG_IMAGETYPE_JNG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_IJNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_pplt (mng_datap pData,
+ mng_uint8 iType,
+ mng_uint32 iCount,
+ mng_palette8ep paIndexentries,
+ mng_uint8p paAlphaentries,
+ mng_uint8p paUsedentries)
+{
+ mng_uint32 iX;
+ mng_imagep pImage = (mng_imagep)pData->pObjzero;
+ mng_imagedatap pBuf = pImage->pImgbuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_START)
+#endif
+
+ switch (iType)
+ {
+ case MNG_DELTATYPE_REPLACERGB :
+ {
+ for (iX = 0; iX < iCount; iX++)
+ {
+ if (paUsedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed = paIndexentries [iX].iRed;
+ pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
+ pBuf->aPLTEentries [iX].iBlue = paIndexentries [iX].iBlue;
+ }
+ }
+
+ break;
+ }
+ case MNG_DELTATYPE_DELTARGB :
+ {
+ for (iX = 0; iX < iCount; iX++)
+ {
+ if (paUsedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iRed +
+ paIndexentries [iX].iRed );
+ pBuf->aPLTEentries [iX].iGreen =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
+ paIndexentries [iX].iGreen);
+ pBuf->aPLTEentries [iX].iBlue =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iBlue +
+ paIndexentries [iX].iBlue );
+ }
+ }
+
+ break;
+ }
+ case MNG_DELTATYPE_REPLACEALPHA :
+ {
+ for (iX = 0; iX < iCount; iX++)
+ {
+ if (paUsedentries [iX])
+ pBuf->aTRNSentries [iX] = paAlphaentries [iX];
+ }
+
+ break;
+ }
+ case MNG_DELTATYPE_DELTAALPHA :
+ {
+ for (iX = 0; iX < iCount; iX++)
+ {
+ if (paUsedentries [iX])
+ pBuf->aTRNSentries [iX] =
+ (mng_uint8)(pBuf->aTRNSentries [iX] +
+ paAlphaentries [iX]);
+ }
+
+ break;
+ }
+ case MNG_DELTATYPE_REPLACERGBA :
+ {
+ for (iX = 0; iX < iCount; iX++)
+ {
+ if (paUsedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed = paIndexentries [iX].iRed;
+ pBuf->aPLTEentries [iX].iGreen = paIndexentries [iX].iGreen;
+ pBuf->aPLTEentries [iX].iBlue = paIndexentries [iX].iBlue;
+ pBuf->aTRNSentries [iX] = paAlphaentries [iX];
+ }
+ }
+
+ break;
+ }
+ case MNG_DELTATYPE_DELTARGBA :
+ {
+ for (iX = 0; iX < iCount; iX++)
+ {
+ if (paUsedentries [iX])
+ {
+ pBuf->aPLTEentries [iX].iRed =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iRed +
+ paIndexentries [iX].iRed );
+ pBuf->aPLTEentries [iX].iGreen =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iGreen +
+ paIndexentries [iX].iGreen);
+ pBuf->aPLTEentries [iX].iBlue =
+ (mng_uint8)(pBuf->aPLTEentries [iX].iBlue +
+ paIndexentries [iX].iBlue );
+ pBuf->aTRNSentries [iX] =
+ (mng_uint8)(pBuf->aTRNSentries [iX] +
+ paAlphaentries [iX]);
+ }
+ }
+
+ break;
+ }
+ }
+
+ if ((iType != MNG_DELTATYPE_REPLACERGB) && (iType != MNG_DELTATYPE_DELTARGB))
+ {
+ if (pBuf->bHasTRNS)
+ {
+ if (iCount > pBuf->iTRNScount)
+ pBuf->iTRNScount = iCount;
+ }
+ else
+ {
+ pBuf->iTRNScount = iCount;
+ pBuf->bHasTRNS = MNG_TRUE;
+ }
+ }
+
+ if ((iType != MNG_DELTATYPE_REPLACEALPHA) && (iType != MNG_DELTATYPE_DELTAALPHA))
+ {
+ if (iCount > pBuf->iPLTEcount)
+ pBuf->iPLTEcount = iCount;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_PPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_magn (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint16 iMethodX,
+ mng_uint16 iMX,
+ mng_uint16 iMY,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint16 iMT,
+ mng_uint16 iMB,
+ mng_uint16 iMethodY)
+{
+ mng_uint16 iX;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START)
+#endif
+ /* iterate the object-ids */
+ for (iX = iFirstid; iX <= iLastid; iX++)
+ {
+ if (iX == 0) /* process object 0 ? */
+ {
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pImage->iMAGN_MethodX = iMethodX;
+ pImage->iMAGN_MethodY = iMethodY;
+ pImage->iMAGN_MX = iMX;
+ pImage->iMAGN_MY = iMY;
+ pImage->iMAGN_ML = iML;
+ pImage->iMAGN_MR = iMR;
+ pImage->iMAGN_MT = iMT;
+ pImage->iMAGN_MB = iMB;
+ }
+ else
+ {
+ pImage = tqfind_imageobject (pData, iX);
+ /* object exists & is not frozen ? */
+ if ((pImage) && (!pImage->bFrozen))
+ { /* previous magnification to be done ? */
+ if ((pImage->iMAGN_MethodX) || (pImage->iMAGN_MethodY))
+ {
+ mng_retcode iRetcode = magnify_imageobject (pData, pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ pImage->iMAGN_MethodX = iMethodX;
+ pImage->iMAGN_MethodY = iMethodY;
+ pImage->iMAGN_MX = iMX;
+ pImage->iMAGN_MY = iMY;
+ pImage->iMAGN_ML = iML;
+ pImage->iMAGN_MR = iMR;
+ pImage->iMAGN_MT = iMT;
+ pImage->iMAGN_MB = iMB;
+ }
+ }
+ }
+
+ iX = iFirstid;
+ /* iterate again for showing */
+ while ((iX <= iLastid) && (!pData->bTimerset))
+ {
+ if (iX) /* only real objects ! */
+ {
+ pImage = tqfind_imageobject (pData, iX);
+ /* object exists & is not frozen &
+ is visible & is viewable ? */
+ if ((pImage) && (!pImage->bFrozen) &&
+ (pImage->bVisible) && (pImage->bViewable))
+ display_image (pData, pImage, MNG_FALSE);
+ }
+
+ iX++;
+ }
+
+ if (pData->bTimerset) /* broken ? */
+ {
+ pData->iMAGNfromid = iFirstid;
+ pData->iMAGNtoid = iLastid;
+ pData->iBreakpoint = 9;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_display_magn2 (mng_datap pData)
+{
+ mng_uint16 iX;
+ mng_imagep pImage;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_START)
+#endif
+
+ iX = pData->iMAGNfromid;
+ /* iterate again for showing */
+ while ((iX <= pData->iMAGNtoid) && (!pData->bTimerset))
+ {
+ if (iX) /* only real objects ! */
+ {
+ pImage = tqfind_imageobject (pData, iX);
+ /* object exists & is not frozen &
+ is visible & is viewable ? */
+ if ((pImage) && (!pImage->bFrozen) &&
+ (pImage->bVisible) && (pImage->bViewable))
+ display_image (pData, pImage, MNG_FALSE);
+ }
+
+ iX++;
+ }
+
+ if (pData->bTimerset) /* broken ? */
+ pData->iBreakpoint = 9;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_DISPLAY_MAGN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_DISPLAY_PROCS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_display.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_display.h
new file mode 100644
index 0000000..32d3b5c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_display.h
@@ -0,0 +1,195 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_display.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Display management (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the display managament routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.5.2 - 05/20/2000 - G.Juyn * */
+/* * - added JNG support stuff * */
+/* * * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - changed progressive-display processing * */
+/* * 0.5.3 - 06/22/2000 - G.Juyn * */
+/* * - added support for delta-image processing * */
+/* * - added support for PPLT chunk processing * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * 0.9.3 - 08/07/2000 - G.Juyn * */
+/* * - B111300 - fixup for improved portability * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added JDAA chunk * */
+/* * * */
+/* * 0.9.4 - 11/24/2000 - G.Juyn * */
+/* * - moved restore of object 0 to libmng_display * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_display_h_
+#define _libmng_display_h_
+
+/* ************************************************************************** */
+
+mng_retcode display_progressive_refresh (mng_datap pData,
+ mng_uint32 iInterval);
+
+/* ************************************************************************** */
+
+mng_retcode mng_reset_objzero (mng_datap pData);
+
+mng_retcode display_image (mng_datap pData,
+ mng_imagep pImage,
+ mng_bool bLayeradvanced);
+
+mng_retcode execute_delta_image (mng_datap pData,
+ mng_imagep pTarget,
+ mng_imagep pDelta);
+
+/* ************************************************************************** */
+
+mng_retcode process_display (mng_datap pData);
+
+/* ************************************************************************** */
+
+mng_retcode process_display_ihdr (mng_datap pData);
+
+mng_retcode process_display_idat (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata);
+
+mng_retcode process_display_iend (mng_datap pData);
+mng_retcode process_display_mend (mng_datap pData);
+mng_retcode process_display_defi (mng_datap pData);
+
+mng_retcode process_display_basi (mng_datap pData,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_bool bHasalpha,
+ mng_uint16 iAlpha,
+ mng_uint8 iViewable);
+
+mng_retcode process_display_clon (mng_datap pData,
+ mng_uint16 iSourceid,
+ mng_uint16 iCloneid,
+ mng_uint8 iClonetype,
+ mng_bool bHasdonotshow,
+ mng_uint8 iDonotshow,
+ mng_uint8 iConcrete,
+ mng_bool bHasloca,
+ mng_uint8 iLocationtype,
+ mng_int32 iLocationx,
+ mng_int32 iLocationy);
+mng_retcode process_display_clon2 (mng_datap pData);
+
+mng_retcode process_display_disc (mng_datap pData,
+ mng_uint32 iCount,
+ mng_uint16p pIds);
+
+mng_retcode process_display_fram (mng_datap pData,
+ mng_uint8 iFramemode,
+ mng_uint8 iChangedelay,
+ mng_uint32 iDelay,
+ mng_uint8 iChangetimeout,
+ mng_uint32 iTimeout,
+ mng_uint8 iChangeclipping,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb);
+mng_retcode process_display_fram2 (mng_datap pData);
+
+mng_retcode process_display_move (mng_datap pData,
+ mng_uint16 iFromid,
+ mng_uint16 iToid,
+ mng_uint8 iMovetype,
+ mng_int32 iMovex,
+ mng_int32 iMovey);
+
+mng_retcode process_display_clip (mng_datap pData,
+ mng_uint16 iFromid,
+ mng_uint16 iToid,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb);
+
+mng_retcode process_display_show (mng_datap pData);
+mng_retcode process_display_save (mng_datap pData);
+mng_retcode process_display_seek (mng_datap pData);
+mng_retcode process_display_jhdr (mng_datap pData);
+
+mng_retcode process_display_jdaa (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata);
+
+mng_retcode process_display_jdat (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata);
+
+mng_retcode process_display_dhdr (mng_datap pData,
+ mng_uint16 iObjectid,
+ mng_uint8 iImagetype,
+ mng_uint8 iDeltatype,
+ mng_uint32 iBlockwidth,
+ mng_uint32 iBlockheight,
+ mng_uint32 iBlockx,
+ mng_uint32 iBlocky);
+
+mng_retcode process_display_prom (mng_datap pData,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iFilltype);
+
+mng_retcode process_display_ipng (mng_datap pData);
+mng_retcode process_display_ijng (mng_datap pData);
+
+mng_retcode process_display_pplt (mng_datap pData,
+ mng_uint8 iType,
+ mng_uint32 iCount,
+ mng_palette8ep paIndexentries,
+ mng_uint8p paAlphaentries,
+ mng_uint8p paUsedentries);
+
+mng_retcode process_display_magn (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint16 iMethodX,
+ mng_uint16 iMX,
+ mng_uint16 iMY,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint16 iMT,
+ mng_uint16 iMB,
+ mng_uint16 iMethodY);
+mng_retcode process_display_magn2 (mng_datap pData);
+
+/* ************************************************************************** */
+
+#endif /* _libmng_display_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_dither.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_dither.c
new file mode 100644
index 0000000..4f308e5
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_dither.c
@@ -0,0 +1,54 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_dither.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Dithering routines (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the dithering routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_dither.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+mng_retcode dither_a_row (mng_datap pData,
+ mng_uint8p pRow)
+{
+
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
+
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_dither.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_dither.h
new file mode 100644
index 0000000..7c8ab8a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_dither.h
@@ -0,0 +1,44 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_dither.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Dithering routines (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the dithering routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_dither_h_
+#define _libmng_dither_h_
+
+/* ************************************************************************** */
+
+mng_retcode dither_a_row (mng_datap pData,
+ mng_uint8p pRow);
+
+/* ************************************************************************** */
+
+#endif /* _libmng_dither_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_error.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_error.c
new file mode 100644
index 0000000..b3e4218
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_error.c
@@ -0,0 +1,271 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_error.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.2 * */
+/* * * */
+/* * purpose : Error routines (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the general error handling routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.5.2 - 05/23/2000 - G.Juyn * */
+/* * - added error telltaling * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added errorstrings for delta-image processing * */
+/* * 0.5.2 - 05/31/2000 - G.Juyn * */
+/* * - fixed up punctuation (contributed by Tim Rowley) * */
+/* * 0.5.2 - 06/06/2000 - G.Juyn * */
+/* * - added errorstring for delayed buffer-processing * */
+/* * * */
+/* * 0.9.1 - 07/06/2000 - G.Juyn * */
+/* * - added MNG_NEEDTIMERWAIT errorstring * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - added NEEDSECTIONWAIT errorstring * */
+/* * - added macro + routine to set returncode without * */
+/* * calling error callback * */
+/* * 0.9.1 - 07/19/2000 - G.Juyn * */
+/* * - added errorstring for updatemngheader if not a MNG * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/09/2000 - G.Juyn * */
+/* * - added check for simplicity-bits in MHDR * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - fixed processing of unknown critical chunks * */
+/* * - added support for nEED * */
+/* * 0.9.3 - 10/20/2000 - G.Juyn * */
+/* * - added errorcode for delayed delta-processing * */
+/* * * */
+/* * 0.9.4 - 1/18/2001 - G.Juyn * */
+/* * - added errorcode for MAGN methods * */
+/* * * */
+/* * 1.0.2 - 06/23/2001 - G.Juyn * */
+/* * - added optimization option for MNG-video playback * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ERROR_STRINGS
+ mng_error_entry error_table [] =
+ {
+ {MNG_NOERROR, "No error"},
+ {MNG_OUTOFMEMORY, "Out of memory"},
+ {MNG_INVALIDHANDLE, "The handle is invalid"},
+ {MNG_NOCALLBACK, "A required callback is not defined"},
+ {MNG_UNEXPECTEDEOF, "Encountered unexpected end-of-file"},
+ {MNG_ZLIBERROR, "zlib encountered an error"},
+ {MNG_JPEGERROR, "ijgsrc6b encountered an error"},
+ {MNG_LCMSERROR, "lcms encountered an error"},
+ {MNG_NOOUTPUTPROFILE, "No output-profile defined for CMS"},
+ {MNG_NOSRGBPROFILE, "No sRGB-profile defined for CMS"},
+ {MNG_BUFOVERFLOW, "Internal buffer-overflow"},
+ {MNG_FUNCTIONINVALID, "Function is invalid at this point"},
+ {MNG_OUTPUTERROR, "Writing was unsuccessful; disk full?"},
+ {MNG_JPEGBUFTOOSMALL, "Internal buffer for JPEG processing too small"},
+ {MNG_NEEDMOREDATA, "Reading suspended; waiting for I/O to catch up"},
+ {MNG_NEEDTIMERWAIT, "Timer suspension; normal animation delay"},
+ {MNG_NEEDSECTIONWAIT, "SEEK suspension; application decides"},
+ {MNG_LOOPWITHCACHEOFF, "LOOP encountered when playback cache is turned off"},
+
+ {MNG_APPIOERROR, "Application signalled I/O error"},
+ {MNG_APPTIMERERROR, "Application signalled timing error"},
+ {MNG_APPCMSERROR, "Application signalled CMS error"},
+ {MNG_APPMISCERROR, "Application signalled an error"},
+ {MNG_APPTRACEABORT, "Application signalled error during trace-callback"},
+
+ {MNG_INTERNALERROR, "Internal error in libmng"},
+
+ {MNG_INVALIDSIG, "The signature is invalid"},
+ {MNG_INVALIDCRC, "The CRC for this chunk is invalid"},
+ {MNG_INVALIDLENGTH, "Chunk-length is invalid"},
+ {MNG_SETQUENCEERROR, "Chunk out of sequence"},
+ {MNG_CHUNKNOTALLOWED, "Chunk not allowed at this point"},
+ {MNG_MULTIPLEERROR, "Chunk cannot occur multiple times"},
+ {MNG_PLTEMISSING, "Missing PLTE chunk"},
+ {MNG_IDATMISSING, "Missing IDAT chunk(s)"},
+ {MNG_CANNOTBEEMPTY, "Chunk cannot be empty"},
+ {MNG_GLOBALLENGTHERR, "Global data length invalid"},
+ {MNG_INVALIDBITDEPTH, "The bit_depth is invalid"},
+ {MNG_INVALIDCOLORTYPE, "The color_type is invalid"},
+ {MNG_INVALIDCOMPRESS, "The compression_method is invalid"},
+ {MNG_INVALIDFILTER, "The filter_method or filter_type is invalid"},
+ {MNG_INVALIDINTERLACE, "The interlace_method is invalid"},
+ {MNG_NOTENOUGHIDAT, "There is not enough data in the IDAT chunk(s)"},
+ {MNG_PLTEINDEXERROR, "Palette-index out of bounds"},
+ {MNG_NULLNOTFOUND, "NULL separator not found"},
+ {MNG_KEYWORDNULL, "Keyword cannot be zero-length"},
+ {MNG_OBJECTUNKNOWN, "Object does not exist"},
+ {MNG_OBJECTEXISTS, "Object already exists"},
+ {MNG_TOOMUCHIDAT, "Too much data in IDAT chunk(s)"},
+ {MNG_INVSAMPLEDEPTH, "The sample_depth is invalid"},
+ {MNG_INVOFFSETSIZE, "The offset_type is invalid"},
+ {MNG_INVENTRYTYPE, "The entry_type is invalid"},
+ {MNG_ENDWITHNULL, "Chunk must not end with NULL byte"},
+ {MNG_INVIMAGETYPE, "The image_type is invalid"},
+ {MNG_INVDELTATYPE, "The delta_type is invalid"},
+ {MNG_INVALIDINDEX, "Index-value out of bounds"},
+ {MNG_TOOMUCHJDAT, "Too much data in JDAT chunk(s)"},
+ {MNG_JPEGPARMSERR, "JHDR parameters & JFIF-data do not match"},
+ {MNG_INVFILLMETHOD, "The fill_method is invalid"},
+ {MNG_OBJNOTCONCRETE, "Target object for DHDR must be concrete"},
+ {MNG_TARGETNOALPHA, "Target object must have alpha-channel"},
+ {MNG_MNGTOOCOMPLEX, "MHDR simplicity indicates unsupported feature(s)"},
+ {MNG_UNKNOWNCRITICAL, "Unknown critical chunk encountered"},
+ {MNG_UNSUPPORTEDNEED, "Requested nEED resources are not supported"},
+ {MNG_INVALIDDELTA, "The delta operation is invalid (mismatched color_types?)"},
+ {MNG_INVALIDMETHOD, "Method is invalid"},
+
+ {MNG_INVALIDCNVSTYLE, "Canvas_style is invalid"},
+ {MNG_WRONGCHUNK, "Attempt to access the wrong chunk"},
+ {MNG_INVALIDENTRYIX, "Attempt to access an non-existing entry"},
+ {MNG_NOHEADER, "No valid header-chunk"},
+ {MNG_NOCORRCHUNK, "Parent chunk not found"},
+ {MNG_NOMHDR, "No MNG header (MHDR) found"},
+
+ {MNG_IMAGETOOLARGE, "Image is larger than defined maximum"},
+ {MNG_NOTANANIMATION, "Image is not an animation"},
+ {MNG_FRAMENRTOOHIGH, "Framenr out of bounds"},
+ {MNG_LAYERNRTOOHIGH, "Layernr out of bounds"},
+ {MNG_PLAYTIMETOOHIGH, "Playtime out of bounds"},
+ {MNG_FNNOTIMPLEMENTED, "Function not yet implemented"},
+ {MNG_IMAGEFROZEN, "Image is frozen"},
+
+ {MNG_LCMS_NOHANDLE, "Handle could not be initialized"},
+ {MNG_LCMS_NOMEM, "No memory for gamma-table(s)"},
+ {MNG_LCMS_NOTRANS, "Transformation could not be initialized"},
+ };
+#endif /* MNG_INCLUDE_ERROR_STRINGS */
+
+/* ************************************************************************** */
+
+mng_bool mng_store_error (mng_datap pData,
+ mng_retcode iError,
+ mng_retcode iExtra1,
+ mng_retcode iExtra2)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (pData, MNG_FN_STORE_ERROR, MNG_LC_START)
+#endif
+
+ if (pData != 0)
+ {
+ pData->iErrorcode = iError; /* save also for getlasterror */
+ pData->iErrorx1 = iExtra1;
+ pData->iErrorx2 = iExtra2;
+
+#ifdef MNG_INCLUDE_ERROR_STRINGS
+ { /* binary search variables */
+ mng_int32 iTop, iLower, iUpper, iMiddle;
+ mng_error_entryp pEntry; /* pointer to found entry */
+ /* determine max index of table */
+ iTop = (sizeof (error_table) / sizeof (error_table [0])) - 1;
+
+ iLower = 0; /* initialize binary search */
+ iMiddle = iTop >> 1; /* start in the middle */
+ iUpper = iTop;
+ pEntry = 0; /* no goods yet! */
+
+ do /* the binary search itself */
+ {
+ if (error_table [iMiddle].iError < iError)
+ iLower = iMiddle + 1;
+ else if (error_table [iMiddle].iError > iError)
+ iUpper = iMiddle - 1;
+ else
+ {
+ pEntry = &error_table [iMiddle];
+ break;
+ }
+
+ iMiddle = (iLower + iUpper) >> 1;
+ }
+ while (iLower <= iUpper);
+
+ if (pEntry) /* found it ? */
+ pData->zErrortext = pEntry->zErrortext;
+ else
+ pData->zErrortext = "Unknown error";
+ }
+#else
+ pData->zErrortext = 0;
+#endif /* mng_error_telltale */
+
+ if (iError == 0) /* no error is not severe ! */
+ {
+ pData->iSeverity = 0;
+ }
+ else
+ {
+ switch (iError&0x3C00) /* determine the severity */
+ {
+ case 0x0800 : { pData->iSeverity = 5; break; }
+ case 0x1000 : { pData->iSeverity = 2; break; }
+ case 0x2000 : { pData->iSeverity = 1; break; }
+ default : { pData->iSeverity = 9; }
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (pData, MNG_FN_STORE_ERROR, MNG_LC_END)
+#endif
+
+ return MNG_TRUE;
+}
+
+/* ************************************************************************** */
+
+mng_bool mng_process_error (mng_datap pData,
+ mng_retcode iError,
+ mng_retcode iExtra1,
+ mng_retcode iExtra2)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (pData, MNG_FN_PROCESS_ERROR, MNG_LC_START)
+#endif
+
+ mng_store_error (pData, iError, iExtra1, iExtra2);
+
+ if (pData != 0)
+ {
+ if (pData->fErrorproc) /* callback defined ? */
+ return pData->fErrorproc (((mng_handle)pData), iError, pData->iSeverity,
+ pData->iChunkname, pData->iChunkseq,
+ pData->iErrorx1, pData->iErrorx2, pData->zErrortext);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (pData, MNG_FN_PROCESS_ERROR, MNG_LC_END)
+#endif
+
+ return MNG_FALSE; /* automatic failure */
+}
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_error.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_error.h
new file mode 100644
index 0000000..9ea9316
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_error.h
@@ -0,0 +1,109 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_error.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Error functions (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the generic error-codes and functions * */
+/* * * */
+/* * changes : 0.5.1 - 05/06/2000 - G.Juyn * */
+/* * - added some errorcodes * */
+/* * 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - added some errorcodes * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added application errorcodes (used with callbacks) * */
+/* * - moved chunk-access errorcodes to severity 5 * */
+/* * * */
+/* * 0.5.2 - 05/20/2000 - G.Juyn * */
+/* * - added JNG errorcodes * */
+/* * 0.5.2 - 05/23/2000 - G.Juyn * */
+/* * - added error tell-tale definition * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added errorcodes for delta-image processing * */
+/* * 0.5.2 - 06/06/2000 - G.Juyn * */
+/* * - added errorcode for delayed buffer-processing * */
+/* * - moved errorcodes to "libmng.h" * */
+/* * * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - added macro + routine to set returncode without * */
+/* * calling error callback * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_error_h_
+#define _libmng_error_h_
+
+/* ************************************************************************** */
+/* * * */
+/* * Default error routines * */
+/* * * */
+/* ************************************************************************** */
+
+mng_bool mng_store_error (mng_datap pData,
+ mng_retcode iError,
+ mng_retcode iExtra1,
+ mng_retcode iExtra2);
+
+mng_bool mng_process_error (mng_datap pData,
+ mng_retcode iError,
+ mng_retcode iExtra1,
+ mng_retcode iExtra2);
+
+/* ************************************************************************** */
+/* * * */
+/* * Error handling macros * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_ERROR(D,C) { mng_process_error (D, C, 0, 0); return C; }
+#define MNG_ERRORZ(D,Z) { mng_process_error (D, MNG_ZLIBERROR, Z, 0); return MNG_ZLIBERROR; }
+#define MNG_ERRORJ(D,J) { mng_process_error (D, MNG_JPEGERROR, J, 0); return MNG_JPEGERROR; }
+#define MNG_ERRORL(D,L) { mng_process_error (D, MNG_LCMSERROR, L, 0); return MNG_LCMSERROR; }
+
+#define MNG_RETURN(D,C) { mng_store_error (D, C, 0, 0); return C; }
+
+#define MNG_WARNING(D,C) { if (!mng_process_error (D, C, 0, 0)) return C; }
+
+#define MNG_VALIDHANDLE(H) { if ((H == 0) || (((mng_datap)H)->iMagic != MNG_MAGIC)) \
+ return MNG_INVALIDHANDLE; }
+#define MNG_VALIDHANDLEX(H) { if ((H == 0) || (((mng_datap)H)->iMagic != MNG_MAGIC)) \
+ return 0; }
+#define MNG_VALIDCB(D,C) { if (!((mng_datap)D)->C) \
+ MNG_ERROR (((mng_datap)D), MNG_NOCALLBACK) }
+
+/* ************************************************************************** */
+/* * * */
+/* * Error string-table entry * */
+/* * * */
+/* ************************************************************************** */
+
+typedef struct {
+ mng_retcode iError;
+ mng_pchar zErrortext;
+ } mng_error_entry;
+typedef mng_error_entry * mng_error_entryp;
+
+/* ************************************************************************** */
+
+#endif /* _libmng_error_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_filter.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_filter.c
new file mode 100644
index 0000000..a055f5c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_filter.c
@@ -0,0 +1,890 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_filter.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Filtering routines (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the filtering routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_filter.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_FILTERS
+
+/* ************************************************************************** */
+
+mng_retcode filter_a_row (mng_datap pData)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FILTER_A_ROW, MNG_LC_START)
+#endif
+
+ switch (*(pData->pWorkrow + pData->iFilterofs))
+ {
+ case 1 : {
+ iRetcode = filter_sub (pData);
+ break;
+ }
+ case 2 : {
+ iRetcode = filter_up (pData);
+ break;
+ }
+ case 3 : {
+ iRetcode = filter_average (pData);
+ break;
+ }
+ case 4 : {
+ iRetcode = filter_paeth (pData);
+ break;
+ }
+
+ default : iRetcode = MNG_INVALIDFILTER;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FILTER_A_ROW, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+mng_retcode filter_sub (mng_datap pData)
+{
+ mng_uint32 iBpp;
+ mng_uint8p pRawx;
+ mng_uint8p pRawx_prev;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FILTER_SUB, MNG_LC_START)
+#endif
+
+ iBpp = pData->iFilterbpp;
+ pRawx = pData->pWorkrow + pData->iPixelofs + iBpp;
+ pRawx_prev = pData->pWorkrow + pData->iPixelofs;
+
+ for (iX = iBpp; iX < pData->iRowsize; iX++)
+ {
+ *pRawx = (mng_uint8)(*pRawx + *pRawx_prev);
+ pRawx++;
+ pRawx_prev++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FILTER_SUB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode filter_up (mng_datap pData)
+{
+ mng_uint8p pRawx;
+ mng_uint8p pPriorx;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FILTER_UP, MNG_LC_START)
+#endif
+
+ pRawx = pData->pWorkrow + pData->iPixelofs;
+ pPriorx = pData->pPrevrow + pData->iPixelofs;
+
+ for (iX = 0; iX < pData->iRowsize; iX++)
+ {
+ *pRawx = (mng_uint8)(*pRawx + *pPriorx);
+ pRawx++;
+ pPriorx++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FILTER_UP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode filter_average (mng_datap pData)
+{
+ mng_int32 iBpp;
+ mng_uint8p pRawx;
+ mng_uint8p pRawx_prev;
+ mng_uint8p pPriorx;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FILTER_AVERAGE, MNG_LC_START)
+#endif
+
+ iBpp = pData->iFilterbpp;
+ pRawx = pData->pWorkrow + pData->iPixelofs;
+ pPriorx = pData->pPrevrow + pData->iPixelofs;
+ pRawx_prev = pData->pWorkrow + pData->iPixelofs;
+
+ for (iX = 0; iX < iBpp; iX++)
+ {
+ *pRawx = (mng_uint8)(*pRawx + ((*pPriorx) >> 1));
+ pRawx++;
+ pPriorx++;
+ }
+
+ for (iX = iBpp; iX < pData->iRowsize; iX++)
+ {
+ *pRawx = (mng_uint8)(*pRawx + ((*pRawx_prev + *pPriorx) >> 1));
+ pRawx++;
+ pPriorx++;
+ pRawx_prev++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FILTER_AVERAGE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode filter_paeth (mng_datap pData)
+{
+ mng_int32 iBpp;
+ mng_uint8p pRawx;
+ mng_uint8p pRawx_prev;
+ mng_uint8p pPriorx;
+ mng_uint8p pPriorx_prev;
+ mng_int32 iX;
+ mng_uint32 iA, iB, iC;
+ mng_uint32 iP;
+ mng_uint32 iPa, iPb, iPc;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FILTER_PAETH, MNG_LC_START)
+#endif
+
+ iBpp = pData->iFilterbpp;
+ pRawx = pData->pWorkrow + pData->iPixelofs;
+ pPriorx = pData->pPrevrow + pData->iPixelofs;
+ pRawx_prev = pData->pWorkrow + pData->iPixelofs;
+ pPriorx_prev = pData->pPrevrow + pData->iPixelofs;
+
+ for (iX = 0; iX < iBpp; iX++)
+ {
+ *pRawx = (mng_uint8)(*pRawx + *pPriorx);
+
+ pRawx++;
+ pPriorx++;
+ }
+
+ for (iX = iBpp; iX < pData->iRowsize; iX++)
+ {
+ iA = (mng_uint32)*pRawx_prev;
+ iB = (mng_uint32)*pPriorx;
+ iC = (mng_uint32)*pPriorx_prev;
+ iP = iA + iB - iC;
+ iPa = abs (iP - iA);
+ iPb = abs (iP - iB);
+ iPc = abs (iP - iC);
+
+ if ((iPa <= iPb) && (iPa <= iPc))
+ *pRawx = (mng_uint8)(*pRawx + iA);
+ else
+ if (iPb <= iPc)
+ *pRawx = (mng_uint8)(*pRawx + iB);
+ else
+ *pRawx = (mng_uint8)(*pRawx + iC);
+
+ pRawx++;
+ pPriorx++;
+ pRawx_prev++;
+ pPriorx_prev++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FILTER_PAETH, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode init_rowdiffering (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ROWDIFFERING, MNG_LC_START)
+#endif
+
+ if (pData->iFilter & 0x40) /* has leveling parameters ? */
+ {
+ switch (pData->iColortype) /* salvage leveling parameters */
+ {
+ case 0 : { /* gray */
+ if (pData->iBitdepth <= 8)
+ pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
+ else
+ pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
+
+ break;
+ }
+ case 2 : { /* rgb */
+ if (pData->iBitdepth <= 8)
+ {
+ pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
+ pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
+ pData->iLevel2 = (mng_uint16)*(pData->pWorkrow+2);
+ }
+ else
+ {
+ pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
+ pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
+ pData->iLevel2 = mng_get_uint16 (pData->pWorkrow+4);
+ }
+
+ break;
+ }
+ case 3 : { /* indexed */
+ pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
+ break;
+ }
+ case 4 : { /* gray+alpha */
+ if (pData->iBitdepth <= 8)
+ {
+ pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
+ pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
+ }
+ else
+ {
+ pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
+ pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
+ }
+
+ break;
+ }
+ case 6 : { /* rgb+alpha */
+ if (pData->iBitdepth <= 8)
+ {
+ pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
+ pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
+ pData->iLevel2 = (mng_uint16)*(pData->pWorkrow+2);
+ pData->iLevel3 = (mng_uint16)*(pData->pWorkrow+3);
+ }
+ else
+ {
+ pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
+ pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
+ pData->iLevel2 = mng_get_uint16 (pData->pWorkrow+4);
+ pData->iLevel3 = mng_get_uint16 (pData->pWorkrow+6);
+ }
+
+ break;
+ }
+ }
+ }
+ /* shift the entire row back in place */
+ pRawi = pData->pWorkrow + pData->iFilterofs;
+ pRawo = pData->pWorkrow;
+
+ for (iX = 0; iX < pData->iRowsize + pData->iPixelofs - pData->iFilterofs; iX++)
+ *pRawo++ = *pRawi++;
+
+ pData->iFilterofs = 0; /* indicate so ! */
+
+ if (pData->iFilter & 0x01) /* no adaptive filtering ? */
+ pData->iPixelofs = pData->iFilterofs;
+ else
+ pData->iPixelofs = pData->iFilterofs + 1;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ROWDIFFERING, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_g1 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_G1, MNG_LC_START)
+#endif
+
+ if (pData->iLevel0 & 0x01) /* is it uneven level ? */
+ {
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+ /* just invert every bit */
+ for (iX = 0; iX < pData->iRowsize; iX++)
+ *pRawo++ = (mng_uint8)(~(*pRawi++));
+
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_G1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_g2 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+ mng_int32 iC, iS;
+ mng_uint8 iB, iN, iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_G2, MNG_LC_START)
+#endif
+
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+ iC = 0;
+ iB = 0;
+ iN = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iC)
+ {
+ iC = 4;
+ iB = *pRawi++;
+ iN = 0;
+ iS = 8;
+ }
+
+ iS -= 2;
+ iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x03);
+ iN = (mng_uint8)((iN << 2) + iQ);
+ iC--;
+
+ if (!iC)
+ *pRawo++ = iN;
+
+ }
+
+ if (iC)
+ *pRawo = (mng_uint8)(iN << iS);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_G2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_g4 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+ mng_int32 iC, iS;
+ mng_uint8 iB, iN, iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_G4, MNG_LC_START)
+#endif
+
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+ iC = 0;
+ iB = 0;
+ iN = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iC)
+ {
+ iC = 2;
+ iB = *pRawi++;
+ iN = 0;
+ iS = 8;
+ }
+
+ iS -= 4;
+ iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x0F);
+ iN = (mng_uint8)((iN << 4) + iQ);
+ iC--;
+
+ if (!iC)
+ *pRawo++ = iN;
+
+ }
+
+ if (iC)
+ *pRawo = (mng_uint8)(iN << iS);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_G4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_g8 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_G8, MNG_LC_START)
+#endif
+
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pRawo++ = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
+
+ pRawi++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_G8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_g16 (mng_datap pData)
+{
+ mng_uint16p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_G16, MNG_LC_START)
+#endif
+
+ pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
+ pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pRawo++ = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0) & 0xFFFF);
+
+ pRawi++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_G16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_rgb8 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_RGB8, MNG_LC_START)
+#endif
+
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
+ *pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0 +
+ (mng_uint16)*(pRawo+1)) & 0xFF);
+ *(pRawo+2) = (mng_uint8)(((mng_uint16)*(pRawi+2) + pData->iLevel2 +
+ (mng_uint16)*(pRawo+1)) & 0xFF);
+
+ pRawi += 3;
+ pRawo += 3;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_RGB8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_rgb16 (mng_datap pData)
+{
+ mng_uint16p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_RGB16, MNG_LC_START)
+#endif
+
+ pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
+ pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
+ *pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0 +
+ (mng_uint32)*(pRawo+1)) & 0xFFFF);
+ *(pRawo+2) = (mng_uint16)(((mng_uint32)*(pRawi+2) + (mng_uint32)pData->iLevel2 +
+ (mng_uint32)*(pRawo+1)) & 0xFFFF);
+
+ pRawi += 3;
+ pRawo += 3;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_RGB16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_idx1 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_IDX1, MNG_LC_START)
+#endif
+
+ if (pData->iLevel0 & 0x01) /* is it uneven level ? */
+ {
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+ /* just invert every bit */
+ for (iX = 0; iX < pData->iRowsize; iX++)
+ *pRawo++ = (mng_uint8)(~(*pRawi++));
+
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_IDX1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_idx2 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+ mng_int32 iC, iS;
+ mng_uint8 iB, iN, iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_IDX2, MNG_LC_START)
+#endif
+
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+ iC = 0;
+ iB = 0;
+ iN = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iC)
+ {
+ iC = 4;
+ iB = *pRawi++;
+ iN = 0;
+ iS = 8;
+ }
+
+ iS -= 2;
+ iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x03);
+ iN = (mng_uint8)((iN << 2) + iQ);
+ iC--;
+
+ if (!iC)
+ *pRawo++ = iN;
+
+ }
+
+ if (iC)
+ *pRawo = (mng_uint8)(iN << iS);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_IDX2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_idx4 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+ mng_int32 iC, iS;
+ mng_uint8 iB, iN, iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_IDX4, MNG_LC_START)
+#endif
+
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+ iC = 0;
+ iB = 0;
+ iN = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iC)
+ {
+ iC = 2;
+ iB = *pRawi++;
+ iN = 0;
+ iS = 8;
+ }
+
+ iS -= 4;
+ iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x0F);
+ iN = (mng_uint8)((iN << 4) + iQ);
+ iC--;
+
+ if (!iC)
+ *pRawo++ = iN;
+
+ }
+
+ if (iC)
+ *pRawo = (mng_uint8)(iN << iS);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_IDX4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_idx8 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_IDX8, MNG_LC_START)
+#endif
+
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pRawo++ = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
+
+ pRawi++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_IDX8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_ga8 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_GA8, MNG_LC_START)
+#endif
+
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
+ *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
+
+ pRawi += 2;
+ pRawo += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_GA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_ga16 (mng_datap pData)
+{
+ mng_uint16p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_GA16, MNG_LC_START)
+#endif
+
+ pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
+ pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0) & 0xFFFF);
+ *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
+
+ pRawi += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_GA16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_rgba8 (mng_datap pData)
+{
+ mng_uint8p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_RGBA8, MNG_LC_START)
+#endif
+
+ pRawi = pData->pWorkrow + pData->iPixelofs;
+ pRawo = pData->pPrevrow + pData->iPixelofs;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
+ *pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0 +
+ (mng_uint16)*(pRawo+1)) & 0xFF);
+ *(pRawo+2) = (mng_uint8)(((mng_uint16)*(pRawi+2) + pData->iLevel2 +
+ (mng_uint16)*(pRawo+1)) & 0xFF);
+ *(pRawo+3) = (mng_uint8)(((mng_uint16)*(pRawi+3) + pData->iLevel3) & 0xFF);
+
+ pRawi += 4;
+ pRawo += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_RGBA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode differ_rgba16 (mng_datap pData)
+{
+ mng_uint16p pRawi, pRawo;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_RGBA16, MNG_LC_START)
+#endif
+
+ pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
+ pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
+ *pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0 +
+ (mng_uint32)*(pRawo+1)) & 0xFFFF);
+ *(pRawo+2) = (mng_uint16)(((mng_uint32)*(pRawi+2) + (mng_uint32)pData->iLevel2 +
+ (mng_uint32)*(pRawo+1)) & 0xFFFF);
+ *(pRawo+3) = (mng_uint16)(((mng_uint32)*(pRawi+3) + (mng_uint32)pData->iLevel3) & 0xFFFF);
+
+ pRawi += 4;
+ pRawo += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DIFFER_RGBA16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_FILTERS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_filter.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_filter.h
new file mode 100644
index 0000000..2c8c61d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_filter.h
@@ -0,0 +1,71 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_filter.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Filtering routines (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the filtering routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_filter_h_
+#define _libmng_filter_h_
+
+/* ************************************************************************** */
+
+mng_retcode filter_a_row (mng_datap pData);
+
+mng_retcode filter_sub (mng_datap pData);
+mng_retcode filter_up (mng_datap pData);
+mng_retcode filter_average (mng_datap pData);
+mng_retcode filter_paeth (mng_datap pData);
+
+/* ************************************************************************** */
+
+mng_retcode init_rowdiffering (mng_datap pData);
+
+mng_retcode differ_g1 (mng_datap pData);
+mng_retcode differ_g2 (mng_datap pData);
+mng_retcode differ_g4 (mng_datap pData);
+mng_retcode differ_g8 (mng_datap pData);
+mng_retcode differ_g16 (mng_datap pData);
+mng_retcode differ_rgb8 (mng_datap pData);
+mng_retcode differ_rgb16 (mng_datap pData);
+mng_retcode differ_idx1 (mng_datap pData);
+mng_retcode differ_idx2 (mng_datap pData);
+mng_retcode differ_idx4 (mng_datap pData);
+mng_retcode differ_idx8 (mng_datap pData);
+mng_retcode differ_ga8 (mng_datap pData);
+mng_retcode differ_ga16 (mng_datap pData);
+mng_retcode differ_rgba8 (mng_datap pData);
+mng_retcode differ_rgba16 (mng_datap pData);
+
+/* ************************************************************************** */
+
+#endif /* _libmng_filter_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_hlapi.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_hlapi.c
new file mode 100644
index 0000000..22c113f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_hlapi.c
@@ -0,0 +1,1814 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_hlapi.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.2 * */
+/* * * */
+/* * purpose : high-level application API (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the high-level function interface * */
+/* * for applications. * */
+/* * * */
+/* * changes : 0.5.1 - 05/06/2000 - G.Juyn * */
+/* * - added init of iPLTEcount * */
+/* * 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed calling-convention definition * */
+/* * - changed status-handling of display-routines * */
+/* * - added versioning-control routines * */
+/* * - filled the write routine * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added callback error-reporting support * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * 0.5.1 - 05/13/2000 - G.Juyn * */
+/* * - added eMNGma hack (will be removed in 1.0.0 !!!) * */
+/* * - added TERM animation object pointer (easier reference) * */
+/* * 0.5.1 - 05/14/2000 - G.Juyn * */
+/* * - added cleanup of saved-data (SAVE/SEEK processing) * */
+/* * 0.5.1 - 05/16/2000 - G.Juyn * */
+/* * - moved the actual write_graphic functionality from here * */
+/* * to it's appropriate function in the mng_write module * */
+/* * * */
+/* * 0.5.2 - 05/19/2000 - G.Juyn * */
+/* * - cleaned up some code regarding mixed support * */
+/* * - added JNG support * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - moved init of default zlib parms here from "mng_zlib.c" * */
+/* * - added init of default IJG parms * */
+/* * 0.5.2 - 05/29/2000 - G.Juyn * */
+/* * - fixed inconsistancy with freeing global iCCP profile * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added delta-image field initialization * */
+/* * 0.5.2 - 06/06/2000 - G.Juyn * */
+/* * - added initialization of the buffer-suspend parameter * */
+/* * * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - added initialization of update-region for refresh * */
+/* * - added initialization of Needrefresh parameter * */
+/* * 0.5.3 - 06/17/2000 - G.Juyn * */
+/* * - added initialization of Deltaimmediate * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added initialization of Speed * */
+/* * - added initialization of Imagelevel * */
+/* * 0.5.3 - 06/26/2000 - G.Juyn * */
+/* * - changed userdata variable to mng_ptr * */
+/* * 0.5.3 - 06/29/2000 - G.Juyn * */
+/* * - fixed initialization routine for new mng_handle type * */
+/* * * */
+/* * 0.9.1 - 07/06/2000 - G.Juyn * */
+/* * - changed mng_display_resume to allow to be called after * */
+/* * a suspension return with MNG_NEEDMOREDATA * */
+/* * - added returncode MNG_NEEDTIMERWAIT for timer breaks * */
+/* * 0.9.1 - 07/07/2000 - G.Juyn * */
+/* * - implemented support for freeze/reset/resume & go_xxxx * */
+/* * 0.9.1 - 07/08/2000 - G.Juyn * */
+/* * - added support for improved timing * */
+/* * - added support for improved I/O-suspension * */
+/* * 0.9.1 - 07/14/2000 - G.Juyn * */
+/* * - changed EOF processing behavior * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - added callbacks for SAVE/SEEK processing * */
+/* * - added variable for NEEDSECTIONWAIT breaks * */
+/* * - added variable for freeze & reset processing * */
+/* * 0.9.1 - 07/17/2000 - G.Juyn * */
+/* * - added error cleanup processing * */
+/* * - fixed support for mng_display_reset() * */
+/* * - fixed suspension-buffering for 32K+ chunks * */
+/* * * */
+/* * 0.9.2 - 07/29/2000 - G.Juyn * */
+/* * - fixed small bugs in display processing * */
+/* * 0.9.2 - 07/31/2000 - G.Juyn * */
+/* * - fixed wrapping of suspension parameters * */
+/* * 0.9.2 - 08/04/2000 - G.Juyn * */
+/* * - B111096 - fixed large-buffer read-suspension * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * 0.9.3 - 09/10/2000 - G.Juyn * */
+/* * - fixed DEFI behavior * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - added support for nEED * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added optional support for bKGD for PNG images * */
+/* * - raised initial maximum canvas size * */
+/* * - added support for JDAA * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - added callback to process non-critical unknown chunks * */
+/* * - fixed support for delta-images during read() / display() * */
+/* * 0.9.3 - 10/18/2000 - G.Juyn * */
+/* * - added closestream() processing for mng_cleanup() * */
+/* * 0.9.3 - 10/27/2000 - G.Juyn * */
+/* * - fixed seperate read() & display() processing * */
+/* * * */
+/* * 0.9.4 - 11/20/2000 - G.Juyn * */
+/* * - fixed unwanted repetition in mng_readdisplay() * */
+/* * 0.9.4 - 11/24/2000 - G.Juyn * */
+/* * - moved restore of object 0 to libmng_display * */
+/* * * */
+/* * 1.0.1 - 02/08/2001 - G.Juyn * */
+/* * - added MEND processing callback * */
+/* * 1.0.1 - 02/13/2001 - G.Juyn * */
+/* * - fixed first FRAM_MODE=4 timing problem * */
+/* * 1.0.1 - 04/21/2001 - G.Juyn * */
+/* * - fixed bug with display_reset/display_resume (Thanks G!) * */
+/* * 1.0.1 - 04/22/2001 - G.Juyn * */
+/* * - fixed memory-leak (Thanks Gregg!) * */
+/* * 1.0.1 - 04/23/2001 - G.Juyn * */
+/* * - fixed reset_rundata to drop all objects * */
+/* * 1.0.1 - 04/25/2001 - G.Juyn * */
+/* * - moved mng_clear_cms to libmng_cms * */
+/* * * */
+/* * 1.0.2 - 06/23/2001 - G.Juyn * */
+/* * - added optimization option for MNG-video playback * */
+/* * - added processterm callback * */
+/* * 1.0.2 - 06/25/2001 - G.Juyn * */
+/* * - added option to turn off progressive refresh * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_objects.h"
+#include "libmng_object_prc.h"
+#include "libmng_chunks.h"
+#include "libmng_memory.h"
+#include "libmng_read.h"
+#include "libmng_write.h"
+#include "libmng_display.h"
+#include "libmng_zlib.h"
+#include "libmng_jpeg.h"
+#include "libmng_cms.h"
+#include "libmng_pixels.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * local routines * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+mng_retcode mng_drop_chunks (mng_datap pData)
+{
+ mng_chunkp pChunk;
+ mng_chunkp pNext;
+ mng_cleanupchunk fCleanup;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DROP_CHUNKS, MNG_LC_START)
+#endif
+
+ pChunk = pData->pFirstchunk; /* and get first stored chunk (if any) */
+
+ while (pChunk) /* more chunks to discard ? */
+ {
+ pNext = ((mng_chunk_headerp)pChunk)->pNext;
+ /* call appropriate cleanup */
+ fCleanup = ((mng_chunk_headerp)pChunk)->fCleanup;
+ fCleanup (pData, pChunk);
+
+ pChunk = pNext; /* neeeext */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DROP_CHUNKS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode mng_drop_objects (mng_datap pData,
+ mng_bool bDropaniobj)
+{
+ mng_objectp pObject;
+ mng_objectp pNext;
+ mng_cleanupobject fCleanup;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DROP_OBJECTS, MNG_LC_START)
+#endif
+
+ pObject = pData->pFirstimgobj; /* get first stored image-object (if any) */
+
+ while (pObject) /* more objects to discard ? */
+ {
+ pNext = ((mng_object_headerp)pObject)->pNext;
+ /* call appropriate cleanup */
+ fCleanup = ((mng_object_headerp)pObject)->fCleanup;
+ fCleanup (pData, pObject);
+
+ pObject = pNext; /* neeeext */
+ }
+
+ pData->pFirstimgobj = MNG_NULL; /* clean this up!!! */
+
+ if (bDropaniobj) /* drop animation objects ? */
+ {
+ pObject = pData->pFirstaniobj; /* get first stored animation-object (if any) */
+
+ while (pObject) /* more objects to discard ? */
+ {
+ pNext = ((mng_object_headerp)pObject)->pNext;
+ /* call appropriate cleanup */
+ fCleanup = ((mng_object_headerp)pObject)->fCleanup;
+ fCleanup (pData, pObject);
+
+ pObject = pNext; /* neeeext */
+ }
+
+ pData->pFirstaniobj = MNG_NULL; /* clean this up!!! */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DROP_OBJECTS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode mng_drop_savedata (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DROP_SAVEDATA, MNG_LC_START)
+#endif
+
+ if (pData->pSavedata) /* sanity check */
+ { /* address it more directly */
+ mng_savedatap pSave = pData->pSavedata;
+
+ if (pSave->iGlobalProfilesize) /* cleanup the profile ? */
+ MNG_FREEX (pData, pSave->pGlobalProfile, pSave->iGlobalProfilesize)
+ /* cleanup the save structure */
+ MNG_FREE (pData, pData->pSavedata, sizeof (mng_savedata))
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DROP_SAVEDATA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode mng_reset_rundata (mng_datap pData)
+{
+ drop_invalid_objects (pData); /* drop invalidly stored objects */
+ mng_drop_savedata (pData); /* drop stored savedata */
+ mng_reset_objzero (pData); /* reset object 0 */
+ /* drop stored objects (if any) */
+ mng_drop_objects (pData, MNG_FALSE);
+
+ pData->bFramedone = MNG_FALSE;
+ pData->iFrameseq = 0; /* reset counters & stuff */
+ pData->iLayerseq = 0;
+ pData->iFrametime = 0;
+ pData->iRequestframe = 0;
+ pData->iRequestlayer = 0;
+ pData->iRequesttime = 0;
+ pData->bSearching = MNG_FALSE;
+
+ pData->iRuntime = 0;
+ pData->iSynctime = 0;
+ pData->iStarttime = 0;
+ pData->iEndtime = 0;
+ pData->bRunning = MNG_FALSE;
+ pData->bTimerset = MNG_FALSE;
+ pData->iBreakpoint = 0;
+ pData->bSectionwait = MNG_FALSE;
+ pData->bFreezing = MNG_FALSE;
+ pData->bResetting = MNG_FALSE;
+ pData->bNeedrefresh = MNG_FALSE;
+
+ pData->iIterations = 0;
+ /* start of animation objects! */
+ pData->pCurraniobj = MNG_NULL;
+
+ pData->iUpdateleft = 0; /* reset region */
+ pData->iUpdateright = 0;
+ pData->iUpdatetop = 0;
+ pData->iUpdatebottom = 0;
+ pData->iPLTEcount = 0; /* reset PLTE data */
+
+ pData->iDEFIobjectid = 0; /* reset DEFI data */
+ pData->bDEFIhasdonotshow = MNG_FALSE;
+ pData->iDEFIdonotshow = 0;
+ pData->bDEFIhasconcrete = MNG_FALSE;
+ pData->iDEFIconcrete = 0;
+ pData->bDEFIhasloca = MNG_FALSE;
+ pData->iDEFIlocax = 0;
+ pData->iDEFIlocay = 0;
+ pData->bDEFIhasclip = MNG_FALSE;
+ pData->iDEFIclipl = 0;
+ pData->iDEFIclipr = 0;
+ pData->iDEFIclipt = 0;
+ pData->iDEFIclipb = 0;
+
+ pData->iBACKred = 0; /* reset BACK data */
+ pData->iBACKgreen = 0;
+ pData->iBACKblue = 0;
+ pData->iBACKmandatory = 0;
+ pData->iBACKimageid = 0;
+ pData->iBACKtile = 0;
+
+ pData->iFRAMmode = 1; /* default global FRAM variables */
+ pData->iFRAMdelay = 1;
+ pData->iFRAMtimeout = 0x7fffffffl;
+ pData->bFRAMclipping = MNG_FALSE;
+ pData->iFRAMclipl = 0;
+ pData->iFRAMclipr = 0;
+ pData->iFRAMclipt = 0;
+ pData->iFRAMclipb = 0;
+
+ pData->iFramemode = 1; /* again for the current frame */
+ pData->iFramedelay = 1;
+ pData->iFrametimeout = 0x7fffffffl;
+ pData->bFrameclipping = MNG_FALSE;
+ pData->iFrameclipl = 0;
+ pData->iFrameclipr = 0;
+ pData->iFrameclipt = 0;
+ pData->iFrameclipb = 0;
+
+ pData->iNextdelay = 1;
+
+ pData->iSHOWmode = 0; /* reset SHOW data */
+ pData->iSHOWfromid = 0;
+ pData->iSHOWtoid = 0;
+ pData->iSHOWnextid = 0;
+ pData->iSHOWskip = 0;
+
+ pData->iGlobalPLTEcount = 0; /* reset global PLTE data */
+
+ pData->iGlobalTRNSrawlen = 0; /* reset global tRNS data */
+
+ pData->iGlobalGamma = 0; /* reset global gAMA data */
+
+ pData->iGlobalWhitepointx = 0; /* reset global cHRM data */
+ pData->iGlobalWhitepointy = 0;
+ pData->iGlobalPrimaryredx = 0;
+ pData->iGlobalPrimaryredy = 0;
+ pData->iGlobalPrimarygreenx = 0;
+ pData->iGlobalPrimarygreeny = 0;
+ pData->iGlobalPrimarybluex = 0;
+ pData->iGlobalPrimarybluey = 0;
+
+ pData->iGlobalRendintent = 0; /* reset global sRGB data */
+
+ if (pData->iGlobalProfilesize) /* drop global profile (if any) */
+ MNG_FREE (pData, pData->pGlobalProfile, pData->iGlobalProfilesize)
+
+ pData->iGlobalProfilesize = 0;
+
+ pData->iGlobalBKGDred = 0; /* reset global bKGD data */
+ pData->iGlobalBKGDgreen = 0;
+ pData->iGlobalBKGDblue = 0;
+ /* reset delta-image */
+ pData->pDeltaImage = MNG_NULL;
+ pData->iDeltaImagetype = 0;
+ pData->iDeltatype = 0;
+ pData->iDeltaBlockwidth = 0;
+ pData->iDeltaBlockheight = 0;
+ pData->iDeltaBlockx = 0;
+ pData->iDeltaBlocky = 0;
+ pData->bDeltaimmediate = MNG_FALSE;
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+void cleanup_errors (mng_datap pData)
+{
+ pData->iErrorcode = MNG_NOERROR;
+ pData->iSeverity = 0;
+ pData->iErrorx1 = 0;
+ pData->iErrorx2 = 0;
+ pData->zErrortext = MNG_NULL;
+
+ return;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Versioning control * */
+/* * * */
+/* ************************************************************************** */
+
+mng_pchar MNG_DECL mng_version_text (void)
+{
+ return MNG_VERSION_TEXT;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_version_so (void)
+{
+ return MNG_VERSION_SO;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_version_dll (void)
+{
+ return MNG_VERSION_DLL;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_version_major (void)
+{
+ return MNG_VERSION_MAJOR;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_version_minor (void)
+{
+ return MNG_VERSION_MINOR;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_version_release (void)
+{
+ return MNG_VERSION_RELEASE;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * HLAPI routines * */
+/* * * */
+/* ************************************************************************** */
+
+mng_handle MNG_DECL mng_initialize (mng_ptr pUserdata,
+ mng_memalloc fMemalloc,
+ mng_memfree fMemfree,
+ mng_traceproc fTraceproc)
+{
+ mng_datap pData;
+#ifdef MNG_SUPPORT_DISPLAY
+ mng_retcode iRetcode;
+ mng_imagep pImage;
+#endif
+
+#ifdef MNG_INTERNAL_MEMMNGMT /* allocate the main datastruc */
+ pData = (mng_datap)calloc (1, sizeof (mng_data));
+#else
+ pData = (mng_datap)fMemalloc (sizeof (mng_data));
+#endif
+
+ if (!pData)
+ return MNG_NULL; /* error: out of memory?? */
+ /* validate the structure */
+ pData->iMagic = MNG_MAGIC;
+ /* save userdata field */
+ pData->pUserdata = pUserdata;
+ /* remember trace callback */
+ pData->fTraceproc = fTraceproc;
+
+#ifdef MNG_SUPPORT_TRACE
+ if (mng_trace (pData, MNG_FN_INITIALIZE, MNG_LC_INITIALIZE))
+ {
+ MNG_FREEX (pData, pData, sizeof (mng_data))
+ return MNG_NULL;
+ }
+#endif
+ /* default canvas styles are 8-bit RGB */
+ pData->iCanvasstyle = MNG_CANVAS_RGB8;
+ pData->iBkgdstyle = MNG_CANVAS_RGB8;
+
+ pData->iBGred = 0; /* black */
+ pData->iBGgreen = 0;
+ pData->iBGblue = 0;
+
+ pData->bUseBKGD = MNG_TRUE;
+
+#ifdef MNG_FULL_CMS
+ pData->bIssRGB = MNG_TRUE;
+ pData->hProf1 = 0; /* no profiles yet */
+ pData->hProf2 = 0;
+ pData->hProf3 = 0;
+ pData->hTrans = 0;
+#endif
+
+ pData->dViewgamma = 1.0;
+ pData->dDisplaygamma = 2.2;
+ pData->dDfltimggamma = 0.45455;
+ /* initially remember chunks */
+ pData->bStorechunks = MNG_TRUE;
+ /* no breaks at section-borders */
+ pData->bSectionbreaks = MNG_FALSE;
+ /* initially cache playback info */
+ pData->bCacheplayback = MNG_TRUE;
+ /* progressive refresh for large images */
+ pData->bDoProgressive = MNG_TRUE;
+ /* normal animation-speed ! */
+ pData->iSpeed = mng_st_normal;
+ /* initial image limits */
+ pData->iMaxwidth = 10000;
+ pData->iMaxheight = 10000;
+
+#ifdef MNG_INTERNAL_MEMMNGMT /* internal management */
+ pData->fMemalloc = MNG_NULL;
+ pData->fMemfree = MNG_NULL;
+#else /* keep callbacks */
+ pData->fMemalloc = fMemalloc;
+ pData->fMemfree = fMemfree;
+#endif
+ /* no value (yet) */
+ pData->fOpenstream = MNG_NULL;
+ pData->fClosestream = MNG_NULL;
+ pData->fReaddata = MNG_NULL;
+ pData->fWritedata = MNG_NULL;
+ pData->fErrorproc = MNG_NULL;
+ pData->fProcessheader = MNG_NULL;
+ pData->fProcesstext = MNG_NULL;
+ pData->fProcesssave = MNG_NULL;
+ pData->fProcessseek = MNG_NULL;
+ pData->fProcessneed = MNG_NULL;
+ pData->fProcessmend = MNG_NULL;
+ pData->fProcessunknown = MNG_NULL;
+ pData->fProcessterm = MNG_NULL;
+ pData->fGetcanvasline = MNG_NULL;
+ pData->fGetbkgdline = MNG_NULL;
+ pData->fGetalphaline = MNG_NULL;
+ pData->fRefresh = MNG_NULL;
+ pData->fGettickcount = MNG_NULL;
+ pData->fSettimer = MNG_NULL;
+ pData->fProcessgamma = MNG_NULL;
+ pData->fProcesschroma = MNG_NULL;
+ pData->fProcesssrgb = MNG_NULL;
+ pData->fProcessiccp = MNG_NULL;
+ pData->fProcessarow = MNG_NULL;
+
+#if defined(MNG_SUPPORT_DISPLAY) && (defined(MNG_GAMMA_ONLY) || defined(MNG_FULL_CMS))
+ pData->dLastgamma = 0; /* lookup table needs first-time calc */
+#endif
+
+#ifdef MNG_SUPPORT_DISPLAY /* create object 0 */
+ iRetcode = create_imageobject (pData, 0, MNG_TRUE, MNG_TRUE, MNG_TRUE,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, MNG_FALSE,
+ 0, 0, 0, 0, &pImage);
+
+ if (iRetcode) /* on error drop out */
+ {
+ MNG_FREEX (pData, pData, sizeof (mng_data))
+ return MNG_NULL;
+ }
+
+ pData->pObjzero = pImage;
+#endif
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_INCLUDE_LCMS)
+ mnglcms_initlibrary (); /* init lcms particulairs */
+#endif
+
+#ifdef MNG_SUPPORT_READ
+ pData->bSuspensionmode = MNG_FALSE;
+ pData->iSuspendbufsize = 0;
+ pData->pSuspendbuf = MNG_NULL;
+ pData->pSuspendbufnext = MNG_NULL;
+ pData->iSuspendbufleft = 0;
+ pData->iChunklen = 0;
+ pData->pReadbufnext = MNG_NULL;
+#endif
+
+#ifdef MNG_INCLUDE_ZLIB
+ mngzlib_initialize (pData); /* initialize zlib structures and such */
+ /* default zlib compression parameters */
+ pData->iZlevel = MNG_ZLIB_LEVEL;
+ pData->iZmethod = MNG_ZLIB_METHOD;
+ pData->iZwindowbits = MNG_ZLIB_WINDOWBITS;
+ pData->iZmemlevel = MNG_ZLIB_MEMLEVEL;
+ pData->iZstrategy = MNG_ZLIB_STRATEGY;
+ /* default maximum IDAT data size */
+ pData->iMaxIDAT = MNG_MAX_IDAT_SIZE;
+#endif
+
+#ifdef MNG_INCLUDE_JNG /* default IJG compression parameters */
+ pData->eJPEGdctmethod = MNG_JPEG_DCT;
+ pData->iJPEGquality = MNG_JPEG_TQUALITY;
+ pData->iJPEGsmoothing = MNG_JPEG_SMOOTHING;
+ pData->bJPEGcompressprogr = MNG_JPEG_PROGRESSIVE;
+ pData->bJPEGcompressopt = MNG_JPEG_OPTIMIZED;
+ /* default maximum JDAT data size */
+ pData->iMaxJDAT = MNG_MAX_JDAT_SIZE;
+#endif
+
+ mng_reset ((mng_handle)pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ if (mng_trace (pData, MNG_FN_INITIALIZE, MNG_LC_END))
+ {
+ MNG_FREEX (pData, pData, sizeof (mng_data))
+ return MNG_NULL;
+ }
+#endif
+
+ return (mng_handle)pData; /* if we get here, we're in business */
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_reset (mng_handle hHandle)
+{
+ mng_datap pData;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_RESET, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = ((mng_datap)(hHandle)); /* address main structure */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ mng_drop_savedata (pData); /* cleanup saved-data from SAVE/SEEK */
+#endif
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_FULL_CMS)
+ mng_clear_cms (pData); /* cleanup left-over cms stuff if any */
+#endif
+
+#ifdef MNG_INCLUDE_JNG
+ mngjpeg_cleanup (pData); /* cleanup jpeg stuff */
+#endif
+
+#ifdef MNG_INCLUDE_ZLIB
+ if (pData->bInflating) /* if we've been inflating */
+ {
+#ifdef MNG_INCLUDE_DISPLAY_PROCS
+ cleanup_rowproc (pData); /* cleanup row-processing, */
+#endif
+ mngzlib_inflatefree (pData); /* cleanup inflate! */
+ }
+#endif /* MNG_INCLUDE_ZLIB */
+
+#ifdef MNG_SUPPORT_READ
+ if ((pData->bReading) && (!pData->bEOF))
+ process_eof (pData); /* cleanup app streaming */
+ /* cleanup default read buffers */
+ MNG_FREE (pData, pData->pReadbuf, pData->iReadbufsize)
+ MNG_FREE (pData, pData->pLargebuf, pData->iLargebufsize)
+ MNG_FREE (pData, pData->pSuspendbuf, pData->iSuspendbufsize)
+#endif
+
+#ifdef MNG_SUPPORT_WRITE /* cleanup default write buffer */
+ MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize)
+#endif
+
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ mng_drop_chunks (pData); /* drop stored chunks (if any) */
+#endif
+
+#ifdef MNG_SUPPORT_DISPLAY
+ mng_drop_objects (pData, MNG_TRUE); /* drop stored objects (if any) */
+
+ if (pData->iGlobalProfilesize) /* drop global profile (if any) */
+ MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize)
+#endif
+
+ pData->eSigtype = mng_it_unknown;
+ pData->eImagetype = mng_it_unknown;
+ pData->iWidth = 0; /* these are unknown yet */
+ pData->iHeight = 0;
+ pData->iTicks = 0;
+ pData->iLayercount = 0;
+ pData->iFramecount = 0;
+ pData->iPlaytime = 0;
+ pData->iSimplicity = 0;
+ pData->iAlphadepth = 16; /* assume the worst! */
+
+ pData->iImagelevel = 0; /* no image encountered */
+
+ pData->iMagnify = 0; /* 1-to-1 display */
+ pData->iOffsetx = 0; /* no offsets */
+ pData->iOffsety = 0;
+ pData->iCanvaswidth = 0; /* let the app decide during processheader */
+ pData->iCanvasheight = 0;
+ /* so far, so good */
+ pData->iErrorcode = MNG_NOERROR;
+ pData->iSeverity = 0;
+ pData->iErrorx1 = 0;
+ pData->iErrorx2 = 0;
+ pData->zErrortext = MNG_NULL;
+
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ /* let's assume the best scenario */
+ pData->bPreDraft48 = MNG_FALSE;
+ /* the unknown chunk */
+ pData->iChunkname = MNG_UINT_HUH;
+ pData->iChunkseq = 0;
+ pData->pFirstchunk = MNG_NULL;
+ pData->pLastchunk = MNG_NULL;
+ /* nothing processed yet */
+ pData->bHasheader = MNG_FALSE;
+ pData->bHasMHDR = MNG_FALSE;
+ pData->bHasIHDR = MNG_FALSE;
+ pData->bHasBASI = MNG_FALSE;
+ pData->bHasDHDR = MNG_FALSE;
+#ifdef MNG_INCLUDE_JNG
+ pData->bHasJHDR = MNG_FALSE;
+ pData->bHasJSEP = MNG_FALSE;
+ pData->bHasJDAA = MNG_FALSE;
+ pData->bHasJDAT = MNG_FALSE;
+#endif
+ pData->bHasPLTE = MNG_FALSE;
+ pData->bHasTRNS = MNG_FALSE;
+ pData->bHasGAMA = MNG_FALSE;
+ pData->bHasCHRM = MNG_FALSE;
+ pData->bHasSRGB = MNG_FALSE;
+ pData->bHasICCP = MNG_FALSE;
+ pData->bHasBKGD = MNG_FALSE;
+ pData->bHasIDAT = MNG_FALSE;
+
+ pData->bHasSAVE = MNG_FALSE;
+ pData->bHasBACK = MNG_FALSE;
+ pData->bHasFRAM = MNG_FALSE;
+ pData->bHasTERM = MNG_FALSE;
+ pData->bHasLOOP = MNG_FALSE;
+ /* there's no global stuff yet either */
+ pData->bHasglobalPLTE = MNG_FALSE;
+ pData->bHasglobalTRNS = MNG_FALSE;
+ pData->bHasglobalGAMA = MNG_FALSE;
+ pData->bHasglobalCHRM = MNG_FALSE;
+ pData->bHasglobalSRGB = MNG_FALSE;
+ pData->bHasglobalICCP = MNG_FALSE;
+
+ pData->iDatawidth = 0; /* no IHDR/BASI/DHDR done yet */
+ pData->iDataheight = 0;
+ pData->iBitdepth = 0;
+ pData->iColortype = 0;
+ pData->iCompression = 0;
+ pData->iFilter = 0;
+ pData->iInterlace = 0;
+
+#ifdef MNG_INCLUDE_JNG
+ pData->iJHDRcolortype = 0; /* no JHDR data */
+ pData->iJHDRimgbitdepth = 0;
+ pData->iJHDRimgcompression = 0;
+ pData->iJHDRimginterlace = 0;
+ pData->iJHDRalphabitdepth = 0;
+ pData->iJHDRalphacompression = 0;
+ pData->iJHDRalphafilter = 0;
+ pData->iJHDRalphainterlace = 0;
+#endif
+
+#endif /* MNG_SUPPORT_READ || MNG_SUPPORT_WRITE */
+
+#ifdef MNG_SUPPORT_READ /* no reading done */
+ pData->bReading = MNG_FALSE;
+ pData->bHavesig = MNG_FALSE;
+ pData->bEOF = MNG_FALSE;
+ pData->iReadbufsize = 0;
+ pData->pReadbuf = MNG_NULL;
+
+ pData->iLargebufsize = 0;
+ pData->pLargebuf = MNG_NULL;
+
+ pData->iSuspendtime = 0;
+ pData->bSuspended = MNG_FALSE;
+ pData->iSuspendpoint = 0;
+
+ pData->pSuspendbufnext = pData->pSuspendbuf;
+ pData->iSuspendbufleft = 0;
+#endif /* MNG_SUPPORT_READ */
+
+#ifdef MNG_SUPPORT_WRITE /* no creating/writing done */
+ pData->bCreating = MNG_FALSE;
+ pData->bWriting = MNG_FALSE;
+ pData->iFirstchunkadded = 0;
+ pData->iWritebufsize = 0;
+ pData->pWritebuf = MNG_NULL;
+#endif /* MNG_SUPPORT_WRITE */
+
+#ifdef MNG_SUPPORT_DISPLAY /* done nuttin' yet */
+ pData->bDisplaying = MNG_FALSE;
+ pData->iFrameseq = 0;
+ pData->iLayerseq = 0;
+ pData->iFrametime = 0;
+
+ pData->iRequestframe = 0;
+ pData->iRequestlayer = 0;
+ pData->iRequesttime = 0;
+ pData->bSearching = MNG_FALSE;
+
+ pData->bRestorebkgd = MNG_FALSE;
+
+ pData->iRuntime = 0;
+ pData->iSynctime = 0;
+ pData->iStarttime = 0;
+ pData->iEndtime = 0;
+ pData->bRunning = MNG_FALSE;
+ pData->bTimerset = MNG_FALSE;
+ pData->iBreakpoint = 0;
+ pData->bSectionwait = MNG_FALSE;
+ pData->bFreezing = MNG_FALSE;
+ pData->bResetting = MNG_FALSE;
+ pData->bNeedrefresh = MNG_FALSE;
+ /* these don't exist yet */
+ pData->pCurrentobj = MNG_NULL;
+ pData->pCurraniobj = MNG_NULL;
+ pData->pTermaniobj = MNG_NULL;
+ pData->pLastclone = MNG_NULL;
+ pData->pStoreobj = MNG_NULL;
+ pData->pStorebuf = MNG_NULL;
+ pData->pRetrieveobj = MNG_NULL;
+ /* no saved data ! */
+ pData->pSavedata = MNG_NULL;
+ /* TODO: remove in 1.0.0 !!! */
+ pData->bEMNGMAhack = MNG_FALSE;
+
+ pData->iUpdateleft = 0; /* no region updated yet */
+ pData->iUpdateright = 0;
+ pData->iUpdatetop = 0;
+ pData->iUpdatebottom = 0;
+
+ pData->iPass = -1; /* interlacing stuff and temp buffers */
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = 0;
+ pData->iSamplemul = 0;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = 0;
+ pData->iRowmax = 0;
+ pData->iFilterofs = 0;
+ pData->iPixelofs = 1;
+ pData->iLevel0 = 0;
+ pData->iLevel1 = 0;
+ pData->iLevel2 = 0;
+ pData->iLevel3 = 0;
+ pData->pWorkrow = MNG_NULL;
+ pData->pPrevrow = MNG_NULL;
+ pData->pRGBArow = 0;
+ pData->bIsRGBA16 = MNG_TRUE;
+ pData->bIsOpaque = MNG_TRUE;
+ pData->iFilterbpp = 1;
+
+ pData->iSourcel = 0; /* always initialized just before */
+ pData->iSourcer = 0; /* compositing the next layer */
+ pData->iSourcet = 0;
+ pData->iSourceb = 0;
+ pData->iDestl = 0;
+ pData->iDestr = 0;
+ pData->iDestt = 0;
+ pData->iDestb = 0;
+ /* lists are empty */
+ pData->pFirstimgobj = MNG_NULL;
+ pData->pLastimgobj = MNG_NULL;
+ pData->pFirstaniobj = MNG_NULL;
+ pData->pLastaniobj = MNG_NULL;
+ /* no processing callbacks */
+ pData->fDisplayrow = MNG_NULL;
+ pData->fRestbkgdrow = MNG_NULL;
+ pData->fCorrectrow = MNG_NULL;
+ pData->fRetrieverow = MNG_NULL;
+ pData->fStorerow = MNG_NULL;
+ pData->fProcessrow = MNG_NULL;
+ pData->fDifferrow = MNG_NULL;
+ pData->fInitrowproc = MNG_NULL;
+
+ pData->iPLTEcount = 0; /* no PLTE data */
+
+ pData->iDEFIobjectid = 0; /* no DEFI data */
+ pData->bDEFIhasdonotshow = MNG_FALSE;
+ pData->iDEFIdonotshow = 0;
+ pData->bDEFIhasconcrete = MNG_FALSE;
+ pData->iDEFIconcrete = 0;
+ pData->bDEFIhasloca = MNG_FALSE;
+ pData->iDEFIlocax = 0;
+ pData->iDEFIlocay = 0;
+ pData->bDEFIhasclip = MNG_FALSE;
+ pData->iDEFIclipl = 0;
+ pData->iDEFIclipr = 0;
+ pData->iDEFIclipt = 0;
+ pData->iDEFIclipb = 0;
+
+ pData->iBACKred = 0; /* no BACK data */
+ pData->iBACKgreen = 0;
+ pData->iBACKblue = 0;
+ pData->iBACKmandatory = 0;
+ pData->iBACKimageid = 0;
+ pData->iBACKtile = 0;
+
+ pData->iFRAMmode = 1; /* default global FRAM variables */
+ pData->iFRAMdelay = 1;
+ pData->iFRAMtimeout = 0x7fffffffl;
+ pData->bFRAMclipping = MNG_FALSE;
+ pData->iFRAMclipl = 0;
+ pData->iFRAMclipr = 0;
+ pData->iFRAMclipt = 0;
+ pData->iFRAMclipb = 0;
+
+ pData->iFramemode = 1; /* again for the current frame */
+ pData->iFramedelay = 1;
+ pData->iFrametimeout = 0x7fffffffl;
+ pData->bFrameclipping = MNG_FALSE;
+ pData->iFrameclipl = 0;
+ pData->iFrameclipr = 0;
+ pData->iFrameclipt = 0;
+ pData->iFrameclipb = 0;
+
+ pData->iNextdelay = 1;
+
+ pData->iSHOWmode = 0; /* no SHOW data */
+ pData->iSHOWfromid = 0;
+ pData->iSHOWtoid = 0;
+ pData->iSHOWnextid = 0;
+ pData->iSHOWskip = 0;
+
+ pData->iGlobalPLTEcount = 0; /* no global PLTE data */
+
+ pData->iGlobalTRNSrawlen = 0; /* no global tRNS data */
+
+ pData->iGlobalGamma = 0; /* no global gAMA data */
+
+ pData->iGlobalWhitepointx = 0; /* no global cHRM data */
+ pData->iGlobalWhitepointy = 0;
+ pData->iGlobalPrimaryredx = 0;
+ pData->iGlobalPrimaryredy = 0;
+ pData->iGlobalPrimarygreenx = 0;
+ pData->iGlobalPrimarygreeny = 0;
+ pData->iGlobalPrimarybluex = 0;
+ pData->iGlobalPrimarybluey = 0;
+
+ pData->iGlobalRendintent = 0; /* no global sRGB data */
+
+ pData->iGlobalProfilesize = 0; /* no global iCCP data */
+ pData->pGlobalProfile = MNG_NULL;
+
+ pData->iGlobalBKGDred = 0; /* no global bKGD data */
+ pData->iGlobalBKGDgreen = 0;
+ pData->iGlobalBKGDblue = 0;
+ /* no delta-image */
+ pData->pDeltaImage = MNG_NULL;
+ pData->iDeltaImagetype = 0;
+ pData->iDeltatype = 0;
+ pData->iDeltaBlockwidth = 0;
+ pData->iDeltaBlockheight = 0;
+ pData->iDeltaBlockx = 0;
+ pData->iDeltaBlocky = 0;
+ pData->bDeltaimmediate = MNG_FALSE;
+#endif
+
+#ifdef MNG_INCLUDE_ZLIB
+ pData->bInflating = 0; /* no inflating or deflating */
+ pData->bDeflating = 0; /* going on at the moment */
+#endif
+
+#ifdef MNG_SUPPORT_DISPLAY /* reset object 0 */
+ mng_reset_objzero (pData);
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_RESET, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_cleanup (mng_handle* hHandle)
+{
+ mng_datap pData; /* local vars */
+#ifndef MNG_INTERNAL_MEMMNGMT
+ mng_memfree fFree;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)*hHandle), MNG_FN_CLEANUP, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (*hHandle) /* check validity handle */
+ pData = ((mng_datap)(*hHandle)); /* and address main structure */
+
+ mng_reset (*hHandle); /* do an implicit reset to cleanup most stuff */
+
+#ifdef MNG_SUPPORT_DISPLAY /* drop object 0 */
+ free_imageobject (pData, (mng_imagep)pData->pObjzero);
+#endif
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_INCLUDE_LCMS)
+ if (pData->hProf2) /* output profile defined ? */
+ mnglcms_freeprofile (pData->hProf2);
+
+ if (pData->hProf3) /* sRGB profile defined ? */
+ mnglcms_freeprofile (pData->hProf3);
+#endif /* MNG_SUPPORT_DISPLAY && MNG_INCLUDE_LCMS */
+
+#ifdef MNG_INCLUDE_ZLIB
+ mngzlib_cleanup (pData); /* cleanup zlib stuff */
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)*hHandle), MNG_FN_CLEANUP, MNG_LC_CLEANUP)
+#endif
+
+ pData->iMagic = 0; /* tqinvalidate the actual memory */
+
+#ifdef MNG_INTERNAL_MEMMNGMT
+ free ((void *)*hHandle); /* cleanup the data-structure */
+#else
+ fFree = ((mng_datap)*hHandle)->fMemfree;
+ fFree ((mng_ptr)*hHandle, sizeof (mng_data));
+#endif
+
+ *hHandle = 0; /* wipe pointer to inhibit future use */
+
+ return MNG_NOERROR; /* and we're done */
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_read (mng_handle hHandle)
+{
+ mng_datap pData; /* local vars */
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle and callbacks */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+#ifndef MNG_INTERNAL_MEMMNGMT
+ MNG_VALIDCB (hHandle, fMemalloc)
+ MNG_VALIDCB (hHandle, fMemfree)
+#endif
+
+ MNG_VALIDCB (hHandle, fOpenstream)
+ MNG_VALIDCB (hHandle, fClosestream)
+ MNG_VALIDCB (hHandle, fReaddata)
+
+#ifdef MNG_SUPPORT_DISPLAY /* valid at this point ? */
+ if ((pData->bReading) || (pData->bDisplaying))
+#else
+ if (pData->bReading)
+#endif
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+#ifdef MNG_SUPPORT_WRITE
+ if ((pData->bWriting) || (pData->bCreating))
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+#endif
+
+ if (!pData->bCacheplayback) /* must store playback info to work!! */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ pData->bReading = MNG_TRUE; /* read only! */
+
+ if (!pData->fOpenstream (hHandle)) /* open it and start reading */
+ iRetcode = MNG_APPIOERROR;
+ else
+ iRetcode = read_graphic (pData);
+
+ if (pData->bEOF) /* already at EOF ? */
+ {
+ pData->bReading = MNG_FALSE; /* then we're no longer reading */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ mng_reset_rundata (pData); /* reset rundata */
+#endif
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bSuspended) /* read suspension ? */
+ {
+ iRetcode = MNG_NEEDMOREDATA;
+ pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_read_resume (mng_handle hHandle)
+{
+ mng_datap pData; /* local vars */
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_RESUME, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+ /* can we expect this call ? */
+ if ((!pData->bReading) || (!pData->bSuspended))
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ pData->bSuspended = MNG_FALSE; /* reset the flag */
+
+#ifdef MNG_SUPPORT_DISPLAY /* re-synchronize ? */
+ if ((pData->bDisplaying) && (pData->bRunning))
+ pData->iSynctime = pData->iSynctime - pData->iSuspendtime +
+ pData->fGettickcount (hHandle);
+#endif
+
+ iRetcode = read_graphic (pData); /* continue reading now */
+
+ if (pData->bEOF) /* at EOF ? */
+ {
+ pData->bReading = MNG_FALSE; /* then we're no longer reading */
+
+#ifdef MNG_SUPPORT_DISPLAY
+ mng_reset_rundata (pData); /* reset rundata */
+#endif
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bSuspended) /* read suspension ? */
+ {
+ iRetcode = MNG_NEEDMOREDATA;
+ pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_READ_RESUME, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_WRITE
+mng_retcode MNG_DECL mng_write (mng_handle hHandle)
+{
+ mng_datap pData;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_WRITE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle and callbacks */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+#ifndef MNG_INTERNAL_MEMMNGMT
+ MNG_VALIDCB (hHandle, fMemalloc)
+ MNG_VALIDCB (hHandle, fMemfree)
+#endif
+
+ MNG_VALIDCB (hHandle, fOpenstream)
+ MNG_VALIDCB (hHandle, fClosestream)
+ MNG_VALIDCB (hHandle, fWritedata)
+
+#ifdef MNG_SUPPORT_READ
+ if (pData->bReading) /* valid at this point ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+#endif
+
+ if (pData->bCreating) /* can't write while it's still being made! */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ iRetcode = write_graphic (pData); /* do the write */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_WRITE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_WRITE */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_WRITE
+mng_retcode MNG_DECL mng_create (mng_handle hHandle)
+{
+ mng_datap pData;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_CREATE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle and callbacks */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+#ifndef MNG_INTERNAL_MEMMNGMT
+ MNG_VALIDCB (hHandle, fMemalloc)
+ MNG_VALIDCB (hHandle, fMemfree)
+#endif
+
+#ifdef MNG_SUPPORT_READ
+ if (pData->bReading) /* valid at this point ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+#endif
+
+ if ((pData->bWriting) || (pData->bCreating))
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ iRetcode = mng_reset (hHandle); /* clear any previous stuff */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pData->bCreating = MNG_TRUE; /* indicate we're creating a new file */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_CREATE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_WRITE */
+
+/* ************************************************************************** */
+
+#if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_READ)
+mng_retcode MNG_DECL mng_readdisplay (mng_handle hHandle)
+{
+ mng_datap pData; /* local vars */
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_READDISPLAY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle and callbacks */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+#ifndef MNG_INTERNAL_MEMMNGMT
+ MNG_VALIDCB (hHandle, fMemalloc)
+ MNG_VALIDCB (hHandle, fMemfree)
+#endif
+
+ MNG_VALIDCB (hHandle, fReaddata)
+ MNG_VALIDCB (hHandle, fGetcanvasline)
+ MNG_VALIDCB (hHandle, fRefresh)
+ MNG_VALIDCB (hHandle, fGettickcount)
+ MNG_VALIDCB (hHandle, fSettimer)
+ /* valid at this point ? */
+ if ((pData->bReading) || (pData->bDisplaying))
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+#ifdef MNG_SUPPORT_WRITE
+ if ((pData->bWriting) || (pData->bCreating))
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+#endif
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ pData->bReading = MNG_TRUE; /* read & display! */
+ pData->bDisplaying = MNG_TRUE;
+ pData->bRunning = MNG_TRUE;
+ pData->iFrameseq = 0;
+ pData->iLayerseq = 0;
+ pData->iFrametime = 0;
+ pData->iRequestframe = 0;
+ pData->iRequestlayer = 0;
+ pData->iRequesttime = 0;
+ pData->bSearching = MNG_FALSE;
+ pData->iRuntime = 0;
+ pData->iSynctime = pData->fGettickcount (hHandle);
+ pData->iSuspendtime = 0;
+ pData->iStarttime = pData->iSynctime;
+ pData->iEndtime = 0;
+
+ if (!pData->fOpenstream (hHandle)) /* open it and start reading */
+ iRetcode = MNG_APPIOERROR;
+ else
+ iRetcode = read_graphic (pData);
+
+ if (pData->bEOF) /* already at EOF ? */
+ {
+ pData->bReading = MNG_FALSE; /* then we're no longer reading */
+ drop_invalid_objects (pData); /* drop invalidly stored objects */
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bSuspended) /* read suspension ? */
+ {
+ iRetcode = MNG_NEEDMOREDATA;
+ pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
+ }
+ else
+ if (pData->bTimerset) /* indicate timer break ? */
+ iRetcode = MNG_NEEDTIMERWAIT;
+ else
+ if (pData->bSectionwait) /* indicate section break ? */
+ iRetcode = MNG_NEEDSECTIONWAIT;
+ else
+ pData->bRunning = MNG_FALSE; /* no breaks = end of run */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_READDISPLAY, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+#endif /* MNG_SUPPORT_DISPLAY && MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_display (mng_handle hHandle)
+{
+ mng_datap pData; /* local vars */
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle and callbacks */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+#ifndef MNG_INTERNAL_MEMMNGMT
+ MNG_VALIDCB (hHandle, fMemalloc)
+ MNG_VALIDCB (hHandle, fMemfree)
+#endif
+
+ MNG_VALIDCB (hHandle, fGetcanvasline)
+ MNG_VALIDCB (hHandle, fRefresh)
+ MNG_VALIDCB (hHandle, fGettickcount)
+ MNG_VALIDCB (hHandle, fSettimer)
+
+ if (pData->bDisplaying) /* valid at this point ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+#ifdef MNG_SUPPORT_READ
+ if (pData->bReading)
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+#endif
+
+#ifdef MNG_SUPPORT_WRITE
+ if ((pData->bWriting) || (pData->bCreating))
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+#endif
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ pData->bDisplaying = MNG_TRUE; /* display! */
+ pData->bRunning = MNG_TRUE;
+ pData->iFrameseq = 0;
+ pData->iLayerseq = 0;
+ pData->iFrametime = 0;
+ pData->iRequestframe = 0;
+ pData->iRequestlayer = 0;
+ pData->iRequesttime = 0;
+ pData->bSearching = MNG_FALSE;
+ pData->iRuntime = 0;
+ pData->iSynctime = pData->fGettickcount (hHandle);
+#ifdef MNG_SUPPORT_READ
+ pData->iSuspendtime = 0;
+#endif
+ pData->iStarttime = pData->iSynctime;
+ pData->iEndtime = 0;
+ pData->pCurraniobj = pData->pFirstaniobj;
+
+ iRetcode = process_display (pData); /* go do it */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bTimerset) /* indicate timer break ? */
+ iRetcode = MNG_NEEDTIMERWAIT;
+ else
+ pData->bRunning = MNG_FALSE; /* no breaks = end of run */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_display_resume (mng_handle hHandle)
+{
+ mng_datap pData; /* local vars */
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESUME, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+ if (!pData->bDisplaying) /* can we expect this call ? */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ if (pData->bRunning) /* was it running ? */
+ { /* are we expecting this call ? */
+ if ((pData->bTimerset) || (pData->bSuspended) || (pData->bSectionwait))
+ {
+ pData->bTimerset = MNG_FALSE; /* reset the flags */
+ pData->bSectionwait = MNG_FALSE;
+
+#ifdef MNG_SUPPORT_READ
+ if (pData->bReading) /* set during read&display ? */
+ {
+ if (pData->bSuspended) /* calculate proper synchronization */
+ pData->iSynctime = pData->iSynctime - pData->iSuspendtime +
+ pData->fGettickcount (hHandle);
+ else
+ pData->iSynctime = pData->fGettickcount (hHandle);
+
+ pData->bSuspended = MNG_FALSE; /* now reset this flag */
+ /* and continue reading */
+ iRetcode = read_graphic (pData);
+
+ if (pData->bEOF) /* already at EOF ? */
+ {
+ pData->bReading = MNG_FALSE; /* then we're no longer reading */
+ /* drop invalidly stored objects */
+ drop_invalid_objects (pData);
+ }
+ }
+ else
+#endif /* MNG_SUPPORT_READ */
+ { /* synchronize timing */
+ pData->iSynctime = pData->fGettickcount (hHandle);
+ /* resume display processing */
+ iRetcode = process_display (pData);
+ }
+ }
+ else
+ {
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+ }
+ }
+ else
+ { /* synchronize timing */
+ pData->iSynctime = pData->fGettickcount (hHandle);
+ pData->bRunning = MNG_TRUE; /* it's restarted again ! */
+ /* resume display processing */
+ iRetcode = process_display (pData);
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->bSuspended) /* read suspension ? */
+ {
+ iRetcode = MNG_NEEDMOREDATA;
+ pData->iSuspendtime = pData->fGettickcount ((mng_handle)pData);
+ }
+ else
+ if (pData->bTimerset) /* indicate timer break ? */
+ iRetcode = MNG_NEEDTIMERWAIT;
+ else
+ if (pData->bSectionwait) /* indicate section break ? */
+ iRetcode = MNG_NEEDSECTIONWAIT;
+ else
+ { /* no breaks = end of run */
+ pData->bRunning = MNG_FALSE;
+
+ if (pData->bFreezing) /* trying to freeze ? */
+ { /* then we're there ! */
+ pData->bFreezing = MNG_FALSE;
+ }
+
+ if (pData->bResetting) /* trying to reset as well ? */
+ { /* full stop!!! */
+ pData->bDisplaying = MNG_FALSE;
+
+ iRetcode = mng_reset_rundata (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESUME, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_display_freeze (mng_handle hHandle)
+{
+ mng_datap pData;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_FREEZE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+ /* can we expect this call ? */
+ if ((!pData->bDisplaying) || (pData->bReading))
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ if (pData->bRunning) /* is it running ? */
+ {
+ mng_retcode iRetcode;
+
+ pData->bFreezing = MNG_TRUE; /* indicate we need to freeze */
+ /* continue "normal" processing */
+ iRetcode = mng_display_resume (hHandle);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_FREEZE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_display_reset (mng_handle hHandle)
+{
+ mng_datap pData;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESET, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+ /* can we expect this call ? */
+ if ((!pData->bDisplaying) || (pData->bReading))
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ if (!pData->bCacheplayback) /* must store playback info to work!! */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ if (pData->bRunning) /* is it running ? */
+ {
+ pData->bFreezing = MNG_TRUE; /* indicate we need to freeze */
+ pData->bResetting = MNG_TRUE; /* indicate we're about to reset too */
+ /* continue normal processing ? */
+ iRetcode = mng_display_resume (hHandle);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ else
+ { /* full stop!!! */
+ pData->bDisplaying = MNG_FALSE;
+
+ iRetcode = mng_reset_rundata (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_RESET, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_display_goframe (mng_handle hHandle,
+ mng_uint32 iFramenr)
+{
+ mng_datap pData;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOFRAME, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+ if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
+ MNG_ERROR (pData, MNG_NOTANANIMATION);
+ /* can we expect this call ? */
+ if ((!pData->bDisplaying) || (pData->bRunning))
+ MNG_ERROR ((mng_datap)hHandle, MNG_FUNCTIONINVALID)
+
+ if (!pData->bCacheplayback) /* must store playback info to work!! */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ if (iFramenr > pData->iFramecount) /* is the parameter within bounds ? */
+ MNG_ERROR (pData, MNG_FRAMENRTOOHIGH);
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ pData->iRequestframe = iFramenr; /* go tqfind the requested frame then */
+ iRetcode = process_display (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOFRAME, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_display_golayer (mng_handle hHandle,
+ mng_uint32 iLayernr)
+{
+ mng_datap pData;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOLAYER, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+ if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
+ MNG_ERROR (pData, MNG_NOTANANIMATION)
+ /* can we expect this call ? */
+ if ((!pData->bDisplaying) || (pData->bRunning))
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ if (!pData->bCacheplayback) /* must store playback info to work!! */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ if (iLayernr > pData->iLayercount) /* is the parameter within bounds ? */
+ MNG_ERROR (pData, MNG_LAYERNRTOOHIGH)
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ pData->iRequestlayer = iLayernr; /* go tqfind the requested layer then */
+ iRetcode = process_display (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOLAYER, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_display_gotime (mng_handle hHandle,
+ mng_uint32 iPlaytime)
+{
+ mng_datap pData;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOTIME, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+ if (pData->eImagetype != mng_it_mng) /* is it an animation ? */
+ MNG_ERROR (pData, MNG_NOTANANIMATION)
+ /* can we expect this call ? */
+ if ((!pData->bDisplaying) || (pData->bRunning))
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ if (!pData->bCacheplayback) /* must store playback info to work!! */
+ MNG_ERROR (pData, MNG_FUNCTIONINVALID)
+
+ if (iPlaytime > pData->iPlaytime) /* is the parameter within bounds ? */
+ MNG_ERROR (pData, MNG_PLAYTIMETOOHIGH)
+
+ cleanup_errors (pData); /* cleanup previous errors */
+
+ pData->iRequesttime = iPlaytime; /* go tqfind the requested playtime then */
+ iRetcode = process_display (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_DISPLAY_GOTIME, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_getlasterror (mng_handle hHandle,
+ mng_int8* iSeverity,
+ mng_chunkid* iChunkname,
+ mng_uint32* iChunkseq,
+ mng_int32* iExtra1,
+ mng_int32* iExtra2,
+ mng_pchar* zErrortext)
+{
+ mng_datap pData; /* local vars */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETLASTERROR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle) /* check validity handle */
+ pData = ((mng_datap)hHandle); /* and make it addressable */
+
+ *iSeverity = pData->iSeverity; /* return the appropriate fields */
+
+#if defined(MNG_SUPPORT_READ) || defined(MNG_SUPPORT_WRITE)
+ *iChunkname = pData->iChunkname;
+ *iChunkseq = pData->iChunkseq;
+#else
+ *iChunkname = MNG_UINT_HUH;
+ *iChunkseq = 0;
+#endif
+
+ *iExtra1 = pData->iErrorx1;
+ *iExtra2 = pData->iErrorx2;
+ *zErrortext = pData->zErrortext;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GETLASTERROR, MNG_LC_END)
+#endif
+
+ return pData->iErrorcode; /* and the errorcode */
+}
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_jpeg.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_jpeg.c
new file mode 100644
index 0000000..dba8bf5
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_jpeg.c
@@ -0,0 +1,1066 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_jpeg.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.4 * */
+/* * * */
+/* * purpose : JPEG library interface (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the JPEG library interface * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.5.2 - 05/22/2000 - G.Juyn * */
+/* * - implemented all the JNG routines * */
+/* * * */
+/* * 0.5.3 - 06/17/2000 - G.Juyn * */
+/* * - added tracing of JPEG calls * */
+/* * 0.5.3 - 06/24/2000 - G.Juyn * */
+/* * - fixed inclusion of IJG read/write code * */
+/* * 0.5.3 - 06/29/2000 - G.Juyn * */
+/* * - fixed some 64-bit warnings * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added support for JDAA * */
+/* * * */
+/* * 1.0.1 - 04/19/2001 - G.Juyn * */
+/* * - added export of JPEG functions for DLL * */
+/* * 1.0.1 - 04/22/2001 - G.Juyn * */
+/* * - fixed memory-leaks (Thanks Gregg!) * */
+/* * * */
+/* * 1.0.4 - 06/22/2002 - G.Juyn * */
+/* * - B526138 - returned IJGSRC6B calling convention to * */
+/* * default for MSVC * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_memory.h"
+#include "libmng_pixels.h"
+#include "libmng_jpeg.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+
+/* ************************************************************************** */
+/* * * */
+/* * Local IJG callback routines (source-manager, error-manager and such) * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_IJG6B
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+#ifdef MNG_DEFINE_JPEG_STDCALL
+void MNG_DECL mng_init_source (j_decompress_ptr cinfo)
+#else
+void mng_init_source (j_decompress_ptr cinfo)
+#endif
+{
+ return; /* nothing needed */
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+#ifdef MNG_DEFINE_JPEG_STDCALL
+boolean MNG_DECL mng_fill_input_buffer (j_decompress_ptr cinfo)
+#else
+boolean mng_fill_input_buffer (j_decompress_ptr cinfo)
+#endif
+{
+ return FALSE; /* force IJG routine to return to caller */
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+#ifdef MNG_DEFINE_JPEG_STDCALL
+void MNG_DECL mng_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+#else
+void mng_skip_input_data (j_decompress_ptr cinfo, long num_bytes)
+#endif
+{
+ if (num_bytes > 0) /* ignore fony calls */
+ { /* address my generic structure */
+ mng_datap pData = (mng_datap)cinfo->client_data;
+ /* address source manager */
+ mngjpeg_sourcep pSrc = pData->pJPEGdinfo->src;
+ /* problem scenario ? */
+ if (pSrc->bytes_in_buffer < (size_t)num_bytes)
+ { /* tell the boss we need to skip some data! */
+ pData->iJPEGtoskip = (mng_uint32)((size_t)num_bytes - pSrc->bytes_in_buffer);
+
+ pSrc->bytes_in_buffer = 0; /* let the JPEG lib suspend */
+ pSrc->next_input_byte = MNG_NULL;
+ }
+ else
+ { /* simply advance in the buffer */
+ pSrc->bytes_in_buffer -= num_bytes;
+ pSrc->next_input_byte += num_bytes;
+ }
+ }
+
+ return;
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+#ifdef MNG_DEFINE_JPEG_STDCALL
+void MNG_DECL mng_skip_input_data2 (j_decompress_ptr cinfo, long num_bytes)
+#else
+void mng_skip_input_data2 (j_decompress_ptr cinfo, long num_bytes)
+#endif
+{
+ if (num_bytes > 0) /* ignore fony calls */
+ { /* address my generic structure */
+ mng_datap pData = (mng_datap)cinfo->client_data;
+ /* address source manager */
+ mngjpeg_sourcep pSrc = pData->pJPEGdinfo2->src;
+ /* problem scenario ? */
+ if (pSrc->bytes_in_buffer < (size_t)num_bytes)
+ { /* tell the boss we need to skip some data! */
+ pData->iJPEGtoskip2 = (mng_uint32)((size_t)num_bytes - pSrc->bytes_in_buffer);
+
+ pSrc->bytes_in_buffer = 0; /* let the JPEG lib suspend */
+ pSrc->next_input_byte = MNG_NULL;
+ }
+ else
+ { /* simply advance in the buffer */
+ pSrc->bytes_in_buffer -= num_bytes;
+ pSrc->next_input_byte += num_bytes;
+ }
+ }
+
+ return;
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+#ifdef MNG_DEFINE_JPEG_STDCALL
+void MNG_DECL mng_term_source (j_decompress_ptr cinfo)
+#else
+void mng_term_source (j_decompress_ptr cinfo)
+#endif
+{
+ return; /* nothing needed */
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_USE_SETJMP
+#ifdef MNG_DEFINE_JPEG_STDCALL
+void MNG_DECL mng_error_exit (j_common_ptr cinfo)
+#else
+void mng_error_exit (j_common_ptr cinfo)
+#endif
+{ /* address my generic structure */
+ mng_datap pData = (mng_datap)cinfo->client_data;
+
+#ifdef MNG_ERROR_TELLTALE /* fill the message text ??? */
+ (*cinfo->err->output_message) (cinfo);
+#endif
+ /* return to the point of no return... */
+ longjmp (pData->sErrorbuf, cinfo->err->msg_code);
+}
+#endif /* MNG_USE_SETJMP */
+
+/* ************************************************************************** */
+
+#ifdef MNG_USE_SETJMP
+#ifdef MNG_DEFINE_JPEG_STDCALL
+void MNG_DECL mng_output_message (j_common_ptr cinfo)
+#else
+void mng_output_message (j_common_ptr cinfo)
+#endif
+{
+ return; /* just do nothing ! */
+}
+#endif /* MNG_USE_SETJMP */
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_IJG6B */
+
+/* ************************************************************************** */
+/* * * */
+/* * Global JPEG routines * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode mngjpeg_initialize (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_INITIALIZE, MNG_LC_START)
+#endif
+ /* allocate space for JPEG structures if necessary */
+#ifdef MNG_INCLUDE_JNG_READ
+ if (pData->pJPEGderr == MNG_NULL)
+ MNG_ALLOC (pData, pData->pJPEGderr, sizeof (mngjpeg_error ))
+ if (pData->pJPEGdsrc == MNG_NULL)
+ MNG_ALLOC (pData, pData->pJPEGdsrc, sizeof (mngjpeg_source))
+ if (pData->pJPEGdinfo == MNG_NULL)
+ MNG_ALLOC (pData, pData->pJPEGdinfo, sizeof (mngjpeg_decomp))
+ /* enable reverse addressing */
+ pData->pJPEGdinfo->client_data = pData;
+
+ if (pData->pJPEGderr2 == MNG_NULL)
+ MNG_ALLOC (pData, pData->pJPEGderr2, sizeof (mngjpeg_error ))
+ if (pData->pJPEGdsrc2 == MNG_NULL)
+ MNG_ALLOC (pData, pData->pJPEGdsrc2, sizeof (mngjpeg_source))
+ if (pData->pJPEGdinfo2 == MNG_NULL)
+ MNG_ALLOC (pData, pData->pJPEGdinfo2, sizeof (mngjpeg_decomp))
+ /* enable reverse addressing */
+ pData->pJPEGdinfo2->client_data = pData;
+#endif
+
+#ifdef MNG_INCLUDE_JNG_WRITE
+ if (pData->pJPEGcerr == MNG_NULL)
+ MNG_ALLOC (pData, pData->pJPEGcerr, sizeof (mngjpeg_error ))
+ if (pData->pJPEGcinfo == MNG_NULL)
+ MNG_ALLOC (pData, pData->pJPEGcinfo, sizeof (mngjpeg_comp ))
+ /* enable reverse addressing */
+ pData->pJPEGcinfo->client_data = pData;
+#endif
+
+ if (pData->pJPEGbuf == MNG_NULL) /* initialize temporary buffers */
+ {
+ pData->iJPEGbufmax = MNG_JPEG_MAXBUF;
+ MNG_ALLOC (pData, pData->pJPEGbuf, pData->iJPEGbufmax)
+ }
+
+ if (pData->pJPEGbuf2 == MNG_NULL)
+ {
+ pData->iJPEGbufmax2 = MNG_JPEG_MAXBUF;
+ MNG_ALLOC (pData, pData->pJPEGbuf2, pData->iJPEGbufmax2)
+ }
+
+ pData->pJPEGcurrent = pData->pJPEGbuf;
+ pData->iJPEGbufremain = 0;
+ pData->pJPEGrow = MNG_NULL;
+ pData->iJPEGrowlen = 0;
+ pData->iJPEGtoskip = 0;
+
+ pData->pJPEGcurrent2 = pData->pJPEGbuf2;
+ pData->iJPEGbufremain2 = 0;
+ pData->pJPEGrow2 = MNG_NULL;
+ pData->iJPEGrowlen2 = 0;
+ pData->iJPEGtoskip2 = 0;
+ /* not doing anything yet ! */
+ pData->bJPEGcompress = MNG_FALSE;
+
+ pData->bJPEGdecompress = MNG_FALSE;
+ pData->bJPEGhasheader = MNG_FALSE;
+ pData->bJPEGdecostarted = MNG_FALSE;
+ pData->bJPEGscanstarted = MNG_FALSE;
+
+ pData->bJPEGdecompress2 = MNG_FALSE;
+ pData->bJPEGhasheader2 = MNG_FALSE;
+ pData->bJPEGdecostarted2 = MNG_FALSE;
+ pData->bJPEGscanstarted2 = MNG_FALSE;
+
+ pData->iJPEGrow = 0; /* zero input/output lines */
+ pData->iJPEGalpharow = 0;
+ pData->iJPEGrgbrow = 0;
+ pData->iJPEGdisprow = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_INITIALIZE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mngjpeg_cleanup (mng_datap pData)
+{
+#if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
+ mng_retcode iRetcode;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_CLEANUP, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_IJG6B
+#ifdef MNG_USE_SETJMP
+ iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
+ if (iRetcode != 0) /* got here from longjmp ? */
+ MNG_ERRORJ (pData, iRetcode) /* then IJG-lib issued an error */
+#endif
+
+#ifdef MNG_INCLUDE_JNG_READ /* still decompressing something ? */
+ if (pData->bJPEGdecompress)
+ jpeg_destroy_decompress (pData->pJPEGdinfo);
+ if (pData->bJPEGdecompress2)
+ jpeg_destroy_decompress (pData->pJPEGdinfo2);
+#endif
+
+#ifdef MNG_INCLUDE_JNG_WRITE
+ if (pData->bJPEGcompress) /* still compressing something ? */
+ jpeg_destroy_compress (pData->pJPEGcinfo);
+#endif
+
+#endif /* MNG_INCLUDE_IJG6B */
+ /* cleanup temporary buffers */
+ MNG_FREE (pData, pData->pJPEGbuf2, pData->iJPEGbufmax2)
+ MNG_FREE (pData, pData->pJPEGbuf, pData->iJPEGbufmax)
+ /* cleanup space for JPEG structures */
+#ifdef MNG_INCLUDE_JNG_WRITE
+ MNG_FREE (pData, pData->pJPEGcinfo, sizeof (mngjpeg_comp ))
+ MNG_FREE (pData, pData->pJPEGcerr, sizeof (mngjpeg_error ))
+#endif
+
+#ifdef MNG_INCLUDE_JNG_READ
+ MNG_FREE (pData, pData->pJPEGdinfo, sizeof (mngjpeg_decomp))
+ MNG_FREE (pData, pData->pJPEGdsrc, sizeof (mngjpeg_source))
+ MNG_FREE (pData, pData->pJPEGderr, sizeof (mngjpeg_error ))
+ MNG_FREE (pData, pData->pJPEGdinfo2, sizeof (mngjpeg_decomp))
+ MNG_FREE (pData, pData->pJPEGdsrc2, sizeof (mngjpeg_source))
+ MNG_FREE (pData, pData->pJPEGderr2, sizeof (mngjpeg_error ))
+#endif
+
+ MNG_FREE (pData, pData->pJPEGrow2, pData->iJPEGrowlen2)
+ MNG_FREE (pData, pData->pJPEGrow, pData->iJPEGrowlen)
+ /* whatever we were doing ... */
+ /* we don't anymore ... */
+ pData->bJPEGcompress = MNG_FALSE;
+
+ pData->bJPEGdecompress = MNG_FALSE;
+ pData->bJPEGhasheader = MNG_FALSE;
+ pData->bJPEGdecostarted = MNG_FALSE;
+ pData->bJPEGscanstarted = MNG_FALSE;
+
+ pData->bJPEGdecompress2 = MNG_FALSE;
+ pData->bJPEGhasheader2 = MNG_FALSE;
+ pData->bJPEGdecostarted2 = MNG_FALSE;
+ pData->bJPEGscanstarted2 = MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_CLEANUP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * JPEG decompression routines (JDAT) * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+mng_retcode mngjpeg_decompressinit (mng_datap pData)
+{
+#if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
+ mng_retcode iRetcode;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_IJG6B
+ /* allocate and initialize a JPEG decompression object */
+ pData->pJPEGdinfo->err = jpeg_std_error (pData->pJPEGderr);
+
+#ifdef MNG_USE_SETJMP /* setup local JPEG error-routines */
+ pData->pJPEGderr->error_exit = mng_error_exit;
+ pData->pJPEGderr->output_message = mng_output_message;
+
+ iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
+ if (iRetcode != 0) /* got here from longjmp ? */
+ MNG_ERRORJ (pData, iRetcode) /* then IJG-lib issued an error */
+#endif /* MNG_USE_SETJMP */
+
+ /* allocate and initialize a JPEG decompression object (continued) */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_JPEG_CREATE_DECOMPRESS)
+#endif
+ jpeg_create_decompress (pData->pJPEGdinfo);
+
+ pData->bJPEGdecompress = MNG_TRUE; /* indicate it's initialized */
+
+ /* specify the source of the compressed data (eg, a file) */
+ /* no, not a file; we have buffered input */
+ pData->pJPEGdinfo->src = pData->pJPEGdsrc;
+ /* use the default handler */
+ pData->pJPEGdinfo->src->resync_to_restart = jpeg_resync_to_restart;
+ /* setup local source routine & parms */
+ pData->pJPEGdinfo->src->init_source = mng_init_source;
+ pData->pJPEGdinfo->src->fill_input_buffer = mng_fill_input_buffer;
+ pData->pJPEGdinfo->src->skip_input_data = mng_skip_input_data;
+ pData->pJPEGdinfo->src->term_source = mng_term_source;
+ pData->pJPEGdinfo->src->next_input_byte = pData->pJPEGcurrent;
+ pData->pJPEGdinfo->src->bytes_in_buffer = pData->iJPEGbufremain;
+
+#endif /* MNG_INCLUDE_IJG6B */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+mng_retcode mngjpeg_decompressdata (mng_datap pData,
+ mng_uint32 iRawsize,
+ mng_uint8p pRawdata)
+{
+ mng_retcode iRetcode;
+ mng_uint32 iRemain;
+ mng_uint8p pWork;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_START)
+#endif
+
+#if defined (MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
+ iRetcode = setjmp (pData->sErrorbuf);/* initialize local JPEG error-recovery */
+ if (iRetcode != 0) /* got here from longjmp ? */
+ MNG_ERRORJ (pData, iRetcode) /* then IJG-lib issued an error */
+#endif
+
+ pWork = pRawdata;
+ iRemain = iRawsize;
+
+ if (pData->iJPEGtoskip) /* JPEG-lib told us to skip some more data ? */
+ {
+ if (iRemain > pData->iJPEGtoskip) /* enough data in this buffer ? */
+ {
+ iRemain -= pData->iJPEGtoskip; /* skip enough to access the next byte */
+ pWork += pData->iJPEGtoskip;
+
+ pData->iJPEGtoskip = 0; /* no more to skip then */
+ }
+ else
+ {
+ pData->iJPEGtoskip -= iRemain; /* skip all data in the buffer */
+ iRemain = 0; /* and indicate this accordingly */
+ }
+ /* the skip set current-pointer to NULL ! */
+ pData->pJPEGcurrent = pData->pJPEGbuf;
+ }
+
+ while (iRemain) /* repeat until no more input-bytes */
+ { /* need to shift anything ? */
+ if ((pData->pJPEGcurrent > pData->pJPEGbuf) &&
+ (pData->pJPEGcurrent - pData->pJPEGbuf + pData->iJPEGbufremain + iRemain > pData->iJPEGbufmax))
+ {
+ if (pData->iJPEGbufremain > 0) /* then do so */
+ MNG_COPY (pData->pJPEGbuf, pData->pJPEGcurrent, pData->iJPEGbufremain)
+
+ pData->pJPEGcurrent = pData->pJPEGbuf;
+ }
+ /* does the remaining input fit into the buffer ? */
+ if (pData->iJPEGbufremain + iRemain <= pData->iJPEGbufmax)
+ { /* move the lot */
+ MNG_COPY ((pData->pJPEGcurrent + pData->iJPEGbufremain), pWork, iRemain)
+
+ pData->iJPEGbufremain += iRemain;/* adjust remaining_bytes counter */
+ iRemain = 0; /* and indicate there's no input left */
+ }
+ else
+ { /* calculate what does fit */
+ mng_uint32 iFits = pData->iJPEGbufmax - pData->iJPEGbufremain;
+
+ if (iFits <= 0) /* no space is just bugger 'm all */
+ MNG_ERROR (pData, MNG_JPEGBUFTOOSMALL)
+ /* move that */
+ MNG_COPY ((pData->pJPEGcurrent + pData->iJPEGbufremain), pWork, iFits)
+
+ pData->iJPEGbufremain += iFits; /* adjust remain_bytes counter */
+ iRemain -= iFits; /* and the input-parms */
+ pWork += iFits;
+ }
+
+#ifdef MNG_INCLUDE_IJG6B
+ pData->pJPEGdinfo->src->next_input_byte = pData->pJPEGcurrent;
+ pData->pJPEGdinfo->src->bytes_in_buffer = pData->iJPEGbufremain;
+
+ if (!pData->bJPEGhasheader) /* haven't got the header yet ? */
+ {
+ /* call jpeg_read_header() to obtain image info */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_HEADER)
+#endif
+ if (jpeg_read_header (pData->pJPEGdinfo, TRUE) != JPEG_SUSPENDED)
+ { /* indicate the header's oke */
+ pData->bJPEGhasheader = MNG_TRUE;
+ /* let's do some sanity checks ! */
+ if ((pData->pJPEGdinfo->image_width != pData->iDatawidth ) ||
+ (pData->pJPEGdinfo->image_height != pData->iDataheight) )
+ MNG_ERROR (pData, MNG_JPEGPARMSERR)
+
+ if ( ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAY ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA) ) &&
+ (pData->pJPEGdinfo->jpeg_color_space != JCS_GRAYSCALE ) )
+ MNG_ERROR (pData, MNG_JPEGPARMSERR)
+
+ if ( ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLOR ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) ) &&
+ (pData->pJPEGdinfo->jpeg_color_space != JCS_YCbCr ) )
+ MNG_ERROR (pData, MNG_JPEGPARMSERR)
+ /* indicate whether or not it's progressive */
+ pData->bJPEGprogressive = (mng_bool)jpeg_has_multiple_scans (pData->pJPEGdinfo);
+ /* progressive+alpha can't display "on-the-fly"!! */
+ if ((pData->bJPEGprogressive) &&
+ ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) ))
+ pData->fDisplayrow = MNG_NULL;
+ /* allocate a row of JPEG-samples */
+ if (pData->pJPEGdinfo->jpeg_color_space == JCS_YCbCr)
+ pData->iJPEGrowlen = pData->pJPEGdinfo->image_width * 3;
+ else
+ pData->iJPEGrowlen = pData->pJPEGdinfo->image_width;
+
+ MNG_ALLOC (pData, pData->pJPEGrow, pData->iJPEGrowlen)
+
+ pData->iJPEGrgbrow = 0; /* quite empty up to now */
+ }
+
+ pData->pJPEGcurrent = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
+ pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
+ }
+ /* decompress not started ? */
+ if ((pData->bJPEGhasheader) && (!pData->bJPEGdecostarted))
+ {
+ /* set parameters for decompression */
+
+ if (pData->bJPEGprogressive) /* progressive display ? */
+ pData->pJPEGdinfo->buffered_image = TRUE;
+
+ /* jpeg_start_decompress(...); */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_DECOMPRESS)
+#endif
+ if (jpeg_start_decompress (pData->pJPEGdinfo) == TRUE)
+ /* indicate it started */
+ pData->bJPEGdecostarted = MNG_TRUE;
+
+ pData->pJPEGcurrent = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
+ pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
+ }
+ /* process some scanlines ? */
+ if ((pData->bJPEGhasheader) && (pData->bJPEGdecostarted) &&
+ ((!jpeg_input_complete (pData->pJPEGdinfo)) ||
+ (pData->pJPEGdinfo->output_scanline < pData->pJPEGdinfo->output_height)))
+ {
+ mng_int32 iLines;
+
+ /* for (each output pass) */
+ do
+ { /* address the row output buffer */
+ JSAMPROW pRow = (JSAMPROW)pData->pJPEGrow;
+
+ /* init new pass ? */
+ if ((pData->bJPEGprogressive) &&
+ ((!pData->bJPEGscanstarted) ||
+ (pData->pJPEGdinfo->output_scanline >= pData->pJPEGdinfo->output_height)))
+ {
+ pData->bJPEGscanstarted = MNG_TRUE;
+
+ /* adjust output decompression parameters if required */
+ /* nop */
+
+ /* start a new output pass */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_OUTPUT)
+#endif
+ jpeg_start_output (pData->pJPEGdinfo, pData->pJPEGdinfo->input_scan_number);
+
+ pData->iJPEGrow = 0; /* start at row 0 in the image again */
+ }
+
+ /* while (scan lines remain to be read) */
+ do
+ {
+ /* jpeg_read_scanlines(...); */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_SCANLINES)
+#endif
+ iLines = jpeg_read_scanlines (pData->pJPEGdinfo, (JSAMPARRAY)&pRow, 1);
+
+ pData->pJPEGcurrent = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
+ pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
+
+ if (iLines > 0) /* got something ? */
+ {
+ if (pData->fStorerow2) /* store in object ? */
+ {
+ iRetcode = ((mng_storerow)pData->fStorerow2) (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+ }
+ }
+ while ((pData->pJPEGdinfo->output_scanline < pData->pJPEGdinfo->output_height) &&
+ (iLines > 0)); /* until end-of-image or not enough input-data */
+
+ /* terminate output pass */
+ if ((pData->bJPEGprogressive) &&
+ (pData->pJPEGdinfo->output_scanline >= pData->pJPEGdinfo->output_height))
+ {
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_OUTPUT)
+#endif
+ jpeg_finish_output (pData->pJPEGdinfo);
+ /* this scan has ended */
+ pData->bJPEGscanstarted = MNG_FALSE;
+ }
+ }
+ while ((!jpeg_input_complete (pData->pJPEGdinfo)) && (iLines > 0));
+ }
+ /* end of image ? */
+ if ((pData->bJPEGhasheader) && (pData->bJPEGdecostarted) &&
+ (jpeg_input_complete (pData->pJPEGdinfo)) &&
+ (pData->pJPEGdinfo->input_scan_number == pData->pJPEGdinfo->output_scan_number))
+ {
+ /* jpeg_finish_decompress(...); */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_DECOMPRESS)
+#endif
+ if (jpeg_finish_decompress (pData->pJPEGdinfo) == TRUE)
+ { /* indicate it's done */
+ pData->bJPEGhasheader = MNG_FALSE;
+ pData->bJPEGdecostarted = MNG_FALSE;
+ pData->pJPEGcurrent = (mng_uint8p)pData->pJPEGdinfo->src->next_input_byte;
+ pData->iJPEGbufremain = (mng_uint32)pData->pJPEGdinfo->src->bytes_in_buffer;
+ /* remaining fluff is an error ! */
+ if ((pData->iJPEGbufremain > 0) || (iRemain > 0))
+ MNG_ERROR (pData, MNG_TOOMUCHJDAT)
+ }
+ }
+#endif /* MNG_INCLUDE_IJG6B */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+mng_retcode mngjpeg_decompressfree (mng_datap pData)
+{
+#if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
+ mng_retcode iRetcode;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_IJG6B
+#ifdef MNG_USE_SETJMP
+ iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
+ if (iRetcode != 0) /* got here from longjmp ? */
+ MNG_ERRORJ (pData, iRetcode) /* then IJG-lib issued an error */
+#endif
+ /* free the row of JPEG-samples*/
+ MNG_FREE (pData, pData->pJPEGrow, pData->iJPEGrowlen)
+
+ /* release the JPEG decompression object */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_JPEG_DESTROY_DECOMPRESS)
+#endif
+ jpeg_destroy_decompress (pData->pJPEGdinfo);
+
+ pData->bJPEGdecompress = MNG_FALSE; /* indicate it's done */
+
+#endif /* MNG_INCLUDE_IJG6B */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+/* * * */
+/* * JPEG decompression routines (JDAA) * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+mng_retcode mngjpeg_decompressinit2 (mng_datap pData)
+{
+#if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
+ mng_retcode iRetcode;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_IJG6B
+ /* allocate and initialize a JPEG decompression object */
+ pData->pJPEGdinfo2->err = jpeg_std_error (pData->pJPEGderr2);
+
+#ifdef MNG_USE_SETJMP /* setup local JPEG error-routines */
+ pData->pJPEGderr2->error_exit = mng_error_exit;
+ pData->pJPEGderr2->output_message = mng_output_message;
+
+ iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
+ if (iRetcode != 0) /* got here from longjmp ? */
+ MNG_ERRORJ (pData, iRetcode) /* then IJG-lib issued an error */
+#endif /* MNG_USE_SETJMP */
+
+ /* allocate and initialize a JPEG decompression object (continued) */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_JPEG_CREATE_DECOMPRESS)
+#endif
+ jpeg_create_decompress (pData->pJPEGdinfo2);
+
+ pData->bJPEGdecompress2 = MNG_TRUE; /* indicate it's initialized */
+
+ /* specify the source of the compressed data (eg, a file) */
+ /* no, not a file; we have buffered input */
+ pData->pJPEGdinfo2->src = pData->pJPEGdsrc2;
+ /* use the default handler */
+ pData->pJPEGdinfo2->src->resync_to_restart = jpeg_resync_to_restart;
+ /* setup local source routine & parms */
+ pData->pJPEGdinfo2->src->init_source = mng_init_source;
+ pData->pJPEGdinfo2->src->fill_input_buffer = mng_fill_input_buffer;
+ pData->pJPEGdinfo2->src->skip_input_data = mng_skip_input_data2;
+ pData->pJPEGdinfo2->src->term_source = mng_term_source;
+ pData->pJPEGdinfo2->src->next_input_byte = pData->pJPEGcurrent2;
+ pData->pJPEGdinfo2->src->bytes_in_buffer = pData->iJPEGbufremain2;
+
+#endif /* MNG_INCLUDE_IJG6B */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSINIT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+mng_retcode mngjpeg_decompressdata2 (mng_datap pData,
+ mng_uint32 iRawsize,
+ mng_uint8p pRawdata)
+{
+ mng_retcode iRetcode;
+ mng_uint32 iRemain;
+ mng_uint8p pWork;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_START)
+#endif
+
+#if defined (MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
+ iRetcode = setjmp (pData->sErrorbuf);/* initialize local JPEG error-recovery */
+ if (iRetcode != 0) /* got here from longjmp ? */
+ MNG_ERRORJ (pData, iRetcode) /* then IJG-lib issued an error */
+#endif
+
+ pWork = pRawdata;
+ iRemain = iRawsize;
+
+ if (pData->iJPEGtoskip2) /* JPEG-lib told us to skip some more data ? */
+ {
+ if (iRemain > pData->iJPEGtoskip2) /* enough data in this buffer ? */
+ {
+ iRemain -= pData->iJPEGtoskip2; /* skip enough to access the next byte */
+ pWork += pData->iJPEGtoskip2;
+
+ pData->iJPEGtoskip2 = 0; /* no more to skip then */
+ }
+ else
+ {
+ pData->iJPEGtoskip2 -= iRemain; /* skip all data in the buffer */
+ iRemain = 0; /* and indicate this accordingly */
+ }
+ /* the skip set current-pointer to NULL ! */
+ pData->pJPEGcurrent2 = pData->pJPEGbuf2;
+ }
+
+ while (iRemain) /* repeat until no more input-bytes */
+ { /* need to shift anything ? */
+ if ((pData->pJPEGcurrent2 > pData->pJPEGbuf2) &&
+ (pData->pJPEGcurrent2 - pData->pJPEGbuf2 + pData->iJPEGbufremain2 + iRemain > pData->iJPEGbufmax2))
+ {
+ if (pData->iJPEGbufremain2 > 0) /* then do so */
+ MNG_COPY (pData->pJPEGbuf2, pData->pJPEGcurrent2, pData->iJPEGbufremain2)
+
+ pData->pJPEGcurrent2 = pData->pJPEGbuf2;
+ }
+ /* does the remaining input fit into the buffer ? */
+ if (pData->iJPEGbufremain2 + iRemain <= pData->iJPEGbufmax2)
+ { /* move the lot */
+ MNG_COPY ((pData->pJPEGcurrent2 + pData->iJPEGbufremain2), pWork, iRemain)
+ /* adjust remaining_bytes counter */
+ pData->iJPEGbufremain2 += iRemain;
+ iRemain = 0; /* and indicate there's no input left */
+ }
+ else
+ { /* calculate what does fit */
+ mng_uint32 iFits = pData->iJPEGbufmax2 - pData->iJPEGbufremain2;
+
+ if (iFits <= 0) /* no space is just bugger 'm all */
+ MNG_ERROR (pData, MNG_JPEGBUFTOOSMALL)
+ /* move that */
+ MNG_COPY ((pData->pJPEGcurrent2 + pData->iJPEGbufremain2), pWork, iFits)
+
+ pData->iJPEGbufremain2 += iFits; /* adjust remain_bytes counter */
+ iRemain -= iFits; /* and the input-parms */
+ pWork += iFits;
+ }
+
+#ifdef MNG_INCLUDE_IJG6B
+ pData->pJPEGdinfo2->src->next_input_byte = pData->pJPEGcurrent2;
+ pData->pJPEGdinfo2->src->bytes_in_buffer = pData->iJPEGbufremain2;
+
+ if (!pData->bJPEGhasheader2) /* haven't got the header yet ? */
+ {
+ /* call jpeg_read_header() to obtain image info */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_HEADER)
+#endif
+ if (jpeg_read_header (pData->pJPEGdinfo2, TRUE) != JPEG_SUSPENDED)
+ { /* indicate the header's oke */
+ pData->bJPEGhasheader2 = MNG_TRUE;
+ /* let's do some sanity checks ! */
+ if ((pData->pJPEGdinfo2->image_width != pData->iDatawidth ) ||
+ (pData->pJPEGdinfo2->image_height != pData->iDataheight) )
+ MNG_ERROR (pData, MNG_JPEGPARMSERR)
+
+ if (pData->pJPEGdinfo2->jpeg_color_space != JCS_GRAYSCALE)
+ MNG_ERROR (pData, MNG_JPEGPARMSERR)
+ /* indicate whether or not it's progressive */
+ pData->bJPEGprogressive2 = (mng_bool)jpeg_has_multiple_scans (pData->pJPEGdinfo2);
+
+ if (pData->bJPEGprogressive2) /* progressive alphachannel not allowed !!! */
+ MNG_ERROR (pData, MNG_JPEGPARMSERR)
+ /* allocate a row of JPEG-samples */
+ if (pData->pJPEGdinfo2->jpeg_color_space == JCS_YCbCr)
+ pData->iJPEGrowlen2 = pData->pJPEGdinfo2->image_width * 3;
+ else
+ pData->iJPEGrowlen2 = pData->pJPEGdinfo2->image_width;
+
+ MNG_ALLOC (pData, pData->pJPEGrow2, pData->iJPEGrowlen2)
+
+ pData->iJPEGalpharow = 0; /* quite empty up to now */
+ }
+
+ pData->pJPEGcurrent2 = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
+ pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
+ }
+ /* decompress not started ? */
+ if ((pData->bJPEGhasheader2) && (!pData->bJPEGdecostarted2))
+ {
+ /* set parameters for decompression */
+
+ if (pData->bJPEGprogressive2) /* progressive display ? */
+ pData->pJPEGdinfo2->buffered_image = TRUE;
+
+ /* jpeg_start_decompress(...); */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_DECOMPRESS)
+#endif
+ if (jpeg_start_decompress (pData->pJPEGdinfo2) == TRUE)
+ /* indicate it started */
+ pData->bJPEGdecostarted2 = MNG_TRUE;
+
+ pData->pJPEGcurrent2 = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
+ pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
+ }
+ /* process some scanlines ? */
+ if ((pData->bJPEGhasheader2) && (pData->bJPEGdecostarted2) &&
+ ((!jpeg_input_complete (pData->pJPEGdinfo2)) ||
+ (pData->pJPEGdinfo2->output_scanline < pData->pJPEGdinfo2->output_height)))
+ {
+ mng_int32 iLines;
+
+ /* for (each output pass) */
+ do
+ { /* address the row output buffer */
+ JSAMPROW pRow = (JSAMPROW)pData->pJPEGrow2;
+
+ /* init new pass ? */
+ if ((pData->bJPEGprogressive2) &&
+ ((!pData->bJPEGscanstarted2) ||
+ (pData->pJPEGdinfo2->output_scanline >= pData->pJPEGdinfo2->output_height)))
+ {
+ pData->bJPEGscanstarted2 = MNG_TRUE;
+
+ /* adjust output decompression parameters if required */
+ /* nop */
+
+ /* start a new output pass */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_START_OUTPUT)
+#endif
+ jpeg_start_output (pData->pJPEGdinfo2, pData->pJPEGdinfo2->input_scan_number);
+
+ pData->iJPEGrow = 0; /* start at row 0 in the image again */
+ }
+
+ /* while (scan lines remain to be read) */
+ do
+ {
+ /* jpeg_read_scanlines(...); */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_READ_SCANLINES)
+#endif
+ iLines = jpeg_read_scanlines (pData->pJPEGdinfo2, (JSAMPARRAY)&pRow, 1);
+
+ pData->pJPEGcurrent2 = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
+ pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
+
+ if (iLines > 0) /* got something ? */
+ {
+ if (pData->fStorerow3) /* store in object ? */
+ {
+ iRetcode = ((mng_storerow)pData->fStorerow3) (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+ }
+ }
+ while ((pData->pJPEGdinfo2->output_scanline < pData->pJPEGdinfo2->output_height) &&
+ (iLines > 0)); /* until end-of-image or not enough input-data */
+
+ /* terminate output pass */
+ if ((pData->bJPEGprogressive2) &&
+ (pData->pJPEGdinfo2->output_scanline >= pData->pJPEGdinfo2->output_height))
+ {
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_OUTPUT)
+#endif
+ jpeg_finish_output (pData->pJPEGdinfo2);
+ /* this scan has ended */
+ pData->bJPEGscanstarted2 = MNG_FALSE;
+ }
+ }
+ while ((!jpeg_input_complete (pData->pJPEGdinfo2)) && (iLines > 0));
+ }
+ /* end of image ? */
+ if ((pData->bJPEGhasheader2) && (pData->bJPEGdecostarted2) &&
+ (jpeg_input_complete (pData->pJPEGdinfo2)) &&
+ (pData->pJPEGdinfo2->input_scan_number == pData->pJPEGdinfo2->output_scan_number))
+ {
+ /* jpeg_finish_decompress(...); */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_JPEG_FINISH_DECOMPRESS)
+#endif
+ if (jpeg_finish_decompress (pData->pJPEGdinfo2) == TRUE)
+ { /* indicate it's done */
+ pData->bJPEGhasheader2 = MNG_FALSE;
+ pData->bJPEGdecostarted2 = MNG_FALSE;
+ pData->pJPEGcurrent2 = (mng_uint8p)pData->pJPEGdinfo2->src->next_input_byte;
+ pData->iJPEGbufremain2 = (mng_uint32)pData->pJPEGdinfo2->src->bytes_in_buffer;
+ /* remaining fluff is an error ! */
+ if ((pData->iJPEGbufremain2 > 0) || (iRemain > 0))
+ MNG_ERROR (pData, MNG_TOOMUCHJDAT)
+ }
+ }
+#endif /* MNG_INCLUDE_IJG6B */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSDATA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG_READ
+mng_retcode mngjpeg_decompressfree2 (mng_datap pData)
+{
+#if defined(MNG_INCLUDE_IJG6B) && defined(MNG_USE_SETJMP)
+ mng_retcode iRetcode;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_IJG6B
+#ifdef MNG_USE_SETJMP
+ iRetcode = setjmp (pData->sErrorbuf);/* setup local JPEG error-recovery */
+ if (iRetcode != 0) /* got here from longjmp ? */
+ MNG_ERRORJ (pData, iRetcode) /* then IJG-lib issued an error */
+#endif
+ /* free the row of JPEG-samples*/
+ MNG_FREE (pData, pData->pJPEGrow2, pData->iJPEGrowlen2)
+
+ /* release the JPEG decompression object */
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_JPEG_DESTROY_DECOMPRESS)
+#endif
+ jpeg_destroy_decompress (pData->pJPEGdinfo2);
+
+ pData->bJPEGdecompress2 = MNG_FALSE; /* indicate it's done */
+
+#endif /* MNG_INCLUDE_IJG6B */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_JPEG_DECOMPRESSFREE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG_READ */
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_jpeg.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_jpeg.h
new file mode 100644
index 0000000..0f1aa6f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_jpeg.h
@@ -0,0 +1,59 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_jpeg.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : JPEG library interface (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the JPEG library interface * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added support for JDAA * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_jpeg_h_
+#define _libmng_jpeg_h_
+
+/* ************************************************************************** */
+
+mng_retcode mngjpeg_initialize (mng_datap pData);
+mng_retcode mngjpeg_cleanup (mng_datap pData);
+
+mng_retcode mngjpeg_decompressinit (mng_datap pData);
+mng_retcode mngjpeg_decompressdata (mng_datap pData,
+ mng_uint32 iRawsize,
+ mng_uint8p pRawdata);
+mng_retcode mngjpeg_decompressfree (mng_datap pData);
+
+mng_retcode mngjpeg_decompressinit2 (mng_datap pData);
+mng_retcode mngjpeg_decompressdata2 (mng_datap pData,
+ mng_uint32 iRawsize,
+ mng_uint8p pRawdata);
+mng_retcode mngjpeg_decompressfree2 (mng_datap pData);
+
+/* ************************************************************************** */
+
+#endif /* _libmng_jpeg_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_memory.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_memory.h
new file mode 100644
index 0000000..568d324
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_memory.h
@@ -0,0 +1,66 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_memory.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Memory management (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of memory management functions * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.5.3 - 06/12/2000 - G.Juyn * */
+/* * - swapped MNG_COPY parameter-names * */
+/* * 0.5.3 - 06/27/2000 - G.Juyn * */
+/* * - changed size parameter to mng_size_t * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_memory_h_
+#define _libmng_memory_h_
+
+/* ************************************************************************** */
+/* * * */
+/* * Generic memory manager macros * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INTERNAL_MEMMNGMT
+#define MNG_ALLOC(H,P,L) { P = calloc (1, (mng_size_t)(L)); \
+ if (P == 0) { MNG_ERROR (H, MNG_OUTOFMEMORY) } }
+#define MNG_ALLOCX(H,P,L) { P = calloc (1, (mng_size_t)(L)); }
+#define MNG_FREE(H,P,L) { if (P) { free (P); P = 0; } }
+#define MNG_FREEX(H,P,L) { if (P) free (P); }
+#else
+#define MNG_ALLOC(H,P,L) { P = H->fMemalloc ((mng_size_t)(L)); \
+ if (P == 0) { MNG_ERROR (H, MNG_OUTOFMEMORY) } }
+#define MNG_ALLOCX(H,P,L) { P = H->fMemalloc ((mng_size_t)(L)); }
+#define MNG_FREE(H,P,L) { if (P) { H->fMemfree (P, (mng_size_t)(L)); P = 0; } }
+#define MNG_FREEX(H,P,L) { if (P) { H->fMemfree (P, (mng_size_t)(L)); } }
+#endif /* mng_internal_memmngmt */
+
+#define MNG_COPY(D,S,L) { memcpy (D, S, (mng_size_t)(L)); }
+
+/* ************************************************************************** */
+
+#endif /* _libmng_memory_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_object_prc.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_object_prc.c
new file mode 100644
index 0000000..31d8ace
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_object_prc.c
@@ -0,0 +1,3828 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_object_prc.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.2 * */
+/* * * */
+/* * purpose : Object processing routines (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the internal object processing routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * * */
+/* * 0.5.2 - 05/20/2000 - G.Juyn * */
+/* * - fixed to support JNG objects * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - added support for global color-chunks in animation * */
+/* * - added support for global PLTE,tRNS,bKGD in animation * */
+/* * - added SAVE & SEEK animation objects * */
+/* * 0.5.2 - 05/29/2000 - G.Juyn * */
+/* * - added initialization of framenr/layernr/playtime * */
+/* * - changed ani_object create routines not to return the * */
+/* * created object (wasn't necessary) * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added object promotion routine (PROM handling) * */
+/* * - added ani-object routines for delta-image processing * */
+/* * - added compression/filter/interlace fields to * */
+/* * object-buffer for delta-image processing * */
+/* * * */
+/* * 0.5.3 - 06/17/2000 - G.Juyn * */
+/* * - changed support for delta-image processing * */
+/* * 0.5.3 - 06/20/2000 - G.Juyn * */
+/* * - fixed some small things (as precaution) * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added processing of PLTE/tRNS & color-info for * */
+/* * delta-images in the ani_objects chain * */
+/* * 0.5.3 - 06/22/2000 - G.Juyn * */
+/* * - added support for PPLT chunk * */
+/* * * */
+/* * 0.9.1 - 07/07/2000 - G.Juyn * */
+/* * - added support for freeze/restart/resume & go_xxxx * */
+/* * 0.9.1 - 07/16/2000 - G.Juyn * */
+/* * - fixed support for mng_display() after mng_read() * */
+/* * * */
+/* * 0.9.2 - 07/29/2000 - G.Juyn * */
+/* * - fixed small bugs in display processing * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/07/2000 - G.Juyn * */
+/* * - B111300 - fixup for improved portability * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/10/2000 - G.Juyn * */
+/* * - fixed DEFI behavior * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - added valid-flag to stored objects for read() / display()* */
+/* * - added routine to discard "invalid" objects * */
+/* * 0.9.3 - 10/18/2000 - G.Juyn * */
+/* * - fixed delta-processing behavior * */
+/* * 0.9.3 - 10/19/2000 - G.Juyn * */
+/* * - added storage for pixel-/alpha-sampledepth for delta's * */
+/* * * */
+/* * 0.9.4 - 1/18/2001 - G.Juyn * */
+/* * - removed "old" MAGN methods 3 & 4 * */
+/* * - added "new" MAGN methods 3, 4 & 5 * */
+/* * * */
+/* * 0.9.5 - 1/22/2001 - G.Juyn * */
+/* * - B129681 - fixed compiler warnings SGI/Irix * */
+/* * * */
+/* * 1.0.2 - 06/23/2001 - G.Juyn * */
+/* * - added optimization option for MNG-video playback * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_memory.h"
+#include "libmng_objects.h"
+#include "libmng_display.h"
+#include "libmng_pixels.h"
+#include "libmng_object_prc.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_DISPLAY_PROCS
+
+/* ************************************************************************** */
+/* * * */
+/* * Generic object routines * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode drop_invalid_objects (mng_datap pData)
+{
+ mng_objectp pObject;
+ mng_objectp pNext;
+ mng_cleanupobject fCleanup;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DROP_INVALID_OBJECTS, MNG_LC_START)
+#endif
+
+ pObject = pData->pFirstimgobj; /* get first stored image-object (if any) */
+
+ while (pObject) /* more objects to check ? */
+ {
+ pNext = ((mng_object_headerp)pObject)->pNext;
+ /* invalid ? */
+ if (!((mng_imagep)pObject)->bValid)
+ { /* call appropriate cleanup */
+ fCleanup = ((mng_object_headerp)pObject)->fCleanup;
+ fCleanup (pData, pObject);
+ }
+
+ pObject = pNext; /* neeeext */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DROP_INVALID_OBJECTS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Image-data-object routines * */
+/* * * */
+/* * these handle the "object buffer" as defined by the MNG specification * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode create_imagedataobject (mng_datap pData,
+ mng_bool bConcrete,
+ mng_bool bViewable,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace,
+ mng_imagedatap *ppObject)
+{
+ mng_imagedatap pImagedata;
+ mng_uint32 iSamplesize = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_IMGDATAOBJECT, MNG_LC_START)
+#endif
+ /* get a buffer */
+ MNG_ALLOC (pData, pImagedata, sizeof (mng_imagedata))
+ /* fill the appropriate fields */
+ pImagedata->sHeader.fCleanup = (mng_cleanupobject)free_imagedataobject;
+ pImagedata->sHeader.fProcess = 0;
+ pImagedata->iRefcount = 1;
+ pImagedata->bFrozen = MNG_FALSE;
+ pImagedata->bConcrete = bConcrete;
+ pImagedata->bViewable = bViewable;
+ pImagedata->iWidth = iWidth;
+ pImagedata->iHeight = iHeight;
+ pImagedata->iBitdepth = iBitdepth;
+ pImagedata->iColortype = iColortype;
+ pImagedata->iCompression = iCompression;
+ pImagedata->iFilter = iFilter;
+ pImagedata->iInterlace = iInterlace;
+ pImagedata->iAlphabitdepth = 0;
+ pImagedata->iJHDRcompression = 0;
+ pImagedata->iJHDRinterlace = 0;
+ pImagedata->iPixelsampledepth = iBitdepth;
+ pImagedata->iAlphasampledepth = iBitdepth;
+ /* determine samplesize from color_type/bit_depth */
+ switch (iColortype) /* for < 8-bit samples we just reserve 8 bits */
+ {
+ case 0 : ; /* gray */
+ case 8 : { /* JPEG gray */
+ if (iBitdepth > 8)
+ iSamplesize = 2;
+ else
+ iSamplesize = 1;
+
+ break;
+ }
+ case 2 : ; /* rgb */
+ case 10 : { /* JPEG rgb */
+ if (iBitdepth > 8)
+ iSamplesize = 6;
+ else
+ iSamplesize = 3;
+
+ break;
+ }
+ case 3 : { /* indexed */
+ iSamplesize = 1;
+ break;
+ }
+ case 4 : ; /* gray+alpha */
+ case 12 : { /* JPEG gray+alpha */
+ if (iBitdepth > 8)
+ iSamplesize = 4;
+ else
+ iSamplesize = 2;
+
+ break;
+ }
+ case 6 : ; /* rgb+alpha */
+ case 14 : { /* JPEG rgb+alpha */
+ if (iBitdepth > 8)
+ iSamplesize = 8;
+ else
+ iSamplesize = 4;
+
+ break;
+ }
+ }
+ /* make sure we remember all this */
+ pImagedata->iSamplesize = iSamplesize;
+ pImagedata->iRowsize = iSamplesize * iWidth;
+ pImagedata->iImgdatasize = pImagedata->iRowsize * iHeight;
+
+ if (pImagedata->iImgdatasize) /* need a buffer ? */
+ { /* so allocate it */
+ MNG_ALLOCX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize)
+
+ if (!pImagedata->pImgdata) /* enough memory ? */
+ {
+ MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata))
+ MNG_ERROR (pData, MNG_OUTOFMEMORY)
+ }
+ }
+ /* check global stuff */
+ pImagedata->bHasGAMA = pData->bHasglobalGAMA;
+ pImagedata->bHasCHRM = pData->bHasglobalCHRM;
+ pImagedata->bHasSRGB = pData->bHasglobalSRGB;
+ pImagedata->bHasICCP = pData->bHasglobalICCP;
+ pImagedata->bHasBKGD = pData->bHasglobalBKGD;
+
+ if (pData->bHasglobalGAMA) /* global gAMA present ? */
+ pImagedata->iGamma = pData->iGlobalGamma;
+
+ if (pData->bHasglobalCHRM) /* global cHRM present ? */
+ {
+ pImagedata->iWhitepointx = pData->iGlobalWhitepointx;
+ pImagedata->iWhitepointy = pData->iGlobalWhitepointy;
+ pImagedata->iPrimaryredx = pData->iGlobalPrimaryredx;
+ pImagedata->iPrimaryredy = pData->iGlobalPrimaryredy;
+ pImagedata->iPrimarygreenx = pData->iGlobalPrimarygreenx;
+ pImagedata->iPrimarygreeny = pData->iGlobalPrimarygreeny;
+ pImagedata->iPrimarybluex = pData->iGlobalPrimarybluex;
+ pImagedata->iPrimarybluey = pData->iGlobalPrimarybluey;
+ }
+
+ if (pData->bHasglobalSRGB) /* glbal sRGB present ? */
+ pImagedata->iRenderingintent = pData->iGlobalRendintent;
+
+ if (pData->bHasglobalICCP) /* glbal iCCP present ? */
+ {
+ pImagedata->iProfilesize = pData->iGlobalProfilesize;
+
+ if (pImagedata->iProfilesize)
+ {
+ MNG_ALLOCX (pData, pImagedata->pProfile, pImagedata->iProfilesize)
+
+ if (!pImagedata->pProfile) /* enough memory ? */
+ {
+ MNG_FREEX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize)
+ MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata))
+ MNG_ERROR (pData, MNG_OUTOFMEMORY)
+ }
+
+ MNG_COPY (pImagedata->pProfile, pData->pGlobalProfile, pImagedata->iProfilesize)
+ }
+ }
+
+ if (pData->bHasglobalBKGD) /* global bKGD present ? */
+ {
+ pImagedata->iBKGDred = pData->iGlobalBKGDred;
+ pImagedata->iBKGDgreen = pData->iGlobalBKGDgreen;
+ pImagedata->iBKGDblue = pData->iGlobalBKGDblue;
+ }
+
+ *ppObject = pImagedata; /* return it */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_IMGDATAOBJECT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_imagedataobject (mng_datap pData,
+ mng_imagedatap pImagedata)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IMGDATAOBJECT, MNG_LC_START)
+#endif
+
+ if (pImagedata->iRefcount) /* decrease reference count */
+ pImagedata->iRefcount--;
+
+ if (!pImagedata->iRefcount) /* reached zero ? */
+ {
+ if (pImagedata->iProfilesize) /* stored an iCCP profile ? */
+ MNG_FREEX (pData, pImagedata->pProfile, pImagedata->iProfilesize)
+
+ if (pImagedata->iImgdatasize) /* sample-buffer present ? */
+ MNG_FREEX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize)
+ /* drop the buffer */
+ MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata))
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IMGDATAOBJECT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode clone_imagedataobject (mng_datap pData,
+ mng_bool bConcrete,
+ mng_imagedatap pSource,
+ mng_imagedatap *ppClone)
+{
+ mng_imagedatap pNewdata;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLONE_IMGDATAOBJECT, MNG_LC_START)
+#endif
+ /* get a buffer */
+ MNG_ALLOC (pData, pNewdata, sizeof (mng_imagedata))
+ /* blatently copy the original buffer */
+ MNG_COPY (pNewdata, pSource, sizeof (mng_imagedata))
+
+ pNewdata->iRefcount = 1; /* only the reference count */
+ pNewdata->bConcrete = bConcrete; /* and concrete-flag are different */
+
+ if (pNewdata->iImgdatasize) /* sample buffer present ? */
+ {
+ MNG_ALLOCX (pData, pNewdata->pImgdata, pNewdata->iImgdatasize)
+
+ if (!pNewdata->pImgdata) /* not enough memory ? */
+ {
+ MNG_FREEX (pData, pNewdata, sizeof (mng_imagedata))
+ MNG_ERROR (pData, MNG_OUTOFMEMORY)
+ }
+ /* make a copy */
+ MNG_COPY (pNewdata->pImgdata, pSource->pImgdata, pNewdata->iImgdatasize)
+ }
+
+ if (pNewdata->iProfilesize) /* iCCP profile present ? */
+ {
+ MNG_ALLOCX (pData, pNewdata->pProfile, pNewdata->iProfilesize)
+
+ if (!pNewdata->pProfile) /* enough memory ? */
+ {
+ MNG_FREEX (pData, pNewdata, sizeof (mng_imagedata))
+ MNG_ERROR (pData, MNG_OUTOFMEMORY)
+ }
+ /* make a copy */
+ MNG_COPY (pNewdata->pProfile, pSource->pProfile, pNewdata->iProfilesize)
+ }
+
+ *ppClone = pNewdata; /* return the clone */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLONE_IMGDATAOBJECT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Image-object routines * */
+/* * * */
+/* * these handle the "object" as defined by the MNG specification * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode create_imageobject (mng_datap pData,
+ mng_uint16 iId,
+ mng_bool bConcrete,
+ mng_bool bVisible,
+ mng_bool bViewable,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace,
+ mng_int32 iPosx,
+ mng_int32 iPosy,
+ mng_bool bClipped,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb,
+ mng_imagep *ppObject)
+{
+ mng_imagep pImage;
+ mng_imagep pPrev, pNext;
+ mng_retcode iRetcode;
+ mng_imagedatap pImgbuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_IMGOBJECT, MNG_LC_START)
+#endif
+ /* get a buffer */
+ MNG_ALLOC (pData, pImage, sizeof (mng_image))
+ /* now get a new "object buffer" */
+ iRetcode = create_imagedataobject (pData, bConcrete, bViewable,
+ iWidth, iHeight, iBitdepth, iColortype,
+ iCompression, iFilter, iInterlace,
+ &pImgbuf);
+
+ if (iRetcode) /* on error bail out */
+ {
+ MNG_FREEX (pData, pImage, sizeof (mng_image))
+ return iRetcode;
+ }
+ /* fill the appropriate fields */
+ pImage->sHeader.fCleanup = (mng_cleanupobject)free_imageobject;
+ pImage->sHeader.fProcess = 0;
+ pImage->iId = iId;
+ pImage->bFrozen = MNG_FALSE;
+ pImage->bVisible = bVisible;
+ pImage->bViewable = bViewable;
+ pImage->bValid = (mng_bool)((pData->bDisplaying) &&
+ (pData->bRunning ) &&
+ (!pData->bFreezing ) );
+ pImage->iPosx = iPosx;
+ pImage->iPosy = iPosy;
+ pImage->bClipped = bClipped;
+ pImage->iClipl = iClipl;
+ pImage->iClipr = iClipr;
+ pImage->iClipt = iClipt;
+ pImage->iClipb = iClipb;
+ pImage->iMAGN_MethodX = 0;
+ pImage->iMAGN_MethodY = 0;
+ pImage->iMAGN_MX = 0;
+ pImage->iMAGN_MY = 0;
+ pImage->iMAGN_ML = 0;
+ pImage->iMAGN_MR = 0;
+ pImage->iMAGN_MT = 0;
+ pImage->iMAGN_MB = 0;
+ pImage->pImgbuf = pImgbuf;
+
+ if (iId) /* only if not object 0 ! */
+ { /* tqfind previous lower object-id */
+ pPrev = (mng_imagep)pData->pLastimgobj;
+
+ while ((pPrev) && (pPrev->iId > iId))
+ pPrev = (mng_imagep)pPrev->sHeader.pPrev;
+
+ if (pPrev) /* found it ? */
+ {
+ pImage->sHeader.pPrev = pPrev; /* than link it in place */
+ pImage->sHeader.pNext = pPrev->sHeader.pNext;
+ pPrev->sHeader.pNext = pImage;
+ }
+ else /* if not found, it becomes the first ! */
+ {
+ pImage->sHeader.pNext = pData->pFirstimgobj;
+ pData->pFirstimgobj = pImage;
+ }
+
+ pNext = (mng_imagep)pImage->sHeader.pNext;
+
+ if (pNext)
+ pNext->sHeader.pPrev = pImage;
+ else
+ pData->pLastimgobj = pImage;
+
+ }
+
+ *ppObject = pImage; /* and return the new buffer */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_IMGOBJECT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* okido */
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_imageobject (mng_datap pData,
+ mng_imagep pImage)
+{
+ mng_retcode iRetcode;
+ mng_imagep pPrev = pImage->sHeader.pPrev;
+ mng_imagep pNext = pImage->sHeader.pNext;
+ mng_imagedatap pImgbuf = pImage->pImgbuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IMGOBJECT, MNG_LC_START)
+#endif
+
+ if (pImage->iId) /* not for object 0 */
+ {
+ if (pPrev) /* unlink from the list first ! */
+ pPrev->sHeader.pNext = pImage->sHeader.pNext;
+ else
+ pData->pFirstimgobj = pImage->sHeader.pNext;
+
+ if (pNext)
+ pNext->sHeader.pPrev = pImage->sHeader.pPrev;
+ else
+ pData->pLastimgobj = pImage->sHeader.pPrev;
+
+ }
+ /* unlink the image-data buffer */
+ iRetcode = free_imagedataobject (pData, pImgbuf);
+ /* drop it's own buffer */
+ MNG_FREEX (pData, pImage, sizeof (mng_image))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_IMGOBJECT, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+mng_imagep tqfind_imageobject (mng_datap pData,
+ mng_uint16 iId)
+{
+ mng_imagep pImage = (mng_imagep)pData->pFirstimgobj;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (pData, MNG_FN_FIND_IMGOBJECT, MNG_LC_START)
+#endif
+ /* look up the right id */
+ while ((pImage) && (pImage->iId != iId))
+ pImage = (mng_imagep)pImage->sHeader.pNext;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (pData, MNG_FN_FIND_IMGOBJECT, MNG_LC_END)
+#endif
+
+ return pImage;
+}
+
+/* ************************************************************************** */
+
+mng_retcode clone_imageobject (mng_datap pData,
+ mng_uint16 iId,
+ mng_bool bPartial,
+ mng_bool bVisible,
+ mng_bool bAbstract,
+ mng_bool bHasloca,
+ mng_uint8 iLocationtype,
+ mng_int32 iLocationx,
+ mng_int32 iLocationy,
+ mng_imagep pSource,
+ mng_imagep *ppClone)
+{
+ mng_imagep pNew;
+ mng_imagep pPrev, pNext;
+ mng_retcode iRetcode;
+ mng_imagedatap pImgbuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLONE_IMGOBJECT, MNG_LC_START)
+#endif
+
+ if ((pSource->iId) && /* needs magnification ? */
+ ((pSource->iMAGN_MethodX) || (pSource->iMAGN_MethodY)))
+ {
+ iRetcode = magnify_imageobject (pData, pSource);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ /* get a buffer */
+ MNG_ALLOC (pData, pNew, sizeof (mng_image))
+ /* fill or copy the appropriate fields */
+ pNew->sHeader.fCleanup = (mng_cleanupobject)free_imageobject;
+ pNew->sHeader.fProcess = 0;
+ pNew->iId = iId;
+ pNew->bFrozen = MNG_FALSE;
+ pNew->bVisible = bVisible;
+ pNew->bViewable = pSource->bViewable;
+
+ if (bHasloca) /* location info available ? */
+ {
+ if (iLocationtype == 0) /* absolute position ? */
+ {
+ pNew->iPosx = iLocationx;
+ pNew->iPosy = iLocationy;
+ }
+ else /* relative */
+ {
+ pNew->iPosx = pSource->iPosx + iLocationx;
+ pNew->iPosy = pSource->iPosy + iLocationy;
+ }
+ }
+ else /* copy from source */
+ {
+ pNew->iPosx = pSource->iPosx;
+ pNew->iPosy = pSource->iPosy;
+ }
+ /* copy clipping info */
+ pNew->bClipped = pSource->bClipped;
+ pNew->iClipl = pSource->iClipl;
+ pNew->iClipr = pSource->iClipr;
+ pNew->iClipt = pSource->iClipt;
+ pNew->iClipb = pSource->iClipb;
+ /* copy magnification info */
+ pNew->iMAGN_MethodX = pSource->iMAGN_MethodX;
+ pNew->iMAGN_MethodY = pSource->iMAGN_MethodY;
+ pNew->iMAGN_MX = pSource->iMAGN_MX;
+ pNew->iMAGN_MY = pSource->iMAGN_MY;
+ pNew->iMAGN_ML = pSource->iMAGN_ML;
+ pNew->iMAGN_MR = pSource->iMAGN_MR;
+ pNew->iMAGN_MT = pSource->iMAGN_MT;
+ pNew->iMAGN_MB = pSource->iMAGN_MB;
+
+ if (iId) /* not for object 0 */
+ { /* tqfind previous lower object-id */
+ pPrev = (mng_imagep)pData->pLastimgobj;
+ while ((pPrev) && (pPrev->iId > iId))
+ pPrev = (mng_imagep)pPrev->sHeader.pPrev;
+
+ if (pPrev) /* found it ? */
+ {
+ pNew->sHeader.pPrev = pPrev; /* than link it in place */
+ pNew->sHeader.pNext = pPrev->sHeader.pNext;
+ pPrev->sHeader.pNext = pNew;
+ }
+ else /* if not found, it becomes the first ! */
+ {
+ pNew->sHeader.pNext = pData->pFirstimgobj;
+ pData->pFirstimgobj = pNew;
+ }
+
+ pNext = (mng_imagep)pNew->sHeader.pNext;
+
+ if (pNext)
+ pNext->sHeader.pPrev = pNew;
+ else
+ pData->pLastimgobj = pNew;
+
+ }
+
+ if (bPartial) /* partial clone ? */
+ {
+ pNew->pImgbuf = pSource->pImgbuf; /* use the same object buffer */
+ pNew->pImgbuf->iRefcount++; /* and increase the reference count */
+ }
+ else /* create a full clone ! */
+ {
+ mng_bool bConcrete = MNG_FALSE; /* it's abstract by default (?) */
+
+ if (!bAbstract) /* determine concreteness from source ? */
+ bConcrete = pSource->pImgbuf->bConcrete;
+ /* create a full clone ! */
+ iRetcode = clone_imagedataobject (pData, bConcrete, pSource->pImgbuf, &pImgbuf);
+
+ if (iRetcode) /* on error bail out */
+ {
+ MNG_FREEX (pData, pNew, sizeof (mng_image))
+ return iRetcode;
+ }
+
+ pNew->pImgbuf = pImgbuf; /* and remember it */
+ }
+
+ *ppClone = pNew; /* return it */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLONE_IMGOBJECT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode renum_imageobject (mng_datap pData,
+ mng_imagep pSource,
+ mng_uint16 iId,
+ mng_bool bVisible,
+ mng_bool bAbstract,
+ mng_bool bHasloca,
+ mng_uint8 iLocationtype,
+ mng_int32 iLocationx,
+ mng_int32 iLocationy)
+{
+ mng_imagep pPrev, pNext;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RENUM_IMGOBJECT, MNG_LC_START)
+#endif
+
+ pSource->bVisible = bVisible; /* store the new visibility */
+
+ if (bHasloca) /* location info available ? */
+ {
+ if (iLocationtype == 0) /* absolute position ? */
+ {
+ pSource->iPosx = iLocationx;
+ pSource->iPosy = iLocationy;
+ }
+ else /* relative */
+ {
+ pSource->iPosx = pSource->iPosx + iLocationx;
+ pSource->iPosy = pSource->iPosy + iLocationy;
+ }
+ }
+
+ if (iId) /* not for object 0 */
+ { /* tqfind previous lower object-id */
+ pPrev = (mng_imagep)pData->pLastimgobj;
+ while ((pPrev) && (pPrev->iId > iId))
+ pPrev = (mng_imagep)pPrev->sHeader.pPrev;
+ /* different from current ? */
+ if (pPrev != (mng_imagep)pSource->sHeader.pPrev)
+ {
+ if (pSource->sHeader.pPrev) /* unlink from current position !! */
+ ((mng_imagep)pSource->sHeader.pPrev)->sHeader.pNext = pSource->sHeader.pNext;
+ else
+ pData->pFirstimgobj = pSource->sHeader.pNext;
+
+ if (pSource->sHeader.pNext)
+ ((mng_imagep)pSource->sHeader.pNext)->sHeader.pPrev = pSource->sHeader.pPrev;
+ else
+ pData->pLastimgobj = pSource->sHeader.pPrev;
+
+ if (pPrev) /* found the previous ? */
+ { /* than link it in place */
+ pSource->sHeader.pPrev = pPrev;
+ pSource->sHeader.pNext = pPrev->sHeader.pNext;
+ pPrev->sHeader.pNext = pSource;
+ }
+ else /* if not found, it becomes the first ! */
+ {
+ pSource->sHeader.pNext = pData->pFirstimgobj;
+ pData->pFirstimgobj = pSource;
+ }
+
+ pNext = (mng_imagep)pSource->sHeader.pNext;
+
+ if (pNext)
+ pNext->sHeader.pPrev = pSource;
+ else
+ pData->pLastimgobj = pSource;
+
+ }
+ }
+
+ pSource->iId = iId; /* now set the new id! */
+
+ if (bAbstract) /* force it to abstract ? */
+ pSource->pImgbuf->bConcrete = MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RENUM_IMGOBJECT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode reset_object_details (mng_datap pData,
+ mng_imagep pImage,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace,
+ mng_bool bResetall)
+{
+ mng_imagedatap pBuf = pImage->pImgbuf;
+ mng_uint32 iSamplesize = 0;
+ mng_uint32 iRowsize;
+ mng_uint32 iImgdatasize;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESET_OBJECTDETAILS, MNG_LC_START)
+#endif
+
+ pBuf->iWidth = iWidth; /* set buffer characteristics */
+ pBuf->iHeight = iHeight;
+ pBuf->iBitdepth = iBitdepth;
+ pBuf->iColortype = iColortype;
+ pBuf->iCompression = iCompression;
+ pBuf->iFilter = iFilter;
+ pBuf->iInterlace = iInterlace;
+ pBuf->iAlphabitdepth = 0;
+ /* determine samplesize from color_type/bit_depth */
+ switch (iColortype) /* for < 8-bit samples we just reserve 8 bits */
+ {
+ case 0 : ; /* gray */
+ case 8 : { /* JPEG gray */
+ if (iBitdepth > 8)
+ iSamplesize = 2;
+ else
+ iSamplesize = 1;
+
+ break;
+ }
+ case 2 : ; /* rgb */
+ case 10 : { /* JPEG rgb */
+ if (iBitdepth > 8)
+ iSamplesize = 6;
+ else
+ iSamplesize = 3;
+
+ break;
+ }
+ case 3 : { /* indexed */
+ iSamplesize = 1;
+ break;
+ }
+ case 4 : ; /* gray+alpha */
+ case 12 : { /* JPEG gray+alpha */
+ if (iBitdepth > 8)
+ iSamplesize = 4;
+ else
+ iSamplesize = 2;
+
+ break;
+ }
+ case 6 : ; /* rgb+alpha */
+ case 14 : { /* JPEG rgb+alpha */
+ if (iBitdepth > 8)
+ iSamplesize = 8;
+ else
+ iSamplesize = 4;
+
+ break;
+ }
+ }
+
+ iRowsize = iSamplesize * iWidth;
+ iImgdatasize = iRowsize * iHeight;
+ /* buffer size changed ? */
+ if (iImgdatasize != pBuf->iImgdatasize)
+ { /* drop the old one */
+ MNG_FREE (pData, pBuf->pImgdata, pBuf->iImgdatasize)
+
+ if (iImgdatasize) /* allocate new sample-buffer ? */
+ MNG_ALLOC (pData, pBuf->pImgdata, iImgdatasize)
+ }
+
+ pBuf->iSamplesize = iSamplesize; /* remember new sizes */
+ pBuf->iRowsize = iRowsize;
+ pBuf->iImgdatasize = iImgdatasize;
+ /* dimension set and clipping not ? */
+ if ((iWidth) && (iHeight) && (!pImage->bClipped))
+ {
+ pImage->iClipl = 0; /* set clipping to dimension by default */
+ pImage->iClipr = iWidth;
+ pImage->iClipt = 0;
+ pImage->iClipb = iHeight;
+ }
+
+ if (pImage->iId) /* reset magnification info ? */
+ {
+ pImage->iMAGN_MethodX = 0;
+ pImage->iMAGN_MethodY = 0;
+ pImage->iMAGN_MX = 0;
+ pImage->iMAGN_MY = 0;
+ pImage->iMAGN_ML = 0;
+ pImage->iMAGN_MR = 0;
+ pImage->iMAGN_MT = 0;
+ pImage->iMAGN_MB = 0;
+ }
+
+ if (bResetall) /* reset the other characteristics ? */
+ {
+ pBuf->bHasPLTE = MNG_FALSE;
+ pBuf->bHasTRNS = MNG_FALSE;
+ pBuf->bHasGAMA = pData->bHasglobalGAMA;
+ pBuf->bHasCHRM = pData->bHasglobalCHRM;
+ pBuf->bHasSRGB = pData->bHasglobalSRGB;
+ pBuf->bHasICCP = pData->bHasglobalICCP;
+ pBuf->bHasBKGD = pData->bHasglobalBKGD;
+
+ if (pBuf->iProfilesize) /* drop possibly old ICC profile */
+ {
+ MNG_FREE (pData, pBuf->pProfile, pBuf->iProfilesize)
+ pBuf->iProfilesize = 0;
+ }
+
+ if (pData->bHasglobalGAMA) /* global gAMA present ? */
+ pBuf->iGamma = pData->iGlobalGamma;
+
+ if (pData->bHasglobalCHRM) /* global cHRM present ? */
+ {
+ pBuf->iWhitepointx = pData->iGlobalWhitepointx;
+ pBuf->iWhitepointy = pData->iGlobalWhitepointy;
+ pBuf->iPrimaryredx = pData->iGlobalPrimaryredx;
+ pBuf->iPrimaryredy = pData->iGlobalPrimaryredy;
+ pBuf->iPrimarygreenx = pData->iGlobalPrimarygreenx;
+ pBuf->iPrimarygreeny = pData->iGlobalPrimarygreeny;
+ pBuf->iPrimarybluex = pData->iGlobalPrimarybluex;
+ pBuf->iPrimarybluey = pData->iGlobalPrimarybluey;
+ }
+
+ if (pData->bHasglobalSRGB) /* global sRGB present ? */
+ pBuf->iRenderingintent = pData->iGlobalRendintent;
+
+ if (pData->bHasglobalICCP) /* global iCCP present ? */
+ {
+ if (pData->iGlobalProfilesize)
+ {
+ MNG_ALLOC (pData, pBuf->pProfile, pData->iGlobalProfilesize)
+ MNG_COPY (pBuf->pProfile, pData->pGlobalProfile, pData->iGlobalProfilesize)
+ }
+
+ pBuf->iProfilesize = pData->iGlobalProfilesize;
+ }
+
+ if (pData->bHasglobalBKGD) /* global bKGD present ? */
+ {
+ pBuf->iBKGDred = pData->iGlobalBKGDred;
+ pBuf->iBKGDgreen = pData->iGlobalBKGDgreen;
+ pBuf->iBKGDblue = pData->iGlobalBKGDblue;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESET_OBJECTDETAILS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode promote_imageobject (mng_datap pData,
+ mng_imagep pImage,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iFilltype)
+{
+ mng_uint8p pNewbuf;
+ mng_uint32 iNewbufsize;
+ mng_uint32 iNewrowsize;
+ mng_uint32 iNewsamplesize;
+ mng_uint32 iX, iY;
+ mng_uint8p pSrcline, pDstline;
+ mng_uint8 iB;
+ mng_imagedatap pBuf = pImage->pImgbuf;
+ mng_uint32 iW = pBuf->iWidth;
+ mng_uint32 iH = pBuf->iHeight;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_IMGOBJECT, MNG_LC_START)
+#endif
+
+ if ((pBuf->iColortype == 3) && (iColortype == 2))
+ { /* indexed -> rgb */
+ iNewsamplesize = 3;
+ iNewrowsize = iW * iNewsamplesize;
+ iNewbufsize = iH * iNewrowsize;
+
+ MNG_ALLOC (pData, pNewbuf, iNewbufsize)
+
+ pSrcline = pBuf->pImgdata;
+ pDstline = pNewbuf;
+
+ for (iY = 0; iY < iH; iY++)
+ {
+ for (iX = 0; iX < iW; iX++)
+ {
+ iB = *pSrcline;
+
+ if ((mng_uint32)iB < pBuf->iPLTEcount)
+ {
+ *pDstline = pBuf->aPLTEentries [iB].iRed;
+ *(pDstline+1) = pBuf->aPLTEentries [iB].iGreen;
+ *(pDstline+2) = pBuf->aPLTEentries [iB].iBlue;
+ }
+
+ pSrcline++;
+ pDstline += 3;
+ }
+ }
+
+ MNG_FREEX (pData, pBuf->pImgdata, pBuf->iImgdatasize)
+
+ pBuf->iBitdepth = iBitdepth;
+ pBuf->iColortype = iColortype;
+ pBuf->iSamplesize = iNewsamplesize;
+ pBuf->iRowsize = iNewrowsize;
+ pBuf->iImgdatasize = iNewbufsize;
+ pBuf->pImgdata = pNewbuf;
+ pBuf->bHasPLTE = MNG_FALSE;
+ pBuf->bHasTRNS = MNG_FALSE;
+ }
+ else
+ if ((pBuf->iColortype == 3) && (iColortype == 6))
+ { /* indexed -> rgba */
+ iNewsamplesize = 4;
+ iNewrowsize = iW * iNewsamplesize;
+ iNewbufsize = iH * iNewrowsize;
+
+ MNG_ALLOC (pData, pNewbuf, iNewbufsize)
+
+ pSrcline = pBuf->pImgdata;
+ pDstline = pNewbuf;
+
+ for (iY = 0; iY < iH; iY++)
+ {
+ for (iX = 0; iX < iW; iX++)
+ {
+ iB = *pSrcline;
+
+ if ((mng_uint32)iB < pBuf->iPLTEcount)
+ {
+ *pDstline = pBuf->aPLTEentries [iB].iRed;
+ *(pDstline+1) = pBuf->aPLTEentries [iB].iGreen;
+ *(pDstline+2) = pBuf->aPLTEentries [iB].iBlue;
+
+ if ((mng_uint32)iB < pBuf->iTRNScount)
+ *(pDstline+3) = pBuf->aTRNSentries [iB];
+ else
+ *(pDstline+3) = 255;
+ }
+
+ pSrcline++;
+ pDstline += 4;
+ }
+ }
+
+ MNG_FREEX (pData, pBuf->pImgdata, pBuf->iImgdatasize)
+
+ pBuf->iBitdepth = iBitdepth;
+ pBuf->iColortype = iColortype;
+ pBuf->iSamplesize = iNewsamplesize;
+ pBuf->iRowsize = iNewrowsize;
+ pBuf->iImgdatasize = iNewbufsize;
+ pBuf->pImgdata = pNewbuf;
+ pBuf->bHasPLTE = MNG_FALSE;
+ pBuf->bHasTRNS = MNG_FALSE;
+ }
+ else
+ {
+
+ /* TODO: other promotion */
+
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROMOTE_IMGOBJECT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_imageobject (mng_datap pData,
+ mng_imagep pImage)
+{
+ mng_uint8p pNewdata;
+ mng_uint8p pSrcline1;
+ mng_uint8p pSrcline2;
+ mng_uint8p pTempline;
+ mng_uint8p pDstline;
+ mng_uint32 iNewrowsize;
+ mng_uint32 iNewsize;
+ mng_uint32 iY;
+ mng_int32 iS, iM;
+ mng_retcode iRetcode;
+
+ mng_imagedatap pBuf = pImage->pImgbuf;
+ mng_uint32 iNewW = pBuf->iWidth;
+ mng_uint32 iNewH = pBuf->iHeight;
+ mng_magnify_x fMagnifyX = MNG_NULL;
+ mng_magnify_y fMagnifyY = MNG_NULL;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_IMGOBJECT, MNG_LC_START)
+#endif
+
+ if (pBuf->iColortype == 3) /* indexed color ? */
+ { /* concrete buffer ? */
+ if ((pBuf->bConcrete) && (pImage->iId))
+ MNG_ERROR (pData, MNG_INVALIDCOLORTYPE)
+
+ if (pBuf->iTRNScount) /* with transparency ? */
+ iRetcode = promote_imageobject (pData, pImage, 8, 6, 0);
+ else
+ iRetcode = promote_imageobject (pData, pImage, 8, 2, 0);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ if (pImage->iMAGN_MethodX) /* determine new width */
+ {
+ if (pImage->iMAGN_MethodX == 1)
+ {
+ iNewW = pImage->iMAGN_ML;
+ if (pBuf->iWidth > 1)
+ iNewW = iNewW + pImage->iMAGN_MR;
+ if (pBuf->iWidth > 2)
+ iNewW = iNewW + (pBuf->iWidth - 2) * (pImage->iMAGN_MX);
+ }
+ else
+ {
+ iNewW = pBuf->iWidth + pImage->iMAGN_ML - 1;
+ if (pBuf->iWidth > 2)
+ iNewW = iNewW + pImage->iMAGN_MR - 1;
+ if (pBuf->iWidth > 3)
+ iNewW = iNewW + (pBuf->iWidth - 3) * (pImage->iMAGN_MX - 1);
+ }
+ }
+
+ if (pImage->iMAGN_MethodY) /* determine new height */
+ {
+ if (pImage->iMAGN_MethodY == 1)
+ {
+ iNewH = pImage->iMAGN_MT;
+ if (pBuf->iHeight > 1)
+ iNewH = iNewH + pImage->iMAGN_ML;
+ if (pBuf->iHeight > 2)
+ iNewH = iNewH + (pBuf->iHeight - 2) * (pImage->iMAGN_MY);
+ }
+ else
+ {
+ iNewH = pBuf->iHeight + pImage->iMAGN_MT - 1;
+ if (pBuf->iHeight > 2)
+ iNewH = iNewH + pImage->iMAGN_MB - 1;
+ if (pBuf->iHeight > 3)
+ iNewH = iNewH + (pBuf->iHeight - 3) * (pImage->iMAGN_MY - 1);
+ }
+ }
+ /* get new buffer */
+ iNewrowsize = iNewW * pBuf->iSamplesize;
+ iNewsize = iNewH * iNewrowsize;
+
+ MNG_ALLOC (pData, pNewdata, iNewsize);
+
+ switch (pBuf->iColortype) /* determine magnification routines */
+ {
+ case 0 : ;
+ case 8 : {
+ if (pBuf->iBitdepth <= 8)
+ {
+ switch (pImage->iMAGN_MethodX)
+ {
+ case 1 : { fMagnifyX = magnify_g8_x1; break; }
+ case 2 : { fMagnifyX = magnify_g8_x2; break; }
+ case 3 : { fMagnifyX = magnify_g8_x3; break; }
+ case 4 : { fMagnifyX = magnify_g8_x2; break; }
+ case 5 : { fMagnifyX = magnify_g8_x3; break; }
+ }
+
+ switch (pImage->iMAGN_MethodY)
+ {
+ case 1 : { fMagnifyY = magnify_g8_y1; break; }
+ case 2 : { fMagnifyY = magnify_g8_y2; break; }
+ case 3 : { fMagnifyY = magnify_g8_y3; break; }
+ case 4 : { fMagnifyY = magnify_g8_y2; break; }
+ case 5 : { fMagnifyY = magnify_g8_y3; break; }
+ }
+ }
+ else
+ {
+
+ /* TODO: magnify 16-bit */
+
+ }
+
+ break;
+ }
+
+ case 2 : ;
+ case 10 : {
+ if (pBuf->iBitdepth <= 8)
+ {
+ switch (pImage->iMAGN_MethodX)
+ {
+ case 1 : { fMagnifyX = magnify_rgb8_x1; break; }
+ case 2 : { fMagnifyX = magnify_rgb8_x2; break; }
+ case 3 : { fMagnifyX = magnify_rgb8_x3; break; }
+ case 4 : { fMagnifyX = magnify_rgb8_x2; break; }
+ case 5 : { fMagnifyX = magnify_rgb8_x3; break; }
+ }
+
+ switch (pImage->iMAGN_MethodY)
+ {
+ case 1 : { fMagnifyY = magnify_rgb8_y1; break; }
+ case 2 : { fMagnifyY = magnify_rgb8_y2; break; }
+ case 3 : { fMagnifyY = magnify_rgb8_y3; break; }
+ case 4 : { fMagnifyY = magnify_rgb8_y2; break; }
+ case 5 : { fMagnifyY = magnify_rgb8_y3; break; }
+ }
+ }
+ else
+ {
+
+ /* TODO: magnify 16-bit */
+
+ }
+
+ break;
+ }
+
+ case 4 : ;
+ case 12 : {
+ if (pBuf->iBitdepth <= 8)
+ {
+ switch (pImage->iMAGN_MethodX)
+ {
+ case 1 : { fMagnifyX = magnify_ga8_x1; break; }
+ case 2 : { fMagnifyX = magnify_ga8_x2; break; }
+ case 3 : { fMagnifyX = magnify_ga8_x3; break; }
+ case 4 : { fMagnifyX = magnify_ga8_x4; break; }
+ case 5 : { fMagnifyX = magnify_ga8_x5; break; }
+ }
+
+ switch (pImage->iMAGN_MethodY)
+ {
+ case 1 : { fMagnifyY = magnify_ga8_y1; break; }
+ case 2 : { fMagnifyY = magnify_ga8_y2; break; }
+ case 3 : { fMagnifyY = magnify_ga8_y3; break; }
+ case 4 : { fMagnifyY = magnify_ga8_y4; break; }
+ case 5 : { fMagnifyY = magnify_ga8_y5; break; }
+ }
+ }
+ else
+ {
+
+ /* TODO: magnify 16-bit */
+
+ }
+
+ break;
+ }
+
+ case 6 : ;
+ case 14 : {
+ if (pBuf->iBitdepth <= 8)
+ {
+ switch (pImage->iMAGN_MethodX)
+ {
+ case 1 : { fMagnifyX = magnify_rgba8_x1; break; }
+ case 2 : { fMagnifyX = magnify_rgba8_x2; break; }
+ case 3 : { fMagnifyX = magnify_rgba8_x3; break; }
+ case 4 : { fMagnifyX = magnify_rgba8_x4; break; }
+ case 5 : { fMagnifyX = magnify_rgba8_x5; break; }
+ }
+
+ switch (pImage->iMAGN_MethodY)
+ {
+ case 1 : { fMagnifyY = magnify_rgba8_y1; break; }
+ case 2 : { fMagnifyY = magnify_rgba8_y2; break; }
+ case 3 : { fMagnifyY = magnify_rgba8_y3; break; }
+ case 4 : { fMagnifyY = magnify_rgba8_y4; break; }
+ case 5 : { fMagnifyY = magnify_rgba8_y5; break; }
+ }
+ }
+ else
+ {
+
+ /* TODO: magnify 16-bit */
+
+ }
+
+ break;
+ }
+ }
+
+ pSrcline1 = pBuf->pImgdata; /* initialize row-loop variables */
+ pDstline = pNewdata;
+ /* allocate temporary row */
+ MNG_ALLOC (pData, pTempline, iNewrowsize)
+
+ for (iY = 0; iY < pBuf->iHeight; iY++)
+ {
+ pSrcline2 = pSrcline1 + pBuf->iRowsize;
+
+ if (fMagnifyX) /* magnifying in X-direction ? */
+ {
+ iRetcode = fMagnifyX (pData, pImage->iMAGN_MX,
+ pImage->iMAGN_ML, pImage->iMAGN_MR,
+ pBuf->iWidth, pSrcline1, pDstline);
+
+ if (iRetcode) /* on error bail out */
+ {
+ MNG_FREEX (pData, pTempline, iNewrowsize)
+ MNG_FREEX (pData, pNewdata, iNewsize)
+ return iRetcode;
+ }
+ }
+ else
+ {
+ MNG_COPY (pDstline, pSrcline1, iNewrowsize)
+ }
+
+ pDstline += iNewrowsize;
+ /* magnifying in Y-direction ? */
+ if ((fMagnifyY) &&
+ ((iY < pBuf->iHeight - 1) || (pBuf->iHeight == 1) || (pImage->iMAGN_MethodY == 1)))
+ {
+ if (iY == 0) /* first interval ? */
+ {
+ if (pBuf->iHeight == 1) /* single row ? */
+ pSrcline2 = MNG_NULL;
+
+ iM = (mng_int32)pImage->iMAGN_MT;
+ }
+ else /* last interval ? */
+ if (((pImage->iMAGN_MethodY == 1) && (iY == (pBuf->iHeight - 1))) ||
+ ((pImage->iMAGN_MethodY != 1) && (iY == (pBuf->iHeight - 2))) )
+ iM = (mng_int32)pImage->iMAGN_MB;
+ else /* middle interval */
+ iM = (mng_int32)pImage->iMAGN_MY;
+
+ for (iS = 1; iS < iM; iS++)
+ {
+ iRetcode = fMagnifyY (pData, iS, iM, pBuf->iWidth,
+ pSrcline1, pSrcline2, pTempline);
+
+ if (iRetcode) /* on error bail out */
+ {
+ MNG_FREEX (pData, pTempline, iNewrowsize)
+ MNG_FREEX (pData, pNewdata, iNewsize)
+ return iRetcode;
+ }
+
+ if (fMagnifyX) /* magnifying in X-direction ? */
+ {
+ iRetcode = fMagnifyX (pData, pImage->iMAGN_MX,
+ pImage->iMAGN_ML, pImage->iMAGN_MR,
+ pBuf->iWidth, pTempline, pDstline);
+
+ if (iRetcode) /* on error bail out */
+ {
+ MNG_FREEX (pData, pTempline, iNewrowsize)
+ MNG_FREEX (pData, pNewdata, iNewsize)
+ return iRetcode;
+ }
+ }
+ else
+ {
+ MNG_COPY (pDstline, pTempline, iNewrowsize)
+ }
+
+ pDstline += iNewrowsize;
+ }
+ }
+
+ pSrcline1 += pBuf->iRowsize;
+ }
+ /* drop temporary row */
+ MNG_FREEX (pData, pTempline, iNewrowsize)
+ /* drop old pixel-data */
+ MNG_FREEX (pData, pBuf->pImgdata, pBuf->iImgdatasize)
+
+ pBuf->pImgdata = pNewdata; /* save new buffer dimensions */
+ pBuf->iRowsize = iNewrowsize;
+ pBuf->iImgdatasize = iNewsize;
+ pBuf->iWidth = iNewW;
+ pBuf->iHeight = iNewH;
+
+ if (pImage->iId) /* real object ? */
+ {
+ pImage->iMAGN_MethodX = 0; /* it's done; don't do it again !!! */
+ pImage->iMAGN_MethodY = 0;
+ pImage->iMAGN_MX = 0;
+ pImage->iMAGN_MY = 0;
+ pImage->iMAGN_ML = 0;
+ pImage->iMAGN_MR = 0;
+ pImage->iMAGN_MT = 0;
+ pImage->iMAGN_MB = 0;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_IMGOBJECT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Animation-object routines * */
+/* * * */
+/* * these handle the animation objects used to re-run parts of a MNG. * */
+/* * eg. during LOOP or TERM processing * */
+/* * * */
+/* ************************************************************************** */
+
+void add_ani_object (mng_datap pData,
+ mng_object_headerp pObject)
+{
+ mng_object_headerp pLast = (mng_object_headerp)pData->pLastaniobj;
+
+ if (pLast) /* link it as last in the chain */
+ {
+ pObject->pPrev = pLast;
+ pLast->pNext = pObject;
+ }
+ else
+ {
+ pObject->pPrev = MNG_NULL; /* be on the safe side */
+ pData->pFirstaniobj = pObject;
+ }
+
+ pObject->pNext = MNG_NULL; /* be on the safe side */
+ pData->pLastaniobj = pObject;
+ /* keep track for jumping */
+ pObject->iFramenr = pData->iFrameseq;
+ pObject->iLayernr = pData->iLayerseq;
+ pObject->iPlaytime = pData->iFrametime;
+ /* save restart object ? */
+ if ((pData->bDisplaying) && (!pData->bRunning) && (!pData->pCurraniobj))
+ pData->pCurraniobj = pObject;
+
+ return;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_image (mng_datap pData)
+{
+ mng_ani_imagep pImage;
+ mng_imagep pCurrent;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_IMAGE, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ if (pData->bHasDHDR) /* processing delta-image ? */
+ pCurrent = (mng_imagep)pData->pObjzero;
+ else /* get the current object */
+ pCurrent = (mng_imagep)pData->pCurrentobj;
+
+ if (!pCurrent) /* otherwise object 0 */
+ pCurrent = (mng_imagep)pData->pObjzero;
+ /* now just clone the object !!! */
+ iRetcode = clone_imageobject (pData, 0, MNG_FALSE, pCurrent->bVisible,
+ MNG_FALSE, MNG_FALSE, 0, 0, 0, pCurrent, &pImage);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ pImage->sHeader.fCleanup = free_ani_image;
+ pImage->sHeader.fProcess = process_ani_image;
+
+ add_ani_object (pData, (mng_object_headerp)pImage);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_IMAGE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* okido */
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_image (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_imagep pImage = (mng_ani_imagep)pObject;
+ mng_imagedatap pImgbuf = pImage->pImgbuf;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_IMAGE, MNG_LC_START)
+#endif
+ /* unlink the image-data buffer */
+ iRetcode = free_imagedataobject (pData, pImgbuf);
+ /* drop it's own buffer */
+ MNG_FREEX (pData, pImage, sizeof (mng_ani_image))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_IMAGE, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_image (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_retcode iRetcode = MNG_NOERROR;
+ mng_ani_imagep pImage = (mng_imagep)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IMAGE, MNG_LC_START)
+#endif
+
+ if (pData->bHasDHDR) /* processing delta-image ? */
+ {
+ mng_imagep pDelta = (mng_imagep)pData->pDeltaImage;
+
+ if (!pData->iBreakpoint) /* only execute if not broken before */
+ { /* make sure to process pixels as well */
+ pData->bDeltaimmediate = MNG_FALSE;
+ /* execute the delta process */
+ iRetcode = execute_delta_image (pData, pDelta, (mng_imagep)pObject);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+ /* now go and shoot it off (if required) */
+ if ((pDelta->bVisible) && (pDelta->bViewable))
+ iRetcode = display_image (pData, pDelta, MNG_FALSE);
+
+ if (!pData->bTimerset)
+ pData->bHasDHDR = MNG_FALSE; /* this image signifies IEND !! */
+
+ }
+ else
+ if (pData->pCurrentobj) /* active object ? */
+ {
+ mng_imagep pCurrent = (mng_imagep)pData->pCurrentobj;
+ mng_imagedatap pBuf = pCurrent->pImgbuf;
+
+ if (!pData->iBreakpoint) /* don't copy it again ! */
+ {
+ if (pBuf->iImgdatasize) /* buffer present in active object ? */
+ /* then drop it */
+ MNG_FREE (pData, pBuf->pImgdata, pBuf->iImgdatasize)
+
+ if (pBuf->iProfilesize) /* iCCP profile present ? */
+ /* then drop it */
+ MNG_FREE (pData, pBuf->pProfile, pBuf->iProfilesize)
+ /* now blatently copy the animation buffer */
+ MNG_COPY (pBuf, pImage->pImgbuf, sizeof (mng_imagedata))
+ /* copy viewability */
+ pCurrent->bViewable = pImage->bViewable;
+
+ if (pBuf->iImgdatasize) /* sample buffer present ? */
+ { /* then make a copy */
+ MNG_ALLOC (pData, pBuf->pImgdata, pBuf->iImgdatasize)
+ MNG_COPY (pBuf->pImgdata, pImage->pImgbuf->pImgdata, pBuf->iImgdatasize)
+ }
+
+ if (pBuf->iProfilesize) /* iCCP profile present ? */
+ { /* then make a copy */
+ MNG_ALLOC (pData, pBuf->pProfile, pBuf->iProfilesize)
+ MNG_COPY (pBuf->pProfile, pImage->pImgbuf->pProfile, pBuf->iProfilesize)
+ }
+ }
+ /* now go and shoot it off (if required) */
+ if ((pCurrent->bVisible) && (pCurrent->bViewable))
+ iRetcode = display_image (pData, pCurrent, MNG_FALSE);
+ }
+ else
+ {
+ mng_imagep pObjzero = (mng_imagep)pData->pObjzero;
+ /* overlay with object 0 status */
+ pImage->bVisible = pObjzero->bVisible;
+ pImage->bViewable = pObjzero->bViewable;
+ pImage->iPosx = pObjzero->iPosx;
+ pImage->iPosy = pObjzero->iPosy;
+ pImage->bClipped = pObjzero->bClipped;
+ pImage->iClipl = pObjzero->iClipl;
+ pImage->iClipr = pObjzero->iClipr;
+ pImage->iClipt = pObjzero->iClipt;
+ pImage->iClipb = pObjzero->iClipb;
+ /* now this should do the trick */
+ if ((pImage->bVisible) && (pImage->bViewable))
+ iRetcode = display_image (pData, pImage, MNG_FALSE);
+ }
+
+ if (!iRetcode) /* all's well ? */
+ {
+ if (pData->bTimerset) /* timer break ? */
+ pData->iBreakpoint = 99; /* fictive number; no more processing needed! */
+ else
+ pData->iBreakpoint = 0; /* else clear it */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IMAGE, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_plte (mng_datap pData,
+ mng_uint32 iEntrycount,
+ mng_palette8ep paEntries)
+{
+ mng_ani_pltep pPLTE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_PLTE, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pPLTE, sizeof (mng_ani_plte))
+
+ pPLTE->sHeader.fCleanup = free_ani_plte;
+ pPLTE->sHeader.fProcess = process_ani_plte;
+
+ add_ani_object (pData, (mng_object_headerp)pPLTE);
+
+ pPLTE->iEntrycount = iEntrycount;
+
+ MNG_COPY (pPLTE->aEntries, paEntries, sizeof (pPLTE->aEntries))
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_PLTE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_plte (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_PLTE, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_plte))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_PLTE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_plte (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_pltep pPLTE = (mng_ani_pltep)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PLTE, MNG_LC_START)
+#endif
+
+ pData->bHasglobalPLTE = MNG_TRUE;
+ pData->iGlobalPLTEcount = pPLTE->iEntrycount;
+
+ MNG_COPY (pData->aGlobalPLTEentries, pPLTE->aEntries, sizeof (pPLTE->aEntries))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PLTE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_trns (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata)
+{
+ mng_ani_trnsp pTRNS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_TRNS, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pTRNS, sizeof (mng_ani_trns))
+
+ pTRNS->sHeader.fCleanup = free_ani_trns;
+ pTRNS->sHeader.fProcess = process_ani_trns;
+
+ add_ani_object (pData, (mng_object_headerp)pTRNS);
+
+ pTRNS->iRawlen = iRawlen;
+
+ MNG_COPY (pTRNS->aRawdata, pRawdata, sizeof (pTRNS->aRawdata))
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_TRNS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_trns (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_TRNS, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_trns))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_TRNS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_trns (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_trnsp pTRNS = (mng_ani_trnsp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_TRNS, MNG_LC_START)
+#endif
+
+ pData->bHasglobalTRNS = MNG_TRUE;
+ pData->iGlobalTRNSrawlen = pTRNS->iRawlen;
+
+ MNG_COPY (pData->aGlobalTRNSrawdata, pTRNS->aRawdata, sizeof (pTRNS->aRawdata))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_TRNS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_gama (mng_datap pData,
+ mng_bool bEmpty,
+ mng_uint32 iGamma)
+{
+ mng_ani_gamap pGAMA;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_GAMA, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pGAMA, sizeof (mng_ani_gama))
+
+ pGAMA->sHeader.fCleanup = free_ani_gama;
+ pGAMA->sHeader.fProcess = process_ani_gama;
+
+ add_ani_object (pData, (mng_object_headerp)pGAMA);
+
+ pGAMA->bEmpty = bEmpty;
+ pGAMA->iGamma = iGamma;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_GAMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_gama (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_GAMA, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_gama))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_GAMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_gama (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_gamap pGAMA = (mng_ani_gamap)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_GAMA, MNG_LC_START)
+#endif
+
+ if (pGAMA->bEmpty) /* empty chunk ? */
+ { /* clear global gAMA */
+ pData->bHasglobalGAMA = MNG_FALSE;
+ pData->iGlobalGamma = 0;
+ }
+ else
+ { /* set global gAMA */
+ pData->bHasglobalGAMA = MNG_TRUE;
+ pData->iGlobalGamma = pGAMA->iGamma;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_GAMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_chrm (mng_datap pData,
+ mng_bool bEmpty,
+ mng_uint32 iWhitepointx,
+ mng_uint32 iWhitepointy,
+ mng_uint32 iRedx,
+ mng_uint32 iRedy,
+ mng_uint32 iGreenx,
+ mng_uint32 iGreeny,
+ mng_uint32 iBluex,
+ mng_uint32 iBluey)
+{
+ mng_ani_chrmp pCHRM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_CHRM, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pCHRM, sizeof (mng_ani_chrm))
+
+ pCHRM->sHeader.fCleanup = free_ani_chrm;
+ pCHRM->sHeader.fProcess = process_ani_chrm;
+
+ add_ani_object (pData, (mng_object_headerp)pCHRM);
+
+ pCHRM->bEmpty = bEmpty;
+ pCHRM->iWhitepointx = iWhitepointx;
+ pCHRM->iWhitepointy = iWhitepointy;
+ pCHRM->iRedx = iRedx;
+ pCHRM->iRedy = iRedy;
+ pCHRM->iGreenx = iGreenx;
+ pCHRM->iGreeny = iGreeny;
+ pCHRM->iBluex = iBluex;
+ pCHRM->iBluey = iBluey;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_CHRM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_chrm (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_CHRM, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_chrm))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_CHRM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_chrm (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_chrmp pCHRM = (mng_ani_chrmp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CHRM, MNG_LC_START)
+#endif
+
+ if (pCHRM->bEmpty) /* empty chunk ? */
+ { /* clear global cHRM */
+ pData->bHasglobalCHRM = MNG_FALSE;
+ pData->iGlobalWhitepointx = 0;
+ pData->iGlobalWhitepointy = 0;
+ pData->iGlobalPrimaryredx = 0;
+ pData->iGlobalPrimaryredy = 0;
+ pData->iGlobalPrimarygreenx = 0;
+ pData->iGlobalPrimarygreeny = 0;
+ pData->iGlobalPrimarybluex = 0;
+ pData->iGlobalPrimarybluey = 0;
+ }
+ else
+ { /* set global cHRM */
+ pData->bHasglobalCHRM = MNG_TRUE;
+ pData->iGlobalWhitepointx = pCHRM->iWhitepointx;
+ pData->iGlobalWhitepointy = pCHRM->iWhitepointy;
+ pData->iGlobalPrimaryredx = pCHRM->iRedx;
+ pData->iGlobalPrimaryredy = pCHRM->iRedy;
+ pData->iGlobalPrimarygreenx = pCHRM->iGreenx;
+ pData->iGlobalPrimarygreeny = pCHRM->iGreeny;
+ pData->iGlobalPrimarybluex = pCHRM->iBluex;
+ pData->iGlobalPrimarybluey = pCHRM->iBluey;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CHRM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_srgb (mng_datap pData,
+ mng_bool bEmpty,
+ mng_uint8 iRenderingintent)
+{
+ mng_ani_srgbp pSRGB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_SRGB, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pSRGB, sizeof (mng_ani_srgb))
+
+ pSRGB->sHeader.fCleanup = free_ani_srgb;
+ pSRGB->sHeader.fProcess = process_ani_srgb;
+
+ add_ani_object (pData, (mng_object_headerp)pSRGB);
+
+ pSRGB->bEmpty = bEmpty;
+ pSRGB->iRenderingintent = iRenderingintent;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_SRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_srgb (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_SRGB, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_srgb))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_SRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_srgb (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_srgbp pSRGB = (mng_ani_srgbp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SRGB, MNG_LC_START)
+#endif
+
+ if (pSRGB->bEmpty) /* empty chunk ? */
+ { /* clear global sRGB */
+ pData->bHasglobalSRGB = MNG_FALSE;
+ pData->iGlobalRendintent = 0;
+ }
+ else
+ { /* set global sRGB */
+ pData->bHasglobalSRGB = MNG_TRUE;
+ pData->iGlobalRendintent = pSRGB->iRenderingintent;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_iccp (mng_datap pData,
+ mng_bool bEmpty,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile)
+{
+ mng_ani_iccpp pICCP;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_ICCP, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pICCP, sizeof (mng_ani_iccp))
+
+ pICCP->sHeader.fCleanup = free_ani_iccp;
+ pICCP->sHeader.fProcess = process_ani_iccp;
+
+ add_ani_object (pData, (mng_object_headerp)pICCP);
+
+ pICCP->bEmpty = bEmpty;
+ pICCP->iProfilesize = iProfilesize;
+
+ if (iProfilesize)
+ {
+ MNG_ALLOC (pData, pICCP->pProfile, iProfilesize)
+ MNG_COPY (pICCP->pProfile, pProfile, iProfilesize)
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_ICCP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_iccp (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_iccpp pICCP = (mng_ani_iccpp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_ICCP, MNG_LC_START)
+#endif
+
+ if (pICCP->iProfilesize)
+ MNG_FREEX (pData, pICCP->pProfile, pICCP->iProfilesize)
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_iccp))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_ICCP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_iccp (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_iccpp pICCP = (mng_ani_iccpp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_ICCP, MNG_LC_START)
+#endif
+
+ if (pICCP->bEmpty) /* empty chunk ? */
+ { /* clear global iCCP */
+ pData->bHasglobalICCP = MNG_FALSE;
+
+ if (pData->iGlobalProfilesize)
+ MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize)
+
+ pData->iGlobalProfilesize = 0;
+ pData->pGlobalProfile = MNG_NULL;
+ }
+ else
+ { /* set global iCCP */
+ pData->bHasglobalICCP = MNG_TRUE;
+ pData->iGlobalProfilesize = pICCP->iProfilesize;
+
+ if (pICCP->iProfilesize)
+ {
+ MNG_ALLOC (pData, pData->pGlobalProfile, pICCP->iProfilesize)
+ MNG_COPY (pData->pGlobalProfile, pICCP->pProfile, pICCP->iProfilesize)
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_ICCP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_bkgd (mng_datap pData,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue)
+{
+ mng_ani_bkgdp pBKGD;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_BKGD, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pBKGD, sizeof (mng_ani_bkgd))
+
+ pBKGD->sHeader.fCleanup = free_ani_bkgd;
+ pBKGD->sHeader.fProcess = process_ani_bkgd;
+
+ add_ani_object (pData, (mng_object_headerp)pBKGD);
+
+ pBKGD->iRed = iRed;
+ pBKGD->iGreen = iGreen;
+ pBKGD->iBlue = iBlue;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_BKGD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_bkgd (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_BKGD, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_bkgd))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_BKGD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_bkgd (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_bkgdp pBKGD = (mng_ani_bkgdp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BKGD, MNG_LC_START)
+#endif
+
+ pData->bHasglobalBKGD = MNG_TRUE;
+ pData->iGlobalBKGDred = pBKGD->iRed;
+ pData->iGlobalBKGDgreen = pBKGD->iGreen;
+ pData->iGlobalBKGDblue = pBKGD->iBlue;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BKGD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_loop (mng_datap pData,
+ mng_uint8 iLevel,
+ mng_uint32 iRepeatcount,
+ mng_uint8 iTermcond,
+ mng_uint32 iItermin,
+ mng_uint32 iItermax,
+ mng_uint32 iCount,
+ mng_uint32p pSignals)
+{
+ mng_ani_loopp pLOOP;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_LOOP, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pLOOP, sizeof (mng_ani_loop))
+
+ pLOOP->sHeader.fCleanup = free_ani_loop;
+ pLOOP->sHeader.fProcess = process_ani_loop;
+
+ add_ani_object (pData, (mng_object_headerp)pLOOP);
+
+ pLOOP->iLevel = iLevel;
+ pLOOP->iRepeatcount = iRepeatcount;
+ pLOOP->iTermcond = iTermcond;
+ pLOOP->iItermin = iItermin;
+ pLOOP->iItermax = iItermax;
+ pLOOP->iCount = iCount;
+ /* running counter starts with repeat_count */
+ pLOOP->iRunningcount = iRepeatcount;
+
+ if (iCount)
+ {
+ MNG_ALLOC (pData, pLOOP->pSignals, (iCount << 1))
+ MNG_COPY (pLOOP->pSignals, pSignals, (iCount << 1))
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_LOOP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_loop (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_loopp pLOOP = (mng_ani_loopp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_LOOP, MNG_LC_START)
+#endif
+
+ if (pLOOP->iCount) /* drop signal buffer ? */
+ MNG_FREEX (pData, pLOOP->pSignals, (pLOOP->iCount << 1))
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_loop))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_LOOP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_loop (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_loopp pLOOP = (mng_ani_loopp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_LOOP, MNG_LC_START)
+#endif
+ /* just reset the running counter */
+ pLOOP->iRunningcount = pLOOP->iRepeatcount;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_LOOP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_endl (mng_datap pData,
+ mng_uint8 iLevel)
+{
+ mng_ani_endlp pENDL;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_ENDL, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pENDL, sizeof (mng_ani_endl))
+
+ pENDL->sHeader.fCleanup = free_ani_endl;
+ pENDL->sHeader.fProcess = process_ani_endl;
+
+ add_ani_object (pData, (mng_object_headerp)pENDL);
+
+ pENDL->iLevel = iLevel;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_ENDL, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_endl (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_ENDL, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_endl))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_ENDL, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_endl (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_endlp pENDL = (mng_ani_endlp)pObject;
+ mng_ani_loopp pLOOP;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_ENDL, MNG_LC_START)
+#endif
+
+ if ((pData->bDisplaying) && (pData->bRunning))
+ {
+ pLOOP = pENDL->pLOOP; /* determine matching LOOP */
+
+ if (!pLOOP) /* haven't got it yet ? */
+ { /* go and look back in the list */
+ pLOOP = (mng_ani_loopp)pENDL->sHeader.pPrev;
+
+ while ((pLOOP) &&
+ ((pLOOP->sHeader.fCleanup != free_ani_loop) ||
+ (pLOOP->iLevel != pENDL->iLevel) ))
+ pLOOP = pLOOP->sHeader.pPrev;
+ }
+ /* got it now ? */
+ if ((pLOOP) && (pLOOP->iLevel == pENDL->iLevel))
+ {
+ pENDL->pLOOP = pLOOP; /* save for next time ! */
+ /* decrease running counter ? */
+ if ((pLOOP->iRunningcount) && (pLOOP->iRunningcount < 0x7fffffffL))
+ pLOOP->iRunningcount--;
+
+ /* TODO: we're cheating out on the termination_condition,
+ iteration_min, iteration_max and possible Q_SIGNALS;
+ the code is just not ready for that can of worms.... */
+
+ if (!pLOOP->iRunningcount) /* reached zero ? */
+ { /* was this the outer LOOP ? */
+ if (pData->pFirstaniobj == (mng_objectp)pLOOP)
+ pData->bHasLOOP = MNG_FALSE;
+ }
+ else
+ {
+ if (pData->pCurraniobj) /* was we processing objects ? */
+ pData->pCurraniobj = pLOOP; /* then restart with LOOP */
+ else /* else restart behind LOOP !!! */
+ pData->pCurraniobj = pLOOP->sHeader.pNext;
+ }
+ }
+ else
+ {
+ MNG_ERROR (pData, 1234);
+ /* TODO: error abort ??? */
+
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_ENDL, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_defi (mng_datap pData)
+{
+ mng_ani_defip pDEFI;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_DEFI, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pDEFI, sizeof (mng_ani_defi))
+
+ pDEFI->sHeader.fCleanup = free_ani_defi;
+ pDEFI->sHeader.fProcess = process_ani_defi;
+
+ add_ani_object (pData, (mng_object_headerp)pDEFI);
+
+ pDEFI->iId = pData->iDEFIobjectid;
+ pDEFI->bHasdonotshow = pData->bDEFIhasdonotshow;
+ pDEFI->iDonotshow = pData->iDEFIdonotshow;
+ pDEFI->bHasconcrete = pData->bDEFIhasconcrete;
+ pDEFI->iConcrete = pData->iDEFIconcrete;
+ pDEFI->bHasloca = pData->bDEFIhasloca;
+ pDEFI->iLocax = pData->iDEFIlocax;
+ pDEFI->iLocay = pData->iDEFIlocay;
+ pDEFI->bHasclip = pData->bDEFIhasclip;
+ pDEFI->iClipl = pData->iDEFIclipl;
+ pDEFI->iClipr = pData->iDEFIclipr;
+ pDEFI->iClipt = pData->iDEFIclipt;
+ pDEFI->iClipb = pData->iDEFIclipb;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_DEFI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_defi (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_DEFI, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_defi))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_DEFI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_defi (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_defip pDEFI = (mng_ani_defip)pObject;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_DEFI, MNG_LC_START)
+#endif
+
+ pData->iDEFIobjectid = pDEFI->iId;
+ pData->bDEFIhasdonotshow = pDEFI->bHasdonotshow;
+ pData->iDEFIdonotshow = pDEFI->iDonotshow;
+ pData->bDEFIhasconcrete = pDEFI->bHasconcrete;
+ pData->iDEFIconcrete = pDEFI->iConcrete;
+ pData->bDEFIhasloca = pDEFI->bHasloca;
+ pData->iDEFIlocax = pDEFI->iLocax;
+ pData->iDEFIlocay = pDEFI->iLocay;
+ pData->bDEFIhasclip = pDEFI->bHasclip;
+ pData->iDEFIclipl = pDEFI->iClipl;
+ pData->iDEFIclipr = pDEFI->iClipr;
+ pData->iDEFIclipt = pDEFI->iClipt;
+ pData->iDEFIclipb = pDEFI->iClipb;
+
+ iRetcode = process_display_defi (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_DEFI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_basi (mng_datap pData,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_bool bHasalpha,
+ mng_uint16 iAlpha,
+ mng_uint8 iViewable)
+{
+ mng_ani_basip pBASI;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_BASI, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pBASI, sizeof (mng_ani_basi))
+
+ pBASI->sHeader.fCleanup = free_ani_basi;
+ pBASI->sHeader.fProcess = process_ani_basi;
+
+ add_ani_object (pData, (mng_object_headerp)pBASI);
+
+ pBASI->iRed = iRed;
+ pBASI->iGreen = iGreen;
+ pBASI->iBlue = iBlue;
+ pBASI->bHasalpha = bHasalpha;
+ pBASI->iAlpha = iAlpha;
+ pBASI->iViewable = iViewable;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_BASI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_basi (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_BASI, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_basi))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_BASI, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_basi (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_basip pBASI = (mng_ani_basip)pObject;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BASI, MNG_LC_START)
+#endif
+
+ iRetcode = process_display_basi (pData, pBASI->iRed, pBASI->iGreen, pBASI->iBlue,
+ pBASI->bHasalpha, pBASI->iAlpha, pBASI->iViewable);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BASI, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_clon (mng_datap pData,
+ mng_uint16 iCloneid,
+ mng_uint16 iSourceid,
+ mng_uint8 iClonetype,
+ mng_bool bHasdonotshow,
+ mng_uint8 iDonotshow,
+ mng_uint8 iConcrete,
+ mng_bool bHasloca,
+ mng_uint8 iLocatype,
+ mng_int32 iLocax,
+ mng_int32 iLocay)
+{
+ mng_ani_clonp pCLON;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_CLON, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pCLON, sizeof (mng_ani_clon))
+
+ pCLON->sHeader.fCleanup = free_ani_clon;
+ pCLON->sHeader.fProcess = process_ani_clon;
+
+ add_ani_object (pData, (mng_object_headerp)pCLON);
+
+ pCLON->iCloneid = iCloneid;
+ pCLON->iSourceid = iSourceid;
+ pCLON->iClonetype = iClonetype;
+ pCLON->bHasdonotshow = bHasdonotshow;
+ pCLON->iDonotshow = iDonotshow;
+ pCLON->iConcrete = iConcrete;
+ pCLON->bHasloca = bHasloca;
+ pCLON->iLocatype = iLocatype;
+ pCLON->iLocax = iLocax;
+ pCLON->iLocay = iLocay;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_CLON, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_clon (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_CLON, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_clon))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_CLON, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_clon (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_clonp pCLON = (mng_ani_clonp)pObject;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CLON, MNG_LC_START)
+#endif
+
+ iRetcode = process_display_clon (pData, pCLON->iCloneid, pCLON->iSourceid,
+ pCLON->iClonetype, pCLON->bHasdonotshow,
+ pCLON->iDonotshow, pCLON->iConcrete,
+ pCLON->bHasloca, pCLON->iLocatype,
+ pCLON->iLocax, pCLON->iLocay);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CLON, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_back (mng_datap pData,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_uint8 iMandatory,
+ mng_uint16 iImageid,
+ mng_uint8 iTile)
+{
+ mng_ani_backp pBACK;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_BACK, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pBACK, sizeof (mng_ani_back))
+
+ pBACK->sHeader.fCleanup = free_ani_back;
+ pBACK->sHeader.fProcess = process_ani_back;
+
+ add_ani_object (pData, (mng_object_headerp)pBACK);
+
+ pBACK->iRed = iRed;
+ pBACK->iGreen = iGreen;
+ pBACK->iBlue = iBlue;
+ pBACK->iMandatory = iMandatory;
+ pBACK->iImageid = iImageid;
+ pBACK->iTile = iTile;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_BACK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_back (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_BACK, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_back))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_BACK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_back (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_backp pBACK = (mng_ani_backp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BACK, MNG_LC_START)
+#endif
+
+ pData->iBACKred = pBACK->iRed;
+ pData->iBACKgreen = pBACK->iGreen;
+ pData->iBACKblue = pBACK->iBlue;
+ pData->iBACKmandatory = pBACK->iMandatory;
+ pData->iBACKimageid = pBACK->iImageid;
+ pData->iBACKtile = pBACK->iTile;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_BACK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_fram (mng_datap pData,
+ mng_uint8 iFramemode,
+ mng_uint8 iChangedelay,
+ mng_uint32 iDelay,
+ mng_uint8 iChangetimeout,
+ mng_uint32 iTimeout,
+ mng_uint8 iChangeclipping,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb)
+{
+ mng_ani_framp pFRAM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_FRAM, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pFRAM, sizeof (mng_ani_fram))
+
+ pFRAM->sHeader.fCleanup = free_ani_fram;
+ pFRAM->sHeader.fProcess = process_ani_fram;
+
+ add_ani_object (pData, (mng_object_headerp)pFRAM);
+
+ pFRAM->iFramemode = iFramemode;
+ pFRAM->iChangedelay = iChangedelay;
+ pFRAM->iDelay = iDelay;
+ pFRAM->iChangetimeout = iChangetimeout;
+ pFRAM->iTimeout = iTimeout;
+ pFRAM->iChangeclipping = iChangeclipping;
+ pFRAM->iCliptype = iCliptype;
+ pFRAM->iClipl = iClipl;
+ pFRAM->iClipr = iClipr;
+ pFRAM->iClipt = iClipt;
+ pFRAM->iClipb = iClipb;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_FRAM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_fram (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_FRAM, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_fram))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_FRAM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_fram (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_framp pFRAM = (mng_ani_framp)pObject;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_FRAM, MNG_LC_START)
+#endif
+
+ if (pData->iBreakpoint) /* previously broken ? */
+ {
+ iRetcode = process_display_fram2 (pData);
+ pData->iBreakpoint = 0; /* not again */
+ }
+ else
+ iRetcode = process_display_fram (pData, pFRAM->iFramemode,
+ pFRAM->iChangedelay, pFRAM->iDelay,
+ pFRAM->iChangetimeout, pFRAM->iTimeout,
+ pFRAM->iChangeclipping, pFRAM->iCliptype,
+ pFRAM->iClipl, pFRAM->iClipr,
+ pFRAM->iClipt, pFRAM->iClipb);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_FRAM, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_move (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iType,
+ mng_int32 iLocax,
+ mng_int32 iLocay)
+{
+ mng_ani_movep pMOVE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_MOVE, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pMOVE, sizeof (mng_ani_move))
+
+ pMOVE->sHeader.fCleanup = free_ani_move;
+ pMOVE->sHeader.fProcess = process_ani_move;
+
+ add_ani_object (pData, (mng_object_headerp)pMOVE);
+
+ pMOVE->iFirstid = iFirstid;
+ pMOVE->iLastid = iLastid;
+ pMOVE->iType = iType;
+ pMOVE->iLocax = iLocax;
+ pMOVE->iLocay = iLocay;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_MOVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_move (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_MOVE, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_move))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_MOVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_move (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_retcode iRetcode;
+ mng_ani_movep pMOVE = (mng_ani_movep)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_MOVE, MNG_LC_START)
+#endif
+ /* re-process the MOVE chunk */
+ iRetcode = process_display_move (pData, pMOVE->iFirstid, pMOVE->iLastid,
+ pMOVE->iType,
+ pMOVE->iLocax, pMOVE->iLocay);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_MOVE, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_clip (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iType,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb)
+{
+ mng_ani_clipp pCLIP;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_CLIP, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pCLIP, sizeof (mng_ani_clip))
+
+ pCLIP->sHeader.fCleanup = free_ani_clip;
+ pCLIP->sHeader.fProcess = process_ani_clip;
+
+ add_ani_object (pData, (mng_object_headerp)pCLIP);
+
+ pCLIP->iFirstid = iFirstid;
+ pCLIP->iLastid = iLastid;
+ pCLIP->iType = iType;
+ pCLIP->iClipl = iClipl;
+ pCLIP->iClipr = iClipr;
+ pCLIP->iClipt = iClipt;
+ pCLIP->iClipb = iClipb;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_CLIP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_clip (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_CLIP, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_clip))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_CLIP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_clip (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_retcode iRetcode;
+ mng_ani_clipp pCLIP = (mng_ani_clipp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CLIP, MNG_LC_START)
+#endif
+ /* re-process the CLIP chunk */
+ iRetcode = process_display_clip (pData, pCLIP->iFirstid, pCLIP->iLastid,
+ pCLIP->iType,
+ pCLIP->iClipl, pCLIP->iClipr,
+ pCLIP->iClipt, pCLIP->iClipb);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_CLIP, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_show (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iMode)
+{
+ mng_ani_showp pSHOW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_SHOW, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pSHOW, sizeof (mng_ani_show))
+
+ pSHOW->sHeader.fCleanup = free_ani_show;
+ pSHOW->sHeader.fProcess = process_ani_show;
+
+ add_ani_object (pData, (mng_object_headerp)pSHOW);
+
+ pSHOW->iFirstid = iFirstid;
+ pSHOW->iLastid = iLastid;
+ pSHOW->iMode = iMode;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_SHOW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_show (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_SHOW, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_show))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_SHOW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_show (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_retcode iRetcode;
+ mng_ani_showp pSHOW = (mng_ani_showp)pObject;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SHOW, MNG_LC_START)
+#endif
+
+ if (pData->iBreakpoint) /* returning from breakpoint ? */
+ {
+ iRetcode = process_display_show (pData);
+ }
+ else
+ { /* "re-run" SHOW chunk */
+ pData->iSHOWmode = pSHOW->iMode;
+ pData->iSHOWfromid = pSHOW->iFirstid;
+ pData->iSHOWtoid = pSHOW->iLastid;
+
+ iRetcode = process_display_show (pData);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SHOW, MNG_LC_END)
+#endif
+
+ return iRetcode;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_term (mng_datap pData,
+ mng_uint8 iTermaction,
+ mng_uint8 iIteraction,
+ mng_uint32 iDelay,
+ mng_uint32 iItermax)
+{
+ mng_ani_termp pTERM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_TERM, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pTERM, sizeof (mng_ani_term))
+
+ pTERM->sHeader.fCleanup = free_ani_term;
+ pTERM->sHeader.fProcess = process_ani_term;
+
+ add_ani_object (pData, (mng_object_headerp)pTERM);
+
+ pTERM->iTermaction = iTermaction;
+ pTERM->iIteraction = iIteraction;
+ pTERM->iDelay = iDelay;
+ pTERM->iItermax = iItermax;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_TERM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_term (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_TERM, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_term))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_TERM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_term (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_TERM, MNG_LC_START)
+#endif
+
+ /* dummy: no action required! */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_TERM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_save (mng_datap pData)
+{
+ mng_ani_savep pSAVE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_SAVE, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pSAVE, sizeof (mng_ani_save))
+
+ pSAVE->sHeader.fCleanup = free_ani_save;
+ pSAVE->sHeader.fProcess = process_ani_save;
+
+ add_ani_object (pData, (mng_object_headerp)pSAVE);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_SAVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_save (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_SAVE, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_save))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_SAVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_save (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SAVE, MNG_LC_START)
+#endif
+
+ iRetcode = process_display_save (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SAVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_seek (mng_datap pData)
+{
+ mng_ani_seekp pSEEK;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_SEEK, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pSEEK, sizeof (mng_ani_seek))
+
+ pSEEK->sHeader.fCleanup = free_ani_seek;
+ pSEEK->sHeader.fProcess = process_ani_seek;
+
+ add_ani_object (pData, (mng_object_headerp)pSEEK);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_SEEK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_seek (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_SEEK, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_seek))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_SEEK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_seek (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SEEK, MNG_LC_START)
+#endif
+
+ iRetcode = process_display_seek (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_SEEK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_dhdr (mng_datap pData,
+ mng_uint16 iObjectid,
+ mng_uint8 iImagetype,
+ mng_uint8 iDeltatype,
+ mng_uint32 iBlockwidth,
+ mng_uint32 iBlockheight,
+ mng_uint32 iBlockx,
+ mng_uint32 iBlocky)
+{
+ mng_ani_dhdrp pDHDR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_DHDR, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pDHDR, sizeof (mng_ani_dhdr))
+
+ pDHDR->sHeader.fCleanup = free_ani_dhdr;
+ pDHDR->sHeader.fProcess = process_ani_dhdr;
+
+ pDHDR->iObjectid = iObjectid;
+ pDHDR->iImagetype = iImagetype;
+ pDHDR->iDeltatype = iDeltatype;
+ pDHDR->iBlockwidth = iBlockwidth;
+ pDHDR->iBlockheight = iBlockheight;
+ pDHDR->iBlockx = iBlockx;
+ pDHDR->iBlocky = iBlocky;
+
+ add_ani_object (pData, (mng_object_headerp)pDHDR);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_DHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_dhdr (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_DHDR, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_dhdr))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_DHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_dhdr (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_dhdrp pDHDR = (mng_ani_dhdrp)pObject;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_DHDR, MNG_LC_START)
+#endif
+
+ pData->bHasDHDR = MNG_TRUE; /* let everyone know we're inside a DHDR */
+
+ iRetcode = process_display_dhdr (pData, pDHDR->iObjectid,
+ pDHDR->iImagetype, pDHDR->iDeltatype,
+ pDHDR->iBlockwidth, pDHDR->iBlockheight,
+ pDHDR->iBlockx, pDHDR->iBlocky);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_DHDR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_prom (mng_datap pData,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iFilltype)
+{
+ mng_ani_promp pPROM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_PROM, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pPROM, sizeof (mng_ani_prom))
+
+ pPROM->sHeader.fCleanup = free_ani_prom;
+ pPROM->sHeader.fProcess = process_ani_prom;
+
+ pPROM->iBitdepth = iBitdepth;
+ pPROM->iColortype = iColortype;
+ pPROM->iFilltype = iFilltype;
+
+ add_ani_object (pData, (mng_object_headerp)pPROM);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_PROM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_prom (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_PROM, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_prom))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_PROM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_prom (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_promp pPROM = (mng_ani_promp)pObject;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PROM, MNG_LC_START)
+#endif
+
+ iRetcode = process_display_prom (pData, pPROM->iBitdepth,
+ pPROM->iColortype, pPROM->iFilltype);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PROM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_ipng (mng_datap pData)
+{
+ mng_ani_ipngp pIPNG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_IPNG, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pIPNG, sizeof (mng_ani_ipng))
+
+ pIPNG->sHeader.fCleanup = free_ani_ipng;
+ pIPNG->sHeader.fProcess = process_ani_ipng;
+
+ add_ani_object (pData, (mng_object_headerp)pIPNG);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_IPNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_ipng (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_IPNG, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_ipng))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_IPNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_ipng (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IPNG, MNG_LC_START)
+#endif
+
+ iRetcode = process_display_ipng (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IPNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_ijng (mng_datap pData)
+{
+ mng_ani_ijngp pIJNG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_IJNG, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pIJNG, sizeof (mng_ani_ijng))
+
+ pIJNG->sHeader.fCleanup = free_ani_ijng;
+ pIJNG->sHeader.fProcess = process_ani_ijng;
+
+ add_ani_object (pData, (mng_object_headerp)pIJNG);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_IJNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_ijng (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_IJNG, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_ijng))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_IJNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_ijng (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IJNG, MNG_LC_START)
+#endif
+
+ iRetcode = process_display_ijng (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_IJNG, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_pplt (mng_datap pData,
+ mng_uint8 iType,
+ mng_uint32 iCount,
+ mng_palette8ep paIndexentries,
+ mng_uint8p paAlphaentries,
+ mng_uint8p paUsedentries)
+{
+ mng_ani_ppltp pPPLT;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_PPLT, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pPPLT, sizeof (mng_ani_pplt))
+
+ pPPLT->sHeader.fCleanup = free_ani_pplt;
+ pPPLT->sHeader.fProcess = process_ani_pplt;
+
+ pPPLT->iType = iType;
+ pPPLT->iCount = iCount;
+
+ MNG_COPY (pPPLT->aIndexentries, paIndexentries, sizeof (pPPLT->aIndexentries))
+ MNG_COPY (pPPLT->aAlphaentries, paAlphaentries, sizeof (pPPLT->aAlphaentries))
+ MNG_COPY (pPPLT->aUsedentries, paUsedentries, sizeof (pPPLT->aUsedentries ))
+
+ add_ani_object (pData, (mng_object_headerp)pPPLT);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_PPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_pplt (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_PPLT, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_pplt))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_PPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_pplt (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_ppltp pPPLT = (mng_ani_ppltp)pObject;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PPLT, MNG_LC_START)
+#endif
+
+ iRetcode = process_display_pplt (pData, pPPLT->iType, pPPLT->iCount,
+ pPPLT->aIndexentries, pPPLT->aAlphaentries,
+ pPPLT->aUsedentries);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_PPLT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* ************************************************************************** */
+
+mng_retcode create_ani_magn (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint16 iMethodX,
+ mng_uint16 iMX,
+ mng_uint16 iMY,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint16 iMT,
+ mng_uint16 iMB,
+ mng_uint16 iMethodY)
+{
+ mng_ani_magnp pMAGN;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_MAGN, MNG_LC_START)
+#endif
+
+ if (pData->bCacheplayback) /* caching playback info ? */
+ {
+ MNG_ALLOC (pData, pMAGN, sizeof (mng_ani_magn))
+
+ pMAGN->sHeader.fCleanup = free_ani_magn;
+ pMAGN->sHeader.fProcess = process_ani_magn;
+
+ pMAGN->iFirstid = iFirstid;
+ pMAGN->iLastid = iLastid;
+ pMAGN->iMethodX = iMethodX;
+ pMAGN->iMX = iMX;
+ pMAGN->iMY = iMY;
+ pMAGN->iML = iML;
+ pMAGN->iMR = iMR;
+ pMAGN->iMT = iMT;
+ pMAGN->iMB = iMB;
+ pMAGN->iMethodY = iMethodY;
+
+ add_ani_object (pData, (mng_object_headerp)pMAGN);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CREATE_ANI_MAGN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_magn (mng_datap pData,
+ mng_objectp pObject)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_MAGN, MNG_LC_START)
+#endif
+
+ MNG_FREEX (pData, pObject, sizeof (mng_ani_magn))
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_FREE_ANI_MAGN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_magn (mng_datap pData,
+ mng_objectp pObject)
+{
+ mng_ani_magnp pMAGN = (mng_ani_magnp)pObject;
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_MAGN, MNG_LC_START)
+#endif
+
+ iRetcode = process_display_magn (pData, pMAGN->iFirstid, pMAGN->iLastid,
+ pMAGN->iMethodX, pMAGN->iMX, pMAGN->iMY,
+ pMAGN->iML, pMAGN->iMR, pMAGN->iMT, pMAGN->iMB,
+ pMAGN->iMethodY);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_ANI_MAGN, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_DISPLAY_PROCS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_object_prc.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_object_prc.h
new file mode 100644
index 0000000..97b4a77
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_object_prc.h
@@ -0,0 +1,432 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_object_prc.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Object processing routines (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the internal object processing routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - added support for global color-chunks in animation * */
+/* * - added support for global PLTE,tRNS,bKGD in animation * */
+/* * - added SAVE & SEEK animation objects * */
+/* * 0.5.2 - 05/29/2000 - G.Juyn * */
+/* * - changed ani_object create routines not to return the * */
+/* * created object (wasn't necessary) * */
+/* * - added compression/filter/interlace fields to * */
+/* * object-buffer for delta-image processing * */
+/* * * */
+/* * 0.5.3 - 06/22/2000 - G.Juyn * */
+/* * - added support for PPLT chunk * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - added routine to discard "invalid" objects * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_object_prc_h_
+#define _libmng_object_prc_h_
+
+/* ************************************************************************** */
+
+mng_retcode drop_invalid_objects (mng_datap pData);
+
+/* ************************************************************************** */
+
+mng_retcode create_imagedataobject (mng_datap pData,
+ mng_bool bConcrete,
+ mng_bool bViewable,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace,
+ mng_imagedatap *ppObject);
+
+mng_retcode free_imagedataobject (mng_datap pData,
+ mng_imagedatap pImagedata);
+
+mng_retcode clone_imagedataobject (mng_datap pData,
+ mng_bool bConcrete,
+ mng_imagedatap pSource,
+ mng_imagedatap *ppClone);
+
+/* ************************************************************************** */
+
+mng_retcode create_imageobject (mng_datap pData,
+ mng_uint16 iId,
+ mng_bool bConcrete,
+ mng_bool bVisible,
+ mng_bool bViewable,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace,
+ mng_int32 iPosx,
+ mng_int32 iPosy,
+ mng_bool bClipped,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb,
+ mng_imagep *ppObject);
+
+mng_retcode free_imageobject (mng_datap pData,
+ mng_imagep pImage);
+
+mng_imagep tqfind_imageobject (mng_datap pData,
+ mng_uint16 iId);
+
+mng_retcode clone_imageobject (mng_datap pData,
+ mng_uint16 iId,
+ mng_bool bPartial,
+ mng_bool bVisible,
+ mng_bool bAbstract,
+ mng_bool bHasloca,
+ mng_uint8 iLocationtype,
+ mng_int32 iLocationx,
+ mng_int32 iLocationy,
+ mng_imagep pSource,
+ mng_imagep *ppClone);
+
+mng_retcode renum_imageobject (mng_datap pData,
+ mng_imagep pSource,
+ mng_uint16 iId,
+ mng_bool bVisible,
+ mng_bool bAbstract,
+ mng_bool bHasloca,
+ mng_uint8 iLocationtype,
+ mng_int32 iLocationx,
+ mng_int32 iLocationy);
+
+mng_retcode reset_object_details (mng_datap pData,
+ mng_imagep pImage,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iCompression,
+ mng_uint8 iFilter,
+ mng_uint8 iInterlace,
+ mng_bool bResetall);
+
+mng_retcode promote_imageobject (mng_datap pData,
+ mng_imagep pImage,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iFilltype);
+
+mng_retcode magnify_imageobject (mng_datap pData,
+ mng_imagep pImage);
+
+/* ************************************************************************** */
+
+mng_retcode create_ani_image (mng_datap pData);
+
+mng_retcode create_ani_plte (mng_datap pData,
+ mng_uint32 iEntrycount,
+ mng_palette8ep paEntries);
+
+mng_retcode create_ani_trns (mng_datap pData,
+ mng_uint32 iRawlen,
+ mng_uint8p pRawdata);
+
+mng_retcode create_ani_gama (mng_datap pData,
+ mng_bool bEmpty,
+ mng_uint32 iGamma);
+
+mng_retcode create_ani_chrm (mng_datap pData,
+ mng_bool bEmpty,
+ mng_uint32 iWhitepointx,
+ mng_uint32 iWhitepointy,
+ mng_uint32 iRedx,
+ mng_uint32 iRedy,
+ mng_uint32 iGreenx,
+ mng_uint32 iGreeny,
+ mng_uint32 iBluex,
+ mng_uint32 iBluey);
+
+mng_retcode create_ani_srgb (mng_datap pData,
+ mng_bool bEmpty,
+ mng_uint8 iRenderinginent);
+
+mng_retcode create_ani_iccp (mng_datap pData,
+ mng_bool bEmpty,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile);
+
+mng_retcode create_ani_bkgd (mng_datap pData,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue);
+
+mng_retcode create_ani_loop (mng_datap pData,
+ mng_uint8 iLevel,
+ mng_uint32 iRepeatcount,
+ mng_uint8 iTermcond,
+ mng_uint32 iItermin,
+ mng_uint32 iItermax,
+ mng_uint32 iCount,
+ mng_uint32p pSignals);
+
+mng_retcode create_ani_endl (mng_datap pData,
+ mng_uint8 iLevel);
+
+mng_retcode create_ani_defi (mng_datap pData);
+
+mng_retcode create_ani_basi (mng_datap pData,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_bool bHasalpha,
+ mng_uint16 iAlpha,
+ mng_uint8 iViewable);
+
+mng_retcode create_ani_clon (mng_datap pData,
+ mng_uint16 iCloneid,
+ mng_uint16 iSourceid,
+ mng_uint8 iClonetype,
+ mng_bool bHasdonotshow,
+ mng_uint8 iDonotshow,
+ mng_uint8 iConcrete,
+ mng_bool bHasloca,
+ mng_uint8 iLocatype,
+ mng_int32 iLocax,
+ mng_int32 iLocay);
+
+mng_retcode create_ani_back (mng_datap pData,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue,
+ mng_uint8 iMandatory,
+ mng_uint16 iImageid,
+ mng_uint8 iTile);
+
+mng_retcode create_ani_fram (mng_datap pData,
+ mng_uint8 iFramemode,
+ mng_uint8 iChangedelay,
+ mng_uint32 iDelay,
+ mng_uint8 iChangetimeout,
+ mng_uint32 iTimeout,
+ mng_uint8 iChangeclipping,
+ mng_uint8 iCliptype,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb);
+
+mng_retcode create_ani_move (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iType,
+ mng_int32 iLocax,
+ mng_int32 iLocay);
+
+mng_retcode create_ani_clip (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iType,
+ mng_int32 iClipl,
+ mng_int32 iClipr,
+ mng_int32 iClipt,
+ mng_int32 iClipb);
+
+mng_retcode create_ani_show (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint8 iMode);
+
+mng_retcode create_ani_term (mng_datap pData,
+ mng_uint8 iTermaction,
+ mng_uint8 iIteraction,
+ mng_uint32 iDelay,
+ mng_uint32 iItermax);
+
+mng_retcode create_ani_save (mng_datap pData);
+mng_retcode create_ani_seek (mng_datap pData);
+
+mng_retcode create_ani_dhdr (mng_datap pData,
+ mng_uint16 iObjectid,
+ mng_uint8 iImagetype,
+ mng_uint8 iDeltatype,
+ mng_uint32 iBlockwidth,
+ mng_uint32 iBlockheight,
+ mng_uint32 iBlockx,
+ mng_uint32 iBlocky);
+
+mng_retcode create_ani_prom (mng_datap pData,
+ mng_uint8 iBitdepth,
+ mng_uint8 iColortype,
+ mng_uint8 iFilltype);
+
+mng_retcode create_ani_ipng (mng_datap pData);
+mng_retcode create_ani_ijng (mng_datap pData);
+
+mng_retcode create_ani_pplt (mng_datap pData,
+ mng_uint8 iType,
+ mng_uint32 iCount,
+ mng_palette8ep paIndexentries,
+ mng_uint8p paAlphaentries,
+ mng_uint8p paUsedentries);
+
+mng_retcode create_ani_magn (mng_datap pData,
+ mng_uint16 iFirstid,
+ mng_uint16 iLastid,
+ mng_uint16 iMethodX,
+ mng_uint16 iMX,
+ mng_uint16 iMY,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint16 iMT,
+ mng_uint16 iMB,
+ mng_uint16 iMethodY);
+
+/* ************************************************************************** */
+
+mng_retcode free_ani_image (mng_datap pData,
+ mng_objectp pObject);
+
+mng_retcode free_ani_plte (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_trns (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_gama (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_chrm (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_srgb (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_iccp (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_bkgd (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_loop (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_endl (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_defi (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_basi (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_clon (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_back (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_fram (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_move (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_clip (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_show (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_term (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_save (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_seek (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_dhdr (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_prom (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_ipng (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_ijng (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_pplt (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode free_ani_magn (mng_datap pData,
+ mng_objectp pObject);
+
+/* ************************************************************************** */
+
+mng_retcode process_ani_image (mng_datap pData,
+ mng_objectp pObject);
+
+mng_retcode process_ani_plte (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_trns (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_gama (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_chrm (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_srgb (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_iccp (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_bkgd (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_loop (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_endl (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_defi (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_basi (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_clon (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_back (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_fram (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_move (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_clip (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_show (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_term (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_save (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_seek (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_dhdr (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_prom (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_ipng (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_ijng (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_pplt (mng_datap pData,
+ mng_objectp pObject);
+mng_retcode process_ani_magn (mng_datap pData,
+ mng_objectp pObject);
+
+/* ************************************************************************** */
+
+#endif /* _libmng_object_prc_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_objects.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_objects.h
new file mode 100644
index 0000000..67647f3
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_objects.h
@@ -0,0 +1,509 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_objects.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Internal object structures (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the internal object structures * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.5.2 - 05/23/2000 - G.Juyn * */
+/* * - changed inclusion to DISPLAY_PROCS * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - added global color-chunks for animations * */
+/* * - added global PLTE,tRNS,bKGD chunks for animation * */
+/* * - added SAVE & SEEK animation objects * */
+/* * 0.5.2 - 05/29/2000 - G.Juyn * */
+/* * - added framenr/layernr/playtime to object header * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added ani-objects for delta-image processing * */
+/* * - added compression/filter/interlace fields to * */
+/* * object-buffer for delta-image processing * */
+/* * * */
+/* * 0.5.3 - 06/17/2000 - G.Juyn * */
+/* * - changed definition of aTRNSentries * */
+/* * 0.5.3 - 06/22/2000 - G.Juyn * */
+/* * - added definition for PPLT animation-processing * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/10/2000 - G.Juyn * */
+/* * - fixed DEFI behavior * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added support for delta-JNG * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - added valid-flag to stored objects for read() / display()* */
+/* * 0.9.3 - 10/19/2000 - G.Juyn * */
+/* * - added storage for pixel-/alpha-sampledepth for delta's * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_objects_h_
+#define _libmng_objects_h_
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_DISPLAY_PROCS
+
+/* ************************************************************************** */
+
+typedef mng_retcode (*mng_cleanupobject) (mng_datap pData,
+ mng_objectp pHeader);
+
+typedef mng_retcode (*mng_processobject) (mng_datap pData,
+ mng_objectp pHeader);
+
+/* ************************************************************************** */
+
+typedef struct {
+ mng_cleanupobject fCleanup;
+ mng_processobject fProcess;
+ mng_objectp pNext; /* for double-linked list */
+ mng_objectp pPrev;
+ mng_uint32 iFramenr;
+ mng_uint32 iLayernr;
+ mng_uint32 iPlaytime;
+ } mng_object_header;
+typedef mng_object_header * mng_object_headerp;
+
+/* ************************************************************************** */
+
+typedef struct { /* MNG specification "object-buffer" */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint32 iRefcount; /* reference counter */
+ mng_bool bFrozen; /* frozen flag */
+ mng_bool bConcrete; /* concrete flag */
+ mng_bool bViewable; /* viewable flag */
+ mng_uint32 iWidth; /* image specifics */
+ mng_uint32 iHeight;
+ mng_uint8 iBitdepth;
+ mng_uint8 iColortype;
+ mng_uint8 iCompression;
+ mng_uint8 iFilter;
+ mng_uint8 iInterlace;
+
+ mng_uint8 iAlphabitdepth; /* used only for JNG images */
+ mng_uint8 iJHDRcompression;
+ mng_uint8 iJHDRinterlace;
+
+ mng_uint8 iPixelsampledepth; /* used with delta-images */
+ mng_uint8 iAlphasampledepth;
+
+ mng_bool bHasPLTE; /* PLTE chunk present */
+ mng_bool bHasTRNS; /* tRNS chunk present */
+ mng_bool bHasGAMA; /* gAMA chunk present */
+ mng_bool bHasCHRM; /* cHRM chunk present */
+ mng_bool bHasSRGB; /* sRGB chunk present */
+ mng_bool bHasICCP; /* iCCP chunk present */
+ mng_bool bHasBKGD; /* bKGD chunk present */
+
+ mng_uint32 iPLTEcount; /* PLTE fields */
+ mng_rgbpaltab aPLTEentries;
+
+ mng_uint16 iTRNSgray; /* tRNS fields */
+ mng_uint16 iTRNSred;
+ mng_uint16 iTRNSgreen;
+ mng_uint16 iTRNSblue;
+ mng_uint32 iTRNScount;
+ mng_uint8arr aTRNSentries;
+
+ mng_uint32 iGamma; /* gAMA fields */
+
+ mng_uint32 iWhitepointx; /* cHRM fields */
+ mng_uint32 iWhitepointy;
+ mng_uint32 iPrimaryredx;
+ mng_uint32 iPrimaryredy;
+ mng_uint32 iPrimarygreenx;
+ mng_uint32 iPrimarygreeny;
+ mng_uint32 iPrimarybluex;
+ mng_uint32 iPrimarybluey;
+
+ mng_uint8 iRenderingintent; /* sRGB fields */
+
+ mng_uint32 iProfilesize; /* iCCP fields */
+ mng_ptr pProfile;
+
+ mng_uint8 iBKGDindex; /* bKGD fields */
+ mng_uint16 iBKGDgray;
+ mng_uint16 iBKGDred;
+ mng_uint16 iBKGDgreen;
+ mng_uint16 iBKGDblue;
+
+ mng_uint32 iSamplesize; /* size of a sample */
+ mng_uint32 iRowsize; /* size of a row of samples */
+ mng_uint32 iImgdatasize; /* size of the sample data buffer */
+ mng_uint8p pImgdata; /* actual sample data buffer */
+
+ } mng_imagedata;
+typedef mng_imagedata * mng_imagedatap;
+
+/* ************************************************************************** */
+
+typedef struct { /* MNG specification "object" */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iId; /* object-id */
+ mng_bool bFrozen; /* frozen flag */
+ mng_bool bVisible; /* potential visibility flag */
+ mng_bool bViewable; /* viewable flag */
+ mng_bool bValid; /* marks invalid when only reading */
+ mng_int32 iPosx; /* location fields */
+ mng_int32 iPosy;
+ mng_bool bClipped; /* clipping fields */
+ mng_int32 iClipl;
+ mng_int32 iClipr;
+ mng_int32 iClipt;
+ mng_int32 iClipb;
+ mng_uint16 iMAGN_MethodX; /* magnification (MAGN) */
+ mng_uint16 iMAGN_MethodY;
+ mng_uint16 iMAGN_MX;
+ mng_uint16 iMAGN_MY;
+ mng_uint16 iMAGN_ML;
+ mng_uint16 iMAGN_MR;
+ mng_uint16 iMAGN_MT;
+ mng_uint16 iMAGN_MB;
+ mng_imagedatap pImgbuf; /* the image-data buffer */
+ } mng_image;
+typedef mng_image * mng_imagep;
+
+/* ************************************************************************** */
+
+ /* "on-the-fly" image (= object 0) */
+typedef mng_image mng_ani_image; /* let's (ab)use the general "object" */
+typedef mng_ani_image * mng_ani_imagep; /* that's actualy crucial, so don't change it! */
+
+/* ************************************************************************** */
+
+typedef struct { /* global PLTE object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint32 iEntrycount;
+ mng_rgbpaltab aEntries;
+ } mng_ani_plte;
+typedef mng_ani_plte * mng_ani_pltep;
+
+/* ************************************************************************** */
+
+typedef struct { /* global tRNS object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint32 iRawlen;
+ mng_uint8arr aRawdata;
+ } mng_ani_trns;
+typedef mng_ani_trns * mng_ani_trnsp;
+
+/* ************************************************************************** */
+
+typedef struct { /* global gAMA object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_bool bEmpty;
+ mng_uint32 iGamma;
+ } mng_ani_gama;
+typedef mng_ani_gama * mng_ani_gamap;
+
+/* ************************************************************************** */
+
+typedef struct { /* global gCRM object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_bool bEmpty;
+ mng_uint32 iWhitepointx;
+ mng_uint32 iWhitepointy;
+ mng_uint32 iRedx;
+ mng_uint32 iRedy;
+ mng_uint32 iGreenx;
+ mng_uint32 iGreeny;
+ mng_uint32 iBluex;
+ mng_uint32 iBluey;
+ } mng_ani_chrm;
+typedef mng_ani_chrm * mng_ani_chrmp;
+
+/* ************************************************************************** */
+
+typedef struct { /* global sRGB object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_bool bEmpty;
+ mng_uint8 iRenderingintent;
+ } mng_ani_srgb;
+typedef mng_ani_srgb * mng_ani_srgbp;
+
+/* ************************************************************************** */
+
+typedef struct { /* global iCCP object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_bool bEmpty;
+ mng_uint32 iProfilesize;
+ mng_ptr pProfile;
+ } mng_ani_iccp;
+typedef mng_ani_iccp * mng_ani_iccpp;
+
+/* ************************************************************************** */
+
+typedef struct { /* global bKGD object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iRed;
+ mng_uint16 iGreen;
+ mng_uint16 iBlue;
+ } mng_ani_bkgd;
+typedef mng_ani_bkgd * mng_ani_bkgdp;
+
+/* ************************************************************************** */
+
+typedef struct { /* LOOP object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint8 iLevel;
+ mng_uint32 iRepeatcount;
+ mng_uint8 iTermcond;
+ mng_uint32 iItermin;
+ mng_uint32 iItermax;
+ mng_uint32 iCount;
+ mng_uint32p pSignals;
+
+ mng_uint32 iRunningcount; /* running counter */
+ } mng_ani_loop;
+typedef mng_ani_loop * mng_ani_loopp;
+
+/* ************************************************************************** */
+
+typedef struct { /* ENDL object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint8 iLevel;
+
+ mng_ani_loopp pLOOP; /* matching LOOP */
+ } mng_ani_endl;
+typedef mng_ani_endl * mng_ani_endlp;
+
+/* ************************************************************************** */
+
+typedef struct { /* DEFI object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iId;
+ mng_bool bHasdonotshow;
+ mng_uint8 iDonotshow;
+ mng_bool bHasconcrete;
+ mng_uint8 iConcrete;
+ mng_bool bHasloca;
+ mng_int32 iLocax;
+ mng_int32 iLocay;
+ mng_bool bHasclip;
+ mng_int32 iClipl;
+ mng_int32 iClipr;
+ mng_int32 iClipt;
+ mng_int32 iClipb;
+ } mng_ani_defi;
+typedef mng_ani_defi * mng_ani_defip;
+
+/* ************************************************************************** */
+
+typedef struct { /* BASI object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iRed;
+ mng_uint16 iGreen;
+ mng_uint16 iBlue;
+ mng_bool bHasalpha;
+ mng_uint16 iAlpha;
+ mng_uint8 iViewable;
+ } mng_ani_basi;
+typedef mng_ani_basi * mng_ani_basip;
+
+/* ************************************************************************** */
+
+typedef struct { /* CLON object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iCloneid;
+ mng_uint16 iSourceid;
+ mng_uint8 iClonetype;
+ mng_bool bHasdonotshow;
+ mng_uint8 iDonotshow;
+ mng_uint8 iConcrete;
+ mng_bool bHasloca;
+ mng_uint8 iLocatype;
+ mng_int32 iLocax;
+ mng_int32 iLocay;
+ } mng_ani_clon;
+typedef mng_ani_clon * mng_ani_clonp;
+
+/* ************************************************************************** */
+
+typedef struct { /* BACK object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iRed;
+ mng_uint16 iGreen;
+ mng_uint16 iBlue;
+ mng_uint8 iMandatory;
+ mng_uint16 iImageid;
+ mng_uint8 iTile;
+ } mng_ani_back;
+typedef mng_ani_back * mng_ani_backp;
+
+/* ************************************************************************** */
+
+typedef struct { /* FRAM object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint8 iFramemode;
+ mng_uint8 iChangedelay;
+ mng_uint32 iDelay;
+ mng_uint8 iChangetimeout;
+ mng_uint32 iTimeout;
+ mng_uint8 iChangeclipping;
+ mng_uint8 iCliptype;
+ mng_int32 iClipl;
+ mng_int32 iClipr;
+ mng_int32 iClipt;
+ mng_int32 iClipb;
+ } mng_ani_fram;
+typedef mng_ani_fram * mng_ani_framp;
+
+/* ************************************************************************** */
+
+typedef struct { /* MOVE object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iFirstid;
+ mng_uint16 iLastid;
+ mng_uint8 iType;
+ mng_int32 iLocax;
+ mng_int32 iLocay;
+ } mng_ani_move;
+typedef mng_ani_move * mng_ani_movep;
+
+/* ************************************************************************** */
+
+typedef struct { /* CLIP object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iFirstid;
+ mng_uint16 iLastid;
+ mng_uint8 iType;
+ mng_int32 iClipl;
+ mng_int32 iClipr;
+ mng_int32 iClipt;
+ mng_int32 iClipb;
+ } mng_ani_clip;
+typedef mng_ani_clip * mng_ani_clipp;
+
+/* ************************************************************************** */
+
+typedef struct { /* SHOW object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iFirstid;
+ mng_uint16 iLastid;
+ mng_uint8 iMode;
+ } mng_ani_show;
+typedef mng_ani_show * mng_ani_showp;
+
+/* ************************************************************************** */
+
+typedef struct { /* TERM object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint8 iTermaction;
+ mng_uint8 iIteraction;
+ mng_uint32 iDelay;
+ mng_uint32 iItermax;
+ } mng_ani_term;
+typedef mng_ani_term * mng_ani_termp;
+
+/* ************************************************************************** */
+
+typedef struct { /* SAVE object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ } mng_ani_save;
+typedef mng_ani_save * mng_ani_savep;
+
+/* ************************************************************************** */
+
+typedef struct { /* SEEK object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ } mng_ani_seek;
+typedef mng_ani_seek * mng_ani_seekp;
+
+/* ************************************************************************** */
+
+typedef struct { /* DHDR object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iObjectid;
+ mng_uint8 iImagetype;
+ mng_uint8 iDeltatype;
+ mng_uint32 iBlockwidth;
+ mng_uint32 iBlockheight;
+ mng_uint32 iBlockx;
+ mng_uint32 iBlocky;
+ } mng_ani_dhdr;
+typedef mng_ani_dhdr * mng_ani_dhdrp;
+
+/* ************************************************************************** */
+
+typedef struct { /* PROM object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint8 iBitdepth;
+ mng_uint8 iColortype;
+ mng_uint8 iFilltype;
+ } mng_ani_prom;
+typedef mng_ani_prom * mng_ani_promp;
+
+/* ************************************************************************** */
+
+typedef struct { /* IPNG object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ } mng_ani_ipng;
+typedef mng_ani_ipng * mng_ani_ipngp;
+
+/* ************************************************************************** */
+
+typedef struct { /* IJNG object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ } mng_ani_ijng;
+typedef mng_ani_ijng * mng_ani_ijngp;
+
+/* ************************************************************************** */
+
+typedef struct { /* PPLT object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint8 iType;
+ mng_uint32 iCount;
+ mng_rgbpaltab aIndexentries;
+ mng_uint8arr aAlphaentries;
+ mng_uint8arr aUsedentries;
+ } mng_ani_pplt;
+typedef mng_ani_pplt * mng_ani_ppltp;
+
+/* ************************************************************************** */
+
+typedef struct { /* MAGN object */
+ mng_object_header sHeader; /* default header (DO NOT REMOVE) */
+ mng_uint16 iFirstid;
+ mng_uint16 iLastid;
+ mng_uint16 iMethodX;
+ mng_uint16 iMX;
+ mng_uint16 iMY;
+ mng_uint16 iML;
+ mng_uint16 iMR;
+ mng_uint16 iMT;
+ mng_uint16 iMB;
+ mng_uint16 iMethodY;
+ } mng_ani_magn;
+typedef mng_ani_magn * mng_ani_magnp;
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_DISPLAY_PROCS */
+
+/* ************************************************************************** */
+
+#endif /* _libmng_objects_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_pixels.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_pixels.c
new file mode 100644
index 0000000..07af830
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_pixels.c
@@ -0,0 +1,10845 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_pixels.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.4 * */
+/* * * */
+/* * purpose : Pixel-row management routines (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the pixel-row management routines * */
+/* * * */
+/* * the dual alpha-composing for RGBA/BGRA/etc output-canvas' * */
+/* * is based on the Note on Compositing chapter of the * */
+/* * DOH-3 draft, noted to me by Adam M. Costello * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added callback error-reporting support * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * * */
+/* * 0.5.2 - 05/22/2000 - G.Juyn * */
+/* * - added JNG support * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - fixed minor bugs 16-bit pixel-handling * */
+/* * - added delta-image row-processing routines * */
+/* * 0.5.2 - 06/02/2000 - G.Juyn * */
+/* * - fixed endian support (hopefully) * */
+/* * 0.5.2 - 06/03/2000 - G.Juyn * */
+/* * - fixed makeup for Linux gcc compile * */
+/* * 0.5.2 - 06/05/2000 - G.Juyn * */
+/* * - implemented app bkgd restore routines * */
+/* * - implemented RGBA8, ARGB8, BGRA8 & ABGR8 display routines * */
+/* * - added support for RGB8_A8 canvasstyle * */
+/* * 0.5.2 - 06/09/2000 - G.Juyn * */
+/* * - fixed alpha-handling for alpha canvasstyles * */
+/* * * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - changed progressive-display processing * */
+/* * 0.5.3 - 06/17/2000 - G.Juyn * */
+/* * - changed to support delta-images * */
+/* * - optimized some store_xxx routines * */
+/* * 0.5.3 - 06/20/2000 - G.Juyn * */
+/* * - fixed nasty bug with embedded PNG after delta-image * */
+/* * 0.5.3 - 06/24/2000 - G.Juyn * */
+/* * - fixed problem with 16-bit GA format * */
+/* * 0.5.3 - 06/25/2000 - G.Juyn * */
+/* * - fixed problem with cheap transparency for 4-bit gray * */
+/* * - fixed display_xxxx routines for interlaced images * */
+/* * 0.5.3 - 06/28/2000 - G.Juyn * */
+/* * - fixed compiler-warning for non-initialized iB variable * */
+/* * * */
+/* * 0.9.1 - 07/05/2000 - G.Juyn * */
+/* * - fixed mandatory BACK color to be opaque * */
+/* * * */
+/* * 0.9.2 - 07/31/2000 - G.Juyn * */
+/* * - B110547 - fixed bug in interlace code * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/20/2000 - G.Juyn * */
+/* * - fixed app-supplied background restore * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * 0.9.3 - 09/30/2000 - G.Juyn * */
+/* * - fixed MAGN rounding errors (thanks Matthias!) * */
+/* * 0.9.3 - 10/10/2000 - G.Juyn * */
+/* * - fixed alpha-blending for RGBA canvasstyle * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - fixed alpha-blending for other alpha-canvasstyles * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added optional support for bKGD for PNG images * */
+/* * - added support for JDAA * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - fixed support for bKGD * */
+/* * 0.9.3 - 10/19/2000 - G.Juyn * */
+/* * - implemented delayed delta-processing * */
+/* * 0.9.3 - 10/28/2000 - G.Juyn * */
+/* * - fixed tRNS processing for gray-image < 8-bits * */
+/* * * */
+/* * 0.9.4 - 12/16/2000 - G.Juyn * */
+/* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
+/* * 0.9.4 - 1/18/2001 - G.Juyn * */
+/* * - removed "old" MAGN methods 3 & 4 * */
+/* * - added "new" MAGN methods 3, 4 & 5 * */
+/* * - removed test filter-methods 1 & 65 * */
+/* * * */
+/* * 1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly) * */
+/* * - added BGRA8 canvas with premultiplied alpha * */
+/* * 1.0.1 - 04/25/2001 - G.Juyn * */
+/* * - moved mng_clear_cms to libmng_cms * */
+/* * * */
+/* * 1.0.2 - 06/25/2001 - G.Juyn * */
+/* * - added option to turn off progressive refresh * */
+/* * * */
+/* * 1.0.4 - 11/04/2001 - G.Juyn * */
+/* * - fixed possible compile-problem in cleanup_rowproc * */
+/* * 1.0.4 - 06/22/2002 - G.Juyn * */
+/* * - B558212 - off by one error * */
+/* * - MNG subimage alpha composite wrong for rgba8 images * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_objects.h"
+#include "libmng_memory.h"
+#include "libmng_cms.h"
+#include "libmng_filter.h"
+#include "libmng_pixels.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_DISPLAY_PROCS
+
+/* TODO: magnification & canvas-positioning/-clipping */
+
+/* TODO: major optimization of pixel-loops by using assembler (?) */
+
+/* ************************************************************************** */
+/* * * */
+/* * Interlace tables * */
+/* * * */
+/* ************************************************************************** */
+
+mng_uint32 const interlace_row [7] = { 0, 0, 4, 0, 2, 0, 1 };
+mng_uint32 const interlace_rowskip [7] = { 8, 8, 8, 4, 4, 2, 2 };
+mng_uint32 const interlace_col [7] = { 0, 4, 0, 2, 0, 1, 0 };
+mng_uint32 const interlace_colskip [7] = { 8, 8, 4, 4, 2, 2, 1 };
+mng_uint32 const interlace_roundoff [7] = { 7, 7, 3, 3, 1, 1, 0 };
+mng_uint32 const interlace_divider [7] = { 3, 3, 2, 2, 1, 1, 0 };
+
+/* ************************************************************************** */
+/* * * */
+/* * Alpha composing macros * */
+/* * the code below is slightly modified from the libpng package * */
+/* * the original was last optimized by Greg Roelofs & Mark Adler * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_COMPOSE8(RET,FG,ALPHA,BG) { \
+ mng_uint16 iH = (mng_uint16)((mng_uint16)(FG) * (mng_uint16)(ALPHA) \
+ + (mng_uint16)(BG)*(mng_uint16)(255 - \
+ (mng_uint16)(ALPHA)) + (mng_uint16)128); \
+ (RET) = (mng_uint8)((iH + (iH >> 8)) >> 8); }
+
+#define MNG_COMPOSE16(RET,FG,ALPHA,BG) { \
+ mng_uint32 iH = (mng_uint32)((mng_uint32)(FG) * (mng_uint32)(ALPHA) \
+ + (mng_uint32)(BG)*(mng_uint32)(65535L - \
+ (mng_uint32)(ALPHA)) + (mng_uint32)32768L); \
+ (RET) = (mng_uint16)((iH + (iH >> 16)) >> 16); }
+
+/* ************************************************************************** */
+/* * * */
+/* * Alpha blending macros * */
+/* * this code is based on Adam Costello's "Note on Compositing" from the * */
+/* * mng-list which gives the following formula: * */
+/* * * */
+/* * top pixel = (Rt, Gt, Bt, At) * */
+/* * bottom pixel = (Rb, Gb, Bb, Ab) * */
+/* * composite pixel = (Rc, Gc, Bc, Ac) * */
+/* * * */
+/* * all values in the range 0..1 * */
+/* * * */
+/* * Ac = 1 - (1 - At)(1 - Ab) * */
+/* * s = At / Ac * */
+/* * t = (1 - At) Ab / Ac * */
+/* * Rc = s Rt + t Rb * */
+/* * Gc = s Gt + t Gb * */
+/* * Bc = s Bt + t Bb * */
+/* * * */
+/* * (I just hope I coded it correctly in integer arithmetic...) * */
+/* * * */
+/* ************************************************************************** */
+
+#define MNG_BLEND8(RT, GT, BT, AT, RB, GB, BB, AB, RC, GC, BC, AC) { \
+ mng_uint32 S, T; \
+ (AC) = (mng_uint8)((mng_uint32)255 - \
+ ((((mng_uint32)255 - (mng_uint32)(AT)) * \
+ ((mng_uint32)255 - (mng_uint32)(AB)) ) >> 8)); \
+ S = (mng_uint32)(((mng_uint32)(AT) << 8) / \
+ (mng_uint32)(AC)); \
+ T = (mng_uint32)(((mng_uint32)255 - (mng_uint32)(AT)) * \
+ (mng_uint32)(AB) / (mng_uint32)(AC)); \
+ (RC) = (mng_uint8)((S * (mng_uint32)(RT) + \
+ T * (mng_uint32)(RB) + (mng_uint32)127) >> 8); \
+ (GC) = (mng_uint8)((S * (mng_uint32)(GT) + \
+ T * (mng_uint32)(GB) + (mng_uint32)127) >> 8); \
+ (BC) = (mng_uint8)((S * (mng_uint32)(BT) + \
+ T * (mng_uint32)(BB) + (mng_uint32)127) >> 8); }
+
+#define MNG_BLEND16(RT, GT, BT, AT, RB, GB, BB, AB, RC, GC, BC, AC) { \
+ mng_uint32 S, T; \
+ (AC) = (mng_uint16)((mng_uint32)65525 - \
+ ((((mng_uint32)65535 - (mng_uint32)(AT)) * \
+ ((mng_uint32)65535 - (mng_uint32)(AB)) ) >> 16)); \
+ S = (mng_uint32)(((mng_uint32)(AT) << 16) / \
+ (mng_uint32)(AC)); \
+ T = (mng_uint32)(((mng_uint32)65535 - (mng_uint32)(AT)) * \
+ (mng_uint32)(AB) / (mng_uint32)(AC)); \
+ (RC) = (mng_uint16)((S * (mng_uint32)(RT) + \
+ T * (mng_uint32)(RB) + (mng_uint32)32767) >> 16); \
+ (GC) = (mng_uint16)((S * (mng_uint32)(GT) + \
+ T * (mng_uint32)(GB) + (mng_uint32)32767) >> 16); \
+ (BC) = (mng_uint16)((S * (mng_uint32)(BT) + \
+ T * (mng_uint32)(BB) + (mng_uint32)32767) >> 16); }
+
+/* ************************************************************************** */
+
+/* note a good optimizing compiler will optimize this */
+#define DIV255B8(x) (mng_uint8)(((x) + 127) / 255)
+#define DIV255B16(x) (mng_uint16)(((x) + 32767) / 65535)
+
+/* ************************************************************************** */
+/* * * */
+/* * Progressive display check - checks to see if progressive display is * */
+/* * in order & indicates so * */
+/* * * */
+/* * The routine is called after a call to one of the display_xxx routines * */
+/* * if appropriate * */
+/* * * */
+/* * The refresh is warrented in the read_chunk routine (mng_read.c) * */
+/* * and only during read&display processing, since there's not much point * */
+/* * doing it from memory! * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode display_progressive_check (mng_datap pData)
+{
+ if ((pData->bDoProgressive) && /* need progressive display? */
+ ((pData->eImagetype != mng_it_mng) || (pData->iDataheight > 300)) &&
+ (pData->iDestb - pData->iDestt > 50) && (!pData->pCurraniobj))
+ {
+ mng_int32 iC = pData->iRow + pData->iDestt - pData->iSourcet;
+
+ if (iC % 20 == 0) /* every 20th line */
+ pData->bNeedrefresh = MNG_TRUE;
+
+ }
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Display routines - convert rowdata (which is already color-corrected) * */
+/* * to the output canvas, respecting the opacity information * */
+/* * * */
+/* ************************************************************************** */
+
+void check_update_region (mng_datap pData)
+{ /* determine actual canvas row */
+ mng_int32 iRow = pData->iRow + pData->iDestt - pData->iSourcet;
+ /* check for change in update-region */
+ if ((pData->iDestl < (mng_int32)pData->iUpdateleft) || (pData->iUpdateright == 0))
+ pData->iUpdateleft = pData->iDestl;
+
+ if (pData->iDestr > (mng_int32)pData->iUpdateright)
+ pData->iUpdateright = pData->iDestr;
+
+ if ((iRow < (mng_int32)pData->iUpdatetop) || (pData->iUpdatebottom == 0))
+ pData->iUpdatetop = iRow;
+
+ if (iRow+1 > (mng_int32)pData->iUpdatebottom)
+ pData->iUpdatebottom = iRow+1;
+
+ return;
+}
+
+/* ************************************************************************** */
+
+mng_retcode display_rgb8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START)
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ {
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16)
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16)
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16)
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ }
+ else
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *pDataline, iA8, *pScanline )
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1))
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iA8, *(pScanline+2))
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode display_rgba8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START)
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ *(pScanline+3) = *(pDataline+6);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+3);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*(pScanline+3));
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ *(pScanline+3) = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16)
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16)
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16)
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16)
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+3);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *pDataline, iFGa8, *pScanline )
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1))
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2))
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8)
+ /* and return the composed values */
+ *pScanline = iCr8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCb8;
+ *(pScanline+3) = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode display_argb8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_START)
+#endif
+
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+6);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+4);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *(pDataline+2);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pScanline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *(pDataline+6);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *(pDataline+4);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+1));
+ iBGg16 = (mng_uint16)(*(pScanline+2));
+ iBGb16 = (mng_uint16)(*(pScanline+3));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16)
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16)
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16)
+ /* and return the composed values */
+ /* alpha remains fully opaque !!! */
+ *(pScanline+1) = (mng_uint8)(iFGr16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iFGb16 >> 8);
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+1));
+ iBGg16 = (mng_uint16)(*(pScanline+2));
+ iBGb16 = (mng_uint16)(*(pScanline+3));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16)
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCa16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCb16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pScanline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *pDataline;
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *(pDataline+2);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do simple alpha composing */
+ /* alpha itself remains fully opaque !!! */
+ MNG_COMPOSE8 (*(pScanline+1), *pDataline, iFGa8, *(pScanline+1))
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2))
+ MNG_COMPOSE8 (*(pScanline+3), *(pDataline+2), iFGa8, *(pScanline+3))
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+1), *(pScanline+2), *(pScanline+3), iBGa8,
+ iCr8, iCg8, iCb8, iCa8)
+ /* and return the composed values */
+ *pScanline = iCa8;
+ *(pScanline+1) = iCr8;
+ *(pScanline+2) = iCg8;
+ *(pScanline+3) = iCb8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ARGB8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode display_rgb8_a8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pAlphaline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_START)
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination rows */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ pAlphaline = (mng_uint8p)pData->fGetalphaline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination rows starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pAlphaline = pAlphaline + pData->iCol + pData->iDestl;
+
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ *pAlphaline = *(pDataline+6);
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *pAlphaline = *(pDataline+3);
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pAlphaline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+4);
+ *pAlphaline = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16)
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16)
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16)
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*pScanline );
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*(pScanline+2));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16)
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
+ *pAlphaline = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pAlphaline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *pDataline;
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *(pDataline+2);
+ *pAlphaline = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *pDataline, iFGa8, *pScanline )
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1))
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2))
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
+ iCr8, iCg8, iCb8, iCa8)
+ /* and return the composed values */
+ *pScanline = iCr8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCb8;
+ *pAlphaline = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pAlphaline += pData->iColinc;
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8_A8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode display_bgr8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iA16;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint8 iA8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_START)
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 8;
+ else
+ pDataline = pDataline + (pData->iSourcel / pData->iColinc) * 4;
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* get alpha value */
+ iA16 = mng_get_uint16 (pDataline+6);
+
+ if (iA16) /* any opacity at all ? */
+ {
+ if (iA16 == 0xFFFF) /* fully opaque ? */
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ }
+ else
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+2));
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*pScanline );
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16)
+ MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16)
+ MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16)
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGb16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ {
+ iA8 = *(pDataline+3); /* get alpha value */
+
+ if (iA8) /* any opacity at all ? */
+ {
+ if (iA8 == 0xFF) /* fully opaque ? */
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ }
+ else
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *(pDataline+2), iA8, *pScanline )
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1))
+ MNG_COMPOSE8 (*(pScanline+2), *pDataline, iA8, *(pScanline+2))
+ }
+ }
+
+ pScanline += (pData->iColinc * 3);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGR8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode display_bgra8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_START)
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+6);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+3);
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*(pScanline+3));
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *(pDataline+4);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+6);
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+2));
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*pScanline );
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16)
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16)
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16)
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iFGb16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGr16 >> 8);
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+2));
+ iBGg16 = (mng_uint16)(*(pScanline+1));
+ iBGb16 = (mng_uint16)(*pScanline );
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16)
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCb16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCr16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *(pScanline+3);
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+2);
+ *(pScanline+1) = *(pDataline+1);
+ *(pScanline+2) = *pDataline;
+ *(pScanline+3) = *(pDataline+3);
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do alpha composing */
+ MNG_COMPOSE8 (*pScanline, *(pDataline+2), iFGa8, *pScanline )
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1))
+ MNG_COMPOSE8 (*(pScanline+2), *pDataline, iFGa8, *(pScanline+2))
+ /* alpha remains fully opaque !!! */
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+2), *(pScanline+1), *pScanline, iBGa8,
+ iCr8, iCg8, iCb8, iCa8)
+ /* and return the composed values */
+ *pScanline = iCb8;
+ *(pScanline+1) = iCg8;
+ *(pScanline+2) = iCr8;
+ *(pScanline+3) = iCa8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode display_bgra8_pm (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint32 s, t;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_START)
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ if ((s = pDataline[6]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = pDataline[4];
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ {
+ pScanline[0] = DIV255B8(s * pDataline[4]);
+ pScanline[1] = DIV255B8(s * pDataline[2]);
+ pScanline[2] = DIV255B8(s * pDataline[0]);
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* copy the values and premultiply */
+ if ((s = pDataline[3]) == 0)
+ *(mng_uint32*) pScanline = 0; /* set all components = 0 */
+ else
+ {
+ if (s == 255)
+ {
+ pScanline[0] = pDataline[2];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ {
+ pScanline[0] = DIV255B8(s * pDataline[2]);
+ pScanline[1] = DIV255B8(s * pDataline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0]);
+ pScanline[3] = (mng_uint8)s;
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* get alpha values */
+ if ((s = pDataline[6]) != 0) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if (s == 255)
+ { /* plain copy it */
+ pScanline[0] = pDataline[4];
+ pScanline[1] = pDataline[2];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = DIV255B8(s * pDataline[4] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[2] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ {
+ if ((s = pDataline[3]) != 0) /* any opacity at all ? */
+ { /* fully opaque ? */
+ if (s == 255)
+ { /* then simply copy the values */
+ pScanline[0] = pDataline[2];
+ pScanline[1] = pDataline[1];
+ pScanline[2] = pDataline[0];
+ pScanline[3] = 255;
+ }
+ else
+ { /* now blend (premultiplied) */
+ t = 255 - s;
+ pScanline[0] = DIV255B8(s * pDataline[2] + t * pScanline[0]);
+ pScanline[1] = DIV255B8(s * pDataline[1] + t * pScanline[1]);
+ pScanline[2] = DIV255B8(s * pDataline[0] + t * pScanline[2]);
+ pScanline[3] = (mng_uint8)(255 - DIV255B8(t * (255 - pScanline[3])));
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_BGRA8PM, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode display_abgr8 (mng_datap pData)
+{
+ mng_uint8p pScanline;
+ mng_uint8p pDataline;
+ mng_int32 iX;
+ mng_uint16 iFGa16, iBGa16, iCa16;
+ mng_uint8 iFGa8, iBGa8, iCa8;
+ mng_uint16 iFGr16, iFGg16, iFGb16;
+ mng_uint16 iBGr16, iBGg16, iBGb16;
+ mng_uint16 iCr16, iCg16, iCb16;
+ mng_uint8 iCr8, iCg8, iCb8;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_START)
+#endif
+ /* viewable row ? */
+ if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
+ { /* address destination row */
+ pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
+ pData->iRow + pData->iDestt -
+ pData->iSourcet);
+ /* adjust destination row starting-point */
+ pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
+ pDataline = pData->pRGBArow; /* address source row */
+
+ if (pData->bIsRGBA16) /* adjust source row starting-point */
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
+ else
+ pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
+
+ if (pData->bIsOpaque) /* forget about transparency ? */
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* scale down by dropping the LSB */
+ *pScanline = *(pDataline+6);
+ *(pScanline+1) = *(pDataline+4);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *pDataline;
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *pDataline;
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ else
+ {
+ if (pData->bIsRGBA16) /* 16-bit input row ? */
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ { /* get alpha values */
+ iFGa16 = mng_get_uint16 (pDataline+6);
+ iBGa16 = (mng_uint16)(*pScanline);
+ iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
+
+ if (iFGa16) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
+ { /* plain copy it */
+ *pScanline = *(pDataline+6);
+ *(pScanline+1) = *(pDataline+4);
+ *(pScanline+2) = *(pDataline+2);
+ *(pScanline+3) = *pDataline;
+ }
+ else
+ {
+ if (iBGa16 == 0xFFFF) /* background fully opaque ? */
+ { /* get the proper values */
+ iFGr16 = mng_get_uint16 (pDataline );
+ iFGg16 = mng_get_uint16 (pDataline+2);
+ iFGb16 = mng_get_uint16 (pDataline+4);
+ /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+3));
+ iBGg16 = (mng_uint16)(*(pScanline+2));
+ iBGb16 = (mng_uint16)(*(pScanline+1));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* now compose */
+ MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16)
+ MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16)
+ MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16)
+ /* and return the composed values */
+ /* alpha itself remains fully opaque !!! */
+ *(pScanline+1) = (mng_uint8)(iFGb16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iFGg16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iFGr16 >> 8);
+ }
+ else
+ { /* scale background up */
+ iBGr16 = (mng_uint16)(*(pScanline+3));
+ iBGg16 = (mng_uint16)(*(pScanline+2));
+ iBGb16 = (mng_uint16)(*(pScanline+1));
+ iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
+ iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
+ iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
+ /* let's blend */
+ MNG_BLEND16 (mng_get_uint16 (pDataline ),
+ mng_get_uint16 (pDataline+2),
+ mng_get_uint16 (pDataline+4), iFGa16,
+ iBGr16, iBGg16, iBGb16, iBGa16,
+ iCr16, iCg16, iCb16, iCa16)
+ /* and return the composed values */
+ *pScanline = (mng_uint8)(iCa16 >> 8);
+ *(pScanline+1) = (mng_uint8)(iCb16 >> 8);
+ *(pScanline+2) = (mng_uint8)(iCg16 >> 8);
+ *(pScanline+3) = (mng_uint8)(iCr16 >> 8);
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 8;
+ }
+ }
+ else
+ {
+ for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer; iX += pData->iColinc)
+ {
+ iFGa8 = *(pDataline+3); /* get alpha values */
+ iBGa8 = *pScanline;
+
+ if (iFGa8) /* any opacity at all ? */
+ { /* fully opaque or background fully transtqparent ? */
+ if ((iFGa8 == 0xFF) || (iBGa8 == 0))
+ { /* then simply copy the values */
+ *pScanline = *(pDataline+3);
+ *(pScanline+1) = *(pDataline+2);
+ *(pScanline+2) = *(pDataline+1);
+ *(pScanline+3) = *pDataline;
+ }
+ else
+ {
+ if (iBGa8 == 0xFF) /* background fully opaque ? */
+ { /* do simple alpha composing */
+ /* alpha itself remains fully opaque !!! */
+ MNG_COMPOSE8 (*(pScanline+1), *(pDataline+2), iFGa8, *(pScanline+1))
+ MNG_COMPOSE8 (*(pScanline+2), *(pDataline+1), iFGa8, *(pScanline+2))
+ MNG_COMPOSE8 (*(pScanline+3), *pDataline, iFGa8, *(pScanline+3))
+ }
+ else
+ { /* now blend */
+ MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
+ *(pScanline+3), *(pScanline+2), *(pScanline+1), iBGa8,
+ iCr8, iCg8, iCb8, iCa8)
+ /* and return the composed values */
+ *pScanline = iCa8;
+ *(pScanline+1) = iCb8;
+ *(pScanline+2) = iCg8;
+ *(pScanline+3) = iCr8;
+ }
+ }
+ }
+
+ pScanline += (pData->iColinc << 2);
+ pDataline += 4;
+ }
+ }
+ }
+ }
+
+ check_update_region (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_ABGR8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Background restore routines - restore the background with info from * */
+/* * the BACK and/or bKGD chunk or the app's background canvas * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode restore_bkgd_backimage (mng_datap pData)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BACKIMAGE, MNG_LC_START)
+#endif
+ /* make it easy on yourself */
+ iRetcode = restore_bkgd_backcolor (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+
+ /* TODO: loading the background-image */
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BACKIMAGE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode restore_bkgd_backcolor (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pWork = pData->pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BACKCOLOR, MNG_LC_START)
+#endif
+
+ for (iX = pData->iSourcel; iX < pData->iSourcer; iX++)
+ { /* ok; drop the background-color in there */
+ *pWork = (mng_uint8)(pData->iBACKred >> 8);
+ *(pWork+1) = (mng_uint8)(pData->iBACKgreen >> 8);
+ *(pWork+2) = (mng_uint8)(pData->iBACKblue >> 8);
+ *(pWork+3) = 0xFF; /* opaque! it's mandatory */
+
+ pWork += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BACKCOLOR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode restore_bkgd_bkgd (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pWork = pData->pRGBArow;
+ mng_imagep pImage;
+ mng_imagedatap pBuf;
+ mng_uint8 iRed = 0;
+ mng_uint8 iGreen = 0;
+ mng_uint8 iBlue = 0;
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BKGD, MNG_LC_START)
+#endif
+ /* determine the correct image buffer */
+ pImage = (mng_imagep)pData->pCurrentobj;
+
+ if (!pImage)
+ pImage = (mng_imagep)pData->pObjzero;
+
+ pBuf = pImage->pImgbuf;
+
+ switch (pBuf->iColortype)
+ {
+ case 0 : ; /* gray types */
+ case 4 : {
+ mng_uint8 iGray;
+
+ if (pBuf->iBitdepth > 8)
+ iGray = (mng_uint8)(pBuf->iBKGDgray >> 8);
+ else
+ {
+ iGray = (mng_uint8)pBuf->iBKGDgray;
+ /* please note how tricky the next code is !! */
+ switch (pBuf->iBitdepth)
+ {
+ case 1 : iGray = (mng_uint8)((iGray << 1) + iGray);
+ case 2 : iGray = (mng_uint8)((iGray << 2) + iGray);
+ case 4 : iGray = (mng_uint8)((iGray << 4) + iGray);
+ }
+ }
+
+ iRed = iGray;
+ iGreen = iGray;
+ iBlue = iGray;
+
+ break;
+ }
+
+ case 3 : { /* indexed type */
+ iRed = pBuf->aPLTEentries [pBuf->iBKGDindex].iRed;
+ iGreen = pBuf->aPLTEentries [pBuf->iBKGDindex].iGreen;
+ iBlue = pBuf->aPLTEentries [pBuf->iBKGDindex].iBlue;
+
+ break;
+ }
+
+ case 2 : ; /* rgb types */
+ case 6 : {
+ if (pBuf->iBitdepth > 8)
+ {
+ iRed = (mng_uint8)(pBuf->iBKGDred >> 8);
+ iGreen = (mng_uint8)(pBuf->iBKGDgreen >> 8);
+ iBlue = (mng_uint8)(pBuf->iBKGDblue >> 8);
+ }
+ else
+ {
+ iRed = (mng_uint8)(pBuf->iBKGDred );
+ iGreen = (mng_uint8)(pBuf->iBKGDgreen);
+ iBlue = (mng_uint8)(pBuf->iBKGDblue );
+ }
+
+ break;
+ }
+ }
+
+ for (iX = pData->iSourcel; iX < pData->iSourcer; iX++)
+ {
+ *pWork = iRed;
+ *(pWork+1) = iGreen;
+ *(pWork+2) = iBlue;
+ *(pWork+3) = 0x00; /* transparant for alpha-canvasses */
+
+ pWork += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BKGD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode restore_bkgd_bgcolor (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pWork = pData->pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGCOLOR, MNG_LC_START)
+#endif
+
+ for (iX = pData->iSourcel; iX < pData->iSourcer; iX++)
+ { /* ok; drop the background-color in there */
+ *pWork = (mng_uint8)(pData->iBGred >> 8);
+ *(pWork+1) = (mng_uint8)(pData->iBGgreen >> 8);
+ *(pWork+2) = (mng_uint8)(pData->iBGblue >> 8);
+ *(pWork+3) = 0x00; /* transparant for alpha-canvasses */
+
+ pWork += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGCOLOR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode restore_bkgd_rgb8 (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pBkgd;
+ mng_uint8p pWork = pData->pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_RGB8, MNG_LC_START)
+#endif
+
+ if (pData->fGetbkgdline) /* can we access the background ? */
+ { /* point to the right pixel then */
+ pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
+ pData->iRow + pData->iDestt) +
+ (3 * pData->iDestl);
+
+ for (iX = pData->iSourcel; iX < pData->iSourcer; iX++)
+ {
+ *pWork = *pBkgd; /* ok; copy the pixel */
+ *(pWork+1) = *(pBkgd+1);
+ *(pWork+2) = *(pBkgd+2);
+ *(pWork+3) = 0x00; /* transparant for alpha-canvasses */
+
+ pWork += 4;
+ pBkgd += 3;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_RGB8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode restore_bkgd_bgr8 (mng_datap pData)
+{
+ mng_int32 iX;
+ mng_uint8p pBkgd;
+ mng_uint8p pWork = pData->pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGR8, MNG_LC_START)
+#endif
+
+ if (pData->fGetbkgdline) /* can we access the background ? */
+ { /* point to the right pixel then */
+ pBkgd = (mng_uint8p)pData->fGetbkgdline ((mng_handle)pData,
+ pData->iRow + pData->iDestt) +
+ (3 * pData->iDestl);
+
+ for (iX = pData->iSourcel; iX < pData->iSourcer; iX++)
+ {
+ *pWork = *(pBkgd+2); /* ok; copy the pixel */
+ *(pWork+1) = *(pBkgd+1);
+ *(pWork+2) = *pBkgd;
+ *(pWork+3) = 0x00; /* transparant for alpha-canvasses */
+
+ pWork += 4;
+ pBkgd += 3;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RESTORE_BGR8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Row retrieval routines - retrieve processed & uncompressed row-data * */
+/* * from the current "object" * */
+/* * * */
+/* ************************************************************************** */
+
+/* TODO: a serious optimization is to retrieve only those pixels that will
+ actually be displayed; this would require changes in
+ the "display_image" routine (in mng_display.c) &
+ all the "retrieve_xxx" routines below &
+ the "display_xxx" routines above !!!!!
+ NOTE that "correct_xxx" routines would not require modification */
+
+mng_retcode retrieve_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_G8, MNG_LC_START)
+#endif
+
+ pRGBArow = pData->pRGBArow; /* temporary work pointers */
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ if (pBuf->bHasTRNS) /* tRNS in buffer ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iG = *pWorkrow; /* get the gray-value */
+ /* is it transtqparent ? */
+ if ((mng_uint16)iG == pBuf->iTRNSgray)
+ {
+ *pRGBArow = 0x00; /* nuttin to display */
+ *(pRGBArow+1) = 0x00;
+ *(pRGBArow+2) = 0x00;
+ *(pRGBArow+3) = 0x00;
+ }
+ else
+ {
+ switch (pBuf->iBitdepth) /* LBR to 8-bits ! */
+ {
+ case 1 : iG = (mng_uint8)((iG << 1) + iG);
+ case 2 : iG = (mng_uint8)((iG << 2) + iG);
+ case 4 : iG = (mng_uint8)((iG << 4) + iG);
+ }
+
+ *pRGBArow = iG; /* put in intermediate row */
+ *(pRGBArow+1) = iG;
+ *(pRGBArow+2) = iG;
+ *(pRGBArow+3) = 0xFF;
+ }
+
+ pWorkrow++; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iG = *pWorkrow; /* get the gray-value */
+
+ switch (pBuf->iBitdepth) /* LBR to 8-bits ! */
+ {
+ case 1 : iG = (mng_uint8)((iG << 1) + iG);
+ case 2 : iG = (mng_uint8)((iG << 2) + iG);
+ case 4 : iG = (mng_uint8)((iG << 4) + iG);
+ }
+
+ *pRGBArow = iG; /* put in intermediate row */
+ *(pRGBArow+1) = iG;
+ *(pRGBArow+2) = iG;
+ *(pRGBArow+3) = 0xFF;
+
+ pWorkrow++; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_G8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode retrieve_g16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_G16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pRGBArow = pData->pRGBArow;
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ if (pBuf->bHasTRNS) /* tRNS in buffer ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iG = mng_get_uint16 (pWorkrow); /* get the gray-value */
+ /* is it transtqparent ? */
+ if (iG == pBuf->iTRNSgray)
+ { /* nuttin to display */
+ mng_put_uint16 (pRGBArow, 0x0000);
+ mng_put_uint16 (pRGBArow+2, 0x0000);
+ mng_put_uint16 (pRGBArow+4, 0x0000);
+ mng_put_uint16 (pRGBArow+6, 0x0000);
+ }
+ else
+ { /* put in intermediate row */
+ mng_put_uint16 (pRGBArow, iG);
+ mng_put_uint16 (pRGBArow+2, iG);
+ mng_put_uint16 (pRGBArow+4, iG);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+ }
+
+ pWorkrow += 2; /* next pixel */
+ pRGBArow += 8;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iG = mng_get_uint16 (pWorkrow); /* get the gray-value */
+
+ mng_put_uint16 (pRGBArow, iG); /* and put in intermediate row */
+ mng_put_uint16 (pRGBArow+2, iG);
+ mng_put_uint16 (pRGBArow+4, iG);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+
+ pWorkrow += 2; /* next pixel */
+ pRGBArow += 8;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_G16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode retrieve_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iR, iG, iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB8, MNG_LC_START)
+#endif
+
+ pRGBArow = pData->pRGBArow; /* temporary work pointers */
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ if (pBuf->bHasTRNS) /* tRNS in buffer ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iR = *pWorkrow; /* get the rgb-values */
+ iG = *(pWorkrow+1);
+ iB = *(pWorkrow+2);
+ /* is it transtqparent ? */
+ if (((mng_uint16)iR == pBuf->iTRNSred ) &&
+ ((mng_uint16)iG == pBuf->iTRNSgreen) &&
+ ((mng_uint16)iB == pBuf->iTRNSblue ) )
+ {
+ *pRGBArow = 0x00; /* nothing to display */
+ *(pRGBArow+1) = 0x00;
+ *(pRGBArow+2) = 0x00;
+ *(pRGBArow+3) = 0x00;
+ }
+ else
+ {
+ *pRGBArow = iR; /* put in intermediate row */
+ *(pRGBArow+1) = iG;
+ *(pRGBArow+2) = iB;
+ *(pRGBArow+3) = 0xFF;
+ }
+
+ pWorkrow += 3; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pRGBArow = *pWorkrow; /* just copy the pixel */
+ *(pRGBArow+1) = *(pWorkrow+1);
+ *(pRGBArow+2) = *(pWorkrow+2);
+ *(pRGBArow+3) = 0xFF;
+
+ pWorkrow += 3; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode retrieve_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iR, iG, iB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pRGBArow = pData->pRGBArow;
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ if (pBuf->bHasTRNS) /* tRNS in buffer ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iR = mng_get_uint16 (pWorkrow); /* get the rgb-values */
+ iG = mng_get_uint16 (pWorkrow+2);
+ iB = mng_get_uint16 (pWorkrow+4);
+ /* is it transtqparent ? */
+ if ((iR == pBuf->iTRNSred ) &&
+ (iG == pBuf->iTRNSgreen) &&
+ (iB == pBuf->iTRNSblue ) )
+ { /* nothing to display */
+ mng_put_uint16 (pRGBArow, 0x0000);
+ mng_put_uint16 (pRGBArow+2, 0x0000);
+ mng_put_uint16 (pRGBArow+4, 0x0000);
+ mng_put_uint16 (pRGBArow+6, 0x0000);
+ }
+ else
+ { /* put in intermediate row */
+ mng_put_uint16 (pRGBArow, iR);
+ mng_put_uint16 (pRGBArow+2, iG);
+ mng_put_uint16 (pRGBArow+4, iB);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+ }
+
+ pWorkrow += 6; /* next pixel */
+ pRGBArow += 8;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* just copy the pixel */
+ mng_put_uint16 (pRGBArow, mng_get_uint16 (pWorkrow ));
+ mng_put_uint16 (pRGBArow+2, mng_get_uint16 (pWorkrow+2));
+ mng_put_uint16 (pRGBArow+4, mng_get_uint16 (pWorkrow+4));
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+
+ pWorkrow += 6; /* next pixel */
+ pRGBArow += 8;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGB16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode retrieve_idx8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_IDX8, MNG_LC_START)
+#endif
+
+ pRGBArow = pData->pRGBArow; /* temporary work pointers */
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ if (pBuf->bHasTRNS) /* tRNS in buffer ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iQ = *pWorkrow; /* get the index */
+ /* is it valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ /* transparency for this index ? */
+ if ((mng_uint32)iQ < pBuf->iTRNScount)
+ *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
+ else
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR)
+
+ pWorkrow++; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iQ = *pWorkrow; /* get the index */
+ /* is it valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR)
+
+ pWorkrow++; /* next pixel */
+ pRGBArow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_IDX8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode retrieve_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_GA8, MNG_LC_START)
+#endif
+
+ pRGBArow = pData->pRGBArow; /* temporary work pointers */
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iG = *pWorkrow; /* get the gray-value */
+ *pRGBArow = iG; /* put in intermediate row */
+ *(pRGBArow+1) = iG;
+ *(pRGBArow+2) = iG;
+ *(pRGBArow+3) = *(pWorkrow+1);
+
+ pWorkrow += 2; /* next pixel */
+ pRGBArow += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_GA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode retrieve_ga16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iG;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_GA16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pRGBArow = pData->pRGBArow;
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iG = mng_get_uint16 (pWorkrow); /* get the gray-value */
+
+ mng_put_uint16 (pRGBArow, iG); /* and put in intermediate row */
+ mng_put_uint16 (pRGBArow+2, iG);
+ mng_put_uint16 (pRGBArow+4, iG);
+ mng_put_uint16 (pRGBArow+6, mng_get_uint16 (pWorkrow+2));
+
+ pWorkrow += 4; /* next pixel */
+ pRGBArow += 8;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_GA16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode retrieve_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA8, MNG_LC_START)
+#endif
+
+ pRGBArow = pData->pRGBArow; /* temporary work pointers */
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+ /* can't be easier than this ! */
+ MNG_COPY (pRGBArow, pWorkrow, pBuf->iRowsize)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode retrieve_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pRetrieveobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pRGBArow = pData->pRGBArow;
+ pWorkrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize);
+ /* can't be easier than this ! */
+ MNG_COPY (pRGBArow, pWorkrow, pBuf->iRowsize)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_RETRIEVE_RGBA16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Row storage routines - store processed & uncompressed row-data * */
+/* * into the current "object" * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode store_g1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G1, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it white ? */
+ *pOutrow = 0x01; /* white */
+ else
+ *pOutrow = 0x00; /* black */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_g2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G2, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+ iQ = (mng_uint8)((iB & iM) >> iS); /* get the gray level */
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_g4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G4, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+
+ iQ = (mng_uint8)((iB & iM) >> iS); /* get the gray level */
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_g16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* copy into object buffer */
+ mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
+
+ pOutrow += (pData->iColinc << 1); /* next pixel */
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_G16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGB8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* copy the RGB bytes */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+
+ pWorkrow += 3; /* next pixel */
+ pOutrow += (pData->iColinc * 3);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGB8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGB16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ MNG_COPY (pOutrow, pWorkrow, 6) /* copy the RGB bytes */
+
+ pWorkrow += 6; /* next pixel */
+ pOutrow += (pData->iColinc * 6);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGB16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_idx1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX1, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* store the index */
+ *pOutrow = 0x01;
+ else
+ *pOutrow = 0x00;
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_idx2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX2, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* store the index */
+ *pOutrow = (mng_uint8)((iB & iM) >> iS);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_idx4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX4, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* store the index */
+ *pOutrow = (mng_uint8)((iB & iM) >> iS);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_idx8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_IDX8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_GA8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* copy the GA bytes */
+ *(pOutrow+1) = *(pWorkrow+1);
+
+ pWorkrow += 2; /* next pixel */
+ pOutrow += (pData->iColinc << 1);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_GA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_ga16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_GA16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ MNG_COPY (pOutrow, pWorkrow, 4) /* copy the GA bytes */
+
+ pWorkrow += 4; /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_GA16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGBA8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* copy the RGBA bytes */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+ *(pOutrow+3) = *(pWorkrow+3);
+
+ pWorkrow += 4; /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGBA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGBA16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ MNG_COPY (pOutrow, pWorkrow, 8) /* copy the RGBA bytes */
+
+ pWorkrow += 8; /* next pixel */
+ pOutrow += (pData->iColinc << 3);
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_RGBA16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Row storage routines (JPEG) - store processed & uncompressed row-data * */
+/* * into the current "object" * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pJPEGrow; /* temporary work pointers */
+ pOutrow = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
+ /* easy as pie ... */
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8, MNG_LC_END)
+#endif
+
+ return next_jpeg_row (pData); /* we've got one more row of gray-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pJPEGrow; /* temporary work pointers */
+ pOutrow = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
+ /* easy as pie ... */
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples * 3)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8, MNG_LC_END)
+#endif
+
+ return next_jpeg_row (pData); /* we've got one more row of rgb-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_GA8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pJPEGrow; /* temporary work pointers */
+ pOutrow = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* copy into object buffer */
+
+ pOutrow += 2; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_GA8, MNG_LC_END)
+#endif
+
+ return next_jpeg_row (pData); /* we've got one more row of gray-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGBA8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pJPEGrow; /* temporary work pointers */
+ pOutrow = pBuf->pImgdata + (pData->iJPEGrow * pBuf->iRowsize);
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* copy pixel into object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow += 3;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGBA8, MNG_LC_END)
+#endif
+
+ return next_jpeg_row (pData); /* we've got one more row of rgb-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g8_alpha (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_ALPHA, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pJPEGrow2;
+ pOutrow = pBuf->pImgdata + (pData->iJPEGalpharow * pBuf->iRowsize) + 1;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += 2; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_ALPHA, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_rgb8_alpha (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_ALPHA, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pJPEGrow2;
+ pOutrow = pBuf->pImgdata + (pData->iJPEGalpharow * pBuf->iRowsize) + 3;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_ALPHA, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g8_a1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A1, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it opaque ? */
+ *pOutrow = 0xFF; /* opaque */
+ else
+ *pOutrow = 0x00; /* transtqparent */
+
+ pOutrow += 2; /* next pixel */
+ iM >>= 1;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A1, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g8_a2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A2, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+ switch ((iB & iM) >> iS) /* determine the alpha level */
+ {
+ case 0x03 : { *pOutrow = 0xFF; break; }
+ case 0x02 : { *pOutrow = 0xAA; break; }
+ case 0x01 : { *pOutrow = 0x55; break; }
+ default : { *pOutrow = 0x00; }
+ }
+
+ pOutrow += 2; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A2, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g8_a4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A4, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the alpha level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ iQ = (mng_uint8)(iQ + (iQ << 4)); /* expand to 8-bit by replication */
+
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += 2; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A4, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g8_a8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += 2; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A8, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g8_a16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* only high-order byte! */
+
+ pOutrow += 2; /* next pixel */
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G8_A16, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_rgb8_a1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A1, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it opaque ? */
+ *pOutrow = 0xFF; /* opaque */
+ else
+ *pOutrow = 0x00; /* transtqparent */
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 1;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A1, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_rgb8_a2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A2, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+ switch ((iB & iM) >> iS) /* determine the alpha level */
+ {
+ case 0x03 : { *pOutrow = 0xFF; break; }
+ case 0x02 : { *pOutrow = 0xAA; break; }
+ case 0x01 : { *pOutrow = 0x55; break; }
+ default : { *pOutrow = 0x00; }
+ }
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A2, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_rgb8_a4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A4, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the alpha level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ iQ = (mng_uint8)(iQ + (iQ << 4)); /* expand to 8-bit by replication */
+
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A4, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_rgb8_a8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in buffer */
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A8, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_rgb8_a16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* only high-order byte */
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_RGB8_A16, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g12_a1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A1, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 2;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* opaque ? */
+ mng_put_uint16 (pOutrow, 0xFFFF);/* opaque */
+ else
+ mng_put_uint16 (pOutrow, 0x0000);/* transtqparent */
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 1;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A1, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g12_a2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A2, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 2;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+ switch ((iB & iM) >> iS) /* determine the gray level */
+ {
+ case 0x03 : { mng_put_uint16 (pOutrow, 0xFFFF); break; }
+ case 0x02 : { mng_put_uint16 (pOutrow, 0xAAAA); break; }
+ case 0x01 : { mng_put_uint16 (pOutrow, 0x5555); break; }
+ default : { mng_put_uint16 (pOutrow, 0x0000); }
+ }
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A2, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g12_a4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint16 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A4, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 2;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the gray level */
+ iQ = (mng_uint16)((iB & iM) >> iS);
+ iQ = (mng_uint16)(iQ + (iQ << 4)); /* expand to 16-bit by replication */
+ iQ = (mng_uint16)(iQ + (iQ << 8));
+ /* put in object buffer */
+ mng_put_uint16 (pOutrow, iQ);
+
+ pOutrow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A4, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g12_a8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 2;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iW = (mng_uint16)(*pWorkrow); /* get input byte */
+ iW = (mng_uint16)(iW + (iW << 8)); /* expand to 16-bit by replication */
+
+ mng_put_uint16 (pOutrow, iW); /* put in object buffer */
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A8, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g12_a16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 2;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* copy it */
+ mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
+
+ pOutrow += 4; /* next pixel */
+ pWorkrow += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_STORE_JPEG_G12_A16, MNG_LC_END)
+#endif
+
+ return next_jpeg_alpharow (pData); /* we've got one more row of alpha-samples */
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image row routines - apply the processed & uncompressed row-data * */
+/* * onto the target "object" * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode delta_g1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G1, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it white ? */
+ *pOutrow = 0xFF; /* white */
+ else
+ *pOutrow = 0x00; /* black */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* invert if it is white ? */
+ *pOutrow = (mng_uint8)(*pOutrow ^ 0xFF);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G1, MNG_LC_END)
+#endif
+
+ return store_g1 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_g2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G2, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+ switch ((iB & iM) >> iS) /* determine the gray level */
+ {
+ case 0x03 : { *pOutrow = 0xFF; break; }
+ case 0x02 : { *pOutrow = 0xAA; break; }
+ case 0x01 : { *pOutrow = 0x55; break; }
+ default : { *pOutrow = 0x00; }
+ }
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* determine the gray level */
+ switch (((*pOutrow >> 6) + ((iB & iM) >> iS)) & 0x03)
+ {
+ case 0x03 : { *pOutrow = 0xFF; break; }
+ case 0x02 : { *pOutrow = 0xAA; break; }
+ case 0x01 : { *pOutrow = 0x55; break; }
+ default : { *pOutrow = 0x00; }
+ }
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G2, MNG_LC_END)
+#endif
+
+ return store_g2 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_g4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G4, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the gray level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* expand to 8-bit by replication */
+ iQ = (mng_uint8)(iQ + (iQ << 4));
+
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the gray level */
+ iQ = (mng_uint8)(((*pOutrow >> 4) + ((iB & iM) >> iS)) & 0x0F);
+ /* expand to 8-bit by replication */
+ iQ = (mng_uint8)(iQ + (iQ << 4));
+
+ *pOutrow = iQ; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G4, MNG_LC_END)
+#endif
+
+ return store_g4 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* add to object buffer */
+ *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G8, MNG_LC_END)
+#endif
+
+ return store_g8 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_g16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ /* next pixel */
+ pOutrow += (pData->iColinc << 1);
+ pWorkrow += 2;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* add to object buffer */
+ mng_put_uint16 (pOutrow, (mng_uint16)(mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow) ));
+ /* next pixel */
+ pOutrow += (pData->iColinc << 1);
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G16, MNG_LC_END)
+#endif
+
+ return store_g16 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+ /* next pixel */
+ pOutrow += (pData->iColinc * 3);
+ pWorkrow += 3;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* add to object buffer */
+ *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow );
+ *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
+ *(pOutrow+2) = (mng_uint8)(*(pOutrow+2) + *(pWorkrow+2));
+ /* next pixel */
+ pOutrow += (pData->iColinc * 3);
+ pWorkrow += 3;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB8, MNG_LC_END)
+#endif
+
+ return store_rgb8 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+ *(pOutrow+3) = *(pWorkrow+3);
+ *(pOutrow+4) = *(pWorkrow+4);
+ *(pOutrow+5) = *(pWorkrow+5);
+ /* next pixel */
+ pOutrow += (pData->iColinc * 6);
+ pWorkrow += 6;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* add to object buffer */
+ mng_put_uint16 (pOutrow, (mng_uint16)(mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow ) ));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
+ mng_get_uint16 (pWorkrow+2) ));
+ mng_put_uint16 (pOutrow+4, (mng_uint16)(mng_get_uint16 (pOutrow+4 ) +
+ mng_get_uint16 (pWorkrow+4) ));
+ /* next pixel */
+ pOutrow += (pData->iColinc * 6);
+ pWorkrow += 6;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB16, MNG_LC_END)
+#endif
+
+ return store_rgb16 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_idx1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX1, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* put the right index value */
+ *pOutrow = 1;
+ else
+ *pOutrow = 0;
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* invert if it is non-zero index */
+ *pOutrow = (mng_uint8)(*pOutrow ^ 0x01);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 1;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX1, MNG_LC_END)
+#endif
+
+ return store_idx1 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_idx2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX2, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* put the index */
+ *pOutrow = (mng_uint8)((iB & iM) >> iS);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* calculate the index */
+ *pOutrow = (mng_uint8)((*pOutrow + ((iB & iM) >> iS)) & 0x03);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX2, MNG_LC_END)
+#endif
+
+ return store_idx2 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_idx4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX4, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* put the index */
+ *pOutrow = (mng_uint8)((iB & iM) >> iS);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* calculate the index */
+ *pOutrow = (mng_uint8)((*pOutrow + ((iB & iM) >> iS)) & 0x0F);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX4, MNG_LC_END)
+#endif
+
+ return store_idx4 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_idx8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* add to object buffer */
+ *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow);
+
+ pOutrow += pData->iColinc; /* next pixel */
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_IDX8, MNG_LC_END)
+#endif
+
+ return store_idx8 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ /* next pixel */
+ pOutrow += (pData->iColinc << 1);
+ pWorkrow += 2;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* add to object buffer */
+ *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow );
+ *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
+ /* next pixel */
+ pOutrow += (pData->iColinc << 1);
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8, MNG_LC_END)
+#endif
+
+ return store_ga8 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_ga16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+ *(pOutrow+3) = *(pWorkrow+3);
+ /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ pWorkrow += 4;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* add to object buffer */
+ mng_put_uint16 (pOutrow, (mng_uint16)(mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow ) ));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
+ mng_get_uint16 (pWorkrow+2) ));
+ /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ pWorkrow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16, MNG_LC_END)
+#endif
+
+ return store_ga16 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow; /* put in object buffer */
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+ *(pOutrow+3) = *(pWorkrow+3);
+ /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ pWorkrow += 4;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* add to object buffer */
+ *pOutrow = (mng_uint8)(*pOutrow + *pWorkrow );
+ *(pOutrow+1) = (mng_uint8)(*(pOutrow+1) + *(pWorkrow+1));
+ *(pOutrow+2) = (mng_uint8)(*(pOutrow+2) + *(pWorkrow+2));
+ *(pOutrow+3) = (mng_uint8)(*(pOutrow+3) + *(pWorkrow+3));
+ /* next pixel */
+ pOutrow += (pData->iColinc << 2);
+ pWorkrow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8, MNG_LC_END)
+#endif
+
+ return store_rgba8 (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pDeltaImage)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iDeltaBlocky * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) +
+ (pData->iDeltaBlockx * pBuf->iSamplesize);
+ /* pixel tqreplace ? */
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ MNG_COPY (pOutrow, pWorkrow, 8) /* put in object buffer */
+ /* next pixel */
+ pOutrow += (pData->iColinc << 3);
+ pWorkrow += 8;
+ }
+ }
+ else
+ { /* pixel add ! */
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* add to object buffer */
+ mng_put_uint16 (pOutrow, (mng_uint16)(mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow ) ));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)(mng_get_uint16 (pOutrow+2 ) +
+ mng_get_uint16 (pWorkrow+2) ));
+ mng_put_uint16 (pOutrow+4, (mng_uint16)(mng_get_uint16 (pOutrow+4 ) +
+ mng_get_uint16 (pWorkrow+4) ));
+ mng_put_uint16 (pOutrow+6, (mng_uint16)(mng_get_uint16 (pOutrow+6 ) +
+ mng_get_uint16 (pWorkrow+6) ));
+ /* next pixel */
+ pOutrow += (pData->iColinc << 3);
+ pWorkrow += 8;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16, MNG_LC_END)
+#endif
+
+ return store_rgba16 (pData);
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image row routines - apply the source row onto the target * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode delta_g1_g1 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G1_G1, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples)
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0x01);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G1_G1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_g2_g2 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G2_G2, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples)
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0x03);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G2_G2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_g4_g4 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G4_G4, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples)
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0x0F);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G4_G4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_g8_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G8_G8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples)
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G8_G8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_g16_g16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G16_G16, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 1))
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow) +
+ mng_get_uint16 (pWorkrow)) & 0xFFFF));
+
+ pOutrow += 2;
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_G16_G16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgb8_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB8_RGB8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples * 3)
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < (pData->iRowsamples * 3); iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB8_RGB8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgb16_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB16_RGB16, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples * 6))
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow )) & 0xFFFF));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
+ mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
+ mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
+ mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
+
+ pOutrow += 6;
+ pWorkrow += 6;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGB16_RGB16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_ga8_ga8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_GA8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples << 1)
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < (pData->iRowsamples << 1); iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_GA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_ga8_g8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_G8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow;
+
+ pOutrow += 2;
+ pWorkrow++;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow += 2;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_G8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_ga8_a8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_A8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 1;
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow;
+
+ pOutrow += 2;
+ pWorkrow++;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow += 2;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA8_A8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_ga16_ga16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_GA16, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 2))
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow )) & 0xFFFF));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
+ mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
+
+ pOutrow += 4;
+ pWorkrow += 4;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_GA16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_ga16_g16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_A16, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow));
+
+ pOutrow += 4;
+ pWorkrow += 2;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow) +
+ mng_get_uint16 (pWorkrow)) & 0xFFFF));
+
+ pOutrow += 4;
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_A16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_ga16_a16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_G16, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow+2, mng_get_uint16 (pWorkrow));
+
+ pOutrow += 4;
+ pWorkrow += 2;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
+ mng_get_uint16 (pWorkrow)) & 0xFFFF));
+
+ pOutrow += 4;
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_GA16_G16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgba8_rgba8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGBA8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, pData->iRowsamples << 2)
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < (pData->iRowsamples << 2); iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow++;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGBA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgba8_rgb8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGB8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow;
+ *(pOutrow+1) = *(pWorkrow+1);
+ *(pOutrow+2) = *(pWorkrow+2);
+
+ pOutrow += 4;
+ pWorkrow += 3;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow ) & 0xFF);
+ *(pOutrow+1) = (mng_uint8)(((mng_uint16)*(pOutrow+1) +
+ (mng_uint16)*(pWorkrow+1)) & 0xFF);
+ *(pOutrow+2) = (mng_uint8)(((mng_uint16)*(pOutrow+2) +
+ (mng_uint16)*(pWorkrow+2)) & 0xFF);
+
+ pOutrow += 4;
+ pWorkrow += 3;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_RGB8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgba8_a8 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_A8, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize) + 3;
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = *pWorkrow;
+
+ pOutrow += 4;
+ pWorkrow++;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pOutrow = (mng_uint8)(((mng_uint16)*pOutrow +
+ (mng_uint16)*pWorkrow) & 0xFF);
+
+ pOutrow += 4;
+ pWorkrow++;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA8_A8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgba16_rgba16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGBA16, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ MNG_COPY (pOutrow, pWorkrow, (pData->iRowsamples << 3))
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow )) & 0xFFFF));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
+ mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
+ mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
+ mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
+ mng_put_uint16 (pOutrow+6, (mng_uint16)((mng_get_uint16 (pOutrow+6) +
+ mng_get_uint16 (pWorkrow+6)) & 0xFFFF));
+
+ pOutrow += 8;
+ pWorkrow += 8;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGBA16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgba16_rgb16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGB16, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow, mng_get_uint16 (pWorkrow ));
+ mng_put_uint16 (pOutrow+2, mng_get_uint16 (pWorkrow+2));
+ mng_put_uint16 (pOutrow+4, mng_get_uint16 (pWorkrow+4));
+
+ pOutrow += 8;
+ pWorkrow += 6;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow, (mng_uint16)((mng_get_uint16 (pOutrow ) +
+ mng_get_uint16 (pWorkrow )) & 0xFFFF));
+ mng_put_uint16 (pOutrow+2, (mng_uint16)((mng_get_uint16 (pOutrow+2) +
+ mng_get_uint16 (pWorkrow+2)) & 0xFFFF));
+ mng_put_uint16 (pOutrow+4, (mng_uint16)((mng_get_uint16 (pOutrow+4) +
+ mng_get_uint16 (pWorkrow+4)) & 0xFFFF));
+
+ pOutrow += 8;
+ pWorkrow += 6;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_RGB16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode delta_rgba16_a16 (mng_datap pData)
+{
+ mng_imagedatap pBuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ mng_uint8p pWorkrow;
+ mng_uint8p pOutrow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_A16, MNG_LC_START)
+#endif
+
+ pWorkrow = pData->pRGBArow;
+ pOutrow = pBuf->pImgdata + (pData->iRow * pBuf->iRowsize ) +
+ (pData->iCol * pBuf->iSamplesize);
+
+ if ((pData->iDeltatype == MNG_DELTATYPE_REPLACE ) ||
+ (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELREPLACE) )
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow+6, mng_get_uint16 (pWorkrow));
+
+ pOutrow += 8;
+ pWorkrow += 2;
+ }
+ }
+ else
+ if (pData->iDeltatype == MNG_DELTATYPE_BLOCKPIXELADD)
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ mng_put_uint16 (pOutrow+6, (mng_uint16)((mng_get_uint16 (pOutrow+6) +
+ mng_get_uint16 (pWorkrow)) & 0xFFFF));
+
+ pOutrow += 8;
+ pWorkrow += 2;
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DELTA_RGBA16_A16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image row routines - scale the source to bitdepth of target * */
+/* * * */
+/* ************************************************************************** */
+
+
+
+/* ************************************************************************** */
+/* * * */
+/* * Row processing routines - convert uncompressed data from zlib to * */
+/* * managable row-data which serves as input to the color-management * */
+/* * routines * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode process_g1 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G1, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ if (pBuf->iTRNSgray) /* white transtqparent ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it white ? */
+ /* transtqparent ! */
+ mng_put_uint32 (pRGBArow, 0x00000000);
+ else /* opaque black */
+ mng_put_uint32 (pRGBArow, 0x000000FF);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 1;
+ }
+ }
+ else /* black transtqparent */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it white ? */
+ /* opaque white */
+ mng_put_uint32 (pRGBArow, 0xFFFFFFFF);
+ else /* transtqparent */
+ mng_put_uint32 (pRGBArow, 0x00000000);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 1;
+ }
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else /* no transparency */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ }
+
+ if (iB & iM) /* is it white ? */
+ /* opaque white */
+ mng_put_uint32 (pRGBArow, 0xFFFFFFFF);
+ else /* opaque black */
+ mng_put_uint32 (pRGBArow, 0x000000FF);
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 1;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_g2 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G2, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* determine gray level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+
+ if (iQ == pBuf->iTRNSgray) /* transtqparent ? */
+ mng_put_uint32 (pRGBArow, 0x00000000);
+ else
+ {
+ switch (iQ) /* determine the gray level */
+ {
+ case 0x03 : { mng_put_uint32 (pRGBArow, 0xFFFFFFFF); break; }
+ case 0x02 : { mng_put_uint32 (pRGBArow, 0xAAAAAAFF); break; }
+ case 0x01 : { mng_put_uint32 (pRGBArow, 0x555555FF); break; }
+ default : { mng_put_uint32 (pRGBArow, 0x000000FF); }
+ }
+ }
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+
+ switch ((iB & iM) >> iS) /* determine the gray level */
+ {
+ case 0x03 : { mng_put_uint32 (pRGBArow, 0xFFFFFFFF); break; }
+ case 0x02 : { mng_put_uint32 (pRGBArow, 0xAAAAAAFF); break; }
+ case 0x01 : { mng_put_uint32 (pRGBArow, 0x555555FF); break; }
+ default : { mng_put_uint32 (pRGBArow, 0x000000FF); }
+ }
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_g4 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G4, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the gray level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+
+ if (iQ == pBuf->iTRNSgray) /* transtqparent ? */
+ {
+ *pRGBArow = 0; /* put in intermediate row */
+ *(pRGBArow+1) = 0;
+ *(pRGBArow+2) = 0;
+ *(pRGBArow+3) = 0;
+ }
+ else
+ { /* expand to 8-bit by replication */
+ iQ = (mng_uint8)(iQ + (iQ << 4));
+
+ *pRGBArow = iQ; /* put in intermediate row */
+ *(pRGBArow+1) = iQ;
+ *(pRGBArow+2) = iQ;
+ *(pRGBArow+3) = 0xFF;
+ }
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the gray level */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ iQ = (mng_uint8)(iQ + (iQ << 4));/* expand to 8-bit by replication */
+
+ *pRGBArow = iQ; /* put in intermediate row */
+ *(pRGBArow+1) = iQ;
+ *(pRGBArow+2) = iQ;
+ *(pRGBArow+3) = 0xFF;
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_g8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G8, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iB = *pWorkrow; /* get next input-byte */
+
+ if (iB == pBuf->iTRNSgray) /* transtqparent ? */
+ {
+ *pRGBArow = 0; /* put in intermediate row */
+ *(pRGBArow+1) = 0;
+ *(pRGBArow+2) = 0;
+ *(pRGBArow+3) = 0;
+ }
+ else
+ {
+ *pRGBArow = iB; /* put in intermediate row */
+ *(pRGBArow+1) = iB;
+ *(pRGBArow+2) = iB;
+ *(pRGBArow+3) = 0xFF;
+ }
+
+ pRGBArow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iB = *pWorkrow; /* get next input-byte */
+
+ *pRGBArow = iB; /* put in intermediate row */
+ *(pRGBArow+1) = iB;
+ *(pRGBArow+2) = iB;
+ *(pRGBArow+3) = 0xFF;
+
+ pRGBArow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_g16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iW;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G16, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iW = mng_get_uint16 (pWorkrow); /* get input */
+
+ if (iW == pBuf->iTRNSgray) /* transtqparent ? */
+ { /* put in intermediate row */
+ mng_put_uint16 (pRGBArow, 0);
+ mng_put_uint16 (pRGBArow+2, 0);
+ mng_put_uint16 (pRGBArow+4, 0);
+ mng_put_uint16 (pRGBArow+6, 0);
+ }
+ else
+ { /* put in intermediate row */
+ mng_put_uint16 (pRGBArow, iW);
+ mng_put_uint16 (pRGBArow+2, iW);
+ mng_put_uint16 (pRGBArow+4, iW);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+ }
+
+ pRGBArow += 8; /* next pixel */
+ pWorkrow += 2;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iW = mng_get_uint16 (pWorkrow); /* get input */
+
+ mng_put_uint16 (pRGBArow, iW); /* and put in intermediate row */
+ mng_put_uint16 (pRGBArow+2, iW);
+ mng_put_uint16 (pRGBArow+4, iW);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+
+ pRGBArow += 8; /* next pixel */
+ pWorkrow += 2;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_G16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_rgb8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iR, iG, iB;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGB8, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iR = *pWorkrow; /* get the RGB values */
+ iG = *(pWorkrow+1);
+ iB = *(pWorkrow+2);
+ /* transtqparent ? */
+ if ((iR == pBuf->iTRNSred) && (iG == pBuf->iTRNSgreen) &&
+ (iB == pBuf->iTRNSblue))
+ {
+ *pRGBArow = 0; /* this pixel is transtqparent ! */
+ *(pRGBArow+1) = 0;
+ *(pRGBArow+2) = 0;
+ *(pRGBArow+3) = 0;
+ }
+ else
+ {
+ *pRGBArow = iR; /* copy the RGB values */
+ *(pRGBArow+1) = iG;
+ *(pRGBArow+2) = iB;
+ *(pRGBArow+3) = 0xFF; /* this one isn't transtqparent */
+ }
+
+ pWorkrow += 3; /* next pixel */
+ pRGBArow += 4;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pRGBArow = *pWorkrow; /* copy the RGB bytes */
+ *(pRGBArow+1) = *(pWorkrow+1);
+ *(pRGBArow+2) = *(pWorkrow+2);
+ *(pRGBArow+3) = 0xFF; /* no alpha; so always fully opaque */
+
+ pWorkrow += 3; /* next pixel */
+ pRGBArow += 4;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGB8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_rgb16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iR, iG, iB;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGB16, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iR = mng_get_uint16 (pWorkrow); /* get the RGB values */
+ iG = mng_get_uint16 (pWorkrow+2);
+ iB = mng_get_uint16 (pWorkrow+4);
+ /* transtqparent ? */
+ if ((iR == pBuf->iTRNSred) && (iG == pBuf->iTRNSgreen) &&
+ (iB == pBuf->iTRNSblue))
+ { /* transtqparent then */
+ mng_put_uint16 (pRGBArow, 0);
+ mng_put_uint16 (pRGBArow+2, 0);
+ mng_put_uint16 (pRGBArow+4, 0);
+ mng_put_uint16 (pRGBArow+6, 0);
+ }
+ else
+ { /* put in intermediate row */
+ mng_put_uint16 (pRGBArow, iR);
+ mng_put_uint16 (pRGBArow+2, iG);
+ mng_put_uint16 (pRGBArow+4, iB);
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+ }
+
+ pWorkrow += 6; /* next pixel */
+ pRGBArow += 8;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ { /* copy the RGB values */
+ mng_put_uint16 (pRGBArow, mng_get_uint16 (pWorkrow ));
+ mng_put_uint16 (pRGBArow+2, mng_get_uint16 (pWorkrow+2));
+ mng_put_uint16 (pRGBArow+4, mng_get_uint16 (pWorkrow+4));
+ mng_put_uint16 (pRGBArow+6, 0xFFFF);
+
+ pWorkrow += 6; /* next pixel */
+ pRGBArow += 8;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGB16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_idx1 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX1, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ iS = 7;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ /* transparency for this index ? */
+ if ((mng_uint32)iQ < pBuf->iTRNScount)
+ *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
+ else
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR)
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 1;
+ iS -= 1;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0x80;
+ iS = 7;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR)
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 1;
+ iS -= 1;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_idx2 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX2, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ /* transparency for this index ? */
+ if ((mng_uint32)iQ < pBuf->iTRNScount)
+ *(pRGBArow+3) = pBuf->aTRNSentries [iQ];
+ else
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR)
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = *pWorkrow; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xC0;
+ iS = 6;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ *pRGBArow = pBuf->aPLTEentries [iQ].iRed;
+ *(pRGBArow+1) = pBuf->aPLTEentries [iQ].iGreen;
+ *(pRGBArow+2) = pBuf->aPLTEentries [iQ].iBlue;
+ *(pRGBArow+3) = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR)
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 2;
+ iS -= 2;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_idx4 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iB;
+ mng_uint8 iM;
+ mng_uint32 iS;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX4, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+ iM = 0; /* start at pixel 0 */
+ iB = 0;
+ iS = 0;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = pWorkrow [0]; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
+ pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
+ pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
+ /* transparency for this index ? */
+ if ((mng_uint32)iQ < pBuf->iTRNScount)
+ pRGBArow [3] = pBuf->aTRNSentries [iQ];
+ else
+ pRGBArow [3] = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR)
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ if (!iM) /* tqmask underflow ? */
+ {
+ iB = pWorkrow [0]; /* get next input-byte */
+ pWorkrow++;
+ iM = 0xF0;
+ iS = 4;
+ }
+ /* get the index */
+ iQ = (mng_uint8)((iB & iM) >> iS);
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
+ pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
+ pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
+ pRGBArow [3] = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR)
+
+ pRGBArow += 4; /* next pixel */
+ iM >>= 4;
+ iS -= 4;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_idx8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint8 iQ;
+ mng_imagedatap pBuf = (mng_imagedatap)pData->pStorebuf;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX8, MNG_LC_START)
+#endif
+
+ if (!pBuf) /* no object? then use obj 0 */
+ pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ if (pBuf->bHasTRNS) /* tRNS encountered ? */
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iQ = *pWorkrow; /* get input byte */
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
+ pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
+ pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
+ /* transparency for this index ? */
+ if ((mng_uint32)iQ < pBuf->iTRNScount)
+ pRGBArow [3] = pBuf->aTRNSentries [iQ];
+ else
+ pRGBArow [3] = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR)
+
+ pRGBArow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's not fully opaque */
+ }
+ else
+ {
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iQ = *pWorkrow; /* get input byte */
+ /* index valid ? */
+ if ((mng_uint32)iQ < pBuf->iPLTEcount)
+ { /* put in intermediate row */
+ pRGBArow [0] = pBuf->aPLTEentries [iQ].iRed;
+ pRGBArow [1] = pBuf->aPLTEentries [iQ].iGreen;
+ pRGBArow [2] = pBuf->aPLTEentries [iQ].iBlue;
+ pRGBArow [3] = 0xFF;
+ }
+ else
+ MNG_ERROR (pData, MNG_PLTEINDEXERROR)
+
+ pRGBArow += 4; /* next pixel */
+ pWorkrow++;
+ }
+
+ pData->bIsOpaque = MNG_TRUE; /* it's fully opaque */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_IDX8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ga8 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_GA8, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ *pRGBArow = *pWorkrow; /* copy the gray value */
+ *(pRGBArow+1) = *pWorkrow;
+ *(pRGBArow+2) = *pWorkrow;
+ *(pRGBArow+3) = *(pWorkrow+1); /* copy the alpha value */
+
+ pWorkrow += 2; /* next pixel */
+ pRGBArow += 4;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's definitely not fully opaque */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_GA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_ga16 (mng_datap pData)
+{
+ mng_uint8p pWorkrow;
+ mng_uint8p pRGBArow;
+ mng_int32 iX;
+ mng_uint16 iW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_GA16, MNG_LC_START)
+#endif
+ /* temporary work pointers */
+ pWorkrow = pData->pWorkrow + pData->iPixelofs;
+ pRGBArow = pData->pRGBArow;
+
+ for (iX = 0; iX < pData->iRowsamples; iX++)
+ {
+ iW = mng_get_uint16 (pWorkrow); /* copy the gray value */
+ mng_put_uint16 (pRGBArow, iW);
+ mng_put_uint16 (pRGBArow+2, iW);
+ mng_put_uint16 (pRGBArow+4, iW);
+ /* copy the alpha value */
+ mng_put_uint16 (pRGBArow+6, mng_get_uint16 (pWorkrow+2));
+
+ pWorkrow += 4; /* next pixel */
+ pRGBArow += 8;
+ }
+
+ pData->bIsOpaque = MNG_FALSE; /* it's definitely not fully opaque */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_GA16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_rgba8 (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGBA8, MNG_LC_START)
+#endif
+ /* this is the easiest transform */
+ MNG_COPY (pData->pRGBArow, pData->pWorkrow + pData->iPixelofs, pData->iRowsize)
+
+ pData->bIsOpaque = MNG_FALSE; /* it's definitely not fully opaque */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGBA8, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_rgba16 (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGBA16, MNG_LC_START)
+#endif
+ /* this is the easiest transform */
+ MNG_COPY (pData->pRGBArow, pData->pWorkrow + pData->iPixelofs, pData->iRowsize)
+
+ pData->bIsOpaque = MNG_FALSE; /* it's definitely not fully opaque */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RGBA16, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Row processing initialization routines - set up the variables needed * */
+/* * to process uncompressed row-data * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode init_g1_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G1_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_g1;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_g1;
+ else
+ pData->fStorerow = (mng_fptr)store_g1;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g1;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 7;
+ pData->iSamplediv = 3;
+ pData->iRowsize = (pData->iRowsamples + 7) >> 3;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G1_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_g1_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G1_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_g1;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_g1;
+ else
+ pData->fStorerow = (mng_fptr)store_g1;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g1;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 7;
+ pData->iSamplediv = 3;
+ pData->iRowsize = ((pData->iRowsamples + 7) >> 3);
+ pData->iRowmax = ((pData->iDatawidth + 7) >> 3) + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G1_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_g2_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G2_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_g2;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_g2;
+ else
+ pData->fStorerow = (mng_fptr)store_g2;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g2;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 3;
+ pData->iSamplediv = 2;
+ pData->iRowsize = (pData->iRowsamples + 3) >> 2;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G2_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_g2_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G2_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_g2;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_g2;
+ else
+ pData->fStorerow = (mng_fptr)store_g2;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g2;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 3;
+ pData->iSamplediv = 2;
+ pData->iRowsize = ((pData->iRowsamples + 3) >> 2);
+ pData->iRowmax = ((pData->iDatawidth + 3) >> 2) + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G2_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_g4_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G4_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_g4;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_g4;
+ else
+ pData->fStorerow = (mng_fptr)store_g4;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g4;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 1;
+ pData->iSamplediv = 1;
+ pData->iRowsize = (pData->iRowsamples + 1) >> 1;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G4_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_g4_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G4_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_g4;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_g4;
+ else
+ pData->fStorerow = (mng_fptr)store_g4;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g4;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 1;
+ pData->iSamplediv = 1;
+ pData->iRowsize = ((pData->iRowsamples + 1) >> 1);
+ pData->iRowmax = ((pData->iDatawidth + 1) >> 1) + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G4_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_g8_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G8_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_g8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_g8;
+ else
+ pData->fStorerow = (mng_fptr)store_g8;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g8;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G8_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_g8_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G8_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_g8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_g8;
+ else
+ pData->fStorerow = (mng_fptr)store_g8;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g8;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples;
+ pData->iRowmax = pData->iDatawidth + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G8_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_g16_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G16_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_g16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_g16;
+ else
+ pData->fStorerow = (mng_fptr)store_g16;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g16;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 2;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 1;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 2;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G16_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_g16_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G16_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_g16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_g16;
+ else
+ pData->fStorerow = (mng_fptr)store_g16;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g16;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 2;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 1;
+ pData->iRowmax = (pData->iDatawidth << 1) + pData->iPixelofs;
+ pData->iFilterbpp = 2;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_G16_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_rgb8_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB8_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_rgb8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_rgb8;
+ else
+ pData->fStorerow = (mng_fptr)store_rgb8;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_rgb8;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 3;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples * 3;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 3;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB8_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_rgb8_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB8_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_rgb8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_rgb8;
+ else
+ pData->fStorerow = (mng_fptr)store_rgb8;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_rgb8;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 3;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples * 3;
+ pData->iRowmax = (pData->iDatawidth * 3) + pData->iPixelofs;
+ pData->iFilterbpp = 3;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB8_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_rgb16_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB16_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_rgb16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_rgb16;
+ else
+ pData->fStorerow = (mng_fptr)store_rgb16;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_rgb16;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 6;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples * 6;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 6;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB16_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_rgb16_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB16_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_rgb16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_rgb16;
+ else
+ pData->fStorerow = (mng_fptr)store_rgb16;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_rgb16;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 6;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples * 6;
+ pData->iRowmax = (pData->iDatawidth * 6) + pData->iPixelofs;
+ pData->iFilterbpp = 6;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGB16_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_idx1_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX1_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_idx1;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_idx1;
+ else
+ pData->fStorerow = (mng_fptr)store_idx1;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_idx1;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 7;
+ pData->iSamplediv = 3;
+ pData->iRowsize = (pData->iRowsamples + 7) >> 3;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX1_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_idx1_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX1_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_idx1;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_idx1;
+ else
+ pData->fStorerow = (mng_fptr)store_idx1;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_idx1;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 7;
+ pData->iSamplediv = 3;
+ pData->iRowsize = (pData->iRowsamples + 7) >> 3;
+ pData->iRowmax = ((pData->iDatawidth + 7) >> 3) + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX1_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_idx2_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX2_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_idx2;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_idx2;
+ else
+ pData->fStorerow = (mng_fptr)store_idx2;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_idx2;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 3;
+ pData->iSamplediv = 2;
+ pData->iRowsize = (pData->iRowsamples + 3) >> 2;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX2_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_idx2_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX2_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_idx2;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_idx2;
+ else
+ pData->fStorerow = (mng_fptr)store_idx2;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_idx2;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 3;
+ pData->iSamplediv = 2;
+ pData->iRowsize = (pData->iRowsamples + 3) >> 2;
+ pData->iRowmax = ((pData->iDatawidth + 3) >> 2) + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX2_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_idx4_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX4_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_idx4;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_idx4;
+ else
+ pData->fStorerow = (mng_fptr)store_idx4;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_idx4;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 1;
+ pData->iSamplediv = 1;
+ pData->iRowsize = (pData->iRowsamples + 1) >> 1;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX4_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_idx4_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX4_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_idx4;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_idx4;
+ else
+ pData->fStorerow = (mng_fptr)store_idx4;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_idx4;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 1;
+ pData->iSamplediv = 1;
+ pData->iRowsize = (pData->iRowsamples + 1) >> 1;
+ pData->iRowmax = ((pData->iDatawidth + 1) >> 1) + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX4_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_idx8_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX8_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_idx8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_idx8;
+ else
+ pData->fStorerow = (mng_fptr)store_idx8;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_idx8;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX8_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_idx8_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX8_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_idx8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_idx8;
+ else
+ pData->fStorerow = (mng_fptr)store_idx8;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_idx8;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples;
+ pData->iRowmax = pData->iDatawidth + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_IDX8_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_ga8_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GA8_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_ga8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_ga8;
+ else
+ pData->fStorerow = (mng_fptr)store_ga8;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_ga8;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 2;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 1;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 2;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GA8_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_ga8_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GA8_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_ga8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_ga8;
+ else
+ pData->fStorerow = (mng_fptr)store_ga8;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_ga8;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 2;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 1;
+ pData->iRowmax = (pData->iDatawidth << 1) + pData->iPixelofs;
+ pData->iFilterbpp = 2;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GA8_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_ga16_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GA16_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_ga16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_ga16;
+ else
+ pData->fStorerow = (mng_fptr)store_ga16;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_ga16;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 4;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 2;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 4;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GA16_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_ga16_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GA16_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_ga16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_ga16;
+ else
+ pData->fStorerow = (mng_fptr)store_ga16;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_ga16;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 4;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 2;
+ pData->iRowmax = (pData->iDatawidth << 2) + pData->iPixelofs;
+ pData->iFilterbpp = 4;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_GA16_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_rgba8_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGBA8_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_rgba8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_rgba8;
+ else
+ pData->fStorerow = (mng_fptr)store_rgba8;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_rgba8;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 4;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 2;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 4;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGBA8_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_rgba8_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGBA8_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_rgba8;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_rgba8;
+ else
+ pData->fStorerow = (mng_fptr)store_rgba8;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_rgba8;
+
+ pData->iPass = 0; /* from 0..6; is 1..7 in specifications */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 4;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 2;
+ pData->iRowmax = (pData->iDatawidth << 2) + pData->iPixelofs;
+ pData->iFilterbpp = 4;
+ pData->bIsRGBA16 = MNG_FALSE; /* intermediate row is 8-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGBA8_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_rgba16_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGBA16_NI, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_rgba16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_rgba16;
+ else
+ pData->fStorerow = (mng_fptr)store_rgba16;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_rgba16;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 8;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 3;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 8;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGBA16_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_rgba16_i (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGBA16_I, MNG_LC_START)
+#endif
+
+ if (pData->fDisplayrow)
+ pData->fProcessrow = (mng_fptr)process_rgba16;
+
+ if (pData->pStoreobj) /* store in object too ? */
+ { /* immediate delta ? */
+ if ((pData->bHasDHDR) && (pData->bDeltaimmediate))
+ pData->fStorerow = (mng_fptr)delta_rgba16;
+ else
+ pData->fStorerow = (mng_fptr)store_rgba16;
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_rgba16;
+
+ pData->iPass = 0; /* from 0..6; (1..7 in specification) */
+ pData->iRow = interlace_row [0];
+ pData->iRowinc = interlace_rowskip [0];
+ pData->iCol = interlace_col [0];
+ pData->iColinc = interlace_colskip [0];
+ pData->iRowsamples = (pData->iDatawidth + interlace_roundoff [0]) >> interlace_divider [0];
+ pData->iSamplemul = 8;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 3;
+ pData->iRowmax = (pData->iDatawidth << 3) + pData->iPixelofs;
+ pData->iFilterbpp = 8;
+ pData->bIsRGBA16 = MNG_TRUE; /* intermediate row is 16-bit deep */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_RGBA16_I, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Row processing initialization routines (JPEG) - set up the variables * */
+/* * needed to process uncompressed row-data * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+
+/* ************************************************************************** */
+
+mng_retcode init_jpeg_a1_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JPEG_A1_NI, MNG_LC_START)
+#endif
+
+ if (pData->pStoreobj) /* store in object too ? */
+ {
+ if (pData->iJHDRimgbitdepth == 8)
+ {
+ switch (pData->iJHDRcolortype)
+ {
+ case 12 : { pData->fStorerow = (mng_fptr)store_jpeg_g8_a1; break; }
+ case 14 : { pData->fStorerow = (mng_fptr)store_jpeg_rgb8_a1; break; }
+ }
+ }
+
+ /* TODO: bitdepth 12 & 20 */
+
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g1;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 7;
+ pData->iSamplediv = 3;
+ pData->iRowsize = (pData->iRowsamples + 7) >> 3;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JPEG_A1_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_jpeg_a2_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JPEG_A2_NI, MNG_LC_START)
+#endif
+
+ if (pData->pStoreobj) /* store in object too ? */
+ {
+ if (pData->iJHDRimgbitdepth == 8)
+ {
+ switch (pData->iJHDRcolortype)
+ {
+ case 12 : { pData->fStorerow = (mng_fptr)store_jpeg_g8_a2; break; }
+ case 14 : { pData->fStorerow = (mng_fptr)store_jpeg_rgb8_a2; break; }
+ }
+ }
+
+ /* TODO: bitdepth 12 & 20 */
+
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g2;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 3;
+ pData->iSamplediv = 2;
+ pData->iRowsize = (pData->iRowsamples + 3) >> 2;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JPEG_A2_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_jpeg_a4_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JPEG_A4_NI, MNG_LC_START)
+#endif
+
+ if (pData->pStoreobj) /* store in object too ? */
+ {
+ if (pData->iJHDRimgbitdepth == 8)
+ {
+ switch (pData->iJHDRcolortype)
+ {
+ case 12 : { pData->fStorerow = (mng_fptr)store_jpeg_g8_a4; break; }
+ case 14 : { pData->fStorerow = (mng_fptr)store_jpeg_rgb8_a4; break; }
+ }
+ }
+
+ /* TODO: bitdepth 12 & 20 */
+
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g4;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 1;
+ pData->iSamplediv = 1;
+ pData->iRowsize = (pData->iRowsamples + 1) >> 1;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JPEG_A4_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_jpeg_a8_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JPEG_A8_NI, MNG_LC_START)
+#endif
+
+ if (pData->pStoreobj) /* store in object too ? */
+ {
+ if (pData->iJHDRimgbitdepth == 8)
+ {
+ switch (pData->iJHDRcolortype)
+ {
+ case 12 : { pData->fStorerow = (mng_fptr)store_jpeg_g8_a8; break; }
+ case 14 : { pData->fStorerow = (mng_fptr)store_jpeg_rgb8_a8; break; }
+ }
+ }
+
+ /* TODO: bitdepth 12 & 20 */
+
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g8;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 1;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 1;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JPEG_A8_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+mng_retcode init_jpeg_a16_ni (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JPEG_A16_NI, MNG_LC_START)
+#endif
+
+ if (pData->pStoreobj) /* store in object too ? */
+ {
+ if (pData->iJHDRimgbitdepth == 8)
+ {
+ switch (pData->iJHDRcolortype)
+ {
+ case 12 : { pData->fStorerow = (mng_fptr)store_jpeg_g8_a16; break; }
+ case 14 : { pData->fStorerow = (mng_fptr)store_jpeg_rgb8_a16; break; }
+ }
+ }
+
+ /* TODO: bitdepth 12 & 20 */
+
+ }
+
+ if (pData->iFilter & 0x40) /* leveling & differing ? */
+ pData->fDifferrow = (mng_fptr)differ_g16;
+
+ pData->iPass = -1;
+ pData->iRow = 0;
+ pData->iRowinc = 1;
+ pData->iCol = 0;
+ pData->iColinc = 1;
+ pData->iRowsamples = pData->iDatawidth;
+ pData->iSamplemul = 2;
+ pData->iSampleofs = 0;
+ pData->iSamplediv = 0;
+ pData->iRowsize = pData->iRowsamples << 1;
+ pData->iRowmax = pData->iRowsize + pData->iPixelofs;
+ pData->iFilterbpp = 2;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_JPEG_A16_NI, MNG_LC_END)
+#endif
+
+ return init_rowproc (pData);
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+/* * * */
+/* * Generic row processing initialization & cleanup routines * */
+/* * - initialize the buffers used by the row processing routines * */
+/* * - cleanup the buffers used by the row processing routines * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode init_rowproc (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ROWPROC, MNG_LC_START)
+#endif
+
+ if (pData->pStoreobj) /* storage object selected ? */
+ {
+ pData->pStorebuf = ((mng_imagep)pData->pStoreobj)->pImgbuf;
+ /* and so it becomes viewable ! */
+ ((mng_imagep)pData->pStoreobj)->bViewable = MNG_TRUE;
+ ((mng_imagedatap)pData->pStorebuf)->bViewable = MNG_TRUE;
+ }
+
+ /* allocate the buffers; the individual init routines have already
+ calculated the required maximum size; except in the case of a JNG
+ without alpha!!! */
+ if (pData->iRowmax)
+ {
+ MNG_ALLOC (pData, pData->pWorkrow, pData->iRowmax)
+ MNG_ALLOC (pData, pData->pPrevrow, pData->iRowmax)
+ }
+
+ /* allocate an RGBA16 row for intermediate processing */
+ MNG_ALLOC (pData, pData->pRGBArow, (pData->iDatawidth << 3));
+
+#ifndef MNG_NO_CMS
+ if (pData->fDisplayrow) /* display "on-the-fly" ? */
+ {
+#if defined(MNG_FULL_CMS) /* determine color-management initialization */
+ mng_retcode iRetcode = init_full_cms (pData);
+#elif defined(MNG_GAMMA_ONLY)
+ mng_retcode iRetcode = init_gamma_only (pData);
+#elif defined(MNG_APP_CMS)
+ mng_retcode iRetcode = init_app_cms (pData);
+#endif
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* !MNG_NO_CMS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_INIT_ROWPROC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode next_row (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_ROW, MNG_LC_START)
+#endif
+
+ pData->iRow += pData->iRowinc; /* increase the row counter */
+
+ if (pData->iPass >= 0) /* interlaced ? */
+ {
+ while ((pData->iPass < 7) && /* went 'outside' the image ? */
+ ((pData->iRow >= (mng_int32)pData->iDataheight) ||
+ (pData->iCol >= (mng_int32)pData->iDatawidth ) ))
+ {
+ pData->iPass++; /* next pass ! */
+
+ if (pData->iPass < 7) /* there's only 7 passes ! */
+ {
+ pData->iRow = interlace_row [pData->iPass];
+ pData->iRowinc = interlace_rowskip [pData->iPass];
+ pData->iCol = interlace_col [pData->iPass];
+ pData->iColinc = interlace_colskip [pData->iPass];
+ pData->iRowsamples = (pData->iDatawidth - pData->iCol + interlace_roundoff [pData->iPass])
+ >> interlace_divider [pData->iPass];
+
+ if (pData->iSamplemul > 1) /* recalculate row dimension */
+ pData->iRowsize = pData->iRowsamples * pData->iSamplemul;
+ else
+ if (pData->iSamplediv > 0)
+ pData->iRowsize = (pData->iRowsamples + pData->iSampleofs) >> pData->iSamplediv;
+ else
+ pData->iRowsize = pData->iRowsamples;
+
+ }
+
+ if ((pData->iPass < 7) && /* reset previous row to zeroes ? */
+ (pData->iRow < (mng_int32)pData->iDataheight) &&
+ (pData->iCol < (mng_int32)pData->iDatawidth ) )
+ { /* making sure the filters will work properly! */
+ mng_int32 iX;
+ mng_uint8p pTemp = pData->pPrevrow;
+
+ for (iX = 0; iX < pData->iRowsize; iX++)
+ {
+ *pTemp = 0;
+ pTemp++;
+ }
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_ROW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode cleanup_rowproc (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLEANUP_ROWPROC, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_LCMS /* cleanup cms profile/transform */
+ {
+ mng_retcode iRetcode = mng_clear_cms (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif /* MNG_INCLUDE_LCMS */
+
+ if (pData->pWorkrow) /* cleanup buffer for working row */
+ MNG_FREE (pData, pData->pWorkrow, pData->iRowmax)
+
+ if (pData->pPrevrow) /* cleanup buffer for previous row */
+ MNG_FREE (pData, pData->pPrevrow, pData->iRowmax)
+
+ if (pData->pRGBArow) /* cleanup buffer for intermediate row */
+ MNG_FREE (pData, pData->pRGBArow, (pData->iDatawidth << 3))
+
+ pData->pWorkrow = 0; /* propogate uninitialized buffers */
+ pData->pPrevrow = 0;
+ pData->pRGBArow = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_CLEANUP_ROWPROC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* woohiii */
+}
+
+/* ************************************************************************** */
+/* * * */
+/* * Generic row processing routines for JNG * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+
+/* ************************************************************************** */
+
+mng_retcode display_jpeg_rows (mng_datap pData)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_JPEG_ROWS, MNG_LC_START)
+#endif
+ /* any completed rows ? */
+ if ((pData->iJPEGrow > pData->iJPEGdisprow) &&
+ (pData->iJPEGalpharow > pData->iJPEGdisprow) )
+ {
+ mng_uint32 iX, iMax;
+ mng_uint32 iSaverow = pData->iRow; /* save alpha decompression row-count */
+ /* determine the highest complete(!) row */
+ if (pData->iJPEGrow > pData->iJPEGalpharow)
+ iMax = pData->iJPEGalpharow;
+ else
+ iMax = pData->iJPEGrow;
+ /* display the rows */
+ for (iX = pData->iJPEGdisprow; iX < iMax; iX++)
+ {
+ pData->iRow = iX; /* make sure we all know which row to handle */
+ /* makeup an intermediate row from the buffer */
+ iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
+ /* color-correct it if necessary */
+ if ((!iRetcode) && (pData->fCorrectrow))
+ iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
+
+ if (!iRetcode) /* and display it */
+ {
+ iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
+
+ if (!iRetcode) /* check progressive display refresh */
+ iRetcode = display_progressive_check (pData);
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ pData->iJPEGdisprow = iMax; /* keep track of the last displayed row */
+ pData->iRow = iSaverow; /* restore alpha decompression row-count */
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_DISPLAY_JPEG_ROWS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode next_jpeg_alpharow (mng_datap pData)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ALPHAROW, MNG_LC_START)
+#endif
+
+ pData->iJPEGalpharow++; /* count the row */
+
+ if (pData->fDisplayrow) /* display "on-the-fly" ? */
+ { /* try to display what you can */
+ iRetcode = display_jpeg_rows (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ALPHAROW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode next_jpeg_row (mng_datap pData)
+{
+ mng_retcode iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ROW, MNG_LC_START)
+#endif
+
+ pData->iJPEGrow++; /* increase the row-counter */
+
+ if (pData->fDisplayrow) /* display "on-the-fly" ? */
+ { /* has alpha channel ? */
+ if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
+ (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
+ { /* try to display what you can */
+ iRetcode = display_jpeg_rows (pData);
+ }
+ else
+ { /* make sure we all know which row to handle */
+ pData->iRow = pData->iJPEGrow - 1;
+ /* makeup an intermediate row from the buffer */
+ iRetcode = ((mng_retrieverow)pData->fRetrieverow) (pData);
+ /* color-correct it if necessary */
+ if ((!iRetcode) && (pData->fCorrectrow))
+ iRetcode = ((mng_correctrow)pData->fCorrectrow) (pData);
+
+ if (!iRetcode) /* and display it */
+ {
+ iRetcode = ((mng_displayrow)pData->fDisplayrow) (pData);
+
+ if (!iRetcode) /* check progressive display refresh */
+ iRetcode = display_progressive_check (pData);
+ }
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+
+ /* surpassed last filled row ? */
+ if (pData->iJPEGrow > pData->iJPEGrgbrow)
+ pData->iJPEGrgbrow = pData->iJPEGrow;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_NEXT_JPEG_ROW, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+mng_retcode magnify_g8_x1 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX, iS, iM;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X1, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ iM = iML;
+ else
+ if (iX == (iWidth - 1)) /* last interval ? */
+ iM = iMR;
+ else
+ iM = iMX;
+
+ for (iS = 1; iS < iM; iS++) /* fill interval */
+ {
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ }
+
+ pTempsrc1++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_g8_x2 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X2, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 1;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = iMR;
+ else
+ iM = iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ { /* is it same as first ? */
+ if (*pTempsrc1 == *pTempsrc2)
+ {
+ for (iS = 1; iS < iM; iS++) /* then just repeat the first */
+ {
+ *pTempdst = *pTempsrc1;
+ pTempdst++;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++) /* calculate the distances */
+ {
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2)) + (mng_int32)(*pTempsrc1) );
+ pTempdst++;
+ }
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_g8_x3 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM, iH;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X3, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 1;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = iMR;
+ else
+ iM = iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ { /* is it same as first ? */
+ if (*pTempsrc1 == *pTempsrc2)
+ {
+ for (iS = 1; iS < iM; iS++) /* then just repeat the first */
+ {
+ *pTempdst = *pTempsrc1;
+ pTempdst++;
+ }
+ }
+ else
+ {
+ iH = (iM+1) / 2; /* calculate halfway point */
+
+ for (iS = 1; iS < iH; iS++) /* replicate first half */
+ {
+ *pTempdst = *pTempsrc1;
+ pTempdst++;
+ }
+
+ for (iS = iH; iS < iM; iS++) /* replicate second half */
+ {
+ *pTempdst = *pTempsrc2;
+ pTempdst++;
+ }
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1++;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_X3, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgb8_x1 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX, iS, iM;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X1, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ iM = iML;
+ else
+ if (iX == (iWidth - 1)) /* last interval ? */
+ iM = iMR;
+ else
+ iM = iMX;
+
+ for (iS = 1; iS < iM; iS++) /* fill interval */
+ {
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ }
+
+ pTempsrc1 += 3;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgb8_x2 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X2, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 3;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = (mng_int32)iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = (mng_int32)iMR;
+ else
+ iM = (mng_int32)iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1; /* just repeat the first */
+ else /* calculate the distance */
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2)) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+
+ if (*(pTempsrc1+1) == *(pTempsrc2+1))
+ *pTempdst = *(pTempsrc1+1);
+ else
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
+ (mng_int32)(*(pTempsrc1+1)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+1)) );
+
+ pTempdst++;
+
+ if (*(pTempsrc1+2) == *(pTempsrc2+2))
+ *pTempdst = *(pTempsrc1+2);
+ else
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
+ (mng_int32)(*(pTempsrc1+2)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+2)) );
+
+ pTempdst++;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1 += 3;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgb8_x3 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM, iH;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X3, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 3;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = (mng_int32)iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = (mng_int32)iMR;
+ else
+ iM = (mng_int32)iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ {
+ iH = (iM+1) / 2; /* calculate halfway point */
+
+ for (iS = 1; iS < iH; iS++) /* replicate first half */
+ {
+ *pTempdst = *pTempsrc1;
+ *(pTempdst+1) = *(pTempsrc1+1);
+ *(pTempdst+2) = *(pTempsrc1+2);
+
+ pTempdst += 3;
+ }
+
+ for (iS = iH; iS < iM; iS++) /* replicate second half */
+ {
+ *pTempdst = *pTempsrc2;
+ *(pTempdst+1) = *(pTempsrc2+1);
+ *(pTempdst+2) = *(pTempsrc2+2);
+
+ pTempdst += 3;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1 += 3;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_X3, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_ga8_x1 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX, iS, iM;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X1, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ iM = iML;
+ else
+ if (iX == (iWidth - 1)) /* last interval ? */
+ iM = iMR;
+ else
+ iM = iMX;
+
+ for (iS = 1; iS < iM; iS++) /* fill interval */
+ {
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ }
+
+ pTempsrc1 += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_ga8_x2 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X2, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 2;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = iMR;
+ else
+ iM = iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1; /* just repeat the first */
+ else /* calculate the distance */
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2)) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+
+ if (*(pTempsrc1+1) == *(pTempsrc2+1))
+ *pTempdst = *(pTempsrc1+1);
+ else
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
+ (mng_int32)(*(pTempsrc1+1)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+1)) );
+
+ pTempdst++;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1 += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_ga8_x3 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM, iH;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X3, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 2;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = iMR;
+ else
+ iM = iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ {
+ iH = (iM+1) / 2; /* calculate halfway point */
+
+ for (iS = 1; iS < iH; iS++) /* replicate first half */
+ {
+ *pTempdst = *pTempsrc1;
+ *(pTempdst+1) = *(pTempsrc1+1);
+
+ pTempdst += 2;
+ }
+
+ for (iS = iH; iS < iM; iS++) /* replicate second half */
+ {
+ *pTempdst = *pTempsrc2;
+ *(pTempdst+1) = *(pTempsrc2+1);
+
+ pTempdst += 2;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1 += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X3, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_ga8_x4 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM, iH;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X4, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 2;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = iMR;
+ else
+ iM = iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ {
+ iH = (iM+1) / 2; /* calculate halfway point */
+
+ for (iS = 1; iS < iH; iS++) /* first half */
+ {
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1; /* just repeat the first */
+ else /* calculate the distance */
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2)) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+
+ *pTempdst = *(pTempsrc1+1); /* replicate alpha from left */
+
+ pTempdst++;
+ }
+
+ for (iS = iH; iS < iM; iS++) /* second half */
+ {
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1; /* just repeat the first */
+ else /* calculate the distance */
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2)) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+
+ *pTempdst = *(pTempsrc2+1); /* replicate alpha from right */
+
+ pTempdst++;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1 += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_ga8_x5 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM, iH;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X5, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 2;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = iMR;
+ else
+ iM = iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ {
+ iH = (iM+1) / 2; /* calculate halfway point */
+
+ for (iS = 1; iS < iH; iS++) /* first half */
+ {
+ *pTempdst = *pTempsrc1; /* replicate gray from left */
+
+ pTempdst++;
+
+ if (*(pTempsrc1+1) == *(pTempsrc2+1))
+ *pTempdst = *(pTempsrc1+1);/* just repeat the first */
+ else /* calculate the distance */
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
+ (mng_int32)(*(pTempsrc1+1)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+1)) );
+
+ pTempdst++;
+ }
+
+ for (iS = iH; iS < iM; iS++) /* second half */
+ {
+ *pTempdst = *pTempsrc2; /* replicate gray from right */
+
+ pTempdst++;
+
+ if (*(pTempsrc1+1) == *(pTempsrc2+1))
+ *pTempdst = *(pTempsrc1+1);/* just repeat the first */
+ else /* calculate the distance */
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
+ (mng_int32)(*(pTempsrc1+1)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+1)) );
+
+ pTempdst++;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1 += 2;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_X5, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgba8_x1 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX, iS, iM;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X1, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+3);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ iM = iML;
+ else
+ if (iX == (iWidth - 1)) /* last interval ? */
+ iM = iMR;
+ else
+ iM = iMX;
+
+ for (iS = 1; iS < iM; iS++) /* fill interval */
+ {
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+3);
+ pTempdst++;
+ }
+
+ pTempsrc1 += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgba8_x2 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X2, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 4;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+3);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = (mng_int32)iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = (mng_int32)iMR;
+ else
+ iM = (mng_int32)iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1; /* just repeat the first */
+ else /* calculate the distance */
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2)) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+
+ if (*(pTempsrc1+1) == *(pTempsrc2+1))
+ *pTempdst = *(pTempsrc1+1);
+ else
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
+ (mng_int32)(*(pTempsrc1+1)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+1)) );
+
+ pTempdst++;
+
+ if (*(pTempsrc1+2) == *(pTempsrc2+2))
+ *pTempdst = *(pTempsrc1+2);
+ else
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
+ (mng_int32)(*(pTempsrc1+2)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+2)) );
+
+ pTempdst++;
+
+ if (*(pTempsrc1+3) == *(pTempsrc2+3))
+ *pTempdst = *(pTempsrc1+3);
+ else
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+3)) -
+ (mng_int32)(*(pTempsrc1+3)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+3)) );
+
+ pTempdst++;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+3);
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1 += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgba8_x3 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM, iH;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X3, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 4;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+3);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = (mng_int32)iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = (mng_int32)iMR;
+ else
+ iM = (mng_int32)iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ {
+ iH = (iM+1) / 2; /* calculate halfway point */
+
+ for (iS = 1; iS < iH; iS++) /* replicate first half */
+ {
+ *pTempdst = *pTempsrc1;
+ *(pTempdst+1) = *(pTempsrc1+1);
+ *(pTempdst+2) = *(pTempsrc1+2);
+ *(pTempdst+3) = *(pTempsrc1+3);
+
+ pTempdst += 4;
+ }
+
+ for (iS = iH; iS < iM; iS++) /* replicate second half */
+ {
+ *pTempdst = *pTempsrc2;
+ *(pTempdst+1) = *(pTempsrc2+1);
+ *(pTempdst+2) = *(pTempsrc2+2);
+ *(pTempdst+3) = *(pTempsrc2+3);
+
+ pTempdst += 4;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+3);
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1 += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X3, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgba8_x4 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM, iH;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X4, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 4;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+3);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = (mng_int32)iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = (mng_int32)iMR;
+ else
+ iM = (mng_int32)iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ {
+ iH = (iM+1) / 2; /* calculate halfway point */
+
+ for (iS = 1; iS < iH; iS++) /* first half */
+ {
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1; /* just repeat the first */
+ else /* calculate the distance */
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2)) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+
+ if (*(pTempsrc1+1) == *(pTempsrc2+1))
+ *pTempdst = *(pTempsrc1+1);
+ else
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
+ (mng_int32)(*(pTempsrc1+1)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+1)) );
+
+ pTempdst++;
+
+ if (*(pTempsrc1+2) == *(pTempsrc2+2))
+ *pTempdst = *(pTempsrc1+2);
+ else
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
+ (mng_int32)(*(pTempsrc1+2)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+2)) );
+
+ pTempdst++;
+ /* replicate alpha from left */
+ *pTempdst = *(pTempsrc1+3);
+
+ pTempdst++;
+ }
+
+ for (iS = iH; iS < iM; iS++) /* second half */
+ {
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1; /* just repeat the first */
+ else /* calculate the distance */
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2)) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+
+ if (*(pTempsrc1+1) == *(pTempsrc2+1))
+ *pTempdst = *(pTempsrc1+1);
+ else
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+1)) -
+ (mng_int32)(*(pTempsrc1+1)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+1)) );
+
+ pTempdst++;
+
+ if (*(pTempsrc1+2) == *(pTempsrc2+2))
+ *pTempdst = *(pTempsrc1+2);
+ else
+ *pTempdst = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+2)) -
+ (mng_int32)(*(pTempsrc1+2)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+2)) );
+
+ pTempdst++;
+ /* replicate alpha from right */
+ *pTempdst = *(pTempsrc2+3);
+
+ pTempdst++;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+3);
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1 += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgba8_x5 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_int32 iS, iM, iH;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X5, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline; /* initialize pixel-loop */
+ pTempdst = pDstline;
+
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ pTempsrc2 = pTempsrc1 + 4;
+
+ *pTempdst = *pTempsrc1; /* copy original source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+3);
+ pTempdst++;
+
+ if (iX == 0) /* first interval ? */
+ {
+ if (iWidth == 1) /* single pixel ? */
+ pTempsrc2 = MNG_NULL;
+
+ iM = (mng_int32)iML;
+ }
+ else
+ if (iX == (iWidth - 2)) /* last interval ? */
+ iM = (mng_int32)iMR;
+ else
+ iM = (mng_int32)iMX;
+ /* fill interval ? */
+ if ((iX < iWidth - 1) || (iWidth == 1))
+ {
+ if (pTempsrc2) /* do we have the second pixel ? */
+ {
+ iH = (iM+1) / 2; /* calculate halfway point */
+
+ for (iS = 1; iS < iH; iS++) /* first half */
+ {
+ *pTempdst = *pTempsrc1; /* replicate color from left */
+ *(pTempdst+1) = *(pTempsrc1+1);
+ *(pTempdst+2) = *(pTempsrc1+2);
+
+ if (*(pTempsrc1+3) == *(pTempsrc2+3))
+ *(pTempdst+3) = *(pTempsrc1+3);
+ else
+ *(pTempdst+3) = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+3)) -
+ (mng_int32)(*(pTempsrc1+3)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+3)) );
+
+ pTempdst += 4;
+ }
+
+ for (iS = iH; iS < iM; iS++) /* second half */
+ {
+ *pTempdst = *pTempsrc2; /* replicate color from right */
+ *(pTempdst+1) = *(pTempsrc2+1);
+ *(pTempdst+2) = *(pTempsrc2+2);
+
+ if (*(pTempsrc1+3) == *(pTempsrc2+3))
+ *(pTempdst+3) = *(pTempsrc1+3);
+ else
+ *(pTempdst+3) = (mng_uint8)(((2 * iS * ( (mng_int32)(*(pTempsrc2+3)) -
+ (mng_int32)(*(pTempsrc1+3)) ) + iM) /
+ (iM * 2)) + (mng_int32)(*(pTempsrc1+3)) );
+
+ pTempdst += 4;
+ }
+ }
+ else
+ {
+ for (iS = 1; iS < iM; iS++)
+ {
+ *pTempdst = *pTempsrc1; /* repeat first source pixel */
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+1);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+2);
+ pTempdst++;
+ *pTempdst = *(pTempsrc1+3);
+ pTempdst++;
+ }
+ }
+ }
+
+ pTempsrc1 += 4;
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_X4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_g8_y1 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y1, MNG_LC_START)
+#endif
+
+ MNG_COPY (pDstline, pSrcline1, iWidth)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_g8_y2 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y2, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline1; /* initialize pixel-loop */
+ pTempsrc2 = pSrcline2;
+ pTempdst = pDstline;
+
+ if (pTempsrc2) /* do we have a second line ? */
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ { /* calculate the distances */
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+ }
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pTempdst, pTempsrc1, iWidth)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_g8_y3 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y3, MNG_LC_START)
+#endif
+
+ if (pSrcline2) /* do we have a second line ? */
+ {
+ if (iS < (iM+1) / 2) /* top half ? */
+ MNG_COPY (pDstline, pSrcline1, iWidth)
+ else
+ MNG_COPY (pDstline, pSrcline2, iWidth)
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pDstline, pSrcline1, iWidth)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_G8_Y3, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgb8_y1 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y1, MNG_LC_START)
+#endif
+
+ MNG_COPY (pDstline, pSrcline1, iWidth * 3)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgb8_y2 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y2, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline1; /* initialize pixel-loop */
+ pTempsrc2 = pSrcline2;
+ pTempdst = pDstline;
+
+ if (pTempsrc2) /* do we have a second line ? */
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ { /* calculate the distances */
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+ }
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pTempdst, pTempsrc1, iWidth * 3)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgb8_y3 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y3, MNG_LC_START)
+#endif
+
+ if (pSrcline2) /* do we have a second line ? */
+ {
+ if (iS < (iM+1) / 2) /* top half ? */
+ MNG_COPY (pDstline, pSrcline1, iWidth * 3)
+ else
+ MNG_COPY (pDstline, pSrcline2, iWidth * 3)
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pDstline, pSrcline1, iWidth * 3)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGB8_Y3, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_ga8_y1 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y1, MNG_LC_START)
+#endif
+
+ MNG_COPY (pDstline, pSrcline1, iWidth << 1)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_ga8_y2 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y2, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline1; /* initialize pixel-loop */
+ pTempsrc2 = pSrcline2;
+ pTempdst = pDstline;
+
+ if (pTempsrc2) /* do we have a second line ? */
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ { /* calculate the distances */
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+ }
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pTempdst, pTempsrc1, iWidth << 1)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_ga8_y3 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y3, MNG_LC_START)
+#endif
+
+ if (pSrcline2) /* do we have a second line ? */
+ {
+ if (iS < (iM+1) / 2) /* top half ? */
+ MNG_COPY (pDstline, pSrcline1, iWidth << 1)
+ else
+ MNG_COPY (pDstline, pSrcline2, iWidth << 1)
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pDstline, pSrcline1, iWidth << 1)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_ga8_y4 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y4, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline1; /* initialize pixel-loop */
+ pTempsrc2 = pSrcline2;
+ pTempdst = pDstline;
+
+ if (pTempsrc2) /* do we have a second line ? */
+ {
+ if (iS < (iM+1) / 2) /* top half ? */
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ { /* calculate the distances */
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2 += 2;
+
+ *pTempdst++ = *pTempsrc1++; /* replicate alpha from top */
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ { /* calculate the distances */
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1 += 2;
+ pTempsrc2++;
+
+ *pTempdst++ = *pTempsrc2++; /* replicate alpha from bottom */
+ }
+ }
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pTempdst, pTempsrc1, iWidth << 1)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_ga8_y5 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y5, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline1; /* initialize pixel-loop */
+ pTempsrc2 = pSrcline2;
+ pTempdst = pDstline;
+
+ if (pTempsrc2) /* do we have a second line ? */
+ {
+ if (iS < (iM+1) / 2) /* top half ? */
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ *pTempdst = *pTempsrc1; /* replicate gray from top */
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2) /* calculate the distances */
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ *pTempdst = *pTempsrc2; /* replicate gray from bottom */
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2) /* calculate the distances */
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+ }
+ }
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pTempdst, pTempsrc1, iWidth << 1)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_GA8_Y5, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgba8_y1 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y1, MNG_LC_START)
+#endif
+
+ MNG_COPY (pDstline, pSrcline1, iWidth << 2)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y1, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgba8_y2 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y2, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline1; /* initialize pixel-loop */
+ pTempsrc2 = pSrcline2;
+ pTempdst = pDstline;
+
+ if (pTempsrc2) /* do we have a second line ? */
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ { /* calculate the distances */
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+ }
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pTempdst, pTempsrc1, iWidth << 2)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgba8_y3 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y3, MNG_LC_START)
+#endif
+
+ if (pSrcline2) /* do we have a second line ? */
+ {
+ if (iS < (iM+1) / 2) /* top half ? */
+ MNG_COPY (pDstline, pSrcline1, iWidth << 2)
+ else
+ MNG_COPY (pDstline, pSrcline2, iWidth << 2)
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pDstline, pSrcline1, iWidth << 2)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgba8_y4 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y4, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline1; /* initialize pixel-loop */
+ pTempsrc2 = pSrcline2;
+ pTempdst = pDstline;
+
+ if (pTempsrc2) /* do we have a second line ? */
+ {
+ if (iS < (iM+1) / 2) /* top half ? */
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ { /* calculate the distances */
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2 += 2;
+
+ *pTempdst++ = *pTempsrc1++; /* replicate alpha from top */
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ { /* calculate the distances */
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+
+ if (*pTempsrc1 == *pTempsrc2)
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1 += 2;
+ pTempsrc2++;
+
+ *pTempdst++ = *pTempsrc2++; /* replicate alpha from bottom */
+ }
+ }
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pTempdst, pTempsrc1, iWidth << 2)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y4, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode magnify_rgba8_y5 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline)
+{
+ mng_uint32 iX;
+ mng_uint8p pTempsrc1;
+ mng_uint8p pTempsrc2;
+ mng_uint8p pTempdst;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y5, MNG_LC_START)
+#endif
+
+ pTempsrc1 = pSrcline1; /* initialize pixel-loop */
+ pTempsrc2 = pSrcline2;
+ pTempdst = pDstline;
+
+ if (pTempsrc2) /* do we have a second line ? */
+ {
+ if (iS < (iM+1) / 2) /* top half ? */
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ *pTempdst++ = *pTempsrc1++; /* replicate color from top */
+ *pTempdst++ = *pTempsrc1++;
+ *pTempdst++ = *pTempsrc1++;
+
+ pTempsrc2 += 3;
+
+ if (*pTempsrc1 == *pTempsrc2) /* calculate the distances */
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+ }
+ }
+ else
+ {
+ for (iX = 0; iX < iWidth; iX++)
+ {
+ *pTempdst++ = *pTempsrc2++; /* replicate color from bottom */
+ *pTempdst++ = *pTempsrc2++;
+ *pTempdst++ = *pTempsrc2++;
+
+ pTempsrc1 += 3;
+
+ if (*pTempsrc1 == *pTempsrc2) /* calculate the distances */
+ *pTempdst = *pTempsrc1;
+ else
+ *pTempdst = (mng_uint8)( ( (2 * iS * ( (mng_int32)(*pTempsrc2) -
+ (mng_int32)(*pTempsrc1) ) + iM) /
+ (iM * 2) ) + (mng_int32)(*pTempsrc1) );
+
+ pTempdst++;
+ pTempsrc1++;
+ pTempsrc2++;
+ }
+ }
+ }
+ else
+ { /* just repeat the entire line */
+ MNG_COPY (pTempdst, pTempsrc1, iWidth << 2)
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_MAGNIFY_RGBA8_Y5, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_DISPLAY_PROCS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_pixels.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_pixels.h
new file mode 100644
index 0000000..aa97c70
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_pixels.h
@@ -0,0 +1,570 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_pixels.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.1 * */
+/* * * */
+/* * purpose : Pixel-row management routines (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the pixel-row management routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.5.2 - 05/22/2000 - G.Juyn * */
+/* * - added some JNG definitions * */
+/* * - added delta-image row-processing routines * */
+/* * 0.5.2 - 06/05/2000 - G.Juyn * */
+/* * - added support for RGB8_A8 canvasstyle * */
+/* * * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - changed progressive-display processing * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN support * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added optional support for bKGD for PNG images * */
+/* * - added support for JDAA * */
+/* * 0.9.3 - 10/19/2000 - G.Juyn * */
+/* * - implemented delayed delta-processing * */
+/* * * */
+/* * 0.9.4 - 1/18/2001 - G.Juyn * */
+/* * - added "new" MAGN methods 3, 4 & 5 * */
+/* * * */
+/* * 1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly) * */
+/* * - added BGRA8 canvas with premultiplied alpha * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_pixels_h_
+#define _libmng_pixels_h_
+
+/* ************************************************************************** */
+/* * * */
+/* * Progressive display check - checks to see if progressive display is * */
+/* * in order & indicates so * */
+/* * * */
+/* * The routine is called after a call to one of the display_xxx routines * */
+/* * if appropriate * */
+/* * * */
+/* * The refresh is warrented in the read_chunk routine (mng_read.c) * */
+/* * and only during read&display processing, since there's not much point * */
+/* * doing it from memory! * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode display_progressive_check (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Display routines - convert rowdata (which is already color-corrected) * */
+/* * to the output canvas, respecting any transparency information * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode display_rgb8 (mng_datap pData);
+mng_retcode display_rgba8 (mng_datap pData);
+mng_retcode display_argb8 (mng_datap pData);
+mng_retcode display_rgb8_a8 (mng_datap pData);
+mng_retcode display_bgr8 (mng_datap pData);
+mng_retcode display_bgra8 (mng_datap pData);
+mng_retcode display_bgra8_pm (mng_datap pData);
+mng_retcode display_abgr8 (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Background restore routines - restore the background with info from * */
+/* * the BACK and/or bKGD chunk and/or the app's background canvas * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode restore_bkgd_backimage (mng_datap pData);
+mng_retcode restore_bkgd_backcolor (mng_datap pData);
+mng_retcode restore_bkgd_bkgd (mng_datap pData);
+mng_retcode restore_bkgd_bgcolor (mng_datap pData);
+mng_retcode restore_bkgd_rgb8 (mng_datap pData);
+mng_retcode restore_bkgd_bgr8 (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Row retrieval routines - retrieve processed & uncompressed row-data * */
+/* * from the current "object" * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode retrieve_g8 (mng_datap pData);
+mng_retcode retrieve_g16 (mng_datap pData);
+mng_retcode retrieve_rgb8 (mng_datap pData);
+mng_retcode retrieve_rgb16 (mng_datap pData);
+mng_retcode retrieve_idx8 (mng_datap pData);
+mng_retcode retrieve_ga8 (mng_datap pData);
+mng_retcode retrieve_ga16 (mng_datap pData);
+mng_retcode retrieve_rgba8 (mng_datap pData);
+mng_retcode retrieve_rgba16 (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Row storage routines - store processed & uncompressed row-data * */
+/* * into the current "object" * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode store_g1 (mng_datap pData);
+mng_retcode store_g2 (mng_datap pData);
+mng_retcode store_g4 (mng_datap pData);
+mng_retcode store_g8 (mng_datap pData);
+mng_retcode store_g16 (mng_datap pData);
+mng_retcode store_rgb8 (mng_datap pData);
+mng_retcode store_rgb16 (mng_datap pData);
+mng_retcode store_idx1 (mng_datap pData);
+mng_retcode store_idx2 (mng_datap pData);
+mng_retcode store_idx4 (mng_datap pData);
+mng_retcode store_idx8 (mng_datap pData);
+mng_retcode store_ga8 (mng_datap pData);
+mng_retcode store_ga16 (mng_datap pData);
+mng_retcode store_rgba8 (mng_datap pData);
+mng_retcode store_rgba16 (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Row storage routines (JPEG) - store processed & uncompressed row-data * */
+/* * into the current "object" * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode store_jpeg_g8 (mng_datap pData);
+mng_retcode store_jpeg_rgb8 (mng_datap pData);
+mng_retcode store_jpeg_ga8 (mng_datap pData);
+mng_retcode store_jpeg_rgba8 (mng_datap pData);
+
+mng_retcode store_jpeg_g12 (mng_datap pData);
+mng_retcode store_jpeg_rgb12 (mng_datap pData);
+mng_retcode store_jpeg_ga12 (mng_datap pData);
+mng_retcode store_jpeg_rgba12 (mng_datap pData);
+
+mng_retcode store_jpeg_g8_alpha (mng_datap pData);
+mng_retcode store_jpeg_rgb8_alpha (mng_datap pData);
+
+mng_retcode store_jpeg_g8_a1 (mng_datap pData);
+mng_retcode store_jpeg_g8_a2 (mng_datap pData);
+mng_retcode store_jpeg_g8_a4 (mng_datap pData);
+mng_retcode store_jpeg_g8_a8 (mng_datap pData);
+mng_retcode store_jpeg_g8_a16 (mng_datap pData);
+
+mng_retcode store_jpeg_rgb8_a1 (mng_datap pData);
+mng_retcode store_jpeg_rgb8_a2 (mng_datap pData);
+mng_retcode store_jpeg_rgb8_a4 (mng_datap pData);
+mng_retcode store_jpeg_rgb8_a8 (mng_datap pData);
+mng_retcode store_jpeg_rgb8_a16 (mng_datap pData);
+
+mng_retcode store_jpeg_g12_a1 (mng_datap pData);
+mng_retcode store_jpeg_g12_a2 (mng_datap pData);
+mng_retcode store_jpeg_g12_a4 (mng_datap pData);
+mng_retcode store_jpeg_g12_a8 (mng_datap pData);
+mng_retcode store_jpeg_g12_a16 (mng_datap pData);
+
+mng_retcode store_jpeg_rgb12_a1 (mng_datap pData);
+mng_retcode store_jpeg_rgb12_a2 (mng_datap pData);
+mng_retcode store_jpeg_rgb12_a4 (mng_datap pData);
+mng_retcode store_jpeg_rgb12_a8 (mng_datap pData);
+mng_retcode store_jpeg_rgb12_a16 (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image row routines - apply the processed & uncompressed row-data * */
+/* * onto the target "object" * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode delta_g1 (mng_datap pData);
+mng_retcode delta_g2 (mng_datap pData);
+mng_retcode delta_g4 (mng_datap pData);
+mng_retcode delta_g8 (mng_datap pData);
+mng_retcode delta_g16 (mng_datap pData);
+mng_retcode delta_rgb8 (mng_datap pData);
+mng_retcode delta_rgb16 (mng_datap pData);
+mng_retcode delta_idx1 (mng_datap pData);
+mng_retcode delta_idx2 (mng_datap pData);
+mng_retcode delta_idx4 (mng_datap pData);
+mng_retcode delta_idx8 (mng_datap pData);
+mng_retcode delta_ga8 (mng_datap pData);
+mng_retcode delta_ga16 (mng_datap pData);
+mng_retcode delta_rgba8 (mng_datap pData);
+mng_retcode delta_rgba16 (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image row routines - apply the source row onto the target * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode delta_g1_g1 (mng_datap pData);
+mng_retcode delta_g2_g2 (mng_datap pData);
+mng_retcode delta_g4_g4 (mng_datap pData);
+mng_retcode delta_g8_g8 (mng_datap pData);
+mng_retcode delta_g16_g16 (mng_datap pData);
+mng_retcode delta_rgb8_rgb8 (mng_datap pData);
+mng_retcode delta_rgb16_rgb16 (mng_datap pData);
+mng_retcode delta_ga8_ga8 (mng_datap pData);
+mng_retcode delta_ga8_g8 (mng_datap pData);
+mng_retcode delta_ga8_a8 (mng_datap pData);
+mng_retcode delta_ga16_ga16 (mng_datap pData);
+mng_retcode delta_ga16_g16 (mng_datap pData);
+mng_retcode delta_ga16_a16 (mng_datap pData);
+mng_retcode delta_rgba8_rgba8 (mng_datap pData);
+mng_retcode delta_rgba8_rgb8 (mng_datap pData);
+mng_retcode delta_rgba8_a8 (mng_datap pData);
+mng_retcode delta_rgba16_rgba16 (mng_datap pData);
+mng_retcode delta_rgba16_rgb16 (mng_datap pData);
+mng_retcode delta_rgba16_a16 (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Delta-image row routines - scale the source to bitdepth of target * */
+/* * * */
+/* ************************************************************************** */
+
+
+
+/* ************************************************************************** */
+/* * * */
+/* * Row processing routines - convert uncompressed data from zlib to * */
+/* * managable row-data which serves as input to the color-management * */
+/* * routines * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode process_g1 (mng_datap pData);
+mng_retcode process_g2 (mng_datap pData);
+mng_retcode process_g4 (mng_datap pData);
+mng_retcode process_g8 (mng_datap pData);
+mng_retcode process_g16 (mng_datap pData);
+mng_retcode process_rgb8 (mng_datap pData);
+mng_retcode process_rgb16 (mng_datap pData);
+mng_retcode process_idx1 (mng_datap pData);
+mng_retcode process_idx2 (mng_datap pData);
+mng_retcode process_idx4 (mng_datap pData);
+mng_retcode process_idx8 (mng_datap pData);
+mng_retcode process_ga8 (mng_datap pData);
+mng_retcode process_ga16 (mng_datap pData);
+mng_retcode process_rgba8 (mng_datap pData);
+mng_retcode process_rgba16 (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Row processing initialization routines - set up the variables needed * */
+/* * to process uncompressed row-data * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode init_g1_ni (mng_datap pData);
+mng_retcode init_g1_i (mng_datap pData);
+mng_retcode init_g2_ni (mng_datap pData);
+mng_retcode init_g2_i (mng_datap pData);
+mng_retcode init_g4_ni (mng_datap pData);
+mng_retcode init_g4_i (mng_datap pData);
+mng_retcode init_g8_ni (mng_datap pData);
+mng_retcode init_g8_i (mng_datap pData);
+mng_retcode init_g16_ni (mng_datap pData);
+mng_retcode init_g16_i (mng_datap pData);
+mng_retcode init_rgb8_ni (mng_datap pData);
+mng_retcode init_rgb8_i (mng_datap pData);
+mng_retcode init_rgb16_ni (mng_datap pData);
+mng_retcode init_rgb16_i (mng_datap pData);
+mng_retcode init_idx1_ni (mng_datap pData);
+mng_retcode init_idx1_i (mng_datap pData);
+mng_retcode init_idx2_ni (mng_datap pData);
+mng_retcode init_idx2_i (mng_datap pData);
+mng_retcode init_idx4_ni (mng_datap pData);
+mng_retcode init_idx4_i (mng_datap pData);
+mng_retcode init_idx8_ni (mng_datap pData);
+mng_retcode init_idx8_i (mng_datap pData);
+mng_retcode init_ga8_ni (mng_datap pData);
+mng_retcode init_ga8_i (mng_datap pData);
+mng_retcode init_ga16_ni (mng_datap pData);
+mng_retcode init_ga16_i (mng_datap pData);
+mng_retcode init_rgba8_ni (mng_datap pData);
+mng_retcode init_rgba8_i (mng_datap pData);
+mng_retcode init_rgba16_ni (mng_datap pData);
+mng_retcode init_rgba16_i (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Row processing initialization routines (JPEG) - set up the variables * */
+/* * needed to process uncompressed row-data * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode init_jpeg_a1_ni (mng_datap pData);
+mng_retcode init_jpeg_a2_ni (mng_datap pData);
+mng_retcode init_jpeg_a4_ni (mng_datap pData);
+mng_retcode init_jpeg_a8_ni (mng_datap pData);
+mng_retcode init_jpeg_a16_ni (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * General row processing routines * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode init_rowproc (mng_datap pData);
+mng_retcode next_row (mng_datap pData);
+mng_retcode next_jpeg_alpharow (mng_datap pData);
+mng_retcode next_jpeg_row (mng_datap pData);
+mng_retcode cleanup_rowproc (mng_datap pData);
+
+/* ************************************************************************** */
+/* * * */
+/* * Magnification row routines - apply magnification transforms * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode magnify_g8_x1 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_g8_x2 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_g8_x3 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgb8_x1 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgb8_x2 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgb8_x3 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_ga8_x1 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_ga8_x2 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_ga8_x3 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_ga8_x4 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_ga8_x5 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgba8_x1 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgba8_x2 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgba8_x3 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgba8_x4 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgba8_x5 (mng_datap pData,
+ mng_uint16 iMX,
+ mng_uint16 iML,
+ mng_uint16 iMR,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline,
+ mng_uint8p pDstline);
+
+mng_retcode magnify_g8_y1 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_g8_y2 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_g8_y3 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgb8_y1 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgb8_y2 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgb8_y3 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_ga8_y1 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_ga8_y2 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_ga8_y3 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_ga8_y4 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_ga8_y5 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgba8_y1 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgba8_y2 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgba8_y3 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgba8_y4 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+mng_retcode magnify_rgba8_y5 (mng_datap pData,
+ mng_int32 iS,
+ mng_int32 iM,
+ mng_uint32 iWidth,
+ mng_uint8p pSrcline1,
+ mng_uint8p pSrcline2,
+ mng_uint8p pDstline);
+
+/* ************************************************************************** */
+
+#endif /* _libmng_pixels_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_prop_xs.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_prop_xs.c
new file mode 100644
index 0000000..6cd823e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_prop_xs.c
@@ -0,0 +1,2357 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_prop_xs.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.4 * */
+/* * * */
+/* * purpose : property get/set interface (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the property get/set functions * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - fixed calling convention * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added set_outputprofile2 & set_srgbprofile2 * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * * */
+/* * 0.5.2 - 05/23/2000 - G.Juyn * */
+/* * - changed inclusion of cms-routines * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - added support for get/set default zlib/IJG parms * */
+/* * 0.5.2 - 05/31/2000 - G.Juyn * */
+/* * - fixed up punctuation (contribution by Tim Rowley) * */
+/* * 0.5.2 - 06/05/2000 - G.Juyn * */
+/* * - added support for RGB8_A8 canvasstyle * */
+/* * * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added get/set for speedtype to facilitate testing * */
+/* * - added get for imagelevel during processtext callback * */
+/* * 0.5.3 - 06/26/2000 - G.Juyn * */
+/* * - changed userdata variable to mng_ptr * */
+/* * 0.5.3 - 06/29/2000 - G.Juyn * */
+/* * - fixed incompatible return-types * */
+/* * * */
+/* * 0.9.1 - 07/08/2000 - G.Juyn * */
+/* * - added get routines for internal display variables * */
+/* * - added get/set routines for suspensionmode variable * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - added get/set routines for sectionbreak variable * */
+/* * * */
+/* * 0.9.2 - 07/31/2000 - G.Juyn * */
+/* * - added status_xxxx functions * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 10/10/2000 - G.Juyn * */
+/* * - added support for alpha-depth prediction * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added functions to retrieve PNG/JNG specific header-info * */
+/* * 0.9.3 - 10/20/2000 - G.Juyn * */
+/* * - added get/set for bKGD preference setting * */
+/* * 0.9.3 - 10/21/2000 - G.Juyn * */
+/* * - added get function for interlace/progressive display * */
+/* * * */
+/* * 1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly) * */
+/* * - added BGRA8 canvas with premultiplied alpha * */
+/* * 1.0.1 - 05/02/2001 - G.Juyn * */
+/* * - added "default" sRGB generation (Thanks Marti!) * */
+/* * * */
+/* * 1.0.2 - 06/23/2001 - G.Juyn * */
+/* * - added optimization option for MNG-video playback * */
+/* * 1.0.2 - 06/25/2001 - G.Juyn * */
+/* * - added option to turn off progressive refresh * */
+/* * * */
+/* * 1.0.3 - 08/06/2001 - G.Juyn * */
+/* * - added get function for last processed BACK chunk * */
+/* * * */
+/* * 1.0.4 - 06/22/2002 - G.Juyn * */
+/* * - B495442 - invalid returnvalue in mng_get_suspensionmode * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_cms.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Property set functions * */
+/* * * */
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_userdata (mng_handle hHandle,
+ mng_ptr pUserdata)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_USERDATA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->pUserdata = pUserdata;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_USERDATA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_canvasstyle (mng_handle hHandle,
+ mng_uint32 iStyle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_CANVASSTYLE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+
+ switch (iStyle)
+ {
+ case MNG_CANVAS_RGB8 : break;
+ case MNG_CANVAS_RGBA8 : break;
+ case MNG_CANVAS_ARGB8 : break;
+ case MNG_CANVAS_RGB8_A8 : break;
+ case MNG_CANVAS_BGR8 : break;
+ case MNG_CANVAS_BGRA8 : break;
+ case MNG_CANVAS_BGRA8PM : break;
+ case MNG_CANVAS_ABGR8 : break;
+/* case MNG_CANVAS_RGB16 : break; */
+/* case MNG_CANVAS_RGBA16 : break; */
+/* case MNG_CANVAS_ARGB16 : break; */
+/* case MNG_CANVAS_BGR16 : break; */
+/* case MNG_CANVAS_BGRA16 : break; */
+/* case MNG_CANVAS_ABGR16 : break; */
+/* case MNG_CANVAS_INDEX8 : break; */
+/* case MNG_CANVAS_INDEXA8 : break; */
+/* case MNG_CANVAS_AINDEX8 : break; */
+/* case MNG_CANVAS_GRAY8 : break; */
+/* case MNG_CANVAS_GRAY16 : break; */
+/* case MNG_CANVAS_GRAYA8 : break; */
+/* case MNG_CANVAS_GRAYA16 : break; */
+/* case MNG_CANVAS_AGRAY8 : break; */
+/* case MNG_CANVAS_AGRAY16 : break; */
+/* case MNG_CANVAS_DX15 : break; */
+/* case MNG_CANVAS_DX16 : break; */
+ default : { MNG_ERROR (((mng_datap)hHandle), MNG_INVALIDCNVSTYLE) }
+ }
+
+ ((mng_datap)hHandle)->iCanvasstyle = iStyle;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_CANVASSTYLE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_bkgdstyle (mng_handle hHandle,
+ mng_uint32 iStyle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_BKGDSTYLE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+
+ switch (iStyle) /* alpha-modes not supported */
+ {
+ case MNG_CANVAS_RGB8 : break;
+ case MNG_CANVAS_BGR8 : break;
+/* case MNG_CANVAS_RGB16 : break; */
+/* case MNG_CANVAS_BGR16 : break; */
+/* case MNG_CANVAS_INDEX8 : break; */
+/* case MNG_CANVAS_GRAY8 : break; */
+/* case MNG_CANVAS_GRAY16 : break; */
+/* case MNG_CANVAS_DX15 : break; */
+/* case MNG_CANVAS_DX16 : break; */
+ default : MNG_ERROR (((mng_datap)hHandle), MNG_INVALIDCNVSTYLE)
+ }
+
+ ((mng_datap)hHandle)->iBkgdstyle = iStyle;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_BKGDSTYLE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_bgcolor (mng_handle hHandle,
+ mng_uint16 iRed,
+ mng_uint16 iGreen,
+ mng_uint16 iBlue)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_BGCOLOR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iBGred = iRed;
+ ((mng_datap)hHandle)->iBGgreen = iGreen;
+ ((mng_datap)hHandle)->iBGblue = iBlue;
+ ((mng_datap)hHandle)->bUseBKGD = MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_BGCOLOR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_usebkgd (mng_handle hHandle,
+ mng_bool bUseBKGD)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_USEBKGD, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->bUseBKGD = bUseBKGD;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_USEBKGD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_storechunks (mng_handle hHandle,
+ mng_bool bStorechunks)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_STORECHUNKS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->bStorechunks = bStorechunks;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_STORECHUNKS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_sectionbreaks (mng_handle hHandle,
+ mng_bool bSectionbreaks)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SECTIONBREAKS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->bSectionbreaks = bSectionbreaks;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SECTIONBREAKS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_cacheplayback (mng_handle hHandle,
+ mng_bool bCacheplayback)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_CACHEPLAYBACK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+
+ if (((mng_datap)hHandle)->bHasheader)
+ MNG_ERROR (((mng_datap)hHandle), MNG_FUNCTIONINVALID)
+
+ ((mng_datap)hHandle)->bCacheplayback = bCacheplayback;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_CACHEPLAYBACK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_doprogressive (mng_handle hHandle,
+ mng_bool bDoProgressive)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DOPROGRESSIVE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+
+ ((mng_datap)hHandle)->bDoProgressive = bDoProgressive;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DOPROGRESSIVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_set_srgb (mng_handle hHandle,
+ mng_bool bIssRGB)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGB, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->bIssRGB = bIssRGB;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_set_outputprofile (mng_handle hHandle,
+ mng_pchar zFilename)
+{
+#ifdef MNG_INCLUDE_LCMS
+ mng_datap pData;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTPROFILE, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_LCMS
+ MNG_VALIDHANDLE (hHandle)
+
+ pData = (mng_datap)hHandle; /* address the structure */
+
+ if (pData->hProf2) /* previously defined ? */
+ mnglcms_freeprofile (pData->hProf2);
+ /* allocate new CMS profile handle */
+ pData->hProf2 = mnglcms_createfileprofile (zFilename);
+
+ if (!pData->hProf2) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+#endif /* MNG_INCLUDE_LCMS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTPROFILE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_set_outputprofile2 (mng_handle hHandle,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile)
+{
+#ifdef MNG_INCLUDE_LCMS
+ mng_datap pData;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTPROFILE2, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_LCMS
+ MNG_VALIDHANDLE (hHandle)
+
+ pData = (mng_datap)hHandle; /* address the structure */
+
+ if (pData->hProf2) /* previously defined ? */
+ mnglcms_freeprofile (pData->hProf2);
+ /* allocate new CMS profile handle */
+ pData->hProf2 = mnglcms_creatememprofile (iProfilesize, pProfile);
+
+ if (!pData->hProf2) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+#endif /* MNG_INCLUDE_LCMS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTPROFILE2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_outputsrgb (mng_handle hHandle)
+{
+#ifdef MNG_INCLUDE_LCMS
+ mng_datap pData;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTSRGB, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_LCMS
+ MNG_VALIDHANDLE (hHandle)
+
+ pData = (mng_datap)hHandle; /* address the structure */
+
+ if (pData->hProf2) /* previously defined ? */
+ mnglcms_freeprofile (pData->hProf2);
+ /* allocate new CMS profile handle */
+ pData->hProf2 = mnglcms_createsrgbprofile ();
+
+ if (!pData->hProf2) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+#endif /* MNG_INCLUDE_LCMS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_OUTPUTSRGB, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_set_srgbprofile (mng_handle hHandle,
+ mng_pchar zFilename)
+{
+#ifdef MNG_INCLUDE_LCMS
+ mng_datap pData;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBPROFILE2, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_LCMS
+ MNG_VALIDHANDLE (hHandle)
+
+ pData = (mng_datap)hHandle; /* address the structure */
+
+ if (pData->hProf3) /* previously defined ? */
+ mnglcms_freeprofile (pData->hProf3);
+ /* allocate new CMS profile handle */
+ pData->hProf3 = mnglcms_createfileprofile (zFilename);
+
+ if (!pData->hProf3) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+#endif /* MNG_INCLUDE_LCMS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBPROFILE2, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_set_srgbprofile2 (mng_handle hHandle,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile)
+{
+#ifdef MNG_INCLUDE_LCMS
+ mng_datap pData;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBPROFILE, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_LCMS
+ MNG_VALIDHANDLE (hHandle)
+
+ pData = (mng_datap)hHandle; /* address the structure */
+
+ if (pData->hProf3) /* previously defined ? */
+ mnglcms_freeprofile (pData->hProf3);
+ /* allocate new CMS profile handle */
+ pData->hProf3 = mnglcms_creatememprofile (iProfilesize, pProfile);
+
+ if (!pData->hProf3) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+#endif /* MNG_INCLUDE_LCMS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBPROFILE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_srgbimplicit (mng_handle hHandle)
+{
+#ifdef MNG_INCLUDE_LCMS
+ mng_datap pData;
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBIMPLICIT, MNG_LC_START)
+#endif
+
+#ifdef MNG_INCLUDE_LCMS
+ MNG_VALIDHANDLE (hHandle)
+
+ pData = (mng_datap)hHandle; /* address the structure */
+
+ if (pData->hProf3) /* previously defined ? */
+ mnglcms_freeprofile (pData->hProf3);
+ /* allocate new CMS profile handle */
+ pData->hProf3 = mnglcms_createsrgbprofile ();
+
+ if (!pData->hProf3) /* handle error ? */
+ MNG_ERRORL (pData, MNG_LCMS_NOHANDLE)
+#endif /* MNG_INCLUDE_LCMS */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SRGBIMPLICIT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_viewgamma (mng_handle hHandle,
+ mng_float dGamma)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_VIEWGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->dViewgamma = dGamma;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_VIEWGAMMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_displaygamma (mng_handle hHandle,
+ mng_float dGamma)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DISPLAYGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->dDisplaygamma = dGamma;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DISPLAYGAMMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_dfltimggamma (mng_handle hHandle,
+ mng_float dGamma)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DFLTIMGGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->dDfltimggamma = dGamma;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DFLTIMGGAMMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_viewgammaint (mng_handle hHandle,
+ mng_uint32 iGamma)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_VIEWGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->dViewgamma = (mng_float)iGamma / 100000;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_VIEWGAMMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_displaygammaint (mng_handle hHandle,
+ mng_uint32 iGamma)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DISPLAYGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->dDisplaygamma = (mng_float)iGamma / 100000;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DISPLAYGAMMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_dfltimggammaint (mng_handle hHandle,
+ mng_uint32 iGamma)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DFLTIMGGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->dDfltimggamma = (mng_float)iGamma / 100000;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_DFLTIMGGAMMA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_maxcanvaswidth (mng_handle hHandle,
+ mng_uint32 iMaxwidth)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASWIDTH, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iMaxwidth = iMaxwidth;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASWIDTH, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_maxcanvasheight (mng_handle hHandle,
+ mng_uint32 iMaxheight)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASHEIGHT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iMaxheight = iMaxheight;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASHEIGHT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_set_maxcanvassize (mng_handle hHandle,
+ mng_uint32 iMaxwidth,
+ mng_uint32 iMaxheight)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASSIZE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iMaxwidth = iMaxwidth;
+ ((mng_datap)hHandle)->iMaxheight = iMaxheight;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_MAXCANVASSIZE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_retcode MNG_DECL mng_set_zlib_level (mng_handle hHandle,
+ mng_int32 iZlevel)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_LEVEL, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iZlevel = iZlevel;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_LEVEL, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_retcode MNG_DECL mng_set_zlib_method (mng_handle hHandle,
+ mng_int32 iZmethod)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_METHOD, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iZmethod = iZmethod;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_METHOD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_retcode MNG_DECL mng_set_zlib_windowbits (mng_handle hHandle,
+ mng_int32 iZwindowbits)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_WINDOWBITS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iZwindowbits = iZwindowbits;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_WINDOWBITS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_retcode MNG_DECL mng_set_zlib_memlevel (mng_handle hHandle,
+ mng_int32 iZmemlevel)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_MEMLEVEL, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iZmemlevel = iZmemlevel;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_MEMLEVEL, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_retcode MNG_DECL mng_set_zlib_strategy (mng_handle hHandle,
+ mng_int32 iZstrategy)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_STRATEGY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iZstrategy = iZstrategy;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_STRATEGY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_retcode MNG_DECL mng_set_zlib_maxidat (mng_handle hHandle,
+ mng_uint32 iMaxIDAT)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_MAXIDAT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iMaxIDAT = iMaxIDAT;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_ZLIB_MAXIDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_retcode MNG_DECL mng_set_jpeg_dctmethod (mng_handle hHandle,
+ mngjpeg_dctmethod eJPEGdctmethod)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_DCTMETHOD, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->eJPEGdctmethod = eJPEGdctmethod;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_DCTMETHOD, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_retcode MNG_DECL mng_set_jpeg_quality (mng_handle hHandle,
+ mng_int32 iJPEGquality)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_TQUALITY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iJPEGquality = iJPEGquality;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_TQUALITY, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_retcode MNG_DECL mng_set_jpeg_smoothing (mng_handle hHandle,
+ mng_int32 iJPEGsmoothing)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_SMOOTHING, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iJPEGsmoothing = iJPEGsmoothing;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_SMOOTHING, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_retcode MNG_DECL mng_set_jpeg_progressive (mng_handle hHandle,
+ mng_bool bJPEGprogressive)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_PROGRESSIVE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->bJPEGcompressprogr = bJPEGprogressive;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_PROGRESSIVE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_retcode MNG_DECL mng_set_jpeg_optimized (mng_handle hHandle,
+ mng_bool bJPEGoptimized)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_OPTIMIZED, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->bJPEGcompressopt = bJPEGoptimized;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_OPTIMIZED, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_retcode MNG_DECL mng_set_jpeg_maxjdat (mng_handle hHandle,
+ mng_uint32 iMaxJDAT)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_MAXJDAT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iMaxJDAT = iMaxJDAT;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_JPEG_MAXJDAT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_retcode MNG_DECL mng_set_suspensionmode (mng_handle hHandle,
+ mng_bool bSuspensionmode)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SUSPENSIONMODE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+
+ if (((mng_datap)hHandle)->bReading) /* we must NOT be reading !!! */
+ MNG_ERROR ((mng_datap)hHandle, MNG_FUNCTIONINVALID)
+
+ ((mng_datap)hHandle)->bSuspensionmode = bSuspensionmode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SUSPENSIONMODE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode MNG_DECL mng_set_speed (mng_handle hHandle,
+ mng_speedtype iSpeed)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SPEED, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ ((mng_datap)hHandle)->iSpeed = iSpeed;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_SET_SPEED, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+/* * * */
+/* * Property get functions * */
+/* * * */
+/* ************************************************************************** */
+
+mng_ptr MNG_DECL mng_get_userdata (mng_handle hHandle)
+{ /* no tracing in here to prevent recursive calls */
+ MNG_VALIDHANDLEX (hHandle)
+ return ((mng_datap)hHandle)->pUserdata;
+}
+
+/* ************************************************************************** */
+
+mng_imgtype MNG_DECL mng_get_sigtype (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SIGTYPE, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return mng_it_unknown;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SIGTYPE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->eSigtype;
+}
+
+/* ************************************************************************** */
+
+mng_imgtype MNG_DECL mng_get_imagetype (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGETYPE, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return mng_it_unknown;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGETYPE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->eImagetype;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_imagewidth (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGEWIDTH, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGEWIDTH, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iWidth;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_imageheight (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGEWIDTH, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGEHEIGHT, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iHeight;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_ticks (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_TICKS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_TICKS, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iTicks;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_framecount (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_FRAMECOUNT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_FRAMECOUNT, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iFramecount;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_layercount (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_LAYERCOUNT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_LAYERCOUNT, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iLayercount;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_playtime (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_PLAYTIME, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_PLAYTIME, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iPlaytime;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_simplicity (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SIMPLICITY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SIMPLICITY, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iSimplicity;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_bitdepth (mng_handle hHandle)
+{
+ mng_uint8 iRslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_BITDEPTH, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ if (((mng_datap)hHandle)->eImagetype == mng_it_png)
+ iRslt = ((mng_datap)hHandle)->iBitdepth;
+ else
+ if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
+ iRslt = ((mng_datap)hHandle)->iJHDRimgbitdepth;
+ else
+ iRslt = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_BITDEPTH, MNG_LC_END)
+#endif
+
+ return iRslt;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_colortype (mng_handle hHandle)
+{
+ mng_uint8 iRslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_COLORTYPE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ if (((mng_datap)hHandle)->eImagetype == mng_it_png)
+ iRslt = ((mng_datap)hHandle)->iColortype;
+ else
+ if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
+ iRslt = ((mng_datap)hHandle)->iJHDRcolortype;
+ else
+ iRslt = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_COLORTYPE, MNG_LC_END)
+#endif
+
+ return iRslt;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_compression (mng_handle hHandle)
+{
+ mng_uint8 iRslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_COMPRESSION, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ if (((mng_datap)hHandle)->eImagetype == mng_it_png)
+ iRslt = ((mng_datap)hHandle)->iCompression;
+ else
+ if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
+ iRslt = ((mng_datap)hHandle)->iJHDRimgcompression;
+ else
+ iRslt = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_COMPRESSION, MNG_LC_END)
+#endif
+
+ return iRslt;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_filter (mng_handle hHandle)
+{
+ mng_uint8 iRslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_FILTER, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ if (((mng_datap)hHandle)->eImagetype == mng_it_png)
+ iRslt = ((mng_datap)hHandle)->iFilter;
+ else
+ iRslt = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_FILTER, MNG_LC_END)
+#endif
+
+ return iRslt;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_interlace (mng_handle hHandle)
+{
+ mng_uint8 iRslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_INTERLACE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ if (((mng_datap)hHandle)->eImagetype == mng_it_png)
+ iRslt = ((mng_datap)hHandle)->iInterlace;
+ else
+ if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
+ iRslt = ((mng_datap)hHandle)->iJHDRimginterlace;
+ else
+ iRslt = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_INTERLACE, MNG_LC_END)
+#endif
+
+ return iRslt;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_alphabitdepth (mng_handle hHandle)
+{
+ mng_uint8 iRslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHABITDEPTH, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
+ iRslt = ((mng_datap)hHandle)->iJHDRalphabitdepth;
+ else
+ iRslt = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHABITDEPTH, MNG_LC_END)
+#endif
+
+ return iRslt;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_refreshpass (mng_handle hHandle)
+{
+ mng_uint8 iRslt;
+ mng_datap pData;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_REFRESHPASS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ pData = (mng_datap)hHandle;
+ /* for PNG we know the exact pass */
+ if ((pData->eImagetype == mng_it_png) && (pData->iPass >= 0))
+ iRslt = pData->iPass;
+#ifdef MNG_INCLUDE_JNG
+ else /* for JNG we'll fake it... */
+ if ((pData->eImagetype == mng_it_jng) &&
+ (pData->bJPEGhasheader) && (pData->bJPEGdecostarted) &&
+ (pData->bJPEGprogressive))
+ {
+ if (pData->pJPEGdinfo->input_scan_number <= 1)
+ iRslt = 0; /* first pass (I think...) */
+ else
+ if (jpeg_input_complete (pData->pJPEGdinfo))
+ iRslt = 7; /* input complete; aka final pass */
+ else
+ iRslt = 3; /* anything between 0 and 7 will do */
+
+ }
+#endif
+ else
+ iRslt = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_REFRESHPASS, MNG_LC_END)
+#endif
+
+ return iRslt;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_alphacompression (mng_handle hHandle)
+{
+ mng_uint8 iRslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHACOMPRESSION, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
+ iRslt = ((mng_datap)hHandle)->iJHDRalphacompression;
+ else
+ iRslt = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHACOMPRESSION, MNG_LC_END)
+#endif
+
+ return iRslt;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_alphafilter (mng_handle hHandle)
+{
+ mng_uint8 iRslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHAFILTER, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
+ iRslt = ((mng_datap)hHandle)->iJHDRalphafilter;
+ else
+ iRslt = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHAFILTER, MNG_LC_END)
+#endif
+
+ return iRslt;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_alphainterlace (mng_handle hHandle)
+{
+ mng_uint8 iRslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHAINTERLACE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ if (((mng_datap)hHandle)->eImagetype == mng_it_jng)
+ iRslt = ((mng_datap)hHandle)->iJHDRalphainterlace;
+ else
+ iRslt = 0;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHAINTERLACE, MNG_LC_END)
+#endif
+
+ return iRslt;
+}
+
+/* ************************************************************************** */
+
+mng_uint8 MNG_DECL mng_get_alphadepth (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHADEPTH, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ALPHADEPTH, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iAlphadepth;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_canvasstyle (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CANVASSTYLE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CANVASSTYLE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iCanvasstyle;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_bkgdstyle (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_BKGDSTYLE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_BKGDSTYLE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iBkgdstyle;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_get_bgcolor (mng_handle hHandle,
+ mng_uint16* iRed,
+ mng_uint16* iGreen,
+ mng_uint16* iBlue)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GET_BGCOLOR, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLE (hHandle)
+ *iRed = ((mng_datap)hHandle)->iBGred;
+ *iGreen = ((mng_datap)hHandle)->iBGgreen;
+ *iBlue = ((mng_datap)hHandle)->iBGblue;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (((mng_datap)hHandle), MNG_FN_GET_BGCOLOR, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_bool MNG_DECL mng_get_usebkgd (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_USEBKGD, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_USEBKGD, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bUseBKGD;
+}
+
+/* ************************************************************************** */
+
+mng_bool MNG_DECL mng_get_storechunks (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_STORECHUNKS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_STORECHUNKS, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bStorechunks;
+}
+
+/* ************************************************************************** */
+
+mng_bool MNG_DECL mng_get_sectionbreaks (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_SECTIONBREAKS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_SECTIONBREAKS, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bSectionbreaks;
+}
+
+/* ************************************************************************** */
+
+mng_bool MNG_DECL mng_get_cacheplayback (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_CACHEPLAYBACK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_CACHEPLAYBACK, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bCacheplayback;
+}
+
+/* ************************************************************************** */
+
+mng_bool MNG_DECL mng_get_doprogressive (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_DOPROGRESSIVE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_DOPROGRESSIVE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bDoProgressive;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_bool MNG_DECL mng_get_srgb (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_SRGB, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEB (((mng_datap)hHandle), MNG_FN_GET_SRGB, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bIssRGB;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+mng_float MNG_DECL mng_get_viewgamma (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_VIEWGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_VIEWGAMMA, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->dViewgamma;
+}
+
+/* ************************************************************************** */
+
+mng_float MNG_DECL mng_get_displaygamma (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DISPLAYGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DISPLAYGAMMA, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->dDisplaygamma;
+}
+
+/* ************************************************************************** */
+
+mng_float MNG_DECL mng_get_dfltimggamma (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DFLTIMGGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DFLTIMGGAMMA, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->dDfltimggamma;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_viewgammaint (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_VIEWGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_VIEWGAMMA, MNG_LC_END)
+#endif
+
+ return (mng_uint32)(((mng_datap)hHandle)->dViewgamma * 100000);
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_displaygammaint (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DISPLAYGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DISPLAYGAMMA, MNG_LC_END)
+#endif
+
+ return (mng_uint32)(((mng_datap)hHandle)->dDisplaygamma * 100000);
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_dfltimggammaint (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DFLTIMGGAMMA, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_DFLTIMGGAMMA, MNG_LC_END)
+#endif
+
+ return (mng_uint32)(((mng_datap)hHandle)->dDfltimggamma * 100000);
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_maxcanvaswidth (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_MAXCANVASWIDTH, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_MAXCANVASWIDTH, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iMaxwidth;
+}
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_maxcanvasheight (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_MAXCANVASHEIGHT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_MAXCANVASHEIGHT, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iMaxheight;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_int32 MNG_DECL mng_get_zlib_level (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_LEVEL, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_LEVEL, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iZlevel;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_int32 MNG_DECL mng_get_zlib_method (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_METHOD, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_METHOD, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iZmethod;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_int32 MNG_DECL mng_get_zlib_windowbits (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_WINDOWBITS, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_WINDOWBITS, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iZwindowbits;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_int32 MNG_DECL mng_get_zlib_memlevel (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_MEMLEVEL, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_MEMLEVEL, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iZmemlevel;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_int32 MNG_DECL mng_get_zlib_strategy (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_STRATEGY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_STRATEGY, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iZstrategy;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+mng_uint32 MNG_DECL mng_get_zlib_maxidat (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_MAXIDAT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_ZLIB_MAXIDAT, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iMaxIDAT;
+}
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mngjpeg_dctmethod MNG_DECL mng_get_jpeg_dctmethod (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_DCTMETHOD, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return JDCT_ISLOW;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_DCTMETHOD, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->eJPEGdctmethod;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_int32 MNG_DECL mng_get_jpeg_quality (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_TQUALITY, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_TQUALITY, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iJPEGquality;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_int32 MNG_DECL mng_get_jpeg_smoothing (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_SMOOTHING, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_SMOOTHING, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iJPEGsmoothing;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_bool MNG_DECL mng_get_jpeg_progressive (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_PROGRESSIVE, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_PROGRESSIVE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bJPEGcompressprogr;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_bool MNG_DECL mng_get_jpeg_optimized (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_OPTIMIZED, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_OPTIMIZED, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bJPEGcompressopt;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+mng_uint32 MNG_DECL mng_get_jpeg_maxjdat (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_MAXJDAT, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_JPEG_MAXJDAT, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iMaxJDAT;
+}
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_bool MNG_DECL mng_get_suspensionmode (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SUSPENSIONMODE, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SUSPENSIONMODE, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bSuspensionmode;
+}
+#endif /* MNG_SUPPORT_READ */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_speedtype MNG_DECL mng_get_speed (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SPEED, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return mng_st_normal;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_SPEED, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iSpeed;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+mng_uint32 MNG_DECL mng_get_imagelevel (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGELEVEL, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_IMAGELEVEL, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iImagelevel;
+}
+
+/* ************************************************************************** */
+
+mng_retcode MNG_DECL mng_get_lastbackchunk (mng_handle hHandle,
+ mng_uint16* iRed,
+ mng_uint16* iGreen,
+ mng_uint16* iBlue,
+ mng_uint8* iMandatory)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_LASTBACKCHUNK, MNG_LC_START)
+#endif
+
+ MNG_VALIDHANDLEX (hHandle)
+
+ if (((mng_datap)hHandle)->eImagetype != mng_it_mng)
+ MNG_ERROR (((mng_datap)hHandle), MNG_FUNCTIONINVALID)
+
+ *iRed = ((mng_datap)hHandle)->iBACKred;
+ *iGreen = ((mng_datap)hHandle)->iBACKgreen;
+ *iBlue = ((mng_datap)hHandle)->iBACKblue;
+ *iMandatory = ((mng_datap)hHandle)->iBACKmandatory;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_LASTBACKCHUNK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_uint32 MNG_DECL mng_get_starttime (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_STARTTIME, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return mng_st_normal;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_STARTTIME, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iStarttime;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_uint32 MNG_DECL mng_get_runtime (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_RUNTIME, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return mng_st_normal;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_RUNTIME, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iRuntime;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_uint32 MNG_DECL mng_get_currentframe (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTFRAME, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return mng_st_normal;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTFRAME, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iFrameseq;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_uint32 MNG_DECL mng_get_currentlayer (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTLAYER, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return mng_st_normal;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTLAYER, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iLayerseq;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_uint32 MNG_DECL mng_get_currentplaytime (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTPLAYTIME, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return mng_st_normal;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_GET_CURRENTPLAYTIME, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->iFrametime;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+mng_bool MNG_DECL mng_status_error (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_ERROR, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_ERROR, MNG_LC_END)
+#endif
+
+ return (mng_bool)((mng_datap)hHandle)->iErrorcode;
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_bool MNG_DECL mng_status_reading (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_READING, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_READING, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bReading;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_READ
+mng_bool MNG_DECL mng_status_suspendbreak (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_SUSPENDBREAK, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_SUSPENDBREAK, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bSuspended;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_WRITE
+mng_bool MNG_DECL mng_status_creating (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_CREATING, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_CREATING, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bCreating;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_WRITE
+mng_bool MNG_DECL mng_status_writing (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_WRITING, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_WRITING, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bWriting;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_bool MNG_DECL mng_status_displaying (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_DISPLAYING, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_DISPLAYING, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bDisplaying;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_bool MNG_DECL mng_status_running (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_RUNNING, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_RUNNING, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bRunning;
+}
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_bool MNG_DECL mng_status_timerbreak (mng_handle hHandle)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_TIMERBREAK, MNG_LC_START)
+#endif
+
+ if ((hHandle == 0) || (((mng_datap)hHandle)->iMagic != MNG_MAGIC))
+ return MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACEX (((mng_datap)hHandle), MNG_FN_STATUS_TIMERBREAK, MNG_LC_END)
+#endif
+
+ return ((mng_datap)hHandle)->bTimerset;
+}
+#endif
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_read.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_read.c
new file mode 100644
index 0000000..e907ad7
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_read.c
@@ -0,0 +1,696 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_read.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.4 * */
+/* * * */
+/* * purpose : Read logic (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the high-level read logic * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - added callback error-reporting support * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * * */
+/* * 0.5.2 - 05/19/2000 - G.Juyn * */
+/* * - cleaned up some code regarding mixed support * */
+/* * 0.5.2 - 05/20/2000 - G.Juyn * */
+/* * - added support for JNG * */
+/* * 0.5.2 - 05/31/2000 - G.Juyn * */
+/* * - fixed up punctuation (contribution by Tim Rowley) * */
+/* * * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - changed progressive-display processing * */
+/* * * */
+/* * 0.9.1 - 07/08/2000 - G.Juyn * */
+/* * - changed read-processing for improved I/O-suspension * */
+/* * 0.9.1 - 07/14/2000 - G.Juyn * */
+/* * - changed EOF processing behavior * */
+/* * 0.9.1 - 07/14/2000 - G.Juyn * */
+/* * - changed default readbuffer size from 1024 to 4200 * */
+/* * * */
+/* * 0.9.2 - 07/27/2000 - G.Juyn * */
+/* * - B110320 - fixed GCC warning about mix-sized pointer math * */
+/* * 0.9.2 - 07/31/2000 - G.Juyn * */
+/* * - B110546 - fixed for improperly returning UNEXPECTEDEOF * */
+/* * 0.9.2 - 08/04/2000 - G.Juyn * */
+/* * - B111096 - fixed large-buffer read-suspension * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - removed test-MaGN * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added support for JDAA * */
+/* * * */
+/* * 0.9.5 - 01/23/2001 - G.Juyn * */
+/* * - fixed timing-problem with switching framing_modes * */
+/* * * */
+/* * 1.0.4 - 06/22/2002 - G.Juyn * */
+/* * - B495443 - incorrect suspend check in read_databuffer * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_memory.h"
+#include "libmng_objects.h"
+#include "libmng_object_prc.h"
+#include "libmng_chunks.h"
+#include "libmng_chunk_prc.h"
+#include "libmng_chunk_io.h"
+#include "libmng_display.h"
+#include "libmng_read.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_READ_PROCS
+
+/* ************************************************************************** */
+
+mng_retcode process_eof (mng_datap pData)
+{
+ if (!pData->bEOF) /* haven't closed the stream yet ? */
+ {
+ pData->bEOF = MNG_TRUE; /* now we do! */
+
+ if (!pData->fClosestream ((mng_handle)pData))
+ MNG_ERROR (pData, MNG_APPIOERROR)
+ }
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode read_databuffer (mng_datap pData,
+ mng_uint8p pBuf,
+ mng_uint32 iSize,
+ mng_uint32 * iRead)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DATABUFFER, MNG_LC_START)
+#endif
+
+ if (pData->bSuspensionmode)
+ {
+ mng_uint8p pTemp;
+ mng_uint32 iTemp;
+
+ *iRead = 0; /* let's be negative about the outcome */
+
+ if (!pData->pSuspendbuf) /* need to create a suspension buffer ? */
+ {
+ pData->iSuspendbufsize = MNG_SUSPENDBUFFERSIZE;
+ /* so, create it */
+ MNG_ALLOC (pData, pData->pSuspendbuf, pData->iSuspendbufsize)
+
+ pData->iSuspendbufleft = 0; /* make sure to fill it first time */
+ pData->pSuspendbufnext = pData->pSuspendbuf;
+ }
+ /* more than our buffer can hold ? */
+ if (iSize > pData->iSuspendbufsize)
+ {
+ mng_uint32 iRemain;
+
+ if (!pData->pReadbufnext) /* first time ? */
+ {
+ if (pData->iSuspendbufleft) /* do we have some data left ? */
+ { /* then copy it */
+ MNG_COPY (pBuf, pData->pSuspendbufnext, pData->iSuspendbufleft)
+ /* fixup variables */
+ pData->pReadbufnext = pBuf + pData->iSuspendbufleft;
+ pData->pSuspendbufnext = pData->pSuspendbuf;
+ pData->iSuspendbufleft = 0;
+ }
+ else
+ {
+ pData->pReadbufnext = pBuf;
+ }
+ }
+ /* calculate how much to get */
+ iRemain = iSize - (mng_uint32)(pData->pReadbufnext - pBuf);
+ /* let's go get it */
+ if (!pData->fReaddata (((mng_handle)pData), pData->pReadbufnext, iRemain, &iTemp))
+ MNG_ERROR (pData, MNG_APPIOERROR);
+ /* first read after suspension return 0 means EOF */
+ if ((pData->iSuspendpoint) && (iTemp == 0))
+ { /* that makes it final */
+ mng_retcode iRetcode = process_eof (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ /* indicate the source is depleted */
+ *iRead = iSize - iRemain + iTemp;
+ }
+ else
+ {
+ if (iTemp < iRemain) /* suspension required ? */
+ {
+ pData->pReadbufnext = pData->pReadbufnext + iTemp;
+ pData->bSuspended = MNG_TRUE;
+ }
+ else
+ {
+ *iRead = iSize; /* got it all now ! */
+ }
+ }
+ }
+ else
+ { /* need to read some more ? */
+ while ((!pData->bSuspended) && (!pData->bEOF) && (iSize > pData->iSuspendbufleft))
+ { /* not enough space left in buffer ? */
+ if (pData->iSuspendbufsize - pData->iSuspendbufleft -
+ (mng_uint32)(pData->pSuspendbufnext - pData->pSuspendbuf) <
+ MNG_SUSPENDRETQUESTSIZE)
+ {
+ if (pData->iSuspendbufleft) /* then lets shift (if there's anything left) */
+ MNG_COPY (pData->pSuspendbuf, pData->pSuspendbufnext, pData->iSuspendbufleft)
+ /* adjust running pointer */
+ pData->pSuspendbufnext = pData->pSuspendbuf;
+ }
+ /* still not enough room ? */
+ if (pData->iSuspendbufsize - pData->iSuspendbufleft < MNG_SUSPENDRETQUESTSIZE)
+ MNG_ERROR (pData, MNG_INTERNALERROR)
+ /* now read some more data */
+ pTemp = pData->pSuspendbufnext + pData->iSuspendbufleft;
+
+ if (!pData->fReaddata (((mng_handle)pData), pTemp, MNG_SUSPENDRETQUESTSIZE, &iTemp))
+ MNG_ERROR (pData, MNG_APPIOERROR);
+ /* adjust fill-counter */
+ pData->iSuspendbufleft += iTemp;
+ /* first read after suspension returning 0 means EOF */
+ if ((pData->iSuspendpoint) && (iTemp == 0))
+ { /* that makes it final */
+ mng_retcode iRetcode = process_eof (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if (pData->iSuspendbufleft) /* return the leftover scraps */
+ MNG_COPY (pBuf, pData->pSuspendbufnext, pData->iSuspendbufleft)
+ /* and indicate so */
+ *iRead = pData->iSuspendbufleft;
+ pData->pSuspendbufnext = pData->pSuspendbuf;
+ pData->iSuspendbufleft = 0;
+ }
+ else
+ { /* suspension required ? */
+ if ((iSize > pData->iSuspendbufleft) && (iTemp < MNG_SUSPENDRETQUESTSIZE))
+ pData->bSuspended = MNG_TRUE;
+
+ }
+
+ pData->iSuspendpoint = 0; /* reset it here in case we loop back */
+ }
+
+ if ((!pData->bSuspended) && (!pData->bEOF))
+ { /* return the data ! */
+ MNG_COPY (pBuf, pData->pSuspendbufnext, iSize)
+
+ *iRead = iSize; /* returned it all */
+ /* adjust suspension-buffer variables */
+ pData->pSuspendbufnext += iSize;
+ pData->iSuspendbufleft -= iSize;
+ }
+ }
+ }
+ else
+ {
+ if (!pData->fReaddata (((mng_handle)pData), (mng_ptr)pBuf, iSize, iRead))
+ {
+ if (*iRead == 0) /* suspension required ? */
+ pData->bSuspended = MNG_TRUE;
+ else
+ MNG_ERROR (pData, MNG_APPIOERROR);
+ }
+ }
+
+ pData->iSuspendpoint = 0; /* safely reset it here ! */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_DATABUFFER, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode process_raw_chunk (mng_datap pData,
+ mng_uint8p pBuf,
+ mng_uint32 iBuflen)
+{
+ /* the table-idea & binary search code was adapted from
+ libpng 1.1.0 (pngread.c) */
+ /* NOTE1: the table must remain sorted by chunkname, otherwise the binary
+ search will break !!! */
+ /* NOTE2: the tqlayout must remain equal to the header part of all the
+ chunk-structures (yes, that means even the pNext and pPrev fields;
+ it's wasting a bit of space, but hey, the code is a lot easier) */
+
+ mng_chunk_header chunk_unknown = {MNG_UINT_HUH, init_unknown, free_unknown,
+ read_unknown, write_unknown, 0, 0};
+
+ mng_chunk_header chunk_table [] =
+ {
+ {MNG_UINT_BACK, init_back, free_back, read_back, write_back, 0, 0},
+ {MNG_UINT_BASI, init_basi, free_basi, read_basi, write_basi, 0, 0},
+ {MNG_UINT_CLIP, init_clip, free_clip, read_clip, write_clip, 0, 0},
+ {MNG_UINT_CLON, init_clon, free_clon, read_clon, write_clon, 0, 0},
+ {MNG_UINT_DBYK, init_dbyk, free_dbyk, read_dbyk, write_dbyk, 0, 0},
+ {MNG_UINT_DEFI, init_defi, free_defi, read_defi, write_defi, 0, 0},
+ {MNG_UINT_DHDR, init_dhdr, free_dhdr, read_dhdr, write_dhdr, 0, 0},
+ {MNG_UINT_DISC, init_disc, free_disc, read_disc, write_disc, 0, 0},
+ {MNG_UINT_DROP, init_drop, free_drop, read_drop, write_drop, 0, 0},
+ {MNG_UINT_ENDL, init_endl, free_endl, read_endl, write_endl, 0, 0},
+ {MNG_UINT_FRAM, init_fram, free_fram, read_fram, write_fram, 0, 0},
+ {MNG_UINT_IDAT, init_idat, free_idat, read_idat, write_idat, 0, 0}, /* 12-th element! */
+ {MNG_UINT_IEND, init_iend, free_iend, read_iend, write_iend, 0, 0},
+ {MNG_UINT_IHDR, init_ihdr, free_ihdr, read_ihdr, write_ihdr, 0, 0},
+ {MNG_UINT_IJNG, init_ijng, free_ijng, read_ijng, write_ijng, 0, 0},
+ {MNG_UINT_IPNG, init_ipng, free_ipng, read_ipng, write_ipng, 0, 0},
+#ifdef MNG_INCLUDE_JNG
+ {MNG_UINT_JDAA, init_jdaa, free_jdaa, read_jdaa, write_jdaa, 0, 0},
+ {MNG_UINT_JDAT, init_jdat, free_jdat, read_jdat, write_jdat, 0, 0},
+ {MNG_UINT_JHDR, init_jhdr, free_jhdr, read_jhdr, write_jhdr, 0, 0},
+ {MNG_UINT_JSEP, init_jsep, free_jsep, read_jsep, write_jsep, 0, 0},
+ {MNG_UINT_JdAA, init_jdaa, free_jdaa, read_jdaa, write_jdaa, 0, 0},
+#endif
+ {MNG_UINT_LOOP, init_loop, free_loop, read_loop, write_loop, 0, 0},
+ {MNG_UINT_MAGN, init_magn, free_magn, read_magn, write_magn, 0, 0},
+ {MNG_UINT_MEND, init_mend, free_mend, read_mend, write_mend, 0, 0},
+ {MNG_UINT_MHDR, init_mhdr, free_mhdr, read_mhdr, write_mhdr, 0, 0},
+ {MNG_UINT_MOVE, init_move, free_move, read_move, write_move, 0, 0},
+ {MNG_UINT_ORDR, init_ordr, free_ordr, read_ordr, write_ordr, 0, 0},
+ {MNG_UINT_PAST, init_past, free_past, read_past, write_past, 0, 0},
+ {MNG_UINT_PLTE, init_plte, free_plte, read_plte, write_plte, 0, 0},
+ {MNG_UINT_PPLT, init_pplt, free_pplt, read_pplt, write_pplt, 0, 0},
+ {MNG_UINT_PROM, init_prom, free_prom, read_prom, write_prom, 0, 0},
+ {MNG_UINT_SAVE, init_save, free_save, read_save, write_save, 0, 0},
+ {MNG_UINT_SEEK, init_seek, free_seek, read_seek, write_seek, 0, 0},
+ {MNG_UINT_SHOW, init_show, free_show, read_show, write_show, 0, 0},
+ {MNG_UINT_TERM, init_term, free_term, read_term, write_term, 0, 0},
+ {MNG_UINT_bKGD, init_bkgd, free_bkgd, read_bkgd, write_bkgd, 0, 0},
+ {MNG_UINT_cHRM, init_chrm, free_chrm, read_chrm, write_chrm, 0, 0},
+ {MNG_UINT_eXPI, init_expi, free_expi, read_expi, write_expi, 0, 0},
+ {MNG_UINT_fPRI, init_fpri, free_fpri, read_fpri, write_fpri, 0, 0},
+ {MNG_UINT_gAMA, init_gama, free_gama, read_gama, write_gama, 0, 0},
+ {MNG_UINT_hIST, init_hist, free_hist, read_hist, write_hist, 0, 0},
+ {MNG_UINT_iCCP, init_iccp, free_iccp, read_iccp, write_iccp, 0, 0},
+ {MNG_UINT_iTXt, init_itxt, free_itxt, read_itxt, write_itxt, 0, 0},
+ {MNG_UINT_nEED, init_need, free_need, read_need, write_need, 0, 0},
+/* TODO: {MNG_UINT_oFFs, 0, 0, 0, 0, 0, 0}, */
+/* TODO: {MNG_UINT_pCAL, 0, 0, 0, 0, 0, 0}, */
+ {MNG_UINT_pHYg, init_phyg, free_phyg, read_phyg, write_phyg, 0, 0},
+ {MNG_UINT_pHYs, init_phys, free_phys, read_phys, write_phys, 0, 0},
+ {MNG_UINT_sBIT, init_sbit, free_sbit, read_sbit, write_sbit, 0, 0},
+/* TODO: {MNG_UINT_sCAL, 0, 0, 0, 0, 0, 0}, */
+ {MNG_UINT_sPLT, init_splt, free_splt, read_splt, write_splt, 0, 0},
+ {MNG_UINT_sRGB, init_srgb, free_srgb, read_srgb, write_srgb, 0, 0},
+ {MNG_UINT_tEXt, init_text, free_text, read_text, write_text, 0, 0},
+ {MNG_UINT_tIME, init_time, free_time, read_time, write_time, 0, 0},
+ {MNG_UINT_tRNS, init_trns, free_trns, read_trns, write_trns, 0, 0},
+ {MNG_UINT_zTXt, init_ztxt, free_ztxt, read_ztxt, write_ztxt, 0, 0},
+ };
+ /* binary search variables */
+ mng_int32 iTop, iLower, iUpper, iMiddle;
+ mng_chunk_headerp pEntry; /* pointer to found entry */
+ mng_chunkid iChunkname; /* the chunk's tag */
+ mng_chunkp pChunk; /* chunk structure (if #define MNG_STORE_CHUNKS) */
+ mng_retcode iRetcode; /* temporary error-code */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RAW_CHUNK, MNG_LC_START)
+#endif
+ /* get the chunkname */
+ iChunkname = (mng_chunkid)(mng_get_uint32 (pBuf));
+
+ pBuf += sizeof (mng_chunkid); /* adjust the buffer */
+ iBuflen -= sizeof (mng_chunkid);
+ /* determine max index of table */
+ iTop = (sizeof (chunk_table) / sizeof (chunk_table [0])) - 1;
+
+ /* binary search; with 52 chunks, worst-case is 7 comparisons */
+ iLower = 0;
+ iMiddle = 11; /* start with the IDAT entry */
+ iUpper = iTop;
+ pEntry = 0; /* no goods yet! */
+ pChunk = 0;
+
+ do /* the binary search itself */
+ {
+ if (chunk_table [iMiddle].iChunkname < iChunkname)
+ iLower = iMiddle + 1;
+ else if (chunk_table [iMiddle].iChunkname > iChunkname)
+ iUpper = iMiddle - 1;
+ else
+ {
+ pEntry = &chunk_table [iMiddle];
+ break;
+ }
+
+ iMiddle = (iLower + iUpper) >> 1;
+ }
+ while (iLower <= iUpper);
+
+ if (!pEntry) /* unknown chunk ? */
+ pEntry = &chunk_unknown; /* make it so! */
+
+ pData->iChunkname = iChunkname; /* keep track of where we are */
+ pData->iChunkseq++;
+
+ if (pEntry->fRead) /* read-callback available ? */
+ {
+ iRetcode = pEntry->fRead (pData, pEntry, iBuflen, (mng_ptr)pBuf, &pChunk);
+
+ if (!iRetcode) /* everything oke ? */
+ { /* remember unknown chunk's id */
+ if ((pChunk) && (pEntry == &chunk_unknown))
+ ((mng_chunk_headerp)pChunk)->iChunkname = iChunkname;
+ }
+ }
+ else
+ iRetcode = MNG_NOERROR;
+
+ if (pChunk) /* store this chunk ? */
+ add_chunk (pData, pChunk); /* do it */
+
+#ifdef MNG_INCLUDE_JNG /* implicit EOF ? */
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR) && (!pData->bHasJHDR))
+#else
+ if ((!pData->bHasMHDR) && (!pData->bHasIHDR))
+#endif
+ iRetcode = process_eof (pData); /* then do some EOF processing */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_PROCESS_RAW_CHUNK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode read_chunk (mng_datap pData)
+{
+ mng_uint32 iBufmax = pData->iReadbufsize;
+ mng_uint8p pBuf = pData->pReadbuf;
+ mng_uint32 iBuflen = 0; /* number of bytes requested */
+ mng_uint32 iRead = 0; /* number of bytes read */
+ mng_uint32 iCrc; /* calculated CRC */
+ mng_retcode iRetcode = MNG_NOERROR;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_CHUNK, MNG_LC_START)
+#endif
+
+#ifdef MNG_SUPPORT_DISPLAY
+ if (pData->pCurraniobj) /* processing an animation object ? */
+ {
+ do /* process it then */
+ {
+ iRetcode = ((mng_object_headerp)pData->pCurraniobj)->fProcess (pData, pData->pCurraniobj);
+ /* refresh needed ? */
+/* if ((!iRetcode) && (!pData->bTimerset) && (pData->bNeedrefresh))
+ iRetcode = display_progressive_refresh (pData, 1); */
+ /* can we advance to next object ? */
+ if ((!iRetcode) && (pData->pCurraniobj) &&
+ (!pData->bTimerset) && (!pData->bSectionwait))
+ {
+ pData->pCurraniobj = ((mng_object_headerp)pData->pCurraniobj)->pNext;
+ /* TERM processing to be done ? */
+ if ((!pData->pCurraniobj) && (pData->bHasTERM) && (!pData->bHasMHDR))
+ iRetcode = process_display_mend (pData);
+ }
+ } /* until error or a break or no more objects */
+ while ((!iRetcode) && (pData->pCurraniobj) &&
+ (!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bFreezing));
+ }
+ else
+ {
+ if (pData->iBreakpoint) /* do we need to finish something first ? */
+ {
+ switch (pData->iBreakpoint) /* return to broken display routine */
+ {
+ case 1 : { iRetcode = process_display_fram2 (pData); break; }
+ case 2 : { iRetcode = process_display_ihdr (pData); break; }
+ case 3 : ; /* same as 4 !!! */
+ case 4 : { iRetcode = process_display_show (pData); break; }
+ case 5 : { iRetcode = process_display_clon2 (pData); break; }
+#ifdef MNG_INCLUDE_JNG
+ case 7 : { iRetcode = process_display_jhdr (pData); break; }
+#endif
+ case 6 : ; /* same as 8 !!! */
+ case 8 : { iRetcode = process_display_iend (pData); break; }
+ case 9 : { iRetcode = process_display_magn2 (pData); break; }
+ }
+ }
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+#endif /* MNG_SUPPORT_DISPLAY */
+ /* can we continue processing now, or do we */
+ /* need to wait for the timer to finish (again) ? */
+#ifdef MNG_SUPPORT_DISPLAY
+ if ((!pData->bTimerset) && (!pData->bSectionwait) && (!pData->bEOF))
+#else
+ if (!pData->bEOF)
+#endif
+ { /* freezing in progress ? */
+ if ((pData->bFreezing) && (pData->iSuspendpoint == 0))
+ pData->bRunning = MNG_FALSE; /* then this is the right moment to do it */
+
+ if (pData->iSuspendpoint <= 2)
+ {
+ iBuflen = sizeof (mng_uint32); /* read length */
+ iRetcode = read_databuffer (pData, pBuf, iBuflen, &iRead);
+
+ if (iRetcode) /* bail on errors */
+ return iRetcode;
+
+ if (pData->bSuspended) /* suspended ? */
+ pData->iSuspendpoint = 2;
+ else /* save the length */
+ pData->iChunklen = mng_get_uint32 (pBuf);
+
+ }
+
+ if (!pData->bSuspended) /* still going ? */
+ { /* previously suspended or not eof ? */
+ if ((pData->iSuspendpoint > 2) || (iRead == iBuflen))
+ { /* determine length chunkname + data + crc */
+ iBuflen = pData->iChunklen + (mng_uint32)(sizeof (mng_chunkid) + sizeof (iCrc));
+
+ if (iBuflen < iBufmax) /* does it fit in default buffer ? */
+ { /* note that we don't use the full size
+ so there's always a zero-byte at the
+ very end !!! */
+ iRetcode = read_databuffer (pData, pBuf, iBuflen, &iRead);
+
+ if (iRetcode) /* bail on errors */
+ return iRetcode;
+
+ if (pData->bSuspended) /* suspended ? */
+ pData->iSuspendpoint = 3;
+ else
+ {
+ if (iRead != iBuflen) /* did we get all the data ? */
+ iRetcode = MNG_UNEXPECTEDEOF;
+ else
+ {
+ mng_uint32 iL = iBuflen - (mng_uint32)(sizeof (iCrc));
+ /* calculate the crc */
+ iCrc = crc (pData, pBuf, iL);
+ /* and check it */
+ if (!(iCrc == mng_get_uint32 (pBuf + iL)))
+ iRetcode = MNG_INVALIDCRC;
+ else
+ iRetcode = process_raw_chunk (pData, pBuf, iL);
+ }
+ }
+ }
+ else
+ {
+ if (!pData->iSuspendpoint) /* create additional large buffer ? */
+ { /* again reserve space for the last zero-byte */
+ pData->iLargebufsize = iBuflen + 1;
+ MNG_ALLOC (pData, pData->pLargebuf, pData->iLargebufsize)
+ }
+
+ iRetcode = read_databuffer (pData, pData->pLargebuf, iBuflen, &iRead);
+
+ if (iRetcode)
+ return iRetcode;
+
+ if (pData->bSuspended) /* suspended ? */
+ pData->iSuspendpoint = 4;
+ else
+ {
+ if (iRead != iBuflen) /* did we get all the data ? */
+ iRetcode = MNG_UNEXPECTEDEOF;
+ else
+ {
+ mng_uint32 iL = iBuflen - (mng_uint32)(sizeof (iCrc));
+ /* calculate the crc */
+ iCrc = crc (pData, pData->pLargebuf, iL);
+ /* and check it */
+ if (!(iCrc == mng_get_uint32 (pData->pLargebuf + iL)))
+ iRetcode = MNG_INVALIDCRC;
+ else
+ iRetcode = process_raw_chunk (pData, pData->pLargebuf, iL);
+ }
+ /* cleanup additional large buffer */
+ MNG_FREE (pData, pData->pLargebuf, pData->iLargebufsize)
+ }
+ }
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ }
+ else
+ { /* that's final */
+ iRetcode = process_eof (pData);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+
+ if ((iRead != 0) || /* did we get an unexpected eof ? */
+#ifdef MNG_INCLUDE_JNG
+ (pData->bHasIHDR || pData->bHasMHDR || pData->bHasJHDR))
+#else
+ (pData->bHasIHDR || pData->bHasMHDR))
+#endif
+ MNG_ERROR (pData, MNG_UNEXPECTEDEOF);
+ }
+ }
+ }
+
+#ifdef MNG_SUPPORT_DISPLAY /* refresh needed ? */
+ if ((!pData->bTimerset) && (!pData->bSuspended) && (pData->bNeedrefresh))
+ {
+ iRetcode = display_progressive_refresh (pData, 1);
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#endif
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_CHUNK, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode read_graphic (mng_datap pData)
+{
+ mng_uint32 iBuflen; /* number of bytes requested */
+ mng_uint32 iRead; /* number of bytes read */
+ mng_retcode iRetcode; /* temporary error-code */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_GRAPHIC, MNG_LC_START)
+#endif
+
+ if (!pData->pReadbuf) /* buffer allocated ? */
+ {
+ pData->iReadbufsize = 4200; /* allocate a default read buffer */
+ MNG_ALLOC (pData, pData->pReadbuf, pData->iReadbufsize)
+ }
+ /* haven't processed the signature ? */
+ if ((!pData->bHavesig) || (pData->iSuspendpoint == 1))
+ {
+ iBuflen = 2 * sizeof (mng_uint32); /* read signature */
+
+ iRetcode = read_databuffer (pData, pData->pReadbuf, iBuflen, &iRead);
+
+ if (iRetcode)
+ return iRetcode;
+
+ if (pData->bSuspended) /* input suspension ? */
+ pData->iSuspendpoint = 1;
+ else
+ {
+ if (iRead != iBuflen) /* full signature received ? */
+ MNG_ERROR (pData, MNG_UNEXPECTEDEOF);
+ /* is it a valid signature ? */
+ if (mng_get_uint32 (pData->pReadbuf) == PNG_SIG)
+ pData->eSigtype = mng_it_png;
+ else
+ if (mng_get_uint32 (pData->pReadbuf) == JNG_SIG)
+ pData->eSigtype = mng_it_jng;
+ else
+ if (mng_get_uint32 (pData->pReadbuf) == MNG_SIG)
+ pData->eSigtype = mng_it_mng;
+ else
+ MNG_ERROR (pData, MNG_INVALIDSIG);
+ /* all of it ? */
+ if (mng_get_uint32 (pData->pReadbuf+4) != POST_SIG)
+ MNG_ERROR (pData, MNG_INVALIDSIG);
+
+ pData->bHavesig = MNG_TRUE;
+ }
+ }
+
+ if (!pData->bSuspended) /* still going ? */
+ {
+ do
+ {
+ iRetcode = read_chunk (pData); /* process a chunk */
+
+ if (iRetcode) /* on error bail out */
+ return iRetcode;
+ }
+#ifdef MNG_SUPPORT_DISPLAY /* until EOF or a break-request */
+ while (((!pData->bEOF) || (pData->pCurraniobj)) && (!pData->bSuspended) &&
+ (!pData->bTimerset) && (!pData->bSectionwait));
+#else
+ while ((!pData->bEOF) && (!pData->bSuspended));
+#endif
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_READ_GRAPHIC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_READ_PROCS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_read.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_read.h
new file mode 100644
index 0000000..280043d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_read.h
@@ -0,0 +1,45 @@
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_read.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Read management (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the read management routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 10/18/2000 - G.Juyn * */
+/* * - added closestream() processing for mng_cleanup() * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_read_h_
+#define _libmng_read_h_
+
+/* ************************************************************************** */
+
+mng_retcode process_eof (mng_datap pData);
+
+mng_retcode read_graphic (mng_datap pData);
+
+/* ************************************************************************** */
+
+#endif /* _libmng_read_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_trace.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_trace.c
new file mode 100644
index 0000000..732854f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_trace.c
@@ -0,0 +1,1174 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_trace.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.3 * */
+/* * * */
+/* * purpose : Trace functions (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the trace functions * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - added callback error-reporting support * */
+/* * * */
+/* * 0.5.2 - 05/23/2000 - G.Juyn * */
+/* * - added trace telltale reporting * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - added tracestrings for global animation color-chunks * */
+/* * - added tracestrings for get/set of default ZLIB/IJG parms * */
+/* * - added tracestrings for global PLTE,tRNS,bKGD * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added tracestrings for image-object promotion * */
+/* * - added tracestrings for delta-image processing * */
+/* * 0.5.2 - 06/02/2000 - G.Juyn * */
+/* * - added tracestrings for getalphaline callback * */
+/* * 0.5.2 - 06/05/2000 - G.Juyn * */
+/* * - added tracestring for RGB8_A8 canvasstyle * */
+/* * 0.5.2 - 06/06/2000 - G.Juyn * */
+/* * - added tracestring for mng_read_resume HLAPI function * */
+/* * * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added tracestrings for get/set speedtype * */
+/* * - added tracestring for get imagelevel * */
+/* * 0.5.3 - 06/22/2000 - G.Juyn * */
+/* * - added tracestring for delta-image processing * */
+/* * - added tracestrings for PPLT chunk processing * */
+/* * * */
+/* * 0.9.1 - 07/07/2000 - G.Juyn * */
+/* * - added tracecodes for special display processing * */
+/* * 0.9.1 - 07/08/2000 - G.Juyn * */
+/* * - added tracestring for get/set suspensionmode * */
+/* * - added tracestrings for get/set display variables * */
+/* * - added tracecode for read_databuffer (I/O-suspension) * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - added tracestrings for SAVE/SEEK callbacks * */
+/* * - added tracestrings for get/set sectionbreaks * */
+/* * - added tracestring for special error routine * */
+/* * 0.9.1 - 07/19/2000 - G.Juyn * */
+/* * - added tracestring for updatemngheader * */
+/* * * */
+/* * 0.9.2 - 07/31/2000 - G.Juyn * */
+/* * - added tracestrings for status_xxxxx functions * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * - added tracestring for updatemngsimplicity * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * 0.9.3 - 10/10/2000 - G.Juyn * */
+/* * - added support for alpha-depth prediction * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - added JDAA chunk * */
+/* * - added support for nEED * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added functions to retrieve PNG/JNG specific header-info * */
+/* * - added optional support for bKGD for PNG images * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - added callback to process non-critical unknown chunks * */
+/* * - added routine to discard "invalid" objects * */
+/* * 0.9.3 - 10/19/2000 - G.Juyn * */
+/* * - implemented delayed delta-processing * */
+/* * 0.9.3 - 10/20/2000 - G.Juyn * */
+/* * - added get/set for bKGD preference setting * */
+/* * 0.9.3 - 10/21/2000 - G.Juyn * */
+/* * - added get function for interlace/progressive display * */
+/* * * */
+/* * 0.9.4 - 1/18/2001 - G.Juyn * */
+/* * - added "new" MAGN methods 3, 4 & 5 * */
+/* * * */
+/* * 1.0.1 - 02/08/2001 - G.Juyn * */
+/* * - added MEND processing callback * */
+/* * 1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly) * */
+/* * - added BGRA8 canvas with premultiplied alpha * */
+/* * 1.0.1 - 05/02/2001 - G.Juyn * */
+/* * - added "default" sRGB generation (Thanks Marti!) * */
+/* * * */
+/* * 1.0.2 - 06/23/2001 - G.Juyn * */
+/* * - added optimization option for MNG-video playback * */
+/* * - added processterm callback * */
+/* * 1.0.2 - 06/25/2001 - G.Juyn * */
+/* * - added option to turn off progressive refresh * */
+/* * * */
+/* * 1.0.3 - 08/06/2001 - G.Juyn * */
+/* * - added get function for last processed BACK chunk * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_TRACE_PROCS
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_TRACE_STRINGS
+ mng_trace_entry trace_table [] =
+ {
+ {MNG_FN_INITIALIZE, "initialize"},
+ {MNG_FN_RESET, "reset"},
+ {MNG_FN_CLEANUP, "cleanup"},
+ {MNG_FN_READ, "read"},
+ {MNG_FN_WRITE, "write"},
+ {MNG_FN_CREATE, "create"},
+ {MNG_FN_READDISPLAY, "readdisplay"},
+ {MNG_FN_DISPLAY, "display"},
+ {MNG_FN_DISPLAY_RESUME, "display_resume"},
+ {MNG_FN_DISPLAY_FREEZE, "display_freeze"},
+ {MNG_FN_DISPLAY_RESET, "display_reset"},
+ {MNG_FN_DISPLAY_GOFRAME, "display_goframe"},
+ {MNG_FN_DISPLAY_GOLAYER, "display_golayer"},
+ {MNG_FN_DISPLAY_GOTIME, "display_gotime"},
+ {MNG_FN_GETLASTERROR, "getlasterror"},
+ {MNG_FN_READ_RESUME, "read_resume"},
+
+ {MNG_FN_SETCB_MEMALLOC, "setcb_memalloc"},
+ {MNG_FN_SETCB_MEMFREE, "setcb_memfree"},
+ {MNG_FN_SETCB_READDATA, "setcb_readdata"},
+ {MNG_FN_SETCB_WRITEDATA, "setcb_writedata"},
+ {MNG_FN_SETCB_ERRORPROC, "setcb_errorproc"},
+ {MNG_FN_SETCB_TRACEPROC, "setcb_traceproc"},
+ {MNG_FN_SETCB_PROCESSHEADER, "setcb_processheader"},
+ {MNG_FN_SETCB_PROCESSTEXT, "setcb_processtext"},
+ {MNG_FN_SETCB_GETCANVASLINE, "setcb_getcanvasline"},
+ {MNG_FN_SETCB_GETBKGDLINE, "setcb_getbkgdline"},
+ {MNG_FN_SETCB_REFRESH, "setcb_refresh"},
+ {MNG_FN_SETCB_GETTICKCOUNT, "setcb_gettickcount"},
+ {MNG_FN_SETCB_SETTIMER, "setcb_settimer"},
+ {MNG_FN_SETCB_PROCESSGAMMA, "setcb_processgamma"},
+ {MNG_FN_SETCB_PROCESSCHROMA, "setcb_processchroma"},
+ {MNG_FN_SETCB_PROCESSSRGB, "setcb_processsrgb"},
+ {MNG_FN_SETCB_PROCESSICCP, "setcb_processiccp"},
+ {MNG_FN_SETCB_PROCESSAROW, "setcb_processarow"},
+ {MNG_FN_SETCB_OPENSTREAM, "setcb_openstream"},
+ {MNG_FN_SETCB_CLOSESTREAM, "setcb_closestream"},
+ {MNG_FN_SETCB_GETALPHALINE, "setcb_getalphaline"},
+ {MNG_FN_SETCB_PROCESSSAVE, "setcb_processsave"},
+ {MNG_FN_SETCB_PROCESSSEEK, "setcb_processseek"},
+ {MNG_FN_SETCB_PROCESSNEED, "setcb_processneed"},
+ {MNG_FN_SETCB_PROCESSUNKNOWN, "setcb_processunknown"},
+ {MNG_FN_SETCB_PROCESSMEND, "setcb_processmend"},
+ {MNG_FN_SETCB_PROCESSTERM, "setcb_processterm"},
+
+ {MNG_FN_GETCB_MEMALLOC, "getcb_memalloc"},
+ {MNG_FN_GETCB_MEMFREE, "getcb_memfree"},
+ {MNG_FN_GETCB_READDATA, "getcb_readdata,"},
+ {MNG_FN_GETCB_WRITEDATA, "getcb_writedata"},
+ {MNG_FN_GETCB_ERRORPROC, "getcb_errorproc"},
+ {MNG_FN_GETCB_TRACEPROC, "getcb_traceproc"},
+ {MNG_FN_GETCB_PROCESSHEADER, "getcb_processheader"},
+ {MNG_FN_GETCB_PROCESSTEXT, "getcb_processtext"},
+ {MNG_FN_GETCB_GETCANVASLINE, "getcb_getcanvasline"},
+ {MNG_FN_GETCB_GETBKGDLINE, "getcb_getbkgdline"},
+ {MNG_FN_GETCB_REFRESH, "getcb_refresh"},
+ {MNG_FN_GETCB_GETTICKCOUNT, "getcb_gettickcount"},
+ {MNG_FN_GETCB_SETTIMER, "getcb_settimer"},
+ {MNG_FN_GETCB_PROCESSGAMMA, "getcb_processgamma"},
+ {MNG_FN_GETCB_PROCESSCHROMA, "getcb_processchroma"},
+ {MNG_FN_GETCB_PROCESSSRGB, "getcb_processsrgb"},
+ {MNG_FN_GETCB_PROCESSICCP, "getcb_processiccp"},
+ {MNG_FN_GETCB_PROCESSAROW, "getcb_processarow"},
+ {MNG_FN_GETCB_OPENSTREAM, "getcb_openstream"},
+ {MNG_FN_GETCB_CLOSESTREAM, "getcb_closestream"},
+ {MNG_FN_GETCB_GETALPHALINE, "getcb_getalphaline"},
+ {MNG_FN_GETCB_PROCESSSAVE, "getcb_processsave"},
+ {MNG_FN_GETCB_PROCESSSEEK, "getcb_processseek"},
+ {MNG_FN_GETCB_PROCESSNEED, "getcb_processneed"},
+ {MNG_FN_GETCB_PROCESSUNKNOWN, "getcb_processunknown"},
+ {MNG_FN_GETCB_PROCESSMEND, "getcb_processmend"},
+ {MNG_FN_GETCB_PROCESSTERM, "getcb_processterm"},
+
+ {MNG_FN_SET_USERDATA, "set_userdata"},
+ {MNG_FN_SET_CANVASSTYLE, "set_canvasstyle"},
+ {MNG_FN_SET_BKGDSTYLE, "set_bkgdstyle"},
+ {MNG_FN_SET_BGCOLOR, "set_bgcolor"},
+ {MNG_FN_SET_STORECHUNKS, "set_storechunks"},
+ {MNG_FN_SET_VIEWGAMMA, "set_viewgamma"},
+ {MNG_FN_SET_DISPLAYGAMMA, "set_displaygamma"},
+ {MNG_FN_SET_DFLTIMGGAMMA, "set_dfltimggamma"},
+ {MNG_FN_SET_SRGB, "set_srgb"},
+ {MNG_FN_SET_OUTPUTPROFILE, "set_outputprofile"},
+ {MNG_FN_SET_SRGBPROFILE, "set_srgbprofile"},
+ {MNG_FN_SET_MAXCANVASWIDTH, "set_maxcanvaswidth"},
+ {MNG_FN_SET_MAXCANVASHEIGHT, "set_maxcanvasheight"},
+ {MNG_FN_SET_MAXCANVASSIZE, "set_maxcanvassize"},
+ {MNG_FN_SET_ZLIB_LEVEL, "set_zlib_level"},
+ {MNG_FN_SET_ZLIB_METHOD, "set_zlib_method"},
+ {MNG_FN_SET_ZLIB_WINDOWBITS, "set_zlib_windowbits"},
+ {MNG_FN_SET_ZLIB_MEMLEVEL, "set_zlib_memlevel"},
+ {MNG_FN_SET_ZLIB_STRATEGY, "set_zlib_strategy"},
+ {MNG_FN_SET_ZLIB_MAXIDAT, "set_zlib_maxidat"},
+ {MNG_FN_SET_JPEG_DCTMETHOD, "set_jpeg_dctmethod"},
+ {MNG_FN_SET_JPEG_TQUALITY, "set_jpeg_quality"},
+ {MNG_FN_SET_JPEG_SMOOTHING, "set_jpeg_smoothing"},
+ {MNG_FN_SET_JPEG_PROGRESSIVE, "set_jpeg_progressive"},
+ {MNG_FN_SET_JPEG_OPTIMIZED, "set_jpeg_optimized"},
+ {MNG_FN_SET_JPEG_MAXJDAT, "set_jpeg_maxjdat"},
+ {MNG_FN_SET_SPEED, "set_speed"},
+ {MNG_FN_SET_SUSPENSIONMODE, "set_suspensionmode"},
+ {MNG_FN_SET_SECTIONBREAKS, "set_sectionbreaks"},
+ {MNG_FN_SET_USEBKGD, "set_usebkgd"},
+ {MNG_FN_SET_OUTPUTPROFILE2, "set_outputprofile2"},
+ {MNG_FN_SET_SRGBPROFILE2, "set_srgbprofile2"},
+ {MNG_FN_SET_OUTPUTSRGB, "set_outputsrgb"},
+ {MNG_FN_SET_SRGBIMPLICIT, "set_srgbimplicit"},
+ {MNG_FN_SET_CACHEPLAYBACK, "set_cacheplayback"},
+ {MNG_FN_SET_DOPROGRESSIVE, "set_doprogressive"},
+
+ {MNG_FN_GET_USERDATA, "get_userdata"},
+ {MNG_FN_GET_SIGTYPE, "get_sigtype"},
+ {MNG_FN_GET_IMAGETYPE, "get_imagetype"},
+ {MNG_FN_GET_IMAGEWIDTH, "get_imagewidth"},
+ {MNG_FN_GET_IMAGEHEIGHT, "get_imageheight"},
+ {MNG_FN_GET_TICKS, "get_ticks"},
+ {MNG_FN_GET_FRAMECOUNT, "get_framecount"},
+ {MNG_FN_GET_LAYERCOUNT, "get_layercount"},
+ {MNG_FN_GET_PLAYTIME, "get_playtime"},
+ {MNG_FN_GET_SIMPLICITY, "get_simplicity"},
+ {MNG_FN_GET_CANVASSTYLE, "get_canvasstyle"},
+ {MNG_FN_GET_BKGDSTYLE, "get_bkgdstyle"},
+ {MNG_FN_GET_BGCOLOR, "get_bgcolor"},
+ {MNG_FN_GET_STORECHUNKS, "get_storechunks"},
+ {MNG_FN_GET_VIEWGAMMA, "get_viewgamma"},
+ {MNG_FN_GET_DISPLAYGAMMA, "get_displaygamma"},
+ {MNG_FN_GET_DFLTIMGGAMMA, "get_dfltimggamma"},
+ {MNG_FN_GET_SRGB, "get_srgb"},
+ {MNG_FN_GET_MAXCANVASWIDTH, "get_maxcanvaswidth"},
+ {MNG_FN_GET_MAXCANVASHEIGHT, "get_maxcanvasheight"},
+ {MNG_FN_GET_ZLIB_LEVEL, "get_zlib_level"},
+ {MNG_FN_GET_ZLIB_METHOD, "get_zlib_method"},
+ {MNG_FN_GET_ZLIB_WINDOWBITS, "get_zlib_windowbits"},
+ {MNG_FN_GET_ZLIB_MEMLEVEL, "get_zlib_memlevel"},
+ {MNG_FN_GET_ZLIB_STRATEGY, "get_zlib_strategy"},
+ {MNG_FN_GET_ZLIB_MAXIDAT, "get_zlib_maxidat"},
+ {MNG_FN_GET_JPEG_DCTMETHOD, "get_jpeg_dctmethod"},
+ {MNG_FN_GET_JPEG_TQUALITY, "get_jpeg_quality"},
+ {MNG_FN_GET_JPEG_SMOOTHING, "get_jpeg_smoothing"},
+ {MNG_FN_GET_JPEG_PROGRESSIVE, "get_jpeg_progressive"},
+ {MNG_FN_GET_JPEG_OPTIMIZED, "get_jpeg_optimized"},
+ {MNG_FN_GET_JPEG_MAXJDAT, "get_jpeg_maxjdat"},
+ {MNG_FN_GET_SPEED, "get_speed"},
+ {MNG_FN_GET_IMAGELEVEL, "get_imagelevel"},
+ {MNG_FN_GET_SUSPENSIONMODE, "get_speed"},
+ {MNG_FN_GET_STARTTIME, "get_starttime"},
+ {MNG_FN_GET_RUNTIME, "get_runtime"},
+ {MNG_FN_GET_CURRENTFRAME, "get_currentframe"},
+ {MNG_FN_GET_CURRENTLAYER, "get_currentlayer"},
+ {MNG_FN_GET_CURRENTPLAYTIME, "get_currentplaytime"},
+ {MNG_FN_GET_SECTIONBREAKS, "get_sectionbreaks"},
+ {MNG_FN_GET_ALPHADEPTH, "get_alphadepth"},
+ {MNG_FN_GET_BITDEPTH, "get_bitdepth"},
+ {MNG_FN_GET_COLORTYPE, "get_colortype"},
+ {MNG_FN_GET_COMPRESSION, "get_compression"},
+ {MNG_FN_GET_FILTER, "get_filter"},
+ {MNG_FN_GET_INTERLACE, "get_interlace"},
+ {MNG_FN_GET_ALPHABITDEPTH, "get_alphabitdepth"},
+ {MNG_FN_GET_ALPHACOMPRESSION, "get_alphacompression"},
+ {MNG_FN_GET_ALPHAFILTER, "get_alphafilter"},
+ {MNG_FN_GET_ALPHAINTERLACE, "get_alphainterlace"},
+ {MNG_FN_GET_USEBKGD, "get_usebkgd"},
+ {MNG_FN_GET_REFRESHPASS, "get_refreshpass"},
+ {MNG_FN_GET_CACHEPLAYBACK, "get_cacheplayback"},
+ {MNG_FN_GET_DOPROGRESSIVE, "get_doprogressive"},
+ {MNG_FN_GET_LASTBACKCHUNK, "get_lastbackchunk"},
+
+ {MNG_FN_STATUS_ERROR, "status_error"},
+ {MNG_FN_STATUS_READING, "status_reading"},
+ {MNG_FN_STATUS_SUSPENDBREAK, "status_suspendbreak"},
+ {MNG_FN_STATUS_CREATING, "status_creating"},
+ {MNG_FN_STATUS_WRITING, "status_writing"},
+ {MNG_FN_STATUS_DISPLAYING, "status_displaying"},
+ {MNG_FN_STATUS_RUNNING, "status_running"},
+ {MNG_FN_STATUS_TIMERBREAK, "status_timerbreak"},
+
+ {MNG_FN_ITERATE_CHUNKS, "iterate_chunks"},
+
+ {MNG_FN_GETCHUNK_IHDR, "getchunk_ihdr"},
+ {MNG_FN_GETCHUNK_PLTE, "getchunk_plte"},
+ {MNG_FN_GETCHUNK_IDAT, "getchunk_idat"},
+ {MNG_FN_GETCHUNK_IEND, "getchunk_iend"},
+ {MNG_FN_GETCHUNK_TRNS, "getchunk_trns"},
+ {MNG_FN_GETCHUNK_GAMA, "getchunk_gama"},
+ {MNG_FN_GETCHUNK_CHRM, "getchunk_chrm"},
+ {MNG_FN_GETCHUNK_SRGB, "getchunk_srgb"},
+ {MNG_FN_GETCHUNK_ICCP, "getchunk_iccp"},
+ {MNG_FN_GETCHUNK_TEXT, "getchunk_text"},
+ {MNG_FN_GETCHUNK_ZTXT, "getchunk_ztxt"},
+ {MNG_FN_GETCHUNK_ITXT, "getchunk_itxt"},
+ {MNG_FN_GETCHUNK_BKGD, "getchunk_bkgd"},
+ {MNG_FN_GETCHUNK_PHYS, "getchunk_phys"},
+ {MNG_FN_GETCHUNK_SBIT, "getchunk_sbit"},
+ {MNG_FN_GETCHUNK_SPLT, "getchunk_splt"},
+ {MNG_FN_GETCHUNK_HIST, "getchunk_hist"},
+ {MNG_FN_GETCHUNK_TIME, "getchunk_time"},
+ {MNG_FN_GETCHUNK_MHDR, "getchunk_mhdr"},
+ {MNG_FN_GETCHUNK_MEND, "getchunk_mend"},
+ {MNG_FN_GETCHUNK_LOOP, "getchunk_loop"},
+ {MNG_FN_GETCHUNK_ENDL, "getchunk_endl"},
+ {MNG_FN_GETCHUNK_DEFI, "getchunk_defi"},
+ {MNG_FN_GETCHUNK_BASI, "getchunk_basi"},
+ {MNG_FN_GETCHUNK_CLON, "getchunk_clon"},
+ {MNG_FN_GETCHUNK_PAST, "getchunk_past"},
+ {MNG_FN_GETCHUNK_DISC, "getchunk_disc"},
+ {MNG_FN_GETCHUNK_BACK, "getchunk_back"},
+ {MNG_FN_GETCHUNK_FRAM, "getchunk_fram"},
+ {MNG_FN_GETCHUNK_MOVE, "getchunk_move"},
+ {MNG_FN_GETCHUNK_CLIP, "getchunk_clip"},
+ {MNG_FN_GETCHUNK_SHOW, "getchunk_show"},
+ {MNG_FN_GETCHUNK_TERM, "getchunk_term"},
+ {MNG_FN_GETCHUNK_SAVE, "getchunk_save"},
+ {MNG_FN_GETCHUNK_SEEK, "getchunk_seek"},
+ {MNG_FN_GETCHUNK_EXPI, "getchunk_expi"},
+ {MNG_FN_GETCHUNK_FPRI, "getchunk_fpri"},
+ {MNG_FN_GETCHUNK_NEED, "getchunk_need"},
+ {MNG_FN_GETCHUNK_PHYG, "getchunk_phyg"},
+ {MNG_FN_GETCHUNK_JHDR, "getchunk_jhdr"},
+ {MNG_FN_GETCHUNK_JDAT, "getchunk_jdat"},
+ {MNG_FN_GETCHUNK_JSEP, "getchunk_jsep"},
+ {MNG_FN_GETCHUNK_DHDR, "getchunk_dhdr"},
+ {MNG_FN_GETCHUNK_PROM, "getchunk_prom"},
+ {MNG_FN_GETCHUNK_IPNG, "getchunk_ipng"},
+ {MNG_FN_GETCHUNK_PPLT, "getchunk_pplt"},
+ {MNG_FN_GETCHUNK_IJNG, "getchunk_ijng"},
+ {MNG_FN_GETCHUNK_DROP, "getchunk_drop"},
+ {MNG_FN_GETCHUNK_DBYK, "getchunk_dbyk"},
+ {MNG_FN_GETCHUNK_ORDR, "getchunk_ordr"},
+ {MNG_FN_GETCHUNK_UNKNOWN, "getchunk_unknown"},
+ {MNG_FN_GETCHUNK_MAGN, "getchunk_magn"},
+ {MNG_FN_GETCHUNK_JDAA, "getchunk_jdaa"},
+
+ {MNG_FN_GETCHUNK_PAST_SRC, "getchunk_past_src"},
+ {MNG_FN_GETCHUNK_SAVE_ENTRY, "getchunk_save_entry"},
+ {MNG_FN_GETCHUNK_PPLT_ENTRY, "getchunk_pplt_entry"},
+ {MNG_FN_GETCHUNK_ORDR_ENTRY, "getchunk_ordr_entry"},
+
+ {MNG_FN_PUTCHUNK_IHDR, "putchunk_ihdr"},
+ {MNG_FN_PUTCHUNK_PLTE, "putchunk_plte"},
+ {MNG_FN_PUTCHUNK_IDAT, "putchunk_idat"},
+ {MNG_FN_PUTCHUNK_IEND, "putchunk_iend"},
+ {MNG_FN_PUTCHUNK_TRNS, "putchunk_trns"},
+ {MNG_FN_PUTCHUNK_GAMA, "putchunk_gama"},
+ {MNG_FN_PUTCHUNK_CHRM, "putchunk_chrm"},
+ {MNG_FN_PUTCHUNK_SRGB, "putchunk_srgb"},
+ {MNG_FN_PUTCHUNK_ICCP, "putchunk_iccp"},
+ {MNG_FN_PUTCHUNK_TEXT, "putchunk_text"},
+ {MNG_FN_PUTCHUNK_ZTXT, "putchunk_ztxt"},
+ {MNG_FN_PUTCHUNK_ITXT, "putchunk_itxt"},
+ {MNG_FN_PUTCHUNK_BKGD, "putchunk_bkgd"},
+ {MNG_FN_PUTCHUNK_PHYS, "putchunk_phys"},
+ {MNG_FN_PUTCHUNK_SBIT, "putchunk_sbit"},
+ {MNG_FN_PUTCHUNK_SPLT, "putchunk_splt"},
+ {MNG_FN_PUTCHUNK_HIST, "putchunk_hist"},
+ {MNG_FN_PUTCHUNK_TIME, "putchunk_time"},
+ {MNG_FN_PUTCHUNK_MHDR, "putchunk_mhdr"},
+ {MNG_FN_PUTCHUNK_MEND, "putchunk_mend"},
+ {MNG_FN_PUTCHUNK_LOOP, "putchunk_loop"},
+ {MNG_FN_PUTCHUNK_ENDL, "putchunk_endl"},
+ {MNG_FN_PUTCHUNK_DEFI, "putchunk_defi"},
+ {MNG_FN_PUTCHUNK_BASI, "putchunk_basi"},
+ {MNG_FN_PUTCHUNK_CLON, "putchunk_clon"},
+ {MNG_FN_PUTCHUNK_PAST, "putchunk_past"},
+ {MNG_FN_PUTCHUNK_DISC, "putchunk_disc"},
+ {MNG_FN_PUTCHUNK_BACK, "putchunk_back"},
+ {MNG_FN_PUTCHUNK_FRAM, "putchunk_fram"},
+ {MNG_FN_PUTCHUNK_MOVE, "putchunk_move"},
+ {MNG_FN_PUTCHUNK_CLIP, "putchunk_clip"},
+ {MNG_FN_PUTCHUNK_SHOW, "putchunk_show"},
+ {MNG_FN_PUTCHUNK_TERM, "putchunk_term"},
+ {MNG_FN_PUTCHUNK_SAVE, "putchunk_save"},
+ {MNG_FN_PUTCHUNK_SEEK, "putchunk_seek"},
+ {MNG_FN_PUTCHUNK_EXPI, "putchunk_expi"},
+ {MNG_FN_PUTCHUNK_FPRI, "putchunk_fpri"},
+ {MNG_FN_PUTCHUNK_NEED, "putchunk_need"},
+ {MNG_FN_PUTCHUNK_PHYG, "putchunk_phyg"},
+ {MNG_FN_PUTCHUNK_JHDR, "putchunk_jhdr"},
+ {MNG_FN_PUTCHUNK_JDAT, "putchunk_jdat"},
+ {MNG_FN_PUTCHUNK_JSEP, "putchunk_jsep"},
+ {MNG_FN_PUTCHUNK_DHDR, "putchunk_dhdr"},
+ {MNG_FN_PUTCHUNK_PROM, "putchunk_prom"},
+ {MNG_FN_PUTCHUNK_IPNG, "putchunk_ipng"},
+ {MNG_FN_PUTCHUNK_PPLT, "putchunk_pplt"},
+ {MNG_FN_PUTCHUNK_IJNG, "putchunk_ijng"},
+ {MNG_FN_PUTCHUNK_DROP, "putchunk_drop"},
+ {MNG_FN_PUTCHUNK_DBYK, "putchunk_dbyk"},
+ {MNG_FN_PUTCHUNK_ORDR, "putchunk_ordr"},
+ {MNG_FN_PUTCHUNK_UNKNOWN, "putchunk_unknown"},
+ {MNG_FN_PUTCHUNK_MAGN, "putchunk_magn"},
+ {MNG_FN_PUTCHUNK_JDAA, "putchunk_jdaa"},
+
+ {MNG_FN_PUTCHUNK_PAST_SRC, "putchunk_past_src"},
+ {MNG_FN_PUTCHUNK_SAVE_ENTRY, "putchunk_save_entry"},
+ {MNG_FN_PUTCHUNK_PPLT_ENTRY, "putchunk_pplt_entry"},
+ {MNG_FN_PUTCHUNK_ORDR_ENTRY, "putchunk_ordr_entry"},
+
+ {MNG_FN_GETIMGDATA_SEQ, "getimgdata_seq"},
+ {MNG_FN_GETIMGDATA_CHUNKSEQ, "getimgdata_chunkseq"},
+ {MNG_FN_GETIMGDATA_CHUNK, "getimgdata_chunk"},
+
+ {MNG_FN_PUTIMGDATA_IHDR, "putimgdata_ihdr"},
+ {MNG_FN_PUTIMGDATA_JHDR, "putimgdata_jhdr"},
+ {MNG_FN_PUTIMGDATA_BASI, "putimgdata_basi"},
+ {MNG_FN_PUTIMGDATA_DHDR, "putimgdata_dhdr"},
+
+ {MNG_FN_UPDATEMNGHEADER, "updatemngheader"},
+ {MNG_FN_UPDATEMNGSIMPLICITY, "updatemngsimplicity"},
+
+ {MNG_FN_PROCESS_RAW_CHUNK, "process_raw_chunk"},
+ {MNG_FN_READ_GRAPHIC, "read_graphic"},
+ {MNG_FN_DROP_CHUNKS, "drop_chunks"},
+ {MNG_FN_PROCESS_ERROR, "process_error"},
+ {MNG_FN_CLEAR_CMS, "clear_cms"},
+ {MNG_FN_DROP_OBJECTS, "drop_objects"},
+ {MNG_FN_READ_CHUNK, "read_chunk"},
+ {MNG_FN_LOAD_BKGDLAYER, "load_bkgdlayer"},
+ {MNG_FN_NEXT_FRAME, "next_frame"},
+ {MNG_FN_NEXT_LAYER, "next_layer"},
+ {MNG_FN_INTERFRAME_DELAY, "interframe_delay"},
+ {MNG_FN_DISPLAY_IMAGE, "display_image"},
+ {MNG_FN_DROP_IMGOBJECTS, "drop_imgobjects"},
+ {MNG_FN_DROP_ANIOBJECTS, "drop_aniobjects"},
+ {MNG_FN_INFLATE_BUFFER, "inflate_buffer"},
+ {MNG_FN_DEFLATE_BUFFER, "deflate_buffer"},
+ {MNG_FN_WRITE_RAW_CHUNK, "write_raw_chunk"},
+ {MNG_FN_WRITE_GRAPHIC, "write_graphic"},
+ {MNG_FN_SAVE_STATE, "save_state"},
+ {MNG_FN_RESTORE_STATE, "restore_state"},
+ {MNG_FN_DROP_SAVEDATA, "drop_savedata"},
+ {MNG_FN_EXECUTE_DELTA_IMAGE, "execute_delta_image"},
+ {MNG_FN_PROCESS_DISPLAY, "process_display"},
+ {MNG_FN_CLEAR_CANVAS, "clear_canvas"},
+ {MNG_FN_READ_DATABUFFER, "read_databuffer"},
+ {MNG_FN_STORE_ERROR, "store_error"},
+ {MNG_FN_DROP_INVALID_OBJECTS, "drop_invalid_objects"},
+
+ {MNG_FN_DISPLAY_RGB8, "display_rgb8"},
+ {MNG_FN_DISPLAY_RGBA8, "display_rgba8"},
+ {MNG_FN_DISPLAY_ARGB8, "display_argb8"},
+ {MNG_FN_DISPLAY_BGR8, "display_bgr8"},
+ {MNG_FN_DISPLAY_BGRA8, "display_bgra8"},
+ {MNG_FN_DISPLAY_ABGR8, "display_abgr8"},
+ {MNG_FN_DISPLAY_RGB16, "display_rgb16"},
+ {MNG_FN_DISPLAY_RGBA16, "display_rgba16"},
+ {MNG_FN_DISPLAY_ARGB16, "display_argb16"},
+ {MNG_FN_DISPLAY_BGR16, "display_bgr16"},
+ {MNG_FN_DISPLAY_BGRA16, "display_bgra16"},
+ {MNG_FN_DISPLAY_ABGR16, "display_abgr16"},
+ {MNG_FN_DISPLAY_INDEX8, "display_index8"},
+ {MNG_FN_DISPLAY_INDEXA8, "display_indexa8"},
+ {MNG_FN_DISPLAY_AINDEX8, "display_aindex8"},
+ {MNG_FN_DISPLAY_GRAY8, "display_gray8"},
+ {MNG_FN_DISPLAY_GRAY16, "display_gray16"},
+ {MNG_FN_DISPLAY_GRAYA8, "display_graya8"},
+ {MNG_FN_DISPLAY_GRAYA16, "display_graya16"},
+ {MNG_FN_DISPLAY_AGRAY8, "display_agray8"},
+ {MNG_FN_DISPLAY_AGRAY16, "display_agray16"},
+ {MNG_FN_DISPLAY_DX15, "display_dx15"},
+ {MNG_FN_DISPLAY_DX16, "display_dx16"},
+ {MNG_FN_DISPLAY_RGB8_A8, "display_rgb8_a8"},
+ {MNG_FN_DISPLAY_BGRA8PM, "display_bgra8_pm"},
+
+ {MNG_FN_INIT_FULL_CMS, "init_full_cms"},
+ {MNG_FN_CORRECT_FULL_CMS, "correct_full_cms"},
+ {MNG_FN_INIT_GAMMA_ONLY, "init_gamma_only"},
+ {MNG_FN_CORRECT_GAMMA_ONLY, "correct_gamma_only"},
+ {MNG_FN_CORRECT_APP_CMS, "correct_app_cms"},
+ {MNG_FN_INIT_FULL_CMS_OBJ, "init_full_cms_obj"},
+ {MNG_FN_INIT_GAMMA_ONLY_OBJ, "init_gamma_only_obj"},
+ {MNG_FN_INIT_APP_CMS, "init_app_cms"},
+ {MNG_FN_INIT_APP_CMS_OBJ, "init_app_cms_obj"},
+
+ {MNG_FN_PROCESS_G1, "process_g1"},
+ {MNG_FN_PROCESS_G2, "process_g2"},
+ {MNG_FN_PROCESS_G4, "process_g4"},
+ {MNG_FN_PROCESS_G8, "process_g8"},
+ {MNG_FN_PROCESS_G16, "process_g16"},
+ {MNG_FN_PROCESS_RGB8, "process_rgb8"},
+ {MNG_FN_PROCESS_RGB16, "process_rgb16"},
+ {MNG_FN_PROCESS_IDX1, "process_idx1"},
+ {MNG_FN_PROCESS_IDX2, "process_idx2"},
+ {MNG_FN_PROCESS_IDX4, "process_idx4"},
+ {MNG_FN_PROCESS_IDX8, "process_idx8"},
+ {MNG_FN_PROCESS_GA8, "process_ga8"},
+ {MNG_FN_PROCESS_GA16, "process_ga16"},
+ {MNG_FN_PROCESS_RGBA8, "process_rgba8"},
+ {MNG_FN_PROCESS_RGBA16, "process_rgba16"},
+
+ {MNG_FN_INIT_G1_NI, "init_g1_ni"},
+ {MNG_FN_INIT_G1_I, "init_g1_i"},
+ {MNG_FN_INIT_G2_NI, "init_g2_ni"},
+ {MNG_FN_INIT_G2_I, "init_g2_i"},
+ {MNG_FN_INIT_G4_NI, "init_g4_ni"},
+ {MNG_FN_INIT_G4_I, "init_g4_i"},
+ {MNG_FN_INIT_G8_NI, "init_g8_ni"},
+ {MNG_FN_INIT_G8_I, "init_g8_i"},
+ {MNG_FN_INIT_G16_NI, "init_g16_ni"},
+ {MNG_FN_INIT_G16_I, "init_g16_i"},
+ {MNG_FN_INIT_RGB8_NI, "init_rgb8_ni"},
+ {MNG_FN_INIT_RGB8_I, "init_rgb8_i"},
+ {MNG_FN_INIT_RGB16_NI, "init_rgb16_ni"},
+ {MNG_FN_INIT_RGB16_I, "init_rgb16_i"},
+ {MNG_FN_INIT_IDX1_NI, "init_idx1_ni"},
+ {MNG_FN_INIT_IDX1_I, "init_idx1_i"},
+ {MNG_FN_INIT_IDX2_NI, "init_idx2_ni"},
+ {MNG_FN_INIT_IDX2_I, "init_idx2_i"},
+ {MNG_FN_INIT_IDX4_NI, "init_idx4_ni"},
+ {MNG_FN_INIT_IDX4_I, "init_idx4_i"},
+ {MNG_FN_INIT_IDX8_NI, "init_idx8_ni"},
+ {MNG_FN_INIT_IDX8_I, "init_idx8_i"},
+ {MNG_FN_INIT_GA8_NI, "init_ga8_ni"},
+ {MNG_FN_INIT_GA8_I, "init_ga8_i"},
+ {MNG_FN_INIT_GA16_NI, "init_ga16_ni"},
+ {MNG_FN_INIT_GA16_I, "init_ga16_i"},
+ {MNG_FN_INIT_RGBA8_NI, "init_rgba8_ni"},
+ {MNG_FN_INIT_RGBA8_I, "init_rgba8_i"},
+ {MNG_FN_INIT_RGBA16_NI, "init_rgba16_ni"},
+ {MNG_FN_INIT_RGBA16_I, "init_rgba16_i"},
+
+ {MNG_FN_INIT_ROWPROC, "init_rowproc"},
+ {MNG_FN_NEXT_ROW, "next_row"},
+ {MNG_FN_CLEANUP_ROWPROC, "cleanup_rowproc"},
+
+ {MNG_FN_FILTER_A_ROW, "filter_a_row"},
+ {MNG_FN_FILTER_SUB, "filter_sub"},
+ {MNG_FN_FILTER_UP, "filter_up"},
+ {MNG_FN_FILTER_AVERAGE, "filter_average"},
+ {MNG_FN_FILTER_PAETH, "filter_paeth"},
+
+ {MNG_FN_INIT_ROWDIFFERING, "init_rowdiffering"},
+ {MNG_FN_DIFFER_G1, "differ_g1"},
+ {MNG_FN_DIFFER_G2, "differ_g2"},
+ {MNG_FN_DIFFER_G4, "differ_g4"},
+ {MNG_FN_DIFFER_G8, "differ_g8"},
+ {MNG_FN_DIFFER_G16, "differ_g16"},
+ {MNG_FN_DIFFER_RGB8, "differ_rgb8"},
+ {MNG_FN_DIFFER_RGB16, "differ_rgb16"},
+ {MNG_FN_DIFFER_IDX1, "differ_idx1"},
+ {MNG_FN_DIFFER_IDX2, "differ_idx2"},
+ {MNG_FN_DIFFER_IDX4, "differ_idx4"},
+ {MNG_FN_DIFFER_IDX8, "differ_idx8"},
+ {MNG_FN_DIFFER_GA8, "differ_ga8"},
+ {MNG_FN_DIFFER_GA16, "differ_ga16"},
+ {MNG_FN_DIFFER_RGBA8, "differ_rgba8"},
+ {MNG_FN_DIFFER_RGBA16, "differ_rgba16"},
+
+ {MNG_FN_CREATE_IMGDATAOBJECT, "create_imgdataobject"},
+ {MNG_FN_FREE_IMGDATAOBJECT, "free_imgdataobject"},
+ {MNG_FN_CLONE_IMGDATAOBJECT, "clone_imgdataobject"},
+ {MNG_FN_CREATE_IMGOBJECT, "create_imgobject"},
+ {MNG_FN_FREE_IMGOBJECT, "free_imgobject"},
+ {MNG_FN_FIND_IMGOBJECT, "tqfind_imgobject"},
+ {MNG_FN_CLONE_IMGOBJECT, "clone_imgobject"},
+ {MNG_FN_RESET_OBJECTDETAILS, "reset_objectdetails"},
+ {MNG_FN_RENUM_IMGOBJECT, "renum_imgobject"},
+ {MNG_FN_PROMOTE_IMGOBJECT, "promote_imgobject"},
+ {MNG_FN_MAGNIFY_IMGOBJECT, "magnify_imgobject"},
+
+ {MNG_FN_STORE_G1, "store_g1"},
+ {MNG_FN_STORE_G2, "store_g2"},
+ {MNG_FN_STORE_G4, "store_g4"},
+ {MNG_FN_STORE_G8, "store_g8"},
+ {MNG_FN_STORE_G16, "store_g16"},
+ {MNG_FN_STORE_RGB8, "store_rgb8"},
+ {MNG_FN_STORE_RGB16, "store_rgb16"},
+ {MNG_FN_STORE_IDX1, "store_idx1"},
+ {MNG_FN_STORE_IDX2, "store_idx2"},
+ {MNG_FN_STORE_IDX4, "store_idx4"},
+ {MNG_FN_STORE_IDX8, "store_idx8"},
+ {MNG_FN_STORE_GA8, "store_ga8"},
+ {MNG_FN_STORE_GA16, "store_ga16"},
+ {MNG_FN_STORE_RGBA8, "store_rgba8"},
+ {MNG_FN_STORE_RGBA16, "store_rgba16"},
+
+ {MNG_FN_RETRIEVE_G8, "retrieve_g8"},
+ {MNG_FN_RETRIEVE_G16, "retrieve_g16"},
+ {MNG_FN_RETRIEVE_RGB8, "retrieve_rgb8"},
+ {MNG_FN_RETRIEVE_RGB16, "retrieve_rgb16"},
+ {MNG_FN_RETRIEVE_IDX8, "retrieve_idx8"},
+ {MNG_FN_RETRIEVE_GA8, "retrieve_ga8"},
+ {MNG_FN_RETRIEVE_GA16, "retrieve_ga16"},
+ {MNG_FN_RETRIEVE_RGBA8, "retrieve_rgba8"},
+ {MNG_FN_RETRIEVE_RGBA16, "retrieve_rgba16"},
+
+ {MNG_FN_DELTA_G1, "delta_g1"},
+ {MNG_FN_DELTA_G2, "delta_g2"},
+ {MNG_FN_DELTA_G4, "delta_g4"},
+ {MNG_FN_DELTA_G8, "delta_g8"},
+ {MNG_FN_DELTA_G16, "delta_g16"},
+ {MNG_FN_DELTA_RGB8, "delta_rgb8"},
+ {MNG_FN_DELTA_RGB16, "delta_rgb16"},
+ {MNG_FN_DELTA_IDX1, "delta_idx1"},
+ {MNG_FN_DELTA_IDX2, "delta_idx2"},
+ {MNG_FN_DELTA_IDX4, "delta_idx4"},
+ {MNG_FN_DELTA_IDX8, "delta_idx8"},
+ {MNG_FN_DELTA_GA8, "delta_ga8"},
+ {MNG_FN_DELTA_GA16, "delta_ga16"},
+ {MNG_FN_DELTA_RGBA8, "delta_rgba8"},
+ {MNG_FN_DELTA_RGBA16, "delta_rgba16"},
+
+ {MNG_FN_CREATE_ANI_LOOP, "create_ani_loop"},
+ {MNG_FN_CREATE_ANI_ENDL, "create_ani_endl"},
+ {MNG_FN_CREATE_ANI_DEFI, "create_ani_defi"},
+ {MNG_FN_CREATE_ANI_BASI, "create_ani_basi"},
+ {MNG_FN_CREATE_ANI_CLON, "create_ani_clon"},
+ {MNG_FN_CREATE_ANI_PAST, "create_ani_past"},
+ {MNG_FN_CREATE_ANI_DISC, "create_ani_disc"},
+ {MNG_FN_CREATE_ANI_BACK, "create_ani_back"},
+ {MNG_FN_CREATE_ANI_FRAM, "create_ani_fram"},
+ {MNG_FN_CREATE_ANI_MOVE, "create_ani_move"},
+ {MNG_FN_CREATE_ANI_CLIP, "create_ani_clip"},
+ {MNG_FN_CREATE_ANI_SHOW, "create_ani_show"},
+ {MNG_FN_CREATE_ANI_TERM, "create_ani_term"},
+ {MNG_FN_CREATE_ANI_SAVE, "create_ani_save"},
+ {MNG_FN_CREATE_ANI_SEEK, "create_ani_seek"},
+ {MNG_FN_CREATE_ANI_GAMA, "create_ani_gama"},
+ {MNG_FN_CREATE_ANI_CHRM, "create_ani_chrm"},
+ {MNG_FN_CREATE_ANI_SRGB, "create_ani_srgb"},
+ {MNG_FN_CREATE_ANI_ICCP, "create_ani_iccp"},
+ {MNG_FN_CREATE_ANI_PLTE, "create_ani_plte"},
+ {MNG_FN_CREATE_ANI_TRNS, "create_ani_trns"},
+ {MNG_FN_CREATE_ANI_BKGD, "create_ani_bkgd"},
+ {MNG_FN_CREATE_ANI_DHDR, "create_ani_dhdr"},
+ {MNG_FN_CREATE_ANI_PROM, "create_ani_prom"},
+ {MNG_FN_CREATE_ANI_IPNG, "create_ani_ipng"},
+ {MNG_FN_CREATE_ANI_IJNG, "create_ani_ijng"},
+ {MNG_FN_CREATE_ANI_PPLT, "create_ani_pplt"},
+ {MNG_FN_CREATE_ANI_MAGN, "create_ani_magn"},
+
+ {MNG_FN_CREATE_ANI_IMAGE, "create_ani_image"},
+
+ {MNG_FN_FREE_ANI_LOOP, "free_ani_loop"},
+ {MNG_FN_FREE_ANI_ENDL, "free_ani_endl"},
+ {MNG_FN_FREE_ANI_DEFI, "free_ani_defi"},
+ {MNG_FN_FREE_ANI_BASI, "free_ani_basi"},
+ {MNG_FN_FREE_ANI_CLON, "free_ani_clon"},
+ {MNG_FN_FREE_ANI_PAST, "free_ani_past"},
+ {MNG_FN_FREE_ANI_DISC, "free_ani_disc"},
+ {MNG_FN_FREE_ANI_BACK, "free_ani_back"},
+ {MNG_FN_FREE_ANI_FRAM, "free_ani_fram"},
+ {MNG_FN_FREE_ANI_MOVE, "free_ani_move"},
+ {MNG_FN_FREE_ANI_CLIP, "free_ani_clip"},
+ {MNG_FN_FREE_ANI_SHOW, "free_ani_show"},
+ {MNG_FN_FREE_ANI_TERM, "free_ani_term"},
+ {MNG_FN_FREE_ANI_SAVE, "free_ani_save"},
+ {MNG_FN_FREE_ANI_SEEK, "free_ani_seek"},
+ {MNG_FN_FREE_ANI_GAMA, "free_ani_gama"},
+ {MNG_FN_FREE_ANI_CHRM, "free_ani_chrm"},
+ {MNG_FN_FREE_ANI_SRGB, "free_ani_srgb"},
+ {MNG_FN_FREE_ANI_ICCP, "free_ani_iccp"},
+ {MNG_FN_FREE_ANI_PLTE, "free_ani_plte"},
+ {MNG_FN_FREE_ANI_TRNS, "free_ani_trns"},
+ {MNG_FN_FREE_ANI_BKGD, "free_ani_bkgd"},
+ {MNG_FN_FREE_ANI_DHDR, "free_ani_dhdr"},
+ {MNG_FN_FREE_ANI_PROM, "free_ani_prom"},
+ {MNG_FN_FREE_ANI_IPNG, "free_ani_ipng"},
+ {MNG_FN_FREE_ANI_IJNG, "free_ani_ijng"},
+ {MNG_FN_FREE_ANI_PPLT, "free_ani_pplt"},
+ {MNG_FN_FREE_ANI_MAGN, "free_ani_magn"},
+
+ {MNG_FN_FREE_ANI_IMAGE, "free_ani_image"},
+
+ {MNG_FN_PROCESS_ANI_LOOP, "process_ani_loop"},
+ {MNG_FN_PROCESS_ANI_ENDL, "process_ani_endl"},
+ {MNG_FN_PROCESS_ANI_DEFI, "process_ani_defi"},
+ {MNG_FN_PROCESS_ANI_BASI, "process_ani_basi"},
+ {MNG_FN_PROCESS_ANI_CLON, "process_ani_clon"},
+ {MNG_FN_PROCESS_ANI_PAST, "process_ani_past"},
+ {MNG_FN_PROCESS_ANI_DISC, "process_ani_disc"},
+ {MNG_FN_PROCESS_ANI_BACK, "process_ani_back"},
+ {MNG_FN_PROCESS_ANI_FRAM, "process_ani_fram"},
+ {MNG_FN_PROCESS_ANI_MOVE, "process_ani_move"},
+ {MNG_FN_PROCESS_ANI_CLIP, "process_ani_clip"},
+ {MNG_FN_PROCESS_ANI_SHOW, "process_ani_show"},
+ {MNG_FN_PROCESS_ANI_TERM, "process_ani_term"},
+ {MNG_FN_PROCESS_ANI_SAVE, "process_ani_save"},
+ {MNG_FN_PROCESS_ANI_SEEK, "process_ani_seek"},
+ {MNG_FN_PROCESS_ANI_GAMA, "process_ani_gama"},
+ {MNG_FN_PROCESS_ANI_CHRM, "process_ani_chrm"},
+ {MNG_FN_PROCESS_ANI_SRGB, "process_ani_srgb"},
+ {MNG_FN_PROCESS_ANI_ICCP, "process_ani_iccp"},
+ {MNG_FN_PROCESS_ANI_PLTE, "process_ani_plte"},
+ {MNG_FN_PROCESS_ANI_TRNS, "process_ani_trns"},
+ {MNG_FN_PROCESS_ANI_BKGD, "process_ani_bkgd"},
+ {MNG_FN_PROCESS_ANI_DHDR, "process_ani_dhdr"},
+ {MNG_FN_PROCESS_ANI_PROM, "process_ani_prom"},
+ {MNG_FN_PROCESS_ANI_IPNG, "process_ani_ipng"},
+ {MNG_FN_PROCESS_ANI_IJNG, "process_ani_ijng"},
+ {MNG_FN_PROCESS_ANI_PPLT, "process_ani_pplt"},
+ {MNG_FN_PROCESS_ANI_MAGN, "process_ani_magn"},
+
+ {MNG_FN_PROCESS_ANI_IMAGE, "process_ani_image"},
+
+ {MNG_FN_RESTORE_BACKIMAGE, "restore_backimage"},
+ {MNG_FN_RESTORE_BACKCOLOR, "restore_backcolor"},
+ {MNG_FN_RESTORE_BGCOLOR, "restore_bgcolor"},
+ {MNG_FN_RESTORE_RGB8, "restore_rgb8"},
+ {MNG_FN_RESTORE_BGR8, "restore_bgr8"},
+ {MNG_FN_RESTORE_BKGD, "restore_bkgd"},
+
+ {MNG_FN_INIT_IHDR, "init_ihdr"},
+ {MNG_FN_INIT_PLTE, "init_plte"},
+ {MNG_FN_INIT_IDAT, "init_idat"},
+ {MNG_FN_INIT_IEND, "init_iend"},
+ {MNG_FN_INIT_TRNS, "init_trns"},
+ {MNG_FN_INIT_GAMA, "init_gama"},
+ {MNG_FN_INIT_CHRM, "init_chrm"},
+ {MNG_FN_INIT_SRGB, "init_srgb"},
+ {MNG_FN_INIT_ICCP, "init_iccp"},
+ {MNG_FN_INIT_TEXT, "init_text"},
+ {MNG_FN_INIT_ZTXT, "init_ztxt"},
+ {MNG_FN_INIT_ITXT, "init_itxt"},
+ {MNG_FN_INIT_BKGD, "init_bkgd"},
+ {MNG_FN_INIT_PHYS, "init_phys"},
+ {MNG_FN_INIT_SBIT, "init_sbit"},
+ {MNG_FN_INIT_SPLT, "init_splt"},
+ {MNG_FN_INIT_HIST, "init_hist"},
+ {MNG_FN_INIT_TIME, "init_time"},
+ {MNG_FN_INIT_MHDR, "init_mhdr"},
+ {MNG_FN_INIT_MEND, "init_mend"},
+ {MNG_FN_INIT_LOOP, "init_loop"},
+ {MNG_FN_INIT_ENDL, "init_endl"},
+ {MNG_FN_INIT_DEFI, "init_defi"},
+ {MNG_FN_INIT_BASI, "init_basi"},
+ {MNG_FN_INIT_CLON, "init_clon"},
+ {MNG_FN_INIT_PAST, "init_past"},
+ {MNG_FN_INIT_DISC, "init_disc"},
+ {MNG_FN_INIT_BACK, "init_back"},
+ {MNG_FN_INIT_FRAM, "init_fram"},
+ {MNG_FN_INIT_MOVE, "init_move"},
+ {MNG_FN_INIT_CLIP, "init_clip"},
+ {MNG_FN_INIT_SHOW, "init_show"},
+ {MNG_FN_INIT_TERM, "init_term"},
+ {MNG_FN_INIT_SAVE, "init_save"},
+ {MNG_FN_INIT_SEEK, "init_seek"},
+ {MNG_FN_INIT_EXPI, "init_expi"},
+ {MNG_FN_INIT_FPRI, "init_fpri"},
+ {MNG_FN_INIT_NEED, "init_need"},
+ {MNG_FN_INIT_PHYG, "init_phyg"},
+ {MNG_FN_INIT_JHDR, "init_jhdr"},
+ {MNG_FN_INIT_JDAT, "init_jdat"},
+ {MNG_FN_INIT_JSEP, "init_jsep"},
+ {MNG_FN_INIT_DHDR, "init_dhdr"},
+ {MNG_FN_INIT_PROM, "init_prom"},
+ {MNG_FN_INIT_IPNG, "init_ipng"},
+ {MNG_FN_INIT_PPLT, "init_pplt"},
+ {MNG_FN_INIT_IJNG, "init_ijng"},
+ {MNG_FN_INIT_DROP, "init_drop"},
+ {MNG_FN_INIT_DBYK, "init_dbyk"},
+ {MNG_FN_INIT_ORDR, "init_ordr"},
+ {MNG_FN_INIT_UNKNOWN, "init_unknown"},
+ {MNG_FN_INIT_MAGN, "init_magn"},
+ {MNG_FN_INIT_JDAA, "init_jdaa"},
+
+ {MNG_FN_FREE_IHDR, "free_ihdr"},
+ {MNG_FN_FREE_PLTE, "free_plte"},
+ {MNG_FN_FREE_IDAT, "free_idat"},
+ {MNG_FN_FREE_IEND, "free_iend"},
+ {MNG_FN_FREE_TRNS, "free_trns"},
+ {MNG_FN_FREE_GAMA, "free_gama"},
+ {MNG_FN_FREE_CHRM, "free_chrm"},
+ {MNG_FN_FREE_SRGB, "free_srgb"},
+ {MNG_FN_FREE_ICCP, "free_iccp"},
+ {MNG_FN_FREE_TEXT, "free_text"},
+ {MNG_FN_FREE_ZTXT, "free_ztxt"},
+ {MNG_FN_FREE_ITXT, "free_itxt"},
+ {MNG_FN_FREE_BKGD, "free_bkgd"},
+ {MNG_FN_FREE_PHYS, "free_phys"},
+ {MNG_FN_FREE_SBIT, "free_sbit"},
+ {MNG_FN_FREE_SPLT, "free_splt"},
+ {MNG_FN_FREE_HIST, "free_hist"},
+ {MNG_FN_FREE_TIME, "free_time"},
+ {MNG_FN_FREE_MHDR, "free_mhdr"},
+ {MNG_FN_FREE_MEND, "free_mend"},
+ {MNG_FN_FREE_LOOP, "free_loop"},
+ {MNG_FN_FREE_ENDL, "free_endl"},
+ {MNG_FN_FREE_DEFI, "free_defi"},
+ {MNG_FN_FREE_BASI, "free_basi"},
+ {MNG_FN_FREE_CLON, "free_clon"},
+ {MNG_FN_FREE_PAST, "free_past"},
+ {MNG_FN_FREE_DISC, "free_disc"},
+ {MNG_FN_FREE_BACK, "free_back"},
+ {MNG_FN_FREE_FRAM, "free_fram"},
+ {MNG_FN_FREE_MOVE, "free_move"},
+ {MNG_FN_FREE_CLIP, "free_clip"},
+ {MNG_FN_FREE_SHOW, "free_show"},
+ {MNG_FN_FREE_TERM, "free_term"},
+ {MNG_FN_FREE_SAVE, "free_save"},
+ {MNG_FN_FREE_SEEK, "free_seek"},
+ {MNG_FN_FREE_EXPI, "free_expi"},
+ {MNG_FN_FREE_FPRI, "free_fpri"},
+ {MNG_FN_FREE_NEED, "free_need"},
+ {MNG_FN_FREE_PHYG, "free_phyg"},
+ {MNG_FN_FREE_JHDR, "free_jhdr"},
+ {MNG_FN_FREE_JDAT, "free_jdat"},
+ {MNG_FN_FREE_JSEP, "free_jsep"},
+ {MNG_FN_FREE_DHDR, "free_dhdr"},
+ {MNG_FN_FREE_PROM, "free_prom"},
+ {MNG_FN_FREE_IPNG, "free_ipng"},
+ {MNG_FN_FREE_PPLT, "free_pplt"},
+ {MNG_FN_FREE_IJNG, "free_ijng"},
+ {MNG_FN_FREE_DROP, "free_drop"},
+ {MNG_FN_FREE_DBYK, "free_dbyk"},
+ {MNG_FN_FREE_ORDR, "free_ordr"},
+ {MNG_FN_FREE_UNKNOWN, "free_unknown"},
+ {MNG_FN_FREE_MAGN, "free_magn"},
+ {MNG_FN_FREE_JDAA, "free_jdaa"},
+
+ {MNG_FN_READ_IHDR, "read_ihdr"},
+ {MNG_FN_READ_PLTE, "read_plte"},
+ {MNG_FN_READ_IDAT, "read_idat"},
+ {MNG_FN_READ_IEND, "read_iend"},
+ {MNG_FN_READ_TRNS, "read_trns"},
+ {MNG_FN_READ_GAMA, "read_gama"},
+ {MNG_FN_READ_CHRM, "read_chrm"},
+ {MNG_FN_READ_SRGB, "read_srgb"},
+ {MNG_FN_READ_ICCP, "read_iccp"},
+ {MNG_FN_READ_TEXT, "read_text"},
+ {MNG_FN_READ_ZTXT, "read_ztxt"},
+ {MNG_FN_READ_ITXT, "read_itxt"},
+ {MNG_FN_READ_BKGD, "read_bkgd"},
+ {MNG_FN_READ_PHYS, "read_phys"},
+ {MNG_FN_READ_SBIT, "read_sbit"},
+ {MNG_FN_READ_SPLT, "read_splt"},
+ {MNG_FN_READ_HIST, "read_hist"},
+ {MNG_FN_READ_TIME, "read_time"},
+ {MNG_FN_READ_MHDR, "read_mhdr"},
+ {MNG_FN_READ_MEND, "read_mend"},
+ {MNG_FN_READ_LOOP, "read_loop"},
+ {MNG_FN_READ_ENDL, "read_endl"},
+ {MNG_FN_READ_DEFI, "read_defi"},
+ {MNG_FN_READ_BASI, "read_basi"},
+ {MNG_FN_READ_CLON, "read_clon"},
+ {MNG_FN_READ_PAST, "read_past"},
+ {MNG_FN_READ_DISC, "read_disc"},
+ {MNG_FN_READ_BACK, "read_back"},
+ {MNG_FN_READ_FRAM, "read_fram"},
+ {MNG_FN_READ_MOVE, "read_move"},
+ {MNG_FN_READ_CLIP, "read_clip"},
+ {MNG_FN_READ_SHOW, "read_show"},
+ {MNG_FN_READ_TERM, "read_term"},
+ {MNG_FN_READ_SAVE, "read_save"},
+ {MNG_FN_READ_SEEK, "read_seek"},
+ {MNG_FN_READ_EXPI, "read_expi"},
+ {MNG_FN_READ_FPRI, "read_fpri"},
+ {MNG_FN_READ_NEED, "read_need"},
+ {MNG_FN_READ_PHYG, "read_phyg"},
+ {MNG_FN_READ_JHDR, "read_jhdr"},
+ {MNG_FN_READ_JDAT, "read_jdat"},
+ {MNG_FN_READ_JSEP, "read_jsep"},
+ {MNG_FN_READ_DHDR, "read_dhdr"},
+ {MNG_FN_READ_PROM, "read_prom"},
+ {MNG_FN_READ_IPNG, "read_ipng"},
+ {MNG_FN_READ_PPLT, "read_pplt"},
+ {MNG_FN_READ_IJNG, "read_ijng"},
+ {MNG_FN_READ_DROP, "read_drop"},
+ {MNG_FN_READ_DBYK, "read_dbyk"},
+ {MNG_FN_READ_ORDR, "read_ordr"},
+ {MNG_FN_READ_UNKNOWN, "read_unknown"},
+ {MNG_FN_READ_MAGN, "read_magn"},
+ {MNG_FN_READ_JDAA, "read_jdaa"},
+
+ {MNG_FN_WRITE_IHDR, "write_ihdr"},
+ {MNG_FN_WRITE_PLTE, "write_plte"},
+ {MNG_FN_WRITE_IDAT, "write_idat"},
+ {MNG_FN_WRITE_IEND, "write_iend"},
+ {MNG_FN_WRITE_TRNS, "write_trns"},
+ {MNG_FN_WRITE_GAMA, "write_gama"},
+ {MNG_FN_WRITE_CHRM, "write_chrm"},
+ {MNG_FN_WRITE_SRGB, "write_srgb"},
+ {MNG_FN_WRITE_ICCP, "write_iccp"},
+ {MNG_FN_WRITE_TEXT, "write_text"},
+ {MNG_FN_WRITE_ZTXT, "write_ztxt"},
+ {MNG_FN_WRITE_ITXT, "write_itxt"},
+ {MNG_FN_WRITE_BKGD, "write_bkgd"},
+ {MNG_FN_WRITE_PHYS, "write_phys"},
+ {MNG_FN_WRITE_SBIT, "write_sbit"},
+ {MNG_FN_WRITE_SPLT, "write_splt"},
+ {MNG_FN_WRITE_HIST, "write_hist"},
+ {MNG_FN_WRITE_TIME, "write_time"},
+ {MNG_FN_WRITE_MHDR, "write_mhdr"},
+ {MNG_FN_WRITE_MEND, "write_mend"},
+ {MNG_FN_WRITE_LOOP, "write_loop"},
+ {MNG_FN_WRITE_ENDL, "write_endl"},
+ {MNG_FN_WRITE_DEFI, "write_defi"},
+ {MNG_FN_WRITE_BASI, "write_basi"},
+ {MNG_FN_WRITE_CLON, "write_clon"},
+ {MNG_FN_WRITE_PAST, "write_past"},
+ {MNG_FN_WRITE_DISC, "write_disc"},
+ {MNG_FN_WRITE_BACK, "write_back"},
+ {MNG_FN_WRITE_FRAM, "write_fram"},
+ {MNG_FN_WRITE_MOVE, "write_move"},
+ {MNG_FN_WRITE_CLIP, "write_clip"},
+ {MNG_FN_WRITE_SHOW, "write_show"},
+ {MNG_FN_WRITE_TERM, "write_term"},
+ {MNG_FN_WRITE_SAVE, "write_save"},
+ {MNG_FN_WRITE_SEEK, "write_seek"},
+ {MNG_FN_WRITE_EXPI, "write_expi"},
+ {MNG_FN_WRITE_FPRI, "write_fpri"},
+ {MNG_FN_WRITE_NEED, "write_need"},
+ {MNG_FN_WRITE_PHYG, "write_phyg"},
+ {MNG_FN_WRITE_JHDR, "write_jhdr"},
+ {MNG_FN_WRITE_JDAT, "write_jdat"},
+ {MNG_FN_WRITE_JSEP, "write_jsep"},
+ {MNG_FN_WRITE_DHDR, "write_dhdr"},
+ {MNG_FN_WRITE_PROM, "write_prom"},
+ {MNG_FN_WRITE_IPNG, "write_ipng"},
+ {MNG_FN_WRITE_PPLT, "write_pplt"},
+ {MNG_FN_WRITE_IJNG, "write_ijng"},
+ {MNG_FN_WRITE_DROP, "write_drop"},
+ {MNG_FN_WRITE_DBYK, "write_dbyk"},
+ {MNG_FN_WRITE_ORDR, "write_ordr"},
+ {MNG_FN_WRITE_UNKNOWN, "write_unknown"},
+ {MNG_FN_WRITE_MAGN, "write_magn"},
+ {MNG_FN_WRITE_JDAA, "write_jdaa"},
+
+ {MNG_FN_ZLIB_INITIALIZE, "zlib_initialize"},
+ {MNG_FN_ZLIB_CLEANUP, "zlib_cleanup"},
+ {MNG_FN_ZLIB_INFLATEINIT, "zlib_inflateinit"},
+ {MNG_FN_ZLIB_INFLATEROWS, "zlib_inflaterows"},
+ {MNG_FN_ZLIB_INFLATEDATA, "zlib_inflatedata"},
+ {MNG_FN_ZLIB_INFLATEFREE, "zlib_inflatefree"},
+ {MNG_FN_ZLIB_DEFLATEINIT, "zlib_deflateinit"},
+ {MNG_FN_ZLIB_DEFLATEROWS, "zlib_deflaterows"},
+ {MNG_FN_ZLIB_DEFLATEDATA, "zlib_deflatedata"},
+ {MNG_FN_ZLIB_DEFLATEFREE, "zlib_deflatefree"},
+
+ {MNG_FN_PROCESS_DISPLAY_IHDR, "process_display_ihdr"},
+ {MNG_FN_PROCESS_DISPLAY_PLTE, "process_display_plte"},
+ {MNG_FN_PROCESS_DISPLAY_IDAT, "process_display_idat"},
+ {MNG_FN_PROCESS_DISPLAY_IEND, "process_display_iend"},
+ {MNG_FN_PROCESS_DISPLAY_TRNS, "process_display_trns"},
+ {MNG_FN_PROCESS_DISPLAY_GAMA, "process_display_gama"},
+ {MNG_FN_PROCESS_DISPLAY_CHRM, "process_display_chrm"},
+ {MNG_FN_PROCESS_DISPLAY_SRGB, "process_display_srgb"},
+ {MNG_FN_PROCESS_DISPLAY_ICCP, "process_display_iccp"},
+ {MNG_FN_PROCESS_DISPLAY_BKGD, "process_display_bkgd"},
+ {MNG_FN_PROCESS_DISPLAY_PHYS, "process_display_phys"},
+ {MNG_FN_PROCESS_DISPLAY_SBIT, "process_display_sbit"},
+ {MNG_FN_PROCESS_DISPLAY_SPLT, "process_display_splt"},
+ {MNG_FN_PROCESS_DISPLAY_HIST, "process_display_hist"},
+ {MNG_FN_PROCESS_DISPLAY_MHDR, "process_display_mhdr"},
+ {MNG_FN_PROCESS_DISPLAY_MEND, "process_display_mend"},
+ {MNG_FN_PROCESS_DISPLAY_LOOP, "process_display_loop"},
+ {MNG_FN_PROCESS_DISPLAY_ENDL, "process_display_endl"},
+ {MNG_FN_PROCESS_DISPLAY_DEFI, "process_display_defi"},
+ {MNG_FN_PROCESS_DISPLAY_BASI, "process_display_basi"},
+ {MNG_FN_PROCESS_DISPLAY_CLON, "process_display_clon"},
+ {MNG_FN_PROCESS_DISPLAY_PAST, "process_display_past"},
+ {MNG_FN_PROCESS_DISPLAY_DISC, "process_display_disc"},
+ {MNG_FN_PROCESS_DISPLAY_BACK, "process_display_back"},
+ {MNG_FN_PROCESS_DISPLAY_FRAM, "process_display_fram"},
+ {MNG_FN_PROCESS_DISPLAY_MOVE, "process_display_move"},
+ {MNG_FN_PROCESS_DISPLAY_CLIP, "process_display_clip"},
+ {MNG_FN_PROCESS_DISPLAY_SHOW, "process_display_show"},
+ {MNG_FN_PROCESS_DISPLAY_TERM, "process_display_term"},
+ {MNG_FN_PROCESS_DISPLAY_SAVE, "process_display_save"},
+ {MNG_FN_PROCESS_DISPLAY_SEEK, "process_display_seek"},
+ {MNG_FN_PROCESS_DISPLAY_EXPI, "process_display_expi"},
+ {MNG_FN_PROCESS_DISPLAY_FPRI, "process_display_fpri"},
+ {MNG_FN_PROCESS_DISPLAY_NEED, "process_display_need"},
+ {MNG_FN_PROCESS_DISPLAY_PHYG, "process_display_phyg"},
+ {MNG_FN_PROCESS_DISPLAY_JHDR, "process_display_jhdr"},
+ {MNG_FN_PROCESS_DISPLAY_JDAT, "process_display_jdat"},
+ {MNG_FN_PROCESS_DISPLAY_JSEP, "process_display_jsep"},
+ {MNG_FN_PROCESS_DISPLAY_DHDR, "process_display_dhdr"},
+ {MNG_FN_PROCESS_DISPLAY_PROM, "process_display_prom"},
+ {MNG_FN_PROCESS_DISPLAY_IPNG, "process_display_ipng"},
+ {MNG_FN_PROCESS_DISPLAY_PPLT, "process_display_pplt"},
+ {MNG_FN_PROCESS_DISPLAY_IJNG, "process_display_ijng"},
+ {MNG_FN_PROCESS_DISPLAY_DROP, "process_display_drop"},
+ {MNG_FN_PROCESS_DISPLAY_DBYK, "process_display_dbyk"},
+ {MNG_FN_PROCESS_DISPLAY_ORDR, "process_display_ordr"},
+ {MNG_FN_PROCESS_DISPLAY_MAGN, "process_display_magn"},
+ {MNG_FN_PROCESS_DISPLAY_JDAA, "process_display_jdaa"},
+
+ {MNG_FN_JPEG_INITIALIZE, "jpeg_initialize"},
+ {MNG_FN_JPEG_CLEANUP, "jpeg_cleanup"},
+ {MNG_FN_JPEG_DECOMPRESSINIT, "jpeg_decompressinit"},
+ {MNG_FN_JPEG_DECOMPRESSDATA, "jpeg_decompressdata"},
+ {MNG_FN_JPEG_DECOMPRESSFREE, "jpeg_decompressfree"},
+
+ {MNG_FN_STORE_JPEG_G8, "store_jpeg_g8"},
+ {MNG_FN_STORE_JPEG_RGB8, "store_jpeg_rgb8"},
+ {MNG_FN_STORE_JPEG_G12, "store_jpeg_g12"},
+ {MNG_FN_STORE_JPEG_RGB12, "store_jpeg_rgb12"},
+ {MNG_FN_STORE_JPEG_GA8, "store_jpeg_ga8"},
+ {MNG_FN_STORE_JPEG_RGBA8, "store_jpeg_rgba8"},
+ {MNG_FN_STORE_JPEG_GA12, "store_jpeg_ga12"},
+ {MNG_FN_STORE_JPEG_RGBA12, "store_jpeg_rgba12"},
+ {MNG_FN_STORE_JPEG_G8_ALPHA, "store_jpeg_g8_alpha"},
+ {MNG_FN_STORE_JPEG_RGB8_ALPHA, "store_jpeg_rgb8_alpha"},
+
+ {MNG_FN_INIT_JPEG_A1_NI, "init_jpeg_a1_ni"},
+ {MNG_FN_INIT_JPEG_A2_NI, "init_jpeg_a2_ni"},
+ {MNG_FN_INIT_JPEG_A4_NI, "init_jpeg_a4_ni"},
+ {MNG_FN_INIT_JPEG_A8_NI, "init_jpeg_a8_ni"},
+ {MNG_FN_INIT_JPEG_A16_NI, "init_jpeg_a16_ni"},
+
+ {MNG_FN_STORE_JPEG_G8_A1, "store_jpeg_g8_a1"},
+ {MNG_FN_STORE_JPEG_G8_A2, "store_jpeg_g8_a2"},
+ {MNG_FN_STORE_JPEG_G8_A4, "store_jpeg_g8_a4"},
+ {MNG_FN_STORE_JPEG_G8_A8, "store_jpeg_g8_a8"},
+ {MNG_FN_STORE_JPEG_G8_A16, "store_jpeg_g8_a16"},
+
+ {MNG_FN_STORE_JPEG_RGB8_A1, "store_jpeg_rgb8_a1"},
+ {MNG_FN_STORE_JPEG_RGB8_A2, "store_jpeg_rgb8_a2"},
+ {MNG_FN_STORE_JPEG_RGB8_A4, "store_jpeg_rgb8_a4"},
+ {MNG_FN_STORE_JPEG_RGB8_A8, "store_jpeg_rgb8_a8"},
+ {MNG_FN_STORE_JPEG_RGB8_A16, "store_jpeg_rgb8_a16"},
+
+ {MNG_FN_STORE_JPEG_G12_A1, "store_jpeg_g12_a1"},
+ {MNG_FN_STORE_JPEG_G12_A2, "store_jpeg_g12_a2"},
+ {MNG_FN_STORE_JPEG_G12_A4, "store_jpeg_g12_a4"},
+ {MNG_FN_STORE_JPEG_G12_A8, "store_jpeg_g12_a8"},
+ {MNG_FN_STORE_JPEG_G12_A16, "store_jpeg_g12_a16"},
+
+ {MNG_FN_STORE_JPEG_RGB12_A1, "store_jpeg_rgb12_a1"},
+ {MNG_FN_STORE_JPEG_RGB12_A2, "store_jpeg_rgb12_a2"},
+ {MNG_FN_STORE_JPEG_RGB12_A4, "store_jpeg_rgb12_a4"},
+ {MNG_FN_STORE_JPEG_RGB12_A8, "store_jpeg_rgb12_a8"},
+ {MNG_FN_STORE_JPEG_RGB12_A16, "store_jpeg_rgb12_a16"},
+
+ {MNG_FN_NEXT_JPEG_ALPHAROW, "next_jpeg_alpharow"},
+ {MNG_FN_NEXT_JPEG_ROW, "next_jpeg_row"},
+ {MNG_FN_DISPLAY_JPEG_ROWS, "display_jpeg_rows"},
+
+ {MNG_FN_MAGNIFY_G8_X1, "magnify_g8_x1"},
+ {MNG_FN_MAGNIFY_G8_X2, "magnify_g8_x2"},
+ {MNG_FN_MAGNIFY_RGB8_X1, "magnify_rgb8_x1"},
+ {MNG_FN_MAGNIFY_RGB8_X2, "magnify_rgb8_x2"},
+ {MNG_FN_MAGNIFY_GA8_X1, "magnify_ga8_x1"},
+ {MNG_FN_MAGNIFY_GA8_X2, "magnify_ga8_x2"},
+ {MNG_FN_MAGNIFY_GA8_X3, "magnify_ga8_x3"},
+ {MNG_FN_MAGNIFY_GA8_X4, "magnify_ga8_x4"},
+ {MNG_FN_MAGNIFY_RGBA8_X1, "magnify_rgba8_x1"},
+ {MNG_FN_MAGNIFY_RGBA8_X2, "magnify_rgba8_x2"},
+ {MNG_FN_MAGNIFY_RGBA8_X3, "magnify_rgba8_x3"},
+ {MNG_FN_MAGNIFY_RGBA8_X4, "magnify_rgba8_x4"},
+ {MNG_FN_MAGNIFY_G8_X3, "magnify_g8_x3"},
+ {MNG_FN_MAGNIFY_RGB8_X3, "magnify_rgb8_x3"},
+ {MNG_FN_MAGNIFY_GA8_X5, "magnify_ga8_x5"},
+ {MNG_FN_MAGNIFY_RGBA8_X5, "magnify_rgba8_x5"},
+
+ {MNG_FN_MAGNIFY_G8_Y1, "magnify_g8_y1"},
+ {MNG_FN_MAGNIFY_G8_Y2, "magnify_g8_y2"},
+ {MNG_FN_MAGNIFY_RGB8_Y1, "magnify_rgb8_y1"},
+ {MNG_FN_MAGNIFY_RGB8_Y2, "magnify_rgb8_y2"},
+ {MNG_FN_MAGNIFY_GA8_Y1, "magnify_ga8_y1"},
+ {MNG_FN_MAGNIFY_GA8_Y2, "magnify_ga8_y2"},
+ {MNG_FN_MAGNIFY_GA8_Y3, "magnify_ga8_y3"},
+ {MNG_FN_MAGNIFY_GA8_Y4, "magnify_ga8_y4"},
+ {MNG_FN_MAGNIFY_RGBA8_Y1, "magnify_rgba8_y1"},
+ {MNG_FN_MAGNIFY_RGBA8_Y2, "magnify_rgba8_y2"},
+ {MNG_FN_MAGNIFY_RGBA8_Y3, "magnify_rgba8_y3"},
+ {MNG_FN_MAGNIFY_RGBA8_Y4, "magnify_rgba8_y4"},
+ {MNG_FN_MAGNIFY_G8_Y3, "magnify_g8_y3"},
+ {MNG_FN_MAGNIFY_RGB8_Y3, "magnify_rgb8_y3"},
+ {MNG_FN_MAGNIFY_GA8_Y5, "magnify_ga8_y5"},
+ {MNG_FN_MAGNIFY_RGBA8_Y5, "magnify_rgba8_y5"},
+
+ {MNG_FN_DELTA_G1_G1, "delta_g1_g1"},
+ {MNG_FN_DELTA_G2_G2, "delta_g2_g2"},
+ {MNG_FN_DELTA_G4_G4, "delta_g4_g4"},
+ {MNG_FN_DELTA_G8_G8, "delta_g8_g8"},
+ {MNG_FN_DELTA_G16_G16, "delta_g16_g16"},
+ {MNG_FN_DELTA_RGB8_RGB8, "delta_rgb8_rgb8"},
+ {MNG_FN_DELTA_RGB16_RGB16, "delta_rgb16_rgb16"},
+ {MNG_FN_DELTA_GA8_GA8, "delta_ga8_ga8"},
+ {MNG_FN_DELTA_GA8_G8, "delta_ga8_g8"},
+ {MNG_FN_DELTA_GA8_A8, "delta_ga8_a8"},
+ {MNG_FN_DELTA_GA16_GA16, "delta_ga16_ga16"},
+ {MNG_FN_DELTA_GA16_G16, "delta_ga16_g16"},
+ {MNG_FN_DELTA_GA16_A16, "delta_ga16_a16"},
+ {MNG_FN_DELTA_RGBA8_RGBA8, "delta_rgba8_rgba8"},
+ {MNG_FN_DELTA_RGBA8_RGB8, "delta_rgba8_rgb8"},
+ {MNG_FN_DELTA_RGBA8_A8, "delta_rgba8_a8"},
+ {MNG_FN_DELTA_RGBA16_RGBA16, "delta_rgba16_rgba16"},
+ {MNG_FN_DELTA_RGBA16_RGB16, "delta_rgba16_rgb16"},
+ {MNG_FN_DELTA_RGBA16_A16, "delta_rgba16_a16"},
+ };
+#endif /* MNG_INCLUDE_TRACE_STINGS */
+
+/* ************************************************************************** */
+
+mng_retcode mng_trace (mng_datap pData,
+ mng_uint32 iFunction,
+ mng_uint32 iLocation)
+{
+ mng_pchar zName = 0; /* bufferptr for tracestring */
+
+ if ((pData == 0) || (pData->iMagic != MNG_MAGIC))
+ return MNG_INVALIDHANDLE; /* no good if the handle is corrupt */
+
+ if (pData->fTraceproc) /* report back to user ? */
+ {
+#ifdef MNG_INCLUDE_TRACE_STRINGS
+ { /* binary search variables */
+ mng_int32 iTop, iLower, iUpper, iMiddle;
+ mng_trace_entryp pEntry; /* pointer to found entry */
+ /* determine max index of table */
+ iTop = (sizeof (trace_table) / sizeof (trace_table [0])) - 1;
+
+ iLower = 0; /* initialize binary search */
+ iMiddle = iTop >> 1; /* start in the middle */
+ iUpper = iTop;
+ pEntry = 0; /* no goods yet! */
+
+ do /* the binary search itself */
+ {
+ if (trace_table [iMiddle].iFunction < iFunction)
+ iLower = iMiddle + 1;
+ else if (trace_table [iMiddle].iFunction > iFunction)
+ iUpper = iMiddle - 1;
+ else
+ {
+ pEntry = &trace_table [iMiddle];
+ break;
+ };
+
+ iMiddle = (iLower + iUpper) >> 1;
+ }
+ while (iLower <= iUpper);
+
+ if (pEntry) /* found it ? */
+ zName = pEntry->zTracetext;
+
+ }
+#endif
+ /* oke, now tell */
+ if (!pData->fTraceproc (((mng_handle)pData), iFunction, iLocation, zName))
+ return MNG_APPTRACEABORT;
+
+ }
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_TRACE_PROCS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_trace.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_trace.h
new file mode 100644
index 0000000..e8824da
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_trace.h
@@ -0,0 +1,1215 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_trace.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.3 * */
+/* * * */
+/* * purpose : Trace functions (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the trace functions * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - added chunk-access function trace-codes * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * 0.5.1 - 05/13/2000 - G.Juyn * */
+/* * - added save_state & restore_state trace-codes * */
+/* * 0.5.1 - 05/15/2000 - G.Juyn * */
+/* * - added getimgdata & putimgdata trace-codes * */
+/* * * */
+/* * 0.5.2 - 05/20/2000 - G.Juyn * */
+/* * - added JNG tracecodes * */
+/* * 0.5.2 - 05/23/2000 - G.Juyn * */
+/* * - added trace-table entry definition * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - added tracecodes for global animation color-chunks * */
+/* * - added tracecodes for get/set of default ZLIB/IJG parms * */
+/* * - added tracecodes for global PLTE,tRNS,bKGD * */
+/* * 0.5.2 - 05/30/2000 - G.Juyn * */
+/* * - added tracecodes for image-object promotion * */
+/* * - added tracecodes for delta-image processing * */
+/* * 0.5.2 - 06/02/2000 - G.Juyn * */
+/* * - added tracecodes for getalphaline callback * */
+/* * 0.5.2 - 06/05/2000 - G.Juyn * */
+/* * - added tracecode for RGB8_A8 canvasstyle * */
+/* * 0.5.2 - 06/06/2000 - G.Juyn * */
+/* * - added tracecode for mng_read_resume HLAPI function * */
+/* * * */
+/* * 0.5.3 - 06/06/2000 - G.Juyn * */
+/* * - added tracecodes for tracing JPEG progression * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added tracecodes for get/set speedtype * */
+/* * - added tracecodes for get imagelevel * */
+/* * 0.5.3 - 06/22/2000 - G.Juyn * */
+/* * - added tracecode for delta-image processing * */
+/* * - added tracecodes for PPLT chunk processing * */
+/* * * */
+/* * 0.9.1 - 07/07/2000 - G.Juyn * */
+/* * - added tracecodes for special display processing * */
+/* * 0.9.1 - 07/08/2000 - G.Juyn * */
+/* * - added tracecode for get/set suspensionmode * */
+/* * - added tracecodes for get/set display variables * */
+/* * - added tracecode for read_databuffer (I/O-suspension) * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - added tracecodes for SAVE/SEEK callbacks * */
+/* * - added tracecodes for get/set sectionbreaks * */
+/* * - added tracecode for special error routine * */
+/* * 0.9.1 - 07/19/2000 - G.Juyn * */
+/* * - added tracecode for updatemngheader * */
+/* * * */
+/* * 0.9.2 - 07/31/2000 - G.Juyn * */
+/* * - added tracecodes for status_xxxxx functions * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * - added tracecode for updatemngsimplicity * */
+/* * * */
+/* * 0.9.3 - 08/26/2000 - G.Juyn * */
+/* * - added MAGN chunk * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * 0.9.3 - 10/10/2000 - G.Juyn * */
+/* * - added support for alpha-depth prediction * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - added JDAA chunk * */
+/* * - added support for nEED * */
+/* * 0.9.3 - 10/16/2000 - G.Juyn * */
+/* * - added functions to retrieve PNG/JNG specific header-info * */
+/* * - added optional support for bKGD for PNG images * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - added callback to process non-critical unknown chunks * */
+/* * - added routine to discard "invalid" objects * */
+/* * 0.9.3 - 10/19/2000 - G.Juyn * */
+/* * - implemented delayed delta-processing * */
+/* * 0.9.3 - 10/20/2000 - G.Juyn * */
+/* * - added get/set for bKGD preference setting * */
+/* * 0.9.3 - 10/21/2000 - G.Juyn * */
+/* * - added get function for interlace/progressive display * */
+/* * * */
+/* * 0.9.4 - 1/18/2001 - G.Juyn * */
+/* * - added "new" MAGN methods 3, 4 & 5 * */
+/* * * */
+/* * 1.0.1 - 02/08/2001 - G.Juyn * */
+/* * - added MEND processing callback * */
+/* * 1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly) * */
+/* * - added BGRA8 canvas with premultiplied alpha * */
+/* * 1.0.1 - 05/02/2001 - G.Juyn * */
+/* * - added "default" sRGB generation (Thanks Marti!) * */
+/* * * */
+/* * 1.0.2 - 06/23/2001 - G.Juyn * */
+/* * - added optimization option for MNG-video playback * */
+/* * - added processterm callback * */
+/* * 1.0.2 - 06/25/2001 - G.Juyn * */
+/* * - added option to turn off progressive refresh * */
+/* * * */
+/* * 1.0.3 - 08/06/2001 - G.Juyn * */
+/* * - added get function for last processed BACK chunk * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_trace_h_
+#define _libmng_trace_h_
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_TRACE_PROCS
+
+/* ************************************************************************** */
+
+/* TODO: add a trace-tqmask so certain functions can be excluded */
+
+mng_retcode mng_trace (mng_datap pData,
+ mng_uint32 iFunction,
+ mng_uint32 iLocation);
+
+/* ************************************************************************** */
+
+#define MNG_TRACE(D,F,L) { mng_retcode iR = mng_trace (D,F,L); \
+ if (iR) return iR; }
+
+#define MNG_TRACEB(D,F,L) { if (mng_trace (D,F,L)) return MNG_FALSE; }
+
+#define MNG_TRACEX(D,F,L) { if (mng_trace (D,F,L)) return 0; }
+
+/* ************************************************************************** */
+
+#define MNG_LC_START 1
+#define MNG_LC_END 2
+#define MNG_LC_INITIALIZE 3
+#define MNG_LC_CLEANUP 4
+
+/* ************************************************************************** */
+
+#define MNG_LC_JPEG_CREATE_DECOMPRESS 101
+#define MNG_LC_JPEG_READ_HEADER 102
+#define MNG_LC_JPEG_START_DECOMPRESS 103
+#define MNG_LC_JPEG_START_OUTPUT 104
+#define MNG_LC_JPEG_READ_SCANLINES 105
+#define MNG_LC_JPEG_FINISH_OUTPUT 106
+#define MNG_LC_JPEG_FINISH_DECOMPRESS 107
+#define MNG_LC_JPEG_DESTROY_DECOMPRESS 108
+
+/* ************************************************************************** */
+
+#define MNG_FN_INITIALIZE 1
+#define MNG_FN_RESET 2
+#define MNG_FN_CLEANUP 3
+#define MNG_FN_READ 4
+#define MNG_FN_WRITE 5
+#define MNG_FN_CREATE 6
+#define MNG_FN_READDISPLAY 7
+#define MNG_FN_DISPLAY 8
+#define MNG_FN_DISPLAY_RESUME 9
+#define MNG_FN_DISPLAY_FREEZE 10
+#define MNG_FN_DISPLAY_RESET 11
+#define MNG_FN_DISPLAY_GOFRAME 12
+#define MNG_FN_DISPLAY_GOLAYER 13
+#define MNG_FN_DISPLAY_GOTIME 14
+#define MNG_FN_GETLASTERROR 15
+#define MNG_FN_READ_RESUME 16
+
+#define MNG_FN_SETCB_MEMALLOC 101
+#define MNG_FN_SETCB_MEMFREE 102
+#define MNG_FN_SETCB_READDATA 103
+#define MNG_FN_SETCB_WRITEDATA 104
+#define MNG_FN_SETCB_ERRORPROC 105
+#define MNG_FN_SETCB_TRACEPROC 106
+#define MNG_FN_SETCB_PROCESSHEADER 107
+#define MNG_FN_SETCB_PROCESSTEXT 108
+#define MNG_FN_SETCB_GETCANVASLINE 109
+#define MNG_FN_SETCB_GETBKGDLINE 110
+#define MNG_FN_SETCB_REFRESH 111
+#define MNG_FN_SETCB_GETTICKCOUNT 112
+#define MNG_FN_SETCB_SETTIMER 113
+#define MNG_FN_SETCB_PROCESSGAMMA 114
+#define MNG_FN_SETCB_PROCESSCHROMA 115
+#define MNG_FN_SETCB_PROCESSSRGB 116
+#define MNG_FN_SETCB_PROCESSICCP 117
+#define MNG_FN_SETCB_PROCESSAROW 118
+#define MNG_FN_SETCB_OPENSTREAM 119
+#define MNG_FN_SETCB_CLOSESTREAM 120
+#define MNG_FN_SETCB_GETALPHALINE 121
+#define MNG_FN_SETCB_PROCESSSAVE 122
+#define MNG_FN_SETCB_PROCESSSEEK 123
+#define MNG_FN_SETCB_PROCESSNEED 124
+#define MNG_FN_SETCB_PROCESSUNKNOWN 125
+#define MNG_FN_SETCB_PROCESSMEND 126
+#define MNG_FN_SETCB_PROCESSTERM 127
+
+#define MNG_FN_GETCB_MEMALLOC 201
+#define MNG_FN_GETCB_MEMFREE 202
+#define MNG_FN_GETCB_READDATA 203
+#define MNG_FN_GETCB_WRITEDATA 204
+#define MNG_FN_GETCB_ERRORPROC 205
+#define MNG_FN_GETCB_TRACEPROC 206
+#define MNG_FN_GETCB_PROCESSHEADER 207
+#define MNG_FN_GETCB_PROCESSTEXT 208
+#define MNG_FN_GETCB_GETCANVASLINE 209
+#define MNG_FN_GETCB_GETBKGDLINE 210
+#define MNG_FN_GETCB_REFRESH 211
+#define MNG_FN_GETCB_GETTICKCOUNT 212
+#define MNG_FN_GETCB_SETTIMER 213
+#define MNG_FN_GETCB_PROCESSGAMMA 214
+#define MNG_FN_GETCB_PROCESSCHROMA 215
+#define MNG_FN_GETCB_PROCESSSRGB 216
+#define MNG_FN_GETCB_PROCESSICCP 217
+#define MNG_FN_GETCB_PROCESSAROW 218
+#define MNG_FN_GETCB_OPENSTREAM 219
+#define MNG_FN_GETCB_CLOSESTREAM 220
+#define MNG_FN_GETCB_GETALPHALINE 221
+#define MNG_FN_GETCB_PROCESSSAVE 222
+#define MNG_FN_GETCB_PROCESSSEEK 223
+#define MNG_FN_GETCB_PROCESSNEED 224
+#define MNG_FN_GETCB_PROCESSUNKNOWN 225
+#define MNG_FN_GETCB_PROCESSMEND 226
+#define MNG_FN_GETCB_PROCESSTERM 227
+
+#define MNG_FN_SET_USERDATA 301
+#define MNG_FN_SET_CANVASSTYLE 302
+#define MNG_FN_SET_BKGDSTYLE 303
+#define MNG_FN_SET_BGCOLOR 304
+#define MNG_FN_SET_STORECHUNKS 305
+#define MNG_FN_SET_VIEWGAMMA 306
+#define MNG_FN_SET_DISPLAYGAMMA 307
+#define MNG_FN_SET_DFLTIMGGAMMA 308
+#define MNG_FN_SET_SRGB 309
+#define MNG_FN_SET_OUTPUTPROFILE 310
+#define MNG_FN_SET_SRGBPROFILE 311
+#define MNG_FN_SET_MAXCANVASWIDTH 312
+#define MNG_FN_SET_MAXCANVASHEIGHT 313
+#define MNG_FN_SET_MAXCANVASSIZE 314
+#define MNG_FN_SET_ZLIB_LEVEL 315
+#define MNG_FN_SET_ZLIB_METHOD 316
+#define MNG_FN_SET_ZLIB_WINDOWBITS 317
+#define MNG_FN_SET_ZLIB_MEMLEVEL 318
+#define MNG_FN_SET_ZLIB_STRATEGY 319
+#define MNG_FN_SET_ZLIB_MAXIDAT 320
+#define MNG_FN_SET_JPEG_DCTQT_METHOD 321
+#define MNG_FN_SET_JPEG_TQUALITY 322
+#define MNG_FN_SET_JPEG_SMOOTHING 323
+#define MNG_FN_SET_JPEG_PROGRESSIVE 324
+#define MNG_FN_SET_JPEG_OPTIMIZED 325
+#define MNG_FN_SET_JPEG_MAXJDAT 326
+#define MNG_FN_SET_SPEED 327
+#define MNG_FN_SET_SUSPENSIONMODE 328
+#define MNG_FN_SET_SECTIONBREAKS 329
+#define MNG_FN_SET_USEBKGD 330
+#define MNG_FN_SET_OUTPUTPROFILE2 331
+#define MNG_FN_SET_SRGBPROFILE2 332
+#define MNG_FN_SET_OUTPUTSRGB 333
+#define MNG_FN_SET_SRGBIMPLICIT 334
+#define MNG_FN_SET_CACHEPLAYBACK 335
+#define MNG_FN_SET_DOPROGRESSIVE 336
+
+#define MNG_FN_GET_USERDATA 401
+#define MNG_FN_GET_SIGTYPE 402
+#define MNG_FN_GET_IMAGETYPE 403
+#define MNG_FN_GET_IMAGEWIDTH 404
+#define MNG_FN_GET_IMAGEHEIGHT 405
+#define MNG_FN_GET_TICKS 406
+#define MNG_FN_GET_FRAMECOUNT 407
+#define MNG_FN_GET_LAYERCOUNT 408
+#define MNG_FN_GET_PLAYTIME 409
+#define MNG_FN_GET_SIMPLICITY 410
+#define MNG_FN_GET_CANVASSTYLE 411
+#define MNG_FN_GET_BKGDSTYLE 412
+#define MNG_FN_GET_BGCOLOR 413
+#define MNG_FN_GET_STORECHUNKS 414
+#define MNG_FN_GET_VIEWGAMMA 415
+#define MNG_FN_GET_DISPLAYGAMMA 416
+#define MNG_FN_GET_DFLTIMGGAMMA 417
+#define MNG_FN_GET_SRGB 418
+#define MNG_FN_GET_MAXCANVASWIDTH 419
+#define MNG_FN_GET_MAXCANVASHEIGHT 420
+#define MNG_FN_GET_ZLIB_LEVEL 421
+#define MNG_FN_GET_ZLIB_METHOD 422
+#define MNG_FN_GET_ZLIB_WINDOWBITS 423
+#define MNG_FN_GET_ZLIB_MEMLEVEL 424
+#define MNG_FN_GET_ZLIB_STRATEGY 425
+#define MNG_FN_GET_ZLIB_MAXIDAT 426
+#define MNG_FN_GET_JPEG_DCTQT_METHOD 427
+#define MNG_FN_GET_JPEG_TQUALITY 428
+#define MNG_FN_GET_JPEG_SMOOTHING 429
+#define MNG_FN_GET_JPEG_PROGRESSIVE 430
+#define MNG_FN_GET_JPEG_OPTIMIZED 431
+#define MNG_FN_GET_JPEG_MAXJDAT 432
+#define MNG_FN_GET_SPEED 433
+#define MNG_FN_GET_IMAGELEVEL 434
+#define MNG_FN_GET_SUSPENSIONMODE 435
+#define MNG_FN_GET_STARTTIME 436
+#define MNG_FN_GET_RUNTIME 437
+#define MNG_FN_GET_CURRENTFRAME 438
+#define MNG_FN_GET_CURRENTLAYER 439
+#define MNG_FN_GET_CURRENTPLAYTIME 440
+#define MNG_FN_GET_SECTIONBREAKS 441
+#define MNG_FN_GET_ALPHADEPTH 442
+#define MNG_FN_GET_BITDEPTH 443
+#define MNG_FN_GET_COLORTYPE 444
+#define MNG_FN_GET_COMPRESSION 445
+#define MNG_FN_GET_FILTER 446
+#define MNG_FN_GET_INTERLACE 447
+#define MNG_FN_GET_ALPHABITDEPTH 448
+#define MNG_FN_GET_ALPHACOMPRESSION 449
+#define MNG_FN_GET_ALPHAFILTER 450
+#define MNG_FN_GET_ALPHAINTERLACE 451
+#define MNG_FN_GET_USEBKGD 452
+#define MNG_FN_GET_REFRESHPASS 453
+#define MNG_FN_GET_CACHEPLAYBACK 454
+#define MNG_FN_GET_DOPROGRESSIVE 455
+#define MNG_FN_GET_LASTBACKCHUNK 456
+
+#define MNG_FN_STATUS_ERROR 481
+#define MNG_FN_STATUS_READING 482
+#define MNG_FN_STATUS_SUSPENDBREAK 483
+#define MNG_FN_STATUS_CREATING 484
+#define MNG_FN_STATUS_WRITING 485
+#define MNG_FN_STATUS_DISPLAYING 486
+#define MNG_FN_STATUS_RUNNING 487
+#define MNG_FN_STATUS_TIMERBREAK 488
+
+/* ************************************************************************** */
+
+#define MNG_FN_ITERATE_CHUNKS 601
+
+#define MNG_FN_GETCHUNK_IHDR 701
+#define MNG_FN_GETCHUNK_PLTE 702
+#define MNG_FN_GETCHUNK_IDAT 703
+#define MNG_FN_GETCHUNK_IEND 704
+#define MNG_FN_GETCHUNK_TRNS 705
+#define MNG_FN_GETCHUNK_GAMA 706
+#define MNG_FN_GETCHUNK_CHRM 707
+#define MNG_FN_GETCHUNK_SRGB 708
+#define MNG_FN_GETCHUNK_ICCP 709
+#define MNG_FN_GETCHUNK_TEXT 710
+#define MNG_FN_GETCHUNK_ZTXT 711
+#define MNG_FN_GETCHUNK_ITXT 712
+#define MNG_FN_GETCHUNK_BKGD 713
+#define MNG_FN_GETCHUNK_PHYS 714
+#define MNG_FN_GETCHUNK_SBIT 715
+#define MNG_FN_GETCHUNK_SPLT 716
+#define MNG_FN_GETCHUNK_HIST 717
+#define MNG_FN_GETCHUNK_TIME 718
+#define MNG_FN_GETCHUNK_MHDR 719
+#define MNG_FN_GETCHUNK_MEND 720
+#define MNG_FN_GETCHUNK_LOOP 721
+#define MNG_FN_GETCHUNK_ENDL 722
+#define MNG_FN_GETCHUNK_DEFI 723
+#define MNG_FN_GETCHUNK_BASI 724
+#define MNG_FN_GETCHUNK_CLON 725
+#define MNG_FN_GETCHUNK_PAST 726
+#define MNG_FN_GETCHUNK_DISC 727
+#define MNG_FN_GETCHUNK_BACK 728
+#define MNG_FN_GETCHUNK_FRAM 729
+#define MNG_FN_GETCHUNK_MOVE 730
+#define MNG_FN_GETCHUNK_CLIP 731
+#define MNG_FN_GETCHUNK_SHOW 732
+#define MNG_FN_GETCHUNK_TERM 733
+#define MNG_FN_GETCHUNK_SAVE 734
+#define MNG_FN_GETCHUNK_SEEK 735
+#define MNG_FN_GETCHUNK_EXPI 736
+#define MNG_FN_GETCHUNK_FPRI 737
+#define MNG_FN_GETCHUNK_NEED 738
+#define MNG_FN_GETCHUNK_PHYG 739
+#define MNG_FN_GETCHUNK_JHDR 740
+#define MNG_FN_GETCHUNK_JDAT 741
+#define MNG_FN_GETCHUNK_JSEP 742
+#define MNG_FN_GETCHUNK_DHDR 743
+#define MNG_FN_GETCHUNK_PROM 744
+#define MNG_FN_GETCHUNK_IPNG 745
+#define MNG_FN_GETCHUNK_PPLT 746
+#define MNG_FN_GETCHUNK_IJNG 747
+#define MNG_FN_GETCHUNK_DROP 748
+#define MNG_FN_GETCHUNK_DBYK 749
+#define MNG_FN_GETCHUNK_ORDR 750
+#define MNG_FN_GETCHUNK_UNKNOWN 751
+#define MNG_FN_GETCHUNK_MAGN 752
+#define MNG_FN_GETCHUNK_JDAA 753
+
+#define MNG_FN_GETCHUNK_PAST_SRC 781
+#define MNG_FN_GETCHUNK_SAVE_ENTRY 782
+#define MNG_FN_GETCHUNK_PPLT_ENTRY 783
+#define MNG_FN_GETCHUNK_ORDR_ENTRY 784
+
+#define MNG_FN_PUTCHUNK_IHDR 801
+#define MNG_FN_PUTCHUNK_PLTE 802
+#define MNG_FN_PUTCHUNK_IDAT 803
+#define MNG_FN_PUTCHUNK_IEND 804
+#define MNG_FN_PUTCHUNK_TRNS 805
+#define MNG_FN_PUTCHUNK_GAMA 806
+#define MNG_FN_PUTCHUNK_CHRM 807
+#define MNG_FN_PUTCHUNK_SRGB 808
+#define MNG_FN_PUTCHUNK_ICCP 809
+#define MNG_FN_PUTCHUNK_TEXT 810
+#define MNG_FN_PUTCHUNK_ZTXT 811
+#define MNG_FN_PUTCHUNK_ITXT 812
+#define MNG_FN_PUTCHUNK_BKGD 813
+#define MNG_FN_PUTCHUNK_PHYS 814
+#define MNG_FN_PUTCHUNK_SBIT 815
+#define MNG_FN_PUTCHUNK_SPLT 816
+#define MNG_FN_PUTCHUNK_HIST 817
+#define MNG_FN_PUTCHUNK_TIME 818
+#define MNG_FN_PUTCHUNK_MHDR 819
+#define MNG_FN_PUTCHUNK_MEND 820
+#define MNG_FN_PUTCHUNK_LOOP 821
+#define MNG_FN_PUTCHUNK_ENDL 822
+#define MNG_FN_PUTCHUNK_DEFI 823
+#define MNG_FN_PUTCHUNK_BASI 824
+#define MNG_FN_PUTCHUNK_CLON 825
+#define MNG_FN_PUTCHUNK_PAST 826
+#define MNG_FN_PUTCHUNK_DISC 827
+#define MNG_FN_PUTCHUNK_BACK 828
+#define MNG_FN_PUTCHUNK_FRAM 829
+#define MNG_FN_PUTCHUNK_MOVE 830
+#define MNG_FN_PUTCHUNK_CLIP 831
+#define MNG_FN_PUTCHUNK_SHOW 832
+#define MNG_FN_PUTCHUNK_TERM 833
+#define MNG_FN_PUTCHUNK_SAVE 834
+#define MNG_FN_PUTCHUNK_SEEK 835
+#define MNG_FN_PUTCHUNK_EXPI 836
+#define MNG_FN_PUTCHUNK_FPRI 837
+#define MNG_FN_PUTCHUNK_NEED 838
+#define MNG_FN_PUTCHUNK_PHYG 839
+#define MNG_FN_PUTCHUNK_JHDR 840
+#define MNG_FN_PUTCHUNK_JDAT 841
+#define MNG_FN_PUTCHUNK_JSEP 842
+#define MNG_FN_PUTCHUNK_DHDR 843
+#define MNG_FN_PUTCHUNK_PROM 844
+#define MNG_FN_PUTCHUNK_IPNG 845
+#define MNG_FN_PUTCHUNK_PPLT 846
+#define MNG_FN_PUTCHUNK_IJNG 847
+#define MNG_FN_PUTCHUNK_DROP 848
+#define MNG_FN_PUTCHUNK_DBYK 849
+#define MNG_FN_PUTCHUNK_ORDR 850
+#define MNG_FN_PUTCHUNK_UNKNOWN 851
+#define MNG_FN_PUTCHUNK_MAGN 852
+#define MNG_FN_PUTCHUNK_JDAA 853
+
+#define MNG_FN_PUTCHUNK_PAST_SRC 881
+#define MNG_FN_PUTCHUNK_SAVE_ENTRY 882
+#define MNG_FN_PUTCHUNK_PPLT_ENTRY 883
+#define MNG_FN_PUTCHUNK_ORDR_ENTRY 884
+
+/* ************************************************************************** */
+
+#define MNG_FN_GETIMGDATA_SEQ 901
+#define MNG_FN_GETIMGDATA_CHUNKSEQ 902
+#define MNG_FN_GETIMGDATA_CHUNK 903
+
+#define MNG_FN_PUTIMGDATA_IHDR 951
+#define MNG_FN_PUTIMGDATA_JHDR 952
+#define MNG_FN_PUTIMGDATA_BASI 953
+#define MNG_FN_PUTIMGDATA_DHDR 954
+
+#define MNG_FN_UPDATEMNGHEADER 981
+#define MNG_FN_UPDATEMNGSIMPLICITY 982
+
+/* ************************************************************************** */
+
+#define MNG_FN_PROCESS_RAW_CHUNK 1001
+#define MNG_FN_READ_GRAPHIC 1002
+#define MNG_FN_DROP_CHUNKS 1003
+#define MNG_FN_PROCESS_ERROR 1004
+#define MNG_FN_CLEAR_CMS 1005
+#define MNG_FN_DROP_OBJECTS 1006
+#define MNG_FN_READ_CHUNK 1007
+#define MNG_FN_LOAD_BKGDLAYER 1008
+#define MNG_FN_NEXT_FRAME 1009
+#define MNG_FN_NEXT_LAYER 1010
+#define MNG_FN_INTERFRAME_DELAY 1011
+#define MNG_FN_DISPLAY_IMAGE 1012
+#define MNG_FN_DROP_IMGOBJECTS 1013
+#define MNG_FN_DROP_ANIOBJECTS 1014
+#define MNG_FN_INFLATE_BUFFER 1015
+#define MNG_FN_DEFLATE_BUFFER 1016
+#define MNG_FN_WRITE_RAW_CHUNK 1017
+#define MNG_FN_WRITE_GRAPHIC 1018
+#define MNG_FN_SAVE_STATE 1019
+#define MNG_FN_RESTORE_STATE 1020
+#define MNG_FN_DROP_SAVEDATA 1021
+#define MNG_FN_EXECUTE_DELTA_IMAGE 1022
+#define MNG_FN_PROCESS_DISPLAY 1023
+#define MNG_FN_CLEAR_CANVAS 1024
+#define MNG_FN_READ_DATABUFFER 1025
+#define MNG_FN_STORE_ERROR 1026
+#define MNG_FN_DROP_INVALID_OBJECTS 1027
+
+/* ************************************************************************** */
+
+#define MNG_FN_DISPLAY_RGB8 1101
+#define MNG_FN_DISPLAY_RGBA8 1102
+#define MNG_FN_DISPLAY_ARGB8 1103
+#define MNG_FN_DISPLAY_BGR8 1104
+#define MNG_FN_DISPLAY_BGRA8 1105
+#define MNG_FN_DISPLAY_ABGR8 1106
+#define MNG_FN_DISPLAY_RGB16 1107
+#define MNG_FN_DISPLAY_RGBA16 1108
+#define MNG_FN_DISPLAY_ARGB16 1109
+#define MNG_FN_DISPLAY_BGR16 1110
+#define MNG_FN_DISPLAY_BGRA16 1111
+#define MNG_FN_DISPLAY_ABGR16 1112
+#define MNG_FN_DISPLAY_INDEX8 1113
+#define MNG_FN_DISPLAY_INDEXA8 1114
+#define MNG_FN_DISPLAY_AINDEX8 1115
+#define MNG_FN_DISPLAY_GRAY8 1116
+#define MNG_FN_DISPLAY_GRAY16 1117
+#define MNG_FN_DISPLAY_GRAYA8 1118
+#define MNG_FN_DISPLAY_GRAYA16 1119
+#define MNG_FN_DISPLAY_AGRAY8 1120
+#define MNG_FN_DISPLAY_AGRAY16 1121
+#define MNG_FN_DISPLAY_DX15 1122
+#define MNG_FN_DISPLAY_DX16 1123
+#define MNG_FN_DISPLAY_RGB8_A8 1124
+#define MNG_FN_DISPLAY_BGRA8PM 1125
+
+/* ************************************************************************** */
+
+#define MNG_FN_INIT_FULL_CMS 1201
+#define MNG_FN_CORRECT_FULL_CMS 1202
+#define MNG_FN_INIT_GAMMA_ONLY 1204
+#define MNG_FN_CORRECT_GAMMA_ONLY 1205
+#define MNG_FN_CORRECT_APP_CMS 1206
+#define MNG_FN_INIT_FULL_CMS_OBJ 1207
+#define MNG_FN_INIT_GAMMA_ONLY_OBJ 1208
+#define MNG_FN_INIT_APP_CMS 1209
+#define MNG_FN_INIT_APP_CMS_OBJ 1210
+
+/* ************************************************************************** */
+
+#define MNG_FN_PROCESS_G1 1301
+#define MNG_FN_PROCESS_G2 1302
+#define MNG_FN_PROCESS_G4 1303
+#define MNG_FN_PROCESS_G8 1304
+#define MNG_FN_PROCESS_G16 1305
+#define MNG_FN_PROCESS_RGB8 1306
+#define MNG_FN_PROCESS_RGB16 1307
+#define MNG_FN_PROCESS_IDX1 1308
+#define MNG_FN_PROCESS_IDX2 1309
+#define MNG_FN_PROCESS_IDX4 1310
+#define MNG_FN_PROCESS_IDX8 1311
+#define MNG_FN_PROCESS_GA8 1312
+#define MNG_FN_PROCESS_GA16 1313
+#define MNG_FN_PROCESS_RGBA8 1314
+#define MNG_FN_PROCESS_RGBA16 1315
+
+/* ************************************************************************** */
+
+#define MNG_FN_INIT_G1_NI 1401
+#define MNG_FN_INIT_G1_I 1402
+#define MNG_FN_INIT_G2_NI 1403
+#define MNG_FN_INIT_G2_I 1404
+#define MNG_FN_INIT_G4_NI 1405
+#define MNG_FN_INIT_G4_I 1406
+#define MNG_FN_INIT_G8_NI 1407
+#define MNG_FN_INIT_G8_I 1408
+#define MNG_FN_INIT_G16_NI 1409
+#define MNG_FN_INIT_G16_I 1410
+#define MNG_FN_INIT_RGB8_NI 1411
+#define MNG_FN_INIT_RGB8_I 1412
+#define MNG_FN_INIT_RGB16_NI 1413
+#define MNG_FN_INIT_RGB16_I 1414
+#define MNG_FN_INIT_IDX1_NI 1415
+#define MNG_FN_INIT_IDX1_I 1416
+#define MNG_FN_INIT_IDX2_NI 1417
+#define MNG_FN_INIT_IDX2_I 1418
+#define MNG_FN_INIT_IDX4_NI 1419
+#define MNG_FN_INIT_IDX4_I 1420
+#define MNG_FN_INIT_IDX8_NI 1421
+#define MNG_FN_INIT_IDX8_I 1422
+#define MNG_FN_INIT_GA8_NI 1423
+#define MNG_FN_INIT_GA8_I 1424
+#define MNG_FN_INIT_GA16_NI 1425
+#define MNG_FN_INIT_GA16_I 1426
+#define MNG_FN_INIT_RGBA8_NI 1427
+#define MNG_FN_INIT_RGBA8_I 1428
+#define MNG_FN_INIT_RGBA16_NI 1429
+#define MNG_FN_INIT_RGBA16_I 1430
+
+#define MNG_FN_INIT_ROWPROC 1497
+#define MNG_FN_NEXT_ROW 1498
+#define MNG_FN_CLEANUP_ROWPROC 1499
+
+/* ************************************************************************** */
+
+#define MNG_FN_FILTER_A_ROW 1501
+#define MNG_FN_FILTER_SUB 1502
+#define MNG_FN_FILTER_UP 1503
+#define MNG_FN_FILTER_AVERAGE 1504
+#define MNG_FN_FILTER_PAETH 1505
+
+#define MNG_FN_INIT_ROWDIFFERING 1551
+#define MNG_FN_DIFFER_G1 1552
+#define MNG_FN_DIFFER_G2 1553
+#define MNG_FN_DIFFER_G4 1554
+#define MNG_FN_DIFFER_G8 1555
+#define MNG_FN_DIFFER_G16 1556
+#define MNG_FN_DIFFER_RGB8 1557
+#define MNG_FN_DIFFER_RGB16 1558
+#define MNG_FN_DIFFER_IDX1 1559
+#define MNG_FN_DIFFER_IDX2 1560
+#define MNG_FN_DIFFER_IDX4 1561
+#define MNG_FN_DIFFER_IDX8 1562
+#define MNG_FN_DIFFER_GA8 1563
+#define MNG_FN_DIFFER_GA16 1564
+#define MNG_FN_DIFFER_RGBA8 1565
+#define MNG_FN_DIFFER_RGBA16 1566
+
+/* ************************************************************************** */
+
+#define MNG_FN_CREATE_IMGDATAOBJECT 1601
+#define MNG_FN_FREE_IMGDATAOBJECT 1602
+#define MNG_FN_CLONE_IMGDATAOBJECT 1603
+#define MNG_FN_CREATE_IMGOBJECT 1604
+#define MNG_FN_FREE_IMGOBJECT 1605
+#define MNG_FN_FIND_IMGOBJECT 1606
+#define MNG_FN_CLONE_IMGOBJECT 1607
+#define MNG_FN_RESET_OBJECTDETAILS 1608
+#define MNG_FN_RENUM_IMGOBJECT 1609
+#define MNG_FN_PROMOTE_IMGOBJECT 1610
+#define MNG_FN_MAGNIFY_IMGOBJECT 1611
+
+/* ************************************************************************** */
+
+#define MNG_FN_STORE_G1 1701
+#define MNG_FN_STORE_G2 1702
+#define MNG_FN_STORE_G4 1703
+#define MNG_FN_STORE_G8 1704
+#define MNG_FN_STORE_G16 1705
+#define MNG_FN_STORE_RGB8 1706
+#define MNG_FN_STORE_RGB16 1707
+#define MNG_FN_STORE_IDX1 1708
+#define MNG_FN_STORE_IDX2 1709
+#define MNG_FN_STORE_IDX4 1710
+#define MNG_FN_STORE_IDX8 1711
+#define MNG_FN_STORE_GA8 1712
+#define MNG_FN_STORE_GA16 1713
+#define MNG_FN_STORE_RGBA8 1714
+#define MNG_FN_STORE_RGBA16 1715
+
+#define MNG_FN_RETRIEVE_G8 1751
+#define MNG_FN_RETRIEVE_G16 1752
+#define MNG_FN_RETRIEVE_RGB8 1753
+#define MNG_FN_RETRIEVE_RGB16 1754
+#define MNG_FN_RETRIEVE_IDX8 1755
+#define MNG_FN_RETRIEVE_GA8 1756
+#define MNG_FN_RETRIEVE_GA16 1757
+#define MNG_FN_RETRIEVE_RGBA8 1758
+#define MNG_FN_RETRIEVE_RGBA16 1759
+
+#define MNG_FN_DELTA_G1 1771
+#define MNG_FN_DELTA_G2 1772
+#define MNG_FN_DELTA_G4 1773
+#define MNG_FN_DELTA_G8 1774
+#define MNG_FN_DELTA_G16 1775
+#define MNG_FN_DELTA_RGB8 1776
+#define MNG_FN_DELTA_RGB16 1777
+#define MNG_FN_DELTA_IDX1 1778
+#define MNG_FN_DELTA_IDX2 1779
+#define MNG_FN_DELTA_IDX4 1780
+#define MNG_FN_DELTA_IDX8 1781
+#define MNG_FN_DELTA_GA8 1782
+#define MNG_FN_DELTA_GA16 1783
+#define MNG_FN_DELTA_RGBA8 1784
+#define MNG_FN_DELTA_RGBA16 1785
+
+/* ************************************************************************** */
+
+#define MNG_FN_CREATE_ANI_LOOP 1801
+#define MNG_FN_CREATE_ANI_ENDL 1802
+#define MNG_FN_CREATE_ANI_DEFI 1803
+#define MNG_FN_CREATE_ANI_BASI 1804
+#define MNG_FN_CREATE_ANI_CLON 1805
+#define MNG_FN_CREATE_ANI_PAST 1806
+#define MNG_FN_CREATE_ANI_DISC 1807
+#define MNG_FN_CREATE_ANI_BACK 1808
+#define MNG_FN_CREATE_ANI_FRAM 1809
+#define MNG_FN_CREATE_ANI_MOVE 1810
+#define MNG_FN_CREATE_ANI_CLIP 1811
+#define MNG_FN_CREATE_ANI_SHOW 1812
+#define MNG_FN_CREATE_ANI_TERM 1813
+#define MNG_FN_CREATE_ANI_SAVE 1814
+#define MNG_FN_CREATE_ANI_SEEK 1815
+#define MNG_FN_CREATE_ANI_GAMA 1816
+#define MNG_FN_CREATE_ANI_CHRM 1817
+#define MNG_FN_CREATE_ANI_SRGB 1818
+#define MNG_FN_CREATE_ANI_ICCP 1819
+#define MNG_FN_CREATE_ANI_PLTE 1820
+#define MNG_FN_CREATE_ANI_TRNS 1821
+#define MNG_FN_CREATE_ANI_BKGD 1822
+#define MNG_FN_CREATE_ANI_DHDR 1823
+#define MNG_FN_CREATE_ANI_PROM 1824
+#define MNG_FN_CREATE_ANI_IPNG 1825
+#define MNG_FN_CREATE_ANI_IJNG 1826
+#define MNG_FN_CREATE_ANI_PPLT 1827
+#define MNG_FN_CREATE_ANI_MAGN 1828
+
+#define MNG_FN_CREATE_ANI_IMAGE 1891
+
+/* ************************************************************************** */
+
+#define MNG_FN_FREE_ANI_LOOP 1901
+#define MNG_FN_FREE_ANI_ENDL 1902
+#define MNG_FN_FREE_ANI_DEFI 1903
+#define MNG_FN_FREE_ANI_BASI 1904
+#define MNG_FN_FREE_ANI_CLON 1905
+#define MNG_FN_FREE_ANI_PAST 1906
+#define MNG_FN_FREE_ANI_DISC 1907
+#define MNG_FN_FREE_ANI_BACK 1908
+#define MNG_FN_FREE_ANI_FRAM 1909
+#define MNG_FN_FREE_ANI_MOVE 1910
+#define MNG_FN_FREE_ANI_CLIP 1911
+#define MNG_FN_FREE_ANI_SHOW 1912
+#define MNG_FN_FREE_ANI_TERM 1913
+#define MNG_FN_FREE_ANI_SAVE 1914
+#define MNG_FN_FREE_ANI_SEEK 1915
+#define MNG_FN_FREE_ANI_GAMA 1916
+#define MNG_FN_FREE_ANI_CHRM 1917
+#define MNG_FN_FREE_ANI_SRGB 1918
+#define MNG_FN_FREE_ANI_ICCP 1919
+#define MNG_FN_FREE_ANI_PLTE 1920
+#define MNG_FN_FREE_ANI_TRNS 1921
+#define MNG_FN_FREE_ANI_BKGD 1922
+#define MNG_FN_FREE_ANI_DHDR 1923
+#define MNG_FN_FREE_ANI_PROM 1924
+#define MNG_FN_FREE_ANI_IPNG 1925
+#define MNG_FN_FREE_ANI_IJNG 1926
+#define MNG_FN_FREE_ANI_PPLT 1927
+#define MNG_FN_FREE_ANI_MAGN 1928
+
+#define MNG_FN_FREE_ANI_IMAGE 1991
+
+/* ************************************************************************** */
+
+#define MNG_FN_PROCESS_ANI_LOOP 2001
+#define MNG_FN_PROCESS_ANI_ENDL 2002
+#define MNG_FN_PROCESS_ANI_DEFI 2003
+#define MNG_FN_PROCESS_ANI_BASI 2004
+#define MNG_FN_PROCESS_ANI_CLON 2005
+#define MNG_FN_PROCESS_ANI_PAST 2006
+#define MNG_FN_PROCESS_ANI_DISC 2007
+#define MNG_FN_PROCESS_ANI_BACK 2008
+#define MNG_FN_PROCESS_ANI_FRAM 2009
+#define MNG_FN_PROCESS_ANI_MOVE 2010
+#define MNG_FN_PROCESS_ANI_CLIP 2011
+#define MNG_FN_PROCESS_ANI_SHOW 2012
+#define MNG_FN_PROCESS_ANI_TERM 2013
+#define MNG_FN_PROCESS_ANI_SAVE 2014
+#define MNG_FN_PROCESS_ANI_SEEK 2015
+#define MNG_FN_PROCESS_ANI_GAMA 2016
+#define MNG_FN_PROCESS_ANI_CHRM 2017
+#define MNG_FN_PROCESS_ANI_SRGB 2018
+#define MNG_FN_PROCESS_ANI_ICCP 2019
+#define MNG_FN_PROCESS_ANI_PLTE 2020
+#define MNG_FN_PROCESS_ANI_TRNS 2021
+#define MNG_FN_PROCESS_ANI_BKGD 2022
+#define MNG_FN_PROCESS_ANI_DHDR 2023
+#define MNG_FN_PROCESS_ANI_PROM 2024
+#define MNG_FN_PROCESS_ANI_IPNG 2025
+#define MNG_FN_PROCESS_ANI_IJNG 2026
+#define MNG_FN_PROCESS_ANI_PPLT 2027
+#define MNG_FN_PROCESS_ANI_MAGN 2028
+
+#define MNG_FN_PROCESS_ANI_IMAGE 2091
+
+/* ************************************************************************** */
+
+#define MNG_FN_RESTORE_BACKIMAGE 2101
+#define MNG_FN_RESTORE_BACKCOLOR 2102
+#define MNG_FN_RESTORE_BGCOLOR 2103
+#define MNG_FN_RESTORE_RGB8 2104
+#define MNG_FN_RESTORE_BGR8 2105
+#define MNG_FN_RESTORE_BKGD 2106
+
+/* ************************************************************************** */
+
+#define MNG_FN_INIT_IHDR 2201
+#define MNG_FN_INIT_PLTE 2202
+#define MNG_FN_INIT_IDAT 2203
+#define MNG_FN_INIT_IEND 2204
+#define MNG_FN_INIT_TRNS 2205
+#define MNG_FN_INIT_GAMA 2206
+#define MNG_FN_INIT_CHRM 2207
+#define MNG_FN_INIT_SRGB 2208
+#define MNG_FN_INIT_ICCP 2209
+#define MNG_FN_INIT_TEXT 2210
+#define MNG_FN_INIT_ZTXT 2211
+#define MNG_FN_INIT_ITXT 2212
+#define MNG_FN_INIT_BKGD 2213
+#define MNG_FN_INIT_PHYS 2214
+#define MNG_FN_INIT_SBIT 2215
+#define MNG_FN_INIT_SPLT 2216
+#define MNG_FN_INIT_HIST 2217
+#define MNG_FN_INIT_TIME 2218
+#define MNG_FN_INIT_MHDR 2219
+#define MNG_FN_INIT_MEND 2220
+#define MNG_FN_INIT_LOOP 2221
+#define MNG_FN_INIT_ENDL 2222
+#define MNG_FN_INIT_DEFI 2223
+#define MNG_FN_INIT_BASI 2224
+#define MNG_FN_INIT_CLON 2225
+#define MNG_FN_INIT_PAST 2226
+#define MNG_FN_INIT_DISC 2227
+#define MNG_FN_INIT_BACK 2228
+#define MNG_FN_INIT_FRAM 2229
+#define MNG_FN_INIT_MOVE 2230
+#define MNG_FN_INIT_CLIP 2231
+#define MNG_FN_INIT_SHOW 2232
+#define MNG_FN_INIT_TERM 2233
+#define MNG_FN_INIT_SAVE 2234
+#define MNG_FN_INIT_SEEK 2235
+#define MNG_FN_INIT_EXPI 2236
+#define MNG_FN_INIT_FPRI 2237
+#define MNG_FN_INIT_NEED 2238
+#define MNG_FN_INIT_PHYG 2239
+#define MNG_FN_INIT_JHDR 2240
+#define MNG_FN_INIT_JDAT 2241
+#define MNG_FN_INIT_JSEP 2242
+#define MNG_FN_INIT_DHDR 2243
+#define MNG_FN_INIT_PROM 2244
+#define MNG_FN_INIT_IPNG 2245
+#define MNG_FN_INIT_PPLT 2246
+#define MNG_FN_INIT_IJNG 2247
+#define MNG_FN_INIT_DROP 2248
+#define MNG_FN_INIT_DBYK 2249
+#define MNG_FN_INIT_ORDR 2250
+#define MNG_FN_INIT_UNKNOWN 2251
+#define MNG_FN_INIT_MAGN 2252
+#define MNG_FN_INIT_JDAA 2253
+
+/* ************************************************************************** */
+
+#define MNG_FN_FREE_IHDR 2401
+#define MNG_FN_FREE_PLTE 2402
+#define MNG_FN_FREE_IDAT 2403
+#define MNG_FN_FREE_IEND 2404
+#define MNG_FN_FREE_TRNS 2405
+#define MNG_FN_FREE_GAMA 2406
+#define MNG_FN_FREE_CHRM 2407
+#define MNG_FN_FREE_SRGB 2408
+#define MNG_FN_FREE_ICCP 2409
+#define MNG_FN_FREE_TEXT 2410
+#define MNG_FN_FREE_ZTXT 2411
+#define MNG_FN_FREE_ITXT 2412
+#define MNG_FN_FREE_BKGD 2413
+#define MNG_FN_FREE_PHYS 2414
+#define MNG_FN_FREE_SBIT 2415
+#define MNG_FN_FREE_SPLT 2416
+#define MNG_FN_FREE_HIST 2417
+#define MNG_FN_FREE_TIME 2418
+#define MNG_FN_FREE_MHDR 2419
+#define MNG_FN_FREE_MEND 2420
+#define MNG_FN_FREE_LOOP 2421
+#define MNG_FN_FREE_ENDL 2422
+#define MNG_FN_FREE_DEFI 2423
+#define MNG_FN_FREE_BASI 2424
+#define MNG_FN_FREE_CLON 2425
+#define MNG_FN_FREE_PAST 2426
+#define MNG_FN_FREE_DISC 2427
+#define MNG_FN_FREE_BACK 2428
+#define MNG_FN_FREE_FRAM 2429
+#define MNG_FN_FREE_MOVE 2430
+#define MNG_FN_FREE_CLIP 2431
+#define MNG_FN_FREE_SHOW 2432
+#define MNG_FN_FREE_TERM 2433
+#define MNG_FN_FREE_SAVE 2434
+#define MNG_FN_FREE_SEEK 2435
+#define MNG_FN_FREE_EXPI 2436
+#define MNG_FN_FREE_FPRI 2437
+#define MNG_FN_FREE_NEED 2438
+#define MNG_FN_FREE_PHYG 2439
+#define MNG_FN_FREE_JHDR 2440
+#define MNG_FN_FREE_JDAT 2441
+#define MNG_FN_FREE_JSEP 2442
+#define MNG_FN_FREE_DHDR 2443
+#define MNG_FN_FREE_PROM 2444
+#define MNG_FN_FREE_IPNG 2445
+#define MNG_FN_FREE_PPLT 2446
+#define MNG_FN_FREE_IJNG 2447
+#define MNG_FN_FREE_DROP 2448
+#define MNG_FN_FREE_DBYK 2449
+#define MNG_FN_FREE_ORDR 2450
+#define MNG_FN_FREE_UNKNOWN 2451
+#define MNG_FN_FREE_MAGN 2452
+#define MNG_FN_FREE_JDAA 2453
+
+/* ************************************************************************** */
+
+#define MNG_FN_READ_IHDR 2601
+#define MNG_FN_READ_PLTE 2602
+#define MNG_FN_READ_IDAT 2603
+#define MNG_FN_READ_IEND 2604
+#define MNG_FN_READ_TRNS 2605
+#define MNG_FN_READ_GAMA 2606
+#define MNG_FN_READ_CHRM 2607
+#define MNG_FN_READ_SRGB 2608
+#define MNG_FN_READ_ICCP 2609
+#define MNG_FN_READ_TEXT 2610
+#define MNG_FN_READ_ZTXT 2611
+#define MNG_FN_READ_ITXT 2612
+#define MNG_FN_READ_BKGD 2613
+#define MNG_FN_READ_PHYS 2614
+#define MNG_FN_READ_SBIT 2615
+#define MNG_FN_READ_SPLT 2616
+#define MNG_FN_READ_HIST 2617
+#define MNG_FN_READ_TIME 2618
+#define MNG_FN_READ_MHDR 2619
+#define MNG_FN_READ_MEND 2620
+#define MNG_FN_READ_LOOP 2621
+#define MNG_FN_READ_ENDL 2622
+#define MNG_FN_READ_DEFI 2623
+#define MNG_FN_READ_BASI 2624
+#define MNG_FN_READ_CLON 2625
+#define MNG_FN_READ_PAST 2626
+#define MNG_FN_READ_DISC 2627
+#define MNG_FN_READ_BACK 2628
+#define MNG_FN_READ_FRAM 2629
+#define MNG_FN_READ_MOVE 2630
+#define MNG_FN_READ_CLIP 2631
+#define MNG_FN_READ_SHOW 2632
+#define MNG_FN_READ_TERM 2633
+#define MNG_FN_READ_SAVE 2634
+#define MNG_FN_READ_SEEK 2635
+#define MNG_FN_READ_EXPI 2636
+#define MNG_FN_READ_FPRI 2637
+#define MNG_FN_READ_NEED 2638
+#define MNG_FN_READ_PHYG 2639
+#define MNG_FN_READ_JHDR 2640
+#define MNG_FN_READ_JDAT 2641
+#define MNG_FN_READ_JSEP 2642
+#define MNG_FN_READ_DHDR 2643
+#define MNG_FN_READ_PROM 2644
+#define MNG_FN_READ_IPNG 2645
+#define MNG_FN_READ_PPLT 2646
+#define MNG_FN_READ_IJNG 2647
+#define MNG_FN_READ_DROP 2648
+#define MNG_FN_READ_DBYK 2649
+#define MNG_FN_READ_ORDR 2650
+#define MNG_FN_READ_UNKNOWN 2651
+#define MNG_FN_READ_MAGN 2652
+#define MNG_FN_READ_JDAA 2653
+
+/* ************************************************************************** */
+
+#define MNG_FN_WRITE_IHDR 2801
+#define MNG_FN_WRITE_PLTE 2802
+#define MNG_FN_WRITE_IDAT 2803
+#define MNG_FN_WRITE_IEND 2804
+#define MNG_FN_WRITE_TRNS 2805
+#define MNG_FN_WRITE_GAMA 2806
+#define MNG_FN_WRITE_CHRM 2807
+#define MNG_FN_WRITE_SRGB 2808
+#define MNG_FN_WRITE_ICCP 2809
+#define MNG_FN_WRITE_TEXT 2810
+#define MNG_FN_WRITE_ZTXT 2811
+#define MNG_FN_WRITE_ITXT 2812
+#define MNG_FN_WRITE_BKGD 2813
+#define MNG_FN_WRITE_PHYS 2814
+#define MNG_FN_WRITE_SBIT 2815
+#define MNG_FN_WRITE_SPLT 2816
+#define MNG_FN_WRITE_HIST 2817
+#define MNG_FN_WRITE_TIME 2818
+#define MNG_FN_WRITE_MHDR 2819
+#define MNG_FN_WRITE_MEND 2820
+#define MNG_FN_WRITE_LOOP 2821
+#define MNG_FN_WRITE_ENDL 2822
+#define MNG_FN_WRITE_DEFI 2823
+#define MNG_FN_WRITE_BASI 2824
+#define MNG_FN_WRITE_CLON 2825
+#define MNG_FN_WRITE_PAST 2826
+#define MNG_FN_WRITE_DISC 2827
+#define MNG_FN_WRITE_BACK 2828
+#define MNG_FN_WRITE_FRAM 2829
+#define MNG_FN_WRITE_MOVE 2830
+#define MNG_FN_WRITE_CLIP 2831
+#define MNG_FN_WRITE_SHOW 2832
+#define MNG_FN_WRITE_TERM 2833
+#define MNG_FN_WRITE_SAVE 2834
+#define MNG_FN_WRITE_SEEK 2835
+#define MNG_FN_WRITE_EXPI 2836
+#define MNG_FN_WRITE_FPRI 2837
+#define MNG_FN_WRITE_NEED 2838
+#define MNG_FN_WRITE_PHYG 2839
+#define MNG_FN_WRITE_JHDR 2840
+#define MNG_FN_WRITE_JDAT 2841
+#define MNG_FN_WRITE_JSEP 2842
+#define MNG_FN_WRITE_DHDR 2843
+#define MNG_FN_WRITE_PROM 2844
+#define MNG_FN_WRITE_IPNG 2845
+#define MNG_FN_WRITE_PPLT 2846
+#define MNG_FN_WRITE_IJNG 2847
+#define MNG_FN_WRITE_DROP 2848
+#define MNG_FN_WRITE_DBYK 2849
+#define MNG_FN_WRITE_ORDR 2850
+#define MNG_FN_WRITE_UNKNOWN 2851
+#define MNG_FN_WRITE_MAGN 2852
+#define MNG_FN_WRITE_JDAA 2853
+
+/* ************************************************************************** */
+
+#define MNG_FN_ZLIB_INITIALIZE 3001
+#define MNG_FN_ZLIB_CLEANUP 3002
+#define MNG_FN_ZLIB_INFLATEINIT 3003
+#define MNG_FN_ZLIB_INFLATEROWS 3004
+#define MNG_FN_ZLIB_INFLATEDATA 3005
+#define MNG_FN_ZLIB_INFLATEFREE 3006
+#define MNG_FN_ZLIB_DEFLATEINIT 3007
+#define MNG_FN_ZLIB_DEFLATEROWS 3008
+#define MNG_FN_ZLIB_DEFLATEDATA 3009
+#define MNG_FN_ZLIB_DEFLATEFREE 3010
+
+/* ************************************************************************** */
+
+#define MNG_FN_PROCESS_DISPLAY_IHDR 3201
+#define MNG_FN_PROCESS_DISPLAY_PLTE 3202
+#define MNG_FN_PROCESS_DISPLAY_IDAT 3203
+#define MNG_FN_PROCESS_DISPLAY_IEND 3204
+#define MNG_FN_PROCESS_DISPLAY_TRNS 3205
+#define MNG_FN_PROCESS_DISPLAY_GAMA 3206
+#define MNG_FN_PROCESS_DISPLAY_CHRM 3207
+#define MNG_FN_PROCESS_DISPLAY_SRGB 3208
+#define MNG_FN_PROCESS_DISPLAY_ICCP 3209
+#define MNG_FN_PROCESS_DISPLAY_BKGD 3210
+#define MNG_FN_PROCESS_DISPLAY_PHYS 3211
+#define MNG_FN_PROCESS_DISPLAY_SBIT 3212
+#define MNG_FN_PROCESS_DISPLAY_SPLT 3213
+#define MNG_FN_PROCESS_DISPLAY_HIST 3214
+#define MNG_FN_PROCESS_DISPLAY_MHDR 3215
+#define MNG_FN_PROCESS_DISPLAY_MEND 3216
+#define MNG_FN_PROCESS_DISPLAY_LOOP 3217
+#define MNG_FN_PROCESS_DISPLAY_ENDL 3218
+#define MNG_FN_PROCESS_DISPLAY_DEFI 3219
+#define MNG_FN_PROCESS_DISPLAY_BASI 3220
+#define MNG_FN_PROCESS_DISPLAY_CLON 3221
+#define MNG_FN_PROCESS_DISPLAY_PAST 3222
+#define MNG_FN_PROCESS_DISPLAY_DISC 3223
+#define MNG_FN_PROCESS_DISPLAY_BACK 3224
+#define MNG_FN_PROCESS_DISPLAY_FRAM 3225
+#define MNG_FN_PROCESS_DISPLAY_MOVE 3226
+#define MNG_FN_PROCESS_DISPLAY_CLIP 3227
+#define MNG_FN_PROCESS_DISPLAY_SHOW 3228
+#define MNG_FN_PROCESS_DISPLAY_TERM 3229
+#define MNG_FN_PROCESS_DISPLAY_SAVE 3230
+#define MNG_FN_PROCESS_DISPLAY_SEEK 3231
+#define MNG_FN_PROCESS_DISPLAY_EXPI 3232
+#define MNG_FN_PROCESS_DISPLAY_FPRI 3233
+#define MNG_FN_PROCESS_DISPLAY_NEED 3234
+#define MNG_FN_PROCESS_DISPLAY_PHYG 3235
+#define MNG_FN_PROCESS_DISPLAY_JHDR 3236
+#define MNG_FN_PROCESS_DISPLAY_JDAT 3237
+#define MNG_FN_PROCESS_DISPLAY_JSEP 3238
+#define MNG_FN_PROCESS_DISPLAY_DHDR 3239
+#define MNG_FN_PROCESS_DISPLAY_PROM 3240
+#define MNG_FN_PROCESS_DISPLAY_IPNG 3241
+#define MNG_FN_PROCESS_DISPLAY_PPLT 3242
+#define MNG_FN_PROCESS_DISPLAY_IJNG 3243
+#define MNG_FN_PROCESS_DISPLAY_DROP 3244
+#define MNG_FN_PROCESS_DISPLAY_DBYK 3245
+#define MNG_FN_PROCESS_DISPLAY_ORDR 3246
+#define MNG_FN_PROCESS_DISPLAY_MAGN 3247
+#define MNG_FN_PROCESS_DISPLAY_JDAA 3248
+
+/* ************************************************************************** */
+
+#define MNG_FN_JPEG_INITIALIZE 3401
+#define MNG_FN_JPEG_CLEANUP 3402
+#define MNG_FN_JPEG_DECOMPRESSINIT 3403
+#define MNG_FN_JPEG_DECOMPRESSDATA 3404
+#define MNG_FN_JPEG_DECOMPRESSFREE 3405
+
+#define MNG_FN_STORE_JPEG_G8 3501
+#define MNG_FN_STORE_JPEG_RGB8 3502
+#define MNG_FN_STORE_JPEG_G12 3503
+#define MNG_FN_STORE_JPEG_RGB12 3504
+#define MNG_FN_STORE_JPEG_GA8 3505
+#define MNG_FN_STORE_JPEG_RGBA8 3506
+#define MNG_FN_STORE_JPEG_GA12 3507
+#define MNG_FN_STORE_JPEG_RGBA12 3508
+#define MNG_FN_STORE_JPEG_G8_ALPHA 3509
+#define MNG_FN_STORE_JPEG_RGB8_ALPHA 3510
+
+#define MNG_FN_INIT_JPEG_A1_NI 3511
+#define MNG_FN_INIT_JPEG_A2_NI 3512
+#define MNG_FN_INIT_JPEG_A4_NI 3513
+#define MNG_FN_INIT_JPEG_A8_NI 3514
+#define MNG_FN_INIT_JPEG_A16_NI 3515
+
+#define MNG_FN_STORE_JPEG_G8_A1 3521
+#define MNG_FN_STORE_JPEG_G8_A2 3522
+#define MNG_FN_STORE_JPEG_G8_A4 3523
+#define MNG_FN_STORE_JPEG_G8_A8 3524
+#define MNG_FN_STORE_JPEG_G8_A16 3525
+
+#define MNG_FN_STORE_JPEG_RGB8_A1 3531
+#define MNG_FN_STORE_JPEG_RGB8_A2 3532
+#define MNG_FN_STORE_JPEG_RGB8_A4 3533
+#define MNG_FN_STORE_JPEG_RGB8_A8 3534
+#define MNG_FN_STORE_JPEG_RGB8_A16 3535
+
+#define MNG_FN_STORE_JPEG_G12_A1 3541
+#define MNG_FN_STORE_JPEG_G12_A2 3542
+#define MNG_FN_STORE_JPEG_G12_A4 3543
+#define MNG_FN_STORE_JPEG_G12_A8 3544
+#define MNG_FN_STORE_JPEG_G12_A16 3545
+
+#define MNG_FN_STORE_JPEG_RGB12_A1 3551
+#define MNG_FN_STORE_JPEG_RGB12_A2 3552
+#define MNG_FN_STORE_JPEG_RGB12_A4 3553
+#define MNG_FN_STORE_JPEG_RGB12_A8 3554
+#define MNG_FN_STORE_JPEG_RGB12_A16 3555
+
+#define MNG_FN_NEXT_JPEG_ALPHAROW 3591
+#define MNG_FN_NEXT_JPEG_ROW 3592
+#define MNG_FN_DISPLAY_JPEG_ROWS 3593
+
+/* ************************************************************************** */
+
+#define MNG_FN_MAGNIFY_G8_X1 3701
+#define MNG_FN_MAGNIFY_G8_X2 3702
+#define MNG_FN_MAGNIFY_RGB8_X1 3703
+#define MNG_FN_MAGNIFY_RGB8_X2 3704
+#define MNG_FN_MAGNIFY_GA8_X1 3705
+#define MNG_FN_MAGNIFY_GA8_X2 3706
+#define MNG_FN_MAGNIFY_GA8_X3 3707
+#define MNG_FN_MAGNIFY_GA8_X4 3708
+#define MNG_FN_MAGNIFY_RGBA8_X1 3709
+#define MNG_FN_MAGNIFY_RGBA8_X2 3710
+#define MNG_FN_MAGNIFY_RGBA8_X3 3711
+#define MNG_FN_MAGNIFY_RGBA8_X4 3712
+#define MNG_FN_MAGNIFY_G8_X3 3713
+#define MNG_FN_MAGNIFY_RGB8_X3 3714
+#define MNG_FN_MAGNIFY_GA8_X5 3715
+#define MNG_FN_MAGNIFY_RGBA8_X5 3716
+
+#define MNG_FN_MAGNIFY_G8_Y1 3751
+#define MNG_FN_MAGNIFY_G8_Y2 3752
+#define MNG_FN_MAGNIFY_RGB8_Y1 3753
+#define MNG_FN_MAGNIFY_RGB8_Y2 3754
+#define MNG_FN_MAGNIFY_GA8_Y1 3755
+#define MNG_FN_MAGNIFY_GA8_Y2 3756
+#define MNG_FN_MAGNIFY_GA8_Y3 3757
+#define MNG_FN_MAGNIFY_GA8_Y4 3758
+#define MNG_FN_MAGNIFY_RGBA8_Y1 3759
+#define MNG_FN_MAGNIFY_RGBA8_Y2 3760
+#define MNG_FN_MAGNIFY_RGBA8_Y3 3761
+#define MNG_FN_MAGNIFY_RGBA8_Y4 3762
+#define MNG_FN_MAGNIFY_G8_Y3 3763
+#define MNG_FN_MAGNIFY_RGB8_Y3 3764
+#define MNG_FN_MAGNIFY_GA8_Y5 3765
+#define MNG_FN_MAGNIFY_RGBA8_Y5 3766
+
+/* ************************************************************************** */
+
+#define MNG_FN_DELTA_G1_G1 3801
+#define MNG_FN_DELTA_G2_G2 3802
+#define MNG_FN_DELTA_G4_G4 3803
+#define MNG_FN_DELTA_G8_G8 3804
+#define MNG_FN_DELTA_G16_G16 3805
+#define MNG_FN_DELTA_RGB8_RGB8 3806
+#define MNG_FN_DELTA_RGB16_RGB16 3807
+#define MNG_FN_DELTA_GA8_GA8 3808
+#define MNG_FN_DELTA_GA8_G8 3809
+#define MNG_FN_DELTA_GA8_A8 3810
+#define MNG_FN_DELTA_GA16_GA16 3811
+#define MNG_FN_DELTA_GA16_G16 3812
+#define MNG_FN_DELTA_GA16_A16 3813
+#define MNG_FN_DELTA_RGBA8_RGBA8 3814
+#define MNG_FN_DELTA_RGBA8_RGB8 3815
+#define MNG_FN_DELTA_RGBA8_A8 3816
+#define MNG_FN_DELTA_RGBA16_RGBA16 3817
+#define MNG_FN_DELTA_RGBA16_RGB16 3818
+#define MNG_FN_DELTA_RGBA16_A16 3819
+
+/* ************************************************************************** */
+/* * * */
+/* * Trace string-table entry * */
+/* * * */
+/* ************************************************************************** */
+
+typedef struct {
+ mng_uint32 iFunction;
+ mng_pchar zTracetext;
+ } mng_trace_entry;
+typedef mng_trace_entry * mng_trace_entryp;
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_TRACE_PROCS */
+
+/* ************************************************************************** */
+
+#endif /* _libmng_trace_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_types.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_types.h
new file mode 100644
index 0000000..c9c3d4a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_types.h
@@ -0,0 +1,497 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_types.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.3 * */
+/* * * */
+/* * purpose : type specifications * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Specification of the types used by the library * */
+/* * Creates platform-independant structure * */
+/* * * */
+/* * changes : 0.5.1 - 05/06/2000 - G.Juyn * */
+/* * - added iteratechunk callback definition * */
+/* * 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - improved definitions for DLL support * */
+/* * - added 8-bit palette definition * */
+/* * - added general array definitions * */
+/* * - added MNG_NULL definition * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - changed most callback prototypes to allow the app * */
+/* * to report errors during callback processing * */
+/* * 0.5.1 - 05/16/2000 - G.Juyn * */
+/* * - moved standard header includes into this file * */
+/* * (stdlib/mem for mem-mngmt & math for fp gamma-calc) * */
+/* * * */
+/* * 0.5.2 - 05/18/2000 - G.Juyn * */
+/* * - B003 - fixed problem with <mem.h> being proprietary * */
+/* * to Borland platform * */
+/* * - added helper definitions for JNG (IJG-based) * */
+/* * - fixed support for IJGSRC6B * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - added default IJG compression parameters and such * */
+/* * 0.5.2 - 05/31/2000 - G.Juyn * */
+/* * - fixed inclusion for memcpy (contributed by Tim Rowley) * */
+/* * - added mng_int32p (contributed by Tim Rowley) * */
+/* * 0.5.2 - 06/02/2000 - G.Juyn * */
+/* * - removed SWAP_ENDIAN reference (contributed by Tim Rowley)* */
+/* * - added getalphaline callback for RGB8_A8 canvasstyle * */
+/* * * */
+/* * 0.5.3 - 06/21/2000 - G.Juyn * */
+/* * - added speedtype to facilitate testing * */
+/* * 0.5.3 - 06/27/2000 - G.Juyn * */
+/* * - added typedef for mng_size_t * */
+/* * - changed size parameter for memory callbacks to * */
+/* * mng_size_t * */
+/* * 0.5.3 - 06/28/2000 - G.Juyn * */
+/* * - changed definition of 32-bit ints (64-bit platforms) * */
+/* * - changed definition of mng_handle (64-bit platforms) * */
+/* * 0.5.3 - 06/29/2000 - G.Juyn * */
+/* * - changed definition of mng_handle (again) * */
+/* * - swapped refresh parameters * */
+/* * - added inclusion of stdlib.h for abs() * */
+/* * * */
+/* * 0.9.0 - 06/30/2000 - G.Juyn * */
+/* * - changed refresh parameters to 'x,y,width,height' * */
+/* * 0.9.1 - 07/10/2000 - G.Juyn * */
+/* * - added suspendbuffer constants * */
+/* * 0.9.1 - 07/15/2000 - G.Juyn * */
+/* * - added callbacks for SAVE/SEEK processing * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/07/2000 - G.Juyn * */
+/* * - B111300 - fixup for improved portability * */
+/* * 0.9.3 - 08/12/2000 - G.Juyn * */
+/* * - added workaround for faulty PhotoShop iCCP chunk * */
+/* * 0.9.3 - 09/11/2000 - G.Juyn * */
+/* * - added export of zlib functions from windows dll * */
+/* * - fixed inclusion parameters once again to make those * */
+/* * external libs work together * */
+/* * - re-fixed fixed inclusion parameters * */
+/* * (these freeking libraries make me mad) * */
+/* * 0.9.3 - 10/11/2000 - G.Juyn * */
+/* * - added support for nEED * */
+/* * 0.9.3 - 10/17/2000 - G.Juyn * */
+/* * - added callback to process non-critical unknown chunks * */
+/* * * */
+/* * 0.9.4 - 11/20/2000 - R.Giles * */
+/* * - fixed inclusion of lcms header for non-windows platforms * */
+/* * 0.9.4 - 12/12/2000 - G.Juyn * */
+/* * - changed callback convention for MSVC (Thanks Chad) * */
+/* * 0.9.4 - 12/16/2000 - G.Juyn * */
+/* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
+/* * * */
+/* * 1.0.1 - 02/08/2001 - G.Juyn * */
+/* * - added MEND processing callback * */
+/* * * */
+/* * 1.0.2 - 06/23/2001 - G.Juyn * */
+/* * - added processterm callback * */
+/* * * */
+/* * 1.0.3 - 08/06/2001 - G.Juyn * */
+/* * - changed inclusion of lcms.h for Linux platforms * */
+/* * * */
+/* ************************************************************************** */
+
+#ifndef _libmng_types_h_
+#define _libmng_types_h_
+
+/* ************************************************************************** */
+
+#ifdef __BORLANDC__
+#pragma option -AT /* turn off strict ANSI-C for the moment */
+#endif
+
+#ifndef WIN32
+#if defined(_WIN32) || defined(__WIN32__) || defined(_Windows) || defined(_WINDOWS)
+#define WIN32 /* gather them into a single define */
+#endif
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Here's where the external & standard libs are embedded * */
+/* * * */
+/* * (it can be a bit of a pain in the lower-back to get them to work * */
+/* * together) * */
+/* * * */
+/* ************************************************************************** */
+
+#ifdef WIN32 /* only include needed stuff */
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#endif
+
+#ifdef MNG_USE_DLL
+#ifdef MNG_SKIP_ZLIB
+#undef MNG_INCLUDE_ZLIB
+#endif
+#ifdef MNG_SKIP_LCMS
+#undef MNG_INCLUDE_LCMS
+#endif
+#ifdef MNG_SKIP_IJG6B
+#undef MNG_INCLUDE_IJG6B
+#endif
+#endif
+
+#ifdef MNG_INCLUDE_ZLIB /* zlib by Mark Adler & Jean-loup Gailly */
+#include "zlib.h"
+#endif
+
+#ifdef MNG_INCLUDE_LCMS /* little cms by Marti Maria Saguer */
+#ifndef ZLIB_DLL
+#undef FAR
+#endif
+#if defined(WIN32) || defined(linux) /* different header locations */
+#include "lcms.h"
+#else
+#include "lcms/lcms.h"
+#endif
+#endif /* MNG_INCLUDE_LCMS */
+
+#ifdef MNG_INCLUDE_IJG6B /* IJG's jpgsrc6b */
+#include <stdio.h>
+#ifdef MNG_USE_SETJMP
+#include <setjmp.h> /* needed for error-recovery (blergh) */
+#else
+#ifdef WIN32
+#define USE_WINDOWS_MESSAGEBOX /* display a messagebox under Windoze */
+#endif
+#endif /* MNG_USE_SETJMP */
+#ifdef FAR
+#undef FAR /* possibly defined by zlib or lcms */
+#endif
+#include "jpeglib.h" /* all that for JPEG support :-) */
+#endif /* MNG_INCLUDE_IJG6B */
+
+#if defined(MNG_INTERNAL_MEMMNGMT) || defined(MNG_INCLUDE_FILTERS)
+#include <stdlib.h> /* "calloc" & "free" & "abs" */
+#endif
+
+#include <limits.h> /* get proper integer widths */
+
+#ifdef WIN32
+/* B003 */
+#if defined __BORLANDC__
+#include <mem.h> /* defines "memcpy" for BCB */
+#else
+#include <memory.h> /* defines "memcpy" for other win32 platforms */
+#endif
+/* B003 */
+#ifdef MNG_CHECK_BAD_ICCP
+#include <string.h> /* strncmp() */
+#endif
+#else
+#ifdef BSD
+#include <strings.h> /* defines "memcpy" for BSD (?) */
+#else
+#include <string.h> /* defines "memcpy" for all others (???) */
+#endif
+#endif
+
+#if defined(MNG_FULL_CMS) || defined(MNG_GAMMA_ONLY)
+#include <math.h> /* fp gamma-calculation */
+#endif
+
+/* ************************************************************************** */
+/* * * */
+/* * Platform-dependant stuff * */
+/* * * */
+/* ************************************************************************** */
+
+/* TODO: this may require some elaboration for other platforms;
+ only works with BCB for now */
+
+#ifndef MNG_DLL
+#if defined(MNG_BUILD_DLL) || defined(MNG_USE_DLL)
+#define MNG_DLL
+#endif
+#endif
+
+#if defined(MNG_DLL) && defined(WIN32) /* setup DLL calling conventions */
+#define MNG_DECL __stdcall
+#if defined(MNG_BUILD_DLL)
+#define MNG_EXT __declspec(dllexport)
+#elif defined(MNG_USE_DLL)
+#define MNG_EXT __declspec(dllimport)
+#else
+#define MNG_EXT
+#endif
+#ifdef MNG_STRICT_ANSI
+#undef MNG_STRICT_ANSI /* can't do strict-ANSI with this DLL-stuff */
+#endif
+#else
+#define MNG_DECL /* dummies for non-DLL */
+#define MNG_EXT
+#endif /* MNG_DLL && WIN32 */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* now force ANSI-C from here on */
+#endif
+
+/* ************************************************************************** */
+
+#if USHRT_MAX == 0xffffffffU /* get the proper 32-bit width !!! */
+typedef unsigned short mng_uint32;
+typedef signed short mng_int32;
+#elif UINT_MAX == 0xffffffffU
+typedef unsigned int mng_uint32;
+typedef signed int mng_int32;
+#elif ULONG_MAX == 0xffffffffU
+typedef unsigned long mng_uint32;
+typedef signed long mng_int32;
+#else
+#error "Sorry, I can't tqfind any 32-bit integers on this platform."
+#endif
+
+typedef signed short mng_int16; /* other basic integers */
+typedef unsigned short mng_uint16;
+typedef signed char mng_int8;
+typedef unsigned char mng_uint8;
+
+typedef double mng_float; /* basic float */
+
+typedef size_t mng_size_t; /* size field for memory allocation */
+
+typedef char * mng_pchar; /* string */
+typedef void * mng_ptr; /* generic pointer */
+typedef void (*mng_fptr) (void); /* generic function pointer */
+
+/* ************************************************************************** */
+/* * * */
+/* * Platform-independant from here * */
+/* * * */
+/* ************************************************************************** */
+
+typedef mng_uint32 * mng_uint32p; /* pointer to unsigned longs */
+typedef mng_int32 * mng_int32p; /* pointer to longs */
+typedef mng_uint16 * mng_uint16p; /* pointer to unsigned words */
+typedef mng_uint8 * mng_uint8p; /* pointer to unsigned bytes */
+
+typedef mng_int8 mng_bool; /* booleans */
+
+struct mng_data_struct;
+typedef struct mng_data_struct * mng_handle; /* generic handle */
+
+typedef mng_int32 mng_retcode; /* generic return code */
+typedef mng_int32 mng_chunkid; /* 4-byte chunkname identifier */
+typedef mng_ptr mng_chunkp; /* pointer to a chunk-structure */
+typedef mng_ptr mng_objectp; /* pointer to an object-structure */
+
+typedef mng_chunkid * mng_chunkidp; /* pointer to chunkid */
+
+typedef struct { /* 8-bit palette element */
+ mng_uint8 iRed;
+ mng_uint8 iGreen;
+ mng_uint8 iBlue;
+ } mng_palette8e;
+typedef mng_palette8e mng_palette8[256]; /* 8-bit palette */
+typedef mng_palette8e * mng_palette8ep;
+
+typedef mng_uint8 mng_uint8arr[256]; /* generic arrays */
+typedef mng_uint8 mng_uint8arr4[4];
+typedef mng_uint16 mng_uint16arr[256];
+typedef mng_uint32 mng_uint32arr2[2];
+
+/* ************************************************************************** */
+
+#define MNG_FALSE 0
+#define MNG_TRUE 1
+#define MNG_NULL 0
+
+#define MNG_SUSPENDBUFFERSIZE 32768
+#define MNG_SUSPENDRETQUESTSIZE 1024
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+
+/* size of temporary zlib buffer for deflate processing */
+#define MNG_ZLIB_MAXBUF 8192
+
+/* default zlib compression parameters for deflateinit2 */
+#define MNG_ZLIB_LEVEL 9 /* level */
+#define MNG_ZLIB_METHOD Z_DEFLATED /* method */
+#define MNG_ZLIB_WINDOWBITS 15 /* window size */
+#define MNG_ZLIB_MEMLEVEL 9 /* memory level */
+#define MNG_ZLIB_STRATEGY Z_DEFAULT_STRATEGY /* strategy */
+
+#define MNG_MAX_IDAT_SIZE 4096 /* maximum size of IDAT data */
+
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_JNG
+
+#ifdef MNG_INCLUDE_IJG6B /* IJG helper defs */
+typedef struct jpeg_compress_struct mngjpeg_comp;
+typedef struct jpeg_decompress_struct mngjpeg_decomp;
+typedef struct jpeg_error_mgr mngjpeg_error;
+typedef struct jpeg_source_mgr mngjpeg_source;
+
+typedef mngjpeg_comp * mngjpeg_compp;
+typedef mngjpeg_decomp * mngjpeg_decompp;
+typedef mngjpeg_error * mngjpeg_errorp;
+typedef mngjpeg_source * mngjpeg_sourcep;
+
+typedef J_DCT_METHOD mngjpeg_dctmethod;
+
+/* default IJG parameters for compression */
+#define MNG_JPEG_DCT JDCT_DEFAULT /* DCT algorithm (JDCT_ISLOW) */
+#define MNG_JPEG_TQUALITY 100 /* quality 0..100; 100=best */
+#define MNG_JPEG_SMOOTHING 0 /* default no smoothing */
+#define MNG_JPEG_PROGRESSIVE MNG_FALSE /* default is just baseline */
+#define MNG_JPEG_OPTIMIZED MNG_FALSE /* default is not optimized */
+#endif /* MNG_INCLUDE_IJG6B */
+
+#define MNG_JPEG_MAXBUF 65500 /* max size of temp JPEG buffer */
+#define MNG_MAX_JDAT_SIZE 4096 /* maximum size of JDAT data */
+
+#endif /* MNG_INCLUDE_JNG */
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_LCMS
+typedef cmsHPROFILE mng_cmsprof; /* little CMS helper defs */
+typedef cmsHTRANSFORM mng_cmstrans;
+typedef cmsCIExyY mng_CIExyY;
+typedef cmsCIExyYTRIPLE mng_CIExyYTRIPLE;
+typedef LPGAMMATABLE mng_gammatabp;
+#endif /* MNG_INCLUDE_LCMS */
+
+/* ************************************************************************** */
+
+ /* enumeration of known graphics types */
+enum mng_imgtypes {mng_it_unknown, mng_it_png, mng_it_mng, mng_it_jng};
+typedef enum mng_imgtypes mng_imgtype;
+
+ /* enumeration of animation speed-types */
+enum mng_speedtypes {mng_st_normal, mng_st_fast, mng_st_slow, mng_st_slowest};
+typedef enum mng_speedtypes mng_speedtype;
+
+/* ************************************************************************** */
+
+ /* memory management callbacks */
+typedef mng_ptr (MNG_DECL *mng_memalloc) (mng_size_t iLen);
+typedef void (MNG_DECL *mng_memfree) (mng_ptr iPtr,
+ mng_size_t iLen);
+
+ /* I/O management callbacks */
+typedef mng_bool (MNG_DECL *mng_openstream) (mng_handle hHandle);
+typedef mng_bool (MNG_DECL *mng_closestream) (mng_handle hHandle);
+typedef mng_bool (MNG_DECL *mng_readdata) (mng_handle hHandle,
+ mng_ptr pBuf,
+ mng_uint32 iBuflen,
+ mng_uint32p pRead);
+typedef mng_bool (MNG_DECL *mng_writedata) (mng_handle hHandle,
+ mng_ptr pBuf,
+ mng_uint32 iBuflen,
+ mng_uint32p pWritten);
+
+ /* error & trace processing callbacks */
+typedef mng_bool (MNG_DECL *mng_errorproc) (mng_handle hHandle,
+ mng_int32 iErrorcode,
+ mng_int8 iSeverity,
+ mng_chunkid iChunkname,
+ mng_uint32 iChunkseq,
+ mng_int32 iExtra1,
+ mng_int32 iExtra2,
+ mng_pchar zErrortext);
+typedef mng_bool (MNG_DECL *mng_traceproc) (mng_handle hHandle,
+ mng_int32 iFuncnr,
+ mng_int32 iFuncseq,
+ mng_pchar zFuncname);
+
+ /* read processing callbacks */
+typedef mng_bool (MNG_DECL *mng_processheader) (mng_handle hHandle,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight);
+typedef mng_bool (MNG_DECL *mng_processtext) (mng_handle hHandle,
+ mng_uint8 iType,
+ mng_pchar zKeyword,
+ mng_pchar zText,
+ mng_pchar zLanguage,
+ mng_pchar zTranslation);
+typedef mng_bool (MNG_DECL *mng_processsave) (mng_handle hHandle);
+typedef mng_bool (MNG_DECL *mng_processseek) (mng_handle hHandle,
+ mng_pchar zName);
+typedef mng_bool (MNG_DECL *mng_processneed) (mng_handle hHandle,
+ mng_pchar zKeyword);
+typedef mng_bool (MNG_DECL *mng_processmend) (mng_handle hHandle,
+ mng_uint32 iIterationsdone,
+ mng_uint32 iIterationsleft);
+typedef mng_bool (MNG_DECL *mng_processunknown) (mng_handle hHandle,
+ mng_chunkid iChunkid,
+ mng_uint32 iRawlen,
+ mng_ptr pRawdata);
+typedef mng_bool (MNG_DECL *mng_processterm) (mng_handle hHandle,
+ mng_uint8 iTermaction,
+ mng_uint8 iIteraction,
+ mng_uint32 iDelay,
+ mng_uint32 iItermax);
+
+ /* display processing callbacks */
+typedef mng_ptr (MNG_DECL *mng_getcanvasline) (mng_handle hHandle,
+ mng_uint32 iLinenr);
+typedef mng_ptr (MNG_DECL *mng_getbkgdline) (mng_handle hHandle,
+ mng_uint32 iLinenr);
+typedef mng_ptr (MNG_DECL *mng_getalphaline) (mng_handle hHandle,
+ mng_uint32 iLinenr);
+typedef mng_bool (MNG_DECL *mng_refresh) (mng_handle hHandle,
+ mng_uint32 iX,
+ mng_uint32 iY,
+ mng_uint32 iWidth,
+ mng_uint32 iHeight);
+
+ /* timer management callbacks */
+typedef mng_uint32 (MNG_DECL *mng_gettickcount) (mng_handle hHandle);
+typedef mng_bool (MNG_DECL *mng_settimer) (mng_handle hHandle,
+ mng_uint32 iMsecs);
+
+ /* color management callbacks */
+typedef mng_bool (MNG_DECL *mng_processgamma) (mng_handle hHandle,
+ mng_uint32 iGamma);
+typedef mng_bool (MNG_DECL *mng_processchroma) (mng_handle hHandle,
+ mng_uint32 iWhitepointx,
+ mng_uint32 iWhitepointy,
+ mng_uint32 iRedx,
+ mng_uint32 iRedy,
+ mng_uint32 iGreenx,
+ mng_uint32 iGreeny,
+ mng_uint32 iBluex,
+ mng_uint32 iBluey);
+typedef mng_bool (MNG_DECL *mng_processsrgb) (mng_handle hHandle,
+ mng_uint8 iRenderingintent);
+typedef mng_bool (MNG_DECL *mng_processiccp) (mng_handle hHandle,
+ mng_uint32 iProfilesize,
+ mng_ptr pProfile);
+typedef mng_bool (MNG_DECL *mng_processarow) (mng_handle hHandle,
+ mng_uint32 iRowsamples,
+ mng_bool bIsRGBA16,
+ mng_ptr pRow);
+
+ /* chunk access callback(s) */
+typedef mng_bool (MNG_DECL *mng_iteratechunk) (mng_handle hHandle,
+ mng_handle hChunk,
+ mng_chunkid iChunkid,
+ mng_uint32 iChunkseq);
+
+/* ************************************************************************** */
+
+#endif /* _libmng_types_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_write.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_write.c
new file mode 100644
index 0000000..07a530f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_write.c
@@ -0,0 +1,139 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_write.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Write management (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the write management routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * 0.5.1 - 05/16/2000 - G.Juyn * */
+/* * - moved the actual write_graphic functionality from * */
+/* * mng_hlapi to it's appropriate function here * */
+/* * * */
+/* * 0.9.1 - 07/19/2000 - G.Juyn * */
+/* * - fixed writing of signature * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_memory.h"
+#include "libmng_chunks.h"
+#include "libmng_chunk_io.h"
+#include "libmng_write.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_WRITE_PROCS
+
+/* ************************************************************************** */
+
+mng_retcode write_graphic (mng_datap pData)
+{
+ mng_chunkp pChunk;
+ mng_retcode iRetcode;
+ mng_uint32 iWritten;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_GRAPHIC, MNG_LC_START)
+#endif
+
+ pChunk = pData->pFirstchunk; /* we'll start with the first, thank you */
+
+ if (pChunk) /* is there anything to write ? */
+ { /* open the file */
+ if (!pData->fOpenstream ((mng_handle)pData))
+ MNG_ERROR (pData, MNG_APPIOERROR)
+ else
+ {
+ pData->bWriting = MNG_TRUE; /* indicate writing */
+ pData->iWritebufsize = 32768; /* get a temporary write buffer */
+ /* reserve 12 bytes for length, chunkname & crc */
+ MNG_ALLOC (pData, pData->pWritebuf, pData->iWritebufsize+12)
+ /* write the signature */
+ if (((mng_chunk_headerp)pChunk)->iChunkname == MNG_UINT_IHDR)
+ mng_put_uint32 (pData->pWritebuf, PNG_SIG);
+ else
+ if (((mng_chunk_headerp)pChunk)->iChunkname == MNG_UINT_JHDR)
+ mng_put_uint32 (pData->pWritebuf, JNG_SIG);
+ else
+ mng_put_uint32 (pData->pWritebuf, MNG_SIG);
+
+ mng_put_uint32 (pData->pWritebuf+4, POST_SIG);
+
+ if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, 8, &iWritten))
+ {
+ MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize+12)
+ MNG_ERROR (pData, MNG_APPIOERROR)
+ }
+
+ if (iWritten != 8) /* disk full ? */
+ {
+ MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize+12)
+ MNG_ERROR (pData, MNG_OUTPUTERROR)
+ }
+
+ while (pChunk) /* so long as there's something to write */
+ { /* let's call it's output routine */
+ iRetcode = ((mng_chunk_headerp)pChunk)->fWrite (pData, pChunk);
+
+ if (iRetcode) /* on error bail out */
+ {
+ MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize+12)
+ return iRetcode;
+ }
+ /* neeeext */
+ pChunk = ((mng_chunk_headerp)pChunk)->pNext;
+ }
+ /* free the temporary buffer */
+ MNG_FREE (pData, pData->pWritebuf, pData->iWritebufsize+12)
+
+ pData->bWriting = MNG_FALSE; /* done writing */
+ /* close the stream now */
+ if (!pData->fClosestream ((mng_handle)pData))
+ MNG_ERROR (pData, MNG_APPIOERROR)
+
+ }
+ }
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_WRITE_GRAPHIC, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_WRITE_PROCS */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_write.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_write.h
new file mode 100644
index 0000000..df72396
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_write.h
@@ -0,0 +1,43 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_write.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : Write management (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the write management routines * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_write_h_
+#define _libmng_write_h_
+
+/* ************************************************************************** */
+
+mng_retcode write_graphic (mng_datap pData);
+
+/* ************************************************************************** */
+
+#endif /* _libmng_write_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_zlib.c b/tqtinterface/qt4/src/3rdparty/libmng/libmng_zlib.c
new file mode 100644
index 0000000..0730b2f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_zlib.c
@@ -0,0 +1,451 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_zlib.c copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : ZLIB library interface (implementation) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : implementation of the ZLIB library interface * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * 0.5.1 - 05/11/2000 - G.Juyn * */
+/* * - filled the deflatedata routine * */
+/* * 0.5.1 - 05/12/2000 - G.Juyn * */
+/* * - changed trace to macro for callback error-reporting * */
+/* * * */
+/* * 0.5.2 - 05/20/2000 - G.Juyn * */
+/* * - fixed for JNG alpha handling * */
+/* * 0.5.2 - 05/24/2000 - G.Juyn * */
+/* * - moved init of default zlib parms from here to * */
+/* * "mng_hlapi.c" * */
+/* * * */
+/* * 0.5.3 - 06/16/2000 - G.Juyn * */
+/* * - changed progressive-display processing * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* * 0.9.3 - 08/08/2000 - G.Juyn * */
+/* * - fixed compiler-warnings from Mozilla * */
+/* * 0.9.3 - 09/07/2000 - G.Juyn * */
+/* * - added support for new filter_types * */
+/* * * */
+/* ************************************************************************** */
+
+#include "libmng.h"
+#include "libmng_data.h"
+#include "libmng_error.h"
+#include "libmng_trace.h"
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+#include "libmng_memory.h"
+#include "libmng_pixels.h"
+#include "libmng_filter.h"
+#include "libmng_zlib.h"
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+/* ************************************************************************** */
+
+#ifdef MNG_INCLUDE_ZLIB
+
+/* ************************************************************************** */
+
+voidpf mngzlib_alloc (voidpf pData,
+ uInt iCount,
+ uInt iSize)
+{
+ voidpf pPtr; /* temporary space */
+
+#ifdef MNG_INTERNAL_MEMMNGMT
+ pPtr = calloc (iCount, iSize); /* local allocation */
+#else
+ if (((mng_datap)pData)->fMemalloc) /* callback function set ? */
+ pPtr = ((mng_datap)pData)->fMemalloc (iCount * iSize);
+ else
+ pPtr = Z_NULL; /* can't allocate! */
+#endif
+
+ return pPtr; /* return the result */
+}
+
+/* ************************************************************************** */
+
+void mngzlib_free (voidpf pData,
+ voidpf pAddress)
+{
+#ifdef MNG_INTERNAL_MEMMNGMT
+ free (pAddress); /* free locally */
+#else
+ if (((mng_datap)pData)->fMemfree) /* callback set? */
+ ((mng_datap)pData)->fMemfree (pAddress, 1);
+#endif
+}
+
+/* ************************************************************************** */
+
+mng_retcode mngzlib_initialize (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_INITIALIZE, MNG_LC_START)
+#endif
+
+#ifdef MNG_INTERNAL_MEMMNGMT
+ pData->sZlib.zalloc = Z_NULL; /* let zlib figure out memory management */
+ pData->sZlib.zfree = Z_NULL;
+ pData->sZlib.opaque = Z_NULL;
+#else /* use user-provided callbacks */
+ pData->sZlib.zalloc = mngzlib_alloc;
+ pData->sZlib.zfree = mngzlib_free;
+ pData->sZlib.opaque = (voidpf)pData;
+#endif
+
+ pData->bInflating = MNG_FALSE; /* not performing any action yet */
+ pData->bDeflating = MNG_FALSE;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_INITIALIZE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+mng_retcode mngzlib_cleanup (mng_datap pData)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_CLEANUP, MNG_LC_START)
+#endif
+
+ if (pData->bInflating) /* force zlib cleanup */
+ mngzlib_inflatefree (pData);
+ if (pData->bDeflating)
+ mngzlib_deflatefree (pData);
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_CLEANUP, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+mng_retcode mngzlib_inflateinit (mng_datap pData)
+{
+ int iZrslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEINIT, MNG_LC_START)
+#endif
+ /* initialize zlib structures and such */
+ iZrslt = inflateInit (&pData->sZlib);
+
+ if (iZrslt != Z_OK) /* on error bail out */
+ MNG_ERRORZ (pData, (mng_uint32)iZrslt)
+
+ pData->bInflating = MNG_TRUE; /* really inflating something now */
+ pData->sZlib.next_out = 0; /* force JIT initialization */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEINIT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+#ifdef MNG_SUPPORT_DISPLAY
+mng_retcode mngzlib_inflaterows (mng_datap pData,
+ mng_uint32 iInlen,
+ mng_uint8p pIndata)
+{
+ int iZrslt;
+ mng_retcode iRslt;
+ mng_ptr pSwap;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEROWS, MNG_LC_START)
+#endif
+
+ pData->sZlib.next_in = pIndata; /* let zlib know where to get stuff */
+ pData->sZlib.avail_in = (uInt)iInlen;
+
+ if (pData->sZlib.next_out == 0) /* initialize output variables ? */
+ { /* let zlib know where to store stuff */
+ pData->sZlib.next_out = pData->pWorkrow;
+ pData->sZlib.avail_out = (uInt)(pData->iRowsize + pData->iPixelofs);
+ }
+
+ do
+ { /* now inflate a row */
+ iZrslt = inflate (&pData->sZlib, Z_SYNC_FLUSH);
+ /* produced a full row ? */
+ if (((iZrslt == Z_OK) || (iZrslt == Z_STREAM_END)) &&
+ (pData->sZlib.avail_out == 0))
+ { /* shouldn't we be at the end ? */
+ if (pData->iRow >= (mng_int32)pData->iDataheight)
+/* MNG_ERROR (pData, MNG_TOOMUCHIDAT) */ ; /* TODO: check this!!! */
+ else
+ { /* has leveling info ? */
+/* if (pData->iFilterofs)
+ iRslt = init_rowdiffering (pData);
+ else
+ iRslt = MNG_NOERROR; */
+ /* filter the row if necessary */
+/* if ((!iRslt) && (pData->iFilterofs < pData->iPixelofs ) &&
+ (*(pData->pWorkrow + pData->iFilterofs)) ) */
+ if (*(pData->pWorkrow + pData->iFilterofs))
+ iRslt = filter_a_row (pData);
+ else
+ iRslt = MNG_NOERROR;
+ /* additonal leveling/differing ? */
+ if ((!iRslt) && (pData->fDifferrow))
+ {
+ iRslt = ((mng_differrow)pData->fDifferrow) (pData);
+
+ pSwap = pData->pWorkrow;
+ pData->pWorkrow = pData->pPrevrow;
+ pData->pPrevrow = pSwap; /* make sure we're processing the right data */
+ }
+
+ if (!iRslt)
+ {
+#ifdef MNG_INCLUDE_JNG
+ if (pData->bHasJHDR) /* is JNG alpha-channel ? */
+ { /* just store in object ? */
+ if ((!iRslt) && (pData->fStorerow))
+ iRslt = ((mng_storerow)pData->fStorerow) (pData);
+ }
+ else
+#endif /* MNG_INCLUDE_JNG */
+ { /* process this row */
+ if ((!iRslt) && (pData->fProcessrow))
+ iRslt = ((mng_processrow)pData->fProcessrow) (pData);
+ /* store in object ? */
+ if ((!iRslt) && (pData->fStorerow))
+ iRslt = ((mng_storerow)pData->fStorerow) (pData);
+ /* color correction ? */
+ if ((!iRslt) && (pData->fCorrectrow))
+ iRslt = ((mng_correctrow)pData->fCorrectrow) (pData);
+ /* slap onto canvas ? */
+ if ((!iRslt) && (pData->fDisplayrow))
+ {
+ iRslt = ((mng_displayrow)pData->fDisplayrow) (pData);
+
+ if (!iRslt) /* check progressive display refresh */
+ iRslt = display_progressive_check (pData);
+
+ }
+ }
+ }
+
+ if (iRslt) /* on error bail out */
+ MNG_ERROR (pData, iRslt);
+
+ if (!pData->fDifferrow) /* swap row-pointers */
+ {
+ pSwap = pData->pWorkrow;
+ pData->pWorkrow = pData->pPrevrow;
+ pData->pPrevrow = pSwap; /* so prev points to the processed row! */
+ }
+
+ iRslt = next_row (pData); /* adjust variables for next row */
+
+ if (iRslt) /* on error bail out */
+ MNG_ERROR (pData, iRslt);
+ }
+ /* let zlib know where to store next output */
+ pData->sZlib.next_out = pData->pWorkrow;
+ pData->sZlib.avail_out = (uInt)(pData->iRowsize + pData->iPixelofs);
+ }
+ } /* until some error or EOI */
+ while ((iZrslt == Z_OK) && (pData->sZlib.avail_in > 0));
+ /* on error bail out */
+ if ((iZrslt != Z_OK) && (iZrslt != Z_STREAM_END))
+ MNG_ERRORZ (pData, (mng_uint32)iZrslt)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEROWS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+#endif /* MNG_SUPPORT_DISPLAY */
+
+/* ************************************************************************** */
+
+mng_retcode mngzlib_inflatedata (mng_datap pData,
+ mng_uint32 iInlen,
+ mng_uint8p pIndata)
+{
+ int iZrslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEDATA, MNG_LC_START)
+#endif
+ /* let zlib know where to get stuff */
+ pData->sZlib.next_in = pIndata;
+ pData->sZlib.avail_in = (uInt)iInlen;
+ /* now inflate the data in one go! */
+ iZrslt = inflate (&pData->sZlib, Z_FINISH);
+ /* not enough room in output-buffer ? */
+ if ((iZrslt == Z_BUF_ERROR) || (pData->sZlib.avail_in > 0))
+ return MNG_BUFOVERFLOW;
+ /* on error bail out */
+ if ((iZrslt != Z_OK) && (iZrslt != Z_STREAM_END))
+ MNG_ERRORZ (pData, (mng_uint32)iZrslt)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEDATA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mngzlib_inflatefree (mng_datap pData)
+{
+ int iZrslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEFREE, MNG_LC_START)
+#endif
+
+ pData->bInflating = MNG_FALSE; /* stopped it */
+
+ iZrslt = inflateEnd (&pData->sZlib); /* let zlib cleanup it's own stuff */
+
+ if (iZrslt != Z_OK) /* on error bail out */
+ MNG_ERRORZ (pData, (mng_uint32)iZrslt)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_INFLATEFREE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+mng_retcode mngzlib_deflateinit (mng_datap pData)
+{
+ int iZrslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEINIT, MNG_LC_START)
+#endif
+ /* initialize zlib structures and such */
+ iZrslt = deflateInit2 (&pData->sZlib, pData->iZlevel, pData->iZmethod,
+ pData->iZwindowbits, pData->iZmemlevel,
+ pData->iZstrategy);
+
+ if (iZrslt != Z_OK) /* on error bail out */
+ MNG_ERRORZ (pData, (mng_uint32)iZrslt)
+
+ pData->bDeflating = MNG_TRUE; /* really deflating something now */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEINIT, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+mng_retcode mngzlib_deflaterows (mng_datap pData,
+ mng_uint32 iInlen,
+ mng_uint8p pIndata)
+{
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEROWS, MNG_LC_START)
+#endif
+
+
+
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEROWS, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mngzlib_deflatedata (mng_datap pData,
+ mng_uint32 iInlen,
+ mng_uint8p pIndata)
+{
+ int iZrslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEDATA, MNG_LC_START)
+#endif
+
+ pData->sZlib.next_in = pIndata; /* let zlib know where to get stuff */
+ pData->sZlib.avail_in = (uInt)iInlen;
+ /* now deflate the data in one go! */
+ iZrslt = deflate (&pData->sZlib, Z_FINISH);
+ /* not enough room in output-buffer ? */
+ if ((iZrslt == Z_BUF_ERROR) || (pData->sZlib.avail_in > 0))
+ return MNG_BUFOVERFLOW;
+ /* on error bail out */
+ if ((iZrslt != Z_OK) && (iZrslt != Z_STREAM_END))
+ MNG_ERRORZ (pData, (mng_uint32)iZrslt)
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEDATA, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR;
+}
+
+/* ************************************************************************** */
+
+mng_retcode mngzlib_deflatefree (mng_datap pData)
+{
+ int iZrslt;
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEFREE, MNG_LC_START)
+#endif
+
+ iZrslt = deflateEnd (&pData->sZlib); /* let zlib cleanup it's own stuff */
+
+ if (iZrslt != Z_OK) /* on error bail out */
+ MNG_ERRORZ (pData, (mng_uint32)iZrslt)
+
+ pData->bDeflating = MNG_FALSE; /* stopped it */
+
+#ifdef MNG_SUPPORT_TRACE
+ MNG_TRACE (pData, MNG_FN_ZLIB_DEFLATEFREE, MNG_LC_END)
+#endif
+
+ return MNG_NOERROR; /* done */
+}
+
+/* ************************************************************************** */
+
+#endif /* MNG_INCLUDE_ZLIB */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/libmng_zlib.h b/tqtinterface/qt4/src/3rdparty/libmng/libmng_zlib.h
new file mode 100644
index 0000000..e5bfbdb
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/libmng_zlib.h
@@ -0,0 +1,62 @@
+/* ************************************************************************** */
+/* * For conditions of distribution and use, * */
+/* * see copyright notice in libmng.h * */
+/* ************************************************************************** */
+/* * * */
+/* * project : libmng * */
+/* * file : libmng_zlib.h copyright (c) 2000 G.Juyn * */
+/* * version : 1.0.0 * */
+/* * * */
+/* * purpose : ZLIB package interface (definition) * */
+/* * * */
+/* * author : G.Juyn * */
+/* * web : http://www.3-t.com * */
+/* * email : mailto:info@3-t.com * */
+/* * * */
+/* * comment : Definition of the ZLIB package interface * */
+/* * * */
+/* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
+/* * - changed strict-ANSI stuff * */
+/* * * */
+/* * 0.9.2 - 08/05/2000 - G.Juyn * */
+/* * - changed file-prefixes * */
+/* * * */
+/* ************************************************************************** */
+
+#if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
+#pragma option -A /* force ANSI-C */
+#endif
+
+#ifndef _libmng_zlib_h_
+#define _libmng_zlib_h_
+
+/* ************************************************************************** */
+
+mng_retcode mngzlib_initialize (mng_datap pData);
+mng_retcode mngzlib_cleanup (mng_datap pData);
+
+mng_retcode mngzlib_inflateinit (mng_datap pData);
+mng_retcode mngzlib_inflaterows (mng_datap pData,
+ mng_uint32 iInlen,
+ mng_uint8p pIndata);
+mng_retcode mngzlib_inflatedata (mng_datap pData,
+ mng_uint32 iInlen,
+ mng_uint8p pIndata);
+mng_retcode mngzlib_inflatefree (mng_datap pData);
+
+mng_retcode mngzlib_deflateinit (mng_datap pData);
+mng_retcode mngzlib_deflaterows (mng_datap pData,
+ mng_uint32 iInlen,
+ mng_uint8p pIndata);
+mng_retcode mngzlib_deflatedata (mng_datap pData,
+ mng_uint32 iInlen,
+ mng_uint8p pIndata);
+mng_retcode mngzlib_deflatefree (mng_datap pData);
+
+/* ************************************************************************** */
+
+#endif /* _libmng_zlib_h_ */
+
+/* ************************************************************************** */
+/* * end of file * */
+/* ************************************************************************** */
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/ltmain.sh b/tqtinterface/qt4/src/3rdparty/libmng/ltmain.sh
new file mode 100644
index 0000000..7cd29f6
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/ltmain.sh
@@ -0,0 +1,4988 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun configure.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+# Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that tqcontains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell, and then maybe $echo will work.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.4.2
+TIMESTAMP=" (1.922.2.54 2001/09/11 03:33:37)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \015\012 \040\040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+ save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+ save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+# Make sure IFS has a sensible default
+: ${IFS=" "}
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ echo "$modename: not configured to build any kind of library" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+ arg="$1"
+ shift
+
+ case $arg in
+ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ execute_dlfiles)
+ execute_dlfiles="$execute_dlfiles $arg"
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
+ prev=
+ prevopt=
+ continue
+ fi
+
+ # Have we seen a non-optional argument yet?
+ case $arg in
+ --help)
+ show_help=yes
+ ;;
+
+ --version)
+ echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+ exit 0
+ ;;
+
+ --config)
+ sed -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --dry-run | -n)
+ run=:
+ ;;
+
+ --features)
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+ exit 0
+ ;;
+
+ --finish) mode="finish" ;;
+
+ --mode) prevopt="--mode" prev=mode ;;
+ --mode=*) mode="$optarg" ;;
+
+ --quiet | --silent)
+ show=:
+ ;;
+
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
+ -*)
+ $echo "$modename: unrecognized option \`$arg'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ nonopt="$arg"
+ break
+ ;;
+ esac
+done
+
+if test -n "$prevopt"; then
+ $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+fi
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end. This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+if test -z "$show_help"; then
+
+ # Infer the operation mode.
+ if test -z "$mode"; then
+ case $nonopt in
+ *cc | *++ | gcc* | *-gcc*)
+ mode=link
+ for arg
+ do
+ case $arg in
+ -c)
+ mode=compile
+ break
+ ;;
+ esac
+ done
+ ;;
+ *db | *dbx | *strace | *truss)
+ mode=execute
+ ;;
+ *install*|cp|mv)
+ mode=install
+ ;;
+ *rm)
+ mode=uninstall
+ ;;
+ *)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
+ # Just use the default operation mode.
+ if test -z "$mode"; then
+ if test -n "$nonopt"; then
+ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+ else
+ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+ fi
+ fi
+ ;;
+ esac
+ fi
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$modename --help --mode=$mode' for more information."
+
+ # These modes are in order of execution frequency so that they run quickly.
+ case $mode in
+ # libtool compile mode
+ compile)
+ modename="$modename: compile"
+ # Get the compilation command and the source file.
+ base_compile=
+ prev=
+ lastarg=
+ srcfile="$nonopt"
+ suppress_output=
+
+ user_target=no
+ for arg
+ do
+ case $prev in
+ "") ;;
+ xcompiler)
+ # Aesthetically quote the previous argument.
+ prev=
+ lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+
+ case $arg in
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ continue
+ ;;
+ esac
+
+ # Accept any command-line options.
+ case $arg in
+ -o)
+ if test "$user_target" != "no"; then
+ $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+ exit 1
+ fi
+ user_target=next
+ ;;
+
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
+
+ -prefer-pic)
+ pic_mode=yes
+ continue
+ ;;
+
+ -prefer-non-pic)
+ pic_mode=no
+ continue
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Wc,*)
+ args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"`
+ lastarg=
+ save_ifs="$IFS"; IFS=','
+ for arg in $args; do
+ IFS="$save_ifs"
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ lastarg="$lastarg $arg"
+ done
+ IFS="$save_ifs"
+ lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"`
+
+ # Add the arguments to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ continue
+ ;;
+ esac
+
+ case $user_target in
+ next)
+ # The next one is the -o target name
+ user_target=yes
+ continue
+ ;;
+ yes)
+ # We got the output file
+ user_target=set
+ libobj="$arg"
+ continue
+ ;;
+ esac
+
+ # Accept the current argument as the source file.
+ lastarg="$srcfile"
+ srcfile="$arg"
+
+ # Aesthetically quote the previous argument.
+
+ # Backslashify any backslashes, double quotes, and dollar signs.
+ # These are the only characters that are still specially
+ # interpreted inside of double-quoted scrings.
+ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly
+ # in scan sets, so we specify it separately.
+ case $lastarg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ lastarg="\"$lastarg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ done
+
+ case $user_target in
+ set)
+ ;;
+ no)
+ # Get the name of the library object.
+ libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ ;;
+ *)
+ $echo "$modename: you must specify a target with \`-o'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is tqreplaced with file.lo
+ xform='[cCFSfmso]'
+ case $libobj in
+ *.ada) xform=ada ;;
+ *.adb) xform=adb ;;
+ *.ads) xform=ads ;;
+ *.asm) xform=asm ;;
+ *.c++) xform=c++ ;;
+ *.cc) xform=cc ;;
+ *.cpp) xform=cpp ;;
+ *.cxx) xform=cxx ;;
+ *.f90) xform=f90 ;;
+ *.for) xform=for ;;
+ esac
+
+ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+ case $libobj in
+ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+ *)
+ $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$base_compile"; then
+ $echo "$modename: you must specify a compilation command" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $libobj"
+ else
+ removelist="$libobj"
+ fi
+
+ $run $rm $removelist
+ trap "$run $rm $removelist; exit 1" 1 2 15
+
+ # On Cygwin there's no "real" PIC flag so we must build both object types
+ case $host_os in
+ cygwin* | mingw* | pw32* | os2*)
+ pic_mode=default
+ ;;
+ esac
+ if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+ # non-PIC code in shared libraries is not supported
+ pic_mode=default
+ fi
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ removelist="$removelist $output_obj $lockfile"
+ trap "$run $rm $removelist; exit 1" 1 2 15
+ else
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until $run ln "$0" "$lockfile" 2>/dev/null; do
+ $show "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ echo "\
+*** ERROR, $lockfile exists and tqcontains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+ echo $srcfile > "$lockfile"
+ fi
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ if test "$pic_mode" != no; then
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ command="$base_compile $srcfile $pic_flag -DPIC"
+ else
+ # Don't build PIC code
+ command="$base_compile $srcfile"
+ fi
+ if test "$build_old_libs" = yes; then
+ lo_libobj="$libobj"
+ dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$libobj"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+ if test -d "$dir"; then
+ $show "$rm $libobj"
+ $run $rm $libobj
+ else
+ $show "$mkdir $dir"
+ $run $mkdir $dir
+ status=$?
+ if test $status -ne 0 && test ! -d $dir; then
+ exit $status
+ fi
+ fi
+ fi
+ if test "$compiler_o_lo" = yes; then
+ output_obj="$libobj"
+ command="$command -o $output_obj"
+ elif test "$compiler_c_o" = yes; then
+ output_obj="$obj"
+ command="$command -o $output_obj"
+ fi
+
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ test -n "$output_obj" && $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile tqcontains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test x"$output_obj" != x"$libobj"; then
+ $show "$mv $output_obj $libobj"
+ if $run $mv $output_obj $libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # If we have no pic_flag, then copy the object into place and finish.
+ if (test -z "$pic_flag" || test "$pic_mode" != default) &&
+ test "$build_old_libs" = yes; then
+ # Rename the .lo from within objdir to obj
+ if test -f $obj; then
+ $show $rm $obj
+ $run $rm $obj
+ fi
+
+ $show "$mv $libobj $obj"
+ if $run $mv $libobj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
+ libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+ # Now arrange that obj and lo_libobj become the same file
+ $show "(cd $xdir && $LN_S $baseobj $libobj)"
+ if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $run $rm "$lockfile"
+ fi
+ exit 0
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Allow error messages only from the first compilation.
+ suppress_output=' >/dev/null 2>&1'
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ if test "$pic_mode" != yes; then
+ # Don't build PIC code
+ command="$base_compile $srcfile"
+ else
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ command="$base_compile $srcfile $pic_flag -DPIC"
+ fi
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ output_obj="$obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile tqcontains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed
+ if test x"$output_obj" != x"$obj"; then
+ $show "$mv $output_obj $obj"
+ if $run $mv $output_obj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we do not
+ # accidentally link it into a program.
+ if test "$build_libtool_libs" != yes; then
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > \$libobj" || exit $?
+ else
+ # Move the .lo from within objdir
+ $show "$mv $libobj $lo_libobj"
+ if $run $mv $libobj $lo_libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+ fi
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $run $rm "$lockfile"
+ fi
+
+ exit 0
+ ;;
+
+ # libtool link mode
+ link | relink)
+ modename="$modename: link"
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invokation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ libtool_args="$nonopt"
+ compile_command="$nonopt"
+ finalize_command="$nonopt"
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ old_deplibs=
+ compiler_flags=
+ linker_flags=
+ dllsearchpath=
+ lib_search_path=`pwd`
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ ltlibs=
+ module=no
+ no_install=no
+ objs=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case $arg in
+ -all-static | -static)
+ if test "X$arg" = "X-all-static"; then
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ else
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ fi
+ build_libtool_libs=no
+ build_old_libs=yes
+ prefer_static_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test $# -gt 0; do
+ arg="$1"
+ shift
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test
+ ;;
+ *) qarg=$arg ;;
+ esac
+ libtool_args="$libtool_args $qarg"
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case $prev in
+ output)
+ compile_command="$compile_command @OUTPUT@"
+ finalize_command="$finalize_command @OUTPUT@"
+ ;;
+ esac
+
+ case $prev in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ compile_command="$compile_command @SYMFILE@"
+ finalize_command="$finalize_command @SYMFILE@"
+ preload=yes
+ fi
+ case $arg in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ continue
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ if test ! -f "$arg"; then
+ $echo "$modename: symbol file \`$arg' does not exist"
+ exit 1
+ fi
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case $arg in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ xcompiler)
+ compiler_flags="$compiler_flags $qarg"
+ prev=
+ compile_command="$compile_command $qarg"
+ finalize_command="$finalize_command $qarg"
+ continue
+ ;;
+ xlinker)
+ linker_flags="$linker_flags $qarg"
+ compiler_flags="$compiler_flags $wl$qarg"
+ prev=
+ compile_command="$compile_command $wl$qarg"
+ finalize_command="$finalize_command $wl$qarg"
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi # test -n $prev
+
+ prevarg="$arg"
+
+ case $arg in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+ continue
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: more than one -exported-symbols argument is not allowed"
+ exit 1
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+ # so, if we see these flags be careful not to treat them like -L
+ -L[A-Z][A-Z]*:*)
+ case $with_gcc/$host in
+ no/*-*-irix*)
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ ;;
+ esac
+ continue
+ ;;
+
+ -L*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+ exit 1
+ fi
+ dir="$absdir"
+ ;;
+ esac
+ case "$deplibs " in
+ *" -L$dir "*) ;;
+ *)
+ deplibs="$deplibs -L$dir"
+ lib_search_path="$lib_search_path $dir"
+ ;;
+ esac
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ case :$dllsearchpath: in
+ *":$dir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$dir";;
+ esac
+ ;;
+ esac
+ continue
+ ;;
+
+ -l*)
+ if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+ case $host in
+ *-*-cygwin* | *-*-pw32* | *-*-beos*)
+ # These systems don't actually have a C or math library (as such)
+ continue
+ ;;
+ *-*-mingw* | *-*-os2*)
+ # These systems don't actually have a C library (as such)
+ test "X$arg" = "X-lc" && continue
+ ;;
+ *-*-openbsd*)
+ # Do not include libc due to us having libc/libc_r.
+ test "X$arg" = "X-lc" && continue
+ ;;
+ esac
+ elif test "X$arg" = "X-lc_r"; then
+ case $host in
+ *-*-openbsd*)
+ # Do not include libc_r directly, use -pthread flag.
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ continue
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ -no-fast-install)
+ fast_install=no
+ continue
+ ;;
+
+ -no-install)
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ # The PATH hackery in wrapper scripts is required on Windows
+ # in order for the loader to tqfind any dlls it needs.
+ $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2
+ $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2
+ fast_install=no
+ ;;
+ *) no_install=yes ;;
+ esac
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -static)
+ # The effects of -static are defined in a previous loop.
+ # We used to do the same as -all-static on platforms that
+ # didn't have a PIC flag, but the assumption that the effects
+ # would be equivalent was wrong. It would break on at least
+ # Digital Unix and AIX.
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ -Wc,*)
+ args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'`
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ case $flag in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ flag="\"$flag\""
+ ;;
+ esac
+ arg="$arg $wl$flag"
+ compiler_flags="$compiler_flags $flag"
+ done
+ IFS="$save_ifs"
+ arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+ ;;
+
+ -Wl,*)
+ args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'`
+ arg=
+ save_ifs="$IFS"; IFS=','
+ for flag in $args; do
+ IFS="$save_ifs"
+ case $flag in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ flag="\"$flag\""
+ ;;
+ esac
+ arg="$arg $wl$flag"
+ compiler_flags="$compiler_flags $wl$flag"
+ linker_flags="$linker_flags $flag"
+ done
+ IFS="$save_ifs"
+ arg=`$echo "X$arg" | $Xsed -e "s/^ //"`
+ ;;
+
+ -Xcompiler)
+ prev=xcompiler
+ continue
+ ;;
+
+ -Xlinker)
+ prev=xlinker
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+
+ *.lo | *.$objext)
+ # A library or standard object.
+ if test "$prev" = dlfiles; then
+ # This file was specified with -dlopen.
+ if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+ dlfiles="$dlfiles $arg"
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+ prev=
+ else
+ case $arg in
+ *.lo) libobjs="$libobjs $arg" ;;
+ *) objs="$objs $arg" ;;
+ esac
+ fi
+ ;;
+
+ *.$libext)
+ # An archive.
+ deplibs="$deplibs $arg"
+ old_deplibs="$old_deplibs $arg"
+ continue
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ if test "$prev" = dlfiles; then
+ # This library was specified with -dlopen.
+ dlfiles="$dlfiles $arg"
+ prev=
+ elif test "$prev" = dlprefiles; then
+ # The library was specified with -dlpreopen.
+ dlprefiles="$dlprefiles $arg"
+ prev=
+ else
+ deplibs="$deplibs $arg"
+ fi
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+ esac # arg
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+ done # argument parsing loop
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+
+ # calculate the name of the file, without its directory
+ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+ libobjs_save="$libobjs"
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ shlib_search_path=
+ fi
+ eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+ # Create the object directory.
+ if test ! -d "$output_objdir"; then
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$output_objdir"; then
+ exit $status
+ fi
+ fi
+
+ # Determine the type of output
+ case $output in
+ "")
+ $echo "$modename: you must specify an output file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ *.$libext) linkmode=oldlib ;;
+ *.lo | *.$objext) linkmode=obj ;;
+ *.la) linkmode=lib ;;
+ *) linkmode=prog ;; # Anything else should be a program.
+ esac
+
+ specialdeplibs=
+ libs=
+ # Find all interdependent deplibs by searching for libraries
+ # that are linked more than once (e.g. -la -lb -la)
+ for deplib in $deplibs; do
+ case "$libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ libs="$libs $deplib"
+ done
+ deplibs=
+ newdependency_libs=
+ newlib_search_path=
+ need_relink=no # whether we're linking any uninstalled libtool libraries
+ notinst_deplibs= # not-installed libtool libraries
+ notinst_path= # paths that contain not-installed libtool libraries
+ case $linkmode in
+ lib)
+ passes="conv link"
+ for file in $dlfiles $dlprefiles; do
+ case $file in
+ *.la) ;;
+ *)
+ $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ prog)
+ compile_deplibs=
+ finalize_deplibs=
+ alldeplibs=no
+ newdlfiles=
+ newdlprefiles=
+ passes="conv scan dlopen dlpreopen link"
+ ;;
+ *) passes="conv"
+ ;;
+ esac
+ for pass in $passes; do
+ if test "$linkmode" = prog; then
+ # Determine which files to process
+ case $pass in
+ dlopen)
+ libs="$dlfiles"
+ save_deplibs="$deplibs" # Collect dlpreopened libraries
+ deplibs=
+ ;;
+ dlpreopen) libs="$dlprefiles" ;;
+ link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+ esac
+ fi
+ for deplib in $libs; do
+ lib=
+ found=no
+ case $deplib in
+ -l*)
+ if test "$linkmode" = oldlib && test "$linkmode" = obj; then
+ $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2
+ continue
+ fi
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ name=`$echo "X$deplib" | $Xsed -e 's/^-l//'`
+ for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ # Search the libtool library
+ lib="$searchdir/lib${name}.la"
+ if test -f "$lib"; then
+ found=yes
+ break
+ fi
+ done
+ if test "$found" != yes; then
+ # deplib doesn't seem to be a libtool library
+ if test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ deplibs="$deplib $deplibs"
+ test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+ fi
+ continue
+ fi
+ ;; # -l
+ -L*)
+ case $linkmode in
+ lib)
+ deplibs="$deplib $deplibs"
+ test "$pass" = conv && continue
+ newdependency_libs="$deplib $newdependency_libs"
+ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+ ;;
+ prog)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ if test "$pass" = scan; then
+ deplibs="$deplib $deplibs"
+ newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ ;;
+ *)
+ $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2
+ ;;
+ esac # linkmode
+ continue
+ ;; # -L
+ -R*)
+ if test "$pass" = link; then
+ dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+ # Make sure the xrpath tqcontains only unique directories.
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ fi
+ deplibs="$deplib $deplibs"
+ continue
+ ;;
+ *.la) lib="$deplib" ;;
+ *.$libext)
+ if test "$pass" = conv; then
+ deplibs="$deplib $deplibs"
+ continue
+ fi
+ case $linkmode in
+ lib)
+ if test "$deplibs_check_method" != pass_all; then
+ echo
+ echo "*** Warning: This library needs some functionality provided by $deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ else
+ echo
+ echo "*** Warning: Linking the shared library $output against the"
+ echo "*** static library $deplib is not portable!"
+ deplibs="$deplib $deplibs"
+ fi
+ continue
+ ;;
+ prog)
+ if test "$pass" != link; then
+ deplibs="$deplib $deplibs"
+ else
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ fi
+ continue
+ ;;
+ esac # linkmode
+ ;; # *.$libext
+ *.lo | *.$objext)
+ if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlopen support or we're linking statically,
+ # we need to preload.
+ newdlprefiles="$newdlprefiles $deplib"
+ compile_deplibs="$deplib $compile_deplibs"
+ finalize_deplibs="$deplib $finalize_deplibs"
+ else
+ newdlfiles="$newdlfiles $deplib"
+ fi
+ continue
+ ;;
+ %DEPLIBS%)
+ alldeplibs=yes
+ continue
+ ;;
+ esac # case $deplib
+ if test "$found" = yes || test -f "$lib"; then :
+ else
+ $echo "$modename: cannot tqfind the library \`$lib'" 1>&2
+ exit 1
+ fi
+
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+
+ ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$ladir" = "X$lib" && ladir="."
+
+ dlname=
+ dlopen=
+ dlpreopen=
+ libdir=
+ library_names=
+ old_library=
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variable installed.
+ installed=yes
+
+ # Read the .la file
+ case $lib in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+
+ if test "$linkmode,$pass" = "lib,link" ||
+ test "$linkmode,$pass" = "prog,scan" ||
+ { test "$linkmode" = oldlib && test "$linkmode" = obj; }; then
+ # Add dl[pre]opened files of deplib
+ test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+ test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+ fi
+
+ if test "$pass" = conv; then
+ # Only check for convenience libraries
+ deplibs="$lib $deplibs"
+ if test -z "$libdir"; then
+ if test -z "$old_library"; then
+ $echo "$modename: cannot tqfind name of link library for \`$lib'" 1>&2
+ exit 1
+ fi
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $ladir/$objdir/$old_library"
+ old_convenience="$old_convenience $ladir/$objdir/$old_library"
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ deplibs="$deplib $deplibs"
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ tmp_libs="$tmp_libs $deplib"
+ done
+ elif test "$linkmode" != prog && test "$linkmode" != lib; then
+ $echo "$modename: \`$lib' is not a convenience library" 1>&2
+ exit 1
+ fi
+ continue
+ fi # $pass = conv
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+ if test -z "$linklib"; then
+ $echo "$modename: cannot tqfind name of link library for \`$lib'" 1>&2
+ exit 1
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$pass" = dlopen; then
+ if test -z "$libdir"; then
+ $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2
+ exit 1
+ fi
+ if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking
+ # statically, we need to preload.
+ dlprefiles="$dlprefiles $lib"
+ else
+ newdlfiles="$newdlfiles $lib"
+ fi
+ continue
+ fi # $pass = dlopen
+
+ # We need an absolute path.
+ case $ladir in
+ [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+ *)
+ abs_ladir=`cd "$ladir" && pwd`
+ if test -z "$abs_ladir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ abs_ladir="$ladir"
+ fi
+ ;;
+ esac
+ laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+
+ # Find the relevant object directory and library name.
+ if test "X$installed" = Xyes; then
+ if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+ $echo "$modename: warning: library \`$lib' was moved." 1>&2
+ dir="$ladir"
+ absdir="$abs_ladir"
+ libdir="$abs_ladir"
+ else
+ dir="$libdir"
+ absdir="$libdir"
+ fi
+ else
+ dir="$ladir/$objdir"
+ absdir="$abs_ladir/$objdir"
+ # Remove this search path later
+ notinst_path="$notinst_path $abs_ladir"
+ fi # $installed = yes
+ name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+
+ # This library was specified with -dlpreopen.
+ if test "$pass" = dlpreopen; then
+ if test -z "$libdir"; then
+ $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2
+ exit 1
+ fi
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ newdlprefiles="$newdlprefiles $dir/$old_library"
+ # Otherwise, use the dlname, so that lt_dlopen tqfinds it.
+ elif test -n "$dlname"; then
+ newdlprefiles="$newdlprefiles $dir/$dlname"
+ else
+ newdlprefiles="$newdlprefiles $dir/$linklib"
+ fi
+ fi # $pass = dlpreopen
+
+ if test -z "$libdir"; then
+ # Link the convenience library
+ if test "$linkmode" = lib; then
+ deplibs="$dir/$old_library $deplibs"
+ elif test "$linkmode,$pass" = "prog,link"; then
+ compile_deplibs="$dir/$old_library $compile_deplibs"
+ finalize_deplibs="$dir/$old_library $finalize_deplibs"
+ else
+ deplibs="$lib $deplibs"
+ fi
+ continue
+ fi
+
+ if test "$linkmode" = prog && test "$pass" != link; then
+ newlib_search_path="$newlib_search_path $ladir"
+ deplibs="$lib $deplibs"
+
+ linkalldeplibs=no
+ if test "$link_all_deplibs" != no || test -z "$library_names" ||
+ test "$build_libtool_libs" = no; then
+ linkalldeplibs=yes
+ fi
+
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test
+ esac
+ # Need to link against all dependency_libs?
+ if test "$linkalldeplibs" = yes; then
+ deplibs="$deplib $deplibs"
+ else
+ # Need to hardcode shared library paths
+ # or/and link against static libraries
+ newdependency_libs="$deplib $newdependency_libs"
+ fi
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ tmp_libs="$tmp_libs $deplib"
+ done # for deplib
+ continue
+ fi # $linkmode = prog...
+
+ link_static=no # Whether the deplib will be linked statically
+ if test -n "$library_names" &&
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ # Link against this shared library
+
+ if test "$linkmode,$pass" = "prog,link" ||
+ { test "$linkmode" = lib && test "$hardcode_into_libs" = yes; }; then
+ # Hardcode the library path.
+ # Skip directories that are in the system default run-time
+ # search path.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+ if test "$linkmode" = prog; then
+ # We need to hardcode the library path
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath tqcontains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *" $absdir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
+ fi
+ fi # $linkmode,$pass = prog,link...
+
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+
+ if test "$installed" = no; then
+ notinst_deplibs="$notinst_deplibs $lib"
+ need_relink=yes
+ fi
+
+ if test -n "$old_archive_from_expsyms_cmds"; then
+ # figure out the soname
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+ libname=`eval \\$echo \"$libname_spec\"`
+ # use dlname if we got it. it's perfectly good, no?
+ if test -n "$dlname"; then
+ soname="$dlname"
+ elif test -n "$soname_spec"; then
+ # bleh windows
+ case $host in
+ *cygwin*)
+ major=`expr $current - $age`
+ versuffix="-$major"
+ ;;
+ esac
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ # Make a new name for the extract_expsyms_cmds to use
+ soroot="$soname"
+ soname=`echo $soroot | sed -e 's/^.*\///'`
+ newlib="libimp-`echo $soname | sed 's/^lib//;s/\.dll$//'`.a"
+
+ # If the library has no export list, then create one now
+ if test -f "$output_objdir/$soname-def"; then :
+ else
+ $show "extracting exported symbol list from \`$soname'"
+ save_ifs="$IFS"; IFS='~'
+ eval cmds=\"$extract_expsyms_cmds\"
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Create $newlib
+ if test -f "$output_objdir/$newlib"; then :; else
+ $show "generating import library for \`$soname'"
+ save_ifs="$IFS"; IFS='~'
+ eval cmds=\"$old_archive_from_expsyms_cmds\"
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+ # make sure the library variables are pointing to the new library
+ dir=$output_objdir
+ linklib=$newlib
+ fi # test -n "$old_archive_from_expsyms_cmds"
+
+ if test "$linkmode" = prog || test "$mode" != relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ lib_linked=yes
+ case $hardcode_action in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = no; then
+ case $host in
+ *-*-sunos*) add_shlibpath="$dir" ;;
+ esac
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ relink)
+ if test "$hardcode_direct" = yes; then
+ add="$dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$dir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ add_shlibpath="$dir"
+ add="-l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+ *) lib_linked=no ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ $echo "$modename: configuration error: unsupported hardcode properties"
+ exit 1
+ fi
+
+ if test -n "$add_shlibpath"; then
+ case :$compile_shlibpath: in
+ *":$add_shlibpath:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+ esac
+ fi
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+ test -n "$add" && compile_deplibs="$add $compile_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ if test "$hardcode_direct" != yes && \
+ test "$hardcode_minus_L" != yes && \
+ test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ fi
+ fi
+ fi
+
+ if test "$linkmode" = prog || test "$mode" = relink; then
+ add_shlibpath=
+ add_dir=
+ add=
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes; then
+ add="$libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ add_dir="-L$libdir"
+ add="-l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case :$finalize_shlibpath: in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+ esac
+ add="-l$name"
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ add_dir="-L$libdir"
+ add="-l$name"
+ fi
+
+ if test "$linkmode" = prog; then
+ test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+ test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+ else
+ test -n "$add_dir" && deplibs="$add_dir $deplibs"
+ test -n "$add" && deplibs="$add $deplibs"
+ fi
+ fi
+ elif test "$linkmode" = prog; then
+ if test "$alldeplibs" = yes &&
+ { test "$deplibs_check_method" = pass_all ||
+ { test "$build_libtool_libs" = yes &&
+ test -n "$library_names"; }; }; then
+ # We only need to search for static libraries
+ continue
+ fi
+
+ # Try to link the static library
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_deplibs="$dir/$linklib $compile_deplibs"
+ finalize_deplibs="$dir/$linklib $finalize_deplibs"
+ else
+ compile_deplibs="-l$name -L$dir $compile_deplibs"
+ finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+ fi
+ elif test "$build_libtool_libs" = yes; then
+ # Not a shared library
+ if test "$deplibs_check_method" != pass_all; then
+ # We're trying link a shared library against a static one
+ # but the system doesn't support it.
+
+ # Just print a warning and add the library to dependency_libs so
+ # that the program can be linked against the static library.
+ echo
+ echo "*** Warning: This library needs some functionality provided by $lib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ if test "$module" = yes; then
+ echo "*** Therefore, libtool will create a static module, that should work "
+ echo "*** as long as the dlopening application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not tqfind such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ else
+ convenience="$convenience $dir/$old_library"
+ old_convenience="$old_convenience $dir/$old_library"
+ deplibs="$dir/$old_library $deplibs"
+ link_static=yes
+ fi
+ fi # link shared/static library?
+
+ if test "$linkmode" = lib; then
+ if test -n "$dependency_libs" &&
+ { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes ||
+ test "$link_static" = yes; }; then
+ # Extract -R from dependency_libs
+ temp_deplibs=
+ for libdir in $dependency_libs; do
+ case $libdir in
+ -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'`
+ case " $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ *) temp_deplibs="$temp_deplibs $libdir";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ newlib_search_path="$newlib_search_path $absdir"
+ # Link against this library
+ test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+ # ... and its dependency_libs
+ tmp_libs=
+ for deplib in $dependency_libs; do
+ newdependency_libs="$deplib $newdependency_libs"
+ case "$tmp_libs " in
+ *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+ esac
+ tmp_libs="$tmp_libs $deplib"
+ done
+
+ if test "$link_all_deplibs" != no; then
+ # Add the search paths of all dependency libraries
+ for deplib in $dependency_libs; do
+ case $deplib in
+ -L*) path="$deplib" ;;
+ *.la)
+ dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$deplib" && dir="."
+ # We need an absolute path.
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ absdir="$dir"
+ fi
+ ;;
+ esac
+ if grep "^installed=no" $deplib > /dev/null; then
+ path="-L$absdir/$objdir"
+ else
+ eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ if test "$absdir" != "$libdir"; then
+ $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2
+ fi
+ path="-L$absdir"
+ fi
+ ;;
+ *) continue ;;
+ esac
+ case " $deplibs " in
+ *" $path "*) ;;
+ *) deplibs="$deplibs $path" ;;
+ esac
+ done
+ fi # link_all_deplibs != no
+ fi # linkmode = lib
+ done # for deplib in $libs
+ if test "$pass" = dlpreopen; then
+ # Link the dlpreopened libraries before other libraries
+ for deplib in $save_deplibs; do
+ deplibs="$deplib $deplibs"
+ done
+ fi
+ if test "$pass" != dlopen; then
+ test "$pass" != scan && dependency_libs="$newdependency_libs"
+ if test "$pass" != conv; then
+ # Make sure lib_search_path tqcontains only unique directories.
+ lib_search_path=
+ for dir in $newlib_search_path; do
+ case "$lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir" ;;
+ esac
+ done
+ newlib_search_path=
+ fi
+
+ if test "$linkmode,$pass" != "prog,link"; then
+ vars="deplibs"
+ else
+ vars="compile_deplibs finalize_deplibs"
+ fi
+ for var in $vars dependency_libs; do
+ # Add libraries to $var in reverse order
+ eval tmp_libs=\"\$$var\"
+ new_libs=
+ for deplib in $tmp_libs; do
+ case $deplib in
+ -L*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $specialdeplibs " in
+ *" $deplib "*) new_libs="$deplib $new_libs" ;;
+ *)
+ case " $new_libs " in
+ *" $deplib "*) ;;
+ *) new_libs="$deplib $new_libs" ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+ tmp_libs=
+ for deplib in $new_libs; do
+ case $deplib in
+ -L*)
+ case " $tmp_libs " in
+ *" $deplib "*) ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ ;;
+ *) tmp_libs="$tmp_libs $deplib" ;;
+ esac
+ done
+ eval $var=\"$tmp_libs\"
+ done # for var
+ fi
+ if test "$pass" = "conv" &&
+ { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then
+ libs="$deplibs" # reset libs
+ deplibs=
+ fi
+ done # for pass
+ if test "$linkmode" = prog; then
+ dlfiles="$newdlfiles"
+ dlprefiles="$newdlprefiles"
+ fi
+
+ case $linkmode in
+ oldlib)
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+ fi
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ objs="$objs$old_deplibs"
+ ;;
+
+ lib)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case $outputname in
+ lib*)
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ if test "$module" = no; then
+ $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ eval libname=\"$libname_spec\"
+ else
+ libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ fi
+ ;;
+ esac
+
+ if test -n "$objs"; then
+ if test "$deplibs_check_method" != pass_all; then
+ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1
+ exit 1
+ else
+ echo
+ echo "*** Warning: Linking the shared library $output against the non-libtool"
+ echo "*** objects $objs is not portable!"
+ libobjs="$libobjs $objs"
+ fi
+ fi
+
+ if test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2
+ fi
+
+ set dummy $rpath
+ if test "$#" -gt 2; then
+ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+ fi
+ install_libdir="$2"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ libext=al
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+ fi
+ else
+
+ # Parse the version information argument.
+ save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ IFS="$save_ifs"
+
+ if test -n "$8"; then
+ $echo "$modename: too many parameters to \`-version-info'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ current="$2"
+ revision="$3"
+ age="$4"
+
+ # Check that each of the things are valid numbers.
+ case $current in
+ [0-9]*) ;;
+ *)
+ $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case $revision in
+ [0-9]*) ;;
+ *)
+ $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case $age in
+ [0-9]*) ;;
+ *)
+ $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test "$age" -gt "$current"; then
+ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case $version_type in
+ none) ;;
+
+ darwin)
+ # Like Linux, but with the current version available in
+ # verstring for coding it into the library header
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ # Darwin ld doesn't like 0 for these options...
+ minor_current=`expr $current + 1`
+ verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current";
+ ;;
+
+ irix)
+ major=`expr $current - $age + 1`
+ verstring="sgi$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test "$loop" -ne 0; do
+ iface=`expr $revision - $loop`
+ loop=`expr $loop - 1`
+ verstring="sgi$major.$iface:$verstring"
+ done
+
+ # Before this point, $major must not contain `.'.
+ major=.$major
+ versuffix="$major.$revision"
+ ;;
+
+ linux)
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ major=`expr $current - $age`
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test "$loop" -ne 0; do
+ iface=`expr $current - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ windows)
+ # Use '-' rather than '.', since we only want one
+ # extension on DOS 8.3 filesystems.
+ major=`expr $current - $age`
+ versuffix="-$major"
+ ;;
+
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ verstring="0.0"
+ case $version_type in
+ darwin)
+ # we can't check for "0.0" in archive_cmds due to quoting
+ # problems, so we reset it completely
+ verstring=""
+ ;;
+ *)
+ verstring="0.0"
+ ;;
+ esac
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+ fi
+
+ if test "$mode" != relink; then
+ # Remove our outputs.
+ $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+ $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ # Eliminate all temporary directories.
+ for path in $notinst_path; do
+ lib_search_path=`echo "$lib_search_path " | sed -e 's% $path % %g'`
+ deplibs=`echo "$deplibs " | sed -e 's% -L$path % %g'`
+ dependency_libs=`echo "$dependency_libs " | sed -e 's% -L$path % %g'`
+ done
+
+ if test -n "$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+ fi
+
+ # Make sure dlfiles tqcontains only unique files that won't be dlpreopened
+ old_dlfiles="$dlfiles"
+ dlfiles=
+ for lib in $old_dlfiles; do
+ case " $dlprefiles $dlfiles " in
+ *" $lib "*) ;;
+ *) dlfiles="$dlfiles $lib" ;;
+ esac
+ done
+
+ # Make sure dlprefiles tqcontains only unique files
+ old_dlprefiles="$dlprefiles"
+ dlprefiles=
+ for lib in $old_dlprefiles; do
+ case "$dlprefiles " in
+ *" $lib "*) ;;
+ *) dlprefiles="$dlprefiles $lib" ;;
+ esac
+ done
+
+ if test "$build_libtool_libs" = yes; then
+ if test -n "$rpath"; then
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # Rhapsody C library is in the System framework
+ deplibs="$deplibs -framework System"
+ ;;
+ *-*-netbsd*)
+ # Don't link with libc until the a.out ld.so is fixed.
+ ;;
+ *-*-openbsd*)
+ # Do not include libc due to us having libc/libc_r.
+ ;;
+ *)
+ # Add libc to deplibs on all other systems if necessary.
+ if test "$build_libtool_need_lc" = "yes"; then
+ deplibs="$deplibs -lc"
+ fi
+ ;;
+ esac
+ fi
+
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case $deplibs_check_method in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behaviour.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $rm conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $rm conftest
+ $CC -o conftest conftest.c $deplibs
+ if test "$?" -eq 0 ; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test -n "$name" && test "$name" != "0"; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ else
+ # Error occured in the first compile. Let's try to salvage the situation:
+ # Compile a seperate program for each library.
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test -n "$name" && test "$name" != "0"; then
+ $rm conftest
+ $CC -o conftest conftest.c $i
+ # Did it work?
+ if test "$?" -eq 0 ; then
+ ldd_output=`ldd conftest`
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method
+ file_magic_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test -n "$name" && test "$name" != "0"; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null \
+ | grep " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+ case $potliblink in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+ | sed 10q \
+ | egrep "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ match_pattern*)
+ set dummy $deplibs_check_method
+ match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"`
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test -n "$name" && test "$name" != "0"; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ if eval echo \"$potent_lib\" 2>/dev/null \
+ | sed 10q \
+ | egrep "$match_pattern_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+ -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' |
+ grep . >/dev/null; then
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody tqreplace the C library is the System framework
+ newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'`
+ ;;
+ esac
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ echo "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not tqfind such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+
+ if test "$allow_undefined" = no; then
+ echo
+ echo "*** Since this library must not contain undefined symbols,"
+ echo "*** because either the platform does not support them or"
+ echo "*** it was explicitly requested with -no-undefined,"
+ echo "*** libtool will only create a static version of it."
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ fi
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ if test "$hardcode_into_libs" = yes; then
+ # Hardcode the library paths
+ hardcode_libdirs=
+ dep_rpath=
+ rpath="$finalize_rpath"
+ test "$mode" != relink && rpath="$compile_rpath$rpath"
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ dep_rpath="$dep_rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+ fi
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+ fi
+ test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+ fi
+
+ shlibpath="$finalize_shlibpath"
+ test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+ if test -n "$shlibpath"; then
+ eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+ fi
+
+ # Get the real and link names of the library.
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+ test -z "$dlname" && dlname=$soname
+
+ lib="$output_objdir/$realname"
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Ensure that we have .o objects for linkers which dislike .lo
+ # (e.g. aix) in case we are running --disable-static
+ for obj in $libobjs; do
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+ oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+ if test ! -f $xdir/$oldobj; then
+ $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
+ $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
+ fi
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ $show "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $run $rm $export_symbols
+ eval cmds=\"$export_symbols_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex"; then
+ $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+ $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+ $run eval '$mv "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+ fi
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case $xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ libobjs="$libobjs "`tqfind $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linker_flags="$linker_flags $flag"
+ fi
+
+ # Make a backup of the uninstalled library when relinking
+ if test "$mode" = relink; then
+ $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $?
+ fi
+
+ # Do each of the archive commands.
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval cmds=\"$archive_expsym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Restore the uninstalled library and exit
+ if test "$mode" = relink; then
+ $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $?
+ exit 0
+ fi
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ obj)
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+ fi
+
+ case $output in
+ *.lo)
+ if test -n "$objs$old_deplibs"; then
+ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+ exit 1
+ fi
+ libobj="$output"
+ obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $run $rm $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${obj}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case $xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ reload_conv_objs="$reload_objs "`tqfind $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+ output="$obj"
+ eval cmds=\"$reload_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > $libobj" || exit $?
+ exit 0
+ fi
+
+ if test -n "$pic_flag" || test "$pic_mode" != default; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ eval cmds=\"$reload_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ else
+ # Just create a symlink.
+ $show $rm $libobj
+ $run $rm $libobj
+ xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$libobj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+ oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+ $show "(cd $xdir && $LN_S $oldobj $baseobj)"
+ $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
+ fi
+
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ ;;
+
+ prog)
+ case $host in
+ *cygwin*) output=`echo $output | sed -e 's,.exe$,,;s,$,.exe,'` ;;
+ esac
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+ fi
+
+ if test "$preload" = yes; then
+ if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown &&
+ test "$dlopen_self_static" = unknown; then
+ $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+ fi
+ fi
+
+ case $host in
+ *-*-rhapsody* | *-*-darwin1.[012])
+ # On Rhapsody tqreplace the C library is the System framework
+ compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+ finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'`
+ ;;
+ esac
+
+ compile_command="$compile_command $compile_deplibs"
+ finalize_command="$finalize_command $finalize_deplibs"
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ case $host in
+ *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*)
+ case :$dllsearchpath: in
+ *":$libdir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$libdir";;
+ esac
+ ;;
+ esac
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ dlsyms=
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ dlsyms="${outputname}S.c"
+ else
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+ fi
+ fi
+
+ if test -n "$dlsyms"; then
+ case $dlsyms in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${outputname}.nm"
+
+ $show "$rm $nlist ${nlist}S ${nlist}T"
+ $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+ # Parse the name list into a source file.
+ $show "creating $output_objdir/$dlsyms"
+
+ test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ $show "generating symbol list for \`$output'"
+
+ test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for arg in $progfiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$output.exp"
+ $run $rm $export_symbols
+ $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ else
+ $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+ $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+ $run eval 'mv "$nlist"T "$nlist"'
+ fi
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ name=`echo "$arg" | sed -e 's%^.*/%%'`
+ $run eval 'echo ": $name " >> "$nlist"'
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -z "$run"; then
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $mv "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+ :
+ else
+ grep -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr void *
+#else
+# define lt_ptr char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+ eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms"
+
+ $echo >> "$output_objdir/$dlsyms" "\
+ {0, (lt_ptr) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ fi
+
+ pic_flag_for_symtable=
+ case $host in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+ esac;;
+ *-*-hpux*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC";;
+ esac
+ esac
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+ $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+ # Clean up the generated files.
+ $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+ $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+ # Transform the symbol file into the correct name.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ ;;
+ *)
+ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+ exit 1
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ $show "$link_command"
+ $run eval "$link_command"
+ status=$?
+
+ # Delete the generated files.
+ if test -n "$dlsyms"; then
+ $show "$rm $output_objdir/${outputname}S.${objext}"
+ $run $rm "$output_objdir/${outputname}S.${objext}"
+ fi
+
+ exit $status
+ fi
+
+ if test -n "$shlibpath_var"; then
+ # We should set the shlibpath_var
+ rpath=
+ for dir in $temp_rpath; do
+ case $dir in
+ [\\/]* | [A-Za-z]:[\\/]*)
+ # Absolute path.
+ rpath="$rpath$dir:"
+ ;;
+ *)
+ # Relative path: add a thisdir entry.
+ rpath="$rpath\$thisdir/$dir:"
+ ;;
+ esac
+ done
+ temp_rpath="$rpath"
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$no_install" = yes; then
+ # We don't need to create a wrapper script.
+ link_command="$compile_var$compile_command$compile_rpath"
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ # Delete the old output file.
+ $run $rm $output
+ # Link the executable and exit
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+ exit 0
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+ $echo "$modename: \`$output' will be relinked during installation" 1>&2
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+
+ # Now create the wrapper script.
+ $show "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+ relink_command="$var=\"$var_value\"; export $var; $relink_command"
+ fi
+ done
+ relink_command="(cd `pwd`; $relink_command)"
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $echo for shipping.
+ if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+ case $0 in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+ esac
+ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if our run command is non-null.
+ if test -z "$run"; then
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+ esac
+ # test for cygwin because mv fails w/o .exe extensions
+ case $host in
+ *cygwin*) exeext=.exe ;;
+ *) exeext= ;;
+ esac
+ $rm $output
+ trap "$rm $output; exit 1" 1 2 15
+
+ $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variable:
+ notinst_deplibs='$notinst_deplibs'
+else
+ # When we are sourced in execute mode, \$file and \$echo are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ echo=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$echo works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$echo will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $echo >> $output "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+ done
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ echo >> $output "\
+ program=lt-'$outputname'$exeext
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" || \\
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $mkdir \"\$progdir\"
+ else
+ $rm \"\$progdir/\$file\"
+ fi"
+
+ echo >> $output "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+ else
+ $echo \"\$relink_command_output\" >&2
+ $rm \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $rm \"\$progdir/\$program\";
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $rm \"\$progdir/\$file\"
+ fi"
+ else
+ echo >> $output "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ echo >> $output "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $echo >> $output "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $echo >> $output "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $echo >> $output "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ # win32 systems need to use the prog path for dll
+ # lookup to work
+ *-*-cygwin* | *-*-pw32*)
+ $echo >> $output "\
+ exec \$progdir/\$program \${1+\"\$@\"}
+"
+ ;;
+
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2*)
+ $echo >> $output "\
+ exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $echo >> $output "\
+ # Export the path to the program.
+ PATH=\"\$progdir:\$PATH\"
+ export PATH
+
+ exec \$program \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $echo >> $output "\
+ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"This script is just a wrapper for \$program.\" 1>&2
+ echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+ chmod +x $output
+ fi
+ exit 0
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ # Add in members from convenience archives.
+ for xlib in $addlibs; do
+ # Extract the objects.
+ case $xlib in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test "$status" -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ oldobjs="$oldobjs "`tqfind $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ eval cmds=\"$old_archive_from_new_cmds\"
+ else
+ # Ensure that we have .o objects in place in case we decided
+ # not to build a shared library, and have fallen back to building
+ # static libs even though --disable-static was passed!
+ for oldobj in $oldobjs; do
+ if test ! -f $oldobj; then
+ xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$oldobj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
+ obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+ $show "(cd $xdir && ${LN_S} $obj $baseobj)"
+ $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
+ fi
+ done
+
+ eval cmds=\"$old_archive_cmds\"
+ fi
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$generated"; then
+ $show "${rm}r$generated"
+ $run ${rm}r$generated
+ fi
+
+ # Now create the libtool archive.
+ case $output in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ $show "creating $output"
+
+ # Preserve any variables that may affect compiler behavior
+ for var in $variables_saved_for_relink; do
+ if eval test -z \"\${$var+set}\"; then
+ relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command"
+ elif eval var_value=\$$var; test -z "$var_value"; then
+ relink_command="$var=; export $var; $relink_command"
+ else
+ var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"`
+ relink_command="$var=\"$var_value\"; export $var; $relink_command"
+ fi
+ done
+ # Quote the link command for shipping.
+ relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args)"
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+
+ # Only create the output if not a dry run.
+ if test -z "$run"; then
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ # Replace all uninstalled libtool libraries with the installed ones
+ newdependency_libs=
+ for deplib in $dependency_libs; do
+ case $deplib in
+ *.la)
+ name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdependency_libs="$newdependency_libs $libdir/$name"
+ ;;
+ *) newdependency_libs="$newdependency_libs $deplib" ;;
+ esac
+ done
+ dependency_libs="$newdependency_libs"
+ newdlfiles=
+ for lib in $dlfiles; do
+ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdlfiles="$newdlfiles $libdir/$name"
+ done
+ dlfiles="$newdlfiles"
+ newdlprefiles=
+ for lib in $dlprefiles; do
+ name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'`
+ eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+ if test -z "$libdir"; then
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+ newdlprefiles="$newdlprefiles $libdir/$name"
+ done
+ dlprefiles="$newdlprefiles"
+ fi
+ $rm $output
+ # place dlname in correct position for cygwin
+ tdlname=$dlname
+ case $host,$output,$installed,$module,$dlname in
+ *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+ esac
+ $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+ if test "$installed" = no && test "$need_relink" = yes; then
+ $echo >> $output "\
+relink_command=\"$relink_command\""
+ fi
+ done
+ fi
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+ $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $?
+ ;;
+ esac
+ exit 0
+ ;;
+
+ # libtool install mode
+ install)
+ modename="$modename: install"
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+ # Allow the use of GNU shtool's install command.
+ $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then
+ # Aesthetically quote it.
+ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$arg "
+ arg="$1"
+ shift
+ else
+ install_prog=
+ arg="$nonopt"
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog$arg"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest="$arg"
+ continue
+ fi
+
+ case $arg in
+ -d) isdir=yes ;;
+ -f) prev="-f" ;;
+ -g) prev="-g" ;;
+ -m) prev="-m" ;;
+ -o) prev="-o" ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*) ;;
+
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest="$arg"
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case $arg in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog $arg"
+ done
+
+ if test -z "$install_prog"; then
+ $echo "$modename: you must specify an install program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prev' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ $echo "$modename: no file or destination specified" 1>&2
+ else
+ $echo "$modename: you must specify a destination" 1>&2
+ fi
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Strip any trailing slash from the destination.
+ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$destdir" = "X$dest" && destdir=.
+ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files
+ if test "$#" -gt 2; then
+ $echo "$modename: \`$dest' is not a directory" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ fi
+ case $destdir in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case $file in
+ *.lo) ;;
+ *)
+ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case $file in
+ *.$libext)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ library_names=
+ old_library=
+ relink_command=
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/
+ test "X$dir" = "X$file/" && dir=
+ dir="$dir$objdir"
+
+ if test -n "$relink_command"; then
+ $echo "$modename: warning: relinking \`$file'" 1>&2
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ continue
+ fi
+ fi
+
+ # See the names of the shared library.
+ set dummy $library_names
+ if test -n "$2"; then
+ realname="$2"
+ shift
+ shift
+
+ srcname="$realname"
+ test -n "$relink_command" && srcname="$realname"T
+
+ # Install the shared library and build the symlinks.
+ $show "$install_prog $dir/$srcname $destdir/$realname"
+ $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $?
+ if test -n "$stripme" && test -n "$striplib"; then
+ $show "$striplib $destdir/$realname"
+ $run eval "$striplib $destdir/$realname" || exit $?
+ fi
+
+ if test "$#" -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ for linkname
+ do
+ if test "$linkname" != "$realname"; then
+ $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ fi
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ eval cmds=\"$postinstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Install the pseudo-library for information purposes.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ instname="$dir/$name"i
+ $show "$install_prog $instname $destdir/$name"
+ $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case $destfile in
+ *.lo)
+ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+ ;;
+ *.$objext)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ if test -n "$destfile"; then
+ $show "$install_prog $file $destfile"
+ $run eval "$install_prog $file $destfile" || exit $?
+ fi
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+ $show "$install_prog $staticobj $staticdest"
+ $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+ fi
+ exit 0
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ notinst_deplibs=
+ relink_command=
+
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Check the variables that should have been set.
+ if test -z "$notinst_deplibs"; then
+ $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+ exit 1
+ fi
+
+ finalize=yes
+ for lib in $notinst_deplibs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ # If there is no directory component, then add one.
+ case $lib in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ fi
+ libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+ finalize=no
+ fi
+ done
+
+ relink_command=
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ if test "$finalize" = yes && test -z "$run"; then
+ tmpdir="/tmp"
+ test -n "$TMPDIR" && tmpdir="$TMPDIR"
+ tmpdir=`mktemp -d $tmpdir/libtool-XXXXXX 2> /dev/null`
+ if test $? = 0 ; then :
+ else
+ tmpdir="$tmpdir/libtool-$$"
+ fi
+ if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+ else
+ $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+ continue
+ fi
+ file=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ ${rm}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ $echo "$modename: warning: cannot relink \`$file'" 1>&2
+ fi
+ else
+ # Install the binary that we compiled earlier.
+ file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ # remove .exe since cygwin /usr/bin/install will append another
+ # one anyways
+ case $install_prog,$host in
+ /usr/bin/install*,*cygwin*)
+ case $file:$destfile in
+ *.exe:*.exe)
+ # this is ok
+ ;;
+ *.exe:*)
+ destfile=$destfile.exe
+ ;;
+ *:*.exe)
+ destfile=`echo $destfile | sed -e 's,.exe$,,'`
+ ;;
+ esac
+ ;;
+ esac
+ $show "$install_prog$stripme $file $destfile"
+ $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+ test -n "$outputname" && ${rm}r "$tmpdir"
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ $show "$install_prog $file $oldlib"
+ $run eval "$install_prog \$file \$oldlib" || exit $?
+
+ if test -n "$stripme" && test -n "$striplib"; then
+ $show "$old_striplib $oldlib"
+ $run eval "$old_striplib $oldlib" || exit $?
+ fi
+
+ # Do each command in the postinstall commands.
+ eval cmds=\"$old_postinstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$future_libdirs"; then
+ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+ fi
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ test -n "$run" && current_libdirs=" -n$current_libdirs"
+ exec_cmd='$SHELL $0 --finish$current_libdirs'
+ else
+ exit 0
+ fi
+ ;;
+
+ # libtool finish mode
+ finish)
+ modename="$modename: finish"
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ eval cmds=\"$finish_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || admincmds="$admincmds
+ $cmd"
+ done
+ IFS="$save_ifs"
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $run eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ test "$show" = : && exit 0
+
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ echo " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ echo " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ echo " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+ echo "See any operating system documentation about shared libraries for"
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ echo "----------------------------------------------------------------------"
+ exit 0
+ ;;
+
+ # libtool execute mode
+ execute)
+ modename="$modename: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ $echo "$modename: you must specify a COMMAND" 1>&2
+ $echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test ! -f "$file"; then
+ $echo "$modename: \`$file' is not a file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case $file in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ $echo "$modename: cannot tqfind \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case $file in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case $file in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+ args="$args \"$file\""
+ done
+
+ if test -z "$run"; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved enviroment variables
+ if test "${save_LC_ALL+set}" = set; then
+ LC_ALL="$save_LC_ALL"; export LC_ALL
+ fi
+ if test "${save_LANG+set}" = set; then
+ LANG="$save_LANG"; export LANG
+ fi
+
+ # Now prepare to actually exec the command.
+ exec_cmd="\$cmd$args"
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+ $echo "export $shlibpath_var"
+ fi
+ $echo "$cmd$args"
+ exit 0
+ fi
+ ;;
+
+ # libtool clean and uninstall mode
+ clean | uninstall)
+ modename="$modename: $mode"
+ rm="$nonopt"
+ files=
+ rmforce=
+ exit_status=0
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ for arg
+ do
+ case $arg in
+ -f) rm="$rm $arg"; rmforce=yes ;;
+ -*) rm="$rm $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ if test -z "$rm"; then
+ $echo "$modename: you must specify an RM program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ rmdirs=
+
+ for file in $files; do
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$file"; then
+ dir=.
+ objdir="$objdir"
+ else
+ objdir="$dir/$objdir"
+ fi
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ test "$mode" = uninstall && objdir="$dir"
+
+ # Remember objdir for removal later, being careful to avoid duplicates
+ if test "$mode" = clean; then
+ case " $rmdirs " in
+ *" $objdir "*) ;;
+ *) rmdirs="$rmdirs $objdir" ;;
+ esac
+ fi
+
+ # Don't error if the file doesn't exist and rm -f was used.
+ if (test -L "$file") >/dev/null 2>&1 \
+ || (test -h "$file") >/dev/null 2>&1 \
+ || test -f "$file"; then
+ :
+ elif test -d "$file"; then
+ exit_status=1
+ continue
+ elif test "$rmforce" = yes; then
+ continue
+ fi
+
+ rmfiles="$file"
+
+ case $name in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ . $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $objdir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+ test "$mode" = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+
+ if test "$mode" = uninstall; then
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ eval cmds=\"$postuninstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ if test "$?" -ne 0 && test "$rmforce" != yes; then
+ exit_status=1
+ fi
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ eval cmds=\"$old_postuninstall_cmds\"
+ save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ if test "$?" -ne 0 && test "$rmforce" != yes; then
+ exit_status=1
+ fi
+ done
+ IFS="$save_ifs"
+ fi
+ # FIXME: should reinstall the best remaining shared library.
+ fi
+ fi
+ ;;
+
+ *.lo)
+ if test "$build_old_libs" = yes; then
+ oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+ rmfiles="$rmfiles $dir/$oldobj"
+ fi
+ ;;
+
+ *)
+ # Do a test to see if this is a libtool program.
+ if test "$mode" = clean &&
+ (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ relink_command=
+ . $dir/$file
+
+ rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+ if test "$fast_install" = yes && test -n "$relink_command"; then
+ rmfiles="$rmfiles $objdir/lt-$name"
+ fi
+ fi
+ ;;
+ esac
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles || exit_status=1
+ done
+
+ # Try to remove the ${objdir}s in the directories where we deleted files
+ for dir in $rmdirs; do
+ if test -d "$dir"; then
+ $show "rmdir $dir"
+ $run rmdir $dir >/dev/null 2>&1
+ fi
+ done
+
+ exit $exit_status
+ ;;
+
+ "")
+ $echo "$modename: you must specify a MODE" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$exec_cmd"; then
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ fi
+fi # test -z "$show_help"
+
+if test -n "$exec_cmd"; then
+ eval exec $exec_cmd
+ exit 1
+fi
+
+# We need to display help for each of the modes.
+case $mode in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+-n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --finish same as \`--mode=finish'
+ --help display this help message and exit
+ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
+ --quiet same as \`--silent'
+ --silent don't print informational messages
+ --version print version information
+
+MODE must be one of the following:
+
+ clean remove files from the build directory
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+ exit 0
+ ;;
+
+clean)
+ $echo \
+"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+compile)
+ $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -prefer-pic try to building PIC objects only
+ -prefer-non-pic try to building non-PIC objects only
+ -static always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+execute)
+ $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+finish)
+ $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that tqcontains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+install)
+ $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+link)
+ $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-fast-install disable the fast-install mode
+ -no-install link a not-installable executable
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -static do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+uninstall)
+ $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+*)
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/makefiles/Makefile.am b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/Makefile.am
new file mode 100644
index 0000000..2bdd30c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/Makefile.am
@@ -0,0 +1,27 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = 1.3 foreign no-dependencies
+
+# include the app subdirectories in the distribution
+EXTRA_DIST = makefiles doc contrib Unix
+
+
+# libmng release @VERSION@
+libmng_la_LDFLAGS = -version-info 1:0:0
+
+lib_LTLIBRARIES = libmng.la
+
+include_HEADERS = libmng.h libmng_conf.h libmng_types.h
+noinst_HEADERS = libmng_chunk_io.h libmng_chunk_prc.h libmng_chunks.h \
+ libmng_cms.h libmng_data.h libmng_display.h libmng_dither.h \
+ libmng_error.h libmng_filter.h libmng_jpeg.h libmng_memory.h \
+ libmng_object_prc.h libmng_objects.h libmng_pixels.h \
+ libmng_read.h libmng_trace.h libmng_write.h libmng_zlib.h
+
+libmng_la_SOURCES = libmng_callback_xs.c libmng_chunk_io.c \
+ libmng_chunk_prc.c libmng_chunk_xs.c libmng_cms.c \
+ libmng_display.c libmng_dither.c libmng_error.c \
+ libmng_filter.c libmng_hlapi.c libmng_jpeg.c \
+ libmng_object_prc.c libmng_pixels.c libmng_prop_xs.c \
+ libmng_read.c libmng_trace.c libmng_write.c libmng_zlib.c
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/makefiles/README b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/README
new file mode 100644
index 0000000..3661002
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/README
@@ -0,0 +1,25 @@
+For conditions of distribution and use, see copyright notice in libmng.h
+or the file LICENSE in the top-level directory of the source distribution.
+
+This directory hosts the makefiles for all currently supported platforms.
+
+If you're using a system with POSIX shell capabilities, you can use the
+'configure' script in the top-level directory, or generate it by running
+'autogen.sh' if you have the necessary tools installed.
+
+Otherwise, copy the module for your environment (or the closest thing)
+into the libmng source-directory and change it to your needs. If you
+create a new file for a platform not on the list send it to me (gerard @
+libmng.com) and I'll be happy to include it in the next release!
+
+
+Current files:
+
+makefile.bcb3 - Borland C++ Builder
+makefile.vcwin32 - Microsoft Visual C++
+makefile.unix - generic Unix
+makefile.linux - Linux ELF (builds shared library)
+makefile.mingw - builds a static library for mingw32
+
+
+Makefile.am, aclocal.m4 and configure.in - automake/autoconf source
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/makefiles/acinclude.m4 b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/acinclude.m4
new file mode 100644
index 0000000..60506df
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/acinclude.m4
@@ -0,0 +1,74 @@
+#serial 12
+
+dnl By default, many hosts won't let programs access large files;
+dnl one must use special compiler options to get large-file access to work.
+dnl For more details about this brain damage please see:
+dnl http://www.sas.com/standards/large.file/x_open.20Mar96.html
+
+dnl Written by Paul Eggert <eggert@twinsun.com>.
+
+dnl Internal subroutine of AC_SYS_LARGEFILE.
+dnl AC_SYS_LARGEFILE_TEST_INCLUDES
+AC_DEFUN(AC_SYS_LARGEFILE_TEST_INCLUDES,
+ [[#include <sys/types.h>
+ int a[(off_t) 9223372036854775807 == 9223372036854775807 ? 1 : -1];
+ ]])
+
+dnl Internal subroutine of AC_SYS_LARGEFILE.
+dnl AC_SYS_LARGEFILE_MACRO_VALUE(C-MACRO, VALUE, CACHE-VAR, COMMENT, INCLUDES, FUNCTION-BODY)
+AC_DEFUN(AC_SYS_LARGEFILE_MACRO_VALUE,
+ [AC_CACHE_CHECK([for $1 value needed for large files], $3,
+ [$3=no
+ AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES
+$5
+ ,
+ [$6],
+ ,
+ [AC_TRY_COMPILE([#define $1 $2]
+AC_SYS_LARGEFILE_TEST_INCLUDES
+$5
+ ,
+ [$6],
+ [$3=$2])])])
+ if test "[$]$3" != no; then
+ AC_DEFINE_UNQUOTED([$1], [$]$3, [$4])
+ fi])
+
+AC_DEFUN(AC_SYS_LARGEFILE,
+ [AC_ARG_ENABLE(largefile,
+ [ --disable-largefile omit support for large files])
+ if test "$enable_largefile" != no; then
+
+ AC_CACHE_CHECK([for special C compiler options needed for large files],
+ ac_cv_sys_largefile_CC,
+ [ac_cv_sys_largefile_CC=no
+ if test "$GCC" != yes; then
+ # IRIX 6.2 and later do not support large files by default,
+ # so use the C compiler's -n32 option if that helps.
+ AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, , ,
+ [ac_save_CC="$CC"
+ CC="$CC -n32"
+ AC_TRY_COMPILE(AC_SYS_LARGEFILE_TEST_INCLUDES, ,
+ ac_cv_sys_largefile_CC=' -n32')
+ CC="$ac_save_CC"])
+ fi])
+ if test "$ac_cv_sys_largefile_CC" != no; then
+ CC="$CC$ac_cv_sys_largefile_CC"
+ fi
+
+ AC_SYS_LARGEFILE_MACRO_VALUE(_FILE_OFFSET_BITS, 64,
+ ac_cv_sys_file_offset_bits,
+ [Number of bits in a file offset, on hosts where this is settable.])
+ AC_SYS_LARGEFILE_MACRO_VALUE(_LARGEFILE_SOURCE, 1,
+ ac_cv_sys_largefile_source,
+ [Define to make ftello visible on some hosts (e.g. HP-UX 10.20).],
+ [#include <stdio.h>], [return !ftello;])
+ AC_SYS_LARGEFILE_MACRO_VALUE(_LARGE_FILES, 1,
+ ac_cv_sys_large_files,
+ [Define for large files, on AIX-style hosts.])
+ AC_SYS_LARGEFILE_MACRO_VALUE(_XOPEN_SOURCE, 500,
+ ac_cv_sys_xopen_source,
+ [Define to make ftello visible on some hosts (e.g. glibc 2.1.3).],
+ [#include <stdio.h>], [return !ftello;])
+ fi
+ ])
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/makefiles/configure.in b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/configure.in
new file mode 100644
index 0000000..511b363
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/configure.in
@@ -0,0 +1,177 @@
+dnl Process this file with autoconf to produce a configure script.
+
+AC_INIT(libmng.h)
+
+dnl this call will define PACKAGE and VERSION
+dnl please use this as the primary reference for the version number
+AM_INIT_AUTOMAKE(libmng, 1.0.4)
+
+dnl pass the version string on the the makefiles
+AC_SUBST(PACKAGE)
+AC_SUBST(VERSION)
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_ISC_POSIX
+AM_C_PROTOTYPES
+if test "x$U" != "x"; then
+ AC_MSG_ERROR(Compiler not ANSI compliant)
+fi
+AM_PROG_LIBTOOL
+AC_PROG_INSTALL
+
+dnl support for files >2GB
+AC_SYS_LARGEFILE
+
+dnl Check for required header files
+AC_HEADER_STDC
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+
+dnl need pow and fabs
+AC_CHECK_FUNC(pow, , AC_CHECK_LIB(m, pow, LIBS="$LIBS -lm"))
+
+
+dnl what functionality we want to add (read, write, display).
+dnl all on by default. see libmng_conf.h for full descriptions
+
+dnl we only support the full mng spec for not (no LC or VLC)
+AC_DEFINE(MNG_SUPPORT_FULL)
+
+dnl remove support in library to read images?
+AC_ARG_ENABLE(read,
+[ --disable-read remove read support from library])
+if test "x$enable_read" != "xno"; then
+ AC_DEFINE(MNG_SUPPORT_READ)
+fi
+
+dnl remove support in library to write images?
+AC_ARG_ENABLE(write,
+[ --disable-write remove write support from library])
+if test "x$enable_write" != "xno"; then
+ AC_DEFINE(MNG_SUPPORT_WRITE)
+fi
+
+dnl remove support in library to display images?
+AC_ARG_ENABLE(display,
+[ --disable-display remove display support from library])
+if test "x$enable_display" != "xno"; then
+ AC_DEFINE(MNG_SUPPORT_DISPLAY)
+fi
+
+dnl remove support in library to access chunks?
+AC_ARG_ENABLE(chunks,
+[ --disable-chunks remove support for chunk access])
+if test "x$enable_chunks" != "xno"; then
+ AC_DEFINE(MNG_ACCESS_CHUNKS)
+fi
+
+dnl disable support for accessing chunks that have been previously read?
+AC_ARG_ENABLE(storechunks,
+[ --disable-storechunks remove support for access of previous chunks],[
+if test "x$enable_storechunks" != "xno"; then
+ AC_DEFINE(MNG_STORE_CHUNKS)
+fi
+])
+
+dnl enable support for debug tracing callbacks and messages?
+AC_ARG_ENABLE(trace,
+[ --enable-trace include support for debug tracing callbacks],[
+if test "x$enable_trace" = "xyes"; then
+ AC_DEFINE(MNG_SUPPORT_TRACE)
+ AC_DEFINE(MNG_TRACE_TELLTALE)
+fi
+])
+
+dnl verbose error text
+dnl this should always be on
+AC_DEFINE(MNG_ERROR_TELLTALE)
+
+
+dnl libz is required.
+AC_ARG_WITH(zlib,
+[ --with-zlib[=DIR] use zlib include/library files in DIR],[
+ if test -d "$withval"; then
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ fi
+])
+AC_CHECK_HEADER(zlib.h,
+ AC_CHECK_LIB(z, gzread, , AC_MSG_ERROR(zlib library not found)),
+ AC_MSG_ERROR(zlib header not found)
+)
+
+dnl check for jpeg library
+AC_ARG_WITH(jpeg,
+[ --with-jpeg[=DIR] use jpeg include/library files in DIR],
+[with_jpeg=$withval],[with_jpeg=_auto])
+
+ if test "x$with_jpeg" != "xno" -a "x$with_jpeg" != "xyes" -a \
+ "x$with_jpeg" != "x_auto"; then
+ # Save in case test with directory specified fails
+ _cppflags=${CPPFLAGS}
+ _ldflags=${LDFLAGS}
+ _restore=1
+
+ CPPFLAGS="${CPPFLAGS} -I$withval/include"
+ LDFLAGS="${LDFLAGS} -L$withval/lib"
+ else
+ _restore=0
+ fi
+
+ if test "x$with_jpeg" != "xno"; then
+ AC_CHECK_HEADER(jpeglib.h,
+ AC_CHECK_LIB(jpeg, jpeg_read_header, [
+ LIBS="$LIBS -ljpeg"
+ AC_DEFINE(HAVE_LIBJPEG)
+ _restore=0
+ ],
+ AC_MSG_WARN(jpeg library not found)),
+ AC_MSG_WARN(jpeg header not found)
+ )
+ fi
+
+ test $_restore -eq 1 && CPPFLAGS=$_cppflags LDFLAGS=$_ldflags
+
+dnl check for lcms library
+AC_ARG_WITH(lcms,
+[ --with-lcms[=DIR] use lcms include/library files in DIR],
+[with_lcms=$withval],[with_lcms=_auto])
+
+ if test "x$with_lcms" != "xno" -a "x$with_lcms" != "xyes" -a \
+ "x$with_lcms" != "x_auto"; then
+ # Save in case test with directory specified fails
+ _cppflags=$CPPFLAGS
+ _ldflags=$LDFLAGS
+ _restore=1
+
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ else
+ _restore=0
+ fi
+
+ if test "x$with_lcms" != "xno"; then
+ AC_CHECK_HEADER(lcms.h, [
+ have_lcms=yes
+ AC_CHECK_LIB(lcms, cmsCreateRGBProfile, [
+ LIBS="$LIBS -llcms"
+ AC_DEFINE(HAVE_LIBLCMS)
+ dnl for now this implies MNG_INCLUDE_LCMS in the headers:
+ AC_DEFINE(MNG_FULL_CMS)
+ _restore=0
+ have_lcms=yes
+ ],[
+ have_lcms=no
+ ])
+ ])
+ dnl give feedback only if the user asked specifically for lcms
+ if test "x$with_lcms" != "x_auto" -a "x$have_lcms" != "xyes"; then
+ AC_MSG_WARN([lcms not found... disabling CMS support])
+ fi
+ fi
+
+ test $_restore -eq 1 && CPPFLAGS=$_cppflags LDFLAGS=$_ldflags
+
+AC_OUTPUT(Makefile)
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.bcb3 b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.bcb3
new file mode 100644
index 0000000..5c4e434
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.bcb3
@@ -0,0 +1,105 @@
+#
+# For conditions of distribution and use, see copyright notice in libmng.h
+#
+# makefile for libmng - THE MNG library
+# this makefile is suitable for Borland C++ Builder.
+# it works (at least) with Borland C++ Builder v3
+
+# Configuration options are now in mng_conf.h
+# this option forces dll compatibility
+MNGOPT = -DMNG_BUILD_DLL
+
+# The name of your C compiler:
+CC= bcc32
+
+# compiler options:
+CFLAGS= -WD -O2 -Hc -w-par -k -y -v -vi -c -tWD \
+ -wuse -wucp -wstv -wstu -wsig -wpin -wnod -wnak -wdef -wcln -wbbf -wasm -wamp \
+ -wamb -Tkh30000 -ff -5 -I.;..\zlib;..\jpgsrc6b;..\lcms\include $(MNGOPT)
+
+# source files
+SOURCES= libmng_hlapi.c libmng_callback_xs.c libmng_prop_xs.c libmng_chunk_xs.c \
+ libmng_read.c libmng_write.c libmng_display.c \
+ libmng_object_prc.c libmng_chunk_prc.c libmng_chunk_io.c libmng_error.c \
+ libmng_trace.c libmng_pixels.c libmng_filter.c libmng_dither.c \
+ libmng_zlib.c libmng_jpeg.c libmng_cms.c
+
+# object files
+OBJECTS= libmng_hlapi.obj libmng_callback_xs.obj libmng_prop_xs.obj libmng_chunk_xs.obj \
+ libmng_read.obj libmng_write.obj libmng_display.obj \
+ libmng_object_prc.obj libmng_chunk_prc.obj libmng_chunk_io.obj libmng_error.obj \
+ libmng_trace.obj libmng_pixels.obj libmng_filter.obj libmng_dither.obj \
+ libmng_zlib.obj libmng_jpeg.obj libmng_cms.obj
+
+# type dependancies
+.c.obj:
+ $(CC) $(CFLAGS) -c{ $<}
+
+# make options
+all: libmng.lib
+
+clean:
+ - del *.obj
+ - del libmng.lib
+
+# file dependancies
+libmng.lib: $(OBJECTS)
+ - del libmng.lib
+ tlib libmng.lib /E /C @&&|
++libmng_hlapi.obj +libmng_callback_xs.obj +libmng_prop_xs.obj +libmng_chunk_xs.obj &
++libmng_read.obj +libmng_write.obj +libmng_display.obj &
++libmng_object_prc.obj +libmng_chunk_prc.obj +libmng_chunk_io.obj +libmng_error.obj &
++libmng_trace.obj +libmng_pixels.obj +libmng_filter.obj +libmng_dither.obj &
++libmng_zlib.obj +libmng_jpeg.obj +libmng_cms.obj
+|
+
+libmng_hlapi.obj: libmng_hlapi.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_memory.h libmng_error.h libmng_trace.h libmng_read.h \
+ libmng_write.h libmng_display.h libmng_zlib.h libmng_cms.h libmng_zlib.h
+libmng_callback_xs.obj: libmng_callback_xs.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h
+libmng_prop_xs.obj: libmng_prop_xs.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_cms.h
+libmng_chunk_xs.obj: libmng_chunk_xs.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_chunks.h libmng_chunk_prc.h libmng_error.h libmng_trace.h
+libmng_read.obj: libmng_read.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_chunk_prc.h libmng_chunk_io.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_read.h libmng_display.h
+libmng_write.obj: libmng_write.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_write.h
+libmng_display.obj: libmng_display.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_zlib.h libmng_cms.h \
+ libmng_pixels.h libmng_display.h
+libmng_object_prc.obj: libmng_object_prc.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_display.h libmng_pixels.h
+libmng_chunk_prc.obj: libmng_chunk_prc.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_chunks.h libmng_chunk_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h
+libmng_chunk_io.obj: libmng_chunk_io.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h libmng_chunks.h \
+ libmng_chunk_io.h libmng_chunk_prc libmng_memory.h libmng_error.h \
+ libmng_trace.h libmng_display.h libmng_zlib.h libmng_pixels.h
+libmng_error.obj: libmng_error.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h
+libmng_trace.obj: libmng_trace.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h
+libmng_pixels.obj: libmng_pixels.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_memory.h libmng_error.h libmng_trace.h \
+ libmng_cms.h libmng_filter.h libmng_pixels.h
+libmng_filter.obj: libmng_filter.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_filter.h
+libmng_dither.obj: libmng_dither.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_dither.h
+libmng_zlib.obj: libmng_zlib.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_memory.h libmng_error.h libmng_trace.h libmng_pixels.h \
+ libmng_filter.h libmng_zlib.h
+libmng_jpeg.obj: libmng_jpeg.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_memory.h libmng_error.h libmng_trace.h \
+ libmng_pixels.h libmng_jpeg.h
+libmng_cms.obj: libmng_cms.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_error.h libmng_trace.h libmng_cms.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.dj b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.dj
new file mode 100644
index 0000000..b50c886
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.dj
@@ -0,0 +1,151 @@
+#
+# For conditions of distribution and use, see copyright notice in libmng.h
+#
+# makefile for libmng - THE MNG library
+# This makefile have been tested on DJGPP v2
+# (Based on makefile.linux since both are GNU compilers)
+#
+# By Silvio Fonseca - gissi@sti.com.br
+
+#compiler
+CC=gcc
+
+#default build options
+OPTIONS=
+
+#DJGPP directory
+prefix=C:/DJGPP
+installprefix=C:\DJGPP
+
+#ZLIB Library and includes
+ZLIBLIB=$(prefix)/lib
+#ZLIBLIB=../zlib
+ZLIBINC=$(prefix)/include
+#ZLIBINC=../zlib
+
+#Jpeg library and includes
+JPEGLIB=$(prefix)/lib
+#JPEGLIB=../jpgsrc
+JPEGINC=$(prefix)/include
+#JPEGINC=../jpgsrc
+
+#Lcms library and includes
+LCMSLIB=$(prefix)/lib
+#LCMSLIB=../lcms
+LCMSINC=$(prefix)/include
+#LCMSINC=../lcms
+
+ALIGN=
+# for i386:
+#ALIGN=-malign-loops=2 -malign-functions=2
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+
+CFLAGS=-I$(ZLIBINC) -I$(JPEGINC) -I$(LCMSINC) -Wall -O3 -funroll-loops \
+ $(OPTIONS) $(ALIGN) # $(WARNMORE) -g
+LDFLAGS=-L. -Wl,-rpath,. \
+ -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \
+ -L$(JPEGLIB) -Wl,-rpath,$(JPEGLIB) \
+ -L$(LCMSLIB) -Wl,-rpath,$(LCMSLIB) \
+ -lmng -lz -ljpeg -llcms -lm
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+OBJS = \
+ libmng_callback_xs.o \
+ libmng_chunk_io.o \
+ libmng_chunk_prc.o \
+ libmng_chunk_xs.o \
+ libmng_cms.o \
+ libmng_display.o \
+ libmng_dither.o \
+ libmng_error.o \
+ libmng_filter.o \
+ libmng_hlapi.o \
+ libmng_jpeg.o \
+ libmng_object_prc.o \
+ libmng_pixels.o \
+ libmng_prop_xs.o \
+ libmng_read.o \
+ libmng_trace.o \
+ libmng_write.o \
+ libmng_zlib.o
+
+OBJSDLL = $(OBJS:.0=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c
+
+all: libmng.a
+
+libmng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ ranlib $@
+
+install: libmng.a
+ -@md $(installprefix)\include $(installprefix)\lib
+ copy libmng.h $(installprefix)\include
+ copy libmng_conf.h $(installprefix)\include
+ copy libmng_types.h $(installprefix)\include
+ copy libmng.a $(installprefix)\lib
+
+clean:
+ del *.o
+ del libmng.a
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+libmng_hlapi.o libmng_hlapi.pic.o: libmng_hlapi.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_memory.h libmng_error.h libmng_trace.h libmng_read.h \
+ libmng_write.h libmng_display.h libmng_zlib.h libmng_cms.h libmng_zlib.h
+libmng_callback_xs.o libmng_callback_xs.pic.o: libmng_callback_xs.c libmng.h \
+ libmng_conf.h libmng_types.h libmng_data.h libmng_error.h libmng_trace.h
+libmng_prop_xs.o libmng_prop_xs.pic.o: libmng_prop_xs.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_error.h libmng_trace.h libmng_cms.h
+libmng_chunk_xs.o libmng_chunk_xs.pic.o: libmng_chunk_xs.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_chunks.h libmng_chunk_prc.h \
+ libmng_error.h libmng_trace.h
+libmng_read.o libmng_read.pic.o: libmng_read.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_chunk_prc.h libmng_chunk_io.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_read.h libmng_display.h
+libmng_write.o libmng_write.pic.o: libmng_write.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_write.h
+libmng_display.o libmng_display.pic.o: libmng_display.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_objects.h libmng_object_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_zlib.h libmng_cms.h libmng_pixels.h \
+ libmng_display.h
+libmng_object_prc.o libmng_object_prc.pic.o: libmng_object_prc.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_objects.h libmng_object_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_display.h libmng_pixels.h
+libmng_chunk_prc.o libmng_chunk_prc.pic.o: libmng_chunk_prc.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_chunks.h libmng_chunk_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h
+libmng_chunk_io.o libmng_chunk_io.pic.o: libmng_chunk_io.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_chunk_io.h libmng_chunk_prc.h libmng_memory.h libmng_error.h \
+ libmng_trace.h libmng_display.h libmng_zlib.h libmng_pixels.h
+libmng_error.o libmng_error.pic.o: libmng_error.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h
+libmng_trace.o libmng_trace.pic.o: libmng_trace.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h
+libmng_pixels.o libmng_pixels.pic.o: libmng_pixels.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_memory.h libmng_error.h libmng_trace.h \
+ libmng_cms.h libmng_filter.h libmng_pixels.h
+libmng_filter.o libmng_filter.pic.o: libmng_filter.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_filter.h
+libmng_dither.o libmng_dither.pic.o: libmng_dither.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_dither.h
+libmng_zlib.o libmng_zlib.pic.o: libmng_zlib.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_memory.h libmng_error.h libmng_trace.h libmng_pixels.h \
+ libmng_filter.h libmng_zlib.h
+libmng_jpeg.o libmng_jpeg.pic.o: libmng_jpeg.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_memory.h libmng_error.h libmng_trace.h libmng_pixels.h libmng_jpeg.h
+libmng_cms.o libmng_cms.pic.o: libmng_cms.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_error.h libmng_trace.h libmng_cms.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.linux b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.linux
new file mode 100644
index 0000000..ddaeb39
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.linux
@@ -0,0 +1,176 @@
+#
+# For conditions of distribution and use, see copyright notice in libmng.h
+#
+# makefile for libmng - THE MNG library
+# this makefile is suitable for Linux ELF with gcc
+#
+# (this file is heavily copied from makefile.linux in the libpng package)
+
+# compiler
+CC=gcc
+
+# default build options (this forces shared library compatibility!!)
+#OPTIONS = -DMNG_BUILD_SO
+OPTIONS = -DMNG_BUILD_SO -DMNG_FULL_CMS
+
+# where "make install" puts libmng.a,libmng.so*,libmng.h,libmng_conf.h,libmng_types.h
+prefix=/usr/local
+
+# Where the zlib library and include files are located
+#ZLIBLIB=../zlib
+#ZLIBINC=../zlib
+ZLIBLIB=/usr/local/lib
+ZLIBINC=/usr/local/include
+
+# Where the jpeg library and include files are located
+#JPEGLIB=../jpgsrc
+#JPEGINC=../jpgsrc
+JPEGLIB=/usr/local/lib
+JPEGINC=/usr/local/include
+
+# Where the lcms library and include files are located
+#LCMSLIB=../lcms/lib
+#LCMSINC=../lcms/source
+LCMSLIB=/usr/local/lib
+LCMSINC=/usr/local/include
+
+ALIGN=
+# for i386:
+#ALIGN=-malign-loops=2 -malign-functions=2
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+
+# for pgcc version 2.95.1, -O3 is buggy; don't use it.
+
+CFLAGS=-I$(ZLIBINC) -I$(JPEGINC) -I$(LCMSINC) -Wall -O3 -funroll-loops \
+ $(OPTIONS) $(ALIGN) # $(WARNMORE) -g
+LDFLAGS=-L. -Wl,-rpath,. \
+ -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \
+ -L$(JPEGLIB) -Wl,-rpath,$(JPEGLIB) \
+ -L$(LCMSLIB) -Wl,-rpath,$(LCMSLIB) \
+ -lmng -lz -ljpeg -llcms -lm
+
+RANLIB=ranlib
+#RANLIB=echo
+
+# current version numbers
+MNGMAJ = 1
+MNGMIN = 1.0.4
+MNGVER = $(MNGMAJ).$(MNGMIN)
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+OBJS = \
+ libmng_callback_xs.o \
+ libmng_chunk_io.o \
+ libmng_chunk_prc.o \
+ libmng_chunk_xs.o \
+ libmng_cms.o \
+ libmng_display.o \
+ libmng_dither.o \
+ libmng_error.o \
+ libmng_filter.o \
+ libmng_hlapi.o \
+ libmng_jpeg.o \
+ libmng_object_prc.o \
+ libmng_pixels.o \
+ libmng_prop_xs.o \
+ libmng_read.o \
+ libmng_trace.o \
+ libmng_write.o \
+ libmng_zlib.o
+
+OBJSDLL = $(OBJS:.0=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c
+
+all: libmng.a libmng.so
+
+libmng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libmng.so: libmng.so.$(MNGMAJ)
+ ln -sf libmng.so.$(MNGMAJ) libmng.so
+
+libmng.so.$(MNGMAJ): libmng.so.$(MNGVER)
+ ln -sf libmng.so.$(MNGVER) libmng.so.$(MNGMAJ)
+
+libmng.so.$(MNGVER): $(OBJSDLL)
+# $(CC) -shared -Wl,-soname,libmng.so.$(MNGMAJ) -o libmng.so.$(MNGVER) \
+# $(OBJSDLL) -L$(ZLIBLIB) -L$(JPEGLIB) -L$(LCMSLIB) -lz -lm -lc
+ $(CC) -shared -Wl,-soname,libmng.so.$(MNGMAJ) -o libmng.so.$(MNGVER) \
+ $(OBJSDLL) -L$(ZLIBLIB) -L$(JPEGLIB) -ljpeg -L$(LCMSLIB) -llcms \
+ -lz -lm -lc
+
+install: libmng.a libmng.so.$(MNGVER)
+ -@mkdir $(INCPATH) $(LIBPATH)
+ cp libmng.h libmng_conf.h libmng_types.h $(INCPATH)
+ chmod 644 $(INCPATH)/libmng.h $(INCPATH)/libmng_conf.h $(INCPATH)/libmng_types.h
+ cp libmng.a libmng.so.$(MNGVER) $(LIBPATH)
+ chmod 755 $(LIBPATH)/libmng.so.$(MNGVER)
+ -@/bin/rm -f $(LIBPATH)/libmng.so.$(MNGMAJ) $(LIBPATH)/libmng.so
+ (cd $(LIBPATH); ln -sf libmng.so.$(MNGVER) libmng.so.$(MNGMAJ); \
+ ln -sf libmng.so.$(MNGMAJ) libmng.so)
+
+clean:
+ /bin/rm -f *.o libmng.a libmng.so*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+libmng_hlapi.o libmng_hlapi.pic.o: libmng_hlapi.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_memory.h libmng_error.h libmng_trace.h libmng_read.h \
+ libmng_write.h libmng_display.h libmng_zlib.h libmng_cms.h libmng_zlib.h
+libmng_callback_xs.o libmng_callback_xs.pic.o: libmng_callback_xs.c libmng.h \
+ libmng_conf.h libmng_types.h libmng_data.h libmng_error.h libmng_trace.h
+libmng_prop_xs.o libmng_prop_xs.pic.o: libmng_prop_xs.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_error.h libmng_trace.h libmng_cms.h
+libmng_chunk_xs.o libmng_chunk_xs.pic.o: libmng_chunk_xs.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_chunks.h libmng_chunk_prc.h \
+ libmng_error.h libmng_trace.h
+libmng_read.o libmng_read.pic.o: libmng_read.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_chunk_prc.h libmng_chunk_io.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_read.h libmng_display.h
+libmng_write.o libmng_write.pic.o: libmng_write.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_write.h
+libmng_display.o libmng_display.pic.o: libmng_display.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_objects.h libmng_object_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_zlib.h libmng_cms.h libmng_pixels.h \
+ libmng_display.h
+libmng_object_prc.o libmng_object_prc.pic.o: libmng_object_prc.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_objects.h libmng_object_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_display.h libmng_pixels.h
+libmng_chunk_prc.o libmng_chunk_prc.pic.o: libmng_chunk_prc.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_chunks.h libmng_chunk_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h
+libmng_chunk_io.o libmng_chunk_io.pic.o: libmng_chunk_io.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_chunk_io.h libmng_chunk_prc.h libmng_memory.h libmng_error.h \
+ libmng_trace.h libmng_display.h libmng_zlib.h libmng_pixels.h
+libmng_error.o libmng_error.pic.o: libmng_error.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h
+libmng_trace.o libmng_trace.pic.o: libmng_trace.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h
+libmng_pixels.o libmng_pixels.pic.o: libmng_pixels.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_memory.h libmng_error.h libmng_trace.h \
+ libmng_cms.h libmng_filter.h libmng_pixels.h
+libmng_filter.o libmng_filter.pic.o: libmng_filter.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_filter.h
+libmng_dither.o libmng_dither.pic.o: libmng_dither.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_dither.h
+libmng_zlib.o libmng_zlib.pic.o: libmng_zlib.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_memory.h libmng_error.h libmng_trace.h libmng_pixels.h \
+ libmng_filter.h libmng_zlib.h
+libmng_jpeg.o libmng_jpeg.pic.o: libmng_jpeg.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_memory.h libmng_error.h libmng_trace.h libmng_pixels.h libmng_jpeg.h
+libmng_cms.o libmng_cms.pic.o: libmng_cms.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_error.h libmng_trace.h libmng_cms.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.mingw b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.mingw
new file mode 100644
index 0000000..dec67fd
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.mingw
@@ -0,0 +1,160 @@
+#
+# For conditions of distribution and use, see copyright notice in libmng.h
+#
+# makefile for libmng - THE MNG library
+# this makefile is for MinGW32, it have been tested with gcc 2.95.3,
+# binutils 2.11.90 and mingw-runtime 1.0
+#
+# By Benoit Blanchon - benoit.blanchon@laposte.net
+#
+# Note : this makefile builds a static library; although it's seems to be
+# possible to build working DLL and import lib, I didn't manage do to it.
+# If you do, please let me know.
+
+# outputs
+LIBMNG_A = libmng.a
+INSTALL_PREFIX = C:/MinGW/
+# maybe you sould tqreplace with anti-slashes
+
+# default build options
+OPTIONS = -DMNG_NO_CMS -DMNG_ACCESS_CHUNKS -DMNG_STORE_CHUNKS
+
+# Where the zlib library and include files are located
+ZLIBLIB=-lz
+#ZLIBLIB=-L../zlib -lz
+#ZLIBINC=-I../zlib
+
+# Where the jpeg library and include files are located
+JPEGLIB=-ljpeg
+#JPEGLIB=-L../jpgsrc -ljpeg
+#JPEGINC=-I../jpgsrc
+
+# Where the lcms library and include files are located
+#LCMSLIB=-llcms
+#LCMSLIB=-L../lcms/lib -llcms
+#LCMSINC=-I../lcms/source
+
+# file deletion command
+RM=rm -f
+#RM=del
+
+# directory creation command
+MKDIR=mkdir -p
+
+# file copy command
+COPY=cp
+#COPY=copy
+
+# compiler
+CC=gcc
+
+ALIGN=
+# for i386:
+#ALIGN=-malign-loops=2 -malign-functions=2
+
+CFLAGS=$(ZLIBINC) $(JPEGINC) $(LCMSINC) -Wall -O3 -funroll-loops $(OPTIONS) $(ALIGN)
+LDFLAGS=-L. -lmng $(ZLIBLIB) $(JPEGLIB) $(LCMSLIB) -lm
+
+# library (.a) file creation command
+AR= ar rc
+# second step in .a creation (use "touch" if not needed)
+AR2= ranlib
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+OBJS = \
+ libmng_callback_xs.o \
+ libmng_chunk_io.o \
+ libmng_chunk_prc.o \
+ libmng_chunk_xs.o \
+ libmng_cms.o \
+ libmng_display.o \
+ libmng_dither.o \
+ libmng_error.o \
+ libmng_filter.o \
+ libmng_hlapi.o \
+ libmng_jpeg.o \
+ libmng_object_prc.o \
+ libmng_pixels.o \
+ libmng_prop_xs.o \
+ libmng_read.o \
+ libmng_trace.o \
+ libmng_write.o \
+ libmng_zlib.o
+
+.SUFFIXES: .c .o
+
+.c.o:
+ $(CC) -c $(CFLAGS) -o $@ $*.c
+
+all: $(LIBMNG_A)
+
+$(LIBMNG_A) : $(OBJS)
+ $(RM) $@
+ $(AR) $@ $(OBJS)
+ $(AR2) $@
+
+install : $(LIBMNG_A)
+ $(MKDIR) $(INSTALL_PREFIX)include
+ $(COPY) libmng.h $(INSTALL_PREFIX)include
+ $(COPY) libmng_conf.h $(INSTALL_PREFIX)include
+ $(COPY) libmng_types.h $(INSTALL_PREFIX)include
+ $(MKDIR) $(INSTALL_PREFIX)lib
+ $(COPY) $(LIBMNG_A) $(INSTALL_PREFIX)lib
+
+clean:
+ $(RM) *.o
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+libmng_hlapi.o : libmng_hlapi.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_memory.h libmng_error.h libmng_trace.h libmng_read.h \
+ libmng_write.h libmng_display.h libmng_zlib.h libmng_cms.h libmng_zlib.h
+libmng_callback_xs.o : libmng_callback_xs.c libmng.h \
+ libmng_conf.h libmng_types.h libmng_data.h libmng_error.h libmng_trace.h
+libmng_prop_xs.o : libmng_prop_xs.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_error.h libmng_trace.h libmng_cms.h
+libmng_chunk_xs.o : libmng_chunk_xs.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_chunks.h libmng_chunk_prc.h \
+ libmng_error.h libmng_trace.h
+libmng_read.o : libmng_read.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_chunk_prc.h libmng_chunk_io.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_read.h libmng_display.h
+libmng_write.o : libmng_write.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_write.h
+libmng_display.o : libmng_display.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_objects.h libmng_object_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_zlib.h libmng_cms.h libmng_pixels.h \
+ libmng_display.h
+libmng_object_prc.o : libmng_object_prc.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_objects.h libmng_object_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h libmng_display.h libmng_pixels.h
+libmng_chunk_prc.o : libmng_chunk_prc.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_chunks.h libmng_chunk_prc.h libmng_memory.h \
+ libmng_error.h libmng_trace.h
+libmng_chunk_io.o : libmng_chunk_io.c libmng.h libmng_conf.h \
+ libmng_types.h libmng_data.h libmng_objects.h libmng_object_prc.h \
+ libmng_chunks.h libmng_chunk_io.h libmng_chunk_prc.h libmng_memory.h libmng_error.h \
+ libmng_trace.h libmng_display.h libmng_zlib.h libmng_pixels.h
+libmng_error.o : libmng_error.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h
+libmng_trace.o : libmng_trace.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h
+libmng_pixels.o : libmng_pixels.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_memory.h libmng_error.h libmng_trace.h \
+ libmng_cms.h libmng_filter.h libmng_pixels.h
+libmng_filter.o : libmng_filter.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_filter.h
+libmng_dither.o : libmng_dither.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_error.h libmng_trace.h libmng_dither.h
+libmng_zlib.o : libmng_zlib.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_memory.h libmng_error.h libmng_trace.h libmng_pixels.h \
+ libmng_filter.h libmng_zlib.h
+libmng_jpeg.o : libmng_jpeg.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_memory.h libmng_error.h libmng_trace.h libmng_pixels.h libmng_jpeg.h
+libmng_cms.o : libmng_cms.c libmng.h libmng_conf.h libmng_types.h \
+ libmng_data.h libmng_objects.h libmng_error.h libmng_trace.h libmng_cms.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.unix b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.unix
new file mode 100644
index 0000000..d09261f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.unix
@@ -0,0 +1,66 @@
+#
+# For conditions of distribution and use, see copyright notice in libmng.h
+#
+# makefile for libmng - THE MNG library
+# this makefile is suitable for generic unix
+
+# Configuration options are now in libmng_conf.h
+
+# The name of your C compiler:
+CC= cc
+
+# Location of jpeg header files
+JPEG_INC= /cs/include/jpeg
+
+# Location of zlib header files
+ZLIB_INC= /cs/include
+
+# Location of lcms header files
+# (switch on MNG_FULL_CMS in libmng_conf.h if you want to use this)
+LCMS_INC= /ltmp/lcms-1.06/source
+
+# compiler options:
+CFLAGS= -O -I. -I$(ZLIB_INC) -I$(JPEG_INC) -I$(LCMS_INC)
+
+# source files
+SOURCES= \
+ libmng_callback_xs.c \
+ libmng_chunk_io.c \
+ libmng_chunk_prc.c \
+ libmng_chunk_xs.c \
+ libmng_cms.c \
+ libmng_display.c \
+ libmng_dither.c \
+ libmng_error.c \
+ libmng_filter.c \
+ libmng_hlapi.c \
+ libmng_jpeg.c \
+ libmng_object_prc.c \
+ libmng_pixels.c \
+ libmng_prop_xs.c \
+ libmng_read.c \
+ libmng_trace.c \
+ libmng_write.c \
+ libmng_zlib.c
+
+# object files
+OBJECTS= $(SOURCES:%.c=%.o)
+
+# type dependancies
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+
+all: libmng.a
+
+clean:
+ /bin/rm -f $(OBJECTS)
+ /bin/rm -f libmng.a
+ /bin/rm -f *~ core
+
+libmng.a: $(OBJECTS)
+ ar r libmng.a $(OBJECTS)
+
+depend:
+ makedepend -- $(CFLAGS) $(IFLAGS) -- *.c
+
+# DO NOT DELETE
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.vcwin32 b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.vcwin32
new file mode 100644
index 0000000..51ae1cc
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/makefiles/makefile.vcwin32
@@ -0,0 +1,96 @@
+# makefile for libmng
+# Copyright (C) 2000 AM(s98t269@stmail.eng.kagawa-u.ac.jp)
+# For conditions of distribution and use, see copyright notice in libmng.h
+# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib
+# Assumes that libjpeg.lib, *.h have been copied to ..\jpgsrc6b
+# Assumes that lcmsdll.lib and lcmsstat.lib have been copied to ..\lcms\lib\msvc
+# To use, do "nmake /f makefiles\makefile.vcwin32"
+
+# -------- Microsoft Visual C++ 4.0 and later, no assembler code --------
+
+CFLAGS= -Ox -GA3s -nologo -W3 -I..\zlib -I..\jpgsrc6b -I..\lcms\include
+
+CC=cl
+LD=link
+LDFLAGS=
+O=.obj
+
+#uncomment next to put error messages in a file
+#ERRFILE= >> mngerrs
+
+# variables
+OBJS1 = libmng_callback_xs$(O) libmng_chunk_io$(O) libmng_chunk_prc$(O)
+OBJS2 = libmng_chunk_xs$(O) libmng_cms$(O) libmng_display$(O) libmng_dither$(O)
+OBJS3 = libmng_error$(O) libmng_filter$(O) libmng_hlapi$(O) libmng_jpeg$(O)
+OBJS4 = libmng_object_prc$(O) libmng_pixels$(O) libmng_prop_xs$(O)
+OBJS5 = libmng_read$(O) libmng_trace$(O) libmng_write$(O) libmng_zlib$(O)
+
+all: libmng.lib
+
+libmng_callback_xs$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_chunk_io$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_chunk_prc$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_chunk_xs$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_cms$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_display$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_dither$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_error$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_filter$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_hlapi$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_jpeg$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_object_prc$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_pixels$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_prop_xs$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_read$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_trace$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_write$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng_zlib$(O): libmng.h libmng_data.h libmng_error.h libmng_trace.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libmng.lib: $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5)
+ echo something to del > libmng.lib
+ del libmng.lib
+ lib /OUT:libmng.lib $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5)
+
+mngtest.exe: mngtest.obj libmng.lib
+ $(LD) $(LDFLAGS) mngtest.obj libmng.lib ..\zlib\zlib.lib /OUT:mngtest.exe /SUBSYSTEM:CONSOLE
+
+test: mngtest.exe
+ mngtest
+
+# End of makefile for libmng
+
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/missing b/tqtinterface/qt4/src/3rdparty/libmng/missing
new file mode 100755
index 0000000..e20b014
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/missing
@@ -0,0 +1,198 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997, 2001 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.in; then
+ configure_ac=configure.ac
+else
+ configure_ac=configure.in
+fi
+
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison create \`y.tab.[ch]', if possible, from existing .[ch]
+ flex create \`lex.yy.c', if possible, from existing .c
+ lex create \`lex.yy.c', if possible, from existing .c
+ makeinfo touch the output file
+ yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing - GNU libit 0.0"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acinclude.m4' or \`$configure_ac'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`$configure_ac'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`acconfig.h' or \`$configure_ac'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac`
+ test -z "$files" && files="config.h"
+ touch_files=
+ for f in $files; do
+ case "$f" in
+ *:*) touch_files="$touch_files "`echo "$f" |
+ sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+ *) touch_files="$touch_files $f.in";;
+ esac
+ done
+ touch $touch_files
+ ;;
+
+ automake)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ tqfind . -type f -name Makefile.am -print |
+ sed 's/\.am$/.in/' |
+ while read f; do touch "$f"; done
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.y' file. You may need the \`Bison' package
+ in order for those modifications to take effect. You can get
+ \`Bison' from any GNU archive site."
+ rm -f y.tab.c y.tab.h
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.y)
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.c
+ fi
+ SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" y.tab.h
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f y.tab.h ]; then
+ echo >y.tab.h
+ fi
+ if [ ! -f y.tab.c ]; then
+ echo 'main() { return 0; }' >y.tab.c
+ fi
+ ;;
+
+ lex|flex)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.l' file. You may need the \`Flex' package
+ in order for those modifications to take effect. You can get
+ \`Flex' from any GNU archive site."
+ rm -f lex.yy.c
+ if [ $# -ne 1 ]; then
+ eval LASTARG="\${$#}"
+ case "$LASTARG" in
+ *.l)
+ SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+ if [ -f "$SRCFILE" ]; then
+ cp "$SRCFILE" lex.yy.c
+ fi
+ ;;
+ esac
+ fi
+ if [ ! -f lex.yy.c ]; then
+ echo 'main() { return 0; }' >lex.yy.c
+ fi
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. You should only need it if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequirements for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/tqtinterface/qt4/src/3rdparty/libmng/mkinstalldirs b/tqtinterface/qt4/src/3rdparty/libmng/mkinstalldirs
new file mode 100755
index 0000000..4f58503
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libmng/mkinstalldirs
@@ -0,0 +1,40 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain
+
+# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $
+
+errstatus=0
+
+for file
+do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d
+ do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp"
+
+ mkdir "$pathcomp" || lasterr=$?
+
+ if test ! -d "$pathcomp"; then
+ errstatus=$lasterr
+ fi
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/ANNOUNCE b/tqtinterface/qt4/src/3rdparty/libpng/ANNOUNCE
new file mode 100644
index 0000000..04f46ec
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/ANNOUNCE
@@ -0,0 +1,29 @@
+
+Libpng 1.2.5 - October 3, 2002
+
+This is a public release of libpng, intended for use in production codes.
+
+Changes since the last public release (1.2.4):
+
+ Revised makefile.cygwin to use DLL number 12 instead of 13.
+ Added code to contrib/gregbook/readpng2.c to ignore unused chunks.
+ Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11)
+ Removed some stray *.o files from contrib/gregbook.
+ Changed png_error() to png_warning() about "Too much data" in pngpread.c
+ and about "Extra compressed data" in pngrutil.c.
+ Prevent png_ptr->pass from exceeding 7 in png_push_finish_row().
+ Updated makefile.hggcc
+ Updated png.c and pnggccrd.c handling of return from png_mmx_support()
+ Only issue png_warning() about "Too much data" in pngpread.c when avail_in
+ is nonzero.
+ Updated makefiles to install a separate libpng.so.3 with its own rpath.
+ Revised makefiles to not remove previous minor versions of shared libraries.
+ Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared
+ library loader directive.
+ Revised libpng-config script.
+ Relocated two misplaced PNGAPI lines in pngtest.c
+
+Send comments/corrections/commendations to
+png-implement@ccrc.wustl.edu or to randeg@alum.rpi.edu
+
+Glenn R-P
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/CHANGES b/tqtinterface/qt4/src/3rdparty/libpng/CHANGES
new file mode 100644
index 0000000..5f05e9f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/CHANGES
@@ -0,0 +1,1184 @@
+
+CHANGES - changes for libpng
+
+version 0.2
+ added reader into png.h
+ fixed small problems in stub file
+version 0.3
+ added pull reader
+ split up pngwrite.c to several files
+ added pnglib.txt
+ added example.c
+ cleaned up writer, adding a few new tranformations
+ fixed some bugs in writer
+ interfaced with zlib 0.5
+ added K&R support
+ added check for 64 KB blocks for 16 bit machines
+version 0.4
+ cleaned up code and commented code
+ simplified time handling into png_time
+ created png_color_16 and png_color_8 to handle color needs
+ cleaned up color type defines
+ fixed various bugs
+ made various names more consistant
+ interfaced with zlib 0.71
+ cleaned up zTXt reader and writer (using zlib's Reset functions)
+ split transformations into pngrtran.c and pngwtran.c
+version 0.5
+ interfaced with zlib 0.8
+ fixed many reading and writing bugs
+ saved using 3 spaces instead of tabs
+version 0.6
+ added png_large_malloc() and png_large_free()
+ added png_size_t
+ cleaned up some compiler warnings
+ added png_start_read_image()
+version 0.7
+ cleaned up lots of bugs
+ finished dithering and other stuff
+ added test program
+ changed name from pnglib to libpng
+version 0.71 [June, 1995]
+ changed pngtest.png for zlib 0.93
+ fixed error in libpng.txt and example.c
+version 0.8
+ cleaned up some bugs
+ added png_set_filler()
+ split up pngstub.c into pngmem.c, pngio.c, and pngerror.c
+ added #define's to remove unwanted code
+ moved png_info_init() to png.c
+ added old_size into png_realloc()
+ added functions to manually set filtering and compression info
+ changed compression parameters based on image type
+ optimized filter selection code
+ added version info
+ changed external functions passing floats to doubles (k&r problems?)
+ put all the configurable stuff in pngconf.h
+ enabled png_set_shift to work with paletted images on read
+ added png_read_update_info() - updates info structure with
+ transformations
+version 0.81 [August, 1995]
+ incorporated Tim Wegner's medium model code (thanks, Tim)
+version 0.82 [September, 1995]
+ [unspecified changes]
+version 0.85 [December, 1995]
+ added more medium model code (almost everything's a far)
+ added i/o, error, and memory callback functions
+ fixed some bugs (16 bit, 4 bit interlaced, etc.)
+ added first run progressive reader (barely tested)
+version 0.86 [January, 1996]
+ fixed bugs
+ improved documentation
+version 0.87 [January, 1996]
+ fixed medium model bugs
+ fixed other bugs introduced in 0.85 and 0.86
+ added some minor documentation
+version 0.88 [January, 1996]
+ fixed progressive bugs
+ tqreplaced tabs with spaces
+ cleaned up documentation
+ added callbacks for read/write and warning/error functions
+version 0.89 [July, 1996]
+ added new initialization API to make libpng work better with shared libs
+ we now have png_create_read_struct(), png_create_write_struct(),
+ png_create_info_struct(), png_destroy_read_struct(), and
+ png_destroy_write_struct() instead of the separate calls to
+ malloc and png_read_init(), png_info_init(), and png_write_init()
+ changed warning/error callback functions to fix bug - this means you
+ should use the new initialization API if you were using the old
+ png_set_message_fn() calls, and that the old API no longer exists
+ so that people are aware that they need to change their code
+ changed filter selection API to allow selection of multiple filters
+ since it didn't work in previous versions of libpng anyways
+ optimized filter selection code
+ fixed png_set_background() to allow using an arbitrary RGB color for
+ paletted images
+ fixed gamma and background correction for paletted images, so
+ png_correct_palette is not needed unless you are correcting an
+ external palette (you will need to #define PNG_CORRECT_PALETTE_SUPPORTED
+ in pngconf.h) - if nobody uses this, it may disappear in the future.
+ fixed bug with Borland 64K memory allocation (Alexander Lehmann)
+ fixed bug in interlace handling (Smarasderagd, I think)
+ added more error checking for writing and image to reduce invalid files
+ separated read and write functions so that they won't both be linked
+ into a binary when only reading or writing functionality is used
+ new pngtest image also has interlacing and zTXt
+ updated documentation to reflect new API
+version 0.90 [January, 1997]
+ made CRC errors/warnings on critical and ancillary chunks configurable
+ libpng will use the zlib CRC routines by (compile-time) default
+ changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner)
+ added external C++ wrapper statements to png.h (Gilles Dauphin)
+ allow PNG file to be read when some or all of file signature has already
+ been read from the beginning of the stream. ****This affects the size
+ of info_struct and invalidates all programs that use a shared libpng****
+ fixed png_filler() declarations
+ fixed? background color conversions
+ fixed order of error function pointers to match documentation
+ current chunk name is now available in png_struct to reduce the number
+ of nearly identical error messages (will simplify multi-lingual
+ support when available)
+ try to get ready for unknown-chunk callback functions:
+ - previously read critical chunks are flagged, so the chunk handling
+ routines can determine if the chunk is in the right place
+ - all chunk handling routines have the same prototypes, so we will
+ be able to handle all chunks via a callback mechanism
+ try to fix Linux "setjmp" buffer size problems
+ removed png_large_malloc, png_large_free, and png_realloc functions.
+version 0.95 [March, 1997]
+ fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never
+ fixed bug in PNG file signature compares when start != 0
+ changed parameter type of png_set_filler(...filler...) from png_byte
+ to png_uint_32
+ added test for MACOS to ensure that both math.h and fp.h are not #included
+ added macros for libpng to be compiled as a Windows DLL (Andreas Kupries)
+ added "packswap" transformation, which changes the endianness of
+ packed-pixel bytes (Kevin Bracey)
+ added "strip_alpha" transformation, which removes the alpha channel of
+ input images without using it (not neccesarily a good idea)
+ added "swap_alpha" transformation, which puts the alpha channel in front
+ of the color bytes instead of after
+ removed all implicit variable tests which assume NULL == 0 (I think)
+ changed several variables to "png_size_t" to show 16/32-bit limitations
+ added new pCAL chunk read/write support
+ added experimental filter selection weighting (Greg Roelofs)
+ removed old png_set_rgbx() and png_set_xrgb() functions that have been
+ obsolete for about 2 years now (use png_set_filler() instead)
+ added macros to read 16- and 32-bit ints directly from buffer, to be
+ used only on those systems that support it (namely PowerPC and 680x0)
+ With some testing, this may become the default for MACOS/PPC systems.
+ only calculate CRC on data if we are going to use it
+ added macros for zTXt compression type PNG_zTXt_COMPRESSION_???
+ added macros for simple libpng debugging output selectable at compile time
+ removed PNG_READ_END_MODE in progressive reader (Smarasderagd)
+ more description of info_struct in libpng.txt and png.h
+ more instructions in example.c
+ more chunk types tested in pngtest.c
+ renamed pngrcb.c to pngset.c, and all png_read_<chunk> functions to be
+ png_set_<chunk>. We now have corresponding png_get_<chunk>
+ functions in pngget.c to get infomation in info_ptr. This isolates
+ the application from the internal organization of png_info_struct
+ (good for shared library implementations).
+version 0.96 [May, 1997]
+ fixed serious bug with < 8bpp images introduced in 0.95
+ fixed 256-color transparency bug (Greg Roelofs)
+ fixed up documentation (Greg Roelofs, Laszlo Nyul)
+ fixed "error" in pngconf.h for Linux setjmp() behaviour
+ fixed DOS medium model support (Tim Wegner)
+ fixed png_check_keyword() for case with error in static string text
+ added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul)
+ added typecasts to quiet compiler errors
+ added more debugging info
+version 0.97 [January, 1998]
+ removed PNG_USE_OWN_CRC capability
+ relocated png_set_crc_action from pngrutil.c to pngrtran.c
+ fixed typecasts of "new_key", etc. (Andreas Dilger)
+ added RFC 1152 [sic] date support
+ fixed bug in gamma handling of 4-bit grayscale
+ added 2-bit grayscale gamma handling (Glenn R-P)
+ added more typecasts. 65536L becomes (png_uint_32)65536L, etc. (Glenn R-P)
+ minor corrections in libpng.txt
+ added simple sRGB support (Glenn R-P)
+ easier conditional compiling, e.g. define PNG_READ/WRITE_NOT_FULLY_SUPPORTED;
+ all configurable options can be selected from command-line instead
+ of having to edit pngconf.h (Glenn R-P)
+ fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P)
+ added more conditions for png_do_background, to avoid changing
+ black pixels to background when a background is supplied and
+ no pixels are transtqparent
+ repaired PNG_NO_STDIO behaviour
+ tested NODIV support and made it default behaviour (Greg Roelofs)
+ added "-m" option and PNGTEST_DEBUG_MEMORY to pngtest (John Bowler)
+ regularized version numbering scheme and bumped shared-library major
+ version number to 2 to avoid problems with libpng 0.89 apps (Greg Roelofs)
+version 0.98 [January, 1998]
+ cleaned up some typos in libpng.txt and in code documentation
+ fixed memory leaks in pCAL chunk processing (Glenn R-P and John Bowler)
+ cosmetic change "display_gamma" to "screen_gamma" in pngrtran.c
+ changed recommendation about file_gamma for PC images to .51 from .45,
+ in example.c and libpng.txt, added comments to distinguish between
+ screen_gamma, viewing_gamma, and display_gamma.
+ changed all references to RFC1152 to read RFC1123 and changed the
+ PNG_TIME_RFC1152_SUPPORTED macro to PNG_TIME_RFC1123_SUPPORTED
+ added png_invert_alpha capability (Glenn R-P -- suggestion by Jon Vincent)
+ changed srgb_intent from png_byte to int to avoid compiler bugs
+version 0.99 [January 30, 1998]
+ free info_ptr->text instead of end_info_ptr->text in pngread.c (John Bowler)
+ fixed a longstanding "packswap" bug in pngtrans.c
+ fixed some inconsistencies in pngconf.h that prevented compiling with
+ PNG_READ_GAMMA_SUPPORTED and PNG_READ_hIST_SUPPORTED undefined
+ fixed some typos and made other minor rearrangement of libpng.txt (Andreas)
+ changed recommendation about file_gamma for PC images to .50 from .51 in
+ example.c and libpng.txt, and changed file_gamma for sRGB images to .45
+ added a number of functions to access information from the png structure
+ png_get_image_height(), etc. (Glenn R-P, suggestion by Brad Pettit)
+ added TARGET_MACOS similar to zlib-1.0.8
+ define PNG_ALWAYS_EXTERN when __MWERKS__ && WIN32 are defined
+ added type casting to all png_malloc() function calls
+version 0.99a [January 31, 1998]
+ Added type casts and parentheses to all returns that return a value.(Tim W.)
+version 0.99b [February 4, 1998]
+ Added type cast png_uint_32 on malloc function calls where needed.
+ Changed type of num_hist from png_uint_32 to int (same as num_palette).
+ Added checks for rowbytes overflow, in case png_size_t is less than 32 bits.
+ Renamed makefile.elf to makefile.lnx.
+version 0.99c [February 7, 1998]
+ More type casting. Removed erroneous overflow test in pngmem.c.
+ Added png_buffered_memcpy() and png_buffered_memset(), apply them to rowbytes.
+ Added UNIX manual pages libpng.3 (incorporating libpng.txt) and png.5.
+version 0.99d [February 11, 1998]
+ Renamed "far_to_near()" "png_far_to_near()"
+ Revised libpng.3
+ Version 99c "buffered" operations didn't work as intended. Replaced them
+ with png_memcpy_check() and png_memset_check().
+ Added many "if (png_ptr == NULL) return" to quell compiler warnings about
+ unused png_ptr, mostly in pngget.c and pngset.c.
+ Check for overlength tRNS chunk present when indexed-color PLTE is read.
+ Cleaned up spelling errors in libpng.3/libpng.txt
+ Corrected a problem with png_get_tRNS() which returned undefined trans array
+version 0.99e [February 28, 1998]
+ Corrected png_get_tRNS() again.
+ Add parentheses for easier reading of pngget.c, fixed "||" should be "&&".
+ Touched up example.c to make more of it compileable, although the entire
+ file still can't be compiled (Willem van Schaik)
+ Fixed a bug in png_do_shift() (Bryan Tsai)
+ Added a space in png.h prototype for png_write_chunk_start()
+ Replaced pngtest.png with one created with zlib 1.1.1
+ Changed pngtest to report PASS even when file size is different (Jean-loup G.)
+ Corrected some logic errors in png_do_invert_alpha() (Chris Patterson)
+version 0.99f [March 5, 1998]
+ Corrected a bug in pngpread() introduced in version 99c (Kevin Bracey)
+ Moved makefiles into a "scripts" directory, and added INSTALL instruction file
+ Added makefile.os2 and pngos2.def (A. Zabolotny) and makefile.s2x (W. Sebok)
+ Added pointers to "note on libpng versions" in makefile.lnx and README
+ Added row callback feature when reading and writing nonprogressive rows
+ and added a test of this feature in pngtest.c
+ Added user transform callbacks, with test of the feature in pngtest.c
+version 0.99g [March 6, 1998, morning]
+ Minor changes to pngtest.c to suppress compiler warnings.
+ Removed "beta" language from documentation.
+version 0.99h [March 6, 1998, evening]
+ Minor changes to previous minor changes to pngtest.c
+ Changed PNG_READ_NOT_FULLY_SUPPORTED to PNG_READ_TRANSFORMS_NOT_SUPPORTED
+ and added PNG_PROGRESSIVE_READ_NOT_SUPPORTED macro
+ Added user transform capability
+version 1.00 [March 7, 1998]
+ Changed several typedefs in pngrutil.c
+ Added makefile.wat (Pawel Mrochen), updated makefile.tc3 (Willem van Schaik)
+ tqreplaced "while(1)" with "for(;;)"
+ added PNGARG() to prototypes in pngtest.c and removed some prototypes
+ updated some of the makefiles (Tom Lane)
+ changed some typedefs (s_start, etc.) in pngrutil.c
+ fixed dimensions of "short_months" array in pngwrite.c
+ Replaced ansi2knr.c with the one from jpeg-v6
+version 1.0.0 [March 8, 1998]
+ Changed name from 1.00 to 1.0.0 (Adam Costello)
+ Added smakefile.ppc (with SCOPTIONS.ppc) for Amiga PPC (Andreas Kleinert)
+version 1.0.0a [March 9, 1998]
+ Fixed three bugs in pngrtran.c to make gamma+background handling consistent
+ (Greg Roelofs)
+ Changed format of the PNG_LIBPNG_VER integer to xyyzz instead of xyz
+ for major, minor, and bugfix releases. This is 10001. (Adam Costello,
+ Tom Lane)
+ Make months range from 1-12 in png_convert_to_rfc1123
+version 1.0.0b [March 13, 1998]
+ Quieted compiler complaints about two empty "for" loops in pngrutil.c
+ Minor changes to makefile.s2x
+ Removed #ifdef/#endif around a png_free() in pngread.c
+version 1.0.1 [March 14, 1998]
+ Changed makefile.s2x to reduce security risk of using a relative pathname
+ Fixed some typos in the documentation (Greg).
+ Fixed a problem with value of "channels" returned by png_read_update_info()
+version 1.0.1a [April 21, 1998]
+ Optimized Paeth calculations by replacing abs() function calls with intrinsics
+ plus other loop optimizations. Improves avg decoding speed by about 20%.
+ Commented out i386istic "align" compiler flags in makefile.lnx.
+ Reduced the default warning level in some makefiles, to make them consistent.
+ Removed references to IJG and JPEG in the ansi2knr.c copyright statement.
+ Fixed a bug in png_do_strip_filler with XXRRGGBB => RRGGBB transformation.
+ Added grayscale and 16-bit capability to png_do_read_filler().
+ Fixed a bug in pngset.c, introduced in version 0.99c, that sets rowbytes
+ too large when writing an image with bit_depth < 8 (Bob Dellaca).
+ Corrected some bugs in the experimental weighted filtering heuristics.
+ Moved a misplaced pngrutil code block that truncates tRNS if it has more
+ than num_palette entries -- test was done before num_palette was defined.
+ Fixed a png_convert_to_rfc1123() bug that converts day 31 to 0 (Steve Eddins).
+ Changed compiler flags in makefile.wat for better optimization (Pawel Mrochen).
+version 1.0.1b [May 2, 1998]
+ Relocated png_do_gray_to_rgb() within png_do_read_transformations() (Greg).
+ Relocated the png_composite macros from pngrtran.c to png.h (Greg).
+ Added makefile.sco (contributed by Mike Hopkirk).
+ Fixed two bugs (missing definitions of "istop") introduced in libpng-1.0.1a.
+ Fixed a bug in pngrtran.c that would set channels=5 under some circumstances.
+ More work on the Paeth-filtering, achieving imperceptible speedup (A Kleinert).
+ More work on loop optimization which may help when compiled with C++ compilers.
+ Added warnings when people try to use transforms they've defined out.
+ Collapsed 4 "i" and "c" loops into single "i" loops in pngrtran and pngwtran.
+ Revised paragraph about png_set_expand() in libpng.txt and libpng.3 (Greg)
+version 1.0.1c [May 11, 1998]
+ Fixed a bug in pngrtran.c (introduced in libpng-1.0.1a) where the masks for
+ filler bytes should have been 0xff instead of 0xf.
+ Added max_pixel_depth=32 in pngrutil.c when using FILLER with palette images.
+ Moved PNG_WRITE_WEIGHTED_FILTER_SUPPORTED and PNG_WRITE_FLUSH_SUPPORTED
+ out of the PNG_WRITE_TRANSFORMS_NOT_SUPPORTED block of pngconf.h
+ Added "PNG_NO_WRITE_TRANSFORMS" etc., as alternatives for *_NOT_SUPPORTED,
+ for consistency, in pngconf.h
+ Added individual "ifndef PNG_NO_[CAPABILITY]" in pngconf.h to make it easier
+ to remove unwanted capabilities via the compile line
+ Made some corrections to grammar (which, it's) in documentation (Greg).
+ Corrected example.c, use of row_pointers in png_write_image().
+version 1.0.1d [May 24, 1998]
+ Corrected several statements that used side effects illegally in pngrutil.c
+ and pngtrans.c, that were introduced in version 1.0.1b
+ Revised png_read_rows() to avoid repeated if-testing for NULL (A Kleinert)
+ More corrections to example.c, use of row_pointers in png_write_image()
+ and png_read_rows().
+ Added pngdll.mak and pngdef.pas to scripts directory, contributed by
+ Bob Dellaca, to make a png32bd.dll with Borland C++ 4.5
+ Fixed error in example.c with png_set_text: num_text is 3, not 2 (Guido V.)
+ Changed several loops from count-down to count-up, for consistency.
+version 1.0.1e [June 6, 1998]
+ Revised libpng.txt and libpng.3 description of png_set_read|write_fn(), and
+ added warnings when people try to set png_read_fn and png_write_fn in
+ the same structure.
+ Added a test such that png_do_gamma will be done when num_trans==0
+ for truecolor images that have defined a background. This corrects an
+ error that was introduced in libpng-0.90 that can cause gamma processing
+ to be skipped.
+ Added tests in png.h to include "trans" and "trans_values" in structures
+ when PNG_READ_BACKGROUND_SUPPORTED or PNG_READ_EXPAND_SUPPORTED is defined.
+ Add png_free(png_ptr->time_buffer) in png_destroy_read_struct()
+ Moved png_convert_to_rfc_1123() from pngwrite.c to png.c
+ Added capability for user-provided malloc_fn() and free_fn() functions,
+ and revised pngtest.c to demonstrate their use, replacing the
+ PNGTEST_DEBUG_MEM feature.
+ Added makefile.w32, for Microsoft C++ 4.0 and later (Tim Wegner).
+version 1.0.2 [June 14, 1998]
+ Fixed two bugs in makefile.bor .
+version 1.0.2a [December 30, 1998]
+ Replaced and extended code that was removed from png_set_filler() in 1.0.1a.
+ Fixed a bug in png_do_filler() that made it fail to write filler bytes in
+ the left-most pixel of each row (Kevin Bracey).
+ Changed "static pngcharp tIME_string" to "static char tIME_string[30]"
+ in pngtest.c (Duncan Simpson).
+ Fixed a bug in pngtest.c that caused pngtest to try to write a tIME chunk
+ even when no tIME chunk was present in the source file.
+ Fixed a problem in pngrutil.c: gray_to_rgb didn't always work with 16-bit.
+ Fixed a problem in png_read_push_finish_row(), which would not skip some
+ passes that it should skip, for images that are less than 3 pixels high.
+ Interchanged the order of calls to png_do_swap() and png_do_shift()
+ in pngwtran.c (John Cromer).
+ Added #ifdef PNG_DEBUG/#endif surrounding use of PNG_DEBUG in png.h .
+ Changed "bad adaptive filter type" from error to warning in pngrutil.c .
+ Fixed a documentation error about default filtering with 8-bit indexed-color.
+ Separated the PNG_NO_STDIO macro into PNG_NO_STDIO and PNG_NO_CONSOLE_IO
+ (L. Peter Deutsch).
+ Added png_set_rgb_to_gray() and png_get_rgb_to_gray_status() functions.
+ Added png_get_copyright() and png_get_header_version() functions.
+ Revised comments on png_set_progressive_read_fn() in libpng.txt and example.c
+ Added information about debugging in libpng.txt and libpng.3 .
+ Changed "ln -sf" to "ln -s -f" in makefile.s2x, makefile.lnx, and makefile.sco.
+ Removed lines after Dynamic Dependencies" in makefile.aco .
+ Revised makefile.dec to make a shared library (Jeremie Petit).
+ Removed trailing blanks from all files.
+version 1.0.2a [January 6, 1999]
+ Removed misplaced #endif and #ifdef PNG_NO_EXTERN near the end of png.h
+ Added "if" tests to silence complaints about unused png_ptr in png.h and png.c
+ Changed "check_if_png" function in example.c to return true (nonzero) if PNG.
+ Changed libpng.txt to demonstrate png_sig_cmp() instead of png_check_sig()
+ which is obsolete.
+version 1.0.3 [January 14, 1999]
+ Added makefile.hux, for Hewlett Packard HPUX 10.20 and 11.00 (Jim Rice)
+ Added a statement of Y2K compliance in png.h, libpng.3, and Y2KINFO.
+version 1.0.3a [August 12, 1999]
+ Added check for PNG_READ_INTERLACE_SUPPORTED in pngread.c; issue a warning
+ if an attempt is made to read an interlaced image when it's not supported.
+ Added check if png_ptr->trans is defined before freeing it in pngread.c
+ Modified the Y2K statement to include versions back to version 0.71
+ Fixed a bug in the check for valid IHDR bit_depth/color_types in pngrutil.c
+ Modified makefile.wat (added -zp8 flag, ".symbolic", changed some comments)
+ Replaced leading blanks with tab characters in makefile.hux
+ Changed "dworkin.wustl.edu" to "ccrc.wustl.edu" in various documents.
+ Changed (float)red and (float)green to (double)red, (double)green
+ in png_set_rgb_to_gray() to avoid "promotion" problems in AIX.
+ Fixed a bug in pngconf.h that omitted <stdio.h> when PNG_DEBUG==0 (K Bracey).
+ Reformatted libpng.3 and libpngpf.3 with proper fonts (script by J. vanZandt).
+ Updated documentation to refer to the PNG-1.2 specification.
+ Removed ansi2knr.c and left pointers to the latest source for ansi2knr.c
+ in makefile.knr, INSTALL, and README (L. Peter Deutsch)
+ Fixed bugs in calculation of the length of rowbytes when adding alpha
+ channels to 16-bit images, in pngrtran.c (Chris Nokleberg)
+ Added function png_set_user_transform_info() to store user_transform_ptr,
+ user_depth, and user_channels into the png_struct, and a function
+ png_get_user_transform_ptr() to retrieve the pointer (Chris Nokleberg)
+ Added function png_set_empty_plte_permitted() to make libpng useable
+ in MNG applications.
+ Corrected the typedef for png_free_ptr in png.h (Jesse Jones).
+ Correct gamma with srgb is 45455 instead of 45000 in pngrutil.c, to be
+ consistent with PNG-1.2, and allow variance of 500 before complaining.
+ Added assembler code contributed by Intel in file pngvcrd.c and modified
+ makefile.w32 to use it (Nirav Chhatrapati, INTEL Corporation, Gilles Vollant)
+ Changed "ln -s -f" to "ln -f -s" in the makefiles to make Solaris happy.
+ Added some aliases for png_set_expand() in pngrtran.c, namely
+ png_set_expand_PLTE(), png_set_expand_depth(), and png_set_expand_tRNS()
+ (Greg Roelofs, in "PNG: The Definitive Guide").
+ Added makefile.beo for BEOS on X86, contributed by Sander Stok.
+version 1.0.3b [August 26, 1999]
+ Replaced 2147483647L several places with PNG_MAX_UINT macro, defined in png.h
+ Changed leading blanks to tabs in all makefiles.
+ Define PNG_USE_PNGVCRD in makefile.w32, to get MMX assembler code.
+ Made alternate versions of png_set_expand() in pngrtran.c, namely
+ png_set_gray_1_2_4_to_8, png_set_palette_to_rgb, and png_set_tRNS_to_alpha
+ (Greg Roelofs, in "PNG: The Definitive Guide"). Deleted the 1.0.3a aliases.
+ Relocated start of 'extern "C"' block in png.h so it doesn't include pngconf.h
+ Revised calculation of num_blocks in pngmem.c to avoid a potentially
+ negative shift distance, whose results are undefined in the C language.
+ Added a check in pngset.c to prevent writing multiple tIME chunks.
+ Added a check in pngwrite.c to detect invalid small window_bits sizes.
+version 1.0.3d [September 4, 1999]
+ Fixed type casting of igamma in pngrutil.c
+ Added new png_expand functions to scripts/pngdef.pas and pngos2.def
+ Added a demo read_user_transform_fn that examines the row filters in pngtest.c
+version 1.0.4 [September 24, 1999]
+ Define PNG_ALWAYS_EXTERN in pngconf.h if __STDC__ is defined
+ Delete #define PNG_INTERNAL and include "png.h" from pngasmrd.h
+ Made several minor corrections to pngtest.c
+ Renamed the makefiles with longer but more user friendly extensions.
+ Copied the PNG copyright and license to a separate LICENSE file.
+ Revised documentation, png.h, and example.c to remove reference to
+ "viewing_gamma" which no longer appears in the PNG specification.
+ Revised pngvcrd.c to use MMX code for interlacing only on the final pass.
+ Updated pngvcrd.c to use the faster C filter algorithms from libpng-1.0.1a
+ Split makefile.win32vc into two versions, makefile.vcawin32 (uses MMX
+ assembler code) and makefile.vcwin32 (doesn't).
+ Added a CPU timing report to pngtest.c (enabled by defining PNGTEST_TIMING)
+ Added a copy of pngnow.png to the distribution.
+version 1.0.4a [September 25, 1999]
+ Increase max_pixel_depth in pngrutil.c if a user transform needs it.
+ Changed several division operations to right-shifts in pngvcrd.c
+version 1.0.4b [September 30, 1999]
+ Added parentheses in line 3732 of pngvcrd.c
+ Added a comment in makefile.linux warning about buggy -O3 in pgcc 2.95.1
+version 1.0.4c [October 1, 1999]
+ Added a "png_check_version" function in png.c and pngtest.c that will generate
+ a helpful compiler error if an old png.h is found in the search path.
+ Changed type of png_user_transform_depth|channels from int to png_byte.
+version 1.0.4d [October 6, 1999]
+ Changed 0.45 to 0.45455 in png_set_sRGB()
+ Removed unused PLTE entries from pngnow.png
+ Re-enabled some parts of pngvcrd.c (png_combine_row) that work properly.
+version 1.0.4e [October 10, 1999]
+ Fixed sign error in pngvcrd.c (Greg Roelofs)
+ Replaced some instances of memcpy with simple assignments in pngvcrd (GR-P)
+version 1.0.4f [October 15, 1999]
+ Surrounded example.c code with #if 0 .. #endif to prevent people from
+ inadvertently trying to compile it.
+ Changed png_get_header_version() from a function to a macro in png.h
+ Added type casting mostly in pngrtran.c and pngwtran.c
+ Removed some pointless "ptr = NULL" in pngmem.c
+ Added a "contrib" directory containing the source code from Greg's book.
+version 1.0.5 [October 15, 1999]
+ Minor editing of the INSTALL and README files.
+version 1.0.5a [October 23, 1999]
+ Added contrib/pngsuite and contrib/pngminus (Willem van Schaik)
+ Fixed a typo in the png_set_sRGB() function call in example.c (Jan Nijtmans)
+ Further optimization and bugfix of pngvcrd.c
+ Revised pngset.c so that it does not allocate or free memory in the user's
+ text_ptr structure. Instead, it makes its own copy.
+ Created separate write_end_info_struct in pngtest.c for a more severe test.
+ Added code in pngwrite.c to free info_ptr->text[i].key to stop a memory leak.
+version 1.0.5b [November 23, 1999]
+ Moved PNG_FLAG_HAVE_CHUNK_HEADER, PNG_FLAG_BACKGROUND_IS_GRAY and
+ PNG_FLAG_WROTE_tIME from flags to mode.
+ Added png_write_info_before_PLTE() function.
+ Fixed some typecasting in contrib/gregbook/*.c
+ Updated scripts/makevms.com and added makevms.com to contrib/gregbook
+ and contrib/pngminus (Martin Zinser)
+version 1.0.5c [November 26, 1999]
+ Moved png_get_header_version from png.h to png.c, to accomodate ansi2knr.
+ Removed all global arrays (according to PNG_NO_GLOBAL_ARRAYS macro), to
+ accomodate making DLL's: Moved usr_png_ver from global variable to function
+ png_get_header_ver() in png.c. Moved png_sig to png_sig_bytes in png.c and
+ eliminated use of png_sig in pngwutil.c. Moved the various png_CHNK arrays
+ into pngtypes.h. Eliminated use of global png_pass arrays. Declared the
+ png_CHNK and png_pass arrays to be "const". Made the global arrays
+ available to applications (although none are used in libpng itself) when
+ PNG_NO_GLOBAL_ARRAYS is not defined or when PNG_GLOBAL_ARRAYS is defined.
+ Removed some extraneous "-I" from contrib/pngminus/makefile.std
+ Changed the PNG_sRGB_INTENT macros in png.h to be consistent with PNG-1.2.
+ Change PNG_SRGB_INTENT to PNG_sRGB_INTENT in libpng.txt and libpng.3
+version 1.0.5d [November 29, 1999]
+ Add type cast (png_const_charp) two places in png.c
+ Eliminated pngtypes.h; use macros instead to declare PNG_CHNK arrays.
+ Renamed "PNG_GLOBAL_ARRAYS" to "PNG_USE_GLOBAL_ARRAYS" and made available
+ to applications a macro "PNG_USE_LOCAL_ARRAYS".
+ #ifdef out all the new declarations when PNG_USE_GLOBAL_ARRAYS is defined.
+ Added PNG_EXPORT_VAR macro to accommodate making DLL's.
+version 1.0.5e [November 30, 1999]
+ Added iCCP, iTXt, and sPLT support; added "lang" member to the png_text
+ structure; refactored the inflate/deflate support to make adding new chunks
+ with trailing compressed parts easier in the future, and added new functions
+ png_free_iCCP, png_free_pCAL, png_free_sPLT, png_free_text, png_get_iCCP,
+ png_get_spalettes, png_set_iCCP, png_set_spalettes (Eric S. Raymond).
+ NOTE: Applications that write text chunks MUST define png_text->lang
+ before calling png_set_text(). It must be set to NULL if you want to
+ write tEXt or zTXt chunks. If you want your application to be able to
+ run with older versions of libpng, use
+
+ #ifdef PNG_iTXt_SUPPORTED
+ png_text[i].lang = NULL;
+ #endif
+
+ Changed png_get_oFFs() and png_set_oFFs() to use signed rather than unsigned
+ offsets (Eric S. Raymond).
+ Combined PNG_READ_cHNK_SUPPORTED and PNG_WRITE_cHNK_SUPPORTED macros into
+ PNG_cHNK_SUPPORTED and combined the three types of PNG_text_SUPPORTED
+ macros, leaving the separate macros also available.
+ Removed comments on #endifs at the end of many short, non-nested #if-blocks.
+version 1.0.5f [December 6, 1999]
+ Changed makefile.solaris to issue a warning about potential problems when
+ the ucb "ld" is in the path ahead of the ccs "ld".
+ Removed "- [date]" from the "synopsis" line in libpng.3 and libpngpf.3.
+ Added sCAL chunk support (Eric S. Raymond).
+version 1.0.5g [December 7, 1999]
+ Fixed "png_free_spallettes" typo in png.h
+ Added code to handle new chunks in pngpread.c
+ Moved PNG_CHNK string macro definitions outside of PNG_NO_EXTERN block
+ Added "translated_key" to png_text structure and png_write_iTXt().
+ Added code in pngwrite.c to work around a newly discovered zlib bug.
+version 1.0.5h [December 10, 1999]
+ NOTE: regarding the note for version 1.0.5e, the following must also
+ be included in your code:
+ png_text[i].translated_key = NULL;
+ Unknown chunk handling is now supported.
+ Option to eliminate all floating point support was added. Some new
+ fixed-point functions such as png_set_gAMA_fixed() were added.
+ Expanded tabs and removed trailing blanks in source files.
+version 1.0.5i [December 13, 1999]
+ Added some type casts to silence compiler warnings.
+ Renamed "png_free_spalette" to "png_free_spalettes" for consistency.
+ Removed leading blanks from a #define in pngvcrd.c
+ Added some parameters to the new png_set_keep_unknown_chunks() function.
+ Added a test for up->location != 0 in the first instance of writing
+ unknown chunks in pngwrite.c
+ Changed "num" to "i" in png_free_spalettes() and png_free_unknowns() to
+ prevent recursion.
+ Added png_free_hIST() function.
+ Various patches to fix bugs in the sCAL and integer cHRM processing,
+ and to add some convenience macros for use with sCAL.
+version 1.0.5j [December 21, 1999]
+ Changed "unit" parameter of png_write_sCAL from png_byte to int, to work
+ around buggy compilers.
+ Added new type "png_fixed_point" for integers that hold float*100000 values
+ Restored backward compatibility of tEXt/zTXt chunk processing:
+ Restored the first four members of png_text to the same order as v.1.0.5d.
+ Added members "lang_key" and "itxt_length" to png_text struct. Set
+ text_length=0 when "text" tqcontains iTXt data. Use the "compression"
+ member to distinguish among tEXt/zTXt/iTXt types. Added
+ PNG_ITXT_COMPRESSION_NONE (1) and PNG_ITXT_COMPRESSION_zTXt(2) macros.
+ The "Note" above, about backward incompatibility of libpng-1.0.5e, no
+ longer applies.
+ Fixed png_read|write_iTXt() to read|write parameters in the right order,
+ and to write the iTXt chunk after IDAT if it appears in the end_ptr.
+ Added pnggccrd.c, version of pngvcrd.c Intel assembler for gcc (Greg Roelofs)
+ Reversed the order of trying to write floating-point and fixed-point gAMA.
+version 1.0.5k [December 27, 1999]
+ Added many parentheses, e.g., "if (a && b & c)" becomes "if (a && (b & c))"
+ Added png_handle_as_unknown() function (Glenn)
+ Added png_free_chunk_list() function and chunk_list and num_chunk_list members
+ of png_ptr.
+ Eliminated erroneous warnings about multiple sPLT chunks and sPLT-after-PLTE.
+ Fixed a libpng-1.0.5h bug in pngrutil.c that was issuing erroneous warnings
+ about ignoring incorrect gAMA with sRGB (gAMA was in fact not ignored)
+ Added png_free_tRNS(); png_set_tRNS() now malloc's its own trans array (ESR).
+ Define png_get_int_32 when oFFs chunk is supported as well as when pCAL is.
+ Changed type of proflen from png_int_32 to png_uint_32 in png_get_iCCP().
+version 1.0.5l [January 1, 2000]
+ Added functions png_set_read_user_chunk_fn() and png_get_user_chunk_ptr()
+ for setting a callback function to handle unknown chunks and for
+ retrieving the associated user pointer (Glenn).
+version 1.0.5m [January 7, 2000]
+ Added high-level functions png_read_png(), png_write_png(), png_free_pixels().
+version 1.0.5n [January 9, 2000]
+ Added png_free_PLTE() function, and modified png_set_PLTE() to malloc its
+ own memory for info_ptr->palette. This makes it safe for the calling
+ application to free its copy of the palette any time after it calls
+ png_set_PLTE().
+version 1.0.5o [January 20, 2000]
+ Cosmetic changes only (removed some trailing blanks and TABs)
+version 1.0.5p [January 31, 2000]
+ Renamed pngdll.mak to makefile.bd32
+ Cosmetic changes in pngtest.c
+version 1.0.5q [February 5, 2000]
+ Relocated the makefile.solaris warning about PATH problems.
+ Fixed pngvcrd.c bug by pushing/popping registers in mmxsupport (Bruce Oberg)
+ Revised makefile.gcmmx
+ Added PNG_SETJMP_SUPPORTED, PNG_SETJMP_NOT_SUPPORTED, and PNG_ABORT() macros
+version 1.0.5r [February 7, 2000]
+ Removed superfluous prototype for png_get_itxt from png.h
+ Fixed a bug in pngrtran.c that improperly expanded the background color.
+ Return *num_text=0 from png_get_text() when appropriate, and fix documentation
+ of png_get_text() in libpng.txt/libpng.3.
+version 1.0.5s [February 18, 2000]
+ Added "png_jmp_env()" macro to pngconf.h, to help people migrate to the
+ new error handler that's planned for the next libpng release, and changed
+ example.c, pngtest.c, and contrib programs to use this macro.
+ Revised some of the DLL-export macros in pngconf.h (Greg Roelofs)
+ Fixed a bug in png_read_png() that caused it to fail to expand some images
+ that it should have expanded.
+ Fixed some mistakes in the unused and undocumented INCH_CONVERSIONS functions
+ in pngget.c
+ Changed the allocation of palette, history, and trans arrays back to
+ the version 1.0.5 method (linking instead of copying) which restores
+ backward compatibility with version 1.0.5. Added some remarks about
+ that in example.c. Added "free_me" member to info_ptr and png_ptr
+ and added png_free_data() function.
+ Updated makefile.linux and makefile.gccmmx to make directories conditionally.
+ Made cosmetic changes to pngasmrd.h
+ Added png_set_rows() and png_get_rows(), for use with png_read|write_png().
+ Modified png_read_png() to allocate info_ptr->row_pointers only if it
+ hasn't already been allocated.
+version 1.0.5t [March 4, 2000]
+ Changed png_jmp_env() migration aiding macro to png_jmpbuf().
+ Fixed "interlace" typo (should be "interlaced") in contrib/gregbook/read2-x.c
+ Fixed bug with use of PNG_BEFORE_IHDR bit in png_ptr->mode, introduced when
+ PNG_FLAG_HAVE_CHUNK_HEADER was moved into png_ptr->mode in version 1.0.5b
+ Files in contrib/gregbook were revised to use png_jmpbuf() and to select
+ a 24-bit visual if one is available, and to allow abbreviated options.
+ Files in contrib/pngminus were revised to use the png_jmpbuf() macro.
+ Removed spaces in makefile.linux and makefile.gcmmx, introduced in 1.0.5s
+version 1.0.5u [March 5, 2000]
+ Simplified the code that detects old png.h in png.c and pngtest.c
+ Renamed png_spalette (_p, _pp) to png_sPLT_t (_tp, _tpp)
+ Increased precision of rgb_to_gray calculations from 8 to 15 bits and
+ added png_set_rgb_to_gray_fixed() function.
+ Added makefile.bc32 (32-bit Borland C++, C mode)
+version 1.0.5v [March 11, 2000]
+ Added some parentheses to the png_jmpbuf macro definition.
+ Updated references to the zlib home page, which has moved to freesoftware.com.
+ Corrected bugs in documentation regarding png_read_row() and png_write_row().
+ Updated documentation of png_rgb_to_gray calculations in libpng.3/libpng.txt.
+ Renamed makefile.borland,turboc3 back to makefile.bor,tc3 as in version 1.0.3,
+ revised borland makefiles; added makefile.ibmvac3 and makefile.gcc (Cosmin)
+version 1.0.6 [March 20, 2000]
+ Minor revisions of makefile.bor, libpng.txt, and gregbook/rpng2-win.c
+ Added makefile.sggcc (SGI IRIX with gcc)
+version 1.0.6d [April 7, 2000]
+ Changed sprintf() to strcpy() in png_write_sCAL_s() to work without STDIO
+ Added data_length parameter to png_decompress_chunk() function
+ Revised documentation to remove reference to abandoned png_free_chnk functions
+ Fixed an error in png_rgb_to_gray_fixed()
+ Revised example.c, usage of png_destroy_write_struct().
+ Renamed makefile.ibmvac3 to makefile.ibmc, added libpng.icc IBM project file
+ Added a check for info_ptr->free_me&PNG_FREE_TEXT when freeing text in png.c
+ Simplify png_sig_bytes() function to remove use of non-ISO-C strdup().
+version 1.0.6e [April 9, 2000]
+ Added png_data_freer() function.
+ In the code that checks for over-length tRNS chunks, added check of
+ info_ptr->num_trans as well as png_ptr->num_trans (Matthias Benckmann)
+ Minor revisions of libpng.txt/libpng.3.
+ Check for existing data and free it if the free_me flag is set, in png_set_*()
+ and png_handle_*().
+ Only define PNG_WEIGHTED_FILTERS_SUPPORTED when PNG_FLOATING_POINT_SUPPORTED
+ is defined.
+ Changed several instances of PNG_NO_CONSOLE_ID to PNG_NO_STDIO in pngrutil.c
+ and mentioned the purposes of the two macros in libpng.txt/libpng.3.
+version 1.0.6f [April 14, 2000]
+ Revised png_set_iCCP() and png_set_rows() to avoid prematurely freeing data.
+ Add checks in png_set_text() for NULL members of the input text structure.
+ Revised libpng.txt/libpng.3.
+ Removed superfluous prototype for png_set_itxt from png.h
+ Removed "else" from pngread.c, after png_error(), and changed "0" to "length".
+ Changed several png_errors about malformed ancillary chunks to png_warnings.
+version 1.0.6g [April 24, 2000]
+ Added png_pass-* arrays to pnggccrd.c when PNG_USE_LOCAL_ARRAYS is defined.
+ Relocated paragraph about png_set_background() in libpng.3/libpng.txt
+ and other revisions (Matthias Benckmann)
+ Relocated info_ptr->free_me, png_ptr->free_me, and other info_ptr and
+ png_ptr members to restore binary compatibility with libpng-1.0.5
+ (breaks compatibility with libpng-1.0.6).
+version 1.0.6h [April 24, 2000]
+ Changed shared library so-number pattern from 2.x.y.z to xy.z (this builds
+ libpng.so.10 & libpng.so.10.6h instead of libpng.so.2 & libpng.so.2.1.0.6h)
+ This is a temporary change for test purposes.
+version 1.0.6i [May 2, 2000]
+ Rearranged some members at the end of png_info and png_struct, to put
+ unknown_chunks_num and free_me within the original size of the png_structs
+ and free_me, png_read_user_fn, and png_free_fn within the original png_info,
+ because some old applications allocate the structs directly instead of
+ using png_create_*().
+ Added documentation of user memory functions in libpng.txt/libpng.3
+ Modified png_read_png so that it will use user_allocated row_pointers
+ if present, unless free_me directs that it be freed, and added description
+ of the use of png_set_rows() and png_get_rows() in libpng.txt/libpng.3.
+ Added PNG_LEGACY_SUPPORTED macro, and #ifdef out all new (since version
+ 1.00) members of png_struct and png_info, to regain binary compatibility
+ when you define this macro. Capabilities lost in this event
+ are user transforms (new in version 1.0.0),the user transform pointer
+ (new in version 1.0.2), rgb_to_gray (new in 1.0.5), iCCP, sCAL, sPLT,
+ the high-level interface, and unknown chunks support (all new in 1.0.6).
+ This was necessary because of old applications that allocate the structs
+ directly as authors were instructed to do in libpng-0.88 and earlier,
+ instead of using png_create_*().
+ Added modes PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT which
+ can be used to detect codes that directly allocate the structs, and
+ code to check these modes in png_read_init() and png_write_init() and
+ generate a libpng error if the modes aren't set and PNG_LEGACY_SUPPORTED
+ was not defined.
+ Added makefile.intel and updated makefile.watcom (Pawel Mrochen)
+version 1.0.6j [May 3, 2000]
+ Overloaded png_read_init() and png_write_init() with macros that convert
+ calls to png_read_init_2() or png_write_init_2() that check the version
+ and structure sizes.
+version 1.0.7beta11 [May 7, 2000]
+ Removed the new PNG_CREATED_READ_STRUCT and PNG_CREATED_WRITE_STRUCT modes
+ which are no longer used.
+ Eliminated the three new members of png_text when PNG_LEGACY_SUPPORTED is
+ defined or when neither PNG_READ_iTXt_SUPPORTED nor PNG_WRITE_iTXT_SUPPORTED
+ is defined.
+ Made PNG_NO_READ|WRITE_iTXt the default setting, to avoid memory
+ overrun when old applications fill the info_ptr->text structure directly.
+ Added PNGAPI macro, and added it to the definitions of all exported functions.
+ Relocated version macro definitions ahead of the includes of zlib.h and
+ pngconf.h in png.h.
+version 1.0.7beta12 [May 12, 2000]
+ Revised pngset.c to avoid a problem with expanding the png_debug macro.
+ Deleted some extraneous defines from pngconf.h
+ Made PNG_NO_CONSOLE_IO the default condition when PNG_BUILD_DLL is defined.
+ Use MSC _RPTn debugging instead of fprintf if _MSC_VER is defined.
+ Added png_access_version_number() function.
+ Check for tqmask&PNG_FREE_CHNK (for TEXT, SCAL, PCAL) in png_free_data().
+ Expanded libpng.3/libpng.txt information about png_data_freer().
+version 1.0.7beta14 [May 17, 2000] (beta13 was not published)
+ Changed pnggccrd.c and pngvcrd.c to handle bad adaptive filter types as
+ warnings instead of errors, as pngrutil.c does.
+ Set the PNG_INFO_IDAT valid flag in png_set_rows() so png_write_png()
+ will actually write IDATs.
+ Made the default PNG_USE_LOCAL_ARRAYS depend on PNG_DLL instead of WIN32.
+ Make png_free_data() ignore its final parameter except when freeing data
+ that can have multiple instances (text, sPLT, unknowns).
+ Fixed a new bug in png_set_rows().
+ Removed info_ptr->valid tests from png_free_data(), as in version 1.0.5.
+ Added png_set_invalid() function.
+ Fixed incorrect illustrations of png_destroy_write_struct() in example.c.
+version 1.0.7beta15 [May 30, 2000]
+ Revised the deliberately erroneous Linux setjmp code in pngconf.h to produce
+ fewer error messages.
+ Rearranged checks for Z_OK to check the most likely path first in pngpread.c
+ and pngwutil.c.
+ Added checks in pngtest.c for png_create_*() returning NULL, and mentioned
+ in libpng.txt/libpng.3 the need for applications to check this.
+ Changed names of png_default_*() functions in pngtest to pngtest_*().
+ Changed return type of png_get_x|y_offset_*() from png_uint_32 to png_int_32.
+ Fixed some bugs in the unused PNG_INCH_CONVERSIONS functions in pngget.c
+ Set each pointer to NULL after freeing it in png_free_data().
+ Worked around a problem in pngconf.h; AIX's strings.h defines an "index"
+ macro that conflicts with libpng's png_color_16.index. (Dimitri Papadapoulos)
+ Added "msvc" directory with MSVC++ project files (Simon-Pierre Cadieux).
+version 1.0.7beta16 [June 4, 2000]
+ Revised the workaround of AIX string.h "index" bug.
+ Added a check for overlength PLTE chunk in pngrutil.c.
+ Added PNG_NO_POINTER_INDEXING macro to use array-indexing instead of pointer
+ indexing in pngrutil.c and pngwutil.c to accommodate a buggy compiler.
+ Added a warning in png_decompress_chunk() when it runs out of data, e.g.
+ when it tries to read an erroneous PhotoShop iCCP chunk.
+ Added PNG_USE_DLL macro.
+ Revised the copyright/disclaimer/license notice.
+ Added contrib/msvctest directory
+version 1.0.7rc1 [June 9, 2000]
+ Corrected the definition of PNG_TRANSFORM_INVERT_ALPHA (0x0400 not 0x0200)
+ Added contrib/visupng directory (Willem van Schaik)
+version 1.0.7beta18 [June 23, 2000]
+ Revised PNGAPI definition, and pngvcrd.c to work with __GCC__
+ and do not redefine PNGAPI if it is passed in via a compiler directive.
+ Revised visupng/PngFile.c to remove returns from within the Try block.
+ Removed leading underscores from "_PNG_H" and "_PNG_SAVE_BSD_SOURCE" macros.
+ Updated contrib/visupng/cexcept.h to version 1.0.0.
+ Fixed bugs in pngwrite.c and pngwutil.c that prevented writing iCCP chunks.
+version 1.0.7rc2 [June 28, 2000]
+ Updated license to include disclaimers required by UCITA.
+ Fixed "DJBPP" typo in pnggccrd.c introduced in beta18.
+version 1.0.7 [July 1, 2000]
+ Revised the definition of "trans_values" in libpng.3/libpng.txt
+version 1.0.8beta1 [July 8, 2000]
+ Added png_free(png_ptr, key) two places in pngpread.c to stop memory leaks.
+ Changed PNG_NO_STDIO to PNG_NO_CONSOLE_IO, several places in pngrutil.c and
+ pngwutil.c.
+ Changed PNG_EXPORT_VAR to use PNG_IMPEXP, in pngconf.h.
+ Removed unused "#include <assert.h>" from png.c
+ Added WindowsCE support.
+ Revised pnggccrd.c to work with gcc-2.95.2 and in the Cygwin environment.
+version 1.0.8beta2 [July 10, 2000]
+ Added project files to the wince directory and made further revisions
+ of pngtest.c, pngrio.c, and pngwio.c in support of WindowsCE.
+version 1.0.8beta3 [July 11, 2000]
+ Only set the PNG_FLAG_FREE_TRNS or PNG_FREE_TRNS flag in png_handle_tRNS()
+ for indexed-color input files to avoid potential double-freeing trans array
+ under some unusual conditions; problem was introduced in version 1.0.6f.
+ Further revisions to pngtest.c and files in the wince subdirectory.
+version 1.0.8beta4 [July 14, 2000]
+ Added the files pngbar.png and pngbar.jpg to the distribution.
+ Added makefile.cygwin, and cygwin support in pngconf.h
+ Added PNG_NO_ZALLOC_ZERO macro (makes png_zalloc skip zeroing memory)
+version 1.0.8rc1 [July 16, 2000]
+ Revised png_debug() macros and statements to eliminate compiler warnings.
+version 1.0.8 [July 24, 2000]
+ Added png_flush() in pngwrite.c, after png_write_IEND().
+ Updated makefile.hpux to build a shared library.
+version 1.0.9beta1 [November 10, 2000]
+ Fixed typo in scripts/makefile.hpux
+ Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser)
+ Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser)
+ Changed "cdrom.com" in documentation to "libpng.org"
+ Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg).
+ Changed type of "params" from voidp to png_voidp in png_read|write_png().
+ Make sure PNGAPI and PNG_IMPEXP are defined in pngconf.h.
+ Revised the 3 instances of WRITEFILE in pngtest.c.
+ Relocated "msvc" and "wince" project subdirectories into "dll" subdirectory.
+ Updated png.rc in dll/msvc project
+ Revised makefile.dec to define and use LIBPATH and INCPATH
+ Increased size of global png_libpng_ver[] array from 12 to 18 chars.
+ Made global png_libpng_ver[], png_sig[] and png_pass_*[] arrays const.
+ Removed duplicate png_crc_finish() from png_handle_bKGD() function.
+ Added a warning when application calls png_read_update_info() multiple times.
+ Revised makefile.cygwin
+ Fixed bugs in iCCP support in pngrutil.c and pngwutil.c.
+ Replaced png_set_empty_plte_permitted() with png_permit_mng_features().
+version 1.0.9beta2 [November 19, 2000]
+ Renamed the "dll" subdirectory "projects".
+ Added borland project files to "projects" subdirectory.
+ Set VS_FF_PRERELEASE and VS_FF_PATCHED flags in msvc/png.rc when appropriate.
+ Add error message in png_set_compression_buffer_size() when malloc fails.
+version 1.0.9beta3 [November 23, 2000]
+ Revised PNG_LIBPNG_BUILD_TYPE macro in png.h, used in the msvc project.
+ Removed the png_flush() in pngwrite.c that crashes some applications
+ that don't set png_output_flush_fn.
+ Added makefile.macosx and makefile.aix to scripts directory.
+version 1.0.9beta4 [December 1, 2000]
+ Change png_chunk_warning to png_warning in png_check_keyword().
+ Increased the first part of msg buffer from 16 to 18 in png_chunk_error().
+version 1.0.9beta5 [December 15, 2000]
+ Added support for filter method 64 (for PNG datastreams embedded in MNG).
+version 1.0.9beta6 [December 18, 2000]
+ Revised png_set_filter() to accept filter method 64 when appropriate.
+ Added new PNG_HAVE_PNG_SIGNATURE bit to png_ptr->mode and use it to
+ help prevent applications from using MNG features in PNG datastreams.
+ Added png_permit_mng_features() function.
+ Revised libpng.3/libpng.txt. Changed "filter type" to "filter method".
+version 1.0.9rc1 [December 23, 2000]
+ Revised test for PNG_HAVE_PNG_SIGNATURE in pngrutil.c
+ Fixed error handling of unknown compression type in png_decompress_chunk().
+ In pngconf.h, define __cdecl when _MSC_VER is defined.
+version 1.0.9beta7 [December 28, 2000]
+ Changed PNG_TEXT_COMPRESSION_zTXt to PNG_COMPRESSION_TYPE_BASE several places.
+ Revised memory management in png_set_hIST and png_handle_hIST in a backward
+ compatible manner. PLTE and tRNS were revised similarly.
+ Revised the iCCP chunk reader to ignore trailing garbage.
+version 1.0.9beta8 [January 12, 2001]
+ Moved pngasmrd.h into pngconf.h.
+ Improved handling of out-of-spec garbage iCCP chunks generated by PhotoShop.
+version 1.0.9beta9 [January 15, 2001]
+ Added png_set_invalid, png_permit_mng_features, and png_mmx_supported to
+ wince and msvc project module definition files.
+ Minor revision of makefile.cygwin.
+ Fixed bug with progressive reading of narrow interlaced images in pngpread.c
+version 1.0.9beta10 [January 16, 2001]
+ Do not typedef png_FILE_p in pngconf.h when PNG_NO_STDIO is defined.
+ Fixed "png_mmx_supported" typo in project definition files.
+version 1.0.9beta11 [January 19, 2001]
+ Updated makefile.sgi to make shared library.
+ Removed png_mmx_support() function and disabled PNG_MNG_FEATURES_SUPPORTED
+ by default, for the benefit of DLL forward compatibility. These will
+ be re-enabled in version 1.2.0.
+version 1.0.9rc2 [January 22, 2001]
+ Revised cygwin support.
+version 1.0.9 [January 31, 2001]
+ Added check of cygwin's ALL_STATIC in pngconf.h
+ Added "-nommx" parameter to contrib/gregbook/rpng2-win and rpng2-x demos.
+version 1.0.10beta1 [March 14, 2001]
+ Revised makefile.dec, makefile.sgi, and makefile.sggcc; added makefile.hpgcc.
+ Reformatted libpng.3 to eliminate bad line breaks.
+ Added checks for _mmx_supported in the read_filter_row function of pnggccrd.c
+ Added prototype for png_mmx_support() near the top of pnggccrd.c
+ Moved some error checking from png_handle_IHDR to png_set_IHDR.
+ Added PNG_NO_READ_SUPPORTED and PNG_NO_WRITE_SUPPORTED macros.
+ Revised png_mmx_support() function in pnggccrd.c
+ Restored version 1.0.8 PNG_WRITE_EMPTY_PLTE_SUPPORTED behavior in pngwutil.c
+ Fixed memory leak in contrib/visupng/PngFile.c
+ Fixed bugs in png_combine_row() in pnggccrd.c and pngvcrd.c (C version)
+ Added warnings when retrieving or setting gamma=0.
+ Increased the first part of msg buffer from 16 to 18 in png_chunk_warning().
+version 1.0.10rc1 [March 23, 2001]
+ Changed all instances of memcpy, strcpy, and strlen to png_memcpy, png_strcpy,
+ and png_strlen.
+ Revised png_mmx_supported() function in pnggccrd.c to return proper value.
+ Fixed bug in progressive reading (pngpread.c) with small images (height < 8).
+version 1.0.10 [March 30, 2001]
+ Deleted extraneous space (introduced in 1.0.9) from line 42 of makefile.cygwin
+ Added beos project files (Chris Herborth)
+version 1.0.11beta1 [April 3, 2001]
+ Added type casts on several png_malloc() calls (Dimitri Papadapoulos).
+ Removed a no-longer needed AIX work-around from pngconf.h
+ Changed several "//" single-line comments to C-style in pnggccrd.c
+version 1.0.11beta2 [April 11, 2001]
+ Removed PNGAPI from several functions whose prototypes did not have PNGAPI.
+ Updated scripts/pngos2.def
+version 1.0.11beta3 [April 14, 2001]
+ Added checking the results of many instances of png_malloc() for NULL
+version 1.0.11beta4 [April 20, 2001]
+ Undid the changes from version 1.0.11beta3. Added a check for NULL return
+ from user's malloc_fn().
+ Removed some useless type casts of the NULL pointer.
+ Added makefile.netbsd
+version 1.0.11 [April 27, 2001]
+ Revised makefile.netbsd
+version 1.0.12beta1 [May 14, 2001]
+ Test for Windows platform in pngconf.h when including malloc.h (Emmanuel Blot)
+ Updated makefile.cygwin and handling of Cygwin's ALL_STATIC in pngconf.h
+ Added some never-to-be-executed code in pnggccrd.c to quiet compiler warnings.
+ Eliminated the png_error about apps using png_read|write_init(). Instead,
+ libpng will reallocate the png_struct and info_struct if they are too small.
+ This retains future binary compatibility for old applications written for
+ libpng-0.88 and earlier.
+version 1.2.0beta1 [May 6, 2001]
+ Bumped DLLNUM to 2.
+ Re-enabled PNG_MNG_FEATURES_SUPPORTED and enabled PNG_ASSEMBLER_CODE_SUPPORTED
+ by default.
+ Added runtime selection of MMX features.
+ Added png_set_strip_error_numbers function and related macros.
+version 1.2.0beta2 [May 7, 2001]
+ Finished merging 1.2.0beta1 with version 1.0.11
+ Added a check for attempts to read or write PLTE in grayscale PNG datastreams.
+version 1.2.0beta3 [May 17, 2001]
+ Enabled user memory function by default.
+ Modified png_create_struct so it passes user mem_ptr to user memory allocator.
+ Increased png_mng_features flag from png_byte to png_uint_32.
+ Bumped shared-library (so-number) and dll-number to 3.
+version 1.2.0beta4 [June 23, 2001]
+ Check for missing profile length field in iCCP chunk and free chunk_data
+ in case of truncated iCCP chunk.
+ Bumped shared-library number to 3 in makefile.sgi and makefile.sggcc
+ Bumped dll-number from 2 to 3 in makefile.cygwin
+ Revised contrib/gregbook/rpng*-x.c to avoid a memory leak and to exit cleanly
+ if user attempts to run it on an 8-bit display.
+ Updated contrib/gregbook
+ Use png_malloc instead of png_zalloc to allocate palette in pngset.c
+ Updated makefile.ibmc
+ Added some typecasts to eliminate gcc 3.0 warnings. Changed prototypes
+ of png_write_oFFS width and height from png_uint_32 to png_int_32.
+ Updated example.c
+ Revised prototypes for png_debug_malloc and png_debug_free in pngtest.c
+version 1.2.0beta5 [August 8, 2001]
+ Revised contrib/gregbook
+ Revised makefile.gcmmx
+ Revised pnggccrd.c to conditionally compile some thread-unsafe code only
+ when PNG_THREAD_UNSAFE_OK is defined.
+ Added tests to prevent pngwutil.c from writing a bKGD or tRNS chunk with
+ value exceeding 2^bit_depth-1
+ Revised makefile.sgi and makefile.sggcc
+ Replaced calls to fprintf(stderr,...) with png_warning() in pnggccrd.c
+ Removed restriction that do_invert_mono only operate on 1-bit opaque files
+version 1.2.0 [September 1, 2001]
+ Changed a png_warning() to png_debug() in pnggccrd.c
+ Fixed contrib/gregbook/rpng-x.c, rpng2-x.c to avoid crash with XFreeGC().
+version 1.2.1beta1 [October 19, 2001]
+ Revised makefile.std in contrib/pngminus
+ Include background_1 in png_struct regardless of gamma support.
+ Revised makefile.netbsd and makefile.macosx, added makefile.darwin.
+ Revised example.c to provide more details about using row_callback().
+version 1.2.1beta2 [October 25, 2001]
+ Added type cast to each NULL appearing in a function call, except for
+ WINCE functions.
+ Added makefile.so9.
+version 1.2.1beta3 [October 27, 2001]
+ Removed type casts from all NULLs.
+ Simplified png_create_struct_2().
+version 1.2.1beta4 [November 7, 2001]
+ Revised png_create_info_struct() and png_creat_struct_2().
+ Added error message if png_write_info() was omitted.
+ Type cast NULLs appearing in function calls when _NO_PROTO or
+ PNG_TYPECAST_NULL is defined.
+version 1.2.1rc1 [November 24, 2001]
+ Type cast NULLs appearing in function calls except when PNG_NO_TYPECAST_NULL
+ is defined.
+ Changed typecast of "size" argument to png_size_t in pngmem.c calls to
+ the user malloc_fn, to agree with the prototype in png.h
+ Added a pop/push operation to pnggccrd.c, to preserve Eflag (Maxim Sobolev)
+ Updated makefile.sgi to recognize LIBPATH and INCPATH.
+ Updated various makefiles so "make clean" does not remove previous major
+ version of the shared library.
+version 1.2.1rc2 [December 4, 2001]
+ Always allocate 256-entry internal palette, hist, and trans arrays, to
+ avoid out-of-bounds memory reference caused by invalid PNG datastreams.
+ Added a check for prefix_length > data_length in iCCP chunk handler.
+version 1.2.1 [December 7, 2001]
+ None.
+version 1.2.2beta1 [February 22, 2002]
+ Fixed a bug with reading the length of iCCP profiles (Larry Reeves).
+ Revised makefile.linux, makefile.gcmmx, and makefile.sgi to generate
+ libpng.a, libpng12.so (not libpng.so.3), and libpng12/png.h
+ Revised makefile.darwin to remove "-undefined suppress" option.
+ Added checks for gamma and chromaticity values over 21474.83, which exceed
+ the limit for PNG unsigned 32-bit integers when encoded.
+ Revised calls to png_create_read_struct() and png_create_write_struct()
+ for simpler debugging.
+ Revised png_zalloc() so zlib handles errors (uses PNG_FLAG_MALLOC_NULL_MEM_OK)
+version 1.2.2beta2 [February 23, 2002]
+ Check chunk_length and idat_size for invalid (over PNG_MAX_UINT) lengths.
+ Check for invalid image dimensions in png_get_IHDR.
+ Added missing "fi;" in the install target of the SGI makefiles.
+ Added install-static to all makefiles that make shared libraries.
+ Always do gamma compensation when image is partially transtqparent.
+version 1.2.2beta3 [March 7, 2002]
+ Compute background.gray and background_1.gray even when color_type is RGB
+ in case image gets reduced to gray later.
+ Modified shared-library makefiles to install pkgconfig/libpngNN.pc.
+ Export (with PNGAPI) png_zalloc, png_zfree, and png_handle_as_unknown
+ Removed unused png_write_destroy_info prototype from png.h
+ Eliminated incorrect use of width_mmx from pnggccrd.c in pixel_bytes == 8 case
+ Added install-shared target to all makefiles that make shared libraries.
+ Stopped a double free of palette, hist, and trans when not using free_me.
+ Added makefile.32sunu for Sun Ultra 32 and makefile.64sunu for Sun Ultra 64.
+version 1.2.2beta4 [March 8, 2002]
+ Compute background.gray and background_1.gray even when color_type is RGB
+ in case image gets reduced to gray later (Jason Summers).
+ Relocated a misplaced /bin/rm in the "install-shared" makefile targets
+ Added PNG_1_0_X macro which can be used to build a 1.0.x-compatible library.
+version 1.2.2beta5 [March 26, 2002]
+ Added missing PNGAPI to several function definitions.
+ Check for invalid bit_depth or color_type in png_get_IHDR(), and
+ check for missing PLTE or IHDR in png_push_read_chunk() (Matthias Clasen).
+ Revised iTXt support to accept NULL for lang and lang_key.
+ Compute gamma for color components of background even when color_type is gray.
+ Changed "()" to "{}" in scripts/libpng.pc.in.
+ Revised makefiles to put png.h and pngconf.h only in $prefix/include/libpngNN
+ Revised makefiles to make symlink to libpng.so.NN in addition to libpngNN.so
+version 1.2.2beta6 [March 31, 2002]
+version 1.0.13beta1 [March 31, 2002]
+ Prevent png_zalloc() from trying to memset memory that it failed to acquire.
+ Add typecasts of PNG_MAX_UINT in pngset_cHRM_fixed() (Matt Holgate).
+ Ensure that the right function (user or default) is used to free the
+ png_struct after an error in png_create_read_struct_2().
+version 1.2.2rc1 [April 7, 2002]
+version 1.0.13rc1 [April 7, 2002]
+ Save the ebx register in pnggccrd.c (Sami Farin)
+ Add "mem_ptr = png_ptr->mem_ptr" in png_destroy_write_struct() (Paul Gardner).
+ Updated makefiles to put headers in include/libpng and remove old include/*.h.
+version 1.2.2 [April 15, 2002]
+version 1.0.13 [April 15, 2002]
+ Revised description of png_set_filter() in libpng.3/libpng.txt.
+ Revised makefile.netbsd and added makefile.neNNbsd and makefile.freebsd
+version 1.0.13patch01 [April 17, 2002]
+version 1.2.2patch01 [April 17, 2002]
+ Changed ${PNGMAJ}.${PNGVER} bug to ${PNGVER} in makefile.sgi and makefile.sggcc
+ Fixed VER -> PNGVER typo in makefile.macosx and added install-static to install
+ Added install: target to makefile.32sunu and makefile.64sunu
+version 1.0.13patch03 [April 18, 2002]
+version 1.2.2patch03 [April 18, 2002]
+ Revised 15 makefiles to link libpng.a to libpngNN.a and the include libpng
+ subdirectory to libpngNN subdirectory without the full pathname.
+ Moved generation of libpng.pc from "install" to "all" in 15 makefiles.
+version 1.2.3rc1 [April 28, 2002]
+ Added install-man target to 15 makefiles (Dimitri Papadopolous-Orfanos).
+ Added $(DESTDIR) feature to 24 makefiles (Tim Mooney)
+ Fixed bug with $prefix, should be $(prefix) in makefile.hpux.
+ Updated cygwin-specific portion of pngconf.h and revised makefile.cygwin
+ Added a link from libpngNN.pc to libpng.pc in 15 makefiles.
+ Added links from include/libpngNN/*.h to include/*.h in 24 makefiles.
+ Revised makefile.darwin to make relative links without full pathname.
+ Added setjmp() at the end of png_create_*_struct_2() in case user forgets
+ to put one in their application.
+ Restored png_zalloc() and png_zfree() prototypes to version 1.2.1 and
+ removed them from module definition files.
+version 1.2.3rc2 [May 1, 2002]
+ Fixed bug in reporting number of channels in pngget.c and pngset.c,
+ that was introduced in version 1.2.2beta5.
+ Exported png_zalloc(), png_zfree(), png_default_read(), png_default_write(),
+ png_default_flush(), and png_push_fill_buffer() and included them in
+ module definition files.
+ Added "libpng.pc" dependency to the "install-shared" target in 15 makefiles.
+version 1.2.3rc3 [May 1, 2002]
+ Revised prototype for png_default_flush()
+ Remove old libpng.pc and libpngNN.pc before installing new ones.
+version 1.2.3rc4 [May 2, 2002]
+ Typos in *.def files (png_default_read|write -> png_default_read|write_data)
+ In makefiles, changed rm libpng.NN.pc to rm libpngNN.pc
+ Added libpng-config and libpngNN-config and modified makefiles to install them.
+ Changed $(MANPATH) to $(DESTDIR)$(MANPATH) in makefiles
+ Added "Win32 DLL VB" configuration to projects/msvc/libpng.dsp
+version 1.2.3rc5 [May 11, 2002]
+ Changed "error" and "message" in prototypes to "error_message" and
+ "warning_message" to avoid namespace conflict.
+ Revised 15 makefiles to build libpng-config from libpng-config-*.in
+ Once more restored png_zalloc and png_zfree to regular nonexported form.
+ Restored png_default_read|write_data, png_default_flush, png_read_fill_buffer
+ to nonexported form, but with PNGAPI, and removed them from module def files.
+version 1.2.3rc6 [May 14, 2002]
+ Removed "PNGAPI" from png_zalloc() and png_zfree() in png.c
+ Changed "Gz" to "Gd" in projects/msvc/libpng.dsp and zlib.dsp.
+ Removed leftover libpng-config "sed" script from four makefiles.
+ Revised libpng-config creating script in 16 makefiles.
+version 1.2.3 [May 22, 2002]
+ Revised libpng-config target in makefile.cygwin.
+ Removed description of png_set_mem_fn() from documentation.
+ Revised makefile.freebsd.
+ Minor cosmetic changes to 15 makefiles, e.g., $(DI) = $(DESTDIR)/$(INCDIR).
+ Revised projects/msvc/README.txt
+ Changed -lpng to -lpngNN in LDFLAGS in several makefiles.
+version 1.2.4beta1 [May 24, 2002]
+ Added libpng.pc and libpng-config to "all:" target in 16 makefiles.
+ Fixed bug in 16 makefiles: $(DESTDIR)/$(LIBPATH) to $(DESTDIR)$(LIBPATH)
+ Added missing "\" before closing double quote in makefile.gcmmx.
+ Plugged various memory leaks; added png_malloc_warn() and png_set_text_2()
+ functions.
+version 1.2.4beta2 [June 25, 2002]
+ Plugged memory leak of png_ptr->current_text (Matt Holgate).
+ Check for buffer overflow before reading CRC in pngpread.c (Warwick Allison)
+ Added -soname to the loader flags in makefile.dec, makefile.sgi, and
+ makefile.sggcc.
+ Added "test-installed" target to makefile.linux, makefile.gcmmx,
+ makefile.sgi, and makefile.sggcc.
+version 1.2.4beta3 [June 28, 2002]
+ Plugged memory leak of row_buf in pngtest.c when there is a png_error().
+ Detect buffer overflow in pngpread.c when IDAT is corrupted with extra data.
+ Added "test-installed" target to makefile.32sunu, makefile.64sunu,
+ makefile.beos, makefile.darwin, makefile.dec, makefile.macosx,
+ makefile.solaris, makefile.hpux, makefile.hpgcc, and makefile.so9.
+version 1.2.4rc1 and 1.0.14rc1 [July 2, 2002]
+ Added "test-installed" target to makefile.cygwin and makefile.sco.
+ Revised pnggccrd.c to be able to back out version 1.0.x via PNG_1_0_X macro.
+version 1.2.4 and 1.0.14 [July 8, 2002]
+ Changed png_warning() to png_error() when width is too large to process.
+version 1.2.4patch01 [July 20, 2002]
+ Revised makefile.cygwin to use DLL number 12 instead of 13.
+version 1.2.5beta1 [August 6, 2002]
+ Added code to contrib/gregbook/readpng2.c to ignore unused chunks.
+ Replaced toucan.png in contrib/gregbook (it has been corrupt since 1.0.11)
+ Removed some stray *.o files from contrib/gregbook.
+ Changed png_error() to png_warning() about "Too much data" in pngpread.c
+ and about "Extra compressed data" in pngrutil.c.
+ Prevent png_ptr->pass from exceeding 7 in png_push_finish_row().
+ Updated makefile.hpgcc
+ Updated png.c and pnggccrd.c handling of return from png_mmx_support()
+version 1.2.5beta2 [August 15, 2002]
+ Only issue png_warning() about "Too much data" in pngpread.c when avail_in
+ is nonzero.
+ Updated makefiles to install a separate libpng.so.3 with its own rpath.
+version 1.2.5rc1 and 1.0.15rc1 [August 24, 2002]
+ Revised makefiles to not remove previous minor versions of shared libraries.
+version 1.2.5rc2 and 1.0.15rc2 [September 16, 2002]
+ Revised 13 makefiles to remove "-lz" and "-L$(ZLIBLIB)", etc., from shared
+ library loader directive.
+ Added missing "$OBJSDLL" line to makefile.gcmmx.
+ Added missing "; fi" to makefile.32sunu.
+version 1.2.5rc3 and 1.0.15rc3 [September 18, 2002]
+ Revised libpng-config script.
+version 1.2.5 and 1.0.15 [October 3, 2002]
+ Revised makefile.macosx, makefile.darwin, makefile.hpgcc, and makefile.hpux,
+ and makefile.aix.
+ Relocated two misplaced PNGAPI lines in pngtest.c
+
+Send comments/corrections/commendations to
+png-implement@ccrc.wustl.edu or to randeg@alum.rpi.edu
+
+Glenn R-P
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/INSTALL b/tqtinterface/qt4/src/3rdparty/libpng/INSTALL
new file mode 100644
index 0000000..93980f3
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/INSTALL
@@ -0,0 +1,151 @@
+
+Installing libpng version 1.2.5 - October 3, 2002
+
+Before installing libpng, you must first install zlib. zlib
+can usually be found wherever you got libpng. zlib can be
+placed in another directory, at the same level as libpng.
+Note that your system might already have a preinstalled
+zlib, but you will still need to have access to the
+zlib.h and zconf.h include files that correspond to the
+version of zlib that's installed.
+
+You can rename the directories that you downloaded (they
+might be called "libpng-1.2.5" or "lpng109" and "zlib-1.1.4"
+or "zlib114") so that you have directories called "zlib" and "libpng".
+
+Your directory structure should look like this:
+
+ .. (the tqparent directory)
+ libpng (this directory)
+ INSTALL (this file)
+ README
+ *.h
+ *.c
+ contrib
+ gregbook
+ msvctest
+ pngminus
+ pngsuite
+ visupng
+ projects
+ beos
+ borland
+ msvc
+ netware.txt
+ wince.txt
+ scripts
+ makefile.*
+ libpng*.in
+ pngtest.png
+ etc.
+ zlib
+ README
+ *.h
+ *.c
+ contrib
+ etc.
+
+If the line endings in the files look funny, you may wish to get the other
+distribution of libpng. It is available in both tar.gz (UNIX style line
+endings) and zip (DOS style line endings) formats.
+
+If you are building libpng with MSVC, you can enter the libpng\msvc directory
+and follow the instructions in msvc\README.txt.
+
+You can build libpng for WindowsCE by entering the downloading and installing
+the libpng\wince directory as instructed in the projects\wince.txt file, and
+then following the instructions in the README* files. Similarly, you can
+build libpng for Netware as instructed in projects\netware.txt.
+
+Else enter the zlib directory and follow the instructions in zlib/README,
+then come back here and choose the appropriate makefile.sys in the scripts
+directory.
+
+The files that are presently available in the scripts directory
+include
+
+ makefile.std => Generic UNIX makefile (cc, creates static libpng.a)
+ makefile.linux => Linux/ELF makefile (gcc, creates libpng12.so.0.1.2.5)
+ makefile.gcmmx => Linux/ELF makefile (gcc, creates libpng12.so.0.1.2.5,
+ uses assembler code tuned for Intel MMX platform)
+ makefile.gcc => Generic makefile (gcc, creates static libpng.a)
+ makefile.knr => Archaic UNIX Makefile that converts files with
+ ansi2knr (Requires ansi2knr.c from
+ ftp://ftp.cs.wisc.edu/ghost)
+ makefile.aix => AIX/gcc makefile
+ makefile.cygwin => Cygwin/gcc makefile
+ makefile.darwin => Darwin makefile
+ makefile.dec => DEC Alpha UNIX makefile
+ makefile.hpgcc => FreeBSD makefile
+ makefile.hpgcc => HPUX makefile using gcc
+ makefile.hpux => HPUX (10.20 and 11.00) makefile
+ makefile.ibmc => IBM C/C++ version 3.x for Win32 and OS/2 (static)
+ makefile.intel => Intel C/C++ version 4.0 and later
+ libpng.icc => Project file for IBM VisualAge/C++ version 4.0 or later
+ makefile.macosx => MACOS X Makefile
+ makefile.netbsd => NetBSD/cc makefile, uses PNGGCCRD, makes libpng.so.
+ makefile.ne0bsd => NetBSD/cc makefile, uses PNGGCCRD, makes libpng0.so
+ makefile.openbsd => OpenBSD makefile
+ makefile.sgi => Silicon Graphics IRIX makefile (cc, creates static lib)
+ makefile.sggcc => Silicon Graphics (gcc, creates libpng12.so.0.1.2.5)
+ makefile.sunos => Sun makefile
+ makefile.solaris => Solaris 2.X makefile (gcc, creates libpng12.so.0.1.2.5)
+ makefile.so9 => Solaris 9 makefile (gcc, creates libpng12.so.0.1.2.5)
+ makefile.32sunu => Sun Ultra 32-bit makefile
+ makefile.64sunu => Sun Ultra 64-bit makefile
+ makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc
+ makefile.mips => MIPS makefile
+ makefile.acorn => Acorn makefile
+ makefile.amiga => Amiga makefile
+ smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
+ (Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
+ makefile.atari => Atari makefile
+ makefile.beos => BEOS makefile for X86
+ makefile.bor => Borland makefile (uses bcc)
+ makefile.bc32 => 32-bit Borland C++ (all modules compiled in C mode)
+ makefile.bd32 => To make a png32bd.dll with Borland C++ 4.5
+ makefile.tc3 => Turbo C 3.0 makefile
+ makefile.dj2 => DJGPP 2 makefile
+ makefile.msc => Microsoft C makefile
+ makefile.vcawin32 => makefile for Microsoft Visual C++ 5.0 and later (uses
+ assembler code tuned for Intel MMX platform)
+ makefile.vcwin32 => makefile for Microsoft Visual C++ 4.0 and later (does
+ not use assembler code)
+ makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def)
+ pngos2.def => OS/2 module definition file used by makefile.os2
+ makefile.watcom => Watcom 10a+ Makefile, 32-bit flat memory model
+ makevms.com => VMS build script
+ descrip.mms => VMS makefile for MMS or MMK
+ pngdef.pas => Defines for a png32bd.dll with Borland C++ 4.5
+ SCOPTIONS.ppc => Used with smakefile.ppc
+
+Copy the file (or files) that you need from the
+scripts directory into this directory, for example
+
+ MSDOS example: copy scripts\makefile.msc makefile
+ UNIX example: cp scripts/makefile.std makefile
+
+Read the makefile to see if you need to change any source or
+target directories to match your preferences.
+
+Then read pngconf.h to see if you want to make any configuration
+changes.
+
+Then just run "make test" which will create the libpng library in
+this directory and run a quick test that reads the "pngtest.png"
+file and writes a "pngout.png" file that should be identical to it.
+Look for "9782 zero samples" in the output of the test. For more
+confidence, you can run another test by typing "pngtest pngnow.png"
+and looking for "289 zero samples" in the output. Also, you can
+run "pngtest -m *.png" in the "contrib/pngsuite" directory and compare
+your output with the result shown in contrib/pngsuite/README.
+
+Most of the makefiles will allow you to run "make install" to
+put the library in its final resting place (if you want to
+do that, run "make install" in the zlib directory first if necessary).
+Some also allow you to run "make test-installed" after you have
+run "make install".
+
+Further information can be found in the README and libpng.txt
+files, in the individual makefiles, in png.h, in the README files in
+subdirectories of the LIB directory, and the manual pages libpng.3 and png.5.
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/KNOWNBUG b/tqtinterface/qt4/src/3rdparty/libpng/KNOWNBUG
new file mode 100644
index 0000000..3b81a6a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/KNOWNBUG
@@ -0,0 +1,11 @@
+
+Known bugs in libpng version 1.2.5
+
+1. April 22, 2001: pnggccrd.c has been reported to crash on NetBSD when
+ reading interlaced PNG files, when assembler code is enabled but running
+ on a non-MMX i386 platform.
+
+ STATUS: Under investigation. The change to pnggccrd.c in libpng-1.2.1
+ fixed a problem under FreeBSD but not the problem with NetBSD, which
+ still fails as of libpng-1.2.2rc1.
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/LICENSE b/tqtinterface/qt4/src/3rdparty/libpng/LICENSE
new file mode 100644
index 0000000..28b3b66
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/LICENSE
@@ -0,0 +1,102 @@
+
+This copy of the libpng notices is provided for your convenience. In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.
+
+COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson
+and are distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+ There is no warranty against interference with your enjoyment of the
+ library or against infringement. There is no warranty that our
+ efforts or the library will fulfill any of your particular purposes
+ or needs. This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and effort is with
+ the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+
+The PNG Reference Library is supplied "AS IS". The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose. The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and must not
+ be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from any
+ source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products. If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+ printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+randeg@alum.rpi.edu
+October 3, 2002
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/README b/tqtinterface/qt4/src/3rdparty/libpng/README
new file mode 100644
index 0000000..d7b6dd1
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/README
@@ -0,0 +1,269 @@
+README for libpng 1.2.5 - October 3, 2002 (shared library 12.0)
+See the note about version numbers near the top of png.h
+
+See INSTALL for instructions on how to install libpng.
+
+Libpng comes in two distribution formats. Get libpng-*.tar.gz if you
+want UNIX-style line endings in the text files, or lpng*.zip if you want
+DOS-style line endings.
+
+Version 0.89 was the first official release of libpng. Don't let the
+fact that it's the first release fool you. The libpng library has been in
+extensive use and testing since mid-1995. By late 1997 it had
+finally gotten to the stage where there hadn't been significant
+changes to the API in some time, and people have a bad feeling about
+libraries with versions < 1.0. Version 1.0.0 was released in
+March 1998.
+
+****
+Note that some of the changes to the png_info structure render this
+version of the library binary incompatible with libpng-0.89 or
+earlier versions if you are using a shared library. The type of the
+"filler" parameter for png_set_filler() has changed from png_byte to
+png_uint_32, which will affect shared-library applications that use
+this function.
+
+To avoid problems with changes to the internals of png_info_struct,
+new APIs have been made available in 0.95 to avoid direct application
+access to info_ptr. These functions are the png_set_<chunk> and
+png_get_<chunk> functions. These functions should be used when
+accessing/storing the info_struct data, rather than manipulating it
+directly, to avoid such problems in the future.
+
+It is important to note that the APIs do not make current programs
+that access the info struct directly incompatible with the new
+library. However, it is strongly suggested that new programs use
+the new APIs (as shown in example.c and pngtest.c), and older programs
+be converted to the new format, to facilitate upgrades in the future.
+****
+
+Additions since 0.90 include the ability to compile libpng as a
+Windows DLL, and new APIs for accessing data in the info struct.
+Experimental functions include the ability to set weighting and cost
+factors for row filter selection, direct reads of integers from buffers
+on big-endian processors that support misaligned data access, faster
+methods of doing alpha composition, and more accurate 16->8 bit color
+conversion.
+
+The additions since 0.89 include the ability to read from a PNG stream
+which has had some (or all) of the signature bytes read by the calling
+application. This also allows the reading of embedded PNG streams that
+do not have the PNG file signature. As well, it is now possible to set
+the library action on the detection of chunk CRC errors. It is possible
+to set different actions based on whether the CRC error occurred in a
+critical or an ancillary chunk.
+
+The changes made to the library, and bugs fixed are based on discussions
+on the PNG implementation mailing list <png-implement@ccrc.wustl.edu>
+and not on material submitted privately to Guy, Andreas, or Glenn. They will
+forward any good suggestions to the list.
+
+For a detailed description on using libpng, read libpng.txt. For
+examples of libpng in a program, see example.c and pngtest.c. For usage
+information and restrictions (what little they are) on libpng, see
+png.h. For a description on using zlib (the compression library used by
+libpng) and zlib's restrictions, see zlib.h
+
+I have included a general makefile, as well as several machine and
+compiler specific ones, but you may have to modify one for your own needs.
+
+You should use zlib 1.0.4 or later to run this, but it MAY work with
+versions as old as zlib 0.95. Even so, there are bugs in older zlib
+versions which can cause the output of invalid compression streams for
+some images. You will definitely need zlib 1.0.4 or later if you are
+taking advantage of the MS-DOS "far" structure allocation for the small
+and medium memory models. You should also note that zlib is a
+compression library that is useful for more things than just PNG files.
+You can use zlib as a drop-in tqreplacement for fread() and fwrite() if
+you are so inclined.
+
+zlib should be available at the same place that libpng is.
+If not, it should be at ftp.uu.net in /graphics/png
+Eventually, it will be at ftp.uu.net in /pub/archiving/zip/zlib
+
+You may also want a copy of the PNG specification. It is available
+as an RFC and a W3C Recommendation. Failing
+these resources you can try ftp.uu.net in the /graphics/png directory.
+
+This code is currently being archived at ftp.uu.net in the
+/graphics/png directory, and on CompuServe, Lib 20 (PNG SUPPORT)
+at GO GRAPHSUP. If you can't tqfind it in any of those places,
+e-mail me, and I'll help you tqfind it.
+
+If you have any code changes, requests, problems, etc., please e-mail
+them to me. Also, I'd appreciate any make files or project files,
+and any modifications you needed to make to get libpng to compile,
+along with a #define variable to tell what compiler/system you are on.
+If you needed to add transformations to libpng, or wish libpng would
+provide the image in a different way, drop me a note (and code, if
+possible), so I can consider supporting the transformation.
+Finally, if you get any warning messages when compiling libpng
+(note: not zlib), and they are easy to fix, I'd appreciate the
+fix. Please mention "libpng" somewhere in the subject line. Thanks.
+
+This release was created and will be supported by myself (of course
+based in a large way on Guy's and Andreas' earlier work), and the PNG group.
+
+randeg@alum.rpi.edu
+png-implement@ccrc.wustl.edu
+
+You can't reach Guy, the original libpng author, at the addresses
+given in previous versions of this document. He and Andreas will read mail
+addressed to the png-implement list, however.
+
+Please do not send general questions about PNG. Send them to
+the address in the specification (png-group@w3.org). At the same
+time, please do not send libpng questions to that address, send them to me
+or to png-implement@ccrc.wustl.edu. I'll
+get them in the end anyway. If you have a question about something
+in the PNG specification that is related to using libpng, send it
+to me. Send me any questions that start with "I was using libpng,
+and ...". If in doubt, send questions to me. I'll bounce them
+to others, if necessary.
+
+Please do not send suggestions on how to change PNG. We have
+been discussing PNG for three years now, and it is official and
+finished. If you have suggestions for libpng, however, I'll
+gladly listen. Even if your suggestion is not used for version
+1.0, it may be used later.
+
+Files in this distribution:
+
+ ANNOUNCE => Announcement of this version, with recent changes
+ CHANGES => Description of changes between libpng versions
+ KNOWNBUG => List of known bugs and deficiencies
+ LICENSE => License to use and redistribute libpng
+ README => This file
+ TODO => Things not implemented in the current library
+ Y2KINFO => Statement of Y2K compliance
+ example.c => Example code for using libpng functions
+ libpng.3 => manual page for libpng (includes libpng.txt)
+ libpng.txt => Description of libpng and its functions
+ libpngpf.3 => manual page for libpng's private functions
+ png.5 => manual page for the PNG format
+ png.c => Basic interface functions common to library
+ png.h => Library function and interface declarations
+ pngconf.h => System specific library configuration
+ pngasmrd.h => Header file for assembler-coded functions
+ pngerror.c => Error/warning message I/O functions
+ pngget.c => Functions for retrieving info from struct
+ pngmem.c => Memory handling functions
+ pngbar.png => PNG logo, 88x31
+ pngnow.png => PNG logo, 98x31
+ pngpread.c => Progressive reading functions
+ pngread.c => Read data/helper high-level functions
+ pngrio.c => Lowest-level data read I/O functions
+ pngrtran.c => Read data transformation functions
+ pngrutil.c => Read data utility functions
+ pngset.c => Functions for storing data into the info_struct
+ pngtest.c => Library test program
+ pngtest.png => Library test sample image
+ pngtrans.c => Common data transformation functions
+ pngwio.c => Lowest-level write I/O functions
+ pngwrite.c => High-level write functions
+ pngwtran.c => Write data transformations
+ pngwutil.c => Write utility functions
+ contrib => Contributions
+ gregbook => source code for PNG reading and writing, from
+ Greg Roelofs' "PNG: The Definitive Guide",
+ O'Reilly, 1999
+ msvctest => Builds and runs pngtest using a MSVC workspace
+ pngminus => Simple pnm2png and png2pnm programs
+ pngsuite => Test images
+ visupng => Contains a MSVC workspace for VisualPng
+ projects => Contains project files and workspaces for building DLL
+ beos => Contains a Beos workspace for building libpng
+ borland => Contains a Borland workspace for building libpng
+ and zlib
+ msvc => Contains a Microsoft Visual C++ (MSVC) workspace
+ for building libpng and zlib
+ netware.txt => Contains instructions for downloading a set of
+ project files for building libpng and zlib on
+ Netware.
+ wince.txt => Contains instructions for downloading a Microsoft
+ Visual C++ (Windows CD Toolkit) workspace for
+ building libpng and zlib on WindowsCE
+ scripts => Directory containing scripts for building libpng:
+ descrip.mms => VMS makefile for MMS or MMK
+ makefile.std => Generic UNIX makefile (cc, creates static libpng.a)
+ makefile.linux => Linux/ELF makefile
+ (gcc, creates libpng12.so.0.1.2.5)
+ makefile.gcmmx => Linux/ELF makefile (gcc, creates
+ libpng12.so.0.1.2.5, uses assembler code
+ tuned for Intel MMX platform)
+ makefile.gcc => Generic makefile (gcc, creates static libpng.a)
+ makefile.knr => Archaic UNIX Makefile that converts files with
+ ansi2knr (Requires ansi2knr.c from
+ ftp://ftp.cs.wisc.edu/ghost)
+ makefile.aix => AIX makefile
+ makefile.cygwin => Cygwin/gcc makefile
+ makefile.darwin => Darwin makefile
+ makefile.dec => DEC Alpha UNIX makefile
+ makefile.freebsd => FreeBSD makefile
+ makefile.hpgcc => HPUX makefile using gcc
+ makefile.hpux => HPUX (10.20 and 11.00) makefile
+ makefile.ibmc => IBM C/C++ version 3.x for Win32 and OS/2 (static)
+ makefile.intel => Intel C/C++ version 4.0 and later
+ libpng.icc => Project file, IBM VisualAge/C++ 4.0 or later
+ makefile.macosx => MACOS X Makefile
+ makefile.netbsd => NetBSD/cc makefile, PNGGCCRD, makes libpng.so.
+ makefile.ne0bsd => NetBSD/cc makefile, PNGGCCRD, makes libpng0.so
+ makefile.openbsd => OpenBSD makefile
+ makefile.sgi => Silicon Graphics IRIX (cc, creates static lib)
+ makefile.sggcc => Silicon Graphics (gcc, creates libpng12.so.0.1.2.5)
+ makefile.sunos => Sun makefile
+ makefile.solaris => Solaris 2.X makefile
+ (gcc, creates libpng12.so.0.1.2.5)
+ makefile.so9 => Solaris 9 makefile
+ (gcc, creates libpng12.so.0.1.2.5)
+ makefile.32sunu => Sun Ultra 32-bit makefile
+ makefile.64sunu => Sun Ultra 64-bit makefile
+ makefile.sco => For SCO OSr5 ELF and Unixware 7 with Native cc
+ makefile.mips => MIPS makefile
+ makefile.acorn => Acorn makefile
+ makefile.amiga => Amiga makefile
+ smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC
+ compiler (Requires SCOPTIONS, copied from
+ scripts/SCOPTIONS.ppc)
+ makefile.atari => Atari makefile
+ makefile.beos => BEOS makefile for X86
+ makefile.bor => Borland makefile (uses bcc)
+ makefile.bc32 => 32-bit Borland C++ (all modules compiled in C mode)
+ makefile.bd32 => To make a png32bd.dll with Borland C++ 4.5
+ makefile.tc3 => Turbo C 3.0 makefile
+ makefile.dj2 => DJGPP 2 makefile
+ makefile.msc => Microsoft C makefile
+ makefile.vcawin32 => makefile for Microsoft Visual C++ 5.0 and
+ later (uses assembler code tuned for Intel MMX
+ platform)
+ makefile.vcwin32 => makefile for Microsoft Visual C++ 4.0 and
+ later (does not use assembler code)
+ makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def)
+ pngos2.def => OS/2 module definition file used by makefile.os2
+ makefile.watcom => Watcom 10a+ Makefile, 32-bit flat memory model
+ makevms.com => VMS build script
+ pngdef.pas => Defines for a png32bd.dll with Borland C++ 4.5
+ SCOPTIONS.ppc => Used with smakefile.ppc
+ mangle => Directory containing scripts to build libpng12m.so:
+ mangle.in => Function-decoration macros added to png.h by the
+ makefiles.
+ makefile.linux => Linux/ELF makefile
+ (gcc, creates libpng12m.so.0.1.2.5)
+ makefile.gcmmx => Linux/ELF makefile (gcc, creates
+ libpng12.so.0m.1.2.5, uses assembler code
+ tuned for Intel MMX platform)
+ makefile.sgi => Silicon Graphics (cc, creates libpng12m.so)
+ makefile.sggcc => Silicon Graphics (gcc, creates libpng12m.so)
+
+Good luck, and happy coding.
+
+-Glenn Randers-Pehrson
+ Internet: randeg@alum.rpi.edu
+
+-Andreas Eric Dilger
+ Internet: adilger@enel.ucalgary.ca
+ Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/
+
+-Guy Eric Schalnat
+ (formerly of Group 42, Inc)
+ Internet: gschal@infinet.com
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/README.trolltech b/tqtinterface/qt4/src/3rdparty/libpng/README.trolltech
new file mode 100644
index 0000000..d443f80
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/README.trolltech
@@ -0,0 +1,15 @@
+This is libPNG 1.2.5, patched by Trolltech to fix a serious security vulnerability (CERT VU#388984)
+
+The patch is as follows:
+
+--- //depot/qt/3/src/3rdparty/libpng/pngrutil.c#4 Thu Aug 5 15:37:03 CEST 2004
++++ /home/dev/qt/3/src/3rdparty/libpng/pngrutil.c Thu Aug 5 15:37:03 CEST 2004
+@@ -1241,7 +1241,7 @@
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Missing PLTE before tRNS");
+ }
+- else if (length > (png_uint_32)png_ptr->num_palette)
++ if (length > (png_uint_32)png_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Incorrect tRNS chunk length");
+ png_crc_finish(png_ptr, length);
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/TODO b/tqtinterface/qt4/src/3rdparty/libpng/TODO
new file mode 100644
index 0000000..a5f6395
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/TODO
@@ -0,0 +1,24 @@
+TODO - list of things to do for libpng:
+
+Final bug fixes.
+Improve API by hiding the png_struct and png_info structs.
+Finish work on the no-floating-point version (including gamma compensation)
+Better C++ wrapper/full C++ implementation?
+Fix problem with C++ and EXTERN "C".
+cHRM transformation.
+Improve setjmp/longjmp usage or remove it in favor of returning error codes.
+Add "grayscale->palette" transformation and "palette->grayscale" detection.
+Improved dithering.
+Multi-lingual error and warning message support.
+Complete sRGB transformation (presently it simply uses gamma=0.45455).
+Man pages for function calls.
+Better documentation.
+Better filter selection
+ (counting huffman bits/precompression? filter inertia? filter costs?).
+Histogram creation.
+Text conversion between different code pages (Latin-1 -> Mac and DOS).
+Should we always malloc 2^bit_depth PLTE/tRNS/hIST entries for safety?
+Build gamma tables using fixed point (and do away with floating point entirely).
+Use greater precision when changing to linear gamma for compositing against
+ background and doing rgb-to-gray transformation.
+Investigate pre-incremented loop counters and other loop constructions.
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/Y2KINFO b/tqtinterface/qt4/src/3rdparty/libpng/Y2KINFO
new file mode 100644
index 0000000..f86ebd1
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/Y2KINFO
@@ -0,0 +1,55 @@
+ Y2K compliance in libpng:
+ =========================
+
+ October 3, 2002
+
+ Since the PNG Development group is an ad-hoc body, we can't make
+ an official declaration.
+
+ This is your unofficial assurance that libpng from version 0.71 and
+ upward through 1.2.5 are Y2K compliant. It is my belief that earlier
+ versions were also Y2K compliant.
+
+ Libpng only has three year fields. One is a 2-byte unsigned integer
+ that will hold years up to 65535. The other two hold the date in text
+ format, and will hold years up to 9999.
+
+ The integer is
+ "png_uint_16 year" in png_time_struct.
+
+ The strings are
+ "png_charp time_buffer" in png_struct and
+ "near_time_buffer", which is a local character string in png.c.
+
+ There are seven time-related functions:
+
+ png_convert_to_rfc_1123() in png.c
+ (formerly png_convert_to_rfc_1152() in error)
+ png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ png_convert_from_time_t() in pngwrite.c
+ png_get_tIME() in pngget.c
+ png_handle_tIME() in pngrutil.c, called in pngread.c
+ png_set_tIME() in pngset.c
+ png_write_tIME() in pngwutil.c, called in pngwrite.c
+
+ All appear to handle dates properly in a Y2K environment. The
+ png_convert_from_time_t() function calls gmtime() to convert from system
+ clock time, which returns (year - 1900), which we properly convert to
+ the full 4-digit year. There is a possibility that applications using
+ libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+ function, or that they are incorrectly passing only a 2-digit year
+ instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ but this is not under our control. The libpng documentation has always
+ stated that it works with 4-digit years, and the APIs have been
+ documented as such.
+
+ The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
+ integer to hold the year, and can hold years as large as 65535.
+
+ zlib, upon which libpng depends, is also Y2K compliant. It tqcontains
+ no date-related code.
+
+
+ Glenn Randers-Pehrson
+ libpng maintainer
+ PNG Development Group
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/configure b/tqtinterface/qt4/src/3rdparty/libpng/configure
new file mode 100755
index 0000000..ca05aca
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/configure
@@ -0,0 +1,6 @@
+echo "
+ There is no \"configure\" script for Libpng-1.2.5. Instead, please
+ copy the appropriate makefile for your system from the \"scripts\"
+ directory. Read the INSTALL file for more details.
+"
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/example.c b/tqtinterface/qt4/src/3rdparty/libpng/example.c
new file mode 100644
index 0000000..b39478a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/example.c
@@ -0,0 +1,804 @@
+
+#if 0 /* in case someone actually tries to compile this */
+
+/* example.c - an example of using libpng */
+
+/* This is an example of how to use libpng to read and write PNG files.
+ * The file libpng.txt is much more verbose then this. If you have not
+ * read it, do so first. This was designed to be a starting point of an
+ * implementation. This is not officially part of libpng, is hereby placed
+ * in the public domain, and therefore does not require a copyright notice.
+ *
+ * This file does not currently compile, because it is missing certain
+ * parts, like allocating memory to hold an image. You will have to
+ * supply these parts to get it to compile. For an example of a minimal
+ * working PNG reader/writer, see pngtest.c, included in this distribution;
+ * see also the programs in the contrib directory.
+ */
+
+#include "png.h"
+
+ /* The png_jmpbuf() macro, used in error handling, became available in
+ * libpng version 1.0.6. If you want to be able to run your code with older
+ * versions of libpng, you must define the macro yourself (but only if it
+ * is not already defined by libpng!).
+ */
+
+#ifndef png_jmpbuf
+# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#endif
+
+/* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp()
+ * returns zero if the image is a PNG and nonzero if it isn't a PNG.
+ *
+ * The function check_if_png() shown here, but not used, returns nonzero (true)
+ * if the file can be opened and is a PNG, 0 (false) otherwise.
+ *
+ * If this call is successful, and you are going to keep the file open,
+ * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
+ * you have created the png_ptr, so that libpng knows your application
+ * has read that many bytes from the start of the file. Make sure you
+ * don't call png_set_sig_bytes() with more than 8 bytes read or give it
+ * an incorrect number of bytes read, or you will either have read too
+ * many bytes (your fault), or you are telling libpng to read the wrong
+ * number of magic bytes (also your fault).
+ *
+ * Many applications already read the first 2 or 4 bytes from the start
+ * of the image to determine the file type, so it would be easiest just
+ * to pass the bytes to png_sig_cmp() or even skip that if you know
+ * you have a PNG file, and call png_set_sig_bytes().
+ */
+#define PNG_BYTES_TO_CHECK 4
+int check_if_png(char *file_name, FILE **fp)
+{
+ char buf[PNG_BYTES_TO_CHECK];
+
+ /* Open the prospective PNG file. */
+ if ((*fp = fopen(file_name, "rb")) == NULL)
+ return 0;
+
+ /* Read in some of the signature bytes */
+ if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
+ return 0;
+
+ /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
+ Return nonzero (true) if they match */
+
+ return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
+}
+
+/* Read a PNG file. You may want to return an error code if the read
+ * fails (depending upon the failure). There are two "prototypes" given
+ * here - one where we are given the filename, and we need to open the
+ * file, and the other where we are given an open file (possibly with
+ * some or all of the magic bytes read - see comments above).
+ */
+#ifdef open_file /* prototype 1 */
+void read_png(char *file_name) /* We need to open the file */
+{
+ png_structp png_ptr;
+ png_infop info_ptr;
+ unsigned int sig_read = 0;
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type;
+ FILE *fp;
+
+ if ((fp = fopen(file_name, "rb")) == NULL)
+ return (ERROR);
+#else no_open_file /* prototype 2 */
+void read_png(FILE *fp, unsigned int sig_read) /* file is already open */
+{
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type;
+#endif no_open_file /* only use one prototype! */
+
+ /* Create and initialize the png_struct with the desired error handler
+ * functions. If you want to use the default stderr and longjump method,
+ * you can supply NULL for the last three parameters. We also supply the
+ * the compiler header file version, so that we know if the application
+ * was compiled with a compatible version of the library. RETQUIRED
+ */
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+ png_voidp user_error_ptr, user_error_fn, user_warning_fn);
+
+ if (png_ptr == NULL)
+ {
+ fclose(fp);
+ return (ERROR);
+ }
+
+ /* Allocate/initialize the memory for image information. RETQUIRED. */
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL)
+ {
+ fclose(fp);
+ png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
+ return (ERROR);
+ }
+
+ /* Set error handling if you are using the setjmp/longjmp method (this is
+ * the normal method of doing things with libpng). RETQUIRED unless you
+ * set up your own error handlers in the png_create_read_struct() earlier.
+ */
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ /* Free all of the memory associated with the png_ptr and info_ptr */
+ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+ fclose(fp);
+ /* If we get here, we had a problem reading the file */
+ return (ERROR);
+ }
+
+ /* One of the following I/O initialization methods is RETQUIRED */
+#ifdef streams /* PNG file I/O method 1 */
+ /* Set up the input control if you are using standard C streams */
+ png_init_io(png_ptr, fp);
+
+#else no_streams /* PNG file I/O method 2 */
+ /* If you are using tqreplacement read functions, instead of calling
+ * png_init_io() here you would call:
+ */
+ png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
+ /* where user_io_ptr is a structure you want available to the callbacks */
+#endif no_streams /* Use only one I/O method! */
+
+ /* If we have already read some of the signature */
+ png_set_sig_bytes(png_ptr, sig_read);
+
+#ifdef hilevel
+ /*
+ * If you have enough memory to read in the entire image at once,
+ * and you need to specify only transforms that can be controlled
+ * with one of the PNG_TRANSFORM_* bits (this presently excludes
+ * dithering, filling, setting background, and doing gamma
+ * adjustment), then you can read the entire image (including
+ * pixels) into the info structure with this call:
+ */
+ png_read_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL);
+#else
+ /* OK, you're doing it the hard way, with the lower-level functions */
+
+ /* The call to png_read_info() gives us all of the information from the
+ * PNG file before the first IDAT (image data chunk). RETQUIRED
+ */
+ png_read_info(png_ptr, info_ptr);
+
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+ &interlace_type, int_p_NULL, int_p_NULL);
+
+/* Set up the data transformations you want. Note that these are all
+ * optional. Only call them if you want/need them. Many of the
+ * transformations only work on specific types of images, and many
+ * are mutually exclusive.
+ */
+
+ /* tell libpng to strip 16 bit/color files down to 8 bits/color */
+ png_set_strip_16(png_ptr);
+
+ /* Strip alpha bytes from the input data without combining with the
+ * background (not recommended).
+ */
+ png_set_strip_alpha(png_ptr);
+
+ /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
+ * byte into separate bytes (useful for paletted and grayscale images).
+ */
+ png_set_packing(png_ptr);
+
+ /* Change the order of packed pixels to least significant bit first
+ * (not useful if you are using png_set_packing). */
+ png_set_packswap(png_ptr);
+
+ /* Expand paletted colors into true RGB triplets */
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_palette_rgb(png_ptr);
+
+ /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
+ if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
+ png_set_gray_1_2_4_to_8(png_ptr);
+
+ /* Expand paletted or RGB images with transparency to full alpha channels
+ * so the data will be available as RGBA quartets.
+ */
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(png_ptr);
+
+ /* Set the background color to draw transtqparent and alpha images over.
+ * It is possible to set the red, green, and blue components directly
+ * for paletted images instead of supplying a palette index. Note that
+ * even if the PNG file supplies a background, you are not required to
+ * use it - you should use the (solid) application background if it has one.
+ */
+
+ png_color_16 my_background, *image_background;
+
+ if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+ png_set_background(png_ptr, image_background,
+ PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ else
+ png_set_background(png_ptr, &my_background,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+ /* Some suggestions as to how to get a screen gamma value */
+
+ /* Note that screen gamma is the display_exponent, which includes
+ * the CRT_exponent and any correction for viewing conditions */
+ if (/* We have a user-defined screen gamma value */)
+ {
+ screen_gamma = user-defined screen_gamma;
+ }
+ /* This is one way that applications share the same screen gamma value */
+ else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
+ {
+ screen_gamma = atof(gamma_str);
+ }
+ /* If we don't have another value */
+ else
+ {
+ screen_gamma = 2.2; /* A good guess for a PC monitors in a dimly
+ lit room */
+ screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */
+ }
+
+ /* Tell libpng to handle the gamma conversion for you. The final call
+ * is a good guess for PC generated images, but it should be configurable
+ * by the user at run time by the user. It is strongly suggested that
+ * your application support gamma correction.
+ */
+
+ int intent;
+
+ if (png_get_sRGB(png_ptr, info_ptr, &intent))
+ png_set_gamma(png_ptr, screen_gamma, 0.45455);
+ else
+ {
+ double image_gamma;
+ if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
+ png_set_gamma(png_ptr, screen_gamma, image_gamma);
+ else
+ png_set_gamma(png_ptr, screen_gamma, 0.45455);
+ }
+
+ /* Dither RGB files down to 8 bit palette or reduce palettes
+ * to the number of colors available on your screen.
+ */
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ int num_palette;
+ png_colorp palette;
+
+ /* This reduces the image to the application supplied palette */
+ if (/* we have our own palette */)
+ {
+ /* An array of colors to which the image should be dithered */
+ png_color std_color_cube[MAX_SCREEN_COLORS];
+
+ png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
+ MAX_SCREEN_COLORS, png_uint_16p_NULL, 0);
+ }
+ /* This reduces the image to the palette supplied in the file */
+ else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette))
+ {
+ png_uint_16p histogram = NULL;
+
+ png_get_hIST(png_ptr, info_ptr, &histogram);
+
+ png_set_dither(png_ptr, palette, num_palette,
+ max_screen_colors, histogram, 0);
+ }
+ }
+
+ /* invert monochrome files to have 0 as white and 1 as black */
+ png_set_invert_mono(png_ptr);
+
+ /* If you want to shift the pixel values from the range [0,255] or
+ * [0,65535] to the original [0,7] or [0,31], or whatever range the
+ * colors were originally in:
+ */
+ if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+ {
+ png_color_8p sig_bit;
+
+ png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+ png_set_shift(png_ptr, sig_bit);
+ }
+
+ /* flip the RGB pixels to BGR (or RGBA to BGRA) */
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ png_set_bgr(png_ptr);
+
+ /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+ png_set_swap_alpha(png_ptr);
+
+ /* swap bytes of 16 bit files to least significant byte first */
+ png_set_swap(png_ptr);
+
+ /* Add filler (or alpha) byte (before/after each RGB triplet) */
+ png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
+
+ /* Turn on interlace handling. RETQUIRED if you are not using
+ * png_read_image(). To see how to handle interlacing passes,
+ * see the png_read_row() method below:
+ */
+ number_passes = png_set_interlace_handling(png_ptr);
+
+ /* Optional call to gamma correct and add the background to the palette
+ * and update info structure. RETQUIRED if you are expecting libpng to
+ * update the palette for you (ie you selected such a transform above).
+ */
+ png_read_update_info(png_ptr, info_ptr);
+
+ /* Allocate the memory to hold the image using the fields of info_ptr. */
+
+ /* The easiest way to read the image: */
+ png_bytep row_pointers[height];
+
+ for (row = 0; row < height; row++)
+ {
+ row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
+ info_ptr));
+ }
+
+ /* Now it's time to read the image. One of these methods is RETQUIRED */
+#ifdef entire /* Read the entire image in one go */
+ png_read_image(png_ptr, row_pointers);
+
+#else no_entire /* Read the image one or more scanlines at a time */
+ /* The other way to read images - deal with interlacing: */
+
+ for (pass = 0; pass < number_passes; pass++)
+ {
+#ifdef single /* Read the image a single row at a time */
+ for (y = 0; y < height; y++)
+ {
+ png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL, 1);
+ }
+
+#else no_single /* Read the image several rows at a time */
+ for (y = 0; y < height; y += number_of_rows)
+ {
+#ifdef sparkle /* Read the image using the "sparkle" effect. */
+ png_read_rows(png_ptr, &row_pointers[y], png_bytepp_NULL,
+ number_of_rows);
+#else no_sparkle /* Read the image using the "rectangle" effect */
+ png_read_rows(png_ptr, png_bytepp_NULL, &row_pointers[y],
+ number_of_rows);
+#endif no_sparkle /* use only one of these two methods */
+ }
+
+ /* if you want to display the image after every pass, do
+ so here */
+#endif no_single /* use only one of these two methods */
+ }
+#endif no_entire /* use only one of these two methods */
+
+ /* read rest of file, and get additional chunks in info_ptr - RETQUIRED */
+ png_read_end(png_ptr, info_ptr);
+#endif hilevel
+
+ /* At this point you have read the entire image */
+
+ /* clean up after the read, and free any memory allocated - RETQUIRED */
+ png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
+
+ /* close the file */
+ fclose(fp);
+
+ /* that's it */
+ return (OK);
+}
+
+/* progressively read a file */
+
+int
+initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
+{
+ /* Create and initialize the png_struct with the desired error handler
+ * functions. If you want to use the default stderr and longjump method,
+ * you can supply NULL for the last three parameters. We also check that
+ * the library version is compatible in case we are using dynamically
+ * linked libraries.
+ */
+ *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+ png_voidp user_error_ptr, user_error_fn, user_warning_fn);
+
+ if (*png_ptr == NULL)
+ {
+ *info_ptr = NULL;
+ return (ERROR);
+ }
+
+ *info_ptr = png_create_info_struct(png_ptr);
+
+ if (*info_ptr == NULL)
+ {
+ png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL);
+ return (ERROR);
+ }
+
+ if (setjmp(png_jmpbuf((*png_ptr))))
+ {
+ png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL);
+ return (ERROR);
+ }
+
+ /* This one's new. You will need to provide all three
+ * function callbacks, even if you aren't using them all.
+ * If you aren't using all functions, you can specify NULL
+ * parameters. Even when all three functions are NULL,
+ * you need to call png_set_progressive_read_fn().
+ * These functions shouldn't be dependent on global or
+ * static variables if you are decoding several images
+ * simultaneously. You should store stream specific data
+ * in a separate struct, given as the second parameter,
+ * and retrieve the pointer from inside the callbacks using
+ * the function png_get_progressive_ptr(png_ptr).
+ */
+ png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
+ info_callback, row_callback, end_callback);
+
+ return (OK);
+}
+
+int
+process_data(png_structp *png_ptr, png_infop *info_ptr,
+ png_bytep buffer, png_uint_32 length)
+{
+ if (setjmp(png_jmpbuf((*png_ptr))))
+ {
+ /* Free the png_ptr and info_ptr memory on error */
+ png_destroy_read_struct(png_ptr, info_ptr, png_infopp_NULL);
+ return (ERROR);
+ }
+
+ /* This one's new also. Simply give it chunks of data as
+ * they arrive from the data stream (in order, of course).
+ * On Segmented machines, don't give it any more than 64K.
+ * The library seems to run fine with sizes of 4K, although
+ * you can give it much less if necessary (I assume you can
+ * give it chunks of 1 byte, but I haven't tried with less
+ * than 256 bytes yet). When this function returns, you may
+ * want to display any rows that were generated in the row
+ * callback, if you aren't already displaying them there.
+ */
+ png_process_data(*png_ptr, *info_ptr, buffer, length);
+ return (OK);
+}
+
+info_callback(png_structp png_ptr, png_infop info)
+{
+/* do any setup here, including setting any of the transformations
+ * mentioned in the Reading PNG files section. For now, you _must_
+ * call either png_start_read_image() or png_read_update_info()
+ * after all the transformations are set (even if you don't set
+ * any). You may start getting rows before png_process_data()
+ * returns, so this is your last chance to prepare for that.
+ */
+}
+
+row_callback(png_structp png_ptr, png_bytep new_row,
+ png_uint_32 row_num, int pass)
+{
+/*
+ * This function is called for every row in the image. If the
+ * image is interlaced, and you turned on the interlace handler,
+ * this function will be called for every row in every pass.
+ *
+ * In this function you will receive a pointer to new row data from
+ * libpng called new_row that is to tqreplace a corresponding row (of
+ * the same data format) in a buffer allocated by your application.
+ *
+ * The new row data pointer new_row may be NULL, indicating there is
+ * no new data to be tqreplaced (in cases of interlace loading).
+ *
+ * If new_row is not NULL then you need to call
+ * png_progressive_combine_row() to tqreplace the corresponding row as
+ * shown below:
+ */
+ /* Check if row_num is in bounds. */
+ if((row_num >= 0) && (row_num < height))
+ {
+ /* Get pointer to corresponding row in our
+ * PNG read buffer.
+ */
+ png_bytep old_row = ((png_bytep *)our_data)[row_num];
+
+ /* If both rows are allocated then copy the new row
+ * data to the corresponding row data.
+ */
+ if((old_row != NULL) && (new_row != NULL))
+ png_progressive_combine_row(png_ptr, old_row, new_row);
+ }
+/*
+ * The rows and passes are called in order, so you don't really
+ * need the row_num and pass, but I'm supplying them because it
+ * may make your life easier.
+ *
+ * For the non-NULL rows of interlaced images, you must call
+ * png_progressive_combine_row() passing in the new row and the
+ * old row, as demonstrated above. You can call this function for
+ * NULL rows (it will just return) and for non-interlaced images
+ * (it just does the png_memcpy for you) if it will make the code
+ * easier. Thus, you can just do this for all cases:
+ */
+
+ png_progressive_combine_row(png_ptr, old_row, new_row);
+
+/* where old_row is what was displayed for previous rows. Note
+ * that the first pass (pass == 0 really) will completely cover
+ * the old row, so the rows do not have to be initialized. After
+ * the first pass (and only for interlaced images), you will have
+ * to pass the current row as new_row, and the function will combine
+ * the old row and the new row.
+ */
+}
+
+end_callback(png_structp png_ptr, png_infop info)
+{
+/* this function is called when the whole image has been read,
+ * including any chunks after the image (up to and including
+ * the IEND). You will usually have the same info chunk as you
+ * had in the header, although some data may have been added
+ * to the comments and time fields.
+ *
+ * Most people won't do much here, perhaps setting a flag that
+ * marks the image as finished.
+ */
+}
+
+/* write a png file */
+void write_png(char *file_name /* , ... other image information ... */)
+{
+ FILE *fp;
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_colorp palette;
+
+ /* open the file */
+ fp = fopen(file_name, "wb");
+ if (fp == NULL)
+ return (ERROR);
+
+ /* Create and initialize the png_struct with the desired error handler
+ * functions. If you want to use the default stderr and longjump method,
+ * you can supply NULL for the last three parameters. We also check that
+ * the library version is compatible with the one used at compile time,
+ * in case we are using dynamically linked libraries. RETQUIRED.
+ */
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
+ png_voidp user_error_ptr, user_error_fn, user_warning_fn);
+
+ if (png_ptr == NULL)
+ {
+ fclose(fp);
+ return (ERROR);
+ }
+
+ /* Allocate/initialize the image information data. RETQUIRED */
+ info_ptr = png_create_info_struct(png_ptr);
+ if (info_ptr == NULL)
+ {
+ fclose(fp);
+ png_destroy_write_struct(&png_ptr, png_infopp_NULL);
+ return (ERROR);
+ }
+
+ /* Set error handling. RETQUIRED if you aren't supplying your own
+ * error handling functions in the png_create_write_struct() call.
+ */
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ /* If we get here, we had a problem reading the file */
+ fclose(fp);
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ return (ERROR);
+ }
+
+ /* One of the following I/O initialization functions is RETQUIRED */
+#ifdef streams /* I/O initialization method 1 */
+ /* set up the output control if you are using standard C streams */
+ png_init_io(png_ptr, fp);
+#else no_streams /* I/O initialization method 2 */
+ /* If you are using tqreplacement read functions, instead of calling
+ * png_init_io() here you would call */
+ png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,
+ user_IO_flush_function);
+ /* where user_io_ptr is a structure you want available to the callbacks */
+#endif no_streams /* only use one initialization method */
+
+#ifdef hilevel
+ /* This is the easy way. Use it if you already have all the
+ * image info living info in the structure. You could "|" many
+ * PNG_TRANSFORM flags into the png_transforms integer here.
+ */
+ png_write_png(png_ptr, info_ptr, png_transforms, png_voidp_NULL);
+#else
+ /* This is the hard way */
+
+ /* Set the image information here. Width and height are up to 2^31,
+ * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
+ * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
+ * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
+ * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
+ * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
+ * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. RETQUIRED
+ */
+ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,
+ PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+
+ /* set the palette if there is one. RETQUIRED for indexed-color images */
+ palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH
+ * sizeof (png_color));
+ /* ... set palette colors ... */
+ png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
+ /* You must not free palette here, because png_set_PLTE only makes a link to
+ the palette that you malloced. Wait until you are about to destroy
+ the png structure. */
+
+ /* optional significant bit chunk */
+ /* if we are dealing with a grayscale image then */
+ sig_bit.gray = true_bit_depth;
+ /* otherwise, if we are dealing with a color image then */
+ sig_bit.red = true_red_bit_depth;
+ sig_bit.green = true_green_bit_depth;
+ sig_bit.blue = true_blue_bit_depth;
+ /* if the image has an alpha channel then */
+ sig_bit.alpha = true_alpha_bit_depth;
+ png_set_sBIT(png_ptr, info_ptr, sig_bit);
+
+
+ /* Optional gamma chunk is strongly suggested if you have any guess
+ * as to the correct gamma of the image.
+ */
+ png_set_gAMA(png_ptr, info_ptr, gamma);
+
+ /* Optionally write comments into the image */
+ text_ptr[0].key = "Title";
+ text_ptr[0].text = "Mona Lisa";
+ text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
+ text_ptr[1].key = "Author";
+ text_ptr[1].text = "Leonardo DaVinci";
+ text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
+ text_ptr[2].key = "Description";
+ text_ptr[2].text = "<long text>";
+ text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr[0].lang = NULL;
+ text_ptr[1].lang = NULL;
+ text_ptr[2].lang = NULL;
+#endif
+ png_set_text(png_ptr, info_ptr, text_ptr, 3);
+
+ /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */
+ /* note that if sRGB is present the gAMA and cHRM chunks must be ignored
+ * on read and must be written in accordance with the sRGB profile */
+
+ /* Write the file header information. RETQUIRED */
+ png_write_info(png_ptr, info_ptr);
+
+ /* If you want, you can write the info in two steps, in case you need to
+ * write your private chunk ahead of PLTE:
+ *
+ * png_write_info_before_PLTE(write_ptr, write_info_ptr);
+ * write_my_chunk();
+ * png_write_info(png_ptr, info_ptr);
+ *
+ * However, given the level of known- and unknown-chunk support in 1.1.0
+ * and up, this should no longer be necessary.
+ */
+
+ /* Once we write out the header, the compression type on the text
+ * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
+ * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
+ * at the end.
+ */
+
+ /* set up the transformations you want. Note that these are
+ * all optional. Only call them if you want them.
+ */
+
+ /* invert monochrome pixels */
+ png_set_invert_mono(png_ptr);
+
+ /* Shift the pixels up to a legal bit depth and fill in
+ * as appropriate to correctly scale the image.
+ */
+ png_set_shift(png_ptr, &sig_bit);
+
+ /* pack pixels into bytes */
+ png_set_packing(png_ptr);
+
+ /* swap location of alpha bytes from ARGB to RGBA */
+ png_set_swap_alpha(png_ptr);
+
+ /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
+ * RGB (4 channels -> 3 channels). The second parameter is not used.
+ */
+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+
+ /* flip BGR pixels to RGB */
+ png_set_bgr(png_ptr);
+
+ /* swap bytes of 16-bit files to most significant byte first */
+ png_set_swap(png_ptr);
+
+ /* swap bits of 1, 2, 4 bit packed pixel formats */
+ png_set_packswap(png_ptr);
+
+ /* turn on interlace handling if you are not using png_write_image() */
+ if (interlacing)
+ number_passes = png_set_interlace_handling(png_ptr);
+ else
+ number_passes = 1;
+
+ /* The easiest way to write the image (you may have a different memory
+ * tqlayout, however, so choose what fits your needs best). You need to
+ * use the first method if you aren't handling interlacing yourself.
+ */
+ png_uint_32 k, height, width;
+ png_byte image[height][width*bytes_per_pixel];
+ png_bytep row_pointers[height];
+ for (k = 0; k < height; k++)
+ row_pointers[k] = image + k*width*bytes_per_pixel;
+
+ /* One of the following output methods is RETQUIRED */
+#ifdef entire /* write out the entire image data in one call */
+ png_write_image(png_ptr, row_pointers);
+
+ /* the other way to write the image - deal with interlacing */
+
+#else no_entire /* write out the image data by one or more scanlines */
+ /* The number of passes is either 1 for non-interlaced images,
+ * or 7 for interlaced images.
+ */
+ for (pass = 0; pass < number_passes; pass++)
+ {
+ /* Write a few rows at a time. */
+ png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows);
+
+ /* If you are only writing one row at a time, this works */
+ for (y = 0; y < height; y++)
+ {
+ png_write_rows(png_ptr, &row_pointers[y], 1);
+ }
+ }
+#endif no_entire /* use only one output method */
+
+ /* You can write optional chunks like tEXt, zTXt, and tIME at the end
+ * as well. Shouldn't be necessary in 1.1.0 and up as all the public
+ * chunks are supported and you can use png_set_unknown_chunks() to
+ * register unknown chunks into the info structure to be written out.
+ */
+
+ /* It is RETQUIRED to call this to finish writing the rest of the file */
+ png_write_end(png_ptr, info_ptr);
+#endif hilevel
+
+ /* If you png_malloced a palette, free it here (don't free info_ptr->palette,
+ as recommended in versions 1.0.5m and earlier of this example; if
+ libpng mallocs info_ptr->palette, libpng will free it). If you
+ allocated it with malloc() instead of png_malloc(), use free() instead
+ of png_free(). */
+ png_free(png_ptr, palette);
+ palette=NULL;
+
+ /* Similarly, if you png_malloced any data that you passed in with
+ png_set_something(), such as a hist or trans array, free it here,
+ when you can be sure that libpng is through with it. */
+ png_free(png_ptr, trans);
+ trans=NULL;
+
+ /* clean up after the write, and free any memory allocated */
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ /* close the file */
+ fclose(fp);
+
+ /* that's it */
+ return (OK);
+}
+
+#endif /* if 0 */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/libpng.3 b/tqtinterface/qt4/src/3rdparty/libpng/libpng.3
new file mode 100644
index 0000000..2f89149
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/libpng.3
@@ -0,0 +1,3958 @@
+.TH LIBPNG 3 "October 3, 2002"
+.SH NAME
+libpng \- Portable Network Graphics (PNG) Reference Library 1.2.5
+.SH SYNOPSIS
+\fI\fB
+
+\fB#include <png.h>\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_access_version_number \fI(void\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_check_sig (png_bytep \fP\fIsig\fP\fB, int \fInum\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_chunk_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_chunk_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_convert_from_struct_tm (png_timep \fP\fIptime\fP\fB, struct tm FAR * \fIttime\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_convert_from_time_t (png_timep \fP\fIptime\fP\fB, time_t \fIttime\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_charp png_convert_to_rfc1123 (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fIptime\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_infop png_create_info_struct (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_read_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_read_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_write_struct (png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarn_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_structp png_create_write_struct_2(png_const_charp \fP\fIuser_png_ver\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fP\fIwarn_fn\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug(int \fP\fIlevel\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug1(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fIp1\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_debug2(int \fP\fIlevel\fP\fB, png_const_charp \fP\fImessage\fP\fB, \fP\fIp1\fP\fB, \fIp2\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_info_struct (png_structp \fP\fIpng_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_read_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fP\fIinfo_ptr_ptr\fP\fB, png_infopp \fIend_info_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_write_struct (png_structpp \fP\fIpng_ptr_ptr\fP\fB, png_infopp \fIinfo_ptr_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_error (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fIerror\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_chunk_list (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_default(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fIptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_free_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fInum\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_asm_flags (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_bit_depth (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fI*background\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_channels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fI*white_x\fP\fB, double \fP\fI*white_y\fP\fB, double \fP\fI*red_x\fP\fB, double \fP\fI*red_y\fP\fB, double \fP\fI*green_x\fP\fB, double \fP\fI*green_y\fP\fB, double \fP\fI*blue_x\fP\fB, double \fI*blue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*white_x\fP\fB, png_uint_32 \fP\fI*white_y\fP\fB, png_uint_32 \fP\fI*red_x\fP\fB, png_uint_32 \fP\fI*red_y\fP\fB, png_uint_32 \fP\fI*green_x\fP\fB, png_uint_32 \fP\fI*green_y\fP\fB, png_uint_32 \fP\fI*blue_x\fP\fB, png_uint_32 \fI*blue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_color_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_compression_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_copyright (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_error_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_filter_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fI*file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fI*int_file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_header_ver (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_header_version (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fI*hist\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charpp \fP\fIname\fP\fB, int \fP\fI*compression_type\fP\fB, png_charpp \fP\fIprofile\fP\fB, png_uint_32 \fI*proflen\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*width\fP\fB, png_uint_32 \fP\fI*height\fP\fB, int \fP\fI*bit_depth\fP\fB, int \fP\fI*color_type\fP\fB, int \fP\fI*interlace_type\fP\fB, int \fP\fI*compression_type\fP\fB, int \fI*filter_type\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_image_height (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_image_width (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_interlace_type (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_io_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_libpng_ver (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_mem_ptr(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_mmx_bitdepth_threshold (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_mmx_flagtqmask (int \fP\fIflag_select\fP\fB, int \fI*compilerID\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_mmx_rowbytes_threshold (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*offset_x\fP\fB, png_uint_32 \fP\fI*offset_y\fP\fB, int \fI*unit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fI*purpose\fP\fB, png_int_32 \fP\fI*X0\fP\fB, png_int_32 \fP\fI*X1\fP\fB, int \fP\fI*type\fP\fB, int \fP\fI*nparams\fP\fB, png_charp \fP\fI*units\fP\fB, png_charpp \fI*params\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fI*res_x\fP\fB, png_uint_32 \fP\fI*res_y\fP\fB, int \fI*unit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBfloat png_get_pixel_aspect_ratio (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_progressive_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fI*palette\fP\fB, int \fI*num_palette\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_byte png_get_rgb_to_gray_status (png_structp \fIpng_ptr)
+
+\fBpng_uint_32 png_get_rowbytes (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_bytepp png_get_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fI*sig_bit\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_bytep png_get_signature (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fI*splt_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fI*intent\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fI*text_ptr\fP\fB, int \fI*num_text\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fI*mod_time\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fI*trans\fP\fB, int \fP\fI*num_trans\fP\fB, png_color_16p \fI*trans_values\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkpp \fIunknowns\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_user_chunk_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_get_user_transform_ptr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_valid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIflag\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_x_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_x_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_x_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_y_offset_microns (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_y_offset_pixels (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_y_pixels_per_meter (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_compression_buffer_size (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_handle_as_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_init_io (png_structp \fP\fIpng_ptr\fP\fB, FILE \fI*fp\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_info_init (png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_info_init_2 (png_infopp \fP\fIptr_ptr\fP\fB, png_size_t \fIpng_info_struct_size\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc_default(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_malloc_warn (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidp png_memcpy (png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_size_t \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_memcpy_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, png_voidp \fP\fIs2\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidp png_memset (png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_size_t \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_memset_check (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIs1\fP\fB, int \fP\fIvalue\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_mmx_support \fI(void\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_permit_empty_plte (png_structp \fP\fIpng_ptr\fP\fB, int \fIempty_plte_permitted\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_progressive_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIold_row\fP\fB, png_bytep \fInew_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_infop \fIend_info_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_read_init (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_read_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fIdisplay_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_bytepp \fP\fIdisplay_row\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_update_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_set_asm_flags (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIasm_flags\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_background (png_structp \fP\fIpng_ptr\fP\fB, png_color_16p \fP\fIbackground_color\fP\fB, int \fP\fIbackground_gamma_code\fP\fB, int \fP\fIneed_expand\fP\fB, double \fIbackground_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_bgr (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_16p \fIbackground\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_level (png_structp \fP\fIpng_ptr\fP\fB, int \fIlevel\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_mem_level (png_structp \fP\fIpng_ptr\fP\fB, int \fImem_level\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_method (png_structp \fP\fIpng_ptr\fP\fB, int \fImethod\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_strategy (png_structp \fP\fIpng_ptr\fP\fB, int \fIstrategy\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_window_bits (png_structp \fP\fIpng_ptr\fP\fB, int \fIwindow_bits\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_crc_action (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcrit_action\fP\fB, int \fIancil_action\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_dither (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fP\fInum_palette\fP\fB, int \fP\fImaximum_colors\fP\fB, png_uint_16p \fP\fIhistogram\fP\fB, int \fIfull_dither\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_error_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIerror_ptr\fP\fB, png_error_ptr \fP\fIerror_fn\fP\fB, png_error_ptr \fIwarning_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_expand (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_filler (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, int \fIflags\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_filter (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fImethod\fP\fB, int \fIfilters\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_filter_heuristics (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIheuristic_method\fP\fB, int \fP\fInum_weights\fP\fB, png_doublep \fP\fIfilter_weights\fP\fB, png_doublep \fIfilter_costs\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_flush (png_structp \fP\fIpng_ptr\fP\fB, int \fInrows\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gamma (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIscreen_gamma\fP\fB, double \fIdefault_file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIfile_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gray_1_2_4_to_8(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_gray_to_rgb (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_16p \fIhist\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, png_uint_32 \fIproflen\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_set_interlace_handling (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_invalid (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fItqmask\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_invert_alpha (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_invert_mono (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIinterlace_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fIfilter_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_keep_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIkeep\fP\fB, png_bytep \fP\fIchunk_list\fP\fB, int \fInum_chunks\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_mem_fn(png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fImem_ptr\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_free_ptr \fIfree_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_set_mmx_thresholds (png_structp \fP\fIpng_ptr\fP\fB, png_byte \fP\fImmx_bitdepth_threshold\fP\fB, png_uint_32 \fImmx_rowbytes_threshold\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIoffset_x\fP\fB, png_uint_32 \fP\fIoffset_y\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_packing (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_packswap (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_palette_to_rgb(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fP\fIres_x\fP\fB, png_uint_32 \fP\fIres_y\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_progressive_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIprogressive_ptr\fP\fB, png_progressive_info_ptr \fP\fIinfo_fn\fP\fB, png_progressive_row_ptr \fP\fIrow_fn\fP\fB, png_progressive_end_ptr \fIend_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fIread_data_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_read_status_ptr \fIread_row_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIread_user_transform_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_rgb_to_gray (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIerror_action\fP\fB, double \fP\fIred\fP\fB, double \fIgreen\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_rgb_to_gray_fixed (png_structp \fP\fIpng_ptr\fP\fB, int error_action png_fixed_point \fP\fIred\fP\fB, png_fixed_point \fIgreen\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_rows (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytepp \fIrow_pointers\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_color_8p \fIsig_bit\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_shift (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fItrue_bits\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sig_bytes (png_structp \fP\fIpng_ptr\fP\fB, int \fInum_bytes\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_spalette_p \fP\fIsplt_ptr\fP\fB, int \fInum_spalettes\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_sRGB_gAMA_and_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fIintent\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_strip_16 (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_strip_alpha (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_strip_error_numbers (png_structp \fIpng_ptr,
+
+\fBpng_uint_32 \fIstrip_mode\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_swap (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_swap_alpha (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_text (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fP\fInum_trans\fP\fB, png_color_16p \fItrans_values\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_tRNS_to_alpha(png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_set_unknown_chunks (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_unknown_chunkp \fP\fIunknowns\fP\fB, int \fP\fInum\fP\fB, int \fIlocation\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_unknown_chunk_location(png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fIchunk\fP\fB, int \fIlocation\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_read_user_chunk_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_chunk_ptr\fP\fB, png_user_chunk_ptr \fIread_user_chunk_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_user_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIuser_transform_ptr\fP\fB, int \fP\fIuser_transform_depth\fP\fB, int \fIuser_transform_channels\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_write_fn (png_structp \fP\fIpng_ptr\fP\fB, png_voidp \fP\fIio_ptr\fP\fB, png_rw_ptr \fP\fIwrite_data_fn\fP\fB, png_flush_ptr \fIoutput_flush_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_write_status_fn (png_structp \fP\fIpng_ptr\fP\fB, png_write_status_ptr \fIwrite_row_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_write_user_transform_fn (png_structp \fP\fIpng_ptr\fP\fB, png_user_transform_ptr \fIwrite_user_transform_fn\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_set_compression_buffer_size(png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_sig_cmp (png_bytep \fP\fIsig\fP\fB, png_size_t \fP\fIstart\fP\fB, png_size_t \fInum_to_check\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_start_read_image (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_warning (png_structp \fP\fIpng_ptr\fP\fB, png_const_charp \fImessage\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk_end (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_chunk_start (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIchunk_name\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_destroy (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_flush (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_image (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fIimage\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_write_init (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBDEPRECATED: void png_write_init_2 (png_structpp \fP\fIptr_ptr\fP\fB, png_const_charp \fP\fIuser_png_ver\fP\fB, png_size_t \fP\fIpng_struct_size\fP\fB, png_size_t \fIpng_info_size\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_info_before_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_png (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, int \fP\fItransforms\fP\fB, png_voidp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_rows (png_structp \fP\fIpng_ptr\fP\fB, png_bytepp \fP\fIrow\fP\fB, png_uint_32 \fInum_rows\fP\fB);\fP
+
+\fI\fB
+
+.SH DESCRIPTION
+The
+.I libpng
+library supports encoding, decoding, and various manipulations of
+the Portable Network Graphics (PNG) format image files. It uses the
+.IR zlib(3)
+compression library.
+Following is a copy of the libpng.txt file that accompanies libpng.
+.SH LIBPNG.TXT
+libpng.txt - A description on how to use and modify libpng
+
+ libpng version 1.2.5 - October 3, 2002
+ Updated and distributed by Glenn Randers-Pehrson
+ <randeg@alum.rpi.edu>
+ Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ For conditions of distribution and use, see copyright
+ notice in png.h.
+
+ based on:
+
+ libpng 1.0 beta 6 version 0.96 May 28, 1997
+ Updated and distributed by Andreas Dilger
+ Copyright (c) 1996, 1997 Andreas Dilger
+
+ libpng 1.0 beta 2 - version 0.88 January 26, 1996
+ For conditions of distribution and use, see copyright
+ notice in png.h. Copyright (c) 1995, 1996 Guy Eric
+ Schalnat, Group 42, Inc.
+
+ Updated/rewritten per request in the libpng FAQ
+ Copyright (c) 1995, 1996 Frank J. T. Wojcik
+ December 18, 1995 & January 20, 1996
+
+.SH I. Introduction
+
+This file describes how to use and modify the PNG reference library
+(known as libpng) for your own use. There are five sections to this
+file: introduction, structures, reading, writing, and modification and
+configuration notes for various special platforms. In addition to this
+file, example.c is a good starting point for using the library, as
+it is heavily commented and should include everything most people
+will need. We assume that libpng is already installed; see the
+INSTALL file for instructions on how to install libpng.
+
+Libpng was written as a companion to the PNG specification, as a way
+of reducing the amount of time and effort it takes to support the PNG
+file format in application programs.
+
+The PNG-1.2 specification is available at <http://www.libpng.org/pub/png>
+and at <ftp://ftp.uu.net/graphics/png/documents/>.
+
+The PNG-1.0 specification is available
+as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> and as a
+W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
+additional chunks are described in the special-purpose public chunks
+documents at <ftp://ftp.uu.net/graphics/png/documents/>.
+
+Other information
+about PNG, and the latest version of libpng, can be found at the PNG home
+page, <http://www.libpng.org/pub/png/>
+and at <ftp://ftp.uu.net/graphics/png/>.
+
+Most users will not have to modify the library significantly; advanced
+users may want to modify it more. All attempts were made to make it as
+complete as possible, while keeping the code easy to understand.
+Currently, this library only supports C. Support for other languages
+is being considered.
+
+Libpng has been designed to handle multiple sessions at one time,
+to be easily modifiable, to be portable to the vast majority of
+machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
+to use. The ultimate goal of libpng is to promote the acceptance of
+the PNG file format in whatever way possible. While there is still
+work to be done (see the TODO file), libpng should cover the
+majority of the needs of its users.
+
+Libpng uses zlib for its compression and decompression of PNG files.
+Further information about zlib, and the latest version of zlib, can
+be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
+The zlib compression utility is a general purpose utility that is
+useful for more than PNG files, and can be used without libpng.
+See the documentation delivered with zlib for more details.
+You can usually tqfind the source files for the zlib utility wherever you
+tqfind the libpng source files.
+
+Libpng is thread safe, provided the threads are using different
+instances of the structures. Each thread should have its own
+png_struct and png_info instances, and thus its own image.
+Libpng does not protect itself against two threads using the
+same instance of a structure. Note: thread safety may be defeated
+by use of some of the MMX assembler code in pnggccrd.c, which is only
+compiled when the user defines PNG_THREAD_UNSAFE_OK.
+
+
+.SH II. Structures
+
+There are two main structures that are important to libpng, png_struct
+and png_info. The first, png_struct, is an internal structure that
+will not, for the most part, be used by a user except as the first
+variable passed to every libpng function call.
+
+The png_info structure is designed to provide information about the
+PNG file. At one time, the fields of png_info were intended to be
+directly accessible to the user. However, this tended to cause problems
+with applications using dynamically loaded libraries, and as a result
+a set of interface functions for png_info (the png_get_*() and png_set_*()
+functions) was developed. The fields of png_info are still available for
+older applications, but it is suggested that applications use the new
+interfaces if at all possible.
+
+Applications that do make direct access to the members of png_struct (except
+for png_ptr->jmpbuf) must be recompiled whenever the library is updated,
+and applications that make direct access to the members of png_info must
+be recompiled if they were compiled or loaded with libpng version 1.0.6,
+in which the members were in a different order. In version 1.0.7, the
+members of the png_info structure reverted to the old order, as they were
+in versions 0.97c through 1.0.5. Starting with version 2.0.0, both
+structures are going to be hidden, and the contents of the structures will
+only be accessible through the png_get/png_set functions.
+
+The png.h header file is an invaluable reference for programming with libpng.
+And while I'm on the topic, make sure you include the libpng header file:
+
+#include <png.h>
+
+.SH III. Reading
+
+We'll now walk you through the possible functions to call when reading
+in a PNG file sequentially, briefly explaining the syntax and purpose
+of each one. See example.c and png.h for more detail. While
+progressive reading is covered in the next section, you will still
+need some of the functions discussed in this section to read a PNG
+file.
+
+.SS Setup
+
+You will want to do the I/O initialization(*) before you get into libpng,
+so if it doesn't work, you don't have much to undo. Of course, you
+will also want to insure that you are, in fact, dealing with a PNG
+file. Libpng provides a simple check to see if a file is a PNG file.
+To use it, pass in the first 1 to 8 bytes of the file to the function
+png_sig_cmp(), and it will return 0 if the bytes match the corresponding
+bytes of the PNG signature, or nonzero otherwise. Of course, the more bytes
+you pass in, the greater the accuracy of the prediction.
+
+If you are intending to keep the file pointer open for use in libpng,
+you must ensure you don't read more than 8 bytes from the beginning
+of the file, and you also have to make a call to png_set_sig_bytes_read()
+with the number of bytes you read from the beginning. Libpng will
+then only check the bytes (if any) that your program didn't read.
+
+(*): If you are not using the standard I/O functions, you will need
+to tqreplace them with custom functions. See the discussion under
+Customizing libpng.
+
+
+ FILE *fp = fopen(file_name, "rb");
+ if (!fp)
+ {
+ return (ERROR);
+ }
+ fread(header, 1, number, fp);
+ is_png = !png_sig_cmp(header, 0, number);
+ if (!is_png)
+ {
+ return (NOT_PNG);
+ }
+
+
+Next, png_struct and png_info need to be allocated and initialized. In
+order to ensure that the size of these structures is correct even with a
+dynamically linked libpng, there are functions to initialize and
+allocate the structures. We also pass the library version, optional
+pointers to error handling functions, and a pointer to a data struct for
+use by the error functions, if necessary (the pointer and functions can
+be NULL if the default error handlers are to be used). See the section
+on Changes to Libpng below regarding the old initialization functions.
+The structure allocation functions quietly return NULL if they fail to
+create the structure, so your application should check for that.
+
+ png_structp png_ptr = png_create_read_struct
+ (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+ user_error_fn, user_warning_fn);
+ if (!png_ptr)
+ return (ERROR);
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_read_struct(&png_ptr,
+ (png_infopp)NULL, (png_infopp)NULL);
+ return (ERROR);
+ }
+
+ png_infop end_info = png_create_info_struct(png_ptr);
+ if (!end_info)
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ (png_infopp)NULL);
+ return (ERROR);
+ }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_read_struct_2() instead of png_create_read_struct():
+
+ png_structp png_ptr = png_create_read_struct_2
+ (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+ user_error_fn, user_warning_fn, (png_voidp)
+ user_mem_ptr, user_malloc_fn, user_free_fn);
+
+The error handling routines passed to png_create_read_struct()
+and the memory alloc/free routines passed to png_create_struct_2()
+are only necessary if you are not using the libpng supplied error
+handling and memory alloc/free functions.
+
+When libpng encounters an error, it expects to longjmp back
+to your routine. Therefore, you will need to call setjmp and pass
+your png_jmpbuf(png_ptr). If you read the file from different
+routines, you will need to update the jmpbuf field every time you enter
+a new routine that will call a png_*() function.
+
+See your documentation of setjmp/longjmp for your compiler for more
+information on setjmp/longjmp. See the discussion on libpng error
+handling in the Customizing Libpng section below for more information
+on the libpng error handling. If an error occurs, and libpng longjmp's
+back to your setjmp, you will want to call png_destroy_read_struct() to
+free any memory.
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ &end_info);
+ fclose(fp);
+ return (ERROR);
+ }
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the input code. The default for libpng is to
+use the C function fread(). If you use this, you will need to pass a
+valid FILE * in the function png_init_io(). Be sure that the file is
+opened in binary mode. If you wish to handle reading data in another
+way, you need not call the png_init_io() function, but you must then
+implement the libpng I/O methods discussed in the Customizing Libpng
+section below.
+
+ png_init_io(png_ptr, fp);
+
+If you had previously opened the file and read any of the signature from
+the beginning in order to see if this was a PNG file, you need to let
+libpng know that there are some bytes missing from the start of the file.
+
+ png_set_sig_bytes(png_ptr, number);
+
+.SS Setting up callback code
+
+You can set up a callback function to handle any unknown chunks in the
+input stream. You must supply the function
+
+ read_chunk_callback(png_ptr ptr,
+ png_unknown_chunkp chunk);
+ {
+ /* The unknown chunk structure tqcontains your
+ chunk data: */
+ png_byte name[5];
+ png_byte *data;
+ png_size_t size;
+ /* Note that libpng has already taken care of
+ the CRC handling */
+
+ /* put your code here. Return one of the
+ following: */
+
+ return (-n); /* chunk had an error */
+ return (0); /* did not recognize */
+ return (n); /* success */
+ }
+
+(You can give your function another name that you like instead of
+"read_chunk_callback")
+
+To inform libpng about your function, use
+
+ png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,
+ read_chunk_callback);
+
+This names not only the callback function, but also a user pointer that
+you can retrieve with
+
+ png_get_user_chunk_ptr(png_ptr);
+
+At this point, you can set up a callback function that will be
+called after each row has been read, which you can use to control
+a progress meter or the like. It's demonstrated in pngtest.c.
+You must supply a function
+
+ void read_row_callback(png_ptr ptr, png_uint_32 row,
+ int pass);
+ {
+ /* put your code here */
+ }
+
+(You can give it another name that you like instead of "read_row_callback")
+
+To inform libpng about your function, use
+
+ png_set_read_status_fn(png_ptr, read_row_callback);
+
+.SS Unknown-chunk handling
+
+Now you get to set the way the library processes unknown chunks in the
+input PNG stream. Both known and unknown chunks will be read. Normal
+behavior is that known chunks will be parsed into information in
+various info_ptr members; unknown chunks will be discarded. To change
+this, you can call:
+
+ png_set_keep_unknown_chunks(png_ptr, info_ptr, keep,
+ chunk_list, num_chunks);
+ keep - 0: do not keep
+ 1: keep only if safe-to-copy
+ 2: keep even if unsafe-to-copy
+ chunk_list - list of chunks affected (a byte string,
+ five bytes per chunk, NULL or '\0' if
+ num_chunks is 0)
+ num_chunks - number of chunks affected; if 0, all
+ unknown chunks are affected
+
+Unknown chunks declared in this way will be saved as raw data onto a
+list of png_unknown_chunk structures. If a chunk that is normally
+known to libpng is named in the list, it will be handled as unknown,
+according to the "keep" directive. If a chunk is named in successive
+instances of png_set_keep_unknown_chunks(), the final instance will
+take precedence.
+
+.SS The high-level read interface
+
+At this point there are two ways to proceed; through the high-level
+read interface, or through a sequence of low-level read operations.
+You can use the high-level interface if (a) you are willing to read
+the entire image into memory, and (b) the input transformations
+you want to do are limited to the following set:
+
+ PNG_TRANSFORM_IDENTITY No transformation
+ PNG_TRANSFORM_STRIP_16 Strip 16-bit samples to
+ 8 bits
+ PNG_TRANSFORM_STRIP_ALPHA Discard the alpha channel
+ PNG_TRANSFORM_PACKING Expand 1, 2 and 4-bit
+ samples to bytes
+ PNG_TRANSFORM_PACKSWAP Change order of packed
+ pixels to LSB first
+ PNG_TRANSFORM_EXPAND Perform set_expand()
+ PNG_TRANSFORM_INVERT_MONO Invert monochrome images
+ PNG_TRANSFORM_SHIFT Normalize pixels to the
+ sBIT depth
+ PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA
+ to BGRA
+ PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA
+ to AG
+ PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity
+ to transparency
+ PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples
+
+(This excludes setting a background color, doing gamma transformation,
+dithering, and setting filler.) If this is the case, simply do this:
+
+ png_read_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of
+some set of transformation flags. This call is equivalent to png_read_info(),
+followed the set of transformations indicated by the transform tqmask,
+then png_read_image(), and finally png_read_end().
+
+(The final parameter of this call is not yet used. Someday it might point
+to transformation parameters required by some future input transform.)
+
+After you have called png_read_png(), you can retrieve the image data
+with
+
+ row_pointers = png_get_rows(png_ptr, info_ptr);
+
+where row_pointers is an array of pointers to the pixel data for each row:
+
+ png_bytep row_pointers[height];
+
+If you know your image size and pixel size ahead of time, you can allocate
+row_pointers prior to calling png_read_png() with
+
+ row_pointers = png_malloc(png_ptr,
+ height*sizeof(png_bytep));
+ for (int i=0; i<height, i++)
+ row_pointers[i]=png_malloc(png_ptr,
+ width*pixel_size);
+ png_set_rows(png_ptr, info_ptr, &row_pointers);
+
+Alternatively you could allocate your image in one big block and define
+row_pointers[i] to point into the proper places in your block.
+
+If you use png_set_rows(), the application is responsible for freeing
+row_pointers (and row_pointers[i], if they were separately allocated).
+
+If you don't allocate row_pointers ahead of time, png_read_png() will
+do it, and it'll be free'ed when you call png_destroy_*().
+
+.SS The low-level read interface
+
+If you are going the low-level route, you are now ready to read all
+the file information up to the actual image data. You do this with a
+call to png_read_info().
+
+ png_read_info(png_ptr, info_ptr);
+
+This will process all chunks up to but not including the image data.
+
+.SS Querying the info structure
+
+Functions are used to get the information from the info_ptr once it
+has been read. Note that these fields may not be completely filled
+in until png_read_end() has read the chunk data following the image.
+
+ png_get_IHDR(png_ptr, info_ptr, &width, &height,
+ &bit_depth, &color_type, &interlace_type,
+ &compression_type, &filter_method);
+
+ width - holds the width of the image
+ in pixels (up to 2^31).
+ height - holds the height of the image
+ in pixels (up to 2^31).
+ bit_depth - holds the bit depth of one of the
+ image channels. (valid values are
+ 1, 2, 4, 8, 16 and depend also on
+ the color_type. See also
+ significant bits (sBIT) below).
+ color_type - describes which color/alpha channels
+ are present.
+ PNG_COLOR_TYPE_GRAY
+ (bit depths 1, 2, 4, 8, 16)
+ PNG_COLOR_TYPE_GRAY_ALPHA
+ (bit depths 8, 16)
+ PNG_COLOR_TYPE_PALETTE
+ (bit depths 1, 2, 4, 8)
+ PNG_COLOR_TYPE_RGB
+ (bit_depths 8, 16)
+ PNG_COLOR_TYPE_RGB_ALPHA
+ (bit_depths 8, 16)
+
+ PNG_COLOR_MASK_PALETTE
+ PNG_COLOR_MASK_COLOR
+ PNG_COLOR_MASK_ALPHA
+
+ filter_method - (must be PNG_FILTER_TYPE_BASE
+ for PNG 1.0, and can also be
+ PNG_INTRAPIXEL_DIFFERENCING if
+ the PNG datastream is embedded in
+ a MNG-1.0 datastream)
+ compression_type - (must be PNG_COMPRESSION_TYPE_BASE
+ for PNG 1.0)
+ interlace_type - (PNG_INTERLACE_NONE or
+ PNG_INTERLACE_ADAM7)
+ Any or all of interlace_type, compression_type, of
+ filter_method can be NULL if you are
+ not interested in their values.
+
+ channels = png_get_channels(png_ptr, info_ptr);
+ channels - number of channels of info for the
+ color type (valid values are 1 (GRAY,
+ PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
+ 4 (RGB_ALPHA or RGB + filler byte))
+ rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+ rowbytes - number of bytes needed to hold a row
+
+ signature = png_get_signature(png_ptr, info_ptr);
+ signature - holds the signature read from the
+ file (if any). The data is kept in
+ the same offset it would be if the
+ whole signature were read (i.e. if an
+ application had already read in 4
+ bytes of signature before starting
+ libpng, the remaining 4 bytes would
+ be in signature[4] through signature[7]
+ (see png_set_sig_bytes())).
+
+
+ width = png_get_image_width(png_ptr,
+ info_ptr);
+ height = png_get_image_height(png_ptr,
+ info_ptr);
+ bit_depth = png_get_bit_depth(png_ptr,
+ info_ptr);
+ color_type = png_get_color_type(png_ptr,
+ info_ptr);
+ filter_method = png_get_filter_type(png_ptr,
+ info_ptr);
+ compression_type = png_get_compression_type(png_ptr,
+ info_ptr);
+ interlace_type = png_get_interlace_type(png_ptr,
+ info_ptr);
+
+
+These are also important, but their validity depends on whether the chunk
+has been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
+png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
+data has been read, or zero if it is missing. The parameters to the
+png_get_<chunk> are set directly if they are simple data types, or a pointer
+into the info_ptr is returned for any complex types.
+
+ png_get_PLTE(png_ptr, info_ptr, &palette,
+ &num_palette);
+ palette - the palette for the file
+ (array of png_color)
+ num_palette - number of entries in the palette
+
+ png_get_gAMA(png_ptr, info_ptr, &gamma);
+ gamma - the gamma the file is written
+ at (PNG_INFO_gAMA)
+
+ png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
+ srgb_intent - the rendering intent (PNG_INFO_sRGB)
+ The presence of the sRGB chunk
+ means that the pixel data is in the
+ sRGB color space. This chunk also
+ implies specific values of gAMA and
+ cHRM.
+
+ png_get_iCCP(png_ptr, info_ptr, &name,
+ &compression_type, &profile, &proflen);
+ name - The profile name.
+ compression - The compression type; always
+ PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+ You may give NULL to this argument to
+ ignore it.
+ profile - International Color Consortium color
+ profile data. May contain NULs.
+ proflen - length of profile data in bytes.
+
+ png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+ sig_bit - the number of significant bits for
+ (PNG_INFO_sBIT) each of the gray,
+ red, green, and blue channels,
+ whichever are appropriate for the
+ given color type (png_color_16)
+
+ png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
+ &trans_values);
+ trans - array of transtqparent entries for
+ palette (PNG_INFO_tRNS)
+ trans_values - graylevel or color sample values of
+ the single transtqparent color for
+ non-paletted images (PNG_INFO_tRNS)
+ num_trans - number of transtqparent entries
+ (PNG_INFO_tRNS)
+
+ png_get_hIST(png_ptr, info_ptr, &hist);
+ (PNG_INFO_hIST)
+ hist - histogram of palette (array of
+ png_uint_16)
+
+ png_get_tIME(png_ptr, info_ptr, &mod_time);
+ mod_time - time image was last modified
+ (PNG_VALID_tIME)
+
+ png_get_bKGD(png_ptr, info_ptr, &background);
+ background - background color (PNG_VALID_bKGD)
+ valid 16-bit red, green and blue
+ values, regardless of color_type
+
+ num_comments = png_get_text(png_ptr, info_ptr,
+ &text_ptr, &num_text);
+ num_comments - number of comments
+ text_ptr - array of png_text holding image
+ comments
+ text_ptr[i].compression - type of compression used
+ on "text" PNG_TEXT_COMPRESSION_NONE
+ PNG_TEXT_COMPRESSION_zTXt
+ PNG_ITXT_COMPRESSION_NONE
+ PNG_ITXT_COMPRESSION_zTXt
+ text_ptr[i].key - keyword for comment. Must contain
+ 1-79 characters.
+ text_ptr[i].text - text comments for current
+ keyword. Can be empty.
+ text_ptr[i].text_length - length of text string,
+ after decompression, 0 for iTXt
+ text_ptr[i].itxt_length - length of itxt string,
+ after decompression, 0 for tEXt/zTXt
+ text_ptr[i].lang - language of comment (empty
+ string for unknown).
+ text_ptr[i].lang_key - keyword in UTF-8
+ (empty string for unknown).
+ num_text - number of comments (same as
+ num_comments; you can put NULL here
+ to avoid the duplication)
+ Note while png_set_text() will accept text, language,
+ and translated keywords that can be NULL pointers, the
+ structure returned by png_get_text will always contain
+ regular zero-terminated C strings. They might be
+ empty strings but they will never be NULL pointers.
+
+ num_spalettes = png_get_sPLT(png_ptr, info_ptr,
+ &palette_ptr);
+ palette_ptr - array of palette structures holding
+ contents of one or more sPLT chunks
+ read.
+ num_spalettes - number of sPLT chunks read.
+
+ png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
+ &unit_type);
+ offset_x - positive offset from the left edge
+ of the screen
+ offset_y - positive offset from the top edge
+ of the screen
+ unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+ png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
+ &unit_type);
+ res_x - pixels/unit physical resolution in
+ x direction
+ res_y - pixels/unit physical resolution in
+ x direction
+ unit_type - PNG_RESOLUTION_UNKNOWN,
+ PNG_RESOLUTION_METER
+
+ png_get_sCAL(png_ptr, info_ptr, &unit, &width,
+ &height)
+ unit - physical scale units (an integer)
+ width - width of a pixel in physical scale units
+ height - height of a pixel in physical scale units
+ (width and height are doubles)
+
+ png_get_sCAL_s(png_ptr, info_ptr, &unit, &width,
+ &height)
+ unit - physical scale units (an integer)
+ width - width of a pixel in physical scale units
+ height - height of a pixel in physical scale units
+ (width and height are strings like "2.54")
+
+ num_unknown_chunks = png_get_unknown_chunks(png_ptr,
+ info_ptr, &unknowns)
+ unknowns - array of png_unknown_chunk
+ structures holding unknown chunks
+ unknowns[i].name - name of unknown chunk
+ unknowns[i].data - data of unknown chunk
+ unknowns[i].size - size of unknown chunk's data
+ unknowns[i].location - position of chunk in file
+
+ The value of "i" corresponds to the order in which the
+ chunks were read from the PNG file or inserted with the
+ png_set_unknown_chunks() function.
+
+The data from the pHYs chunk can be retrieved in several convenient
+forms:
+
+ res_x = png_get_x_pixels_per_meter(png_ptr,
+ info_ptr)
+ res_y = png_get_y_pixels_per_meter(png_ptr,
+ info_ptr)
+ res_x_and_y = png_get_pixels_per_meter(png_ptr,
+ info_ptr)
+ res_x = png_get_x_pixels_per_inch(png_ptr,
+ info_ptr)
+ res_y = png_get_y_pixels_per_inch(png_ptr,
+ info_ptr)
+ res_x_and_y = png_get_pixels_per_inch(png_ptr,
+ info_ptr)
+ aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
+ info_ptr)
+
+ (Each of these returns 0 [signifying "unknown"] if
+ the data is not present or if res_x is 0;
+ res_x_and_y is 0 if res_x != res_y)
+
+The data from the oFFs chunk can be retrieved in several convenient
+forms:
+
+ x_offset = png_get_x_offset_microns(png_ptr, info_ptr);
+ y_offset = png_get_y_offset_microns(png_ptr, info_ptr);
+ x_offset = png_get_x_offset_inches(png_ptr, info_ptr);
+ y_offset = png_get_y_offset_inches(png_ptr, info_ptr);
+
+ (Each of these returns 0 [signifying "unknown" if both
+ x and y are 0] if the data is not present or if the
+ chunk is present but the unit is the pixel)
+
+For more information, see the png_info definition in png.h and the
+PNG specification for chunk contents. Be careful with trusting
+rowbytes, as some of the transformations could increase the space
+needed to hold a row (expand, filler, gray_to_rgb, etc.).
+See png_read_update_info(), below.
+
+A quick word about text_ptr and num_text. PNG stores comments in
+keyword/text pairs, one pair per chunk, with no limit on the number
+of text chunks, and a 2^31 byte limit on their size. While there are
+suggested keywords, there is no requirement to restrict the use to these
+strings. It is strongly suggested that keywords and text be sensible
+to humans (that's the point), so don't use abbreviations. Non-printing
+symbols are not allowed. See the PNG specification for more details.
+There is also no requirement to have text after the keyword.
+
+Keywords should be limited to 79 Latin-1 characters without leading or
+trailing spaces, but non-consecutive spaces are allowed within the
+keyword. It is possible to have the same keyword any number of times.
+The text_ptr is an array of png_text structures, each holding a
+pointer to a language string, a pointer to a keyword and a pointer to
+a text string. The text string, language code, and translated
+keyword may be empty or NULL pointers. The keyword/text
+pairs are put into the array in the order that they are received.
+However, some or all of the text chunks may be after the image, so, to
+make sure you have read all the text chunks, don't mess with these
+until after you read the stuff after the image. This will be
+mentioned again below in the discussion that goes with png_read_end().
+
+.SS Input transformations
+
+After you've read the header information, you can set up the library
+to handle any special transformations of the image data. The various
+ways to transform the data will be described in the order that they
+should occur. This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths. Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data. For example, don't swap red and blue on grayscale data.
+
+The colors used for the background and transparency values should be
+supplied in the same format/depth as the current image data. They
+are stored in the same format/depth as the image data in a bKGD or tRNS
+chunk, so this is what libpng expects for this data. The colors are
+transformed to keep in sync with the image data when an application
+calls the png_read_update_info() routine (see below).
+
+Data will be decoded into the supplied row buffers packed into bytes
+unless the library has been told to transform it into another format.
+For example, 4 bit/pixel paletted or grayscale data will be returned
+2 pixels/byte with the leftmost pixel in the high-order bits of the
+byte, unless png_set_packing() is called. 8-bit RGB data will be stored
+in RGB RGB RGB format unless png_set_filler() is called to insert filler
+bytes, either before or after each RGB triplet. 16-bit RGB data will
+be returned RRGGBB RRGGBB, with the most significant byte of the color
+value first, unless png_set_strip_16() is called to transform it to
+regular RGB RGB triplets, or png_set_filler() is called to insert
+filler bytes, either before or after each RRGGBB triplet. Similarly,
+8-bit or 16-bit grayscale data can be modified with png_set_filler()
+or png_set_strip_16().
+
+The following code transforms grayscale images of less than 8 to 8 bits,
+changes paletted images to RGB, and adds a full alpha channel if there is
+transparency information in a tRNS chunk. This is most useful on
+grayscale images with bit depths of 2 or 4 or if there is a multiple-image
+viewing application that wishes to treat all images in the same way.
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_palette_to_rgb(png_ptr);
+
+ if (color_type == PNG_COLOR_TYPE_GRAY &&
+ bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
+
+ if (png_get_valid(png_ptr, info_ptr,
+ PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
+
+These three functions are actually aliases for png_set_expand(), added
+in libpng version 1.0.4, with the function names expanded to improve code
+readability. In some future version they may actually do different
+things.
+
+PNG can have files with 16 bits per channel. If you only can handle
+8 bits per channel, this will strip the pixels down to 8 bit.
+
+ if (bit_depth == 16)
+ png_set_strip_16(png_ptr);
+
+If, for some reason, you don't need the alpha channel on an image,
+and you want to remove it rather than combining it with the background
+(but the image author certainly had in mind that you *would* combine
+it with the background, so that's what you should probably do):
+
+ if (color_type & PNG_COLOR_MASK_ALPHA)
+ png_set_strip_alpha(png_ptr);
+
+In PNG files, the alpha channel in an image
+is the level of opacity. If you need the alpha channel in an image to
+be the level of transparency instead of opacity, you can invert the
+alpha channel (or the tRNS chunk data) after it's read, so that 0 is
+fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
+images) is fully transtqparent, with
+
+ png_set_invert_alpha(png_ptr);
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit
+files. This code expands to 1 pixel per byte without changing the
+values of the pixels:
+
+ if (bit_depth < 8)
+ png_set_packing(png_ptr);
+
+PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels
+stored in a PNG image have been "scaled" or "shifted" up to the next
+higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to
+8 bits/sample in the range [0, 255]). However, it is also possible to
+convert the PNG pixel data back to the original bit depth of the image.
+This call reduces the pixels back down to the original bit depth:
+
+ png_color_8p sig_bit;
+
+ if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
+ png_set_shift(png_ptr, sig_bit);
+
+PNG files store 3-color pixels in red, green, blue order. This code
+changes the storage of the pixels to blue, green, red:
+
+ if (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ png_set_bgr(png_ptr);
+
+PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them
+into 4 or 8 bytes for windowing systems that need them in this format:
+
+ if (color_type == PNG_COLOR_TYPE_RGB)
+ png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);
+
+where "filler" is the 8 or 16-bit number to fill with, and the location is
+either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether
+you want the filler before the RGB or after. This transformation
+does not affect images that already have full alpha channels. To add an
+opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which
+will generate RGBA pixels.
+
+If you are reading an image with an alpha channel, and you need the
+data as ARGB instead of the normal PNG format RGBA:
+
+ if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ png_set_swap_alpha(png_ptr);
+
+For some uses, you may want a grayscale image to be represented as
+RGB. This code will do that conversion:
+
+ if (color_type == PNG_COLOR_TYPE_GRAY ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ png_set_gray_to_rgb(png_ptr);
+
+Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
+with alpha.
+
+ if (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ png_set_rgb_to_gray_fixed(png_ptr, error_action,
+ int red_weight, int green_weight);
+
+ error_action = 1: silently do the conversion
+ error_action = 2: issue a warning if the original
+ image has any pixel where
+ red != green or red != blue
+ error_action = 3: issue an error and abort the
+ conversion if the original
+ image has any pixel where
+ red != green or red != blue
+
+ red_weight: weight of red component times 100000
+ green_weight: weight of green component times 100000
+ If either weight is negative, default
+ weights (21268, 71514) are used.
+
+If you have set error_action = 1 or 2, you can
+later check whether the image really was gray, after processing
+the image rows, with the png_get_rgb_to_gray_status(png_ptr) function.
+It will return a png_byte that is zero if the image was gray or
+1 if there were any non-gray pixels. bKGD and sBIT data
+will be silently converted to grayscale, using the green channel
+data, regardless of the error_action setting.
+
+With red_weight+green_weight<=100000,
+the normalized graylevel is computed:
+
+ int rw = red_weight * 65536;
+ int gw = green_weight * 65536;
+ int bw = 65536 - (rw + gw);
+ gray = (rw*red + gw*green + bw*blue)/65536;
+
+The default values approximate those recommended in the Charles
+Poynton's Color FAQ, <http://www.inforamp.net/~poynton/>
+Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
+
+ Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+
+Libpng approximates this with
+
+ Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
+
+which can be expressed with integers as
+
+ Y = (6969 * R + 23434 * G + 2365 * B)/32768
+
+The calculation is done in a linear colorspace, if the image gamma
+is known.
+
+If you have a grayscale and you are using png_set_expand_depth(),
+png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to
+a higher bit-depth, you must either supply the background color as a gray
+value at the original file bit-depth (need_expand = 1) or else supply the
+background color as an RGB triplet at the final, expanded bit depth
+(need_expand = 0). Similarly, if you are reading a paletted image, you
+must either supply the background color as a palette index (need_expand = 1)
+or as an RGB triplet that may or may not be in the palette (need_expand = 0).
+
+ png_color_16 my_background;
+ png_color_16p image_background;
+
+ if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+ png_set_background(png_ptr, image_background,
+ PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ else
+ png_set_background(png_ptr, &my_background,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+The png_set_background() function tells libpng to composite images
+with alpha or simple transparency against the supplied background
+color. If the PNG file tqcontains a bKGD chunk (PNG_INFO_bKGD valid),
+you may use this color, or supply another color more suitable for
+the current display (e.g., the background color from a web page). You
+need to tell libpng whether the color is in the gamma space of the
+display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
+(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
+that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
+know why anyone would use this, but it's here).
+
+To properly display PNG images on any kind of system, the application needs
+to know what the display gamma is. Ideally, the user will know this, and
+the application will allow them to set it. One method of allowing the user
+to set the display gamma separately for each system is to check for a
+SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be
+correctly set.
+
+Note that display_gamma is the overall gamma correction required to produce
+pleasing results, which depends on the lighting conditions in the surrounding
+environment. In a dim or brightly lit room, no compensation other than
+the physical gamma exponent of the monitor is needed, while in a dark room
+a slightly smaller exponent is better.
+
+ double gamma, screen_gamma;
+
+ if (/* We have a user-defined screen
+ gamma value */)
+ {
+ screen_gamma = user_defined_screen_gamma;
+ }
+ /* One way that applications can share the same
+ screen gamma value */
+ else if ((gamma_str = getenv("SCREEN_GAMMA"))
+ != NULL)
+ {
+ screen_gamma = (double)atof(gamma_str);
+ }
+ /* If we don't have another value */
+ else
+ {
+ screen_gamma = 2.2; /* A good guess for a
+ PC monitor in a bright office or a dim room */
+ screen_gamma = 2.0; /* A good guess for a
+ PC monitor in a dark room */
+ screen_gamma = 1.7 or 1.0; /* A good
+ guess for Mac systems */
+ }
+
+The png_set_gamma() function handles gamma transformations of the data.
+Pass both the file gamma and the current screen_gamma. If the file does
+not have a gamma value, you can pass one anyway if you have an idea what
+it is (usually 0.45455 is a good guess for GIF images on PCs). Note
+that file gammas are inverted from screen gammas. See the discussions
+on gamma in the PNG specification for an excellent description of what
+gamma is, and why all applications should support it. It is strongly
+recommended that PNG viewers support gamma correction.
+
+ if (png_get_gAMA(png_ptr, info_ptr, &gamma))
+ png_set_gamma(png_ptr, screen_gamma, gamma);
+ else
+ png_set_gamma(png_ptr, screen_gamma, 0.45455);
+
+If you need to reduce an RGB file to a paletted file, or if a paletted
+file has more entries then will fit on your screen, png_set_dither()
+will do that. Note that this is a simple match dither that merely
+tqfinds the closest color available. This should work fairly well with
+optimized palettes, and fairly badly with linear color cubes. If you
+pass a palette that is larger then maximum_colors, the file will
+reduce the number of colors in the palette so it will fit into
+maximum_colors. If there is a histogram, it will use it to make
+more intelligent choices when reducing the palette. If there is no
+histogram, it may not do as good a job.
+
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ if (png_get_valid(png_ptr, info_ptr,
+ PNG_INFO_PLTE))
+ {
+ png_uint_16p histogram = NULL;
+
+ png_get_hIST(png_ptr, info_ptr,
+ &histogram);
+ png_set_dither(png_ptr, palette, num_palette,
+ max_screen_colors, histogram, 1);
+ }
+ else
+ {
+ png_color std_color_cube[MAX_SCREEN_COLORS] =
+ { ... colors ... };
+
+ png_set_dither(png_ptr, std_color_cube,
+ MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,
+ NULL,0);
+ }
+ }
+
+PNG files describe monochrome as black being zero and white being one.
+The following code will reverse this (make black be one and white be
+zero):
+
+ if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY)
+ png_set_invert_mono(png_ptr);
+
+This function can also be used to invert grayscale and gray-alpha images:
+
+ if (color_type == PNG_COLOR_TYPE_GRAY ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ png_set_invert_mono(png_ptr);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first). This code changes the storage to the
+other way (little-endian, i.e. least significant bits first, the
+way PCs store them):
+
+ if (bit_depth == 16)
+ png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+ if (bit_depth < 8)
+ png_set_packswap(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs. This is done by setting a callback
+with
+
+ png_set_read_user_transform_fn(png_ptr,
+ read_transform_fn);
+
+You must supply the function
+
+ void read_transform_fn(png_ptr ptr, row_info_ptr
+ row_info, png_bytep data)
+
+See pngtest.c for a working example. Your function will be called
+after all of the other transformations have been processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function, and you can inform libpng that your transform
+function will change the number of channels or bit depth with the
+function
+
+ png_set_user_transform_info(png_ptr, user_ptr,
+ user_depth, user_channels);
+
+The user's application, not libpng, is responsible for allocating and
+freeing any memory required for the user structure.
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr(). For example:
+
+ voidp read_user_transform_ptr =
+ png_get_user_transform_ptr(png_ptr);
+
+The last thing to handle is interlacing; this is covered in detail below,
+but you must call the function here if you want libpng to handle expansion
+of the interlaced image.
+
+ number_of_passes = png_set_interlace_handling(png_ptr);
+
+After setting the transformations, libpng can update your png_info
+structure to reflect any transformations you've requested with this
+call. This is most useful to update the info structure's rowbytes
+field so you can use it to allocate your image memory. This function
+will also update your palette with the correct screen_gamma and
+background if these have been given with the calls above.
+
+ png_read_update_info(png_ptr, info_ptr);
+
+After you call png_read_update_info(), you can allocate any
+memory you need to hold the image. The row data is simply
+raw byte data for all forms of images. As the actual allocation
+varies among applications, no example will be given. If you
+are allocating one large chunk, you will need to build an
+array of pointers to each row, as it will be needed for some
+of the functions below.
+
+.SS Reading image data
+
+After you've allocated memory, you can read the image data.
+The simplest way to do this is in one function call. If you are
+allocating enough memory to hold the whole image, you can just
+call png_read_image() and libpng will read in all the image data
+and put it in the memory area supplied. You will need to pass in
+an array of pointers to each row.
+
+This function automatically handles interlacing, so you don't need
+to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_read_rows().
+
+ png_read_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+ png_bytep row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to read in the whole image at once, you can
+use png_read_rows() instead. If there is no interlacing (check
+interlace_type == PNG_INTERLACE_NONE), this is simple:
+
+ png_read_rows(png_ptr, row_pointers, NULL,
+ number_of_rows);
+
+where row_pointers is the same as in the png_read_image() call.
+
+If you are doing this just one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+ png_bytep row_pointer = row;
+ png_read_row(png_ptr, row_pointer, NULL);
+
+If the file is interlaced (interlace_type != 0 in the IHDR chunk), things
+get somewhat harder. The only current (PNG Specification version 1.2)
+interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
+is a somewhat complicated 2D interlace scheme, known as Adam7, that
+breaks down an image into seven smaller images of varying size, based
+on an 8x8 grid.
+
+libpng can fill out those images or it can give them to you "as is".
+If you want them filled out, there are two ways to do that. The one
+mentioned in the PNG specification is to expand each pixel to cover
+those pixels that have not been read yet (the "rectangle" method).
+This results in a blocky image for the first pass, which gradually
+smooths out as more pixels are read. The other method is the "sparkle"
+method, where pixels are drawn only in their final locations, with the
+rest of the image remaining whatever colors they were initialized to
+before the start of the read. The first method usually looks better,
+but tends to be slower, as there are more pixels to put in the rows.
+
+If you don't want libpng to handle the interlacing details, just call
+png_read_rows() seven times to read in all seven images. Each of the
+images is a valid image by itself, or they can all be combined on an
+8x8 grid to form a single image (although if you intend to combine them
+you would be far better off using the libpng interlace handling).
+
+The first pass will return an image 1/8 as wide as the entire image
+(every 8th column starting in column 0) and 1/8 as high as the original
+(every 8th row starting in row 0), the second will be 1/8 as wide
+(starting in column 4) and 1/8 as high (also starting in row 0). The
+third pass will be 1/4 as wide (every 4th pixel starting in column 0) and
+1/8 as high (every 8th row starting in row 4), and the fourth pass will
+be 1/4 as wide and 1/4 as high (every 4th column starting in column 2,
+and every 4th row starting in row 0). The fifth pass will return an
+image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),
+while the sixth pass will be 1/2 as wide and 1/2 as high as the original
+(starting in column 1 and row 0). The seventh and final pass will be as
+wide as the original, and 1/2 as high, containing all of the odd
+numbered scanlines. Phew!
+
+If you want libpng to expand the images, call this before calling
+png_start_read_image() or png_read_update_info():
+
+ if (interlace_type == PNG_INTERLACE_ADAM7)
+ number_of_passes
+ = png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed. Currently, this
+is seven, but may change if another interlace type is added.
+This function can be called even if the file is not interlaced,
+where it will return one pass.
+
+If you are not going to display the image after each pass, but are
+going to wait until the entire image is read in, use the sparkle
+effect. This effect is faster and the end result of either method
+is exactly the same. If you are planning on displaying the image
+after each pass, the "rectangle" effect is generally considered the
+better looking one.
+
+If you only want the "sparkle" effect, just call png_read_rows() as
+normal, with the third parameter NULL. Make sure you make pass over
+the image number_of_passes times, and you don't change the data in the
+rows between calls. You can change the locations of the data, just
+not the data. Each pass only writes the pixels appropriate for that
+pass, and assumes the data from previous passes is still valid.
+
+ png_read_rows(png_ptr, row_pointers, NULL,
+ number_of_rows);
+
+If you only want the first effect (the rectangles), do the same as
+before except pass the row buffer in the third parameter, and leave
+the second parameter NULL.
+
+ png_read_rows(png_ptr, NULL, row_pointers,
+ number_of_rows);
+
+.SS Finishing a sequential read
+
+After you are finished reading the image through either the high- or
+low-level interfaces, you can finish reading the file. If you are
+interested in comments or time, which may be stored either before or
+after the image data, you should pass the separate png_info struct if
+you want to keep the comments from before and after the image
+separate. If you are not interested, you can pass NULL.
+
+ png_read_end(png_ptr, end_info);
+
+When you are done, you can free all memory allocated by libpng like this:
+
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ &end_info);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+ png_free_data(png_ptr, info_ptr, tqmask, seq)
+ tqmask - identifies data to be freed, a tqmask
+ containing the logical OR of one or
+ more of
+ PNG_FREE_PLTE, PNG_FREE_TRNS,
+ PNG_FREE_HIST, PNG_FREE_ICCP,
+ PNG_FREE_PCAL, PNG_FREE_ROWS,
+ PNG_FREE_SCAL, PNG_FREE_SPLT,
+ PNG_FREE_TEXT, PNG_FREE_UNKN,
+ or simply PNG_FREE_ALL
+ seq - sequence number of item to be freed
+ (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user and not by libpng, and will in those
+cases do nothing. The "seq" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed. If "seq" is not
+-1, and multiple items are allowed for the data type identified in
+the tqmask, such as text or sPLT, only the n'th item in the structure
+is freed, where n is "seq".
+
+The default behavior is only to free data that was allocated internally
+by libpng. This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+ png_data_freer(png_ptr, info_ptr, freer, tqmask)
+ tqmask - which data elements are affected
+ same choices as in png_free_data()
+ freer - one of
+ PNG_DESTROY_WILL_FREE_DATA
+ PNG_SET_WILL_FREE_DATA
+ PNG_USER_WILL_FREE_DATA
+
+This function only affects data that has already been allocated.
+You can call this function after reading the PNG data but before calling
+any png_set_*() functions, to control whether the user or the png_set_*()
+function is responsible for freeing any existing data that might be present,
+and again after the png_set_*() functions to control whether the user
+or png_destroy_*() is supposed to free the data. When the user assumes
+responsibility for libpng-allocated data, the application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated your row_pointers in a single block, as suggested above in
+the description of the high level read interface, you must not transfer
+responsibility for freeing it to the png_set_rows or png_read_destroy function,
+because they would also try to free the individual row_pointers[i].
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key. Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+
+The png_free_data() function will turn off the "valid" flag for anything
+it frees. If you need to turn the flag off for a chunk that was freed by your
+application instead of by libpng, you can use
+
+ png_set_invalid(png_ptr, info_ptr, tqmask);
+ tqmask - identifies the chunks to be made invalid,
+ containing the logical OR of one or
+ more of
+ PNG_INFO_gAMA, PNG_INFO_sBIT,
+ PNG_INFO_cHRM, PNG_INFO_PLTE,
+ PNG_INFO_tRNS, PNG_INFO_bKGD,
+ PNG_INFO_hIST, PNG_INFO_pHYs,
+ PNG_INFO_oFFs, PNG_INFO_tIME,
+ PNG_INFO_pCAL, PNG_INFO_sRGB,
+ PNG_INFO_iCCP, PNG_INFO_sPLT,
+ PNG_INFO_sCAL, PNG_INFO_IDAT
+
+For a more compact example of reading a PNG image, see the file example.c.
+
+.SS Reading PNG files progressively
+
+The progressive reader is slightly different then the non-progressive
+reader. Instead of calling png_read_info(), png_read_rows(), and
+png_read_end(), you make one call to png_process_data(), which calls
+callbacks when it has the info, a row, or the end of the image. You
+set up these callbacks with png_set_progressive_read_fn(). You don't
+have to worry about the input/output functions of libpng, as you are
+giving the library the data directly in png_process_data(). I will
+assume that you have read the section on reading PNG files above,
+so I will only highlight the differences (although I will show
+all of the code).
+
+png_structp png_ptr;
+png_infop info_ptr;
+
+ /* An example code fragment of how you would
+ initialize the progressive reader in your
+ application. */
+ int
+ initialize_png_reader()
+ {
+ png_ptr = png_create_read_struct
+ (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+ user_error_fn, user_warning_fn);
+ if (!png_ptr)
+ return (ERROR);
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
+ (png_infopp)NULL);
+ return (ERROR);
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ (png_infopp)NULL);
+ return (ERROR);
+ }
+
+ /* This one's new. You can provide functions
+ to be called when the header info is valid,
+ when each row is completed, and when the image
+ is finished. If you aren't using all functions,
+ you can specify NULL parameters. Even when all
+ three functions are NULL, you need to call
+ png_set_progressive_read_fn(). You can use
+ any struct as the user_ptr (cast to a void pointer
+ for the function call), and retrieve the pointer
+ from inside the callbacks using the function
+
+ png_get_progressive_ptr(png_ptr);
+
+ which will return a void pointer, which you have
+ to cast appropriately.
+ */
+ png_set_progressive_read_fn(png_ptr, (void *)user_ptr,
+ info_callback, row_callback, end_callback);
+
+ return 0;
+ }
+
+ /* A code fragment that you call as you receive blocks
+ of data */
+ int
+ process_data(png_bytep buffer, png_uint_32 length)
+ {
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ (png_infopp)NULL);
+ return (ERROR);
+ }
+
+ /* This one's new also. Simply give it a chunk
+ of data from the file stream (in order, of
+ course). On machines with segmented memory
+ models machines, don't give it any more than
+ 64K. The library seems to run fine with sizes
+ of 4K. Although you can give it much less if
+ necessary (I assume you can give it chunks of
+ 1 byte, I haven't tried less then 256 bytes
+ yet). When this function returns, you may
+ want to display any rows that were generated
+ in the row callback if you don't already do
+ so there.
+ */
+ png_process_data(png_ptr, info_ptr, buffer, length);
+ return 0;
+ }
+
+ /* This function is called (as set by
+ png_set_progressive_read_fn() above) when enough data
+ has been supplied so all of the header has been
+ read.
+ */
+ void
+ info_callback(png_structp png_ptr, png_infop info)
+ {
+ /* Do any setup here, including setting any of
+ the transformations mentioned in the Reading
+ PNG files section. For now, you _must_ call
+ either png_start_read_image() or
+ png_read_update_info() after all the
+ transformations are set (even if you don't set
+ any). You may start getting rows before
+ png_process_data() returns, so this is your
+ last chance to prepare for that.
+ */
+ }
+
+ /* This function is called when each row of image
+ data is complete */
+ void
+ row_callback(png_structp png_ptr, png_bytep new_row,
+ png_uint_32 row_num, int pass)
+ {
+ /* If the image is interlaced, and you turned
+ on the interlace handler, this function will
+ be called for every row in every pass. Some
+ of these rows will not be changed from the
+ previous pass. When the row is not changed,
+ the new_row variable will be NULL. The rows
+ and passes are called in order, so you don't
+ really need the row_num and pass, but I'm
+ supplying them because it may make your life
+ easier.
+
+ For the non-NULL rows of interlaced images,
+ you must call png_progressive_combine_row()
+ passing in the row and the old row. You can
+ call this function for NULL rows (it will just
+ return) and for non-interlaced images (it just
+ does the memcpy for you) if it will make the
+ code easier. Thus, you can just do this for
+ all cases:
+ */
+
+ png_progressive_combine_row(png_ptr, old_row,
+ new_row);
+
+ /* where old_row is what was displayed for
+ previously for the row. Note that the first
+ pass (pass == 0, really) will completely cover
+ the old row, so the rows do not have to be
+ initialized. After the first pass (and only
+ for interlaced images), you will have to pass
+ the current row, and the function will combine
+ the old row and the new row.
+ */
+ }
+
+ void
+ end_callback(png_structp png_ptr, png_infop info)
+ {
+ /* This function is called after the whole image
+ has been read, including any chunks after the
+ image (up to and including the IEND). You
+ will usually have the same info chunk as you
+ had in the header, although some data may have
+ been added to the comments and time fields.
+
+ Most people won't do much here, perhaps setting
+ a flag that marks the image as finished.
+ */
+ }
+
+
+
+.SH IV. Writing
+
+Much of this is very similar to reading. However, everything of
+importance is repeated here, so you won't have to constantly look
+back up in the reading section to understand writing.
+
+.SS Setup
+
+You will want to do the I/O initialization before you get into libpng,
+so if it doesn't work, you don't have anything to undo. If you are not
+using the standard I/O functions, you will need to tqreplace them with
+custom writing functions. See the discussion under Customizing libpng.
+
+ FILE *fp = fopen(file_name, "wb");
+ if (!fp)
+ {
+ return (ERROR);
+ }
+
+Next, png_struct and png_info need to be allocated and initialized.
+As these can be both relatively large, you may not want to store these
+on the stack, unless you have stack space to spare. Of course, you
+will want to check if they return NULL. If you are also reading,
+you won't want to name your read structure and your write structure
+both "png_ptr"; you can call them anything you like, such as
+"read_ptr" and "write_ptr". Look at pngtest.c, for example.
+
+ png_structp png_ptr = png_create_write_struct
+ (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+ user_error_fn, user_warning_fn);
+ if (!png_ptr)
+ return (ERROR);
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_write_struct(&png_ptr,
+ (png_infopp)NULL);
+ return (ERROR);
+ }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_write_struct_2() instead of png_create_write_struct():
+
+ png_structp png_ptr = png_create_write_struct_2
+ (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+ user_error_fn, user_warning_fn, (png_voidp)
+ user_mem_ptr, user_malloc_fn, user_free_fn);
+
+After you have these structures, you will need to set up the
+error handling. When libpng encounters an error, it expects to
+longjmp() back to your routine. Therefore, you will need to call
+setjmp() and pass the png_jmpbuf(png_ptr). If you
+write the file from different routines, you will need to update
+the png_jmpbuf(png_ptr) every time you enter a new routine that will
+call a png_*() function. See your documentation of setjmp/longjmp
+for your compiler for more information on setjmp/longjmp. See
+the discussion on libpng error handling in the Customizing Libpng
+section below for more information on the libpng error handling.
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ fclose(fp);
+ return (ERROR);
+ }
+ ...
+ return;
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the output code. The default for libpng is to
+use the C function fwrite(). If you use this, you will need to pass a
+valid FILE * in the function png_init_io(). Be sure that the file is
+opened in binary mode. Again, if you wish to handle writing data in
+another way, see the discussion on libpng I/O handling in the Customizing
+Libpng section below.
+
+ png_init_io(png_ptr, fp);
+
+.SS Write callbacks
+
+At this point, you can set up a callback function that will be
+called after each row has been written, which you can use to control
+a progress meter or the like. It's demonstrated in pngtest.c.
+You must supply a function
+
+ void write_row_callback(png_ptr, png_uint_32 row,
+ int pass);
+ {
+ /* put your code here */
+ }
+
+(You can give it another name that you like instead of "write_row_callback")
+
+To inform libpng about your function, use
+
+ png_set_write_status_fn(png_ptr, write_row_callback);
+
+You now have the option of modifying how the compression library will
+run. The following functions are mainly for testing, but may be useful
+in some cases, like if you need to write PNG files extremely fast and
+are willing to give up some compression, or if you want to get the
+maximum possible compression at the expense of slower writing. If you
+have no special needs in this area, let the library do what it wants by
+not calling this function at all, as it has been tuned to deliver a good
+speed/compression ratio. The second parameter to png_set_filter() is
+the filter method, for which the only valid values are 0 (as of the
+July 1999 PNG specification, version 1.2) or 64 (if you are writing
+a PNG datastream that is to be embedded in a MNG datastream). The third
+parameter is a flag that indicates which filter type(s) are to be tested
+for each scanline. See the PNG specification for details on the specific filter
+types.
+
+
+ /* turn on or off filtering, and/or choose
+ specific filters. You can use either a single
+ PNG_FILTER_VALUE_NAME or the logical OR of one
+ or more PNG_FILTER_NAME masks. */
+ png_set_filter(png_ptr, 0,
+ PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE |
+ PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB |
+ PNG_FILTER_UP | PNG_FILTER_VALUE_UP |
+ PNG_FILTER_AVE | PNG_FILTER_VALUE_AVE |
+ PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
+ PNG_ALL_FILTERS);
+
+If an application
+wants to start and stop using particular filters during compression,
+it should start out with all of the filters (to ensure that the previous
+row of pixels will be stored in case it's needed later), and then add
+and remove them after the start of compression.
+
+If you are writing a PNG datastream that is to be embedded in a MNG
+datastream, the second parameter can be either 0 or 64.
+
+The png_set_compression_*() functions interface to the zlib compression
+library, and should mostly be ignored unless you really know what you are
+doing. The only generally useful call is png_set_compression_level()
+which changes how much time zlib spends on trying to compress the image
+data. See the Compression Library (zlib.h and algorithm.txt, distributed
+with zlib) for details on the compression levels.
+
+ /* set the zlib compression level */
+ png_set_compression_level(png_ptr,
+ Z_BEST_COMPRESSION);
+
+ /* set other zlib parameters */
+ png_set_compression_mem_level(png_ptr, 8);
+ png_set_compression_strategy(png_ptr,
+ Z_DEFAULT_STRATEGY);
+ png_set_compression_window_bits(png_ptr, 15);
+ png_set_compression_method(png_ptr, 8);
+ png_set_compression_buffer_size(png_ptr, 8192)
+
+extern PNG_EXPORT(void,png_set_zbuf_size)
+
+.SS Setting the contents of info for output
+
+You now need to fill in the png_info structure with all the data you
+wish to write before the actual image. Note that the only thing you
+are allowed to write after the image is the text chunks and the time
+chunk (as of PNG Specification 1.2, anyway). See png_write_end() and
+the latest PNG specification for more information on that. If you
+wish to write them before the image, fill them in now, and flag that
+data as being valid. If you want to wait until after the data, don't
+fill them until png_write_end(). For all the fields in png_info and
+their data types, see png.h. For explanations of what the fields
+contain, see the PNG specification.
+
+Some of the more important parts of the png_info are:
+
+ png_set_IHDR(png_ptr, info_ptr, width, height,
+ bit_depth, color_type, interlace_type,
+ compression_type, filter_method)
+ width - holds the width of the image
+ in pixels (up to 2^31).
+ height - holds the height of the image
+ in pixels (up to 2^31).
+ bit_depth - holds the bit depth of one of the
+ image channels.
+ (valid values are 1, 2, 4, 8, 16
+ and depend also on the
+ color_type. See also significant
+ bits (sBIT) below).
+ color_type - describes which color/alpha
+ channels are present.
+ PNG_COLOR_TYPE_GRAY
+ (bit depths 1, 2, 4, 8, 16)
+ PNG_COLOR_TYPE_GRAY_ALPHA
+ (bit depths 8, 16)
+ PNG_COLOR_TYPE_PALETTE
+ (bit depths 1, 2, 4, 8)
+ PNG_COLOR_TYPE_RGB
+ (bit_depths 8, 16)
+ PNG_COLOR_TYPE_RGB_ALPHA
+ (bit_depths 8, 16)
+
+ PNG_COLOR_MASK_PALETTE
+ PNG_COLOR_MASK_COLOR
+ PNG_COLOR_MASK_ALPHA
+
+ interlace_type - PNG_INTERLACE_NONE or
+ PNG_INTERLACE_ADAM7
+ compression_type - (must be
+ PNG_COMPRESSION_TYPE_DEFAULT)
+ filter_method - (must be PNG_FILTER_TYPE_DEFAULT
+ or, if you are writing a PNG to
+ be embedded in a MNG datastream,
+ can also be
+ PNG_INTRAPIXEL_DIFFERENCING)
+
+ png_set_PLTE(png_ptr, info_ptr, palette,
+ num_palette);
+ palette - the palette for the file
+ (array of png_color)
+ num_palette - number of entries in the palette
+
+ png_set_gAMA(png_ptr, info_ptr, gamma);
+ gamma - the gamma the image was created
+ at (PNG_INFO_gAMA)
+
+ png_set_sRGB(png_ptr, info_ptr, srgb_intent);
+ srgb_intent - the rendering intent
+ (PNG_INFO_sRGB) The presence of
+ the sRGB chunk means that the pixel
+ data is in the sRGB color space.
+ This chunk also implies specific
+ values of gAMA and cHRM. Rendering
+ intent is the CSS-1 property that
+ has been defined by the International
+ Color Consortium
+ (http://www.color.org).
+ It can be one of
+ PNG_sRGB_INTENT_SATURATION,
+ PNG_sRGB_INTENT_PERCEPTUAL,
+ PNG_sRGB_INTENT_ABSOLUTE, or
+ PNG_sRGB_INTENT_RELATIVE.
+
+
+ png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
+ srgb_intent);
+ srgb_intent - the rendering intent
+ (PNG_INFO_sRGB) The presence of the
+ sRGB chunk means that the pixel
+ data is in the sRGB color space.
+ This function also causes gAMA and
+ cHRM chunks with the specific values
+ that are consistent with sRGB to be
+ written.
+
+ png_set_iCCP(png_ptr, info_ptr, name, compression_type,
+ profile, proflen);
+ name - The profile name.
+ compression - The compression type; always
+ PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+ You may give NULL to this argument to
+ ignore it.
+ profile - International Color Consortium color
+ profile data. May contain NULs.
+ proflen - length of profile data in bytes.
+
+ png_set_sBIT(png_ptr, info_ptr, sig_bit);
+ sig_bit - the number of significant bits for
+ (PNG_INFO_sBIT) each of the gray, red,
+ green, and blue channels, whichever are
+ appropriate for the given color type
+ (png_color_16)
+
+ png_set_tRNS(png_ptr, info_ptr, trans, num_trans,
+ trans_values);
+ trans - array of transtqparent entries for
+ palette (PNG_INFO_tRNS)
+ trans_values - graylevel or color sample values of
+ the single transtqparent color for
+ non-paletted images (PNG_INFO_tRNS)
+ num_trans - number of transtqparent entries
+ (PNG_INFO_tRNS)
+
+ png_set_hIST(png_ptr, info_ptr, hist);
+ (PNG_INFO_hIST)
+ hist - histogram of palette (array of
+ png_uint_16)
+
+ png_set_tIME(png_ptr, info_ptr, mod_time);
+ mod_time - time image was last modified
+ (PNG_VALID_tIME)
+
+ png_set_bKGD(png_ptr, info_ptr, background);
+ background - background color (PNG_VALID_bKGD)
+
+ png_set_text(png_ptr, info_ptr, text_ptr, num_text);
+ text_ptr - array of png_text holding image
+ comments
+ text_ptr[i].compression - type of compression used
+ on "text" PNG_TEXT_COMPRESSION_NONE
+ PNG_TEXT_COMPRESSION_zTXt
+ PNG_ITXT_COMPRESSION_NONE
+ PNG_ITXT_COMPRESSION_zTXt
+ text_ptr[i].key - keyword for comment. Must contain
+ 1-79 characters.
+ text_ptr[i].text - text comments for current
+ keyword. Can be NULL or empty.
+ text_ptr[i].text_length - length of text string,
+ after decompression, 0 for iTXt
+ text_ptr[i].itxt_length - length of itxt string,
+ after decompression, 0 for tEXt/zTXt
+ text_ptr[i].lang - language of comment (NULL or
+ empty for unknown).
+ text_ptr[i].translated_keyword - keyword in UTF-8 (NULL
+ or empty for unknown).
+ num_text - number of comments
+
+ png_set_sPLT(png_ptr, info_ptr, &palette_ptr,
+ num_spalettes);
+ palette_ptr - array of png_sPLT_struct structures
+ to be added to the list of palettes
+ in the info structure.
+ num_spalettes - number of palette structures to be
+ added.
+
+ png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
+ unit_type);
+ offset_x - positive offset from the left
+ edge of the screen
+ offset_y - positive offset from the top
+ edge of the screen
+ unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+ png_set_pHYs(png_ptr, info_ptr, res_x, res_y,
+ unit_type);
+ res_x - pixels/unit physical resolution
+ in x direction
+ res_y - pixels/unit physical resolution
+ in y direction
+ unit_type - PNG_RESOLUTION_UNKNOWN,
+ PNG_RESOLUTION_METER
+
+ png_set_sCAL(png_ptr, info_ptr, unit, width, height)
+ unit - physical scale units (an integer)
+ width - width of a pixel in physical scale units
+ height - height of a pixel in physical scale units
+ (width and height are doubles)
+
+ png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)
+ unit - physical scale units (an integer)
+ width - width of a pixel in physical scale units
+ height - height of a pixel in physical scale units
+ (width and height are strings like "2.54")
+
+ png_set_unknown_chunks(png_ptr, info_ptr, &unknowns,
+ num_unknowns)
+ unknowns - array of png_unknown_chunk
+ structures holding unknown chunks
+ unknowns[i].name - name of unknown chunk
+ unknowns[i].data - data of unknown chunk
+ unknowns[i].size - size of unknown chunk's data
+ unknowns[i].location - position to write chunk in file
+ 0: do not write chunk
+ PNG_HAVE_IHDR: before PLTE
+ PNG_HAVE_PLTE: before IDAT
+ PNG_AFTER_IDAT: after IDAT
+
+The "location" member is set automatically according to
+what part of the output file has already been written.
+You can change its value after calling png_set_unknown_chunks()
+as demonstrated in pngtest.c. Within each of the "locations",
+the chunks are sequenced according to their position in the
+structure (that is, the value of "i", which is the order in which
+the chunk was either read from the input file or defined with
+png_set_unknown_chunks).
+
+A quick word about text and num_text. text is an array of png_text
+structures. num_text is the number of valid structures in the array.
+Each png_text structure holds a language code, a keyword, a text value,
+and a compression type.
+
+The compression types have the same valid numbers as the compression
+types of the image data. Currently, the only valid number is zero.
+However, you can store text either compressed or uncompressed, unlike
+images, which always have to be compressed. So if you don't want the
+text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
+Because tEXt and zTXt chunks don't have a language field, if you
+specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt
+any language code or translated keyword will not be written out.
+
+Until text gets around 1000 bytes, it is not worth compressing it.
+After the text has been written out to the file, the compression type
+is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
+so that it isn't written out again at the end (in case you are calling
+png_write_end() with the same struct.
+
+The keywords that are given in the PNG Specification are:
+
+ Title Short (one line) title or
+ caption for image
+ Author Name of image's creator
+ Description Description of image (possibly long)
+ Copyright Copyright notice
+ Creation Time Time of original image creation
+ (usually RFC 1123 format, see below)
+ Software Software used to create the image
+ Disclaimer Legal disclaimer
+ Warning Warning of nature of content
+ Source Device used to create the image
+ Comment Miscellaneous comment; conversion
+ from other image format
+
+The keyword-text pairs work like this. Keywords should be short
+simple descriptions of what the comment is about. Some typical
+keywords are found in the PNG specification, as is some recommendations
+on keywords. You can repeat keywords in a file. You can even write
+some text before the image and some after. For example, you may want
+to put a description of the image before the image, but leave the
+disclaimer until after, so viewers working over modem connections
+don't have to wait for the disclaimer to go over the modem before
+they start seeing the image. Finally, keywords should be full
+words, not abbreviations. Keywords and text are in the ISO 8859-1
+(Latin-1) character set (a superset of regular ASCII) and can not
+contain NUL characters, and should not contain control or other
+unprintable characters. To make the comments widely readable, stick
+with basic ASCII, and avoid machine specific character set extensions
+like the IBM-PC character set. The keyword must be present, but
+you can leave off the text string on non-compressed pairs.
+Compressed pairs must have a text string, as only the text string
+is compressed anyway, so the compression would be meaningless.
+
+PNG supports modification time via the png_time structure. Two
+conversion routines are provided, png_convert_from_time_t() for
+time_t and png_convert_from_struct_tm() for struct tm. The
+time_t routine uses gmtime(). You don't have to use either of
+these, but if you wish to fill in the png_time structure directly,
+you should provide the time in universal time (GMT) if possible
+instead of your local time. Note that the year number is the full
+year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and
+that months start with 1.
+
+If you want to store the time of the original image creation, you should
+use a plain tEXt chunk with the "Creation Time" keyword. This is
+necessary because the "creation time" of a PNG image is somewhat vague,
+depending on whether you mean the PNG file, the time the image was
+created in a non-PNG format, a still photo from which the image was
+scanned, or possibly the subject matter itself. In order to facilitate
+machine-readable dates, it is recommended that the "Creation Time"
+tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),
+although this isn't a requirement. Unlike the tIME chunk, the
+"Creation Time" tEXt chunk is not expected to be automatically changed
+by the software. To facilitate the use of RFC 1123 dates, a function
+png_convert_to_rfc1123(png_timep) is provided to convert from PNG
+time to an RFC 1123 format string.
+
+.SS Writing unknown chunks
+
+You can use the png_set_unknown_chunks function to queue up chunks
+for writing. You give it a chunk name, raw data, and a size; that's
+all there is to it. The chunks will be written by the next following
+png_write_info_before_PLTE, png_write_info, or png_write_end function.
+Any chunks previously read into the info structure's unknown-chunk
+list will also be written out in a sequence that satisfies the PNG
+specification's ordering rules.
+
+.SS The high-level write interface
+
+At this point there are two ways to proceed; through the high-level
+write interface, or through a sequence of low-level write operations.
+You can use the high-level interface if your image data is present
+in the info structure. All defined output
+transformations are permitted, enabled by the following masks.
+
+ PNG_TRANSFORM_IDENTITY No transformation
+ PNG_TRANSFORM_PACKING Pack 1, 2 and 4-bit samples
+ PNG_TRANSFORM_PACKSWAP Change order of packed
+ pixels to LSB first
+ PNG_TRANSFORM_INVERT_MONO Invert monochrome images
+ PNG_TRANSFORM_SHIFT Normalize pixels to the
+ sBIT depth
+ PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA
+ to BGRA
+ PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA
+ to AG
+ PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity
+ to transparency
+ PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples
+ PNG_TRANSFORM_STRIP_FILLER Strip out filler bytes.
+
+If you have valid image data in the info structure (you can use
+png_set_rows() to put image data in the info structure), simply do this:
+
+ png_write_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of some set of
+transformation flags. This call is equivalent to png_write_info(),
+followed the set of transformations indicated by the transform tqmask,
+then png_write_image(), and finally png_write_end().
+
+(The final parameter of this call is not yet used. Someday it might point
+to transformation parameters required by some future output transform.)
+
+.SS The low-level write interface
+
+If you are going the low-level route instead, you are now ready to
+write all the file information up to the actual image data. You do
+this with a call to png_write_info().
+
+ png_write_info(png_ptr, info_ptr);
+
+Note that there is one transformation you may need to do before
+png_write_info(). In PNG files, the alpha channel in an image is the
+level of opacity. If your data is supplied as a level of
+transparency, you can invert the alpha channel before you write it, so
+that 0 is fully transtqparent and 255 (in 8-bit or paletted images) or
+65535 (in 16-bit images) is fully opaque, with
+
+ png_set_invert_alpha(png_ptr);
+
+This must appear before png_write_info() instead of later with the
+other transformations because in the case of paletted images the tRNS
+chunk data has to be inverted before the tRNS chunk is written. If
+your image is not a paletted image, the tRNS data (which in such cases
+represents a single color to be rendered as transtqparent) won't need to
+be changed, and you can safely do this transformation after your
+png_write_info() call.
+
+If you need to write a private chunk that you want to appear before
+the PLTE chunk when PLTE is present, you can write the PNG info in
+two steps, and insert code to write your own chunk between them:
+
+ png_write_info_before_PLTE(png_ptr, info_ptr);
+ png_set_unknown_chunks(png_ptr, info_ptr, ...);
+ png_write_info(png_ptr, info_ptr);
+
+After you've written the file information, you can set up the library
+to handle any special transformations of the image data. The various
+ways to transform the data will be described in the order that they
+should occur. This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths. Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data. For example, don't swap red and blue on grayscale data.
+
+PNG files store RGB pixels packed into 3 or 6 bytes. This code tells
+the library to strip input data that has 4 or 8 bytes per pixel down
+to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2
+bytes per pixel).
+
+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+
+where the 0 is unused, and the location is either PNG_FILLER_BEFORE or
+PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel
+is stored XRGB or RGBX.
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit files.
+If the data is supplied at 1 pixel per byte, use this code, which will
+correctly pack the pixels into a single byte:
+
+ png_set_packing(png_ptr);
+
+PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your
+data is of another bit depth, you can write an sBIT chunk into the
+file so that decoders can recover the original data if desired.
+
+ /* Set the true bit depth of the image data */
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ sig_bit.red = true_bit_depth;
+ sig_bit.green = true_bit_depth;
+ sig_bit.blue = true_bit_depth;
+ }
+ else
+ {
+ sig_bit.gray = true_bit_depth;
+ }
+ if (color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ sig_bit.alpha = true_bit_depth;
+ }
+
+ png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+
+If the data is stored in the row buffer in a bit depth other than
+one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),
+this will scale the values to appear to be the correct bit depth as
+is required by PNG.
+
+ png_set_shift(png_ptr, &sig_bit);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first). This code would be used if they are
+supplied the other way (little-endian, i.e. least significant bits
+first, the way PCs store them):
+
+ if (bit_depth > 8)
+ png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+ if (bit_depth < 8)
+ png_set_packswap(png_ptr);
+
+PNG files store 3 color pixels in red, green, blue order. This code
+would be used if they are supplied as blue, green, red:
+
+ png_set_bgr(png_ptr);
+
+PNG files describe monochrome as black being zero and white being
+one. This code would be used if the pixels are supplied with this reversed
+(black being one and white being zero):
+
+ png_set_invert_mono(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs. This is done by setting a callback
+with
+
+ png_set_write_user_transform_fn(png_ptr,
+ write_transform_fn);
+
+You must supply the function
+
+ void write_transform_fn(png_ptr ptr, row_info_ptr
+ row_info, png_bytep data)
+
+See pngtest.c for a working example. Your function will be called
+before any of the other transformations are processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function.
+
+ png_set_user_transform_info(png_ptr, user_ptr, 0, 0);
+
+The user_channels and user_depth parameters of this function are ignored
+when writing; you can set them to zero as shown.
+
+You can retrieve the pointer via the function png_get_user_transform_ptr().
+For example:
+
+ voidp write_user_transform_ptr =
+ png_get_user_transform_ptr(png_ptr);
+
+It is possible to have libpng flush any pending output, either manually,
+or automatically after a certain number of lines have been written. To
+flush the output stream a single time call:
+
+ png_write_flush(png_ptr);
+
+and to have libpng flush the output stream periodically after a certain
+number of scanlines have been written, call:
+
+ png_set_flush(png_ptr, nrows);
+
+Note that the distance between rows is from the last time png_write_flush()
+was called, or the first row of the image if it has never been called.
+So if you write 50 lines, and then png_set_flush 25, it will flush the
+output on the next scanline, and every 25 lines thereafter, unless
+png_write_flush() is called before 25 more lines have been written.
+If nrows is too small (less than about 10 lines for a 640 pixel wide
+RGB image) the image compression may decrease noticeably (although this
+may be acceptable for real-time applications). Infrequent flushing will
+only degrade the compression performance by a few percent over images
+that do not use flushing.
+
+.SS Writing the image data
+
+That's it for the transformations. Now you can write the image data.
+The simplest way to do this is in one function call. If you have the
+whole image in memory, you can just call png_write_image() and libpng
+will write the image. You will need to pass in an array of pointers to
+each row. This function automatically handles interlacing, so you don't
+need to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_write_rows().
+
+ png_write_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+ png_byte *row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to write the whole image at once, you can
+use png_write_rows() instead. If the file is not interlaced,
+this is simple:
+
+ png_write_rows(png_ptr, row_pointers,
+ number_of_rows);
+
+row_pointers is the same as in the png_write_image() call.
+
+If you are just writing one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+ png_bytep row_pointer = row;
+
+ png_write_row(png_ptr, row_pointer);
+
+When the file is interlaced, things can get a good deal more
+complicated. The only currently (as of the PNG Specification
+version 1.2, dated July 1999) defined interlacing scheme for PNG files
+is the "Adam7" interlace scheme, that breaks down an
+image into seven smaller images of varying size. libpng will build
+these images for you, or you can do them yourself. If you want to
+build them yourself, see the PNG specification for details of which
+pixels to write when.
+
+If you don't want libpng to handle the interlacing details, just
+use png_set_interlace_handling() and call png_write_rows() the
+correct number of times to write all seven sub-images.
+
+If you want libpng to build the sub-images, call this before you start
+writing any rows:
+
+ number_of_passes =
+ png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed. Currently, this
+is seven, but may change if another interlace type is added.
+
+Then write the complete image number_of_passes times.
+
+ png_write_rows(png_ptr, row_pointers,
+ number_of_rows);
+
+As some of these rows are not used, and thus return immediately,
+you may want to read about interlacing in the PNG specification,
+and only update the rows that are actually used.
+
+.SS Finishing a sequential write
+
+After you are finished writing the image, you should finish writing
+the file. If you are interested in writing comments or time, you should
+pass an appropriately filled png_info pointer. If you are not interested,
+you can pass NULL.
+
+ png_write_end(png_ptr, info_ptr);
+
+When you are done, you can free all memory used by libpng like this:
+
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+ png_free_data(png_ptr, info_ptr, tqmask, seq)
+ tqmask - identifies data to be freed, a tqmask
+ containing the logical OR of one or
+ more of
+ PNG_FREE_PLTE, PNG_FREE_TRNS,
+ PNG_FREE_HIST, PNG_FREE_ICCP,
+ PNG_FREE_PCAL, PNG_FREE_ROWS,
+ PNG_FREE_SCAL, PNG_FREE_SPLT,
+ PNG_FREE_TEXT, PNG_FREE_UNKN,
+ or simply PNG_FREE_ALL
+ seq - sequence number of item to be freed
+ (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user and not by libpng, and will in those
+cases do nothing. The "seq" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed. If "seq" is not
+-1, and multiple items are allowed for the data type identified in
+the tqmask, such as text or sPLT, only the n'th item in the structure
+is freed, where n is "seq".
+
+If you allocated data such as a palette that you passed
+in to libpng with png_set_*, you must not free it until just before the call to
+png_destroy_write_struct().
+
+The default behavior is only to free data that was allocated internally
+by libpng. This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+ png_data_freer(png_ptr, info_ptr, freer, tqmask)
+ tqmask - which data elements are affected
+ same choices as in png_free_data()
+ freer - one of
+ PNG_DESTROY_WILL_FREE_DATA
+ PNG_SET_WILL_FREE_DATA
+ PNG_USER_WILL_FREE_DATA
+
+For example, to transfer responsibility for some data from a read structure
+to a write structure, you could use
+
+ png_data_freer(read_ptr, read_info_ptr,
+ PNG_USER_WILL_FREE_DATA,
+ PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+ png_data_freer(write_ptr, write_info_ptr,
+ PNG_DESTROY_WILL_FREE_DATA,
+ PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+
+thereby briefly reassigning responsibility for freeing to the user but
+immediately afterwards reassigning it once more to the write_destroy
+function. Having done this, it would then be safe to destroy the read
+structure and continue to use the PLTE, tRNS, and hIST data in the write
+structure.
+
+This function only affects data that has already been allocated.
+You can call this function before calling after the png_set_*() functions
+to control whether the user or png_destroy_*() is supposed to free the data.
+When the user assumes responsibility for libpng-allocated data, the
+application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key. Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+For a more compact example of writing a PNG image, see the file example.c.
+
+.SH V. Modifying/Customizing libpng:
+
+There are three issues here. The first is changing how libpng does
+standard things like memory allocation, input/output, and error handling.
+The second deals with more complicated things like adding new chunks,
+adding new transformations, and generally changing how libpng works.
+Both of those are compile-time issues; that is, they are generally
+determined at the time the code is written, and there is rarely a need
+to provide the user with a means of changing them. The third is a
+run-time issue: choosing between and/or tuning one or more alternate
+versions of computationally intensive routines; specifically, optimized
+assembly-language (and therefore compiler- and platform-dependent)
+versions.
+
+Memory allocation, input/output, and error handling
+
+All of the memory allocation, input/output, and error handling in libpng
+goes through callbacks that are user-settable. The default routines are
+in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively. To change
+these functions, call the appropriate png_set_*_fn() function.
+
+Memory allocation is done through the functions png_malloc()
+and png_free(). These currently just call the standard C functions. If
+your pointers can't access more then 64K at a time, you will want to set
+MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling
+memory allocation on a platform will change between applications, these
+functions must be modified in the library at compile time. If you prefer
+to use a different method of allocating and freeing data, you can use
+png_create_read_struct_2() or png_create_write_struct_2() to register
+your own functions as described above.
+
+These functions also provide a void pointer that can be retrieved via
+
+ mem_ptr=png_get_mem_ptr(png_ptr);
+
+Your tqreplacement memory functions must have prototypes as follows:
+
+ png_voidp malloc_fn(png_structp png_ptr,
+ png_size_t size);
+ void free_fn(png_structp png_ptr, png_voidp ptr);
+
+Your malloc_fn() should return NULL in case of failure. The png_malloc()
+function will call png_error() if it receives a NULL from the system
+memory allocator or from your tqreplacement malloc_fn().
+
+Input/Output in libpng is done through png_read() and png_write(),
+which currently just call fread() and fwrite(). The FILE * is stored in
+png_struct and is initialized via png_init_io(). If you wish to change
+the method of I/O, the library supplies callbacks that you can set
+through the function png_set_read_fn() and png_set_write_fn() at run
+time, instead of calling the png_init_io() function. These functions
+also provide a void pointer that can be retrieved via the function
+png_get_io_ptr(). For example:
+
+ png_set_read_fn(png_structp read_ptr,
+ voidp read_io_ptr, png_rw_ptr read_data_fn)
+
+ png_set_write_fn(png_structp write_ptr,
+ voidp write_io_ptr, png_rw_ptr write_data_fn,
+ png_flush_ptr output_flush_fn);
+
+ voidp read_io_ptr = png_get_io_ptr(read_ptr);
+ voidp write_io_ptr = png_get_io_ptr(write_ptr);
+
+The tqreplacement I/O functions must have prototypes as follows:
+
+ void user_read_data(png_structp png_ptr,
+ png_bytep data, png_size_t length);
+ void user_write_data(png_structp png_ptr,
+ png_bytep data, png_size_t length);
+ void user_flush_data(png_structp png_ptr);
+
+Supplying NULL for the read, write, or flush functions sets them back
+to using the default C stream functions. It is an error to read from
+a write stream, and vice versa.
+
+Error handling in libpng is done through png_error() and png_warning().
+Errors handled through png_error() are fatal, meaning that png_error()
+should never return to its caller. Currently, this is handled via
+setjmp() and longjmp() (unless you have compiled libpng with
+PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()),
+but you could change this to do things like exit() if you should wish.
+
+On non-fatal errors, png_warning() is called
+to print a warning message, and then control returns to the calling code.
+By default png_error() and png_warning() print a message on stderr via
+fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined
+(because you don't want the messages) or PNG_NO_STDIO defined (because
+fprintf() isn't available). If you wish to change the behavior of the error
+functions, you will need to set up your own message callbacks. These
+functions are normally supplied at the time that the png_struct is created.
+It is also possible to redirect errors and warnings to your own tqreplacement
+functions after png_create_*_struct() has been called by calling:
+
+ png_set_error_fn(png_structp png_ptr,
+ png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warning_fn);
+
+ png_voidp error_ptr = png_get_error_ptr(png_ptr);
+
+If NULL is supplied for either error_fn or warning_fn, then the libpng
+default function will be used, calling fprintf() and/or longjmp() if a
+problem is encountered. The tqreplacement error functions should have
+parameters as follows:
+
+ void user_error_fn(png_structp png_ptr,
+ png_const_charp error_msg);
+ void user_warning_fn(png_structp png_ptr,
+ png_const_charp warning_msg);
+
+The motivation behind using setjmp() and longjmp() is the C++ throw and
+catch exception handling methods. This makes the code much easier to write,
+as there is no need to check every return code of every function call.
+However, there are some uncertainties about the status of local variables
+after a longjmp, so the user may want to be careful about doing anything after
+setjmp returns non-zero besides returning itself. Consult your compiler
+documentation for more details. For an alternative approach, you may wish
+to use the "cexcept" facility (see http://cexcept.sourceforge.net).
+
+.SS Custom chunks
+
+If you need to read or write custom chunks, you may need to get deeper
+into the libpng code. The library now has mechanisms for storing
+and writing chunks of unknown type; you can even declare callbacks
+for custom chunks. Hoewver, this may not be good enough if the
+library code itself needs to know about interactions between your
+chunk and existing `intrinsic' chunks.
+
+If you need to write a new intrinsic chunk, first read the PNG
+specification. Acquire a first level of
+understanding of how it works. Pay particular attention to the
+sections that describe chunk names, and look at how other chunks were
+designed, so you can do things similarly. Second, check out the
+sections of libpng that read and write chunks. Try to tqfind a chunk
+that is similar to yours and use it as a template. More details can
+be found in the comments inside the code. It is best to handle unknown
+chunks in a generic method, via callback functions, instead of by
+modifying libpng functions.
+
+If you wish to write your own transformation for the data, look through
+the part of the code that does the transformations, and check out some of
+the simpler ones to get an idea of how they work. Try to tqfind a similar
+transformation to the one you want to add and copy off of it. More details
+can be found in the comments inside the code itself.
+
+.SS Configuring for 16 bit platforms
+
+You will want to look into zconf.h to tell zlib (and thus libpng) that
+it cannot allocate more then 64K at a time. Even if you can, the memory
+won't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K.
+
+.SS Configuring for DOS
+
+For DOS users who only have access to the lower 640K, you will
+have to limit zlib's memory usage via a png_set_compression_mem_level()
+call. See zlib.h or zconf.h in the zlib library for more information.
+
+.SS Configuring for Medium Model
+
+Libpng's support for medium model has been tested on most of the popular
+compilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
+defined, and FAR gets defined to far in pngconf.h, and you should be
+all set. Everything in the library (except for zlib's structure) is
+expecting far data. You must use the typedefs with the p or pp on
+the end for pointers (or at least look at them and be careful). Make
+note that the rows of data are defined as png_bytepp, which is an
+unsigned char far * far *.
+
+.SS Configuring for gui/windowing platforms:
+
+You will need to write new error and warning functions that use the GUI
+interface, as described previously, and set them to be the error and
+warning functions at the time that png_create_*_struct() is called,
+in order to have them available during the structure initialization.
+They can be changed later via png_set_error_fn(). On some compilers,
+you may also have to change the memory allocators (png_malloc, etc.).
+
+.SS Configuring for compiler xxx:
+
+All includes for libpng are in pngconf.h. If you need to add/change/delete
+an include, this is the place to do it. The includes that are not
+needed outside libpng are protected by the PNG_INTERNAL definition,
+which is only defined for those routines inside libpng itself. The
+files in libpng proper only include png.h, which includes pngconf.h.
+
+.SS Configuring zlib:
+
+There are special functions to configure the compression. Perhaps the
+most useful one changes the compression level, which currently uses
+input compression values in the range 0 - 9. The library normally
+uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests
+have shown that for a large majority of images, compression values in
+the range 3-6 compress nearly as well as higher levels, and do so much
+faster. For online applications it may be desirable to have maximum speed
+(Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also
+specify no compression (Z_NO_COMPRESSION = 0), but this would create
+files larger than just storing the raw bitmap. You can specify the
+compression level by calling:
+
+ png_set_compression_level(png_ptr, level);
+
+Another useful one is to reduce the memory level used by the library.
+The memory level defaults to 8, but it can be lowered if you are
+short on memory (running DOS, for example, where you only have 640K).
+Note that the memory level does have an effect on compression; among
+other things, lower levels will result in sections of incompressible
+data being emitted in smaller stored blocks, with a correspondingly
+larger relative overhead of up to 15% in the worst case.
+
+ png_set_compression_mem_level(png_ptr, level);
+
+The other functions are for configuring zlib. They are not recommended
+for normal use and may result in writing an invalid PNG file. See
+zlib.h for more information on what these mean.
+
+ png_set_compression_strategy(png_ptr,
+ strategy);
+ png_set_compression_window_bits(png_ptr,
+ window_bits);
+ png_set_compression_method(png_ptr, method);
+ png_set_compression_buffer_size(png_ptr, size);
+
+.SS Controlling row filtering
+
+If you want to control whether libpng uses filtering or not, which
+filters are used, and how it goes about picking row filters, you
+can call one of these functions. The selection and configuration
+of row filters can have a significant impact on the size and
+encoding speed and a somewhat lesser impact on the decoding speed
+of an image. Filtering is enabled by default for RGB and grayscale
+images (with and without alpha), but not for paletted images nor
+for any images with bit depths less than 8 bits/pixel.
+
+The 'method' parameter sets the main filtering method, which is
+currently only '0' in the PNG 1.2 specification. The 'filters'
+parameter sets which filter(s), if any, should be used for each
+scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
+to turn filtering on and off, respectively.
+
+Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
+PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
+ORed together with '|' to specify one or more filters to use.
+These filters are described in more detail in the PNG specification.
+If you intend to change the filter type during the course of writing
+the image, you should start with flags set for all of the filters
+you intend to use so that libpng can initialize its internal
+structures appropriately for all of the filter types. (Note that this
+means the first row must always be adaptively filtered, because libpng
+currently does not allocate the filter buffers until png_write_row()
+is called for the first time.)
+
+ filters = PNG_FILTER_NONE | PNG_FILTER_SUB
+ PNG_FILTER_UP | PNG_FILTER_AVE |
+ PNG_FILTER_PAETH | PNG_ALL_FILTERS;
+
+ png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
+ filters);
+ The second parameter can also be
+ PNG_INTRAPIXEL_DIFFERENCING if you are
+ writing a PNG to be embedded in a MNG
+ datastream. This parameter must be the
+ same as the value of filter_method used
+ in png_set_IHDR().
+
+It is also possible to influence how libpng chooses from among the
+available filters. This is done in one or both of two ways - by
+telling it how important it is to keep the same filter for successive
+rows, and by telling it the relative computational costs of the filters.
+
+ double weights[3] = {1.5, 1.3, 1.1},
+ costs[PNG_FILTER_VALUE_LAST] =
+ {1.0, 1.3, 1.3, 1.5, 1.7};
+
+ png_set_filter_heuristics(png_ptr,
+ PNG_FILTER_HEURISTIC_WEIGHTED, 3,
+ weights, costs);
+
+The weights are multiplying factors that indicate to libpng that the
+row filter should be the same for successive rows unless another row filter
+is that many times better than the previous filter. In the above example,
+if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
+"sum of absolute differences" 1.5 x 1.3 times higher than other filters
+and still be chosen, while the NONE filter could have a sum 1.1 times
+higher than other filters and still be chosen. Unspecified weights are
+taken to be 1.0, and the specified weights should probably be declining
+like those above in order to emphasize recent filters over older filters.
+
+The filter costs specify for each filter type a relative decoding cost
+to be considered when selecting row filters. This means that filters
+with higher costs are less likely to be chosen over filters with lower
+costs, unless their "sum of absolute differences" is that much smaller.
+The costs do not necessarily reflect the exact computational speeds of
+the various filters, since this would unduly influence the final image
+size.
+
+Note that the numbers above were invented purely for this example and
+are given only to help explain the function usage. Little testing has
+been done to tqfind optimum values for either the costs or the weights.
+
+.SS Removing unwanted object code
+
+There are a bunch of #define's in pngconf.h that control what parts of
+libpng are compiled. All the defines end in _SUPPORTED. If you are
+never going to use a capability, you can change the #define to #undef
+before recompiling libpng and save yourself code and data space, or
+you can turn off individual capabilities with defines that begin with
+PNG_NO_.
+
+You can also turn all of the transforms and ancillary chunk capabilities
+off en masse with compiler directives that define
+PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
+or all four,
+along with directives to turn on any of the capabilities that you do
+want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable
+the extra transformations but still leave the library fully capable of reading
+and writing PNG files with all known public chunks
+Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive
+produces a library that is incapable of reading or writing ancillary chunks.
+If you are not using the progressive reading capability, you can
+turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse
+this with the INTERLACING capability, which you'll still have).
+
+All the reading and writing specific code are in separate files, so the
+linker should only grab the files it needs. However, if you want to
+make sure, or if you are building a stand alone library, all the
+reading files start with pngr and all the writing files start with
+pngw. The files that don't match either (like png.c, pngtrans.c, etc.)
+are used for both reading and writing, and always need to be included.
+The progressive reader is in pngpread.c
+
+If you are creating or distributing a dynamically linked library (a .so
+or DLL file), you should not remove or disable any parts of the library,
+as this will cause applications linked with different versions of the
+library to fail if they call functions not available in your library.
+The size of the library itself should not be an issue, because only
+those sections that are actually used will be loaded into memory.
+
+.SS Requesting debug printout
+
+The macro definition PNG_DEBUG can be used to request debugging
+printout. Set it to an integer value in the range 0 to 3. Higher
+numbers result in increasing amounts of debugging information. The
+information is printed to the "stderr" file, unless another file
+name is specified in the PNG_DEBUG_FILE macro definition.
+
+When PNG_DEBUG > 0, the following functions (macros) become available:
+
+ png_debug(level, message)
+ png_debug1(level, message, p1)
+ png_debug2(level, message, p1, p2)
+
+in which "level" is compared to PNG_DEBUG to decide whether to print
+the message, "message" is the formatted string to be printed,
+and p1 and p2 are parameters that are to be embedded in the string
+according to printf-style formatting directives. For example,
+
+ png_debug1(2, "foo=%d\n", foo);
+
+is expanded to
+
+ if(PNG_DEBUG > 2)
+ fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
+
+When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
+can still use PNG_DEBUG to control your own debugging:
+
+ #ifdef PNG_DEBUG
+ fprintf(stderr, ...
+ #endif
+
+When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
+having level = 0 will be printed. There aren't any such statements in
+this version of libpng, but if you insert some they will be printed.
+
+.SH VI. Runtime optimization
+
+A new feature in libpng 1.2.0 is the ability to dynamically switch between
+standard and optimized versions of some routines. Currently these are
+limited to three computationally intensive tasks when reading PNG files:
+decoding row filters, expanding interlacing, and combining interlaced or
+transtqparent row data with previous row data. Currently the optimized
+versions are available only for x86 (Intel, AMD, etc.) platforms with
+MMX support, though this may change in future versions. (For example,
+the non-MMX assembler optimizations for zlib might become similarly
+runtime-selectable in future releases, in which case libpng could be
+extended to support them. Alternatively, the compile-time choice of
+floating-point versus integer routines for gamma correction might become
+runtime-selectable.)
+
+Because such optimizations tend to be very platform- and compiler-dependent,
+both in how they are written and in how they perform, the new runtime code
+in libpng has been written to allow programs to query, enable, and disable
+either specific optimizations or all such optimizations. For example, to
+enable all possible optimizations (bearing in mind that some "optimizations"
+may actually run more slowly in rare cases):
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ png_uint_32 tqmask, flags;
+
+ flags = png_get_asm_flags(png_ptr);
+ tqmask = png_get_asm_flagtqmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+ png_set_asm_flags(png_ptr, flags | tqmask);
+ #endif
+
+To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ
+by itself when calling png_get_asm_flagtqmask(); similarly for optimizing
+only writing. To disable all optimizations:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ flags = png_get_asm_flags(png_ptr);
+ tqmask = png_get_asm_flagtqmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+ png_set_asm_flags(png_ptr, flags & ~tqmask);
+ #endif
+
+To enable or disable only MMX-related features, use png_get_mmx_flagtqmask()
+in place of png_get_asm_flagtqmask(). The mmx version takes one additional
+parameter:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ int selection = PNG_SELECT_READ | PNG_SELECT_WRITE;
+ int compilerID;
+
+ tqmask = png_get_mmx_flagtqmask(selection, &compilerID);
+ #endif
+
+On return, compilerID will indicate which version of the MMX assembler
+optimizations was compiled. Currently two flavors exist: Microsoft
+Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2).
+On non-x86 platforms or on systems compiled without MMX optimizations, a
+value of -1 is used.
+
+Note that both png_get_asm_flagtqmask() and png_get_mmx_flagtqmask() return
+all valid, settable optimization bits for the version of the library that's
+currently in use. In the case of shared (dynamically linked) libraries,
+this may include optimizations that did not exist at the time the code was
+written and compiled. It is also possible, of course, to enable only known,
+specific optimizations; for example:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
+ | PNG_ASM_FLAG_MMX_READ_INTERLACE \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_UP \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+ png_set_asm_flags(png_ptr, flags);
+ #endif
+
+This method would enable only the MMX read-optimizations available at the
+time of libpng 1.2.0's release, regardless of whether a later version of
+the DLL were actually being used. (Also note that these functions did not
+exist in versions older than 1.2.0, so any attempt to run a dynamically
+linked app on such an older version would fail.)
+
+To determine whether the processor supports MMX instructions at all, use
+the png_mmx_support() function:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ mmxsupport = png_mmx_support();
+ #endif
+
+It returns -1 if MMX support is not compiled into libpng, 0 if MMX code
+is compiled but MMX is not supported by the processor, or 1 if MMX support
+is fully available. Note that png_mmx_support(), png_get_mmx_flagtqmask(),
+and png_get_asm_flagtqmask() all may be called without allocating and ini-
+tializing any PNG structures (for example, as part of a usage screen or
+"about" box).
+
+The following code can be used to prevent an application from using the
+thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK
+defined:
+
+#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \
+ && defined(PNG_THREAD_UNSAFE_OK)
+ /* Disable thread-unsafe features of pnggccrd */
+ if (png_access_version() >= 10200)
+ {
+ png_uint_32 mmx_disable_mask = 0;
+ png_uint_32 asm_flags;
+
+ mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
+ asm_flags = png_get_asm_flags(png_ptr);
+ png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask);
+ }
+#endif
+
+For more extensive examples of runtime querying, enabling and disabling
+of optimized features, see contrib/gregbook/readpng2.c in the libpng
+source-code distribution.
+
+
+.SH VII. MNG support
+
+The MNG specification (available at http://www.libpng.org/pub/mng) allows
+certain extensions to PNG for PNG images that are embedded in MNG datastreams.
+Libpng can support some of these extensions. To enable them, use the
+png_permit_mng_features() function:
+
+ feature_set = png_permit_mng_features(png_ptr, tqmask)
+ tqmask is a png_uint_32 containing the logical OR of the
+ features you want to enable. These include
+ PNG_FLAG_MNG_EMPTY_PLTE
+ PNG_FLAG_MNG_FILTER_64
+ PNG_ALL_MNG_FEATURES
+ feature_set is a png_32_uint that is the logical AND of
+ your tqmask with the set of MNG features that is
+ supported by the version of libpng that you are using.
+
+It is an error to use this function when reading or writing a standalone
+PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped
+in a MNG datastream. As a minimum, it must have the MNG 8-byte signature
+and the MHDR and MEND chunks. Libpng does not provide support for these
+or any other MNG chunks; your application must provide its own support for
+them. You may wish to consider using libmng (available at
+http://www.libmng.com) instead.
+
+.SH VIII. Changes to Libpng from version 0.88
+
+It should be noted that versions of libpng later than 0.96 are not
+distributed by the original libpng author, Guy Schalnat, nor by
+Andreas Dilger, who had taken over from Guy during 1996 and 1997, and
+distributed versions 0.89 through 0.96, but rather by another member
+of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are
+still alive and well, but they have moved on to other things.
+
+The old libpng functions png_read_init(), png_write_init(),
+png_info_init(), png_read_destroy(), and png_write_destroy() have been
+moved to PNG_INTERNAL in version 0.95 to discourage their use. These
+functions will be removed from libpng version 2.0.0.
+
+The preferred method of creating and initializing the libpng structures is
+via the png_create_read_struct(), png_create_write_struct(), and
+png_create_info_struct() because they isolate the size of the structures
+from the application, allow version error checking, and also allow the
+use of custom error handling routines during the initialization, which
+the old functions do not. The functions png_read_destroy() and
+png_write_destroy() do not actually free the memory that libpng
+allocated for these structs, but just reset the data structures, so they
+can be used instead of png_destroy_read_struct() and
+png_destroy_write_struct() if you feel there is too much system overhead
+allocating and freeing the png_struct for each image read.
+
+Setting the error callbacks via png_set_message_fn() before
+png_read_init() as was suggested in libpng-0.88 is no longer supported
+because this caused applications that do not use custom error functions
+to fail if the png_ptr was not initialized to zero. It is still possible
+to set the error callbacks AFTER png_read_init(), or to change them with
+png_set_error_fn(), which is essentially the same function, but with a new
+name to force compilation errors with applications that try to use the old
+method.
+
+Starting with version 1.0.7, you can tqfind out which version of the library
+you are using at run-time:
+
+ png_uint_32 libpng_vn = png_access_version_number();
+
+The number libpng_vn is constructed from the major version, minor
+version with leading zero, and release number with leading zero,
+(e.g., libpng_vn for version 1.0.7 is 10007).
+
+You can also check which version of png.h you used when compiling your
+application:
+
+ png_uint_32 application_vn = PNG_LIBPNG_VER;
+
+.SH IX. Y2K Compliance in libpng
+
+October 3, 2002
+
+Since the PNG Development group is an ad-hoc body, we can't make
+an official declaration.
+
+This is your unofficial assurance that libpng from version 0.71 and
+upward through 1.2.5 are Y2K compliant. It is my belief that earlier
+versions were also Y2K compliant.
+
+Libpng only has three year fields. One is a 2-byte unsigned integer that
+will hold years up to 65535. The other two hold the date in text
+format, and will hold years up to 9999.
+
+The integer is
+ "png_uint_16 year" in png_time_struct.
+
+The strings are
+ "png_charp time_buffer" in png_struct and
+ "near_time_buffer", which is a local character string in png.c.
+
+There are seven time-related functions:
+
+ png_convert_to_rfc_1123() in png.c
+ (formerly png_convert_to_rfc_1152() in error)
+ png_convert_from_struct_tm() in pngwrite.c, called
+ in pngwrite.c
+ png_convert_from_time_t() in pngwrite.c
+ png_get_tIME() in pngget.c
+ png_handle_tIME() in pngrutil.c, called in pngread.c
+ png_set_tIME() in pngset.c
+ png_write_tIME() in pngwutil.c, called in pngwrite.c
+
+All appear to handle dates properly in a Y2K environment. The
+png_convert_from_time_t() function calls gmtime() to convert from system
+clock time, which returns (year - 1900), which we properly convert to
+the full 4-digit year. There is a possibility that applications using
+libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+function, or that they are incorrectly passing only a 2-digit year
+instead of "year - 1900" into the png_convert_from_struct_tm() function,
+but this is not under our control. The libpng documentation has always
+stated that it works with 4-digit years, and the APIs have been
+documented as such.
+
+The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
+integer to hold the year, and can hold years as large as 65535.
+
+zlib, upon which libpng depends, is also Y2K compliant. It tqcontains
+no date-related code.
+
+
+ Glenn Randers-Pehrson
+ libpng maintainer
+ PNG Development Group
+
+.SH NOTE
+
+Note about libpng version numbers:
+
+Due to various miscommunications, unforeseen code incompatibilities
+and occasional factors outside the authors' control, version numbering
+on the library has not always been consistent and straightforward.
+The following table summarizes matters since version 0.89c, which was
+the first widely used release:
+
+ source png.h png.h shared-lib
+ version string int version
+ ------- ------ ----- ----------
+ 0.89c ("beta 3") 0.89 89 1.0.89
+ 0.90 ("beta 4") 0.90 90 0.90
+ 0.95 ("beta 5") 0.95 95 0.95
+ 0.96 ("beta 6") 0.96 96 0.96
+ 0.97b ("beta 7") 1.00.97 97 1.0.1
+ 0.97c 0.97 97 2.0.97
+ 0.98 0.98 98 2.0.98
+ 0.99 0.99 98 2.0.99
+ 0.99a-m 0.99 99 2.0.99
+ 1.00 1.00 100 2.1.0
+ 1.0.0 1.0.0 100 2.1.0
+ 1.0.0 (from here on, the 100 2.1.0
+ 1.0.1 png.h string is 10001 2.1.0
+ 1.0.1a-e identical to the 10002 from here on, the
+ 1.0.2 source version) 10002 shared library is 2.V
+ 1.0.2a-b 10003 where V is the source
+ 1.0.1 10001 code version except as
+ 1.0.1a-e 10002 2.1.0.1a-e noted.
+ 1.0.2 10002 2.1.0.2
+ 1.0.2a-b 10003 2.1.0.2a-b
+ 1.0.3 10003 2.1.0.3
+ 1.0.3a-d 10004 2.1.0.3a-d
+ 1.0.4 10004 2.1.0.4
+ 1.0.4a-f 10005 2.1.0.4a-f
+ 1.0.5 (+ 2 patches) 10005 2.1.0.5
+ 1.0.5a-d 10006 2.1.0.5a-d
+ 1.0.5e-r 10100 2.1.0.5e-r
+ 1.0.5s-v 10006 2.1.0.5s-v
+ 1.0.6 (+ 3 patches) 10006 2.1.0.6
+ 1.0.6d-g 10007 2.1.0.6d-g
+ 1.0.6h 10007 10.6h
+ 1.0.6i 10007 10.6i
+ 1.0.6j 10007 2.1.0.6j
+ 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14
+ 1.0.7beta15-18 1 10007 2.1.0.7beta15-18
+ 1.0.7rc1-2 1 10007 2.1.0.7rc1-2
+ 1.0.7 1 10007 2.1.0.7
+ 1.0.8beta1-4 1 10008 2.1.0.8beta1-4
+ 1.0.8rc1 1 10008 2.1.0.8rc1
+ 1.0.8 1 10008 2.1.0.8
+ 1.0.9beta1-6 1 10009 2.1.0.9beta1-6
+ 1.0.9rc1 1 10009 2.1.0.9rc1
+ 1.0.9beta7-10 1 10009 2.1.0.9beta7-10
+ 1.0.9rc2 1 10009 2.1.0.9rc2
+ 1.0.9 1 10009 2.1.0.9
+ 1.0.10beta1 1 10010 2.1.0.10beta1
+ 1.0.10rc1 1 10010 2.1.0.10rc1
+ 1.0.10 1 10010 2.1.0.10
+ 1.0.11beta1-3 1 10011 2.1.0.11beta1-3
+ 1.0.11rc1 1 10011 2.1.0.11rc1
+ 1.0.11 1 10011 2.1.0.11
+ 1.0.12beta1-2 2 10012 2.1.0.12beta1-2
+ 1.0.12rc1 2 10012 2.1.0.12rc1
+ 1.0.12 2 10012 2.1.0.12
+ 1.1.0a-f - 10100 2.1.1.0a-f abandoned
+ 1.2.0beta1-2 2 10200 2.1.2.0beta1-2
+ 1.2.0beta3-5 3 10200 3.1.2.0beta3-5
+ 1.2.0rc1 3 10200 3.1.2.0rc1
+ 1.2.0 3 10200 3.1.2.0
+ 1.2.1beta-4 3 10201 3.1.2.1beta1-4
+ 1.2.1rc1-2 3 10201 3.1.2.1rc1-2
+ 1.2.1 3 10201 3.1.2.1
+ 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6
+ 1.0.13beta1 10 10013 10.so.0.1.0.13beta1
+ 1.0.13rc1 10 10013 10.so.0.1.0.13rc1
+ 1.2.2rc1 12 10202 12.so.0.1.2.2rc1
+ 1.0.13 10 10013 10.so.0.1.0.13
+ 1.2.2 12 10202 12.so.0.1.2.2
+ 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6
+ 1.2.3 12 10203 12.so.0.1.2.3
+ 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3
+ 1.2.4rc1 13 10204 12.so.0.1.2.4rc1
+ 1.0.14 10 10014 10.so.0.1.0.14
+ 1.2.4 13 10204 12.so.0.1.2.4
+ 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3
+ 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3
+ 1.0.15 10 10015 10.so.0.1.0.15
+ 1.2.5 13 10205 12.so.0.1.2.5
+
+Henceforth the source version will match the shared-library minor
+and patch numbers; the shared-library major version number will be
+used for changes in backward compatibility, as it is intended. The
+PNG_PNGLIB_VER macro, which is not used within libpng but is available
+for applications, is an unsigned integer of the form xyyzz corresponding
+to the source version x.y.z (leading zeros in y and z). Beta versions
+were given the previous public release number plus a letter, until
+version 1.0.6j; from then on they were given the upcoming public
+release number plus "betaNN" or "rcN".
+
+.SH "SEE ALSO"
+libpngpf(3), png(5)
+.LP
+.IR libpng :
+.IP
+ftp://ftp.uu.net/graphics/png
+http://www.libpng.org/pub/png
+
+.LP
+.IR zlib :
+.IP
+(generally) at the same location as
+.I libpng
+or at
+.br
+ftp://ftp.uu.net/pub/archiving/zip/zlib
+.br
+ftp://ftp.info-zip.org/pub/infozip/zlib
+
+.LP
+.IR PNG specification: RFC 2083
+.IP
+(generally) at the same location as
+.I libpng
+or at
+.br
+ftp://ds.internic.net/rfc/rfc2083.txt
+.br
+or (as a W3C Recommendation) at
+.br
+http://www.w3.org/TR/REC-png.html
+
+.LP
+In the case of any inconsistency between the PNG specification
+and this library, the specification takes precedence.
+
+.SH AUTHORS
+This man page: Glenn Randers-Pehrson
+<randeg@alum.rpi.edu>
+
+The contributing authors would like to thank all those who helped
+with testing, bug fixes, and patience. This wouldn't have been
+possible without all of you.
+
+Thanks to Frank J. T. Wojcik for helping with the documentation.
+
+Libpng version 1.2.5 - October 3, 2002:
+Initially created in 1995 by Guy Eric Schalnat, then of Group 42, Inc.
+Currently maintained by Glenn Randers-Pehrson (randeg@alum.rpi.edu).
+
+Supported by the PNG development group
+.br
+(png-implement@ccrc.wustl.edu).
+
+.SH COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+
+(This copy of the libpng notices is provided for your convenience. In case of
+any discrepancy between this copy and the notices in the file png.h that is
+included in the libpng distribution, the latter shall prevail.)
+
+If you modify libpng you may insert additional notices immediately following
+this sentence.
+
+libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
+Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+distributed according to the same disclaimer and license as libpng-1.0.6
+with the following individuals added to the list of Contributing Authors
+
+ Simon-Pierre Cadieux
+ Eric S. Raymond
+ Gilles Vollant
+
+and with the following additions to the disclaimer:
+
+ There is no warranty against interference with your
+ enjoyment of the library or against infringement.
+ There is no warranty that our efforts or the library
+ will fulfill any of your particular purposes or needs.
+ This library is provided with all faults, and the entire
+ risk of satisfactory quality, performance, accuracy, and
+ effort is with the user.
+
+libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+Copyright (c) 1998, 1999 Glenn Randers-Pehrson
+Distributed according to the same disclaimer and license as libpng-0.96,
+with the following individuals added to the list of Contributing Authors:
+
+ Tom Lane
+ Glenn Randers-Pehrson
+ Willem van Schaik
+
+libpng versions 0.89, June 1996, through 0.96, May 1997, are
+Copyright (c) 1996, 1997 Andreas Dilger
+Distributed according to the same disclaimer and license as libpng-0.88,
+with the following individuals added to the list of Contributing Authors:
+
+ John Bowler
+ Kevin Bracey
+ Sam Bushell
+ Magnus Holmgren
+ Greg Roelofs
+ Tom Tanner
+
+libpng versions 0.5, May 1995, through 0.88, January 1996, are
+Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+
+For the purposes of this copyright and license, "Contributing Authors"
+is defined as the following set of individuals:
+
+ Andreas Dilger
+ Dave Martindale
+ Guy Eric Schalnat
+ Paul Schmidt
+ Tim Wegner
+
+The PNG Reference Library is supplied "AS IS". The Contributing Authors
+and Group 42, Inc. disclaim all warranties, expressed or implied,
+including, without limitation, the warranties of merchantability and of
+fitness for any purpose. The Contributing Authors and Group 42, Inc.
+assume no liability for direct, indirect, incidental, special, exemplary,
+or consequential damages, which may result from the use of the PNG
+Reference Library, even if advised of the possibility of such damage.
+
+Permission is hereby granted to use, copy, modify, and distribute this
+source code, or portions hereof, for any purpose, without fee, subject
+to the following restrictions:
+
+1. The origin of this source code must not be misrepresented.
+
+2. Altered versions must be plainly marked as such and
+ must not be misrepresented as being the original source.
+
+3. This Copyright notice may not be removed or altered from
+ any source or altered source distribution.
+
+The Contributing Authors and Group 42, Inc. specifically permit, without
+fee, and encourage the use of this source code as a component to
+supporting the PNG file format in commercial products. If you use this
+source code in a product, acknowledgment is not required but would be
+appreciated.
+
+
+A "png_get_copyright" function is available, for convenient use in "about"
+boxes and the like:
+
+ printf("%s",png_get_copyright(NULL));
+
+Also, the PNG logo (in PNG format, of course) is supplied in the
+files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+
+Libpng is OSI Certified Open Source Software. OSI Certified Open Source is a
+certification mark of the Open Source Initiative.
+
+Glenn Randers-Pehrson
+randeg@alum.rpi.edu
+October 3, 2002
+
+.\" end of man page
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/libpng.txt b/tqtinterface/qt4/src/3rdparty/libpng/libpng.txt
new file mode 100644
index 0000000..eb7132b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/libpng.txt
@@ -0,0 +1,2905 @@
+libpng.txt - A description on how to use and modify libpng
+
+ libpng version 1.2.5 - October 3, 2002
+ Updated and distributed by Glenn Randers-Pehrson
+ <randeg@alum.rpi.edu>
+ Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ For conditions of distribution and use, see copyright
+ notice in png.h.
+
+ based on:
+
+ libpng 1.0 beta 6 version 0.96 May 28, 1997
+ Updated and distributed by Andreas Dilger
+ Copyright (c) 1996, 1997 Andreas Dilger
+
+ libpng 1.0 beta 2 - version 0.88 January 26, 1996
+ For conditions of distribution and use, see copyright
+ notice in png.h. Copyright (c) 1995, 1996 Guy Eric
+ Schalnat, Group 42, Inc.
+
+ Updated/rewritten per request in the libpng FAQ
+ Copyright (c) 1995, 1996 Frank J. T. Wojcik
+ December 18, 1995 & January 20, 1996
+
+I. Introduction
+
+This file describes how to use and modify the PNG reference library
+(known as libpng) for your own use. There are five sections to this
+file: introduction, structures, reading, writing, and modification and
+configuration notes for various special platforms. In addition to this
+file, example.c is a good starting point for using the library, as
+it is heavily commented and should include everything most people
+will need. We assume that libpng is already installed; see the
+INSTALL file for instructions on how to install libpng.
+
+Libpng was written as a companion to the PNG specification, as a way
+of reducing the amount of time and effort it takes to support the PNG
+file format in application programs.
+
+The PNG-1.2 specification is available at <http://www.libpng.org/pub/png>
+and at <ftp://ftp.uu.net/graphics/png/documents/>.
+
+The PNG-1.0 specification is available
+as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/> and as a
+W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
+additional chunks are described in the special-purpose public chunks
+documents at <ftp://ftp.uu.net/graphics/png/documents/>.
+
+Other information
+about PNG, and the latest version of libpng, can be found at the PNG home
+page, <http://www.libpng.org/pub/png/>
+and at <ftp://ftp.uu.net/graphics/png/>.
+
+Most users will not have to modify the library significantly; advanced
+users may want to modify it more. All attempts were made to make it as
+complete as possible, while keeping the code easy to understand.
+Currently, this library only supports C. Support for other languages
+is being considered.
+
+Libpng has been designed to handle multiple sessions at one time,
+to be easily modifiable, to be portable to the vast majority of
+machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
+to use. The ultimate goal of libpng is to promote the acceptance of
+the PNG file format in whatever way possible. While there is still
+work to be done (see the TODO file), libpng should cover the
+majority of the needs of its users.
+
+Libpng uses zlib for its compression and decompression of PNG files.
+Further information about zlib, and the latest version of zlib, can
+be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
+The zlib compression utility is a general purpose utility that is
+useful for more than PNG files, and can be used without libpng.
+See the documentation delivered with zlib for more details.
+You can usually tqfind the source files for the zlib utility wherever you
+tqfind the libpng source files.
+
+Libpng is thread safe, provided the threads are using different
+instances of the structures. Each thread should have its own
+png_struct and png_info instances, and thus its own image.
+Libpng does not protect itself against two threads using the
+same instance of a structure. Note: thread safety may be defeated
+by use of some of the MMX assembler code in pnggccrd.c, which is only
+compiled when the user defines PNG_THREAD_UNSAFE_OK.
+
+
+II. Structures
+
+There are two main structures that are important to libpng, png_struct
+and png_info. The first, png_struct, is an internal structure that
+will not, for the most part, be used by a user except as the first
+variable passed to every libpng function call.
+
+The png_info structure is designed to provide information about the
+PNG file. At one time, the fields of png_info were intended to be
+directly accessible to the user. However, this tended to cause problems
+with applications using dynamically loaded libraries, and as a result
+a set of interface functions for png_info (the png_get_*() and png_set_*()
+functions) was developed. The fields of png_info are still available for
+older applications, but it is suggested that applications use the new
+interfaces if at all possible.
+
+Applications that do make direct access to the members of png_struct (except
+for png_ptr->jmpbuf) must be recompiled whenever the library is updated,
+and applications that make direct access to the members of png_info must
+be recompiled if they were compiled or loaded with libpng version 1.0.6,
+in which the members were in a different order. In version 1.0.7, the
+members of the png_info structure reverted to the old order, as they were
+in versions 0.97c through 1.0.5. Starting with version 2.0.0, both
+structures are going to be hidden, and the contents of the structures will
+only be accessible through the png_get/png_set functions.
+
+The png.h header file is an invaluable reference for programming with libpng.
+And while I'm on the topic, make sure you include the libpng header file:
+
+#include <png.h>
+
+III. Reading
+
+We'll now walk you through the possible functions to call when reading
+in a PNG file sequentially, briefly explaining the syntax and purpose
+of each one. See example.c and png.h for more detail. While
+progressive reading is covered in the next section, you will still
+need some of the functions discussed in this section to read a PNG
+file.
+
+Setup
+
+You will want to do the I/O initialization(*) before you get into libpng,
+so if it doesn't work, you don't have much to undo. Of course, you
+will also want to insure that you are, in fact, dealing with a PNG
+file. Libpng provides a simple check to see if a file is a PNG file.
+To use it, pass in the first 1 to 8 bytes of the file to the function
+png_sig_cmp(), and it will return 0 if the bytes match the corresponding
+bytes of the PNG signature, or nonzero otherwise. Of course, the more bytes
+you pass in, the greater the accuracy of the prediction.
+
+If you are intending to keep the file pointer open for use in libpng,
+you must ensure you don't read more than 8 bytes from the beginning
+of the file, and you also have to make a call to png_set_sig_bytes_read()
+with the number of bytes you read from the beginning. Libpng will
+then only check the bytes (if any) that your program didn't read.
+
+(*): If you are not using the standard I/O functions, you will need
+to tqreplace them with custom functions. See the discussion under
+Customizing libpng.
+
+
+ FILE *fp = fopen(file_name, "rb");
+ if (!fp)
+ {
+ return (ERROR);
+ }
+ fread(header, 1, number, fp);
+ is_png = !png_sig_cmp(header, 0, number);
+ if (!is_png)
+ {
+ return (NOT_PNG);
+ }
+
+
+Next, png_struct and png_info need to be allocated and initialized. In
+order to ensure that the size of these structures is correct even with a
+dynamically linked libpng, there are functions to initialize and
+allocate the structures. We also pass the library version, optional
+pointers to error handling functions, and a pointer to a data struct for
+use by the error functions, if necessary (the pointer and functions can
+be NULL if the default error handlers are to be used). See the section
+on Changes to Libpng below regarding the old initialization functions.
+The structure allocation functions quietly return NULL if they fail to
+create the structure, so your application should check for that.
+
+ png_structp png_ptr = png_create_read_struct
+ (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+ user_error_fn, user_warning_fn);
+ if (!png_ptr)
+ return (ERROR);
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_read_struct(&png_ptr,
+ (png_infopp)NULL, (png_infopp)NULL);
+ return (ERROR);
+ }
+
+ png_infop end_info = png_create_info_struct(png_ptr);
+ if (!end_info)
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ (png_infopp)NULL);
+ return (ERROR);
+ }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_read_struct_2() instead of png_create_read_struct():
+
+ png_structp png_ptr = png_create_read_struct_2
+ (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+ user_error_fn, user_warning_fn, (png_voidp)
+ user_mem_ptr, user_malloc_fn, user_free_fn);
+
+The error handling routines passed to png_create_read_struct()
+and the memory alloc/free routines passed to png_create_struct_2()
+are only necessary if you are not using the libpng supplied error
+handling and memory alloc/free functions.
+
+When libpng encounters an error, it expects to longjmp back
+to your routine. Therefore, you will need to call setjmp and pass
+your png_jmpbuf(png_ptr). If you read the file from different
+routines, you will need to update the jmpbuf field every time you enter
+a new routine that will call a png_*() function.
+
+See your documentation of setjmp/longjmp for your compiler for more
+information on setjmp/longjmp. See the discussion on libpng error
+handling in the Customizing Libpng section below for more information
+on the libpng error handling. If an error occurs, and libpng longjmp's
+back to your setjmp, you will want to call png_destroy_read_struct() to
+free any memory.
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ &end_info);
+ fclose(fp);
+ return (ERROR);
+ }
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the input code. The default for libpng is to
+use the C function fread(). If you use this, you will need to pass a
+valid FILE * in the function png_init_io(). Be sure that the file is
+opened in binary mode. If you wish to handle reading data in another
+way, you need not call the png_init_io() function, but you must then
+implement the libpng I/O methods discussed in the Customizing Libpng
+section below.
+
+ png_init_io(png_ptr, fp);
+
+If you had previously opened the file and read any of the signature from
+the beginning in order to see if this was a PNG file, you need to let
+libpng know that there are some bytes missing from the start of the file.
+
+ png_set_sig_bytes(png_ptr, number);
+
+Setting up callback code
+
+You can set up a callback function to handle any unknown chunks in the
+input stream. You must supply the function
+
+ read_chunk_callback(png_ptr ptr,
+ png_unknown_chunkp chunk);
+ {
+ /* The unknown chunk structure tqcontains your
+ chunk data: */
+ png_byte name[5];
+ png_byte *data;
+ png_size_t size;
+ /* Note that libpng has already taken care of
+ the CRC handling */
+
+ /* put your code here. Return one of the
+ following: */
+
+ return (-n); /* chunk had an error */
+ return (0); /* did not recognize */
+ return (n); /* success */
+ }
+
+(You can give your function another name that you like instead of
+"read_chunk_callback")
+
+To inform libpng about your function, use
+
+ png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,
+ read_chunk_callback);
+
+This names not only the callback function, but also a user pointer that
+you can retrieve with
+
+ png_get_user_chunk_ptr(png_ptr);
+
+At this point, you can set up a callback function that will be
+called after each row has been read, which you can use to control
+a progress meter or the like. It's demonstrated in pngtest.c.
+You must supply a function
+
+ void read_row_callback(png_ptr ptr, png_uint_32 row,
+ int pass);
+ {
+ /* put your code here */
+ }
+
+(You can give it another name that you like instead of "read_row_callback")
+
+To inform libpng about your function, use
+
+ png_set_read_status_fn(png_ptr, read_row_callback);
+
+Unknown-chunk handling
+
+Now you get to set the way the library processes unknown chunks in the
+input PNG stream. Both known and unknown chunks will be read. Normal
+behavior is that known chunks will be parsed into information in
+various info_ptr members; unknown chunks will be discarded. To change
+this, you can call:
+
+ png_set_keep_unknown_chunks(png_ptr, info_ptr, keep,
+ chunk_list, num_chunks);
+ keep - 0: do not keep
+ 1: keep only if safe-to-copy
+ 2: keep even if unsafe-to-copy
+ chunk_list - list of chunks affected (a byte string,
+ five bytes per chunk, NULL or '\0' if
+ num_chunks is 0)
+ num_chunks - number of chunks affected; if 0, all
+ unknown chunks are affected
+
+Unknown chunks declared in this way will be saved as raw data onto a
+list of png_unknown_chunk structures. If a chunk that is normally
+known to libpng is named in the list, it will be handled as unknown,
+according to the "keep" directive. If a chunk is named in successive
+instances of png_set_keep_unknown_chunks(), the final instance will
+take precedence.
+
+The high-level read interface
+
+At this point there are two ways to proceed; through the high-level
+read interface, or through a sequence of low-level read operations.
+You can use the high-level interface if (a) you are willing to read
+the entire image into memory, and (b) the input transformations
+you want to do are limited to the following set:
+
+ PNG_TRANSFORM_IDENTITY No transformation
+ PNG_TRANSFORM_STRIP_16 Strip 16-bit samples to
+ 8 bits
+ PNG_TRANSFORM_STRIP_ALPHA Discard the alpha channel
+ PNG_TRANSFORM_PACKING Expand 1, 2 and 4-bit
+ samples to bytes
+ PNG_TRANSFORM_PACKSWAP Change order of packed
+ pixels to LSB first
+ PNG_TRANSFORM_EXPAND Perform set_expand()
+ PNG_TRANSFORM_INVERT_MONO Invert monochrome images
+ PNG_TRANSFORM_SHIFT Normalize pixels to the
+ sBIT depth
+ PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA
+ to BGRA
+ PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA
+ to AG
+ PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity
+ to transparency
+ PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples
+
+(This excludes setting a background color, doing gamma transformation,
+dithering, and setting filler.) If this is the case, simply do this:
+
+ png_read_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of
+some set of transformation flags. This call is equivalent to png_read_info(),
+followed the set of transformations indicated by the transform tqmask,
+then png_read_image(), and finally png_read_end().
+
+(The final parameter of this call is not yet used. Someday it might point
+to transformation parameters required by some future input transform.)
+
+After you have called png_read_png(), you can retrieve the image data
+with
+
+ row_pointers = png_get_rows(png_ptr, info_ptr);
+
+where row_pointers is an array of pointers to the pixel data for each row:
+
+ png_bytep row_pointers[height];
+
+If you know your image size and pixel size ahead of time, you can allocate
+row_pointers prior to calling png_read_png() with
+
+ row_pointers = png_malloc(png_ptr,
+ height*sizeof(png_bytep));
+ for (int i=0; i<height, i++)
+ row_pointers[i]=png_malloc(png_ptr,
+ width*pixel_size);
+ png_set_rows(png_ptr, info_ptr, &row_pointers);
+
+Alternatively you could allocate your image in one big block and define
+row_pointers[i] to point into the proper places in your block.
+
+If you use png_set_rows(), the application is responsible for freeing
+row_pointers (and row_pointers[i], if they were separately allocated).
+
+If you don't allocate row_pointers ahead of time, png_read_png() will
+do it, and it'll be free'ed when you call png_destroy_*().
+
+The low-level read interface
+
+If you are going the low-level route, you are now ready to read all
+the file information up to the actual image data. You do this with a
+call to png_read_info().
+
+ png_read_info(png_ptr, info_ptr);
+
+This will process all chunks up to but not including the image data.
+
+Querying the info structure
+
+Functions are used to get the information from the info_ptr once it
+has been read. Note that these fields may not be completely filled
+in until png_read_end() has read the chunk data following the image.
+
+ png_get_IHDR(png_ptr, info_ptr, &width, &height,
+ &bit_depth, &color_type, &interlace_type,
+ &compression_type, &filter_method);
+
+ width - holds the width of the image
+ in pixels (up to 2^31).
+ height - holds the height of the image
+ in pixels (up to 2^31).
+ bit_depth - holds the bit depth of one of the
+ image channels. (valid values are
+ 1, 2, 4, 8, 16 and depend also on
+ the color_type. See also
+ significant bits (sBIT) below).
+ color_type - describes which color/alpha channels
+ are present.
+ PNG_COLOR_TYPE_GRAY
+ (bit depths 1, 2, 4, 8, 16)
+ PNG_COLOR_TYPE_GRAY_ALPHA
+ (bit depths 8, 16)
+ PNG_COLOR_TYPE_PALETTE
+ (bit depths 1, 2, 4, 8)
+ PNG_COLOR_TYPE_RGB
+ (bit_depths 8, 16)
+ PNG_COLOR_TYPE_RGB_ALPHA
+ (bit_depths 8, 16)
+
+ PNG_COLOR_MASK_PALETTE
+ PNG_COLOR_MASK_COLOR
+ PNG_COLOR_MASK_ALPHA
+
+ filter_method - (must be PNG_FILTER_TYPE_BASE
+ for PNG 1.0, and can also be
+ PNG_INTRAPIXEL_DIFFERENCING if
+ the PNG datastream is embedded in
+ a MNG-1.0 datastream)
+ compression_type - (must be PNG_COMPRESSION_TYPE_BASE
+ for PNG 1.0)
+ interlace_type - (PNG_INTERLACE_NONE or
+ PNG_INTERLACE_ADAM7)
+ Any or all of interlace_type, compression_type, of
+ filter_method can be NULL if you are
+ not interested in their values.
+
+ channels = png_get_channels(png_ptr, info_ptr);
+ channels - number of channels of info for the
+ color type (valid values are 1 (GRAY,
+ PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
+ 4 (RGB_ALPHA or RGB + filler byte))
+ rowbytes = png_get_rowbytes(png_ptr, info_ptr);
+ rowbytes - number of bytes needed to hold a row
+
+ signature = png_get_signature(png_ptr, info_ptr);
+ signature - holds the signature read from the
+ file (if any). The data is kept in
+ the same offset it would be if the
+ whole signature were read (i.e. if an
+ application had already read in 4
+ bytes of signature before starting
+ libpng, the remaining 4 bytes would
+ be in signature[4] through signature[7]
+ (see png_set_sig_bytes())).
+
+
+ width = png_get_image_width(png_ptr,
+ info_ptr);
+ height = png_get_image_height(png_ptr,
+ info_ptr);
+ bit_depth = png_get_bit_depth(png_ptr,
+ info_ptr);
+ color_type = png_get_color_type(png_ptr,
+ info_ptr);
+ filter_method = png_get_filter_type(png_ptr,
+ info_ptr);
+ compression_type = png_get_compression_type(png_ptr,
+ info_ptr);
+ interlace_type = png_get_interlace_type(png_ptr,
+ info_ptr);
+
+
+These are also important, but their validity depends on whether the chunk
+has been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
+png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
+data has been read, or zero if it is missing. The parameters to the
+png_get_<chunk> are set directly if they are simple data types, or a pointer
+into the info_ptr is returned for any complex types.
+
+ png_get_PLTE(png_ptr, info_ptr, &palette,
+ &num_palette);
+ palette - the palette for the file
+ (array of png_color)
+ num_palette - number of entries in the palette
+
+ png_get_gAMA(png_ptr, info_ptr, &gamma);
+ gamma - the gamma the file is written
+ at (PNG_INFO_gAMA)
+
+ png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
+ srgb_intent - the rendering intent (PNG_INFO_sRGB)
+ The presence of the sRGB chunk
+ means that the pixel data is in the
+ sRGB color space. This chunk also
+ implies specific values of gAMA and
+ cHRM.
+
+ png_get_iCCP(png_ptr, info_ptr, &name,
+ &compression_type, &profile, &proflen);
+ name - The profile name.
+ compression - The compression type; always
+ PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+ You may give NULL to this argument to
+ ignore it.
+ profile - International Color Consortium color
+ profile data. May contain NULs.
+ proflen - length of profile data in bytes.
+
+ png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+ sig_bit - the number of significant bits for
+ (PNG_INFO_sBIT) each of the gray,
+ red, green, and blue channels,
+ whichever are appropriate for the
+ given color type (png_color_16)
+
+ png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
+ &trans_values);
+ trans - array of transtqparent entries for
+ palette (PNG_INFO_tRNS)
+ trans_values - graylevel or color sample values of
+ the single transtqparent color for
+ non-paletted images (PNG_INFO_tRNS)
+ num_trans - number of transtqparent entries
+ (PNG_INFO_tRNS)
+
+ png_get_hIST(png_ptr, info_ptr, &hist);
+ (PNG_INFO_hIST)
+ hist - histogram of palette (array of
+ png_uint_16)
+
+ png_get_tIME(png_ptr, info_ptr, &mod_time);
+ mod_time - time image was last modified
+ (PNG_VALID_tIME)
+
+ png_get_bKGD(png_ptr, info_ptr, &background);
+ background - background color (PNG_VALID_bKGD)
+ valid 16-bit red, green and blue
+ values, regardless of color_type
+
+ num_comments = png_get_text(png_ptr, info_ptr,
+ &text_ptr, &num_text);
+ num_comments - number of comments
+ text_ptr - array of png_text holding image
+ comments
+ text_ptr[i].compression - type of compression used
+ on "text" PNG_TEXT_COMPRESSION_NONE
+ PNG_TEXT_COMPRESSION_zTXt
+ PNG_ITXT_COMPRESSION_NONE
+ PNG_ITXT_COMPRESSION_zTXt
+ text_ptr[i].key - keyword for comment. Must contain
+ 1-79 characters.
+ text_ptr[i].text - text comments for current
+ keyword. Can be empty.
+ text_ptr[i].text_length - length of text string,
+ after decompression, 0 for iTXt
+ text_ptr[i].itxt_length - length of itxt string,
+ after decompression, 0 for tEXt/zTXt
+ text_ptr[i].lang - language of comment (empty
+ string for unknown).
+ text_ptr[i].lang_key - keyword in UTF-8
+ (empty string for unknown).
+ num_text - number of comments (same as
+ num_comments; you can put NULL here
+ to avoid the duplication)
+ Note while png_set_text() will accept text, language,
+ and translated keywords that can be NULL pointers, the
+ structure returned by png_get_text will always contain
+ regular zero-terminated C strings. They might be
+ empty strings but they will never be NULL pointers.
+
+ num_spalettes = png_get_sPLT(png_ptr, info_ptr,
+ &palette_ptr);
+ palette_ptr - array of palette structures holding
+ contents of one or more sPLT chunks
+ read.
+ num_spalettes - number of sPLT chunks read.
+
+ png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
+ &unit_type);
+ offset_x - positive offset from the left edge
+ of the screen
+ offset_y - positive offset from the top edge
+ of the screen
+ unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+ png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
+ &unit_type);
+ res_x - pixels/unit physical resolution in
+ x direction
+ res_y - pixels/unit physical resolution in
+ x direction
+ unit_type - PNG_RESOLUTION_UNKNOWN,
+ PNG_RESOLUTION_METER
+
+ png_get_sCAL(png_ptr, info_ptr, &unit, &width,
+ &height)
+ unit - physical scale units (an integer)
+ width - width of a pixel in physical scale units
+ height - height of a pixel in physical scale units
+ (width and height are doubles)
+
+ png_get_sCAL_s(png_ptr, info_ptr, &unit, &width,
+ &height)
+ unit - physical scale units (an integer)
+ width - width of a pixel in physical scale units
+ height - height of a pixel in physical scale units
+ (width and height are strings like "2.54")
+
+ num_unknown_chunks = png_get_unknown_chunks(png_ptr,
+ info_ptr, &unknowns)
+ unknowns - array of png_unknown_chunk
+ structures holding unknown chunks
+ unknowns[i].name - name of unknown chunk
+ unknowns[i].data - data of unknown chunk
+ unknowns[i].size - size of unknown chunk's data
+ unknowns[i].location - position of chunk in file
+
+ The value of "i" corresponds to the order in which the
+ chunks were read from the PNG file or inserted with the
+ png_set_unknown_chunks() function.
+
+The data from the pHYs chunk can be retrieved in several convenient
+forms:
+
+ res_x = png_get_x_pixels_per_meter(png_ptr,
+ info_ptr)
+ res_y = png_get_y_pixels_per_meter(png_ptr,
+ info_ptr)
+ res_x_and_y = png_get_pixels_per_meter(png_ptr,
+ info_ptr)
+ res_x = png_get_x_pixels_per_inch(png_ptr,
+ info_ptr)
+ res_y = png_get_y_pixels_per_inch(png_ptr,
+ info_ptr)
+ res_x_and_y = png_get_pixels_per_inch(png_ptr,
+ info_ptr)
+ aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
+ info_ptr)
+
+ (Each of these returns 0 [signifying "unknown"] if
+ the data is not present or if res_x is 0;
+ res_x_and_y is 0 if res_x != res_y)
+
+The data from the oFFs chunk can be retrieved in several convenient
+forms:
+
+ x_offset = png_get_x_offset_microns(png_ptr, info_ptr);
+ y_offset = png_get_y_offset_microns(png_ptr, info_ptr);
+ x_offset = png_get_x_offset_inches(png_ptr, info_ptr);
+ y_offset = png_get_y_offset_inches(png_ptr, info_ptr);
+
+ (Each of these returns 0 [signifying "unknown" if both
+ x and y are 0] if the data is not present or if the
+ chunk is present but the unit is the pixel)
+
+For more information, see the png_info definition in png.h and the
+PNG specification for chunk contents. Be careful with trusting
+rowbytes, as some of the transformations could increase the space
+needed to hold a row (expand, filler, gray_to_rgb, etc.).
+See png_read_update_info(), below.
+
+A quick word about text_ptr and num_text. PNG stores comments in
+keyword/text pairs, one pair per chunk, with no limit on the number
+of text chunks, and a 2^31 byte limit on their size. While there are
+suggested keywords, there is no requirement to restrict the use to these
+strings. It is strongly suggested that keywords and text be sensible
+to humans (that's the point), so don't use abbreviations. Non-printing
+symbols are not allowed. See the PNG specification for more details.
+There is also no requirement to have text after the keyword.
+
+Keywords should be limited to 79 Latin-1 characters without leading or
+trailing spaces, but non-consecutive spaces are allowed within the
+keyword. It is possible to have the same keyword any number of times.
+The text_ptr is an array of png_text structures, each holding a
+pointer to a language string, a pointer to a keyword and a pointer to
+a text string. The text string, language code, and translated
+keyword may be empty or NULL pointers. The keyword/text
+pairs are put into the array in the order that they are received.
+However, some or all of the text chunks may be after the image, so, to
+make sure you have read all the text chunks, don't mess with these
+until after you read the stuff after the image. This will be
+mentioned again below in the discussion that goes with png_read_end().
+
+Input transformations
+
+After you've read the header information, you can set up the library
+to handle any special transformations of the image data. The various
+ways to transform the data will be described in the order that they
+should occur. This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths. Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data. For example, don't swap red and blue on grayscale data.
+
+The colors used for the background and transparency values should be
+supplied in the same format/depth as the current image data. They
+are stored in the same format/depth as the image data in a bKGD or tRNS
+chunk, so this is what libpng expects for this data. The colors are
+transformed to keep in sync with the image data when an application
+calls the png_read_update_info() routine (see below).
+
+Data will be decoded into the supplied row buffers packed into bytes
+unless the library has been told to transform it into another format.
+For example, 4 bit/pixel paletted or grayscale data will be returned
+2 pixels/byte with the leftmost pixel in the high-order bits of the
+byte, unless png_set_packing() is called. 8-bit RGB data will be stored
+in RGB RGB RGB format unless png_set_filler() is called to insert filler
+bytes, either before or after each RGB triplet. 16-bit RGB data will
+be returned RRGGBB RRGGBB, with the most significant byte of the color
+value first, unless png_set_strip_16() is called to transform it to
+regular RGB RGB triplets, or png_set_filler() is called to insert
+filler bytes, either before or after each RRGGBB triplet. Similarly,
+8-bit or 16-bit grayscale data can be modified with png_set_filler()
+or png_set_strip_16().
+
+The following code transforms grayscale images of less than 8 to 8 bits,
+changes paletted images to RGB, and adds a full alpha channel if there is
+transparency information in a tRNS chunk. This is most useful on
+grayscale images with bit depths of 2 or 4 or if there is a multiple-image
+viewing application that wishes to treat all images in the same way.
+
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_palette_to_rgb(png_ptr);
+
+ if (color_type == PNG_COLOR_TYPE_GRAY &&
+ bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
+
+ if (png_get_valid(png_ptr, info_ptr,
+ PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
+
+These three functions are actually aliases for png_set_expand(), added
+in libpng version 1.0.4, with the function names expanded to improve code
+readability. In some future version they may actually do different
+things.
+
+PNG can have files with 16 bits per channel. If you only can handle
+8 bits per channel, this will strip the pixels down to 8 bit.
+
+ if (bit_depth == 16)
+ png_set_strip_16(png_ptr);
+
+If, for some reason, you don't need the alpha channel on an image,
+and you want to remove it rather than combining it with the background
+(but the image author certainly had in mind that you *would* combine
+it with the background, so that's what you should probably do):
+
+ if (color_type & PNG_COLOR_MASK_ALPHA)
+ png_set_strip_alpha(png_ptr);
+
+In PNG files, the alpha channel in an image
+is the level of opacity. If you need the alpha channel in an image to
+be the level of transparency instead of opacity, you can invert the
+alpha channel (or the tRNS chunk data) after it's read, so that 0 is
+fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
+images) is fully transtqparent, with
+
+ png_set_invert_alpha(png_ptr);
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit
+files. This code expands to 1 pixel per byte without changing the
+values of the pixels:
+
+ if (bit_depth < 8)
+ png_set_packing(png_ptr);
+
+PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels
+stored in a PNG image have been "scaled" or "shifted" up to the next
+higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to
+8 bits/sample in the range [0, 255]). However, it is also possible to
+convert the PNG pixel data back to the original bit depth of the image.
+This call reduces the pixels back down to the original bit depth:
+
+ png_color_8p sig_bit;
+
+ if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
+ png_set_shift(png_ptr, sig_bit);
+
+PNG files store 3-color pixels in red, green, blue order. This code
+changes the storage of the pixels to blue, green, red:
+
+ if (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ png_set_bgr(png_ptr);
+
+PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them
+into 4 or 8 bytes for windowing systems that need them in this format:
+
+ if (color_type == PNG_COLOR_TYPE_RGB)
+ png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);
+
+where "filler" is the 8 or 16-bit number to fill with, and the location is
+either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether
+you want the filler before the RGB or after. This transformation
+does not affect images that already have full alpha channels. To add an
+opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which
+will generate RGBA pixels.
+
+If you are reading an image with an alpha channel, and you need the
+data as ARGB instead of the normal PNG format RGBA:
+
+ if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ png_set_swap_alpha(png_ptr);
+
+For some uses, you may want a grayscale image to be represented as
+RGB. This code will do that conversion:
+
+ if (color_type == PNG_COLOR_TYPE_GRAY ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ png_set_gray_to_rgb(png_ptr);
+
+Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
+with alpha.
+
+ if (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ png_set_rgb_to_gray_fixed(png_ptr, error_action,
+ int red_weight, int green_weight);
+
+ error_action = 1: silently do the conversion
+ error_action = 2: issue a warning if the original
+ image has any pixel where
+ red != green or red != blue
+ error_action = 3: issue an error and abort the
+ conversion if the original
+ image has any pixel where
+ red != green or red != blue
+
+ red_weight: weight of red component times 100000
+ green_weight: weight of green component times 100000
+ If either weight is negative, default
+ weights (21268, 71514) are used.
+
+If you have set error_action = 1 or 2, you can
+later check whether the image really was gray, after processing
+the image rows, with the png_get_rgb_to_gray_status(png_ptr) function.
+It will return a png_byte that is zero if the image was gray or
+1 if there were any non-gray pixels. bKGD and sBIT data
+will be silently converted to grayscale, using the green channel
+data, regardless of the error_action setting.
+
+With red_weight+green_weight<=100000,
+the normalized graylevel is computed:
+
+ int rw = red_weight * 65536;
+ int gw = green_weight * 65536;
+ int bw = 65536 - (rw + gw);
+ gray = (rw*red + gw*green + bw*blue)/65536;
+
+The default values approximate those recommended in the Charles
+Poynton's Color FAQ, <http://www.inforamp.net/~poynton/>
+Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
+
+ Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+
+Libpng approximates this with
+
+ Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
+
+which can be expressed with integers as
+
+ Y = (6969 * R + 23434 * G + 2365 * B)/32768
+
+The calculation is done in a linear colorspace, if the image gamma
+is known.
+
+If you have a grayscale and you are using png_set_expand_depth(),
+png_set_expand(), or png_set_gray_to_rgb to change to truecolor or to
+a higher bit-depth, you must either supply the background color as a gray
+value at the original file bit-depth (need_expand = 1) or else supply the
+background color as an RGB triplet at the final, expanded bit depth
+(need_expand = 0). Similarly, if you are reading a paletted image, you
+must either supply the background color as a palette index (need_expand = 1)
+or as an RGB triplet that may or may not be in the palette (need_expand = 0).
+
+ png_color_16 my_background;
+ png_color_16p image_background;
+
+ if (png_get_bKGD(png_ptr, info_ptr, &image_background))
+ png_set_background(png_ptr, image_background,
+ PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
+ else
+ png_set_background(png_ptr, &my_background,
+ PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+The png_set_background() function tells libpng to composite images
+with alpha or simple transparency against the supplied background
+color. If the PNG file tqcontains a bKGD chunk (PNG_INFO_bKGD valid),
+you may use this color, or supply another color more suitable for
+the current display (e.g., the background color from a web page). You
+need to tell libpng whether the color is in the gamma space of the
+display (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
+(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
+that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
+know why anyone would use this, but it's here).
+
+To properly display PNG images on any kind of system, the application needs
+to know what the display gamma is. Ideally, the user will know this, and
+the application will allow them to set it. One method of allowing the user
+to set the display gamma separately for each system is to check for a
+SCREEN_GAMMA or DISPLAY_GAMMA environment variable, which will hopefully be
+correctly set.
+
+Note that display_gamma is the overall gamma correction required to produce
+pleasing results, which depends on the lighting conditions in the surrounding
+environment. In a dim or brightly lit room, no compensation other than
+the physical gamma exponent of the monitor is needed, while in a dark room
+a slightly smaller exponent is better.
+
+ double gamma, screen_gamma;
+
+ if (/* We have a user-defined screen
+ gamma value */)
+ {
+ screen_gamma = user_defined_screen_gamma;
+ }
+ /* One way that applications can share the same
+ screen gamma value */
+ else if ((gamma_str = getenv("SCREEN_GAMMA"))
+ != NULL)
+ {
+ screen_gamma = (double)atof(gamma_str);
+ }
+ /* If we don't have another value */
+ else
+ {
+ screen_gamma = 2.2; /* A good guess for a
+ PC monitor in a bright office or a dim room */
+ screen_gamma = 2.0; /* A good guess for a
+ PC monitor in a dark room */
+ screen_gamma = 1.7 or 1.0; /* A good
+ guess for Mac systems */
+ }
+
+The png_set_gamma() function handles gamma transformations of the data.
+Pass both the file gamma and the current screen_gamma. If the file does
+not have a gamma value, you can pass one anyway if you have an idea what
+it is (usually 0.45455 is a good guess for GIF images on PCs). Note
+that file gammas are inverted from screen gammas. See the discussions
+on gamma in the PNG specification for an excellent description of what
+gamma is, and why all applications should support it. It is strongly
+recommended that PNG viewers support gamma correction.
+
+ if (png_get_gAMA(png_ptr, info_ptr, &gamma))
+ png_set_gamma(png_ptr, screen_gamma, gamma);
+ else
+ png_set_gamma(png_ptr, screen_gamma, 0.45455);
+
+If you need to reduce an RGB file to a paletted file, or if a paletted
+file has more entries then will fit on your screen, png_set_dither()
+will do that. Note that this is a simple match dither that merely
+tqfinds the closest color available. This should work fairly well with
+optimized palettes, and fairly badly with linear color cubes. If you
+pass a palette that is larger then maximum_colors, the file will
+reduce the number of colors in the palette so it will fit into
+maximum_colors. If there is a histogram, it will use it to make
+more intelligent choices when reducing the palette. If there is no
+histogram, it may not do as good a job.
+
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ if (png_get_valid(png_ptr, info_ptr,
+ PNG_INFO_PLTE))
+ {
+ png_uint_16p histogram = NULL;
+
+ png_get_hIST(png_ptr, info_ptr,
+ &histogram);
+ png_set_dither(png_ptr, palette, num_palette,
+ max_screen_colors, histogram, 1);
+ }
+ else
+ {
+ png_color std_color_cube[MAX_SCREEN_COLORS] =
+ { ... colors ... };
+
+ png_set_dither(png_ptr, std_color_cube,
+ MAX_SCREEN_COLORS, MAX_SCREEN_COLORS,
+ NULL,0);
+ }
+ }
+
+PNG files describe monochrome as black being zero and white being one.
+The following code will reverse this (make black be one and white be
+zero):
+
+ if (bit_depth == 1 && color_type == PNG_COLOR_TYPE_GRAY)
+ png_set_invert_mono(png_ptr);
+
+This function can also be used to invert grayscale and gray-alpha images:
+
+ if (color_type == PNG_COLOR_TYPE_GRAY ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ png_set_invert_mono(png_ptr);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first). This code changes the storage to the
+other way (little-endian, i.e. least significant bits first, the
+way PCs store them):
+
+ if (bit_depth == 16)
+ png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+ if (bit_depth < 8)
+ png_set_packswap(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs. This is done by setting a callback
+with
+
+ png_set_read_user_transform_fn(png_ptr,
+ read_transform_fn);
+
+You must supply the function
+
+ void read_transform_fn(png_ptr ptr, row_info_ptr
+ row_info, png_bytep data)
+
+See pngtest.c for a working example. Your function will be called
+after all of the other transformations have been processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function, and you can inform libpng that your transform
+function will change the number of channels or bit depth with the
+function
+
+ png_set_user_transform_info(png_ptr, user_ptr,
+ user_depth, user_channels);
+
+The user's application, not libpng, is responsible for allocating and
+freeing any memory required for the user structure.
+
+You can retrieve the pointer via the function
+png_get_user_transform_ptr(). For example:
+
+ voidp read_user_transform_ptr =
+ png_get_user_transform_ptr(png_ptr);
+
+The last thing to handle is interlacing; this is covered in detail below,
+but you must call the function here if you want libpng to handle expansion
+of the interlaced image.
+
+ number_of_passes = png_set_interlace_handling(png_ptr);
+
+After setting the transformations, libpng can update your png_info
+structure to reflect any transformations you've requested with this
+call. This is most useful to update the info structure's rowbytes
+field so you can use it to allocate your image memory. This function
+will also update your palette with the correct screen_gamma and
+background if these have been given with the calls above.
+
+ png_read_update_info(png_ptr, info_ptr);
+
+After you call png_read_update_info(), you can allocate any
+memory you need to hold the image. The row data is simply
+raw byte data for all forms of images. As the actual allocation
+varies among applications, no example will be given. If you
+are allocating one large chunk, you will need to build an
+array of pointers to each row, as it will be needed for some
+of the functions below.
+
+Reading image data
+
+After you've allocated memory, you can read the image data.
+The simplest way to do this is in one function call. If you are
+allocating enough memory to hold the whole image, you can just
+call png_read_image() and libpng will read in all the image data
+and put it in the memory area supplied. You will need to pass in
+an array of pointers to each row.
+
+This function automatically handles interlacing, so you don't need
+to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_read_rows().
+
+ png_read_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+ png_bytep row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to read in the whole image at once, you can
+use png_read_rows() instead. If there is no interlacing (check
+interlace_type == PNG_INTERLACE_NONE), this is simple:
+
+ png_read_rows(png_ptr, row_pointers, NULL,
+ number_of_rows);
+
+where row_pointers is the same as in the png_read_image() call.
+
+If you are doing this just one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+ png_bytep row_pointer = row;
+ png_read_row(png_ptr, row_pointer, NULL);
+
+If the file is interlaced (interlace_type != 0 in the IHDR chunk), things
+get somewhat harder. The only current (PNG Specification version 1.2)
+interlacing type for PNG is (interlace_type == PNG_INTERLACE_ADAM7)
+is a somewhat complicated 2D interlace scheme, known as Adam7, that
+breaks down an image into seven smaller images of varying size, based
+on an 8x8 grid.
+
+libpng can fill out those images or it can give them to you "as is".
+If you want them filled out, there are two ways to do that. The one
+mentioned in the PNG specification is to expand each pixel to cover
+those pixels that have not been read yet (the "rectangle" method).
+This results in a blocky image for the first pass, which gradually
+smooths out as more pixels are read. The other method is the "sparkle"
+method, where pixels are drawn only in their final locations, with the
+rest of the image remaining whatever colors they were initialized to
+before the start of the read. The first method usually looks better,
+but tends to be slower, as there are more pixels to put in the rows.
+
+If you don't want libpng to handle the interlacing details, just call
+png_read_rows() seven times to read in all seven images. Each of the
+images is a valid image by itself, or they can all be combined on an
+8x8 grid to form a single image (although if you intend to combine them
+you would be far better off using the libpng interlace handling).
+
+The first pass will return an image 1/8 as wide as the entire image
+(every 8th column starting in column 0) and 1/8 as high as the original
+(every 8th row starting in row 0), the second will be 1/8 as wide
+(starting in column 4) and 1/8 as high (also starting in row 0). The
+third pass will be 1/4 as wide (every 4th pixel starting in column 0) and
+1/8 as high (every 8th row starting in row 4), and the fourth pass will
+be 1/4 as wide and 1/4 as high (every 4th column starting in column 2,
+and every 4th row starting in row 0). The fifth pass will return an
+image 1/2 as wide, and 1/4 as high (starting at column 0 and row 2),
+while the sixth pass will be 1/2 as wide and 1/2 as high as the original
+(starting in column 1 and row 0). The seventh and final pass will be as
+wide as the original, and 1/2 as high, containing all of the odd
+numbered scanlines. Phew!
+
+If you want libpng to expand the images, call this before calling
+png_start_read_image() or png_read_update_info():
+
+ if (interlace_type == PNG_INTERLACE_ADAM7)
+ number_of_passes
+ = png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed. Currently, this
+is seven, but may change if another interlace type is added.
+This function can be called even if the file is not interlaced,
+where it will return one pass.
+
+If you are not going to display the image after each pass, but are
+going to wait until the entire image is read in, use the sparkle
+effect. This effect is faster and the end result of either method
+is exactly the same. If you are planning on displaying the image
+after each pass, the "rectangle" effect is generally considered the
+better looking one.
+
+If you only want the "sparkle" effect, just call png_read_rows() as
+normal, with the third parameter NULL. Make sure you make pass over
+the image number_of_passes times, and you don't change the data in the
+rows between calls. You can change the locations of the data, just
+not the data. Each pass only writes the pixels appropriate for that
+pass, and assumes the data from previous passes is still valid.
+
+ png_read_rows(png_ptr, row_pointers, NULL,
+ number_of_rows);
+
+If you only want the first effect (the rectangles), do the same as
+before except pass the row buffer in the third parameter, and leave
+the second parameter NULL.
+
+ png_read_rows(png_ptr, NULL, row_pointers,
+ number_of_rows);
+
+Finishing a sequential read
+
+After you are finished reading the image through either the high- or
+low-level interfaces, you can finish reading the file. If you are
+interested in comments or time, which may be stored either before or
+after the image data, you should pass the separate png_info struct if
+you want to keep the comments from before and after the image
+separate. If you are not interested, you can pass NULL.
+
+ png_read_end(png_ptr, end_info);
+
+When you are done, you can free all memory allocated by libpng like this:
+
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ &end_info);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+ png_free_data(png_ptr, info_ptr, tqmask, seq)
+ tqmask - identifies data to be freed, a tqmask
+ containing the logical OR of one or
+ more of
+ PNG_FREE_PLTE, PNG_FREE_TRNS,
+ PNG_FREE_HIST, PNG_FREE_ICCP,
+ PNG_FREE_PCAL, PNG_FREE_ROWS,
+ PNG_FREE_SCAL, PNG_FREE_SPLT,
+ PNG_FREE_TEXT, PNG_FREE_UNKN,
+ or simply PNG_FREE_ALL
+ seq - sequence number of item to be freed
+ (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user and not by libpng, and will in those
+cases do nothing. The "seq" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed. If "seq" is not
+-1, and multiple items are allowed for the data type identified in
+the tqmask, such as text or sPLT, only the n'th item in the structure
+is freed, where n is "seq".
+
+The default behavior is only to free data that was allocated internally
+by libpng. This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+ png_data_freer(png_ptr, info_ptr, freer, tqmask)
+ tqmask - which data elements are affected
+ same choices as in png_free_data()
+ freer - one of
+ PNG_DESTROY_WILL_FREE_DATA
+ PNG_SET_WILL_FREE_DATA
+ PNG_USER_WILL_FREE_DATA
+
+This function only affects data that has already been allocated.
+You can call this function after reading the PNG data but before calling
+any png_set_*() functions, to control whether the user or the png_set_*()
+function is responsible for freeing any existing data that might be present,
+and again after the png_set_*() functions to control whether the user
+or png_destroy_*() is supposed to free the data. When the user assumes
+responsibility for libpng-allocated data, the application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated your row_pointers in a single block, as suggested above in
+the description of the high level read interface, you must not transfer
+responsibility for freeing it to the png_set_rows or png_read_destroy function,
+because they would also try to free the individual row_pointers[i].
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key. Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+
+The png_free_data() function will turn off the "valid" flag for anything
+it frees. If you need to turn the flag off for a chunk that was freed by your
+application instead of by libpng, you can use
+
+ png_set_invalid(png_ptr, info_ptr, tqmask);
+ tqmask - identifies the chunks to be made invalid,
+ containing the logical OR of one or
+ more of
+ PNG_INFO_gAMA, PNG_INFO_sBIT,
+ PNG_INFO_cHRM, PNG_INFO_PLTE,
+ PNG_INFO_tRNS, PNG_INFO_bKGD,
+ PNG_INFO_hIST, PNG_INFO_pHYs,
+ PNG_INFO_oFFs, PNG_INFO_tIME,
+ PNG_INFO_pCAL, PNG_INFO_sRGB,
+ PNG_INFO_iCCP, PNG_INFO_sPLT,
+ PNG_INFO_sCAL, PNG_INFO_IDAT
+
+For a more compact example of reading a PNG image, see the file example.c.
+
+Reading PNG files progressively
+
+The progressive reader is slightly different then the non-progressive
+reader. Instead of calling png_read_info(), png_read_rows(), and
+png_read_end(), you make one call to png_process_data(), which calls
+callbacks when it has the info, a row, or the end of the image. You
+set up these callbacks with png_set_progressive_read_fn(). You don't
+have to worry about the input/output functions of libpng, as you are
+giving the library the data directly in png_process_data(). I will
+assume that you have read the section on reading PNG files above,
+so I will only highlight the differences (although I will show
+all of the code).
+
+png_structp png_ptr;
+png_infop info_ptr;
+
+ /* An example code fragment of how you would
+ initialize the progressive reader in your
+ application. */
+ int
+ initialize_png_reader()
+ {
+ png_ptr = png_create_read_struct
+ (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+ user_error_fn, user_warning_fn);
+ if (!png_ptr)
+ return (ERROR);
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_read_struct(&png_ptr, (png_infopp)NULL,
+ (png_infopp)NULL);
+ return (ERROR);
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ (png_infopp)NULL);
+ return (ERROR);
+ }
+
+ /* This one's new. You can provide functions
+ to be called when the header info is valid,
+ when each row is completed, and when the image
+ is finished. If you aren't using all functions,
+ you can specify NULL parameters. Even when all
+ three functions are NULL, you need to call
+ png_set_progressive_read_fn(). You can use
+ any struct as the user_ptr (cast to a void pointer
+ for the function call), and retrieve the pointer
+ from inside the callbacks using the function
+
+ png_get_progressive_ptr(png_ptr);
+
+ which will return a void pointer, which you have
+ to cast appropriately.
+ */
+ png_set_progressive_read_fn(png_ptr, (void *)user_ptr,
+ info_callback, row_callback, end_callback);
+
+ return 0;
+ }
+
+ /* A code fragment that you call as you receive blocks
+ of data */
+ int
+ process_data(png_bytep buffer, png_uint_32 length)
+ {
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_read_struct(&png_ptr, &info_ptr,
+ (png_infopp)NULL);
+ return (ERROR);
+ }
+
+ /* This one's new also. Simply give it a chunk
+ of data from the file stream (in order, of
+ course). On machines with segmented memory
+ models machines, don't give it any more than
+ 64K. The library seems to run fine with sizes
+ of 4K. Although you can give it much less if
+ necessary (I assume you can give it chunks of
+ 1 byte, I haven't tried less then 256 bytes
+ yet). When this function returns, you may
+ want to display any rows that were generated
+ in the row callback if you don't already do
+ so there.
+ */
+ png_process_data(png_ptr, info_ptr, buffer, length);
+ return 0;
+ }
+
+ /* This function is called (as set by
+ png_set_progressive_read_fn() above) when enough data
+ has been supplied so all of the header has been
+ read.
+ */
+ void
+ info_callback(png_structp png_ptr, png_infop info)
+ {
+ /* Do any setup here, including setting any of
+ the transformations mentioned in the Reading
+ PNG files section. For now, you _must_ call
+ either png_start_read_image() or
+ png_read_update_info() after all the
+ transformations are set (even if you don't set
+ any). You may start getting rows before
+ png_process_data() returns, so this is your
+ last chance to prepare for that.
+ */
+ }
+
+ /* This function is called when each row of image
+ data is complete */
+ void
+ row_callback(png_structp png_ptr, png_bytep new_row,
+ png_uint_32 row_num, int pass)
+ {
+ /* If the image is interlaced, and you turned
+ on the interlace handler, this function will
+ be called for every row in every pass. Some
+ of these rows will not be changed from the
+ previous pass. When the row is not changed,
+ the new_row variable will be NULL. The rows
+ and passes are called in order, so you don't
+ really need the row_num and pass, but I'm
+ supplying them because it may make your life
+ easier.
+
+ For the non-NULL rows of interlaced images,
+ you must call png_progressive_combine_row()
+ passing in the row and the old row. You can
+ call this function for NULL rows (it will just
+ return) and for non-interlaced images (it just
+ does the memcpy for you) if it will make the
+ code easier. Thus, you can just do this for
+ all cases:
+ */
+
+ png_progressive_combine_row(png_ptr, old_row,
+ new_row);
+
+ /* where old_row is what was displayed for
+ previously for the row. Note that the first
+ pass (pass == 0, really) will completely cover
+ the old row, so the rows do not have to be
+ initialized. After the first pass (and only
+ for interlaced images), you will have to pass
+ the current row, and the function will combine
+ the old row and the new row.
+ */
+ }
+
+ void
+ end_callback(png_structp png_ptr, png_infop info)
+ {
+ /* This function is called after the whole image
+ has been read, including any chunks after the
+ image (up to and including the IEND). You
+ will usually have the same info chunk as you
+ had in the header, although some data may have
+ been added to the comments and time fields.
+
+ Most people won't do much here, perhaps setting
+ a flag that marks the image as finished.
+ */
+ }
+
+
+
+IV. Writing
+
+Much of this is very similar to reading. However, everything of
+importance is repeated here, so you won't have to constantly look
+back up in the reading section to understand writing.
+
+Setup
+
+You will want to do the I/O initialization before you get into libpng,
+so if it doesn't work, you don't have anything to undo. If you are not
+using the standard I/O functions, you will need to tqreplace them with
+custom writing functions. See the discussion under Customizing libpng.
+
+ FILE *fp = fopen(file_name, "wb");
+ if (!fp)
+ {
+ return (ERROR);
+ }
+
+Next, png_struct and png_info need to be allocated and initialized.
+As these can be both relatively large, you may not want to store these
+on the stack, unless you have stack space to spare. Of course, you
+will want to check if they return NULL. If you are also reading,
+you won't want to name your read structure and your write structure
+both "png_ptr"; you can call them anything you like, such as
+"read_ptr" and "write_ptr". Look at pngtest.c, for example.
+
+ png_structp png_ptr = png_create_write_struct
+ (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+ user_error_fn, user_warning_fn);
+ if (!png_ptr)
+ return (ERROR);
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr)
+ {
+ png_destroy_write_struct(&png_ptr,
+ (png_infopp)NULL);
+ return (ERROR);
+ }
+
+If you want to use your own memory allocation routines,
+define PNG_USER_MEM_SUPPORTED and use
+png_create_write_struct_2() instead of png_create_write_struct():
+
+ png_structp png_ptr = png_create_write_struct_2
+ (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
+ user_error_fn, user_warning_fn, (png_voidp)
+ user_mem_ptr, user_malloc_fn, user_free_fn);
+
+After you have these structures, you will need to set up the
+error handling. When libpng encounters an error, it expects to
+longjmp() back to your routine. Therefore, you will need to call
+setjmp() and pass the png_jmpbuf(png_ptr). If you
+write the file from different routines, you will need to update
+the png_jmpbuf(png_ptr) every time you enter a new routine that will
+call a png_*() function. See your documentation of setjmp/longjmp
+for your compiler for more information on setjmp/longjmp. See
+the discussion on libpng error handling in the Customizing Libpng
+section below for more information on the libpng error handling.
+
+ if (setjmp(png_jmpbuf(png_ptr)))
+ {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ fclose(fp);
+ return (ERROR);
+ }
+ ...
+ return;
+
+If you would rather avoid the complexity of setjmp/longjmp issues,
+you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
+errors will result in a call to PNG_ABORT() which defaults to abort().
+
+Now you need to set up the output code. The default for libpng is to
+use the C function fwrite(). If you use this, you will need to pass a
+valid FILE * in the function png_init_io(). Be sure that the file is
+opened in binary mode. Again, if you wish to handle writing data in
+another way, see the discussion on libpng I/O handling in the Customizing
+Libpng section below.
+
+ png_init_io(png_ptr, fp);
+
+Write callbacks
+
+At this point, you can set up a callback function that will be
+called after each row has been written, which you can use to control
+a progress meter or the like. It's demonstrated in pngtest.c.
+You must supply a function
+
+ void write_row_callback(png_ptr, png_uint_32 row,
+ int pass);
+ {
+ /* put your code here */
+ }
+
+(You can give it another name that you like instead of "write_row_callback")
+
+To inform libpng about your function, use
+
+ png_set_write_status_fn(png_ptr, write_row_callback);
+
+You now have the option of modifying how the compression library will
+run. The following functions are mainly for testing, but may be useful
+in some cases, like if you need to write PNG files extremely fast and
+are willing to give up some compression, or if you want to get the
+maximum possible compression at the expense of slower writing. If you
+have no special needs in this area, let the library do what it wants by
+not calling this function at all, as it has been tuned to deliver a good
+speed/compression ratio. The second parameter to png_set_filter() is
+the filter method, for which the only valid values are 0 (as of the
+July 1999 PNG specification, version 1.2) or 64 (if you are writing
+a PNG datastream that is to be embedded in a MNG datastream). The third
+parameter is a flag that indicates which filter type(s) are to be tested
+for each scanline. See the PNG specification for details on the specific filter
+types.
+
+
+ /* turn on or off filtering, and/or choose
+ specific filters. You can use either a single
+ PNG_FILTER_VALUE_NAME or the logical OR of one
+ or more PNG_FILTER_NAME masks. */
+ png_set_filter(png_ptr, 0,
+ PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE |
+ PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB |
+ PNG_FILTER_UP | PNG_FILTER_VALUE_UP |
+ PNG_FILTER_AVE | PNG_FILTER_VALUE_AVE |
+ PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH|
+ PNG_ALL_FILTERS);
+
+If an application
+wants to start and stop using particular filters during compression,
+it should start out with all of the filters (to ensure that the previous
+row of pixels will be stored in case it's needed later), and then add
+and remove them after the start of compression.
+
+If you are writing a PNG datastream that is to be embedded in a MNG
+datastream, the second parameter can be either 0 or 64.
+
+The png_set_compression_*() functions interface to the zlib compression
+library, and should mostly be ignored unless you really know what you are
+doing. The only generally useful call is png_set_compression_level()
+which changes how much time zlib spends on trying to compress the image
+data. See the Compression Library (zlib.h and algorithm.txt, distributed
+with zlib) for details on the compression levels.
+
+ /* set the zlib compression level */
+ png_set_compression_level(png_ptr,
+ Z_BEST_COMPRESSION);
+
+ /* set other zlib parameters */
+ png_set_compression_mem_level(png_ptr, 8);
+ png_set_compression_strategy(png_ptr,
+ Z_DEFAULT_STRATEGY);
+ png_set_compression_window_bits(png_ptr, 15);
+ png_set_compression_method(png_ptr, 8);
+ png_set_compression_buffer_size(png_ptr, 8192)
+
+extern PNG_EXPORT(void,png_set_zbuf_size)
+
+Setting the contents of info for output
+
+You now need to fill in the png_info structure with all the data you
+wish to write before the actual image. Note that the only thing you
+are allowed to write after the image is the text chunks and the time
+chunk (as of PNG Specification 1.2, anyway). See png_write_end() and
+the latest PNG specification for more information on that. If you
+wish to write them before the image, fill them in now, and flag that
+data as being valid. If you want to wait until after the data, don't
+fill them until png_write_end(). For all the fields in png_info and
+their data types, see png.h. For explanations of what the fields
+contain, see the PNG specification.
+
+Some of the more important parts of the png_info are:
+
+ png_set_IHDR(png_ptr, info_ptr, width, height,
+ bit_depth, color_type, interlace_type,
+ compression_type, filter_method)
+ width - holds the width of the image
+ in pixels (up to 2^31).
+ height - holds the height of the image
+ in pixels (up to 2^31).
+ bit_depth - holds the bit depth of one of the
+ image channels.
+ (valid values are 1, 2, 4, 8, 16
+ and depend also on the
+ color_type. See also significant
+ bits (sBIT) below).
+ color_type - describes which color/alpha
+ channels are present.
+ PNG_COLOR_TYPE_GRAY
+ (bit depths 1, 2, 4, 8, 16)
+ PNG_COLOR_TYPE_GRAY_ALPHA
+ (bit depths 8, 16)
+ PNG_COLOR_TYPE_PALETTE
+ (bit depths 1, 2, 4, 8)
+ PNG_COLOR_TYPE_RGB
+ (bit_depths 8, 16)
+ PNG_COLOR_TYPE_RGB_ALPHA
+ (bit_depths 8, 16)
+
+ PNG_COLOR_MASK_PALETTE
+ PNG_COLOR_MASK_COLOR
+ PNG_COLOR_MASK_ALPHA
+
+ interlace_type - PNG_INTERLACE_NONE or
+ PNG_INTERLACE_ADAM7
+ compression_type - (must be
+ PNG_COMPRESSION_TYPE_DEFAULT)
+ filter_method - (must be PNG_FILTER_TYPE_DEFAULT
+ or, if you are writing a PNG to
+ be embedded in a MNG datastream,
+ can also be
+ PNG_INTRAPIXEL_DIFFERENCING)
+
+ png_set_PLTE(png_ptr, info_ptr, palette,
+ num_palette);
+ palette - the palette for the file
+ (array of png_color)
+ num_palette - number of entries in the palette
+
+ png_set_gAMA(png_ptr, info_ptr, gamma);
+ gamma - the gamma the image was created
+ at (PNG_INFO_gAMA)
+
+ png_set_sRGB(png_ptr, info_ptr, srgb_intent);
+ srgb_intent - the rendering intent
+ (PNG_INFO_sRGB) The presence of
+ the sRGB chunk means that the pixel
+ data is in the sRGB color space.
+ This chunk also implies specific
+ values of gAMA and cHRM. Rendering
+ intent is the CSS-1 property that
+ has been defined by the International
+ Color Consortium
+ (http://www.color.org).
+ It can be one of
+ PNG_sRGB_INTENT_SATURATION,
+ PNG_sRGB_INTENT_PERCEPTUAL,
+ PNG_sRGB_INTENT_ABSOLUTE, or
+ PNG_sRGB_INTENT_RELATIVE.
+
+
+ png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr,
+ srgb_intent);
+ srgb_intent - the rendering intent
+ (PNG_INFO_sRGB) The presence of the
+ sRGB chunk means that the pixel
+ data is in the sRGB color space.
+ This function also causes gAMA and
+ cHRM chunks with the specific values
+ that are consistent with sRGB to be
+ written.
+
+ png_set_iCCP(png_ptr, info_ptr, name, compression_type,
+ profile, proflen);
+ name - The profile name.
+ compression - The compression type; always
+ PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
+ You may give NULL to this argument to
+ ignore it.
+ profile - International Color Consortium color
+ profile data. May contain NULs.
+ proflen - length of profile data in bytes.
+
+ png_set_sBIT(png_ptr, info_ptr, sig_bit);
+ sig_bit - the number of significant bits for
+ (PNG_INFO_sBIT) each of the gray, red,
+ green, and blue channels, whichever are
+ appropriate for the given color type
+ (png_color_16)
+
+ png_set_tRNS(png_ptr, info_ptr, trans, num_trans,
+ trans_values);
+ trans - array of transtqparent entries for
+ palette (PNG_INFO_tRNS)
+ trans_values - graylevel or color sample values of
+ the single transtqparent color for
+ non-paletted images (PNG_INFO_tRNS)
+ num_trans - number of transtqparent entries
+ (PNG_INFO_tRNS)
+
+ png_set_hIST(png_ptr, info_ptr, hist);
+ (PNG_INFO_hIST)
+ hist - histogram of palette (array of
+ png_uint_16)
+
+ png_set_tIME(png_ptr, info_ptr, mod_time);
+ mod_time - time image was last modified
+ (PNG_VALID_tIME)
+
+ png_set_bKGD(png_ptr, info_ptr, background);
+ background - background color (PNG_VALID_bKGD)
+
+ png_set_text(png_ptr, info_ptr, text_ptr, num_text);
+ text_ptr - array of png_text holding image
+ comments
+ text_ptr[i].compression - type of compression used
+ on "text" PNG_TEXT_COMPRESSION_NONE
+ PNG_TEXT_COMPRESSION_zTXt
+ PNG_ITXT_COMPRESSION_NONE
+ PNG_ITXT_COMPRESSION_zTXt
+ text_ptr[i].key - keyword for comment. Must contain
+ 1-79 characters.
+ text_ptr[i].text - text comments for current
+ keyword. Can be NULL or empty.
+ text_ptr[i].text_length - length of text string,
+ after decompression, 0 for iTXt
+ text_ptr[i].itxt_length - length of itxt string,
+ after decompression, 0 for tEXt/zTXt
+ text_ptr[i].lang - language of comment (NULL or
+ empty for unknown).
+ text_ptr[i].translated_keyword - keyword in UTF-8 (NULL
+ or empty for unknown).
+ num_text - number of comments
+
+ png_set_sPLT(png_ptr, info_ptr, &palette_ptr,
+ num_spalettes);
+ palette_ptr - array of png_sPLT_struct structures
+ to be added to the list of palettes
+ in the info structure.
+ num_spalettes - number of palette structures to be
+ added.
+
+ png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y,
+ unit_type);
+ offset_x - positive offset from the left
+ edge of the screen
+ offset_y - positive offset from the top
+ edge of the screen
+ unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
+
+ png_set_pHYs(png_ptr, info_ptr, res_x, res_y,
+ unit_type);
+ res_x - pixels/unit physical resolution
+ in x direction
+ res_y - pixels/unit physical resolution
+ in y direction
+ unit_type - PNG_RESOLUTION_UNKNOWN,
+ PNG_RESOLUTION_METER
+
+ png_set_sCAL(png_ptr, info_ptr, unit, width, height)
+ unit - physical scale units (an integer)
+ width - width of a pixel in physical scale units
+ height - height of a pixel in physical scale units
+ (width and height are doubles)
+
+ png_set_sCAL_s(png_ptr, info_ptr, unit, width, height)
+ unit - physical scale units (an integer)
+ width - width of a pixel in physical scale units
+ height - height of a pixel in physical scale units
+ (width and height are strings like "2.54")
+
+ png_set_unknown_chunks(png_ptr, info_ptr, &unknowns,
+ num_unknowns)
+ unknowns - array of png_unknown_chunk
+ structures holding unknown chunks
+ unknowns[i].name - name of unknown chunk
+ unknowns[i].data - data of unknown chunk
+ unknowns[i].size - size of unknown chunk's data
+ unknowns[i].location - position to write chunk in file
+ 0: do not write chunk
+ PNG_HAVE_IHDR: before PLTE
+ PNG_HAVE_PLTE: before IDAT
+ PNG_AFTER_IDAT: after IDAT
+
+The "location" member is set automatically according to
+what part of the output file has already been written.
+You can change its value after calling png_set_unknown_chunks()
+as demonstrated in pngtest.c. Within each of the "locations",
+the chunks are sequenced according to their position in the
+structure (that is, the value of "i", which is the order in which
+the chunk was either read from the input file or defined with
+png_set_unknown_chunks).
+
+A quick word about text and num_text. text is an array of png_text
+structures. num_text is the number of valid structures in the array.
+Each png_text structure holds a language code, a keyword, a text value,
+and a compression type.
+
+The compression types have the same valid numbers as the compression
+types of the image data. Currently, the only valid number is zero.
+However, you can store text either compressed or uncompressed, unlike
+images, which always have to be compressed. So if you don't want the
+text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
+Because tEXt and zTXt chunks don't have a language field, if you
+specify PNG_TEXT_COMPRESSION_NONE or PNG_TEXT_COMPRESSION_zTXt
+any language code or translated keyword will not be written out.
+
+Until text gets around 1000 bytes, it is not worth compressing it.
+After the text has been written out to the file, the compression type
+is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
+so that it isn't written out again at the end (in case you are calling
+png_write_end() with the same struct.
+
+The keywords that are given in the PNG Specification are:
+
+ Title Short (one line) title or
+ caption for image
+ Author Name of image's creator
+ Description Description of image (possibly long)
+ Copyright Copyright notice
+ Creation Time Time of original image creation
+ (usually RFC 1123 format, see below)
+ Software Software used to create the image
+ Disclaimer Legal disclaimer
+ Warning Warning of nature of content
+ Source Device used to create the image
+ Comment Miscellaneous comment; conversion
+ from other image format
+
+The keyword-text pairs work like this. Keywords should be short
+simple descriptions of what the comment is about. Some typical
+keywords are found in the PNG specification, as is some recommendations
+on keywords. You can repeat keywords in a file. You can even write
+some text before the image and some after. For example, you may want
+to put a description of the image before the image, but leave the
+disclaimer until after, so viewers working over modem connections
+don't have to wait for the disclaimer to go over the modem before
+they start seeing the image. Finally, keywords should be full
+words, not abbreviations. Keywords and text are in the ISO 8859-1
+(Latin-1) character set (a superset of regular ASCII) and can not
+contain NUL characters, and should not contain control or other
+unprintable characters. To make the comments widely readable, stick
+with basic ASCII, and avoid machine specific character set extensions
+like the IBM-PC character set. The keyword must be present, but
+you can leave off the text string on non-compressed pairs.
+Compressed pairs must have a text string, as only the text string
+is compressed anyway, so the compression would be meaningless.
+
+PNG supports modification time via the png_time structure. Two
+conversion routines are provided, png_convert_from_time_t() for
+time_t and png_convert_from_struct_tm() for struct tm. The
+time_t routine uses gmtime(). You don't have to use either of
+these, but if you wish to fill in the png_time structure directly,
+you should provide the time in universal time (GMT) if possible
+instead of your local time. Note that the year number is the full
+year (e.g. 1998, rather than 98 - PNG is year 2000 compliant!), and
+that months start with 1.
+
+If you want to store the time of the original image creation, you should
+use a plain tEXt chunk with the "Creation Time" keyword. This is
+necessary because the "creation time" of a PNG image is somewhat vague,
+depending on whether you mean the PNG file, the time the image was
+created in a non-PNG format, a still photo from which the image was
+scanned, or possibly the subject matter itself. In order to facilitate
+machine-readable dates, it is recommended that the "Creation Time"
+tEXt chunk use RFC 1123 format dates (e.g. "22 May 1997 18:07:10 GMT"),
+although this isn't a requirement. Unlike the tIME chunk, the
+"Creation Time" tEXt chunk is not expected to be automatically changed
+by the software. To facilitate the use of RFC 1123 dates, a function
+png_convert_to_rfc1123(png_timep) is provided to convert from PNG
+time to an RFC 1123 format string.
+
+Writing unknown chunks
+
+You can use the png_set_unknown_chunks function to queue up chunks
+for writing. You give it a chunk name, raw data, and a size; that's
+all there is to it. The chunks will be written by the next following
+png_write_info_before_PLTE, png_write_info, or png_write_end function.
+Any chunks previously read into the info structure's unknown-chunk
+list will also be written out in a sequence that satisfies the PNG
+specification's ordering rules.
+
+The high-level write interface
+
+At this point there are two ways to proceed; through the high-level
+write interface, or through a sequence of low-level write operations.
+You can use the high-level interface if your image data is present
+in the info structure. All defined output
+transformations are permitted, enabled by the following masks.
+
+ PNG_TRANSFORM_IDENTITY No transformation
+ PNG_TRANSFORM_PACKING Pack 1, 2 and 4-bit samples
+ PNG_TRANSFORM_PACKSWAP Change order of packed
+ pixels to LSB first
+ PNG_TRANSFORM_INVERT_MONO Invert monochrome images
+ PNG_TRANSFORM_SHIFT Normalize pixels to the
+ sBIT depth
+ PNG_TRANSFORM_BGR Flip RGB to BGR, RGBA
+ to BGRA
+ PNG_TRANSFORM_SWAP_ALPHA Flip RGBA to ARGB or GA
+ to AG
+ PNG_TRANSFORM_INVERT_ALPHA Change alpha from opacity
+ to transparency
+ PNG_TRANSFORM_SWAP_ENDIAN Byte-swap 16-bit samples
+ PNG_TRANSFORM_STRIP_FILLER Strip out filler bytes.
+
+If you have valid image data in the info structure (you can use
+png_set_rows() to put image data in the info structure), simply do this:
+
+ png_write_png(png_ptr, info_ptr, png_transforms, NULL)
+
+where png_transforms is an integer containing the logical OR of some set of
+transformation flags. This call is equivalent to png_write_info(),
+followed the set of transformations indicated by the transform tqmask,
+then png_write_image(), and finally png_write_end().
+
+(The final parameter of this call is not yet used. Someday it might point
+to transformation parameters required by some future output transform.)
+
+The low-level write interface
+
+If you are going the low-level route instead, you are now ready to
+write all the file information up to the actual image data. You do
+this with a call to png_write_info().
+
+ png_write_info(png_ptr, info_ptr);
+
+Note that there is one transformation you may need to do before
+png_write_info(). In PNG files, the alpha channel in an image is the
+level of opacity. If your data is supplied as a level of
+transparency, you can invert the alpha channel before you write it, so
+that 0 is fully transtqparent and 255 (in 8-bit or paletted images) or
+65535 (in 16-bit images) is fully opaque, with
+
+ png_set_invert_alpha(png_ptr);
+
+This must appear before png_write_info() instead of later with the
+other transformations because in the case of paletted images the tRNS
+chunk data has to be inverted before the tRNS chunk is written. If
+your image is not a paletted image, the tRNS data (which in such cases
+represents a single color to be rendered as transtqparent) won't need to
+be changed, and you can safely do this transformation after your
+png_write_info() call.
+
+If you need to write a private chunk that you want to appear before
+the PLTE chunk when PLTE is present, you can write the PNG info in
+two steps, and insert code to write your own chunk between them:
+
+ png_write_info_before_PLTE(png_ptr, info_ptr);
+ png_set_unknown_chunks(png_ptr, info_ptr, ...);
+ png_write_info(png_ptr, info_ptr);
+
+After you've written the file information, you can set up the library
+to handle any special transformations of the image data. The various
+ways to transform the data will be described in the order that they
+should occur. This is important, as some of these change the color
+type and/or bit depth of the data, and some others only work on
+certain color types and bit depths. Even though each transformation
+checks to see if it has data that it can do something with, you should
+make sure to only enable a transformation if it will be valid for the
+data. For example, don't swap red and blue on grayscale data.
+
+PNG files store RGB pixels packed into 3 or 6 bytes. This code tells
+the library to strip input data that has 4 or 8 bytes per pixel down
+to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2
+bytes per pixel).
+
+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+
+where the 0 is unused, and the location is either PNG_FILLER_BEFORE or
+PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel
+is stored XRGB or RGBX.
+
+PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
+they can, resulting in, for example, 8 pixels per byte for 1 bit files.
+If the data is supplied at 1 pixel per byte, use this code, which will
+correctly pack the pixels into a single byte:
+
+ png_set_packing(png_ptr);
+
+PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your
+data is of another bit depth, you can write an sBIT chunk into the
+file so that decoders can recover the original data if desired.
+
+ /* Set the true bit depth of the image data */
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ sig_bit.red = true_bit_depth;
+ sig_bit.green = true_bit_depth;
+ sig_bit.blue = true_bit_depth;
+ }
+ else
+ {
+ sig_bit.gray = true_bit_depth;
+ }
+ if (color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ sig_bit.alpha = true_bit_depth;
+ }
+
+ png_set_sBIT(png_ptr, info_ptr, &sig_bit);
+
+If the data is stored in the row buffer in a bit depth other than
+one supported by PNG (e.g. 3 bit data in the range 0-7 for a 4-bit PNG),
+this will scale the values to appear to be the correct bit depth as
+is required by PNG.
+
+ png_set_shift(png_ptr, &sig_bit);
+
+PNG files store 16 bit pixels in network byte order (big-endian,
+ie. most significant bits first). This code would be used if they are
+supplied the other way (little-endian, i.e. least significant bits
+first, the way PCs store them):
+
+ if (bit_depth > 8)
+ png_set_swap(png_ptr);
+
+If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
+need to change the order the pixels are packed into bytes, you can use:
+
+ if (bit_depth < 8)
+ png_set_packswap(png_ptr);
+
+PNG files store 3 color pixels in red, green, blue order. This code
+would be used if they are supplied as blue, green, red:
+
+ png_set_bgr(png_ptr);
+
+PNG files describe monochrome as black being zero and white being
+one. This code would be used if the pixels are supplied with this reversed
+(black being one and white being zero):
+
+ png_set_invert_mono(png_ptr);
+
+Finally, you can write your own transformation function if none of
+the existing ones meets your needs. This is done by setting a callback
+with
+
+ png_set_write_user_transform_fn(png_ptr,
+ write_transform_fn);
+
+You must supply the function
+
+ void write_transform_fn(png_ptr ptr, row_info_ptr
+ row_info, png_bytep data)
+
+See pngtest.c for a working example. Your function will be called
+before any of the other transformations are processed.
+
+You can also set up a pointer to a user structure for use by your
+callback function.
+
+ png_set_user_transform_info(png_ptr, user_ptr, 0, 0);
+
+The user_channels and user_depth parameters of this function are ignored
+when writing; you can set them to zero as shown.
+
+You can retrieve the pointer via the function png_get_user_transform_ptr().
+For example:
+
+ voidp write_user_transform_ptr =
+ png_get_user_transform_ptr(png_ptr);
+
+It is possible to have libpng flush any pending output, either manually,
+or automatically after a certain number of lines have been written. To
+flush the output stream a single time call:
+
+ png_write_flush(png_ptr);
+
+and to have libpng flush the output stream periodically after a certain
+number of scanlines have been written, call:
+
+ png_set_flush(png_ptr, nrows);
+
+Note that the distance between rows is from the last time png_write_flush()
+was called, or the first row of the image if it has never been called.
+So if you write 50 lines, and then png_set_flush 25, it will flush the
+output on the next scanline, and every 25 lines thereafter, unless
+png_write_flush() is called before 25 more lines have been written.
+If nrows is too small (less than about 10 lines for a 640 pixel wide
+RGB image) the image compression may decrease noticeably (although this
+may be acceptable for real-time applications). Infrequent flushing will
+only degrade the compression performance by a few percent over images
+that do not use flushing.
+
+Writing the image data
+
+That's it for the transformations. Now you can write the image data.
+The simplest way to do this is in one function call. If you have the
+whole image in memory, you can just call png_write_image() and libpng
+will write the image. You will need to pass in an array of pointers to
+each row. This function automatically handles interlacing, so you don't
+need to call png_set_interlace_handling() or call this function multiple
+times, or any of that other stuff necessary with png_write_rows().
+
+ png_write_image(png_ptr, row_pointers);
+
+where row_pointers is:
+
+ png_byte *row_pointers[height];
+
+You can point to void or char or whatever you use for pixels.
+
+If you don't want to write the whole image at once, you can
+use png_write_rows() instead. If the file is not interlaced,
+this is simple:
+
+ png_write_rows(png_ptr, row_pointers,
+ number_of_rows);
+
+row_pointers is the same as in the png_write_image() call.
+
+If you are just writing one row at a time, you can do this with
+a single row_pointer instead of an array of row_pointers:
+
+ png_bytep row_pointer = row;
+
+ png_write_row(png_ptr, row_pointer);
+
+When the file is interlaced, things can get a good deal more
+complicated. The only currently (as of the PNG Specification
+version 1.2, dated July 1999) defined interlacing scheme for PNG files
+is the "Adam7" interlace scheme, that breaks down an
+image into seven smaller images of varying size. libpng will build
+these images for you, or you can do them yourself. If you want to
+build them yourself, see the PNG specification for details of which
+pixels to write when.
+
+If you don't want libpng to handle the interlacing details, just
+use png_set_interlace_handling() and call png_write_rows() the
+correct number of times to write all seven sub-images.
+
+If you want libpng to build the sub-images, call this before you start
+writing any rows:
+
+ number_of_passes =
+ png_set_interlace_handling(png_ptr);
+
+This will return the number of passes needed. Currently, this
+is seven, but may change if another interlace type is added.
+
+Then write the complete image number_of_passes times.
+
+ png_write_rows(png_ptr, row_pointers,
+ number_of_rows);
+
+As some of these rows are not used, and thus return immediately,
+you may want to read about interlacing in the PNG specification,
+and only update the rows that are actually used.
+
+Finishing a sequential write
+
+After you are finished writing the image, you should finish writing
+the file. If you are interested in writing comments or time, you should
+pass an appropriately filled png_info pointer. If you are not interested,
+you can pass NULL.
+
+ png_write_end(png_ptr, info_ptr);
+
+When you are done, you can free all memory used by libpng like this:
+
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+It is also possible to individually free the info_ptr members that
+point to libpng-allocated storage with the following function:
+
+ png_free_data(png_ptr, info_ptr, tqmask, seq)
+ tqmask - identifies data to be freed, a tqmask
+ containing the logical OR of one or
+ more of
+ PNG_FREE_PLTE, PNG_FREE_TRNS,
+ PNG_FREE_HIST, PNG_FREE_ICCP,
+ PNG_FREE_PCAL, PNG_FREE_ROWS,
+ PNG_FREE_SCAL, PNG_FREE_SPLT,
+ PNG_FREE_TEXT, PNG_FREE_UNKN,
+ or simply PNG_FREE_ALL
+ seq - sequence number of item to be freed
+ (-1 for all items)
+
+This function may be safely called when the relevant storage has
+already been freed, or has not yet been allocated, or was allocated
+by the user and not by libpng, and will in those
+cases do nothing. The "seq" parameter is ignored if only one item
+of the selected data type, such as PLTE, is allowed. If "seq" is not
+-1, and multiple items are allowed for the data type identified in
+the tqmask, such as text or sPLT, only the n'th item in the structure
+is freed, where n is "seq".
+
+If you allocated data such as a palette that you passed
+in to libpng with png_set_*, you must not free it until just before the call to
+png_destroy_write_struct().
+
+The default behavior is only to free data that was allocated internally
+by libpng. This can be changed, so that libpng will not free the data,
+or so that it will free data that was allocated by the user with png_malloc()
+or png_zalloc() and passed in via a png_set_*() function, with
+
+ png_data_freer(png_ptr, info_ptr, freer, tqmask)
+ tqmask - which data elements are affected
+ same choices as in png_free_data()
+ freer - one of
+ PNG_DESTROY_WILL_FREE_DATA
+ PNG_SET_WILL_FREE_DATA
+ PNG_USER_WILL_FREE_DATA
+
+For example, to transfer responsibility for some data from a read structure
+to a write structure, you could use
+
+ png_data_freer(read_ptr, read_info_ptr,
+ PNG_USER_WILL_FREE_DATA,
+ PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+ png_data_freer(write_ptr, write_info_ptr,
+ PNG_DESTROY_WILL_FREE_DATA,
+ PNG_FREE_PLTE|PNG_FREE_tRNS|PNG_FREE_hIST)
+
+thereby briefly reassigning responsibility for freeing to the user but
+immediately afterwards reassigning it once more to the write_destroy
+function. Having done this, it would then be safe to destroy the read
+structure and continue to use the PLTE, tRNS, and hIST data in the write
+structure.
+
+This function only affects data that has already been allocated.
+You can call this function before calling after the png_set_*() functions
+to control whether the user or png_destroy_*() is supposed to free the data.
+When the user assumes responsibility for libpng-allocated data, the
+application must use
+png_free() to free it, and when the user transfers responsibility to libpng
+for data that the user has allocated, the user must have used png_malloc()
+or png_zalloc() to allocate it.
+
+If you allocated text_ptr.text, text_ptr.lang, and text_ptr.translated_keyword
+separately, do not transfer responsibility for freeing text_ptr to libpng,
+because when libpng fills a png_text structure it combines these members with
+the key member, and png_free_data() will free only text_ptr.key. Similarly,
+if you transfer responsibility for free'ing text_ptr from libpng to your
+application, your application must not separately free those members.
+For a more compact example of writing a PNG image, see the file example.c.
+
+V. Modifying/Customizing libpng:
+
+There are three issues here. The first is changing how libpng does
+standard things like memory allocation, input/output, and error handling.
+The second deals with more complicated things like adding new chunks,
+adding new transformations, and generally changing how libpng works.
+Both of those are compile-time issues; that is, they are generally
+determined at the time the code is written, and there is rarely a need
+to provide the user with a means of changing them. The third is a
+run-time issue: choosing between and/or tuning one or more alternate
+versions of computationally intensive routines; specifically, optimized
+assembly-language (and therefore compiler- and platform-dependent)
+versions.
+
+Memory allocation, input/output, and error handling
+
+All of the memory allocation, input/output, and error handling in libpng
+goes through callbacks that are user-settable. The default routines are
+in pngmem.c, pngrio.c, pngwio.c, and pngerror.c, respectively. To change
+these functions, call the appropriate png_set_*_fn() function.
+
+Memory allocation is done through the functions png_malloc()
+and png_free(). These currently just call the standard C functions. If
+your pointers can't access more then 64K at a time, you will want to set
+MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling
+memory allocation on a platform will change between applications, these
+functions must be modified in the library at compile time. If you prefer
+to use a different method of allocating and freeing data, you can use
+png_create_read_struct_2() or png_create_write_struct_2() to register
+your own functions as described above.
+
+These functions also provide a void pointer that can be retrieved via
+
+ mem_ptr=png_get_mem_ptr(png_ptr);
+
+Your tqreplacement memory functions must have prototypes as follows:
+
+ png_voidp malloc_fn(png_structp png_ptr,
+ png_size_t size);
+ void free_fn(png_structp png_ptr, png_voidp ptr);
+
+Your malloc_fn() should return NULL in case of failure. The png_malloc()
+function will call png_error() if it receives a NULL from the system
+memory allocator or from your tqreplacement malloc_fn().
+
+Input/Output in libpng is done through png_read() and png_write(),
+which currently just call fread() and fwrite(). The FILE * is stored in
+png_struct and is initialized via png_init_io(). If you wish to change
+the method of I/O, the library supplies callbacks that you can set
+through the function png_set_read_fn() and png_set_write_fn() at run
+time, instead of calling the png_init_io() function. These functions
+also provide a void pointer that can be retrieved via the function
+png_get_io_ptr(). For example:
+
+ png_set_read_fn(png_structp read_ptr,
+ voidp read_io_ptr, png_rw_ptr read_data_fn)
+
+ png_set_write_fn(png_structp write_ptr,
+ voidp write_io_ptr, png_rw_ptr write_data_fn,
+ png_flush_ptr output_flush_fn);
+
+ voidp read_io_ptr = png_get_io_ptr(read_ptr);
+ voidp write_io_ptr = png_get_io_ptr(write_ptr);
+
+The tqreplacement I/O functions must have prototypes as follows:
+
+ void user_read_data(png_structp png_ptr,
+ png_bytep data, png_size_t length);
+ void user_write_data(png_structp png_ptr,
+ png_bytep data, png_size_t length);
+ void user_flush_data(png_structp png_ptr);
+
+Supplying NULL for the read, write, or flush functions sets them back
+to using the default C stream functions. It is an error to read from
+a write stream, and vice versa.
+
+Error handling in libpng is done through png_error() and png_warning().
+Errors handled through png_error() are fatal, meaning that png_error()
+should never return to its caller. Currently, this is handled via
+setjmp() and longjmp() (unless you have compiled libpng with
+PNG_SETJMP_NOT_SUPPORTED, in which case it is handled via PNG_ABORT()),
+but you could change this to do things like exit() if you should wish.
+
+On non-fatal errors, png_warning() is called
+to print a warning message, and then control returns to the calling code.
+By default png_error() and png_warning() print a message on stderr via
+fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined
+(because you don't want the messages) or PNG_NO_STDIO defined (because
+fprintf() isn't available). If you wish to change the behavior of the error
+functions, you will need to set up your own message callbacks. These
+functions are normally supplied at the time that the png_struct is created.
+It is also possible to redirect errors and warnings to your own tqreplacement
+functions after png_create_*_struct() has been called by calling:
+
+ png_set_error_fn(png_structp png_ptr,
+ png_voidp error_ptr, png_error_ptr error_fn,
+ png_error_ptr warning_fn);
+
+ png_voidp error_ptr = png_get_error_ptr(png_ptr);
+
+If NULL is supplied for either error_fn or warning_fn, then the libpng
+default function will be used, calling fprintf() and/or longjmp() if a
+problem is encountered. The tqreplacement error functions should have
+parameters as follows:
+
+ void user_error_fn(png_structp png_ptr,
+ png_const_charp error_msg);
+ void user_warning_fn(png_structp png_ptr,
+ png_const_charp warning_msg);
+
+The motivation behind using setjmp() and longjmp() is the C++ throw and
+catch exception handling methods. This makes the code much easier to write,
+as there is no need to check every return code of every function call.
+However, there are some uncertainties about the status of local variables
+after a longjmp, so the user may want to be careful about doing anything after
+setjmp returns non-zero besides returning itself. Consult your compiler
+documentation for more details. For an alternative approach, you may wish
+to use the "cexcept" facility (see http://cexcept.sourceforge.net).
+
+Custom chunks
+
+If you need to read or write custom chunks, you may need to get deeper
+into the libpng code. The library now has mechanisms for storing
+and writing chunks of unknown type; you can even declare callbacks
+for custom chunks. Hoewver, this may not be good enough if the
+library code itself needs to know about interactions between your
+chunk and existing `intrinsic' chunks.
+
+If you need to write a new intrinsic chunk, first read the PNG
+specification. Acquire a first level of
+understanding of how it works. Pay particular attention to the
+sections that describe chunk names, and look at how other chunks were
+designed, so you can do things similarly. Second, check out the
+sections of libpng that read and write chunks. Try to tqfind a chunk
+that is similar to yours and use it as a template. More details can
+be found in the comments inside the code. It is best to handle unknown
+chunks in a generic method, via callback functions, instead of by
+modifying libpng functions.
+
+If you wish to write your own transformation for the data, look through
+the part of the code that does the transformations, and check out some of
+the simpler ones to get an idea of how they work. Try to tqfind a similar
+transformation to the one you want to add and copy off of it. More details
+can be found in the comments inside the code itself.
+
+Configuring for 16 bit platforms
+
+You will want to look into zconf.h to tell zlib (and thus libpng) that
+it cannot allocate more then 64K at a time. Even if you can, the memory
+won't be accessible. So limit zlib and libpng to 64K by defining MAXSEG_64K.
+
+Configuring for DOS
+
+For DOS users who only have access to the lower 640K, you will
+have to limit zlib's memory usage via a png_set_compression_mem_level()
+call. See zlib.h or zconf.h in the zlib library for more information.
+
+Configuring for Medium Model
+
+Libpng's support for medium model has been tested on most of the popular
+compilers. Make sure MAXSEG_64K gets defined, USE_FAR_KEYWORD gets
+defined, and FAR gets defined to far in pngconf.h, and you should be
+all set. Everything in the library (except for zlib's structure) is
+expecting far data. You must use the typedefs with the p or pp on
+the end for pointers (or at least look at them and be careful). Make
+note that the rows of data are defined as png_bytepp, which is an
+unsigned char far * far *.
+
+Configuring for gui/windowing platforms:
+
+You will need to write new error and warning functions that use the GUI
+interface, as described previously, and set them to be the error and
+warning functions at the time that png_create_*_struct() is called,
+in order to have them available during the structure initialization.
+They can be changed later via png_set_error_fn(). On some compilers,
+you may also have to change the memory allocators (png_malloc, etc.).
+
+Configuring for compiler xxx:
+
+All includes for libpng are in pngconf.h. If you need to add/change/delete
+an include, this is the place to do it. The includes that are not
+needed outside libpng are protected by the PNG_INTERNAL definition,
+which is only defined for those routines inside libpng itself. The
+files in libpng proper only include png.h, which includes pngconf.h.
+
+Configuring zlib:
+
+There are special functions to configure the compression. Perhaps the
+most useful one changes the compression level, which currently uses
+input compression values in the range 0 - 9. The library normally
+uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests
+have shown that for a large majority of images, compression values in
+the range 3-6 compress nearly as well as higher levels, and do so much
+faster. For online applications it may be desirable to have maximum speed
+(Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also
+specify no compression (Z_NO_COMPRESSION = 0), but this would create
+files larger than just storing the raw bitmap. You can specify the
+compression level by calling:
+
+ png_set_compression_level(png_ptr, level);
+
+Another useful one is to reduce the memory level used by the library.
+The memory level defaults to 8, but it can be lowered if you are
+short on memory (running DOS, for example, where you only have 640K).
+Note that the memory level does have an effect on compression; among
+other things, lower levels will result in sections of incompressible
+data being emitted in smaller stored blocks, with a correspondingly
+larger relative overhead of up to 15% in the worst case.
+
+ png_set_compression_mem_level(png_ptr, level);
+
+The other functions are for configuring zlib. They are not recommended
+for normal use and may result in writing an invalid PNG file. See
+zlib.h for more information on what these mean.
+
+ png_set_compression_strategy(png_ptr,
+ strategy);
+ png_set_compression_window_bits(png_ptr,
+ window_bits);
+ png_set_compression_method(png_ptr, method);
+ png_set_compression_buffer_size(png_ptr, size);
+
+Controlling row filtering
+
+If you want to control whether libpng uses filtering or not, which
+filters are used, and how it goes about picking row filters, you
+can call one of these functions. The selection and configuration
+of row filters can have a significant impact on the size and
+encoding speed and a somewhat lesser impact on the decoding speed
+of an image. Filtering is enabled by default for RGB and grayscale
+images (with and without alpha), but not for paletted images nor
+for any images with bit depths less than 8 bits/pixel.
+
+The 'method' parameter sets the main filtering method, which is
+currently only '0' in the PNG 1.2 specification. The 'filters'
+parameter sets which filter(s), if any, should be used for each
+scanline. Possible values are PNG_ALL_FILTERS and PNG_NO_FILTERS
+to turn filtering on and off, respectively.
+
+Individual filter types are PNG_FILTER_NONE, PNG_FILTER_SUB,
+PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH, which can be bitwise
+ORed together with '|' to specify one or more filters to use.
+These filters are described in more detail in the PNG specification.
+If you intend to change the filter type during the course of writing
+the image, you should start with flags set for all of the filters
+you intend to use so that libpng can initialize its internal
+structures appropriately for all of the filter types. (Note that this
+means the first row must always be adaptively filtered, because libpng
+currently does not allocate the filter buffers until png_write_row()
+is called for the first time.)
+
+ filters = PNG_FILTER_NONE | PNG_FILTER_SUB
+ PNG_FILTER_UP | PNG_FILTER_AVE |
+ PNG_FILTER_PAETH | PNG_ALL_FILTERS;
+
+ png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
+ filters);
+ The second parameter can also be
+ PNG_INTRAPIXEL_DIFFERENCING if you are
+ writing a PNG to be embedded in a MNG
+ datastream. This parameter must be the
+ same as the value of filter_method used
+ in png_set_IHDR().
+
+It is also possible to influence how libpng chooses from among the
+available filters. This is done in one or both of two ways - by
+telling it how important it is to keep the same filter for successive
+rows, and by telling it the relative computational costs of the filters.
+
+ double weights[3] = {1.5, 1.3, 1.1},
+ costs[PNG_FILTER_VALUE_LAST] =
+ {1.0, 1.3, 1.3, 1.5, 1.7};
+
+ png_set_filter_heuristics(png_ptr,
+ PNG_FILTER_HEURISTIC_WEIGHTED, 3,
+ weights, costs);
+
+The weights are multiplying factors that indicate to libpng that the
+row filter should be the same for successive rows unless another row filter
+is that many times better than the previous filter. In the above example,
+if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
+"sum of absolute differences" 1.5 x 1.3 times higher than other filters
+and still be chosen, while the NONE filter could have a sum 1.1 times
+higher than other filters and still be chosen. Unspecified weights are
+taken to be 1.0, and the specified weights should probably be declining
+like those above in order to emphasize recent filters over older filters.
+
+The filter costs specify for each filter type a relative decoding cost
+to be considered when selecting row filters. This means that filters
+with higher costs are less likely to be chosen over filters with lower
+costs, unless their "sum of absolute differences" is that much smaller.
+The costs do not necessarily reflect the exact computational speeds of
+the various filters, since this would unduly influence the final image
+size.
+
+Note that the numbers above were invented purely for this example and
+are given only to help explain the function usage. Little testing has
+been done to tqfind optimum values for either the costs or the weights.
+
+Removing unwanted object code
+
+There are a bunch of #define's in pngconf.h that control what parts of
+libpng are compiled. All the defines end in _SUPPORTED. If you are
+never going to use a capability, you can change the #define to #undef
+before recompiling libpng and save yourself code and data space, or
+you can turn off individual capabilities with defines that begin with
+PNG_NO_.
+
+You can also turn all of the transforms and ancillary chunk capabilities
+off en masse with compiler directives that define
+PNG_NO_READ[or WRITE]_TRANSFORMS, or PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS,
+or all four,
+along with directives to turn on any of the capabilities that you do
+want. The PNG_NO_READ[or WRITE]_TRANSFORMS directives disable
+the extra transformations but still leave the library fully capable of reading
+and writing PNG files with all known public chunks
+Use of the PNG_NO_READ[or WRITE]_ANCILLARY_CHUNKS directive
+produces a library that is incapable of reading or writing ancillary chunks.
+If you are not using the progressive reading capability, you can
+turn that off with PNG_NO_PROGRESSIVE_READ (don't confuse
+this with the INTERLACING capability, which you'll still have).
+
+All the reading and writing specific code are in separate files, so the
+linker should only grab the files it needs. However, if you want to
+make sure, or if you are building a stand alone library, all the
+reading files start with pngr and all the writing files start with
+pngw. The files that don't match either (like png.c, pngtrans.c, etc.)
+are used for both reading and writing, and always need to be included.
+The progressive reader is in pngpread.c
+
+If you are creating or distributing a dynamically linked library (a .so
+or DLL file), you should not remove or disable any parts of the library,
+as this will cause applications linked with different versions of the
+library to fail if they call functions not available in your library.
+The size of the library itself should not be an issue, because only
+those sections that are actually used will be loaded into memory.
+
+Requesting debug printout
+
+The macro definition PNG_DEBUG can be used to request debugging
+printout. Set it to an integer value in the range 0 to 3. Higher
+numbers result in increasing amounts of debugging information. The
+information is printed to the "stderr" file, unless another file
+name is specified in the PNG_DEBUG_FILE macro definition.
+
+When PNG_DEBUG > 0, the following functions (macros) become available:
+
+ png_debug(level, message)
+ png_debug1(level, message, p1)
+ png_debug2(level, message, p1, p2)
+
+in which "level" is compared to PNG_DEBUG to decide whether to print
+the message, "message" is the formatted string to be printed,
+and p1 and p2 are parameters that are to be embedded in the string
+according to printf-style formatting directives. For example,
+
+ png_debug1(2, "foo=%d\n", foo);
+
+is expanded to
+
+ if(PNG_DEBUG > 2)
+ fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
+
+When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
+can still use PNG_DEBUG to control your own debugging:
+
+ #ifdef PNG_DEBUG
+ fprintf(stderr, ...
+ #endif
+
+When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
+having level = 0 will be printed. There aren't any such statements in
+this version of libpng, but if you insert some they will be printed.
+
+VI. Runtime optimization
+
+A new feature in libpng 1.2.0 is the ability to dynamically switch between
+standard and optimized versions of some routines. Currently these are
+limited to three computationally intensive tasks when reading PNG files:
+decoding row filters, expanding interlacing, and combining interlaced or
+transtqparent row data with previous row data. Currently the optimized
+versions are available only for x86 (Intel, AMD, etc.) platforms with
+MMX support, though this may change in future versions. (For example,
+the non-MMX assembler optimizations for zlib might become similarly
+runtime-selectable in future releases, in which case libpng could be
+extended to support them. Alternatively, the compile-time choice of
+floating-point versus integer routines for gamma correction might become
+runtime-selectable.)
+
+Because such optimizations tend to be very platform- and compiler-dependent,
+both in how they are written and in how they perform, the new runtime code
+in libpng has been written to allow programs to query, enable, and disable
+either specific optimizations or all such optimizations. For example, to
+enable all possible optimizations (bearing in mind that some "optimizations"
+may actually run more slowly in rare cases):
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ png_uint_32 tqmask, flags;
+
+ flags = png_get_asm_flags(png_ptr);
+ tqmask = png_get_asm_flagtqmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+ png_set_asm_flags(png_ptr, flags | tqmask);
+ #endif
+
+To enable only optimizations relevant to reading PNGs, use PNG_SELECT_READ
+by itself when calling png_get_asm_flagtqmask(); similarly for optimizing
+only writing. To disable all optimizations:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ flags = png_get_asm_flags(png_ptr);
+ tqmask = png_get_asm_flagtqmask(PNG_SELECT_READ | PNG_SELECT_WRITE);
+ png_set_asm_flags(png_ptr, flags & ~tqmask);
+ #endif
+
+To enable or disable only MMX-related features, use png_get_mmx_flagtqmask()
+in place of png_get_asm_flagtqmask(). The mmx version takes one additional
+parameter:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ int selection = PNG_SELECT_READ | PNG_SELECT_WRITE;
+ int compilerID;
+
+ tqmask = png_get_mmx_flagtqmask(selection, &compilerID);
+ #endif
+
+On return, compilerID will indicate which version of the MMX assembler
+optimizations was compiled. Currently two flavors exist: Microsoft
+Visual C++ (compilerID == 1) and GNU C (a.k.a. gcc/gas, compilerID == 2).
+On non-x86 platforms or on systems compiled without MMX optimizations, a
+value of -1 is used.
+
+Note that both png_get_asm_flagtqmask() and png_get_mmx_flagtqmask() return
+all valid, settable optimization bits for the version of the library that's
+currently in use. In the case of shared (dynamically linked) libraries,
+this may include optimizations that did not exist at the time the code was
+written and compiled. It is also possible, of course, to enable only known,
+specific optimizations; for example:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ flags = PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
+ | PNG_ASM_FLAG_MMX_READ_INTERLACE \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_UP \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+ png_set_asm_flags(png_ptr, flags);
+ #endif
+
+This method would enable only the MMX read-optimizations available at the
+time of libpng 1.2.0's release, regardless of whether a later version of
+the DLL were actually being used. (Also note that these functions did not
+exist in versions older than 1.2.0, so any attempt to run a dynamically
+linked app on such an older version would fail.)
+
+To determine whether the processor supports MMX instructions at all, use
+the png_mmx_support() function:
+
+ #if defined(PNG_LIBPNG_VER) && (PNG_LIBPNG_VER >= 10200)
+ mmxsupport = png_mmx_support();
+ #endif
+
+It returns -1 if MMX support is not compiled into libpng, 0 if MMX code
+is compiled but MMX is not supported by the processor, or 1 if MMX support
+is fully available. Note that png_mmx_support(), png_get_mmx_flagtqmask(),
+and png_get_asm_flagtqmask() all may be called without allocating and ini-
+tializing any PNG structures (for example, as part of a usage screen or
+"about" box).
+
+The following code can be used to prevent an application from using the
+thread_unsafe features, even if libpng was built with PNG_THREAD_UNSAFE_OK
+defined:
+
+#if defined(PNG_USE_PNGGCCRD) && defined(PNG_ASSEMBLER_CODE_SUPPORTED) \
+ && defined(PNG_THREAD_UNSAFE_OK)
+ /* Disable thread-unsafe features of pnggccrd */
+ if (png_access_version() >= 10200)
+ {
+ png_uint_32 mmx_disable_mask = 0;
+ png_uint_32 asm_flags;
+
+ mmx_disable_mask |= ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH );
+ asm_flags = png_get_asm_flags(png_ptr);
+ png_set_asm_flags(png_ptr, asm_flags & ~mmx_disable_mask);
+ }
+#endif
+
+For more extensive examples of runtime querying, enabling and disabling
+of optimized features, see contrib/gregbook/readpng2.c in the libpng
+source-code distribution.
+
+
+VII. MNG support
+
+The MNG specification (available at http://www.libpng.org/pub/mng) allows
+certain extensions to PNG for PNG images that are embedded in MNG datastreams.
+Libpng can support some of these extensions. To enable them, use the
+png_permit_mng_features() function:
+
+ feature_set = png_permit_mng_features(png_ptr, tqmask)
+ tqmask is a png_uint_32 containing the logical OR of the
+ features you want to enable. These include
+ PNG_FLAG_MNG_EMPTY_PLTE
+ PNG_FLAG_MNG_FILTER_64
+ PNG_ALL_MNG_FEATURES
+ feature_set is a png_32_uint that is the logical AND of
+ your tqmask with the set of MNG features that is
+ supported by the version of libpng that you are using.
+
+It is an error to use this function when reading or writing a standalone
+PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped
+in a MNG datastream. As a minimum, it must have the MNG 8-byte signature
+and the MHDR and MEND chunks. Libpng does not provide support for these
+or any other MNG chunks; your application must provide its own support for
+them. You may wish to consider using libmng (available at
+http://www.libmng.com) instead.
+
+VIII. Changes to Libpng from version 0.88
+
+It should be noted that versions of libpng later than 0.96 are not
+distributed by the original libpng author, Guy Schalnat, nor by
+Andreas Dilger, who had taken over from Guy during 1996 and 1997, and
+distributed versions 0.89 through 0.96, but rather by another member
+of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are
+still alive and well, but they have moved on to other things.
+
+The old libpng functions png_read_init(), png_write_init(),
+png_info_init(), png_read_destroy(), and png_write_destroy() have been
+moved to PNG_INTERNAL in version 0.95 to discourage their use. These
+functions will be removed from libpng version 2.0.0.
+
+The preferred method of creating and initializing the libpng structures is
+via the png_create_read_struct(), png_create_write_struct(), and
+png_create_info_struct() because they isolate the size of the structures
+from the application, allow version error checking, and also allow the
+use of custom error handling routines during the initialization, which
+the old functions do not. The functions png_read_destroy() and
+png_write_destroy() do not actually free the memory that libpng
+allocated for these structs, but just reset the data structures, so they
+can be used instead of png_destroy_read_struct() and
+png_destroy_write_struct() if you feel there is too much system overhead
+allocating and freeing the png_struct for each image read.
+
+Setting the error callbacks via png_set_message_fn() before
+png_read_init() as was suggested in libpng-0.88 is no longer supported
+because this caused applications that do not use custom error functions
+to fail if the png_ptr was not initialized to zero. It is still possible
+to set the error callbacks AFTER png_read_init(), or to change them with
+png_set_error_fn(), which is essentially the same function, but with a new
+name to force compilation errors with applications that try to use the old
+method.
+
+Starting with version 1.0.7, you can tqfind out which version of the library
+you are using at run-time:
+
+ png_uint_32 libpng_vn = png_access_version_number();
+
+The number libpng_vn is constructed from the major version, minor
+version with leading zero, and release number with leading zero,
+(e.g., libpng_vn for version 1.0.7 is 10007).
+
+You can also check which version of png.h you used when compiling your
+application:
+
+ png_uint_32 application_vn = PNG_LIBPNG_VER;
+
+IX. Y2K Compliance in libpng
+
+October 3, 2002
+
+Since the PNG Development group is an ad-hoc body, we can't make
+an official declaration.
+
+This is your unofficial assurance that libpng from version 0.71 and
+upward through 1.2.5 are Y2K compliant. It is my belief that earlier
+versions were also Y2K compliant.
+
+Libpng only has three year fields. One is a 2-byte unsigned integer that
+will hold years up to 65535. The other two hold the date in text
+format, and will hold years up to 9999.
+
+The integer is
+ "png_uint_16 year" in png_time_struct.
+
+The strings are
+ "png_charp time_buffer" in png_struct and
+ "near_time_buffer", which is a local character string in png.c.
+
+There are seven time-related functions:
+
+ png_convert_to_rfc_1123() in png.c
+ (formerly png_convert_to_rfc_1152() in error)
+ png_convert_from_struct_tm() in pngwrite.c, called
+ in pngwrite.c
+ png_convert_from_time_t() in pngwrite.c
+ png_get_tIME() in pngget.c
+ png_handle_tIME() in pngrutil.c, called in pngread.c
+ png_set_tIME() in pngset.c
+ png_write_tIME() in pngwutil.c, called in pngwrite.c
+
+All appear to handle dates properly in a Y2K environment. The
+png_convert_from_time_t() function calls gmtime() to convert from system
+clock time, which returns (year - 1900), which we properly convert to
+the full 4-digit year. There is a possibility that applications using
+libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+function, or that they are incorrectly passing only a 2-digit year
+instead of "year - 1900" into the png_convert_from_struct_tm() function,
+but this is not under our control. The libpng documentation has always
+stated that it works with 4-digit years, and the APIs have been
+documented as such.
+
+The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
+integer to hold the year, and can hold years as large as 65535.
+
+zlib, upon which libpng depends, is also Y2K compliant. It tqcontains
+no date-related code.
+
+
+ Glenn Randers-Pehrson
+ libpng maintainer
+ PNG Development Group
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/libpngpf.3 b/tqtinterface/qt4/src/3rdparty/libpng/libpngpf.3
new file mode 100644
index 0000000..a3bc995
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/libpngpf.3
@@ -0,0 +1,552 @@
+.TH LIBPNGPF 3 "October 3, 2002"
+.SH NAME
+libpng \- Portable Network Graphics (PNG) Reference Library 1.2.5
+(private functions)
+.SH SYNOPSIS
+\fB#include <png.h>\fP
+
+\fI\fB
+
+\fBvoid png_build_gamma_table (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_build_grayscale_palette (int \fP\fIbit_depth\fP\fB, png_colorp \fIpalette\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_calculate_crc (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIptr\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_check_chunk_name (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIchunk_name\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_size_t png_check_keyword (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charpp \fInew_key\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_combine_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fItqmask\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_correct_palette (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, int \fInum_palette\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_crc_error (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_crc_finish (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIskip\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_crc_read (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuf\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_create_struct (int \fItype\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_voidp png_create_struct_2 (int \fP\fItype\fP\fB, png_malloc_ptr \fP\fImalloc_fn\fP\fB, png_voidp \fImem_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_charp png_decompress_chunk (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcomp_type\fP\fB, png_charp \fP\fIchunkdata\fP\fB, png_size_t \fP\fIchunklength\fP\fB, png_size_t \fP\fIprefix_length\fP\fB, png_size_t \fI*data_length\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_struct (png_voidp \fIstruct_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_destroy_struct_2 (png_voidp \fP\fIstruct_ptr\fP\fB, png_free_ptr \fP\fIfree_fn\fP\fB, png_voidp \fImem_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_background (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fP\fItrans_values\fP\fB, png_color_16p \fP\fIbackground\fP\fB, png_color_16p \fP\fIbackground_1\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_bytep \fP\fIgamma_from_1\fP\fB, png_bytep \fP\fIgamma_to_1\fP\fB, png_uint_16pp \fP\fIgamma_16\fP\fB, png_uint_16pp \fP\fIgamma_16_from_1\fP\fB, png_uint_16pp \fP\fIgamma_16_to_1\fP\fB, int \fIgamma_shift\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_bgr (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_chop (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_dither (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIpalette_lookup\fP\fB, png_bytep \fIdither_lookup\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_expand (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_16p \fItrans_value\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_expand_palette (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_bytep \fP\fItrans\fP\fB, int \fInum_trans\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_gamma (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIgamma_table\fP\fB, png_uint_16pp \fP\fIgamma_16_table\fP\fB, int \fIgamma_shift\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_gray_to_rgb (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_invert (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_pack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIbit_depth\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_packswap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_read_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fP\fIfiller\fP\fB, png_uint_32 \fIflags\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_read_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fP\fIpass\fP\fB, png_uint_32 \fItransformations\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_read_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_read_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_do_rgb_to_gray (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_shift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIbit_depth\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_strip_filler (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_uint_32 \fIflags\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_swap (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_unpack (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_unshift (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_color_8p \fIsig_bits\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_write_interlace (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, int \fIpass\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_write_invert_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_write_swap_alpha (png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_do_write_transformations (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid *png_far_to_near (png_structp png_ptr,png_voidp \fP\fIptr\fP\fB, int \fIcheck\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_flush (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_int_32 png_get_int_32 (png_bytep \fIbuf\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_16 png_get_uint_16 (png_bytep \fIbuf\fP\fB);\fP
+
+\fI\fB
+
+\fBpng_uint_32 png_get_uint_32 (png_bytep \fIbuf\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_bKGD (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_cHRM (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_gAMA (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_IEND (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_iTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_sRGB (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_info_destroy (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_init_mmx_flags (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_init_read_transformations (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_IDAT_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_process_some_data (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_check_crc (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_crc_finish (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_crc_skip (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_fill_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_handle_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_handle_unknown (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_handle_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_uint_32 \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_have_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_have_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_have_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIrow\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_process_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_chunk (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_end (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_IDAT (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_sig (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_read_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_restore_buffer (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIbuffer\fP\fB, png_size_t \fIbuffer_length\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_push_save_buffer (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_filter_row (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fP\fIrow_info\fP\fB, png_bytep \fP\fIrow\fP\fB, png_bytep \fP\fIprev_row\fP\fB, int \fIfilter\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_push_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_start_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_read_transform_info (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fIinfo_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_reset_crc (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_save_int_32 (png_bytep \fP\fIbuf\fP\fB, png_int_32 \fIi\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_save_uint_16 (png_bytep \fP\fIbuf\fP\fB, unsigned int \fIi\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_save_uint_32 (png_bytep \fP\fIbuf\fP\fB, png_uint_32 \fIi\fP\fB);\fP
+
+\fI\fB
+
+\fBint png_set_text_2 (png_structp \fP\fIpng_ptr\fP\fB, png_infop \fP\fIinfo_ptr\fP\fB, png_textp \fP\fItext_ptr\fP\fB, int \fInum_text)\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_cHRM (png_structp \fP\fIpng_ptr\fP\fB, double \fP\fIwhite_x\fP\fB, double \fP\fIwhite_y\fP\fB, double \fP\fIred_x\fP\fB, double \fP\fIred_y\fP\fB, double \fP\fIgreen_x\fP\fB, double \fP\fIgreen_y\fP\fB, double \fP\fIblue_x\fP\fB, double \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_cHRM_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwhite_x\fP\fB, png_uint_32 \fP\fIwhite_y\fP\fB, png_uint_32 \fP\fIred_x\fP\fB, png_uint_32 \fP\fIred_y\fP\fB, png_uint_32 \fP\fIgreen_x\fP\fB, png_uint_32 \fP\fIgreen_y\fP\fB, png_uint_32 \fP\fIblue_x\fP\fB, png_uint_32 \fIblue_y\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_data (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_filtered_row (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fIfiltered_row\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_tqfind_filter (png_structp \fP\fIpng_ptr\fP\fB, png_row_infop \fIrow_info\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_finish_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_gAMA (png_structp \fP\fIpng_ptr\fP\fB, double \fIfile_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_gAMA_fixed (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fIint_file_gamma\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_hIST (png_structp \fP\fIpng_ptr\fP\fB, png_uint_16p \fP\fIhist\fP\fB, int \fInum_hist\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_iCCP (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIname\fP\fB, int \fP\fIcompression_type\fP\fB, png_charp \fP\fIprofile\fP\fB, int \fIproflen\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_IDAT (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fIdata\fP\fB, png_size_t \fIlength\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_IEND (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_IHDR (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIwidth\fP\fB, png_uint_32 \fP\fIheight\fP\fB, int \fP\fIbit_depth\fP\fB, int \fP\fIcolor_type\fP\fB, int \fP\fIcompression_type\fP\fB, int \fP\fIfilter_type\fP\fB, int \fIinterlace_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_iTXt (png_structp \fP\fIpng_ptr\fP\fB, int \fP\fIcompression\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fIlang\fP\fB, png_charp \fP\fItranslated_key\fP\fB, png_charp \fItext)\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_oFFs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_offset\fP\fB, png_uint_32 \fP\fIy_offset\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_pCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIpurpose\fP\fB, png_int_32 \fP\fIX0\fP\fB, png_int_32 \fP\fIX1\fP\fB, int \fP\fItype\fP\fB, int \fP\fInparams\fP\fB, png_charp \fP\fIunits\fP\fB, png_charpp \fIparams\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_pHYs (png_structp \fP\fIpng_ptr\fP\fB, png_uint_32 \fP\fIx_pixels_per_unit\fP\fB, png_uint_32 \fP\fIy_pixels_per_unit\fP\fB, int \fIunit_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_PLTE (png_structp \fP\fIpng_ptr\fP\fB, png_colorp \fP\fIpalette\fP\fB, png_uint_32 \fInum_pal\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sBIT (png_structp \fP\fIpng_ptr\fP\fB, png_color_8p \fP\fIsbit\fP\fB, int \fIcolor_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sCAL (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, double \fP\fIwidth\fP\fB, double \fIheight\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sCAL_s (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIunit\fP\fB, png_charp \fP\fIwidth\fP\fB, png_charp \fIheight\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sig (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sRGB (png_structp \fP\fIpng_ptr\fP\fB, int \fIintent\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_sPLT (png_structp \fP\fIpng_ptr\fP\fB, png_spalette_p \fIpalette\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_start_row (png_structp \fIpng_ptr\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_tEXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fItext_len\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_tIME (png_structp \fP\fIpng_ptr\fP\fB, png_timep \fImod_time\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_tRNS (png_structp \fP\fIpng_ptr\fP\fB, png_bytep \fP\fItrans\fP\fB, png_color_16p \fP\fIvalues\fP\fB, int \fP\fInumber\fP\fB, int \fIcolor_type\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_write_zTXt (png_structp \fP\fIpng_ptr\fP\fB, png_charp \fP\fIkey\fP\fB, png_charp \fP\fItext\fP\fB, png_size_t \fP\fItext_len\fP\fB, int \fIcompression\fP\fB);\fP
+
+\fI\fB
+
+\fBvoidpf png_zalloc (voidpf \fP\fIpng_ptr\fP\fB, uInt \fP\fIitems\fP\fB, uInt \fIsize\fP\fB);\fP
+
+\fI\fB
+
+\fBvoid png_zfree (voidpf \fP\fIpng_ptr\fP\fB, voidpf \fIptr\fP\fB);\fP
+
+\fI\fB
+
+.SH DESCRIPTION
+The functions listed above are used privately by libpng
+and are not recommended for use by applications. They are
+not "exported" to applications using shared libraries. They
+are listed alphabetically here as an aid to libpng maintainers.
+See png.h for more information on these functions.
+
+.SH SEE ALSO
+libpng(3), png(5)
+.SH AUTHOR
+Glenn Randers-Pehrson
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/png.5 b/tqtinterface/qt4/src/3rdparty/libpng/png.5
new file mode 100644
index 0000000..a96de03
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/png.5
@@ -0,0 +1,60 @@
+.TH PNG 5 "October 3, 2002"
+.SH NAME
+png \- Portable Network Graphics (PNG) format
+.SH DESCRIPTION
+PNG (Portable Network Graphics) is an extensible file format for the
+lossless, portable, well-compressed storage of raster images. PNG provides
+a patent-free tqreplacement for GIF and can also tqreplace many
+common uses of TIFF. Indexed-color, grayscale, and truecolor images are
+supported, plus an optional alpha channel. Sample depths range from
+1 to 16 bits.
+.br
+
+PNG is designed to work well in online viewing applications, such as the
+World Wide Web, so it is fully streamable with a progressive display
+option. PNG is robust, providing both full file integrity checking and
+fast, simple detection of common transmission errors. Also, PNG can store
+gamma and chromaticity data for improved color matching on heterogeneous
+platforms.
+
+.SH "SEE ALSO"
+.IR libpng(3), zlib(3), deflate(5), and zlib(5)
+.LP
+PNG 1.2 specification, July 1999:
+.IP
+.br
+http://www.libpng.org/pub/png
+.br
+or ftp://ftp.uu.net/graphics/png/documents
+.LP
+PNG 1.0 specification, October 1996:
+.IP
+.br
+RFC 2083
+.IP
+.br
+ftp://ds.internic.net/rfc/rfc2083.txt
+.br
+or (as a W3C Recommendation) at
+.br
+http://www.w3.org/TR/REC-png.html
+.SH AUTHORS
+This man page: Glenn Randers-Pehrson
+.LP
+Portable Network Graphics (PNG) Specification Version 1.2 (July 8, 1999):
+Glenn Randers-Pehrson and others (png-list@ccrc.wustl.edu).
+.LP
+Portable Network Graphics (PNG) Specification Version 1.0 (October 1, 1996):
+Thomas Boutell and others (png-list@ccrc.wustl.edu).
+.LP
+
+
+.SH COPYRIGHT NOTICE
+The PNG-1.2 specification is copyright (c) 1999 Glenn Randers-Pehrson.
+See the specification for conditions of use and distribution.
+.LP
+The PNG-1.0 specification is copyright (c) 1996 Massachusetts Institute of
+Technology. See the specification for conditions of use and distribution.
+.LP
+.\" end of man page
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/png.c b/tqtinterface/qt4/src/3rdparty/libpng/png.c
new file mode 100644
index 0000000..d3370d8
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/png.c
@@ -0,0 +1,805 @@
+
+/* png.c - location for general purpose libpng functions
+ *
+ * libpng version 1.2.5 - October 3, 2002
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ */
+
+#define PNG_INTERNAL
+#define PNG_NO_EXTERN
+#include "png.h"
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef version_1_2_5 Your_png_h_is_not_version_1_2_5;
+
+/* Version information for C files. This had better match the version
+ * string defined in png.h. */
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* png_libpng_ver was changed to a function in version 1.0.5c */
+const char png_libpng_ver[18] = "1.2.5";
+
+/* png_sig was changed to a function in version 1.0.5c */
+/* Place to hold the signature string for a PNG file. */
+const png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+
+/* Invoke global declarations for constant strings for known chunk types */
+PNG_IHDR;
+PNG_IDAT;
+PNG_IEND;
+PNG_PLTE;
+PNG_bKGD;
+PNG_cHRM;
+PNG_gAMA;
+PNG_hIST;
+PNG_iCCP;
+PNG_iTXt;
+PNG_oFFs;
+PNG_pCAL;
+PNG_sCAL;
+PNG_pHYs;
+PNG_sBIT;
+PNG_sPLT;
+PNG_sRGB;
+PNG_tEXt;
+PNG_tIME;
+PNG_tRNS;
+PNG_zTXt;
+
+/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+/* start of interlace block */
+const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+/* offset to next interlace block */
+const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+/* start of interlace block in the y direction */
+const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+/* offset to next interlace block in the y direction */
+const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+/* width of interlace block (used in assembler routines only) */
+#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
+#endif
+
+/* Height of interlace block. This is not currently used - if you need
+ * it, uncomment it here and in png.h
+const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+*/
+
+/* Mask to determine which pixels are valid in a pass */
+const int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+
+/* Mask to determine which pixels to overwrite while displaying */
+const int FARDATA png_pass_dsp_mask[]
+ = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+
+#endif
+
+/* Tells libpng that we have already handled the first "num_bytes" bytes
+ * of the PNG file signature. If the PNG data is embedded into another
+ * stream we can set num_bytes = 8 so that libpng will not attempt to read
+ * or write any of the magic bytes before it starts on the IHDR.
+ */
+
+void PNGAPI
+png_set_sig_bytes(png_structp png_ptr, int num_bytes)
+{
+ png_debug(1, "in png_set_sig_bytes\n");
+ if (num_bytes > 8)
+ png_error(png_ptr, "Too many bytes for PNG signature.");
+
+ png_ptr->sig_bytes = (png_byte)(num_bytes < 0 ? 0 : num_bytes);
+}
+
+/* Checks whether the supplied bytes match the PNG signature. We allow
+ * checking less than the full 8-byte signature so that those apps that
+ * already read the first few bytes of a file to determine the file type
+ * can simply check the remaining bytes for extra assurance. Returns
+ * an integer less than, equal to, or greater than zero if sig is found,
+ * respectively, to be less than, to match, or be greater than the correct
+ * PNG signature (this is the same behaviour as strcmp, memcmp, etc).
+ */
+int PNGAPI
+png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
+{
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+ if (num_to_check > 8)
+ num_to_check = 8;
+ else if (num_to_check < 1)
+ return (0);
+
+ if (start > 7)
+ return (0);
+
+ if (start + num_to_check > 8)
+ num_to_check = 8 - start;
+
+ return ((int)(png_memcmp(&sig[start], &png_signature[start], num_to_check)));
+}
+
+/* (Obsolete) function to check signature bytes. It does not allow one
+ * to check a partial signature. This function might be removed in the
+ * future - use png_sig_cmp(). Returns true (nonzero) if the file is a PNG.
+ */
+int PNGAPI
+png_check_sig(png_bytep sig, int num)
+{
+ return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
+}
+
+/* Function to allocate memory for zlib and clear it to 0. */
+#ifdef PNG_1_0_X
+voidpf PNGAPI
+#else
+voidpf /* private */
+#endif
+png_zalloc(voidpf png_ptr, uInt items, uInt size)
+{
+ png_uint_32 num_bytes = (png_uint_32)items * size;
+ png_voidp ptr;
+ png_structp p=(png_structp)png_ptr;
+ png_uint_32 save_flags=p->flags;
+
+ p->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
+ ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
+ p->flags=save_flags;
+
+#ifndef PNG_NO_ZALLOC_ZERO
+ if (ptr == NULL)
+ return ((voidpf)ptr);
+
+ if (num_bytes > (png_uint_32)0x8000L)
+ {
+ png_memset(ptr, 0, (png_size_t)0x8000L);
+ png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
+ (png_size_t)(num_bytes - (png_uint_32)0x8000L));
+ }
+ else
+ {
+ png_memset(ptr, 0, (png_size_t)num_bytes);
+ }
+#endif
+ return ((voidpf)ptr);
+}
+
+/* function to free memory for zlib */
+#ifdef PNG_1_0_X
+void PNGAPI
+#else
+void /* private */
+#endif
+png_zfree(voidpf png_ptr, voidpf ptr)
+{
+ png_free((png_structp)png_ptr, (png_voidp)ptr);
+}
+
+/* Reset the CRC variable to 32 bits of 1's. Care must be taken
+ * in case CRC is > 32 bits to leave the top bits 0.
+ */
+void /* PRIVATE */
+png_reset_crc(png_structp png_ptr)
+{
+ png_ptr->crc = crc32(0, Z_NULL, 0);
+}
+
+/* Calculate the CRC over a section of data. We can only pass as
+ * much data to this routine as the largest single buffer size. We
+ * also check that this data will actually be used before going to the
+ * trouble of calculating it.
+ */
+void /* PRIVATE */
+png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
+{
+ int need_crc = 1;
+
+ if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+ else /* critical */
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+ need_crc = 0;
+ }
+
+ if (need_crc)
+ png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
+}
+
+/* Allocate the memory for an info_struct for the application. We don't
+ * really need the png_ptr, but it could potentially be useful in the
+ * future. This should be used in favour of malloc(sizeof(png_info))
+ * and png_info_init() so that applications that want to use a shared
+ * libpng don't have to be recompiled if png_info changes size.
+ */
+png_infop PNGAPI
+png_create_info_struct(png_structp png_ptr)
+{
+ png_infop info_ptr;
+
+ png_debug(1, "in png_create_info_struct\n");
+ if(png_ptr == NULL) return (NULL);
+#ifdef PNG_USER_MEM_SUPPORTED
+ info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
+ png_ptr->malloc_fn, png_ptr->mem_ptr);
+#else
+ info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
+#endif
+ if (info_ptr != NULL)
+ png_info_init_3(&info_ptr, sizeof(png_info));
+
+ return (info_ptr);
+}
+
+/* This function frees the memory associated with a single info struct.
+ * Normally, one would use either png_destroy_read_struct() or
+ * png_destroy_write_struct() to free an info struct, but this may be
+ * useful for some applications.
+ */
+void PNGAPI
+png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
+{
+ png_infop info_ptr = NULL;
+
+ png_debug(1, "in png_destroy_info_struct\n");
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (info_ptr != NULL)
+ {
+ png_info_destroy(png_ptr, info_ptr);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn,
+ png_ptr->mem_ptr);
+#else
+ png_destroy_struct((png_voidp)info_ptr);
+#endif
+ *info_ptr_ptr = NULL;
+ }
+}
+
+/* Initialize the info structure. This is now an internal function (0.89)
+ * and applications using it are urged to use png_create_info_struct()
+ * instead.
+ */
+#undef png_info_init
+void PNGAPI
+png_info_init(png_infop info_ptr)
+{
+ /* We only come here via pre-1.0.12-compiled applications */
+ png_info_init_3(&info_ptr, 0);
+}
+
+void PNGAPI
+png_info_init_3(png_infopp ptr_ptr, png_size_t png_info_struct_size)
+{
+ png_infop info_ptr = *ptr_ptr;
+
+ png_debug(1, "in png_info_init_3\n");
+
+ if(sizeof(png_info) > png_info_struct_size)
+ {
+ png_destroy_struct(info_ptr);
+ info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO);
+ *ptr_ptr = info_ptr;
+ }
+
+ /* set everything to 0 */
+ png_memset(info_ptr, 0, sizeof (png_info));
+}
+
+#ifdef PNG_FREE_ME_SUPPORTED
+void PNGAPI
+png_data_freer(png_structp png_ptr, png_infop info_ptr,
+ int freer, png_uint_32 tqmask)
+{
+ png_debug(1, "in png_data_freer\n");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+ if(freer == PNG_DESTROY_WILL_FREE_DATA)
+ info_ptr->free_me |= tqmask;
+ else if(freer == PNG_USER_WILL_FREE_DATA)
+ info_ptr->free_me &= ~tqmask;
+ else
+ png_warning(png_ptr,
+ "Unknown freer parameter in png_data_freer.");
+}
+#endif
+
+void PNGAPI
+png_free_data(png_structp png_ptr, png_infop info_ptr, png_uint_32 tqmask,
+ int num)
+{
+ png_debug(1, "in png_free_data\n");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+#if defined(PNG_TEXT_SUPPORTED)
+/* free text item num or (if num == -1) all text items */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((tqmask & PNG_FREE_TEXT) & info_ptr->free_me)
+#else
+if (tqmask & PNG_FREE_TEXT)
+#endif
+{
+ if (num != -1)
+ {
+ if (info_ptr->text && info_ptr->text[num].key)
+ {
+ png_free(png_ptr, info_ptr->text[num].key);
+ info_ptr->text[num].key = NULL;
+ }
+ }
+ else
+ {
+ int i;
+ for (i = 0; i < info_ptr->num_text; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, i);
+ png_free(png_ptr, info_ptr->text);
+ info_ptr->text = NULL;
+ info_ptr->num_text=0;
+ }
+}
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+/* free any tRNS entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((tqmask & PNG_FREE_TRNS) & info_ptr->free_me)
+#else
+if ((tqmask & PNG_FREE_TRNS) && (png_ptr->flags & PNG_FLAG_FREE_TRNS))
+#endif
+{
+ png_free(png_ptr, info_ptr->trans);
+ info_ptr->valid &= ~PNG_INFO_tRNS;
+#ifndef PNG_FREE_ME_SUPPORTED
+ png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+ info_ptr->trans = NULL;
+}
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+/* free any sCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((tqmask & PNG_FREE_SCAL) & info_ptr->free_me)
+#else
+if (tqmask & PNG_FREE_SCAL)
+#endif
+{
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, info_ptr->scal_s_width);
+ png_free(png_ptr, info_ptr->scal_s_height);
+ info_ptr->scal_s_width = NULL;
+ info_ptr->scal_s_height = NULL;
+#endif
+ info_ptr->valid &= ~PNG_INFO_sCAL;
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+/* free any pCAL entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((tqmask & PNG_FREE_PCAL) & info_ptr->free_me)
+#else
+if (tqmask & PNG_FREE_PCAL)
+#endif
+{
+ png_free(png_ptr, info_ptr->pcal_purpose);
+ png_free(png_ptr, info_ptr->pcal_units);
+ info_ptr->pcal_purpose = NULL;
+ info_ptr->pcal_units = NULL;
+ if (info_ptr->pcal_params != NULL)
+ {
+ int i;
+ for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
+ {
+ png_free(png_ptr, info_ptr->pcal_params[i]);
+ info_ptr->pcal_params[i]=NULL;
+ }
+ png_free(png_ptr, info_ptr->pcal_params);
+ info_ptr->pcal_params = NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_pCAL;
+}
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+/* free any iCCP entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((tqmask & PNG_FREE_ICCP) & info_ptr->free_me)
+#else
+if (tqmask & PNG_FREE_ICCP)
+#endif
+{
+ png_free(png_ptr, info_ptr->iccp_name);
+ png_free(png_ptr, info_ptr->iccp_profile);
+ info_ptr->iccp_name = NULL;
+ info_ptr->iccp_profile = NULL;
+ info_ptr->valid &= ~PNG_INFO_iCCP;
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+/* free a given sPLT entry, or (if num == -1) all sPLT entries */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((tqmask & PNG_FREE_SPLT) & info_ptr->free_me)
+#else
+if (tqmask & PNG_FREE_SPLT)
+#endif
+{
+ if (num != -1)
+ {
+ if(info_ptr->splt_palettes)
+ {
+ png_free(png_ptr, info_ptr->splt_palettes[num].name);
+ png_free(png_ptr, info_ptr->splt_palettes[num].entries);
+ info_ptr->splt_palettes[num].name = NULL;
+ info_ptr->splt_palettes[num].entries = NULL;
+ }
+ }
+ else
+ {
+ if(info_ptr->splt_palettes_num)
+ {
+ int i;
+ for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_SPLT, i);
+
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes = NULL;
+ info_ptr->splt_palettes_num = 0;
+ }
+ info_ptr->valid &= ~PNG_INFO_sPLT;
+ }
+}
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((tqmask & PNG_FREE_UNKN) & info_ptr->free_me)
+#else
+if (tqmask & PNG_FREE_UNKN)
+#endif
+{
+ if (num != -1)
+ {
+ if(info_ptr->unknown_chunks)
+ {
+ png_free(png_ptr, info_ptr->unknown_chunks[num].data);
+ info_ptr->unknown_chunks[num].data = NULL;
+ }
+ }
+ else
+ {
+ int i;
+
+ if(info_ptr->unknown_chunks_num)
+ {
+ for (i = 0; i < (int)info_ptr->unknown_chunks_num; i++)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_UNKN, i);
+
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks = NULL;
+ info_ptr->unknown_chunks_num = 0;
+ }
+ }
+}
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+/* free any hIST entry */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((tqmask & PNG_FREE_HIST) & info_ptr->free_me)
+#else
+if ((tqmask & PNG_FREE_HIST) && (png_ptr->flags & PNG_FLAG_FREE_HIST))
+#endif
+{
+ png_free(png_ptr, info_ptr->hist);
+ info_ptr->hist = NULL;
+ info_ptr->valid &= ~PNG_INFO_hIST;
+#ifndef PNG_FREE_ME_SUPPORTED
+ png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
+}
+#endif
+
+/* free any PLTE entry that was internally allocated */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((tqmask & PNG_FREE_PLTE) & info_ptr->free_me)
+#else
+if ((tqmask & PNG_FREE_PLTE) && (png_ptr->flags & PNG_FLAG_FREE_PLTE))
+#endif
+{
+ png_zfree(png_ptr, info_ptr->palette);
+ info_ptr->palette = NULL;
+ info_ptr->valid &= ~PNG_INFO_PLTE;
+#ifndef PNG_FREE_ME_SUPPORTED
+ png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+ info_ptr->num_palette = 0;
+}
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* free any image bits attached to the info structure */
+#ifdef PNG_FREE_ME_SUPPORTED
+if ((tqmask & PNG_FREE_ROWS) & info_ptr->free_me)
+#else
+if (tqmask & PNG_FREE_ROWS)
+#endif
+{
+ if(info_ptr->row_pointers)
+ {
+ int row;
+ for (row = 0; row < (int)info_ptr->height; row++)
+ {
+ png_free(png_ptr, info_ptr->row_pointers[row]);
+ info_ptr->row_pointers[row]=NULL;
+ }
+ png_free(png_ptr, info_ptr->row_pointers);
+ info_ptr->row_pointers=NULL;
+ }
+ info_ptr->valid &= ~PNG_INFO_IDAT;
+}
+#endif
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ if(num == -1)
+ info_ptr->free_me &= ~tqmask;
+ else
+ info_ptr->free_me &= ~(tqmask & ~PNG_FREE_MUL);
+#endif
+}
+
+/* This is an internal routine to free any memory that the info struct is
+ * pointing to before re-using it or freeing the struct itself. Recall
+ * that png_free() checks for NULL pointers for us.
+ */
+void /* PRIVATE */
+png_info_destroy(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_info_destroy\n");
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ if (png_ptr->num_chunk_list)
+ {
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list=NULL;
+ png_ptr->num_chunk_list=0;
+ }
+#endif
+
+ png_info_init_3(&info_ptr, sizeof(png_info));
+}
+
+/* This function returns a pointer to the io_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy() or png_read_destroy() are called.
+ */
+png_voidp PNGAPI
+png_get_io_ptr(png_structp png_ptr)
+{
+ return (png_ptr->io_ptr);
+}
+
+#if !defined(PNG_NO_STDIO)
+/* Initialize the default input/output functions for the PNG file. If you
+ * use your own read or write routines, you can call either png_set_read_fn()
+ * or png_set_write_fn() instead of png_init_io(). If you have defined
+ * PNG_NO_STDIO, you must use a function of your own because "FILE *" isn't
+ * necessarily available.
+ */
+void PNGAPI
+png_init_io(png_structp png_ptr, png_FILE_p fp)
+{
+ png_debug(1, "in png_init_io\n");
+ png_ptr->io_ptr = (png_voidp)fp;
+}
+#endif
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+/* Convert the supplied time into an RFC 1123 string suitable for use in
+ * a "Creation Time" or other text-based time string.
+ */
+png_charp PNGAPI
+png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
+{
+ static PNG_CONST char short_months[12][4] =
+ {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+ if (png_ptr->time_buffer == NULL)
+ {
+ png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
+ sizeof(char)));
+ }
+
+#if defined(_WIN32_WCE)
+ {
+ wchar_t time_buf[29];
+ wsprintf(time_buf, TEXT("%d %S %d %02d:%02d:%02d +0000"),
+ ptime->day % 32, short_months[(ptime->month - 1) % 12],
+ ptime->year, ptime->hour % 24, ptime->minute % 60,
+ ptime->second % 61);
+ WideCharToMultiByte(CP_ACP, 0, time_buf, -1, png_ptr->time_buffer, 29,
+ NULL, NULL);
+ }
+#else
+#ifdef USE_FAR_KEYWORD
+ {
+ char near_time_buf[29];
+ sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000",
+ ptime->day % 32, short_months[(ptime->month - 1) % 12],
+ ptime->year, ptime->hour % 24, ptime->minute % 60,
+ ptime->second % 61);
+ png_memcpy(png_ptr->time_buffer, near_time_buf,
+ 29*sizeof(char));
+ }
+#else
+ sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000",
+ ptime->day % 32, short_months[(ptime->month - 1) % 12],
+ ptime->year, ptime->hour % 24, ptime->minute % 60,
+ ptime->second % 61);
+#endif
+#endif /* _WIN32_WCE */
+ return ((png_charp)png_ptr->time_buffer);
+}
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+
+#if 0
+/* Signature string for a PNG file. */
+png_bytep PNGAPI
+png_sig_bytes(void)
+{
+ return ((png_bytep)"\211\120\116\107\015\012\032\012");
+}
+#endif
+
+png_charp PNGAPI
+png_get_copyright(png_structp png_ptr)
+{
+ if (png_ptr != NULL || png_ptr == NULL) /* silence compiler warning */
+ return ((png_charp) "\n libpng version 1.2.5 - October 3, 2002\n\
+ Copyright (c) 1998-2002 Glenn Randers-Pehrson\n\
+ Copyright (c) 1996-1997 Andreas Dilger\n\
+ Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.\n");
+ return ((png_charp) "");
+}
+
+/* The following return the library version as a short string in the
+ * format 1.0.0 through 99.99.99zz. To get the version of *.h files used
+ * with your application, print out PNG_LIBPNG_VER_STRING, which is defined
+ * in png.h.
+ */
+
+png_charp PNGAPI
+png_get_libpng_ver(png_structp png_ptr)
+{
+ /* Version of *.c files used when building libpng */
+ if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
+ return((png_charp) "1.2.5");
+ return((png_charp) "1.2.5");
+}
+
+png_charp PNGAPI
+png_get_header_ver(png_structp png_ptr)
+{
+ /* Version of *.h files used when building libpng */
+ if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
+ return((png_charp) PNG_LIBPNG_VER_STRING);
+ return((png_charp) PNG_LIBPNG_VER_STRING);
+}
+
+png_charp PNGAPI
+png_get_header_version(png_structp png_ptr)
+{
+ /* Returns longer string containing both version and date */
+ if(png_ptr != NULL) /* silence compiler warning about unused png_ptr */
+ return((png_charp) PNG_HEADER_VERSION_STRING);
+ return((png_charp) PNG_HEADER_VERSION_STRING);
+}
+
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+int PNGAPI
+png_handle_as_unknown(png_structp png_ptr, png_bytep chunk_name)
+{
+ /* check chunk_name and return "keep" value if it's on the list, else 0 */
+ int i;
+ png_bytep p;
+ if((png_ptr == NULL && chunk_name == NULL) || png_ptr->num_chunk_list<=0)
+ return 0;
+ p=png_ptr->chunk_list+png_ptr->num_chunk_list*5-5;
+ for (i = png_ptr->num_chunk_list; i; i--, p-=5)
+ if (!png_memcmp(chunk_name, p, 4))
+ return ((int)*(p+4));
+ return 0;
+}
+#endif
+
+/* This function, added to libpng-1.0.6g, is untested. */
+int PNGAPI
+png_reset_zstream(png_structp png_ptr)
+{
+ return (inflateReset(&png_ptr->zstream));
+}
+
+/* This function was added to libpng-1.0.7 */
+png_uint_32 PNGAPI
+png_access_version_number(void)
+{
+ /* Version of *.c files used when building libpng */
+ return((png_uint_32) 10205L);
+}
+
+
+#if !defined(PNG_1_0_X)
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+ /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */
+/* this INTERNAL function was added to libpng 1.2.0 */
+void /* PRIVATE */
+png_init_mmx_flags (png_structp png_ptr)
+{
+ png_ptr->mmx_rowbytes_threshold = 0;
+ png_ptr->mmx_bitdepth_threshold = 0;
+
+# if (defined(PNG_USE_PNGVCRD) || defined(PNG_USE_PNGGCCRD))
+
+ png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_COMPILED;
+
+ if (png_mmx_support() > 0) {
+ png_ptr->asm_flags |= PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
+# ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+ | PNG_ASM_FLAG_MMX_READ_COMBINE_ROW
+# endif
+# ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
+ | PNG_ASM_FLAG_MMX_READ_INTERLACE
+# endif
+# ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+ ;
+# else
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB
+ | PNG_ASM_FLAG_MMX_READ_FILTER_UP
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+
+ png_ptr->mmx_rowbytes_threshold = PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT;
+ png_ptr->mmx_bitdepth_threshold = PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT;
+# endif
+ } else {
+ png_ptr->asm_flags &= ~( PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU
+ | PNG_MMX_READ_FLAGS
+ | PNG_MMX_WRITE_FLAGS );
+ }
+
+# else /* !((PNGVCRD || PNGGCCRD) && PNG_ASSEMBLER_CODE_SUPPORTED)) */
+
+ /* clear all MMX flags; no support is compiled in */
+ png_ptr->asm_flags &= ~( PNG_MMX_FLAGS );
+
+# endif /* ?(PNGVCRD || PNGGCCRD) */
+}
+
+#endif /* !(PNG_ASSEMBLER_CODE_SUPPORTED) */
+
+/* this function was added to libpng 1.2.0 */
+#if !defined(PNG_USE_PNGGCCRD) && \
+ !(defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD))
+int PNGAPI
+png_mmx_support(void)
+{
+ return -1;
+}
+#endif
+#endif /* PNG_1_0_X */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/png.h b/tqtinterface/qt4/src/3rdparty/libpng/png.h
new file mode 100644
index 0000000..d57b248
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/png.h
@@ -0,0 +1,3289 @@
+/* png.h - header file for PNG reference library
+ *
+ * libpng version 1.2.5 - October 3, 2002
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * Authors and maintainers:
+ * libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
+ * libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
+ * libpng versions 0.97, January 1998, through 1.2.5 - October 3, 2002: Glenn
+ * See also "Contributing Authors", below.
+ *
+ * Note about libpng version numbers:
+ *
+ * Due to various miscommunications, unforeseen code incompatibilities
+ * and occasional factors outside the authors' control, version numbering
+ * on the library has not always been consistent and straightforward.
+ * The following table summarizes matters since version 0.89c, which was
+ * the first widely used release:
+ *
+ * source png.h png.h shared-lib
+ * version string int version
+ * ------- ------ ----- ----------
+ * 0.89c "1.0 beta 3" 0.89 89 1.0.89
+ * 0.90 "1.0 beta 4" 0.90 90 0.90 [should have been 2.0.90]
+ * 0.95 "1.0 beta 5" 0.95 95 0.95 [should have been 2.0.95]
+ * 0.96 "1.0 beta 6" 0.96 96 0.96 [should have been 2.0.96]
+ * 0.97b "1.00.97 beta 7" 1.00.97 97 1.0.1 [should have been 2.0.97]
+ * 0.97c 0.97 97 2.0.97
+ * 0.98 0.98 98 2.0.98
+ * 0.99 0.99 98 2.0.99
+ * 0.99a-m 0.99 99 2.0.99
+ * 1.00 1.00 100 2.1.0 [100 should be 10000]
+ * 1.0.0 (from here on, the 100 2.1.0 [100 should be 10000]
+ * 1.0.1 png.h string is 10001 2.1.0
+ * 1.0.1a-e identical to the 10002 from here on, the shared library
+ * 1.0.2 source version) 10002 is 2.V where V is the source code
+ * 1.0.2a-b 10003 version, except as noted.
+ * 1.0.3 10003
+ * 1.0.3a-d 10004
+ * 1.0.4 10004
+ * 1.0.4a-f 10005
+ * 1.0.5 (+ 2 patches) 10005
+ * 1.0.5a-d 10006
+ * 1.0.5e-r 10100 (not source compatible)
+ * 1.0.5s-v 10006 (not binary compatible)
+ * 1.0.6 (+ 3 patches) 10006 (still binary incompatible)
+ * 1.0.6d-f 10007 (still binary incompatible)
+ * 1.0.6g 10007
+ * 1.0.6h 10007 10.6h (testing xy.z so-numbering)
+ * 1.0.6i 10007 10.6i
+ * 1.0.6j 10007 2.1.0.6j (incompatible with 1.0.0)
+ * 1.0.7beta11-14 DLLNUM 10007 2.1.0.7beta11-14 (binary compatible)
+ * 1.0.7beta15-18 1 10007 2.1.0.7beta15-18 (binary compatible)
+ * 1.0.7rc1-2 1 10007 2.1.0.7rc1-2 (binary compatible)
+ * 1.0.7 1 10007 (still compatible)
+ * 1.0.8beta1-4 1 10008 2.1.0.8beta1-4
+ * 1.0.8rc1 1 10008 2.1.0.8rc1
+ * 1.0.8 1 10008 2.1.0.8
+ * 1.0.9beta1-6 1 10009 2.1.0.9beta1-6
+ * 1.0.9rc1 1 10009 2.1.0.9rc1
+ * 1.0.9beta7-10 1 10009 2.1.0.9beta7-10
+ * 1.0.9rc2 1 10009 2.1.0.9rc2
+ * 1.0.9 1 10009 2.1.0.9
+ * 1.0.10beta1 1 10010 2.1.0.10beta1
+ * 1.0.10rc1 1 10010 2.1.0.10rc1
+ * 1.0.10 1 10010 2.1.0.10
+ * 1.0.11beta1-3 1 10011 2.1.0.11beta1-3
+ * 1.0.11rc1 1 10011 2.1.0.11rc1
+ * 1.0.11 1 10011 2.1.0.11
+ * 1.0.12beta1-2 2 10012 2.1.0.12beta1-2
+ * 1.0.12rc1 2 10012 2.1.0.12rc1
+ * 1.0.12 2 10012 2.1.0.12
+ * 1.1.0a-f - 10100 2.1.1.0a-f (branch abandoned)
+ * 1.2.0beta1-2 2 10200 2.1.2.0beta1-2
+ * 1.2.0beta3-5 3 10200 3.1.2.0beta3-5
+ * 1.2.0rc1 3 10200 3.1.2.0rc1
+ * 1.2.0 3 10200 3.1.2.0
+ * 1.2.1beta1-4 3 10201 3.1.2.1beta1-4
+ * 1.2.1rc1-2 3 10201 3.1.2.1rc1-2
+ * 1.2.1 3 10201 3.1.2.1
+ * 1.2.2beta1-6 12 10202 12.so.0.1.2.2beta1-6
+ * 1.0.13beta1 10 10013 10.so.0.1.0.13beta1
+ * 1.0.13rc1 10 10013 10.so.0.1.0.13rc1
+ * 1.2.2rc1 12 10202 12.so.0.1.2.2rc1
+ * 1.0.13 10 10013 10.so.0.1.0.13
+ * 1.2.2 12 10202 12.so.0.1.2.2
+ * 1.2.3rc1-6 12 10203 12.so.0.1.2.3rc1-6
+ * 1.2.3 12 10203 12.so.0.1.2.3
+ * 1.2.4beta1-3 13 10204 12.so.0.1.2.4beta1-3
+ * 1.0.14rc1 13 10014 10.so.0.1.0.14rc1
+ * 1.2.4rc1 13 10204 12.so.0.1.2.4rc1
+ * 1.0.14 10 10014 10.so.0.1.0.14
+ * 1.2.4 13 10204 12.so.0.1.2.4
+ * 1.2.5beta1-2 13 10205 12.so.0.1.2.5beta1-2
+ * 1.0.15rc1-3 10 10015 10.so.0.1.0.15rc1-3
+ * 1.2.5rc1-3 13 10205 12.so.0.1.2.5rc1-3
+ * 1.0.15 10 10015 10.so.0.1.0.15
+ * 1.2.5 13 10205 12.so.0.1.2.5
+ *
+ * Henceforth the source version will match the shared-library major
+ * and minor numbers; the shared-library major version number will be
+ * used for changes in backward compatibility, as it is intended. The
+ * PNG_LIBPNG_VER macro, which is not used within libpng but is available
+ * for applications, is an unsigned integer of the form xyyzz corresponding
+ * to the source version x.y.z (leading zeros in y and z). Beta versions
+ * were given the previous public release number plus a letter, until
+ * version 1.0.6j; from then on they were given the upcoming public
+ * release number plus "betaNN" or "rcN".
+ *
+ * Binary incompatibility exists only when applications make direct access
+ * to the info_ptr or png_ptr members through png.h, and the compiled
+ * application is loaded with a different version of the library.
+ *
+ * DLLNUM will change each time there are forward or backward changes
+ * in binary compatibility (e.g., when a new feature is added).
+ *
+ * See libpng.txt or libpng.3 for more information. The PNG specification
+ * is available as RFC 2083 <ftp://ftp.uu.net/graphics/png/documents/>
+ * and as a W3C Recommendation <http://www.w3.org/TR/REC.png.html>
+ */
+
+/*
+ * COPYRIGHT NOTICE, DISCLAIMER, and LICENSE:
+ *
+ * If you modify libpng you may insert additional notices immediately following
+ * this sentence.
+ *
+ * libpng versions 1.0.7, July 1, 2000, through 1.2.5, October 3, 2002, are
+ * Copyright (c) 2000-2002 Glenn Randers-Pehrson, and are
+ * distributed according to the same disclaimer and license as libpng-1.0.6
+ * with the following individuals added to the list of Contributing Authors
+ *
+ * Simon-Pierre Cadieux
+ * Eric S. Raymond
+ * Gilles Vollant
+ *
+ * and with the following additions to the disclaimer:
+ *
+ * There is no warranty against interference with your enjoyment of the
+ * library or against infringement. There is no warranty that our
+ * efforts or the library will fulfill any of your particular purposes
+ * or needs. This library is provided with all faults, and the entire
+ * risk of satisfactory quality, performance, accuracy, and effort is with
+ * the user.
+ *
+ * libpng versions 0.97, January 1998, through 1.0.6, March 20, 2000, are
+ * Copyright (c) 1998, 1999, 2000 Glenn Randers-Pehrson
+ * Distributed according to the same disclaimer and license as libpng-0.96,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * Tom Lane
+ * Glenn Randers-Pehrson
+ * Willem van Schaik
+ *
+ * libpng versions 0.89, June 1996, through 0.96, May 1997, are
+ * Copyright (c) 1996, 1997 Andreas Dilger
+ * Distributed according to the same disclaimer and license as libpng-0.88,
+ * with the following individuals added to the list of Contributing Authors:
+ *
+ * John Bowler
+ * Kevin Bracey
+ * Sam Bushell
+ * Magnus Holmgren
+ * Greg Roelofs
+ * Tom Tanner
+ *
+ * libpng versions 0.5, May 1995, through 0.88, January 1996, are
+ * Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
+ *
+ * For the purposes of this copyright and license, "Contributing Authors"
+ * is defined as the following set of individuals:
+ *
+ * Andreas Dilger
+ * Dave Martindale
+ * Guy Eric Schalnat
+ * Paul Schmidt
+ * Tim Wegner
+ *
+ * The PNG Reference Library is supplied "AS IS". The Contributing Authors
+ * and Group 42, Inc. disclaim all warranties, expressed or implied,
+ * including, without limitation, the warranties of merchantability and of
+ * fitness for any purpose. The Contributing Authors and Group 42, Inc.
+ * assume no liability for direct, indirect, incidental, special, exemplary,
+ * or consequential damages, which may result from the use of the PNG
+ * Reference Library, even if advised of the possibility of such damage.
+ *
+ * Permission is hereby granted to use, copy, modify, and distribute this
+ * source code, or portions hereof, for any purpose, without fee, subject
+ * to the following restrictions:
+ *
+ * 1. The origin of this source code must not be misrepresented.
+ *
+ * 2. Altered versions must be plainly marked as such and
+ * must not be misrepresented as being the original source.
+ *
+ * 3. This Copyright notice may not be removed or altered from
+ * any source or altered source distribution.
+ *
+ * The Contributing Authors and Group 42, Inc. specifically permit, without
+ * fee, and encourage the use of this source code as a component to
+ * supporting the PNG file format in commercial products. If you use this
+ * source code in a product, acknowledgment is not required but would be
+ * appreciated.
+ */
+
+/*
+ * A "png_get_copyright" function is available, for convenient use in "about"
+ * boxes and the like:
+ *
+ * printf("%s",png_get_copyright(NULL));
+ *
+ * Also, the PNG logo (in PNG format, of course) is supplied in the
+ * files "pngbar.png" and "pngbar.jpg (88x31) and "pngnow.png" (98x31).
+ */
+
+/*
+ * Libpng is OSI Certified Open Source Software. OSI Certified is a
+ * certification mark of the Open Source Initiative.
+ */
+
+/*
+ * The contributing authors would like to thank all those who helped
+ * with testing, bug fixes, and patience. This wouldn't have been
+ * possible without all of you.
+ *
+ * Thanks to Frank J. T. Wojcik for helping with the documentation.
+ */
+
+/*
+ * Y2K compliance in libpng:
+ * =========================
+ *
+ * October 3, 2002
+ *
+ * Since the PNG Development group is an ad-hoc body, we can't make
+ * an official declaration.
+ *
+ * This is your unofficial assurance that libpng from version 0.71 and
+ * upward through 1.2.5 are Y2K compliant. It is my belief that earlier
+ * versions were also Y2K compliant.
+ *
+ * Libpng only has three year fields. One is a 2-byte unsigned integer
+ * that will hold years up to 65535. The other two hold the date in text
+ * format, and will hold years up to 9999.
+ *
+ * The integer is
+ * "png_uint_16 year" in png_time_struct.
+ *
+ * The strings are
+ * "png_charp time_buffer" in png_struct and
+ * "near_time_buffer", which is a local character string in png.c.
+ *
+ * There are seven time-related functions:
+ * png.c: png_convert_to_rfc_1123() in png.c
+ * (formerly png_convert_to_rfc_1152() in error)
+ * png_convert_from_struct_tm() in pngwrite.c, called in pngwrite.c
+ * png_convert_from_time_t() in pngwrite.c
+ * png_get_tIME() in pngget.c
+ * png_handle_tIME() in pngrutil.c, called in pngread.c
+ * png_set_tIME() in pngset.c
+ * png_write_tIME() in pngwutil.c, called in pngwrite.c
+ *
+ * All handle dates properly in a Y2K environment. The
+ * png_convert_from_time_t() function calls gmtime() to convert from system
+ * clock time, which returns (year - 1900), which we properly convert to
+ * the full 4-digit year. There is a possibility that applications using
+ * libpng are not passing 4-digit years into the png_convert_to_rfc_1123()
+ * function, or that they are incorrectly passing only a 2-digit year
+ * instead of "year - 1900" into the png_convert_from_struct_tm() function,
+ * but this is not under our control. The libpng documentation has always
+ * stated that it works with 4-digit years, and the APIs have been
+ * documented as such.
+ *
+ * The tIME chunk itself is also Y2K compliant. It uses a 2-byte unsigned
+ * integer to hold the year, and can hold years as large as 65535.
+ *
+ * zlib, upon which libpng depends, is also Y2K compliant. It tqcontains
+ * no date-related code.
+ *
+ * Glenn Randers-Pehrson
+ * libpng maintainer
+ * PNG Development Group
+ */
+
+#ifndef PNG_H
+#define PNG_H
+
+/* This is not the place to learn how to use libpng. The file libpng.txt
+ * describes how to use libpng, and the file example.c summarizes it
+ * with some code on which to build. This file is useful for looking
+ * at the actual function definitions and structure components.
+ */
+
+/* Version information for png.h - this should match the version in png.c */
+#define PNG_LIBPNG_VER_STRING "1.2.5"
+
+#define PNG_LIBPNG_VER_SONUM 0
+#define PNG_LIBPNG_VER_DLLNUM %DLLNUM%
+
+/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
+#define PNG_LIBPNG_VER_MAJOR 1
+#define PNG_LIBPNG_VER_MINOR 2
+#define PNG_LIBPNG_VER_RELEASE 5
+/* This should match the numeric part of the final component of
+ * PNG_LIBPNG_VER_STRING, omitting any leading zero: */
+
+#define PNG_LIBPNG_VER_BUILD 0
+
+#define PNG_LIBPNG_BUILD_ALPHA 1
+#define PNG_LIBPNG_BUILD_BETA 2
+#define PNG_LIBPNG_BUILD_RC 3
+#define PNG_LIBPNG_BUILD_STABLE 4
+#define PNG_LIBPNG_BUILD_TYPEMASK 7
+#define PNG_LIBPNG_BUILD_PATCH 8 /* Can be OR'ed with STABLE only */
+#define PNG_LIBPNG_BUILD_TYPE 4
+
+/* Careful here. At one time, Guy wanted to use 082, but that would be octal.
+ * We must not include leading zeros.
+ * Versions 0.7 through 1.0.0 were in the range 0 to 100 here (only
+ * version 1.0.0 was mis-numbered 100 instead of 10000). From
+ * version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release */
+#define PNG_LIBPNG_VER 10205 /* 1.2.5 */
+
+#ifndef PNG_VERSION_INFO_ONLY
+
+/* include the compression library's header */
+#include "zlib.h"
+
+/* include all user configurable info, including optional assembler routines */
+#include "pngconf.h"
+
+/* Inhibit C++ name-mangling for libpng functions but not for system calls. */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* This file is arranged in several sections. The first section tqcontains
+ * structure and type definitions. The second section tqcontains the external
+ * library functions, while the third has the internal library functions,
+ * which applications aren't expected to use directly.
+ */
+
+#ifndef PNG_NO_TYPECAST_NULL
+#define int_p_NULL (int *)NULL
+#define png_bytep_NULL (png_bytep)NULL
+#define png_bytepp_NULL (png_bytepp)NULL
+#define png_doublep_NULL (png_doublep)NULL
+#define png_error_ptr_NULL (png_error_ptr)NULL
+#define png_flush_ptr_NULL (png_flush_ptr)NULL
+#define png_free_ptr_NULL (png_free_ptr)NULL
+#define png_infopp_NULL (png_infopp)NULL
+#define png_malloc_ptr_NULL (png_malloc_ptr)NULL
+#define png_read_status_ptr_NULL (png_read_status_ptr)NULL
+#define png_rw_ptr_NULL (png_rw_ptr)NULL
+#define png_structp_NULL (png_structp)NULL
+#define png_uint_16p_NULL (png_uint_16p)NULL
+#define png_voidp_NULL (png_voidp)NULL
+#define png_write_status_ptr_NULL (png_write_status_ptr)NULL
+#else
+#define int_p_NULL NULL
+#define png_bytep_NULL NULL
+#define png_bytepp_NULL NULL
+#define png_doublep_NULL NULL
+#define png_error_ptr_NULL NULL
+#define png_flush_ptr_NULL NULL
+#define png_free_ptr_NULL NULL
+#define png_infopp_NULL NULL
+#define png_malloc_ptr_NULL NULL
+#define png_read_status_ptr_NULL NULL
+#define png_rw_ptr_NULL NULL
+#define png_structp_NULL NULL
+#define png_uint_16p_NULL NULL
+#define png_voidp_NULL NULL
+#define png_write_status_ptr_NULL NULL
+#endif
+
+/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* Version information for C files, stored in png.c. This had better match
+ * the version above.
+ */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (const char) png_libpng_ver[18];
+ /* need room for 99.99.99beta99z */
+#else
+#define png_libpng_ver png_get_header_ver(NULL)
+#endif
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+/* This was removed in version 1.0.5c */
+/* Structures to facilitate easy interlacing. See png.c for more details */
+PNG_EXPORT_VAR (const int FARDATA) png_pass_start[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_inc[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_ystart[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_yinc[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_mask[7];
+PNG_EXPORT_VAR (const int FARDATA) png_pass_dsp_mask[7];
+#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+PNG_EXPORT_VAR (const int FARDATA) png_pass_width[7];
+#endif
+/* This isn't currently used. If you need it, see png.c for more details.
+PNG_EXPORT_VAR (const int FARDATA) png_pass_height[7];
+*/
+#endif
+
+#endif /* PNG_NO_EXTERN */
+
+/* Three color definitions. The order of the red, green, and blue, (and the
+ * exact size) is not important, although the size of the fields need to
+ * be png_byte or png_uint_16 (as defined below).
+ */
+typedef struct png_color_struct
+{
+ png_byte red;
+ png_byte green;
+ png_byte blue;
+} png_color;
+typedef png_color FAR * png_colorp;
+typedef png_color FAR * FAR * png_colorpp;
+
+typedef struct png_color_16_struct
+{
+ png_byte index; /* used for palette files */
+ png_uint_16 red; /* for use in red green blue files */
+ png_uint_16 green;
+ png_uint_16 blue;
+ png_uint_16 gray; /* for use in grayscale files */
+} png_color_16;
+typedef png_color_16 FAR * png_color_16p;
+typedef png_color_16 FAR * FAR * png_color_16pp;
+
+typedef struct png_color_8_struct
+{
+ png_byte red; /* for use in red green blue files */
+ png_byte green;
+ png_byte blue;
+ png_byte gray; /* for use in grayscale files */
+ png_byte alpha; /* for alpha channel files */
+} png_color_8;
+typedef png_color_8 FAR * png_color_8p;
+typedef png_color_8 FAR * FAR * png_color_8pp;
+
+/*
+ * The following two structures are used for the in-core representation
+ * of sPLT chunks.
+ */
+typedef struct png_sPLT_entry_struct
+{
+ png_uint_16 red;
+ png_uint_16 green;
+ png_uint_16 blue;
+ png_uint_16 alpha;
+ png_uint_16 frequency;
+} png_sPLT_entry;
+typedef png_sPLT_entry FAR * png_sPLT_entryp;
+typedef png_sPLT_entry FAR * FAR * png_sPLT_entrypp;
+
+/* When the depth of the sPLT palette is 8 bits, the color and alpha samples
+ * occupy the LSB of their respective members, and the MSB of each member
+ * is zero-filled. The frequency member always occupies the full 16 bits.
+ */
+
+typedef struct png_sPLT_struct
+{
+ png_charp name; /* palette name */
+ png_byte depth; /* depth of palette samples */
+ png_sPLT_entryp entries; /* palette entries */
+ png_int_32 nentries; /* number of palette entries */
+} png_sPLT_t;
+typedef png_sPLT_t FAR * png_sPLT_tp;
+typedef png_sPLT_t FAR * FAR * png_sPLT_tpp;
+
+#ifdef PNG_TEXT_SUPPORTED
+/* png_text holds the contents of a text/ztxt/itxt chunk in a PNG file,
+ * and whether that contents is compressed or not. The "key" field
+ * points to a regular zero-terminated C string. The "text", "lang", and
+ * "lang_key" fields can be regular C strings, empty strings, or NULL pointers.
+ * However, the * structure returned by png_get_text() will always contain
+ * regular zero-terminated C strings (possibly empty), never NULL pointers,
+ * so they can be safely used in printf() and other string-handling functions.
+ */
+typedef struct png_text_struct
+{
+ int compression; /* compression value:
+ -1: tEXt, none
+ 0: zTXt, deflate
+ 1: iTXt, none
+ 2: iTXt, deflate */
+ png_charp key; /* keyword, 1-79 character description of "text" */
+ png_charp text; /* comment, may be an empty string (ie "")
+ or a NULL pointer */
+ png_size_t text_length; /* length of the text string */
+#ifdef PNG_iTXt_SUPPORTED
+ png_size_t itxt_length; /* length of the itxt string */
+ png_charp lang; /* language code, 0-79 characters
+ or a NULL pointer */
+ png_charp lang_key; /* keyword translated UTF-8 string, 0 or more
+ chars or a NULL pointer */
+#endif
+} png_text;
+typedef png_text FAR * png_textp;
+typedef png_text FAR * FAR * png_textpp;
+#endif
+
+/* Supported compression types for text in PNG files (tEXt, and zTXt).
+ * The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed. */
+#define PNG_TEXT_COMPRESSION_NONE_WR -3
+#define PNG_TEXT_COMPRESSION_zTXt_WR -2
+#define PNG_TEXT_COMPRESSION_NONE -1
+#define PNG_TEXT_COMPRESSION_zTXt 0
+#define PNG_ITXT_COMPRESSION_NONE 1
+#define PNG_ITXT_COMPRESSION_zTXt 2
+#define PNG_TEXT_COMPRESSION_LAST 3 /* Not a valid value */
+
+/* png_time is a way to hold the time in an machine independent way.
+ * Two conversions are provided, both from time_t and struct tm. There
+ * is no portable way to convert to either of these structures, as far
+ * as I know. If you know of a portable way, send it to me. As a side
+ * note - PNG has always been Year 2000 compliant!
+ */
+typedef struct png_time_struct
+{
+ png_uint_16 year; /* full year, as in, 1995 */
+ png_byte month; /* month of year, 1 - 12 */
+ png_byte day; /* day of month, 1 - 31 */
+ png_byte hour; /* hour of day, 0 - 23 */
+ png_byte minute; /* minute of hour, 0 - 59 */
+ png_byte second; /* second of minute, 0 - 60 (for leap seconds) */
+} png_time;
+typedef png_time FAR * png_timep;
+typedef png_time FAR * FAR * png_timepp;
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+/* png_unknown_chunk is a structure to hold queued chunks for which there is
+ * no specific support. The idea is that we can use this to queue
+ * up private chunks for output even though the library doesn't actually
+ * know about their semantics.
+ */
+typedef struct png_unknown_chunk_t
+{
+ png_byte name[5];
+ png_byte *data;
+ png_size_t size;
+
+ /* libpng-using applications should NOT directly modify this byte. */
+ png_byte location; /* mode of operation at read time */
+}
+png_unknown_chunk;
+typedef png_unknown_chunk FAR * png_unknown_chunkp;
+typedef png_unknown_chunk FAR * FAR * png_unknown_chunkpp;
+#endif
+
+/* png_info is a structure that holds the information in a PNG file so
+ * that the application can tqfind out the characteristics of the image.
+ * If you are reading the file, this structure will tell you what is
+ * in the PNG file. If you are writing the file, fill in the information
+ * you want to put into the PNG file, then call png_write_info().
+ * The names chosen should be very close to the PNG specification, so
+ * consult that document for information about the meaning of each field.
+ *
+ * With libpng < 0.95, it was only possible to directly set and read the
+ * the values in the png_info_struct, which meant that the contents and
+ * order of the values had to remain fixed. With libpng 0.95 and later,
+ * however, there are now functions that abstract the contents of
+ * png_info_struct from the application, so this makes it easier to use
+ * libpng with dynamic libraries, and even makes it possible to use
+ * libraries that don't have all of the libpng ancillary chunk-handing
+ * functionality.
+ *
+ * In any case, the order of the parameters in png_info_struct should NOT
+ * be changed for as long as possible to keep compatibility with applications
+ * that use the old direct-access method with png_info_struct.
+ *
+ * The following members may have allocated storage attached that should be
+ * cleaned up before the structure is discarded: palette, trans, text,
+ * pcal_purpose, pcal_units, pcal_params, hist, iccp_name, iccp_profile,
+ * splt_palettes, scal_unit, row_pointers, and unknowns. By default, these
+ * are automatically freed when the info structure is deallocated, if they were
+ * allocated internally by libpng. This behavior can be changed by means
+ * of the png_data_freer() function.
+ *
+ * More allocation details: all the chunk-reading functions that
+ * change these members go through the corresponding png_set_*
+ * functions. A function to clear these members is available: see
+ * png_free_data(). The png_set_* functions do not depend on being
+ * able to point info structure members to any of the storage they are
+ * passed (they make their own copies), EXCEPT that the png_set_text
+ * functions use the same storage passed to them in the text_ptr or
+ * itxt_ptr structure argument, and the png_set_rows and png_set_unknowns
+ * functions do not make their own copies.
+ */
+typedef struct png_info_struct
+{
+ /* the following are necessary for every PNG file */
+ png_uint_32 width; /* width of image in pixels (from IHDR) */
+ png_uint_32 height; /* height of image in pixels (from IHDR) */
+ png_uint_32 valid; /* valid chunk data (see PNG_INFO_ below) */
+ png_uint_32 rowbytes; /* bytes needed to hold an untransformed row */
+ png_colorp palette; /* array of color values (valid & PNG_INFO_PLTE) */
+ png_uint_16 num_palette; /* number of color entries in "palette" (PLTE) */
+ png_uint_16 num_trans; /* number of transtqparent palette color (tRNS) */
+ png_byte bit_depth; /* 1, 2, 4, 8, or 16 bits/channel (from IHDR) */
+ png_byte color_type; /* see PNG_COLOR_TYPE_ below (from IHDR) */
+ /* The following three should have been named *_method not *_type */
+ png_byte compression_type; /* must be PNG_COMPRESSION_TYPE_BASE (IHDR) */
+ png_byte filter_type; /* must be PNG_FILTER_TYPE_BASE (from IHDR) */
+ png_byte interlace_type; /* One of PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+
+ /* The following is informational only on read, and not used on writes. */
+ png_byte channels; /* number of data channels per pixel (1, 2, 3, 4) */
+ png_byte pixel_depth; /* number of bits per pixel */
+ png_byte spare_byte; /* to align the data, and for future use */
+ png_byte signature[8]; /* magic bytes read by libpng from start of file */
+
+ /* The rest of the data is optional. If you are reading, check the
+ * valid field to see if the information in these are valid. If you
+ * are writing, set the valid field to those chunks you want written,
+ * and initialize the appropriate fields below.
+ */
+
+#if defined(PNG_gAMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+ /* The gAMA chunk describes the gamma characteristics of the system
+ * on which the image was created, normally in the range [1.0, 2.5].
+ * Data is valid if (valid & PNG_INFO_gAMA) is non-zero.
+ */
+ float gamma; /* gamma value of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+ /* GR-P, 0.96a */
+ /* Data valid if (valid & PNG_INFO_sRGB) non-zero. */
+ png_byte srgb_intent; /* sRGB rendering intent [0, 1, 2, or 3] */
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+ /* The tEXt, and zTXt chunks contain human-readable textual data in
+ * uncompressed, compressed, and optionally compressed forms, respectively.
+ * The data in "text" is an array of pointers to uncompressed,
+ * null-terminated C strings. Each chunk has a keyword that describes the
+ * textual data contained in that chunk. Keywords are not required to be
+ * unique, and the text string may be empty. Any number of text chunks may
+ * be in an image.
+ */
+ int num_text; /* number of comments read/to write */
+ int max_text; /* current size of text array */
+ png_textp text; /* array of comments read/to write */
+#endif /* PNG_TEXT_SUPPORTED */
+
+#if defined(PNG_tIME_SUPPORTED)
+ /* The tIME chunk holds the last time the displayed image data was
+ * modified. See the png_time struct for the contents of this struct.
+ */
+ png_time mod_time;
+#endif
+
+#if defined(PNG_sBIT_SUPPORTED)
+ /* The sBIT chunk specifies the number of significant high-order bits
+ * in the pixel data. Values are in the range [1, bit_depth], and are
+ * only specified for the channels in the pixel data. The contents of
+ * the low-order bits is not specified. Data is valid if
+ * (valid & PNG_INFO_sBIT) is non-zero.
+ */
+ png_color_8 sig_bit; /* significant bits in color channels */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_EXPAND_SUPPORTED) || \
+defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* The tRNS chunk supplies transparency data for paletted images and
+ * other image types that don't need a full alpha channel. There are
+ * "num_trans" transparency values for a paletted image, stored in the
+ * same order as the palette colors, starting from index 0. Values
+ * for the data are in the range [0, 255], ranging from fully transtqparent
+ * to fully opaque, respectively. For non-paletted images, there is a
+ * single color specified that should be treated as fully transtqparent.
+ * Data is valid if (valid & PNG_INFO_tRNS) is non-zero.
+ */
+ png_bytep trans; /* transtqparent values for paletted image */
+ png_color_16 trans_values; /* transtqparent color for non-palette image */
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* The bKGD chunk gives the suggested image background color if the
+ * display program does not have its own background color and the image
+ * is needs to composited onto a background before display. The colors
+ * in "background" are normally in the same color space/depth as the
+ * pixel data. Data is valid if (valid & PNG_INFO_bKGD) is non-zero.
+ */
+ png_color_16 background;
+#endif
+
+#if defined(PNG_oFFs_SUPPORTED)
+ /* The oFFs chunk gives the offset in "offset_unit_type" units rightwards
+ * and downwards from the top-left corner of the display, page, or other
+ * application-specific co-ordinate space. See the PNG_OFFSET_ defines
+ * below for the unit types. Valid if (valid & PNG_INFO_oFFs) non-zero.
+ */
+ png_int_32 x_offset; /* x offset on page */
+ png_int_32 y_offset; /* y offset on page */
+ png_byte offset_unit_type; /* offset units type */
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+ /* The pHYs chunk gives the physical pixel density of the image for
+ * display or printing in "phys_unit_type" units (see PNG_RESOLUTION_
+ * defines below). Data is valid if (valid & PNG_INFO_pHYs) is non-zero.
+ */
+ png_uint_32 x_pixels_per_unit; /* horizontal pixel density */
+ png_uint_32 y_pixels_per_unit; /* vertical pixel density */
+ png_byte phys_unit_type; /* resolution type (see PNG_RESOLUTION_ below) */
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+ /* The hIST chunk tqcontains the relative frequency or importance of the
+ * various palette entries, so that a viewer can intelligently select a
+ * reduced-color palette, if required. Data is an array of "num_palette"
+ * values in the range [0,65535]. Data valid if (valid & PNG_INFO_hIST)
+ * is non-zero.
+ */
+ png_uint_16p hist;
+#endif
+
+#ifdef PNG_cHRM_SUPPORTED
+ /* The cHRM chunk describes the CIE color characteristics of the monitor
+ * on which the PNG was created. This data allows the viewer to do gamut
+ * mapping of the input image to ensure that the viewer sees the same
+ * colors in the image as the creator. Values are in the range
+ * [0.0, 0.8]. Data valid if (valid & PNG_INFO_cHRM) non-zero.
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float x_white;
+ float y_white;
+ float x_red;
+ float y_red;
+ float x_green;
+ float y_green;
+ float x_blue;
+ float y_blue;
+#endif
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+ /* The pCAL chunk describes a transformation between the stored pixel
+ * values and original physical data values used to create the image.
+ * The integer range [0, 2^bit_depth - 1] maps to the floating-point
+ * range given by [pcal_X0, pcal_X1], and are further transformed by a
+ * (possibly non-linear) transformation function given by "pcal_type"
+ * and "pcal_params" into "pcal_units". Please see the PNG_ETQUATION_
+ * defines below, and the PNG-Group's PNG extensions document for a
+ * complete description of the transformations and how they should be
+ * implemented, and for a description of the ASCII parameter strings.
+ * Data values are valid if (valid & PNG_INFO_pCAL) non-zero.
+ */
+ png_charp pcal_purpose; /* pCAL chunk description string */
+ png_int_32 pcal_X0; /* minimum value */
+ png_int_32 pcal_X1; /* maximum value */
+ png_charp pcal_units; /* Latin-1 string giving physical units */
+ png_charpp pcal_params; /* ASCII strings containing parameter values */
+ png_byte pcal_type; /* equation type (see PNG_ETQUATION_ below) */
+ png_byte pcal_nparams; /* number of parameters given in pcal_params */
+#endif
+
+/* New members added in libpng-1.0.6 */
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_uint_32 free_me; /* flags items libpng is responsible for freeing */
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ /* storage for unknown chunks that the library doesn't recognize. */
+ png_unknown_chunkp unknown_chunks;
+ png_size_t unknown_chunks_num;
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+ /* iCCP chunk data. */
+ png_charp iccp_name; /* profile name */
+ png_charp iccp_profile; /* International Color Consortium profile data */
+ /* Note to maintainer: should be png_bytep */
+ png_uint_32 iccp_proflen; /* ICC profile data length */
+ png_byte iccp_compression; /* Always zero */
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+ /* data on sPLT chunks (there may be more than one). */
+ png_sPLT_tp splt_palettes;
+ png_uint_32 splt_palettes_num;
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+ /* The sCAL chunk describes the actual physical dimensions of the
+ * subject matter of the graphic. The chunk tqcontains a unit specification
+ * a byte value, and two ASCII strings representing floating-point
+ * values. The values are width and height corresponsing to one pixel
+ * in the image. This external representation is converted to double
+ * here. Data values are valid if (valid & PNG_INFO_sCAL) is non-zero.
+ */
+ png_byte scal_unit; /* unit of physical scale */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ double scal_pixel_width; /* width of one pixel */
+ double scal_pixel_height; /* height of one pixel */
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_charp scal_s_width; /* string containing height */
+ png_charp scal_s_height; /* string containing width */
+#endif
+#endif
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+ /* Memory has been allocated if (valid & PNG_ALLOCATED_INFO_ROWS) non-zero */
+ /* Data valid if (valid & PNG_INFO_IDAT) non-zero */
+ png_bytepp row_pointers; /* the image bits */
+#endif
+
+#if defined(PNG_FIXED_POINT_SUPPORTED) && defined(PNG_gAMA_SUPPORTED)
+ png_fixed_point int_gamma; /* gamma of image, if (valid & PNG_INFO_gAMA) */
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED) && defined(PNG_FIXED_POINT_SUPPORTED)
+ png_fixed_point int_x_white;
+ png_fixed_point int_y_white;
+ png_fixed_point int_x_red;
+ png_fixed_point int_y_red;
+ png_fixed_point int_x_green;
+ png_fixed_point int_y_green;
+ png_fixed_point int_x_blue;
+ png_fixed_point int_y_blue;
+#endif
+
+} png_info;
+
+typedef png_info FAR * png_infop;
+typedef png_info FAR * FAR * png_infopp;
+
+/* Maximum positive integer used in PNG is (2^31)-1 */
+#define PNG_UINT_31_MAX ((png_uint_32)0x7fffffffL)
+#define PNG_UINT_32_MAX (~((png_uint_32)0))
+#define PNG_SIZE_MAX (~((png_size_t)0))
+/* PNG_MAX_UINT is deprecated; use PNG_UINT_31_MAX instead. */
+#define PNG_MAX_UINT PNG_UINT_31_MAX
+
+/* These describe the color_type field in png_info. */
+/* color type masks */
+#define PNG_COLOR_MASK_PALETTE 1
+#define PNG_COLOR_MASK_COLOR 2
+#define PNG_COLOR_MASK_ALPHA 4
+
+/* color types. Note that not all combinations are legal */
+#define PNG_COLOR_TYPE_GRAY 0
+#define PNG_COLOR_TYPE_PALETTE (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_PALETTE)
+#define PNG_COLOR_TYPE_RGB (PNG_COLOR_MASK_COLOR)
+#define PNG_COLOR_TYPE_RGB_ALPHA (PNG_COLOR_MASK_COLOR | PNG_COLOR_MASK_ALPHA)
+#define PNG_COLOR_TYPE_GRAY_ALPHA (PNG_COLOR_MASK_ALPHA)
+/* aliases */
+#define PNG_COLOR_TYPE_RGBA PNG_COLOR_TYPE_RGB_ALPHA
+#define PNG_COLOR_TYPE_GA PNG_COLOR_TYPE_GRAY_ALPHA
+
+/* This is for compression type. PNG 1.0-1.2 only define the single type. */
+#define PNG_COMPRESSION_TYPE_BASE 0 /* Deflate method 8, 32K window */
+#define PNG_COMPRESSION_TYPE_DEFAULT PNG_COMPRESSION_TYPE_BASE
+
+/* This is for filter type. PNG 1.0-1.2 only define the single type. */
+#define PNG_FILTER_TYPE_BASE 0 /* Single row per-byte filtering */
+#define PNG_INTRAPIXEL_DIFFERENCING 64 /* Used only in MNG datastreams */
+#define PNG_FILTER_TYPE_DEFAULT PNG_FILTER_TYPE_BASE
+
+/* These are for the interlacing type. These values should NOT be changed. */
+#define PNG_INTERLACE_NONE 0 /* Non-interlaced image */
+#define PNG_INTERLACE_ADAM7 1 /* Adam7 interlacing */
+#define PNG_INTERLACE_LAST 2 /* Not a valid value */
+
+/* These are for the oFFs chunk. These values should NOT be changed. */
+#define PNG_OFFSET_PIXEL 0 /* Offset in pixels */
+#define PNG_OFFSET_MICROMETER 1 /* Offset in micrometers (1/10^6 meter) */
+#define PNG_OFFSET_LAST 2 /* Not a valid value */
+
+/* These are for the pCAL chunk. These values should NOT be changed. */
+#define PNG_ETQUATION_LINEAR 0 /* Linear transformation */
+#define PNG_ETQUATION_BASE_E 1 /* Exponential base e transform */
+#define PNG_ETQUATION_ARBITRARY 2 /* Arbitrary base exponential transform */
+#define PNG_ETQUATION_HYPERBOLIC 3 /* Hyperbolic sine transformation */
+#define PNG_ETQUATION_LAST 4 /* Not a valid value */
+
+/* These are for the sCAL chunk. These values should NOT be changed. */
+#define PNG_SCALE_UNKNOWN 0 /* unknown unit (image scale) */
+#define PNG_SCALE_METER 1 /* meters per pixel */
+#define PNG_SCALE_RADIAN 2 /* radians per pixel */
+#define PNG_SCALE_LAST 3 /* Not a valid value */
+
+/* These are for the pHYs chunk. These values should NOT be changed. */
+#define PNG_RESOLUTION_UNKNOWN 0 /* pixels/unknown unit (aspect ratio) */
+#define PNG_RESOLUTION_METER 1 /* pixels/meter */
+#define PNG_RESOLUTION_LAST 2 /* Not a valid value */
+
+/* These are for the sRGB chunk. These values should NOT be changed. */
+#define PNG_sRGB_INTENT_PERCEPTUAL 0
+#define PNG_sRGB_INTENT_RELATIVE 1
+#define PNG_sRGB_INTENT_SATURATION 2
+#define PNG_sRGB_INTENT_ABSOLUTE 3
+#define PNG_sRGB_INTENT_LAST 4 /* Not a valid value */
+
+/* This is for text chunks */
+#define PNG_KEYWORD_MAX_LENGTH 79
+
+/* Maximum number of entries in PLTE/sPLT/tRNS arrays */
+#define PNG_MAX_PALETTE_LENGTH 256
+
+/* These determine if an ancillary chunk's data has been successfully read
+ * from the PNG header, or if the application has filled in the corresponding
+ * data in the info_struct to be written into the output file. The values
+ * of the PNG_INFO_<chunk> defines should NOT be changed.
+ */
+#define PNG_INFO_gAMA 0x0001
+#define PNG_INFO_sBIT 0x0002
+#define PNG_INFO_cHRM 0x0004
+#define PNG_INFO_PLTE 0x0008
+#define PNG_INFO_tRNS 0x0010
+#define PNG_INFO_bKGD 0x0020
+#define PNG_INFO_hIST 0x0040
+#define PNG_INFO_pHYs 0x0080
+#define PNG_INFO_oFFs 0x0100
+#define PNG_INFO_tIME 0x0200
+#define PNG_INFO_pCAL 0x0400
+#define PNG_INFO_sRGB 0x0800 /* GR-P, 0.96a */
+#define PNG_INFO_iCCP 0x1000 /* ESR, 1.0.6 */
+#define PNG_INFO_sPLT 0x2000 /* ESR, 1.0.6 */
+#define PNG_INFO_sCAL 0x4000 /* ESR, 1.0.6 */
+#define PNG_INFO_IDAT 0x8000L /* ESR, 1.0.6 */
+
+/* This is used for the transformation routines, as some of them
+ * change these values for the row. It also should enable using
+ * the routines for other purposes.
+ */
+typedef struct png_row_info_struct
+{
+ png_uint_32 width; /* width of row */
+ png_uint_32 rowbytes; /* number of bytes in row */
+ png_byte color_type; /* color type of row */
+ png_byte bit_depth; /* bit depth of row */
+ png_byte channels; /* number of channels (1, 2, 3, or 4) */
+ png_byte pixel_depth; /* bits per pixel (depth * channels) */
+} png_row_info;
+
+typedef png_row_info FAR * png_row_infop;
+typedef png_row_info FAR * FAR * png_row_infopp;
+
+/* These are the function types for the I/O functions and for the functions
+ * that allow the user to override the default I/O functions with his or her
+ * own. The png_error_ptr type should match that of user-supplied warning
+ * and error functions, while the png_rw_ptr type should match that of the
+ * user read/write data functions.
+ */
+typedef struct png_struct_def png_struct;
+typedef png_struct FAR * png_structp;
+
+typedef void (PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
+typedef void (PNGAPI *png_rw_ptr) PNGARG((png_structp, png_bytep, png_size_t));
+typedef void (PNGAPI *png_flush_ptr) PNGARG((png_structp));
+typedef void (PNGAPI *png_read_status_ptr) PNGARG((png_structp, png_uint_32,
+ int));
+typedef void (PNGAPI *png_write_status_ptr) PNGARG((png_structp, png_uint_32,
+ int));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+typedef void (PNGAPI *png_progressive_info_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_end_ptr) PNGARG((png_structp, png_infop));
+typedef void (PNGAPI *png_progressive_row_ptr) PNGARG((png_structp, png_bytep,
+ png_uint_32, int));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+typedef void (PNGAPI *png_user_transform_ptr) PNGARG((png_structp,
+ png_row_infop, png_bytep));
+#endif
+
+#if defined(PNG_USER_CHUNKS_SUPPORTED)
+typedef int (PNGAPI *png_user_chunk_ptr) PNGARG((png_structp, png_unknown_chunkp));
+#endif
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+typedef void (PNGAPI *png_unknown_chunk_ptr) PNGARG((png_structp));
+#endif
+
+/* Transform masks for the high-level interface */
+#define PNG_TRANSFORM_IDENTITY 0x0000 /* read and write */
+#define PNG_TRANSFORM_STRIP_16 0x0001 /* read only */
+#define PNG_TRANSFORM_STRIP_ALPHA 0x0002 /* read only */
+#define PNG_TRANSFORM_PACKING 0x0004 /* read and write */
+#define PNG_TRANSFORM_PACKSWAP 0x0008 /* read and write */
+#define PNG_TRANSFORM_EXPAND 0x0010 /* read only */
+#define PNG_TRANSFORM_INVERT_MONO 0x0020 /* read and write */
+#define PNG_TRANSFORM_SHIFT 0x0040 /* read and write */
+#define PNG_TRANSFORM_BGR 0x0080 /* read and write */
+#define PNG_TRANSFORM_SWAP_ALPHA 0x0100 /* read and write */
+#define PNG_TRANSFORM_SWAP_ENDIAN 0x0200 /* read and write */
+#define PNG_TRANSFORM_INVERT_ALPHA 0x0400 /* read and write */
+#define PNG_TRANSFORM_STRIP_FILLER 0x0800 /* WRITE only */
+
+/* Flags for MNG supported features */
+#define PNG_FLAG_MNG_EMPTY_PLTE 0x01
+#define PNG_FLAG_MNG_FILTER_64 0x04
+#define PNG_ALL_MNG_FEATURES 0x05
+
+typedef png_voidp (*png_malloc_ptr) PNGARG((png_structp, png_size_t));
+typedef void (*png_free_ptr) PNGARG((png_structp, png_voidp));
+
+/* The structure that holds the information to read and write PNG files.
+ * The only people who need to care about what is inside of this are the
+ * people who will be modifying the library for their own special needs.
+ * It should NOT be accessed directly by an application, except to store
+ * the jmp_buf.
+ */
+
+struct png_struct_def
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf jmpbuf; /* used in png_error */
+#endif
+ png_error_ptr error_fn; /* function for printing errors and aborting */
+ png_error_ptr warning_fn; /* function for printing warnings */
+ png_voidp error_ptr; /* user supplied struct for error functions */
+ png_rw_ptr write_data_fn; /* function for writing output data */
+ png_rw_ptr read_data_fn; /* function for reading input data */
+ png_voidp io_ptr; /* ptr to application struct for I/O functions */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ png_user_transform_ptr read_user_transform_fn; /* user read transform */
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ png_user_transform_ptr write_user_transform_fn; /* user write transform */
+#endif
+
+/* These were added in libpng-1.0.2 */
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ png_voidp user_transform_ptr; /* user supplied struct for user transform */
+ png_byte user_transform_depth; /* bit depth of user transformed pixels */
+ png_byte user_transform_channels; /* channels in user transformed pixels */
+#endif
+#endif
+
+ png_uint_32 mode; /* tells us where we are in the PNG file */
+ png_uint_32 flags; /* flags indicating various things to libpng */
+ png_uint_32 transformations; /* which transformations to perform */
+
+ z_stream zstream; /* pointer to decompression structure (below) */
+ png_bytep zbuf; /* buffer for zlib */
+ png_size_t zbuf_size; /* size of zbuf */
+ int zlib_level; /* holds zlib compression level */
+ int zlib_method; /* holds zlib compression method */
+ int zlib_window_bits; /* holds zlib compression window bits */
+ int zlib_mem_level; /* holds zlib compression memory level */
+ int zlib_strategy; /* holds zlib compression strategy */
+
+ png_uint_32 width; /* width of image in pixels */
+ png_uint_32 height; /* height of image in pixels */
+ png_uint_32 num_rows; /* number of rows in current pass */
+ png_uint_32 usr_width; /* width of row at start of write */
+ png_uint_32 rowbytes; /* size of row in bytes */
+ png_uint_32 irowbytes; /* size of current interlaced row in bytes */
+ png_uint_32 iwidth; /* width of current interlaced row in pixels */
+ png_uint_32 row_number; /* current row in interlace pass */
+ png_bytep prev_row; /* buffer to save previous (unfiltered) row */
+ png_bytep row_buf; /* buffer to save current (unfiltered) row */
+ png_bytep sub_row; /* buffer to save "sub" row when filtering */
+ png_bytep up_row; /* buffer to save "up" row when filtering */
+ png_bytep avg_row; /* buffer to save "avg" row when filtering */
+ png_bytep paeth_row; /* buffer to save "Paeth" row when filtering */
+ png_row_info row_info; /* used for transformation routines */
+
+ png_uint_32 idat_size; /* current IDAT size for read */
+ png_uint_32 crc; /* current chunk CRC value */
+ png_colorp palette; /* palette from the input file */
+ png_uint_16 num_palette; /* number of color entries in palette */
+ png_uint_16 num_trans; /* number of transparency values */
+ png_byte chunk_name[5]; /* null-terminated name of current chunk */
+ png_byte compression; /* file compression type (always 0) */
+ png_byte filter; /* file filter type (always 0) */
+ png_byte interlaced; /* PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7 */
+ png_byte pass; /* current interlace pass (0 - 6) */
+ png_byte do_filter; /* row filter flags (see PNG_FILTER_ below ) */
+ png_byte color_type; /* color type of file */
+ png_byte bit_depth; /* bit depth of file */
+ png_byte usr_bit_depth; /* bit depth of users row */
+ png_byte pixel_depth; /* number of bits per pixel */
+ png_byte channels; /* number of channels in file */
+ png_byte usr_channels; /* channels at start of write */
+ png_byte sig_bytes; /* magic bytes read/written from start of file */
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+#ifdef PNG_LEGACY_SUPPORTED
+ png_byte filler; /* filler byte for pixel expansion */
+#else
+ png_uint_16 filler; /* filler bytes for pixel expansion */
+#endif
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED)
+ png_byte background_gamma_type;
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ float background_gamma;
+# endif
+ png_color_16 background; /* background color in screen gamma space */
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ png_color_16 background_1; /* background normalized to gamma 1.0 */
+#endif
+#endif /* PNG_bKGD_SUPPORTED */
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+ png_flush_ptr output_flush_fn;/* Function for flushing output */
+ png_uint_32 flush_dist; /* how many rows apart to flush, 0 - no flush */
+ png_uint_32 flush_rows; /* number of rows written since last flush */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ int gamma_shift; /* number of "insignificant" bits 16-bit gamma */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float gamma; /* file gamma value */
+ float screen_gamma; /* screen gamma value (display_exponent) */
+#endif
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_bytep gamma_table; /* gamma table for 8-bit depth files */
+ png_bytep gamma_from_1; /* converts from 1.0 to screen */
+ png_bytep gamma_to_1; /* converts from file to 1.0 */
+ png_uint_16pp gamma_16_table; /* gamma table for 16-bit depth files */
+ png_uint_16pp gamma_16_from_1; /* converts from 1.0 to screen */
+ png_uint_16pp gamma_16_to_1; /* converts from file to 1.0 */
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_sBIT_SUPPORTED)
+ png_color_8 sig_bit; /* significant bits in each available channel */
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+ png_color_8 shift; /* shift for significant bit tranformation */
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED) \
+ || defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_bytep trans; /* transparency values for paletted files */
+ png_color_16 trans_values; /* transparency values for non-paletted files */
+#endif
+
+ png_read_status_ptr read_row_fn; /* called after each row is decoded */
+ png_write_status_ptr write_row_fn; /* called after each row is encoded */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_progressive_info_ptr info_fn; /* called after header data fully read */
+ png_progressive_row_ptr row_fn; /* called after each prog. row is decoded */
+ png_progressive_end_ptr end_fn; /* called after image is complete */
+ png_bytep save_buffer_ptr; /* current location in save_buffer */
+ png_bytep save_buffer; /* buffer for previously read data */
+ png_bytep current_buffer_ptr; /* current location in current_buffer */
+ png_bytep current_buffer; /* buffer for recently used data */
+ png_uint_32 push_length; /* size of current input chunk */
+ png_uint_32 skip_length; /* bytes to skip in input data */
+ png_size_t save_buffer_size; /* amount of data now in save_buffer */
+ png_size_t save_buffer_max; /* total size of save_buffer */
+ png_size_t buffer_size; /* total amount of available input data */
+ png_size_t current_buffer_size; /* amount of data now in current_buffer */
+ int process_mode; /* what push library is currently doing */
+ int cur_palette; /* current push library palette index */
+
+# if defined(PNG_TEXT_SUPPORTED)
+ png_size_t current_text_size; /* current size of text input data */
+ png_size_t current_text_left; /* how much text left to read in input */
+ png_charp current_text; /* current text chunk buffer */
+ png_charp current_text_ptr; /* current location in current_text */
+# endif /* PNG_PROGRESSIVE_READ_SUPPORTED && PNG_TEXT_SUPPORTED */
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* for the Borland special 64K segment handler */
+ png_bytepp offset_table_ptr;
+ png_bytep offset_table;
+ png_uint_16 offset_table_number;
+ png_uint_16 offset_table_count;
+ png_uint_16 offset_table_count_free;
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+ png_bytep palette_lookup; /* lookup table for dithering */
+ png_bytep dither_index; /* index translation for palette files */
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED) || defined(PNG_hIST_SUPPORTED)
+ png_uint_16p hist; /* histogram */
+#endif
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ png_byte heuristic_method; /* heuristic for row filter selection */
+ png_byte num_prev_filters; /* number of weights for previous rows */
+ png_bytep prev_filters; /* filter type(s) of previous row(s) */
+ png_uint_16p filter_weights; /* weight(s) for previous line(s) */
+ png_uint_16p inv_filter_weights; /* 1/weight(s) for previous line(s) */
+ png_uint_16p filter_costs; /* relative filter calculation cost */
+ png_uint_16p inv_filter_costs; /* 1/relative filter calculation cost */
+#endif
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ png_charp time_buffer; /* String to hold RFC 1123 time text */
+#endif
+
+/* New members added in libpng-1.0.6 */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_uint_32 free_me; /* flags items libpng is responsible for freeing */
+#endif
+
+#if defined(PNG_USER_CHUNKS_SUPPORTED)
+ png_voidp user_chunk_ptr;
+ png_user_chunk_ptr read_user_chunk_fn; /* user read chunk handler */
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ int num_chunk_list;
+ png_bytep chunk_list;
+#endif
+
+/* New members added in libpng-1.0.3 */
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ png_byte rgb_to_gray_status;
+ /* These were changed from png_byte in libpng-1.0.6 */
+ png_uint_16 rgb_to_gray_red_coeff;
+ png_uint_16 rgb_to_gray_green_coeff;
+ png_uint_16 rgb_to_gray_blue_coeff;
+#endif
+
+/* New member added in libpng-1.0.4 (renamed in 1.0.9) */
+#if defined(PNG_MNG_FEATURES_SUPPORTED) || \
+ defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* changed from png_byte to png_uint_32 at version 1.2.0 */
+#ifdef PNG_1_0_X
+ png_byte mng_features_permitted;
+#else
+ png_uint_32 mng_features_permitted;
+#endif /* PNG_1_0_X */
+#endif
+
+/* New member added in libpng-1.0.7 */
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_fixed_point int_gamma;
+#endif
+
+/* New member added in libpng-1.0.9, ifdef'ed out in 1.0.12, enabled in 1.2.0 */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ png_byte filter_type;
+#endif
+
+#if defined(PNG_1_0_X) || (defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD))
+/* New member added in libpng-1.0.10, ifdef'ed out in 1.2.0 */
+ png_uint_32 row_buf_size;
+#endif
+
+/* New members added in libpng-1.2.0 */
+#if !defined(PNG_1_0_X) && defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+ png_byte mmx_bitdepth_threshold;
+ png_uint_32 mmx_rowbytes_threshold;
+ png_uint_32 asm_flags;
+#endif
+
+/* New members added in libpng-1.0.2 but first enabled by default in 1.2.0 */
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_voidp mem_ptr; /* user supplied struct for mem functions */
+ png_malloc_ptr malloc_fn; /* function for allocating memory */
+ png_free_ptr free_fn; /* function for freeing memory */
+#endif
+
+/* New member added in libpng-1.0.13 and 1.2.0 */
+ png_bytep big_row_buf; /* buffer to save current (unfiltered) row */
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* The following three members were added at version 1.0.14 and 1.2.4 */
+ png_bytep dither_sort; /* working sort array */
+ png_bytep index_to_palette; /* where the original index currently is */
+ /* in the palette */
+ png_bytep palette_to_index; /* which original index points to this */
+ /* palette color */
+#endif
+
+};
+
+
+/* This prevents a compiler error in png.c if png.c and png.h are both at
+ version 1.2.5
+ */
+typedef png_structp version_1_2_5;
+
+typedef png_struct FAR * FAR * png_structpp;
+
+/* Here are the function definitions most commonly used. This is not
+ * the place to tqfind out how to use libpng. See libpng.txt for the
+ * full explanation, see example.c for the summary. This just provides
+ * a simple one line description of the use of each function.
+ */
+
+/* Returns the version number of the library */
+extern PNG_EXPORT(png_uint_32,png_access_version_number) PNGARG((void));
+
+/* Tell lib we have already handled the first <num_bytes> magic bytes.
+ * Handling more than 8 bytes from the beginning of the file is an error.
+ */
+extern PNG_EXPORT(void,png_set_sig_bytes) PNGARG((png_structp png_ptr,
+ int num_bytes));
+
+/* Check sig[start] through sig[start + num_to_check - 1] to see if it's a
+ * PNG file. Returns zero if the supplied bytes match the 8-byte PNG
+ * signature, and non-zero otherwise. Having num_to_check == 0 or
+ * start > 7 will always fail (ie return non-zero).
+ */
+extern PNG_EXPORT(int,png_sig_cmp) PNGARG((png_bytep sig, png_size_t start,
+ png_size_t num_to_check));
+
+/* Simple signature checking function. This is the same as calling
+ * png_check_sig(sig, n) := !png_sig_cmp(sig, 0, n).
+ */
+extern PNG_EXPORT(int,png_check_sig) PNGARG((png_bytep sig, int num));
+
+/* Allocate and initialize png_ptr struct for reading, and any other memory. */
+extern PNG_EXPORT(png_structp,png_create_read_struct)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn));
+
+/* Allocate and initialize png_ptr struct for writing, and any other memory */
+extern PNG_EXPORT(png_structp,png_create_write_struct)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn));
+
+extern PNG_EXPORT(png_uint_32,png_get_compression_buffer_size)
+ PNGARG((png_structp png_ptr));
+
+extern PNG_EXPORT(void,png_set_compression_buffer_size)
+ PNGARG((png_structp png_ptr, png_uint_32 size));
+
+/* Reset the compression stream */
+extern PNG_EXPORT(int,png_reset_zstream) PNGARG((png_structp png_ptr));
+
+/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */
+#ifdef PNG_USER_MEM_SUPPORTED
+extern PNG_EXPORT(png_structp,png_create_read_struct_2)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+extern PNG_EXPORT(png_structp,png_create_write_struct_2)
+ PNGARG((png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+#endif
+
+/* Write a PNG chunk - size, type, (optional) data, CRC. */
+extern PNG_EXPORT(void,png_write_chunk) PNGARG((png_structp png_ptr,
+ png_bytep chunk_name, png_bytep data, png_size_t length));
+
+/* Write the start of a PNG chunk - length and chunk name. */
+extern PNG_EXPORT(void,png_write_chunk_start) PNGARG((png_structp png_ptr,
+ png_bytep chunk_name, png_uint_32 length));
+
+/* Write the data of a PNG chunk started with png_write_chunk_start(). */
+extern PNG_EXPORT(void,png_write_chunk_data) PNGARG((png_structp png_ptr,
+ png_bytep data, png_size_t length));
+
+/* Finish a chunk started with png_write_chunk_start() (includes CRC). */
+extern PNG_EXPORT(void,png_write_chunk_end) PNGARG((png_structp png_ptr));
+
+/* Allocate and initialize the info structure */
+extern PNG_EXPORT(png_infop,png_create_info_struct)
+ PNGARG((png_structp png_ptr));
+
+/* Initialize the info structure (old interface - DEPRECATED) */
+extern PNG_EXPORT(void,png_info_init) PNGARG((png_infop info_ptr));
+#undef png_info_init
+#define png_info_init(info_ptr) png_info_init_3(&info_ptr, sizeof(png_info));
+extern PNG_EXPORT(void,png_info_init_3) PNGARG((png_infopp info_ptr,
+ png_size_t png_info_struct_size));
+
+/* Writes all the PNG information before the image. */
+extern PNG_EXPORT(void,png_write_info_before_PLTE) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+extern PNG_EXPORT(void,png_write_info) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+/* read the information before the actual image data. */
+extern PNG_EXPORT(void,png_read_info) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+extern PNG_EXPORT(png_charp,png_convert_to_rfc1123)
+ PNGARG((png_structp png_ptr, png_timep ptime));
+#endif
+
+#if !defined(_WIN32_WCE)
+/* "time.h" functions are not supported on WindowsCE */
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+/* convert from a struct tm to png_time */
+extern PNG_EXPORT(void,png_convert_from_struct_tm) PNGARG((png_timep ptime,
+ struct tm FAR * ttime));
+
+/* convert from time_t to png_time. Uses gmtime() */
+extern PNG_EXPORT(void,png_convert_from_time_t) PNGARG((png_timep ptime,
+ time_t ttime));
+#endif /* PNG_WRITE_tIME_SUPPORTED */
+#endif /* _WIN32_WCE */
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expand data to 24-bit RGB, or 8-bit grayscale, with alpha if available. */
+extern PNG_EXPORT(void,png_set_expand) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_gray_1_2_4_to_8) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_palette_to_rgb) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(void,png_set_tRNS_to_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* Use blue, green, red order for pixels. */
+extern PNG_EXPORT(void,png_set_bgr) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+/* Expand the grayscale to 24-bit RGB if necessary. */
+extern PNG_EXPORT(void,png_set_gray_to_rgb) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+/* Reduce RGB to grayscale. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_rgb_to_gray) PNGARG((png_structp png_ptr,
+ int error_action, double red, double green ));
+#endif
+extern PNG_EXPORT(void,png_set_rgb_to_gray_fixed) PNGARG((png_structp png_ptr,
+ int error_action, png_fixed_point red, png_fixed_point green ));
+extern PNG_EXPORT(png_byte,png_get_rgb_to_gray_status) PNGARG((png_structp
+ png_ptr));
+#endif
+
+extern PNG_EXPORT(void,png_build_grayscale_palette) PNGARG((int bit_depth,
+ png_colorp palette));
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_strip_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_swap_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+extern PNG_EXPORT(void,png_set_invert_alpha) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte to 24-bit RGB images. */
+extern PNG_EXPORT(void,png_set_filler) PNGARG((png_structp png_ptr,
+ png_uint_32 filler, int flags));
+/* The values of the PNG_FILLER_ defines should NOT be changed */
+#define PNG_FILLER_BEFORE 0
+#define PNG_FILLER_AFTER 1
+#endif /* PNG_READ_FILLER_SUPPORTED || PNG_WRITE_FILLER_SUPPORTED */
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* Swap bytes in 16-bit depth files. */
+extern PNG_EXPORT(void,png_set_swap) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* Use 1 byte per pixel in 1, 2, or 4-bit depth files. */
+extern PNG_EXPORT(void,png_set_packing) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* Swap packing order of pixels in bytes. */
+extern PNG_EXPORT(void,png_set_packswap) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Converts files to legal bit depths. */
+extern PNG_EXPORT(void,png_set_shift) PNGARG((png_structp png_ptr,
+ png_color_8p true_bits));
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Have the code handle the interlacing. Returns the number of passes. */
+extern PNG_EXPORT(int,png_set_interlace_handling) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+/* Invert monochrome files */
+extern PNG_EXPORT(void,png_set_invert_mono) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+/* Handle alpha and tRNS by replacing with a background color. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_background) PNGARG((png_structp png_ptr,
+ png_color_16p background_color, int background_gamma_code,
+ int need_expand, double background_gamma));
+#endif
+#define PNG_BACKGROUND_GAMMA_UNKNOWN 0
+#define PNG_BACKGROUND_GAMMA_SCREEN 1
+#define PNG_BACKGROUND_GAMMA_FILE 2
+#define PNG_BACKGROUND_GAMMA_UNITQUE 3
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* strip the second byte of information from a 16-bit depth file. */
+extern PNG_EXPORT(void,png_set_strip_16) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* Turn on dithering, and reduce the palette to the number of colors available. */
+extern PNG_EXPORT(void,png_set_dither) PNGARG((png_structp png_ptr,
+ png_colorp palette, int num_palette, int maximum_colors,
+ png_uint_16p histogram, int full_dither));
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+/* Handle gamma correction. Screen_gamma=(display_exponent) */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_gamma) PNGARG((png_structp png_ptr,
+ double screen_gamma, double default_file_gamma));
+#endif
+#endif
+
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+/* Permit or disallow empty PLTE (0: not permitted, 1: permitted) */
+/* Deprecated and will be removed. Use png_permit_mng_features() instead. */
+extern PNG_EXPORT(void,png_permit_empty_plte) PNGARG((png_structp png_ptr,
+ int empty_plte_permitted));
+#endif
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+/* Set how many lines between output flushes - 0 for no flushing */
+extern PNG_EXPORT(void,png_set_flush) PNGARG((png_structp png_ptr, int nrows));
+/* Flush the current PNG output buffer */
+extern PNG_EXPORT(void,png_write_flush) PNGARG((png_structp png_ptr));
+#endif
+
+/* optional update palette with requested transformations */
+extern PNG_EXPORT(void,png_start_read_image) PNGARG((png_structp png_ptr));
+
+/* optional call to update the users info structure */
+extern PNG_EXPORT(void,png_read_update_info) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+/* read one or more rows of image data. */
+extern PNG_EXPORT(void,png_read_rows) PNGARG((png_structp png_ptr,
+ png_bytepp row, png_bytepp display_row, png_uint_32 num_rows));
+
+/* read a row of data. */
+extern PNG_EXPORT(void,png_read_row) PNGARG((png_structp png_ptr,
+ png_bytep row,
+ png_bytep display_row));
+
+/* read the whole image into memory at once. */
+extern PNG_EXPORT(void,png_read_image) PNGARG((png_structp png_ptr,
+ png_bytepp image));
+
+/* write a row of image data */
+extern PNG_EXPORT(void,png_write_row) PNGARG((png_structp png_ptr,
+ png_bytep row));
+
+/* write a few rows of image data */
+extern PNG_EXPORT(void,png_write_rows) PNGARG((png_structp png_ptr,
+ png_bytepp row, png_uint_32 num_rows));
+
+/* write the image data */
+extern PNG_EXPORT(void,png_write_image) PNGARG((png_structp png_ptr,
+ png_bytepp image));
+
+/* writes the end of the PNG file. */
+extern PNG_EXPORT(void,png_write_end) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+/* read the end of the PNG file. */
+extern PNG_EXPORT(void,png_read_end) PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+/* free any memory associated with the png_info_struct */
+extern PNG_EXPORT(void,png_destroy_info_struct) PNGARG((png_structp png_ptr,
+ png_infopp info_ptr_ptr));
+
+/* free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_read_struct) PNGARG((png_structpp
+ png_ptr_ptr, png_infopp info_ptr_ptr, png_infopp end_info_ptr_ptr));
+
+/* free all memory used by the read (old method - NOT DLL EXPORTED) */
+extern void png_read_destroy PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_infop end_info_ptr));
+
+/* free any memory associated with the png_struct and the png_info_structs */
+extern PNG_EXPORT(void,png_destroy_write_struct)
+ PNGARG((png_structpp png_ptr_ptr, png_infopp info_ptr_ptr));
+
+/* free any memory used in png_ptr struct (old method - NOT DLL EXPORTED) */
+extern void png_write_destroy PNGARG((png_structp png_ptr));
+
+/* set the libpng method of handling chunk CRC errors */
+extern PNG_EXPORT(void,png_set_crc_action) PNGARG((png_structp png_ptr,
+ int crit_action, int ancil_action));
+
+/* Values for png_set_crc_action() to say how to handle CRC errors in
+ * ancillary and critical chunks, and whether to use the data contained
+ * therein. Note that it is impossible to "discard" data in a critical
+ * chunk. For versions prior to 0.90, the action was always error/quit,
+ * whereas in version 0.90 and later, the action for CRC errors in ancillary
+ * chunks is warn/discard. These values should NOT be changed.
+ *
+ * value action:critical action:ancillary
+ */
+#define PNG_CRC_DEFAULT 0 /* error/quit warn/discard data */
+#define PNG_CRC_ERROR_TQUIT 1 /* error/quit error/quit */
+#define PNG_CRC_WARN_DISCARD 2 /* (INVALID) warn/discard data */
+#define PNG_CRC_WARN_USE 3 /* warn/use data warn/use data */
+#define PNG_CRC_TQUIET_USE 4 /* quiet/use data quiet/use data */
+#define PNG_CRC_NO_CHANGE 5 /* use current value use current value */
+
+/* These functions give the user control over the scan-line filtering in
+ * libpng and the compression methods used by zlib. These functions are
+ * mainly useful for testing, as the defaults should work with most users.
+ * Those users who are tight on memory or want faster performance at the
+ * expense of compression can modify them. See the compression library
+ * header file (zlib.h) for an explination of the compression functions.
+ */
+
+/* set the filtering method(s) used by libpng. Currently, the only valid
+ * value for "method" is 0.
+ */
+extern PNG_EXPORT(void,png_set_filter) PNGARG((png_structp png_ptr, int method,
+ int filters));
+
+/* Flags for png_set_filter() to say which filters to use. The flags
+ * are chosen so that they don't conflict with real filter types
+ * below, in case they are supplied instead of the #defined constants.
+ * These values should NOT be changed.
+ */
+#define PNG_NO_FILTERS 0x00
+#define PNG_FILTER_NONE 0x08
+#define PNG_FILTER_SUB 0x10
+#define PNG_FILTER_UP 0x20
+#define PNG_FILTER_AVG 0x40
+#define PNG_FILTER_PAETH 0x80
+#define PNG_ALL_FILTERS (PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP | \
+ PNG_FILTER_AVG | PNG_FILTER_PAETH)
+
+/* Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
+ * These defines should NOT be changed.
+ */
+#define PNG_FILTER_VALUE_NONE 0
+#define PNG_FILTER_VALUE_SUB 1
+#define PNG_FILTER_VALUE_UP 2
+#define PNG_FILTER_VALUE_AVG 3
+#define PNG_FILTER_VALUE_PAETH 4
+#define PNG_FILTER_VALUE_LAST 5
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* EXPERIMENTAL */
+/* The "heuristic_method" is given by one of the PNG_FILTER_HEURISTIC_
+ * defines, either the default (minimum-sum-of-absolute-differences), or
+ * the experimental method (weighted-minimum-sum-of-absolute-differences).
+ *
+ * Weights are factors >= 1.0, indicating how important it is to keep the
+ * filter type consistent between rows. Larger numbers mean the current
+ * filter is that many times as likely to be the same as the "num_weights"
+ * previous filters. This is cumulative for each previous row with a weight.
+ * There needs to be "num_weights" values in "filter_weights", or it can be
+ * NULL if the weights aren't being specified. Weights have no influence on
+ * the selection of the first row filter. Well chosen weights can (in theory)
+ * improve the compression for a given image.
+ *
+ * Costs are factors >= 1.0 indicating the relative decoding costs of a
+ * filter type. Higher costs indicate more decoding expense, and are
+ * therefore less likely to be selected over a filter with lower computational
+ * costs. There needs to be a value in "filter_costs" for each valid filter
+ * type (given by PNG_FILTER_VALUE_LAST), or it can be NULL if you aren't
+ * setting the costs. Costs try to improve the speed of decompression without
+ * unduly increasing the compressed image size.
+ *
+ * A negative weight or cost indicates the default value is to be used, and
+ * values in the range [0.0, 1.0) indicate the value is to remain unchanged.
+ * The default values for both weights and costs are currently 1.0, but may
+ * change if good general weighting/cost heuristics can be found. If both
+ * the weights and costs are set to 1.0, this degenerates the WEIGHTED method
+ * to the UNWEIGHTED method, but with added encoding time/computation.
+ */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_filter_heuristics) PNGARG((png_structp png_ptr,
+ int heuristic_method, int num_weights, png_doublep filter_weights,
+ png_doublep filter_costs));
+#endif
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+/* Heuristic used for row filter selection. These defines should NOT be
+ * changed.
+ */
+#define PNG_FILTER_HEURISTIC_DEFAULT 0 /* Currently "UNWEIGHTED" */
+#define PNG_FILTER_HEURISTIC_UNWEIGHTED 1 /* Used by libpng < 0.95 */
+#define PNG_FILTER_HEURISTIC_WEIGHTED 2 /* Experimental feature */
+#define PNG_FILTER_HEURISTIC_LAST 3 /* Not a valid value */
+
+/* Set the library compression level. Currently, valid values range from
+ * 0 - 9, corresponding directly to the zlib compression levels 0 - 9
+ * (0 - no compression, 9 - "maximal" compression). Note that tests have
+ * shown that zlib compression levels 3-6 usually perform as well as level 9
+ * for PNG images, and do considerably fewer caclulations. In the future,
+ * these values may not correspond directly to the zlib compression levels.
+ */
+extern PNG_EXPORT(void,png_set_compression_level) PNGARG((png_structp png_ptr,
+ int level));
+
+extern PNG_EXPORT(void,png_set_compression_mem_level)
+ PNGARG((png_structp png_ptr, int mem_level));
+
+extern PNG_EXPORT(void,png_set_compression_strategy)
+ PNGARG((png_structp png_ptr, int strategy));
+
+extern PNG_EXPORT(void,png_set_compression_window_bits)
+ PNGARG((png_structp png_ptr, int window_bits));
+
+extern PNG_EXPORT(void,png_set_compression_method) PNGARG((png_structp png_ptr,
+ int method));
+
+/* These next functions are called for input/output, memory, and error
+ * handling. They are in the file pngrio.c, pngwio.c, and pngerror.c,
+ * and call standard C I/O routines such as fread(), fwrite(), and
+ * fprintf(). These functions can be made to use other I/O routines
+ * at run time for those applications that need to handle I/O in a
+ * different manner by calling png_set_???_fn(). See libpng.txt for
+ * more information.
+ */
+
+#if !defined(PNG_NO_STDIO)
+/* Initialize the input/output for the PNG file to the default functions. */
+extern PNG_EXPORT(void,png_init_io) PNGARG((png_structp png_ptr, png_FILE_p fp));
+#endif
+
+/* Replace the (error and abort), and warning functions with user
+ * supplied functions. If no messages are to be printed you must still
+ * write and use tqreplacement functions. The tqreplacement error_fn should
+ * still do a longjmp to the last setjmp location if you are using this
+ * method of error handling. If error_fn or warning_fn is NULL, the
+ * default function will be used.
+ */
+
+extern PNG_EXPORT(void,png_set_error_fn) PNGARG((png_structp png_ptr,
+ png_voidp error_ptr, png_error_ptr error_fn, png_error_ptr warning_fn));
+
+/* Return the user pointer associated with the error functions */
+extern PNG_EXPORT(png_voidp,png_get_error_ptr) PNGARG((png_structp png_ptr));
+
+/* Replace the default data output functions with a user supplied one(s).
+ * If buffered output is not used, then output_flush_fn can be set to NULL.
+ * If PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile time
+ * output_flush_fn will be ignored (and thus can be NULL).
+ */
+extern PNG_EXPORT(void,png_set_write_fn) PNGARG((png_structp png_ptr,
+ png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn));
+
+/* Replace the default data input function with a user supplied one. */
+extern PNG_EXPORT(void,png_set_read_fn) PNGARG((png_structp png_ptr,
+ png_voidp io_ptr, png_rw_ptr read_data_fn));
+
+/* Return the user pointer associated with the I/O functions */
+extern PNG_EXPORT(png_voidp,png_get_io_ptr) PNGARG((png_structp png_ptr));
+
+extern PNG_EXPORT(void,png_set_read_status_fn) PNGARG((png_structp png_ptr,
+ png_read_status_ptr read_row_fn));
+
+extern PNG_EXPORT(void,png_set_write_status_fn) PNGARG((png_structp png_ptr,
+ png_write_status_ptr write_row_fn));
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* Replace the default memory allocation functions with user supplied one(s). */
+extern PNG_EXPORT(void,png_set_mem_fn) PNGARG((png_structp png_ptr,
+ png_voidp mem_ptr, png_malloc_ptr malloc_fn, png_free_ptr free_fn));
+/* Return the user pointer associated with the memory functions */
+extern PNG_EXPORT(png_voidp,png_get_mem_ptr) PNGARG((png_structp png_ptr));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_read_user_transform_fn) PNGARG((png_structp
+ png_ptr, png_user_transform_ptr read_user_transform_fn));
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_write_user_transform_fn) PNGARG((png_structp
+ png_ptr, png_user_transform_ptr write_user_transform_fn));
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+extern PNG_EXPORT(void,png_set_user_transform_info) PNGARG((png_structp
+ png_ptr, png_voidp user_transform_ptr, int user_transform_depth,
+ int user_transform_channels));
+/* Return the user pointer associated with the user transform functions */
+extern PNG_EXPORT(png_voidp,png_get_user_transform_ptr)
+ PNGARG((png_structp png_ptr));
+#endif
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+extern PNG_EXPORT(void,png_set_read_user_chunk_fn) PNGARG((png_structp png_ptr,
+ png_voidp user_chunk_ptr, png_user_chunk_ptr read_user_chunk_fn));
+extern PNG_EXPORT(png_voidp,png_get_user_chunk_ptr) PNGARG((png_structp
+ png_ptr));
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+/* Sets the function callbacks for the push reader, and a pointer to a
+ * user-defined structure available to the callback functions.
+ */
+extern PNG_EXPORT(void,png_set_progressive_read_fn) PNGARG((png_structp png_ptr,
+ png_voidp progressive_ptr,
+ png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+ png_progressive_end_ptr end_fn));
+
+/* returns the user pointer associated with the push read functions */
+extern PNG_EXPORT(png_voidp,png_get_progressive_ptr)
+ PNGARG((png_structp png_ptr));
+
+/* function to be called when data becomes available */
+extern PNG_EXPORT(void,png_process_data) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytep buffer, png_size_t buffer_size));
+
+/* function that combines rows. Not very much different than the
+ * png_combine_row() call. Is this even used?????
+ */
+extern PNG_EXPORT(void,png_progressive_combine_row) PNGARG((png_structp png_ptr,
+ png_bytep old_row, png_bytep new_row));
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+extern PNG_EXPORT(png_voidp,png_malloc) PNGARG((png_structp png_ptr,
+ png_uint_32 size));
+
+#if defined(PNG_1_0_X)
+# define png_malloc_warn png_malloc
+#else
+/* Added at libpng version 1.2.4 */
+extern PNG_EXPORT(png_voidp,png_malloc_warn) PNGARG((png_structp png_ptr,
+ png_uint_32 size));
+#endif
+
+/* frees a pointer allocated by png_malloc() */
+extern PNG_EXPORT(void,png_free) PNGARG((png_structp png_ptr, png_voidp ptr));
+
+#if defined(PNG_1_0_X)
+/* Function to allocate memory for zlib. */
+extern PNG_EXPORT(voidpf,png_zalloc) PNGARG((voidpf png_ptr, uInt items,
+ uInt size));
+
+/* Function to free memory for zlib */
+extern PNG_EXPORT(void,png_zfree) PNGARG((voidpf png_ptr, voidpf ptr));
+#endif
+
+/* Free data that was allocated internally */
+extern PNG_EXPORT(void,png_free_data) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 free_me, int num));
+#ifdef PNG_FREE_ME_SUPPORTED
+/* Reassign responsibility for freeing existing data, whether allocated
+ * by libpng or by the application */
+extern PNG_EXPORT(void,png_data_freer) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int freer, png_uint_32 tqmask));
+#endif
+/* assignments for png_data_freer */
+#define PNG_DESTROY_WILL_FREE_DATA 1
+#define PNG_SET_WILL_FREE_DATA 1
+#define PNG_USER_WILL_FREE_DATA 2
+/* Flags for png_ptr->free_me and info_ptr->free_me */
+#define PNG_FREE_HIST 0x0008
+#define PNG_FREE_ICCP 0x0010
+#define PNG_FREE_SPLT 0x0020
+#define PNG_FREE_ROWS 0x0040
+#define PNG_FREE_PCAL 0x0080
+#define PNG_FREE_SCAL 0x0100
+#define PNG_FREE_UNKN 0x0200
+#define PNG_FREE_LIST 0x0400
+#define PNG_FREE_PLTE 0x1000
+#define PNG_FREE_TRNS 0x2000
+#define PNG_FREE_TEXT 0x4000
+#define PNG_FREE_ALL 0x7fff
+#define PNG_FREE_MUL 0x4220 /* PNG_FREE_SPLT|PNG_FREE_TEXT|PNG_FREE_UNKN */
+
+#ifdef PNG_USER_MEM_SUPPORTED
+extern PNG_EXPORT(png_voidp,png_malloc_default) PNGARG((png_structp png_ptr,
+ png_uint_32 size));
+extern PNG_EXPORT(void,png_free_default) PNGARG((png_structp png_ptr,
+ png_voidp ptr));
+#endif
+
+extern PNG_EXPORT(png_voidp,png_memcpy_check) PNGARG((png_structp png_ptr,
+ png_voidp s1, png_voidp s2, png_uint_32 size));
+
+extern PNG_EXPORT(png_voidp,png_memset_check) PNGARG((png_structp png_ptr,
+ png_voidp s1, int value, png_uint_32 size));
+
+#if defined(USE_FAR_KEYWORD) /* memory model conversion function */
+extern void *png_far_to_near PNGARG((png_structp png_ptr,png_voidp ptr,
+ int check));
+#endif /* USE_FAR_KEYWORD */
+
+/* Fatal error in PNG image of libpng - can't continue */
+extern PNG_EXPORT(void,png_error) PNGARG((png_structp png_ptr,
+ png_const_charp error_message));
+
+/* The same, but the chunk name is prepended to the error string. */
+extern PNG_EXPORT(void,png_chunk_error) PNGARG((png_structp png_ptr,
+ png_const_charp error_message));
+
+/* Non-fatal error in libpng. Can continue, but may have a problem. */
+extern PNG_EXPORT(void,png_warning) PNGARG((png_structp png_ptr,
+ png_const_charp warning_message));
+
+/* Non-fatal error in libpng, chunk name is prepended to message. */
+extern PNG_EXPORT(void,png_chunk_warning) PNGARG((png_structp png_ptr,
+ png_const_charp warning_message));
+
+/* The png_set_<chunk> functions are for storing values in the png_info_struct.
+ * Similarly, the png_get_<chunk> calls are used to read values from the
+ * png_info_struct, either storing the parameters in the passed variables, or
+ * setting pointers into the png_info_struct where the data is stored. The
+ * png_get_<chunk> functions return a non-zero value if the data was available
+ * in info_ptr, or return zero and do not change any of the parameters if the
+ * data was not available.
+ *
+ * These functions should be used instead of directly accessing png_info
+ * to avoid problems with future changes in the size and internal tqlayout of
+ * png_info_struct.
+ */
+/* Returns "flag" if chunk data is valid in info_ptr. */
+extern PNG_EXPORT(png_uint_32,png_get_valid) PNGARG((png_structp png_ptr,
+png_infop info_ptr, png_uint_32 flag));
+
+/* Returns number of bytes needed to hold a transformed row. */
+extern PNG_EXPORT(png_uint_32,png_get_rowbytes) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* Returns row_pointers, which is an array of pointers to scanlines that was
+returned from png_read_png(). */
+extern PNG_EXPORT(png_bytepp,png_get_rows) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+/* Set row_pointers, which is an array of pointers to scanlines for use
+by png_write_png(). */
+extern PNG_EXPORT(void,png_set_rows) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytepp row_pointers));
+#endif
+
+/* Returns number of color channels in image. */
+extern PNG_EXPORT(png_byte,png_get_channels) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* Returns image width in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_width) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image height in pixels. */
+extern PNG_EXPORT(png_uint_32, png_get_image_height) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image bit_depth. */
+extern PNG_EXPORT(png_byte, png_get_bit_depth) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image color_type. */
+extern PNG_EXPORT(png_byte, png_get_color_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image filter_type. */
+extern PNG_EXPORT(png_byte, png_get_filter_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image interlace_type. */
+extern PNG_EXPORT(png_byte, png_get_interlace_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image compression_type. */
+extern PNG_EXPORT(png_byte, png_get_compression_type) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns image resolution in pixels per meter, from pHYs chunk data. */
+extern PNG_EXPORT(png_uint_32, png_get_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_x_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_uint_32, png_get_y_pixels_per_meter) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+/* Returns pixel aspect ratio, computed from pHYs chunk data. */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(float, png_get_pixel_aspect_ratio) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+#endif
+
+/* Returns image x, y offset in pixels or microns, from oFFs chunk data. */
+extern PNG_EXPORT(png_int_32, png_get_x_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_y_offset_pixels) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_x_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+extern PNG_EXPORT(png_int_32, png_get_y_offset_microns) PNGARG((png_structp
+png_ptr, png_infop info_ptr));
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+/* Returns pointer to signature string read from PNG header */
+extern PNG_EXPORT(png_bytep,png_get_signature) PNGARG((png_structp png_ptr,
+png_infop info_ptr));
+
+#if defined(PNG_bKGD_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_bKGD) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_16p *background));
+#endif
+
+#if defined(PNG_bKGD_SUPPORTED)
+extern PNG_EXPORT(void,png_set_bKGD) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_16p background));
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double *white_x, double *white_y, double *red_x,
+ double *red_y, double *green_x, double *green_y, double *blue_x,
+ double *blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_cHRM_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point *int_white_x, png_fixed_point
+ *int_white_y, png_fixed_point *int_red_x, png_fixed_point *int_red_y,
+ png_fixed_point *int_green_x, png_fixed_point *int_green_y, png_fixed_point
+ *int_blue_x, png_fixed_point *int_blue_y));
+#endif
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double white_x, double white_y, double red_x,
+ double red_y, double green_x, double green_y, double blue_x, double blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_cHRM_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point int_white_x, png_fixed_point int_white_y,
+ png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+ int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+ png_fixed_point int_blue_y));
+#endif
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_gAMA) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double *file_gamma));
+#endif
+extern PNG_EXPORT(png_uint_32,png_get_gAMA_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point *int_file_gamma));
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_gAMA) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, double file_gamma));
+#endif
+extern PNG_EXPORT(void,png_set_gAMA_fixed) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_fixed_point int_file_gamma));
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_hIST) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_16p *hist));
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+extern PNG_EXPORT(void,png_set_hIST) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_16p hist));
+#endif
+
+extern PNG_EXPORT(png_uint_32,png_get_IHDR) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 *width, png_uint_32 *height,
+ int *bit_depth, int *color_type, int *interlace_method,
+ int *compression_method, int *filter_method));
+
+extern PNG_EXPORT(void,png_set_IHDR) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_method, int compression_method,
+ int filter_method));
+
+#if defined(PNG_oFFs_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_oFFs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_int_32 *offset_x, png_int_32 *offset_y,
+ int *unit_type));
+#endif
+
+#if defined(PNG_oFFs_SUPPORTED)
+extern PNG_EXPORT(void,png_set_oFFs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_int_32 offset_x, png_int_32 offset_y,
+ int unit_type));
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_pCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charp *purpose, png_int_32 *X0, png_int_32 *X1,
+ int *type, int *nparams, png_charp *units, png_charpp *params));
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+extern PNG_EXPORT(void,png_set_pCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charp purpose, png_int_32 X0, png_int_32 X1,
+ int type, int nparams, png_charp units, png_charpp params));
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_pHYs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type));
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+extern PNG_EXPORT(void,png_set_pHYs) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 res_x, png_uint_32 res_y, int unit_type));
+#endif
+
+extern PNG_EXPORT(png_uint_32,png_get_PLTE) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_colorp *palette, int *num_palette));
+
+extern PNG_EXPORT(void,png_set_PLTE) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_colorp palette, int num_palette));
+
+#if defined(PNG_sBIT_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sBIT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_8p *sig_bit));
+#endif
+
+#if defined(PNG_sBIT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sBIT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_color_8p sig_bit));
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sRGB) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int *intent));
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sRGB) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int intent));
+extern PNG_EXPORT(void,png_set_sRGB_gAMA_and_cHRM) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int intent));
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_iCCP) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charpp name, int *compression_type,
+ png_charpp profile, png_uint_32 *proflen));
+ /* Note to maintainer: profile should be png_bytepp */
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+extern PNG_EXPORT(void,png_set_iCCP) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_charp name, int compression_type,
+ png_charp profile, png_uint_32 proflen));
+ /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_sPLT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_sPLT_tpp entries));
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_sPLT) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_sPLT_tp entries, int nentries));
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+/* png_get_text also returns the number of text chunks in *num_text */
+extern PNG_EXPORT(png_uint_32,png_get_text) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_textp *text_ptr, int *num_text));
+#endif
+
+/*
+ * Note while png_set_text() will accept a structure whose text,
+ * language, and translated keywords are NULL pointers, the structure
+ * returned by png_get_text will always contain regular
+ * zero-terminated C strings. They might be empty strings but
+ * they will never be NULL pointers.
+ */
+
+#if defined(PNG_TEXT_SUPPORTED)
+extern PNG_EXPORT(void,png_set_text) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_textp text_ptr, int num_text));
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_tIME) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_timep *mod_time));
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+extern PNG_EXPORT(void,png_set_tIME) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_timep mod_time));
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+extern PNG_EXPORT(png_uint_32,png_get_tRNS) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytep *trans, int *num_trans,
+ png_color_16p *trans_values));
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+extern PNG_EXPORT(void,png_set_tRNS) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_bytep trans, int num_trans,
+ png_color_16p trans_values));
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int *unit, double *width, double *height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_get_sCAL_s) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int *unit, png_charpp swidth, png_charpp sheight));
+#endif
+#endif
+#endif /* PNG_sCAL_SUPPORTED */
+
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int unit, double width, double height));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+extern PNG_EXPORT(void,png_set_sCAL_s) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int unit, png_charp swidth, png_charp sheight));
+#endif
+#endif /* PNG_sCAL_SUPPORTED || PNG_WRITE_sCAL_SUPPORTED */
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+/* provide a list of chunks and how they are to be handled, if the built-in
+ handling or default unknown chunk handling is not desired. Any chunks not
+ listed will be handled in the default manner. The IHDR and IEND chunks
+ must not be listed.
+ keep = 0: follow default behavour
+ = 1: do not keep
+ = 2: keep only if safe-to-copy
+ = 3: keep even if unsafe-to-copy
+*/
+extern PNG_EXPORT(void, png_set_keep_unknown_chunks) PNGARG((png_structp
+ png_ptr, int keep, png_bytep chunk_list, int num_chunks));
+extern PNG_EXPORT(void, png_set_unknown_chunks) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns));
+extern PNG_EXPORT(void, png_set_unknown_chunk_location)
+ PNGARG((png_structp png_ptr, png_infop info_ptr, int chunk, int location));
+extern PNG_EXPORT(png_uint_32,png_get_unknown_chunks) PNGARG((png_structp
+ png_ptr, png_infop info_ptr, png_unknown_chunkpp entries));
+#endif
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+PNG_EXPORT(int,png_handle_as_unknown) PNGARG((png_structp png_ptr, png_bytep
+ chunk_name));
+#endif
+
+/* Png_free_data() will turn off the "valid" flag for anything it frees.
+ If you need to turn it off for a chunk that your application has freed,
+ you can use png_set_invalid(png_ptr, info_ptr, PNG_INFO_CHNK); */
+extern PNG_EXPORT(void, png_set_invalid) PNGARG((png_structp png_ptr,
+ png_infop info_ptr, int tqmask));
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+/* The "params" pointer is currently not used and is for future expansion. */
+extern PNG_EXPORT(void, png_read_png) PNGARG((png_structp png_ptr,
+ png_infop info_ptr,
+ int transforms,
+ png_voidp params));
+extern PNG_EXPORT(void, png_write_png) PNGARG((png_structp png_ptr,
+ png_infop info_ptr,
+ int transforms,
+ png_voidp params));
+#endif
+
+/* Define PNG_DEBUG at compile time for debugging information. Higher
+ * numbers for PNG_DEBUG mean more debugging information. This has
+ * only been added since version 0.95 so it is not implemented throughout
+ * libpng yet, but more support will be added as needed.
+ */
+#ifdef PNG_DEBUG
+#if (PNG_DEBUG > 0)
+#if !defined(PNG_DEBUG_FILE) && defined(_MSC_VER)
+#include <crtdbg.h>
+#if (PNG_DEBUG > 1)
+#define png_debug(l,m) _RPT0(_CRT_WARN,m)
+#define png_debug1(l,m,p1) _RPT1(_CRT_WARN,m,p1)
+#define png_debug2(l,m,p1,p2) _RPT2(_CRT_WARN,m,p1,p2)
+#endif
+#else /* PNG_DEBUG_FILE || !_MSC_VER */
+#ifndef PNG_DEBUG_FILE
+#define PNG_DEBUG_FILE stderr
+#endif /* PNG_DEBUG_FILE */
+#if (PNG_DEBUG > 1)
+#define png_debug(l,m) \
+{ \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":"")))); \
+}
+#define png_debug1(l,m,p1) \
+{ \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1); \
+}
+#define png_debug2(l,m,p1,p2) \
+{ \
+ int num_tabs=l; \
+ fprintf(PNG_DEBUG_FILE,"%s"m,(num_tabs==1 ? "\t" : \
+ (num_tabs==2 ? "\t\t":(num_tabs>2 ? "\t\t\t":""))),p1,p2); \
+}
+#endif /* (PNG_DEBUG > 1) */
+#endif /* _MSC_VER */
+#endif /* (PNG_DEBUG > 0) */
+#endif /* PNG_DEBUG */
+#ifndef png_debug
+#define png_debug(l, m)
+#endif
+#ifndef png_debug1
+#define png_debug1(l, m, p1)
+#endif
+#ifndef png_debug2
+#define png_debug2(l, m, p1, p2)
+#endif
+
+extern PNG_EXPORT(png_bytep,png_sig_bytes) PNGARG((void));
+
+extern PNG_EXPORT(png_charp,png_get_copyright) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_ver) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_header_version) PNGARG((png_structp png_ptr));
+extern PNG_EXPORT(png_charp,png_get_libpng_ver) PNGARG((png_structp png_ptr));
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+extern PNG_EXPORT(png_uint_32,png_permit_mng_features) PNGARG((png_structp
+ png_ptr, png_uint_32 mng_features_permitted));
+#endif
+
+/* Added to version 1.2.0 */
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+#define PNG_ASM_FLAG_MMX_SUPPORT_COMPILED 0x01 /* not user-settable */
+#define PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU 0x02 /* not user-settable */
+#define PNG_ASM_FLAG_MMX_READ_COMBINE_ROW 0x04
+#define PNG_ASM_FLAG_MMX_READ_INTERLACE 0x08
+#define PNG_ASM_FLAG_MMX_READ_FILTER_SUB 0x10
+#define PNG_ASM_FLAG_MMX_READ_FILTER_UP 0x20
+#define PNG_ASM_FLAG_MMX_READ_FILTER_AVG 0x40
+#define PNG_ASM_FLAG_MMX_READ_FILTER_PAETH 0x80
+#define PNG_ASM_FLAGS_INITIALIZED 0x80000000 /* not user-settable */
+
+#define PNG_MMX_READ_FLAGS ( PNG_ASM_FLAG_MMX_READ_COMBINE_ROW \
+ | PNG_ASM_FLAG_MMX_READ_INTERLACE \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_SUB \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_UP \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_AVG \
+ | PNG_ASM_FLAG_MMX_READ_FILTER_PAETH )
+#define PNG_MMX_WRITE_FLAGS ( 0 )
+
+#define PNG_MMX_FLAGS ( PNG_ASM_FLAG_MMX_SUPPORT_COMPILED \
+ | PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU \
+ | PNG_MMX_READ_FLAGS \
+ | PNG_MMX_WRITE_FLAGS )
+
+#define PNG_SELECT_READ 1
+#define PNG_SELECT_WRITE 2
+
+
+#if !defined(PNG_1_0_X)
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_mmx_flagtqmask)
+ PNGARG((int flag_select, int *compilerID));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_asm_flagtqmask)
+ PNGARG((int flag_select));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_asm_flags)
+ PNGARG((png_structp png_ptr));
+
+/* pngget.c */
+extern PNG_EXPORT(png_byte,png_get_mmx_bitdepth_threshold)
+ PNGARG((png_structp png_ptr));
+
+/* pngget.c */
+extern PNG_EXPORT(png_uint_32,png_get_mmx_rowbytes_threshold)
+ PNGARG((png_structp png_ptr));
+
+/* pngset.c */
+extern PNG_EXPORT(void,png_set_asm_flags)
+ PNGARG((png_structp png_ptr, png_uint_32 asm_flags));
+
+/* pngset.c */
+extern PNG_EXPORT(void,png_set_mmx_thresholds)
+ PNGARG((png_structp png_ptr, png_byte mmx_bitdepth_threshold,
+ png_uint_32 mmx_rowbytes_threshold));
+
+#endif /* PNG_1_0_X */
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#if !defined(PNG_1_0_X)
+/* png.c, pnggccrd.c, or pngvcrd.c */
+extern PNG_EXPORT(int,png_mmx_support) PNGARG((void));
+
+/* Strip the prepended error numbers ("#nnn ") from error and warning
+ * messages before passing them to the error or warning handler. */
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+extern PNG_EXPORT(void,png_set_strip_error_numbers) PNGARG((png_structp
+ png_ptr, png_uint_32 strip_mode));
+#endif
+#endif /* PNG_1_0_X */
+
+/* Maintainer: Put new public prototypes here ^, in libpng.3, and project defs */
+
+#define PNG_HEADER_VERSION_STRING \
+ " libpng version 1.2.5 - October 3, 2002 (header)\n"
+
+#ifdef PNG_READ_COMPOSITE_NODIV_SUPPORTED
+/* With these routines we avoid an integer divide, which will be slower on
+ * most machines. However, it does take more operations than the corresponding
+ * divide method, so it may be slower on a few RISC systems. There are two
+ * shifts (by 8 or 16 bits) and an addition, versus a single integer divide.
+ *
+ * Note that the rounding factors are NOT supposed to be the same! 128 and
+ * 32768 are correct for the NODIV code; 127 and 32767 are correct for the
+ * standard method.
+ *
+ * [Optimized code by Greg Roelofs and Mark Adler...blame us for bugs. :-) ]
+ */
+
+ /* fg and bg should be in `gamma 1.0' space; alpha is the opacity */
+
+# define png_composite(composite, fg, alpha, bg) \
+ { png_uint_16 temp = (png_uint_16)((png_uint_16)(fg) * (png_uint_16)(alpha) \
+ + (png_uint_16)(bg)*(png_uint_16)(255 - \
+ (png_uint_16)(alpha)) + (png_uint_16)128); \
+ (composite) = (png_byte)((temp + (temp >> 8)) >> 8); }
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ { png_uint_32 temp = (png_uint_32)((png_uint_32)(fg) * (png_uint_32)(alpha) \
+ + (png_uint_32)(bg)*(png_uint_32)(65535L - \
+ (png_uint_32)(alpha)) + (png_uint_32)32768L); \
+ (composite) = (png_uint_16)((temp + (temp >> 16)) >> 16); }
+
+#else /* standard method using integer division */
+
+# define png_composite(composite, fg, alpha, bg) \
+ (composite) = (png_byte)(((png_uint_16)(fg) * (png_uint_16)(alpha) + \
+ (png_uint_16)(bg) * (png_uint_16)(255 - (png_uint_16)(alpha)) + \
+ (png_uint_16)127) / 255)
+
+# define png_composite_16(composite, fg, alpha, bg) \
+ (composite) = (png_uint_16)(((png_uint_32)(fg) * (png_uint_32)(alpha) + \
+ (png_uint_32)(bg)*(png_uint_32)(65535L - (png_uint_32)(alpha)) + \
+ (png_uint_32)32767) / (png_uint_32)65535L)
+
+#endif /* PNG_READ_COMPOSITE_NODIV_SUPPORTED */
+
+/* These next functions are used internally in the code. They generally
+ * shouldn't be used unless you are writing code to add or tqreplace some
+ * functionality in libpng. More information about most functions can
+ * be found in the files where the functions are located.
+ */
+
+#if defined(PNG_INTERNAL)
+
+/* Various modes of operation. Note that after an init, mode is set to
+ * zero automatically when the structure is created.
+ */
+#define PNG_HAVE_IHDR 0x01
+#define PNG_HAVE_PLTE 0x02
+#define PNG_HAVE_IDAT 0x04
+#define PNG_AFTER_IDAT 0x08
+#define PNG_HAVE_IEND 0x10
+#define PNG_HAVE_gAMA 0x20
+#define PNG_HAVE_cHRM 0x40
+#define PNG_HAVE_sRGB 0x80
+#define PNG_HAVE_CHUNK_HEADER 0x100
+#define PNG_WROTE_tIME 0x200
+#define PNG_WROTE_INFO_BEFORE_PLTE 0x400
+#define PNG_BACKGROUND_IS_GRAY 0x800
+#define PNG_HAVE_PNG_SIGNATURE 0x1000
+
+/* flags for the transformations the PNG library does on the image data */
+#define PNG_BGR 0x0001
+#define PNG_INTERLACE 0x0002
+#define PNG_PACK 0x0004
+#define PNG_SHIFT 0x0008
+#define PNG_SWAP_BYTES 0x0010
+#define PNG_INVERT_MONO 0x0020
+#define PNG_DITHER 0x0040
+#define PNG_BACKGROUND 0x0080
+#define PNG_BACKGROUND_EXPAND 0x0100
+ /* 0x0200 unused */
+#define PNG_16_TO_8 0x0400
+#define PNG_RGBA 0x0800
+#define PNG_EXPAND 0x1000
+#define PNG_GAMMA 0x2000
+#define PNG_GRAY_TO_RGB 0x4000
+#define PNG_FILLER 0x8000L
+#define PNG_PACKSWAP 0x10000L
+#define PNG_SWAP_ALPHA 0x20000L
+#define PNG_STRIP_ALPHA 0x40000L
+#define PNG_INVERT_ALPHA 0x80000L
+#define PNG_USER_TRANSFORM 0x100000L
+#define PNG_RGB_TO_GRAY_ERR 0x200000L
+#define PNG_RGB_TO_GRAY_WARN 0x400000L
+#define PNG_RGB_TO_GRAY 0x600000L /* two bits, RGB_TO_GRAY_ERR|WARN */
+
+/* flags for png_create_struct */
+#define PNG_STRUCT_PNG 0x0001
+#define PNG_STRUCT_INFO 0x0002
+
+/* Scaling factor for filter heuristic weighting calculations */
+#define PNG_WEIGHT_SHIFT 8
+#define PNG_WEIGHT_FACTOR (1<<(PNG_WEIGHT_SHIFT))
+#define PNG_COST_SHIFT 3
+#define PNG_COST_FACTOR (1<<(PNG_COST_SHIFT))
+
+/* flags for the png_ptr->flags rather than declaring a byte for each one */
+#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
+#define PNG_FLAG_ZLIB_CUSTOM_LEVEL 0x0002
+#define PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL 0x0004
+#define PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS 0x0008
+#define PNG_FLAG_ZLIB_CUSTOM_METHOD 0x0010
+#define PNG_FLAG_ZLIB_FINISHED 0x0020
+#define PNG_FLAG_ROW_INIT 0x0040
+#define PNG_FLAG_FILLER_AFTER 0x0080
+#define PNG_FLAG_CRC_ANCILLARY_USE 0x0100
+#define PNG_FLAG_CRC_ANCILLARY_NOWARN 0x0200
+#define PNG_FLAG_CRC_CRITICAL_USE 0x0400
+#define PNG_FLAG_CRC_CRITICAL_IGNORE 0x0800
+#define PNG_FLAG_FREE_PLTE 0x1000
+#define PNG_FLAG_FREE_TRNS 0x2000
+#define PNG_FLAG_FREE_HIST 0x4000
+#define PNG_FLAG_KEEP_UNKNOWN_CHUNKS 0x8000L
+#define PNG_FLAG_KEEP_UNSAFE_CHUNKS 0x10000L
+#define PNG_FLAG_LIBRARY_MISMATCH 0x20000L
+#define PNG_FLAG_STRIP_ERROR_NUMBERS 0x40000L
+#define PNG_FLAG_STRIP_ERROR_TEXT 0x80000L
+#define PNG_FLAG_MALLOC_NULL_MEM_OK 0x100000L
+
+/* For use in png_set_keep_unknown, png_handle_as_unknown */
+#define HANDLE_CHUNK_AS_DEFAULT 0
+#define HANDLE_CHUNK_NEVER 1
+#define HANDLE_CHUNK_IF_SAFE 2
+#define HANDLE_CHUNK_ALWAYS 3
+
+#define PNG_FLAG_CRC_ANCILLARY_MASK (PNG_FLAG_CRC_ANCILLARY_USE | \
+ PNG_FLAG_CRC_ANCILLARY_NOWARN)
+
+#define PNG_FLAG_CRC_CRITICAL_MASK (PNG_FLAG_CRC_CRITICAL_USE | \
+ PNG_FLAG_CRC_CRITICAL_IGNORE)
+
+#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
+ PNG_FLAG_CRC_CRITICAL_MASK)
+
+/* save typing and make code easier to understand */
+#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
+ abs((int)((c1).green) - (int)((c2).green)) + \
+ abs((int)((c1).blue) - (int)((c2).blue)))
+
+/* variables declared in png.c - only it needs to define PNG_NO_EXTERN */
+#if !defined(PNG_NO_EXTERN) || defined(PNG_ALWAYS_EXTERN)
+/* place to hold the signature string for a PNG file. */
+#ifdef PNG_USE_GLOBAL_ARRAYS
+ PNG_EXPORT_VAR (const png_byte FARDATA) png_sig[8];
+#else
+#define png_sig png_sig_bytes(NULL)
+#endif
+#endif /* PNG_NO_EXTERN */
+
+/* Constant strings for known chunk types. If you need to add a chunk,
+ * define the name here, and add an invocation of the macro in png.c and
+ * wherever it's needed.
+ */
+#define PNG_IHDR const png_byte png_IHDR[5] = { 73, 72, 68, 82, '\0'}
+#define PNG_IDAT const png_byte png_IDAT[5] = { 73, 68, 65, 84, '\0'}
+#define PNG_IEND const png_byte png_IEND[5] = { 73, 69, 78, 68, '\0'}
+#define PNG_PLTE const png_byte png_PLTE[5] = { 80, 76, 84, 69, '\0'}
+#define PNG_bKGD const png_byte png_bKGD[5] = { 98, 75, 71, 68, '\0'}
+#define PNG_cHRM const png_byte png_cHRM[5] = { 99, 72, 82, 77, '\0'}
+#define PNG_gAMA const png_byte png_gAMA[5] = {103, 65, 77, 65, '\0'}
+#define PNG_hIST const png_byte png_hIST[5] = {104, 73, 83, 84, '\0'}
+#define PNG_iCCP const png_byte png_iCCP[5] = {105, 67, 67, 80, '\0'}
+#define PNG_iTXt const png_byte png_iTXt[5] = {105, 84, 88, 116, '\0'}
+#define PNG_oFFs const png_byte png_oFFs[5] = {111, 70, 70, 115, '\0'}
+#define PNG_pCAL const png_byte png_pCAL[5] = {112, 67, 65, 76, '\0'}
+#define PNG_sCAL const png_byte png_sCAL[5] = {115, 67, 65, 76, '\0'}
+#define PNG_pHYs const png_byte png_pHYs[5] = {112, 72, 89, 115, '\0'}
+#define PNG_sBIT const png_byte png_sBIT[5] = {115, 66, 73, 84, '\0'}
+#define PNG_sPLT const png_byte png_sPLT[5] = {115, 80, 76, 84, '\0'}
+#define PNG_sRGB const png_byte png_sRGB[5] = {115, 82, 71, 66, '\0'}
+#define PNG_tEXt const png_byte png_tEXt[5] = {116, 69, 88, 116, '\0'}
+#define PNG_tIME const png_byte png_tIME[5] = {116, 73, 77, 69, '\0'}
+#define PNG_tRNS const png_byte png_tRNS[5] = {116, 82, 78, 83, '\0'}
+#define PNG_zTXt const png_byte png_zTXt[5] = {122, 84, 88, 116, '\0'}
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IHDR[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IDAT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_IEND[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_PLTE[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_bKGD[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_cHRM[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_gAMA[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_hIST[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_iCCP[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_iTXt[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_oFFs[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_pCAL[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sCAL[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_pHYs[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sBIT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sPLT[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_sRGB[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tEXt[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tIME[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_tRNS[5];
+PNG_EXPORT_VAR (const png_byte FARDATA) png_zTXt[5];
+#endif /* PNG_USE_GLOBAL_ARRAYS */
+
+
+/* Inline macros to do direct reads of bytes from the input buffer. These
+ * require that you are using an architecture that uses PNG byte ordering
+ * (MSB first) and supports unaligned data storage. I think that PowerPC
+ * in big-endian mode and 680x0 are the only ones that will support this.
+ * The x86 line of processors definitely do not. The png_get_int_32()
+ * routine also assumes we are using two's complement format for negative
+ * values, which is almost certainly true.
+ */
+#if defined(PNG_READ_BIG_ENDIAN_SUPPORTED)
+# if defined(PNG_pCAL_SUPPORTED) || defined(PNG_oFFs_SUPPORTED)
+# define png_get_int_32(buf) ( *((png_int_32p) (buf)))
+# endif
+# define png_get_uint_32(buf) ( *((png_uint_32p) (buf)))
+# define png_get_uint_16(buf) ( *((png_uint_16p) (buf)))
+#else
+# if defined(PNG_pCAL_SUPPORTED) || defined(PNG_oFFs_SUPPORTED)
+PNG_EXTERN png_int_32 png_get_int_32 PNGARG((png_bytep buf));
+# endif
+PNG_EXTERN png_uint_32 png_get_uint_32 PNGARG((png_bytep buf));
+PNG_EXTERN png_uint_16 png_get_uint_16 PNGARG((png_bytep buf));
+#endif /* !PNG_READ_BIG_ENDIAN_SUPPORTED */
+PNG_EXTERN png_uint_32 png_get_uint_31 PNGARG((png_structp png_ptr,
+ png_bytep buf));
+
+/* Initialize png_ptr struct for reading, and allocate any other memory.
+ * (old interface - DEPRECATED - use png_create_read_struct instead).
+ */
+extern PNG_EXPORT(void,png_read_init) PNGARG((png_structp png_ptr));
+#undef png_read_init
+#define png_read_init(png_ptr) png_read_init_3(&png_ptr, \
+ PNG_LIBPNG_VER_STRING, sizeof(png_struct));
+extern PNG_EXPORT(void,png_read_init_3) PNGARG((png_structpp ptr_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size));
+extern PNG_EXPORT(void,png_read_init_2) PNGARG((png_structp png_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+ png_info_size));
+
+/* Initialize png_ptr struct for writing, and allocate any other memory.
+ * (old interface - DEPRECATED - use png_create_write_struct instead).
+ */
+extern PNG_EXPORT(void,png_write_init) PNGARG((png_structp png_ptr));
+#undef png_write_init
+#define png_write_init(png_ptr) png_write_init_3(&png_ptr, \
+ PNG_LIBPNG_VER_STRING, sizeof(png_struct));
+extern PNG_EXPORT(void,png_write_init_3) PNGARG((png_structpp ptr_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size));
+extern PNG_EXPORT(void,png_write_init_2) PNGARG((png_structp png_ptr,
+ png_const_charp user_png_ver, png_size_t png_struct_size, png_size_t
+ png_info_size));
+
+/* Allocate memory for an internal libpng struct */
+PNG_EXTERN png_voidp png_create_struct PNGARG((int type));
+
+/* Free memory from internal libpng struct */
+PNG_EXTERN void png_destroy_struct PNGARG((png_voidp struct_ptr));
+
+PNG_EXTERN png_voidp png_create_struct_2 PNGARG((int type, png_malloc_ptr
+ malloc_fn, png_voidp mem_ptr));
+PNG_EXTERN void png_destroy_struct_2 PNGARG((png_voidp struct_ptr,
+ png_free_ptr free_fn, png_voidp mem_ptr));
+
+/* Free any memory that info_ptr points to and reset struct. */
+PNG_EXTERN void png_info_destroy PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+#ifndef PNG_1_0_X
+/* Function to allocate memory for zlib. */
+PNG_EXTERN voidpf png_zalloc PNGARG((voidpf png_ptr, uInt items, uInt size));
+
+/* Function to free memory for zlib */
+PNG_EXTERN void png_zfree PNGARG((voidpf png_ptr, voidpf ptr));
+
+/* Next four functions are used internally as callbacks. PNGAPI is required
+ * but not PNG_EXPORT. PNGAPI added at libpng version 1.2.3. */
+
+PNG_EXTERN void PNGAPI png_default_read_data PNGARG((png_structp png_ptr,
+ png_bytep data, png_size_t length));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void PNGAPI png_push_fill_buffer PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t length));
+#endif
+
+PNG_EXTERN void PNGAPI png_default_write_data PNGARG((png_structp png_ptr,
+ png_bytep data, png_size_t length));
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+#if !defined(PNG_NO_STDIO)
+PNG_EXTERN void PNGAPI png_default_flush PNGARG((png_structp png_ptr));
+#endif
+#endif
+#else /* PNG_1_0_X */
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_fill_buffer PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t length));
+#endif
+#endif /* PNG_1_0_X */
+
+/* Reset the CRC variable */
+PNG_EXTERN void png_reset_crc PNGARG((png_structp png_ptr));
+
+/* Write the "data" buffer to whatever output you are using. */
+PNG_EXTERN void png_write_data PNGARG((png_structp png_ptr, png_bytep data,
+ png_size_t length));
+
+/* Read data from whatever input you are using into the "data" buffer */
+PNG_EXTERN void png_read_data PNGARG((png_structp png_ptr, png_bytep data,
+ png_size_t length));
+
+/* Read bytes into buf, and update png_ptr->crc */
+PNG_EXTERN void png_crc_read PNGARG((png_structp png_ptr, png_bytep buf,
+ png_size_t length));
+
+/* Decompress data in a chunk that uses compression */
+#if defined(PNG_zTXt_SUPPORTED) || defined(PNG_iTXt_SUPPORTED) || \
+ defined(PNG_iCCP_SUPPORTED) || defined(PNG_sPLT_SUPPORTED)
+PNG_EXTERN png_charp png_decompress_chunk PNGARG((png_structp png_ptr,
+ int comp_type, png_charp chunkdata, png_size_t chunklength,
+ png_size_t prefix_length, png_size_t *data_length));
+#endif
+
+/* Read "skip" bytes, read the file crc, and (optionally) verify png_ptr->crc */
+PNG_EXTERN int png_crc_finish PNGARG((png_structp png_ptr, png_uint_32 skip));
+
+/* Read the CRC from the file and compare it to the libpng calculated CRC */
+PNG_EXTERN int png_crc_error PNGARG((png_structp png_ptr));
+
+/* Calculate the CRC over a section of data. Note that we are only
+ * passing a maximum of 64K on systems that have this as a memory limit,
+ * since this is the maximum buffer size we can specify.
+ */
+PNG_EXTERN void png_calculate_crc PNGARG((png_structp png_ptr, png_bytep ptr,
+ png_size_t length));
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+PNG_EXTERN void png_flush PNGARG((png_structp png_ptr));
+#endif
+
+
+/* Place a 32-bit number into a buffer in PNG byte order (big-endian).
+ * The only currently known PNG chunks that use signed numbers are
+ * the ancillary extension chunks, oFFs and pCAL.
+ */
+PNG_EXTERN void png_save_uint_32 PNGARG((png_bytep buf, png_uint_32 i));
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+PNG_EXTERN void png_save_int_32 PNGARG((png_bytep buf, png_int_32 i));
+#endif
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+PNG_EXTERN void png_save_uint_16 PNGARG((png_bytep buf, unsigned int i));
+
+/* simple function to write the signature */
+PNG_EXTERN void png_write_sig PNGARG((png_structp png_ptr));
+
+/* write various chunks */
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information.
+ */
+PNG_EXTERN void png_write_IHDR PNGARG((png_structp png_ptr, png_uint_32 width,
+ png_uint_32 height,
+ int bit_depth, int color_type, int compression_method, int filter_method,
+ int interlace_method));
+
+PNG_EXTERN void png_write_PLTE PNGARG((png_structp png_ptr, png_colorp palette,
+ png_uint_32 num_pal));
+
+PNG_EXTERN void png_write_IDAT PNGARG((png_structp png_ptr, png_bytep data,
+ png_size_t length));
+
+PNG_EXTERN void png_write_IEND PNGARG((png_structp png_ptr));
+
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA PNGARG((png_structp png_ptr, double file_gamma));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_gAMA_fixed PNGARG((png_structp png_ptr, png_fixed_point
+ file_gamma));
+#endif
+#endif
+
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+PNG_EXTERN void png_write_sBIT PNGARG((png_structp png_ptr, png_color_8p sbit,
+ int color_type));
+#endif
+
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM PNGARG((png_structp png_ptr,
+ double white_x, double white_y,
+ double red_x, double red_y, double green_x, double green_y,
+ double blue_x, double blue_y));
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_cHRM_fixed PNGARG((png_structp png_ptr,
+ png_fixed_point int_white_x, png_fixed_point int_white_y,
+ png_fixed_point int_red_x, png_fixed_point int_red_y, png_fixed_point
+ int_green_x, png_fixed_point int_green_y, png_fixed_point int_blue_x,
+ png_fixed_point int_blue_y));
+#endif
+#endif
+
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+PNG_EXTERN void png_write_sRGB PNGARG((png_structp png_ptr,
+ int intent));
+#endif
+
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+PNG_EXTERN void png_write_iCCP PNGARG((png_structp png_ptr,
+ png_charp name, int compression_type,
+ png_charp profile, int proflen));
+ /* Note to maintainer: profile should be png_bytep */
+#endif
+
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+PNG_EXTERN void png_write_sPLT PNGARG((png_structp png_ptr,
+ png_sPLT_tp palette));
+#endif
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+PNG_EXTERN void png_write_tRNS PNGARG((png_structp png_ptr, png_bytep trans,
+ png_color_16p values, int number, int color_type));
+#endif
+
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+PNG_EXTERN void png_write_bKGD PNGARG((png_structp png_ptr,
+ png_color_16p values, int color_type));
+#endif
+
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+PNG_EXTERN void png_write_hIST PNGARG((png_structp png_ptr, png_uint_16p hist,
+ int num_hist));
+#endif
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+PNG_EXTERN png_size_t png_check_keyword PNGARG((png_structp png_ptr,
+ png_charp key, png_charpp new_key));
+#endif
+
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+PNG_EXTERN void png_write_tEXt PNGARG((png_structp png_ptr, png_charp key,
+ png_charp text, png_size_t text_len));
+#endif
+
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+PNG_EXTERN void png_write_zTXt PNGARG((png_structp png_ptr, png_charp key,
+ png_charp text, png_size_t text_len, int compression));
+#endif
+
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+PNG_EXTERN void png_write_iTXt PNGARG((png_structp png_ptr,
+ int compression, png_charp key, png_charp lang, png_charp lang_key,
+ png_charp text));
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED) /* Added at version 1.0.14 and 1.2.4 */
+PNG_EXTERN int png_set_text_2 PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_textp text_ptr, int num_text));
+#endif
+
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+PNG_EXTERN void png_write_oFFs PNGARG((png_structp png_ptr,
+ png_int_32 x_offset, png_int_32 y_offset, int unit_type));
+#endif
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+PNG_EXTERN void png_write_pCAL PNGARG((png_structp png_ptr, png_charp purpose,
+ png_int_32 X0, png_int_32 X1, int type, int nparams,
+ png_charp units, png_charpp params));
+#endif
+
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+PNG_EXTERN void png_write_pHYs PNGARG((png_structp png_ptr,
+ png_uint_32 x_pixels_per_unit, png_uint_32 y_pixels_per_unit,
+ int unit_type));
+#endif
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+PNG_EXTERN void png_write_tIME PNGARG((png_structp png_ptr,
+ png_timep mod_time));
+#endif
+
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+PNG_EXTERN void png_write_sCAL PNGARG((png_structp png_ptr,
+ int unit, double width, double height));
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+PNG_EXTERN void png_write_sCAL_s PNGARG((png_structp png_ptr,
+ int unit, png_charp width, png_charp height));
+#endif
+#endif
+#endif
+
+/* Called when finished processing a row of data */
+PNG_EXTERN void png_write_finish_row PNGARG((png_structp png_ptr));
+
+/* Internal use only. Called before first row of data */
+PNG_EXTERN void png_write_start_row PNGARG((png_structp png_ptr));
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_build_gamma_table PNGARG((png_structp png_ptr));
+#endif
+
+/* combine a row of data, dealing with alpha, etc. if requested */
+PNG_EXTERN void png_combine_row PNGARG((png_structp png_ptr, png_bytep row,
+ int tqmask));
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+/* expand an interlaced row */
+/* OLD pre-1.0.9 interface:
+PNG_EXTERN void png_do_read_interlace PNGARG((png_row_infop row_info,
+ png_bytep row, int pass, png_uint_32 transformations));
+ */
+PNG_EXTERN void png_do_read_interlace PNGARG((png_structp png_ptr));
+#endif
+
+/* GRR TO DO (2.0 or whenever): simplify other internal calling interfaces */
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* grab pixels out of a row for an interlaced pass */
+PNG_EXTERN void png_do_write_interlace PNGARG((png_row_infop row_info,
+ png_bytep row, int pass));
+#endif
+
+/* unfilter a row */
+PNG_EXTERN void png_read_filter_row PNGARG((png_structp png_ptr,
+ png_row_infop row_info, png_bytep row, png_bytep prev_row, int filter));
+
+/* Choose the best filter to use and filter the row data */
+PNG_EXTERN void png_write_tqfind_filter PNGARG((png_structp png_ptr,
+ png_row_infop row_info));
+
+/* Write out the filtered row. */
+PNG_EXTERN void png_write_filtered_row PNGARG((png_structp png_ptr,
+ png_bytep filtered_row));
+/* finish a row while reading, dealing with interlacing passes, etc. */
+PNG_EXTERN void png_read_finish_row PNGARG((png_structp png_ptr));
+
+/* initialize the row buffers, etc. */
+PNG_EXTERN void png_read_start_row PNGARG((png_structp png_ptr));
+/* optional call to update the users info structure */
+PNG_EXTERN void png_read_transform_info PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+
+/* these are the functions that do the transformations */
+#if defined(PNG_READ_FILLER_SUPPORTED)
+PNG_EXTERN void png_do_read_filler PNGARG((png_row_infop row_info,
+ png_bytep row, png_uint_32 filler, png_uint_32 flags));
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_read_swap_alpha PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_write_swap_alpha PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_read_invert_alpha PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_write_invert_alpha PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+ defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+PNG_EXTERN void png_do_strip_filler PNGARG((png_row_infop row_info,
+ png_bytep row, png_uint_32 flags));
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+PNG_EXTERN void png_do_swap PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED) || defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+PNG_EXTERN void png_do_packswap PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+PNG_EXTERN int png_do_rgb_to_gray PNGARG((png_structp png_ptr, png_row_infop
+ row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+PNG_EXTERN void png_do_gray_to_rgb PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+PNG_EXTERN void png_do_unpack PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+PNG_EXTERN void png_do_unshift PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_8p sig_bits));
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+PNG_EXTERN void png_do_invert PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+PNG_EXTERN void png_do_chop PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+PNG_EXTERN void png_do_dither PNGARG((png_row_infop row_info,
+ png_bytep row, png_bytep palette_lookup, png_bytep dither_lookup));
+
+# if defined(PNG_CORRECT_PALETTE_SUPPORTED)
+PNG_EXTERN void png_correct_palette PNGARG((png_structp png_ptr,
+ png_colorp palette, int num_palette));
+# endif
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+PNG_EXTERN void png_do_bgr PNGARG((png_row_infop row_info, png_bytep row));
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+PNG_EXTERN void png_do_pack PNGARG((png_row_infop row_info,
+ png_bytep row, png_uint_32 bit_depth));
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+PNG_EXTERN void png_do_shift PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_8p bit_depth));
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_16p trans_values, png_color_16p background,
+ png_color_16p background_1,
+ png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+ png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+ png_uint_16pp gamma_16_to_1, int gamma_shift));
+#else
+PNG_EXTERN void png_do_background PNGARG((png_row_infop row_info, png_bytep row,
+ png_color_16p trans_values, png_color_16p background));
+#endif
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+PNG_EXTERN void png_do_gamma PNGARG((png_row_infop row_info, png_bytep row,
+ png_bytep gamma_table, png_uint_16pp gamma_16_table,
+ int gamma_shift));
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+PNG_EXTERN void png_do_expand_palette PNGARG((png_row_infop row_info,
+ png_bytep row, png_colorp palette, png_bytep trans, int num_trans));
+PNG_EXTERN void png_do_expand PNGARG((png_row_infop row_info,
+ png_bytep row, png_color_16p trans_value));
+#endif
+
+/* The following decodes the appropriate chunks, and does error correction,
+ * then calls the appropriate callback for the chunk if it is valid.
+ */
+
+/* decode the IHDR chunk */
+PNG_EXTERN void png_handle_IHDR PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+PNG_EXTERN void png_handle_PLTE PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+PNG_EXTERN void png_handle_IEND PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+PNG_EXTERN void png_handle_bKGD PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED)
+PNG_EXTERN void png_handle_cHRM PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_gAMA_SUPPORTED)
+PNG_EXTERN void png_handle_gAMA PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_hIST_SUPPORTED)
+PNG_EXTERN void png_handle_hIST PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_iCCP_SUPPORTED)
+extern void png_handle_iCCP PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+PNG_EXTERN void png_handle_iTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_oFFs_SUPPORTED)
+PNG_EXTERN void png_handle_oFFs PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+PNG_EXTERN void png_handle_pCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+PNG_EXTERN void png_handle_pHYs PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sBIT_SUPPORTED)
+PNG_EXTERN void png_handle_sBIT PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED)
+PNG_EXTERN void png_handle_sCAL PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+extern void png_handle_sPLT PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+PNG_EXTERN void png_handle_sRGB PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+PNG_EXTERN void png_handle_tEXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tIME_SUPPORTED)
+PNG_EXTERN void png_handle_tIME PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+PNG_EXTERN void png_handle_tRNS PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+PNG_EXTERN void png_handle_zTXt PNGARG((png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 length));
+#endif
+
+PNG_EXTERN void png_handle_unknown PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length));
+
+PNG_EXTERN void png_check_chunk_name PNGARG((png_structp png_ptr,
+ png_bytep chunk_name));
+
+/* handle the transformations for reading and writing */
+PNG_EXTERN void png_do_read_transformations PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_do_write_transformations PNGARG((png_structp png_ptr));
+
+PNG_EXTERN void png_init_read_transformations PNGARG((png_structp png_ptr));
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+PNG_EXTERN void png_push_read_chunk PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_push_read_sig PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_push_check_crc PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_crc_skip PNGARG((png_structp png_ptr,
+ png_uint_32 length));
+PNG_EXTERN void png_push_crc_finish PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_save_buffer PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_restore_buffer PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t buffer_length));
+PNG_EXTERN void png_push_read_IDAT PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_process_IDAT_data PNGARG((png_structp png_ptr,
+ png_bytep buffer, png_size_t buffer_length));
+PNG_EXTERN void png_push_process_row PNGARG((png_structp png_ptr));
+PNG_EXTERN void png_push_handle_unknown PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_have_info PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_push_have_end PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_push_have_row PNGARG((png_structp png_ptr, png_bytep row));
+PNG_EXTERN void png_push_read_end PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_process_some_data PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+PNG_EXTERN void png_read_push_finish_row PNGARG((png_structp png_ptr));
+#if defined(PNG_READ_tEXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_tEXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_tEXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_zTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_zTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+PNG_EXTERN void png_push_handle_iTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr, png_uint_32 length));
+PNG_EXTERN void png_push_read_iTXt PNGARG((png_structp png_ptr,
+ png_infop info_ptr));
+#endif
+
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+#ifdef PNG_MNG_FEATURES_SUPPORTED
+PNG_EXTERN void png_do_read_intrapixel PNGARG((png_row_infop row_info,
+ png_bytep row));
+PNG_EXTERN void png_do_write_intrapixel PNGARG((png_row_infop row_info,
+ png_bytep row));
+#endif
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+/* png.c */ /* PRIVATE */
+PNG_EXTERN void png_init_mmx_flags PNGARG((png_structp png_ptr));
+#endif
+/* Maintainer: Put new private prototypes here ^ and in libpngpf.3 */
+
+#endif /* PNG_INTERNAL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PNG_VERSION_INFO_ONLY */
+/* do not put anything past this line */
+#endif /* PNG_H */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngasmrd.h b/tqtinterface/qt4/src/3rdparty/libpng/pngasmrd.h
new file mode 100644
index 0000000..d086d8c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngasmrd.h
@@ -0,0 +1,11 @@
+/* pngasmrd.h - assembler version of utilities to read a PNG file
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 2002 Glenn Randers-Pehrson
+ *
+ */
+
+/* This file is obsolete in libpng-1.0.9 and later; its contents now appear
+ * at the end of pngconf.h.
+ */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngbar.jpg b/tqtinterface/qt4/src/3rdparty/libpng/pngbar.jpg
new file mode 100644
index 0000000..70ba8d8
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngbar.jpg
Binary files differ
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngbar.png b/tqtinterface/qt4/src/3rdparty/libpng/pngbar.png
new file mode 100644
index 0000000..7b4b75e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngbar.png
Binary files differ
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngconf.h b/tqtinterface/qt4/src/3rdparty/libpng/pngconf.h
new file mode 100644
index 0000000..bd4893b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngconf.h
@@ -0,0 +1,1364 @@
+/* pngconf.h - machine configurable file for libpng
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+/* Any machine specific code is near the front of this file, so if you
+ * are configuring libpng for a machine, you may want to read the section
+ * starting here down to where it starts to typedef png_color, png_text,
+ * and png_info.
+ */
+
+#ifndef PNGCONF_H
+#define PNGCONF_H
+
+#ifndef __i386__ /* change this if MMX/SSE become supported on x86_64! */
+#define PNG_NO_ASSEMBLER_CODE
+#endif
+
+/* This is the size of the compression buffer, and thus the size of
+ * an IDAT chunk. Make this whatever size you feel is best for your
+ * machine. One of these will be allocated per png_struct. When this
+ * is full, it writes the data to the disk, and does some other
+ * calculations. Making this an extremely small size will slow
+ * the library down, but you may want to experiment to determine
+ * where it becomes significant, if you are concerned with memory
+ * usage. Note that zlib allocates at least 32Kb also. For readers,
+ * this describes the size of the buffer available to read the data in.
+ * Unless this gets smaller than the size of a row (compressed),
+ * it should not make much difference how big this is.
+ */
+
+#ifndef PNG_ZBUF_SIZE
+# define PNG_ZBUF_SIZE 8192
+#endif
+
+/* Enable if you want a write-only libpng */
+
+#ifndef PNG_NO_READ_SUPPORTED
+# define PNG_READ_SUPPORTED
+#endif
+
+/* Enable if you want a read-only libpng */
+
+#ifndef PNG_NO_WRITE_SUPPORTED
+# define PNG_WRITE_SUPPORTED
+#endif
+
+/* Enabled by default in 1.2.0. You can disable this if you don't need to
+ support PNGs that are embedded in MNG datastreams */
+#if !defined(PNG_1_0_X) && !defined(PNG_NO_MNG_FEATURES)
+# ifndef PNG_MNG_FEATURES_SUPPORTED
+# define PNG_MNG_FEATURES_SUPPORTED
+# endif
+#endif
+
+#ifndef PNG_NO_FLOATING_POINT_SUPPORTED
+# ifndef PNG_FLOATING_POINT_SUPPORTED
+# define PNG_FLOATING_POINT_SUPPORTED
+# endif
+#endif
+
+/* If you are running on a machine where you cannot allocate more
+ * than 64K of memory at once, uncomment this. While libpng will not
+ * normally need that much memory in a chunk (unless you load up a very
+ * large file), zlib needs to know how big of a chunk it can use, and
+ * libpng thus makes sure to check any memory allocation to verify it
+ * will fit into memory.
+#define PNG_MAX_MALLOC_64K
+ */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+# define PNG_MAX_MALLOC_64K
+#endif
+
+/* Special munging to support doing things the 'cygwin' way:
+ * 'Normal' png-on-win32 defines/defaults:
+ * PNG_BUILD_DLL -- building dll
+ * PNG_USE_DLL -- building an application, linking to dll
+ * (no define) -- building static library, or building an
+ * application and linking to the static lib
+ * 'Cygwin' defines/defaults:
+ * PNG_BUILD_DLL -- (ignored) building the dll
+ * (no define) -- (ignored) building an application, linking to the dll
+ * PNG_STATIC -- (ignored) building the static lib, or building an
+ * application that links to the static lib.
+ * ALL_STATIC -- (ignored) building various static libs, or building an
+ * application that links to the static libs.
+ * Thus,
+ * a cygwin user should define either PNG_BUILD_DLL or PNG_STATIC, and
+ * this bit of #ifdefs will define the 'correct' config variables based on
+ * that. If a cygwin user *wants* to define 'PNG_USE_DLL' that's okay, but
+ * unnecessary.
+ *
+ * Also, the precedence order is:
+ * ALL_STATIC (since we can't #undef something outside our namespace)
+ * PNG_BUILD_DLL
+ * PNG_STATIC
+ * (nothing) == PNG_USE_DLL
+ *
+ * CYGWIN (2002-01-20): The preceding is now obsolete. With the advent
+ * of auto-import in binutils, we no longer need to worry about
+ * __declspec(dllexport) / __declspec(dllimport) and friends. Therefore,
+ * we don't need to worry about PNG_STATIC or ALL_STATIC when it comes
+ * to __declspec() stuff. However, we DO need to worry about
+ * PNG_BUILD_DLL and PNG_STATIC because those change some defaults
+ * such as CONSOLE_IO and whether GLOBAL_ARRAYS are allowed.
+ */
+#if defined(__CYGWIN__)
+# if defined(ALL_STATIC)
+# if defined(PNG_BUILD_DLL)
+# undef PNG_BUILD_DLL
+# endif
+# if defined(PNG_USE_DLL)
+# undef PNG_USE_DLL
+# endif
+# if defined(PNG_DLL)
+# undef PNG_DLL
+# endif
+# if !defined(PNG_STATIC)
+# define PNG_STATIC
+# endif
+# else
+# if defined (PNG_BUILD_DLL)
+# if defined(PNG_STATIC)
+# undef PNG_STATIC
+# endif
+# if defined(PNG_USE_DLL)
+# undef PNG_USE_DLL
+# endif
+# if !defined(PNG_DLL)
+# define PNG_DLL
+# endif
+# else
+# if defined(PNG_STATIC)
+# if defined(PNG_USE_DLL)
+# undef PNG_USE_DLL
+# endif
+# if defined(PNG_DLL)
+# undef PNG_DLL
+# endif
+# else
+# if !defined(PNG_USE_DLL)
+# define PNG_USE_DLL
+# endif
+# if !defined(PNG_DLL)
+# define PNG_DLL
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* This protects us against compilers that run on a windowing system
+ * and thus don't have or would rather us not use the stdio types:
+ * stdin, stdout, and stderr. The only one currently used is stderr
+ * in png_error() and png_warning(). #defining PNG_NO_CONSOLE_IO will
+ * prevent these from being compiled and used. #defining PNG_NO_STDIO
+ * will also prevent these, plus will prevent the entire set of stdio
+ * macros and functions (FILE *, printf, etc.) from being compiled and used,
+ * unless (PNG_DEBUG > 0) has been #defined.
+ *
+ * #define PNG_NO_CONSOLE_IO
+ * #define PNG_NO_STDIO
+ */
+
+#if defined(_WIN32_WCE)
+# include <windows.h>
+ /* Console I/O functions are not supported on WindowsCE */
+# define PNG_NO_CONSOLE_IO
+# ifdef PNG_DEBUG
+# undef PNG_DEBUG
+# endif
+#endif
+
+#ifdef PNG_BUILD_DLL
+# ifndef PNG_CONSOLE_IO_SUPPORTED
+# ifndef PNG_NO_CONSOLE_IO
+# define PNG_NO_CONSOLE_IO
+# endif
+# endif
+#endif
+
+# ifdef PNG_NO_STDIO
+# ifndef PNG_NO_CONSOLE_IO
+# define PNG_NO_CONSOLE_IO
+# endif
+# ifdef PNG_DEBUG
+# if (PNG_DEBUG > 0)
+# include <stdio.h>
+# endif
+# endif
+# else
+# if !defined(_WIN32_WCE)
+/* "stdio.h" functions are not supported on WindowsCE */
+# include <stdio.h>
+# endif
+# endif
+
+/* This macro protects us against machines that don't have function
+ * prototypes (ie K&R style headers). If your compiler does not handle
+ * function prototypes, define this macro and use the included ansi2knr.
+ * I've always been able to use _NO_PROTO as the indicator, but you may
+ * need to drag the empty declaration out in front of here, or change the
+ * ifdef to suit your own needs.
+ */
+#ifndef PNGARG
+
+#ifdef OF /* zlib prototype munger */
+# define PNGARG(arglist) OF(arglist)
+#else
+
+#ifdef _NO_PROTO
+# define PNGARG(arglist) ()
+# ifndef PNG_TYPECAST_NULL
+# define PNG_TYPECAST_NULL
+# endif
+#else
+# define PNGARG(arglist) arglist
+#endif /* _NO_PROTO */
+
+#endif /* OF */
+
+#endif /* PNGARG */
+
+/* Try to determine if we are compiling on a Mac. Note that testing for
+ * just __MWERKS__ is not good enough, because the Codewarrior is now used
+ * on non-Mac platforms.
+ */
+#ifndef MACOS
+# if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \
+ defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC)
+# define MACOS
+# endif
+#endif
+
+/* enough people need this for various reasons to include it here */
+#if !defined(MACOS) && !defined(RISCOS) && !defined(_WIN32_WCE)
+# include <sys/types.h>
+#endif
+
+#if !defined(PNG_SETJMP_NOT_SUPPORTED) && !defined(PNG_NO_SETJMP_SUPPORTED)
+# define PNG_SETJMP_SUPPORTED
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* This is an attempt to force a single setjmp behaviour on Linux. If
+ * the X config stuff didn't define _BSD_SOURCE we wouldn't need this.
+ */
+
+# ifdef __linux__
+# ifdef _BSD_SOURCE
+# define PNG_SAVE_BSD_SOURCE
+# undef _BSD_SOURCE
+# endif
+# ifdef _SETJMP_H
+ __png.h__ already includes setjmp.h;
+ __dont__ include it again.;
+# endif
+# endif /* __linux__ */
+
+ /* include setjmp.h for error handling */
+# include <setjmp.h>
+
+# ifdef __linux__
+# ifdef PNG_SAVE_BSD_SOURCE
+# define _BSD_SOURCE
+# undef PNG_SAVE_BSD_SOURCE
+# endif
+# endif /* __linux__ */
+#endif /* PNG_SETJMP_SUPPORTED */
+
+#ifdef BSD
+# include <strings.h>
+#else
+# include <string.h>
+#endif
+
+/* Other defines for things like memory and the like can go here. */
+#ifdef PNG_INTERNAL
+
+#include <stdlib.h>
+
+/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
+ * aren't usually used outside the library (as far as I know), so it is
+ * debatable if they should be exported at all. In the future, when it is
+ * possible to have run-time registry of chunk-handling functions, some of
+ * these will be made available again.
+#define PNG_EXTERN extern
+ */
+#define PNG_EXTERN
+
+/* Other defines specific to compilers can go here. Try to keep
+ * them inside an appropriate ifdef/endif pair for portability.
+ */
+
+#if defined(PNG_FLOATING_POINT_SUPPORTED)
+# if defined(MACOS)
+ /* We need to check that <math.h> hasn't already been included earlier
+ * as it seems it doesn't agree with <fp.h>, yet we should really use
+ * <fp.h> if possible.
+ */
+# if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
+# include <fp.h>
+# endif
+# else
+# include <math.h>
+# endif
+# if defined(_AMIGA) && defined(__SASC) && defined(_M68881)
+ /* Amiga SAS/C: We must include builtin FPU functions when compiling using
+ * MATH=68881
+ */
+# include <m68881.h>
+# endif
+#endif
+
+/* Codewarrior on NT has linking problems without this. */
+#if (defined(__MWERKS__) && defined(WIN32)) || defined(__STDC__)
+# define PNG_ALWAYS_EXTERN
+#endif
+
+/* For some reason, Borland C++ defines memcmp, etc. in mem.h, not
+ * stdlib.h like it should (I think). Or perhaps this is a C++
+ * "feature"?
+ */
+#ifdef __TURBOC__
+# include <mem.h>
+#endif
+
+#if defined(_MSC_VER) && (defined(WIN32) || defined(_Windows) || \
+ defined(_WINDOWS) || defined(_WIN32) || defined(__WIN32__))
+# include <malloc.h>
+#endif
+
+/* This controls how fine the dithering gets. As this allocates
+ * a largish chunk of memory (32K), those who are not as concerned
+ * with dithering quality can decrease some or all of these.
+ */
+#ifndef PNG_DITHER_RED_BITS
+# define PNG_DITHER_RED_BITS 5
+#endif
+#ifndef PNG_DITHER_GREEN_BITS
+# define PNG_DITHER_GREEN_BITS 5
+#endif
+#ifndef PNG_DITHER_BLUE_BITS
+# define PNG_DITHER_BLUE_BITS 5
+#endif
+
+/* This controls how fine the gamma correction becomes when you
+ * are only interested in 8 bits anyway. Increasing this value
+ * results in more memory being used, and more pow() functions
+ * being called to fill in the gamma tables. Don't set this value
+ * less then 8, and even that may not work (I haven't tested it).
+ */
+
+#ifndef PNG_MAX_GAMMA_8
+# define PNG_MAX_GAMMA_8 11
+#endif
+
+/* This controls how much a difference in gamma we can tolerate before
+ * we actually start doing gamma conversion.
+ */
+#ifndef PNG_GAMMA_THRESHOLD
+# define PNG_GAMMA_THRESHOLD 0.05
+#endif
+
+#endif /* PNG_INTERNAL */
+
+/* The following uses const char * instead of char * for error
+ * and warning message functions, so some compilers won't complain.
+ * If you do not want to use const, define PNG_NO_CONST here.
+ */
+
+#ifndef PNG_NO_CONST
+# define PNG_CONST const
+#else
+# define PNG_CONST
+#endif
+
+/* The following defines give you the ability to remove code from the
+ * library that you will not be using. I wish I could figure out how to
+ * automate this, but I can't do that without making it seriously hard
+ * on the users. So if you are not using an ability, change the #define
+ * to and #undef, and that part of the library will not be compiled. If
+ * your linker can't tqfind a function, you may want to make sure the
+ * ability is defined here. Some of these depend upon some others being
+ * defined. I haven't figured out all the interactions here, so you may
+ * have to experiment awhile to get everything to compile. If you are
+ * creating or using a shared library, you probably shouldn't touch this,
+ * as it will affect the size of the structures, and this will cause bad
+ * things to happen if the library and/or application ever change.
+ */
+
+/* Any features you will not be using can be undef'ed here */
+
+/* GR-P, 0.96a: Set "*TRANSFORMS_SUPPORTED as default but allow user
+ * to turn it off with "*TRANSFORMS_NOT_SUPPORTED" or *PNG_NO_*_TRANSFORMS
+ * on the compile line, then pick and choose which ones to define without
+ * having to edit this file. It is safe to use the *TRANSFORMS_NOT_SUPPORTED
+ * if you only want to have a png-compliant reader/writer but don't need
+ * any of the extra transformations. This saves about 80 kbytes in a
+ * typical installation of the library. (PNG_NO_* form added in version
+ * 1.0.1c, for consistency)
+ */
+
+/* The size of the png_text structure changed in libpng-1.0.6 when
+ * iTXt is supported. It is turned off by default, to support old apps
+ * that malloc the png_text structure instead of calling png_set_text()
+ * and letting libpng malloc it. It will be turned on by default in
+ * libpng-1.3.0.
+ */
+
+#ifndef PNG_iTXt_SUPPORTED
+# if !defined(PNG_READ_iTXt_SUPPORTED) && !defined(PNG_NO_READ_iTXt)
+# define PNG_NO_READ_iTXt
+# endif
+# if !defined(PNG_WRITE_iTXt_SUPPORTED) && !defined(PNG_NO_WRITE_iTXt)
+# define PNG_NO_WRITE_iTXt
+# endif
+#endif
+
+/* The following support, added after version 1.0.0, can be turned off here en
+ * masse by defining PNG_LEGACY_SUPPORTED in case you need binary compatibility
+ * with old applications that require the length of png_struct and png_info
+ * to remain unchanged.
+ */
+
+#ifdef PNG_LEGACY_SUPPORTED
+# define PNG_NO_FREE_ME
+# define PNG_NO_READ_UNKNOWN_CHUNKS
+# define PNG_NO_WRITE_UNKNOWN_CHUNKS
+# define PNG_NO_READ_USER_CHUNKS
+# define PNG_NO_READ_iCCP
+# define PNG_NO_WRITE_iCCP
+# define PNG_NO_READ_iTXt
+# define PNG_NO_WRITE_iTXt
+# define PNG_NO_READ_sCAL
+# define PNG_NO_WRITE_sCAL
+# define PNG_NO_READ_sPLT
+# define PNG_NO_WRITE_sPLT
+# define PNG_NO_INFO_IMAGE
+# define PNG_NO_READ_RGB_TO_GRAY
+# define PNG_NO_READ_USER_TRANSFORM
+# define PNG_NO_WRITE_USER_TRANSFORM
+# define PNG_NO_USER_MEM
+# define PNG_NO_READ_EMPTY_PLTE
+# define PNG_NO_MNG_FEATURES
+# define PNG_NO_FIXED_POINT_SUPPORTED
+#endif
+
+/* Ignore attempt to turn off both floating and fixed point support */
+#if !defined(PNG_FLOATING_POINT_SUPPORTED) || \
+ !defined(PNG_NO_FIXED_POINT_SUPPORTED)
+# define PNG_FIXED_POINT_SUPPORTED
+#endif
+
+#ifndef PNG_NO_FREE_ME
+# define PNG_FREE_ME_SUPPORTED
+#endif
+
+#if defined(PNG_READ_SUPPORTED)
+
+#if !defined(PNG_READ_TRANSFORMS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_READ_TRANSFORMS)
+# define PNG_READ_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_TRANSFORMS_SUPPORTED
+# ifndef PNG_NO_READ_EXPAND
+# define PNG_READ_EXPAND_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_SHIFT
+# define PNG_READ_SHIFT_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_PACK
+# define PNG_READ_PACK_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_BGR
+# define PNG_READ_BGR_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_SWAP
+# define PNG_READ_SWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_PACKSWAP
+# define PNG_READ_PACKSWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_INVERT
+# define PNG_READ_INVERT_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_DITHER
+# define PNG_READ_DITHER_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_BACKGROUND
+# define PNG_READ_BACKGROUND_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_16_TO_8
+# define PNG_READ_16_TO_8_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_FILLER
+# define PNG_READ_FILLER_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_GAMMA
+# define PNG_READ_GAMMA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_GRAY_TO_RGB
+# define PNG_READ_GRAY_TO_RGB_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_SWAP_ALPHA
+# define PNG_READ_SWAP_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_INVERT_ALPHA
+# define PNG_READ_INVERT_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_STRIP_ALPHA
+# define PNG_READ_STRIP_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_USER_TRANSFORM
+# define PNG_READ_USER_TRANSFORM_SUPPORTED
+# endif
+# ifndef PNG_NO_READ_RGB_TO_GRAY
+# define PNG_READ_RGB_TO_GRAY_SUPPORTED
+# endif
+#endif /* PNG_READ_TRANSFORMS_SUPPORTED */
+
+#if !defined(PNG_NO_PROGRESSIVE_READ) && \
+ !defined(PNG_PROGRESSIVE_READ_NOT_SUPPORTED) /* if you don't do progressive */
+# define PNG_PROGRESSIVE_READ_SUPPORTED /* reading. This is not talking */
+#endif /* about interlacing capability! You'll */
+ /* still have interlacing unless you change the following line: */
+
+#define PNG_READ_INTERLACING_SUPPORTED /* required for PNG-compliant decoders */
+
+#ifndef PNG_NO_READ_COMPOSITE_NODIV
+# ifndef PNG_NO_READ_COMPOSITED_NODIV /* libpng-1.0.x misspelling */
+# define PNG_READ_COMPOSITE_NODIV_SUPPORTED /* well tested on Intel, SGI */
+# endif
+#endif
+
+/* Deprecated, will be removed from version 2.0.0.
+ Use PNG_MNG_FEATURES_SUPPORTED instead. */
+#ifndef PNG_NO_READ_EMPTY_PLTE
+# define PNG_READ_EMPTY_PLTE_SUPPORTED
+#endif
+
+#endif /* PNG_READ_SUPPORTED */
+
+#if defined(PNG_WRITE_SUPPORTED)
+
+# if !defined(PNG_WRITE_TRANSFORMS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_WRITE_TRANSFORMS)
+# define PNG_WRITE_TRANSFORMS_SUPPORTED
+#endif
+
+#ifdef PNG_WRITE_TRANSFORMS_SUPPORTED
+# ifndef PNG_NO_WRITE_SHIFT
+# define PNG_WRITE_SHIFT_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_PACK
+# define PNG_WRITE_PACK_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_BGR
+# define PNG_WRITE_BGR_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_SWAP
+# define PNG_WRITE_SWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_PACKSWAP
+# define PNG_WRITE_PACKSWAP_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_INVERT
+# define PNG_WRITE_INVERT_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_FILLER
+# define PNG_WRITE_FILLER_SUPPORTED /* same as WRITE_STRIP_ALPHA */
+# endif
+# ifndef PNG_NO_WRITE_SWAP_ALPHA
+# define PNG_WRITE_SWAP_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_INVERT_ALPHA
+# define PNG_WRITE_INVERT_ALPHA_SUPPORTED
+# endif
+# ifndef PNG_NO_WRITE_USER_TRANSFORM
+# define PNG_WRITE_USER_TRANSFORM_SUPPORTED
+# endif
+#endif /* PNG_WRITE_TRANSFORMS_SUPPORTED */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+# ifndef PNG_NO_USER_TRANSFORM_PTR
+# define PNG_USER_TRANSFORM_PTR_SUPPORTED
+# endif
+#endif
+
+#define PNG_WRITE_INTERLACING_SUPPORTED /* not required for PNG-compliant
+ encoders, but can cause trouble
+ if left undefined */
+
+#if !defined(PNG_NO_WRITE_WEIGHTED_FILTER) && \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+# define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
+#endif
+
+#ifndef PNG_1_0_X
+#ifndef PNG_NO_ERROR_NUMBERS
+#define PNG_ERROR_NUMBERS_SUPPORTED
+#endif
+#endif /* PNG_1_0_X */
+
+#ifndef PNG_NO_WRITE_FLUSH
+# define PNG_WRITE_FLUSH_SUPPORTED
+#endif
+
+/* Deprecated, see PNG_MNG_FEATURES_SUPPORTED, above */
+#ifndef PNG_NO_WRITE_EMPTY_PLTE
+# define PNG_WRITE_EMPTY_PLTE_SUPPORTED
+#endif
+
+#endif /* PNG_WRITE_SUPPORTED */
+
+#ifndef PNG_NO_STDIO
+# define PNG_TIME_RFC1123_SUPPORTED
+#endif
+
+/* This adds extra functions in pngget.c for accessing data from the
+ * info pointer (added in version 0.99)
+ * png_get_image_width()
+ * png_get_image_height()
+ * png_get_bit_depth()
+ * png_get_color_type()
+ * png_get_compression_type()
+ * png_get_filter_type()
+ * png_get_interlace_type()
+ * png_get_pixel_aspect_ratio()
+ * png_get_pixels_per_meter()
+ * png_get_x_offset_pixels()
+ * png_get_y_offset_pixels()
+ * png_get_x_offset_microns()
+ * png_get_y_offset_microns()
+ */
+#if !defined(PNG_NO_EASY_ACCESS) && !defined(PNG_EASY_ACCESS_SUPPORTED)
+# define PNG_EASY_ACCESS_SUPPORTED
+#endif
+
+/* PNG_ASSEMBLER_CODE was enabled by default in version 1.2.0
+ even when PNG_USE_PNGVCRD or PNG_USE_PNGGCCRD is not defined */
+#if defined(PNG_READ_SUPPORTED) && !defined(PNG_NO_ASSEMBLER_CODE)
+# ifndef PNG_ASSEMBLER_CODE_SUPPORTED
+# define PNG_ASSEMBLER_CODE_SUPPORTED
+# endif
+# if defined(XP_MACOSX) && !defined(PNG_NO_MMX_CODE)
+ /* work around Intel-Mac compiler bug */
+# define PNG_NO_MMX_CODE
+# endif
+# if !defined(PNG_MMX_CODE_SUPPORTED) && !defined(PNG_NO_MMX_CODE)
+# define PNG_MMX_CODE_SUPPORTED
+# endif
+#endif
+
+/* If you are sure that you don't need thread safety and you are compiling
+ with PNG_USE_PNGCCRD for an MMX application, you can define this for
+ faster execution. See pnggccrd.c.
+#define PNG_THREAD_UNSAFE_OK
+*/
+
+#if !defined(PNG_1_0_X)
+#if !defined(PNG_NO_USER_MEM) && !defined(PNG_USER_MEM_SUPPORTED)
+# define PNG_USER_MEM_SUPPORTED
+#endif
+#endif /* PNG_1_0_X */
+
+#ifndef PNG_USER_WIDTH_MAX
+# define PNG_USER_WIDTH_MAX 1000000L
+#endif
+#ifndef PNG_USER_HEIGHT_MAX
+# define PNG_USER_HEIGHT_MAX 1000000L
+#endif
+
+/* These are currently experimental features, define them if you want */
+
+/* very little testing */
+/*
+#ifdef PNG_READ_SUPPORTED
+# ifndef PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+# define PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED
+# endif
+#endif
+*/
+
+/* This is only for PowerPC big-endian and 680x0 systems */
+/* some testing */
+/*
+#ifdef PNG_READ_SUPPORTED
+# ifndef PNG_PNG_READ_BIG_ENDIAN_SUPPORTED
+# define PNG_READ_BIG_ENDIAN_SUPPORTED
+# endif
+#endif
+*/
+
+/* Buggy compilers (e.g., gcc 2.7.2.2) need this */
+/*
+#define PNG_NO_POINTER_INDEXING
+*/
+
+/* These functions are turned off by default, as they will be phased out. */
+/*
+#define PNG_USELESS_TESTS_SUPPORTED
+#define PNG_CORRECT_PALETTE_SUPPORTED
+*/
+
+/* Any chunks you are not interested in, you can undef here. The
+ * ones that allocate memory may be expecially important (hIST,
+ * tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info
+ * a bit smaller.
+ */
+
+#if defined(PNG_READ_SUPPORTED) && \
+ !defined(PNG_READ_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_READ_ANCILLARY_CHUNKS)
+# define PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#if defined(PNG_WRITE_SUPPORTED) && \
+ !defined(PNG_WRITE_ANCILLARY_CHUNKS_NOT_SUPPORTED) && \
+ !defined(PNG_NO_WRITE_ANCILLARY_CHUNKS)
+# define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+#endif
+
+#ifdef PNG_READ_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_READ_TEXT
+# define PNG_NO_READ_iTXt
+# define PNG_NO_READ_tEXt
+# define PNG_NO_READ_zTXt
+#endif
+#ifndef PNG_NO_READ_bKGD
+# define PNG_READ_bKGD_SUPPORTED
+# define PNG_bKGD_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_cHRM
+# define PNG_READ_cHRM_SUPPORTED
+# define PNG_cHRM_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_gAMA
+# define PNG_READ_gAMA_SUPPORTED
+# define PNG_gAMA_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_hIST
+# define PNG_READ_hIST_SUPPORTED
+# define PNG_hIST_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iCCP
+# define PNG_READ_iCCP_SUPPORTED
+# define PNG_iCCP_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_iTXt
+# ifndef PNG_READ_iTXt_SUPPORTED
+# define PNG_READ_iTXt_SUPPORTED
+# endif
+# ifndef PNG_iTXt_SUPPORTED
+# define PNG_iTXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_READ_oFFs
+# define PNG_READ_oFFs_SUPPORTED
+# define PNG_oFFs_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_pCAL
+# define PNG_READ_pCAL_SUPPORTED
+# define PNG_pCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sCAL
+# define PNG_READ_sCAL_SUPPORTED
+# define PNG_sCAL_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_pHYs
+# define PNG_READ_pHYs_SUPPORTED
+# define PNG_pHYs_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sBIT
+# define PNG_READ_sBIT_SUPPORTED
+# define PNG_sBIT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sPLT
+# define PNG_READ_sPLT_SUPPORTED
+# define PNG_sPLT_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_sRGB
+# define PNG_READ_sRGB_SUPPORTED
+# define PNG_sRGB_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tEXt
+# define PNG_READ_tEXt_SUPPORTED
+# define PNG_tEXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tIME
+# define PNG_READ_tIME_SUPPORTED
+# define PNG_tIME_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_tRNS
+# define PNG_READ_tRNS_SUPPORTED
+# define PNG_tRNS_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_zTXt
+# define PNG_READ_zTXt_SUPPORTED
+# define PNG_zTXt_SUPPORTED
+#endif
+#ifndef PNG_NO_READ_UNKNOWN_CHUNKS
+# define PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
+# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+# define PNG_UNKNOWN_CHUNKS_SUPPORTED
+# endif
+# ifndef PNG_NO_HANDLE_AS_UNKNOWN
+# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# endif
+#endif
+#if !defined(PNG_NO_READ_USER_CHUNKS) && \
+ defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+# define PNG_READ_USER_CHUNKS_SUPPORTED
+# define PNG_USER_CHUNKS_SUPPORTED
+# ifdef PNG_NO_READ_UNKNOWN_CHUNKS
+# undef PNG_NO_READ_UNKNOWN_CHUNKS
+# endif
+# ifdef PNG_NO_HANDLE_AS_UNKNOWN
+# undef PNG_NO_HANDLE_AS_UNKNOWN
+# endif
+#endif
+#ifndef PNG_NO_READ_OPT_PLTE
+# define PNG_READ_OPT_PLTE_SUPPORTED /* only affects support of the */
+#endif /* optional PLTE chunk in RGB and RGBA images */
+#if defined(PNG_READ_iTXt_SUPPORTED) || defined(PNG_READ_tEXt_SUPPORTED) || \
+ defined(PNG_READ_zTXt_SUPPORTED)
+# define PNG_READ_TEXT_SUPPORTED
+# define PNG_TEXT_SUPPORTED
+#endif
+
+#endif /* PNG_READ_ANCILLARY_CHUNKS_SUPPORTED */
+
+#ifdef PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED
+
+#ifdef PNG_NO_WRITE_TEXT
+# define PNG_NO_WRITE_iTXt
+# define PNG_NO_WRITE_tEXt
+# define PNG_NO_WRITE_zTXt
+#endif
+#ifndef PNG_NO_WRITE_bKGD
+# define PNG_WRITE_bKGD_SUPPORTED
+# ifndef PNG_bKGD_SUPPORTED
+# define PNG_bKGD_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_cHRM
+# define PNG_WRITE_cHRM_SUPPORTED
+# ifndef PNG_cHRM_SUPPORTED
+# define PNG_cHRM_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_gAMA
+# define PNG_WRITE_gAMA_SUPPORTED
+# ifndef PNG_gAMA_SUPPORTED
+# define PNG_gAMA_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_hIST
+# define PNG_WRITE_hIST_SUPPORTED
+# ifndef PNG_hIST_SUPPORTED
+# define PNG_hIST_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_iCCP
+# define PNG_WRITE_iCCP_SUPPORTED
+# ifndef PNG_iCCP_SUPPORTED
+# define PNG_iCCP_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_iTXt
+# ifndef PNG_WRITE_iTXt_SUPPORTED
+# define PNG_WRITE_iTXt_SUPPORTED
+# endif
+# ifndef PNG_iTXt_SUPPORTED
+# define PNG_iTXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_oFFs
+# define PNG_WRITE_oFFs_SUPPORTED
+# ifndef PNG_oFFs_SUPPORTED
+# define PNG_oFFs_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_pCAL
+# define PNG_WRITE_pCAL_SUPPORTED
+# ifndef PNG_pCAL_SUPPORTED
+# define PNG_pCAL_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sCAL
+# define PNG_WRITE_sCAL_SUPPORTED
+# ifndef PNG_sCAL_SUPPORTED
+# define PNG_sCAL_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_pHYs
+# define PNG_WRITE_pHYs_SUPPORTED
+# ifndef PNG_pHYs_SUPPORTED
+# define PNG_pHYs_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sBIT
+# define PNG_WRITE_sBIT_SUPPORTED
+# ifndef PNG_sBIT_SUPPORTED
+# define PNG_sBIT_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sPLT
+# define PNG_WRITE_sPLT_SUPPORTED
+# ifndef PNG_sPLT_SUPPORTED
+# define PNG_sPLT_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_sRGB
+# define PNG_WRITE_sRGB_SUPPORTED
+# ifndef PNG_sRGB_SUPPORTED
+# define PNG_sRGB_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_tEXt
+# define PNG_WRITE_tEXt_SUPPORTED
+# ifndef PNG_tEXt_SUPPORTED
+# define PNG_tEXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_tIME
+# define PNG_WRITE_tIME_SUPPORTED
+# ifndef PNG_tIME_SUPPORTED
+# define PNG_tIME_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_tRNS
+# define PNG_WRITE_tRNS_SUPPORTED
+# ifndef PNG_tRNS_SUPPORTED
+# define PNG_tRNS_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_zTXt
+# define PNG_WRITE_zTXt_SUPPORTED
+# ifndef PNG_zTXt_SUPPORTED
+# define PNG_zTXt_SUPPORTED
+# endif
+#endif
+#ifndef PNG_NO_WRITE_UNKNOWN_CHUNKS
+# define PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED
+# ifndef PNG_UNKNOWN_CHUNKS_SUPPORTED
+# define PNG_UNKNOWN_CHUNKS_SUPPORTED
+# endif
+# ifndef PNG_NO_HANDLE_AS_UNKNOWN
+# ifndef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# define PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+# endif
+# endif
+#endif
+#if defined(PNG_WRITE_iTXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
+ defined(PNG_WRITE_zTXt_SUPPORTED)
+# define PNG_WRITE_TEXT_SUPPORTED
+# ifndef PNG_TEXT_SUPPORTED
+# define PNG_TEXT_SUPPORTED
+# endif
+#endif
+
+#endif /* PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED */
+
+/* Turn this off to disable png_read_png() and
+ * png_write_png() and leave the row_pointers member
+ * out of the info structure.
+ */
+#ifndef PNG_NO_INFO_IMAGE
+# define PNG_INFO_IMAGE_SUPPORTED
+#endif
+
+/* need the time information for reading tIME chunks */
+#if defined(PNG_tIME_SUPPORTED)
+# if !defined(_WIN32_WCE)
+ /* "time.h" functions are not supported on WindowsCE */
+# include <time.h>
+# endif
+#endif
+
+/* Some typedefs to get us started. These should be safe on most of the
+ * common platforms. The typedefs should be at least as large as the
+ * numbers suggest (a png_uint_32 must be at least 32 bits long), but they
+ * don't have to be exactly that size. Some compilers dislike passing
+ * unsigned shorts as function parameters, so you may be better off using
+ * unsigned int for png_uint_16. Likewise, for 64-bit systems, you may
+ * want to have unsigned int for png_uint_32 instead of unsigned long.
+ */
+
+typedef unsigned long png_uint_32;
+typedef long png_int_32;
+typedef unsigned short png_uint_16;
+typedef short png_int_16;
+typedef unsigned char png_byte;
+
+/* This is usually size_t. It is typedef'ed just in case you need it to
+ change (I'm not sure if you will or not, so I thought I'd be safe) */
+typedef size_t png_size_t;
+
+/* The following is needed for medium model support. It cannot be in the
+ * PNG_INTERNAL section. Needs modification for other compilers besides
+ * MSC. Model independent support declares all arrays and pointers to be
+ * large using the far keyword. The zlib version used must also support
+ * model independent data. As of version zlib 1.0.4, the necessary changes
+ * have been made in zlib. The USE_FAR_KEYWORD define triggers other
+ * changes that are needed. (Tim Wegner)
+ */
+
+/* Separate compiler dependencies (problem here is that zlib.h always
+ defines FAR. (SJT) */
+#ifdef __BORLANDC__
+# if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
+# define LDATA 1
+# else
+# define LDATA 0
+# endif
+ /* GRR: why is Cygwin in here? Cygwin is not Borland C... */
+# if !defined(__WIN32__) && !defined(__FLAT__) && !defined(__CYGWIN__)
+# define PNG_MAX_MALLOC_64K
+# if (LDATA != 1)
+# ifndef FAR
+# define FAR __far
+# endif
+# define USE_FAR_KEYWORD
+# endif /* LDATA != 1 */
+ /* Possibly useful for moving data out of default segment.
+ * Uncomment it if you want. Could also define FARDATA as
+ * const if your compiler supports it. (SJT)
+# define FARDATA FAR
+ */
+# endif /* __WIN32__, __FLAT__, __CYGWIN__ */
+#endif /* __BORLANDC__ */
+
+
+/* Suggest testing for specific compiler first before testing for
+ * FAR. The Watcom compiler defines both __MEDIUM__ and M_I86MM,
+ * making reliance oncertain keywords suspect. (SJT)
+ */
+
+/* MSC Medium model */
+#if defined(FAR)
+# if defined(M_I86MM)
+# define USE_FAR_KEYWORD
+# define FARDATA FAR
+# include <dos.h>
+# endif
+#endif
+
+/* SJT: default case */
+#ifndef FAR
+# define FAR
+#endif
+
+/* At this point FAR is always defined */
+#ifndef FARDATA
+# define FARDATA
+#endif
+
+/* Typedef for floating-point numbers that are converted
+ to fixed-point with a multiple of 100,000, e.g., int_gamma */
+typedef png_int_32 png_fixed_point;
+
+/* Add typedefs for pointers */
+typedef void FAR * png_voidp;
+typedef png_byte FAR * png_bytep;
+typedef png_uint_32 FAR * png_uint_32p;
+typedef png_int_32 FAR * png_int_32p;
+typedef png_uint_16 FAR * png_uint_16p;
+typedef png_int_16 FAR * png_int_16p;
+typedef PNG_CONST char FAR * png_const_charp;
+typedef char FAR * png_charp;
+typedef png_fixed_point FAR * png_fixed_point_p;
+
+#ifndef PNG_NO_STDIO
+#if defined(_WIN32_WCE)
+typedef HANDLE png_FILE_p;
+#else
+typedef FILE * png_FILE_p;
+#endif
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double FAR * png_doublep;
+#endif
+
+/* Pointers to pointers; i.e. arrays */
+typedef png_byte FAR * FAR * png_bytepp;
+typedef png_uint_32 FAR * FAR * png_uint_32pp;
+typedef png_int_32 FAR * FAR * png_int_32pp;
+typedef png_uint_16 FAR * FAR * png_uint_16pp;
+typedef png_int_16 FAR * FAR * png_int_16pp;
+typedef PNG_CONST char FAR * FAR * png_const_charpp;
+typedef char FAR * FAR * png_charpp;
+typedef png_fixed_point FAR * FAR * png_fixed_point_pp;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+typedef double FAR * FAR * png_doublepp;
+#endif
+
+/* Pointers to pointers to pointers; i.e., pointer to array */
+typedef char FAR * FAR * FAR * png_charppp;
+
+/* libpng typedefs for types in zlib. If zlib changes
+ * or another compression library is used, then change these.
+ * Eliminates need to change all the source files.
+ */
+typedef charf * png_zcharp;
+typedef charf * FAR * png_zcharpp;
+typedef z_stream FAR * png_zstreamp;
+
+/*
+ * Define PNG_BUILD_DLL if the module being built is a Windows
+ * LIBPNG DLL.
+ *
+ * Define PNG_USE_DLL if you want to *link* to the Windows LIBPNG DLL.
+ * It is equivalent to Microsoft predefined macro _DLL that is
+ * automatically defined when you compile using the share
+ * version of the CRT (C Run-Time library)
+ *
+ * The cygwin mods make this behavior a little different:
+ * Define PNG_BUILD_DLL if you are building a dll for use with cygwin
+ * Define PNG_STATIC if you are building a static library for use with cygwin,
+ * -or- if you are building an application that you want to link to the
+ * static library.
+ * PNG_USE_DLL is defined by default (no user action needed) unless one of
+ * the other flags is defined.
+ */
+
+#if !defined(PNG_DLL) && (defined(PNG_BUILD_DLL) || defined(PNG_USE_DLL))
+# define PNG_DLL
+#endif
+/* If CYGWIN, then disallow GLOBAL ARRAYS unless building a static lib.
+ * When building a static lib, default to no GLOBAL ARRAYS, but allow
+ * command-line override
+ */
+#if defined(__CYGWIN__)
+# if !defined(PNG_STATIC)
+# if defined(PNG_USE_GLOBAL_ARRAYS)
+# undef PNG_USE_GLOBAL_ARRAYS
+# endif
+# if !defined(PNG_USE_LOCAL_ARRAYS)
+# define PNG_USE_LOCAL_ARRAYS
+# endif
+# else
+# if defined(PNG_USE_LOCAL_ARRAYS) || defined(PNG_NO_GLOBAL_ARRAYS)
+# if defined(PNG_USE_GLOBAL_ARRAYS)
+# undef PNG_USE_GLOBAL_ARRAYS
+# endif
+# endif
+# endif
+# if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+# define PNG_USE_LOCAL_ARRAYS
+# endif
+#endif
+
+/* Do not use global arrays (helps with building DLL's)
+ * They are no longer used in libpng itself, since version 1.0.5c,
+ * but might be required for some pre-1.0.5c applications.
+ */
+#if !defined(PNG_USE_LOCAL_ARRAYS) && !defined(PNG_USE_GLOBAL_ARRAYS)
+# if defined(PNG_NO_GLOBAL_ARRAYS) || (defined(__GNUC__) && defined(PNG_DLL))
+# define PNG_USE_LOCAL_ARRAYS
+# else
+# define PNG_USE_GLOBAL_ARRAYS
+# endif
+#endif
+
+#if defined(__CYGWIN__)
+# undef PNGAPI
+# define PNGAPI __cdecl
+# undef PNG_IMPEXP
+# define PNG_IMPEXP
+#endif
+
+/* If you define PNGAPI, e.g., with compiler option "-DPNGAPI=__stdcall",
+ * you may get warnings regarding the linkage of png_zalloc and png_zfree.
+ * Don't ignore those warnings; you must also reset the default calling
+ * convention in your compiler to match your PNGAPI, and you must build
+ * zlib and your applications the same way you build libpng.
+ */
+
+#ifndef PNGAPI
+
+#if defined(__MINGW32__) && !defined(PNG_MODULEDEF)
+# ifndef PNG_NO_MODULEDEF
+# define PNG_NO_MODULEDEF
+# endif
+#endif
+
+#if !defined(PNG_IMPEXP) && defined(PNG_BUILD_DLL) && !defined(PNG_NO_MODULEDEF)
+# define PNG_IMPEXP
+#endif
+
+#if defined(PNG_DLL) || defined(_DLL) || defined(__DLL__ ) || \
+ (( defined(_Windows) || defined(_WINDOWS) || \
+ defined(WIN32) || defined(_WIN32) || defined(__WIN32__) ))
+
+# if defined(__GNUC__) || (defined (_MSC_VER) && (_MSC_VER >= 800))
+# define PNGAPI __cdecl
+# else
+# define PNGAPI _cdecl
+# endif
+
+# if !defined(PNG_IMPEXP) && (!defined(PNG_DLL) || \
+ 0 /* WINCOMPILER_WITH_NO_SUPPORT_FOR_DECLIMPEXP */)
+# define PNG_IMPEXP
+# endif
+
+# if !defined(PNG_IMPEXP)
+
+# define PNG_EXPORT_TYPE1(type,symbol) PNG_IMPEXP type PNGAPI symbol
+# define PNG_EXPORT_TYPE2(type,symbol) type PNG_IMPEXP PNGAPI symbol
+
+ /* Borland/Microsoft */
+# if defined(_MSC_VER) || defined(__BORLANDC__)
+# if (_MSC_VER >= 800) || (__BORLANDC__ >= 0x500)
+# define PNG_EXPORT PNG_EXPORT_TYPE1
+# else
+# define PNG_EXPORT PNG_EXPORT_TYPE2
+# if defined(PNG_BUILD_DLL)
+# define PNG_IMPEXP __export
+# else
+# define PNG_IMPEXP /*__import */ /* doesn't exist AFAIK in
+ VC++ */
+# endif /* Exists in Borland C++ for
+ C++ classes (== huge) */
+# endif
+# endif
+
+# if !defined(PNG_IMPEXP)
+# if defined(PNG_BUILD_DLL)
+# define PNG_IMPEXP __declspec(dllexport)
+# else
+# define PNG_IMPEXP __declspec(dllimport)
+# endif
+# endif
+# endif /* PNG_IMPEXP */
+#else /* !(DLL || non-cygwin WINDOWS) */
+# if (defined(__IBMC__) || defined(IBMCPP__)) && defined(__OS2__)
+# define PNGAPI _System
+# define PNG_IMPEXP
+# else
+# if 0 /* ... other platforms, with other meanings */
+# else
+# define PNGAPI
+# define PNG_IMPEXP
+# endif
+# endif
+#endif
+#endif
+
+#ifndef PNGAPI
+# define PNGAPI
+#endif
+#ifndef PNG_IMPEXP
+# define PNG_IMPEXP
+#endif
+
+#ifndef PNG_EXPORT
+# define PNG_EXPORT(type,symbol) PNG_IMPEXP type PNGAPI symbol
+#endif
+
+#ifdef PNG_USE_GLOBAL_ARRAYS
+# ifndef PNG_EXPORT_VAR
+# define PNG_EXPORT_VAR(type) extern PNG_IMPEXP type
+# endif
+#endif
+
+/* User may want to use these so they are not in PNG_INTERNAL. Any library
+ * functions that are passed far data must be model independent.
+ */
+
+#ifndef PNG_ABORT
+# define PNG_ABORT() abort()
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+# define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
+#else
+# define png_jmpbuf(png_ptr) \
+ (LIBPNG_WAS_COMPILED_WITH__PNG_SETJMP_NOT_SUPPORTED)
+#endif
+
+#if defined(USE_FAR_KEYWORD) /* memory model independent fns */
+/* use this to make far-to-near assignments */
+# define CHECK 1
+# define NOCHECK 0
+# define CVT_PTR(ptr) (png_far_to_near(png_ptr,ptr,CHECK))
+# define CVT_PTR_NOCHECK(ptr) (png_far_to_near(png_ptr,ptr,NOCHECK))
+# define png_strcpy _fstrcpy
+# define png_strncpy _fstrncpy /* Added to v 1.2.6 */
+# define png_strlen _fstrlen
+# define png_memcmp _fmemcmp /* SJT: added */
+# define png_memcpy _fmemcpy
+# define png_memset _fmemset
+#else /* use the usual functions */
+# define CVT_PTR(ptr) (ptr)
+# define CVT_PTR_NOCHECK(ptr) (ptr)
+# define png_strcpy strcpy
+# define png_strncpy strncpy /* Added to v 1.2.6 */
+# define png_strlen strlen
+# define png_memcmp memcmp /* SJT: added */
+# define png_memcpy memcpy
+# define png_memset memset
+#endif
+/* End of memory model independent support */
+
+/* Just a little check that someone hasn't tried to define something
+ * contradictory.
+ */
+#if (PNG_ZBUF_SIZE > 65536) && defined(PNG_MAX_MALLOC_64K)
+# undef PNG_ZBUF_SIZE
+# define PNG_ZBUF_SIZE 65536
+#endif
+
+#ifdef PNG_READ_SUPPORTED
+/* Prior to libpng-1.0.9, this block was in pngasmrd.h */
+#if defined(PNG_INTERNAL)
+
+/* These are the default thresholds before the MMX code kicks in; if either
+ * rowbytes or bitdepth is below the threshold, plain C code is used. These
+ * can be overridden at runtime via the png_set_mmx_thresholds() call in
+ * libpng 1.2.0 and later. The values below were chosen by Intel.
+ */
+
+#ifndef PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT
+# define PNG_MMX_ROWBYTES_THRESHOLD_DEFAULT 128 /* >= */
+#endif
+#ifndef PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT
+# define PNG_MMX_BITDEPTH_THRESHOLD_DEFAULT 9 /* >= */
+#endif
+
+/* Set this in the makefile for VC++ on Pentium, not here. */
+/* Platform must be Pentium. Makefile must assemble and load pngvcrd.c .
+ * MMX will be detected at run time and used if present.
+ */
+#ifdef PNG_USE_PNGVCRD
+# define PNG_HAVE_ASSEMBLER_COMBINE_ROW
+# define PNG_HAVE_ASSEMBLER_READ_INTERLACE
+# define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+#endif
+
+/* Set this in the makefile for gcc/as on Pentium, not here. */
+/* Platform must be Pentium. Makefile must assemble and load pnggccrd.c .
+ * MMX will be detected at run time and used if present.
+ */
+#ifdef PNG_USE_PNGGCCRD
+# define PNG_HAVE_ASSEMBLER_COMBINE_ROW
+# define PNG_HAVE_ASSEMBLER_READ_INTERLACE
+# define PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+#endif
+/* - see pnggccrd.c for info about what is currently enabled */
+
+#endif /* PNG_INTERNAL */
+#endif /* PNG_READ_SUPPORTED */
+
+#endif /* PNGCONF_H */
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngerror.c b/tqtinterface/qt4/src/3rdparty/libpng/pngerror.c
new file mode 100644
index 0000000..29e1e66
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngerror.c
@@ -0,0 +1,301 @@
+
+/* pngerror.c - stub functions for i/o and memory allocation
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all error handling. Users who
+ * need special error handling are expected to write tqreplacement functions
+ * and use png_set_error_fn() to use those functions. See the instructions
+ * at each function.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+static void /* PRIVATE */
+png_default_error PNGARG((png_structp png_ptr,
+ png_const_charp error_message));
+static void /* PRIVATE */
+png_default_warning PNGARG((png_structp png_ptr,
+ png_const_charp warning_message));
+
+/* This function is called whenever there is a fatal error. This function
+ * should not be changed. If there is a need to handle errors differently,
+ * you should supply a tqreplacement error function and use png_set_error_fn()
+ * to tqreplace the error function at run-time.
+ */
+void PNGAPI
+png_error(png_structp png_ptr, png_const_charp error_message)
+{
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ char msg[16];
+ if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+ {
+ int offset = 0;
+ if (*error_message == '#')
+ {
+ for (offset=1; offset<15; offset++)
+ if (*(error_message+offset) == ' ')
+ break;
+ if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+ {
+ int i;
+ for (i=0; i<offset-1; i++)
+ msg[i]=error_message[i+1];
+ msg[i]='\0';
+ error_message=msg;
+ }
+ else
+ error_message+=offset;
+ }
+ else
+ {
+ if (png_ptr->flags&PNG_FLAG_STRIP_ERROR_TEXT)
+ {
+ msg[0]='0';
+ msg[1]='\0';
+ error_message=msg;
+ }
+ }
+ }
+#endif
+ if (png_ptr->error_fn != NULL)
+ (*(png_ptr->error_fn))(png_ptr, error_message);
+
+ /* if the following returns or doesn't exist, use the default function,
+ which will not return */
+ png_default_error(png_ptr, error_message);
+}
+
+/* This function is called whenever there is a non-fatal error. This function
+ * should not be changed. If there is a need to handle warnings differently,
+ * you should supply a tqreplacement warning function and use
+ * png_set_error_fn() to tqreplace the warning function at run-time.
+ */
+void PNGAPI
+png_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+ int offset = 0;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (png_ptr->flags&(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))
+#endif
+ {
+ if (*warning_message == '#')
+ {
+ for (offset=1; offset<15; offset++)
+ if (*(warning_message+offset) == ' ')
+ break;
+ }
+ }
+ if (png_ptr->warning_fn != NULL)
+ (*(png_ptr->warning_fn))(png_ptr,
+ (png_const_charp)(warning_message+offset));
+ else
+ png_default_warning(png_ptr, (png_const_charp)(warning_message+offset));
+}
+
+/* These utilities are used internally to build an error message that relates
+ * to the current chunk. The chunk name comes from png_ptr->chunk_name,
+ * this is used to prefix the message. The message is limited in length
+ * to 63 bytes, the name characters are output as hex digits wrapped in []
+ * if the character is invalid.
+ */
+#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
+static PNG_CONST char png_digit[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
+ 'F' };
+
+static void /* PRIVATE */
+png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp
+ error_message)
+{
+ int iout = 0, iin = 0;
+
+ while (iin < 4)
+ {
+ int c = png_ptr->chunk_name[iin++];
+ if (isnonalpha(c))
+ {
+ buffer[iout++] = '[';
+ buffer[iout++] = png_digit[(c & 0xf0) >> 4];
+ buffer[iout++] = png_digit[c & 0x0f];
+ buffer[iout++] = ']';
+ }
+ else
+ {
+ buffer[iout++] = (png_byte)c;
+ }
+ }
+
+ if (error_message == NULL)
+ buffer[iout] = 0;
+ else
+ {
+ buffer[iout++] = ':';
+ buffer[iout++] = ' ';
+ png_strncpy(buffer+iout, error_message, 63);
+ buffer[iout+63] = 0;
+ }
+}
+
+void PNGAPI
+png_chunk_error(png_structp png_ptr, png_const_charp error_message)
+{
+ char msg[18+64];
+ if (png_ptr == NULL)
+ png_error(png_ptr, error_message);
+ else
+ {
+ png_format_buffer(png_ptr, msg, error_message);
+ png_error(png_ptr, msg);
+ }
+}
+
+void PNGAPI
+png_chunk_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+ char msg[18+64];
+ if (png_ptr == NULL)
+ png_warning(png_ptr, warning_message);
+ else
+ {
+ png_format_buffer(png_ptr, msg, warning_message);
+ png_warning(png_ptr, msg);
+ }
+}
+
+/* This is the default error handling function. Note that tqreplacements for
+ * this function MUST NOT RETURN, or the program will likely crash. This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void /* PRIVATE */
+png_default_error(png_structp png_ptr, png_const_charp error_message)
+{
+#ifndef PNG_NO_CONSOLE_IO
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (*error_message == '#')
+ {
+ int offset;
+ char error_number[16];
+ for (offset=0; offset<15; offset++)
+ {
+ error_number[offset] = *(error_message+offset+1);
+ if (*(error_message+offset) == ' ')
+ break;
+ }
+ if((offset > 1) && (offset < 15))
+ {
+ error_number[offset-1]='\0';
+ fprintf(stderr, "libpng error no. %s: %s\n", error_number,
+ error_message+offset);
+ }
+ else
+ fprintf(stderr, "libpng error: %s, offset=%d\n", error_message,offset);
+ }
+ else
+#endif
+ fprintf(stderr, "libpng error: %s\n", error_message);
+#else
+ if (error_message)
+ /* make compiler happy */ ;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+# ifdef USE_FAR_KEYWORD
+ {
+ jmp_buf jmpbuf;
+ png_memcpy(jmpbuf,png_ptr->jmpbuf,sizeof(jmp_buf));
+ longjmp(jmpbuf, 1);
+ }
+# else
+ longjmp(png_ptr->jmpbuf, 1);
+# endif
+#else
+ if (png_ptr)
+ /* make compiler happy */ ;
+ PNG_ABORT();
+#endif
+}
+
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway. Replacement functions don't have to do anything
+ * here if you don't want them to. In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void /* PRIVATE */
+png_default_warning(png_structp png_ptr, png_const_charp warning_message)
+{
+#ifndef PNG_NO_CONSOLE_IO
+# ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ if (*warning_message == '#')
+ {
+ int offset;
+ char warning_number[16];
+ for (offset=0; offset<15; offset++)
+ {
+ warning_number[offset]=*(warning_message+offset+1);
+ if (*(warning_message+offset) == ' ')
+ break;
+ }
+ if((offset > 1) && (offset < 15))
+ {
+ warning_number[offset-1]='\0';
+ fprintf(stderr, "libpng warning no. %s: %s\n", warning_number,
+ warning_message+offset);
+ }
+ else
+ fprintf(stderr, "libpng warning: %s\n", warning_message);
+ }
+ else
+# endif
+ fprintf(stderr, "libpng warning: %s\n", warning_message);
+#else
+ if (warning_message)
+ /* appease compiler */ ;
+#endif
+ if (png_ptr)
+ return;
+}
+
+/* This function is called when the application wants to use another method
+ * of handling errors and warnings. Note that the error function MUST NOT
+ * return to the calling routine or serious problems will occur. The return
+ * method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
+ */
+void PNGAPI
+png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warning_fn)
+{
+ png_ptr->error_ptr = error_ptr;
+ png_ptr->error_fn = error_fn;
+ png_ptr->warning_fn = warning_fn;
+}
+
+
+/* This function returns a pointer to the error_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_error_ptr(png_structp png_ptr)
+{
+ return ((png_voidp)png_ptr->error_ptr);
+}
+
+
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+void PNGAPI
+png_set_strip_error_numbers(png_structp png_ptr, png_uint_32 strip_mode)
+{
+ if(png_ptr != NULL)
+ {
+ png_ptr->flags &=
+ ((~(PNG_FLAG_STRIP_ERROR_NUMBERS|PNG_FLAG_STRIP_ERROR_TEXT))&strip_mode);
+ }
+}
+#endif
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pnggccrd.c b/tqtinterface/qt4/src/3rdparty/libpng/pnggccrd.c
new file mode 100644
index 0000000..23ad357
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pnggccrd.c
@@ -0,0 +1,5397 @@
+/* pnggccrd.c - mixed C/assembler version of utilities to read a PNG file
+ *
+ * For Intel x86 CPU (Pentium-MMX or later) and GNU C compiler.
+ *
+ * See http://www.intel.com/drg/pentiumII/appnotes/916/916.htm
+ * and http://www.intel.com/drg/pentiumII/appnotes/923/923.htm
+ * for Intel's performance analysis of the MMX vs. non-MMX code.
+ *
+ * libpng version 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * Copyright (c) 1998, Intel Corporation
+ *
+ * Based on MSVC code contributed by Nirav Chhatrapati, Intel Corp., 1998.
+ * Interface to libpng contributed by Gilles Vollant, 1999.
+ * GNU C port by Greg Roelofs, 1999-2001.
+ *
+ * Lines 2350-4300 converted in place with intel2gas 1.3.1:
+ *
+ * intel2gas -mdI pnggccrd.c.partially-msvc -o pnggccrd.c
+ *
+ * and then cleaned up by hand. See http://hermes.terminal.at/intel2gas/ .
+ *
+ * NOTE: A sufficiently recent version of GNU as (or as.exe under DOS/Windows)
+ * is required to assemble the newer MMX instructions such as movq.
+ * For djgpp, see
+ *
+ * ftp://ftp.simtel.net/pub/simtelnet/gnu/djgpp/v2gnu/bnu281b.zip
+ *
+ * (or a later version in the same directory). For Linux, check your
+ * distribution's web site(s) or try these links:
+ *
+ * http://rufus.w3.org/linux/RPM/binutils.html
+ * http://www.debian.org/Packages/stable/devel/binutils.html
+ * ftp://ftp.slackware.com/pub/linux/slackware/slackware/slakware/d1/
+ * binutils.tgz
+ *
+ * For other platforms, see the main GNU site:
+ *
+ * ftp://ftp.gnu.org/pub/gnu/binutils/
+ *
+ * Version 2.5.2l.15 is definitely too old...
+ */
+
+/*
+ * TEMPORARY PORTING NOTES AND CHANGELOG (mostly by Greg Roelofs)
+ * =====================================
+ *
+ * 19991006:
+ * - fixed sign error in post-MMX cleanup code (16- & 32-bit cases)
+ *
+ * 19991007:
+ * - additional optimizations (possible or definite):
+ * x [DONE] write MMX code for 64-bit case (pixel_bytes == 8) [not tested]
+ * - write MMX code for 48-bit case (pixel_bytes == 6)
+ * - figure out what's up with 24-bit case (pixel_bytes == 3):
+ * why subtract 8 from width_mmx in the pass 4/5 case?
+ * (only width_mmx case) (near line 1606)
+ * x [DONE] tqreplace pixel_bytes within each block with the true
+ * constant value (or are compilers smart enough to do that?)
+ * - rewrite all MMX interlacing code so it's aligned with
+ * the *beginning* of the row buffer, not the end. This
+ * would not only allow one to eliminate half of the memory
+ * writes for odd passes (that is, pass == odd), it may also
+ * eliminate some unaligned-data-access exceptions (assuming
+ * there's a penalty for not aligning 64-bit accesses on
+ * 64-bit boundaries). The only catch is that the "leftover"
+ * pixel(s) at the end of the row would have to be saved,
+ * but there are enough unused MMX registers in every case,
+ * so this is not a problem. A further benefit is that the
+ * post-MMX cleanup code (C code) in at least some of the
+ * cases could be done within the assembler block.
+ * x [DONE] the "v3 v2 v1 v0 v7 v6 v5 v4" comments are confusing,
+ * inconsistent, and don't match the MMX Programmer's Reference
+ * Manual conventions anyway. They should be changed to
+ * "b7 b6 b5 b4 b3 b2 b1 b0," where b0 indicates the byte that
+ * was lowest in memory (e.g., corresponding to a left pixel)
+ * and b7 is the byte that was highest (e.g., a right pixel).
+ *
+ * 19991016:
+ * - Brennan's Guide notwithstanding, gcc under Linux does *not*
+ * want globals prefixed by underscores when referencing them--
+ * i.e., if the variable is const4, then refer to it as const4,
+ * not _const4. This seems to be a djgpp-specific requirement.
+ * Also, such variables apparently *must* be declared outside
+ * of functions; neither static nor automatic variables work if
+ * defined within the scope of a single function, but both
+ * static and truly global (multi-module) variables work fine.
+ *
+ * 19991023:
+ * - fixed png_combine_row() non-MMX replication bug (odd passes only?)
+ * - switched from string-concatenation-with-macros to cleaner method of
+ * renaming global variables for djgpp--i.e., always use prefixes in
+ * inlined assembler code (== strings) and conditionally rename the
+ * variables, not the other way around. Hence _const4, _mask8_0, etc.
+ *
+ * 19991024:
+ * - fixed mmxsupport()/png_do_read_interlace() first-row bug
+ * This one was severely weird: even though mmxsupport() doesn't touch
+ * ebx (where "row" pointer was stored), it nevertheless managed to zero
+ * the register (even in static/non-fPIC code--see below), which in turn
+ * caused png_do_read_interlace() to return prematurely on the first row of
+ * interlaced images (i.e., without expanding the interlaced pixels).
+ * Inspection of the generated assembly code didn't turn up any clues,
+ * although it did point at a minor optimization (i.e., get rid of
+ * mmx_supported_local variable and just use eax). Possibly the CPUID
+ * instruction is more destructive than it looks? (Not yet checked.)
+ * - "info gcc" was next to useless, so compared fPIC and non-fPIC assembly
+ * listings... Apparently register spillage has to do with ebx, since
+ * it's used to index the global offset table. Commenting it out of the
+ * input-reg lists in png_combine_row() eliminated compiler barfage, so
+ * ifdef'd with __PIC__ macro: if defined, use a global for untqmask
+ *
+ * 19991107:
+ * - verified CPUID clobberage: 12-char string constant ("GenuineIntel",
+ * "AuthenticAMD", etc.) placed in ebx:ecx:edx. Still need to polish.
+ *
+ * 19991120:
+ * - made "diff" variable (now "_dif") global to simplify conversion of
+ * filtering routines (running out of regs, sigh). "diff" is still used
+ * in interlacing routines, however.
+ * - fixed up both versions of mmxsupport() (ORIG_THAT_USED_TO_CLOBBER_EBX
+ * macro determines which is used); original not yet tested.
+ *
+ * 20000213:
+ * - when compiling with gcc, be sure to use -fomit-frame-pointer
+ *
+ * 20000319:
+ * - fixed a register-name typo in png_do_read_interlace(), default (MMX) case,
+ * pass == 4 or 5, that caused visible corruption of interlaced images
+ *
+ * 20000623:
+ * - Various problems were reported with gcc 2.95.2 in the Cygwin environment,
+ * many of the form "forbidden register 0 (ax) was spilled for class AREG."
+ * This is explained at http://gcc.gnu.org/fom_serv/cache/23.html, and
+ * Chuck Wilson supplied a patch involving dummy output registers. See
+ * http://sourceforge.net/bugs/?func=detailbug&bug_id=108741&group_id=5624
+ * for the original (anonymous) SourceForge bug report.
+ *
+ * 20000706:
+ * - Chuck Wilson passed along these remaining gcc 2.95.2 errors:
+ * pnggccrd.c: In function `png_combine_row':
+ * pnggccrd.c:525: more than 10 operands in `asm'
+ * pnggccrd.c:669: more than 10 operands in `asm'
+ * pnggccrd.c:828: more than 10 operands in `asm'
+ * pnggccrd.c:994: more than 10 operands in `asm'
+ * pnggccrd.c:1177: more than 10 operands in `asm'
+ * They are all the same problem and can be worked around by using the
+ * global _untqmask variable unconditionally, not just in the -fPIC case.
+ * Reportedly earlier versions of gcc also have the problem with more than
+ * 10 operands; they just don't report it. Much strangeness ensues, etc.
+ *
+ * 20000729:
+ * - enabled png_read_filter_row_mmx_up() (shortest remaining unconverted
+ * MMX routine); began converting png_read_filter_row_mmx_sub()
+ * - to finish remaining sections:
+ * - clean up indentation and comments
+ * - preload local variables
+ * - add output and input regs (order of former determines numerical
+ * mapping of latter)
+ * - avoid all usage of ebx (including bx, bh, bl) register [20000823]
+ * - remove "$" from addressing of Shift and Mask variables [20000823]
+ *
+ * 20000731:
+ * - global union vars causing segfaults in png_read_filter_row_mmx_sub()?
+ *
+ * 20000822:
+ * - ARGH, stupid png_read_filter_row_mmx_sub() segfault only happens with
+ * shared-library (-fPIC) version! Code works just fine as part of static
+ * library. Damn damn damn damn damn, should have tested that sooner.
+ * ebx is getting clobbered again (explicitly this time); need to save it
+ * on stack or rewrite asm code to avoid using it altogether. Blargh!
+ *
+ * 20000823:
+ * - first section was trickiest; all remaining sections have ebx -> edx now.
+ * (-fPIC works again.) Also added missing underscores to various Shift*
+ * and *Mask* globals and got rid of leading "$" signs.
+ *
+ * 20000826:
+ * - added visual separators to help navigate microscopic printed copies
+ * (http://pobox.com/~newt/code/gpr-latest.zip, mode 10); started working
+ * on png_read_filter_row_mmx_avg()
+ *
+ * 20000828:
+ * - finished png_read_filter_row_mmx_avg(): only Paeth left! (930 lines...)
+ * What the hell, did png_read_filter_row_mmx_paeth(), too. Comments not
+ * cleaned up/shortened in either routine, but functionality is complete
+ * and seems to be working fine.
+ *
+ * 20000829:
+ * - ahhh, figured out last(?) bit of gcc/gas asm-fu: if register is listed
+ * as an input reg (with dummy output variables, etc.), then it *cannot*
+ * also appear in the clobber list or gcc 2.95.2 will barf. The solution
+ * is simple enough...
+ *
+ * 20000914:
+ * - bug in png_read_filter_row_mmx_avg(): 16-bit grayscale not handled
+ * correctly (but 48-bit RGB just fine)
+ *
+ * 20000916:
+ * - fixed bug in png_read_filter_row_mmx_avg(), bpp == 2 case; three errors:
+ * - "_ShiftBpp.use = 24;" should have been "_ShiftBpp.use = 16;"
+ * - "_ShiftRem.use = 40;" should have been "_ShiftRem.use = 48;"
+ * - "psllq _ShiftRem, %%mm2" should have been "psrlq _ShiftRem, %%mm2"
+ *
+ * 20010101:
+ * - added new png_init_mmx_flags() function (here only because it needs to
+ * call mmxsupport(), which should probably become global png_mmxsupport());
+ * modified other MMX routines to run conditionally (png_ptr->asm_flags)
+ *
+ * 20010103:
+ * - renamed mmxsupport() to png_mmx_support(), with auto-set of mmx_supported,
+ * and made it public; moved png_init_mmx_flags() to png.c as internal func
+ *
+ * 20010104:
+ * - removed dependency on png_read_filter_row_c() (C code already duplicated
+ * within MMX version of png_read_filter_row()) so no longer necessary to
+ * compile it into pngrutil.o
+ *
+ * 20010310:
+ * - fixed buffer-overrun bug in png_combine_row() C code (non-MMX)
+ *
+ * 20020304:
+ * - eliminated incorrect use of width_mmx in pixel_bytes == 8 case
+ *
+ * STILL TO DO:
+ * - test png_do_read_interlace() 64-bit case (pixel_bytes == 8)
+ * - write MMX code for 48-bit case (pixel_bytes == 6)
+ * - figure out what's up with 24-bit case (pixel_bytes == 3):
+ * why subtract 8 from width_mmx in the pass 4/5 case?
+ * (only width_mmx case) (near line 1606)
+ * - rewrite all MMX interlacing code so it's aligned with beginning
+ * of the row buffer, not the end (see 19991007 for details)
+ * x pick one version of mmxsupport() and get rid of the other
+ * - add error messages to any remaining bogus default cases
+ * - enable pixel_depth == 8 cases in png_read_filter_row()? (test speed)
+ * x add support for runtime enable/disable/query of various MMX routines
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_USE_PNGGCCRD)
+
+int PNGAPI png_mmx_support(void);
+
+#ifdef PNG_USE_LOCAL_ARRAYS
+static const int FARDATA png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+static const int FARDATA png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+static const int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1};
+#endif
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+/* djgpp, Win32, and Cygwin add their own underscores to global variables,
+ * so define them without: */
+#if defined(__DJGPP__) || defined(WIN32) || defined(__CYGWIN__)
+# define _mmx_supported mmx_supported
+# define _const4 const4
+# define _const6 const6
+# define _mask8_0 tqmask8_0
+# define _mask16_1 tqmask16_1
+# define _mask16_0 tqmask16_0
+# define _mask24_2 tqmask24_2
+# define _mask24_1 tqmask24_1
+# define _mask24_0 tqmask24_0
+# define _mask32_3 tqmask32_3
+# define _mask32_2 tqmask32_2
+# define _mask32_1 tqmask32_1
+# define _mask32_0 tqmask32_0
+# define _mask48_5 tqmask48_5
+# define _mask48_4 tqmask48_4
+# define _mask48_3 tqmask48_3
+# define _mask48_2 tqmask48_2
+# define _mask48_1 tqmask48_1
+# define _mask48_0 tqmask48_0
+# define _LBCarryMask LBCarryMask
+# define _HBClearMask HBClearMask
+# define _ActiveMask ActiveMask
+# define _ActiveMask2 ActiveMask2
+# define _ActiveMaskEnd ActiveMaskEnd
+# define _ShiftBpp ShiftBpp
+# define _ShiftRem ShiftRem
+#ifdef PNG_THREAD_UNSAFE_OK
+# define _untqmask untqmask
+# define _FullLength FullLength
+# define _MMXLength MMXLength
+# define _dif dif
+# define _patemp patemp
+# define _pbtemp pbtemp
+# define _pctemp pctemp
+#endif
+#endif
+
+
+/* These constants are used in the inlined MMX assembly code.
+ Ignore gcc's "At top level: defined but not used" warnings. */
+
+/* GRR 20000706: originally _untqmask was needed only when compiling with -fPIC,
+ * since that case uses the %ebx register for indexing the Global Offset Table
+ * and there were no other registers available. But gcc 2.95 and later emit
+ * "more than 10 operands in `asm'" errors when %ebx is used to preload untqmask
+ * in the non-PIC case, so we'll just use the global unconditionally now.
+ */
+#ifdef PNG_THREAD_UNSAFE_OK
+static int _untqmask;
+#endif
+
+static unsigned long long _mask8_0 = 0x0102040810204080LL;
+
+static unsigned long long _mask16_1 = 0x0101020204040808LL;
+static unsigned long long _mask16_0 = 0x1010202040408080LL;
+
+static unsigned long long _mask24_2 = 0x0101010202020404LL;
+static unsigned long long _mask24_1 = 0x0408080810101020LL;
+static unsigned long long _mask24_0 = 0x2020404040808080LL;
+
+static unsigned long long _mask32_3 = 0x0101010102020202LL;
+static unsigned long long _mask32_2 = 0x0404040408080808LL;
+static unsigned long long _mask32_1 = 0x1010101020202020LL;
+static unsigned long long _mask32_0 = 0x4040404080808080LL;
+
+static unsigned long long _mask48_5 = 0x0101010101010202LL;
+static unsigned long long _mask48_4 = 0x0202020204040404LL;
+static unsigned long long _mask48_3 = 0x0404080808080808LL;
+static unsigned long long _mask48_2 = 0x1010101010102020LL;
+static unsigned long long _mask48_1 = 0x2020202040404040LL;
+static unsigned long long _mask48_0 = 0x4040808080808080LL;
+
+static unsigned long long _const4 = 0x0000000000FFFFFFLL;
+//static unsigned long long _const5 = 0x000000FFFFFF0000LL; // NOT USED
+static unsigned long long _const6 = 0x00000000000000FFLL;
+
+// These are used in the row-filter routines and should/would be local
+// variables if not for gcc addressing limitations.
+// WARNING: Their presence probably defeats the thread safety of libpng.
+
+#ifdef PNG_THREAD_UNSAFE_OK
+static png_uint_32 _FullLength;
+static png_uint_32 _MMXLength;
+static int _dif;
+static int _patemp; // temp variables for Paeth routine
+static int _pbtemp;
+static int _pctemp;
+#endif
+
+void /* PRIVATE */
+png_squelch_warnings(void)
+{
+#ifdef PNG_THREAD_UNSAFE_OK
+ _dif = _dif;
+ _patemp = _patemp;
+ _pbtemp = _pbtemp;
+ _pctemp = _pctemp;
+ _MMXLength = _MMXLength;
+#endif
+ _const4 = _const4;
+ _const6 = _const6;
+ _mask8_0 = _mask8_0;
+ _mask16_1 = _mask16_1;
+ _mask16_0 = _mask16_0;
+ _mask24_2 = _mask24_2;
+ _mask24_1 = _mask24_1;
+ _mask24_0 = _mask24_0;
+ _mask32_3 = _mask32_3;
+ _mask32_2 = _mask32_2;
+ _mask32_1 = _mask32_1;
+ _mask32_0 = _mask32_0;
+ _mask48_5 = _mask48_5;
+ _mask48_4 = _mask48_4;
+ _mask48_3 = _mask48_3;
+ _mask48_2 = _mask48_2;
+ _mask48_1 = _mask48_1;
+ _mask48_0 = _mask48_0;
+}
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
+
+static int _mmx_supported = 2;
+
+/*===========================================================================*/
+/* */
+/* P N G _ C O M B I N E _ R O W */
+/* */
+/*===========================================================================*/
+
+#if defined(PNG_HAVE_ASSEMBLER_COMBINE_ROW)
+
+#define BPP2 2
+#define BPP3 3 /* bytes per pixel (a.k.a. pixel_bytes) */
+#define BPP4 4
+#define BPP6 6 /* (defined only to help avoid cut-and-paste errors) */
+#define BPP8 8
+
+/* Combines the row recently read in with the previous row.
+ This routine takes care of alpha and transparency if requested.
+ This routine also handles the two methods of progressive display
+ of interlaced images, depending on the tqmask value.
+ The tqmask value describes which pixels are to be combined with
+ the row. The pattern always repeats every 8 pixels, so just 8
+ bits are needed. A one indicates the pixel is to be combined; a
+ zero indicates the pixel is to be skipped. This is in addition
+ to any alpha or transparency value associated with the pixel.
+ If you want all pixels to be combined, pass 0xff (255) in tqmask. */
+
+/* Use this routine for the x86 platform - it uses a faster MMX routine
+ if the machine supports MMX. */
+
+void /* PRIVATE */
+png_combine_row(png_structp png_ptr, png_bytep row, int tqmask)
+{
+ png_debug(1, "in png_combine_row (pnggccrd.c)\n");
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+ if (_mmx_supported == 2) {
+ /* this should have happened in png_init_mmx_flags() already */
+ png_warning(png_ptr, "asm_flags may not have been initialized");
+ png_mmx_support();
+ }
+#endif
+
+ if (tqmask == 0xff)
+ {
+ png_debug(2,"tqmask == 0xff: doing single png_memcpy()\n");
+ png_memcpy(row, png_ptr->row_buf + 1,
+ (png_size_t)((png_ptr->width * png_ptr->row_info.pixel_depth + 7) >> 3));
+ }
+ else /* (png_combine_row() is never called with tqmask == 0) */
+ {
+ switch (png_ptr->row_info.pixel_depth)
+ {
+ case 1: /* png_ptr->row_info.pixel_depth */
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int s_inc, s_start, s_end;
+ int m;
+ int shift;
+ png_uint_32 i;
+
+ sp = png_ptr->row_buf + 1;
+ dp = row;
+ m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+ else
+#endif
+ {
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+
+ shift = s_start;
+
+ for (i = 0; i < png_ptr->width; i++)
+ {
+ if (m & tqmask)
+ {
+ int value;
+
+ value = (*sp >> shift) & 0x1;
+ *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+
+ case 2: /* png_ptr->row_info.pixel_depth */
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int s_start, s_end, s_inc;
+ int m;
+ int shift;
+ png_uint_32 i;
+ int value;
+
+ sp = png_ptr->row_buf + 1;
+ dp = row;
+ m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+ else
+#endif
+ {
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+
+ shift = s_start;
+
+ for (i = 0; i < png_ptr->width; i++)
+ {
+ if (m & tqmask)
+ {
+ value = (*sp >> shift) & 0x3;
+ *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+
+ case 4: /* png_ptr->row_info.pixel_depth */
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int s_start, s_end, s_inc;
+ int m;
+ int shift;
+ png_uint_32 i;
+ int value;
+
+ sp = png_ptr->row_buf + 1;
+ dp = row;
+ m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+ else
+#endif
+ {
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+ shift = s_start;
+
+ for (i = 0; i < png_ptr->width; i++)
+ {
+ if (m & tqmask)
+ {
+ value = (*sp >> shift) & 0xf;
+ *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+
+ case 8: /* png_ptr->row_info.pixel_depth */
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
+ /* && _mmx_supported */ )
+#else
+ if (_mmx_supported)
+#endif
+ {
+ png_uint_32 len;
+ int diff;
+ int dummy_value_a; // fix 'forbidden register spilled' error
+ int dummy_value_d;
+ int dummy_value_c;
+ int dummy_value_S;
+ int dummy_value_D;
+ _untqmask = ~tqmask; // global variable for -fPIC version
+ srcptr = png_ptr->row_buf + 1;
+ dstptr = row;
+ len = png_ptr->width &~7; // reduce to multiple of 8
+ diff = (int) (png_ptr->width & 7); // amount lost
+
+ __asm__ __volatile__ (
+ "movd _untqmask, %%mm7 \n\t" // load bit pattern
+ "psubb %%mm6, %%mm6 \n\t" // zero mm6
+ "punpcklbw %%mm7, %%mm7 \n\t"
+ "punpcklwd %%mm7, %%mm7 \n\t"
+ "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks
+
+ "movq _mask8_0, %%mm0 \n\t"
+ "pand %%mm7, %%mm0 \n\t" // nonzero if keep byte
+ "pcmpeqb %%mm6, %%mm0 \n\t" // zeros->1s, v versa
+
+// preload "movl len, %%ecx \n\t" // load length of line
+// preload "movl srcptr, %%esi \n\t" // load source
+// preload "movl dstptr, %%edi \n\t" // load dest
+
+ "cmpl $0, %%ecx \n\t" // len == 0 ?
+ "je mainloop8end \n\t"
+
+ "mainloop8: \n\t"
+ "movq (%%esi), %%mm4 \n\t" // *srcptr
+ "pand %%mm0, %%mm4 \n\t"
+ "movq %%mm0, %%mm6 \n\t"
+ "pandn (%%edi), %%mm6 \n\t" // *dstptr
+ "por %%mm6, %%mm4 \n\t"
+ "movq %%mm4, (%%edi) \n\t"
+ "addl $8, %%esi \n\t" // inc by 8 bytes processed
+ "addl $8, %%edi \n\t"
+ "subl $8, %%ecx \n\t" // dec by 8 pixels processed
+ "ja mainloop8 \n\t"
+
+ "mainloop8end: \n\t"
+// preload "movl diff, %%ecx \n\t" // (diff is in eax)
+ "movl %%eax, %%ecx \n\t"
+ "cmpl $0, %%ecx \n\t"
+ "jz end8 \n\t"
+// preload "movl tqmask, %%edx \n\t"
+ "sall $24, %%edx \n\t" // make low byte, high byte
+
+ "secondloop8: \n\t"
+ "sall %%edx \n\t" // move high bit to CF
+ "jnc skip8 \n\t" // if CF = 0
+ "movb (%%esi), %%al \n\t"
+ "movb %%al, (%%edi) \n\t"
+
+ "skip8: \n\t"
+ "incl %%esi \n\t"
+ "incl %%edi \n\t"
+ "decl %%ecx \n\t"
+ "jnz secondloop8 \n\t"
+
+ "end8: \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=a" (dummy_value_a), // output regs (dummy)
+ "=d" (dummy_value_d),
+ "=c" (dummy_value_c),
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "3" (srcptr), // esi // input regs
+ "4" (dstptr), // edi
+ "0" (diff), // eax
+// was (untqmask) "b" RESERVED // ebx // Global Offset Table idx
+ "2" (len), // ecx
+ "1" (tqmask) // edx
+
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm4", "%mm6", "%mm7" // clobber list
+#endif
+ );
+ }
+ else /* mmx _not supported - Use modified C routine */
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+ {
+ register png_uint_32 i;
+ png_uint_32 initial_val = png_pass_start[png_ptr->pass];
+ /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
+ register int stride = png_pass_inc[png_ptr->pass];
+ /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
+ register int rep_bytes = png_pass_width[png_ptr->pass];
+ /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
+ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
+ int diff = (int) (png_ptr->width & 7); /* amount lost */
+ register png_uint_32 final_val = len; /* GRR bugfix */
+
+ srcptr = png_ptr->row_buf + 1 + initial_val;
+ dstptr = row + initial_val;
+
+ for (i = initial_val; i < final_val; i += stride)
+ {
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ if (diff) /* number of leftover pixels: 3 for pngtest */
+ {
+ final_val+=diff /* *BPP1 */ ;
+ for (; i < final_val; i += stride)
+ {
+ if (rep_bytes > (int)(final_val-i))
+ rep_bytes = (int)(final_val-i);
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ }
+
+ } /* end of else (_mmx_supported) */
+
+ break;
+ } /* end 8 bpp */
+
+ case 16: /* png_ptr->row_info.pixel_depth */
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
+ /* && _mmx_supported */ )
+#else
+ if (_mmx_supported)
+#endif
+ {
+ png_uint_32 len;
+ int diff;
+ int dummy_value_a; // fix 'forbidden register spilled' error
+ int dummy_value_d;
+ int dummy_value_c;
+ int dummy_value_S;
+ int dummy_value_D;
+ _untqmask = ~tqmask; // global variable for -fPIC version
+ srcptr = png_ptr->row_buf + 1;
+ dstptr = row;
+ len = png_ptr->width &~7; // reduce to multiple of 8
+ diff = (int) (png_ptr->width & 7); // amount lost //
+
+ __asm__ __volatile__ (
+ "movd _untqmask, %%mm7 \n\t" // load bit pattern
+ "psubb %%mm6, %%mm6 \n\t" // zero mm6
+ "punpcklbw %%mm7, %%mm7 \n\t"
+ "punpcklwd %%mm7, %%mm7 \n\t"
+ "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks
+
+ "movq _mask16_0, %%mm0 \n\t"
+ "movq _mask16_1, %%mm1 \n\t"
+
+ "pand %%mm7, %%mm0 \n\t"
+ "pand %%mm7, %%mm1 \n\t"
+
+ "pcmpeqb %%mm6, %%mm0 \n\t"
+ "pcmpeqb %%mm6, %%mm1 \n\t"
+
+// preload "movl len, %%ecx \n\t" // load length of line
+// preload "movl srcptr, %%esi \n\t" // load source
+// preload "movl dstptr, %%edi \n\t" // load dest
+
+ "cmpl $0, %%ecx \n\t"
+ "jz mainloop16end \n\t"
+
+ "mainloop16: \n\t"
+ "movq (%%esi), %%mm4 \n\t"
+ "pand %%mm0, %%mm4 \n\t"
+ "movq %%mm0, %%mm6 \n\t"
+ "movq (%%edi), %%mm7 \n\t"
+ "pandn %%mm7, %%mm6 \n\t"
+ "por %%mm6, %%mm4 \n\t"
+ "movq %%mm4, (%%edi) \n\t"
+
+ "movq 8(%%esi), %%mm5 \n\t"
+ "pand %%mm1, %%mm5 \n\t"
+ "movq %%mm1, %%mm7 \n\t"
+ "movq 8(%%edi), %%mm6 \n\t"
+ "pandn %%mm6, %%mm7 \n\t"
+ "por %%mm7, %%mm5 \n\t"
+ "movq %%mm5, 8(%%edi) \n\t"
+
+ "addl $16, %%esi \n\t" // inc by 16 bytes processed
+ "addl $16, %%edi \n\t"
+ "subl $8, %%ecx \n\t" // dec by 8 pixels processed
+ "ja mainloop16 \n\t"
+
+ "mainloop16end: \n\t"
+// preload "movl diff, %%ecx \n\t" // (diff is in eax)
+ "movl %%eax, %%ecx \n\t"
+ "cmpl $0, %%ecx \n\t"
+ "jz end16 \n\t"
+// preload "movl tqmask, %%edx \n\t"
+ "sall $24, %%edx \n\t" // make low byte, high byte
+
+ "secondloop16: \n\t"
+ "sall %%edx \n\t" // move high bit to CF
+ "jnc skip16 \n\t" // if CF = 0
+ "movw (%%esi), %%ax \n\t"
+ "movw %%ax, (%%edi) \n\t"
+
+ "skip16: \n\t"
+ "addl $2, %%esi \n\t"
+ "addl $2, %%edi \n\t"
+ "decl %%ecx \n\t"
+ "jnz secondloop16 \n\t"
+
+ "end16: \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=a" (dummy_value_a), // output regs (dummy)
+ "=c" (dummy_value_c),
+ "=d" (dummy_value_d),
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "0" (diff), // eax // input regs
+// was (untqmask) " " RESERVED // ebx // Global Offset Table idx
+ "1" (len), // ecx
+ "2" (tqmask), // edx
+ "3" (srcptr), // esi
+ "4" (dstptr) // edi
+
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1", "%mm4" // clobber list
+ , "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ else /* mmx _not supported - Use modified C routine */
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+ {
+ register png_uint_32 i;
+ png_uint_32 initial_val = BPP2 * png_pass_start[png_ptr->pass];
+ /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
+ register int stride = BPP2 * png_pass_inc[png_ptr->pass];
+ /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
+ register int rep_bytes = BPP2 * png_pass_width[png_ptr->pass];
+ /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
+ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
+ int diff = (int) (png_ptr->width & 7); /* amount lost */
+ register png_uint_32 final_val = BPP2 * len; /* GRR bugfix */
+
+ srcptr = png_ptr->row_buf + 1 + initial_val;
+ dstptr = row + initial_val;
+
+ for (i = initial_val; i < final_val; i += stride)
+ {
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ if (diff) /* number of leftover pixels: 3 for pngtest */
+ {
+ final_val+=diff*BPP2;
+ for (; i < final_val; i += stride)
+ {
+ if (rep_bytes > (int)(final_val-i))
+ rep_bytes = (int)(final_val-i);
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ }
+ } /* end of else (_mmx_supported) */
+
+ break;
+ } /* end 16 bpp */
+
+ case 24: /* png_ptr->row_info.pixel_depth */
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
+ /* && _mmx_supported */ )
+#else
+ if (_mmx_supported)
+#endif
+ {
+ png_uint_32 len;
+ int diff;
+ int dummy_value_a; // fix 'forbidden register spilled' error
+ int dummy_value_d;
+ int dummy_value_c;
+ int dummy_value_S;
+ int dummy_value_D;
+ _untqmask = ~tqmask; // global variable for -fPIC version
+ srcptr = png_ptr->row_buf + 1;
+ dstptr = row;
+ len = png_ptr->width &~7; // reduce to multiple of 8
+ diff = (int) (png_ptr->width & 7); // amount lost //
+
+ __asm__ __volatile__ (
+ "movd _untqmask, %%mm7 \n\t" // load bit pattern
+ "psubb %%mm6, %%mm6 \n\t" // zero mm6
+ "punpcklbw %%mm7, %%mm7 \n\t"
+ "punpcklwd %%mm7, %%mm7 \n\t"
+ "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks
+
+ "movq _mask24_0, %%mm0 \n\t"
+ "movq _mask24_1, %%mm1 \n\t"
+ "movq _mask24_2, %%mm2 \n\t"
+
+ "pand %%mm7, %%mm0 \n\t"
+ "pand %%mm7, %%mm1 \n\t"
+ "pand %%mm7, %%mm2 \n\t"
+
+ "pcmpeqb %%mm6, %%mm0 \n\t"
+ "pcmpeqb %%mm6, %%mm1 \n\t"
+ "pcmpeqb %%mm6, %%mm2 \n\t"
+
+// preload "movl len, %%ecx \n\t" // load length of line
+// preload "movl srcptr, %%esi \n\t" // load source
+// preload "movl dstptr, %%edi \n\t" // load dest
+
+ "cmpl $0, %%ecx \n\t"
+ "jz mainloop24end \n\t"
+
+ "mainloop24: \n\t"
+ "movq (%%esi), %%mm4 \n\t"
+ "pand %%mm0, %%mm4 \n\t"
+ "movq %%mm0, %%mm6 \n\t"
+ "movq (%%edi), %%mm7 \n\t"
+ "pandn %%mm7, %%mm6 \n\t"
+ "por %%mm6, %%mm4 \n\t"
+ "movq %%mm4, (%%edi) \n\t"
+
+ "movq 8(%%esi), %%mm5 \n\t"
+ "pand %%mm1, %%mm5 \n\t"
+ "movq %%mm1, %%mm7 \n\t"
+ "movq 8(%%edi), %%mm6 \n\t"
+ "pandn %%mm6, %%mm7 \n\t"
+ "por %%mm7, %%mm5 \n\t"
+ "movq %%mm5, 8(%%edi) \n\t"
+
+ "movq 16(%%esi), %%mm6 \n\t"
+ "pand %%mm2, %%mm6 \n\t"
+ "movq %%mm2, %%mm4 \n\t"
+ "movq 16(%%edi), %%mm7 \n\t"
+ "pandn %%mm7, %%mm4 \n\t"
+ "por %%mm4, %%mm6 \n\t"
+ "movq %%mm6, 16(%%edi) \n\t"
+
+ "addl $24, %%esi \n\t" // inc by 24 bytes processed
+ "addl $24, %%edi \n\t"
+ "subl $8, %%ecx \n\t" // dec by 8 pixels processed
+
+ "ja mainloop24 \n\t"
+
+ "mainloop24end: \n\t"
+// preload "movl diff, %%ecx \n\t" // (diff is in eax)
+ "movl %%eax, %%ecx \n\t"
+ "cmpl $0, %%ecx \n\t"
+ "jz end24 \n\t"
+// preload "movl tqmask, %%edx \n\t"
+ "sall $24, %%edx \n\t" // make low byte, high byte
+
+ "secondloop24: \n\t"
+ "sall %%edx \n\t" // move high bit to CF
+ "jnc skip24 \n\t" // if CF = 0
+ "movw (%%esi), %%ax \n\t"
+ "movw %%ax, (%%edi) \n\t"
+ "xorl %%eax, %%eax \n\t"
+ "movb 2(%%esi), %%al \n\t"
+ "movb %%al, 2(%%edi) \n\t"
+
+ "skip24: \n\t"
+ "addl $3, %%esi \n\t"
+ "addl $3, %%edi \n\t"
+ "decl %%ecx \n\t"
+ "jnz secondloop24 \n\t"
+
+ "end24: \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=a" (dummy_value_a), // output regs (dummy)
+ "=d" (dummy_value_d),
+ "=c" (dummy_value_c),
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "3" (srcptr), // esi // input regs
+ "4" (dstptr), // edi
+ "0" (diff), // eax
+// was (untqmask) "b" RESERVED // ebx // Global Offset Table idx
+ "2" (len), // ecx
+ "1" (tqmask) // edx
+
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1", "%mm2" // clobber list
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ else /* mmx _not supported - Use modified C routine */
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+ {
+ register png_uint_32 i;
+ png_uint_32 initial_val = BPP3 * png_pass_start[png_ptr->pass];
+ /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
+ register int stride = BPP3 * png_pass_inc[png_ptr->pass];
+ /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
+ register int rep_bytes = BPP3 * png_pass_width[png_ptr->pass];
+ /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
+ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
+ int diff = (int) (png_ptr->width & 7); /* amount lost */
+ register png_uint_32 final_val = BPP3 * len; /* GRR bugfix */
+
+ srcptr = png_ptr->row_buf + 1 + initial_val;
+ dstptr = row + initial_val;
+
+ for (i = initial_val; i < final_val; i += stride)
+ {
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ if (diff) /* number of leftover pixels: 3 for pngtest */
+ {
+ final_val+=diff*BPP3;
+ for (; i < final_val; i += stride)
+ {
+ if (rep_bytes > (int)(final_val-i))
+ rep_bytes = (int)(final_val-i);
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ }
+ } /* end of else (_mmx_supported) */
+
+ break;
+ } /* end 24 bpp */
+
+ case 32: /* png_ptr->row_info.pixel_depth */
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
+ /* && _mmx_supported */ )
+#else
+ if (_mmx_supported)
+#endif
+ {
+ png_uint_32 len;
+ int diff;
+ int dummy_value_a; // fix 'forbidden register spilled' error
+ int dummy_value_d;
+ int dummy_value_c;
+ int dummy_value_S;
+ int dummy_value_D;
+ _untqmask = ~tqmask; // global variable for -fPIC version
+ srcptr = png_ptr->row_buf + 1;
+ dstptr = row;
+ len = png_ptr->width &~7; // reduce to multiple of 8
+ diff = (int) (png_ptr->width & 7); // amount lost //
+
+ __asm__ __volatile__ (
+ "movd _untqmask, %%mm7 \n\t" // load bit pattern
+ "psubb %%mm6, %%mm6 \n\t" // zero mm6
+ "punpcklbw %%mm7, %%mm7 \n\t"
+ "punpcklwd %%mm7, %%mm7 \n\t"
+ "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks
+
+ "movq _mask32_0, %%mm0 \n\t"
+ "movq _mask32_1, %%mm1 \n\t"
+ "movq _mask32_2, %%mm2 \n\t"
+ "movq _mask32_3, %%mm3 \n\t"
+
+ "pand %%mm7, %%mm0 \n\t"
+ "pand %%mm7, %%mm1 \n\t"
+ "pand %%mm7, %%mm2 \n\t"
+ "pand %%mm7, %%mm3 \n\t"
+
+ "pcmpeqb %%mm6, %%mm0 \n\t"
+ "pcmpeqb %%mm6, %%mm1 \n\t"
+ "pcmpeqb %%mm6, %%mm2 \n\t"
+ "pcmpeqb %%mm6, %%mm3 \n\t"
+
+// preload "movl len, %%ecx \n\t" // load length of line
+// preload "movl srcptr, %%esi \n\t" // load source
+// preload "movl dstptr, %%edi \n\t" // load dest
+
+ "cmpl $0, %%ecx \n\t" // lcr
+ "jz mainloop32end \n\t"
+
+ "mainloop32: \n\t"
+ "movq (%%esi), %%mm4 \n\t"
+ "pand %%mm0, %%mm4 \n\t"
+ "movq %%mm0, %%mm6 \n\t"
+ "movq (%%edi), %%mm7 \n\t"
+ "pandn %%mm7, %%mm6 \n\t"
+ "por %%mm6, %%mm4 \n\t"
+ "movq %%mm4, (%%edi) \n\t"
+
+ "movq 8(%%esi), %%mm5 \n\t"
+ "pand %%mm1, %%mm5 \n\t"
+ "movq %%mm1, %%mm7 \n\t"
+ "movq 8(%%edi), %%mm6 \n\t"
+ "pandn %%mm6, %%mm7 \n\t"
+ "por %%mm7, %%mm5 \n\t"
+ "movq %%mm5, 8(%%edi) \n\t"
+
+ "movq 16(%%esi), %%mm6 \n\t"
+ "pand %%mm2, %%mm6 \n\t"
+ "movq %%mm2, %%mm4 \n\t"
+ "movq 16(%%edi), %%mm7 \n\t"
+ "pandn %%mm7, %%mm4 \n\t"
+ "por %%mm4, %%mm6 \n\t"
+ "movq %%mm6, 16(%%edi) \n\t"
+
+ "movq 24(%%esi), %%mm7 \n\t"
+ "pand %%mm3, %%mm7 \n\t"
+ "movq %%mm3, %%mm5 \n\t"
+ "movq 24(%%edi), %%mm4 \n\t"
+ "pandn %%mm4, %%mm5 \n\t"
+ "por %%mm5, %%mm7 \n\t"
+ "movq %%mm7, 24(%%edi) \n\t"
+
+ "addl $32, %%esi \n\t" // inc by 32 bytes processed
+ "addl $32, %%edi \n\t"
+ "subl $8, %%ecx \n\t" // dec by 8 pixels processed
+ "ja mainloop32 \n\t"
+
+ "mainloop32end: \n\t"
+// preload "movl diff, %%ecx \n\t" // (diff is in eax)
+ "movl %%eax, %%ecx \n\t"
+ "cmpl $0, %%ecx \n\t"
+ "jz end32 \n\t"
+// preload "movl tqmask, %%edx \n\t"
+ "sall $24, %%edx \n\t" // low byte => high byte
+
+ "secondloop32: \n\t"
+ "sall %%edx \n\t" // move high bit to CF
+ "jnc skip32 \n\t" // if CF = 0
+ "movl (%%esi), %%eax \n\t"
+ "movl %%eax, (%%edi) \n\t"
+
+ "skip32: \n\t"
+ "addl $4, %%esi \n\t"
+ "addl $4, %%edi \n\t"
+ "decl %%ecx \n\t"
+ "jnz secondloop32 \n\t"
+
+ "end32: \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=a" (dummy_value_a), // output regs (dummy)
+ "=d" (dummy_value_d),
+ "=c" (dummy_value_c),
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "3" (srcptr), // esi // input regs
+ "4" (dstptr), // edi
+ "0" (diff), // eax
+// was (untqmask) "b" RESERVED // ebx // Global Offset Table idx
+ "2" (len), // ecx
+ "1" (tqmask) // edx
+
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ else /* mmx _not supported - Use modified C routine */
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+ {
+ register png_uint_32 i;
+ png_uint_32 initial_val = BPP4 * png_pass_start[png_ptr->pass];
+ /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
+ register int stride = BPP4 * png_pass_inc[png_ptr->pass];
+ /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
+ register int rep_bytes = BPP4 * png_pass_width[png_ptr->pass];
+ /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
+ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
+ int diff = (int) (png_ptr->width & 7); /* amount lost */
+ register png_uint_32 final_val = BPP4 * len; /* GRR bugfix */
+
+ srcptr = png_ptr->row_buf + 1 + initial_val;
+ dstptr = row + initial_val;
+
+ for (i = initial_val; i < final_val; i += stride)
+ {
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ if (diff) /* number of leftover pixels: 3 for pngtest */
+ {
+ final_val+=diff*BPP4;
+ for (; i < final_val; i += stride)
+ {
+ if (rep_bytes > (int)(final_val-i))
+ rep_bytes = (int)(final_val-i);
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ }
+ } /* end of else (_mmx_supported) */
+
+ break;
+ } /* end 32 bpp */
+
+ case 48: /* png_ptr->row_info.pixel_depth */
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
+ /* && _mmx_supported */ )
+#else
+ if (_mmx_supported)
+#endif
+ {
+ png_uint_32 len;
+ int diff;
+ int dummy_value_a; // fix 'forbidden register spilled' error
+ int dummy_value_d;
+ int dummy_value_c;
+ int dummy_value_S;
+ int dummy_value_D;
+ _untqmask = ~tqmask; // global variable for -fPIC version
+ srcptr = png_ptr->row_buf + 1;
+ dstptr = row;
+ len = png_ptr->width &~7; // reduce to multiple of 8
+ diff = (int) (png_ptr->width & 7); // amount lost //
+
+ __asm__ __volatile__ (
+ "movd _untqmask, %%mm7 \n\t" // load bit pattern
+ "psubb %%mm6, %%mm6 \n\t" // zero mm6
+ "punpcklbw %%mm7, %%mm7 \n\t"
+ "punpcklwd %%mm7, %%mm7 \n\t"
+ "punpckldq %%mm7, %%mm7 \n\t" // fill reg with 8 masks
+
+ "movq _mask48_0, %%mm0 \n\t"
+ "movq _mask48_1, %%mm1 \n\t"
+ "movq _mask48_2, %%mm2 \n\t"
+ "movq _mask48_3, %%mm3 \n\t"
+ "movq _mask48_4, %%mm4 \n\t"
+ "movq _mask48_5, %%mm5 \n\t"
+
+ "pand %%mm7, %%mm0 \n\t"
+ "pand %%mm7, %%mm1 \n\t"
+ "pand %%mm7, %%mm2 \n\t"
+ "pand %%mm7, %%mm3 \n\t"
+ "pand %%mm7, %%mm4 \n\t"
+ "pand %%mm7, %%mm5 \n\t"
+
+ "pcmpeqb %%mm6, %%mm0 \n\t"
+ "pcmpeqb %%mm6, %%mm1 \n\t"
+ "pcmpeqb %%mm6, %%mm2 \n\t"
+ "pcmpeqb %%mm6, %%mm3 \n\t"
+ "pcmpeqb %%mm6, %%mm4 \n\t"
+ "pcmpeqb %%mm6, %%mm5 \n\t"
+
+// preload "movl len, %%ecx \n\t" // load length of line
+// preload "movl srcptr, %%esi \n\t" // load source
+// preload "movl dstptr, %%edi \n\t" // load dest
+
+ "cmpl $0, %%ecx \n\t"
+ "jz mainloop48end \n\t"
+
+ "mainloop48: \n\t"
+ "movq (%%esi), %%mm7 \n\t"
+ "pand %%mm0, %%mm7 \n\t"
+ "movq %%mm0, %%mm6 \n\t"
+ "pandn (%%edi), %%mm6 \n\t"
+ "por %%mm6, %%mm7 \n\t"
+ "movq %%mm7, (%%edi) \n\t"
+
+ "movq 8(%%esi), %%mm6 \n\t"
+ "pand %%mm1, %%mm6 \n\t"
+ "movq %%mm1, %%mm7 \n\t"
+ "pandn 8(%%edi), %%mm7 \n\t"
+ "por %%mm7, %%mm6 \n\t"
+ "movq %%mm6, 8(%%edi) \n\t"
+
+ "movq 16(%%esi), %%mm6 \n\t"
+ "pand %%mm2, %%mm6 \n\t"
+ "movq %%mm2, %%mm7 \n\t"
+ "pandn 16(%%edi), %%mm7 \n\t"
+ "por %%mm7, %%mm6 \n\t"
+ "movq %%mm6, 16(%%edi) \n\t"
+
+ "movq 24(%%esi), %%mm7 \n\t"
+ "pand %%mm3, %%mm7 \n\t"
+ "movq %%mm3, %%mm6 \n\t"
+ "pandn 24(%%edi), %%mm6 \n\t"
+ "por %%mm6, %%mm7 \n\t"
+ "movq %%mm7, 24(%%edi) \n\t"
+
+ "movq 32(%%esi), %%mm6 \n\t"
+ "pand %%mm4, %%mm6 \n\t"
+ "movq %%mm4, %%mm7 \n\t"
+ "pandn 32(%%edi), %%mm7 \n\t"
+ "por %%mm7, %%mm6 \n\t"
+ "movq %%mm6, 32(%%edi) \n\t"
+
+ "movq 40(%%esi), %%mm7 \n\t"
+ "pand %%mm5, %%mm7 \n\t"
+ "movq %%mm5, %%mm6 \n\t"
+ "pandn 40(%%edi), %%mm6 \n\t"
+ "por %%mm6, %%mm7 \n\t"
+ "movq %%mm7, 40(%%edi) \n\t"
+
+ "addl $48, %%esi \n\t" // inc by 48 bytes processed
+ "addl $48, %%edi \n\t"
+ "subl $8, %%ecx \n\t" // dec by 8 pixels processed
+
+ "ja mainloop48 \n\t"
+
+ "mainloop48end: \n\t"
+// preload "movl diff, %%ecx \n\t" // (diff is in eax)
+ "movl %%eax, %%ecx \n\t"
+ "cmpl $0, %%ecx \n\t"
+ "jz end48 \n\t"
+// preload "movl tqmask, %%edx \n\t"
+ "sall $24, %%edx \n\t" // make low byte, high byte
+
+ "secondloop48: \n\t"
+ "sall %%edx \n\t" // move high bit to CF
+ "jnc skip48 \n\t" // if CF = 0
+ "movl (%%esi), %%eax \n\t"
+ "movl %%eax, (%%edi) \n\t"
+
+ "skip48: \n\t"
+ "addl $4, %%esi \n\t"
+ "addl $4, %%edi \n\t"
+ "decl %%ecx \n\t"
+ "jnz secondloop48 \n\t"
+
+ "end48: \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=a" (dummy_value_a), // output regs (dummy)
+ "=d" (dummy_value_d),
+ "=c" (dummy_value_c),
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "3" (srcptr), // esi // input regs
+ "4" (dstptr), // edi
+ "0" (diff), // eax
+// was (untqmask) "b" RESERVED // ebx // Global Offset Table idx
+ "2" (len), // ecx
+ "1" (tqmask) // edx
+
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1", "%mm2", "%mm3" // clobber list
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ else /* mmx _not supported - Use modified C routine */
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+ {
+ register png_uint_32 i;
+ png_uint_32 initial_val = BPP6 * png_pass_start[png_ptr->pass];
+ /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
+ register int stride = BPP6 * png_pass_inc[png_ptr->pass];
+ /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
+ register int rep_bytes = BPP6 * png_pass_width[png_ptr->pass];
+ /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
+ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
+ int diff = (int) (png_ptr->width & 7); /* amount lost */
+ register png_uint_32 final_val = BPP6 * len; /* GRR bugfix */
+
+ srcptr = png_ptr->row_buf + 1 + initial_val;
+ dstptr = row + initial_val;
+
+ for (i = initial_val; i < final_val; i += stride)
+ {
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ if (diff) /* number of leftover pixels: 3 for pngtest */
+ {
+ final_val+=diff*BPP6;
+ for (; i < final_val; i += stride)
+ {
+ if (rep_bytes > (int)(final_val-i))
+ rep_bytes = (int)(final_val-i);
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ }
+ } /* end of else (_mmx_supported) */
+
+ break;
+ } /* end 48 bpp */
+
+ case 64: /* png_ptr->row_info.pixel_depth */
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+ register png_uint_32 i;
+ png_uint_32 initial_val = BPP8 * png_pass_start[png_ptr->pass];
+ /* png.c: png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
+ register int stride = BPP8 * png_pass_inc[png_ptr->pass];
+ /* png.c: png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
+ register int rep_bytes = BPP8 * png_pass_width[png_ptr->pass];
+ /* png.c: png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
+ png_uint_32 len = png_ptr->width &~7; /* reduce to mult. of 8 */
+ int diff = (int) (png_ptr->width & 7); /* amount lost */
+ register png_uint_32 final_val = BPP8 * len; /* GRR bugfix */
+
+ srcptr = png_ptr->row_buf + 1 + initial_val;
+ dstptr = row + initial_val;
+
+ for (i = initial_val; i < final_val; i += stride)
+ {
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ if (diff) /* number of leftover pixels: 3 for pngtest */
+ {
+ final_val+=diff*BPP8;
+ for (; i < final_val; i += stride)
+ {
+ if (rep_bytes > (int)(final_val-i))
+ rep_bytes = (int)(final_val-i);
+ png_memcpy(dstptr, srcptr, rep_bytes);
+ srcptr += stride;
+ dstptr += stride;
+ }
+ }
+
+ break;
+ } /* end 64 bpp */
+
+ default: /* png_ptr->row_info.pixel_depth != 1,2,4,8,16,24,32,48,64 */
+ {
+ /* this should never happen */
+ png_warning(png_ptr, "Invalid row_info.pixel_depth in pnggccrd");
+ break;
+ }
+ } /* end switch (png_ptr->row_info.pixel_depth) */
+
+ } /* end if (non-trivial tqmask) */
+
+} /* end png_combine_row() */
+
+#endif /* PNG_HAVE_ASSEMBLER_COMBINE_ROW */
+
+
+
+
+/*===========================================================================*/
+/* */
+/* P N G _ D O _ R E A D _ I N T E R L A C E */
+/* */
+/*===========================================================================*/
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+#if defined(PNG_HAVE_ASSEMBLER_READ_INTERLACE)
+
+/* png_do_read_interlace() is called after any 16-bit to 8-bit conversion
+ * has taken place. [GRR: what other steps come before and/or after?]
+ */
+
+void /* PRIVATE */
+png_do_read_interlace(png_structp png_ptr)
+{
+ png_row_infop row_info = &(png_ptr->row_info);
+ png_bytep row = png_ptr->row_buf + 1;
+ int pass = png_ptr->pass;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ png_uint_32 transformations = png_ptr->transformations;
+#endif
+
+ png_debug(1, "in png_do_read_interlace (pnggccrd.c)\n");
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+ if (_mmx_supported == 2) {
+#if !defined(PNG_1_0_X)
+ /* this should have happened in png_init_mmx_flags() already */
+ png_warning(png_ptr, "asm_flags may not have been initialized");
+#endif
+ png_mmx_support();
+ }
+#endif
+
+ if (row != NULL && row_info != NULL)
+ {
+ png_uint_32 final_width;
+
+ final_width = row_info->width * png_pass_inc[pass];
+
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp, dp;
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ png_byte v;
+ png_uint_32 i;
+ int j;
+
+ sp = row + (png_size_t)((row_info->width - 1) >> 3);
+ dp = row + (png_size_t)((final_width - 1) >> 3);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)((row_info->width + 7) & 7);
+ dshift = (int)((final_width + 7) & 7);
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+ else
+#endif
+ {
+ sshift = 7 - (int)((row_info->width + 7) & 7);
+ dshift = 7 - (int)((final_width + 7) & 7);
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+
+ for (i = row_info->width; i; i--)
+ {
+ v = (png_byte)((*sp >> sshift) & 0x1);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ png_bytep sp, dp;
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ png_uint_32 i;
+
+ sp = row + (png_size_t)((row_info->width - 1) >> 2);
+ dp = row + (png_size_t)((final_width - 1) >> 2);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (png_size_t)(((row_info->width + 3) & 3) << 1);
+ dshift = (png_size_t)(((final_width + 3) & 3) << 1);
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+ else
+#endif
+ {
+ sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
+ dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+
+ for (i = row_info->width; i; i--)
+ {
+ png_byte v;
+ int j;
+
+ v = (png_byte)((*sp >> sshift) & 0x3);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp, dp;
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ png_uint_32 i;
+
+ sp = row + (png_size_t)((row_info->width - 1) >> 1);
+ dp = row + (png_size_t)((final_width - 1) >> 1);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (png_size_t)(((row_info->width + 1) & 1) << 2);
+ dshift = (png_size_t)(((final_width + 1) & 1) << 2);
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+ else
+#endif
+ {
+ sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
+ dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+
+ for (i = row_info->width; i; i--)
+ {
+ png_byte v;
+ int j;
+
+ v = (png_byte)((*sp >> sshift) & 0xf);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+
+ /*====================================================================*/
+
+ default: /* 8-bit or larger (this is where the routine is modified) */
+ {
+#if 0
+// static unsigned long long _const4 = 0x0000000000FFFFFFLL; no good
+// static unsigned long long const4 = 0x0000000000FFFFFFLL; no good
+// unsigned long long _const4 = 0x0000000000FFFFFFLL; no good
+// unsigned long long const4 = 0x0000000000FFFFFFLL; no good
+#endif
+ png_bytep sptr, dp;
+ png_uint_32 i;
+ png_size_t pixel_bytes;
+ int width = (int)row_info->width;
+
+ pixel_bytes = (row_info->pixel_depth >> 3);
+
+ /* point sptr at the last pixel in the pre-expanded row: */
+ sptr = row + (width - 1) * pixel_bytes;
+
+ /* point dp at the last pixel position in the expanded row: */
+ dp = row + (final_width - 1) * pixel_bytes;
+
+ /* New code by Nirav Chhatrapati - Intel Corporation */
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+#if !defined(PNG_1_0_X)
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE)
+ /* && _mmx_supported */ )
+#else
+ if (_mmx_supported)
+#endif
+ {
+ //--------------------------------------------------------------
+ if (pixel_bytes == 3)
+ {
+ if (((pass == 0) || (pass == 1)) && width)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $21, %%edi \n\t"
+ // (png_pass_inc[pass] - 1)*pixel_bytes
+
+ ".loop3_pass0: \n\t"
+ "movd (%%esi), %%mm0 \n\t" // x x x x x 2 1 0
+ "pand _const4, %%mm0 \n\t" // z z z z z 2 1 0
+ "movq %%mm0, %%mm1 \n\t" // z z z z z 2 1 0
+ "psllq $16, %%mm0 \n\t" // z z z 2 1 0 z z
+ "movq %%mm0, %%mm2 \n\t" // z z z 2 1 0 z z
+ "psllq $24, %%mm0 \n\t" // 2 1 0 z z z z z
+ "psrlq $8, %%mm1 \n\t" // z z z z z z 2 1
+ "por %%mm2, %%mm0 \n\t" // 2 1 0 2 1 0 z z
+ "por %%mm1, %%mm0 \n\t" // 2 1 0 2 1 0 2 1
+ "movq %%mm0, %%mm3 \n\t" // 2 1 0 2 1 0 2 1
+ "psllq $16, %%mm0 \n\t" // 0 2 1 0 2 1 z z
+ "movq %%mm3, %%mm4 \n\t" // 2 1 0 2 1 0 2 1
+ "punpckhdq %%mm0, %%mm3 \n\t" // 0 2 1 0 2 1 0 2
+ "movq %%mm4, 16(%%edi) \n\t"
+ "psrlq $32, %%mm0 \n\t" // z z z z 0 2 1 0
+ "movq %%mm3, 8(%%edi) \n\t"
+ "punpckldq %%mm4, %%mm0 \n\t" // 1 0 2 1 0 2 1 0
+ "subl $3, %%esi \n\t"
+ "movq %%mm0, (%%edi) \n\t"
+ "subl $24, %%edi \n\t"
+ "decl %%ecx \n\t"
+ "jnz .loop3_pass0 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width) // ecx
+// doesn't work "i" (0x0000000000FFFFFFLL) // %1 (a.k.a. _const4)
+
+#if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1", "%mm2" // clobber list
+ , "%mm3", "%mm4"
+#endif
+ );
+ }
+ else if (((pass == 2) || (pass == 3)) && width)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $9, %%edi \n\t"
+ // (png_pass_inc[pass] - 1)*pixel_bytes
+
+ ".loop3_pass2: \n\t"
+ "movd (%%esi), %%mm0 \n\t" // x x x x x 2 1 0
+ "pand _const4, %%mm0 \n\t" // z z z z z 2 1 0
+ "movq %%mm0, %%mm1 \n\t" // z z z z z 2 1 0
+ "psllq $16, %%mm0 \n\t" // z z z 2 1 0 z z
+ "movq %%mm0, %%mm2 \n\t" // z z z 2 1 0 z z
+ "psllq $24, %%mm0 \n\t" // 2 1 0 z z z z z
+ "psrlq $8, %%mm1 \n\t" // z z z z z z 2 1
+ "por %%mm2, %%mm0 \n\t" // 2 1 0 2 1 0 z z
+ "por %%mm1, %%mm0 \n\t" // 2 1 0 2 1 0 2 1
+ "movq %%mm0, 4(%%edi) \n\t"
+ "psrlq $16, %%mm0 \n\t" // z z 2 1 0 2 1 0
+ "subl $3, %%esi \n\t"
+ "movd %%mm0, (%%edi) \n\t"
+ "subl $12, %%edi \n\t"
+ "decl %%ecx \n\t"
+ "jnz .loop3_pass2 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width) // ecx
+
+#if 0 /* %mm0, ..., %mm2 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1", "%mm2" // clobber list
+#endif
+ );
+ }
+ else if (width) /* && ((pass == 4) || (pass == 5)) */
+ {
+ int width_mmx = ((width >> 1) << 1) - 8; // GRR: huh?
+ if (width_mmx < 0)
+ width_mmx = 0;
+ width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes
+ if (width_mmx)
+ {
+ // png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+ // sptr points at last pixel in pre-expanded row
+ // dp points at last pixel position in expanded row
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $3, %%esi \n\t"
+ "subl $9, %%edi \n\t"
+ // (png_pass_inc[pass] + 1)*pixel_bytes
+
+ ".loop3_pass4: \n\t"
+ "movq (%%esi), %%mm0 \n\t" // x x 5 4 3 2 1 0
+ "movq %%mm0, %%mm1 \n\t" // x x 5 4 3 2 1 0
+ "movq %%mm0, %%mm2 \n\t" // x x 5 4 3 2 1 0
+ "psllq $24, %%mm0 \n\t" // 4 3 2 1 0 z z z
+ "pand _const4, %%mm1 \n\t" // z z z z z 2 1 0
+ "psrlq $24, %%mm2 \n\t" // z z z x x 5 4 3
+ "por %%mm1, %%mm0 \n\t" // 4 3 2 1 0 2 1 0
+ "movq %%mm2, %%mm3 \n\t" // z z z x x 5 4 3
+ "psllq $8, %%mm2 \n\t" // z z x x 5 4 3 z
+ "movq %%mm0, (%%edi) \n\t"
+ "psrlq $16, %%mm3 \n\t" // z z z z z x x 5
+ "pand _const6, %%mm3 \n\t" // z z z z z z z 5
+ "por %%mm3, %%mm2 \n\t" // z z x x 5 4 3 5
+ "subl $6, %%esi \n\t"
+ "movd %%mm2, 8(%%edi) \n\t"
+ "subl $12, %%edi \n\t"
+ "subl $2, %%ecx \n\t"
+ "jnz .loop3_pass4 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width_mmx) // ecx
+
+#if 0 /* %mm0, ..., %mm3 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1" // clobber list
+ , "%mm2", "%mm3"
+#endif
+ );
+ }
+
+ sptr -= width_mmx*3;
+ dp -= width_mmx*6;
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+
+ png_memcpy(v, sptr, 3);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, 3);
+ dp -= 3;
+ }
+ sptr -= 3;
+ }
+ }
+ } /* end of pixel_bytes == 3 */
+
+ //--------------------------------------------------------------
+ else if (pixel_bytes == 1)
+ {
+ if (((pass == 0) || (pass == 1)) && width)
+ {
+ int width_mmx = ((width >> 2) << 2);
+ width -= width_mmx; // 0-3 pixels => 0-3 bytes
+ if (width_mmx)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $3, %%esi \n\t"
+ "subl $31, %%edi \n\t"
+
+ ".loop1_pass0: \n\t"
+ "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0
+ "movq %%mm0, %%mm1 \n\t" // x x x x 3 2 1 0
+ "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0
+ "movq %%mm0, %%mm2 \n\t" // 3 3 2 2 1 1 0 0
+ "punpcklwd %%mm0, %%mm0 \n\t" // 1 1 1 1 0 0 0 0
+ "movq %%mm0, %%mm3 \n\t" // 1 1 1 1 0 0 0 0
+ "punpckldq %%mm0, %%mm0 \n\t" // 0 0 0 0 0 0 0 0
+ "punpckhdq %%mm3, %%mm3 \n\t" // 1 1 1 1 1 1 1 1
+ "movq %%mm0, (%%edi) \n\t"
+ "punpckhwd %%mm2, %%mm2 \n\t" // 3 3 3 3 2 2 2 2
+ "movq %%mm3, 8(%%edi) \n\t"
+ "movq %%mm2, %%mm4 \n\t" // 3 3 3 3 2 2 2 2
+ "punpckldq %%mm2, %%mm2 \n\t" // 2 2 2 2 2 2 2 2
+ "punpckhdq %%mm4, %%mm4 \n\t" // 3 3 3 3 3 3 3 3
+ "movq %%mm2, 16(%%edi) \n\t"
+ "subl $4, %%esi \n\t"
+ "movq %%mm4, 24(%%edi) \n\t"
+ "subl $32, %%edi \n\t"
+ "subl $4, %%ecx \n\t"
+ "jnz .loop1_pass0 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width_mmx) // ecx
+
+#if 0 /* %mm0, ..., %mm4 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1", "%mm2" // clobber list
+ , "%mm3", "%mm4"
+#endif
+ );
+ }
+
+ sptr -= width_mmx;
+ dp -= width_mmx*8;
+ for (i = width; i; i--)
+ {
+ int j;
+
+ /* I simplified this part in version 1.0.4e
+ * here and in several other instances where
+ * pixel_bytes == 1 -- GR-P
+ *
+ * Original code:
+ *
+ * png_byte v[8];
+ * png_memcpy(v, sptr, pixel_bytes);
+ * for (j = 0; j < png_pass_inc[pass]; j++)
+ * {
+ * png_memcpy(dp, v, pixel_bytes);
+ * dp -= pixel_bytes;
+ * }
+ * sptr -= pixel_bytes;
+ *
+ * Replacement code is in the next three lines:
+ */
+
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp-- = *sptr;
+ }
+ --sptr;
+ }
+ }
+ else if (((pass == 2) || (pass == 3)) && width)
+ {
+ int width_mmx = ((width >> 2) << 2);
+ width -= width_mmx; // 0-3 pixels => 0-3 bytes
+ if (width_mmx)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $3, %%esi \n\t"
+ "subl $15, %%edi \n\t"
+
+ ".loop1_pass2: \n\t"
+ "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0
+ "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0
+ "movq %%mm0, %%mm1 \n\t" // 3 3 2 2 1 1 0 0
+ "punpcklwd %%mm0, %%mm0 \n\t" // 1 1 1 1 0 0 0 0
+ "punpckhwd %%mm1, %%mm1 \n\t" // 3 3 3 3 2 2 2 2
+ "movq %%mm0, (%%edi) \n\t"
+ "subl $4, %%esi \n\t"
+ "movq %%mm1, 8(%%edi) \n\t"
+ "subl $16, %%edi \n\t"
+ "subl $4, %%ecx \n\t"
+ "jnz .loop1_pass2 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width_mmx) // ecx
+
+#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1" // clobber list
+#endif
+ );
+ }
+
+ sptr -= width_mmx;
+ dp -= width_mmx*4;
+ for (i = width; i; i--)
+ {
+ int j;
+
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp-- = *sptr;
+ }
+ --sptr;
+ }
+ }
+ else if (width) /* && ((pass == 4) || (pass == 5)) */
+ {
+ int width_mmx = ((width >> 3) << 3);
+ width -= width_mmx; // 0-3 pixels => 0-3 bytes
+ if (width_mmx)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $7, %%esi \n\t"
+ "subl $15, %%edi \n\t"
+
+ ".loop1_pass4: \n\t"
+ "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
+ "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0
+ "punpcklbw %%mm0, %%mm0 \n\t" // 3 3 2 2 1 1 0 0
+ "punpckhbw %%mm1, %%mm1 \n\t" // 7 7 6 6 5 5 4 4
+ "movq %%mm1, 8(%%edi) \n\t"
+ "subl $8, %%esi \n\t"
+ "movq %%mm0, (%%edi) \n\t"
+ "subl $16, %%edi \n\t"
+ "subl $8, %%ecx \n\t"
+ "jnz .loop1_pass4 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (none)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width_mmx) // ecx
+
+#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1" // clobber list
+#endif
+ );
+ }
+
+ sptr -= width_mmx;
+ dp -= width_mmx*2;
+ for (i = width; i; i--)
+ {
+ int j;
+
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp-- = *sptr;
+ }
+ --sptr;
+ }
+ }
+ } /* end of pixel_bytes == 1 */
+
+ //--------------------------------------------------------------
+ else if (pixel_bytes == 2)
+ {
+ if (((pass == 0) || (pass == 1)) && width)
+ {
+ int width_mmx = ((width >> 1) << 1);
+ width -= width_mmx; // 0,1 pixels => 0,2 bytes
+ if (width_mmx)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $2, %%esi \n\t"
+ "subl $30, %%edi \n\t"
+
+ ".loop2_pass0: \n\t"
+ "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0
+ "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0
+ "movq %%mm0, %%mm1 \n\t" // 3 2 3 2 1 0 1 0
+ "punpckldq %%mm0, %%mm0 \n\t" // 1 0 1 0 1 0 1 0
+ "punpckhdq %%mm1, %%mm1 \n\t" // 3 2 3 2 3 2 3 2
+ "movq %%mm0, (%%edi) \n\t"
+ "movq %%mm0, 8(%%edi) \n\t"
+ "movq %%mm1, 16(%%edi) \n\t"
+ "subl $4, %%esi \n\t"
+ "movq %%mm1, 24(%%edi) \n\t"
+ "subl $32, %%edi \n\t"
+ "subl $2, %%ecx \n\t"
+ "jnz .loop2_pass0 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width_mmx) // ecx
+
+#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1" // clobber list
+#endif
+ );
+ }
+
+ sptr -= (width_mmx*2 - 2); // sign fixed
+ dp -= (width_mmx*16 - 2); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 2;
+ png_memcpy(v, sptr, 2);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 2;
+ png_memcpy(dp, v, 2);
+ }
+ }
+ }
+ else if (((pass == 2) || (pass == 3)) && width)
+ {
+ int width_mmx = ((width >> 1) << 1) ;
+ width -= width_mmx; // 0,1 pixels => 0,2 bytes
+ if (width_mmx)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $2, %%esi \n\t"
+ "subl $14, %%edi \n\t"
+
+ ".loop2_pass2: \n\t"
+ "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0
+ "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0
+ "movq %%mm0, %%mm1 \n\t" // 3 2 3 2 1 0 1 0
+ "punpckldq %%mm0, %%mm0 \n\t" // 1 0 1 0 1 0 1 0
+ "punpckhdq %%mm1, %%mm1 \n\t" // 3 2 3 2 3 2 3 2
+ "movq %%mm0, (%%edi) \n\t"
+ "subl $4, %%esi \n\t"
+ "movq %%mm1, 8(%%edi) \n\t"
+ "subl $16, %%edi \n\t"
+ "subl $2, %%ecx \n\t"
+ "jnz .loop2_pass2 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width_mmx) // ecx
+
+#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1" // clobber list
+#endif
+ );
+ }
+
+ sptr -= (width_mmx*2 - 2); // sign fixed
+ dp -= (width_mmx*8 - 2); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 2;
+ png_memcpy(v, sptr, 2);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 2;
+ png_memcpy(dp, v, 2);
+ }
+ }
+ }
+ else if (width) // pass == 4 or 5
+ {
+ int width_mmx = ((width >> 1) << 1) ;
+ width -= width_mmx; // 0,1 pixels => 0,2 bytes
+ if (width_mmx)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $2, %%esi \n\t"
+ "subl $6, %%edi \n\t"
+
+ ".loop2_pass4: \n\t"
+ "movd (%%esi), %%mm0 \n\t" // x x x x 3 2 1 0
+ "punpcklwd %%mm0, %%mm0 \n\t" // 3 2 3 2 1 0 1 0
+ "subl $4, %%esi \n\t"
+ "movq %%mm0, (%%edi) \n\t"
+ "subl $8, %%edi \n\t"
+ "subl $2, %%ecx \n\t"
+ "jnz .loop2_pass4 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width_mmx) // ecx
+
+#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0" // clobber list
+#endif
+ );
+ }
+
+ sptr -= (width_mmx*2 - 2); // sign fixed
+ dp -= (width_mmx*4 - 2); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 2;
+ png_memcpy(v, sptr, 2);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 2;
+ png_memcpy(dp, v, 2);
+ }
+ }
+ }
+ } /* end of pixel_bytes == 2 */
+
+ //--------------------------------------------------------------
+ else if (pixel_bytes == 4)
+ {
+ if (((pass == 0) || (pass == 1)) && width)
+ {
+ int width_mmx = ((width >> 1) << 1);
+ width -= width_mmx; // 0,1 pixels => 0,4 bytes
+ if (width_mmx)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $4, %%esi \n\t"
+ "subl $60, %%edi \n\t"
+
+ ".loop4_pass0: \n\t"
+ "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
+ "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0
+ "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0
+ "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4
+ "movq %%mm0, (%%edi) \n\t"
+ "movq %%mm0, 8(%%edi) \n\t"
+ "movq %%mm0, 16(%%edi) \n\t"
+ "movq %%mm0, 24(%%edi) \n\t"
+ "movq %%mm1, 32(%%edi) \n\t"
+ "movq %%mm1, 40(%%edi) \n\t"
+ "movq %%mm1, 48(%%edi) \n\t"
+ "subl $8, %%esi \n\t"
+ "movq %%mm1, 56(%%edi) \n\t"
+ "subl $64, %%edi \n\t"
+ "subl $2, %%ecx \n\t"
+ "jnz .loop4_pass0 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width_mmx) // ecx
+
+#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1" // clobber list
+#endif
+ );
+ }
+
+ sptr -= (width_mmx*4 - 4); // sign fixed
+ dp -= (width_mmx*32 - 4); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 4;
+ png_memcpy(v, sptr, 4);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 4;
+ png_memcpy(dp, v, 4);
+ }
+ }
+ }
+ else if (((pass == 2) || (pass == 3)) && width)
+ {
+ int width_mmx = ((width >> 1) << 1);
+ width -= width_mmx; // 0,1 pixels => 0,4 bytes
+ if (width_mmx)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $4, %%esi \n\t"
+ "subl $28, %%edi \n\t"
+
+ ".loop4_pass2: \n\t"
+ "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
+ "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0
+ "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0
+ "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4
+ "movq %%mm0, (%%edi) \n\t"
+ "movq %%mm0, 8(%%edi) \n\t"
+ "movq %%mm1, 16(%%edi) \n\t"
+ "movq %%mm1, 24(%%edi) \n\t"
+ "subl $8, %%esi \n\t"
+ "subl $32, %%edi \n\t"
+ "subl $2, %%ecx \n\t"
+ "jnz .loop4_pass2 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width_mmx) // ecx
+
+#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1" // clobber list
+#endif
+ );
+ }
+
+ sptr -= (width_mmx*4 - 4); // sign fixed
+ dp -= (width_mmx*16 - 4); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 4;
+ png_memcpy(v, sptr, 4);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 4;
+ png_memcpy(dp, v, 4);
+ }
+ }
+ }
+ else if (width) // pass == 4 or 5
+ {
+ int width_mmx = ((width >> 1) << 1) ;
+ width -= width_mmx; // 0,1 pixels => 0,4 bytes
+ if (width_mmx)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $4, %%esi \n\t"
+ "subl $12, %%edi \n\t"
+
+ ".loop4_pass4: \n\t"
+ "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
+ "movq %%mm0, %%mm1 \n\t" // 7 6 5 4 3 2 1 0
+ "punpckldq %%mm0, %%mm0 \n\t" // 3 2 1 0 3 2 1 0
+ "punpckhdq %%mm1, %%mm1 \n\t" // 7 6 5 4 7 6 5 4
+ "movq %%mm0, (%%edi) \n\t"
+ "subl $8, %%esi \n\t"
+ "movq %%mm1, 8(%%edi) \n\t"
+ "subl $16, %%edi \n\t"
+ "subl $2, %%ecx \n\t"
+ "jnz .loop4_pass4 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width_mmx) // ecx
+
+#if 0 /* %mm0, %mm1 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0", "%mm1" // clobber list
+#endif
+ );
+ }
+
+ sptr -= (width_mmx*4 - 4); // sign fixed
+ dp -= (width_mmx*8 - 4); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 4;
+ png_memcpy(v, sptr, 4);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 4;
+ png_memcpy(dp, v, 4);
+ }
+ }
+ }
+ } /* end of pixel_bytes == 4 */
+
+ //--------------------------------------------------------------
+ else if (pixel_bytes == 8)
+ {
+// GRR TEST: should work, but needs testing (special 64-bit version of rpng2?)
+ // GRR NOTE: no need to combine passes here!
+ if (((pass == 0) || (pass == 1)) && width)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ // source is 8-byte RRGGBBAA
+ // dest is 64-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA ...
+ __asm__ __volatile__ (
+ "subl $56, %%edi \n\t" // start of last block
+
+ ".loop8_pass0: \n\t"
+ "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
+ "movq %%mm0, (%%edi) \n\t"
+ "movq %%mm0, 8(%%edi) \n\t"
+ "movq %%mm0, 16(%%edi) \n\t"
+ "movq %%mm0, 24(%%edi) \n\t"
+ "movq %%mm0, 32(%%edi) \n\t"
+ "movq %%mm0, 40(%%edi) \n\t"
+ "movq %%mm0, 48(%%edi) \n\t"
+ "subl $8, %%esi \n\t"
+ "movq %%mm0, 56(%%edi) \n\t"
+ "subl $64, %%edi \n\t"
+ "decl %%ecx \n\t"
+ "jnz .loop8_pass0 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width) // ecx
+
+#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0" // clobber list
+#endif
+ );
+ }
+ else if (((pass == 2) || (pass == 3)) && width)
+ {
+ // source is 8-byte RRGGBBAA
+ // dest is 32-byte RRGGBBAA RRGGBBAA RRGGBBAA RRGGBBAA
+ // (recall that expansion is _in place_: sptr and dp
+ // both point at locations within same row buffer)
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $24, %%edi \n\t" // start of last block
+
+ ".loop8_pass2: \n\t"
+ "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
+ "movq %%mm0, (%%edi) \n\t"
+ "movq %%mm0, 8(%%edi) \n\t"
+ "movq %%mm0, 16(%%edi) \n\t"
+ "subl $8, %%esi \n\t"
+ "movq %%mm0, 24(%%edi) \n\t"
+ "subl $32, %%edi \n\t"
+ "decl %%ecx \n\t"
+ "jnz .loop8_pass2 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width) // ecx
+
+#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0" // clobber list
+#endif
+ );
+ }
+ }
+ else if (width) // pass == 4 or 5
+ {
+ // source is 8-byte RRGGBBAA
+ // dest is 16-byte RRGGBBAA RRGGBBAA
+ {
+ int dummy_value_c; // fix 'forbidden register spilled'
+ int dummy_value_S;
+ int dummy_value_D;
+
+ __asm__ __volatile__ (
+ "subl $8, %%edi \n\t" // start of last block
+
+ ".loop8_pass4: \n\t"
+ "movq (%%esi), %%mm0 \n\t" // 7 6 5 4 3 2 1 0
+ "movq %%mm0, (%%edi) \n\t"
+ "subl $8, %%esi \n\t"
+ "movq %%mm0, 8(%%edi) \n\t"
+ "subl $16, %%edi \n\t"
+ "decl %%ecx \n\t"
+ "jnz .loop8_pass4 \n\t"
+ "EMMS \n\t" // DONE
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "1" (sptr), // esi // input regs
+ "2" (dp), // edi
+ "0" (width) // ecx
+
+#if 0 /* %mm0 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ : "%mm0" // clobber list
+#endif
+ );
+ }
+ }
+
+ } /* end of pixel_bytes == 8 */
+
+ //--------------------------------------------------------------
+ else if (pixel_bytes == 6)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, 6);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, 6);
+ dp -= 6;
+ }
+ sptr -= 6;
+ }
+ } /* end of pixel_bytes == 6 */
+
+ //--------------------------------------------------------------
+ else
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, pixel_bytes);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sptr-= pixel_bytes;
+ }
+ }
+ } // end of _mmx_supported ========================================
+
+ else /* MMX not supported: use modified C code - takes advantage
+ * of inlining of png_memcpy for a constant */
+ /* GRR 19991007: does it? or should pixel_bytes in each
+ * block be tqreplaced with immediate value (e.g., 1)? */
+ /* GRR 19991017: tqreplaced with constants in each case */
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+ {
+ if (pixel_bytes == 1)
+ {
+ for (i = width; i; i--)
+ {
+ int j;
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp-- = *sptr;
+ }
+ --sptr;
+ }
+ }
+ else if (pixel_bytes == 3)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, 3);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, 3);
+ dp -= 3;
+ }
+ sptr -= 3;
+ }
+ }
+ else if (pixel_bytes == 2)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, 2);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, 2);
+ dp -= 2;
+ }
+ sptr -= 2;
+ }
+ }
+ else if (pixel_bytes == 4)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, 4);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+#ifdef PNG_DEBUG
+ if (dp < row || dp+3 > row+png_ptr->row_buf_size)
+ {
+ printf("dp out of bounds: row=%d, dp=%d, rp=%d\n",
+ row, dp, row+png_ptr->row_buf_size);
+ printf("row_buf=%d\n",png_ptr->row_buf_size);
+ }
+#endif
+ png_memcpy(dp, v, 4);
+ dp -= 4;
+ }
+ sptr -= 4;
+ }
+ }
+ else if (pixel_bytes == 6)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, 6);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, 6);
+ dp -= 6;
+ }
+ sptr -= 6;
+ }
+ }
+ else if (pixel_bytes == 8)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, 8);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, 8);
+ dp -= 8;
+ }
+ sptr -= 8;
+ }
+ }
+ else /* GRR: should never be reached */
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, pixel_bytes);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sptr -= pixel_bytes;
+ }
+ }
+
+ } /* end if (MMX not supported) */
+ break;
+ }
+ } /* end switch (row_info->pixel_depth) */
+
+ row_info->width = final_width;
+ row_info->rowbytes = ((final_width *
+ (png_uint_32)row_info->pixel_depth + 7) >> 3);
+ }
+
+} /* end png_do_read_interlace() */
+
+#endif /* PNG_HAVE_ASSEMBLER_READ_INTERLACE */
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+
+
+#if defined(PNG_HAVE_ASSEMBLER_READ_FILTER_ROW)
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+
+// These variables are utilized in the functions below. They are declared
+// globally here to ensure tqalignment on 8-byte boundaries.
+
+union uAll {
+ long long use;
+ double align;
+} _LBCarryMask = {0x0101010101010101LL},
+ _HBClearMask = {0x7f7f7f7f7f7f7f7fLL},
+ _ActiveMask, _ActiveMask2, _ActiveMaskEnd, _ShiftBpp, _ShiftRem;
+
+#ifdef PNG_THREAD_UNSAFE_OK
+//===========================================================================//
+// //
+// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ A V G //
+// //
+//===========================================================================//
+
+// Optimized code for PNG Average filter decoder
+
+static void /* PRIVATE */
+png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row,
+ png_bytep prev_row)
+{
+ int bpp;
+ int dummy_value_c; // fix 'forbidden register 2 (cx) was spilled' error
+ int dummy_value_S;
+ int dummy_value_D;
+
+ bpp = (row_info->pixel_depth + 7) >> 3; // get # bytes per pixel
+ _FullLength = row_info->rowbytes; // # of bytes to filter
+
+ __asm__ __volatile__ (
+ // initialize address pointers and offset
+#ifdef __PIC__
+ "pushl %%ebx \n\t" // save index to Global Offset Table
+#endif
+//pre "movl row, %%edi \n\t" // edi: Avg(x)
+ "xorl %%ebx, %%ebx \n\t" // ebx: x
+ "movl %%edi, %%edx \n\t"
+//pre "movl prev_row, %%esi \n\t" // esi: Prior(x)
+//pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx)
+ "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp)
+
+ "xorl %%eax,%%eax \n\t"
+
+ // Compute the Raw value for the first bpp bytes
+ // Raw(x) = Avg(x) + (Prior(x)/2)
+ "avg_rlp: \n\t"
+ "movb (%%esi,%%ebx,),%%al \n\t" // load al with Prior(x)
+ "incl %%ebx \n\t"
+ "shrb %%al \n\t" // divide by 2
+ "addb -1(%%edi,%%ebx,),%%al \n\t" // add Avg(x); -1 to offset inc ebx
+//pre "cmpl bpp, %%ebx \n\t" // (bpp is preloaded into ecx)
+ "cmpl %%ecx, %%ebx \n\t"
+ "movb %%al,-1(%%edi,%%ebx,) \n\t" // write Raw(x); -1 to offset inc ebx
+ "jb avg_rlp \n\t" // mov does not affect flags
+
+ // get # of bytes to tqalignment
+ "movl %%edi, _dif \n\t" // take start of row
+ "addl %%ebx, _dif \n\t" // add bpp
+ "addl $0xf, _dif \n\t" // add 7+8 to incr past tqalignment bdry
+ "andl $0xfffffff8, _dif \n\t" // tqmask to tqalignment boundary
+ "subl %%edi, _dif \n\t" // subtract from start => value ebx at
+ "jz avg_go \n\t" // tqalignment
+
+ // fix tqalignment
+ // Compute the Raw value for the bytes up to the tqalignment boundary
+ // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
+ "xorl %%ecx, %%ecx \n\t"
+
+ "avg_lp1: \n\t"
+ "xorl %%eax, %%eax \n\t"
+ "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x)
+ "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp)
+ "addw %%cx, %%ax \n\t"
+ "incl %%ebx \n\t"
+ "shrw %%ax \n\t" // divide by 2
+ "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset inc ebx
+ "cmpl _dif, %%ebx \n\t" // check if at tqalignment boundary
+ "movb %%al, -1(%%edi,%%ebx,) \n\t" // write Raw(x); -1 to offset inc ebx
+ "jb avg_lp1 \n\t" // repeat until at tqalignment boundary
+
+ "avg_go: \n\t"
+ "movl _FullLength, %%eax \n\t"
+ "movl %%eax, %%ecx \n\t"
+ "subl %%ebx, %%eax \n\t" // subtract tqalignment fix
+ "andl $0x00000007, %%eax \n\t" // calc bytes over mult of 8
+ "subl %%eax, %%ecx \n\t" // drop over bytes from original length
+ "movl %%ecx, _MMXLength \n\t"
+#ifdef __PIC__
+ "popl %%ebx \n\t" // restore index to Global Offset Table
+#endif
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "0" (bpp), // ecx // input regs
+ "1" (prev_row), // esi
+ "2" (row) // edi
+
+ : "%eax", "%edx" // clobber list
+#ifndef __PIC__
+ , "%ebx"
+#endif
+ // GRR: INCLUDE "memory" as clobbered? (_dif, _MMXLength)
+ // (seems to work fine without...)
+ );
+
+ // now do the math for the rest of the row
+ switch (bpp)
+ {
+ case 3:
+ {
+ _ActiveMask.use = 0x0000000000ffffffLL;
+ _ShiftBpp.use = 24; // == 3 * 8
+ _ShiftRem.use = 40; // == 64 - 24
+
+ __asm__ __volatile__ (
+ // re-init address pointers and offset
+ "movq _ActiveMask, %%mm7 \n\t"
+ "movl _dif, %%ecx \n\t" // ecx: x = offset to
+ "movq _LBCarryMask, %%mm5 \n\t" // tqalignment boundary
+// preload "movl row, %%edi \n\t" // edi: Avg(x)
+ "movq _HBClearMask, %%mm4 \n\t"
+// preload "movl prev_row, %%esi \n\t" // esi: Prior(x)
+
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes
+ // (correct pos. in loop below)
+ "avg_3lp: \n\t"
+ "movq (%%edi,%%ecx,), %%mm0 \n\t" // load mm0 with Avg(x)
+ "movq %%mm5, %%mm3 \n\t"
+ "psrlq _ShiftRem, %%mm2 \n\t" // correct position Raw(x-bpp)
+ // data
+ "movq (%%esi,%%ecx,), %%mm1 \n\t" // load mm1 with Prior(x)
+ "movq %%mm7, %%mm6 \n\t"
+ "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte
+ "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2
+ "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for
+ // each byte
+ // add 1st active group (Raw(x-bpp)/2) to average with LBCarry
+ "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
+ // LBCarrys
+ "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
+ // where both
+ // lsb's were == 1 (only valid for active group)
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
+ // for each byte
+ "pand %%mm6, %%mm2 \n\t" // leave only Active Group 1
+ // bytes to add to Avg
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
+ // Avg for each Active
+ // byte
+ // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry
+ "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 tqmask to cover
+ // bytes 3-5
+ "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
+ "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly
+ "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
+ // LBCarrys
+ "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
+ // where both
+ // lsb's were == 1 (only valid for active group)
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
+ // for each byte
+ "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
+ // bytes to add to Avg
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
+ // Avg for each Active
+ // byte
+
+ // add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry
+ "psllq _ShiftBpp, %%mm6 \n\t" // shift mm6 tqmask to cover last
+ // two
+ // bytes
+ "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
+ "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly
+ // Data only needs to be shifted once here to
+ // get the correct x-bpp offset.
+ "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
+ // LBCarrys
+ "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
+ // where both
+ // lsb's were == 1 (only valid for active group)
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
+ // for each byte
+ "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
+ // bytes to add to Avg
+ "addl $8, %%ecx \n\t"
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
+ // Avg for each Active
+ // byte
+ // now ready to write back to memory
+ "movq %%mm0, -8(%%edi,%%ecx,) \n\t"
+ // move updated Raw(x) to use as Raw(x-bpp) for next loop
+ "cmpl _MMXLength, %%ecx \n\t"
+ "movq %%mm0, %%mm2 \n\t" // mov updated Raw(x) to mm2
+ "jb avg_3lp \n\t"
+
+ : "=S" (dummy_value_S), // output regs (dummy)
+ "=D" (dummy_value_D)
+
+ : "0" (prev_row), // esi // input regs
+ "1" (row) // edi
+
+ : "%ecx" // clobber list
+#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2", "%mm3"
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ break; // end 3 bpp
+
+ case 6:
+ case 4:
+ //case 7: // who wrote this? PNG doesn't support 5 or 7 bytes/pixel
+ //case 5: // GRR BOGUS
+ {
+ _ActiveMask.use = 0xffffffffffffffffLL; // use shift below to clear
+ // appropriate inactive bytes
+ _ShiftBpp.use = bpp << 3;
+ _ShiftRem.use = 64 - _ShiftBpp.use;
+
+ __asm__ __volatile__ (
+ "movq _HBClearMask, %%mm4 \n\t"
+
+ // re-init address pointers and offset
+ "movl _dif, %%ecx \n\t" // ecx: x = offset to
+ // tqalignment boundary
+
+ // load _ActiveMask and clear all bytes except for 1st active group
+ "movq _ActiveMask, %%mm7 \n\t"
+// preload "movl row, %%edi \n\t" // edi: Avg(x)
+ "psrlq _ShiftRem, %%mm7 \n\t"
+// preload "movl prev_row, %%esi \n\t" // esi: Prior(x)
+ "movq %%mm7, %%mm6 \n\t"
+ "movq _LBCarryMask, %%mm5 \n\t"
+ "psllq _ShiftBpp, %%mm6 \n\t" // create tqmask for 2nd active
+ // group
+
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes
+ // (we correct pos. in loop below)
+ "avg_4lp: \n\t"
+ "movq (%%edi,%%ecx,), %%mm0 \n\t"
+ "psrlq _ShiftRem, %%mm2 \n\t" // shift data to pos. correctly
+ "movq (%%esi,%%ecx,), %%mm1 \n\t"
+ // add (Prev_row/2) to average
+ "movq %%mm5, %%mm3 \n\t"
+ "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte
+ "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2
+ "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for
+ // each byte
+ // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry
+ "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
+ // LBCarrys
+ "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
+ // where both
+ // lsb's were == 1 (only valid for active group)
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
+ // for each byte
+ "pand %%mm7, %%mm2 \n\t" // leave only Active Group 1
+ // bytes to add to Avg
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg
+ // for each Active
+ // byte
+ // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry
+ "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
+ "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly
+ "addl $8, %%ecx \n\t"
+ "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
+ // LBCarrys
+ "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
+ // where both
+ // lsb's were == 1 (only valid for active group)
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
+ // for each byte
+ "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
+ // bytes to add to Avg
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
+ // Avg for each Active
+ // byte
+ "cmpl _MMXLength, %%ecx \n\t"
+ // now ready to write back to memory
+ "movq %%mm0, -8(%%edi,%%ecx,) \n\t"
+ // prep Raw(x-bpp) for next loop
+ "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
+ "jb avg_4lp \n\t"
+
+ : "=S" (dummy_value_S), // output regs (dummy)
+ "=D" (dummy_value_D)
+
+ : "0" (prev_row), // esi // input regs
+ "1" (row) // edi
+
+ : "%ecx" // clobber list
+#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2", "%mm3"
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ break; // end 4,6 bpp
+
+ case 2:
+ {
+ _ActiveMask.use = 0x000000000000ffffLL;
+ _ShiftBpp.use = 16; // == 2 * 8
+ _ShiftRem.use = 48; // == 64 - 16
+
+ __asm__ __volatile__ (
+ // load _ActiveMask
+ "movq _ActiveMask, %%mm7 \n\t"
+ // re-init address pointers and offset
+ "movl _dif, %%ecx \n\t" // ecx: x = offset to tqalignment
+ // boundary
+ "movq _LBCarryMask, %%mm5 \n\t"
+// preload "movl row, %%edi \n\t" // edi: Avg(x)
+ "movq _HBClearMask, %%mm4 \n\t"
+// preload "movl prev_row, %%esi \n\t" // esi: Prior(x)
+
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes
+ // (we correct pos. in loop below)
+ "avg_2lp: \n\t"
+ "movq (%%edi,%%ecx,), %%mm0 \n\t"
+ "psrlq _ShiftRem, %%mm2 \n\t" // shift data to pos. correctly
+ "movq (%%esi,%%ecx,), %%mm1 \n\t" // (GRR BUGFIX: was psllq)
+ // add (Prev_row/2) to average
+ "movq %%mm5, %%mm3 \n\t"
+ "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte
+ "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2
+ "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each
+ // byte
+ "movq %%mm7, %%mm6 \n\t"
+ "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for
+ // each byte
+
+ // add 1st active group (Raw(x-bpp)/2) to average with _LBCarry
+ "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
+ // LBCarrys
+ "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
+ // where both
+ // lsb's were == 1 (only valid
+ // for active group)
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
+ // for each byte
+ "pand %%mm6, %%mm2 \n\t" // leave only Active Group 1
+ // bytes to add to Avg
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to Avg
+ // for each Active byte
+
+ // add 2nd active group (Raw(x-bpp)/2) to average with _LBCarry
+ "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 tqmask to cover
+ // bytes 2 & 3
+ "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
+ "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly
+ "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
+ // LBCarrys
+ "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
+ // where both
+ // lsb's were == 1 (only valid
+ // for active group)
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
+ // for each byte
+ "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
+ // bytes to add to Avg
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
+ // Avg for each Active byte
+
+ // add 3rd active group (Raw(x-bpp)/2) to average with _LBCarry
+ "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 tqmask to cover
+ // bytes 4 & 5
+ "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
+ "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly
+ "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
+ // LBCarrys
+ "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
+ // where both lsb's were == 1
+ // (only valid for active group)
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
+ // for each byte
+ "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
+ // bytes to add to Avg
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
+ // Avg for each Active byte
+
+ // add 4th active group (Raw(x-bpp)/2) to average with _LBCarry
+ "psllq _ShiftBpp, %%mm6 \n\t" // shift the mm6 tqmask to cover
+ // bytes 6 & 7
+ "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
+ "psllq _ShiftBpp, %%mm2 \n\t" // shift data to pos. correctly
+ "addl $8, %%ecx \n\t"
+ "movq %%mm3, %%mm1 \n\t" // now use mm1 for getting
+ // LBCarrys
+ "pand %%mm2, %%mm1 \n\t" // get LBCarrys for each byte
+ // where both
+ // lsb's were == 1 (only valid
+ // for active group)
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm2 \n\t" // add LBCarrys to (Raw(x-bpp)/2)
+ // for each byte
+ "pand %%mm6, %%mm2 \n\t" // leave only Active Group 2
+ // bytes to add to Avg
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) + LBCarrys to
+ // Avg for each Active byte
+
+ "cmpl _MMXLength, %%ecx \n\t"
+ // now ready to write back to memory
+ "movq %%mm0, -8(%%edi,%%ecx,) \n\t"
+ // prep Raw(x-bpp) for next loop
+ "movq %%mm0, %%mm2 \n\t" // mov updated Raws to mm2
+ "jb avg_2lp \n\t"
+
+ : "=S" (dummy_value_S), // output regs (dummy)
+ "=D" (dummy_value_D)
+
+ : "0" (prev_row), // esi // input regs
+ "1" (row) // edi
+
+ : "%ecx" // clobber list
+#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2", "%mm3"
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ break; // end 2 bpp
+
+ case 1:
+ {
+ __asm__ __volatile__ (
+ // re-init address pointers and offset
+#ifdef __PIC__
+ "pushl %%ebx \n\t" // save Global Offset Table index
+#endif
+ "movl _dif, %%ebx \n\t" // ebx: x = offset to tqalignment
+ // boundary
+// preload "movl row, %%edi \n\t" // edi: Avg(x)
+ "cmpl _FullLength, %%ebx \n\t" // test if offset at end of array
+ "jnb avg_1end \n\t"
+ // do Paeth decode for remaining bytes
+// preload "movl prev_row, %%esi \n\t" // esi: Prior(x)
+ "movl %%edi, %%edx \n\t"
+// preload "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx)
+ "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp)
+ "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx
+ // in loop below
+ "avg_1lp: \n\t"
+ // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
+ "xorl %%eax, %%eax \n\t"
+ "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x)
+ "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp)
+ "addw %%cx, %%ax \n\t"
+ "incl %%ebx \n\t"
+ "shrw %%ax \n\t" // divide by 2
+ "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset
+ // inc ebx
+ "cmpl _FullLength, %%ebx \n\t" // check if at end of array
+ "movb %%al, -1(%%edi,%%ebx,) \n\t" // write back Raw(x);
+ // mov does not affect flags; -1 to offset inc ebx
+ "jb avg_1lp \n\t"
+
+ "avg_1end: \n\t"
+#ifdef __PIC__
+ "popl %%ebx \n\t" // Global Offset Table index
+#endif
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "0" (bpp), // ecx // input regs
+ "1" (prev_row), // esi
+ "2" (row) // edi
+
+ : "%eax", "%edx" // clobber list
+#ifndef __PIC__
+ , "%ebx"
+#endif
+ );
+ }
+ return; // end 1 bpp
+
+ case 8:
+ {
+ __asm__ __volatile__ (
+ // re-init address pointers and offset
+ "movl _dif, %%ecx \n\t" // ecx: x == offset to tqalignment
+ "movq _LBCarryMask, %%mm5 \n\t" // boundary
+// preload "movl row, %%edi \n\t" // edi: Avg(x)
+ "movq _HBClearMask, %%mm4 \n\t"
+// preload "movl prev_row, %%esi \n\t" // esi: Prior(x)
+
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%ecx,), %%mm2 \n\t" // load previous aligned 8 bytes
+ // (NO NEED to correct pos. in loop below)
+
+ "avg_8lp: \n\t"
+ "movq (%%edi,%%ecx,), %%mm0 \n\t"
+ "movq %%mm5, %%mm3 \n\t"
+ "movq (%%esi,%%ecx,), %%mm1 \n\t"
+ "addl $8, %%ecx \n\t"
+ "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte
+ "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2
+ "pand %%mm2, %%mm3 \n\t" // get LBCarrys for each byte
+ // where both lsb's were == 1
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7, each byte
+ "paddb %%mm3, %%mm0 \n\t" // add LBCarrys to Avg, each byte
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7, each byte
+ "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg, each
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) to Avg for each
+ "cmpl _MMXLength, %%ecx \n\t"
+ "movq %%mm0, -8(%%edi,%%ecx,) \n\t"
+ "movq %%mm0, %%mm2 \n\t" // reuse as Raw(x-bpp)
+ "jb avg_8lp \n\t"
+
+ : "=S" (dummy_value_S), // output regs (dummy)
+ "=D" (dummy_value_D)
+
+ : "0" (prev_row), // esi // input regs
+ "1" (row) // edi
+
+ : "%ecx" // clobber list
+#if 0 /* %mm0, ..., %mm5 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2"
+ , "%mm3", "%mm4", "%mm5"
+#endif
+ );
+ }
+ break; // end 8 bpp
+
+ default: // bpp greater than 8 (!= 1,2,3,4,[5],6,[7],8)
+ {
+
+#ifdef PNG_DEBUG
+ // GRR: PRINT ERROR HERE: SHOULD NEVER BE REACHED
+ png_debug(1,
+ "Internal logic error in pnggccrd (png_read_filter_row_mmx_avg())\n");
+#endif
+
+#if 0
+ __asm__ __volatile__ (
+ "movq _LBCarryMask, %%mm5 \n\t"
+ // re-init address pointers and offset
+ "movl _dif, %%ebx \n\t" // ebx: x = offset to
+ // tqalignment boundary
+ "movl row, %%edi \n\t" // edi: Avg(x)
+ "movq _HBClearMask, %%mm4 \n\t"
+ "movl %%edi, %%edx \n\t"
+ "movl prev_row, %%esi \n\t" // esi: Prior(x)
+ "subl bpp, %%edx \n\t" // edx: Raw(x-bpp)
+ "avg_Alp: \n\t"
+ "movq (%%edi,%%ebx,), %%mm0 \n\t"
+ "movq %%mm5, %%mm3 \n\t"
+ "movq (%%esi,%%ebx,), %%mm1 \n\t"
+ "pand %%mm1, %%mm3 \n\t" // get lsb for each prev_row byte
+ "movq (%%edx,%%ebx,), %%mm2 \n\t"
+ "psrlq $1, %%mm1 \n\t" // divide prev_row bytes by 2
+ "pand %%mm2, %%mm3 \n\t" // get LBCarrys for each byte
+ // where both lsb's were == 1
+ "psrlq $1, %%mm2 \n\t" // divide raw bytes by 2
+ "pand %%mm4, %%mm1 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm3, %%mm0 \n\t" // add LBCarrys to Avg for each
+ // byte
+ "pand %%mm4, %%mm2 \n\t" // clear invalid bit 7 of each
+ // byte
+ "paddb %%mm1, %%mm0 \n\t" // add (Prev_row/2) to Avg for
+ // each byte
+ "addl $8, %%ebx \n\t"
+ "paddb %%mm2, %%mm0 \n\t" // add (Raw/2) to Avg for each
+ // byte
+ "cmpl _MMXLength, %%ebx \n\t"
+ "movq %%mm0, -8(%%edi,%%ebx,) \n\t"
+ "jb avg_Alp \n\t"
+
+ : // FIXASM: output regs/vars go here, e.g.: "=m" (memory_var)
+
+ : // FIXASM: input regs, e.g.: "c" (count), "S" (src), "D" (dest)
+
+ : "%ebx", "%edx", "%edi", "%esi" // CHECKASM: clobber list
+ );
+#endif /* 0 - NEVER REACHED */
+ }
+ break;
+
+ } // end switch (bpp)
+
+ __asm__ __volatile__ (
+ // MMX acceleration complete; now do clean-up
+ // check if any remaining bytes left to decode
+#ifdef __PIC__
+ "pushl %%ebx \n\t" // save index to Global Offset Table
+#endif
+ "movl _MMXLength, %%ebx \n\t" // ebx: x == offset bytes after MMX
+//pre "movl row, %%edi \n\t" // edi: Avg(x)
+ "cmpl _FullLength, %%ebx \n\t" // test if offset at end of array
+ "jnb avg_end \n\t"
+
+ // do Avg decode for remaining bytes
+//pre "movl prev_row, %%esi \n\t" // esi: Prior(x)
+ "movl %%edi, %%edx \n\t"
+//pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx)
+ "subl %%ecx, %%edx \n\t" // edx: Raw(x-bpp)
+ "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx below
+
+ "avg_lp2: \n\t"
+ // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
+ "xorl %%eax, %%eax \n\t"
+ "movb (%%esi,%%ebx,), %%cl \n\t" // load cl with Prior(x)
+ "movb (%%edx,%%ebx,), %%al \n\t" // load al with Raw(x-bpp)
+ "addw %%cx, %%ax \n\t"
+ "incl %%ebx \n\t"
+ "shrw %%ax \n\t" // divide by 2
+ "addb -1(%%edi,%%ebx,), %%al \n\t" // add Avg(x); -1 to offset inc ebx
+ "cmpl _FullLength, %%ebx \n\t" // check if at end of array
+ "movb %%al, -1(%%edi,%%ebx,) \n\t" // write back Raw(x) [mov does not
+ "jb avg_lp2 \n\t" // affect flags; -1 to offset inc ebx]
+
+ "avg_end: \n\t"
+ "EMMS \n\t" // end MMX; prep for poss. FP instrs.
+#ifdef __PIC__
+ "popl %%ebx \n\t" // restore index to Global Offset Table
+#endif
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "0" (bpp), // ecx // input regs
+ "1" (prev_row), // esi
+ "2" (row) // edi
+
+ : "%eax", "%edx" // clobber list
+#ifndef __PIC__
+ , "%ebx"
+#endif
+ );
+
+} /* end png_read_filter_row_mmx_avg() */
+#endif
+
+
+
+#ifdef PNG_THREAD_UNSAFE_OK
+//===========================================================================//
+// //
+// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ P A E T H //
+// //
+//===========================================================================//
+
+// Optimized code for PNG Paeth filter decoder
+
+static void /* PRIVATE */
+png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row,
+ png_bytep prev_row)
+{
+ int bpp;
+ int dummy_value_c; // fix 'forbidden register 2 (cx) was spilled' error
+ int dummy_value_S;
+ int dummy_value_D;
+
+ bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel
+ _FullLength = row_info->rowbytes; // # of bytes to filter
+
+ __asm__ __volatile__ (
+#ifdef __PIC__
+ "pushl %%ebx \n\t" // save index to Global Offset Table
+#endif
+ "xorl %%ebx, %%ebx \n\t" // ebx: x offset
+//pre "movl row, %%edi \n\t"
+ "xorl %%edx, %%edx \n\t" // edx: x-bpp offset
+//pre "movl prev_row, %%esi \n\t"
+ "xorl %%eax, %%eax \n\t"
+
+ // Compute the Raw value for the first bpp bytes
+ // Note: the formula works out to be always
+ // Paeth(x) = Raw(x) + Prior(x) where x < bpp
+ "paeth_rlp: \n\t"
+ "movb (%%edi,%%ebx,), %%al \n\t"
+ "addb (%%esi,%%ebx,), %%al \n\t"
+ "incl %%ebx \n\t"
+//pre "cmpl bpp, %%ebx \n\t" (bpp is preloaded into ecx)
+ "cmpl %%ecx, %%ebx \n\t"
+ "movb %%al, -1(%%edi,%%ebx,) \n\t"
+ "jb paeth_rlp \n\t"
+ // get # of bytes to tqalignment
+ "movl %%edi, _dif \n\t" // take start of row
+ "addl %%ebx, _dif \n\t" // add bpp
+ "xorl %%ecx, %%ecx \n\t"
+ "addl $0xf, _dif \n\t" // add 7 + 8 to incr past tqalignment
+ // boundary
+ "andl $0xfffffff8, _dif \n\t" // tqmask to tqalignment boundary
+ "subl %%edi, _dif \n\t" // subtract from start ==> value ebx
+ // at tqalignment
+ "jz paeth_go \n\t"
+ // fix tqalignment
+
+ "paeth_lp1: \n\t"
+ "xorl %%eax, %%eax \n\t"
+ // pav = p - a = (a + b - c) - a = b - c
+ "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al
+ "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl
+ "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp)
+ "movl %%eax, _patemp \n\t" // Save pav for later use
+ "xorl %%eax, %%eax \n\t"
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al
+ "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp)
+ "movl %%eax, %%ecx \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "addl _patemp, %%eax \n\t" // pcv = pav + pbv
+ // pc = abs(pcv)
+ "testl $0x80000000, %%eax \n\t"
+ "jz paeth_pca \n\t"
+ "negl %%eax \n\t" // reverse sign of neg values
+
+ "paeth_pca: \n\t"
+ "movl %%eax, _pctemp \n\t" // save pc for later use
+ // pb = abs(pbv)
+ "testl $0x80000000, %%ecx \n\t"
+ "jz paeth_pba \n\t"
+ "negl %%ecx \n\t" // reverse sign of neg values
+
+ "paeth_pba: \n\t"
+ "movl %%ecx, _pbtemp \n\t" // save pb for later use
+ // pa = abs(pav)
+ "movl _patemp, %%eax \n\t"
+ "testl $0x80000000, %%eax \n\t"
+ "jz paeth_paa \n\t"
+ "negl %%eax \n\t" // reverse sign of neg values
+
+ "paeth_paa: \n\t"
+ "movl %%eax, _patemp \n\t" // save pa for later use
+ // test if pa <= pb
+ "cmpl %%ecx, %%eax \n\t"
+ "jna paeth_abb \n\t"
+ // pa > pb; now test if pb <= pc
+ "cmpl _pctemp, %%ecx \n\t"
+ "jna paeth_bbc \n\t"
+ // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl
+ "jmp paeth_paeth \n\t"
+
+ "paeth_bbc: \n\t"
+ // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
+ "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl
+ "jmp paeth_paeth \n\t"
+
+ "paeth_abb: \n\t"
+ // pa <= pb; now test if pa <= pc
+ "cmpl _pctemp, %%eax \n\t"
+ "jna paeth_abc \n\t"
+ // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl
+ "jmp paeth_paeth \n\t"
+
+ "paeth_abc: \n\t"
+ // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
+ "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl
+
+ "paeth_paeth: \n\t"
+ "incl %%ebx \n\t"
+ "incl %%edx \n\t"
+ // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
+ "addb %%cl, -1(%%edi,%%ebx,) \n\t"
+ "cmpl _dif, %%ebx \n\t"
+ "jb paeth_lp1 \n\t"
+
+ "paeth_go: \n\t"
+ "movl _FullLength, %%ecx \n\t"
+ "movl %%ecx, %%eax \n\t"
+ "subl %%ebx, %%eax \n\t" // subtract tqalignment fix
+ "andl $0x00000007, %%eax \n\t" // calc bytes over mult of 8
+ "subl %%eax, %%ecx \n\t" // drop over bytes from original length
+ "movl %%ecx, _MMXLength \n\t"
+#ifdef __PIC__
+ "popl %%ebx \n\t" // restore index to Global Offset Table
+#endif
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "0" (bpp), // ecx // input regs
+ "1" (prev_row), // esi
+ "2" (row) // edi
+
+ : "%eax", "%edx" // clobber list
+#ifndef __PIC__
+ , "%ebx"
+#endif
+ );
+
+ // now do the math for the rest of the row
+ switch (bpp)
+ {
+ case 3:
+ {
+ _ActiveMask.use = 0x0000000000ffffffLL;
+ _ActiveMaskEnd.use = 0xffff000000000000LL;
+ _ShiftBpp.use = 24; // == bpp(3) * 8
+ _ShiftRem.use = 40; // == 64 - 24
+
+ __asm__ __volatile__ (
+ "movl _dif, %%ecx \n\t"
+// preload "movl row, %%edi \n\t"
+// preload "movl prev_row, %%esi \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%ecx,), %%mm1 \n\t"
+ "paeth_3lp: \n\t"
+ "psrlq _ShiftRem, %%mm1 \n\t" // shift last 3 bytes to 1st
+ // 3 bytes
+ "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x)
+ "punpcklbw %%mm0, %%mm1 \n\t" // unpack High bytes of a
+ "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // prep c=Prior(x-bpp) bytes
+ "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
+ "psrlq _ShiftRem, %%mm3 \n\t" // shift last 3 bytes to 1st
+ // 3 bytes
+ // pav = p - a = (a + b - c) - a = b - c
+ "movq %%mm2, %%mm4 \n\t"
+ "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movq %%mm1, %%mm5 \n\t"
+ "psubw %%mm3, %%mm4 \n\t"
+ "pxor %%mm7, %%mm7 \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "movq %%mm4, %%mm6 \n\t"
+ "psubw %%mm3, %%mm5 \n\t"
+
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ "pcmpgtw %%mm4, %%mm0 \n\t" // create tqmask pav bytes < 0
+ "paddw %%mm5, %%mm6 \n\t"
+ "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "pcmpgtw %%mm5, %%mm7 \n\t" // create tqmask pbv bytes < 0
+ "psubw %%mm0, %%mm4 \n\t"
+ "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
+ "psubw %%mm0, %%mm4 \n\t"
+ "psubw %%mm7, %%mm5 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "pcmpgtw %%mm6, %%mm0 \n\t" // create tqmask pcv bytes < 0
+ "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "psubw %%mm7, %%mm5 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ // test pa <= pb
+ "movq %%mm4, %%mm7 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
+ "movq %%mm7, %%mm0 \n\t"
+ // use mm7 tqmask to merge pa & pb
+ "pand %%mm7, %%mm5 \n\t"
+ // use mm0 tqmask copy to merge a & b
+ "pand %%mm0, %%mm2 \n\t"
+ "pandn %%mm4, %%mm7 \n\t"
+ "pandn %%mm1, %%mm0 \n\t"
+ "paddw %%mm5, %%mm7 \n\t"
+ "paddw %%mm2, %%mm0 \n\t"
+ // test ((pa <= pb)? pa:pb) <= pc
+ "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
+ "pxor %%mm1, %%mm1 \n\t"
+ "pand %%mm7, %%mm3 \n\t"
+ "pandn %%mm0, %%mm7 \n\t"
+ "paddw %%mm3, %%mm7 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "packuswb %%mm1, %%mm7 \n\t"
+ "movq (%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp)
+ "pand _ActiveMask, %%mm7 \n\t"
+ "movq %%mm3, %%mm2 \n\t" // load b=Prior(x) step 1
+ "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x)
+ "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
+ "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value
+ "movq %%mm7, %%mm1 \n\t" // now mm1 will be used as
+ // Raw(x-bpp)
+ // now do Paeth for 2nd set of bytes (3-5)
+ "psrlq _ShiftBpp, %%mm2 \n\t" // load b=Prior(x) step 2
+ "punpcklbw %%mm0, %%mm1 \n\t" // unpack High bytes of a
+ "pxor %%mm7, %%mm7 \n\t"
+ "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movq %%mm1, %%mm5 \n\t"
+ // pav = p - a = (a + b - c) - a = b - c
+ "movq %%mm2, %%mm4 \n\t"
+ "psubw %%mm3, %%mm5 \n\t"
+ "psubw %%mm3, %%mm4 \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) =
+ // pav + pbv = pbv + pav
+ "movq %%mm5, %%mm6 \n\t"
+ "paddw %%mm4, %%mm6 \n\t"
+
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ "pcmpgtw %%mm5, %%mm0 \n\t" // create tqmask pbv bytes < 0
+ "pcmpgtw %%mm4, %%mm7 \n\t" // create tqmask pav bytes < 0
+ "pand %%mm5, %%mm0 \n\t" // only pbv bytes < 0 in mm0
+ "pand %%mm4, %%mm7 \n\t" // only pav bytes < 0 in mm7
+ "psubw %%mm0, %%mm5 \n\t"
+ "psubw %%mm7, %%mm4 \n\t"
+ "psubw %%mm0, %%mm5 \n\t"
+ "psubw %%mm7, %%mm4 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "pcmpgtw %%mm6, %%mm0 \n\t" // create tqmask pcv bytes < 0
+ "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "psubw %%mm0, %%mm6 \n\t"
+ // test pa <= pb
+ "movq %%mm4, %%mm7 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
+ "movq %%mm7, %%mm0 \n\t"
+ // use mm7 tqmask to merge pa & pb
+ "pand %%mm7, %%mm5 \n\t"
+ // use mm0 tqmask copy to merge a & b
+ "pand %%mm0, %%mm2 \n\t"
+ "pandn %%mm4, %%mm7 \n\t"
+ "pandn %%mm1, %%mm0 \n\t"
+ "paddw %%mm5, %%mm7 \n\t"
+ "paddw %%mm2, %%mm0 \n\t"
+ // test ((pa <= pb)? pa:pb) <= pc
+ "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
+ "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x)
+ "pand %%mm7, %%mm3 \n\t"
+ "pandn %%mm0, %%mm7 \n\t"
+ "pxor %%mm1, %%mm1 \n\t"
+ "paddw %%mm3, %%mm7 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "packuswb %%mm1, %%mm7 \n\t"
+ "movq %%mm2, %%mm3 \n\t" // load c=Prior(x-bpp) step 1
+ "pand _ActiveMask, %%mm7 \n\t"
+ "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
+ "psllq _ShiftBpp, %%mm7 \n\t" // shift bytes to 2nd group of
+ // 3 bytes
+ // pav = p - a = (a + b - c) - a = b - c
+ "movq %%mm2, %%mm4 \n\t"
+ "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x)
+ "psllq _ShiftBpp, %%mm3 \n\t" // load c=Prior(x-bpp) step 2
+ "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value
+ "movq %%mm7, %%mm1 \n\t"
+ "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
+ "psllq _ShiftBpp, %%mm1 \n\t" // shift bytes
+ // now mm1 will be used as Raw(x-bpp)
+ // now do Paeth for 3rd, and final, set of bytes (6-7)
+ "pxor %%mm7, %%mm7 \n\t"
+ "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a
+ "psubw %%mm3, %%mm4 \n\t"
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movq %%mm1, %%mm5 \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "movq %%mm4, %%mm6 \n\t"
+ "psubw %%mm3, %%mm5 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "paddw %%mm5, %%mm6 \n\t"
+
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ "pcmpgtw %%mm4, %%mm0 \n\t" // create tqmask pav bytes < 0
+ "pcmpgtw %%mm5, %%mm7 \n\t" // create tqmask pbv bytes < 0
+ "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
+ "psubw %%mm0, %%mm4 \n\t"
+ "psubw %%mm7, %%mm5 \n\t"
+ "psubw %%mm0, %%mm4 \n\t"
+ "psubw %%mm7, %%mm5 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "pcmpgtw %%mm6, %%mm0 \n\t" // create tqmask pcv bytes < 0
+ "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "psubw %%mm0, %%mm6 \n\t"
+ // test pa <= pb
+ "movq %%mm4, %%mm7 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
+ "movq %%mm7, %%mm0 \n\t"
+ // use mm0 tqmask copy to merge a & b
+ "pand %%mm0, %%mm2 \n\t"
+ // use mm7 tqmask to merge pa & pb
+ "pand %%mm7, %%mm5 \n\t"
+ "pandn %%mm1, %%mm0 \n\t"
+ "pandn %%mm4, %%mm7 \n\t"
+ "paddw %%mm2, %%mm0 \n\t"
+ "paddw %%mm5, %%mm7 \n\t"
+ // test ((pa <= pb)? pa:pb) <= pc
+ "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
+ "pand %%mm7, %%mm3 \n\t"
+ "pandn %%mm0, %%mm7 \n\t"
+ "paddw %%mm3, %%mm7 \n\t"
+ "pxor %%mm1, %%mm1 \n\t"
+ "packuswb %%mm7, %%mm1 \n\t"
+ // step ecx to next set of 8 bytes and repeat loop til done
+ "addl $8, %%ecx \n\t"
+ "pand _ActiveMaskEnd, %%mm1 \n\t"
+ "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with
+ // Raw(x)
+
+ "cmpl _MMXLength, %%ecx \n\t"
+ "pxor %%mm0, %%mm0 \n\t" // pxor does not affect flags
+ "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value
+ // mm1 will be used as Raw(x-bpp) next loop
+ // mm3 ready to be used as Prior(x-bpp) next loop
+ "jb paeth_3lp \n\t"
+
+ : "=S" (dummy_value_S), // output regs (dummy)
+ "=D" (dummy_value_D)
+
+ : "0" (prev_row), // esi // input regs
+ "1" (row) // edi
+
+ : "%ecx" // clobber list
+#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2", "%mm3"
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ break; // end 3 bpp
+
+ case 6:
+ //case 7: // GRR BOGUS
+ //case 5: // GRR BOGUS
+ {
+ _ActiveMask.use = 0x00000000ffffffffLL;
+ _ActiveMask2.use = 0xffffffff00000000LL;
+ _ShiftBpp.use = bpp << 3; // == bpp * 8
+ _ShiftRem.use = 64 - _ShiftBpp.use;
+
+ __asm__ __volatile__ (
+ "movl _dif, %%ecx \n\t"
+// preload "movl row, %%edi \n\t"
+// preload "movl prev_row, %%esi \n\t"
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%ecx,), %%mm1 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+
+ "paeth_6lp: \n\t"
+ // must shift to position Raw(x-bpp) data
+ "psrlq _ShiftRem, %%mm1 \n\t"
+ // do first set of 4 bytes
+ "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes
+ "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a
+ "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x)
+ "punpcklbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b
+ // must shift to position Prior(x-bpp) data
+ "psrlq _ShiftRem, %%mm3 \n\t"
+ // pav = p - a = (a + b - c) - a = b - c
+ "movq %%mm2, %%mm4 \n\t"
+ "punpcklbw %%mm0, %%mm3 \n\t" // unpack Low bytes of c
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movq %%mm1, %%mm5 \n\t"
+ "psubw %%mm3, %%mm4 \n\t"
+ "pxor %%mm7, %%mm7 \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "movq %%mm4, %%mm6 \n\t"
+ "psubw %%mm3, %%mm5 \n\t"
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ "pcmpgtw %%mm4, %%mm0 \n\t" // create tqmask pav bytes < 0
+ "paddw %%mm5, %%mm6 \n\t"
+ "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "pcmpgtw %%mm5, %%mm7 \n\t" // create tqmask pbv bytes < 0
+ "psubw %%mm0, %%mm4 \n\t"
+ "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
+ "psubw %%mm0, %%mm4 \n\t"
+ "psubw %%mm7, %%mm5 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "pcmpgtw %%mm6, %%mm0 \n\t" // create tqmask pcv bytes < 0
+ "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "psubw %%mm7, %%mm5 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ // test pa <= pb
+ "movq %%mm4, %%mm7 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
+ "movq %%mm7, %%mm0 \n\t"
+ // use mm7 tqmask to merge pa & pb
+ "pand %%mm7, %%mm5 \n\t"
+ // use mm0 tqmask copy to merge a & b
+ "pand %%mm0, %%mm2 \n\t"
+ "pandn %%mm4, %%mm7 \n\t"
+ "pandn %%mm1, %%mm0 \n\t"
+ "paddw %%mm5, %%mm7 \n\t"
+ "paddw %%mm2, %%mm0 \n\t"
+ // test ((pa <= pb)? pa:pb) <= pc
+ "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
+ "pxor %%mm1, %%mm1 \n\t"
+ "pand %%mm7, %%mm3 \n\t"
+ "pandn %%mm0, %%mm7 \n\t"
+ "paddw %%mm3, %%mm7 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "packuswb %%mm1, %%mm7 \n\t"
+ "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp)
+ "pand _ActiveMask, %%mm7 \n\t"
+ "psrlq _ShiftRem, %%mm3 \n\t"
+ "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x) step 1
+ "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor and Raw(x)
+ "movq %%mm2, %%mm6 \n\t"
+ "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value
+ "movq -8(%%edi,%%ecx,), %%mm1 \n\t"
+ "psllq _ShiftBpp, %%mm6 \n\t"
+ "movq %%mm7, %%mm5 \n\t"
+ "psrlq _ShiftRem, %%mm1 \n\t"
+ "por %%mm6, %%mm3 \n\t"
+ "psllq _ShiftBpp, %%mm5 \n\t"
+ "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
+ "por %%mm5, %%mm1 \n\t"
+ // do second set of 4 bytes
+ "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
+ "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a
+ // pav = p - a = (a + b - c) - a = b - c
+ "movq %%mm2, %%mm4 \n\t"
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movq %%mm1, %%mm5 \n\t"
+ "psubw %%mm3, %%mm4 \n\t"
+ "pxor %%mm7, %%mm7 \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "movq %%mm4, %%mm6 \n\t"
+ "psubw %%mm3, %%mm5 \n\t"
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ "pcmpgtw %%mm4, %%mm0 \n\t" // create tqmask pav bytes < 0
+ "paddw %%mm5, %%mm6 \n\t"
+ "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "pcmpgtw %%mm5, %%mm7 \n\t" // create tqmask pbv bytes < 0
+ "psubw %%mm0, %%mm4 \n\t"
+ "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
+ "psubw %%mm0, %%mm4 \n\t"
+ "psubw %%mm7, %%mm5 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "pcmpgtw %%mm6, %%mm0 \n\t" // create tqmask pcv bytes < 0
+ "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "psubw %%mm7, %%mm5 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ // test pa <= pb
+ "movq %%mm4, %%mm7 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
+ "movq %%mm7, %%mm0 \n\t"
+ // use mm7 tqmask to merge pa & pb
+ "pand %%mm7, %%mm5 \n\t"
+ // use mm0 tqmask copy to merge a & b
+ "pand %%mm0, %%mm2 \n\t"
+ "pandn %%mm4, %%mm7 \n\t"
+ "pandn %%mm1, %%mm0 \n\t"
+ "paddw %%mm5, %%mm7 \n\t"
+ "paddw %%mm2, %%mm0 \n\t"
+ // test ((pa <= pb)? pa:pb) <= pc
+ "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
+ "pxor %%mm1, %%mm1 \n\t"
+ "pand %%mm7, %%mm3 \n\t"
+ "pandn %%mm0, %%mm7 \n\t"
+ "pxor %%mm1, %%mm1 \n\t"
+ "paddw %%mm3, %%mm7 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ // step ecx to next set of 8 bytes and repeat loop til done
+ "addl $8, %%ecx \n\t"
+ "packuswb %%mm7, %%mm1 \n\t"
+ "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with Raw(x)
+ "cmpl _MMXLength, %%ecx \n\t"
+ "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value
+ // mm1 will be used as Raw(x-bpp) next loop
+ "jb paeth_6lp \n\t"
+
+ : "=S" (dummy_value_S), // output regs (dummy)
+ "=D" (dummy_value_D)
+
+ : "0" (prev_row), // esi // input regs
+ "1" (row) // edi
+
+ : "%ecx" // clobber list
+#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2", "%mm3"
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ break; // end 6 bpp
+
+ case 4:
+ {
+ _ActiveMask.use = 0x00000000ffffffffLL;
+
+ __asm__ __volatile__ (
+ "movl _dif, %%ecx \n\t"
+// preload "movl row, %%edi \n\t"
+// preload "movl prev_row, %%esi \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // only time should need to read
+ // a=Raw(x-bpp) bytes
+ "paeth_4lp: \n\t"
+ // do first set of 4 bytes
+ "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes
+ "punpckhbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a
+ "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x)
+ "punpcklbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
+ // pav = p - a = (a + b - c) - a = b - c
+ "movq %%mm2, %%mm4 \n\t"
+ "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movq %%mm1, %%mm5 \n\t"
+ "psubw %%mm3, %%mm4 \n\t"
+ "pxor %%mm7, %%mm7 \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "movq %%mm4, %%mm6 \n\t"
+ "psubw %%mm3, %%mm5 \n\t"
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ "pcmpgtw %%mm4, %%mm0 \n\t" // create tqmask pav bytes < 0
+ "paddw %%mm5, %%mm6 \n\t"
+ "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "pcmpgtw %%mm5, %%mm7 \n\t" // create tqmask pbv bytes < 0
+ "psubw %%mm0, %%mm4 \n\t"
+ "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
+ "psubw %%mm0, %%mm4 \n\t"
+ "psubw %%mm7, %%mm5 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "pcmpgtw %%mm6, %%mm0 \n\t" // create tqmask pcv bytes < 0
+ "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "psubw %%mm7, %%mm5 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ // test pa <= pb
+ "movq %%mm4, %%mm7 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
+ "movq %%mm7, %%mm0 \n\t"
+ // use mm7 tqmask to merge pa & pb
+ "pand %%mm7, %%mm5 \n\t"
+ // use mm0 tqmask copy to merge a & b
+ "pand %%mm0, %%mm2 \n\t"
+ "pandn %%mm4, %%mm7 \n\t"
+ "pandn %%mm1, %%mm0 \n\t"
+ "paddw %%mm5, %%mm7 \n\t"
+ "paddw %%mm2, %%mm0 \n\t"
+ // test ((pa <= pb)? pa:pb) <= pc
+ "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
+ "pxor %%mm1, %%mm1 \n\t"
+ "pand %%mm7, %%mm3 \n\t"
+ "pandn %%mm0, %%mm7 \n\t"
+ "paddw %%mm3, %%mm7 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "packuswb %%mm1, %%mm7 \n\t"
+ "movq (%%esi,%%ecx,), %%mm3 \n\t" // load c=Prior(x-bpp)
+ "pand _ActiveMask, %%mm7 \n\t"
+ "movq %%mm3, %%mm2 \n\t" // load b=Prior(x) step 1
+ "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x)
+ "punpcklbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
+ "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value
+ "movq %%mm7, %%mm1 \n\t" // now mm1 will be used as Raw(x-bpp)
+ // do second set of 4 bytes
+ "punpckhbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b
+ "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a
+ // pav = p - a = (a + b - c) - a = b - c
+ "movq %%mm2, %%mm4 \n\t"
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movq %%mm1, %%mm5 \n\t"
+ "psubw %%mm3, %%mm4 \n\t"
+ "pxor %%mm7, %%mm7 \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "movq %%mm4, %%mm6 \n\t"
+ "psubw %%mm3, %%mm5 \n\t"
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ "pcmpgtw %%mm4, %%mm0 \n\t" // create tqmask pav bytes < 0
+ "paddw %%mm5, %%mm6 \n\t"
+ "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "pcmpgtw %%mm5, %%mm7 \n\t" // create tqmask pbv bytes < 0
+ "psubw %%mm0, %%mm4 \n\t"
+ "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
+ "psubw %%mm0, %%mm4 \n\t"
+ "psubw %%mm7, %%mm5 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "pcmpgtw %%mm6, %%mm0 \n\t" // create tqmask pcv bytes < 0
+ "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "psubw %%mm7, %%mm5 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ // test pa <= pb
+ "movq %%mm4, %%mm7 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
+ "movq %%mm7, %%mm0 \n\t"
+ // use mm7 tqmask to merge pa & pb
+ "pand %%mm7, %%mm5 \n\t"
+ // use mm0 tqmask copy to merge a & b
+ "pand %%mm0, %%mm2 \n\t"
+ "pandn %%mm4, %%mm7 \n\t"
+ "pandn %%mm1, %%mm0 \n\t"
+ "paddw %%mm5, %%mm7 \n\t"
+ "paddw %%mm2, %%mm0 \n\t"
+ // test ((pa <= pb)? pa:pb) <= pc
+ "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
+ "pxor %%mm1, %%mm1 \n\t"
+ "pand %%mm7, %%mm3 \n\t"
+ "pandn %%mm0, %%mm7 \n\t"
+ "pxor %%mm1, %%mm1 \n\t"
+ "paddw %%mm3, %%mm7 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ // step ecx to next set of 8 bytes and repeat loop til done
+ "addl $8, %%ecx \n\t"
+ "packuswb %%mm7, %%mm1 \n\t"
+ "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add predictor with Raw(x)
+ "cmpl _MMXLength, %%ecx \n\t"
+ "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value
+ // mm1 will be used as Raw(x-bpp) next loop
+ "jb paeth_4lp \n\t"
+
+ : "=S" (dummy_value_S), // output regs (dummy)
+ "=D" (dummy_value_D)
+
+ : "0" (prev_row), // esi // input regs
+ "1" (row) // edi
+
+ : "%ecx" // clobber list
+#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2", "%mm3"
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ break; // end 4 bpp
+
+ case 8: // bpp == 8
+ {
+ _ActiveMask.use = 0x00000000ffffffffLL;
+
+ __asm__ __volatile__ (
+ "movl _dif, %%ecx \n\t"
+// preload "movl row, %%edi \n\t"
+// preload "movl prev_row, %%esi \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // only time should need to read
+ // a=Raw(x-bpp) bytes
+ "paeth_8lp: \n\t"
+ // do first set of 4 bytes
+ "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes
+ "punpcklbw %%mm0, %%mm1 \n\t" // unpack Low bytes of a
+ "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x)
+ "punpcklbw %%mm0, %%mm2 \n\t" // unpack Low bytes of b
+ // pav = p - a = (a + b - c) - a = b - c
+ "movq %%mm2, %%mm4 \n\t"
+ "punpcklbw %%mm0, %%mm3 \n\t" // unpack Low bytes of c
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movq %%mm1, %%mm5 \n\t"
+ "psubw %%mm3, %%mm4 \n\t"
+ "pxor %%mm7, %%mm7 \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "movq %%mm4, %%mm6 \n\t"
+ "psubw %%mm3, %%mm5 \n\t"
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ "pcmpgtw %%mm4, %%mm0 \n\t" // create tqmask pav bytes < 0
+ "paddw %%mm5, %%mm6 \n\t"
+ "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "pcmpgtw %%mm5, %%mm7 \n\t" // create tqmask pbv bytes < 0
+ "psubw %%mm0, %%mm4 \n\t"
+ "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
+ "psubw %%mm0, %%mm4 \n\t"
+ "psubw %%mm7, %%mm5 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "pcmpgtw %%mm6, %%mm0 \n\t" // create tqmask pcv bytes < 0
+ "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "psubw %%mm7, %%mm5 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ // test pa <= pb
+ "movq %%mm4, %%mm7 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
+ "movq %%mm7, %%mm0 \n\t"
+ // use mm7 tqmask to merge pa & pb
+ "pand %%mm7, %%mm5 \n\t"
+ // use mm0 tqmask copy to merge a & b
+ "pand %%mm0, %%mm2 \n\t"
+ "pandn %%mm4, %%mm7 \n\t"
+ "pandn %%mm1, %%mm0 \n\t"
+ "paddw %%mm5, %%mm7 \n\t"
+ "paddw %%mm2, %%mm0 \n\t"
+ // test ((pa <= pb)? pa:pb) <= pc
+ "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
+ "pxor %%mm1, %%mm1 \n\t"
+ "pand %%mm7, %%mm3 \n\t"
+ "pandn %%mm0, %%mm7 \n\t"
+ "paddw %%mm3, %%mm7 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "packuswb %%mm1, %%mm7 \n\t"
+ "movq -8(%%esi,%%ecx,), %%mm3 \n\t" // read c=Prior(x-bpp) bytes
+ "pand _ActiveMask, %%mm7 \n\t"
+ "movq (%%esi,%%ecx,), %%mm2 \n\t" // load b=Prior(x)
+ "paddb (%%edi,%%ecx,), %%mm7 \n\t" // add Paeth predictor with Raw(x)
+ "punpckhbw %%mm0, %%mm3 \n\t" // unpack High bytes of c
+ "movq %%mm7, (%%edi,%%ecx,) \n\t" // write back updated value
+ "movq -8(%%edi,%%ecx,), %%mm1 \n\t" // read a=Raw(x-bpp) bytes
+
+ // do second set of 4 bytes
+ "punpckhbw %%mm0, %%mm2 \n\t" // unpack High bytes of b
+ "punpckhbw %%mm0, %%mm1 \n\t" // unpack High bytes of a
+ // pav = p - a = (a + b - c) - a = b - c
+ "movq %%mm2, %%mm4 \n\t"
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movq %%mm1, %%mm5 \n\t"
+ "psubw %%mm3, %%mm4 \n\t"
+ "pxor %%mm7, %%mm7 \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "movq %%mm4, %%mm6 \n\t"
+ "psubw %%mm3, %%mm5 \n\t"
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ "pcmpgtw %%mm4, %%mm0 \n\t" // create tqmask pav bytes < 0
+ "paddw %%mm5, %%mm6 \n\t"
+ "pand %%mm4, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "pcmpgtw %%mm5, %%mm7 \n\t" // create tqmask pbv bytes < 0
+ "psubw %%mm0, %%mm4 \n\t"
+ "pand %%mm5, %%mm7 \n\t" // only pbv bytes < 0 in mm0
+ "psubw %%mm0, %%mm4 \n\t"
+ "psubw %%mm7, %%mm5 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ "pcmpgtw %%mm6, %%mm0 \n\t" // create tqmask pcv bytes < 0
+ "pand %%mm6, %%mm0 \n\t" // only pav bytes < 0 in mm7
+ "psubw %%mm7, %%mm5 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ // test pa <= pb
+ "movq %%mm4, %%mm7 \n\t"
+ "psubw %%mm0, %%mm6 \n\t"
+ "pcmpgtw %%mm5, %%mm7 \n\t" // pa > pb?
+ "movq %%mm7, %%mm0 \n\t"
+ // use mm7 tqmask to merge pa & pb
+ "pand %%mm7, %%mm5 \n\t"
+ // use mm0 tqmask copy to merge a & b
+ "pand %%mm0, %%mm2 \n\t"
+ "pandn %%mm4, %%mm7 \n\t"
+ "pandn %%mm1, %%mm0 \n\t"
+ "paddw %%mm5, %%mm7 \n\t"
+ "paddw %%mm2, %%mm0 \n\t"
+ // test ((pa <= pb)? pa:pb) <= pc
+ "pcmpgtw %%mm6, %%mm7 \n\t" // pab > pc?
+ "pxor %%mm1, %%mm1 \n\t"
+ "pand %%mm7, %%mm3 \n\t"
+ "pandn %%mm0, %%mm7 \n\t"
+ "pxor %%mm1, %%mm1 \n\t"
+ "paddw %%mm3, %%mm7 \n\t"
+ "pxor %%mm0, %%mm0 \n\t"
+ // step ecx to next set of 8 bytes and repeat loop til done
+ "addl $8, %%ecx \n\t"
+ "packuswb %%mm7, %%mm1 \n\t"
+ "paddb -8(%%edi,%%ecx,), %%mm1 \n\t" // add Paeth predictor with Raw(x)
+ "cmpl _MMXLength, %%ecx \n\t"
+ "movq %%mm1, -8(%%edi,%%ecx,) \n\t" // write back updated value
+ // mm1 will be used as Raw(x-bpp) next loop
+ "jb paeth_8lp \n\t"
+
+ : "=S" (dummy_value_S), // output regs (dummy)
+ "=D" (dummy_value_D)
+
+ : "0" (prev_row), // esi // input regs
+ "1" (row) // edi
+
+ : "%ecx" // clobber list
+#if 0 /* %mm0, ..., %mm7 not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2", "%mm3"
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ break; // end 8 bpp
+
+ case 1: // bpp = 1
+ case 2: // bpp = 2
+ default: // bpp > 8
+ {
+ __asm__ __volatile__ (
+#ifdef __PIC__
+ "pushl %%ebx \n\t" // save Global Offset Table index
+#endif
+ "movl _dif, %%ebx \n\t"
+ "cmpl _FullLength, %%ebx \n\t"
+ "jnb paeth_dend \n\t"
+
+// preload "movl row, %%edi \n\t"
+// preload "movl prev_row, %%esi \n\t"
+ // do Paeth decode for remaining bytes
+ "movl %%ebx, %%edx \n\t"
+// preload "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx)
+ "subl %%ecx, %%edx \n\t" // edx = ebx - bpp
+ "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx
+
+ "paeth_dlp: \n\t"
+ "xorl %%eax, %%eax \n\t"
+ // pav = p - a = (a + b - c) - a = b - c
+ "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al
+ "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl
+ "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp)
+ "movl %%eax, _patemp \n\t" // Save pav for later use
+ "xorl %%eax, %%eax \n\t"
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al
+ "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp)
+ "movl %%eax, %%ecx \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "addl _patemp, %%eax \n\t" // pcv = pav + pbv
+ // pc = abs(pcv)
+ "testl $0x80000000, %%eax \n\t"
+ "jz paeth_dpca \n\t"
+ "negl %%eax \n\t" // reverse sign of neg values
+
+ "paeth_dpca: \n\t"
+ "movl %%eax, _pctemp \n\t" // save pc for later use
+ // pb = abs(pbv)
+ "testl $0x80000000, %%ecx \n\t"
+ "jz paeth_dpba \n\t"
+ "negl %%ecx \n\t" // reverse sign of neg values
+
+ "paeth_dpba: \n\t"
+ "movl %%ecx, _pbtemp \n\t" // save pb for later use
+ // pa = abs(pav)
+ "movl _patemp, %%eax \n\t"
+ "testl $0x80000000, %%eax \n\t"
+ "jz paeth_dpaa \n\t"
+ "negl %%eax \n\t" // reverse sign of neg values
+
+ "paeth_dpaa: \n\t"
+ "movl %%eax, _patemp \n\t" // save pa for later use
+ // test if pa <= pb
+ "cmpl %%ecx, %%eax \n\t"
+ "jna paeth_dabb \n\t"
+ // pa > pb; now test if pb <= pc
+ "cmpl _pctemp, %%ecx \n\t"
+ "jna paeth_dbbc \n\t"
+ // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl
+ "jmp paeth_dpaeth \n\t"
+
+ "paeth_dbbc: \n\t"
+ // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
+ "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl
+ "jmp paeth_dpaeth \n\t"
+
+ "paeth_dabb: \n\t"
+ // pa <= pb; now test if pa <= pc
+ "cmpl _pctemp, %%eax \n\t"
+ "jna paeth_dabc \n\t"
+ // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl
+ "jmp paeth_dpaeth \n\t"
+
+ "paeth_dabc: \n\t"
+ // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
+ "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl
+
+ "paeth_dpaeth: \n\t"
+ "incl %%ebx \n\t"
+ "incl %%edx \n\t"
+ // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
+ "addb %%cl, -1(%%edi,%%ebx,) \n\t"
+ "cmpl _FullLength, %%ebx \n\t"
+ "jb paeth_dlp \n\t"
+
+ "paeth_dend: \n\t"
+#ifdef __PIC__
+ "popl %%ebx \n\t" // index to Global Offset Table
+#endif
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "0" (bpp), // ecx // input regs
+ "1" (prev_row), // esi
+ "2" (row) // edi
+
+ : "%eax", "%edx" // clobber list
+#ifndef __PIC__
+ , "%ebx"
+#endif
+ );
+ }
+ return; // No need to go further with this one
+
+ } // end switch (bpp)
+
+ __asm__ __volatile__ (
+ // MMX acceleration complete; now do clean-up
+ // check if any remaining bytes left to decode
+#ifdef __PIC__
+ "pushl %%ebx \n\t" // save index to Global Offset Table
+#endif
+ "movl _MMXLength, %%ebx \n\t"
+ "cmpl _FullLength, %%ebx \n\t"
+ "jnb paeth_end \n\t"
+//pre "movl row, %%edi \n\t"
+//pre "movl prev_row, %%esi \n\t"
+ // do Paeth decode for remaining bytes
+ "movl %%ebx, %%edx \n\t"
+//pre "subl bpp, %%edx \n\t" // (bpp is preloaded into ecx)
+ "subl %%ecx, %%edx \n\t" // edx = ebx - bpp
+ "xorl %%ecx, %%ecx \n\t" // zero ecx before using cl & cx below
+
+ "paeth_lp2: \n\t"
+ "xorl %%eax, %%eax \n\t"
+ // pav = p - a = (a + b - c) - a = b - c
+ "movb (%%esi,%%ebx,), %%al \n\t" // load Prior(x) into al
+ "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl
+ "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp)
+ "movl %%eax, _patemp \n\t" // Save pav for later use
+ "xorl %%eax, %%eax \n\t"
+ // pbv = p - b = (a + b - c) - b = a - c
+ "movb (%%edi,%%edx,), %%al \n\t" // load Raw(x-bpp) into al
+ "subl %%ecx, %%eax \n\t" // subtract Prior(x-bpp)
+ "movl %%eax, %%ecx \n\t"
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ "addl _patemp, %%eax \n\t" // pcv = pav + pbv
+ // pc = abs(pcv)
+ "testl $0x80000000, %%eax \n\t"
+ "jz paeth_pca2 \n\t"
+ "negl %%eax \n\t" // reverse sign of neg values
+
+ "paeth_pca2: \n\t"
+ "movl %%eax, _pctemp \n\t" // save pc for later use
+ // pb = abs(pbv)
+ "testl $0x80000000, %%ecx \n\t"
+ "jz paeth_pba2 \n\t"
+ "negl %%ecx \n\t" // reverse sign of neg values
+
+ "paeth_pba2: \n\t"
+ "movl %%ecx, _pbtemp \n\t" // save pb for later use
+ // pa = abs(pav)
+ "movl _patemp, %%eax \n\t"
+ "testl $0x80000000, %%eax \n\t"
+ "jz paeth_paa2 \n\t"
+ "negl %%eax \n\t" // reverse sign of neg values
+
+ "paeth_paa2: \n\t"
+ "movl %%eax, _patemp \n\t" // save pa for later use
+ // test if pa <= pb
+ "cmpl %%ecx, %%eax \n\t"
+ "jna paeth_abb2 \n\t"
+ // pa > pb; now test if pb <= pc
+ "cmpl _pctemp, %%ecx \n\t"
+ "jna paeth_bbc2 \n\t"
+ // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl
+ "jmp paeth_paeth2 \n\t"
+
+ "paeth_bbc2: \n\t"
+ // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
+ "movb (%%esi,%%ebx,), %%cl \n\t" // load Prior(x) into cl
+ "jmp paeth_paeth2 \n\t"
+
+ "paeth_abb2: \n\t"
+ // pa <= pb; now test if pa <= pc
+ "cmpl _pctemp, %%eax \n\t"
+ "jna paeth_abc2 \n\t"
+ // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ "movb (%%esi,%%edx,), %%cl \n\t" // load Prior(x-bpp) into cl
+ "jmp paeth_paeth2 \n\t"
+
+ "paeth_abc2: \n\t"
+ // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
+ "movb (%%edi,%%edx,), %%cl \n\t" // load Raw(x-bpp) into cl
+
+ "paeth_paeth2: \n\t"
+ "incl %%ebx \n\t"
+ "incl %%edx \n\t"
+ // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
+ "addb %%cl, -1(%%edi,%%ebx,) \n\t"
+ "cmpl _FullLength, %%ebx \n\t"
+ "jb paeth_lp2 \n\t"
+
+ "paeth_end: \n\t"
+ "EMMS \n\t" // end MMX; prep for poss. FP instrs.
+#ifdef __PIC__
+ "popl %%ebx \n\t" // restore index to Global Offset Table
+#endif
+
+ : "=c" (dummy_value_c), // output regs (dummy)
+ "=S" (dummy_value_S),
+ "=D" (dummy_value_D)
+
+ : "0" (bpp), // ecx // input regs
+ "1" (prev_row), // esi
+ "2" (row) // edi
+
+ : "%eax", "%edx" // clobber list (no input regs!)
+#ifndef __PIC__
+ , "%ebx"
+#endif
+ );
+
+} /* end png_read_filter_row_mmx_paeth() */
+#endif
+
+
+
+
+#ifdef PNG_THREAD_UNSAFE_OK
+//===========================================================================//
+// //
+// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ S U B //
+// //
+//===========================================================================//
+
+// Optimized code for PNG Sub filter decoder
+
+static void /* PRIVATE */
+png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row)
+{
+ int bpp;
+ int dummy_value_a;
+ int dummy_value_D;
+
+ bpp = (row_info->pixel_depth + 7) >> 3; // calc number of bytes per pixel
+ _FullLength = row_info->rowbytes - bpp; // number of bytes to filter
+
+ __asm__ __volatile__ (
+//pre "movl row, %%edi \n\t"
+ "movl %%edi, %%esi \n\t" // lp = row
+//pre "movl bpp, %%eax \n\t"
+ "addl %%eax, %%edi \n\t" // rp = row + bpp
+//irr "xorl %%eax, %%eax \n\t"
+ // get # of bytes to tqalignment
+ "movl %%edi, _dif \n\t" // take start of row
+ "addl $0xf, _dif \n\t" // add 7 + 8 to incr past
+ // tqalignment boundary
+ "xorl %%ecx, %%ecx \n\t"
+ "andl $0xfffffff8, _dif \n\t" // tqmask to tqalignment boundary
+ "subl %%edi, _dif \n\t" // subtract from start ==> value
+ "jz sub_go \n\t" // ecx at tqalignment
+
+ "sub_lp1: \n\t" // fix tqalignment
+ "movb (%%esi,%%ecx,), %%al \n\t"
+ "addb %%al, (%%edi,%%ecx,) \n\t"
+ "incl %%ecx \n\t"
+ "cmpl _dif, %%ecx \n\t"
+ "jb sub_lp1 \n\t"
+
+ "sub_go: \n\t"
+ "movl _FullLength, %%eax \n\t"
+ "movl %%eax, %%edx \n\t"
+ "subl %%ecx, %%edx \n\t" // subtract tqalignment fix
+ "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8
+ "subl %%edx, %%eax \n\t" // drop over bytes from length
+ "movl %%eax, _MMXLength \n\t"
+
+ : "=a" (dummy_value_a), // 0 // output regs (dummy)
+ "=D" (dummy_value_D) // 1
+
+ : "0" (bpp), // eax // input regs
+ "1" (row) // edi
+
+ : "%ebx", "%ecx", "%edx" // clobber list
+ , "%esi"
+
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2", "%mm3"
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+
+ // now do the math for the rest of the row
+ switch (bpp)
+ {
+ case 3:
+ {
+ _ActiveMask.use = 0x0000ffffff000000LL;
+ _ShiftBpp.use = 24; // == 3 * 8
+ _ShiftRem.use = 40; // == 64 - 24
+
+ __asm__ __volatile__ (
+// preload "movl row, %%edi \n\t"
+ "movq _ActiveMask, %%mm7 \n\t" // load _ActiveMask for 2nd
+ // active byte group
+ "movl %%edi, %%esi \n\t" // lp = row
+// preload "movl bpp, %%eax \n\t"
+ "addl %%eax, %%edi \n\t" // rp = row + bpp
+ "movq %%mm7, %%mm6 \n\t"
+ "movl _dif, %%edx \n\t"
+ "psllq _ShiftBpp, %%mm6 \n\t" // move tqmask in mm6 to cover
+ // 3rd active byte group
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%edx,), %%mm1 \n\t"
+
+ "sub_3lp: \n\t" // shift data for adding first
+ "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for tqmask;
+ // shift clears inactive bytes)
+ // add 1st active group
+ "movq (%%edi,%%edx,), %%mm0 \n\t"
+ "paddb %%mm1, %%mm0 \n\t"
+
+ // add 2nd active group
+ "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
+ "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly
+ "pand %%mm7, %%mm1 \n\t" // tqmask to use 2nd active group
+ "paddb %%mm1, %%mm0 \n\t"
+
+ // add 3rd active group
+ "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
+ "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly
+ "pand %%mm6, %%mm1 \n\t" // tqmask to use 3rd active group
+ "addl $8, %%edx \n\t"
+ "paddb %%mm1, %%mm0 \n\t"
+
+ "cmpl _MMXLength, %%edx \n\t"
+ "movq %%mm0, -8(%%edi,%%edx,) \n\t" // write updated Raws to array
+ "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop
+ "jb sub_3lp \n\t"
+
+ : "=a" (dummy_value_a), // 0 // output regs (dummy)
+ "=D" (dummy_value_D) // 1
+
+ : "0" (bpp), // eax // input regs
+ "1" (row) // edi
+
+ : "%edx", "%esi" // clobber list
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm6", "%mm7"
+#endif
+ );
+ }
+ break;
+
+ case 1:
+ {
+ __asm__ __volatile__ (
+ "movl _dif, %%edx \n\t"
+// preload "movl row, %%edi \n\t"
+ "cmpl _FullLength, %%edx \n\t"
+ "jnb sub_1end \n\t"
+ "movl %%edi, %%esi \n\t" // lp = row
+ "xorl %%eax, %%eax \n\t"
+// preload "movl bpp, %%eax \n\t"
+ "addl %%eax, %%edi \n\t" // rp = row + bpp
+
+ "sub_1lp: \n\t"
+ "movb (%%esi,%%edx,), %%al \n\t"
+ "addb %%al, (%%edi,%%edx,) \n\t"
+ "incl %%edx \n\t"
+ "cmpl _FullLength, %%edx \n\t"
+ "jb sub_1lp \n\t"
+
+ "sub_1end: \n\t"
+
+ : "=a" (dummy_value_a), // 0 // output regs (dummy)
+ "=D" (dummy_value_D) // 1
+
+ : "0" (bpp), // eax // input regs
+ "1" (row) // edi
+
+ : "%edx", "%esi" // clobber list
+ );
+ }
+ return;
+
+ case 6:
+ case 4:
+ //case 7: // GRR BOGUS
+ //case 5: // GRR BOGUS
+ {
+ _ShiftBpp.use = bpp << 3;
+ _ShiftRem.use = 64 - _ShiftBpp.use;
+
+ __asm__ __volatile__ (
+// preload "movl row, %%edi \n\t"
+ "movl _dif, %%edx \n\t"
+ "movl %%edi, %%esi \n\t" // lp = row
+// preload "movl bpp, %%eax \n\t"
+ "addl %%eax, %%edi \n\t" // rp = row + bpp
+
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%edx,), %%mm1 \n\t"
+
+ "sub_4lp: \n\t" // shift data for adding first
+ "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for tqmask;
+ // shift clears inactive bytes)
+ "movq (%%edi,%%edx,), %%mm0 \n\t"
+ "paddb %%mm1, %%mm0 \n\t"
+
+ // add 2nd active group
+ "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
+ "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly
+ "addl $8, %%edx \n\t"
+ "paddb %%mm1, %%mm0 \n\t"
+
+ "cmpl _MMXLength, %%edx \n\t"
+ "movq %%mm0, -8(%%edi,%%edx,) \n\t"
+ "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop
+ "jb sub_4lp \n\t"
+
+ : "=a" (dummy_value_a), // 0 // output regs (dummy)
+ "=D" (dummy_value_D) // 1
+
+ : "0" (bpp), // eax // input regs
+ "1" (row) // edi
+
+ : "%edx", "%esi" // clobber list
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1"
+#endif
+ );
+ }
+ break;
+
+ case 2:
+ {
+ _ActiveMask.use = 0x00000000ffff0000LL;
+ _ShiftBpp.use = 16; // == 2 * 8
+ _ShiftRem.use = 48; // == 64 - 16
+
+ __asm__ __volatile__ (
+ "movq _ActiveMask, %%mm7 \n\t" // load _ActiveMask for 2nd
+ // active byte group
+ "movl _dif, %%edx \n\t"
+ "movq %%mm7, %%mm6 \n\t"
+// preload "movl row, %%edi \n\t"
+ "psllq _ShiftBpp, %%mm6 \n\t" // move tqmask in mm6 to cover
+ // 3rd active byte group
+ "movl %%edi, %%esi \n\t" // lp = row
+ "movq %%mm6, %%mm5 \n\t"
+// preload "movl bpp, %%eax \n\t"
+ "addl %%eax, %%edi \n\t" // rp = row + bpp
+ "psllq _ShiftBpp, %%mm5 \n\t" // move tqmask in mm5 to cover
+ // 4th active byte group
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%edx,), %%mm1 \n\t"
+
+ "sub_2lp: \n\t" // shift data for adding first
+ "psrlq _ShiftRem, %%mm1 \n\t" // bpp bytes (no need for tqmask;
+ // shift clears inactive bytes)
+ // add 1st active group
+ "movq (%%edi,%%edx,), %%mm0 \n\t"
+ "paddb %%mm1, %%mm0 \n\t"
+
+ // add 2nd active group
+ "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
+ "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly
+ "pand %%mm7, %%mm1 \n\t" // tqmask to use 2nd active group
+ "paddb %%mm1, %%mm0 \n\t"
+
+ // add 3rd active group
+ "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
+ "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly
+ "pand %%mm6, %%mm1 \n\t" // tqmask to use 3rd active group
+ "paddb %%mm1, %%mm0 \n\t"
+
+ // add 4th active group
+ "movq %%mm0, %%mm1 \n\t" // mov updated Raws to mm1
+ "psllq _ShiftBpp, %%mm1 \n\t" // shift data to pos. correctly
+ "pand %%mm5, %%mm1 \n\t" // tqmask to use 4th active group
+ "addl $8, %%edx \n\t"
+ "paddb %%mm1, %%mm0 \n\t"
+ "cmpl _MMXLength, %%edx \n\t"
+ "movq %%mm0, -8(%%edi,%%edx,) \n\t" // write updated Raws to array
+ "movq %%mm0, %%mm1 \n\t" // prep 1st add at top of loop
+ "jb sub_2lp \n\t"
+
+ : "=a" (dummy_value_a), // 0 // output regs (dummy)
+ "=D" (dummy_value_D) // 1
+
+ : "0" (bpp), // eax // input regs
+ "1" (row) // edi
+
+ : "%edx", "%esi" // clobber list
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ break;
+
+ case 8:
+ {
+ __asm__ __volatile__ (
+// preload "movl row, %%edi \n\t"
+ "movl _dif, %%edx \n\t"
+ "movl %%edi, %%esi \n\t" // lp = row
+// preload "movl bpp, %%eax \n\t"
+ "addl %%eax, %%edi \n\t" // rp = row + bpp
+ "movl _MMXLength, %%ecx \n\t"
+
+ // prime the pump: load the first Raw(x-bpp) data set
+ "movq -8(%%edi,%%edx,), %%mm7 \n\t"
+ "andl $0x0000003f, %%ecx \n\t" // calc bytes over mult of 64
+
+ "sub_8lp: \n\t"
+ "movq (%%edi,%%edx,), %%mm0 \n\t" // load Sub(x) for 1st 8 bytes
+ "paddb %%mm7, %%mm0 \n\t"
+ "movq 8(%%edi,%%edx,), %%mm1 \n\t" // load Sub(x) for 2nd 8 bytes
+ "movq %%mm0, (%%edi,%%edx,) \n\t" // write Raw(x) for 1st 8 bytes
+
+ // Now mm0 will be used as Raw(x-bpp) for the 2nd group of 8 bytes.
+ // This will be repeated for each group of 8 bytes with the 8th
+ // group being used as the Raw(x-bpp) for the 1st group of the
+ // next loop.
+
+ "paddb %%mm0, %%mm1 \n\t"
+ "movq 16(%%edi,%%edx,), %%mm2 \n\t" // load Sub(x) for 3rd 8 bytes
+ "movq %%mm1, 8(%%edi,%%edx,) \n\t" // write Raw(x) for 2nd 8 bytes
+ "paddb %%mm1, %%mm2 \n\t"
+ "movq 24(%%edi,%%edx,), %%mm3 \n\t" // load Sub(x) for 4th 8 bytes
+ "movq %%mm2, 16(%%edi,%%edx,) \n\t" // write Raw(x) for 3rd 8 bytes
+ "paddb %%mm2, %%mm3 \n\t"
+ "movq 32(%%edi,%%edx,), %%mm4 \n\t" // load Sub(x) for 5th 8 bytes
+ "movq %%mm3, 24(%%edi,%%edx,) \n\t" // write Raw(x) for 4th 8 bytes
+ "paddb %%mm3, %%mm4 \n\t"
+ "movq 40(%%edi,%%edx,), %%mm5 \n\t" // load Sub(x) for 6th 8 bytes
+ "movq %%mm4, 32(%%edi,%%edx,) \n\t" // write Raw(x) for 5th 8 bytes
+ "paddb %%mm4, %%mm5 \n\t"
+ "movq 48(%%edi,%%edx,), %%mm6 \n\t" // load Sub(x) for 7th 8 bytes
+ "movq %%mm5, 40(%%edi,%%edx,) \n\t" // write Raw(x) for 6th 8 bytes
+ "paddb %%mm5, %%mm6 \n\t"
+ "movq 56(%%edi,%%edx,), %%mm7 \n\t" // load Sub(x) for 8th 8 bytes
+ "movq %%mm6, 48(%%edi,%%edx,) \n\t" // write Raw(x) for 7th 8 bytes
+ "addl $64, %%edx \n\t"
+ "paddb %%mm6, %%mm7 \n\t"
+ "cmpl %%ecx, %%edx \n\t"
+ "movq %%mm7, -8(%%edi,%%edx,) \n\t" // write Raw(x) for 8th 8 bytes
+ "jb sub_8lp \n\t"
+
+ "cmpl _MMXLength, %%edx \n\t"
+ "jnb sub_8lt8 \n\t"
+
+ "sub_8lpA: \n\t"
+ "movq (%%edi,%%edx,), %%mm0 \n\t"
+ "addl $8, %%edx \n\t"
+ "paddb %%mm7, %%mm0 \n\t"
+ "cmpl _MMXLength, %%edx \n\t"
+ "movq %%mm0, -8(%%edi,%%edx,) \n\t" // -8 to offset early addl edx
+ "movq %%mm0, %%mm7 \n\t" // move calculated Raw(x) data
+ // to mm1 to be new Raw(x-bpp)
+ // for next loop
+ "jb sub_8lpA \n\t"
+
+ "sub_8lt8: \n\t"
+
+ : "=a" (dummy_value_a), // 0 // output regs (dummy)
+ "=D" (dummy_value_D) // 1
+
+ : "0" (bpp), // eax // input regs
+ "1" (row) // edi
+
+ : "%ecx", "%edx", "%esi" // clobber list
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2", "%mm3", "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+ }
+ break;
+
+ default: // bpp greater than 8 bytes GRR BOGUS
+ {
+ __asm__ __volatile__ (
+ "movl _dif, %%edx \n\t"
+// preload "movl row, %%edi \n\t"
+ "movl %%edi, %%esi \n\t" // lp = row
+// preload "movl bpp, %%eax \n\t"
+ "addl %%eax, %%edi \n\t" // rp = row + bpp
+
+ "sub_Alp: \n\t"
+ "movq (%%edi,%%edx,), %%mm0 \n\t"
+ "movq (%%esi,%%edx,), %%mm1 \n\t"
+ "addl $8, %%edx \n\t"
+ "paddb %%mm1, %%mm0 \n\t"
+ "cmpl _MMXLength, %%edx \n\t"
+ "movq %%mm0, -8(%%edi,%%edx,) \n\t" // mov does not affect flags;
+ // -8 to offset addl edx
+ "jb sub_Alp \n\t"
+
+ : "=a" (dummy_value_a), // 0 // output regs (dummy)
+ "=D" (dummy_value_D) // 1
+
+ : "0" (bpp), // eax // input regs
+ "1" (row) // edi
+
+ : "%edx", "%esi" // clobber list
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1"
+#endif
+ );
+ }
+ break;
+
+ } // end switch (bpp)
+
+ __asm__ __volatile__ (
+ "movl _MMXLength, %%edx \n\t"
+//pre "movl row, %%edi \n\t"
+ "cmpl _FullLength, %%edx \n\t"
+ "jnb sub_end \n\t"
+
+ "movl %%edi, %%esi \n\t" // lp = row
+//pre "movl bpp, %%eax \n\t"
+ "addl %%eax, %%edi \n\t" // rp = row + bpp
+ "xorl %%eax, %%eax \n\t"
+
+ "sub_lp2: \n\t"
+ "movb (%%esi,%%edx,), %%al \n\t"
+ "addb %%al, (%%edi,%%edx,) \n\t"
+ "incl %%edx \n\t"
+ "cmpl _FullLength, %%edx \n\t"
+ "jb sub_lp2 \n\t"
+
+ "sub_end: \n\t"
+ "EMMS \n\t" // end MMX instructions
+
+ : "=a" (dummy_value_a), // 0 // output regs (dummy)
+ "=D" (dummy_value_D) // 1
+
+ : "0" (bpp), // eax // input regs
+ "1" (row) // edi
+
+ : "%edx", "%esi" // clobber list
+ );
+
+} // end of png_read_filter_row_mmx_sub()
+#endif
+
+
+
+
+//===========================================================================//
+// //
+// P N G _ R E A D _ F I L T E R _ R O W _ M M X _ U P //
+// //
+//===========================================================================//
+
+// Optimized code for PNG Up filter decoder
+
+static void /* PRIVATE */
+png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row,
+ png_bytep prev_row)
+{
+ png_uint_32 len;
+ int dummy_value_d; // fix 'forbidden register 3 (dx) was spilled' error
+ int dummy_value_S;
+ int dummy_value_D;
+
+ len = row_info->rowbytes; // number of bytes to filter
+
+ __asm__ __volatile__ (
+//pre "movl row, %%edi \n\t"
+ // get # of bytes to tqalignment
+#ifdef __PIC__
+ "pushl %%ebx \n\t"
+#endif
+ "movl %%edi, %%ecx \n\t"
+ "xorl %%ebx, %%ebx \n\t"
+ "addl $0x7, %%ecx \n\t"
+ "xorl %%eax, %%eax \n\t"
+ "andl $0xfffffff8, %%ecx \n\t"
+//pre "movl prev_row, %%esi \n\t"
+ "subl %%edi, %%ecx \n\t"
+ "jz up_go \n\t"
+
+ "up_lp1: \n\t" // fix tqalignment
+ "movb (%%edi,%%ebx,), %%al \n\t"
+ "addb (%%esi,%%ebx,), %%al \n\t"
+ "incl %%ebx \n\t"
+ "cmpl %%ecx, %%ebx \n\t"
+ "movb %%al, -1(%%edi,%%ebx,) \n\t" // mov does not affect flags; -1 to
+ "jb up_lp1 \n\t" // offset incl ebx
+
+ "up_go: \n\t"
+//pre "movl len, %%edx \n\t"
+ "movl %%edx, %%ecx \n\t"
+ "subl %%ebx, %%edx \n\t" // subtract tqalignment fix
+ "andl $0x0000003f, %%edx \n\t" // calc bytes over mult of 64
+ "subl %%edx, %%ecx \n\t" // drop over bytes from length
+
+ // unrolled loop - use all MMX registers and interleave to reduce
+ // number of branch instructions (loops) and reduce partial stalls
+ "up_loop: \n\t"
+ "movq (%%esi,%%ebx,), %%mm1 \n\t"
+ "movq (%%edi,%%ebx,), %%mm0 \n\t"
+ "movq 8(%%esi,%%ebx,), %%mm3 \n\t"
+ "paddb %%mm1, %%mm0 \n\t"
+ "movq 8(%%edi,%%ebx,), %%mm2 \n\t"
+ "movq %%mm0, (%%edi,%%ebx,) \n\t"
+ "paddb %%mm3, %%mm2 \n\t"
+ "movq 16(%%esi,%%ebx,), %%mm5 \n\t"
+ "movq %%mm2, 8(%%edi,%%ebx,) \n\t"
+ "movq 16(%%edi,%%ebx,), %%mm4 \n\t"
+ "movq 24(%%esi,%%ebx,), %%mm7 \n\t"
+ "paddb %%mm5, %%mm4 \n\t"
+ "movq 24(%%edi,%%ebx,), %%mm6 \n\t"
+ "movq %%mm4, 16(%%edi,%%ebx,) \n\t"
+ "paddb %%mm7, %%mm6 \n\t"
+ "movq 32(%%esi,%%ebx,), %%mm1 \n\t"
+ "movq %%mm6, 24(%%edi,%%ebx,) \n\t"
+ "movq 32(%%edi,%%ebx,), %%mm0 \n\t"
+ "movq 40(%%esi,%%ebx,), %%mm3 \n\t"
+ "paddb %%mm1, %%mm0 \n\t"
+ "movq 40(%%edi,%%ebx,), %%mm2 \n\t"
+ "movq %%mm0, 32(%%edi,%%ebx,) \n\t"
+ "paddb %%mm3, %%mm2 \n\t"
+ "movq 48(%%esi,%%ebx,), %%mm5 \n\t"
+ "movq %%mm2, 40(%%edi,%%ebx,) \n\t"
+ "movq 48(%%edi,%%ebx,), %%mm4 \n\t"
+ "movq 56(%%esi,%%ebx,), %%mm7 \n\t"
+ "paddb %%mm5, %%mm4 \n\t"
+ "movq 56(%%edi,%%ebx,), %%mm6 \n\t"
+ "movq %%mm4, 48(%%edi,%%ebx,) \n\t"
+ "addl $64, %%ebx \n\t"
+ "paddb %%mm7, %%mm6 \n\t"
+ "cmpl %%ecx, %%ebx \n\t"
+ "movq %%mm6, -8(%%edi,%%ebx,) \n\t" // (+56)movq does not affect flags;
+ "jb up_loop \n\t" // -8 to offset addl ebx
+
+ "cmpl $0, %%edx \n\t" // test for bytes over mult of 64
+ "jz up_end \n\t"
+
+ "cmpl $8, %%edx \n\t" // test for less than 8 bytes
+ "jb up_lt8 \n\t" // [added by lcreeve@netins.net]
+
+ "addl %%edx, %%ecx \n\t"
+ "andl $0x00000007, %%edx \n\t" // calc bytes over mult of 8
+ "subl %%edx, %%ecx \n\t" // drop over bytes from length
+ "jz up_lt8 \n\t"
+
+ "up_lpA: \n\t" // use MMX regs to update 8 bytes sim.
+ "movq (%%esi,%%ebx,), %%mm1 \n\t"
+ "movq (%%edi,%%ebx,), %%mm0 \n\t"
+ "addl $8, %%ebx \n\t"
+ "paddb %%mm1, %%mm0 \n\t"
+ "cmpl %%ecx, %%ebx \n\t"
+ "movq %%mm0, -8(%%edi,%%ebx,) \n\t" // movq does not affect flags; -8 to
+ "jb up_lpA \n\t" // offset add ebx
+ "cmpl $0, %%edx \n\t" // test for bytes over mult of 8
+ "jz up_end \n\t"
+
+ "up_lt8: \n\t"
+ "xorl %%eax, %%eax \n\t"
+ "addl %%edx, %%ecx \n\t" // move over byte count into counter
+
+ "up_lp2: \n\t" // use x86 regs for remaining bytes
+ "movb (%%edi,%%ebx,), %%al \n\t"
+ "addb (%%esi,%%ebx,), %%al \n\t"
+ "incl %%ebx \n\t"
+ "cmpl %%ecx, %%ebx \n\t"
+ "movb %%al, -1(%%edi,%%ebx,) \n\t" // mov does not affect flags; -1 to
+ "jb up_lp2 \n\t" // offset inc ebx
+
+ "up_end: \n\t"
+ "EMMS \n\t" // conversion of filtered row complete
+#ifdef __PIC__
+ "popl %%ebx \n\t"
+#endif
+
+ : "=d" (dummy_value_d), // 0 // output regs (dummy)
+ "=S" (dummy_value_S), // 1
+ "=D" (dummy_value_D) // 2
+
+ : "0" (len), // edx // input regs
+ "1" (prev_row), // esi
+ "2" (row) // edi
+
+ : "%eax", "%ebx", "%ecx" // clobber list (no input regs!)
+
+#if 0 /* MMX regs (%mm0, etc.) not supported by gcc 2.7.2.3 or egcs 1.1 */
+ , "%mm0", "%mm1", "%mm2", "%mm3"
+ , "%mm4", "%mm5", "%mm6", "%mm7"
+#endif
+ );
+
+} // end of png_read_filter_row_mmx_up()
+
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
+
+
+
+/*===========================================================================*/
+/* */
+/* P N G _ R E A D _ F I L T E R _ R O W */
+/* */
+/*===========================================================================*/
+
+
+/* Optimized png_read_filter_row routines */
+
+void /* PRIVATE */
+png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
+ row, png_bytep prev_row, int filter)
+{
+#ifdef PNG_DEBUG
+ char filnm[10];
+#endif
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+/* GRR: these are superseded by png_ptr->asm_flags: */
+#define UseMMX_sub 1 // GRR: converted 20000730
+#define UseMMX_up 1 // GRR: converted 20000729
+#define UseMMX_avg 1 // GRR: converted 20000828 (+ 16-bit bugfix 20000916)
+#define UseMMX_paeth 1 // GRR: converted 20000828
+
+ if (_mmx_supported == 2) {
+ /* this should have happened in png_init_mmx_flags() already */
+#if !defined(PNG_1_0_X)
+ png_warning(png_ptr, "asm_flags may not have been initialized");
+#endif
+ png_mmx_support();
+ }
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_DEBUG
+ png_debug(1, "in png_read_filter_row (pnggccrd.c)\n");
+ switch (filter)
+ {
+ case 0: sprintf(filnm, "none");
+ break;
+ case 1: sprintf(filnm, "sub-%s",
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" :
+#endif
+#endif
+"x86");
+ break;
+ case 2: sprintf(filnm, "up-%s",
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+#if !defined(PNG_1_0_X)
+ (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" :
+#endif
+#endif
+ "x86");
+ break;
+ case 3: sprintf(filnm, "avg-%s",
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" :
+#endif
+#endif
+ "x86");
+ break;
+ case 4: sprintf(filnm, "Paeth-%s",
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX":
+#endif
+#endif
+"x86");
+ break;
+ default: sprintf(filnm, "unknw");
+ break;
+ }
+ png_debug2(0, "row_number=%5ld, %5s, ", png_ptr->row_number, filnm);
+ png_debug1(0, "row=0x%08lx, ", (unsigned long)row);
+ png_debug2(0, "pixdepth=%2d, bytes=%d, ", (int)row_info->pixel_depth,
+ (int)((row_info->pixel_depth + 7) >> 3));
+ png_debug1(0,"rowbytes=%8ld\n", row_info->rowbytes);
+#endif /* PNG_DEBUG */
+
+ switch (filter)
+ {
+ case PNG_FILTER_VALUE_NONE:
+ break;
+
+ case PNG_FILTER_VALUE_SUB:
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) &&
+ (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
+ (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
+#else
+ if (_mmx_supported)
+#endif
+ {
+ png_read_filter_row_mmx_sub(row_info, row);
+ }
+ else
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+ {
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_bytep rp = row + bpp;
+ png_bytep lp = row;
+
+ for (i = bpp; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
+ rp++;
+ }
+ } /* end !UseMMX_sub */
+ break;
+
+ case PNG_FILTER_VALUE_UP:
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+#if !defined(PNG_1_0_X)
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) &&
+ (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
+ (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
+#else
+ if (_mmx_supported)
+#endif
+ {
+ png_read_filter_row_mmx_up(row_info, row, prev_row);
+ }
+ else
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+ {
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+
+ for (i = 0; i < istop; ++i)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+ } /* end !UseMMX_up */
+ break;
+
+ case PNG_FILTER_VALUE_AVG:
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) &&
+ (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
+ (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
+#else
+ if (_mmx_supported)
+#endif
+ {
+ png_read_filter_row_mmx_avg(row_info, row, prev_row);
+ }
+ else
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+ {
+ png_uint_32 i;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+ png_bytep lp = row;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_uint_32 istop = row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++) >> 1)) & 0xff);
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++ + *lp++) >> 1)) & 0xff);
+ rp++;
+ }
+ } /* end !UseMMX_avg */
+ break;
+
+ case PNG_FILTER_VALUE_PAETH:
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_THREAD_UNSAFE_OK)
+#if !defined(PNG_1_0_X)
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) &&
+ (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
+ (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
+#else
+ if (_mmx_supported)
+#endif
+ {
+ png_read_filter_row_mmx_paeth(row_info, row, prev_row);
+ }
+ else
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+ {
+ png_uint_32 i;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+ png_bytep lp = row;
+ png_bytep cp = prev_row;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_uint_32 istop = row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++) /* use leftover rp,pp */
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ a = *lp++;
+ b = *pp++;
+ c = *cp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ /*
+ if (pa <= pb && pa <= pc)
+ p = a;
+ else if (pb <= pc)
+ p = b;
+ else
+ p = c;
+ */
+
+ p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
+
+ *rp = (png_byte)(((int)(*rp) + p) & 0xff);
+ rp++;
+ }
+ } /* end !UseMMX_paeth */
+ break;
+
+ default:
+ png_warning(png_ptr, "Ignoring bad row-filter type");
+ *row=0;
+ break;
+ }
+}
+
+#endif /* PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
+
+
+/*===========================================================================*/
+/* */
+/* P N G _ M M X _ S U P P O R T */
+/* */
+/*===========================================================================*/
+
+/* GRR NOTES: (1) the following code assumes 386 or better (pushfl/popfl)
+ * (2) all instructions compile with gcc 2.7.2.3 and later
+ * (3) the function is moved down here to prevent gcc from
+ * inlining it in multiple places and then barfing be-
+ * cause the ".NOT_SUPPORTED" label is multiply defined
+ * [is there a way to signal that a *single* function should
+ * not be inlined? is there a way to modify the label for
+ * each inlined instance, e.g., by appending _1, _2, etc.?
+ * maybe if don't use leading "." in label name? (nope...sigh)]
+ */
+
+int PNGAPI
+png_mmx_support(void)
+{
+#if defined(PNG_MMX_CODE_SUPPORTED)
+ __asm__ __volatile__ (
+ "pushl %%ebx \n\t" // ebx gets clobbered by CPUID instruction
+ "pushl %%ecx \n\t" // so does ecx...
+ "pushl %%edx \n\t" // ...and edx (but ecx & edx safe on Linux)
+// ".byte 0x66 \n\t" // convert 16-bit pushf to 32-bit pushfd
+// "pushf \n\t" // 16-bit pushf
+ "pushfl \n\t" // save Eflag to stack
+ "popl %%eax \n\t" // get Eflag from stack into eax
+ "movl %%eax, %%ecx \n\t" // make another copy of Eflag in ecx
+ "xorl $0x200000, %%eax \n\t" // toggle ID bit in Eflag (i.e., bit 21)
+ "pushl %%eax \n\t" // save modified Eflag back to stack
+// ".byte 0x66 \n\t" // convert 16-bit popf to 32-bit popfd
+// "popf \n\t" // 16-bit popf
+ "popfl \n\t" // restore modified value to Eflag reg
+ "pushfl \n\t" // save Eflag to stack
+ "popl %%eax \n\t" // get Eflag from stack
+ "pushl %%ecx \n\t" // save original Eflag to stack
+ "popfl \n\t" // restore original Eflag
+ "xorl %%ecx, %%eax \n\t" // compare new Eflag with original Eflag
+ "jz 0f \n\t" // if same, CPUID instr. is not supported
+
+ "xorl %%eax, %%eax \n\t" // set eax to zero
+// ".byte 0x0f, 0xa2 \n\t" // CPUID instruction (two-byte opcode)
+ "cpuid \n\t" // get the CPU identification info
+ "cmpl $1, %%eax \n\t" // make sure eax return non-zero value
+ "jl 0f \n\t" // if eax is zero, MMX is not supported
+
+ "xorl %%eax, %%eax \n\t" // set eax to zero and...
+ "incl %%eax \n\t" // ...increment eax to 1. This pair is
+ // faster than the instruction "mov eax, 1"
+ "cpuid \n\t" // get the CPU identification info again
+ "andl $0x800000, %%edx \n\t" // tqmask out all bits but MMX bit (23)
+ "cmpl $0, %%edx \n\t" // 0 = MMX not supported
+ "jz 0f \n\t" // non-zero = yes, MMX IS supported
+
+ "movl $1, %%eax \n\t" // set return value to 1
+ "jmp 1f \n\t" // DONE: have MMX support
+
+ "0: \n\t" // .NOT_SUPPORTED: target label for jump instructions
+ "movl $0, %%eax \n\t" // set return value to 0
+ "1: \n\t" // .RETURN: target label for jump instructions
+ "movl %%eax, _mmx_supported \n\t" // save in global static variable, too
+ "popl %%edx \n\t" // restore edx
+ "popl %%ecx \n\t" // restore ecx
+ "popl %%ebx \n\t" // restore ebx
+
+// "ret \n\t" // DONE: no MMX support
+ // (fall through to standard C "ret")
+
+ : // output list (none)
+
+ : // any variables used on input (none)
+
+ : "%eax" // clobber list
+// , "%ebx", "%ecx", "%edx" // GRR: we handle these manually
+// , "memory" // if write to a variable gcc thought was in a reg
+// , "cc" // "condition codes" (flag bits)
+ );
+#else
+ _mmx_supported = 0;
+#endif /* PNG_MMX_CODE_SUPPORTED */
+
+ return _mmx_supported;
+}
+
+
+#endif /* PNG_USE_PNGGCCRD */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngget.c b/tqtinterface/qt4/src/3rdparty/libpng/pngget.c
new file mode 100644
index 0000000..c1b113c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngget.c
@@ -0,0 +1,927 @@
+
+/* pngget.c - retrieval of values from info struct
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+png_uint_32 PNGAPI
+png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->valid & flag);
+ else
+ return(0);
+}
+
+png_uint_32 PNGAPI
+png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->rowbytes);
+ else
+ return(0);
+}
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+png_bytepp PNGAPI
+png_get_rows(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->row_pointers);
+ else
+ return(0);
+}
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+/* easy access to info, added in libpng-0.99 */
+png_uint_32 PNGAPI
+png_get_image_width(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->width;
+ }
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_image_height(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->height;
+ }
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->bit_depth;
+ }
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_color_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->color_type;
+ }
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->filter_type;
+ }
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->interlace_type;
+ }
+ return (0);
+}
+
+png_byte PNGAPI
+png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ {
+ return info_ptr->compression_type;
+ }
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
+ if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+ return (0);
+ else return (info_ptr->x_pixels_per_unit);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
+ if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
+ return (0);
+ else return (info_ptr->y_pixels_per_unit);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_uint_32 PNGAPI
+png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
+ if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
+ info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
+ return (0);
+ else return (info_ptr->x_pixels_per_unit);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+float PNGAPI
+png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
+ {
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_pHYs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
+ if (info_ptr->x_pixels_per_unit == 0)
+ return ((float)0.0);
+ else
+ return ((float)((float)info_ptr->y_pixels_per_unit
+ /(float)info_ptr->x_pixels_per_unit));
+ }
+#else
+ return (0.0);
+#endif
+ return ((float)0.0);
+}
+#endif
+
+png_int_32 PNGAPI
+png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
+ if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+ return (0);
+ else return (info_ptr->x_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
+ if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
+ return (0);
+ else return (info_ptr->y_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
+ if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+ return (0);
+ else return (info_ptr->x_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+png_int_32 PNGAPI
+png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+#if defined(PNG_oFFs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ {
+ png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
+ if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
+ return (0);
+ else return (info_ptr->y_offset);
+ }
+#else
+ return (0);
+#endif
+ return (0);
+}
+
+#if defined(PNG_INCH_CONVERSIONS) && defined(PNG_FLOATING_POINT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
+ *.0254 +.5));
+}
+
+png_uint_32 PNGAPI
+png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
+ *.0254 +.5));
+}
+
+png_uint_32 PNGAPI
+png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
+ *.0254 +.5));
+}
+
+float PNGAPI
+png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
+ *.00003937);
+}
+
+float PNGAPI
+png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
+{
+ return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
+ *.00003937);
+}
+
+#if defined(PNG_pHYs_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+ png_uint_32 retval = 0;
+
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function\n", "pHYs");
+ if (res_x != NULL)
+ {
+ *res_x = info_ptr->x_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+ if (res_y != NULL)
+ {
+ *res_y = info_ptr->y_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+ if (unit_type != NULL)
+ {
+ *unit_type = (int)info_ptr->phys_unit_type;
+ retval |= PNG_INFO_pHYs;
+ if(*unit_type == 1)
+ {
+ if (res_x != NULL) *res_x = (png_uint_32)(*res_x * .0254 + .50);
+ if (res_y != NULL) *res_y = (png_uint_32)(*res_y * .0254 + .50);
+ }
+ }
+ }
+ return (retval);
+}
+#endif /* PNG_pHYs_SUPPORTED */
+#endif /* PNG_INCH_CONVERSIONS && PNG_FLOATING_POINT_SUPPORTED */
+
+/* png_get_channels really belongs in here, too, but it's been around longer */
+
+#endif /* PNG_EASY_ACCESS_SUPPORTED */
+
+png_byte PNGAPI
+png_get_channels(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->channels);
+ else
+ return (0);
+}
+
+png_bytep PNGAPI
+png_get_signature(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr != NULL && info_ptr != NULL)
+ return(info_ptr->signature);
+ else
+ return (NULL);
+}
+
+#if defined(PNG_bKGD_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
+ png_color_16p *background)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
+ && background != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "bKGD");
+ *background = &(info_ptr->background);
+ return (PNG_INFO_bKGD);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
+ double *white_x, double *white_y, double *red_x, double *red_y,
+ double *green_x, double *green_y, double *blue_x, double *blue_y)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+ {
+ png_debug1(1, "in %s retrieval function\n", "cHRM");
+ if (white_x != NULL)
+ *white_x = (double)info_ptr->x_white;
+ if (white_y != NULL)
+ *white_y = (double)info_ptr->y_white;
+ if (red_x != NULL)
+ *red_x = (double)info_ptr->x_red;
+ if (red_y != NULL)
+ *red_y = (double)info_ptr->y_red;
+ if (green_x != NULL)
+ *green_x = (double)info_ptr->x_green;
+ if (green_y != NULL)
+ *green_y = (double)info_ptr->y_green;
+ if (blue_x != NULL)
+ *blue_x = (double)info_ptr->x_blue;
+ if (blue_y != NULL)
+ *blue_y = (double)info_ptr->y_blue;
+ return (PNG_INFO_cHRM);
+ }
+ return (0);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+ png_fixed_point *white_x, png_fixed_point *white_y, png_fixed_point *red_x,
+ png_fixed_point *red_y, png_fixed_point *green_x, png_fixed_point *green_y,
+ png_fixed_point *blue_x, png_fixed_point *blue_y)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
+ {
+ png_debug1(1, "in %s retrieval function\n", "cHRM");
+ if (white_x != NULL)
+ *white_x = info_ptr->int_x_white;
+ if (white_y != NULL)
+ *white_y = info_ptr->int_y_white;
+ if (red_x != NULL)
+ *red_x = info_ptr->int_x_red;
+ if (red_y != NULL)
+ *red_y = info_ptr->int_y_red;
+ if (green_x != NULL)
+ *green_x = info_ptr->int_x_green;
+ if (green_y != NULL)
+ *green_y = info_ptr->int_y_green;
+ if (blue_x != NULL)
+ *blue_x = info_ptr->int_x_blue;
+ if (blue_y != NULL)
+ *blue_y = info_ptr->int_y_blue;
+ return (PNG_INFO_cHRM);
+ }
+ return (0);
+}
+#endif
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+ && file_gamma != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "gAMA");
+ *file_gamma = (double)info_ptr->gamma;
+ return (PNG_INFO_gAMA);
+ }
+ return (0);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_gAMA_fixed(png_structp png_ptr, png_infop info_ptr,
+ png_fixed_point *int_file_gamma)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+ && int_file_gamma != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "gAMA");
+ *int_file_gamma = info_ptr->int_gamma;
+ return (PNG_INFO_gAMA);
+ }
+ return (0);
+}
+#endif
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
+ && file_srgb_intent != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "sRGB");
+ *file_srgb_intent = (int)info_ptr->srgb_intent;
+ return (PNG_INFO_sRGB);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_iCCP_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_iCCP(png_structp png_ptr, png_infop info_ptr,
+ png_charpp name, int *compression_type,
+ png_charpp profile, png_uint_32 *proflen)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)
+ && name != NULL && profile != NULL && proflen != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "iCCP");
+ *name = info_ptr->iccp_name;
+ *profile = info_ptr->iccp_profile;
+ /* compression_type is a dummy so the API won't have to change
+ if we introduce multiple compression types later. */
+ *proflen = (int)info_ptr->iccp_proflen;
+ *compression_type = (int)info_ptr->iccp_compression;
+ return (PNG_INFO_iCCP);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sPLT(png_structp png_ptr, png_infop info_ptr,
+ png_sPLT_tpp spalettes)
+{
+ if (png_ptr != NULL && info_ptr != NULL && spalettes != NULL)
+ *spalettes = info_ptr->splt_palettes;
+ return ((png_uint_32)info_ptr->splt_palettes_num);
+}
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
+ && hist != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "hIST");
+ *hist = info_ptr->hist;
+ return (PNG_INFO_hIST);
+ }
+ return (0);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *width, png_uint_32 *height, int *bit_depth,
+ int *color_type, int *interlace_type, int *compression_type,
+ int *filter_type)
+
+{
+ if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
+ bit_depth != NULL && color_type != NULL)
+ {
+ int pixel_depth, channels;
+ png_uint_32 rowbytes_per_pixel;
+
+ png_debug1(1, "in %s retrieval function\n", "IHDR");
+ *width = info_ptr->width;
+ *height = info_ptr->height;
+ *bit_depth = info_ptr->bit_depth;
+ if (info_ptr->bit_depth < 1 || info_ptr->bit_depth > 16)
+ png_error(png_ptr, "Invalid bit depth");
+ *color_type = info_ptr->color_type;
+ if (info_ptr->color_type > 6)
+ png_error(png_ptr, "Invalid color type");
+ if (compression_type != NULL)
+ *compression_type = info_ptr->compression_type;
+ if (filter_type != NULL)
+ *filter_type = info_ptr->filter_type;
+ if (interlace_type != NULL)
+ *interlace_type = info_ptr->interlace_type;
+
+ /* check for potential overflow of rowbytes */
+ if (*color_type == PNG_COLOR_TYPE_PALETTE)
+ channels = 1;
+ else if (*color_type & PNG_COLOR_MASK_COLOR)
+ channels = 3;
+ else
+ channels = 1;
+ if (*color_type & PNG_COLOR_MASK_ALPHA)
+ channels++;
+ pixel_depth = *bit_depth * channels;
+ rowbytes_per_pixel = (pixel_depth + 7) >> 3;
+ if (width == 0 || *width > PNG_MAX_UINT)
+ png_error(png_ptr, "Invalid image width");
+ if (height == 0 || *height > PNG_MAX_UINT)
+ png_error(png_ptr, "Invalid image height");
+ if (*width > PNG_MAX_UINT/rowbytes_per_pixel - 64)
+ {
+ png_error(png_ptr,
+ "Width too large for libpng to process image data.");
+ }
+ return (1);
+ }
+ return (0);
+}
+
+#if defined(PNG_oFFs_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
+ png_int_32 *offset_x, png_int_32 *offset_y, int *unit_type)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)
+ && offset_x != NULL && offset_y != NULL && unit_type != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "oFFs");
+ *offset_x = info_ptr->x_offset;
+ *offset_y = info_ptr->y_offset;
+ *unit_type = (int)info_ptr->offset_unit_type;
+ return (PNG_INFO_oFFs);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
+ png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
+ png_charp *units, png_charpp *params)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)
+ && purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
+ nparams != NULL && units != NULL && params != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "pCAL");
+ *purpose = info_ptr->pcal_purpose;
+ *X0 = info_ptr->pcal_X0;
+ *X1 = info_ptr->pcal_X1;
+ *type = (int)info_ptr->pcal_type;
+ *nparams = (int)info_ptr->pcal_nparams;
+ *units = info_ptr->pcal_units;
+ *params = info_ptr->pcal_params;
+ return (PNG_INFO_pCAL);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL(png_structp png_ptr, png_infop info_ptr,
+ int *unit, double *width, double *height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ *unit = info_ptr->scal_unit;
+ *width = info_ptr->scal_pixel_width;
+ *height = info_ptr->scal_pixel_height;
+ return (PNG_INFO_sCAL);
+ }
+ return(0);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+png_uint_32 PNGAPI
+png_get_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+ int *unit, png_charpp width, png_charpp height)
+{
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ *unit = info_ptr->scal_unit;
+ *width = info_ptr->scal_s_width;
+ *height = info_ptr->scal_s_height;
+ return (PNG_INFO_sCAL);
+ }
+ return(0);
+}
+#endif
+#endif
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
+{
+ png_uint_32 retval = 0;
+
+ if (png_ptr != NULL && info_ptr != NULL &&
+ (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_debug1(1, "in %s retrieval function\n", "pHYs");
+ if (res_x != NULL)
+ {
+ *res_x = info_ptr->x_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+ if (res_y != NULL)
+ {
+ *res_y = info_ptr->y_pixels_per_unit;
+ retval |= PNG_INFO_pHYs;
+ }
+ if (unit_type != NULL)
+ {
+ *unit_type = (int)info_ptr->phys_unit_type;
+ retval |= PNG_INFO_pHYs;
+ }
+ }
+ return (retval);
+}
+#endif
+
+png_uint_32 PNGAPI
+png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
+ int *num_palette)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_PLTE)
+ && palette != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "PLTE");
+ *palette = info_ptr->palette;
+ *num_palette = info_ptr->num_palette;
+ png_debug1(3, "num_palette = %d\n", *num_palette);
+ return (PNG_INFO_PLTE);
+ }
+ return (0);
+}
+
+#if defined(PNG_sBIT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)
+ && sig_bit != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "sBIT");
+ *sig_bit = &(info_ptr->sig_bit);
+ return (PNG_INFO_sBIT);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
+ int *num_text)
+{
+ if (png_ptr != NULL && info_ptr != NULL && info_ptr->num_text > 0)
+ {
+ png_debug1(1, "in %s retrieval function\n",
+ (png_ptr->chunk_name[0] == '\0' ? "text"
+ : (png_const_charp)png_ptr->chunk_name));
+ if (text_ptr != NULL)
+ *text_ptr = info_ptr->text;
+ if (num_text != NULL)
+ *num_text = info_ptr->num_text;
+ return ((png_uint_32)info_ptr->num_text);
+ }
+ if (num_text != NULL)
+ *num_text = 0;
+ return(0);
+}
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
+{
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)
+ && mod_time != NULL)
+ {
+ png_debug1(1, "in %s retrieval function\n", "tIME");
+ *mod_time = &(info_ptr->mod_time);
+ return (PNG_INFO_tIME);
+ }
+ return (0);
+}
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
+ png_bytep *trans, int *num_trans, png_color_16p *trans_values)
+{
+ png_uint_32 retval = 0;
+ if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ png_debug1(1, "in %s retrieval function\n", "tRNS");
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (trans != NULL)
+ {
+ *trans = info_ptr->trans;
+ retval |= PNG_INFO_tRNS;
+ }
+ if (trans_values != NULL)
+ *trans_values = &(info_ptr->trans_values);
+ }
+ else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
+ {
+ if (trans_values != NULL)
+ {
+ *trans_values = &(info_ptr->trans_values);
+ retval |= PNG_INFO_tRNS;
+ }
+ if(trans != NULL)
+ *trans = NULL;
+ }
+ if(num_trans != NULL)
+ {
+ *num_trans = info_ptr->num_trans;
+ retval |= PNG_INFO_tRNS;
+ }
+ }
+ return (retval);
+}
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+png_uint_32 PNGAPI
+png_get_unknown_chunks(png_structp png_ptr, png_infop info_ptr,
+ png_unknown_chunkpp unknowns)
+{
+ if (png_ptr != NULL && info_ptr != NULL && unknowns != NULL)
+ *unknowns = info_ptr->unknown_chunks;
+ return ((png_uint_32)info_ptr->unknown_chunks_num);
+}
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+png_byte PNGAPI
+png_get_rgb_to_gray_status (png_structp png_ptr)
+{
+ return (png_byte)(png_ptr? png_ptr->rgb_to_gray_status : 0);
+}
+#endif
+
+#if defined(PNG_USER_CHUNKS_SUPPORTED)
+png_voidp PNGAPI
+png_get_user_chunk_ptr(png_structp png_ptr)
+{
+ return (png_ptr? png_ptr->user_chunk_ptr : NULL);
+}
+#endif
+
+
+png_uint_32 PNGAPI
+png_get_compression_buffer_size(png_structp png_ptr)
+{
+ return (png_uint_32)(png_ptr? png_ptr->zbuf_size : 0L);
+}
+
+
+#ifndef PNG_1_0_X
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+/* this function was added to libpng 1.2.0 and should exist by default */
+png_uint_32 PNGAPI
+png_get_asm_flags (png_structp png_ptr)
+{
+ return (png_uint_32)(png_ptr? png_ptr->asm_flags : 0L);
+}
+
+/* this function was added to libpng 1.2.0 and should exist by default */
+png_uint_32 PNGAPI
+png_get_asm_flagtqmask (int flag_select)
+{
+ png_uint_32 settable_asm_flags = 0;
+
+ if (flag_select & PNG_SELECT_READ)
+ settable_asm_flags |=
+ PNG_ASM_FLAG_MMX_READ_COMBINE_ROW |
+ PNG_ASM_FLAG_MMX_READ_INTERLACE |
+ PNG_ASM_FLAG_MMX_READ_FILTER_SUB |
+ PNG_ASM_FLAG_MMX_READ_FILTER_UP |
+ PNG_ASM_FLAG_MMX_READ_FILTER_AVG |
+ PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+ /* no non-MMX flags yet */
+
+#if 0
+ /* GRR: no write-flags yet, either, but someday... */
+ if (flag_select & PNG_SELECT_WRITE)
+ settable_asm_flags |=
+ PNG_ASM_FLAG_MMX_WRITE_ [whatever] ;
+#endif /* 0 */
+
+ return settable_asm_flags; /* _theoretically_ settable capabilities only */
+}
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED)
+ /* GRR: could add this: && defined(PNG_MMX_CODE_SUPPORTED) */
+/* this function was added to libpng 1.2.0 */
+png_uint_32 PNGAPI
+png_get_mmx_flagtqmask (int flag_select, int *compilerID)
+{
+ png_uint_32 settable_mmx_flags = 0;
+
+ if (flag_select & PNG_SELECT_READ)
+ settable_mmx_flags |=
+ PNG_ASM_FLAG_MMX_READ_COMBINE_ROW |
+ PNG_ASM_FLAG_MMX_READ_INTERLACE |
+ PNG_ASM_FLAG_MMX_READ_FILTER_SUB |
+ PNG_ASM_FLAG_MMX_READ_FILTER_UP |
+ PNG_ASM_FLAG_MMX_READ_FILTER_AVG |
+ PNG_ASM_FLAG_MMX_READ_FILTER_PAETH ;
+#if 0
+ /* GRR: no MMX write support yet, but someday... */
+ if (flag_select & PNG_SELECT_WRITE)
+ settable_mmx_flags |=
+ PNG_ASM_FLAG_MMX_WRITE_ [whatever] ;
+#endif /* 0 */
+
+ if (compilerID != NULL) {
+#ifdef PNG_USE_PNGVCRD
+ *compilerID = 1; /* MSVC */
+#else
+#ifdef PNG_USE_PNGGCCRD
+ *compilerID = 2; /* gcc/gas */
+#else
+ *compilerID = -1; /* unknown (i.e., no asm/MMX code compiled) */
+#endif
+#endif
+ }
+
+ return settable_mmx_flags; /* _theoretically_ settable capabilities only */
+}
+
+/* this function was added to libpng 1.2.0 */
+png_byte PNGAPI
+png_get_mmx_bitdepth_threshold (png_structp png_ptr)
+{
+ return (png_byte)(png_ptr? png_ptr->mmx_bitdepth_threshold : 0);
+}
+
+/* this function was added to libpng 1.2.0 */
+png_uint_32 PNGAPI
+png_get_mmx_rowbytes_threshold (png_structp png_ptr)
+{
+ return (png_uint_32)(png_ptr? png_ptr->mmx_rowbytes_threshold : 0L);
+}
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED */
+#endif /* PNG_1_0_X */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngmem.c b/tqtinterface/qt4/src/3rdparty/libpng/pngmem.c
new file mode 100644
index 0000000..c94a33d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngmem.c
@@ -0,0 +1,566 @@
+
+/* pngmem.c - stub functions for memory allocation
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all memory allocation. Users who
+ * need special memory handling are expected to supply tqreplacement
+ * functions for png_malloc() and png_free(), and to use
+ * png_create_read_struct_2() and png_create_write_struct_2() to
+ * identify the tqreplacement functions.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Borland DOS special memory handler */
+#if defined(__TURBOC__) && !defined(_Windows) && !defined(__FLAT__)
+/* if you change this, be sure to change the one in png.h also */
+
+/* Allocate memory for a png_struct. The malloc and memset can be tqreplaced
+ by a single call to calloc() if this is thought to improve performance. */
+png_voidp /* PRIVATE */
+png_create_struct(int type)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
+}
+
+/* Alternate version of png_create_struct, for use with user-defined malloc. */
+png_voidp /* PRIVATE */
+png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_size_t size;
+ png_voidp struct_ptr;
+
+ if (type == PNG_STRUCT_INFO)
+ size = sizeof(png_info);
+ else if (type == PNG_STRUCT_PNG)
+ size = sizeof(png_struct);
+ else
+ return (png_get_copyright());
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(malloc_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ struct_ptr = (*(malloc_fn))(png_ptr, (png_uint_32)size);
+ }
+ else
+#endif /* PNG_USER_MEM_SUPPORTED */
+ struct_ptr = (png_voidp)farmalloc(size));
+ if (struct_ptr != NULL)
+ png_memset(struct_ptr, 0, size);
+ return (struct_ptr);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct(png_voidp struct_ptr)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
+ png_voidp mem_ptr)
+{
+#endif
+ if (struct_ptr != NULL)
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(free_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ (*(free_fn))(png_ptr, struct_ptr);
+ return;
+ }
+#endif /* PNG_USER_MEM_SUPPORTED */
+ farfree (struct_ptr);
+ }
+}
+
+/* Allocate memory. For reasonable files, size should never exceed
+ * 64K. However, zlib may allocate more then 64K if you don't tell
+ * it not to. See zconf.h and png.h for more information. zlib does
+ * need to allocate exactly 64K, so whatever you call here must
+ * have the ability to do that.
+ *
+ * Borland seems to have a problem in DOS mode for exactly 64K.
+ * It gives you a segment with an offset of 8 (perhaps to store its
+ * memory stuff). zlib doesn't like this at all, so we have to
+ * detect and deal with it. This code should not be needed in
+ * Windows or OS/2 modes, and only in 16 bit mode. This code has
+ * been updated by Alexander Lehmann for version 0.89 to waste less
+ * memory.
+ *
+ * Note that we can't use png_size_t for the "size" declaration,
+ * since on some systems a png_size_t is a 16-bit quantity, and as a
+ * result, we would be truncating potentially larger memory requests
+ * (which should cause a fatal error) and introducing major problems.
+ */
+
+png_voidp PNGAPI
+png_malloc(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+
+ if (png_ptr == NULL || size == 0)
+ return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(png_ptr->malloc_fn != NULL)
+ {
+ ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+ if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of memory!");
+ return (ret);
+ }
+ else
+ return png_malloc_default(png_ptr, size);
+}
+
+png_voidp PNGAPI
+png_malloc_default(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (size > (png_uint_32)65536L)
+ png_error(png_ptr, "Cannot Allocate > 64K");
+#endif
+
+ if (size == (png_uint_32)65536L)
+ {
+ if (png_ptr->offset_table == NULL)
+ {
+ /* try to see if we need to do any of this fancy stuff */
+ ret = farmalloc(size);
+ if (ret == NULL || ((png_size_t)ret & 0xffff))
+ {
+ int num_blocks;
+ png_uint_32 total_size;
+ png_bytep table;
+ int i;
+ png_byte huge * hptr;
+
+ if (ret != NULL)
+ {
+ farfree(ret);
+ ret = NULL;
+ }
+
+ if(png_ptr->zlib_window_bits > 14)
+ num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
+ else
+ num_blocks = 1;
+ if (png_ptr->zlib_mem_level >= 7)
+ num_blocks += (int)(1 << (png_ptr->zlib_mem_level - 7));
+ else
+ num_blocks++;
+
+ total_size = ((png_uint_32)65536L) * (png_uint_32)num_blocks+16;
+
+ table = farmalloc(total_size);
+
+ if (table == NULL)
+ {
+ if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
+ else
+ png_warning(png_ptr, "Out Of Memory.");
+ return (NULL);
+ }
+
+ if ((png_size_t)table & 0xfff0)
+ {
+ if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr,
+ "Farmalloc didn't return normalized pointer");
+ else
+ png_warning(png_ptr,
+ "Farmalloc didn't return normalized pointer");
+ return (NULL);
+ }
+
+ png_ptr->offset_table = table;
+ png_ptr->offset_table_ptr = farmalloc(num_blocks *
+ sizeof (png_bytep));
+
+ if (png_ptr->offset_table_ptr == NULL)
+ {
+ if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out Of memory."); /* Note "O" and "M" */
+ else
+ png_warning(png_ptr, "Out Of memory.");
+ return (NULL);
+ }
+
+ hptr = (png_byte huge *)table;
+ if ((png_size_t)hptr & 0xf)
+ {
+ hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
+ hptr = hptr + 16L; /* "hptr += 16L" fails on Turbo C++ 3.0 */
+ }
+ for (i = 0; i < num_blocks; i++)
+ {
+ png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
+ hptr = hptr + (png_uint_32)65536L; /* "+=" fails on TC++3.0 */
+ }
+
+ png_ptr->offset_table_number = num_blocks;
+ png_ptr->offset_table_count = 0;
+ png_ptr->offset_table_count_free = 0;
+ }
+ }
+
+ if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
+ {
+ if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of Memory."); /* Note "o" and "M" */
+ else
+ png_warning(png_ptr, "Out of Memory.");
+ return (NULL);
+ }
+
+ ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
+ }
+ else
+ ret = farmalloc(size);
+
+ if (ret == NULL)
+ {
+ if (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
+ else
+ png_warning(png_ptr, "Out of memory."); /* Note "o" and "m" */
+ }
+
+ return (ret);
+}
+
+/* free a pointer allocated by png_malloc(). In the default
+ configuration, png_ptr is not used, but is passed in case it
+ is needed. If ptr is NULL, return without taking any action. */
+void PNGAPI
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr->free_fn != NULL)
+ {
+ (*(png_ptr->free_fn))(png_ptr, ptr);
+ return;
+ }
+ else png_free_default(png_ptr, ptr);
+}
+
+void PNGAPI
+png_free_default(png_structp png_ptr, png_voidp ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ if (png_ptr->offset_table != NULL)
+ {
+ int i;
+
+ for (i = 0; i < png_ptr->offset_table_count; i++)
+ {
+ if (ptr == png_ptr->offset_table_ptr[i])
+ {
+ ptr = NULL;
+ png_ptr->offset_table_count_free++;
+ break;
+ }
+ }
+ if (png_ptr->offset_table_count_free == png_ptr->offset_table_count)
+ {
+ farfree(png_ptr->offset_table);
+ farfree(png_ptr->offset_table_ptr);
+ png_ptr->offset_table = NULL;
+ png_ptr->offset_table_ptr = NULL;
+ }
+ }
+
+ if (ptr != NULL)
+ {
+ farfree(ptr);
+ }
+}
+
+#else /* Not the Borland DOS special memory handler */
+
+/* Allocate memory for a png_struct or a png_info. The malloc and
+ memset can be tqreplaced by a single call to calloc() if this is thought
+ to improve performance noticably. */
+png_voidp /* PRIVATE */
+png_create_struct(int type)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_struct_2(type, png_malloc_ptr_NULL, png_voidp_NULL));
+}
+
+/* Allocate memory for a png_struct or a png_info. The malloc and
+ memset can be tqreplaced by a single call to calloc() if this is thought
+ to improve performance noticably. */
+png_voidp /* PRIVATE */
+png_create_struct_2(int type, png_malloc_ptr malloc_fn, png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_size_t size;
+ png_voidp struct_ptr;
+
+ if (type == PNG_STRUCT_INFO)
+ size = sizeof(png_info);
+ else if (type == PNG_STRUCT_PNG)
+ size = sizeof(png_struct);
+ else
+ return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(malloc_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ struct_ptr = (*(malloc_fn))(png_ptr, size);
+ if (struct_ptr != NULL)
+ png_memset(struct_ptr, 0, size);
+ return (struct_ptr);
+ }
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ if ((struct_ptr = (png_voidp)halloc(size,1)) != NULL)
+# else
+ if ((struct_ptr = (png_voidp)malloc(size)) != NULL)
+# endif
+#endif
+ {
+ png_memset(struct_ptr, 0, size);
+ }
+
+ return (struct_ptr);
+}
+
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct(png_voidp struct_ptr)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2(struct_ptr, png_free_ptr_NULL, png_voidp_NULL);
+}
+
+/* Free memory allocated by a png_create_struct() call */
+void /* PRIVATE */
+png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn,
+ png_voidp mem_ptr)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ if (struct_ptr != NULL)
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(free_fn != NULL)
+ {
+ png_struct dummy_struct;
+ png_structp png_ptr = &dummy_struct;
+ png_ptr->mem_ptr=mem_ptr;
+ (*(free_fn))(png_ptr, struct_ptr);
+ return;
+ }
+#endif /* PNG_USER_MEM_SUPPORTED */
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ farfree(struct_ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ hfree(struct_ptr);
+# else
+ free(struct_ptr);
+# endif
+#endif
+ }
+}
+
+/* Allocate memory. For reasonable files, size should never exceed
+ 64K. However, zlib may allocate more then 64K if you don't tell
+ it not to. See zconf.h and png.h for more information. zlib does
+ need to allocate exactly 64K, so whatever you call here must
+ have the ability to do that. */
+
+png_voidp PNGAPI
+png_malloc(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+
+ if (png_ptr == NULL || size == 0)
+ return (NULL);
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if(png_ptr->malloc_fn != NULL)
+ {
+ ret = ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, (png_size_t)size));
+ if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of Memory!");
+ return (ret);
+ }
+ else
+ return (png_malloc_default(png_ptr, size));
+}
+
+png_voidp PNGAPI
+png_malloc_default(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ret;
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (size > (png_uint_32)65536L)
+ {
+ if(png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Cannot Allocate > 64K");
+ else
+ return NULL;
+ }
+#endif
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ ret = farmalloc(size);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ ret = halloc(size, 1);
+# else
+ ret = malloc((size_t)size);
+# endif
+#endif
+
+ if (ret == NULL && (png_ptr->flags&PNG_FLAG_MALLOC_NULL_MEM_OK) == 0)
+ png_error(png_ptr, "Out of Memory");
+
+ return (ret);
+}
+
+/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
+ without taking any action. */
+void PNGAPI
+png_free(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (png_ptr->free_fn != NULL)
+ {
+ (*(png_ptr->free_fn))(png_ptr, ptr);
+ return;
+ }
+ else png_free_default(png_ptr, ptr);
+}
+void PNGAPI
+png_free_default(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL || ptr == NULL)
+ return;
+
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+#if defined(__TURBOC__) && !defined(__FLAT__)
+ farfree(ptr);
+#else
+# if defined(_MSC_VER) && defined(MAXSEG_64K)
+ hfree(ptr);
+# else
+ free(ptr);
+# endif
+#endif
+}
+
+#endif /* Not Borland DOS special memory handler */
+
+#if defined(PNG_1_0_X)
+# define png_malloc_warn png_malloc
+#else
+/* This function was added at libpng version 1.2.3. The png_malloc_warn()
+ * function will issue a png_warning and return NULL instead of issuing a
+ * png_error, if it fails to allocate the requested memory.
+ */
+png_voidp PNGAPI
+png_malloc_warn(png_structp png_ptr, png_uint_32 size)
+{
+ png_voidp ptr;
+ png_uint_32 save_flags=png_ptr->flags;
+
+ png_ptr->flags|=PNG_FLAG_MALLOC_NULL_MEM_OK;
+ ptr = (png_voidp)png_malloc((png_structp)png_ptr, size);
+ png_ptr->flags=save_flags;
+ return(ptr);
+}
+#endif
+
+png_voidp PNGAPI
+png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
+ png_uint_32 length)
+{
+ png_size_t size;
+
+ size = (png_size_t)length;
+ if ((png_uint_32)size != length)
+ png_error(png_ptr,"Overflow in png_memcpy_check.");
+
+ return(png_memcpy (s1, s2, size));
+}
+
+png_voidp PNGAPI
+png_memset_check (png_structp png_ptr, png_voidp s1, int value,
+ png_uint_32 length)
+{
+ png_size_t size;
+
+ size = (png_size_t)length;
+ if ((png_uint_32)size != length)
+ png_error(png_ptr,"Overflow in png_memset_check.");
+
+ return (png_memset (s1, value, size));
+
+}
+
+#ifdef PNG_USER_MEM_SUPPORTED
+/* This function is called when the application wants to use another method
+ * of allocating and freeing memory.
+ */
+void PNGAPI
+png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
+ malloc_fn, png_free_ptr free_fn)
+{
+ png_ptr->mem_ptr = mem_ptr;
+ png_ptr->malloc_fn = malloc_fn;
+ png_ptr->free_fn = free_fn;
+}
+
+/* This function returns a pointer to the mem_ptr associated with the user
+ * functions. The application should free any memory associated with this
+ * pointer before png_write_destroy and png_read_destroy are called.
+ */
+png_voidp PNGAPI
+png_get_mem_ptr(png_structp png_ptr)
+{
+ return ((png_voidp)png_ptr->mem_ptr);
+}
+#endif /* PNG_USER_MEM_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngnow.png b/tqtinterface/qt4/src/3rdparty/libpng/pngnow.png
new file mode 100644
index 0000000..b089121
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngnow.png
Binary files differ
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngpread.c b/tqtinterface/qt4/src/3rdparty/libpng/pngpread.c
new file mode 100644
index 0000000..36701f6
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngpread.c
@@ -0,0 +1,1547 @@
+
+/* pngpread.c - read a png file in push mode
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+
+/* push model modes */
+#define PNG_READ_SIG_MODE 0
+#define PNG_READ_CHUNK_MODE 1
+#define PNG_READ_IDAT_MODE 2
+#define PNG_SKIP_MODE 3
+#define PNG_READ_tEXt_MODE 4
+#define PNG_READ_zTXt_MODE 5
+#define PNG_READ_DONE_MODE 6
+#define PNG_READ_iTXt_MODE 7
+#define PNG_ERROR_MODE 8
+
+void PNGAPI
+png_process_data(png_structp png_ptr, png_infop info_ptr,
+ png_bytep buffer, png_size_t buffer_size)
+{
+ png_push_restore_buffer(png_ptr, buffer, buffer_size);
+
+ while (png_ptr->buffer_size)
+ {
+ png_process_some_data(png_ptr, info_ptr);
+ }
+}
+
+/* What we do with the incoming data depends on what we were previously
+ * doing before we ran out of data...
+ */
+void /* PRIVATE */
+png_process_some_data(png_structp png_ptr, png_infop info_ptr)
+{
+ switch (png_ptr->process_mode)
+ {
+ case PNG_READ_SIG_MODE:
+ {
+ png_push_read_sig(png_ptr, info_ptr);
+ break;
+ }
+ case PNG_READ_CHUNK_MODE:
+ {
+ png_push_read_chunk(png_ptr, info_ptr);
+ break;
+ }
+ case PNG_READ_IDAT_MODE:
+ {
+ png_push_read_IDAT(png_ptr);
+ break;
+ }
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ case PNG_READ_tEXt_MODE:
+ {
+ png_push_read_tEXt(png_ptr, info_ptr);
+ break;
+ }
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ case PNG_READ_zTXt_MODE:
+ {
+ png_push_read_zTXt(png_ptr, info_ptr);
+ break;
+ }
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ case PNG_READ_iTXt_MODE:
+ {
+ png_push_read_iTXt(png_ptr, info_ptr);
+ break;
+ }
+#endif
+ case PNG_SKIP_MODE:
+ {
+ png_push_crc_finish(png_ptr);
+ break;
+ }
+ default:
+ {
+ png_ptr->buffer_size = 0;
+ break;
+ }
+ }
+}
+
+/* Read any remaining signature bytes from the stream and compare them with
+ * the correct PNG signature. It is possible that this routine is called
+ * with bytes already read from the signature, either because they have been
+ * checked by the calling application, or because of multiple calls to this
+ * routine.
+ */
+void /* PRIVATE */
+png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
+{
+ png_size_t num_checked = png_ptr->sig_bytes,
+ num_to_check = 8 - num_checked;
+
+ if (png_ptr->buffer_size < num_to_check)
+ {
+ num_to_check = png_ptr->buffer_size;
+ }
+
+ png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
+ num_to_check);
+ png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes+num_to_check);
+
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+ {
+ if (num_checked < 4 &&
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_error(png_ptr, "Not a PNG file");
+ else
+ png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+ }
+ else
+ {
+ if (png_ptr->sig_bytes >= 8)
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+ }
+}
+
+void /* PRIVATE */
+png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IHDR;
+ PNG_IDAT;
+ PNG_IEND;
+ PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ PNG_sCAL;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ PNG_sRGB;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ PNG_sPLT;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ PNG_zTXt;
+#endif
+#endif /* PNG_USE_LOCAL_ARRAYS */
+ /* First we make sure we have enough data for the 4 byte chunk name
+ * and the 4 byte chunk length before proceeding with decoding the
+ * chunk data. To fully decode each of these chunks, we also make
+ * sure we have enough data in the buffer for the 4 byte CRC at the
+ * end of every chunk (except IDAT, which is handled separately).
+ */
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+ {
+ png_byte chunk_length[4];
+
+ if (png_ptr->buffer_size < 8)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+ }
+
+ if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length);
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length);
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+ {
+ /* If we reach an IDAT chunk, this means we have read all of the
+ * header chunks, and we can start reading the image (or if this
+ * is called after the image has been read - we have an error).
+ */
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ if (png_ptr->push_length == 0)
+ return;
+
+ if (png_ptr->mode & PNG_AFTER_IDAT)
+ png_error(png_ptr, "Too many IDAT's found");
+ }
+
+ png_ptr->idat_size = png_ptr->push_length;
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ png_ptr->process_mode = PNG_READ_IDAT_MODE;
+ png_push_have_info(png_ptr, info_ptr);
+ png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ return;
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length);
+
+ png_ptr->process_mode = PNG_READ_DONE_MODE;
+ png_push_have_end(png_ptr, info_ptr);
+ }
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length);
+ }
+#endif
+ else
+ {
+ if (png_ptr->push_length + 4 > png_ptr->buffer_size)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+ png_push_handle_unknown(png_ptr, info_ptr, png_ptr->push_length);
+ }
+
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+}
+
+void /* PRIVATE */
+png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
+{
+ png_ptr->process_mode = PNG_SKIP_MODE;
+ png_ptr->skip_length = skip;
+}
+
+void /* PRIVATE */
+png_push_crc_finish(png_structp png_ptr)
+{
+ if (png_ptr->skip_length && png_ptr->save_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
+ save_size = (png_size_t)png_ptr->skip_length;
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+
+ png_ptr->skip_length -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (png_ptr->skip_length && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
+ save_size = (png_size_t)png_ptr->skip_length;
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_ptr->skip_length -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+ if (!png_ptr->skip_length)
+ {
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_crc_finish(png_ptr, 0);
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ }
+}
+
+void PNGAPI
+png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
+{
+ png_bytep ptr;
+
+ ptr = buffer;
+ if (png_ptr->save_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (length < png_ptr->save_buffer_size)
+ save_size = length;
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
+ length -= save_size;
+ ptr += save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (length && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (length < png_ptr->current_buffer_size)
+ save_size = length;
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+}
+
+void /* PRIVATE */
+png_push_save_buffer(png_structp png_ptr)
+{
+ if (png_ptr->save_buffer_size)
+ {
+ if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
+ {
+ png_size_t i,istop;
+ png_bytep sp;
+ png_bytep dp;
+
+ istop = png_ptr->save_buffer_size;
+ for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
+ i < istop; i++, sp++, dp++)
+ {
+ *dp = *sp;
+ }
+ }
+ }
+ if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
+ png_ptr->save_buffer_max)
+ {
+ png_size_t new_max;
+ png_bytep old_buffer;
+
+ if (png_ptr->save_buffer_size > PNG_SIZE_MAX -
+ (png_ptr->current_buffer_size + 256))
+ {
+ png_error(png_ptr, "Potential overflow of save_buffer");
+ }
+ new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
+ old_buffer = png_ptr->save_buffer;
+ png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)new_max);
+ png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
+ png_free(png_ptr, old_buffer);
+ png_ptr->save_buffer_max = new_max;
+ }
+ if (png_ptr->current_buffer_size)
+ {
+ png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
+ png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
+ png_ptr->save_buffer_size += png_ptr->current_buffer_size;
+ png_ptr->current_buffer_size = 0;
+ }
+ png_ptr->save_buffer_ptr = png_ptr->save_buffer;
+ png_ptr->buffer_size = 0;
+}
+
+void /* PRIVATE */
+png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
+ png_size_t buffer_length)
+{
+ png_ptr->current_buffer = buffer;
+ png_ptr->current_buffer_size = buffer_length;
+ png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size;
+ png_ptr->current_buffer_ptr = png_ptr->current_buffer;
+}
+
+void /* PRIVATE */
+png_push_read_IDAT(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IDAT;
+#endif
+ if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER))
+ {
+ png_byte chunk_length[4];
+
+ if (png_ptr->buffer_size < 8)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_fill_buffer(png_ptr, chunk_length, 4);
+ png_ptr->push_length = png_get_uint_31(png_ptr,chunk_length);
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER;
+
+ if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+ {
+ png_ptr->process_mode = PNG_READ_CHUNK_MODE;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ png_error(png_ptr, "Not enough compressed data");
+ return;
+ }
+
+ png_ptr->idat_size = png_ptr->push_length;
+ }
+ if (png_ptr->idat_size && png_ptr->save_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
+ {
+ save_size = (png_size_t)png_ptr->idat_size;
+ /* check for overflow */
+ if((png_uint_32)save_size != png_ptr->idat_size)
+ png_error(png_ptr, "save_size overflowed in pngpread");
+ }
+ else
+ save_size = png_ptr->save_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
+ png_ptr->idat_size -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->save_buffer_size -= save_size;
+ png_ptr->save_buffer_ptr += save_size;
+ }
+ if (png_ptr->idat_size && png_ptr->current_buffer_size)
+ {
+ png_size_t save_size;
+
+ if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
+ {
+ save_size = (png_size_t)png_ptr->idat_size;
+ /* check for overflow */
+ if((png_uint_32)save_size != png_ptr->idat_size)
+ png_error(png_ptr, "save_size overflowed in pngpread");
+ }
+ else
+ save_size = png_ptr->current_buffer_size;
+
+ png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
+
+ png_ptr->idat_size -= save_size;
+ png_ptr->buffer_size -= save_size;
+ png_ptr->current_buffer_size -= save_size;
+ png_ptr->current_buffer_ptr += save_size;
+ }
+ if (!png_ptr->idat_size)
+ {
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_crc_finish(png_ptr, 0);
+ png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ }
+}
+
+void /* PRIVATE */
+png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
+ png_size_t buffer_length)
+{
+ int ret;
+
+ if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
+ png_error(png_ptr, "Extra compression data");
+
+ png_ptr->zstream.next_in = buffer;
+ png_ptr->zstream.avail_in = (uInt)buffer_length;
+ for(;;)
+ {
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret != Z_OK)
+ {
+ if (ret == Z_STREAM_END)
+ {
+ if (png_ptr->zstream.avail_in)
+ png_error(png_ptr, "Extra compressed data");
+ if (!(png_ptr->zstream.avail_out))
+ {
+ png_push_process_row(png_ptr);
+ }
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+ else if (ret == Z_BUF_ERROR)
+ break;
+ else
+ png_error(png_ptr, "Decompression Error");
+ }
+ if (!(png_ptr->zstream.avail_out))
+ {
+ if ((
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+ png_ptr->interlaced && png_ptr->pass > 6) ||
+ (!png_ptr->interlaced &&
+#endif
+ png_ptr->row_number == png_ptr->num_rows-1))
+ {
+ if (png_ptr->zstream.avail_in)
+ png_warning(png_ptr, "Too much data in IDAT chunks");
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+ png_push_process_row(png_ptr);
+ png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ }
+ else
+ break;
+ }
+}
+
+void /* PRIVATE */
+png_push_process_row(png_structp png_ptr)
+{
+ png_ptr->row_info.color_type = png_ptr->color_type;
+ png_ptr->row_info.width = png_ptr->iwidth;
+ png_ptr->row_info.channels = png_ptr->channels;
+ png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+ png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+
+ png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
+ (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
+
+ png_read_filter_row(png_ptr, &(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+ (int)(png_ptr->row_buf[0]));
+
+ png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+ png_ptr->rowbytes + 1);
+
+ if (png_ptr->transformations)
+ png_do_read_transformations(png_ptr);
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+ /* blow up interlaced rows to full size */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ if (png_ptr->pass < 6)
+/* old interface (pre-1.0.9):
+ png_do_read_interlace(&(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+ png_do_read_interlace(png_ptr);
+
+ switch (png_ptr->pass)
+ {
+ case 0:
+ {
+ int i;
+ for (i = 0; i < 8 && png_ptr->pass == 0; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr); /* updates png_ptr->pass */
+ }
+ if (png_ptr->pass == 2) /* pass 1 might be empty */
+ {
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ if (png_ptr->pass == 4 && png_ptr->height <= 4)
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ if (png_ptr->pass == 6 && png_ptr->height <= 4)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ break;
+ }
+ case 1:
+ {
+ int i;
+ for (i = 0; i < 8 && png_ptr->pass == 1; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+ if (png_ptr->pass == 2) /* skip top 4 generated rows */
+ {
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ break;
+ }
+ case 2:
+ {
+ int i;
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+ for (i = 0; i < 4 && png_ptr->pass == 2; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ if (png_ptr->pass == 4) /* pass 3 might be empty */
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ break;
+ }
+ case 3:
+ {
+ int i;
+ for (i = 0; i < 4 && png_ptr->pass == 3; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+ if (png_ptr->pass == 4) /* skip top two generated rows */
+ {
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ break;
+ }
+ case 4:
+ {
+ int i;
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+ for (i = 0; i < 2 && png_ptr->pass == 4; i++)
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ if (png_ptr->pass == 6) /* pass 5 might be empty */
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ break;
+ }
+ case 5:
+ {
+ int i;
+ for (i = 0; i < 2 && png_ptr->pass == 5; i++)
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+ if (png_ptr->pass == 6) /* skip top generated row */
+ {
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ break;
+ }
+ case 6:
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ if (png_ptr->pass != 6)
+ break;
+ png_push_have_row(png_ptr, png_bytep_NULL);
+ png_read_push_finish_row(png_ptr);
+ }
+ }
+ }
+ else
+#endif
+ {
+ png_push_have_row(png_ptr, png_ptr->row_buf + 1);
+ png_read_push_finish_row(png_ptr);
+ }
+}
+
+void /* PRIVATE */
+png_read_push_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ const int FARDATA png_pass_start[] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ const int FARDATA png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ const int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ const int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
+
+ /* Width of interlace block. This is not currently used - if you need
+ * it, uncomment it here and in png.h
+ const int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
+ */
+
+ /* Height of interlace block. This is not currently used - if you need
+ * it, uncomment it here and in png.h
+ const int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
+ */
+#endif
+
+ png_ptr->row_number++;
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ png_memset_check(png_ptr, png_ptr->prev_row, 0,
+ png_ptr->rowbytes + 1);
+ do
+ {
+ png_ptr->pass++;
+ if ((png_ptr->pass == 1 && png_ptr->width < 5) ||
+ (png_ptr->pass == 3 && png_ptr->width < 3) ||
+ (png_ptr->pass == 5 && png_ptr->width < 2))
+ png_ptr->pass++;
+
+ if (png_ptr->pass > 7)
+ png_ptr->pass--;
+ if (png_ptr->pass >= 7)
+ break;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ png_ptr->irowbytes = ((png_ptr->iwidth *
+ png_ptr->pixel_depth + 7) >> 3) + 1;
+
+ if (png_ptr->transformations & PNG_INTERLACE)
+ break;
+
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+
+ } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0);
+ }
+}
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+void /* PRIVATE */
+png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+ {
+ png_error(png_ptr, "Out of place tEXt");
+ /* to quiet some compiler warnings */
+ if(info_ptr == NULL) return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ png_ptr->skip_length = 0; /* This may not be necessary */
+
+ if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
+ {
+ png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+ png_ptr->skip_length = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(length+1));
+ png_ptr->current_text[length] = '\0';
+ png_ptr->current_text_ptr = png_ptr->current_text;
+ png_ptr->current_text_size = (png_size_t)length;
+ png_ptr->current_text_left = (png_size_t)length;
+ png_ptr->process_mode = PNG_READ_tEXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->buffer_size && png_ptr->current_text_left)
+ {
+ png_size_t text_size;
+
+ if (png_ptr->buffer_size < png_ptr->current_text_left)
+ text_size = png_ptr->buffer_size;
+ else
+ text_size = png_ptr->current_text_left;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+ png_ptr->current_text_left -= text_size;
+ png_ptr->current_text_ptr += text_size;
+ }
+ if (!(png_ptr->current_text_left))
+ {
+ png_textp text_ptr;
+ png_charp text;
+ png_charp key;
+ int ret;
+
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_crc_finish(png_ptr);
+
+#if defined(PNG_MAX_MALLOC_64K)
+ if (png_ptr->skip_length)
+ return;
+#endif
+
+ key = png_ptr->current_text;
+
+ for (text = key; *text; text++)
+ /* empty loop */ ;
+
+ if (text != key + png_ptr->current_text_size)
+ text++;
+
+ text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+ text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+ text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+#endif
+ text_ptr->text = text;
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, key);
+ png_free(png_ptr, text_ptr);
+ png_ptr->current_text = NULL;
+
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to store text chunk.");
+ }
+}
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+void /* PRIVATE */
+png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+ {
+ png_error(png_ptr, "Out of place zTXt");
+ /* to quiet some compiler warnings */
+ if(info_ptr == NULL) return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ /* We can't handle zTXt chunks > 64K, since we don't have enough space
+ * to be able to store the uncompressed data. Actually, the threshold
+ * is probably around 32K, but it isn't as definite as 64K is.
+ */
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "zTXt chunk too large to fit in memory");
+ png_push_crc_skip(png_ptr, length);
+ return;
+ }
+#endif
+
+ png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(length+1));
+ png_ptr->current_text[length] = '\0';
+ png_ptr->current_text_ptr = png_ptr->current_text;
+ png_ptr->current_text_size = (png_size_t)length;
+ png_ptr->current_text_left = (png_size_t)length;
+ png_ptr->process_mode = PNG_READ_zTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->buffer_size && png_ptr->current_text_left)
+ {
+ png_size_t text_size;
+
+ if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
+ text_size = png_ptr->buffer_size;
+ else
+ text_size = png_ptr->current_text_left;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+ png_ptr->current_text_left -= text_size;
+ png_ptr->current_text_ptr += text_size;
+ }
+ if (!(png_ptr->current_text_left))
+ {
+ png_textp text_ptr;
+ png_charp text;
+ png_charp key;
+ int ret;
+ png_size_t text_size, key_size;
+
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_crc_finish(png_ptr);
+
+ key = png_ptr->current_text;
+
+ for (text = key; *text; text++)
+ /* empty loop */ ;
+
+ /* zTXt can't have zero text */
+ if (text == key + png_ptr->current_text_size)
+ {
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ return;
+ }
+
+ text++;
+
+ if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
+ {
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ return;
+ }
+
+ text++;
+
+ png_ptr->zstream.next_in = (png_bytep )text;
+ png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
+ (text - key));
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ key_size = text - key;
+ text_size = 0;
+ text = NULL;
+ ret = Z_STREAM_END;
+
+ while (png_ptr->zstream.avail_in)
+ {
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ {
+ inflateReset(&png_ptr->zstream);
+ png_ptr->zstream.avail_in = 0;
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ png_free(png_ptr, text);
+ return;
+ }
+ if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
+ {
+ if (text == NULL)
+ {
+ text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
+ + key_size + 1));
+ png_memcpy(text + key_size, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+ png_memcpy(text, key, key_size);
+ text_size = key_size + png_ptr->zbuf_size -
+ png_ptr->zstream.avail_out;
+ *(text + text_size) = '\0';
+ }
+ else
+ {
+ png_charp tmp;
+
+ tmp = text;
+ text = (png_charp)png_malloc(png_ptr, text_size +
+ (png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
+ + 1));
+ png_memcpy(text, tmp, text_size);
+ png_free(png_ptr, tmp);
+ png_memcpy(text + text_size, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+ text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+ *(text + text_size) = '\0';
+ }
+ if (ret != Z_STREAM_END)
+ {
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ if (ret == Z_STREAM_END)
+ break;
+ }
+
+ inflateReset(&png_ptr->zstream);
+ png_ptr->zstream.avail_in = 0;
+
+ if (ret != Z_STREAM_END)
+ {
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ png_free(png_ptr, text);
+ return;
+ }
+
+ png_ptr->current_text = NULL;
+ png_free(png_ptr, key);
+ key = text;
+ text += key_size;
+
+ text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+ text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
+ text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+#endif
+ text_ptr->text = text;
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, key);
+ png_free(png_ptr, text_ptr);
+
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to store text chunk.");
+ }
+}
+#endif
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+void /* PRIVATE */
+png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND))
+ {
+ png_error(png_ptr, "Out of place iTXt");
+ /* to quiet some compiler warnings */
+ if(info_ptr == NULL) return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ png_ptr->skip_length = 0; /* This may not be necessary */
+
+ if (length > (png_uint_32)65535L) /* Can't hold entire string in memory */
+ {
+ png_warning(png_ptr, "iTXt chunk too large to fit in memory");
+ png_ptr->skip_length = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ png_ptr->current_text = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)(length+1));
+ png_ptr->current_text[length] = '\0';
+ png_ptr->current_text_ptr = png_ptr->current_text;
+ png_ptr->current_text_size = (png_size_t)length;
+ png_ptr->current_text_left = (png_size_t)length;
+ png_ptr->process_mode = PNG_READ_iTXt_MODE;
+}
+
+void /* PRIVATE */
+png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr)
+{
+
+ if (png_ptr->buffer_size && png_ptr->current_text_left)
+ {
+ png_size_t text_size;
+
+ if (png_ptr->buffer_size < png_ptr->current_text_left)
+ text_size = png_ptr->buffer_size;
+ else
+ text_size = png_ptr->current_text_left;
+ png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
+ png_ptr->current_text_left -= text_size;
+ png_ptr->current_text_ptr += text_size;
+ }
+ if (!(png_ptr->current_text_left))
+ {
+ png_textp text_ptr;
+ png_charp key;
+ int comp_flag;
+ png_charp lang;
+ png_charp lang_key;
+ png_charp text;
+ int ret;
+
+ if (png_ptr->buffer_size < 4)
+ {
+ png_push_save_buffer(png_ptr);
+ return;
+ }
+
+ png_push_crc_finish(png_ptr);
+
+#if defined(PNG_MAX_MALLOC_64K)
+ if (png_ptr->skip_length)
+ return;
+#endif
+
+ key = png_ptr->current_text;
+
+ for (lang = key; *lang; lang++)
+ /* empty loop */ ;
+
+ if (lang != key + png_ptr->current_text_size)
+ lang++;
+
+ comp_flag = *lang++;
+ lang++; /* skip comp_type, always zero */
+
+ for (lang_key = lang; *lang_key; lang_key++)
+ /* empty loop */ ;
+ lang_key++; /* skip NUL separator */
+
+ for (text = lang_key; *text; text++)
+ /* empty loop */ ;
+
+ if (text != key + png_ptr->current_text_size)
+ text++;
+
+ text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
+ text_ptr->compression = comp_flag + 2;
+ text_ptr->key = key;
+ text_ptr->lang = lang;
+ text_ptr->lang_key = lang_key;
+ text_ptr->text = text;
+ text_ptr->text_length = 0;
+ text_ptr->itxt_length = png_strlen(text);
+
+ ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_ptr->current_text = NULL;
+
+ png_free(png_ptr, text_ptr);
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to store iTXt chunk.");
+ }
+}
+#endif
+
+/* This function is called when we haven't found a handler for this
+ * chunk. If there isn't a problem with the chunk itself (ie a bad chunk
+ * name or a critical chunk), the chunk is (currently) silently ignored.
+ */
+void /* PRIVATE */
+png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32
+ length)
+{
+ png_uint_32 skip=0;
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ {
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ HANDLE_CHUNK_ALWAYS
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+ && png_ptr->read_user_chunk_fn == NULL
+#endif
+ )
+#endif
+ png_chunk_error(png_ptr, "unknown critical chunk");
+
+ /* to quiet compiler warnings about unused info_ptr */
+ if (info_ptr == NULL)
+ return;
+ }
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+ {
+ png_unknown_chunk chunk;
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "unknown chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
+ chunk.data = (png_bytep)png_malloc(png_ptr, length);
+ png_crc_read(png_ptr, chunk.data, length);
+ chunk.size = length;
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+ if(png_ptr->read_user_chunk_fn != NULL)
+ {
+ /* callback to user unknown chunk handler */
+ if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
+ {
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ HANDLE_CHUNK_ALWAYS)
+ png_chunk_error(png_ptr, "unknown critical chunk");
+ }
+ png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+ }
+ else
+#endif
+ png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+ png_free(png_ptr, chunk.data);
+ }
+ else
+#endif
+ skip=length;
+ png_push_crc_skip(png_ptr, skip);
+}
+
+void /* PRIVATE */
+png_push_have_info(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->info_fn != NULL)
+ (*(png_ptr->info_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_end(png_structp png_ptr, png_infop info_ptr)
+{
+ if (png_ptr->end_fn != NULL)
+ (*(png_ptr->end_fn))(png_ptr, info_ptr);
+}
+
+void /* PRIVATE */
+png_push_have_row(png_structp png_ptr, png_bytep row)
+{
+ if (png_ptr->row_fn != NULL)
+ (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
+ (int)png_ptr->pass);
+}
+
+void PNGAPI
+png_progressive_combine_row (png_structp png_ptr,
+ png_bytep old_row, png_bytep new_row)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ const int FARDATA png_pass_dsp_mask[7] =
+ {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+#endif
+ if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
+ png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
+}
+
+void PNGAPI
+png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
+ png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn,
+ png_progressive_end_ptr end_fn)
+{
+ png_ptr->info_fn = info_fn;
+ png_ptr->row_fn = row_fn;
+ png_ptr->end_fn = end_fn;
+
+ png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
+}
+
+png_voidp PNGAPI
+png_get_progressive_ptr(png_structp png_ptr)
+{
+ return png_ptr->io_ptr;
+}
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngread.c b/tqtinterface/qt4/src/3rdparty/libpng/pngread.c
new file mode 100644
index 0000000..306cda3
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngread.c
@@ -0,0 +1,1418 @@
+
+/* pngread.c - read a PNG file
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file tqcontains routines that an application calls directly to
+ * read a PNG file or stream.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Create a PNG structure for reading, and allocate any memory needed. */
+png_structp PNGAPI
+png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
+ warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
+}
+
+/* Alternate create PNG structure for reading, and allocate any memory needed. */
+png_structp PNGAPI
+png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+
+ png_structp png_ptr;
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ jmp_buf jmpbuf;
+#endif
+#endif
+
+ int i;
+
+ png_debug(1, "in png_create_read_struct\n");
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+ (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
+#else
+ png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+#endif
+ if (png_ptr == NULL)
+ return (NULL);
+
+#if !defined(PNG_1_0_X)
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+ png_init_mmx_flags(png_ptr); /* 1.2.0 addition */
+#endif
+#endif /* PNG_1_0_X */
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+#else
+ if (setjmp(png_ptr->jmpbuf))
+#endif
+ {
+ png_free(png_ptr, png_ptr->zbuf);
+ png_ptr->zbuf=NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)png_ptr,
+ (png_free_ptr)free_fn, (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)png_ptr);
+#endif
+ return (NULL);
+ }
+#ifdef USE_FAR_KEYWORD
+ png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
+#endif
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif
+
+ png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+ i=0;
+ do
+ {
+ if(user_png_ver[i] != png_libpng_ver[i])
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+ } while (png_libpng_ver[i++]);
+
+ if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+ {
+ /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+ * we must recompile any applications that use any older library version.
+ * For versions after libpng 1.0, we will be compatible, so we need
+ * only check the first digit.
+ */
+ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+ (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
+ (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char msg[80];
+ if (user_png_ver)
+ {
+ sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ sprintf(msg, "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+#endif
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "Incompatible libpng version in application and library");
+ }
+ }
+
+ /* initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+ png_ptr->zstream.zalloc = png_zalloc;
+ png_ptr->zstream.zfree = png_zfree;
+ png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+ switch (inflateInit(&png_ptr->zstream))
+ {
+ case Z_OK: /* Do nothing */ break;
+ case Z_MEM_ERROR:
+ case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory error"); break;
+ case Z_VERSION_ERROR: png_error(png_ptr, "zlib version error"); break;
+ default: png_error(png_ptr, "Unknown zlib error");
+ }
+
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* Applications that neglect to set up their own setjmp() and then encounter
+ a png_error() will longjmp here. Since the jmpbuf is then meaningless we
+ abort instead of returning. */
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+ PNG_ABORT();
+ png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
+#else
+ if (setjmp(png_ptr->jmpbuf))
+ PNG_ABORT();
+#endif
+#endif
+ return (png_ptr);
+}
+
+/* Initialize PNG structure for reading, and allocate any memory needed.
+ This interface is deprecated in favour of the png_create_read_struct(),
+ and it will eventually disappear. */
+#undef png_read_init
+void PNGAPI
+png_read_init(png_structp png_ptr)
+{
+ /* We only come here via pre-1.0.7-compiled applications */
+ png_read_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
+}
+
+void PNGAPI
+png_read_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size, png_size_t png_info_size)
+{
+ /* We only come here via pre-1.0.12-compiled applications */
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ if(sizeof(png_struct) > png_struct_size || sizeof(png_info) > png_info_size)
+ {
+ char msg[80];
+ png_ptr->warning_fn=NULL;
+ if (user_png_ver)
+ {
+ sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ sprintf(msg, "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+ }
+#endif
+ if(sizeof(png_struct) > png_struct_size)
+ {
+ png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "The png struct allocated by the application for reading is too small.");
+ }
+ if(sizeof(png_info) > png_info_size)
+ {
+ png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "The info struct allocated by application for reading is too small.");
+ }
+ png_read_init_3(&png_ptr, user_png_ver, png_struct_size);
+}
+
+void PNGAPI
+png_read_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp; /* to save current jump buffer */
+#endif
+
+ int i=0;
+
+ png_structp png_ptr=*ptr_ptr;
+
+ do
+ {
+ if(user_png_ver[i] != png_libpng_ver[i])
+ {
+#ifdef PNG_LEGACY_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+ png_ptr->warning_fn=NULL;
+ png_warning(png_ptr,
+ "Application uses deprecated png_read_init() and should be recompiled.");
+ break;
+#endif
+ }
+ } while (png_libpng_ver[i++]);
+
+ png_debug(1, "in png_read_init_3\n");
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* save jump buffer and error functions */
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+#endif
+
+ if(sizeof(png_struct) > png_struct_size)
+ {
+ png_destroy_struct(png_ptr);
+ *ptr_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+ png_ptr = *ptr_ptr;
+ }
+
+ /* reset all variables to 0 */
+ png_memset(png_ptr, 0, sizeof (png_struct));
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* restore jump buffer */
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+#endif
+
+ /* initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+ png_ptr->zstream.zalloc = png_zalloc;
+ png_ptr->zstream.zfree = png_zfree;
+ png_ptr->zstream.opaque = (voidpf)png_ptr;
+
+ switch (inflateInit(&png_ptr->zstream))
+ {
+ case Z_OK: /* Do nothing */ break;
+ case Z_MEM_ERROR:
+ case Z_STREAM_ERROR: png_error(png_ptr, "zlib memory"); break;
+ case Z_VERSION_ERROR: png_error(png_ptr, "zlib version"); break;
+ default: png_error(png_ptr, "Unknown zlib error");
+ }
+
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ png_set_read_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL);
+}
+
+/* Read the information before the actual image data. This has been
+ * changed in v0.90 to allow reading a file that already has the magic
+ * bytes read from the stream. You can tell libpng how many bytes have
+ * been read from the beginning of the stream (up to the maximum of 8)
+ * via png_set_sig_bytes(), and we will only check the remaining bytes
+ * here. The application can then have access to the signature bytes we
+ * read if it is determined that this isn't a valid PNG file.
+ */
+void PNGAPI
+png_read_info(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_read_info\n");
+ /* If we haven't checked all of the PNG signature bytes, do so now. */
+ if (png_ptr->sig_bytes < 8)
+ {
+ png_size_t num_checked = png_ptr->sig_bytes,
+ num_to_check = 8 - num_checked;
+
+ png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
+ png_ptr->sig_bytes = 8;
+
+ if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
+ {
+ if (num_checked < 4 &&
+ png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4))
+ png_error(png_ptr, "Not a PNG file");
+ else
+ png_error(png_ptr, "PNG file corrupted by ASCII conversion");
+ }
+ if (num_checked < 3)
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+ }
+
+ for(;;)
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IHDR;
+ PNG_IDAT;
+ PNG_IEND;
+ PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ PNG_sCAL;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ PNG_sPLT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ PNG_zTXt;
+#endif
+#endif /* PNG_GLOBAL_ARRAYS */
+ png_byte chunk_length[4];
+ png_uint_32 length;
+
+ png_read_data(png_ptr, chunk_length, 4);
+ length = png_get_uint_31(png_ptr,chunk_length);
+
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+
+ png_debug2(0, "Reading %s chunk, length=%lu.\n", png_ptr->chunk_name,
+ length);
+
+ /* This should be a binary subdivision search or a hash for
+ * matching the chunk name rather than a linear search.
+ */
+ if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+ png_handle_IHDR(png_ptr, info_ptr, length);
+ else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+ png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+ {
+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ png_handle_unknown(png_ptr, info_ptr, length);
+ if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+ break;
+ }
+ }
+#endif
+ else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ png_handle_PLTE(png_ptr, info_ptr, length);
+ else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before IDAT");
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ png_error(png_ptr, "Missing PLTE before IDAT");
+
+ png_ptr->idat_size = length;
+ png_ptr->mode |= PNG_HAVE_IDAT;
+ break;
+ }
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+ else
+ png_handle_unknown(png_ptr, info_ptr, length);
+ }
+}
+
+/* optional call to update the users info_ptr structure */
+void PNGAPI
+png_read_update_info(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_read_update_info\n");
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ png_read_start_row(png_ptr);
+ else
+ png_warning(png_ptr,
+ "Ignoring extra png_read_update_info() call; row buffer not reallocated");
+ png_read_transform_info(png_ptr, info_ptr);
+}
+
+/* Initialize palette, background, etc, after transformations
+ * are set, but before any reading takes place. This allows
+ * the user to obtain a gamma-corrected palette, for example.
+ * If the user doesn't call this, we will do it ourselves.
+ */
+void PNGAPI
+png_start_read_image(png_structp png_ptr)
+{
+ png_debug(1, "in png_start_read_image\n");
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ png_read_start_row(png_ptr);
+}
+
+void PNGAPI
+png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IDAT;
+ const int png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
+ const int png_pass_mask[7] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
+#endif
+ int ret;
+ png_debug2(1, "in png_read_row (row %lu, pass %d)\n",
+ png_ptr->row_number, png_ptr->pass);
+ if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
+ png_read_start_row(png_ptr);
+ if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+ {
+ /* check for transforms that have been set but were defined out */
+#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
+#endif
+#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
+#endif
+ }
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+ /* if interlaced and we do not need a new row, combine row and return */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ switch (png_ptr->pass)
+ {
+ case 0:
+ if (png_ptr->row_number & 0x07)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 1:
+ if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 2:
+ if ((png_ptr->row_number & 0x07) != 4)
+ {
+ if (dsp_row != NULL && (png_ptr->row_number & 4))
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 3:
+ if ((png_ptr->row_number & 3) || png_ptr->width < 3)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 4:
+ if ((png_ptr->row_number & 3) != 2)
+ {
+ if (dsp_row != NULL && (png_ptr->row_number & 2))
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 5:
+ if ((png_ptr->row_number & 1) || png_ptr->width < 2)
+ {
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 6:
+ if (!(png_ptr->row_number & 1))
+ {
+ png_read_finish_row(png_ptr);
+ return;
+ }
+ break;
+ }
+ }
+#endif
+
+ if (!(png_ptr->mode & PNG_HAVE_IDAT))
+ png_error(png_ptr, "Invalid attempt to read row data");
+
+ png_ptr->zstream.next_out = png_ptr->row_buf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
+ do
+ {
+ if (!(png_ptr->zstream.avail_in))
+ {
+ while (!png_ptr->idat_size)
+ {
+ png_byte chunk_length[4];
+
+ png_crc_finish(png_ptr, 0);
+
+ png_read_data(png_ptr, chunk_length, 4);
+ png_ptr->idat_size = png_get_uint_31(png_ptr,chunk_length);
+
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ png_error(png_ptr, "Not enough image data");
+ }
+ png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_in = png_ptr->zbuf;
+ if (png_ptr->zbuf_size > png_ptr->idat_size)
+ png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+ png_crc_read(png_ptr, png_ptr->zbuf,
+ (png_size_t)png_ptr->zstream.avail_in);
+ png_ptr->idat_size -= png_ptr->zstream.avail_in;
+ }
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret == Z_STREAM_END)
+ {
+ if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
+ png_ptr->idat_size)
+ png_error(png_ptr, "Extra compressed data");
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+ if (ret != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+ "Decompression error");
+
+ } while (png_ptr->zstream.avail_out);
+
+ png_ptr->row_info.color_type = png_ptr->color_type;
+ png_ptr->row_info.width = png_ptr->iwidth;
+ png_ptr->row_info.channels = png_ptr->channels;
+ png_ptr->row_info.bit_depth = png_ptr->bit_depth;
+ png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
+ png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
+ (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
+
+ if(png_ptr->row_buf[0])
+ png_read_filter_row(png_ptr, &(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->prev_row + 1,
+ (int)(png_ptr->row_buf[0]));
+
+ png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
+ png_ptr->rowbytes + 1);
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+ {
+ /* Intrapixel differencing */
+ png_do_read_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+ }
+#endif
+
+ if (png_ptr->transformations)
+ png_do_read_transformations(png_ptr);
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+ /* blow up interlaced rows to full size */
+ if (png_ptr->interlaced &&
+ (png_ptr->transformations & PNG_INTERLACE))
+ {
+ if (png_ptr->pass < 6)
+/* old interface (pre-1.0.9):
+ png_do_read_interlace(&(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
+ */
+ png_do_read_interlace(png_ptr);
+
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row,
+ png_pass_dsp_mask[png_ptr->pass]);
+ if (row != NULL)
+ png_combine_row(png_ptr, row,
+ png_pass_mask[png_ptr->pass]);
+ }
+ else
+#endif
+ {
+ if (row != NULL)
+ png_combine_row(png_ptr, row, 0xff);
+ if (dsp_row != NULL)
+ png_combine_row(png_ptr, dsp_row, 0xff);
+ }
+ png_read_finish_row(png_ptr);
+
+ if (png_ptr->read_row_fn != NULL)
+ (*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+/* Read one or more rows of image data. If the image is interlaced,
+ * and png_set_interlace_handling() has been called, the rows need to
+ * contain the contents of the rows from the previous pass. If the
+ * image has alpha or transparency, and png_handle_alpha()[*] has been
+ * called, the rows contents must be initialized to the contents of the
+ * screen.
+ *
+ * "row" holds the actual image, and pixels are placed in it
+ * as they arrive. If the image is displayed after each pass, it will
+ * appear to "sparkle" in. "display_row" can be used to display a
+ * "chunky" progressive image, with finer detail added as it becomes
+ * available. If you do not want this "chunky" display, you may pass
+ * NULL for display_row. If you do not want the sparkle display, and
+ * you have not called png_handle_alpha(), you may pass NULL for rows.
+ * If you have called png_handle_alpha(), and the image has either an
+ * alpha channel or a transparency chunk, you must provide a buffer for
+ * rows. In this case, you do not have to provide a display_row buffer
+ * also, but you may. If the image is not interlaced, or if you have
+ * not called png_set_interlace_handling(), the display_row buffer will
+ * be ignored, so pass NULL to it.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.5
+ */
+
+void PNGAPI
+png_read_rows(png_structp png_ptr, png_bytepp row,
+ png_bytepp display_row, png_uint_32 num_rows)
+{
+ png_uint_32 i;
+ png_bytepp rp;
+ png_bytepp dp;
+
+ png_debug(1, "in png_read_rows\n");
+ rp = row;
+ dp = display_row;
+ if (rp != NULL && dp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep rptr = *rp++;
+ png_bytep dptr = *dp++;
+
+ png_read_row(png_ptr, rptr, dptr);
+ }
+ else if(rp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep rptr = *rp;
+ png_read_row(png_ptr, rptr, png_bytep_NULL);
+ rp++;
+ }
+ else if(dp != NULL)
+ for (i = 0; i < num_rows; i++)
+ {
+ png_bytep dptr = *dp;
+ png_read_row(png_ptr, png_bytep_NULL, dptr);
+ dp++;
+ }
+}
+
+/* Read the entire image. If the image has an alpha channel or a tRNS
+ * chunk, and you have called png_handle_alpha()[*], you will need to
+ * initialize the image to the current image that PNG will be overlaying.
+ * We set the num_rows again here, in case it was incorrectly set in
+ * png_read_start_row() by a call to png_read_update_info() or
+ * png_start_read_image() if png_set_interlace_handling() wasn't called
+ * prior to either of these functions like it should have been. You can
+ * only call this function once. If you desire to have an image for
+ * each pass of a interlaced image, use png_read_rows() instead.
+ *
+ * [*] png_handle_alpha() does not exist yet, as of libpng version 1.2.5
+ */
+void PNGAPI
+png_read_image(png_structp png_ptr, png_bytepp image)
+{
+ png_uint_32 i,image_height;
+ int pass, j;
+ png_bytepp rp;
+
+ png_debug(1, "in png_read_image\n");
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+ pass = png_set_interlace_handling(png_ptr);
+#else
+ if (png_ptr->interlaced)
+ png_error(png_ptr,
+ "Cannot read interlaced image -- interlace handler disabled.");
+ pass = 1;
+#endif
+
+
+ image_height=png_ptr->height;
+ png_ptr->num_rows = image_height; /* Make sure this is set correctly */
+
+ for (j = 0; j < pass; j++)
+ {
+ rp = image;
+ for (i = 0; i < image_height; i++)
+ {
+ png_read_row(png_ptr, *rp, png_bytep_NULL);
+ rp++;
+ }
+ }
+}
+
+/* Read the end of the PNG file. Will not read past the end of the
+ * file, will verify the end is accurate, and will read any comments
+ * or time information at the end of the file, if info is not NULL.
+ */
+void PNGAPI
+png_read_end(png_structp png_ptr, png_infop info_ptr)
+{
+ png_byte chunk_length[4];
+ png_uint_32 length;
+
+ png_debug(1, "in png_read_end\n");
+ png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
+
+ do
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IHDR;
+ PNG_IDAT;
+ PNG_IEND;
+ PNG_PLTE;
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ PNG_bKGD;
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ PNG_cHRM;
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ PNG_gAMA;
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ PNG_hIST;
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ PNG_iCCP;
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ PNG_iTXt;
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ PNG_oFFs;
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ PNG_pCAL;
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ PNG_pHYs;
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ PNG_sBIT;
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ PNG_sCAL;
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ PNG_sPLT;
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ PNG_sRGB;
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ PNG_tEXt;
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ PNG_tIME;
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ PNG_tRNS;
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ PNG_zTXt;
+#endif
+#endif /* PNG_GLOBAL_ARRAYS */
+
+ png_read_data(png_ptr, chunk_length, 4);
+ length = png_get_uint_31(png_ptr,chunk_length);
+
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+
+ png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
+
+ if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
+ png_handle_IHDR(png_ptr, info_ptr, length);
+ else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
+ png_handle_IEND(png_ptr, info_ptr, length);
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
+ else if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name))
+ {
+ if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
+ png_error(png_ptr, "Too many IDAT's found");
+ }
+ else
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_handle_unknown(png_ptr, info_ptr, length);
+ if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ png_ptr->mode |= PNG_HAVE_PLTE;
+ }
+#endif
+ else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
+ {
+ /* Zero length IDATs are legal after the last IDAT has been
+ * read, but not after other chunks have been read.
+ */
+ if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
+ png_error(png_ptr, "Too many IDAT's found");
+ png_crc_finish(png_ptr, length);
+ }
+ else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
+ png_handle_PLTE(png_ptr, info_ptr, length);
+#if defined(PNG_READ_bKGD_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
+ png_handle_bKGD(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_cHRM_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
+ png_handle_cHRM(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_gAMA_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
+ png_handle_gAMA(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
+ png_handle_hIST(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_oFFs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
+ png_handle_oFFs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
+ png_handle_pCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sCAL_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4))
+ png_handle_sCAL(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_pHYs_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
+ png_handle_pHYs(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sBIT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
+ png_handle_sBIT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
+ png_handle_sRGB(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iCCP_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4))
+ png_handle_iCCP(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_sPLT_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4))
+ png_handle_sPLT(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tEXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
+ png_handle_tEXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tIME_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
+ png_handle_tIME(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
+ png_handle_tRNS(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_zTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
+ png_handle_zTXt(png_ptr, info_ptr, length);
+#endif
+#if defined(PNG_READ_iTXt_SUPPORTED)
+ else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4))
+ png_handle_iTXt(png_ptr, info_ptr, length);
+#endif
+ else
+ png_handle_unknown(png_ptr, info_ptr, length);
+ } while (!(png_ptr->mode & PNG_HAVE_IEND));
+}
+
+/* free all memory used by the read */
+void PNGAPI
+png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
+ png_infopp end_info_ptr_ptr)
+{
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL, end_info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn = NULL;
+ png_voidp mem_ptr = NULL;
+#endif
+
+ png_debug(1, "in png_destroy_read_struct\n");
+ if (png_ptr_ptr != NULL)
+ png_ptr = *png_ptr_ptr;
+
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (end_info_ptr_ptr != NULL)
+ end_info_ptr = *end_info_ptr_ptr;
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+ mem_ptr = png_ptr->mem_ptr;
+#endif
+
+ png_read_destroy(png_ptr, info_ptr, end_info_ptr);
+
+ if (info_ptr != NULL)
+ {
+#if defined(PNG_TEXT_SUPPORTED)
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TEXT, -1);
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)info_ptr);
+#endif
+ *info_ptr_ptr = NULL;
+ }
+
+ if (end_info_ptr != NULL)
+ {
+#if defined(PNG_READ_TEXT_SUPPORTED)
+ png_free_data(png_ptr, end_info_ptr, PNG_FREE_TEXT, -1);
+#endif
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)end_info_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)end_info_ptr);
+#endif
+ *end_info_ptr_ptr = NULL;
+ }
+
+ if (png_ptr != NULL)
+ {
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)png_ptr);
+#endif
+ *png_ptr_ptr = NULL;
+ }
+}
+
+/* free all memory used by the read (old method) */
+void /* PRIVATE */
+png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp;
+#endif
+ png_error_ptr error_fn;
+ png_error_ptr warning_fn;
+ png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn;
+#endif
+
+ png_debug(1, "in png_read_destroy\n");
+ if (info_ptr != NULL)
+ png_info_destroy(png_ptr, info_ptr);
+
+ if (end_info_ptr != NULL)
+ png_info_destroy(png_ptr, end_info_ptr);
+
+ png_free(png_ptr, png_ptr->zbuf);
+ png_free(png_ptr, png_ptr->big_row_buf);
+ png_free(png_ptr, png_ptr->prev_row);
+#if defined(PNG_READ_DITHER_SUPPORTED)
+ png_free(png_ptr, png_ptr->palette_lookup);
+ png_free(png_ptr, png_ptr->dither_index);
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ png_free(png_ptr, png_ptr->gamma_table);
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ png_free(png_ptr, png_ptr->gamma_from_1);
+ png_free(png_ptr, png_ptr->gamma_to_1);
+#endif
+#ifdef PNG_FREE_ME_SUPPORTED
+ if (png_ptr->free_me & PNG_FREE_PLTE)
+ png_zfree(png_ptr, png_ptr->palette);
+ png_ptr->free_me &= ~PNG_FREE_PLTE;
+#else
+ if (png_ptr->flags & PNG_FLAG_FREE_PLTE)
+ png_zfree(png_ptr, png_ptr->palette);
+ png_ptr->flags &= ~PNG_FLAG_FREE_PLTE;
+#endif
+#if defined(PNG_tRNS_SUPPORTED) || \
+ defined(PNG_READ_EXPAND_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+ if (png_ptr->free_me & PNG_FREE_TRNS)
+ png_free(png_ptr, png_ptr->trans);
+ png_ptr->free_me &= ~PNG_FREE_TRNS;
+#else
+ if (png_ptr->flags & PNG_FLAG_FREE_TRNS)
+ png_free(png_ptr, png_ptr->trans);
+ png_ptr->flags &= ~PNG_FLAG_FREE_TRNS;
+#endif
+#endif
+#if defined(PNG_READ_hIST_SUPPORTED)
+#ifdef PNG_FREE_ME_SUPPORTED
+ if (png_ptr->free_me & PNG_FREE_HIST)
+ png_free(png_ptr, png_ptr->hist);
+ png_ptr->free_me &= ~PNG_FREE_HIST;
+#else
+ if (png_ptr->flags & PNG_FLAG_FREE_HIST)
+ png_free(png_ptr, png_ptr->hist);
+ png_ptr->flags &= ~PNG_FLAG_FREE_HIST;
+#endif
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (png_ptr->gamma_16_table != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_table[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_table);
+ }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_16_from_1 != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_from_1);
+ }
+ if (png_ptr->gamma_16_to_1 != NULL)
+ {
+ int i;
+ int istop = (1 << (8 - png_ptr->gamma_shift));
+ for (i = 0; i < istop; i++)
+ {
+ png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
+ }
+ png_free(png_ptr, png_ptr->gamma_16_to_1);
+ }
+#endif
+#endif
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ png_free(png_ptr, png_ptr->time_buffer);
+#endif
+
+ inflateEnd(&png_ptr->zstream);
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+ png_free(png_ptr, png_ptr->save_buffer);
+#endif
+
+#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
+#ifdef PNG_TEXT_SUPPORTED
+ png_free(png_ptr, png_ptr->current_text);
+#endif /* PNG_TEXT_SUPPORTED */
+#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */
+
+ /* Save the important info out of the png_struct, in case it is
+ * being used again.
+ */
+#ifdef PNG_SETJMP_SUPPORTED
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+#endif
+
+ error_fn = png_ptr->error_fn;
+ warning_fn = png_ptr->warning_fn;
+ error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+#endif
+
+ png_memset(png_ptr, 0, sizeof (png_struct));
+
+ png_ptr->error_fn = error_fn;
+ png_ptr->warning_fn = warning_fn;
+ png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr->free_fn = free_fn;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+#endif
+
+}
+
+void PNGAPI
+png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
+{
+ png_ptr->read_row_fn = read_row_fn;
+}
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_read_png(png_structp png_ptr, png_infop info_ptr,
+ int transforms,
+ voidp params)
+{
+ int row;
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+ /* invert the alpha channel from opacity to transparency */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+ png_set_invert_alpha(png_ptr);
+#endif
+
+ /* The call to png_read_info() gives us all of the information from the
+ * PNG file before the first IDAT (image data chunk).
+ */
+ png_read_info(png_ptr, info_ptr);
+
+ if (info_ptr->height > PNG_UINT_32_MAX/sizeof(png_bytep))
+ png_error(png_ptr,"Image is too high to process with png_read_png()");
+
+ /* -------------- image transformations start here ------------------- */
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+ /* tell libpng to strip 16 bit/color files down to 8 bits/color */
+ if (transforms & PNG_TRANSFORM_STRIP_16)
+ png_set_strip_16(png_ptr);
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+ /* Strip alpha bytes from the input data without combining with the
+ * background (not recommended).
+ */
+ if (transforms & PNG_TRANSFORM_STRIP_ALPHA)
+ png_set_strip_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) && !defined(PNG_READ_EXPAND_SUPPORTED)
+ /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
+ * byte into separate bytes (useful for paletted and grayscale images).
+ */
+ if (transforms & PNG_TRANSFORM_PACKING)
+ png_set_packing(png_ptr);
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ /* Change the order of packed pixels to least significant bit first
+ * (not useful if you are using png_set_packing). */
+ if (transforms & PNG_TRANSFORM_PACKSWAP)
+ png_set_packswap(png_ptr);
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ /* Expand paletted colors into true RGB triplets
+ * Expand grayscale images to full 8 bits from 1, 2, or 4 bits/pixel
+ * Expand paletted or RGB images with transparency to full alpha
+ * channels so the data will be available as RGBA quartets.
+ */
+ if (transforms & PNG_TRANSFORM_EXPAND)
+ if ((png_ptr->bit_depth < 8) ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) ||
+ (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)))
+ png_set_expand(png_ptr);
+#endif
+
+ /* We don't handle background color or gamma transformation or dithering. */
+
+#if defined(PNG_READ_INVERT_SUPPORTED)
+ /* invert monochrome files to have 0 as white and 1 as black */
+ if (transforms & PNG_TRANSFORM_INVERT_MONO)
+ png_set_invert_mono(png_ptr);
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+ /* If you want to shift the pixel values from the range [0,255] or
+ * [0,65535] to the original [0,7] or [0,31], or whatever range the
+ * colors were originally in:
+ */
+ if ((transforms & PNG_TRANSFORM_SHIFT)
+ && png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
+ {
+ png_color_8p sig_bit;
+
+ png_get_sBIT(png_ptr, info_ptr, &sig_bit);
+ png_set_shift(png_ptr, sig_bit);
+ }
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED)
+ /* flip the RGB pixels to BGR (or RGBA to BGRA) */
+ if (transforms & PNG_TRANSFORM_BGR)
+ png_set_bgr(png_ptr);
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+ /* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
+ if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+ png_set_swap_alpha(png_ptr);
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED)
+ /* swap bytes of 16 bit files to least significant byte first */
+ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+ png_set_swap(png_ptr);
+#endif
+
+ /* We don't handle adding filler bytes */
+
+ /* Optional call to gamma correct and add the background to the palette
+ * and update info structure. RETQUIRED if you are expecting libpng to
+ * update the palette for you (i.e., you selected such a transform above).
+ */
+ png_read_update_info(png_ptr, info_ptr);
+
+ /* -------------- image transformations end here ------------------- */
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+#endif
+ if(info_ptr->row_pointers == NULL)
+ {
+ info_ptr->row_pointers = (png_bytepp)png_malloc(png_ptr,
+ info_ptr->height * sizeof(png_bytep));
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_ROWS;
+#endif
+ for (row = 0; row < (int)info_ptr->height; row++)
+ {
+ info_ptr->row_pointers[row] = (png_bytep)png_malloc(png_ptr,
+ png_get_rowbytes(png_ptr, info_ptr));
+ }
+ }
+
+ png_read_image(png_ptr, info_ptr->row_pointers);
+ info_ptr->valid |= PNG_INFO_IDAT;
+
+ /* read rest of file, and get additional chunks in info_ptr - RETQUIRED */
+ png_read_end(png_ptr, info_ptr);
+
+ if(transforms == 0 || params == NULL)
+ /* quiet compiler warnings */ return;
+
+}
+#endif
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngrio.c b/tqtinterface/qt4/src/3rdparty/libpng/pngrio.c
new file mode 100644
index 0000000..0598231
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngrio.c
@@ -0,0 +1,161 @@
+
+/* pngrio.c - functions for data input
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all input. Users who need
+ * special handling are expected to write a function that has the same
+ * arguments as this and performs a similar function, but that possibly
+ * has a different input method. Note that you shouldn't change this
+ * function, but rather write a tqreplacement function and then make
+ * libpng use it at run time with png_set_read_fn(...).
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Read the data from whatever input you are using. The default routine
+ reads from a file pointer. Note that this routine sometimes gets called
+ with very small lengths, so you should implement some kind of simple
+ buffering if you are using unbuffered reads. This should never be asked
+ to read more then 64K on a 16 bit machine. */
+void /* PRIVATE */
+png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_debug1(4,"reading %d bytes\n", (int)length);
+ if (png_ptr->read_data_fn != NULL)
+ (*(png_ptr->read_data_fn))(png_ptr, data, length);
+ else
+ png_error(png_ptr, "Call to NULL read function");
+}
+
+#if !defined(PNG_NO_STDIO)
+/* This is the function that does the actual reading of data. If you are
+ not reading from a standard C stream, you should create a tqreplacement
+ read_data function and use it at run time with png_set_read_fn(), rather
+ than changing the library. */
+#ifndef USE_FAR_KEYWORD
+void PNGAPI
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check;
+
+ /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+ * instead of an int, which is what fread() actually returns.
+ */
+#if defined(_WIN32_WCE)
+ if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+ check = 0;
+#else
+ check = (png_size_t)fread(data, (png_size_t)1, length,
+ (png_FILE_p)png_ptr->io_ptr);
+#endif
+
+ if (check != length)
+ png_error(png_ptr, "Read Error");
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+ can't handle far buffers in the medium and small models, we have to copy
+ the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void /* PRIVATE */
+png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ int check;
+ png_byte *n_data;
+ png_FILE_p io_ptr;
+
+ /* Check if data really is near. If so, use usual code. */
+ n_data = (png_byte *)CVT_PTR_NOCHECK(data);
+ io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+ if ((png_bytep)n_data == data)
+ {
+#if defined(_WIN32_WCE)
+ if ( !ReadFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+ check = 0;
+#else
+ check = fread(n_data, 1, length, io_ptr);
+#endif
+ }
+ else
+ {
+ png_byte buf[NEAR_BUF_SIZE];
+ png_size_t read, remaining, err;
+ check = 0;
+ remaining = length;
+ do
+ {
+ read = MIN(NEAR_BUF_SIZE, remaining);
+#if defined(_WIN32_WCE)
+ if ( !ReadFile((HANDLE)(io_ptr), buf, read, &err, NULL) )
+ err = 0;
+#else
+ err = fread(buf, (png_size_t)1, read, io_ptr);
+#endif
+ png_memcpy(data, buf, read); /* copy far buffer to near buffer */
+ if(err != read)
+ break;
+ else
+ check += err;
+ data += read;
+ remaining -= read;
+ }
+ while (remaining != 0);
+ }
+ if ((png_uint_32)check != (png_uint_32)length)
+ png_error(png_ptr, "read Error");
+}
+#endif
+#endif
+
+/* This function allows the application to supply a new input function
+ for libpng if standard C streams aren't being used.
+
+ This function takes as its arguments:
+ png_ptr - pointer to a png input data structure
+ io_ptr - pointer to user supplied structure containing info about
+ the input functions. May be NULL.
+ read_data_fn - pointer to a new input function that takes as its
+ arguments a pointer to a png_struct, a pointer to
+ a location where input data can be stored, and a 32-bit
+ unsigned int that is the number of bytes to be read.
+ To exit and output any fatal error messages the new write
+ function should call png_error(png_ptr, "Error msg"). */
+void PNGAPI
+png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
+ png_rw_ptr read_data_fn)
+{
+ png_ptr->io_ptr = io_ptr;
+
+#if !defined(PNG_NO_STDIO)
+ if (read_data_fn != NULL)
+ png_ptr->read_data_fn = read_data_fn;
+ else
+ png_ptr->read_data_fn = png_default_read_data;
+#else
+ png_ptr->read_data_fn = read_data_fn;
+#endif
+
+ /* It is an error to write to a read tqdevice */
+ if (png_ptr->write_data_fn != NULL)
+ {
+ png_ptr->write_data_fn = NULL;
+ png_warning(png_ptr,
+ "It's an error to set both read_data_fn and write_data_fn in the ");
+ png_warning(png_ptr,
+ "same structure. Resetting write_data_fn to NULL.");
+ }
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+ png_ptr->output_flush_fn = NULL;
+#endif
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngrtran.c b/tqtinterface/qt4/src/3rdparty/libpng/pngrtran.c
new file mode 100644
index 0000000..a695731
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngrtran.c
@@ -0,0 +1,4175 @@
+
+/* pngrtran.c - transforms the data in a row for PNG readers
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file tqcontains functions optionally called by an application
+ * in order to tell libpng how to handle data when reading a PNG.
+ * Transformations that are used in both reading and writing are
+ * in pngtrans.c.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+/* Set the action on getting a CRC error for an ancillary or critical chunk. */
+void PNGAPI
+png_set_crc_action(png_structp png_ptr, int crit_action, int ancil_action)
+{
+ png_debug(1, "in png_set_crc_action\n");
+ /* Tell libpng how we react to CRC errors in critical chunks */
+ switch (crit_action)
+ {
+ case PNG_CRC_NO_CHANGE: /* leave setting as is */
+ break;
+ case PNG_CRC_WARN_USE: /* warn/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE;
+ break;
+ case PNG_CRC_TQUIET_USE: /* quiet/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_CRITICAL_USE |
+ PNG_FLAG_CRC_CRITICAL_IGNORE;
+ break;
+ case PNG_CRC_WARN_DISCARD: /* not a valid action for critical data */
+ png_warning(png_ptr, "Can't discard critical data on CRC error.");
+ case PNG_CRC_ERROR_TQUIT: /* error/quit */
+ case PNG_CRC_DEFAULT:
+ default:
+ png_ptr->flags &= ~PNG_FLAG_CRC_CRITICAL_MASK;
+ break;
+ }
+
+ switch (ancil_action)
+ {
+ case PNG_CRC_NO_CHANGE: /* leave setting as is */
+ break;
+ case PNG_CRC_WARN_USE: /* warn/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE;
+ break;
+ case PNG_CRC_TQUIET_USE: /* quiet/use data */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_USE |
+ PNG_FLAG_CRC_ANCILLARY_NOWARN;
+ break;
+ case PNG_CRC_ERROR_TQUIT: /* error/quit */
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ png_ptr->flags |= PNG_FLAG_CRC_ANCILLARY_NOWARN;
+ break;
+ case PNG_CRC_WARN_DISCARD: /* warn/discard data */
+ case PNG_CRC_DEFAULT:
+ default:
+ png_ptr->flags &= ~PNG_FLAG_CRC_ANCILLARY_MASK;
+ break;
+ }
+}
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+ defined(PNG_FLOATING_POINT_SUPPORTED)
+/* handle alpha and tRNS via a background color */
+void PNGAPI
+png_set_background(png_structp png_ptr,
+ png_color_16p background_color, int background_gamma_code,
+ int need_expand, double background_gamma)
+{
+ png_debug(1, "in png_set_background\n");
+ if (background_gamma_code == PNG_BACKGROUND_GAMMA_UNKNOWN)
+ {
+ png_warning(png_ptr, "Application must supply a known background gamma");
+ return;
+ }
+
+ png_ptr->transformations |= PNG_BACKGROUND;
+ png_memcpy(&(png_ptr->background), background_color, sizeof(png_color_16));
+ png_ptr->background_gamma = (float)background_gamma;
+ png_ptr->background_gamma_type = (png_byte)(background_gamma_code);
+ png_ptr->transformations |= (need_expand ? PNG_BACKGROUND_EXPAND : 0);
+
+ /* Note: if need_expand is set and color_type is either RGB or RGB_ALPHA
+ * (in which case need_expand is superfluous anyway), the background color
+ * might actually be gray yet not be flagged as such. This is not a problem
+ * for the current code, which uses PNG_BACKGROUND_IS_GRAY only to
+ * decide when to do the png_do_gray_to_rgb() transformation.
+ */
+ if ((need_expand && !(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) ||
+ (!need_expand && background_color->red == background_color->green &&
+ background_color->red == background_color->blue))
+ png_ptr->mode |= PNG_BACKGROUND_IS_GRAY;
+}
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* strip 16 bit depth files to 8 bit depth */
+void PNGAPI
+png_set_strip_16(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_strip_16\n");
+ png_ptr->transformations |= PNG_16_TO_8;
+}
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_strip_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_strip_alpha\n");
+ png_ptr->transformations |= PNG_STRIP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+/* Dither file to 8 bit. Supply a palette, the current number
+ * of elements in the palette, the maximum number of elements
+ * allowed, and a histogram if possible. If the current number
+ * of colors is greater then the maximum number, the palette will be
+ * modified to fit in the maximum number. "full_dither" indicates
+ * whether we need a dithering cube set up for RGB images, or if we
+ * simply are reducing the number of colors in a paletted image.
+ */
+
+typedef struct png_dsort_struct
+{
+ struct png_dsort_struct FAR * next;
+ png_byte left;
+ png_byte right;
+} png_dsort;
+typedef png_dsort FAR * png_dsortp;
+typedef png_dsort FAR * FAR * png_dsortpp;
+
+void PNGAPI
+png_set_dither(png_structp png_ptr, png_colorp palette,
+ int num_palette, int maximum_colors, png_uint_16p histogram,
+ int full_dither)
+{
+ png_debug(1, "in png_set_dither\n");
+ png_ptr->transformations |= PNG_DITHER;
+
+ if (!full_dither)
+ {
+ int i;
+
+ png_ptr->dither_index = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * sizeof (png_byte)));
+ for (i = 0; i < num_palette; i++)
+ png_ptr->dither_index[i] = (png_byte)i;
+ }
+
+ if (num_palette > maximum_colors)
+ {
+ if (histogram != NULL)
+ {
+ /* This is easy enough, just throw out the least used colors.
+ Perhaps not the best solution, but good enough. */
+
+ int i;
+
+ /* initialize an array to sort colors */
+ png_ptr->dither_sort = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * sizeof (png_byte)));
+
+ /* initialize the dither_sort array */
+ for (i = 0; i < num_palette; i++)
+ png_ptr->dither_sort[i] = (png_byte)i;
+
+ /* Find the least used palette entries by starting a
+ bubble sort, and running it until we have sorted
+ out enough colors. Note that we don't care about
+ sorting all the colors, just tqfinding which are
+ least used. */
+
+ for (i = num_palette - 1; i >= maximum_colors; i--)
+ {
+ int done; /* to stop early if the list is pre-sorted */
+ int j;
+
+ done = 1;
+ for (j = 0; j < i; j++)
+ {
+ if (histogram[png_ptr->dither_sort[j]]
+ < histogram[png_ptr->dither_sort[j + 1]])
+ {
+ png_byte t;
+
+ t = png_ptr->dither_sort[j];
+ png_ptr->dither_sort[j] = png_ptr->dither_sort[j + 1];
+ png_ptr->dither_sort[j + 1] = t;
+ done = 0;
+ }
+ }
+ if (done)
+ break;
+ }
+
+ /* swap the palette around, and set up a table, if necessary */
+ if (full_dither)
+ {
+ int j = num_palette;
+
+ /* put all the useful colors within the max, but don't
+ move the others */
+ for (i = 0; i < maximum_colors; i++)
+ {
+ if ((int)png_ptr->dither_sort[i] >= maximum_colors)
+ {
+ do
+ j--;
+ while ((int)png_ptr->dither_sort[j] >= maximum_colors);
+ palette[i] = palette[j];
+ }
+ }
+ }
+ else
+ {
+ int j = num_palette;
+
+ /* move all the used colors inside the max limit, and
+ develop a translation table */
+ for (i = 0; i < maximum_colors; i++)
+ {
+ /* only move the colors we need to */
+ if ((int)png_ptr->dither_sort[i] >= maximum_colors)
+ {
+ png_color tmp_color;
+
+ do
+ j--;
+ while ((int)png_ptr->dither_sort[j] >= maximum_colors);
+
+ tmp_color = palette[j];
+ palette[j] = palette[i];
+ palette[i] = tmp_color;
+ /* indicate where the color went */
+ png_ptr->dither_index[j] = (png_byte)i;
+ png_ptr->dither_index[i] = (png_byte)j;
+ }
+ }
+
+ /* tqfind closest color for those colors we are not using */
+ for (i = 0; i < num_palette; i++)
+ {
+ if ((int)png_ptr->dither_index[i] >= maximum_colors)
+ {
+ int min_d, k, min_k, d_index;
+
+ /* tqfind the closest color to one we threw out */
+ d_index = png_ptr->dither_index[i];
+ min_d = PNG_COLOR_DIST(palette[d_index], palette[0]);
+ for (k = 1, min_k = 0; k < maximum_colors; k++)
+ {
+ int d;
+
+ d = PNG_COLOR_DIST(palette[d_index], palette[k]);
+
+ if (d < min_d)
+ {
+ min_d = d;
+ min_k = k;
+ }
+ }
+ /* point to closest color */
+ png_ptr->dither_index[i] = (png_byte)min_k;
+ }
+ }
+ }
+ png_free(png_ptr, png_ptr->dither_sort);
+ png_ptr->dither_sort=NULL;
+ }
+ else
+ {
+ /* This is much harder to do simply (and quickly). Perhaps
+ we need to go through a median cut routine, but those
+ don't always behave themselves with only a few colors
+ as input. So we will just tqfind the closest two colors,
+ and throw out one of them (chosen somewhat randomly).
+ [We don't understand this at all, so if someone wants to
+ work on improving it, be our guest - AED, GRP]
+ */
+ int i;
+ int max_d;
+ int num_new_palette;
+ png_dsortp t;
+ png_dsortpp hash;
+
+ t=NULL;
+
+ /* initialize palette index arrays */
+ png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * sizeof (png_byte)));
+ png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(num_palette * sizeof (png_byte)));
+
+ /* initialize the sort array */
+ for (i = 0; i < num_palette; i++)
+ {
+ png_ptr->index_to_palette[i] = (png_byte)i;
+ png_ptr->palette_to_index[i] = (png_byte)i;
+ }
+
+ hash = (png_dsortpp)png_malloc(png_ptr, (png_uint_32)(769 *
+ sizeof (png_dsortp)));
+ for (i = 0; i < 769; i++)
+ hash[i] = NULL;
+/* png_memset(hash, 0, 769 * sizeof (png_dsortp)); */
+
+ num_new_palette = num_palette;
+
+ /* initial wild guess at how far apart the farthest pixel
+ pair we will be eliminating will be. Larger
+ numbers mean more areas will be allocated, Smaller
+ numbers run the risk of not saving enough data, and
+ having to do this all over again.
+
+ I have not done extensive checking on this number.
+ */
+ max_d = 96;
+
+ while (num_new_palette > maximum_colors)
+ {
+ for (i = 0; i < num_new_palette - 1; i++)
+ {
+ int j;
+
+ for (j = i + 1; j < num_new_palette; j++)
+ {
+ int d;
+
+ d = PNG_COLOR_DIST(palette[i], palette[j]);
+
+ if (d <= max_d)
+ {
+
+ t = (png_dsortp)png_malloc_warn(png_ptr,
+ (png_uint_32)(sizeof(png_dsort)));
+ if (t == NULL)
+ break;
+ t->next = hash[d];
+ t->left = (png_byte)i;
+ t->right = (png_byte)j;
+ hash[d] = t;
+ }
+ }
+ if (t == NULL)
+ break;
+ }
+
+ if (t != NULL)
+ for (i = 0; i <= max_d; i++)
+ {
+ if (hash[i] != NULL)
+ {
+ png_dsortp p;
+
+ for (p = hash[i]; p; p = p->next)
+ {
+ if ((int)png_ptr->index_to_palette[p->left]
+ < num_new_palette &&
+ (int)png_ptr->index_to_palette[p->right]
+ < num_new_palette)
+ {
+ int j, next_j;
+
+ if (num_new_palette & 0x01)
+ {
+ j = p->left;
+ next_j = p->right;
+ }
+ else
+ {
+ j = p->right;
+ next_j = p->left;
+ }
+
+ num_new_palette--;
+ palette[png_ptr->index_to_palette[j]]
+ = palette[num_new_palette];
+ if (!full_dither)
+ {
+ int k;
+
+ for (k = 0; k < num_palette; k++)
+ {
+ if (png_ptr->dither_index[k] ==
+ png_ptr->index_to_palette[j])
+ png_ptr->dither_index[k] =
+ png_ptr->index_to_palette[next_j];
+ if ((int)png_ptr->dither_index[k] ==
+ num_new_palette)
+ png_ptr->dither_index[k] =
+ png_ptr->index_to_palette[j];
+ }
+ }
+
+ png_ptr->index_to_palette[png_ptr->palette_to_index
+ [num_new_palette]] = png_ptr->index_to_palette[j];
+ png_ptr->palette_to_index[png_ptr->index_to_palette[j]]
+ = png_ptr->palette_to_index[num_new_palette];
+
+ png_ptr->index_to_palette[j] = (png_byte)num_new_palette;
+ png_ptr->palette_to_index[num_new_palette] = (png_byte)j;
+ }
+ if (num_new_palette <= maximum_colors)
+ break;
+ }
+ if (num_new_palette <= maximum_colors)
+ break;
+ }
+ }
+
+ for (i = 0; i < 769; i++)
+ {
+ if (hash[i] != NULL)
+ {
+ png_dsortp p = hash[i];
+ while (p)
+ {
+ t = p->next;
+ png_free(png_ptr, p);
+ p = t;
+ }
+ }
+ hash[i] = 0;
+ }
+ max_d += 96;
+ }
+ png_free(png_ptr, hash);
+ png_free(png_ptr, png_ptr->palette_to_index);
+ png_free(png_ptr, png_ptr->index_to_palette);
+ png_ptr->palette_to_index=NULL;
+ png_ptr->index_to_palette=NULL;
+ }
+ num_palette = maximum_colors;
+ }
+ if (png_ptr->palette == NULL)
+ {
+ png_ptr->palette = palette;
+ }
+ png_ptr->num_palette = (png_uint_16)num_palette;
+
+ if (full_dither)
+ {
+ int i;
+ png_bytep distance;
+ int total_bits = PNG_DITHER_RED_BITS + PNG_DITHER_GREEN_BITS +
+ PNG_DITHER_BLUE_BITS;
+ int num_red = (1 << PNG_DITHER_RED_BITS);
+ int num_green = (1 << PNG_DITHER_GREEN_BITS);
+ int num_blue = (1 << PNG_DITHER_BLUE_BITS);
+ png_size_t num_entries = ((png_size_t)1 << total_bits);
+
+ png_ptr->palette_lookup = (png_bytep )png_malloc(png_ptr,
+ (png_uint_32)(num_entries * sizeof (png_byte)));
+
+ png_memset(png_ptr->palette_lookup, 0, num_entries * sizeof (png_byte));
+
+ distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+ sizeof(png_byte)));
+
+ png_memset(distance, 0xff, num_entries * sizeof(png_byte));
+
+ for (i = 0; i < num_palette; i++)
+ {
+ int ir, ig, ib;
+ int r = (palette[i].red >> (8 - PNG_DITHER_RED_BITS));
+ int g = (palette[i].green >> (8 - PNG_DITHER_GREEN_BITS));
+ int b = (palette[i].blue >> (8 - PNG_DITHER_BLUE_BITS));
+
+ for (ir = 0; ir < num_red; ir++)
+ {
+ int dr = abs(ir - r);
+ int index_r = (ir << (PNG_DITHER_BLUE_BITS + PNG_DITHER_GREEN_BITS));
+
+ for (ig = 0; ig < num_green; ig++)
+ {
+ int dg = abs(ig - g);
+ int dt = dr + dg;
+ int dm = ((dr > dg) ? dr : dg);
+ int index_g = index_r | (ig << PNG_DITHER_BLUE_BITS);
+
+ for (ib = 0; ib < num_blue; ib++)
+ {
+ int d_index = index_g | ib;
+ int db = abs(ib - b);
+ int dmax = ((dm > db) ? dm : db);
+ int d = dmax + dt + db;
+
+ if (d < (int)distance[d_index])
+ {
+ distance[d_index] = (png_byte)d;
+ png_ptr->palette_lookup[d_index] = (png_byte)i;
+ }
+ }
+ }
+ }
+ }
+
+ png_free(png_ptr, distance);
+ }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+/* Transform the image from the file_gamma to the screen_gamma. We
+ * only do transformations on images where the file_gamma and screen_gamma
+ * are not close reciprocals, otherwise it slows things down slightly, and
+ * also needlessly introduces small errors.
+ *
+ * We will turn off gamma transformation later if no semitranstqparent entries
+ * are present in the tRNS array for palette images. We can't do it here
+ * because we don't necessarily have the tRNS chunk yet.
+ */
+void PNGAPI
+png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
+{
+ png_debug(1, "in png_set_gamma\n");
+ if ((fabs(scrn_gamma * file_gamma - 1.0) > PNG_GAMMA_THRESHOLD) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA) ||
+ (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE))
+ png_ptr->transformations |= PNG_GAMMA;
+ png_ptr->gamma = (float)file_gamma;
+ png_ptr->screen_gamma = (float)scrn_gamma;
+}
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expand paletted images to RGB, expand grayscale images of
+ * less than 8-bit depth to 8-bit depth, and expand tRNS chunks
+ * to alpha channels.
+ */
+void PNGAPI
+png_set_expand(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_expand\n");
+ png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* GRR 19990627: the following three functions currently are identical
+ * to png_set_expand(). However, it is entirely reasonable that someone
+ * might wish to expand an indexed image to RGB but *not* expand a single,
+ * fully transtqparent palette entry to a full alpha channel--perhaps instead
+ * convert tRNS to the grayscale/RGB format (16-bit RGB value), or tqreplace
+ * the transtqparent color with a particular RGB value, or drop tRNS entirely.
+ * IOW, a future version of the library may make the transformations flag
+ * a bit more fine-grained, with separate bits for each of these three
+ * functions.
+ *
+ * More to the point, these functions make it obvious what libpng will be
+ * doing, whereas "expand" can (and does) mean any number of things.
+ */
+
+/* Expand paletted images to RGB. */
+void PNGAPI
+png_set_palette_to_rgb(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_expand\n");
+ png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand grayscale images of less than 8-bit depth to 8 bits. */
+void PNGAPI
+png_set_gray_1_2_4_to_8(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_expand\n");
+ png_ptr->transformations |= PNG_EXPAND;
+}
+
+/* Expand tRNS chunks to alpha channels. */
+void PNGAPI
+png_set_tRNS_to_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_expand\n");
+ png_ptr->transformations |= PNG_EXPAND;
+}
+#endif /* defined(PNG_READ_EXPAND_SUPPORTED) */
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+void PNGAPI
+png_set_gray_to_rgb(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_gray_to_rgb\n");
+ png_ptr->transformations |= PNG_GRAY_TO_RGB;
+}
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+#if defined(PNG_FLOATING_POINT_SUPPORTED)
+/* Convert a RGB image to a grayscale of the same width. This allows us,
+ * for example, to convert a 24 bpp RGB image into an 8 bpp grayscale image.
+ */
+
+void PNGAPI
+png_set_rgb_to_gray(png_structp png_ptr, int error_action, double red,
+ double green)
+{
+ int red_fixed = (int)((float)red*100000.0 + 0.5);
+ int green_fixed = (int)((float)green*100000.0 + 0.5);
+ png_set_rgb_to_gray_fixed(png_ptr, error_action, red_fixed, green_fixed);
+}
+#endif
+
+void PNGAPI
+png_set_rgb_to_gray_fixed(png_structp png_ptr, int error_action,
+ png_fixed_point red, png_fixed_point green)
+{
+ png_debug(1, "in png_set_rgb_to_gray\n");
+ switch(error_action)
+ {
+ case 1: png_ptr->transformations |= PNG_RGB_TO_GRAY;
+ break;
+ case 2: png_ptr->transformations |= PNG_RGB_TO_GRAY_WARN;
+ break;
+ case 3: png_ptr->transformations |= PNG_RGB_TO_GRAY_ERR;
+ }
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ png_ptr->transformations |= PNG_EXPAND;
+#else
+ {
+ png_warning(png_ptr, "Cannot do RGB_TO_GRAY without EXPAND_SUPPORTED.");
+ png_ptr->transformations &= ~PNG_RGB_TO_GRAY;
+ }
+#endif
+ {
+ png_uint_16 red_int, green_int;
+ if(red < 0 || green < 0)
+ {
+ red_int = 6968; /* .212671 * 32768 + .5 */
+ green_int = 23434; /* .715160 * 32768 + .5 */
+ }
+ else if(red + green < 100000L)
+ {
+ red_int = (png_uint_16)(((png_uint_32)red*32768L)/100000L);
+ green_int = (png_uint_16)(((png_uint_32)green*32768L)/100000L);
+ }
+ else
+ {
+ png_warning(png_ptr, "ignoring out of range rgb_to_gray coefficients");
+ red_int = 6968;
+ green_int = 23434;
+ }
+ png_ptr->rgb_to_gray_red_coeff = red_int;
+ png_ptr->rgb_to_gray_green_coeff = green_int;
+ png_ptr->rgb_to_gray_blue_coeff = (png_uint_16)(32768-red_int-green_int);
+ }
+}
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+void PNGAPI
+png_set_read_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+ read_user_transform_fn)
+{
+ png_debug(1, "in png_set_read_user_transform_fn\n");
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ png_ptr->transformations |= PNG_USER_TRANSFORM;
+ png_ptr->read_user_transform_fn = read_user_transform_fn;
+#endif
+#ifdef PNG_LEGACY_SUPPORTED
+ if(read_user_transform_fn)
+ png_warning(png_ptr,
+ "This version of libpng does not support user transforms");
+#endif
+}
+#endif
+
+/* Initialize everything needed for the read. This includes modifying
+ * the palette.
+ */
+void /* PRIVATE */
+png_init_read_transformations(png_structp png_ptr)
+{
+ png_debug(1, "in png_init_read_transformations\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if(png_ptr != NULL)
+#endif
+ {
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || defined(PNG_READ_SHIFT_SUPPORTED) \
+ || defined(PNG_READ_GAMMA_SUPPORTED)
+ int color_type = png_ptr->color_type;
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED) && defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if ((png_ptr->transformations & PNG_BACKGROUND_EXPAND) &&
+ (png_ptr->transformations & PNG_EXPAND))
+ {
+ if (!(color_type & PNG_COLOR_MASK_COLOR)) /* i.e., GRAY or GRAY_ALPHA */
+ {
+ /* expand background chunk. */
+ switch (png_ptr->bit_depth)
+ {
+ case 1:
+ png_ptr->background.gray *= (png_uint_16)0xff;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ break;
+ case 2:
+ png_ptr->background.gray *= (png_uint_16)0x55;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ break;
+ case 4:
+ png_ptr->background.gray *= (png_uint_16)0x11;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ break;
+ case 8:
+ case 16:
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ break;
+ }
+ }
+ else if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_ptr->background.red =
+ png_ptr->palette[png_ptr->background.index].red;
+ png_ptr->background.green =
+ png_ptr->palette[png_ptr->background.index].green;
+ png_ptr->background.blue =
+ png_ptr->palette[png_ptr->background.index].blue;
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ {
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ if (!(png_ptr->transformations & PNG_EXPAND))
+#endif
+ {
+ /* invert the alpha channel (in tRNS) unless the pixels are
+ going to be expanded, in which case leave it for later */
+ int i,istop;
+ istop=(int)png_ptr->num_trans;
+ for (i=0; i<istop; i++)
+ png_ptr->trans[i] = (png_byte)(255 - png_ptr->trans[i]);
+ }
+ }
+#endif
+
+ }
+ }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+ png_ptr->background_1 = png_ptr->background;
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+
+ if ((color_type == PNG_COLOR_TYPE_PALETTE && png_ptr->num_trans != 0)
+ && (fabs(png_ptr->screen_gamma * png_ptr->gamma - 1.0)
+ < PNG_GAMMA_THRESHOLD))
+ {
+ int i,k;
+ k=0;
+ for (i=0; i<png_ptr->num_trans; i++)
+ {
+ if (png_ptr->trans[i] != 0 && png_ptr->trans[i] != 0xff)
+ k=1; /* partial transparency is present */
+ }
+ if (k == 0)
+ png_ptr->transformations &= (~PNG_GAMMA);
+ }
+
+ if (png_ptr->transformations & (PNG_GAMMA | PNG_RGB_TO_GRAY))
+ {
+ png_build_gamma_table(png_ptr);
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->transformations & PNG_BACKGROUND)
+ {
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ /* could skip if no transparency and
+ */
+ png_color back, back_1;
+ png_colorp palette = png_ptr->palette;
+ int num_palette = png_ptr->num_palette;
+ int i;
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+ {
+ back.red = png_ptr->gamma_table[png_ptr->background.red];
+ back.green = png_ptr->gamma_table[png_ptr->background.green];
+ back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+ back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+ back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+ back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+ }
+ else
+ {
+ double g, gs;
+
+ switch (png_ptr->background_gamma_type)
+ {
+ case PNG_BACKGROUND_GAMMA_SCREEN:
+ g = (png_ptr->screen_gamma);
+ gs = 1.0;
+ break;
+ case PNG_BACKGROUND_GAMMA_FILE:
+ g = 1.0 / (png_ptr->gamma);
+ gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ break;
+ case PNG_BACKGROUND_GAMMA_UNITQUE:
+ g = 1.0 / (png_ptr->background_gamma);
+ gs = 1.0 / (png_ptr->background_gamma *
+ png_ptr->screen_gamma);
+ break;
+ default:
+ g = 1.0; /* back_1 */
+ gs = 1.0; /* back */
+ }
+
+ if ( fabs(gs - 1.0) < PNG_GAMMA_THRESHOLD)
+ {
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+ }
+ else
+ {
+ back.red = (png_byte)(pow(
+ (double)png_ptr->background.red/255, gs) * 255.0 + .5);
+ back.green = (png_byte)(pow(
+ (double)png_ptr->background.green/255, gs) * 255.0 + .5);
+ back.blue = (png_byte)(pow(
+ (double)png_ptr->background.blue/255, gs) * 255.0 + .5);
+ }
+
+ back_1.red = (png_byte)(pow(
+ (double)png_ptr->background.red/255, g) * 255.0 + .5);
+ back_1.green = (png_byte)(pow(
+ (double)png_ptr->background.green/255, g) * 255.0 + .5);
+ back_1.blue = (png_byte)(pow(
+ (double)png_ptr->background.blue/255, g) * 255.0 + .5);
+ }
+ for (i = 0; i < num_palette; i++)
+ {
+ if (i < (int)png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+ {
+ if (png_ptr->trans[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else /* if (png_ptr->trans[i] != 0xff) */
+ {
+ png_byte v, w;
+
+ v = png_ptr->gamma_to_1[palette[i].red];
+ png_composite(w, v, png_ptr->trans[i], back_1.red);
+ palette[i].red = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[palette[i].green];
+ png_composite(w, v, png_ptr->trans[i], back_1.green);
+ palette[i].green = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[palette[i].blue];
+ png_composite(w, v, png_ptr->trans[i], back_1.blue);
+ palette[i].blue = png_ptr->gamma_from_1[w];
+ }
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ }
+ /* if (png_ptr->background_gamma_type!=PNG_BACKGROUND_GAMMA_UNKNOWN) */
+ else
+ /* color_type != PNG_COLOR_TYPE_PALETTE */
+ {
+ double m = (double)(((png_uint_32)1 << png_ptr->bit_depth) - 1);
+ double g = 1.0;
+ double gs = 1.0;
+
+ switch (png_ptr->background_gamma_type)
+ {
+ case PNG_BACKGROUND_GAMMA_SCREEN:
+ g = (png_ptr->screen_gamma);
+ gs = 1.0;
+ break;
+ case PNG_BACKGROUND_GAMMA_FILE:
+ g = 1.0 / (png_ptr->gamma);
+ gs = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ break;
+ case PNG_BACKGROUND_GAMMA_UNITQUE:
+ g = 1.0 / (png_ptr->background_gamma);
+ gs = 1.0 / (png_ptr->background_gamma *
+ png_ptr->screen_gamma);
+ break;
+ }
+
+ png_ptr->background_1.gray = (png_uint_16)(pow(
+ (double)png_ptr->background.gray / m, g) * m + .5);
+ png_ptr->background.gray = (png_uint_16)(pow(
+ (double)png_ptr->background.gray / m, gs) * m + .5);
+
+ if ((png_ptr->background.red != png_ptr->background.green) ||
+ (png_ptr->background.red != png_ptr->background.blue) ||
+ (png_ptr->background.red != png_ptr->background.gray))
+ {
+ /* RGB or RGBA with color background */
+ png_ptr->background_1.red = (png_uint_16)(pow(
+ (double)png_ptr->background.red / m, g) * m + .5);
+ png_ptr->background_1.green = (png_uint_16)(pow(
+ (double)png_ptr->background.green / m, g) * m + .5);
+ png_ptr->background_1.blue = (png_uint_16)(pow(
+ (double)png_ptr->background.blue / m, g) * m + .5);
+ png_ptr->background.red = (png_uint_16)(pow(
+ (double)png_ptr->background.red / m, gs) * m + .5);
+ png_ptr->background.green = (png_uint_16)(pow(
+ (double)png_ptr->background.green / m, gs) * m + .5);
+ png_ptr->background.blue = (png_uint_16)(pow(
+ (double)png_ptr->background.blue / m, gs) * m + .5);
+ }
+ else
+ {
+ /* GRAY, GRAY ALPHA, RGB, or RGBA with gray background */
+ png_ptr->background_1.red = png_ptr->background_1.green
+ = png_ptr->background_1.blue = png_ptr->background_1.gray;
+ png_ptr->background.red = png_ptr->background.green
+ = png_ptr->background.blue = png_ptr->background.gray;
+ }
+ }
+ }
+ else
+ /* transformation does not include PNG_BACKGROUND */
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_colorp palette = png_ptr->palette;
+ int num_palette = png_ptr->num_palette;
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ else
+#endif
+#endif /* PNG_READ_GAMMA_SUPPORTED && PNG_FLOATING_POINT_SUPPORTED */
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ /* No GAMMA transformation */
+ if ((png_ptr->transformations & PNG_BACKGROUND) &&
+ (color_type == PNG_COLOR_TYPE_PALETTE))
+ {
+ int i;
+ int istop = (int)png_ptr->num_trans;
+ png_color back;
+ png_colorp palette = png_ptr->palette;
+
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+
+ for (i = 0; i < istop; i++)
+ {
+ if (png_ptr->trans[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else if (png_ptr->trans[i] != 0xff)
+ {
+ /* The png_composite() macro is defined in png.h */
+ png_composite(palette[i].red, palette[i].red,
+ png_ptr->trans[i], back.red);
+ png_composite(palette[i].green, palette[i].green,
+ png_ptr->trans[i], back.green);
+ png_composite(palette[i].blue, palette[i].blue,
+ png_ptr->trans[i], back.blue);
+ }
+ }
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED */
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+ if ((png_ptr->transformations & PNG_SHIFT) &&
+ (color_type == PNG_COLOR_TYPE_PALETTE))
+ {
+ png_uint_16 i;
+ png_uint_16 istop = png_ptr->num_palette;
+ int sr = 8 - png_ptr->sig_bit.red;
+ int sg = 8 - png_ptr->sig_bit.green;
+ int sb = 8 - png_ptr->sig_bit.blue;
+
+ if (sr < 0 || sr > 8)
+ sr = 0;
+ if (sg < 0 || sg > 8)
+ sg = 0;
+ if (sb < 0 || sb > 8)
+ sb = 0;
+ for (i = 0; i < istop; i++)
+ {
+ png_ptr->palette[i].red >>= sr;
+ png_ptr->palette[i].green >>= sg;
+ png_ptr->palette[i].blue >>= sb;
+ }
+ }
+#endif /* PNG_READ_SHIFT_SUPPORTED */
+ }
+#if !defined(PNG_READ_GAMMA_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED) \
+ && !defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if(png_ptr)
+ return;
+#endif
+}
+
+/* Modify the info structure to reflect the transformations. The
+ * info should be updated so a PNG file could be written with it,
+ * assuming the transformations result in valid PNG data.
+ */
+void /* PRIVATE */
+png_read_transform_info(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_read_transform_info\n");
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (png_ptr->num_trans)
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ else
+ info_ptr->color_type = PNG_COLOR_TYPE_RGB;
+ info_ptr->bit_depth = 8;
+ info_ptr->num_trans = 0;
+ }
+ else
+ {
+ if (png_ptr->num_trans)
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+ if (info_ptr->bit_depth < 8)
+ info_ptr->bit_depth = 8;
+ info_ptr->num_trans = 0;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->transformations & PNG_BACKGROUND)
+ {
+ info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+ info_ptr->num_trans = 0;
+ info_ptr->background = png_ptr->background;
+ }
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (png_ptr->transformations & PNG_GAMMA)
+ {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ info_ptr->gamma = png_ptr->gamma;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_gamma = png_ptr->int_gamma;
+#endif
+ }
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+ if ((png_ptr->transformations & PNG_16_TO_8) && (info_ptr->bit_depth == 16))
+ info_ptr->bit_depth = 8;
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+ if (png_ptr->transformations & PNG_DITHER)
+ {
+ if (((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)) &&
+ png_ptr->palette_lookup && info_ptr->bit_depth == 8)
+ {
+ info_ptr->color_type = PNG_COLOR_TYPE_PALETTE;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+ if ((png_ptr->transformations & PNG_PACK) && (info_ptr->bit_depth < 8))
+ info_ptr->bit_depth = 8;
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+ info_ptr->color_type |= PNG_COLOR_MASK_COLOR;
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ info_ptr->color_type &= ~PNG_COLOR_MASK_COLOR;
+#endif
+
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ info_ptr->channels = 1;
+ else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ info_ptr->channels = 3;
+ else
+ info_ptr->channels = 1;
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_STRIP_ALPHA)
+ info_ptr->color_type &= ~PNG_COLOR_MASK_ALPHA;
+#endif
+
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ info_ptr->channels++;
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+ /* STRIP_ALPHA and FILLER allowed: MASK_ALPHA bit stripped above */
+ if ((png_ptr->transformations & PNG_FILLER) &&
+ ((info_ptr->color_type == PNG_COLOR_TYPE_RGB) ||
+ (info_ptr->color_type == PNG_COLOR_TYPE_GRAY)))
+ {
+ info_ptr->channels++;
+#if 0 /* if adding a true alpha channel not just filler */
+ info_ptr->color_type |= PNG_COLOR_MASK_ALPHA;
+#endif
+ }
+#endif
+
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) && \
+defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ if(png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ if(info_ptr->bit_depth < png_ptr->user_transform_depth)
+ info_ptr->bit_depth = png_ptr->user_transform_depth;
+ if(info_ptr->channels < png_ptr->user_transform_channels)
+ info_ptr->channels = png_ptr->user_transform_channels;
+ }
+#endif
+
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels *
+ info_ptr->bit_depth);
+ info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
+
+#if !defined(PNG_READ_EXPAND_SUPPORTED)
+ if(png_ptr)
+ return;
+#endif
+}
+
+/* Transform the row. The order of transformations is significant,
+ * and is very touchy. If you add a transformation, take care to
+ * decide how it fits in with the other transformations here.
+ */
+void /* PRIVATE */
+png_do_read_transformations(png_structp png_ptr)
+{
+ png_debug(1, "in png_do_read_transformations\n");
+#if !defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (png_ptr->row_buf == NULL)
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char msg[50];
+
+ sprintf(msg, "NULL row buffer for row %ld, pass %d", png_ptr->row_number,
+ png_ptr->pass);
+ png_error(png_ptr, msg);
+#else
+ png_error(png_ptr, "NULL row buffer");
+#endif
+ }
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (png_ptr->row_info.color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_do_expand_palette(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->palette, png_ptr->trans, png_ptr->num_trans);
+ }
+ else
+ {
+ if (png_ptr->num_trans)
+ png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->trans_values));
+ else
+ png_do_expand(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ NULL);
+ }
+ }
+#endif
+
+#if defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_STRIP_ALPHA)
+ png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ PNG_FLAG_FILLER_AFTER);
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & PNG_RGB_TO_GRAY)
+ {
+ int rgb_error =
+ png_do_rgb_to_gray(png_ptr, &(png_ptr->row_info), png_ptr->row_buf + 1);
+ if(rgb_error)
+ {
+ png_ptr->rgb_to_gray_status=1;
+ if(png_ptr->transformations == PNG_RGB_TO_GRAY_WARN)
+ png_warning(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ if(png_ptr->transformations == PNG_RGB_TO_GRAY_ERR)
+ png_error(png_ptr, "png_do_rgb_to_gray found nongray pixel");
+ }
+ }
+#endif
+
+/*
+From Andreas Dilger e-mail to png-implement, 26 March 1998:
+
+ In most cases, the "simple transparency" should be done prior to doing
+ gray-to-RGB, or you will have to test 3x as many bytes to check if a
+ pixel is transtqparent. You would also need to make sure that the
+ transparency information is upgraded to RGB.
+
+ To summarize, the current flow is:
+ - Gray + simple transparency -> compare 1 or 2 gray bytes and composite
+ with background "in place" if transtqparent,
+ convert to RGB if necessary
+ - Gray + alpha -> composite with gray background and remove alpha bytes,
+ convert to RGB if necessary
+
+ To support RGB backgrounds for gray images we need:
+ - Gray + simple transparency -> convert to RGB + simple transparency, compare
+ 3 or 6 bytes and composite with background
+ "in place" if transtqparent (3x compare/pixel
+ compared to doing composite with gray bkgrnd)
+ - Gray + alpha -> convert to RGB + alpha, composite with background and
+ remove alpha bytes (3x float operations/pixel
+ compared with composite on gray background)
+
+ Greg's change will do this. The reason it wasn't done before is for
+ performance, as this increases the per-pixel operations. If we would check
+ in advance if the background was gray or RGB, and position the gray-to-RGB
+ transform appropriately, then it would save a lot of work/time.
+ */
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+ /* if gray -> RGB, do so now only if background is non-gray; else do later
+ * for performance reasons */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ !(png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+ png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if ((png_ptr->transformations & PNG_BACKGROUND) &&
+ ((png_ptr->num_trans != 0 ) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA)))
+ png_do_background(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->trans_values), &(png_ptr->background)
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ , &(png_ptr->background_1),
+ png_ptr->gamma_table, png_ptr->gamma_from_1,
+ png_ptr->gamma_to_1, png_ptr->gamma_16_table,
+ png_ptr->gamma_16_from_1, png_ptr->gamma_16_to_1,
+ png_ptr->gamma_shift
+#endif
+);
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if ((png_ptr->transformations & PNG_GAMMA) &&
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ !((png_ptr->transformations & PNG_BACKGROUND) &&
+ ((png_ptr->num_trans != 0) ||
+ (png_ptr->color_type & PNG_COLOR_MASK_ALPHA))) &&
+#endif
+ (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE))
+ png_do_gamma(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->gamma_table, png_ptr->gamma_16_table,
+ png_ptr->gamma_shift);
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+ if (png_ptr->transformations & PNG_16_TO_8)
+ png_do_chop(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+ if (png_ptr->transformations & PNG_DITHER)
+ {
+ png_do_dither((png_row_infop)&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->palette_lookup, png_ptr->dither_index);
+ if(png_ptr->row_info.rowbytes == (png_uint_32)0)
+ png_error(png_ptr, "png_do_dither returned rowbytes=0");
+ }
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_do_unshift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_do_unpack(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+ /* if gray -> RGB, do so now only if we did not do so above */
+ if ((png_ptr->transformations & PNG_GRAY_TO_RGB) &&
+ (png_ptr->mode & PNG_BACKGROUND_IS_GRAY))
+ png_do_gray_to_rgb(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_do_read_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->filler, png_ptr->flags);
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_read_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_ALPHA)
+ png_do_read_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ if(png_ptr->read_user_transform_fn != NULL)
+ (*(png_ptr->read_user_transform_fn)) /* user read transform function */
+ (png_ptr, /* png_ptr */
+ &(png_ptr->row_info), /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_uint_32 rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ if(png_ptr->user_transform_depth)
+ png_ptr->row_info.bit_depth = png_ptr->user_transform_depth;
+ if(png_ptr->user_transform_channels)
+ png_ptr->row_info.channels = png_ptr->user_transform_channels;
+#endif
+ png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+ png_ptr->row_info.channels);
+ png_ptr->row_info.rowbytes = (png_ptr->row_info.width *
+ png_ptr->row_info.pixel_depth+7)>>3;
+ }
+#endif
+
+}
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+/* Unpack pixels of 1, 2, or 4 bits per pixel into 1 byte per pixel,
+ * without changing the actual values. Thus, if you had a row with
+ * a bit depth of 1, you would end up with bytes that only contained
+ * the numbers 0 or 1. If you would rather they contain 0 and 255, use
+ * png_do_shift() after this.
+ */
+void /* PRIVATE */
+png_do_unpack(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_unpack\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
+#else
+ if (row_info->bit_depth < 8)
+#endif
+ {
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x01);
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+ case 2:
+ {
+
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 2);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x03);
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp = row + (png_size_t)((row_width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)row_width - 1;
+ png_uint_32 shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ *dp = (png_byte)((*sp >> shift) & 0x0f);
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_width * row_info->channels;
+ }
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED)
+/* Reverse the effects of png_do_shift. This routine merely shifts the
+ * pixels back to their significant bits values. Thus, if you have
+ * a row of bit depth 8, but only 5 are significant, this will shift
+ * the values back to 0 through 31.
+ */
+void /* PRIVATE */
+png_do_unshift(png_row_infop row_info, png_bytep row, png_color_8p sig_bits)
+{
+ png_debug(1, "in png_do_unshift\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL && sig_bits != NULL &&
+#endif
+ row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ int shift[4];
+ int channels = 0;
+ int c;
+ png_uint_16 value = 0;
+ png_uint_32 row_width = row_info->width;
+
+ if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ shift[channels++] = row_info->bit_depth - sig_bits->red;
+ shift[channels++] = row_info->bit_depth - sig_bits->green;
+ shift[channels++] = row_info->bit_depth - sig_bits->blue;
+ }
+ else
+ {
+ shift[channels++] = row_info->bit_depth - sig_bits->gray;
+ }
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ shift[channels++] = row_info->bit_depth - sig_bits->alpha;
+ }
+
+ for (c = 0; c < channels; c++)
+ {
+ if (shift[c] <= 0)
+ shift[c] = 0;
+ else
+ value = 1;
+ }
+
+ if (!value)
+ return;
+
+ switch (row_info->bit_depth)
+ {
+ case 2:
+ {
+ png_bytep bp;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (bp = row, i = 0; i < istop; i++)
+ {
+ *bp >>= 1;
+ *bp++ &= 0x55;
+ }
+ break;
+ }
+ case 4:
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_byte tqmask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
+ (png_byte)((int)0xf >> shift[0]));
+
+ for (i = 0; i < istop; i++)
+ {
+ *bp >>= shift[0];
+ *bp++ &= tqmask;
+ }
+ break;
+ }
+ case 8:
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_width * channels;
+
+ for (i = 0; i < istop; i++)
+ {
+ *bp++ >>= shift[i%channels];
+ }
+ break;
+ }
+ case 16:
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_width;
+
+ for (i = 0; i < istop; i++)
+ {
+ value = (png_uint_16)((*bp << 8) + *(bp + 1));
+ value >>= shift[i%channels];
+ *bp++ = (png_byte)(value >> 8);
+ *bp++ = (png_byte)(value & 0xff);
+ }
+ break;
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_16_TO_8_SUPPORTED)
+/* chop rows of bit depth 16 down to 8 */
+void /* PRIVATE */
+png_do_chop(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_chop\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
+#else
+ if (row_info->bit_depth == 16)
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->width * row_info->channels;
+
+ for (i = 0; i<istop; i++, sp += 2, dp++)
+ {
+#if defined(PNG_READ_16_TO_8_ACCURATE_SCALE_SUPPORTED)
+ /* This does a more accurate scaling of the 16-bit color
+ * value, rather than a simple low-byte truncation.
+ *
+ * What the ideal calculation should be:
+ * *dp = (((((png_uint_32)(*sp) << 8) |
+ * (png_uint_32)(*(sp + 1))) * 255 + 127) / (png_uint_32)65535L;
+ *
+ * GRR: no, I think this is what it really should be:
+ * *dp = (((((png_uint_32)(*sp) << 8) |
+ * (png_uint_32)(*(sp + 1))) + 128L) / (png_uint_32)257L;
+ *
+ * GRR: here's the exact calculation with shifts:
+ * temp = (((png_uint_32)(*sp) << 8) | (png_uint_32)(*(sp + 1))) + 128L;
+ * *dp = (temp - (temp >> 8)) >> 8;
+ *
+ * Approximate calculation with shift/add instead of multiply/divide:
+ * *dp = ((((png_uint_32)(*sp) << 8) |
+ * (png_uint_32)((int)(*(sp + 1)) - *sp)) + 128) >> 8;
+ *
+ * What we actually do to avoid extra shifting and conversion:
+ */
+
+ *dp = *sp + ((((int)(*(sp + 1)) - *sp) > 128) ? 1 : 0);
+#else
+ /* Simply discard the low order byte */
+ *dp = *sp;
+#endif
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = (png_byte)(8 * row_info->channels);
+ row_info->rowbytes = row_info->width * row_info->channels;
+ }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_read_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_swap_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This converts from RGBA to ARGB */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+ /* This converts from RRGGBBAA to AARRGGBB */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This converts from GA to AG */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save;
+ }
+ }
+ /* This converts from GGAA to AAGG */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_byte save[2];
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ save[0] = *(--sp);
+ save[1] = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = save[0];
+ *(--dp) = save[1];
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_read_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_invert_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This inverts the alpha channel in RGBA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+
+/* This does nothing:
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ We can tqreplace it with:
+*/
+ sp-=3;
+ dp=sp;
+ }
+ }
+ /* This inverts the alpha channel in RRGGBBAA */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = (png_byte)(255 - *(--sp));
+
+/* This does nothing:
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ We can tqreplace it with:
+*/
+ sp-=6;
+ dp=sp;
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This inverts the alpha channel in GA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = *(--sp);
+ }
+ }
+ /* This inverts the alpha channel in GGAA */
+ else
+ {
+ png_bytep sp = row + row_info->rowbytes;
+ png_bytep dp = sp;
+ png_uint_32 i;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = (png_byte)(255 - *(--sp));
+ *(--dp) = (png_byte)(255 - *(--sp));
+/*
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+*/
+ sp-=2;
+ dp=sp;
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+/* Add filler channel if we have RGB color */
+void /* PRIVATE */
+png_do_read_filler(png_row_infop row_info, png_bytep row,
+ png_uint_32 filler, png_uint_32 flags)
+{
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ png_byte hi_filler = (png_byte)((filler>>8) & 0xff);
+ png_byte lo_filler = (png_byte)(filler & 0xff);
+
+ png_debug(1, "in png_do_read_filler\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if(row_info->bit_depth == 8)
+ {
+ /* This changes the data from G to GX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ row_info->channels = 2;
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ /* This changes the data from G to XG */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 2;
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ }
+ else if(row_info->bit_depth == 16)
+ {
+ /* This changes the data from GG to GGXX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ row_info->channels = 2;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ /* This changes the data from GG to XXGG */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 2;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ }
+ } /* COLOR_TYPE == GRAY */
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if(row_info->bit_depth == 8)
+ {
+ /* This changes the data from RGB to RGBX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = lo_filler;
+ row_info->channels = 4;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ /* This changes the data from RGB to XRGB */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 3;
+ png_bytep dp = sp + (png_size_t)row_width;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 4;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ }
+ }
+ else if(row_info->bit_depth == 16)
+ {
+ /* This changes the data from RRGGBB to RRGGBBXX */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ }
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ row_info->channels = 4;
+ row_info->pixel_depth = 64;
+ row_info->rowbytes = row_width * 8;
+ }
+ /* This changes the data from RRGGBB to XXRRGGBB */
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 6;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = *(--sp);
+ *(--dp) = hi_filler;
+ *(--dp) = lo_filler;
+ }
+ row_info->channels = 4;
+ row_info->pixel_depth = 64;
+ row_info->rowbytes = row_width * 8;
+ }
+ }
+ } /* COLOR_TYPE == RGB */
+}
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+/* expand grayscale files to RGB, with or without alpha */
+void /* PRIVATE */
+png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
+{
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ png_debug(1, "in png_do_gray_to_rgb\n");
+ if (row_info->bit_depth >= 8 &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ !(row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + (png_size_t)row_width - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *sp;
+ *(dp--) = *sp;
+ *(dp--) = *(sp--);
+ }
+ }
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp = row + (png_size_t)row_width * 2 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 2;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *(sp--);
+ *(dp--) = *sp;
+ *(dp--) = *sp;
+ *(dp--) = *(sp--);
+ }
+ }
+ else
+ {
+ png_bytep sp = row + (png_size_t)row_width * 4 - 1;
+ png_bytep dp = sp + (png_size_t)row_width * 4;
+ for (i = 0; i < row_width; i++)
+ {
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *sp;
+ *(dp--) = *(sp - 1);
+ *(dp--) = *(sp--);
+ *(dp--) = *(sp--);
+ }
+ }
+ }
+ row_info->channels += (png_byte)2;
+ row_info->color_type |= PNG_COLOR_MASK_COLOR;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = ((row_width *
+ row_info->pixel_depth + 7) >> 3);
+ }
+}
+#endif
+
+#if defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+/* reduce RGB files to grayscale, with or without alpha
+ * using the equation given in Poynton's ColorFAQ at
+ * <http://www.inforamp.net/~poynton/>
+ * Copyright (c) 1998-01-04 Charles Poynton poynton@inforamp.net
+ *
+ * Y = 0.212671 * R + 0.715160 * G + 0.072169 * B
+ *
+ * We approximate this with
+ *
+ * Y = 0.21268 * R + 0.7151 * G + 0.07217 * B
+ *
+ * which can be expressed with integers as
+ *
+ * Y = (6969 * R + 23434 * G + 2365 * B)/32768
+ *
+ * The calculation is to be done in a linear colorspace.
+ *
+ * Other integer coefficents can be used via png_set_rgb_to_gray().
+ */
+int /* PRIVATE */
+png_do_rgb_to_gray(png_structp png_ptr, png_row_infop row_info, png_bytep row)
+
+{
+ png_uint_32 i;
+
+ png_uint_32 row_width = row_info->width;
+ int rgb_error = 0;
+
+ png_debug(1, "in png_do_rgb_to_gray\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ png_uint_32 rc = png_ptr->rgb_to_gray_red_coeff;
+ png_uint_32 gc = png_ptr->rgb_to_gray_green_coeff;
+ png_uint_32 bc = png_ptr->rgb_to_gray_blue_coeff;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = png_ptr->gamma_to_1[*(sp++)];
+ png_byte green = png_ptr->gamma_to_1[*(sp++)];
+ png_byte blue = png_ptr->gamma_to_1[*(sp++)];
+ if(red != green || red != blue)
+ {
+ rgb_error |= 1;
+ *(dp++) = png_ptr->gamma_from_1[
+ (rc*red+gc*green+bc*blue)>>15];
+ }
+ else
+ *(dp++) = *(sp-1);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = *(sp++);
+ png_byte green = *(sp++);
+ png_byte blue = *(sp++);
+ if(red != green || red != blue)
+ {
+ rgb_error |= 1;
+ *(dp++) = (png_byte)((rc*red+gc*green+bc*blue)>>15);
+ }
+ else
+ *(dp++) = *(sp-1);
+ }
+ }
+ }
+
+ else /* RGB bit_depth == 16 */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_16_to_1 != NULL &&
+ png_ptr->gamma_16_from_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, w;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+ if(red == green && red == blue)
+ w = red;
+ else
+ {
+ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
+ png_ptr->gamma_shift][red>>8];
+ png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
+ png_ptr->gamma_shift][green>>8];
+ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
+ png_ptr->gamma_shift][blue>>8];
+ png_uint_16 gray16 = (png_uint_16)((rc*red_1 + gc*green_1
+ + bc*blue_1)>>15);
+ w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+ png_ptr->gamma_shift][gray16 >> 8];
+ rgb_error |= 1;
+ }
+
+ *(dp++) = (png_byte)((w>>8) & 0xff);
+ *(dp++) = (png_byte)(w & 0xff);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, gray16;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+ if(red != green || red != blue)
+ rgb_error |= 1;
+ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+ *(dp++) = (png_byte)((gray16>>8) & 0xff);
+ *(dp++) = (png_byte)(gray16 & 0xff);
+ }
+ }
+ }
+ }
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_from_1 != NULL && png_ptr->gamma_to_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = png_ptr->gamma_to_1[*(sp++)];
+ png_byte green = png_ptr->gamma_to_1[*(sp++)];
+ png_byte blue = png_ptr->gamma_to_1[*(sp++)];
+ if(red != green || red != blue)
+ rgb_error |= 1;
+ *(dp++) = png_ptr->gamma_from_1
+ [(rc*red + gc*green + bc*blue)>>15];
+ *(dp++) = *(sp++); /* alpha */
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte red = *(sp++);
+ png_byte green = *(sp++);
+ png_byte blue = *(sp++);
+ if(red != green || red != blue)
+ rgb_error |= 1;
+ *(dp++) = (png_byte)((gc*red + gc*green + bc*blue)>>8);
+ *(dp++) = *(sp++); /* alpha */
+ }
+ }
+ }
+ else /* RGBA bit_depth == 16 */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED) || defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->gamma_16_to_1 != NULL &&
+ png_ptr->gamma_16_from_1 != NULL)
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, w;
+
+ red = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)(((*(sp))<<8) | *(sp+1)); sp+=2;
+
+ if(red == green && red == blue)
+ w = red;
+ else
+ {
+ png_uint_16 red_1 = png_ptr->gamma_16_to_1[(red&0xff) >>
+ png_ptr->gamma_shift][red>>8];
+ png_uint_16 green_1 = png_ptr->gamma_16_to_1[(green&0xff) >>
+ png_ptr->gamma_shift][green>>8];
+ png_uint_16 blue_1 = png_ptr->gamma_16_to_1[(blue&0xff) >>
+ png_ptr->gamma_shift][blue>>8];
+ png_uint_16 gray16 = (png_uint_16)((rc * red_1
+ + gc * green_1 + bc * blue_1)>>15);
+ w = png_ptr->gamma_16_from_1[(gray16&0xff) >>
+ png_ptr->gamma_shift][gray16 >> 8];
+ rgb_error |= 1;
+ }
+
+ *(dp++) = (png_byte)((w>>8) & 0xff);
+ *(dp++) = (png_byte)(w & 0xff);
+ *(dp++) = *(sp++); /* alpha */
+ *(dp++) = *(sp++);
+ }
+ }
+ else
+#endif
+ {
+ png_bytep sp = row;
+ png_bytep dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 red, green, blue, gray16;
+ red = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+ green = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+ blue = (png_uint_16)((*(sp)<<8) | *(sp+1)); sp+=2;
+ if(red != green || red != blue)
+ rgb_error |= 1;
+ gray16 = (png_uint_16)((rc*red + gc*green + bc*blue)>>15);
+ *(dp++) = (png_byte)((gray16>>8) & 0xff);
+ *(dp++) = (png_byte)(gray16 & 0xff);
+ *(dp++) = *(sp++); /* alpha */
+ *(dp++) = *(sp++);
+ }
+ }
+ }
+ }
+ row_info->channels -= (png_byte)2;
+ row_info->color_type &= ~PNG_COLOR_MASK_COLOR;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = ((row_width *
+ row_info->pixel_depth + 7) >> 3);
+ }
+ return rgb_error;
+}
+#endif
+
+/* Build a grayscale palette. Palette is assumed to be 1 << bit_depth
+ * large of png_color. This lets grayscale images be treated as
+ * paletted. Most useful for gamma correction and simplification
+ * of code.
+ */
+void PNGAPI
+png_build_grayscale_palette(int bit_depth, png_colorp palette)
+{
+ int num_palette;
+ int color_inc;
+ int i;
+ int v;
+
+ png_debug(1, "in png_do_build_grayscale_palette\n");
+ if (palette == NULL)
+ return;
+
+ switch (bit_depth)
+ {
+ case 1:
+ num_palette = 2;
+ color_inc = 0xff;
+ break;
+ case 2:
+ num_palette = 4;
+ color_inc = 0x55;
+ break;
+ case 4:
+ num_palette = 16;
+ color_inc = 0x11;
+ break;
+ case 8:
+ num_palette = 256;
+ color_inc = 1;
+ break;
+ default:
+ num_palette = 0;
+ color_inc = 0;
+ break;
+ }
+
+ for (i = 0, v = 0; i < num_palette; i++, v += color_inc)
+ {
+ palette[i].red = (png_byte)v;
+ palette[i].green = (png_byte)v;
+ palette[i].blue = (png_byte)v;
+ }
+}
+
+/* This function is currently unused. Do we really need it? */
+#if defined(PNG_READ_DITHER_SUPPORTED) && defined(PNG_CORRECT_PALETTE_SUPPORTED)
+void /* PRIVATE */
+png_correct_palette(png_structp png_ptr, png_colorp palette,
+ int num_palette)
+{
+ png_debug(1, "in png_correct_palette\n");
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) && \
+ defined(PNG_READ_GAMMA_SUPPORTED) && defined(PNG_FLOATING_POINT_SUPPORTED)
+ if (png_ptr->transformations & (PNG_GAMMA | PNG_BACKGROUND))
+ {
+ png_color back, back_1;
+
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_FILE)
+ {
+ back.red = png_ptr->gamma_table[png_ptr->background.red];
+ back.green = png_ptr->gamma_table[png_ptr->background.green];
+ back.blue = png_ptr->gamma_table[png_ptr->background.blue];
+
+ back_1.red = png_ptr->gamma_to_1[png_ptr->background.red];
+ back_1.green = png_ptr->gamma_to_1[png_ptr->background.green];
+ back_1.blue = png_ptr->gamma_to_1[png_ptr->background.blue];
+ }
+ else
+ {
+ double g;
+
+ g = 1.0 / (png_ptr->background_gamma * png_ptr->screen_gamma);
+
+ if (png_ptr->background_gamma_type == PNG_BACKGROUND_GAMMA_SCREEN ||
+ fabs(g - 1.0) < PNG_GAMMA_THRESHOLD)
+ {
+ back.red = png_ptr->background.red;
+ back.green = png_ptr->background.green;
+ back.blue = png_ptr->background.blue;
+ }
+ else
+ {
+ back.red =
+ (png_byte)(pow((double)png_ptr->background.red/255, g) *
+ 255.0 + 0.5);
+ back.green =
+ (png_byte)(pow((double)png_ptr->background.green/255, g) *
+ 255.0 + 0.5);
+ back.blue =
+ (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+ 255.0 + 0.5);
+ }
+
+ g = 1.0 / png_ptr->background_gamma;
+
+ back_1.red =
+ (png_byte)(pow((double)png_ptr->background.red/255, g) *
+ 255.0 + 0.5);
+ back_1.green =
+ (png_byte)(pow((double)png_ptr->background.green/255, g) *
+ 255.0 + 0.5);
+ back_1.blue =
+ (png_byte)(pow((double)png_ptr->background.blue/255, g) *
+ 255.0 + 0.5);
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_uint_32 i;
+
+ for (i = 0; i < (png_uint_32)num_palette; i++)
+ {
+ if (i < png_ptr->num_trans && png_ptr->trans[i] == 0)
+ {
+ palette[i] = back;
+ }
+ else if (i < png_ptr->num_trans && png_ptr->trans[i] != 0xff)
+ {
+ png_byte v, w;
+
+ v = png_ptr->gamma_to_1[png_ptr->palette[i].red];
+ png_composite(w, v, png_ptr->trans[i], back_1.red);
+ palette[i].red = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[png_ptr->palette[i].green];
+ png_composite(w, v, png_ptr->trans[i], back_1.green);
+ palette[i].green = png_ptr->gamma_from_1[w];
+
+ v = png_ptr->gamma_to_1[png_ptr->palette[i].blue];
+ png_composite(w, v, png_ptr->trans[i], back_1.blue);
+ palette[i].blue = png_ptr->gamma_from_1[w];
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ }
+ else
+ {
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ if (palette[i].red == (png_byte)png_ptr->trans_values.gray)
+ {
+ palette[i] = back;
+ }
+ else
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+ }
+ }
+ else
+#endif
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (png_ptr->transformations & PNG_GAMMA)
+ {
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ palette[i].red = png_ptr->gamma_table[palette[i].red];
+ palette[i].green = png_ptr->gamma_table[palette[i].green];
+ palette[i].blue = png_ptr->gamma_table[palette[i].blue];
+ }
+ }
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ else
+#endif
+#endif
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+ if (png_ptr->transformations & PNG_BACKGROUND)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_color back;
+
+ back.red = (png_byte)png_ptr->background.red;
+ back.green = (png_byte)png_ptr->background.green;
+ back.blue = (png_byte)png_ptr->background.blue;
+
+ for (i = 0; i < (int)png_ptr->num_trans; i++)
+ {
+ if (png_ptr->trans[i] == 0)
+ {
+ palette[i].red = back.red;
+ palette[i].green = back.green;
+ palette[i].blue = back.blue;
+ }
+ else if (png_ptr->trans[i] != 0xff)
+ {
+ png_composite(palette[i].red, png_ptr->palette[i].red,
+ png_ptr->trans[i], back.red);
+ png_composite(palette[i].green, png_ptr->palette[i].green,
+ png_ptr->trans[i], back.green);
+ png_composite(palette[i].blue, png_ptr->palette[i].blue,
+ png_ptr->trans[i], back.blue);
+ }
+ }
+ }
+ else /* assume grayscale palette (what else could it be?) */
+ {
+ int i;
+
+ for (i = 0; i < num_palette; i++)
+ {
+ if (i == (png_byte)png_ptr->trans_values.gray)
+ {
+ palette[i].red = (png_byte)png_ptr->background.red;
+ palette[i].green = (png_byte)png_ptr->background.green;
+ palette[i].blue = (png_byte)png_ptr->background.blue;
+ }
+ }
+ }
+ }
+#endif
+}
+#endif
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED)
+/* Replace any alpha or transparency with the supplied background color.
+ * "background" is already in the screen gamma, while "background_1" is
+ * at a gamma of 1.0. Paletted files have already been taken care of.
+ */
+void /* PRIVATE */
+png_do_background(png_row_infop row_info, png_bytep row,
+ png_color_16p trans_values, png_color_16p background
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ , png_color_16p background_1,
+ png_bytep gamma_table, png_bytep gamma_from_1, png_bytep gamma_to_1,
+ png_uint_16pp gamma_16, png_uint_16pp gamma_16_from_1,
+ png_uint_16pp gamma_16_to_1, int gamma_shift
+#endif
+ )
+{
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+ int shift;
+
+ png_debug(1, "in png_do_background\n");
+ if (background != NULL &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ (!(row_info->color_type & PNG_COLOR_MASK_ALPHA) ||
+ (row_info->color_type != PNG_COLOR_TYPE_PALETTE && trans_values)))
+ {
+ switch (row_info->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ sp = row;
+ shift = 7;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x01)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ if (!shift)
+ {
+ shift = 7;
+ sp++;
+ }
+ else
+ shift--;
+ }
+ break;
+ }
+ case 2:
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ else
+ {
+ png_byte p = (png_byte)((*sp >> shift) & 0x03);
+ png_byte g = (png_byte)((gamma_table [p | (p << 2) |
+ (p << 4) | (p << 6)] >> 6) & 0x03);
+ *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *sp |= (png_byte)(g << shift);
+ }
+ if (!shift)
+ {
+ shift = 6;
+ sp++;
+ }
+ else
+ shift -= 2;
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ shift = 6;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x03)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ if (!shift)
+ {
+ shift = 6;
+ sp++;
+ }
+ else
+ shift -= 2;
+ }
+ }
+ break;
+ }
+ case 4:
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ else
+ {
+ png_byte p = (png_byte)((*sp >> shift) & 0x0f);
+ png_byte g = (png_byte)((gamma_table[p |
+ (p << 4)] >> 4) & 0x0f);
+ *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *sp |= (png_byte)(g << shift);
+ }
+ if (!shift)
+ {
+ shift = 4;
+ sp++;
+ }
+ else
+ shift -= 4;
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ shift = 4;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((png_uint_16)((*sp >> shift) & 0x0f)
+ == trans_values->gray)
+ {
+ *sp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *sp |= (png_byte)(background->gray << shift);
+ }
+ if (!shift)
+ {
+ shift = 4;
+ sp++;
+ }
+ else
+ shift -= 4;
+ }
+ }
+ break;
+ }
+ case 8:
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == trans_values->gray)
+ {
+ *sp = (png_byte)background->gray;
+ }
+ else
+ {
+ *sp = gamma_table[*sp];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ if (*sp == trans_values->gray)
+ {
+ *sp = (png_byte)background->gray;
+ }
+ }
+ }
+ break;
+ }
+ case 16:
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ if (v == trans_values->gray)
+ {
+ /* background is already in screen gamma */
+ *sp = (png_byte)((background->gray >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->gray & 0xff);
+ }
+ else
+ {
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 2)
+ {
+ png_uint_16 v;
+
+ v = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ if (v == trans_values->gray)
+ {
+ *sp = (png_byte)((background->gray >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->gray & 0xff);
+ }
+ }
+ }
+ break;
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_table != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 3)
+ {
+ if (*sp == trans_values->red &&
+ *(sp + 1) == trans_values->green &&
+ *(sp + 2) == trans_values->blue)
+ {
+ *sp = (png_byte)background->red;
+ *(sp + 1) = (png_byte)background->green;
+ *(sp + 2) = (png_byte)background->blue;
+ }
+ else
+ {
+ *sp = gamma_table[*sp];
+ *(sp + 1) = gamma_table[*(sp + 1)];
+ *(sp + 2) = gamma_table[*(sp + 2)];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 3)
+ {
+ if (*sp == trans_values->red &&
+ *(sp + 1) == trans_values->green &&
+ *(sp + 2) == trans_values->blue)
+ {
+ *sp = (png_byte)background->red;
+ *(sp + 1) = (png_byte)background->green;
+ *(sp + 2) = (png_byte)background->blue;
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_16 != NULL)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+ png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
+ if (r == trans_values->red && g == trans_values->green &&
+ b == trans_values->blue)
+ {
+ /* background is already in screen gamma */
+ *sp = (png_byte)((background->red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->red & 0xff);
+ *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(background->green & 0xff);
+ *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ else
+ {
+ png_uint_16 v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(sp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(sp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp += 6)
+ {
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp+1));
+ png_uint_16 g = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+ png_uint_16 b = (png_uint_16)(((*(sp+4)) << 8) + *(sp+5));
+
+ if (r == trans_values->red && g == trans_values->green &&
+ b == trans_values->blue)
+ {
+ *sp = (png_byte)((background->red >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(background->red & 0xff);
+ *(sp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(sp + 3) = (png_byte)(background->green & 0xff);
+ *(sp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(sp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 2, dp++)
+ {
+ png_uint_16 a = *(sp + 1);
+
+ if (a == 0xff)
+ {
+ *dp = gamma_table[*sp];
+ }
+ else if (a == 0)
+ {
+ /* background is already in screen gamma */
+ *dp = (png_byte)background->gray;
+ }
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, background_1->gray);
+ *dp = gamma_from_1[w];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 2, dp++)
+ {
+ png_byte a = *(sp + 1);
+
+ if (a == 0xff)
+ {
+ *dp = *sp;
+ }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ else if (a == 0)
+ {
+ *dp = (png_byte)background->gray;
+ }
+ else
+ {
+ png_composite(*dp, *sp, a, background_1->gray);
+ }
+#else
+ *dp = (png_byte)background->gray;
+#endif
+ }
+ }
+ }
+ else /* if (png_ptr->bit_depth == 16) */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 2)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ else if (a == 0)
+#else
+ else
+#endif
+ {
+ /* background is already in screen gamma */
+ *dp = (png_byte)((background->gray >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->gray & 0xff);
+ }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ else
+ {
+ png_uint_16 g, v, w;
+
+ g = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(v, g, a, background_1->gray);
+ w = gamma_16_from_1[(v&0xff) >> gamma_shift][v >> 8];
+ *dp = (png_byte)((w >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(w & 0xff);
+ }
+#endif
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 2)
+ {
+ png_uint_16 a = (png_uint_16)(((*(sp+2)) << 8) + *(sp+3));
+ if (a == (png_uint_16)0xffff)
+ {
+ png_memcpy(dp, sp, 2);
+ }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ else if (a == 0)
+#else
+ else
+#endif
+ {
+ *dp = (png_byte)((background->gray >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->gray & 0xff);
+ }
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ else
+ {
+ png_uint_16 g, v;
+
+ g = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_composite_16(v, g, a, background_1->gray);
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ }
+#endif
+ }
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_to_1 != NULL && gamma_from_1 != NULL &&
+ gamma_table != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 3)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0xff)
+ {
+ *dp = gamma_table[*sp];
+ *(dp + 1) = gamma_table[*(sp + 1)];
+ *(dp + 2) = gamma_table[*(sp + 2)];
+ }
+ else if (a == 0)
+ {
+ /* background is already in screen gamma */
+ *dp = (png_byte)background->red;
+ *(dp + 1) = (png_byte)background->green;
+ *(dp + 2) = (png_byte)background->blue;
+ }
+ else
+ {
+ png_byte v, w;
+
+ v = gamma_to_1[*sp];
+ png_composite(w, v, a, background_1->red);
+ *dp = gamma_from_1[w];
+ v = gamma_to_1[*(sp + 1)];
+ png_composite(w, v, a, background_1->green);
+ *(dp + 1) = gamma_from_1[w];
+ v = gamma_to_1[*(sp + 2)];
+ png_composite(w, v, a, background_1->blue);
+ *(dp + 2) = gamma_from_1[w];
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 4, dp += 3)
+ {
+ png_byte a = *(sp + 3);
+
+ if (a == 0xff)
+ {
+ *dp = *sp;
+ *(dp + 1) = *(sp + 1);
+ *(dp + 2) = *(sp + 2);
+ }
+ else if (a == 0)
+ {
+ *dp = (png_byte)background->red;
+ *(dp + 1) = (png_byte)background->green;
+ *(dp + 2) = (png_byte)background->blue;
+ }
+ else
+ {
+ png_composite(*dp, *sp, a, background->red);
+ png_composite(*(dp + 1), *(sp + 1), a,
+ background->green);
+ png_composite(*(dp + 2), *(sp + 2), a,
+ background->blue);
+ }
+ }
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+ if (gamma_16 != NULL && gamma_16_from_1 != NULL &&
+ gamma_16_to_1 != NULL)
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 8, dp += 6)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+ if (a == (png_uint_16)0xffff)
+ {
+ png_uint_16 v;
+
+ v = gamma_16[*(sp + 1) >> gamma_shift][*sp];
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(v & 0xff);
+ v = gamma_16[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(v & 0xff);
+ }
+ else if (a == 0)
+ {
+ /* background is already in screen gamma */
+ *dp = (png_byte)((background->red >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->red & 0xff);
+ *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(background->green & 0xff);
+ *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ else
+ {
+ png_uint_16 v, w, x;
+
+ v = gamma_16_to_1[*(sp + 1) >> gamma_shift][*sp];
+ png_composite_16(w, v, a, background_1->red);
+ x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+ *dp = (png_byte)((x >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(x & 0xff);
+ v = gamma_16_to_1[*(sp + 3) >> gamma_shift][*(sp + 2)];
+ png_composite_16(w, v, a, background_1->green);
+ x = gamma_16_from_1[((w&0xff) >> gamma_shift)][w >> 8];
+ *(dp + 2) = (png_byte)((x >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(x & 0xff);
+ v = gamma_16_to_1[*(sp + 5) >> gamma_shift][*(sp + 4)];
+ png_composite_16(w, v, a, background_1->blue);
+ x = gamma_16_from_1[(w & 0xff) >> gamma_shift][w >> 8];
+ *(dp + 4) = (png_byte)((x >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(x & 0xff);
+ }
+ }
+ }
+ else
+#endif
+ {
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++, sp += 8, dp += 6)
+ {
+ png_uint_16 a = (png_uint_16)(((png_uint_16)(*(sp + 6))
+ << 8) + (png_uint_16)(*(sp + 7)));
+ if (a == (png_uint_16)0xffff)
+ {
+ png_memcpy(dp, sp, 6);
+ }
+ else if (a == 0)
+ {
+ *dp = (png_byte)((background->red >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(background->red & 0xff);
+ *(dp + 2) = (png_byte)((background->green >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(background->green & 0xff);
+ *(dp + 4) = (png_byte)((background->blue >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(background->blue & 0xff);
+ }
+ else
+ {
+ png_uint_16 v;
+
+ png_uint_16 r = (png_uint_16)(((*sp) << 8) + *(sp + 1));
+ png_uint_16 g = (png_uint_16)(((*(sp + 2)) << 8)
+ + *(sp + 3));
+ png_uint_16 b = (png_uint_16)(((*(sp + 4)) << 8)
+ + *(sp + 5));
+
+ png_composite_16(v, r, a, background->red);
+ *dp = (png_byte)((v >> 8) & 0xff);
+ *(dp + 1) = (png_byte)(v & 0xff);
+ png_composite_16(v, g, a, background->green);
+ *(dp + 2) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 3) = (png_byte)(v & 0xff);
+ png_composite_16(v, b, a, background->blue);
+ *(dp + 4) = (png_byte)((v >> 8) & 0xff);
+ *(dp + 5) = (png_byte)(v & 0xff);
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+ row_info->channels--;
+ row_info->pixel_depth = (png_byte)(row_info->channels *
+ row_info->bit_depth);
+ row_info->rowbytes = ((row_width *
+ row_info->pixel_depth + 7) >> 3);
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+/* Gamma correct the image, avoiding the alpha channel. Make sure
+ * you do this after you deal with the transparency issue on grayscale
+ * or RGB images. If your bit depth is 8, use gamma_table, if it
+ * is 16, use gamma_16_table and gamma_shift. Build these with
+ * build_gamma_table().
+ */
+void /* PRIVATE */
+png_do_gamma(png_row_infop row_info, png_bytep row,
+ png_bytep gamma_table, png_uint_16pp gamma_16_table,
+ int gamma_shift)
+{
+ png_bytep sp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_gamma\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ ((row_info->bit_depth <= 8 && gamma_table != NULL) ||
+ (row_info->bit_depth == 16 && gamma_16_table != NULL)))
+ {
+ switch (row_info->color_type)
+ {
+ case PNG_COLOR_TYPE_RGB:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v;
+
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ *sp = gamma_table[*sp];
+ sp++;
+ sp++;
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 4;
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp += 2;
+ }
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 4;
+ }
+ }
+ break;
+ }
+ case PNG_COLOR_TYPE_GRAY:
+ {
+ if (row_info->bit_depth == 2)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i += 4)
+ {
+ int a = *sp & 0xc0;
+ int b = *sp & 0x30;
+ int c = *sp & 0x0c;
+ int d = *sp & 0x03;
+
+ *sp = (png_byte)(
+ ((((int)gamma_table[a|(a>>2)|(a>>4)|(a>>6)]) ) & 0xc0)|
+ ((((int)gamma_table[(b<<2)|b|(b>>2)|(b>>4)])>>2) & 0x30)|
+ ((((int)gamma_table[(c<<4)|(c<<2)|c|(c>>2)])>>4) & 0x0c)|
+ ((((int)gamma_table[(d<<6)|(d<<4)|(d<<2)|d])>>6) ));
+ sp++;
+ }
+ }
+ if (row_info->bit_depth == 4)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i += 2)
+ {
+ int msb = *sp & 0xf0;
+ int lsb = *sp & 0x0f;
+
+ *sp = (png_byte)((((int)gamma_table[msb | (msb >> 4)]) & 0xf0)
+ | (((int)gamma_table[(lsb << 4) | lsb]) >> 4));
+ sp++;
+ }
+ }
+ else if (row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ *sp = gamma_table[*sp];
+ sp++;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ png_uint_16 v = gamma_16_table[*(sp + 1) >> gamma_shift][*sp];
+ *sp = (png_byte)((v >> 8) & 0xff);
+ *(sp + 1) = (png_byte)(v & 0xff);
+ sp += 2;
+ }
+ }
+ break;
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+/* Expands a palette row to an RGB or RGBA row depending
+ * upon whether you supply trans and num_trans.
+ */
+void /* PRIVATE */
+png_do_expand_palette(png_row_infop row_info, png_bytep row,
+ png_colorp palette, png_bytep trans, int num_trans)
+{
+ int shift, value;
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_expand_palette\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (row_info->bit_depth < 8)
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp >> shift) & 0x01)
+ *dp = 1;
+ else
+ *dp = 0;
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+ case 2:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)value;
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+ case 4:
+ {
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((row_width & 0x01) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)value;
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 4;
+
+ dp--;
+ }
+ break;
+ }
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+ switch (row_info->bit_depth)
+ {
+ case 8:
+ {
+ if (trans != NULL)
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width << 2) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if ((int)(*sp) >= num_trans)
+ *dp-- = 0xff;
+ else
+ *dp-- = trans[*sp];
+ *dp-- = palette[*sp].blue;
+ *dp-- = palette[*sp].green;
+ *dp-- = palette[*sp].red;
+ sp--;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 32;
+ row_info->rowbytes = row_width * 4;
+ row_info->color_type = 6;
+ row_info->channels = 4;
+ }
+ else
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width * 3) - 1;
+
+ for (i = 0; i < row_width; i++)
+ {
+ *dp-- = palette[*sp].blue;
+ *dp-- = palette[*sp].green;
+ *dp-- = palette[*sp].red;
+ sp--;
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 24;
+ row_info->rowbytes = row_width * 3;
+ row_info->color_type = 2;
+ row_info->channels = 3;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* If the bit depth < 8, it is expanded to 8. Also, if the
+ * transparency value is supplied, an alpha channel is built.
+ */
+void /* PRIVATE */
+png_do_expand(png_row_infop row_info, png_bytep row,
+ png_color_16p trans_value)
+{
+ int shift, value;
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_expand\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_uint_16 gray = (png_uint_16)(trans_value ? trans_value->gray : 0);
+
+ if (row_info->bit_depth < 8)
+ {
+ switch (row_info->bit_depth)
+ {
+ case 1:
+ {
+ gray = (png_uint_16)(gray*0xff);
+ sp = row + (png_size_t)((row_width - 1) >> 3);
+ dp = row + (png_size_t)row_width - 1;
+ shift = 7 - (int)((row_width + 7) & 0x07);
+ for (i = 0; i < row_width; i++)
+ {
+ if ((*sp >> shift) & 0x01)
+ *dp = 0xff;
+ else
+ *dp = 0;
+ if (shift == 7)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift++;
+
+ dp--;
+ }
+ break;
+ }
+ case 2:
+ {
+ gray = (png_uint_16)(gray*0x55);
+ sp = row + (png_size_t)((row_width - 1) >> 2);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((3 - ((row_width + 3) & 0x03)) << 1);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp = (png_byte)(value | (value << 2) | (value << 4) |
+ (value << 6));
+ if (shift == 6)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift += 2;
+
+ dp--;
+ }
+ break;
+ }
+ case 4:
+ {
+ gray = (png_uint_16)(gray*0x11);
+ sp = row + (png_size_t)((row_width - 1) >> 1);
+ dp = row + (png_size_t)row_width - 1;
+ shift = (int)((1 - ((row_width + 1) & 0x01)) << 2);
+ for (i = 0; i < row_width; i++)
+ {
+ value = (*sp >> shift) & 0x0f;
+ *dp = (png_byte)(value | (value << 4));
+ if (shift == 4)
+ {
+ shift = 0;
+ sp--;
+ }
+ else
+ shift = 4;
+
+ dp--;
+ }
+ break;
+ }
+ }
+ row_info->bit_depth = 8;
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+
+ if (trans_value != NULL)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row + (png_size_t)row_width - 1;
+ dp = row + (png_size_t)(row_width << 1) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*sp == gray)
+ *dp-- = 0;
+ else
+ *dp-- = 0xff;
+ *dp-- = *sp--;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ sp = row + row_info->rowbytes - 1;
+ dp = row + (row_info->rowbytes << 1) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (((png_uint_16)*(sp) |
+ ((png_uint_16)*(sp - 1) << 8)) == gray)
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ row_info->color_type = PNG_COLOR_TYPE_GRAY_ALPHA;
+ row_info->channels = 2;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 1);
+ row_info->rowbytes =
+ ((row_width * row_info->pixel_depth) >> 3);
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB && trans_value)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ sp = row + (png_size_t)row_info->rowbytes - 1;
+ dp = row + (png_size_t)(row_width << 2) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if (*(sp - 2) == trans_value->red &&
+ *(sp - 1) == trans_value->green &&
+ *(sp - 0) == trans_value->blue)
+ *dp-- = 0;
+ else
+ *dp-- = 0xff;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ sp = row + row_info->rowbytes - 1;
+ dp = row + (png_size_t)(row_width << 3) - 1;
+ for (i = 0; i < row_width; i++)
+ {
+ if ((((png_uint_16)*(sp - 4) |
+ ((png_uint_16)*(sp - 5) << 8)) == trans_value->red) &&
+ (((png_uint_16)*(sp - 2) |
+ ((png_uint_16)*(sp - 3) << 8)) == trans_value->green) &&
+ (((png_uint_16)*(sp - 0) |
+ ((png_uint_16)*(sp - 1) << 8)) == trans_value->blue))
+ {
+ *dp-- = 0;
+ *dp-- = 0;
+ }
+ else
+ {
+ *dp-- = 0xff;
+ *dp-- = 0xff;
+ }
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ *dp-- = *sp--;
+ }
+ }
+ row_info->color_type = PNG_COLOR_TYPE_RGB_ALPHA;
+ row_info->channels = 4;
+ row_info->pixel_depth = (png_byte)(row_info->bit_depth << 2);
+ row_info->rowbytes =
+ ((row_width * row_info->pixel_depth) >> 3);
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_DITHER_SUPPORTED)
+void /* PRIVATE */
+png_do_dither(png_row_infop row_info, png_bytep row,
+ png_bytep palette_lookup, png_bytep dither_lookup)
+{
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width=row_info->width;
+
+ png_debug(1, "in png_do_dither\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB &&
+ palette_lookup && row_info->bit_depth == 8)
+ {
+ int r, g, b, p;
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ r = *sp++;
+ g = *sp++;
+ b = *sp++;
+
+ /* this looks real messy, but the compiler will reduce
+ it down to a reasonable formula. For example, with
+ 5 bits per color, we get:
+ p = (((r >> 3) & 0x1f) << 10) |
+ (((g >> 3) & 0x1f) << 5) |
+ ((b >> 3) & 0x1f);
+ */
+ p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+ ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+ (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+ (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+ ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+ (PNG_DITHER_BLUE_BITS)) |
+ ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+ ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+ *dp++ = palette_lookup[p];
+ }
+ row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+ row_info->channels = 1;
+ row_info->pixel_depth = row_info->bit_depth;
+ row_info->rowbytes =
+ ((row_width * row_info->pixel_depth + 7) >> 3);
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA &&
+ palette_lookup != NULL && row_info->bit_depth == 8)
+ {
+ int r, g, b, p;
+ sp = row;
+ dp = row;
+ for (i = 0; i < row_width; i++)
+ {
+ r = *sp++;
+ g = *sp++;
+ b = *sp++;
+ sp++;
+
+ p = (((r >> (8 - PNG_DITHER_RED_BITS)) &
+ ((1 << PNG_DITHER_RED_BITS) - 1)) <<
+ (PNG_DITHER_GREEN_BITS + PNG_DITHER_BLUE_BITS)) |
+ (((g >> (8 - PNG_DITHER_GREEN_BITS)) &
+ ((1 << PNG_DITHER_GREEN_BITS) - 1)) <<
+ (PNG_DITHER_BLUE_BITS)) |
+ ((b >> (8 - PNG_DITHER_BLUE_BITS)) &
+ ((1 << PNG_DITHER_BLUE_BITS) - 1));
+
+ *dp++ = palette_lookup[p];
+ }
+ row_info->color_type = PNG_COLOR_TYPE_PALETTE;
+ row_info->channels = 1;
+ row_info->pixel_depth = row_info->bit_depth;
+ row_info->rowbytes =
+ ((row_width * row_info->pixel_depth + 7) >> 3);
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_PALETTE &&
+ dither_lookup && row_info->bit_depth == 8)
+ {
+ sp = row;
+ for (i = 0; i < row_width; i++, sp++)
+ {
+ *sp = dither_lookup[*sp];
+ }
+ }
+ }
+}
+#endif
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+#if defined(PNG_READ_GAMMA_SUPPORTED)
+static int png_gamma_shift[] =
+ {0x10, 0x21, 0x42, 0x84, 0x110, 0x248, 0x550, 0xff0};
+
+/* We build the 8- or 16-bit gamma tables here. Note that for 16-bit
+ * tables, we don't make a full table if we are reducing to 8-bit in
+ * the future. Note also how the gamma_16 tables are segmented so that
+ * we don't need to allocate > 64K chunks for a full 16-bit table.
+ */
+void /* PRIVATE */
+png_build_gamma_table(png_structp png_ptr)
+{
+ png_debug(1, "in png_build_gamma_table\n");
+ if(png_ptr->gamma != 0.0)
+ {
+ if (png_ptr->bit_depth <= 8)
+ {
+ int i;
+ double g;
+
+ if (png_ptr->screen_gamma > .000001)
+ g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ else
+ g = 1.0;
+
+ png_ptr->gamma_table = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)256);
+
+ for (i = 0; i < 256; i++)
+ {
+ png_ptr->gamma_table[i] = (png_byte)(pow((double)i / 255.0,
+ g) * 255.0 + .5);
+ }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & ((PNG_BACKGROUND) | PNG_RGB_TO_GRAY))
+ {
+
+ g = 1.0 / (png_ptr->gamma);
+
+ png_ptr->gamma_to_1 = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)256);
+
+ for (i = 0; i < 256; i++)
+ {
+ png_ptr->gamma_to_1[i] = (png_byte)(pow((double)i / 255.0,
+ g) * 255.0 + .5);
+ }
+
+
+ png_ptr->gamma_from_1 = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)256);
+
+ if(png_ptr->screen_gamma > 0.000001)
+ g = 1.0 / png_ptr->screen_gamma;
+ else
+ g = png_ptr->gamma; /* probably doing rgb_to_gray */
+
+ for (i = 0; i < 256; i++)
+ {
+ png_ptr->gamma_from_1[i] = (png_byte)(pow((double)i / 255.0,
+ g) * 255.0 + .5);
+
+ }
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
+ }
+ else
+ {
+ double g;
+ int i, j, shift, num;
+ int sig_bit;
+ png_uint_32 ig;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ sig_bit = (int)png_ptr->sig_bit.red;
+ if ((int)png_ptr->sig_bit.green > sig_bit)
+ sig_bit = png_ptr->sig_bit.green;
+ if ((int)png_ptr->sig_bit.blue > sig_bit)
+ sig_bit = png_ptr->sig_bit.blue;
+ }
+ else
+ {
+ sig_bit = (int)png_ptr->sig_bit.gray;
+ }
+
+ if (sig_bit > 0)
+ shift = 16 - sig_bit;
+ else
+ shift = 0;
+
+ if (png_ptr->transformations & PNG_16_TO_8)
+ {
+ if (shift < (16 - PNG_MAX_GAMMA_8))
+ shift = (16 - PNG_MAX_GAMMA_8);
+ }
+
+ if (shift > 8)
+ shift = 8;
+ if (shift < 0)
+ shift = 0;
+
+ png_ptr->gamma_shift = (png_byte)shift;
+
+ num = (1 << (8 - shift));
+
+ if (png_ptr->screen_gamma > .000001)
+ g = 1.0 / (png_ptr->gamma * png_ptr->screen_gamma);
+ else
+ g = 1.0;
+
+ png_ptr->gamma_16_table = (png_uint_16pp)png_malloc(png_ptr,
+ (png_uint_32)(num * sizeof (png_uint_16p)));
+
+ if (png_ptr->transformations & (PNG_16_TO_8 | PNG_BACKGROUND))
+ {
+ double fin, fout;
+ png_uint_32 last, max;
+
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * sizeof (png_uint_16)));
+ }
+
+ g = 1.0 / g;
+ last = 0;
+ for (i = 0; i < 256; i++)
+ {
+ fout = ((double)i + 0.5) / 256.0;
+ fin = pow(fout, g);
+ max = (png_uint_32)(fin * (double)((png_uint_32)num << 8));
+ while (last <= max)
+ {
+ png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+ [(int)(last >> (8 - shift))] = (png_uint_16)(
+ (png_uint_16)i | ((png_uint_16)i << 8));
+ last++;
+ }
+ }
+ while (last < ((png_uint_32)num << 8))
+ {
+ png_ptr->gamma_16_table[(int)(last & (0xff >> shift))]
+ [(int)(last >> (8 - shift))] = (png_uint_16)65535L;
+ last++;
+ }
+ }
+ else
+ {
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_table[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * sizeof (png_uint_16)));
+
+ ig = (((png_uint_32)i * (png_uint_32)png_gamma_shift[shift]) >> 4);
+ for (j = 0; j < 256; j++)
+ {
+ png_ptr->gamma_16_table[i][j] =
+ (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+ 65535.0, g) * 65535.0 + .5);
+ }
+ }
+ }
+
+#if defined(PNG_READ_BACKGROUND_SUPPORTED) || \
+ defined(PNG_READ_RGB_TO_GRAY_SUPPORTED)
+ if (png_ptr->transformations & (PNG_BACKGROUND | PNG_RGB_TO_GRAY))
+ {
+
+ g = 1.0 / (png_ptr->gamma);
+
+ png_ptr->gamma_16_to_1 = (png_uint_16pp)png_malloc(png_ptr,
+ (png_uint_32)(num * sizeof (png_uint_16p )));
+
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_to_1[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * sizeof (png_uint_16)));
+
+ ig = (((png_uint_32)i *
+ (png_uint_32)png_gamma_shift[shift]) >> 4);
+ for (j = 0; j < 256; j++)
+ {
+ png_ptr->gamma_16_to_1[i][j] =
+ (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+ 65535.0, g) * 65535.0 + .5);
+ }
+ }
+
+ if(png_ptr->screen_gamma > 0.000001)
+ g = 1.0 / png_ptr->screen_gamma;
+ else
+ g = png_ptr->gamma; /* probably doing rgb_to_gray */
+
+ png_ptr->gamma_16_from_1 = (png_uint_16pp)png_malloc(png_ptr,
+ (png_uint_32)(num * sizeof (png_uint_16p)));
+
+ for (i = 0; i < num; i++)
+ {
+ png_ptr->gamma_16_from_1[i] = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(256 * sizeof (png_uint_16)));
+
+ ig = (((png_uint_32)i *
+ (png_uint_32)png_gamma_shift[shift]) >> 4);
+ for (j = 0; j < 256; j++)
+ {
+ png_ptr->gamma_16_from_1[i][j] =
+ (png_uint_16)(pow((double)(ig + ((png_uint_32)j << 8)) /
+ 65535.0, g) * 65535.0 + .5);
+ }
+ }
+ }
+#endif /* PNG_READ_BACKGROUND_SUPPORTED || PNG_RGB_TO_GRAY_SUPPORTED */
+ }
+ }
+}
+#endif
+/* To do: install integer version of png_build_gamma_table here */
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* undoes intrapixel differencing */
+void /* PRIVATE */
+png_do_read_intrapixel(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_read_intrapixel\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((256 + *rp + *(rp+1))&0xff);
+ *(rp+2) = (png_byte)((256 + *(rp+2) + *(rp+1))&0xff);
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0=*(rp )<<8 | *(rp+1);
+ png_uint_32 s1=*(rp+2)<<8 | *(rp+3);
+ png_uint_32 s2=*(rp+4)<<8 | *(rp+5);
+ png_uint_32 red=(65536+s0+s1)&0xffff;
+ png_uint_32 blue=(65536+s2+s1)&0xffff;
+ *(rp ) = (png_byte)((red>>8)&0xff);
+ *(rp+1) = (png_byte)(red&0xff);
+ *(rp+4) = (png_byte)((blue>>8)&0xff);
+ *(rp+5) = (png_byte)(blue&0xff);
+ }
+ }
+ }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngrutil.c b/tqtinterface/qt4/src/3rdparty/libpng/pngrutil.c
new file mode 100644
index 0000000..dc3b371
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngrutil.c
@@ -0,0 +1,3119 @@
+
+/* pngrutil.c - utilities to read a PNG file
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file tqcontains routines that are only called from within
+ * libpng itself during the course of reading an image.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if 0 && defined(_WIN32_WCE)
+/* strtod() function is not supported on WindowsCE */
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+__inline double strtod(const char *nptr, char **endptr)
+{
+ double result = 0;
+ int len;
+ wchar_t *str, *end;
+
+ len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
+ str = (wchar_t *)malloc(len * sizeof(wchar_t));
+ if ( NULL != str )
+ {
+ MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
+ result = wcstod(str, &end);
+ len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
+ *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
+ free(str);
+ }
+ return result;
+}
+# endif
+#endif
+
+png_uint_32 /* PRIVATE */
+png_get_uint_31(png_structp png_ptr, png_bytep buf)
+{
+ png_uint_32 i = png_get_uint_32(buf);
+ if (i > PNG_UINT_31_MAX)
+ png_error(png_ptr, "PNG unsigned integer out of range.\n");
+ return (i);
+}
+#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
+png_uint_32 /* PRIVATE */
+png_get_uint_32(png_bytep buf)
+{
+ png_uint_32 i = ((png_uint_32)(*buf) << 24) +
+ ((png_uint_32)(*(buf + 1)) << 16) +
+ ((png_uint_32)(*(buf + 2)) << 8) +
+ (png_uint_32)(*(buf + 3));
+
+ return (i);
+}
+
+#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_READ_oFFs_SUPPORTED)
+/* Grab a signed 32-bit integer from a buffer in big-endian format. The
+ * data is stored in the PNG file in two's complement format, and it is
+ * assumed that the machine format for signed integers is the same. */
+png_int_32 /* PRIVATE */
+png_get_int_32(png_bytep buf)
+{
+ png_int_32 i = ((png_int_32)(*buf) << 24) +
+ ((png_int_32)(*(buf + 1)) << 16) +
+ ((png_int_32)(*(buf + 2)) << 8) +
+ (png_int_32)(*(buf + 3));
+
+ return (i);
+}
+#endif /* PNG_READ_pCAL_SUPPORTED */
+
+/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
+png_uint_16 /* PRIVATE */
+png_get_uint_16(png_bytep buf)
+{
+ png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
+ (png_uint_16)(*(buf + 1)));
+
+ return (i);
+}
+#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
+
+/* Read data, and (optionally) run it through the CRC. */
+void /* PRIVATE */
+png_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
+{
+ png_read_data(png_ptr, buf, length);
+ png_calculate_crc(png_ptr, buf, length);
+}
+
+/* Optionally skip data and then check the CRC. Depending on whether we
+ are reading a ancillary or critical chunk, and how the program has set
+ things up, we may calculate the CRC on the data and print a message.
+ Returns '1' if there was a CRC error, '0' otherwise. */
+int /* PRIVATE */
+png_crc_finish(png_structp png_ptr, png_uint_32 skip)
+{
+ png_size_t i;
+ png_size_t istop = png_ptr->zbuf_size;
+
+ for (i = (png_size_t)skip; i > istop; i -= istop)
+ {
+ png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+ }
+ if (i)
+ {
+ png_crc_read(png_ptr, png_ptr->zbuf, i);
+ }
+
+ if (png_crc_error(png_ptr))
+ {
+ if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */
+ !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
+ (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */
+ (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+ else
+ {
+ png_chunk_error(png_ptr, "CRC error");
+ }
+ return (1);
+ }
+
+ return (0);
+}
+
+/* Compare the CRC stored in the PNG file with that calculated by libpng from
+ the data it has read thus far. */
+int /* PRIVATE */
+png_crc_error(png_structp png_ptr)
+{
+ png_byte crc_bytes[4];
+ png_uint_32 crc;
+ int need_crc = 1;
+
+ if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
+ {
+ if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
+ (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ need_crc = 0;
+ }
+ else /* critical */
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
+ need_crc = 0;
+ }
+
+ png_read_data(png_ptr, crc_bytes, 4);
+
+ if (need_crc)
+ {
+ crc = png_get_uint_32(crc_bytes);
+ return ((int)(crc != png_ptr->crc));
+ }
+ else
+ return (0);
+}
+
+#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
+ defined(PNG_READ_iCCP_SUPPORTED)
+/*
+ * Decompress trailing data in a chunk. The assumption is that chunkdata
+ * points at an allocated area holding the contents of a chunk with a
+ * trailing compressed part. What we get back is an allocated area
+ * holding the original prefix part and an uncompressed version of the
+ * trailing part (the malloc area passed in is freed).
+ */
+png_charp /* PRIVATE */
+png_decompress_chunk(png_structp png_ptr, int comp_type,
+ png_charp chunkdata, png_size_t chunklength,
+ png_size_t prefix_size, png_size_t *newlength)
+{
+ static char msg[] = "Error decoding compressed text";
+ png_charp text = NULL;
+ png_size_t text_size;
+
+ if (comp_type == PNG_COMPRESSION_TYPE_BASE)
+ {
+ int ret = Z_OK;
+ png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
+ png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ text_size = 0;
+ text = NULL;
+
+ while (png_ptr->zstream.avail_in)
+ {
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_warning(png_ptr, png_ptr->zstream.msg);
+ else
+ png_warning(png_ptr, msg);
+ inflateReset(&png_ptr->zstream);
+ png_ptr->zstream.avail_in = 0;
+
+ if (text == NULL)
+ {
+ text_size = prefix_size + sizeof(msg) + 1;
+ text = (png_charp)png_malloc_warn(png_ptr, text_size);
+ if (text == NULL)
+ {
+ png_free(png_ptr,chunkdata);
+ png_error(png_ptr,"Not enough memory to decompress chunk");
+ }
+ png_memcpy(text, chunkdata, prefix_size);
+ }
+
+ text[text_size - 1] = 0x00;
+
+ /* Copy what we can of the error message into the text chunk */
+ text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
+ text_size = sizeof(msg) > text_size ? text_size : sizeof(msg);
+ png_memcpy(text + prefix_size, msg, text_size + 1);
+ break;
+ }
+ if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
+ {
+ if (text == NULL)
+ {
+ text_size = prefix_size +
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+ text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
+ if (text == NULL)
+ {
+ png_free(png_ptr,chunkdata);
+ png_error(png_ptr,"Not enough memory to decompress chunk.");
+ }
+ png_memcpy(text + prefix_size, png_ptr->zbuf,
+ text_size - prefix_size);
+ png_memcpy(text, chunkdata, prefix_size);
+ *(text + text_size) = 0x00;
+ }
+ else
+ {
+ png_charp tmp;
+
+ tmp = text;
+ text = (png_charp)png_malloc_warn(png_ptr,
+ (png_uint_32)(text_size +
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
+ if (text == NULL)
+ {
+ png_free(png_ptr, tmp);
+ png_free(png_ptr, chunkdata);
+ png_error(png_ptr,"Not enough memory to decompress chunk..");
+ }
+ png_memcpy(text, tmp, text_size);
+ png_free(png_ptr, tmp);
+ png_memcpy(text + text_size, png_ptr->zbuf,
+ (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
+ text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
+ *(text + text_size) = 0x00;
+ }
+ if (ret == Z_STREAM_END)
+ break;
+ else
+ {
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ }
+ }
+ if (ret != Z_STREAM_END)
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char umsg[52];
+
+ if (ret == Z_BUF_ERROR)
+ sprintf(umsg,"Buffer error in compressed datastream in %s chunk",
+ png_ptr->chunk_name);
+ else if (ret == Z_DATA_ERROR)
+ sprintf(umsg,"Data error in compressed datastream in %s chunk",
+ png_ptr->chunk_name);
+ else
+ sprintf(umsg,"Incomplete compressed datastream in %s chunk",
+ png_ptr->chunk_name);
+ png_warning(png_ptr, umsg);
+#else
+ png_warning(png_ptr,
+ "Incomplete compressed datastream in chunk other than IDAT");
+#endif
+ text_size=prefix_size;
+ if (text == NULL)
+ {
+ text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
+ if (text == NULL)
+ {
+ png_free(png_ptr, chunkdata);
+ png_error(png_ptr,"Not enough memory for text.");
+ }
+ png_memcpy(text, chunkdata, prefix_size);
+ }
+ *(text + text_size) = 0x00;
+ }
+
+ inflateReset(&png_ptr->zstream);
+ png_ptr->zstream.avail_in = 0;
+
+ png_free(png_ptr, chunkdata);
+ chunkdata = text;
+ *newlength=text_size;
+ }
+ else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char umsg[50];
+
+ sprintf(umsg, "Unknown zTXt compression type %d", comp_type);
+ png_warning(png_ptr, umsg);
+#else
+ png_warning(png_ptr, "Unknown zTXt compression type");
+#endif
+
+ *(chunkdata + prefix_size) = 0x00;
+ *newlength=prefix_size;
+ }
+
+ return chunkdata;
+}
+#endif
+
+/* read and check the IDHR chunk */
+void /* PRIVATE */
+png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[13];
+ png_uint_32 width, height;
+ int bit_depth, color_type, compression_type, filter_type;
+ int interlace_type;
+
+ png_debug(1, "in png_handle_IHDR\n");
+
+ if (png_ptr->mode & PNG_HAVE_IHDR)
+ png_error(png_ptr, "Out of place IHDR");
+
+ /* check the length */
+ if (length != 13)
+ png_error(png_ptr, "Invalid IHDR chunk");
+
+ png_ptr->mode |= PNG_HAVE_IHDR;
+
+ png_crc_read(png_ptr, buf, 13);
+ png_crc_finish(png_ptr, 0);
+
+ width = png_get_uint_32(buf);
+ height = png_get_uint_32(buf + 4);
+ bit_depth = buf[8];
+ color_type = buf[9];
+ compression_type = buf[10];
+ filter_type = buf[11];
+ interlace_type = buf[12];
+
+
+ /* set internal variables */
+ png_ptr->width = width;
+ png_ptr->height = height;
+ png_ptr->bit_depth = (png_byte)bit_depth;
+ png_ptr->interlaced = (png_byte)interlace_type;
+ png_ptr->color_type = (png_byte)color_type;
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ png_ptr->filter_type = (png_byte)filter_type;
+#endif
+
+ /* tqfind number of channels */
+ switch (png_ptr->color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ case PNG_COLOR_TYPE_PALETTE:
+ png_ptr->channels = 1;
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ png_ptr->channels = 3;
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ png_ptr->channels = 2;
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ png_ptr->channels = 4;
+ break;
+ }
+
+ /* set up other useful info */
+ png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
+ png_ptr->channels);
+ png_ptr->rowbytes = ((png_ptr->width *
+ (png_uint_32)png_ptr->pixel_depth + 7) >> 3);
+ png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
+ png_debug1(3,"channels = %d\n", png_ptr->channels);
+ png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
+ png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
+ color_type, interlace_type, compression_type, filter_type);
+}
+
+/* read and check the palette */
+void /* PRIVATE */
+png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_color palette[PNG_MAX_PALETTE_LENGTH];
+ int num, i;
+#ifndef PNG_NO_POINTER_INDEXING
+ png_colorp pal_ptr;
+#endif
+
+ png_debug(1, "in png_handle_PLTE\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before PLTE");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid PLTE after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ png_error(png_ptr, "Duplicate PLTE chunk");
+
+ png_ptr->mode |= PNG_HAVE_PLTE;
+
+ if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+ {
+ png_warning(png_ptr,
+ "Ignoring PLTE chunk in grayscale PNG");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
+ {
+ if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ png_warning(png_ptr, "Invalid palette chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else
+ {
+ png_error(png_ptr, "Invalid palette chunk");
+ }
+ }
+
+ num = (int)length / 3;
+
+#ifndef PNG_NO_POINTER_INDEXING
+ for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ pal_ptr->red = buf[0];
+ pal_ptr->green = buf[1];
+ pal_ptr->blue = buf[2];
+ }
+#else
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[3];
+
+ png_crc_read(png_ptr, buf, 3);
+ /* don't depend upon png_color being any order */
+ palette[i].red = buf[0];
+ palette[i].green = buf[1];
+ palette[i].blue = buf[2];
+ }
+#endif
+
+ /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
+ whatever the normal CRC configuration tells us. However, if we
+ have an RGB image, the PLTE can be considered ancillary, so
+ we will act as though it is. */
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+#endif
+ {
+ png_crc_finish(png_ptr, 0);
+ }
+#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+ else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */
+ {
+ /* If we don't want to use the data from an ancillary chunk,
+ we have two options: an error abort, or a warning and we
+ ignore the data in this chunk (which should be OK, since
+ it's considered ancillary for a RGB or RGBA image). */
+ if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
+ {
+ if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
+ {
+ png_chunk_error(png_ptr, "CRC error");
+ }
+ else
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ return;
+ }
+ }
+ /* Otherwise, we (optionally) emit a warning and use the chunk. */
+ else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
+ {
+ png_chunk_warning(png_ptr, "CRC error");
+ }
+ }
+#endif
+
+ png_set_PLTE(png_ptr, info_ptr, palette, num);
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ if (png_ptr->num_trans > (png_uint_16)num)
+ {
+ png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
+ png_ptr->num_trans = (png_uint_16)num;
+ }
+ if (info_ptr->num_trans > (png_uint_16)num)
+ {
+ png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
+ info_ptr->num_trans = (png_uint_16)num;
+ }
+ }
+ }
+#endif
+
+}
+
+void /* PRIVATE */
+png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_debug(1, "in png_handle_IEND\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
+ {
+ png_error(png_ptr, "No image in file");
+
+ info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
+ }
+
+ png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
+
+ if (length != 0)
+ {
+ png_warning(png_ptr, "Incorrect IEND chunk length");
+ }
+ png_crc_finish(png_ptr, length);
+}
+
+#if defined(PNG_READ_gAMA_SUPPORTED)
+void /* PRIVATE */
+png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_fixed_point igamma;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float file_gamma;
+#endif
+ png_byte buf[4];
+
+ png_debug(1, "in png_handle_gAMA\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before gAMA");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid gAMA after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place gAMA chunk");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+ )
+ {
+ png_warning(png_ptr, "Duplicate gAMA chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 4)
+ {
+ png_warning(png_ptr, "Incorrect gAMA chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 4);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ igamma = (png_fixed_point)png_get_uint_32(buf);
+ /* check for zero gamma */
+ if (igamma == 0)
+ {
+ png_warning(png_ptr,
+ "Ignoring gAMA chunk with gamma=0");
+ return;
+ }
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_sRGB)
+ if(igamma < 45000L || igamma > 46000L)
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect gAMA value when sRGB is also present");
+#ifndef PNG_NO_CONSOLE_IO
+ fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
+#endif
+ return;
+ }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ file_gamma = (float)igamma / (float)100000.0;
+# ifdef PNG_READ_GAMMA_SUPPORTED
+ png_ptr->gamma = file_gamma;
+# endif
+ png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
+#endif
+}
+#endif
+
+#if defined(PNG_READ_sBIT_SUPPORTED)
+void /* PRIVATE */
+png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_size_t truelen;
+ png_byte buf[4];
+
+ png_debug(1, "in png_handle_sBIT\n");
+
+ buf[0] = buf[1] = buf[2] = buf[3] = 0;
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sBIT");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sBIT after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ {
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place sBIT chunk");
+ }
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
+ {
+ png_warning(png_ptr, "Duplicate sBIT chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 3;
+ else
+ truelen = (png_size_t)png_ptr->channels;
+
+ if (length != truelen)
+ {
+ png_warning(png_ptr, "Incorrect sBIT chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, truelen);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_ptr->sig_bit.red = buf[0];
+ png_ptr->sig_bit.green = buf[1];
+ png_ptr->sig_bit.blue = buf[2];
+ png_ptr->sig_bit.alpha = buf[3];
+ }
+ else
+ {
+ png_ptr->sig_bit.gray = buf[0];
+ png_ptr->sig_bit.red = buf[0];
+ png_ptr->sig_bit.green = buf[0];
+ png_ptr->sig_bit.blue = buf[0];
+ png_ptr->sig_bit.alpha = buf[1];
+ }
+ png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
+}
+#endif
+
+#if defined(PNG_READ_cHRM_SUPPORTED)
+void /* PRIVATE */
+png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[4];
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+ png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+ int_y_green, int_x_blue, int_y_blue;
+
+ png_uint_32 uint_x, uint_y;
+
+ png_debug(1, "in png_handle_cHRM\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before cHRM");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid cHRM after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Missing PLTE before cHRM");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ && !(info_ptr->valid & PNG_INFO_sRGB)
+#endif
+ )
+ {
+ png_warning(png_ptr, "Duplicate cHRM chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 32)
+ {
+ png_warning(png_ptr, "Incorrect cHRM chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_x = png_get_uint_32(buf);
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_y = png_get_uint_32(buf);
+
+ if (uint_x > 80000L || uint_y > 80000L ||
+ uint_x + uint_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid cHRM white point");
+ png_crc_finish(png_ptr, 24);
+ return;
+ }
+ int_x_white = (png_fixed_point)uint_x;
+ int_y_white = (png_fixed_point)uint_y;
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_x = png_get_uint_32(buf);
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_y = png_get_uint_32(buf);
+
+ if (uint_x > 80000L || uint_y > 80000L ||
+ uint_x + uint_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid cHRM red point");
+ png_crc_finish(png_ptr, 16);
+ return;
+ }
+ int_x_red = (png_fixed_point)uint_x;
+ int_y_red = (png_fixed_point)uint_y;
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_x = png_get_uint_32(buf);
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_y = png_get_uint_32(buf);
+
+ if (uint_x > 80000L || uint_y > 80000L ||
+ uint_x + uint_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid cHRM green point");
+ png_crc_finish(png_ptr, 8);
+ return;
+ }
+ int_x_green = (png_fixed_point)uint_x;
+ int_y_green = (png_fixed_point)uint_y;
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_x = png_get_uint_32(buf);
+
+ png_crc_read(png_ptr, buf, 4);
+ uint_y = png_get_uint_32(buf);
+
+ if (uint_x > 80000L || uint_y > 80000L ||
+ uint_x + uint_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid cHRM blue point");
+ png_crc_finish(png_ptr, 0);
+ return;
+ }
+ int_x_blue = (png_fixed_point)uint_x;
+ int_y_blue = (png_fixed_point)uint_y;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ white_x = (float)int_x_white / (float)100000.0;
+ white_y = (float)int_y_white / (float)100000.0;
+ red_x = (float)int_x_red / (float)100000.0;
+ red_y = (float)int_y_red / (float)100000.0;
+ green_x = (float)int_x_green / (float)100000.0;
+ green_y = (float)int_y_green / (float)100000.0;
+ blue_x = (float)int_x_blue / (float)100000.0;
+ blue_y = (float)int_y_blue / (float)100000.0;
+#endif
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_sRGB)
+ {
+ if (abs(int_x_white - 31270L) > 1000 ||
+ abs(int_y_white - 32900L) > 1000 ||
+ abs(int_x_red - 64000L) > 1000 ||
+ abs(int_y_red - 33000L) > 1000 ||
+ abs(int_x_green - 30000L) > 1000 ||
+ abs(int_y_green - 60000L) > 1000 ||
+ abs(int_x_blue - 15000L) > 1000 ||
+ abs(int_y_blue - 6000L) > 1000)
+ {
+
+ png_warning(png_ptr,
+ "Ignoring incorrect cHRM value when sRGB is also present");
+#ifndef PNG_NO_CONSOLE_IO
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
+ white_x, white_y, red_x, red_y);
+ fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
+ green_x, green_y, blue_x, blue_y);
+#else
+ fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
+ int_x_white, int_y_white, int_x_red, int_y_red);
+ fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
+ int_x_green, int_y_green, int_x_blue, int_y_blue);
+#endif
+#endif /* PNG_NO_CONSOLE_IO */
+ }
+ png_crc_finish(png_ptr, 0);
+ return;
+ }
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_set_cHRM(png_ptr, info_ptr,
+ white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_set_cHRM_fixed(png_ptr, info_ptr,
+ int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
+ int_y_green, int_x_blue, int_y_blue);
+#endif
+ if (png_crc_finish(png_ptr, 0))
+ return;
+}
+#endif
+
+#if defined(PNG_READ_sRGB_SUPPORTED)
+void /* PRIVATE */
+png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ int intent;
+ png_byte buf[1];
+
+ png_debug(1, "in png_handle_sRGB\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sRGB");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sRGB after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place sRGB chunk");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
+ {
+ png_warning(png_ptr, "Duplicate sRGB chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 1)
+ {
+ png_warning(png_ptr, "Incorrect sRGB chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 1);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ intent = buf[0];
+ /* check for bad intent */
+ if (intent >= PNG_sRGB_INTENT_LAST)
+ {
+ png_warning(png_ptr, "Unknown sRGB intent");
+ return;
+ }
+
+#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
+ if ((info_ptr->valid & PNG_INFO_gAMA))
+ {
+ int igamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ igamma=(int)info_ptr->int_gamma;
+#else
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ igamma=(int)(info_ptr->gamma * 100000.);
+# endif
+#endif
+ if(igamma < 45000L || igamma > 46000L)
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect gAMA value when sRGB is also present");
+#ifndef PNG_NO_CONSOLE_IO
+# ifdef PNG_FIXED_POINT_SUPPORTED
+ fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
+# else
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
+# endif
+# endif
+#endif
+ }
+ }
+#endif /* PNG_READ_gAMA_SUPPORTED */
+
+#ifdef PNG_READ_cHRM_SUPPORTED
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ if (info_ptr->valid & PNG_INFO_cHRM)
+ if (abs(info_ptr->int_x_white - 31270L) > 1000 ||
+ abs(info_ptr->int_y_white - 32900L) > 1000 ||
+ abs(info_ptr->int_x_red - 64000L) > 1000 ||
+ abs(info_ptr->int_y_red - 33000L) > 1000 ||
+ abs(info_ptr->int_x_green - 30000L) > 1000 ||
+ abs(info_ptr->int_y_green - 60000L) > 1000 ||
+ abs(info_ptr->int_x_blue - 15000L) > 1000 ||
+ abs(info_ptr->int_y_blue - 6000L) > 1000)
+ {
+ png_warning(png_ptr,
+ "Ignoring incorrect cHRM value when sRGB is also present");
+ }
+#endif /* PNG_FIXED_POINT_SUPPORTED */
+#endif /* PNG_READ_cHRM_SUPPORTED */
+
+ png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
+}
+#endif /* PNG_READ_sRGB_SUPPORTED */
+
+#if defined(PNG_READ_iCCP_SUPPORTED)
+void /* PRIVATE */
+png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+ png_charp chunkdata;
+ png_byte compression_type;
+ png_bytep pC;
+ png_charp profile;
+ png_uint_32 skip = 0;
+ png_uint_32 profile_size, profile_length;
+ png_size_t slength, prefix_length, data_length;
+
+ png_debug(1, "in png_handle_iCCP\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before iCCP");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid iCCP after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->mode & PNG_HAVE_PLTE)
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Out of place iCCP chunk");
+
+ if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
+ {
+ png_warning(png_ptr, "Duplicate iCCP chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "iCCP chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+
+ if (png_crc_finish(png_ptr, skip))
+ {
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+
+ chunkdata[slength] = 0x00;
+
+ for (profile = chunkdata; *profile; profile++)
+ /* empty loop to tqfind end of name */ ;
+
+ ++profile;
+
+ /* there should be at least one zero (the compression type byte)
+ following the separator, and we should be on it */
+ if ( profile >= chunkdata + slength)
+ {
+ png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "Malformed iCCP chunk");
+ return;
+ }
+
+ /* compression_type should always be zero */
+ compression_type = *profile++;
+ if (compression_type)
+ {
+ png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
+ compression_type=0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8
+ wrote nonzero) */
+ }
+
+ prefix_length = profile - chunkdata;
+ chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
+ slength, prefix_length, &data_length);
+
+ profile_length = data_length - prefix_length;
+
+ if ( prefix_length > data_length || profile_length < 4)
+ {
+ png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "Profile size field missing from iCCP chunk");
+ return;
+ }
+
+ /* Check the profile_size recorded in the first 32 bits of the ICC profile */
+ pC = (png_bytep)(chunkdata+prefix_length);
+ profile_size = ((*(pC ))<<24) |
+ ((*(pC+1))<<16) |
+ ((*(pC+2))<< 8) |
+ ((*(pC+3)) );
+
+ if(profile_size < profile_length)
+ profile_length = profile_size;
+
+ if(profile_size > profile_length)
+ {
+ png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "Ignoring truncated iCCP profile.\n");
+ return;
+ }
+
+ png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
+ chunkdata + prefix_length, profile_length);
+ png_free(png_ptr, chunkdata);
+}
+#endif /* PNG_READ_iCCP_SUPPORTED */
+
+#if defined(PNG_READ_sPLT_SUPPORTED)
+void /* PRIVATE */
+png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+{
+ png_bytep chunkdata;
+ png_bytep entry_start;
+ png_sPLT_t new_palette;
+#ifdef PNG_NO_POINTER_INDEXING
+ png_sPLT_entryp pp;
+#endif
+ int data_length, entry_size, i;
+ png_uint_32 skip = 0;
+ png_size_t slength;
+
+ png_debug(1, "in png_handle_sPLT\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sPLT");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sPLT after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "sPLT chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+
+ if (png_crc_finish(png_ptr, skip))
+ {
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+
+ chunkdata[slength] = 0x00;
+
+ for (entry_start = chunkdata; *entry_start; entry_start++)
+ /* empty loop to tqfind end of name */ ;
+ ++entry_start;
+
+ /* a sample depth should follow the separator, and we should be on it */
+ if (entry_start > chunkdata + slength)
+ {
+ png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "malformed sPLT chunk");
+ return;
+ }
+
+ new_palette.depth = *entry_start++;
+ entry_size = (new_palette.depth == 8 ? 6 : 10);
+ data_length = (slength - (entry_start - chunkdata));
+
+ /* integrity-check the data length */
+ if (data_length % entry_size)
+ {
+ png_free(png_ptr, chunkdata);
+ png_warning(png_ptr, "sPLT chunk has bad length");
+ return;
+ }
+
+ new_palette.nentries = data_length / entry_size;
+ if (new_palette.nentries > PNG_SIZE_MAX / sizeof(png_sPLT_entry))
+ {
+ png_warning(png_ptr, "sPLT chunk too long");
+ return;
+ }
+ new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
+ png_ptr, new_palette.nentries * sizeof(png_sPLT_entry));
+ if (new_palette.entries == NULL)
+ {
+ png_warning(png_ptr, "sPLT chunk requires too much memory");
+ return;
+ }
+
+#ifndef PNG_NO_POINTER_INDEXING
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+ png_sPLT_entryp pp = new_palette.entries + i;
+
+ if (new_palette.depth == 8)
+ {
+ pp->red = *entry_start++;
+ pp->green = *entry_start++;
+ pp->blue = *entry_start++;
+ pp->alpha = *entry_start++;
+ }
+ else
+ {
+ pp->red = png_get_uint_16(entry_start); entry_start += 2;
+ pp->green = png_get_uint_16(entry_start); entry_start += 2;
+ pp->blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+ pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#else
+ pp = new_palette.entries;
+ for (i = 0; i < new_palette.nentries; i++)
+ {
+
+ if (new_palette.depth == 8)
+ {
+ pp[i].red = *entry_start++;
+ pp[i].green = *entry_start++;
+ pp[i].blue = *entry_start++;
+ pp[i].alpha = *entry_start++;
+ }
+ else
+ {
+ pp[i].red = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].blue = png_get_uint_16(entry_start); entry_start += 2;
+ pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
+ }
+ pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
+ }
+#endif
+
+ /* discard all chunk data except the name and stash that */
+ new_palette.name = (png_charp)chunkdata;
+
+ png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
+
+ png_free(png_ptr, chunkdata);
+ png_free(png_ptr, new_palette.entries);
+}
+#endif /* PNG_READ_sPLT_SUPPORTED */
+
+#if defined(PNG_READ_tRNS_SUPPORTED)
+void /* PRIVATE */
+png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
+
+ png_debug(1, "in png_handle_tRNS\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before tRNS");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid tRNS after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
+ {
+ png_warning(png_ptr, "Duplicate tRNS chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (!(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ /* Should be an error, but we can cope with it */
+ png_warning(png_ptr, "Missing PLTE before tRNS");
+ }
+ if (length > (png_uint_32)png_ptr->num_palette ||
+ length > PNG_MAX_PALETTE_LENGTH)
+ {
+ png_warning(png_ptr, "Incorrect tRNS chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ if (length == 0)
+ {
+ png_warning(png_ptr, "Zero length tRNS chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, readbuf, (png_size_t)length);
+ png_ptr->num_trans = (png_uint_16)length;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_byte buf[6];
+
+ if (length != 6)
+ {
+ png_warning(png_ptr, "Incorrect tRNS chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, (png_size_t)length);
+ png_ptr->num_trans = 1;
+ png_ptr->trans_values.red = png_get_uint_16(buf);
+ png_ptr->trans_values.green = png_get_uint_16(buf + 2);
+ png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_byte buf[6];
+
+ if (length != 2)
+ {
+ png_warning(png_ptr, "Incorrect tRNS chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 2);
+ png_ptr->num_trans = 1;
+ png_ptr->trans_values.gray = png_get_uint_16(buf);
+ }
+ else
+ {
+ png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
+ &(png_ptr->trans_values));
+}
+#endif
+
+#if defined(PNG_READ_bKGD_SUPPORTED)
+void /* PRIVATE */
+png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_size_t truelen;
+ png_byte buf[6];
+
+ png_debug(1, "in png_handle_bKGD\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before bKGD");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid bKGD after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
+ !(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ png_warning(png_ptr, "Missing PLTE before bKGD");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
+ {
+ png_warning(png_ptr, "Duplicate bKGD chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ truelen = 1;
+ else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ truelen = 6;
+ else
+ truelen = 2;
+
+ if (length != truelen)
+ {
+ png_warning(png_ptr, "Incorrect bKGD chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, truelen);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ /* We convert the index value into RGB components so that we can allow
+ * arbitrary RGB values for background when we have transparency, and
+ * so it is easy to determine the RGB values of the background color
+ * from the info_ptr struct. */
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_ptr->background.index = buf[0];
+ if(info_ptr->num_palette)
+ {
+ if(buf[0] > info_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Incorrect bKGD chunk index value");
+ return;
+ }
+ png_ptr->background.red =
+ (png_uint_16)png_ptr->palette[buf[0]].red;
+ png_ptr->background.green =
+ (png_uint_16)png_ptr->palette[buf[0]].green;
+ png_ptr->background.blue =
+ (png_uint_16)png_ptr->palette[buf[0]].blue;
+ }
+ }
+ else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
+ {
+ png_ptr->background.red =
+ png_ptr->background.green =
+ png_ptr->background.blue =
+ png_ptr->background.gray = png_get_uint_16(buf);
+ }
+ else
+ {
+ png_ptr->background.red = png_get_uint_16(buf);
+ png_ptr->background.green = png_get_uint_16(buf + 2);
+ png_ptr->background.blue = png_get_uint_16(buf + 4);
+ }
+
+ png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
+}
+#endif
+
+#if defined(PNG_READ_hIST_SUPPORTED)
+void /* PRIVATE */
+png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ int num, i;
+ png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
+
+ png_debug(1, "in png_handle_hIST\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before hIST");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid hIST after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (!(png_ptr->mode & PNG_HAVE_PLTE))
+ {
+ png_warning(png_ptr, "Missing PLTE before hIST");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
+ {
+ png_warning(png_ptr, "Duplicate hIST chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ num = (int)length / 2 ;
+ if (num != png_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Incorrect hIST chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ for (i = 0; i < num; i++)
+ {
+ png_byte buf[2];
+
+ png_crc_read(png_ptr, buf, 2);
+ readbuf[i] = png_get_uint_16(buf);
+ }
+
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ png_set_hIST(png_ptr, info_ptr, readbuf);
+}
+#endif
+
+#if defined(PNG_READ_pHYs_SUPPORTED)
+void /* PRIVATE */
+png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[9];
+ png_uint_32 res_x, res_y;
+ int unit_type;
+
+ png_debug(1, "in png_handle_pHYs\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before pHYs");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid pHYs after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
+ {
+ png_warning(png_ptr, "Duplicate pHYs chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_warning(png_ptr, "Incorrect pHYs chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 9);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ res_x = png_get_uint_32(buf);
+ res_y = png_get_uint_32(buf + 4);
+ unit_type = buf[8];
+ png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
+}
+#endif
+
+#if defined(PNG_READ_oFFs_SUPPORTED)
+void /* PRIVATE */
+png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[9];
+ png_int_32 offset_x, offset_y;
+ int unit_type;
+
+ png_debug(1, "in png_handle_oFFs\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before oFFs");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid oFFs after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
+ {
+ png_warning(png_ptr, "Duplicate oFFs chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (length != 9)
+ {
+ png_warning(png_ptr, "Incorrect oFFs chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 9);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ offset_x = png_get_int_32(buf);
+ offset_y = png_get_int_32(buf + 4);
+ unit_type = buf[8];
+ png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
+}
+#endif
+
+#if defined(PNG_READ_pCAL_SUPPORTED)
+/* read the pCAL chunk (described in the PNG Extensions document) */
+void /* PRIVATE */
+png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_charp purpose;
+ png_int_32 X0, X1;
+ png_byte type, nparams;
+ png_charp buf, units, endptr;
+ png_charpp params;
+ png_size_t slength;
+ int i;
+
+ png_debug(1, "in png_handle_pCAL\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before pCAL");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid pCAL after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
+ {
+ png_warning(png_ptr, "Duplicate pCAL chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
+ length + 1);
+ purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (purpose == NULL)
+ {
+ png_warning(png_ptr, "No memory for pCAL purpose.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)purpose, slength);
+
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, purpose);
+ return;
+ }
+
+ purpose[slength] = 0x00; /* null terminate the last string */
+
+ png_debug(3, "Finding end of pCAL purpose string\n");
+ for (buf = purpose; *buf; buf++)
+ /* empty loop */ ;
+
+ endptr = purpose + slength;
+
+ /* We need to have at least 12 bytes after the purpose string
+ in order to get the parameter information. */
+ if (endptr <= buf + 12)
+ {
+ png_warning(png_ptr, "Invalid pCAL data");
+ png_free(png_ptr, purpose);
+ return;
+ }
+
+ png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
+ X0 = png_get_int_32((png_bytep)buf+1);
+ X1 = png_get_int_32((png_bytep)buf+5);
+ type = buf[9];
+ nparams = buf[10];
+ units = buf + 11;
+
+ png_debug(3, "Checking pCAL equation type and number of parameters\n");
+ /* Check that we have the right number of parameters for known
+ equation types. */
+ if ((type == PNG_ETQUATION_LINEAR && nparams != 2) ||
+ (type == PNG_ETQUATION_BASE_E && nparams != 3) ||
+ (type == PNG_ETQUATION_ARBITRARY && nparams != 3) ||
+ (type == PNG_ETQUATION_HYPERBOLIC && nparams != 4))
+ {
+ png_warning(png_ptr, "Invalid pCAL parameters for equation type");
+ png_free(png_ptr, purpose);
+ return;
+ }
+ else if (type >= PNG_ETQUATION_LAST)
+ {
+ png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+ }
+
+ for (buf = units; *buf; buf++)
+ /* Empty loop to move past the units string. */ ;
+
+ png_debug(3, "Allocating pCAL parameters array\n");
+ params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
+ *sizeof(png_charp))) ;
+ if (params == NULL)
+ {
+ png_free(png_ptr, purpose);
+ png_warning(png_ptr, "No memory for pCAL params.");
+ return;
+ }
+
+ /* Get pointers to the start of each parameter string. */
+ for (i = 0; i < (int)nparams; i++)
+ {
+ buf++; /* Skip the null string terminator from previous parameter. */
+
+ png_debug1(3, "Reading pCAL parameter %d\n", i);
+ for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
+ /* Empty loop to move past each parameter string */ ;
+
+ /* Make sure we haven't run out of data yet */
+ if (buf > endptr)
+ {
+ png_warning(png_ptr, "Invalid pCAL data");
+ png_free(png_ptr, purpose);
+ png_free(png_ptr, params);
+ return;
+ }
+ }
+
+ png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
+ units, params);
+
+ png_free(png_ptr, purpose);
+ png_free(png_ptr, params);
+}
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED)
+/* read the sCAL chunk */
+void /* PRIVATE */
+png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_charp buffer, ep;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ double width, height;
+ png_charp vp;
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_charp swidth, sheight;
+#endif
+#endif
+ png_size_t slength;
+
+ png_debug(1, "in png_handle_sCAL\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before sCAL");
+ else if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+ png_warning(png_ptr, "Invalid sCAL after IDAT");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
+ {
+ png_warning(png_ptr, "Duplicate sCAL chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
+ length + 1);
+ buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (buffer == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)buffer, slength);
+
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, buffer);
+ return;
+ }
+
+ buffer[slength] = 0x00; /* null terminate the last string */
+
+ ep = buffer + 1; /* skip unit byte */
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ width = strtod(ep, &vp);
+ if (*vp)
+ {
+ png_warning(png_ptr, "malformed width string in sCAL chunk");
+ return;
+ }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
+ if (swidth == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
+ return;
+ }
+ png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
+#endif
+#endif
+
+ for (ep = buffer; *ep; ep++)
+ /* empty loop */ ;
+ ep++;
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ height = strtod(ep, &vp);
+ if (*vp)
+ {
+ png_warning(png_ptr, "malformed height string in sCAL chunk");
+ return;
+ }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
+ if (swidth == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
+ return;
+ }
+ png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
+#endif
+#endif
+
+ if (buffer + slength < ep
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ || width <= 0. || height <= 0.
+#endif
+ )
+ {
+ png_warning(png_ptr, "Invalid sCAL data");
+ png_free(png_ptr, buffer);
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, swidth);
+ png_free(png_ptr, sheight);
+#endif
+ return;
+ }
+
+
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
+#endif
+#endif
+
+ png_free(png_ptr, buffer);
+#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
+ png_free(png_ptr, swidth);
+ png_free(png_ptr, sheight);
+#endif
+}
+#endif
+
+#if defined(PNG_READ_tIME_SUPPORTED)
+void /* PRIVATE */
+png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_byte buf[7];
+ png_time mod_time;
+
+ png_debug(1, "in png_handle_tIME\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Out of place tIME chunk");
+ else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
+ {
+ png_warning(png_ptr, "Duplicate tIME chunk");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ if (length != 7)
+ {
+ png_warning(png_ptr, "Incorrect tIME chunk length");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+
+ png_crc_read(png_ptr, buf, 7);
+ if (png_crc_finish(png_ptr, 0))
+ return;
+
+ mod_time.second = buf[6];
+ mod_time.minute = buf[5];
+ mod_time.hour = buf[4];
+ mod_time.day = buf[3];
+ mod_time.month = buf[2];
+ mod_time.year = png_get_uint_16(buf);
+
+ png_set_tIME(png_ptr, info_ptr, &mod_time);
+}
+#endif
+
+#if defined(PNG_READ_tEXt_SUPPORTED)
+/* Note: this does not properly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_textp text_ptr;
+ png_charp key;
+ png_charp text;
+ png_uint_32 skip = 0;
+ png_size_t slength;
+ int ret;
+
+ png_debug(1, "in png_handle_tEXt\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before tEXt");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "tEXt chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+
+ key = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (key == NULL)
+ {
+ png_warning(png_ptr, "No memory to process text chunk.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)key, slength);
+
+ if (png_crc_finish(png_ptr, skip))
+ {
+ png_free(png_ptr, key);
+ return;
+ }
+
+ key[slength] = 0x00;
+
+ for (text = key; *text; text++)
+ /* empty loop to tqfind end of key */ ;
+
+ if (text != key + slength)
+ text++;
+
+ text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
+ if (text_ptr == NULL)
+ {
+ png_warning(png_ptr, "Not enough memory to process text chunk.");
+ png_free(png_ptr, key);
+ return;
+ }
+ text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
+ text_ptr->key = key;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+ text_ptr->itxt_length = 0;
+#endif
+ text_ptr->text = text;
+ text_ptr->text_length = png_strlen(text);
+
+ ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, key);
+ png_free(png_ptr, text_ptr);
+ if (ret)
+ png_warning(png_ptr, "Insufficient memory to process text chunk.");
+}
+#endif
+
+#if defined(PNG_READ_zTXt_SUPPORTED)
+/* note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_textp text_ptr;
+ png_charp chunkdata;
+ png_charp text;
+ int comp_type;
+ int ret;
+ png_size_t slength, prefix_len, data_len;
+
+ png_debug(1, "in png_handle_zTXt\n");
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before zTXt");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ /* We will no doubt have problems with chunks even half this size, but
+ there is no hard and fast rule to tell us where to stop. */
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr,"zTXt chunk too large to fit in memory");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (chunkdata == NULL)
+ {
+ png_warning(png_ptr,"Out of memory processing zTXt chunk.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+
+ chunkdata[slength] = 0x00;
+
+ for (text = chunkdata; *text; text++)
+ /* empty loop */ ;
+
+ /* zTXt must have some text after the chunkdataword */
+ if (text == chunkdata + slength)
+ {
+ comp_type = PNG_TEXT_COMPRESSION_NONE;
+ png_warning(png_ptr, "Zero length zTXt chunk");
+ }
+ else
+ {
+ comp_type = *(++text);
+ if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
+ {
+ png_warning(png_ptr, "Unknown compression type in zTXt chunk");
+ comp_type = PNG_TEXT_COMPRESSION_zTXt;
+ }
+ text++; /* skip the compression_method byte */
+ }
+ prefix_len = text - chunkdata;
+
+ chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
+ (png_size_t)length, prefix_len, &data_len);
+
+ text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
+ if (text_ptr == NULL)
+ {
+ png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+ text_ptr->compression = comp_type;
+ text_ptr->key = chunkdata;
+#ifdef PNG_iTXt_SUPPORTED
+ text_ptr->lang = NULL;
+ text_ptr->lang_key = NULL;
+ text_ptr->itxt_length = 0;
+#endif
+ text_ptr->text = chunkdata + prefix_len;
+ text_ptr->text_length = data_len;
+
+ ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, text_ptr);
+ png_free(png_ptr, chunkdata);
+ if (ret)
+ png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
+}
+#endif
+
+#if defined(PNG_READ_iTXt_SUPPORTED)
+/* note: this does not correctly handle chunks that are > 64K under DOS */
+void /* PRIVATE */
+png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_textp text_ptr;
+ png_charp chunkdata;
+ png_charp key, lang, text, lang_key;
+ int comp_flag;
+ int comp_type = 0;
+ int ret;
+ png_size_t slength, prefix_len, data_len;
+
+ png_debug(1, "in png_handle_iTXt\n");
+
+ if (!(png_ptr->mode & PNG_HAVE_IHDR))
+ png_error(png_ptr, "Missing IHDR before iTXt");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+#ifdef PNG_MAX_MALLOC_64K
+ /* We will no doubt have problems with chunks even half this size, but
+ there is no hard and fast rule to tell us where to stop. */
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr,"iTXt chunk too large to fit in memory");
+ png_crc_finish(png_ptr, length);
+ return;
+ }
+#endif
+
+ chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
+ if (chunkdata == NULL)
+ {
+ png_warning(png_ptr, "No memory to process iTXt chunk.");
+ return;
+ }
+ slength = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
+ if (png_crc_finish(png_ptr, 0))
+ {
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+
+ chunkdata[slength] = 0x00;
+
+ for (lang = chunkdata; *lang; lang++)
+ /* empty loop */ ;
+ lang++; /* skip NUL separator */
+
+ /* iTXt must have a language tag (possibly empty), two compression bytes,
+ translated keyword (possibly empty), and possibly some text after the
+ keyword */
+
+ if (lang >= chunkdata + slength)
+ {
+ comp_flag = PNG_TEXT_COMPRESSION_NONE;
+ png_warning(png_ptr, "Zero length iTXt chunk");
+ }
+ else
+ {
+ comp_flag = *lang++;
+ comp_type = *lang++;
+ }
+
+ for (lang_key = lang; *lang_key; lang_key++)
+ /* empty loop */ ;
+ lang_key++; /* skip NUL separator */
+
+ for (text = lang_key; *text; text++)
+ /* empty loop */ ;
+ text++; /* skip NUL separator */
+
+ prefix_len = text - chunkdata;
+
+ key=chunkdata;
+ if (comp_flag)
+ chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
+ (size_t)length, prefix_len, &data_len);
+ else
+ data_len=png_strlen(chunkdata + prefix_len);
+ text_ptr = (png_textp)png_malloc_warn(png_ptr, (png_uint_32)sizeof(png_text));
+ if (text_ptr == NULL)
+ {
+ png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
+ png_free(png_ptr, chunkdata);
+ return;
+ }
+ text_ptr->compression = (int)comp_flag + 1;
+ text_ptr->lang_key = chunkdata+(lang_key-key);
+ text_ptr->lang = chunkdata+(lang-key);
+ text_ptr->itxt_length = data_len;
+ text_ptr->text_length = 0;
+ text_ptr->key = chunkdata;
+ text_ptr->text = chunkdata + prefix_len;
+
+ ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
+
+ png_free(png_ptr, text_ptr);
+ png_free(png_ptr, chunkdata);
+ if (ret)
+ png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
+}
+#endif
+
+/* This function is called when we haven't found a handler for a
+ chunk. If there isn't a problem with the chunk itself (ie bad
+ chunk name, CRC, or a critical chunk), the chunk is silently ignored
+ -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
+ case it will be saved away to be written out later. */
+void /* PRIVATE */
+png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
+{
+ png_uint_32 skip = 0;
+
+ png_debug(1, "in png_handle_unknown\n");
+
+ if (png_ptr->mode & PNG_HAVE_IDAT)
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IDAT;
+#endif
+ if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* not an IDAT */
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ }
+
+ png_check_chunk_name(png_ptr, png_ptr->chunk_name);
+
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ {
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ HANDLE_CHUNK_ALWAYS
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+ && png_ptr->read_user_chunk_fn == NULL
+#endif
+ )
+#endif
+ png_chunk_error(png_ptr, "unknown critical chunk");
+ }
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
+ {
+ png_unknown_chunk chunk;
+
+#ifdef PNG_MAX_MALLOC_64K
+ if (length > (png_uint_32)65535L)
+ {
+ png_warning(png_ptr, "unknown chunk too large to fit in memory");
+ skip = length - (png_uint_32)65535L;
+ length = (png_uint_32)65535L;
+ }
+#endif
+ png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name);
+ chunk.data = (png_bytep)png_malloc(png_ptr, length);
+ chunk.size = (png_size_t)length;
+ png_crc_read(png_ptr, (png_bytep)chunk.data, length);
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+ if(png_ptr->read_user_chunk_fn != NULL)
+ {
+ /* callback to user unknown chunk handler */
+ if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0)
+ {
+ if (!(png_ptr->chunk_name[0] & 0x20))
+ if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
+ HANDLE_CHUNK_ALWAYS)
+ {
+ png_free(png_ptr, chunk.data);
+ png_chunk_error(png_ptr, "unknown critical chunk");
+ }
+ png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+ }
+ }
+ else
+#endif
+ png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1);
+ png_free(png_ptr, chunk.data);
+ }
+ else
+#endif
+ skip = length;
+
+ png_crc_finish(png_ptr, skip);
+
+#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+ info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
+#endif
+}
+
+/* This function is called to verify that a chunk name is valid.
+ This function can't have the "critical chunk check" incorporated
+ into it, since in the future we will need to be able to call user
+ functions to handle unknown critical chunks after we check that
+ the chunk name itself is valid. */
+
+#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
+
+void /* PRIVATE */
+png_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
+{
+ png_debug(1, "in png_check_chunk_name\n");
+ if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
+ isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
+ {
+ png_chunk_error(png_ptr, "invalid chunk type");
+ }
+}
+
+/* Combines the row recently read in with the existing pixels in the
+ row. This routine takes care of alpha and transparency if requested.
+ This routine also handles the two methods of progressive display
+ of interlaced images, depending on the tqmask value.
+ The tqmask value describes which pixels are to be combined with
+ the row. The pattern always repeats every 8 pixels, so just 8
+ bits are needed. A one indicates the pixel is to be combined,
+ a zero indicates the pixel is to be skipped. This is in addition
+ to any alpha or transparency value associated with the pixel. If
+ you want all pixels to be combined, pass 0xff (255) in tqmask. */
+#ifndef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+void /* PRIVATE */
+png_combine_row(png_structp png_ptr, png_bytep row, int tqmask)
+{
+ png_debug(1,"in png_combine_row\n");
+ if (tqmask == 0xff)
+ {
+ png_memcpy(row, png_ptr->row_buf + 1,
+ (png_size_t)((png_ptr->width *
+ png_ptr->row_info.pixel_depth + 7) >> 3));
+ }
+ else
+ {
+ switch (png_ptr->row_info.pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ int s_inc, s_start, s_end;
+ int m = 0x80;
+ int shift;
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+ else
+#endif
+ {
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+
+ shift = s_start;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & tqmask)
+ {
+ int value;
+
+ value = (*sp >> shift) & 0x01;
+ *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ int s_start, s_end, s_inc;
+ int m = 0x80;
+ int shift;
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+ int value;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+ else
+#endif
+ {
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+
+ shift = s_start;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & tqmask)
+ {
+ value = (*sp >> shift) & 0x03;
+ *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ int s_start, s_end, s_inc;
+ int m = 0x80;
+ int shift;
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+ int value;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+ else
+#endif
+ {
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+ shift = s_start;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & tqmask)
+ {
+ value = (*sp >> shift) & 0xf;
+ *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ default:
+ {
+ png_bytep sp = png_ptr->row_buf + 1;
+ png_bytep dp = row;
+ png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+ png_uint_32 i;
+ png_uint_32 row_width = png_ptr->width;
+ png_byte m = 0x80;
+
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (m & tqmask)
+ {
+ png_memcpy(dp, sp, pixel_bytes);
+ }
+
+ sp += pixel_bytes;
+ dp += pixel_bytes;
+
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+ }
+ }
+}
+#endif /* !PNG_HAVE_ASSEMBLER_COMBINE_ROW */
+
+#ifdef PNG_READ_INTERLACING_SUPPORTED
+#ifndef PNG_HAVE_ASSEMBLER_READ_INTERLACE /* else in pngvcrd.c, pnggccrd.c */
+/* OLD pre-1.0.9 interface:
+void png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
+ png_uint_32 transformations)
+ */
+void /* PRIVATE */
+png_do_read_interlace(png_structp png_ptr)
+{
+ png_row_infop row_info = &(png_ptr->row_info);
+ png_bytep row = png_ptr->row_buf + 1;
+ int pass = png_ptr->pass;
+ png_uint_32 transformations = png_ptr->transformations;
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+ /* offset to next interlace block */
+ const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+
+ png_debug(1,"in png_do_read_interlace (stock C version)\n");
+ if (row != NULL && row_info != NULL)
+ {
+ png_uint_32 final_width;
+
+ final_width = row_info->width * png_pass_inc[pass];
+
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ int jstop = png_pass_inc[pass];
+ png_byte v;
+ png_uint_32 i;
+ int j;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)((row_info->width + 7) & 0x07);
+ dshift = (int)((final_width + 7) & 0x07);
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+ else
+#endif
+ {
+ sshift = 7 - (int)((row_info->width + 7) & 0x07);
+ dshift = 7 - (int)((final_width + 7) & 0x07);
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ v = (png_byte)((*sp >> sshift) & 0x01);
+ for (j = 0; j < jstop; j++)
+ {
+ *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
+ png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ int jstop = png_pass_inc[pass];
+ png_uint_32 i;
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)(((row_info->width + 3) & 0x03) << 1);
+ dshift = (int)(((final_width + 3) & 0x03) << 1);
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+ else
+#endif
+ {
+ sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
+ dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v;
+ int j;
+
+ v = (png_byte)((*sp >> sshift) & 0x03);
+ for (j = 0; j < jstop; j++)
+ {
+ *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
+ png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ png_uint_32 i;
+ int jstop = png_pass_inc[pass];
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)(((row_info->width + 1) & 0x01) << 2);
+ dshift = (int)(((final_width + 1) & 0x01) << 2);
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+ else
+#endif
+ {
+ sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
+ dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v = (png_byte)((*sp >> sshift) & 0xf);
+ int j;
+
+ for (j = 0; j < jstop; j++)
+ {
+ *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+ default:
+ {
+ png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
+ png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
+ png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
+
+ int jstop = png_pass_inc[pass];
+ png_uint_32 i;
+
+ for (i = 0; i < row_info->width; i++)
+ {
+ png_byte v[8];
+ int j;
+
+ png_memcpy(v, sp, pixel_bytes);
+ for (j = 0; j < jstop; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sp -= pixel_bytes;
+ }
+ break;
+ }
+ }
+ row_info->width = final_width;
+ row_info->rowbytes = ((final_width *
+ (png_uint_32)row_info->pixel_depth + 7) >> 3);
+ }
+#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
+ transformations = transformations; /* silence compiler warning */
+#endif
+}
+#endif /* !PNG_HAVE_ASSEMBLER_READ_INTERLACE */
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+#ifndef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+void /* PRIVATE */
+png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
+ png_bytep prev_row, int filter)
+{
+ png_debug(1, "in png_read_filter_row\n");
+ png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
+ switch (filter)
+ {
+ case PNG_FILTER_VALUE_NONE:
+ break;
+ case PNG_FILTER_VALUE_SUB:
+ {
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_bytep rp = row + bpp;
+ png_bytep lp = row;
+
+ for (i = bpp; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ case PNG_FILTER_VALUE_UP:
+ {
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ case PNG_FILTER_VALUE_AVG:
+ {
+ png_uint_32 i;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+ png_bytep lp = row;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_uint_32 istop = row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++) / 2 )) & 0xff);
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ (int)(*pp++ + *lp++) / 2 ) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ case PNG_FILTER_VALUE_PAETH:
+ {
+ png_uint_32 i;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+ png_bytep lp = row;
+ png_bytep cp = prev_row;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_uint_32 istop=row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++) /* use leftover rp,pp */
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ a = *lp++;
+ b = *pp++;
+ c = *cp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ /*
+ if (pa <= pb && pa <= pc)
+ p = a;
+ else if (pb <= pc)
+ p = b;
+ else
+ p = c;
+ */
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ *rp = (png_byte)(((int)(*rp) + p) & 0xff);
+ rp++;
+ }
+ break;
+ }
+ default:
+ png_warning(png_ptr, "Ignoring bad adaptive filter type");
+ *row=0;
+ break;
+ }
+}
+#endif /* !PNG_HAVE_ASSEMBLER_READ_FILTER_ROW */
+
+void /* PRIVATE */
+png_read_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ png_debug(1, "in png_read_finish_row\n");
+ png_ptr->row_number++;
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+ do
+ {
+ png_ptr->pass++;
+ if (png_ptr->pass >= 7)
+ break;
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+ png_ptr->irowbytes = ((png_ptr->iwidth *
+ (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
+
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+ if (!(png_ptr->num_rows))
+ continue;
+ }
+ else /* if (png_ptr->transformations & PNG_INTERLACE) */
+ break;
+ } while (png_ptr->iwidth == 0);
+
+ if (png_ptr->pass < 7)
+ return;
+ }
+
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
+ {
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IDAT;
+#endif
+ char extra;
+ int ret;
+
+ png_ptr->zstream.next_out = (Byte *)&extra;
+ png_ptr->zstream.avail_out = (uInt)1;
+ for(;;)
+ {
+ if (!(png_ptr->zstream.avail_in))
+ {
+ while (!png_ptr->idat_size)
+ {
+ png_byte chunk_length[4];
+
+ png_crc_finish(png_ptr, 0);
+
+ png_read_data(png_ptr, chunk_length, 4);
+ png_ptr->idat_size = png_get_uint_32(chunk_length);
+
+ png_reset_crc(png_ptr);
+ png_crc_read(png_ptr, png_ptr->chunk_name, 4);
+ if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
+ png_error(png_ptr, "Not enough image data");
+
+ }
+ png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_in = png_ptr->zbuf;
+ if (png_ptr->zbuf_size > png_ptr->idat_size)
+ png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
+ png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
+ png_ptr->idat_size -= png_ptr->zstream.avail_in;
+ }
+ ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
+ if (ret == Z_STREAM_END)
+ {
+ if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
+ png_ptr->idat_size)
+ png_warning(png_ptr, "Extra compressed data");
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+ if (ret != Z_OK)
+ png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
+ "Decompression Error");
+
+ if (!(png_ptr->zstream.avail_out))
+ {
+ png_warning(png_ptr, "Extra compressed data.");
+ png_ptr->mode |= PNG_AFTER_IDAT;
+ png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+ break;
+ }
+
+ }
+ png_ptr->zstream.avail_out = 0;
+ }
+
+ if (png_ptr->idat_size || png_ptr->zstream.avail_in)
+ png_warning(png_ptr, "Extra compression data");
+
+ inflateReset(&png_ptr->zstream);
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+}
+
+void /* PRIVATE */
+png_read_start_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ const int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ const int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ const int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ int max_pixel_depth;
+ png_uint_32 row_bytes;
+
+ png_debug(1, "in png_read_start_row\n");
+ png_ptr->zstream.avail_in = 0;
+ png_init_read_transformations(png_ptr);
+ if (png_ptr->interlaced)
+ {
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+ else
+ png_ptr->num_rows = png_ptr->height;
+
+ png_ptr->iwidth = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+
+ row_bytes = ((png_ptr->iwidth *
+ (png_uint_32)png_ptr->pixel_depth + 7) >> 3) +1;
+ png_ptr->irowbytes = (png_size_t)row_bytes;
+ if((png_uint_32)png_ptr->irowbytes != row_bytes)
+ png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
+ }
+ else
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->iwidth = png_ptr->width;
+ png_ptr->irowbytes = png_ptr->rowbytes + 1;
+ }
+ max_pixel_depth = png_ptr->pixel_depth;
+
+#if defined(PNG_READ_PACK_SUPPORTED)
+ if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
+ max_pixel_depth = 8;
+#endif
+
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ if (png_ptr->transformations & PNG_EXPAND)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (png_ptr->num_trans)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 24;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (max_pixel_depth < 8)
+ max_pixel_depth = 8;
+ if (png_ptr->num_trans)
+ max_pixel_depth *= 2;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (png_ptr->num_trans)
+ {
+ max_pixel_depth *= 4;
+ max_pixel_depth /= 3;
+ }
+ }
+ }
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & (PNG_FILLER))
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ max_pixel_depth = 32;
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ if (max_pixel_depth <= 8)
+ max_pixel_depth = 16;
+ else
+ max_pixel_depth = 32;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ if (max_pixel_depth <= 32)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 64;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+ if (png_ptr->transformations & PNG_GRAY_TO_RGB)
+ {
+ if (
+#if defined(PNG_READ_EXPAND_SUPPORTED)
+ (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
+#endif
+#if defined(PNG_READ_FILLER_SUPPORTED)
+ (png_ptr->transformations & (PNG_FILLER)) ||
+#endif
+ png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ if (max_pixel_depth <= 16)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 64;
+ }
+ else
+ {
+ if (max_pixel_depth <= 8)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ max_pixel_depth = 32;
+ else
+ max_pixel_depth = 24;
+ }
+ else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ max_pixel_depth = 64;
+ else
+ max_pixel_depth = 48;
+ }
+ }
+#endif
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
+defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ if(png_ptr->transformations & PNG_USER_TRANSFORM)
+ {
+ int user_pixel_depth=png_ptr->user_transform_depth*
+ png_ptr->user_transform_channels;
+ if(user_pixel_depth > max_pixel_depth)
+ max_pixel_depth=user_pixel_depth;
+ }
+#endif
+
+ /* align the width on the next larger 8 pixels. Mainly used
+ for interlacing */
+ row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
+ /* calculate the maximum bytes needed, adding a byte and a pixel
+ for safety's sake */
+ row_bytes = ((row_bytes * (png_uint_32)max_pixel_depth + 7) >> 3) +
+ 1 + ((max_pixel_depth + 7) >> 3);
+#ifdef PNG_MAX_MALLOC_64K
+ if (row_bytes > (png_uint_32)65536L)
+ png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+ png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
+ png_ptr->row_buf = png_ptr->big_row_buf+32;
+#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD)
+ png_ptr->row_buf_size = row_bytes;
+#endif
+
+#ifdef PNG_MAX_MALLOC_64K
+ if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
+ png_error(png_ptr, "This image requires a row greater than 64KB");
+#endif
+ png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
+ png_ptr->rowbytes + 1));
+
+ png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
+
+ png_debug1(3, "width = %lu,\n", png_ptr->width);
+ png_debug1(3, "height = %lu,\n", png_ptr->height);
+ png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
+ png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
+ png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
+ png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
+
+ png_ptr->flags |= PNG_FLAG_ROW_INIT;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngset.c b/tqtinterface/qt4/src/3rdparty/libpng/pngset.c
new file mode 100644
index 0000000..86805b1
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngset.c
@@ -0,0 +1,1162 @@
+
+/* pngset.c - storage of image information into info struct
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * The functions here are used during reads to store data from the file
+ * into the info struct, and during writes to store application data
+ * into the info struct for writing into the file. This abstracts the
+ * info struct and allows us to change the structure in the future.
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_bKGD_SUPPORTED)
+void PNGAPI
+png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
+{
+ png_debug1(1, "in %s storage function\n", "bKGD");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_memcpy(&(info_ptr->background), background, sizeof(png_color_16));
+ info_ptr->valid |= PNG_INFO_bKGD;
+}
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
+ double white_x, double white_y, double red_x, double red_y,
+ double green_x, double green_y, double blue_x, double blue_y)
+{
+ png_debug1(1, "in %s storage function\n", "cHRM");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (white_x < 0.0 || white_y < 0.0 ||
+ red_x < 0.0 || red_y < 0.0 ||
+ green_x < 0.0 || green_y < 0.0 ||
+ blue_x < 0.0 || blue_y < 0.0)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set negative chromaticity value");
+ return;
+ }
+ if (white_x > 21474.83 || white_y > 21474.83 ||
+ red_x > 21474.83 || red_y > 21474.83 ||
+ green_x > 21474.83 || green_y > 21474.83 ||
+ blue_x > 21474.83 || blue_y > 21474.83)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set chromaticity value exceeding 21474.83");
+ return;
+ }
+
+ info_ptr->x_white = (float)white_x;
+ info_ptr->y_white = (float)white_y;
+ info_ptr->x_red = (float)red_x;
+ info_ptr->y_red = (float)red_y;
+ info_ptr->x_green = (float)green_x;
+ info_ptr->y_green = (float)green_y;
+ info_ptr->x_blue = (float)blue_x;
+ info_ptr->y_blue = (float)blue_y;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_x_white = (png_fixed_point)(white_x*100000.+0.5);
+ info_ptr->int_y_white = (png_fixed_point)(white_y*100000.+0.5);
+ info_ptr->int_x_red = (png_fixed_point)( red_x*100000.+0.5);
+ info_ptr->int_y_red = (png_fixed_point)( red_y*100000.+0.5);
+ info_ptr->int_x_green = (png_fixed_point)(green_x*100000.+0.5);
+ info_ptr->int_y_green = (png_fixed_point)(green_y*100000.+0.5);
+ info_ptr->int_x_blue = (png_fixed_point)( blue_x*100000.+0.5);
+ info_ptr->int_y_blue = (png_fixed_point)( blue_y*100000.+0.5);
+#endif
+ info_ptr->valid |= PNG_INFO_cHRM;
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_cHRM_fixed(png_structp png_ptr, png_infop info_ptr,
+ png_fixed_point white_x, png_fixed_point white_y, png_fixed_point red_x,
+ png_fixed_point red_y, png_fixed_point green_x, png_fixed_point green_y,
+ png_fixed_point blue_x, png_fixed_point blue_y)
+{
+ png_debug1(1, "in %s storage function\n", "cHRM");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (white_x < 0 || white_y < 0 ||
+ red_x < 0 || red_y < 0 ||
+ green_x < 0 || green_y < 0 ||
+ blue_x < 0 || blue_y < 0)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set negative chromaticity value");
+ return;
+ }
+ if (white_x > (double) PNG_MAX_UINT || white_y > (double) PNG_MAX_UINT ||
+ red_x > (double) PNG_MAX_UINT || red_y > (double) PNG_MAX_UINT ||
+ green_x > (double) PNG_MAX_UINT || green_y > (double) PNG_MAX_UINT ||
+ blue_x > (double) PNG_MAX_UINT || blue_y > (double) PNG_MAX_UINT)
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to set chromaticity value exceeding 21474.83");
+ return;
+ }
+ info_ptr->int_x_white = white_x;
+ info_ptr->int_y_white = white_y;
+ info_ptr->int_x_red = red_x;
+ info_ptr->int_y_red = red_y;
+ info_ptr->int_x_green = green_x;
+ info_ptr->int_y_green = green_y;
+ info_ptr->int_x_blue = blue_x;
+ info_ptr->int_y_blue = blue_y;
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ info_ptr->x_white = (float)(white_x/100000.);
+ info_ptr->y_white = (float)(white_y/100000.);
+ info_ptr->x_red = (float)( red_x/100000.);
+ info_ptr->y_red = (float)( red_y/100000.);
+ info_ptr->x_green = (float)(green_x/100000.);
+ info_ptr->y_green = (float)(green_y/100000.);
+ info_ptr->x_blue = (float)( blue_x/100000.);
+ info_ptr->y_blue = (float)( blue_y/100000.);
+#endif
+ info_ptr->valid |= PNG_INFO_cHRM;
+}
+#endif
+#endif
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
+{
+ double gamma;
+ png_debug1(1, "in %s storage function\n", "gAMA");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* Check for overflow */
+ if (file_gamma > 21474.83)
+ {
+ png_warning(png_ptr, "Limiting gamma to 21474.83");
+ gamma=21474.83;
+ }
+ else
+ gamma=file_gamma;
+ info_ptr->gamma = (float)gamma;
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_gamma = (int)(gamma*100000.+.5);
+#endif
+ info_ptr->valid |= PNG_INFO_gAMA;
+ if(gamma == 0.0)
+ png_warning(png_ptr, "Setting gamma=0");
+}
+#endif
+void PNGAPI
+png_set_gAMA_fixed(png_structp png_ptr, png_infop info_ptr, png_fixed_point
+ int_gamma)
+{
+ png_fixed_point gamma;
+
+ png_debug1(1, "in %s storage function\n", "gAMA");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (int_gamma > (png_fixed_point) PNG_MAX_UINT)
+ {
+ png_warning(png_ptr, "Limiting gamma to 21474.83");
+ gamma=PNG_MAX_UINT;
+ }
+ else
+ {
+ if (int_gamma < 0)
+ {
+ png_warning(png_ptr, "Setting negative gamma to zero");
+ gamma=0;
+ }
+ else
+ gamma=int_gamma;
+ }
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ info_ptr->gamma = (float)(gamma/100000.);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ info_ptr->int_gamma = gamma;
+#endif
+ info_ptr->valid |= PNG_INFO_gAMA;
+ if(gamma == 0)
+ png_warning(png_ptr, "Setting gamma=0");
+}
+#endif
+
+#if defined(PNG_hIST_SUPPORTED)
+void PNGAPI
+png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
+{
+ int i;
+
+ png_debug1(1, "in %s storage function\n", "hIST");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+ if (info_ptr->num_palette == 0)
+ {
+ png_warning(png_ptr,
+ "Palette size 0, hIST allocation skipped.");
+ return;
+ }
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_HIST, 0);
+#endif
+ /* Changed from info->num_palette to 256 in version 1.2.1 */
+ png_ptr->hist = (png_uint_16p)png_malloc_warn(png_ptr,
+ (png_uint_32)(256 * sizeof (png_uint_16)));
+ if (png_ptr->hist == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for hIST chunk data.");
+ return;
+ }
+
+ for (i = 0; i < info_ptr->num_palette; i++)
+ png_ptr->hist[i] = hist[i];
+ info_ptr->hist = png_ptr->hist;
+ info_ptr->valid |= PNG_INFO_hIST;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_HIST;
+#else
+ png_ptr->flags |= PNG_FLAG_FREE_HIST;
+#endif
+}
+#endif
+
+void PNGAPI
+png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 width, png_uint_32 height, int bit_depth,
+ int color_type, int interlace_type, int compression_type,
+ int filter_type)
+{
+ int rowbytes_per_pixel;
+ png_debug1(1, "in %s storage function\n", "IHDR");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /* check for width and height valid values */
+ if (width == 0 || height == 0)
+ png_error(png_ptr, "Image width or height is zero in IHDR");
+ if (width > PNG_MAX_UINT || height > PNG_MAX_UINT)
+ png_error(png_ptr, "Invalid image size in IHDR");
+ if (width > PNG_USER_WIDTH_MAX || height > PNG_USER_HEIGHT_MAX)
+ png_error(png_ptr, "image size exceeds user limits in IHDR");
+
+ /* check other values */
+ if (bit_depth != 1 && bit_depth != 2 && bit_depth != 4 &&
+ bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth in IHDR");
+
+ if (color_type < 0 || color_type == 1 ||
+ color_type == 5 || color_type > 6)
+ png_error(png_ptr, "Invalid color type in IHDR");
+
+ if (((color_type == PNG_COLOR_TYPE_PALETTE) && bit_depth > 8) ||
+ ((color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_GRAY_ALPHA ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8))
+ png_error(png_ptr, "Invalid color type/bit depth combination in IHDR");
+
+ if (interlace_type >= PNG_INTERLACE_LAST)
+ png_error(png_ptr, "Unknown interlace method in IHDR");
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ png_error(png_ptr, "Unknown compression method in IHDR");
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ /* Accept filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not read a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a tqmask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&png_ptr->mng_features_permitted)
+ png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n");
+ if(filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ if(!((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING) &&
+ ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
+ png_error(png_ptr, "Unknown filter method in IHDR");
+ if(png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)
+ png_warning(png_ptr, "Invalid filter method in IHDR");
+ }
+#else
+ if(filter_type != PNG_FILTER_TYPE_BASE)
+ png_error(png_ptr, "Unknown filter method in IHDR");
+#endif
+
+ info_ptr->width = width;
+ info_ptr->height = height;
+ info_ptr->bit_depth = (png_byte)bit_depth;
+ info_ptr->color_type =(png_byte) color_type;
+ info_ptr->compression_type = (png_byte)compression_type;
+ info_ptr->filter_type = (png_byte)filter_type;
+ info_ptr->interlace_type = (png_byte)interlace_type;
+ if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ info_ptr->channels = 1;
+ else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
+ info_ptr->channels = 3;
+ else
+ info_ptr->channels = 1;
+ if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
+ info_ptr->channels++;
+ info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
+
+ /* check for overflow */
+ rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3;
+ if ( width > PNG_MAX_UINT/rowbytes_per_pixel - 64)
+ {
+ png_warning(png_ptr,
+ "Width too large to process image data; rowbytes will overflow.");
+ info_ptr->rowbytes = (png_size_t)0;
+ }
+ else
+ info_ptr->rowbytes = (info_ptr->width * info_ptr->pixel_depth + 7) >> 3;
+}
+
+#if defined(PNG_oFFs_SUPPORTED)
+void PNGAPI
+png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
+ png_int_32 offset_x, png_int_32 offset_y, int unit_type)
+{
+ png_debug1(1, "in %s storage function\n", "oFFs");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_offset = offset_x;
+ info_ptr->y_offset = offset_y;
+ info_ptr->offset_unit_type = (png_byte)unit_type;
+ info_ptr->valid |= PNG_INFO_oFFs;
+}
+#endif
+
+#if defined(PNG_pCAL_SUPPORTED)
+void PNGAPI
+png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
+ png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
+ png_charp units, png_charpp params)
+{
+ png_uint_32 length;
+ int i;
+
+ png_debug1(1, "in %s storage function\n", "pCAL");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ length = png_strlen(purpose) + 1;
+ png_debug1(3, "allocating purpose for info (%lu bytes)\n", length);
+ info_ptr->pcal_purpose = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->pcal_purpose == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL purpose.");
+ return;
+ }
+ png_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
+
+ png_debug(3, "storing X0, X1, type, and nparams in info\n");
+ info_ptr->pcal_X0 = X0;
+ info_ptr->pcal_X1 = X1;
+ info_ptr->pcal_type = (png_byte)type;
+ info_ptr->pcal_nparams = (png_byte)nparams;
+
+ length = png_strlen(units) + 1;
+ png_debug1(3, "allocating units for info (%lu bytes)\n", length);
+ info_ptr->pcal_units = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->pcal_units == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL units.");
+ return;
+ }
+ png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
+
+ info_ptr->pcal_params = (png_charpp)png_malloc_warn(png_ptr,
+ (png_uint_32)((nparams + 1) * sizeof(png_charp)));
+ if (info_ptr->pcal_params == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL params.");
+ return;
+ }
+
+ info_ptr->pcal_params[nparams] = NULL;
+
+ for (i = 0; i < nparams; i++)
+ {
+ length = png_strlen(params[i]) + 1;
+ png_debug2(3, "allocating parameter %d for info (%lu bytes)\n", i, length);
+ info_ptr->pcal_params[i] = (png_charp)png_malloc_warn(png_ptr, length);
+ if (info_ptr->pcal_params[i] == NULL)
+ {
+ png_warning(png_ptr, "Insufficient memory for pCAL parameter.");
+ return;
+ }
+ png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
+ }
+
+ info_ptr->valid |= PNG_INFO_pCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_PCAL;
+#endif
+}
+#endif
+
+#if defined(PNG_READ_sCAL_SUPPORTED) || defined(PNG_WRITE_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL(png_structp png_ptr, png_infop info_ptr,
+ int unit, double width, double height)
+{
+ png_debug1(1, "in %s storage function\n", "sCAL");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->scal_unit = (png_byte)unit;
+ info_ptr->scal_pixel_width = width;
+ info_ptr->scal_pixel_height = height;
+
+ info_ptr->valid |= PNG_INFO_sCAL;
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void PNGAPI
+png_set_sCAL_s(png_structp png_ptr, png_infop info_ptr,
+ int unit, png_charp swidth, png_charp sheight)
+{
+ png_uint_32 length;
+
+ png_debug1(1, "in %s storage function\n", "sCAL");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->scal_unit = (png_byte)unit;
+
+ length = png_strlen(swidth) + 1;
+ png_debug1(3, "allocating unit for info (%d bytes)\n", length);
+ info_ptr->scal_s_width = (png_charp)png_malloc(png_ptr, length);
+ png_memcpy(info_ptr->scal_s_width, swidth, (png_size_t)length);
+
+ length = png_strlen(sheight) + 1;
+ png_debug1(3, "allocating unit for info (%d bytes)\n", length);
+ info_ptr->scal_s_height = (png_charp)png_malloc(png_ptr, length);
+ png_memcpy(info_ptr->scal_s_height, sheight, (png_size_t)length);
+
+ info_ptr->valid |= PNG_INFO_sCAL;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_SCAL;
+#endif
+}
+#endif
+#endif
+#endif
+
+#if defined(PNG_pHYs_SUPPORTED)
+void PNGAPI
+png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
+ png_uint_32 res_x, png_uint_32 res_y, int unit_type)
+{
+ png_debug1(1, "in %s storage function\n", "pHYs");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->x_pixels_per_unit = res_x;
+ info_ptr->y_pixels_per_unit = res_y;
+ info_ptr->phys_unit_type = (png_byte)unit_type;
+ info_ptr->valid |= PNG_INFO_pHYs;
+}
+#endif
+
+void PNGAPI
+png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
+ png_colorp palette, int num_palette)
+{
+
+ png_debug1(1, "in %s storage function\n", "PLTE");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ /*
+ * It may not actually be necessary to set png_ptr->palette here;
+ * we do it for backward compatibility with the way the png_handle_tRNS
+ * function used to do the allocation.
+ */
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_PLTE, 0);
+#endif
+ /* Changed in libpng-1.2.1 to allocate 256 instead of num_palette entries,
+ in case of an invalid PNG file that has too-large sample values. */
+ png_ptr->palette = (png_colorp)png_zalloc(png_ptr, (uInt)256,
+ sizeof (png_color));
+ if (png_ptr->palette == NULL)
+ png_error(png_ptr, "Unable to malloc palette");
+ png_memcpy(png_ptr->palette, palette, num_palette * sizeof (png_color));
+ info_ptr->palette = png_ptr->palette;
+ info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
+
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_PLTE;
+#else
+ png_ptr->flags |= PNG_FLAG_FREE_PLTE;
+#endif
+
+ info_ptr->valid |= PNG_INFO_PLTE;
+}
+
+#if defined(PNG_sBIT_SUPPORTED)
+void PNGAPI
+png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
+ png_color_8p sig_bit)
+{
+ png_debug1(1, "in %s storage function\n", "sBIT");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_memcpy(&(info_ptr->sig_bit), sig_bit, sizeof (png_color_8));
+ info_ptr->valid |= PNG_INFO_sBIT;
+}
+#endif
+
+#if defined(PNG_sRGB_SUPPORTED)
+void PNGAPI
+png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
+{
+ png_debug1(1, "in %s storage function\n", "sRGB");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ info_ptr->srgb_intent = (png_byte)intent;
+ info_ptr->valid |= PNG_INFO_sRGB;
+}
+
+void PNGAPI
+png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
+ int intent)
+{
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float file_gamma;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_fixed_point int_file_gamma;
+#endif
+#endif
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_fixed_point int_white_x, int_white_y, int_red_x, int_red_y, int_green_x,
+ int_green_y, int_blue_x, int_blue_y;
+#endif
+#endif
+ png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ png_set_sRGB(png_ptr, info_ptr, intent);
+
+#if defined(PNG_gAMA_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ file_gamma = (float).45455;
+ png_set_gAMA(png_ptr, info_ptr, file_gamma);
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ int_file_gamma = 45455L;
+ png_set_gAMA_fixed(png_ptr, info_ptr, int_file_gamma);
+#endif
+#endif
+
+#if defined(PNG_cHRM_SUPPORTED)
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ int_white_x = 31270L;
+ int_white_y = 32900L;
+ int_red_x = 64000L;
+ int_red_y = 33000L;
+ int_green_x = 30000L;
+ int_green_y = 60000L;
+ int_blue_x = 15000L;
+ int_blue_y = 6000L;
+
+ png_set_cHRM_fixed(png_ptr, info_ptr,
+ int_white_x, int_white_y, int_red_x, int_red_y, int_green_x, int_green_y,
+ int_blue_x, int_blue_y);
+#endif
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ white_x = (float).3127;
+ white_y = (float).3290;
+ red_x = (float).64;
+ red_y = (float).33;
+ green_x = (float).30;
+ green_y = (float).60;
+ blue_x = (float).15;
+ blue_y = (float).06;
+
+ png_set_cHRM(png_ptr, info_ptr,
+ white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
+#endif
+#endif
+}
+#endif
+
+
+#if defined(PNG_iCCP_SUPPORTED)
+void PNGAPI
+png_set_iCCP(png_structp png_ptr, png_infop info_ptr,
+ png_charp name, int compression_type,
+ png_charp profile, png_uint_32 proflen)
+{
+ png_charp new_iccp_name;
+ png_charp new_iccp_profile;
+
+ png_debug1(1, "in %s storage function\n", "iCCP");
+ if (png_ptr == NULL || info_ptr == NULL || name == NULL || profile == NULL)
+ return;
+
+ new_iccp_name = (png_charp)png_malloc(png_ptr, png_strlen(name)+1);
+ png_strcpy(new_iccp_name, name);
+ new_iccp_profile = (png_charp)png_malloc(png_ptr, proflen);
+ png_memcpy(new_iccp_profile, profile, (png_size_t)proflen);
+
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ICCP, 0);
+
+ info_ptr->iccp_proflen = proflen;
+ info_ptr->iccp_name = new_iccp_name;
+ info_ptr->iccp_profile = new_iccp_profile;
+ /* Compression is always zero but is here so the API and info structure
+ * does not have to change if we introduce multiple compression types */
+ info_ptr->iccp_compression = (png_byte)compression_type;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_ICCP;
+#endif
+ info_ptr->valid |= PNG_INFO_iCCP;
+}
+#endif
+
+#if defined(PNG_TEXT_SUPPORTED)
+void PNGAPI
+png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+ int num_text)
+{
+ int ret;
+ ret=png_set_text_2(png_ptr, info_ptr, text_ptr, num_text);
+ if (ret)
+ png_error(png_ptr, "Insufficient memory to store text");
+}
+
+int /* PRIVATE */
+png_set_text_2(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
+ int num_text)
+{
+ int i;
+
+ png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
+ "text" : (png_const_charp)png_ptr->chunk_name));
+
+ if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
+ return(0);
+
+ /* Make sure we have enough space in the "text" array in info_struct
+ * to hold all of the incoming text_ptr objects.
+ */
+ if (info_ptr->num_text + num_text > info_ptr->max_text)
+ {
+ if (info_ptr->text != NULL)
+ {
+ png_textp old_text;
+ int old_max;
+
+ old_max = info_ptr->max_text;
+ info_ptr->max_text = info_ptr->num_text + num_text + 8;
+ old_text = info_ptr->text;
+ info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
+ if (info_ptr->text == NULL)
+ {
+ png_free(png_ptr, old_text);
+ return(1);
+ }
+ png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
+ sizeof(png_text)));
+ png_free(png_ptr, old_text);
+ }
+ else
+ {
+ info_ptr->max_text = num_text + 8;
+ info_ptr->num_text = 0;
+ info_ptr->text = (png_textp)png_malloc_warn(png_ptr,
+ (png_uint_32)(info_ptr->max_text * sizeof (png_text)));
+ if (info_ptr->text == NULL)
+ return(1);
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_TEXT;
+#endif
+ }
+ png_debug1(3, "allocated %d entries for info_ptr->text\n",
+ info_ptr->max_text);
+ }
+ for (i = 0; i < num_text; i++)
+ {
+ png_size_t text_length,key_len;
+ png_size_t lang_len,lang_key_len;
+ png_textp textp = &(info_ptr->text[info_ptr->num_text]);
+
+ if (text_ptr[i].key == NULL)
+ continue;
+
+ key_len = png_strlen(text_ptr[i].key);
+
+ if(text_ptr[i].compression <= 0)
+ {
+ lang_len = 0;
+ lang_key_len = 0;
+ }
+ else
+#ifdef PNG_iTXt_SUPPORTED
+ {
+ /* set iTXt data */
+ if (text_ptr[i].lang != NULL)
+ lang_len = png_strlen(text_ptr[i].lang);
+ else
+ lang_len = 0;
+ if (text_ptr[i].lang_key != NULL)
+ lang_key_len = png_strlen(text_ptr[i].lang_key);
+ else
+ lang_key_len = 0;
+ }
+#else
+ {
+ png_warning(png_ptr, "iTXt chunk not supported.");
+ continue;
+ }
+#endif
+
+ if (text_ptr[i].text == NULL || text_ptr[i].text[0] == '\0')
+ {
+ text_length = 0;
+#ifdef PNG_iTXt_SUPPORTED
+ if(text_ptr[i].compression > 0)
+ textp->compression = PNG_ITXT_COMPRESSION_NONE;
+ else
+#endif
+ textp->compression = PNG_TEXT_COMPRESSION_NONE;
+ }
+ else
+ {
+ text_length = png_strlen(text_ptr[i].text);
+ textp->compression = text_ptr[i].compression;
+ }
+
+ textp->key = (png_charp)png_malloc_warn(png_ptr,
+ (png_uint_32)(key_len + text_length + lang_len + lang_key_len + 4));
+ if (textp->key == NULL)
+ return(1);
+ png_debug2(2, "Allocated %lu bytes at %x in png_set_text\n",
+ (png_uint_32)(key_len + lang_len + lang_key_len + text_length + 4),
+ (int)textp->key);
+
+ png_memcpy(textp->key, text_ptr[i].key,
+ (png_size_t)(key_len));
+ *(textp->key+key_len) = '\0';
+#ifdef PNG_iTXt_SUPPORTED
+ if (text_ptr[i].compression > 0)
+ {
+ textp->lang=textp->key + key_len + 1;
+ png_memcpy(textp->lang, text_ptr[i].lang, lang_len);
+ *(textp->lang+lang_len) = '\0';
+ textp->lang_key=textp->lang + lang_len + 1;
+ png_memcpy(textp->lang_key, text_ptr[i].lang_key, lang_key_len);
+ *(textp->lang_key+lang_key_len) = '\0';
+ textp->text=textp->lang_key + lang_key_len + 1;
+ }
+ else
+#endif
+ {
+#ifdef PNG_iTXt_SUPPORTED
+ textp->lang=NULL;
+ textp->lang_key=NULL;
+#endif
+ textp->text=textp->key + key_len + 1;
+ }
+ if(text_length)
+ png_memcpy(textp->text, text_ptr[i].text,
+ (png_size_t)(text_length));
+ *(textp->text+text_length) = '\0';
+
+#ifdef PNG_iTXt_SUPPORTED
+ if(textp->compression > 0)
+ {
+ textp->text_length = 0;
+ textp->itxt_length = text_length;
+ }
+ else
+#endif
+ {
+ textp->text_length = text_length;
+#ifdef PNG_iTXt_SUPPORTED
+ textp->itxt_length = 0;
+#endif
+ }
+ info_ptr->text[info_ptr->num_text]= *textp;
+ info_ptr->num_text++;
+ png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
+ }
+ return(0);
+}
+#endif
+
+#if defined(PNG_tIME_SUPPORTED)
+void PNGAPI
+png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
+{
+ png_debug1(1, "in %s storage function\n", "tIME");
+ if (png_ptr == NULL || info_ptr == NULL ||
+ (png_ptr->mode & PNG_WROTE_tIME))
+ return;
+
+ png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time));
+ info_ptr->valid |= PNG_INFO_tIME;
+}
+#endif
+
+#if defined(PNG_tRNS_SUPPORTED)
+void PNGAPI
+png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
+ png_bytep trans, int num_trans, png_color_16p trans_values)
+{
+ png_debug1(1, "in %s storage function\n", "tRNS");
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if (trans != NULL)
+ {
+ /*
+ * It may not actually be necessary to set png_ptr->trans here;
+ * we do it for backward compatibility with the way the png_handle_tRNS
+ * function used to do the allocation.
+ */
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_free_data(png_ptr, info_ptr, PNG_FREE_TRNS, 0);
+#endif
+ /* Changed from num_trans to 256 in version 1.2.1 */
+ png_ptr->trans = info_ptr->trans = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)256);
+ png_memcpy(info_ptr->trans, trans, (png_size_t)num_trans);
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_TRNS;
+#else
+ png_ptr->flags |= PNG_FLAG_FREE_TRNS;
+#endif
+ }
+
+ if (trans_values != NULL)
+ {
+ png_memcpy(&(info_ptr->trans_values), trans_values,
+ sizeof(png_color_16));
+ if (num_trans == 0)
+ num_trans = 1;
+ }
+ info_ptr->num_trans = (png_uint_16)num_trans;
+ info_ptr->valid |= PNG_INFO_tRNS;
+}
+#endif
+
+#if defined(PNG_sPLT_SUPPORTED)
+void PNGAPI
+png_set_sPLT(png_structp png_ptr,
+ png_infop info_ptr, png_sPLT_tp entries, int nentries)
+{
+ png_sPLT_tp np;
+ int i;
+
+ np = (png_sPLT_tp)png_malloc_warn(png_ptr,
+ (info_ptr->splt_palettes_num + nentries) * sizeof(png_sPLT_t));
+ if (np == NULL)
+ {
+ png_warning(png_ptr, "No memory for sPLT palettes.");
+ return;
+ }
+
+ png_memcpy(np, info_ptr->splt_palettes,
+ info_ptr->splt_palettes_num * sizeof(png_sPLT_t));
+ png_free(png_ptr, info_ptr->splt_palettes);
+ info_ptr->splt_palettes=NULL;
+
+ for (i = 0; i < nentries; i++)
+ {
+ png_sPLT_tp to = np + info_ptr->splt_palettes_num + i;
+ png_sPLT_tp from = entries + i;
+
+ to->name = (png_charp)png_malloc(png_ptr,
+ png_strlen(from->name) + 1);
+ png_strcpy(to->name, from->name);
+ to->entries = (png_sPLT_entryp)png_malloc(png_ptr,
+ from->nentries * sizeof(png_sPLT_entry));
+ png_memcpy(to->entries, from->entries,
+ from->nentries * sizeof(png_sPLT_entry));
+ to->nentries = from->nentries;
+ to->depth = from->depth;
+ }
+
+ info_ptr->splt_palettes = np;
+ info_ptr->splt_palettes_num += nentries;
+ info_ptr->valid |= PNG_INFO_sPLT;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_SPLT;
+#endif
+}
+#endif /* PNG_sPLT_SUPPORTED */
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_unknown_chunks(png_structp png_ptr,
+ png_infop info_ptr, png_unknown_chunkp unknowns, int num_unknowns)
+{
+ png_unknown_chunkp np;
+ int i;
+
+ if (png_ptr == NULL || info_ptr == NULL || num_unknowns == 0)
+ return;
+
+ np = (png_unknown_chunkp)png_malloc_warn(png_ptr,
+ (info_ptr->unknown_chunks_num + num_unknowns) *
+ sizeof(png_unknown_chunk));
+ if (np == NULL)
+ {
+ png_warning(png_ptr, "Out of memory while processing unknown chunk.");
+ return;
+ }
+
+ png_memcpy(np, info_ptr->unknown_chunks,
+ info_ptr->unknown_chunks_num * sizeof(png_unknown_chunk));
+ png_free(png_ptr, info_ptr->unknown_chunks);
+ info_ptr->unknown_chunks=NULL;
+
+ for (i = 0; i < num_unknowns; i++)
+ {
+ png_unknown_chunkp to = np + info_ptr->unknown_chunks_num + i;
+ png_unknown_chunkp from = unknowns + i;
+
+ png_strcpy((png_charp)to->name, (png_charp)from->name);
+ to->data = (png_bytep)png_malloc(png_ptr, from->size);
+ if (to->data == NULL)
+ png_warning(png_ptr, "Out of memory while processing unknown chunk.");
+ else
+ {
+ png_memcpy(to->data, from->data, from->size);
+ to->size = from->size;
+
+ /* note our location in the read or write sequence */
+ to->location = (png_byte)(png_ptr->mode & 0xff);
+ }
+ }
+
+ info_ptr->unknown_chunks = np;
+ info_ptr->unknown_chunks_num += num_unknowns;
+#ifdef PNG_FREE_ME_SUPPORTED
+ info_ptr->free_me |= PNG_FREE_UNKN;
+#endif
+}
+void PNGAPI
+png_set_unknown_chunk_location(png_structp png_ptr, png_infop info_ptr,
+ int chunk, int location)
+{
+ if(png_ptr != NULL && info_ptr != NULL && chunk >= 0 && chunk <
+ (int)info_ptr->unknown_chunks_num)
+ info_ptr->unknown_chunks[chunk].location = (png_byte)location;
+}
+#endif
+
+#if defined(PNG_READ_EMPTY_PLTE_SUPPORTED) || \
+ defined(PNG_WRITE_EMPTY_PLTE_SUPPORTED)
+void PNGAPI
+png_permit_empty_plte (png_structp png_ptr, int empty_plte_permitted)
+{
+ /* This function is deprecated in favor of png_permit_mng_features()
+ and will be removed from libpng-2.0.0 */
+ png_debug(1, "in png_permit_empty_plte, DEPRECATED.\n");
+ if (png_ptr == NULL)
+ return;
+ png_ptr->mng_features_permitted = (png_byte)
+ ((png_ptr->mng_features_permitted & (~(PNG_FLAG_MNG_EMPTY_PLTE))) |
+ ((empty_plte_permitted & PNG_FLAG_MNG_EMPTY_PLTE)));
+}
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+png_uint_32 PNGAPI
+png_permit_mng_features (png_structp png_ptr, png_uint_32 mng_features)
+{
+ png_debug(1, "in png_permit_mng_features\n");
+ if (png_ptr == NULL)
+ return (png_uint_32)0;
+ png_ptr->mng_features_permitted =
+ (png_byte)(mng_features & PNG_ALL_MNG_FEATURES);
+ return (png_uint_32)png_ptr->mng_features_permitted;
+}
+#endif
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_keep_unknown_chunks(png_structp png_ptr, int keep, png_bytep
+ chunk_list, int num_chunks)
+{
+ png_bytep new_list, p;
+ int i, old_num_chunks;
+ if (num_chunks == 0)
+ {
+ if(keep == HANDLE_CHUNK_ALWAYS || keep == HANDLE_CHUNK_IF_SAFE)
+ png_ptr->flags |= PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+ else
+ png_ptr->flags &= ~PNG_FLAG_KEEP_UNKNOWN_CHUNKS;
+
+ if(keep == HANDLE_CHUNK_ALWAYS)
+ png_ptr->flags |= PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+ else
+ png_ptr->flags &= ~PNG_FLAG_KEEP_UNSAFE_CHUNKS;
+ return;
+ }
+ if (chunk_list == NULL)
+ return;
+ old_num_chunks=png_ptr->num_chunk_list;
+ new_list=(png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(5*(num_chunks+old_num_chunks)));
+ if(png_ptr->chunk_list != NULL)
+ {
+ png_memcpy(new_list, png_ptr->chunk_list,
+ (png_size_t)(5*old_num_chunks));
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list=NULL;
+ }
+ png_memcpy(new_list+5*old_num_chunks, chunk_list,
+ (png_size_t)(5*num_chunks));
+ for (p=new_list+5*old_num_chunks+4, i=0; i<num_chunks; i++, p+=5)
+ *p=(png_byte)keep;
+ png_ptr->num_chunk_list=old_num_chunks+num_chunks;
+ png_ptr->chunk_list=new_list;
+#ifdef PNG_FREE_ME_SUPPORTED
+ png_ptr->free_me |= PNG_FREE_LIST;
+#endif
+}
+#endif
+
+#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+void PNGAPI
+png_set_read_user_chunk_fn(png_structp png_ptr, png_voidp user_chunk_ptr,
+ png_user_chunk_ptr read_user_chunk_fn)
+{
+ png_debug(1, "in png_set_read_user_chunk_fn\n");
+ png_ptr->read_user_chunk_fn = read_user_chunk_fn;
+ png_ptr->user_chunk_ptr = user_chunk_ptr;
+}
+#endif
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
+{
+ png_debug1(1, "in %s storage function\n", "rows");
+
+ if (png_ptr == NULL || info_ptr == NULL)
+ return;
+
+ if(info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
+ info_ptr->row_pointers = row_pointers;
+ if(row_pointers)
+ info_ptr->valid |= PNG_INFO_IDAT;
+}
+#endif
+
+void PNGAPI
+png_set_compression_buffer_size(png_structp png_ptr, png_uint_32 size)
+{
+ if(png_ptr->zbuf)
+ png_free(png_ptr, png_ptr->zbuf);
+ png_ptr->zbuf_size = (png_size_t)size;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+}
+
+void PNGAPI
+png_set_invalid(png_structp png_ptr, png_infop info_ptr, int tqmask)
+{
+ if (png_ptr && info_ptr)
+ info_ptr->valid &= ~(tqmask);
+}
+
+
+#ifndef PNG_1_0_X
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+/* this function was added to libpng 1.2.0 and should always exist by default */
+void PNGAPI
+png_set_asm_flags (png_structp png_ptr, png_uint_32 asm_flags)
+{
+ png_uint_32 settable_asm_flags;
+ png_uint_32 settable_mmx_flags;
+
+ settable_mmx_flags =
+#ifdef PNG_HAVE_ASSEMBLER_COMBINE_ROW
+ PNG_ASM_FLAG_MMX_READ_COMBINE_ROW |
+#endif
+#ifdef PNG_HAVE_ASSEMBLER_READ_INTERLACE
+ PNG_ASM_FLAG_MMX_READ_INTERLACE |
+#endif
+#ifdef PNG_HAVE_ASSEMBLER_READ_FILTER_ROW
+ PNG_ASM_FLAG_MMX_READ_FILTER_SUB |
+ PNG_ASM_FLAG_MMX_READ_FILTER_UP |
+ PNG_ASM_FLAG_MMX_READ_FILTER_AVG |
+ PNG_ASM_FLAG_MMX_READ_FILTER_PAETH |
+#endif
+ 0;
+
+ /* could be some non-MMX ones in the future, but not currently: */
+ settable_asm_flags = settable_mmx_flags;
+
+ if (!(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_COMPILED) ||
+ !(png_ptr->asm_flags & PNG_ASM_FLAG_MMX_SUPPORT_IN_CPU))
+ {
+ /* clear all MMX flags if MMX isn't supported */
+ settable_asm_flags &= ~settable_mmx_flags;
+ png_ptr->asm_flags &= ~settable_mmx_flags;
+ }
+
+ /* we're replacing the settable bits with those passed in by the user,
+ * so first zero them out of the master copy, then logical-OR in the
+ * allowed subset that was requested */
+
+ png_ptr->asm_flags &= ~settable_asm_flags; /* zero them */
+ png_ptr->asm_flags |= (asm_flags & settable_asm_flags); /* set them */
+}
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+/* this function was added to libpng 1.2.0 */
+void PNGAPI
+png_set_mmx_thresholds (png_structp png_ptr,
+ png_byte mmx_bitdepth_threshold,
+ png_uint_32 mmx_rowbytes_threshold)
+{
+ png_ptr->mmx_bitdepth_threshold = mmx_bitdepth_threshold;
+ png_ptr->mmx_rowbytes_threshold = mmx_rowbytes_threshold;
+}
+#endif /* ?PNG_ASSEMBLER_CODE_SUPPORTED */
+#endif /* ?PNG_1_0_X */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngtest.c b/tqtinterface/qt4/src/3rdparty/libpng/pngtest.c
new file mode 100644
index 0000000..66bb2a0
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngtest.c
@@ -0,0 +1,1541 @@
+
+/* pngtest.c - a simple test program to test libpng
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This program reads in a PNG image, writes it out again, and then
+ * compares the two files. If the files are identical, this shows that
+ * the basic chunk handling, filtering, and (de)compression code is working
+ * properly. It does not currently test all of the transforms, although
+ * it probably should.
+ *
+ * The program will report "FAIL" in certain legitimate cases:
+ * 1) when the compression level or filter selection method is changed.
+ * 2) when the maximum IDAT size (PNG_ZBUF_SIZE in pngconf.h) is not 8192.
+ * 3) unknown unsafe-to-copy ancillary chunks or unknown critical chunks
+ * exist in the input file.
+ * 4) others not listed here...
+ * In these cases, it is best to check with another tool such as "pngcheck"
+ * to see what the differences between the two files are.
+ *
+ * If a filename is given on the command-line, then this file is used
+ * for the input, rather than the default "pngtest.png". This allows
+ * testing a wide variety of files easily. You can also test a number
+ * of files at once by typing "pngtest -m file1.png file2.png ..."
+ */
+
+#if defined(_WIN32_WCE)
+# if _WIN32_WCE < 211
+ __error__ (f|w)printf functions are not supported on old WindowsCE.;
+# endif
+# include <windows.h>
+# include <stdlib.h>
+# define READFILE(file, data, length, check) \
+ if (ReadFile(file, data, length, &check,NULL)) check = 0
+# define WRITEFILE(file, data, length, check)) \
+ if (WriteFile(file, data, length, &check, NULL)) check = 0
+# define FCLOSE(file) CloseHandle(file)
+#else
+# include <stdio.h>
+# include <stdlib.h>
+# include <assert.h>
+# define READFILE(file, data, length, check) \
+ check=(png_size_t)fread(data,(png_size_t)1,length,file)
+# define WRITEFILE(file, data, length, check) \
+ check=(png_size_t)fwrite(data,(png_size_t)1, length, file)
+# define FCLOSE(file) fclose(file)
+#endif
+
+#if defined(PNG_NO_STDIO)
+# if defined(_WIN32_WCE)
+ typedef HANDLE png_FILE_p;
+# else
+ typedef FILE * png_FILE_p;
+# endif
+#endif
+
+/* Makes pngtest verbose so we can tqfind problems (needs to be before png.h) */
+#ifndef PNG_DEBUG
+# define PNG_DEBUG 0
+#endif
+
+#if !PNG_DEBUG
+# define SINGLE_ROWBUF_ALLOC /* makes buffer overruns easier to nail */
+#endif
+
+/* Turn on CPU timing
+#define PNGTEST_TIMING
+*/
+
+#ifdef PNG_NO_FLOATING_POINT_SUPPORTED
+#undef PNGTEST_TIMING
+#endif
+
+#ifdef PNGTEST_TIMING
+static float t_start, t_stop, t_decode, t_encode, t_misc;
+#include <time.h>
+#endif
+
+#include "png.h"
+
+/* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
+#ifndef png_jmpbuf
+# define png_jmpbuf(png_ptr) png_ptr->jmpbuf
+#endif
+
+#ifdef PNGTEST_TIMING
+static float t_start, t_stop, t_decode, t_encode, t_misc;
+#if !defined(PNG_tIME_SUPPORTED)
+#include <time.h>
+#endif
+#endif
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+static int tIME_chunk_present=0;
+static char tIME_string[30] = "no tIME chunk present in file";
+#endif
+
+static int verbose = 0;
+
+int test_one_file PNGARG((PNG_CONST char *inname, PNG_CONST char *outname));
+
+#ifdef __TURBOC__
+#include <mem.h>
+#endif
+
+/* defined so I can write to a file on gui/windowing platforms */
+/* #define STDERR stderr */
+#define STDERR stdout /* for DOS */
+
+/* example of using row callbacks to make a simple progress meter */
+static int status_pass=1;
+static int status_dots_requested=0;
+static int status_dots=1;
+
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+read_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
+{
+ if(png_ptr == NULL || row_number > PNG_MAX_UINT) return;
+ if(status_pass != pass)
+ {
+ fprintf(stdout,"\n Pass %d: ",pass);
+ status_pass = pass;
+ status_dots = 31;
+ }
+ status_dots--;
+ if(status_dots == 0)
+ {
+ fprintf(stdout, "\n ");
+ status_dots=30;
+ }
+ fprintf(stdout, "r");
+}
+
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+write_row_callback(png_structp png_ptr, png_uint_32 row_number, int pass)
+{
+ if(png_ptr == NULL || row_number > PNG_MAX_UINT || pass > 7) return;
+ fprintf(stdout, "w");
+}
+
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+/* Example of using user transform callback (we don't transform anything,
+ but merely examine the row filters. We set this to 256 rather than
+ 5 in case illegal filter values are present.) */
+static png_uint_32 filters_used[256];
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_filters(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+{
+ if(png_ptr != NULL && row_info != NULL)
+ ++filters_used[*(data-1)];
+}
+#endif
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+/* example of using user transform callback (we don't transform anything,
+ but merely count the zero samples) */
+
+static png_uint_32 zero_samples;
+
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data);
+void
+#ifdef PNG_1_0_X
+PNGAPI
+#endif
+count_zero_samples(png_structp png_ptr, png_row_infop row_info, png_bytep data)
+{
+ png_bytep dp = data;
+ if(png_ptr == NULL)return;
+
+ /* contents of row_info:
+ * png_uint_32 width width of row
+ * png_uint_32 rowbytes number of bytes in row
+ * png_byte color_type color type of pixels
+ * png_byte bit_depth bit depth of samples
+ * png_byte channels number of channels (1-4)
+ * png_byte pixel_depth bits per pixel (depth*channels)
+ */
+
+
+ /* counts the number of zero samples (or zero pixels if color_type is 3 */
+
+ if(row_info->color_type == 0 || row_info->color_type == 3)
+ {
+ int pos=0;
+ png_uint_32 n, nstop;
+ for (n=0, nstop=row_info->width; n<nstop; n++)
+ {
+ if(row_info->bit_depth == 1)
+ {
+ if(((*dp << pos++ ) & 0x80) == 0) zero_samples++;
+ if(pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
+ if(row_info->bit_depth == 2)
+ {
+ if(((*dp << (pos+=2)) & 0xc0) == 0) zero_samples++;
+ if(pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
+ if(row_info->bit_depth == 4)
+ {
+ if(((*dp << (pos+=4)) & 0xf0) == 0) zero_samples++;
+ if(pos == 8)
+ {
+ pos = 0;
+ dp++;
+ }
+ }
+ if(row_info->bit_depth == 8)
+ if(*dp++ == 0) zero_samples++;
+ if(row_info->bit_depth == 16)
+ {
+ if((*dp | *(dp+1)) == 0) zero_samples++;
+ dp+=2;
+ }
+ }
+ }
+ else /* other color types */
+ {
+ png_uint_32 n, nstop;
+ int channel;
+ int color_channels = row_info->channels;
+ if(row_info->color_type > 3)color_channels--;
+
+ for (n=0, nstop=row_info->width; n<nstop; n++)
+ {
+ for (channel = 0; channel < color_channels; channel++)
+ {
+ if(row_info->bit_depth == 8)
+ if(*dp++ == 0) zero_samples++;
+ if(row_info->bit_depth == 16)
+ {
+ if((*dp | *(dp+1)) == 0) zero_samples++;
+ dp+=2;
+ }
+ }
+ if(row_info->color_type > 3)
+ {
+ dp++;
+ if(row_info->bit_depth == 16)dp++;
+ }
+ }
+ }
+}
+#endif /* PNG_WRITE_USER_TRANSFORM_SUPPORTED */
+
+static int wrote_question = 0;
+
+#if defined(PNG_NO_STDIO)
+/* START of code to validate stdio-free compilation */
+/* These copies of the default read/write functions come from pngrio.c and */
+/* pngwio.c. They allow "don't include stdio" testing of the library. */
+/* This is the function that does the actual reading of data. If you are
+ not reading from a standard C stream, you should create a tqreplacement
+ read_data function and use it at run time with png_set_read_fn(), rather
+ than changing the library. */
+
+#ifndef USE_FAR_KEYWORD
+static void
+pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_size_t check;
+
+ /* fread() returns 0 on error, so it is OK to store this in a png_size_t
+ * instead of an int, which is what fread() actually returns.
+ */
+ READFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
+
+ if (check != length)
+ {
+ png_error(png_ptr, "Read Error!");
+ }
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+ can't handle far buffers in the medium and small models, we have to copy
+ the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void
+pngtest_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ int check;
+ png_byte *n_data;
+ png_FILE_p io_ptr;
+
+ /* Check if data really is near. If so, use usual code. */
+ n_data = (png_byte *)CVT_PTR_NOCHECK(data);
+ io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+ if ((png_bytep)n_data == data)
+ {
+ READFILE(io_ptr, n_data, length, check);
+ }
+ else
+ {
+ png_byte buf[NEAR_BUF_SIZE];
+ png_size_t read, remaining, err;
+ check = 0;
+ remaining = length;
+ do
+ {
+ read = MIN(NEAR_BUF_SIZE, remaining);
+ READFILE(io_ptr, buf, 1, err);
+ png_memcpy(data, buf, read); /* copy far buffer to near buffer */
+ if(err != read)
+ break;
+ else
+ check += err;
+ data += read;
+ remaining -= read;
+ }
+ while (remaining != 0);
+ }
+ if (check != length)
+ {
+ png_error(png_ptr, "read Error");
+ }
+}
+#endif /* USE_FAR_KEYWORD */
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+static void
+pngtest_flush(png_structp png_ptr)
+{
+#if !defined(_WIN32_WCE)
+ png_FILE_p io_ptr;
+ io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
+ if (io_ptr != NULL)
+ fflush(io_ptr);
+#endif
+}
+#endif
+
+/* This is the function that does the actual writing of data. If you are
+ not writing to a standard C stream, you should create a tqreplacement
+ write_data function and use it at run time with png_set_write_fn(), rather
+ than changing the library. */
+#ifndef USE_FAR_KEYWORD
+static void
+pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_uint_32 check;
+
+ WRITEFILE((png_FILE_p)png_ptr->io_ptr, data, length, check);
+ if (check != length)
+ {
+ png_error(png_ptr, "Write Error");
+ }
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+ can't handle far buffers in the medium and small models, we have to copy
+ the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+static void
+pngtest_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_uint_32 check;
+ png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
+ png_FILE_p io_ptr;
+
+ /* Check if data really is near. If so, use usual code. */
+ near_data = (png_byte *)CVT_PTR_NOCHECK(data);
+ io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+ if ((png_bytep)near_data == data)
+ {
+ WRITEFILE(io_ptr, near_data, length, check);
+ }
+ else
+ {
+ png_byte buf[NEAR_BUF_SIZE];
+ png_size_t written, remaining, err;
+ check = 0;
+ remaining = length;
+ do
+ {
+ written = MIN(NEAR_BUF_SIZE, remaining);
+ png_memcpy(buf, data, written); /* copy far buffer to near buffer */
+ WRITEFILE(io_ptr, buf, written, err);
+ if (err != written)
+ break;
+ else
+ check += err;
+ data += written;
+ remaining -= written;
+ }
+ while (remaining != 0);
+ }
+ if (check != length)
+ {
+ png_error(png_ptr, "Write Error");
+ }
+}
+
+#endif /* USE_FAR_KEYWORD */
+
+/* This function is called when there is a warning, but the library thinks
+ * it can continue anyway. Replacement functions don't have to do anything
+ * here if you don't want to. In the default configuration, png_ptr is
+ * not used, but it is passed in case it may be useful.
+ */
+static void
+pngtest_warning(png_structp png_ptr, png_const_charp message)
+{
+ PNG_CONST char *name = "UNKNOWN (ERROR!)";
+ if (png_ptr != NULL && png_ptr->error_ptr != NULL)
+ name = png_ptr->error_ptr;
+ fprintf(STDERR, "%s: libpng warning: %s\n", name, message);
+}
+
+/* This is the default error handling function. Note that tqreplacements for
+ * this function MUST NOT RETURN, or the program will likely crash. This
+ * function is used by default, or if the program supplies NULL for the
+ * error function pointer in png_set_error_fn().
+ */
+static void
+pngtest_error(png_structp png_ptr, png_const_charp message)
+{
+ pngtest_warning(png_ptr, message);
+ /* We can return because png_error calls the default handler, which is
+ * actually OK in this case. */
+}
+#endif /* PNG_NO_STDIO */
+/* END of code to validate stdio-free compilation */
+
+/* START of code to validate memory allocation and deallocation */
+#ifdef PNG_USER_MEM_SUPPORTED
+
+/* Allocate memory. For reasonable files, size should never exceed
+ 64K. However, zlib may allocate more then 64K if you don't tell
+ it not to. See zconf.h and png.h for more information. zlib does
+ need to allocate exactly 64K, so whatever you call here must
+ have the ability to do that.
+
+ This piece of code can be compiled to validate max 64K allocations
+ by setting MAXSEG_64K in zlib zconf.h *or* PNG_MAX_MALLOC_64K. */
+typedef struct memory_information
+{
+ png_uint_32 size;
+ png_voidp pointer;
+ struct memory_information FAR *next;
+} memory_information;
+typedef memory_information FAR *memory_infop;
+
+static memory_infop pinformation = NULL;
+static int current_allocation = 0;
+static int maximum_allocation = 0;
+static int total_allocation = 0;
+static int num_allocations = 0;
+
+png_voidp png_debug_malloc PNGARG((png_structp png_ptr, png_uint_32 size));
+void png_debug_free PNGARG((png_structp png_ptr, png_voidp ptr));
+
+png_voidp
+png_debug_malloc(png_structp png_ptr, png_uint_32 size)
+{
+
+ /* png_malloc has already tested for NULL; png_create_struct calls
+ png_debug_malloc directly, with png_ptr == NULL which is OK */
+
+ if (size == 0)
+ return (NULL);
+
+ /* This calls the library allocator twice, once to get the requested
+ buffer and once to get a new free list entry. */
+ {
+ memory_infop pinfo = (memory_infop)png_malloc_default(png_ptr,
+ (png_uint_32)sizeof *pinfo);
+ pinfo->size = size;
+ current_allocation += size;
+ total_allocation += size;
+ num_allocations ++;
+ if (current_allocation > maximum_allocation)
+ maximum_allocation = current_allocation;
+ pinfo->pointer = (png_voidp)png_malloc_default(png_ptr, size);
+ pinfo->next = pinformation;
+ pinformation = pinfo;
+ /* Make sure the caller isn't assuming zeroed memory. */
+ png_memset(pinfo->pointer, 0xdd, pinfo->size);
+#if PNG_DEBUG
+ if(verbose)
+ printf("png_malloc %lu bytes at %x\n",size,pinfo->pointer);
+#endif
+ assert(pinfo->size != 12345678);
+ return (png_voidp)(pinfo->pointer);
+ }
+}
+
+/* Free a pointer. It is removed from the list at the same time. */
+void
+png_debug_free(png_structp png_ptr, png_voidp ptr)
+{
+ if (png_ptr == NULL)
+ fprintf(STDERR, "NULL pointer to png_debug_free.\n");
+ if (ptr == 0)
+ {
+#if 0 /* This happens all the time. */
+ fprintf(STDERR, "WARNING: freeing NULL pointer\n");
+#endif
+ return;
+ }
+
+ /* Unlink the element from the list. */
+ {
+ memory_infop FAR *ppinfo = &pinformation;
+ for (;;)
+ {
+ memory_infop pinfo = *ppinfo;
+ if (pinfo->pointer == ptr)
+ {
+ *ppinfo = pinfo->next;
+ current_allocation -= pinfo->size;
+ if (current_allocation < 0)
+ fprintf(STDERR, "Duplicate free of memory\n");
+ /* We must free the list element too, but first kill
+ the memory that is to be freed. */
+ png_memset(ptr, 0x55, pinfo->size);
+ png_free_default(png_ptr, pinfo);
+ pinfo=NULL;
+ break;
+ }
+ if (pinfo->next == NULL)
+ {
+ fprintf(STDERR, "Pointer %x not found\n", (unsigned int)ptr);
+ break;
+ }
+ ppinfo = &pinfo->next;
+ }
+ }
+
+ /* Finally free the data. */
+#if PNG_DEBUG
+ if(verbose)
+ printf("Freeing %x\n",ptr);
+#endif
+ png_free_default(png_ptr, ptr);
+ ptr=NULL;
+}
+#endif /* PNG_USER_MEM_SUPPORTED */
+/* END of code to test memory allocation/deallocation */
+
+/* Test one file */
+int
+test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
+{
+ static png_FILE_p fpin;
+ static png_FILE_p fpout; /* "static" prevents setjmp corruption */
+ png_structp read_ptr;
+ png_infop read_info_ptr, end_info_ptr;
+#ifdef PNG_WRITE_SUPPORTED
+ png_structp write_ptr;
+ png_infop write_info_ptr;
+ png_infop write_end_info_ptr;
+#else
+ png_structp write_ptr = NULL;
+ png_infop write_info_ptr = NULL;
+ png_infop write_end_info_ptr = NULL;
+#endif
+ png_bytep row_buf;
+ png_uint_32 y;
+ png_uint_32 width, height;
+ int num_pass, pass;
+ int bit_depth, color_type;
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ jmp_buf jmpbuf;
+#endif
+#endif
+
+#if defined(_WIN32_WCE)
+ TCHAR path[MAX_PATH];
+#endif
+ char inbuf[256], outbuf[256];
+
+ row_buf = NULL;
+
+#if defined(_WIN32_WCE)
+ MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
+ if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+ if ((fpin = fopen(inname, "rb")) == NULL)
+#endif
+ {
+ fprintf(STDERR, "Could not tqfind input file %s\n", inname);
+ return (1);
+ }
+
+#if defined(_WIN32_WCE)
+ MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
+ if ((fpout = CreateFile(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+ if ((fpout = fopen(outname, "wb")) == NULL)
+#endif
+ {
+ fprintf(STDERR, "Could not open output file %s\n", outname);
+ FCLOSE(fpin);
+ return (1);
+ }
+
+ png_debug(0, "Allocating read and write structures\n");
+#ifdef PNG_USER_MEM_SUPPORTED
+ read_ptr = png_create_read_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+ png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
+ (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
+#else
+ read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+ png_error_ptr_NULL, png_error_ptr_NULL);
+#endif
+#if defined(PNG_NO_STDIO)
+ png_set_error_fn(read_ptr, (png_voidp)inname, pngtest_error,
+ pngtest_warning);
+#endif
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNG_USER_MEM_SUPPORTED
+ write_ptr = png_create_write_struct_2(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+ png_error_ptr_NULL, png_error_ptr_NULL, png_voidp_NULL,
+ (png_malloc_ptr)png_debug_malloc, (png_free_ptr)png_debug_free);
+#else
+ write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, png_voidp_NULL,
+ png_error_ptr_NULL, png_error_ptr_NULL);
+#endif
+#if defined(PNG_NO_STDIO)
+ png_set_error_fn(write_ptr, (png_voidp)inname, pngtest_error,
+ pngtest_warning);
+#endif
+#endif
+ png_debug(0, "Allocating read_info, write_info and end_info structures\n");
+ read_info_ptr = png_create_info_struct(read_ptr);
+ end_info_ptr = png_create_info_struct(read_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ write_info_ptr = png_create_info_struct(write_ptr);
+ write_end_info_ptr = png_create_info_struct(write_ptr);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ png_debug(0, "Setting jmpbuf for read struct\n");
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+#else
+ if (setjmp(png_jmpbuf(read_ptr)))
+#endif
+ {
+ fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
+ if (row_buf)
+ png_free(read_ptr, row_buf);
+ png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+ png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (1);
+ }
+#ifdef USE_FAR_KEYWORD
+ png_memcpy(png_jmpbuf(read_ptr),jmpbuf,sizeof(jmp_buf));
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+ png_debug(0, "Setting jmpbuf for write struct\n");
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+#else
+ if (setjmp(png_jmpbuf(write_ptr)))
+#endif
+ {
+ fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
+ png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+ png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (1);
+ }
+#ifdef USE_FAR_KEYWORD
+ png_memcpy(png_jmpbuf(write_ptr),jmpbuf,sizeof(jmp_buf));
+#endif
+#endif
+#endif
+
+ png_debug(0, "Initializing input and output streams\n");
+#if !defined(PNG_NO_STDIO)
+ png_init_io(read_ptr, fpin);
+# ifdef PNG_WRITE_SUPPORTED
+ png_init_io(write_ptr, fpout);
+# endif
+#else
+ png_set_read_fn(read_ptr, (png_voidp)fpin, pngtest_read_data);
+# ifdef PNG_WRITE_SUPPORTED
+ png_set_write_fn(write_ptr, (png_voidp)fpout, pngtest_write_data,
+# if defined(PNG_WRITE_FLUSH_SUPPORTED)
+ pngtest_flush);
+# else
+ NULL);
+# endif
+# endif
+#endif
+ if(status_dots_requested == 1)
+ {
+#ifdef PNG_WRITE_SUPPORTED
+ png_set_write_status_fn(write_ptr, write_row_callback);
+#endif
+ png_set_read_status_fn(read_ptr, read_row_callback);
+ }
+ else
+ {
+#ifdef PNG_WRITE_SUPPORTED
+ png_set_write_status_fn(write_ptr, png_write_status_ptr_NULL);
+#endif
+ png_set_read_status_fn(read_ptr, png_read_status_ptr_NULL);
+ }
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ {
+ int i;
+ for(i=0; i<256; i++)
+ filters_used[i]=0;
+ png_set_read_user_transform_fn(read_ptr, count_filters);
+ }
+#endif
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ zero_samples=0;
+ png_set_write_user_transform_fn(write_ptr, count_zero_samples);
+#endif
+
+#define HANDLE_CHUNK_IF_SAFE 2
+#define HANDLE_CHUNK_ALWAYS 3
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ png_set_keep_unknown_chunks(read_ptr, HANDLE_CHUNK_ALWAYS,
+ png_bytep_NULL, 0);
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ png_set_keep_unknown_chunks(write_ptr, HANDLE_CHUNK_IF_SAFE,
+ png_bytep_NULL, 0);
+#endif
+
+ png_debug(0, "Reading info struct\n");
+ png_read_info(read_ptr, read_info_ptr);
+
+ png_debug(0, "Transferring info struct\n");
+ {
+ int interlace_type, compression_type, filter_type;
+
+ if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
+ &color_type, &interlace_type, &compression_type, &filter_type))
+ {
+ png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ color_type, interlace_type, compression_type, filter_type);
+#else
+ color_type, PNG_INTERLACE_NONE, compression_type, filter_type);
+#endif
+ }
+ }
+#if defined(PNG_FIXED_POINT_SUPPORTED)
+#if defined(PNG_cHRM_SUPPORTED)
+ {
+ png_fixed_point white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
+ blue_y;
+ if (png_get_cHRM_fixed(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
+ &red_y, &green_x, &green_y, &blue_x, &blue_y))
+ {
+ png_set_cHRM_fixed(write_ptr, write_info_ptr, white_x, white_y, red_x,
+ red_y, green_x, green_y, blue_x, blue_y);
+ }
+ }
+#endif
+#if defined(PNG_gAMA_SUPPORTED)
+ {
+ png_fixed_point gamma;
+
+ if (png_get_gAMA_fixed(read_ptr, read_info_ptr, &gamma))
+ {
+ png_set_gAMA_fixed(write_ptr, write_info_ptr, gamma);
+ }
+ }
+#endif
+#else /* Use floating point versions */
+#if defined(PNG_FLOATING_POINT_SUPPORTED)
+#if defined(PNG_cHRM_SUPPORTED)
+ {
+ double white_x, white_y, red_x, red_y, green_x, green_y, blue_x,
+ blue_y;
+ if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
+ &red_y, &green_x, &green_y, &blue_x, &blue_y))
+ {
+ png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
+ red_y, green_x, green_y, blue_x, blue_y);
+ }
+ }
+#endif
+#if defined(PNG_gAMA_SUPPORTED)
+ {
+ double gamma;
+
+ if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
+ {
+ png_set_gAMA(write_ptr, write_info_ptr, gamma);
+ }
+ }
+#endif
+#endif /* floating point */
+#endif /* fixed point */
+#if defined(PNG_iCCP_SUPPORTED)
+ {
+ png_charp name;
+ png_charp profile;
+ png_uint_32 proflen;
+ int compression_type;
+
+ if (png_get_iCCP(read_ptr, read_info_ptr, &name, &compression_type,
+ &profile, &proflen))
+ {
+ png_set_iCCP(write_ptr, write_info_ptr, name, compression_type,
+ profile, proflen);
+ }
+ }
+#endif
+#if defined(PNG_sRGB_SUPPORTED)
+ {
+ int intent;
+
+ if (png_get_sRGB(read_ptr, read_info_ptr, &intent))
+ {
+ png_set_sRGB(write_ptr, write_info_ptr, intent);
+ }
+ }
+#endif
+ {
+ png_colorp palette;
+ int num_palette;
+
+ if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
+ {
+ png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
+ }
+ }
+#if defined(PNG_bKGD_SUPPORTED)
+ {
+ png_color_16p background;
+
+ if (png_get_bKGD(read_ptr, read_info_ptr, &background))
+ {
+ png_set_bKGD(write_ptr, write_info_ptr, background);
+ }
+ }
+#endif
+#if defined(PNG_hIST_SUPPORTED)
+ {
+ png_uint_16p hist;
+
+ if (png_get_hIST(read_ptr, read_info_ptr, &hist))
+ {
+ png_set_hIST(write_ptr, write_info_ptr, hist);
+ }
+ }
+#endif
+#if defined(PNG_oFFs_SUPPORTED)
+ {
+ png_int_32 offset_x, offset_y;
+ int unit_type;
+
+ if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
+ {
+ png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
+ }
+ }
+#endif
+#if defined(PNG_pCAL_SUPPORTED)
+ {
+ png_charp purpose, units;
+ png_charpp params;
+ png_int_32 X0, X1;
+ int type, nparams;
+
+ if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
+ &nparams, &units, &params))
+ {
+ png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
+ nparams, units, params);
+ }
+ }
+#endif
+#if defined(PNG_pHYs_SUPPORTED)
+ {
+ png_uint_32 res_x, res_y;
+ int unit_type;
+
+ if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
+ {
+ png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
+ }
+ }
+#endif
+#if defined(PNG_sBIT_SUPPORTED)
+ {
+ png_color_8p sig_bit;
+
+ if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
+ {
+ png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
+ }
+ }
+#endif
+#if defined(PNG_sCAL_SUPPORTED)
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ {
+ int unit;
+ double scal_width, scal_height;
+
+ if (png_get_sCAL(read_ptr, read_info_ptr, &unit, &scal_width,
+ &scal_height))
+ {
+ png_set_sCAL(write_ptr, write_info_ptr, unit, scal_width, scal_height);
+ }
+ }
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ {
+ int unit;
+ png_charp scal_width, scal_height;
+
+ if (png_get_sCAL_s(read_ptr, read_info_ptr, &unit, &scal_width,
+ &scal_height))
+ {
+ png_set_sCAL_s(write_ptr, write_info_ptr, unit, scal_width, scal_height);
+ }
+ }
+#endif
+#endif
+#endif
+#if defined(PNG_TEXT_SUPPORTED)
+ {
+ png_textp text_ptr;
+ int num_text;
+
+ if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
+ {
+ png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text);
+ png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
+ }
+ }
+#endif
+#if defined(PNG_tIME_SUPPORTED)
+ {
+ png_timep mod_time;
+
+ if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
+ {
+ png_set_tIME(write_ptr, write_info_ptr, mod_time);
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ /* we have to use png_strcpy instead of "=" because the string
+ pointed to by png_convert_to_rfc1123() gets free'ed before
+ we use it */
+ png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time));
+ tIME_chunk_present++;
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+ }
+ }
+#endif
+#if defined(PNG_tRNS_SUPPORTED)
+ {
+ png_bytep trans;
+ int num_trans;
+ png_color_16p trans_values;
+
+ if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
+ &trans_values))
+ {
+ png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
+ trans_values);
+ }
+ }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ {
+ png_unknown_chunkp unknowns;
+ int num_unknowns = (int)png_get_unknown_chunks(read_ptr, read_info_ptr,
+ &unknowns);
+ if (num_unknowns)
+ {
+ png_size_t i;
+ png_set_unknown_chunks(write_ptr, write_info_ptr, unknowns,
+ num_unknowns);
+ /* copy the locations from the read_info_ptr. The automatically
+ generated locations in write_info_ptr are wrong because we
+ haven't written anything yet */
+ for (i = 0; i < (png_size_t)num_unknowns; i++)
+ png_set_unknown_chunk_location(write_ptr, write_info_ptr, i,
+ unknowns[i].location);
+ }
+ }
+#endif
+
+#ifdef PNG_WRITE_SUPPORTED
+ png_debug(0, "\nWriting info struct\n");
+
+/* If we wanted, we could write info in two steps:
+ png_write_info_before_PLTE(write_ptr, write_info_ptr);
+ */
+ png_write_info(write_ptr, write_info_ptr);
+#endif
+
+#ifdef SINGLE_ROWBUF_ALLOC
+ png_debug(0, "\nAllocating row buffer...");
+ row_buf = (png_bytep)png_malloc(read_ptr,
+ png_get_rowbytes(read_ptr, read_info_ptr));
+ png_debug1(0, "0x%08lx\n\n", (unsigned long)row_buf);
+#endif /* SINGLE_ROWBUF_ALLOC */
+ png_debug(0, "Writing row data\n");
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ num_pass = png_set_interlace_handling(read_ptr);
+# ifdef PNG_WRITE_SUPPORTED
+ png_set_interlace_handling(write_ptr);
+# endif
+#else
+ num_pass=1;
+#endif
+
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_misc += (t_stop - t_start);
+ t_start = t_stop;
+#endif
+ for (pass = 0; pass < num_pass; pass++)
+ {
+ png_debug1(0, "Writing row data for pass %d\n",pass);
+ for (y = 0; y < height; y++)
+ {
+#ifndef SINGLE_ROWBUF_ALLOC
+ png_debug2(0, "\nAllocating row buffer (pass %d, y = %ld)...", pass,y);
+ row_buf = (png_bytep)png_malloc(read_ptr,
+ png_get_rowbytes(read_ptr, read_info_ptr));
+ png_debug2(0, "0x%08lx (%ld bytes)\n", (unsigned long)row_buf,
+ png_get_rowbytes(read_ptr, read_info_ptr));
+#endif /* !SINGLE_ROWBUF_ALLOC */
+ png_read_rows(read_ptr, (png_bytepp)&row_buf, png_bytepp_NULL, 1);
+
+#ifdef PNG_WRITE_SUPPORTED
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_decode += (t_stop - t_start);
+ t_start = t_stop;
+#endif
+ png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_encode += (t_stop - t_start);
+ t_start = t_stop;
+#endif
+#endif /* PNG_WRITE_SUPPORTED */
+
+#ifndef SINGLE_ROWBUF_ALLOC
+ png_debug2(0, "Freeing row buffer (pass %d, y = %ld)\n\n", pass, y);
+ png_free(read_ptr, row_buf);
+#endif /* !SINGLE_ROWBUF_ALLOC */
+ }
+ }
+
+#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+ png_free_data(read_ptr, read_info_ptr, PNG_FREE_UNKN, -1);
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ png_free_data(write_ptr, write_info_ptr, PNG_FREE_UNKN, -1);
+#endif
+
+ png_debug(0, "Reading and writing end_info data\n");
+
+ png_read_end(read_ptr, end_info_ptr);
+#if defined(PNG_TEXT_SUPPORTED)
+ {
+ png_textp text_ptr;
+ int num_text;
+
+ if (png_get_text(read_ptr, end_info_ptr, &text_ptr, &num_text) > 0)
+ {
+ png_debug1(0, "Handling %d iTXt/tEXt/zTXt chunks\n", num_text);
+ png_set_text(write_ptr, write_end_info_ptr, text_ptr, num_text);
+ }
+ }
+#endif
+#if defined(PNG_tIME_SUPPORTED)
+ {
+ png_timep mod_time;
+
+ if (png_get_tIME(read_ptr, end_info_ptr, &mod_time))
+ {
+ png_set_tIME(write_ptr, write_end_info_ptr, mod_time);
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ /* we have to use png_strcpy instead of "=" because the string
+ pointed to by png_convert_to_rfc1123() gets free'ed before
+ we use it */
+ png_strcpy(tIME_string,png_convert_to_rfc1123(read_ptr, mod_time));
+ tIME_chunk_present++;
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+ }
+ }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ {
+ png_unknown_chunkp unknowns;
+ int num_unknowns;
+ num_unknowns = (int)png_get_unknown_chunks(read_ptr, end_info_ptr,
+ &unknowns);
+ if (num_unknowns)
+ {
+ png_size_t i;
+ png_set_unknown_chunks(write_ptr, write_end_info_ptr, unknowns,
+ num_unknowns);
+ /* copy the locations from the read_info_ptr. The automatically
+ generated locations in write_end_info_ptr are wrong because we
+ haven't written the end_info yet */
+ for (i = 0; i < (png_size_t)num_unknowns; i++)
+ png_set_unknown_chunk_location(write_ptr, write_end_info_ptr, i,
+ unknowns[i].location);
+ }
+ }
+#endif
+#ifdef PNG_WRITE_SUPPORTED
+ png_write_end(write_ptr, write_end_info_ptr);
+#endif
+
+#ifdef PNG_EASY_ACCESS_SUPPORTED
+ if(verbose)
+ {
+ png_uint_32 iwidth, iheight;
+ iwidth = png_get_image_width(write_ptr, write_info_ptr);
+ iheight = png_get_image_height(write_ptr, write_info_ptr);
+ fprintf(STDERR, "Image width = %lu, height = %lu\n",
+ iwidth, iheight);
+ }
+#endif
+
+ png_debug(0, "Destroying data structs\n");
+#ifdef SINGLE_ROWBUF_ALLOC
+ png_debug(1, "destroying row_buf for read_ptr\n");
+ png_free(read_ptr, row_buf);
+ row_buf=NULL;
+#endif /* SINGLE_ROWBUF_ALLOC */
+ png_debug(1, "destroying read_ptr, read_info_ptr, end_info_ptr\n");
+ png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
+#ifdef PNG_WRITE_SUPPORTED
+ png_debug(1, "destroying write_end_info_ptr\n");
+ png_destroy_info_struct(write_ptr, &write_end_info_ptr);
+ png_debug(1, "destroying write_ptr, write_info_ptr\n");
+ png_destroy_write_struct(&write_ptr, &write_info_ptr);
+#endif
+ png_debug(0, "Destruction complete.\n");
+
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+
+ png_debug(0, "Opening files for comparison\n");
+#if defined(_WIN32_WCE)
+ MultiByteToWideChar(CP_ACP, 0, inname, -1, path, MAX_PATH);
+ if ((fpin = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+ if ((fpin = fopen(inname, "rb")) == NULL)
+#endif
+ {
+ fprintf(STDERR, "Could not tqfind file %s\n", inname);
+ return (1);
+ }
+
+#if defined(_WIN32_WCE)
+ MultiByteToWideChar(CP_ACP, 0, outname, -1, path, MAX_PATH);
+ if ((fpout = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
+#else
+ if ((fpout = fopen(outname, "rb")) == NULL)
+#endif
+ {
+ fprintf(STDERR, "Could not tqfind file %s\n", outname);
+ FCLOSE(fpin);
+ return (1);
+ }
+
+ for(;;)
+ {
+ png_size_t num_in, num_out;
+
+ READFILE(fpin, inbuf, 1, num_in);
+ READFILE(fpout, outbuf, 1, num_out);
+
+ if (num_in != num_out)
+ {
+ fprintf(STDERR, "\nFiles %s and %s are of a different size\n",
+ inname, outname);
+ if(wrote_question == 0)
+ {
+ fprintf(STDERR,
+ " Was %s written with the same maximum IDAT chunk size (%d bytes),",
+ inname,PNG_ZBUF_SIZE);
+ fprintf(STDERR,
+ "\n filtering heuristic (libpng default), compression");
+ fprintf(STDERR,
+ " level (zlib default),\n and zlib version (%s)?\n\n",
+ ZLIB_VERSION);
+ wrote_question=1;
+ }
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (0);
+ }
+
+ if (!num_in)
+ break;
+
+ if (png_memcmp(inbuf, outbuf, num_in))
+ {
+ fprintf(STDERR, "\nFiles %s and %s are different\n", inname, outname);
+ if(wrote_question == 0)
+ {
+ fprintf(STDERR,
+ " Was %s written with the same maximum IDAT chunk size (%d bytes),",
+ inname,PNG_ZBUF_SIZE);
+ fprintf(STDERR,
+ "\n filtering heuristic (libpng default), compression");
+ fprintf(STDERR,
+ " level (zlib default),\n and zlib version (%s)?\n\n",
+ ZLIB_VERSION);
+ wrote_question=1;
+ }
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+ return (0);
+ }
+ }
+
+ FCLOSE(fpin);
+ FCLOSE(fpout);
+
+ return (0);
+}
+
+/* input and output filenames */
+#ifdef RISCOS
+static PNG_CONST char *inname = "pngtest/png";
+static PNG_CONST char *outname = "pngout/png";
+#else
+static PNG_CONST char *inname = "pngtest.png";
+static PNG_CONST char *outname = "pngout.png";
+#endif
+
+int
+main(int argc, char *argv[])
+{
+ int multiple = 0;
+ int ierror = 0;
+
+ fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
+ fprintf(STDERR, " with zlib version %s\n", ZLIB_VERSION);
+ fprintf(STDERR,"%s",png_get_copyright(NULL));
+ /* Show the version of libpng used in building the library */
+ fprintf(STDERR," library (%lu):%s", png_access_version_number(),
+ png_get_header_version(NULL));
+ /* Show the version of libpng used in building the application */
+ fprintf(STDERR," pngtest (%lu):%s", (unsigned long)PNG_LIBPNG_VER,
+ PNG_HEADER_VERSION_STRING);
+ fprintf(STDERR," sizeof(png_struct)=%ld, sizeof(png_info)=%ld\n",
+ (long)sizeof(png_struct), (long)sizeof(png_info));
+
+ /* Do some consistency checking on the memory allocation settings, I'm
+ not sure this matters, but it is nice to know, the first of these
+ tests should be impossible because of the way the macros are set
+ in pngconf.h */
+#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
+ fprintf(STDERR, " NOTE: Zlib compiled for max 64k, libpng not\n");
+#endif
+ /* I think the following can happen. */
+#if !defined(MAXSEG_64K) && defined(PNG_MAX_MALLOC_64K)
+ fprintf(STDERR, " NOTE: libpng compiled for max 64k, zlib not\n");
+#endif
+
+ if (strcmp(png_libpng_ver, PNG_LIBPNG_VER_STRING))
+ {
+ fprintf(STDERR,
+ "Warning: versions are different between png.h and png.c\n");
+ fprintf(STDERR, " png.h version: %s\n", PNG_LIBPNG_VER_STRING);
+ fprintf(STDERR, " png.c version: %s\n\n", png_libpng_ver);
+ ++ierror;
+ }
+
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "-m") == 0)
+ {
+ multiple = 1;
+ status_dots_requested = 0;
+ }
+ else if (strcmp(argv[1], "-mv") == 0 ||
+ strcmp(argv[1], "-vm") == 0 )
+ {
+ multiple = 1;
+ verbose = 1;
+ status_dots_requested = 1;
+ }
+ else if (strcmp(argv[1], "-v") == 0)
+ {
+ verbose = 1;
+ status_dots_requested = 1;
+ inname = argv[2];
+ }
+ else
+ {
+ inname = argv[1];
+ status_dots_requested = 0;
+ }
+ }
+
+ if (!multiple && argc == 3+verbose)
+ outname = argv[2+verbose];
+
+ if ((!multiple && argc > 3+verbose) || (multiple && argc < 2))
+ {
+ fprintf(STDERR,
+ "usage: %s [infile.png] [outfile.png]\n\t%s -m {infile.png}\n",
+ argv[0], argv[0]);
+ fprintf(STDERR,
+ " reads/writes one PNG file (without -m) or multiple files (-m)\n");
+ fprintf(STDERR,
+ " with -m %s is used as a temporary file\n", outname);
+ exit(1);
+ }
+
+ if (multiple)
+ {
+ int i;
+#ifdef PNG_USER_MEM_SUPPORTED
+ int allocation_now = current_allocation;
+#endif
+ for (i=2; i<argc; ++i)
+ {
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ int k;
+#endif
+ int kerror;
+ fprintf(STDERR, "Testing %s:",argv[i]);
+ kerror = test_one_file(argv[i], outname);
+ if (kerror == 0)
+ {
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples);
+#else
+ fprintf(STDERR, " PASS\n");
+#endif
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ for (k=0; k<256; k++)
+ if(filters_used[k])
+ fprintf(STDERR, " Filter %d was used %lu times\n",
+ k,filters_used[k]);
+#endif
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ if(tIME_chunk_present != 0)
+ fprintf(STDERR, " tIME = %s\n",tIME_string);
+ tIME_chunk_present = 0;
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+ }
+ else
+ {
+ fprintf(STDERR, " FAIL\n");
+ ierror += kerror;
+ }
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (allocation_now != current_allocation)
+ fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+ current_allocation-allocation_now);
+ if (current_allocation != 0)
+ {
+ memory_infop pinfo = pinformation;
+
+ fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+ current_allocation);
+ while (pinfo != NULL)
+ {
+ fprintf(STDERR, " %lu bytes at %x\n", pinfo->size,
+ (unsigned int) pinfo->pointer);
+ pinfo = pinfo->next;
+ }
+ }
+#endif
+ }
+#ifdef PNG_USER_MEM_SUPPORTED
+ fprintf(STDERR, " Current memory allocation: %10d bytes\n",
+ current_allocation);
+ fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
+ maximum_allocation);
+ fprintf(STDERR, " Total memory allocation: %10d bytes\n",
+ total_allocation);
+ fprintf(STDERR, " Number of allocations: %10d\n",
+ num_allocations);
+#endif
+ }
+ else
+ {
+ int i;
+ for (i=0; i<3; ++i)
+ {
+ int kerror;
+#ifdef PNG_USER_MEM_SUPPORTED
+ int allocation_now = current_allocation;
+#endif
+ if (i == 1) status_dots_requested = 1;
+ else if(verbose == 0)status_dots_requested = 0;
+ if (i == 0 || verbose == 1 || ierror != 0)
+ fprintf(STDERR, "Testing %s:",inname);
+ kerror = test_one_file(inname, outname);
+ if(kerror == 0)
+ {
+ if(verbose == 1 || i == 2)
+ {
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ int k;
+#endif
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ fprintf(STDERR, "\n PASS (%lu zero samples)\n",zero_samples);
+#else
+ fprintf(STDERR, " PASS\n");
+#endif
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED)
+ for (k=0; k<256; k++)
+ if(filters_used[k])
+ fprintf(STDERR, " Filter %d was used %lu times\n",
+ k,filters_used[k]);
+#endif
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ if(tIME_chunk_present != 0)
+ fprintf(STDERR, " tIME = %s\n",tIME_string);
+#endif /* PNG_TIME_RFC1123_SUPPORTED */
+ }
+ }
+ else
+ {
+ if(verbose == 0 && i != 2)
+ fprintf(STDERR, "Testing %s:",inname);
+ fprintf(STDERR, " FAIL\n");
+ ierror += kerror;
+ }
+#ifdef PNG_USER_MEM_SUPPORTED
+ if (allocation_now != current_allocation)
+ fprintf(STDERR, "MEMORY ERROR: %d bytes lost\n",
+ current_allocation-allocation_now);
+ if (current_allocation != 0)
+ {
+ memory_infop pinfo = pinformation;
+
+ fprintf(STDERR, "MEMORY ERROR: %d bytes still allocated\n",
+ current_allocation);
+ while (pinfo != NULL)
+ {
+ fprintf(STDERR," %lu bytes at %x\n",
+ pinfo->size, (unsigned int)pinfo->pointer);
+ pinfo = pinfo->next;
+ }
+ }
+#endif
+ }
+#ifdef PNG_USER_MEM_SUPPORTED
+ fprintf(STDERR, " Current memory allocation: %10d bytes\n",
+ current_allocation);
+ fprintf(STDERR, " Maximum memory allocation: %10d bytes\n",
+ maximum_allocation);
+ fprintf(STDERR, " Total memory allocation: %10d bytes\n",
+ total_allocation);
+ fprintf(STDERR, " Number of allocations: %10d\n",
+ num_allocations);
+#endif
+ }
+
+#ifdef PNGTEST_TIMING
+ t_stop = (float)clock();
+ t_misc += (t_stop - t_start);
+ t_start = t_stop;
+ fprintf(STDERR," CPU time used = %.3f seconds",
+ (t_misc+t_decode+t_encode)/(float)CLOCKS_PER_SEC);
+ fprintf(STDERR," (decoding %.3f,\n",
+ t_decode/(float)CLOCKS_PER_SEC);
+ fprintf(STDERR," encoding %.3f ,",
+ t_encode/(float)CLOCKS_PER_SEC);
+ fprintf(STDERR," other %.3f seconds)\n\n",
+ t_misc/(float)CLOCKS_PER_SEC);
+#endif
+
+ if (ierror == 0)
+ fprintf(STDERR, "libpng passes test\n");
+ else
+ fprintf(STDERR, "libpng FAILS test\n");
+ return (int)(ierror != 0);
+}
+
+/* Generate a compiler error if there is an old png.h in the search path. */
+typedef version_1_2_5 your_png_h_is_not_version_1_2_5;
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngtest.png b/tqtinterface/qt4/src/3rdparty/libpng/pngtest.png
new file mode 100644
index 0000000..deed108
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngtest.png
Binary files differ
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngtrans.c b/tqtinterface/qt4/src/3rdparty/libpng/pngtrans.c
new file mode 100644
index 0000000..f08fb4e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngtrans.c
@@ -0,0 +1,640 @@
+
+/* pngtrans.c - transforms the data in a row (used by both readers and writers)
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* turn on BGR-to-RGB mapping */
+void PNGAPI
+png_set_bgr(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_bgr\n");
+ png_ptr->transformations |= PNG_BGR;
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* turn on 16 bit byte swapping */
+void PNGAPI
+png_set_swap(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_swap\n");
+ if (png_ptr->bit_depth == 16)
+ png_ptr->transformations |= PNG_SWAP_BYTES;
+}
+#endif
+
+#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED)
+/* turn on pixel packing */
+void PNGAPI
+png_set_packing(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_packing\n");
+ if (png_ptr->bit_depth < 8)
+ {
+ png_ptr->transformations |= PNG_PACK;
+ png_ptr->usr_bit_depth = 8;
+ }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+/* turn on packed pixel swapping */
+void PNGAPI
+png_set_packswap(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_packswap\n");
+ if (png_ptr->bit_depth < 8)
+ png_ptr->transformations |= PNG_PACKSWAP;
+}
+#endif
+
+#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
+void PNGAPI
+png_set_shift(png_structp png_ptr, png_color_8p true_bits)
+{
+ png_debug(1, "in png_set_shift\n");
+ png_ptr->transformations |= PNG_SHIFT;
+ png_ptr->shift = *true_bits;
+}
+#endif
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
+ defined(PNG_WRITE_INTERLACING_SUPPORTED)
+int PNGAPI
+png_set_interlace_handling(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_interlace handling\n");
+ if (png_ptr->interlaced)
+ {
+ png_ptr->transformations |= PNG_INTERLACE;
+ return (7);
+ }
+
+ return (1);
+}
+#endif
+
+#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
+/* Add a filler byte on read, or remove a filler or alpha byte on write.
+ * The filler type has changed in v0.95 to allow future 2-byte fillers
+ * for 48-bit input data, as well as to avoid problems with some compilers
+ * that don't like bytes as parameters.
+ */
+void PNGAPI
+png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
+{
+ png_debug(1, "in png_set_filler\n");
+ png_ptr->transformations |= PNG_FILLER;
+ png_ptr->filler = (png_byte)filler;
+ if (filler_loc == PNG_FILLER_AFTER)
+ png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
+ else
+ png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
+
+ /* This should probably go in the "do_filler" routine.
+ * I attempted to do that in libpng-1.0.1a but that caused problems
+ * so I restored it in libpng-1.0.2a
+ */
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_ptr->usr_channels = 4;
+ }
+
+ /* Also I added this in libpng-1.0.2a (what happens when we expand
+ * a less-than-8-bit grayscale to GA? */
+
+ if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY && png_ptr->bit_depth >= 8)
+ {
+ png_ptr->usr_channels = 2;
+ }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_swap_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_swap_alpha\n");
+ png_ptr->transformations |= PNG_SWAP_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
+ defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void PNGAPI
+png_set_invert_alpha(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_invert_alpha\n");
+ png_ptr->transformations |= PNG_INVERT_ALPHA;
+}
+#endif
+
+#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
+void PNGAPI
+png_set_invert_mono(png_structp png_ptr)
+{
+ png_debug(1, "in png_set_invert_mono\n");
+ png_ptr->transformations |= PNG_INVERT_MONO;
+}
+
+/* invert monochrome grayscale data */
+void /* PRIVATE */
+png_do_invert(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_invert\n");
+ /* This test removed from libpng version 1.0.13 and 1.2.0:
+ * if (row_info->bit_depth == 1 &&
+ */
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row == NULL || row_info == NULL)
+ return;
+#endif
+ if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(~(*rp));
+ rp++;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ row_info->bit_depth == 8)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i+=2)
+ {
+ *rp = (png_byte)(~(*rp));
+ rp+=2;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA &&
+ row_info->bit_depth == 16)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+
+ for (i = 0; i < istop; i+=4)
+ {
+ *rp = (png_byte)(~(*rp));
+ *(rp+1) = (png_byte)(~(*(rp+1)));
+ rp+=4;
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_SWAP_SUPPORTED) || defined(PNG_WRITE_SWAP_SUPPORTED)
+/* swaps byte order on 16 bit depth images */
+void /* PRIVATE */
+png_do_swap(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_swap\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->bit_depth == 16)
+ {
+ png_bytep rp = row;
+ png_uint_32 i;
+ png_uint_32 istop= row_info->width * row_info->channels;
+
+ for (i = 0; i < istop; i++, rp += 2)
+ {
+ png_byte t = *rp;
+ *rp = *(rp + 1);
+ *(rp + 1) = t;
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+static png_byte onebppswaptable[256] = {
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
+ 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
+ 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+ 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
+ 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
+ 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+ 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
+ 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
+ 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+ 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
+ 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
+ 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+ 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
+ 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
+ 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+ 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
+ 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
+ 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+ 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
+ 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
+ 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+ 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
+ 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
+ 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+ 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
+ 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
+ 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+ 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
+ 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
+ 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
+ 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
+};
+
+static png_byte twobppswaptable[256] = {
+ 0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
+ 0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
+ 0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
+ 0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
+ 0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
+ 0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
+ 0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
+ 0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
+ 0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
+ 0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
+ 0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
+ 0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
+ 0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
+ 0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
+ 0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
+ 0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
+ 0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
+ 0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
+ 0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
+ 0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
+ 0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
+ 0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
+ 0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
+ 0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
+ 0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
+ 0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
+ 0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
+ 0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
+ 0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
+ 0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
+ 0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
+ 0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
+};
+
+static png_byte fourbppswaptable[256] = {
+ 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
+ 0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
+ 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
+ 0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
+ 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
+ 0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
+ 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
+ 0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
+ 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
+ 0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
+ 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
+ 0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
+ 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
+ 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
+ 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
+ 0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
+ 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
+ 0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
+ 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
+ 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
+ 0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
+ 0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
+ 0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
+ 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
+ 0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
+ 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
+ 0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
+ 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
+ 0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
+ 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
+ 0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
+ 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
+};
+
+/* swaps pixel packing order within bytes */
+void /* PRIVATE */
+png_do_packswap(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_packswap\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->bit_depth < 8)
+ {
+ png_bytep rp, end, table;
+
+ end = row + row_info->rowbytes;
+
+ if (row_info->bit_depth == 1)
+ table = onebppswaptable;
+ else if (row_info->bit_depth == 2)
+ table = twobppswaptable;
+ else if (row_info->bit_depth == 4)
+ table = fourbppswaptable;
+ else
+ return;
+
+ for (rp = row; rp < end; rp++)
+ *rp = table[*rp];
+ }
+}
+#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
+ defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
+/* remove filler or alpha byte(s) */
+void /* PRIVATE */
+png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
+{
+ png_debug(1, "in png_do_strip_filler\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+/*
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
+ row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+*/
+ png_bytep sp=row;
+ png_bytep dp=row;
+ png_uint_32 row_width=row_info->width;
+ png_uint_32 i;
+
+ if (row_info->channels == 4)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This converts from RGBX or RGBA to RGB */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ dp+=3; sp+=4;
+ for (i = 1; i < row_width; i++)
+ {
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ sp++;
+ }
+ }
+ /* This converts from XRGB or ARGB to RGB */
+ else
+ {
+ for (i = 0; i < row_width; i++)
+ {
+ sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 24;
+ row_info->rowbytes = row_width * 3;
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ /* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
+ sp += 8; dp += 6;
+ for (i = 1; i < row_width; i++)
+ {
+ /* This could be (although png_memcpy is probably slower):
+ png_memcpy(dp, sp, 6);
+ sp += 8;
+ dp += 6;
+ */
+
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ sp += 2;
+ }
+ }
+ else
+ {
+ /* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
+ for (i = 0; i < row_width; i++)
+ {
+ /* This could be (although png_memcpy is probably slower):
+ png_memcpy(dp, sp, 6);
+ sp += 8;
+ dp += 6;
+ */
+
+ sp+=2;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 48;
+ row_info->rowbytes = row_width * 6;
+ }
+ row_info->channels = 3;
+ row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+ }
+/*
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
+ row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+*/
+ else if (row_info->channels == 2)
+ {
+ if (row_info->bit_depth == 8)
+ {
+ /* This converts from GX or GA to G */
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ for (i = 0; i < row_width; i++)
+ {
+ *dp++ = *sp++;
+ sp++;
+ }
+ }
+ /* This converts from XG or AG to G */
+ else
+ {
+ for (i = 0; i < row_width; i++)
+ {
+ sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 8;
+ row_info->rowbytes = row_width;
+ }
+ else /* if (row_info->bit_depth == 16) */
+ {
+ if (flags & PNG_FLAG_FILLER_AFTER)
+ {
+ /* This converts from GGXX or GGAA to GG */
+ sp += 4; dp += 2;
+ for (i = 1; i < row_width; i++)
+ {
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ sp += 2;
+ }
+ }
+ else
+ {
+ /* This converts from XXGG or AAGG to GG */
+ for (i = 0; i < row_width; i++)
+ {
+ sp += 2;
+ *dp++ = *sp++;
+ *dp++ = *sp++;
+ }
+ }
+ row_info->pixel_depth = 16;
+ row_info->rowbytes = row_width * 2;
+ }
+ row_info->channels = 1;
+ row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
+ }
+ }
+}
+#endif
+
+#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
+/* swaps red and blue bytes within a pixel */
+void /* PRIVATE */
+png_do_bgr(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_bgr\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 3)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 2);
+ *(rp + 2) = save;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 4)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 2);
+ *(rp + 2) = save;
+ }
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 6)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 4);
+ *(rp + 4) = save;
+ save = *(rp + 1);
+ *(rp + 1) = *(rp + 5);
+ *(rp + 5) = save;
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += 8)
+ {
+ png_byte save = *rp;
+ *rp = *(rp + 4);
+ *(rp + 4) = save;
+ save = *(rp + 1);
+ *(rp + 1) = *(rp + 5);
+ *(rp + 5) = save;
+ }
+ }
+ }
+ }
+}
+#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */
+
+#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED) || \
+ defined(PNG_LEGACY_SUPPORTED)
+void PNGAPI
+png_set_user_transform_info(png_structp png_ptr, png_voidp
+ user_transform_ptr, int user_transform_depth, int user_transform_channels)
+{
+ png_debug(1, "in png_set_user_transform_info\n");
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ png_ptr->user_transform_ptr = user_transform_ptr;
+ png_ptr->user_transform_depth = (png_byte)user_transform_depth;
+ png_ptr->user_transform_channels = (png_byte)user_transform_channels;
+#else
+ if(user_transform_ptr || user_transform_depth || user_transform_channels)
+ png_warning(png_ptr,
+ "This version of libpng does not support user transform info");
+#endif
+}
+#endif
+
+/* This function returns a pointer to the user_transform_ptr associated with
+ * the user transform functions. The application should free any memory
+ * associated with this pointer before png_write_destroy and png_read_destroy
+ * are called.
+ */
+png_voidp PNGAPI
+png_get_user_transform_ptr(png_structp png_ptr)
+{
+#if defined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
+ return ((png_voidp)png_ptr->user_transform_ptr);
+#else
+ if(png_ptr)
+ return (NULL);
+ return (NULL);
+#endif
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngvcrd.c b/tqtinterface/qt4/src/3rdparty/libpng/pngvcrd.c
new file mode 100644
index 0000000..53ddb87
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngvcrd.c
@@ -0,0 +1,3845 @@
+/* pngvcrd.c - mixed C/assembler version of utilities to read a PNG file
+ *
+ * For Intel x86 CPU and Microsoft Visual C++ compiler
+ *
+ * libpng version 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * Copyright (c) 1998, Intel Corporation
+ *
+ * Contributed by Nirav Chhatrapati, Intel Corporation, 1998
+ * Interface to libpng contributed by Gilles Vollant, 1999
+ *
+ *
+ * In png_do_read_interlace() in libpng versions 1.0.3a through 1.0.4d,
+ * a sign error in the post-MMX cleanup code for each pixel_depth resulted
+ * in bad pixels at the beginning of some rows of some images, and also
+ * (due to out-of-range memory reads and writes) caused heap corruption
+ * when compiled with MSVC 6.0. The error was fixed in version 1.0.4e.
+ *
+ * [png_read_filter_row_mmx_avg() bpp == 2 bugfix, GRR 20000916]
+ *
+ * [runtime MMX configuration, GRR 20010102]
+ *
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+
+#if defined(PNG_ASSEMBLER_CODE_SUPPORTED) && defined(PNG_USE_PNGVCRD)
+
+static int mmx_supported=2;
+
+
+int PNGAPI
+png_mmx_support(void)
+{
+ int mmx_supported_local = 0;
+ _asm {
+ push ebx //CPUID will trash these
+ push ecx
+ push edx
+
+ pushfd //Save Eflag to stack
+ pop eax //Get Eflag from stack into eax
+ mov ecx, eax //Make another copy of Eflag in ecx
+ xor eax, 0x200000 //Toggle ID bit in Eflag [i.e. bit(21)]
+ push eax //Save modified Eflag back to stack
+
+ popfd //Restored modified value back to Eflag reg
+ pushfd //Save Eflag to stack
+ pop eax //Get Eflag from stack
+ push ecx // save original Eflag to stack
+ popfd // restore original Eflag
+ xor eax, ecx //Compare the new Eflag with the original Eflag
+ jz NOT_SUPPORTED //If the same, CPUID instruction is not supported,
+ //skip following instructions and jump to
+ //NOT_SUPPORTED label
+
+ xor eax, eax //Set eax to zero
+
+ _asm _emit 0x0f //CPUID instruction (two bytes opcode)
+ _asm _emit 0xa2
+
+ cmp eax, 1 //make sure eax return non-zero value
+ jl NOT_SUPPORTED //If eax is zero, mmx not supported
+
+ xor eax, eax //set eax to zero
+ inc eax //Now increment eax to 1. This instruction is
+ //faster than the instruction "mov eax, 1"
+
+ _asm _emit 0x0f //CPUID instruction
+ _asm _emit 0xa2
+
+ and edx, 0x00800000 //tqmask out all bits but mmx bit(24)
+ cmp edx, 0 // 0 = mmx not supported
+ jz NOT_SUPPORTED // non-zero = Yes, mmx IS supported
+
+ mov mmx_supported_local, 1 //set return value to 1
+
+NOT_SUPPORTED:
+ mov eax, mmx_supported_local //move return value to eax
+ pop edx //CPUID trashed these
+ pop ecx
+ pop ebx
+ }
+
+ //mmx_supported_local=0; // test code for force don't support MMX
+ //printf("MMX : %u (1=MMX supported)\n",mmx_supported_local);
+
+ mmx_supported = mmx_supported_local;
+ return mmx_supported_local;
+}
+
+/* Combines the row recently read in with the previous row.
+ This routine takes care of alpha and transparency if requested.
+ This routine also handles the two methods of progressive display
+ of interlaced images, depending on the tqmask value.
+ The tqmask value describes which pixels are to be combined with
+ the row. The pattern always repeats every 8 pixels, so just 8
+ bits are needed. A one indicates the pixel is to be combined; a
+ zero indicates the pixel is to be skipped. This is in addition
+ to any alpha or transparency value associated with the pixel. If
+ you want all pixels to be combined, pass 0xff (255) in tqmask. */
+
+/* Use this routine for x86 platform - uses faster MMX routine if machine
+ supports MMX */
+
+void /* PRIVATE */
+png_combine_row(png_structp png_ptr, png_bytep row, int tqmask)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+
+ png_debug(1,"in png_combine_row_asm\n");
+
+ if (mmx_supported == 2) {
+ /* this should have happened in png_init_mmx_flags() already */
+ png_warning(png_ptr, "asm_flags may not have been initialized");
+ png_mmx_support();
+ }
+
+ if (tqmask == 0xff)
+ {
+ png_memcpy(row, png_ptr->row_buf + 1,
+ (png_size_t)((png_ptr->width * png_ptr->row_info.pixel_depth + 7) >> 3));
+ }
+ /* GRR: add "else if (tqmask == 0)" case?
+ * or does png_combine_row() not even get called in that case? */
+ else
+ {
+ switch (png_ptr->row_info.pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int s_inc, s_start, s_end;
+ int m;
+ int shift;
+ png_uint_32 i;
+
+ sp = png_ptr->row_buf + 1;
+ dp = row;
+ m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+ else
+#endif
+ {
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+
+ shift = s_start;
+
+ for (i = 0; i < png_ptr->width; i++)
+ {
+ if (m & tqmask)
+ {
+ int value;
+
+ value = (*sp >> shift) & 0x1;
+ *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int s_start, s_end, s_inc;
+ int m;
+ int shift;
+ png_uint_32 i;
+ int value;
+
+ sp = png_ptr->row_buf + 1;
+ dp = row;
+ m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+ else
+#endif
+ {
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+
+ shift = s_start;
+
+ for (i = 0; i < png_ptr->width; i++)
+ {
+ if (m & tqmask)
+ {
+ value = (*sp >> shift) & 0x3;
+ *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int s_start, s_end, s_inc;
+ int m;
+ int shift;
+ png_uint_32 i;
+ int value;
+
+ sp = png_ptr->row_buf + 1;
+ dp = row;
+ m = 0x80;
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ {
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+ else
+#endif
+ {
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+ shift = s_start;
+
+ for (i = 0; i < png_ptr->width; i++)
+ {
+ if (m & tqmask)
+ {
+ value = (*sp >> shift) & 0xf;
+ *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
+ *dp |= (png_byte)(value << shift);
+ }
+
+ if (shift == s_end)
+ {
+ shift = s_start;
+ sp++;
+ dp++;
+ }
+ else
+ shift += s_inc;
+ if (m == 1)
+ m = 0x80;
+ else
+ m >>= 1;
+ }
+ break;
+ }
+
+ case 8:
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+ png_uint_32 len;
+ int m;
+ int diff, untqmask;
+
+ __int64 tqmask0=0x0102040810204080;
+
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
+ /* && mmx_supported */ )
+ {
+ srcptr = png_ptr->row_buf + 1;
+ dstptr = row;
+ m = 0x80;
+ untqmask = ~tqmask;
+ len = png_ptr->width &~7; //reduce to multiple of 8
+ diff = png_ptr->width & 7; //amount lost
+
+ _asm
+ {
+ movd mm7, untqmask //load bit pattern
+ psubb mm6,mm6 //zero mm6
+ punpcklbw mm7,mm7
+ punpcklwd mm7,mm7
+ punpckldq mm7,mm7 //fill register with 8 masks
+
+ movq mm0,tqmask0
+
+ pand mm0,mm7 //nonzero if keep byte
+ pcmpeqb mm0,mm6 //zeros->1s, v versa
+
+ mov ecx,len //load length of line (pixels)
+ mov esi,srcptr //load source
+ mov ebx,dstptr //load dest
+ cmp ecx,0 //lcr
+ je mainloop8end
+
+mainloop8:
+ movq mm4,[esi]
+ pand mm4,mm0
+ movq mm6,mm0
+ pandn mm6,[ebx]
+ por mm4,mm6
+ movq [ebx],mm4
+
+ add esi,8 //inc by 8 bytes processed
+ add ebx,8
+ sub ecx,8 //dec by 8 pixels processed
+
+ ja mainloop8
+mainloop8end:
+
+ mov ecx,diff
+ cmp ecx,0
+ jz end8
+
+ mov edx,tqmask
+ sal edx,24 //make low byte the high byte
+
+secondloop8:
+ sal edx,1 //move high bit to CF
+ jnc skip8 //if CF = 0
+ mov al,[esi]
+ mov [ebx],al
+skip8:
+ inc esi
+ inc ebx
+
+ dec ecx
+ jnz secondloop8
+end8:
+ emms
+ }
+ }
+ else /* mmx not supported - use modified C routine */
+ {
+ register unsigned int incr1, initial_val, final_val;
+ png_size_t pixel_bytes;
+ png_uint_32 i;
+ register int disp = png_pass_inc[png_ptr->pass];
+ int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+ srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
+ pixel_bytes;
+ dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
+ initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+ final_val = png_ptr->width*pixel_bytes;
+ incr1 = (disp)*pixel_bytes;
+ for (i = initial_val; i < final_val; i += incr1)
+ {
+ png_memcpy(dstptr, srcptr, pixel_bytes);
+ srcptr += incr1;
+ dstptr += incr1;
+ }
+ } /* end of else */
+
+ break;
+ } // end 8 bpp
+
+ case 16:
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+ png_uint_32 len;
+ int untqmask, diff;
+ __int64 tqmask1=0x0101020204040808,
+ tqmask0=0x1010202040408080;
+
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
+ /* && mmx_supported */ )
+ {
+ srcptr = png_ptr->row_buf + 1;
+ dstptr = row;
+
+ untqmask = ~tqmask;
+ len = (png_ptr->width)&~7;
+ diff = (png_ptr->width)&7;
+ _asm
+ {
+ movd mm7, untqmask //load bit pattern
+ psubb mm6,mm6 //zero mm6
+ punpcklbw mm7,mm7
+ punpcklwd mm7,mm7
+ punpckldq mm7,mm7 //fill register with 8 masks
+
+ movq mm0,tqmask0
+ movq mm1,tqmask1
+
+ pand mm0,mm7
+ pand mm1,mm7
+
+ pcmpeqb mm0,mm6
+ pcmpeqb mm1,mm6
+
+ mov ecx,len //load length of line
+ mov esi,srcptr //load source
+ mov ebx,dstptr //load dest
+ cmp ecx,0 //lcr
+ jz mainloop16end
+
+mainloop16:
+ movq mm4,[esi]
+ pand mm4,mm0
+ movq mm6,mm0
+ movq mm7,[ebx]
+ pandn mm6,mm7
+ por mm4,mm6
+ movq [ebx],mm4
+
+ movq mm5,[esi+8]
+ pand mm5,mm1
+ movq mm7,mm1
+ movq mm6,[ebx+8]
+ pandn mm7,mm6
+ por mm5,mm7
+ movq [ebx+8],mm5
+
+ add esi,16 //inc by 16 bytes processed
+ add ebx,16
+ sub ecx,8 //dec by 8 pixels processed
+
+ ja mainloop16
+
+mainloop16end:
+ mov ecx,diff
+ cmp ecx,0
+ jz end16
+
+ mov edx,tqmask
+ sal edx,24 //make low byte the high byte
+secondloop16:
+ sal edx,1 //move high bit to CF
+ jnc skip16 //if CF = 0
+ mov ax,[esi]
+ mov [ebx],ax
+skip16:
+ add esi,2
+ add ebx,2
+
+ dec ecx
+ jnz secondloop16
+end16:
+ emms
+ }
+ }
+ else /* mmx not supported - use modified C routine */
+ {
+ register unsigned int incr1, initial_val, final_val;
+ png_size_t pixel_bytes;
+ png_uint_32 i;
+ register int disp = png_pass_inc[png_ptr->pass];
+ int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+ srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
+ pixel_bytes;
+ dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
+ initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+ final_val = png_ptr->width*pixel_bytes;
+ incr1 = (disp)*pixel_bytes;
+ for (i = initial_val; i < final_val; i += incr1)
+ {
+ png_memcpy(dstptr, srcptr, pixel_bytes);
+ srcptr += incr1;
+ dstptr += incr1;
+ }
+ } /* end of else */
+
+ break;
+ } // end 16 bpp
+
+ case 24:
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+ png_uint_32 len;
+ int untqmask, diff;
+
+ __int64 tqmask2=0x0101010202020404, //24bpp
+ tqmask1=0x0408080810101020,
+ tqmask0=0x2020404040808080;
+
+ srcptr = png_ptr->row_buf + 1;
+ dstptr = row;
+
+ untqmask = ~tqmask;
+ len = (png_ptr->width)&~7;
+ diff = (png_ptr->width)&7;
+
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
+ /* && mmx_supported */ )
+ {
+ _asm
+ {
+ movd mm7, untqmask //load bit pattern
+ psubb mm6,mm6 //zero mm6
+ punpcklbw mm7,mm7
+ punpcklwd mm7,mm7
+ punpckldq mm7,mm7 //fill register with 8 masks
+
+ movq mm0,tqmask0
+ movq mm1,tqmask1
+ movq mm2,tqmask2
+
+ pand mm0,mm7
+ pand mm1,mm7
+ pand mm2,mm7
+
+ pcmpeqb mm0,mm6
+ pcmpeqb mm1,mm6
+ pcmpeqb mm2,mm6
+
+ mov ecx,len //load length of line
+ mov esi,srcptr //load source
+ mov ebx,dstptr //load dest
+ cmp ecx,0
+ jz mainloop24end
+
+mainloop24:
+ movq mm4,[esi]
+ pand mm4,mm0
+ movq mm6,mm0
+ movq mm7,[ebx]
+ pandn mm6,mm7
+ por mm4,mm6
+ movq [ebx],mm4
+
+
+ movq mm5,[esi+8]
+ pand mm5,mm1
+ movq mm7,mm1
+ movq mm6,[ebx+8]
+ pandn mm7,mm6
+ por mm5,mm7
+ movq [ebx+8],mm5
+
+ movq mm6,[esi+16]
+ pand mm6,mm2
+ movq mm4,mm2
+ movq mm7,[ebx+16]
+ pandn mm4,mm7
+ por mm6,mm4
+ movq [ebx+16],mm6
+
+ add esi,24 //inc by 24 bytes processed
+ add ebx,24
+ sub ecx,8 //dec by 8 pixels processed
+
+ ja mainloop24
+
+mainloop24end:
+ mov ecx,diff
+ cmp ecx,0
+ jz end24
+
+ mov edx,tqmask
+ sal edx,24 //make low byte the high byte
+secondloop24:
+ sal edx,1 //move high bit to CF
+ jnc skip24 //if CF = 0
+ mov ax,[esi]
+ mov [ebx],ax
+ xor eax,eax
+ mov al,[esi+2]
+ mov [ebx+2],al
+skip24:
+ add esi,3
+ add ebx,3
+
+ dec ecx
+ jnz secondloop24
+
+end24:
+ emms
+ }
+ }
+ else /* mmx not supported - use modified C routine */
+ {
+ register unsigned int incr1, initial_val, final_val;
+ png_size_t pixel_bytes;
+ png_uint_32 i;
+ register int disp = png_pass_inc[png_ptr->pass];
+ int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+ srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
+ pixel_bytes;
+ dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
+ initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+ final_val = png_ptr->width*pixel_bytes;
+ incr1 = (disp)*pixel_bytes;
+ for (i = initial_val; i < final_val; i += incr1)
+ {
+ png_memcpy(dstptr, srcptr, pixel_bytes);
+ srcptr += incr1;
+ dstptr += incr1;
+ }
+ } /* end of else */
+
+ break;
+ } // end 24 bpp
+
+ case 32:
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+ png_uint_32 len;
+ int untqmask, diff;
+
+ __int64 tqmask3=0x0101010102020202, //32bpp
+ tqmask2=0x0404040408080808,
+ tqmask1=0x1010101020202020,
+ tqmask0=0x4040404080808080;
+
+ srcptr = png_ptr->row_buf + 1;
+ dstptr = row;
+
+ untqmask = ~tqmask;
+ len = (png_ptr->width)&~7;
+ diff = (png_ptr->width)&7;
+
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
+ /* && mmx_supported */ )
+ {
+ _asm
+ {
+ movd mm7, untqmask //load bit pattern
+ psubb mm6,mm6 //zero mm6
+ punpcklbw mm7,mm7
+ punpcklwd mm7,mm7
+ punpckldq mm7,mm7 //fill register with 8 masks
+
+ movq mm0,tqmask0
+ movq mm1,tqmask1
+ movq mm2,tqmask2
+ movq mm3,tqmask3
+
+ pand mm0,mm7
+ pand mm1,mm7
+ pand mm2,mm7
+ pand mm3,mm7
+
+ pcmpeqb mm0,mm6
+ pcmpeqb mm1,mm6
+ pcmpeqb mm2,mm6
+ pcmpeqb mm3,mm6
+
+ mov ecx,len //load length of line
+ mov esi,srcptr //load source
+ mov ebx,dstptr //load dest
+
+ cmp ecx,0 //lcr
+ jz mainloop32end
+
+mainloop32:
+ movq mm4,[esi]
+ pand mm4,mm0
+ movq mm6,mm0
+ movq mm7,[ebx]
+ pandn mm6,mm7
+ por mm4,mm6
+ movq [ebx],mm4
+
+ movq mm5,[esi+8]
+ pand mm5,mm1
+ movq mm7,mm1
+ movq mm6,[ebx+8]
+ pandn mm7,mm6
+ por mm5,mm7
+ movq [ebx+8],mm5
+
+ movq mm6,[esi+16]
+ pand mm6,mm2
+ movq mm4,mm2
+ movq mm7,[ebx+16]
+ pandn mm4,mm7
+ por mm6,mm4
+ movq [ebx+16],mm6
+
+ movq mm7,[esi+24]
+ pand mm7,mm3
+ movq mm5,mm3
+ movq mm4,[ebx+24]
+ pandn mm5,mm4
+ por mm7,mm5
+ movq [ebx+24],mm7
+
+ add esi,32 //inc by 32 bytes processed
+ add ebx,32
+ sub ecx,8 //dec by 8 pixels processed
+
+ ja mainloop32
+
+mainloop32end:
+ mov ecx,diff
+ cmp ecx,0
+ jz end32
+
+ mov edx,tqmask
+ sal edx,24 //make low byte the high byte
+secondloop32:
+ sal edx,1 //move high bit to CF
+ jnc skip32 //if CF = 0
+ mov eax,[esi]
+ mov [ebx],eax
+skip32:
+ add esi,4
+ add ebx,4
+
+ dec ecx
+ jnz secondloop32
+
+end32:
+ emms
+ }
+ }
+ else /* mmx _not supported - Use modified C routine */
+ {
+ register unsigned int incr1, initial_val, final_val;
+ png_size_t pixel_bytes;
+ png_uint_32 i;
+ register int disp = png_pass_inc[png_ptr->pass];
+ int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+ srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
+ pixel_bytes;
+ dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
+ initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+ final_val = png_ptr->width*pixel_bytes;
+ incr1 = (disp)*pixel_bytes;
+ for (i = initial_val; i < final_val; i += incr1)
+ {
+ png_memcpy(dstptr, srcptr, pixel_bytes);
+ srcptr += incr1;
+ dstptr += incr1;
+ }
+ } /* end of else */
+
+ break;
+ } // end 32 bpp
+
+ case 48:
+ {
+ png_bytep srcptr;
+ png_bytep dstptr;
+ png_uint_32 len;
+ int untqmask, diff;
+
+ __int64 tqmask5=0x0101010101010202,
+ tqmask4=0x0202020204040404,
+ tqmask3=0x0404080808080808,
+ tqmask2=0x1010101010102020,
+ tqmask1=0x2020202040404040,
+ tqmask0=0x4040808080808080;
+
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_COMBINE_ROW)
+ /* && mmx_supported */ )
+ {
+ srcptr = png_ptr->row_buf + 1;
+ dstptr = row;
+
+ untqmask = ~tqmask;
+ len = (png_ptr->width)&~7;
+ diff = (png_ptr->width)&7;
+ _asm
+ {
+ movd mm7, untqmask //load bit pattern
+ psubb mm6,mm6 //zero mm6
+ punpcklbw mm7,mm7
+ punpcklwd mm7,mm7
+ punpckldq mm7,mm7 //fill register with 8 masks
+
+ movq mm0,tqmask0
+ movq mm1,tqmask1
+ movq mm2,tqmask2
+ movq mm3,tqmask3
+ movq mm4,tqmask4
+ movq mm5,tqmask5
+
+ pand mm0,mm7
+ pand mm1,mm7
+ pand mm2,mm7
+ pand mm3,mm7
+ pand mm4,mm7
+ pand mm5,mm7
+
+ pcmpeqb mm0,mm6
+ pcmpeqb mm1,mm6
+ pcmpeqb mm2,mm6
+ pcmpeqb mm3,mm6
+ pcmpeqb mm4,mm6
+ pcmpeqb mm5,mm6
+
+ mov ecx,len //load length of line
+ mov esi,srcptr //load source
+ mov ebx,dstptr //load dest
+
+ cmp ecx,0
+ jz mainloop48end
+
+mainloop48:
+ movq mm7,[esi]
+ pand mm7,mm0
+ movq mm6,mm0
+ pandn mm6,[ebx]
+ por mm7,mm6
+ movq [ebx],mm7
+
+ movq mm6,[esi+8]
+ pand mm6,mm1
+ movq mm7,mm1
+ pandn mm7,[ebx+8]
+ por mm6,mm7
+ movq [ebx+8],mm6
+
+ movq mm6,[esi+16]
+ pand mm6,mm2
+ movq mm7,mm2
+ pandn mm7,[ebx+16]
+ por mm6,mm7
+ movq [ebx+16],mm6
+
+ movq mm7,[esi+24]
+ pand mm7,mm3
+ movq mm6,mm3
+ pandn mm6,[ebx+24]
+ por mm7,mm6
+ movq [ebx+24],mm7
+
+ movq mm6,[esi+32]
+ pand mm6,mm4
+ movq mm7,mm4
+ pandn mm7,[ebx+32]
+ por mm6,mm7
+ movq [ebx+32],mm6
+
+ movq mm7,[esi+40]
+ pand mm7,mm5
+ movq mm6,mm5
+ pandn mm6,[ebx+40]
+ por mm7,mm6
+ movq [ebx+40],mm7
+
+ add esi,48 //inc by 32 bytes processed
+ add ebx,48
+ sub ecx,8 //dec by 8 pixels processed
+
+ ja mainloop48
+mainloop48end:
+
+ mov ecx,diff
+ cmp ecx,0
+ jz end48
+
+ mov edx,tqmask
+ sal edx,24 //make low byte the high byte
+
+secondloop48:
+ sal edx,1 //move high bit to CF
+ jnc skip48 //if CF = 0
+ mov eax,[esi]
+ mov [ebx],eax
+skip48:
+ add esi,4
+ add ebx,4
+
+ dec ecx
+ jnz secondloop48
+
+end48:
+ emms
+ }
+ }
+ else /* mmx _not supported - Use modified C routine */
+ {
+ register unsigned int incr1, initial_val, final_val;
+ png_size_t pixel_bytes;
+ png_uint_32 i;
+ register int disp = png_pass_inc[png_ptr->pass];
+ int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+ srcptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
+ pixel_bytes;
+ dstptr = row + offset_table[png_ptr->pass]*pixel_bytes;
+ initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+ final_val = png_ptr->width*pixel_bytes;
+ incr1 = (disp)*pixel_bytes;
+ for (i = initial_val; i < final_val; i += incr1)
+ {
+ png_memcpy(dstptr, srcptr, pixel_bytes);
+ srcptr += incr1;
+ dstptr += incr1;
+ }
+ } /* end of else */
+
+ break;
+ } // end 48 bpp
+
+ default:
+ {
+ png_bytep sptr;
+ png_bytep dp;
+ png_size_t pixel_bytes;
+ int offset_table[7] = {0, 4, 0, 2, 0, 1, 0};
+ unsigned int i;
+ register int disp = png_pass_inc[png_ptr->pass]; // get the offset
+ register unsigned int incr1, initial_val, final_val;
+
+ pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
+ sptr = png_ptr->row_buf + 1 + offset_table[png_ptr->pass]*
+ pixel_bytes;
+ dp = row + offset_table[png_ptr->pass]*pixel_bytes;
+ initial_val = offset_table[png_ptr->pass]*pixel_bytes;
+ final_val = png_ptr->width*pixel_bytes;
+ incr1 = (disp)*pixel_bytes;
+ for (i = initial_val; i < final_val; i += incr1)
+ {
+ png_memcpy(dp, sptr, pixel_bytes);
+ sptr += incr1;
+ dp += incr1;
+ }
+ break;
+ }
+ } /* end switch (png_ptr->row_info.pixel_depth) */
+ } /* end if (non-trivial tqmask) */
+
+} /* end png_combine_row() */
+
+
+#if defined(PNG_READ_INTERLACING_SUPPORTED)
+
+void /* PRIVATE */
+png_do_read_interlace(png_structp png_ptr)
+{
+ png_row_infop row_info = &(png_ptr->row_info);
+ png_bytep row = png_ptr->row_buf + 1;
+ int pass = png_ptr->pass;
+ png_uint_32 transformations = png_ptr->transformations;
+#ifdef PNG_USE_LOCAL_ARRAYS
+ const int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+
+ png_debug(1,"in png_do_read_interlace\n");
+
+ if (mmx_supported == 2) {
+ /* this should have happened in png_init_mmx_flags() already */
+ png_warning(png_ptr, "asm_flags may not have been initialized");
+ png_mmx_support();
+ }
+
+ if (row != NULL && row_info != NULL)
+ {
+ png_uint_32 final_width;
+
+ final_width = row_info->width * png_pass_inc[pass];
+
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp, dp;
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ png_byte v;
+ png_uint_32 i;
+ int j;
+
+ sp = row + (png_size_t)((row_info->width - 1) >> 3);
+ dp = row + (png_size_t)((final_width - 1) >> 3);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (int)((row_info->width + 7) & 7);
+ dshift = (int)((final_width + 7) & 7);
+ s_start = 7;
+ s_end = 0;
+ s_inc = -1;
+ }
+ else
+#endif
+ {
+ sshift = 7 - (int)((row_info->width + 7) & 7);
+ dshift = 7 - (int)((final_width + 7) & 7);
+ s_start = 0;
+ s_end = 7;
+ s_inc = 1;
+ }
+
+ for (i = row_info->width; i; i--)
+ {
+ v = (png_byte)((*sp >> sshift) & 0x1);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+
+ case 2:
+ {
+ png_bytep sp, dp;
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ png_uint_32 i;
+
+ sp = row + (png_size_t)((row_info->width - 1) >> 2);
+ dp = row + (png_size_t)((final_width - 1) >> 2);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (png_size_t)(((row_info->width + 3) & 3) << 1);
+ dshift = (png_size_t)(((final_width + 3) & 3) << 1);
+ s_start = 6;
+ s_end = 0;
+ s_inc = -2;
+ }
+ else
+#endif
+ {
+ sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
+ dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
+ s_start = 0;
+ s_end = 6;
+ s_inc = 2;
+ }
+
+ for (i = row_info->width; i; i--)
+ {
+ png_byte v;
+ int j;
+
+ v = (png_byte)((*sp >> sshift) & 0x3);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+
+ case 4:
+ {
+ png_bytep sp, dp;
+ int sshift, dshift;
+ int s_start, s_end, s_inc;
+ png_uint_32 i;
+
+ sp = row + (png_size_t)((row_info->width - 1) >> 1);
+ dp = row + (png_size_t)((final_width - 1) >> 1);
+#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (transformations & PNG_PACKSWAP)
+ {
+ sshift = (png_size_t)(((row_info->width + 1) & 1) << 2);
+ dshift = (png_size_t)(((final_width + 1) & 1) << 2);
+ s_start = 4;
+ s_end = 0;
+ s_inc = -4;
+ }
+ else
+#endif
+ {
+ sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
+ dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
+ s_start = 0;
+ s_end = 4;
+ s_inc = 4;
+ }
+
+ for (i = row_info->width; i; i--)
+ {
+ png_byte v;
+ int j;
+
+ v = (png_byte)((*sp >> sshift) & 0xf);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
+ *dp |= (png_byte)(v << dshift);
+ if (dshift == s_end)
+ {
+ dshift = s_start;
+ dp--;
+ }
+ else
+ dshift += s_inc;
+ }
+ if (sshift == s_end)
+ {
+ sshift = s_start;
+ sp--;
+ }
+ else
+ sshift += s_inc;
+ }
+ break;
+ }
+
+ default: // This is the place where the routine is modified
+ {
+ __int64 const4 = 0x0000000000FFFFFF;
+ // __int64 const5 = 0x000000FFFFFF0000; // unused...
+ __int64 const6 = 0x00000000000000FF;
+ png_bytep sptr, dp;
+ png_uint_32 i;
+ png_size_t pixel_bytes;
+ int width = row_info->width;
+
+ pixel_bytes = (row_info->pixel_depth >> 3);
+
+ sptr = row + (width - 1) * pixel_bytes;
+ dp = row + (final_width - 1) * pixel_bytes;
+ // New code by Nirav Chhatrapati - Intel Corporation
+ // sign fix by GRR
+ // NOTE: there is NO MMX code for 48-bit and 64-bit images
+
+ // use MMX routine if machine supports it
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_INTERLACE)
+ /* && mmx_supported */ )
+ {
+ if (pixel_bytes == 3)
+ {
+ if (((pass == 0) || (pass == 1)) && width)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width
+ sub edi, 21 // (png_pass_inc[pass] - 1)*pixel_bytes
+loop_pass0:
+ movd mm0, [esi] ; X X X X X v2 v1 v0
+ pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0
+ movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0
+ psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0
+ movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0
+ psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0
+ psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1
+ por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0
+ por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1
+ movq mm3, mm0 ; v2 v1 v0 v2 v1 v0 v2 v1
+ psllq mm0, 16 ; v0 v2 v1 v0 v2 v1 0 0
+ movq mm4, mm3 ; v2 v1 v0 v2 v1 v0 v2 v1
+ punpckhdq mm3, mm0 ; v0 v2 v1 v0 v2 v1 v0 v2
+ movq [edi+16] , mm4
+ psrlq mm0, 32 ; 0 0 0 0 v0 v2 v1 v0
+ movq [edi+8] , mm3
+ punpckldq mm0, mm4 ; v1 v0 v2 v1 v0 v2 v1 v0
+ sub esi, 3
+ movq [edi], mm0
+ sub edi, 24
+ //sub esi, 3
+ dec ecx
+ jnz loop_pass0
+ EMMS
+ }
+ }
+ else if (((pass == 2) || (pass == 3)) && width)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width
+ sub edi, 9 // (png_pass_inc[pass] - 1)*pixel_bytes
+loop_pass2:
+ movd mm0, [esi] ; X X X X X v2 v1 v0
+ pand mm0, const4 ; 0 0 0 0 0 v2 v1 v0
+ movq mm1, mm0 ; 0 0 0 0 0 v2 v1 v0
+ psllq mm0, 16 ; 0 0 0 v2 v1 v0 0 0
+ movq mm2, mm0 ; 0 0 0 v2 v1 v0 0 0
+ psllq mm0, 24 ; v2 v1 v0 0 0 0 0 0
+ psrlq mm1, 8 ; 0 0 0 0 0 0 v2 v1
+ por mm0, mm2 ; v2 v1 v0 v2 v1 v0 0 0
+ por mm0, mm1 ; v2 v1 v0 v2 v1 v0 v2 v1
+ movq [edi+4], mm0 ; move to memory
+ psrlq mm0, 16 ; 0 0 v2 v1 v0 v2 v1 v0
+ movd [edi], mm0 ; move to memory
+ sub esi, 3
+ sub edi, 12
+ dec ecx
+ jnz loop_pass2
+ EMMS
+ }
+ }
+ else if (width) /* && ((pass == 4) || (pass == 5)) */
+ {
+ int width_mmx = ((width >> 1) << 1) - 8;
+ if (width_mmx < 0)
+ width_mmx = 0;
+ width -= width_mmx; // 8 or 9 pix, 24 or 27 bytes
+ if (width_mmx)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width_mmx
+ sub esi, 3
+ sub edi, 9
+loop_pass4:
+ movq mm0, [esi] ; X X v2 v1 v0 v5 v4 v3
+ movq mm7, mm0 ; X X v2 v1 v0 v5 v4 v3
+ movq mm6, mm0 ; X X v2 v1 v0 v5 v4 v3
+ psllq mm0, 24 ; v1 v0 v5 v4 v3 0 0 0
+ pand mm7, const4 ; 0 0 0 0 0 v5 v4 v3
+ psrlq mm6, 24 ; 0 0 0 X X v2 v1 v0
+ por mm0, mm7 ; v1 v0 v5 v4 v3 v5 v4 v3
+ movq mm5, mm6 ; 0 0 0 X X v2 v1 v0
+ psllq mm6, 8 ; 0 0 X X v2 v1 v0 0
+ movq [edi], mm0 ; move quad to memory
+ psrlq mm5, 16 ; 0 0 0 0 0 X X v2
+ pand mm5, const6 ; 0 0 0 0 0 0 0 v2
+ por mm6, mm5 ; 0 0 X X v2 v1 v0 v2
+ movd [edi+8], mm6 ; move double to memory
+ sub esi, 6
+ sub edi, 12
+ sub ecx, 2
+ jnz loop_pass4
+ EMMS
+ }
+ }
+
+ sptr -= width_mmx*3;
+ dp -= width_mmx*6;
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+
+ png_memcpy(v, sptr, 3);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, 3);
+ dp -= 3;
+ }
+ sptr -= 3;
+ }
+ }
+ } /* end of pixel_bytes == 3 */
+
+ else if (pixel_bytes == 1)
+ {
+ if (((pass == 0) || (pass == 1)) && width)
+ {
+ int width_mmx = ((width >> 2) << 2);
+ width -= width_mmx;
+ if (width_mmx)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width_mmx
+ sub edi, 31
+ sub esi, 3
+loop1_pass0:
+ movd mm0, [esi] ; X X X X v0 v1 v2 v3
+ movq mm1, mm0 ; X X X X v0 v1 v2 v3
+ punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3
+ movq mm2, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3
+ punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3
+ movq mm3, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3
+ punpckldq mm0, mm0 ; v3 v3 v3 v3 v3 v3 v3 v3
+ punpckhdq mm3, mm3 ; v2 v2 v2 v2 v2 v2 v2 v2
+ movq [edi], mm0 ; move to memory v3
+ punpckhwd mm2, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1
+ movq [edi+8], mm3 ; move to memory v2
+ movq mm4, mm2 ; v0 v0 v0 v0 v1 v1 v1 v1
+ punpckldq mm2, mm2 ; v1 v1 v1 v1 v1 v1 v1 v1
+ punpckhdq mm4, mm4 ; v0 v0 v0 v0 v0 v0 v0 v0
+ movq [edi+16], mm2 ; move to memory v1
+ movq [edi+24], mm4 ; move to memory v0
+ sub esi, 4
+ sub edi, 32
+ sub ecx, 4
+ jnz loop1_pass0
+ EMMS
+ }
+ }
+
+ sptr -= width_mmx;
+ dp -= width_mmx*8;
+ for (i = width; i; i--)
+ {
+ int j;
+
+ /* I simplified this part in version 1.0.4e
+ * here and in several other instances where
+ * pixel_bytes == 1 -- GR-P
+ *
+ * Original code:
+ *
+ * png_byte v[8];
+ * png_memcpy(v, sptr, pixel_bytes);
+ * for (j = 0; j < png_pass_inc[pass]; j++)
+ * {
+ * png_memcpy(dp, v, pixel_bytes);
+ * dp -= pixel_bytes;
+ * }
+ * sptr -= pixel_bytes;
+ *
+ * Replacement code is in the next three lines:
+ */
+
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ *dp-- = *sptr;
+ sptr--;
+ }
+ }
+ else if (((pass == 2) || (pass == 3)) && width)
+ {
+ int width_mmx = ((width >> 2) << 2);
+ width -= width_mmx;
+ if (width_mmx)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width_mmx
+ sub edi, 15
+ sub esi, 3
+loop1_pass2:
+ movd mm0, [esi] ; X X X X v0 v1 v2 v3
+ punpcklbw mm0, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3
+ movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3
+ punpcklwd mm0, mm0 ; v2 v2 v2 v2 v3 v3 v3 v3
+ punpckhwd mm1, mm1 ; v0 v0 v0 v0 v1 v1 v1 v1
+ movq [edi], mm0 ; move to memory v2 and v3
+ sub esi, 4
+ movq [edi+8], mm1 ; move to memory v1 and v0
+ sub edi, 16
+ sub ecx, 4
+ jnz loop1_pass2
+ EMMS
+ }
+ }
+
+ sptr -= width_mmx;
+ dp -= width_mmx*4;
+ for (i = width; i; i--)
+ {
+ int j;
+
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp-- = *sptr;
+ }
+ sptr --;
+ }
+ }
+ else if (width) /* && ((pass == 4) || (pass == 5))) */
+ {
+ int width_mmx = ((width >> 3) << 3);
+ width -= width_mmx;
+ if (width_mmx)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width_mmx
+ sub edi, 15
+ sub esi, 7
+loop1_pass4:
+ movq mm0, [esi] ; v0 v1 v2 v3 v4 v5 v6 v7
+ movq mm1, mm0 ; v0 v1 v2 v3 v4 v5 v6 v7
+ punpcklbw mm0, mm0 ; v4 v4 v5 v5 v6 v6 v7 v7
+ //movq mm1, mm0 ; v0 v0 v1 v1 v2 v2 v3 v3
+ punpckhbw mm1, mm1 ;v0 v0 v1 v1 v2 v2 v3 v3
+ movq [edi+8], mm1 ; move to memory v0 v1 v2 and v3
+ sub esi, 8
+ movq [edi], mm0 ; move to memory v4 v5 v6 and v7
+ //sub esi, 4
+ sub edi, 16
+ sub ecx, 8
+ jnz loop1_pass4
+ EMMS
+ }
+ }
+
+ sptr -= width_mmx;
+ dp -= width_mmx*2;
+ for (i = width; i; i--)
+ {
+ int j;
+
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ *dp-- = *sptr;
+ }
+ sptr --;
+ }
+ }
+ } /* end of pixel_bytes == 1 */
+
+ else if (pixel_bytes == 2)
+ {
+ if (((pass == 0) || (pass == 1)) && width)
+ {
+ int width_mmx = ((width >> 1) << 1);
+ width -= width_mmx;
+ if (width_mmx)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width_mmx
+ sub esi, 2
+ sub edi, 30
+loop2_pass0:
+ movd mm0, [esi] ; X X X X v1 v0 v3 v2
+ punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2
+ movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2
+ punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2
+ punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0
+ movq [edi], mm0
+ movq [edi + 8], mm0
+ movq [edi + 16], mm1
+ movq [edi + 24], mm1
+ sub esi, 4
+ sub edi, 32
+ sub ecx, 2
+ jnz loop2_pass0
+ EMMS
+ }
+ }
+
+ sptr -= (width_mmx*2 - 2); // sign fixed
+ dp -= (width_mmx*16 - 2); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 2;
+ png_memcpy(v, sptr, 2);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 2;
+ png_memcpy(dp, v, 2);
+ }
+ }
+ }
+ else if (((pass == 2) || (pass == 3)) && width)
+ {
+ int width_mmx = ((width >> 1) << 1) ;
+ width -= width_mmx;
+ if (width_mmx)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width_mmx
+ sub esi, 2
+ sub edi, 14
+loop2_pass2:
+ movd mm0, [esi] ; X X X X v1 v0 v3 v2
+ punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2
+ movq mm1, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2
+ punpckldq mm0, mm0 ; v3 v2 v3 v2 v3 v2 v3 v2
+ punpckhdq mm1, mm1 ; v1 v0 v1 v0 v1 v0 v1 v0
+ movq [edi], mm0
+ sub esi, 4
+ movq [edi + 8], mm1
+ //sub esi, 4
+ sub edi, 16
+ sub ecx, 2
+ jnz loop2_pass2
+ EMMS
+ }
+ }
+
+ sptr -= (width_mmx*2 - 2); // sign fixed
+ dp -= (width_mmx*8 - 2); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 2;
+ png_memcpy(v, sptr, 2);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 2;
+ png_memcpy(dp, v, 2);
+ }
+ }
+ }
+ else if (width) // pass == 4 or 5
+ {
+ int width_mmx = ((width >> 1) << 1) ;
+ width -= width_mmx;
+ if (width_mmx)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width_mmx
+ sub esi, 2
+ sub edi, 6
+loop2_pass4:
+ movd mm0, [esi] ; X X X X v1 v0 v3 v2
+ punpcklwd mm0, mm0 ; v1 v0 v1 v0 v3 v2 v3 v2
+ sub esi, 4
+ movq [edi], mm0
+ sub edi, 8
+ sub ecx, 2
+ jnz loop2_pass4
+ EMMS
+ }
+ }
+
+ sptr -= (width_mmx*2 - 2); // sign fixed
+ dp -= (width_mmx*4 - 2); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 2;
+ png_memcpy(v, sptr, 2);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 2;
+ png_memcpy(dp, v, 2);
+ }
+ }
+ }
+ } /* end of pixel_bytes == 2 */
+
+ else if (pixel_bytes == 4)
+ {
+ if (((pass == 0) || (pass == 1)) && width)
+ {
+ int width_mmx = ((width >> 1) << 1) ;
+ width -= width_mmx;
+ if (width_mmx)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width_mmx
+ sub esi, 4
+ sub edi, 60
+loop4_pass0:
+ movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4
+ movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4
+ punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4
+ punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0
+ movq [edi], mm0
+ movq [edi + 8], mm0
+ movq [edi + 16], mm0
+ movq [edi + 24], mm0
+ movq [edi+32], mm1
+ movq [edi + 40], mm1
+ movq [edi+ 48], mm1
+ sub esi, 8
+ movq [edi + 56], mm1
+ sub edi, 64
+ sub ecx, 2
+ jnz loop4_pass0
+ EMMS
+ }
+ }
+
+ sptr -= (width_mmx*4 - 4); // sign fixed
+ dp -= (width_mmx*32 - 4); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 4;
+ png_memcpy(v, sptr, 4);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 4;
+ png_memcpy(dp, v, 4);
+ }
+ }
+ }
+ else if (((pass == 2) || (pass == 3)) && width)
+ {
+ int width_mmx = ((width >> 1) << 1) ;
+ width -= width_mmx;
+ if (width_mmx)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width_mmx
+ sub esi, 4
+ sub edi, 28
+loop4_pass2:
+ movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4
+ movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4
+ punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4
+ punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0
+ movq [edi], mm0
+ movq [edi + 8], mm0
+ movq [edi+16], mm1
+ movq [edi + 24], mm1
+ sub esi, 8
+ sub edi, 32
+ sub ecx, 2
+ jnz loop4_pass2
+ EMMS
+ }
+ }
+
+ sptr -= (width_mmx*4 - 4); // sign fixed
+ dp -= (width_mmx*16 - 4); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 4;
+ png_memcpy(v, sptr, 4);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 4;
+ png_memcpy(dp, v, 4);
+ }
+ }
+ }
+ else if (width) // pass == 4 or 5
+ {
+ int width_mmx = ((width >> 1) << 1) ;
+ width -= width_mmx;
+ if (width_mmx)
+ {
+ _asm
+ {
+ mov esi, sptr
+ mov edi, dp
+ mov ecx, width_mmx
+ sub esi, 4
+ sub edi, 12
+loop4_pass4:
+ movq mm0, [esi] ; v3 v2 v1 v0 v7 v6 v5 v4
+ movq mm1, mm0 ; v3 v2 v1 v0 v7 v6 v5 v4
+ punpckldq mm0, mm0 ; v7 v6 v5 v4 v7 v6 v5 v4
+ punpckhdq mm1, mm1 ; v3 v2 v1 v0 v3 v2 v1 v0
+ movq [edi], mm0
+ sub esi, 8
+ movq [edi + 8], mm1
+ sub edi, 16
+ sub ecx, 2
+ jnz loop4_pass4
+ EMMS
+ }
+ }
+
+ sptr -= (width_mmx*4 - 4); // sign fixed
+ dp -= (width_mmx*8 - 4); // sign fixed
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ sptr -= 4;
+ png_memcpy(v, sptr, 4);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ dp -= 4;
+ png_memcpy(dp, v, 4);
+ }
+ }
+ }
+
+ } /* end of pixel_bytes == 4 */
+
+ else if (pixel_bytes == 6)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, 6);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, 6);
+ dp -= 6;
+ }
+ sptr -= 6;
+ }
+ } /* end of pixel_bytes == 6 */
+
+ else
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, pixel_bytes);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sptr-= pixel_bytes;
+ }
+ }
+ } /* end of mmx_supported */
+
+ else /* MMX not supported: use modified C code - takes advantage
+ * of inlining of memcpy for a constant */
+ {
+ if (pixel_bytes == 1)
+ {
+ for (i = width; i; i--)
+ {
+ int j;
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ *dp-- = *sptr;
+ sptr--;
+ }
+ }
+ else if (pixel_bytes == 3)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, pixel_bytes);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sptr -= pixel_bytes;
+ }
+ }
+ else if (pixel_bytes == 2)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, pixel_bytes);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sptr -= pixel_bytes;
+ }
+ }
+ else if (pixel_bytes == 4)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, pixel_bytes);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sptr -= pixel_bytes;
+ }
+ }
+ else if (pixel_bytes == 6)
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, pixel_bytes);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sptr -= pixel_bytes;
+ }
+ }
+ else
+ {
+ for (i = width; i; i--)
+ {
+ png_byte v[8];
+ int j;
+ png_memcpy(v, sptr, pixel_bytes);
+ for (j = 0; j < png_pass_inc[pass]; j++)
+ {
+ png_memcpy(dp, v, pixel_bytes);
+ dp -= pixel_bytes;
+ }
+ sptr -= pixel_bytes;
+ }
+ }
+
+ } /* end of MMX not supported */
+ break;
+ }
+ } /* end switch (row_info->pixel_depth) */
+
+ row_info->width = final_width;
+ row_info->rowbytes = ((final_width *
+ (png_uint_32)row_info->pixel_depth + 7) >> 3);
+ }
+
+}
+
+#endif /* PNG_READ_INTERLACING_SUPPORTED */
+
+
+// These variables are utilized in the functions below. They are declared
+// globally here to ensure tqalignment on 8-byte boundaries.
+
+union uAll {
+ __int64 use;
+ double align;
+} LBCarryMask = {0x0101010101010101},
+ HBClearMask = {0x7f7f7f7f7f7f7f7f},
+ ActiveMask, ActiveMask2, ActiveMaskEnd, ShiftBpp, ShiftRem;
+
+
+// Optimized code for PNG Average filter decoder
+void /* PRIVATE */
+png_read_filter_row_mmx_avg(png_row_infop row_info, png_bytep row
+ , png_bytep prev_row)
+{
+ int bpp;
+ png_uint_32 FullLength;
+ png_uint_32 MMXLength;
+ //png_uint_32 len;
+ int diff;
+
+ bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel
+ FullLength = row_info->rowbytes; // # of bytes to filter
+ _asm {
+ // Init address pointers and offset
+ mov edi, row // edi ==> Avg(x)
+ xor ebx, ebx // ebx ==> x
+ mov edx, edi
+ mov esi, prev_row // esi ==> Prior(x)
+ sub edx, bpp // edx ==> Raw(x-bpp)
+
+ xor eax, eax
+ // Compute the Raw value for the first bpp bytes
+ // Raw(x) = Avg(x) + (Prior(x)/2)
+davgrlp:
+ mov al, [esi + ebx] // Load al with Prior(x)
+ inc ebx
+ shr al, 1 // divide by 2
+ add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx
+ cmp ebx, bpp
+ mov [edi+ebx-1], al // Write back Raw(x);
+ // mov does not affect flags; -1 to offset inc ebx
+ jb davgrlp
+ // get # of bytes to tqalignment
+ mov diff, edi // take start of row
+ add diff, ebx // add bpp
+ add diff, 0xf // add 7 + 8 to incr past tqalignment boundary
+ and diff, 0xfffffff8 // tqmask to tqalignment boundary
+ sub diff, edi // subtract from start ==> value ebx at tqalignment
+ jz davggo
+ // fix tqalignment
+ // Compute the Raw value for the bytes upto the tqalignment boundary
+ // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
+ xor ecx, ecx
+davglp1:
+ xor eax, eax
+ mov cl, [esi + ebx] // load cl with Prior(x)
+ mov al, [edx + ebx] // load al with Raw(x-bpp)
+ add ax, cx
+ inc ebx
+ shr ax, 1 // divide by 2
+ add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx
+ cmp ebx, diff // Check if at tqalignment boundary
+ mov [edi+ebx-1], al // Write back Raw(x);
+ // mov does not affect flags; -1 to offset inc ebx
+ jb davglp1 // Repeat until at tqalignment boundary
+davggo:
+ mov eax, FullLength
+ mov ecx, eax
+ sub eax, ebx // subtract tqalignment fix
+ and eax, 0x00000007 // calc bytes over mult of 8
+ sub ecx, eax // drop over bytes from original length
+ mov MMXLength, ecx
+ } // end _asm block
+ // Now do the math for the rest of the row
+ switch ( bpp )
+ {
+ case 3:
+ {
+ ActiveMask.use = 0x0000000000ffffff;
+ ShiftBpp.use = 24; // == 3 * 8
+ ShiftRem.use = 40; // == 64 - 24
+ _asm {
+ // Re-init address pointers and offset
+ movq mm7, ActiveMask
+ mov ebx, diff // ebx ==> x = offset to tqalignment boundary
+ movq mm5, LBCarryMask
+ mov edi, row // edi ==> Avg(x)
+ movq mm4, HBClearMask
+ mov esi, prev_row // esi ==> Prior(x)
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes
+ // (we correct position in loop below)
+davg3lp:
+ movq mm0, [edi + ebx] // Load mm0 with Avg(x)
+ // Add (Prev_row/2) to Average
+ movq mm3, mm5
+ psrlq mm2, ShiftRem // Correct position Raw(x-bpp) data
+ movq mm1, [esi + ebx] // Load mm1 with Prior(x)
+ movq mm6, mm7
+ pand mm3, mm1 // get lsb for each prev_row byte
+ psrlq mm1, 1 // divide prev_row bytes by 2
+ pand mm1, mm4 // clear invalid bit 7 of each byte
+ paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte
+ // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry
+ movq mm1, mm3 // now use mm1 for getting LBCarrys
+ pand mm1, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1 (Only valid for active group)
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
+ pand mm2, mm6 // Leave only Active Group 1 bytes to add to Avg
+ paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active
+ // byte
+ // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry
+ psllq mm6, ShiftBpp // shift the mm6 tqmask to cover bytes 3-5
+ movq mm2, mm0 // mov updated Raws to mm2
+ psllq mm2, ShiftBpp // shift data to position correctly
+ movq mm1, mm3 // now use mm1 for getting LBCarrys
+ pand mm1, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1 (Only valid for active group)
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
+ pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
+ paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active
+ // byte
+
+ // Add 3rd active group (Raw(x-bpp)/2) to Average with LBCarry
+ psllq mm6, ShiftBpp // shift the mm6 tqmask to cover the last two
+ // bytes
+ movq mm2, mm0 // mov updated Raws to mm2
+ psllq mm2, ShiftBpp // shift data to position correctly
+ // Data only needs to be shifted once here to
+ // get the correct x-bpp offset.
+ movq mm1, mm3 // now use mm1 for getting LBCarrys
+ pand mm1, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1 (Only valid for active group)
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
+ pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
+ add ebx, 8
+ paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active
+ // byte
+
+ // Now ready to write back to memory
+ movq [edi + ebx - 8], mm0
+ // Move updated Raw(x) to use as Raw(x-bpp) for next loop
+ cmp ebx, MMXLength
+ movq mm2, mm0 // mov updated Raw(x) to mm2
+ jb davg3lp
+ } // end _asm block
+ }
+ break;
+
+ case 6:
+ case 4:
+ case 7:
+ case 5:
+ {
+ ActiveMask.use = 0xffffffffffffffff; // use shift below to clear
+ // appropriate inactive bytes
+ ShiftBpp.use = bpp << 3;
+ ShiftRem.use = 64 - ShiftBpp.use;
+ _asm {
+ movq mm4, HBClearMask
+ // Re-init address pointers and offset
+ mov ebx, diff // ebx ==> x = offset to tqalignment boundary
+ // Load ActiveMask and clear all bytes except for 1st active group
+ movq mm7, ActiveMask
+ mov edi, row // edi ==> Avg(x)
+ psrlq mm7, ShiftRem
+ mov esi, prev_row // esi ==> Prior(x)
+ movq mm6, mm7
+ movq mm5, LBCarryMask
+ psllq mm6, ShiftBpp // Create tqmask for 2nd active group
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes
+ // (we correct position in loop below)
+davg4lp:
+ movq mm0, [edi + ebx]
+ psrlq mm2, ShiftRem // shift data to position correctly
+ movq mm1, [esi + ebx]
+ // Add (Prev_row/2) to Average
+ movq mm3, mm5
+ pand mm3, mm1 // get lsb for each prev_row byte
+ psrlq mm1, 1 // divide prev_row bytes by 2
+ pand mm1, mm4 // clear invalid bit 7 of each byte
+ paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte
+ // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry
+ movq mm1, mm3 // now use mm1 for getting LBCarrys
+ pand mm1, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1 (Only valid for active group)
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
+ pand mm2, mm7 // Leave only Active Group 1 bytes to add to Avg
+ paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active
+ // byte
+ // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry
+ movq mm2, mm0 // mov updated Raws to mm2
+ psllq mm2, ShiftBpp // shift data to position correctly
+ add ebx, 8
+ movq mm1, mm3 // now use mm1 for getting LBCarrys
+ pand mm1, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1 (Only valid for active group)
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
+ pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
+ paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active
+ // byte
+ cmp ebx, MMXLength
+ // Now ready to write back to memory
+ movq [edi + ebx - 8], mm0
+ // Prep Raw(x-bpp) for next loop
+ movq mm2, mm0 // mov updated Raws to mm2
+ jb davg4lp
+ } // end _asm block
+ }
+ break;
+ case 2:
+ {
+ ActiveMask.use = 0x000000000000ffff;
+ ShiftBpp.use = 16; // == 2 * 8 [BUGFIX]
+ ShiftRem.use = 48; // == 64 - 16 [BUGFIX]
+ _asm {
+ // Load ActiveMask
+ movq mm7, ActiveMask
+ // Re-init address pointers and offset
+ mov ebx, diff // ebx ==> x = offset to tqalignment boundary
+ movq mm5, LBCarryMask
+ mov edi, row // edi ==> Avg(x)
+ movq mm4, HBClearMask
+ mov esi, prev_row // esi ==> Prior(x)
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes
+ // (we correct position in loop below)
+davg2lp:
+ movq mm0, [edi + ebx]
+ psrlq mm2, ShiftRem // shift data to position correctly [BUGFIX]
+ movq mm1, [esi + ebx]
+ // Add (Prev_row/2) to Average
+ movq mm3, mm5
+ pand mm3, mm1 // get lsb for each prev_row byte
+ psrlq mm1, 1 // divide prev_row bytes by 2
+ pand mm1, mm4 // clear invalid bit 7 of each byte
+ movq mm6, mm7
+ paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte
+ // Add 1st active group (Raw(x-bpp)/2) to Average with LBCarry
+ movq mm1, mm3 // now use mm1 for getting LBCarrys
+ pand mm1, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1 (Only valid for active group)
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
+ pand mm2, mm6 // Leave only Active Group 1 bytes to add to Avg
+ paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte
+ // Add 2nd active group (Raw(x-bpp)/2) to Average with LBCarry
+ psllq mm6, ShiftBpp // shift the mm6 tqmask to cover bytes 2 & 3
+ movq mm2, mm0 // mov updated Raws to mm2
+ psllq mm2, ShiftBpp // shift data to position correctly
+ movq mm1, mm3 // now use mm1 for getting LBCarrys
+ pand mm1, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1 (Only valid for active group)
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
+ pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
+ paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte
+
+ // Add rdd active group (Raw(x-bpp)/2) to Average with LBCarry
+ psllq mm6, ShiftBpp // shift the mm6 tqmask to cover bytes 4 & 5
+ movq mm2, mm0 // mov updated Raws to mm2
+ psllq mm2, ShiftBpp // shift data to position correctly
+ // Data only needs to be shifted once here to
+ // get the correct x-bpp offset.
+ movq mm1, mm3 // now use mm1 for getting LBCarrys
+ pand mm1, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1 (Only valid for active group)
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
+ pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
+ paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte
+
+ // Add 4th active group (Raw(x-bpp)/2) to Average with LBCarry
+ psllq mm6, ShiftBpp // shift the mm6 tqmask to cover bytes 6 & 7
+ movq mm2, mm0 // mov updated Raws to mm2
+ psllq mm2, ShiftBpp // shift data to position correctly
+ // Data only needs to be shifted once here to
+ // get the correct x-bpp offset.
+ add ebx, 8
+ movq mm1, mm3 // now use mm1 for getting LBCarrys
+ pand mm1, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1 (Only valid for active group)
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm2, mm1 // add LBCarrys to (Raw(x-bpp)/2) for each byte
+ pand mm2, mm6 // Leave only Active Group 2 bytes to add to Avg
+ paddb mm0, mm2 // add (Raw/2) + LBCarrys to Avg for each Active byte
+
+ cmp ebx, MMXLength
+ // Now ready to write back to memory
+ movq [edi + ebx - 8], mm0
+ // Prep Raw(x-bpp) for next loop
+ movq mm2, mm0 // mov updated Raws to mm2
+ jb davg2lp
+ } // end _asm block
+ }
+ break;
+
+ case 1: // bpp == 1
+ {
+ _asm {
+ // Re-init address pointers and offset
+ mov ebx, diff // ebx ==> x = offset to tqalignment boundary
+ mov edi, row // edi ==> Avg(x)
+ cmp ebx, FullLength // Test if offset at end of array
+ jnb davg1end
+ // Do Paeth decode for remaining bytes
+ mov esi, prev_row // esi ==> Prior(x)
+ mov edx, edi
+ xor ecx, ecx // zero ecx before using cl & cx in loop below
+ sub edx, bpp // edx ==> Raw(x-bpp)
+davg1lp:
+ // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
+ xor eax, eax
+ mov cl, [esi + ebx] // load cl with Prior(x)
+ mov al, [edx + ebx] // load al with Raw(x-bpp)
+ add ax, cx
+ inc ebx
+ shr ax, 1 // divide by 2
+ add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx
+ cmp ebx, FullLength // Check if at end of array
+ mov [edi+ebx-1], al // Write back Raw(x);
+ // mov does not affect flags; -1 to offset inc ebx
+ jb davg1lp
+davg1end:
+ } // end _asm block
+ }
+ return;
+
+ case 8: // bpp == 8
+ {
+ _asm {
+ // Re-init address pointers and offset
+ mov ebx, diff // ebx ==> x = offset to tqalignment boundary
+ movq mm5, LBCarryMask
+ mov edi, row // edi ==> Avg(x)
+ movq mm4, HBClearMask
+ mov esi, prev_row // esi ==> Prior(x)
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm2, [edi + ebx - 8] // Load previous aligned 8 bytes
+ // (NO NEED to correct position in loop below)
+davg8lp:
+ movq mm0, [edi + ebx]
+ movq mm3, mm5
+ movq mm1, [esi + ebx]
+ add ebx, 8
+ pand mm3, mm1 // get lsb for each prev_row byte
+ psrlq mm1, 1 // divide prev_row bytes by 2
+ pand mm3, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm1, mm4 // clear invalid bit 7 of each byte
+ paddb mm0, mm3 // add LBCarrys to Avg for each byte
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte
+ paddb mm0, mm2 // add (Raw/2) to Avg for each byte
+ cmp ebx, MMXLength
+ movq [edi + ebx - 8], mm0
+ movq mm2, mm0 // reuse as Raw(x-bpp)
+ jb davg8lp
+ } // end _asm block
+ }
+ break;
+ default: // bpp greater than 8
+ {
+ _asm {
+ movq mm5, LBCarryMask
+ // Re-init address pointers and offset
+ mov ebx, diff // ebx ==> x = offset to tqalignment boundary
+ mov edi, row // edi ==> Avg(x)
+ movq mm4, HBClearMask
+ mov edx, edi
+ mov esi, prev_row // esi ==> Prior(x)
+ sub edx, bpp // edx ==> Raw(x-bpp)
+davgAlp:
+ movq mm0, [edi + ebx]
+ movq mm3, mm5
+ movq mm1, [esi + ebx]
+ pand mm3, mm1 // get lsb for each prev_row byte
+ movq mm2, [edx + ebx]
+ psrlq mm1, 1 // divide prev_row bytes by 2
+ pand mm3, mm2 // get LBCarrys for each byte where both
+ // lsb's were == 1
+ psrlq mm2, 1 // divide raw bytes by 2
+ pand mm1, mm4 // clear invalid bit 7 of each byte
+ paddb mm0, mm3 // add LBCarrys to Avg for each byte
+ pand mm2, mm4 // clear invalid bit 7 of each byte
+ paddb mm0, mm1 // add (Prev_row/2) to Avg for each byte
+ add ebx, 8
+ paddb mm0, mm2 // add (Raw/2) to Avg for each byte
+ cmp ebx, MMXLength
+ movq [edi + ebx - 8], mm0
+ jb davgAlp
+ } // end _asm block
+ }
+ break;
+ } // end switch ( bpp )
+
+ _asm {
+ // MMX acceleration complete now do clean-up
+ // Check if any remaining bytes left to decode
+ mov ebx, MMXLength // ebx ==> x = offset bytes remaining after MMX
+ mov edi, row // edi ==> Avg(x)
+ cmp ebx, FullLength // Test if offset at end of array
+ jnb davgend
+ // Do Paeth decode for remaining bytes
+ mov esi, prev_row // esi ==> Prior(x)
+ mov edx, edi
+ xor ecx, ecx // zero ecx before using cl & cx in loop below
+ sub edx, bpp // edx ==> Raw(x-bpp)
+davglp2:
+ // Raw(x) = Avg(x) + ((Raw(x-bpp) + Prior(x))/2)
+ xor eax, eax
+ mov cl, [esi + ebx] // load cl with Prior(x)
+ mov al, [edx + ebx] // load al with Raw(x-bpp)
+ add ax, cx
+ inc ebx
+ shr ax, 1 // divide by 2
+ add al, [edi+ebx-1] // Add Avg(x); -1 to offset inc ebx
+ cmp ebx, FullLength // Check if at end of array
+ mov [edi+ebx-1], al // Write back Raw(x);
+ // mov does not affect flags; -1 to offset inc ebx
+ jb davglp2
+davgend:
+ emms // End MMX instructions; prep for possible FP instrs.
+ } // end _asm block
+}
+
+// Optimized code for PNG Paeth filter decoder
+void /* PRIVATE */
+png_read_filter_row_mmx_paeth(png_row_infop row_info, png_bytep row,
+ png_bytep prev_row)
+{
+ png_uint_32 FullLength;
+ png_uint_32 MMXLength;
+ //png_uint_32 len;
+ int bpp;
+ int diff;
+ //int ptemp;
+ int patemp, pbtemp, pctemp;
+
+ bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel
+ FullLength = row_info->rowbytes; // # of bytes to filter
+ _asm
+ {
+ xor ebx, ebx // ebx ==> x offset
+ mov edi, row
+ xor edx, edx // edx ==> x-bpp offset
+ mov esi, prev_row
+ xor eax, eax
+
+ // Compute the Raw value for the first bpp bytes
+ // Note: the formula works out to be always
+ // Paeth(x) = Raw(x) + Prior(x) where x < bpp
+dpthrlp:
+ mov al, [edi + ebx]
+ add al, [esi + ebx]
+ inc ebx
+ cmp ebx, bpp
+ mov [edi + ebx - 1], al
+ jb dpthrlp
+ // get # of bytes to tqalignment
+ mov diff, edi // take start of row
+ add diff, ebx // add bpp
+ xor ecx, ecx
+ add diff, 0xf // add 7 + 8 to incr past tqalignment boundary
+ and diff, 0xfffffff8 // tqmask to tqalignment boundary
+ sub diff, edi // subtract from start ==> value ebx at tqalignment
+ jz dpthgo
+ // fix tqalignment
+dpthlp1:
+ xor eax, eax
+ // pav = p - a = (a + b - c) - a = b - c
+ mov al, [esi + ebx] // load Prior(x) into al
+ mov cl, [esi + edx] // load Prior(x-bpp) into cl
+ sub eax, ecx // subtract Prior(x-bpp)
+ mov patemp, eax // Save pav for later use
+ xor eax, eax
+ // pbv = p - b = (a + b - c) - b = a - c
+ mov al, [edi + edx] // load Raw(x-bpp) into al
+ sub eax, ecx // subtract Prior(x-bpp)
+ mov ecx, eax
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ add eax, patemp // pcv = pav + pbv
+ // pc = abs(pcv)
+ test eax, 0x80000000
+ jz dpthpca
+ neg eax // reverse sign of neg values
+dpthpca:
+ mov pctemp, eax // save pc for later use
+ // pb = abs(pbv)
+ test ecx, 0x80000000
+ jz dpthpba
+ neg ecx // reverse sign of neg values
+dpthpba:
+ mov pbtemp, ecx // save pb for later use
+ // pa = abs(pav)
+ mov eax, patemp
+ test eax, 0x80000000
+ jz dpthpaa
+ neg eax // reverse sign of neg values
+dpthpaa:
+ mov patemp, eax // save pa for later use
+ // test if pa <= pb
+ cmp eax, ecx
+ jna dpthabb
+ // pa > pb; now test if pb <= pc
+ cmp ecx, pctemp
+ jna dpthbbc
+ // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ mov cl, [esi + edx] // load Prior(x-bpp) into cl
+ jmp dpthpaeth
+dpthbbc:
+ // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
+ mov cl, [esi + ebx] // load Prior(x) into cl
+ jmp dpthpaeth
+dpthabb:
+ // pa <= pb; now test if pa <= pc
+ cmp eax, pctemp
+ jna dpthabc
+ // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ mov cl, [esi + edx] // load Prior(x-bpp) into cl
+ jmp dpthpaeth
+dpthabc:
+ // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
+ mov cl, [edi + edx] // load Raw(x-bpp) into cl
+dpthpaeth:
+ inc ebx
+ inc edx
+ // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
+ add [edi + ebx - 1], cl
+ cmp ebx, diff
+ jb dpthlp1
+dpthgo:
+ mov ecx, FullLength
+ mov eax, ecx
+ sub eax, ebx // subtract tqalignment fix
+ and eax, 0x00000007 // calc bytes over mult of 8
+ sub ecx, eax // drop over bytes from original length
+ mov MMXLength, ecx
+ } // end _asm block
+ // Now do the math for the rest of the row
+ switch ( bpp )
+ {
+ case 3:
+ {
+ ActiveMask.use = 0x0000000000ffffff;
+ ActiveMaskEnd.use = 0xffff000000000000;
+ ShiftBpp.use = 24; // == bpp(3) * 8
+ ShiftRem.use = 40; // == 64 - 24
+ _asm
+ {
+ mov ebx, diff
+ mov edi, row
+ mov esi, prev_row
+ pxor mm0, mm0
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm1, [edi+ebx-8]
+dpth3lp:
+ psrlq mm1, ShiftRem // shift last 3 bytes to 1st 3 bytes
+ movq mm2, [esi + ebx] // load b=Prior(x)
+ punpcklbw mm1, mm0 // Unpack High bytes of a
+ movq mm3, [esi+ebx-8] // Prep c=Prior(x-bpp) bytes
+ punpcklbw mm2, mm0 // Unpack High bytes of b
+ psrlq mm3, ShiftRem // shift last 3 bytes to 1st 3 bytes
+ // pav = p - a = (a + b - c) - a = b - c
+ movq mm4, mm2
+ punpcklbw mm3, mm0 // Unpack High bytes of c
+ // pbv = p - b = (a + b - c) - b = a - c
+ movq mm5, mm1
+ psubw mm4, mm3
+ pxor mm7, mm7
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ movq mm6, mm4
+ psubw mm5, mm3
+
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ pcmpgtw mm0, mm4 // Create tqmask pav bytes < 0
+ paddw mm6, mm5
+ pand mm0, mm4 // Only pav bytes < 0 in mm7
+ pcmpgtw mm7, mm5 // Create tqmask pbv bytes < 0
+ psubw mm4, mm0
+ pand mm7, mm5 // Only pbv bytes < 0 in mm0
+ psubw mm4, mm0
+ psubw mm5, mm7
+ pxor mm0, mm0
+ pcmpgtw mm0, mm6 // Create tqmask pcv bytes < 0
+ pand mm0, mm6 // Only pav bytes < 0 in mm7
+ psubw mm5, mm7
+ psubw mm6, mm0
+ // test pa <= pb
+ movq mm7, mm4
+ psubw mm6, mm0
+ pcmpgtw mm7, mm5 // pa > pb?
+ movq mm0, mm7
+ // use mm7 tqmask to merge pa & pb
+ pand mm5, mm7
+ // use mm0 tqmask copy to merge a & b
+ pand mm2, mm0
+ pandn mm7, mm4
+ pandn mm0, mm1
+ paddw mm7, mm5
+ paddw mm0, mm2
+ // test ((pa <= pb)? pa:pb) <= pc
+ pcmpgtw mm7, mm6 // pab > pc?
+ pxor mm1, mm1
+ pand mm3, mm7
+ pandn mm7, mm0
+ paddw mm7, mm3
+ pxor mm0, mm0
+ packuswb mm7, mm1
+ movq mm3, [esi + ebx] // load c=Prior(x-bpp)
+ pand mm7, ActiveMask
+ movq mm2, mm3 // load b=Prior(x) step 1
+ paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x)
+ punpcklbw mm3, mm0 // Unpack High bytes of c
+ movq [edi + ebx], mm7 // write back updated value
+ movq mm1, mm7 // Now mm1 will be used as Raw(x-bpp)
+ // Now do Paeth for 2nd set of bytes (3-5)
+ psrlq mm2, ShiftBpp // load b=Prior(x) step 2
+ punpcklbw mm1, mm0 // Unpack High bytes of a
+ pxor mm7, mm7
+ punpcklbw mm2, mm0 // Unpack High bytes of b
+ // pbv = p - b = (a + b - c) - b = a - c
+ movq mm5, mm1
+ // pav = p - a = (a + b - c) - a = b - c
+ movq mm4, mm2
+ psubw mm5, mm3
+ psubw mm4, mm3
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) =
+ // pav + pbv = pbv + pav
+ movq mm6, mm5
+ paddw mm6, mm4
+
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ pcmpgtw mm0, mm5 // Create tqmask pbv bytes < 0
+ pcmpgtw mm7, mm4 // Create tqmask pav bytes < 0
+ pand mm0, mm5 // Only pbv bytes < 0 in mm0
+ pand mm7, mm4 // Only pav bytes < 0 in mm7
+ psubw mm5, mm0
+ psubw mm4, mm7
+ psubw mm5, mm0
+ psubw mm4, mm7
+ pxor mm0, mm0
+ pcmpgtw mm0, mm6 // Create tqmask pcv bytes < 0
+ pand mm0, mm6 // Only pav bytes < 0 in mm7
+ psubw mm6, mm0
+ // test pa <= pb
+ movq mm7, mm4
+ psubw mm6, mm0
+ pcmpgtw mm7, mm5 // pa > pb?
+ movq mm0, mm7
+ // use mm7 tqmask to merge pa & pb
+ pand mm5, mm7
+ // use mm0 tqmask copy to merge a & b
+ pand mm2, mm0
+ pandn mm7, mm4
+ pandn mm0, mm1
+ paddw mm7, mm5
+ paddw mm0, mm2
+ // test ((pa <= pb)? pa:pb) <= pc
+ pcmpgtw mm7, mm6 // pab > pc?
+ movq mm2, [esi + ebx] // load b=Prior(x)
+ pand mm3, mm7
+ pandn mm7, mm0
+ pxor mm1, mm1
+ paddw mm7, mm3
+ pxor mm0, mm0
+ packuswb mm7, mm1
+ movq mm3, mm2 // load c=Prior(x-bpp) step 1
+ pand mm7, ActiveMask
+ punpckhbw mm2, mm0 // Unpack High bytes of b
+ psllq mm7, ShiftBpp // Shift bytes to 2nd group of 3 bytes
+ // pav = p - a = (a + b - c) - a = b - c
+ movq mm4, mm2
+ paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x)
+ psllq mm3, ShiftBpp // load c=Prior(x-bpp) step 2
+ movq [edi + ebx], mm7 // write back updated value
+ movq mm1, mm7
+ punpckhbw mm3, mm0 // Unpack High bytes of c
+ psllq mm1, ShiftBpp // Shift bytes
+ // Now mm1 will be used as Raw(x-bpp)
+ // Now do Paeth for 3rd, and final, set of bytes (6-7)
+ pxor mm7, mm7
+ punpckhbw mm1, mm0 // Unpack High bytes of a
+ psubw mm4, mm3
+ // pbv = p - b = (a + b - c) - b = a - c
+ movq mm5, mm1
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ movq mm6, mm4
+ psubw mm5, mm3
+ pxor mm0, mm0
+ paddw mm6, mm5
+
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ pcmpgtw mm0, mm4 // Create tqmask pav bytes < 0
+ pcmpgtw mm7, mm5 // Create tqmask pbv bytes < 0
+ pand mm0, mm4 // Only pav bytes < 0 in mm7
+ pand mm7, mm5 // Only pbv bytes < 0 in mm0
+ psubw mm4, mm0
+ psubw mm5, mm7
+ psubw mm4, mm0
+ psubw mm5, mm7
+ pxor mm0, mm0
+ pcmpgtw mm0, mm6 // Create tqmask pcv bytes < 0
+ pand mm0, mm6 // Only pav bytes < 0 in mm7
+ psubw mm6, mm0
+ // test pa <= pb
+ movq mm7, mm4
+ psubw mm6, mm0
+ pcmpgtw mm7, mm5 // pa > pb?
+ movq mm0, mm7
+ // use mm0 tqmask copy to merge a & b
+ pand mm2, mm0
+ // use mm7 tqmask to merge pa & pb
+ pand mm5, mm7
+ pandn mm0, mm1
+ pandn mm7, mm4
+ paddw mm0, mm2
+ paddw mm7, mm5
+ // test ((pa <= pb)? pa:pb) <= pc
+ pcmpgtw mm7, mm6 // pab > pc?
+ pand mm3, mm7
+ pandn mm7, mm0
+ paddw mm7, mm3
+ pxor mm1, mm1
+ packuswb mm1, mm7
+ // Step ebx to next set of 8 bytes and repeat loop til done
+ add ebx, 8
+ pand mm1, ActiveMaskEnd
+ paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x)
+
+ cmp ebx, MMXLength
+ pxor mm0, mm0 // pxor does not affect flags
+ movq [edi + ebx - 8], mm1 // write back updated value
+ // mm1 will be used as Raw(x-bpp) next loop
+ // mm3 ready to be used as Prior(x-bpp) next loop
+ jb dpth3lp
+ } // end _asm block
+ }
+ break;
+
+ case 6:
+ case 7:
+ case 5:
+ {
+ ActiveMask.use = 0x00000000ffffffff;
+ ActiveMask2.use = 0xffffffff00000000;
+ ShiftBpp.use = bpp << 3; // == bpp * 8
+ ShiftRem.use = 64 - ShiftBpp.use;
+ _asm
+ {
+ mov ebx, diff
+ mov edi, row
+ mov esi, prev_row
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm1, [edi+ebx-8]
+ pxor mm0, mm0
+dpth6lp:
+ // Must shift to position Raw(x-bpp) data
+ psrlq mm1, ShiftRem
+ // Do first set of 4 bytes
+ movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes
+ punpcklbw mm1, mm0 // Unpack Low bytes of a
+ movq mm2, [esi + ebx] // load b=Prior(x)
+ punpcklbw mm2, mm0 // Unpack Low bytes of b
+ // Must shift to position Prior(x-bpp) data
+ psrlq mm3, ShiftRem
+ // pav = p - a = (a + b - c) - a = b - c
+ movq mm4, mm2
+ punpcklbw mm3, mm0 // Unpack Low bytes of c
+ // pbv = p - b = (a + b - c) - b = a - c
+ movq mm5, mm1
+ psubw mm4, mm3
+ pxor mm7, mm7
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ movq mm6, mm4
+ psubw mm5, mm3
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ pcmpgtw mm0, mm4 // Create tqmask pav bytes < 0
+ paddw mm6, mm5
+ pand mm0, mm4 // Only pav bytes < 0 in mm7
+ pcmpgtw mm7, mm5 // Create tqmask pbv bytes < 0
+ psubw mm4, mm0
+ pand mm7, mm5 // Only pbv bytes < 0 in mm0
+ psubw mm4, mm0
+ psubw mm5, mm7
+ pxor mm0, mm0
+ pcmpgtw mm0, mm6 // Create tqmask pcv bytes < 0
+ pand mm0, mm6 // Only pav bytes < 0 in mm7
+ psubw mm5, mm7
+ psubw mm6, mm0
+ // test pa <= pb
+ movq mm7, mm4
+ psubw mm6, mm0
+ pcmpgtw mm7, mm5 // pa > pb?
+ movq mm0, mm7
+ // use mm7 tqmask to merge pa & pb
+ pand mm5, mm7
+ // use mm0 tqmask copy to merge a & b
+ pand mm2, mm0
+ pandn mm7, mm4
+ pandn mm0, mm1
+ paddw mm7, mm5
+ paddw mm0, mm2
+ // test ((pa <= pb)? pa:pb) <= pc
+ pcmpgtw mm7, mm6 // pab > pc?
+ pxor mm1, mm1
+ pand mm3, mm7
+ pandn mm7, mm0
+ paddw mm7, mm3
+ pxor mm0, mm0
+ packuswb mm7, mm1
+ movq mm3, [esi + ebx - 8] // load c=Prior(x-bpp)
+ pand mm7, ActiveMask
+ psrlq mm3, ShiftRem
+ movq mm2, [esi + ebx] // load b=Prior(x) step 1
+ paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x)
+ movq mm6, mm2
+ movq [edi + ebx], mm7 // write back updated value
+ movq mm1, [edi+ebx-8]
+ psllq mm6, ShiftBpp
+ movq mm5, mm7
+ psrlq mm1, ShiftRem
+ por mm3, mm6
+ psllq mm5, ShiftBpp
+ punpckhbw mm3, mm0 // Unpack High bytes of c
+ por mm1, mm5
+ // Do second set of 4 bytes
+ punpckhbw mm2, mm0 // Unpack High bytes of b
+ punpckhbw mm1, mm0 // Unpack High bytes of a
+ // pav = p - a = (a + b - c) - a = b - c
+ movq mm4, mm2
+ // pbv = p - b = (a + b - c) - b = a - c
+ movq mm5, mm1
+ psubw mm4, mm3
+ pxor mm7, mm7
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ movq mm6, mm4
+ psubw mm5, mm3
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ pcmpgtw mm0, mm4 // Create tqmask pav bytes < 0
+ paddw mm6, mm5
+ pand mm0, mm4 // Only pav bytes < 0 in mm7
+ pcmpgtw mm7, mm5 // Create tqmask pbv bytes < 0
+ psubw mm4, mm0
+ pand mm7, mm5 // Only pbv bytes < 0 in mm0
+ psubw mm4, mm0
+ psubw mm5, mm7
+ pxor mm0, mm0
+ pcmpgtw mm0, mm6 // Create tqmask pcv bytes < 0
+ pand mm0, mm6 // Only pav bytes < 0 in mm7
+ psubw mm5, mm7
+ psubw mm6, mm0
+ // test pa <= pb
+ movq mm7, mm4
+ psubw mm6, mm0
+ pcmpgtw mm7, mm5 // pa > pb?
+ movq mm0, mm7
+ // use mm7 tqmask to merge pa & pb
+ pand mm5, mm7
+ // use mm0 tqmask copy to merge a & b
+ pand mm2, mm0
+ pandn mm7, mm4
+ pandn mm0, mm1
+ paddw mm7, mm5
+ paddw mm0, mm2
+ // test ((pa <= pb)? pa:pb) <= pc
+ pcmpgtw mm7, mm6 // pab > pc?
+ pxor mm1, mm1
+ pand mm3, mm7
+ pandn mm7, mm0
+ pxor mm1, mm1
+ paddw mm7, mm3
+ pxor mm0, mm0
+ // Step ex to next set of 8 bytes and repeat loop til done
+ add ebx, 8
+ packuswb mm1, mm7
+ paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x)
+ cmp ebx, MMXLength
+ movq [edi + ebx - 8], mm1 // write back updated value
+ // mm1 will be used as Raw(x-bpp) next loop
+ jb dpth6lp
+ } // end _asm block
+ }
+ break;
+
+ case 4:
+ {
+ ActiveMask.use = 0x00000000ffffffff;
+ _asm {
+ mov ebx, diff
+ mov edi, row
+ mov esi, prev_row
+ pxor mm0, mm0
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm1, [edi+ebx-8] // Only time should need to read
+ // a=Raw(x-bpp) bytes
+dpth4lp:
+ // Do first set of 4 bytes
+ movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes
+ punpckhbw mm1, mm0 // Unpack Low bytes of a
+ movq mm2, [esi + ebx] // load b=Prior(x)
+ punpcklbw mm2, mm0 // Unpack High bytes of b
+ // pav = p - a = (a + b - c) - a = b - c
+ movq mm4, mm2
+ punpckhbw mm3, mm0 // Unpack High bytes of c
+ // pbv = p - b = (a + b - c) - b = a - c
+ movq mm5, mm1
+ psubw mm4, mm3
+ pxor mm7, mm7
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ movq mm6, mm4
+ psubw mm5, mm3
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ pcmpgtw mm0, mm4 // Create tqmask pav bytes < 0
+ paddw mm6, mm5
+ pand mm0, mm4 // Only pav bytes < 0 in mm7
+ pcmpgtw mm7, mm5 // Create tqmask pbv bytes < 0
+ psubw mm4, mm0
+ pand mm7, mm5 // Only pbv bytes < 0 in mm0
+ psubw mm4, mm0
+ psubw mm5, mm7
+ pxor mm0, mm0
+ pcmpgtw mm0, mm6 // Create tqmask pcv bytes < 0
+ pand mm0, mm6 // Only pav bytes < 0 in mm7
+ psubw mm5, mm7
+ psubw mm6, mm0
+ // test pa <= pb
+ movq mm7, mm4
+ psubw mm6, mm0
+ pcmpgtw mm7, mm5 // pa > pb?
+ movq mm0, mm7
+ // use mm7 tqmask to merge pa & pb
+ pand mm5, mm7
+ // use mm0 tqmask copy to merge a & b
+ pand mm2, mm0
+ pandn mm7, mm4
+ pandn mm0, mm1
+ paddw mm7, mm5
+ paddw mm0, mm2
+ // test ((pa <= pb)? pa:pb) <= pc
+ pcmpgtw mm7, mm6 // pab > pc?
+ pxor mm1, mm1
+ pand mm3, mm7
+ pandn mm7, mm0
+ paddw mm7, mm3
+ pxor mm0, mm0
+ packuswb mm7, mm1
+ movq mm3, [esi + ebx] // load c=Prior(x-bpp)
+ pand mm7, ActiveMask
+ movq mm2, mm3 // load b=Prior(x) step 1
+ paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x)
+ punpcklbw mm3, mm0 // Unpack High bytes of c
+ movq [edi + ebx], mm7 // write back updated value
+ movq mm1, mm7 // Now mm1 will be used as Raw(x-bpp)
+ // Do second set of 4 bytes
+ punpckhbw mm2, mm0 // Unpack Low bytes of b
+ punpcklbw mm1, mm0 // Unpack Low bytes of a
+ // pav = p - a = (a + b - c) - a = b - c
+ movq mm4, mm2
+ // pbv = p - b = (a + b - c) - b = a - c
+ movq mm5, mm1
+ psubw mm4, mm3
+ pxor mm7, mm7
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ movq mm6, mm4
+ psubw mm5, mm3
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ pcmpgtw mm0, mm4 // Create tqmask pav bytes < 0
+ paddw mm6, mm5
+ pand mm0, mm4 // Only pav bytes < 0 in mm7
+ pcmpgtw mm7, mm5 // Create tqmask pbv bytes < 0
+ psubw mm4, mm0
+ pand mm7, mm5 // Only pbv bytes < 0 in mm0
+ psubw mm4, mm0
+ psubw mm5, mm7
+ pxor mm0, mm0
+ pcmpgtw mm0, mm6 // Create tqmask pcv bytes < 0
+ pand mm0, mm6 // Only pav bytes < 0 in mm7
+ psubw mm5, mm7
+ psubw mm6, mm0
+ // test pa <= pb
+ movq mm7, mm4
+ psubw mm6, mm0
+ pcmpgtw mm7, mm5 // pa > pb?
+ movq mm0, mm7
+ // use mm7 tqmask to merge pa & pb
+ pand mm5, mm7
+ // use mm0 tqmask copy to merge a & b
+ pand mm2, mm0
+ pandn mm7, mm4
+ pandn mm0, mm1
+ paddw mm7, mm5
+ paddw mm0, mm2
+ // test ((pa <= pb)? pa:pb) <= pc
+ pcmpgtw mm7, mm6 // pab > pc?
+ pxor mm1, mm1
+ pand mm3, mm7
+ pandn mm7, mm0
+ pxor mm1, mm1
+ paddw mm7, mm3
+ pxor mm0, mm0
+ // Step ex to next set of 8 bytes and repeat loop til done
+ add ebx, 8
+ packuswb mm1, mm7
+ paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x)
+ cmp ebx, MMXLength
+ movq [edi + ebx - 8], mm1 // write back updated value
+ // mm1 will be used as Raw(x-bpp) next loop
+ jb dpth4lp
+ } // end _asm block
+ }
+ break;
+ case 8: // bpp == 8
+ {
+ ActiveMask.use = 0x00000000ffffffff;
+ _asm {
+ mov ebx, diff
+ mov edi, row
+ mov esi, prev_row
+ pxor mm0, mm0
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm1, [edi+ebx-8] // Only time should need to read
+ // a=Raw(x-bpp) bytes
+dpth8lp:
+ // Do first set of 4 bytes
+ movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes
+ punpcklbw mm1, mm0 // Unpack Low bytes of a
+ movq mm2, [esi + ebx] // load b=Prior(x)
+ punpcklbw mm2, mm0 // Unpack Low bytes of b
+ // pav = p - a = (a + b - c) - a = b - c
+ movq mm4, mm2
+ punpcklbw mm3, mm0 // Unpack Low bytes of c
+ // pbv = p - b = (a + b - c) - b = a - c
+ movq mm5, mm1
+ psubw mm4, mm3
+ pxor mm7, mm7
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ movq mm6, mm4
+ psubw mm5, mm3
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ pcmpgtw mm0, mm4 // Create tqmask pav bytes < 0
+ paddw mm6, mm5
+ pand mm0, mm4 // Only pav bytes < 0 in mm7
+ pcmpgtw mm7, mm5 // Create tqmask pbv bytes < 0
+ psubw mm4, mm0
+ pand mm7, mm5 // Only pbv bytes < 0 in mm0
+ psubw mm4, mm0
+ psubw mm5, mm7
+ pxor mm0, mm0
+ pcmpgtw mm0, mm6 // Create tqmask pcv bytes < 0
+ pand mm0, mm6 // Only pav bytes < 0 in mm7
+ psubw mm5, mm7
+ psubw mm6, mm0
+ // test pa <= pb
+ movq mm7, mm4
+ psubw mm6, mm0
+ pcmpgtw mm7, mm5 // pa > pb?
+ movq mm0, mm7
+ // use mm7 tqmask to merge pa & pb
+ pand mm5, mm7
+ // use mm0 tqmask copy to merge a & b
+ pand mm2, mm0
+ pandn mm7, mm4
+ pandn mm0, mm1
+ paddw mm7, mm5
+ paddw mm0, mm2
+ // test ((pa <= pb)? pa:pb) <= pc
+ pcmpgtw mm7, mm6 // pab > pc?
+ pxor mm1, mm1
+ pand mm3, mm7
+ pandn mm7, mm0
+ paddw mm7, mm3
+ pxor mm0, mm0
+ packuswb mm7, mm1
+ movq mm3, [esi+ebx-8] // read c=Prior(x-bpp) bytes
+ pand mm7, ActiveMask
+ movq mm2, [esi + ebx] // load b=Prior(x)
+ paddb mm7, [edi + ebx] // add Paeth predictor with Raw(x)
+ punpckhbw mm3, mm0 // Unpack High bytes of c
+ movq [edi + ebx], mm7 // write back updated value
+ movq mm1, [edi+ebx-8] // read a=Raw(x-bpp) bytes
+
+ // Do second set of 4 bytes
+ punpckhbw mm2, mm0 // Unpack High bytes of b
+ punpckhbw mm1, mm0 // Unpack High bytes of a
+ // pav = p - a = (a + b - c) - a = b - c
+ movq mm4, mm2
+ // pbv = p - b = (a + b - c) - b = a - c
+ movq mm5, mm1
+ psubw mm4, mm3
+ pxor mm7, mm7
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ movq mm6, mm4
+ psubw mm5, mm3
+ // pa = abs(p-a) = abs(pav)
+ // pb = abs(p-b) = abs(pbv)
+ // pc = abs(p-c) = abs(pcv)
+ pcmpgtw mm0, mm4 // Create tqmask pav bytes < 0
+ paddw mm6, mm5
+ pand mm0, mm4 // Only pav bytes < 0 in mm7
+ pcmpgtw mm7, mm5 // Create tqmask pbv bytes < 0
+ psubw mm4, mm0
+ pand mm7, mm5 // Only pbv bytes < 0 in mm0
+ psubw mm4, mm0
+ psubw mm5, mm7
+ pxor mm0, mm0
+ pcmpgtw mm0, mm6 // Create tqmask pcv bytes < 0
+ pand mm0, mm6 // Only pav bytes < 0 in mm7
+ psubw mm5, mm7
+ psubw mm6, mm0
+ // test pa <= pb
+ movq mm7, mm4
+ psubw mm6, mm0
+ pcmpgtw mm7, mm5 // pa > pb?
+ movq mm0, mm7
+ // use mm7 tqmask to merge pa & pb
+ pand mm5, mm7
+ // use mm0 tqmask copy to merge a & b
+ pand mm2, mm0
+ pandn mm7, mm4
+ pandn mm0, mm1
+ paddw mm7, mm5
+ paddw mm0, mm2
+ // test ((pa <= pb)? pa:pb) <= pc
+ pcmpgtw mm7, mm6 // pab > pc?
+ pxor mm1, mm1
+ pand mm3, mm7
+ pandn mm7, mm0
+ pxor mm1, mm1
+ paddw mm7, mm3
+ pxor mm0, mm0
+ // Step ex to next set of 8 bytes and repeat loop til done
+ add ebx, 8
+ packuswb mm1, mm7
+ paddb mm1, [edi + ebx - 8] // add Paeth predictor with Raw(x)
+ cmp ebx, MMXLength
+ movq [edi + ebx - 8], mm1 // write back updated value
+ // mm1 will be used as Raw(x-bpp) next loop
+ jb dpth8lp
+ } // end _asm block
+ }
+ break;
+
+ case 1: // bpp = 1
+ case 2: // bpp = 2
+ default: // bpp > 8
+ {
+ _asm {
+ mov ebx, diff
+ cmp ebx, FullLength
+ jnb dpthdend
+ mov edi, row
+ mov esi, prev_row
+ // Do Paeth decode for remaining bytes
+ mov edx, ebx
+ xor ecx, ecx // zero ecx before using cl & cx in loop below
+ sub edx, bpp // Set edx = ebx - bpp
+dpthdlp:
+ xor eax, eax
+ // pav = p - a = (a + b - c) - a = b - c
+ mov al, [esi + ebx] // load Prior(x) into al
+ mov cl, [esi + edx] // load Prior(x-bpp) into cl
+ sub eax, ecx // subtract Prior(x-bpp)
+ mov patemp, eax // Save pav for later use
+ xor eax, eax
+ // pbv = p - b = (a + b - c) - b = a - c
+ mov al, [edi + edx] // load Raw(x-bpp) into al
+ sub eax, ecx // subtract Prior(x-bpp)
+ mov ecx, eax
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ add eax, patemp // pcv = pav + pbv
+ // pc = abs(pcv)
+ test eax, 0x80000000
+ jz dpthdpca
+ neg eax // reverse sign of neg values
+dpthdpca:
+ mov pctemp, eax // save pc for later use
+ // pb = abs(pbv)
+ test ecx, 0x80000000
+ jz dpthdpba
+ neg ecx // reverse sign of neg values
+dpthdpba:
+ mov pbtemp, ecx // save pb for later use
+ // pa = abs(pav)
+ mov eax, patemp
+ test eax, 0x80000000
+ jz dpthdpaa
+ neg eax // reverse sign of neg values
+dpthdpaa:
+ mov patemp, eax // save pa for later use
+ // test if pa <= pb
+ cmp eax, ecx
+ jna dpthdabb
+ // pa > pb; now test if pb <= pc
+ cmp ecx, pctemp
+ jna dpthdbbc
+ // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ mov cl, [esi + edx] // load Prior(x-bpp) into cl
+ jmp dpthdpaeth
+dpthdbbc:
+ // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
+ mov cl, [esi + ebx] // load Prior(x) into cl
+ jmp dpthdpaeth
+dpthdabb:
+ // pa <= pb; now test if pa <= pc
+ cmp eax, pctemp
+ jna dpthdabc
+ // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ mov cl, [esi + edx] // load Prior(x-bpp) into cl
+ jmp dpthdpaeth
+dpthdabc:
+ // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
+ mov cl, [edi + edx] // load Raw(x-bpp) into cl
+dpthdpaeth:
+ inc ebx
+ inc edx
+ // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
+ add [edi + ebx - 1], cl
+ cmp ebx, FullLength
+ jb dpthdlp
+dpthdend:
+ } // end _asm block
+ }
+ return; // No need to go further with this one
+ } // end switch ( bpp )
+ _asm
+ {
+ // MMX acceleration complete now do clean-up
+ // Check if any remaining bytes left to decode
+ mov ebx, MMXLength
+ cmp ebx, FullLength
+ jnb dpthend
+ mov edi, row
+ mov esi, prev_row
+ // Do Paeth decode for remaining bytes
+ mov edx, ebx
+ xor ecx, ecx // zero ecx before using cl & cx in loop below
+ sub edx, bpp // Set edx = ebx - bpp
+dpthlp2:
+ xor eax, eax
+ // pav = p - a = (a + b - c) - a = b - c
+ mov al, [esi + ebx] // load Prior(x) into al
+ mov cl, [esi + edx] // load Prior(x-bpp) into cl
+ sub eax, ecx // subtract Prior(x-bpp)
+ mov patemp, eax // Save pav for later use
+ xor eax, eax
+ // pbv = p - b = (a + b - c) - b = a - c
+ mov al, [edi + edx] // load Raw(x-bpp) into al
+ sub eax, ecx // subtract Prior(x-bpp)
+ mov ecx, eax
+ // pcv = p - c = (a + b - c) -c = (a - c) + (b - c) = pav + pbv
+ add eax, patemp // pcv = pav + pbv
+ // pc = abs(pcv)
+ test eax, 0x80000000
+ jz dpthpca2
+ neg eax // reverse sign of neg values
+dpthpca2:
+ mov pctemp, eax // save pc for later use
+ // pb = abs(pbv)
+ test ecx, 0x80000000
+ jz dpthpba2
+ neg ecx // reverse sign of neg values
+dpthpba2:
+ mov pbtemp, ecx // save pb for later use
+ // pa = abs(pav)
+ mov eax, patemp
+ test eax, 0x80000000
+ jz dpthpaa2
+ neg eax // reverse sign of neg values
+dpthpaa2:
+ mov patemp, eax // save pa for later use
+ // test if pa <= pb
+ cmp eax, ecx
+ jna dpthabb2
+ // pa > pb; now test if pb <= pc
+ cmp ecx, pctemp
+ jna dpthbbc2
+ // pb > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ mov cl, [esi + edx] // load Prior(x-bpp) into cl
+ jmp dpthpaeth2
+dpthbbc2:
+ // pb <= pc; Raw(x) = Paeth(x) + Prior(x)
+ mov cl, [esi + ebx] // load Prior(x) into cl
+ jmp dpthpaeth2
+dpthabb2:
+ // pa <= pb; now test if pa <= pc
+ cmp eax, pctemp
+ jna dpthabc2
+ // pa > pc; Raw(x) = Paeth(x) + Prior(x-bpp)
+ mov cl, [esi + edx] // load Prior(x-bpp) into cl
+ jmp dpthpaeth2
+dpthabc2:
+ // pa <= pc; Raw(x) = Paeth(x) + Raw(x-bpp)
+ mov cl, [edi + edx] // load Raw(x-bpp) into cl
+dpthpaeth2:
+ inc ebx
+ inc edx
+ // Raw(x) = (Paeth(x) + Paeth_Predictor( a, b, c )) mod 256
+ add [edi + ebx - 1], cl
+ cmp ebx, FullLength
+ jb dpthlp2
+dpthend:
+ emms // End MMX instructions; prep for possible FP instrs.
+ } // end _asm block
+}
+
+// Optimized code for PNG Sub filter decoder
+void /* PRIVATE */
+png_read_filter_row_mmx_sub(png_row_infop row_info, png_bytep row)
+{
+ //int test;
+ int bpp;
+ png_uint_32 FullLength;
+ png_uint_32 MMXLength;
+ int diff;
+
+ bpp = (row_info->pixel_depth + 7) >> 3; // Get # bytes per pixel
+ FullLength = row_info->rowbytes - bpp; // # of bytes to filter
+ _asm {
+ mov edi, row
+ mov esi, edi // lp = row
+ add edi, bpp // rp = row + bpp
+ xor eax, eax
+ // get # of bytes to tqalignment
+ mov diff, edi // take start of row
+ add diff, 0xf // add 7 + 8 to incr past
+ // tqalignment boundary
+ xor ebx, ebx
+ and diff, 0xfffffff8 // tqmask to tqalignment boundary
+ sub diff, edi // subtract from start ==> value
+ // ebx at tqalignment
+ jz dsubgo
+ // fix tqalignment
+dsublp1:
+ mov al, [esi+ebx]
+ add [edi+ebx], al
+ inc ebx
+ cmp ebx, diff
+ jb dsublp1
+dsubgo:
+ mov ecx, FullLength
+ mov edx, ecx
+ sub edx, ebx // subtract tqalignment fix
+ and edx, 0x00000007 // calc bytes over mult of 8
+ sub ecx, edx // drop over bytes from length
+ mov MMXLength, ecx
+ } // end _asm block
+
+ // Now do the math for the rest of the row
+ switch ( bpp )
+ {
+ case 3:
+ {
+ ActiveMask.use = 0x0000ffffff000000;
+ ShiftBpp.use = 24; // == 3 * 8
+ ShiftRem.use = 40; // == 64 - 24
+ _asm {
+ mov edi, row
+ movq mm7, ActiveMask // Load ActiveMask for 2nd active byte group
+ mov esi, edi // lp = row
+ add edi, bpp // rp = row + bpp
+ movq mm6, mm7
+ mov ebx, diff
+ psllq mm6, ShiftBpp // Move tqmask in mm6 to cover 3rd active
+ // byte group
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm1, [edi+ebx-8]
+dsub3lp:
+ psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes
+ // no need for tqmask; shift clears inactive bytes
+ // Add 1st active group
+ movq mm0, [edi+ebx]
+ paddb mm0, mm1
+ // Add 2nd active group
+ movq mm1, mm0 // mov updated Raws to mm1
+ psllq mm1, ShiftBpp // shift data to position correctly
+ pand mm1, mm7 // tqmask to use only 2nd active group
+ paddb mm0, mm1
+ // Add 3rd active group
+ movq mm1, mm0 // mov updated Raws to mm1
+ psllq mm1, ShiftBpp // shift data to position correctly
+ pand mm1, mm6 // tqmask to use only 3rd active group
+ add ebx, 8
+ paddb mm0, mm1
+ cmp ebx, MMXLength
+ movq [edi+ebx-8], mm0 // Write updated Raws back to array
+ // Prep for doing 1st add at top of loop
+ movq mm1, mm0
+ jb dsub3lp
+ } // end _asm block
+ }
+ break;
+
+ case 1:
+ {
+ // Placed here just in case this is a duplicate of the
+ // non-MMX code for the SUB filter in png_read_filter_row below
+ //
+ // png_bytep rp;
+ // png_bytep lp;
+ // png_uint_32 i;
+ // bpp = (row_info->pixel_depth + 7) >> 3;
+ // for (i = (png_uint_32)bpp, rp = row + bpp, lp = row;
+ // i < row_info->rowbytes; i++, rp++, lp++)
+ // {
+ // *rp = (png_byte)(((int)(*rp) + (int)(*lp)) & 0xff);
+ // }
+ _asm {
+ mov ebx, diff
+ mov edi, row
+ cmp ebx, FullLength
+ jnb dsub1end
+ mov esi, edi // lp = row
+ xor eax, eax
+ add edi, bpp // rp = row + bpp
+dsub1lp:
+ mov al, [esi+ebx]
+ add [edi+ebx], al
+ inc ebx
+ cmp ebx, FullLength
+ jb dsub1lp
+dsub1end:
+ } // end _asm block
+ }
+ return;
+
+ case 6:
+ case 7:
+ case 4:
+ case 5:
+ {
+ ShiftBpp.use = bpp << 3;
+ ShiftRem.use = 64 - ShiftBpp.use;
+ _asm {
+ mov edi, row
+ mov ebx, diff
+ mov esi, edi // lp = row
+ add edi, bpp // rp = row + bpp
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm1, [edi+ebx-8]
+dsub4lp:
+ psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes
+ // no need for tqmask; shift clears inactive bytes
+ movq mm0, [edi+ebx]
+ paddb mm0, mm1
+ // Add 2nd active group
+ movq mm1, mm0 // mov updated Raws to mm1
+ psllq mm1, ShiftBpp // shift data to position correctly
+ // there is no need for any tqmask
+ // since shift clears inactive bits/bytes
+ add ebx, 8
+ paddb mm0, mm1
+ cmp ebx, MMXLength
+ movq [edi+ebx-8], mm0
+ movq mm1, mm0 // Prep for doing 1st add at top of loop
+ jb dsub4lp
+ } // end _asm block
+ }
+ break;
+
+ case 2:
+ {
+ ActiveMask.use = 0x00000000ffff0000;
+ ShiftBpp.use = 16; // == 2 * 8
+ ShiftRem.use = 48; // == 64 - 16
+ _asm {
+ movq mm7, ActiveMask // Load ActiveMask for 2nd active byte group
+ mov ebx, diff
+ movq mm6, mm7
+ mov edi, row
+ psllq mm6, ShiftBpp // Move tqmask in mm6 to cover 3rd active
+ // byte group
+ mov esi, edi // lp = row
+ movq mm5, mm6
+ add edi, bpp // rp = row + bpp
+ psllq mm5, ShiftBpp // Move tqmask in mm5 to cover 4th active
+ // byte group
+ // PRIME the pump (load the first Raw(x-bpp) data set
+ movq mm1, [edi+ebx-8]
+dsub2lp:
+ // Add 1st active group
+ psrlq mm1, ShiftRem // Shift data for adding 1st bpp bytes
+ // no need for tqmask; shift clears inactive
+ // bytes
+ movq mm0, [edi+ebx]
+ paddb mm0, mm1
+ // Add 2nd active group
+ movq mm1, mm0 // mov updated Raws to mm1
+ psllq mm1, ShiftBpp // shift data to position correctly
+ pand mm1, mm7 // tqmask to use only 2nd active group
+ paddb mm0, mm1
+ // Add 3rd active group
+ movq mm1, mm0 // mov updated Raws to mm1
+ psllq mm1, ShiftBpp // shift data to position correctly
+ pand mm1, mm6 // tqmask to use only 3rd active group
+ paddb mm0, mm1
+ // Add 4th active group
+ movq mm1, mm0 // mov updated Raws to mm1
+ psllq mm1, ShiftBpp // shift data to position correctly
+ pand mm1, mm5 // tqmask to use only 4th active group
+ add ebx, 8
+ paddb mm0, mm1
+ cmp ebx, MMXLength
+ movq [edi+ebx-8], mm0 // Write updated Raws back to array
+ movq mm1, mm0 // Prep for doing 1st add at top of loop
+ jb dsub2lp
+ } // end _asm block
+ }
+ break;
+ case 8:
+ {
+ _asm {
+ mov edi, row
+ mov ebx, diff
+ mov esi, edi // lp = row
+ add edi, bpp // rp = row + bpp
+ mov ecx, MMXLength
+ movq mm7, [edi+ebx-8] // PRIME the pump (load the first
+ // Raw(x-bpp) data set
+ and ecx, 0x0000003f // calc bytes over mult of 64
+dsub8lp:
+ movq mm0, [edi+ebx] // Load Sub(x) for 1st 8 bytes
+ paddb mm0, mm7
+ movq mm1, [edi+ebx+8] // Load Sub(x) for 2nd 8 bytes
+ movq [edi+ebx], mm0 // Write Raw(x) for 1st 8 bytes
+ // Now mm0 will be used as Raw(x-bpp) for
+ // the 2nd group of 8 bytes. This will be
+ // repeated for each group of 8 bytes with
+ // the 8th group being used as the Raw(x-bpp)
+ // for the 1st group of the next loop.
+ paddb mm1, mm0
+ movq mm2, [edi+ebx+16] // Load Sub(x) for 3rd 8 bytes
+ movq [edi+ebx+8], mm1 // Write Raw(x) for 2nd 8 bytes
+ paddb mm2, mm1
+ movq mm3, [edi+ebx+24] // Load Sub(x) for 4th 8 bytes
+ movq [edi+ebx+16], mm2 // Write Raw(x) for 3rd 8 bytes
+ paddb mm3, mm2
+ movq mm4, [edi+ebx+32] // Load Sub(x) for 5th 8 bytes
+ movq [edi+ebx+24], mm3 // Write Raw(x) for 4th 8 bytes
+ paddb mm4, mm3
+ movq mm5, [edi+ebx+40] // Load Sub(x) for 6th 8 bytes
+ movq [edi+ebx+32], mm4 // Write Raw(x) for 5th 8 bytes
+ paddb mm5, mm4
+ movq mm6, [edi+ebx+48] // Load Sub(x) for 7th 8 bytes
+ movq [edi+ebx+40], mm5 // Write Raw(x) for 6th 8 bytes
+ paddb mm6, mm5
+ movq mm7, [edi+ebx+56] // Load Sub(x) for 8th 8 bytes
+ movq [edi+ebx+48], mm6 // Write Raw(x) for 7th 8 bytes
+ add ebx, 64
+ paddb mm7, mm6
+ cmp ebx, ecx
+ movq [edi+ebx-8], mm7 // Write Raw(x) for 8th 8 bytes
+ jb dsub8lp
+ cmp ebx, MMXLength
+ jnb dsub8lt8
+dsub8lpA:
+ movq mm0, [edi+ebx]
+ add ebx, 8
+ paddb mm0, mm7
+ cmp ebx, MMXLength
+ movq [edi+ebx-8], mm0 // use -8 to offset early add to ebx
+ movq mm7, mm0 // Move calculated Raw(x) data to mm1 to
+ // be the new Raw(x-bpp) for the next loop
+ jb dsub8lpA
+dsub8lt8:
+ } // end _asm block
+ }
+ break;
+
+ default: // bpp greater than 8 bytes
+ {
+ _asm {
+ mov ebx, diff
+ mov edi, row
+ mov esi, edi // lp = row
+ add edi, bpp // rp = row + bpp
+dsubAlp:
+ movq mm0, [edi+ebx]
+ movq mm1, [esi+ebx]
+ add ebx, 8
+ paddb mm0, mm1
+ cmp ebx, MMXLength
+ movq [edi+ebx-8], mm0 // mov does not affect flags; -8 to offset
+ // add ebx
+ jb dsubAlp
+ } // end _asm block
+ }
+ break;
+
+ } // end switch ( bpp )
+
+ _asm {
+ mov ebx, MMXLength
+ mov edi, row
+ cmp ebx, FullLength
+ jnb dsubend
+ mov esi, edi // lp = row
+ xor eax, eax
+ add edi, bpp // rp = row + bpp
+dsublp2:
+ mov al, [esi+ebx]
+ add [edi+ebx], al
+ inc ebx
+ cmp ebx, FullLength
+ jb dsublp2
+dsubend:
+ emms // End MMX instructions; prep for possible FP instrs.
+ } // end _asm block
+}
+
+// Optimized code for PNG Up filter decoder
+void /* PRIVATE */
+png_read_filter_row_mmx_up(png_row_infop row_info, png_bytep row,
+ png_bytep prev_row)
+{
+ png_uint_32 len;
+ len = row_info->rowbytes; // # of bytes to filter
+ _asm {
+ mov edi, row
+ // get # of bytes to tqalignment
+ mov ecx, edi
+ xor ebx, ebx
+ add ecx, 0x7
+ xor eax, eax
+ and ecx, 0xfffffff8
+ mov esi, prev_row
+ sub ecx, edi
+ jz dupgo
+ // fix tqalignment
+duplp1:
+ mov al, [edi+ebx]
+ add al, [esi+ebx]
+ inc ebx
+ cmp ebx, ecx
+ mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx
+ jb duplp1
+dupgo:
+ mov ecx, len
+ mov edx, ecx
+ sub edx, ebx // subtract tqalignment fix
+ and edx, 0x0000003f // calc bytes over mult of 64
+ sub ecx, edx // drop over bytes from length
+ // Unrolled loop - use all MMX registers and interleave to reduce
+ // number of branch instructions (loops) and reduce partial stalls
+duploop:
+ movq mm1, [esi+ebx]
+ movq mm0, [edi+ebx]
+ movq mm3, [esi+ebx+8]
+ paddb mm0, mm1
+ movq mm2, [edi+ebx+8]
+ movq [edi+ebx], mm0
+ paddb mm2, mm3
+ movq mm5, [esi+ebx+16]
+ movq [edi+ebx+8], mm2
+ movq mm4, [edi+ebx+16]
+ movq mm7, [esi+ebx+24]
+ paddb mm4, mm5
+ movq mm6, [edi+ebx+24]
+ movq [edi+ebx+16], mm4
+ paddb mm6, mm7
+ movq mm1, [esi+ebx+32]
+ movq [edi+ebx+24], mm6
+ movq mm0, [edi+ebx+32]
+ movq mm3, [esi+ebx+40]
+ paddb mm0, mm1
+ movq mm2, [edi+ebx+40]
+ movq [edi+ebx+32], mm0
+ paddb mm2, mm3
+ movq mm5, [esi+ebx+48]
+ movq [edi+ebx+40], mm2
+ movq mm4, [edi+ebx+48]
+ movq mm7, [esi+ebx+56]
+ paddb mm4, mm5
+ movq mm6, [edi+ebx+56]
+ movq [edi+ebx+48], mm4
+ add ebx, 64
+ paddb mm6, mm7
+ cmp ebx, ecx
+ movq [edi+ebx-8], mm6 // (+56)movq does not affect flags;
+ // -8 to offset add ebx
+ jb duploop
+
+ cmp edx, 0 // Test for bytes over mult of 64
+ jz dupend
+
+
+ // 2 lines added by lcreeve@netins.net
+ // (mail 11 Jul 98 in png-implement list)
+ cmp edx, 8 //test for less than 8 bytes
+ jb duplt8
+
+
+ add ecx, edx
+ and edx, 0x00000007 // calc bytes over mult of 8
+ sub ecx, edx // drop over bytes from length
+ jz duplt8
+ // Loop using MMX registers mm0 & mm1 to update 8 bytes simultaneously
+duplpA:
+ movq mm1, [esi+ebx]
+ movq mm0, [edi+ebx]
+ add ebx, 8
+ paddb mm0, mm1
+ cmp ebx, ecx
+ movq [edi+ebx-8], mm0 // movq does not affect flags; -8 to offset add ebx
+ jb duplpA
+ cmp edx, 0 // Test for bytes over mult of 8
+ jz dupend
+duplt8:
+ xor eax, eax
+ add ecx, edx // move over byte count into counter
+ // Loop using x86 registers to update remaining bytes
+duplp2:
+ mov al, [edi + ebx]
+ add al, [esi + ebx]
+ inc ebx
+ cmp ebx, ecx
+ mov [edi + ebx-1], al // mov does not affect flags; -1 to offset inc ebx
+ jb duplp2
+dupend:
+ // Conversion of filtered row completed
+ emms // End MMX instructions; prep for possible FP instrs.
+ } // end _asm block
+}
+
+
+// Optimized png_read_filter_row routines
+void /* PRIVATE */
+png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
+ row, png_bytep prev_row, int filter)
+{
+#ifdef PNG_DEBUG
+ char filnm[10];
+#endif
+
+ if (mmx_supported == 2) {
+ /* this should have happened in png_init_mmx_flags() already */
+ png_warning(png_ptr, "asm_flags may not have been initialized");
+ png_mmx_support();
+ }
+
+#ifdef PNG_DEBUG
+ png_debug(1, "in png_read_filter_row\n");
+ switch (filter)
+ {
+ case 0: sprintf(filnm, "none");
+ break;
+ case 1: sprintf(filnm, "sub-%s",
+ (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB)? "MMX" : "x86");
+ break;
+ case 2: sprintf(filnm, "up-%s",
+ (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP)? "MMX" : "x86");
+ break;
+ case 3: sprintf(filnm, "avg-%s",
+ (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG)? "MMX" : "x86");
+ break;
+ case 4: sprintf(filnm, "Paeth-%s",
+ (png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH)? "MMX":"x86");
+ break;
+ default: sprintf(filnm, "unknw");
+ break;
+ }
+ png_debug2(0,"row=%5d, %s, ", png_ptr->row_number, filnm);
+ png_debug2(0, "pd=%2d, b=%d, ", (int)row_info->pixel_depth,
+ (int)((row_info->pixel_depth + 7) >> 3));
+ png_debug1(0,"len=%8d, ", row_info->rowbytes);
+#endif /* PNG_DEBUG */
+
+ switch (filter)
+ {
+ case PNG_FILTER_VALUE_NONE:
+ break;
+
+ case PNG_FILTER_VALUE_SUB:
+ {
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_SUB) &&
+ (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
+ (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
+ {
+ png_read_filter_row_mmx_sub(row_info, row);
+ }
+ else
+ {
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_bytep rp = row + bpp;
+ png_bytep lp = row;
+
+ for (i = bpp; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
+ rp++;
+ }
+ }
+ break;
+ }
+
+ case PNG_FILTER_VALUE_UP:
+ {
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_UP) &&
+ (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
+ (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
+ {
+ png_read_filter_row_mmx_up(row_info, row, prev_row);
+ }
+ else
+ {
+ png_uint_32 i;
+ png_uint_32 istop = row_info->rowbytes;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+
+ for (i = 0; i < istop; ++i)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+ }
+ break;
+ }
+
+ case PNG_FILTER_VALUE_AVG:
+ {
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_AVG) &&
+ (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
+ (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
+ {
+ png_read_filter_row_mmx_avg(row_info, row, prev_row);
+ }
+ else
+ {
+ png_uint_32 i;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+ png_bytep lp = row;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_uint_32 istop = row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++) >> 1)) & 0xff);
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) +
+ ((int)(*pp++ + *lp++) >> 1)) & 0xff);
+ rp++;
+ }
+ }
+ break;
+ }
+
+ case PNG_FILTER_VALUE_PAETH:
+ {
+ if ((png_ptr->asm_flags & PNG_ASM_FLAG_MMX_READ_FILTER_PAETH) &&
+ (row_info->pixel_depth >= png_ptr->mmx_bitdepth_threshold) &&
+ (row_info->rowbytes >= png_ptr->mmx_rowbytes_threshold))
+ {
+ png_read_filter_row_mmx_paeth(row_info, row, prev_row);
+ }
+ else
+ {
+ png_uint_32 i;
+ png_bytep rp = row;
+ png_bytep pp = prev_row;
+ png_bytep lp = row;
+ png_bytep cp = prev_row;
+ png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+ png_uint_32 istop=row_info->rowbytes - bpp;
+
+ for (i = 0; i < bpp; i++)
+ {
+ *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
+ rp++;
+ }
+
+ for (i = 0; i < istop; i++) // use leftover rp,pp
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ a = *lp++;
+ b = *pp++;
+ c = *cp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ /*
+ if (pa <= pb && pa <= pc)
+ p = a;
+ else if (pb <= pc)
+ p = b;
+ else
+ p = c;
+ */
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ *rp = (png_byte)(((int)(*rp) + p) & 0xff);
+ rp++;
+ }
+ }
+ break;
+ }
+
+ default:
+ png_warning(png_ptr, "Ignoring bad row filter type");
+ *row=0;
+ break;
+ }
+}
+
+#endif /* PNG_ASSEMBLER_CODE_SUPPORTED && PNG_USE_PNGVCRD */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngwio.c b/tqtinterface/qt4/src/3rdparty/libpng/pngwio.c
new file mode 100644
index 0000000..dc37d37
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngwio.c
@@ -0,0 +1,228 @@
+
+/* pngwio.c - functions for data output
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ *
+ * This file provides a location for all output. Users who need
+ * special handling are expected to write functions that have the same
+ * arguments as these and perform similar functions, but that possibly
+ * use different output methods. Note that you shouldn't change these
+ * functions, but rather write tqreplacement functions and then change
+ * them at run time with png_set_write_fn(...).
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Write the data to whatever output you are using. The default routine
+ writes to a file pointer. Note that this routine sometimes gets called
+ with very small lengths, so you should implement some kind of simple
+ buffering if you are using unbuffered writes. This should never be asked
+ to write more than 64K on a 16 bit machine. */
+
+void /* PRIVATE */
+png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ if (png_ptr->write_data_fn != NULL )
+ (*(png_ptr->write_data_fn))(png_ptr, data, length);
+ else
+ png_error(png_ptr, "Call to NULL write function");
+}
+
+#if !defined(PNG_NO_STDIO)
+/* This is the function that does the actual writing of data. If you are
+ not writing to a standard C stream, you should create a tqreplacement
+ write_data function and use it at run time with png_set_write_fn(), rather
+ than changing the library. */
+#ifndef USE_FAR_KEYWORD
+void PNGAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_uint_32 check;
+
+#if defined(_WIN32_WCE)
+ if ( !WriteFile((HANDLE)(png_ptr->io_ptr), data, length, &check, NULL) )
+ check = 0;
+#else
+ check = fwrite(data, 1, length, (png_FILE_p)(png_ptr->io_ptr));
+#endif
+ if (check != length)
+ png_error(png_ptr, "Write Error");
+}
+#else
+/* this is the model-independent version. Since the standard I/O library
+ can't handle far buffers in the medium and small models, we have to copy
+ the data.
+*/
+
+#define NEAR_BUF_SIZE 1024
+#define MIN(a,b) (a <= b ? a : b)
+
+void PNGAPI
+png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ png_uint_32 check;
+ png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
+ png_FILE_p io_ptr;
+
+ /* Check if data really is near. If so, use usual code. */
+ near_data = (png_byte *)CVT_PTR_NOCHECK(data);
+ io_ptr = (png_FILE_p)CVT_PTR(png_ptr->io_ptr);
+ if ((png_bytep)near_data == data)
+ {
+#if defined(_WIN32_WCE)
+ if ( !WriteFile(io_ptr, near_data, length, &check, NULL) )
+ check = 0;
+#else
+ check = fwrite(near_data, 1, length, io_ptr);
+#endif
+ }
+ else
+ {
+ png_byte buf[NEAR_BUF_SIZE];
+ png_size_t written, remaining, err;
+ check = 0;
+ remaining = length;
+ do
+ {
+ written = MIN(NEAR_BUF_SIZE, remaining);
+ png_memcpy(buf, data, written); /* copy far buffer to near buffer */
+#if defined(_WIN32_WCE)
+ if ( !WriteFile(io_ptr, buf, written, &err, NULL) )
+ err = 0;
+#else
+ err = fwrite(buf, 1, written, io_ptr);
+#endif
+ if (err != written)
+ break;
+ else
+ check += err;
+ data += written;
+ remaining -= written;
+ }
+ while (remaining != 0);
+ }
+ if (check != length)
+ png_error(png_ptr, "Write Error");
+}
+
+#endif
+#endif
+
+/* This function is called to output any data pending writing (normally
+ to disk). After png_flush is called, there should be no data pending
+ writing in any buffers. */
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+void /* PRIVATE */
+png_flush(png_structp png_ptr)
+{
+ if (png_ptr->output_flush_fn != NULL)
+ (*(png_ptr->output_flush_fn))(png_ptr);
+}
+
+#if !defined(PNG_NO_STDIO)
+void PNGAPI
+png_default_flush(png_structp png_ptr)
+{
+#if !defined(_WIN32_WCE)
+ png_FILE_p io_ptr;
+ io_ptr = (png_FILE_p)CVT_PTR((png_ptr->io_ptr));
+ if (io_ptr != NULL)
+ fflush(io_ptr);
+#endif
+}
+#endif
+#endif
+
+/* This function allows the application to supply new output functions for
+ libpng if standard C streams aren't being used.
+
+ This function takes as its arguments:
+ png_ptr - pointer to a png output data structure
+ io_ptr - pointer to user supplied structure containing info about
+ the output functions. May be NULL.
+ write_data_fn - pointer to a new output function that takes as its
+ arguments a pointer to a png_struct, a pointer to
+ data to be written, and a 32-bit unsigned int that is
+ the number of bytes to be written. The new write
+ function should call png_error(png_ptr, "Error msg")
+ to exit and output any fatal error messages.
+ flush_data_fn - pointer to a new flush function that takes as its
+ arguments a pointer to a png_struct. After a call to
+ the flush function, there should be no data in any buffers
+ or pending transmission. If the output method doesn't do
+ any buffering of ouput, a function prototype must still be
+ supplied although it doesn't have to do anything. If
+ PNG_WRITE_FLUSH_SUPPORTED is not defined at libpng compile
+ time, output_flush_fn will be ignored, although it must be
+ supplied for compatibility. */
+void PNGAPI
+png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
+ png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
+{
+ png_ptr->io_ptr = io_ptr;
+
+#if !defined(PNG_NO_STDIO)
+ if (write_data_fn != NULL)
+ png_ptr->write_data_fn = write_data_fn;
+ else
+ png_ptr->write_data_fn = png_default_write_data;
+#else
+ png_ptr->write_data_fn = write_data_fn;
+#endif
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+#if !defined(PNG_NO_STDIO)
+ if (output_flush_fn != NULL)
+ png_ptr->output_flush_fn = output_flush_fn;
+ else
+ png_ptr->output_flush_fn = png_default_flush;
+#else
+ png_ptr->output_flush_fn = output_flush_fn;
+#endif
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+ /* It is an error to read while writing a png file */
+ if (png_ptr->read_data_fn != NULL)
+ {
+ png_ptr->read_data_fn = NULL;
+ png_warning(png_ptr,
+ "Attempted to set both read_data_fn and write_data_fn in");
+ png_warning(png_ptr,
+ "the same structure. Resetting read_data_fn to NULL.");
+ }
+}
+
+#if defined(USE_FAR_KEYWORD)
+#if defined(_MSC_VER)
+void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
+{
+ void *near_ptr;
+ void FAR *far_ptr;
+ FP_OFF(near_ptr) = FP_OFF(ptr);
+ far_ptr = (void FAR *)near_ptr;
+ if(check != 0)
+ if(FP_SEG(ptr) != FP_SEG(far_ptr))
+ png_error(png_ptr,"segment lost in conversion");
+ return(near_ptr);
+}
+# else
+void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
+{
+ void *near_ptr;
+ void FAR *far_ptr;
+ near_ptr = (void FAR *)ptr;
+ far_ptr = (void FAR *)near_ptr;
+ if(check != 0)
+ if(far_ptr != ptr)
+ png_error(png_ptr,"segment lost in conversion");
+ return(near_ptr);
+}
+# endif
+# endif
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngwrite.c b/tqtinterface/qt4/src/3rdparty/libpng/pngwrite.c
new file mode 100644
index 0000000..f29ebf9
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngwrite.c
@@ -0,0 +1,1450 @@
+
+/* pngwrite.c - general routines to write a PNG file
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+/* get internal access to png.h */
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Writes all the PNG information. This is the suggested way to use the
+ * library. If you have a new chunk to add, make a function to write it,
+ * and put it in the correct location here. If you want the chunk written
+ * after the image data, put it in png_write_end(). I strongly encourage
+ * you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
+ * the chunk, as that will keep the code from breaking if you want to just
+ * write a plain PNG file. If you have long comments, I suggest writing
+ * them in png_write_end(), and compressing them.
+ */
+void PNGAPI
+png_write_info_before_PLTE(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_write_info_before_PLTE\n");
+ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+ {
+ png_write_sig(png_ptr); /* write PNG signature */
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ if((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE)&&(png_ptr->mng_features_permitted))
+ {
+ png_warning(png_ptr,"MNG features are not allowed in a PNG datastream\n");
+ png_ptr->mng_features_permitted=0;
+ }
+#endif
+ /* write IHDR information. */
+ png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
+ info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
+ info_ptr->filter_type,
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ info_ptr->interlace_type);
+#else
+ 0);
+#endif
+ /* the rest of these check to see if the valid field has the appropriate
+ flag set, and if it does, writes the chunk. */
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_gAMA)
+ {
+# ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_write_gAMA(png_ptr, info_ptr->gamma);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_write_gAMA_fixed(png_ptr, info_ptr->int_gamma);
+# endif
+#endif
+ }
+#endif
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_sRGB)
+ png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
+#endif
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_iCCP)
+ png_write_iCCP(png_ptr, info_ptr->iccp_name, PNG_COMPRESSION_TYPE_BASE,
+ info_ptr->iccp_profile, (int)info_ptr->iccp_proflen);
+#endif
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_sBIT)
+ png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
+#endif
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_cHRM)
+ {
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+ png_write_cHRM(png_ptr,
+ info_ptr->x_white, info_ptr->y_white,
+ info_ptr->x_red, info_ptr->y_red,
+ info_ptr->x_green, info_ptr->y_green,
+ info_ptr->x_blue, info_ptr->y_blue);
+#else
+# ifdef PNG_FIXED_POINT_SUPPORTED
+ png_write_cHRM_fixed(png_ptr,
+ info_ptr->int_x_white, info_ptr->int_y_white,
+ info_ptr->int_x_red, info_ptr->int_y_red,
+ info_ptr->int_x_green, info_ptr->int_y_green,
+ info_ptr->int_x_blue, info_ptr->int_y_blue);
+# endif
+#endif
+ }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ if (info_ptr->unknown_chunks_num)
+ {
+ png_unknown_chunk *up;
+
+ png_debug(5, "writing extra chunks\n");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ up++)
+ {
+ int keep=png_handle_as_unknown(png_ptr, up->name);
+ if (keep != HANDLE_CHUNK_NEVER &&
+ up->location && (!(up->location & PNG_HAVE_PLTE)) &&
+ ((up->name[3] & 0x20) || keep == HANDLE_CHUNK_ALWAYS ||
+ (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+ {
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+#endif
+ png_ptr->mode |= PNG_WROTE_INFO_BEFORE_PLTE;
+ }
+}
+
+void PNGAPI
+png_write_info(png_structp png_ptr, png_infop info_ptr)
+{
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+ int i;
+#endif
+
+ png_debug(1, "in png_write_info\n");
+
+ png_write_info_before_PLTE(png_ptr, info_ptr);
+
+ if (info_ptr->valid & PNG_INFO_PLTE)
+ png_write_PLTE(png_ptr, info_ptr->palette,
+ (png_uint_32)info_ptr->num_palette);
+ else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_error(png_ptr, "Valid palette required for paletted images\n");
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_tRNS)
+ {
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+ /* invert the alpha channel (in tRNS) */
+ if ((png_ptr->transformations & PNG_INVERT_ALPHA) &&
+ info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ int j;
+ for (j=0; j<(int)info_ptr->num_trans; j++)
+ info_ptr->trans[j] = (png_byte)(255 - info_ptr->trans[j]);
+ }
+#endif
+ png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
+ info_ptr->num_trans, info_ptr->color_type);
+ }
+#endif
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_bKGD)
+ png_write_bKGD(png_ptr, &(info_ptr->background), info_ptr->color_type);
+#endif
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_hIST)
+ png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
+#endif
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_oFFs)
+ png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
+ info_ptr->offset_unit_type);
+#endif
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pCAL)
+ png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
+ info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
+ info_ptr->pcal_units, info_ptr->pcal_params);
+#endif
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_sCAL)
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+ png_write_sCAL(png_ptr, (int)info_ptr->scal_unit,
+ info_ptr->scal_pixel_width, info_ptr->scal_pixel_height);
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+ png_write_sCAL_s(png_ptr, (int)info_ptr->scal_unit,
+ info_ptr->scal_s_width, info_ptr->scal_s_height);
+#else
+ png_warning(png_ptr,
+ "png_write_sCAL not supported; sCAL chunk not written.\n");
+#endif
+#endif
+#endif
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_pHYs)
+ png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
+ info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
+#endif
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_tIME)
+ {
+ png_write_tIME(png_ptr, &(info_ptr->mod_time));
+ png_ptr->mode |= PNG_WROTE_tIME;
+ }
+#endif
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+ if (info_ptr->valid & PNG_INFO_sPLT)
+ for (i = 0; i < (int)info_ptr->splt_palettes_num; i++)
+ png_write_sPLT(png_ptr, info_ptr->splt_palettes + i);
+#endif
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+ /* Check to see if we need to write text chunks */
+ for (i = 0; i < info_ptr->num_text; i++)
+ {
+ png_debug2(2, "Writing header text chunk %d, type %d\n", i,
+ info_ptr->text[i].compression);
+ /* an internationalized chunk? */
+ if (info_ptr->text[i].compression > 0)
+ {
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+ /* write international chunk */
+ png_write_iTXt(png_ptr,
+ info_ptr->text[i].compression,
+ info_ptr->text[i].key,
+ info_ptr->text[i].lang,
+ info_ptr->text[i].lang_key,
+ info_ptr->text[i].text);
+#else
+ png_warning(png_ptr, "Unable to write international text\n");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ /* If we want a compressed text chunk */
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_zTXt)
+ {
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+ /* write compressed chunk */
+ png_write_zTXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0,
+ info_ptr->text[i].compression);
+#else
+ png_warning(png_ptr, "Unable to write compressed text\n");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+ }
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+ /* write uncompressed chunk */
+ png_write_tEXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text,
+ 0);
+#else
+ png_warning(png_ptr, "Unable to write uncompressed text\n");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ if (info_ptr->unknown_chunks_num)
+ {
+ png_unknown_chunk *up;
+
+ png_debug(5, "writing extra chunks\n");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ up++)
+ {
+ int keep=png_handle_as_unknown(png_ptr, up->name);
+ if (keep != HANDLE_CHUNK_NEVER &&
+ up->location && (up->location & PNG_HAVE_PLTE) &&
+ !(up->location & PNG_HAVE_IDAT) &&
+ ((up->name[3] & 0x20) || keep == HANDLE_CHUNK_ALWAYS ||
+ (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+ {
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+#endif
+}
+
+/* Writes the end of the PNG file. If you don't want to write comments or
+ * time information, you can pass NULL for info. If you already wrote these
+ * in png_write_info(), do not write them again here. If you have long
+ * comments, I suggest writing them here, and compressing them.
+ */
+void PNGAPI
+png_write_end(png_structp png_ptr, png_infop info_ptr)
+{
+ png_debug(1, "in png_write_end\n");
+ if (!(png_ptr->mode & PNG_HAVE_IDAT))
+ png_error(png_ptr, "No IDATs written into file");
+
+ /* see if user wants us to write information chunks */
+ if (info_ptr != NULL)
+ {
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+ int i; /* local index variable */
+#endif
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+ /* check to see if user has supplied a time chunk */
+ if ((info_ptr->valid & PNG_INFO_tIME) &&
+ !(png_ptr->mode & PNG_WROTE_tIME))
+ png_write_tIME(png_ptr, &(info_ptr->mod_time));
+#endif
+#if defined(PNG_WRITE_TEXT_SUPPORTED)
+ /* loop through comment chunks */
+ for (i = 0; i < info_ptr->num_text; i++)
+ {
+ png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
+ info_ptr->text[i].compression);
+ /* an internationalized chunk? */
+ if (info_ptr->text[i].compression > 0)
+ {
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+ /* write international chunk */
+ png_write_iTXt(png_ptr,
+ info_ptr->text[i].compression,
+ info_ptr->text[i].key,
+ info_ptr->text[i].lang,
+ info_ptr->text[i].lang_key,
+ info_ptr->text[i].text);
+#else
+ png_warning(png_ptr, "Unable to write international text\n");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ else if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
+ {
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+ /* write compressed chunk */
+ png_write_zTXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0,
+ info_ptr->text[i].compression);
+#else
+ png_warning(png_ptr, "Unable to write compressed text\n");
+#endif
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
+ }
+ else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+ /* write uncompressed chunk */
+ png_write_tEXt(png_ptr, info_ptr->text[i].key,
+ info_ptr->text[i].text, 0);
+#else
+ png_warning(png_ptr, "Unable to write uncompressed text\n");
+#endif
+
+ /* Mark this chunk as written */
+ info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
+ }
+ }
+#endif
+#if defined(PNG_WRITE_UNKNOWN_CHUNKS_SUPPORTED)
+ if (info_ptr->unknown_chunks_num)
+ {
+ png_unknown_chunk *up;
+
+ png_debug(5, "writing extra chunks\n");
+
+ for (up = info_ptr->unknown_chunks;
+ up < info_ptr->unknown_chunks + info_ptr->unknown_chunks_num;
+ up++)
+ {
+ int keep=png_handle_as_unknown(png_ptr, up->name);
+ if (keep != HANDLE_CHUNK_NEVER &&
+ up->location && (up->location & PNG_AFTER_IDAT) &&
+ ((up->name[3] & 0x20) || keep == HANDLE_CHUNK_ALWAYS ||
+ (png_ptr->flags & PNG_FLAG_KEEP_UNSAFE_CHUNKS)))
+ {
+ png_write_chunk(png_ptr, up->name, up->data, up->size);
+ }
+ }
+ }
+#endif
+ }
+
+ png_ptr->mode |= PNG_AFTER_IDAT;
+
+ /* write end of PNG file */
+ png_write_IEND(png_ptr);
+#if 0
+/* This flush, added in libpng-1.0.8, causes some applications to crash
+ because they do not set png_ptr->output_flush_fn */
+ png_flush(png_ptr);
+#endif
+}
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+#if !defined(_WIN32_WCE)
+/* "time.h" functions are not supported on WindowsCE */
+void PNGAPI
+png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
+{
+ png_debug(1, "in png_convert_from_struct_tm\n");
+ ptime->year = (png_uint_16)(1900 + ttime->tm_year);
+ ptime->month = (png_byte)(ttime->tm_mon + 1);
+ ptime->day = (png_byte)ttime->tm_mday;
+ ptime->hour = (png_byte)ttime->tm_hour;
+ ptime->minute = (png_byte)ttime->tm_min;
+ ptime->second = (png_byte)ttime->tm_sec;
+}
+
+void PNGAPI
+png_convert_from_time_t(png_timep ptime, time_t ttime)
+{
+ struct tm *tbuf;
+
+ png_debug(1, "in png_convert_from_time_t\n");
+ tbuf = gmtime(&ttime);
+ png_convert_from_struct_tm(ptime, tbuf);
+}
+#endif
+#endif
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+png_structp PNGAPI
+png_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn)
+{
+#ifdef PNG_USER_MEM_SUPPORTED
+ return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
+ warn_fn, png_voidp_NULL, png_malloc_ptr_NULL, png_free_ptr_NULL));
+}
+
+/* Alternate initialize png_ptr structure, and allocate any memory needed */
+png_structp PNGAPI
+png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
+ png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
+ png_malloc_ptr malloc_fn, png_free_ptr free_fn)
+{
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_structp png_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ jmp_buf jmpbuf;
+#endif
+#endif
+ int i;
+ png_debug(1, "in png_create_write_struct\n");
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
+ (png_malloc_ptr)malloc_fn, (png_voidp)mem_ptr);
+#else
+ png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+#endif /* PNG_USER_MEM_SUPPORTED */
+ if (png_ptr == NULL)
+ return (NULL);
+
+#if !defined(PNG_1_0_X)
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+ png_init_mmx_flags(png_ptr); /* 1.2.0 addition */
+#endif
+#endif /* PNG_1_0_X */
+
+#ifdef PNG_SETJMP_SUPPORTED
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+#else
+ if (setjmp(png_ptr->jmpbuf))
+#endif
+ {
+ png_free(png_ptr, png_ptr->zbuf);
+ png_ptr->zbuf=NULL;
+ png_destroy_struct(png_ptr);
+ return (NULL);
+ }
+#ifdef USE_FAR_KEYWORD
+ png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
+#endif
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
+#endif /* PNG_USER_MEM_SUPPORTED */
+ png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
+
+ i=0;
+ do
+ {
+ if(user_png_ver[i] != png_libpng_ver[i])
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+ } while (png_libpng_ver[i++]);
+
+ if (png_ptr->flags & PNG_FLAG_LIBRARY_MISMATCH)
+ {
+ /* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
+ * we must recompile any applications that use any older library version.
+ * For versions after libpng 1.0, we will be compatible, so we need
+ * only check the first digit.
+ */
+ if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
+ (user_png_ver[0] == '1' && user_png_ver[2] != png_libpng_ver[2]) ||
+ (user_png_ver[0] == '0' && user_png_ver[2] < '9'))
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char msg[80];
+ if (user_png_ver)
+ {
+ sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ sprintf(msg, "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+#endif
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "Incompatible libpng version in application and library");
+ }
+ }
+
+ /* initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+
+ png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
+ png_flush_ptr_NULL);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+ 1, png_doublep_NULL, png_doublep_NULL);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+/* Applications that neglect to set up their own setjmp() and then encounter
+ a png_error() will longjmp here. Since the jmpbuf is then meaningless we
+ abort instead of returning. */
+#ifdef USE_FAR_KEYWORD
+ if (setjmp(jmpbuf))
+ PNG_ABORT();
+ png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
+#else
+ if (setjmp(png_ptr->jmpbuf))
+ PNG_ABORT();
+#endif
+#endif
+ return (png_ptr);
+}
+
+/* Initialize png_ptr structure, and allocate any memory needed */
+#undef png_write_init
+void PNGAPI
+png_write_init(png_structp png_ptr)
+{
+ /* We only come here via pre-1.0.7-compiled applications */
+ png_write_init_2(png_ptr, "1.0.6 or earlier", 0, 0);
+}
+
+void PNGAPI
+png_write_init_2(png_structp png_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size, png_size_t png_info_size)
+{
+ /* We only come here via pre-1.0.12-compiled applications */
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ if(sizeof(png_struct) > png_struct_size || sizeof(png_info) > png_info_size)
+ {
+ char msg[80];
+ png_ptr->warning_fn=NULL;
+ if (user_png_ver)
+ {
+ sprintf(msg, "Application was compiled with png.h from libpng-%.20s",
+ user_png_ver);
+ png_warning(png_ptr, msg);
+ }
+ sprintf(msg, "Application is running with png.c from libpng-%.20s",
+ png_libpng_ver);
+ png_warning(png_ptr, msg);
+ }
+#endif
+ if(sizeof(png_struct) > png_struct_size)
+ {
+ png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "The png struct allocated by the application for writing is too small.");
+ }
+ if(sizeof(png_info) > png_info_size)
+ {
+ png_ptr->error_fn=NULL;
+#ifdef PNG_ERROR_NUMBERS_SUPPORTED
+ png_ptr->flags=0;
+#endif
+ png_error(png_ptr,
+ "The info struct allocated by the application for writing is too small.");
+ }
+ png_write_init_3(&png_ptr, user_png_ver, png_struct_size);
+}
+
+
+void PNGAPI
+png_write_init_3(png_structpp ptr_ptr, png_const_charp user_png_ver,
+ png_size_t png_struct_size)
+{
+ png_structp png_ptr=*ptr_ptr;
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp; /* to save current jump buffer */
+#endif
+ int i = 0;
+ do
+ {
+ if (user_png_ver[i] != png_libpng_ver[i])
+ {
+#ifdef PNG_LEGACY_SUPPORTED
+ png_ptr->flags |= PNG_FLAG_LIBRARY_MISMATCH;
+#else
+ png_ptr->warning_fn=NULL;
+ png_warning(png_ptr,
+ "Application uses deprecated png_write_init() and should be recompiled.");
+ break;
+#endif
+ }
+ } while (png_libpng_ver[i++]);
+
+ png_debug(1, "in png_write_init_3\n");
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* save jump buffer and error functions */
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+#endif
+
+ if (sizeof(png_struct) > png_struct_size)
+ {
+ png_destroy_struct(png_ptr);
+ png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG);
+ *ptr_ptr = png_ptr;
+ }
+
+ /* reset all variables to 0 */
+ png_memset(png_ptr, 0, sizeof (png_struct));
+
+#if !defined(PNG_1_0_X)
+#ifdef PNG_ASSEMBLER_CODE_SUPPORTED
+ png_init_mmx_flags(png_ptr); /* 1.2.0 addition */
+#endif
+#endif /* PNG_1_0_X */
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* restore jump buffer */
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+#endif
+
+ png_set_write_fn(png_ptr, png_voidp_NULL, png_rw_ptr_NULL,
+ png_flush_ptr_NULL);
+
+ /* initialize zbuf - compression buffer */
+ png_ptr->zbuf_size = PNG_ZBUF_SIZE;
+ png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
+ 1, png_doublep_NULL, png_doublep_NULL);
+#endif
+}
+
+/* Write a few rows of image data. If the image is interlaced,
+ * either you will have to write the 7 sub images, or, if you
+ * have called png_set_interlace_handling(), you will have to
+ * "write" the image seven times.
+ */
+void PNGAPI
+png_write_rows(png_structp png_ptr, png_bytepp row,
+ png_uint_32 num_rows)
+{
+ png_uint_32 i; /* row counter */
+ png_bytepp rp; /* row pointer */
+
+ png_debug(1, "in png_write_rows\n");
+ /* loop through the rows */
+ for (i = 0, rp = row; i < num_rows; i++, rp++)
+ {
+ png_write_row(png_ptr, *rp);
+ }
+}
+
+/* Write the image. You only need to call this function once, even
+ * if you are writing an interlaced image.
+ */
+void PNGAPI
+png_write_image(png_structp png_ptr, png_bytepp image)
+{
+ png_uint_32 i; /* row index */
+ int pass, num_pass; /* pass variables */
+ png_bytepp rp; /* points to current row */
+
+ png_debug(1, "in png_write_image\n");
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ /* intialize interlace handling. If image is not interlaced,
+ this will set pass to 1 */
+ num_pass = png_set_interlace_handling(png_ptr);
+#else
+ num_pass = 1;
+#endif
+ /* loop through passes */
+ for (pass = 0; pass < num_pass; pass++)
+ {
+ /* loop through image */
+ for (i = 0, rp = image; i < png_ptr->height; i++, rp++)
+ {
+ png_write_row(png_ptr, *rp);
+ }
+ }
+}
+
+/* called by user to write a row of image data */
+void PNGAPI
+png_write_row(png_structp png_ptr, png_bytep row)
+{
+ png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
+ png_ptr->row_number, png_ptr->pass);
+ /* initialize transformations and other stuff if first time */
+ if (png_ptr->row_number == 0 && png_ptr->pass == 0)
+ {
+ /* make sure we wrote the header info */
+ if (!(png_ptr->mode & PNG_WROTE_INFO_BEFORE_PLTE))
+ png_error(png_ptr,
+ "png_write_info was never called before png_write_row.");
+
+ /* check for transforms that have been set but were defined out */
+#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
+#endif
+#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
+#endif
+
+ png_write_start_row(png_ptr);
+ }
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ /* if interlaced and not interested in row, return */
+ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
+ {
+ switch (png_ptr->pass)
+ {
+ case 0:
+ if (png_ptr->row_number & 0x07)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 1:
+ if ((png_ptr->row_number & 0x07) || png_ptr->width < 5)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 2:
+ if ((png_ptr->row_number & 0x07) != 4)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 3:
+ if ((png_ptr->row_number & 0x03) || png_ptr->width < 3)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 4:
+ if ((png_ptr->row_number & 0x03) != 2)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 5:
+ if ((png_ptr->row_number & 0x01) || png_ptr->width < 2)
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ case 6:
+ if (!(png_ptr->row_number & 0x01))
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ break;
+ }
+ }
+#endif
+
+ /* set up row info for transformations */
+ png_ptr->row_info.color_type = png_ptr->color_type;
+ png_ptr->row_info.width = png_ptr->usr_width;
+ png_ptr->row_info.channels = png_ptr->usr_channels;
+ png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
+ png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
+ png_ptr->row_info.channels);
+
+ png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
+ (png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
+
+ png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
+ png_debug1(3, "row_info->width = %lu\n", png_ptr->row_info.width);
+ png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
+ png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
+ png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
+ png_debug1(3, "row_info->rowbytes = %lu\n", png_ptr->row_info.rowbytes);
+
+ /* Copy user's row into buffer, leaving room for filter byte. */
+ png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
+ png_ptr->row_info.rowbytes);
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+ /* handle interlacing */
+ if (png_ptr->interlaced && png_ptr->pass < 6 &&
+ (png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_do_write_interlace(&(png_ptr->row_info),
+ png_ptr->row_buf + 1, png_ptr->pass);
+ /* this should always get caught above, but still ... */
+ if (!(png_ptr->row_info.width))
+ {
+ png_write_finish_row(png_ptr);
+ return;
+ }
+ }
+#endif
+
+ /* handle other transformations */
+ if (png_ptr->transformations)
+ png_do_write_transformations(png_ptr);
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ /* Write filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not write a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a tqmask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (png_ptr->filter_type == PNG_INTRAPIXEL_DIFFERENCING))
+ {
+ /* Intrapixel differencing */
+ png_do_write_intrapixel(&(png_ptr->row_info), png_ptr->row_buf + 1);
+ }
+#endif
+
+ /* Find a filter if necessary, filter the row and write it out. */
+ png_write_tqfind_filter(png_ptr, &(png_ptr->row_info));
+
+ if (png_ptr->write_row_fn != NULL)
+ (*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
+}
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+/* Set the automatic flush interval or 0 to turn flushing off */
+void PNGAPI
+png_set_flush(png_structp png_ptr, int nrows)
+{
+ png_debug(1, "in png_set_flush\n");
+ png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
+}
+
+/* flush the current output buffers now */
+void PNGAPI
+png_write_flush(png_structp png_ptr)
+{
+ int wrote_IDAT;
+
+ png_debug(1, "in png_write_flush\n");
+ /* We have already written out all of the data */
+ if (png_ptr->row_number >= png_ptr->num_rows)
+ return;
+
+ do
+ {
+ int ret;
+
+ /* compress the data */
+ ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+ wrote_IDAT = 0;
+
+ /* check for compression errors */
+ if (ret != Z_OK)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* write the IDAT and reset the zlib output buffer */
+ png_write_IDAT(png_ptr, png_ptr->zbuf,
+ png_ptr->zbuf_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ wrote_IDAT = 1;
+ }
+ } while(wrote_IDAT == 1);
+
+ /* If there is any data left to be output, write it into a new IDAT */
+ if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
+ {
+ /* write the IDAT and reset the zlib output buffer */
+ png_write_IDAT(png_ptr, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ png_ptr->flush_rows = 0;
+ png_flush(png_ptr);
+}
+#endif /* PNG_WRITE_FLUSH_SUPPORTED */
+
+/* free all memory used by the write */
+void PNGAPI
+png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
+{
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn = NULL;
+ png_voidp mem_ptr = NULL;
+#endif
+
+ png_debug(1, "in png_destroy_write_struct\n");
+ if (png_ptr_ptr != NULL)
+ {
+ png_ptr = *png_ptr_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+ mem_ptr = png_ptr->mem_ptr;
+#endif
+ }
+
+ if (info_ptr_ptr != NULL)
+ info_ptr = *info_ptr_ptr;
+
+ if (info_ptr != NULL)
+ {
+ png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
+
+#if defined(PNG_UNKNOWN_CHUNKS_SUPPORTED)
+ if (png_ptr->num_chunk_list)
+ {
+ png_free(png_ptr, png_ptr->chunk_list);
+ png_ptr->chunk_list=NULL;
+ png_ptr->num_chunk_list=0;
+ }
+#endif
+
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)info_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)info_ptr);
+#endif
+ *info_ptr_ptr = NULL;
+ }
+
+ if (png_ptr != NULL)
+ {
+ png_write_destroy(png_ptr);
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2((png_voidp)png_ptr, (png_free_ptr)free_fn,
+ (png_voidp)mem_ptr);
+#else
+ png_destroy_struct((png_voidp)png_ptr);
+#endif
+ *png_ptr_ptr = NULL;
+ }
+}
+
+
+/* Free any memory used in png_ptr struct (old method) */
+void /* PRIVATE */
+png_write_destroy(png_structp png_ptr)
+{
+#ifdef PNG_SETJMP_SUPPORTED
+ jmp_buf tmp_jmp; /* save jump buffer */
+#endif
+ png_error_ptr error_fn;
+ png_error_ptr warning_fn;
+ png_voidp error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_free_ptr free_fn;
+#endif
+
+ png_debug(1, "in png_write_destroy\n");
+ /* free any memory zlib uses */
+ deflateEnd(&png_ptr->zstream);
+
+ /* free our memory. png_free checks NULL for us. */
+ png_free(png_ptr, png_ptr->zbuf);
+ png_free(png_ptr, png_ptr->row_buf);
+ png_free(png_ptr, png_ptr->prev_row);
+ png_free(png_ptr, png_ptr->sub_row);
+ png_free(png_ptr, png_ptr->up_row);
+ png_free(png_ptr, png_ptr->avg_row);
+ png_free(png_ptr, png_ptr->paeth_row);
+
+#if defined(PNG_TIME_RFC1123_SUPPORTED)
+ png_free(png_ptr, png_ptr->time_buffer);
+#endif
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ png_free(png_ptr, png_ptr->prev_filters);
+ png_free(png_ptr, png_ptr->filter_weights);
+ png_free(png_ptr, png_ptr->inv_filter_weights);
+ png_free(png_ptr, png_ptr->filter_costs);
+ png_free(png_ptr, png_ptr->inv_filter_costs);
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ /* reset structure */
+ png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
+#endif
+
+ error_fn = png_ptr->error_fn;
+ warning_fn = png_ptr->warning_fn;
+ error_ptr = png_ptr->error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ free_fn = png_ptr->free_fn;
+#endif
+
+ png_memset(png_ptr, 0, sizeof (png_struct));
+
+ png_ptr->error_fn = error_fn;
+ png_ptr->warning_fn = warning_fn;
+ png_ptr->error_ptr = error_ptr;
+#ifdef PNG_USER_MEM_SUPPORTED
+ png_ptr->free_fn = free_fn;
+#endif
+
+#ifdef PNG_SETJMP_SUPPORTED
+ png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
+#endif
+}
+
+/* Allow the application to select one or more row filters to use. */
+void PNGAPI
+png_set_filter(png_structp png_ptr, int method, int filters)
+{
+ png_debug(1, "in png_set_filter\n");
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ if((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ (method == PNG_INTRAPIXEL_DIFFERENCING))
+ method = PNG_FILTER_TYPE_BASE;
+#endif
+ if (method == PNG_FILTER_TYPE_BASE)
+ {
+ switch (filters & (PNG_ALL_FILTERS | 0x07))
+ {
+ case 5:
+ case 6:
+ case 7: png_warning(png_ptr, "Unknown row filter for method 0");
+ case PNG_FILTER_VALUE_NONE: png_ptr->do_filter=PNG_FILTER_NONE; break;
+ case PNG_FILTER_VALUE_SUB: png_ptr->do_filter=PNG_FILTER_SUB; break;
+ case PNG_FILTER_VALUE_UP: png_ptr->do_filter=PNG_FILTER_UP; break;
+ case PNG_FILTER_VALUE_AVG: png_ptr->do_filter=PNG_FILTER_AVG; break;
+ case PNG_FILTER_VALUE_PAETH: png_ptr->do_filter=PNG_FILTER_PAETH;break;
+ default: png_ptr->do_filter = (png_byte)filters; break;
+ }
+
+ /* If we have allocated the row_buf, this means we have already started
+ * with the image and we should have allocated all of the filter buffers
+ * that have been selected. If prev_row isn't already allocated, then
+ * it is too late to start using the filters that need it, since we
+ * will be missing the data in the previous row. If an application
+ * wants to start and stop using particular filters during compression,
+ * it should start out with all of the filters, and then add and
+ * remove them after the start of compression.
+ */
+ if (png_ptr->row_buf != NULL)
+ {
+ if ((png_ptr->do_filter & PNG_FILTER_SUB) && png_ptr->sub_row == NULL)
+ {
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_UP) && png_ptr->up_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Up filter after starting");
+ png_ptr->do_filter &= ~PNG_FILTER_UP;
+ }
+ else
+ {
+ png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+ }
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_AVG) && png_ptr->avg_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Average filter after starting");
+ png_ptr->do_filter &= ~PNG_FILTER_AVG;
+ }
+ else
+ {
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+ }
+ }
+
+ if ((png_ptr->do_filter & PNG_FILTER_PAETH) &&
+ png_ptr->paeth_row == NULL)
+ {
+ if (png_ptr->prev_row == NULL)
+ {
+ png_warning(png_ptr, "Can't add Paeth filter after starting");
+ png_ptr->do_filter &= (png_byte)(~PNG_FILTER_PAETH);
+ }
+ else
+ {
+ png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+ }
+ }
+
+ if (png_ptr->do_filter == PNG_NO_FILTERS)
+ png_ptr->do_filter = PNG_FILTER_NONE;
+ }
+ }
+ else
+ png_error(png_ptr, "Unknown custom filter method");
+}
+
+/* This allows us to influence the way in which libpng chooses the "best"
+ * filter for the current scanline. While the "minimum-sum-of-absolute-
+ * differences metric is relatively fast and effective, there is some
+ * question as to whether it can be improved upon by trying to keep the
+ * filtered data going to zlib more consistent, hopefully resulting in
+ * better compression.
+ */
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* GRR 970116 */
+void PNGAPI
+png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
+ int num_weights, png_doublep filter_weights,
+ png_doublep filter_costs)
+{
+ int i;
+
+ png_debug(1, "in png_set_filter_heuristics\n");
+ if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
+ {
+ png_warning(png_ptr, "Unknown filter heuristic method");
+ return;
+ }
+
+ if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
+ {
+ heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
+ }
+
+ if (num_weights < 0 || filter_weights == NULL ||
+ heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
+ {
+ num_weights = 0;
+ }
+
+ png_ptr->num_prev_filters = (png_byte)num_weights;
+ png_ptr->heuristic_method = (png_byte)heuristic_method;
+
+ if (num_weights > 0)
+ {
+ if (png_ptr->prev_filters == NULL)
+ {
+ png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
+ (png_uint_32)(sizeof(png_byte) * num_weights));
+
+ /* To make sure that the weighting starts out fairly */
+ for (i = 0; i < num_weights; i++)
+ {
+ png_ptr->prev_filters[i] = 255;
+ }
+ }
+
+ if (png_ptr->filter_weights == NULL)
+ {
+ png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(sizeof(png_uint_16) * num_weights));
+
+ png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(sizeof(png_uint_16) * num_weights));
+ for (i = 0; i < num_weights; i++)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+ }
+
+ for (i = 0; i < num_weights; i++)
+ {
+ if (filter_weights[i] < 0.0)
+ {
+ png_ptr->inv_filter_weights[i] =
+ png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
+ }
+ else
+ {
+ png_ptr->inv_filter_weights[i] =
+ (png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
+ png_ptr->filter_weights[i] =
+ (png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
+ }
+ }
+ }
+
+ /* If, in the future, there are other filter methods, this would
+ * need to be based on png_ptr->filter.
+ */
+ if (png_ptr->filter_costs == NULL)
+ {
+ png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+ png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
+ (png_uint_32)(sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
+
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+ {
+ png_ptr->inv_filter_costs[i] =
+ png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+ }
+ }
+
+ /* Here is where we set the relative costs of the different filters. We
+ * should take the desired compression level into account when setting
+ * the costs, so that Paeth, for instance, has a high relative cost at low
+ * compression levels, while it has a lower relative cost at higher
+ * compression settings. The filter types are in order of increasing
+ * relative cost, so it would be possible to do this with an algorithm.
+ */
+ for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
+ {
+ if (filter_costs == NULL || filter_costs[i] < 0.0)
+ {
+ png_ptr->inv_filter_costs[i] =
+ png_ptr->filter_costs[i] = PNG_COST_FACTOR;
+ }
+ else if (filter_costs[i] >= 1.0)
+ {
+ png_ptr->inv_filter_costs[i] =
+ (png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
+ png_ptr->filter_costs[i] =
+ (png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
+ }
+ }
+}
+#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
+
+void PNGAPI
+png_set_compression_level(png_structp png_ptr, int level)
+{
+ png_debug(1, "in png_set_compression_level\n");
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
+ png_ptr->zlib_level = level;
+}
+
+void PNGAPI
+png_set_compression_mem_level(png_structp png_ptr, int mem_level)
+{
+ png_debug(1, "in png_set_compression_mem_level\n");
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
+ png_ptr->zlib_mem_level = mem_level;
+}
+
+void PNGAPI
+png_set_compression_strategy(png_structp png_ptr, int strategy)
+{
+ png_debug(1, "in png_set_compression_strategy\n");
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
+ png_ptr->zlib_strategy = strategy;
+}
+
+void PNGAPI
+png_set_compression_window_bits(png_structp png_ptr, int window_bits)
+{
+ if (window_bits > 15)
+ png_warning(png_ptr, "Only compression windows <= 32k supported by PNG");
+ else if (window_bits < 8)
+ png_warning(png_ptr, "Only compression windows >= 256 supported by PNG");
+#ifndef WBITS_8_OK
+ /* avoid libpng bug with 256-byte windows */
+ if (window_bits == 8)
+ {
+ png_warning(png_ptr, "Compression window is being reset to 512");
+ window_bits=9;
+ }
+#endif
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS;
+ png_ptr->zlib_window_bits = window_bits;
+}
+
+void PNGAPI
+png_set_compression_method(png_structp png_ptr, int method)
+{
+ png_debug(1, "in png_set_compression_method\n");
+ if (method != 8)
+ png_warning(png_ptr, "Only compression method 8 is supported by PNG");
+ png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
+ png_ptr->zlib_method = method;
+}
+
+void PNGAPI
+png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
+{
+ png_ptr->write_row_fn = write_row_fn;
+}
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+void PNGAPI
+png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
+ write_user_transform_fn)
+{
+ png_debug(1, "in png_set_write_user_transform_fn\n");
+ png_ptr->transformations |= PNG_USER_TRANSFORM;
+ png_ptr->write_user_transform_fn = write_user_transform_fn;
+}
+#endif
+
+
+#if defined(PNG_INFO_IMAGE_SUPPORTED)
+void PNGAPI
+png_write_png(png_structp png_ptr, png_infop info_ptr,
+ int transforms, voidp params)
+{
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+ /* invert the alpha channel from opacity to transparency */
+ if (transforms & PNG_TRANSFORM_INVERT_ALPHA)
+ png_set_invert_alpha(png_ptr);
+#endif
+
+ /* Write the file header information. */
+ png_write_info(png_ptr, info_ptr);
+
+ /* ------ these transformations don't touch the info structure ------- */
+
+#if defined(PNG_WRITE_INVERT_SUPPORTED)
+ /* invert monochrome pixels */
+ if (transforms & PNG_TRANSFORM_INVERT_MONO)
+ png_set_invert_mono(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+ /* Shift the pixels up to a legal bit depth and fill in
+ * as appropriate to correctly scale the image.
+ */
+ if ((transforms & PNG_TRANSFORM_SHIFT)
+ && (info_ptr->valid & PNG_INFO_sBIT))
+ png_set_shift(png_ptr, &info_ptr->sig_bit);
+#endif
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+ /* pack pixels into bytes */
+ if (transforms & PNG_TRANSFORM_PACKING)
+ png_set_packing(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+ /* swap location of alpha bytes from ARGB to RGBA */
+ if (transforms & PNG_TRANSFORM_SWAP_ALPHA)
+ png_set_swap_alpha(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_FILLER_SUPPORTED)
+ /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
+ * RGB (4 channels -> 3 channels). The second parameter is not used.
+ */
+ if (transforms & PNG_TRANSFORM_STRIP_FILLER)
+ png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
+#endif
+
+#if defined(PNG_WRITE_BGR_SUPPORTED)
+ /* flip BGR pixels to RGB */
+ if (transforms & PNG_TRANSFORM_BGR)
+ png_set_bgr(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_SWAP_SUPPORTED)
+ /* swap bytes of 16-bit files to most significant byte first */
+ if (transforms & PNG_TRANSFORM_SWAP_ENDIAN)
+ png_set_swap(png_ptr);
+#endif
+
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+ /* swap bits of 1, 2, 4 bit packed pixel formats */
+ if (transforms & PNG_TRANSFORM_PACKSWAP)
+ png_set_packswap(png_ptr);
+#endif
+
+ /* ----------------------- end of transformations ------------------- */
+
+ /* write the bits */
+ if (info_ptr->valid & PNG_INFO_IDAT)
+ png_write_image(png_ptr, info_ptr->row_pointers);
+
+ /* It is RETQUIRED to call this to finish writing the rest of the file */
+ png_write_end(png_ptr, info_ptr);
+
+ if(transforms == 0 || params == NULL)
+ /* quiet compiler warnings */ return;
+}
+#endif
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngwtran.c b/tqtinterface/qt4/src/3rdparty/libpng/pngwtran.c
new file mode 100644
index 0000000..582c10d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngwtran.c
@@ -0,0 +1,563 @@
+
+/* pngwtran.c - transforms the data in a row for PNG writers
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Transform the data according to the user's wishes. The order of
+ * transformations is significant.
+ */
+void /* PRIVATE */
+png_do_write_transformations(png_structp png_ptr)
+{
+ png_debug(1, "in png_do_write_transformations\n");
+
+ if (png_ptr == NULL)
+ return;
+
+#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
+ if (png_ptr->transformations & PNG_USER_TRANSFORM)
+ if(png_ptr->write_user_transform_fn != NULL)
+ (*(png_ptr->write_user_transform_fn)) /* user write transform function */
+ (png_ptr, /* png_ptr */
+ &(png_ptr->row_info), /* row_info: */
+ /* png_uint_32 width; width of row */
+ /* png_uint_32 rowbytes; number of bytes in row */
+ /* png_byte color_type; color type of pixels */
+ /* png_byte bit_depth; bit depth of samples */
+ /* png_byte channels; number of channels (1-4) */
+ /* png_byte pixel_depth; bits per pixel (depth*channels) */
+ png_ptr->row_buf + 1); /* start of pixel data for row */
+#endif
+#if defined(PNG_WRITE_FILLER_SUPPORTED)
+ if (png_ptr->transformations & PNG_FILLER)
+ png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ png_ptr->flags);
+#endif
+#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACKSWAP)
+ png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+ if (png_ptr->transformations & PNG_PACK)
+ png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ (png_uint_32)png_ptr->bit_depth);
+#endif
+#if defined(PNG_WRITE_SWAP_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_BYTES)
+ png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+ if (png_ptr->transformations & PNG_SHIFT)
+ png_do_shift(&(png_ptr->row_info), png_ptr->row_buf + 1,
+ &(png_ptr->shift));
+#endif
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_ALPHA)
+ png_do_write_invert_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+ if (png_ptr->transformations & PNG_SWAP_ALPHA)
+ png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_BGR_SUPPORTED)
+ if (png_ptr->transformations & PNG_BGR)
+ png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+#if defined(PNG_WRITE_INVERT_SUPPORTED)
+ if (png_ptr->transformations & PNG_INVERT_MONO)
+ png_do_invert(&(png_ptr->row_info), png_ptr->row_buf + 1);
+#endif
+}
+
+#if defined(PNG_WRITE_PACK_SUPPORTED)
+/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
+ * row_info bit depth should be 8 (one pixel per byte). The channels
+ * should be 1 (this only happens on grayscale and paletted images).
+ */
+void /* PRIVATE */
+png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
+{
+ png_debug(1, "in png_do_pack\n");
+ if (row_info->bit_depth == 8 &&
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ row_info->channels == 1)
+ {
+ switch ((int)bit_depth)
+ {
+ case 1:
+ {
+ png_bytep sp, dp;
+ int tqmask, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ tqmask = 0x80;
+ v = 0;
+
+ for (i = 0; i < row_width; i++)
+ {
+ if (*sp != 0)
+ v |= tqmask;
+ sp++;
+ if (tqmask > 1)
+ tqmask >>= 1;
+ else
+ {
+ tqmask = 0x80;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ }
+ if (tqmask != 0x80)
+ *dp = (png_byte)v;
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp, dp;
+ int shift, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ shift = 6;
+ v = 0;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte value;
+
+ value = (png_byte)(*sp & 0x03);
+ v |= (value << shift);
+ if (shift == 0)
+ {
+ shift = 6;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ else
+ shift -= 2;
+ sp++;
+ }
+ if (shift != 6)
+ *dp = (png_byte)v;
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp, dp;
+ int shift, v;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ sp = row;
+ dp = row;
+ shift = 4;
+ v = 0;
+ for (i = 0; i < row_width; i++)
+ {
+ png_byte value;
+
+ value = (png_byte)(*sp & 0x0f);
+ v |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 4;
+ *dp = (png_byte)v;
+ dp++;
+ v = 0;
+ }
+ else
+ shift -= 4;
+
+ sp++;
+ }
+ if (shift != 4)
+ *dp = (png_byte)v;
+ break;
+ }
+ }
+ row_info->bit_depth = (png_byte)bit_depth;
+ row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
+ row_info->rowbytes =
+ ((row_info->width * row_info->pixel_depth + 7) >> 3);
+ }
+}
+#endif
+
+#if defined(PNG_WRITE_SHIFT_SUPPORTED)
+/* Shift pixel values to take advantage of whole range. Pass the
+ * true number of bits in bit_depth. The row should be packed
+ * according to row_info->bit_depth. Thus, if you had a row of
+ * bit depth 4, but the pixels only had values from 0 to 7, you
+ * would pass 3 as bit_depth, and this routine would translate the
+ * data to 0 to 15.
+ */
+void /* PRIVATE */
+png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
+{
+ png_debug(1, "in png_do_shift\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL &&
+#else
+ if (
+#endif
+ row_info->color_type != PNG_COLOR_TYPE_PALETTE)
+ {
+ int shift_start[4], shift_dec[4];
+ int channels = 0;
+
+ if (row_info->color_type & PNG_COLOR_MASK_COLOR)
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->red;
+ shift_dec[channels] = bit_depth->red;
+ channels++;
+ shift_start[channels] = row_info->bit_depth - bit_depth->green;
+ shift_dec[channels] = bit_depth->green;
+ channels++;
+ shift_start[channels] = row_info->bit_depth - bit_depth->blue;
+ shift_dec[channels] = bit_depth->blue;
+ channels++;
+ }
+ else
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->gray;
+ shift_dec[channels] = bit_depth->gray;
+ channels++;
+ }
+ if (row_info->color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ shift_start[channels] = row_info->bit_depth - bit_depth->alpha;
+ shift_dec[channels] = bit_depth->alpha;
+ channels++;
+ }
+
+ /* with low row depths, could only be grayscale, so one channel */
+ if (row_info->bit_depth < 8)
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_byte tqmask;
+ png_uint_32 row_bytes = row_info->rowbytes;
+
+ if (bit_depth->gray == 1 && row_info->bit_depth == 2)
+ tqmask = 0x55;
+ else if (row_info->bit_depth == 4 && bit_depth->gray == 3)
+ tqmask = 0x11;
+ else
+ tqmask = 0xff;
+
+ for (i = 0; i < row_bytes; i++, bp++)
+ {
+ png_uint_16 v;
+ int j;
+
+ v = *bp;
+ *bp = 0;
+ for (j = shift_start[0]; j > -shift_dec[0]; j -= shift_dec[0])
+ {
+ if (j > 0)
+ *bp |= (png_byte)((v << j) & 0xff);
+ else
+ *bp |= (png_byte)((v >> (-j)) & tqmask);
+ }
+ }
+ }
+ else if (row_info->bit_depth == 8)
+ {
+ png_bytep bp = row;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_info->width;
+
+ for (i = 0; i < istop; i++, bp++)
+ {
+
+ png_uint_16 v;
+ int j;
+ int c = (int)(i%channels);
+
+ v = *bp;
+ *bp = 0;
+ for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+ {
+ if (j > 0)
+ *bp |= (png_byte)((v << j) & 0xff);
+ else
+ *bp |= (png_byte)((v >> (-j)) & 0xff);
+ }
+ }
+ }
+ else
+ {
+ png_bytep bp;
+ png_uint_32 i;
+ png_uint_32 istop = channels * row_info->width;
+
+ for (bp = row, i = 0; i < istop; i++)
+ {
+ int c = (int)(i%channels);
+ png_uint_16 value, v;
+ int j;
+
+ v = (png_uint_16)(((png_uint_16)(*bp) << 8) + *(bp + 1));
+ value = 0;
+ for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
+ {
+ if (j > 0)
+ value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
+ else
+ value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
+ }
+ *bp++ = (png_byte)(value >> 8);
+ *bp++ = (png_byte)(value & 0xff);
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_swap_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This converts from ARGB to RGBA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save;
+ }
+ }
+ /* This converts from AARRGGBB to RRGGBBAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save[2];
+ save[0] = *(sp++);
+ save[1] = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save[0];
+ *(dp++) = save[1];
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This converts from AG to GA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save;
+ }
+ }
+ /* This converts from AAGG to GGAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ png_byte save[2];
+ save[0] = *(sp++);
+ save[1] = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = save[0];
+ *(dp++) = save[1];
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
+void /* PRIVATE */
+png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_invert_alpha\n");
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL)
+#endif
+ {
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ {
+ /* This inverts the alpha channel in RGBA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ /* This inverts the alpha channel in RRGGBBAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ }
+ else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
+ {
+ /* This inverts the alpha channel in GA */
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ /* This inverts the alpha channel in GGAA */
+ else
+ {
+ png_bytep sp, dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ for (i = 0, sp = dp = row; i < row_width; i++)
+ {
+ *(dp++) = *(sp++);
+ *(dp++) = *(sp++);
+ *(dp++) = (png_byte)(255 - *(sp++));
+ *(dp++) = (png_byte)(255 - *(sp++));
+ }
+ }
+ }
+ }
+}
+#endif
+
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+/* undoes intrapixel differencing */
+void /* PRIVATE */
+png_do_write_intrapixel(png_row_infop row_info, png_bytep row)
+{
+ png_debug(1, "in png_do_write_intrapixel\n");
+ if (
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ row != NULL && row_info != NULL &&
+#endif
+ (row_info->color_type & PNG_COLOR_MASK_COLOR))
+ {
+ int bytes_per_pixel;
+ png_uint_32 row_width = row_info->width;
+ if (row_info->bit_depth == 8)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 3;
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 4;
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ *(rp) = (png_byte)((*rp - *(rp+1))&0xff);
+ *(rp+2) = (png_byte)((*(rp+2) - *(rp+1))&0xff);
+ }
+ }
+ else if (row_info->bit_depth == 16)
+ {
+ png_bytep rp;
+ png_uint_32 i;
+
+ if (row_info->color_type == PNG_COLOR_TYPE_RGB)
+ bytes_per_pixel = 6;
+ else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
+ bytes_per_pixel = 8;
+ else
+ return;
+
+ for (i = 0, rp = row; i < row_width; i++, rp += bytes_per_pixel)
+ {
+ png_uint_32 s0=*(rp )<<8 | *(rp+1);
+ png_uint_32 s1=*(rp+2)<<8 | *(rp+3);
+ png_uint_32 s2=*(rp+4)<<8 | *(rp+5);
+ png_uint_32 red=(s0-s1)&0xffff;
+ png_uint_32 blue=(s2-s1)&0xffff;
+ *(rp ) = (png_byte)((red>>8)&0xff);
+ *(rp+1) = (png_byte)(red&0xff);
+ *(rp+4) = (png_byte)((blue>>8)&0xff);
+ *(rp+5) = (png_byte)(blue&0xff);
+ }
+ }
+ }
+}
+#endif /* PNG_MNG_FEATURES_SUPPORTED */
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/pngwutil.c b/tqtinterface/qt4/src/3rdparty/libpng/pngwutil.c
new file mode 100644
index 0000000..b668a57
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/pngwutil.c
@@ -0,0 +1,2694 @@
+
+/* pngwutil.c - utilities to write a PNG file
+ *
+ * libpng 1.2.5 - October 3, 2002
+ * For conditions of distribution and use, see copyright notice in png.h
+ * Copyright (c) 1998-2002 Glenn Randers-Pehrson
+ * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
+ * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
+ */
+
+#define PNG_INTERNAL
+#include "png.h"
+#ifdef PNG_WRITE_SUPPORTED
+
+/* Place a 32-bit number into a buffer in PNG byte order. We work
+ * with unsigned numbers for convenience, although one supported
+ * ancillary chunk uses signed (two's complement) numbers.
+ */
+void /* PRIVATE */
+png_save_uint_32(png_bytep buf, png_uint_32 i)
+{
+ buf[0] = (png_byte)((i >> 24) & 0xff);
+ buf[1] = (png_byte)((i >> 16) & 0xff);
+ buf[2] = (png_byte)((i >> 8) & 0xff);
+ buf[3] = (png_byte)(i & 0xff);
+}
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
+/* The png_save_int_32 function assumes integers are stored in two's
+ * complement format. If this isn't the case, then this routine needs to
+ * be modified to write data in two's complement format.
+ */
+void /* PRIVATE */
+png_save_int_32(png_bytep buf, png_int_32 i)
+{
+ buf[0] = (png_byte)((i >> 24) & 0xff);
+ buf[1] = (png_byte)((i >> 16) & 0xff);
+ buf[2] = (png_byte)((i >> 8) & 0xff);
+ buf[3] = (png_byte)(i & 0xff);
+}
+#endif
+
+/* Place a 16-bit number into a buffer in PNG byte order.
+ * The parameter is declared unsigned int, not png_uint_16,
+ * just to avoid potential problems on pre-ANSI C compilers.
+ */
+void /* PRIVATE */
+png_save_uint_16(png_bytep buf, unsigned int i)
+{
+ buf[0] = (png_byte)((i >> 8) & 0xff);
+ buf[1] = (png_byte)(i & 0xff);
+}
+
+/* Write a PNG chunk all at once. The type is an array of ASCII characters
+ * representing the chunk name. The array must be at least 4 bytes in
+ * length, and does not need to be null terminated. To be safe, pass the
+ * pre-defined chunk names here, and if you need a new one, define it
+ * where the others are defined. The length is the length of the data.
+ * All the data must be present. If that is not possible, use the
+ * png_write_chunk_start(), png_write_chunk_data(), and png_write_chunk_end()
+ * functions instead.
+ */
+void PNGAPI
+png_write_chunk(png_structp png_ptr, png_bytep chunk_name,
+ png_bytep data, png_size_t length)
+{
+ png_write_chunk_start(png_ptr, chunk_name, (png_uint_32)length);
+ png_write_chunk_data(png_ptr, data, length);
+ png_write_chunk_end(png_ptr);
+}
+
+/* Write the start of a PNG chunk. The type is the chunk type.
+ * The total_length is the sum of the lengths of all the data you will be
+ * passing in png_write_chunk_data().
+ */
+void PNGAPI
+png_write_chunk_start(png_structp png_ptr, png_bytep chunk_name,
+ png_uint_32 length)
+{
+ png_byte buf[4];
+ png_debug2(0, "Writing %s chunk (%lu bytes)\n", chunk_name, length);
+
+ /* write the length */
+ png_save_uint_32(buf, length);
+ png_write_data(png_ptr, buf, (png_size_t)4);
+
+ /* write the chunk name */
+ png_write_data(png_ptr, chunk_name, (png_size_t)4);
+ /* reset the crc and run it over the chunk name */
+ png_reset_crc(png_ptr);
+ png_calculate_crc(png_ptr, chunk_name, (png_size_t)4);
+}
+
+/* Write the data of a PNG chunk started with png_write_chunk_start().
+ * Note that multiple calls to this function are allowed, and that the
+ * sum of the lengths from these calls *must* add up to the total_length
+ * given to png_write_chunk_start().
+ */
+void PNGAPI
+png_write_chunk_data(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ /* write the data, and run the CRC over it */
+ if (data != NULL && length > 0)
+ {
+ png_calculate_crc(png_ptr, data, length);
+ png_write_data(png_ptr, data, length);
+ }
+}
+
+/* Finish a chunk started with png_write_chunk_start(). */
+void PNGAPI
+png_write_chunk_end(png_structp png_ptr)
+{
+ png_byte buf[4];
+
+ /* write the crc */
+ png_save_uint_32(buf, png_ptr->crc);
+
+ png_write_data(png_ptr, buf, (png_size_t)4);
+}
+
+/* Simple function to write the signature. If we have already written
+ * the magic bytes of the signature, or more likely, the PNG stream is
+ * being embedded into another stream and doesn't need its own signature,
+ * we should call png_set_sig_bytes() to tell libpng how many of the
+ * bytes have already been written.
+ */
+void /* PRIVATE */
+png_write_sig(png_structp png_ptr)
+{
+ png_byte png_signature[8] = {137, 80, 78, 71, 13, 10, 26, 10};
+ /* write the rest of the 8 byte signature */
+ png_write_data(png_ptr, &png_signature[png_ptr->sig_bytes],
+ (png_size_t)8 - png_ptr->sig_bytes);
+ if(png_ptr->sig_bytes < 3)
+ png_ptr->mode |= PNG_HAVE_PNG_SIGNATURE;
+}
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_iCCP_SUPPORTED)
+/*
+ * This pair of functions encapsulates the operation of (a) compressing a
+ * text string, and (b) issuing it later as a series of chunk data writes.
+ * The compression_state structure is shared context for these functions
+ * set up by the caller in order to make the whole mess thread-safe.
+ */
+
+typedef struct
+{
+ char *input; /* the uncompressed input data */
+ int input_len; /* its length */
+ int num_output_ptr; /* number of output pointers used */
+ int max_output_ptr; /* size of output_ptr */
+ png_charpp output_ptr; /* array of pointers to output */
+} compression_state;
+
+/* compress given text into storage in the png_ptr structure */
+static int /* PRIVATE */
+png_text_compress(png_structp png_ptr,
+ png_charp text, png_size_t text_len, int compression,
+ compression_state *comp)
+{
+ int ret;
+
+ comp->num_output_ptr = comp->max_output_ptr = 0;
+ comp->output_ptr = NULL;
+ comp->input = NULL;
+
+ /* we may just want to pass the text right through */
+ if (compression == PNG_TEXT_COMPRESSION_NONE)
+ {
+ comp->input = text;
+ comp->input_len = text_len;
+ return((int)text_len);
+ }
+
+ if (compression >= PNG_TEXT_COMPRESSION_LAST)
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char msg[50];
+ sprintf(msg, "Unknown compression type %d", compression);
+ png_warning(png_ptr, msg);
+#else
+ png_warning(png_ptr, "Unknown compression type");
+#endif
+ }
+
+ /* We can't write the chunk until we tqfind out how much data we have,
+ * which means we need to run the compressor first and save the
+ * output. This shouldn't be a problem, as the vast majority of
+ * comments should be reasonable, but we will set up an array of
+ * malloc'd pointers to be sure.
+ *
+ * If we knew the application was well behaved, we could simplify this
+ * greatly by assuming we can always malloc an output buffer large
+ * enough to hold the compressed text ((1001 * text_len / 1000) + 12)
+ * and malloc this directly. The only time this would be a bad idea is
+ * if we can't malloc more than 64K and we have 64K of random input
+ * data, or if the input string is incredibly large (although this
+ * wouldn't cause a failure, just a slowdown due to swapping).
+ */
+
+ /* set up the compression buffers */
+ png_ptr->zstream.avail_in = (uInt)text_len;
+ png_ptr->zstream.next_in = (Bytef *)text;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = (Bytef *)png_ptr->zbuf;
+
+ /* this is the same compression loop as in png_write_row() */
+ do
+ {
+ /* compress the data */
+ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+ if (ret != Z_OK)
+ {
+ /* error */
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+ /* check to see if we need more room */
+ if (!png_ptr->zstream.avail_out && png_ptr->zstream.avail_in)
+ {
+ /* make sure the output array has room */
+ if (comp->num_output_ptr >= comp->max_output_ptr)
+ {
+ int old_max;
+
+ old_max = comp->max_output_ptr;
+ comp->max_output_ptr = comp->num_output_ptr + 4;
+ if (comp->output_ptr != NULL)
+ {
+ png_charpp old_ptr;
+
+ old_ptr = comp->output_ptr;
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)(comp->max_output_ptr * sizeof (png_charpp)));
+ png_memcpy(comp->output_ptr, old_ptr, old_max
+ * sizeof (png_charp));
+ png_free(png_ptr, old_ptr);
+ }
+ else
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)(comp->max_output_ptr * sizeof (png_charp)));
+ }
+
+ /* save the data */
+ comp->output_ptr[comp->num_output_ptr] = (png_charp)png_malloc(png_ptr,
+ (png_uint_32)png_ptr->zbuf_size);
+ png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+ png_ptr->zbuf_size);
+ comp->num_output_ptr++;
+
+ /* and reset the buffer */
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ }
+ /* continue until we don't have any more to compress */
+ } while (png_ptr->zstream.avail_in);
+
+ /* finish the compression */
+ do
+ {
+ /* tell zlib we are finished */
+ ret = deflate(&png_ptr->zstream, Z_FINISH);
+
+ if (ret == Z_OK)
+ {
+ /* check to see if we need more room */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* check to make sure our output array has room */
+ if (comp->num_output_ptr >= comp->max_output_ptr)
+ {
+ int old_max;
+
+ old_max = comp->max_output_ptr;
+ comp->max_output_ptr = comp->num_output_ptr + 4;
+ if (comp->output_ptr != NULL)
+ {
+ png_charpp old_ptr;
+
+ old_ptr = comp->output_ptr;
+ /* This could be optimized to realloc() */
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)(comp->max_output_ptr * sizeof (png_charpp)));
+ png_memcpy(comp->output_ptr, old_ptr,
+ old_max * sizeof (png_charp));
+ png_free(png_ptr, old_ptr);
+ }
+ else
+ comp->output_ptr = (png_charpp)png_malloc(png_ptr,
+ (png_uint_32)(comp->max_output_ptr * sizeof (png_charp)));
+ }
+
+ /* save off the data */
+ comp->output_ptr[comp->num_output_ptr] =
+ (png_charp)png_malloc(png_ptr, (png_uint_32)png_ptr->zbuf_size);
+ png_memcpy(comp->output_ptr[comp->num_output_ptr], png_ptr->zbuf,
+ png_ptr->zbuf_size);
+ comp->num_output_ptr++;
+
+ /* and reset the buffer pointers */
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ }
+ }
+ else if (ret != Z_STREAM_END)
+ {
+ /* we got an error */
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+ } while (ret != Z_STREAM_END);
+
+ /* text length is number of buffers plus last buffer */
+ text_len = png_ptr->zbuf_size * comp->num_output_ptr;
+ if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+ text_len += png_ptr->zbuf_size - (png_size_t)png_ptr->zstream.avail_out;
+
+ return((int)text_len);
+}
+
+/* ship the compressed text out via chunk writes */
+static void /* PRIVATE */
+png_write_compressed_data_out(png_structp png_ptr, compression_state *comp)
+{
+ int i;
+
+ /* handle the no-compression case */
+ if (comp->input)
+ {
+ png_write_chunk_data(png_ptr, (png_bytep)comp->input,
+ (png_size_t)comp->input_len);
+ return;
+ }
+
+ /* write saved output buffers, if any */
+ for (i = 0; i < comp->num_output_ptr; i++)
+ {
+ png_write_chunk_data(png_ptr,(png_bytep)comp->output_ptr[i],
+ png_ptr->zbuf_size);
+ png_free(png_ptr, comp->output_ptr[i]);
+ comp->output_ptr[i]=NULL;
+ }
+ if (comp->max_output_ptr != 0)
+ png_free(png_ptr, comp->output_ptr);
+ comp->output_ptr=NULL;
+ /* write anything left in zbuf */
+ if (png_ptr->zstream.avail_out < (png_uint_32)png_ptr->zbuf_size)
+ png_write_chunk_data(png_ptr, png_ptr->zbuf,
+ png_ptr->zbuf_size - png_ptr->zstream.avail_out);
+
+ /* reset zlib for another zTXt/iTXt or the image data */
+ deflateReset(&png_ptr->zstream);
+
+}
+#endif
+
+/* Write the IHDR chunk, and update the png_struct with the necessary
+ * information. Note that the rest of this code depends upon this
+ * information being correct.
+ */
+void /* PRIVATE */
+png_write_IHDR(png_structp png_ptr, png_uint_32 width, png_uint_32 height,
+ int bit_depth, int color_type, int compression_type, int filter_type,
+ int interlace_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IHDR;
+#endif
+ png_byte buf[13]; /* buffer to store the IHDR info */
+
+ png_debug(1, "in png_write_IHDR\n");
+ /* Check that we have valid input data from the application info */
+ switch (color_type)
+ {
+ case PNG_COLOR_TYPE_GRAY:
+ switch (bit_depth)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ case 16: png_ptr->channels = 1; break;
+ default: png_error(png_ptr,"Invalid bit depth for grayscale image");
+ }
+ break;
+ case PNG_COLOR_TYPE_RGB:
+ if (bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth for RGB image");
+ png_ptr->channels = 3;
+ break;
+ case PNG_COLOR_TYPE_PALETTE:
+ switch (bit_depth)
+ {
+ case 1:
+ case 2:
+ case 4:
+ case 8: png_ptr->channels = 1; break;
+ default: png_error(png_ptr, "Invalid bit depth for paletted image");
+ }
+ break;
+ case PNG_COLOR_TYPE_GRAY_ALPHA:
+ if (bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth for grayscale+alpha image");
+ png_ptr->channels = 2;
+ break;
+ case PNG_COLOR_TYPE_RGB_ALPHA:
+ if (bit_depth != 8 && bit_depth != 16)
+ png_error(png_ptr, "Invalid bit depth for RGBA image");
+ png_ptr->channels = 4;
+ break;
+ default:
+ png_error(png_ptr, "Invalid image color type specified");
+ }
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Invalid compression type specified");
+ compression_type = PNG_COMPRESSION_TYPE_BASE;
+ }
+
+ /* Write filter_method 64 (intrapixel differencing) only if
+ * 1. Libpng was compiled with PNG_MNG_FEATURES_SUPPORTED and
+ * 2. Libpng did not write a PNG signature (this filter_method is only
+ * used in PNG datastreams that are embedded in MNG datastreams) and
+ * 3. The application called png_permit_mng_features with a tqmask that
+ * included PNG_FLAG_MNG_FILTER_64 and
+ * 4. The filter_method is 64 and
+ * 5. The color_type is RGB or RGBA
+ */
+ if (
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ !((png_ptr->mng_features_permitted & PNG_FLAG_MNG_FILTER_64) &&
+ ((png_ptr->mode&PNG_HAVE_PNG_SIGNATURE) == 0) &&
+ (color_type == PNG_COLOR_TYPE_RGB ||
+ color_type == PNG_COLOR_TYPE_RGB_ALPHA) &&
+ (filter_type == PNG_INTRAPIXEL_DIFFERENCING)) &&
+#endif
+ filter_type != PNG_FILTER_TYPE_BASE)
+ {
+ png_warning(png_ptr, "Invalid filter type specified");
+ filter_type = PNG_FILTER_TYPE_BASE;
+ }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ if (interlace_type != PNG_INTERLACE_NONE &&
+ interlace_type != PNG_INTERLACE_ADAM7)
+ {
+ png_warning(png_ptr, "Invalid interlace type specified");
+ interlace_type = PNG_INTERLACE_ADAM7;
+ }
+#else
+ interlace_type=PNG_INTERLACE_NONE;
+#endif
+
+ /* save off the relevent information */
+ png_ptr->bit_depth = (png_byte)bit_depth;
+ png_ptr->color_type = (png_byte)color_type;
+ png_ptr->interlaced = (png_byte)interlace_type;
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ png_ptr->filter_type = (png_byte)filter_type;
+#endif
+ png_ptr->width = width;
+ png_ptr->height = height;
+
+ png_ptr->pixel_depth = (png_byte)(bit_depth * png_ptr->channels);
+ png_ptr->rowbytes = ((width * (png_size_t)png_ptr->pixel_depth + 7) >> 3);
+ /* set the usr info, so any transformations can modify it */
+ png_ptr->usr_width = png_ptr->width;
+ png_ptr->usr_bit_depth = png_ptr->bit_depth;
+ png_ptr->usr_channels = png_ptr->channels;
+
+ /* pack the header information into the buffer */
+ png_save_uint_32(buf, width);
+ png_save_uint_32(buf + 4, height);
+ buf[8] = (png_byte)bit_depth;
+ buf[9] = (png_byte)color_type;
+ buf[10] = (png_byte)compression_type;
+ buf[11] = (png_byte)filter_type;
+ buf[12] = (png_byte)interlace_type;
+
+ /* write the chunk */
+ png_write_chunk(png_ptr, (png_bytep)png_IHDR, buf, (png_size_t)13);
+
+ /* initialize zlib with PNG info */
+ png_ptr->zstream.zalloc = png_zalloc;
+ png_ptr->zstream.zfree = png_zfree;
+ png_ptr->zstream.opaque = (voidpf)png_ptr;
+ if (!(png_ptr->do_filter))
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE ||
+ png_ptr->bit_depth < 8)
+ png_ptr->do_filter = PNG_FILTER_NONE;
+ else
+ png_ptr->do_filter = PNG_ALL_FILTERS;
+ }
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_STRATEGY))
+ {
+ if (png_ptr->do_filter != PNG_FILTER_NONE)
+ png_ptr->zlib_strategy = Z_FILTERED;
+ else
+ png_ptr->zlib_strategy = Z_DEFAULT_STRATEGY;
+ }
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_LEVEL))
+ png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL))
+ png_ptr->zlib_mem_level = 8;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_WINDOW_BITS))
+ png_ptr->zlib_window_bits = 15;
+ if (!(png_ptr->flags & PNG_FLAG_ZLIB_CUSTOM_METHOD))
+ png_ptr->zlib_method = 8;
+ deflateInit2(&png_ptr->zstream, png_ptr->zlib_level,
+ png_ptr->zlib_method, png_ptr->zlib_window_bits,
+ png_ptr->zlib_mem_level, png_ptr->zlib_strategy);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+
+ png_ptr->mode = PNG_HAVE_IHDR;
+}
+
+/* write the palette. We are careful not to trust png_color to be in the
+ * correct order for PNG, so people can redefine it to any convenient
+ * structure.
+ */
+void /* PRIVATE */
+png_write_PLTE(png_structp png_ptr, png_colorp palette, png_uint_32 num_pal)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_PLTE;
+#endif
+ png_uint_32 i;
+ png_colorp pal_ptr;
+ png_byte buf[3];
+
+ png_debug(1, "in png_write_PLTE\n");
+ if ((
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ !(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE) &&
+#endif
+ num_pal == 0) || num_pal > 256)
+ {
+ if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ png_error(png_ptr, "Invalid number of colors in palette");
+ }
+ else
+ {
+ png_warning(png_ptr, "Invalid number of colors in palette");
+ return;
+ }
+ }
+
+ if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
+ {
+ png_warning(png_ptr,
+ "Ignoring request to write a PLTE chunk in grayscale PNG");
+ return;
+ }
+
+ png_ptr->num_palette = (png_uint_16)num_pal;
+ png_debug1(3, "num_palette = %d\n", png_ptr->num_palette);
+
+ png_write_chunk_start(png_ptr, (png_bytep)png_PLTE, num_pal * 3);
+#ifndef PNG_NO_POINTER_INDEXING
+ for (i = 0, pal_ptr = palette; i < num_pal; i++, pal_ptr++)
+ {
+ buf[0] = pal_ptr->red;
+ buf[1] = pal_ptr->green;
+ buf[2] = pal_ptr->blue;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+ }
+#else
+ /* This is a little slower but some buggy compilers need to do this instead */
+ pal_ptr=palette;
+ for (i = 0; i < num_pal; i++)
+ {
+ buf[0] = pal_ptr[i].red;
+ buf[1] = pal_ptr[i].green;
+ buf[2] = pal_ptr[i].blue;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)3);
+ }
+#endif
+ png_write_chunk_end(png_ptr);
+ png_ptr->mode |= PNG_HAVE_PLTE;
+}
+
+/* write an IDAT chunk */
+void /* PRIVATE */
+png_write_IDAT(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IDAT;
+#endif
+ png_debug(1, "in png_write_IDAT\n");
+ png_write_chunk(png_ptr, (png_bytep)png_IDAT, data, length);
+ png_ptr->mode |= PNG_HAVE_IDAT;
+}
+
+/* write an IEND chunk */
+void /* PRIVATE */
+png_write_IEND(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_IEND;
+#endif
+ png_debug(1, "in png_write_IEND\n");
+ png_write_chunk(png_ptr, (png_bytep)png_IEND, png_bytep_NULL,
+ (png_size_t)0);
+ png_ptr->mode |= PNG_HAVE_IEND;
+}
+
+#if defined(PNG_WRITE_gAMA_SUPPORTED)
+/* write a gAMA chunk */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA(png_structp png_ptr, double file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_gAMA;
+#endif
+ png_uint_32 igamma;
+ png_byte buf[4];
+
+ png_debug(1, "in png_write_gAMA\n");
+ /* file_gamma is saved in 1/100,000ths */
+ igamma = (png_uint_32)(file_gamma * 100000.0 + 0.5);
+ png_save_uint_32(buf, igamma);
+ png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_gAMA_fixed(png_structp png_ptr, png_fixed_point file_gamma)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_gAMA;
+#endif
+ png_byte buf[4];
+
+ png_debug(1, "in png_write_gAMA\n");
+ /* file_gamma is saved in 1/100,000ths */
+ png_save_uint_32(buf, (png_uint_32)file_gamma);
+ png_write_chunk(png_ptr, (png_bytep)png_gAMA, buf, (png_size_t)4);
+}
+#endif
+#endif
+
+#if defined(PNG_WRITE_sRGB_SUPPORTED)
+/* write a sRGB chunk */
+void /* PRIVATE */
+png_write_sRGB(png_structp png_ptr, int srgb_intent)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sRGB;
+#endif
+ png_byte buf[1];
+
+ png_debug(1, "in png_write_sRGB\n");
+ if(srgb_intent >= PNG_sRGB_INTENT_LAST)
+ png_warning(png_ptr,
+ "Invalid sRGB rendering intent specified");
+ buf[0]=(png_byte)srgb_intent;
+ png_write_chunk(png_ptr, (png_bytep)png_sRGB, buf, (png_size_t)1);
+}
+#endif
+
+#if defined(PNG_WRITE_iCCP_SUPPORTED)
+/* write an iCCP chunk */
+void /* PRIVATE */
+png_write_iCCP(png_structp png_ptr, png_charp name, int compression_type,
+ png_charp profile, int profile_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_iCCP;
+#endif
+ png_size_t name_len;
+ png_charp new_name;
+ compression_state comp;
+ int embedded_profile_len = 0;
+
+ png_debug(1, "in png_write_iCCP\n");
+ if (name == NULL || (name_len = png_check_keyword(png_ptr, name,
+ &new_name)) == 0)
+ {
+ png_warning(png_ptr, "Empty keyword in iCCP chunk");
+ return;
+ }
+
+ if (compression_type != PNG_COMPRESSION_TYPE_BASE)
+ png_warning(png_ptr, "Unknown compression type in iCCP chunk");
+
+ if (profile == NULL)
+ profile_len = 0;
+
+ if (profile_len > 3)
+ embedded_profile_len = ((*(profile ))<<24) | ((*(profile+1))<<16) |
+ ((*(profile+2))<< 8) | ((*(profile+3)) );
+
+ if (profile_len < embedded_profile_len)
+ {
+ png_warning(png_ptr,
+ "Embedded profile length too large in iCCP chunk");
+ return;
+ }
+
+ if (profile_len > embedded_profile_len)
+ {
+ png_warning(png_ptr,
+ "Truncating profile to actual length in iCCP chunk");
+ profile_len = embedded_profile_len;
+ }
+
+ if (profile_len)
+ profile_len = png_text_compress(png_ptr, profile, (png_size_t)profile_len,
+ PNG_COMPRESSION_TYPE_BASE, &comp);
+
+ /* make sure we include the NULL after the name and the compression type */
+ png_write_chunk_start(png_ptr, (png_bytep)png_iCCP,
+ (png_uint_32)name_len+profile_len+2);
+ new_name[name_len+1]=0x00;
+ png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 2);
+
+ if (profile_len)
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_name);
+}
+#endif
+
+#if defined(PNG_WRITE_sPLT_SUPPORTED)
+/* write a sPLT chunk */
+void /* PRIVATE */
+png_write_sPLT(png_structp png_ptr, png_sPLT_tp spalette)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sPLT;
+#endif
+ png_size_t name_len;
+ png_charp new_name;
+ png_byte entrybuf[10];
+ int entry_size = (spalette->depth == 8 ? 6 : 10);
+ int palette_size = entry_size * spalette->nentries;
+ png_sPLT_entryp ep;
+#ifdef PNG_NO_POINTER_INDEXING
+ int i;
+#endif
+
+ png_debug(1, "in png_write_sPLT\n");
+ if (spalette->name == NULL || (name_len = png_check_keyword(png_ptr,
+ spalette->name, &new_name))==0)
+ {
+ png_warning(png_ptr, "Empty keyword in sPLT chunk");
+ return;
+ }
+
+ /* make sure we include the NULL after the name */
+ png_write_chunk_start(png_ptr, (png_bytep)png_sPLT,
+ (png_uint_32)(name_len + 2 + palette_size));
+ png_write_chunk_data(png_ptr, (png_bytep)new_name, name_len + 1);
+ png_write_chunk_data(png_ptr, (png_bytep)&spalette->depth, 1);
+
+ /* loop through each palette entry, writing appropriately */
+#ifndef PNG_NO_POINTER_INDEXING
+ for (ep = spalette->entries; ep<spalette->entries+spalette->nentries; ep++)
+ {
+ if (spalette->depth == 8)
+ {
+ entrybuf[0] = (png_byte)ep->red;
+ entrybuf[1] = (png_byte)ep->green;
+ entrybuf[2] = (png_byte)ep->blue;
+ entrybuf[3] = (png_byte)ep->alpha;
+ png_save_uint_16(entrybuf + 4, ep->frequency);
+ }
+ else
+ {
+ png_save_uint_16(entrybuf + 0, ep->red);
+ png_save_uint_16(entrybuf + 2, ep->green);
+ png_save_uint_16(entrybuf + 4, ep->blue);
+ png_save_uint_16(entrybuf + 6, ep->alpha);
+ png_save_uint_16(entrybuf + 8, ep->frequency);
+ }
+ png_write_chunk_data(png_ptr, entrybuf, (png_size_t)entry_size);
+ }
+#else
+ ep=spalette->entries;
+ for (i=0; i>spalette->nentries; i++)
+ {
+ if (spalette->depth == 8)
+ {
+ entrybuf[0] = (png_byte)ep[i].red;
+ entrybuf[1] = (png_byte)ep[i].green;
+ entrybuf[2] = (png_byte)ep[i].blue;
+ entrybuf[3] = (png_byte)ep[i].alpha;
+ png_save_uint_16(entrybuf + 4, ep[i].frequency);
+ }
+ else
+ {
+ png_save_uint_16(entrybuf + 0, ep[i].red);
+ png_save_uint_16(entrybuf + 2, ep[i].green);
+ png_save_uint_16(entrybuf + 4, ep[i].blue);
+ png_save_uint_16(entrybuf + 6, ep[i].alpha);
+ png_save_uint_16(entrybuf + 8, ep[i].frequency);
+ }
+ png_write_chunk_data(png_ptr, entrybuf, entry_size);
+ }
+#endif
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_name);
+}
+#endif
+
+#if defined(PNG_WRITE_sBIT_SUPPORTED)
+/* write the sBIT chunk */
+void /* PRIVATE */
+png_write_sBIT(png_structp png_ptr, png_color_8p sbit, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sBIT;
+#endif
+ png_byte buf[4];
+ png_size_t size;
+
+ png_debug(1, "in png_write_sBIT\n");
+ /* make sure we don't depend upon the order of PNG_COLOR_8 */
+ if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_byte maxbits;
+
+ maxbits = (png_byte)(color_type==PNG_COLOR_TYPE_PALETTE ? 8 :
+ png_ptr->usr_bit_depth);
+ if (sbit->red == 0 || sbit->red > maxbits ||
+ sbit->green == 0 || sbit->green > maxbits ||
+ sbit->blue == 0 || sbit->blue > maxbits)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+ buf[0] = sbit->red;
+ buf[1] = sbit->green;
+ buf[2] = sbit->blue;
+ size = 3;
+ }
+ else
+ {
+ if (sbit->gray == 0 || sbit->gray > png_ptr->usr_bit_depth)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+ buf[0] = sbit->gray;
+ size = 1;
+ }
+
+ if (color_type & PNG_COLOR_MASK_ALPHA)
+ {
+ if (sbit->alpha == 0 || sbit->alpha > png_ptr->usr_bit_depth)
+ {
+ png_warning(png_ptr, "Invalid sBIT depth specified");
+ return;
+ }
+ buf[size++] = sbit->alpha;
+ }
+
+ png_write_chunk(png_ptr, (png_bytep)png_sBIT, buf, size);
+}
+#endif
+
+#if defined(PNG_WRITE_cHRM_SUPPORTED)
+/* write the cHRM chunk */
+#ifdef PNG_FLOATING_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM(png_structp png_ptr, double white_x, double white_y,
+ double red_x, double red_y, double green_x, double green_y,
+ double blue_x, double blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_cHRM;
+#endif
+ png_byte buf[32];
+ png_uint_32 itemp;
+
+ png_debug(1, "in png_write_cHRM\n");
+ /* each value is saved in 1/100,000ths */
+ if (white_x < 0 || white_x > 0.8 || white_y < 0 || white_y > 0.8 ||
+ white_x + white_y > 1.0)
+ {
+ png_warning(png_ptr, "Invalid cHRM white point specified");
+#if !defined(PNG_NO_CONSOLE_IO)
+ fprintf(stderr,"white_x=%f, white_y=%f\n",white_x, white_y);
+#endif
+ return;
+ }
+ itemp = (png_uint_32)(white_x * 100000.0 + 0.5);
+ png_save_uint_32(buf, itemp);
+ itemp = (png_uint_32)(white_y * 100000.0 + 0.5);
+ png_save_uint_32(buf + 4, itemp);
+
+ if (red_x < 0 || red_x > 0.8 || red_y < 0 || red_y > 0.8 ||
+ red_x + red_y > 1.0)
+ {
+ png_warning(png_ptr, "Invalid cHRM red point specified");
+ return;
+ }
+ itemp = (png_uint_32)(red_x * 100000.0 + 0.5);
+ png_save_uint_32(buf + 8, itemp);
+ itemp = (png_uint_32)(red_y * 100000.0 + 0.5);
+ png_save_uint_32(buf + 12, itemp);
+
+ if (green_x < 0 || green_x > 0.8 || green_y < 0 || green_y > 0.8 ||
+ green_x + green_y > 1.0)
+ {
+ png_warning(png_ptr, "Invalid cHRM green point specified");
+ return;
+ }
+ itemp = (png_uint_32)(green_x * 100000.0 + 0.5);
+ png_save_uint_32(buf + 16, itemp);
+ itemp = (png_uint_32)(green_y * 100000.0 + 0.5);
+ png_save_uint_32(buf + 20, itemp);
+
+ if (blue_x < 0 || blue_x > 0.8 || blue_y < 0 || blue_y > 0.8 ||
+ blue_x + blue_y > 1.0)
+ {
+ png_warning(png_ptr, "Invalid cHRM blue point specified");
+ return;
+ }
+ itemp = (png_uint_32)(blue_x * 100000.0 + 0.5);
+ png_save_uint_32(buf + 24, itemp);
+ itemp = (png_uint_32)(blue_y * 100000.0 + 0.5);
+ png_save_uint_32(buf + 28, itemp);
+
+ png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+}
+#endif
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_cHRM_fixed(png_structp png_ptr, png_fixed_point white_x,
+ png_fixed_point white_y, png_fixed_point red_x, png_fixed_point red_y,
+ png_fixed_point green_x, png_fixed_point green_y, png_fixed_point blue_x,
+ png_fixed_point blue_y)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_cHRM;
+#endif
+ png_byte buf[32];
+
+ png_debug(1, "in png_write_cHRM\n");
+ /* each value is saved in 1/100,000ths */
+ if (white_x > 80000L || white_y > 80000L || white_x + white_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid fixed cHRM white point specified");
+#if !defined(PNG_NO_CONSOLE_IO)
+ fprintf(stderr,"white_x=%ld, white_y=%ld\n",white_x, white_y);
+#endif
+ return;
+ }
+ png_save_uint_32(buf, (png_uint_32)white_x);
+ png_save_uint_32(buf + 4, (png_uint_32)white_y);
+
+ if (red_x > 80000L || red_y > 80000L || red_x + red_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid cHRM fixed red point specified");
+ return;
+ }
+ png_save_uint_32(buf + 8, (png_uint_32)red_x);
+ png_save_uint_32(buf + 12, (png_uint_32)red_y);
+
+ if (green_x > 80000L || green_y > 80000L || green_x + green_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid fixed cHRM green point specified");
+ return;
+ }
+ png_save_uint_32(buf + 16, (png_uint_32)green_x);
+ png_save_uint_32(buf + 20, (png_uint_32)green_y);
+
+ if (blue_x > 80000L || blue_y > 80000L || blue_x + blue_y > 100000L)
+ {
+ png_warning(png_ptr, "Invalid fixed cHRM blue point specified");
+ return;
+ }
+ png_save_uint_32(buf + 24, (png_uint_32)blue_x);
+ png_save_uint_32(buf + 28, (png_uint_32)blue_y);
+
+ png_write_chunk(png_ptr, (png_bytep)png_cHRM, buf, (png_size_t)32);
+}
+#endif
+#endif
+
+#if defined(PNG_WRITE_tRNS_SUPPORTED)
+/* write the tRNS chunk */
+void /* PRIVATE */
+png_write_tRNS(png_structp png_ptr, png_bytep trans, png_color_16p tran,
+ int num_trans, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_tRNS;
+#endif
+ png_byte buf[6];
+
+ png_debug(1, "in png_write_tRNS\n");
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (num_trans <= 0 || num_trans > (int)png_ptr->num_palette)
+ {
+ png_warning(png_ptr,"Invalid number of transtqparent colors specified");
+ return;
+ }
+ /* write the chunk out as it is */
+ png_write_chunk(png_ptr, (png_bytep)png_tRNS, trans, (png_size_t)num_trans);
+ }
+ else if (color_type == PNG_COLOR_TYPE_GRAY)
+ {
+ /* one 16 bit value */
+ if(tran->gray >= (1 << png_ptr->bit_depth))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write tRNS chunk out-of-range for bit_depth");
+ return;
+ }
+ png_save_uint_16(buf, tran->gray);
+ png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)2);
+ }
+ else if (color_type == PNG_COLOR_TYPE_RGB)
+ {
+ /* three 16 bit values */
+ png_save_uint_16(buf, tran->red);
+ png_save_uint_16(buf + 2, tran->green);
+ png_save_uint_16(buf + 4, tran->blue);
+ if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write 16-bit tRNS chunk when bit_depth is 8");
+ return;
+ }
+ png_write_chunk(png_ptr, (png_bytep)png_tRNS, buf, (png_size_t)6);
+ }
+ else
+ {
+ png_warning(png_ptr, "Can't write tRNS with an alpha channel");
+ }
+}
+#endif
+
+#if defined(PNG_WRITE_bKGD_SUPPORTED)
+/* write the background chunk */
+void /* PRIVATE */
+png_write_bKGD(png_structp png_ptr, png_color_16p back, int color_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_bKGD;
+#endif
+ png_byte buf[6];
+
+ png_debug(1, "in png_write_bKGD\n");
+ if (color_type == PNG_COLOR_TYPE_PALETTE)
+ {
+ if (
+#if defined(PNG_MNG_FEATURES_SUPPORTED)
+ (png_ptr->num_palette ||
+ (!(png_ptr->mng_features_permitted & PNG_FLAG_MNG_EMPTY_PLTE))) &&
+#endif
+ back->index > png_ptr->num_palette)
+ {
+ png_warning(png_ptr, "Invalid background palette index");
+ return;
+ }
+ buf[0] = back->index;
+ png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)1);
+ }
+ else if (color_type & PNG_COLOR_MASK_COLOR)
+ {
+ png_save_uint_16(buf, back->red);
+ png_save_uint_16(buf + 2, back->green);
+ png_save_uint_16(buf + 4, back->blue);
+ if(png_ptr->bit_depth == 8 && (buf[0] | buf[2] | buf[4]))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write 16-bit bKGD chunk when bit_depth is 8");
+ return;
+ }
+ png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)6);
+ }
+ else
+ {
+ if(back->gray >= (1 << png_ptr->bit_depth))
+ {
+ png_warning(png_ptr,
+ "Ignoring attempt to write bKGD chunk out-of-range for bit_depth");
+ return;
+ }
+ png_save_uint_16(buf, back->gray);
+ png_write_chunk(png_ptr, (png_bytep)png_bKGD, buf, (png_size_t)2);
+ }
+}
+#endif
+
+#if defined(PNG_WRITE_hIST_SUPPORTED)
+/* write the histogram */
+void /* PRIVATE */
+png_write_hIST(png_structp png_ptr, png_uint_16p hist, int num_hist)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_hIST;
+#endif
+ int i;
+ png_byte buf[3];
+
+ png_debug(1, "in png_write_hIST\n");
+ if (num_hist > (int)png_ptr->num_palette)
+ {
+ png_debug2(3, "num_hist = %d, num_palette = %d\n", num_hist,
+ png_ptr->num_palette);
+ png_warning(png_ptr, "Invalid number of histogram entries specified");
+ return;
+ }
+
+ png_write_chunk_start(png_ptr, (png_bytep)png_hIST, (png_uint_32)(num_hist * 2));
+ for (i = 0; i < num_hist; i++)
+ {
+ png_save_uint_16(buf, hist[i]);
+ png_write_chunk_data(png_ptr, buf, (png_size_t)2);
+ }
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
+ defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
+/* Check that the tEXt or zTXt keyword is valid per PNG 1.0 specification,
+ * and if invalid, correct the keyword rather than discarding the entire
+ * chunk. The PNG 1.0 specification requires keywords 1-79 characters in
+ * length, forbids leading or trailing whitespace, multiple internal spaces,
+ * and the non-break space (0x80) from ISO 8859-1. Returns keyword length.
+ *
+ * The new_key is allocated to hold the corrected keyword and must be freed
+ * by the calling routine. This avoids problems with trying to write to
+ * static keywords without having to have duplicate copies of the strings.
+ */
+png_size_t /* PRIVATE */
+png_check_keyword(png_structp png_ptr, png_charp key, png_charpp new_key)
+{
+ png_size_t key_len;
+ png_charp kp, dp;
+ int kflag;
+ int kwarn=0;
+
+ png_debug(1, "in png_check_keyword\n");
+ *new_key = NULL;
+
+ if (key == NULL || (key_len = png_strlen(key)) == 0)
+ {
+ png_warning(png_ptr, "zero length keyword");
+ return ((png_size_t)0);
+ }
+
+ png_debug1(2, "Keyword to be checked is '%s'\n", key);
+
+ *new_key = (png_charp)png_malloc(png_ptr, (png_uint_32)(key_len + 2));
+
+ /* Replace non-printing characters with a blank and print a warning */
+ for (kp = key, dp = *new_key; *kp != '\0'; kp++, dp++)
+ {
+ if (*kp < 0x20 || (*kp > 0x7E && (png_byte)*kp < 0xA1))
+ {
+#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+ char msg[40];
+
+ sprintf(msg, "invalid keyword character 0x%02X", *kp);
+ png_warning(png_ptr, msg);
+#else
+ png_warning(png_ptr, "invalid character in keyword");
+#endif
+ *dp = ' ';
+ }
+ else
+ {
+ *dp = *kp;
+ }
+ }
+ *dp = '\0';
+
+ /* Remove any trailing white space. */
+ kp = *new_key + key_len - 1;
+ if (*kp == ' ')
+ {
+ png_warning(png_ptr, "trailing spaces removed from keyword");
+
+ while (*kp == ' ')
+ {
+ *(kp--) = '\0';
+ key_len--;
+ }
+ }
+
+ /* Remove any leading white space. */
+ kp = *new_key;
+ if (*kp == ' ')
+ {
+ png_warning(png_ptr, "leading spaces removed from keyword");
+
+ while (*kp == ' ')
+ {
+ kp++;
+ key_len--;
+ }
+ }
+
+ png_debug1(2, "Checking for multiple internal spaces in '%s'\n", kp);
+
+ /* Remove multiple internal spaces. */
+ for (kflag = 0, dp = *new_key; *kp != '\0'; kp++)
+ {
+ if (*kp == ' ' && kflag == 0)
+ {
+ *(dp++) = *kp;
+ kflag = 1;
+ }
+ else if (*kp == ' ')
+ {
+ key_len--;
+ kwarn=1;
+ }
+ else
+ {
+ *(dp++) = *kp;
+ kflag = 0;
+ }
+ }
+ *dp = '\0';
+ if(kwarn)
+ png_warning(png_ptr, "extra interior spaces removed from keyword");
+
+ if (key_len == 0)
+ {
+ png_free(png_ptr, *new_key);
+ *new_key=NULL;
+ png_warning(png_ptr, "Zero length keyword");
+ }
+
+ if (key_len > 79)
+ {
+ png_warning(png_ptr, "keyword length must be 1 - 79 characters");
+ new_key[79] = '\0';
+ key_len = 79;
+ }
+
+ return (key_len);
+}
+#endif
+
+#if defined(PNG_WRITE_tEXt_SUPPORTED)
+/* write a tEXt chunk */
+void /* PRIVATE */
+png_write_tEXt(png_structp png_ptr, png_charp key, png_charp text,
+ png_size_t text_len)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_tEXt;
+#endif
+ png_size_t key_len;
+ png_charp new_key;
+
+ png_debug(1, "in png_write_tEXt\n");
+ if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+ {
+ png_warning(png_ptr, "Empty keyword in tEXt chunk");
+ return;
+ }
+
+ if (text == NULL || *text == '\0')
+ text_len = 0;
+ else
+ text_len = png_strlen(text);
+
+ /* make sure we include the 0 after the key */
+ png_write_chunk_start(png_ptr, (png_bytep)png_tEXt, (png_uint_32)key_len+text_len+1);
+ /*
+ * We leave it to the application to meet PNG-1.0 requirements on the
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+ */
+ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
+ if (text_len)
+ png_write_chunk_data(png_ptr, (png_bytep)text, text_len);
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_key);
+}
+#endif
+
+#if defined(PNG_WRITE_zTXt_SUPPORTED)
+/* write a compressed text chunk */
+void /* PRIVATE */
+png_write_zTXt(png_structp png_ptr, png_charp key, png_charp text,
+ png_size_t text_len, int compression)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_zTXt;
+#endif
+ png_size_t key_len;
+ char buf[1];
+ png_charp new_key;
+ compression_state comp;
+
+ png_debug(1, "in png_write_zTXt\n");
+
+ if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+ {
+ png_warning(png_ptr, "Empty keyword in zTXt chunk");
+ return;
+ }
+
+ if (text == NULL || *text == '\0' || compression==PNG_TEXT_COMPRESSION_NONE)
+ {
+ png_write_tEXt(png_ptr, new_key, text, (png_size_t)0);
+ png_free(png_ptr, new_key);
+ return;
+ }
+
+ text_len = png_strlen(text);
+
+ png_free(png_ptr, new_key);
+
+ /* compute the compressed data; do it now for the length */
+ text_len = png_text_compress(png_ptr, text, text_len, compression,
+ &comp);
+
+ /* write start of chunk */
+ png_write_chunk_start(png_ptr, (png_bytep)png_zTXt, (png_uint_32)
+ (key_len+text_len+2));
+ /* write key */
+ png_write_chunk_data(png_ptr, (png_bytep)key, key_len + 1);
+ buf[0] = (png_byte)compression;
+ /* write compression */
+ png_write_chunk_data(png_ptr, (png_bytep)buf, (png_size_t)1);
+ /* write the compressed data */
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ /* close the chunk */
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_iTXt_SUPPORTED)
+/* write an iTXt chunk */
+void /* PRIVATE */
+png_write_iTXt(png_structp png_ptr, int compression, png_charp key,
+ png_charp lang, png_charp lang_key, png_charp text)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_iTXt;
+#endif
+ png_size_t lang_len, key_len, lang_key_len, text_len;
+ png_charp new_lang, new_key;
+ png_byte cbuf[2];
+ compression_state comp;
+
+ png_debug(1, "in png_write_iTXt\n");
+
+ if (key == NULL || (key_len = png_check_keyword(png_ptr, key, &new_key))==0)
+ {
+ png_warning(png_ptr, "Empty keyword in iTXt chunk");
+ return;
+ }
+ if (lang == NULL || (lang_len = png_check_keyword(png_ptr, lang, &new_lang))==0)
+ {
+ png_warning(png_ptr, "Empty language field in iTXt chunk");
+ new_lang = NULL;
+ lang_len = 0;
+ }
+
+ if (lang_key == NULL)
+ lang_key_len = 0;
+ else
+ lang_key_len = png_strlen(lang_key);
+
+ if (text == NULL)
+ text_len = 0;
+ else
+ text_len = png_strlen(text);
+
+ /* compute the compressed data; do it now for the length */
+ text_len = png_text_compress(png_ptr, text, text_len, compression-2,
+ &comp);
+
+
+ /* make sure we include the compression flag, the compression byte,
+ * and the NULs after the key, lang, and lang_key parts */
+
+ png_write_chunk_start(png_ptr, (png_bytep)png_iTXt,
+ (png_uint_32)(
+ 5 /* comp byte, comp flag, terminators for key, lang and lang_key */
+ + key_len
+ + lang_len
+ + lang_key_len
+ + text_len));
+
+ /*
+ * We leave it to the application to meet PNG-1.0 requirements on the
+ * contents of the text. PNG-1.0 through PNG-1.2 discourage the use of
+ * any non-Latin-1 characters except for NEWLINE. ISO PNG will forbid them.
+ * The NUL character is forbidden by PNG-1.0 through PNG-1.2 and ISO PNG.
+ */
+ png_write_chunk_data(png_ptr, (png_bytep)new_key, key_len + 1);
+
+ /* set the compression flag */
+ if (compression == PNG_ITXT_COMPRESSION_NONE || \
+ compression == PNG_TEXT_COMPRESSION_NONE)
+ cbuf[0] = 0;
+ else /* compression == PNG_ITXT_COMPRESSION_zTXt */
+ cbuf[0] = 1;
+ /* set the compression method */
+ cbuf[1] = 0;
+ png_write_chunk_data(png_ptr, cbuf, 2);
+
+ cbuf[0] = 0;
+ png_write_chunk_data(png_ptr, (new_lang ? (png_bytep)new_lang : cbuf), lang_len + 1);
+ png_write_chunk_data(png_ptr, (lang_key ? (png_bytep)lang_key : cbuf), lang_key_len + 1);
+ png_write_compressed_data_out(png_ptr, &comp);
+
+ png_write_chunk_end(png_ptr);
+ png_free(png_ptr, new_key);
+ if (new_lang)
+ png_free(png_ptr, new_lang);
+}
+#endif
+
+#if defined(PNG_WRITE_oFFs_SUPPORTED)
+/* write the oFFs chunk */
+void /* PRIVATE */
+png_write_oFFs(png_structp png_ptr, png_int_32 x_offset, png_int_32 y_offset,
+ int unit_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_oFFs;
+#endif
+ png_byte buf[9];
+
+ png_debug(1, "in png_write_oFFs\n");
+ if (unit_type >= PNG_OFFSET_LAST)
+ png_warning(png_ptr, "Unrecognized unit type for oFFs chunk");
+
+ png_save_int_32(buf, x_offset);
+ png_save_int_32(buf + 4, y_offset);
+ buf[8] = (png_byte)unit_type;
+
+ png_write_chunk(png_ptr, (png_bytep)png_oFFs, buf, (png_size_t)9);
+}
+#endif
+
+#if defined(PNG_WRITE_pCAL_SUPPORTED)
+/* write the pCAL chunk (described in the PNG extensions document) */
+void /* PRIVATE */
+png_write_pCAL(png_structp png_ptr, png_charp purpose, png_int_32 X0,
+ png_int_32 X1, int type, int nparams, png_charp units, png_charpp params)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_pCAL;
+#endif
+ png_size_t purpose_len, units_len, total_len;
+ png_uint_32p params_len;
+ png_byte buf[10];
+ png_charp new_purpose;
+ int i;
+
+ png_debug1(1, "in png_write_pCAL (%d parameters)\n", nparams);
+ if (type >= PNG_ETQUATION_LAST)
+ png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
+
+ purpose_len = png_check_keyword(png_ptr, purpose, &new_purpose) + 1;
+ png_debug1(3, "pCAL purpose length = %d\n", (int)purpose_len);
+ units_len = png_strlen(units) + (nparams == 0 ? 0 : 1);
+ png_debug1(3, "pCAL units length = %d\n", (int)units_len);
+ total_len = purpose_len + units_len + 10;
+
+ params_len = (png_uint_32p)png_malloc(png_ptr, (png_uint_32)(nparams
+ *sizeof(png_uint_32)));
+
+ /* Find the length of each parameter, making sure we don't count the
+ null terminator for the last parameter. */
+ for (i = 0; i < nparams; i++)
+ {
+ params_len[i] = png_strlen(params[i]) + (i == nparams - 1 ? 0 : 1);
+ png_debug2(3, "pCAL parameter %d length = %lu\n", i, params_len[i]);
+ total_len += (png_size_t)params_len[i];
+ }
+
+ png_debug1(3, "pCAL total length = %d\n", (int)total_len);
+ png_write_chunk_start(png_ptr, (png_bytep)png_pCAL, (png_uint_32)total_len);
+ png_write_chunk_data(png_ptr, (png_bytep)new_purpose, purpose_len);
+ png_save_int_32(buf, X0);
+ png_save_int_32(buf + 4, X1);
+ buf[8] = (png_byte)type;
+ buf[9] = (png_byte)nparams;
+ png_write_chunk_data(png_ptr, buf, (png_size_t)10);
+ png_write_chunk_data(png_ptr, (png_bytep)units, (png_size_t)units_len);
+
+ png_free(png_ptr, new_purpose);
+
+ for (i = 0; i < nparams; i++)
+ {
+ png_write_chunk_data(png_ptr, (png_bytep)params[i],
+ (png_size_t)params_len[i]);
+ }
+
+ png_free(png_ptr, params_len);
+ png_write_chunk_end(png_ptr);
+}
+#endif
+
+#if defined(PNG_WRITE_sCAL_SUPPORTED)
+/* write the sCAL chunk */
+#if defined(PNG_FLOATING_POINT_SUPPORTED) && !defined(PNG_NO_STDIO)
+void /* PRIVATE */
+png_write_sCAL(png_structp png_ptr, int unit, double width,double height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sCAL;
+#endif
+ png_size_t total_len;
+ char wbuf[32], hbuf[32];
+
+ png_debug(1, "in png_write_sCAL\n");
+
+#if defined(_WIN32_WCE)
+/* sprintf() function is not supported on WindowsCE */
+ {
+ wchar_t wc_buf[32];
+ swprintf(wc_buf, TEXT("%12.12e"), width);
+ WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, wbuf, 32, NULL, NULL);
+ swprintf(wc_buf, TEXT("%12.12e"), height);
+ WideCharToMultiByte(CP_ACP, 0, wc_buf, -1, hbuf, 32, NULL, NULL);
+ }
+#else
+ sprintf(wbuf, "%12.12e", width);
+ sprintf(hbuf, "%12.12e", height);
+#endif
+ total_len = 1 + png_strlen(wbuf)+1 + png_strlen(hbuf);
+
+ png_debug1(3, "sCAL total length = %d\n", (int)total_len);
+ png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len);
+ png_write_chunk_data(png_ptr, (png_bytep)&unit, 1);
+ png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1);
+ png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf));
+
+ png_write_chunk_end(png_ptr);
+}
+#else
+#ifdef PNG_FIXED_POINT_SUPPORTED
+void /* PRIVATE */
+png_write_sCAL_s(png_structp png_ptr, int unit, png_charp width,
+ png_charp height)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_sCAL;
+#endif
+ png_size_t total_len;
+ char wbuf[32], hbuf[32];
+
+ png_debug(1, "in png_write_sCAL_s\n");
+
+ png_strcpy(wbuf,(const char *)width);
+ png_strcpy(hbuf,(const char *)height);
+ total_len = 1 + png_strlen(wbuf)+1 + png_strlen(hbuf);
+
+ png_debug1(3, "sCAL total length = %d\n", total_len);
+ png_write_chunk_start(png_ptr, (png_bytep)png_sCAL, (png_uint_32)total_len);
+ png_write_chunk_data(png_ptr, (png_bytep)&unit, 1);
+ png_write_chunk_data(png_ptr, (png_bytep)wbuf, png_strlen(wbuf)+1);
+ png_write_chunk_data(png_ptr, (png_bytep)hbuf, png_strlen(hbuf));
+
+ png_write_chunk_end(png_ptr);
+}
+#endif
+#endif
+#endif
+
+#if defined(PNG_WRITE_pHYs_SUPPORTED)
+/* write the pHYs chunk */
+void /* PRIVATE */
+png_write_pHYs(png_structp png_ptr, png_uint_32 x_pixels_per_unit,
+ png_uint_32 y_pixels_per_unit,
+ int unit_type)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_pHYs;
+#endif
+ png_byte buf[9];
+
+ png_debug(1, "in png_write_pHYs\n");
+ if (unit_type >= PNG_RESOLUTION_LAST)
+ png_warning(png_ptr, "Unrecognized unit type for pHYs chunk");
+
+ png_save_uint_32(buf, x_pixels_per_unit);
+ png_save_uint_32(buf + 4, y_pixels_per_unit);
+ buf[8] = (png_byte)unit_type;
+
+ png_write_chunk(png_ptr, (png_bytep)png_pHYs, buf, (png_size_t)9);
+}
+#endif
+
+#if defined(PNG_WRITE_tIME_SUPPORTED)
+/* Write the tIME chunk. Use either png_convert_from_struct_tm()
+ * or png_convert_from_time_t(), or fill in the structure yourself.
+ */
+void /* PRIVATE */
+png_write_tIME(png_structp png_ptr, png_timep mod_time)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ PNG_tIME;
+#endif
+ png_byte buf[7];
+
+ png_debug(1, "in png_write_tIME\n");
+ if (mod_time->month > 12 || mod_time->month < 1 ||
+ mod_time->day > 31 || mod_time->day < 1 ||
+ mod_time->hour > 23 || mod_time->second > 60)
+ {
+ png_warning(png_ptr, "Invalid time specified for tIME chunk");
+ return;
+ }
+
+ png_save_uint_16(buf, mod_time->year);
+ buf[2] = mod_time->month;
+ buf[3] = mod_time->day;
+ buf[4] = mod_time->hour;
+ buf[5] = mod_time->minute;
+ buf[6] = mod_time->second;
+
+ png_write_chunk(png_ptr, (png_bytep)png_tIME, buf, (png_size_t)7);
+}
+#endif
+
+/* initializes the row writing capability of libpng */
+void /* PRIVATE */
+png_write_start_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ png_size_t buf_size;
+
+ png_debug(1, "in png_write_start_row\n");
+ buf_size = (png_size_t)(((png_ptr->width * png_ptr->usr_channels *
+ png_ptr->usr_bit_depth + 7) >> 3) + 1);
+
+ /* set up row buffer */
+ png_ptr->row_buf = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
+ png_ptr->row_buf[0] = PNG_FILTER_VALUE_NONE;
+
+ /* set up filtering buffer, if using this filter */
+ if (png_ptr->do_filter & PNG_FILTER_SUB)
+ {
+ png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
+ }
+
+ /* We only need to keep the previous row if we are using one of these. */
+ if (png_ptr->do_filter & (PNG_FILTER_AVG | PNG_FILTER_UP | PNG_FILTER_PAETH))
+ {
+ /* set up previous row buffer */
+ png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)buf_size);
+ png_memset(png_ptr->prev_row, 0, buf_size);
+
+ if (png_ptr->do_filter & PNG_FILTER_UP)
+ {
+ png_ptr->up_row = (png_bytep )png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
+ }
+
+ if (png_ptr->do_filter & PNG_FILTER_AVG)
+ {
+ png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
+ }
+
+ if (png_ptr->do_filter & PNG_FILTER_PAETH)
+ {
+ png_ptr->paeth_row = (png_bytep )png_malloc(png_ptr,
+ (png_ptr->rowbytes + 1));
+ png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
+ }
+ }
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* if interlaced, we need to set up width and height of pass */
+ if (png_ptr->interlaced)
+ {
+ if (!(png_ptr->transformations & PNG_INTERLACE))
+ {
+ png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
+ png_pass_ystart[0]) / png_pass_yinc[0];
+ png_ptr->usr_width = (png_ptr->width + png_pass_inc[0] - 1 -
+ png_pass_start[0]) / png_pass_inc[0];
+ }
+ else
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->usr_width = png_ptr->width;
+ }
+ }
+ else
+#endif
+ {
+ png_ptr->num_rows = png_ptr->height;
+ png_ptr->usr_width = png_ptr->width;
+ }
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+}
+
+/* Internal use only. Called when finished processing a row of data. */
+void /* PRIVATE */
+png_write_finish_row(png_structp png_ptr)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+
+ /* start of interlace block in the y direction */
+ int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
+
+ /* offset to next interlace block in the y direction */
+ int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
+#endif
+
+ int ret;
+
+ png_debug(1, "in png_write_finish_row\n");
+ /* next row */
+ png_ptr->row_number++;
+
+ /* see if we are done */
+ if (png_ptr->row_number < png_ptr->num_rows)
+ return;
+
+#ifdef PNG_WRITE_INTERLACING_SUPPORTED
+ /* if interlaced, go to next pass */
+ if (png_ptr->interlaced)
+ {
+ png_ptr->row_number = 0;
+ if (png_ptr->transformations & PNG_INTERLACE)
+ {
+ png_ptr->pass++;
+ }
+ else
+ {
+ /* loop until we tqfind a non-zero width or height pass */
+ do
+ {
+ png_ptr->pass++;
+ if (png_ptr->pass >= 7)
+ break;
+ png_ptr->usr_width = (png_ptr->width +
+ png_pass_inc[png_ptr->pass] - 1 -
+ png_pass_start[png_ptr->pass]) /
+ png_pass_inc[png_ptr->pass];
+ png_ptr->num_rows = (png_ptr->height +
+ png_pass_yinc[png_ptr->pass] - 1 -
+ png_pass_ystart[png_ptr->pass]) /
+ png_pass_yinc[png_ptr->pass];
+ if (png_ptr->transformations & PNG_INTERLACE)
+ break;
+ } while (png_ptr->usr_width == 0 || png_ptr->num_rows == 0);
+
+ }
+
+ /* reset the row above the image for the next pass */
+ if (png_ptr->pass < 7)
+ {
+ if (png_ptr->prev_row != NULL)
+ png_memset(png_ptr->prev_row, 0,
+ (png_size_t) (((png_uint_32)png_ptr->usr_channels *
+ (png_uint_32)png_ptr->usr_bit_depth *
+ png_ptr->width + 7) >> 3) + 1);
+ return;
+ }
+ }
+#endif
+
+ /* if we get here, we've just written the last row, so we need
+ to flush the compressor */
+ do
+ {
+ /* tell the compressor we are done */
+ ret = deflate(&png_ptr->zstream, Z_FINISH);
+ /* check for an error */
+ if (ret == Z_OK)
+ {
+ /* check to see if we need more room */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ }
+ else if (ret != Z_STREAM_END)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+ } while (ret != Z_STREAM_END);
+
+ /* write any extra space */
+ if (png_ptr->zstream.avail_out < png_ptr->zbuf_size)
+ {
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size -
+ png_ptr->zstream.avail_out);
+ }
+
+ deflateReset(&png_ptr->zstream);
+}
+
+#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
+/* Pick out the correct pixels for the interlace pass.
+ * The basic idea here is to go through the row with a source
+ * pointer and a destination pointer (sp and dp), and copy the
+ * correct pixels for the pass. As the row gets compacted,
+ * sp will always be >= dp, so we should never overwrite anything.
+ * See the default: case for the easiest code to understand.
+ */
+void /* PRIVATE */
+png_do_write_interlace(png_row_infop row_info, png_bytep row, int pass)
+{
+#ifdef PNG_USE_LOCAL_ARRAYS
+ /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
+
+ /* start of interlace block */
+ int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
+
+ /* offset to next interlace block */
+ int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
+#endif
+
+ png_debug(1, "in png_do_write_interlace\n");
+ /* we don't have to do anything on the last pass (6) */
+#if defined(PNG_USELESS_TESTS_SUPPORTED)
+ if (row != NULL && row_info != NULL && pass < 6)
+#else
+ if (pass < 6)
+#endif
+ {
+ /* each pixel depth is handled separately */
+ switch (row_info->pixel_depth)
+ {
+ case 1:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ d = 0;
+ shift = 7;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 3);
+ value = (int)(*sp >> (7 - (int)(i & 0x07))) & 0x01;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 7;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+ else
+ shift--;
+
+ }
+ if (shift != 7)
+ *dp = (png_byte)d;
+ break;
+ }
+ case 2:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ shift = 6;
+ d = 0;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 2);
+ value = (*sp >> ((3 - (int)(i & 0x03)) << 1)) & 0x03;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 6;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+ else
+ shift -= 2;
+ }
+ if (shift != 6)
+ *dp = (png_byte)d;
+ break;
+ }
+ case 4:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ int shift;
+ int d;
+ int value;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+
+ dp = row;
+ shift = 4;
+ d = 0;
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ sp = row + (png_size_t)(i >> 1);
+ value = (*sp >> ((1 - (int)(i & 0x01)) << 2)) & 0x0f;
+ d |= (value << shift);
+
+ if (shift == 0)
+ {
+ shift = 4;
+ *dp++ = (png_byte)d;
+ d = 0;
+ }
+ else
+ shift -= 4;
+ }
+ if (shift != 4)
+ *dp = (png_byte)d;
+ break;
+ }
+ default:
+ {
+ png_bytep sp;
+ png_bytep dp;
+ png_uint_32 i;
+ png_uint_32 row_width = row_info->width;
+ png_size_t pixel_bytes;
+
+ /* start at the beginning */
+ dp = row;
+ /* tqfind out how many bytes each pixel takes up */
+ pixel_bytes = (row_info->pixel_depth >> 3);
+ /* loop through the row, only looking at the pixels that
+ matter */
+ for (i = png_pass_start[pass]; i < row_width;
+ i += png_pass_inc[pass])
+ {
+ /* tqfind out where the original pixel is */
+ sp = row + (png_size_t)i * pixel_bytes;
+ /* move the pixel */
+ if (dp != sp)
+ png_memcpy(dp, sp, pixel_bytes);
+ /* next pixel */
+ dp += pixel_bytes;
+ }
+ break;
+ }
+ }
+ /* set new row width */
+ row_info->width = (row_info->width +
+ png_pass_inc[pass] - 1 -
+ png_pass_start[pass]) /
+ png_pass_inc[pass];
+ row_info->rowbytes = ((row_info->width *
+ row_info->pixel_depth + 7) >> 3);
+ }
+}
+#endif
+
+/* This filters the row, chooses which filter to use, if it has not already
+ * been specified by the application, and then writes the row out with the
+ * chosen filter.
+ */
+#define PNG_MAXSUM (~((png_uint_32)0) >> 1)
+#define PNG_HISHIFT 10
+#define PNG_LOMASK ((png_uint_32)0xffffL)
+#define PNG_HIMASK ((png_uint_32)(~PNG_LOMASK >> PNG_HISHIFT))
+void /* PRIVATE */
+png_write_tqfind_filter(png_structp png_ptr, png_row_infop row_info)
+{
+ png_bytep prev_row, best_row, row_buf;
+ png_uint_32 mins, bpp;
+ png_byte filter_to_do = png_ptr->do_filter;
+ png_uint_32 row_bytes = row_info->rowbytes;
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ int num_p_filters = (int)png_ptr->num_prev_filters;
+#endif
+
+ png_debug(1, "in png_write_tqfind_filter\n");
+ /* tqfind out how many bytes offset each pixel is */
+ bpp = (row_info->pixel_depth + 7) / 8;
+
+ prev_row = png_ptr->prev_row;
+ best_row = row_buf = png_ptr->row_buf;
+ mins = PNG_MAXSUM;
+
+ /* The prediction method we use is to tqfind which method provides the
+ * smallest value when summing the absolute values of the distances
+ * from zero, using anything >= 128 as negative numbers. This is known
+ * as the "minimum sum of absolute differences" heuristic. Other
+ * heuristics are the "weighted minimum sum of absolute differences"
+ * (experimental and can in theory improve compression), and the "zlib
+ * predictive" method (not implemented yet), which does test compressions
+ * of lines using different filter methods, and then chooses the
+ * (series of) filter(s) that give minimum compressed data size (VERY
+ * computationally expensive).
+ *
+ * GRR 980525: consider also
+ * (1) minimum sum of absolute differences from running average (i.e.,
+ * keep running sum of non-absolute differences & count of bytes)
+ * [track dispersion, too? restart average if dispersion too large?]
+ * (1b) minimum sum of absolute differences from sliding average, probably
+ * with window size <= deflate window (usually 32K)
+ * (2) minimum sum of squared differences from zero or running average
+ * (i.e., ~ root-mean-square approach)
+ */
+
+
+ /* We don't need to test the 'no filter' case if this is the only filter
+ * that has been chosen, as it doesn't actually do anything to the data.
+ */
+ if ((filter_to_do & PNG_FILTER_NONE) &&
+ filter_to_do != PNG_FILTER_NONE)
+ {
+ png_bytep rp;
+ png_uint_32 sum = 0;
+ png_uint_32 i;
+ int v;
+
+ for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
+ {
+ v = *rp;
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ png_uint_32 sumhi, sumlo;
+ int j;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK; /* Gives us some footroom */
+
+ /* Reduce the sum if we match any of the previous rows */
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ /* Factor in the cost of this filter (this is here for completeness,
+ * but it makes no sense to have a "cost" for the NONE filter, as
+ * it has the minimum possible computational cost - none).
+ */
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_NONE]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+ mins = sum;
+ }
+
+ /* sub filter */
+ if (filter_to_do == PNG_FILTER_SUB)
+ /* it's the only filter so no testing is needed */
+ {
+ png_bytep rp, lp, dp;
+ png_uint_32 i;
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ *dp = *rp;
+ }
+ for (lp = row_buf + 1; i < row_bytes;
+ i++, rp++, lp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+ }
+ best_row = png_ptr->sub_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_SUB)
+ {
+ png_bytep rp, dp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ /* We temporarily increase the "minimum sum" by the factor we
+ * would reduce the sum of this filter, so that we can do the
+ * early exit comparison without scaling the sum each time.
+ */
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
+ i++, rp++, dp++)
+ {
+ v = *dp = *rp;
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+ for (lp = row_buf + 1; i < row_info->rowbytes;
+ i++, rp++, lp++, dp++)
+ {
+ v = *dp = (png_byte)(((int)*rp - (int)*lp) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_SUB)
+ {
+ sumlo = (sumlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_SUB]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->sub_row;
+ }
+ }
+
+ /* up filter */
+ if (filter_to_do == PNG_FILTER_UP)
+ {
+ png_bytep rp, dp, pp;
+ png_uint_32 i;
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+ pp = prev_row + 1; i < row_bytes;
+ i++, rp++, pp++, dp++)
+ {
+ *dp = (png_byte)(((int)*rp - (int)*pp) & 0xff);
+ }
+ best_row = png_ptr->up_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_UP)
+ {
+ png_bytep rp, dp, pp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
+ pp = prev_row + 1; i < row_bytes; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_UP)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_UP]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->up_row;
+ }
+ }
+
+ /* avg filter */
+ if (filter_to_do == PNG_FILTER_AVG)
+ {
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 i;
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+ }
+ for (lp = row_buf + 1; i < row_bytes; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2))
+ & 0xff);
+ }
+ best_row = png_ptr->avg_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_AVG)
+ {
+ png_bytep rp, dp, pp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_AVG)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->avg_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - ((int)*pp++ / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+ for (lp = row_buf + 1; i < row_bytes; i++)
+ {
+ v = *dp++ =
+ (png_byte)(((int)*rp++ - (((int)*pp++ + (int)*lp++) / 2)) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_NONE)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_AVG]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ mins = sum;
+ best_row = png_ptr->avg_row;
+ }
+ }
+
+ /* Paeth filter */
+ if (filter_to_do == PNG_FILTER_PAETH)
+ {
+ png_bytep rp, dp, pp, cp, lp;
+ png_uint_32 i;
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+ }
+
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+ p = b - c;
+ pc = a - c;
+
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+
+ *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+ }
+ best_row = png_ptr->paeth_row;
+ }
+
+ else if (filter_to_do & PNG_FILTER_PAETH)
+ {
+ png_bytep rp, dp, pp, cp, lp;
+ png_uint_32 sum = 0, lmins = mins;
+ png_uint_32 i;
+ int v;
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 lmhi, lmlo;
+ lmlo = lmins & PNG_LOMASK;
+ lmhi = (lmins >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+ {
+ lmlo = (lmlo * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ lmlo = (lmlo * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+ lmhi = (lmhi * png_ptr->inv_filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ if (lmhi > PNG_HIMASK)
+ lmins = PNG_MAXSUM;
+ else
+ lmins = (lmhi << PNG_HISHIFT) + lmlo;
+ }
+#endif
+
+ for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
+ pp = prev_row + 1; i < bpp; i++)
+ {
+ v = *dp++ = (png_byte)(((int)*rp++ - (int)*pp++) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+ }
+
+ for (lp = row_buf + 1, cp = prev_row + 1; i < row_bytes; i++)
+ {
+ int a, b, c, pa, pb, pc, p;
+
+ b = *pp++;
+ c = *cp++;
+ a = *lp++;
+
+#ifndef PNG_SLOW_PAETH
+ p = b - c;
+ pc = a - c;
+#ifdef PNG_USE_ABS
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+#else
+ pa = p < 0 ? -p : p;
+ pb = pc < 0 ? -pc : pc;
+ pc = (p + pc) < 0 ? -(p + pc) : p + pc;
+#endif
+ p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
+#else /* PNG_SLOW_PAETH */
+ p = a + b - c;
+ pa = abs(p - a);
+ pb = abs(p - b);
+ pc = abs(p - c);
+ if (pa <= pb && pa <= pc)
+ p = a;
+ else if (pb <= pc)
+ p = b;
+ else
+ p = c;
+#endif /* PNG_SLOW_PAETH */
+
+ v = *dp++ = (png_byte)(((int)*rp++ - p) & 0xff);
+
+ sum += (v < 128) ? v : 256 - v;
+
+ if (sum > lmins) /* We are already worse, don't continue. */
+ break;
+ }
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ if (png_ptr->heuristic_method == PNG_FILTER_HEURISTIC_WEIGHTED)
+ {
+ int j;
+ png_uint_32 sumhi, sumlo;
+ sumlo = sum & PNG_LOMASK;
+ sumhi = (sum >> PNG_HISHIFT) & PNG_HIMASK;
+
+ for (j = 0; j < num_p_filters; j++)
+ {
+ if (png_ptr->prev_filters[j] == PNG_FILTER_VALUE_PAETH)
+ {
+ sumlo = (sumlo * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_weights[j]) >>
+ PNG_WEIGHT_SHIFT;
+ }
+ }
+
+ sumlo = (sumlo * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+ sumhi = (sumhi * png_ptr->filter_costs[PNG_FILTER_VALUE_PAETH]) >>
+ PNG_COST_SHIFT;
+
+ if (sumhi > PNG_HIMASK)
+ sum = PNG_MAXSUM;
+ else
+ sum = (sumhi << PNG_HISHIFT) + sumlo;
+ }
+#endif
+
+ if (sum < mins)
+ {
+ best_row = png_ptr->paeth_row;
+ }
+ }
+
+ /* Do the actual writing of the filtered row data from the chosen filter. */
+
+ png_write_filtered_row(png_ptr, best_row);
+
+#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
+ /* Save the type of filter we picked this time for future calculations */
+ if (png_ptr->num_prev_filters > 0)
+ {
+ int j;
+ for (j = 1; j < num_p_filters; j++)
+ {
+ png_ptr->prev_filters[j] = png_ptr->prev_filters[j - 1];
+ }
+ png_ptr->prev_filters[j] = best_row[0];
+ }
+#endif
+}
+
+
+/* Do the actual writing of a previously filtered row. */
+void /* PRIVATE */
+png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
+{
+ png_debug(1, "in png_write_filtered_row\n");
+ png_debug1(2, "filter = %d\n", filtered_row[0]);
+ /* set up the zlib input buffer */
+
+ png_ptr->zstream.next_in = filtered_row;
+ png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
+ /* repeat until we have compressed all the data */
+ do
+ {
+ int ret; /* return of zlib */
+
+ /* compress the data */
+ ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
+ /* check for compression errors */
+ if (ret != Z_OK)
+ {
+ if (png_ptr->zstream.msg != NULL)
+ png_error(png_ptr, png_ptr->zstream.msg);
+ else
+ png_error(png_ptr, "zlib error");
+ }
+
+ /* see if it is time to write another IDAT */
+ if (!(png_ptr->zstream.avail_out))
+ {
+ /* write the IDAT and reset the zlib output buffer */
+ png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
+ png_ptr->zstream.next_out = png_ptr->zbuf;
+ png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+ }
+ /* repeat until all data has been compressed */
+ } while (png_ptr->zstream.avail_in);
+
+ /* swap the current and previous rows */
+ if (png_ptr->prev_row != NULL)
+ {
+ png_bytep tptr;
+
+ tptr = png_ptr->prev_row;
+ png_ptr->prev_row = png_ptr->row_buf;
+ png_ptr->row_buf = tptr;
+ }
+
+ /* finish row - updates counters and flushes zlib if last row */
+ png_write_finish_row(png_ptr);
+
+#if defined(PNG_WRITE_FLUSH_SUPPORTED)
+ png_ptr->flush_rows++;
+
+ if (png_ptr->flush_dist > 0 &&
+ png_ptr->flush_rows >= png_ptr->flush_dist)
+ {
+ png_write_flush(png_ptr);
+ }
+#endif
+}
+#endif /* PNG_WRITE_SUPPORTED */
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-shared.proj b/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-shared.proj
new file mode 100644
index 0000000..6d2e3c3
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-shared.proj
Binary files differ
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-shared.txt b/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-shared.txt
new file mode 100644
index 0000000..0cd4d9d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-shared.txt
@@ -0,0 +1,22 @@
+This project builds a shared library version of libpng on x86 BeOS.
+
+It defines PNG_USE_PNGGCCRD, which activates the assembly code in
+pnggccrd.c; this hasn't been extensively tested on BeOS.
+
+To install:
+
+1) build
+
+ Note: As of version 1.0.10, you'll get a fair number of warnings when
+ you compile pnggccrd.c. As far as I know, these are harmless,
+ but it would be better if someone fixed them.
+
+2) copy and png.h, pngconf.h somewhere; /boot/home/config/include (which
+ you'll have to make) is a good choice
+
+3) copy libpng.so to /boot/home/config/lib
+
+4) build your libpng.so applications (remember to include libz.a as
+ well when you link)
+
+- Chris Herborth, March 27, 2001
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-static.proj b/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-static.proj
new file mode 100644
index 0000000..37c0753
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-static.proj
Binary files differ
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-static.txt b/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-static.txt
new file mode 100644
index 0000000..bb80aaa
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/beos/x86-static.txt
@@ -0,0 +1,22 @@
+This project builds a static library version of libpng on x86 BeOS.
+
+It defines PNG_USE_PNGGCCRD, which activates the assembly code in
+pnggccrd.c; this hasn't been extensively tested on BeOS.
+
+To install:
+
+1) build
+
+ Note: As of version 1.0.10, you'll get a fair number of warnings when
+ you compile pnggccrd.c. As far as I know, these are harmless,
+ but it would be better if someone fixed them.
+
+2) copy and png.h, pngconf.h somewhere; /boot/home/config/include (which
+ you'll have to make) is a good choice
+
+3) copy libpng.a to /boot/home/config/lib
+
+4) build your libpng.a applications (remember to include libz.a as
+ well when you link)
+
+- Chris Herborth, March 27, 2001
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpf b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpf
new file mode 100644
index 0000000..e796e3c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpf
@@ -0,0 +1,22 @@
+USEUNIT("libpng.cpp");
+USEUNIT("..\..\pngwutil.c");
+USEUNIT("..\..\pngerror.c");
+USEUNIT("..\..\pngget.c");
+USEUNIT("..\..\pngmem.c");
+USEUNIT("..\..\pngpread.c");
+USEUNIT("..\..\pngread.c");
+USEUNIT("..\..\pngrio.c");
+USEUNIT("..\..\pngrtran.c");
+USEUNIT("..\..\pngrutil.c");
+USEUNIT("..\..\pngset.c");
+USEUNIT("..\..\pngtrans.c");
+USEUNIT("..\..\pngwio.c");
+USEUNIT("..\..\pngwrite.c");
+USEUNIT("..\..\pngwtran.c");
+USEUNIT("..\..\png.c");
+USELIB("zlib.lib");
+//---------------------------------------------------------------------------
+This file is used by the project manager only and should be treated like the project file
+
+
+DllEntryPoint \ No newline at end of file
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpg b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpg
new file mode 100644
index 0000000..80c1977
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpg
@@ -0,0 +1,25 @@
+#------------------------------------------------------------------------------
+VERSION = BWS.01
+#------------------------------------------------------------------------------
+!ifndef ROOT
+ROOT = $(MAKEDIR)\..
+!endif
+#------------------------------------------------------------------------------
+MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$**
+DCC = $(ROOT)\bin\dcc32.exe $**
+BRCC = $(ROOT)\bin\brcc32.exe $**
+#------------------------------------------------------------------------------
+PROJECTS = libpngstat.lib libpng.dll
+#------------------------------------------------------------------------------
+default: $(PROJECTS)
+#------------------------------------------------------------------------------
+
+libpngstat.lib: libpngstat.bpr
+ $(ROOT)\bin\bpr2mak -t$(ROOT)\bin\deflib.bmk $**
+ $(ROOT)\bin\make -$(MAKEFLAGS) -f$*.mak
+
+libpng.dll: libpng.bpr
+ $(ROOT)\bin\bpr2mak $**
+ $(ROOT)\bin\make -$(MAKEFLAGS) -f$*.mak
+
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpr b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpr
new file mode 100644
index 0000000..f5f062b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.bpr
@@ -0,0 +1,157 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!-- C++Builder XML Project -->
+<PROJECT>
+ <MACROS>
+ <VERSION value="BCB.05.03"/>
+ <PROJECT value="libpng.dll"/>
+ <OBJFILES value="libpng.obj ..\..\pngwutil.obj ..\..\pngerror.obj ..\..\pngget.obj
+ ..\..\pngmem.obj ..\..\pngpread.obj ..\..\pngread.obj ..\..\pngrio.obj
+ ..\..\pngrtran.obj ..\..\pngrutil.obj ..\..\pngset.obj ..\..\pngtrans.obj
+ ..\..\pngwio.obj ..\..\pngwrite.obj ..\..\pngwtran.obj ..\..\png.obj"/>
+ <RESFILES value=""/>
+ <DEFFILE value=""/>
+ <RESDEPEN value="$(RESFILES)"/>
+ <LIBFILES value="zlib.lib"/>
+ <LIBRARIES value="bcbsmp50.lib dclocx50.lib NMFast50.lib Tee50.lib Vclx50.lib Vcl50.lib"/>
+ <SPARELIBS value="Vcl50.lib Vclx50.lib Tee50.lib NMFast50.lib dclocx50.lib bcbsmp50.lib"/>
+ <PACKAGES value="Vcl50.bpi Vclx50.bpi bcbsmp50.bpi Qrpt50.bpi Vcldb50.bpi Vclbde50.bpi
+ ibsmp50.bpi vcldbx50.bpi TeeUI50.bpi TeeDB50.bpi Tee50.bpi TeeQR50.bpi
+ VCLIB50.bpi bcbie50.bpi vclie50.bpi Inetdb50.bpi Inet50.bpi NMFast50.bpi
+ dclocx50.bpi bcb97axserver50.bpi SIMULUSCOMPONENTS.bpi Simulus2.bpi"/>
+ <PATHCPP value=".;..\.."/>
+ <PATHPAS value=".;"/>
+ <PATHRC value=".;"/>
+ <PATHASM value=".;"/>
+ <DEBUGLIBPATH value="$(BCB)\lib\debug"/>
+ <RELEASELIBPATH value="$(BCB)\lib\release"/>
+ <LINKER value="tlink32"/>
+ <USERDEFINES value="ZLIB_DLL;Z_PREFIX;PNG_BUILD_DLL;PNG_NO_MODULEDEF"/>
+ <SYSDEFINES value="NO_STRICT;_NO_VCL;_RTLDLL"/>
+ <MAINSOURCE value="libpng.bpf"/>
+ <INCLUDEPATH value="..\..;..\..\..\zlib;$(BCB)\include"/>
+ <LIBPATH value="..\..;$(BCB)\lib\obj;$(BCB)\lib"/>
+ <WARNINGS value="-w8092 -w8091 -w8090 -w8089 -w8087 -wprc -wucp -wstv -wstu -wsig -wpin
+ -wnod -wnak -wdef -wcln -wbbf -wasm -wamp -wamb"/>
+ </MACROS>
+ <OPTIONS>
+ <CFLAG1 value="-WD -O2 -w -Vx -Ve -x- -RT- -X- -a8 -5 -b- -d -k- -vi -tWD -tWM -c"/>
+ <PFLAGS value="-$Y- -$L- -$D- -$C- -v -JPHNE -M"/>
+ <RFLAGS value=""/>
+ <AFLAGS value="/mx /w2 /zn"/>
+ <LFLAGS value="-D&quot;&quot; -aa -Tpd -x -Gn -Gi -w"/>
+ </OPTIONS>
+ <LINKER>
+ <ALLOBJ value="c0d32.obj $(OBJFILES)"/>
+ <ALLRES value="$(RESFILES)"/>
+ <ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32mti.lib"/>
+ </LINKER>
+ <IDEOPTIONS>
+[Version Info]
+IncludeVerInfo=0
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=1
+Locale=2057
+CodePage=1252
+
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=1.0.0.0
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=
+Comments=
+
+[HistoryLists\hlIncludePath]
+Count=18
+Item0=..\..;..\..\..\zlib;$(BCB)\include
+Item1=..\..;P:\My Documents\Source\PNG+ZLib\zlib;$(BCB)\include
+Item2=..\..;..\Source\ThirdParty\PortableNetworkGraphics\external;..\Source\ThirdParty\PortableNetworkGraphics;..\Source\ThirdParty\ZLibCompression\external;$(BCB)\include
+Item3=..\Source\ThirdParty\PortableNetworkGraphics\external;..\Source\ThirdParty\PortableNetworkGraphics;..\Source\ThirdParty\ZLibCompression\external;$(BCB)\include
+Item4=..\Source\ThirdParty\PortableNetworkGraphics\external;..\Source\ThirdParty\PortableNetworkGraphics;..\Source\ThirdParty\ZLibCompression;$(BCB)\include
+Item5=..\Source\ThirdParty\PortableNetworkGraphics;..\Source\ThirdParty\ZLibCompression;$(BCB)\include
+Item6=..\Source\ThirdParty\PortableNetworkGraphics;P:\Development\Source\ThirdParty\ZLibCompression;$(BCB)\include
+Item7=..\Source\ThirdParty\PortableNetworkGraphics;$(BCB)\include
+Item8=$(BCB)\include
+Item9=..\Source;..\Source\General\Templates;..\Source\SIMUtilities;$(BCB)\include;$(BCB)\include\vcl
+Item10=P:\Development\Source\;P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities\;$(BCB)\include;$(BCB)\include\vcl
+Item11=P:\Development\Source;P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities\;$(BCB)\include;$(BCB)\include\vcl
+Item12=P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities\;$(BCB)\include;$(BCB)\include\vcl
+Item13=P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities;$(BCB)\include;$(BCB)\include\vcl
+Item14=P:\Development\Source\General\Templates\;$(BCB)\include;$(BCB)\include\vcl
+Item15=P:\Development\Source\General\Templates;$(BCB)\include;$(BCB)\include\vcl
+Item16=P:\Development\Source;$(BCB)\include;$(BCB)\include\vcl
+Item17=$(BCB)\include;$(BCB)\include\vcl
+
+[HistoryLists\hlLibraryPath]
+Count=10
+Item0=..\..;$(BCB)\lib\obj;$(BCB)\lib
+Item1=..\..;..\Source\ThirdParty\PortableNetworkGraphics\external;..\Source\ThirdParty\PortableNetworkGraphics;$(BCB)\lib\obj;$(BCB)\lib
+Item2=..\Source\ThirdParty\PortableNetworkGraphics\external;..\Source\ThirdParty\PortableNetworkGraphics;$(BCB)\lib\obj;$(BCB)\lib
+Item3=..\Source\ThirdParty\PortableNetworkGraphics;$(BCB)\lib\obj;$(BCB)\lib
+Item4=$(BCB)\lib\obj;$(BCB)\lib
+Item5=..\Source\SIMUtilities;..\Source;$(BCB)\lib\obj;$(BCB)\lib
+Item6=P:\Development\Source\SIMUtilities\;P:\Development\Source\;$(BCB)\lib\obj;$(BCB)\lib
+Item7=P:\Development\Source\SIMUtilities;P:\Development\Source\;$(BCB)\lib\obj;$(BCB)\lib
+Item8=P:\Development\Source\;$(BCB)\lib\obj;$(BCB)\lib
+Item9=P:\Development\Source;$(BCB)\lib\obj;$(BCB)\lib
+
+[HistoryLists\hlDebugSourcePath]
+Count=1
+Item0=$(BCB)\source\vcl
+
+[HistoryLists\hlConditionals]
+Count=20
+Item0=ZLIB_DLL;Z_PREFIX;PNG_BUILD_DLL;PNG_NO_MODULEDEF
+Item1=_DEBUG;ZLIB_DLL;Z_PREFIX;PNG_BUILD_DLL;PNG_NO_MODULEDEF
+Item2=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_NO_MODULEDEF
+Item3=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG=5;PNG_NO_MODULEDEF;PNG_NO_GLOBAL_ARRAYS
+Item4=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG=5;PNG_NO_MODULEDEF;PNG_SETJMP_NOT_SUPPORTED;PNG_DEBUG_FILE=stderr
+Item5=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG;PNG_NO_MODULEDEF;PNG_SETJMP_NOT_SUPPORTED
+Item6=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG=5;PNG_NO_MODULEDEF;PNG_SETJMP_NOT_SUPPORTED
+Item7=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG=5;PNG_NO_MODULEDEF
+Item8=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG;PNG_DEBUG=5
+Item9=PNG_BUILD_DLL;ZLIB_DLL;_DEBUG
+Item10=PNG_BUILD_DLL;ZLIB_DLL
+Item11=PNG_BUILD_DLL
+Item12=PNG_DLL;PNG_BUILD_DLL;ZLIB_DLL
+Item13=PNG_DLL;PNG_BUILD_DLL;PNG_NO_GLOBAL_ARRAYS;ZLIB_DLL
+Item14=PNG_DLL;PNG_BUILD_DLL;PNG_NO_GLOBAL_ARRAYS
+Item15=PNG_DLL;PNG_BUILD_DLL
+Item16=PNG_DLL;PNG_BUILD_DLL;PNG_MODULEDEF
+Item17=_HTML_FORM
+Item18=_DEBUG;_HTML_FORM
+Item19=_DEBUG
+
+[HistoryLists\hlIntOutputDir]
+Count=2
+Item0=..\Obj
+Item1=P:\Development\Obj
+
+[Debugging]
+DebugSourceDirs=
+
+[Parameters]
+RunParams=
+HostApplication=P:\Development\Executables\LibPNGTestApp.exe
+RemoteHost=
+RemotePath=
+RemoteDebug=0
+
+[Compiler]
+ShowInfoMsgs=0
+LinkDebugVcl=0
+LinkCGLIB=0
+ </IDEOPTIONS>
+</PROJECT> \ No newline at end of file
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.cpp b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.cpp
new file mode 100644
index 0000000..4e2f274
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.cpp
@@ -0,0 +1,29 @@
+//---------------------------------------------------------------------------
+#include <windows.h>
+//---------------------------------------------------------------------------
+// Important note about DLL memory management when your DLL uses the
+// static version of the RunTime Library:
+//
+// If your DLL exports any functions that pass String objects (or structs/
+// classes containing nested Strings) as parameter or function results,
+// you will need to add the library MEMMGR.LIB to both the DLL project and
+// any other projects that use the DLL. You will also need to use MEMMGR.LIB
+// if any other projects which use the DLL will be performing new or delete
+// operations on any non-TObject-derived classes which are exported from the
+// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
+// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
+// the file BORLNDMM.DLL should be deployed along with your DLL.
+//
+// To avoid using BORLNDMM.DLL, pass string information using "char *" or
+// ShortString parameters.
+//
+// If your DLL uses the dynamic version of the RTL, you do not need to
+// explicitly add MEMMGR.LIB as this will be done implicitly for you
+//---------------------------------------------------------------------------
+
+int WINAPI DllEntryPoint(HINSTANCE, unsigned long, void*)
+{
+ return 1;
+}
+//---------------------------------------------------------------------------
+ \ No newline at end of file
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.readme.txt b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.readme.txt
new file mode 100644
index 0000000..efe7cbd
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpng.readme.txt
@@ -0,0 +1,19 @@
+Project files to build libpng using Borland C++ Builder v5.0
+
+To use this dll, you will need to:
+
+1) add the following conditional defines to your project
+
+PNG_USE_DLL
+Z_PREFIX
+
+2) add the paths to png.h and zlib.h to your include path
+
+3) add libpng.lib or libpngstat.lib to the project.
+
+If you are using libpng.dll, libpng.dll and zlib.dll will be required for the code to run.
+
+Alternatively, the libpng.dll can be built using zlibstat.lib to produce one dll containing both the zlib and png code.
+
+See the libpng documentation for instructions on how to use the code.
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpngstat.bpf b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpngstat.bpf
new file mode 100644
index 0000000..9159d02
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpngstat.bpf
@@ -0,0 +1,22 @@
+USELIB("zlibstat.lib");
+USEUNIT("..\..\pngerror.c");
+USEUNIT("..\..\png.c");
+USEUNIT("..\..\pngwutil.c");
+USEUNIT("..\..\pngmem.c");
+USEUNIT("..\..\pngpread.c");
+USEUNIT("..\..\pngread.c");
+USEUNIT("..\..\pngrio.c");
+USEUNIT("..\..\pngrtran.c");
+USEUNIT("..\..\pngrutil.c");
+USEUNIT("..\..\pngset.c");
+USEUNIT("..\..\pngtrans.c");
+USEUNIT("..\..\pngwio.c");
+USEUNIT("..\..\pngwrite.c");
+USEUNIT("..\..\pngwtran.c");
+USEUNIT("..\..\pngget.c");
+//---------------------------------------------------------------------------
+#define Library
+
+// To add a file to the library use the Project menu 'Add to Project'.
+
+ \ No newline at end of file
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpngstat.bpr b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpngstat.bpr
new file mode 100644
index 0000000..0b97981
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/libpngstat.bpr
@@ -0,0 +1,109 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!-- C++Builder XML Project -->
+<PROJECT>
+ <MACROS>
+ <VERSION value="BCB.05.03"/>
+ <PROJECT value="libpngstat.lib"/>
+ <OBJFILES value="..\..\pngerror.obj ..\..\png.obj ..\..\pngwutil.obj ..\..\pngmem.obj
+ ..\..\pngpread.obj ..\..\pngread.obj ..\..\pngrio.obj ..\..\pngrtran.obj
+ ..\..\pngrutil.obj ..\..\pngset.obj ..\..\pngtrans.obj ..\..\pngwio.obj
+ ..\..\pngwrite.obj ..\..\pngwtran.obj ..\..\pngget.obj"/>
+ <RESFILES value=""/>
+ <DEFFILE value=""/>
+ <RESDEPEN value="$(RESFILES)"/>
+ <LIBFILES value="zlibstat.lib"/>
+ <LIBRARIES value=""/>
+ <PACKAGES value=""/>
+ <PATHCPP value=".;..\.."/>
+ <PATHPAS value=".;"/>
+ <PATHRC value=".;"/>
+ <PATHASM value=".;"/>
+ <LINKER value="TLib"/>
+ <USERDEFINES value=""/>
+ <SYSDEFINES value="_RTLDLL;NO_STRICT"/>
+ <MAINSOURCE value="libpngstat.bpf"/>
+ <INCLUDEPATH value="..\..;..\..\..\zlib;$(BCB)\include"/>
+ <LIBPATH value="..\..;$(BCB)\lib\obj;$(BCB)\lib"/>
+ <WARNINGS value="-w-par"/>
+ <LISTFILE value=""/>
+ </MACROS>
+ <OPTIONS>
+ <CFLAG1 value="-O2 -w -Vx -Ve -X- -a8 -5 -b- -d -k- -vi -c -tW -tWM"/>
+ <PFLAGS value="-$Y- -$L- -$D- -$C- -v -JPHNE -M"/>
+ <AFLAGS value="/mx /w2 /zn"/>
+ <LFLAGS value=""/>
+ </OPTIONS>
+ <LINKER>
+ <ALLOBJ value="$(OBJFILES)"/>
+ <ALLLIB value=""/>
+ </LINKER>
+ <IDEOPTIONS>
+[Version Info]
+IncludeVerInfo=0
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=0
+Locale=2057
+CodePage=1252
+
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=1.0.0.0
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=1.0.0.0
+Comments=
+
+[HistoryLists\hlIncludePath]
+Count=2
+Item0=..\..;P:\My Documents\Source\PNG+ZLib\zlib;$(BCB)\include
+Item1=..\..;$(BCB)\include;$(BCB)\include\vcl
+
+[HistoryLists\hlLibraryPath]
+Count=1
+Item0=..\..;$(BCB)\lib\obj;$(BCB)\lib
+
+[HistoryLists\hlDebugSourcePath]
+Count=1
+Item0=$(BCB)\source\vcl
+
+[HistoryLists\hlConditionals]
+Count=1
+Item0=_DEBUG
+
+[HistoryLists\hlTlibPageSize]
+Count=1
+Item0=0x0010
+
+[Debugging]
+DebugSourceDirs=$(BCB)\source\vcl
+
+[Parameters]
+RunParams=
+HostApplication=
+RemoteHost=
+RemotePath=
+RemoteDebug=0
+
+[Compiler]
+ShowInfoMsgs=0
+LinkDebugVcl=0
+LinkCGLIB=0
+
+[Language]
+ActiveLang=
+ProjectLang=
+RootDir=
+ </IDEOPTIONS>
+</PROJECT> \ No newline at end of file
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib+libpng.bpg b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib+libpng.bpg
new file mode 100644
index 0000000..f8f4702
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib+libpng.bpg
@@ -0,0 +1,33 @@
+#------------------------------------------------------------------------------
+VERSION = BWS.01
+#------------------------------------------------------------------------------
+!ifndef ROOT
+ROOT = $(MAKEDIR)\..
+!endif
+#------------------------------------------------------------------------------
+MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$**
+DCC = $(ROOT)\bin\dcc32.exe $**
+BRCC = $(ROOT)\bin\brcc32.exe $**
+#------------------------------------------------------------------------------
+PROJECTS = zlibstat.lib libpngstat.lib zlib.dll libpng.dll
+#------------------------------------------------------------------------------
+default: $(PROJECTS)
+#------------------------------------------------------------------------------
+
+libpng.dll: libpng.bpr
+ $(ROOT)\bin\bpr2mak $**
+ $(ROOT)\bin\make -$(MAKEFLAGS) -f$*.mak
+
+zlibstat.lib: zlibstat.bpr
+ $(ROOT)\bin\bpr2mak -t$(ROOT)\bin\deflib.bmk $**
+ $(ROOT)\bin\make -$(MAKEFLAGS) -f$*.mak
+
+zlib.dll: zlib.bpr
+ $(ROOT)\bin\bpr2mak $**
+ $(ROOT)\bin\make -$(MAKEFLAGS) -f$*.mak
+
+libpngstat.lib: libpngstat.bpr
+ $(ROOT)\bin\bpr2mak -t$(ROOT)\bin\deflib.bmk $**
+ $(ROOT)\bin\make -$(MAKEFLAGS) -f$*.mak
+
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpf b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpf
new file mode 100644
index 0000000..7dca899
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpf
@@ -0,0 +1,20 @@
+USEUNIT("zlib.cpp");
+USEUNIT("..\..\..\zlib\zutil.c");
+USEUNIT("..\..\..\zlib\compress.c");
+USEUNIT("..\..\..\zlib\crc32.c");
+USEUNIT("..\..\..\zlib\deflate.c");
+USEUNIT("..\..\..\zlib\gzio.c");
+USEUNIT("..\..\..\zlib\infblock.c");
+USEUNIT("..\..\..\zlib\infcodes.c");
+USEUNIT("..\..\..\zlib\inffast.c");
+USEUNIT("..\..\..\zlib\inflate.c");
+USEUNIT("..\..\..\zlib\inftrees.c");
+USEUNIT("..\..\..\zlib\infutil.c");
+USEUNIT("..\..\..\zlib\trees.c");
+USEUNIT("..\..\..\zlib\uncompr.c");
+USEUNIT("..\..\..\zlib\adler32.c");
+//---------------------------------------------------------------------------
+This file is used by the project manager only and should be treated like the project file
+
+
+DllEntryPoint \ No newline at end of file
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpg b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpg
new file mode 100644
index 0000000..0292b48
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpg
@@ -0,0 +1,25 @@
+#------------------------------------------------------------------------------
+VERSION = BWS.01
+#------------------------------------------------------------------------------
+!ifndef ROOT
+ROOT = $(MAKEDIR)\..
+!endif
+#------------------------------------------------------------------------------
+MAKE = $(ROOT)\bin\make.exe -$(MAKEFLAGS) -f$**
+DCC = $(ROOT)\bin\dcc32.exe $**
+BRCC = $(ROOT)\bin\brcc32.exe $**
+#------------------------------------------------------------------------------
+PROJECTS = zlibstat.lib zlib.dll
+#------------------------------------------------------------------------------
+default: $(PROJECTS)
+#------------------------------------------------------------------------------
+
+zlibstat.lib: zlibstat.bpr
+ $(ROOT)\bin\bpr2mak -t$(ROOT)\bin\deflib.bmk $**
+ $(ROOT)\bin\make -$(MAKEFLAGS) -f$*.mak
+
+zlib.dll: zlib.bpr
+ $(ROOT)\bin\bpr2mak $**
+ $(ROOT)\bin\make -$(MAKEFLAGS) -f$*.mak
+
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpr b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpr
new file mode 100644
index 0000000..b3dda39
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.bpr
@@ -0,0 +1,147 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!-- C++Builder XML Project -->
+<PROJECT>
+ <MACROS>
+ <VERSION value="BCB.05.03"/>
+ <PROJECT value="zlib.dll"/>
+ <OBJFILES value="zlib.obj ..\..\..\zlib\zutil.obj ..\..\..\zlib\compress.obj
+ ..\..\..\zlib\crc32.obj ..\..\..\zlib\deflate.obj ..\..\..\zlib\gzio.obj
+ ..\..\..\zlib\infblock.obj ..\..\..\zlib\infcodes.obj
+ ..\..\..\zlib\inffast.obj ..\..\..\zlib\inflate.obj
+ ..\..\..\zlib\inftrees.obj ..\..\..\zlib\infutil.obj
+ ..\..\..\zlib\trees.obj ..\..\..\zlib\uncompr.obj ..\..\..\zlib\adler32.obj"/>
+ <RESFILES value=""/>
+ <DEFFILE value=""/>
+ <RESDEPEN value="$(RESFILES)"/>
+ <LIBFILES value=""/>
+ <LIBRARIES value="bcbsmp50.lib dclocx50.lib NMFast50.lib Tee50.lib Vclx50.lib Vcl50.lib"/>
+ <SPARELIBS value="Vcl50.lib Vclx50.lib Tee50.lib NMFast50.lib dclocx50.lib bcbsmp50.lib"/>
+ <PACKAGES value="Vcl50.bpi Vclx50.bpi bcbsmp50.bpi Qrpt50.bpi Vcldb50.bpi Vclbde50.bpi
+ ibsmp50.bpi vcldbx50.bpi TeeUI50.bpi TeeDB50.bpi Tee50.bpi TeeQR50.bpi
+ VCLIB50.bpi bcbie50.bpi vclie50.bpi Inetdb50.bpi Inet50.bpi NMFast50.bpi
+ dclocx50.bpi bcb97axserver50.bpi SIMULUSCOMPONENTS.bpi Simulus2.bpi"/>
+ <PATHCPP value=".;..\..\..\zlib"/>
+ <PATHPAS value=".;"/>
+ <PATHRC value=".;"/>
+ <PATHASM value=".;"/>
+ <DEBUGLIBPATH value="$(BCB)\lib\debug"/>
+ <RELEASELIBPATH value="$(BCB)\lib\release"/>
+ <LINKER value="tlink32"/>
+ <USERDEFINES value="ZLIB_DLL;Z_PREFIX"/>
+ <SYSDEFINES value="NO_STRICT;_NO_VCL;_RTLDLL"/>
+ <MAINSOURCE value="zlib.bpf"/>
+ <INCLUDEPATH value="..\..\..\zlib;$(BCB)\include"/>
+ <LIBPATH value="..\..\..\zlib;$(BCB)\lib\obj;$(BCB)\lib"/>
+ <WARNINGS value="-w8092 -w8091 -w8090 -w8089 -w8087 -wprc -wuse -wucp -wstv -wstu -wpin
+ -w-par -wnod -wnak -wdef -wcln -wbbf -w-aus -wasm -wamp -wamb"/>
+ </MACROS>
+ <OPTIONS>
+ <CFLAG1 value="-WD -O2 -w -Vx -Ve -x- -RT- -ff -X- -a8 -5 -b- -d -k- -vi -tWD -tWM -c"/>
+ <PFLAGS value="-$Y- -$L- -$D- -$C- -v -JPHNE -M"/>
+ <RFLAGS value=""/>
+ <AFLAGS value="/mx /w2 /zn"/>
+ <LFLAGS value="-D&quot;&quot; -aa -Tpd -x -Gn -Gi -w"/>
+ </OPTIONS>
+ <LINKER>
+ <ALLOBJ value="c0d32.obj $(OBJFILES)"/>
+ <ALLRES value="$(RESFILES)"/>
+ <ALLLIB value="$(LIBFILES) $(LIBRARIES) import32.lib cw32mti.lib"/>
+ </LINKER>
+ <IDEOPTIONS>
+[Version Info]
+IncludeVerInfo=0
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=1
+Locale=2057
+CodePage=1252
+
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=1.0.0.0
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=1.0.0.0
+Comments=
+
+[HistoryLists\hlIncludePath]
+Count=16
+Item0=..\..\..\zlib;$(BCB)\include
+Item1=..\..\..;..\Source\ThirdParty\ZLibCompression\external;..\Source\ThirdParty\ZLibCompression;..\..\..\zlib;$(BCB)\include
+Item2=..\Source\ThirdParty\ZLibCompression\external;..\Source\ThirdParty\ZLibCompression;..\..\..\zlib;$(BCB)\include
+Item3=P:\My Documents\Source\PNG+ZLib\zlib;$(BCB)\include
+Item4=..\Source\ThirdParty\ZLibCompression\external;..\Source\ThirdParty\ZLibCompression;$(BCB)\include
+Item5=..\Source\ThirdParty\ZLibCompression;$(BCB)\include
+Item6=$(BCB)\include
+Item7=..\Source;..\Source\General\Templates;..\Source\SIMUtilities;$(BCB)\include;$(BCB)\include\vcl
+Item8=P:\Development\Source\;P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities\;$(BCB)\include;$(BCB)\include\vcl
+Item9=P:\Development\Source;P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities\;$(BCB)\include;$(BCB)\include\vcl
+Item10=P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities\;$(BCB)\include;$(BCB)\include\vcl
+Item11=P:\Development\Source\General\Templates\;P:\Development\Source\SIMUtilities;$(BCB)\include;$(BCB)\include\vcl
+Item12=P:\Development\Source\General\Templates\;$(BCB)\include;$(BCB)\include\vcl
+Item13=P:\Development\Source\General\Templates;$(BCB)\include;$(BCB)\include\vcl
+Item14=P:\Development\Source;$(BCB)\include;$(BCB)\include\vcl
+Item15=$(BCB)\include;$(BCB)\include\vcl
+
+[HistoryLists\hlLibraryPath]
+Count=12
+Item0=..\..\..\zlib;$(BCB)\lib\obj;$(BCB)\lib
+Item1=..\..\..;..\Source\ThirdParty\ZLibCompression\external;..\Source\ThirdParty\ZLibCompression;..\..\..\zlib;$(BCB)\lib\obj;$(BCB)\lib
+Item2=..\Source\ThirdParty\ZLibCompression\external;..\Source\ThirdParty\ZLibCompression;..\..\..\zlib;$(BCB)\lib\obj;$(BCB)\lib
+Item3=P:\My Documents\Source\PNG+ZLib\zlib;$(BCB)\lib\obj;$(BCB)\lib
+Item4=..\Source\ThirdParty\ZLibCompression\external;..\Source\ThirdParty\ZLibCompression;$(BCB)\lib\obj;$(BCB)\lib
+Item5=$(BCB)\lib\obj;$(BCB)\lib
+Item6=..\Source\ThirdParty\ZLibCompression;$(BCB)\lib\obj;$(BCB)\lib
+Item7=..\Source\SIMUtilities;..\Source;$(BCB)\lib\obj;$(BCB)\lib
+Item8=P:\Development\Source\SIMUtilities\;P:\Development\Source\;$(BCB)\lib\obj;$(BCB)\lib
+Item9=P:\Development\Source\SIMUtilities;P:\Development\Source\;$(BCB)\lib\obj;$(BCB)\lib
+Item10=P:\Development\Source\;$(BCB)\lib\obj;$(BCB)\lib
+Item11=P:\Development\Source;$(BCB)\lib\obj;$(BCB)\lib
+
+[HistoryLists\hlDebugSourcePath]
+Count=1
+Item0=$(BCB)\source\vcl
+
+[HistoryLists\hlConditionals]
+Count=8
+Item0=ZLIB_DLL;Z_PREFIX
+Item1=ZLIB_DLL;_DEBUG;Z_PREFIX
+Item2=ZLIB_DLL;_DEBUG
+Item3=ZLIB_DLL
+Item4=_WINDOWS;ZLIB_DLL
+Item5=_HTML_FORM
+Item6=_DEBUG;_HTML_FORM
+Item7=_DEBUG
+
+[HistoryLists\hlIntOutputDir]
+Count=2
+Item0=..\Obj
+Item1=P:\Development\Obj
+
+[Debugging]
+DebugSourceDirs=
+
+[Parameters]
+RunParams=
+HostApplication=
+RemoteHost=
+RemotePath=
+RemoteDebug=0
+
+[Compiler]
+ShowInfoMsgs=0
+LinkDebugVcl=0
+LinkCGLIB=0
+ </IDEOPTIONS>
+</PROJECT> \ No newline at end of file
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.cpp b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.cpp
new file mode 100644
index 0000000..2cef71d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlib.cpp
@@ -0,0 +1,30 @@
+//---------------------------------------------------------------------------
+
+#include <windows.h>
+//---------------------------------------------------------------------------
+// Important note about DLL memory management when your DLL uses the
+// static version of the RunTime Library:
+//
+// If your DLL exports any functions that pass String objects (or structs/
+// classes containing nested Strings) as parameter or function results,
+// you will need to add the library MEMMGR.LIB to both the DLL project and
+// any other projects that use the DLL. You will also need to use MEMMGR.LIB
+// if any other projects which use the DLL will be performing new or delete
+// operations on any non-TObject-derived classes which are exported from the
+// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
+// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
+// the file BORLNDMM.DLL should be deployed along with your DLL.
+//
+// To avoid using BORLNDMM.DLL, pass string information using "char *" or
+// ShortString parameters.
+//
+// If your DLL uses the dynamic version of the RTL, you do not need to
+// explicitly add MEMMGR.LIB as this will be done implicitly for you
+//---------------------------------------------------------------------------
+
+int WINAPI DllEntryPoint(HINSTANCE, unsigned long, void*)
+{
+ return 1;
+}
+//---------------------------------------------------------------------------
+ \ No newline at end of file
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlibstat.bpf b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlibstat.bpf
new file mode 100644
index 0000000..14c36bc
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlibstat.bpf
@@ -0,0 +1,20 @@
+USEUNIT("..\..\..\zlib\zutil.c");
+USEUNIT("..\..\..\zlib\compress.c");
+USEUNIT("..\..\..\zlib\crc32.c");
+USEUNIT("..\..\..\zlib\deflate.c");
+USEUNIT("..\..\..\zlib\gzio.c");
+USEUNIT("..\..\..\zlib\infblock.c");
+USEUNIT("..\..\..\zlib\infcodes.c");
+USEUNIT("..\..\..\zlib\inffast.c");
+USEUNIT("..\..\..\zlib\inflate.c");
+USEUNIT("..\..\..\zlib\inftrees.c");
+USEUNIT("..\..\..\zlib\infutil.c");
+USEUNIT("..\..\..\zlib\trees.c");
+USEUNIT("..\..\..\zlib\uncompr.c");
+USEUNIT("..\..\..\zlib\adler32.c");
+//---------------------------------------------------------------------------
+#define Library
+
+// To add a file to the library use the Project menu 'Add to Project'.
+
+ \ No newline at end of file
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlibstat.bpr b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlibstat.bpr
new file mode 100644
index 0000000..9e09038
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/borland/zlibstat.bpr
@@ -0,0 +1,131 @@
+<?xml version='1.0' encoding='utf-8' ?>
+<!-- C++Builder XML Project -->
+<PROJECT>
+ <MACROS>
+ <VERSION value="BCB.05.03"/>
+ <PROJECT value="zlibstat.lib"/>
+ <OBJFILES value="..\..\..\zlib\zutil.obj ..\..\..\zlib\compress.obj ..\..\..\zlib\crc32.obj
+ ..\..\..\zlib\deflate.obj ..\..\..\zlib\gzio.obj
+ ..\..\..\zlib\infblock.obj ..\..\..\zlib\infcodes.obj
+ ..\..\..\zlib\inffast.obj ..\..\..\zlib\inflate.obj
+ ..\..\..\zlib\inftrees.obj ..\..\..\zlib\infutil.obj
+ ..\..\..\zlib\trees.obj ..\..\..\zlib\uncompr.obj ..\..\..\zlib\adler32.obj"/>
+ <RESFILES value=""/>
+ <DEFFILE value=""/>
+ <RESDEPEN value="$(RESFILES)"/>
+ <LIBFILES value=""/>
+ <LIBRARIES value=""/>
+ <PACKAGES value=""/>
+ <PATHCPP value=".;..\..\..\zlib"/>
+ <PATHPAS value=".;"/>
+ <PATHRC value=".;"/>
+ <PATHASM value=".;"/>
+ <LINKER value="TLib"/>
+ <USERDEFINES value="Z_PREFIX"/>
+ <SYSDEFINES value="_RTLDLL;NO_STRICT"/>
+ <MAINSOURCE value="zlibstat.bpf"/>
+ <INCLUDEPATH value="..\..\..\zlib;$(BCB)\include"/>
+ <LIBPATH value="..\..\..\zlib;$(BCB)\lib\obj;$(BCB)\lib"/>
+ <WARNINGS value="-w8092 -w8091 -w8090 -w8089 -w8087 -wprc -wuse -wucp -wstv -wstu -wpin
+ -wnod -wnak -wdef -wcln -wbbf -w-aus -wasm -wamp -wamb"/>
+ <LISTFILE value=""/>
+ </MACROS>
+ <OPTIONS>
+ <CFLAG1 value="-O2 -w -Vx -Ve -x- -RT- -X- -a8 -5 -b- -d -k- -vi -c -tW -tWM"/>
+ <PFLAGS value="-$Y- -$L- -$D- -$C- -v -JPHNE -M"/>
+ <AFLAGS value="/mx /w2 /zn"/>
+ <LFLAGS value=""/>
+ </OPTIONS>
+ <LINKER>
+ <ALLOBJ value="$(OBJFILES)"/>
+ <ALLLIB value=""/>
+ </LINKER>
+ <IDEOPTIONS>
+[Version Info]
+IncludeVerInfo=0
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=0
+Locale=2057
+CodePage=1252
+
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=1.0.0.0
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=1.0.0.0
+Comments=
+
+[HistoryLists\hlIncludePath]
+Count=8
+Item0=..\..\..\zlib;$(BCB)\include
+Item1=..\Source\ThirdParty\ZLibCompression\external;..\..\..\zlib;$(BCB)\include
+Item2=P:\My Documents\Source\PNG+ZLib\zlib;$(BCB)\include
+Item3=..\Source\ThirdParty\ZLibCompression\external;$(BCB)\include
+Item4=..\Source\ThirdParty\ZLibCompression\external;..\Source\ThirdParty\ZLibCompression\ext;..\Source\ThirdParty\ZLibCompression;$(BCB)\include
+Item5=..\Source\ThirdParty\ZLibCompression;$(BCB)\include
+Item6=$(BCB)\include
+Item7=$(BCB)\include;$(BCB)\include\vcl
+
+[HistoryLists\hlLibraryPath]
+Count=7
+Item0=..\..\..\zlib;$(BCB)\lib\obj;$(BCB)\lib
+Item1=$(BCB)\lib\obj;$(BCB)\lib
+Item2=..\Source\ThirdParty\ZLibCompression\external;..\..\..\zlib;$(BCB)\lib\obj;$(BCB)\lib
+Item3=P:\My Documents\Source\PNG+ZLib\zlib;$(BCB)\lib\obj;$(BCB)\lib
+Item4=..\Source\ThirdParty\ZLibCompression\external;$(BCB)\lib\obj;$(BCB)\lib
+Item5=..\Source\ThirdParty\ZLibCompression\external;..\Source\ThirdParty\ZLibCompression\ext;..\Source\ThirdParty\ZLibCompression;$(BCB)\lib\obj;$(BCB)\lib
+Item6=..\Source\ThirdParty\ZLibCompression;$(BCB)\lib\obj;$(BCB)\lib
+
+[HistoryLists\hlDebugSourcePath]
+Count=1
+Item0=$(BCB)\source\vcl
+
+[HistoryLists\hlConditionals]
+Count=3
+Item0=Z_PREFIX
+Item1=ZLIB_DLL
+Item2=_WINDOWS;ZLIB_DLL
+
+[HistoryLists\hlIntOutputDir]
+Count=2
+Item0=..\Obj
+Item1=P:\Development\Obj
+
+[HistoryLists\hlTlibPageSize]
+Count=1
+Item0=0x0010
+
+[Debugging]
+DebugSourceDirs=
+
+[Parameters]
+RunParams=
+HostApplication=
+RemoteHost=
+RemotePath=
+RemoteDebug=0
+
+[Compiler]
+ShowInfoMsgs=0
+LinkDebugVcl=0
+LinkCGLIB=0
+
+[Language]
+ActiveLang=
+ProjectLang=
+RootDir=
+ </IDEOPTIONS>
+</PROJECT> \ No newline at end of file
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/README.txt b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/README.txt
new file mode 100644
index 0000000..57bb642
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/README.txt
@@ -0,0 +1,57 @@
+Microsoft Developer Studio Build File, Format Version 6.00 for
+libpng 1.2.5 (October 3, 2002) and zlib
+
+Copyright (C) 2000 Simon-Pierre Cadieux
+For conditions of distribution and use, see copyright notice in png.h
+
+Assumes that libpng sources are in ..\..
+Assumes that zlib sources have been copied to ..\..\..\zlib
+
+To build:
+
+0) On the main menu, select "File | Open Workspace" and then
+ select "libpng.dsw".
+
+1) On the main menu Select "Build | Set Active configuration".
+ Among the configurations beginning with "libpng" select the
+ one you wish to build (the corresponding "zlib" configuration
+ will be built automatically).
+
+2) Select "Build | Clean"
+
+3) Select "Build | Rebuild All". Ignore warning messages about
+ not being able to tqfind certain include files (e.g., m68881.h,
+ alloc.h).
+
+4) Look in the appropriate "win32" subdirectories for both "zlib"
+ and "libpng" binaries.
+
+This project will build the PNG Development Group's "official" versions of
+libpng and zlib libraries:
+
+ libpng13.dll (default version, currently C code only)
+ libpng13a.dll (C + Assembler version)
+ libpng13b.dll (C + Assembler debug version)
+ libpng13d.dll (C code debug version)
+ libpng13vb.dll (version for VB, uses "stdcall" protocol)
+ libpng13[c,e-m].dll (reserved for official versions)
+ libpng13[n-z].dll (available for private versions)
+ zlib.dll (default version, currently C code only)
+ zlibd.dll (debug version)
+ zlibvb.dll (version for Visual Basic, uses "stdcall" protocol)
+
+If you change anything in libpng, or select different compiler settings,
+please change the library name to an unreserved name, and define
+DLLFNAME_POSTFIX and (PRIVATEBUILD or SPECIALBUILD) accordingly. DLLFNAME_POSTFIX
+should correspond to a string in the range of "N" to "Z" depending on the letter
+you choose for your private version.
+
+All DLLs built by this project use the Microsoft dynamic C runtime library
+MSVCRT.DLL (MSVCRTD.DLL for debug versions). If you distribute any of the
+above mentioned libraries you should also include this DLL in your package.
+For a list of files that are redistributable in Visual C++ 6.0, see
+Common\Redist\Redist.txt on Disc 1 of the Visual C++ 6.0 product CDs.
+
+5) For an example workspace that builds an application using the resulting
+ DLLs, go to Libpng's contrib\msvctest directory and use it to build
+ and run "pngtest".
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/libpng.dsp b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/libpng.dsp
new file mode 100644
index 0000000..d08d3d5
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/libpng.dsp
@@ -0,0 +1,439 @@
+# Microsoft Developer Studio Project File - Name="libpng" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=libpng - Win32 DLL
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "libpng.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "libpng.mak" CFG="libpng - Win32 DLL"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "libpng - Win32 DLL" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "libpng - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "libpng - Win32 DLL ASM" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "libpng - Win32 DLL Debug ASM" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "libpng - Win32 LIB" (based on "Win32 (x86) Static Library")
+!MESSAGE "libpng - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "libpng - Win32 DLL VB" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "libpng - Win32 DLL"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\win32\libpng\dll"
+# PROP Intermediate_Dir ".\win32\libpng\dll"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /c
+# ADD CPP /nologo /MD /W3 /O1 /I "..\.." /I "..\..\..\zlib" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /Yu"png.h" /FD /c
+MTL=midl.exe
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /i "..\.." /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /machine:I386
+# ADD LINK32 /nologo /dll /machine:I386 /out:".\win32\libpng\dll\libpng13.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\win32\libpng\dll_dbg"
+# PROP Intermediate_Dir ".\win32\libpng\dll_dbg"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MDd /W3 /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Zi /Od /I "..\.." /I "..\..\..\zlib" /D "DEBUG" /D "_DEBUG" /D PNG_DEBUG=1 /D "WIN32" /D "_WINDOWS" /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /Yu"png.h" /FD /GZ /c
+MTL=midl.exe
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /i "..\.." /d "_DEBUG" /d PNG_DEBUG=1
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /dll /debug /machine:I386 /out:".\win32\libpng\dll_dbg\libpng13d.dll"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\win32\libpng\dll_asm"
+# PROP Intermediate_Dir ".\win32\libpng\dll_asm"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /c
+# ADD CPP /nologo /MD /W3 /O1 /I "..\.." /I "..\..\..\zlib" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PNG_USE_PNGVCRD" /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /Yu"png.h" /FD /c
+MTL=midl.exe
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /i "..\.." /d "NDEBUG" /d "PNG_USE_PNGVCRD"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /machine:I386
+# ADD LINK32 /nologo /dll /machine:I386 /out:".\win32\libpng\dll_asm\libpng13a.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug ASM"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\win32\libpng\dll_dbga"
+# PROP Intermediate_Dir ".\win32\libpng\dll_dbga"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MDd /W3 /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Zi /Od /I "..\.." /I "..\..\..\zlib" /D "DEBUG" /D "_DEBUG" /D PNG_DEBUG=1 /D "WIN32" /D "_WINDOWS" /D "PNG_USE_PNGVCRD" /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /Yu"png.h" /FD /GZ /c
+MTL=midl.exe
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /i "..\.." /d "_DEBUG" /d PNG_DEBUG=1 /d "PNG_USE_PNGVCRD"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /dll /debug /machine:I386 /out:".\win32\libpng\dll_dbga\libpng13b.dll"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 LIB"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\win32\libpng\lib"
+# PROP Intermediate_Dir ".\win32\libpng\lib"
+# PROP Target_Dir ""
+MTL=midl.exe
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_LIB" /FD /c
+# ADD CPP /nologo /W3 /O1 /I "..\.." /I "..\..\..\zlib" /D "WIN32" /D "NDEBUG" /Yu"png.h" /FD /c
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /i "..\.." /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "libpng - Win32 LIB Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\win32\libpng\lib_dbg"
+# PROP Intermediate_Dir ".\win32\libpng\lib_dbg"
+# PROP Target_Dir ""
+MTL=midl.exe
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /Zi /Od /D "_DEBUG" /D "WIN32" /D "_LIB" /FD /GZ /c
+# ADD CPP /nologo /W3 /Zi /Od /I "..\.." /I "..\..\..\zlib" /D "DEBUG" /D "_DEBUG" /D PNG_DEBUG=1 /D "WIN32" /Yu"png.h" /FD /GZ /c
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL VB"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "libpng___Win32_DLL_VB"
+# PROP BASE Intermediate_Dir "libpng___Win32_DLL_VB"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\win32\libpng\dll_vb"
+# PROP Intermediate_Dir ".\win32\libpng\dll_vb"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /O1 /I "..\.." /I "..\..\..\zlib" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /Yu"png.h" /FD /c
+# ADD CPP /nologo /Gd /MD /W3 /O1 /I "..\.." /I "..\..\..\zlib" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "PNG_BUILD_DLL" /D "ZLIB_DLL" /D PNGAPI=__stdcall /Yu"png.h" /FD /c
+MTL=midl.exe
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /i "..\.." /d "NDEBUG"
+# ADD RSC /l 0x409 /i "..\.." /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /machine:I386 /out:".\win32\libpng\dll\libpng13.dll"
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 /nologo /dll /machine:I386 /out:".\win32\libpng\dll_vb\libpngvb13.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "libpng - Win32 DLL"
+# Name "libpng - Win32 DLL Debug"
+# Name "libpng - Win32 DLL ASM"
+# Name "libpng - Win32 DLL Debug ASM"
+# Name "libpng - Win32 LIB"
+# Name "libpng - Win32 LIB Debug"
+# Name "libpng - Win32 DLL VB"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\png.c
+# SUBTRACT CPP /YX /Yc /Yu
+# End Source File
+# Begin Source File
+
+SOURCE=.\png.rc
+
+!IF "$(CFG)" == "libpng - Win32 DLL"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug ASM"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 LIB"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL VB"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=.\png32ms.def
+
+!IF "$(CFG)" == "libpng - Win32 DLL"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug ASM"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 LIB"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL VB"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngerror.c
+# ADD CPP /Yc"png.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngget.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngmem.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngpread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngread.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngrio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngrtran.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngrutil.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngset.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngtrans.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngvcrd.c
+
+!IF "$(CFG)" == "libpng - Win32 DLL"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug ASM"
+
+!ELSEIF "$(CFG)" == "libpng - Win32 LIB"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL VB"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngwio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngwrite.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngwtran.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngwutil.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\png.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\pngconf.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# Begin Source File
+
+SOURCE=.\readme.txt
+
+!IF "$(CFG)" == "libpng - Win32 DLL"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL ASM"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL Debug ASM"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 LIB"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "libpng - Win32 DLL VB"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# End Target
+# End Project
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/libpng.dsw b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/libpng.dsw
new file mode 100644
index 0000000..eca5b77
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/libpng.dsw
@@ -0,0 +1,44 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "libpng"=.\libpng.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "zlib"=.\zlib.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/png.rc b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/png.rc
new file mode 100644
index 0000000..9912471
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/png.rc
@@ -0,0 +1,100 @@
+#define PNG_VERSION_INFO_ONLY
+
+#include <windows.h>
+#include "png.h"
+
+#define _QUOTE(x) # x
+#define QUOTE(x) _QUOTE(x)
+
+#define PNG_LIBPNG_DLLFNAME "LIBPNG"
+
+#if defined(DLLFNAME_POSTFIX) && !defined(PRIVATEBUILD) && !defined(SPECIALBUILD)
+# error PRIVATEBUILD or SPECIALBUILD must be defined as a string describing the type of change brought to the standard library
+#endif /* defined(DLLFNAME_POSTFIX)... */
+
+#if !defined(DLLFNAME_POSTFIX) && defined(PNG_USE_PNGVCRD)
+# if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
+# define DLLFNAME_POSTFIX "B"
+# else
+# define DLLFNAME_POSTFIX "A"
+# endif /* !defined(DLLFNAME_POSTFIX)... */
+# if !defined(SPECIALBUILD)
+# define SPECIALBUILD "Use MMX instructions"
+# endif /* SPECIALBUILD */
+#endif
+
+#if defined(PNG_DEBUG) && (PNG_DEBUG > 0)
+# define VS_DEBUG VS_FF_DEBUG
+# ifndef DLLFNAME_POSTFIX
+# define DLLFNAME_POSTFIX "D"
+# endif /* DLLFNAME_POSTFIX */
+# ifndef COMMENTS
+# define COMMENTS "PNG_DEBUG=" QUOTE(PNG_DEBUG)
+# endif /* COMMENTS */
+#else
+# define VS_DEBUG 0
+# ifndef DLLFNAME_POSTFIX
+# define DLLFNAME_POSTFIX
+# endif /* DLLFNAME_POSTFIX */
+#endif /* defined(DEBUG)... */
+
+#ifdef PRIVATEBUILD
+# define VS_PRIVATEBUILD VS_FF_PRIVATEBUILD
+#else
+# define VS_PRIVATEBUILD 0
+#endif /* PRIVATEBUILD */
+
+#ifdef SPECIALBUILD
+# define VS_SPECIALBUILD VS_FF_SPECIALBUILD
+#else
+# define VS_SPECIALBUILD 0
+#endif /* SPECIALBUILD */
+
+#if ((PNG_LIBPNG_BUILD_TYPE & PNG_LIBPNG_BUILD_TYPEMASK) != \
+ PNG_LIBPNG_BUILD_STABLE)
+# define VS_PRERELEASE VS_FF_PRERELEASE
+# define VS_PATCHED 0
+#else
+# define VS_PRERELEASE 0
+# if (PNG_LIBPNG_BUILD_TYPE & PNG_LIBPNG_BUILD_PATCHED)
+# define VS_PATCHED VS_FF_PATCHED
+# else
+# define VS_PATCHED 0
+# endif
+#endif
+
+VS_VERSION_INFO VERSIONINFO
+FILEVERSION PNG_LIBPNG_VER_MAJOR, PNG_LIBPNG_VER_MINOR, PNG_LIBPNG_VER_RELEASE, PNG_LIBPNG_VER_BUILD
+PRODUCTVERSION PNG_LIBPNG_VER_MAJOR, PNG_LIBPNG_VER_MINOR, PNG_LIBPNG_VER_RELEASE, PNG_LIBPNG_VER_BUILD
+FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+FILEFLAGS VS_DEBUG | VS_PRIVATEBUILD | VS_SPECIALBUILD | VS_PRERELEASE | VS_PATCHED
+FILEOS VOS__WINDOWS32
+FILETYPE VFT_DLL
+FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN BLOCK "040904E4" /* Language type = U.S English(0x0409) and Character Set = Windows, Multilingual(0x04E4) */
+ BEGIN
+#ifdef COMMENTS
+ VALUE "Comments", COMMENTS "\000"
+#endif /* COMMENTS */
+ VALUE "FileDescription", "PNG image compression library\000"
+ VALUE "FileVersion", PNG_LIBPNG_VER_STRING "\000"
+ VALUE "InternalName", PNG_LIBPNG_DLLFNAME QUOTE(PNG_LIBPNG_VER_MAJOR) DLLFNAME_POSTFIX " (Windows 32 bit)\000"
+ VALUE "LegalCopyright", "\251 1998-2002 Glenn Randers-Pehrson\000"
+ VALUE "OriginalFilename", PNG_LIBPNG_DLLFNAME QUOTE(PNG_LIBPNG_VER_MAJOR) DLLFNAME_POSTFIX ".DLL\000"
+#ifdef PRIVATEBUILD
+ VALUE "PrivateBuild", PRIVATEBUILD
+#endif /* PRIVATEBUILD */
+ VALUE "ProductName", "LibPNG\000"
+ VALUE "ProductVersion", "1\000"
+#ifdef SPECIALBUILD
+ VALUE "SpecialBuild", SPECIALBUILD
+#endif /* SPECIALBUILD */
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 0x04E4
+ END
+END
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/png32ms.def b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/png32ms.def
new file mode 100644
index 0000000..ae6abdd
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/png32ms.def
@@ -0,0 +1,220 @@
+;------------------------------------------
+; LIBPNG module definition file for Windows
+;------------------------------------------
+
+LIBRARY
+DESCRIPTION "PNG image compression library for Windows"
+
+EXPORTS
+;Version 1.2.5
+ png_build_grayscale_palette @1
+ png_check_sig @2
+ png_chunk_error @3
+ png_chunk_warning @4
+ png_convert_from_struct_tm @5
+ png_convert_from_time_t @6
+ png_create_info_struct @7
+ png_create_read_struct @8
+ png_create_write_struct @9
+ png_data_freer @10
+ png_destroy_info_struct @11
+ png_destroy_read_struct @12
+ png_destroy_write_struct @13
+ png_error @14
+ png_free @15
+ png_free_data @16
+ png_get_IHDR @17
+ png_get_PLTE @18
+ png_get_bKGD @19
+ png_get_bit_depth @20
+ png_get_cHRM @21
+ png_get_cHRM_fixed @22
+ png_get_channels @23
+ png_get_color_type @24
+ png_get_compression_buffer_size @25
+ png_get_compression_type @26
+ png_get_copyright @27
+ png_get_error_ptr @28
+ png_get_filter_type @29
+ png_get_gAMA @30
+ png_get_gAMA_fixed @31
+ png_get_hIST @32
+ png_get_header_ver @33
+ png_get_header_version @34
+ png_get_iCCP @35
+ png_get_image_height @36
+ png_get_image_width @37
+ png_get_interlace_type @38
+ png_get_io_ptr @39
+ png_get_libpng_ver @40
+ png_get_oFFs @41
+ png_get_pCAL @42
+ png_get_pHYs @43
+ png_get_pixel_aspect_ratio @44
+ png_get_pixels_per_meter @45
+ png_get_progressive_ptr @46
+ png_get_rgb_to_gray_status @47
+ png_get_rowbytes @48
+ png_get_rows @49
+ png_get_sBIT @50
+ png_get_sCAL @51
+ png_get_sPLT @52
+ png_get_sRGB @53
+ png_get_signature @54
+ png_get_tIME @55
+ png_get_tRNS @56
+ png_get_text @57
+ png_get_unknown_chunks @58
+ png_get_user_chunk_ptr @59
+ png_get_user_transform_ptr @60
+ png_get_valid @61
+ png_get_x_offset_microns @62
+ png_get_x_offset_pixels @63
+ png_get_x_pixels_per_meter @64
+ png_get_y_offset_microns @65
+ png_get_y_offset_pixels @66
+ png_get_y_pixels_per_meter @67
+ png_malloc @68
+ png_memcpy_check @69
+ png_memset_check @70
+; png_permit_empty_plte is deprecated
+ png_permit_empty_plte @71
+ png_process_data @72
+ png_progressive_combine_row @73
+ png_read_end @74
+ png_read_image @75
+ png_read_info @76
+; png_read_init is deprecated
+ png_read_init @77
+ png_read_png @78
+ png_read_row @79
+ png_read_rows @80
+ png_read_update_info @81
+ png_reset_zstream @82
+ png_set_IHDR @83
+ png_set_PLTE @84
+ png_set_bKGD @85
+ png_set_background @86
+ png_set_bgr @87
+ png_set_cHRM @88
+ png_set_cHRM_fixed @89
+ png_set_compression_buffer_size @90
+ png_set_compression_level @91
+ png_set_compression_mem_level @92
+ png_set_compression_method @93
+ png_set_compression_strategy @94
+ png_set_compression_window_bits @95
+ png_set_crc_action @96
+ png_set_dither @97
+ png_set_error_fn @98
+ png_set_expand @99
+ png_set_filler @100
+ png_set_filter @101
+ png_set_filter_heuristics @102
+ png_set_flush @103
+ png_set_gAMA @104
+ png_set_gAMA_fixed @105
+ png_set_gamma @106
+ png_set_gray_1_2_4_to_8 @107
+ png_set_gray_to_rgb @108
+ png_set_hIST @109
+ png_set_iCCP @110
+ png_set_interlace_handling @111
+ png_set_invert_alpha @112
+ png_set_invert_mono @113
+ png_set_keep_unknown_chunks @114
+ png_set_oFFs @115
+ png_set_pCAL @116
+ png_set_pHYs @117
+ png_set_packing @118
+ png_set_packswap @119
+ png_set_palette_to_rgb @120
+ png_set_progressive_read_fn @121
+ png_set_read_fn @122
+ png_set_read_status_fn @123
+ png_set_read_user_chunk_fn @124
+ png_set_read_user_transform_fn @125
+ png_set_rgb_to_gray @126
+ png_set_rgb_to_gray_fixed @127
+ png_set_rows @128
+ png_set_sBIT @129
+ png_set_sCAL @130
+ png_set_sPLT @131
+ png_set_sRGB @132
+ png_set_sRGB_gAMA_and_cHRM @133
+ png_set_shift @134
+ png_set_sig_bytes @135
+ png_set_strip_16 @136
+ png_set_strip_alpha @137
+ png_set_swap @138
+ png_set_swap_alpha @139
+ png_set_tIME @140
+ png_set_tRNS @141
+ png_set_tRNS_to_alpha @142
+ png_set_text @143
+ png_set_unknown_chunk_location @144
+ png_set_unknown_chunks @145
+ png_set_user_transform_info @146
+ png_set_write_fn @147
+ png_set_write_status_fn @148
+ png_set_write_user_transform_fn @149
+ png_sig_cmp @150
+ png_start_read_image @151
+ png_warning @152
+ png_write_chunk @153
+ png_write_chunk_data @154
+ png_write_chunk_end @155
+ png_write_chunk_start @156
+ png_write_end @157
+ png_write_flush @158
+ png_write_image @159
+ png_write_info @160
+ png_write_info_before_PLTE @161
+; png_write_init is deprecated
+ png_write_init @162
+ png_write_png @163
+ png_write_row @164
+ png_write_rows @165
+; png_read_init_2 and png_write_init_2 are deprecated.
+ png_read_init_2 @166
+ png_write_init_2 @167
+ png_access_version_number @168
+; png_sig_bytes @169
+; png_libpng_ver @170
+ png_init_io @171
+ png_convert_to_rfc1123 @172
+ png_set_invalid @173
+; Added at version 1.0.12
+; For compatiblity with 1.0.7-1.0.11
+ png_info_init @174
+ png_read_init_3 @175
+ png_write_init_3 @176
+ png_info_init_3 @177
+ png_destroy_struct @178
+; Added at version 1.2.0
+; For use with PNG_USER_MEM_SUPPORTED
+ png_destroy_struct_2 @179
+ png_create_read_struct_2 @180
+ png_create_write_struct_2 @181
+ png_malloc_default @182
+ png_free_default @183
+; MNG features
+ png_permit_mng_features @184
+; MMX support
+ png_mmx_support @185
+ png_get_mmx_flagtqmask @186
+ png_get_asm_flagtqmask @187
+ png_get_asm_flags @188
+ png_get_mmx_bitdepth_threshold @189
+ png_get_mmx_rowbytes_threshold @190
+ png_set_asm_flags @191
+ png_init_mmx_flags @192
+; Strip error numbers
+ png_set_strip_error_numbers @193
+; Added at version 1.2.2
+ png_handle_as_unknown @194
+; Added at version 1.2.2 and deleted from 1.2.3
+; png_zalloc @195
+; png_zfree @196
+; Added at version 1.2.4
+ png_malloc_warn @195
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/zlib.def b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/zlib.def
new file mode 100644
index 0000000..022aa45
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/zlib.def
@@ -0,0 +1,45 @@
+LIBRARY
+DESCRIPTION "zlib compression library for Windows"
+
+EXPORTS
+ adler32 @1
+ compress @2
+ crc32 @3
+ deflate @4
+ deflateCopy @5
+ deflateEnd @6
+ deflateInit2_ @7
+ deflateInit_ @8
+ deflateParams @9
+ deflateReset @10
+ deflateSetDictionary @11
+ gzclose @12
+ gzdopen @13
+ gzerror @14
+ gzflush @15
+ gzopen @16
+ gzread @17
+ gzwrite @18
+ inflate @19
+ inflateEnd @20
+ inflateInit2_ @21
+ inflateInit_ @22
+ inflateReset @23
+ inflateSetDictionary @24
+ inflateSync @25
+ uncompress @26
+ zlibVersion @27
+ gzprintf @28
+ gzputc @29
+ gzgetc @30
+ gzseek @31
+ gzrewind @32
+ gztell @33
+ gzeof @34
+ gzsetparams @35
+ zError @36
+ inflateSyncPoint @37
+ get_crc_table @38
+ compress2 @39
+ gzputs @40
+ gzgets @41
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/zlib.dsp b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/zlib.dsp
new file mode 100644
index 0000000..df9a5db
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/msvc/zlib.dsp
@@ -0,0 +1,441 @@
+# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=zlib - Win32 DLL
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zlib.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 DLL"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zlib - Win32 DLL" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlib - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlib - Win32 DLL ASM" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlib - Win32 DLL Debug ASM" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlib - Win32 LIB" (based on "Win32 (x86) Static Library")
+!MESSAGE "zlib - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "zlib - Win32 DLL VB" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "zlib - Win32 DLL"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\win32\zlib\dll"
+# PROP Intermediate_Dir ".\win32\zlib\dll"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /FD /c
+# ADD CPP /nologo /MD /W3 /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ZLIB_DLL" /FD /c
+MTL=midl.exe
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /machine:I386
+# ADD LINK32 /nologo /dll /machine:I386
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\win32\zlib\dll_dbg"
+# PROP Intermediate_Dir ".\win32\zlib\dll_dbg"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MDd /W3 /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Zi /Od /D "DEBUG" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "ZLIB_DLL" /FD /GZ /c
+MTL=midl.exe
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /dll /debug /machine:I386 /out:".\win32\zlib\dll_dbg\zlibd.dll"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\win32\zlib\dll_asm"
+# PROP Intermediate_Dir ".\win32\zlib\dll_asm"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /c
+# ADD CPP /nologo /MD /W3 /O1 /I "..\..\..\zlib" /D "NDEBUG" /D "WIN32" /D "_WIN32" /D "_WINDOWS" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FD /c
+MTL=midl.exe
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /i "..\.." /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /machine:I386
+# ADD LINK32 gvmat32.obj /nologo /dll /machine:I386 /out:".\win32\zlib\dll_asm\zliba.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug ASM"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\win32\zlib\dll_dbga"
+# PROP Intermediate_Dir ".\win32\zlib\dll_dbga"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MDd /W3 /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_USRDLL" /FD /GZ /c
+# ADD CPP /nologo /MDd /W3 /Zi /Od /I "..\..\..\zlib" /D "_DEBUG" /D "WIN32" /D "_WIN32" /D "_WINDOWS" /D "ZLIB_DLL" /D "DYNAMIC_CRC_TABLE" /D "ASMV" /FAcs /FD /GZ /c
+MTL=midl.exe
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /i "..\.." /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 gvmat32d.obj /nologo /dll /debug /machine:I386 /out:".\win32\zlib\dll_dbga\zlibb.dll"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\win32\zlib\lib"
+# PROP Intermediate_Dir ".\win32\zlib\lib"
+# PROP Target_Dir ""
+MTL=midl.exe
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_LIB" /FD /c
+# ADD CPP /nologo /W3 /O1 /D "WIN32" /D "NDEBUG" /FD /c
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir ".\win32\zlib\lib_dbg"
+# PROP Intermediate_Dir ".\win32\zlib\lib_dbg"
+# PROP Target_Dir ""
+MTL=midl.exe
+CPP=cl.exe
+# ADD BASE CPP /nologo /W3 /Zi /Od /D "WIN32" /D "_DEBUG" /D "_LIB" /FD /GZ /c
+# ADD CPP /nologo /W3 /Zi /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL VB"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlib___Win32_DLL_VB"
+# PROP BASE Intermediate_Dir "zlib___Win32_DLL_VB"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir ".\win32\zlib\dll_vb"
+# PROP Intermediate_Dir ".\win32\zlib\dll_vb"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ZLIB_DLL" /FD /c
+# ADD CPP /nologo /Gd /MD /W3 /O1 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "ZLIB_DLL" /FD /c
+MTL=midl.exe
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 /nologo /dll /machine:I386
+# SUBTRACT BASE LINK32 /pdb:none
+# ADD LINK32 /nologo /dll /machine:I386 /out:".\win32\zlib\dll_vb/zlibvb.dll"
+# SUBTRACT LINK32 /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "zlib - Win32 DLL"
+# Name "zlib - Win32 DLL Debug"
+# Name "zlib - Win32 DLL ASM"
+# Name "zlib - Win32 DLL Debug ASM"
+# Name "zlib - Win32 LIB"
+# Name "zlib - Win32 LIB Debug"
+# Name "zlib - Win32 DLL VB"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\..\zlib\adler32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\crc32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\deflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\contrib\asm386\gvmat32c.c
+
+!IF "$(CFG)" == "zlib - Win32 DLL"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug ASM"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL VB"
+
+# PROP BASE Exclude_From_Build 1
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\gzio.c
+# ADD CPP /Yc"zutil.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\infblock.c
+# ADD CPP /Yu"zutil.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\infcodes.c
+# ADD CPP /Yu"zutil.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\inffast.c
+# ADD CPP /Yu"zutil.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\inflate.c
+# ADD CPP /Yu"zutil.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\inftrees.c
+# ADD CPP /Yu"zutil.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\infutil.c
+# ADD CPP /Yu"zutil.h"
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\trees.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\uncompr.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\zlib.def
+
+!IF "$(CFG)" == "zlib - Win32 DLL"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug ASM"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL VB"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\msdos\zlib.rc
+
+!IF "$(CFG)" == "zlib - Win32 DLL"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug ASM"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL VB"
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\zutil.c
+# ADD CPP /Yu"zutil.h"
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\..\zlib\deflate.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\infblock.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\infcodes.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\inffast.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\inffixed.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\inftrees.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\infutil.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\trees.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\zconf.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\zlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\..\zlib\zutil.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/netware.txt b/tqtinterface/qt4/src/3rdparty/libpng/projects/netware.txt
new file mode 100644
index 0000000..178361d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/netware.txt
@@ -0,0 +1,6 @@
+A set of project files is available for Netware. Get
+libpng-1.2.5-project-netware.zip from a libpng distribution
+site such as http://libpng.sourceforge.net
+
+Put the zip file in this directory (projects) and then run
+"unzip -a libpng-1.2.5-project-netware.zip"
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/projects/wince.txt b/tqtinterface/qt4/src/3rdparty/libpng/projects/wince.txt
new file mode 100644
index 0000000..a1a26c0
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/projects/wince.txt
@@ -0,0 +1,6 @@
+A set of project files is available for WinCE. Get
+libpng-1.2.5-project-wince.zip from a libpng distribution
+site such as http://libpng.sourceforge.net
+
+Put the zip file in this directory (projects) and then run
+"unzip -a libpng-1.2.5-project-wince.zip"
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/SCOPTIONS.ppc b/tqtinterface/qt4/src/3rdparty/libpng/scripts/SCOPTIONS.ppc
new file mode 100644
index 0000000..2c3503e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/SCOPTIONS.ppc
@@ -0,0 +1,7 @@
+OPTIMIZE
+OPTPEEP
+OPTTIME
+OPTSCHED
+AUTOREGISTER
+PARMS=REGISTERS
+INCLUDEDIR=hlp:ppc/include
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/descrip.mms b/tqtinterface/qt4/src/3rdparty/libpng/scripts/descrip.mms
new file mode 100644
index 0000000..3584b0d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/descrip.mms
@@ -0,0 +1,52 @@
+
+cc_defs = /inc=$(ZLIBSRC)
+c_deb =
+
+.ifdef __DECC__
+pref = /prefix=all
+.endif
+
+
+
+OBJS = png.obj, pngset.obj, pngget.obj, pngrutil.obj, pngtrans.obj,\
+ pngwutil.obj, pngread.obj, pngmem.obj, pngwrite.obj, pngrtran.obj,\
+ pngwtran.obj, pngrio.obj, pngwio.obj, pngerror.obj, pngpread.obj
+
+
+CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
+
+all : pngtest.exe libpng.olb
+ @ write sys$output " pngtest available"
+
+libpng.olb : libpng.olb($(OBJS))
+ @ write sys$output " Libpng available"
+
+
+pngtest.exe : pngtest.obj libpng.olb
+ link pngtest,libpng.olb/lib,$(ZLIBSRC)libz.olb/lib
+
+test : pngtest.exe
+ run pngtest
+
+clean :
+ delete *.obj;*,*.exe;*
+
+
+# Other dependencies.
+png.obj : png.h, pngconf.h
+pngpread.obj : png.h, pngconf.h
+pngset.obj : png.h, pngconf.h
+pngget.obj : png.h, pngconf.h
+pngread.obj : png.h, pngconf.h
+pngrtran.obj : png.h, pngconf.h
+pngrutil.obj : png.h, pngconf.h
+pngerror.obj : png.h, pngconf.h
+pngmem.obj : png.h, pngconf.h
+pngrio.obj : png.h, pngconf.h
+pngwio.obj : png.h, pngconf.h
+pngtest.obj : png.h, pngconf.h
+pngtrans.obj : png.h, pngconf.h
+pngwrite.obj : png.h, pngconf.h
+pngwtran.obj : png.h, pngconf.h
+pngwutil.obj : png.h, pngconf.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng-config-body.in b/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng-config-body.in
new file mode 100755
index 0000000..b466432
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng-config-body.in
@@ -0,0 +1,96 @@
+
+usage()
+{
+ cat <<EOF
+Usage: libpng-config [OPTION] ...
+
+Known values for OPTION are:
+
+ --prefix print libpng prefix
+ --libdir print path to directory containing library
+ --libs print library linking information
+ --ccopts print compiler options
+ --cppflags print pre-processor flags
+ --cflags print preprocessor flags, I_opts, and compiler options
+ --I_opts print "-I" include options
+ --L_opts print linker "-L" flags for dynamic linking
+ --R_opts print dynamic linker "-R" or "-rpath" flags
+ --ldopts print linker options
+ --ldflags print linker flags (ldopts, L_opts, R_opts, and libs)
+ --static revise subsequent outputs for static linking
+ --help print this help and exit
+ --version print version information
+EOF
+
+ exit $1
+}
+
+if test $# -eq 0; then
+ usage 1
+fi
+
+while test $# -gt 0; do
+ case "$1" in
+
+ --prefix)
+ echo ${prefix}
+ ;;
+
+ --version)
+ echo ${version}
+ exit 0
+ ;;
+
+ --help)
+ usage 0
+ ;;
+
+ --ccopts)
+ echo ${ccopts}
+ ;;
+
+ --cppflags)
+ echo ${cppflags}
+ ;;
+
+ --cflags)
+ echo ${I_opts} ${cppflags} ${ccopts}
+ ;;
+
+ --libdir)
+ echo ${libdir}
+ ;;
+
+ --libs)
+ echo ${libs}
+ ;;
+
+ --I_opts)
+ echo ${I_opts}
+ ;;
+
+ --L_opts)
+ echo ${L_opts}
+ ;;
+
+ --R_opts)
+ echo ${R_opts}
+ ;;
+
+ --ldflags)
+ echo ${ldflags} ${L_opts} ${R_opts} ${libs}
+ ;;
+
+ --static)
+ R_opts=""
+ ;;
+
+ *)
+ usage
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+exit 0
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng-config-head.in b/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng-config-head.in
new file mode 100755
index 0000000..0f64fa4
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng-config-head.in
@@ -0,0 +1,21 @@
+#! /bin/sh
+
+# libpng-config
+# provides configuration info for libpng.
+
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Modeled after libxml-config.
+
+version=1.2.5
+prefix=""
+libdir=""
+libs=""
+I_opts=""
+L_opts=""
+R_opts=""
+cppflags=""
+ccopts=""
+ldopts=""
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng.icc b/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng.icc
new file mode 100644
index 0000000..f9c51af
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng.icc
@@ -0,0 +1,44 @@
+// Project file for libpng (static)
+// IBM VisualAge/C++ version 4.0 or later
+// Copyright (C) 2000 Cosmin Truta
+// For conditions of distribution and use, see copyright notice in png.h
+// Notes:
+// All modules are compiled in C mode
+// Tested with IBM VAC++ 4.0 under Win32
+// Expected to work with IBM VAC++ 4.0 or later under OS/2 and Win32
+// Can be easily adapted for IBM VAC++ 4.0 or later under AIX
+// For conditions of distribution and use, see copyright notice in png.h
+
+option incl(searchpath, "../zlib"), opt(level, "2"),
+ link(libsearchpath, "../zlib")
+{
+ target type(lib) "libpng.lib"
+ {
+ source type(c) "png.c"
+ source type(c) "pngerror.c"
+ source type(c) "pngget.c"
+ source type(c) "pngmem.c"
+ source type(c) "pngpread.c"
+ source type(c) "pngread.c"
+ source type(c) "pngrio.c"
+ source type(c) "pngrtran.c"
+ source type(c) "pngrutil.c"
+ source type(c) "pngset.c"
+ source type(c) "pngtrans.c"
+ source type(c) "pngwio.c"
+ source type(c) "pngwrite.c"
+ source type(c) "pngwtran.c"
+ source type(c) "pngwutil.c"
+ }
+}
+
+option incl(searchpath, "../zlib"), opt(level, "2"),
+ link(libsearchpath, "../zlib")
+{
+ target type(exe) "pngtest.exe"
+ {
+ source type(c) "pngtest.c"
+ source type(lib) "libpng.lib"
+ source type(lib) "zlib.lib"
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng.pc.in b/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng.pc.in
new file mode 100644
index 0000000..32ed4a9
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/libpng.pc.in
@@ -0,0 +1,11 @@
+
+prefix=@PREFIX@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${exec_prefix}/include
+
+Name: libpng12
+Description: Loads and saves PNG files
+Version: 1.2.5
+Libs: -L${libdir} -lpng12 -lz -lm
+Cflags: -I${includedir}/libpng12
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.32sunu b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.32sunu
new file mode 100644
index 0000000..5bd0941
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.32sunu
@@ -0,0 +1,224 @@
+# makefile for libpng on Solaris 2.x with cc
+# Contributed by William L. Sebok, based on makefile.linux
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1998 Greg Roelofs
+# Copyright (C) 1996, 1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=cc
+SUN_CC_FLAGS=-fast -xtarget=ultra
+SUN_LD_FLAGS=-fast -xtarget=ultra
+
+# where make install puts libpng.a, libpng12.so and libpng12/png.h
+prefix=/a
+
+# Where the zlib library and include files are located
+# Changing these to ../zlib poses a security risk. If you want
+# to have zlib in an adjacent directory, specify the full path instead of "..".
+#ZLIBLIB=../zlib
+#ZLIBINC=../zlib
+
+ZLIBLIB=/usr/lib
+ZLIBINC=/usr/include
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+CFLAGS=-I$(ZLIBINC) $(SUN_CC_FLAGS) \
+ # $(WARNMORE) -g -DPNG_DEBUG=5
+LDFLAGS=-L. -R. $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng12 -lz -lm
+
+#RANLIB=ranlib
+RANLIB=echo
+
+LIBNAME=libpng12
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -KPIC -o $@ $*.c
+
+all: libpng.a $(LIBNAME).so pngtest libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo libdir=\"$(LIBPATH)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo R_opts=\"-R$(LIBPATH)\"; \
+ echo ccopts=\"-xtarget=ultra\"; \
+ echo ldopts=\"-xtarget=ultra\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -f -s $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJSDLL)
+ @case "`type ld`" in *ucb*) \
+ echo; \
+ echo '## WARNING:'; \
+ echo '## The commands "CC" and "LD" must NOT refer to /usr/ucb/cc'; \
+ echo '## and /usr/ucb/ld. If they do, you need to adjust your PATH'; \
+ echo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \
+ echo '## The environment variable LD_LIBRARY_PATH should not be set'; \
+ echo '## at all. If it is, things are likely to break because of'; \
+ echo '## the libucb dependency that is created.'; \
+ echo; \
+ ;; \
+ esac
+ $(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h $(LIBNAME).so.$(PNGMAJ) \
+ -o $(LIBNAME).so.$(PNGVER) $(OBJSDLL)
+
+libpng.so.3.$(PNGMIN): $(OBJS)
+ $(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h libpng.so.3 \
+ -o libpng.so.3.$(PNGMIN) $(OBJSDLL)
+
+pngtest: pngtest.o $(LIBNAME).so
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm $(DI)/libpng
+ (cd $(DI); ln -f -s $(LIBNAME) libpng; ln -f -s $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -f -s $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGVER)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -f -s libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -f -s libpng.so.3 libpng.so; \
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ); \
+ ln -f -s $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/libpng12.pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/libpng12.pc
+ chmod 644 $(DL)/pkgconfig/libpng12.pc
+ (cd $(DL)/pkgconfig; ln -f -s libpng12.pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/libpng12-config
+ cp libpng-config $(DB)/libpng12-config
+ chmod 755 $(DB)/libpng12-config
+ (cd $(DB); ln -sf libpng12-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ echo
+ echo Testing installed dynamic shared library.
+ $(CC) $(SUN_CC_FLAGS) -I$(ZLIBINC) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags` \
+ $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB)
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngtesti pngout.png \
+ libpng-config $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* \
+ libpng.so.3.$(PNGMIN) \
+ libpng.pc
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.64sunu b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.64sunu
new file mode 100644
index 0000000..a9b40f2
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.64sunu
@@ -0,0 +1,224 @@
+# makefile for libpng on Solaris 2.x with cc
+# Contributed by William L. Sebok, based on makefile.linux
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1998 Greg Roelofs
+# Copyright (C) 1996, 1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=cc
+SUN_CC_FLAGS=-fast -xtarget=ultra -xarch=v9
+SUN_LD_FLAGS=-fast -xtarget=ultra -xarch=v9
+
+# where make install puts libpng.a, libpng12.so and libpng12/png.h
+prefix=/a
+
+# Where the zlib library and include files are located
+# Changing these to ../zlib poses a security risk. If you want
+# to have zlib in an adjacent directory, specify the full path instead of "..".
+#ZLIBLIB=../zlib
+#ZLIBINC=../zlib
+
+ZLIBLIB=/usr/lib
+ZLIBINC=/usr/include
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+CFLAGS=-I$(ZLIBINC) $(SUN_CC_FLAGS) \
+ # $(WARNMORE) -g -DPNG_DEBUG=5
+LDFLAGS=-L. -R. $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng12 -lz -lm
+
+#RANLIB=ranlib
+RANLIB=echo
+
+LIBNAME=libpng12
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -KPIC -o $@ $*.c
+
+all: libpng.a $(LIBNAME).so pngtest libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo libdir=\"$(LIBPATH)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo R_opts=\"-R$(LIBPATH)\"; \
+ echo ccopts=\"-xtarget=ultra -xarch=v9\"; \
+ echo ldopts=\"-xtarget=ultra -xarch=v9\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -f -s $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJSDLL)
+ @case "`type ld`" in *ucb*) \
+ echo; \
+ echo '## WARNING:'; \
+ echo '## The commands "CC" and "LD" must NOT refer to /usr/ucb/cc'; \
+ echo '## and /usr/ucb/ld. If they do, you need to adjust your PATH'; \
+ echo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \
+ echo '## The environment variable LD_LIBRARY_PATH should not be set'; \
+ echo '## at all. If it is, things are likely to break because of'; \
+ echo '## the libucb dependency that is created.'; \
+ echo; \
+ ;; \
+ esac
+ $(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h $(LIBNAME).so.$(PNGMAJ) \
+ -o $(LIBNAME).so.$(PNGVER) $(OBJSDLL)
+
+libpng.so.3.$(PNGMIN): $(OBJSDLL)
+ $(LD) -G -L$(ZLIBLIB) -R$(ZLIBLIB) -h libpng.so.3 \
+ -o libpng.so.3.$(PNGMIN) $(OBJSDLL)
+
+pngtest: pngtest.o $(LIBNAME).so
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm $(DI)/libpng
+ (cd $(DI); ln -f -s $(LIBNAME) libpng; ln -f -s $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -f -s $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGMAJ).$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGVER)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -f -s libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -f -s libpng.so.3 libpng.so; \
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ); \
+ ln -f -s $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -f -s $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ echo
+ echo Testing installed dynamic shared library.
+ $(CC) $(SUN_CC_FLAGS) -I$(ZLIBINC) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags ` \
+ $(SUN_LD_FLAGS) -L$(ZLIBLIB) -R$(ZLIBLIB)
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngtesti pngout.png \
+ libpng-config $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* \
+ libpng.so.3.$(PNGMIN) \
+ libpng.pc
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.acorn b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.acorn
new file mode 100644
index 0000000..470cf89
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.acorn
@@ -0,0 +1,51 @@
+# Project: libpng
+
+
+# Toolflags:
+CCflags = -c -depend !Depend -IC:,Zlib: -g -throwback -DRISCOS -fnah
+C++flags = -c -depend !Depend -IC: -throwback
+Linkflags = -aif -c++ -o $@
+ObjAsmflags = -throwback -NoCache -depend !Depend
+CMHGflags =
+LibFileflags = -c -l -o $@
+Squeezeflags = -o $@
+
+
+# Final targets:
+@.libpng-lib: @.o.png @.o.pngerror @.o.pngrio @.o.pngwio @.o.pngmem \
+ @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngrtran \
+ @.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil
+ LibFile $(LibFileflags) @.o.png @.o.pngerror @.o.pngrio @.o.pngrtran \
+ @.o.pngmem @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngwio \
+ @.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil
+@.mm-libpng-lib: @.mm.png @.mm.pngerror @.mm.pngrio @.mm.pngwio @.mm.pngmem \
+ @.mm.pngpread @.mm.pngset @.mm.pngget @.mm.pngread @.mm.pngrtran \
+ @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite @.mm.pngwtran @.mm.pngwutil
+ LibFile $(LibFileflags) @.mm.png @.mm.pngerror @.mm.pngrio \
+ @.mm.pngwio @.mm.pngmem @.mm.pngpread @.mm.pngset @.mm.pngget \
+ @.mm.pngread @.mm.pngrtran @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite \
+ @.mm.pngwtran @.mm.pngwutil
+
+
+# User-editable dependencies:
+# (C) Copyright 1997 Tom Tanner
+Test: @.pngtest
+ <Prefix$Dir>.pngtest
+ @remove <Prefix$Dir>.pngtest
+
+#It would be nice if you could stop "make" listing from here on!
+@.pngtest: @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib
+ Link $(Linkflags) @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib
+
+.SUFFIXES: .o .mm .c
+
+.c.mm:
+ MemCheck.CC cc $(ccflags) -o $@ LibPng:$<
+.c.o:
+ cc $(ccflags) -o $@ $<
+
+
+# Static dependencies:
+
+
+# Dynamic dependencies:
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.aix b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.aix
new file mode 100644
index 0000000..29cc6eb
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.aix
@@ -0,0 +1,104 @@
+# makefile for libpng using gcc (generic, static library)
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 2000 Cosmin Truta
+# Copyright (C) 2000 Marc O. Gloor (AIX support added, from makefile.gcc)
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Location of the zlib library and include files
+ZLIBINC = ../zlib
+ZLIBLIB = ../zlib
+
+# Compiler, linker, lib and other tools
+CC = gcc
+LD = $(CC)
+AR = ar rcs
+RANLIB = ranlib
+RM = rm -f
+
+LIBNAME=libpng12
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DI=$(DESTDIR)/$(INCPATH)
+DL=$(DESTDIR)/$(LIBPATH)
+
+CDEBUG = -g -DPNG_DEBUG=5
+LDDEBUG =
+CRELEASE = -O2
+LDRELEASE = -s
+WARNMORE=-Wall
+CFLAGS = -I$(ZLIBINC) $(WARNMORE) $(CRELEASE)
+LDFLAGS = -L. -L$(ZLIBLIB) -lpng -lz -lm $(LDRELEASE)
+
+# File extensions
+O=.o
+A=.a
+E=
+
+# Variables
+OBJS = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O) \
+ pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O) \
+ pngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O)
+
+# Targets
+all: libpng$(A) pngtest$(E)
+
+$(LIBNAME)$(A): $(OBJS)
+ $(AR) $@ $(OBJS)
+ $(RANLIB) $@
+
+test: pngtest$(E)
+ ./pngtest$(E)
+
+pngtest$(E): pngtest$(O) $(LIBNAME)$(A)
+ $(LD) -o $@ pngtest$(O) $(LDFLAGS)
+
+install: $(LIBNAME)$(A)
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/libpng ]; then mkdir $(DI)/libpng; fi
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@rm $(DI)/png.h
+ -@rm $(DI)/pngconf.h
+ cp png.h pngconf.h $(DI)/libpng
+ chmod 644 $(DI)/libpng/png.h \
+ cp $(LIBNAME)$(A) $(DL)
+ (cd $(DL); ln -f -s $(LIBNAME)$(A) libpng$(A))
+ $(DI)/libpng/pngconf.h
+ (cd $(DI); ln -f -s libpng/* .;)
+
+clean:
+ /bin/rm -f *.o $(LIBNAME)$(A) pngtest pngout.png
+
+png$(O): png.h pngconf.h
+pngerror$(O): png.h pngconf.h
+pngget$(O): png.h pngconf.h
+pngmem$(O): png.h pngconf.h
+pngpread$(O): png.h pngconf.h
+pngread$(O): png.h pngconf.h
+pngrio$(O): png.h pngconf.h
+pngrtran$(O): png.h pngconf.h
+pngrutil$(O): png.h pngconf.h
+pngset$(O): png.h pngconf.h
+pngtest$(O): png.h pngconf.h
+pngtrans$(O): png.h pngconf.h
+pngwio$(O): png.h pngconf.h
+pngwrite$(O): png.h pngconf.h
+pngwtran$(O): png.h pngconf.h
+pngwutil$(O): png.h pngconf.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.amiga b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.amiga
new file mode 100644
index 0000000..79cb424
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.amiga
@@ -0,0 +1,48 @@
+# Commodore Amiga Makefile
+# makefile for libpng and SAS C V6.5x compiler
+# Copyright (C) 1995-2000 Wolf Faust
+# For conditions of distribution and use, see copyright notice in png.h
+#
+# Note: Use #define PNG_READ_BIG_ENDIAN_SUPPORTED in pngconf.h
+#
+# Location/path of zlib include files
+ZLIB=/zlib
+#compiler
+CC=sc
+#compiler flags
+# WARNING: a bug in V6.51 causes bad code with OPTGO
+# So use V6.55 or set NOOPTGO!!!!!!!!!
+CFLAGS= NOSTKCHK PARMS=REG OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL\
+ OPTLOOP OPTRDEP=4 OPTDEP=4 OPTCOMP=4 INCLUDEDIR=$(ZLIB) \
+ DEFINE=PNG_INTERNAL
+#linker flags
+LDFLAGS= SD ND BATCH
+#link libs
+LDLIBS= libpng.lib libgz.lib LIB:scm.lib LIB:sc.lib Lib:amiga.lib
+# linker
+LN= slink
+# file deletion command
+RM= delete quiet
+# library (.lib) file creation command
+AR= oml
+# make directory command
+MKDIR= makedir
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.lib pngtest
+
+libpng.lib: $(OBJS)
+-$(RM) libpng.lib
+$(AR) libpng.lib r $(OBJS)
+
+pngtest: pngtest.o libpng.lib
+$(LN) <WITH <
+$(LDFLAGS)
+TO pngtest
+FROM LIB:c.o pngtest.o
+LIB $(LDLIBS)
+<
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.atari b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.atari
new file mode 100644
index 0000000..9566d5d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.atari
@@ -0,0 +1,51 @@
+# makefile for libpng
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+# modified for LC56/ATARI assumes libz.lib is in same dir and uses default
+# rules for library management
+#
+CFLAGS=-I..\zlib -O
+LBR = png.lib
+LDFLAGS=-lpng -lz -lm
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+OBJS = $(LBR)(png.o) $(LBR)(pngset.o) $(LBR)(pngget.o) $(LBR)(pngrutil.o)\
+ $(LBR)(pngtrans.o) $(LBR)(pngwutil.o)\
+ $(LBR)(pngread.o) $(LBR)(pngerror.o) $(LBR)(pngwrite.o)\
+ $(LBR)(pngrtran.o) $(LBR)(pngwtran.o)\
+ $(LBR)(pngmem.o) $(LBR)(pngrio.o) $(LBR)(pngwio.o) $(LBR)(pngpread.o)
+
+all: $(LBR) pngtest.ttp
+
+$(LBR): $(OBJS)
+
+pngtest.ttp: pngtest.o $(LBR)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o$@ pngtest.o
+
+install: libpng.a
+ -@mkdir $(DESTDIR)$(INCPATH)
+ -@mkdir $(DESTDIR)$(INCPATH)/libpng
+ -@mkdir $(DESTDIR)$(LIBPATH)
+ -@rm -f $(DESTDIR)$(INCPATH)/png.h
+ -@rm -f $(DESTDIR)$(INCPATH)/pngconf.h
+ cp png.h $(DESTDIR)$(INCPATH)/libpng
+ cp pngconf.h $(DESTDIR)$(INCPATH)/libpng
+ chmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h
+ chmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h
+ (cd $(DESTDIR)$(INCPATH); ln -f -s $(LIBNAME) libpng; \
+ ln -f -s $(LIBNAME)/* .)
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bc32 b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bc32
new file mode 100644
index 0000000..90b178b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bc32
@@ -0,0 +1,151 @@
+# Makefile for libpng
+# 32-bit Borland C++ (Note: All modules are compiled in C mode)
+# To build the library, do:
+# "make -fmakefile.bc32"
+#
+# -------------------- 32-bit Borland C++ --------------------
+
+### Absolutely necessary for this makefile to work
+.AUTODEPEND
+
+## Where zlib.h, zconf.h and zlib.lib are
+ZLIB_DIR=..\zlib
+
+
+## Compiler, linker and lib stuff
+CC=bcc32
+LD=bcc32
+LIB=tlib
+
+#TARGET_CPU=6
+# 3 = 386, 4 = 486, 5 = Pentium etc.
+!ifndef TARGET_CPU
+TARGET_CPU=5
+!endif
+
+# Use this if you don't want Borland's fancy exception handling
+NOEHLIB=noeh32.lib
+
+!ifdef DEBUG
+CDEBUG=-v
+LDEBUG=-v
+!else
+CDEBUG=
+LDEBUG=
+!endif
+
+# STACKOFLOW=1
+!ifdef STACKOFLOW
+CDEBUG=$(CDEBUG) -N
+LDEBUG=$(LDEBUG) -N
+!endif
+
+# -X- turn on dependency generation in the object file
+# -w set all warnings on
+# -O2 optimize for speed
+# -Z global optimization
+CFLAGS=-O2 -Z -X- -w -I$(ZLIB_DIR) -$(TARGET_CPU) $(CDEBUG)
+
+# -M generate map file
+LDFLAGS=-M -L$(ZLIB_DIR) $(LDEBUG)
+
+
+## Variables
+OBJS = \
+ png.obj \
+ pngerror.obj \
+ pngget.obj \
+ pngmem.obj \
+ pngpread.obj \
+ pngread.obj \
+ pngrio.obj \
+ pngrtran.obj \
+ pngrutil.obj \
+ pngset.obj \
+ pngtrans.obj \
+ pngwio.obj \
+ pngwrite.obj \
+ pngwtran.obj \
+ pngwutil.obj
+
+LIBOBJS = \
+ +png.obj \
+ +pngerror.obj \
+ +pngget.obj \
+ +pngmem.obj \
+ +pngpread.obj \
+ +pngread.obj \
+ +pngrio.obj \
+ +pngrtran.obj \
+ +pngrutil.obj \
+ +pngset.obj \
+ +pngtrans.obj \
+ +pngwio.obj \
+ +pngwrite.obj \
+ +pngwtran.obj \
+ +pngwutil.obj
+
+LIBNAME=libpng.lib
+
+
+## Implicit rules
+# Braces let make "batch" calls to the compiler,
+# 2 calls instead of 12; space is important.
+.c.obj:
+ $(CC) $(CFLAGS) -c {$*.c }
+
+.c.exe:
+ $(CC) $(CFLAGS) $(LDFLAGS) $*.c $(LIBNAME) zlib.lib $(NOEHLIB)
+
+.obj.exe:
+ $(LD) $(LDFLAGS) $*.obj $(LIBNAME) zlib.lib $(NOEHLIB)
+
+
+## Major targets
+all: libpng pngtest
+
+libpng: $(LIBNAME)
+
+pngtest: pngtest.exe
+
+test: pngtest.exe
+ pngtest
+
+
+## Minor Targets
+
+png.obj: png.c
+pngerror.obj: pngerror.c
+pngget.obj: pngget.c
+pngmem.obj: pngmem.c
+pngpread.obj: pngpread.c
+pngread.obj: pngread.c
+pngrio.obj: pngrio.c
+pngrtran.obj: pngrtran.c
+pngrutil.obj: pngrutil.c
+pngset.obj: pngset.c
+pngtrans.obj: pngtrans.c
+pngwio.obj: pngwio.c
+pngwrite.obj: pngwrite.c
+pngwtran.obj: pngwtran.c
+pngwutil.obj: pngwutil.c
+
+
+$(LIBNAME): $(OBJS)
+ -del $(LIBNAME)
+ $(LIB) $(LIBNAME) @&&|
+$(LIBOBJS), libpng
+|
+
+
+# Clean up anything else you want
+clean:
+ -del *.obj
+ -del *.exe
+ -del *.lib
+ -del *.lst
+ -del *.map
+ -del *.tds
+
+
+# End of makefile for libpng
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bd32 b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bd32
new file mode 100644
index 0000000..c83fe9c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bd32
@@ -0,0 +1,76 @@
+# Makefile for png32bd.dll
+# -------------------- 32-bit Borland C++ --------------------
+
+# This makefile expects to tqfind zlib.h and zlib32bd.lib in the
+# $(ZLIBDIR) directory.
+
+# The object files here are compiled with the "stdcall" calling convention.
+# This DLL requires zlib32bd.lib to be compiled in the same way.
+
+# Note that png32bd.dll exports the zlib functions adler32, crc32 and
+# the deflate... and inflate... functions. It does not export the
+# compress and uncompress functions, nor any of the gz... functions,
+# since libpng does not call them.
+
+.AUTODEPEND
+
+ZLIBDIR=..\zlib
+ZLIB=zlib32bd.lib
+PNGDLL=png32bd.dll
+PNGLIB=png32bd.lib
+
+CC=bcc32
+CFLAGS= -ps -O2 -N- -k- -d -r- -w-par -w-aus -I$(ZLIBDIR) \
+ -DPNG_NO_GLOBAL_ARRAYS #-DPNG_DEBUG=5
+#LINK=tlink32
+#LINK=ilink32
+LINK=bcc32
+#LINKFLAGS= -Tpd -aa -c
+LINKFLAGS= -WDE
+IMPLIB=implib
+
+# Use this if you don't want Borland's fancy exception handling
+NOEHLIB=noeh32.lib
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $<
+
+.c.exe:
+ $(CC) $(CFLAGS) $< $(PNGLIB) $(NOEHLIB)
+
+
+OBJ1=png.obj pngerror.obj pngget.obj pngmem.obj pngpread.obj
+OBJ2=pngread.obj pngrio.obj pngrtran.obj pngrutil.obj pngset.obj
+OBJ3=pngtrans.obj pngwio.obj pngwrite.obj pngwtran.obj pngwutil.obj
+
+all: $(PNGDLL)
+
+test: pngtest.exe
+ pngtest
+
+
+$(PNGDLL): $(OBJ1) $(OBJ2) $(OBJ3) $(ZLIBDIR)\$(ZLIB)
+ $(LINK) @&&|
+$(LINKFLAGS)
+-e$(PNGDLL)
+$(OBJ1)
+$(OBJ2)
+$(OBJ3)
+$(ZLIBDIR)\$(ZLIB)
+$(NOEHLIB)
+|
+ $(IMPLIB) -c $(@R).lib $@
+
+
+# Clean up anything else you want
+clean:
+ -del *.obj
+ -del *.dll
+ -del *.exe
+ -del *.lib
+ -del *.lst
+ -del *.map
+ -del *.tds
+
+
+# End of makefile for png32bd.dll
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.beos b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.beos
new file mode 100644
index 0000000..2609f03
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.beos
@@ -0,0 +1,199 @@
+# makefile for libpng on BeOS x86 ELF with gcc
+# modified from makefile.linux by Sander Stoks
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1999 Greg Roelofs
+# Copyright (C) 1996, 1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=gcc
+
+# Where the zlib library and include files are located
+ZLIBLIB=/usr/local/lib
+ZLIBINC=/usr/local/include
+
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+ALIGN=
+# For i386:
+# ALIGN=-malign-loops=2 -malign-functions=2
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+
+# On BeOS, -O1 is actually better than -O3. This is a known bug but it's
+# still here in R4.5
+CFLAGS=-I$(ZLIBINC) -Wall -O1 -funroll-loops \
+ $(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5
+# LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng -lz -lm
+LDFLAGS=-L. -Wl,-soname=$(LIBNAME).so.$(PNGMAJ) -L$(ZLIBLIB) -lz -lm
+
+RANLIB=ranlib
+#RANLIB=echo
+
+# where make install puts libpng.a, libpng12.so*, and png.h
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+LIBNAME=libpng12
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS)
+
+.SUFFIXES: .c .o
+
+all: libpng.a $(LIBNAME).so pngtest libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+ cp $(LIBNAME).so* /boot/home/config/lib
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJSDLL)
+ $(CC) -nostart -Wl,-soname,$(LIBNAME).so.$(PNGMAJ) -o \
+ $(LIBNAME).so.$(PNGVER) $(OBJSDLL)
+
+libpng.so.3.$(PNGMIN): $(OBJSDLL)
+ $(CC) -nostart -Wl,-soname,libpng.so.3 -o \
+ libpng.so.3.$(PNGMIN) $(OBJSDLL)
+
+pngtest: pngtest.o $(LIBNAME).so
+ $(CC) -L$(ZLIBLIB) -lz -lpng12 -o pngtest pngtest.o
+
+test: pngtest
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -sf $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGMIN)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -sf libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -sf libpng.so.3 libpng.so; \
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ); \
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ $(CC) $(CFLAGS) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngout.png libpng-config \
+ $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* pngtesti \
+ libpng.so.3.$(PNGMIN) \
+ libpng.pc
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bor b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bor
new file mode 100644
index 0000000..a5651aa
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.bor
@@ -0,0 +1,162 @@
+# Makefile for libpng
+# 16-bit Borland C++ (Note: All modules are compiled in C mode)
+# To build the library, do:
+# "make -fmakefile.bor -DMODEL=c"
+# or: "make -fmakefile.bor -DMODEL=l"
+#
+# ------------ Borland C++ ------------
+
+### Absolutely necessary for this makefile to work
+.AUTODEPEND
+
+## Where zlib.h, zconf.h and zlib_MODEL.lib are
+ZLIB_DIR=..\zlib
+
+
+## Compiler, linker and lib stuff
+CC=bcc
+LD=bcc
+LIB=tlib
+
+!ifndef MODEL
+MODEL=l
+!endif
+
+MODEL_ARG=-m$(MODEL)
+
+#TARGET_CPU=3
+# 2 = 286, 3 = 386, etc.
+!ifndef TARGET_CPU
+TARGET_CPU=2
+!endif
+
+# Use this if you don't want Borland's fancy exception handling
+# (for Borland C++ 4.0 or later)
+#NOEHLIB=noeh$(MODEL).lib
+
+!ifdef DEBUG
+CDEBUG=-v
+LDEBUG=-v
+!else
+CDEBUG=
+LDEBUG=
+!endif
+
+# STACKOFLOW=1
+!ifdef STACKOFLOW
+CDEBUG=$(CDEBUG) -N
+LDEBUG=$(LDEBUG) -N
+!endif
+
+# -X- turn on dependency generation in the object file
+# -w set all warnings on
+# -O2 optimize for speed
+# -Z global optimization
+CFLAGS=-O2 -Z -X- -w -I$(ZLIB_DIR) -$(TARGET_CPU) $(MODEL_ARG) $(CDEBUG)
+
+# -M generate map file
+LDFLAGS=-M -L$(ZLIB_DIR) $(MODEL_ARG) $(LDEBUG)
+
+
+## Variables
+OBJS = \
+ png.obj \
+ pngerror.obj \
+ pngget.obj \
+ pngmem.obj \
+ pngpread.obj \
+ pngread.obj \
+ pngrio.obj \
+ pngrtran.obj \
+ pngrutil.obj \
+ pngset.obj \
+ pngtrans.obj \
+ pngwio.obj \
+ pngwrite.obj \
+ pngwtran.obj \
+ pngwutil.obj
+
+LIBOBJS = \
+ +png.obj \
+ +pngerror.obj \
+ +pngget.obj \
+ +pngmem.obj \
+ +pngpread.obj \
+ +pngread.obj \
+ +pngrio.obj \
+ +pngrtran.obj \
+ +pngrutil.obj \
+ +pngset.obj \
+ +pngtrans.obj \
+ +pngwio.obj \
+ +pngwrite.obj \
+ +pngwtran.obj \
+ +pngwutil.obj
+
+LIBNAME=libpng$(MODEL).lib
+
+
+## Implicit rules
+# Braces let make "batch" calls to the compiler,
+# 2 calls instead of 12; space is important.
+.c.obj:
+ $(CC) $(CFLAGS) -c {$*.c }
+
+.c.exe:
+ $(CC) $(CFLAGS) $(LDFLAGS) $*.c $(LIBNAME) zlib_$(MODEL).lib $(NOEHLIB)
+
+
+## Major targets
+all: libpng pngtest
+
+libpng: $(LIBNAME)
+
+pngtest: pngtest$(MODEL).exe
+
+test: pngtest$(MODEL).exe
+ pngtest$(MODEL)
+
+
+## Minor Targets
+
+png.obj: png.c
+pngerror.obj: pngerror.c
+pngget.obj: pngget.c
+pngmem.obj: pngmem.c
+pngpread.obj: pngpread.c
+pngread.obj: pngread.c
+pngrio.obj: pngrio.c
+pngrtran.obj: pngrtran.c
+pngrutil.obj: pngrutil.c
+pngset.obj: pngset.c
+pngtrans.obj: pngtrans.c
+pngwio.obj: pngwio.c
+pngwrite.obj: pngwrite.c
+pngwtran.obj: pngwtran.c
+pngwutil.obj: pngwutil.c
+
+
+$(LIBNAME): $(OBJS)
+ -del $(LIBNAME)
+ $(LIB) $(LIBNAME) @&&|
+$(LIBOBJS), libpng$(MODEL)
+|
+
+
+pngtest$(MODEL).obj: pngtest.c
+ $(CC) $(CFLAGS) -opngtest$(MODEL) -c pngtest.c
+
+pngtest$(MODEL).exe: pngtest$(MODEL).obj
+ $(LD) $(LDFLAGS) pngtest$(MODEL).obj $(LIBNAME) zlib_$(MODEL).lib $(NOEHLIB)
+
+
+# Clean up anything else you want
+clean:
+ -del *.obj
+ -del *.exe
+ -del *.lib
+ -del *.lst
+ -del *.map
+
+
+# End of makefile for libpng
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.cygwin b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.cygwin
new file mode 100644
index 0000000..a282bef
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.cygwin
@@ -0,0 +1,305 @@
+# makefile for cygwin on x86
+# Builds both dll (with import lib) and static lib versions
+# of the library, and builds two copies of pngtest: one
+# statically linked and one dynamically linked.
+#
+# Copyright (C) 2002 Soren Anderson, Charles Wilson, and Glenn Randers-Pehrson
+# based on makefile for linux-elf w/mmx by:
+# Copyright (C) 1998-2000 Greg Roelofs
+# Copyright (C) 1996, 1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+# This makefile intends to support building outside the src directory
+# if desired. When invoking it, specify an argument to SRCDIR on the
+# command line that points to the top of the directory where your source
+# is located.
+
+ifdef SRCDIR
+VPATH = $(SRCDIR)
+else
+SRCDIR = .
+endif
+
+# Override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+
+DESTDIR=
+
+# To enable assembler optimizations, add '-DPNG_USE_PNGGCCRD' to
+# $CFLAGS, and include pnggccrd.o in $OBJS, below, and in the dependency
+# list at the bottom of this makefile.
+
+CC=gcc
+ifdef MINGW
+MINGW_CCFLAGS=-mno-cygwin -I/usr/include/mingw
+MINGW_LDFLAGS=-mno-cygwin -L/usr/lib/mingw
+endif
+
+# Where "make install" puts libpng*.a, *png*.dll, png.h, and pngconf.h
+ifndef prefix
+prefix=/usr
+$(warning You haven't specified a 'prefix=' location. Defaulting to "/usr")
+endif
+
+# Where the zlib library and include files are located
+ZLIBLIB= /usr/lib
+ZLIBINC=
+#ZLIBLIB=../zlib
+#ZLIBINC=../zlib
+
+ALIGN=
+# for i386:
+#ALIGN=-malign-loops=2 -malign-functions=2
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+
+### if you use the asm, add pnggccrd.o to the OBJS list
+###
+### if you don't need thread safety, but want the asm accel
+#CFLAGS= $(strip $(MINGW_CCFLAGS) -DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD \
+# $(addprefix -I,$(ZLIBINC)) -Wall -O3 $(ALIGN) -funroll-loops \
+# -fomit-frame-pointer) # $(WARNMORE) -g -DPNG_DEBUG=5
+### if you need thread safety and want (minimal) asm accel
+#CFLAGS= $(strip $(MINGW_CCFLAGS) -DPNG_USE_PNGGCCRD $(addprefix -I,$(ZLIBINC)) \
+# -Wall -O3 $(ALIGN) -funroll-loops \
+# -fomit-frame-pointer) # $(WARNMORE) -g -DPNG_DEBUG=5
+### Normal (non-asm) compilation
+CFLAGS= $(strip $(MINGW_CCFLAGS) $(addprefix -I,$(ZLIBINC)) \
+ -Wall -O3 $(ALIGN) -funroll-loops \
+ -fomit-frame-pointer) # $(WARNMORE) -g -DPNG_DEBUG=5
+
+LIBNAME = libpng12
+PNGMAJ = 0
+CYGDLL = 12
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+SHAREDLIB=cygpng$(CYGDLL).dll
+STATLIB=libpng.a
+IMPLIB=libpng.dll.a
+SHAREDDEF=libpng.def
+LIBS=$(SHAREDLIB) $(STATLIB)
+EXE=.exe
+
+LDFLAGS=$(strip -L. $(MINGW_LDFLAGS) -lpng $(addprefix -L,$(ZLIBLIB)) -lz)
+LDSFLAGS=$(strip -shared -L. $(MINGW_LDFLAGS) -Wl,--export-all)
+LDEXTRA=-Wl,--out-implib=$(IMPLIB) $(addprefix -L,$(ZLIBLIB)) -lz
+
+MKDIR=/bin/mkdir -pv
+RANLIB=ranlib
+#RANLIB=echo
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+BINPATH=$(prefix)/bin
+MANPATH=$(prefix)/man
+MAN3PATH=$(MANPATH)/man3
+MAN5PATH=$(MANPATH)/man5
+
+# cosmetic: shortened strings:
+S =$(SRCDIR)
+D =$(DESTDIR)
+DB =$(D)$(BINPATH)
+DI =$(D)$(INCPATH)
+DL =$(D)$(LIBPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o # pnggccrd.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+%.o : %.c
+ $(CC) -c $(CFLAGS) -o $@ $<
+%.pic.o : CFLAGS += -DPNG_BUILD_DLL
+%.pic.o : %.c
+ $(CC) -c $(CFLAGS) -o $@ $<
+
+all: all-static all-shared libpng.pc libpng-config libpng.pc libpng-config
+
+# Make this to verify that "make [...] install" will do what you want.
+buildsetup-tell:
+ @echo VPATH is set to: \"$(VPATH)\"
+ @echo prefix is set to: \"$(prefix)\"
+ @echo -e INCPATH,LIBPATH, etc. are set to:'\n' \
+ $(addprefix $(D),$(INCPATH)'\n' $(LIBPATH)'\n' $(BINPATH)'\n' \
+ $(MANPATH)'\n' $(MAN3PATH)'\n' $(MAN5PATH)'\n')'\n'
+
+libpng.pc: scripts/libpng.pc.in
+ @echo -e Making pkg-config file for this libpng installation..'\n' \
+ using PREFIX=\"$(prefix)\"'\n'
+ cat $(S)/scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! | \
+ sed -e s/-lm// > libpng.pc
+
+libpng-config: scripts/libpng-config-head.in scripts/libpng-config-body.in
+ @echo -e Making $(LIBNAME) libpng-config file for this libpng \
+ installation..'\n' using PREFIX=\"$(prefix)\"'\n'
+ ( cat $(S)/scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo libs=\"-lpng$(CYGDLL) -lz\"; \
+ cat $(S)/scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+static: all-static
+shared: all-shared
+all-static: $(STATLIB) pngtest-stat$(EXE)
+all-shared: $(SHAREDLIB) pngtest$(EXE)
+
+pnggccrd.o: pnggccrd.c png.h pngconf.h
+ @echo ""
+ @echo ' You can ignore the "control reaches end of non-void function"'
+ @echo ' warning and "<variable> defined but not used" warnings:'
+ @echo ""
+ $(CC) -c $(CFLAGS) -o $@ $<
+
+pnggccrd.pic.o: pnggccrd.c png.h pngconf.h
+ @echo ""
+ @echo ' You can ignore the "control reaches end of non-void function"'
+ @echo ' warning and "<variable> defined but not used" warnings:'
+ @echo ""
+ $(CC) -c $(CFLAGS) -DPNG_BUILD_DLL -o $@ $<
+
+$(STATLIB): $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+$(SHAREDDEF): projects/msvc/png32ms.def
+ cat $< | sed -e '1{G;s/^\(.*\)\(\n\)/EXPORTS/;};2,/^EXPORTS/d' | \
+ sed -e 's/\([^;]*\);/;/' > $@
+
+$(SHAREDLIB): $(OBJSDLL) $(SHAREDDEF)
+ $(CC) $(LDSFLAGS) -o $@ $(OBJSDLL) -L. $(LDEXTRA)
+
+pngtest$(EXE): pngtest.pic.o $(SHAREDLIB)
+ $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
+
+pngtest-stat$(EXE): pngtest.o $(STATLIB)
+ $(CC) -static $(CFLAGS) $< $(LDFLAGS) -o $@
+
+pngtest.pic.o: pngtest.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+pngtest.o: pngtest.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+test: test-static test-shared
+
+test-static: pngtest-stat$(EXE)
+ ./pngtest-stat $(S)/pngtest.png
+
+test-shared: pngtest$(EXE)
+ ./pngtest $(S)/pngtest.png
+
+install-static: $(STATLIB) install-headers install-man
+ -@if [ ! -d $(DL) ]; then $(MKDIR) $(DL); fi
+ install -m 644 $(STATLIB) $(DL)/$(LIBNAME).a
+ -@rm -f $(DL)/$(STATLIB)
+ (cd $(DL); ln -sf $(LIBNAME).a $(STATLIB))
+
+install-shared: $(SHAREDLIB) libpng.pc libpng-config install-headers install-man
+ -@if [ ! -d $(DL) ]; then $(MKDIR) $(DL); fi
+ -@if [ ! -d $(DB) ]; then $(MKDIR) $(DB); fi
+ -@if [ ! -d $(DL)/pkgconfig ]; then $(MKDIR) $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ install -m 644 $(IMPLIB) $(DL)/$(LIBNAME).dll.a
+ -@rm -f $(DL)/$(IMPLIB)
+ (cd $(DL); ln -sf $(LIBNAME).dll.a $(IMPLIB))
+ install -s -m 755 $(SHAREDLIB) $(DB)
+ install -m 644 libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc)
+
+install-headers:
+ -@if [ ! -d $(DI) ]; then $(MKDIR) $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then $(MKDIR) $(DI)/$(LIBNAME); fi
+ -@rm -f $(DI)/png.h
+ -@rm -f $(DI)/pngconf.h
+ install -m 644 $(S)/png.h $(S)/pngconf.h $(DI)/$(LIBNAME)
+ -@rm -f $(DI)/libpng
+ (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .)
+
+install-man:
+ -@if [ ! -d $(D)$(MAN3PATH) ]; then $(MKDIR) $(D)$(MAN3PATH); fi
+ -@if [ ! -d $(D)$(MAN5PATH) ]; then $(MKDIR) $(D)$(MAN5PATH); fi
+ install -m 644 $(S)/libpngpf.3 $(S)/libpng.3 $(D)$(MAN3PATH)
+ install -m 644 $(S)/png.5 $(D)$(MAN5PATH)
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+# Run this to verify that a future `configure' run will pick up the settings
+# you want.
+test-config-install: SHELL=/bin/bash
+test-config-install: $(DB)/libpng-config
+ @echo -e Testing libpng-config functions...'\n'
+ @ for TYRA in LDFLAGS CPPFLAGS CFLAGS LIBS VERSION; \
+ do \
+ printf "(%d)\t %10s =%s\n" $$(($$gytiu + 1)) $$TYRA \
+ "$$($(DB)/libpng-config `echo --$$TYRA |tr '[:upper:]' '[:lower:]'`)"; \
+ gytiu=$$(( $$gytiu + 1 )); \
+ done
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ $(CC) $(CFLAGS) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) \
+ -o pngtesti$(EXE) `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti$(EXE) pngtest.png
+
+clean:
+ /bin/rm -f *.pic.o *.o $(STATLIB) $(IMPLIB) $(SHAREDLIB) \
+ pngtest-stat$(EXE) pngtest$(EXE) pngout.png $(SHAREDDEF) \
+ libpng-config libpng.pc pngtesti$(EXE)
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+.PHONY: buildsetup-tell libpng.pc libpng-config test-config-install clean
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h png.c
+pngerror.o pngerror.pic.o: png.h pngconf.h pngerror.c
+pngrio.o pngrio.pic.o: png.h pngconf.h pngrio.c
+pngwio.o pngwio.pic.o: png.h pngconf.h pngwio.c
+pngmem.o pngmem.pic.o: png.h pngconf.h pngmem.c
+pngset.o pngset.pic.o: png.h pngconf.h pngset.c
+pngget.o pngget.pic.o: png.h pngconf.h pngget.c
+pngread.o pngread.pic.o: png.h pngconf.h pngread.c
+pngrtran.o pngrtran.pic.o: png.h pngconf.h pngrtran.c
+pngrutil.o pngrutil.pic.o: png.h pngconf.h pngrutil.c
+pngtrans.o pngtrans.pic.o: png.h pngconf.h pngtrans.c
+pngwrite.o pngwrite.pic.o: png.h pngconf.h pngwrite.c
+pngwtran.o pngwtran.pic.o: png.h pngconf.h pngwtran.c
+pngwutil.o pngwutil.pic.o: png.h pngconf.h pngwutil.c
+pngpread.o pngpread.pic.o: png.h pngconf.h pngpread.c
+
+pngtest.o: png.h pngconf.h pngtest.c
+pngtest-stat.o: png.h pngconf.h pngtest.c
+
+
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.darwin b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.darwin
new file mode 100644
index 0000000..b04044f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.darwin
@@ -0,0 +1,205 @@
+# makefile for libpng on Darwin / Mac OS X
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 2001 Christoph Pfisterer
+# derived from makefile.linux:
+# Copyright (C) 1998, 1999 Greg Roelofs
+# Copyright (C) 1996, 1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+# where "make install" puts libpng.a, libpng12.dylib, png.h and pngconf.h
+prefix=/usr/local
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+CC=cc
+CFLAGS=-I$(ZLIBINC) -Wall -O3 -funroll-loops
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng12 -lz
+
+#RANLIB=echo
+RANLIB=ranlib
+
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+LIBNAME = libpng12
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -fno-common -o $@ $*.c
+
+all: libpng.a $(LIBNAME).dylib pngtest libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! | \
+ sed -e s/-lm// > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).dylib: $(LIBNAME).$(PNGMAJ).dylib
+ ln -sf $(LIBNAME).$(PNGMAJ).dylib $(LIBNAME).dylib
+
+$(LIBNAME).$(PNGMAJ).dylib: $(LIBNAME).$(PNGVER).dylib
+ ln -sf $(LIBNAME).$(PNGVER).dylib $(LIBNAME).$(PNGMAJ).dylib
+
+$(LIBNAME).$(PNGVER).dylib: $(OBJSDLL)
+ $(CC) -dynamiclib \
+ -install_name $(DL)/$(LIBNAME).$(PNGMAJ).dylib \
+ -flat_namespace -undefined suppress \
+ -o $(LIBNAME).$(PNGVER).dylib \
+ $(OBJSDLL)
+
+libpng.3.$(PNGMIN).dylib: $(OBJSDLL)
+ $(CC) -dynamiclib \
+ -install_name $(DL)/libpng.3.dylib \
+ -current_version 3 -compatibility_version 3 \
+ -flat_namespace -undefined suppress \
+ -o libpng.3.$(PNGMIN).dylib \
+ $(OBJSDLL)
+
+pngtest: pngtest.o $(LIBNAME).dylib
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -sf $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).dylib libpng.pc \
+ libpng.3.$(PNGMIN).dylib
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).$(PNGVER)*.dylib
+ -@/bin/rm -f $(DL)/$(LIBNAME).dylib
+ -@/bin/rm -f $(DL)/libpng.dylib
+ -@/bin/rm -f $(DL)/libpng.3.dylib
+ -@/bin/rm -f $(DL)/libpng.3.$(PNGMIN)*.dylib
+ cp $(LIBNAME).$(PNGVER).dylib $(DL)
+ cp libpng.3.$(PNGMIN).dylib $(DL)
+ chmod 755 $(DL)/$(LIBNAME).$(PNGVER).dylib
+ chmod 755 $(DL)/libpng.3.$(PNGMIN).dylib
+ (cd $(DL); \
+ ln -sf libpng.3.$(PNGMIN).dylib libpng.3.dylib; \
+ ln -sf libpng.3.dylib libpng.dylib; \
+ ln -sf $(LIBNAME).$(PNGVER).dylib $(LIBNAME).$(PNGMAJ).dylib; \
+ ln -sf $(LIBNAME).$(PNGMAJ).dylib $(LIBNAME).dylib)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ $(CC) $(CFLAGS) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ rm -f *.o libpng.a pngtest pngout.png libpng-config \
+ libpng.3.$(PNGMIN).dylib \
+ libpng.pc $(LIBNAME).*dylib pngtesti
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.dec b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.dec
new file mode 100644
index 0000000..5d7a11e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.dec
@@ -0,0 +1,185 @@
+# makefile for libpng on DEC Alpha Unix
+# Copyright (C) 2000-2002 Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+LIBNAME = libpng12
+
+CC=cc
+CFLAGS=-std -w1 -I$(ZLIBINC) -O # -g -DPNG_DEBUG=1
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
+
+#RANLIB=echo
+RANLIB=ranlib
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: $(LIBNAME).so libpng.a pngtest libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo ccopts=\"-std\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -f -s $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJS)
+ $(CC) -shared -o $@ $(OBJS) -L$(ZLIBLIB)
+ -soname $(LIBNAME).so.$(PNGMAJ)
+
+libpng.so.3.$(PNGMIN): $(OBJS)
+ $(CC) -shared -o $@ $(OBJS) -L$(ZLIBLIB)
+ -soname libpng.so.3
+
+pngtest: pngtest.o libpng.a
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -sf $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGMIN)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -f -s libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -f -s libpng.so.3 libpng.so; \
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ); \
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ echo
+ echo Testing installed dynamic shared library.
+ $(CC) -w1 -I$(ZLIBINC) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) -R$(ZLIBLIB) \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngtesti pngout.png \
+ libpng-config $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* \
+ libpng.so.3.$(PNGMIN) \
+ libpng.pc
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.dj2 b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.dj2
new file mode 100644
index 0000000..09045c2
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.dj2
@@ -0,0 +1,55 @@
+# DJGPP (DOS gcc) makefile for libpng
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# where make install will put libpng.a and png.h
+#prefix=/usr/local
+prefix=.
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+CC=gcc
+CFLAGS=-I../zlib -O
+LDFLAGS=-L. -L../zlib/ -lpng -lz -lm
+
+RANLIB=ranlib
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o pngwtran.o \
+ pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+ coff2exe pngtest
+
+test: pngtest
+ ./pngtest
+clean:
+ rm -f *.o libpng.a pngtest pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.freebsd b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.freebsd
new file mode 100644
index 0000000..d7d5fae
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.freebsd
@@ -0,0 +1,48 @@
+# makefile for libpng under FreeBSD
+# Copyright (C) 2002 Glenn Randers-Pehrson and Andrey A. Chernov
+# For conditions of distribution and use, see copyright notice in png.h
+
+PREFIX?= /usr/local
+SHLIB_VER?= 5
+
+LIB= png
+SHLIB_MAJOR= ${SHLIB_VER}
+SHLIB_MINOR= 0
+NOPROFILE= YES
+NOOBJ= YES
+
+# where make install puts libpng.a and png.h
+DESTDIR= ${PREFIX}
+LIBDIR= /lib
+INCS= png.h pngconf.h
+INCSDIR= /include/libpng
+INCDIR= ${INCSDIR} # for 4.x bsd.lib.mk
+MAN= libpng.3 libpngpf.3 png.5
+MANDIR= /man/man
+SYMLINKS= libpng/png.h ${INCSDIR}/../png.h \
+ libpng/pngconf.h ${INCSDIR}/../pngconf.h
+LDADD+= -lm -lz
+DPADD+= ${LIBM} ${LIBZ}
+
+CFLAGS+= -I. -DPNG_USE_PNGGCCRD
+.if (${MACHINE_ARCH} != "i386")
+CFLAGS+= -DPNG_NO_ASSEMBLER_CODE
+.endif
+
+SRCS= png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \
+ pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \
+ pngwtran.c pngmem.c pngerror.c pngpread.c pnggccrd.c
+
+pngtest: pngtest.o libpng.a
+ ${CC} ${CFLAGS} -L. -static -o pngtest pngtest.o -lpng -lz -lm
+
+CLEANFILES= pngtest pngtest.o pngout.png
+
+test: pngtest
+ ./pngtest
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+.include <bsd.lib.mk>
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.gcc b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.gcc
new file mode 100644
index 0000000..f7fc368
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.gcc
@@ -0,0 +1,66 @@
+# makefile for libpng using gcc (generic, static library)
+# Copyright (C) 2000 Cosmin Truta
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Location of the zlib library and include files
+ZLIBINC = ../zlib
+ZLIBLIB = ../zlib
+
+# Compiler, linker, lib and other tools
+CC = gcc
+LD = $(CC)
+AR = ar rcs
+RANLIB = ranlib
+RM = rm -f
+
+CDEBUG = -g -DPNG_DEBUG=5
+LDDEBUG =
+CRELEASE = -O2
+LDRELEASE = -s
+CFLAGS = -I$(ZLIBINC) -Wall $(CRELEASE)
+LDFLAGS = -L. -L$(ZLIBLIB) -lpng -lz -lm $(LDRELEASE)
+
+# File extensions
+O=.o
+A=.a
+E=
+
+# Variables
+OBJS = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O) \
+ pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O) \
+ pngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O)
+
+# Targets
+all: libpng$(A) pngtest$(E)
+
+libpng$(A): $(OBJS)
+ $(AR) $@ $(OBJS)
+ $(RANLIB) $@
+
+test: pngtest$(E)
+ ./pngtest$(E)
+
+pngtest$(E): pngtest$(O) libpng$(A)
+ $(LD) -o $@ pngtest$(O) $(LDFLAGS)
+
+clean:
+ $(RM) *$(O) libpng$(A) pngtest$(E) pngout.png
+
+png$(O): png.h pngconf.h
+pngerror$(O): png.h pngconf.h
+pngget$(O): png.h pngconf.h
+pngmem$(O): png.h pngconf.h
+pngpread$(O): png.h pngconf.h
+pngread$(O): png.h pngconf.h
+pngrio$(O): png.h pngconf.h
+pngrtran$(O): png.h pngconf.h
+pngrutil$(O): png.h pngconf.h
+pngset$(O): png.h pngconf.h
+pngtest$(O): png.h pngconf.h
+pngtrans$(O): png.h pngconf.h
+pngwio$(O): png.h pngconf.h
+pngwrite$(O): png.h pngconf.h
+pngwtran$(O): png.h pngconf.h
+pngwutil$(O): png.h pngconf.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.gcmmx b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.gcmmx
new file mode 100644
index 0000000..d0dfdd9
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.gcmmx
@@ -0,0 +1,249 @@
+# makefile for libpng.a and libpng12.so on Linux ELF with gcc using MMX
+# assembler code
+# Copyright 2002 Greg Roelofs and Glenn Randers-Pehrson
+# Copyright 1998-2001 Greg Roelofs
+# Copyright 1996-1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+# CAUTION: Do not use this makefile with gcc versions 2.7.2.2 and earlier.
+
+# WARNING: The assembler code in pnggccrd.c may not be thread safe.
+
+# NOTE: When testing MMX performance on a multitasking system, make sure
+# there are no floating-point programs (e.g., SETI@Home) running in
+# the background! Context switches between MMX and FPU are expensive.
+
+LIBNAME = libpng12
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+CC=gcc
+
+# where "make install" puts libpng12.a, libpng12.so*,
+# libpng12/png.h and libpng12/pngconf.h
+# Prefix must be a full pathname.
+prefix=/usr/local
+
+# Where the zlib library and include files are located.
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+ALIGN=
+# for i386:
+#ALIGN=-malign-loops=2 -malign-functions=2
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+
+# for pgcc version 2.95.1, -O3 is buggy; don't use it.
+
+# Remove -DPNG_THREAD_UNSAFE_OK if you need thread safety
+### for generic gcc:
+CFLAGS=-DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD -I$(ZLIBINC) -Wall \
+ -O3 $(ALIGN) -funroll-loops \
+ -fomit-frame-pointer # $(WARNMORE) -g -DPNG_DEBUG=5
+### for gcc 2.95.2 on 686:
+#CFLAGS=-DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD -I$(ZLIBINC) -Wall -O3 \
+# -mcpu=i686 -malign-double -ffast-math -fstrict-aliasing \
+# $(ALIGN) -funroll-loops -funroll-all-loops -fomit-frame-pointer
+### for gcc 2.7.2.3 on 486 and up:
+#CFLAGS=-DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD -I$(ZLIBINC) -Wall -O3 \
+# -m486 -malign-double -ffast-math \
+# $(ALIGN) -funroll-loops -funroll-all-loops -fomit-frame-pointer
+
+LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng12 -lz -lm
+LDFLAGS_A=-L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) libpng.a -lz -lm
+
+RANLIB=ranlib
+#RANLIB=echo
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o pnggccrd.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c
+
+all: libpng.a $(LIBNAME).so pngtest pngtest-static libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo cppflags=\"-DPNG_THREAD_UNSAFE_OK -DPNG_USE_PNGGCCRD\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo R_opts=\"-Wl,-rpath,$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+pnggccrd.o: pnggccrd.c png.h pngconf.h
+ $(CC) -c $(CFLAGS) -o $@ $*.c
+
+pnggccrd.pic.o: pnggccrd.c png.h pngconf.h
+ $(CC) -c $(CFLAGS) -fPIC -o $@ pnggccrd.c
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJSDLL)
+ $(CC) -shared -Wl,-soname,$(LIBNAME).so.$(PNGMAJ) \
+ -o $(LIBNAME).so.$(PNGVER) \
+ $(OBJSDLL)
+
+libpng.so.3.$(PNGMIN): $(OBJSDLL)
+ $(CC) -shared -Wl,-soname,libpng.so.3 \
+ -o libpng.so.3.$(PNGMIN) \
+ $(OBJSDLL)
+
+pngtest: pngtest.o $(LIBNAME).so
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+pngtest-static: pngtest.o libpng.a
+ $(CC) -o pngtest-static $(CFLAGS) pngtest.o $(LDFLAGS_A)
+
+test: pngtest pngtest-static
+ @echo ""
+ @echo " Running pngtest dynamically linked with $(LIBNAME).so:"
+ @echo ""
+ ./pngtest
+ @echo ""
+ @echo " Running pngtest statically linked with libpng.a:"
+ @echo ""
+ ./pngtest-static
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -sf $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGMIN)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -sf libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -sf libpng.so.3 libpng.so; \
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ); \
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ $(CC) -I$(ZLIBINC) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngout.png libpng-config \
+ $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* pngtest-static pngtesti \
+ libpng.so.3.$(PNGMIN) \
+ libpng.pc
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+png.o png.pic.o: png.h pngconf.h png.c
+pngerror.o pngerror.pic.o: png.h pngconf.h pngerror.c
+pngrio.o pngrio.pic.o: png.h pngconf.h pngrio.c
+pngwio.o pngwio.pic.o: png.h pngconf.h pngwio.c
+pngmem.o pngmem.pic.o: png.h pngconf.h pngmem.c
+pngset.o pngset.pic.o: png.h pngconf.h pngset.c
+pngget.o pngget.pic.o: png.h pngconf.h pngget.c
+pngread.o pngread.pic.o: png.h pngconf.h pngread.c
+pngrtran.o pngrtran.pic.o: png.h pngconf.h pngrtran.c
+pngrutil.o pngrutil.pic.o: png.h pngconf.h pngrutil.c
+pngtrans.o pngtrans.pic.o: png.h pngconf.h pngtrans.c
+pngwrite.o pngwrite.pic.o: png.h pngconf.h pngwrite.c
+pngwtran.o pngwtran.pic.o: png.h pngconf.h pngwtran.c
+pngwutil.o pngwutil.pic.o: png.h pngconf.h pngwutil.c
+pngpread.o pngpread.pic.o: png.h pngconf.h pngpread.c
+
+pngtest.o: png.h pngconf.h pngtest.c
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.hpgcc b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.hpgcc
new file mode 100644
index 0000000..f677308
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.hpgcc
@@ -0,0 +1,217 @@
+# makefile for libpng on HP-UX using GCC with the HP ANSI/C linker.
+# Copyright (C) 2002, Glenn Randers-Pehrson
+# Copyright (C) 2001, Laurent faillie
+# Copyright (C) 1998, 1999 Greg Roelofs
+# Copyright (C) 1996, 1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=gcc
+LD=ld
+
+# where "make install" puts libpng.a, libpng.sl*, png.h and pngconf.h
+prefix=/usr/local
+
+# Where the zlib library and include files are located
+ZLIBLIB=/opt/zlib/lib
+ZLIBINC=/opt/zlib/include
+
+# Note that if you plan to build a libpng shared library, zlib must also
+# be a shared library, which zlib's configure does not do. After running
+# zlib's configure, edit the appropriate lines of makefile to read:
+# CFLAGS=-O1 -DHAVE_UNISTD -DUSE_MAP -fPIC \
+# LDSHARED=ld -b
+# SHAREDLIB=libz.sl
+
+ALIGN=
+# for i386:
+#ALIGN=-malign-loops=2 -malign-functions=2
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+
+# for pgcc version 2.95.1, -O3 is buggy; don't use it.
+
+CFLAGS=-I$(ZLIBINC) -Wall -O3 -funroll-loops \
+ $(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5
+#LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng12 -lz -lm
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng12 -lz -lm
+
+RANLIB=ranlib
+#RANLIB=echo
+
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+LIBNAME = libpng12
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c
+
+all: libpng.a $(LIBNAME).sl pngtest libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).sl: $(LIBNAME).sl.$(PNGMAJ)
+ ln -sf $(LIBNAME).sl.$(PNGMAJ) $(LIBNAME).sl
+
+$(LIBNAME).sl.$(PNGMAJ): $(LIBNAME).sl.$(PNGVER)
+ ln -sf $(LIBNAME).sl.$(PNGVER) $(LIBNAME).sl.$(PNGMAJ)
+
+$(LIBNAME).sl.$(PNGVER): $(OBJSDLL)
+ $(LD) -b +s \
+ +h $(LIBNAME).sl.$(PNGMAJ) -o $(LIBNAME).sl.$(PNGVER) $(OBJSDLL)
+
+libpng.sl.3.$(PNGMIN): $(OBJSDLL)
+ $(LD) -b +s \
+ +h libpng.sl.3 -o libpng.sl.3.$(PNGMIN) $(OBJSDLL)
+
+pngtest: pngtest.o $(LIBNAME).sl
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -sf $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).sl.$(PNGVER) libpng.pc \
+ libpng.sl.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).sl.$(PNGVER)* $(DL)/$(LIBNAME).sl
+ -@/bin/rm -f $(DL)/libpng.sl
+ -@/bin/rm -f $(DL)/libpng.sl.3
+ -@/bin/rm -f $(DL)/libpng.sl.3.$(PNGMIN)*
+ cp $(LIBNAME).sl.$(PNGVER) $(DL)
+ cp libpng.sl.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).sl.$(PNGVER)
+ chmod 755 $(DL)/libpng.sl.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -sf libpng.sl.3.$(PNGMIN) libpng.sl.3; \
+ ln -sf libpng.sl.3 libpng.sl; \
+ ln -sf $(LIBNAME).sl.$(PNGVER) $(LIBNAME).sl.$(PNGMAJ); \
+ ln -sf $(LIBNAME).sl.$(PNGMAJ) $(LIBNAME).sl)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ echo
+ echo Testing installed dynamic shared library.
+ $(CC) -I$(ZLIBINC) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngtesti pngout.png \
+ libpng-config $(LIBNAME).sl $(LIBNAME).sl.$(PNGMAJ)* \
+ libpng.sl.3.$(PNGMIN) \
+ libpng.pc
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.hpux b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.hpux
new file mode 100644
index 0000000..a9c4d35
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.hpux
@@ -0,0 +1,202 @@
+# makefile for libpng, HPUX (10.20 and 11.00) using the ANSI/C product.
+# Copyright (C) 1999-2002 Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42
+# contributed by Jim Rice and updated by Chris Schleicher, Hewlett Packard
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Where the zlib library and include files are located
+ZLIBLIB=/opt/zlib/lib
+ZLIBINC=/opt/zlib/include
+
+# Note that if you plan to build a libpng shared library, zlib must also
+# be a shared library, which zlib's configure does not do. After running
+# zlib's configure, edit the appropriate lines of makefile to read:
+# CFLAGS=-O1 -DHAVE_UNISTD -DUSE_MAP -fPIC \
+# LDSHARED=ld -b
+# SHAREDLIB=libz.sl
+
+CC=cc
+CFLAGS=-I$(ZLIBINC) -O -Ae +DA1.1 +DS2.0
+# Caution: be sure you have built zlib with the same CFLAGS.
+CCFLAGS=-I$(ZLIBINC) -O -Ae +DA1.1 +DS2.0
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
+
+RANLIB=ranlib
+
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+LIBNAME = libpng12
+
+# where make install puts libpng.a, libpng12.sl, and png.h
+prefix=/opt/libpng
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) +z -o $@ $*.c
+
+all: libpng.a $(LIBNAME).sl pngtest libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo ccopts=\"-Ae +DA1.1 +DS2.0\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).sl: $(LIBNAME).sl.$(PNGMAJ)
+ ln -sf $(LIBNAME).sl.$(PNGMAJ) $(LIBNAME).sl
+
+$(LIBNAME).sl.$(PNGMAJ): $(LIBNAME).sl.$(PNGVER)
+ ln -sf $(LIBNAME).sl.$(PNGVER) $(LIBNAME).sl.$(PNGMAJ)
+
+$(LIBNAME).sl.$(PNGVER): $(OBJSDLL)
+ $(LD) -b +s \
+ +h $(LIBNAME).sl.$(PNGMAJ) -o $(LIBNAME).sl.$(PNGVER) $(OBJSDLL)
+
+libpng.sl.3.$(PNGMIN): $(OBJSDLL)
+ $(LD) -b +s \
+ +h libpng.sl.3 -o libpng.sl.3.$(PNGMIN) $(OBJSDLL)
+
+pngtest: pngtest.o libpng.a
+ $(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -sf $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).sl.$(PNGVER) libpng.pc \
+ libpng.sl.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).sl.$(PNGVER)* $(DL)/$(LIBNAME).sl
+ -@/bin/rm -f $(DL)/libpng.sl
+ -@/bin/rm -f $(DL)/libpng.sl.3
+ -@/bin/rm -f $(DL)/libpng.sl.3.$(PNGMIN)*
+ cp $(LIBNAME).sl.$(PNGVER) $(DL)
+ cp libpng.sl.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).sl.$(PNGVER)
+ chmod 755 $(DL)/libpng.sl.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -sf libpng.sl.3.$(PNGMIN) libpng.sl.3; \
+ ln -sf libpng.sl.3 libpng.sl; \
+ ln -sf $(LIBNAME).sl.$(PNGVER) $(LIBNAME).sl.$(PNGMAJ); \
+ ln -sf $(LIBNAME).sl.$(PNGMAJ) $(LIBNAME).sl)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ echo
+ echo Testing installed dynamic shared library.
+ $(CC) $(CCFLAGS) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngtesti pngout.png \
+ libpng-config $(LIBNAME).sl $(LIBNAME).sl.$(PNGMAJ)* \
+ libpng.sl.3.$(PNGMIN) \
+ libpng.pc
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ibmc b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ibmc
new file mode 100644
index 0000000..f09a62c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ibmc
@@ -0,0 +1,71 @@
+# Makefile for libpng (static)
+# IBM C version 3.x for Win32 and OS/2
+# Copyright (C) 2000 Cosmin Truta
+# For conditions of distribution and use, see copyright notice in png.h
+# Notes:
+# Derived from makefile.std
+# All modules are compiled in C mode
+# Tested under Win32, expected to work under OS/2
+# Can be easily adapted for IBM VisualAge/C++ for AIX
+
+# Location of the zlib library and include files
+ZLIBINC = ../zlib
+ZLIBLIB = ../zlib
+
+# Compiler, linker, lib and other tools
+CC = icc
+LD = ilink
+AR = ilib
+RM = del
+
+CFLAGS = -I$(ZLIBINC) -Mc -O2 -W3
+LDFLAGS =
+
+# File extensions
+O=.obj
+A=.lib
+E=.exe
+
+# Variables
+OBJS = png$(O) pngerror$(O) pngget$(O) pngmem$(O) pngpread$(O) \
+ pngread$(O) pngrio$(O) pngrtran$(O) pngrutil$(O) pngset$(O) \
+ pngtrans$(O) pngwio$(O) pngwrite$(O) pngwtran$(O) pngwutil$(O)
+
+LIBS = libpng$(A) $(ZLIBLIB)/zlib$(A)
+
+# Targets
+all: libpng$(A) pngtest$(E)
+
+libpng$(A): $(OBJS)
+ $(AR) -out:$@ $(OBJS)
+
+test: pngtest$(E)
+ pngtest$(E)
+
+pngtest: pngtest$(E)
+
+pngtest$(E): pngtest$(O) libpng$(A)
+ $(LD) $(LDFLAGS) pngtest$(O) $(LIBS)
+
+clean:
+ $(RM) *$(O)
+ $(RM) libpng$(A)
+ $(RM) pngtest$(E)
+ $(RM) pngout.png
+
+png$(O): png.h pngconf.h
+pngerror$(O): png.h pngconf.h
+pngget$(O): png.h pngconf.h
+pngmem$(O): png.h pngconf.h
+pngpread$(O): png.h pngconf.h
+pngread$(O): png.h pngconf.h
+pngrio$(O): png.h pngconf.h
+pngrtran$(O): png.h pngconf.h
+pngrutil$(O): png.h pngconf.h
+pngset$(O): png.h pngconf.h
+pngtest$(O): png.h pngconf.h
+pngtrans$(O): png.h pngconf.h
+pngwio$(O): png.h pngconf.h
+pngwrite$(O): png.h pngconf.h
+pngwtran$(O): png.h pngconf.h
+pngwutil$(O): png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.intel b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.intel
new file mode 100644
index 0000000..1cabe77
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.intel
@@ -0,0 +1,114 @@
+# Makefile for libpng
+# Microsoft Visual C++ with Intel C/C++ Compiler 4.0 and later
+
+# Copyright (C) 2000, Pawel Mrochen, based on makefile.msc which is
+# copyright 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# To use, do "nmake /f scripts\makefile.intel"
+
+
+# ------------------- Intel C/C++ Compiler 4.0 and later -------------------
+
+# Caution: the assembler code was introduced at libpng version 1.0.4 and has
+# not yet been thoroughly tested.
+
+# Use assembler code
+ASMCODE=-DPNG_USE_PNGVCRD
+
+# Where the zlib library and include files are located
+ZLIBLIB=..\zlib
+ZLIBINC=..\zlib
+
+# Target CPU
+CPU=6 # Pentium II
+#CPU=5 # Pentium
+
+# Calling convention
+CALLING=r # __fastcall
+#CALLING=z # __stdcall
+#CALLING=d # __cdecl
+
+# Uncomment next to put error messages in a file
+#ERRFILE=>>pngerrs
+
+# --------------------------------------------------------------------------
+
+
+CC=icl -c
+CFLAGS=-O2 -G$(CPU)$(CALLING) -Qip -Qunroll4 -I$(ZLIBINC) $(ASMCODE) -nologo
+LD=link
+LDFLAGS=/SUBSYSTEM:CONSOLE /NOLOGO
+
+O=.obj
+
+OBJS=png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O) \
+pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O) \
+pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O) pngvcrd$(O)
+
+
+all: test
+
+png$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngset$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngget$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngread$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngpread$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngrtran$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngrutil$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngvcrd$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngerror$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngmem$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngrio$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwio$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngtest$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngtrans$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwrite$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwtran$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwutil$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+libpng.lib: $(OBJS)
+ if exist libpng.lib del libpng.lib
+ lib /NOLOGO /OUT:libpng.lib $(OBJS)
+
+pngtest.exe: pngtest.obj libpng.lib
+ $(LD) $(LDFLAGS) /OUT:pngtest.exe pngtest.obj libpng.lib $(ZLIBLIB)\zlib.lib
+
+test: pngtest.exe
+ pngtest.exe
+
+
+# End of makefile for libpng
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.knr b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.knr
new file mode 100644
index 0000000..44ee538
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.knr
@@ -0,0 +1,99 @@
+# makefile for libpng
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# This makefile requires the file ansi2knr.c, which you can get
+# from the Ghostscript ftp site at ftp://ftp.cs.wisc.edu/ghost/
+# If you have libjpeg, you probably already have ansi2knr.c in the jpeg
+# source distribution.
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+CC=cc
+CFLAGS=-I../zlib -O
+LDFLAGS=-L. -L../zlib/ -lpng -lz -lm
+# flags for ansi2knr
+ANSI2KNRFLAGS=
+
+RANLIB=ranlib
+#RANLIB=echo
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: ansi2knr libpng.a pngtest
+
+# general rule to allow ansi2knr to work
+.c.o:
+ ./ansi2knr $*.c T$*.c
+ $(CC) $(CFLAGS) -c T$*.c
+ rm -f T$*.c $*.o
+ mv T$*.o $*.o
+
+ansi2knr: ansi2knr.c
+ $(CC) $(CFLAGS) $(ANSI2KNRFLAGS) -o ansi2knr ansi2knr.c
+
+libpng.a: ansi2knr $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install: libpng.a
+ -@mkdir $(DESTDIR)$(INCPATH)
+ -@mkdir $(DESTDIR)$(INCPATH)/libpng
+ -@mkdir $(DESTDIR)$(LIBPATH)
+ -@rm -f $(DESTDIR)$(INCPATH)/png.h
+ -@rm -f $(DESTDIR)$(INCPATH)/pngconf.h
+ cp png.h $(DESTDIR)$(INCPATH)/libpng
+ cp pngconf.h $(DESTDIR)$(INCPATH)/libpng
+ chmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h
+ chmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h
+ (cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .)
+ cp libpng.a $(DESTDIR)$(LIBPATH)
+ chmod 644 $(DESTDIR)$(LIBPATH)/libpng.a
+
+clean:
+ rm -f *.o libpng.a pngtest pngout.png ansi2knr
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.linux b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.linux
new file mode 100644
index 0000000..7ec8125
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.linux
@@ -0,0 +1,223 @@
+# makefile for libpng.a and libpng12.so on Linux ELF with gcc
+# Copyright (C) 1998, 1999, 2002 Greg Roelofs and Glenn Randers-Pehrson
+# Copyright (C) 1996, 1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+LIBNAME = libpng12
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+CC=gcc
+
+# where "make install" puts libpng12.a, libpng12.so*,
+# libpng12/png.h and libpng12/pngconf.h
+# Prefix must be a full pathname.
+prefix=/usr/local
+
+# Where the zlib library and include files are located.
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+ALIGN=
+# for i386:
+#ALIGN=-malign-loops=2 -malign-functions=2
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+
+# for pgcc version 2.95.1, -O3 is buggy; don't use it.
+
+CFLAGS=-I$(ZLIBINC) -Wall -O3 -funroll-loops \
+ $(ALIGN) # $(WARNMORE) -g -DPNG_DEBUG=5
+
+LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng12 -lz -lm
+LDFLAGS_A=-L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) libpng.a -lz -lm
+
+RANLIB=ranlib
+#RANLIB=echo
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c
+
+all: libpng.a $(LIBNAME).so pngtest pngtest-static libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo R_opts=\"-Wl,-rpath,$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJSDLL)
+ $(CC) -shared -Wl,-soname,$(LIBNAME).so.$(PNGMAJ) \
+ -o $(LIBNAME).so.$(PNGVER) \
+ $(OBJSDLL)
+
+libpng.so.3.$(PNGMIN): $(OBJSDLL)
+ $(CC) -shared -Wl,-soname,libpng.so.3 \
+ -o libpng.so.3.$(PNGMIN) \
+ $(OBJSDLL)
+
+pngtest: pngtest.o $(LIBNAME).so
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+pngtest-static: pngtest.o libpng.a
+ $(CC) -o pngtest-static $(CFLAGS) pngtest.o $(LDFLAGS_A)
+
+test: pngtest pngtest-static
+ @echo ""
+ @echo " Running pngtest dynamically linked with $(LIBNAME).so:"
+ @echo ""
+ ./pngtest
+ @echo ""
+ @echo " Running pngtest statically linked with libpng.a:"
+ @echo ""
+ ./pngtest-static
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -sf $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGMIN)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -sf libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -sf libpng.so.3 libpng.so; \
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ); \
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ $(CC) -I$(ZLIBINC) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngout.png libpng-config \
+ $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* pngtest-static pngtesti \
+ libpng.so.3.$(PNGMIN) \
+ libpng.pc
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.macosx b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.macosx
new file mode 100644
index 0000000..e348ecf
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.macosx
@@ -0,0 +1,197 @@
+# makefile for libpng, MACOS X
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# Modified by Karin Kosina <kyrah@sim.no> 20011010:
+# build shared library (*.dylib)
+# For conditions of distribution and use, see copyright notice in png.h
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+CC=cc
+
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+CFLAGS=-fno-common -I$(ZLIBINC) -O # -g -DPNG_DEBUG=5
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -current_version $(PNGVER)
+
+LIBNAME=libpng12
+SHAREDLIB_POSTFIX=dylib
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+#RANLIB=echo
+RANLIB=ranlib
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest shared libpng.pc libpng-config
+
+shared: $(LIBNAME).$(PNGVER).$(SHAREDLIB_POSTFIX)
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! | \
+ sed -e s/-lm// > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+$(LIBNAME).$(PNGVER).$(SHAREDLIB_POSTFIX): $(OBJS)
+ cc -dynamiclib -flat_namespace -undefined suppress -o $@ $(OBJS)
+
+libpng.3.$(PNGMIN).$(SHAREDLIB_POSTFIX): $(OBJS)
+ cc -dynamiclib -compatibility_version 3 -flat_namespace \
+ -undefined suppress -o $@ $(OBJS)
+
+pngtest: pngtest.o libpng.a
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -f -s $(LIBNAME) libpng; ln -f -s $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -f -s $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).$(PNGVER).$(SHAREDLIB_POSTFIX) \
+ libpng.pc libpng.3.$(PNGMIN).$(SHAREDLIB_POSTFIX)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f \
+ $(DL)/$(LIBNAME).$(PNGVER)*.$(SHAREDLIB_POSTFIX)
+ -@/bin/rm -f $(DL)/$(LIBNAME).$(SHAREDLIB_POSTFIX)
+ -@/bin/rm -f libpng.$(SHARED_POSTFIX)
+ -@/bin/rm -f libpng.3.$(SHARED_POSTFIX)
+ -@/bin/rm -f libpng.3.$(PNGMIN)*.$(SHARED_POSTFIX)
+ cp libpng.3.$(PNGMIN).$(SHAREDLIB_POSTFIX) $(DL)
+ cp $(LIBNAME).$(PNGVER).$(SHAREDLIB_POSTFIX) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).$(PNGVER).$(SHAREDLIB_POSTFIX)
+ chmod 755 $(DL)/libpng.3.$(PNGMIN).$(SHAREDLIB_POSTFIX)
+ (cd $(DL); \
+ ln -f -s libpng.3.$(PNGMIN).$(SHARED_POSTFIX) \
+ libpng.3.$(SHARED_POSTFIX); \
+ ln -f -s libpng.3.$(SHARED_POSTFIX) libpng.$(SHARED_POSTFIX); \
+ ln -f -s $(LIBNAME).$(PNGVER).$(SHARED_POSTFIX) \
+ libpng.$(SHARED_POSTFIX); \
+ ln -f -s libpng.3.$(PNGMIN).$(SHARED_POSTFIX) \
+ libpng.3.$(SHARED_POSTFIX); \
+ ln -f -s $(LIBNAME).$(PNGVER).$(SHAREDLIB_POSTFIX) \
+ $(LIBNAME).$(PNGMAJ).$(SHAREDLIB_POSTFIX); \
+ ln -f -s $(LIBNAME).$(PNGMAJ).$(SHAREDLIB_POSTFIX) \
+ $(LIBNAME).$(SHAREDLIB_POSTFIX))
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -f -s $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ $(CC) $(CFLAGS) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ rm -f *.o libpng.a pngtest pngout.png libpng-config \
+ $(LIBNAME).$(PNGVER).$(SHAREDLIB_POSTFIX) \
+ $(LIBNAME).$(SHAREDLIB_POSTFIX) \
+ libpng.3.$(PNGMIN).$(SHAREDLIB_POSTFIX) \
+ libpng.pc
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.mips b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.mips
new file mode 100644
index 0000000..f1a557d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.mips
@@ -0,0 +1,83 @@
+# makefile for libpng
+# Copyright (C) Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+CC=cc
+CFLAGS=-I../zlib -O -systype sysv -DSYSV -w -Dmips
+#CFLAGS=-O
+LDFLAGS=-L. -L../zlib/ -lpng -lz -lm
+
+#RANLIB=ranlib
+RANLIB=echo
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install: libpng.a
+ -@mkdir $(DESTDIR)$(INCPATH)
+ -@mkdir $(DESTDIR)$(INCPATH)/libpng
+ -@mkdir $(DESTDIR)$(LIBPATH)
+ -@rm -f $(DESTDIR)$(INCPATH)/png.h
+ -@rm -f $(DESTDIR)$(INCPATH)/pngconf.h
+ cp png.h $(DESTDIR)$(INCPATH)/libpng
+ cp pngconf.h $(DESTDIR)$(INCPATH)/libpng
+ chmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h
+ chmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h
+ (cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .)
+ cp libpng.a $(DESTDIR)$(LIBPATH)
+ chmod 644 $(DESTDIR)$(LIBPATH)/libpng.a
+
+clean:
+ rm -f *.o libpng.a pngtest pngout.png
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.msc b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.msc
new file mode 100644
index 0000000..1cbfd91
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.msc
@@ -0,0 +1,86 @@
+# makefile for libpng
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib
+
+# -------- Microsoft C 5.1 and later, does not use assembler code --------
+MODEL=L
+CFLAGS=-Oait -Gs -nologo -W3 -A$(MODEL) -I..\zlib
+#-Ox generates bad code with MSC 5.1
+CC=cl
+LD=link
+LDFLAGS=/e/st:0x1500/noe
+O=.obj
+
+#uncomment next to put error messages in a file
+ERRFILE= >> pngerrs
+
+# variables
+OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
+OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
+OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
+
+all: libpng.lib
+
+png$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngset$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngget$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngread$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngpread$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrtran$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrutil$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngerror$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngmem$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrio$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwio$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngtest$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngtrans$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwrite$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwtran$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwutil$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
+ del libpng.lib
+ lib libpng $(OBJS1);
+ lib libpng $(OBJS2);
+ lib libpng $(OBJS3);
+
+pngtest.exe: pngtest.obj libpng.lib
+ $(LD) $(LDFLAGS) pngtest.obj,,,libpng.lib ..\zlib\zlib.lib ;
+
+test: pngtest.exe
+ pngtest
+
+# End of makefile for libpng
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ne10bsd b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ne10bsd
new file mode 100644
index 0000000..f5a1a88
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ne10bsd
@@ -0,0 +1,44 @@
+# makefile for libpng for NetBSD for the standard
+# make obj && make depend && make && make test
+# make includes && make install
+# Copyright (C) 2002 Patrick R.L. Welche
+# For conditions of distribution and use, see copyright notice in png.h
+
+# You should also run makefile.netbsd
+
+LOCALBASE?=/usr/local
+LIBDIR= ${LOCALBASE}/lib
+MANDIR= ${LOCALBASE}/man
+INCSDIR=${LOCALBASE}/include/libpng10
+
+LIB= png10
+SHLIB_MAJOR= 0
+SHLIB_MINOR= 1.0.15
+SRCS= pnggccrd.c png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \
+ pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \
+ pngwtran.c pngmem.c pngerror.c pngpread.c
+INCS= png.h pngconf.h
+MAN= libpng.3 libpngpf.3 png.5
+
+CPPFLAGS+=-I${.CURDIR} -DPNG_USE_PNGGCCRD
+
+# something like this for mmx assembler, but it core dumps for me at the moment
+# .if ${MACHINE_ARCH} == "i386"
+# CPPFLAGS+=-DPNG_THREAD_UNSAFE_OK
+# MKLINT= no
+# .else
+ CPPFLAGS+=-DPNG_NO_ASSEMBLER_CODE
+# .endif
+
+CLEANFILES+=pngtest.o pngtest
+
+pngtest.o: pngtest.c
+ ${CC} -c ${CPPFLAGS} ${CFLAGS} ${.ALLSRC} -o ${.TARGET}
+
+pngtest: pngtest.o libpng.a
+ ${CC} ${LDFLAGS} ${.ALLSRC} -o${.TARGET} -lz -lm
+
+test: pngtest
+ cd ${.CURDIR} && ${.OBJDIR}/pngtest
+
+.include <bsd.lib.mk>
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ne12bsd b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ne12bsd
new file mode 100644
index 0000000..4cccc6d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.ne12bsd
@@ -0,0 +1,44 @@
+# makefile for libpng for NetBSD for the standard
+# make obj && make depend && make && make test
+# make includes && make install
+# Copyright (C) 2002 Patrick R.L. Welche
+# For conditions of distribution and use, see copyright notice in png.h
+
+# You should also run makefile.netbsd
+
+LOCALBASE?=/usr/local
+LIBDIR= ${LOCALBASE}/lib
+MANDIR= ${LOCALBASE}/man
+INCSDIR=${LOCALBASE}/include/libpng12
+
+LIB= png12
+SHLIB_MAJOR= 0
+SHLIB_MINOR= 1.2.5
+SRCS= pnggccrd.c png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \
+ pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \
+ pngwtran.c pngmem.c pngerror.c pngpread.c
+INCS= png.h pngconf.h
+MAN= libpng.3 libpngpf.3 png.5
+
+CPPFLAGS+=-I${.CURDIR} -DPNG_USE_PNGGCCRD
+
+# something like this for mmx assembler, but it core dumps for me at the moment
+# .if ${MACHINE_ARCH} == "i386"
+# CPPFLAGS+=-DPNG_THREAD_UNSAFE_OK
+# MKLINT= no
+# .else
+ CPPFLAGS+=-DPNG_NO_ASSEMBLER_CODE
+# .endif
+
+CLEANFILES+=pngtest.o pngtest
+
+pngtest.o: pngtest.c
+ ${CC} -c ${CPPFLAGS} ${CFLAGS} ${.ALLSRC} -o ${.TARGET}
+
+pngtest: pngtest.o libpng.a
+ ${CC} ${LDFLAGS} ${.ALLSRC} -o${.TARGET} -lz -lm
+
+test: pngtest
+ cd ${.CURDIR} && ${.OBJDIR}/pngtest
+
+.include <bsd.lib.mk>
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.netbsd b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.netbsd
new file mode 100644
index 0000000..6b53c4e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.netbsd
@@ -0,0 +1,44 @@
+# makefile for libpng for NetBSD for the standard
+# make obj && make depend && make && make test
+# make includes && make install
+# Copyright (C) 2002 Patrick R.L. Welche
+# For conditions of distribution and use, see copyright notice in png.h
+
+# You should also run makefile.ne0bsd
+
+LOCALBASE?=/usr/local
+LIBDIR= ${LOCALBASE}/lib
+MANDIR= ${LOCALBASE}/man
+INCSDIR=${LOCALBASE}/include/libpng
+
+LIB= png
+SHLIB_MAJOR= 3
+SHLIB_MINOR= 1.2.5
+SRCS= pnggccrd.c png.c pngset.c pngget.c pngrutil.c pngtrans.c pngwutil.c \
+ pngread.c pngrio.c pngwio.c pngwrite.c pngrtran.c \
+ pngwtran.c pngmem.c pngerror.c pngpread.c
+INCS= png.h pngconf.h
+MAN= libpng.3 libpngpf.3 png.5
+
+CPPFLAGS+=-I${.CURDIR} -DPNG_USE_PNGGCCRD
+
+# something like this for mmx assembler, but it core dumps for me at the moment
+# .if ${MACHINE_ARCH} == "i386"
+# CPPFLAGS+=-DPNG_THREAD_UNSAFE_OK
+# MKLINT= no
+# .else
+ CPPFLAGS+=-DPNG_NO_ASSEMBLER_CODE
+# .endif
+
+CLEANFILES+=pngtest.o pngtest
+
+pngtest.o: pngtest.c
+ ${CC} -c ${CPPFLAGS} ${CFLAGS} ${.ALLSRC} -o ${.TARGET}
+
+pngtest: pngtest.o libpng.a
+ ${CC} ${LDFLAGS} ${.ALLSRC} -o${.TARGET} -lz -lm
+
+test: pngtest
+ cd ${.CURDIR} && ${.OBJDIR}/pngtest
+
+.include <bsd.lib.mk>
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.openbsd b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.openbsd
new file mode 100644
index 0000000..af94f40
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.openbsd
@@ -0,0 +1,72 @@
+# makefile for libpng
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+PREFIX?= /usr/local
+LIBDIR= ${PREFIX}/lib
+MANDIR= ${PREFIX}/man/cat
+
+SHLIB_MAJOR= 0
+SHLIB_MINOR= 1.2.5
+
+LIB= png
+SRCS= png.c pngerror.c pnggccrd.c pngget.c pngmem.c pngpread.c \
+ pngread.c pngrio.c pngrtran.c pngrutil.c pngset.c pngtrans.c \
+ pngwio.c pngwrite.c pngwtran.c pngwutil.c
+
+HDRS= png.h pngconf.h
+
+CFLAGS+= -Wall
+CPPFLAGS+= -I${.CURDIR} -DPNG_NO_ASSEMBLER_CODE -DPNG_USE_PNGGCCRD
+
+NOPROFILE= Yes
+
+CLEANFILES+= pngtest.o pngtest
+
+MAN= libpng.3 libpngpf.3 png.5
+DOCS= ANNOUNCE CHANGES LICENSE README libpng.txt
+
+pngtest.o: pngtest.c
+ ${CC} ${CPPFLAGS} ${CFLAGS} -c ${.ALLSRC} -o ${.TARGET}
+
+pngtest: pngtest.o
+ ${CC} ${LDFLAGS} ${.ALLSRC} -o ${.TARGET} -L${.OBJDIR} -lpng -lz -lm
+
+test: pngtest
+ cd ${.OBJDIR} && env \
+ LD_LIBRARY_PATH="${.OBJDIR}" ${.OBJDIR}/pngtest
+
+beforeinstall:
+ if [ ! -d ${DESTDIR}${PREFIX}/include/libpng ]; then \
+ ${INSTALL} -d -o root -g wheel ${DESTDIR}${PREFIX}/include/libpng; \
+ fi
+ if [ ! -d ${DESTDIR}${LIBDIR} ]; then \
+ ${INSTALL} -d -o root -g wheel ${DESTDIR}${LIBDIR}; \
+ fi
+ if [ ! -d ${DESTDIR}${LIBDIR}/debug ]; then \
+ ${INSTALL} -d -o root -g wheel ${DESTDIR}${LIBDIR}/debug; \
+ fi
+ if [ ! -d ${DESTDIR}${MANDIR}3 ]; then \
+ ${INSTALL} -d -o root -g wheel ${DESTDIR}${MANDIR}3; \
+ fi
+ if [ ! -d ${DESTDIR}${MANDIR}5 ]; then \
+ ${INSTALL} -d -o root -g wheel ${DESTDIR}${MANDIR}5; \
+ fi
+ if [ ! -d ${DESTDIR}${PREFIX}/share/doc/png ]; then \
+ ${INSTALL} -d -o root -g wheel ${DESTDIR}${PREFIX}/share/doc/png; \
+ fi
+
+afterinstall:
+ @rm -f ${DESTDIR}${LIBDIR}/libpng_pic.a
+ @rm -f ${DESTDIR}${LIBDIR}/debug/libpng.a
+ @rm -f ${DESTDIR}${PREFIX}/include/png.h
+ @rm -f ${DESTDIR}${PREFIX}/include/pngconf.h
+ @rmdir ${DESTDIR}${LIBDIR}/debug 2>/dev/null || true
+ ${INSTALL} ${INSTALL_COPY} -o ${SHAREOWN} -g ${SHAREGRP} \
+ -m ${NONBINMODE} ${HDRS} ${DESTDIR}${PREFIX}/include/libpng
+ ${INSTALL} ${INSTALL_COPY} -o ${SHAREOWN} -g ${SHAREGRP} \
+ -m ${NONBINMODE} ${HDRS} ${DESTDIR}${PREFIX}/include
+ ${INSTALL} ${INSTALL_COPY} -o ${SHAREOWN} -g ${SHAREGRP} \
+ -m ${NONBINMODE} ${DOCS} ${DESTDIR}${PREFIX}/share/doc/png
+
+.include <bsd.lib.mk>
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.os2 b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.os2
new file mode 100644
index 0000000..588067d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.os2
@@ -0,0 +1,69 @@
+# makefile for libpng on OS/2 with gcc
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Related files: pngos2.def
+
+CC=gcc -Zomf -s
+
+# Where the zlib library and include files are located
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+CFLAGS=-I$(ZLIBINC) -Wall -O6 -funroll-loops -malign-loops=2 \
+ -malign-functions=2 #$(WARNMORE) -g -DPNG_DEBUG=5
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lzdll -Zcrtdll
+AR=emxomfar
+
+PNGLIB=png.lib
+IMPLIB=emximp
+SHAREDLIB=png.dll
+SHAREDLIBIMP=pngdll.lib
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+.SUFFIXES: .c .o
+
+all: $(PNGLIB) $(SHAREDLIB) $(SHAREDLIBIMP)
+
+$(PNGLIB): $(OBJS)
+ $(AR) rc $@ $(OBJS)
+
+$(SHAREDLIB): $(OBJS) pngos2.def
+ $(CC) $(LDFLAGS) -Zdll -o $@ $^
+
+$(SHAREDLIBIMP): pngos2.def
+ $(IMPLIB) -o $@ $^
+
+pngtest.exe: pngtest.o png.dll pngdll.lib
+ $(CC) -o $@ $(CFLAGS) $< $(LDFLAGS)
+
+test: pngtest.exe
+ ./pngtest.exe
+
+clean:
+ rm -f *.o $(PNGLIB) png.dll pngdll.lib pngtest.exe pngout.png
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sco b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sco
new file mode 100644
index 0000000..74068a2
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sco
@@ -0,0 +1,201 @@
+# makefile for SCO OSr5 ELF and Unixware 7 with Native cc
+# Contributed by Mike Hopkirk (hops@sco.com) modified from Makefile.lnx
+# force ELF build dynamic linking, SONAME setting in lib and RPATH in app
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1998 Greg Roelofs
+# Copyright (C) 1996, 1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=cc
+
+# where make install puts libpng.a, libpng.so*, and png.h
+prefix=/usr/local
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+CFLAGS= -dy -belf -I$(ZLIBINC) -O3
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng12 -lz -lm
+
+#RANLIB=ranlib
+RANLIB=echo
+
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+LIBNAME = libpng12
+
+INCPATH=$(prefix)/include/libpng
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -KPIC -o $@ $*.c
+
+all: libpng.a $(LIBNAME).so pngtest libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo ccopts=\"-belf\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -f -s $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJSDLL)
+ $(CC) -G -Wl,-h,$(LIBNAME).so.$(PNGMAJ) -o $(LIBNAME).so.$(PNGVER) \
+ $(OBJSDLL)
+
+libpng.so.3.$(PNGMIN): $(OBJSDLL)
+ $(CC) -G -Wl,-h,libpng.so.3 -o libpng.so.3.$(PNGMIN) \
+ $(OBJSDLL)
+
+pngtest: pngtest.o $(LIBNAME).so
+ LD_RUN_PATH=.:$(ZLIBLIB) $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ -@/bin/rm -f $(DI)/png.h
+ -@/bin/rm -f $(DI)/pngconf.h
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -f -s $(LIBNAME) libpng; ln -f -s $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -f -s $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGMIN)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -f -s libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -f -s libpng.so.3 libpng.so; \
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ); \
+ ln -f -s $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -f -s $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ $(CC) $(CFLAGS) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngout.png libpng-config \
+ $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* pngtest-static pngtesti \
+ libpng.so.3.$(PNGMIN) \
+ libpng.pc
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sggcc b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sggcc
new file mode 100644
index 0000000..082de1b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sggcc
@@ -0,0 +1,211 @@
+# makefile for libpng.a and libpng12.so, SGI IRIX with 'cc'
+# Copyright (C) 2001-2002 Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# Where make install puts libpng.a, libpng12.so, and libpng12/png.h
+# Prefix must be a full pathname.
+
+prefix=/usr/local
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib32
+#ZLIBINC=/usr/local/include
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+LIBNAME=libpng12
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+CC=gcc
+
+# ABI can be blank to use default for your system, -32, -o32, -n32, or -64
+# See "man abi". zlib must be built with the same ABI.
+ABI=
+
+WARNMORE= # -g -DPNG_DEBUG=5
+CFLAGS=$(ABI) -I$(ZLIBINC) -O2 $(WARNMORE) -fPIC -mabi=n32
+LDFLAGS=$(ABI) -L. -L$(ZLIBLIB) -lpng -lz -lm
+LDSHARED=cc $(ABI) -shared -soname $(LIBNAME).so.$(PNGMAJ) \
+ -set_version sgi$(PNGMAJ).0
+LDLEGACY=cc $(ABI) -shared -soname libpng.so.3 \
+ -set_version sgi$3.0
+# See "man dso" for info about shared objects
+
+RANLIB=echo
+#RANLIB=ranlib
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+#LIBPATH=$(prefix)/lib32
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = pnggccrd.o png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest shared libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+shared: $(LIBNAME).so.$(PNGVER)
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo ccopts=\"$(ABI)\"; \
+ echo ldopts=\"$(ABI)\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo libdir=\"$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJS)
+ $(LDSHARED) -o $@ $(OBJS)
+ rm -f $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)
+
+libpng.so.3.$(PNGMIN): $(OBJS)
+ $(LDLEGACY) -o $@ $(OBJS)
+
+pngtest: pngtest.o libpng.a
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ echo
+ echo Testing local static library.
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -sf $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGMIN)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -sf libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -sf libpng.so.3 libpng.so; \
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ); \
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ echo
+ echo Testing installed dynamic shared library.
+ $(CC) -I$(ZLIBINC) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) -rpath $(ZLIBLIB):`$(BINPATH)/libpng12-config --libdir` \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ rm -f *.o libpng.a pngtest pngtesti pngout.png libpng.pc libpng-config \
+ $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* \
+ libpng.so.3.$(PNGMIN) \
+ so_locations
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+pnggccrd.o: png.h pngconf.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sgi b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sgi
new file mode 100644
index 0000000..219b8ad
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sgi
@@ -0,0 +1,217 @@
+# makefile for libpng.a and libpng12.so, SGI IRIX with 'cc'
+# Copyright (C) 2001-2002 Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+LIBNAME=libpng12
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+
+# Where make install puts libpng.a, libpng12.so, and libpng12/png.h
+# Prefix must be a full pathname.
+
+prefix=/usr/local
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib32
+#ZLIBINC=/usr/local/include
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+CC=cc
+
+# ABI can be blank to use default for your system, -32, -o32, -n32, or -64
+# See "man abi". zlib must be built with the same ABI.
+ABI=
+
+WARNMORE=-fullwarn
+# Note: -KPIC is the default anyhow
+#CFLAGS= $(ABI) -I$(ZLIBINC) -O $(WARNMORE) -KPIC -DPNG_USE_PNGGCCRD # -g -DPNG_DEBUG=5
+CFLAGS=$(ABI) -I$(ZLIBINC) -O $(WARNMORE) -DPNG_USE_PNGGCCRD \
+ -DPNG_NO_ASSEMBLER_CODE
+LDFLAGS_A=$(ABI) -L. -L$(ZLIBLIB) -lpng12 -lz -lm
+LDFLAGS=$(ABI) -L. -L$(ZLIBLIB) -lpng -lz -lm
+LDSHARED=cc $(ABI) -shared -soname $(LIBNAME).so.$(PNGMAJ) \
+ -set_version sgi$(PNGMAJ).0
+LDLEGACY=cc $(ABI) -shared -soname libpng.so.3 \
+ -set_version sgi$3.0
+# See "man dso" for info about shared objects
+
+RANLIB=echo
+#RANLIB=ranlib
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+#LIBPATH=$(prefix)/lib32
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = pnggccrd.o png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest shared libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+shared: $(LIBNAME).so.$(PNGVER)
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo cppflags=\"-DPNG_USE_PNGGCCRD -DPNG_NO_ASSEMBLER_CODE\"; \
+ echo ccopts=\"$(ABI)\"; \
+ echo ldopts=\"$(ABI)\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo libdir=\"$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJS)
+ $(LDSHARED) -o $@ $(OBJS)
+ rm -f $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)
+
+libpng.so.3.$(PNGMIN): $(OBJS)
+ $(LDLEGACY) -o $@ $(OBJS)
+
+pngtest: pngtest.o libpng.a
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ echo
+ echo Testing local static library.
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -sf $(LIBNAME) libpng; ln -sf $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -sf $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGMIN)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -sf libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -sf libpng.so.3 libpng.so; \
+ ln -sf $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ); \
+ ln -sf $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -sf $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ echo
+ echo Testing installed dynamic shared library.
+ $(CC) -I$(ZLIBINC) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -L$(ZLIBLIB) -rpath $(ZLIBLIB):`$(BINPATH)/libpng12-config --libdir` \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags`
+ ./pngtesti pngtest.png
+
+clean:
+ rm -f *.o libpng.a pngtest pngtesti pngout.png libpng.pc libpng-config \
+ $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* \
+ libpng.so.3.$(PNGMIN) \
+ so_locations
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+pnggccrd.o: png.h pngconf.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.so9 b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.so9
new file mode 100644
index 0000000..f1ca807
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.so9
@@ -0,0 +1,223 @@
+# makefile for libpng on Solaris 9 (beta) with Forte cc
+# Updated by Chad Schrock for Solaris 9
+# Contributed by William L. Sebok, based on makefile.linux
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1998-2001 Greg Roelofs
+# Copyright (C) 1996-1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+# gcc 2.95 doesn't work.
+CC=cc
+
+# Where make install puts libpng.a, libpng.so*, and png.h
+prefix=/usr/local
+
+# Where the zlib library and include files are located
+# Changing these to ../zlib poses a security risk. If you want
+# to have zlib in an adjacent directory, specify the full path instead of "..".
+#ZLIBLIB=../zlib
+#ZLIBINC=../zlib
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+#Use the preinstalled zlib that comes with Solaris 9:
+ZLIBLIB=/usr/lib
+ZLIBINC=/usr/include
+
+#WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+#CFLAGS=-I$(ZLIBINC) -Wall -O3 $(WARNMORE) -g -DPNG_DEBUG=5
+CFLAGS=-I$(ZLIBINC) -O3
+LDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng12 -lz -lm
+
+#RANLIB=ranlib
+RANLIB=echo
+
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+LIBNAME = libpng12
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -KPIC -o $@ $*.c
+
+all: libpng.a $(LIBNAME).so pngtest libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo R_opts=\"-R$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -f -s $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJSDLL)
+ @case "`type ld`" in *ucb*) \
+ echo; \
+ echo '## WARNING:'; \
+ echo '## The commands "CC" and "LD" must NOT refer to /usr/ucb/cc'; \
+ echo '## and /usr/ucb/ld. If they do, you need to adjust your PATH'; \
+ echo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \
+ echo '## The environment variable LD_LIBRARY_PATH should not be set'; \
+ echo '## at all. If it is, things are likely to break because of'; \
+ echo '## the libucb dependency that is created.'; \
+ echo; \
+ ;; \
+ esac
+ $(LD) -G -h $(LIBNAME).so.$(PNGMAJ) \
+ -o $(LIBNAME).so.$(PNGVER) $(OBJSDLL)
+
+libpng.so.3.$(PNGMIN): $(OBJS)
+ $(LD) -G -h libpng.so.3 \
+ -o libpng.so.3.$(PNGMIN) $(OBJSDLL)
+
+pngtest: pngtest.o $(LIBNAME).so
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -f -s $(LIBNAME) libpng; ln -f -s $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -f -s $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGMIN)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -f -s libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -f -s libpng.so.3 libpng.so; \
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ); \
+ ln -f -s $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so)
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -f -s $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ echo
+ echo Testing installed dynamic shared library.
+ $(CC) -I$(ZLIBINC) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags` \
+ -L$(ZLIBLIB) -R$(ZLIBLIB)
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngtesti pngout.png \
+ libpng-config $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* \
+ libpng.so.3.$(PNGMIN) \
+ libpng.pc
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.solaris b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.solaris
new file mode 100644
index 0000000..9c5a844
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.solaris
@@ -0,0 +1,220 @@
+# makefile for libpng on Solaris 2.x with gcc
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Contributed by William L. Sebok, based on makefile.linux
+# Copyright (C) 1998 Greg Roelofs
+# Copyright (C) 1996, 1997 Andreas Dilger
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC=gcc
+
+# Where make install puts libpng.a, libpng12.so*, and png.h
+prefix=/usr/local
+
+# Where the zlib library and include files are located
+# Changing these to ../zlib poses a security risk. If you want
+# to have zlib in an adjacent directory, specify the full path instead of "..".
+#ZLIBLIB=../zlib
+#ZLIBINC=../zlib
+
+ZLIBLIB=/usr/local/lib
+ZLIBINC=/usr/local/include
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes #-Wconversion
+CFLAGS=-I$(ZLIBINC) -Wall -O3 \
+ # $(WARNMORE) -g -DPNG_DEBUG=5
+LDFLAGS=-L. -R. -L$(ZLIBLIB) -R$(ZLIBLIB) -lpng12 -lz -lm
+
+#RANLIB=ranlib
+RANLIB=echo
+
+PNGMAJ = 0
+PNGMIN = 1.2.5
+PNGVER = $(PNGMAJ).$(PNGMIN)
+LIBNAME = libpng12
+
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+MANPATH=$(prefix)/man
+BINPATH=$(prefix)/bin
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+DB=$(DESTDIR)$(BINPATH)
+DI=$(DESTDIR)$(INCPATH)
+DL=$(DESTDIR)$(LIBPATH)
+DM=$(DESTDIR)$(MANPATH)
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+OBJSDLL = $(OBJS:.o=.pic.o)
+
+.SUFFIXES: .c .o .pic.o
+
+.c.pic.o:
+ $(CC) -c $(CFLAGS) -fPIC -o $@ $*.c
+
+all: libpng.a $(LIBNAME).so pngtest libpng.pc libpng-config
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+libpng.pc:
+ cat scripts/libpng.pc.in | sed -e s\!@PREFIX@!$(prefix)! > libpng.pc
+
+libpng-config:
+ ( cat scripts/libpng-config-head.in; \
+ echo prefix=\"$(prefix)\"; \
+ echo I_opts=\"-I$(INCPATH)/$(LIBNAME)\"; \
+ echo cppflags=\"-DPNG_USE_PNGGCCRD -DPNG_NO_ASSEMBLER_CODE\"; \
+ echo L_opts=\"-L$(LIBPATH)\"; \
+ echo R_opts=\"-R$(LIBPATH)\"; \
+ echo libs=\"-lpng12 -lz -lm\"; \
+ cat scripts/libpng-config-body.in ) > libpng-config
+ chmod +x libpng-config
+
+$(LIBNAME).so: $(LIBNAME).so.$(PNGMAJ)
+ ln -f -s $(LIBNAME).so.$(PNGMAJ) $(LIBNAME).so
+
+$(LIBNAME).so.$(PNGMAJ): $(LIBNAME).so.$(PNGVER)
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ)
+
+$(LIBNAME).so.$(PNGVER): $(OBJSDLL)
+ @case "`type ld`" in *ucb*) \
+ echo; \
+ echo '## WARNING:'; \
+ echo '## The commands "CC" and "LD" must NOT refer to /usr/ucb/cc'; \
+ echo '## and /usr/ucb/ld. If they do, you need to adjust your PATH'; \
+ echo '## environment variable to put /usr/ccs/bin ahead of /usr/ucb.'; \
+ echo '## The environment variable LD_LIBRARY_PATH should not be set'; \
+ echo '## at all. If it is, things are likely to break because of'; \
+ echo '## the libucb dependency that is created.'; \
+ echo; \
+ ;; \
+ esac
+ $(LD) -G -h $(LIBNAME).so.$(PNGMAJ) \
+ -o $(LIBNAME).so.$(PNGVER) $(OBJSDLL)
+
+libpng.so.3.$(PNGMIN): $(OBJS)
+ $(LD) -G -h libpng.so.3 \
+ -o libpng.so.3.$(PNGMIN) $(OBJSDLL)
+
+pngtest: pngtest.o $(LIBNAME).so
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install-headers: png.h pngconf.h
+ -@if [ ! -d $(DI) ]; then mkdir $(DI); fi
+ -@if [ ! -d $(DI)/$(LIBNAME) ]; then mkdir $(DI)/$(LIBNAME); fi
+ cp png.h pngconf.h $(DI)/$(LIBNAME)
+ chmod 644 $(DI)/$(LIBNAME)/png.h $(DI)/$(LIBNAME)/pngconf.h
+ -@/bin/rm -f $(DI)/png.h $(DI)/pngconf.h
+ -@/bin/rm -f $(DI)/libpng
+ (cd $(DI); ln -f -s $(LIBNAME) libpng; ln -f -s $(LIBNAME)/* .)
+
+install-static: install-headers libpng.a
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ cp libpng.a $(DL)/$(LIBNAME).a
+ chmod 644 $(DL)/$(LIBNAME).a
+ -@/bin/rm -f $(DL)/libpng.a
+ (cd $(DL); ln -f -s $(LIBNAME).a libpng.a)
+
+install-shared: install-headers $(LIBNAME).so.$(PNGVER) libpng.pc \
+ libpng.so.3.$(PNGMIN)
+ -@if [ ! -d $(DL) ]; then mkdir $(DL); fi
+ -@/bin/rm -f $(DL)/$(LIBNAME).so.$(PNGVER)* $(DL)/$(LIBNAME).so
+ -@/bin/rm -f $(DL)/libpng.so
+ -@/bin/rm -f $(DL)/libpng.so.3
+ -@/bin/rm -f $(DL)/libpng.so.3.$(PNGMIN)*
+ cp $(LIBNAME).so.$(PNGVER) $(DL)
+ cp libpng.so.3.$(PNGMIN) $(DL)
+ chmod 755 $(DL)/$(LIBNAME).so.$(PNGVER)
+ chmod 755 $(DL)/libpng.so.3.$(PNGMIN)
+ (cd $(DL); \
+ ln -f -s libpng.so.3.$(PNGMIN) libpng.so.3; \
+ ln -f -s libpng.so.3 libpng.so; \
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so; \
+ ln -f -s $(LIBNAME).so.$(PNGVER) $(LIBNAME).so.$(PNGMAJ))
+ -@if [ ! -d $(DL)/pkgconfig ]; then mkdir $(DL)/pkgconfig; fi
+ -@/bin/rm -f $(DL)/pkgconfig/$(LIBNAME).pc
+ -@/bin/rm -f $(DL)/pkgconfig/libpng.pc
+ cp libpng.pc $(DL)/pkgconfig/$(LIBNAME).pc
+ chmod 644 $(DL)/pkgconfig/$(LIBNAME).pc
+ (cd $(DL)/pkgconfig; ln -f -s $(LIBNAME).pc libpng.pc)
+
+install-man: libpng.3 libpngpf.3 png.5
+ -@if [ ! -d $(DM) ]; then mkdir $(DM); fi
+ -@if [ ! -d $(DM)/man3 ]; then mkdir $(DM)/man3; fi
+ -@/bin/rm -f $(DM)/man3/libpng.3
+ -@/bin/rm -f $(DM)/man3/libpngpf.3
+ cp libpng.3 $(DM)/man3
+ cp libpngpf.3 $(DM)/man3
+ -@if [ ! -d $(DM)/man5 ]; then mkdir $(DM)/man5; fi
+ -@/bin/rm -f $(DM)/man5/png.5
+ cp png.5 $(DM)/man5
+
+install-config: libpng-config
+ -@if [ ! -d $(DB) ]; then mkdir $(DB); fi
+ -@/bin/rm -f $(DB)/libpng-config
+ -@/bin/rm -f $(DB)/$(LIBNAME)-config
+ cp libpng-config $(DB)/$(LIBNAME)-config
+ chmod 755 $(DB)/$(LIBNAME)-config
+ (cd $(DB); ln -sf $(LIBNAME)-config libpng-config)
+
+install: install-static install-shared install-man install-config
+
+# If you installed in $(DESTDIR), test-installed won't work until you
+# move the library to its final location.
+
+test-installed:
+ echo
+ echo Testing installed dynamic shared library.
+ $(CC) -I$(ZLIBINC) \
+ `$(BINPATH)/libpng12-config --cflags` pngtest.c \
+ -o pngtesti `$(BINPATH)/libpng12-config --ldflags` \
+ -L$(ZLIBLIB) -R$(ZLIBLIB)
+ ./pngtesti pngtest.png
+
+clean:
+ /bin/rm -f *.o libpng.a pngtest pngtesti pngout.png \
+ libpng-config $(LIBNAME).so $(LIBNAME).so.$(PNGMAJ)* \
+ libpng.so.3.$(PNGMIN) \
+ libpng.pc
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o png.pic.o: png.h pngconf.h
+pngerror.o pngerror.pic.o: png.h pngconf.h
+pngrio.o pngrio.pic.o: png.h pngconf.h
+pngwio.o pngwio.pic.o: png.h pngconf.h
+pngmem.o pngmem.pic.o: png.h pngconf.h
+pngset.o pngset.pic.o: png.h pngconf.h
+pngget.o pngget.pic.o: png.h pngconf.h
+pngread.o pngread.pic.o: png.h pngconf.h
+pngrtran.o pngrtran.pic.o: png.h pngconf.h
+pngrutil.o pngrutil.pic.o: png.h pngconf.h
+pngtrans.o pngtrans.pic.o: png.h pngconf.h
+pngwrite.o pngwrite.pic.o: png.h pngconf.h
+pngwtran.o pngwtran.pic.o: png.h pngconf.h
+pngwutil.o pngwutil.pic.o: png.h pngconf.h
+pngpread.o pngpread.pic.o: png.h pngconf.h
+
+pngtest.o: png.h pngconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.std b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.std
new file mode 100644
index 0000000..5d1f529
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.std
@@ -0,0 +1,89 @@
+# makefile for libpng
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+CC=cc
+CFLAGS=-I$(ZLIBINC) -O # -g -DPNG_DEBUG=5
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
+
+#RANLIB=echo
+RANLIB=ranlib
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install: libpng.a
+ -@mkdir $(DESTDIR)$(INCPATH)
+ -@mkdir $(DESTDIR)$(INCPATH)/libpng
+ -@mkdir $(DESTDIR)$(LIBPATH)
+ -@rm -f $(DESTDIR)$(INCPATH)/png.h
+ -@rm -f $(DESTDIR)$(INCPATH)/pngconf.h
+ cp png.h $(DESTDIR)$(INCPATH)/libpng
+ cp pngconf.h $(DESTDIR)$(INCPATH)/libpng
+ chmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h
+ chmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h
+ (cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .)
+ cp libpng.a $(DESTDIR)$(LIBPATH)
+ chmod 644 $(DESTDIR)$(LIBPATH)/libpng.a
+
+clean:
+ rm -f *.o libpng.a pngtest pngout.png
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sunos b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sunos
new file mode 100644
index 0000000..70a6e88
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.sunos
@@ -0,0 +1,93 @@
+# makefile for libpng
+# Copyright (C) 2002 Glenn Randers-Pehrson
+# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# where make install puts libpng.a and png.h
+prefix=/usr/local
+INCPATH=$(prefix)/include
+LIBPATH=$(prefix)/lib
+
+# override DESTDIR= on the make install command line to easily support
+# installing into a temporary location. Example:
+#
+# make install DESTDIR=/tmp/build/libpng
+#
+# If you're going to install into a temporary location
+# via DESTDIR, $(DESTDIR)$(prefix) must already exist before
+# you execute make install.
+DESTDIR=
+
+# Where the zlib library and include files are located
+#ZLIBLIB=/usr/local/lib
+#ZLIBINC=/usr/local/include
+ZLIBLIB=../zlib
+ZLIBINC=../zlib
+
+
+WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow -Wconversion \
+ -Wmissing-declarations -Wtraditional -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes
+CC=gcc
+CFLAGS=-I$(ZLIBINC) -O # $(WARNMORE) -DPNG_DEBUG=5
+LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
+
+RANLIB=ranlib
+#RANLIB=echo
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
+ pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
+ pngwtran.o pngmem.o pngerror.o pngpread.o
+
+all: libpng.a pngtest
+
+libpng.a: $(OBJS)
+ ar rc $@ $(OBJS)
+ $(RANLIB) $@
+
+pngtest: pngtest.o libpng.a
+ $(CC) -o pngtest $(CFLAGS) pngtest.o $(LDFLAGS)
+
+test: pngtest
+ ./pngtest
+
+install: libpng.a
+ -@mkdir $(DESTDIR)$(INCPATH)
+ -@mkdir $(DESTDIR)$(INCPATH)/libpng
+ -@mkdir $(DESTDIR)$(LIBPATH)
+ -@rm -f $(DESTDIR)$(INCPATH)/png.h
+ -@rm -f $(DESTDIR)$(INCPATH)/pngconf.h
+ cp png.h $(DESTDIR)$(INCPATH)/libpng
+ cp pngconf.h $(DESTDIR)$(INCPATH)/libpng
+ chmod 644 $(DESTDIR)$(INCPATH)/libpng/png.h
+ chmod 644 $(DESTDIR)$(INCPATH)/libpng/pngconf.h
+ (cd $(DESTDIR)$(INCPATH); ln -f -s libpng/* .)
+ cp libpng.a $(DESTDIR)$(LIBPATH)
+ chmod 644 $(DESTDIR)$(LIBPATH)/libpng.a
+
+clean:
+ rm -f *.o libpng.a pngtest pngout.png
+
+DOCS = ANNOUNCE CHANGES INSTALL KNOWNBUG LICENSE README TODO Y2KINFO
+writelock:
+ chmod a-w *.[ch35] $(DOCS) scripts/*
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+png.o: png.h pngconf.h
+pngerror.o: png.h pngconf.h
+pngrio.o: png.h pngconf.h
+pngwio.o: png.h pngconf.h
+pngmem.o: png.h pngconf.h
+pngset.o: png.h pngconf.h
+pngget.o: png.h pngconf.h
+pngread.o: png.h pngconf.h
+pngrtran.o: png.h pngconf.h
+pngrutil.o: png.h pngconf.h
+pngtest.o: png.h pngconf.h
+pngtrans.o: png.h pngconf.h
+pngwrite.o: png.h pngconf.h
+pngwtran.o: png.h pngconf.h
+pngwutil.o: png.h pngconf.h
+pngpread.o: png.h pngconf.h
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.tc3 b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.tc3
new file mode 100644
index 0000000..21435a6
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.tc3
@@ -0,0 +1,89 @@
+# Makefile for libpng
+# TurboC/C++ (Note: All modules are compiled in C mode)
+
+# To use, do "make -fmakefile.tc3"
+
+# ----- Turbo C 3.00 (can be modified to work with earlier versions) -----
+
+MODEL=l
+CFLAGS=-O2 -Z -m$(MODEL) -I..\zlib
+#CFLAGS=-D_NO_PROTO -O2 -Z -m$(MODEL) -I..\zlib # Turbo C older than 3.00
+CC=tcc
+LD=tcc
+LIB=tlib
+LDFLAGS=-m$(MODEL) -L..\zlib
+O=.obj
+E=.exe
+
+# variables
+OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
+OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
+OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
+OBJSL1 = +png$(O) +pngset$(O) +pngget$(O) +pngrutil$(O) +pngtrans$(O)
+OBJSL2 = +pngwutil$(O) +pngmem$(O) +pngpread$(O) +pngread$(O) +pngerror$(O)
+OBJSL3 = +pngwrite$(O) +pngrtran$(O) +pngwtran$(O) +pngrio$(O) +pngwio$(O)
+
+all: libpng$(MODEL).lib pngtest$(E)
+
+pngtest: pngtest$(E)
+
+test: pngtest$(E)
+ pngtest$(E)
+
+png$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngset$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngget$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngread$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngpread$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngrtran$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngrutil$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngerror$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngmem$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngrio$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngwio$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngtest$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngtrans$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngwrite$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngwtran$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+pngwutil$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c
+
+libpng$(MODEL).lib: $(OBJS1) $(OBJS2) $(OBJS3)
+ $(LIB) libpng$(MODEL) +$(OBJSL1)
+ $(LIB) libpng$(MODEL) +$(OBJSL2)
+ $(LIB) libpng$(MODEL) +$(OBJSL3)
+
+pngtest$(E): pngtest$(O) libpng$(MODEL).lib
+ $(LD) $(LDFLAGS) pngtest.obj libpng$(MODEL).lib zlib_$(MODEL).lib
+
+# End of makefile for libpng
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.vcawin32 b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.vcawin32
new file mode 100644
index 0000000..812dd8f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.vcawin32
@@ -0,0 +1,94 @@
+# makefile for libpng
+# Copyright (C) 1998 Tim Wegner
+# For conditions of distribution and use, see copyright notice in png.h
+# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib
+# To use, do "nmake /f scripts\makefile.vcawin32"
+
+# -------- Microsoft Visual C++ 5.0 and later, uses assembler code --------
+
+# Caution: the assembler code was introduced at libpng version 1.0.4 and has
+# not yet been thoroughly tested.
+
+# If you don't want to use assembler code, use makefile.vcwin32 instead.
+
+CFLAGS=-DPNG_USE_PNGVCRD -Ox -GA3s -nologo -W3 -I..\zlib
+
+CC=cl
+LD=link
+LDFLAGS=
+O=.obj
+
+#uncomment next to put error messages in a file
+#ERRFILE= >> pngerrs
+
+# variables
+OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
+OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
+OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O) pngvcrd$(O)
+
+all: libpng.lib
+
+png$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngset$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngget$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngread$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngpread$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrtran$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrutil$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngvcrd$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngerror$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngmem$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrio$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwio$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngtest$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngtrans$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwrite$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwtran$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwutil$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
+ echo something to del > libpng.lib
+ del libpng.lib
+ lib /OUT:libpng.lib $(OBJS1) $(OBJS2) $(OBJS3)
+
+pngtest.exe: pngtest.obj libpng.lib
+ $(LD) $(LDFLAGS) pngtest.obj libpng.lib ..\zlib\zlib.lib /OUT:pngtest.exe /SUBSYSTEM:CONSOLE
+
+test: pngtest.exe
+ pngtest
+
+# End of makefile for libpng
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.vcwin32 b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.vcwin32
new file mode 100644
index 0000000..64b762e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.vcwin32
@@ -0,0 +1,87 @@
+# makefile for libpng
+# Copyright (C) 1998 Tim Wegner
+# For conditions of distribution and use, see copyright notice in png.h
+# Assumes that zlib.lib, zconf.h, and zlib.h have been copied to ..\zlib
+# To use, do "nmake /f scripts\makefile.vcwin32"
+
+# -------- Microsoft Visual C++ 4.0 and later, no assembler code --------
+# If you want to use assembler code, use makefile.vcawin32 instead.
+
+CFLAGS= -Ox -GA3s -nologo -W3 -I..\zlib
+
+CC=cl
+LD=link
+LDFLAGS=
+O=.obj
+
+#uncomment next to put error messages in a file
+#ERRFILE= >> pngerrs
+
+# variables
+OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
+OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
+OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
+
+all: libpng.lib
+
+png$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngset$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngget$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngread$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngpread$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrtran$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrutil$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngerror$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngmem$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngrio$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwio$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngtest$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngtrans$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwrite$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwtran$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+pngwutil$(O): png.h pngconf.h
+ $(CC) -c $(CFLAGS) $*.c $(ERRFILE)
+
+libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
+ echo something to del > libpng.lib
+ del libpng.lib
+ lib /OUT:libpng.lib $(OBJS1) $(OBJS2) $(OBJS3)
+
+pngtest.exe: pngtest.obj libpng.lib
+ $(LD) $(LDFLAGS) pngtest.obj libpng.lib ..\zlib\zlib.lib /OUT:pngtest.exe /SUBSYSTEM:CONSOLE
+
+test: pngtest.exe
+ pngtest
+
+# End of makefile for libpng
+
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.watcom b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.watcom
new file mode 100644
index 0000000..5e860fc
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makefile.watcom
@@ -0,0 +1,109 @@
+# Makefile for libpng
+# Watcom C/C++ 10.0 and later, 32-bit protected mode, flat memory model
+
+# Copyright (C) 2000, Pawel Mrochen, based on makefile.msc which is
+# copyright 1995 Guy Eric Schalnat, Group 42, Inc.
+# For conditions of distribution and use, see copyright notice in png.h
+
+# To use, do "wmake /f scripts\makefile.watcom"
+
+
+# ---------------------- Watcom C/C++ 10.0 and later -----------------------
+
+# Where the zlib library and include files are located
+ZLIBLIB=..\zlib
+ZLIBINC=..\zlib
+
+# Target OS
+OS=DOS
+#OS=NT
+
+# Target CPU
+CPU=6 # Pentium Pro
+#CPU=5 # Pentium
+
+# Calling convention
+CALLING=r # registers
+#CALLING=s # stack
+
+# Uncomment next to put error messages in a file
+#ERRFILE=>>pngerrs
+
+# --------------------------------------------------------------------------
+
+
+CC=wcc386
+CFLAGS=-$(CPU)$(CALLING) -fp$(CPU) -fpi87 -oneatx -mf -bt=$(OS) -i=$(ZLIBINC) -zq
+LD=wcl386
+LDFLAGS=-zq
+
+O=.obj
+
+OBJS1=png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
+OBJS2=pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
+OBJS3=pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
+
+
+all: test
+
+png$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngset$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngget$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngread$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngpread$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngrtran$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngrutil$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngerror$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngmem$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngrio$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwio$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngtest$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngtrans$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwrite$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwtran$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+pngwutil$(O): png.h pngconf.h
+ $(CC) $(CFLAGS) $*.c $(ERRFILE)
+
+libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
+ wlib -b -c -n -q libpng.lib $(OBJS1)
+ wlib -b -c -q libpng.lib $(OBJS2)
+ wlib -b -c -q libpng.lib $(OBJS3)
+
+pngtest.exe: pngtest.obj libpng.lib
+ $(LD) $(LDFLAGS) pngtest.obj libpng.lib $(ZLIBLIB)\zlib.lib
+
+test: pngtest.exe .symbolic
+ pngtest.exe
+
+
+# End of makefile for libpng
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/makevms.com b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makevms.com
new file mode 100644
index 0000000..b9e3895
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/makevms.com
@@ -0,0 +1,144 @@
+$! make libpng under VMS
+$!
+$!
+$! Check for MMK/MMS
+$!
+$! This procedure accepts one parameter (contrib), which causes it to build
+$! the programs from the contrib directory instead of libpng.
+$!
+$ p1 = f$edit(p1,"UPCASE")
+$ if p1 .eqs. "CONTRIB"
+$ then
+$ set def [.contrib.gregbook]
+$ @makevms
+$ set def [-.pngminus]
+$ @makevms
+$ set def [--]
+$ exit
+$ endif
+$ Make = ""
+$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
+$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
+$!
+$! Look for the compiler used
+$!
+$ zlibsrc = "[-.zlib]"
+$ ccopt="/include=''zlibsrc'"
+$ if f$getsyi("HW_MODEL").ge.1024
+$ then
+$ ccopt = "/prefix=all"+ccopt
+$ comp = "__decc__=1"
+$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ else
+$ if f$search("SYS$SYSTEM:DECC$COMPILER.EXE").eqs.""
+$ then
+$ if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ if f$search("SYS$SYSTEM:VAXC.EXE").eqs.""
+$ then
+$ comp = "__gcc__=1"
+$ CC :== GCC
+$ else
+$ comp = "__vaxc__=1"
+$ endif
+$ else
+$ if f$trnlnm("SYS").eqs."" then define sys decc$library_include:
+$ ccopt = "/decc/prefix=all"+ccopt
+$ comp = "__decc__=1"
+$ endif
+$ endif
+$!
+$! Build the thing plain or with mms/mmk
+$!
+$ write sys$output "Compiling Libpng sources ..."
+$ if make.eqs.""
+$ then
+$ dele pngtest.obj;*
+$ CALL MAKE png.OBJ "cc ''CCOPT' png" -
+ png.c png.h pngconf.h
+$ CALL MAKE pngpread.OBJ "cc ''CCOPT' pngpread" -
+ pngpread.c png.h pngconf.h
+$ CALL MAKE pngset.OBJ "cc ''CCOPT' pngset" -
+ pngset.c png.h pngconf.h
+$ CALL MAKE pngget.OBJ "cc ''CCOPT' pngget" -
+ pngget.c png.h pngconf.h
+$ CALL MAKE pngread.OBJ "cc ''CCOPT' pngread" -
+ pngread.c png.h pngconf.h
+$ CALL MAKE pngpread.OBJ "cc ''CCOPT' pngpread" -
+ pngpread.c png.h pngconf.h
+$ CALL MAKE pngrtran.OBJ "cc ''CCOPT' pngrtran" -
+ pngrtran.c png.h pngconf.h
+$ CALL MAKE pngrutil.OBJ "cc ''CCOPT' pngrutil" -
+ pngrutil.c png.h pngconf.h
+$ CALL MAKE pngerror.OBJ "cc ''CCOPT' pngerror" -
+ pngerror.c png.h pngconf.h
+$ CALL MAKE pngmem.OBJ "cc ''CCOPT' pngmem" -
+ pngmem.c png.h pngconf.h
+$ CALL MAKE pngrio.OBJ "cc ''CCOPT' pngrio" -
+ pngrio.c png.h pngconf.h
+$ CALL MAKE pngwio.OBJ "cc ''CCOPT' pngwio" -
+ pngwio.c png.h pngconf.h
+$ CALL MAKE pngtrans.OBJ "cc ''CCOPT' pngtrans" -
+ pngtrans.c png.h pngconf.h
+$ CALL MAKE pngwrite.OBJ "cc ''CCOPT' pngwrite" -
+ pngwrite.c png.h pngconf.h
+$ CALL MAKE pngwtran.OBJ "cc ''CCOPT' pngwtran" -
+ pngwtran.c png.h pngconf.h
+$ CALL MAKE pngwutil.OBJ "cc ''CCOPT' pngwutil" -
+ pngwutil.c png.h pngconf.h
+$ write sys$output "Building Libpng ..."
+$ CALL MAKE libpng.OLB "lib/crea libpng.olb *.obj" *.OBJ
+$ write sys$output "Building pngtest..."
+$ CALL MAKE pngtest.OBJ "cc ''CCOPT' pngtest" -
+ pngtest.c png.h pngconf.h
+$ call make pngtest.exe -
+ "LINK pngtest,libpng.olb/lib,''zlibsrc'libz.olb/lib" -
+ pngtest.obj libpng.olb
+$ write sys$output "Testing Libpng..."
+$ run pngtest
+$ else
+$ if f$search("DESCRIP.MMS") .eqs. "" then copy/nolog [.SCRIPTS]DESCRIP.MMS []
+$ 'make'/macro=('comp',zlibsrc='zlibsrc')
+$ endif
+$ write sys$output "Libpng build completed"
+$ exit
+$!
+$!
+$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES
+$ V = 'F$Verify(0)
+$! P1 = What we are trying to make
+$! P2 = Command to make it
+$! P3 - P8 What it depends on
+$
+$ If F$Search(P1) .Eqs. "" Then Goto Makeit
+$ Time = F$CvTime(F$File(P1,"RDT"))
+$arg=3
+$Loop:
+$ Argument = P'arg
+$ If Argument .Eqs. "" Then Goto Exit
+$ El=0
+$Loop2:
+$ File = F$Element(El," ",Argument)
+$ If File .Eqs. " " Then Goto Endl
+$ AFile = ""
+$Loop3:
+$ OFile = AFile
+$ AFile = F$Search(File)
+$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
+$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
+$ Goto Loop3
+$NextEL:
+$ El = El + 1
+$ Goto Loop2
+$EndL:
+$ arg=arg+1
+$ If arg .Le. 8 Then Goto Loop
+$ Goto Exit
+$
+$Makeit:
+$ VV=F$VERIFY(0)
+$ write sys$output P2
+$ 'P2
+$ VV='F$Verify(VV)
+$Exit:
+$ If V Then Set Verify
+$ENDSUBROUTINE
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/pngdef.pas b/tqtinterface/qt4/src/3rdparty/libpng/scripts/pngdef.pas
new file mode 100644
index 0000000..2ac50c8
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/pngdef.pas
@@ -0,0 +1,795 @@
+unit pngdef;
+
+// Caution: this file has fallen out of date since version 1.0.5. Write to
+// png-implement@ccrc.wustl.edu or to randeg@alum.rpi.edu about volunteering
+// to it up to date.
+
+interface
+
+const
+ PNG_LIBPNG_VER_STRING = '1.2.5';
+ PNG_LIBPNG_VER = 10205;
+
+type
+ png_uint_32 = Cardinal;
+ png_int_32 = Longint;
+ png_uint_16 = Word;
+ png_int_16 = Smallint;
+ png_byte = Byte;
+ png_size_t = png_uint_32;
+ png_charpp = ^png_charp;
+ png_charp = PChar;
+ float = single;
+ int = Integer;
+ png_bytepp = ^png_bytep;
+ png_bytep = ^png_byte;
+ png_uint_16p = ^png_uint_16;
+ png_uint_16pp = ^png_uint_16p;
+ png_voidp = pointer;
+ time_t = Longint;
+ png_doublep = ^png_double;
+ png_double = double;
+
+ user_error_ptr = Pointer;
+ png_error_ptrp = ^png_error_ptr;
+ png_error_ptr = procedure(png_ptr: Pointer; msg: Pointer);
+ stdcall;
+ png_rw_ptrp = ^png_rw_ptr;
+ png_rw_ptr = procedure(png_ptr: Pointer; data: Pointer;
+ length: png_size_t);
+ stdcall;
+ png_flush_ptrp = ^png_flush_ptr;
+ png_flush_ptr = procedure(png_ptr: Pointer);
+ stdcall;
+ png_progressive_info_ptrp = ^png_progressive_info_ptr;
+ png_progressive_info_ptr = procedure(png_ptr: Pointer;
+ info_ptr: Pointer);
+ stdcall;
+ png_progressive_end_ptrp = ^png_progressive_end_ptr;
+ png_progressive_end_ptr = procedure(png_ptr: Pointer;
+ info_ptr: Pointer);
+ stdcall;
+ png_progressive_row_ptrp = ^png_progressive_row_ptr;
+ png_progressive_row_ptr = procedure(png_ptr: Pointer;
+ data: Pointer; length: png_uint_32;
+ count: int);
+ stdcall;
+ png_read_status_ptr = procedure(png_ptr: Pointer;
+ row_number: png_uint_32; pass: int);
+ stdcall;
+ png_write_status_ptr = procedure(png_ptr: Pointer;
+ row_number: png_uint_32; pass: int);
+ stdcall;
+ png_user_chunk_ptr = procedure(png_ptr: Pointer;
+ data: png_unknown_chunkp);
+ stdcall;
+ png_user_transform_ptr = procedure(png_ptr: Pointer;
+ row_info: Pointer; data: png_bytep);
+ stdcall;
+
+ png_colorpp = ^png_colorp;
+ png_colorp = ^png_color;
+ png_color = packed record
+ red, green, blue: png_byte;
+ end;
+
+ png_color_16pp = ^png_color_16p;
+ png_color_16p = ^png_color_16;
+ png_color_16 = packed record
+ index: png_byte; //used for palette files
+ red, green, blue: png_uint_16; //for use in red green blue files
+ gray: png_uint_16; //for use in grayscale files
+ end;
+
+ png_color_8pp = ^png_color_8p;
+ png_color_8p = ^png_color_8;
+ png_color_8 = packed record
+ red, green, blue: png_byte; //for use in red green blue files
+ gray: png_byte; //for use in grayscale files
+ alpha: png_byte; //for alpha channel files
+ end;
+
+ png_textpp = ^png_textp;
+ png_textp = ^png_text;
+ png_text = packed record
+ compression: int; //compression value
+ key: png_charp; //keyword, 1-79 character description of "text"
+ text: png_charp; //comment, may be empty ("")
+ text_length: png_size_t; //length of text field
+ end;
+
+ png_timepp = ^png_timep;
+ png_timep = ^png_time;
+ png_time = packed record
+ year: png_uint_16; //yyyy
+ month: png_byte; //1..12
+ day: png_byte; //1..31
+ hour: png_byte; //0..23
+ minute: png_byte; //0..59
+ second: png_byte; //0..60 (leap seconds)
+ end;
+
+ png_infopp = ^png_infop;
+ png_infop = Pointer;
+
+ png_row_infopp = ^png_row_infop;
+ png_row_infop = ^png_row_info;
+ png_row_info = packed record
+ width: png_uint_32; //width of row
+ rowbytes: png_size_t; //number of bytes in row
+ color_type: png_byte; //color type of row
+ bit_depth: png_byte; //bit depth of row
+ channels: png_byte; //number of channels (1, 2, 3, or 4)
+ pixel_depth: png_byte; //bits per pixel (depth * channels)
+ end;
+
+ png_structpp = ^png_structp;
+ png_structp = Pointer;
+
+const
+
+// Supported compression types for text in PNG files (tEXt, and zTXt).
+// The values of the PNG_TEXT_COMPRESSION_ defines should NOT be changed.
+
+ PNG_TEXT_COMPRESSION_NONE_WR = -3;
+ PNG_TEXT_COMPRESSION_zTXt_WR = -2;
+ PNG_TEXT_COMPRESSION_NONE = -1;
+ PNG_TEXT_COMPRESSION_zTXt = 0;
+
+// These describe the color_type field in png_info.
+// color type masks
+
+ PNG_COLOR_MASK_PALETTE = 1;
+ PNG_COLOR_MASK_COLOR = 2;
+ PNG_COLOR_MASK_ALPHA = 4;
+
+// color types. Note that not all combinations are legal
+
+ PNG_COLOR_TYPE_GRAY = 0;
+ PNG_COLOR_TYPE_PALETTE = PNG_COLOR_MASK_COLOR or
+ PNG_COLOR_MASK_PALETTE;
+ PNG_COLOR_TYPE_RGB = PNG_COLOR_MASK_COLOR;
+ PNG_COLOR_TYPE_RGB_ALPHA = PNG_COLOR_MASK_COLOR or
+ PNG_COLOR_MASK_ALPHA;
+ PNG_COLOR_TYPE_GRAY_ALPHA = PNG_COLOR_MASK_ALPHA;
+
+// This is for compression type. PNG 1.0 only defines the single type.
+
+ PNG_COMPRESSION_TYPE_BASE = 0; // Deflate method 8, 32K window
+ PNG_COMPRESSION_TYPE_DEFAULT = PNG_COMPRESSION_TYPE_BASE;
+
+// This is for filter type. PNG 1.0 only defines the single type.
+
+ PNG_FILTER_TYPE_BASE = 0; // Single row per-byte filtering
+ PNG_FILTER_TYPE_DEFAULT = PNG_FILTER_TYPE_BASE;
+
+// These are for the interlacing type. These values should NOT be changed.
+
+ PNG_INTERLACE_NONE = 0; // Non-interlaced image
+ PNG_INTERLACE_ADAM7 = 1; // Adam7 interlacing
+
+// These are for the oFFs chunk. These values should NOT be changed.
+
+ PNG_OFFSET_PIXEL = 0; // Offset in pixels
+ PNG_OFFSET_MICROMETER = 1; // Offset in micrometers (1/10^6 meter)
+
+// These are for the pCAL chunk. These values should NOT be changed.
+
+ PNG_EQUATION_LINEAR = 0; // Linear transformation
+ PNG_EQUATION_BASE_E = 1; // Exponential base e transform
+ PNG_EQUATION_ARBITRARY = 2; // Arbitrary base exponential transform
+ PNG_EQUATION_HYPERBOLIC = 3; // Hyperbolic sine transformation
+
+// These are for the pHYs chunk. These values should NOT be changed.
+
+ PNG_RESOLUTION_UNKNOWN = 0; // pixels/unknown unit (aspect ratio)
+ PNG_RESOLUTION_METER = 1; // pixels/meter
+
+// These are for the sRGB chunk. These values should NOT be changed.
+ PNG_sRGB_INTENT_PERCEPTUAL = 0;
+ PNG_sRGB_INTENT_RELATIVE = 1;
+ PNG_sRGB_INTENT_SATURATION = 2;
+ PNG_sRGB_INTENT_ABSOLUTE = 3;
+
+// Handle alpha and tRNS by replacing with a background color.
+ PNG_BACKGROUND_GAMMA_UNKNOWN = 0;
+ PNG_BACKGROUND_GAMMA_SCREEN = 1;
+ PNG_BACKGROUND_GAMMA_FILE = 2;
+ PNG_BACKGROUND_GAMMA_UNIQUE = 3;
+
+// Values for png_set_crc_action() to say how to handle CRC errors in
+// ancillary and critical chunks, and whether to use the data contained
+// therein. Note that it is impossible to "discard" data in a critical
+// chunk. For versions prior to 0.90, the action was always error/quit,
+// whereas in version 0.90 and later, the action for CRC errors in ancillary
+// chunks is warn/discard. These values should NOT be changed.
+
+// value action:critical action:ancillary
+
+ PNG_CRC_DEFAULT = 0; // error/quit warn/discard data
+ PNG_CRC_ERROR_QUIT = 1; // error/quit error/quit
+ PNG_CRC_WARN_DISCARD = 2; // (INVALID) warn/discard data
+ PNG_CRC_WARN_USE = 3; // warn/use data warn/use data
+ PNG_CRC_QUIET_USE = 4; // quiet/use data quiet/use data
+ PNG_CRC_NO_CHANGE = 5; // use current value use current value
+
+// Flags for png_set_filter() to say which filters to use. The flags
+// are chosen so that they don't conflict with real filter types
+// below, in case they are supplied instead of the #defined constants.
+// These values should NOT be changed.
+
+ PNG_NO_FILTERS = $00;
+ PNG_FILTER_NONE = $08;
+ PNG_FILTER_SUB = $10;
+ PNG_FILTER_UP = $20;
+ PNG_FILTER_AVG = $40;
+ PNG_FILTER_PAETH = $80;
+ PNG_ALL_FILTERS = PNG_FILTER_NONE or PNG_FILTER_SUB or
+ PNG_FILTER_UP or PNG_FILTER_AVG or
+ PNG_FILTER_PAETH;
+
+// Filter values (not flags) - used in pngwrite.c, pngwutil.c for now.
+// These defines should NOT be changed.
+
+ PNG_FILTER_VALUE_NONE = 0;
+ PNG_FILTER_VALUE_SUB = 1;
+ PNG_FILTER_VALUE_UP = 2;
+ PNG_FILTER_VALUE_AVG = 3;
+ PNG_FILTER_VALUE_PAETH = 4;
+
+// Heuristic used for row filter selection. These defines should NOT be
+// changed.
+
+ PNG_FILTER_HEURISTIC_DEFAULT = 0; // Currently "UNWEIGHTED"
+ PNG_FILTER_HEURISTIC_UNWEIGHTED = 1; // Used by libpng < 0.95
+ PNG_FILTER_HEURISTIC_WEIGHTED = 2; // Experimental feature
+ PNG_FILTER_HEURISTIC_LAST = 3; // Not a valid value
+
+procedure png_build_grayscale_palette(bit_depth: int; palette: png_colorp);
+ stdcall;
+function png_check_sig(sig: png_bytep; num: int): int;
+ stdcall;
+procedure png_chunk_error(png_ptr: png_structp;
+ const mess: png_charp);
+ stdcall;
+procedure png_chunk_warning(png_ptr: png_structp;
+ const mess: png_charp);
+ stdcall;
+procedure png_convert_from_time_t(ptime: png_timep; ttime: time_t);
+ stdcall;
+function png_convert_to_rfc1123(png_ptr: png_structp; ptime: png_timep):
+ png_charp;
+ stdcall;
+function png_create_info_struct(png_ptr: png_structp): png_infop;
+ stdcall;
+function png_create_read_struct(user_png_ver: png_charp;
+ error_ptr: user_error_ptr; error_fn: png_error_ptr;
+ warn_fn: png_error_ptr): png_structp;
+ stdcall;
+function png_get_copyright(png_ptr: png_structp): png_charp;
+ stdcall;
+function png_get_header_ver(png_ptr: png_structp): png_charp;
+ stdcall;
+function png_get_header_version(png_ptr: png_structp): png_charp;
+ stdcall;
+function png_get_libpng_ver(png_ptr: png_structp): png_charp;
+ stdcall;
+function png_create_write_struct(user_png_ver: png_charp;
+ error_ptr: user_error_ptr; error_fn: png_error_ptr;
+ warn_fn: png_error_ptr): png_structp;
+ stdcall;
+procedure png_destroy_info_struct(png_ptr: png_structp;
+ info_ptr_ptr: png_infopp);
+ stdcall;
+procedure png_destroy_read_struct(png_ptr_ptr: png_structpp;
+ info_ptr_ptr, end_info_ptr_ptr: png_infopp);
+ stdcall;
+procedure png_destroy_write_struct(png_ptr_ptr: png_structpp;
+ info_ptr_ptr: png_infopp);
+ stdcall;
+function png_get_IHDR(png_ptr: png_structp; info_ptr: png_infop;
+ var width, height: png_uint_32; var bit_depth,
+ color_type, interlace_type, compression_type,
+ filter_type: int): png_uint_32;
+ stdcall;
+function png_get_PLTE(png_ptr: png_structp; info_ptr: png_infop;
+ var palette: png_colorp; var num_palette: int):
+ png_uint_32;
+ stdcall;
+function png_get_bKGD(png_ptr: png_structp; info_ptr: png_infop;
+ var background: png_color_16p): png_uint_32;
+ stdcall;
+function png_get_bit_depth(png_ptr: png_structp; info_ptr: png_infop):
+ png_byte;
+ stdcall;
+function png_get_cHRM(png_ptr: png_structp; info_ptr: png_infop;
+ var white_x, white_y, red_x, red_y, green_x, green_y,
+ blue_x, blue_y: double): png_uint_32;
+ stdcall;
+function png_get_channels(png_ptr: png_structp; info_ptr: png_infop):
+ png_byte;
+ stdcall;
+function png_get_color_type(png_ptr: png_structp; info_ptr: png_infop):
+ png_byte;
+ stdcall;
+function png_get_compression_type(png_ptr: png_structp;
+ info_ptr: png_infop): png_byte;
+ stdcall;
+function png_get_error_ptr(png_ptr: png_structp): png_voidp;
+ stdcall;
+function png_get_filter_type(png_ptr: png_structp; info_ptr: png_infop):
+ png_byte;
+ stdcall;
+function png_get_gAMA(png_ptr: png_structp; info_ptr: png_infop;
+ var file_gamma: double): png_uint_32;
+ stdcall;
+function png_get_hIST(png_ptr: png_structp; info_ptr: png_infop;
+ var hist: png_uint_16p): png_uint_32;
+ stdcall;
+function png_get_image_height(png_ptr: png_structp; info_ptr: png_infop):
+ png_uint_32;
+ stdcall;
+function png_get_image_width(png_ptr: png_structp; info_ptr: png_infop):
+ png_uint_32;
+ stdcall;
+function png_get_interlace_type(png_ptr: png_structp;
+ info_ptr: png_infop): png_byte;
+ stdcall;
+function png_get_io_ptr(png_ptr: png_structp): png_voidp;
+ stdcall;
+function png_get_oFFs(png_ptr: png_structp; info_ptr: png_infop;
+ var offset_x, offset_y: png_uint_32;
+ var unit_type: int): png_uint_32;
+ stdcall;
+function png_get_sCAL(png_ptr: png_structp; info_ptr: png_infop;
+ var unit:int; var width: png_uint_32; height: png_uint_32):
+ png_uint_32;
+ stdcall
+function png_get_pCAL(png_ptr: png_structp; info_ptr: png_infop;
+ var purpose: png_charp; var X0, X1: png_int_32;
+ var typ, nparams: int; var units: png_charp;
+ var params: png_charpp): png_uint_32;
+ stdcall;
+function png_get_pHYs(png_ptr: png_structp; info_ptr: png_infop;
+ var res_x, res_y: png_uint_32; var unit_type: int):
+ png_uint_32;
+ stdcall;
+function png_get_pixel_aspect_ratio(png_ptr: png_structp;
+ info_ptr: png_infop): float;
+ stdcall;
+function png_get_pixels_per_meter(png_ptr: png_structp;
+ info_ptr: png_infop): png_uint_32;
+ stdcall;
+function png_get_progressive_ptr(png_ptr: png_structp): png_voidp;
+ stdcall;
+function png_get_rgb_to_gray_status(png_ptr: png_structp);
+ stdcall;
+function png_get_rowbytes(png_ptr: png_structp; info_ptr: png_infop):
+ png_uint_32;
+ stdcall;
+function png_get_rows(png_ptr: png_structp; info_ptr: png_infop):
+ png_bytepp;
+ stdcall;
+function png_get_sBIT(png_ptr: png_structp; info_ptr: png_infop;
+ var sig_bits: png_color_8p): png_uint_32;
+ stdcall;
+function png_get_sRGB(png_ptr: png_structp; info_ptr: png_infop;
+ var file_srgb_intent: int): png_uint_32;
+ stdcall;
+function png_get_signature(png_ptr: png_structp; info_ptr: png_infop):
+ png_bytep;
+ stdcall;
+function png_get_tIME(png_ptr: png_structp; info_ptr: png_infop;
+ var mod_time: png_timep): png_uint_32;
+ stdcall;
+function png_get_tRNS(png_ptr: png_structp; info_ptr: png_infop;
+ var trans: png_bytep; var num_trans: int;
+ var trans_values: png_color_16p): png_uint_32;
+ stdcall;
+function png_get_text(png_ptr: png_structp; info_ptr: png_infop;
+ var text_ptr: png_textp; var num_text: int):
+ png_uint_32;
+ stdcall;
+function png_get_user_chunk_ptr(png_ptr: png_structp):
+ png_voidp;
+ stdcall;
+function png_get_valid(png_ptr: png_structp; info_ptr: png_infop;
+ flag: png_uint_32): png_uint_32;
+ stdcall;
+function png_get_x_offset_microns(png_ptr: png_structp;
+ info_ptr: png_infop): png_uint_32;
+ stdcall;
+function png_get_x_offset_pixels(png_ptr: png_structp;
+ info_ptr: png_infop): png_uint_32;
+ stdcall;
+function png_get_x_pixels_per_meter(png_ptr: png_structp;
+ info_ptr: png_infop): png_uint_32;
+ stdcall;
+function png_get_y_offset_microns(png_ptr: png_structp;
+ info_ptr: png_infop): png_uint_32;
+ stdcall;
+function png_get_y_offset_pixels(png_ptr: png_structp;
+ info_ptr: png_infop): png_uint_32;
+ stdcall;
+function png_get_y_pixels_per_meter(png_ptr: png_structp;
+ info_ptr: png_infop): png_uint_32;
+ stdcall;
+procedure png_process_data(png_ptr: png_structp; info_ptr: png_infop;
+ buffer: png_bytep; buffer_size: png_size_t);
+ stdcall;
+procedure png_progressive_combine_row(png_ptr: png_structp;
+ old_row, new_row: png_bytep);
+ stdcall;
+procedure png_read_end(png_ptr: png_structp; info_ptr: png_infop);
+ stdcall;
+procedure png_read_image(png_ptr: png_structp; image: png_bytepp);
+ stdcall;
+procedure png_read_info(png_ptr: png_structp; info_ptr: png_infop);
+ stdcall;
+procedure png_read_row(png_ptr: png_structp; row, dsp_row: png_bytep);
+ stdcall;
+procedure png_read_rows(png_ptr: png_structp; row, display_row:
+ png_bytepp; num_rows: png_uint_32);
+ stdcall;
+procedure png_read_update_info(png_ptr: png_structp; info_ptr: png_infop);
+ stdcall;
+procedure png_set_IHDR(png_ptr: png_structp; info_ptr: png_infop;
+ width, height: png_uint_32; bit_depth, color_type,
+ interlace_type, compression_type, filter_type: int);
+ stdcall;
+procedure png_set_PLTE(png_ptr: png_structp; info_ptr: png_infop;
+ palette: png_colorp; num_palette: int);
+ stdcall;
+procedure png_set_bKGD(png_ptr: png_structp; info_ptr: png_infop;
+ background: png_color_16p);
+ stdcall;
+procedure png_set_background(png_ptr: png_structp;
+ background_color: png_color_16p;
+ background_gamma_code, need_expand: int;
+ background_gamma: double);
+ stdcall;
+procedure png_set_bgr(png_ptr: png_structp);
+ stdcall;
+procedure png_set_cHRM(png_ptr: png_structp; info_ptr: png_infop;
+ white_x, white_y, red_x, red_y, green_x, green_y,
+ blue_x, blue_y: double);
+ stdcall;
+procedure png_set_cHRM_fixed(png_ptr: png_structp; info_ptr: png_infop;
+ white_x, white_y, red_x, red_y, green_x, green_y,
+ blue_x, blue_y: png_fixed_point);
+ stdcall;
+procedure png_set_compression_level(png_ptr: png_structp; level: int);
+ stdcall;
+procedure png_set_compression_mem_level(png_ptr: png_structp;
+ mem_level: int);
+ stdcall;
+procedure png_set_compression_method(png_ptr: png_structp; method: int);
+ stdcall;
+procedure png_set_compression_strategy(png_ptr: png_structp;
+ strategy: int);
+ stdcall;
+procedure png_set_compression_window_bits(png_ptr: png_structp;
+ window_bits: int);
+ stdcall;
+procedure png_set_crc_action(png_ptr: png_structp;
+ crit_action, ancil_action: int);
+ stdcall;
+procedure png_set_dither(png_ptr: png_structp; plaette: png_colorp;
+ num_palette, maximum_colors: int;
+ histogram: png_uint_16p; full_dither: int);
+ stdcall;
+procedure png_set_error_fn(png_ptr: png_structp; error_ptr: png_voidp;
+ error_fn, warning_fn: png_error_ptr);
+ stdcall;
+procedure png_set_expand(png_ptr: png_structp);
+ stdcall;
+procedure png_set_filler(png_ptr: png_structp; filler: png_uint_32;
+ filler_loc: int);
+ stdcall;
+procedure png_set_filter(png_ptr: png_structp; method, filters: int);
+ stdcall;
+procedure png_set_filter_heuristics(png_ptr: png_structp;
+ heuristic_method, num_weights: int;
+ filter_weights, filter_costs: png_doublep);
+ stdcall;
+procedure png_set_flush(png_ptr: png_structp; nrows: int);
+ stdcall;
+procedure png_set_gAMA(png_ptr: png_structp; info_ptr: png_infop;
+ file_gamma: double);
+ stdcall;
+procedure png_set_gAMA_fixed(png_ptr: png_structp; info_ptr: png_infop;
+ file_gamma: png_fixed_point);
+ stdcall;
+procedure png_set_gamma(png_ptr: png_structp; screen_gamma,
+ default_file_gamma: double);
+ stdcall;
+procedure png_set_gray_1_2_4_to_8(png_ptr: png_structp);
+ stdcall;
+procedure png_set_gray_to_rgb(png_ptr: png_structp);
+ stdcall;
+procedure png_set_hIST(png_ptr: png_structp; info_ptr: png_infop;
+ hist: png_uint_16p);
+ stdcall;
+function png_set_interlace_handling(png_ptr: png_structp): int;
+ stdcall;
+procedure png_set_invalid(png_ptr: png_structp; info_ptr:png_infop;
+ tqmask: int);
+ stdcall;
+procedure png_set_invert_alpha(png_ptr: png_structp);
+ stdcall;
+procedure png_set_invert_mono(png_ptr: png_structp);
+ stdcall;
+procedure png_set_oFFs(png_ptr: png_structp; info_ptr: png_infop;
+ offset_x, offset_y: png_uint_32; unit_type: int);
+ stdcall;
+procedure png_set_palette_to_rgb(png_ptr: png_structp);
+ stdcall;
+procedure png_set_pCAL(png_ptr: png_structp; info_ptr: png_infop;
+ purpose: png_charp; X0, X1: png_int_32;
+ typ, nparams: int; units: png_charp;
+ params: png_charpp);
+ stdcall;
+procedure png_set_pHYs(png_ptr: png_structp; info_ptr: png_infop;
+ res_x, res_y: png_uint_32; unit_type: int);
+ stdcall;
+procedure png_set_packing(png_ptr: png_structp);
+ stdcall;
+procedure png_set_packswap(png_ptr: png_structp);
+ stdcall;
+procedure png_set_progressive_read_fn(png_ptr: png_structp;
+ progressive_ptr: png_voidp;
+ info_fn: png_progressive_info_ptr;
+ row_fn: png_progressive_row_ptr;
+ end_fn: png_progressive_end_ptr);
+ stdcall;
+procedure png_set_read_fn(png_ptr: png_structp;
+ io_ptr: png_voidp; read_data_fn: png_rw_ptr);
+ stdcall;
+procedure png_set_read_status_fn(png_ptr: png_structp;
+ read_row_fn: png_read_status_ptr);
+ stdcall;
+procedure png_set_read_user_chunk_fn(png_ptr: png_structp;
+ read_user_chunk_fn: png_user_chunk_ptr);
+ stdcall;
+procedure png_set_read_user_transform_fn(png_ptr: png_structp;
+ read_user_transform_fn: png_user_transform_ptr);
+ stdcall;
+procedure png_set_rgb_to_gray(png_ptr: png_structp; int: error_action;
+ red_weight, green_weight: double);
+ stdcall;
+procedure png_set_rgb_to_gray_fixed(png_ptr: png_structp; int: error_action;
+ red_weight, green_weight: png_fixed_point);
+ stdcall;
+procedure png_set_rows(png_ptr: png_structp; info_ptr: png_infop;
+ row_pointers: png_bytepp);
+ stdcall;
+procedure png_set_sBIT(png_ptr: png_structp; info_ptr: png_infop;
+ sig_bits: png_color_8p);
+ stdcall;
+procedure png_set_sRGB(png_ptr: png_structp; info_ptr: png_infop;
+ intent: int);
+ stdcall;
+procedure png_set_sRGB_gAMA_and_cHRM(png_ptr: png_structp;
+ info_ptr: png_infop; intent: int);
+ stdcall;
+procedure png_set_shift(png_ptr: png_structp; true_bits: png_color_8p);
+ stdcall;
+procedure png_set_sig_bytes(png_ptr: png_structp; num_bytes: int);
+ stdcall;
+procedure png_set_strip_16(png_ptr: png_structp);
+ stdcall;
+procedure png_set_strip_alpha(png_ptr: png_structp);
+ stdcall;
+procedure png_set_swap(png_ptr: png_structp);
+ stdcall;
+procedure png_set_swap_alpha(png_ptr: png_structp);
+ stdcall;
+procedure png_set_tIME(png_ptr: png_structp; info_ptr: png_infop;
+ mod_time: png_timep);
+ stdcall;
+procedure png_set_tRNS(png_ptr: png_structp; info_ptr: png_infop;
+ trans: png_bytep; num_trans: int;
+ trans_values: png_color_16p);
+ stdcall;
+procedure png_set_tRNS_to_alpha(png_ptr: png_structp);
+ stdcall;
+procedure png_set_text(png_ptr: png_structp; info_ptr: png_infop;
+ text_ptr: png_textp; num_text: int);
+ stdcall;
+procedure png_set_write_fn(png_ptr: png_structp;
+ io_ptr: png_voidp; write_data_fn: png_rw_ptr;
+ output_flush_fn: png_flush_ptr);
+ stdcall;
+procedure png_set_write_status_fn(png_ptr: png_structp;
+ write_row_fn: png_write_status_ptr);
+ stdcall;
+procedure png_set_write_user_transform_fn(png_ptr: png_structp;
+ write_user_transform_fn: png_user_transform_ptr);
+ stdcall;
+function png_sig_cmp(sig: png_bytep; start, num_to_check: png_size_t):
+ int;
+ stdcall;
+procedure png_start_read_image(png_ptr: png_structp);
+ stdcall;
+procedure png_write_chunk(png_ptr: png_structp;
+ chunk_name, data: png_bytep; length: png_size_t);
+ stdcall;
+procedure png_write_chunk_data(png_ptr: png_structp;
+ data: png_bytep; length: png_size_t);
+ stdcall;
+procedure png_write_chunk_end(png_ptr: png_structp);
+ stdcall;
+procedure png_write_chunk_start(png_ptr: png_structp;
+ chunk_name: png_bytep; length: png_uint_32);
+ stdcall;
+procedure png_write_end(png_ptr: png_structp; info_ptr: png_infop);
+ stdcall;
+procedure png_write_flush(png_ptr: png_structp);
+ stdcall;
+procedure png_write_image(png_ptr: png_structp; image: png_bytepp);
+ stdcall;
+procedure png_write_info(png_ptr: png_structp; info_ptr: png_infop);
+ stdcall;
+procedure png_write_info_before_PLTE(png_ptr: png_structp; info_ptr: png_infop);
+ stdcall;
+procedure png_write_row(png_ptr: png_structp; row: png_bytep);
+ stdcall;
+procedure png_write_rows(png_ptr: png_structp; row: png_bytepp;
+ num_rows: png_uint_32);
+ stdcall;
+procedure png_get_iCCP(png_ptr: png_structp; info_ptr: png_infop;
+ name: png_charpp; compression_type: int *; profile: png_charpp;
+ proflen: png_int_32): png_bytep;
+ stdcall;
+procedure png_get_sPLT(png_ptr: png_structp;
+ info_ptr: png_infop; entries: png_spalette_pp): png_uint_32;
+ stdcall;
+procedure png_set_iCCP(png_ptr: png_structp; info_ptr: png_infop;
+ name: png_charp; compression_type: int; profile: png_charp;
+ proflen: int);
+ stdcall;
+procedure png_free_data(png_ptr: png_structp; info_ptr: png_infop; num: int);
+ stdcall;
+procedure png_set_sPLT(png_ptr: png_structp; info_ptr: png_infop;
+ entries: png_spalette_p; nentries: int);
+ stdcall;
+
+implementation
+
+const
+ pngDLL = 'png32bd.dll';
+
+procedure png_build_grayscale_palette; external pngDLL;
+function png_check_sig; external pngDLL;
+procedure png_chunk_error; external pngDLL;
+procedure png_chunk_warning; external pngDLL;
+procedure png_convert_from_time_t; external pngDLL;
+function png_convert_to_rfc1123; external pngDLL;
+function png_create_info_struct; external pngDLL;
+function png_create_read_struct; external pngDLL;
+function png_create_write_struct; external pngDLL;
+procedure png_destroy_info_struct; external pngDLL;
+procedure png_destroy_read_struct; external pngDLL;
+procedure png_destroy_write_struct; external pngDLL;
+function png_get_IHDR; external pngDLL;
+function png_get_PLTE; external pngDLL;
+function png_get_bKGD; external pngDLL;
+function png_get_bit_depth; external pngDLL;
+function png_get_cHRM; external pngDLL;
+function png_get_channels; external pngDLL;
+function png_get_color_type; external pngDLL;
+function png_get_compression_type; external pngDLL;
+function png_get_error_ptr; external pngDLL;
+function png_get_filter_type; external pngDLL;
+function png_get_gAMA; external pngDLL;
+function png_get_hIST; external pngDLL;
+function png_get_image_height; external pngDLL;
+function png_get_image_width; external pngDLL;
+function png_get_interlace_type; external pngDLL;
+function png_get_io_ptr; external pngDLL;
+function png_get_oFFs; external pngDLL;
+function png_get_pCAL; external pngDLL;
+function png_get_pHYs; external pngDLL;
+function png_get_pixel_aspect_ratio; external pngDLL;
+function png_get_pixels_per_meter; external pngDLL;
+function png_get_progressive_ptr; external pngDLL;
+function png_get_rowbytes; external pngDLL;
+function png_get_rows; external pngDLL;
+function png_get_sBIT; external pngDLL;
+function png_get_sRGB; external pngDLL;
+function png_get_signature; external pngDLL;
+function png_get_tIME; external pngDLL;
+function png_get_tRNS; external pngDLL;
+function png_get_text; external pngDLL;
+function png_get_user_chunk_ptr; external pngDLL;
+function png_get_valid; external pngDLL;
+function png_get_x_offset_microns; external pngDLL;
+function png_get_x_offset_pixels; external pngDLL;
+function png_get_x_pixels_per_meter; external pngDLL;
+function png_get_y_offset_microns; external pngDLL;
+function png_get_y_offset_pixels; external pngDLL;
+function png_get_y_pixels_per_meter; external pngDLL;
+procedure png_process_data; external pngDLL;
+procedure png_progressive_combine_row; external pngDLL;
+procedure png_read_end; external pngDLL;
+procedure png_read_image; external pngDLL;
+procedure png_read_info; external pngDLL;
+procedure png_read_row; external pngDLL;
+procedure png_read_rows; external pngDLL;
+procedure png_read_update_info; external pngDLL;
+procedure png_set_IHDR; external pngDLL;
+procedure png_set_PLTE; external pngDLL;
+procedure png_set_bKGD; external pngDLL;
+procedure png_set_background; external pngDLL;
+procedure png_set_bgr; external pngDLL;
+procedure png_set_cHRM; external pngDLL;
+procedure png_set_cHRM_fixed; external pngDLL;
+procedure png_set_compression_level; external pngDLL;
+procedure png_set_compression_mem_level; external pngDLL;
+procedure png_set_compression_method; external pngDLL;
+procedure png_set_compression_strategy; external pngDLL;
+procedure png_set_compression_window_bits; external pngDLL;
+procedure png_set_crc_action; external pngDLL;
+procedure png_set_dither; external pngDLL;
+procedure png_set_error_fn; external pngDLL;
+procedure png_set_expand; external pngDLL;
+procedure png_set_filler; external pngDLL;
+procedure png_set_filter; external pngDLL;
+procedure png_set_filter_heuristics; external pngDLL;
+procedure png_set_flush; external pngDLL;
+procedure png_set_gAMA; external pngDLL;
+procedure png_set_gAMA_fixed; external pngDLL;
+procedure png_set_gamma; external pngDLL;
+procedure png_set_gray_to_rgb; external pngDLL;
+procedure png_set_hIST; external pngDLL;
+function png_set_interlace_handling; external pngDLL;
+procedure png_set_invert_alpha; external pngDLL;
+procedure png_set_invert_mono; external pngDLL;
+procedure png_set_oFFs; external pngDLL;
+procedure png_set_pCAL; external pngDLL;
+procedure png_set_pHYs; external pngDLL;
+procedure png_set_packing; external pngDLL;
+procedure png_set_packswap; external pngDLL;
+procedure png_set_progressive_read_fn; external pngDLL;
+procedure png_set_read_fn; external pngDLL;
+procedure png_set_read_status_fn; external pngDLL;
+procedure png_set_read_user_transform_fn; external pngDLL;
+procedure png_set_rgb_to_gray; external pngDLL;
+procedure png_set_rgb_to_gray_fixed; external pngDLL;
+procedure png_set_rows; external pngDLL;
+procedure png_set_sBIT; external pngDLL;
+procedure png_set_sRGB; external pngDLL;
+procedure png_set_sRGB_gAMA_and_cHRM; external pngDLL;
+procedure png_set_shift; external pngDLL;
+procedure png_set_sig_bytes; external pngDLL;
+procedure png_set_strip_16; external pngDLL;
+procedure png_set_strip_alpha; external pngDLL;
+procedure png_set_swap; external pngDLL;
+procedure png_set_swap_alpha; external pngDLL;
+procedure png_set_tIME; external pngDLL;
+procedure png_set_tRNS; external pngDLL;
+procedure png_set_text; external pngDLL;
+procedure png_set_user_chunk_fn; external pngDLL;
+procedure png_set_write_fn; external pngDLL;
+procedure png_set_write_status_fn; external pngDLL;
+procedure png_set_write_user_transform_fn; external pngDLL;
+function png_sig_cmp; external pngDLL;
+procedure png_start_read_image; external pngDLL;
+procedure png_write_chunk; external pngDLL;
+procedure png_write_chunk_data; external pngDLL;
+procedure png_write_chunk_end; external pngDLL;
+procedure png_write_chunk_start; external pngDLL;
+procedure png_write_end; external pngDLL;
+procedure png_write_flush; external pngDLL;
+procedure png_write_image; external pngDLL;
+procedure png_write_info; external pngDLL;
+procedure png_write_info_before_PLTE; external pngDLL;
+procedure png_write_row; external pngDLL;
+procedure png_write_rows; external pngDLL;
+procedure png_get_iCCP; external pngDLL;
+procedure png_get_sPLT; external pngDLL;
+procedure png_set_iCCP; external pngDLL;
+procedure png_set_sPLT; external pngDLL;
+procedure png_free_data; external pngDLL;
+
+end.
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/pngos2.def b/tqtinterface/qt4/src/3rdparty/libpng/scripts/pngos2.def
new file mode 100644
index 0000000..8d3c68c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/pngos2.def
@@ -0,0 +1,241 @@
+;----------------------------------------
+; PNG.LIB module definition file for OS/2
+;----------------------------------------
+
+; Version 1.2.5
+
+LIBRARY PNG
+DESCRIPTION "PNG image compression library for OS/2"
+CODE PRELOAD MOVEABLE DISCARDABLE
+DATA PRELOAD MOVEABLE MULTIPLE
+
+EXPORTS
+
+
+ png_build_grayscale_palette
+ png_check_sig
+ png_chunk_error
+ png_chunk_warning
+ png_convert_from_struct_tm
+ png_convert_from_time_t
+ png_create_info_struct
+ png_create_read_struct
+ png_create_write_struct
+ png_data_freer
+ png_destroy_info_struct
+ png_destroy_read_struct
+ png_destroy_write_struct
+ png_error
+ png_free
+ png_free_data
+ png_get_IHDR
+ png_get_PLTE
+ png_get_bKGD
+ png_get_bit_depth
+ png_get_cHRM
+ png_get_cHRM_fixed
+ png_get_channels
+ png_get_color_type
+ png_get_compression_buffer_size
+ png_get_compression_type
+ png_get_copyright
+ png_get_error_ptr
+ png_get_filter_type
+ png_get_gAMA
+ png_get_gAMA_fixed
+ png_get_hIST
+ png_get_header_ver
+ png_get_header_version
+ png_get_iCCP
+ png_get_image_height
+ png_get_image_width
+ png_get_interlace_type
+ png_get_io_ptr
+ png_get_libpng_ver
+ png_get_oFFs
+ png_get_pCAL
+ png_get_pHYs
+ png_get_pixel_aspect_ratio
+ png_get_pixels_per_meter
+ png_get_progressive_ptr
+ png_get_rgb_to_gray_status
+ png_get_rowbytes
+ png_get_rows
+ png_get_sBIT
+ png_get_sCAL
+ png_get_sPLT
+ png_get_sRGB
+ png_get_signature
+ png_get_tIME
+ png_get_tRNS
+ png_get_text
+ png_get_unknown_chunks
+ png_get_user_chunk_ptr
+ png_get_user_transform_ptr
+ png_get_valid
+ png_get_x_offset_microns
+ png_get_x_offset_pixels
+ png_get_x_pixels_per_meter
+ png_get_y_offset_microns
+ png_get_y_offset_pixels
+ png_get_y_pixels_per_meter
+ png_malloc
+ png_memcpy_check
+ png_memset_check
+ png_permit_empty_plte
+ png_process_data
+ png_progressive_combine_row
+ png_read_end
+ png_read_image
+ png_read_info
+ png_read_init ; deprecated
+ png_read_png
+ png_read_row
+ png_read_rows
+ png_read_update_info
+ png_reset_zstream
+ png_set_IHDR
+ png_set_PLTE
+ png_set_bKGD
+ png_set_background
+ png_set_bgr
+ png_set_cHRM
+ png_set_cHRM_fixed
+ png_set_compression_buffer_size
+ png_set_compression_level
+ png_set_compression_mem_level
+ png_set_compression_method
+ png_set_compression_strategy
+ png_set_compression_window_bits
+ png_set_crc_action
+ png_set_dither
+ png_set_error_fn
+ png_set_expand
+ png_set_filler
+ png_set_filter
+ png_set_filter_heuristics
+ png_set_flush
+ png_set_gAMA
+ png_set_gAMA_fixed
+ png_set_gamma
+ png_set_gray_1_2_4_to_8
+ png_set_gray_to_rgb
+ png_set_hIST
+ png_set_iCCP
+ png_set_interlace_handling
+ png_set_invert_alpha
+ png_set_invert_mono
+ png_set_keep_unknown_chunks
+ png_set_oFFs
+ png_set_pCAL
+ png_set_pHYs
+ png_set_packing
+ png_set_packswap
+ png_set_palette_to_rgb
+ png_set_progressive_read_fn
+ png_set_read_fn
+ png_set_read_status_fn
+ png_set_read_user_chunk_fn
+ png_set_read_user_transform_fn
+ png_set_rgb_to_gray
+ png_set_rgb_to_gray_fixed
+ png_set_rows
+ png_set_sBIT
+ png_set_sCAL
+ png_set_sPLT
+ png_set_sRGB
+ png_set_sRGB_gAMA_and_cHRM
+ png_set_shift
+ png_set_sig_bytes
+ png_set_strip_16
+ png_set_strip_alpha
+ png_set_swap
+ png_set_swap_alpha
+ png_set_tIME
+ png_set_tRNS
+ png_set_tRNS_to_alpha
+ png_set_text
+ png_set_unknown_chunk_location
+ png_set_unknown_chunks
+ png_set_user_transform_info
+ png_set_write_fn
+ png_set_write_status_fn
+ png_set_write_user_transform_fn
+ png_sig_cmp
+ png_start_read_image
+ png_warning
+ png_write_chunk
+ png_write_chunk_data
+ png_write_chunk_end
+ png_write_chunk_start
+ png_write_end
+ png_write_flush
+ png_write_image
+ png_write_info
+ png_write_info_before_PLTE
+ png_write_init ; deprecated
+ png_write_png
+ png_write_row
+ png_write_rows
+ png_read_init_2
+ png_write_init_2
+ png_access_version_number
+ png_init_io
+ png_convert_to_rfc1123
+ png_set_invalid
+
+; Added at version 1.2.0:
+ png_mmx_support
+ png_permit_empty_plte
+ png_permit_mng_features
+ png_get_mmx_flagtqmask
+ png_get_asm_flagtqmask
+ png_get_asm_flags
+ png_get_mmx_bitdepth_threshold
+ png_get_mmx_rowbytes_threshold
+ png_set_asm_flags
+ png_init_mmx_flags
+
+; Added at version 1.2.2:
+ png_handle_as_unknown
+
+; Added at version 1.2.2 and deleted from 1.2.3:
+; png_zalloc
+; png_zfree
+
+; Added at version 1.2.4
+ png_malloc_warn
+
+; These are not present when libpng is compiled with PNG_NO_GLOBAL_ARRAYS
+ png_libpng_ver
+ png_pass_start
+ png_pass_inc
+ png_pass_ystart
+ png_pass_yinc
+ png_pass_mask
+ png_pass_dsp_mask
+; png_pass_width
+; png_pass_height
+
+; These are not present when libpng is compiled with PNG_NO_GLOBAL_ARRAYS
+ png_IHDR
+ png_IDAT
+ png_IEND
+ png_PLTE
+ png_bKGD
+ png_cHRM
+ png_gAMA
+ png_hIST
+ png_iCCP
+ png_iTXt
+ png_oFFs
+ png_pCAL
+ png_pHYs
+ png_sBIT
+ png_sCAL
+ png_sPLT
+ png_sRGB
+ png_tEXt
+ png_tIME
+ png_tRNS
+ png_zTXt
diff --git a/tqtinterface/qt4/src/3rdparty/libpng/scripts/smakefile.ppc b/tqtinterface/qt4/src/3rdparty/libpng/scripts/smakefile.ppc
new file mode 100644
index 0000000..e5c0278
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/libpng/scripts/smakefile.ppc
@@ -0,0 +1,30 @@
+# Amiga powerUP (TM) Makefile
+# makefile for libpng and SAS C V6.58/7.00 PPC compiler
+# Copyright (C) 1998 by Andreas R. Kleinert
+# For conditions of distribution and use, see copyright notice in png.h
+
+CC = scppc
+CFLAGS = NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL IDIR /zlib \
+ OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8
+LIBNAME = libpng.a
+AR = ppc-amigaos-ar
+AR_FLAGS = cr
+RANLIB = ppc-amigaos-ranlib
+LDFLAGS = -r -o
+LDLIBS = ../zlib/libzip.a LIB:scppc.a
+LN = ppc-amigaos-ld
+RM = delete quiet
+MKDIR = makedir
+
+OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o pngread.o \
+pngerror.o pngpread.o pngwrite.o pngrtran.o pngwtran.o pngrio.o pngwio.o pngmem.o
+
+all: $(LIBNAME) pngtest
+
+$(LIBNAME): $(OBJS)
+ $(AR) $(AR_FLAGS) $@ $(OBJS)
+ $(RANLIB) $@
+
+pngtest: pngtest.o $(LIBNAME)
+ $(LN) $(LDFLAGS) pngtest LIB:c_ppc.o pngtest.o $(LIBNAME) $(LDLIBS) \
+LIB:end.o
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/FT-license.txt b/tqtinterface/qt4/src/3rdparty/opentype/FT-license.txt
new file mode 100644
index 0000000..102a03d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/FT-license.txt
@@ -0,0 +1,28 @@
+
+The FreeType 2 font engine is copyrighted work and cannot be used
+legally without a software license. In order to make this project
+usable to a vast majority of developers, we distribute it under two
+mutually exclusive open-source licenses.
+
+This means that *you* must choose *one* of the two licenses described
+below, then obey all its terms and conditions when using FreeType 2 in
+any of your projects or products.
+
+ - The FreeType License, found in the file `FTL.TXT', which is similar
+ to the original BSD license *with* an advertising clause that forces
+ you to explicitly cite the FreeType project in your product's
+ documentation. All details are in the license file. This license
+ is suited to products which don't use the GNU General Public
+ License.
+
+ - The GNU General Public License version 2, found in `GPL.TXT' (any
+ later version can be used also), for programs which already use the
+ GPL. Note that the FTL is incompatible with the GPL due to its
+ advertisement clause.
+
+The contributed PCF driver comes with a license similar to that of the X
+Window System. It is compatible to the above two licenses (see file
+src/pcf/readme).
+
+
+--- end of LICENSE.TXT ---
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/FTL.TXT b/tqtinterface/qt4/src/3rdparty/opentype/FTL.TXT
new file mode 100644
index 0000000..459bda3
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/FTL.TXT
@@ -0,0 +1,174 @@
+ The FreeType Project LICENSE
+ ----------------------------
+
+ 2002-Apr-11
+
+ Copyright 1996-2002 by
+ David Turner, Robert Wilhelm, and Werner Lemberg
+
+
+
+Introduction
+============
+
+ The FreeType Project is distributed in several archive packages;
+ some of them may contain, in addition to the FreeType font engine,
+ various tools and contributions which rely on, or relate to, the
+ FreeType Project.
+
+ This license applies to all files found in such packages, and
+ which do not fall under their own explicit license. The license
+ affects thus the FreeType font engine, the test programs,
+ documentation and makefiles, at the very least.
+
+ This license was inspired by the BSD, Artistic, and IJG
+ (Independent JPEG Group) licenses, which all encourage inclusion
+ and use of free software in commercial and freeware products
+ alike. As a consequence, its main points are that:
+
+ o We don't promise that this software works. However, we will be
+ interested in any kind of bug reports. (`as is' distribution)
+
+ o You can use this software for whatever you want, in parts or
+ full form, without having to pay us. (`royalty-free' usage)
+
+ o You may not pretend that you wrote this software. If you use
+ it, or only parts of it, in a program, you must acknowledge
+ somewhere in your documentation that you have used the
+ FreeType code. (`credits')
+
+ We specifically permit and encourage the inclusion of this
+ software, with or without modifications, in commercial products.
+ We disclaim all warranties covering The FreeType Project and
+ assume no liability related to The FreeType Project.
+
+
+ Finally, many people asked us for a preferred form for a
+ credit/disclaimer to use in compliance with this license. We thus
+ encourage you to use the following text:
+
+ """
+ Portions of this software are copyright © 1996-2002 The FreeType
+ Project (www.freetype.org). All rights reserved.
+ """
+
+
+Legal Terms
+===========
+
+0. Definitions
+--------------
+
+ Throughout this license, the terms `package', `FreeType Project',
+ and `FreeType archive' refer to the set of files originally
+ distributed by the authors (David Turner, Robert Wilhelm, and
+ Werner Lemberg) as the `FreeType Project', be they named as alpha,
+ beta or final release.
+
+ `You' refers to the licensee, or person using the project, where
+ `using' is a generic term including compiling the project's source
+ code as well as linking it to form a `program' or `executable'.
+ This program is referred to as `a program using the FreeType
+ engine'.
+
+ This license applies to all files distributed in the original
+ FreeType Project, including all source code, binaries and
+ documentation, unless otherwise stated in the file in its
+ original, unmodified form as distributed in the original archive.
+ If you are unsure whether or not a particular file is covered by
+ this license, you must contact us to verify this.
+
+ The FreeType Project is copyright (C) 1996-2000 by David Turner,
+ Robert Wilhelm, and Werner Lemberg. All rights reserved except as
+ specified below.
+
+1. No Warranty
+--------------
+
+ THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
+ USE, OF THE FREETYPE PROJECT.
+
+2. Redistribution
+-----------------
+
+ This license grants a worldwide, royalty-free, perpetual and
+ irrevocable right and license to use, execute, perform, compile,
+ display, copy, create derivative works of, distribute and
+ sublicense the FreeType Project (in both source and object code
+ forms) and derivative works thereof for any purpose; and to
+ authorize others to exercise some or all of the rights granted
+ herein, subject to the following conditions:
+
+ o Redistribution of source code must retain this license file
+ (`FTL.TXT') unaltered; any additions, deletions or changes to
+ the original files must be clearly indicated in accompanying
+ documentation. The copyright notices of the unaltered,
+ original files must be preserved in all copies of source
+ files.
+
+ o Redistribution in binary form must provide a disclaimer that
+ states that the software is based in part of the work of the
+ FreeType Team, in the distribution documentation. We also
+ encourage you to put an URL to the FreeType web page in your
+ documentation, though this isn't mandatory.
+
+ These conditions apply to any software derived from or based on
+ the FreeType Project, not just the unmodified files. If you use
+ our work, you must acknowledge us. However, no fee need be paid
+ to us.
+
+3. Advertising
+--------------
+
+ Neither the FreeType authors and contributors nor you shall use
+ the name of the other for commercial, advertising, or promotional
+ purposes without specific prior written permission.
+
+ We suggest, but do not require, that you use one or more of the
+ following phrases to refer to this software in your documentation
+ or advertising materials: `FreeType Project', `FreeType Engine',
+ `FreeType library', or `FreeType Distribution'.
+
+ As you have not signed this license, you are not required to
+ accept it. However, as the FreeType Project is copyrighted
+ material, only this license, or another one contracted with the
+ authors, grants you the right to use, distribute, and modify it.
+ Therefore, by using, distributing, or modifying the FreeType
+ Project, you indicate that you understand and accept all the terms
+ of this license.
+
+4. Contacts
+-----------
+
+ There are two mailing lists related to FreeType:
+
+ o freetype@freetype.org
+
+ Discusses general use and applications of FreeType, as well as
+ future and wanted additions to the library and distribution.
+ If you are looking for support, start in this list if you
+ haven't found anything to help you in the documentation.
+
+ o devel@freetype.org
+
+ Discusses bugs, as well as engine internals, design issues,
+ specific licenses, porting, etc.
+
+ o http://www.freetype.org
+
+ Holds the current FreeType web page, which will allow you to
+ download our latest development version and read online
+ documentation.
+
+ You can also contact us individually at:
+
+ David Turner <david.turner@freetype.org>
+ Robert Wilhelm <robert.wilhelm@freetype.org>
+ Werner Lemberg <werner.lemberg@freetype.org>
+
+
+--- end of FTL.TXT ---
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/README b/tqtinterface/qt4/src/3rdparty/opentype/README
new file mode 100644
index 0000000..26752c8
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/README
@@ -0,0 +1,17 @@
+This directory includes code for using OpenType Layout tables from
+OpenType fonts with FreeType. It is taken from the Pango project who
+ported it from Freetype-1.x to Freetype-2.
+
+The table reading code in:
+
+ ftxopen.[ch]
+ ftxopenf.h
+ ftxgdef.[ch]
+ ftxgpos.[ch]
+ ftxgdef.[ch]
+
+The license for these files is in the file freetype-license.txt.
+
+disasm.[ch] is a partial dumper for OpenType tqlayout tables useful
+in figuring out what is going on.
+
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftglue.c b/tqtinterface/qt4/src/3rdparty/opentype/ftglue.c
new file mode 100644
index 0000000..c9efb62
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftglue.c
@@ -0,0 +1,349 @@
+/* ftglue.c: Glue code for compiling the OpenType code from
+ * FreeType 1 using only the public API of FreeType 2
+ *
+ * By David Turner, The FreeType Project (www.freetype.org)
+ *
+ * This code is explicitely put in the public domain
+ *
+ * See ftglue.h for more information.
+ */
+
+#include "ftglue.h"
+
+#if 0
+#include <stdio.h>
+#define LOG(x) ftglue_log x
+
+static void
+ftglue_log( const char* format, ... )
+{
+ va_list ap;
+
+ va_start( ap, format );
+ vfprintf( stderr, format, ap );
+ va_end( ap );
+}
+
+#else
+#define LOG(x) do {} while (0)
+#endif
+
+/* only used internally */
+static FT_Pointer
+ftglue_qalloc( FT_Memory memory,
+ FT_ULong size,
+ FT_Error *perror )
+{
+ FT_Error error = 0;
+ FT_Pointer block = NULL;
+
+ if ( size > 0 )
+ {
+ block = memory->alloc( memory, size );
+ if ( !block )
+ error = FT_Err_Out_Of_Memory;
+ }
+
+ *perror = error;
+ return block;
+}
+
+#undef TQALLOC /* just in case */
+#define TQALLOC(ptr,size) ( (ptr) = ftglue_qalloc( memory, (size), &error ), error != 0 )
+
+
+FTGLUE_APIDEF( FT_Pointer )
+ftglue_alloc( FT_Memory memory,
+ FT_ULong size,
+ FT_Error *perror )
+{
+ FT_Error error = 0;
+ FT_Pointer block = NULL;
+
+ if ( size > 0 )
+ {
+ block = memory->alloc( memory, size );
+ if ( !block )
+ error = FT_Err_Out_Of_Memory;
+ else
+ memset( (char*)block, 0, (size_t)size );
+ }
+
+ *perror = error;
+ return block;
+}
+
+
+FTGLUE_APIDEF( FT_Pointer )
+ftglue_realloc( FT_Memory memory,
+ FT_Pointer block,
+ FT_ULong old_size,
+ FT_ULong new_size,
+ FT_Error *perror )
+{
+ FT_Pointer block2 = NULL;
+ FT_Error error = 0;
+
+ if ( old_size == 0 || block == NULL )
+ {
+ block2 = ftglue_alloc( memory, new_size, &error );
+ }
+ else if ( new_size == 0 )
+ {
+ ftglue_free( memory, block );
+ }
+ else
+ {
+ block2 = memory->realloc( memory, old_size, new_size, block );
+ if ( block2 == NULL )
+ error = FT_Err_Out_Of_Memory;
+ else if ( new_size > old_size )
+ memset( (char*)block2 + old_size, 0, (size_t)(new_size - old_size) );
+ }
+
+ if ( !error )
+ block = block2;
+
+ *perror = error;
+ return block;
+}
+
+
+FTGLUE_APIDEF( void )
+ftglue_free( FT_Memory memory,
+ FT_Pointer block )
+{
+ if ( block )
+ memory->free( memory, block );
+}
+
+
+FTGLUE_APIDEF( FT_Long )
+ftglue_stream_pos( FT_Stream stream )
+{
+ LOG(( "ftglue:stream:pos() -> %ld\n", stream->pos ));
+ return stream->pos;
+}
+
+
+FTGLUE_APIDEF( FT_Error )
+ftglue_stream_seek( FT_Stream stream,
+ FT_Long pos )
+{
+ FT_Error error = 0;
+
+ stream->pos = pos;
+ if ( stream->read )
+ {
+ if ( stream->read( stream, pos, 0, 0 ) )
+ error = FT_Err_Invalid_Stream_Operation;
+ }
+ else if ( pos > (FT_Long)stream->size )
+ error = FT_Err_Invalid_Stream_Operation;
+
+ LOG(( "ftglue:stream:seek(%ld) -> %d\n", pos, error ));
+ return error;
+}
+
+
+FTGLUE_APIDEF( FT_Error )
+ftglue_stream_frame_enter( FT_Stream stream,
+ FT_ULong count )
+{
+ FT_Error error = FT_Err_Ok;
+ FT_ULong read_bytes;
+
+ if ( stream->read )
+ {
+ /* allocate the frame in memory */
+ FT_Memory memory = stream->memory;
+
+
+ if ( TQALLOC( stream->base, count ) )
+ goto Exit;
+
+ /* read it */
+ read_bytes = stream->read( stream, stream->pos,
+ stream->base, count );
+ if ( read_bytes < count )
+ {
+ FREE( stream->base );
+ error = FT_Err_Invalid_Stream_Operation;
+ }
+ stream->cursor = stream->base;
+ stream->limit = stream->cursor + count;
+ stream->pos += read_bytes;
+ }
+ else
+ {
+ /* check current and new position */
+ if ( stream->pos >= stream->size ||
+ stream->pos + count > stream->size )
+ {
+ error = FT_Err_Invalid_Stream_Operation;
+ goto Exit;
+ }
+
+ /* set cursor */
+ stream->cursor = stream->base + stream->pos;
+ stream->limit = stream->cursor + count;
+ stream->pos += count;
+ }
+
+Exit:
+ LOG(( "ftglue:stream:frame_enter(%ld) -> %d\n", count, error ));
+ return error;
+}
+
+
+FTGLUE_APIDEF( void )
+ftglue_stream_frame_exit( FT_Stream stream )
+{
+ if ( stream->read )
+ {
+ FT_Memory memory = stream->memory;
+
+ FREE( stream->base );
+ }
+ stream->cursor = 0;
+ stream->limit = 0;
+
+ LOG(( "ftglue:stream:frame_exit()\n" ));
+}
+
+
+FTGLUE_APIDEF( FT_Byte )
+ftglue_stream_get_byte( FT_Stream stream )
+{
+ FT_Byte result = 0;
+
+ if ( stream->cursor < stream->limit )
+ result = *stream->cursor++;
+
+ return result;
+}
+
+
+FTGLUE_APIDEF( FT_Short )
+ftglue_stream_get_short( FT_Stream stream )
+{
+ FT_Byte* p;
+ FT_Short result = 0;
+
+ p = stream->cursor;
+ if ( p + 2 <= stream->limit )
+ {
+ result = (FT_Short)((p[0] << 8) | p[1]);
+ stream->cursor = p+2;
+ }
+ return result;
+}
+
+
+FTGLUE_APIDEF( FT_Long )
+ftglue_stream_get_long( FT_Stream stream )
+{
+ FT_Byte* p;
+ FT_Long result = 0;
+
+ p = stream->cursor;
+ if ( p + 4 <= stream->limit )
+ {
+ result = (FT_Long)(((FT_Long)p[0] << 24) |
+ ((FT_Long)p[1] << 16) |
+ ((FT_Long)p[2] << 8) |
+ p[3] );
+ stream->cursor = p+4;
+ }
+ return result;
+}
+
+
+FTGLUE_APIDEF( FT_Error )
+ftglue_face_goto_table( FT_Face face,
+ FT_ULong the_tag,
+ FT_Stream stream )
+{
+ FT_Error error;
+
+ LOG(( "ftglue_face_goto_table( %p, %c%c%c%c, %p )\n",
+ face,
+ (int)((the_tag >> 24) & 0xFF),
+ (int)((the_tag >> 16) & 0xFF),
+ (int)((the_tag >> 8) & 0xFF),
+ (int)(the_tag & 0xFF),
+ stream ));
+
+ if ( !FT_IS_SFNT(face) )
+ {
+ LOG(( "not a SFNT face !!\n" ));
+ error = FT_Err_Invalid_Face_Handle;
+ }
+ else
+ {
+ /* parse the directory table directly, without using
+ * FreeType's built-in data structures
+ */
+ FT_ULong offset = 0;
+ FT_UInt count, nn;
+
+ if ( face->num_faces > 1 )
+ {
+ /* deal with TrueType collections */
+ FT_ULong offset;
+
+ LOG(( ">> This is a TrueType Collection\n" ));
+
+ if ( FILE_Seek( 12 + face->face_index*4 ) ||
+ ACCESS_Frame( 4 ) )
+ goto Exit;
+
+ offset = GET_ULong();
+
+ FORGET_Frame();
+ }
+
+ LOG(( "TrueType offset = %ld\n", offset ));
+
+ if ( FILE_Seek( offset+4 ) ||
+ ACCESS_Frame( 2 ) )
+ goto Exit;
+
+ count = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( FILE_Seek( offset+12 ) ||
+ ACCESS_Frame( count*16 ) )
+ goto Exit;
+
+ for ( nn = 0; nn < count; nn++ )
+ {
+ FT_ULong tag = GET_ULong();
+ FT_ULong checksum = GET_ULong();
+ FT_ULong start = GET_ULong();
+ FT_ULong size = GET_ULong();
+
+ FT_UNUSED(checksum);
+ FT_UNUSED(size);
+
+ if ( tag == the_tag )
+ {
+ LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size ));
+ error = ftglue_stream_seek( stream, offset+start );
+ goto FoundIt;
+ }
+ }
+ error = TT_Err_Table_Missing;
+
+ FoundIt:
+ FORGET_Frame();
+ }
+
+Exit:
+ LOG(( "TrueType error=%d\n", error ));
+
+ return error;
+}
+
+#undef TQALLOC
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftglue.h b/tqtinterface/qt4/src/3rdparty/opentype/ftglue.h
new file mode 100644
index 0000000..5c2057c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftglue.h
@@ -0,0 +1,162 @@
+/* ftglue.c: Glue code for compiling the OpenType code from
+ * FreeType 1 using only the public API of FreeType 2
+ *
+ * By David Turner, The FreeType Project (www.freetype.org)
+ *
+ * This code is explicitely put in the public domain
+ *
+ * ==========================================================================
+ *
+ * the OpenType parser codes was originally written as an extension to
+ * FreeType 1.x. As such, its source code was embedded within the library,
+ * and used many internal FreeType functions to deal with memory and
+ * stream i/o.
+ *
+ * When it was 'salvaged' for Pango and TQt, the code was "ported" to FreeType 2,
+ * which basically means that some macro tricks were performed in order to
+ * directly access FT2 _internal_ functions.
+ *
+ * these functions were never part of FT2 public API, and _did_ change between
+ * various releases. This created chaos for many users: when they upgraded the
+ * FreeType library on their system, they couldn't run Gnome anymore since
+ * Pango refused to link.
+ *
+ * Very fortunately, it's possible to completely avoid this problem because
+ * the FT_StreamRec and FT_MemoryRec structure types, which describe how
+ * memory and stream implementations interface with the rest of the font
+ * library, have always been part of the public API, and never changed.
+ *
+ * What we do thus is re-implement, within the OpenType parser, the few
+ * functions that depend on them. This only adds one or two kilobytes of
+ * code, and ensures that the parser can work with _any_ version
+ * of FreeType installed on your system. How sweet... !
+ *
+ * Note that we assume that Pango doesn't use any other internal functions
+ * from FreeType. It used to in old versions, but this should no longer
+ * be the case. (crossing my fingers).
+ *
+ * - David Turner
+ * - The FreeType Project (www.freetype.org)
+ *
+ * PS: This "glue" code is explicitely put in the public domain
+ */
+#ifndef __OPENTYPE_FTGLUE_H__
+#define __OPENTYPE_FTGLUE_H__
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+FT_BEGIN_HEADER
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+/* utility macros */
+#define TT_Err_Ok FT_Err_Ok
+#define TT_Err_Invalid_Argument FT_Err_Invalid_Argument
+#define TT_Err_Invalid_Face_Handle FT_Err_Invalid_Face_Handle
+#define TT_Err_Table_Missing FT_Err_Table_Missing
+
+#define SET_ERR(c) ( (error = (c)) != 0 )
+
+#ifndef FTGLUE_API
+#define FTGLUE_API(x) extern x
+#endif
+
+#ifndef FTGLUE_APIDEF
+#define FTGLUE_APIDEF(x) x
+#endif
+
+/* stream macros used by the OpenType parser */
+#define FILE_Pos() ftglue_stream_pos( stream )
+#define FILE_Seek(pos) SET_ERR( ftglue_stream_seek( stream, pos ) )
+#define ACCESS_Frame(size) SET_ERR( ftglue_stream_frame_enter( stream, size ) )
+#define FORGET_Frame() ftglue_stream_frame_exit( stream )
+
+#define GET_Byte() ftglue_stream_get_byte( stream )
+#define GET_Short() ftglue_stream_get_short( stream )
+#define GET_Long() ftglue_stream_get_long( stream )
+
+#define GET_Char() ((FT_Char)GET_Byte())
+#define GET_UShort() ((FT_UShort)GET_Short())
+#define GET_ULong() ((FT_ULong)GET_Long())
+#define GET_Tag4() GET_ULong()
+
+FTGLUE_API( FT_Long )
+ftglue_stream_pos( FT_Stream stream );
+
+FTGLUE_API( FT_Error )
+ftglue_stream_seek( FT_Stream stream,
+ FT_Long pos );
+
+FTGLUE_API( FT_Error )
+ftglue_stream_frame_enter( FT_Stream stream,
+ FT_ULong size );
+
+FTGLUE_API( void )
+ftglue_stream_frame_exit( FT_Stream stream );
+
+FTGLUE_API( FT_Byte )
+ftglue_stream_get_byte( FT_Stream stream );
+
+FTGLUE_API( FT_Short )
+ftglue_stream_get_short( FT_Stream stream );
+
+FTGLUE_API( FT_Long )
+ftglue_stream_get_long( FT_Stream stream );
+
+FTGLUE_API( FT_Error )
+ftglue_face_goto_table( FT_Face face,
+ FT_ULong tag,
+ FT_Stream stream );
+
+/* memory macros used by the OpenType parser */
+#define ALLOC(_ptr,_size) \
+ ( (_ptr) = ftglue_alloc( memory, _size, &error ), error != 0 )
+
+#define REALLOC(_ptr,_oldsz,_newsz) \
+ ( (_ptr) = ftglue_realloc( memory, (_ptr), (_oldsz), (_newsz), &error ), error != 0 )
+
+#define FREE(_ptr) \
+ do { \
+ if ( (_ptr) ) \
+ { \
+ ftglue_free( memory, _ptr ); \
+ _ptr = NULL; \
+ } \
+ } while (0)
+
+#define ALLOC_ARRAY(_ptr,_count,_type) \
+ ALLOC(_ptr,(_count)*sizeof(_type))
+
+#define REALLOC_ARRAY(_ptr,_oldcnt,_newcnt,_type) \
+ REALLOC(_ptr,(_oldcnt)*sizeof(_type),(_newcnt)*sizeof(_type))
+
+#define MEM_Copy(dest,source,count) memcpy( (char*)(dest), (const char*)(source), (size_t)(count) )
+
+
+FTGLUE_API( FT_Pointer )
+ftglue_alloc( FT_Memory memory,
+ FT_ULong size,
+ FT_Error *perror_ );
+
+FTGLUE_API( FT_Pointer )
+ftglue_realloc( FT_Memory memory,
+ FT_Pointer block,
+ FT_ULong old_size,
+ FT_ULong new_size,
+ FT_Error *perror_ );
+
+FTGLUE_API( void )
+ftglue_free( FT_Memory memory,
+ FT_Pointer block );
+
+/* */
+
+FT_END_HEADER
+
+#endif /* __OPENTYPE_FTGLUE_H__ */
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftxgdef.c b/tqtinterface/qt4/src/3rdparty/opentype/ftxgdef.c
new file mode 100644
index 0000000..163365a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftxgdef.c
@@ -0,0 +1,1224 @@
+/*******************************************************************
+ *
+ * ftxgdef.c
+ *
+ * TrueType Open GDEF table support.
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#include "ftxopen.h"
+#include "ftxopenf.h"
+
+#include "ftglue.h"
+
+#include FT_TRUETYPE_TAGS_H
+
+#define TTAG_GDEF FT_MAKE_TAG( 'G', 'D', 'E', 'F' )
+
+ static FT_Error Load_AttachList( TTO_AttachList* al,
+ FT_Stream stream );
+ static FT_Error Load_LigCaretList( TTO_LigCaretList* lcl,
+ FT_Stream stream );
+
+ static void Free_AttachList( TTO_AttachList* al,
+ FT_Memory memory );
+ static void Free_LigCaretList( TTO_LigCaretList* lcl,
+ FT_Memory memory );
+
+ static void Free_NewGlyphClasses( TTO_GDEFHeader* gdef,
+ FT_Memory memory );
+
+
+
+ /**********************
+ * Extension Functions
+ **********************/
+
+#if 0
+#define GDEF_ID Build_Extension_ID( 'G', 'D', 'E', 'F' )
+
+
+ static FT_Error GDEF_Create( void* ext,
+ PFace face )
+ {
+ DEFINE_LOAD_LOCALS( face->stream );
+
+ TTO_GDEFHeader* gdef = (TTO_GDEFHeader*)ext;
+ Long table;
+
+
+ /* by convention */
+
+ if ( !gdef )
+ return TT_Err_Ok;
+
+ /* a null offset indicates that there is no GDEF table */
+
+ gdef->offset = 0;
+
+ /* we store the start offset and the size of the subtable */
+
+ table = TT_LookUp_Table( face, TTAG_GDEF );
+ if ( table < 0 )
+ return TT_Err_Ok; /* The table is optional */
+
+ if ( FILE_Seek( face->dirTables[table].Offset ) ||
+ ACCESS_Frame( 4L ) )
+ return error;
+
+ gdef->offset = FILE_Pos() - 4L; /* undo ACCESS_Frame() */
+ gdef->Version = GET_ULong();
+
+ FORGET_Frame();
+
+ gdef->loaded = FALSE;
+
+ return TT_Err_Ok;
+ }
+
+
+ static FT_Error GDEF_Destroy( void* ext,
+ PFace face )
+ {
+ TTO_GDEFHeader* gdef = (TTO_GDEFHeader*)ext;
+
+
+ /* by convention */
+
+ if ( !gdef )
+ return TT_Err_Ok;
+
+ if ( gdef->loaded )
+ {
+ Free_LigCaretList( &gdef->LigCaretList, memory );
+ Free_AttachList( &gdef->AttachList, memory );
+ Free_ClassDefinition( &gdef->GlyphClassDef, memory );
+ Free_ClassDefinition( &gdef->MarkAttachClassDef, memory );
+
+ Free_NewGlyphClasses( gdef, memory );
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_Init_GDEF_Extension( TT_Engine engine )
+ {
+ PEngine_Instance _engine = HANDLE_Engine( engine );
+
+
+ if ( !_engine )
+ return TT_Err_Invalid_Engine;
+
+ return TT_Register_Extension( _engine,
+ GDEF_ID,
+ sizeof ( TTO_GDEFHeader ),
+ GDEF_Create,
+ GDEF_Destroy );
+ }
+#endif
+
+ EXPORT_FUNC
+ FT_Error TT_New_GDEF_Table( FT_Face face,
+ TTO_GDEFHeader** retptr )
+ {
+ FT_Error error;
+ FT_Memory memory = face->memory;
+
+ TTO_GDEFHeader* gdef;
+
+ if ( !retptr )
+ return TT_Err_Invalid_Argument;
+
+ if ( ALLOC( gdef, sizeof( *gdef ) ) )
+ return error;
+
+ gdef->memory = face->memory;
+
+ gdef->GlyphClassDef.loaded = FALSE;
+ gdef->AttachList.loaded = FALSE;
+ gdef->LigCaretList.loaded = FALSE;
+ gdef->MarkAttachClassDef_offset = 0;
+ gdef->MarkAttachClassDef.loaded = FALSE;
+
+ gdef->LastGlyph = 0;
+ gdef->NewGlyphClasses = NULL;
+
+ *retptr = gdef;
+
+ return TT_Err_Ok;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_Load_GDEF_Table( FT_Face face,
+ TTO_GDEFHeader** retptr )
+ {
+ FT_Error error;
+ FT_Memory memory = face->memory;
+ FT_Stream stream = face->stream;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_GDEFHeader* gdef;
+
+
+ if ( !retptr )
+ return TT_Err_Invalid_Argument;
+
+ if (( error = ftglue_face_goto_table( face, TTAG_GDEF, stream ) ))
+ return error;
+
+ if (( error = TT_New_GDEF_Table ( face, &gdef ) ))
+ return error;
+
+ base_offset = FILE_Pos();
+
+ /* skip version */
+
+ if ( FILE_Seek( base_offset + 4L ) ||
+ ACCESS_Frame( 2L ) )
+ goto Fail0;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ /* all GDEF subtables are optional */
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ /* only classes 1-4 are allowed here */
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ClassDefinition( &gdef->GlyphClassDef, 5,
+ stream ) ) != TT_Err_Ok )
+ goto Fail0;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_AttachList( &gdef->AttachList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LigCaretList( &gdef->LigCaretList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ /* OpenType 1.2 has introduced the `MarkAttachClassDef' field. We
+ first have to scan the LookupFlag values to tqfind out whether we
+ must load it or not. Here we only store the offset of the table. */
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ gdef->MarkAttachClassDef_offset = new_offset + base_offset;
+ else
+ gdef->MarkAttachClassDef_offset = 0;
+
+ *retptr = gdef;
+
+ return TT_Err_Ok;
+
+ Fail3:
+ Free_LigCaretList( &gdef->LigCaretList, memory );
+
+ Fail2:
+ Free_AttachList( &gdef->AttachList, memory );
+
+ Fail1:
+ Free_ClassDefinition( &gdef->GlyphClassDef, memory );
+
+ Fail0:
+ FREE( gdef );
+
+ return error;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_Done_GDEF_Table ( TTO_GDEFHeader* gdef )
+ {
+ FT_Memory memory = gdef->memory;
+
+ Free_LigCaretList( &gdef->LigCaretList, memory );
+ Free_AttachList( &gdef->AttachList, memory );
+ Free_ClassDefinition( &gdef->GlyphClassDef, memory );
+ Free_ClassDefinition( &gdef->MarkAttachClassDef, memory );
+
+ Free_NewGlyphClasses( gdef, memory );
+
+ FREE( gdef );
+
+ return TT_Err_Ok;
+ }
+
+
+
+
+ /*******************************
+ * AttachList related functions
+ *******************************/
+
+
+ /* AttachPoint */
+
+ static FT_Error Load_AttachPoint( TTO_AttachPoint* ap,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ FT_Error error;
+
+ FT_UShort n, count;
+ FT_UShort* pi;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ap->PointCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ap->PointIndex = NULL;
+
+ if ( count )
+ {
+ if ( ALLOC_ARRAY( ap->PointIndex, count, FT_UShort ) )
+ return error;
+
+ pi = ap->PointIndex;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( pi );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ pi[n] = GET_UShort();
+
+ FORGET_Frame();
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_AttachPoint( TTO_AttachPoint* ap,
+ FT_Memory memory )
+ {
+ FREE( ap->PointIndex );
+ }
+
+
+ /* AttachList */
+
+ static FT_Error Load_AttachList( TTO_AttachList* al,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ FT_Error error;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_AttachPoint* ap;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &al->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = al->GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ al->AttachPoint = NULL;
+
+ if ( ALLOC_ARRAY( al->AttachPoint, count, TTO_AttachPoint ) )
+ goto Fail2;
+
+ ap = al->AttachPoint;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_AttachPoint( &ap[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ al->loaded = TRUE;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_AttachPoint( &ap[m], memory );
+
+ FREE( ap );
+
+ Fail2:
+ Free_Coverage( &al->Coverage, memory );
+ return error;
+ }
+
+
+ static void Free_AttachList( TTO_AttachList* al,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_AttachPoint* ap;
+
+
+ if ( !al->loaded )
+ return;
+
+ if ( al->AttachPoint )
+ {
+ count = al->GlyphCount;
+ ap = al->AttachPoint;
+
+ for ( n = 0; n < count; n++ )
+ Free_AttachPoint( &ap[n], memory );
+
+ FREE( ap );
+ }
+
+ Free_Coverage( &al->Coverage, memory );
+ }
+
+
+
+ /*********************************
+ * LigCaretList related functions
+ *********************************/
+
+
+ /* CaretValueFormat1 */
+ /* CaretValueFormat2 */
+ /* CaretValueFormat3 */
+ /* CaretValueFormat4 */
+
+ static FT_Error Load_CaretValue( TTO_CaretValue* cv,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cv->CaretValueFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( cv->CaretValueFormat )
+ {
+ case 1:
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cv->cvf.cvf1.Coordinate = GET_Short();
+
+ FORGET_Frame();
+
+ break;
+
+ case 2:
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cv->cvf.cvf2.CaretValuePoint = GET_UShort();
+
+ FORGET_Frame();
+
+ break;
+
+ case 3:
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ cv->cvf.cvf3.Coordinate = GET_Short();
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &cv->cvf.cvf3.Device,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ break;
+
+ case 4:
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cv->cvf.cvf4.IdCaretValue = GET_UShort();
+
+ FORGET_Frame();
+ break;
+
+ default:
+ return TTO_Err_Invalid_GDEF_SubTable_Format;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_CaretValue( TTO_CaretValue* cv,
+ FT_Memory memory )
+ {
+ if ( cv->CaretValueFormat == 3 )
+ Free_Device( &cv->cvf.cvf3.Device, memory );
+ }
+
+
+ /* LigGlyph */
+
+ static FT_Error Load_LigGlyph( TTO_LigGlyph* lg,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ FT_Error error;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_CaretValue* cv;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = lg->CaretCount = GET_UShort();
+
+ FORGET_Frame();
+
+ lg->CaretValue = NULL;
+
+ if ( ALLOC_ARRAY( lg->CaretValue, count, TTO_CaretValue ) )
+ return error;
+
+ cv = lg->CaretValue;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_CaretValue( &cv[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_CaretValue( &cv[m], memory );
+
+ FREE( cv );
+ return error;
+ }
+
+
+ static void Free_LigGlyph( TTO_LigGlyph* lg,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_CaretValue* cv;
+
+
+ if ( lg->CaretValue )
+ {
+ count = lg->CaretCount;
+ cv = lg->CaretValue;
+
+ for ( n = 0; n < count; n++ )
+ Free_CaretValue( &cv[n], memory );
+
+ FREE( cv );
+ }
+ }
+
+
+ /* LigCaretList */
+
+ static FT_Error Load_LigCaretList( TTO_LigCaretList* lcl,
+ FT_Stream stream )
+ {
+ FT_Memory memory = stream->memory;
+ FT_Error error;
+
+ FT_UShort m, n, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_LigGlyph* lg;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &lcl->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = lcl->LigGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ lcl->LigGlyph = NULL;
+
+ if ( ALLOC_ARRAY( lcl->LigGlyph, count, TTO_LigGlyph ) )
+ goto Fail2;
+
+ lg = lcl->LigGlyph;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LigGlyph( &lg[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ lcl->loaded = TRUE;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_LigGlyph( &lg[m], memory );
+
+ FREE( lg );
+
+ Fail2:
+ Free_Coverage( &lcl->Coverage, memory );
+ return error;
+ }
+
+
+ static void Free_LigCaretList( TTO_LigCaretList* lcl,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_LigGlyph* lg;
+
+
+ if ( !lcl->loaded )
+ return;
+
+ if ( lcl->LigGlyph )
+ {
+ count = lcl->LigGlyphCount;
+ lg = lcl->LigGlyph;
+
+ for ( n = 0; n < count; n++ )
+ Free_LigGlyph( &lg[n], memory );
+
+ FREE( lg );
+ }
+
+ Free_Coverage( &lcl->Coverage, memory );
+ }
+
+
+
+ /***********
+ * GDEF API
+ ***********/
+
+
+ static FT_UShort Get_New_Class( TTO_GDEFHeader* gdef,
+ FT_UShort glyphID,
+ FT_UShort index )
+ {
+ FT_UShort glyph_index, array_index, count;
+ FT_UShort byte, bits;
+
+ TTO_ClassRangeRecord* gcrr;
+ FT_UShort** ngc;
+
+
+ if ( glyphID >= gdef->LastGlyph )
+ return 0;
+
+ count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
+ gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
+ ngc = gdef->NewGlyphClasses;
+
+ if ( index < count && glyphID < gcrr[index].Start )
+ {
+ array_index = index;
+ if ( index == 0 )
+ glyph_index = glyphID;
+ else
+ glyph_index = glyphID - gcrr[index - 1].End - 1;
+ }
+ else
+ {
+ array_index = index + 1;
+ glyph_index = glyphID - gcrr[index].End - 1;
+ }
+
+ byte = ngc[array_index][glyph_index / 4];
+ bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
+
+ return bits & 0x000F;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef,
+ FT_UShort glyphID,
+ FT_UShort* property )
+ {
+ FT_UShort class, index;
+
+ FT_Error error;
+
+
+ if ( !gdef || !property )
+ return TT_Err_Invalid_Argument;
+
+ /* first, we check for mark attach classes */
+
+ if ( gdef->MarkAttachClassDef.loaded )
+ {
+ error = Get_Class( &gdef->MarkAttachClassDef, glyphID, &class, &index );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ if ( !error )
+ {
+ *property = class << 8;
+ return TT_Err_Ok;
+ }
+ }
+
+ error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ /* if we have a constructed class table, check whether additional
+ values have been assigned */
+
+ if ( error == TTO_Err_Not_Covered && gdef->NewGlyphClasses )
+ class = Get_New_Class( gdef, glyphID, index );
+
+ switch ( class )
+ {
+ case UNCLASSIFIED_GLYPH:
+ *property = 0;
+ break;
+
+ case SIMPLE_GLYPH:
+ *property = TTO_BASE_GLYPH;
+ break;
+
+ case LIGATURE_GLYPH:
+ *property = TTO_LIGATURE;
+ break;
+
+ case MARK_GLYPH:
+ *property = TTO_MARK;
+ break;
+
+ case COMPONENT_GLYPH:
+ *property = TTO_COMPONENT;
+ break;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ static FT_Error Make_ClassRange( TTO_ClassDefinition* cd,
+ FT_UShort start,
+ FT_UShort end,
+ FT_UShort class,
+ FT_Memory memory )
+ {
+ FT_Error error;
+ FT_UShort index;
+
+ TTO_ClassDefFormat2* cdf2;
+ TTO_ClassRangeRecord* crr;
+
+
+ cdf2 = &cd->cd.cd2;
+
+ if ( REALLOC_ARRAY( cdf2->ClassRangeRecord,
+ cdf2->ClassRangeCount,
+ cdf2->ClassRangeCount + 1 ,
+ TTO_ClassRangeRecord ) )
+ return error;
+
+ cdf2->ClassRangeCount++;
+
+ crr = cdf2->ClassRangeRecord;
+ index = cdf2->ClassRangeCount - 1;
+
+ crr[index].Start = start;
+ crr[index].End = end;
+ crr[index].Class = class;
+
+ cd->Defined[class] = TRUE;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef,
+ FT_UShort num_glyphs,
+ FT_UShort glyph_count,
+ FT_UShort* glyph_array,
+ FT_UShort* class_array )
+ {
+ FT_UShort start, curr_glyph, curr_class;
+ FT_UShort n, m, count;
+ FT_Error error;
+ FT_Memory memory = gdef->memory;
+
+ TTO_ClassDefinition* gcd;
+ TTO_ClassRangeRecord* gcrr;
+ FT_UShort** ngc;
+
+
+ if ( !gdef || !glyph_array || !class_array )
+ return TT_Err_Invalid_Argument;
+
+ gcd = &gdef->GlyphClassDef;
+
+ /* We build a format 2 table */
+
+ gcd->ClassFormat = 2;
+
+ /* A GlyphClassDef table tqcontains at most 5 different class values */
+
+ if ( ALLOC_ARRAY( gcd->Defined, 5, FT_Bool ) )
+ return error;
+
+ gcd->cd.cd2.ClassRangeCount = 0;
+ gcd->cd.cd2.ClassRangeRecord = NULL;
+
+ start = glyph_array[0];
+ curr_class = class_array[0];
+ curr_glyph = start;
+
+ if ( curr_class >= 5 )
+ {
+ error = TT_Err_Invalid_Argument;
+ goto Fail4;
+ }
+
+ glyph_count--;
+
+ for ( n = 0; n <= glyph_count; n++ )
+ {
+ if ( curr_glyph == glyph_array[n] && curr_class == class_array[n] )
+ {
+ if ( n == glyph_count )
+ {
+ if ( ( error = Make_ClassRange( gcd, start,
+ curr_glyph,
+ curr_class,
+ memory ) ) != TT_Err_Ok )
+ goto Fail3;
+ }
+ else
+ {
+ if ( curr_glyph == 0xFFFF )
+ {
+ error = TT_Err_Invalid_Argument;
+ goto Fail3;
+ }
+ else
+ curr_glyph++;
+ }
+ }
+ else
+ {
+ if ( ( error = Make_ClassRange( gcd, start,
+ curr_glyph - 1,
+ curr_class,
+ memory ) ) != TT_Err_Ok )
+ goto Fail3;
+
+ if ( curr_glyph > glyph_array[n] )
+ {
+ error = TT_Err_Invalid_Argument;
+ goto Fail3;
+ }
+
+ start = glyph_array[n];
+ curr_class = class_array[n];
+ curr_glyph = start;
+
+ if ( curr_class >= 5 )
+ {
+ error = TT_Err_Invalid_Argument;
+ goto Fail3;
+ }
+
+ if ( n == glyph_count )
+ {
+ if ( ( error = Make_ClassRange( gcd, start,
+ curr_glyph,
+ curr_class,
+ memory ) ) != TT_Err_Ok )
+ goto Fail3;
+ }
+ else
+ {
+ if ( curr_glyph == 0xFFFF )
+ {
+ error = TT_Err_Invalid_Argument;
+ goto Fail3;
+ }
+ else
+ curr_glyph++;
+ }
+ }
+ }
+
+ /* now prepare the arrays for class values assigned during the lookup
+ process */
+
+ if ( ALLOC_ARRAY( gdef->NewGlyphClasses,
+ gcd->cd.cd2.ClassRangeCount + 1, FT_UShort* ) )
+ goto Fail3;
+
+ count = gcd->cd.cd2.ClassRangeCount;
+ gcrr = gcd->cd.cd2.ClassRangeRecord;
+ ngc = gdef->NewGlyphClasses;
+
+ /* We allocate arrays for all glyphs not covered by the class range
+ records. Each element holds four class values. */
+
+ if ( count > 0 )
+ {
+ if ( gcrr[0].Start )
+ {
+ if ( ALLOC_ARRAY( ngc[0], ( gcrr[0].Start + 3 ) / 4, FT_UShort ) )
+ goto Fail2;
+ }
+
+ for ( n = 1; n < count; n++ )
+ {
+ if ( gcrr[n].Start - gcrr[n - 1].End > 1 )
+ if ( ALLOC_ARRAY( ngc[n],
+ ( gcrr[n].Start - gcrr[n - 1].End + 2 ) / 4,
+ FT_UShort ) )
+ goto Fail1;
+ }
+
+ if ( gcrr[count - 1].End != num_glyphs - 1 )
+ {
+ if ( ALLOC_ARRAY( ngc[count],
+ ( num_glyphs - gcrr[count - 1].End + 2 ) / 4,
+ FT_UShort ) )
+ goto Fail1;
+ }
+ }
+ else if ( num_glyphs > 0 )
+ {
+ if ( ALLOC_ARRAY( ngc[count],
+ ( num_glyphs + 3 ) / 4,
+ FT_UShort ) )
+ goto Fail2;
+ }
+
+ gdef->LastGlyph = num_glyphs - 1;
+
+ gdef->MarkAttachClassDef_offset = 0L;
+ gdef->MarkAttachClassDef.loaded = FALSE;
+
+ gcd->loaded = TRUE;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ FREE( ngc[m] );
+
+ Fail2:
+ FREE( gdef->NewGlyphClasses );
+
+ Fail3:
+ FREE( gcd->cd.cd2.ClassRangeRecord );
+
+ Fail4:
+ FREE( gcd->Defined );
+ return error;
+ }
+
+
+ static void Free_NewGlyphClasses( TTO_GDEFHeader* gdef,
+ FT_Memory memory )
+ {
+ FT_UShort** ngc;
+ FT_UShort n, count;
+
+
+ if ( gdef->NewGlyphClasses )
+ {
+ count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount + 1;
+ ngc = gdef->NewGlyphClasses;
+
+ for ( n = 0; n < count; n++ )
+ FREE( ngc[n] );
+
+ FREE( ngc );
+ }
+ }
+
+
+ FT_Error Add_Glyph_Property( TTO_GDEFHeader* gdef,
+ FT_UShort glyphID,
+ FT_UShort property )
+ {
+ FT_Error error;
+ FT_UShort class, new_class, index;
+ FT_UShort byte, bits, tqmask;
+ FT_UShort array_index, glyph_index, count;
+
+ TTO_ClassRangeRecord* gcrr;
+ FT_UShort** ngc;
+
+
+ error = Get_Class( &gdef->GlyphClassDef, glyphID, &class, &index );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ /* we don't accept glyphs covered in `GlyphClassDef' */
+
+ if ( !error )
+ return TTO_Err_Not_Covered;
+
+ switch ( property )
+ {
+ case 0:
+ new_class = UNCLASSIFIED_GLYPH;
+ break;
+
+ case TTO_BASE_GLYPH:
+ new_class = SIMPLE_GLYPH;
+ break;
+
+ case TTO_LIGATURE:
+ new_class = LIGATURE_GLYPH;
+ break;
+
+ case TTO_MARK:
+ new_class = MARK_GLYPH;
+ break;
+
+ case TTO_COMPONENT:
+ new_class = COMPONENT_GLYPH;
+ break;
+
+ default:
+ return TT_Err_Invalid_Argument;
+ }
+
+ count = gdef->GlyphClassDef.cd.cd2.ClassRangeCount;
+ gcrr = gdef->GlyphClassDef.cd.cd2.ClassRangeRecord;
+ ngc = gdef->NewGlyphClasses;
+
+ if ( index < count && glyphID < gcrr[index].Start )
+ {
+ array_index = index;
+ if ( index == 0 )
+ glyph_index = glyphID;
+ else
+ glyph_index = glyphID - gcrr[index - 1].End - 1;
+ }
+ else
+ {
+ array_index = index + 1;
+ glyph_index = glyphID - gcrr[index].End - 1;
+ }
+
+ byte = ngc[array_index][glyph_index / 4];
+ bits = byte >> ( 16 - ( glyph_index % 4 + 1 ) * 4 );
+ class = bits & 0x000F;
+
+ /* we don't overwrite existing entries */
+
+ if ( !class )
+ {
+ bits = new_class << ( 16 - ( glyph_index % 4 + 1 ) * 4 );
+ tqmask = ~( 0x000F << ( 16 - ( glyph_index % 4 + 1 ) * 4 ) );
+
+ ngc[array_index][glyph_index / 4] &= tqmask;
+ ngc[array_index][glyph_index / 4] |= bits;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ FT_Error Check_Property( TTO_GDEFHeader* gdef,
+ OTL_GlyphItem gitem,
+ FT_UShort flags,
+ FT_UShort* property )
+ {
+ FT_Error error;
+
+ if ( gdef )
+ {
+ FT_UShort basic_glyph_class;
+ FT_UShort desired_attachment_class;
+
+ if ( gitem->gproperties == OTL_GLYPH_PROPERTIES_UNKNOWN )
+ {
+ error = TT_GDEF_Get_Glyph_Property( gdef, gitem->gindex, &gitem->gproperties );
+ if ( error )
+ return error;
+ }
+
+ *property = gitem->gproperties;
+
+ /* If the glyph was found in the MarkAttachmentClass table,
+ * then that class value is the high byte of the result,
+ * otherwise the low byte tqcontains the basic type of the glyph
+ * as defined by the GlyphClassDef table.
+ */
+ if ( *property & IGNORE_SPECIAL_MARKS )
+ basic_glyph_class = TTO_MARK;
+ else
+ basic_glyph_class = *property;
+
+ /* Return Not_Covered, if, for example, basic_glyph_class
+ * is TTO_LIGATURE and LookFlags includes IGNORE_LIGATURES
+ */
+ if ( flags & basic_glyph_class )
+ return TTO_Err_Not_Covered;
+
+ /* The high byte of LookupFlags has the meaning
+ * "ignore marks of attachment type different than
+ * the attachment type specified."
+ */
+ desired_attachment_class = flags & IGNORE_SPECIAL_MARKS;
+ if ( desired_attachment_class )
+ {
+ if ( basic_glyph_class == TTO_MARK &&
+ *property != desired_attachment_class )
+ return TTO_Err_Not_Covered;
+ }
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+/* END */
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftxgdef.h b/tqtinterface/qt4/src/3rdparty/opentype/ftxgdef.h
new file mode 100644
index 0000000..28f55c1
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftxgdef.h
@@ -0,0 +1,224 @@
+/*******************************************************************
+ *
+ * ftxgdef.h
+ *
+ * TrueType Open GDEF table support
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef FTXOPEN_H
+#error "Don't include this file! Use ftxopen.h instead."
+#endif
+
+#ifndef FTXGDEF_H
+#define FTXGDEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TTO_Err_Invalid_GDEF_SubTable_Format 0x1030
+#define TTO_Err_Invalid_GDEF_SubTable 0x1031
+
+
+/* GDEF glyph classes */
+
+#define UNCLASSIFIED_GLYPH 0
+#define SIMPLE_GLYPH 1
+#define LIGATURE_GLYPH 2
+#define MARK_GLYPH 3
+#define COMPONENT_GLYPH 4
+
+/* GDEF glyph properties, corresponding to class values 1-4. Note that
+ TTO_COMPONENT has no corresponding flag in the LookupFlag field. */
+
+#define TTO_BASE_GLYPH 0x0002
+#define TTO_LIGATURE 0x0004
+#define TTO_MARK 0x0008
+#define TTO_COMPONENT 0x0010
+
+
+ /* Attachment related structures */
+
+ struct TTO_AttachPoint_
+ {
+ FT_UShort PointCount; /* size of the PointIndex array */
+ FT_UShort* PointIndex; /* array of contour points */
+ };
+
+ typedef struct TTO_AttachPoint_ TTO_AttachPoint;
+
+
+ struct TTO_AttachList_
+ {
+ FT_Bool loaded;
+
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort GlyphCount; /* number of glyphs with
+ attachments */
+ TTO_AttachPoint* AttachPoint; /* array of AttachPoint tables */
+ };
+
+ typedef struct TTO_AttachList_ TTO_AttachList;
+
+
+ /* Ligature Caret related structures */
+
+ struct TTO_CaretValueFormat1_
+ {
+ FT_Short Coordinate; /* x or y value (in design units) */
+ };
+
+ typedef struct TTO_CaretValueFormat1_ TTO_CaretValueFormat1;
+
+
+ struct TTO_CaretValueFormat2_
+ {
+ FT_UShort CaretValuePoint; /* contour point index on glyph */
+ };
+
+ typedef struct TTO_CaretValueFormat2_ TTO_CaretValueFormat2;
+
+
+ struct TTO_CaretValueFormat3_
+ {
+ FT_Short Coordinate; /* x or y value (in design units) */
+ TTO_Device Device; /* Device table for x or y value */
+ };
+
+ typedef struct TTO_CaretValueFormat3_ TTO_CaretValueFormat3;
+
+
+ struct TTO_CaretValueFormat4_
+ {
+ FT_UShort IdCaretValue; /* metric ID */
+ };
+
+ typedef struct TTO_CaretValueFormat4_ TTO_CaretValueFormat4;
+
+
+ struct TTO_CaretValue_
+ {
+ FT_UShort CaretValueFormat; /* 1, 2, 3, or 4 */
+
+ union
+ {
+ TTO_CaretValueFormat1 cvf1;
+ TTO_CaretValueFormat2 cvf2;
+ TTO_CaretValueFormat3 cvf3;
+ TTO_CaretValueFormat4 cvf4;
+ } cvf;
+ };
+
+ typedef struct TTO_CaretValue_ TTO_CaretValue;
+
+
+ struct TTO_LigGlyph_
+ {
+ FT_Bool loaded;
+
+ FT_UShort CaretCount; /* number of caret values */
+ TTO_CaretValue* CaretValue; /* array of caret values */
+ };
+
+ typedef struct TTO_LigGlyph_ TTO_LigGlyph;
+
+
+ struct TTO_LigCaretList_
+ {
+ FT_Bool loaded;
+
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort LigGlyphCount; /* number of ligature glyphs */
+ TTO_LigGlyph* LigGlyph; /* array of LigGlyph tables */
+ };
+
+ typedef struct TTO_LigCaretList_ TTO_LigCaretList;
+
+
+ /* The `NewGlyphClasses' field is not defined in the TTO specification.
+ We use it for fonts with a constructed `GlyphClassDef' structure
+ (i.e., which don't have a GDEF table) to collect glyph classes
+ assigned during the lookup process. The number of arrays in this
+ pointer array is GlyphClassDef->cd.cd2.ClassRangeCount+1; the nth
+ array then tqcontains the glyph class values of the glyphs not covered
+ by the ClassRangeRecords structures with index n-1 and n. We store
+ glyph class values for four glyphs in a single array element.
+
+ `LastGlyph' is identical to the number of glyphs minus one in the
+ font; we need it only if `NewGlyphClasses' is not NULL (to have an
+ upper bound for the last array).
+
+ Note that we first store the file offset to the `MarkAttachClassDef'
+ field (which has been introduced in OpenType 1.2) -- since the
+ `Version' field value hasn't been increased to indicate that we have
+ one more field for some obscure reason, we must parse the GSUB table
+ to tqfind out whether class values refer to this table. Only then we
+ can finally load the MarkAttachClassDef structure if necessary. */
+
+ struct TTO_GDEFHeader_
+ {
+ FT_Memory memory;
+ FT_ULong offset;
+
+ FT_Fixed Version;
+
+ TTO_ClassDefinition GlyphClassDef;
+ TTO_AttachList AttachList;
+ TTO_LigCaretList LigCaretList;
+ FT_ULong MarkAttachClassDef_offset;
+ TTO_ClassDefinition MarkAttachClassDef; /* new in OT 1.2 */
+
+ FT_UShort LastGlyph;
+ FT_UShort** NewGlyphClasses;
+ };
+
+ typedef struct TTO_GDEFHeader_ TTO_GDEFHeader;
+ typedef struct TTO_GDEFHeader_* TTO_GDEF;
+
+
+ /* finally, the GDEF API */
+
+ /* EXPORT_DEF
+ FT_Error TT_Init_GDEF_Extension( TT_Engine engine ); */
+
+ EXPORT_FUNC
+ FT_Error TT_New_GDEF_Table( FT_Face face,
+ TTO_GDEFHeader** retptr );
+
+ EXPORT_DEF
+ FT_Error TT_Load_GDEF_Table( FT_Face face,
+ TTO_GDEFHeader** gdef );
+
+ EXPORT_DEF
+ FT_Error TT_Done_GDEF_Table ( TTO_GDEFHeader* gdef );
+
+ EXPORT_DEF
+ FT_Error TT_GDEF_Get_Glyph_Property( TTO_GDEFHeader* gdef,
+ FT_UShort glyphID,
+ FT_UShort* property );
+ EXPORT_DEF
+ FT_Error TT_GDEF_Build_ClassDefinition( TTO_GDEFHeader* gdef,
+ FT_UShort num_glyphs,
+ FT_UShort glyph_count,
+ FT_UShort* glyph_array,
+ FT_UShort* class_array );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FTXGDEF_H */
+
+
+/* END */
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftxgpos.c b/tqtinterface/qt4/src/3rdparty/opentype/ftxgpos.c
new file mode 100644
index 0000000..8fa5e11
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftxgpos.c
@@ -0,0 +1,6196 @@
+/*******************************************************************
+ *
+ * ftxgpos.c
+ *
+ * TrueType Open GPOS table support.
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+/* XXX There is *a lot* of duplicated code (cf. formats 7 and 8), but
+ I don't care currently. I believe that it would be possible to
+ save about 50% of TTO code by carefully designing the structures,
+ sharing as much as possible with extensive use of macros. This
+ is something for a volunteer :-) */
+
+#include "ftxopen.h"
+#include "ftxopenf.h"
+
+#include "ftglue.h"
+
+#include FT_TRUETYPE_TAGS_H
+
+#define TTAG_GPOS FT_MAKE_TAG( 'G', 'P', 'O', 'S' )
+
+ struct GPOS_Instance_
+ {
+ TTO_GPOSHeader* gpos;
+ FT_Face face;
+ FT_Bool dvi;
+ FT_UShort load_flags; /* how the glyph should be loaded */
+ FT_Bool r2l;
+
+ FT_UShort last; /* the last valid glyph -- used
+ with cursive positioning */
+ FT_Pos anchor_x; /* the coordinates of the anchor point */
+ FT_Pos anchor_y; /* of the last valid glyph */
+ };
+
+ typedef struct GPOS_Instance_ GPOS_Instance;
+
+
+ static FT_Error GPos_Do_Glyph_Lookup( GPOS_Instance* gpi,
+ FT_UShort lookup_index,
+ OTL_Buffer buffer,
+ FT_UShort context_length,
+ int nesting_level );
+
+
+// #define IN_GLYPH( pos ) (buffer->in_string[(pos)].gindex)
+// #define IN_ITEM( pos ) (&buffer->in_string[(pos)])
+// #define IN_CURGLYPH() (buffer->in_string[buffer->in_pos].gindex)
+// #define IN_CURITEM() (&buffer->in_string[buffer->in_pos])
+// #define IN_PROPERTIES( pos ) (buffer->in_string[(pos)].properties)
+// #define IN_LIGID( pos ) (buffer->in_string[(pos)].ligID)
+// #define IN_COMPONENT( pos ) (buffer->in_string[(pos)].component)
+
+/* the client application must tqreplace this with something more
+ meaningful if multiple master fonts are to be supported. */
+
+ static FT_Error default_mmfunc( FT_Face face,
+ FT_UShort metric_id,
+ FT_Pos* metric_value,
+ void* data )
+ {
+ FT_UNUSED(face);
+ FT_UNUSED(metric_id);
+ FT_UNUSED(metric_value);
+ FT_UNUSED(data);
+ return TTO_Err_No_MM_Interpreter;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_Load_GPOS_Table( FT_Face face,
+ TTO_GPOSHeader** retptr,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ FT_UShort i, num_lookups;
+ TTO_GPOSHeader* gpos;
+ TTO_Lookup* lo;
+
+ FT_Stream stream = face->stream;
+ FT_Error error;
+ FT_Memory memory = face->memory;
+
+
+ if ( !retptr )
+ return TT_Err_Invalid_Argument;
+
+ if ( !stream )
+ return TT_Err_Invalid_Face_Handle;
+
+ if (( error = ftglue_face_goto_table( face, TTAG_GPOS, stream ) ))
+ return error;
+
+ base_offset = FILE_Pos();
+
+ if ( ALLOC ( gpos, sizeof( *gpos ) ) )
+ return error;
+
+ gpos->memory = memory;
+ gpos->gfunc = FT_Load_Glyph;
+ gpos->mmfunc = default_mmfunc;
+
+ /* skip version */
+
+ if ( FILE_Seek( base_offset + 4L ) ||
+ ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ScriptList( &gpos->ScriptList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_FeatureList( &gpos->FeatureList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LookupList( &gpos->LookupList,
+ stream, GPOS ) ) != TT_Err_Ok )
+ goto Fail2;
+
+ gpos->gdef = gdef; /* can be NULL */
+
+ /* We now check the LookupFlags for values larger than 0xFF to tqfind
+ out whether we need to load the `MarkAttachClassDef' field of the
+ GDEF table -- this hack is necessary for OpenType 1.2 tables since
+ the version field of the GDEF table hasn't been incremented.
+
+ For constructed GDEF tables, we only load it if
+ `MarkAttachClassDef_offset' is not zero (nevertheless, a build of
+ a constructed mark attach table is not supported currently). */
+
+ if ( gdef &&
+ gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded )
+ {
+ lo = gpos->LookupList.Lookup;
+ num_lookups = gpos->LookupList.LookupCount;
+
+ for ( i = 0; i < num_lookups; i++ )
+ {
+ if ( lo[i].LookupFlag & IGNORE_SPECIAL_MARKS )
+ {
+ if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) ||
+ ( error = Load_ClassDefinition( &gdef->MarkAttachClassDef,
+ 256, stream ) ) != TT_Err_Ok )
+ goto Fail1;
+
+ break;
+ }
+ }
+ }
+
+ *retptr = gpos;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_LookupList( &gpos->LookupList, GPOS, memory );
+
+ Fail2:
+ Free_FeatureList( &gpos->FeatureList, memory );
+
+ Fail3:
+ Free_ScriptList( &gpos->ScriptList, memory );
+
+ Fail4:
+ FREE( gpos );
+
+ return error;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_Done_GPOS_Table( TTO_GPOSHeader* gpos )
+ {
+ FT_Memory memory = gpos->memory;
+
+ Free_LookupList( &gpos->LookupList, GPOS, memory );
+ Free_FeatureList( &gpos->FeatureList, memory );
+ Free_ScriptList( &gpos->ScriptList, memory );
+
+ return FT_Err_Ok;
+ }
+
+
+ /*****************************
+ * SubTable related functions
+ *****************************/
+
+ /* shared tables */
+
+ /* ValueRecord */
+
+ /* There is a subtle difference in the specs between a `table' and a
+ `record' -- offsets for tqdevice tables in ValueRecords are taken from
+ the tqparent table and not the tqparent record. */
+
+ static FT_Error Load_ValueRecord( TTO_ValueRecord* vr,
+ FT_UShort format,
+ FT_ULong base_offset,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_ULong cur_offset, new_offset;
+
+
+ if ( format & HAVE_X_PLACEMENT )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ vr->XPlacement = GET_Short();
+
+ FORGET_Frame();
+ }
+ else
+ vr->XPlacement = 0;
+
+ if ( format & HAVE_Y_PLACEMENT )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ vr->YPlacement = GET_Short();
+
+ FORGET_Frame();
+ }
+ else
+ vr->YPlacement = 0;
+
+ if ( format & HAVE_X_ADVANCE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ vr->XAdvance = GET_Short();
+
+ FORGET_Frame();
+ }
+ else
+ vr->XAdvance = 0;
+
+ if ( format & HAVE_Y_ADVANCE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ vr->YAdvance = GET_Short();
+
+ FORGET_Frame();
+ }
+ else
+ vr->YAdvance = 0;
+
+ if ( format & HAVE_X_PLACEMENT_DEVICE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &vr->XPlacementDevice,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ goto empty1;
+ }
+ else
+ {
+ empty1:
+ vr->XPlacementDevice.StartSize = 0;
+ vr->XPlacementDevice.EndSize = 0;
+ vr->XPlacementDevice.DeltaValue = NULL;
+ }
+
+ if ( format & HAVE_Y_PLACEMENT_DEVICE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &vr->YPlacementDevice,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ goto empty2;
+ }
+ else
+ {
+ empty2:
+ vr->YPlacementDevice.StartSize = 0;
+ vr->YPlacementDevice.EndSize = 0;
+ vr->YPlacementDevice.DeltaValue = NULL;
+ }
+
+ if ( format & HAVE_X_ADVANCE_DEVICE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &vr->XAdvanceDevice,
+ stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ goto empty3;
+ }
+ else
+ {
+ empty3:
+ vr->XAdvanceDevice.StartSize = 0;
+ vr->XAdvanceDevice.EndSize = 0;
+ vr->XAdvanceDevice.DeltaValue = NULL;
+ }
+
+ if ( format & HAVE_Y_ADVANCE_DEVICE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &vr->YAdvanceDevice,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ goto empty4;
+ }
+ else
+ {
+ empty4:
+ vr->YAdvanceDevice.StartSize = 0;
+ vr->YAdvanceDevice.EndSize = 0;
+ vr->YAdvanceDevice.DeltaValue = NULL;
+ }
+
+ if ( format & HAVE_X_ID_PLACEMENT )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ vr->XIdPlacement = GET_UShort();
+
+ FORGET_Frame();
+ }
+ else
+ vr->XIdPlacement = 0;
+
+ if ( format & HAVE_Y_ID_PLACEMENT )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ vr->YIdPlacement = GET_UShort();
+
+ FORGET_Frame();
+ }
+ else
+ vr->YIdPlacement = 0;
+
+ if ( format & HAVE_X_ID_ADVANCE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ vr->XIdAdvance = GET_UShort();
+
+ FORGET_Frame();
+ }
+ else
+ vr->XIdAdvance = 0;
+
+ if ( format & HAVE_Y_ID_ADVANCE )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ vr->YIdAdvance = GET_UShort();
+
+ FORGET_Frame();
+ }
+ else
+ vr->YIdAdvance = 0;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_Device( &vr->YAdvanceDevice, memory );
+
+ Fail2:
+ Free_Device( &vr->XAdvanceDevice, memory );
+
+ Fail3:
+ Free_Device( &vr->YPlacementDevice, memory );
+ return error;
+ }
+
+
+ static void Free_ValueRecord( TTO_ValueRecord* vr,
+ FT_UShort format,
+ FT_Memory memory )
+ {
+ if ( format & HAVE_Y_ADVANCE_DEVICE )
+ Free_Device( &vr->YAdvanceDevice, memory );
+ if ( format & HAVE_X_ADVANCE_DEVICE )
+ Free_Device( &vr->XAdvanceDevice, memory );
+ if ( format & HAVE_Y_PLACEMENT_DEVICE )
+ Free_Device( &vr->YPlacementDevice, memory );
+ if ( format & HAVE_X_PLACEMENT_DEVICE )
+ Free_Device( &vr->XPlacementDevice, memory );
+ }
+
+
+ static FT_Error Get_ValueRecord( GPOS_Instance* gpi,
+ TTO_ValueRecord* vr,
+ FT_UShort format,
+ OTL_Position gd )
+ {
+ FT_Pos value;
+ FT_Short pixel_value;
+ FT_Error error = TT_Err_Ok;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ FT_UShort x_ppem, y_ppem;
+ FT_Fixed x_scale, y_scale;
+
+
+ if ( !format )
+ return TT_Err_Ok;
+
+ x_ppem = gpi->face->size->metrics.x_ppem;
+ y_ppem = gpi->face->size->metrics.y_ppem;
+ x_scale = gpi->face->size->metrics.x_scale;
+ y_scale = gpi->face->size->metrics.y_scale;
+
+ /* design units -> fractional pixel */
+
+ if ( format & HAVE_X_PLACEMENT )
+ gd->x_pos += x_scale * vr->XPlacement / 0x10000;
+ if ( format & HAVE_Y_PLACEMENT )
+ gd->y_pos += y_scale * vr->YPlacement / 0x10000;
+ if ( format & HAVE_X_ADVANCE )
+ gd->x_advance += x_scale * vr->XAdvance / 0x10000;
+ if ( format & HAVE_Y_ADVANCE )
+ gd->y_advance += y_scale * vr->YAdvance / 0x10000;
+
+ if ( !gpi->dvi )
+ {
+ /* pixel -> fractional pixel */
+
+ if ( format & HAVE_X_PLACEMENT_DEVICE )
+ {
+ Get_Device( &vr->XPlacementDevice, x_ppem, &pixel_value );
+ gd->x_pos += pixel_value << 6;
+ }
+ if ( format & HAVE_Y_PLACEMENT_DEVICE )
+ {
+ Get_Device( &vr->YPlacementDevice, y_ppem, &pixel_value );
+ gd->y_pos += pixel_value << 6;
+ }
+ if ( format & HAVE_X_ADVANCE_DEVICE )
+ {
+ Get_Device( &vr->XAdvanceDevice, x_ppem, &pixel_value );
+ gd->x_advance += pixel_value << 6;
+ }
+ if ( format & HAVE_Y_ADVANCE_DEVICE )
+ {
+ Get_Device( &vr->YAdvanceDevice, y_ppem, &pixel_value );
+ gd->y_advance += pixel_value << 6;
+ }
+ }
+
+ /* values returned from mmfunc() are already in fractional pixels */
+
+ if ( format & HAVE_X_ID_PLACEMENT )
+ {
+ error = (gpos->mmfunc)( gpi->face, vr->XIdPlacement,
+ &value, gpos->data );
+ if ( error )
+ return error;
+ gd->x_pos += value;
+ }
+ if ( format & HAVE_Y_ID_PLACEMENT )
+ {
+ error = (gpos->mmfunc)( gpi->face, vr->YIdPlacement,
+ &value, gpos->data );
+ if ( error )
+ return error;
+ gd->y_pos += value;
+ }
+ if ( format & HAVE_X_ID_ADVANCE )
+ {
+ error = (gpos->mmfunc)( gpi->face, vr->XIdAdvance,
+ &value, gpos->data );
+ if ( error )
+ return error;
+ gd->x_advance += value;
+ }
+ if ( format & HAVE_Y_ID_ADVANCE )
+ {
+ error = (gpos->mmfunc)( gpi->face, vr->YIdAdvance,
+ &value, gpos->data );
+ if ( error )
+ return error;
+ gd->y_advance += value;
+ }
+
+ return error;
+ }
+
+
+ /* AnchorFormat1 */
+ /* AnchorFormat2 */
+ /* AnchorFormat3 */
+ /* AnchorFormat4 */
+
+ static FT_Error Load_Anchor( TTO_Anchor* an,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ an->PosFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( an->PosFormat )
+ {
+ case 1:
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ an->af.af1.XCoordinate = GET_Short();
+ an->af.af1.YCoordinate = GET_Short();
+
+ FORGET_Frame();
+ break;
+
+ case 2:
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ an->af.af2.XCoordinate = GET_Short();
+ an->af.af2.YCoordinate = GET_Short();
+ an->af.af2.AnchorPoint = GET_UShort();
+
+ FORGET_Frame();
+ break;
+
+ case 3:
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ an->af.af3.XCoordinate = GET_Short();
+ an->af.af3.YCoordinate = GET_Short();
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &an->af.af3.XDeviceTable,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ an->af.af3.XDeviceTable.StartSize = 0;
+ an->af.af3.XDeviceTable.EndSize = 0;
+ an->af.af3.XDeviceTable.DeltaValue = NULL;
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Device( &an->af.af3.YDeviceTable,
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ an->af.af3.YDeviceTable.StartSize = 0;
+ an->af.af3.YDeviceTable.EndSize = 0;
+ an->af.af3.YDeviceTable.DeltaValue = NULL;
+ }
+ break;
+
+ case 4:
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ an->af.af4.XIdAnchor = GET_UShort();
+ an->af.af4.YIdAnchor = GET_UShort();
+
+ FORGET_Frame();
+ break;
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ Free_Device( &an->af.af3.XDeviceTable, memory );
+ return error;
+ }
+
+
+ static void Free_Anchor( TTO_Anchor* an,
+ FT_Memory memory)
+ {
+ if ( an->PosFormat == 3 )
+ {
+ Free_Device( &an->af.af3.YDeviceTable, memory );
+ Free_Device( &an->af.af3.XDeviceTable, memory );
+ }
+ }
+
+
+ static FT_Error Get_Anchor( GPOS_Instance* gpi,
+ TTO_Anchor* an,
+ FT_UShort glyph_index,
+ FT_Pos* x_value,
+ FT_Pos* y_value )
+ {
+ FT_Error error = TT_Err_Ok;
+
+ FT_Outline outline;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+ FT_UShort ap;
+
+ FT_Short pixel_value;
+ FT_UShort load_flags;
+
+ FT_UShort x_ppem, y_ppem;
+ FT_Fixed x_scale, y_scale;
+
+
+ x_ppem = gpi->face->size->metrics.x_ppem;
+ y_ppem = gpi->face->size->metrics.y_ppem;
+ x_scale = gpi->face->size->metrics.x_scale;
+ y_scale = gpi->face->size->metrics.y_scale;
+
+ switch ( an->PosFormat )
+ {
+ case 0:
+ /* The special case of an empty AnchorTable */
+
+ return TTO_Err_Not_Covered;
+
+ case 1:
+ *x_value = x_scale * an->af.af1.XCoordinate / 0x10000;
+ *y_value = y_scale * an->af.af1.YCoordinate / 0x10000;
+ break;
+
+ case 2:
+ /* glyphs must be scaled */
+
+ load_flags = gpi->load_flags & ~FT_LOAD_NO_SCALE;
+
+ if ( !gpi->dvi )
+ {
+ error = (gpos->gfunc)( gpi->face, glyph_index, load_flags );
+ if ( error )
+ return error;
+
+ if ( gpi->face->glyph->format != ft_glyph_format_outline )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ ap = an->af.af2.AnchorPoint;
+
+ outline = gpi->face->glyph->outline;
+
+ /* if outline.n_points is set to zero by gfunc(), we use the
+ design coordinate value pair. This can happen e.g. for
+ sbit glyphs */
+
+ if ( !outline.n_points )
+ goto no_contour_point;
+
+ if ( ap >= outline.n_points )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ *x_value = outline.points[ap].x;
+ *y_value = outline.points[ap].y;
+ }
+ else
+ {
+ no_contour_point:
+ *x_value = x_scale * an->af.af3.XCoordinate / 0x10000;
+ *y_value = y_scale * an->af.af3.YCoordinate / 0x10000;
+ }
+ break;
+
+ case 3:
+ if ( !gpi->dvi )
+ {
+ Get_Device( &an->af.af3.XDeviceTable, x_ppem, &pixel_value );
+ *x_value = pixel_value << 6;
+ Get_Device( &an->af.af3.YDeviceTable, y_ppem, &pixel_value );
+ *y_value = pixel_value << 6;
+ }
+ else
+ *x_value = *y_value = 0;
+
+ *x_value += x_scale * an->af.af3.XCoordinate / 0x10000;
+ *y_value += y_scale * an->af.af3.YCoordinate / 0x10000;
+ break;
+
+ case 4:
+ error = (gpos->mmfunc)( gpi->face, an->af.af4.XIdAnchor,
+ x_value, gpos->data );
+ if ( error )
+ return error;
+
+ error = (gpos->mmfunc)( gpi->face, an->af.af4.YIdAnchor,
+ y_value, gpos->data );
+ if ( error )
+ return error;
+ break;
+ }
+
+ return error;
+ }
+
+
+ /* MarkArray */
+
+ static FT_Error Load_MarkArray ( TTO_MarkArray* ma,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_MarkRecord* mr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ma->MarkCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ma->MarkRecord = NULL;
+
+ if ( ALLOC_ARRAY( ma->MarkRecord, count, TTO_MarkRecord ) )
+ return error;
+
+ mr = ma->MarkRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail;
+
+ mr[n].Class = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &mr[n].MarkAnchor, stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_Anchor( &mr[m].MarkAnchor, memory );
+
+ FREE( mr );
+ return error;
+ }
+
+
+ static void Free_MarkArray( TTO_MarkArray* ma,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_MarkRecord* mr;
+
+
+ if ( ma->MarkRecord )
+ {
+ count = ma->MarkCount;
+ mr = ma->MarkRecord;
+
+ for ( n = 0; n < count; n++ )
+ Free_Anchor( &mr[n].MarkAnchor, memory );
+
+ FREE( mr );
+ }
+ }
+
+
+ /* LookupType 1 */
+
+ /* SinglePosFormat1 */
+ /* SinglePosFormat2 */
+
+ FT_Error Load_SinglePos( TTO_SinglePos* sp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count, format;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ValueRecord* vr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ sp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ format = sp->ValueFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( !format )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &sp->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ switch ( sp->PosFormat )
+ {
+ case 1:
+ error = Load_ValueRecord( &sp->spf.spf1.Value, format,
+ base_offset, stream );
+ if ( error )
+ goto Fail2;
+ break;
+
+ case 2:
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = sp->spf.spf2.ValueCount = GET_UShort();
+
+ FORGET_Frame();
+
+ sp->spf.spf2.Value = NULL;
+
+ if ( ALLOC_ARRAY( sp->spf.spf2.Value, count, TTO_ValueRecord ) )
+ goto Fail2;
+
+ vr = sp->spf.spf2.Value;
+
+ for ( n = 0; n < count; n++ )
+ {
+ error = Load_ValueRecord( &vr[n], format, base_offset, stream );
+ if ( error )
+ goto Fail1;
+ }
+ break;
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_ValueRecord( &vr[m], format, memory );
+
+ FREE( vr );
+
+ Fail2:
+ Free_Coverage( &sp->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_SinglePos( TTO_SinglePos* sp,
+ FT_Memory memory )
+ {
+ FT_UShort n, count, format;
+
+ TTO_ValueRecord* v;
+
+
+ format = sp->ValueFormat;
+
+ switch ( sp->PosFormat )
+ {
+ case 1:
+ Free_ValueRecord( &sp->spf.spf1.Value, format, memory );
+ break;
+
+ case 2:
+ if ( sp->spf.spf2.Value )
+ {
+ count = sp->spf.spf2.ValueCount;
+ v = sp->spf.spf2.Value;
+
+ for ( n = 0; n < count; n++ )
+ Free_ValueRecord( &v[n], format, memory );
+
+ FREE( v );
+ }
+ break;
+ }
+
+ Free_Coverage( &sp->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_SinglePos( GPOS_Instance* gpi,
+ TTO_SinglePos* sp,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_UShort index, property;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &sp->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ switch ( sp->PosFormat )
+ {
+ case 1:
+ error = Get_ValueRecord( gpi, &sp->spf.spf1.Value,
+ sp->ValueFormat, POSITION( buffer->in_pos ) );
+ if ( error )
+ return error;
+ break;
+
+ case 2:
+ if ( index >= sp->spf.spf2.ValueCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+ error = Get_ValueRecord( gpi, &sp->spf.spf2.Value[index],
+ sp->ValueFormat, POSITION( buffer->in_pos ) );
+ if ( error )
+ return error;
+ break;
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable;
+ }
+
+ (buffer->in_pos)++;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 2 */
+
+ /* PairSet */
+
+ static FT_Error Load_PairSet ( TTO_PairSet* ps,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong base_offset;
+
+ TTO_PairValueRecord* pvr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ps->PairValueCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ps->PairValueRecord = NULL;
+
+ if ( ALLOC_ARRAY( ps->PairValueRecord, count, TTO_PairValueRecord ) )
+ return error;
+
+ pvr = ps->PairValueRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ pvr[n].SecondGlyph = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( format1 )
+ {
+ error = Load_ValueRecord( &pvr[n].Value1, format1,
+ base_offset, stream );
+ if ( error )
+ goto Fail;
+ }
+ if ( format2 )
+ {
+ error = Load_ValueRecord( &pvr[n].Value2, format2,
+ base_offset, stream );
+ if ( error )
+ {
+ if ( format1 )
+ Free_ValueRecord( &pvr[n].Value1, format1, memory );
+ goto Fail;
+ }
+ }
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ {
+ if ( format1 )
+ Free_ValueRecord( &pvr[m].Value1, format1, memory );
+ if ( format2 )
+ Free_ValueRecord( &pvr[m].Value2, format2, memory );
+ }
+
+ FREE( pvr );
+ return error;
+ }
+
+
+ static void Free_PairSet( TTO_PairSet* ps,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PairValueRecord* pvr;
+
+
+ if ( ps->PairValueRecord )
+ {
+ count = ps->PairValueCount;
+ pvr = ps->PairValueRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( format1 )
+ Free_ValueRecord( &pvr[n].Value1, format1, memory );
+ if ( format2 )
+ Free_ValueRecord( &pvr[n].Value2, format2, memory );
+ }
+
+ FREE( pvr );
+ }
+ }
+
+
+ /* PairPosFormat1 */
+
+ static FT_Error Load_PairPos1( TTO_PairPosFormat1* ppf1,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_PairSet* ps;
+
+
+ base_offset = FILE_Pos() - 8L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ppf1->PairSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ppf1->PairSet = NULL;
+
+ if ( ALLOC_ARRAY( ppf1->PairSet, count, TTO_PairSet ) )
+ return error;
+
+ ps = ppf1->PairSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_PairSet( &ps[n], format1,
+ format2, stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_PairSet( &ps[m], format1, format2, memory );
+
+ FREE( ps );
+ return error;
+ }
+
+
+ static void Free_PairPos1( TTO_PairPosFormat1* ppf1,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PairSet* ps;
+
+
+ if ( ppf1->PairSet )
+ {
+ count = ppf1->PairSetCount;
+ ps = ppf1->PairSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_PairSet( &ps[n], format1, format2, memory );
+
+ FREE( ps );
+ }
+ }
+
+
+ /* PairPosFormat2 */
+
+ static FT_Error Load_PairPos2( TTO_PairPosFormat2* ppf2,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort m, n, k, count1, count2;
+ FT_ULong cur_offset, new_offset1, new_offset2, base_offset;
+
+ TTO_Class1Record* c1r;
+ TTO_Class2Record* c2r;
+
+
+ base_offset = FILE_Pos() - 8L;
+
+ if ( ACCESS_Frame( 8L ) )
+ return error;
+
+ new_offset1 = GET_UShort() + base_offset;
+ new_offset2 = GET_UShort() + base_offset;
+
+ /* `Class1Count' and `Class2Count' are the upper limits for class
+ values, thus we read it now to make additional safety checks. */
+
+ count1 = ppf2->Class1Count = GET_UShort();
+ count2 = ppf2->Class2Count = GET_UShort();
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset1 ) ||
+ ( error = Load_ClassDefinition( &ppf2->ClassDef1, count1,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ if ( FILE_Seek( new_offset2 ) ||
+ ( error = Load_ClassDefinition( &ppf2->ClassDef2, count2,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ ppf2->Class1Record = NULL;
+
+ if ( ALLOC_ARRAY( ppf2->Class1Record, count1, TTO_Class1Record ) )
+ goto Fail2;
+
+ c1r = ppf2->Class1Record;
+
+ for ( m = 0; m < count1; m++ )
+ {
+ c1r[m].Class2Record = NULL;
+
+ if ( ALLOC_ARRAY( c1r[m].Class2Record, count2, TTO_Class2Record ) )
+ goto Fail1;
+
+ c2r = c1r[m].Class2Record;
+
+ for ( n = 0; n < count2; n++ )
+ {
+ if ( format1 )
+ {
+ error = Load_ValueRecord( &c2r[n].Value1, format1,
+ base_offset, stream );
+ if ( error )
+ goto Fail0;
+ }
+ if ( format2 )
+ {
+ error = Load_ValueRecord( &c2r[n].Value2, format2,
+ base_offset, stream );
+ if ( error )
+ {
+ if ( format1 )
+ Free_ValueRecord( &c2r[n].Value1, format1, memory );
+ goto Fail0;
+ }
+ }
+ }
+
+ continue;
+
+ Fail0:
+ for ( k = 0; k < n; k++ )
+ {
+ if ( format1 )
+ Free_ValueRecord( &c2r[k].Value1, format1, memory );
+ if ( format2 )
+ Free_ValueRecord( &c2r[k].Value2, format2, memory );
+ }
+ goto Fail1;
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( k = 0; k < m; k++ )
+ {
+ c2r = c1r[k].Class2Record;
+
+ for ( n = 0; n < count2; n++ )
+ {
+ if ( format1 )
+ Free_ValueRecord( &c2r[n].Value1, format1, memory );
+ if ( format2 )
+ Free_ValueRecord( &c2r[n].Value2, format2, memory );
+ }
+
+ FREE( c2r );
+ }
+
+ FREE( c1r );
+ Fail2:
+
+ Free_ClassDefinition( &ppf2->ClassDef2, memory );
+
+ Fail3:
+ Free_ClassDefinition( &ppf2->ClassDef1, memory );
+ return error;
+ }
+
+
+ static void Free_PairPos2( TTO_PairPosFormat2* ppf2,
+ FT_UShort format1,
+ FT_UShort format2,
+ FT_Memory memory )
+ {
+ FT_UShort m, n, count1, count2;
+
+ TTO_Class1Record* c1r;
+ TTO_Class2Record* c2r;
+
+
+ if ( ppf2->Class1Record )
+ {
+ c1r = ppf2->Class1Record;
+ count1 = ppf2->Class1Count;
+ count2 = ppf2->Class2Count;
+
+ for ( m = 0; m < count1; m++ )
+ {
+ c2r = c1r[m].Class2Record;
+
+ for ( n = 0; n < count2; n++ )
+ {
+ if ( format1 )
+ Free_ValueRecord( &c2r[n].Value1, format1, memory );
+ if ( format2 )
+ Free_ValueRecord( &c2r[n].Value2, format2, memory );
+ }
+
+ FREE( c2r );
+ }
+
+ FREE( c1r );
+
+ Free_ClassDefinition( &ppf2->ClassDef2, memory );
+ Free_ClassDefinition( &ppf2->ClassDef1, memory );
+ }
+ }
+
+
+ FT_Error Load_PairPos( TTO_PairPos* pp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort format1, format2;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 8L ) )
+ return error;
+
+ pp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ format1 = pp->ValueFormat1 = GET_UShort();
+ format2 = pp->ValueFormat2 = GET_UShort();
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &pp->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ switch ( pp->PosFormat )
+ {
+ case 1:
+ error = Load_PairPos1( &pp->ppf.ppf1, format1, format2, stream );
+ if ( error )
+ goto Fail;
+ break;
+
+ case 2:
+ error = Load_PairPos2( &pp->ppf.ppf2, format1, format2, stream );
+ if ( error )
+ goto Fail;
+ break;
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ Free_Coverage( &pp->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_PairPos( TTO_PairPos* pp,
+ FT_Memory memory )
+ {
+ FT_UShort format1, format2;
+
+
+ format1 = pp->ValueFormat1;
+ format2 = pp->ValueFormat2;
+
+ switch ( pp->PosFormat )
+ {
+ case 1:
+ Free_PairPos1( &pp->ppf.ppf1, format1, format2, memory );
+ break;
+
+ case 2:
+ Free_PairPos2( &pp->ppf.ppf2, format1, format2, memory );
+ break;
+ }
+
+ Free_Coverage( &pp->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_PairPos1( GPOS_Instance* gpi,
+ TTO_PairPosFormat1* ppf1,
+ OTL_Buffer buffer,
+ FT_UShort first_pos,
+ FT_UShort index,
+ FT_UShort format1,
+ FT_UShort format2 )
+ {
+ FT_Error error;
+ FT_UShort numpvr, glyph2;
+
+ TTO_PairValueRecord* pvr;
+
+
+ if ( index >= ppf1->PairSetCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ pvr = ppf1->PairSet[index].PairValueRecord;
+ if ( !pvr )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ glyph2 = IN_CURGLYPH();
+
+ for ( numpvr = ppf1->PairSet[index].PairValueCount;
+ numpvr;
+ numpvr--, pvr++ )
+ {
+ if ( glyph2 == pvr->SecondGlyph )
+ {
+ error = Get_ValueRecord( gpi, &pvr->Value1, format1,
+ POSITION( first_pos ) );
+ if ( error )
+ return error;
+ return Get_ValueRecord( gpi, &pvr->Value2, format2,
+ POSITION( buffer->in_pos ) );
+ }
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Lookup_PairPos2( GPOS_Instance* gpi,
+ TTO_PairPosFormat2* ppf2,
+ OTL_Buffer buffer,
+ FT_UShort first_pos,
+ FT_UShort format1,
+ FT_UShort format2 )
+ {
+ FT_Error error;
+ FT_UShort cl1, cl2;
+
+ TTO_Class1Record* c1r;
+ TTO_Class2Record* c2r;
+
+
+ error = Get_Class( &ppf2->ClassDef1, IN_GLYPH( first_pos ),
+ &cl1, NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ error = Get_Class( &ppf2->ClassDef2, IN_CURGLYPH(),
+ &cl2, NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ c1r = &ppf2->Class1Record[cl1];
+ if ( !c1r )
+ return TTO_Err_Invalid_GPOS_SubTable;
+ c2r = &c1r->Class2Record[cl2];
+
+ error = Get_ValueRecord( gpi, &c2r->Value1, format1, POSITION( first_pos ) );
+ if ( error )
+ return error;
+ return Get_ValueRecord( gpi, &c2r->Value2, format2, POSITION( buffer->in_pos ) );
+ }
+
+
+ static FT_Error Lookup_PairPos( GPOS_Instance* gpi,
+ TTO_PairPos* pp,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_Error error;
+ FT_UShort index, property, first_pos;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+
+ if ( buffer->in_pos >= buffer->in_length - 1 )
+ return TTO_Err_Not_Covered; /* Not enough glyphs in stream */
+
+ if ( context_length != 0xFFFF && context_length < 2 )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &pp->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ /* second glyph */
+
+ first_pos = buffer->in_pos;
+ (buffer->in_pos)++;
+
+ while ( CHECK_Property( gpos->gdef, IN_CURITEM(),
+ flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( buffer->in_pos == buffer->in_length )
+ return TTO_Err_Not_Covered;
+ (buffer->in_pos)++;
+ }
+
+ switch ( pp->PosFormat )
+ {
+ case 1:
+ error = Lookup_PairPos1( gpi, &pp->ppf.ppf1, buffer,
+ first_pos, index,
+ pp->ValueFormat1, pp->ValueFormat2 );
+ break;
+
+ case 2:
+ error = Lookup_PairPos2( gpi, &pp->ppf.ppf2, buffer, first_pos,
+ pp->ValueFormat1, pp->ValueFormat2 );
+ break;
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ /* adjusting the `next' glyph */
+
+ if ( pp->ValueFormat2 )
+ (buffer->in_pos)++;
+
+ return error;
+ }
+
+
+ /* LookupType 3 */
+
+ /* CursivePosFormat1 */
+
+ FT_Error Load_CursivePos( TTO_CursivePos* cp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_EntryExitRecord* eer;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ cp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &cp->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = cp->EntryExitCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cp->EntryExitRecord = NULL;
+
+ if ( ALLOC_ARRAY( cp->EntryExitRecord, count, TTO_EntryExitRecord ) )
+ goto Fail2;
+
+ eer = cp->EntryExitRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ FT_ULong entry_offset;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ entry_offset = new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &eer[n].EntryAnchor,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ eer[n].EntryAnchor.PosFormat = 0;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &eer[n].ExitAnchor,
+ stream ) ) != TT_Err_Ok )
+ {
+ if ( entry_offset )
+ Free_Anchor( &eer[n].EntryAnchor, memory );
+ goto Fail1;
+ }
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ eer[n].ExitAnchor.PosFormat = 0;
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ {
+ Free_Anchor( &eer[m].EntryAnchor, memory );
+ Free_Anchor( &eer[m].ExitAnchor, memory );
+ }
+
+ FREE( eer );
+
+ Fail2:
+ Free_Coverage( &cp->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_CursivePos( TTO_CursivePos* cp,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_EntryExitRecord* eer;
+
+
+ if ( cp->EntryExitRecord )
+ {
+ count = cp->EntryExitCount;
+ eer = cp->EntryExitRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ Free_Anchor( &eer[n].EntryAnchor, memory );
+ Free_Anchor( &eer[n].ExitAnchor, memory );
+ }
+
+ FREE( eer );
+ }
+
+ Free_Coverage( &cp->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_CursivePos( GPOS_Instance* gpi,
+ TTO_CursivePos* cp,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_UShort index, property;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_EntryExitRecord* eer;
+ FT_Pos entry_x, entry_y;
+ FT_Pos exit_x, exit_y;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ {
+ gpi->last = 0xFFFF;
+ return TTO_Err_Not_Covered;
+ }
+
+ /* Glyphs not having the right GDEF properties will be ignored, i.e.,
+ gpi->last won't be reset (contrary to user defined properties). */
+
+ if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ /* We don't handle mark glyphs here. According to Andrei, this isn't
+ possible, but who knows... */
+
+ if ( property == MARK_GLYPH )
+ {
+ gpi->last = 0xFFFF;
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &cp->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ {
+ gpi->last = 0xFFFF;
+ return error;
+ }
+
+ if ( index >= cp->EntryExitCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ eer = &cp->EntryExitRecord[index];
+
+ /* Now comes the messiest part of the whole OpenType
+ specification. At first glance, cursive connections seem easy
+ to understand, but there are pitfalls! The reason is that
+ the specs don't mention how to compute the advance values
+ resp. glyph offsets. I was told it would be an omission, to
+ be fixed in the next OpenType version... Again many thanks to
+ Andrei Burago <andreib@microsoft.com> for clarifications.
+
+ Consider the following example:
+
+ | xadv1 |
+ +---------+
+ | |
+ +-----+--+ 1 |
+ | | .| |
+ | 0+--+------+
+ | 2 |
+ | |
+ 0+--------+
+ | xadv2 |
+
+ glyph1: advance width = 12
+ anchor point = (3,1)
+
+ glyph2: advance width = 11
+ anchor point = (9,4)
+
+ LSB is 1 for both glyphs (so the boxes drawn above are glyph
+ bboxes). Writing direction is R2L; `0' denotes the glyph's
+ coordinate origin.
+
+ Now the surprising part: The advance width of the *left* glyph
+ (resp. of the *bottom* glyph) will be modified, no matter
+ whether the writing direction is L2R or R2L (resp. T2B or
+ B2T)! This assymetry is caused by the fact that the glyph's
+ coordinate origin is always the lower left corner for all
+ writing directions.
+
+ Continuing the above example, we can compute the new
+ (horizontal) advance width of glyph2 as
+
+ 9 - 3 = 6 ,
+
+ and the new vertical offset of glyph2 as
+
+ 1 - 4 = -3 .
+
+
+ Vertical writing direction is far more complicated:
+
+ a) Assuming that we recompute the advance height of the lower glyph:
+
+ --
+ +---------+
+ -- | |
+ +-----+--+ 1 | yadv1
+ | | .| |
+ yadv2 | 0+--+------+ -- BSB1 --
+ | 2 | -- -- y_offset
+ | |
+ BSB2 -- 0+--------+ --
+ -- --
+
+ glyph1: advance height = 6
+ anchor point = (3,1)
+
+ glyph2: advance height = 7
+ anchor point = (9,4)
+
+ TSB is 1 for both glyphs; writing direction is T2B.
+
+
+ BSB1 = yadv1 - (TSB1 + ymax1)
+ BSB2 = yadv2 - (TSB2 + ymax2)
+ y_offset = y2 - y1
+
+ vertical advance width of glyph2
+ = y_offset + BSB2 - BSB1
+ = (y2 - y1) + (yadv2 - (TSB2 + ymax2)) - (yadv1 - (TSB1 + ymax1))
+ = y2 - y1 + yadv2 - TSB2 - ymax2 - (yadv1 - TSB1 - ymax1)
+ = y2 - y1 + yadv2 - TSB2 - ymax2 - yadv1 + TSB1 + ymax1
+
+
+ b) Assuming that we recompute the advance height of the upper glyph:
+
+ -- --
+ +---------+ -- TSB1
+ -- -- | |
+ TSB2 -- +-----+--+ 1 | yadv1 ymax1
+ | | .| |
+ yadv2 | 0+--+------+ -- --
+ ymax2 | 2 | -- y_offset
+ | |
+ -- 0+--------+ --
+ --
+
+ glyph1: advance height = 6
+ anchor point = (3,1)
+
+ glyph2: advance height = 7
+ anchor point = (9,4)
+
+ TSB is 1 for both glyphs; writing direction is T2B.
+
+ y_offset = y2 - y1
+
+ vertical advance width of glyph2
+ = TSB1 + ymax1 + y_offset - (TSB2 + ymax2)
+ = TSB1 + ymax1 + y2 - y1 - TSB2 - ymax2
+
+
+ Comparing a) with b) shows that b) is easier to compute. I'll wait
+ for a reply from Andrei to see what should really be implemented...
+
+ Since horizontal advance widths or vertical advance heights
+ can be used alone but not together, no ambiguity occurs. */
+
+ if ( gpi->last == 0xFFFF )
+ goto end;
+
+ /* Get_Anchor() returns TTO_Err_Not_Covered if there is no anchor
+ table. */
+
+ error = Get_Anchor( gpi, &eer->EntryAnchor, IN_CURGLYPH(),
+ &entry_x, &entry_y );
+ if ( error == TTO_Err_Not_Covered )
+ goto end;
+ if ( error )
+ return error;
+
+ if ( gpi->r2l )
+ {
+ POSITION( buffer->in_pos )->x_advance = entry_x - gpi->anchor_x;
+ POSITION( buffer->in_pos )->new_advance = TRUE;
+ }
+ else
+ {
+ POSITION( gpi->last )->x_advance = gpi->anchor_x - entry_x;
+ POSITION( gpi->last )->new_advance = TRUE;
+ }
+
+ if ( flags & RIGHT_TO_LEFT )
+ {
+ POSITION( gpi->last )->cursive_chain = gpi->last - buffer->in_pos;
+ POSITION( gpi->last )->y_pos = entry_y - gpi->anchor_y;
+ }
+ else
+ {
+ POSITION( buffer->in_pos )->cursive_chain = buffer->in_pos - gpi->last;
+ POSITION( buffer->in_pos )->y_pos = gpi->anchor_y - entry_y;
+ }
+
+ end:
+ error = Get_Anchor( gpi, &eer->ExitAnchor, IN_CURGLYPH(),
+ &exit_x, &exit_y );
+ if ( error == TTO_Err_Not_Covered )
+ gpi->last = 0xFFFF;
+ else
+ {
+ gpi->last = buffer->in_pos;
+ gpi->anchor_x = exit_x;
+ gpi->anchor_y = exit_y;
+ }
+ if ( error )
+ return error;
+
+ (buffer->in_pos)++;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 4 */
+
+ /* BaseArray */
+
+ static FT_Error Load_BaseArray( TTO_BaseArray* ba,
+ FT_UShort num_classes,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort m, n, k, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_BaseRecord* br;
+ TTO_Anchor* ban;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ba->BaseCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ba->BaseRecord = NULL;
+
+ if ( ALLOC_ARRAY( ba->BaseRecord, count, TTO_BaseRecord ) )
+ return error;
+
+ br = ba->BaseRecord;
+
+ for ( m = 0; m < count; m++ )
+ {
+ br[m].BaseAnchor = NULL;
+
+ if ( ALLOC_ARRAY( br[m].BaseAnchor, num_classes, TTO_Anchor ) )
+ goto Fail;
+
+ ban = br[m].BaseAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail0;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &ban[n], stream ) ) != TT_Err_Ok )
+ goto Fail0;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ continue;
+ Fail0:
+ for ( k = 0; k < n; k++ )
+ Free_Anchor( &ban[k], memory );
+ goto Fail;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( k = 0; k < m; k++ )
+ {
+ ban = br[k].BaseAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &ban[n], memory );
+
+ FREE( ban );
+ }
+
+ FREE( br );
+ return error;
+ }
+
+
+ static void Free_BaseArray( TTO_BaseArray* ba,
+ FT_UShort num_classes,
+ FT_Memory memory )
+ {
+ FT_UShort m, n, count;
+
+ TTO_BaseRecord* br;
+ TTO_Anchor* ban;
+
+
+ if ( ba->BaseRecord )
+ {
+ count = ba->BaseCount;
+ br = ba->BaseRecord;
+
+ for ( m = 0; m < count; m++ )
+ {
+ ban = br[m].BaseAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &ban[n], memory );
+
+ FREE( ban );
+ }
+
+ FREE( br );
+ }
+ }
+
+
+ /* MarkBasePosFormat1 */
+
+ FT_Error Load_MarkBasePos( TTO_MarkBasePos* mbp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ mbp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mbp->MarkCoverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mbp->BaseCoverage, stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail2;
+
+ mbp->ClassCount = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_MarkArray( &mbp->MarkArray, stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_BaseArray( &mbp->BaseArray, mbp->ClassCount,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_MarkArray( &mbp->MarkArray, memory );
+
+ Fail2:
+ Free_Coverage( &mbp->BaseCoverage, memory );
+
+ Fail3:
+ Free_Coverage( &mbp->MarkCoverage, memory );
+ return error;
+ }
+
+
+ void Free_MarkBasePos( TTO_MarkBasePos* mbp,
+ FT_Memory memory )
+ {
+ Free_BaseArray( &mbp->BaseArray, mbp->ClassCount, memory );
+ Free_MarkArray( &mbp->MarkArray, memory );
+ Free_Coverage( &mbp->BaseCoverage, memory );
+ Free_Coverage( &mbp->MarkCoverage, memory );
+ }
+
+
+ static FT_Error Lookup_MarkBasePos( GPOS_Instance* gpi,
+ TTO_MarkBasePos* mbp,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_UShort i, j, mark_index, base_index, property, class;
+ FT_Pos x_mark_value, y_mark_value, x_base_value, y_base_value;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_MarkArray* ma;
+ TTO_BaseArray* ba;
+ TTO_BaseRecord* br;
+ TTO_Anchor* mark_anchor;
+ TTO_Anchor* base_anchor;
+
+ OTL_Position o;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( flags & IGNORE_BASE_GLYPHS )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gpos->gdef, IN_CURITEM(),
+ flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &mbp->MarkCoverage, IN_CURGLYPH(),
+ &mark_index );
+ if ( error )
+ return error;
+
+ /* now we search backwards for a non-mark glyph */
+
+ i = 1;
+ j = buffer->in_pos - 1;
+
+ while ( i <= buffer->in_pos )
+ {
+ error = TT_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),
+ &property );
+ if ( error )
+ return error;
+
+ if ( !( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS ) )
+ break;
+
+ i++;
+ j--;
+ }
+
+ /* The following assertion is too strong -- at least for mangal.ttf. */
+#if 0
+ if ( property != TTO_BASE_GLYPH )
+ return TTO_Err_Not_Covered;
+#endif
+
+ if ( i > buffer->in_pos )
+ return TTO_Err_Not_Covered;
+
+ error = Coverage_Index( &mbp->BaseCoverage, IN_GLYPH( j ),
+ &base_index );
+ if ( error )
+ return error;
+
+ ma = &mbp->MarkArray;
+
+ if ( mark_index >= ma->MarkCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ class = ma->MarkRecord[mark_index].Class;
+ mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;
+
+ if ( class >= mbp->ClassCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ ba = &mbp->BaseArray;
+
+ if ( base_index >= ba->BaseCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ br = &ba->BaseRecord[base_index];
+ base_anchor = &br->BaseAnchor[class];
+
+ error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(),
+ &x_mark_value, &y_mark_value );
+ if ( error )
+ return error;
+
+ error = Get_Anchor( gpi, base_anchor, IN_GLYPH( j ),
+ &x_base_value, &y_base_value );
+ if ( error )
+ return error;
+
+ /* anchor points are not cumulative */
+
+ o = POSITION( buffer->in_pos );
+
+ o->x_pos = x_base_value - x_mark_value;
+ o->y_pos = y_base_value - y_mark_value;
+ o->x_advance = 0;
+ o->y_advance = 0;
+ o->back = i;
+
+ (buffer->in_pos)++;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 5 */
+
+ /* LigatureAttach */
+
+ static FT_Error Load_LigatureAttach( TTO_LigatureAttach* lat,
+ FT_UShort num_classes,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort m, n, k, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ComponentRecord* cr;
+ TTO_Anchor* lan;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = lat->ComponentCount = GET_UShort();
+
+ FORGET_Frame();
+
+ lat->ComponentRecord = NULL;
+
+ if ( ALLOC_ARRAY( lat->ComponentRecord, count, TTO_ComponentRecord ) )
+ return error;
+
+ cr = lat->ComponentRecord;
+
+ for ( m = 0; m < count; m++ )
+ {
+ cr[m].LigatureAnchor = NULL;
+
+ if ( ALLOC_ARRAY( cr[m].LigatureAnchor, num_classes, TTO_Anchor ) )
+ goto Fail;
+
+ lan = cr[m].LigatureAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail0;
+
+ new_offset = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( new_offset )
+ {
+ new_offset += base_offset;
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &lan[n], stream ) ) != TT_Err_Ok )
+ goto Fail0;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ lan[n].PosFormat = 0;
+ }
+
+ continue;
+ Fail0:
+ for ( k = 0; k < n; k++ )
+ Free_Anchor( &lan[k], memory );
+ goto Fail;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( k = 0; k < m; k++ )
+ {
+ lan = cr[k].LigatureAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &lan[n], memory );
+
+ FREE( lan );
+ }
+
+ FREE( cr );
+ return error;
+ }
+
+
+ static void Free_LigatureAttach( TTO_LigatureAttach* lat,
+ FT_UShort num_classes,
+ FT_Memory memory )
+ {
+ FT_UShort m, n, count;
+
+ TTO_ComponentRecord* cr;
+ TTO_Anchor* lan;
+
+
+ if ( lat->ComponentRecord )
+ {
+ count = lat->ComponentCount;
+ cr = lat->ComponentRecord;
+
+ for ( m = 0; m < count; m++ )
+ {
+ lan = cr[m].LigatureAnchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &lan[n], memory );
+
+ FREE( lan );
+ }
+
+ FREE( cr );
+ }
+ }
+
+
+ /* LigatureArray */
+
+ static FT_Error Load_LigatureArray( TTO_LigatureArray* la,
+ FT_UShort num_classes,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_LigatureAttach* lat;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = la->LigatureCount = GET_UShort();
+
+ FORGET_Frame();
+
+ la->LigatureAttach = NULL;
+
+ if ( ALLOC_ARRAY( la->LigatureAttach, count, TTO_LigatureAttach ) )
+ return error;
+
+ lat = la->LigatureAttach;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LigatureAttach( &lat[n], num_classes,
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_LigatureAttach( &lat[m], num_classes, memory );
+
+ FREE( lat );
+ return error;
+ }
+
+
+ static void Free_LigatureArray( TTO_LigatureArray* la,
+ FT_UShort num_classes,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_LigatureAttach* lat;
+
+
+ if ( la->LigatureAttach )
+ {
+ count = la->LigatureCount;
+ lat = la->LigatureAttach;
+
+ for ( n = 0; n < count; n++ )
+ Free_LigatureAttach( &lat[n], num_classes, memory );
+
+ FREE( lat );
+ }
+ }
+
+
+ /* MarkLigPosFormat1 */
+
+ FT_Error Load_MarkLigPos( TTO_MarkLigPos* mlp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ mlp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mlp->MarkCoverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mlp->LigatureCoverage,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail2;
+
+ mlp->ClassCount = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_MarkArray( &mlp->MarkArray, stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LigatureArray( &mlp->LigatureArray, mlp->ClassCount,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_MarkArray( &mlp->MarkArray, memory );
+
+ Fail2:
+ Free_Coverage( &mlp->LigatureCoverage, memory );
+
+ Fail3:
+ Free_Coverage( &mlp->MarkCoverage, memory );
+ return error;
+ }
+
+
+ void Free_MarkLigPos( TTO_MarkLigPos* mlp,
+ FT_Memory memory)
+ {
+ Free_LigatureArray( &mlp->LigatureArray, mlp->ClassCount, memory );
+ Free_MarkArray( &mlp->MarkArray, memory );
+ Free_Coverage( &mlp->LigatureCoverage, memory );
+ Free_Coverage( &mlp->MarkCoverage, memory );
+ }
+
+
+ static FT_Error Lookup_MarkLigPos( GPOS_Instance* gpi,
+ TTO_MarkLigPos* mlp,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_UShort i, j, mark_index, lig_index, property, class;
+ FT_UShort mark_glyph;
+ FT_Pos x_mark_value, y_mark_value, x_lig_value, y_lig_value;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_MarkArray* ma;
+ TTO_LigatureArray* la;
+ TTO_LigatureAttach* lat;
+ TTO_ComponentRecord* cr;
+ FT_UShort comp_index;
+ TTO_Anchor* mark_anchor;
+ TTO_Anchor* lig_anchor;
+
+ OTL_Position o;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( flags & IGNORE_LIGATURES )
+ return TTO_Err_Not_Covered;
+
+ mark_glyph = IN_CURGLYPH();
+
+ if ( CHECK_Property( gpos->gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &mlp->MarkCoverage, mark_glyph, &mark_index );
+ if ( error )
+ return error;
+
+ /* now we search backwards for a non-mark glyph */
+
+ i = 1;
+ j = buffer->in_pos - 1;
+
+ while ( i <= buffer->in_pos )
+ {
+ error = TT_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),
+ &property );
+ if ( error )
+ return error;
+
+ if ( !( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS ) )
+ break;
+
+ i++;
+ j--;
+ }
+
+ /* Similar to Lookup_MarkBasePos(), I suspect that this assertion is
+ too strong, thus it is commented out. */
+#if 0
+ if ( property != TTO_LIGATURE )
+ return TTO_Err_Not_Covered;
+#endif
+
+ if ( i > buffer->in_pos )
+ return TTO_Err_Not_Covered;
+
+ error = Coverage_Index( &mlp->LigatureCoverage, IN_GLYPH( j ),
+ &lig_index );
+ if ( error )
+ return error;
+
+ ma = &mlp->MarkArray;
+
+ if ( mark_index >= ma->MarkCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ class = ma->MarkRecord[mark_index].Class;
+ mark_anchor = &ma->MarkRecord[mark_index].MarkAnchor;
+
+ if ( class >= mlp->ClassCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ la = &mlp->LigatureArray;
+
+ if ( lig_index >= la->LigatureCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ lat = &la->LigatureAttach[lig_index];
+
+ /* We must now check whether the ligature ID of the current mark glyph
+ is identical to the ligature ID of the found ligature. If yes, we
+ can directly use the component index. If not, we attach the mark
+ glyph to the last component of the ligature. */
+
+ if ( IN_LIGID( j ) == IN_LIGID( buffer->in_pos) )
+ {
+ comp_index = IN_COMPONENT( buffer->in_pos );
+ if ( comp_index >= lat->ComponentCount )
+ return TTO_Err_Not_Covered;
+ }
+ else
+ comp_index = lat->ComponentCount - 1;
+
+ cr = &lat->ComponentRecord[comp_index];
+ lig_anchor = &cr->LigatureAnchor[class];
+
+ error = Get_Anchor( gpi, mark_anchor, IN_CURGLYPH(),
+ &x_mark_value, &y_mark_value );
+ if ( error )
+ return error;
+ error = Get_Anchor( gpi, lig_anchor, IN_GLYPH( j ),
+ &x_lig_value, &y_lig_value );
+ if ( error )
+ return error;
+
+ /* anchor points are not cumulative */
+
+ o = POSITION( buffer->in_pos );
+
+ o->x_pos = x_lig_value - x_mark_value;
+ o->y_pos = y_lig_value - y_mark_value;
+ o->x_advance = 0;
+ o->y_advance = 0;
+ o->back = i;
+
+ (buffer->in_pos)++;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 6 */
+
+ /* Mark2Array */
+
+ static FT_Error Load_Mark2Array( TTO_Mark2Array* m2a,
+ FT_UShort num_classes,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort k, m, n, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Mark2Record* m2r;
+ TTO_Anchor* m2an;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = m2a->Mark2Count = GET_UShort();
+
+ FORGET_Frame();
+
+ m2a->Mark2Record = NULL;
+
+ if ( ALLOC_ARRAY( m2a->Mark2Record, count, TTO_Mark2Record ) )
+ return error;
+
+ m2r = m2a->Mark2Record;
+
+ for ( m = 0; m < count; m++ )
+ {
+ m2r[m].Mark2Anchor = NULL;
+
+ if ( ALLOC_ARRAY( m2r[m].Mark2Anchor, num_classes, TTO_Anchor ) )
+ goto Fail;
+
+ m2an = m2r[m].Mark2Anchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail0;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Anchor( &m2an[n], stream ) ) != TT_Err_Ok )
+ goto Fail0;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ continue;
+ Fail0:
+ for ( k = 0; k < n; k++ )
+ Free_Anchor( &m2an[k], memory );
+ goto Fail;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( k = 0; k < m; k++ )
+ {
+ m2an = m2r[k].Mark2Anchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &m2an[n], memory );
+
+ FREE( m2an );
+ }
+
+ FREE( m2r );
+ return error;
+ }
+
+
+ static void Free_Mark2Array( TTO_Mark2Array* m2a,
+ FT_UShort num_classes,
+ FT_Memory memory )
+ {
+ FT_UShort m, n, count;
+
+ TTO_Mark2Record* m2r;
+ TTO_Anchor* m2an;
+
+
+ if ( m2a->Mark2Record )
+ {
+ count = m2a->Mark2Count;
+ m2r = m2a->Mark2Record;
+
+ for ( m = 0; m < count; m++ )
+ {
+ m2an = m2r[m].Mark2Anchor;
+
+ for ( n = 0; n < num_classes; n++ )
+ Free_Anchor( &m2an[n], memory );
+
+ FREE( m2an );
+ }
+
+ FREE( m2r );
+ }
+ }
+
+
+ /* MarkMarkPosFormat1 */
+
+ FT_Error Load_MarkMarkPos( TTO_MarkMarkPos* mmp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_ULong cur_offset, new_offset, base_offset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ mmp->PosFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mmp->Mark1Coverage,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &mmp->Mark2Coverage,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail2;
+
+ mmp->ClassCount = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_MarkArray( &mmp->Mark1Array, stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Mark2Array( &mmp->Mark2Array, mmp->ClassCount,
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_MarkArray( &mmp->Mark1Array, memory );
+
+ Fail2:
+ Free_Coverage( &mmp->Mark2Coverage, memory );
+
+ Fail3:
+ Free_Coverage( &mmp->Mark1Coverage, memory );
+ return error;
+ }
+
+
+ void Free_MarkMarkPos( TTO_MarkMarkPos* mmp,
+ FT_Memory memory)
+ {
+ Free_Mark2Array( &mmp->Mark2Array, mmp->ClassCount, memory );
+ Free_MarkArray( &mmp->Mark1Array, memory );
+ Free_Coverage( &mmp->Mark2Coverage, memory );
+ Free_Coverage( &mmp->Mark1Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_MarkMarkPos( GPOS_Instance* gpi,
+ TTO_MarkMarkPos* mmp,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length )
+ {
+ FT_UShort j, mark1_index, mark2_index, property, class;
+ FT_Pos x_mark1_value, y_mark1_value,
+ x_mark2_value, y_mark2_value;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_MarkArray* ma1;
+ TTO_Mark2Array* ma2;
+ TTO_Mark2Record* m2r;
+ TTO_Anchor* mark1_anchor;
+ TTO_Anchor* mark2_anchor;
+
+ OTL_Position o;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( flags & IGNORE_MARKS )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gpos->gdef, IN_CURITEM(),
+ flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &mmp->Mark1Coverage, IN_CURGLYPH(),
+ &mark1_index );
+ if ( error )
+ return error;
+
+ /* now we check the preceding glyph whether it is a suitable
+ mark glyph */
+
+ if ( buffer->in_pos == 0 )
+ return TTO_Err_Not_Covered;
+
+ j = buffer->in_pos - 1;
+ error = TT_GDEF_Get_Glyph_Property( gpos->gdef, IN_GLYPH( j ),
+ &property );
+ if ( error )
+ return error;
+
+ if ( flags & IGNORE_SPECIAL_MARKS )
+ {
+ if ( property != (flags & 0xFF00) )
+ return TTO_Err_Not_Covered;
+ }
+ else
+ {
+ if ( property != TTO_MARK )
+ return TTO_Err_Not_Covered;
+ }
+
+ error = Coverage_Index( &mmp->Mark2Coverage, IN_GLYPH( j ),
+ &mark2_index );
+ if ( error )
+ return error;
+
+ ma1 = &mmp->Mark1Array;
+
+ if ( mark1_index >= ma1->MarkCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ class = ma1->MarkRecord[mark1_index].Class;
+ mark1_anchor = &ma1->MarkRecord[mark1_index].MarkAnchor;
+
+ if ( class >= mmp->ClassCount )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ ma2 = &mmp->Mark2Array;
+
+ if ( mark2_index >= ma2->Mark2Count )
+ return TTO_Err_Invalid_GPOS_SubTable;
+
+ m2r = &ma2->Mark2Record[mark2_index];
+ mark2_anchor = &m2r->Mark2Anchor[class];
+
+ error = Get_Anchor( gpi, mark1_anchor, IN_CURGLYPH(),
+ &x_mark1_value, &y_mark1_value );
+ if ( error )
+ return error;
+ error = Get_Anchor( gpi, mark2_anchor, IN_GLYPH( j ),
+ &x_mark2_value, &y_mark2_value );
+ if ( error )
+ return error;
+
+ /* anchor points are not cumulative */
+
+ o = POSITION( buffer->in_pos );
+
+ o->x_pos = x_mark2_value - x_mark1_value;
+ o->y_pos = y_mark2_value - y_mark1_value;
+ o->x_advance = 0;
+ o->y_advance = 0;
+ o->back = 1;
+
+ (buffer->in_pos)++;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* Do the actual positioning for a context positioning (either format
+ 7 or 8). This is only called after we've determined that the stream
+ matches the subrule. */
+
+ static FT_Error Do_ContextPos( GPOS_Instance* gpi,
+ FT_UShort GlyphCount,
+ FT_UShort PosCount,
+ TTO_PosLookupRecord* pos,
+ OTL_Buffer buffer,
+ int nesting_level )
+ {
+ FT_Error error;
+ FT_UShort i, old_pos;
+
+
+ i = 0;
+
+ while ( i < GlyphCount )
+ {
+ if ( PosCount && i == pos->SequenceIndex )
+ {
+ old_pos = buffer->in_pos;
+
+ /* Do a positioning */
+
+ error = GPos_Do_Glyph_Lookup( gpi, pos->LookupListIndex, buffer,
+ GlyphCount, nesting_level );
+
+ if ( error )
+ return error;
+
+ pos++;
+ PosCount--;
+ i += buffer->in_pos - old_pos;
+ }
+ else
+ {
+ i++;
+ (buffer->in_pos)++;
+ }
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 7 */
+
+ /* PosRule */
+
+ static FT_Error Load_PosRule( TTO_PosRule* pr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* i;
+
+ TTO_PosLookupRecord* plr;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ pr->GlyphCount = GET_UShort();
+ pr->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ pr->Input = NULL;
+
+ count = pr->GlyphCount - 1; /* only GlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( pr->Input, count, FT_UShort ) )
+ return error;
+
+ i = pr->Input;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ i[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ pr->PosLookupRecord = NULL;
+
+ count = pr->PosCount;
+
+ if ( ALLOC_ARRAY( pr->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = pr->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ FREE( i );
+ return error;
+ }
+
+
+ static void Free_PosRule( TTO_PosRule* pr,
+ FT_Memory memory )
+ {
+ FREE( pr->PosLookupRecord );
+ FREE( pr->Input );
+ }
+
+
+ /* PosRuleSet */
+
+ static FT_Error Load_PosRuleSet( TTO_PosRuleSet* prs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_PosRule* pr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = prs->PosRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ prs->PosRule = NULL;
+
+ if ( ALLOC_ARRAY( prs->PosRule, count, TTO_PosRule ) )
+ return error;
+
+ pr = prs->PosRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_PosRule( &pr[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_PosRule( &pr[m], memory );
+
+ FREE( pr );
+ return error;
+ }
+
+
+ static void Free_PosRuleSet( TTO_PosRuleSet* prs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PosRule* pr;
+
+
+ if ( prs->PosRule )
+ {
+ count = prs->PosRuleCount;
+ pr = prs->PosRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_PosRule( &pr[n], memory );
+
+ FREE( pr );
+ }
+ }
+
+
+ /* ContextPosFormat1 */
+
+ static FT_Error Load_ContextPos1( TTO_ContextPosFormat1* cpf1,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_PosRuleSet* prs;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &cpf1->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = cpf1->PosRuleSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpf1->PosRuleSet = NULL;
+
+ if ( ALLOC_ARRAY( cpf1->PosRuleSet, count, TTO_PosRuleSet ) )
+ goto Fail2;
+
+ prs = cpf1->PosRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_PosRuleSet( &prs[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_PosRuleSet( &prs[m], memory );
+
+ FREE( prs );
+
+ Fail2:
+ Free_Coverage( &cpf1->Coverage, memory );
+ return error;
+ }
+
+
+ static void Gpos_Free_Context1( TTO_ContextPosFormat1* cpf1,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PosRuleSet* prs;
+
+
+ if ( cpf1->PosRuleSet )
+ {
+ count = cpf1->PosRuleSetCount;
+ prs = cpf1->PosRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_PosRuleSet( &prs[n], memory );
+
+ FREE( prs );
+ }
+
+ Free_Coverage( &cpf1->Coverage, memory );
+ }
+
+
+ /* PosClassRule */
+
+ static FT_Error Load_PosClassRule( TTO_ContextPosFormat2* cpf2,
+ TTO_PosClassRule* pcr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* c;
+ TTO_PosLookupRecord* plr;
+ FT_Bool* d;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ pcr->GlyphCount = GET_UShort();
+ pcr->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( pcr->GlyphCount > cpf2->MaxContextLength )
+ cpf2->MaxContextLength = pcr->GlyphCount;
+
+ pcr->Class = NULL;
+
+ count = pcr->GlyphCount - 1; /* only GlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( pcr->Class, count, FT_UShort ) )
+ return error;
+
+ c = pcr->Class;
+ d = cpf2->ClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ {
+ c[n] = GET_UShort();
+
+ /* We check whether the specific class is used at all. If not,
+ class 0 is used instead. */
+
+ if ( !d[c[n]] )
+ c[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ pcr->PosLookupRecord = NULL;
+
+ count = pcr->PosCount;
+
+ if ( ALLOC_ARRAY( pcr->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = pcr->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ FREE( c );
+ return error;
+ }
+
+
+ static void Free_PosClassRule( TTO_PosClassRule* pcr,
+ FT_Memory memory )
+ {
+ FREE( pcr->PosLookupRecord );
+ FREE( pcr->Class );
+ }
+
+
+ /* PosClassSet */
+
+ static FT_Error Load_PosClassSet( TTO_ContextPosFormat2* cpf2,
+ TTO_PosClassSet* pcs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_PosClassRule* pcr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = pcs->PosClassRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ pcs->PosClassRule = NULL;
+
+ if ( ALLOC_ARRAY( pcs->PosClassRule, count, TTO_PosClassRule ) )
+ return error;
+
+ pcr = pcs->PosClassRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_PosClassRule( cpf2, &pcr[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_PosClassRule( &pcr[m], memory );
+
+ FREE( pcr );
+ return error;
+ }
+
+
+ static void Free_PosClassSet( TTO_PosClassSet* pcs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PosClassRule* pcr;
+
+
+ if ( pcs->PosClassRule )
+ {
+ count = pcs->PosClassRuleCount;
+ pcr = pcs->PosClassRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_PosClassRule( &pcr[n], memory );
+
+ FREE( pcr );
+ }
+ }
+
+
+ /* ContextPosFormat2 */
+
+ static FT_Error Load_ContextPos2( TTO_ContextPosFormat2* cpf2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_PosClassSet* pcs;
+
+
+ base_offset = FILE_Pos() - 2;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &cpf2->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ /* `PosClassSetCount' is the upper limit for class values, thus we
+ read it now to make an additional safety check. */
+
+ count = cpf2->PosClassSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ClassDefinition( &cpf2->ClassDef, count,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ cpf2->PosClassSet = NULL;
+ cpf2->MaxContextLength = 0;
+
+ if ( ALLOC_ARRAY( cpf2->PosClassSet, count, TTO_PosClassSet ) )
+ goto Fail2;
+
+ pcs = cpf2->PosClassSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ if ( new_offset != base_offset ) /* not a NULL offset */
+ {
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_PosClassSet( cpf2, &pcs[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ /* we create a PosClassSet table with no entries */
+
+ cpf2->PosClassSet[n].PosClassRuleCount = 0;
+ cpf2->PosClassSet[n].PosClassRule = NULL;
+ }
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; n++ )
+ Free_PosClassSet( &pcs[m], memory );
+
+ FREE( pcs );
+
+ Fail2:
+ Free_ClassDefinition( &cpf2->ClassDef, memory );
+
+ Fail3:
+ Free_Coverage( &cpf2->Coverage, memory );
+ return error;
+ }
+
+
+ static void Gpos_Free_Context2( TTO_ContextPosFormat2* cpf2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_PosClassSet* pcs;
+
+
+ if ( cpf2->PosClassSet )
+ {
+ count = cpf2->PosClassSetCount;
+ pcs = cpf2->PosClassSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_PosClassSet( &pcs[n], memory );
+
+ FREE( pcs );
+ }
+
+ Free_ClassDefinition( &cpf2->ClassDef, memory );
+ Free_Coverage( &cpf2->Coverage, memory );
+ }
+
+
+ /* ContextPosFormat3 */
+
+ static FT_Error Load_ContextPos3( TTO_ContextPosFormat3* cpf3,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Coverage* c;
+ TTO_PosLookupRecord* plr;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ cpf3->GlyphCount = GET_UShort();
+ cpf3->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpf3->Coverage = NULL;
+
+ count = cpf3->GlyphCount;
+
+ if ( ALLOC_ARRAY( cpf3->Coverage, count, TTO_Coverage ) )
+ return error;
+
+ c = cpf3->Coverage;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &c[n], stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ cpf3->PosLookupRecord = NULL;
+
+ count = cpf3->PosCount;
+
+ if ( ALLOC_ARRAY( cpf3->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = cpf3->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ return error;
+ }
+
+
+ static void Gpos_Free_Context3( TTO_ContextPosFormat3* cpf3,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Coverage* c;
+
+
+ FREE( cpf3->PosLookupRecord );
+
+ if ( cpf3->Coverage )
+ {
+ count = cpf3->GlyphCount;
+ c = cpf3->Coverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+ }
+
+
+ /* ContextPos */
+
+ FT_Error Load_ContextPos( TTO_ContextPos* cp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cp->PosFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( cp->PosFormat )
+ {
+ case 1:
+ return Load_ContextPos1( &cp->cpf.cpf1, stream );
+
+ case 2:
+ return Load_ContextPos2( &cp->cpf.cpf2, stream );
+
+ case 3:
+ return Load_ContextPos3( &cp->cpf.cpf3, stream );
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ void Free_ContextPos( TTO_ContextPos* cp,
+ FT_Memory memory )
+ {
+ switch ( cp->PosFormat )
+ {
+ case 1:
+ Gpos_Free_Context1( &cp->cpf.cpf1, memory );
+ break;
+
+ case 2:
+ Gpos_Free_Context2( &cp->cpf.cpf2, memory );
+ break;
+
+ case 3:
+ Gpos_Free_Context3( &cp->cpf.cpf3, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Lookup_ContextPos1( GPOS_Instance* gpi,
+ TTO_ContextPosFormat1* cpf1,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_Int i, j, k, numpr;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_PosRule* pr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &cpf1->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ pr = cpf1->PosRuleSet[index].PosRule;
+ numpr = cpf1->PosRuleSet[index].PosRuleCount;
+
+ for ( k = 0; k < numpr; k++ )
+ {
+ if ( context_length != 0xFFFF && context_length < pr[k].GlyphCount )
+ goto next_posrule;
+
+ if ( buffer->in_pos + pr[k].GlyphCount > buffer->in_length )
+ goto next_posrule; /* context is too long */
+
+ for ( i = 1, j = buffer->in_pos + 1; i < pr[k].GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + pr[k].GlyphCount - i == (FT_Int)buffer->in_length )
+ goto next_posrule;
+ j++;
+ }
+
+ if ( IN_GLYPH( j ) != pr[k].Input[i - 1] )
+ goto next_posrule;
+ }
+
+ return Do_ContextPos( gpi, pr[k].GlyphCount,
+ pr[k].PosCount, pr[k].PosLookupRecord,
+ buffer,
+ nesting_level );
+
+ next_posrule:
+ ;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Lookup_ContextPos2( GPOS_Instance* gpi,
+ TTO_ContextPosFormat2* cpf2,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_Error error;
+ FT_Memory memory = gpi->face->memory;
+ FT_UShort i, j, k, known_classes;
+
+ FT_UShort* classes;
+ FT_UShort* cl;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_PosClassSet* pcs;
+ TTO_PosClassRule* pr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ /* Note: The coverage table in format 2 doesn't give an index into
+ anything. It just lets us know whether or not we need to
+ do any lookup at all. */
+
+ error = Coverage_Index( &cpf2->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ if ( ALLOC_ARRAY( classes, cpf2->MaxContextLength, FT_UShort ) )
+ return error;
+
+ error = Get_Class( &cpf2->ClassDef, IN_CURGLYPH(),
+ &classes[0], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+ known_classes = 0;
+
+ pcs = &cpf2->PosClassSet[classes[0]];
+ if ( !pcs )
+ {
+ error = TTO_Err_Invalid_GPOS_SubTable;
+ goto End;
+ }
+
+ for ( k = 0; k < pcs->PosClassRuleCount; k++ )
+ {
+ pr = &pcs->PosClassRule[k];
+
+ if ( context_length != 0xFFFF && context_length < pr->GlyphCount )
+ goto next_posclassrule;
+
+ if ( buffer->in_pos + pr->GlyphCount > buffer->in_length )
+ goto next_posclassrule; /* context is too long */
+
+ cl = pr->Class;
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = buffer->in_pos + 1; i < pr->GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+
+ if ( j + pr->GlyphCount - i == (FT_Int)buffer->in_length )
+ goto next_posclassrule;
+ j++;
+ }
+
+ if ( i > known_classes )
+ {
+ /* Keeps us from having to do this for each rule */
+
+ error = Get_Class( &cpf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+ known_classes = i;
+ }
+
+ if ( cl[i - 1] != classes[i] )
+ goto next_posclassrule;
+ }
+
+ error = Do_ContextPos( gpi, pr->GlyphCount,
+ pr->PosCount, pr->PosLookupRecord,
+ buffer,
+ nesting_level );
+ goto End;
+
+ next_posclassrule:
+ ;
+ }
+
+ error = TTO_Err_Not_Covered;
+
+ End:
+ FREE( classes );
+ return error;
+ }
+
+
+ static FT_Error Lookup_ContextPos3( GPOS_Instance* gpi,
+ TTO_ContextPosFormat3* cpf3,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_Error error;
+ FT_UShort index, i, j, property;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_Coverage* c;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ if ( context_length != 0xFFFF && context_length < cpf3->GlyphCount )
+ return TTO_Err_Not_Covered;
+
+ if ( buffer->in_pos + cpf3->GlyphCount > buffer->in_length )
+ return TTO_Err_Not_Covered; /* context is too long */
+
+ c = cpf3->Coverage;
+
+ for ( i = 1, j = 1; i < cpf3->GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + cpf3->GlyphCount - i == (FT_Int)buffer->in_length )
+ return TTO_Err_Not_Covered;
+ j++;
+ }
+
+ error = Coverage_Index( &c[i], IN_GLYPH( j ), &index );
+ if ( error )
+ return error;
+ }
+
+ return Do_ContextPos( gpi, cpf3->GlyphCount,
+ cpf3->PosCount, cpf3->PosLookupRecord,
+ buffer,
+ nesting_level );
+ }
+
+
+ static FT_Error Lookup_ContextPos( GPOS_Instance* gpi,
+ TTO_ContextPos* cp,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ switch ( cp->PosFormat )
+ {
+ case 1:
+ return Lookup_ContextPos1( gpi, &cp->cpf.cpf1, buffer,
+ flags, context_length, nesting_level );
+
+ case 2:
+ return Lookup_ContextPos2( gpi, &cp->cpf.cpf2, buffer,
+ flags, context_length, nesting_level );
+
+ case 3:
+ return Lookup_ContextPos3( gpi, &cp->cpf.cpf3, buffer,
+ flags, context_length, nesting_level );
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ /* LookupType 8 */
+
+ /* ChainPosRule */
+
+ static FT_Error Load_ChainPosRule( TTO_ChainPosRule* cpr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* b;
+ FT_UShort* i;
+ FT_UShort* l;
+
+ TTO_PosLookupRecord* plr;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cpr->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpr->Backtrack = NULL;
+
+ count = cpr->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( cpr->Backtrack, count, FT_UShort ) )
+ return error;
+
+ b = cpr->Backtrack;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail4;
+
+ for ( n = 0; n < count; n++ )
+ b[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ cpr->InputGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpr->Input = NULL;
+
+ count = cpr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( cpr->Input, count, FT_UShort ) )
+ goto Fail4;
+
+ i = cpr->Input;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail3;
+
+ for ( n = 0; n < count; n++ )
+ i[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ cpr->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpr->Lookahead = NULL;
+
+ count = cpr->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( cpr->Lookahead, count, FT_UShort ) )
+ goto Fail3;
+
+ l = cpr->Lookahead;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ l[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ cpr->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpr->PosLookupRecord = NULL;
+
+ count = cpr->PosCount;
+
+ if ( ALLOC_ARRAY( cpr->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = cpr->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ FREE( l );
+
+ Fail3:
+ FREE( i );
+
+ Fail4:
+ FREE( b );
+ return error;
+ }
+
+
+ static void Gpos_Free_ChainPosRule( TTO_ChainPosRule* cpr,
+ FT_Memory memory )
+ {
+ FREE( cpr->PosLookupRecord );
+ FREE( cpr->Lookahead );
+ FREE( cpr->Input );
+ FREE( cpr->Backtrack );
+ }
+
+
+ /* ChainPosRuleSet */
+
+ static FT_Error Load_ChainPosRuleSet( TTO_ChainPosRuleSet* cprs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainPosRule* cpr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cprs->ChainPosRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cprs->ChainPosRule = NULL;
+
+ if ( ALLOC_ARRAY( cprs->ChainPosRule, count, TTO_ChainPosRule ) )
+ return error;
+
+ cpr = cprs->ChainPosRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainPosRule( &cpr[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Gpos_Free_ChainPosRule( &cpr[m], memory );
+
+ FREE( cpr );
+ return error;
+ }
+
+
+ static void Gpos_Free_ChainPosRuleSet( TTO_ChainPosRuleSet* cprs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainPosRule* cpr;
+
+
+ if ( cprs->ChainPosRule )
+ {
+ count = cprs->ChainPosRuleCount;
+ cpr = cprs->ChainPosRule;
+
+ for ( n = 0; n < count; n++ )
+ Gpos_Free_ChainPosRule( &cpr[n], memory );
+
+ FREE( cpr );
+ }
+ }
+
+
+ /* ChainContextPosFormat1 */
+
+ static FT_Error Load_ChainContextPos1( TTO_ChainContextPosFormat1* ccpf1,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainPosRuleSet* cprs;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ccpf1->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = ccpf1->ChainPosRuleSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccpf1->ChainPosRuleSet = NULL;
+
+ if ( ALLOC_ARRAY( ccpf1->ChainPosRuleSet, count, TTO_ChainPosRuleSet ) )
+ goto Fail2;
+
+ cprs = ccpf1->ChainPosRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainPosRuleSet( &cprs[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Gpos_Free_ChainPosRuleSet( &cprs[m], memory );
+
+ FREE( cprs );
+
+ Fail2:
+ Free_Coverage( &ccpf1->Coverage, memory );
+ return error;
+ }
+
+
+ static void Gpos_Free_ChainContext1( TTO_ChainContextPosFormat1* ccpf1,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainPosRuleSet* cprs;
+
+
+ if ( ccpf1->ChainPosRuleSet )
+ {
+ count = ccpf1->ChainPosRuleSetCount;
+ cprs = ccpf1->ChainPosRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ Gpos_Free_ChainPosRuleSet( &cprs[n], memory );
+
+ FREE( cprs );
+ }
+
+ Free_Coverage( &ccpf1->Coverage, memory );
+ }
+
+
+ /* ChainPosClassRule */
+
+ static FT_Error Load_ChainPosClassRule(
+ TTO_ChainContextPosFormat2* ccpf2,
+ TTO_ChainPosClassRule* cpcr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* b;
+ FT_UShort* i;
+ FT_UShort* l;
+ TTO_PosLookupRecord* plr;
+ FT_Bool* d;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cpcr->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( cpcr->BacktrackGlyphCount > ccpf2->MaxBacktrackLength )
+ ccpf2->MaxBacktrackLength = cpcr->BacktrackGlyphCount;
+
+ cpcr->Backtrack = NULL;
+
+ count = cpcr->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( cpcr->Backtrack, count, FT_UShort ) )
+ return error;
+
+ b = cpcr->Backtrack;
+ d = ccpf2->BacktrackClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail4;
+
+ for ( n = 0; n < count; n++ )
+ {
+ b[n] = GET_UShort();
+
+ /* We check whether the specific class is used at all. If not,
+ class 0 is used instead. */
+
+ if ( !d[b[n]] )
+ b[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ cpcr->InputGlyphCount = GET_UShort();
+
+ if ( cpcr->InputGlyphCount > ccpf2->MaxInputLength )
+ ccpf2->MaxInputLength = cpcr->InputGlyphCount;
+
+ FORGET_Frame();
+
+ cpcr->Input = NULL;
+
+ count = cpcr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( cpcr->Input, count, FT_UShort ) )
+ goto Fail4;
+
+ i = cpcr->Input;
+ d = ccpf2->InputClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail3;
+
+ for ( n = 0; n < count; n++ )
+ {
+ i[n] = GET_UShort();
+
+ if ( !d[i[n]] )
+ i[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ cpcr->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( cpcr->LookaheadGlyphCount > ccpf2->MaxLookaheadLength )
+ ccpf2->MaxLookaheadLength = cpcr->LookaheadGlyphCount;
+
+ cpcr->Lookahead = NULL;
+
+ count = cpcr->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( cpcr->Lookahead, count, FT_UShort ) )
+ goto Fail3;
+
+ l = cpcr->Lookahead;
+ d = ccpf2->LookaheadClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ {
+ l[n] = GET_UShort();
+
+ if ( !d[l[n]] )
+ l[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ cpcr->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpcr->PosLookupRecord = NULL;
+
+ count = cpcr->PosCount;
+
+ if ( ALLOC_ARRAY( cpcr->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = cpcr->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ FREE( l );
+
+ Fail3:
+ FREE( i );
+
+ Fail4:
+ FREE( b );
+ return error;
+ }
+
+
+ static void Gpos_Free_ChainPosClassRule( TTO_ChainPosClassRule* cpcr,
+ FT_Memory memory )
+ {
+ FREE( cpcr->PosLookupRecord );
+ FREE( cpcr->Lookahead );
+ FREE( cpcr->Input );
+ FREE( cpcr->Backtrack );
+ }
+
+
+ /* PosClassSet */
+
+ static FT_Error Load_ChainPosClassSet(
+ TTO_ChainContextPosFormat2* ccpf2,
+ TTO_ChainPosClassSet* cpcs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainPosClassRule* cpcr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cpcs->ChainPosClassRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cpcs->ChainPosClassRule = NULL;
+
+ if ( ALLOC_ARRAY( cpcs->ChainPosClassRule, count,
+ TTO_ChainPosClassRule ) )
+ return error;
+
+ cpcr = cpcs->ChainPosClassRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainPosClassRule( ccpf2, &cpcr[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Gpos_Free_ChainPosClassRule( &cpcr[m], memory );
+
+ FREE( cpcr );
+ return error;
+ }
+
+
+ static void Gpos_Free_ChainPosClassSet( TTO_ChainPosClassSet* cpcs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainPosClassRule* cpcr;
+
+
+ if ( cpcs->ChainPosClassRule )
+ {
+ count = cpcs->ChainPosClassRuleCount;
+ cpcr = cpcs->ChainPosClassRule;
+
+ for ( n = 0; n < count; n++ )
+ Gpos_Free_ChainPosClassRule( &cpcr[n], memory );
+
+ FREE( cpcr );
+ }
+ }
+
+
+ static FT_Error Gpos_Load_EmptyOrClassDefinition( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_ULong class_offset,
+ FT_ULong base_offset,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_ULong cur_offset;
+
+ cur_offset = FILE_Pos();
+
+ if ( class_offset )
+ {
+ if ( !FILE_Seek( class_offset + base_offset ) )
+ error = Load_ClassDefinition( cd, limit, stream );
+ }
+ else
+ error = Load_EmptyClassDefinition ( cd, stream );
+
+ if (error == TT_Err_Ok)
+ (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */
+
+ return error;
+ }
+
+ /* ChainContextPosFormat2 */
+
+ static FT_Error Load_ChainContextPos2( TTO_ChainContextPosFormat2* ccpf2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+ FT_ULong backtrack_offset, input_offset, lookahead_offset;
+
+ TTO_ChainPosClassSet* cpcs;
+
+
+ base_offset = FILE_Pos() - 2;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ccpf2->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 8L ) )
+ goto Fail5;
+
+ backtrack_offset = GET_UShort();
+ input_offset = GET_UShort();
+ lookahead_offset = GET_UShort();
+
+ /* `ChainPosClassSetCount' is the upper limit for input class values,
+ thus we read it now to make an additional safety check. No limit
+ is known or needed for the other two class definitions */
+
+ count = ccpf2->ChainPosClassSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ( error = Gpos_Load_EmptyOrClassDefinition( &ccpf2->BacktrackClassDef, 65535,
+ backtrack_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail5;
+ if ( ( error = Gpos_Load_EmptyOrClassDefinition( &ccpf2->InputClassDef, count,
+ input_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ if ( ( error = Gpos_Load_EmptyOrClassDefinition( &ccpf2->LookaheadClassDef, 65535,
+ lookahead_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+
+ ccpf2->ChainPosClassSet = NULL;
+ ccpf2->MaxBacktrackLength = 0;
+ ccpf2->MaxInputLength = 0;
+ ccpf2->MaxLookaheadLength = 0;
+
+ if ( ALLOC_ARRAY( ccpf2->ChainPosClassSet, count, TTO_ChainPosClassSet ) )
+ goto Fail2;
+
+ cpcs = ccpf2->ChainPosClassSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ if ( new_offset != base_offset ) /* not a NULL offset */
+ {
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainPosClassSet( ccpf2, &cpcs[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ /* we create a ChainPosClassSet table with no entries */
+
+ ccpf2->ChainPosClassSet[n].ChainPosClassRuleCount = 0;
+ ccpf2->ChainPosClassSet[n].ChainPosClassRule = NULL;
+ }
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Gpos_Free_ChainPosClassSet( &cpcs[m], memory );
+
+ FREE( cpcs );
+
+ Fail2:
+ Free_ClassDefinition( &ccpf2->LookaheadClassDef, memory );
+
+ Fail3:
+ Free_ClassDefinition( &ccpf2->InputClassDef, memory );
+
+ Fail4:
+ Free_ClassDefinition( &ccpf2->BacktrackClassDef, memory );
+
+ Fail5:
+ Free_Coverage( &ccpf2->Coverage, memory );
+ return error;
+ }
+
+
+ static void Gpos_Free_ChainContext2( TTO_ChainContextPosFormat2* ccpf2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainPosClassSet* cpcs;
+
+
+ if ( ccpf2->ChainPosClassSet )
+ {
+ count = ccpf2->ChainPosClassSetCount;
+ cpcs = ccpf2->ChainPosClassSet;
+
+ for ( n = 0; n < count; n++ )
+ Gpos_Free_ChainPosClassSet( &cpcs[n], memory );
+
+ FREE( cpcs );
+ }
+
+ Free_ClassDefinition( &ccpf2->LookaheadClassDef, memory );
+ Free_ClassDefinition( &ccpf2->InputClassDef, memory );
+ Free_ClassDefinition( &ccpf2->BacktrackClassDef, memory );
+
+ Free_Coverage( &ccpf2->Coverage, memory );
+ }
+
+
+ /* ChainContextPosFormat3 */
+
+ static FT_Error Load_ChainContextPos3( TTO_ChainContextPosFormat3* ccpf3,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, nb, ni, nl, m, count;
+ FT_UShort backtrack_count, input_count, lookahead_count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Coverage* b;
+ TTO_Coverage* i;
+ TTO_Coverage* l;
+ TTO_PosLookupRecord* plr;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ ccpf3->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccpf3->BacktrackCoverage = NULL;
+
+ backtrack_count = ccpf3->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( ccpf3->BacktrackCoverage, backtrack_count,
+ TTO_Coverage ) )
+ return error;
+
+ b = ccpf3->BacktrackCoverage;
+
+ for ( nb = 0; nb < backtrack_count; nb++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &b[nb], stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ ccpf3->InputGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccpf3->InputCoverage = NULL;
+
+ input_count = ccpf3->InputGlyphCount;
+
+ if ( ALLOC_ARRAY( ccpf3->InputCoverage, input_count, TTO_Coverage ) )
+ goto Fail4;
+
+ i = ccpf3->InputCoverage;
+
+ for ( ni = 0; ni < input_count; ni++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &i[ni], stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ ccpf3->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccpf3->LookaheadCoverage = NULL;
+
+ lookahead_count = ccpf3->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( ccpf3->LookaheadCoverage, lookahead_count,
+ TTO_Coverage ) )
+ goto Fail3;
+
+ l = ccpf3->LookaheadCoverage;
+
+ for ( nl = 0; nl < lookahead_count; nl++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &l[nl], stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ ccpf3->PosCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccpf3->PosLookupRecord = NULL;
+
+ count = ccpf3->PosCount;
+
+ if ( ALLOC_ARRAY( ccpf3->PosLookupRecord, count, TTO_PosLookupRecord ) )
+ goto Fail2;
+
+ plr = ccpf3->PosLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ plr[n].SequenceIndex = GET_UShort();
+ plr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( plr );
+
+ Fail2:
+ for ( m = 0; m < nl; nl++ )
+ Free_Coverage( &l[m], memory );
+
+ FREE( l );
+
+ Fail3:
+ for ( m = 0; m < ni; n++ )
+ Free_Coverage( &i[m], memory );
+
+ FREE( i );
+
+ Fail4:
+ for ( m = 0; m < nb; n++ )
+ Free_Coverage( &b[m], memory );
+
+ FREE( b );
+ return error;
+ }
+
+
+ static void Gpos_Free_ChainContext3( TTO_ChainContextPosFormat3* ccpf3,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Coverage* c;
+
+
+ FREE( ccpf3->PosLookupRecord );
+
+ if ( ccpf3->LookaheadCoverage )
+ {
+ count = ccpf3->LookaheadGlyphCount;
+ c = ccpf3->LookaheadCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+
+ if ( ccpf3->InputCoverage )
+ {
+ count = ccpf3->InputGlyphCount;
+ c = ccpf3->InputCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+
+ if ( ccpf3->BacktrackCoverage )
+ {
+ count = ccpf3->BacktrackGlyphCount;
+ c = ccpf3->BacktrackCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+ }
+
+
+ /* ChainContextPos */
+
+ FT_Error Load_ChainContextPos( TTO_ChainContextPos* ccp,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ ccp->PosFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( ccp->PosFormat )
+ {
+ case 1:
+ return Load_ChainContextPos1( &ccp->ccpf.ccpf1, stream );
+
+ case 2:
+ return Load_ChainContextPos2( &ccp->ccpf.ccpf2, stream );
+
+ case 3:
+ return Load_ChainContextPos3( &ccp->ccpf.ccpf3, stream );
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ void Free_ChainContextPos( TTO_ChainContextPos* ccp,
+ FT_Memory memory )
+ {
+ switch ( ccp->PosFormat )
+ {
+ case 1:
+ Gpos_Free_ChainContext1( &ccp->ccpf.ccpf1, memory );
+ break;
+
+ case 2:
+ Gpos_Free_ChainContext2( &ccp->ccpf.ccpf2, memory );
+ break;
+
+ case 3:
+ Gpos_Free_ChainContext3( &ccp->ccpf.ccpf3, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Lookup_ChainContextPos1(
+ GPOS_Instance* gpi,
+ TTO_ChainContextPosFormat1* ccpf1,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_UShort i, j, k, num_cpr;
+ FT_UShort bgc, igc, lgc;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_ChainPosRule* cpr;
+ TTO_ChainPosRule curr_cpr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &ccpf1->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ cpr = ccpf1->ChainPosRuleSet[index].ChainPosRule;
+ num_cpr = ccpf1->ChainPosRuleSet[index].ChainPosRuleCount;
+
+ for ( k = 0; k < num_cpr; k++ )
+ {
+ curr_cpr = cpr[k];
+ bgc = curr_cpr.BacktrackGlyphCount;
+ igc = curr_cpr.InputGlyphCount;
+ lgc = curr_cpr.LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ goto next_chainposrule;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length )
+ goto next_chainposrule;
+
+ if ( bgc )
+ {
+ /* Since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array */
+
+ for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + 1 == bgc - i )
+ goto next_chainposrule;
+ j--;
+ }
+
+ /* In OpenType 1.3, it is undefined whether the offsets of
+ backtrack glyphs is in logical order or not. Version 1.4
+ will clarify this:
+
+ Logical order - a b c d e f g h i j
+ i
+ Input offsets - 0 1
+ Backtrack offsets - 3 2 1 0
+ Lookahead offsets - 0 1 2 3 */
+
+ if ( IN_GLYPH( j ) != curr_cpr.Backtrack[i] )
+ goto next_chainposrule;
+ }
+ }
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + igc - i + lgc == (FT_Int)buffer->in_length )
+ goto next_chainposrule;
+ j++;
+ }
+
+ if ( IN_GLYPH( j ) != curr_cpr.Input[i - 1] )
+ goto next_chainposrule;
+ }
+
+ /* we are starting to check for lookahead glyphs right after the
+ last context glyph */
+
+ for ( i = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + lgc - i == (FT_Int)buffer->in_length )
+ goto next_chainposrule;
+ j++;
+ }
+
+ if ( IN_GLYPH( j ) != curr_cpr.Lookahead[i] )
+ goto next_chainposrule;
+ }
+
+ return Do_ContextPos( gpi, igc,
+ curr_cpr.PosCount,
+ curr_cpr.PosLookupRecord,
+ buffer,
+ nesting_level );
+
+ next_chainposrule:
+ ;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Lookup_ChainContextPos2(
+ GPOS_Instance* gpi,
+ TTO_ChainContextPosFormat2* ccpf2,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_Memory memory = gpi->face->memory;
+ FT_Error error;
+ FT_UShort i, j, k;
+ FT_UShort bgc, igc, lgc;
+ FT_UShort known_backtrack_classes,
+ known_input_classes,
+ known_lookahead_classes;
+
+ FT_UShort* backtrack_classes;
+ FT_UShort* input_classes;
+ FT_UShort* lookahead_classes;
+
+ FT_UShort* bc;
+ FT_UShort* ic;
+ FT_UShort* lc;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_ChainPosClassSet* cpcs;
+ TTO_ChainPosClassRule cpcr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ /* Note: The coverage table in format 2 doesn't give an index into
+ anything. It just lets us know whether or not we need to
+ do any lookup at all. */
+
+ error = Coverage_Index( &ccpf2->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ if ( ALLOC_ARRAY( backtrack_classes, ccpf2->MaxBacktrackLength, FT_UShort ) )
+ return error;
+ known_backtrack_classes = 0;
+
+ if ( ALLOC_ARRAY( input_classes, ccpf2->MaxInputLength, FT_UShort ) )
+ goto End3;
+ known_input_classes = 1;
+
+ if ( ALLOC_ARRAY( lookahead_classes, ccpf2->MaxLookaheadLength, FT_UShort ) )
+ goto End2;
+ known_lookahead_classes = 0;
+
+ error = Get_Class( &ccpf2->InputClassDef, IN_CURGLYPH(),
+ &input_classes[0], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ cpcs = &ccpf2->ChainPosClassSet[input_classes[0]];
+ if ( !cpcs )
+ {
+ error = TTO_Err_Invalid_GPOS_SubTable;
+ goto End1;
+ }
+
+ for ( k = 0; k < cpcs->ChainPosClassRuleCount; k++ )
+ {
+ cpcr = cpcs->ChainPosClassRule[k];
+ bgc = cpcr.BacktrackGlyphCount;
+ igc = cpcr.InputGlyphCount;
+ lgc = cpcr.LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ goto next_chainposclassrule;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length )
+ goto next_chainposclassrule;
+
+ if ( bgc )
+ {
+ /* Since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array.
+ Note that `known_backtrack_classes' starts at index 0. */
+
+ bc = cpcr.Backtrack;
+
+ for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( j + 1 == bgc - i )
+ goto next_chainposclassrule;
+ j++;
+ }
+
+ if ( i >= known_backtrack_classes )
+ {
+ /* Keeps us from having to do this for each rule */
+
+ error = Get_Class( &ccpf2->BacktrackClassDef, IN_GLYPH( j ),
+ &backtrack_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_backtrack_classes = i;
+ }
+
+ if ( bc[i] != backtrack_classes[i] )
+ goto next_chainposclassrule;
+ }
+ }
+
+ ic = cpcr.Input;
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( j + igc - i + lgc == (FT_Int)buffer->in_length )
+ goto next_chainposclassrule;
+ j++;
+ }
+
+ if ( i >= known_input_classes )
+ {
+ error = Get_Class( &ccpf2->InputClassDef, IN_GLYPH( j ),
+ &input_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_input_classes = i;
+ }
+
+ if ( ic[i - 1] != input_classes[i] )
+ goto next_chainposclassrule;
+ }
+
+ /* we are starting to check for lookahead glyphs right after the
+ last context glyph */
+
+ lc = cpcr.Lookahead;
+
+ for ( i = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( j + lgc - i == (FT_Int)buffer->in_length )
+ goto next_chainposclassrule;
+ j++;
+ }
+
+ if ( i >= known_lookahead_classes )
+ {
+ error = Get_Class( &ccpf2->LookaheadClassDef, IN_GLYPH( j ),
+ &lookahead_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_lookahead_classes = i;
+ }
+
+ if ( lc[i] != lookahead_classes[i] )
+ goto next_chainposclassrule;
+ }
+
+ error = Do_ContextPos( gpi, igc,
+ cpcr.PosCount,
+ cpcr.PosLookupRecord,
+ buffer,
+ nesting_level );
+ goto End1;
+
+ next_chainposclassrule:
+ ;
+ }
+
+ error = TTO_Err_Not_Covered;
+
+ End1:
+ FREE( lookahead_classes );
+
+ End2:
+ FREE( input_classes );
+
+ End3:
+ FREE( backtrack_classes );
+ return error;
+ }
+
+
+ static FT_Error Lookup_ChainContextPos3(
+ GPOS_Instance* gpi,
+ TTO_ChainContextPosFormat3* ccpf3,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, i, j, property;
+ FT_UShort bgc, igc, lgc;
+ FT_Error error;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ TTO_Coverage* bc;
+ TTO_Coverage* ic;
+ TTO_Coverage* lc;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gpos->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ bgc = ccpf3->BacktrackGlyphCount;
+ igc = ccpf3->InputGlyphCount;
+ lgc = ccpf3->LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ return TTO_Err_Not_Covered;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > buffer->in_pos || buffer->in_pos + igc + lgc > buffer->in_length )
+ return TTO_Err_Not_Covered;
+
+ if ( bgc )
+ {
+ /* Since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array */
+
+ bc = ccpf3->BacktrackCoverage;
+
+ for ( i = 0, j = buffer->in_pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + 1 == bgc - i )
+ return TTO_Err_Not_Covered;
+ j--;
+ }
+
+ error = Coverage_Index( &bc[i], IN_GLYPH( j ), &index );
+ if ( error )
+ return error;
+ }
+ }
+
+ ic = ccpf3->InputCoverage;
+
+ for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ )
+ {
+ /* We already called CHECK_Property for IN_GLYPH ( buffer->in_pos ) */
+ while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + igc - i + lgc == (FT_Int)buffer->in_length )
+ return TTO_Err_Not_Covered;
+ j++;
+ }
+
+ error = Coverage_Index( &ic[i], IN_GLYPH( j ), &index );
+ if ( error )
+ return error;
+ }
+
+ /* we are starting to check for lookahead glyphs right after the
+ last context glyph */
+
+ lc = ccpf3->LookaheadCoverage;
+
+ for ( i = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + lgc - i == (FT_Int)buffer->in_length )
+ return TTO_Err_Not_Covered;
+ j++;
+ }
+
+ error = Coverage_Index( &lc[i], IN_GLYPH( j ), &index );
+ if ( error )
+ return error;
+ }
+
+ return Do_ContextPos( gpi, igc,
+ ccpf3->PosCount,
+ ccpf3->PosLookupRecord,
+ buffer,
+ nesting_level );
+ }
+
+
+ static FT_Error Lookup_ChainContextPos(
+ GPOS_Instance* gpi,
+ TTO_ChainContextPos* ccp,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ switch ( ccp->PosFormat )
+ {
+ case 1:
+ return Lookup_ChainContextPos1( gpi, &ccp->ccpf.ccpf1, buffer,
+ flags, context_length,
+ nesting_level );
+
+ case 2:
+ return Lookup_ChainContextPos2( gpi, &ccp->ccpf.ccpf2, buffer,
+ flags, context_length,
+ nesting_level );
+
+ case 3:
+ return Lookup_ChainContextPos3( gpi, &ccp->ccpf.ccpf3, buffer,
+ flags, context_length,
+ nesting_level );
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+
+ /***********
+ * GPOS API
+ ***********/
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Select_Script( TTO_GPOSHeader* gpos,
+ FT_ULong script_tag,
+ FT_UShort* script_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+
+
+ if ( !gpos || !script_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ for ( n = 0; n < sl->ScriptCount; n++ )
+ if ( script_tag == sr[n].ScriptTag )
+ {
+ *script_index = n;
+
+ return TT_Err_Ok;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Select_Language( TTO_GPOSHeader* gpos,
+ FT_ULong language_tag,
+ FT_UShort script_index,
+ FT_UShort* language_index,
+ FT_UShort* req_feature_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+
+
+ if ( !gpos || !language_index || !req_feature_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ for ( n = 0; n < s->LangSysCount; n++ )
+ if ( language_tag == lsr[n].LangSysTag )
+ {
+ *language_index = n;
+ *req_feature_index = lsr[n].LangSys.ReqFeatureIndex;
+
+ return TT_Err_Ok;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* selecting 0xFFFF for language_index asks for the values of the
+ default language (DefaultLangSys) */
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Select_Feature( TTO_GPOSHeader* gpos,
+ FT_ULong feature_tag,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_UShort* feature_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+ TTO_LangSys* ls;
+ FT_UShort* fi;
+
+ TTO_FeatureList* fl;
+ TTO_FeatureRecord* fr;
+
+
+ if ( !gpos || !feature_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ fl = &gpos->FeatureList;
+ fr = fl->FeatureRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( language_index == 0xFFFF )
+ ls = &s->DefaultLangSys;
+ else
+ {
+ if ( language_index >= s->LangSysCount )
+ return TT_Err_Invalid_Argument;
+
+ ls = &lsr[language_index].LangSys;
+ }
+
+ fi = ls->FeatureIndex;
+
+ for ( n = 0; n < ls->FeatureCount; n++ )
+ {
+ if ( fi[n] >= fl->FeatureCount )
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+
+ if ( feature_tag == fr[fi[n]].FeatureTag )
+ {
+ *feature_index = fi[n];
+
+ return TT_Err_Ok;
+ }
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* The next three functions return a null-terminated list */
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Query_Scripts( TTO_GPOSHeader* gpos,
+ FT_ULong** script_tag_list )
+ {
+ FT_Error error;
+ FT_Memory memory = gpos->memory;
+ FT_UShort n;
+ FT_ULong* stl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+
+
+ if ( !gpos || !script_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < sl->ScriptCount; n++ )
+ stl[n] = sr[n].ScriptTag;
+ stl[n] = 0;
+
+ *script_tag_list = stl;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Query_Languages( TTO_GPOSHeader* gpos,
+ FT_UShort script_index,
+ FT_ULong** language_tag_list )
+ {
+ FT_Error error;
+ FT_Memory memory = gpos->memory;
+ FT_UShort n;
+ FT_ULong* ltl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+
+
+ if ( !gpos || !language_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < s->LangSysCount; n++ )
+ ltl[n] = lsr[n].LangSysTag;
+ ltl[n] = 0;
+
+ *language_tag_list = ltl;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* selecting 0xFFFF for language_index asks for the values of the
+ default language (DefaultLangSys) */
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Query_Features( TTO_GPOSHeader* gpos,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_ULong** feature_tag_list )
+ {
+ FT_UShort n;
+ FT_Error error;
+ FT_Memory memory = gpos->memory;
+ FT_ULong* ftl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+ TTO_LangSys* ls;
+ FT_UShort* fi;
+
+ TTO_FeatureList* fl;
+ TTO_FeatureRecord* fr;
+
+
+ if ( !gpos || !feature_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gpos->ScriptList;
+ sr = sl->ScriptRecord;
+
+ fl = &gpos->FeatureList;
+ fr = fl->FeatureRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( language_index == 0xFFFF )
+ ls = &s->DefaultLangSys;
+ else
+ {
+ if ( language_index >= s->LangSysCount )
+ return TT_Err_Invalid_Argument;
+
+ ls = &lsr[language_index].LangSys;
+ }
+
+ fi = ls->FeatureIndex;
+
+ if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < ls->FeatureCount; n++ )
+ {
+ if ( fi[n] >= fl->FeatureCount )
+ {
+ FREE( ftl );
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+ ftl[n] = fr[fi[n]].FeatureTag;
+ }
+ ftl[n] = 0;
+
+ *feature_tag_list = ftl;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* Do an individual subtable lookup. Returns TT_Err_Ok if positioning
+ has been done, or TTO_Err_Not_Covered if not. */
+
+ static FT_Error GPos_Do_Glyph_Lookup( GPOS_Instance* gpi,
+ FT_UShort lookup_index,
+ OTL_Buffer buffer,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_Error error = TTO_Err_Not_Covered;
+ FT_UShort i, flags, lookup_count;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+ TTO_Lookup* lo;
+
+
+ nesting_level++;
+
+ if ( nesting_level > TTO_MAX_NESTING_LEVEL )
+ return TTO_Err_Too_Many_Nested_Contexts;
+
+ lookup_count = gpos->LookupList.LookupCount;
+ if (lookup_index >= lookup_count)
+ return error;
+
+ lo = &gpos->LookupList.Lookup[lookup_index];
+ flags = lo->LookupFlag;
+
+ for ( i = 0; i < lo->SubTableCount; i++ )
+ {
+ switch ( lo->LookupType )
+ {
+ case GPOS_LOOKUP_SINGLE:
+ error = Lookup_SinglePos( gpi,
+ &lo->SubTable[i].st.gpos.single,
+ buffer,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_PAIR:
+ error = Lookup_PairPos( gpi,
+ &lo->SubTable[i].st.gpos.pair,
+ buffer,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_CURSIVE:
+ error = Lookup_CursivePos( gpi,
+ &lo->SubTable[i].st.gpos.cursive,
+ buffer,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_MARKBASE:
+ error = Lookup_MarkBasePos( gpi,
+ &lo->SubTable[i].st.gpos.markbase,
+ buffer,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_MARKLIG:
+ error = Lookup_MarkLigPos( gpi,
+ &lo->SubTable[i].st.gpos.marklig,
+ buffer,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_MARKMARK:
+ error = Lookup_MarkMarkPos( gpi,
+ &lo->SubTable[i].st.gpos.markmark,
+ buffer,
+ flags, context_length );
+ break;
+
+ case GPOS_LOOKUP_CONTEXT:
+ error = Lookup_ContextPos( gpi,
+ &lo->SubTable[i].st.gpos.context,
+ buffer,
+ flags, context_length,
+ nesting_level );
+ break;
+
+ case GPOS_LOOKUP_CHAIN:
+ error = Lookup_ChainContextPos( gpi,
+ &lo->SubTable[i].st.gpos.chain,
+ buffer,
+ flags, context_length,
+ nesting_level );
+ break;
+ }
+
+ /* Check whether we have a successful positioning or an error other
+ than TTO_Err_Not_Covered */
+
+ if ( error != TTO_Err_Not_Covered )
+ return error;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* apply one lookup to the input string object */
+
+ static FT_Error GPos_Do_String_Lookup( GPOS_Instance* gpi,
+ FT_UShort lookup_index,
+ OTL_Buffer buffer )
+ {
+ FT_Error error, retError = TTO_Err_Not_Covered;
+ TTO_GPOSHeader* gpos = gpi->gpos;
+
+ FT_UInt* properties = gpos->LookupList.Properties;
+
+ int nesting_level = 0;
+
+
+ gpi->last = 0xFFFF; /* no last valid glyph for cursive pos. */
+
+ buffer->in_pos = 0;
+
+ while ( buffer->in_pos < buffer->in_length )
+ {
+ if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] )
+ {
+ /* 0xFFFF indicates that we don't have a context length yet. */
+
+ /* Note that the connection between mark and base glyphs hold
+ exactly one (string) lookup. For example, it would be possible
+ that in the first lookup, mark glyph X is attached to base
+ glyph A, and in the next lookup it is attached to base glyph B.
+ It is up to the font designer to provide meaningful lookups and
+ lookup order. */
+
+ error = GPos_Do_Glyph_Lookup( gpi, lookup_index, buffer,
+ 0xFFFF, nesting_level );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ }
+ else
+ {
+ /* Contrary to properties defined in GDEF, user-defined properties
+ will always stop a possible cursive positioning. */
+ gpi->last = 0xFFFF;
+
+ error = TTO_Err_Not_Covered;
+ }
+
+ if ( error == TTO_Err_Not_Covered )
+ (buffer->in_pos)++;
+ else
+ retError = error;
+ }
+
+ return retError;
+ }
+
+
+ static FT_Error Position_CursiveChain ( OTL_Buffer buffer )
+ {
+ FT_ULong i, j;
+ OTL_Position positions = buffer->positions;
+
+ /* First handle all left-to-right connections */
+ for (j = 0; j < buffer->in_length; j--)
+ {
+ if (positions[j].cursive_chain > 0)
+ positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos;
+ }
+
+ /* Then handle all right-to-left connections */
+ for (i = buffer->in_length; i > 0; i--)
+ {
+ j = i - 1;
+
+ if (positions[j].cursive_chain < 0)
+ positions[j].y_pos += positions[j - positions[j].cursive_chain].y_pos;
+ }
+
+ return TT_Err_Ok;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Add_Feature( TTO_GPOSHeader* gpos,
+ FT_UShort feature_index,
+ FT_UInt property )
+ {
+ FT_UShort i;
+
+ TTO_Feature feature;
+ FT_UInt* properties;
+ FT_UShort* index;
+ FT_UShort lookup_count;
+
+ /* Each feature can only be added once */
+
+ if ( !gpos ||
+ feature_index >= gpos->FeatureList.FeatureCount ||
+ gpos->FeatureList.ApplyCount == gpos->FeatureList.FeatureCount )
+ return TT_Err_Invalid_Argument;
+
+ gpos->FeatureList.ApplyOrder[gpos->FeatureList.ApplyCount++] = feature_index;
+
+ properties = gpos->LookupList.Properties;
+
+ feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
+ index = feature.LookupListIndex;
+ lookup_count = gpos->LookupList.LookupCount;
+
+ for ( i = 0; i < feature.LookupListCount; i++ )
+ {
+ FT_UShort lookup_index = index[i];
+ if (lookup_index < lookup_count)
+ properties[lookup_index] |= property;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Clear_Features( TTO_GPOSHeader* gpos )
+ {
+ FT_UShort i;
+
+ FT_UInt* properties;
+
+
+ if ( !gpos )
+ return TT_Err_Invalid_Argument;
+
+ gpos->FeatureList.ApplyCount = 0;
+
+ properties = gpos->LookupList.Properties;
+
+ for ( i = 0; i < gpos->LookupList.LookupCount; i++ )
+ properties[i] = 0;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Register_Glyph_Function( TTO_GPOSHeader* gpos,
+ TTO_GlyphFunction gfunc )
+ {
+ if ( !gpos )
+ return TT_Err_Invalid_Argument;
+
+ gpos->gfunc = gfunc;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Register_MM_Function( TTO_GPOSHeader* gpos,
+ TTO_MMFunction mmfunc,
+ void* data )
+ {
+ if ( !gpos )
+ return TT_Err_Invalid_Argument;
+
+ gpos->mmfunc = mmfunc;
+ gpos->data = data;
+
+ return TT_Err_Ok;
+ }
+
+ /* If `dvi' is TRUE, glyph contour points for anchor points and tqdevice
+ tables are ignored -- you will get tqdevice independent values. */
+
+ EXPORT_FUNC
+ FT_Error TT_GPOS_Apply_String( FT_Face face,
+ TTO_GPOSHeader* gpos,
+ FT_UShort load_flags,
+ OTL_Buffer buffer,
+ FT_Bool dvi,
+ FT_Bool r2l )
+ {
+ FT_Error error, retError = TTO_Err_Not_Covered;
+ GPOS_Instance gpi;
+ FT_UShort i, j, feature_index, lookup_count;
+ TTO_Feature feature;
+
+ if ( !face || !gpos ||
+ !buffer || buffer->in_length == 0 || buffer->in_pos >= buffer->in_length )
+ return TT_Err_Invalid_Argument;
+
+ gpi.face = face;
+ gpi.gpos = gpos;
+ gpi.load_flags = load_flags;
+ gpi.r2l = r2l;
+ gpi.dvi = dvi;
+
+ lookup_count = gpos->LookupList.LookupCount;
+
+ for ( i = 0; i < gpos->FeatureList.ApplyCount; i++ )
+ {
+ /* index of i'th feature */
+ feature_index = gpos->FeatureList.ApplyOrder[i];
+ feature = gpos->FeatureList.FeatureRecord[feature_index].Feature;
+
+ for ( j = 0; j < feature.LookupListCount; j++ )
+ {
+ FT_UShort lookup_index = feature.LookupListIndex[j];
+
+ /* Skip nonexistant lookups */
+ if (lookup_index >= lookup_count)
+ continue;
+
+ error = GPos_Do_String_Lookup( &gpi, lookup_index, buffer );
+ if ( error )
+ {
+ if ( error != TTO_Err_Not_Covered )
+ return error;
+ }
+ else
+ retError = error;
+ }
+ }
+
+ error = Position_CursiveChain ( buffer );
+ if ( error )
+ return error;
+
+ return retError;
+ }
+
+/* END */
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftxgpos.h b/tqtinterface/qt4/src/3rdparty/opentype/ftxgpos.h
new file mode 100644
index 0000000..1f3821a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftxgpos.h
@@ -0,0 +1,838 @@
+/*******************************************************************
+ *
+ * ftxgpos.h
+ *
+ * TrueType Open GPOS table support
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef FTXOPEN_H
+#error "Don't include this file! Use ftxopen.h instead."
+#endif
+
+#ifndef FTXGPOS_H
+#define FTXGPOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TTO_Err_Invalid_GPOS_SubTable_Format 0x1020
+#define TTO_Err_Invalid_GPOS_SubTable 0x1021
+
+
+/* Lookup types for glyph positioning */
+
+#define GPOS_LOOKUP_SINGLE 1
+#define GPOS_LOOKUP_PAIR 2
+#define GPOS_LOOKUP_CURSIVE 3
+#define GPOS_LOOKUP_MARKBASE 4
+#define GPOS_LOOKUP_MARKLIG 5
+#define GPOS_LOOKUP_MARKMARK 6
+#define GPOS_LOOKUP_CONTEXT 7
+#define GPOS_LOOKUP_CHAIN 8
+#define GPOS_LOOKUP_EXTENSION 9
+
+
+ /* A pointer to a function which loads a glyph. Its parameters are
+ the same as in a call to TT_Load_Glyph() -- if no glyph loading
+ function will be registered with TTO_GPOS_Register_Glyph_Function(),
+ TT_Load_Glyph() will be called indeed. The purpose of this function
+ pointer is to provide a hook for caching glyph outlines and sbits
+ (using the instance's generic pointer to hold the data).
+
+ If for some reason no outline data is available (e.g. for an
+ embedded bitmap glyph), _glyph->outline.n_points should be set to
+ zero. _glyph can be computed with
+
+ _glyph = HANDLE_Glyph( glyph ) */
+
+ typedef FT_Error (*TTO_GlyphFunction)(FT_Face face,
+ FT_UInt glyphIndex,
+ FT_Int loadFlags );
+
+
+ /* A pointer to a function which accesses the PostScript interpreter.
+ Multiple Master fonts need this interface to convert a metric ID
+ (as stored in an OpenType font version 1.2 or higher) `metric_id'
+ into a metric value (returned in `metric_value').
+
+ `data' points to the user-defined structure specified during a
+ call to TT_GPOS_Register_MM_Function().
+
+ `metric_value' must be returned as a scaled value (but shouldn't
+ be rounded). */
+
+ typedef FT_Error (*TTO_MMFunction)(FT_Face face,
+ FT_UShort metric_id,
+ FT_Pos* metric_value,
+ void* data );
+
+
+ struct TTO_GPOSHeader_
+ {
+ FT_Memory memory;
+
+ FT_Fixed Version;
+
+ TTO_ScriptList ScriptList;
+ TTO_FeatureList FeatureList;
+ TTO_LookupList LookupList;
+
+ TTO_GDEFHeader* gdef;
+
+ /* the next field is used for a callback function to get the
+ glyph outline. */
+
+ TTO_GlyphFunction gfunc;
+
+ /* this is OpenType 1.2 -- Multiple Master fonts need this
+ callback function to get various metric values from the
+ PostScript interpreter. */
+
+ TTO_MMFunction mmfunc;
+ void* data;
+ };
+
+ typedef struct TTO_GPOSHeader_ TTO_GPOSHeader;
+ typedef struct TTO_GPOSHeader_* TTO_GPOS;
+
+
+ /* shared tables */
+
+ struct TTO_ValueRecord_
+ {
+ FT_Short XPlacement; /* horizontal adjustment for
+ placement */
+ FT_Short YPlacement; /* vertical adjustment for
+ placement */
+ FT_Short XAdvance; /* horizontal adjustment for
+ advance */
+ FT_Short YAdvance; /* vertical adjustment for
+ advance */
+ TTO_Device XPlacementDevice; /* tqdevice table for horizontal
+ placement */
+ TTO_Device YPlacementDevice; /* tqdevice table for vertical
+ placement */
+ TTO_Device XAdvanceDevice; /* tqdevice table for horizontal
+ advance */
+ TTO_Device YAdvanceDevice; /* tqdevice table for vertical
+ advance */
+ FT_UShort XIdPlacement; /* horizontal placement metric ID */
+ FT_UShort YIdPlacement; /* vertical placement metric ID */
+ FT_UShort XIdAdvance; /* horizontal advance metric ID */
+ FT_UShort YIdAdvance; /* vertical advance metric ID */
+ };
+
+ typedef struct TTO_ValueRecord_ TTO_ValueRecord;
+
+
+/* Mask values to scan the value format of the ValueRecord structure.
+ We always expand compressed ValueRecords of the font. */
+
+#define HAVE_X_PLACEMENT 0x0001
+#define HAVE_Y_PLACEMENT 0x0002
+#define HAVE_X_ADVANCE 0x0004
+#define HAVE_Y_ADVANCE 0x0008
+#define HAVE_X_PLACEMENT_DEVICE 0x0010
+#define HAVE_Y_PLACEMENT_DEVICE 0x0020
+#define HAVE_X_ADVANCE_DEVICE 0x0040
+#define HAVE_Y_ADVANCE_DEVICE 0x0080
+#define HAVE_X_ID_PLACEMENT 0x0100
+#define HAVE_Y_ID_PLACEMENT 0x0200
+#define HAVE_X_ID_ADVANCE 0x0400
+#define HAVE_Y_ID_ADVANCE 0x0800
+
+
+ struct TTO_AnchorFormat1_
+ {
+ FT_Short XCoordinate; /* horizontal value */
+ FT_Short YCoordinate; /* vertical value */
+ };
+
+ typedef struct TTO_AnchorFormat1_ TTO_AnchorFormat1;
+
+
+ struct TTO_AnchorFormat2_
+ {
+ FT_Short XCoordinate; /* horizontal value */
+ FT_Short YCoordinate; /* vertical value */
+ FT_UShort AnchorPoint; /* index to glyph contour point */
+ };
+
+ typedef struct TTO_AnchorFormat2_ TTO_AnchorFormat2;
+
+
+ struct TTO_AnchorFormat3_
+ {
+ FT_Short XCoordinate; /* horizontal value */
+ FT_Short YCoordinate; /* vertical value */
+ TTO_Device XDeviceTable; /* tqdevice table for X coordinate */
+ TTO_Device YDeviceTable; /* tqdevice table for Y coordinate */
+ };
+
+ typedef struct TTO_AnchorFormat3_ TTO_AnchorFormat3;
+
+
+ struct TTO_AnchorFormat4_
+ {
+ FT_UShort XIdAnchor; /* horizontal metric ID */
+ FT_UShort YIdAnchor; /* vertical metric ID */
+ };
+
+ typedef struct TTO_AnchorFormat4_ TTO_AnchorFormat4;
+
+
+ struct TTO_Anchor_
+ {
+ FT_UShort PosFormat; /* 1, 2, 3, or 4 -- 0 indicates
+ that there is no Anchor table */
+
+ union
+ {
+ TTO_AnchorFormat1 af1;
+ TTO_AnchorFormat2 af2;
+ TTO_AnchorFormat3 af3;
+ TTO_AnchorFormat4 af4;
+ } af;
+ };
+
+ typedef struct TTO_Anchor_ TTO_Anchor;
+
+
+ struct TTO_MarkRecord_
+ {
+ FT_UShort Class; /* mark class */
+ TTO_Anchor MarkAnchor; /* anchor table */
+ };
+
+ typedef struct TTO_MarkRecord_ TTO_MarkRecord;
+
+
+ struct TTO_MarkArray_
+ {
+ FT_UShort MarkCount; /* number of MarkRecord tables */
+ TTO_MarkRecord* MarkRecord; /* array of MarkRecord tables */
+ };
+
+ typedef struct TTO_MarkArray_ TTO_MarkArray;
+
+
+ /* LookupType 1 */
+
+ struct TTO_SinglePosFormat1_
+ {
+ TTO_ValueRecord Value; /* ValueRecord for all covered
+ glyphs */
+ };
+
+ typedef struct TTO_SinglePosFormat1_ TTO_SinglePosFormat1;
+
+
+ struct TTO_SinglePosFormat2_
+ {
+ FT_UShort ValueCount; /* number of ValueRecord tables */
+ TTO_ValueRecord* Value; /* array of ValueRecord tables */
+ };
+
+ typedef struct TTO_SinglePosFormat2_ TTO_SinglePosFormat2;
+
+
+ struct TTO_SinglePos_
+ {
+ FT_UShort PosFormat; /* 1 or 2 */
+ TTO_Coverage Coverage; /* Coverage table */
+
+ FT_UShort ValueFormat; /* format of ValueRecord table */
+
+ union
+ {
+ TTO_SinglePosFormat1 spf1;
+ TTO_SinglePosFormat2 spf2;
+ } spf;
+ };
+
+ typedef struct TTO_SinglePos_ TTO_SinglePos;
+
+
+ /* LookupType 2 */
+
+ struct TTO_PairValueRecord_
+ {
+ FT_UShort SecondGlyph; /* glyph ID for second glyph */
+ TTO_ValueRecord Value1; /* pos. data for first glyph */
+ TTO_ValueRecord Value2; /* pos. data for second glyph */
+ };
+
+ typedef struct TTO_PairValueRecord_ TTO_PairValueRecord;
+
+
+ struct TTO_PairSet_
+ {
+ FT_UShort PairValueCount;
+ /* number of PairValueRecord tables */
+ TTO_PairValueRecord* PairValueRecord;
+ /* array of PairValueRecord tables */
+ };
+
+ typedef struct TTO_PairSet_ TTO_PairSet;
+
+
+ struct TTO_PairPosFormat1_
+ {
+ FT_UShort PairSetCount; /* number of PairSet tables */
+ TTO_PairSet* PairSet; /* array of PairSet tables */
+ };
+
+ typedef struct TTO_PairPosFormat1_ TTO_PairPosFormat1;
+
+
+ struct TTO_Class2Record_
+ {
+ TTO_ValueRecord Value1; /* pos. data for first glyph */
+ TTO_ValueRecord Value2; /* pos. data for second glyph */
+ };
+
+ typedef struct TTO_Class2Record_ TTO_Class2Record;
+
+
+ struct TTO_Class1Record_
+ {
+ TTO_Class2Record* Class2Record; /* array of Class2Record tables */
+ };
+
+ typedef struct TTO_Class1Record_ TTO_Class1Record;
+
+
+ struct TTO_PairPosFormat2_
+ {
+ TTO_ClassDefinition ClassDef1; /* class def. for first glyph */
+ TTO_ClassDefinition ClassDef2; /* class def. for second glyph */
+ FT_UShort Class1Count; /* number of classes in ClassDef1
+ table */
+ FT_UShort Class2Count; /* number of classes in ClassDef2
+ table */
+ TTO_Class1Record* Class1Record; /* array of Class1Record tables */
+ };
+
+ typedef struct TTO_PairPosFormat2_ TTO_PairPosFormat2;
+
+
+ struct TTO_PairPos_
+ {
+ FT_UShort PosFormat; /* 1 or 2 */
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort ValueFormat1; /* format of ValueRecord table
+ for first glyph */
+ FT_UShort ValueFormat2; /* format of ValueRecord table
+ for second glyph */
+
+ union
+ {
+ TTO_PairPosFormat1 ppf1;
+ TTO_PairPosFormat2 ppf2;
+ } ppf;
+ };
+
+ typedef struct TTO_PairPos_ TTO_PairPos;
+
+
+ /* LookupType 3 */
+
+ struct TTO_EntryExitRecord_
+ {
+ TTO_Anchor EntryAnchor; /* entry Anchor table */
+ TTO_Anchor ExitAnchor; /* exit Anchor table */
+ };
+
+
+ typedef struct TTO_EntryExitRecord_ TTO_EntryExitRecord;
+
+ struct TTO_CursivePos_
+ {
+ FT_UShort PosFormat; /* always 1 */
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort EntryExitCount;
+ /* number of EntryExitRecord tables */
+ TTO_EntryExitRecord* EntryExitRecord;
+ /* array of EntryExitRecord tables */
+ };
+
+ typedef struct TTO_CursivePos_ TTO_CursivePos;
+
+
+ /* LookupType 4 */
+
+ struct TTO_BaseRecord_
+ {
+ TTO_Anchor* BaseAnchor; /* array of base glyph anchor
+ tables */
+ };
+
+ typedef struct TTO_BaseRecord_ TTO_BaseRecord;
+
+
+ struct TTO_BaseArray_
+ {
+ FT_UShort BaseCount; /* number of BaseRecord tables */
+ TTO_BaseRecord* BaseRecord; /* array of BaseRecord tables */
+ };
+
+ typedef struct TTO_BaseArray_ TTO_BaseArray;
+
+
+ struct TTO_MarkBasePos_
+ {
+ FT_UShort PosFormat; /* always 1 */
+ TTO_Coverage MarkCoverage; /* mark glyph coverage table */
+ TTO_Coverage BaseCoverage; /* base glyph coverage table */
+ FT_UShort ClassCount; /* number of mark classes */
+ TTO_MarkArray MarkArray; /* mark array table */
+ TTO_BaseArray BaseArray; /* base array table */
+ };
+
+ typedef struct TTO_MarkBasePos_ TTO_MarkBasePos;
+
+
+ /* LookupType 5 */
+
+ struct TTO_ComponentRecord_
+ {
+ TTO_Anchor* LigatureAnchor; /* array of ligature glyph anchor
+ tables */
+ };
+
+ typedef struct TTO_ComponentRecord_ TTO_ComponentRecord;
+
+
+ struct TTO_LigatureAttach_
+ {
+ FT_UShort ComponentCount;
+ /* number of ComponentRecord tables */
+ TTO_ComponentRecord* ComponentRecord;
+ /* array of ComponentRecord tables */
+ };
+
+ typedef struct TTO_LigatureAttach_ TTO_LigatureAttach;
+
+
+ struct TTO_LigatureArray_
+ {
+ FT_UShort LigatureCount; /* number of LigatureAttach tables */
+ TTO_LigatureAttach* LigatureAttach;
+ /* array of LigatureAttach tables */
+ };
+
+ typedef struct TTO_LigatureArray_ TTO_LigatureArray;
+
+
+ struct TTO_MarkLigPos_
+ {
+ FT_UShort PosFormat; /* always 1 */
+ TTO_Coverage MarkCoverage; /* mark glyph coverage table */
+ TTO_Coverage LigatureCoverage;
+ /* ligature glyph coverage table */
+ FT_UShort ClassCount; /* number of mark classes */
+ TTO_MarkArray MarkArray; /* mark array table */
+ TTO_LigatureArray LigatureArray; /* ligature array table */
+ };
+
+ typedef struct TTO_MarkLigPos_ TTO_MarkLigPos;
+
+
+ /* LookupType 6 */
+
+ struct TTO_Mark2Record_
+ {
+ TTO_Anchor* Mark2Anchor; /* array of mark glyph anchor
+ tables */
+ };
+
+ typedef struct TTO_Mark2Record_ TTO_Mark2Record;
+
+
+ struct TTO_Mark2Array_
+ {
+ FT_UShort Mark2Count; /* number of Mark2Record tables */
+ TTO_Mark2Record* Mark2Record; /* array of Mark2Record tables */
+ };
+
+ typedef struct TTO_Mark2Array_ TTO_Mark2Array;
+
+
+ struct TTO_MarkMarkPos_
+ {
+ FT_UShort PosFormat; /* always 1 */
+ TTO_Coverage Mark1Coverage; /* first mark glyph coverage table */
+ TTO_Coverage Mark2Coverage; /* second mark glyph coverave table */
+ FT_UShort ClassCount; /* number of combining mark classes */
+ TTO_MarkArray Mark1Array; /* MarkArray table for first mark */
+ TTO_Mark2Array Mark2Array; /* MarkArray table for second mark */
+ };
+
+ typedef struct TTO_MarkMarkPos_ TTO_MarkMarkPos;
+
+
+ /* needed by both lookup type 7 and 8 */
+
+ struct TTO_PosLookupRecord_
+ {
+ FT_UShort SequenceIndex; /* index into current
+ glyph sequence */
+ FT_UShort LookupListIndex; /* Lookup to apply to that pos. */
+ };
+
+ typedef struct TTO_PosLookupRecord_ TTO_PosLookupRecord;
+
+
+ /* LookupType 7 */
+
+ struct TTO_PosRule_
+ {
+ FT_UShort GlyphCount; /* total number of input glyphs */
+ FT_UShort PosCount; /* number of PosLookupRecord tables */
+ FT_UShort* Input; /* array of input glyph IDs */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of PosLookupRecord tables */
+ };
+
+ typedef struct TTO_PosRule_ TTO_PosRule;
+
+
+ struct TTO_PosRuleSet_
+ {
+ FT_UShort PosRuleCount; /* number of PosRule tables */
+ TTO_PosRule* PosRule; /* array of PosRule tables */
+ };
+
+ typedef struct TTO_PosRuleSet_ TTO_PosRuleSet;
+
+
+ struct TTO_ContextPosFormat1_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort PosRuleSetCount; /* number of PosRuleSet tables */
+ TTO_PosRuleSet* PosRuleSet; /* array of PosRuleSet tables */
+ };
+
+ typedef struct TTO_ContextPosFormat1_ TTO_ContextPosFormat1;
+
+
+ struct TTO_PosClassRule_
+ {
+ FT_UShort GlyphCount; /* total number of context classes */
+ FT_UShort PosCount; /* number of PosLookupRecord tables */
+ FT_UShort* Class; /* array of classes */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of PosLookupRecord tables */
+ };
+
+ typedef struct TTO_PosClassRule_ TTO_PosClassRule;
+
+
+ struct TTO_PosClassSet_
+ {
+ FT_UShort PosClassRuleCount;
+ /* number of PosClassRule tables */
+ TTO_PosClassRule* PosClassRule; /* array of PosClassRule tables */
+ };
+
+ typedef struct TTO_PosClassSet_ TTO_PosClassSet;
+
+
+ /* The `MaxContextLength' field is not defined in the TTO specification
+ but simplifies the implementation of this format. It holds the
+ maximal context length used in the context rules. */
+
+ struct TTO_ContextPosFormat2_
+ {
+ FT_UShort MaxContextLength;
+ /* maximal context length */
+ TTO_Coverage Coverage; /* Coverage table */
+ TTO_ClassDefinition ClassDef; /* ClassDef table */
+ FT_UShort PosClassSetCount;
+ /* number of PosClassSet tables */
+ TTO_PosClassSet* PosClassSet; /* array of PosClassSet tables */
+ };
+
+ typedef struct TTO_ContextPosFormat2_ TTO_ContextPosFormat2;
+
+
+ struct TTO_ContextPosFormat3_
+ {
+ FT_UShort GlyphCount; /* number of input glyphs */
+ FT_UShort PosCount; /* number of PosLookupRecord tables */
+ TTO_Coverage* Coverage; /* array of Coverage tables */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of PosLookupRecord tables */
+ };
+
+ typedef struct TTO_ContextPosFormat3_ TTO_ContextPosFormat3;
+
+
+ struct TTO_ContextPos_
+ {
+ FT_UShort PosFormat; /* 1, 2, or 3 */
+
+ union
+ {
+ TTO_ContextPosFormat1 cpf1;
+ TTO_ContextPosFormat2 cpf2;
+ TTO_ContextPosFormat3 cpf3;
+ } cpf;
+ };
+
+ typedef struct TTO_ContextPos_ TTO_ContextPos;
+
+
+ /* LookupType 8 */
+
+ struct TTO_ChainPosRule_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* total number of backtrack glyphs */
+ FT_UShort* Backtrack; /* array of backtrack glyph IDs */
+ FT_UShort InputGlyphCount;
+ /* total number of input glyphs */
+ FT_UShort* Input; /* array of input glyph IDs */
+ FT_UShort LookaheadGlyphCount;
+ /* total number of lookahead glyphs */
+ FT_UShort* Lookahead; /* array of lookahead glyph IDs */
+ FT_UShort PosCount; /* number of PosLookupRecords */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of PosLookupRecords */
+ };
+
+ typedef struct TTO_ChainPosRule_ TTO_ChainPosRule;
+
+
+ struct TTO_ChainPosRuleSet_
+ {
+ FT_UShort ChainPosRuleCount;
+ /* number of ChainPosRule tables */
+ TTO_ChainPosRule* ChainPosRule; /* array of ChainPosRule tables */
+ };
+
+ typedef struct TTO_ChainPosRuleSet_ TTO_ChainPosRuleSet;
+
+
+ struct TTO_ChainContextPosFormat1_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort ChainPosRuleSetCount;
+ /* number of ChainPosRuleSet tables */
+ TTO_ChainPosRuleSet* ChainPosRuleSet;
+ /* array of ChainPosRuleSet tables */
+ };
+
+ typedef struct TTO_ChainContextPosFormat1_ TTO_ChainContextPosFormat1;
+
+
+ struct TTO_ChainPosClassRule_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* total number of backtrack
+ classes */
+ FT_UShort* Backtrack; /* array of backtrack classes */
+ FT_UShort InputGlyphCount;
+ /* total number of context classes */
+ FT_UShort* Input; /* array of context classes */
+ FT_UShort LookaheadGlyphCount;
+ /* total number of lookahead
+ classes */
+ FT_UShort* Lookahead; /* array of lookahead classes */
+ FT_UShort PosCount; /* number of PosLookupRecords */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of substitution lookups */
+ };
+
+ typedef struct TTO_ChainPosClassRule_ TTO_ChainPosClassRule;
+
+
+ struct TTO_ChainPosClassSet_
+ {
+ FT_UShort ChainPosClassRuleCount;
+ /* number of ChainPosClassRule
+ tables */
+ TTO_ChainPosClassRule* ChainPosClassRule;
+ /* array of ChainPosClassRule
+ tables */
+ };
+
+ typedef struct TTO_ChainPosClassSet_ TTO_ChainPosClassSet;
+
+
+ /* The `MaxXXXLength' fields are not defined in the TTO specification
+ but simplifies the implementation of this format. It holds the
+ maximal context length used in the specific context rules. */
+
+ struct TTO_ChainContextPosFormat2_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+
+ FT_UShort MaxBacktrackLength;
+ /* maximal backtrack length */
+ TTO_ClassDefinition BacktrackClassDef;
+ /* BacktrackClassDef table */
+ FT_UShort MaxInputLength;
+ /* maximal input length */
+ TTO_ClassDefinition InputClassDef;
+ /* InputClassDef table */
+ FT_UShort MaxLookaheadLength;
+ /* maximal lookahead length */
+ TTO_ClassDefinition LookaheadClassDef;
+ /* LookaheadClassDef table */
+
+ FT_UShort ChainPosClassSetCount;
+ /* number of ChainPosClassSet
+ tables */
+ TTO_ChainPosClassSet* ChainPosClassSet;
+ /* array of ChainPosClassSet
+ tables */
+ };
+
+ typedef struct TTO_ChainContextPosFormat2_ TTO_ChainContextPosFormat2;
+
+
+ struct TTO_ChainContextPosFormat3_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* number of backtrack glyphs */
+ TTO_Coverage* BacktrackCoverage;
+ /* array of backtrack Coverage
+ tables */
+ FT_UShort InputGlyphCount;
+ /* number of input glyphs */
+ TTO_Coverage* InputCoverage;
+ /* array of input coverage
+ tables */
+ FT_UShort LookaheadGlyphCount;
+ /* number of lookahead glyphs */
+ TTO_Coverage* LookaheadCoverage;
+ /* array of lookahead coverage
+ tables */
+ FT_UShort PosCount; /* number of PosLookupRecords */
+ TTO_PosLookupRecord* PosLookupRecord;
+ /* array of substitution lookups */
+ };
+
+ typedef struct TTO_ChainContextPosFormat3_ TTO_ChainContextPosFormat3;
+
+
+ struct TTO_ChainContextPos_
+ {
+ FT_UShort PosFormat; /* 1, 2, or 3 */
+
+ union
+ {
+ TTO_ChainContextPosFormat1 ccpf1;
+ TTO_ChainContextPosFormat2 ccpf2;
+ TTO_ChainContextPosFormat3 ccpf3;
+ } ccpf;
+ };
+
+ typedef struct TTO_ChainContextPos_ TTO_ChainContextPos;
+
+
+ union TTO_GPOS_SubTable_
+ {
+ TTO_SinglePos single;
+ TTO_PairPos pair;
+ TTO_CursivePos cursive;
+ TTO_MarkBasePos markbase;
+ TTO_MarkLigPos marklig;
+ TTO_MarkMarkPos markmark;
+ TTO_ContextPos context;
+ TTO_ChainContextPos chain;
+ };
+
+ typedef union TTO_GPOS_SubTable_ TTO_GPOS_SubTable;
+
+
+ /* finally, the GPOS API */
+
+ /* EXPORT_DEF
+ FT_Export ( FT_Error ) TT_Init_GPOS_Extension( TT_Engine engine ); */
+
+ EXPORT_DEF
+ FT_Error TT_Load_GPOS_Table( FT_Face face,
+ TTO_GPOSHeader** gpos,
+ TTO_GDEFHeader* gdef );
+
+ EXPORT_DEF
+ FT_Error TT_Done_GPOS_Table( TTO_GPOSHeader* gpos );
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Select_Script( TTO_GPOSHeader* gpos,
+ FT_ULong script_tag,
+ FT_UShort* script_index );
+ EXPORT_DEF
+ FT_Error TT_GPOS_Select_Language( TTO_GPOSHeader* gpos,
+ FT_ULong language_tag,
+ FT_UShort script_index,
+ FT_UShort* language_index,
+ FT_UShort* req_feature_index );
+ EXPORT_DEF
+ FT_Error TT_GPOS_Select_Feature( TTO_GPOSHeader* gpos,
+ FT_ULong feature_tag,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_UShort* feature_index );
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Query_Scripts( TTO_GPOSHeader* gpos,
+ FT_ULong** script_tag_list );
+ EXPORT_DEF
+ FT_Error TT_GPOS_Query_Languages( TTO_GPOSHeader* gpos,
+ FT_UShort script_index,
+ FT_ULong** language_tag_list );
+ EXPORT_DEF
+ FT_Error TT_GPOS_Query_Features( TTO_GPOSHeader* gpos,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_ULong** feature_tag_list );
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Add_Feature( TTO_GPOSHeader* gpos,
+ FT_UShort feature_index,
+ FT_UInt property );
+ EXPORT_DEF
+ FT_Error TT_GPOS_Clear_Features( TTO_GPOSHeader* gpos );
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Register_Glyph_Function( TTO_GPOSHeader* gpos,
+ TTO_GlyphFunction gfunc );
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Register_MM_Function( TTO_GPOSHeader* gpos,
+ TTO_MMFunction mmfunc,
+ void* data );
+
+ /* If `dvi' is TRUE, glyph contour points for anchor points and tqdevice
+ tables are ignored -- you will get tqdevice independent values. */
+
+ EXPORT_DEF
+ FT_Error TT_GPOS_Apply_String( FT_Face face,
+ TTO_GPOSHeader* gpos,
+ FT_UShort load_flags,
+ OTL_Buffer buffer,
+ FT_Bool dvi,
+ FT_Bool r2l );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FTXGPOS_H */
+
+
+/* END */
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftxgsub.c b/tqtinterface/qt4/src/3rdparty/opentype/ftxgsub.c
new file mode 100644
index 0000000..6d4ff0c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftxgsub.c
@@ -0,0 +1,4156 @@
+/*******************************************************************
+ *
+ * ftxgsub.c
+ *
+ * TrueType Open GSUB table support.
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+/* XXX There is *a lot* of duplicated code (cf. formats 5 and 6), but
+ I don't care currently. I believe that it would be possible to
+ save about 50% of TTO code by carefully designing the structures,
+ sharing as much as possible with extensive use of macros. This
+ is something for a volunteer :-) */
+
+#define EXPORT_FUNC
+
+#include "ftxopen.h"
+#include "ftxopenf.h"
+
+#include "ftglue.h"
+
+#include FT_TRUETYPE_TAGS_H
+
+#define GSUB_ID Build_Extension_ID( 'G', 'S', 'U', 'B' )
+
+
+ static FT_Error GSub_Do_Glyph_Lookup( TTO_GSUBHeader* gsub,
+ FT_UShort lookup_index,
+ OTL_Buffer buffer,
+ FT_UShort context_length,
+ int nesting_level );
+
+
+
+ /**********************
+ * Auxiliary functions
+ **********************/
+
+
+ EXPORT_FUNC
+ FT_Error TT_Load_GSUB_Table( FT_Face face,
+ TTO_GSUBHeader** retptr,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_Stream stream = face->stream;
+ FT_Memory memory = face->memory;
+ FT_Error error;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ FT_UShort i, num_lookups;
+ TTO_GSUBHeader* gsub;
+ TTO_Lookup* lo;
+
+ if ( !retptr )
+ return TT_Err_Invalid_Argument;
+
+ if (( error = ftglue_face_goto_table( face, TTAG_GSUB, stream ) ))
+ return error;
+
+ base_offset = FILE_Pos();
+
+ if ( ALLOC ( gsub, sizeof( *gsub ) ) )
+ return error;
+
+ gsub->memory = memory;
+
+ /* skip version */
+
+ if ( FILE_Seek( base_offset + 4L ) ||
+ ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ScriptList( &gsub->ScriptList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_FeatureList( &gsub->FeatureList,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LookupList( &gsub->LookupList,
+ stream, GSUB ) ) != TT_Err_Ok )
+ goto Fail2;
+
+ gsub->gdef = gdef; /* can be NULL */
+
+ /* We now check the LookupFlags for values larger than 0xFF to tqfind
+ out whether we need to load the `MarkAttachClassDef' field of the
+ GDEF table -- this hack is necessary for OpenType 1.2 tables since
+ the version field of the GDEF table hasn't been incremented.
+
+ For constructed GDEF tables, we only load it if
+ `MarkAttachClassDef_offset' is not zero (nevertheless, a build of
+ a constructed mark attach table is not supported currently). */
+
+ if ( gdef &&
+ gdef->MarkAttachClassDef_offset && !gdef->MarkAttachClassDef.loaded )
+ {
+ lo = gsub->LookupList.Lookup;
+ num_lookups = gsub->LookupList.LookupCount;
+
+ for ( i = 0; i < num_lookups; i++ )
+ {
+
+ if ( lo[i].LookupFlag & IGNORE_SPECIAL_MARKS )
+ {
+ if ( FILE_Seek( gdef->MarkAttachClassDef_offset ) ||
+ ( error = Load_ClassDefinition( &gdef->MarkAttachClassDef,
+ 256, stream ) ) != TT_Err_Ok )
+ goto Fail1;
+
+ break;
+ }
+ }
+ }
+
+ *retptr = gsub;
+
+ return TT_Err_Ok;
+
+ Fail1:
+ Free_LookupList( &gsub->LookupList, GSUB, memory );
+
+ Fail2:
+ Free_FeatureList( &gsub->FeatureList, memory );
+
+ Fail3:
+ Free_ScriptList( &gsub->ScriptList, memory );
+
+ Fail4:
+ FREE ( gsub );
+
+
+ return error;
+ }
+
+ EXPORT_FUNC
+ FT_Error TT_Done_GSUB_Table( TTO_GSUBHeader* gsub )
+ {
+ FT_Memory memory = gsub->memory;
+
+ Free_LookupList( &gsub->LookupList, GSUB, memory );
+ Free_FeatureList( &gsub->FeatureList, memory );
+ Free_ScriptList( &gsub->ScriptList, memory );
+
+ FREE( gsub );
+
+ return TT_Err_Ok;
+ }
+
+ /*****************************
+ * SubTable related functions
+ *****************************/
+
+
+ /* LookupType 1 */
+
+ /* SingleSubstFormat1 */
+ /* SingleSubstFormat2 */
+
+ FT_Error Load_SingleSubst( TTO_SingleSubst* ss,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ FT_UShort* s;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ ss->SubstFormat = GET_UShort();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ss->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ switch ( ss->SubstFormat )
+ {
+ case 1:
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ ss->ssf.ssf1.DeltaGlyphID = GET_UShort();
+
+ FORGET_Frame();
+
+ break;
+
+ case 2:
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = ss->ssf.ssf2.GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ss->ssf.ssf2.Substitute = NULL;
+
+ if ( ALLOC_ARRAY( ss->ssf.ssf2.Substitute, count, FT_UShort ) )
+ goto Fail2;
+
+ s = ss->ssf.ssf2.Substitute;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ s[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ break;
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( s );
+
+ Fail2:
+ Free_Coverage( &ss->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_SingleSubst( TTO_SingleSubst* ss,
+ FT_Memory memory )
+ {
+ switch ( ss->SubstFormat )
+ {
+ case 1:
+ break;
+
+ case 2:
+ FREE( ss->ssf.ssf2.Substitute );
+ break;
+ }
+
+ Free_Coverage( &ss->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_SingleSubst( TTO_SingleSubst* ss,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_UShort index, value, property;
+ FT_Error error;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &ss->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ switch ( ss->SubstFormat )
+ {
+ case 1:
+ value = ( IN_CURGLYPH() + ss->ssf.ssf1.DeltaGlyphID ) & 0xFFFF;
+ if ( ADD_Glyph( buffer, value, 0xFFFF, 0xFFFF ) )
+ return error;
+ break;
+
+ case 2:
+ if ( index >= ss->ssf.ssf2.GlyphCount )
+ return TTO_Err_Invalid_GSUB_SubTable;
+ value = ss->ssf.ssf2.Substitute[index];
+ if ( ADD_Glyph( buffer, value, 0xFFFF, 0xFFFF ) )
+ return error;
+ break;
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable;
+ }
+
+ if ( gdef && gdef->NewGlyphClasses )
+ {
+ /* we inherit the old glyph class to the substituted glyph */
+
+ error = Add_Glyph_Property( gdef, value, property );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 2 */
+
+ /* Sequence */
+
+ static FT_Error Load_Sequence( TTO_Sequence* s,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* sub;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = s->GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ s->Substitute = NULL;
+
+ if ( count )
+ {
+ if ( ALLOC_ARRAY( s->Substitute, count, FT_UShort ) )
+ return error;
+
+ sub = s->Substitute;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( sub );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ sub[n] = GET_UShort();
+
+ FORGET_Frame();
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_Sequence( TTO_Sequence* s,
+ FT_Memory memory )
+ {
+ FREE( s->Substitute );
+ }
+
+
+ /* MultipleSubstFormat1 */
+
+ FT_Error Load_MultipleSubst( TTO_MultipleSubst* ms,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Sequence* s;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ ms->SubstFormat = GET_UShort(); /* should be 1 */
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ms->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = ms->SequenceCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ms->Sequence = NULL;
+
+ if ( ALLOC_ARRAY( ms->Sequence, count, TTO_Sequence ) )
+ goto Fail2;
+
+ s = ms->Sequence;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Sequence( &s[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_Sequence( &s[m], memory );
+
+ FREE( s );
+
+ Fail2:
+ Free_Coverage( &ms->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_MultipleSubst( TTO_MultipleSubst* ms,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Sequence* s;
+
+
+ if ( ms->Sequence )
+ {
+ count = ms->SequenceCount;
+ s = ms->Sequence;
+
+ for ( n = 0; n < count; n++ )
+ Free_Sequence( &s[n], memory );
+
+ FREE( s );
+ }
+
+ Free_Coverage( &ms->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_MultipleSubst( TTO_MultipleSubst* ms,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_Error error;
+ FT_UShort index, property, n, count;
+ FT_UShort*s;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &ms->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ if ( index >= ms->SequenceCount )
+ return TTO_Err_Invalid_GSUB_SubTable;
+
+ count = ms->Sequence[index].GlyphCount;
+ s = ms->Sequence[index].Substitute;
+
+ if ( ADD_String( buffer, 1, count, s, 0xFFFF, 0xFFFF ) )
+ return error;
+
+ if ( gdef && gdef->NewGlyphClasses )
+ {
+ /* this is a guess only ... */
+
+ if ( property == TTO_LIGATURE )
+ property = TTO_BASE_GLYPH;
+
+ for ( n = 0; n < count; n++ )
+ {
+ error = Add_Glyph_Property( gdef, s[n], property );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ }
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 3 */
+
+ /* AlternateSet */
+
+ static FT_Error Load_AlternateSet( TTO_AlternateSet* as,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* a;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = as->GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ as->Alternate = NULL;
+
+ if ( ALLOC_ARRAY( as->Alternate, count, FT_UShort ) )
+ return error;
+
+ a = as->Alternate;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( a );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ a[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_AlternateSet( TTO_AlternateSet* as,
+ FT_Memory memory )
+ {
+ FREE( as->Alternate );
+ }
+
+
+ /* AlternateSubstFormat1 */
+
+ FT_Error Load_AlternateSubst( TTO_AlternateSubst* as,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_AlternateSet* aset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ as->SubstFormat = GET_UShort(); /* should be 1 */
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &as->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = as->AlternateSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ as->AlternateSet = NULL;
+
+ if ( ALLOC_ARRAY( as->AlternateSet, count, TTO_AlternateSet ) )
+ goto Fail2;
+
+ aset = as->AlternateSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_AlternateSet( &aset[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_AlternateSet( &aset[m], memory );
+
+ FREE( aset );
+
+ Fail2:
+ Free_Coverage( &as->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_AlternateSubst( TTO_AlternateSubst* as,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_AlternateSet* aset;
+
+
+ if ( as->AlternateSet )
+ {
+ count = as->AlternateSetCount;
+ aset = as->AlternateSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_AlternateSet( &aset[n], memory );
+
+ FREE( aset );
+ }
+
+ Free_Coverage( &as->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_AlternateSubst( TTO_GSUBHeader* gsub,
+ TTO_AlternateSubst* as,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_Error error;
+ FT_UShort index, alt_index, property;
+
+ TTO_AlternateSet aset;
+
+
+ if ( context_length != 0xFFFF && context_length < 1 )
+ return TTO_Err_Not_Covered;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &as->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ aset = as->AlternateSet[index];
+
+ /* we use a user-defined callback function to get the alternate index */
+
+ if ( gsub->altfunc )
+ alt_index = (gsub->altfunc)( buffer->out_pos, IN_CURGLYPH(),
+ aset.GlyphCount, aset.Alternate,
+ gsub->data );
+ else
+ alt_index = 0;
+
+ if ( ADD_Glyph( buffer, aset.Alternate[alt_index],
+ 0xFFFF, 0xFFFF ) )
+ return error;
+
+ if ( gdef && gdef->NewGlyphClasses )
+ {
+ /* we inherit the old glyph class to the substituted glyph */
+
+ error = Add_Glyph_Property( gdef, aset.Alternate[alt_index],
+ property );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 4 */
+
+ /* Ligature */
+
+ static FT_Error Load_Ligature( TTO_Ligature* l,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* c;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ l->LigGlyph = GET_UShort();
+ l->ComponentCount = GET_UShort();
+
+ FORGET_Frame();
+
+ l->Component = NULL;
+
+ count = l->ComponentCount - 1; /* only ComponentCount - 1 elements */
+
+ if ( ALLOC_ARRAY( l->Component, count, FT_UShort ) )
+ return error;
+
+ c = l->Component;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( c );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ c[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_Ligature( TTO_Ligature* l,
+ FT_Memory memory )
+ {
+ FREE( l->Component );
+ }
+
+
+ /* LigatureSet */
+
+ static FT_Error Load_LigatureSet( TTO_LigatureSet* ls,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Ligature* l;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ls->LigatureCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ls->Ligature = NULL;
+
+ if ( ALLOC_ARRAY( ls->Ligature, count, TTO_Ligature ) )
+ return error;
+
+ l = ls->Ligature;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Ligature( &l[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_Ligature( &l[m], memory );
+
+ FREE( l );
+ return error;
+ }
+
+
+ static void Free_LigatureSet( TTO_LigatureSet* ls,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Ligature* l;
+
+
+ if ( ls->Ligature )
+ {
+ count = ls->LigatureCount;
+ l = ls->Ligature;
+
+ for ( n = 0; n < count; n++ )
+ Free_Ligature( &l[n], memory );
+
+ FREE( l );
+ }
+ }
+
+
+ /* LigatureSubstFormat1 */
+
+ FT_Error Load_LigatureSubst( TTO_LigatureSubst* ls,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_LigatureSet* lset;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ ls->SubstFormat = GET_UShort(); /* should be 1 */
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ls->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = ls->LigatureSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ls->LigatureSet = NULL;
+
+ if ( ALLOC_ARRAY( ls->LigatureSet, count, TTO_LigatureSet ) )
+ goto Fail2;
+
+ lset = ls->LigatureSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LigatureSet( &lset[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_LigatureSet( &lset[m], memory );
+
+ FREE( lset );
+
+ Fail2:
+ Free_Coverage( &ls->Coverage, memory );
+ return error;
+ }
+
+
+ void Free_LigatureSubst( TTO_LigatureSubst* ls,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_LigatureSet* lset;
+
+
+ if ( ls->LigatureSet )
+ {
+ count = ls->LigatureSetCount;
+ lset = ls->LigatureSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_LigatureSet( &lset[n], memory );
+
+ FREE( lset );
+ }
+
+ Free_Coverage( &ls->Coverage, memory );
+ }
+
+
+ static FT_Error Lookup_LigatureSubst( TTO_LigatureSubst* ls,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ TTO_GDEFHeader* gdef )
+ {
+ FT_UShort index, property;
+ FT_Error error;
+ FT_UShort numlig, i, j, is_mark, first_is_mark = FALSE;
+ FT_UShort* c;
+
+ TTO_Ligature* lig;
+
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ if ( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS )
+ first_is_mark = TRUE;
+
+ error = Coverage_Index( &ls->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ if ( index >= ls->LigatureSetCount )
+ return TTO_Err_Invalid_GSUB_SubTable;
+
+ lig = ls->LigatureSet[index].Ligature;
+
+ for ( numlig = ls->LigatureSet[index].LigatureCount;
+ numlig;
+ numlig--, lig++ )
+ {
+ if ( buffer->in_pos + lig->ComponentCount > buffer->in_length )
+ goto next_ligature; /* Not enough glyphs in input */
+
+ c = lig->Component;
+
+ is_mark = first_is_mark;
+
+ if ( context_length != 0xFFFF && context_length < lig->ComponentCount )
+ break;
+
+ for ( i = 1, j = buffer->in_pos + 1; i < lig->ComponentCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + lig->ComponentCount - i == (FT_Int)buffer->in_length )
+ goto next_ligature;
+ j++;
+ }
+
+ if ( !( property == TTO_MARK || property & IGNORE_SPECIAL_MARKS ) )
+ is_mark = FALSE;
+
+ if ( IN_GLYPH( j ) != c[i - 1] )
+ goto next_ligature;
+ }
+
+ if ( gdef && gdef->NewGlyphClasses )
+ {
+ /* this is just a guess ... */
+
+ error = Add_Glyph_Property( gdef, lig->LigGlyph,
+ is_mark ? TTO_MARK : TTO_LIGATURE );
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+ }
+
+ if ( j == buffer->in_pos + i ) /* No input glyphs skipped */
+ {
+ /* We don't use a new ligature ID if there are no skipped
+ glyphs and the ligature already has an ID. */
+
+ if ( IN_LIGID( buffer->in_pos ) )
+ {
+ if ( ADD_String( buffer, i, 1, &lig->LigGlyph,
+ 0xFFFF, 0xFFFF ) )
+ return error;
+ }
+ else
+ {
+ FT_UShort ligID = otl_buffer_allocate_ligid( buffer );
+ if ( ADD_String( buffer, i, 1, &lig->LigGlyph,
+ 0xFFFF, ligID ) )
+ return error;
+ }
+ }
+ else
+ {
+ FT_UShort ligID = otl_buffer_allocate_ligid( buffer );
+ if ( ADD_Glyph( buffer, lig->LigGlyph,
+ 0xFFFF, ligID ) )
+ return error;
+
+ /* Now we must do a second loop to copy the skipped glyphs to
+ `out' and assign component values to it. We start with the
+ glyph after the first component. Glyphs between component
+ i and i+1 belong to component i. Together with the ligID
+ value it is later possible to check whether a specific
+ component value really belongs to a given ligature. */
+
+ for ( i = 0; i < lig->ComponentCount - 1; i++ )
+ {
+ while ( CHECK_Property( gdef, IN_CURITEM(),
+ flags, &property ) )
+ if ( ADD_Glyph( buffer, IN_CURGLYPH(),
+ i, ligID ) )
+ return error;
+
+ (buffer->in_pos)++;
+ }
+ }
+
+ return TT_Err_Ok;
+
+ next_ligature:
+ ;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* Do the actual substitution for a context substitution (either format
+ 5 or 6). This is only called after we've determined that the input
+ matches the subrule. */
+
+ static FT_Error Do_ContextSubst( TTO_GSUBHeader* gsub,
+ FT_UShort GlyphCount,
+ FT_UShort SubstCount,
+ TTO_SubstLookupRecord* subst,
+ OTL_Buffer buffer,
+ int nesting_level )
+ {
+ FT_Error error;
+ FT_UShort i, old_pos;
+
+
+ i = 0;
+
+ while ( i < GlyphCount )
+ {
+ if ( SubstCount && i == subst->SequenceIndex )
+ {
+ old_pos = buffer->in_pos;
+
+ /* Do a substitution */
+
+ error = GSub_Do_Glyph_Lookup( gsub, subst->LookupListIndex, buffer,
+ GlyphCount, nesting_level );
+
+ subst++;
+ SubstCount--;
+ i += buffer->in_pos - old_pos;
+
+ if ( error == TTO_Err_Not_Covered )
+ {
+ /* XXX "can't happen" -- but don't count on it */
+
+ if ( ADD_Glyph( buffer, IN_CURGLYPH(),
+ 0xFFFF, 0xFFFF ) )
+ return error;
+ i++;
+ }
+ else if ( error )
+ return error;
+ }
+ else
+ {
+ /* No substitution for this index */
+
+ if ( ADD_Glyph( buffer, IN_CURGLYPH(),
+ 0xFFFF, 0xFFFF ) )
+ return error;
+ i++;
+ }
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ /* LookupType 5 */
+
+ /* SubRule */
+
+ static FT_Error Load_SubRule( TTO_SubRule* sr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* i;
+
+ TTO_SubstLookupRecord* slr;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ sr->GlyphCount = GET_UShort();
+ sr->SubstCount = GET_UShort();
+
+ FORGET_Frame();
+
+ sr->Input = NULL;
+
+ count = sr->GlyphCount - 1; /* only GlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( sr->Input, count, FT_UShort ) )
+ return error;
+
+ i = sr->Input;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ i[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ sr->SubstLookupRecord = NULL;
+
+ count = sr->SubstCount;
+
+ if ( ALLOC_ARRAY( sr->SubstLookupRecord, count, TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = sr->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ FREE( i );
+ return error;
+ }
+
+
+ static void Free_SubRule( TTO_SubRule* sr,
+ FT_Memory memory )
+ {
+ FREE( sr->SubstLookupRecord );
+ FREE( sr->Input );
+ }
+
+
+ /* SubRuleSet */
+
+ static FT_Error Load_SubRuleSet( TTO_SubRuleSet* srs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_SubRule* sr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = srs->SubRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ srs->SubRule = NULL;
+
+ if ( ALLOC_ARRAY( srs->SubRule, count, TTO_SubRule ) )
+ return error;
+
+ sr = srs->SubRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_SubRule( &sr[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_SubRule( &sr[m], memory );
+
+ FREE( sr );
+ return error;
+ }
+
+
+ static void Free_SubRuleSet( TTO_SubRuleSet* srs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_SubRule* sr;
+
+
+ if ( srs->SubRule )
+ {
+ count = srs->SubRuleCount;
+ sr = srs->SubRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_SubRule( &sr[n], memory );
+
+ FREE( sr );
+ }
+ }
+
+
+ /* ContextSubstFormat1 */
+
+ static FT_Error Load_ContextSubst1( TTO_ContextSubstFormat1* csf1,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_SubRuleSet* srs;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &csf1->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = csf1->SubRuleSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csf1->SubRuleSet = NULL;
+
+ if ( ALLOC_ARRAY( csf1->SubRuleSet, count, TTO_SubRuleSet ) )
+ goto Fail2;
+
+ srs = csf1->SubRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_SubRuleSet( &srs[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_SubRuleSet( &srs[m], memory );
+
+ FREE( srs );
+
+ Fail2:
+ Free_Coverage( &csf1->Coverage, memory );
+ return error;
+ }
+
+
+ static void Gsub_Free_Context1( TTO_ContextSubstFormat1* csf1,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_SubRuleSet* srs;
+
+
+ if ( csf1->SubRuleSet )
+ {
+ count = csf1->SubRuleSetCount;
+ srs = csf1->SubRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_SubRuleSet( &srs[n], memory );
+
+ FREE( srs );
+ }
+
+ Free_Coverage( &csf1->Coverage, memory );
+ }
+
+
+ /* SubClassRule */
+
+ static FT_Error Load_SubClassRule( TTO_ContextSubstFormat2* csf2,
+ TTO_SubClassRule* scr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* c;
+ TTO_SubstLookupRecord* slr;
+ FT_Bool* d;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ scr->GlyphCount = GET_UShort();
+ scr->SubstCount = GET_UShort();
+
+ if ( scr->GlyphCount > csf2->MaxContextLength )
+ csf2->MaxContextLength = scr->GlyphCount;
+
+ FORGET_Frame();
+
+ scr->Class = NULL;
+
+ count = scr->GlyphCount - 1; /* only GlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( scr->Class, count, FT_UShort ) )
+ return error;
+
+ c = scr->Class;
+ d = csf2->ClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ {
+ c[n] = GET_UShort();
+
+ /* We check whether the specific class is used at all. If not,
+ class 0 is used instead. */
+ if ( !d[c[n]] )
+ c[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ scr->SubstLookupRecord = NULL;
+
+ count = scr->SubstCount;
+
+ if ( ALLOC_ARRAY( scr->SubstLookupRecord, count, TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = scr->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ FREE( c );
+ return error;
+ }
+
+
+ static void Free_SubClassRule( TTO_SubClassRule* scr,
+ FT_Memory memory )
+ {
+ FREE( scr->SubstLookupRecord );
+ FREE( scr->Class );
+ }
+
+
+ /* SubClassSet */
+
+ static FT_Error Load_SubClassSet( TTO_ContextSubstFormat2* csf2,
+ TTO_SubClassSet* scs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_SubClassRule* scr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = scs->SubClassRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ scs->SubClassRule = NULL;
+
+ if ( ALLOC_ARRAY( scs->SubClassRule, count, TTO_SubClassRule ) )
+ return error;
+
+ scr = scs->SubClassRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_SubClassRule( csf2, &scr[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_SubClassRule( &scr[m], memory );
+
+ FREE( scr );
+ return error;
+ }
+
+
+ static void Free_SubClassSet( TTO_SubClassSet* scs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_SubClassRule* scr;
+
+
+ if ( scs->SubClassRule )
+ {
+ count = scs->SubClassRuleCount;
+ scr = scs->SubClassRule;
+
+ for ( n = 0; n < count; n++ )
+ Free_SubClassRule( &scr[n], memory );
+
+ FREE( scr );
+ }
+ }
+
+
+ /* ContextSubstFormat2 */
+
+ static FT_Error Load_ContextSubst2( TTO_ContextSubstFormat2* csf2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_SubClassSet* scs;
+
+
+ base_offset = FILE_Pos() - 2;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &csf2->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 4L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ /* `SubClassSetCount' is the upper limit for class values, thus we
+ read it now to make an additional safety check. */
+
+ count = csf2->SubClassSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ClassDefinition( &csf2->ClassDef, count,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+
+ csf2->SubClassSet = NULL;
+ csf2->MaxContextLength = 0;
+
+ if ( ALLOC_ARRAY( csf2->SubClassSet, count, TTO_SubClassSet ) )
+ goto Fail2;
+
+ scs = csf2->SubClassSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ if ( new_offset != base_offset ) /* not a NULL offset */
+ {
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_SubClassSet( csf2, &scs[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ /* we create a SubClassSet table with no entries */
+
+ csf2->SubClassSet[n].SubClassRuleCount = 0;
+ csf2->SubClassSet[n].SubClassRule = NULL;
+ }
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_SubClassSet( &scs[m], memory );
+
+ FREE( scs );
+
+ Fail2:
+ Free_ClassDefinition( &csf2->ClassDef, memory );
+
+ Fail3:
+ Free_Coverage( &csf2->Coverage, memory );
+ return error;
+ }
+
+
+ static void Gsub_Free_Context2( TTO_ContextSubstFormat2* csf2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_SubClassSet* scs;
+
+
+ if ( csf2->SubClassSet )
+ {
+ count = csf2->SubClassSetCount;
+ scs = csf2->SubClassSet;
+
+ for ( n = 0; n < count; n++ )
+ Free_SubClassSet( &scs[n], memory );
+
+ FREE( scs );
+ }
+
+ Free_ClassDefinition( &csf2->ClassDef, memory );
+ Free_Coverage( &csf2->Coverage, memory );
+ }
+
+
+ /* ContextSubstFormat3 */
+
+ static FT_Error Load_ContextSubst3( TTO_ContextSubstFormat3* csf3,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Coverage* c;
+ TTO_SubstLookupRecord* slr;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ csf3->GlyphCount = GET_UShort();
+ csf3->SubstCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csf3->Coverage = NULL;
+
+ count = csf3->GlyphCount;
+
+ if ( ALLOC_ARRAY( csf3->Coverage, count, TTO_Coverage ) )
+ return error;
+
+ c = csf3->Coverage;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &c[n], stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ csf3->SubstLookupRecord = NULL;
+
+ count = csf3->SubstCount;
+
+ if ( ALLOC_ARRAY( csf3->SubstLookupRecord, count,
+ TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = csf3->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ for ( m = 0; m < n; m++ )
+ Free_Coverage( &c[m], memory );
+
+ FREE( c );
+ return error;
+ }
+
+
+ static void Gsub_Free_Context3( TTO_ContextSubstFormat3* csf3,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Coverage* c;
+
+
+ FREE( csf3->SubstLookupRecord );
+
+ if ( csf3->Coverage )
+ {
+ count = csf3->GlyphCount;
+ c = csf3->Coverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+ }
+
+
+ /* ContextSubst */
+
+ FT_Error Load_ContextSubst( TTO_ContextSubst* cs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cs->SubstFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( cs->SubstFormat )
+ {
+ case 1:
+ return Load_ContextSubst1( &cs->csf.csf1, stream );
+
+ case 2:
+ return Load_ContextSubst2( &cs->csf.csf2, stream );
+
+ case 3:
+ return Load_ContextSubst3( &cs->csf.csf3, stream );
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ void Free_ContextSubst( TTO_ContextSubst* cs,
+ FT_Memory memory )
+ {
+ switch ( cs->SubstFormat )
+ {
+ case 1:
+ Gsub_Free_Context1( &cs->csf.csf1, memory );
+ break;
+
+ case 2:
+ Gsub_Free_Context2( &cs->csf.csf2, memory );
+ break;
+
+ case 3:
+ Gsub_Free_Context3( &cs->csf.csf3, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Lookup_ContextSubst1(
+ TTO_GSUBHeader* gsub,
+ TTO_ContextSubstFormat1* csf1,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_UShort i, j, k, numsr;
+ FT_Error error;
+
+ TTO_SubRule* sr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &csf1->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ sr = csf1->SubRuleSet[index].SubRule;
+ numsr = csf1->SubRuleSet[index].SubRuleCount;
+
+ for ( k = 0; k < numsr; k++ )
+ {
+ if ( context_length != 0xFFFF && context_length < sr[k].GlyphCount )
+ goto next_subrule;
+
+ if ( buffer->in_pos + sr[k].GlyphCount > buffer->in_length )
+ goto next_subrule; /* context is too long */
+
+ for ( i = 1, j = buffer->in_pos + 1; i < sr[k].GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + sr[k].GlyphCount - i == (FT_Int)buffer->in_length )
+ goto next_subrule;
+ j++;
+ }
+
+ if ( IN_GLYPH( j ) != sr[k].Input[i - 1] )
+ goto next_subrule;
+ }
+
+ return Do_ContextSubst( gsub, sr[k].GlyphCount,
+ sr[k].SubstCount, sr[k].SubstLookupRecord,
+ buffer,
+ nesting_level );
+ next_subrule:
+ ;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Lookup_ContextSubst2(
+ TTO_GSUBHeader* gsub,
+ TTO_ContextSubstFormat2* csf2,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_Error error;
+ FT_Memory memory = gsub->memory;
+ FT_UShort i, j, k, known_classes;
+
+ FT_UShort* classes;
+ FT_UShort* cl;
+
+ TTO_SubClassSet* scs;
+ TTO_SubClassRule* sr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ /* Note: The coverage table in format 2 doesn't give an index into
+ anything. It just lets us know whether or not we need to
+ do any lookup at all. */
+
+ error = Coverage_Index( &csf2->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ if ( ALLOC_ARRAY( classes, csf2->MaxContextLength, FT_UShort ) )
+ return error;
+
+ error = Get_Class( &csf2->ClassDef, IN_CURGLYPH(),
+ &classes[0], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+ known_classes = 0;
+
+ scs = &csf2->SubClassSet[classes[0]];
+ if ( !scs )
+ {
+ error = TTO_Err_Invalid_GSUB_SubTable;
+ goto End;
+ }
+
+ for ( k = 0; k < scs->SubClassRuleCount; k++ )
+ {
+ sr = &scs->SubClassRule[k];
+
+ if ( context_length != 0xFFFF && context_length < sr->GlyphCount )
+ goto next_subclassrule;
+
+ if ( buffer->in_pos + sr->GlyphCount > buffer->in_length )
+ goto next_subclassrule; /* context is too long */
+
+ cl = sr->Class;
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = buffer->in_pos + 1; i < sr->GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+
+ if ( j + sr->GlyphCount - i < (FT_Int)buffer->in_length )
+ goto next_subclassrule;
+ j++;
+ }
+
+ if ( i > known_classes )
+ {
+ /* Keeps us from having to do this for each rule */
+
+ error = Get_Class( &csf2->ClassDef, IN_GLYPH( j ), &classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End;
+ known_classes = i;
+ }
+
+ if ( cl[i - 1] != classes[i] )
+ goto next_subclassrule;
+ }
+
+ error = Do_ContextSubst( gsub, sr->GlyphCount,
+ sr->SubstCount, sr->SubstLookupRecord,
+ buffer,
+ nesting_level );
+ goto End;
+
+ next_subclassrule:
+ ;
+ }
+
+ error = TTO_Err_Not_Covered;
+
+ End:
+ FREE( classes );
+ return error;
+ }
+
+
+ static FT_Error Lookup_ContextSubst3(
+ TTO_GSUBHeader* gsub,
+ TTO_ContextSubstFormat3* csf3,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_Error error;
+ FT_UShort index, i, j, property;
+
+ TTO_Coverage* c;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ if ( context_length != 0xFFFF && context_length < csf3->GlyphCount )
+ return TTO_Err_Not_Covered;
+
+ if ( buffer->in_pos + csf3->GlyphCount > buffer->in_length )
+ return TTO_Err_Not_Covered; /* context is too long */
+
+ c = csf3->Coverage;
+
+ for ( i = 1, j = buffer->in_pos + 1; i < csf3->GlyphCount; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + csf3->GlyphCount - i == (FT_Int)buffer->in_length )
+ return TTO_Err_Not_Covered;
+ j++;
+ }
+
+ error = Coverage_Index( &c[i], IN_GLYPH( j ), &index );
+ if ( error )
+ return error;
+ }
+
+ return Do_ContextSubst( gsub, csf3->GlyphCount,
+ csf3->SubstCount, csf3->SubstLookupRecord,
+ buffer,
+ nesting_level );
+ }
+
+
+ static FT_Error Lookup_ContextSubst( TTO_GSUBHeader* gsub,
+ TTO_ContextSubst* cs,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ switch ( cs->SubstFormat )
+ {
+ case 1:
+ return Lookup_ContextSubst1( gsub, &cs->csf.csf1, buffer,
+ flags, context_length, nesting_level );
+
+ case 2:
+ return Lookup_ContextSubst2( gsub, &cs->csf.csf2, buffer,
+ flags, context_length, nesting_level );
+
+ case 3:
+ return Lookup_ContextSubst3( gsub, &cs->csf.csf3, buffer,
+ flags, context_length, nesting_level );
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ /* LookupType 6 */
+
+ /* ChainSubRule */
+
+ static FT_Error Load_ChainSubRule( TTO_ChainSubRule* csr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+ FT_UShort* b;
+ FT_UShort* i;
+ FT_UShort* l;
+
+ TTO_SubstLookupRecord* slr;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ csr->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csr->Backtrack = NULL;
+
+ count = csr->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( csr->Backtrack, count, FT_UShort ) )
+ return error;
+
+ b = csr->Backtrack;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail4;
+
+ for ( n = 0; n < count; n++ )
+ b[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ csr->InputGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csr->Input = NULL;
+
+ count = csr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( csr->Input, count, FT_UShort ) )
+ goto Fail4;
+
+ i = csr->Input;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail3;
+
+ for ( n = 0; n < count; n++ )
+ i[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ csr->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csr->Lookahead = NULL;
+
+ count = csr->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( csr->Lookahead, count, FT_UShort ) )
+ goto Fail3;
+
+ l = csr->Lookahead;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ l[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ csr->SubstCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csr->SubstLookupRecord = NULL;
+
+ count = csr->SubstCount;
+
+ if ( ALLOC_ARRAY( csr->SubstLookupRecord, count, TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = csr->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ FREE( l );
+
+ Fail3:
+ FREE( i );
+
+ Fail4:
+ FREE( b );
+ return error;
+ }
+
+
+ static void Gsub_Free_ChainSubRule( TTO_ChainSubRule* csr,
+ FT_Memory memory )
+ {
+ FREE( csr->SubstLookupRecord );
+ FREE( csr->Lookahead );
+ FREE( csr->Input );
+ FREE( csr->Backtrack );
+ }
+
+
+ /* ChainSubRuleSet */
+
+ static FT_Error Load_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainSubRule* csr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = csrs->ChainSubRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ csrs->ChainSubRule = NULL;
+
+ if ( ALLOC_ARRAY( csrs->ChainSubRule, count, TTO_ChainSubRule ) )
+ return error;
+
+ csr = csrs->ChainSubRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainSubRule( &csr[n], stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Gsub_Free_ChainSubRule( &csr[m], memory );
+
+ FREE( csr );
+ return error;
+ }
+
+
+ static void Gsub_Free_ChainSubRuleSet( TTO_ChainSubRuleSet* csrs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainSubRule* csr;
+
+
+ if ( csrs->ChainSubRule )
+ {
+ count = csrs->ChainSubRuleCount;
+ csr = csrs->ChainSubRule;
+
+ for ( n = 0; n < count; n++ )
+ Gsub_Free_ChainSubRule( &csr[n], memory );
+
+ FREE( csr );
+ }
+ }
+
+
+ /* ChainContextSubstFormat1 */
+
+ static FT_Error Load_ChainContextSubst1(
+ TTO_ChainContextSubstFormat1* ccsf1,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainSubRuleSet* csrs;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ccsf1->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = ccsf1->ChainSubRuleSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccsf1->ChainSubRuleSet = NULL;
+
+ if ( ALLOC_ARRAY( ccsf1->ChainSubRuleSet, count, TTO_ChainSubRuleSet ) )
+ goto Fail2;
+
+ csrs = ccsf1->ChainSubRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainSubRuleSet( &csrs[n], stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Gsub_Free_ChainSubRuleSet( &csrs[m], memory );
+
+ FREE( csrs );
+
+ Fail2:
+ Free_Coverage( &ccsf1->Coverage, memory );
+ return error;
+ }
+
+
+ static void Gsub_Free_ChainContext1( TTO_ChainContextSubstFormat1* ccsf1,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainSubRuleSet* csrs;
+
+
+ if ( ccsf1->ChainSubRuleSet )
+ {
+ count = ccsf1->ChainSubRuleSetCount;
+ csrs = ccsf1->ChainSubRuleSet;
+
+ for ( n = 0; n < count; n++ )
+ Gsub_Free_ChainSubRuleSet( &csrs[n], memory );
+
+ FREE( csrs );
+ }
+
+ Free_Coverage( &ccsf1->Coverage, memory );
+ }
+
+
+ /* ChainSubClassRule */
+
+ static FT_Error Load_ChainSubClassRule(
+ TTO_ChainContextSubstFormat2* ccsf2,
+ TTO_ChainSubClassRule* cscr,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* b;
+ FT_UShort* i;
+ FT_UShort* l;
+ TTO_SubstLookupRecord* slr;
+ FT_Bool* d;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ cscr->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( cscr->BacktrackGlyphCount > ccsf2->MaxBacktrackLength )
+ ccsf2->MaxBacktrackLength = cscr->BacktrackGlyphCount;
+
+ cscr->Backtrack = NULL;
+
+ count = cscr->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( cscr->Backtrack, count, FT_UShort ) )
+ return error;
+
+ b = cscr->Backtrack;
+ d = ccsf2->BacktrackClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail4;
+
+ for ( n = 0; n < count; n++ )
+ {
+ b[n] = GET_UShort();
+
+ /* We check whether the specific class is used at all. If not,
+ class 0 is used instead. */
+
+ if ( !d[b[n]] )
+ b[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ cscr->InputGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( cscr->InputGlyphCount > ccsf2->MaxInputLength )
+ ccsf2->MaxInputLength = cscr->InputGlyphCount;
+
+ cscr->Input = NULL;
+
+ count = cscr->InputGlyphCount - 1; /* only InputGlyphCount - 1 elements */
+
+ if ( ALLOC_ARRAY( cscr->Input, count, FT_UShort ) )
+ goto Fail4;
+
+ i = cscr->Input;
+ d = ccsf2->InputClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail3;
+
+ for ( n = 0; n < count; n++ )
+ {
+ i[n] = GET_UShort();
+
+ if ( !d[i[n]] )
+ i[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ cscr->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( cscr->LookaheadGlyphCount > ccsf2->MaxLookaheadLength )
+ ccsf2->MaxLookaheadLength = cscr->LookaheadGlyphCount;
+
+ cscr->Lookahead = NULL;
+
+ count = cscr->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( cscr->Lookahead, count, FT_UShort ) )
+ goto Fail3;
+
+ l = cscr->Lookahead;
+ d = ccsf2->LookaheadClassDef.Defined;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail2;
+
+ for ( n = 0; n < count; n++ )
+ {
+ l[n] = GET_UShort();
+
+ if ( !d[l[n]] )
+ l[n] = 0;
+ }
+
+ FORGET_Frame();
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ cscr->SubstCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cscr->SubstLookupRecord = NULL;
+
+ count = cscr->SubstCount;
+
+ if ( ALLOC_ARRAY( cscr->SubstLookupRecord, count,
+ TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = cscr->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ FREE( l );
+
+ Fail3:
+ FREE( i );
+
+ Fail4:
+ FREE( b );
+ return error;
+ }
+
+
+ static void Gsub_Free_ChainSubClassRule( TTO_ChainSubClassRule* cscr,
+ FT_Memory memory )
+ {
+ FREE( cscr->SubstLookupRecord );
+ FREE( cscr->Lookahead );
+ FREE( cscr->Input );
+ FREE( cscr->Backtrack );
+ }
+
+
+ /* SubClassSet */
+
+ static FT_Error Load_ChainSubClassSet(
+ TTO_ChainContextSubstFormat2* ccsf2,
+ TTO_ChainSubClassSet* cscs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ChainSubClassRule* cscr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cscs->ChainSubClassRuleCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cscs->ChainSubClassRule = NULL;
+
+ if ( ALLOC_ARRAY( cscs->ChainSubClassRule, count,
+ TTO_ChainSubClassRule ) )
+ return error;
+
+ cscr = cscs->ChainSubClassRule;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainSubClassRule( ccsf2, &cscr[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Gsub_Free_ChainSubClassRule( &cscr[m], memory );
+
+ FREE( cscr );
+ return error;
+ }
+
+
+ static void Gsub_Free_ChainSubClassSet( TTO_ChainSubClassSet* cscs,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainSubClassRule* cscr;
+
+
+ if ( cscs->ChainSubClassRule )
+ {
+ count = cscs->ChainSubClassRuleCount;
+ cscr = cscs->ChainSubClassRule;
+
+ for ( n = 0; n < count; n++ )
+ Gsub_Free_ChainSubClassRule( &cscr[n], memory );
+
+ FREE( cscr );
+ }
+ }
+
+ static FT_Error Gsub_Load_EmptyOrClassDefinition( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_ULong class_offset,
+ FT_ULong base_offset,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_ULong cur_offset;
+
+ cur_offset = FILE_Pos();
+
+ if ( class_offset )
+ {
+ if ( !FILE_Seek( class_offset + base_offset ) )
+ error = Load_ClassDefinition( cd, limit, stream );
+ }
+ else
+ error = Load_EmptyClassDefinition ( cd, stream );
+
+ if (error == TT_Err_Ok)
+ (void)FILE_Seek( cur_offset ); /* Changes error as a side-effect */
+
+ return error;
+ }
+
+
+ /* ChainContextSubstFormat2 */
+
+ static FT_Error Load_ChainContextSubst2(
+ TTO_ChainContextSubstFormat2* ccsf2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n = 0, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+ FT_ULong backtrack_offset, input_offset, lookahead_offset;
+
+ TTO_ChainSubClassSet* cscs;
+
+
+ base_offset = FILE_Pos() - 2;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &ccsf2->Coverage, stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+
+ if ( ACCESS_Frame( 8L ) )
+ goto Fail5;
+
+ backtrack_offset = GET_UShort();
+ input_offset = GET_UShort();
+ lookahead_offset = GET_UShort();
+
+ /* `ChainSubClassSetCount' is the upper limit for input class values,
+ thus we read it now to make an additional safety check. No limit
+ is known or needed for the other two class definitions */
+
+ count = ccsf2->ChainSubClassSetCount = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( ( error = Gsub_Load_EmptyOrClassDefinition( &ccsf2->BacktrackClassDef, 65535,
+ backtrack_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail5;
+
+ if ( ( error = Gsub_Load_EmptyOrClassDefinition( &ccsf2->InputClassDef, count,
+ input_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ if ( ( error = Gsub_Load_EmptyOrClassDefinition( &ccsf2->LookaheadClassDef, 65535,
+ lookahead_offset, base_offset,
+ stream ) ) != TT_Err_Ok )
+ goto Fail3;
+
+ ccsf2->ChainSubClassSet = NULL;
+ ccsf2->MaxBacktrackLength = 0;
+ ccsf2->MaxInputLength = 0;
+ ccsf2->MaxLookaheadLength = 0;
+
+ if ( ALLOC_ARRAY( ccsf2->ChainSubClassSet, count, TTO_ChainSubClassSet ) )
+ goto Fail2;
+
+ cscs = ccsf2->ChainSubClassSet;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ if ( new_offset != base_offset ) /* not a NULL offset */
+ {
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_ChainSubClassSet( ccsf2, &cscs[n],
+ stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ /* we create a ChainSubClassSet table with no entries */
+
+ ccsf2->ChainSubClassSet[n].ChainSubClassRuleCount = 0;
+ ccsf2->ChainSubClassSet[n].ChainSubClassRule = NULL;
+ }
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Gsub_Free_ChainSubClassSet( &cscs[m], memory );
+
+ FREE( cscs );
+
+ Fail2:
+ Free_ClassDefinition( &ccsf2->LookaheadClassDef, memory );
+
+ Fail3:
+ Free_ClassDefinition( &ccsf2->InputClassDef, memory );
+
+ Fail4:
+ Free_ClassDefinition( &ccsf2->BacktrackClassDef, memory );
+
+ Fail5:
+ Free_Coverage( &ccsf2->Coverage, memory );
+ return error;
+ }
+
+
+ static void Gsub_Free_ChainContext2( TTO_ChainContextSubstFormat2* ccsf2,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ChainSubClassSet* cscs;
+
+
+ if ( ccsf2->ChainSubClassSet )
+ {
+ count = ccsf2->ChainSubClassSetCount;
+ cscs = ccsf2->ChainSubClassSet;
+
+ for ( n = 0; n < count; n++ )
+ Gsub_Free_ChainSubClassSet( &cscs[n], memory );
+
+ FREE( cscs );
+ }
+
+ Free_ClassDefinition( &ccsf2->LookaheadClassDef, memory );
+ Free_ClassDefinition( &ccsf2->InputClassDef, memory );
+ Free_ClassDefinition( &ccsf2->BacktrackClassDef, memory );
+
+ Free_Coverage( &ccsf2->Coverage, memory );
+ }
+
+
+ /* ChainContextSubstFormat3 */
+
+ static FT_Error Load_ChainContextSubst3(
+ TTO_ChainContextSubstFormat3* ccsf3,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, nb = 0, ni =0, nl = 0, m, count;
+ FT_UShort backtrack_count, input_count, lookahead_count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Coverage* b;
+ TTO_Coverage* i;
+ TTO_Coverage* l;
+ TTO_SubstLookupRecord* slr;
+
+
+ base_offset = FILE_Pos() - 2L;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ ccsf3->BacktrackGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccsf3->BacktrackCoverage = NULL;
+
+ backtrack_count = ccsf3->BacktrackGlyphCount;
+
+ if ( ALLOC_ARRAY( ccsf3->BacktrackCoverage, backtrack_count,
+ TTO_Coverage ) )
+ return error;
+
+ b = ccsf3->BacktrackCoverage;
+
+ for ( nb = 0; nb < backtrack_count; nb++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &b[nb], stream ) ) != TT_Err_Ok )
+ goto Fail4;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail4;
+
+ ccsf3->InputGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccsf3->InputCoverage = NULL;
+
+ input_count = ccsf3->InputGlyphCount;
+
+ if ( ALLOC_ARRAY( ccsf3->InputCoverage, input_count, TTO_Coverage ) )
+ goto Fail4;
+
+ i = ccsf3->InputCoverage;
+
+ for ( ni = 0; ni < input_count; ni++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &i[ni], stream ) ) != TT_Err_Ok )
+ goto Fail3;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail3;
+
+ ccsf3->LookaheadGlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccsf3->LookaheadCoverage = NULL;
+
+ lookahead_count = ccsf3->LookaheadGlyphCount;
+
+ if ( ALLOC_ARRAY( ccsf3->LookaheadCoverage, lookahead_count,
+ TTO_Coverage ) )
+ goto Fail3;
+
+ l = ccsf3->LookaheadCoverage;
+
+ for ( nl = 0; nl < lookahead_count; nl++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Coverage( &l[nl], stream ) ) != TT_Err_Ok )
+ goto Fail2;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ ccsf3->SubstCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ccsf3->SubstLookupRecord = NULL;
+
+ count = ccsf3->SubstCount;
+
+ if ( ALLOC_ARRAY( ccsf3->SubstLookupRecord, count,
+ TTO_SubstLookupRecord ) )
+ goto Fail2;
+
+ slr = ccsf3->SubstLookupRecord;
+
+ if ( ACCESS_Frame( count * 4L ) )
+ goto Fail1;
+
+ for ( n = 0; n < count; n++ )
+ {
+ slr[n].SequenceIndex = GET_UShort();
+ slr[n].LookupListIndex = GET_UShort();
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( slr );
+
+ Fail2:
+ for ( m = 0; m < nl; m++ )
+ Free_Coverage( &l[m], memory );
+
+ FREE( l );
+
+ Fail3:
+ for ( m = 0; m < ni; m++ )
+ Free_Coverage( &i[m], memory );
+
+ FREE( i );
+
+ Fail4:
+ for ( m = 0; m < nb; m++ )
+ Free_Coverage( &b[m], memory );
+
+ FREE( b );
+ return error;
+ }
+
+
+ static void Gsub_Free_ChainContext3( TTO_ChainContextSubstFormat3* ccsf3,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Coverage* c;
+
+
+ FREE( ccsf3->SubstLookupRecord );
+
+ if ( ccsf3->LookaheadCoverage )
+ {
+ count = ccsf3->LookaheadGlyphCount;
+ c = ccsf3->LookaheadCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+
+ if ( ccsf3->InputCoverage )
+ {
+ count = ccsf3->InputGlyphCount;
+ c = ccsf3->InputCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+
+ if ( ccsf3->BacktrackCoverage )
+ {
+ count = ccsf3->BacktrackGlyphCount;
+ c = ccsf3->BacktrackCoverage;
+
+ for ( n = 0; n < count; n++ )
+ Free_Coverage( &c[n], memory );
+
+ FREE( c );
+ }
+ }
+
+
+ /* ChainContextSubst */
+
+ FT_Error Load_ChainContextSubst( TTO_ChainContextSubst* ccs,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ ccs->SubstFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( ccs->SubstFormat )
+ {
+ case 1:
+ return Load_ChainContextSubst1( &ccs->ccsf.ccsf1, stream );
+
+ case 2:
+ return Load_ChainContextSubst2( &ccs->ccsf.ccsf2, stream );
+
+ case 3:
+ return Load_ChainContextSubst3( &ccs->ccsf.ccsf3, stream );
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ void Free_ChainContextSubst( TTO_ChainContextSubst* ccs,
+ FT_Memory memory )
+ {
+ switch ( ccs->SubstFormat )
+ {
+ case 1:
+ Gsub_Free_ChainContext1( &ccs->ccsf.ccsf1, memory );
+ break;
+
+ case 2:
+ Gsub_Free_ChainContext2( &ccs->ccsf.ccsf2, memory );
+ break;
+
+ case 3:
+ Gsub_Free_ChainContext3( &ccs->ccsf.ccsf3, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Lookup_ChainContextSubst1(
+ TTO_GSUBHeader* gsub,
+ TTO_ChainContextSubstFormat1* ccsf1,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_UShort i, j, k, num_csr;
+ FT_UShort bgc, igc, lgc;
+ FT_Error error;
+
+ TTO_ChainSubRule* csr;
+ TTO_ChainSubRule curr_csr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ error = Coverage_Index( &ccsf1->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ csr = ccsf1->ChainSubRuleSet[index].ChainSubRule;
+ num_csr = ccsf1->ChainSubRuleSet[index].ChainSubRuleCount;
+
+ for ( k = 0; k < num_csr; k++ )
+ {
+ curr_csr = csr[k];
+ bgc = curr_csr.BacktrackGlyphCount;
+ igc = curr_csr.InputGlyphCount;
+ lgc = curr_csr.LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ goto next_chainsubrule;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
+ goto next_chainsubrule;
+
+ if ( bgc )
+ {
+ /* since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array */
+
+ for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + 1 == bgc - i )
+ goto next_chainsubrule;
+ j--;
+ }
+
+ /* In OpenType 1.3, it is undefined whether the offsets of
+ backtrack glyphs is in logical order or not. Version 1.4
+ will clarify this:
+
+ Logical order - a b c d e f g h i j
+ i
+ Input offsets - 0 1
+ Backtrack offsets - 3 2 1 0
+ Lookahead offsets - 0 1 2 3 */
+
+ if ( OUT_GLYPH( j ) != curr_csr.Backtrack[i] )
+ goto next_chainsubrule;
+ }
+ }
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + igc - i + lgc == (FT_Int)buffer->in_length )
+ goto next_chainsubrule;
+ j++;
+ }
+
+ if ( IN_GLYPH( j ) != curr_csr.Input[i - 1] )
+ goto next_chainsubrule;
+ }
+
+ /* we are starting to check for lookahead glyphs right after the
+ last context glyph */
+
+ for ( i = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + lgc - i == (FT_Int)buffer->in_length )
+ goto next_chainsubrule;
+ j++;
+ }
+
+ if ( IN_GLYPH( j ) != curr_csr.Lookahead[i] )
+ goto next_chainsubrule;
+ }
+
+ return Do_ContextSubst( gsub, igc,
+ curr_csr.SubstCount,
+ curr_csr.SubstLookupRecord,
+ buffer,
+ nesting_level );
+
+ next_chainsubrule:
+ ;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Lookup_ChainContextSubst2(
+ TTO_GSUBHeader* gsub,
+ TTO_ChainContextSubstFormat2* ccsf2,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, property;
+ FT_Memory memory;
+ FT_Error error;
+ FT_UShort i, j, k;
+ FT_UShort bgc, igc, lgc;
+ FT_UShort known_backtrack_classes,
+ known_input_classes,
+ known_lookahead_classes;
+
+ FT_UShort* backtrack_classes;
+ FT_UShort* input_classes;
+ FT_UShort* lookahead_classes;
+
+ FT_UShort* bc;
+ FT_UShort* ic;
+ FT_UShort* lc;
+
+ TTO_ChainSubClassSet* cscs;
+ TTO_ChainSubClassRule ccsr;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+ memory = gsub->memory;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ /* Note: The coverage table in format 2 doesn't give an index into
+ anything. It just lets us know whether or not we need to
+ do any lookup at all. */
+
+ error = Coverage_Index( &ccsf2->Coverage, IN_CURGLYPH(), &index );
+ if ( error )
+ return error;
+
+ if ( ALLOC_ARRAY( backtrack_classes, ccsf2->MaxBacktrackLength, FT_UShort ) )
+ return error;
+ known_backtrack_classes = 0;
+
+ if ( ALLOC_ARRAY( input_classes, ccsf2->MaxInputLength, FT_UShort ) )
+ goto End3;
+ known_input_classes = 1;
+
+ if ( ALLOC_ARRAY( lookahead_classes, ccsf2->MaxLookaheadLength, FT_UShort ) )
+ goto End2;
+ known_lookahead_classes = 0;
+
+ error = Get_Class( &ccsf2->InputClassDef, IN_CURGLYPH(),
+ &input_classes[0], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ cscs = &ccsf2->ChainSubClassSet[input_classes[0]];
+ if ( !cscs )
+ {
+ error = TTO_Err_Invalid_GSUB_SubTable;
+ goto End1;
+ }
+
+ for ( k = 0; k < cscs->ChainSubClassRuleCount; k++ )
+ {
+ ccsr = cscs->ChainSubClassRule[k];
+ bgc = ccsr.BacktrackGlyphCount;
+ igc = ccsr.InputGlyphCount;
+ lgc = ccsr.LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ goto next_chainsubclassrule;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
+ goto next_chainsubclassrule;
+
+ if ( bgc )
+ {
+ /* Since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array.
+ Note that `known_backtrack_classes' starts at index 0. */
+
+ bc = ccsr.Backtrack;
+
+ for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( j + 1 == bgc - i )
+ goto next_chainsubclassrule;
+ j--;
+ }
+
+ if ( i >= known_backtrack_classes )
+ {
+ /* Keeps us from having to do this for each rule */
+
+ error = Get_Class( &ccsf2->BacktrackClassDef, OUT_GLYPH( j ),
+ &backtrack_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_backtrack_classes = i;
+ }
+
+ if ( bc[i] != backtrack_classes[i] )
+ goto next_chainsubclassrule;
+ }
+ }
+
+ ic = ccsr.Input;
+
+ /* Start at 1 because [0] is implied */
+
+ for ( i = 1, j = buffer->in_pos + 1; i < igc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( j + igc - i + lgc == (FT_Int)buffer->in_length )
+ goto next_chainsubclassrule;
+ j++;
+ }
+
+ if ( i >= known_input_classes )
+ {
+ error = Get_Class( &ccsf2->InputClassDef, IN_GLYPH( j ),
+ &input_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_input_classes = i;
+ }
+
+ if ( ic[i - 1] != input_classes[i] )
+ goto next_chainsubclassrule;
+ }
+
+ /* we are starting to check for lookahead glyphs right after the
+ last context glyph */
+
+ lc = ccsr.Lookahead;
+
+ for ( i = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+
+ if ( j + lgc - i == (FT_Int)buffer->in_length )
+ goto next_chainsubclassrule;
+ j++;
+ }
+
+ if ( i >= known_lookahead_classes )
+ {
+ error = Get_Class( &ccsf2->LookaheadClassDef, IN_GLYPH( j ),
+ &lookahead_classes[i], NULL );
+ if ( error && error != TTO_Err_Not_Covered )
+ goto End1;
+ known_lookahead_classes = i;
+ }
+
+ if ( lc[i] != lookahead_classes[i] )
+ goto next_chainsubclassrule;
+ }
+
+ error = Do_ContextSubst( gsub, igc,
+ ccsr.SubstCount,
+ ccsr.SubstLookupRecord,
+ buffer,
+ nesting_level );
+ goto End1;
+
+ next_chainsubclassrule:
+ ;
+ }
+
+ error = TTO_Err_Not_Covered;
+
+ End1:
+ FREE( lookahead_classes );
+
+ End2:
+ FREE( input_classes );
+
+ End3:
+ FREE( backtrack_classes );
+ return error;
+ }
+
+
+ static FT_Error Lookup_ChainContextSubst3(
+ TTO_GSUBHeader* gsub,
+ TTO_ChainContextSubstFormat3* ccsf3,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_UShort index, i, j, property;
+ FT_UShort bgc, igc, lgc;
+ FT_Error error;
+
+ TTO_Coverage* bc;
+ TTO_Coverage* ic;
+ TTO_Coverage* lc;
+ TTO_GDEFHeader* gdef;
+
+
+ gdef = gsub->gdef;
+
+ if ( CHECK_Property( gdef, IN_CURITEM(), flags, &property ) )
+ return error;
+
+ bgc = ccsf3->BacktrackGlyphCount;
+ igc = ccsf3->InputGlyphCount;
+ lgc = ccsf3->LookaheadGlyphCount;
+
+ if ( context_length != 0xFFFF && context_length < igc )
+ return TTO_Err_Not_Covered;
+
+ /* check whether context is too long; it is a first guess only */
+
+ if ( bgc > buffer->out_pos || buffer->in_pos + igc + lgc > buffer->in_length )
+ return TTO_Err_Not_Covered;
+
+ if ( bgc )
+ {
+ /* Since we don't know in advance the number of glyphs to inspect,
+ we search backwards for matches in the backtrack glyph array */
+
+ bc = ccsf3->BacktrackCoverage;
+
+ for ( i = 0, j = buffer->out_pos - 1; i < bgc; i++, j-- )
+ {
+ while ( CHECK_Property( gdef, OUT_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + 1 == bgc - i )
+ return TTO_Err_Not_Covered;
+ j--;
+ }
+
+ error = Coverage_Index( &bc[i], OUT_GLYPH( j ), &index );
+ if ( error )
+ return error;
+ }
+ }
+
+ ic = ccsf3->InputCoverage;
+
+ for ( i = 0, j = buffer->in_pos; i < igc; i++, j++ )
+ {
+ /* We already called CHECK_Property for IN_GLYPH( buffer->in_pos ) */
+ while ( j > buffer->in_pos && CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + igc - i + lgc == (FT_Int)buffer->in_length )
+ return TTO_Err_Not_Covered;
+ j++;
+ }
+
+ error = Coverage_Index( &ic[i], IN_GLYPH( j ), &index );
+ if ( error )
+ return error;
+ }
+
+ /* we are starting for lookahead glyphs right after the last context
+ glyph */
+
+ lc = ccsf3->LookaheadCoverage;
+
+ for ( i = 0; i < lgc; i++, j++ )
+ {
+ while ( CHECK_Property( gdef, IN_ITEM( j ), flags, &property ) )
+ {
+ if ( error && error != TTO_Err_Not_Covered )
+ return error;
+
+ if ( j + lgc - i == (FT_Int)buffer->in_length )
+ return TTO_Err_Not_Covered;
+ j++;
+ }
+
+ error = Coverage_Index( &lc[i], IN_GLYPH( j ), &index );
+ if ( error )
+ return error;
+ }
+
+ return Do_ContextSubst( gsub, igc,
+ ccsf3->SubstCount,
+ ccsf3->SubstLookupRecord,
+ buffer,
+ nesting_level );
+ }
+
+
+ static FT_Error Lookup_ChainContextSubst(
+ TTO_GSUBHeader* gsub,
+ TTO_ChainContextSubst* ccs,
+ OTL_Buffer buffer,
+ FT_UShort flags,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ switch ( ccs->SubstFormat )
+ {
+ case 1:
+ return Lookup_ChainContextSubst1( gsub, &ccs->ccsf.ccsf1, buffer,
+ flags, context_length,
+ nesting_level );
+
+ case 2:
+ return Lookup_ChainContextSubst2( gsub, &ccs->ccsf.ccsf2, buffer,
+ flags, context_length,
+ nesting_level );
+
+ case 3:
+ return Lookup_ChainContextSubst3( gsub, &ccs->ccsf.ccsf3, buffer,
+ flags, context_length,
+ nesting_level );
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+
+ /***********
+ * GSUB API
+ ***********/
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Select_Script( TTO_GSUBHeader* gsub,
+ FT_ULong script_tag,
+ FT_UShort* script_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+
+
+ if ( !gsub || !script_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ for ( n = 0; n < sl->ScriptCount; n++ )
+ if ( script_tag == sr[n].ScriptTag )
+ {
+ *script_index = n;
+
+ return TT_Err_Ok;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Select_Language( TTO_GSUBHeader* gsub,
+ FT_ULong language_tag,
+ FT_UShort script_index,
+ FT_UShort* language_index,
+ FT_UShort* req_feature_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+
+
+ if ( !gsub || !language_index || !req_feature_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ for ( n = 0; n < s->LangSysCount; n++ )
+ if ( language_tag == lsr[n].LangSysTag )
+ {
+ *language_index = n;
+ *req_feature_index = lsr[n].LangSys.ReqFeatureIndex;
+
+ return TT_Err_Ok;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* selecting 0xFFFF for language_index asks for the values of the
+ default language (DefaultLangSys) */
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub,
+ FT_ULong feature_tag,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_UShort* feature_index )
+ {
+ FT_UShort n;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+ TTO_LangSys* ls;
+ FT_UShort* fi;
+
+ TTO_FeatureList* fl;
+ TTO_FeatureRecord* fr;
+
+
+ if ( !gsub || !feature_index )
+ return TT_Err_Invalid_Argument;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ fl = &gsub->FeatureList;
+ fr = fl->FeatureRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( language_index == 0xFFFF )
+ ls = &s->DefaultLangSys;
+ else
+ {
+ if ( language_index >= s->LangSysCount )
+ return TT_Err_Invalid_Argument;
+
+ ls = &lsr[language_index].LangSys;
+ }
+
+ fi = ls->FeatureIndex;
+
+ for ( n = 0; n < ls->FeatureCount; n++ )
+ {
+ if ( fi[n] >= fl->FeatureCount )
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+
+ if ( feature_tag == fr[fi[n]].FeatureTag )
+ {
+ *feature_index = fi[n];
+
+ return TT_Err_Ok;
+ }
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ /* The next three functions return a null-terminated list */
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub,
+ FT_ULong** script_tag_list )
+ {
+ FT_UShort n;
+ FT_Error error;
+ FT_Memory memory;
+ FT_ULong* stl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+
+
+ if ( !gsub || !script_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ memory = gsub->memory;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( ALLOC_ARRAY( stl, sl->ScriptCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < sl->ScriptCount; n++ )
+ stl[n] = sr[n].ScriptTag;
+ stl[n] = 0;
+
+ *script_tag_list = stl;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub,
+ FT_UShort script_index,
+ FT_ULong** language_tag_list )
+ {
+ FT_UShort n;
+ FT_Error error;
+ FT_Memory memory;
+ FT_ULong* ltl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+
+
+ if ( !gsub || !language_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ memory = gsub->memory;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( ALLOC_ARRAY( ltl, s->LangSysCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < s->LangSysCount; n++ )
+ ltl[n] = lsr[n].LangSysTag;
+ ltl[n] = 0;
+
+ *language_tag_list = ltl;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* selecting 0xFFFF for language_index asks for the values of the
+ default language (DefaultLangSys) */
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Query_Features( TTO_GSUBHeader* gsub,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_ULong** feature_tag_list )
+ {
+ FT_UShort n;
+ FT_Error error;
+ FT_Memory memory;
+ FT_ULong* ftl;
+
+ TTO_ScriptList* sl;
+ TTO_ScriptRecord* sr;
+ TTO_Script* s;
+ TTO_LangSysRecord* lsr;
+ TTO_LangSys* ls;
+ FT_UShort* fi;
+
+ TTO_FeatureList* fl;
+ TTO_FeatureRecord* fr;
+
+
+ if ( !gsub || !feature_tag_list )
+ return TT_Err_Invalid_Argument;
+
+ memory = gsub->memory;
+
+ sl = &gsub->ScriptList;
+ sr = sl->ScriptRecord;
+
+ fl = &gsub->FeatureList;
+ fr = fl->FeatureRecord;
+
+ if ( script_index >= sl->ScriptCount )
+ return TT_Err_Invalid_Argument;
+
+ s = &sr[script_index].Script;
+ lsr = s->LangSysRecord;
+
+ if ( language_index == 0xFFFF )
+ ls = &s->DefaultLangSys;
+ else
+ {
+ if ( language_index >= s->LangSysCount )
+ return TT_Err_Invalid_Argument;
+
+ ls = &lsr[language_index].LangSys;
+ }
+
+ fi = ls->FeatureIndex;
+
+ if ( ALLOC_ARRAY( ftl, ls->FeatureCount + 1, FT_ULong ) )
+ return error;
+
+ for ( n = 0; n < ls->FeatureCount; n++ )
+ {
+ if ( fi[n] >= fl->FeatureCount )
+ {
+ FREE( ftl );
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+ ftl[n] = fr[fi[n]].FeatureTag;
+ }
+ ftl[n] = 0;
+
+ *feature_tag_list = ftl;
+
+ return TT_Err_Ok;
+ }
+
+
+ /* Do an individual subtable lookup. Returns TT_Err_Ok if substitution
+ has been done, or TTO_Err_Not_Covered if not. */
+
+ static FT_Error GSub_Do_Glyph_Lookup( TTO_GSUBHeader* gsub,
+ FT_UShort lookup_index,
+ OTL_Buffer buffer,
+ FT_UShort context_length,
+ int nesting_level )
+ {
+ FT_Error error = TTO_Err_Not_Covered;
+ FT_UShort i, flags, lookup_count;
+ TTO_Lookup* lo;
+
+
+ nesting_level++;
+
+ if ( nesting_level > TTO_MAX_NESTING_LEVEL )
+ return TTO_Err_Too_Many_Nested_Contexts;
+
+ lookup_count = gsub->LookupList.LookupCount;
+ if (lookup_index >= lookup_count)
+ return error;
+
+ lo = &gsub->LookupList.Lookup[lookup_index];
+ flags = lo->LookupFlag;
+
+ for ( i = 0; i < lo->SubTableCount; i++ )
+ {
+ switch ( lo->LookupType )
+ {
+ case GSUB_LOOKUP_SINGLE:
+ error = Lookup_SingleSubst( &lo->SubTable[i].st.gsub.single,
+ buffer,
+ flags, context_length, gsub->gdef );
+ break;
+
+ case GSUB_LOOKUP_MULTIPLE:
+ error = Lookup_MultipleSubst( &lo->SubTable[i].st.gsub.multiple,
+ buffer,
+ flags, context_length, gsub->gdef );
+ break;
+
+ case GSUB_LOOKUP_ALTERNATE:
+ error = Lookup_AlternateSubst( gsub,
+ &lo->SubTable[i].st.gsub.alternate,
+ buffer,
+ flags, context_length, gsub->gdef );
+ break;
+
+ case GSUB_LOOKUP_LIGATURE:
+ error = Lookup_LigatureSubst( &lo->SubTable[i].st.gsub.ligature,
+ buffer,
+ flags, context_length, gsub->gdef );
+ break;
+
+ case GSUB_LOOKUP_CONTEXT:
+ error = Lookup_ContextSubst( gsub, &lo->SubTable[i].st.gsub.context,
+ buffer,
+ flags, context_length, nesting_level );
+ break;
+
+ case GSUB_LOOKUP_CHAIN:
+ error = Lookup_ChainContextSubst( gsub,
+ &lo->SubTable[i].st.gsub.chain,
+ buffer,
+ flags, context_length,
+ nesting_level );
+ break;
+ }
+
+ /* Check whether we have a successful substitution or an error other
+ than TTO_Err_Not_Covered */
+
+ if ( error != TTO_Err_Not_Covered )
+ return error;
+ }
+
+ return TTO_Err_Not_Covered;
+ }
+
+ /* apply one lookup to the input string object */
+
+ static FT_Error GSub_Do_String_Lookup( TTO_GSUBHeader* gsub,
+ FT_UShort lookup_index,
+ OTL_Buffer buffer )
+ {
+ FT_Error error, retError = TTO_Err_Not_Covered;
+
+ FT_UInt* properties = gsub->LookupList.Properties;
+
+ int nesting_level = 0;
+
+
+ while ( buffer->in_pos < buffer->in_length )
+ {
+ if ( ~IN_PROPERTIES( buffer->in_pos ) & properties[lookup_index] )
+ {
+ /* 0xFFFF indicates that we don't have a context length yet */
+ error = GSub_Do_Glyph_Lookup( gsub, lookup_index, buffer,
+ 0xFFFF, nesting_level );
+ if ( error )
+ {
+ if ( error != TTO_Err_Not_Covered )
+ return error;
+ }
+ else
+ retError = error;
+ }
+ else
+ error = TTO_Err_Not_Covered;
+
+ if ( error == TTO_Err_Not_Covered )
+ if ( otl_buffer_copy_output_glyph ( buffer ) )
+ return error;
+ }
+
+ return retError;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub,
+ FT_UShort feature_index,
+ FT_UInt property )
+ {
+ FT_UShort i;
+
+ TTO_Feature feature;
+ FT_UInt* properties;
+ FT_UShort* index;
+ FT_UShort lookup_count;
+
+ /* Each feature can only be added once */
+
+ if ( !gsub ||
+ feature_index >= gsub->FeatureList.FeatureCount ||
+ gsub->FeatureList.ApplyCount == gsub->FeatureList.FeatureCount )
+ return TT_Err_Invalid_Argument;
+
+ gsub->FeatureList.ApplyOrder[gsub->FeatureList.ApplyCount++] = feature_index;
+
+ properties = gsub->LookupList.Properties;
+
+ feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
+ index = feature.LookupListIndex;
+ lookup_count = gsub->LookupList.LookupCount;
+
+ for ( i = 0; i < feature.LookupListCount; i++ )
+ {
+ FT_UShort lookup_index = index[i];
+ if (lookup_index < lookup_count)
+ properties[lookup_index] |= property;
+ }
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub )
+ {
+ FT_UShort i;
+
+ FT_UInt* properties;
+
+
+ if ( !gsub )
+ return TT_Err_Invalid_Argument;
+
+ gsub->FeatureList.ApplyCount = 0;
+
+ properties = gsub->LookupList.Properties;
+
+ for ( i = 0; i < gsub->LookupList.LookupCount; i++ )
+ properties[i] = 0;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub,
+ TTO_AltFunction altfunc,
+ void* data )
+ {
+ if ( !gsub )
+ return TT_Err_Invalid_Argument;
+
+ gsub->altfunc = altfunc;
+ gsub->data = data;
+
+ return TT_Err_Ok;
+ }
+
+
+ EXPORT_FUNC
+ FT_Error TT_GSUB_Apply_String( TTO_GSUBHeader* gsub,
+ OTL_Buffer buffer )
+ {
+ FT_Error error, retError = TTO_Err_Not_Covered;
+ FT_UShort i, j, feature_index, lookup_count;
+ TTO_Feature feature;
+
+ if ( !gsub ||
+ !buffer || buffer->in_length == 0 || buffer->in_pos >= buffer->in_length )
+ return TT_Err_Invalid_Argument;
+
+ lookup_count = gsub->LookupList.LookupCount;
+
+ for ( i = 0; i < gsub->FeatureList.ApplyCount; i++)
+ {
+ feature_index = gsub->FeatureList.ApplyOrder[i];
+ feature = gsub->FeatureList.FeatureRecord[feature_index].Feature;
+
+ for ( j = 0; j < feature.LookupListCount; j++ )
+ {
+ FT_UShort lookup_index = feature.LookupListIndex[j];
+
+ /* Skip nonexistant lookups */
+ if (lookup_index >= lookup_count)
+ continue;
+
+ error = GSub_Do_String_Lookup( gsub, lookup_index, buffer );
+ if ( error )
+ {
+ if ( error != TTO_Err_Not_Covered )
+ goto End;
+ }
+ else
+ retError = error;
+
+ error = otl_buffer_swap( buffer );
+ if ( error )
+ goto End;
+ }
+ }
+
+ error = retError;
+
+ End:
+ return error;
+ }
+
+
+/* END */
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftxgsub.h b/tqtinterface/qt4/src/3rdparty/opentype/ftxgsub.h
new file mode 100644
index 0000000..a8ffa43
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftxgsub.h
@@ -0,0 +1,575 @@
+/*******************************************************************
+ *
+ * ftxgsub.h
+ *
+ * TrueType Open GSUB table support
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef FTXOPEN_H
+#error "Don't include this file! Use ftxopen.h instead."
+#endif
+
+#ifndef FTXGSUB_H
+#define FTXGSUB_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TTO_Err_Invalid_GSUB_SubTable_Format 0x1010
+#define TTO_Err_Invalid_GSUB_SubTable 0x1011
+
+
+/* Lookup types for glyph substitution */
+
+#define GSUB_LOOKUP_SINGLE 1
+#define GSUB_LOOKUP_MULTIPLE 2
+#define GSUB_LOOKUP_ALTERNATE 3
+#define GSUB_LOOKUP_LIGATURE 4
+#define GSUB_LOOKUP_CONTEXT 5
+#define GSUB_LOOKUP_CHAIN 6
+#define GSUB_LOOKUP_EXTENSION 7
+
+
+/* Use this if a feature applies to all glyphs */
+
+#define ALL_GLYPHS 0xFFFF
+
+
+ /* A pointer to a function which selects the alternate glyph. `pos' is
+ the position of the glyph with index `glyphID', `num_alternates'
+ gives the number of alternates in the `alternates' array. `data'
+ points to the user-defined structure specified during a call to
+ TT_GSUB_Register_Alternate_Function(). The function must return an
+ index into the `alternates' array. */
+
+ typedef FT_UShort (*TTO_AltFunction)(FT_ULong pos,
+ FT_UShort glyphID,
+ FT_UShort num_alternates,
+ FT_UShort* alternates,
+ void* data );
+
+
+ struct TTO_GSUBHeader_
+ {
+ FT_Memory memory;
+
+ FT_ULong offset;
+
+ FT_Fixed Version;
+
+ TTO_ScriptList ScriptList;
+ TTO_FeatureList FeatureList;
+ TTO_LookupList LookupList;
+
+ TTO_GDEFHeader* gdef;
+
+ /* the next two fields are used for an alternate substitution callback
+ function to select the proper alternate glyph. */
+
+ TTO_AltFunction altfunc;
+ void* data;
+ };
+
+ typedef struct TTO_GSUBHeader_ TTO_GSUBHeader;
+ typedef struct TTO_GSUBHeader_* TTO_GSUB;
+
+
+ /* LookupType 1 */
+
+ struct TTO_SingleSubstFormat1_
+ {
+ FT_Short DeltaGlyphID; /* constant added to get
+ substitution glyph index */
+ };
+
+ typedef struct TTO_SingleSubstFormat1_ TTO_SingleSubstFormat1;
+
+
+ struct TTO_SingleSubstFormat2_
+ {
+ FT_UShort GlyphCount; /* number of glyph IDs in
+ Substitute array */
+ FT_UShort* Substitute; /* array of substitute glyph IDs */
+ };
+
+ typedef struct TTO_SingleSubstFormat2_ TTO_SingleSubstFormat2;
+
+
+ struct TTO_SingleSubst_
+ {
+ FT_UShort SubstFormat; /* 1 or 2 */
+ TTO_Coverage Coverage; /* Coverage table */
+
+ union
+ {
+ TTO_SingleSubstFormat1 ssf1;
+ TTO_SingleSubstFormat2 ssf2;
+ } ssf;
+ };
+
+ typedef struct TTO_SingleSubst_ TTO_SingleSubst;
+
+
+ /* LookupType 2 */
+
+ struct TTO_Sequence_
+ {
+ FT_UShort GlyphCount; /* number of glyph IDs in the
+ Substitute array */
+ FT_UShort* Substitute; /* string of glyph IDs to
+ substitute */
+ };
+
+ typedef struct TTO_Sequence_ TTO_Sequence;
+
+
+ struct TTO_MultipleSubst_
+ {
+ FT_UShort SubstFormat; /* always 1 */
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort SequenceCount; /* number of Sequence tables */
+ TTO_Sequence* Sequence; /* array of Sequence tables */
+ };
+
+ typedef struct TTO_MultipleSubst_ TTO_MultipleSubst;
+
+
+ /* LookupType 3 */
+
+ struct TTO_AlternateSet_
+ {
+ FT_UShort GlyphCount; /* number of glyph IDs in the
+ Alternate array */
+ FT_UShort* Alternate; /* array of alternate glyph IDs */
+ };
+
+ typedef struct TTO_AlternateSet_ TTO_AlternateSet;
+
+
+ struct TTO_AlternateSubst_
+ {
+ FT_UShort SubstFormat; /* always 1 */
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort AlternateSetCount;
+ /* number of AlternateSet tables */
+ TTO_AlternateSet* AlternateSet; /* array of AlternateSet tables */
+ };
+
+ typedef struct TTO_AlternateSubst_ TTO_AlternateSubst;
+
+
+ /* LookupType 4 */
+
+ struct TTO_Ligature_
+ {
+ FT_UShort LigGlyph; /* glyphID of ligature
+ to substitute */
+ FT_UShort ComponentCount; /* number of components in ligature */
+ FT_UShort* Component; /* array of component glyph IDs */
+ };
+
+ typedef struct TTO_Ligature_ TTO_Ligature;
+
+
+ struct TTO_LigatureSet_
+ {
+ FT_UShort LigatureCount; /* number of Ligature tables */
+ TTO_Ligature* Ligature; /* array of Ligature tables */
+ };
+
+ typedef struct TTO_LigatureSet_ TTO_LigatureSet;
+
+
+ struct TTO_LigatureSubst_
+ {
+ FT_UShort SubstFormat; /* always 1 */
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort LigatureSetCount; /* number of LigatureSet tables */
+ TTO_LigatureSet* LigatureSet; /* array of LigatureSet tables */
+ };
+
+ typedef struct TTO_LigatureSubst_ TTO_LigatureSubst;
+
+
+ /* needed by both lookup type 5 and 6 */
+
+ struct TTO_SubstLookupRecord_
+ {
+ FT_UShort SequenceIndex; /* index into current
+ glyph sequence */
+ FT_UShort LookupListIndex; /* Lookup to apply to that pos. */
+ };
+
+ typedef struct TTO_SubstLookupRecord_ TTO_SubstLookupRecord;
+
+
+ /* LookupType 5 */
+
+ struct TTO_SubRule_
+ {
+ FT_UShort GlyphCount; /* total number of input glyphs */
+ FT_UShort SubstCount; /* number of SubstLookupRecord
+ tables */
+ FT_UShort* Input; /* array of input glyph IDs */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of SubstLookupRecord
+ tables */
+ };
+
+ typedef struct TTO_SubRule_ TTO_SubRule;
+
+
+ struct TTO_SubRuleSet_
+ {
+ FT_UShort SubRuleCount; /* number of SubRule tables */
+ TTO_SubRule* SubRule; /* array of SubRule tables */
+ };
+
+ typedef struct TTO_SubRuleSet_ TTO_SubRuleSet;
+
+
+ struct TTO_ContextSubstFormat1_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort SubRuleSetCount; /* number of SubRuleSet tables */
+ TTO_SubRuleSet* SubRuleSet; /* array of SubRuleSet tables */
+ };
+
+ typedef struct TTO_ContextSubstFormat1_ TTO_ContextSubstFormat1;
+
+
+ struct TTO_SubClassRule_
+ {
+ FT_UShort GlyphCount; /* total number of context classes */
+ FT_UShort SubstCount; /* number of SubstLookupRecord
+ tables */
+ FT_UShort* Class; /* array of classes */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of SubstLookupRecord
+ tables */
+ };
+
+ typedef struct TTO_SubClassRule_ TTO_SubClassRule;
+
+
+ struct TTO_SubClassSet_
+ {
+ FT_UShort SubClassRuleCount;
+ /* number of SubClassRule tables */
+ TTO_SubClassRule* SubClassRule; /* array of SubClassRule tables */
+ };
+
+ typedef struct TTO_SubClassSet_ TTO_SubClassSet;
+
+
+ /* The `MaxContextLength' field is not defined in the TTO specification
+ but simplifies the implementation of this format. It holds the
+ maximal context length used in the context rules. */
+
+ struct TTO_ContextSubstFormat2_
+ {
+ FT_UShort MaxContextLength;
+ /* maximal context length */
+ TTO_Coverage Coverage; /* Coverage table */
+ TTO_ClassDefinition ClassDef; /* ClassDef table */
+ FT_UShort SubClassSetCount;
+ /* number of SubClassSet tables */
+ TTO_SubClassSet* SubClassSet; /* array of SubClassSet tables */
+ };
+
+ typedef struct TTO_ContextSubstFormat2_ TTO_ContextSubstFormat2;
+
+
+ struct TTO_ContextSubstFormat3_
+ {
+ FT_UShort GlyphCount; /* number of input glyphs */
+ FT_UShort SubstCount; /* number of SubstLookupRecords */
+ TTO_Coverage* Coverage; /* array of Coverage tables */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of substitution lookups */
+ };
+
+ typedef struct TTO_ContextSubstFormat3_ TTO_ContextSubstFormat3;
+
+
+ struct TTO_ContextSubst_
+ {
+ FT_UShort SubstFormat; /* 1, 2, or 3 */
+
+ union
+ {
+ TTO_ContextSubstFormat1 csf1;
+ TTO_ContextSubstFormat2 csf2;
+ TTO_ContextSubstFormat3 csf3;
+ } csf;
+ };
+
+ typedef struct TTO_ContextSubst_ TTO_ContextSubst;
+
+
+ /* LookupType 6 */
+
+ struct TTO_ChainSubRule_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* total number of backtrack glyphs */
+ FT_UShort* Backtrack; /* array of backtrack glyph IDs */
+ FT_UShort InputGlyphCount;
+ /* total number of input glyphs */
+ FT_UShort* Input; /* array of input glyph IDs */
+ FT_UShort LookaheadGlyphCount;
+ /* total number of lookahead glyphs */
+ FT_UShort* Lookahead; /* array of lookahead glyph IDs */
+ FT_UShort SubstCount; /* number of SubstLookupRecords */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of SubstLookupRecords */
+ };
+
+ typedef struct TTO_ChainSubRule_ TTO_ChainSubRule;
+
+
+ struct TTO_ChainSubRuleSet_
+ {
+ FT_UShort ChainSubRuleCount;
+ /* number of ChainSubRule tables */
+ TTO_ChainSubRule* ChainSubRule; /* array of ChainSubRule tables */
+ };
+
+ typedef struct TTO_ChainSubRuleSet_ TTO_ChainSubRuleSet;
+
+
+ struct TTO_ChainContextSubstFormat1_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+ FT_UShort ChainSubRuleSetCount;
+ /* number of ChainSubRuleSet tables */
+ TTO_ChainSubRuleSet* ChainSubRuleSet;
+ /* array of ChainSubRuleSet tables */
+ };
+
+ typedef struct TTO_ChainContextSubstFormat1_ TTO_ChainContextSubstFormat1;
+
+
+ struct TTO_ChainSubClassRule_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* total number of backtrack
+ classes */
+ FT_UShort* Backtrack; /* array of backtrack classes */
+ FT_UShort InputGlyphCount;
+ /* total number of context classes */
+ FT_UShort* Input; /* array of context classes */
+ FT_UShort LookaheadGlyphCount;
+ /* total number of lookahead
+ classes */
+ FT_UShort* Lookahead; /* array of lookahead classes */
+ FT_UShort SubstCount; /* number of SubstLookupRecords */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of substitution lookups */
+ };
+
+ typedef struct TTO_ChainSubClassRule_ TTO_ChainSubClassRule;
+
+
+ struct TTO_ChainSubClassSet_
+ {
+ FT_UShort ChainSubClassRuleCount;
+ /* number of ChainSubClassRule
+ tables */
+ TTO_ChainSubClassRule* ChainSubClassRule;
+ /* array of ChainSubClassRule
+ tables */
+ };
+
+ typedef struct TTO_ChainSubClassSet_ TTO_ChainSubClassSet;
+
+
+ /* The `MaxXXXLength' fields are not defined in the TTO specification
+ but simplifies the implementation of this format. It holds the
+ maximal context length used in the specific context rules. */
+
+ struct TTO_ChainContextSubstFormat2_
+ {
+ TTO_Coverage Coverage; /* Coverage table */
+
+ FT_UShort MaxBacktrackLength;
+ /* maximal backtrack length */
+ TTO_ClassDefinition BacktrackClassDef;
+ /* BacktrackClassDef table */
+ FT_UShort MaxInputLength;
+ /* maximal input length */
+ TTO_ClassDefinition InputClassDef;
+ /* InputClassDef table */
+ FT_UShort MaxLookaheadLength;
+ /* maximal lookahead length */
+ TTO_ClassDefinition LookaheadClassDef;
+ /* LookaheadClassDef table */
+
+ FT_UShort ChainSubClassSetCount;
+ /* number of ChainSubClassSet
+ tables */
+ TTO_ChainSubClassSet* ChainSubClassSet;
+ /* array of ChainSubClassSet
+ tables */
+ };
+
+ typedef struct TTO_ChainContextSubstFormat2_ TTO_ChainContextSubstFormat2;
+
+
+ struct TTO_ChainContextSubstFormat3_
+ {
+ FT_UShort BacktrackGlyphCount;
+ /* number of backtrack glyphs */
+ TTO_Coverage* BacktrackCoverage;
+ /* array of backtrack Coverage
+ tables */
+ FT_UShort InputGlyphCount;
+ /* number of input glyphs */
+ TTO_Coverage* InputCoverage;
+ /* array of input coverage
+ tables */
+ FT_UShort LookaheadGlyphCount;
+ /* number of lookahead glyphs */
+ TTO_Coverage* LookaheadCoverage;
+ /* array of lookahead coverage
+ tables */
+ FT_UShort SubstCount; /* number of SubstLookupRecords */
+ TTO_SubstLookupRecord* SubstLookupRecord;
+ /* array of substitution lookups */
+ };
+
+ typedef struct TTO_ChainContextSubstFormat3_ TTO_ChainContextSubstFormat3;
+
+
+ struct TTO_ChainContextSubst_
+ {
+ FT_UShort SubstFormat; /* 1, 2, or 3 */
+
+ union
+ {
+ TTO_ChainContextSubstFormat1 ccsf1;
+ TTO_ChainContextSubstFormat2 ccsf2;
+ TTO_ChainContextSubstFormat3 ccsf3;
+ } ccsf;
+ };
+
+ typedef struct TTO_ChainContextSubst_ TTO_ChainContextSubst;
+
+
+ union TTO_GSUB_SubTable_
+ {
+ TTO_SingleSubst single;
+ TTO_MultipleSubst multiple;
+ TTO_AlternateSubst alternate;
+ TTO_LigatureSubst ligature;
+ TTO_ContextSubst context;
+ TTO_ChainContextSubst chain;
+ };
+
+ typedef union TTO_GSUB_SubTable_ TTO_GSUB_SubTable;
+
+
+ /* A simple string object. It can both `send' and `receive' data.
+ In case of sending, `length' and `pos' will be used. In case of
+ receiving, `pos' points to the first free slot, and `allocated'
+ specifies the amount of allocated memory (and the `length' field
+ will be ignored). The routine TT_Add_String() will increase the
+ amount of memory if necessary. After end of receive, `length'
+ should be set to the value of `pos', and `pos' will be set to zero.
+
+ `properties' (which is treated as a bit field) gives the glyph's
+ properties: If a certain bit is set for a glyph, the feature which
+ has the same bit set in its property value is applied.
+
+ `components' is an internal array which tracks components of
+ ligatures. We need this for MarkToLigature Attachment Positioning
+ Subtables (in GPOS) together with `ligIDs' (which is used to mark
+ ligatures and the skipped glyphs during a ligature lookup).
+ `max_ligID' is increased after a successful ligature lookup.
+
+ NEVER modify any elements of the structure! You should rather copy
+ its contents if necessary.
+
+ TT_Add_String() will also handle allocation; you should use
+ free() in case you want to destroy the arrays in the object. */
+
+
+ /* finally, the GSUB API */
+
+ /* EXPORT_DEF
+ TT_Error TT_Init_GSUB_Extension( TT_Engine engine ); */
+
+ EXPORT_DEF
+ FT_Error TT_Load_GSUB_Table( FT_Face face,
+ TTO_GSUBHeader** gsub,
+ TTO_GDEFHeader* gdef );
+
+ EXPORT_DEF
+ FT_Error TT_Done_GSUB_Table( TTO_GSUBHeader* gsub );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Select_Script( TTO_GSUBHeader* gsub,
+ FT_ULong script_tag,
+ FT_UShort* script_index );
+ EXPORT_DEF
+ FT_Error TT_GSUB_Select_Language( TTO_GSUBHeader* gsub,
+ FT_ULong language_tag,
+ FT_UShort script_index,
+ FT_UShort* language_index,
+ FT_UShort* req_feature_index );
+ EXPORT_DEF
+ FT_Error TT_GSUB_Select_Feature( TTO_GSUBHeader* gsub,
+ FT_ULong feature_tag,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_UShort* feature_index );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Query_Scripts( TTO_GSUBHeader* gsub,
+ FT_ULong** script_tag_list );
+ EXPORT_DEF
+ FT_Error TT_GSUB_Query_Languages( TTO_GSUBHeader* gsub,
+ FT_UShort script_index,
+ FT_ULong** language_tag_list );
+ EXPORT_DEF
+ FT_Error TT_GSUB_Query_Features( TTO_GSUBHeader* gsub,
+ FT_UShort script_index,
+ FT_UShort language_index,
+ FT_ULong** feature_tag_list );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Add_Feature( TTO_GSUBHeader* gsub,
+ FT_UShort feature_index,
+ FT_UInt property );
+ EXPORT_DEF
+ FT_Error TT_GSUB_Clear_Features( TTO_GSUBHeader* gsub );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Register_Alternate_Function( TTO_GSUBHeader* gsub,
+ TTO_AltFunction altfunc,
+ void* data );
+
+ EXPORT_DEF
+ FT_Error TT_GSUB_Apply_String( TTO_GSUBHeader* gsub,
+ OTL_Buffer buffer );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FTXGSUB_H */
+
+
+/* END */
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftxopen.c b/tqtinterface/qt4/src/3rdparty/opentype/ftxopen.c
new file mode 100644
index 0000000..f45e778
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftxopen.c
@@ -0,0 +1,1541 @@
+/*******************************************************************
+ *
+ * ftxopen.c
+ *
+ * TrueType Open common table support.
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#include "ftxopen.h"
+#include "ftxopenf.h"
+
+#include "ftglue.h"
+
+
+ /***************************
+ * Script related functions
+ ***************************/
+
+
+ /* LangSys */
+
+ static FT_Error Load_LangSys( TTO_LangSys* ls,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_UShort n, count;
+ FT_UShort* fi;
+
+
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ ls->LookupOrderOffset = GET_UShort(); /* should be 0 */
+ ls->ReqFeatureIndex = GET_UShort();
+ count = ls->FeatureCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ls->FeatureIndex = NULL;
+
+ if ( ALLOC_ARRAY( ls->FeatureIndex, count, FT_UShort ) )
+ return error;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( ls->FeatureIndex );
+ return error;
+ }
+
+ fi = ls->FeatureIndex;
+
+ for ( n = 0; n < count; n++ )
+ fi[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_LangSys( TTO_LangSys* ls,
+ FT_Memory memory )
+ {
+ FREE( ls->FeatureIndex );
+ }
+
+
+ /* Script */
+
+ static FT_Error Load_Script( TTO_Script* s,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_LangSysRecord* lsr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ if ( new_offset != base_offset ) /* not a NULL offset */
+ {
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LangSys( &s->DefaultLangSys,
+ stream ) ) != TT_Err_Ok )
+ return error;
+ (void)FILE_Seek( cur_offset );
+ }
+ else
+ {
+ /* we create a DefaultLangSys table with no entries */
+
+ s->DefaultLangSys.LookupOrderOffset = 0;
+ s->DefaultLangSys.ReqFeatureIndex = 0xFFFF;
+ s->DefaultLangSys.FeatureCount = 0;
+ s->DefaultLangSys.FeatureIndex = NULL;
+ }
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail2;
+
+ count = s->LangSysCount = GET_UShort();
+
+ /* safety check; otherwise the official handling of TrueType Open
+ fonts won't work */
+
+ if ( s->LangSysCount == 0 && s->DefaultLangSys.FeatureCount == 0 )
+ {
+ error = TTO_Err_Empty_Script;
+ goto Fail2;
+ }
+
+ FORGET_Frame();
+
+ s->LangSysRecord = NULL;
+
+ if ( ALLOC_ARRAY( s->LangSysRecord, count, TTO_LangSysRecord ) )
+ goto Fail2;
+
+ lsr = s->LangSysRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 6L ) )
+ goto Fail1;
+
+ lsr[n].LangSysTag = GET_ULong();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_LangSys( &lsr[n].LangSys, stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_LangSys( &lsr[m].LangSys, memory );
+
+ FREE( s->LangSysRecord );
+
+ Fail2:
+ Free_LangSys( &s->DefaultLangSys, memory );
+ return error;
+ }
+
+
+ static void Free_Script( TTO_Script* s,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_LangSysRecord* lsr;
+
+
+ Free_LangSys( &s->DefaultLangSys, memory );
+
+ if ( s->LangSysRecord )
+ {
+ count = s->LangSysCount;
+ lsr = s->LangSysRecord;
+
+ for ( n = 0; n < count; n++ )
+ Free_LangSys( &lsr[n].LangSys, memory );
+
+ FREE( lsr );
+ }
+ }
+
+
+ /* ScriptList */
+
+ FT_Error Load_ScriptList( TTO_ScriptList* sl,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, script_count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_ScriptRecord* sr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ script_count = GET_UShort();
+
+ FORGET_Frame();
+
+ sl->ScriptRecord = NULL;
+
+ if ( ALLOC_ARRAY( sl->ScriptRecord, script_count, TTO_ScriptRecord ) )
+ return error;
+
+ sr = sl->ScriptRecord;
+
+ sl->ScriptCount= 0;
+ for ( n = 0; n < script_count; n++ )
+ {
+ if ( ACCESS_Frame( 6L ) )
+ goto Fail;
+
+ sr[sl->ScriptCount].ScriptTag = GET_ULong();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+
+ if ( FILE_Seek( new_offset ) )
+ goto Fail;
+
+ error = Load_Script( &sr[sl->ScriptCount].Script, stream );
+ if ( error == TT_Err_Ok )
+ sl->ScriptCount += 1;
+ else if ( error != TTO_Err_Empty_Script )
+ goto Fail;
+
+ (void)FILE_Seek( cur_offset );
+ }
+
+ if ( sl->ScriptCount == 0 )
+ {
+ error = TTO_Err_Invalid_SubTable;
+ goto Fail;
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( n = 0; n < sl->ScriptCount; n++ )
+ Free_Script( &sr[n].Script, memory );
+
+ FREE( sl->ScriptRecord );
+ return error;
+ }
+
+
+ void Free_ScriptList( TTO_ScriptList* sl,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_ScriptRecord* sr;
+
+
+ if ( sl->ScriptRecord )
+ {
+ count = sl->ScriptCount;
+ sr = sl->ScriptRecord;
+
+ for ( n = 0; n < count; n++ )
+ Free_Script( &sr[n].Script, memory );
+
+ FREE( sr );
+ }
+ }
+
+
+
+ /*********************************
+ * Feature List related functions
+ *********************************/
+
+
+ /* Feature */
+
+ static FT_Error Load_Feature( TTO_Feature* f,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* lli;
+
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ f->FeatureParams = GET_UShort(); /* should be 0 */
+ count = f->LookupListCount = GET_UShort();
+
+ FORGET_Frame();
+
+ f->LookupListIndex = NULL;
+
+ if ( ALLOC_ARRAY( f->LookupListIndex, count, FT_UShort ) )
+ return error;
+
+ lli = f->LookupListIndex;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( f->LookupListIndex );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ lli[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_Feature( TTO_Feature* f,
+ FT_Memory memory )
+ {
+ FREE( f->LookupListIndex );
+ }
+
+
+ /* FeatureList */
+
+ FT_Error Load_FeatureList( TTO_FeatureList* fl,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_FeatureRecord* fr;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = fl->FeatureCount = GET_UShort();
+
+ FORGET_Frame();
+
+ fl->FeatureRecord = NULL;
+
+ if ( ALLOC_ARRAY( fl->FeatureRecord, count, TTO_FeatureRecord ) )
+ return error;
+ if ( ALLOC_ARRAY( fl->ApplyOrder, count, FT_UShort ) )
+ goto Fail2;
+
+ fl->ApplyCount = 0;
+
+ fr = fl->FeatureRecord;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 6L ) )
+ goto Fail1;
+
+ fr[n].FeatureTag = GET_ULong();
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Feature( &fr[n].Feature, stream ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ for ( m = 0; m < n; m++ )
+ Free_Feature( &fr[m].Feature, memory );
+
+ FREE( fl->ApplyOrder );
+
+ Fail2:
+ FREE( fl->FeatureRecord );
+
+ return error;
+ }
+
+
+ void Free_FeatureList( TTO_FeatureList* fl,
+ FT_Memory memory)
+ {
+ FT_UShort n, count;
+
+ TTO_FeatureRecord* fr;
+
+
+ if ( fl->FeatureRecord )
+ {
+ count = fl->FeatureCount;
+ fr = fl->FeatureRecord;
+
+ for ( n = 0; n < count; n++ )
+ Free_Feature( &fr[n].Feature, memory );
+
+ FREE( fr );
+ }
+
+ FREE( fl->ApplyOrder );
+ }
+
+
+
+ /********************************
+ * Lookup List related functions
+ ********************************/
+
+ /* the subroutines of the following two functions are defined in
+ ftxgsub.c and ftxgpos.c respectively */
+
+
+ /* SubTable */
+
+ static FT_Error Load_SubTable( TTO_SubTable* st,
+ FT_Stream stream,
+ TTO_Type table_type,
+ FT_UShort lookup_type )
+ {
+ if ( table_type == GSUB )
+ switch ( lookup_type )
+ {
+ case GSUB_LOOKUP_SINGLE:
+ return Load_SingleSubst( &st->st.gsub.single, stream );
+
+ case GSUB_LOOKUP_MULTIPLE:
+ return Load_MultipleSubst( &st->st.gsub.multiple, stream );
+
+ case GSUB_LOOKUP_ALTERNATE:
+ return Load_AlternateSubst( &st->st.gsub.alternate, stream );
+
+ case GSUB_LOOKUP_LIGATURE:
+ return Load_LigatureSubst( &st->st.gsub.ligature, stream );
+
+ case GSUB_LOOKUP_CONTEXT:
+ return Load_ContextSubst( &st->st.gsub.context, stream );
+
+ case GSUB_LOOKUP_CHAIN:
+ return Load_ChainContextSubst( &st->st.gsub.chain, stream );
+
+ default:
+ return TTO_Err_Invalid_GSUB_SubTable_Format;
+ }
+ else
+ switch ( lookup_type )
+ {
+ case GPOS_LOOKUP_SINGLE:
+ return Load_SinglePos( &st->st.gpos.single, stream );
+
+ case GPOS_LOOKUP_PAIR:
+ return Load_PairPos( &st->st.gpos.pair, stream );
+
+ case GPOS_LOOKUP_CURSIVE:
+ return Load_CursivePos( &st->st.gpos.cursive, stream );
+
+ case GPOS_LOOKUP_MARKBASE:
+ return Load_MarkBasePos( &st->st.gpos.markbase, stream );
+
+ case GPOS_LOOKUP_MARKLIG:
+ return Load_MarkLigPos( &st->st.gpos.marklig, stream );
+
+ case GPOS_LOOKUP_MARKMARK:
+ return Load_MarkMarkPos( &st->st.gpos.markmark, stream );
+
+ case GPOS_LOOKUP_CONTEXT:
+ return Load_ContextPos( &st->st.gpos.context, stream );
+
+ case GPOS_LOOKUP_CHAIN:
+ return Load_ChainContextPos( &st->st.gpos.chain, stream );
+
+ default:
+ return TTO_Err_Invalid_GPOS_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ static void Free_SubTable( TTO_SubTable* st,
+ TTO_Type table_type,
+ FT_UShort lookup_type,
+ FT_Memory memory )
+ {
+ if ( table_type == GSUB )
+ switch ( lookup_type )
+ {
+ case GSUB_LOOKUP_SINGLE:
+ Free_SingleSubst( &st->st.gsub.single, memory );
+ break;
+
+ case GSUB_LOOKUP_MULTIPLE:
+ Free_MultipleSubst( &st->st.gsub.multiple, memory );
+ break;
+
+ case GSUB_LOOKUP_ALTERNATE:
+ Free_AlternateSubst( &st->st.gsub.alternate, memory );
+ break;
+
+ case GSUB_LOOKUP_LIGATURE:
+ Free_LigatureSubst( &st->st.gsub.ligature, memory );
+ break;
+
+ case GSUB_LOOKUP_CONTEXT:
+ Free_ContextSubst( &st->st.gsub.context, memory );
+ break;
+
+ case GSUB_LOOKUP_CHAIN:
+ Free_ChainContextSubst( &st->st.gsub.chain, memory );
+ break;
+ }
+ else
+ switch ( lookup_type )
+ {
+ case GPOS_LOOKUP_SINGLE:
+ Free_SinglePos( &st->st.gpos.single, memory );
+ break;
+
+ case GPOS_LOOKUP_PAIR:
+ Free_PairPos( &st->st.gpos.pair, memory );
+ break;
+
+ case GPOS_LOOKUP_CURSIVE:
+ Free_CursivePos( &st->st.gpos.cursive, memory );
+ break;
+
+ case GPOS_LOOKUP_MARKBASE:
+ Free_MarkBasePos( &st->st.gpos.markbase, memory );
+ break;
+
+ case GPOS_LOOKUP_MARKLIG:
+ Free_MarkLigPos( &st->st.gpos.marklig, memory );
+ break;
+
+ case GPOS_LOOKUP_MARKMARK:
+ Free_MarkMarkPos( &st->st.gpos.markmark, memory );
+ break;
+
+ case GPOS_LOOKUP_CONTEXT:
+ Free_ContextPos( &st->st.gpos.context, memory );
+ break;
+
+ case GPOS_LOOKUP_CHAIN:
+ Free_ChainContextPos ( &st->st.gpos.chain, memory );
+ break;
+ }
+ }
+
+
+ /* Lookup */
+
+ static FT_Error Load_Lookup( TTO_Lookup* l,
+ FT_Stream stream,
+ TTO_Type type )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_SubTable* st;
+
+ FT_Bool is_extension = FALSE;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ l->LookupType = GET_UShort();
+ l->LookupFlag = GET_UShort();
+ count = l->SubTableCount = GET_UShort();
+
+ FORGET_Frame();
+
+ l->SubTable = NULL;
+
+ if ( ALLOC_ARRAY( l->SubTable, count, TTO_SubTable ) )
+ return error;
+
+ st = l->SubTable;
+
+ if ( ( type == GSUB && l->LookupType == GSUB_LOOKUP_EXTENSION ) ||
+ ( type == GPOS && l->LookupType == GPOS_LOOKUP_EXTENSION ) )
+ is_extension = TRUE;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+
+ if ( is_extension )
+ {
+ if ( FILE_Seek( new_offset ) || ACCESS_Frame( 8L ) )
+ goto Fail;
+
+ (void)GET_UShort(); /* format should be 1 */
+ l->LookupType = GET_UShort();
+ new_offset = GET_ULong() + base_offset;
+
+ FORGET_Frame();
+ }
+
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_SubTable( &st[n], stream,
+ type, l->LookupType ) ) != TT_Err_Ok )
+ goto Fail;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail:
+ for ( m = 0; m < n; m++ )
+ Free_SubTable( &st[m], type, l->LookupType, memory );
+
+ FREE( l->SubTable );
+ return error;
+ }
+
+
+ static void Free_Lookup( TTO_Lookup* l,
+ TTO_Type type,
+ FT_Memory memory)
+ {
+ FT_UShort n, count;
+
+ TTO_SubTable* st;
+
+
+ if ( l->SubTable )
+ {
+ count = l->SubTableCount;
+ st = l->SubTable;
+
+ for ( n = 0; n < count; n++ )
+ Free_SubTable( &st[n], type, l->LookupType, memory );
+
+ FREE( st );
+ }
+ }
+
+
+ /* LookupList */
+
+ FT_Error Load_LookupList( TTO_LookupList* ll,
+ FT_Stream stream,
+ TTO_Type type )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, m, count;
+ FT_ULong cur_offset, new_offset, base_offset;
+
+ TTO_Lookup* l;
+
+
+ base_offset = FILE_Pos();
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = ll->LookupCount = GET_UShort();
+
+ FORGET_Frame();
+
+ ll->Lookup = NULL;
+
+ if ( ALLOC_ARRAY( ll->Lookup, count, TTO_Lookup ) )
+ return error;
+ if ( ALLOC_ARRAY( ll->Properties, count, FT_UInt ) )
+ goto Fail2;
+
+ l = ll->Lookup;
+
+ for ( n = 0; n < count; n++ )
+ {
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail1;
+
+ new_offset = GET_UShort() + base_offset;
+
+ FORGET_Frame();
+
+ cur_offset = FILE_Pos();
+ if ( FILE_Seek( new_offset ) ||
+ ( error = Load_Lookup( &l[n], stream, type ) ) != TT_Err_Ok )
+ goto Fail1;
+ (void)FILE_Seek( cur_offset );
+ }
+
+ return TT_Err_Ok;
+
+ Fail1:
+ FREE( ll->Properties );
+
+ for ( m = 0; m < n; m++ )
+ Free_Lookup( &l[m], type, memory );
+
+ Fail2:
+ FREE( ll->Lookup );
+ return error;
+ }
+
+
+ void Free_LookupList( TTO_LookupList* ll,
+ TTO_Type type,
+ FT_Memory memory )
+ {
+ FT_UShort n, count;
+
+ TTO_Lookup* l;
+
+
+ FREE( ll->Properties );
+
+ if ( ll->Lookup )
+ {
+ count = ll->LookupCount;
+ l = ll->Lookup;
+
+ for ( n = 0; n < count; n++ )
+ Free_Lookup( &l[n], type, memory );
+
+ FREE( l );
+ }
+ }
+
+
+
+ /*****************************
+ * Coverage related functions
+ *****************************/
+
+
+ /* CoverageFormat1 */
+
+ static FT_Error Load_Coverage1( TTO_CoverageFormat1* cf1,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* ga;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cf1->GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cf1->GlyphArray = NULL;
+
+ if ( ALLOC_ARRAY( cf1->GlyphArray, count, FT_UShort ) )
+ return error;
+
+ ga = cf1->GlyphArray;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( cf1->GlyphArray );
+ return error;
+ }
+
+ for ( n = 0; n < count; n++ )
+ ga[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ static void Free_Coverage1( TTO_CoverageFormat1* cf1,
+ FT_Memory memory)
+ {
+ FREE( cf1->GlyphArray );
+ }
+
+
+ /* CoverageFormat2 */
+
+ static FT_Error Load_Coverage2( TTO_CoverageFormat2* cf2,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ TTO_RangeRecord* rr;
+
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cf2->RangeCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cf2->RangeRecord = NULL;
+
+ if ( ALLOC_ARRAY( cf2->RangeRecord, count, TTO_RangeRecord ) )
+ return error;
+
+ rr = cf2->RangeRecord;
+
+ if ( ACCESS_Frame( count * 6L ) )
+ goto Fail;
+
+ for ( n = 0; n < count; n++ )
+ {
+ rr[n].Start = GET_UShort();
+ rr[n].End = GET_UShort();
+ rr[n].StartCoverageIndex = GET_UShort();
+
+ /* sanity check; we are limited to 16bit integers */
+ if ( rr[n].Start > rr[n].End ||
+ ( rr[n].End - rr[n].Start + (long)rr[n].StartCoverageIndex ) >=
+ 0x10000L )
+ {
+ error = TTO_Err_Invalid_SubTable;
+ goto Fail;
+ }
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( cf2->RangeRecord );
+ return error;
+ }
+
+
+ static void Free_Coverage2( TTO_CoverageFormat2* cf2,
+ FT_Memory memory )
+ {
+ FREE( cf2->RangeRecord );
+ }
+
+
+ FT_Error Load_Coverage( TTO_Coverage* c,
+ FT_Stream stream )
+ {
+ FT_Error error;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ c->CoverageFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( c->CoverageFormat )
+ {
+ case 1:
+ return Load_Coverage1( &c->cf.cf1, stream );
+
+ case 2:
+ return Load_Coverage2( &c->cf.cf2, stream );
+
+ default:
+ return TTO_Err_Invalid_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+ void Free_Coverage( TTO_Coverage* c,
+ FT_Memory memory )
+ {
+ switch ( c->CoverageFormat )
+ {
+ case 1:
+ Free_Coverage1( &c->cf.cf1, memory );
+ break;
+
+ case 2:
+ Free_Coverage2( &c->cf.cf2, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Coverage_Index1( TTO_CoverageFormat1* cf1,
+ FT_UShort glyphID,
+ FT_UShort* index )
+ {
+ FT_UShort min, max, new_min, new_max, middle;
+
+ FT_UShort* array = cf1->GlyphArray;
+
+
+ /* binary search */
+
+ if ( cf1->GlyphCount == 0 )
+ return TTO_Err_Not_Covered;
+
+ new_min = 0;
+ new_max = cf1->GlyphCount - 1;
+
+ do
+ {
+ min = new_min;
+ max = new_max;
+
+ /* we use (min + max) / 2 = max - (max - min) / 2 to avoid
+ overflow and rounding errors */
+
+ middle = max - ( ( max - min ) >> 1 );
+
+ if ( glyphID == array[middle] )
+ {
+ *index = middle;
+ return TT_Err_Ok;
+ }
+ else if ( glyphID < array[middle] )
+ {
+ if ( middle == min )
+ break;
+ new_max = middle - 1;
+ }
+ else
+ {
+ if ( middle == max )
+ break;
+ new_min = middle + 1;
+ }
+ } while ( min < max );
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ static FT_Error Coverage_Index2( TTO_CoverageFormat2* cf2,
+ FT_UShort glyphID,
+ FT_UShort* index )
+ {
+ FT_UShort min, max, new_min, new_max, middle;
+
+ TTO_RangeRecord* rr = cf2->RangeRecord;
+
+
+ /* binary search */
+
+ if ( cf2->RangeCount == 0 )
+ return TTO_Err_Not_Covered;
+
+ new_min = 0;
+ new_max = cf2->RangeCount - 1;
+
+ do
+ {
+ min = new_min;
+ max = new_max;
+
+ /* we use (min + max) / 2 = max - (max - min) / 2 to avoid
+ overflow and rounding errors */
+
+ middle = max - ( ( max - min ) >> 1 );
+
+ if ( glyphID >= rr[middle].Start && glyphID <= rr[middle].End )
+ {
+ *index = rr[middle].StartCoverageIndex + glyphID - rr[middle].Start;
+ return TT_Err_Ok;
+ }
+ else if ( glyphID < rr[middle].Start )
+ {
+ if ( middle == min )
+ break;
+ new_max = middle - 1;
+ }
+ else
+ {
+ if ( middle == max )
+ break;
+ new_min = middle + 1;
+ }
+ } while ( min < max );
+
+ return TTO_Err_Not_Covered;
+ }
+
+
+ FT_Error Coverage_Index( TTO_Coverage* c,
+ FT_UShort glyphID,
+ FT_UShort* index )
+ {
+ switch ( c->CoverageFormat )
+ {
+ case 1:
+ return Coverage_Index1( &c->cf.cf1, glyphID, index );
+
+ case 2:
+ return Coverage_Index2( &c->cf.cf2, glyphID, index );
+
+ default:
+ return TTO_Err_Invalid_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+
+ /*************************************
+ * Class Definition related functions
+ *************************************/
+
+
+ /* ClassDefFormat1 */
+
+ static FT_Error Load_ClassDef1( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* cva;
+ FT_Bool* d;
+
+ TTO_ClassDefFormat1* cdf1;
+
+
+ cdf1 = &cd->cd.cd1;
+
+ if ( ACCESS_Frame( 4L ) )
+ return error;
+
+ cdf1->StartGlyph = GET_UShort();
+ count = cdf1->GlyphCount = GET_UShort();
+
+ FORGET_Frame();
+
+ /* sanity check; we are limited to 16bit integers */
+
+ if ( cdf1->StartGlyph + (long)count >= 0x10000L )
+ return TTO_Err_Invalid_SubTable;
+
+ cdf1->ClassValueArray = NULL;
+
+ if ( ALLOC_ARRAY( cdf1->ClassValueArray, count, FT_UShort ) )
+ return error;
+
+ d = cd->Defined;
+ cva = cdf1->ClassValueArray;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ goto Fail;
+
+ for ( n = 0; n < count; n++ )
+ {
+ cva[n] = GET_UShort();
+ if ( cva[n] >= limit )
+ {
+ error = TTO_Err_Invalid_SubTable;
+ goto Fail;
+ }
+ d[cva[n]] = TRUE;
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( cva );
+
+ return error;
+ }
+
+
+ static void Free_ClassDef1( TTO_ClassDefFormat1* cdf1,
+ FT_Memory memory )
+ {
+ FREE( cdf1->ClassValueArray );
+ }
+
+
+ /* ClassDefFormat2 */
+
+ static FT_Error Load_ClassDef2( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ TTO_ClassRangeRecord* crr;
+ FT_Bool* d;
+
+ TTO_ClassDefFormat2* cdf2;
+
+
+ cdf2 = &cd->cd.cd2;
+
+ if ( ACCESS_Frame( 2L ) )
+ return error;
+
+ count = cdf2->ClassRangeCount = GET_UShort();
+
+ FORGET_Frame();
+
+ cdf2->ClassRangeRecord = NULL;
+
+ if ( ALLOC_ARRAY( cdf2->ClassRangeRecord, count, TTO_ClassRangeRecord ) )
+ return error;
+
+ d = cd->Defined;
+ crr = cdf2->ClassRangeRecord;
+
+ if ( ACCESS_Frame( count * 6L ) )
+ goto Fail;
+
+ for ( n = 0; n < count; n++ )
+ {
+ crr[n].Start = GET_UShort();
+ crr[n].End = GET_UShort();
+ crr[n].Class = GET_UShort();
+
+ /* sanity check */
+
+ if ( crr[n].Start > crr[n].End ||
+ crr[n].Class >= limit )
+ {
+ error = TTO_Err_Invalid_SubTable;
+ goto Fail;
+ }
+ d[crr[n].Class] = TRUE;
+ }
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( crr );
+
+ return error;
+ }
+
+
+ static void Free_ClassDef2( TTO_ClassDefFormat2* cdf2,
+ FT_Memory memory )
+ {
+ FREE( cdf2->ClassRangeRecord );
+ }
+
+
+ /* ClassDefinition */
+
+ FT_Error Load_ClassDefinition( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+
+ if ( ALLOC_ARRAY( cd->Defined, limit, FT_Bool ) )
+ return error;
+
+ if ( ACCESS_Frame( 2L ) )
+ goto Fail;
+
+ cd->ClassFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ switch ( cd->ClassFormat )
+ {
+ case 1:
+ error = Load_ClassDef1( cd, limit, stream );
+ break;
+
+ case 2:
+ error = Load_ClassDef2( cd, limit, stream );
+ break;
+
+ default:
+ error = TTO_Err_Invalid_SubTable_Format;
+ break;
+ }
+
+ if ( error )
+ goto Fail;
+
+ cd->loaded = TRUE;
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( cd->Defined );
+ return error;
+ }
+
+
+ FT_Error Load_EmptyClassDefinition( TTO_ClassDefinition* cd,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+
+ if ( ALLOC_ARRAY( cd->Defined, 1, FT_Bool ) )
+ return error;
+
+ cd->ClassFormat = 1; /* Meaningless */
+ cd->Defined[0] = FALSE;
+
+ if ( ALLOC_ARRAY( cd->cd.cd1.ClassValueArray, 1, FT_UShort ) )
+ goto Fail;
+
+ return TT_Err_Ok;
+
+ Fail:
+ FREE( cd->Defined );
+ return error;
+ }
+
+ void Free_ClassDefinition( TTO_ClassDefinition* cd,
+ FT_Memory memory )
+ {
+ if ( !cd->loaded )
+ return;
+
+ FREE( cd->Defined );
+
+ switch ( cd->ClassFormat )
+ {
+ case 1:
+ Free_ClassDef1( &cd->cd.cd1, memory );
+ break;
+
+ case 2:
+ Free_ClassDef2( &cd->cd.cd2, memory );
+ break;
+ }
+ }
+
+
+ static FT_Error Get_Class1( TTO_ClassDefFormat1* cdf1,
+ FT_UShort glyphID,
+ FT_UShort* class,
+ FT_UShort* index )
+ {
+ FT_UShort* cva = cdf1->ClassValueArray;
+
+
+ if ( index )
+ *index = 0;
+
+ if ( glyphID >= cdf1->StartGlyph &&
+ glyphID <= cdf1->StartGlyph + cdf1->GlyphCount )
+ {
+ *class = cva[glyphID - cdf1->StartGlyph];
+ return TT_Err_Ok;
+ }
+ else
+ {
+ *class = 0;
+ return TTO_Err_Not_Covered;
+ }
+ }
+
+
+ /* we need the index value of the last searched class range record
+ in case of failure for constructed GDEF tables */
+
+ static FT_Error Get_Class2( TTO_ClassDefFormat2* cdf2,
+ FT_UShort glyphID,
+ FT_UShort* class,
+ FT_UShort* index )
+ {
+ FT_Error error = TT_Err_Ok;
+ FT_UShort min, max, new_min, new_max, middle;
+
+ TTO_ClassRangeRecord* crr = cdf2->ClassRangeRecord;
+
+
+ /* binary search */
+
+ if ( cdf2->ClassRangeCount == 0 )
+ {
+ *class = 0;
+ if ( index )
+ *index = 0;
+
+ return TTO_Err_Not_Covered;
+ }
+
+ new_min = 0;
+ new_max = cdf2->ClassRangeCount - 1;
+
+ do
+ {
+ min = new_min;
+ max = new_max;
+
+ /* we use (min + max) / 2 = max - (max - min) / 2 to avoid
+ overflow and rounding errors */
+
+ middle = max - ( ( max - min ) >> 1 );
+
+ if ( glyphID >= crr[middle].Start && glyphID <= crr[middle].End )
+ {
+ *class = crr[middle].Class;
+ error = TT_Err_Ok;
+ break;
+ }
+ else if ( glyphID < crr[middle].Start )
+ {
+ if ( middle == min )
+ {
+ *class = 0;
+ error = TTO_Err_Not_Covered;
+ break;
+ }
+ new_max = middle - 1;
+ }
+ else
+ {
+ if ( middle == max )
+ {
+ *class = 0;
+ error = TTO_Err_Not_Covered;
+ break;
+ }
+ new_min = middle + 1;
+ }
+ } while ( min < max );
+
+ if ( index )
+ *index = middle;
+
+ return error;
+ }
+
+
+ FT_Error Get_Class( TTO_ClassDefinition* cd,
+ FT_UShort glyphID,
+ FT_UShort* class,
+ FT_UShort* index )
+ {
+ switch ( cd->ClassFormat )
+ {
+ case 1:
+ return Get_Class1( &cd->cd.cd1, glyphID, class, index );
+
+ case 2:
+ return Get_Class2( &cd->cd.cd2, glyphID, class, index );
+
+ default:
+ return TTO_Err_Invalid_SubTable_Format;
+ }
+
+ return TT_Err_Ok; /* never reached */
+ }
+
+
+
+ /***************************
+ * Device related functions
+ ***************************/
+
+
+ FT_Error Load_Device( TTO_Device* d,
+ FT_Stream stream )
+ {
+ FT_Error error;
+ FT_Memory memory = stream->memory;
+
+ FT_UShort n, count;
+
+ FT_UShort* dv;
+
+
+ if ( ACCESS_Frame( 6L ) )
+ return error;
+
+ d->StartSize = GET_UShort();
+ d->EndSize = GET_UShort();
+ d->DeltaFormat = GET_UShort();
+
+ FORGET_Frame();
+
+ if ( d->StartSize > d->EndSize ||
+ d->DeltaFormat == 0 || d->DeltaFormat > 3 )
+ return TTO_Err_Invalid_SubTable;
+
+ d->DeltaValue = NULL;
+
+ count = ( ( d->EndSize - d->StartSize + 1 ) >>
+ ( 4 - d->DeltaFormat ) ) + 1;
+
+ if ( ALLOC_ARRAY( d->DeltaValue, count, FT_UShort ) )
+ return error;
+
+ if ( ACCESS_Frame( count * 2L ) )
+ {
+ FREE( d->DeltaValue );
+ return error;
+ }
+
+ dv = d->DeltaValue;
+
+ for ( n = 0; n < count; n++ )
+ dv[n] = GET_UShort();
+
+ FORGET_Frame();
+
+ return TT_Err_Ok;
+ }
+
+
+ void Free_Device( TTO_Device* d,
+ FT_Memory memory )
+ {
+ FREE( d->DeltaValue );
+ }
+
+
+ /* Since we have the delta values stored in compressed form, we must
+ uncompress it now. To simplify the interface, the function always
+ returns a meaningful value in `value'; the error is just for
+ information.
+ | |
+ format = 1: 0011223344556677|8899101112131415|...
+ | |
+ byte 1 byte 2
+
+ 00: (byte >> 14) & tqmask
+ 11: (byte >> 12) & tqmask
+ ...
+
+ tqmask = 0x0003
+ | |
+ format = 2: 0000111122223333|4444555566667777|...
+ | |
+ byte 1 byte 2
+
+ 0000: (byte >> 12) & tqmask
+ 1111: (byte >> 8) & tqmask
+ ...
+
+ tqmask = 0x000F
+ | |
+ format = 3: 0000000011111111|2222222233333333|...
+ | |
+ byte 1 byte 2
+
+ 00000000: (byte >> 8) & tqmask
+ 11111111: (byte >> 0) & tqmask
+ ....
+
+ tqmask = 0x00FF */
+
+ FT_Error Get_Device( TTO_Device* d,
+ FT_UShort size,
+ FT_Short* value )
+ {
+ FT_UShort byte, bits, tqmask, f, s;
+
+
+ f = d->DeltaFormat;
+
+ if ( d->DeltaValue && size >= d->StartSize && size <= d->EndSize )
+ {
+ s = size - d->StartSize;
+ byte = d->DeltaValue[s >> ( 4 - f )];
+ bits = byte >> ( 16 - ( ( s % ( 1 << ( 4 - f ) ) + 1 ) << f ) );
+ tqmask = 0xFFFF >> ( 16 - ( 1 << f ) );
+
+ *value = (FT_Short)( bits & tqmask );
+
+ /* conversion to a signed value */
+
+ if ( *value >= ( ( tqmask + 1 ) >> 1 ) )
+ *value -= tqmask + 1;
+
+ return TT_Err_Ok;
+ }
+ else
+ {
+ *value = 0;
+ return TTO_Err_Not_Covered;
+ }
+ }
+
+
+/* END */
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftxopen.h b/tqtinterface/qt4/src/3rdparty/opentype/ftxopen.h
new file mode 100644
index 0000000..59dcf25
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftxopen.h
@@ -0,0 +1,317 @@
+/*******************************************************************
+ *
+ * ftxopen.h
+ *
+ * TrueType Open support.
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ * This file should be included by the application. Nevertheless,
+ * the table specific APIs (and structures) are located in files like
+ * ftxgsub.h or ftxgpos.h; these header files are read by ftxopen.h .
+ *
+ ******************************************************************/
+
+#ifndef FTXOPEN_H
+#define FTXOPEN_H
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EXPORT_DEF
+#define EXPORT_FUNC
+
+#define TTO_MAX_NESTING_LEVEL 100
+
+#define TTO_Err_Invalid_SubTable_Format 0x1000
+#define TTO_Err_Invalid_SubTable 0x1001
+#define TTO_Err_Not_Covered 0x1002
+#define TTO_Err_Too_Many_Nested_Contexts 0x1003
+#define TTO_Err_No_MM_Interpreter 0x1004
+#define TTO_Err_Empty_Script 0x1005
+
+
+ /* Script list related structures */
+
+ struct TTO_LangSys_
+ {
+ FT_UShort LookupOrderOffset; /* always 0 for TT Open 1.0 */
+ FT_UShort ReqFeatureIndex; /* required FeatureIndex */
+ FT_UShort FeatureCount; /* number of Feature indices */
+ FT_UShort* FeatureIndex; /* array of Feature indices */
+ };
+
+ typedef struct TTO_LangSys_ TTO_LangSys;
+
+
+ struct TTO_LangSysRecord_
+ {
+ FT_ULong LangSysTag; /* LangSysTag identifier */
+ TTO_LangSys LangSys; /* LangSys table */
+ };
+
+ typedef struct TTO_LangSysRecord_ TTO_LangSysRecord;
+
+
+ struct TTO_Script_
+ {
+ TTO_LangSys DefaultLangSys; /* DefaultLangSys table */
+ FT_UShort LangSysCount; /* number of LangSysRecords */
+ TTO_LangSysRecord* LangSysRecord; /* array of LangSysRecords */
+ };
+
+ typedef struct TTO_Script_ TTO_Script;
+
+
+ struct TTO_ScriptRecord_
+ {
+ FT_ULong ScriptTag; /* ScriptTag identifier */
+ TTO_Script Script; /* Script table */
+ };
+
+ typedef struct TTO_ScriptRecord_ TTO_ScriptRecord;
+
+
+ struct TTO_ScriptList_
+ {
+ FT_UShort ScriptCount; /* number of ScriptRecords */
+ TTO_ScriptRecord* ScriptRecord; /* array of ScriptRecords */
+ };
+
+ typedef struct TTO_ScriptList_ TTO_ScriptList;
+
+
+ /* Feature list related structures */
+
+ struct TTO_Feature_
+ {
+ FT_UShort FeatureParams; /* always 0 for TT Open 1.0 */
+ FT_UShort LookupListCount; /* number of LookupList indices */
+ FT_UShort* LookupListIndex; /* array of LookupList indices */
+ };
+
+ typedef struct TTO_Feature_ TTO_Feature;
+
+
+ struct TTO_FeatureRecord_
+ {
+ FT_ULong FeatureTag; /* FeatureTag identifier */
+ TTO_Feature Feature; /* Feature table */
+ };
+
+ typedef struct TTO_FeatureRecord_ TTO_FeatureRecord;
+
+
+ struct TTO_FeatureList_
+ {
+ FT_UShort FeatureCount; /* number of FeatureRecords */
+ TTO_FeatureRecord* FeatureRecord; /* array of FeatureRecords */
+ FT_UShort* ApplyOrder; /* order to apply features */
+ FT_UShort ApplyCount; /* number of elements in ApplyOrder */
+ };
+
+ typedef struct TTO_FeatureList_ TTO_FeatureList;
+
+
+ /* Lookup list related structures */
+
+ struct TTO_SubTable_; /* defined below after inclusion
+ of ftxgsub.h and ftxgpos.h */
+ typedef struct TTO_SubTable_ TTO_SubTable;
+
+
+ struct TTO_Lookup_
+ {
+ FT_UShort LookupType; /* Lookup type */
+ FT_UShort LookupFlag; /* Lookup qualifiers */
+ FT_UShort SubTableCount; /* number of SubTables */
+ TTO_SubTable* SubTable; /* array of SubTables */
+ };
+
+ typedef struct TTO_Lookup_ TTO_Lookup;
+
+
+ /* The `Properties' field is not defined in the TTO specification but
+ is needed for processing lookups. If properties[n] is > 0, the
+ functions TT_GSUB_Apply_String() resp. TT_GPOS_Apply_String() will
+ process Lookup[n] for glyphs which have the specific bit not set in
+ the `properties' field of the input string object. */
+
+ struct TTO_LookupList_
+ {
+ FT_UShort LookupCount; /* number of Lookups */
+ TTO_Lookup* Lookup; /* array of Lookup records */
+ FT_UInt* Properties; /* array of flags */
+ };
+
+ typedef struct TTO_LookupList_ TTO_LookupList;
+
+
+ /* Possible LookupFlag bit masks. `IGNORE_SPECIAL_MARKS' comes from the
+ OpenType 1.2 specification; RIGHT_TO_LEFT has been (re)introduced in
+ OpenType 1.3 -- if set, the last glyph in a cursive attachment
+ sequence has to be positioned on the baseline -- regardless of the
+ writing direction. */
+
+#define RIGHT_TO_LEFT 0x0001
+#define IGNORE_BASE_GLYPHS 0x0002
+#define IGNORE_LIGATURES 0x0004
+#define IGNORE_MARKS 0x0008
+#define IGNORE_SPECIAL_MARKS 0xFF00
+
+
+ struct TTO_CoverageFormat1_
+ {
+ FT_UShort GlyphCount; /* number of glyphs in GlyphArray */
+ FT_UShort* GlyphArray; /* array of glyph IDs */
+ };
+
+ typedef struct TTO_CoverageFormat1_ TTO_CoverageFormat1;
+
+
+ struct TTO_RangeRecord_
+ {
+ FT_UShort Start; /* first glyph ID in the range */
+ FT_UShort End; /* last glyph ID in the range */
+ FT_UShort StartCoverageIndex; /* coverage index of first
+ glyph ID in the range */
+ };
+
+ typedef struct TTO_RangeRecord_ TTO_RangeRecord;
+
+
+ struct TTO_CoverageFormat2_
+ {
+ FT_UShort RangeCount; /* number of RangeRecords */
+ TTO_RangeRecord* RangeRecord; /* array of RangeRecords */
+ };
+
+ typedef struct TTO_CoverageFormat2_ TTO_CoverageFormat2;
+
+
+ struct TTO_Coverage_
+ {
+ FT_UShort CoverageFormat; /* 1 or 2 */
+
+ union
+ {
+ TTO_CoverageFormat1 cf1;
+ TTO_CoverageFormat2 cf2;
+ } cf;
+ };
+
+ typedef struct TTO_Coverage_ TTO_Coverage;
+
+
+ struct TTO_ClassDefFormat1_
+ {
+ FT_UShort StartGlyph; /* first glyph ID of the
+ ClassValueArray */
+ FT_UShort GlyphCount; /* size of the ClassValueArray */
+ FT_UShort* ClassValueArray; /* array of class values */
+ };
+
+ typedef struct TTO_ClassDefFormat1_ TTO_ClassDefFormat1;
+
+
+ struct TTO_ClassRangeRecord_
+ {
+ FT_UShort Start; /* first glyph ID in the range */
+ FT_UShort End; /* last glyph ID in the range */
+ FT_UShort Class; /* applied to all glyphs in range */
+ };
+
+ typedef struct TTO_ClassRangeRecord_ TTO_ClassRangeRecord;
+
+
+ struct TTO_ClassDefFormat2_
+ {
+ FT_UShort ClassRangeCount;
+ /* number of ClassRangeRecords */
+ TTO_ClassRangeRecord* ClassRangeRecord;
+ /* array of ClassRangeRecords */
+ };
+
+ typedef struct TTO_ClassDefFormat2_ TTO_ClassDefFormat2;
+
+
+ /* The `Defined' field is not defined in the TTO specification but
+ apparently needed for processing fonts like trado.ttf: This font
+ refers to a class which tqcontains not a single element. We map such
+ classes to class 0. */
+
+ struct TTO_ClassDefinition_
+ {
+ FT_Bool loaded;
+
+ FT_Bool* Defined; /* array of Booleans.
+ If Defined[n] is FALSE,
+ class n tqcontains no glyphs. */
+ FT_UShort ClassFormat; /* 1 or 2 */
+
+ union
+ {
+ TTO_ClassDefFormat1 cd1;
+ TTO_ClassDefFormat2 cd2;
+ } cd;
+ };
+
+ typedef struct TTO_ClassDefinition_ TTO_ClassDefinition;
+
+
+ struct TTO_Device_
+ {
+ FT_UShort StartSize; /* smallest size to correct */
+ FT_UShort EndSize; /* largest size to correct */
+ FT_UShort DeltaFormat; /* DeltaValue array data format:
+ 1, 2, or 3 */
+ FT_UShort* DeltaValue; /* array of compressed data */
+ };
+
+ typedef struct TTO_Device_ TTO_Device;
+
+
+#include "otlbuffer.h"
+#include "ftxgdef.h"
+#include "ftxgsub.h"
+#include "ftxgpos.h"
+
+
+ struct TTO_SubTable_
+ {
+ union
+ {
+ TTO_GSUB_SubTable gsub;
+ TTO_GPOS_SubTable gpos;
+ } st;
+ };
+
+
+ enum TTO_Type_
+ {
+ GSUB,
+ GPOS
+ };
+
+ typedef enum TTO_Type_ TTO_Type;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FTXOPEN_H */
+
+
+/* END */
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftxopenf.h b/tqtinterface/qt4/src/3rdparty/opentype/ftxopenf.h
new file mode 100644
index 0000000..4c5998e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftxopenf.h
@@ -0,0 +1,163 @@
+/*******************************************************************
+ *
+ * ftxopenf.h
+ *
+ * internal TrueType Open functions
+ *
+ * Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ ******************************************************************/
+
+#ifndef FTXOPENF_H
+#define FTXOPENF_H
+
+#include "ftxopen.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* functions from ftxopen.c */
+
+ FT_Error Load_ScriptList( TTO_ScriptList* sl,
+ FT_Stream stream );
+ FT_Error Load_FeatureList( TTO_FeatureList* fl,
+ FT_Stream input );
+ FT_Error Load_LookupList( TTO_LookupList* ll,
+ FT_Stream input,
+ TTO_Type type );
+
+ FT_Error Load_Coverage( TTO_Coverage* c,
+ FT_Stream input );
+ FT_Error Load_ClassDefinition( TTO_ClassDefinition* cd,
+ FT_UShort limit,
+ FT_Stream input );
+ FT_Error Load_EmptyClassDefinition( TTO_ClassDefinition* cd,
+ FT_Stream input );
+ FT_Error Load_Device( TTO_Device* d,
+ FT_Stream input );
+
+ void Free_ScriptList( TTO_ScriptList* sl,
+ FT_Memory memory );
+ void Free_FeatureList( TTO_FeatureList* fl,
+ FT_Memory memory );
+ void Free_LookupList( TTO_LookupList* ll,
+ TTO_Type type,
+ FT_Memory memory );
+
+ void Free_Coverage( TTO_Coverage* c,
+ FT_Memory memory );
+ void Free_ClassDefinition( TTO_ClassDefinition* cd,
+ FT_Memory memory );
+ void Free_Device( TTO_Device* d,
+ FT_Memory memory );
+
+
+ /* functions from ftxgsub.c */
+
+ FT_Error Load_SingleSubst( TTO_SingleSubst* ss,
+ FT_Stream input );
+ FT_Error Load_MultipleSubst( TTO_MultipleSubst* ms,
+ FT_Stream input );
+ FT_Error Load_AlternateSubst( TTO_AlternateSubst* as,
+ FT_Stream input );
+ FT_Error Load_LigatureSubst( TTO_LigatureSubst* ls,
+ FT_Stream input );
+ FT_Error Load_ContextSubst( TTO_ContextSubst* cs,
+ FT_Stream input );
+ FT_Error Load_ChainContextSubst( TTO_ChainContextSubst* ccs,
+ FT_Stream input );
+
+ void Free_SingleSubst( TTO_SingleSubst* ss,
+ FT_Memory memory );
+ void Free_MultipleSubst( TTO_MultipleSubst* ms,
+ FT_Memory memory );
+ void Free_AlternateSubst( TTO_AlternateSubst* as,
+ FT_Memory memory );
+ void Free_LigatureSubst( TTO_LigatureSubst* ls,
+ FT_Memory memory );
+ void Free_ContextSubst( TTO_ContextSubst* cs,
+ FT_Memory memory );
+ void Free_ChainContextSubst( TTO_ChainContextSubst* ccs,
+ FT_Memory memory );
+
+
+ /* functions from ftxgpos.c */
+
+ FT_Error Load_SinglePos( TTO_SinglePos* sp,
+ FT_Stream input );
+ FT_Error Load_PairPos( TTO_PairPos* pp,
+ FT_Stream input );
+ FT_Error Load_CursivePos( TTO_CursivePos* cp,
+ FT_Stream input );
+ FT_Error Load_MarkBasePos( TTO_MarkBasePos* mbp,
+ FT_Stream input );
+ FT_Error Load_MarkLigPos( TTO_MarkLigPos* mlp,
+ FT_Stream input );
+ FT_Error Load_MarkMarkPos( TTO_MarkMarkPos* mmp,
+ FT_Stream input );
+ FT_Error Load_ContextPos( TTO_ContextPos* cp,
+ FT_Stream input );
+ FT_Error Load_ChainContextPos( TTO_ChainContextPos* ccp,
+ FT_Stream input );
+
+ void Free_SinglePos( TTO_SinglePos* sp,
+ FT_Memory memory );
+ void Free_PairPos( TTO_PairPos* pp,
+ FT_Memory memory );
+ void Free_CursivePos( TTO_CursivePos* cp,
+ FT_Memory memory );
+ void Free_MarkBasePos( TTO_MarkBasePos* mbp,
+ FT_Memory memory );
+ void Free_MarkLigPos( TTO_MarkLigPos* mlp,
+ FT_Memory memory );
+ void Free_MarkMarkPos( TTO_MarkMarkPos* mmp,
+ FT_Memory memory );
+ void Free_ContextPos( TTO_ContextPos* cp,
+ FT_Memory memory );
+ void Free_ChainContextPos( TTO_ChainContextPos* ccp,
+ FT_Memory memory );
+ /* query functions */
+
+ FT_Error Coverage_Index( TTO_Coverage* c,
+ FT_UShort glyphID,
+ FT_UShort* index );
+ FT_Error Get_Class( TTO_ClassDefinition* cd,
+ FT_UShort glyphID,
+ FT_UShort* class,
+ FT_UShort* index );
+ FT_Error Get_Device( TTO_Device* d,
+ FT_UShort size,
+ FT_Short* value );
+
+
+ /* functions from ftxgdef.c */
+
+ FT_Error Add_Glyph_Property( TTO_GDEFHeader* gdef,
+ FT_UShort glyphID,
+ FT_UShort property );
+
+ FT_Error Check_Property( TTO_GDEFHeader* gdef,
+ OTL_GlyphItem item,
+ FT_UShort flags,
+ FT_UShort* property );
+
+#define CHECK_Property( gdef, index, flags, property ) \
+ ( ( error = Check_Property( (gdef), (index), (flags), \
+ (property) ) ) != TT_Err_Ok )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FTXOPENF_H */
+
+
+/* END */
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/ftxopentype.c b/tqtinterface/qt4/src/3rdparty/opentype/ftxopentype.c
new file mode 100644
index 0000000..d1503ff
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/ftxopentype.c
@@ -0,0 +1,14 @@
+/* we need to all the OT support into one file to get efficient inlining */
+
+#if defined(__GNUC__)
+#define inline __inline__
+#else
+#define inline
+#endif
+
+#include "ftglue.c"
+#include "ftxopen.c"
+#include "ftxgdef.c"
+#include "ftxgpos.c"
+#include "ftxgsub.c"
+#include "otlbuffer.c"
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/otlbuffer.c b/tqtinterface/qt4/src/3rdparty/opentype/otlbuffer.c
new file mode 100644
index 0000000..4132216
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/otlbuffer.c
@@ -0,0 +1,235 @@
+/* otlbuffer.c: Buffer of glyphs for substitution/positioning
+ *
+ * Copyright 2004 Red Hat Software
+ *
+ * Portions Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ */
+#include <otlbuffer.h>
+
+/* To get the gcc-3.3 strict-aliasing compatible versions
+ * FREE/REALLOC_ARRAY/etc. rather than the FT_* versions
+ * that
+ */
+#include "ftglue.h"
+
+ static FT_Error
+ otl_buffer_ensure( OTL_Buffer buffer,
+ FT_ULong size )
+ {
+ FT_Memory memory = buffer->memory;
+ FT_ULong new_allocated = buffer->allocated;
+
+ if (size > new_allocated)
+ {
+ FT_Error error;
+
+ while (size > new_allocated)
+ new_allocated += (new_allocated >> 1) + 8;
+
+ if ( REALLOC_ARRAY( buffer->in_string, buffer->allocated, new_allocated, OTL_GlyphItemRec ) )
+ return error;
+ if ( REALLOC_ARRAY( buffer->out_string, buffer->allocated, new_allocated, OTL_GlyphItemRec ) )
+ return error;
+ if ( REALLOC_ARRAY( buffer->positions, buffer->allocated, new_allocated, OTL_PositionRec ) )
+ return error;
+
+ buffer->allocated = new_allocated;
+ }
+
+ return FT_Err_Ok;
+ }
+
+ FT_Error
+ otl_buffer_new( FT_Memory memory,
+ OTL_Buffer *buffer )
+ {
+ FT_Error error;
+
+ if ( ALLOC( *buffer, sizeof( OTL_BufferRec ) ) )
+ return error;
+
+ (*buffer)->memory = memory;
+ (*buffer)->in_length = 0;
+ (*buffer)->out_length = 0;
+ (*buffer)->allocated = 0;
+ (*buffer)->in_pos = 0;
+ (*buffer)->out_pos = 0;
+
+ (*buffer)->in_string = NULL;
+ (*buffer)->out_string = NULL;
+ (*buffer)->positions = NULL;
+ (*buffer)->max_ligID = 0;
+
+ return FT_Err_Ok;
+ }
+
+ FT_Error
+ otl_buffer_swap( OTL_Buffer buffer )
+ {
+ OTL_GlyphItem tmp_string;
+
+ tmp_string = buffer->in_string;
+ buffer->in_string = buffer->out_string;
+ buffer->out_string = tmp_string;
+
+ buffer->in_length = buffer->out_length;
+ buffer->out_length = 0;
+
+ buffer->in_pos = 0;
+ buffer->out_pos = 0;
+
+ return FT_Err_Ok;
+ }
+
+ FT_Error
+ otl_buffer_free( OTL_Buffer buffer )
+ {
+ FT_Memory memory = buffer->memory;
+
+ FREE( buffer->in_string );
+ FREE( buffer->out_string );
+ FREE( buffer->positions );
+ FREE( buffer );
+
+ return FT_Err_Ok;
+ }
+
+ FT_Error
+ otl_buffer_clear( OTL_Buffer buffer )
+ {
+ buffer->in_length = 0;
+ buffer->out_length = 0;
+ buffer->in_pos = 0;
+ buffer->out_pos = 0;
+
+ return FT_Err_Ok;
+ }
+
+ FT_Error
+ otl_buffer_add_glyph( OTL_Buffer buffer,
+ FT_UInt glyph_index,
+ FT_UInt properties,
+ FT_UInt cluster )
+ {
+ FT_Error error;
+ OTL_GlyphItem glyph;
+
+ error = otl_buffer_ensure( buffer, buffer->in_length + 1 );
+ if ( error )
+ return error;
+
+ glyph = &buffer->in_string[buffer->in_length];
+ glyph->gindex = glyph_index;
+ glyph->properties = properties;
+ glyph->cluster = cluster;
+ glyph->component = 0;
+ glyph->ligID = 0;
+ glyph->gproperties = OTL_GLYPH_PROPERTIES_UNKNOWN;
+
+ buffer->in_length++;
+
+ return FT_Err_Ok;
+ }
+
+ /* The following function copies `num_out' elements from `glyph_data'
+ to `buffer->out_string', advancing the in array pointer in the structure
+ by `num_in' elements, and the out array pointer by `num_out' elements.
+ Finally, it sets the `length' field of `out' equal to
+ `pos' of the `out' structure.
+
+ If `component' is 0xFFFF, the component value from buffer->in_pos
+ will copied `num_out' times, otherwise `component' itself will
+ be used to fill the `component' fields.
+
+ If `ligID' is 0xFFFF, the ligID value from buffer->in_pos
+ will copied `num_out' times, otherwise `ligID' itself will
+ be used to fill the `ligID' fields.
+
+ The properties for all tqreplacement glyphs are taken
+ from the glyph at position `buffer->in_pos'.
+
+ The cluster value for the glyph at position buffer->in_pos is used
+ for all tqreplacement glyphs */
+ FT_Error
+ otl_buffer_add_output_glyphs( OTL_Buffer buffer,
+ FT_UShort num_in,
+ FT_UShort num_out,
+ FT_UShort *glyph_data,
+ FT_UShort component,
+ FT_UShort ligID )
+ {
+ FT_Error error;
+ FT_UShort i;
+ FT_UInt properties;
+ FT_UInt cluster;
+
+ error = otl_buffer_ensure( buffer, buffer->out_pos + num_out );
+ if ( error )
+ return error;
+
+ properties = buffer->in_string[buffer->in_pos].properties;
+ cluster = buffer->in_string[buffer->in_pos].cluster;
+ if ( component == 0xFFFF )
+ component = buffer->in_string[buffer->in_pos].component;
+ if ( ligID == 0xFFFF )
+ ligID = buffer->in_string[buffer->in_pos].ligID;
+
+ for ( i = 0; i < num_out; i++ )
+ {
+ OTL_GlyphItem item = &buffer->out_string[buffer->out_pos + i];
+
+ item->gindex = glyph_data[i];
+ item->properties = properties;
+ item->cluster = cluster;
+ item->component = component;
+ item->ligID = ligID;
+ item->gproperties = OTL_GLYPH_PROPERTIES_UNKNOWN;
+ }
+
+ buffer->in_pos += num_in;
+ buffer->out_pos += num_out;
+
+ buffer->out_length = buffer->out_pos;
+
+ return FT_Err_Ok;
+ }
+
+ FT_Error
+ otl_buffer_add_output_glyph( OTL_Buffer buffer,
+ FT_UInt glyph_index,
+ FT_UShort component,
+ FT_UShort ligID )
+ {
+ FT_UShort glyph_data = glyph_index;
+
+ return otl_buffer_add_output_glyphs ( buffer, 1, 1,
+ &glyph_data, component, ligID );
+ }
+
+ FT_Error
+ otl_buffer_copy_output_glyph ( OTL_Buffer buffer )
+ {
+ FT_Error error;
+
+ error = otl_buffer_ensure( buffer, buffer->out_pos + 1 );
+ if ( error )
+ return error;
+
+ buffer->out_string[buffer->out_pos++] = buffer->in_string[buffer->in_pos++];
+ buffer->out_length = buffer->out_pos;
+
+ return FT_Err_Ok;
+ }
+
+ FT_UShort
+ otl_buffer_allocate_ligid( OTL_Buffer buffer )
+ {
+ return buffer->max_ligID++;
+ }
diff --git a/tqtinterface/qt4/src/3rdparty/opentype/otlbuffer.h b/tqtinterface/qt4/src/3rdparty/opentype/otlbuffer.h
new file mode 100644
index 0000000..bb32da8
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/opentype/otlbuffer.h
@@ -0,0 +1,129 @@
+/* otlbuffer.h: Buffer of glyphs for substitution/positioning
+ *
+ * Copyrigh 2004 Red Hat Software
+ *
+ * Portions Copyright 1996-2000 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used
+ * modified and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT. By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ */
+#ifndef OTL_BUFFER_H
+#define OTL_BUFFER_H
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+FT_BEGIN_HEADER
+
+#define OTL_GLYPH_PROPERTIES_UNKNOWN 0xFFFF
+
+#define IN_GLYPH( pos ) buffer->in_string[(pos)].gindex
+#define IN_ITEM( pos ) (&buffer->in_string[(pos)])
+#define IN_CURGLYPH() buffer->in_string[buffer->in_pos].gindex
+#define IN_CURITEM() (&buffer->in_string[buffer->in_pos])
+#define IN_PROPERTIES( pos ) buffer->in_string[(pos)].properties
+#define IN_LIGID( pos ) buffer->in_string[(pos)].ligID
+#define IN_COMPONENT( pos ) (buffer->in_string[(pos)].component)
+
+#define OUT_GLYPH( pos ) buffer->out_string[(pos)].gindex
+#define OUT_ITEM( pos ) (&buffer->out_string[(pos)])
+
+#define POSITION( pos ) (&buffer->positions[(pos)])
+
+#define ADD_String( buffer, num_in, num_out, glyph_data, component, ligID ) \
+ ( ( error = otl_buffer_add_output_glyphs( (buffer), \
+ (num_in), (num_out), \
+ (glyph_data), (component), (ligID) \
+ ) ) != TT_Err_Ok )
+#define ADD_Glyph( buffer, glyph_index, component, ligID ) \
+ ( ( error = otl_buffer_add_output_glyph( (buffer), \
+ (glyph_index), (component), (ligID) \
+ ) ) != TT_Err_Ok )
+
+ typedef struct OTL_GlyphItemRec_ {
+ FT_UInt gindex;
+ FT_UInt properties;
+ FT_UInt cluster;
+ FT_UShort component;
+ FT_UShort ligID;
+ FT_UShort gproperties;
+ } OTL_GlyphItemRec, *OTL_GlyphItem;
+
+ typedef struct OTL_PositionRec_ {
+ FT_Pos x_pos;
+ FT_Pos y_pos;
+ FT_Pos x_advance;
+ FT_Pos y_advance;
+ FT_UShort back; /* number of glyphs to go back
+ for drawing current glyph */
+ FT_Bool new_advance; /* if set, the advance width values are
+ absolute, i.e., they won't be
+ added to the original glyph's value
+ but rather tqreplace them. */
+ FT_Short cursive_chain; /* character to which this connects,
+ may be positive or negative; used
+ only internally */
+ } OTL_PositionRec, *OTL_Position;
+
+
+ typedef struct OTL_BufferRec_{
+ FT_Memory memory;
+ FT_ULong allocated;
+
+ FT_ULong in_length;
+ FT_ULong out_length;
+ FT_ULong in_pos;
+ FT_ULong out_pos;
+
+ OTL_GlyphItem in_string;
+ OTL_GlyphItem out_string;
+ OTL_Position positions;
+ FT_UShort max_ligID;
+ } OTL_BufferRec, *OTL_Buffer;
+
+ FT_Error
+ otl_buffer_new( FT_Memory memory,
+ OTL_Buffer *buffer );
+
+ FT_Error
+ otl_buffer_swap( OTL_Buffer buffer );
+
+ FT_Error
+ otl_buffer_free( OTL_Buffer buffer );
+
+ FT_Error
+ otl_buffer_clear( OTL_Buffer buffer );
+
+ FT_Error
+ otl_buffer_add_glyph( OTL_Buffer buffer,
+ FT_UInt glyph_index,
+ FT_UInt properties,
+ FT_UInt cluster );
+
+ FT_Error
+ otl_buffer_add_output_glyphs( OTL_Buffer buffer,
+ FT_UShort num_in,
+ FT_UShort num_out,
+ FT_UShort *glyph_data,
+ FT_UShort component,
+ FT_UShort ligID );
+
+ FT_Error
+ otl_buffer_add_output_glyph ( OTL_Buffer buffer,
+ FT_UInt glyph_index,
+ FT_UShort component,
+ FT_UShort ligID );
+
+ FT_Error
+ otl_buffer_copy_output_glyph ( OTL_Buffer buffer );
+
+ FT_UShort
+ otl_buffer_allocate_ligid( OTL_Buffer buffer );
+
+FT_END_HEADER
+
+#endif
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/attach.c b/tqtinterface/qt4/src/3rdparty/sqlite/attach.c
new file mode 100644
index 0000000..f1e6f7a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/attach.c
@@ -0,0 +1,308 @@
+/*
+** 2003 April 6
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains code used to implement the ATTACH and DETACH commands.
+**
+** $Id: attach.c,v 1.10 2004/02/12 18:46:39 drh Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** This routine is called by the parser to process an ATTACH statement:
+**
+** ATTACH DATABASE filename AS dbname
+**
+** The pFilename and pDbname arguments are the tokens that define the
+** filename and dbname in the ATTACH statement.
+*/
+void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){
+ Db *aNew;
+ int rc, i;
+ char *zFile, *zName;
+ sqlite *db;
+ Vdbe *v;
+
+ v = sqliteGetVdbe(pParse);
+ sqliteVdbeAddOp(v, OP_Halt, 0, 0);
+ if( pParse->explain ) return;
+ db = pParse->db;
+ if( db->file_format<4 ){
+ sqliteErrorMsg(pParse, "cannot attach auxiliary databases to an "
+ "older format master database", 0);
+ pParse->rc = STQLITE_ERROR;
+ return;
+ }
+ if( db->nDb>=MAX_ATTACHED+2 ){
+ sqliteErrorMsg(pParse, "too many attached databases - max %d",
+ MAX_ATTACHED);
+ pParse->rc = STQLITE_ERROR;
+ return;
+ }
+
+ zFile = 0;
+ sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0);
+ if( zFile==0 ) return;
+ sqliteDequote(zFile);
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ if( sqliteAuthCheck(pParse, STQLITE_ATTACH, zFile, 0, 0)!=STQLITE_OK ){
+ sqliteFree(zFile);
+ return;
+ }
+#endif /* STQLITE_OMIT_AUTHORIZATION */
+
+ zName = 0;
+ sqliteSetNString(&zName, pDbname->z, pDbname->n, 0);
+ if( zName==0 ) return;
+ sqliteDequote(zName);
+ for(i=0; i<db->nDb; i++){
+ if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){
+ sqliteErrorMsg(pParse, "database %z is already in use", zName);
+ pParse->rc = STQLITE_ERROR;
+ sqliteFree(zFile);
+ return;
+ }
+ }
+
+ if( db->aDb==db->aDbStatic ){
+ aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
+ if( aNew==0 ) return;
+ memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
+ }else{
+ aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
+ if( aNew==0 ) return;
+ }
+ db->aDb = aNew;
+ aNew = &db->aDb[db->nDb++];
+ memset(aNew, 0, sizeof(*aNew));
+ sqliteHashInit(&aNew->tblHash, STQLITE_HASH_STRING, 0);
+ sqliteHashInit(&aNew->idxHash, STQLITE_HASH_STRING, 0);
+ sqliteHashInit(&aNew->trigHash, STQLITE_HASH_STRING, 0);
+ sqliteHashInit(&aNew->aFKey, STQLITE_HASH_STRING, 1);
+ aNew->zName = zName;
+ rc = sqliteBtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
+ if( rc ){
+ sqliteErrorMsg(pParse, "unable to open database: %s", zFile);
+ }
+#if STQLITE_HAS_CODEC
+ {
+ extern int sqliteCodecAttach(sqlite*, int, void*, int);
+ char *zKey = 0;
+ int nKey;
+ if( pKey && pKey->z && pKey->n ){
+ sqliteSetNString(&zKey, pKey->z, pKey->n, 0);
+ sqliteDequote(zKey);
+ nKey = strlen(zKey);
+ }else{
+ zKey = 0;
+ nKey = 0;
+ }
+ sqliteCodecAttach(db, db->nDb-1, zKey, nKey);
+ }
+#endif
+ sqliteFree(zFile);
+ db->flags &= ~STQLITE_Initialized;
+ if( pParse->nErr ) return;
+ if( rc==STQLITE_OK ){
+ rc = sqliteInit(pParse->db, &pParse->zErrMsg);
+ }
+ if( rc ){
+ int i = db->nDb - 1;
+ assert( i>=2 );
+ if( db->aDb[i].pBt ){
+ sqliteBtreeClose(db->aDb[i].pBt);
+ db->aDb[i].pBt = 0;
+ }
+ sqliteResetInternalSchema(db, 0);
+ pParse->nErr++;
+ pParse->rc = STQLITE_ERROR;
+ }
+}
+
+/*
+** This routine is called by the parser to process a DETACH statement:
+**
+** DETACH DATABASE dbname
+**
+** The pDbname argument is the name of the database in the DETACH statement.
+*/
+void sqliteDetach(Parse *pParse, Token *pDbname){
+ int i;
+ sqlite *db;
+ Vdbe *v;
+
+ v = sqliteGetVdbe(pParse);
+ sqliteVdbeAddOp(v, OP_Halt, 0, 0);
+ if( pParse->explain ) return;
+ db = pParse->db;
+ for(i=0; i<db->nDb; i++){
+ if( db->aDb[i].pBt==0 || db->aDb[i].zName==0 ) continue;
+ if( strlen(db->aDb[i].zName)!=pDbname->n ) continue;
+ if( sqliteStrNICmp(db->aDb[i].zName, pDbname->z, pDbname->n)==0 ) break;
+ }
+ if( i>=db->nDb ){
+ sqliteErrorMsg(pParse, "no such database: %T", pDbname);
+ return;
+ }
+ if( i<2 ){
+ sqliteErrorMsg(pParse, "cannot detach database %T", pDbname);
+ return;
+ }
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ if( sqliteAuthCheck(pParse,STQLITE_DETACH,db->aDb[i].zName,0,0)!=STQLITE_OK ){
+ return;
+ }
+#endif /* STQLITE_OMIT_AUTHORIZATION */
+ sqliteBtreeClose(db->aDb[i].pBt);
+ db->aDb[i].pBt = 0;
+ sqliteFree(db->aDb[i].zName);
+ sqliteResetInternalSchema(db, i);
+ db->nDb--;
+ if( i<db->nDb ){
+ db->aDb[i] = db->aDb[db->nDb];
+ memset(&db->aDb[db->nDb], 0, sizeof(db->aDb[0]));
+ sqliteResetInternalSchema(db, i);
+ }
+}
+
+/*
+** Initialize a DbFixer structure. This routine must be called prior
+** to passing the structure to one of the sqliteFixAAAA() routines below.
+**
+** The return value indicates whether or not fixation is required. TRUE
+** means we do need to fix the database references, FALSE means we do not.
+*/
+int sqliteFixInit(
+ DbFixer *pFix, /* The fixer to be initialized */
+ Parse *pParse, /* Error messages will be written here */
+ int iDb, /* This is the database that must must be used */
+ const char *zType, /* "view", "trigger", or "index" */
+ const Token *pName /* Name of the view, trigger, or index */
+){
+ sqlite *db;
+
+ if( iDb<0 || iDb==1 ) return 0;
+ db = pParse->db;
+ assert( db->nDb>iDb );
+ pFix->pParse = pParse;
+ pFix->zDb = db->aDb[iDb].zName;
+ pFix->zType = zType;
+ pFix->pName = pName;
+ return 1;
+}
+
+/*
+** The following set of routines walk through the parse tree and assign
+** a specific database to all table references where the database name
+** was left unspecified in the original SQL statement. The pFix structure
+** must have been initialized by a prior call to sqliteFixInit().
+**
+** These routines are used to make sure that an index, trigger, or
+** view in one database does not refer to objects in a different database.
+** (Exception: indices, triggers, and views in the TEMP database are
+** allowed to refer to anything.) If a reference is explicitly made
+** to an object in a different database, an error message is added to
+** pParse->zErrMsg and these routines return non-zero. If everything
+** checks out, these routines return 0.
+*/
+int sqliteFixSrcList(
+ DbFixer *pFix, /* Context of the fixation */
+ SrcList *pList /* The Source list to check and modify */
+){
+ int i;
+ const char *zDb;
+
+ if( pList==0 ) return 0;
+ zDb = pFix->zDb;
+ for(i=0; i<pList->nSrc; i++){
+ if( pList->a[i].zDatabase==0 ){
+ pList->a[i].zDatabase = sqliteStrDup(zDb);
+ }else if( sqliteStrICmp(pList->a[i].zDatabase,zDb)!=0 ){
+ sqliteErrorMsg(pFix->pParse,
+ "%s %z cannot reference objects in database %s",
+ pFix->zType, sqliteStrNDup(pFix->pName->z, pFix->pName->n),
+ pList->a[i].zDatabase);
+ return 1;
+ }
+ if( sqliteFixSelect(pFix, pList->a[i].pSelect) ) return 1;
+ if( sqliteFixExpr(pFix, pList->a[i].pOn) ) return 1;
+ }
+ return 0;
+}
+int sqliteFixSelect(
+ DbFixer *pFix, /* Context of the fixation */
+ Select *pSelect /* The SELECT statement to be fixed to one database */
+){
+ while( pSelect ){
+ if( sqliteFixExprList(pFix, pSelect->pEList) ){
+ return 1;
+ }
+ if( sqliteFixSrcList(pFix, pSelect->pSrc) ){
+ return 1;
+ }
+ if( sqliteFixExpr(pFix, pSelect->pWhere) ){
+ return 1;
+ }
+ if( sqliteFixExpr(pFix, pSelect->pHaving) ){
+ return 1;
+ }
+ pSelect = pSelect->pPrior;
+ }
+ return 0;
+}
+int sqliteFixExpr(
+ DbFixer *pFix, /* Context of the fixation */
+ Expr *pExpr /* The expression to be fixed to one database */
+){
+ while( pExpr ){
+ if( sqliteFixSelect(pFix, pExpr->pSelect) ){
+ return 1;
+ }
+ if( sqliteFixExprList(pFix, pExpr->pList) ){
+ return 1;
+ }
+ if( sqliteFixExpr(pFix, pExpr->pRight) ){
+ return 1;
+ }
+ pExpr = pExpr->pLeft;
+ }
+ return 0;
+}
+int sqliteFixExprList(
+ DbFixer *pFix, /* Context of the fixation */
+ ExprList *pList /* The expression to be fixed to one database */
+){
+ int i;
+ if( pList==0 ) return 0;
+ for(i=0; i<pList->nExpr; i++){
+ if( sqliteFixExpr(pFix, pList->a[i].pExpr) ){
+ return 1;
+ }
+ }
+ return 0;
+}
+int sqliteFixTriggerStep(
+ DbFixer *pFix, /* Context of the fixation */
+ TriggerStep *pStep /* The trigger step be fixed to one database */
+){
+ while( pStep ){
+ if( sqliteFixSelect(pFix, pStep->pSelect) ){
+ return 1;
+ }
+ if( sqliteFixExpr(pFix, pStep->pWhere) ){
+ return 1;
+ }
+ if( sqliteFixExprList(pFix, pStep->pExprList) ){
+ return 1;
+ }
+ pStep = pStep->pNext;
+ }
+ return 0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/auth.c b/tqtinterface/qt4/src/3rdparty/sqlite/auth.c
new file mode 100644
index 0000000..8847d4a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/auth.c
@@ -0,0 +1,219 @@
+/*
+** 2003 January 11
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains code used to implement the sqlite_set_authorizer()
+** API. This facility is an optional feature of the library. Embedded
+** systems that do not need this facility may omit it by recompiling
+** the library with -DSTQLITE_OMIT_AUTHORIZATION=1
+**
+** $Id: auth.c,v 1.12 2004/02/22 18:40:57 drh Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** All of the code in this file may be omitted by defining a single
+** macro.
+*/
+#ifndef STQLITE_OMIT_AUTHORIZATION
+
+/*
+** Set or clear the access authorization function.
+**
+** The access authorization function is be called during the compilation
+** phase to verify that the user has read and/or write access permission on
+** various fields of the database. The first argument to the auth function
+** is a copy of the 3rd argument to this routine. The second argument
+** to the auth function is one of these constants:
+**
+** STQLITE_COPY
+** STQLITE_CREATE_INDEX
+** STQLITE_CREATE_TABLE
+** STQLITE_CREATE_TEMP_INDEX
+** STQLITE_CREATE_TEMP_TABLE
+** STQLITE_CREATE_TEMP_TRIGGER
+** STQLITE_CREATE_TEMP_VIEW
+** STQLITE_CREATE_TRIGGER
+** STQLITE_CREATE_VIEW
+** STQLITE_DELETE
+** STQLITE_DROP_INDEX
+** STQLITE_DROP_TABLE
+** STQLITE_DROP_TEMP_INDEX
+** STQLITE_DROP_TEMP_TABLE
+** STQLITE_DROP_TEMP_TRIGGER
+** STQLITE_DROP_TEMP_VIEW
+** STQLITE_DROP_TRIGGER
+** STQLITE_DROP_VIEW
+** STQLITE_INSERT
+** STQLITE_PRAGMA
+** STQLITE_READ
+** STQLITE_SELECT
+** STQLITE_TRANSACTION
+** STQLITE_UPDATE
+**
+** The third and fourth arguments to the auth function are the name of
+** the table and the column that are being accessed. The auth function
+** should return either STQLITE_OK, STQLITE_DENY, or STQLITE_IGNORE. If
+** STQLITE_OK is returned, it means that access is allowed. STQLITE_DENY
+** means that the SQL statement will never-run - the sqlite_exec() call
+** will return with an error. STQLITE_IGNORE means that the SQL statement
+** should run but attempts to read the specified column will return NULL
+** and attempts to write the column will be ignored.
+**
+** Setting the auth function to NULL disables this hook. The default
+** setting of the auth function is NULL.
+*/
+int sqlite_set_authorizer(
+ sqlite *db,
+ int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
+ void *pArg
+){
+ db->xAuth = xAuth;
+ db->pAuthArg = pArg;
+ return STQLITE_OK;
+}
+
+/*
+** Write an error message into pParse->zErrMsg that explains that the
+** user-supplied authorization function returned an illegal value.
+*/
+static void sqliteAuthBadReturnCode(Parse *pParse, int rc){
+ sqliteErrorMsg(pParse, "illegal return value (%d) from the "
+ "authorization function - should be STQLITE_OK, STQLITE_IGNORE, "
+ "or STQLITE_DENY", rc);
+ pParse->rc = STQLITE_MISUSE;
+}
+
+/*
+** The pExpr should be a TK_COLUMN expression. The table referred to
+** is in pTabList or else it is the NEW or OLD table of a trigger.
+** Check to see if it is OK to read this particular column.
+**
+** If the auth function returns STQLITE_IGNORE, change the TK_COLUMN
+** instruction into a TK_NULL. If the auth function returns STQLITE_DENY,
+** then generate an error.
+*/
+void sqliteAuthRead(
+ Parse *pParse, /* The parser context */
+ Expr *pExpr, /* The expression to check authorization on */
+ SrcList *pTabList /* All table that pExpr might refer to */
+){
+ sqlite *db = pParse->db;
+ int rc;
+ Table *pTab; /* The table being read */
+ const char *zCol; /* Name of the column of the table */
+ int iSrc; /* Index in pTabList->a[] of table being read */
+ const char *zDBase; /* Name of database being accessed */
+
+ if( db->xAuth==0 ) return;
+ assert( pExpr->op==TK_COLUMN );
+ for(iSrc=0; iSrc<pTabList->nSrc; iSrc++){
+ if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break;
+ }
+ if( iSrc>=0 && iSrc<pTabList->nSrc ){
+ pTab = pTabList->a[iSrc].pTab;
+ }else{
+ /* This must be an attempt to read the NEW or OLD pseudo-tables
+ ** of a trigger.
+ */
+ TriggerStack *pStack; /* The stack of current triggers */
+ pStack = pParse->trigStack;
+ assert( pStack!=0 );
+ assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx );
+ pTab = pStack->pTab;
+ }
+ if( pTab==0 ) return;
+ if( pExpr->iColumn>=0 ){
+ assert( pExpr->iColumn<pTab->nCol );
+ zCol = pTab->aCol[pExpr->iColumn].zName;
+ }else if( pTab->iPKey>=0 ){
+ assert( pTab->iPKey<pTab->nCol );
+ zCol = pTab->aCol[pTab->iPKey].zName;
+ }else{
+ zCol = "ROWID";
+ }
+ assert( pExpr->iDb<db->nDb );
+ zDBase = db->aDb[pExpr->iDb].zName;
+ rc = db->xAuth(db->pAuthArg, STQLITE_READ, pTab->zName, zCol, zDBase,
+ pParse->zAuthContext);
+ if( rc==STQLITE_IGNORE ){
+ pExpr->op = TK_NULL;
+ }else if( rc==STQLITE_DENY ){
+ if( db->nDb>2 || pExpr->iDb!=0 ){
+ sqliteErrorMsg(pParse, "access to %s.%s.%s is prohibited",
+ zDBase, pTab->zName, zCol);
+ }else{
+ sqliteErrorMsg(pParse, "access to %s.%s is prohibited", pTab->zName,zCol);
+ }
+ pParse->rc = STQLITE_AUTH;
+ }else if( rc!=STQLITE_OK ){
+ sqliteAuthBadReturnCode(pParse, rc);
+ }
+}
+
+/*
+** Do an authorization check using the code and arguments given. Return
+** either STQLITE_OK (zero) or STQLITE_IGNORE or STQLITE_DENY. If STQLITE_DENY
+** is returned, then the error count and error message in pParse are
+** modified appropriately.
+*/
+int sqliteAuthCheck(
+ Parse *pParse,
+ int code,
+ const char *zArg1,
+ const char *zArg2,
+ const char *zArg3
+){
+ sqlite *db = pParse->db;
+ int rc;
+
+ if( db->xAuth==0 ){
+ return STQLITE_OK;
+ }
+ rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
+ if( rc==STQLITE_DENY ){
+ sqliteErrorMsg(pParse, "not authorized");
+ pParse->rc = STQLITE_AUTH;
+ }else if( rc!=STQLITE_OK && rc!=STQLITE_IGNORE ){
+ rc = STQLITE_DENY;
+ sqliteAuthBadReturnCode(pParse, rc);
+ }
+ return rc;
+}
+
+/*
+** Push an authorization context. After this routine is called, the
+** zArg3 argument to authorization callbacks will be zContext until
+** popped. Or if pParse==0, this routine is a no-op.
+*/
+void sqliteAuthContextPush(
+ Parse *pParse,
+ AuthContext *pContext,
+ const char *zContext
+){
+ pContext->pParse = pParse;
+ if( pParse ){
+ pContext->zAuthContext = pParse->zAuthContext;
+ pParse->zAuthContext = zContext;
+ }
+}
+
+/*
+** Pop an authorization context that was previously pushed
+** by sqliteAuthContextPush
+*/
+void sqliteAuthContextPop(AuthContext *pContext){
+ if( pContext->pParse ){
+ pContext->pParse->zAuthContext = pContext->zAuthContext;
+ pContext->pParse = 0;
+ }
+}
+
+#endif /* STQLITE_OMIT_AUTHORIZATION */
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/btree.c b/tqtinterface/qt4/src/3rdparty/sqlite/btree.c
new file mode 100644
index 0000000..f3b92c6
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/btree.c
@@ -0,0 +1,3579 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** $Id: btree.c,v 1.102 2004/02/14 17:35:07 drh Exp $
+**
+** This file implements a external (disk-based) database using BTrees.
+** For a detailed discussion of BTrees, refer to
+**
+** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
+** "Sorting And Searching", pages 473-480. Addison-Wesley
+** Publishing Company, Reading, Massachusetts.
+**
+** The basic idea is that each page of the file tqcontains N database
+** entries and N+1 pointers to subpages.
+**
+** ----------------------------------------------------------------
+** | Ptr(0) | Key(0) | Ptr(1) | Key(1) | ... | Key(N) | Ptr(N+1) |
+** ----------------------------------------------------------------
+**
+** All of the keys on the page that Ptr(0) points to have values less
+** than Key(0). All of the keys on page Ptr(1) and its subpages have
+** values greater than Key(0) and less than Key(1). All of the keys
+** on Ptr(N+1) and its subpages have values greater than Key(N). And
+** so forth.
+**
+** Finding a particular key requires reading O(log(M)) pages from the
+** disk where M is the number of entries in the tree.
+**
+** In this implementation, a single file can hold one or more separate
+** BTrees. Each BTree is identified by the index of its root page. The
+** key and data for any entry are combined to form the "payload". Up to
+** MX_LOCAL_PAYLOAD bytes of payload can be carried directly on the
+** database page. If the payload is larger than MX_LOCAL_PAYLOAD bytes
+** then surplus bytes are stored on overflow pages. The payload for an
+** entry and the preceding pointer are combined to form a "Cell". Each
+** page has a small header which tqcontains the Ptr(N+1) pointer.
+**
+** The first page of the file tqcontains a magic string used to verify that
+** the file really is a valid BTree database, a pointer to a list of unused
+** pages in the file, and some meta information. The root of the first
+** BTree begins on page 2 of the file. (Pages are numbered beginning with
+** 1, not 0.) Thus a minimum database tqcontains 2 pages.
+*/
+#include "sqliteInt.h"
+#include "pager.h"
+#include "btree.h"
+#include <assert.h>
+
+/* Forward declarations */
+static BtOps sqliteBtreeOps;
+static BtCursorOps sqliteBtreeCursorOps;
+
+/*
+** Macros used for byteswapping. B is a pointer to the Btree
+** structure. This is needed to access the Btree.needSwab boolean
+** in order to tell if byte swapping is needed or not.
+** X is an unsigned integer. SWAB16 byte swaps a 16-bit integer.
+** SWAB32 byteswaps a 32-bit integer.
+*/
+#define SWAB16(B,X) ((B)->needSwab? swab16((u16)X) : ((u16)X))
+#define SWAB32(B,X) ((B)->needSwab? swab32(X) : (X))
+#define SWAB_ADD(B,X,A) \
+ if((B)->needSwab){ X=swab32(swab32(X)+A); }else{ X += (A); }
+
+/*
+** The following global variable - available only if STQLITE_TEST is
+** defined - is used to determine whether new databases are created in
+** native byte order or in non-native byte order. Non-native byte order
+** databases are created for testing purposes only. Under normal operation,
+** only native byte-order databases should be created, but we should be
+** able to read or write existing databases regardless of the byteorder.
+*/
+#ifdef STQLITE_TEST
+int btree_native_byte_order = 1;
+#else
+# define btree_native_byte_order 1
+#endif
+
+/*
+** Forward declarations of structures used only in this file.
+*/
+typedef struct PageOne PageOne;
+typedef struct MemPage MemPage;
+typedef struct PageHdr PageHdr;
+typedef struct Cell Cell;
+typedef struct CellHdr CellHdr;
+typedef struct FreeBlk FreeBlk;
+typedef struct OverflowPage OverflowPage;
+typedef struct FreelistInfo FreelistInfo;
+
+/*
+** All structures on a database page are aligned to 4-byte boundries.
+** This routine rounds up a number of bytes to the next multiple of 4.
+**
+** This might need to change for computer architectures that require
+** and 8-byte tqalignment boundry for structures.
+*/
+#define ROUNDUP(X) ((X+3) & ~3)
+
+/*
+** This is a magic string that appears at the beginning of every
+** STQLite database in order to identify the file as a real database.
+*/
+static const char zMagicHeader[] =
+ "** This file tqcontains an STQLite 2.1 database **";
+#define MAGIC_SIZE (sizeof(zMagicHeader))
+
+/*
+** This is a magic integer also used to test the integrity of the database
+** file. This integer is used in addition to the string above so that
+** if the file is written on a little-endian architecture and read
+** on a big-endian architectures (or vice versa) we can detect the
+** problem.
+**
+** The number used was obtained at random and has no special
+** significance other than the fact that it represents a different
+** integer on little-endian and big-endian machines.
+*/
+#define MAGIC 0xdae37528
+
+/*
+** The first page of the database file tqcontains a magic header string
+** to identify the file as an STQLite database file. It also tqcontains
+** a pointer to the first free page of the file. Page 2 tqcontains the
+** root of the principle BTree. The file might contain other BTrees
+** rooted on pages above 2.
+**
+** The first page also tqcontains STQLITE_N_BTREE_META integers that
+** can be used by higher-level routines.
+**
+** Remember that pages are numbered beginning with 1. (See pager.c
+** for additional information.) Page 0 does not exist and a page
+** number of 0 is used to mean "no such page".
+*/
+struct PageOne {
+ char zMagic[MAGIC_SIZE]; /* String that identifies the file as a database */
+ int iMagic; /* Integer to verify correct byte order */
+ Pgno freeList; /* First free page in a list of all free pages */
+ int nFree; /* Number of pages on the free list */
+ int aMeta[STQLITE_N_BTREE_META-1]; /* User defined integers */
+};
+
+/*
+** Each database page has a header that is an instance of this
+** structure.
+**
+** PageHdr.firstFree is 0 if there is no free space on this page.
+** Otherwise, PageHdr.firstFree is the index in MemPage.u.aDisk[] of a
+** FreeBlk structure that describes the first block of free space.
+** All free space is defined by a linked list of FreeBlk structures.
+**
+** Data is stored in a linked list of Cell structures. PageHdr.firstCell
+** is the index into MemPage.u.aDisk[] of the first cell on the page. The
+** Cells are kept in sorted order.
+**
+** A Cell tqcontains all information about a database entry and a pointer
+** to a child page that tqcontains other entries less than itself. In
+** other words, the i-th Cell tqcontains both Ptr(i) and Key(i). The
+** right-most pointer of the page is contained in PageHdr.rightChild.
+*/
+struct PageHdr {
+ Pgno rightChild; /* Child page that comes after all cells on this page */
+ u16 firstCell; /* Index in MemPage.u.aDisk[] of the first cell */
+ u16 firstFree; /* Index in MemPage.u.aDisk[] of the first free block */
+};
+
+/*
+** Entries on a page of the database are called "Cells". Each Cell
+** has a header and data. This structure defines the header. The
+** key and data (collectively the "payload") follow this header on
+** the database page.
+**
+** A definition of the complete Cell structure is given below. The
+** header for the cell must be defined first in order to do some
+** of the sizing #defines that follow.
+*/
+struct CellHdr {
+ Pgno leftChild; /* Child page that comes before this cell */
+ u16 nKey; /* Number of bytes in the key */
+ u16 iNext; /* Index in MemPage.u.aDisk[] of next cell in sorted order */
+ u8 nKeyHi; /* Upper 8 bits of key size for keys larger than 64K bytes */
+ u8 nDataHi; /* Upper 8 bits of data size when the size is more than 64K */
+ u16 nData; /* Number of bytes of data */
+};
+
+/*
+** The key and data size are split into a lower 16-bit segment and an
+** upper 8-bit segment in order to pack them together into a smaller
+** space. The following macros reassembly a key or data size back
+** into an integer.
+*/
+#define NKEY(b,h) (SWAB16(b,h.nKey) + h.nKeyHi*65536)
+#define NDATA(b,h) (SWAB16(b,h.nData) + h.nDataHi*65536)
+
+/*
+** The minimum size of a complete Cell. The Cell must contain a header
+** and at least 4 bytes of payload.
+*/
+#define MIN_CELL_SIZE (sizeof(CellHdr)+4)
+
+/*
+** The maximum number of database entries that can be held in a single
+** page of the database.
+*/
+#define MX_CELL ((STQLITE_USABLE_SIZE-sizeof(PageHdr))/MIN_CELL_SIZE)
+
+/*
+** The amount of usable space on a single page of the BTree. This is the
+** page size minus the overhead of the page header.
+*/
+#define USABLE_SPACE (STQLITE_USABLE_SIZE - sizeof(PageHdr))
+
+/*
+** The maximum amount of payload (in bytes) that can be stored locally for
+** a database entry. If the entry tqcontains more data than this, the
+** extra goes onto overflow pages.
+**
+** This number is chosen so that at least 4 cells will fit on every page.
+*/
+#define MX_LOCAL_PAYLOAD ((USABLE_SPACE/4-(sizeof(CellHdr)+sizeof(Pgno)))&~3)
+
+/*
+** Data on a database page is stored as a linked list of Cell structures.
+** Both the key and the data are stored in aPayload[]. The key always comes
+** first. The aPayload[] field grows as necessary to hold the key and data,
+** up to a maximum of MX_LOCAL_PAYLOAD bytes. If the size of the key and
+** data combined exceeds MX_LOCAL_PAYLOAD bytes, then Cell.ovfl is the
+** page number of the first overflow page.
+**
+** Though this structure is fixed in size, the Cell on the database
+** page varies in size. Every cell has a CellHdr and at least 4 bytes
+** of payload space. Additional payload bytes (up to the maximum of
+** MX_LOCAL_PAYLOAD) and the Cell.ovfl value are allocated only as
+** needed.
+*/
+struct Cell {
+ CellHdr h; /* The cell header */
+ char aPayload[MX_LOCAL_PAYLOAD]; /* Key and data */
+ Pgno ovfl; /* The first overflow page */
+};
+
+/*
+** Free space on a page is remembered using a linked list of the FreeBlk
+** structures. Space on a database page is allocated in increments of
+** at least 4 bytes and is always aligned to a 4-byte boundry. The
+** linked list of FreeBlks is always kept in order by address.
+*/
+struct FreeBlk {
+ u16 iSize; /* Number of bytes in this block of free space */
+ u16 iNext; /* Index in MemPage.u.aDisk[] of the next free block */
+};
+
+/*
+** The number of bytes of payload that will fit on a single overflow page.
+*/
+#define OVERFLOW_SIZE (STQLITE_USABLE_SIZE-sizeof(Pgno))
+
+/*
+** When the key and data for a single entry in the BTree will not fit in
+** the MX_LOCAL_PAYLOAD bytes of space available on the database page,
+** then all extra bytes are written to a linked list of overflow pages.
+** Each overflow page is an instance of the following structure.
+**
+** Unused pages in the database are also represented by instances of
+** the OverflowPage structure. The PageOne.freeList field is the
+** page number of the first page in a linked list of unused database
+** pages.
+*/
+struct OverflowPage {
+ Pgno iNext;
+ char aPayload[OVERFLOW_SIZE];
+};
+
+/*
+** The PageOne.freeList field points to a linked list of overflow pages
+** hold information about free pages. The aPayload section of each
+** overflow page tqcontains an instance of the following structure. The
+** aFree[] array holds the page number of nFree unused pages in the disk
+** file.
+*/
+struct FreelistInfo {
+ int nFree;
+ Pgno aFree[(OVERFLOW_SIZE-sizeof(int))/sizeof(Pgno)];
+};
+
+/*
+** For every page in the database file, an instance of the following structure
+** is stored in memory. The u.aDisk[] array tqcontains the raw bits read from
+** the disk. The rest is auxiliary information held in memory only. The
+** auxiliary info is only valid for regular database pages - it is not
+** used for overflow pages and pages on the freelist.
+**
+** Of particular interest in the auxiliary info is the apCell[] entry. Each
+** apCell[] entry is a pointer to a Cell structure in u.aDisk[]. The cells are
+** put in this array so that they can be accessed in constant time, rather
+** than in linear time which would be needed if we had to walk the linked
+** list on every access.
+**
+** Note that apCell[] tqcontains enough space to hold up to two more Cells
+** than can possibly fit on one page. In the steady state, every apCell[]
+** points to memory inside u.aDisk[]. But in the middle of an insert
+** operation, some apCell[] entries may temporarily point to data space
+** outside of u.aDisk[]. This is a transient situation that is quickly
+** resolved. But while it is happening, it is possible for a database
+** page to hold as many as two more cells than it might otherwise hold.
+** The extra two entries in apCell[] are an allowance for this situation.
+**
+** The pParent field points back to the tqparent page. This allows us to
+** walk up the BTree from any leaf to the root. Care must be taken to
+** unref() the tqparent page pointer when this page is no longer referenced.
+** The pageDestructor() routine handles that chore.
+*/
+struct MemPage {
+ union u_page_data {
+ char aDisk[STQLITE_PAGE_SIZE]; /* Page data stored on disk */
+ PageHdr hdr; /* Overlay page header */
+ } u;
+ u8 isInit; /* True if auxiliary data is initialized */
+ u8 idxShift; /* True if apCell[] indices have changed */
+ u8 isOverfull; /* Some apCell[] points outside u.aDisk[] */
+ MemPage *pParent; /* The tqparent of this page. NULL for root */
+ int idxParent; /* Index in pParent->apCell[] of this node */
+ int nFree; /* Number of free bytes in u.aDisk[] */
+ int nCell; /* Number of entries on this page */
+ Cell *apCell[MX_CELL+2]; /* All data entires in sorted order */
+};
+
+/*
+** The in-memory image of a disk page has the auxiliary information appended
+** to the end. EXTRA_SIZE is the number of bytes of space needed to hold
+** that extra information.
+*/
+#define EXTRA_SIZE (sizeof(MemPage)-sizeof(union u_page_data))
+
+/*
+** Everything we need to know about an open database
+*/
+struct Btree {
+ BtOps *pOps; /* Function table */
+ Pager *pPager; /* The page cache */
+ BtCursor *pCursor; /* A list of all open cursors */
+ PageOne *page1; /* First page of the database */
+ u8 inTrans; /* True if a transaction is in progress */
+ u8 inCkpt; /* True if there is a checkpoint on the transaction */
+ u8 readOnly; /* True if the underlying file is readonly */
+ u8 needSwab; /* Need to byte-swapping */
+};
+typedef Btree Bt;
+
+/*
+** A cursor is a pointer to a particular entry in the BTree.
+** The entry is identified by its MemPage and the index in
+** MemPage.apCell[] of the entry.
+*/
+struct BtCursor {
+ BtCursorOps *pOps; /* Function table */
+ Btree *pBt; /* The Btree to which this cursor belongs */
+ BtCursor *pNext, *pPrev; /* Forms a linked list of all cursors */
+ BtCursor *pShared; /* Loop of cursors with the same root page */
+ Pgno pgnoRoot; /* The root page of this tree */
+ MemPage *pPage; /* Page that tqcontains the entry */
+ int idx; /* Index of the entry in pPage->apCell[] */
+ u8 wrFlag; /* True if writable */
+ u8 eSkip; /* Determines if next step operation is a no-op */
+ u8 iMatch; /* compare result from last sqliteBtreeMoveto() */
+};
+
+/*
+** Legal values for BtCursor.eSkip.
+*/
+#define SKIP_NONE 0 /* Always step the cursor */
+#define SKIP_NEXT 1 /* The next sqliteBtreeNext() is a no-op */
+#define SKIP_PREV 2 /* The next sqliteBtreePrevious() is a no-op */
+#define SKIP_INVALID 3 /* Calls to Next() and Previous() are invalid */
+
+/* Forward declarations */
+static int fileBtreeCloseCursor(BtCursor *pCur);
+
+/*
+** Routines for byte swapping.
+*/
+u16 swab16(u16 x){
+ return ((x & 0xff)<<8) | ((x>>8)&0xff);
+}
+u32 swab32(u32 x){
+ return ((x & 0xff)<<24) | ((x & 0xff00)<<8) |
+ ((x>>8) & 0xff00) | ((x>>24)&0xff);
+}
+
+/*
+** Compute the total number of bytes that a Cell needs on the main
+** database page. The number returned includes the Cell header,
+** local payload storage, and the pointer to overflow pages (if
+** applicable). Additional space allocated on overflow pages
+** is NOT included in the value returned from this routine.
+*/
+static int cellSize(Btree *pBt, Cell *pCell){
+ int n = NKEY(pBt, pCell->h) + NDATA(pBt, pCell->h);
+ if( n>MX_LOCAL_PAYLOAD ){
+ n = MX_LOCAL_PAYLOAD + sizeof(Pgno);
+ }else{
+ n = ROUNDUP(n);
+ }
+ n += sizeof(CellHdr);
+ return n;
+}
+
+/*
+** Defragment the page given. All Cells are moved to the
+** beginning of the page and all free space is collected
+** into one big FreeBlk at the end of the page.
+*/
+static void defragmentPage(Btree *pBt, MemPage *pPage){
+ int pc, i, n;
+ FreeBlk *pFBlk;
+ char newPage[STQLITE_USABLE_SIZE];
+
+ assert( sqlitepager_iswriteable(pPage) );
+ assert( pPage->isInit );
+ pc = sizeof(PageHdr);
+ pPage->u.hdr.firstCell = SWAB16(pBt, pc);
+ memcpy(newPage, pPage->u.aDisk, pc);
+ for(i=0; i<pPage->nCell; i++){
+ Cell *pCell = pPage->apCell[i];
+
+ /* This routine should never be called on an overfull page. The
+ ** following asserts verify that constraint. */
+ assert( Addr(pCell) > Addr(pPage) );
+ assert( Addr(pCell) < Addr(pPage) + STQLITE_USABLE_SIZE );
+
+ n = cellSize(pBt, pCell);
+ pCell->h.iNext = SWAB16(pBt, pc + n);
+ memcpy(&newPage[pc], pCell, n);
+ pPage->apCell[i] = (Cell*)&pPage->u.aDisk[pc];
+ pc += n;
+ }
+ assert( pPage->nFree==STQLITE_USABLE_SIZE-pc );
+ memcpy(pPage->u.aDisk, newPage, pc);
+ if( pPage->nCell>0 ){
+ pPage->apCell[pPage->nCell-1]->h.iNext = 0;
+ }
+ pFBlk = (FreeBlk*)&pPage->u.aDisk[pc];
+ pFBlk->iSize = SWAB16(pBt, STQLITE_USABLE_SIZE - pc);
+ pFBlk->iNext = 0;
+ pPage->u.hdr.firstFree = SWAB16(pBt, pc);
+ memset(&pFBlk[1], 0, STQLITE_USABLE_SIZE - pc - sizeof(FreeBlk));
+}
+
+/*
+** Allocate nByte bytes of space on a page. nByte must be a
+** multiple of 4.
+**
+** Return the index into pPage->u.aDisk[] of the first byte of
+** the new allocation. Or return 0 if there is not enough free
+** space on the page to satisfy the allocation request.
+**
+** If the page tqcontains nBytes of free space but does not contain
+** nBytes of contiguous free space, then this routine automatically
+** calls defragementPage() to consolidate all free space before
+** allocating the new chunk.
+*/
+static int allocateSpace(Btree *pBt, MemPage *pPage, int nByte){
+ FreeBlk *p;
+ u16 *pIdx;
+ int start;
+ int iSize;
+#ifndef NDEBUG
+ int cnt = 0;
+#endif
+
+ assert( sqlitepager_iswriteable(pPage) );
+ assert( nByte==ROUNDUP(nByte) );
+ assert( pPage->isInit );
+ if( pPage->nFree<nByte || pPage->isOverfull ) return 0;
+ pIdx = &pPage->u.hdr.firstFree;
+ p = (FreeBlk*)&pPage->u.aDisk[SWAB16(pBt, *pIdx)];
+ while( (iSize = SWAB16(pBt, p->iSize))<nByte ){
+ assert( cnt++ < STQLITE_USABLE_SIZE/4 );
+ if( p->iNext==0 ){
+ defragmentPage(pBt, pPage);
+ pIdx = &pPage->u.hdr.firstFree;
+ }else{
+ pIdx = &p->iNext;
+ }
+ p = (FreeBlk*)&pPage->u.aDisk[SWAB16(pBt, *pIdx)];
+ }
+ if( iSize==nByte ){
+ start = SWAB16(pBt, *pIdx);
+ *pIdx = p->iNext;
+ }else{
+ FreeBlk *pNew;
+ start = SWAB16(pBt, *pIdx);
+ pNew = (FreeBlk*)&pPage->u.aDisk[start + nByte];
+ pNew->iNext = p->iNext;
+ pNew->iSize = SWAB16(pBt, iSize - nByte);
+ *pIdx = SWAB16(pBt, start + nByte);
+ }
+ pPage->nFree -= nByte;
+ return start;
+}
+
+/*
+** Return a section of the MemPage.u.aDisk[] to the freelist.
+** The first byte of the new free block is pPage->u.aDisk[start]
+** and the size of the block is "size" bytes. Size must be
+** a multiple of 4.
+**
+** Most of the effort here is involved in coalesing adjacent
+** free blocks into a single big free block.
+*/
+static void freeSpace(Btree *pBt, MemPage *pPage, int start, int size){
+ int end = start + size;
+ u16 *pIdx, idx;
+ FreeBlk *pFBlk;
+ FreeBlk *pNew;
+ FreeBlk *pNext;
+ int iSize;
+
+ assert( sqlitepager_iswriteable(pPage) );
+ assert( size == ROUNDUP(size) );
+ assert( start == ROUNDUP(start) );
+ assert( pPage->isInit );
+ pIdx = &pPage->u.hdr.firstFree;
+ idx = SWAB16(pBt, *pIdx);
+ while( idx!=0 && idx<start ){
+ pFBlk = (FreeBlk*)&pPage->u.aDisk[idx];
+ iSize = SWAB16(pBt, pFBlk->iSize);
+ if( idx + iSize == start ){
+ pFBlk->iSize = SWAB16(pBt, iSize + size);
+ if( idx + iSize + size == SWAB16(pBt, pFBlk->iNext) ){
+ pNext = (FreeBlk*)&pPage->u.aDisk[idx + iSize + size];
+ if( pBt->needSwab ){
+ pFBlk->iSize = swab16((u16)swab16(pNext->iSize)+iSize+size);
+ }else{
+ pFBlk->iSize += pNext->iSize;
+ }
+ pFBlk->iNext = pNext->iNext;
+ }
+ pPage->nFree += size;
+ return;
+ }
+ pIdx = &pFBlk->iNext;
+ idx = SWAB16(pBt, *pIdx);
+ }
+ pNew = (FreeBlk*)&pPage->u.aDisk[start];
+ if( idx != end ){
+ pNew->iSize = SWAB16(pBt, size);
+ pNew->iNext = SWAB16(pBt, idx);
+ }else{
+ pNext = (FreeBlk*)&pPage->u.aDisk[idx];
+ pNew->iSize = SWAB16(pBt, size + SWAB16(pBt, pNext->iSize));
+ pNew->iNext = pNext->iNext;
+ }
+ *pIdx = SWAB16(pBt, start);
+ pPage->nFree += size;
+}
+
+/*
+** Initialize the auxiliary information for a disk block.
+**
+** The pParent parameter must be a pointer to the MemPage which
+** is the tqparent of the page being initialized. The root of the
+** BTree (usually page 2) has no tqparent and so for that page,
+** pParent==NULL.
+**
+** Return STQLITE_OK on success. If we see that the page does
+** not contain a well-formed database page, then return
+** STQLITE_CORRUPT. Note that a return of STQLITE_OK does not
+** guarantee that the page is well-formed. It only shows that
+** we failed to detect any corruption.
+*/
+static int initPage(Bt *pBt, MemPage *pPage, Pgno pgnoThis, MemPage *pParent){
+ int idx; /* An index into pPage->u.aDisk[] */
+ Cell *pCell; /* A pointer to a Cell in pPage->u.aDisk[] */
+ FreeBlk *pFBlk; /* A pointer to a free block in pPage->u.aDisk[] */
+ int sz; /* The size of a Cell in bytes */
+ int freeSpace; /* Amount of free space on the page */
+
+ if( pPage->pParent ){
+ assert( pPage->pParent==pParent );
+ return STQLITE_OK;
+ }
+ if( pParent ){
+ pPage->pParent = pParent;
+ sqlitepager_ref(pParent);
+ }
+ if( pPage->isInit ) return STQLITE_OK;
+ pPage->isInit = 1;
+ pPage->nCell = 0;
+ freeSpace = USABLE_SPACE;
+ idx = SWAB16(pBt, pPage->u.hdr.firstCell);
+ while( idx!=0 ){
+ if( idx>STQLITE_USABLE_SIZE-MIN_CELL_SIZE ) goto page_format_error;
+ if( idx<sizeof(PageHdr) ) goto page_format_error;
+ if( idx!=ROUNDUP(idx) ) goto page_format_error;
+ pCell = (Cell*)&pPage->u.aDisk[idx];
+ sz = cellSize(pBt, pCell);
+ if( idx+sz > STQLITE_USABLE_SIZE ) goto page_format_error;
+ freeSpace -= sz;
+ pPage->apCell[pPage->nCell++] = pCell;
+ idx = SWAB16(pBt, pCell->h.iNext);
+ }
+ pPage->nFree = 0;
+ idx = SWAB16(pBt, pPage->u.hdr.firstFree);
+ while( idx!=0 ){
+ int iNext;
+ if( idx>STQLITE_USABLE_SIZE-sizeof(FreeBlk) ) goto page_format_error;
+ if( idx<sizeof(PageHdr) ) goto page_format_error;
+ pFBlk = (FreeBlk*)&pPage->u.aDisk[idx];
+ pPage->nFree += SWAB16(pBt, pFBlk->iSize);
+ iNext = SWAB16(pBt, pFBlk->iNext);
+ if( iNext>0 && iNext <= idx ) goto page_format_error;
+ idx = iNext;
+ }
+ if( pPage->nCell==0 && pPage->nFree==0 ){
+ /* As a special case, an uninitialized root page appears to be
+ ** an empty database */
+ return STQLITE_OK;
+ }
+ if( pPage->nFree!=freeSpace ) goto page_format_error;
+ return STQLITE_OK;
+
+page_format_error:
+ return STQLITE_CORRUPT;
+}
+
+/*
+** Set up a raw page so that it looks like a database page holding
+** no entries.
+*/
+static void zeroPage(Btree *pBt, MemPage *pPage){
+ PageHdr *pHdr;
+ FreeBlk *pFBlk;
+ assert( sqlitepager_iswriteable(pPage) );
+ memset(pPage, 0, STQLITE_USABLE_SIZE);
+ pHdr = &pPage->u.hdr;
+ pHdr->firstCell = 0;
+ pHdr->firstFree = SWAB16(pBt, sizeof(*pHdr));
+ pFBlk = (FreeBlk*)&pHdr[1];
+ pFBlk->iNext = 0;
+ pPage->nFree = STQLITE_USABLE_SIZE - sizeof(*pHdr);
+ pFBlk->iSize = SWAB16(pBt, pPage->nFree);
+ pPage->nCell = 0;
+ pPage->isOverfull = 0;
+}
+
+/*
+** This routine is called when the reference count for a page
+** reaches zero. We need to unref the pParent pointer when that
+** happens.
+*/
+static void pageDestructor(void *pData){
+ MemPage *pPage = (MemPage*)pData;
+ if( pPage->pParent ){
+ MemPage *pParent = pPage->pParent;
+ pPage->pParent = 0;
+ sqlitepager_unref(pParent);
+ }
+}
+
+/*
+** Open a new database.
+**
+** Actually, this routine just sets up the internal data structures
+** for accessing the database. We do not open the database file
+** until the first page is loaded.
+**
+** zFilename is the name of the database file. If zFilename is NULL
+** a new database with a random name is created. This randomly named
+** database file will be deleted when sqliteBtreeClose() is called.
+*/
+int sqliteBtreeOpen(
+ const char *zFilename, /* Name of the file containing the BTree database */
+ int omitJournal, /* if TRUE then do not journal this file */
+ int nCache, /* How many pages in the page cache */
+ Btree **ppBtree /* Pointer to new Btree object written here */
+){
+ Btree *pBt;
+ int rc;
+
+ /*
+ ** The following asserts make sure that structures used by the btree are
+ ** the right size. This is to guard against size changes that result
+ ** when compiling on a different architecture.
+ */
+ assert( sizeof(u32)==4 );
+ assert( sizeof(u16)==2 );
+ assert( sizeof(Pgno)==4 );
+ assert( sizeof(PageHdr)==8 );
+ assert( sizeof(CellHdr)==12 );
+ assert( sizeof(FreeBlk)==4 );
+ assert( sizeof(OverflowPage)==STQLITE_USABLE_SIZE );
+ assert( sizeof(FreelistInfo)==OVERFLOW_SIZE );
+ assert( sizeof(ptr)==sizeof(char*) );
+ assert( sizeof(uptr)==sizeof(ptr) );
+
+ pBt = sqliteMalloc( sizeof(*pBt) );
+ if( pBt==0 ){
+ *ppBtree = 0;
+ return STQLITE_NOMEM;
+ }
+ if( nCache<10 ) nCache = 10;
+ rc = sqlitepager_open(&pBt->pPager, zFilename, nCache, EXTRA_SIZE,
+ !omitJournal);
+ if( rc!=STQLITE_OK ){
+ if( pBt->pPager ) sqlitepager_close(pBt->pPager);
+ sqliteFree(pBt);
+ *ppBtree = 0;
+ return rc;
+ }
+ sqlitepager_set_destructor(pBt->pPager, pageDestructor);
+ pBt->pCursor = 0;
+ pBt->page1 = 0;
+ pBt->readOnly = sqlitepager_isreadonly(pBt->pPager);
+ pBt->pOps = &sqliteBtreeOps;
+ *ppBtree = pBt;
+ return STQLITE_OK;
+}
+
+/*
+** Close an open database and tqinvalidate all cursors.
+*/
+static int fileBtreeClose(Btree *pBt){
+ while( pBt->pCursor ){
+ fileBtreeCloseCursor(pBt->pCursor);
+ }
+ sqlitepager_close(pBt->pPager);
+ sqliteFree(pBt);
+ return STQLITE_OK;
+}
+
+/*
+** Change the limit on the number of pages allowed in the cache.
+**
+** The maximum number of cache pages is set to the absolute
+** value of mxPage. If mxPage is negative, the pager will
+** operate asynchronously - it will not stop to do fsync()s
+** to insure data is written to the disk surface before
+** continuing. Transactions still work if synchronous is off,
+** and the database cannot be corrupted if this program
+** crashes. But if the operating system crashes or there is
+** an abrupt power failure when synchronous is off, the database
+** could be left in an inconsistent and unrecoverable state.
+** Synchronous is on by default so database corruption is not
+** normally a worry.
+*/
+static int fileBtreeSetCacheSize(Btree *pBt, int mxPage){
+ sqlitepager_set_cachesize(pBt->pPager, mxPage);
+ return STQLITE_OK;
+}
+
+/*
+** Change the way data is synced to disk in order to increase or decrease
+** how well the database resists damage due to OS crashes and power
+** failures. Level 1 is the same as asynchronous (no syncs() occur and
+** there is a high probability of damage) Level 2 is the default. There
+** is a very low but non-zero probability of damage. Level 3 reduces the
+** probability of damage to near zero but with a write performance reduction.
+*/
+static int fileBtreeSetSafetyLevel(Btree *pBt, int level){
+ sqlitepager_set_safety_level(pBt->pPager, level);
+ return STQLITE_OK;
+}
+
+/*
+** Get a reference to page1 of the database file. This will
+** also acquire a readlock on that file.
+**
+** STQLITE_OK is returned on success. If the file is not a
+** well-formed database file, then STQLITE_CORRUPT is returned.
+** STQLITE_BUSY is returned if the database is locked. STQLITE_NOMEM
+** is returned if we run out of memory. STQLITE_PROTOCOL is returned
+** if there is a locking protocol violation.
+*/
+static int lockBtree(Btree *pBt){
+ int rc;
+ if( pBt->page1 ) return STQLITE_OK;
+ rc = sqlitepager_get(pBt->pPager, 1, (void**)&pBt->page1);
+ if( rc!=STQLITE_OK ) return rc;
+
+ /* Do some checking to help insure the file we opened really is
+ ** a valid database file.
+ */
+ if( sqlitepager_pagecount(pBt->pPager)>0 ){
+ PageOne *pP1 = pBt->page1;
+ if( strcmp(pP1->zMagic,zMagicHeader)!=0 ||
+ (pP1->iMagic!=MAGIC && swab32(pP1->iMagic)!=MAGIC) ){
+ rc = STQLITE_NOTADB;
+ goto page1_init_failed;
+ }
+ pBt->needSwab = pP1->iMagic!=MAGIC;
+ }
+ return rc;
+
+page1_init_failed:
+ sqlitepager_unref(pBt->page1);
+ pBt->page1 = 0;
+ return rc;
+}
+
+/*
+** If there are no outstanding cursors and we are not in the middle
+** of a transaction but there is a read lock on the database, then
+** this routine unrefs the first page of the database file which
+** has the effect of releasing the read lock.
+**
+** If there are any outstanding cursors, this routine is a no-op.
+**
+** If there is a transaction in progress, this routine is a no-op.
+*/
+static void unlockBtreeIfUnused(Btree *pBt){
+ if( pBt->inTrans==0 && pBt->pCursor==0 && pBt->page1!=0 ){
+ sqlitepager_unref(pBt->page1);
+ pBt->page1 = 0;
+ pBt->inTrans = 0;
+ pBt->inCkpt = 0;
+ }
+}
+
+/*
+** Create a new database by initializing the first two pages of the
+** file.
+*/
+static int newDatabase(Btree *pBt){
+ MemPage *pRoot;
+ PageOne *pP1;
+ int rc;
+ if( sqlitepager_pagecount(pBt->pPager)>1 ) return STQLITE_OK;
+ pP1 = pBt->page1;
+ rc = sqlitepager_write(pBt->page1);
+ if( rc ) return rc;
+ rc = sqlitepager_get(pBt->pPager, 2, (void**)&pRoot);
+ if( rc ) return rc;
+ rc = sqlitepager_write(pRoot);
+ if( rc ){
+ sqlitepager_unref(pRoot);
+ return rc;
+ }
+ strcpy(pP1->zMagic, zMagicHeader);
+ if( btree_native_byte_order ){
+ pP1->iMagic = MAGIC;
+ pBt->needSwab = 0;
+ }else{
+ pP1->iMagic = swab32(MAGIC);
+ pBt->needSwab = 1;
+ }
+ zeroPage(pBt, pRoot);
+ sqlitepager_unref(pRoot);
+ return STQLITE_OK;
+}
+
+/*
+** Attempt to start a new transaction.
+**
+** A transaction must be started before attempting any changes
+** to the database. None of the following routines will work
+** unless a transaction is started first:
+**
+** sqliteBtreeCreateTable()
+** sqliteBtreeCreateIndex()
+** sqliteBtreeClearTable()
+** sqliteBtreeDropTable()
+** sqliteBtreeInsert()
+** sqliteBtreeDelete()
+** sqliteBtreeUpdateMeta()
+*/
+static int fileBtreeBeginTrans(Btree *pBt){
+ int rc;
+ if( pBt->inTrans ) return STQLITE_ERROR;
+ if( pBt->readOnly ) return STQLITE_READONLY;
+ if( pBt->page1==0 ){
+ rc = lockBtree(pBt);
+ if( rc!=STQLITE_OK ){
+ return rc;
+ }
+ }
+ rc = sqlitepager_begin(pBt->page1);
+ if( rc==STQLITE_OK ){
+ rc = newDatabase(pBt);
+ }
+ if( rc==STQLITE_OK ){
+ pBt->inTrans = 1;
+ pBt->inCkpt = 0;
+ }else{
+ unlockBtreeIfUnused(pBt);
+ }
+ return rc;
+}
+
+/*
+** Commit the transaction currently in progress.
+**
+** This will release the write lock on the database file. If there
+** are no active cursors, it also releases the read lock.
+*/
+static int fileBtreeCommit(Btree *pBt){
+ int rc;
+ rc = pBt->readOnly ? STQLITE_OK : sqlitepager_commit(pBt->pPager);
+ pBt->inTrans = 0;
+ pBt->inCkpt = 0;
+ unlockBtreeIfUnused(pBt);
+ return rc;
+}
+
+/*
+** Rollback the transaction in progress. All cursors will be
+** invalided by this operation. Any attempt to use a cursor
+** that was open at the beginning of this operation will result
+** in an error.
+**
+** This will release the write lock on the database file. If there
+** are no active cursors, it also releases the read lock.
+*/
+static int fileBtreeRollback(Btree *pBt){
+ int rc;
+ BtCursor *pCur;
+ if( pBt->inTrans==0 ) return STQLITE_OK;
+ pBt->inTrans = 0;
+ pBt->inCkpt = 0;
+ rc = pBt->readOnly ? STQLITE_OK : sqlitepager_rollback(pBt->pPager);
+ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
+ if( pCur->pPage && pCur->pPage->isInit==0 ){
+ sqlitepager_unref(pCur->pPage);
+ pCur->pPage = 0;
+ }
+ }
+ unlockBtreeIfUnused(pBt);
+ return rc;
+}
+
+/*
+** Set the checkpoint for the current transaction. The checkpoint serves
+** as a sub-transaction that can be rolled back independently of the
+** main transaction. You must start a transaction before starting a
+** checkpoint. The checkpoint is ended automatically if the transaction
+** commits or rolls back.
+**
+** Only one checkpoint may be active at a time. It is an error to try
+** to start a new checkpoint if another checkpoint is already active.
+*/
+static int fileBtreeBeginCkpt(Btree *pBt){
+ int rc;
+ if( !pBt->inTrans || pBt->inCkpt ){
+ return pBt->readOnly ? STQLITE_READONLY : STQLITE_ERROR;
+ }
+ rc = pBt->readOnly ? STQLITE_OK : sqlitepager_ckpt_begin(pBt->pPager);
+ pBt->inCkpt = 1;
+ return rc;
+}
+
+
+/*
+** Commit a checkpoint to transaction currently in progress. If no
+** checkpoint is active, this is a no-op.
+*/
+static int fileBtreeCommitCkpt(Btree *pBt){
+ int rc;
+ if( pBt->inCkpt && !pBt->readOnly ){
+ rc = sqlitepager_ckpt_commit(pBt->pPager);
+ }else{
+ rc = STQLITE_OK;
+ }
+ pBt->inCkpt = 0;
+ return rc;
+}
+
+/*
+** Rollback the checkpoint to the current transaction. If there
+** is no active checkpoint or transaction, this routine is a no-op.
+**
+** All cursors will be invalided by this operation. Any attempt
+** to use a cursor that was open at the beginning of this operation
+** will result in an error.
+*/
+static int fileBtreeRollbackCkpt(Btree *pBt){
+ int rc;
+ BtCursor *pCur;
+ if( pBt->inCkpt==0 || pBt->readOnly ) return STQLITE_OK;
+ rc = sqlitepager_ckpt_rollback(pBt->pPager);
+ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
+ if( pCur->pPage && pCur->pPage->isInit==0 ){
+ sqlitepager_unref(pCur->pPage);
+ pCur->pPage = 0;
+ }
+ }
+ pBt->inCkpt = 0;
+ return rc;
+}
+
+/*
+** Create a new cursor for the BTree whose root is on the page
+** iTable. The act of acquiring a cursor gets a read lock on
+** the database file.
+**
+** If wrFlag==0, then the cursor can only be used for reading.
+** If wrFlag==1, then the cursor can be used for reading or for
+** writing if other conditions for writing are also met. These
+** are the conditions that must be met in order for writing to
+** be allowed:
+**
+** 1: The cursor must have been opened with wrFlag==1
+**
+** 2: No other cursors may be open with wrFlag==0 on the same table
+**
+** 3: The database must be writable (not on read-only media)
+**
+** 4: There must be an active transaction.
+**
+** Condition 2 warrants further discussion. If any cursor is opened
+** on a table with wrFlag==0, that prevents all other cursors from
+** writing to that table. This is a kind of "read-lock". When a cursor
+** is opened with wrFlag==0 it is guaranteed that the table will not
+** change as long as the cursor is open. This allows the cursor to
+** do a sequential scan of the table without having to worry about
+** entries being inserted or deleted during the scan. Cursors should
+** be opened with wrFlag==0 only if this read-lock property is needed.
+** That is to say, cursors should be opened with wrFlag==0 only if they
+** intend to use the sqliteBtreeNext() system call. All other cursors
+** should be opened with wrFlag==1 even if they never really intend
+** to write.
+**
+** No checking is done to make sure that page iTable really is the
+** root page of a b-tree. If it is not, then the cursor acquired
+** will not work correctly.
+*/
+static int fileBtreeCursor(Btree *pBt, int iTable, int wrFlag, BtCursor **ppCur){
+ int rc;
+ BtCursor *pCur, *pRing;
+
+ if( pBt->page1==0 ){
+ rc = lockBtree(pBt);
+ if( rc!=STQLITE_OK ){
+ *ppCur = 0;
+ return rc;
+ }
+ }
+ pCur = sqliteMalloc( sizeof(*pCur) );
+ if( pCur==0 ){
+ rc = STQLITE_NOMEM;
+ goto create_cursor_exception;
+ }
+ pCur->pgnoRoot = (Pgno)iTable;
+ rc = sqlitepager_get(pBt->pPager, pCur->pgnoRoot, (void**)&pCur->pPage);
+ if( rc!=STQLITE_OK ){
+ goto create_cursor_exception;
+ }
+ rc = initPage(pBt, pCur->pPage, pCur->pgnoRoot, 0);
+ if( rc!=STQLITE_OK ){
+ goto create_cursor_exception;
+ }
+ pCur->pOps = &sqliteBtreeCursorOps;
+ pCur->pBt = pBt;
+ pCur->wrFlag = wrFlag;
+ pCur->idx = 0;
+ pCur->eSkip = SKIP_INVALID;
+ pCur->pNext = pBt->pCursor;
+ if( pCur->pNext ){
+ pCur->pNext->pPrev = pCur;
+ }
+ pCur->pPrev = 0;
+ pRing = pBt->pCursor;
+ while( pRing && pRing->pgnoRoot!=pCur->pgnoRoot ){ pRing = pRing->pNext; }
+ if( pRing ){
+ pCur->pShared = pRing->pShared;
+ pRing->pShared = pCur;
+ }else{
+ pCur->pShared = pCur;
+ }
+ pBt->pCursor = pCur;
+ *ppCur = pCur;
+ return STQLITE_OK;
+
+create_cursor_exception:
+ *ppCur = 0;
+ if( pCur ){
+ if( pCur->pPage ) sqlitepager_unref(pCur->pPage);
+ sqliteFree(pCur);
+ }
+ unlockBtreeIfUnused(pBt);
+ return rc;
+}
+
+/*
+** Close a cursor. The read lock on the database file is released
+** when the last cursor is closed.
+*/
+static int fileBtreeCloseCursor(BtCursor *pCur){
+ Btree *pBt = pCur->pBt;
+ if( pCur->pPrev ){
+ pCur->pPrev->pNext = pCur->pNext;
+ }else{
+ pBt->pCursor = pCur->pNext;
+ }
+ if( pCur->pNext ){
+ pCur->pNext->pPrev = pCur->pPrev;
+ }
+ if( pCur->pPage ){
+ sqlitepager_unref(pCur->pPage);
+ }
+ if( pCur->pShared!=pCur ){
+ BtCursor *pRing = pCur->pShared;
+ while( pRing->pShared!=pCur ){ pRing = pRing->pShared; }
+ pRing->pShared = pCur->pShared;
+ }
+ unlockBtreeIfUnused(pBt);
+ sqliteFree(pCur);
+ return STQLITE_OK;
+}
+
+/*
+** Make a temporary cursor by filling in the fields of pTempCur.
+** The temporary cursor is not on the cursor list for the Btree.
+*/
+static void getTempCursor(BtCursor *pCur, BtCursor *pTempCur){
+ memcpy(pTempCur, pCur, sizeof(*pCur));
+ pTempCur->pNext = 0;
+ pTempCur->pPrev = 0;
+ if( pTempCur->pPage ){
+ sqlitepager_ref(pTempCur->pPage);
+ }
+}
+
+/*
+** Delete a temporary cursor such as was made by the CreateTemporaryCursor()
+** function above.
+*/
+static void releaseTempCursor(BtCursor *pCur){
+ if( pCur->pPage ){
+ sqlitepager_unref(pCur->pPage);
+ }
+}
+
+/*
+** Set *pSize to the number of bytes of key in the entry the
+** cursor currently points to. Always return STQLITE_OK.
+** Failure is not possible. If the cursor is not currently
+** pointing to an entry (which can happen, for example, if
+** the database is empty) then *pSize is set to 0.
+*/
+static int fileBtreeKeySize(BtCursor *pCur, int *pSize){
+ Cell *pCell;
+ MemPage *pPage;
+
+ pPage = pCur->pPage;
+ assert( pPage!=0 );
+ if( pCur->idx >= pPage->nCell ){
+ *pSize = 0;
+ }else{
+ pCell = pPage->apCell[pCur->idx];
+ *pSize = NKEY(pCur->pBt, pCell->h);
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Read payload information from the entry that the pCur cursor is
+** pointing to. Begin reading the payload at "offset" and read
+** a total of "amt" bytes. Put the result in zBuf.
+**
+** This routine does not make a distinction between key and data.
+** It just reads bytes from the payload area.
+*/
+static int getPayload(BtCursor *pCur, int offset, int amt, char *zBuf){
+ char *aPayload;
+ Pgno nextPage;
+ int rc;
+ Btree *pBt = pCur->pBt;
+ assert( pCur!=0 && pCur->pPage!=0 );
+ assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
+ aPayload = pCur->pPage->apCell[pCur->idx]->aPayload;
+ if( offset<MX_LOCAL_PAYLOAD ){
+ int a = amt;
+ if( a+offset>MX_LOCAL_PAYLOAD ){
+ a = MX_LOCAL_PAYLOAD - offset;
+ }
+ memcpy(zBuf, &aPayload[offset], a);
+ if( a==amt ){
+ return STQLITE_OK;
+ }
+ offset = 0;
+ zBuf += a;
+ amt -= a;
+ }else{
+ offset -= MX_LOCAL_PAYLOAD;
+ }
+ if( amt>0 ){
+ nextPage = SWAB32(pBt, pCur->pPage->apCell[pCur->idx]->ovfl);
+ }
+ while( amt>0 && nextPage ){
+ OverflowPage *pOvfl;
+ rc = sqlitepager_get(pBt->pPager, nextPage, (void**)&pOvfl);
+ if( rc!=0 ){
+ return rc;
+ }
+ nextPage = SWAB32(pBt, pOvfl->iNext);
+ if( offset<OVERFLOW_SIZE ){
+ int a = amt;
+ if( a + offset > OVERFLOW_SIZE ){
+ a = OVERFLOW_SIZE - offset;
+ }
+ memcpy(zBuf, &pOvfl->aPayload[offset], a);
+ offset = 0;
+ amt -= a;
+ zBuf += a;
+ }else{
+ offset -= OVERFLOW_SIZE;
+ }
+ sqlitepager_unref(pOvfl);
+ }
+ if( amt>0 ){
+ return STQLITE_CORRUPT;
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Read part of the key associated with cursor pCur. A maximum
+** of "amt" bytes will be transfered into zBuf[]. The transfer
+** begins at "offset". The number of bytes actually read is
+** returned.
+**
+** Change: It used to be that the amount returned will be smaller
+** than the amount requested if there are not enough bytes in the key
+** to satisfy the request. But now, it must be the case that there
+** is enough data available to satisfy the request. If not, an exception
+** is raised. The change was made in an effort to boost performance
+** by eliminating unneeded tests.
+*/
+static int fileBtreeKey(BtCursor *pCur, int offset, int amt, char *zBuf){
+ MemPage *pPage;
+
+ assert( amt>=0 );
+ assert( offset>=0 );
+ assert( pCur->pPage!=0 );
+ pPage = pCur->pPage;
+ if( pCur->idx >= pPage->nCell ){
+ return 0;
+ }
+ assert( amt+offset <= NKEY(pCur->pBt, pPage->apCell[pCur->idx]->h) );
+ getPayload(pCur, offset, amt, zBuf);
+ return amt;
+}
+
+/*
+** Set *pSize to the number of bytes of data in the entry the
+** cursor currently points to. Always return STQLITE_OK.
+** Failure is not possible. If the cursor is not currently
+** pointing to an entry (which can happen, for example, if
+** the database is empty) then *pSize is set to 0.
+*/
+static int fileBtreeDataSize(BtCursor *pCur, int *pSize){
+ Cell *pCell;
+ MemPage *pPage;
+
+ pPage = pCur->pPage;
+ assert( pPage!=0 );
+ if( pCur->idx >= pPage->nCell ){
+ *pSize = 0;
+ }else{
+ pCell = pPage->apCell[pCur->idx];
+ *pSize = NDATA(pCur->pBt, pCell->h);
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Read part of the data associated with cursor pCur. A maximum
+** of "amt" bytes will be transfered into zBuf[]. The transfer
+** begins at "offset". The number of bytes actually read is
+** returned. The amount returned will be smaller than the
+** amount requested if there are not enough bytes in the data
+** to satisfy the request.
+*/
+static int fileBtreeData(BtCursor *pCur, int offset, int amt, char *zBuf){
+ Cell *pCell;
+ MemPage *pPage;
+
+ assert( amt>=0 );
+ assert( offset>=0 );
+ assert( pCur->pPage!=0 );
+ pPage = pCur->pPage;
+ if( pCur->idx >= pPage->nCell ){
+ return 0;
+ }
+ pCell = pPage->apCell[pCur->idx];
+ assert( amt+offset <= NDATA(pCur->pBt, pCell->h) );
+ getPayload(pCur, offset + NKEY(pCur->pBt, pCell->h), amt, zBuf);
+ return amt;
+}
+
+/*
+** Compare an external key against the key on the entry that pCur points to.
+**
+** The external key is pKey and is nKey bytes long. The last nIgnore bytes
+** of the key associated with pCur are ignored, as if they do not exist.
+** (The normal case is for nIgnore to be zero in which case the entire
+** internal key is used in the comparison.)
+**
+** The comparison result is written to *pRes as follows:
+**
+** *pRes<0 This means pCur<pKey
+**
+** *pRes==0 This means pCur==pKey for all nKey bytes
+**
+** *pRes>0 This means pCur>pKey
+**
+** When one key is an exact prefix of the other, the shorter key is
+** considered less than the longer one. In order to be equal the
+** keys must be exactly the same length. (The length of the pCur key
+** is the actual key length minus nIgnore bytes.)
+*/
+static int fileBtreeKeyCompare(
+ BtCursor *pCur, /* Pointer to entry to compare against */
+ const void *pKey, /* Key to compare against entry that pCur points to */
+ int nKey, /* Number of bytes in pKey */
+ int nIgnore, /* Ignore this many bytes at the end of pCur */
+ int *pResult /* Write the result here */
+){
+ Pgno nextPage;
+ int n, c, rc, nLocal;
+ Cell *pCell;
+ Btree *pBt = pCur->pBt;
+ const char *zKey = (const char*)pKey;
+
+ assert( pCur->pPage );
+ assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
+ pCell = pCur->pPage->apCell[pCur->idx];
+ nLocal = NKEY(pBt, pCell->h) - nIgnore;
+ if( nLocal<0 ) nLocal = 0;
+ n = nKey<nLocal ? nKey : nLocal;
+ if( n>MX_LOCAL_PAYLOAD ){
+ n = MX_LOCAL_PAYLOAD;
+ }
+ c = memcmp(pCell->aPayload, zKey, n);
+ if( c!=0 ){
+ *pResult = c;
+ return STQLITE_OK;
+ }
+ zKey += n;
+ nKey -= n;
+ nLocal -= n;
+ nextPage = SWAB32(pBt, pCell->ovfl);
+ while( nKey>0 && nLocal>0 ){
+ OverflowPage *pOvfl;
+ if( nextPage==0 ){
+ return STQLITE_CORRUPT;
+ }
+ rc = sqlitepager_get(pBt->pPager, nextPage, (void**)&pOvfl);
+ if( rc ){
+ return rc;
+ }
+ nextPage = SWAB32(pBt, pOvfl->iNext);
+ n = nKey<nLocal ? nKey : nLocal;
+ if( n>OVERFLOW_SIZE ){
+ n = OVERFLOW_SIZE;
+ }
+ c = memcmp(pOvfl->aPayload, zKey, n);
+ sqlitepager_unref(pOvfl);
+ if( c!=0 ){
+ *pResult = c;
+ return STQLITE_OK;
+ }
+ nKey -= n;
+ nLocal -= n;
+ zKey += n;
+ }
+ if( c==0 ){
+ c = nLocal - nKey;
+ }
+ *pResult = c;
+ return STQLITE_OK;
+}
+
+/*
+** Move the cursor down to a new child page. The newPgno argument is the
+** page number of the child page in the byte order of the disk image.
+*/
+static int moveToChild(BtCursor *pCur, int newPgno){
+ int rc;
+ MemPage *pNewPage;
+ Btree *pBt = pCur->pBt;
+
+ newPgno = SWAB32(pBt, newPgno);
+ rc = sqlitepager_get(pBt->pPager, newPgno, (void**)&pNewPage);
+ if( rc ) return rc;
+ rc = initPage(pBt, pNewPage, newPgno, pCur->pPage);
+ if( rc ) return rc;
+ assert( pCur->idx>=pCur->pPage->nCell
+ || pCur->pPage->apCell[pCur->idx]->h.leftChild==SWAB32(pBt,newPgno) );
+ assert( pCur->idx<pCur->pPage->nCell
+ || pCur->pPage->u.hdr.rightChild==SWAB32(pBt,newPgno) );
+ pNewPage->idxParent = pCur->idx;
+ pCur->pPage->idxShift = 0;
+ sqlitepager_unref(pCur->pPage);
+ pCur->pPage = pNewPage;
+ pCur->idx = 0;
+ if( pNewPage->nCell<1 ){
+ return STQLITE_CORRUPT;
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Move the cursor up to the tqparent page.
+**
+** pCur->idx is set to the cell index that tqcontains the pointer
+** to the page we are coming from. If we are coming from the
+** right-most child page then pCur->idx is set to one more than
+** the largest cell index.
+*/
+static void moveToParent(BtCursor *pCur){
+ Pgno oldPgno;
+ MemPage *pParent;
+ MemPage *pPage;
+ int idxParent;
+ pPage = pCur->pPage;
+ assert( pPage!=0 );
+ pParent = pPage->pParent;
+ assert( pParent!=0 );
+ idxParent = pPage->idxParent;
+ sqlitepager_ref(pParent);
+ sqlitepager_unref(pPage);
+ pCur->pPage = pParent;
+ assert( pParent->idxShift==0 );
+ if( pParent->idxShift==0 ){
+ pCur->idx = idxParent;
+#ifndef NDEBUG
+ /* Verify that pCur->idx is the correct index to point back to the child
+ ** page we just came from
+ */
+ oldPgno = SWAB32(pCur->pBt, sqlitepager_pagenumber(pPage));
+ if( pCur->idx<pParent->nCell ){
+ assert( pParent->apCell[idxParent]->h.leftChild==oldPgno );
+ }else{
+ assert( pParent->u.hdr.rightChild==oldPgno );
+ }
+#endif
+ }else{
+ /* The MemPage.idxShift flag indicates that cell indices might have
+ ** changed since idxParent was set and hence idxParent might be out
+ ** of date. So recompute the tqparent cell index by scanning all cells
+ ** and locating the one that points to the child we just came from.
+ */
+ int i;
+ pCur->idx = pParent->nCell;
+ oldPgno = SWAB32(pCur->pBt, sqlitepager_pagenumber(pPage));
+ for(i=0; i<pParent->nCell; i++){
+ if( pParent->apCell[i]->h.leftChild==oldPgno ){
+ pCur->idx = i;
+ break;
+ }
+ }
+ }
+}
+
+/*
+** Move the cursor to the root page
+*/
+static int moveToRoot(BtCursor *pCur){
+ MemPage *pNew;
+ int rc;
+ Btree *pBt = pCur->pBt;
+
+ rc = sqlitepager_get(pBt->pPager, pCur->pgnoRoot, (void**)&pNew);
+ if( rc ) return rc;
+ rc = initPage(pBt, pNew, pCur->pgnoRoot, 0);
+ if( rc ) return rc;
+ sqlitepager_unref(pCur->pPage);
+ pCur->pPage = pNew;
+ pCur->idx = 0;
+ return STQLITE_OK;
+}
+
+/*
+** Move the cursor down to the left-most leaf entry beneath the
+** entry to which it is currently pointing.
+*/
+static int moveToLeftmost(BtCursor *pCur){
+ Pgno pgno;
+ int rc;
+
+ while( (pgno = pCur->pPage->apCell[pCur->idx]->h.leftChild)!=0 ){
+ rc = moveToChild(pCur, pgno);
+ if( rc ) return rc;
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Move the cursor down to the right-most leaf entry beneath the
+** page to which it is currently pointing. Notice the difference
+** between moveToLeftmost() and moveToRightmost(). moveToLeftmost()
+** tqfinds the left-most entry beneath the *entry* whereas moveToRightmost()
+** tqfinds the right-most entry beneath the *page*.
+*/
+static int moveToRightmost(BtCursor *pCur){
+ Pgno pgno;
+ int rc;
+
+ while( (pgno = pCur->pPage->u.hdr.rightChild)!=0 ){
+ pCur->idx = pCur->pPage->nCell;
+ rc = moveToChild(pCur, pgno);
+ if( rc ) return rc;
+ }
+ pCur->idx = pCur->pPage->nCell - 1;
+ return STQLITE_OK;
+}
+
+/* Move the cursor to the first entry in the table. Return STQLITE_OK
+** on success. Set *pRes to 0 if the cursor actually points to something
+** or set *pRes to 1 if the table is empty.
+*/
+static int fileBtreeFirst(BtCursor *pCur, int *pRes){
+ int rc;
+ if( pCur->pPage==0 ) return STQLITE_ABORT;
+ rc = moveToRoot(pCur);
+ if( rc ) return rc;
+ if( pCur->pPage->nCell==0 ){
+ *pRes = 1;
+ return STQLITE_OK;
+ }
+ *pRes = 0;
+ rc = moveToLeftmost(pCur);
+ pCur->eSkip = SKIP_NONE;
+ return rc;
+}
+
+/* Move the cursor to the last entry in the table. Return STQLITE_OK
+** on success. Set *pRes to 0 if the cursor actually points to something
+** or set *pRes to 1 if the table is empty.
+*/
+static int fileBtreeLast(BtCursor *pCur, int *pRes){
+ int rc;
+ if( pCur->pPage==0 ) return STQLITE_ABORT;
+ rc = moveToRoot(pCur);
+ if( rc ) return rc;
+ assert( pCur->pPage->isInit );
+ if( pCur->pPage->nCell==0 ){
+ *pRes = 1;
+ return STQLITE_OK;
+ }
+ *pRes = 0;
+ rc = moveToRightmost(pCur);
+ pCur->eSkip = SKIP_NONE;
+ return rc;
+}
+
+/* Move the cursor so that it points to an entry near pKey.
+** Return a success code.
+**
+** If an exact match is not found, then the cursor is always
+** left pointing at a leaf page which would hold the entry if it
+** were present. The cursor might point to an entry that comes
+** before or after the key.
+**
+** The result of comparing the key with the entry to which the
+** cursor is left pointing is stored in pCur->iMatch. The same
+** value is also written to *pRes if pRes!=NULL. The meaning of
+** this value is as follows:
+**
+** *pRes<0 The cursor is left pointing at an entry that
+** is smaller than pKey or if the table is empty
+** and the cursor is therefore left point to nothing.
+**
+** *pRes==0 The cursor is left pointing at an entry that
+** exactly matches pKey.
+**
+** *pRes>0 The cursor is left pointing at an entry that
+** is larger than pKey.
+*/
+static
+int fileBtreeMoveto(BtCursor *pCur, const void *pKey, int nKey, int *pRes){
+ int rc;
+ if( pCur->pPage==0 ) return STQLITE_ABORT;
+ pCur->eSkip = SKIP_NONE;
+ rc = moveToRoot(pCur);
+ if( rc ) return rc;
+ for(;;){
+ int lwr, upr;
+ Pgno chldPg;
+ MemPage *pPage = pCur->pPage;
+ int c = -1; /* pRes return if table is empty must be -1 */
+ lwr = 0;
+ upr = pPage->nCell-1;
+ while( lwr<=upr ){
+ pCur->idx = (lwr+upr)/2;
+ rc = fileBtreeKeyCompare(pCur, pKey, nKey, 0, &c);
+ if( rc ) return rc;
+ if( c==0 ){
+ pCur->iMatch = c;
+ if( pRes ) *pRes = 0;
+ return STQLITE_OK;
+ }
+ if( c<0 ){
+ lwr = pCur->idx+1;
+ }else{
+ upr = pCur->idx-1;
+ }
+ }
+ assert( lwr==upr+1 );
+ assert( pPage->isInit );
+ if( lwr>=pPage->nCell ){
+ chldPg = pPage->u.hdr.rightChild;
+ }else{
+ chldPg = pPage->apCell[lwr]->h.leftChild;
+ }
+ if( chldPg==0 ){
+ pCur->iMatch = c;
+ if( pRes ) *pRes = c;
+ return STQLITE_OK;
+ }
+ pCur->idx = lwr;
+ rc = moveToChild(pCur, chldPg);
+ if( rc ) return rc;
+ }
+ /* NOT REACHED */
+}
+
+/*
+** Advance the cursor to the next entry in the database. If
+** successful then set *pRes=0. If the cursor
+** was already pointing to the last entry in the database before
+** this routine was called, then set *pRes=1.
+*/
+static int fileBtreeNext(BtCursor *pCur, int *pRes){
+ int rc;
+ MemPage *pPage = pCur->pPage;
+ assert( pRes!=0 );
+ if( pPage==0 ){
+ *pRes = 1;
+ return STQLITE_ABORT;
+ }
+ assert( pPage->isInit );
+ assert( pCur->eSkip!=SKIP_INVALID );
+ if( pPage->nCell==0 ){
+ *pRes = 1;
+ return STQLITE_OK;
+ }
+ assert( pCur->idx<pPage->nCell );
+ if( pCur->eSkip==SKIP_NEXT ){
+ pCur->eSkip = SKIP_NONE;
+ *pRes = 0;
+ return STQLITE_OK;
+ }
+ pCur->eSkip = SKIP_NONE;
+ pCur->idx++;
+ if( pCur->idx>=pPage->nCell ){
+ if( pPage->u.hdr.rightChild ){
+ rc = moveToChild(pCur, pPage->u.hdr.rightChild);
+ if( rc ) return rc;
+ rc = moveToLeftmost(pCur);
+ *pRes = 0;
+ return rc;
+ }
+ do{
+ if( pPage->pParent==0 ){
+ *pRes = 1;
+ return STQLITE_OK;
+ }
+ moveToParent(pCur);
+ pPage = pCur->pPage;
+ }while( pCur->idx>=pPage->nCell );
+ *pRes = 0;
+ return STQLITE_OK;
+ }
+ *pRes = 0;
+ if( pPage->u.hdr.rightChild==0 ){
+ return STQLITE_OK;
+ }
+ rc = moveToLeftmost(pCur);
+ return rc;
+}
+
+/*
+** Step the cursor to the back to the previous entry in the database. If
+** successful then set *pRes=0. If the cursor
+** was already pointing to the first entry in the database before
+** this routine was called, then set *pRes=1.
+*/
+static int fileBtreePrevious(BtCursor *pCur, int *pRes){
+ int rc;
+ Pgno pgno;
+ MemPage *pPage;
+ pPage = pCur->pPage;
+ if( pPage==0 ){
+ *pRes = 1;
+ return STQLITE_ABORT;
+ }
+ assert( pPage->isInit );
+ assert( pCur->eSkip!=SKIP_INVALID );
+ if( pPage->nCell==0 ){
+ *pRes = 1;
+ return STQLITE_OK;
+ }
+ if( pCur->eSkip==SKIP_PREV ){
+ pCur->eSkip = SKIP_NONE;
+ *pRes = 0;
+ return STQLITE_OK;
+ }
+ pCur->eSkip = SKIP_NONE;
+ assert( pCur->idx>=0 );
+ if( (pgno = pPage->apCell[pCur->idx]->h.leftChild)!=0 ){
+ rc = moveToChild(pCur, pgno);
+ if( rc ) return rc;
+ rc = moveToRightmost(pCur);
+ }else{
+ while( pCur->idx==0 ){
+ if( pPage->pParent==0 ){
+ if( pRes ) *pRes = 1;
+ return STQLITE_OK;
+ }
+ moveToParent(pCur);
+ pPage = pCur->pPage;
+ }
+ pCur->idx--;
+ rc = STQLITE_OK;
+ }
+ *pRes = 0;
+ return rc;
+}
+
+/*
+** Allocate a new page from the database file.
+**
+** The new page is marked as dirty. (In other words, sqlitepager_write()
+** has already been called on the new page.) The new page has also
+** been referenced and the calling routine is responsible for calling
+** sqlitepager_unref() on the new page when it is done.
+**
+** STQLITE_OK is returned on success. Any other return value indicates
+** an error. *ppPage and *pPgno are undefined in the event of an error.
+** Do not invoke sqlitepager_unref() on *ppPage if an error is returned.
+**
+** If the "nearby" parameter is not 0, then a (feeble) effort is made to
+** locate a page close to the page number "nearby". This can be used in an
+** attempt to keep related pages close to each other in the database file,
+** which in turn can make database access faster.
+*/
+static int allocatePage(Btree *pBt, MemPage **ppPage, Pgno *pPgno, Pgno nearby){
+ PageOne *pPage1 = pBt->page1;
+ int rc;
+ if( pPage1->freeList ){
+ OverflowPage *pOvfl;
+ FreelistInfo *pInfo;
+
+ rc = sqlitepager_write(pPage1);
+ if( rc ) return rc;
+ SWAB_ADD(pBt, pPage1->nFree, -1);
+ rc = sqlitepager_get(pBt->pPager, SWAB32(pBt, pPage1->freeList),
+ (void**)&pOvfl);
+ if( rc ) return rc;
+ rc = sqlitepager_write(pOvfl);
+ if( rc ){
+ sqlitepager_unref(pOvfl);
+ return rc;
+ }
+ pInfo = (FreelistInfo*)pOvfl->aPayload;
+ if( pInfo->nFree==0 ){
+ *pPgno = SWAB32(pBt, pPage1->freeList);
+ pPage1->freeList = pOvfl->iNext;
+ *ppPage = (MemPage*)pOvfl;
+ }else{
+ int closest, n;
+ n = SWAB32(pBt, pInfo->nFree);
+ if( n>1 && nearby>0 ){
+ int i, dist;
+ closest = 0;
+ dist = SWAB32(pBt, pInfo->aFree[0]) - nearby;
+ if( dist<0 ) dist = -dist;
+ for(i=1; i<n; i++){
+ int d2 = SWAB32(pBt, pInfo->aFree[i]) - nearby;
+ if( d2<0 ) d2 = -d2;
+ if( d2<dist ) closest = i;
+ }
+ }else{
+ closest = 0;
+ }
+ SWAB_ADD(pBt, pInfo->nFree, -1);
+ *pPgno = SWAB32(pBt, pInfo->aFree[closest]);
+ pInfo->aFree[closest] = pInfo->aFree[n-1];
+ rc = sqlitepager_get(pBt->pPager, *pPgno, (void**)ppPage);
+ sqlitepager_unref(pOvfl);
+ if( rc==STQLITE_OK ){
+ sqlitepager_dont_rollback(*ppPage);
+ rc = sqlitepager_write(*ppPage);
+ }
+ }
+ }else{
+ *pPgno = sqlitepager_pagecount(pBt->pPager) + 1;
+ rc = sqlitepager_get(pBt->pPager, *pPgno, (void**)ppPage);
+ if( rc ) return rc;
+ rc = sqlitepager_write(*ppPage);
+ }
+ return rc;
+}
+
+/*
+** Add a page of the database file to the freelist. Either pgno or
+** pPage but not both may be 0.
+**
+** sqlitepager_unref() is NOT called for pPage.
+*/
+static int freePage(Btree *pBt, void *pPage, Pgno pgno){
+ PageOne *pPage1 = pBt->page1;
+ OverflowPage *pOvfl = (OverflowPage*)pPage;
+ int rc;
+ int needUnref = 0;
+ MemPage *pMemPage;
+
+ if( pgno==0 ){
+ assert( pOvfl!=0 );
+ pgno = sqlitepager_pagenumber(pOvfl);
+ }
+ assert( pgno>2 );
+ assert( sqlitepager_pagenumber(pOvfl)==pgno );
+ pMemPage = (MemPage*)pPage;
+ pMemPage->isInit = 0;
+ if( pMemPage->pParent ){
+ sqlitepager_unref(pMemPage->pParent);
+ pMemPage->pParent = 0;
+ }
+ rc = sqlitepager_write(pPage1);
+ if( rc ){
+ return rc;
+ }
+ SWAB_ADD(pBt, pPage1->nFree, 1);
+ if( pPage1->nFree!=0 && pPage1->freeList!=0 ){
+ OverflowPage *pFreeIdx;
+ rc = sqlitepager_get(pBt->pPager, SWAB32(pBt, pPage1->freeList),
+ (void**)&pFreeIdx);
+ if( rc==STQLITE_OK ){
+ FreelistInfo *pInfo = (FreelistInfo*)pFreeIdx->aPayload;
+ int n = SWAB32(pBt, pInfo->nFree);
+ if( n<(sizeof(pInfo->aFree)/sizeof(pInfo->aFree[0])) ){
+ rc = sqlitepager_write(pFreeIdx);
+ if( rc==STQLITE_OK ){
+ pInfo->aFree[n] = SWAB32(pBt, pgno);
+ SWAB_ADD(pBt, pInfo->nFree, 1);
+ sqlitepager_unref(pFreeIdx);
+ sqlitepager_dont_write(pBt->pPager, pgno);
+ return rc;
+ }
+ }
+ sqlitepager_unref(pFreeIdx);
+ }
+ }
+ if( pOvfl==0 ){
+ assert( pgno>0 );
+ rc = sqlitepager_get(pBt->pPager, pgno, (void**)&pOvfl);
+ if( rc ) return rc;
+ needUnref = 1;
+ }
+ rc = sqlitepager_write(pOvfl);
+ if( rc ){
+ if( needUnref ) sqlitepager_unref(pOvfl);
+ return rc;
+ }
+ pOvfl->iNext = pPage1->freeList;
+ pPage1->freeList = SWAB32(pBt, pgno);
+ memset(pOvfl->aPayload, 0, OVERFLOW_SIZE);
+ if( needUnref ) rc = sqlitepager_unref(pOvfl);
+ return rc;
+}
+
+/*
+** Erase all the data out of a cell. This involves returning overflow
+** pages back the freelist.
+*/
+static int clearCell(Btree *pBt, Cell *pCell){
+ Pager *pPager = pBt->pPager;
+ OverflowPage *pOvfl;
+ Pgno ovfl, nextOvfl;
+ int rc;
+
+ if( NKEY(pBt, pCell->h) + NDATA(pBt, pCell->h) <= MX_LOCAL_PAYLOAD ){
+ return STQLITE_OK;
+ }
+ ovfl = SWAB32(pBt, pCell->ovfl);
+ pCell->ovfl = 0;
+ while( ovfl ){
+ rc = sqlitepager_get(pPager, ovfl, (void**)&pOvfl);
+ if( rc ) return rc;
+ nextOvfl = SWAB32(pBt, pOvfl->iNext);
+ rc = freePage(pBt, pOvfl, ovfl);
+ if( rc ) return rc;
+ sqlitepager_unref(pOvfl);
+ ovfl = nextOvfl;
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Create a new cell from key and data. Overflow pages are allocated as
+** necessary and linked to this cell.
+*/
+static int fillInCell(
+ Btree *pBt, /* The whole Btree. Needed to allocate pages */
+ Cell *pCell, /* Populate this Cell structure */
+ const void *pKey, int nKey, /* The key */
+ const void *pData,int nData /* The data */
+){
+ OverflowPage *pOvfl, *pPrior;
+ Pgno *pNext;
+ int spaceLeft;
+ int n, rc;
+ int nPayload;
+ const char *pPayload;
+ char *pSpace;
+ Pgno nearby = 0;
+
+ pCell->h.leftChild = 0;
+ pCell->h.nKey = SWAB16(pBt, nKey & 0xffff);
+ pCell->h.nKeyHi = nKey >> 16;
+ pCell->h.nData = SWAB16(pBt, nData & 0xffff);
+ pCell->h.nDataHi = nData >> 16;
+ pCell->h.iNext = 0;
+
+ pNext = &pCell->ovfl;
+ pSpace = pCell->aPayload;
+ spaceLeft = MX_LOCAL_PAYLOAD;
+ pPayload = pKey;
+ pKey = 0;
+ nPayload = nKey;
+ pPrior = 0;
+ while( nPayload>0 ){
+ if( spaceLeft==0 ){
+ rc = allocatePage(pBt, (MemPage**)&pOvfl, pNext, nearby);
+ if( rc ){
+ *pNext = 0;
+ }else{
+ nearby = *pNext;
+ }
+ if( pPrior ) sqlitepager_unref(pPrior);
+ if( rc ){
+ clearCell(pBt, pCell);
+ return rc;
+ }
+ if( pBt->needSwab ) *pNext = swab32(*pNext);
+ pPrior = pOvfl;
+ spaceLeft = OVERFLOW_SIZE;
+ pSpace = pOvfl->aPayload;
+ pNext = &pOvfl->iNext;
+ }
+ n = nPayload;
+ if( n>spaceLeft ) n = spaceLeft;
+ memcpy(pSpace, pPayload, n);
+ nPayload -= n;
+ if( nPayload==0 && pData ){
+ pPayload = pData;
+ nPayload = nData;
+ pData = 0;
+ }else{
+ pPayload += n;
+ }
+ spaceLeft -= n;
+ pSpace += n;
+ }
+ *pNext = 0;
+ if( pPrior ){
+ sqlitepager_unref(pPrior);
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Change the MemPage.pParent pointer on the page whose number is
+** given in the second argument so that MemPage.pParent holds the
+** pointer in the third argument.
+*/
+static void reparentPage(Pager *pPager, Pgno pgno, MemPage *pNewParent,int idx){
+ MemPage *pThis;
+
+ if( pgno==0 ) return;
+ assert( pPager!=0 );
+ pThis = sqlitepager_lookup(pPager, pgno);
+ if( pThis && pThis->isInit ){
+ if( pThis->pParent!=pNewParent ){
+ if( pThis->pParent ) sqlitepager_unref(pThis->pParent);
+ pThis->pParent = pNewParent;
+ if( pNewParent ) sqlitepager_ref(pNewParent);
+ }
+ pThis->idxParent = idx;
+ sqlitepager_unref(pThis);
+ }
+}
+
+/*
+** Retqparent all tqchildren of the given page to be the given page.
+** In other words, for every child of pPage, invoke reparentPage()
+** to make sure that each child knows that pPage is its tqparent.
+**
+** This routine gets called after you memcpy() one page into
+** another.
+*/
+static void reparentChildPages(Btree *pBt, MemPage *pPage){
+ int i;
+ Pager *pPager = pBt->pPager;
+ for(i=0; i<pPage->nCell; i++){
+ reparentPage(pPager, SWAB32(pBt, pPage->apCell[i]->h.leftChild), pPage, i);
+ }
+ reparentPage(pPager, SWAB32(pBt, pPage->u.hdr.rightChild), pPage, i);
+ pPage->idxShift = 0;
+}
+
+/*
+** Remove the i-th cell from pPage. This routine effects pPage only.
+** The cell content is not freed or deallocated. It is assumed that
+** the cell content has been copied someplace else. This routine just
+** removes the reference to the cell from pPage.
+**
+** "sz" must be the number of bytes in the cell.
+**
+** Do not bother maintaining the integrity of the linked list of Cells.
+** Only the pPage->apCell[] array is important. The relinkCellList()
+** routine will be called soon after this routine in order to rebuild
+** the linked list.
+*/
+static void dropCell(Btree *pBt, MemPage *pPage, int idx, int sz){
+ int j;
+ assert( idx>=0 && idx<pPage->nCell );
+ assert( sz==cellSize(pBt, pPage->apCell[idx]) );
+ assert( sqlitepager_iswriteable(pPage) );
+ freeSpace(pBt, pPage, Addr(pPage->apCell[idx]) - Addr(pPage), sz);
+ for(j=idx; j<pPage->nCell-1; j++){
+ pPage->apCell[j] = pPage->apCell[j+1];
+ }
+ pPage->nCell--;
+ pPage->idxShift = 1;
+}
+
+/*
+** Insert a new cell on pPage at cell index "i". pCell points to the
+** content of the cell.
+**
+** If the cell content will fit on the page, then put it there. If it
+** will not fit, then just make pPage->apCell[i] point to the content
+** and set pPage->isOverfull.
+**
+** Do not bother maintaining the integrity of the linked list of Cells.
+** Only the pPage->apCell[] array is important. The relinkCellList()
+** routine will be called soon after this routine in order to rebuild
+** the linked list.
+*/
+static void insertCell(Btree *pBt, MemPage *pPage, int i, Cell *pCell, int sz){
+ int idx, j;
+ assert( i>=0 && i<=pPage->nCell );
+ assert( sz==cellSize(pBt, pCell) );
+ assert( sqlitepager_iswriteable(pPage) );
+ idx = allocateSpace(pBt, pPage, sz);
+ for(j=pPage->nCell; j>i; j--){
+ pPage->apCell[j] = pPage->apCell[j-1];
+ }
+ pPage->nCell++;
+ if( idx<=0 ){
+ pPage->isOverfull = 1;
+ pPage->apCell[i] = pCell;
+ }else{
+ memcpy(&pPage->u.aDisk[idx], pCell, sz);
+ pPage->apCell[i] = (Cell*)&pPage->u.aDisk[idx];
+ }
+ pPage->idxShift = 1;
+}
+
+/*
+** Rebuild the linked list of cells on a page so that the cells
+** occur in the order specified by the pPage->apCell[] array.
+** Invoke this routine once to repair damage after one or more
+** invocations of either insertCell() or dropCell().
+*/
+static void relinkCellList(Btree *pBt, MemPage *pPage){
+ int i;
+ u16 *pIdx;
+ assert( sqlitepager_iswriteable(pPage) );
+ pIdx = &pPage->u.hdr.firstCell;
+ for(i=0; i<pPage->nCell; i++){
+ int idx = Addr(pPage->apCell[i]) - Addr(pPage);
+ assert( idx>0 && idx<STQLITE_USABLE_SIZE );
+ *pIdx = SWAB16(pBt, idx);
+ pIdx = &pPage->apCell[i]->h.iNext;
+ }
+ *pIdx = 0;
+}
+
+/*
+** Make a copy of the contents of pFrom into pTo. The pFrom->apCell[]
+** pointers that point into pFrom->u.aDisk[] must be adjusted to point
+** into pTo->u.aDisk[] instead. But some pFrom->apCell[] entries might
+** not point to pFrom->u.aDisk[]. Those are unchanged.
+*/
+static void copyPage(MemPage *pTo, MemPage *pFrom){
+ uptr from, to;
+ int i;
+ memcpy(pTo->u.aDisk, pFrom->u.aDisk, STQLITE_USABLE_SIZE);
+ pTo->pParent = 0;
+ pTo->isInit = 1;
+ pTo->nCell = pFrom->nCell;
+ pTo->nFree = pFrom->nFree;
+ pTo->isOverfull = pFrom->isOverfull;
+ to = Addr(pTo);
+ from = Addr(pFrom);
+ for(i=0; i<pTo->nCell; i++){
+ uptr x = Addr(pFrom->apCell[i]);
+ if( x>from && x<from+STQLITE_USABLE_SIZE ){
+ *((uptr*)&pTo->apCell[i]) = x + to - from;
+ }else{
+ pTo->apCell[i] = pFrom->apCell[i];
+ }
+ }
+}
+
+/*
+** The following parameters determine how many adjacent pages get involved
+** in a balancing operation. NN is the number of neighbors on either side
+** of the page that participate in the balancing operation. NB is the
+** total number of pages that participate, including the target page and
+** NN neighbors on either side.
+**
+** The minimum value of NN is 1 (of course). Increasing NN above 1
+** (to 2 or 3) gives a modest improvement in SELECT and DELETE performance
+** in exchange for a larger degradation in INSERT and UPDATE performance.
+** The value of NN appears to give the best results overall.
+*/
+#define NN 1 /* Number of neighbors on either side of pPage */
+#define NB (NN*2+1) /* Total pages involved in the balance */
+
+/*
+** This routine redistributes Cells on pPage and up to two siblings
+** of pPage so that all pages have about the same amount of free space.
+** Usually one sibling on either side of pPage is used in the balancing,
+** though both siblings might come from one side if pPage is the first
+** or last child of its tqparent. If pPage has fewer than two siblings
+** (something which can only happen if pPage is the root page or a
+** child of root) then all available siblings participate in the balancing.
+**
+** The number of siblings of pPage might be increased or decreased by
+** one in an effort to keep pages between 66% and 100% full. The root page
+** is special and is allowed to be less than 66% full. If pPage is
+** the root page, then the depth of the tree might be increased
+** or decreased by one, as necessary, to keep the root page from being
+** overfull or empty.
+**
+** This routine calls relinkCellList() on its input page regardless of
+** whether or not it does any real balancing. Client routines will typically
+** invoke insertCell() or dropCell() before calling this routine, so we
+** need to call relinkCellList() to clean up the mess that those other
+** routines left behind.
+**
+** pCur is left pointing to the same cell as when this routine was called
+** even if that cell gets moved to a different page. pCur may be NULL.
+** Set the pCur parameter to NULL if you do not care about keeping track
+** of a cell as that will save this routine the work of keeping track of it.
+**
+** Note that when this routine is called, some of the Cells on pPage
+** might not actually be stored in pPage->u.aDisk[]. This can happen
+** if the page is overfull. Part of the job of this routine is to
+** make sure all Cells for pPage once again fit in pPage->u.aDisk[].
+**
+** In the course of balancing the siblings of pPage, the tqparent of pPage
+** might become overfull or underfull. If that happens, then this routine
+** is called recursively on the tqparent.
+**
+** If this routine fails for any reason, it might leave the database
+** in a corrupted state. So if this routine fails, the database should
+** be rolled back.
+*/
+static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
+ MemPage *pParent; /* The tqparent of pPage */
+ int nCell; /* Number of cells in apCell[] */
+ int nOld; /* Number of pages in apOld[] */
+ int nNew; /* Number of pages in apNew[] */
+ int nDiv; /* Number of cells in apDiv[] */
+ int i, j, k; /* Loop counters */
+ int idx; /* Index of pPage in pParent->apCell[] */
+ int nxDiv; /* Next divider slot in pParent->apCell[] */
+ int rc; /* The return code */
+ int iCur; /* apCell[iCur] is the cell of the cursor */
+ MemPage *pOldCurPage; /* The cursor originally points to this page */
+ int subtotal; /* Subtotal of bytes in cells on one page */
+ MemPage *extraUnref = 0; /* A page that needs to be unref-ed */
+ MemPage *apOld[NB]; /* pPage and up to two siblings */
+ Pgno pgnoOld[NB]; /* Page numbers for each page in apOld[] */
+ MemPage *apNew[NB+1]; /* pPage and up to NB siblings after balancing */
+ Pgno pgnoNew[NB+1]; /* Page numbers for each page in apNew[] */
+ int idxDiv[NB]; /* Indices of divider cells in pParent */
+ Cell *apDiv[NB]; /* Divider cells in pParent */
+ Cell aTemp[NB]; /* Temporary holding area for apDiv[] */
+ int cntNew[NB+1]; /* Index in apCell[] of cell after i-th page */
+ int szNew[NB+1]; /* Combined size of cells place on i-th page */
+ MemPage aOld[NB]; /* Temporary copies of pPage and its siblings */
+ Cell *apCell[(MX_CELL+2)*NB]; /* All cells from pages being balanced */
+ int szCell[(MX_CELL+2)*NB]; /* Local size of all cells */
+
+ /*
+ ** Return without doing any work if pPage is neither overfull nor
+ ** underfull.
+ */
+ assert( sqlitepager_iswriteable(pPage) );
+ if( !pPage->isOverfull && pPage->nFree<STQLITE_USABLE_SIZE/2
+ && pPage->nCell>=2){
+ relinkCellList(pBt, pPage);
+ return STQLITE_OK;
+ }
+
+ /*
+ ** Find the tqparent of the page to be balanceed.
+ ** If there is no tqparent, it means this page is the root page and
+ ** special rules apply.
+ */
+ pParent = pPage->pParent;
+ if( pParent==0 ){
+ Pgno pgnoChild;
+ MemPage *pChild;
+ assert( pPage->isInit );
+ if( pPage->nCell==0 ){
+ if( pPage->u.hdr.rightChild ){
+ /*
+ ** The root page is empty. Copy the one child page
+ ** into the root page and return. This reduces the depth
+ ** of the BTree by one.
+ */
+ pgnoChild = SWAB32(pBt, pPage->u.hdr.rightChild);
+ rc = sqlitepager_get(pBt->pPager, pgnoChild, (void**)&pChild);
+ if( rc ) return rc;
+ memcpy(pPage, pChild, STQLITE_USABLE_SIZE);
+ pPage->isInit = 0;
+ rc = initPage(pBt, pPage, sqlitepager_pagenumber(pPage), 0);
+ assert( rc==STQLITE_OK );
+ reparentChildPages(pBt, pPage);
+ if( pCur && pCur->pPage==pChild ){
+ sqlitepager_unref(pChild);
+ pCur->pPage = pPage;
+ sqlitepager_ref(pPage);
+ }
+ freePage(pBt, pChild, pgnoChild);
+ sqlitepager_unref(pChild);
+ }else{
+ relinkCellList(pBt, pPage);
+ }
+ return STQLITE_OK;
+ }
+ if( !pPage->isOverfull ){
+ /* It is OK for the root page to be less than half full.
+ */
+ relinkCellList(pBt, pPage);
+ return STQLITE_OK;
+ }
+ /*
+ ** If we get to here, it means the root page is overfull.
+ ** When this happens, Create a new child page and copy the
+ ** contents of the root into the child. Then make the root
+ ** page an empty page with rightChild pointing to the new
+ ** child. Then fall thru to the code below which will cause
+ ** the overfull child page to be split.
+ */
+ rc = sqlitepager_write(pPage);
+ if( rc ) return rc;
+ rc = allocatePage(pBt, &pChild, &pgnoChild, sqlitepager_pagenumber(pPage));
+ if( rc ) return rc;
+ assert( sqlitepager_iswriteable(pChild) );
+ copyPage(pChild, pPage);
+ pChild->pParent = pPage;
+ pChild->idxParent = 0;
+ sqlitepager_ref(pPage);
+ pChild->isOverfull = 1;
+ if( pCur && pCur->pPage==pPage ){
+ sqlitepager_unref(pPage);
+ pCur->pPage = pChild;
+ }else{
+ extraUnref = pChild;
+ }
+ zeroPage(pBt, pPage);
+ pPage->u.hdr.rightChild = SWAB32(pBt, pgnoChild);
+ pParent = pPage;
+ pPage = pChild;
+ }
+ rc = sqlitepager_write(pParent);
+ if( rc ) return rc;
+ assert( pParent->isInit );
+
+ /*
+ ** Find the Cell in the tqparent page whose h.leftChild points back
+ ** to pPage. The "idx" variable is the index of that cell. If pPage
+ ** is the rightmost child of pParent then set idx to pParent->nCell
+ */
+ if( pParent->idxShift ){
+ Pgno pgno, swabPgno;
+ pgno = sqlitepager_pagenumber(pPage);
+ swabPgno = SWAB32(pBt, pgno);
+ for(idx=0; idx<pParent->nCell; idx++){
+ if( pParent->apCell[idx]->h.leftChild==swabPgno ){
+ break;
+ }
+ }
+ assert( idx<pParent->nCell || pParent->u.hdr.rightChild==swabPgno );
+ }else{
+ idx = pPage->idxParent;
+ }
+
+ /*
+ ** Initialize variables so that it will be safe to jump
+ ** directly to balance_cleanup at any moment.
+ */
+ nOld = nNew = 0;
+ sqlitepager_ref(pParent);
+
+ /*
+ ** Find sibling pages to pPage and the Cells in pParent that divide
+ ** the siblings. An attempt is made to tqfind NN siblings on either
+ ** side of pPage. More siblings are taken from one side, however, if
+ ** pPage there are fewer than NN siblings on the other side. If pParent
+ ** has NB or fewer tqchildren then all tqchildren of pParent are taken.
+ */
+ nxDiv = idx - NN;
+ if( nxDiv + NB > pParent->nCell ){
+ nxDiv = pParent->nCell - NB + 1;
+ }
+ if( nxDiv<0 ){
+ nxDiv = 0;
+ }
+ nDiv = 0;
+ for(i=0, k=nxDiv; i<NB; i++, k++){
+ if( k<pParent->nCell ){
+ idxDiv[i] = k;
+ apDiv[i] = pParent->apCell[k];
+ nDiv++;
+ pgnoOld[i] = SWAB32(pBt, apDiv[i]->h.leftChild);
+ }else if( k==pParent->nCell ){
+ pgnoOld[i] = SWAB32(pBt, pParent->u.hdr.rightChild);
+ }else{
+ break;
+ }
+ rc = sqlitepager_get(pBt->pPager, pgnoOld[i], (void**)&apOld[i]);
+ if( rc ) goto balance_cleanup;
+ rc = initPage(pBt, apOld[i], pgnoOld[i], pParent);
+ if( rc ) goto balance_cleanup;
+ apOld[i]->idxParent = k;
+ nOld++;
+ }
+
+ /*
+ ** Set iCur to be the index in apCell[] of the cell that the cursor
+ ** is pointing to. We will need this later on in order to keep the
+ ** cursor pointing at the same cell. If pCur points to a page that
+ ** has no involvement with this rebalancing, then set iCur to a large
+ ** number so that the iCur==j tests always fail in the main cell
+ ** distribution loop below.
+ */
+ if( pCur ){
+ iCur = 0;
+ for(i=0; i<nOld; i++){
+ if( pCur->pPage==apOld[i] ){
+ iCur += pCur->idx;
+ break;
+ }
+ iCur += apOld[i]->nCell;
+ if( i<nOld-1 && pCur->pPage==pParent && pCur->idx==idxDiv[i] ){
+ break;
+ }
+ iCur++;
+ }
+ pOldCurPage = pCur->pPage;
+ }
+
+ /*
+ ** Make copies of the content of pPage and its siblings into aOld[].
+ ** The rest of this function will use data from the copies rather
+ ** that the original pages since the original pages will be in the
+ ** process of being overwritten.
+ */
+ for(i=0; i<nOld; i++){
+ copyPage(&aOld[i], apOld[i]);
+ }
+
+ /*
+ ** Load pointers to all cells on sibling pages and the divider cells
+ ** into the local apCell[] array. Make copies of the divider cells
+ ** into aTemp[] and remove the the divider Cells from pParent.
+ */
+ nCell = 0;
+ for(i=0; i<nOld; i++){
+ MemPage *pOld = &aOld[i];
+ for(j=0; j<pOld->nCell; j++){
+ apCell[nCell] = pOld->apCell[j];
+ szCell[nCell] = cellSize(pBt, apCell[nCell]);
+ nCell++;
+ }
+ if( i<nOld-1 ){
+ szCell[nCell] = cellSize(pBt, apDiv[i]);
+ memcpy(&aTemp[i], apDiv[i], szCell[nCell]);
+ apCell[nCell] = &aTemp[i];
+ dropCell(pBt, pParent, nxDiv, szCell[nCell]);
+ assert( SWAB32(pBt, apCell[nCell]->h.leftChild)==pgnoOld[i] );
+ apCell[nCell]->h.leftChild = pOld->u.hdr.rightChild;
+ nCell++;
+ }
+ }
+
+ /*
+ ** Figure out the number of pages needed to hold all nCell cells.
+ ** Store this number in "k". Also compute szNew[] which is the total
+ ** size of all cells on the i-th page and cntNew[] which is the index
+ ** in apCell[] of the cell that divides path i from path i+1.
+ ** cntNew[k] should equal nCell.
+ **
+ ** This little patch of code is critical for keeping the tree
+ ** balanced.
+ */
+ for(subtotal=k=i=0; i<nCell; i++){
+ subtotal += szCell[i];
+ if( subtotal > USABLE_SPACE ){
+ szNew[k] = subtotal - szCell[i];
+ cntNew[k] = i;
+ subtotal = 0;
+ k++;
+ }
+ }
+ szNew[k] = subtotal;
+ cntNew[k] = nCell;
+ k++;
+ for(i=k-1; i>0; i--){
+ while( szNew[i]<USABLE_SPACE/2 ){
+ cntNew[i-1]--;
+ assert( cntNew[i-1]>0 );
+ szNew[i] += szCell[cntNew[i-1]];
+ szNew[i-1] -= szCell[cntNew[i-1]-1];
+ }
+ }
+ assert( cntNew[0]>0 );
+
+ /*
+ ** Allocate k new pages. Reuse old pages where possible.
+ */
+ for(i=0; i<k; i++){
+ if( i<nOld ){
+ apNew[i] = apOld[i];
+ pgnoNew[i] = pgnoOld[i];
+ apOld[i] = 0;
+ sqlitepager_write(apNew[i]);
+ }else{
+ rc = allocatePage(pBt, &apNew[i], &pgnoNew[i], pgnoNew[i-1]);
+ if( rc ) goto balance_cleanup;
+ }
+ nNew++;
+ zeroPage(pBt, apNew[i]);
+ apNew[i]->isInit = 1;
+ }
+
+ /* Free any old pages that were not reused as new pages.
+ */
+ while( i<nOld ){
+ rc = freePage(pBt, apOld[i], pgnoOld[i]);
+ if( rc ) goto balance_cleanup;
+ sqlitepager_unref(apOld[i]);
+ apOld[i] = 0;
+ i++;
+ }
+
+ /*
+ ** Put the new pages in accending order. This helps to
+ ** keep entries in the disk file in order so that a scan
+ ** of the table is a linear scan through the file. That
+ ** in turn helps the operating system to deliver pages
+ ** from the disk more rapidly.
+ **
+ ** An O(n^2) insertion sort algorithm is used, but since
+ ** n is never more than NB (a small constant), that should
+ ** not be a problem.
+ **
+ ** When NB==3, this one optimization makes the database
+ ** about 25% faster for large insertions and deletions.
+ */
+ for(i=0; i<k-1; i++){
+ int minV = pgnoNew[i];
+ int minI = i;
+ for(j=i+1; j<k; j++){
+ if( pgnoNew[j]<(unsigned)minV ){
+ minI = j;
+ minV = pgnoNew[j];
+ }
+ }
+ if( minI>i ){
+ int t;
+ MemPage *pT;
+ t = pgnoNew[i];
+ pT = apNew[i];
+ pgnoNew[i] = pgnoNew[minI];
+ apNew[i] = apNew[minI];
+ pgnoNew[minI] = t;
+ apNew[minI] = pT;
+ }
+ }
+
+ /*
+ ** Evenly distribute the data in apCell[] across the new pages.
+ ** Insert divider cells into pParent as necessary.
+ */
+ j = 0;
+ for(i=0; i<nNew; i++){
+ MemPage *pNew = apNew[i];
+ while( j<cntNew[i] ){
+ assert( pNew->nFree>=szCell[j] );
+ if( pCur && iCur==j ){ pCur->pPage = pNew; pCur->idx = pNew->nCell; }
+ insertCell(pBt, pNew, pNew->nCell, apCell[j], szCell[j]);
+ j++;
+ }
+ assert( pNew->nCell>0 );
+ assert( !pNew->isOverfull );
+ relinkCellList(pBt, pNew);
+ if( i<nNew-1 && j<nCell ){
+ pNew->u.hdr.rightChild = apCell[j]->h.leftChild;
+ apCell[j]->h.leftChild = SWAB32(pBt, pgnoNew[i]);
+ if( pCur && iCur==j ){ pCur->pPage = pParent; pCur->idx = nxDiv; }
+ insertCell(pBt, pParent, nxDiv, apCell[j], szCell[j]);
+ j++;
+ nxDiv++;
+ }
+ }
+ assert( j==nCell );
+ apNew[nNew-1]->u.hdr.rightChild = aOld[nOld-1].u.hdr.rightChild;
+ if( nxDiv==pParent->nCell ){
+ pParent->u.hdr.rightChild = SWAB32(pBt, pgnoNew[nNew-1]);
+ }else{
+ pParent->apCell[nxDiv]->h.leftChild = SWAB32(pBt, pgnoNew[nNew-1]);
+ }
+ if( pCur ){
+ if( j<=iCur && pCur->pPage==pParent && pCur->idx>idxDiv[nOld-1] ){
+ assert( pCur->pPage==pOldCurPage );
+ pCur->idx += nNew - nOld;
+ }else{
+ assert( pOldCurPage!=0 );
+ sqlitepager_ref(pCur->pPage);
+ sqlitepager_unref(pOldCurPage);
+ }
+ }
+
+ /*
+ ** Retqparent tqchildren of all cells.
+ */
+ for(i=0; i<nNew; i++){
+ reparentChildPages(pBt, apNew[i]);
+ }
+ reparentChildPages(pBt, pParent);
+
+ /*
+ ** balance the tqparent page.
+ */
+ rc = balance(pBt, pParent, pCur);
+
+ /*
+ ** Cleanup before returning.
+ */
+balance_cleanup:
+ if( extraUnref ){
+ sqlitepager_unref(extraUnref);
+ }
+ for(i=0; i<nOld; i++){
+ if( apOld[i]!=0 && apOld[i]!=&aOld[i] ) sqlitepager_unref(apOld[i]);
+ }
+ for(i=0; i<nNew; i++){
+ sqlitepager_unref(apNew[i]);
+ }
+ if( pCur && pCur->pPage==0 ){
+ pCur->pPage = pParent;
+ pCur->idx = 0;
+ }else{
+ sqlitepager_unref(pParent);
+ }
+ return rc;
+}
+
+/*
+** This routine checks all cursors that point to the same table
+** as pCur points to. If any of those cursors were opened with
+** wrFlag==0 then this routine returns STQLITE_LOCKED. If all
+** cursors point to the same table were opened with wrFlag==1
+** then this routine returns STQLITE_OK.
+**
+** In addition to checking for read-locks (where a read-lock
+** means a cursor opened with wrFlag==0) this routine also moves
+** all cursors other than pCur so that they are pointing to the
+** first Cell on root page. This is necessary because an insert
+** or delete might change the number of cells on a page or delete
+** a page entirely and we do not want to leave any cursors
+** pointing to non-existant pages or cells.
+*/
+static int checkReadLocks(BtCursor *pCur){
+ BtCursor *p;
+ assert( pCur->wrFlag );
+ for(p=pCur->pShared; p!=pCur; p=p->pShared){
+ assert( p );
+ assert( p->pgnoRoot==pCur->pgnoRoot );
+ if( p->wrFlag==0 ) return STQLITE_LOCKED;
+ if( sqlitepager_pagenumber(p->pPage)!=p->pgnoRoot ){
+ moveToRoot(p);
+ }
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Insert a new record into the BTree. The key is given by (pKey,nKey)
+** and the data is given by (pData,nData). The cursor is used only to
+** define what database the record should be inserted into. The cursor
+** is left pointing at the new record.
+*/
+static int fileBtreeInsert(
+ BtCursor *pCur, /* Insert data into the table of this cursor */
+ const void *pKey, int nKey, /* The key of the new record */
+ const void *pData, int nData /* The data of the new record */
+){
+ Cell newCell;
+ int rc;
+ int loc;
+ int szNew;
+ MemPage *pPage;
+ Btree *pBt = pCur->pBt;
+
+ if( pCur->pPage==0 ){
+ return STQLITE_ABORT; /* A rollback destroyed this cursor */
+ }
+ if( !pBt->inTrans || nKey+nData==0 ){
+ /* Must start a transaction before doing an insert */
+ return pBt->readOnly ? STQLITE_READONLY : STQLITE_ERROR;
+ }
+ assert( !pBt->readOnly );
+ if( !pCur->wrFlag ){
+ return STQLITE_PERM; /* Cursor not open for writing */
+ }
+ if( checkReadLocks(pCur) ){
+ return STQLITE_LOCKED; /* The table pCur points to has a read lock */
+ }
+ rc = fileBtreeMoveto(pCur, pKey, nKey, &loc);
+ if( rc ) return rc;
+ pPage = pCur->pPage;
+ assert( pPage->isInit );
+ rc = sqlitepager_write(pPage);
+ if( rc ) return rc;
+ rc = fillInCell(pBt, &newCell, pKey, nKey, pData, nData);
+ if( rc ) return rc;
+ szNew = cellSize(pBt, &newCell);
+ if( loc==0 ){
+ newCell.h.leftChild = pPage->apCell[pCur->idx]->h.leftChild;
+ rc = clearCell(pBt, pPage->apCell[pCur->idx]);
+ if( rc ) return rc;
+ dropCell(pBt, pPage, pCur->idx, cellSize(pBt, pPage->apCell[pCur->idx]));
+ }else if( loc<0 && pPage->nCell>0 ){
+ assert( pPage->u.hdr.rightChild==0 ); /* Must be a leaf page */
+ pCur->idx++;
+ }else{
+ assert( pPage->u.hdr.rightChild==0 ); /* Must be a leaf page */
+ }
+ insertCell(pBt, pPage, pCur->idx, &newCell, szNew);
+ rc = balance(pCur->pBt, pPage, pCur);
+ /* sqliteBtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */
+ /* fflush(stdout); */
+ pCur->eSkip = SKIP_INVALID;
+ return rc;
+}
+
+/*
+** Delete the entry that the cursor is pointing to.
+**
+** The cursor is left pointing at either the next or the previous
+** entry. If the cursor is left pointing to the next entry, then
+** the pCur->eSkip flag is set to SKIP_NEXT which forces the next call to
+** sqliteBtreeNext() to be a no-op. That way, you can always call
+** sqliteBtreeNext() after a delete and the cursor will be left
+** pointing to the first entry after the deleted entry. Similarly,
+** pCur->eSkip is set to SKIP_PREV is the cursor is left pointing to
+** the entry prior to the deleted entry so that a subsequent call to
+** sqliteBtreePrevious() will always leave the cursor pointing at the
+** entry immediately before the one that was deleted.
+*/
+static int fileBtreeDelete(BtCursor *pCur){
+ MemPage *pPage = pCur->pPage;
+ Cell *pCell;
+ int rc;
+ Pgno pgnoChild;
+ Btree *pBt = pCur->pBt;
+
+ assert( pPage->isInit );
+ if( pCur->pPage==0 ){
+ return STQLITE_ABORT; /* A rollback destroyed this cursor */
+ }
+ if( !pBt->inTrans ){
+ /* Must start a transaction before doing a delete */
+ return pBt->readOnly ? STQLITE_READONLY : STQLITE_ERROR;
+ }
+ assert( !pBt->readOnly );
+ if( pCur->idx >= pPage->nCell ){
+ return STQLITE_ERROR; /* The cursor is not pointing to anything */
+ }
+ if( !pCur->wrFlag ){
+ return STQLITE_PERM; /* Did not open this cursor for writing */
+ }
+ if( checkReadLocks(pCur) ){
+ return STQLITE_LOCKED; /* The table pCur points to has a read lock */
+ }
+ rc = sqlitepager_write(pPage);
+ if( rc ) return rc;
+ pCell = pPage->apCell[pCur->idx];
+ pgnoChild = SWAB32(pBt, pCell->h.leftChild);
+ clearCell(pBt, pCell);
+ if( pgnoChild ){
+ /*
+ ** The entry we are about to delete is not a leaf so if we do not
+ ** do something we will leave a hole on an internal page.
+ ** We have to fill the hole by moving in a cell from a leaf. The
+ ** next Cell after the one to be deleted is guaranteed to exist and
+ ** to be a leaf so we can use it.
+ */
+ BtCursor leafCur;
+ Cell *pNext;
+ int szNext;
+ int notUsed;
+ getTempCursor(pCur, &leafCur);
+ rc = fileBtreeNext(&leafCur, &notUsed);
+ if( rc!=STQLITE_OK ){
+ if( rc!=STQLITE_NOMEM ) rc = STQLITE_CORRUPT;
+ return rc;
+ }
+ rc = sqlitepager_write(leafCur.pPage);
+ if( rc ) return rc;
+ dropCell(pBt, pPage, pCur->idx, cellSize(pBt, pCell));
+ pNext = leafCur.pPage->apCell[leafCur.idx];
+ szNext = cellSize(pBt, pNext);
+ pNext->h.leftChild = SWAB32(pBt, pgnoChild);
+ insertCell(pBt, pPage, pCur->idx, pNext, szNext);
+ rc = balance(pBt, pPage, pCur);
+ if( rc ) return rc;
+ pCur->eSkip = SKIP_NEXT;
+ dropCell(pBt, leafCur.pPage, leafCur.idx, szNext);
+ rc = balance(pBt, leafCur.pPage, pCur);
+ releaseTempCursor(&leafCur);
+ }else{
+ dropCell(pBt, pPage, pCur->idx, cellSize(pBt, pCell));
+ if( pCur->idx>=pPage->nCell ){
+ pCur->idx = pPage->nCell-1;
+ if( pCur->idx<0 ){
+ pCur->idx = 0;
+ pCur->eSkip = SKIP_NEXT;
+ }else{
+ pCur->eSkip = SKIP_PREV;
+ }
+ }else{
+ pCur->eSkip = SKIP_NEXT;
+ }
+ rc = balance(pBt, pPage, pCur);
+ }
+ return rc;
+}
+
+/*
+** Create a new BTree table. Write into *piTable the page
+** number for the root page of the new table.
+**
+** In the current implementation, BTree tables and BTree indices are the
+** the same. In the future, we may change this so that BTree tables
+** are restricted to having a 4-byte integer key and arbitrary data and
+** BTree indices are restricted to having an arbitrary key and no data.
+** But for now, this routine also serves to create indices.
+*/
+static int fileBtreeCreateTable(Btree *pBt, int *piTable){
+ MemPage *pRoot;
+ Pgno pgnoRoot;
+ int rc;
+ if( !pBt->inTrans ){
+ /* Must start a transaction first */
+ return pBt->readOnly ? STQLITE_READONLY : STQLITE_ERROR;
+ }
+ if( pBt->readOnly ){
+ return STQLITE_READONLY;
+ }
+ rc = allocatePage(pBt, &pRoot, &pgnoRoot, 0);
+ if( rc ) return rc;
+ assert( sqlitepager_iswriteable(pRoot) );
+ zeroPage(pBt, pRoot);
+ sqlitepager_unref(pRoot);
+ *piTable = (int)pgnoRoot;
+ return STQLITE_OK;
+}
+
+/*
+** Erase the given database page and all its tqchildren. Return
+** the page to the freelist.
+*/
+static int clearDatabasePage(Btree *pBt, Pgno pgno, int freePageFlag){
+ MemPage *pPage;
+ int rc;
+ Cell *pCell;
+ int idx;
+
+ rc = sqlitepager_get(pBt->pPager, pgno, (void**)&pPage);
+ if( rc ) return rc;
+ rc = sqlitepager_write(pPage);
+ if( rc ) return rc;
+ rc = initPage(pBt, pPage, pgno, 0);
+ if( rc ) return rc;
+ idx = SWAB16(pBt, pPage->u.hdr.firstCell);
+ while( idx>0 ){
+ pCell = (Cell*)&pPage->u.aDisk[idx];
+ idx = SWAB16(pBt, pCell->h.iNext);
+ if( pCell->h.leftChild ){
+ rc = clearDatabasePage(pBt, SWAB32(pBt, pCell->h.leftChild), 1);
+ if( rc ) return rc;
+ }
+ rc = clearCell(pBt, pCell);
+ if( rc ) return rc;
+ }
+ if( pPage->u.hdr.rightChild ){
+ rc = clearDatabasePage(pBt, SWAB32(pBt, pPage->u.hdr.rightChild), 1);
+ if( rc ) return rc;
+ }
+ if( freePageFlag ){
+ rc = freePage(pBt, pPage, pgno);
+ }else{
+ zeroPage(pBt, pPage);
+ }
+ sqlitepager_unref(pPage);
+ return rc;
+}
+
+/*
+** Delete all information from a single table in the database.
+*/
+static int fileBtreeClearTable(Btree *pBt, int iTable){
+ int rc;
+ BtCursor *pCur;
+ if( !pBt->inTrans ){
+ return pBt->readOnly ? STQLITE_READONLY : STQLITE_ERROR;
+ }
+ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
+ if( pCur->pgnoRoot==(Pgno)iTable ){
+ if( pCur->wrFlag==0 ) return STQLITE_LOCKED;
+ moveToRoot(pCur);
+ }
+ }
+ rc = clearDatabasePage(pBt, (Pgno)iTable, 0);
+ if( rc ){
+ fileBtreeRollback(pBt);
+ }
+ return rc;
+}
+
+/*
+** Erase all information in a table and add the root of the table to
+** the freelist. Except, the root of the principle table (the one on
+** page 2) is never added to the freelist.
+*/
+static int fileBtreeDropTable(Btree *pBt, int iTable){
+ int rc;
+ MemPage *pPage;
+ BtCursor *pCur;
+ if( !pBt->inTrans ){
+ return pBt->readOnly ? STQLITE_READONLY : STQLITE_ERROR;
+ }
+ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){
+ if( pCur->pgnoRoot==(Pgno)iTable ){
+ return STQLITE_LOCKED; /* Cannot drop a table that has a cursor */
+ }
+ }
+ rc = sqlitepager_get(pBt->pPager, (Pgno)iTable, (void**)&pPage);
+ if( rc ) return rc;
+ rc = fileBtreeClearTable(pBt, iTable);
+ if( rc ) return rc;
+ if( iTable>2 ){
+ rc = freePage(pBt, pPage, iTable);
+ }else{
+ zeroPage(pBt, pPage);
+ }
+ sqlitepager_unref(pPage);
+ return rc;
+}
+
+#if 0 /* UNTESTED */
+/*
+** Copy all cell data from one database file into another.
+** pages back the freelist.
+*/
+static int copyCell(Btree *pBtFrom, BTree *pBtTo, Cell *pCell){
+ Pager *pFromPager = pBtFrom->pPager;
+ OverflowPage *pOvfl;
+ Pgno ovfl, nextOvfl;
+ Pgno *pPrev;
+ int rc = STQLITE_OK;
+ MemPage *pNew, *pPrevPg;
+ Pgno new;
+
+ if( NKEY(pBtTo, pCell->h) + NDATA(pBtTo, pCell->h) <= MX_LOCAL_PAYLOAD ){
+ return STQLITE_OK;
+ }
+ pPrev = &pCell->ovfl;
+ pPrevPg = 0;
+ ovfl = SWAB32(pBtTo, pCell->ovfl);
+ while( ovfl && rc==STQLITE_OK ){
+ rc = sqlitepager_get(pFromPager, ovfl, (void**)&pOvfl);
+ if( rc ) return rc;
+ nextOvfl = SWAB32(pBtFrom, pOvfl->iNext);
+ rc = allocatePage(pBtTo, &pNew, &new, 0);
+ if( rc==STQLITE_OK ){
+ rc = sqlitepager_write(pNew);
+ if( rc==STQLITE_OK ){
+ memcpy(pNew, pOvfl, STQLITE_USABLE_SIZE);
+ *pPrev = SWAB32(pBtTo, new);
+ if( pPrevPg ){
+ sqlitepager_unref(pPrevPg);
+ }
+ pPrev = &pOvfl->iNext;
+ pPrevPg = pNew;
+ }
+ }
+ sqlitepager_unref(pOvfl);
+ ovfl = nextOvfl;
+ }
+ if( pPrevPg ){
+ sqlitepager_unref(pPrevPg);
+ }
+ return rc;
+}
+#endif
+
+
+#if 0 /* UNTESTED */
+/*
+** Copy a page of data from one database over to another.
+*/
+static int copyDatabasePage(
+ Btree *pBtFrom,
+ Pgno pgnoFrom,
+ Btree *pBtTo,
+ Pgno *pTo
+){
+ MemPage *pPageFrom, *pPage;
+ Pgno to;
+ int rc;
+ Cell *pCell;
+ int idx;
+
+ rc = sqlitepager_get(pBtFrom->pPager, pgno, (void**)&pPageFrom);
+ if( rc ) return rc;
+ rc = allocatePage(pBt, &pPage, pTo, 0);
+ if( rc==STQLITE_OK ){
+ rc = sqlitepager_write(pPage);
+ }
+ if( rc==STQLITE_OK ){
+ memcpy(pPage, pPageFrom, STQLITE_USABLE_SIZE);
+ idx = SWAB16(pBt, pPage->u.hdr.firstCell);
+ while( idx>0 ){
+ pCell = (Cell*)&pPage->u.aDisk[idx];
+ idx = SWAB16(pBt, pCell->h.iNext);
+ if( pCell->h.leftChild ){
+ Pgno newChld;
+ rc = copyDatabasePage(pBtFrom, SWAB32(pBtFrom, pCell->h.leftChild),
+ pBtTo, &newChld);
+ if( rc ) return rc;
+ pCell->h.leftChild = SWAB32(pBtFrom, newChld);
+ }
+ rc = copyCell(pBtFrom, pBtTo, pCell);
+ if( rc ) return rc;
+ }
+ if( pPage->u.hdr.rightChild ){
+ Pgno newChld;
+ rc = copyDatabasePage(pBtFrom, SWAB32(pBtFrom, pPage->u.hdr.rightChild),
+ pBtTo, &newChld);
+ if( rc ) return rc;
+ pPage->u.hdr.rightChild = SWAB32(pBtTo, newChild);
+ }
+ }
+ sqlitepager_unref(pPage);
+ return rc;
+}
+#endif
+
+/*
+** Read the meta-information out of a database file.
+*/
+static int fileBtreeGetMeta(Btree *pBt, int *aMeta){
+ PageOne *pP1;
+ int rc;
+ int i;
+
+ rc = sqlitepager_get(pBt->pPager, 1, (void**)&pP1);
+ if( rc ) return rc;
+ aMeta[0] = SWAB32(pBt, pP1->nFree);
+ for(i=0; i<sizeof(pP1->aMeta)/sizeof(pP1->aMeta[0]); i++){
+ aMeta[i+1] = SWAB32(pBt, pP1->aMeta[i]);
+ }
+ sqlitepager_unref(pP1);
+ return STQLITE_OK;
+}
+
+/*
+** Write meta-information back into the database.
+*/
+static int fileBtreeUpdateMeta(Btree *pBt, int *aMeta){
+ PageOne *pP1;
+ int rc, i;
+ if( !pBt->inTrans ){
+ return pBt->readOnly ? STQLITE_READONLY : STQLITE_ERROR;
+ }
+ pP1 = pBt->page1;
+ rc = sqlitepager_write(pP1);
+ if( rc ) return rc;
+ for(i=0; i<sizeof(pP1->aMeta)/sizeof(pP1->aMeta[0]); i++){
+ pP1->aMeta[i] = SWAB32(pBt, aMeta[i+1]);
+ }
+ return STQLITE_OK;
+}
+
+/******************************************************************************
+** The complete implementation of the BTree subsystem is above this line.
+** All the code the follows is for testing and troubleshooting the BTree
+** subsystem. None of the code that follows is used during normal operation.
+******************************************************************************/
+
+/*
+** Print a disassembly of the given page on standard output. This routine
+** is used for debugging and testing only.
+*/
+#ifdef STQLITE_TEST
+static int fileBtreePageDump(Btree *pBt, int pgno, int recursive){
+ int rc;
+ MemPage *pPage;
+ int i, j;
+ int nFree;
+ u16 idx;
+ char range[20];
+ unsigned char payload[20];
+ rc = sqlitepager_get(pBt->pPager, (Pgno)pgno, (void**)&pPage);
+ if( rc ){
+ return rc;
+ }
+ if( recursive ) printf("PAGE %d:\n", pgno);
+ i = 0;
+ idx = SWAB16(pBt, pPage->u.hdr.firstCell);
+ while( idx>0 && idx<=STQLITE_USABLE_SIZE-MIN_CELL_SIZE ){
+ Cell *pCell = (Cell*)&pPage->u.aDisk[idx];
+ int sz = cellSize(pBt, pCell);
+ sprintf(range,"%d..%d", idx, idx+sz-1);
+ sz = NKEY(pBt, pCell->h) + NDATA(pBt, pCell->h);
+ if( sz>sizeof(payload)-1 ) sz = sizeof(payload)-1;
+ memcpy(payload, pCell->aPayload, sz);
+ for(j=0; j<sz; j++){
+ if( payload[j]<0x20 || payload[j]>0x7f ) payload[j] = '.';
+ }
+ payload[sz] = 0;
+ printf(
+ "cell %2d: i=%-10s chld=%-4d nk=%-4d nd=%-4d payload=%s\n",
+ i, range, (int)pCell->h.leftChild,
+ NKEY(pBt, pCell->h), NDATA(pBt, pCell->h),
+ payload
+ );
+ if( pPage->isInit && pPage->apCell[i]!=pCell ){
+ printf("**** apCell[%d] does not match on prior entry ****\n", i);
+ }
+ i++;
+ idx = SWAB16(pBt, pCell->h.iNext);
+ }
+ if( idx!=0 ){
+ printf("ERROR: next cell index out of range: %d\n", idx);
+ }
+ printf("right_child: %d\n", SWAB32(pBt, pPage->u.hdr.rightChild));
+ nFree = 0;
+ i = 0;
+ idx = SWAB16(pBt, pPage->u.hdr.firstFree);
+ while( idx>0 && idx<STQLITE_USABLE_SIZE ){
+ FreeBlk *p = (FreeBlk*)&pPage->u.aDisk[idx];
+ sprintf(range,"%d..%d", idx, idx+p->iSize-1);
+ nFree += SWAB16(pBt, p->iSize);
+ printf("freeblock %2d: i=%-10s size=%-4d total=%d\n",
+ i, range, SWAB16(pBt, p->iSize), nFree);
+ idx = SWAB16(pBt, p->iNext);
+ i++;
+ }
+ if( idx!=0 ){
+ printf("ERROR: next freeblock index out of range: %d\n", idx);
+ }
+ if( recursive && pPage->u.hdr.rightChild!=0 ){
+ idx = SWAB16(pBt, pPage->u.hdr.firstCell);
+ while( idx>0 && idx<STQLITE_USABLE_SIZE-MIN_CELL_SIZE ){
+ Cell *pCell = (Cell*)&pPage->u.aDisk[idx];
+ fileBtreePageDump(pBt, SWAB32(pBt, pCell->h.leftChild), 1);
+ idx = SWAB16(pBt, pCell->h.iNext);
+ }
+ fileBtreePageDump(pBt, SWAB32(pBt, pPage->u.hdr.rightChild), 1);
+ }
+ sqlitepager_unref(pPage);
+ return STQLITE_OK;
+}
+#endif
+
+#ifdef STQLITE_TEST
+/*
+** Fill aResult[] with information about the entry and page that the
+** cursor is pointing to.
+**
+** aResult[0] = The page number
+** aResult[1] = The entry number
+** aResult[2] = Total number of entries on this page
+** aResult[3] = Size of this entry
+** aResult[4] = Number of free bytes on this page
+** aResult[5] = Number of free blocks on the page
+** aResult[6] = Page number of the left child of this entry
+** aResult[7] = Page number of the right child for the whole page
+**
+** This routine is used for testing and debugging only.
+*/
+static int fileBtreeCursorDump(BtCursor *pCur, int *aResult){
+ int cnt, idx;
+ MemPage *pPage = pCur->pPage;
+ Btree *pBt = pCur->pBt;
+ aResult[0] = sqlitepager_pagenumber(pPage);
+ aResult[1] = pCur->idx;
+ aResult[2] = pPage->nCell;
+ if( pCur->idx>=0 && pCur->idx<pPage->nCell ){
+ aResult[3] = cellSize(pBt, pPage->apCell[pCur->idx]);
+ aResult[6] = SWAB32(pBt, pPage->apCell[pCur->idx]->h.leftChild);
+ }else{
+ aResult[3] = 0;
+ aResult[6] = 0;
+ }
+ aResult[4] = pPage->nFree;
+ cnt = 0;
+ idx = SWAB16(pBt, pPage->u.hdr.firstFree);
+ while( idx>0 && idx<STQLITE_USABLE_SIZE ){
+ cnt++;
+ idx = SWAB16(pBt, ((FreeBlk*)&pPage->u.aDisk[idx])->iNext);
+ }
+ aResult[5] = cnt;
+ aResult[7] = SWAB32(pBt, pPage->u.hdr.rightChild);
+ return STQLITE_OK;
+}
+#endif
+
+/*
+** Return the pager associated with a BTree. This routine is used for
+** testing and debugging only.
+*/
+static Pager *fileBtreePager(Btree *pBt){
+ return pBt->pPager;
+}
+
+/*
+** This structure is passed around through all the sanity checking routines
+** in order to keep track of some global state information.
+*/
+typedef struct IntegrityCk IntegrityCk;
+struct IntegrityCk {
+ Btree *pBt; /* The tree being checked out */
+ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */
+ int nPage; /* Number of pages in the database */
+ int *anRef; /* Number of times each page is referenced */
+ char *zErrMsg; /* An error message. NULL of no errors seen. */
+};
+
+/*
+** Append a message to the error message string.
+*/
+static void checkAppendMsg(IntegrityCk *pCheck, char *zMsg1, char *zMsg2){
+ if( pCheck->zErrMsg ){
+ char *zOld = pCheck->zErrMsg;
+ pCheck->zErrMsg = 0;
+ sqliteSetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0);
+ sqliteFree(zOld);
+ }else{
+ sqliteSetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0);
+ }
+}
+
+/*
+** Add 1 to the reference count for page iPage. If this is the second
+** reference to the page, add an error message to pCheck->zErrMsg.
+** Return 1 if there are 2 ore more references to the page and 0 if
+** if this is the first reference to the page.
+**
+** Also check that the page number is in bounds.
+*/
+static int checkRef(IntegrityCk *pCheck, int iPage, char *zContext){
+ if( iPage==0 ) return 1;
+ if( iPage>pCheck->nPage || iPage<0 ){
+ char zBuf[100];
+ sprintf(zBuf, "invalid page number %d", iPage);
+ checkAppendMsg(pCheck, zContext, zBuf);
+ return 1;
+ }
+ if( pCheck->anRef[iPage]==1 ){
+ char zBuf[100];
+ sprintf(zBuf, "2nd reference to page %d", iPage);
+ checkAppendMsg(pCheck, zContext, zBuf);
+ return 1;
+ }
+ return (pCheck->anRef[iPage]++)>1;
+}
+
+/*
+** Check the integrity of the freelist or of an overflow page list.
+** Verify that the number of pages on the list is N.
+*/
+static void checkList(
+ IntegrityCk *pCheck, /* Integrity checking context */
+ int isFreeList, /* True for a freelist. False for overflow page list */
+ int iPage, /* Page number for first page in the list */
+ int N, /* Expected number of pages in the list */
+ char *zContext /* Context for error messages */
+){
+ int i;
+ char zMsg[100];
+ while( N-- > 0 ){
+ OverflowPage *pOvfl;
+ if( iPage<1 ){
+ sprintf(zMsg, "%d pages missing from overflow list", N+1);
+ checkAppendMsg(pCheck, zContext, zMsg);
+ break;
+ }
+ if( checkRef(pCheck, iPage, zContext) ) break;
+ if( sqlitepager_get(pCheck->pPager, (Pgno)iPage, (void**)&pOvfl) ){
+ sprintf(zMsg, "failed to get page %d", iPage);
+ checkAppendMsg(pCheck, zContext, zMsg);
+ break;
+ }
+ if( isFreeList ){
+ FreelistInfo *pInfo = (FreelistInfo*)pOvfl->aPayload;
+ int n = SWAB32(pCheck->pBt, pInfo->nFree);
+ for(i=0; i<n; i++){
+ checkRef(pCheck, SWAB32(pCheck->pBt, pInfo->aFree[i]), zContext);
+ }
+ N -= n;
+ }
+ iPage = SWAB32(pCheck->pBt, pOvfl->iNext);
+ sqlitepager_unref(pOvfl);
+ }
+}
+
+/*
+** Return negative if zKey1<zKey2.
+** Return zero if zKey1==zKey2.
+** Return positive if zKey1>zKey2.
+*/
+static int keyCompare(
+ const char *zKey1, int nKey1,
+ const char *zKey2, int nKey2
+){
+ int min = nKey1>nKey2 ? nKey2 : nKey1;
+ int c = memcmp(zKey1, zKey2, min);
+ if( c==0 ){
+ c = nKey1 - nKey2;
+ }
+ return c;
+}
+
+/*
+** Do various sanity checks on a single page of a tree. Return
+** the tree depth. Root pages return 0. Parents of root pages
+** return 1, and so forth.
+**
+** These checks are done:
+**
+** 1. Make sure that cells and freeblocks do not overlap
+** but combine to completely cover the page.
+** 2. Make sure cell keys are in order.
+** 3. Make sure no key is less than or equal to zLowerBound.
+** 4. Make sure no key is greater than or equal to zUpperBound.
+** 5. Check the integrity of overflow pages.
+** 6. Recursively call checkTreePage on all tqchildren.
+** 7. Verify that the depth of all tqchildren is the same.
+** 8. Make sure this page is at least 33% full or else it is
+** the root of the tree.
+*/
+static int checkTreePage(
+ IntegrityCk *pCheck, /* Context for the sanity check */
+ int iPage, /* Page number of the page to check */
+ MemPage *pParent, /* Parent page */
+ char *zParentContext, /* Parent context */
+ char *zLowerBound, /* All keys should be greater than this, if not NULL */
+ int nLower, /* Number of characters in zLowerBound */
+ char *zUpperBound, /* All keys should be less than this, if not NULL */
+ int nUpper /* Number of characters in zUpperBound */
+){
+ MemPage *pPage;
+ int i, rc, depth, d2, pgno;
+ char *zKey1, *zKey2;
+ int nKey1, nKey2;
+ BtCursor cur;
+ Btree *pBt;
+ char zMsg[100];
+ char zContext[100];
+ char hit[STQLITE_USABLE_SIZE];
+
+ /* Check that the page exists
+ */
+ cur.pBt = pBt = pCheck->pBt;
+ if( iPage==0 ) return 0;
+ if( checkRef(pCheck, iPage, zParentContext) ) return 0;
+ sprintf(zContext, "On tree page %d: ", iPage);
+ if( (rc = sqlitepager_get(pCheck->pPager, (Pgno)iPage, (void**)&pPage))!=0 ){
+ sprintf(zMsg, "unable to get the page. error code=%d", rc);
+ checkAppendMsg(pCheck, zContext, zMsg);
+ return 0;
+ }
+ if( (rc = initPage(pBt, pPage, (Pgno)iPage, pParent))!=0 ){
+ sprintf(zMsg, "initPage() returns error code %d", rc);
+ checkAppendMsg(pCheck, zContext, zMsg);
+ sqlitepager_unref(pPage);
+ return 0;
+ }
+
+ /* Check out all the cells.
+ */
+ depth = 0;
+ if( zLowerBound ){
+ zKey1 = sqliteMalloc( nLower+1 );
+ memcpy(zKey1, zLowerBound, nLower);
+ zKey1[nLower] = 0;
+ }else{
+ zKey1 = 0;
+ }
+ nKey1 = nLower;
+ cur.pPage = pPage;
+ for(i=0; i<pPage->nCell; i++){
+ Cell *pCell = pPage->apCell[i];
+ int sz;
+
+ /* Check payload overflow pages
+ */
+ nKey2 = NKEY(pBt, pCell->h);
+ sz = nKey2 + NDATA(pBt, pCell->h);
+ sprintf(zContext, "On page %d cell %d: ", iPage, i);
+ if( sz>MX_LOCAL_PAYLOAD ){
+ int nPage = (sz - MX_LOCAL_PAYLOAD + OVERFLOW_SIZE - 1)/OVERFLOW_SIZE;
+ checkList(pCheck, 0, SWAB32(pBt, pCell->ovfl), nPage, zContext);
+ }
+
+ /* Check that keys are in the right order
+ */
+ cur.idx = i;
+ zKey2 = sqliteMallocRaw( nKey2+1 );
+ getPayload(&cur, 0, nKey2, zKey2);
+ if( zKey1 && keyCompare(zKey1, nKey1, zKey2, nKey2)>=0 ){
+ checkAppendMsg(pCheck, zContext, "Key is out of order");
+ }
+
+ /* Check sanity of left child page.
+ */
+ pgno = SWAB32(pBt, pCell->h.leftChild);
+ d2 = checkTreePage(pCheck, pgno, pPage, zContext, zKey1,nKey1,zKey2,nKey2);
+ if( i>0 && d2!=depth ){
+ checkAppendMsg(pCheck, zContext, "Child page depth differs");
+ }
+ depth = d2;
+ sqliteFree(zKey1);
+ zKey1 = zKey2;
+ nKey1 = nKey2;
+ }
+ pgno = SWAB32(pBt, pPage->u.hdr.rightChild);
+ sprintf(zContext, "On page %d at right child: ", iPage);
+ checkTreePage(pCheck, pgno, pPage, zContext, zKey1,nKey1,zUpperBound,nUpper);
+ sqliteFree(zKey1);
+
+ /* Check for complete coverage of the page
+ */
+ memset(hit, 0, sizeof(hit));
+ memset(hit, 1, sizeof(PageHdr));
+ for(i=SWAB16(pBt, pPage->u.hdr.firstCell); i>0 && i<STQLITE_USABLE_SIZE; ){
+ Cell *pCell = (Cell*)&pPage->u.aDisk[i];
+ int j;
+ for(j=i+cellSize(pBt, pCell)-1; j>=i; j--) hit[j]++;
+ i = SWAB16(pBt, pCell->h.iNext);
+ }
+ for(i=SWAB16(pBt,pPage->u.hdr.firstFree); i>0 && i<STQLITE_USABLE_SIZE; ){
+ FreeBlk *pFBlk = (FreeBlk*)&pPage->u.aDisk[i];
+ int j;
+ for(j=i+SWAB16(pBt,pFBlk->iSize)-1; j>=i; j--) hit[j]++;
+ i = SWAB16(pBt,pFBlk->iNext);
+ }
+ for(i=0; i<STQLITE_USABLE_SIZE; i++){
+ if( hit[i]==0 ){
+ sprintf(zMsg, "Unused space at byte %d of page %d", i, iPage);
+ checkAppendMsg(pCheck, zMsg, 0);
+ break;
+ }else if( hit[i]>1 ){
+ sprintf(zMsg, "Multiple uses for byte %d of page %d", i, iPage);
+ checkAppendMsg(pCheck, zMsg, 0);
+ break;
+ }
+ }
+
+ /* Check that free space is kept to a minimum
+ */
+#if 0
+ if( pParent && pParent->nCell>2 && pPage->nFree>3*STQLITE_USABLE_SIZE/4 ){
+ sprintf(zMsg, "free space (%d) greater than max (%d)", pPage->nFree,
+ STQLITE_USABLE_SIZE/3);
+ checkAppendMsg(pCheck, zContext, zMsg);
+ }
+#endif
+
+ sqlitepager_unref(pPage);
+ return depth;
+}
+
+/*
+** This routine does a complete check of the given BTree file. aRoot[] is
+** an array of pages numbers were each page number is the root page of
+** a table. nRoot is the number of entries in aRoot.
+**
+** If everything checks out, this routine returns NULL. If something is
+** amiss, an error message is written into memory obtained from malloc()
+** and a pointer to that error message is returned. The calling function
+** is responsible for freeing the error message when it is done.
+*/
+char *fileBtreeIntegrityCheck(Btree *pBt, int *aRoot, int nRoot){
+ int i;
+ int nRef;
+ IntegrityCk sCheck;
+
+ nRef = *sqlitepager_stats(pBt->pPager);
+ if( lockBtree(pBt)!=STQLITE_OK ){
+ return sqliteStrDup("Unable to acquire a read lock on the database");
+ }
+ sCheck.pBt = pBt;
+ sCheck.pPager = pBt->pPager;
+ sCheck.nPage = sqlitepager_pagecount(sCheck.pPager);
+ if( sCheck.nPage==0 ){
+ unlockBtreeIfUnused(pBt);
+ return 0;
+ }
+ sCheck.anRef = sqliteMallocRaw( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
+ sCheck.anRef[1] = 1;
+ for(i=2; i<=sCheck.nPage; i++){ sCheck.anRef[i] = 0; }
+ sCheck.zErrMsg = 0;
+
+ /* Check the integrity of the freelist
+ */
+ checkList(&sCheck, 1, SWAB32(pBt, pBt->page1->freeList),
+ SWAB32(pBt, pBt->page1->nFree), "Main freelist: ");
+
+ /* Check all the tables.
+ */
+ for(i=0; i<nRoot; i++){
+ if( aRoot[i]==0 ) continue;
+ checkTreePage(&sCheck, aRoot[i], 0, "List of tree roots: ", 0,0,0,0);
+ }
+
+ /* Make sure every page in the file is referenced
+ */
+ for(i=1; i<=sCheck.nPage; i++){
+ if( sCheck.anRef[i]==0 ){
+ char zBuf[100];
+ sprintf(zBuf, "Page %d is never used", i);
+ checkAppendMsg(&sCheck, zBuf, 0);
+ }
+ }
+
+ /* Make sure this analysis did not leave any unref() pages
+ */
+ unlockBtreeIfUnused(pBt);
+ if( nRef != *sqlitepager_stats(pBt->pPager) ){
+ char zBuf[100];
+ sprintf(zBuf,
+ "Outstanding page count goes from %d to %d during this analysis",
+ nRef, *sqlitepager_stats(pBt->pPager)
+ );
+ checkAppendMsg(&sCheck, zBuf, 0);
+ }
+
+ /* Clean up and report errors.
+ */
+ sqliteFree(sCheck.anRef);
+ return sCheck.zErrMsg;
+}
+
+/*
+** Return the full pathname of the underlying database file.
+*/
+static const char *fileBtreeGetFilename(Btree *pBt){
+ assert( pBt->pPager!=0 );
+ return sqlitepager_filename(pBt->pPager);
+}
+
+/*
+** Copy the complete content of pBtFrom into pBtTo. A transaction
+** must be active for both files.
+**
+** The size of file pBtFrom may be reduced by this operation.
+** If anything goes wrong, the transaction on pBtFrom is rolled back.
+*/
+static int fileBtreeCopyFile(Btree *pBtTo, Btree *pBtFrom){
+ int rc = STQLITE_OK;
+ Pgno i, nPage, nToPage;
+
+ if( !pBtTo->inTrans || !pBtFrom->inTrans ) return STQLITE_ERROR;
+ if( pBtTo->needSwab!=pBtFrom->needSwab ) return STQLITE_ERROR;
+ if( pBtTo->pCursor ) return STQLITE_BUSY;
+ memcpy(pBtTo->page1, pBtFrom->page1, STQLITE_USABLE_SIZE);
+ rc = sqlitepager_overwrite(pBtTo->pPager, 1, pBtFrom->page1);
+ nToPage = sqlitepager_pagecount(pBtTo->pPager);
+ nPage = sqlitepager_pagecount(pBtFrom->pPager);
+ for(i=2; rc==STQLITE_OK && i<=nPage; i++){
+ void *pPage;
+ rc = sqlitepager_get(pBtFrom->pPager, i, &pPage);
+ if( rc ) break;
+ rc = sqlitepager_overwrite(pBtTo->pPager, i, pPage);
+ if( rc ) break;
+ sqlitepager_unref(pPage);
+ }
+ for(i=nPage+1; rc==STQLITE_OK && i<=nToPage; i++){
+ void *pPage;
+ rc = sqlitepager_get(pBtTo->pPager, i, &pPage);
+ if( rc ) break;
+ rc = sqlitepager_write(pPage);
+ sqlitepager_unref(pPage);
+ sqlitepager_dont_write(pBtTo->pPager, i);
+ }
+ if( !rc && nPage<nToPage ){
+ rc = sqlitepager_truncate(pBtTo->pPager, nPage);
+ }
+ if( rc ){
+ fileBtreeRollback(pBtTo);
+ }
+ return rc;
+}
+
+/*
+** The following tables contain pointers to all of the interface
+** routines for this implementation of the B*Tree backend. To
+** substitute a different implemention of the backend, one has merely
+** to provide pointers to alternative functions in similar tables.
+*/
+static BtOps sqliteBtreeOps = {
+ fileBtreeClose,
+ fileBtreeSetCacheSize,
+ fileBtreeSetSafetyLevel,
+ fileBtreeBeginTrans,
+ fileBtreeCommit,
+ fileBtreeRollback,
+ fileBtreeBeginCkpt,
+ fileBtreeCommitCkpt,
+ fileBtreeRollbackCkpt,
+ fileBtreeCreateTable,
+ fileBtreeCreateTable, /* Really sqliteBtreeCreateIndex() */
+ fileBtreeDropTable,
+ fileBtreeClearTable,
+ fileBtreeCursor,
+ fileBtreeGetMeta,
+ fileBtreeUpdateMeta,
+ fileBtreeIntegrityCheck,
+ fileBtreeGetFilename,
+ fileBtreeCopyFile,
+ fileBtreePager,
+#ifdef STQLITE_TEST
+ fileBtreePageDump,
+#endif
+};
+static BtCursorOps sqliteBtreeCursorOps = {
+ fileBtreeMoveto,
+ fileBtreeDelete,
+ fileBtreeInsert,
+ fileBtreeFirst,
+ fileBtreeLast,
+ fileBtreeNext,
+ fileBtreePrevious,
+ fileBtreeKeySize,
+ fileBtreeKey,
+ fileBtreeKeyCompare,
+ fileBtreeDataSize,
+ fileBtreeData,
+ fileBtreeCloseCursor,
+#ifdef STQLITE_TEST
+ fileBtreeCursorDump,
+#endif
+};
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/btree.h b/tqtinterface/qt4/src/3rdparty/sqlite/btree.h
new file mode 100644
index 0000000..f9afabc
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/btree.h
@@ -0,0 +1,156 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This header file defines the interface that the sqlite B-Tree file
+** subsystem. See comments in the source code for a detailed description
+** of what each interface routine does.
+**
+** @(#) $Id: btree.h,v 1.36 2004/02/10 02:57:59 drh Exp $
+*/
+#ifndef _BTREE_H_
+#define _BTREE_H_
+
+/*
+** Forward declarations of structure
+*/
+typedef struct Btree Btree;
+typedef struct BtCursor BtCursor;
+typedef struct BtOps BtOps;
+typedef struct BtCursorOps BtCursorOps;
+
+
+/*
+** An instance of the following structure tqcontains pointers to all
+** methods against an open BTree. Alternative BTree implementations
+** (examples: file based versus in-memory) can be created by substituting
+** different methods. Users of the BTree cannot tell the difference.
+**
+** In C++ we could do this by defining a virtual base class and then
+** creating subclasses for each different implementation. But this is
+** C not C++ so we have to be a little more explicit.
+*/
+struct BtOps {
+ int (*Close)(Btree*);
+ int (*SetCacheSize)(Btree*, int);
+ int (*SetSafetyLevel)(Btree*, int);
+ int (*BeginTrans)(Btree*);
+ int (*Commit)(Btree*);
+ int (*Rollback)(Btree*);
+ int (*BeginCkpt)(Btree*);
+ int (*CommitCkpt)(Btree*);
+ int (*RollbackCkpt)(Btree*);
+ int (*CreateTable)(Btree*, int*);
+ int (*CreateIndex)(Btree*, int*);
+ int (*DropTable)(Btree*, int);
+ int (*ClearTable)(Btree*, int);
+ int (*Cursor)(Btree*, int iTable, int wrFlag, BtCursor **ppCur);
+ int (*GetMeta)(Btree*, int*);
+ int (*UpdateMeta)(Btree*, int*);
+ char *(*IntegrityCheck)(Btree*, int*, int);
+ const char *(*GetFilename)(Btree*);
+ int (*Copyfile)(Btree*,Btree*);
+ struct Pager *(*Pager)(Btree*);
+#ifdef STQLITE_TEST
+ int (*PageDump)(Btree*, int, int);
+#endif
+};
+
+/*
+** An instance of this structure defines all of the methods that can
+** be executed against a cursor.
+*/
+struct BtCursorOps {
+ int (*Moveto)(BtCursor*, const void *pKey, int nKey, int *pRes);
+ int (*Delete)(BtCursor*);
+ int (*Insert)(BtCursor*, const void *pKey, int nKey,
+ const void *pData, int nData);
+ int (*First)(BtCursor*, int *pRes);
+ int (*Last)(BtCursor*, int *pRes);
+ int (*Next)(BtCursor*, int *pRes);
+ int (*Previous)(BtCursor*, int *pRes);
+ int (*KeySize)(BtCursor*, int *pSize);
+ int (*Key)(BtCursor*, int offset, int amt, char *zBuf);
+ int (*KeyCompare)(BtCursor*, const void *pKey, int nKey,
+ int nIgnore, int *pRes);
+ int (*DataSize)(BtCursor*, int *pSize);
+ int (*Data)(BtCursor*, int offset, int amt, char *zBuf);
+ int (*CloseCursor)(BtCursor*);
+#ifdef STQLITE_TEST
+ int (*CursorDump)(BtCursor*, int*);
+#endif
+};
+
+/*
+** The number of 4-byte "meta" values contained on the first page of each
+** database file.
+*/
+#define STQLITE_N_BTREE_META 10
+
+int sqliteBtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree);
+int sqliteRbtreeOpen(const char *zFilename, int mode, int nPg, Btree **ppBtree);
+
+#define btOps(pBt) (*((BtOps **)(pBt)))
+#define btCOps(pCur) (*((BtCursorOps **)(pCur)))
+
+#define sqliteBtreeClose(pBt) (btOps(pBt)->Close(pBt))
+#define sqliteBtreeSetCacheSize(pBt, sz) (btOps(pBt)->SetCacheSize(pBt, sz))
+#define sqliteBtreeSetSafetyLevel(pBt, sl) (btOps(pBt)->SetSafetyLevel(pBt, sl))
+#define sqliteBtreeBeginTrans(pBt) (btOps(pBt)->BeginTrans(pBt))
+#define sqliteBtreeCommit(pBt) (btOps(pBt)->Commit(pBt))
+#define sqliteBtreeRollback(pBt) (btOps(pBt)->Rollback(pBt))
+#define sqliteBtreeBeginCkpt(pBt) (btOps(pBt)->BeginCkpt(pBt))
+#define sqliteBtreeCommitCkpt(pBt) (btOps(pBt)->CommitCkpt(pBt))
+#define sqliteBtreeRollbackCkpt(pBt) (btOps(pBt)->RollbackCkpt(pBt))
+#define sqliteBtreeCreateTable(pBt,piTable)\
+ (btOps(pBt)->CreateTable(pBt,piTable))
+#define sqliteBtreeCreateIndex(pBt, piIndex)\
+ (btOps(pBt)->CreateIndex(pBt, piIndex))
+#define sqliteBtreeDropTable(pBt, iTable) (btOps(pBt)->DropTable(pBt, iTable))
+#define sqliteBtreeClearTable(pBt, iTable)\
+ (btOps(pBt)->ClearTable(pBt, iTable))
+#define sqliteBtreeCursor(pBt, iTable, wrFlag, ppCur)\
+ (btOps(pBt)->Cursor(pBt, iTable, wrFlag, ppCur))
+#define sqliteBtreeMoveto(pCur, pKey, nKey, pRes)\
+ (btCOps(pCur)->Moveto(pCur, pKey, nKey, pRes))
+#define sqliteBtreeDelete(pCur) (btCOps(pCur)->Delete(pCur))
+#define sqliteBtreeInsert(pCur, pKey, nKey, pData, nData) \
+ (btCOps(pCur)->Insert(pCur, pKey, nKey, pData, nData))
+#define sqliteBtreeFirst(pCur, pRes) (btCOps(pCur)->First(pCur, pRes))
+#define sqliteBtreeLast(pCur, pRes) (btCOps(pCur)->Last(pCur, pRes))
+#define sqliteBtreeNext(pCur, pRes) (btCOps(pCur)->Next(pCur, pRes))
+#define sqliteBtreePrevious(pCur, pRes) (btCOps(pCur)->Previous(pCur, pRes))
+#define sqliteBtreeKeySize(pCur, pSize) (btCOps(pCur)->KeySize(pCur, pSize) )
+#define sqliteBtreeKey(pCur, offset, amt, zBuf)\
+ (btCOps(pCur)->Key(pCur, offset, amt, zBuf))
+#define sqliteBtreeKeyCompare(pCur, pKey, nKey, nIgnore, pRes)\
+ (btCOps(pCur)->KeyCompare(pCur, pKey, nKey, nIgnore, pRes))
+#define sqliteBtreeDataSize(pCur, pSize) (btCOps(pCur)->DataSize(pCur, pSize))
+#define sqliteBtreeData(pCur, offset, amt, zBuf)\
+ (btCOps(pCur)->Data(pCur, offset, amt, zBuf))
+#define sqliteBtreeCloseCursor(pCur) (btCOps(pCur)->CloseCursor(pCur))
+#define sqliteBtreeGetMeta(pBt, aMeta) (btOps(pBt)->GetMeta(pBt, aMeta))
+#define sqliteBtreeUpdateMeta(pBt, aMeta) (btOps(pBt)->UpdateMeta(pBt, aMeta))
+#define sqliteBtreeIntegrityCheck(pBt, aRoot, nRoot)\
+ (btOps(pBt)->IntegrityCheck(pBt, aRoot, nRoot))
+#define sqliteBtreeGetFilename(pBt) (btOps(pBt)->GetFilename(pBt))
+#define sqliteBtreeCopyFile(pBt1, pBt2) (btOps(pBt1)->Copyfile(pBt1, pBt2))
+#define sqliteBtreePager(pBt) (btOps(pBt)->Pager(pBt))
+
+#ifdef STQLITE_TEST
+#define sqliteBtreePageDump(pBt, pgno, recursive)\
+ (btOps(pBt)->PageDump(pBt, pgno, recursive))
+#define sqliteBtreeCursorDump(pCur, aResult)\
+ (btCOps(pCur)->CursorDump(pCur, aResult))
+int btree_native_byte_order;
+#endif /* STQLITE_TEST */
+
+
+#endif /* _BTREE_H_ */
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/btree_rb.c b/tqtinterface/qt4/src/3rdparty/sqlite/btree_rb.c
new file mode 100644
index 0000000..cc90075
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/btree_rb.c
@@ -0,0 +1,1488 @@
+/*
+** 2003 Feb 4
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** $Id: btree_rb.c,v 1.24 2004/02/29 00:11:31 drh Exp $
+**
+** This file implements an in-core database using Red-Black balanced
+** binary trees.
+**
+** It was contributed to STQLite by anonymous on 2003-Feb-04 23:24:49 UTC.
+*/
+#include "btree.h"
+#include "sqliteInt.h"
+#include <assert.h>
+
+/*
+** Omit this whole file if the STQLITE_OMIT_INMEMORYDB macro is
+** defined. This allows a lot of code to be omitted for installations
+** that do not need it.
+*/
+#ifndef STQLITE_OMIT_INMEMORYDB
+
+
+typedef struct BtRbTree BtRbTree;
+typedef struct BtRbNode BtRbNode;
+typedef struct BtRollbackOp BtRollbackOp;
+typedef struct Rbtree Rbtree;
+typedef struct RbtCursor RbtCursor;
+
+/* Forward declarations */
+static BtOps sqliteRbtreeOps;
+static BtCursorOps sqliteRbtreeCursorOps;
+
+/*
+ * During each transaction (or checkpoint), a linked-list of
+ * "rollback-operations" is accumulated. If the transaction is rolled back,
+ * then the list of operations must be executed (to restore the database to
+ * it's state before the transaction started). If the transaction is to be
+ * committed, just delete the list.
+ *
+ * Each operation is represented as follows, depending on the value of eOp:
+ *
+ * ROLLBACK_INSERT -> Need to insert (pKey, pData) into table iTab.
+ * ROLLBACK_DELETE -> Need to delete the record (pKey) into table iTab.
+ * ROLLBACK_CREATE -> Need to create table iTab.
+ * ROLLBACK_DROP -> Need to drop table iTab.
+ */
+struct BtRollbackOp {
+ u8 eOp;
+ int iTab;
+ int nKey;
+ void *pKey;
+ int nData;
+ void *pData;
+ BtRollbackOp *pNext;
+};
+
+/*
+** Legal values for BtRollbackOp.eOp:
+*/
+#define ROLLBACK_INSERT 1 /* Insert a record */
+#define ROLLBACK_DELETE 2 /* Delete a record */
+#define ROLLBACK_CREATE 3 /* Create a table */
+#define ROLLBACK_DROP 4 /* Drop a table */
+
+struct Rbtree {
+ BtOps *pOps; /* Function table */
+ int aMetaData[STQLITE_N_BTREE_META];
+
+ int next_idx; /* next available table index */
+ Hash tblHash; /* All created tables, by index */
+ u8 isAnonymous; /* True if this Rbtree is to be deleted when closed */
+ u8 eTransState; /* State of this Rbtree wrt transactions */
+
+ BtRollbackOp *pTransRollback;
+ BtRollbackOp *pCheckRollback;
+ BtRollbackOp *pCheckRollbackTail;
+};
+
+/*
+** Legal values for Rbtree.eTransState.
+*/
+#define TRANS_NONE 0 /* No transaction is in progress */
+#define TRANS_INTRANSACTION 1 /* A transaction is in progress */
+#define TRANS_INCHECKPOINT 2 /* A checkpoint is in progress */
+#define TRANS_ROLLBACK 3 /* We are currently rolling back a checkpoint or
+ * transaction. */
+
+struct RbtCursor {
+ BtCursorOps *pOps; /* Function table */
+ Rbtree *pRbtree;
+ BtRbTree *pTree;
+ int iTree; /* Index of pTree in pRbtree */
+ BtRbNode *pNode;
+ RbtCursor *pShared; /* List of all cursors on the same Rbtree */
+ u8 eSkip; /* Determines if next step operation is a no-op */
+ u8 wrFlag; /* True if this cursor is open for writing */
+};
+
+/*
+** Legal values for RbtCursor.eSkip.
+*/
+#define SKIP_NONE 0 /* Always step the cursor */
+#define SKIP_NEXT 1 /* The next sqliteRbtreeNext() is a no-op */
+#define SKIP_PREV 2 /* The next sqliteRbtreePrevious() is a no-op */
+#define SKIP_INVALID 3 /* Calls to Next() and Previous() are invalid */
+
+struct BtRbTree {
+ RbtCursor *pCursors; /* All cursors pointing to this tree */
+ BtRbNode *pHead; /* Head of the tree, or NULL */
+};
+
+struct BtRbNode {
+ int nKey;
+ void *pKey;
+ int nData;
+ void *pData;
+ u8 isBlack; /* true for a black node, 0 for a red node */
+ BtRbNode *pParent; /* Nodes tqparent node, NULL for the tree head */
+ BtRbNode *pLeft; /* Nodes left child, or NULL */
+ BtRbNode *pRight; /* Nodes right child, or NULL */
+
+ int nBlackHeight; /* Only used during the red-black integrity check */
+};
+
+/* Forward declarations */
+static int memRbtreeMoveto(
+ RbtCursor* pCur,
+ const void *pKey,
+ int nKey,
+ int *pRes
+);
+static int memRbtreeClearTable(Rbtree* tree, int n);
+static int memRbtreeNext(RbtCursor* pCur, int *pRes);
+static int memRbtreeLast(RbtCursor* pCur, int *pRes);
+static int memRbtreePrevious(RbtCursor* pCur, int *pRes);
+
+
+/*
+** This routine checks all cursors that point to the same table
+** as pCur points to. If any of those cursors were opened with
+** wrFlag==0 then this routine returns STQLITE_LOCKED. If all
+** cursors point to the same table were opened with wrFlag==1
+** then this routine returns STQLITE_OK.
+**
+** In addition to checking for read-locks (where a read-lock
+** means a cursor opened with wrFlag==0) this routine also NULLs
+** out the pNode field of all other cursors.
+** This is necessary because an insert
+** or delete might change erase the node out from under
+** another cursor.
+*/
+static int checkReadLocks(RbtCursor *pCur){
+ RbtCursor *p;
+ assert( pCur->wrFlag );
+ for(p=pCur->pTree->pCursors; p; p=p->pShared){
+ if( p!=pCur ){
+ if( p->wrFlag==0 ) return STQLITE_LOCKED;
+ p->pNode = 0;
+ }
+ }
+ return STQLITE_OK;
+}
+
+/*
+ * The key-compare function for the red-black trees. Returns as follows:
+ *
+ * (key1 < key2) -1
+ * (key1 == key2) 0
+ * (key1 > key2) 1
+ *
+ * Keys are compared using memcmp(). If one key is an exact prefix of the
+ * other, then the shorter key is less than the longer key.
+ */
+static int key_compare(void const*pKey1, int nKey1, void const*pKey2, int nKey2)
+{
+ int mcmp = memcmp(pKey1, pKey2, (nKey1 <= nKey2)?nKey1:nKey2);
+ if( mcmp == 0){
+ if( nKey1 == nKey2 ) return 0;
+ return ((nKey1 < nKey2)?-1:1);
+ }
+ return ((mcmp>0)?1:-1);
+}
+
+/*
+ * Perform the LEFT-rotate transformation on node X of tree pTree. This
+ * transform is part of the red-black balancing code.
+ *
+ * | |
+ * X Y
+ * / \ / \
+ * a Y X c
+ * / \ / \
+ * b c a b
+ *
+ * BEFORE AFTER
+ */
+static void leftRotate(BtRbTree *pTree, BtRbNode *pX)
+{
+ BtRbNode *pY;
+ BtRbNode *pb;
+ pY = pX->pRight;
+ pb = pY->pLeft;
+
+ pY->pParent = pX->pParent;
+ if( pX->pParent ){
+ if( pX->pParent->pLeft == pX ) pX->pParent->pLeft = pY;
+ else pX->pParent->pRight = pY;
+ }
+ pY->pLeft = pX;
+ pX->pParent = pY;
+ pX->pRight = pb;
+ if( pb ) pb->pParent = pX;
+ if( pTree->pHead == pX ) pTree->pHead = pY;
+}
+
+/*
+ * Perform the RIGHT-rotate transformation on node X of tree pTree. This
+ * transform is part of the red-black balancing code.
+ *
+ * | |
+ * X Y
+ * / \ / \
+ * Y c a X
+ * / \ / \
+ * a b b c
+ *
+ * BEFORE AFTER
+ */
+static void rightRotate(BtRbTree *pTree, BtRbNode *pX)
+{
+ BtRbNode *pY;
+ BtRbNode *pb;
+ pY = pX->pLeft;
+ pb = pY->pRight;
+
+ pY->pParent = pX->pParent;
+ if( pX->pParent ){
+ if( pX->pParent->pLeft == pX ) pX->pParent->pLeft = pY;
+ else pX->pParent->pRight = pY;
+ }
+ pY->pRight = pX;
+ pX->pParent = pY;
+ pX->pLeft = pb;
+ if( pb ) pb->pParent = pX;
+ if( pTree->pHead == pX ) pTree->pHead = pY;
+}
+
+/*
+ * A string-manipulation helper function for check_redblack_tree(). If (orig ==
+ * NULL) a copy of val is returned. If (orig != NULL) then a copy of the *
+ * concatenation of orig and val is returned. The original orig is deleted
+ * (using sqliteFree()).
+ */
+static char *append_val(char * orig, char const * val){
+ char *z;
+ if( !orig ){
+ z = sqliteStrDup( val );
+ } else{
+ z = 0;
+ sqliteSetString(&z, orig, val, (char*)0);
+ sqliteFree( orig );
+ }
+ return z;
+}
+
+/*
+ * Append a string representation of the entire node to orig and return it.
+ * This is used to produce debugging information if check_redblack_tree() tqfinds
+ * a problem with a red-black binary tree.
+ */
+static char *append_node(char * orig, BtRbNode *pNode, int indent)
+{
+ char buf[128];
+ int i;
+
+ for( i=0; i<indent; i++ ){
+ orig = append_val(orig, " ");
+ }
+
+ sprintf(buf, "%p", pNode);
+ orig = append_val(orig, buf);
+
+ if( pNode ){
+ indent += 3;
+ if( pNode->isBlack ){
+ orig = append_val(orig, " B \n");
+ }else{
+ orig = append_val(orig, " R \n");
+ }
+ orig = append_node( orig, pNode->pLeft, indent );
+ orig = append_node( orig, pNode->pRight, indent );
+ }else{
+ orig = append_val(orig, "\n");
+ }
+ return orig;
+}
+
+/*
+ * Print a representation of a node to stdout. This function is only included
+ * so you can call it from within a debugger if things get really bad. It
+ * is not called from anyplace in the code.
+ */
+static void print_node(BtRbNode *pNode)
+{
+ char * str = append_node(0, pNode, 0);
+ printf(str);
+
+ /* Suppress a warning message about print_node() being unused */
+ (void)print_node;
+}
+
+/*
+ * Check the following properties of the red-black tree:
+ * (1) - If a node is red, both of it's tqchildren are black
+ * (2) - Each path from a given node to a leaf (NULL) node passes thru the
+ * same number of black nodes
+ *
+ * If there is a problem, append a description (using append_val() ) to *msg.
+ */
+static void check_redblack_tree(BtRbTree * tree, char ** msg)
+{
+ BtRbNode *pNode;
+
+ /* 0 -> came from tqparent
+ * 1 -> came from left
+ * 2 -> came from right */
+ int prev_step = 0;
+
+ pNode = tree->pHead;
+ while( pNode ){
+ switch( prev_step ){
+ case 0:
+ if( pNode->pLeft ){
+ pNode = pNode->pLeft;
+ }else{
+ prev_step = 1;
+ }
+ break;
+ case 1:
+ if( pNode->pRight ){
+ pNode = pNode->pRight;
+ prev_step = 0;
+ }else{
+ prev_step = 2;
+ }
+ break;
+ case 2:
+ /* Check red-black property (1) */
+ if( !pNode->isBlack &&
+ ( (pNode->pLeft && !pNode->pLeft->isBlack) ||
+ (pNode->pRight && !pNode->pRight->isBlack) )
+ ){
+ char buf[128];
+ sprintf(buf, "Red node with red child at %p\n", pNode);
+ *msg = append_val(*msg, buf);
+ *msg = append_node(*msg, tree->pHead, 0);
+ *msg = append_val(*msg, "\n");
+ }
+
+ /* Check red-black property (2) */
+ {
+ int leftHeight = 0;
+ int rightHeight = 0;
+ if( pNode->pLeft ){
+ leftHeight += pNode->pLeft->nBlackHeight;
+ leftHeight += (pNode->pLeft->isBlack?1:0);
+ }
+ if( pNode->pRight ){
+ rightHeight += pNode->pRight->nBlackHeight;
+ rightHeight += (pNode->pRight->isBlack?1:0);
+ }
+ if( leftHeight != rightHeight ){
+ char buf[128];
+ sprintf(buf, "Different black-heights at %p\n", pNode);
+ *msg = append_val(*msg, buf);
+ *msg = append_node(*msg, tree->pHead, 0);
+ *msg = append_val(*msg, "\n");
+ }
+ pNode->nBlackHeight = leftHeight;
+ }
+
+ if( pNode->pParent ){
+ if( pNode == pNode->pParent->pLeft ) prev_step = 1;
+ else prev_step = 2;
+ }
+ pNode = pNode->pParent;
+ break;
+ default: assert(0);
+ }
+ }
+}
+
+/*
+ * Node pX has just been inserted into pTree (by code in sqliteRbtreeInsert()).
+ * It is possible that pX is a red node with a red tqparent, which is a violation
+ * of the red-black tree properties. This function performs rotations and
+ * color changes to rebalance the tree
+ */
+static void do_insert_balancing(BtRbTree *pTree, BtRbNode *pX)
+{
+ /* In the first iteration of this loop, pX points to the red node just
+ * inserted in the tree. If the tqparent of pX exists (pX is not the root
+ * node) and is red, then the properties of the red-black tree are
+ * violated.
+ *
+ * At the start of any subsequent iterations, pX points to a red node
+ * with a red tqparent. In all other respects the tree is a legal red-black
+ * binary tree. */
+ while( pX != pTree->pHead && !pX->pParent->isBlack ){
+ BtRbNode *pUncle;
+ BtRbNode *pGrandtqparent;
+
+ /* Grandtqparent of pX must exist and must be black. */
+ pGrandtqparent = pX->pParent->pParent;
+ assert( pGrandtqparent );
+ assert( pGrandtqparent->isBlack );
+
+ /* Uncle of pX may or may not exist. */
+ if( pX->pParent == pGrandtqparent->pLeft )
+ pUncle = pGrandtqparent->pRight;
+ else
+ pUncle = pGrandtqparent->pLeft;
+
+ /* If the uncle of pX exists and is red, we do the following:
+ * | |
+ * G(b) G(r)
+ * / \ / \
+ * U(r) P(r) U(b) P(b)
+ * \ \
+ * X(r) X(r)
+ *
+ * BEFORE AFTER
+ * pX is then set to G. If the tqparent of G is red, then the while loop
+ * will run again. */
+ if( pUncle && !pUncle->isBlack ){
+ pGrandtqparent->isBlack = 0;
+ pUncle->isBlack = 1;
+ pX->pParent->isBlack = 1;
+ pX = pGrandtqparent;
+ }else{
+
+ if( pX->pParent == pGrandtqparent->pLeft ){
+ if( pX == pX->pParent->pRight ){
+ /* If pX is a right-child, do the following transform, essentially
+ * to change pX into a left-child:
+ * | |
+ * G(b) G(b)
+ * / \ / \
+ * P(r) U(b) X(r) U(b)
+ * \ /
+ * X(r) P(r) <-- new X
+ *
+ * BEFORE AFTER
+ */
+ pX = pX->pParent;
+ leftRotate(pTree, pX);
+ }
+
+ /* Do the following transform, which balances the tree :)
+ * | |
+ * G(b) P(b)
+ * / \ / \
+ * P(r) U(b) X(r) G(r)
+ * / \
+ * X(r) U(b)
+ *
+ * BEFORE AFTER
+ */
+ assert( pGrandtqparent == pX->pParent->pParent );
+ pGrandtqparent->isBlack = 0;
+ pX->pParent->isBlack = 1;
+ rightRotate( pTree, pGrandtqparent );
+
+ }else{
+ /* This code is symetric to the illustrated case above. */
+ if( pX == pX->pParent->pLeft ){
+ pX = pX->pParent;
+ rightRotate(pTree, pX);
+ }
+ assert( pGrandtqparent == pX->pParent->pParent );
+ pGrandtqparent->isBlack = 0;
+ pX->pParent->isBlack = 1;
+ leftRotate( pTree, pGrandtqparent );
+ }
+ }
+ }
+ pTree->pHead->isBlack = 1;
+}
+
+/*
+ * A child of pParent, which in turn had child pX, has just been removed from
+ * pTree (the figure below depicts the operation, Z is being removed). pParent
+ * or pX, or both may be NULL.
+ * | |
+ * P P
+ * / \ / \
+ * Z X
+ * / \
+ * X nil
+ *
+ * This function is only called if Z was black. In this case the red-black tree
+ * properties have been violated, and pX has an "extra black". This function
+ * performs rotations and color-changes to re-balance the tree.
+ */
+static
+void do_delete_balancing(BtRbTree *pTree, BtRbNode *pX, BtRbNode *pParent)
+{
+ BtRbNode *pSib;
+
+ /* TODO: Comment this code! */
+ while( pX != pTree->pHead && (!pX || pX->isBlack) ){
+ if( pX == pParent->pLeft ){
+ pSib = pParent->pRight;
+ if( pSib && !(pSib->isBlack) ){
+ pSib->isBlack = 1;
+ pParent->isBlack = 0;
+ leftRotate(pTree, pParent);
+ pSib = pParent->pRight;
+ }
+ if( !pSib ){
+ pX = pParent;
+ }else if(
+ (!pSib->pLeft || pSib->pLeft->isBlack) &&
+ (!pSib->pRight || pSib->pRight->isBlack) ) {
+ pSib->isBlack = 0;
+ pX = pParent;
+ }else{
+ if( (!pSib->pRight || pSib->pRight->isBlack) ){
+ if( pSib->pLeft ) pSib->pLeft->isBlack = 1;
+ pSib->isBlack = 0;
+ rightRotate( pTree, pSib );
+ pSib = pParent->pRight;
+ }
+ pSib->isBlack = pParent->isBlack;
+ pParent->isBlack = 1;
+ if( pSib->pRight ) pSib->pRight->isBlack = 1;
+ leftRotate(pTree, pParent);
+ pX = pTree->pHead;
+ }
+ }else{
+ pSib = pParent->pLeft;
+ if( pSib && !(pSib->isBlack) ){
+ pSib->isBlack = 1;
+ pParent->isBlack = 0;
+ rightRotate(pTree, pParent);
+ pSib = pParent->pLeft;
+ }
+ if( !pSib ){
+ pX = pParent;
+ }else if(
+ (!pSib->pLeft || pSib->pLeft->isBlack) &&
+ (!pSib->pRight || pSib->pRight->isBlack) ){
+ pSib->isBlack = 0;
+ pX = pParent;
+ }else{
+ if( (!pSib->pLeft || pSib->pLeft->isBlack) ){
+ if( pSib->pRight ) pSib->pRight->isBlack = 1;
+ pSib->isBlack = 0;
+ leftRotate( pTree, pSib );
+ pSib = pParent->pLeft;
+ }
+ pSib->isBlack = pParent->isBlack;
+ pParent->isBlack = 1;
+ if( pSib->pLeft ) pSib->pLeft->isBlack = 1;
+ rightRotate(pTree, pParent);
+ pX = pTree->pHead;
+ }
+ }
+ pParent = pX->pParent;
+ }
+ if( pX ) pX->isBlack = 1;
+}
+
+/*
+ * Create table n in tree pRbtree. Table n must not exist.
+ */
+static void btreeCreateTable(Rbtree* pRbtree, int n)
+{
+ BtRbTree *pNewTbl = sqliteMalloc(sizeof(BtRbTree));
+ sqliteHashInsert(&pRbtree->tblHash, 0, n, pNewTbl);
+}
+
+/*
+ * Log a single "rollback-op" for the given Rbtree. See comments for struct
+ * BtRollbackOp.
+ */
+static void btreeLogRollbackOp(Rbtree* pRbtree, BtRollbackOp *pRollbackOp)
+{
+ assert( pRbtree->eTransState == TRANS_INCHECKPOINT ||
+ pRbtree->eTransState == TRANS_INTRANSACTION );
+ if( pRbtree->eTransState == TRANS_INTRANSACTION ){
+ pRollbackOp->pNext = pRbtree->pTransRollback;
+ pRbtree->pTransRollback = pRollbackOp;
+ }
+ if( pRbtree->eTransState == TRANS_INCHECKPOINT ){
+ if( !pRbtree->pCheckRollback ){
+ pRbtree->pCheckRollbackTail = pRollbackOp;
+ }
+ pRollbackOp->pNext = pRbtree->pCheckRollback;
+ pRbtree->pCheckRollback = pRollbackOp;
+ }
+}
+
+int sqliteRbtreeOpen(
+ const char *zFilename,
+ int mode,
+ int nPg,
+ Btree **ppBtree
+){
+ Rbtree **ppRbtree = (Rbtree**)ppBtree;
+ *ppRbtree = (Rbtree *)sqliteMalloc(sizeof(Rbtree));
+ if( sqlite_malloc_failed ) goto open_no_mem;
+ sqliteHashInit(&(*ppRbtree)->tblHash, STQLITE_HASH_INT, 0);
+
+ /* Create a binary tree for the STQLITE_MASTER table at location 2 */
+ btreeCreateTable(*ppRbtree, 2);
+ if( sqlite_malloc_failed ) goto open_no_mem;
+ (*ppRbtree)->next_idx = 3;
+ (*ppRbtree)->pOps = &sqliteRbtreeOps;
+ /* Set file type to 4; this is so that "attach ':memory:' as ...." does not
+ ** think that the database in uninitialised and refuse to attach
+ */
+ (*ppRbtree)->aMetaData[2] = 4;
+
+ return STQLITE_OK;
+
+open_no_mem:
+ *ppBtree = 0;
+ return STQLITE_NOMEM;
+}
+
+/*
+ * Create a new table in the supplied Rbtree. Set *n to the new table number.
+ * Return STQLITE_OK if the operation is a success.
+ */
+static int memRbtreeCreateTable(Rbtree* tree, int* n)
+{
+ assert( tree->eTransState != TRANS_NONE );
+
+ *n = tree->next_idx++;
+ btreeCreateTable(tree, *n);
+ if( sqlite_malloc_failed ) return STQLITE_NOMEM;
+
+ /* Set up the rollback structure (if we are not doing this as part of a
+ * rollback) */
+ if( tree->eTransState != TRANS_ROLLBACK ){
+ BtRollbackOp *pRollbackOp = sqliteMalloc(sizeof(BtRollbackOp));
+ if( pRollbackOp==0 ) return STQLITE_NOMEM;
+ pRollbackOp->eOp = ROLLBACK_DROP;
+ pRollbackOp->iTab = *n;
+ btreeLogRollbackOp(tree, pRollbackOp);
+ }
+
+ return STQLITE_OK;
+}
+
+/*
+ * Delete table n from the supplied Rbtree.
+ */
+static int memRbtreeDropTable(Rbtree* tree, int n)
+{
+ BtRbTree *pTree;
+ assert( tree->eTransState != TRANS_NONE );
+
+ memRbtreeClearTable(tree, n);
+ pTree = sqliteHashInsert(&tree->tblHash, 0, n, 0);
+ assert(pTree);
+ assert( pTree->pCursors==0 );
+ sqliteFree(pTree);
+
+ if( tree->eTransState != TRANS_ROLLBACK ){
+ BtRollbackOp *pRollbackOp = sqliteMalloc(sizeof(BtRollbackOp));
+ if( pRollbackOp==0 ) return STQLITE_NOMEM;
+ pRollbackOp->eOp = ROLLBACK_CREATE;
+ pRollbackOp->iTab = n;
+ btreeLogRollbackOp(tree, pRollbackOp);
+ }
+
+ return STQLITE_OK;
+}
+
+static int memRbtreeKeyCompare(RbtCursor* pCur, const void *pKey, int nKey,
+ int nIgnore, int *pRes)
+{
+ assert(pCur);
+
+ if( !pCur->pNode ) {
+ *pRes = -1;
+ } else {
+ if( (pCur->pNode->nKey - nIgnore) < 0 ){
+ *pRes = -1;
+ }else{
+ *pRes = key_compare(pCur->pNode->pKey, pCur->pNode->nKey-nIgnore,
+ pKey, nKey);
+ }
+ }
+ return STQLITE_OK;
+}
+
+/*
+ * Get a new cursor for table iTable of the supplied Rbtree. The wrFlag
+ * parameter indicates that the cursor is open for writing.
+ *
+ * Note that RbtCursor.eSkip and RbtCursor.pNode both initialize to 0.
+ */
+static int memRbtreeCursor(
+ Rbtree* tree,
+ int iTable,
+ int wrFlag,
+ RbtCursor **ppCur
+){
+ RbtCursor *pCur;
+ assert(tree);
+ pCur = *ppCur = sqliteMalloc(sizeof(RbtCursor));
+ if( sqlite_malloc_failed ) return STQLITE_NOMEM;
+ pCur->pTree = sqliteHashFind(&tree->tblHash, 0, iTable);
+ assert( pCur->pTree );
+ pCur->pRbtree = tree;
+ pCur->iTree = iTable;
+ pCur->pOps = &sqliteRbtreeCursorOps;
+ pCur->wrFlag = wrFlag;
+ pCur->pShared = pCur->pTree->pCursors;
+ pCur->pTree->pCursors = pCur;
+
+ assert( (*ppCur)->pTree );
+ return STQLITE_OK;
+}
+
+/*
+ * Insert a new record into the Rbtree. The key is given by (pKey,nKey)
+ * and the data is given by (pData,nData). The cursor is used only to
+ * define what database the record should be inserted into. The cursor
+ * is left pointing at the new record.
+ *
+ * If the key exists already in the tree, just tqreplace the data.
+ */
+static int memRbtreeInsert(
+ RbtCursor* pCur,
+ const void *pKey,
+ int nKey,
+ const void *pDataInput,
+ int nData
+){
+ void * pData;
+ int match;
+
+ /* It is illegal to call sqliteRbtreeInsert() if we are
+ ** not in a transaction */
+ assert( pCur->pRbtree->eTransState != TRANS_NONE );
+
+ /* Make sure some other cursor isn't trying to read this same table */
+ if( checkReadLocks(pCur) ){
+ return STQLITE_LOCKED; /* The table pCur points to has a read lock */
+ }
+
+ /* Take a copy of the input data now, in case we need it for the
+ * tqreplace case */
+ pData = sqliteMallocRaw(nData);
+ if( sqlite_malloc_failed ) return STQLITE_NOMEM;
+ memcpy(pData, pDataInput, nData);
+
+ /* Move the cursor to a node near the key to be inserted. If the key already
+ * exists in the table, then (match == 0). In this case we can just tqreplace
+ * the data associated with the entry, we don't need to manipulate the tree.
+ *
+ * If there is no exact match, then the cursor points at what would be either
+ * the predecessor (match == -1) or successor (match == 1) of the
+ * searched-for key, were it to be inserted. The new node becomes a child of
+ * this node.
+ *
+ * The new node is initially red.
+ */
+ memRbtreeMoveto( pCur, pKey, nKey, &match);
+ if( match ){
+ BtRbNode *pNode = sqliteMalloc(sizeof(BtRbNode));
+ if( pNode==0 ) return STQLITE_NOMEM;
+ pNode->nKey = nKey;
+ pNode->pKey = sqliteMallocRaw(nKey);
+ if( sqlite_malloc_failed ) return STQLITE_NOMEM;
+ memcpy(pNode->pKey, pKey, nKey);
+ pNode->nData = nData;
+ pNode->pData = pData;
+ if( pCur->pNode ){
+ switch( match ){
+ case -1:
+ assert( !pCur->pNode->pRight );
+ pNode->pParent = pCur->pNode;
+ pCur->pNode->pRight = pNode;
+ break;
+ case 1:
+ assert( !pCur->pNode->pLeft );
+ pNode->pParent = pCur->pNode;
+ pCur->pNode->pLeft = pNode;
+ break;
+ default:
+ assert(0);
+ }
+ }else{
+ pCur->pTree->pHead = pNode;
+ }
+
+ /* Point the cursor at the node just inserted, as per STQLite requirements */
+ pCur->pNode = pNode;
+
+ /* A new node has just been inserted, so run the balancing code */
+ do_insert_balancing(pCur->pTree, pNode);
+
+ /* Set up a rollback-op in case we have to roll this operation back */
+ if( pCur->pRbtree->eTransState != TRANS_ROLLBACK ){
+ BtRollbackOp *pOp = sqliteMalloc( sizeof(BtRollbackOp) );
+ if( pOp==0 ) return STQLITE_NOMEM;
+ pOp->eOp = ROLLBACK_DELETE;
+ pOp->iTab = pCur->iTree;
+ pOp->nKey = pNode->nKey;
+ pOp->pKey = sqliteMallocRaw( pOp->nKey );
+ if( sqlite_malloc_failed ) return STQLITE_NOMEM;
+ memcpy( pOp->pKey, pNode->pKey, pOp->nKey );
+ btreeLogRollbackOp(pCur->pRbtree, pOp);
+ }
+
+ }else{
+ /* No need to insert a new node in the tree, as the key already exists.
+ * Just clobber the current nodes data. */
+
+ /* Set up a rollback-op in case we have to roll this operation back */
+ if( pCur->pRbtree->eTransState != TRANS_ROLLBACK ){
+ BtRollbackOp *pOp = sqliteMalloc( sizeof(BtRollbackOp) );
+ if( pOp==0 ) return STQLITE_NOMEM;
+ pOp->iTab = pCur->iTree;
+ pOp->nKey = pCur->pNode->nKey;
+ pOp->pKey = sqliteMallocRaw( pOp->nKey );
+ if( sqlite_malloc_failed ) return STQLITE_NOMEM;
+ memcpy( pOp->pKey, pCur->pNode->pKey, pOp->nKey );
+ pOp->nData = pCur->pNode->nData;
+ pOp->pData = pCur->pNode->pData;
+ pOp->eOp = ROLLBACK_INSERT;
+ btreeLogRollbackOp(pCur->pRbtree, pOp);
+ }else{
+ sqliteFree( pCur->pNode->pData );
+ }
+
+ /* Actually clobber the nodes data */
+ pCur->pNode->pData = pData;
+ pCur->pNode->nData = nData;
+ }
+
+ return STQLITE_OK;
+}
+
+/* Move the cursor so that it points to an entry near pKey.
+** Return a success code.
+**
+** *pRes<0 The cursor is left pointing at an entry that
+** is smaller than pKey or if the table is empty
+** and the cursor is therefore left point to nothing.
+**
+** *pRes==0 The cursor is left pointing at an entry that
+** exactly matches pKey.
+**
+** *pRes>0 The cursor is left pointing at an entry that
+** is larger than pKey.
+*/
+static int memRbtreeMoveto(
+ RbtCursor* pCur,
+ const void *pKey,
+ int nKey,
+ int *pRes
+){
+ BtRbNode *pTmp = 0;
+
+ pCur->pNode = pCur->pTree->pHead;
+ *pRes = -1;
+ while( pCur->pNode && *pRes ) {
+ *pRes = key_compare(pCur->pNode->pKey, pCur->pNode->nKey, pKey, nKey);
+ pTmp = pCur->pNode;
+ switch( *pRes ){
+ case 1: /* cursor > key */
+ pCur->pNode = pCur->pNode->pLeft;
+ break;
+ case -1: /* cursor < key */
+ pCur->pNode = pCur->pNode->pRight;
+ break;
+ }
+ }
+
+ /* If (pCur->pNode == NULL), then we have failed to tqfind a match. Set
+ * pCur->pNode to pTmp, which is either NULL (if the tree is empty) or the
+ * last node traversed in the search. In either case the relation ship
+ * between pTmp and the searched for key is already stored in *pRes. pTmp is
+ * either the successor or predecessor of the key we tried to move to. */
+ if( !pCur->pNode ) pCur->pNode = pTmp;
+ pCur->eSkip = SKIP_NONE;
+
+ return STQLITE_OK;
+}
+
+
+/*
+** Delete the entry that the cursor is pointing to.
+**
+** The cursor is left pointing at either the next or the previous
+** entry. If the cursor is left pointing to the next entry, then
+** the pCur->eSkip flag is set to SKIP_NEXT which forces the next call to
+** sqliteRbtreeNext() to be a no-op. That way, you can always call
+** sqliteRbtreeNext() after a delete and the cursor will be left
+** pointing to the first entry after the deleted entry. Similarly,
+** pCur->eSkip is set to SKIP_PREV is the cursor is left pointing to
+** the entry prior to the deleted entry so that a subsequent call to
+** sqliteRbtreePrevious() will always leave the cursor pointing at the
+** entry immediately before the one that was deleted.
+*/
+static int memRbtreeDelete(RbtCursor* pCur)
+{
+ BtRbNode *pZ; /* The one being deleted */
+ BtRbNode *pChild; /* The child of the spliced out node */
+
+ /* It is illegal to call sqliteRbtreeDelete() if we are
+ ** not in a transaction */
+ assert( pCur->pRbtree->eTransState != TRANS_NONE );
+
+ /* Make sure some other cursor isn't trying to read this same table */
+ if( checkReadLocks(pCur) ){
+ return STQLITE_LOCKED; /* The table pCur points to has a read lock */
+ }
+
+ pZ = pCur->pNode;
+ if( !pZ ){
+ return STQLITE_OK;
+ }
+
+ /* If we are not currently doing a rollback, set up a rollback op for this
+ * deletion */
+ if( pCur->pRbtree->eTransState != TRANS_ROLLBACK ){
+ BtRollbackOp *pOp = sqliteMalloc( sizeof(BtRollbackOp) );
+ if( pOp==0 ) return STQLITE_NOMEM;
+ pOp->iTab = pCur->iTree;
+ pOp->nKey = pZ->nKey;
+ pOp->pKey = pZ->pKey;
+ pOp->nData = pZ->nData;
+ pOp->pData = pZ->pData;
+ pOp->eOp = ROLLBACK_INSERT;
+ btreeLogRollbackOp(pCur->pRbtree, pOp);
+ }
+
+ /* First do a standard binary-tree delete (node pZ is to be deleted). How
+ * to do this depends on how many tqchildren pZ has:
+ *
+ * If pZ has no tqchildren or one child, then splice out pZ. If pZ has two
+ * tqchildren, splice out the successor of pZ and tqreplace the key and data of
+ * pZ with the key and data of the spliced out successor. */
+ if( pZ->pLeft && pZ->pRight ){
+ BtRbNode *pTmp;
+ int dummy;
+ pCur->eSkip = SKIP_NONE;
+ memRbtreeNext(pCur, &dummy);
+ assert( dummy == 0 );
+ if( pCur->pRbtree->eTransState == TRANS_ROLLBACK ){
+ sqliteFree(pZ->pKey);
+ sqliteFree(pZ->pData);
+ }
+ pZ->pData = pCur->pNode->pData;
+ pZ->nData = pCur->pNode->nData;
+ pZ->pKey = pCur->pNode->pKey;
+ pZ->nKey = pCur->pNode->nKey;
+ pTmp = pZ;
+ pZ = pCur->pNode;
+ pCur->pNode = pTmp;
+ pCur->eSkip = SKIP_NEXT;
+ }else{
+ int res;
+ pCur->eSkip = SKIP_NONE;
+ memRbtreeNext(pCur, &res);
+ pCur->eSkip = SKIP_NEXT;
+ if( res ){
+ memRbtreeLast(pCur, &res);
+ memRbtreePrevious(pCur, &res);
+ pCur->eSkip = SKIP_PREV;
+ }
+ if( pCur->pRbtree->eTransState == TRANS_ROLLBACK ){
+ sqliteFree(pZ->pKey);
+ sqliteFree(pZ->pData);
+ }
+ }
+
+ /* pZ now points at the node to be spliced out. This block does the
+ * splicing. */
+ {
+ BtRbNode **ppParentSlot = 0;
+ assert( !pZ->pLeft || !pZ->pRight ); /* pZ has at most one child */
+ pChild = ((pZ->pLeft)?pZ->pLeft:pZ->pRight);
+ if( pZ->pParent ){
+ assert( pZ == pZ->pParent->pLeft || pZ == pZ->pParent->pRight );
+ ppParentSlot = ((pZ == pZ->pParent->pLeft)
+ ?&pZ->pParent->pLeft:&pZ->pParent->pRight);
+ *ppParentSlot = pChild;
+ }else{
+ pCur->pTree->pHead = pChild;
+ }
+ if( pChild ) pChild->pParent = pZ->pParent;
+ }
+
+ /* pZ now points at the spliced out node. pChild is the only child of pZ, or
+ * NULL if pZ has no tqchildren. If pZ is black, and not the tree root, then we
+ * will have violated the "same number of black nodes in every path to a
+ * leaf" property of the red-black tree. The code in do_delete_balancing()
+ * repairs this. */
+ if( pZ->isBlack ){
+ do_delete_balancing(pCur->pTree, pChild, pZ->pParent);
+ }
+
+ sqliteFree(pZ);
+ return STQLITE_OK;
+}
+
+/*
+ * Empty table n of the Rbtree.
+ */
+static int memRbtreeClearTable(Rbtree* tree, int n)
+{
+ BtRbTree *pTree;
+ BtRbNode *pNode;
+
+ pTree = sqliteHashFind(&tree->tblHash, 0, n);
+ assert(pTree);
+
+ pNode = pTree->pHead;
+ while( pNode ){
+ if( pNode->pLeft ){
+ pNode = pNode->pLeft;
+ }
+ else if( pNode->pRight ){
+ pNode = pNode->pRight;
+ }
+ else {
+ BtRbNode *pTmp = pNode->pParent;
+ if( tree->eTransState == TRANS_ROLLBACK ){
+ sqliteFree( pNode->pKey );
+ sqliteFree( pNode->pData );
+ }else{
+ BtRollbackOp *pRollbackOp = sqliteMallocRaw(sizeof(BtRollbackOp));
+ if( pRollbackOp==0 ) return STQLITE_NOMEM;
+ pRollbackOp->eOp = ROLLBACK_INSERT;
+ pRollbackOp->iTab = n;
+ pRollbackOp->nKey = pNode->nKey;
+ pRollbackOp->pKey = pNode->pKey;
+ pRollbackOp->nData = pNode->nData;
+ pRollbackOp->pData = pNode->pData;
+ btreeLogRollbackOp(tree, pRollbackOp);
+ }
+ sqliteFree( pNode );
+ if( pTmp ){
+ if( pTmp->pLeft == pNode ) pTmp->pLeft = 0;
+ else if( pTmp->pRight == pNode ) pTmp->pRight = 0;
+ }
+ pNode = pTmp;
+ }
+ }
+
+ pTree->pHead = 0;
+ return STQLITE_OK;
+}
+
+static int memRbtreeFirst(RbtCursor* pCur, int *pRes)
+{
+ if( pCur->pTree->pHead ){
+ pCur->pNode = pCur->pTree->pHead;
+ while( pCur->pNode->pLeft ){
+ pCur->pNode = pCur->pNode->pLeft;
+ }
+ }
+ if( pCur->pNode ){
+ *pRes = 0;
+ }else{
+ *pRes = 1;
+ }
+ pCur->eSkip = SKIP_NONE;
+ return STQLITE_OK;
+}
+
+static int memRbtreeLast(RbtCursor* pCur, int *pRes)
+{
+ if( pCur->pTree->pHead ){
+ pCur->pNode = pCur->pTree->pHead;
+ while( pCur->pNode->pRight ){
+ pCur->pNode = pCur->pNode->pRight;
+ }
+ }
+ if( pCur->pNode ){
+ *pRes = 0;
+ }else{
+ *pRes = 1;
+ }
+ pCur->eSkip = SKIP_NONE;
+ return STQLITE_OK;
+}
+
+/*
+** Advance the cursor to the next entry in the database. If
+** successful then set *pRes=0. If the cursor
+** was already pointing to the last entry in the database before
+** this routine was called, then set *pRes=1.
+*/
+static int memRbtreeNext(RbtCursor* pCur, int *pRes)
+{
+ if( pCur->pNode && pCur->eSkip != SKIP_NEXT ){
+ if( pCur->pNode->pRight ){
+ pCur->pNode = pCur->pNode->pRight;
+ while( pCur->pNode->pLeft )
+ pCur->pNode = pCur->pNode->pLeft;
+ }else{
+ BtRbNode * pX = pCur->pNode;
+ pCur->pNode = pX->pParent;
+ while( pCur->pNode && (pCur->pNode->pRight == pX) ){
+ pX = pCur->pNode;
+ pCur->pNode = pX->pParent;
+ }
+ }
+ }
+ pCur->eSkip = SKIP_NONE;
+
+ if( !pCur->pNode ){
+ *pRes = 1;
+ }else{
+ *pRes = 0;
+ }
+
+ return STQLITE_OK;
+}
+
+static int memRbtreePrevious(RbtCursor* pCur, int *pRes)
+{
+ if( pCur->pNode && pCur->eSkip != SKIP_PREV ){
+ if( pCur->pNode->pLeft ){
+ pCur->pNode = pCur->pNode->pLeft;
+ while( pCur->pNode->pRight )
+ pCur->pNode = pCur->pNode->pRight;
+ }else{
+ BtRbNode * pX = pCur->pNode;
+ pCur->pNode = pX->pParent;
+ while( pCur->pNode && (pCur->pNode->pLeft == pX) ){
+ pX = pCur->pNode;
+ pCur->pNode = pX->pParent;
+ }
+ }
+ }
+ pCur->eSkip = SKIP_NONE;
+
+ if( !pCur->pNode ){
+ *pRes = 1;
+ }else{
+ *pRes = 0;
+ }
+
+ return STQLITE_OK;
+}
+
+static int memRbtreeKeySize(RbtCursor* pCur, int *pSize)
+{
+ if( pCur->pNode ){
+ *pSize = pCur->pNode->nKey;
+ }else{
+ *pSize = 0;
+ }
+ return STQLITE_OK;
+}
+
+static int memRbtreeKey(RbtCursor* pCur, int offset, int amt, char *zBuf)
+{
+ if( !pCur->pNode ) return 0;
+ if( !pCur->pNode->pKey || ((amt + offset) <= pCur->pNode->nKey) ){
+ memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, amt);
+ }else{
+ memcpy(zBuf, ((char*)pCur->pNode->pKey)+offset, pCur->pNode->nKey-offset);
+ amt = pCur->pNode->nKey-offset;
+ }
+ return amt;
+}
+
+static int memRbtreeDataSize(RbtCursor* pCur, int *pSize)
+{
+ if( pCur->pNode ){
+ *pSize = pCur->pNode->nData;
+ }else{
+ *pSize = 0;
+ }
+ return STQLITE_OK;
+}
+
+static int memRbtreeData(RbtCursor *pCur, int offset, int amt, char *zBuf)
+{
+ if( !pCur->pNode ) return 0;
+ if( (amt + offset) <= pCur->pNode->nData ){
+ memcpy(zBuf, ((char*)pCur->pNode->pData)+offset, amt);
+ }else{
+ memcpy(zBuf, ((char*)pCur->pNode->pData)+offset ,pCur->pNode->nData-offset);
+ amt = pCur->pNode->nData-offset;
+ }
+ return amt;
+}
+
+static int memRbtreeCloseCursor(RbtCursor* pCur)
+{
+ if( pCur->pTree->pCursors==pCur ){
+ pCur->pTree->pCursors = pCur->pShared;
+ }else{
+ RbtCursor *p = pCur->pTree->pCursors;
+ while( p && p->pShared!=pCur ){ p = p->pShared; }
+ assert( p!=0 );
+ if( p ){
+ p->pShared = pCur->pShared;
+ }
+ }
+ sqliteFree(pCur);
+ return STQLITE_OK;
+}
+
+static int memRbtreeGetMeta(Rbtree* tree, int* aMeta)
+{
+ memcpy( aMeta, tree->aMetaData, sizeof(int) * STQLITE_N_BTREE_META );
+ return STQLITE_OK;
+}
+
+static int memRbtreeUpdateMeta(Rbtree* tree, int* aMeta)
+{
+ memcpy( tree->aMetaData, aMeta, sizeof(int) * STQLITE_N_BTREE_META );
+ return STQLITE_OK;
+}
+
+/*
+ * Check that each table in the Rbtree meets the requirements for a red-black
+ * binary tree. If an error is found, return an explanation of the problem in
+ * memory obtained from sqliteMalloc(). Parameters aRoot and nRoot are ignored.
+ */
+static char *memRbtreeIntegrityCheck(Rbtree* tree, int* aRoot, int nRoot)
+{
+ char * msg = 0;
+ HashElem *p;
+
+ for(p=sqliteHashFirst(&tree->tblHash); p; p=sqliteHashNext(p)){
+ BtRbTree *pTree = sqliteHashData(p);
+ check_redblack_tree(pTree, &msg);
+ }
+
+ return msg;
+}
+
+static int memRbtreeSetCacheSize(Rbtree* tree, int sz)
+{
+ return STQLITE_OK;
+}
+
+static int memRbtreeSetSafetyLevel(Rbtree *pBt, int level){
+ return STQLITE_OK;
+}
+
+static int memRbtreeBeginTrans(Rbtree* tree)
+{
+ if( tree->eTransState != TRANS_NONE )
+ return STQLITE_ERROR;
+
+ assert( tree->pTransRollback == 0 );
+ tree->eTransState = TRANS_INTRANSACTION;
+ return STQLITE_OK;
+}
+
+/*
+** Delete a linked list of BtRollbackOp structures.
+*/
+static void deleteRollbackList(BtRollbackOp *pOp){
+ while( pOp ){
+ BtRollbackOp *pTmp = pOp->pNext;
+ sqliteFree(pOp->pData);
+ sqliteFree(pOp->pKey);
+ sqliteFree(pOp);
+ pOp = pTmp;
+ }
+}
+
+static int memRbtreeCommit(Rbtree* tree){
+ /* Just delete pTransRollback and pCheckRollback */
+ deleteRollbackList(tree->pCheckRollback);
+ deleteRollbackList(tree->pTransRollback);
+ tree->pTransRollback = 0;
+ tree->pCheckRollback = 0;
+ tree->pCheckRollbackTail = 0;
+ tree->eTransState = TRANS_NONE;
+ return STQLITE_OK;
+}
+
+/*
+ * Close the supplied Rbtree. Delete everything associated with it.
+ */
+static int memRbtreeClose(Rbtree* tree)
+{
+ HashElem *p;
+ memRbtreeCommit(tree);
+ while( (p=sqliteHashFirst(&tree->tblHash))!=0 ){
+ tree->eTransState = TRANS_ROLLBACK;
+ memRbtreeDropTable(tree, sqliteHashKeysize(p));
+ }
+ sqliteHashClear(&tree->tblHash);
+ sqliteFree(tree);
+ return STQLITE_OK;
+}
+
+/*
+ * Execute and delete the supplied rollback-list on pRbtree.
+ */
+static void execute_rollback_list(Rbtree *pRbtree, BtRollbackOp *pList)
+{
+ BtRollbackOp *pTmp;
+ RbtCursor cur;
+ int res;
+
+ cur.pRbtree = pRbtree;
+ cur.wrFlag = 1;
+ while( pList ){
+ switch( pList->eOp ){
+ case ROLLBACK_INSERT:
+ cur.pTree = sqliteHashFind( &pRbtree->tblHash, 0, pList->iTab );
+ assert(cur.pTree);
+ cur.iTree = pList->iTab;
+ cur.eSkip = SKIP_NONE;
+ memRbtreeInsert( &cur, pList->pKey,
+ pList->nKey, pList->pData, pList->nData );
+ break;
+ case ROLLBACK_DELETE:
+ cur.pTree = sqliteHashFind( &pRbtree->tblHash, 0, pList->iTab );
+ assert(cur.pTree);
+ cur.iTree = pList->iTab;
+ cur.eSkip = SKIP_NONE;
+ memRbtreeMoveto(&cur, pList->pKey, pList->nKey, &res);
+ assert(res == 0);
+ memRbtreeDelete( &cur );
+ break;
+ case ROLLBACK_CREATE:
+ btreeCreateTable(pRbtree, pList->iTab);
+ break;
+ case ROLLBACK_DROP:
+ memRbtreeDropTable(pRbtree, pList->iTab);
+ break;
+ default:
+ assert(0);
+ }
+ sqliteFree(pList->pKey);
+ sqliteFree(pList->pData);
+ pTmp = pList->pNext;
+ sqliteFree(pList);
+ pList = pTmp;
+ }
+}
+
+static int memRbtreeRollback(Rbtree* tree)
+{
+ tree->eTransState = TRANS_ROLLBACK;
+ execute_rollback_list(tree, tree->pCheckRollback);
+ execute_rollback_list(tree, tree->pTransRollback);
+ tree->pTransRollback = 0;
+ tree->pCheckRollback = 0;
+ tree->pCheckRollbackTail = 0;
+ tree->eTransState = TRANS_NONE;
+ return STQLITE_OK;
+}
+
+static int memRbtreeBeginCkpt(Rbtree* tree)
+{
+ if( tree->eTransState != TRANS_INTRANSACTION )
+ return STQLITE_ERROR;
+
+ assert( tree->pCheckRollback == 0 );
+ assert( tree->pCheckRollbackTail == 0 );
+ tree->eTransState = TRANS_INCHECKPOINT;
+ return STQLITE_OK;
+}
+
+static int memRbtreeCommitCkpt(Rbtree* tree)
+{
+ if( tree->eTransState == TRANS_INCHECKPOINT ){
+ if( tree->pCheckRollback ){
+ tree->pCheckRollbackTail->pNext = tree->pTransRollback;
+ tree->pTransRollback = tree->pCheckRollback;
+ tree->pCheckRollback = 0;
+ tree->pCheckRollbackTail = 0;
+ }
+ tree->eTransState = TRANS_INTRANSACTION;
+ }
+ return STQLITE_OK;
+}
+
+static int memRbtreeRollbackCkpt(Rbtree* tree)
+{
+ if( tree->eTransState != TRANS_INCHECKPOINT ) return STQLITE_OK;
+ tree->eTransState = TRANS_ROLLBACK;
+ execute_rollback_list(tree, tree->pCheckRollback);
+ tree->pCheckRollback = 0;
+ tree->pCheckRollbackTail = 0;
+ tree->eTransState = TRANS_INTRANSACTION;
+ return STQLITE_OK;
+}
+
+#ifdef STQLITE_TEST
+static int memRbtreePageDump(Rbtree* tree, int pgno, int rec)
+{
+ assert(!"Cannot call sqliteRbtreePageDump");
+ return STQLITE_OK;
+}
+
+static int memRbtreeCursorDump(RbtCursor* pCur, int* aRes)
+{
+ assert(!"Cannot call sqliteRbtreeCursorDump");
+ return STQLITE_OK;
+}
+#endif
+
+static struct Pager *memRbtreePager(Rbtree* tree)
+{
+ return 0;
+}
+
+/*
+** Return the full pathname of the underlying database file.
+*/
+static const char *memRbtreeGetFilename(Rbtree *pBt){
+ return 0; /* A NULL return indicates there is no underlying file */
+}
+
+/*
+** The copy file function is not implemented for the in-memory database
+*/
+static int memRbtreeCopyFile(Rbtree *pBt, Rbtree *pBt2){
+ return STQLITE_INTERNAL; /* Not implemented */
+}
+
+static BtOps sqliteRbtreeOps = {
+ (int(*)(Btree*)) memRbtreeClose,
+ (int(*)(Btree*,int)) memRbtreeSetCacheSize,
+ (int(*)(Btree*,int)) memRbtreeSetSafetyLevel,
+ (int(*)(Btree*)) memRbtreeBeginTrans,
+ (int(*)(Btree*)) memRbtreeCommit,
+ (int(*)(Btree*)) memRbtreeRollback,
+ (int(*)(Btree*)) memRbtreeBeginCkpt,
+ (int(*)(Btree*)) memRbtreeCommitCkpt,
+ (int(*)(Btree*)) memRbtreeRollbackCkpt,
+ (int(*)(Btree*,int*)) memRbtreeCreateTable,
+ (int(*)(Btree*,int*)) memRbtreeCreateTable,
+ (int(*)(Btree*,int)) memRbtreeDropTable,
+ (int(*)(Btree*,int)) memRbtreeClearTable,
+ (int(*)(Btree*,int,int,BtCursor**)) memRbtreeCursor,
+ (int(*)(Btree*,int*)) memRbtreeGetMeta,
+ (int(*)(Btree*,int*)) memRbtreeUpdateMeta,
+ (char*(*)(Btree*,int*,int)) memRbtreeIntegrityCheck,
+ (const char*(*)(Btree*)) memRbtreeGetFilename,
+ (int(*)(Btree*,Btree*)) memRbtreeCopyFile,
+ (struct Pager*(*)(Btree*)) memRbtreePager,
+#ifdef STQLITE_TEST
+ (int(*)(Btree*,int,int)) memRbtreePageDump,
+#endif
+};
+
+static BtCursorOps sqliteRbtreeCursorOps = {
+ (int(*)(BtCursor*,const void*,int,int*)) memRbtreeMoveto,
+ (int(*)(BtCursor*)) memRbtreeDelete,
+ (int(*)(BtCursor*,const void*,int,const void*,int)) memRbtreeInsert,
+ (int(*)(BtCursor*,int*)) memRbtreeFirst,
+ (int(*)(BtCursor*,int*)) memRbtreeLast,
+ (int(*)(BtCursor*,int*)) memRbtreeNext,
+ (int(*)(BtCursor*,int*)) memRbtreePrevious,
+ (int(*)(BtCursor*,int*)) memRbtreeKeySize,
+ (int(*)(BtCursor*,int,int,char*)) memRbtreeKey,
+ (int(*)(BtCursor*,const void*,int,int,int*)) memRbtreeKeyCompare,
+ (int(*)(BtCursor*,int*)) memRbtreeDataSize,
+ (int(*)(BtCursor*,int,int,char*)) memRbtreeData,
+ (int(*)(BtCursor*)) memRbtreeCloseCursor,
+#ifdef STQLITE_TEST
+ (int(*)(BtCursor*,int*)) memRbtreeCursorDump,
+#endif
+
+};
+
+#endif /* STQLITE_OMIT_INMEMORYDB */
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/build.c b/tqtinterface/qt4/src/3rdparty/sqlite/build.c
new file mode 100644
index 0000000..71e0110
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/build.c
@@ -0,0 +1,2157 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains C code routines that are called by the STQLite parser
+** when syntax rules are reduced. The routines in this file handle the
+** following kinds of SQL syntax:
+**
+** CREATE TABLE
+** DROP TABLE
+** CREATE INDEX
+** DROP INDEX
+** creating ID lists
+** BEGIN TRANSACTION
+** COMMIT
+** ROLLBACK
+** PRAGMA
+**
+** $Id: build.c,v 1.175 2004/02/24 01:04:12 drh Exp $
+*/
+#include "sqliteInt.h"
+#include <ctype.h>
+
+/*
+** This routine is called when a new SQL statement is beginning to
+** be parsed. Check to see if the schema for the database needs
+** to be read from the STQLITE_MASTER and STQLITE_TEMP_MASTER tables.
+** If it does, then read it.
+*/
+void sqliteBeginParse(Parse *pParse, int explainFlag){
+ sqlite *db = pParse->db;
+ int i;
+ pParse->explain = explainFlag;
+ if((db->flags & STQLITE_Initialized)==0 && db->init.busy==0 ){
+ int rc = sqliteInit(db, &pParse->zErrMsg);
+ if( rc!=STQLITE_OK ){
+ pParse->rc = rc;
+ pParse->nErr++;
+ }
+ }
+ for(i=0; i<db->nDb; i++){
+ DbClearProperty(db, i, DB_Locked);
+ if( !db->aDb[i].inTrans ){
+ DbClearProperty(db, i, DB_Cookie);
+ }
+ }
+ pParse->nVar = 0;
+}
+
+/*
+** This routine is called after a single SQL statement has been
+** parsed and we want to execute the VDBE code to implement
+** that statement. Prior action routines should have already
+** constructed VDBE code to do the work of the SQL statement.
+** This routine just has to execute the VDBE code.
+**
+** Note that if an error occurred, it might be the case that
+** no VDBE code was generated.
+*/
+void sqliteExec(Parse *pParse){
+ sqlite *db = pParse->db;
+ Vdbe *v = pParse->pVdbe;
+
+ if( v==0 && (v = sqliteGetVdbe(pParse))!=0 ){
+ sqliteVdbeAddOp(v, OP_Halt, 0, 0);
+ }
+ if( sqlite_malloc_failed ) return;
+ if( v && pParse->nErr==0 ){
+ FILE *trace = (db->flags & STQLITE_VdbeTrace)!=0 ? stdout : 0;
+ sqliteVdbeTrace(v, trace);
+ sqliteVdbeMakeReady(v, pParse->nVar, pParse->explain);
+ pParse->rc = pParse->nErr ? STQLITE_ERROR : STQLITE_DONE;
+ pParse->colNamesSet = 0;
+ }else if( pParse->rc==STQLITE_OK ){
+ pParse->rc = STQLITE_ERROR;
+ }
+ pParse->nTab = 0;
+ pParse->nMem = 0;
+ pParse->nSet = 0;
+ pParse->nAgg = 0;
+ pParse->nVar = 0;
+}
+
+/*
+** Locate the in-memory structure that describes
+** a particular database table given the name
+** of that table and (optionally) the name of the database
+** containing the table. Return NULL if not found.
+**
+** If zDatabase is 0, all databases are searched for the
+** table and the first matching table is returned. (No checking
+** for duplicate table names is done.) The search order is
+** TEMP first, then MAIN, then any auxiliary databases added
+** using the ATTACH command.
+**
+** See also sqliteLocateTable().
+*/
+Table *sqliteFindTable(sqlite *db, const char *zName, const char *zDatabase){
+ Table *p = 0;
+ int i;
+ for(i=0; i<db->nDb; i++){
+ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
+ if( zDatabase!=0 && sqliteStrICmp(zDatabase, db->aDb[j].zName) ) continue;
+ p = sqliteHashFind(&db->aDb[j].tblHash, zName, strlen(zName)+1);
+ if( p ) break;
+ }
+ return p;
+}
+
+/*
+** Locate the in-memory structure that describes
+** a particular database table given the name
+** of that table and (optionally) the name of the database
+** containing the table. Return NULL if not found.
+** Also leave an error message in pParse->zErrMsg.
+**
+** The difference between this routine and sqliteFindTable()
+** is that this routine leaves an error message in pParse->zErrMsg
+** where sqliteFindTable() does not.
+*/
+Table *sqliteLocateTable(Parse *pParse, const char *zName, const char *zDbase){
+ Table *p;
+
+ p = sqliteFindTable(pParse->db, zName, zDbase);
+ if( p==0 ){
+ if( zDbase ){
+ sqliteErrorMsg(pParse, "no such table: %s.%s", zDbase, zName);
+ }else if( sqliteFindTable(pParse->db, zName, 0)!=0 ){
+ sqliteErrorMsg(pParse, "table \"%s\" is not in database \"%s\"",
+ zName, zDbase);
+ }else{
+ sqliteErrorMsg(pParse, "no such table: %s", zName);
+ }
+ }
+ return p;
+}
+
+/*
+** Locate the in-memory structure that describes
+** a particular index given the name of that index
+** and the name of the database that tqcontains the index.
+** Return NULL if not found.
+**
+** If zDatabase is 0, all databases are searched for the
+** table and the first matching index is returned. (No checking
+** for duplicate index names is done.) The search order is
+** TEMP first, then MAIN, then any auxiliary databases added
+** using the ATTACH command.
+*/
+Index *sqliteFindIndex(sqlite *db, const char *zName, const char *zDb){
+ Index *p = 0;
+ int i;
+ for(i=0; i<db->nDb; i++){
+ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
+ if( zDb && sqliteStrICmp(zDb, db->aDb[j].zName) ) continue;
+ p = sqliteHashFind(&db->aDb[j].idxHash, zName, strlen(zName)+1);
+ if( p ) break;
+ }
+ return p;
+}
+
+/*
+** Remove the given index from the index hash table, and free
+** its memory structures.
+**
+** The index is removed from the database hash tables but
+** it is not unlinked from the Table that it indexes.
+** Unlinking from the Table must be done by the calling function.
+*/
+static void sqliteDeleteIndex(sqlite *db, Index *p){
+ Index *pOld;
+
+ assert( db!=0 && p->zName!=0 );
+ pOld = sqliteHashInsert(&db->aDb[p->iDb].idxHash, p->zName,
+ strlen(p->zName)+1, 0);
+ if( pOld!=0 && pOld!=p ){
+ sqliteHashInsert(&db->aDb[p->iDb].idxHash, pOld->zName,
+ strlen(pOld->zName)+1, pOld);
+ }
+ sqliteFree(p);
+}
+
+/*
+** Unlink the given index from its table, then remove
+** the index from the index hash table and free its memory
+** structures.
+*/
+void sqliteUnlinkAndDeleteIndex(sqlite *db, Index *pIndex){
+ if( pIndex->pTable->pIndex==pIndex ){
+ pIndex->pTable->pIndex = pIndex->pNext;
+ }else{
+ Index *p;
+ for(p=pIndex->pTable->pIndex; p && p->pNext!=pIndex; p=p->pNext){}
+ if( p && p->pNext==pIndex ){
+ p->pNext = pIndex->pNext;
+ }
+ }
+ sqliteDeleteIndex(db, pIndex);
+}
+
+/*
+** Erase all schema information from the in-memory hash tables of
+** database connection. This routine is called to reclaim memory
+** before the connection closes. It is also called during a rollback
+** if there were schema changes during the transaction.
+**
+** If iDb<=0 then reset the internal schema tables for all database
+** files. If iDb>=2 then reset the internal schema for only the
+** single file indicated.
+*/
+void sqliteResetInternalSchema(sqlite *db, int iDb){
+ HashElem *pElem;
+ Hash temp1;
+ Hash temp2;
+ int i, j;
+
+ assert( iDb>=0 && iDb<db->nDb );
+ db->flags &= ~STQLITE_Initialized;
+ for(i=iDb; i<db->nDb; i++){
+ Db *pDb = &db->aDb[i];
+ temp1 = pDb->tblHash;
+ temp2 = pDb->trigHash;
+ sqliteHashInit(&pDb->trigHash, STQLITE_HASH_STRING, 0);
+ sqliteHashClear(&pDb->aFKey);
+ sqliteHashClear(&pDb->idxHash);
+ for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
+ Trigger *pTrigger = sqliteHashData(pElem);
+ sqliteDeleteTrigger(pTrigger);
+ }
+ sqliteHashClear(&temp2);
+ sqliteHashInit(&pDb->tblHash, STQLITE_HASH_STRING, 0);
+ for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
+ Table *pTab = sqliteHashData(pElem);
+ sqliteDeleteTable(db, pTab);
+ }
+ sqliteHashClear(&temp1);
+ DbClearProperty(db, i, DB_SchemaLoaded);
+ if( iDb>0 ) return;
+ }
+ assert( iDb==0 );
+ db->flags &= ~STQLITE_InternChanges;
+
+ /* If one or more of the auxiliary database files has been closed,
+ ** then remove then from the auxiliary database list. We take the
+ ** opportunity to do this here since we have just deleted all of the
+ ** schema hash tables and therefore do not have to make any changes
+ ** to any of those tables.
+ */
+ for(i=0; i<db->nDb; i++){
+ struct Db *pDb = &db->aDb[i];
+ if( pDb->pBt==0 ){
+ if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
+ pDb->pAux = 0;
+ }
+ }
+ for(i=j=2; i<db->nDb; i++){
+ struct Db *pDb = &db->aDb[i];
+ if( pDb->pBt==0 ){
+ sqliteFree(pDb->zName);
+ pDb->zName = 0;
+ continue;
+ }
+ if( j<i ){
+ db->aDb[j] = db->aDb[i];
+ }
+ j++;
+ }
+ memset(&db->aDb[j], 0, (db->nDb-j)*sizeof(db->aDb[j]));
+ db->nDb = j;
+ if( db->nDb<=2 && db->aDb!=db->aDbStatic ){
+ memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0]));
+ sqliteFree(db->aDb);
+ db->aDb = db->aDbStatic;
+ }
+}
+
+/*
+** This routine is called whenever a rollback occurs. If there were
+** schema changes during the transaction, then we have to reset the
+** internal hash tables and reload them from disk.
+*/
+void sqliteRollbackInternalChanges(sqlite *db){
+ if( db->flags & STQLITE_InternChanges ){
+ sqliteResetInternalSchema(db, 0);
+ }
+}
+
+/*
+** This routine is called when a commit occurs.
+*/
+void sqliteCommitInternalChanges(sqlite *db){
+ db->aDb[0].schema_cookie = db->next_cookie;
+ db->flags &= ~STQLITE_InternChanges;
+}
+
+/*
+** Remove the memory data structures associated with the given
+** Table. No changes are made to disk by this routine.
+**
+** This routine just deletes the data structure. It does not unlink
+** the table data structure from the hash table. Nor does it remove
+** foreign keys from the sqlite.aFKey hash table. But it does destroy
+** memory structures of the indices and foreign keys associated with
+** the table.
+**
+** Indices associated with the table are unlinked from the "db"
+** data structure if db!=NULL. If db==NULL, indices attached to
+** the table are deleted, but it is assumed they have already been
+** unlinked.
+*/
+void sqliteDeleteTable(sqlite *db, Table *pTable){
+ int i;
+ Index *pIndex, *pNext;
+ FKey *pFKey, *pNextFKey;
+
+ if( pTable==0 ) return;
+
+ /* Delete all indices associated with this table
+ */
+ for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
+ pNext = pIndex->pNext;
+ assert( pIndex->iDb==pTable->iDb || (pTable->iDb==0 && pIndex->iDb==1) );
+ sqliteDeleteIndex(db, pIndex);
+ }
+
+ /* Delete all foreign keys associated with this table. The keys
+ ** should have already been unlinked from the db->aFKey hash table
+ */
+ for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){
+ pNextFKey = pFKey->pNextFrom;
+ assert( pTable->iDb<db->nDb );
+ assert( sqliteHashFind(&db->aDb[pTable->iDb].aFKey,
+ pFKey->zTo, strlen(pFKey->zTo)+1)!=pFKey );
+ sqliteFree(pFKey);
+ }
+
+ /* Delete the Table structure itself.
+ */
+ for(i=0; i<pTable->nCol; i++){
+ sqliteFree(pTable->aCol[i].zName);
+ sqliteFree(pTable->aCol[i].zDflt);
+ sqliteFree(pTable->aCol[i].zType);
+ }
+ sqliteFree(pTable->zName);
+ sqliteFree(pTable->aCol);
+ sqliteSelectDelete(pTable->pSelect);
+ sqliteFree(pTable);
+}
+
+/*
+** Unlink the given table from the hash tables and the delete the
+** table structure with all its indices and foreign keys.
+*/
+static void sqliteUnlinkAndDeleteTable(sqlite *db, Table *p){
+ Table *pOld;
+ FKey *pF1, *pF2;
+ int i = p->iDb;
+ assert( db!=0 );
+ pOld = sqliteHashInsert(&db->aDb[i].tblHash, p->zName, strlen(p->zName)+1, 0);
+ assert( pOld==0 || pOld==p );
+ for(pF1=p->pFKey; pF1; pF1=pF1->pNextFrom){
+ int nTo = strlen(pF1->zTo) + 1;
+ pF2 = sqliteHashFind(&db->aDb[i].aFKey, pF1->zTo, nTo);
+ if( pF2==pF1 ){
+ sqliteHashInsert(&db->aDb[i].aFKey, pF1->zTo, nTo, pF1->pNextTo);
+ }else{
+ while( pF2 && pF2->pNextTo!=pF1 ){ pF2=pF2->pNextTo; }
+ if( pF2 ){
+ pF2->pNextTo = pF1->pNextTo;
+ }
+ }
+ }
+ sqliteDeleteTable(db, p);
+}
+
+/*
+** Construct the name of a user table or index from a token.
+**
+** Space to hold the name is obtained from sqliteMalloc() and must
+** be freed by the calling function.
+*/
+char *sqliteTableNameFromToken(Token *pName){
+ char *zName = sqliteStrNDup(pName->z, pName->n);
+ sqliteDequote(zName);
+ return zName;
+}
+
+/*
+** Generate code to open the appropriate master table. The table
+** opened will be STQLITE_MASTER for persistent tables and
+** STQLITE_TEMP_MASTER for temporary tables. The table is opened
+** on cursor 0.
+*/
+void sqliteOpenMasterTable(Vdbe *v, int isTemp){
+ sqliteVdbeAddOp(v, OP_Integer, isTemp, 0);
+ sqliteVdbeAddOp(v, OP_OpenWrite, 0, 2);
+}
+
+/*
+** Begin constructing a new table representation in memory. This is
+** the first of several action routines that get called in response
+** to a CREATE TABLE statement. In particular, this routine is called
+** after seeing tokens "CREATE" and "TABLE" and the table name. The
+** pStart token is the CREATE and pName is the table name. The isTemp
+** flag is true if the table should be stored in the auxiliary database
+** file instead of in the main database file. This is normally the case
+** when the "TEMP" or "TEMPORARY" keyword occurs in between
+** CREATE and TABLE.
+**
+** The new table record is initialized and put in pParse->pNewTable.
+** As more of the CREATE TABLE statement is parsed, additional action
+** routines will be called to add more information to this record.
+** At the end of the CREATE TABLE statement, the sqliteEndTable() routine
+** is called to complete the construction of the new table record.
+*/
+void sqliteStartTable(
+ Parse *pParse, /* Parser context */
+ Token *pStart, /* The "CREATE" token */
+ Token *pName, /* Name of table or view to create */
+ int isTemp, /* True if this is a TEMP table */
+ int isView /* True if this is a VIEW */
+){
+ Table *pTable;
+ Index *pIdx;
+ char *zName;
+ sqlite *db = pParse->db;
+ Vdbe *v;
+ int iDb;
+
+ pParse->sFirstToken = *pStart;
+ zName = sqliteTableNameFromToken(pName);
+ if( zName==0 ) return;
+ if( db->init.iDb==1 ) isTemp = 1;
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ assert( (isTemp & 1)==isTemp );
+ {
+ int code;
+ char *zDb = isTemp ? "temp" : "main";
+ if( sqliteAuthCheck(pParse, STQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
+ sqliteFree(zName);
+ return;
+ }
+ if( isView ){
+ if( isTemp ){
+ code = STQLITE_CREATE_TEMP_VIEW;
+ }else{
+ code = STQLITE_CREATE_VIEW;
+ }
+ }else{
+ if( isTemp ){
+ code = STQLITE_CREATE_TEMP_TABLE;
+ }else{
+ code = STQLITE_CREATE_TABLE;
+ }
+ }
+ if( sqliteAuthCheck(pParse, code, zName, 0, zDb) ){
+ sqliteFree(zName);
+ return;
+ }
+ }
+#endif
+
+
+ /* Before trying to create a temporary table, make sure the Btree for
+ ** holding temporary tables is open.
+ */
+ if( isTemp && db->aDb[1].pBt==0 && !pParse->explain ){
+ int rc = sqliteBtreeFactory(db, 0, 0, MAX_PAGES, &db->aDb[1].pBt);
+ if( rc!=STQLITE_OK ){
+ sqliteErrorMsg(pParse, "unable to open a temporary database "
+ "file for storing temporary tables");
+ pParse->nErr++;
+ return;
+ }
+ if( db->flags & STQLITE_InTrans ){
+ rc = sqliteBtreeBeginTrans(db->aDb[1].pBt);
+ if( rc!=STQLITE_OK ){
+ sqliteErrorMsg(pParse, "unable to get a write lock on "
+ "the temporary database file");
+ pParse->nErr++;
+ return;
+ }
+ }
+ }
+
+ /* Make sure the new table name does not collide with an existing
+ ** index or table name. Issue an error message if it does.
+ **
+ ** If we are re-reading the sqlite_master table because of a schema
+ ** change and a new permanent table is found whose name collides with
+ ** an existing temporary table, that is not an error.
+ */
+ pTable = sqliteFindTable(db, zName, 0);
+ iDb = isTemp ? 1 : db->init.iDb;
+ if( pTable!=0 && (pTable->iDb==iDb || !db->init.busy) ){
+ sqliteErrorMsg(pParse, "table %T already exists", pName);
+ sqliteFree(zName);
+ return;
+ }
+ if( (pIdx = sqliteFindIndex(db, zName, 0))!=0 &&
+ (pIdx->iDb==0 || !db->init.busy) ){
+ sqliteErrorMsg(pParse, "there is already an index named %s", zName);
+ sqliteFree(zName);
+ return;
+ }
+ pTable = sqliteMalloc( sizeof(Table) );
+ if( pTable==0 ){
+ sqliteFree(zName);
+ return;
+ }
+ pTable->zName = zName;
+ pTable->nCol = 0;
+ pTable->aCol = 0;
+ pTable->iPKey = -1;
+ pTable->pIndex = 0;
+ pTable->iDb = iDb;
+ if( pParse->pNewTable ) sqliteDeleteTable(db, pParse->pNewTable);
+ pParse->pNewTable = pTable;
+
+ /* Begin generating the code that will insert the table record into
+ ** the STQLITE_MASTER table. Note in particular that we must go ahead
+ ** and allocate the record number for the table entry now. Before any
+ ** PRIMARY KEY or UNITQUE keywords are parsed. Those keywords will cause
+ ** indices to be created and the table record must come before the
+ ** indices. Hence, the record number for the table must be allocated
+ ** now.
+ */
+ if( !db->init.busy && (v = sqliteGetVdbe(pParse))!=0 ){
+ sqliteBeginWriteOperation(pParse, 0, isTemp);
+ if( !isTemp ){
+ sqliteVdbeAddOp(v, OP_Integer, db->file_format, 0);
+ sqliteVdbeAddOp(v, OP_SetCookie, 0, 1);
+ }
+ sqliteOpenMasterTable(v, isTemp);
+ sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
+ }
+}
+
+/*
+** Add a new column to the table currently being constructed.
+**
+** The parser calls this routine once for each column declaration
+** in a CREATE TABLE statement. sqliteStartTable() gets called
+** first to get things going. Then this routine is called for each
+** column.
+*/
+void sqliteAddColumn(Parse *pParse, Token *pName){
+ Table *p;
+ int i;
+ char *z = 0;
+ Column *pCol;
+ if( (p = pParse->pNewTable)==0 ) return;
+ sqliteSetNString(&z, pName->z, pName->n, 0);
+ if( z==0 ) return;
+ sqliteDequote(z);
+ for(i=0; i<p->nCol; i++){
+ if( sqliteStrICmp(z, p->aCol[i].zName)==0 ){
+ sqliteErrorMsg(pParse, "duplicate column name: %s", z);
+ sqliteFree(z);
+ return;
+ }
+ }
+ if( (p->nCol & 0x7)==0 ){
+ Column *aNew;
+ aNew = sqliteRealloc( p->aCol, (p->nCol+8)*sizeof(p->aCol[0]));
+ if( aNew==0 ) return;
+ p->aCol = aNew;
+ }
+ pCol = &p->aCol[p->nCol];
+ memset(pCol, 0, sizeof(p->aCol[0]));
+ pCol->zName = z;
+ pCol->sortOrder = STQLITE_SO_NUM;
+ p->nCol++;
+}
+
+/*
+** This routine is called by the parser while in the middle of
+** parsing a CREATE TABLE statement. A "NOT NULL" constraint has
+** been seen on a column. This routine sets the notNull flag on
+** the column currently under construction.
+*/
+void sqliteAddNotNull(Parse *pParse, int onError){
+ Table *p;
+ int i;
+ if( (p = pParse->pNewTable)==0 ) return;
+ i = p->nCol-1;
+ if( i>=0 ) p->aCol[i].notNull = onError;
+}
+
+/*
+** This routine is called by the parser while in the middle of
+** parsing a CREATE TABLE statement. The pFirst token is the first
+** token in the sequence of tokens that describe the type of the
+** column currently under construction. pLast is the last token
+** in the sequence. Use this information to construct a string
+** that tqcontains the typename of the column and store that string
+** in zType.
+*/
+void sqliteAddColumnType(Parse *pParse, Token *pFirst, Token *pLast){
+ Table *p;
+ int i, j;
+ int n;
+ char *z, **pz;
+ Column *pCol;
+ if( (p = pParse->pNewTable)==0 ) return;
+ i = p->nCol-1;
+ if( i<0 ) return;
+ pCol = &p->aCol[i];
+ pz = &pCol->zType;
+ n = pLast->n + Addr(pLast->z) - Addr(pFirst->z);
+ sqliteSetNString(pz, pFirst->z, n, 0);
+ z = *pz;
+ if( z==0 ) return;
+ for(i=j=0; z[i]; i++){
+ int c = z[i];
+ if( isspace(c) ) continue;
+ z[j++] = c;
+ }
+ z[j] = 0;
+ if( pParse->db->file_format>=4 ){
+ pCol->sortOrder = sqliteCollateType(z, n);
+ }else{
+ pCol->sortOrder = STQLITE_SO_NUM;
+ }
+}
+
+/*
+** The given token is the default value for the last column added to
+** the table currently under construction. If "minusFlag" is true, it
+** means the value token was preceded by a minus sign.
+**
+** This routine is called by the parser while in the middle of
+** parsing a CREATE TABLE statement.
+*/
+void sqliteAddDefaultValue(Parse *pParse, Token *pVal, int minusFlag){
+ Table *p;
+ int i;
+ char **pz;
+ if( (p = pParse->pNewTable)==0 ) return;
+ i = p->nCol-1;
+ if( i<0 ) return;
+ pz = &p->aCol[i].zDflt;
+ if( minusFlag ){
+ sqliteSetNString(pz, "-", 1, pVal->z, pVal->n, 0);
+ }else{
+ sqliteSetNString(pz, pVal->z, pVal->n, 0);
+ }
+ sqliteDequote(*pz);
+}
+
+/*
+** Designate the PRIMARY KEY for the table. pList is a list of names
+** of columns that form the primary key. If pList is NULL, then the
+** most recently added column of the table is the primary key.
+**
+** A table can have at most one primary key. If the table already has
+** a primary key (and this is the second primary key) then create an
+** error.
+**
+** If the PRIMARY KEY is on a single column whose datatype is INTEGER,
+** then we will try to use that column as the row id. (Exception:
+** For backwards compatibility with older databases, do not do this
+** if the file format version number is less than 1.) Set the Table.iPKey
+** field of the table under construction to be the index of the
+** INTEGER PRIMARY KEY column. Table.iPKey is set to -1 if there is
+** no INTEGER PRIMARY KEY.
+**
+** If the key is not an INTEGER PRIMARY KEY, then create a unique
+** index for the key. No index is created for INTEGER PRIMARY KEYs.
+*/
+void sqliteAddPrimaryKey(Parse *pParse, IdList *pList, int onError){
+ Table *pTab = pParse->pNewTable;
+ char *zType = 0;
+ int iCol = -1, i;
+ if( pTab==0 ) goto primary_key_exit;
+ if( pTab->hasPrimKey ){
+ sqliteErrorMsg(pParse,
+ "table \"%s\" has more than one primary key", pTab->zName);
+ goto primary_key_exit;
+ }
+ pTab->hasPrimKey = 1;
+ if( pList==0 ){
+ iCol = pTab->nCol - 1;
+ pTab->aCol[iCol].isPrimKey = 1;
+ }else{
+ for(i=0; i<pList->nId; i++){
+ for(iCol=0; iCol<pTab->nCol; iCol++){
+ if( sqliteStrICmp(pList->a[i].zName, pTab->aCol[iCol].zName)==0 ) break;
+ }
+ if( iCol<pTab->nCol ) pTab->aCol[iCol].isPrimKey = 1;
+ }
+ if( pList->nId>1 ) iCol = -1;
+ }
+ if( iCol>=0 && iCol<pTab->nCol ){
+ zType = pTab->aCol[iCol].zType;
+ }
+ if( pParse->db->file_format>=1 &&
+ zType && sqliteStrICmp(zType, "INTEGER")==0 ){
+ pTab->iPKey = iCol;
+ pTab->keyConf = onError;
+ }else{
+ sqliteCreateIndex(pParse, 0, 0, pList, onError, 0, 0);
+ pList = 0;
+ }
+
+primary_key_exit:
+ sqliteIdListDelete(pList);
+ return;
+}
+
+/*
+** Return the appropriate collating type given a type name.
+**
+** The collation type is text (STQLITE_SO_TEXT) if the type
+** name tqcontains the character stream "text" or "blob" or
+** "clob". Any other type name is collated as numeric
+** (STQLITE_SO_NUM).
+*/
+int sqliteCollateType(const char *zType, int nType){
+ int i;
+ for(i=0; i<nType-3; i++){
+ int c = *(zType++) | 0x60;
+ if( (c=='b' || c=='c') && sqliteStrNICmp(zType, "lob", 3)==0 ){
+ return STQLITE_SO_TEXT;
+ }
+ if( c=='c' && sqliteStrNICmp(zType, "har", 3)==0 ){
+ return STQLITE_SO_TEXT;
+ }
+ if( c=='t' && sqliteStrNICmp(zType, "ext", 3)==0 ){
+ return STQLITE_SO_TEXT;
+ }
+ }
+ return STQLITE_SO_NUM;
+}
+
+/*
+** This routine is called by the parser while in the middle of
+** parsing a CREATE TABLE statement. A "COLLATE" clause has
+** been seen on a column. This routine sets the Column.sortOrder on
+** the column currently under construction.
+*/
+void sqliteAddCollateType(Parse *pParse, int collType){
+ Table *p;
+ int i;
+ if( (p = pParse->pNewTable)==0 ) return;
+ i = p->nCol-1;
+ if( i>=0 ) p->aCol[i].sortOrder = collType;
+}
+
+/*
+** Come up with a new random value for the schema cookie. Make sure
+** the new value is different from the old.
+**
+** The schema cookie is used to determine when the schema for the
+** database changes. After each schema change, the cookie value
+** changes. When a process first reads the schema it records the
+** cookie. Thereafter, whenever it goes to access the database,
+** it checks the cookie to make sure the schema has not changed
+** since it was last read.
+**
+** This plan is not completely bullet-proof. It is possible for
+** the schema to change multiple times and for the cookie to be
+** set back to prior value. But schema changes are infrequent
+** and the probability of hitting the same cookie value is only
+** 1 chance in 2^32. So we're safe enough.
+*/
+void sqliteChangeCookie(sqlite *db, Vdbe *v){
+ if( db->next_cookie==db->aDb[0].schema_cookie ){
+ unsigned char r;
+ sqliteRandomness(1, &r);
+ db->next_cookie = db->aDb[0].schema_cookie + r + 1;
+ db->flags |= STQLITE_InternChanges;
+ sqliteVdbeAddOp(v, OP_Integer, db->next_cookie, 0);
+ sqliteVdbeAddOp(v, OP_SetCookie, 0, 0);
+ }
+}
+
+/*
+** Measure the number of characters needed to output the given
+** identifier. The number returned includes any quotes used
+** but does not include the null terminator.
+*/
+static int identLength(const char *z){
+ int n;
+ int needQuote = 0;
+ for(n=0; *z; n++, z++){
+ if( *z=='\'' ){ n++; needQuote=1; }
+ }
+ return n + needQuote*2;
+}
+
+/*
+** Write an identifier onto the end of the given string. Add
+** quote characters as needed.
+*/
+static void identPut(char *z, int *pIdx, char *zIdent){
+ int i, j, needQuote;
+ i = *pIdx;
+ for(j=0; zIdent[j]; j++){
+ if( !isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
+ }
+ needQuote = zIdent[j]!=0 || isdigit(zIdent[0])
+ || sqliteKeywordCode(zIdent, j)!=TK_ID;
+ if( needQuote ) z[i++] = '\'';
+ for(j=0; zIdent[j]; j++){
+ z[i++] = zIdent[j];
+ if( zIdent[j]=='\'' ) z[i++] = '\'';
+ }
+ if( needQuote ) z[i++] = '\'';
+ z[i] = 0;
+ *pIdx = i;
+}
+
+/*
+** Generate a CREATE TABLE statement appropriate for the given
+** table. Memory to hold the text of the statement is obtained
+** from sqliteMalloc() and must be freed by the calling function.
+*/
+static char *createTableStmt(Table *p){
+ int i, k, n;
+ char *zStmt;
+ char *zSep, *zSep2, *zEnd;
+ n = 0;
+ for(i=0; i<p->nCol; i++){
+ n += identLength(p->aCol[i].zName);
+ }
+ n += identLength(p->zName);
+ if( n<40 ){
+ zSep = "";
+ zSep2 = ",";
+ zEnd = ")";
+ }else{
+ zSep = "\n ";
+ zSep2 = ",\n ";
+ zEnd = "\n)";
+ }
+ n += 35 + 6*p->nCol;
+ zStmt = sqliteMallocRaw( n );
+ if( zStmt==0 ) return 0;
+ strcpy(zStmt, p->iDb==1 ? "CREATE TEMP TABLE " : "CREATE TABLE ");
+ k = strlen(zStmt);
+ identPut(zStmt, &k, p->zName);
+ zStmt[k++] = '(';
+ for(i=0; i<p->nCol; i++){
+ strcpy(&zStmt[k], zSep);
+ k += strlen(&zStmt[k]);
+ zSep = zSep2;
+ identPut(zStmt, &k, p->aCol[i].zName);
+ }
+ strcpy(&zStmt[k], zEnd);
+ return zStmt;
+}
+
+/*
+** This routine is called to report the final ")" that terminates
+** a CREATE TABLE statement.
+**
+** The table structure that other action routines have been building
+** is added to the internal hash tables, assuming no errors have
+** occurred.
+**
+** An entry for the table is made in the master table on disk, unless
+** this is a temporary table or db->init.busy==1. When db->init.busy==1
+** it means we are reading the sqlite_master table because we just
+** connected to the database or because the sqlite_master table has
+** recently changes, so the entry for this table already exists in
+** the sqlite_master table. We do not want to create it again.
+**
+** If the pSelect argument is not NULL, it means that this routine
+** was called to create a table generated from a
+** "CREATE TABLE ... AS SELECT ..." statement. The column names of
+** the new table will match the result set of the SELECT.
+*/
+void sqliteEndTable(Parse *pParse, Token *pEnd, Select *pSelect){
+ Table *p;
+ sqlite *db = pParse->db;
+
+ if( (pEnd==0 && pSelect==0) || pParse->nErr || sqlite_malloc_failed ) return;
+ p = pParse->pNewTable;
+ if( p==0 ) return;
+
+ /* If the table is generated from a SELECT, then construct the
+ ** list of columns and the text of the table.
+ */
+ if( pSelect ){
+ Table *pSelTab = sqliteResultSetOfSelect(pParse, 0, pSelect);
+ if( pSelTab==0 ) return;
+ assert( p->aCol==0 );
+ p->nCol = pSelTab->nCol;
+ p->aCol = pSelTab->aCol;
+ pSelTab->nCol = 0;
+ pSelTab->aCol = 0;
+ sqliteDeleteTable(0, pSelTab);
+ }
+
+ /* If the db->init.busy is 1 it means we are reading the SQL off the
+ ** "sqlite_master" or "sqlite_temp_master" table on the disk.
+ ** So do not write to the disk again. Extract the root page number
+ ** for the table from the db->init.newTnum field. (The page number
+ ** should have been put there by the sqliteOpenCb routine.)
+ */
+ if( db->init.busy ){
+ p->tnum = db->init.newTnum;
+ }
+
+ /* If not initializing, then create a record for the new table
+ ** in the STQLITE_MASTER table of the database. The record number
+ ** for the new table entry should already be on the stack.
+ **
+ ** If this is a TEMPORARY table, write the entry into the auxiliary
+ ** file instead of into the main database file.
+ */
+ if( !db->init.busy ){
+ int n;
+ Vdbe *v;
+
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ) return;
+ if( p->pSelect==0 ){
+ /* A regular table */
+ sqliteVdbeOp3(v, OP_CreateTable, 0, p->iDb, (char*)&p->tnum, P3_POINTER);
+ }else{
+ /* A view */
+ sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+ }
+ p->tnum = 0;
+ sqliteVdbeAddOp(v, OP_Pull, 1, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0, p->pSelect==0?"table":"view", P3_STATIC);
+ sqliteVdbeOp3(v, OP_String, 0, 0, p->zName, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0, p->zName, 0);
+ sqliteVdbeAddOp(v, OP_Dup, 4, 0);
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ if( pSelect ){
+ char *z = createTableStmt(p);
+ n = z ? strlen(z) : 0;
+ sqliteVdbeChangeP3(v, -1, z, n);
+ sqliteFree(z);
+ }else{
+ assert( pEnd!=0 );
+ n = Addr(pEnd->z) - Addr(pParse->sFirstToken.z) + 1;
+ sqliteVdbeChangeP3(v, -1, pParse->sFirstToken.z, n);
+ }
+ sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
+ if( !p->iDb ){
+ sqliteChangeCookie(db, v);
+ }
+ sqliteVdbeAddOp(v, OP_Close, 0, 0);
+ if( pSelect ){
+ sqliteVdbeAddOp(v, OP_Integer, p->iDb, 0);
+ sqliteVdbeAddOp(v, OP_OpenWrite, 1, 0);
+ pParse->nTab = 2;
+ sqliteSelect(pParse, pSelect, SRT_Table, 1, 0, 0, 0);
+ }
+ sqliteEndWriteOperation(pParse);
+ }
+
+ /* Add the table to the in-memory representation of the database.
+ */
+ if( pParse->explain==0 && pParse->nErr==0 ){
+ Table *pOld;
+ FKey *pFKey;
+ pOld = sqliteHashInsert(&db->aDb[p->iDb].tblHash,
+ p->zName, strlen(p->zName)+1, p);
+ if( pOld ){
+ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */
+ return;
+ }
+ for(pFKey=p->pFKey; pFKey; pFKey=pFKey->pNextFrom){
+ int nTo = strlen(pFKey->zTo) + 1;
+ pFKey->pNextTo = sqliteHashFind(&db->aDb[p->iDb].aFKey, pFKey->zTo, nTo);
+ sqliteHashInsert(&db->aDb[p->iDb].aFKey, pFKey->zTo, nTo, pFKey);
+ }
+ pParse->pNewTable = 0;
+ db->nTable++;
+ db->flags |= STQLITE_InternChanges;
+ }
+}
+
+/*
+** The parser calls this routine in order to create a new VIEW
+*/
+void sqliteCreateView(
+ Parse *pParse, /* The parsing context */
+ Token *pBegin, /* The CREATE token that begins the statement */
+ Token *pName, /* The token that holds the name of the view */
+ Select *pSelect, /* A SELECT statement that will become the new view */
+ int isTemp /* TRUE for a TEMPORARY view */
+){
+ Table *p;
+ int n;
+ const char *z;
+ Token sEnd;
+ DbFixer sFix;
+
+ sqliteStartTable(pParse, pBegin, pName, isTemp, 1);
+ p = pParse->pNewTable;
+ if( p==0 || pParse->nErr ){
+ sqliteSelectDelete(pSelect);
+ return;
+ }
+ if( sqliteFixInit(&sFix, pParse, p->iDb, "view", pName)
+ && sqliteFixSelect(&sFix, pSelect)
+ ){
+ sqliteSelectDelete(pSelect);
+ return;
+ }
+
+ /* Make a copy of the entire SELECT statement that defines the view.
+ ** This will force all the Expr.token.z values to be dynamically
+ ** allocated rather than point to the input string - which means that
+ ** they will persist after the current sqlite_exec() call returns.
+ */
+ p->pSelect = sqliteSelectDup(pSelect);
+ sqliteSelectDelete(pSelect);
+ if( !pParse->db->init.busy ){
+ sqliteViewGetColumnNames(pParse, p);
+ }
+
+ /* Locate the end of the CREATE VIEW statement. Make sEnd point to
+ ** the end.
+ */
+ sEnd = pParse->sLastToken;
+ if( sEnd.z[0]!=0 && sEnd.z[0]!=';' ){
+ sEnd.z += sEnd.n;
+ }
+ sEnd.n = 0;
+ n = ((int)sEnd.z) - (int)pBegin->z;
+ z = pBegin->z;
+ while( n>0 && (z[n-1]==';' || isspace(z[n-1])) ){ n--; }
+ sEnd.z = &z[n-1];
+ sEnd.n = 1;
+
+ /* Use sqliteEndTable() to add the view to the STQLITE_MASTER table */
+ sqliteEndTable(pParse, &sEnd, 0);
+ return;
+}
+
+/*
+** The Table structure pTable is really a VIEW. Fill in the names of
+** the columns of the view in the pTable structure. Return the number
+** of errors. If an error is seen leave an error message in pParse->zErrMsg.
+*/
+int sqliteViewGetColumnNames(Parse *pParse, Table *pTable){
+ ExprList *pEList;
+ Select *pSel;
+ Table *pSelTab;
+ int nErr = 0;
+
+ assert( pTable );
+
+ /* A positive nCol means the columns names for this view are
+ ** already known.
+ */
+ if( pTable->nCol>0 ) return 0;
+
+ /* A negative nCol is a special marker meaning that we are currently
+ ** trying to compute the column names. If we enter this routine with
+ ** a negative nCol, it means two or more views form a loop, like this:
+ **
+ ** CREATE VIEW one AS SELECT * FROM two;
+ ** CREATE VIEW two AS SELECT * FROM one;
+ **
+ ** Actually, this error is caught previously and so the following test
+ ** should always fail. But we will leave it in place just to be safe.
+ */
+ if( pTable->nCol<0 ){
+ sqliteErrorMsg(pParse, "view %s is circularly defined", pTable->zName);
+ return 1;
+ }
+
+ /* If we get this far, it means we need to compute the table names.
+ */
+ assert( pTable->pSelect ); /* If nCol==0, then pTable must be a VIEW */
+ pSel = pTable->pSelect;
+
+ /* Note that the call to sqliteResultSetOfSelect() will expand any
+ ** "*" elements in this list. But we will need to restore the list
+ ** back to its original configuration afterwards, so we save a copy of
+ ** the original in pEList.
+ */
+ pEList = pSel->pEList;
+ pSel->pEList = sqliteExprListDup(pEList);
+ if( pSel->pEList==0 ){
+ pSel->pEList = pEList;
+ return 1; /* Malloc failed */
+ }
+ pTable->nCol = -1;
+ pSelTab = sqliteResultSetOfSelect(pParse, 0, pSel);
+ if( pSelTab ){
+ assert( pTable->aCol==0 );
+ pTable->nCol = pSelTab->nCol;
+ pTable->aCol = pSelTab->aCol;
+ pSelTab->nCol = 0;
+ pSelTab->aCol = 0;
+ sqliteDeleteTable(0, pSelTab);
+ DbSetProperty(pParse->db, pTable->iDb, DB_UnresetViews);
+ }else{
+ pTable->nCol = 0;
+ nErr++;
+ }
+ sqliteSelectUnbind(pSel);
+ sqliteExprListDelete(pSel->pEList);
+ pSel->pEList = pEList;
+ return nErr;
+}
+
+/*
+** Clear the column names from the VIEW pTable.
+**
+** This routine is called whenever any other table or view is modified.
+** The view passed into this routine might depend directly or indirectly
+** on the modified or deleted table so we need to clear the old column
+** names so that they will be recomputed.
+*/
+static void sqliteViewResetColumnNames(Table *pTable){
+ int i;
+ Column *pCol;
+ assert( pTable!=0 && pTable->pSelect!=0 );
+ for(i=0, pCol=pTable->aCol; i<pTable->nCol; i++, pCol++){
+ sqliteFree(pCol->zName);
+ sqliteFree(pCol->zDflt);
+ sqliteFree(pCol->zType);
+ }
+ sqliteFree(pTable->aCol);
+ pTable->aCol = 0;
+ pTable->nCol = 0;
+}
+
+/*
+** Clear the column names from every VIEW in database idx.
+*/
+static void sqliteViewResetAll(sqlite *db, int idx){
+ HashElem *i;
+ if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
+ for(i=sqliteHashFirst(&db->aDb[idx].tblHash); i; i=sqliteHashNext(i)){
+ Table *pTab = sqliteHashData(i);
+ if( pTab->pSelect ){
+ sqliteViewResetColumnNames(pTab);
+ }
+ }
+ DbClearProperty(db, idx, DB_UnresetViews);
+}
+
+/*
+** Given a token, look up a table with that name. If not found, leave
+** an error for the parser to tqfind and return NULL.
+*/
+Table *sqliteTableFromToken(Parse *pParse, Token *pTok){
+ char *zName;
+ Table *pTab;
+ zName = sqliteTableNameFromToken(pTok);
+ if( zName==0 ) return 0;
+ pTab = sqliteFindTable(pParse->db, zName, 0);
+ sqliteFree(zName);
+ if( pTab==0 ){
+ sqliteErrorMsg(pParse, "no such table: %T", pTok);
+ }
+ return pTab;
+}
+
+/*
+** This routine is called to do the work of a DROP TABLE statement.
+** pName is the name of the table to be dropped.
+*/
+void sqliteDropTable(Parse *pParse, Token *pName, int isView){
+ Table *pTable;
+ Vdbe *v;
+ int base;
+ sqlite *db = pParse->db;
+ int iDb;
+
+ if( pParse->nErr || sqlite_malloc_failed ) return;
+ pTable = sqliteTableFromToken(pParse, pName);
+ if( pTable==0 ) return;
+ iDb = pTable->iDb;
+ assert( iDb>=0 && iDb<db->nDb );
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ {
+ int code;
+ const char *zTab = SCHEMA_TABLE(pTable->iDb);
+ const char *zDb = db->aDb[pTable->iDb].zName;
+ if( sqliteAuthCheck(pParse, STQLITE_DELETE, zTab, 0, zDb)){
+ return;
+ }
+ if( isView ){
+ if( iDb==1 ){
+ code = STQLITE_DROP_TEMP_VIEW;
+ }else{
+ code = STQLITE_DROP_VIEW;
+ }
+ }else{
+ if( iDb==1 ){
+ code = STQLITE_DROP_TEMP_TABLE;
+ }else{
+ code = STQLITE_DROP_TABLE;
+ }
+ }
+ if( sqliteAuthCheck(pParse, code, pTable->zName, 0, zDb) ){
+ return;
+ }
+ if( sqliteAuthCheck(pParse, STQLITE_DELETE, pTable->zName, 0, zDb) ){
+ return;
+ }
+ }
+#endif
+ if( pTable->readOnly ){
+ sqliteErrorMsg(pParse, "table %s may not be dropped", pTable->zName);
+ pParse->nErr++;
+ return;
+ }
+ if( isView && pTable->pSelect==0 ){
+ sqliteErrorMsg(pParse, "use DROP TABLE to delete table %s", pTable->zName);
+ return;
+ }
+ if( !isView && pTable->pSelect ){
+ sqliteErrorMsg(pParse, "use DROP VIEW to delete view %s", pTable->zName);
+ return;
+ }
+
+ /* Generate code to remove the table from the master table
+ ** on disk.
+ */
+ v = sqliteGetVdbe(pParse);
+ if( v ){
+ static VdbeOpList dropTable[] = {
+ { OP_Rewind, 0, ADDR(8), 0},
+ { OP_String, 0, 0, 0}, /* 1 */
+ { OP_MemStore, 1, 1, 0},
+ { OP_MemLoad, 1, 0, 0}, /* 3 */
+ { OP_Column, 0, 2, 0},
+ { OP_Ne, 0, ADDR(7), 0},
+ { OP_Delete, 0, 0, 0},
+ { OP_Next, 0, ADDR(3), 0}, /* 7 */
+ };
+ Index *pIdx;
+ Trigger *pTrigger;
+ sqliteBeginWriteOperation(pParse, 0, pTable->iDb);
+
+ /* Drop all triggers associated with the table being dropped */
+ pTrigger = pTable->pTrigger;
+ while( pTrigger ){
+ assert( pTrigger->iDb==pTable->iDb || pTrigger->iDb==1 );
+ sqliteDropTriggerPtr(pParse, pTrigger, 1);
+ if( pParse->explain ){
+ pTrigger = pTrigger->pNext;
+ }else{
+ pTrigger = pTable->pTrigger;
+ }
+ }
+
+ /* Drop all STQLITE_MASTER entries that refer to the table */
+ sqliteOpenMasterTable(v, pTable->iDb);
+ base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
+ sqliteVdbeChangeP3(v, base+1, pTable->zName, 0);
+
+ /* Drop all STQLITE_TEMP_MASTER entries that refer to the table */
+ if( pTable->iDb!=1 ){
+ sqliteOpenMasterTable(v, 1);
+ base = sqliteVdbeAddOpList(v, ArraySize(dropTable), dropTable);
+ sqliteVdbeChangeP3(v, base+1, pTable->zName, 0);
+ }
+
+ if( pTable->iDb==0 ){
+ sqliteChangeCookie(db, v);
+ }
+ sqliteVdbeAddOp(v, OP_Close, 0, 0);
+ if( !isView ){
+ sqliteVdbeAddOp(v, OP_Destroy, pTable->tnum, pTable->iDb);
+ for(pIdx=pTable->pIndex; pIdx; pIdx=pIdx->pNext){
+ sqliteVdbeAddOp(v, OP_Destroy, pIdx->tnum, pIdx->iDb);
+ }
+ }
+ sqliteEndWriteOperation(pParse);
+ }
+
+ /* Delete the in-memory description of the table.
+ **
+ ** Exception: if the SQL statement began with the EXPLAIN keyword,
+ ** then no changes should be made.
+ */
+ if( !pParse->explain ){
+ sqliteUnlinkAndDeleteTable(db, pTable);
+ db->flags |= STQLITE_InternChanges;
+ }
+ sqliteViewResetAll(db, iDb);
+}
+
+/*
+** This routine constructs a P3 string suitable for an OP_MakeIdxKey
+** opcode and adds that P3 string to the most recently inserted instruction
+** in the virtual machine. The P3 string consists of a single character
+** for each column in the index pIdx of table pTab. If the column uses
+** a numeric sort order, then the P3 string character corresponding to
+** that column is 'n'. If the column uses a text sort order, then the
+** P3 string is 't'. See the OP_MakeIdxKey opcode documentation for
+** additional information. See also the sqliteAddKeyType() routine.
+*/
+void sqliteAddIdxKeyType(Vdbe *v, Index *pIdx){
+ char *zType;
+ Table *pTab;
+ int i, n;
+ assert( pIdx!=0 && pIdx->pTable!=0 );
+ pTab = pIdx->pTable;
+ n = pIdx->nColumn;
+ zType = sqliteMallocRaw( n+1 );
+ if( zType==0 ) return;
+ for(i=0; i<n; i++){
+ int iCol = pIdx->aiColumn[i];
+ assert( iCol>=0 && iCol<pTab->nCol );
+ if( (pTab->aCol[iCol].sortOrder & STQLITE_SO_TYPEMASK)==STQLITE_SO_TEXT ){
+ zType[i] = 't';
+ }else{
+ zType[i] = 'n';
+ }
+ }
+ zType[n] = 0;
+ sqliteVdbeChangeP3(v, -1, zType, n);
+ sqliteFree(zType);
+}
+
+/*
+** This routine is called to create a new foreign key on the table
+** currently under construction. pFromCol determines which columns
+** in the current table point to the foreign key. If pFromCol==0 then
+** connect the key to the last column inserted. pTo is the name of
+** the table referred to. pToCol is a list of tables in the other
+** pTo table that the foreign key points to. flags tqcontains all
+** information about the conflict resolution algorithms specified
+** in the ON DELETE, ON UPDATE and ON INSERT clauses.
+**
+** An FKey structure is created and added to the table currently
+** under construction in the pParse->pNewTable field. The new FKey
+** is not linked into db->aFKey at this point - that does not happen
+** until sqliteEndTable().
+**
+** The foreign key is set for IMMEDIATE processing. A subsequent call
+** to sqliteDeferForeignKey() might change this to DEFERRED.
+*/
+void sqliteCreateForeignKey(
+ Parse *pParse, /* Parsing context */
+ IdList *pFromCol, /* Columns in this table that point to other table */
+ Token *pTo, /* Name of the other table */
+ IdList *pToCol, /* Columns in the other table */
+ int flags /* Conflict resolution algorithms. */
+){
+ Table *p = pParse->pNewTable;
+ int nByte;
+ int i;
+ int nCol;
+ char *z;
+ FKey *pFKey = 0;
+
+ assert( pTo!=0 );
+ if( p==0 || pParse->nErr ) goto fk_end;
+ if( pFromCol==0 ){
+ int iCol = p->nCol-1;
+ if( iCol<0 ) goto fk_end;
+ if( pToCol && pToCol->nId!=1 ){
+ sqliteErrorMsg(pParse, "foreign key on %s"
+ " should reference only one column of table %T",
+ p->aCol[iCol].zName, pTo);
+ goto fk_end;
+ }
+ nCol = 1;
+ }else if( pToCol && pToCol->nId!=pFromCol->nId ){
+ sqliteErrorMsg(pParse,
+ "number of columns in foreign key does not match the number of "
+ "columns in the referenced table");
+ goto fk_end;
+ }else{
+ nCol = pFromCol->nId;
+ }
+ nByte = sizeof(*pFKey) + nCol*sizeof(pFKey->aCol[0]) + pTo->n + 1;
+ if( pToCol ){
+ for(i=0; i<pToCol->nId; i++){
+ nByte += strlen(pToCol->a[i].zName) + 1;
+ }
+ }
+ pFKey = sqliteMalloc( nByte );
+ if( pFKey==0 ) goto fk_end;
+ pFKey->pFrom = p;
+ pFKey->pNextFrom = p->pFKey;
+ z = (char*)&pFKey[1];
+ pFKey->aCol = (struct sColMap*)z;
+ z += sizeof(struct sColMap)*nCol;
+ pFKey->zTo = z;
+ memcpy(z, pTo->z, pTo->n);
+ z[pTo->n] = 0;
+ z += pTo->n+1;
+ pFKey->pNextTo = 0;
+ pFKey->nCol = nCol;
+ if( pFromCol==0 ){
+ pFKey->aCol[0].iFrom = p->nCol-1;
+ }else{
+ for(i=0; i<nCol; i++){
+ int j;
+ for(j=0; j<p->nCol; j++){
+ if( sqliteStrICmp(p->aCol[j].zName, pFromCol->a[i].zName)==0 ){
+ pFKey->aCol[i].iFrom = j;
+ break;
+ }
+ }
+ if( j>=p->nCol ){
+ sqliteErrorMsg(pParse,
+ "unknown column \"%s\" in foreign key definition",
+ pFromCol->a[i].zName);
+ goto fk_end;
+ }
+ }
+ }
+ if( pToCol ){
+ for(i=0; i<nCol; i++){
+ int n = strlen(pToCol->a[i].zName);
+ pFKey->aCol[i].zCol = z;
+ memcpy(z, pToCol->a[i].zName, n);
+ z[n] = 0;
+ z += n+1;
+ }
+ }
+ pFKey->isDeferred = 0;
+ pFKey->deleteConf = flags & 0xff;
+ pFKey->updateConf = (flags >> 8 ) & 0xff;
+ pFKey->insertConf = (flags >> 16 ) & 0xff;
+
+ /* Link the foreign key to the table as the last step.
+ */
+ p->pFKey = pFKey;
+ pFKey = 0;
+
+fk_end:
+ sqliteFree(pFKey);
+ sqliteIdListDelete(pFromCol);
+ sqliteIdListDelete(pToCol);
+}
+
+/*
+** This routine is called when an INITIALLY IMMEDIATE or INITIALLY DEFERRED
+** clause is seen as part of a foreign key definition. The isDeferred
+** parameter is 1 for INITIALLY DEFERRED and 0 for INITIALLY IMMEDIATE.
+** The behavior of the most recently created foreign key is adjusted
+** accordingly.
+*/
+void sqliteDeferForeignKey(Parse *pParse, int isDeferred){
+ Table *pTab;
+ FKey *pFKey;
+ if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return;
+ pFKey->isDeferred = isDeferred;
+}
+
+/*
+** Create a new index for an SQL table. pIndex is the name of the index
+** and pTable is the name of the table that is to be indexed. Both will
+** be NULL for a primary key or an index that is created to satisfy a
+** UNITQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable
+** as the table to be indexed. pParse->pNewTable is a table that is
+** currently being constructed by a CREATE TABLE statement.
+**
+** pList is a list of columns to be indexed. pList will be NULL if this
+** is a primary key or unique-constraint on the most recent column added
+** to the table currently under construction.
+*/
+void sqliteCreateIndex(
+ Parse *pParse, /* All information about this parse */
+ Token *pName, /* Name of the index. May be NULL */
+ SrcList *pTable, /* Name of the table to index. Use pParse->pNewTable if 0 */
+ IdList *pList, /* A list of columns to be indexed */
+ int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
+ Token *pStart, /* The CREATE token that begins a CREATE TABLE statement */
+ Token *pEnd /* The ")" that closes the CREATE INDEX statement */
+){
+ Table *pTab; /* Table to be indexed */
+ Index *pIndex; /* The index to be created */
+ char *zName = 0;
+ int i, j;
+ Token nullId; /* Fake token for an empty ID list */
+ DbFixer sFix; /* For assigning database names to pTable */
+ int isTemp; /* True for a temporary index */
+ sqlite *db = pParse->db;
+
+ if( pParse->nErr || sqlite_malloc_failed ) goto exit_create_index;
+ if( db->init.busy
+ && sqliteFixInit(&sFix, pParse, db->init.iDb, "index", pName)
+ && sqliteFixSrcList(&sFix, pTable)
+ ){
+ goto exit_create_index;
+ }
+
+ /*
+ ** Find the table that is to be indexed. Return early if not found.
+ */
+ if( pTable!=0 ){
+ assert( pName!=0 );
+ assert( pTable->nSrc==1 );
+ pTab = sqliteSrcListLookup(pParse, pTable);
+ }else{
+ assert( pName==0 );
+ pTab = pParse->pNewTable;
+ }
+ if( pTab==0 || pParse->nErr ) goto exit_create_index;
+ if( pTab->readOnly ){
+ sqliteErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
+ goto exit_create_index;
+ }
+ if( pTab->iDb>=2 && db->init.busy==0 ){
+ sqliteErrorMsg(pParse, "table %s may not have indices added", pTab->zName);
+ goto exit_create_index;
+ }
+ if( pTab->pSelect ){
+ sqliteErrorMsg(pParse, "views may not be indexed");
+ goto exit_create_index;
+ }
+ isTemp = pTab->iDb==1;
+
+ /*
+ ** Find the name of the index. Make sure there is not already another
+ ** index or table with the same name.
+ **
+ ** Exception: If we are reading the names of permanent indices from the
+ ** sqlite_master table (because some other process changed the schema) and
+ ** one of the index names collides with the name of a temporary table or
+ ** index, then we will continue to process this index.
+ **
+ ** If pName==0 it means that we are
+ ** dealing with a primary key or UNITQUE constraint. We have to invent our
+ ** own name.
+ */
+ if( pName && !db->init.busy ){
+ Index *pISameName; /* Another index with the same name */
+ Table *pTSameName; /* A table with same name as the index */
+ zName = sqliteStrNDup(pName->z, pName->n);
+ if( zName==0 ) goto exit_create_index;
+ if( (pISameName = sqliteFindIndex(db, zName, 0))!=0 ){
+ sqliteErrorMsg(pParse, "index %s already exists", zName);
+ goto exit_create_index;
+ }
+ if( (pTSameName = sqliteFindTable(db, zName, 0))!=0 ){
+ sqliteErrorMsg(pParse, "there is already a table named %s", zName);
+ goto exit_create_index;
+ }
+ }else if( pName==0 ){
+ char zBuf[30];
+ int n;
+ Index *pLoop;
+ for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
+ sprintf(zBuf,"%d)",n);
+ zName = 0;
+ sqliteSetString(&zName, "(", pTab->zName, " autoindex ", zBuf, (char*)0);
+ if( zName==0 ) goto exit_create_index;
+ }else{
+ zName = sqliteStrNDup(pName->z, pName->n);
+ }
+
+ /* Check for authorization to create an index.
+ */
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ {
+ const char *zDb = db->aDb[pTab->iDb].zName;
+
+ assert( pTab->iDb==db->init.iDb || isTemp );
+ if( sqliteAuthCheck(pParse, STQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){
+ goto exit_create_index;
+ }
+ i = STQLITE_CREATE_INDEX;
+ if( isTemp ) i = STQLITE_CREATE_TEMP_INDEX;
+ if( sqliteAuthCheck(pParse, i, zName, pTab->zName, zDb) ){
+ goto exit_create_index;
+ }
+ }
+#endif
+
+ /* If pList==0, it means this routine was called to make a primary
+ ** key out of the last column added to the table under construction.
+ ** So create a fake list to simulate this.
+ */
+ if( pList==0 ){
+ nullId.z = pTab->aCol[pTab->nCol-1].zName;
+ nullId.n = strlen(nullId.z);
+ pList = sqliteIdListAppend(0, &nullId);
+ if( pList==0 ) goto exit_create_index;
+ }
+
+ /*
+ ** Allocate the index structure.
+ */
+ pIndex = sqliteMalloc( sizeof(Index) + strlen(zName) + 1 +
+ sizeof(int)*pList->nId );
+ if( pIndex==0 ) goto exit_create_index;
+ pIndex->aiColumn = (int*)&pIndex[1];
+ pIndex->zName = (char*)&pIndex->aiColumn[pList->nId];
+ strcpy(pIndex->zName, zName);
+ pIndex->pTable = pTab;
+ pIndex->nColumn = pList->nId;
+ pIndex->onError = onError;
+ pIndex->autoIndex = pName==0;
+ pIndex->iDb = isTemp ? 1 : db->init.iDb;
+
+ /* Scan the names of the columns of the table to be indexed and
+ ** load the column indices into the Index structure. Report an error
+ ** if any column is not found.
+ */
+ for(i=0; i<pList->nId; i++){
+ for(j=0; j<pTab->nCol; j++){
+ if( sqliteStrICmp(pList->a[i].zName, pTab->aCol[j].zName)==0 ) break;
+ }
+ if( j>=pTab->nCol ){
+ sqliteErrorMsg(pParse, "table %s has no column named %s",
+ pTab->zName, pList->a[i].zName);
+ sqliteFree(pIndex);
+ goto exit_create_index;
+ }
+ pIndex->aiColumn[i] = j;
+ }
+
+ /* Link the new Index structure to its table and to the other
+ ** in-memory database structures.
+ */
+ if( !pParse->explain ){
+ Index *p;
+ p = sqliteHashInsert(&db->aDb[pIndex->iDb].idxHash,
+ pIndex->zName, strlen(pIndex->zName)+1, pIndex);
+ if( p ){
+ assert( p==pIndex ); /* Malloc must have failed */
+ sqliteFree(pIndex);
+ goto exit_create_index;
+ }
+ db->flags |= STQLITE_InternChanges;
+ }
+
+ /* When adding an index to the list of indices for a table, make
+ ** sure all indices labeled OE_Replace come after all those labeled
+ ** OE_Ignore. This is necessary for the correct operation of UPDATE
+ ** and INSERT.
+ */
+ if( onError!=OE_Replace || pTab->pIndex==0
+ || pTab->pIndex->onError==OE_Replace){
+ pIndex->pNext = pTab->pIndex;
+ pTab->pIndex = pIndex;
+ }else{
+ Index *pOther = pTab->pIndex;
+ while( pOther->pNext && pOther->pNext->onError!=OE_Replace ){
+ pOther = pOther->pNext;
+ }
+ pIndex->pNext = pOther->pNext;
+ pOther->pNext = pIndex;
+ }
+
+ /* If the db->init.busy is 1 it means we are reading the SQL off the
+ ** "sqlite_master" table on the disk. So do not write to the disk
+ ** again. Extract the table number from the db->init.newTnum field.
+ */
+ if( db->init.busy && pTable!=0 ){
+ pIndex->tnum = db->init.newTnum;
+ }
+
+ /* If the db->init.busy is 0 then create the index on disk. This
+ ** involves writing the index into the master table and filling in the
+ ** index with the current table contents.
+ **
+ ** The db->init.busy is 0 when the user first enters a CREATE INDEX
+ ** command. db->init.busy is 1 when a database is opened and
+ ** CREATE INDEX statements are read out of the master table. In
+ ** the latter case the index already exists on disk, which is why
+ ** we don't want to recreate it.
+ **
+ ** If pTable==0 it means this index is generated as a primary key
+ ** or UNITQUE constraint of a CREATE TABLE statement. Since the table
+ ** has just been created, it tqcontains no data and the index initialization
+ ** step can be skipped.
+ */
+ else if( db->init.busy==0 ){
+ int n;
+ Vdbe *v;
+ int lbl1, lbl2;
+ int i;
+ int addr;
+
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ) goto exit_create_index;
+ if( pTable!=0 ){
+ sqliteBeginWriteOperation(pParse, 0, isTemp);
+ sqliteOpenMasterTable(v, isTemp);
+ }
+ sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0, "index", P3_STATIC);
+ sqliteVdbeOp3(v, OP_String, 0, 0, pIndex->zName, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0, pTab->zName, 0);
+ sqliteVdbeOp3(v, OP_CreateIndex, 0, isTemp,(char*)&pIndex->tnum,P3_POINTER);
+ pIndex->tnum = 0;
+ if( pTable ){
+ sqliteVdbeCode(v,
+ OP_Dup, 0, 0,
+ OP_Integer, isTemp, 0,
+ OP_OpenWrite, 1, 0,
+ 0);
+ }
+ addr = sqliteVdbeAddOp(v, OP_String, 0, 0);
+ if( pStart && pEnd ){
+ n = Addr(pEnd->z) - Addr(pStart->z) + 1;
+ sqliteVdbeChangeP3(v, addr, pStart->z, n);
+ }
+ sqliteVdbeAddOp(v, OP_MakeRecord, 5, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, 0, 0);
+ if( pTable ){
+ sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqliteVdbeOp3(v, OP_OpenRead, 2, pTab->tnum, pTab->zName, 0);
+ lbl2 = sqliteVdbeMakeLabel(v);
+ sqliteVdbeAddOp(v, OP_Rewind, 2, lbl2);
+ lbl1 = sqliteVdbeAddOp(v, OP_Recno, 2, 0);
+ for(i=0; i<pIndex->nColumn; i++){
+ int iCol = pIndex->aiColumn[i];
+ if( pTab->iPKey==iCol ){
+ sqliteVdbeAddOp(v, OP_Dup, i, 0);
+ }else{
+ sqliteVdbeAddOp(v, OP_Column, 2, iCol);
+ }
+ }
+ sqliteVdbeAddOp(v, OP_MakeIdxKey, pIndex->nColumn, 0);
+ if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIndex);
+ sqliteVdbeOp3(v, OP_IdxPut, 1, pIndex->onError!=OE_None,
+ "indexed columns are not unique", P3_STATIC);
+ sqliteVdbeAddOp(v, OP_Next, 2, lbl1);
+ sqliteVdbeResolveLabel(v, lbl2);
+ sqliteVdbeAddOp(v, OP_Close, 2, 0);
+ sqliteVdbeAddOp(v, OP_Close, 1, 0);
+ }
+ if( pTable!=0 ){
+ if( !isTemp ){
+ sqliteChangeCookie(db, v);
+ }
+ sqliteVdbeAddOp(v, OP_Close, 0, 0);
+ sqliteEndWriteOperation(pParse);
+ }
+ }
+
+ /* Clean up before exiting */
+exit_create_index:
+ sqliteIdListDelete(pList);
+ sqliteSrcListDelete(pTable);
+ sqliteFree(zName);
+ return;
+}
+
+/*
+** This routine will drop an existing named index. This routine
+** implements the DROP INDEX statement.
+*/
+void sqliteDropIndex(Parse *pParse, SrcList *pName){
+ Index *pIndex;
+ Vdbe *v;
+ sqlite *db = pParse->db;
+
+ if( pParse->nErr || sqlite_malloc_failed ) return;
+ assert( pName->nSrc==1 );
+ pIndex = sqliteFindIndex(db, pName->a[0].zName, pName->a[0].zDatabase);
+ if( pIndex==0 ){
+ sqliteErrorMsg(pParse, "no such index: %S", pName, 0);
+ goto exit_drop_index;
+ }
+ if( pIndex->autoIndex ){
+ sqliteErrorMsg(pParse, "index associated with UNITQUE "
+ "or PRIMARY KEY constraint cannot be dropped", 0);
+ goto exit_drop_index;
+ }
+ if( pIndex->iDb>1 ){
+ sqliteErrorMsg(pParse, "cannot alter schema of attached "
+ "databases", 0);
+ goto exit_drop_index;
+ }
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ {
+ int code = STQLITE_DROP_INDEX;
+ Table *pTab = pIndex->pTable;
+ const char *zDb = db->aDb[pIndex->iDb].zName;
+ const char *zTab = SCHEMA_TABLE(pIndex->iDb);
+ if( sqliteAuthCheck(pParse, STQLITE_DELETE, zTab, 0, zDb) ){
+ goto exit_drop_index;
+ }
+ if( pIndex->iDb ) code = STQLITE_DROP_TEMP_INDEX;
+ if( sqliteAuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){
+ goto exit_drop_index;
+ }
+ }
+#endif
+
+ /* Generate code to remove the index and from the master table */
+ v = sqliteGetVdbe(pParse);
+ if( v ){
+ static VdbeOpList dropIndex[] = {
+ { OP_Rewind, 0, ADDR(9), 0},
+ { OP_String, 0, 0, 0}, /* 1 */
+ { OP_MemStore, 1, 1, 0},
+ { OP_MemLoad, 1, 0, 0}, /* 3 */
+ { OP_Column, 0, 1, 0},
+ { OP_Eq, 0, ADDR(8), 0},
+ { OP_Next, 0, ADDR(3), 0},
+ { OP_Goto, 0, ADDR(9), 0},
+ { OP_Delete, 0, 0, 0}, /* 8 */
+ };
+ int base;
+
+ sqliteBeginWriteOperation(pParse, 0, pIndex->iDb);
+ sqliteOpenMasterTable(v, pIndex->iDb);
+ base = sqliteVdbeAddOpList(v, ArraySize(dropIndex), dropIndex);
+ sqliteVdbeChangeP3(v, base+1, pIndex->zName, 0);
+ if( pIndex->iDb==0 ){
+ sqliteChangeCookie(db, v);
+ }
+ sqliteVdbeAddOp(v, OP_Close, 0, 0);
+ sqliteVdbeAddOp(v, OP_Destroy, pIndex->tnum, pIndex->iDb);
+ sqliteEndWriteOperation(pParse);
+ }
+
+ /* Delete the in-memory description of this index.
+ */
+ if( !pParse->explain ){
+ sqliteUnlinkAndDeleteIndex(db, pIndex);
+ db->flags |= STQLITE_InternChanges;
+ }
+
+exit_drop_index:
+ sqliteSrcListDelete(pName);
+}
+
+/*
+** Append a new element to the given IdList. Create a new IdList if
+** need be.
+**
+** A new IdList is returned, or NULL if malloc() fails.
+*/
+IdList *sqliteIdListAppend(IdList *pList, Token *pToken){
+ if( pList==0 ){
+ pList = sqliteMalloc( sizeof(IdList) );
+ if( pList==0 ) return 0;
+ pList->nAlloc = 0;
+ }
+ if( pList->nId>=pList->nAlloc ){
+ struct IdList_item *a;
+ pList->nAlloc = pList->nAlloc*2 + 5;
+ a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]) );
+ if( a==0 ){
+ sqliteIdListDelete(pList);
+ return 0;
+ }
+ pList->a = a;
+ }
+ memset(&pList->a[pList->nId], 0, sizeof(pList->a[0]));
+ if( pToken ){
+ char **pz = &pList->a[pList->nId].zName;
+ sqliteSetNString(pz, pToken->z, pToken->n, 0);
+ if( *pz==0 ){
+ sqliteIdListDelete(pList);
+ return 0;
+ }else{
+ sqliteDequote(*pz);
+ }
+ }
+ pList->nId++;
+ return pList;
+}
+
+/*
+** Append a new table name to the given SrcList. Create a new SrcList if
+** need be. A new entry is created in the SrcList even if pToken is NULL.
+**
+** A new SrcList is returned, or NULL if malloc() fails.
+**
+** If pDatabase is not null, it means that the table has an optional
+** database name prefix. Like this: "database.table". The pDatabase
+** points to the table name and the pTable points to the database name.
+** The SrcList.a[].zName field is filled with the table name which might
+** come from pTable (if pDatabase is NULL) or from pDatabase.
+** SrcList.a[].zDatabase is filled with the database name from pTable,
+** or with NULL if no database is specified.
+**
+** In other words, if call like this:
+**
+** sqliteSrcListAppend(A,B,0);
+**
+** Then B is a table name and the database name is unspecified. If called
+** like this:
+**
+** sqliteSrcListAppend(A,B,C);
+**
+** Then C is the table name and B is the database name.
+*/
+SrcList *sqliteSrcListAppend(SrcList *pList, Token *pTable, Token *pDatabase){
+ if( pList==0 ){
+ pList = sqliteMalloc( sizeof(SrcList) );
+ if( pList==0 ) return 0;
+ pList->nAlloc = 1;
+ }
+ if( pList->nSrc>=pList->nAlloc ){
+ SrcList *pNew;
+ pList->nAlloc *= 2;
+ pNew = sqliteRealloc(pList,
+ sizeof(*pList) + (pList->nAlloc-1)*sizeof(pList->a[0]) );
+ if( pNew==0 ){
+ sqliteSrcListDelete(pList);
+ return 0;
+ }
+ pList = pNew;
+ }
+ memset(&pList->a[pList->nSrc], 0, sizeof(pList->a[0]));
+ if( pDatabase && pDatabase->z==0 ){
+ pDatabase = 0;
+ }
+ if( pDatabase && pTable ){
+ Token *pTemp = pDatabase;
+ pDatabase = pTable;
+ pTable = pTemp;
+ }
+ if( pTable ){
+ char **pz = &pList->a[pList->nSrc].zName;
+ sqliteSetNString(pz, pTable->z, pTable->n, 0);
+ if( *pz==0 ){
+ sqliteSrcListDelete(pList);
+ return 0;
+ }else{
+ sqliteDequote(*pz);
+ }
+ }
+ if( pDatabase ){
+ char **pz = &pList->a[pList->nSrc].zDatabase;
+ sqliteSetNString(pz, pDatabase->z, pDatabase->n, 0);
+ if( *pz==0 ){
+ sqliteSrcListDelete(pList);
+ return 0;
+ }else{
+ sqliteDequote(*pz);
+ }
+ }
+ pList->a[pList->nSrc].iCursor = -1;
+ pList->nSrc++;
+ return pList;
+}
+
+/*
+** Assign cursors to all tables in a SrcList
+*/
+void sqliteSrcListAssignCursors(Parse *pParse, SrcList *pList){
+ int i;
+ for(i=0; i<pList->nSrc; i++){
+ if( pList->a[i].iCursor<0 ){
+ pList->a[i].iCursor = pParse->nTab++;
+ }
+ }
+}
+
+/*
+** Add an alias to the last identifier on the given identifier list.
+*/
+void sqliteSrcListAddAlias(SrcList *pList, Token *pToken){
+ if( pList && pList->nSrc>0 ){
+ int i = pList->nSrc - 1;
+ sqliteSetNString(&pList->a[i].zAlias, pToken->z, pToken->n, 0);
+ sqliteDequote(pList->a[i].zAlias);
+ }
+}
+
+/*
+** Delete an IdList.
+*/
+void sqliteIdListDelete(IdList *pList){
+ int i;
+ if( pList==0 ) return;
+ for(i=0; i<pList->nId; i++){
+ sqliteFree(pList->a[i].zName);
+ }
+ sqliteFree(pList->a);
+ sqliteFree(pList);
+}
+
+/*
+** Return the index in pList of the identifier named zId. Return -1
+** if not found.
+*/
+int sqliteIdListIndex(IdList *pList, const char *zName){
+ int i;
+ if( pList==0 ) return -1;
+ for(i=0; i<pList->nId; i++){
+ if( sqliteStrICmp(pList->a[i].zName, zName)==0 ) return i;
+ }
+ return -1;
+}
+
+/*
+** Delete an entire SrcList including all its substructure.
+*/
+void sqliteSrcListDelete(SrcList *pList){
+ int i;
+ if( pList==0 ) return;
+ for(i=0; i<pList->nSrc; i++){
+ sqliteFree(pList->a[i].zDatabase);
+ sqliteFree(pList->a[i].zName);
+ sqliteFree(pList->a[i].zAlias);
+ if( pList->a[i].pTab && pList->a[i].pTab->isTransient ){
+ sqliteDeleteTable(0, pList->a[i].pTab);
+ }
+ sqliteSelectDelete(pList->a[i].pSelect);
+ sqliteExprDelete(pList->a[i].pOn);
+ sqliteIdListDelete(pList->a[i].pUsing);
+ }
+ sqliteFree(pList);
+}
+
+/*
+** Begin a transaction
+*/
+void sqliteBeginTransaction(Parse *pParse, int onError){
+ sqlite *db;
+
+ if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
+ if( pParse->nErr || sqlite_malloc_failed ) return;
+ if( sqliteAuthCheck(pParse, STQLITE_TRANSACTION, "BEGIN", 0, 0) ) return;
+ if( db->flags & STQLITE_InTrans ){
+ sqliteErrorMsg(pParse, "cannot start a transaction within a transaction");
+ return;
+ }
+ sqliteBeginWriteOperation(pParse, 0, 0);
+ if( !pParse->explain ){
+ db->flags |= STQLITE_InTrans;
+ db->onError = onError;
+ }
+}
+
+/*
+** Commit a transaction
+*/
+void sqliteCommitTransaction(Parse *pParse){
+ sqlite *db;
+
+ if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
+ if( pParse->nErr || sqlite_malloc_failed ) return;
+ if( sqliteAuthCheck(pParse, STQLITE_TRANSACTION, "COMMIT", 0, 0) ) return;
+ if( (db->flags & STQLITE_InTrans)==0 ){
+ sqliteErrorMsg(pParse, "cannot commit - no transaction is active");
+ return;
+ }
+ if( !pParse->explain ){
+ db->flags &= ~STQLITE_InTrans;
+ }
+ sqliteEndWriteOperation(pParse);
+ if( !pParse->explain ){
+ db->onError = OE_Default;
+ }
+}
+
+/*
+** Rollback a transaction
+*/
+void sqliteRollbackTransaction(Parse *pParse){
+ sqlite *db;
+ Vdbe *v;
+
+ if( pParse==0 || (db=pParse->db)==0 || db->aDb[0].pBt==0 ) return;
+ if( pParse->nErr || sqlite_malloc_failed ) return;
+ if( sqliteAuthCheck(pParse, STQLITE_TRANSACTION, "ROLLBACK", 0, 0) ) return;
+ if( (db->flags & STQLITE_InTrans)==0 ){
+ sqliteErrorMsg(pParse, "cannot rollback - no transaction is active");
+ return;
+ }
+ v = sqliteGetVdbe(pParse);
+ if( v ){
+ sqliteVdbeAddOp(v, OP_Rollback, 0, 0);
+ }
+ if( !pParse->explain ){
+ db->flags &= ~STQLITE_InTrans;
+ db->onError = OE_Default;
+ }
+}
+
+/*
+** Generate VDBE code that will verify the schema cookie for all
+** named database files.
+*/
+void sqliteCodeVerifySchema(Parse *pParse, int iDb){
+ sqlite *db = pParse->db;
+ Vdbe *v = sqliteGetVdbe(pParse);
+ assert( iDb>=0 && iDb<db->nDb );
+ assert( db->aDb[iDb].pBt!=0 );
+ if( iDb!=1 && !DbHasProperty(db, iDb, DB_Cookie) ){
+ sqliteVdbeAddOp(v, OP_VerifyCookie, iDb, db->aDb[iDb].schema_cookie);
+ DbSetProperty(db, iDb, DB_Cookie);
+ }
+}
+
+/*
+** Generate VDBE code that prepares for doing an operation that
+** might change the database.
+**
+** This routine starts a new transaction if we are not already within
+** a transaction. If we are already within a transaction, then a checkpoint
+** is set if the setCheckpoint parameter is true. A checkpoint should
+** be set for operations that might fail (due to a constraint) part of
+** the way through and which will need to undo some writes without having to
+** rollback the whole transaction. For operations where all constraints
+** can be checked before any changes are made to the database, it is never
+** necessary to undo a write and the checkpoint should not be set.
+**
+** Only database iDb and the temp database are made writable by this call.
+** If iDb==0, then the main and temp databases are made writable. If
+** iDb==1 then only the temp database is made writable. If iDb>1 then the
+** specified auxiliary database and the temp database are made writable.
+*/
+void sqliteBeginWriteOperation(Parse *pParse, int setCheckpoint, int iDb){
+ Vdbe *v;
+ sqlite *db = pParse->db;
+ if( DbHasProperty(db, iDb, DB_Locked) ) return;
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ) return;
+ if( !db->aDb[iDb].inTrans ){
+ sqliteVdbeAddOp(v, OP_Transaction, iDb, 0);
+ DbSetProperty(db, iDb, DB_Locked);
+ sqliteCodeVerifySchema(pParse, iDb);
+ if( iDb!=1 ){
+ sqliteBeginWriteOperation(pParse, setCheckpoint, 1);
+ }
+ }else if( setCheckpoint ){
+ sqliteVdbeAddOp(v, OP_Checkpoint, iDb, 0);
+ DbSetProperty(db, iDb, DB_Locked);
+ }
+}
+
+/*
+** Generate code that concludes an operation that may have changed
+** the database. If a statement transaction was started, then emit
+** an OP_Commit that will cause the changes to be committed to disk.
+**
+** Note that checkpoints are automatically committed at the end of
+** a statement. Note also that there can be multiple calls to
+** sqliteBeginWriteOperation() but there should only be a single
+** call to sqliteEndWriteOperation() at the conclusion of the statement.
+*/
+void sqliteEndWriteOperation(Parse *pParse){
+ Vdbe *v;
+ sqlite *db = pParse->db;
+ if( pParse->trigStack ) return; /* if this is in a trigger */
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ) return;
+ if( db->flags & STQLITE_InTrans ){
+ /* A BEGIN has executed. Do not commit until we see an explicit
+ ** COMMIT statement. */
+ }else{
+ sqliteVdbeAddOp(v, OP_Commit, 0, 0);
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/config.h b/tqtinterface/qt4/src/3rdparty/sqlite/config.h
new file mode 100644
index 0000000..0cf0524
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/config.h
@@ -0,0 +1,23 @@
+#include <tqglobal.h>
+#include <tqconfig.h>
+
+#ifndef TQT_POINTER_SIZE
+# ifdef TQ_OS_WIN32
+# define TQT_POINTER_SIZE 4
+# elif TQ_OS_WIN64
+# define TQT_POINTER_SIZE 8
+# else
+# error This platform is unsupported
+# endif
+#endif /* TQT_POINTER_SIZE */
+
+#define STQLITE_PTR_SZ TQT_POINTER_SIZE
+
+#ifdef UNICODE
+# undef UNICODE
+#endif
+
+#ifdef TQ_CC_MSVC
+# pragma warning(disable: 4018)
+# pragma warning(disable: 4761)
+#endif
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/copy.c b/tqtinterface/qt4/src/3rdparty/sqlite/copy.c
new file mode 100644
index 0000000..6ce324c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/copy.c
@@ -0,0 +1,110 @@
+/*
+** 2003 April 6
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains code used to implement the COPY command.
+**
+** $Id: copy.c,v 1.9 2004/02/25 13:47:31 drh Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** The COPY command is for compatibility with PostgreSQL and specificially
+** for the ability to read the output of pg_dump. The format is as
+** follows:
+**
+** COPY table FROM file [USING DELIMITERS string]
+**
+** "table" is an existing table name. We will read lines of code from
+** file to fill this table with data. File might be "stdin". The optional
+** delimiter string identifies the field separators. The default is a tab.
+*/
+void sqliteCopy(
+ Parse *pParse, /* The parser context */
+ SrcList *pTableName, /* The name of the table into which we will insert */
+ Token *pFilename, /* The file from which to obtain information */
+ Token *pDelimiter, /* Use this as the field delimiter */
+ int onError /* What to do if a constraint fails */
+){
+ Table *pTab;
+ int i;
+ Vdbe *v;
+ int addr, end;
+ char *zFile = 0;
+ const char *zDb;
+ sqlite *db = pParse->db;
+
+
+ if( sqlite_malloc_failed ) goto copy_cleanup;
+ assert( pTableName->nSrc==1 );
+ pTab = sqliteSrcListLookup(pParse, pTableName);
+ if( pTab==0 || sqliteIsReadOnly(pParse, pTab, 0) ) goto copy_cleanup;
+ zFile = sqliteStrNDup(pFilename->z, pFilename->n);
+ sqliteDequote(zFile);
+ assert( pTab->iDb<db->nDb );
+ zDb = db->aDb[pTab->iDb].zName;
+ if( sqliteAuthCheck(pParse, STQLITE_INSERT, pTab->zName, 0, zDb)
+ || sqliteAuthCheck(pParse, STQLITE_COPY, pTab->zName, zFile, zDb) ){
+ goto copy_cleanup;
+ }
+ v = sqliteGetVdbe(pParse);
+ if( v ){
+ sqliteBeginWriteOperation(pParse, 1, pTab->iDb);
+ addr = sqliteVdbeOp3(v, OP_FileOpen, 0, 0, pFilename->z, pFilename->n);
+ sqliteVdbeDequoteP3(v, addr);
+ sqliteOpenTableAndIndices(pParse, pTab, 0);
+ if( db->flags & STQLITE_CountRows ){
+ sqliteVdbeAddOp(v, OP_Integer, 0, 0); /* Initialize the row count */
+ }
+ end = sqliteVdbeMakeLabel(v);
+ addr = sqliteVdbeAddOp(v, OP_FileRead, pTab->nCol, end);
+ if( pDelimiter ){
+ sqliteVdbeChangeP3(v, addr, pDelimiter->z, pDelimiter->n);
+ sqliteVdbeDequoteP3(v, addr);
+ }else{
+ sqliteVdbeChangeP3(v, addr, "\t", 1);
+ }
+ if( pTab->iPKey>=0 ){
+ sqliteVdbeAddOp(v, OP_FileColumn, pTab->iPKey, 0);
+ sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
+ }else{
+ sqliteVdbeAddOp(v, OP_NewRecno, 0, 0);
+ }
+ for(i=0; i<pTab->nCol; i++){
+ if( i==pTab->iPKey ){
+ /* The integer primary key column is filled with NULL since its
+ ** value is always pulled from the record number */
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ }else{
+ sqliteVdbeAddOp(v, OP_FileColumn, i, 0);
+ }
+ }
+ sqliteGenerateConstraintChecks(pParse, pTab, 0, 0, pTab->iPKey>=0,
+ 0, onError, addr);
+ sqliteCompleteInsertion(pParse, pTab, 0, 0, 0, 0, -1);
+ if( (db->flags & STQLITE_CountRows)!=0 ){
+ sqliteVdbeAddOp(v, OP_AddImm, 1, 0); /* Increment row count */
+ }
+ sqliteVdbeAddOp(v, OP_Goto, 0, addr);
+ sqliteVdbeResolveLabel(v, end);
+ sqliteVdbeAddOp(v, OP_Noop, 0, 0);
+ sqliteEndWriteOperation(pParse);
+ if( db->flags & STQLITE_CountRows ){
+ sqliteVdbeAddOp(v, OP_ColumnName, 0, 1);
+ sqliteVdbeChangeP3(v, -1, "rows inserted", P3_STATIC);
+ sqliteVdbeAddOp(v, OP_Callback, 1, 0);
+ }
+ }
+
+copy_cleanup:
+ sqliteSrcListDelete(pTableName);
+ sqliteFree(zFile);
+ return;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/date.c b/tqtinterface/qt4/src/3rdparty/sqlite/date.c
new file mode 100644
index 0000000..cbc825e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/date.c
@@ -0,0 +1,873 @@
+/*
+** 2003 October 31
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains the C functions that implement date and time
+** functions for STQLite.
+**
+** There is only one exported symbol in this file - the function
+** sqliteRegisterDateTimeFunctions() found at the bottom of the file.
+** All other code has file scope.
+**
+** $Id: date.c,v 1.16 2004/02/29 01:08:18 drh Exp $
+**
+** NOTES:
+**
+** STQLite processes all times and dates as Julian Day numbers. The
+** dates and times are stored as the number of days since noon
+** in Greenwich on November 24, 4714 B.C. according to the Gregorian
+** calendar system.
+**
+** 1970-01-01 00:00:00 is JD 2440587.5
+** 2000-01-01 00:00:00 is JD 2451544.5
+**
+** This implemention requires years to be expressed as a 4-digit number
+** which means that only dates between 0000-01-01 and 9999-12-31 can
+** be represented, even though julian day numbers allow a much wider
+** range of dates.
+**
+** The Gregorian calendar system is used for all dates and times,
+** even those that predate the Gregorian calendar. Historians usually
+** use the Julian calendar for dates prior to 1582-10-15 and for some
+** dates afterwards, depending on locale. Beware of this difference.
+**
+** The conversion algorithms are implemented based on descriptions
+** in the following text:
+**
+** Jean Meeus
+** Astronomical Algorithms, 2nd Edition, 1998
+** ISBM 0-943396-61-1
+** Willmann-Bell, Inc
+** Richmond, Virginia (USA)
+*/
+#include "os.h"
+#include "sqliteInt.h"
+#include <ctype.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <time.h>
+
+#ifndef STQLITE_OMIT_DATETIME_FUNCS
+
+/*
+** A structure for holding a single date and time.
+*/
+typedef struct DateTime DateTime;
+struct DateTime {
+ double rJD; /* The julian day number */
+ int Y, M, D; /* Year, month, and day */
+ int h, m; /* Hour and minutes */
+ int tz; /* Timezone offset in minutes */
+ double s; /* Seconds */
+ char validYMD; /* True if Y,M,D are valid */
+ char validHMS; /* True if h,m,s are valid */
+ char validJD; /* True if rJD is valid */
+ char validTZ; /* True if tz is valid */
+};
+
+
+/*
+** Convert zDate into one or more integers. Additional arguments
+** come in groups of 5 as follows:
+**
+** N number of digits in the integer
+** min minimum allowed value of the integer
+** max maximum allowed value of the integer
+** nextC first character after the integer
+** pVal where to write the integers value.
+**
+** Conversions continue until one with nextC==0 is encountered.
+** The function returns the number of successful conversions.
+*/
+static int getDigits(const char *zDate, ...){
+ va_list ap;
+ int val;
+ int N;
+ int min;
+ int max;
+ int nextC;
+ int *pVal;
+ int cnt = 0;
+ va_start(ap, zDate);
+ do{
+ N = va_arg(ap, int);
+ min = va_arg(ap, int);
+ max = va_arg(ap, int);
+ nextC = va_arg(ap, int);
+ pVal = va_arg(ap, int*);
+ val = 0;
+ while( N-- ){
+ if( !isdigit(*zDate) ){
+ return cnt;
+ }
+ val = val*10 + *zDate - '0';
+ zDate++;
+ }
+ if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
+ return cnt;
+ }
+ *pVal = val;
+ zDate++;
+ cnt++;
+ }while( nextC );
+ return cnt;
+}
+
+/*
+** Read text from z[] and convert into a floating point number. Return
+** the number of digits converted.
+*/
+static int getValue(const char *z, double *pR){
+ const char *zEnd;
+ *pR = sqliteAtoF(z, &zEnd);
+ return zEnd - z;
+}
+
+/*
+** Parse a timezone extension on the end of a date-time.
+** The extension is of the form:
+**
+** (+/-)HH:MM
+**
+** If the parse is successful, write the number of minutes
+** of change in *pnMin and return 0. If a parser error occurs,
+** return 0.
+**
+** A missing specifier is not considered an error.
+*/
+static int parseTimezone(const char *zDate, DateTime *p){
+ int sgn = 0;
+ int nHr, nMn;
+ while( isspace(*zDate) ){ zDate++; }
+ p->tz = 0;
+ if( *zDate=='-' ){
+ sgn = -1;
+ }else if( *zDate=='+' ){
+ sgn = +1;
+ }else{
+ return *zDate!=0;
+ }
+ zDate++;
+ if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
+ return 1;
+ }
+ zDate += 5;
+ p->tz = sgn*(nMn + nHr*60);
+ while( isspace(*zDate) ){ zDate++; }
+ return *zDate!=0;
+}
+
+/*
+** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
+** The HH, MM, and SS must each be exactly 2 digits. The
+** fractional seconds FFFF can be one or more digits.
+**
+** Return 1 if there is a parsing error and 0 on success.
+*/
+static int parseHhMmSs(const char *zDate, DateTime *p){
+ int h, m, s;
+ double ms = 0.0;
+ if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
+ return 1;
+ }
+ zDate += 5;
+ if( *zDate==':' ){
+ zDate++;
+ if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
+ return 1;
+ }
+ zDate += 2;
+ if( *zDate=='.' && isdigit(zDate[1]) ){
+ double rScale = 1.0;
+ zDate++;
+ while( isdigit(*zDate) ){
+ ms = ms*10.0 + *zDate - '0';
+ rScale *= 10.0;
+ zDate++;
+ }
+ ms /= rScale;
+ }
+ }else{
+ s = 0;
+ }
+ p->validJD = 0;
+ p->validHMS = 1;
+ p->h = h;
+ p->m = m;
+ p->s = s + ms;
+ if( parseTimezone(zDate, p) ) return 1;
+ p->validTZ = p->tz!=0;
+ return 0;
+}
+
+/*
+** Convert from YYYY-MM-DD HH:MM:SS to julian day. We always assume
+** that the YYYY-MM-DD is according to the Gregorian calendar.
+**
+** Reference: Meeus page 61
+*/
+static void computeJD(DateTime *p){
+ int Y, M, D, A, B, X1, X2;
+
+ if( p->validJD ) return;
+ if( p->validYMD ){
+ Y = p->Y;
+ M = p->M;
+ D = p->D;
+ }else{
+ Y = 2000; /* If no YMD specified, assume 2000-Jan-01 */
+ M = 1;
+ D = 1;
+ }
+ if( M<=2 ){
+ Y--;
+ M += 12;
+ }
+ A = Y/100;
+ B = 2 - A + (A/4);
+ X1 = 365.25*(Y+4716);
+ X2 = 30.6001*(M+1);
+ p->rJD = X1 + X2 + D + B - 1524.5;
+ p->validJD = 1;
+ p->validYMD = 0;
+ if( p->validHMS ){
+ p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
+ if( p->validTZ ){
+ p->rJD += p->tz*60/86400.0;
+ p->validHMS = 0;
+ p->validTZ = 0;
+ }
+ }
+}
+
+/*
+** Parse dates of the form
+**
+** YYYY-MM-DD HH:MM:SS.FFF
+** YYYY-MM-DD HH:MM:SS
+** YYYY-MM-DD HH:MM
+** YYYY-MM-DD
+**
+** Write the result into the DateTime structure and return 0
+** on success and 1 if the input string is not a well-formed
+** date.
+*/
+static int parseYyyyMmDd(const char *zDate, DateTime *p){
+ int Y, M, D, neg;
+
+ if( zDate[0]=='-' ){
+ zDate++;
+ neg = 1;
+ }else{
+ neg = 0;
+ }
+ if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
+ return 1;
+ }
+ zDate += 10;
+ while( isspace(*zDate) ){ zDate++; }
+ if( parseHhMmSs(zDate, p)==0 ){
+ /* We got the time */
+ }else if( *zDate==0 ){
+ p->validHMS = 0;
+ }else{
+ return 1;
+ }
+ p->validJD = 0;
+ p->validYMD = 1;
+ p->Y = neg ? -Y : Y;
+ p->M = M;
+ p->D = D;
+ if( p->validTZ ){
+ computeJD(p);
+ }
+ return 0;
+}
+
+/*
+** Attempt to parse the given string into a Julian Day Number. Return
+** the number of errors.
+**
+** The following are acceptable forms for the input string:
+**
+** YYYY-MM-DD HH:MM:SS.FFF +/-HH:MM
+** DDDD.DD
+** now
+**
+** In the first form, the +/-HH:MM is always optional. The fractional
+** seconds extension (the ".FFF") is optional. The seconds portion
+** (":SS.FFF") is option. The year and date can be omitted as long
+** as there is a time string. The time string can be omitted as long
+** as there is a year and date.
+*/
+static int parseDateOrTime(const char *zDate, DateTime *p){
+ memset(p, 0, sizeof(*p));
+ if( parseYyyyMmDd(zDate,p)==0 ){
+ return 0;
+ }else if( parseHhMmSs(zDate, p)==0 ){
+ return 0;
+ }else if( sqliteStrICmp(zDate,"now")==0){
+ double r;
+ if( sqliteOsCurrentTime(&r)==0 ){
+ p->rJD = r;
+ p->validJD = 1;
+ return 0;
+ }
+ return 1;
+ }else if( sqliteIsNumber(zDate) ){
+ p->rJD = sqliteAtoF(zDate, 0);
+ p->validJD = 1;
+ return 0;
+ }
+ return 1;
+}
+
+/*
+** Compute the Year, Month, and Day from the julian day number.
+*/
+static void computeYMD(DateTime *p){
+ int Z, A, B, C, D, E, X1;
+ if( p->validYMD ) return;
+ if( !p->validJD ){
+ p->Y = 2000;
+ p->M = 1;
+ p->D = 1;
+ }else{
+ Z = p->rJD + 0.5;
+ A = (Z - 1867216.25)/36524.25;
+ A = Z + 1 + A - (A/4);
+ B = A + 1524;
+ C = (B - 122.1)/365.25;
+ D = 365.25*C;
+ E = (B-D)/30.6001;
+ X1 = 30.6001*E;
+ p->D = B - D - X1;
+ p->M = E<14 ? E-1 : E-13;
+ p->Y = p->M>2 ? C - 4716 : C - 4715;
+ }
+ p->validYMD = 1;
+}
+
+/*
+** Compute the Hour, Minute, and Seconds from the julian day number.
+*/
+static void computeHMS(DateTime *p){
+ int Z, s;
+ if( p->validHMS ) return;
+ Z = p->rJD + 0.5;
+ s = (p->rJD + 0.5 - Z)*86400000.0 + 0.5;
+ p->s = 0.001*s;
+ s = p->s;
+ p->s -= s;
+ p->h = s/3600;
+ s -= p->h*3600;
+ p->m = s/60;
+ p->s += s - p->m*60;
+ p->validHMS = 1;
+}
+
+/*
+** Compute both YMD and HMS
+*/
+static void computeYMD_HMS(DateTime *p){
+ computeYMD(p);
+ computeHMS(p);
+}
+
+/*
+** Clear the YMD and HMS and the TZ
+*/
+static void clearYMD_HMS_TZ(DateTime *p){
+ p->validYMD = 0;
+ p->validHMS = 0;
+ p->validTZ = 0;
+}
+
+/*
+** Compute the difference (in days) between localtime and UTC (a.k.a. GMT)
+** for the time value p where p is in UTC.
+*/
+static double localtimeOffset(DateTime *p){
+ DateTime x, y;
+ time_t t;
+ struct tm *pTm;
+ x = *p;
+ computeYMD_HMS(&x);
+ if( x.Y<1971 || x.Y>=2038 ){
+ x.Y = 2000;
+ x.M = 1;
+ x.D = 1;
+ x.h = 0;
+ x.m = 0;
+ x.s = 0.0;
+ } else {
+ int s = x.s + 0.5;
+ x.s = s;
+ }
+ x.tz = 0;
+ x.validJD = 0;
+ computeJD(&x);
+ t = (x.rJD-2440587.5)*86400.0 + 0.5;
+ sqliteOsEnterMutex();
+ pTm = localtime(&t);
+ y.Y = pTm->tm_year + 1900;
+ y.M = pTm->tm_mon + 1;
+ y.D = pTm->tm_mday;
+ y.h = pTm->tm_hour;
+ y.m = pTm->tm_min;
+ y.s = pTm->tm_sec;
+ sqliteOsLeaveMutex();
+ y.validYMD = 1;
+ y.validHMS = 1;
+ y.validJD = 0;
+ y.validTZ = 0;
+ computeJD(&y);
+ return y.rJD - x.rJD;
+}
+
+/*
+** Process a modifier to a date-time stamp. The modifiers are
+** as follows:
+**
+** NNN days
+** NNN hours
+** NNN minutes
+** NNN.NNNN seconds
+** NNN months
+** NNN years
+** start of month
+** start of year
+** start of week
+** start of day
+** weekday N
+** unixepoch
+** localtime
+** utc
+**
+** Return 0 on success and 1 if there is any kind of error.
+*/
+static int parseModifier(const char *zMod, DateTime *p){
+ int rc = 1;
+ int n;
+ double r;
+ char *z, zBuf[30];
+ z = zBuf;
+ for(n=0; n<sizeof(zBuf)-1 && zMod[n]; n++){
+ z[n] = tolower(zMod[n]);
+ }
+ z[n] = 0;
+ switch( z[0] ){
+ case 'l': {
+ /* localtime
+ **
+ ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
+ ** show local time.
+ */
+ if( strcmp(z, "localtime")==0 ){
+ computeJD(p);
+ p->rJD += localtimeOffset(p);
+ clearYMD_HMS_TZ(p);
+ rc = 0;
+ }
+ break;
+ }
+ case 'u': {
+ /*
+ ** unixepoch
+ **
+ ** Treat the current value of p->rJD as the number of
+ ** seconds since 1970. Convert to a real julian day number.
+ */
+ if( strcmp(z, "unixepoch")==0 && p->validJD ){
+ p->rJD = p->rJD/86400.0 + 2440587.5;
+ clearYMD_HMS_TZ(p);
+ rc = 0;
+ }else if( strcmp(z, "utc")==0 ){
+ double c1;
+ computeJD(p);
+ c1 = localtimeOffset(p);
+ p->rJD -= c1;
+ clearYMD_HMS_TZ(p);
+ p->rJD += c1 - localtimeOffset(p);
+ rc = 0;
+ }
+ break;
+ }
+ case 'w': {
+ /*
+ ** weekday N
+ **
+ ** Move the date to the same time on the next occurrance of
+ ** weekday N where 0==Sunday, 1==Monday, and so forth. If the
+ ** date is already on the appropriate weekday, this is a no-op.
+ */
+ if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0
+ && (n=r)==r && n>=0 && r<7 ){
+ int Z;
+ computeYMD_HMS(p);
+ p->validTZ = 0;
+ p->validJD = 0;
+ computeJD(p);
+ Z = p->rJD + 1.5;
+ Z %= 7;
+ if( Z>n ) Z -= 7;
+ p->rJD += n - Z;
+ clearYMD_HMS_TZ(p);
+ rc = 0;
+ }
+ break;
+ }
+ case 's': {
+ /*
+ ** start of TTTTT
+ **
+ ** Move the date backwards to the beginning of the current day,
+ ** or month or year.
+ */
+ if( strncmp(z, "start of ", 9)!=0 ) break;
+ z += 9;
+ computeYMD(p);
+ p->validHMS = 1;
+ p->h = p->m = 0;
+ p->s = 0.0;
+ p->validTZ = 0;
+ p->validJD = 0;
+ if( strcmp(z,"month")==0 ){
+ p->D = 1;
+ rc = 0;
+ }else if( strcmp(z,"year")==0 ){
+ computeYMD(p);
+ p->M = 1;
+ p->D = 1;
+ rc = 0;
+ }else if( strcmp(z,"day")==0 ){
+ rc = 0;
+ }
+ break;
+ }
+ case '+':
+ case '-':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9': {
+ n = getValue(z, &r);
+ if( n<=0 ) break;
+ if( z[n]==':' ){
+ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
+ ** specified number of hours, minutes, seconds, and fractional seconds
+ ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be
+ ** omitted.
+ */
+ const char *z2 = z;
+ DateTime tx;
+ int day;
+ if( !isdigit(*z2) ) z2++;
+ memset(&tx, 0, sizeof(tx));
+ if( parseHhMmSs(z2, &tx) ) break;
+ computeJD(&tx);
+ tx.rJD -= 0.5;
+ day = (int)tx.rJD;
+ tx.rJD -= day;
+ if( z[0]=='-' ) tx.rJD = -tx.rJD;
+ computeJD(p);
+ clearYMD_HMS_TZ(p);
+ p->rJD += tx.rJD;
+ rc = 0;
+ break;
+ }
+ z += n;
+ while( isspace(z[0]) ) z++;
+ n = strlen(z);
+ if( n>10 || n<3 ) break;
+ if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
+ computeJD(p);
+ rc = 0;
+ if( n==3 && strcmp(z,"day")==0 ){
+ p->rJD += r;
+ }else if( n==4 && strcmp(z,"hour")==0 ){
+ p->rJD += r/24.0;
+ }else if( n==6 && strcmp(z,"minute")==0 ){
+ p->rJD += r/(24.0*60.0);
+ }else if( n==6 && strcmp(z,"second")==0 ){
+ p->rJD += r/(24.0*60.0*60.0);
+ }else if( n==5 && strcmp(z,"month")==0 ){
+ int x, y;
+ computeYMD_HMS(p);
+ p->M += r;
+ x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
+ p->Y += x;
+ p->M -= x*12;
+ p->validJD = 0;
+ computeJD(p);
+ y = r;
+ if( y!=r ){
+ p->rJD += (r - y)*30.0;
+ }
+ }else if( n==4 && strcmp(z,"year")==0 ){
+ computeYMD_HMS(p);
+ p->Y += r;
+ p->validJD = 0;
+ computeJD(p);
+ }else{
+ rc = 1;
+ }
+ clearYMD_HMS_TZ(p);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ return rc;
+}
+
+/*
+** Process time function arguments. argv[0] is a date-time stamp.
+** argv[1] and following are modifiers. Parse them all and write
+** the resulting time into the DateTime structure p. Return 0
+** on success and 1 if there are any errors.
+*/
+static int isDate(int argc, const char **argv, DateTime *p){
+ int i;
+ if( argc==0 ) return 1;
+ if( argv[0]==0 || parseDateOrTime(argv[0], p) ) return 1;
+ for(i=1; i<argc; i++){
+ if( argv[i]==0 || parseModifier(argv[i], p) ) return 1;
+ }
+ return 0;
+}
+
+
+/*
+** The following routines implement the various date and time functions
+** of STQLite.
+*/
+
+/*
+** julianday( TIMESTRING, MOD, MOD, ...)
+**
+** Return the julian day number of the date specified in the arguments
+*/
+static void juliandayFunc(sqlite_func *context, int argc, const char **argv){
+ DateTime x;
+ if( isDate(argc, argv, &x)==0 ){
+ computeJD(&x);
+ sqlite_set_result_double(context, x.rJD);
+ }
+}
+
+/*
+** datetime( TIMESTRING, MOD, MOD, ...)
+**
+** Return YYYY-MM-DD HH:MM:SS
+*/
+static void datetimeFunc(sqlite_func *context, int argc, const char **argv){
+ DateTime x;
+ if( isDate(argc, argv, &x)==0 ){
+ char zBuf[100];
+ computeYMD_HMS(&x);
+ sprintf(zBuf, "%04d-%02d-%02d %02d:%02d:%02d",x.Y, x.M, x.D, x.h, x.m,
+ (int)(x.s));
+ sqlite_set_result_string(context, zBuf, -1);
+ }
+}
+
+/*
+** time( TIMESTRING, MOD, MOD, ...)
+**
+** Return HH:MM:SS
+*/
+static void timeFunc(sqlite_func *context, int argc, const char **argv){
+ DateTime x;
+ if( isDate(argc, argv, &x)==0 ){
+ char zBuf[100];
+ computeHMS(&x);
+ sprintf(zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
+ sqlite_set_result_string(context, zBuf, -1);
+ }
+}
+
+/*
+** date( TIMESTRING, MOD, MOD, ...)
+**
+** Return YYYY-MM-DD
+*/
+static void dateFunc(sqlite_func *context, int argc, const char **argv){
+ DateTime x;
+ if( isDate(argc, argv, &x)==0 ){
+ char zBuf[100];
+ computeYMD(&x);
+ sprintf(zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
+ sqlite_set_result_string(context, zBuf, -1);
+ }
+}
+
+/*
+** strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
+**
+** Return a string described by FORMAT. Conversions as follows:
+**
+** %d day of month
+** %f ** fractional seconds SS.SSS
+** %H hour 00-24
+** %j day of year 000-366
+** %J ** Julian day number
+** %m month 01-12
+** %M minute 00-59
+** %s seconds since 1970-01-01
+** %S seconds 00-59
+** %w day of week 0-6 sunday==0
+** %W week of year 00-53
+** %Y year 0000-9999
+** %% %
+*/
+static void strftimeFunc(sqlite_func *context, int argc, const char **argv){
+ DateTime x;
+ int n, i, j;
+ char *z;
+ const char *zFmt = argv[0];
+ char zBuf[100];
+ if( argv[0]==0 || isDate(argc-1, argv+1, &x) ) return;
+ for(i=0, n=1; zFmt[i]; i++, n++){
+ if( zFmt[i]=='%' ){
+ switch( zFmt[i+1] ){
+ case 'd':
+ case 'H':
+ case 'm':
+ case 'M':
+ case 'S':
+ case 'W':
+ n++;
+ /* fall thru */
+ case 'w':
+ case '%':
+ break;
+ case 'f':
+ n += 8;
+ break;
+ case 'j':
+ n += 3;
+ break;
+ case 'Y':
+ n += 8;
+ break;
+ case 's':
+ case 'J':
+ n += 50;
+ break;
+ default:
+ return; /* ERROR. return a NULL */
+ }
+ i++;
+ }
+ }
+ if( n<sizeof(zBuf) ){
+ z = zBuf;
+ }else{
+ z = sqliteMalloc( n );
+ if( z==0 ) return;
+ }
+ computeJD(&x);
+ computeYMD_HMS(&x);
+ for(i=j=0; zFmt[i]; i++){
+ if( zFmt[i]!='%' ){
+ z[j++] = zFmt[i];
+ }else{
+ i++;
+ switch( zFmt[i] ){
+ case 'd': sprintf(&z[j],"%02d",x.D); j+=2; break;
+ case 'f': {
+ int s = x.s;
+ int ms = (x.s - s)*1000.0;
+ sprintf(&z[j],"%02d.%03d",s,ms);
+ j += strlen(&z[j]);
+ break;
+ }
+ case 'H': sprintf(&z[j],"%02d",x.h); j+=2; break;
+ case 'W': /* Fall thru */
+ case 'j': {
+ int n;
+ DateTime y = x;
+ y.validJD = 0;
+ y.M = 1;
+ y.D = 1;
+ computeJD(&y);
+ n = x.rJD - y.rJD + 1;
+ if( zFmt[i]=='W' ){
+ sprintf(&z[j],"%02d",(n+6)/7);
+ j += 2;
+ }else{
+ sprintf(&z[j],"%03d",n);
+ j += 3;
+ }
+ break;
+ }
+ case 'J': sprintf(&z[j],"%.16g",x.rJD); j+=strlen(&z[j]); break;
+ case 'm': sprintf(&z[j],"%02d",x.M); j+=2; break;
+ case 'M': sprintf(&z[j],"%02d",x.m); j+=2; break;
+ case 's': {
+ sprintf(&z[j],"%d",(int)((x.rJD-2440587.5)*86400.0 + 0.5));
+ j += strlen(&z[j]);
+ break;
+ }
+ case 'S': sprintf(&z[j],"%02d",(int)(x.s+0.5)); j+=2; break;
+ case 'w': z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break;
+ case 'Y': sprintf(&z[j],"%04d",x.Y); j+=strlen(&z[j]); break;
+ case '%': z[j++] = '%'; break;
+ }
+ }
+ }
+ z[j] = 0;
+ sqlite_set_result_string(context, z, -1);
+ if( z!=zBuf ){
+ sqliteFree(z);
+ }
+}
+
+
+#endif /* !defined(STQLITE_OMIT_DATETIME_FUNCS) */
+
+/*
+** This function registered all of the above C functions as SQL
+** functions. This should be the only routine in this file with
+** external linkage.
+*/
+void sqliteRegisterDateTimeFunctions(sqlite *db){
+ static struct {
+ char *zName;
+ int nArg;
+ int dataType;
+ void (*xFunc)(sqlite_func*,int,const char**);
+ } aFuncs[] = {
+#ifndef STQLITE_OMIT_DATETIME_FUNCS
+ { "julianday", -1, STQLITE_NUMERIC, juliandayFunc },
+ { "date", -1, STQLITE_TEXT, dateFunc },
+ { "time", -1, STQLITE_TEXT, timeFunc },
+ { "datetime", -1, STQLITE_TEXT, datetimeFunc },
+ { "strftime", -1, STQLITE_TEXT, strftimeFunc },
+#endif
+ };
+ int i;
+
+ for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
+ sqlite_create_function(db, aFuncs[i].zName,
+ aFuncs[i].nArg, aFuncs[i].xFunc, 0);
+ if( aFuncs[i].xFunc ){
+ sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
+ }
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/delete.c b/tqtinterface/qt4/src/3rdparty/sqlite/delete.c
new file mode 100644
index 0000000..5dbcb48
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/delete.c
@@ -0,0 +1,393 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains C code routines that are called by the parser
+** to handle DELETE FROM statements.
+**
+** $Id: delete.c,v 1.61 2004/02/24 01:05:32 drh Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** Look up every table that is named in pSrc. If any table is not found,
+** add an error message to pParse->zErrMsg and return NULL. If all tables
+** are found, return a pointer to the last table.
+*/
+Table *sqliteSrcListLookup(Parse *pParse, SrcList *pSrc){
+ Table *pTab = 0;
+ int i;
+ for(i=0; i<pSrc->nSrc; i++){
+ const char *zTab = pSrc->a[i].zName;
+ const char *zDb = pSrc->a[i].zDatabase;
+ pTab = sqliteLocateTable(pParse, zTab, zDb);
+ pSrc->a[i].pTab = pTab;
+ }
+ return pTab;
+}
+
+/*
+** Check to make sure the given table is writable. If it is not
+** writable, generate an error message and return 1. If it is
+** writable return 0;
+*/
+int sqliteIsReadOnly(Parse *pParse, Table *pTab, int viewOk){
+ if( pTab->readOnly ){
+ sqliteErrorMsg(pParse, "table %s may not be modified", pTab->zName);
+ return 1;
+ }
+ if( !viewOk && pTab->pSelect ){
+ sqliteErrorMsg(pParse, "cannot modify %s because it is a view",pTab->zName);
+ return 1;
+ }
+ return 0;
+}
+
+/*
+** Process a DELETE FROM statement.
+*/
+void sqliteDeleteFrom(
+ Parse *pParse, /* The parser context */
+ SrcList *pTabList, /* The table from which we should delete things */
+ Expr *pWhere /* The WHERE clause. May be null */
+){
+ Vdbe *v; /* The virtual database engine */
+ Table *pTab; /* The table from which records will be deleted */
+ const char *zDb; /* Name of database holding pTab */
+ int end, addr; /* A couple addresses of generated code */
+ int i; /* Loop counter */
+ WhereInfo *pWInfo; /* Information about the WHERE clause */
+ Index *pIdx; /* For looping over indices of the table */
+ int iCur; /* VDBE Cursor number for pTab */
+ sqlite *db; /* Main database structure */
+ int isView; /* True if attempting to delete from a view */
+ AuthContext sContext; /* Authorization context */
+
+ int row_triggers_exist = 0; /* True if any triggers exist */
+ int before_triggers; /* True if there are BEFORE triggers */
+ int after_triggers; /* True if there are AFTER triggers */
+ int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */
+
+ sContext.pParse = 0;
+ if( pParse->nErr || sqlite_malloc_failed ){
+ pTabList = 0;
+ goto delete_from_cleanup;
+ }
+ db = pParse->db;
+ assert( pTabList->nSrc==1 );
+
+ /* Locate the table which we want to delete. This table has to be
+ ** put in an SrcList structure because some of the subroutines we
+ ** will be calling are designed to work with multiple tables and expect
+ ** an SrcList* parameter instead of just a Table* parameter.
+ */
+ pTab = sqliteSrcListLookup(pParse, pTabList);
+ if( pTab==0 ) goto delete_from_cleanup;
+ before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger,
+ TK_DELETE, TK_BEFORE, TK_ROW, 0);
+ after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger,
+ TK_DELETE, TK_AFTER, TK_ROW, 0);
+ row_triggers_exist = before_triggers || after_triggers;
+ isView = pTab->pSelect!=0;
+ if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
+ goto delete_from_cleanup;
+ }
+ assert( pTab->iDb<db->nDb );
+ zDb = db->aDb[pTab->iDb].zName;
+ if( sqliteAuthCheck(pParse, STQLITE_DELETE, pTab->zName, 0, zDb) ){
+ goto delete_from_cleanup;
+ }
+
+ /* If pTab is really a view, make sure it has been initialized.
+ */
+ if( isView && sqliteViewGetColumnNames(pParse, pTab) ){
+ goto delete_from_cleanup;
+ }
+
+ /* Allocate a cursor used to store the old.* data for a trigger.
+ */
+ if( row_triggers_exist ){
+ oldIdx = pParse->nTab++;
+ }
+
+ /* Resolve the column names in all the expressions.
+ */
+ assert( pTabList->nSrc==1 );
+ iCur = pTabList->a[0].iCursor = pParse->nTab++;
+ if( pWhere ){
+ if( sqliteExprResolveIds(pParse, pTabList, 0, pWhere) ){
+ goto delete_from_cleanup;
+ }
+ if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
+ goto delete_from_cleanup;
+ }
+ }
+
+ /* Start the view context
+ */
+ if( isView ){
+ sqliteAuthContextPush(pParse, &sContext, pTab->zName);
+ }
+
+ /* Begin generating code.
+ */
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ){
+ goto delete_from_cleanup;
+ }
+ sqliteBeginWriteOperation(pParse, row_triggers_exist, pTab->iDb);
+
+ /* If we are trying to delete from a view, construct that view into
+ ** a temporary table.
+ */
+ if( isView ){
+ Select *pView = sqliteSelectDup(pTab->pSelect);
+ sqliteSelect(pParse, pView, SRT_TempTable, iCur, 0, 0, 0);
+ sqliteSelectDelete(pView);
+ }
+
+ /* Initialize the counter of the number of rows deleted, if
+ ** we are counting rows.
+ */
+ if( db->flags & STQLITE_CountRows ){
+ sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+ }
+
+ /* Special case: A DELETE without a WHERE clause deletes everything.
+ ** It is easier just to erase the whole table. Note, however, that
+ ** this means that the row change count will be incorrect.
+ */
+ if( pWhere==0 && !row_triggers_exist ){
+ if( db->flags & STQLITE_CountRows ){
+ /* If counting rows deleted, just count the total number of
+ ** entries in the table. */
+ int endOfLoop = sqliteVdbeMakeLabel(v);
+ int addr;
+ if( !isView ){
+ sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqliteVdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
+ }
+ sqliteVdbeAddOp(v, OP_Rewind, iCur, sqliteVdbeCurrentAddr(v)+2);
+ addr = sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
+ sqliteVdbeAddOp(v, OP_Next, iCur, addr);
+ sqliteVdbeResolveLabel(v, endOfLoop);
+ sqliteVdbeAddOp(v, OP_Close, iCur, 0);
+ }
+ if( !isView ){
+ sqliteVdbeAddOp(v, OP_Clear, pTab->tnum, pTab->iDb);
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ sqliteVdbeAddOp(v, OP_Clear, pIdx->tnum, pIdx->iDb);
+ }
+ }
+ }
+
+ /* The usual case: There is a WHERE clause so we have to scan through
+ ** the table and pick which records to delete.
+ */
+ else{
+ /* Begin the database scan
+ */
+ pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1, 0);
+ if( pWInfo==0 ) goto delete_from_cleanup;
+
+ /* Remember the key of every item to be deleted.
+ */
+ sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
+ if( db->flags & STQLITE_CountRows ){
+ sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
+ }
+
+ /* End the database scan loop.
+ */
+ sqliteWhereEnd(pWInfo);
+
+ /* Open the pseudo-table used to store OLD if there are triggers.
+ */
+ if( row_triggers_exist ){
+ sqliteVdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
+ }
+
+ /* Delete every item whose key was written to the list during the
+ ** database scan. We have to delete items after the scan is complete
+ ** because deleting an item can change the scan order.
+ */
+ sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
+ end = sqliteVdbeMakeLabel(v);
+
+ /* This is the beginning of the delete loop when there are
+ ** row triggers.
+ */
+ if( row_triggers_exist ){
+ addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
+ if( !isView ){
+ sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqliteVdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
+ }
+ sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
+
+ sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
+ sqliteVdbeAddOp(v, OP_RowData, iCur, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
+ if( !isView ){
+ sqliteVdbeAddOp(v, OP_Close, iCur, 0);
+ }
+
+ sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_BEFORE, pTab, -1,
+ oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
+ addr);
+ }
+
+ if( !isView ){
+ /* Open cursors for the table we are deleting from and all its
+ ** indices. If there are row triggers, this happens inside the
+ ** OP_ListRead loop because the cursor have to all be closed
+ ** before the trigger fires. If there are no row triggers, the
+ ** cursors are opened only once on the outside the loop.
+ */
+ pParse->nTab = iCur + 1;
+ sqliteOpenTableAndIndices(pParse, pTab, iCur);
+
+ /* This is the beginning of the delete loop when there are no
+ ** row triggers */
+ if( !row_triggers_exist ){
+ addr = sqliteVdbeAddOp(v, OP_ListRead, 0, end);
+ }
+
+ /* Delete the row */
+ sqliteGenerateRowDelete(db, v, pTab, iCur, pParse->trigStack==0);
+ }
+
+ /* If there are row triggers, close all cursors then invoke
+ ** the AFTER triggers
+ */
+ if( row_triggers_exist ){
+ if( !isView ){
+ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ sqliteVdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
+ }
+ sqliteVdbeAddOp(v, OP_Close, iCur, 0);
+ }
+ sqliteCodeRowTrigger(pParse, TK_DELETE, 0, TK_AFTER, pTab, -1,
+ oldIdx, (pParse->trigStack)?pParse->trigStack->orconf:OE_Default,
+ addr);
+ }
+
+ /* End of the delete loop */
+ sqliteVdbeAddOp(v, OP_Goto, 0, addr);
+ sqliteVdbeResolveLabel(v, end);
+ sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
+
+ /* Close the cursors after the loop if there are no row triggers */
+ if( !row_triggers_exist ){
+ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ sqliteVdbeAddOp(v, OP_Close, iCur + i, pIdx->tnum);
+ }
+ sqliteVdbeAddOp(v, OP_Close, iCur, 0);
+ pParse->nTab = iCur;
+ }
+ }
+ sqliteVdbeAddOp(v, OP_SetCounts, 0, 0);
+ sqliteEndWriteOperation(pParse);
+
+ /*
+ ** Return the number of rows that were deleted.
+ */
+ if( db->flags & STQLITE_CountRows ){
+ sqliteVdbeAddOp(v, OP_ColumnName, 0, 1);
+ sqliteVdbeChangeP3(v, -1, "rows deleted", P3_STATIC);
+ sqliteVdbeAddOp(v, OP_Callback, 1, 0);
+ }
+
+delete_from_cleanup:
+ sqliteAuthContextPop(&sContext);
+ sqliteSrcListDelete(pTabList);
+ sqliteExprDelete(pWhere);
+ return;
+}
+
+/*
+** This routine generates VDBE code that causes a single row of a
+** single table to be deleted.
+**
+** The VDBE must be in a particular state when this routine is called.
+** These are the requirements:
+**
+** 1. A read/write cursor pointing to pTab, the table containing the row
+** to be deleted, must be opened as cursor number "base".
+**
+** 2. Read/write cursors for all indices of pTab must be open as
+** cursor number base+i for the i-th index.
+**
+** 3. The record number of the row to be deleted must be on the top
+** of the stack.
+**
+** This routine pops the top of the stack to remove the record number
+** and then generates code to remove both the table record and all index
+** entries that point to that record.
+*/
+void sqliteGenerateRowDelete(
+ sqlite *db, /* The database containing the index */
+ Vdbe *v, /* Generate code into this VDBE */
+ Table *pTab, /* Table containing the row to be deleted */
+ int iCur, /* Cursor number for the table */
+ int count /* Increment the row change counter */
+){
+ int addr;
+ addr = sqliteVdbeAddOp(v, OP_NotExists, iCur, 0);
+ sqliteGenerateRowIndexDelete(db, v, pTab, iCur, 0);
+ sqliteVdbeAddOp(v, OP_Delete, iCur,
+ (count?OPFLAG_NCHANGE:0) | OPFLAG_CSCHANGE);
+ sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
+}
+
+/*
+** This routine generates VDBE code that causes the deletion of all
+** index entries associated with a single row of a single table.
+**
+** The VDBE must be in a particular state when this routine is called.
+** These are the requirements:
+**
+** 1. A read/write cursor pointing to pTab, the table containing the row
+** to be deleted, must be opened as cursor number "iCur".
+**
+** 2. Read/write cursors for all indices of pTab must be open as
+** cursor number iCur+i for the i-th index.
+**
+** 3. The "iCur" cursor must be pointing to the row that is to be
+** deleted.
+*/
+void sqliteGenerateRowIndexDelete(
+ sqlite *db, /* The database containing the index */
+ Vdbe *v, /* Generate code into this VDBE */
+ Table *pTab, /* Table containing the row to be deleted */
+ int iCur, /* Cursor number for the table */
+ char *aIdxUsed /* Only delete if aIdxUsed!=0 && aIdxUsed[i]!=0 */
+){
+ int i;
+ Index *pIdx;
+
+ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
+ int j;
+ if( aIdxUsed!=0 && aIdxUsed[i-1]==0 ) continue;
+ sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
+ for(j=0; j<pIdx->nColumn; j++){
+ int idx = pIdx->aiColumn[j];
+ if( idx==pTab->iPKey ){
+ sqliteVdbeAddOp(v, OP_Dup, j, 0);
+ }else{
+ sqliteVdbeAddOp(v, OP_Column, iCur, idx);
+ }
+ }
+ sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
+ if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
+ sqliteVdbeAddOp(v, OP_IdxDelete, iCur+i, 0);
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/expr.c b/tqtinterface/qt4/src/3rdparty/sqlite/expr.c
new file mode 100644
index 0000000..d19fe47
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/expr.c
@@ -0,0 +1,1656 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains routines used for analyzing expressions and
+** for generating VDBE code that evaluates expressions in STQLite.
+**
+** $Id: expr.c,v 1.112 2004/02/25 13:47:31 drh Exp $
+*/
+#include "sqliteInt.h"
+#include <ctype.h>
+
+/*
+** Construct a new expression node and return a pointer to it. Memory
+** for this node is obtained from sqliteMalloc(). The calling function
+** is responsible for making sure the node eventually gets freed.
+*/
+Expr *sqliteExpr(int op, Expr *pLeft, Expr *pRight, Token *pToken){
+ Expr *pNew;
+ pNew = sqliteMalloc( sizeof(Expr) );
+ if( pNew==0 ){
+ /* When malloc fails, we leak memory from pLeft and pRight */
+ return 0;
+ }
+ pNew->op = op;
+ pNew->pLeft = pLeft;
+ pNew->pRight = pRight;
+ if( pToken ){
+ assert( pToken->dyn==0 );
+ pNew->token = *pToken;
+ pNew->span = *pToken;
+ }else{
+ assert( pNew->token.dyn==0 );
+ assert( pNew->token.z==0 );
+ assert( pNew->token.n==0 );
+ if( pLeft && pRight ){
+ sqliteExprSpan(pNew, &pLeft->span, &pRight->span);
+ }else{
+ pNew->span = pNew->token;
+ }
+ }
+ return pNew;
+}
+
+/*
+** Set the Expr.span field of the given expression to span all
+** text between the two given tokens.
+*/
+void sqliteExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
+ assert( pRight!=0 );
+ assert( pLeft!=0 );
+ /* Note: pExpr might be NULL due to a prior malloc failure */
+ if( pExpr && pRight->z && pLeft->z ){
+ if( pLeft->dyn==0 && pRight->dyn==0 ){
+ pExpr->span.z = pLeft->z;
+ pExpr->span.n = pRight->n + Addr(pRight->z) - Addr(pLeft->z);
+ }else{
+ pExpr->span.z = 0;
+ }
+ }
+}
+
+/*
+** Construct a new expression node for a function with multiple
+** arguments.
+*/
+Expr *sqliteExprFunction(ExprList *pList, Token *pToken){
+ Expr *pNew;
+ pNew = sqliteMalloc( sizeof(Expr) );
+ if( pNew==0 ){
+ /* sqliteExprListDelete(pList); // Leak pList when malloc fails */
+ return 0;
+ }
+ pNew->op = TK_FUNCTION;
+ pNew->pList = pList;
+ if( pToken ){
+ assert( pToken->dyn==0 );
+ pNew->token = *pToken;
+ }else{
+ pNew->token.z = 0;
+ }
+ pNew->span = pNew->token;
+ return pNew;
+}
+
+/*
+** Recursively delete an expression tree.
+*/
+void sqliteExprDelete(Expr *p){
+ if( p==0 ) return;
+ if( p->span.dyn ) sqliteFree((char*)p->span.z);
+ if( p->token.dyn ) sqliteFree((char*)p->token.z);
+ sqliteExprDelete(p->pLeft);
+ sqliteExprDelete(p->pRight);
+ sqliteExprListDelete(p->pList);
+ sqliteSelectDelete(p->pSelect);
+ sqliteFree(p);
+}
+
+
+/*
+** The following group of routines make deep copies of expressions,
+** expression lists, ID lists, and select statements. The copies can
+** be deleted (by being passed to their respective ...Delete() routines)
+** without effecting the originals.
+**
+** The expression list, ID, and source lists return by sqliteExprListDup(),
+** sqliteIdListDup(), and sqliteSrcListDup() can not be further expanded
+** by subsequent calls to sqlite*ListAppend() routines.
+**
+** Any tables that the SrcList might point to are not duplicated.
+*/
+Expr *sqliteExprDup(Expr *p){
+ Expr *pNew;
+ if( p==0 ) return 0;
+ pNew = sqliteMallocRaw( sizeof(*p) );
+ if( pNew==0 ) return 0;
+ memcpy(pNew, p, sizeof(*pNew));
+ if( p->token.z!=0 ){
+ pNew->token.z = sqliteStrDup(p->token.z);
+ pNew->token.dyn = 1;
+ }else{
+ assert( pNew->token.z==0 );
+ }
+ pNew->span.z = 0;
+ pNew->pLeft = sqliteExprDup(p->pLeft);
+ pNew->pRight = sqliteExprDup(p->pRight);
+ pNew->pList = sqliteExprListDup(p->pList);
+ pNew->pSelect = sqliteSelectDup(p->pSelect);
+ return pNew;
+}
+void sqliteTokenCopy(Token *pTo, Token *pFrom){
+ if( pTo->dyn ) sqliteFree((char*)pTo->z);
+ if( pFrom->z ){
+ pTo->n = pFrom->n;
+ pTo->z = sqliteStrNDup(pFrom->z, pFrom->n);
+ pTo->dyn = 1;
+ }else{
+ pTo->z = 0;
+ }
+}
+ExprList *sqliteExprListDup(ExprList *p){
+ ExprList *pNew;
+ struct ExprList_item *pItem;
+ int i;
+ if( p==0 ) return 0;
+ pNew = sqliteMalloc( sizeof(*pNew) );
+ if( pNew==0 ) return 0;
+ pNew->nExpr = pNew->nAlloc = p->nExpr;
+ pNew->a = pItem = sqliteMalloc( p->nExpr*sizeof(p->a[0]) );
+ for(i=0; pItem && i<p->nExpr; i++, pItem++){
+ Expr *pNewExpr, *pOldExpr;
+ pItem->pExpr = pNewExpr = sqliteExprDup(pOldExpr = p->a[i].pExpr);
+ if( pOldExpr->span.z!=0 && pNewExpr ){
+ /* Always make a copy of the span for top-level expressions in the
+ ** expression list. The logic in SELECT processing that determines
+ ** the names of columns in the result set needs this information */
+ sqliteTokenCopy(&pNewExpr->span, &pOldExpr->span);
+ }
+ assert( pNewExpr==0 || pNewExpr->span.z!=0
+ || pOldExpr->span.z==0 || sqlite_malloc_failed );
+ pItem->zName = sqliteStrDup(p->a[i].zName);
+ pItem->sortOrder = p->a[i].sortOrder;
+ pItem->isAgg = p->a[i].isAgg;
+ pItem->done = 0;
+ }
+ return pNew;
+}
+SrcList *sqliteSrcListDup(SrcList *p){
+ SrcList *pNew;
+ int i;
+ int nByte;
+ if( p==0 ) return 0;
+ nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
+ pNew = sqliteMallocRaw( nByte );
+ if( pNew==0 ) return 0;
+ pNew->nSrc = pNew->nAlloc = p->nSrc;
+ for(i=0; i<p->nSrc; i++){
+ struct SrcList_item *pNewItem = &pNew->a[i];
+ struct SrcList_item *pOldItem = &p->a[i];
+ pNewItem->zDatabase = sqliteStrDup(pOldItem->zDatabase);
+ pNewItem->zName = sqliteStrDup(pOldItem->zName);
+ pNewItem->zAlias = sqliteStrDup(pOldItem->zAlias);
+ pNewItem->jointype = pOldItem->jointype;
+ pNewItem->iCursor = pOldItem->iCursor;
+ pNewItem->pTab = 0;
+ pNewItem->pSelect = sqliteSelectDup(pOldItem->pSelect);
+ pNewItem->pOn = sqliteExprDup(pOldItem->pOn);
+ pNewItem->pUsing = sqliteIdListDup(pOldItem->pUsing);
+ }
+ return pNew;
+}
+IdList *sqliteIdListDup(IdList *p){
+ IdList *pNew;
+ int i;
+ if( p==0 ) return 0;
+ pNew = sqliteMallocRaw( sizeof(*pNew) );
+ if( pNew==0 ) return 0;
+ pNew->nId = pNew->nAlloc = p->nId;
+ pNew->a = sqliteMallocRaw( p->nId*sizeof(p->a[0]) );
+ if( pNew->a==0 ) return 0;
+ for(i=0; i<p->nId; i++){
+ struct IdList_item *pNewItem = &pNew->a[i];
+ struct IdList_item *pOldItem = &p->a[i];
+ pNewItem->zName = sqliteStrDup(pOldItem->zName);
+ pNewItem->idx = pOldItem->idx;
+ }
+ return pNew;
+}
+Select *sqliteSelectDup(Select *p){
+ Select *pNew;
+ if( p==0 ) return 0;
+ pNew = sqliteMallocRaw( sizeof(*p) );
+ if( pNew==0 ) return 0;
+ pNew->isDistinct = p->isDistinct;
+ pNew->pEList = sqliteExprListDup(p->pEList);
+ pNew->pSrc = sqliteSrcListDup(p->pSrc);
+ pNew->pWhere = sqliteExprDup(p->pWhere);
+ pNew->pGroupBy = sqliteExprListDup(p->pGroupBy);
+ pNew->pHaving = sqliteExprDup(p->pHaving);
+ pNew->pOrderBy = sqliteExprListDup(p->pOrderBy);
+ pNew->op = p->op;
+ pNew->pPrior = sqliteSelectDup(p->pPrior);
+ pNew->nLimit = p->nLimit;
+ pNew->nOffset = p->nOffset;
+ pNew->zSelect = 0;
+ pNew->iLimit = -1;
+ pNew->iOffset = -1;
+ return pNew;
+}
+
+
+/*
+** Add a new element to the end of an expression list. If pList is
+** initially NULL, then create a new expression list.
+*/
+ExprList *sqliteExprListAppend(ExprList *pList, Expr *pExpr, Token *pName){
+ if( pList==0 ){
+ pList = sqliteMalloc( sizeof(ExprList) );
+ if( pList==0 ){
+ /* sqliteExprDelete(pExpr); // Leak memory if malloc fails */
+ return 0;
+ }
+ assert( pList->nAlloc==0 );
+ }
+ if( pList->nAlloc<=pList->nExpr ){
+ pList->nAlloc = pList->nAlloc*2 + 4;
+ pList->a = sqliteRealloc(pList->a, pList->nAlloc*sizeof(pList->a[0]));
+ if( pList->a==0 ){
+ /* sqliteExprDelete(pExpr); // Leak memory if malloc fails */
+ pList->nExpr = pList->nAlloc = 0;
+ return pList;
+ }
+ }
+ assert( pList->a!=0 );
+ if( pExpr || pName ){
+ struct ExprList_item *pItem = &pList->a[pList->nExpr++];
+ memset(pItem, 0, sizeof(*pItem));
+ pItem->pExpr = pExpr;
+ if( pName ){
+ sqliteSetNString(&pItem->zName, pName->z, pName->n, 0);
+ sqliteDequote(pItem->zName);
+ }
+ }
+ return pList;
+}
+
+/*
+** Delete an entire expression list.
+*/
+void sqliteExprListDelete(ExprList *pList){
+ int i;
+ if( pList==0 ) return;
+ for(i=0; i<pList->nExpr; i++){
+ sqliteExprDelete(pList->a[i].pExpr);
+ sqliteFree(pList->a[i].zName);
+ }
+ sqliteFree(pList->a);
+ sqliteFree(pList);
+}
+
+/*
+** Walk an expression tree. Return 1 if the expression is constant
+** and 0 if it involves variables.
+**
+** For the purposes of this function, a double-quoted string (ex: "abc")
+** is considered a variable but a single-quoted string (ex: 'abc') is
+** a constant.
+*/
+int sqliteExprIsConstant(Expr *p){
+ switch( p->op ){
+ case TK_ID:
+ case TK_COLUMN:
+ case TK_DOT:
+ case TK_FUNCTION:
+ return 0;
+ case TK_NULL:
+ case TK_STRING:
+ case TK_INTEGER:
+ case TK_FLOAT:
+ case TK_VARIABLE:
+ return 1;
+ default: {
+ if( p->pLeft && !sqliteExprIsConstant(p->pLeft) ) return 0;
+ if( p->pRight && !sqliteExprIsConstant(p->pRight) ) return 0;
+ if( p->pList ){
+ int i;
+ for(i=0; i<p->pList->nExpr; i++){
+ if( !sqliteExprIsConstant(p->pList->a[i].pExpr) ) return 0;
+ }
+ }
+ return p->pLeft!=0 || p->pRight!=0 || (p->pList && p->pList->nExpr>0);
+ }
+ }
+ return 0;
+}
+
+/*
+** If the given expression codes a constant integer that is small enough
+** to fit in a 32-bit integer, return 1 and put the value of the integer
+** in *pValue. If the expression is not an integer or if it is too big
+** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
+*/
+int sqliteExprIsInteger(Expr *p, int *pValue){
+ switch( p->op ){
+ case TK_INTEGER: {
+ if( sqliteFitsIn32Bits(p->token.z) ){
+ *pValue = atoi(p->token.z);
+ return 1;
+ }
+ break;
+ }
+ case TK_STRING: {
+ const char *z = p->token.z;
+ int n = p->token.n;
+ if( n>0 && z[0]=='-' ){ z++; n--; }
+ while( n>0 && *z && isdigit(*z) ){ z++; n--; }
+ if( n==0 && sqliteFitsIn32Bits(p->token.z) ){
+ *pValue = atoi(p->token.z);
+ return 1;
+ }
+ break;
+ }
+ case TK_UPLUS: {
+ return sqliteExprIsInteger(p->pLeft, pValue);
+ }
+ case TK_UMINUS: {
+ int v;
+ if( sqliteExprIsInteger(p->pLeft, &v) ){
+ *pValue = -v;
+ return 1;
+ }
+ break;
+ }
+ default: break;
+ }
+ return 0;
+}
+
+/*
+** Return TRUE if the given string is a row-id column name.
+*/
+int sqliteIsRowid(const char *z){
+ if( sqliteStrICmp(z, "_ROWID_")==0 ) return 1;
+ if( sqliteStrICmp(z, "ROWID")==0 ) return 1;
+ if( sqliteStrICmp(z, "OID")==0 ) return 1;
+ return 0;
+}
+
+/*
+** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
+** that name in the set of source tables in pSrcList and make the pExpr
+** expression node refer back to that source column. The following changes
+** are made to pExpr:
+**
+** pExpr->iDb Set the index in db->aDb[] of the database holding
+** the table.
+** pExpr->iTable Set to the cursor number for the table obtained
+** from pSrcList.
+** pExpr->iColumn Set to the column number within the table.
+** pExpr->dataType Set to the appropriate data type for the column.
+** pExpr->op Set to TK_COLUMN.
+** pExpr->pLeft Any expression this points to is deleted
+** pExpr->pRight Any expression this points to is deleted.
+**
+** The pDbToken is the name of the database (the "X"). This value may be
+** NULL meaning that name is of the form Y.Z or Z. Any available database
+** can be used. The pTableToken is the name of the table (the "Y"). This
+** value can be NULL if pDbToken is also NULL. If pTableToken is NULL it
+** means that the form of the name is Z and that columns from any table
+** can be used.
+**
+** If the name cannot be resolved unambiguously, leave an error message
+** in pParse and return non-zero. Return zero on success.
+*/
+static int lookupName(
+ Parse *pParse, /* The parsing context */
+ Token *pDbToken, /* Name of the database containing table, or NULL */
+ Token *pTableToken, /* Name of table containing column, or NULL */
+ Token *pColumnToken, /* Name of the column. */
+ SrcList *pSrcList, /* List of tables used to resolve column names */
+ ExprList *pEList, /* List of expressions used to resolve "AS" */
+ Expr *pExpr /* Make this EXPR node point to the selected column */
+){
+ char *zDb = 0; /* Name of the database. The "X" in X.Y.Z */
+ char *zTab = 0; /* Name of the table. The "Y" in X.Y.Z or Y.Z */
+ char *zCol = 0; /* Name of the column. The "Z" */
+ int i, j; /* Loop counters */
+ int cnt = 0; /* Number of matching column names */
+ int cntTab = 0; /* Number of matching table names */
+ sqlite *db = pParse->db; /* The database */
+
+ assert( pColumnToken && pColumnToken->z ); /* The Z in X.Y.Z cannot be NULL */
+ if( pDbToken && pDbToken->z ){
+ zDb = sqliteStrNDup(pDbToken->z, pDbToken->n);
+ sqliteDequote(zDb);
+ }else{
+ zDb = 0;
+ }
+ if( pTableToken && pTableToken->z ){
+ zTab = sqliteStrNDup(pTableToken->z, pTableToken->n);
+ sqliteDequote(zTab);
+ }else{
+ assert( zDb==0 );
+ zTab = 0;
+ }
+ zCol = sqliteStrNDup(pColumnToken->z, pColumnToken->n);
+ sqliteDequote(zCol);
+ if( sqlite_malloc_failed ){
+ return 1; /* Leak memory (zDb and zTab) if malloc fails */
+ }
+ assert( zTab==0 || pEList==0 );
+
+ pExpr->iTable = -1;
+ for(i=0; i<pSrcList->nSrc; i++){
+ struct SrcList_item *pItem = &pSrcList->a[i];
+ Table *pTab = pItem->pTab;
+ Column *pCol;
+
+ if( pTab==0 ) continue;
+ assert( pTab->nCol>0 );
+ if( zTab ){
+ if( pItem->zAlias ){
+ char *zTabName = pItem->zAlias;
+ if( sqliteStrICmp(zTabName, zTab)!=0 ) continue;
+ }else{
+ char *zTabName = pTab->zName;
+ if( zTabName==0 || sqliteStrICmp(zTabName, zTab)!=0 ) continue;
+ if( zDb!=0 && sqliteStrICmp(db->aDb[pTab->iDb].zName, zDb)!=0 ){
+ continue;
+ }
+ }
+ }
+ if( 0==(cntTab++) ){
+ pExpr->iTable = pItem->iCursor;
+ pExpr->iDb = pTab->iDb;
+ }
+ for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
+ if( sqliteStrICmp(pCol->zName, zCol)==0 ){
+ cnt++;
+ pExpr->iTable = pItem->iCursor;
+ pExpr->iDb = pTab->iDb;
+ /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
+ pExpr->iColumn = j==pTab->iPKey ? -1 : j;
+ pExpr->dataType = pCol->sortOrder & STQLITE_SO_TYPEMASK;
+ break;
+ }
+ }
+ }
+
+ /* If we have not already resolved the name, then maybe
+ ** it is a new.* or old.* trigger argument reference
+ */
+ if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){
+ TriggerStack *pTriggerStack = pParse->trigStack;
+ Table *pTab = 0;
+ if( pTriggerStack->newIdx != -1 && sqliteStrICmp("new", zTab) == 0 ){
+ pExpr->iTable = pTriggerStack->newIdx;
+ assert( pTriggerStack->pTab );
+ pTab = pTriggerStack->pTab;
+ }else if( pTriggerStack->oldIdx != -1 && sqliteStrICmp("old", zTab) == 0 ){
+ pExpr->iTable = pTriggerStack->oldIdx;
+ assert( pTriggerStack->pTab );
+ pTab = pTriggerStack->pTab;
+ }
+
+ if( pTab ){
+ int j;
+ Column *pCol = pTab->aCol;
+
+ pExpr->iDb = pTab->iDb;
+ cntTab++;
+ for(j=0; j < pTab->nCol; j++, pCol++) {
+ if( sqliteStrICmp(pCol->zName, zCol)==0 ){
+ cnt++;
+ pExpr->iColumn = j==pTab->iPKey ? -1 : j;
+ pExpr->dataType = pCol->sortOrder & STQLITE_SO_TYPEMASK;
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ ** Perhaps the name is a reference to the ROWID
+ */
+ if( cnt==0 && cntTab==1 && sqliteIsRowid(zCol) ){
+ cnt = 1;
+ pExpr->iColumn = -1;
+ pExpr->dataType = STQLITE_SO_NUM;
+ }
+
+ /*
+ ** If the input is of the form Z (not Y.Z or X.Y.Z) then the name Z
+ ** might refer to an result-set alias. This happens, for example, when
+ ** we are resolving names in the WHERE clause of the following command:
+ **
+ ** SELECT a+b AS x FROM table WHERE x<10;
+ **
+ ** In cases like this, tqreplace pExpr with a copy of the expression that
+ ** forms the result set entry ("a+b" in the example) and return immediately.
+ ** Note that the expression in the result set should have already been
+ ** resolved by the time the WHERE clause is resolved.
+ */
+ if( cnt==0 && pEList!=0 ){
+ for(j=0; j<pEList->nExpr; j++){
+ char *zAs = pEList->a[j].zName;
+ if( zAs!=0 && sqliteStrICmp(zAs, zCol)==0 ){
+ assert( pExpr->pLeft==0 && pExpr->pRight==0 );
+ pExpr->op = TK_AS;
+ pExpr->iColumn = j;
+ pExpr->pLeft = sqliteExprDup(pEList->a[j].pExpr);
+ sqliteFree(zCol);
+ assert( zTab==0 && zDb==0 );
+ return 0;
+ }
+ }
+ }
+
+ /*
+ ** If X and Y are NULL (in other words if only the column name Z is
+ ** supplied) and the value of Z is enclosed in double-quotes, then
+ ** Z is a string literal if it doesn't match any column names. In that
+ ** case, we need to return right away and not make any changes to
+ ** pExpr.
+ */
+ if( cnt==0 && zTab==0 && pColumnToken->z[0]=='"' ){
+ sqliteFree(zCol);
+ return 0;
+ }
+
+ /*
+ ** cnt==0 means there was not match. cnt>1 means there were two or
+ ** more matches. Either way, we have an error.
+ */
+ if( cnt!=1 ){
+ char *z = 0;
+ char *zErr;
+ zErr = cnt==0 ? "no such column: %s" : "ambiguous column name: %s";
+ if( zDb ){
+ sqliteSetString(&z, zDb, ".", zTab, ".", zCol, 0);
+ }else if( zTab ){
+ sqliteSetString(&z, zTab, ".", zCol, 0);
+ }else{
+ z = sqliteStrDup(zCol);
+ }
+ sqliteErrorMsg(pParse, zErr, z);
+ sqliteFree(z);
+ }
+
+ /* Clean up and return
+ */
+ sqliteFree(zDb);
+ sqliteFree(zTab);
+ sqliteFree(zCol);
+ sqliteExprDelete(pExpr->pLeft);
+ pExpr->pLeft = 0;
+ sqliteExprDelete(pExpr->pRight);
+ pExpr->pRight = 0;
+ pExpr->op = TK_COLUMN;
+ sqliteAuthRead(pParse, pExpr, pSrcList);
+ return cnt!=1;
+}
+
+/*
+** This routine walks an expression tree and resolves references to
+** table columns. Nodes of the form ID.ID or ID resolve into an
+** index to the table in the table list and a column offset. The
+** Expr.opcode for such nodes is changed to TK_COLUMN. The Expr.iTable
+** value is changed to the index of the referenced table in pTabList
+** plus the "base" value. The base value will ultimately become the
+** VDBE cursor number for a cursor that is pointing into the referenced
+** table. The Expr.iColumn value is changed to the index of the column
+** of the referenced table. The Expr.iColumn value for the special
+** ROWID column is -1. Any INTEGER PRIMARY KEY column is tried as an
+** alias for ROWID.
+**
+** We also check for instances of the IN operator. IN comes in two
+** forms:
+**
+** expr IN (exprlist)
+** and
+** expr IN (SELECT ...)
+**
+** The first form is handled by creating a set holding the list
+** of allowed values. The second form causes the SELECT to generate
+** a temporary table.
+**
+** This routine also looks for scalar SELECTs that are part of an expression.
+** If it tqfinds any, it generates code to write the value of that select
+** into a memory cell.
+**
+** Unknown columns or tables provoke an error. The function returns
+** the number of errors seen and leaves an error message on pParse->zErrMsg.
+*/
+int sqliteExprResolveIds(
+ Parse *pParse, /* The parser context */
+ SrcList *pSrcList, /* List of tables used to resolve column names */
+ ExprList *pEList, /* List of expressions used to resolve "AS" */
+ Expr *pExpr /* The expression to be analyzed. */
+){
+ int i;
+
+ if( pExpr==0 || pSrcList==0 ) return 0;
+ for(i=0; i<pSrcList->nSrc; i++){
+ assert( pSrcList->a[i].iCursor>=0 && pSrcList->a[i].iCursor<pParse->nTab );
+ }
+ switch( pExpr->op ){
+ /* Double-quoted strings (ex: "abc") are used as identifiers if
+ ** possible. Otherwise they remain as strings. Single-quoted
+ ** strings (ex: 'abc') are always string literals.
+ */
+ case TK_STRING: {
+ if( pExpr->token.z[0]=='\'' ) break;
+ /* Fall thru into the TK_ID case if this is a double-quoted string */
+ }
+ /* A lone identifier is the name of a columnd.
+ */
+ case TK_ID: {
+ if( lookupName(pParse, 0, 0, &pExpr->token, pSrcList, pEList, pExpr) ){
+ return 1;
+ }
+ break;
+ }
+
+ /* A table name and column name: ID.ID
+ ** Or a database, table and column: ID.ID.ID
+ */
+ case TK_DOT: {
+ Token *pColumn;
+ Token *pTable;
+ Token *pDb;
+ Expr *pRight;
+
+ pRight = pExpr->pRight;
+ if( pRight->op==TK_ID ){
+ pDb = 0;
+ pTable = &pExpr->pLeft->token;
+ pColumn = &pRight->token;
+ }else{
+ assert( pRight->op==TK_DOT );
+ pDb = &pExpr->pLeft->token;
+ pTable = &pRight->pLeft->token;
+ pColumn = &pRight->pRight->token;
+ }
+ if( lookupName(pParse, pDb, pTable, pColumn, pSrcList, 0, pExpr) ){
+ return 1;
+ }
+ break;
+ }
+
+ case TK_IN: {
+ Vdbe *v = sqliteGetVdbe(pParse);
+ if( v==0 ) return 1;
+ if( sqliteExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){
+ return 1;
+ }
+ if( pExpr->pSelect ){
+ /* Case 1: expr IN (SELECT ...)
+ **
+ ** Generate code to write the results of the select into a temporary
+ ** table. The cursor number of the temporary table has already
+ ** been put in iTable by sqliteExprResolveInSelect().
+ */
+ pExpr->iTable = pParse->nTab++;
+ sqliteVdbeAddOp(v, OP_OpenTemp, pExpr->iTable, 1);
+ sqliteSelect(pParse, pExpr->pSelect, SRT_Set, pExpr->iTable, 0,0,0);
+ }else if( pExpr->pList ){
+ /* Case 2: expr IN (exprlist)
+ **
+ ** Create a set to put the exprlist values in. The Set id is stored
+ ** in iTable.
+ */
+ int i, iSet;
+ for(i=0; i<pExpr->pList->nExpr; i++){
+ Expr *pE2 = pExpr->pList->a[i].pExpr;
+ if( !sqliteExprIsConstant(pE2) ){
+ sqliteErrorMsg(pParse,
+ "right-hand side of IN operator must be constant");
+ return 1;
+ }
+ if( sqliteExprCheck(pParse, pE2, 0, 0) ){
+ return 1;
+ }
+ }
+ iSet = pExpr->iTable = pParse->nSet++;
+ for(i=0; i<pExpr->pList->nExpr; i++){
+ Expr *pE2 = pExpr->pList->a[i].pExpr;
+ switch( pE2->op ){
+ case TK_FLOAT:
+ case TK_INTEGER:
+ case TK_STRING: {
+ int addr;
+ assert( pE2->token.z );
+ addr = sqliteVdbeOp3(v, OP_SetInsert, iSet, 0,
+ pE2->token.z, pE2->token.n);
+ sqliteVdbeDequoteP3(v, addr);
+ break;
+ }
+ default: {
+ sqliteExprCode(pParse, pE2);
+ sqliteVdbeAddOp(v, OP_SetInsert, iSet, 0);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ case TK_SELECT: {
+ /* This has to be a scalar SELECT. Generate code to put the
+ ** value of this select in a memory cell and record the number
+ ** of the memory cell in iColumn.
+ */
+ pExpr->iColumn = pParse->nMem++;
+ if( sqliteSelect(pParse, pExpr->pSelect, SRT_Mem, pExpr->iColumn,0,0,0) ){
+ return 1;
+ }
+ break;
+ }
+
+ /* For all else, just recursively walk the tree */
+ default: {
+ if( pExpr->pLeft
+ && sqliteExprResolveIds(pParse, pSrcList, pEList, pExpr->pLeft) ){
+ return 1;
+ }
+ if( pExpr->pRight
+ && sqliteExprResolveIds(pParse, pSrcList, pEList, pExpr->pRight) ){
+ return 1;
+ }
+ if( pExpr->pList ){
+ int i;
+ ExprList *pList = pExpr->pList;
+ for(i=0; i<pList->nExpr; i++){
+ Expr *pArg = pList->a[i].pExpr;
+ if( sqliteExprResolveIds(pParse, pSrcList, pEList, pArg) ){
+ return 1;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** pExpr is a node that defines a function of some kind. It might
+** be a syntactic function like "count(x)" or it might be a function
+** that implements an operator, like "a LIKE b".
+**
+** This routine makes *pzName point to the name of the function and
+** *pnName hold the number of characters in the function name.
+*/
+static void getFunctionName(Expr *pExpr, const char **pzName, int *pnName){
+ switch( pExpr->op ){
+ case TK_FUNCTION: {
+ *pzName = pExpr->token.z;
+ *pnName = pExpr->token.n;
+ break;
+ }
+ case TK_LIKE: {
+ *pzName = "like";
+ *pnName = 4;
+ break;
+ }
+ case TK_GLOB: {
+ *pzName = "glob";
+ *pnName = 4;
+ break;
+ }
+ default: {
+ *pzName = "can't happen";
+ *pnName = 12;
+ break;
+ }
+ }
+}
+
+/*
+** Error check the functions in an expression. Make sure all
+** function names are recognized and all functions have the correct
+** number of arguments. Leave an error message in pParse->zErrMsg
+** if anything is amiss. Return the number of errors.
+**
+** if pIsAgg is not null and this expression is an aggregate function
+** (like count(*) or max(value)) then write a 1 into *pIsAgg.
+*/
+int sqliteExprCheck(Parse *pParse, Expr *pExpr, int allowAgg, int *pIsAgg){
+ int nErr = 0;
+ if( pExpr==0 ) return 0;
+ switch( pExpr->op ){
+ case TK_GLOB:
+ case TK_LIKE:
+ case TK_FUNCTION: {
+ int n = pExpr->pList ? pExpr->pList->nExpr : 0; /* Number of arguments */
+ int no_such_func = 0; /* True if no such function exists */
+ int wrong_num_args = 0; /* True if wrong number of arguments */
+ int is_agg = 0; /* True if is an aggregate function */
+ int i;
+ int nId; /* Number of characters in function name */
+ const char *zId; /* The function name. */
+ FuncDef *pDef;
+
+ getFunctionName(pExpr, &zId, &nId);
+ pDef = sqliteFindFunction(pParse->db, zId, nId, n, 0);
+ if( pDef==0 ){
+ pDef = sqliteFindFunction(pParse->db, zId, nId, -1, 0);
+ if( pDef==0 ){
+ no_such_func = 1;
+ }else{
+ wrong_num_args = 1;
+ }
+ }else{
+ is_agg = pDef->xFunc==0;
+ }
+ if( is_agg && !allowAgg ){
+ sqliteErrorMsg(pParse, "misuse of aggregate function %.*s()", nId, zId);
+ nErr++;
+ is_agg = 0;
+ }else if( no_such_func ){
+ sqliteErrorMsg(pParse, "no such function: %.*s", nId, zId);
+ nErr++;
+ }else if( wrong_num_args ){
+ sqliteErrorMsg(pParse,"wrong number of arguments to function %.*s()",
+ nId, zId);
+ nErr++;
+ }
+ if( is_agg ){
+ pExpr->op = TK_AGG_FUNCTION;
+ if( pIsAgg ) *pIsAgg = 1;
+ }
+ for(i=0; nErr==0 && i<n; i++){
+ nErr = sqliteExprCheck(pParse, pExpr->pList->a[i].pExpr,
+ allowAgg && !is_agg, pIsAgg);
+ }
+ if( pDef==0 ){
+ /* Already reported an error */
+ }else if( pDef->dataType>=0 ){
+ if( pDef->dataType<n ){
+ pExpr->dataType =
+ sqliteExprType(pExpr->pList->a[pDef->dataType].pExpr);
+ }else{
+ pExpr->dataType = STQLITE_SO_NUM;
+ }
+ }else if( pDef->dataType==STQLITE_ARGS ){
+ pDef->dataType = STQLITE_SO_TEXT;
+ for(i=0; i<n; i++){
+ if( sqliteExprType(pExpr->pList->a[i].pExpr)==STQLITE_SO_NUM ){
+ pExpr->dataType = STQLITE_SO_NUM;
+ break;
+ }
+ }
+ }else if( pDef->dataType==STQLITE_NUMERIC ){
+ pExpr->dataType = STQLITE_SO_NUM;
+ }else{
+ pExpr->dataType = STQLITE_SO_TEXT;
+ }
+ }
+ default: {
+ if( pExpr->pLeft ){
+ nErr = sqliteExprCheck(pParse, pExpr->pLeft, allowAgg, pIsAgg);
+ }
+ if( nErr==0 && pExpr->pRight ){
+ nErr = sqliteExprCheck(pParse, pExpr->pRight, allowAgg, pIsAgg);
+ }
+ if( nErr==0 && pExpr->pList ){
+ int n = pExpr->pList->nExpr;
+ int i;
+ for(i=0; nErr==0 && i<n; i++){
+ Expr *pE2 = pExpr->pList->a[i].pExpr;
+ nErr = sqliteExprCheck(pParse, pE2, allowAgg, pIsAgg);
+ }
+ }
+ break;
+ }
+ }
+ return nErr;
+}
+
+/*
+** Return either STQLITE_SO_NUM or STQLITE_SO_TEXT to indicate whether the
+** given expression should sort as numeric values or as text.
+**
+** The sqliteExprResolveIds() and sqliteExprCheck() routines must have
+** both been called on the expression before it is passed to this routine.
+*/
+int sqliteExprType(Expr *p){
+ if( p==0 ) return STQLITE_SO_NUM;
+ while( p ) switch( p->op ){
+ case TK_PLUS:
+ case TK_MINUS:
+ case TK_STAR:
+ case TK_SLASH:
+ case TK_AND:
+ case TK_OR:
+ case TK_ISNULL:
+ case TK_NOTNULL:
+ case TK_NOT:
+ case TK_UMINUS:
+ case TK_UPLUS:
+ case TK_BITAND:
+ case TK_BITOR:
+ case TK_BITNOT:
+ case TK_LSHIFT:
+ case TK_RSHIFT:
+ case TK_REM:
+ case TK_INTEGER:
+ case TK_FLOAT:
+ case TK_IN:
+ case TK_BETWEEN:
+ case TK_GLOB:
+ case TK_LIKE:
+ return STQLITE_SO_NUM;
+
+ case TK_STRING:
+ case TK_NULL:
+ case TK_CONCAT:
+ case TK_VARIABLE:
+ return STQLITE_SO_TEXT;
+
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_NE:
+ case TK_EQ:
+ if( sqliteExprType(p->pLeft)==STQLITE_SO_NUM ){
+ return STQLITE_SO_NUM;
+ }
+ p = p->pRight;
+ break;
+
+ case TK_AS:
+ p = p->pLeft;
+ break;
+
+ case TK_COLUMN:
+ case TK_FUNCTION:
+ case TK_AGG_FUNCTION:
+ return p->dataType;
+
+ case TK_SELECT:
+ assert( p->pSelect );
+ assert( p->pSelect->pEList );
+ assert( p->pSelect->pEList->nExpr>0 );
+ p = p->pSelect->pEList->a[0].pExpr;
+ break;
+
+ case TK_CASE: {
+ if( p->pRight && sqliteExprType(p->pRight)==STQLITE_SO_NUM ){
+ return STQLITE_SO_NUM;
+ }
+ if( p->pList ){
+ int i;
+ ExprList *pList = p->pList;
+ for(i=1; i<pList->nExpr; i+=2){
+ if( sqliteExprType(pList->a[i].pExpr)==STQLITE_SO_NUM ){
+ return STQLITE_SO_NUM;
+ }
+ }
+ }
+ return STQLITE_SO_TEXT;
+ }
+
+ default:
+ assert( p->op==TK_ABORT ); /* Can't Happen */
+ break;
+ }
+ return STQLITE_SO_NUM;
+}
+
+/*
+** Generate code into the current Vdbe to evaluate the given
+** expression and leave the result on the top of stack.
+*/
+void sqliteExprCode(Parse *pParse, Expr *pExpr){
+ Vdbe *v = pParse->pVdbe;
+ int op;
+ if( v==0 || pExpr==0 ) return;
+ switch( pExpr->op ){
+ case TK_PLUS: op = OP_Add; break;
+ case TK_MINUS: op = OP_Subtract; break;
+ case TK_STAR: op = OP_Multiply; break;
+ case TK_SLASH: op = OP_Divide; break;
+ case TK_AND: op = OP_And; break;
+ case TK_OR: op = OP_Or; break;
+ case TK_LT: op = OP_Lt; break;
+ case TK_LE: op = OP_Le; break;
+ case TK_GT: op = OP_Gt; break;
+ case TK_GE: op = OP_Ge; break;
+ case TK_NE: op = OP_Ne; break;
+ case TK_EQ: op = OP_Eq; break;
+ case TK_ISNULL: op = OP_IsNull; break;
+ case TK_NOTNULL: op = OP_NotNull; break;
+ case TK_NOT: op = OP_Not; break;
+ case TK_UMINUS: op = OP_Negative; break;
+ case TK_BITAND: op = OP_BitAnd; break;
+ case TK_BITOR: op = OP_BitOr; break;
+ case TK_BITNOT: op = OP_BitNot; break;
+ case TK_LSHIFT: op = OP_ShiftLeft; break;
+ case TK_RSHIFT: op = OP_ShiftRight; break;
+ case TK_REM: op = OP_Remainder; break;
+ default: break;
+ }
+ switch( pExpr->op ){
+ case TK_COLUMN: {
+ if( pParse->useAgg ){
+ sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
+ }else if( pExpr->iColumn>=0 ){
+ sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn);
+ }else{
+ sqliteVdbeAddOp(v, OP_Recno, pExpr->iTable, 0);
+ }
+ break;
+ }
+ case TK_STRING:
+ case TK_FLOAT:
+ case TK_INTEGER: {
+ if( pExpr->op==TK_INTEGER && sqliteFitsIn32Bits(pExpr->token.z) ){
+ sqliteVdbeAddOp(v, OP_Integer, atoi(pExpr->token.z), 0);
+ }else{
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ }
+ assert( pExpr->token.z );
+ sqliteVdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n);
+ sqliteVdbeDequoteP3(v, -1);
+ break;
+ }
+ case TK_NULL: {
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ break;
+ }
+ case TK_VARIABLE: {
+ sqliteVdbeAddOp(v, OP_Variable, pExpr->iTable, 0);
+ break;
+ }
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_NE:
+ case TK_EQ: {
+ if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==STQLITE_SO_TEXT ){
+ op += 6; /* Convert numeric opcodes to text opcodes */
+ }
+ /* Fall through into the next case */
+ }
+ case TK_AND:
+ case TK_OR:
+ case TK_PLUS:
+ case TK_STAR:
+ case TK_MINUS:
+ case TK_REM:
+ case TK_BITAND:
+ case TK_BITOR:
+ case TK_SLASH: {
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteExprCode(pParse, pExpr->pRight);
+ sqliteVdbeAddOp(v, op, 0, 0);
+ break;
+ }
+ case TK_LSHIFT:
+ case TK_RSHIFT: {
+ sqliteExprCode(pParse, pExpr->pRight);
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteVdbeAddOp(v, op, 0, 0);
+ break;
+ }
+ case TK_CONCAT: {
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteExprCode(pParse, pExpr->pRight);
+ sqliteVdbeAddOp(v, OP_Concat, 2, 0);
+ break;
+ }
+ case TK_UMINUS: {
+ assert( pExpr->pLeft );
+ if( pExpr->pLeft->op==TK_FLOAT || pExpr->pLeft->op==TK_INTEGER ){
+ Token *p = &pExpr->pLeft->token;
+ char *z = sqliteMalloc( p->n + 2 );
+ sprintf(z, "-%.*s", p->n, p->z);
+ if( pExpr->pLeft->op==TK_INTEGER && sqliteFitsIn32Bits(z) ){
+ sqliteVdbeAddOp(v, OP_Integer, atoi(z), 0);
+ }else{
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ }
+ sqliteVdbeChangeP3(v, -1, z, p->n+1);
+ sqliteFree(z);
+ break;
+ }
+ /* Fall through into TK_NOT */
+ }
+ case TK_BITNOT:
+ case TK_NOT: {
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteVdbeAddOp(v, op, 0, 0);
+ break;
+ }
+ case TK_ISNULL:
+ case TK_NOTNULL: {
+ int dest;
+ sqliteVdbeAddOp(v, OP_Integer, 1, 0);
+ sqliteExprCode(pParse, pExpr->pLeft);
+ dest = sqliteVdbeCurrentAddr(v) + 2;
+ sqliteVdbeAddOp(v, op, 1, dest);
+ sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
+ break;
+ }
+ case TK_AGG_FUNCTION: {
+ sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg);
+ break;
+ }
+ case TK_GLOB:
+ case TK_LIKE:
+ case TK_FUNCTION: {
+ ExprList *pList = pExpr->pList;
+ int nExpr = pList ? pList->nExpr : 0;
+ FuncDef *pDef;
+ int nId;
+ const char *zId;
+ getFunctionName(pExpr, &zId, &nId);
+ pDef = sqliteFindFunction(pParse->db, zId, nId, nExpr, 0);
+ assert( pDef!=0 );
+ nExpr = sqliteExprCodeExprList(pParse, pList, pDef->includeTypes);
+ sqliteVdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER);
+ break;
+ }
+ case TK_SELECT: {
+ sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0);
+ break;
+ }
+ case TK_IN: {
+ int addr;
+ sqliteVdbeAddOp(v, OP_Integer, 1, 0);
+ sqliteExprCode(pParse, pExpr->pLeft);
+ addr = sqliteVdbeCurrentAddr(v);
+ sqliteVdbeAddOp(v, OP_NotNull, -1, addr+4);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, addr+6);
+ if( pExpr->pSelect ){
+ sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, addr+6);
+ }else{
+ sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, addr+6);
+ }
+ sqliteVdbeAddOp(v, OP_AddImm, -1, 0);
+ break;
+ }
+ case TK_BETWEEN: {
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
+ sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
+ sqliteVdbeAddOp(v, OP_Ge, 0, 0);
+ sqliteVdbeAddOp(v, OP_Pull, 1, 0);
+ sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
+ sqliteVdbeAddOp(v, OP_Le, 0, 0);
+ sqliteVdbeAddOp(v, OP_And, 0, 0);
+ break;
+ }
+ case TK_UPLUS:
+ case TK_AS: {
+ sqliteExprCode(pParse, pExpr->pLeft);
+ break;
+ }
+ case TK_CASE: {
+ int expr_end_label;
+ int jumpInst;
+ int addr;
+ int nExpr;
+ int i;
+
+ assert(pExpr->pList);
+ assert((pExpr->pList->nExpr % 2) == 0);
+ assert(pExpr->pList->nExpr > 0);
+ nExpr = pExpr->pList->nExpr;
+ expr_end_label = sqliteVdbeMakeLabel(v);
+ if( pExpr->pLeft ){
+ sqliteExprCode(pParse, pExpr->pLeft);
+ }
+ for(i=0; i<nExpr; i=i+2){
+ sqliteExprCode(pParse, pExpr->pList->a[i].pExpr);
+ if( pExpr->pLeft ){
+ sqliteVdbeAddOp(v, OP_Dup, 1, 1);
+ jumpInst = sqliteVdbeAddOp(v, OP_Ne, 1, 0);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ }else{
+ jumpInst = sqliteVdbeAddOp(v, OP_IfNot, 1, 0);
+ }
+ sqliteExprCode(pParse, pExpr->pList->a[i+1].pExpr);
+ sqliteVdbeAddOp(v, OP_Goto, 0, expr_end_label);
+ addr = sqliteVdbeCurrentAddr(v);
+ sqliteVdbeChangeP2(v, jumpInst, addr);
+ }
+ if( pExpr->pLeft ){
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ }
+ if( pExpr->pRight ){
+ sqliteExprCode(pParse, pExpr->pRight);
+ }else{
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ }
+ sqliteVdbeResolveLabel(v, expr_end_label);
+ break;
+ }
+ case TK_RAISE: {
+ if( !pParse->trigStack ){
+ sqliteErrorMsg(pParse,
+ "RAISE() may only be used within a trigger-program");
+ pParse->nErr++;
+ return;
+ }
+ if( pExpr->iColumn == OE_Rollback ||
+ pExpr->iColumn == OE_Abort ||
+ pExpr->iColumn == OE_Fail ){
+ sqliteVdbeOp3(v, OP_Halt, STQLITE_CONSTRAINT, pExpr->iColumn,
+ pExpr->token.z, pExpr->token.n);
+ sqliteVdbeDequoteP3(v, -1);
+ } else {
+ assert( pExpr->iColumn == OE_Ignore );
+ sqliteVdbeOp3(v, OP_Goto, 0, pParse->trigStack->ignoreJump,
+ "(IGNORE jump)", 0);
+ }
+ }
+ break;
+ }
+}
+
+/*
+** Generate code that pushes the value of every element of the given
+** expression list onto the stack. If the includeTypes flag is true,
+** then also push a string that is the datatype of each element onto
+** the stack after the value.
+**
+** Return the number of elements pushed onto the stack.
+*/
+int sqliteExprCodeExprList(
+ Parse *pParse, /* Parsing context */
+ ExprList *pList, /* The expression list to be coded */
+ int includeTypes /* TRUE to put datatypes on the stack too */
+){
+ struct ExprList_item *pItem;
+ int i, n;
+ Vdbe *v;
+ if( pList==0 ) return 0;
+ v = sqliteGetVdbe(pParse);
+ n = pList->nExpr;
+ for(pItem=pList->a, i=0; i<n; i++, pItem++){
+ sqliteExprCode(pParse, pItem->pExpr);
+ if( includeTypes ){
+ sqliteVdbeOp3(v, OP_String, 0, 0,
+ sqliteExprType(pItem->pExpr)==STQLITE_SO_NUM ? "numeric" : "text",
+ P3_STATIC);
+ }
+ }
+ return includeTypes ? n*2 : n;
+}
+
+/*
+** Generate code for a boolean expression such that a jump is made
+** to the label "dest" if the expression is true but execution
+** continues straight thru if the expression is false.
+**
+** If the expression evaluates to NULL (neither true nor false), then
+** take the jump if the jumpIfNull flag is true.
+*/
+void sqliteExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
+ Vdbe *v = pParse->pVdbe;
+ int op = 0;
+ if( v==0 || pExpr==0 ) return;
+ switch( pExpr->op ){
+ case TK_LT: op = OP_Lt; break;
+ case TK_LE: op = OP_Le; break;
+ case TK_GT: op = OP_Gt; break;
+ case TK_GE: op = OP_Ge; break;
+ case TK_NE: op = OP_Ne; break;
+ case TK_EQ: op = OP_Eq; break;
+ case TK_ISNULL: op = OP_IsNull; break;
+ case TK_NOTNULL: op = OP_NotNull; break;
+ default: break;
+ }
+ switch( pExpr->op ){
+ case TK_AND: {
+ int d2 = sqliteVdbeMakeLabel(v);
+ sqliteExprIfFalse(pParse, pExpr->pLeft, d2, !jumpIfNull);
+ sqliteExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqliteVdbeResolveLabel(v, d2);
+ break;
+ }
+ case TK_OR: {
+ sqliteExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqliteExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
+ break;
+ }
+ case TK_NOT: {
+ sqliteExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+ break;
+ }
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_NE:
+ case TK_EQ: {
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteExprCode(pParse, pExpr->pRight);
+ if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==STQLITE_SO_TEXT ){
+ op += 6; /* Convert numeric opcodes to text opcodes */
+ }
+ sqliteVdbeAddOp(v, op, jumpIfNull, dest);
+ break;
+ }
+ case TK_ISNULL:
+ case TK_NOTNULL: {
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteVdbeAddOp(v, op, 1, dest);
+ break;
+ }
+ case TK_IN: {
+ int addr;
+ sqliteExprCode(pParse, pExpr->pLeft);
+ addr = sqliteVdbeCurrentAddr(v);
+ sqliteVdbeAddOp(v, OP_NotNull, -1, addr+3);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, jumpIfNull ? dest : addr+4);
+ if( pExpr->pSelect ){
+ sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, dest);
+ }else{
+ sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, dest);
+ }
+ break;
+ }
+ case TK_BETWEEN: {
+ int addr;
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
+ sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
+ addr = sqliteVdbeAddOp(v, OP_Lt, !jumpIfNull, 0);
+ sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
+ sqliteVdbeAddOp(v, OP_Le, jumpIfNull, dest);
+ sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+ sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ break;
+ }
+ default: {
+ sqliteExprCode(pParse, pExpr);
+ sqliteVdbeAddOp(v, OP_If, jumpIfNull, dest);
+ break;
+ }
+ }
+}
+
+/*
+** Generate code for a boolean expression such that a jump is made
+** to the label "dest" if the expression is false but execution
+** continues straight thru if the expression is true.
+**
+** If the expression evaluates to NULL (neither true nor false) then
+** jump if jumpIfNull is true or fall through if jumpIfNull is false.
+*/
+void sqliteExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
+ Vdbe *v = pParse->pVdbe;
+ int op = 0;
+ if( v==0 || pExpr==0 ) return;
+ switch( pExpr->op ){
+ case TK_LT: op = OP_Ge; break;
+ case TK_LE: op = OP_Gt; break;
+ case TK_GT: op = OP_Le; break;
+ case TK_GE: op = OP_Lt; break;
+ case TK_NE: op = OP_Eq; break;
+ case TK_EQ: op = OP_Ne; break;
+ case TK_ISNULL: op = OP_NotNull; break;
+ case TK_NOTNULL: op = OP_IsNull; break;
+ default: break;
+ }
+ switch( pExpr->op ){
+ case TK_AND: {
+ sqliteExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
+ sqliteExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ break;
+ }
+ case TK_OR: {
+ int d2 = sqliteVdbeMakeLabel(v);
+ sqliteExprIfTrue(pParse, pExpr->pLeft, d2, !jumpIfNull);
+ sqliteExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
+ sqliteVdbeResolveLabel(v, d2);
+ break;
+ }
+ case TK_NOT: {
+ sqliteExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
+ break;
+ }
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_NE:
+ case TK_EQ: {
+ if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==STQLITE_SO_TEXT ){
+ /* Convert numeric comparison opcodes into text comparison opcodes.
+ ** This step depends on the fact that the text comparision opcodes are
+ ** always 6 greater than their corresponding numeric comparison
+ ** opcodes.
+ */
+ assert( OP_Eq+6 == OP_StrEq );
+ op += 6;
+ }
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteExprCode(pParse, pExpr->pRight);
+ sqliteVdbeAddOp(v, op, jumpIfNull, dest);
+ break;
+ }
+ case TK_ISNULL:
+ case TK_NOTNULL: {
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteVdbeAddOp(v, op, 1, dest);
+ break;
+ }
+ case TK_IN: {
+ int addr;
+ sqliteExprCode(pParse, pExpr->pLeft);
+ addr = sqliteVdbeCurrentAddr(v);
+ sqliteVdbeAddOp(v, OP_NotNull, -1, addr+3);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, jumpIfNull ? dest : addr+4);
+ if( pExpr->pSelect ){
+ sqliteVdbeAddOp(v, OP_NotFound, pExpr->iTable, dest);
+ }else{
+ sqliteVdbeAddOp(v, OP_SetNotFound, pExpr->iTable, dest);
+ }
+ break;
+ }
+ case TK_BETWEEN: {
+ int addr;
+ sqliteExprCode(pParse, pExpr->pLeft);
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
+ sqliteExprCode(pParse, pExpr->pList->a[0].pExpr);
+ addr = sqliteVdbeCurrentAddr(v);
+ sqliteVdbeAddOp(v, OP_Ge, !jumpIfNull, addr+3);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, dest);
+ sqliteExprCode(pParse, pExpr->pList->a[1].pExpr);
+ sqliteVdbeAddOp(v, OP_Gt, jumpIfNull, dest);
+ break;
+ }
+ default: {
+ sqliteExprCode(pParse, pExpr);
+ sqliteVdbeAddOp(v, OP_IfNot, jumpIfNull, dest);
+ break;
+ }
+ }
+}
+
+/*
+** Do a deep comparison of two expression trees. Return TRUE (non-zero)
+** if they are identical and return FALSE if they differ in any way.
+*/
+int sqliteExprCompare(Expr *pA, Expr *pB){
+ int i;
+ if( pA==0 ){
+ return pB==0;
+ }else if( pB==0 ){
+ return 0;
+ }
+ if( pA->op!=pB->op ) return 0;
+ if( !sqliteExprCompare(pA->pLeft, pB->pLeft) ) return 0;
+ if( !sqliteExprCompare(pA->pRight, pB->pRight) ) return 0;
+ if( pA->pList ){
+ if( pB->pList==0 ) return 0;
+ if( pA->pList->nExpr!=pB->pList->nExpr ) return 0;
+ for(i=0; i<pA->pList->nExpr; i++){
+ if( !sqliteExprCompare(pA->pList->a[i].pExpr, pB->pList->a[i].pExpr) ){
+ return 0;
+ }
+ }
+ }else if( pB->pList ){
+ return 0;
+ }
+ if( pA->pSelect || pB->pSelect ) return 0;
+ if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 0;
+ if( pA->token.z ){
+ if( pB->token.z==0 ) return 0;
+ if( pB->token.n!=pA->token.n ) return 0;
+ if( sqliteStrNICmp(pA->token.z, pB->token.z, pB->token.n)!=0 ) return 0;
+ }
+ return 1;
+}
+
+/*
+** Add a new element to the pParse->aAgg[] array and return its index.
+*/
+static int appendAggInfo(Parse *pParse){
+ if( (pParse->nAgg & 0x7)==0 ){
+ int amt = pParse->nAgg + 8;
+ AggExpr *aAgg = sqliteRealloc(pParse->aAgg, amt*sizeof(pParse->aAgg[0]));
+ if( aAgg==0 ){
+ return -1;
+ }
+ pParse->aAgg = aAgg;
+ }
+ memset(&pParse->aAgg[pParse->nAgg], 0, sizeof(pParse->aAgg[0]));
+ return pParse->nAgg++;
+}
+
+/*
+** Analyze the given expression looking for aggregate functions and
+** for variables that need to be added to the pParse->aAgg[] array.
+** Make additional entries to the pParse->aAgg[] array as necessary.
+**
+** This routine should only be called after the expression has been
+** analyzed by sqliteExprResolveIds() and sqliteExprCheck().
+**
+** If errors are seen, leave an error message in zErrMsg and return
+** the number of errors.
+*/
+int sqliteExprAnalyzeAggregates(Parse *pParse, Expr *pExpr){
+ int i;
+ AggExpr *aAgg;
+ int nErr = 0;
+
+ if( pExpr==0 ) return 0;
+ switch( pExpr->op ){
+ case TK_COLUMN: {
+ aAgg = pParse->aAgg;
+ for(i=0; i<pParse->nAgg; i++){
+ if( aAgg[i].isAgg ) continue;
+ if( aAgg[i].pExpr->iTable==pExpr->iTable
+ && aAgg[i].pExpr->iColumn==pExpr->iColumn ){
+ break;
+ }
+ }
+ if( i>=pParse->nAgg ){
+ i = appendAggInfo(pParse);
+ if( i<0 ) return 1;
+ pParse->aAgg[i].isAgg = 0;
+ pParse->aAgg[i].pExpr = pExpr;
+ }
+ pExpr->iAgg = i;
+ break;
+ }
+ case TK_AGG_FUNCTION: {
+ aAgg = pParse->aAgg;
+ for(i=0; i<pParse->nAgg; i++){
+ if( !aAgg[i].isAgg ) continue;
+ if( sqliteExprCompare(aAgg[i].pExpr, pExpr) ){
+ break;
+ }
+ }
+ if( i>=pParse->nAgg ){
+ i = appendAggInfo(pParse);
+ if( i<0 ) return 1;
+ pParse->aAgg[i].isAgg = 1;
+ pParse->aAgg[i].pExpr = pExpr;
+ pParse->aAgg[i].pFunc = sqliteFindFunction(pParse->db,
+ pExpr->token.z, pExpr->token.n,
+ pExpr->pList ? pExpr->pList->nExpr : 0, 0);
+ }
+ pExpr->iAgg = i;
+ break;
+ }
+ default: {
+ if( pExpr->pLeft ){
+ nErr = sqliteExprAnalyzeAggregates(pParse, pExpr->pLeft);
+ }
+ if( nErr==0 && pExpr->pRight ){
+ nErr = sqliteExprAnalyzeAggregates(pParse, pExpr->pRight);
+ }
+ if( nErr==0 && pExpr->pList ){
+ int n = pExpr->pList->nExpr;
+ int i;
+ for(i=0; nErr==0 && i<n; i++){
+ nErr = sqliteExprAnalyzeAggregates(pParse, pExpr->pList->a[i].pExpr);
+ }
+ }
+ break;
+ }
+ }
+ return nErr;
+}
+
+/*
+** Locate a user function given a name and a number of arguments.
+** Return a pointer to the FuncDef structure that defines that
+** function, or return NULL if the function does not exist.
+**
+** If the createFlag argument is true, then a new (blank) FuncDef
+** structure is created and liked into the "db" structure if a
+** no matching function previously existed. When createFlag is true
+** and the nArg parameter is -1, then only a function that accepts
+** any number of arguments will be returned.
+**
+** If createFlag is false and nArg is -1, then the first valid
+** function found is returned. A function is valid if either xFunc
+** or xStep is non-zero.
+*/
+FuncDef *sqliteFindFunction(
+ sqlite *db, /* An open database */
+ const char *zName, /* Name of the function. Not null-terminated */
+ int nName, /* Number of characters in the name */
+ int nArg, /* Number of arguments. -1 means any number */
+ int createFlag /* Create new entry if true and does not otherwise exist */
+){
+ FuncDef *pFirst, *p, *pMaybe;
+ pFirst = p = (FuncDef*)sqliteHashFind(&db->aFunc, zName, nName);
+ if( p && !createFlag && nArg<0 ){
+ while( p && p->xFunc==0 && p->xStep==0 ){ p = p->pNext; }
+ return p;
+ }
+ pMaybe = 0;
+ while( p && p->nArg!=nArg ){
+ if( p->nArg<0 && !createFlag && (p->xFunc || p->xStep) ) pMaybe = p;
+ p = p->pNext;
+ }
+ if( p && !createFlag && p->xFunc==0 && p->xStep==0 ){
+ return 0;
+ }
+ if( p==0 && pMaybe ){
+ assert( createFlag==0 );
+ return pMaybe;
+ }
+ if( p==0 && createFlag && (p = sqliteMalloc(sizeof(*p)))!=0 ){
+ p->nArg = nArg;
+ p->pNext = pFirst;
+ p->dataType = pFirst ? pFirst->dataType : STQLITE_NUMERIC;
+ sqliteHashInsert(&db->aFunc, zName, nName, (void*)p);
+ }
+ return p;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/func.c b/tqtinterface/qt4/src/3rdparty/sqlite/func.c
new file mode 100644
index 0000000..acfb381
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/func.c
@@ -0,0 +1,646 @@
+/*
+** 2002 February 23
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains the C functions that implement various SQL
+** functions of STQLite.
+**
+** There is only one exported symbol in this file - the function
+** sqliteRegisterBuildinFunctions() found at the bottom of the file.
+** All other code has file scope.
+**
+** $Id: func.c,v 1.43 2004/02/25 22:51:06 rdc Exp $
+*/
+#include <ctype.h>
+#include <math.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "sqliteInt.h"
+#include "os.h"
+
+/*
+** Implementation of the non-aggregate min() and max() functions
+*/
+static void minmaxFunc(sqlite_func *context, int argc, const char **argv){
+ const char *zBest;
+ int i;
+ int (*xCompare)(const char*, const char*);
+ int tqmask; /* 0 for min() or 0xffffffff for max() */
+
+ if( argc==0 ) return;
+ tqmask = (int)sqlite_user_data(context);
+ zBest = argv[0];
+ if( zBest==0 ) return;
+ if( argv[1][0]=='n' ){
+ xCompare = sqliteCompare;
+ }else{
+ xCompare = strcmp;
+ }
+ for(i=2; i<argc; i+=2){
+ if( argv[i]==0 ) return;
+ if( (xCompare(argv[i], zBest)^tqmask)<0 ){
+ zBest = argv[i];
+ }
+ }
+ sqlite_set_result_string(context, zBest, -1);
+}
+
+/*
+** Return the type of the argument.
+*/
+static void typeofFunc(sqlite_func *context, int argc, const char **argv){
+ assert( argc==2 );
+ sqlite_set_result_string(context, argv[1], -1);
+}
+
+/*
+** Implementation of the length() function
+*/
+static void lengthFunc(sqlite_func *context, int argc, const char **argv){
+ const char *z;
+ int len;
+
+ assert( argc==1 );
+ z = argv[0];
+ if( z==0 ) return;
+#ifdef STQLITE_UTF8
+ for(len=0; *z; z++){ if( (0xc0&*z)!=0x80 ) len++; }
+#else
+ len = strlen(z);
+#endif
+ sqlite_set_result_int(context, len);
+}
+
+/*
+** Implementation of the abs() function
+*/
+static void absFunc(sqlite_func *context, int argc, const char **argv){
+ const char *z;
+ assert( argc==1 );
+ z = argv[0];
+ if( z==0 ) return;
+ if( z[0]=='-' && isdigit(z[1]) ) z++;
+ sqlite_set_result_string(context, z, -1);
+}
+
+/*
+** Implementation of the substr() function
+*/
+static void substrFunc(sqlite_func *context, int argc, const char **argv){
+ const char *z;
+#ifdef STQLITE_UTF8
+ const char *z2;
+ int i;
+#endif
+ int p1, p2, len;
+ assert( argc==3 );
+ z = argv[0];
+ if( z==0 ) return;
+ p1 = atoi(argv[1]?argv[1]:0);
+ p2 = atoi(argv[2]?argv[2]:0);
+#ifdef STQLITE_UTF8
+ for(len=0, z2=z; *z2; z2++){ if( (0xc0&*z2)!=0x80 ) len++; }
+#else
+ len = strlen(z);
+#endif
+ if( p1<0 ){
+ p1 += len;
+ if( p1<0 ){
+ p2 += p1;
+ p1 = 0;
+ }
+ }else if( p1>0 ){
+ p1--;
+ }
+ if( p1+p2>len ){
+ p2 = len-p1;
+ }
+#ifdef STQLITE_UTF8
+ for(i=0; i<p1 && z[i]; i++){
+ if( (z[i]&0xc0)==0x80 ) p1++;
+ }
+ while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p1++; }
+ for(; i<p1+p2 && z[i]; i++){
+ if( (z[i]&0xc0)==0x80 ) p2++;
+ }
+ while( z[i] && (z[i]&0xc0)==0x80 ){ i++; p2++; }
+#endif
+ if( p2<0 ) p2 = 0;
+ sqlite_set_result_string(context, &z[p1], p2);
+}
+
+/*
+** Implementation of the round() function
+*/
+static void roundFunc(sqlite_func *context, int argc, const char **argv){
+ int n;
+ double r;
+ char zBuf[100];
+ assert( argc==1 || argc==2 );
+ if( argv[0]==0 || (argc==2 && argv[1]==0) ) return;
+ n = argc==2 ? atoi(argv[1]) : 0;
+ if( n>30 ) n = 30;
+ if( n<0 ) n = 0;
+ r = sqliteAtoF(argv[0], 0);
+ sprintf(zBuf,"%.*f",n,r);
+ sqlite_set_result_string(context, zBuf, -1);
+}
+
+/*
+** Implementation of the upper() and lower() SQL functions.
+*/
+static void upperFunc(sqlite_func *context, int argc, const char **argv){
+ char *z;
+ int i;
+ if( argc<1 || argv[0]==0 ) return;
+ z = sqlite_set_result_string(context, argv[0], -1);
+ if( z==0 ) return;
+ for(i=0; z[i]; i++){
+ if( islower(z[i]) ) z[i] = toupper(z[i]);
+ }
+}
+static void lowerFunc(sqlite_func *context, int argc, const char **argv){
+ char *z;
+ int i;
+ if( argc<1 || argv[0]==0 ) return;
+ z = sqlite_set_result_string(context, argv[0], -1);
+ if( z==0 ) return;
+ for(i=0; z[i]; i++){
+ if( isupper(z[i]) ) z[i] = tolower(z[i]);
+ }
+}
+
+/*
+** Implementation of the IFNULL(), NVL(), and COALESCE() functions.
+** All three do the same thing. They return the first non-NULL
+** argument.
+*/
+static void ifnullFunc(sqlite_func *context, int argc, const char **argv){
+ int i;
+ for(i=0; i<argc; i++){
+ if( argv[i] ){
+ sqlite_set_result_string(context, argv[i], -1);
+ break;
+ }
+ }
+}
+
+/*
+** Implementation of random(). Return a random integer.
+*/
+static void randomFunc(sqlite_func *context, int argc, const char **argv){
+ int r;
+ sqliteRandomness(sizeof(r), &r);
+ sqlite_set_result_int(context, r);
+}
+
+/*
+** Implementation of the last_insert_rowid() SQL function. The return
+** value is the same as the sqlite_last_insert_rowid() API function.
+*/
+static void last_insert_rowid(sqlite_func *context, int arg, const char **argv){
+ sqlite *db = sqlite_user_data(context);
+ sqlite_set_result_int(context, sqlite_last_insert_rowid(db));
+}
+
+/*
+** Implementation of the change_count() SQL function. The return
+** value is the same as the sqlite_changes() API function.
+*/
+static void change_count(sqlite_func *context, int arg, const char **argv){
+ sqlite *db = sqlite_user_data(context);
+ sqlite_set_result_int(context, sqlite_changes(db));
+}
+
+/*
+** Implementation of the last_statement_change_count() SQL function. The
+** return value is the same as the sqlite_last_statement_changes() API function.
+*/
+static void last_statement_change_count(sqlite_func *context, int arg,
+ const char **argv){
+ sqlite *db = sqlite_user_data(context);
+ sqlite_set_result_int(context, sqlite_last_statement_changes(db));
+}
+
+/*
+** Implementation of the like() SQL function. This function implements
+** the build-in LIKE operator. The first argument to the function is the
+** string and the second argument is the pattern. So, the SQL statements:
+**
+** A LIKE B
+**
+** is implemented as like(A,B).
+*/
+static void likeFunc(sqlite_func *context, int arg, const char **argv){
+ if( argv[0]==0 || argv[1]==0 ) return;
+ sqlite_set_result_int(context,
+ sqliteLikeCompare((const unsigned char*)argv[0],
+ (const unsigned char*)argv[1]));
+}
+
+/*
+** Implementation of the glob() SQL function. This function implements
+** the build-in GLOB operator. The first argument to the function is the
+** string and the second argument is the pattern. So, the SQL statements:
+**
+** A GLOB B
+**
+** is implemented as glob(A,B).
+*/
+static void globFunc(sqlite_func *context, int arg, const char **argv){
+ if( argv[0]==0 || argv[1]==0 ) return;
+ sqlite_set_result_int(context,
+ sqliteGlobCompare((const unsigned char*)argv[0],
+ (const unsigned char*)argv[1]));
+}
+
+/*
+** Implementation of the NULLIF(x,y) function. The result is the first
+** argument if the arguments are different. The result is NULL if the
+** arguments are equal to each other.
+*/
+static void nullifFunc(sqlite_func *context, int argc, const char **argv){
+ if( argv[0]!=0 && sqliteCompare(argv[0],argv[1])!=0 ){
+ sqlite_set_result_string(context, argv[0], -1);
+ }
+}
+
+/*
+** Implementation of the VERSION(*) function. The result is the version
+** of the STQLite library that is running.
+*/
+static void versionFunc(sqlite_func *context, int argc, const char **argv){
+ sqlite_set_result_string(context, sqlite_version, -1);
+}
+
+/*
+** EXPERIMENTAL - This is not an official function. The interface may
+** change. This function may disappear. Do not write code that depends
+** on this function.
+**
+** Implementation of the TQUOTE() function. This function takes a single
+** argument. If the argument is numeric, the return value is the same as
+** the argument. If the argument is NULL, the return value is the string
+** "NULL". Otherwise, the argument is enclosed in single quotes with
+** single-quote escapes.
+*/
+static void quoteFunc(sqlite_func *context, int argc, const char **argv){
+ if( argc<1 ) return;
+ if( argv[0]==0 ){
+ sqlite_set_result_string(context, "NULL", 4);
+ }else if( sqliteIsNumber(argv[0]) ){
+ sqlite_set_result_string(context, argv[0], -1);
+ }else{
+ int i,j,n;
+ char *z;
+ for(i=n=0; argv[0][i]; i++){ if( argv[0][i]=='\'' ) n++; }
+ z = sqliteMalloc( i+n+3 );
+ if( z==0 ) return;
+ z[0] = '\'';
+ for(i=0, j=1; argv[0][i]; i++){
+ z[j++] = argv[0][i];
+ if( argv[0][i]=='\'' ){
+ z[j++] = '\'';
+ }
+ }
+ z[j++] = '\'';
+ z[j] = 0;
+ sqlite_set_result_string(context, z, j);
+ sqliteFree(z);
+ }
+}
+
+#ifdef STQLITE_SOUNDEX
+/*
+** Compute the soundex encoding of a word.
+*/
+static void soundexFunc(sqlite_func *context, int argc, const char **argv){
+ char zResult[8];
+ const char *zIn;
+ int i, j;
+ static const unsigned char iCode[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
+ 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 3, 0, 1, 2, 0, 0, 2, 2, 4, 5, 5, 0,
+ 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0,
+ };
+ assert( argc==1 );
+ zIn = argv[0];
+ for(i=0; zIn[i] && !isalpha(zIn[i]); i++){}
+ if( zIn[i] ){
+ zResult[0] = toupper(zIn[i]);
+ for(j=1; j<4 && zIn[i]; i++){
+ int code = iCode[zIn[i]&0x7f];
+ if( code>0 ){
+ zResult[j++] = code + '0';
+ }
+ }
+ while( j<4 ){
+ zResult[j++] = '0';
+ }
+ zResult[j] = 0;
+ sqlite_set_result_string(context, zResult, 4);
+ }else{
+ sqlite_set_result_string(context, "?000", 4);
+ }
+}
+#endif
+
+#ifdef STQLITE_TEST
+/*
+** This function generates a string of random characters. Used for
+** generating test data.
+*/
+static void randStr(sqlite_func *context, int argc, const char **argv){
+ static const unsigned char zSrc[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPTQRSTUVWXYZ"
+ "0123456789"
+ ".-!,:*^+=_|?/<> ";
+ int iMin, iMax, n, r, i;
+ unsigned char zBuf[1000];
+ if( argc>=1 ){
+ iMin = atoi(argv[0]);
+ if( iMin<0 ) iMin = 0;
+ if( iMin>=sizeof(zBuf) ) iMin = sizeof(zBuf)-1;
+ }else{
+ iMin = 1;
+ }
+ if( argc>=2 ){
+ iMax = atoi(argv[1]);
+ if( iMax<iMin ) iMax = iMin;
+ if( iMax>=sizeof(zBuf) ) iMax = sizeof(zBuf)-1;
+ }else{
+ iMax = 50;
+ }
+ n = iMin;
+ if( iMax>iMin ){
+ sqliteRandomness(sizeof(r), &r);
+ r &= 0x7fffffff;
+ n += r%(iMax + 1 - iMin);
+ }
+ assert( n<sizeof(zBuf) );
+ sqliteRandomness(n, zBuf);
+ for(i=0; i<n; i++){
+ zBuf[i] = zSrc[zBuf[i]%(sizeof(zSrc)-1)];
+ }
+ zBuf[n] = 0;
+ sqlite_set_result_string(context, zBuf, n);
+}
+#endif
+
+/*
+** An instance of the following structure holds the context of a
+** sum() or avg() aggregate computation.
+*/
+typedef struct SumCtx SumCtx;
+struct SumCtx {
+ double sum; /* Sum of terms */
+ int cnt; /* Number of elements summed */
+};
+
+/*
+** Routines used to compute the sum or average.
+*/
+static void sumStep(sqlite_func *context, int argc, const char **argv){
+ SumCtx *p;
+ if( argc<1 ) return;
+ p = sqlite_aggregate_context(context, sizeof(*p));
+ if( p && argv[0] ){
+ p->sum += sqliteAtoF(argv[0], 0);
+ p->cnt++;
+ }
+}
+static void sumFinalize(sqlite_func *context){
+ SumCtx *p;
+ p = sqlite_aggregate_context(context, sizeof(*p));
+ sqlite_set_result_double(context, p ? p->sum : 0.0);
+}
+static void avgFinalize(sqlite_func *context){
+ SumCtx *p;
+ p = sqlite_aggregate_context(context, sizeof(*p));
+ if( p && p->cnt>0 ){
+ sqlite_set_result_double(context, p->sum/(double)p->cnt);
+ }
+}
+
+/*
+** An instance of the following structure holds the context of a
+** variance or standard deviation computation.
+*/
+typedef struct StdDevCtx StdDevCtx;
+struct StdDevCtx {
+ double sum; /* Sum of terms */
+ double sum2; /* Sum of the squares of terms */
+ int cnt; /* Number of terms counted */
+};
+
+#if 0 /* Omit because math library is required */
+/*
+** Routines used to compute the standard deviation as an aggregate.
+*/
+static void stdDevStep(sqlite_func *context, int argc, const char **argv){
+ StdDevCtx *p;
+ double x;
+ if( argc<1 ) return;
+ p = sqlite_aggregate_context(context, sizeof(*p));
+ if( p && argv[0] ){
+ x = sqliteAtoF(argv[0], 0);
+ p->sum += x;
+ p->sum2 += x*x;
+ p->cnt++;
+ }
+}
+static void stdDevFinalize(sqlite_func *context){
+ double rN = sqlite_aggregate_count(context);
+ StdDevCtx *p = sqlite_aggregate_context(context, sizeof(*p));
+ if( p && p->cnt>1 ){
+ double rCnt = cnt;
+ sqlite_set_result_double(context,
+ sqrt((p->sum2 - p->sum*p->sum/rCnt)/(rCnt-1.0)));
+ }
+}
+#endif
+
+/*
+** The following structure keeps track of state information for the
+** count() aggregate function.
+*/
+typedef struct CountCtx CountCtx;
+struct CountCtx {
+ int n;
+};
+
+/*
+** Routines to implement the count() aggregate function.
+*/
+static void countStep(sqlite_func *context, int argc, const char **argv){
+ CountCtx *p;
+ p = sqlite_aggregate_context(context, sizeof(*p));
+ if( (argc==0 || argv[0]) && p ){
+ p->n++;
+ }
+}
+static void countFinalize(sqlite_func *context){
+ CountCtx *p;
+ p = sqlite_aggregate_context(context, sizeof(*p));
+ sqlite_set_result_int(context, p ? p->n : 0);
+}
+
+/*
+** This function tracks state information for the min() and max()
+** aggregate functions.
+*/
+typedef struct MinMaxCtx MinMaxCtx;
+struct MinMaxCtx {
+ char *z; /* The best so far */
+ char zBuf[28]; /* Space that can be used for storage */
+};
+
+/*
+** Routines to implement min() and max() aggregate functions.
+*/
+static void minmaxStep(sqlite_func *context, int argc, const char **argv){
+ MinMaxCtx *p;
+ int (*xCompare)(const char*, const char*);
+ int tqmask; /* 0 for min() or 0xffffffff for max() */
+
+ assert( argc==2 );
+ if( argv[1][0]=='n' ){
+ xCompare = sqliteCompare;
+ }else{
+ xCompare = strcmp;
+ }
+ tqmask = (int)sqlite_user_data(context);
+ p = sqlite_aggregate_context(context, sizeof(*p));
+ if( p==0 || argc<1 || argv[0]==0 ) return;
+ if( p->z==0 || (xCompare(argv[0],p->z)^tqmask)<0 ){
+ int len;
+ if( !p->zBuf[0] ){
+ sqliteFree(p->z);
+ }
+ len = strlen(argv[0]);
+ if( len < sizeof(p->zBuf)-1 ){
+ p->z = &p->zBuf[1];
+ p->zBuf[0] = 1;
+ }else{
+ p->z = sqliteMalloc( len+1 );
+ p->zBuf[0] = 0;
+ if( p->z==0 ) return;
+ }
+ strcpy(p->z, argv[0]);
+ }
+}
+static void minMaxFinalize(sqlite_func *context){
+ MinMaxCtx *p;
+ p = sqlite_aggregate_context(context, sizeof(*p));
+ if( p && p->z ){
+ sqlite_set_result_string(context, p->z, strlen(p->z));
+ }
+ if( p && !p->zBuf[0] ){
+ sqliteFree(p->z);
+ }
+}
+
+/*
+** This function registered all of the above C functions as SQL
+** functions. This should be the only routine in this file with
+** external linkage.
+*/
+void sqliteRegisterBuiltinFunctions(sqlite *db){
+ static struct {
+ char *zName;
+ signed char nArg;
+ signed char dataType;
+ u8 argType; /* 0: none. 1: db 2: (-1) */
+ void (*xFunc)(sqlite_func*,int,const char**);
+ } aFuncs[] = {
+ { "min", -1, STQLITE_ARGS, 0, minmaxFunc },
+ { "min", 0, 0, 0, 0 },
+ { "max", -1, STQLITE_ARGS, 2, minmaxFunc },
+ { "max", 0, 0, 2, 0 },
+ { "typeof", 1, STQLITE_TEXT, 0, typeofFunc },
+ { "length", 1, STQLITE_NUMERIC, 0, lengthFunc },
+ { "substr", 3, STQLITE_TEXT, 0, substrFunc },
+ { "abs", 1, STQLITE_NUMERIC, 0, absFunc },
+ { "round", 1, STQLITE_NUMERIC, 0, roundFunc },
+ { "round", 2, STQLITE_NUMERIC, 0, roundFunc },
+ { "upper", 1, STQLITE_TEXT, 0, upperFunc },
+ { "lower", 1, STQLITE_TEXT, 0, lowerFunc },
+ { "coalesce", -1, STQLITE_ARGS, 0, ifnullFunc },
+ { "coalesce", 0, 0, 0, 0 },
+ { "coalesce", 1, 0, 0, 0 },
+ { "ifnull", 2, STQLITE_ARGS, 0, ifnullFunc },
+ { "random", -1, STQLITE_NUMERIC, 0, randomFunc },
+ { "like", 2, STQLITE_NUMERIC, 0, likeFunc },
+ { "glob", 2, STQLITE_NUMERIC, 0, globFunc },
+ { "nullif", 2, STQLITE_ARGS, 0, nullifFunc },
+ { "sqlite_version",0,STQLITE_TEXT, 0, versionFunc},
+ { "quote", 1, STQLITE_ARGS, 0, quoteFunc },
+ { "last_insert_rowid", 0, STQLITE_NUMERIC, 1, last_insert_rowid },
+ { "change_count", 0, STQLITE_NUMERIC, 1, change_count },
+ { "last_statement_change_count",
+ 0, STQLITE_NUMERIC, 1, last_statement_change_count },
+#ifdef STQLITE_SOUNDEX
+ { "soundex", 1, STQLITE_TEXT, 0, soundexFunc},
+#endif
+#ifdef STQLITE_TEST
+ { "randstr", 2, STQLITE_TEXT, 0, randStr },
+#endif
+ };
+ static struct {
+ char *zName;
+ signed char nArg;
+ signed char dataType;
+ u8 argType;
+ void (*xStep)(sqlite_func*,int,const char**);
+ void (*xFinalize)(sqlite_func*);
+ } aAggs[] = {
+ { "min", 1, 0, 0, minmaxStep, minMaxFinalize },
+ { "max", 1, 0, 2, minmaxStep, minMaxFinalize },
+ { "sum", 1, STQLITE_NUMERIC, 0, sumStep, sumFinalize },
+ { "avg", 1, STQLITE_NUMERIC, 0, sumStep, avgFinalize },
+ { "count", 0, STQLITE_NUMERIC, 0, countStep, countFinalize },
+ { "count", 1, STQLITE_NUMERIC, 0, countStep, countFinalize },
+#if 0
+ { "stddev", 1, STQLITE_NUMERIC, 0, stdDevStep, stdDevFinalize },
+#endif
+ };
+ static const char *azTypeFuncs[] = { "min", "max", "typeof" };
+ int i;
+
+ for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
+ void *pArg = aFuncs[i].argType==2 ? (void*)(-1) : db;
+ sqlite_create_function(db, aFuncs[i].zName,
+ aFuncs[i].nArg, aFuncs[i].xFunc, pArg);
+ if( aFuncs[i].xFunc ){
+ sqlite_function_type(db, aFuncs[i].zName, aFuncs[i].dataType);
+ }
+ }
+ for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
+ void *pArg = aAggs[i].argType==2 ? (void*)(-1) : db;
+ sqlite_create_aggregate(db, aAggs[i].zName,
+ aAggs[i].nArg, aAggs[i].xStep, aAggs[i].xFinalize, pArg);
+ sqlite_function_type(db, aAggs[i].zName, aAggs[i].dataType);
+ }
+ for(i=0; i<sizeof(azTypeFuncs)/sizeof(azTypeFuncs[0]); i++){
+ int n = strlen(azTypeFuncs[i]);
+ FuncDef *p = sqliteHashFind(&db->aFunc, azTypeFuncs[i], n);
+ while( p ){
+ p->includeTypes = 1;
+ p = p->pNext;
+ }
+ }
+ sqliteRegisterDateTimeFunctions(db);
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/hash.c b/tqtinterface/qt4/src/3rdparty/sqlite/hash.c
new file mode 100644
index 0000000..06650c1
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/hash.c
@@ -0,0 +1,356 @@
+/*
+** 2001 September 22
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This is the implementation of generic hash-tables
+** used in STQLite.
+**
+** $Id: hash.c,v 1.11 2004/01/08 02:17:33 drh Exp $
+*/
+#include "sqliteInt.h"
+#include <assert.h>
+
+/* Turn bulk memory into a hash table object by initializing the
+** fields of the Hash structure.
+**
+** "new" is a pointer to the hash table that is to be initialized.
+** keyClass is one of the constants STQLITE_HASH_INT, STQLITE_HASH_POINTER,
+** STQLITE_HASH_BINARY, or STQLITE_HASH_STRING. The value of keyClass
+** determines what kind of key the hash table will use. "copyKey" is
+** true if the hash table should make its own private copy of keys and
+** false if it should just use the supplied pointer. CopyKey only makes
+** sense for STQLITE_HASH_STRING and STQLITE_HASH_BINARY and is ignored
+** for other key classes.
+*/
+void sqliteHashInit(Hash *new, int keyClass, int copyKey){
+ assert( new!=0 );
+ assert( keyClass>=STQLITE_HASH_INT && keyClass<=STQLITE_HASH_BINARY );
+ new->keyClass = keyClass;
+ new->copyKey = copyKey &&
+ (keyClass==STQLITE_HASH_STRING || keyClass==STQLITE_HASH_BINARY);
+ new->first = 0;
+ new->count = 0;
+ new->htsize = 0;
+ new->ht = 0;
+}
+
+/* Remove all entries from a hash table. Reclaim all memory.
+** Call this routine to delete a hash table or to reset a hash table
+** to the empty state.
+*/
+void sqliteHashClear(Hash *pH){
+ HashElem *elem; /* For looping over all elements of the table */
+
+ assert( pH!=0 );
+ elem = pH->first;
+ pH->first = 0;
+ if( pH->ht ) sqliteFree(pH->ht);
+ pH->ht = 0;
+ pH->htsize = 0;
+ while( elem ){
+ HashElem *next_elem = elem->next;
+ if( pH->copyKey && elem->pKey ){
+ sqliteFree(elem->pKey);
+ }
+ sqliteFree(elem);
+ elem = next_elem;
+ }
+ pH->count = 0;
+}
+
+/*
+** Hash and comparison functions when the mode is STQLITE_HASH_INT
+*/
+static int intHash(const void *pKey, int nKey){
+ return nKey ^ (nKey<<8) ^ (nKey>>8);
+}
+static int intCompare(const void *pKey1, int n1, const void *pKey2, int n2){
+ return n2 - n1;
+}
+
+#if 0 /* NOT USED */
+/*
+** Hash and comparison functions when the mode is STQLITE_HASH_POINTER
+*/
+static int ptrHash(const void *pKey, int nKey){
+ uptr x = Addr(pKey);
+ return x ^ (x<<8) ^ (x>>8);
+}
+static int ptrCompare(const void *pKey1, int n1, const void *pKey2, int n2){
+ if( pKey1==pKey2 ) return 0;
+ if( pKey1<pKey2 ) return -1;
+ return 1;
+}
+#endif
+
+/*
+** Hash and comparison functions when the mode is STQLITE_HASH_STRING
+*/
+static int strHash(const void *pKey, int nKey){
+ return sqliteHashNoCase((const char*)pKey, nKey);
+}
+static int strCompare(const void *pKey1, int n1, const void *pKey2, int n2){
+ if( n1!=n2 ) return n2-n1;
+ return sqliteStrNICmp((const char*)pKey1,(const char*)pKey2,n1);
+}
+
+/*
+** Hash and comparison functions when the mode is STQLITE_HASH_BINARY
+*/
+static int binHash(const void *pKey, int nKey){
+ int h = 0;
+ const char *z = (const char *)pKey;
+ while( nKey-- > 0 ){
+ h = (h<<3) ^ h ^ *(z++);
+ }
+ return h & 0x7fffffff;
+}
+static int binCompare(const void *pKey1, int n1, const void *pKey2, int n2){
+ if( n1!=n2 ) return n2-n1;
+ return memcmp(pKey1,pKey2,n1);
+}
+
+/*
+** Return a pointer to the appropriate hash function given the key class.
+**
+** The C syntax in this function definition may be unfamilar to some
+** programmers, so we provide the following additional explanation:
+**
+** The name of the function is "hashFunction". The function takes a
+** single parameter "keyClass". The return value of hashFunction()
+** is a pointer to another function. Specifically, the return value
+** of hashFunction() is a pointer to a function that takes two parameters
+** with types "const void*" and "int" and returns an "int".
+*/
+static int (*hashFunction(int keyClass))(const void*,int){
+ switch( keyClass ){
+ case STQLITE_HASH_INT: return &intHash;
+ /* case STQLITE_HASH_POINTER: return &ptrHash; // NOT USED */
+ case STQLITE_HASH_STRING: return &strHash;
+ case STQLITE_HASH_BINARY: return &binHash;;
+ default: break;
+ }
+ return 0;
+}
+
+/*
+** Return a pointer to the appropriate hash function given the key class.
+**
+** For help in interpreted the obscure C code in the function definition,
+** see the header comment on the previous function.
+*/
+static int (*compareFunction(int keyClass))(const void*,int,const void*,int){
+ switch( keyClass ){
+ case STQLITE_HASH_INT: return &intCompare;
+ /* case STQLITE_HASH_POINTER: return &ptrCompare; // NOT USED */
+ case STQLITE_HASH_STRING: return &strCompare;
+ case STQLITE_HASH_BINARY: return &binCompare;
+ default: break;
+ }
+ return 0;
+}
+
+
+/* Resize the hash table so that it cantains "new_size" buckets.
+** "new_size" must be a power of 2. The hash table might fail
+** to resize if sqliteMalloc() fails.
+*/
+static void rehash(Hash *pH, int new_size){
+ struct _ht *new_ht; /* The new hash table */
+ HashElem *elem, *next_elem; /* For looping over existing elements */
+ HashElem *x; /* Element being copied to new hash table */
+ int (*xHash)(const void*,int); /* The hash function */
+
+ assert( (new_size & (new_size-1))==0 );
+ new_ht = (struct _ht *)sqliteMalloc( new_size*sizeof(struct _ht) );
+ if( new_ht==0 ) return;
+ if( pH->ht ) sqliteFree(pH->ht);
+ pH->ht = new_ht;
+ pH->htsize = new_size;
+ xHash = hashFunction(pH->keyClass);
+ for(elem=pH->first, pH->first=0; elem; elem = next_elem){
+ int h = (*xHash)(elem->pKey, elem->nKey) & (new_size-1);
+ next_elem = elem->next;
+ x = new_ht[h].chain;
+ if( x ){
+ elem->next = x;
+ elem->prev = x->prev;
+ if( x->prev ) x->prev->next = elem;
+ else pH->first = elem;
+ x->prev = elem;
+ }else{
+ elem->next = pH->first;
+ if( pH->first ) pH->first->prev = elem;
+ elem->prev = 0;
+ pH->first = elem;
+ }
+ new_ht[h].chain = elem;
+ new_ht[h].count++;
+ }
+}
+
+/* This function (for internal use only) locates an element in an
+** hash table that matches the given key. The hash for this key has
+** already been computed and is passed as the 4th parameter.
+*/
+static HashElem *tqfindElementGivenHash(
+ const Hash *pH, /* The pH to be searched */
+ const void *pKey, /* The key we are searching for */
+ int nKey,
+ int h /* The hash for this key. */
+){
+ HashElem *elem; /* Used to loop thru the element list */
+ int count; /* Number of elements left to test */
+ int (*xCompare)(const void*,int,const void*,int); /* comparison function */
+
+ if( pH->ht ){
+ elem = pH->ht[h].chain;
+ count = pH->ht[h].count;
+ xCompare = compareFunction(pH->keyClass);
+ while( count-- && elem ){
+ if( (*xCompare)(elem->pKey,elem->nKey,pKey,nKey)==0 ){
+ return elem;
+ }
+ elem = elem->next;
+ }
+ }
+ return 0;
+}
+
+/* Remove a single entry from the hash table given a pointer to that
+** element and a hash on the element's key.
+*/
+static void removeElementGivenHash(
+ Hash *pH, /* The pH containing "elem" */
+ HashElem* elem, /* The element to be removed from the pH */
+ int h /* Hash value for the element */
+){
+ if( elem->prev ){
+ elem->prev->next = elem->next;
+ }else{
+ pH->first = elem->next;
+ }
+ if( elem->next ){
+ elem->next->prev = elem->prev;
+ }
+ if( pH->ht[h].chain==elem ){
+ pH->ht[h].chain = elem->next;
+ }
+ pH->ht[h].count--;
+ if( pH->ht[h].count<=0 ){
+ pH->ht[h].chain = 0;
+ }
+ if( pH->copyKey && elem->pKey ){
+ sqliteFree(elem->pKey);
+ }
+ sqliteFree( elem );
+ pH->count--;
+}
+
+/* Attempt to locate an element of the hash table pH with a key
+** that matches pKey,nKey. Return the data for this element if it is
+** found, or NULL if there is no match.
+*/
+void *sqliteHashFind(const Hash *pH, const void *pKey, int nKey){
+ int h; /* A hash on key */
+ HashElem *elem; /* The element that matches key */
+ int (*xHash)(const void*,int); /* The hash function */
+
+ if( pH==0 || pH->ht==0 ) return 0;
+ xHash = hashFunction(pH->keyClass);
+ assert( xHash!=0 );
+ h = (*xHash)(pKey,nKey);
+ assert( (pH->htsize & (pH->htsize-1))==0 );
+ elem = tqfindElementGivenHash(pH,pKey,nKey, h & (pH->htsize-1));
+ return elem ? elem->data : 0;
+}
+
+/* Insert an element into the hash table pH. The key is pKey,nKey
+** and the data is "data".
+**
+** If no element exists with a matching key, then a new
+** element is created. A copy of the key is made if the copyKey
+** flag is set. NULL is returned.
+**
+** If another element already exists with the same key, then the
+** new data tqreplaces the old data and the old data is returned.
+** The key is not copied in this instance. If a malloc fails, then
+** the new data is returned and the hash table is unchanged.
+**
+** If the "data" parameter to this function is NULL, then the
+** element corresponding to "key" is removed from the hash table.
+*/
+void *sqliteHashInsert(Hash *pH, const void *pKey, int nKey, void *data){
+ int hraw; /* Raw hash value of the key */
+ int h; /* the hash of the key modulo hash table size */
+ HashElem *elem; /* Used to loop thru the element list */
+ HashElem *new_elem; /* New element added to the pH */
+ int (*xHash)(const void*,int); /* The hash function */
+
+ assert( pH!=0 );
+ xHash = hashFunction(pH->keyClass);
+ assert( xHash!=0 );
+ hraw = (*xHash)(pKey, nKey);
+ assert( (pH->htsize & (pH->htsize-1))==0 );
+ h = hraw & (pH->htsize-1);
+ elem = tqfindElementGivenHash(pH,pKey,nKey,h);
+ if( elem ){
+ void *old_data = elem->data;
+ if( data==0 ){
+ removeElementGivenHash(pH,elem,h);
+ }else{
+ elem->data = data;
+ }
+ return old_data;
+ }
+ if( data==0 ) return 0;
+ new_elem = (HashElem*)sqliteMalloc( sizeof(HashElem) );
+ if( new_elem==0 ) return data;
+ if( pH->copyKey && pKey!=0 ){
+ new_elem->pKey = sqliteMallocRaw( nKey );
+ if( new_elem->pKey==0 ){
+ sqliteFree(new_elem);
+ return data;
+ }
+ memcpy((void*)new_elem->pKey, pKey, nKey);
+ }else{
+ new_elem->pKey = (void*)pKey;
+ }
+ new_elem->nKey = nKey;
+ pH->count++;
+ if( pH->htsize==0 ) rehash(pH,8);
+ if( pH->htsize==0 ){
+ pH->count = 0;
+ sqliteFree(new_elem);
+ return data;
+ }
+ if( pH->count > pH->htsize ){
+ rehash(pH,pH->htsize*2);
+ }
+ assert( (pH->htsize & (pH->htsize-1))==0 );
+ h = hraw & (pH->htsize-1);
+ elem = pH->ht[h].chain;
+ if( elem ){
+ new_elem->next = elem;
+ new_elem->prev = elem->prev;
+ if( elem->prev ){ elem->prev->next = new_elem; }
+ else { pH->first = new_elem; }
+ elem->prev = new_elem;
+ }else{
+ new_elem->next = pH->first;
+ new_elem->prev = 0;
+ if( pH->first ){ pH->first->prev = new_elem; }
+ pH->first = new_elem;
+ }
+ pH->ht[h].count++;
+ pH->ht[h].chain = new_elem;
+ new_elem->data = data;
+ return 0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/hash.h b/tqtinterface/qt4/src/3rdparty/sqlite/hash.h
new file mode 100644
index 0000000..e462bd6
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/hash.h
@@ -0,0 +1,109 @@
+/*
+** 2001 September 22
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This is the header file for the generic hash-table implemenation
+** used in STQLite.
+**
+** $Id: hash.h,v 1.6 2004/01/08 02:17:33 drh Exp $
+*/
+#ifndef _STQLITE_HASH_H_
+#define _STQLITE_HASH_H_
+
+/* Forward declarations of structures. */
+typedef struct Hash Hash;
+typedef struct HashElem HashElem;
+
+/* A complete hash table is an instance of the following structure.
+** The internals of this structure are intended to be opaque -- client
+** code should not attempt to access or modify the fields of this structure
+** directly. Change this structure only by using the routines below.
+** However, many of the "procedures" and "functions" for modifying and
+** accessing this structure are really macros, so we can't really make
+** this structure opaque.
+*/
+struct Hash {
+ char keyClass; /* STQLITE_HASH_INT, _POINTER, _STRING, _BINARY */
+ char copyKey; /* True if copy of key made on insert */
+ int count; /* Number of entries in this table */
+ HashElem *first; /* The first element of the array */
+ int htsize; /* Number of buckets in the hash table */
+ struct _ht { /* the hash table */
+ int count; /* Number of entries with this hash */
+ HashElem *chain; /* Pointer to first entry with this hash */
+ } *ht;
+};
+
+/* Each element in the hash table is an instance of the following
+** structure. All elements are stored on a single doubly-linked list.
+**
+** Again, this structure is intended to be opaque, but it can't really
+** be opaque because it is used by macros.
+*/
+struct HashElem {
+ HashElem *next, *prev; /* Next and previous elements in the table */
+ void *data; /* Data associated with this element */
+ void *pKey; int nKey; /* Key associated with this element */
+};
+
+/*
+** There are 4 different modes of operation for a hash table:
+**
+** STQLITE_HASH_INT nKey is used as the key and pKey is ignored.
+**
+** STQLITE_HASH_POINTER pKey is used as the key and nKey is ignored.
+**
+** STQLITE_HASH_STRING pKey points to a string that is nKey bytes long
+** (including the null-terminator, if any). Case
+** is ignored in comparisons.
+**
+** STQLITE_HASH_BINARY pKey points to binary data nKey bytes long.
+** memcmp() is used to compare keys.
+**
+** A copy of the key is made for STQLITE_HASH_STRING and STQLITE_HASH_BINARY
+** if the copyKey parameter to HashInit is 1.
+*/
+#define STQLITE_HASH_INT 1
+/* #define STQLITE_HASH_POINTER 2 // NOT USED */
+#define STQLITE_HASH_STRING 3
+#define STQLITE_HASH_BINARY 4
+
+/*
+** Access routines. To delete, insert a NULL pointer.
+*/
+void sqliteHashInit(Hash*, int keytype, int copyKey);
+void *sqliteHashInsert(Hash*, const void *pKey, int nKey, void *pData);
+void *sqliteHashFind(const Hash*, const void *pKey, int nKey);
+void sqliteHashClear(Hash*);
+
+/*
+** Macros for looping over all elements of a hash table. The idiom is
+** like this:
+**
+** Hash h;
+** HashElem *p;
+** ...
+** for(p=sqliteHashFirst(&h); p; p=sqliteHashNext(p)){
+** SomeStructure *pData = sqliteHashData(p);
+** // do something with pData
+** }
+*/
+#define sqliteHashFirst(H) ((H)->first)
+#define sqliteHashNext(E) ((E)->next)
+#define sqliteHashData(E) ((E)->data)
+#define sqliteHashKey(E) ((E)->pKey)
+#define sqliteHashKeysize(E) ((E)->nKey)
+
+/*
+** Number of entries in a hash table
+*/
+#define sqliteHashCount(H) ((H)->count)
+
+#endif /* _STQLITE_HASH_H_ */
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/insert.c b/tqtinterface/qt4/src/3rdparty/sqlite/insert.c
new file mode 100644
index 0000000..66d29df
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/insert.c
@@ -0,0 +1,919 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains C code routines that are called by the parser
+** to handle INSERT statements in STQLite.
+**
+** $Id: insert.c,v 1.94 2004/02/24 01:05:33 drh Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** This routine is call to handle SQL of the following forms:
+**
+** insert into TABLE (IDLIST) values(EXPRLIST)
+** insert into TABLE (IDLIST) select
+**
+** The IDLIST following the table name is always optional. If omitted,
+** then a list of all columns for the table is substituted. The IDLIST
+** appears in the pColumn parameter. pColumn is NULL if IDLIST is omitted.
+**
+** The pList parameter holds EXPRLIST in the first form of the INSERT
+** statement above, and pSelect is NULL. For the second form, pList is
+** NULL and pSelect is a pointer to the select statement used to generate
+** data for the insert.
+**
+** The code generated follows one of three templates. For a simple
+** select with data coming from a VALUES clause, the code executes
+** once straight down through. The template looks like this:
+**
+** open write cursor to <table> and its indices
+** puts VALUES clause expressions onto the stack
+** write the resulting record into <table>
+** cleanup
+**
+** If the statement is of the form
+**
+** INSERT INTO <table> SELECT ...
+**
+** And the SELECT clause does not read from <table> at any time, then
+** the generated code follows this template:
+**
+** goto B
+** A: setup for the SELECT
+** loop over the tables in the SELECT
+** gosub C
+** end loop
+** cleanup after the SELECT
+** goto D
+** B: open write cursor to <table> and its indices
+** goto A
+** C: insert the select result into <table>
+** return
+** D: cleanup
+**
+** The third template is used if the insert statement takes its
+** values from a SELECT but the data is being inserted into a table
+** that is also read as part of the SELECT. In the third form,
+** we have to use a intermediate table to store the results of
+** the select. The template is like this:
+**
+** goto B
+** A: setup for the SELECT
+** loop over the tables in the SELECT
+** gosub C
+** end loop
+** cleanup after the SELECT
+** goto D
+** C: insert the select result into the intermediate table
+** return
+** B: open a cursor to an intermediate table
+** goto A
+** D: open write cursor to <table> and its indices
+** loop over the intermediate table
+** transfer values form intermediate table into <table>
+** end the loop
+** cleanup
+*/
+void sqliteInsert(
+ Parse *pParse, /* Parser context */
+ SrcList *pTabList, /* Name of table into which we are inserting */
+ ExprList *pList, /* List of values to be inserted */
+ Select *pSelect, /* A SELECT statement to use as the data source */
+ IdList *pColumn, /* Column names corresponding to IDLIST. */
+ int onError /* How to handle constraint errors */
+){
+ Table *pTab; /* The table to insert into */
+ char *zTab; /* Name of the table into which we are inserting */
+ const char *zDb; /* Name of the database holding this table */
+ int i, j, idx; /* Loop counters */
+ Vdbe *v; /* Generate code into this virtual machine */
+ Index *pIdx; /* For looping over indices of the table */
+ int nColumn; /* Number of columns in the data */
+ int base; /* VDBE Cursor number for pTab */
+ int iCont, iBreak; /* Beginning and end of the loop over srcTab */
+ sqlite *db; /* The main database structure */
+ int keyColumn = -1; /* Column that is the INTEGER PRIMARY KEY */
+ int endOfLoop; /* Label for the end of the insertion loop */
+ int useTempTable; /* Store SELECT results in intermediate table */
+ int srcTab; /* Data comes from this temporary cursor if >=0 */
+ int iSelectLoop; /* Address of code that implements the SELECT */
+ int iCleanup; /* Address of the cleanup code */
+ int iInsertBlock; /* Address of the subroutine used to insert data */
+ int iCntMem; /* Memory cell used for the row counter */
+ int isView; /* True if attempting to insert into a view */
+
+ int row_triggers_exist = 0; /* True if there are FOR EACH ROW triggers */
+ int before_triggers; /* True if there are BEFORE triggers */
+ int after_triggers; /* True if there are AFTER triggers */
+ int newIdx = -1; /* Cursor for the NEW table */
+
+ if( pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
+ db = pParse->db;
+
+ /* Locate the table into which we will be inserting new information.
+ */
+ assert( pTabList->nSrc==1 );
+ zTab = pTabList->a[0].zName;
+ if( zTab==0 ) goto insert_cleanup;
+ pTab = sqliteSrcListLookup(pParse, pTabList);
+ if( pTab==0 ){
+ goto insert_cleanup;
+ }
+ assert( pTab->iDb<db->nDb );
+ zDb = db->aDb[pTab->iDb].zName;
+ if( sqliteAuthCheck(pParse, STQLITE_INSERT, pTab->zName, 0, zDb) ){
+ goto insert_cleanup;
+ }
+
+ /* Ensure that:
+ * (a) the table is not read-only,
+ * (b) that if it is a view then ON INSERT triggers exist
+ */
+ before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT,
+ TK_BEFORE, TK_ROW, 0);
+ after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger, TK_INSERT,
+ TK_AFTER, TK_ROW, 0);
+ row_triggers_exist = before_triggers || after_triggers;
+ isView = pTab->pSelect!=0;
+ if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
+ goto insert_cleanup;
+ }
+ if( pTab==0 ) goto insert_cleanup;
+
+ /* If pTab is really a view, make sure it has been initialized.
+ */
+ if( isView && sqliteViewGetColumnNames(pParse, pTab) ){
+ goto insert_cleanup;
+ }
+
+ /* Allocate a VDBE
+ */
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ) goto insert_cleanup;
+ sqliteBeginWriteOperation(pParse, pSelect || row_triggers_exist, pTab->iDb);
+
+ /* if there are row triggers, allocate a temp table for new.* references. */
+ if( row_triggers_exist ){
+ newIdx = pParse->nTab++;
+ }
+
+ /* Figure out how many columns of data are supplied. If the data
+ ** is coming from a SELECT statement, then this step also generates
+ ** all the code to implement the SELECT statement and invoke a subroutine
+ ** to process each row of the result. (Template 2.) If the SELECT
+ ** statement uses the the table that is being inserted into, then the
+ ** subroutine is also coded here. That subroutine stores the SELECT
+ ** results in a temporary table. (Template 3.)
+ */
+ if( pSelect ){
+ /* Data is coming from a SELECT. Generate code to implement that SELECT
+ */
+ int rc, iInitCode;
+ iInitCode = sqliteVdbeAddOp(v, OP_Goto, 0, 0);
+ iSelectLoop = sqliteVdbeCurrentAddr(v);
+ iInsertBlock = sqliteVdbeMakeLabel(v);
+ rc = sqliteSelect(pParse, pSelect, SRT_Subroutine, iInsertBlock, 0,0,0);
+ if( rc || pParse->nErr || sqlite_malloc_failed ) goto insert_cleanup;
+ iCleanup = sqliteVdbeMakeLabel(v);
+ sqliteVdbeAddOp(v, OP_Goto, 0, iCleanup);
+ assert( pSelect->pEList );
+ nColumn = pSelect->pEList->nExpr;
+
+ /* Set useTempTable to TRUE if the result of the SELECT statement
+ ** should be written into a temporary table. Set to FALSE if each
+ ** row of the SELECT can be written directly into the result table.
+ **
+ ** A temp table must be used if the table being updated is also one
+ ** of the tables being read by the SELECT statement. Also use a
+ ** temp table in the case of row triggers.
+ */
+ if( row_triggers_exist ){
+ useTempTable = 1;
+ }else{
+ int addr = sqliteVdbeFindOp(v, OP_OpenRead, pTab->tnum);
+ useTempTable = 0;
+ if( addr>0 ){
+ VdbeOp *pOp = sqliteVdbeGetOp(v, addr-2);
+ if( pOp->opcode==OP_Integer && pOp->p1==pTab->iDb ){
+ useTempTable = 1;
+ }
+ }
+ }
+
+ if( useTempTable ){
+ /* Generate the subroutine that SELECT calls to process each row of
+ ** the result. Store the result in a temporary table
+ */
+ srcTab = pParse->nTab++;
+ sqliteVdbeResolveLabel(v, iInsertBlock);
+ sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
+ sqliteVdbeAddOp(v, OP_NewRecno, srcTab, 0);
+ sqliteVdbeAddOp(v, OP_Pull, 1, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, srcTab, 0);
+ sqliteVdbeAddOp(v, OP_Return, 0, 0);
+
+ /* The following code runs first because the GOTO at the very top
+ ** of the program jumps to it. Create the temporary table, then jump
+ ** back up and execute the SELECT code above.
+ */
+ sqliteVdbeChangeP2(v, iInitCode, sqliteVdbeCurrentAddr(v));
+ sqliteVdbeAddOp(v, OP_OpenTemp, srcTab, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, iSelectLoop);
+ sqliteVdbeResolveLabel(v, iCleanup);
+ }else{
+ sqliteVdbeChangeP2(v, iInitCode, sqliteVdbeCurrentAddr(v));
+ }
+ }else{
+ /* This is the case if the data for the INSERT is coming from a VALUES
+ ** clause
+ */
+ SrcList dummy;
+ assert( pList!=0 );
+ srcTab = -1;
+ useTempTable = 0;
+ assert( pList );
+ nColumn = pList->nExpr;
+ dummy.nSrc = 0;
+ for(i=0; i<nColumn; i++){
+ if( sqliteExprResolveIds(pParse, &dummy, 0, pList->a[i].pExpr) ){
+ goto insert_cleanup;
+ }
+ if( sqliteExprCheck(pParse, pList->a[i].pExpr, 0, 0) ){
+ goto insert_cleanup;
+ }
+ }
+ }
+
+ /* Make sure the number of columns in the source data matches the number
+ ** of columns to be inserted into the table.
+ */
+ if( pColumn==0 && nColumn!=pTab->nCol ){
+ sqliteErrorMsg(pParse,
+ "table %S has %d columns but %d values were supplied",
+ pTabList, 0, pTab->nCol, nColumn);
+ goto insert_cleanup;
+ }
+ if( pColumn!=0 && nColumn!=pColumn->nId ){
+ sqliteErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId);
+ goto insert_cleanup;
+ }
+
+ /* If the INSERT statement included an IDLIST term, then make sure
+ ** all elements of the IDLIST really are columns of the table and
+ ** remember the column indices.
+ **
+ ** If the table has an INTEGER PRIMARY KEY column and that column
+ ** is named in the IDLIST, then record in the keyColumn variable
+ ** the index into IDLIST of the primary key column. keyColumn is
+ ** the index of the primary key as it appears in IDLIST, not as
+ ** is appears in the original table. (The index of the primary
+ ** key in the original table is pTab->iPKey.)
+ */
+ if( pColumn ){
+ for(i=0; i<pColumn->nId; i++){
+ pColumn->a[i].idx = -1;
+ }
+ for(i=0; i<pColumn->nId; i++){
+ for(j=0; j<pTab->nCol; j++){
+ if( sqliteStrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){
+ pColumn->a[i].idx = j;
+ if( j==pTab->iPKey ){
+ keyColumn = i;
+ }
+ break;
+ }
+ }
+ if( j>=pTab->nCol ){
+ if( sqliteIsRowid(pColumn->a[i].zName) ){
+ keyColumn = i;
+ }else{
+ sqliteErrorMsg(pParse, "table %S has no column named %s",
+ pTabList, 0, pColumn->a[i].zName);
+ pParse->nErr++;
+ goto insert_cleanup;
+ }
+ }
+ }
+ }
+
+ /* If there is no IDLIST term but the table has an integer primary
+ ** key, the set the keyColumn variable to the primary key column index
+ ** in the original table definition.
+ */
+ if( pColumn==0 ){
+ keyColumn = pTab->iPKey;
+ }
+
+ /* Open the temp table for FOR EACH ROW triggers
+ */
+ if( row_triggers_exist ){
+ sqliteVdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
+ }
+
+ /* Initialize the count of rows to be inserted
+ */
+ if( db->flags & STQLITE_CountRows ){
+ iCntMem = pParse->nMem++;
+ sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+ sqliteVdbeAddOp(v, OP_MemStore, iCntMem, 1);
+ }
+
+ /* Open tables and indices if there are no row triggers */
+ if( !row_triggers_exist ){
+ base = pParse->nTab;
+ idx = sqliteOpenTableAndIndices(pParse, pTab, base);
+ pParse->nTab += idx;
+ }
+
+ /* If the data source is a temporary table, then we have to create
+ ** a loop because there might be multiple rows of data. If the data
+ ** source is a subroutine call from the SELECT statement, then we need
+ ** to launch the SELECT statement processing.
+ */
+ if( useTempTable ){
+ iBreak = sqliteVdbeMakeLabel(v);
+ sqliteVdbeAddOp(v, OP_Rewind, srcTab, iBreak);
+ iCont = sqliteVdbeCurrentAddr(v);
+ }else if( pSelect ){
+ sqliteVdbeAddOp(v, OP_Goto, 0, iSelectLoop);
+ sqliteVdbeResolveLabel(v, iInsertBlock);
+ }
+
+ /* Run the BEFORE and INSTEAD OF triggers, if there are any
+ */
+ endOfLoop = sqliteVdbeMakeLabel(v);
+ if( before_triggers ){
+
+ /* build the NEW.* reference row. Note that if there is an INTEGER
+ ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
+ ** translated into a unique ID for the row. But on a BEFORE trigger,
+ ** we do not know what the unique ID will be (because the insert has
+ ** not happened yet) so we substitute a rowid of -1
+ */
+ if( keyColumn<0 ){
+ sqliteVdbeAddOp(v, OP_Integer, -1, 0);
+ }else if( useTempTable ){
+ sqliteVdbeAddOp(v, OP_Column, srcTab, keyColumn);
+ }else if( pSelect ){
+ sqliteVdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
+ }else{
+ sqliteExprCode(pParse, pList->a[keyColumn].pExpr);
+ sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ sqliteVdbeAddOp(v, OP_Integer, -1, 0);
+ sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
+ }
+
+ /* Create the new column data
+ */
+ for(i=0; i<pTab->nCol; i++){
+ if( pColumn==0 ){
+ j = i;
+ }else{
+ for(j=0; j<pColumn->nId; j++){
+ if( pColumn->a[j].idx==i ) break;
+ }
+ }
+ if( pColumn && j>=pColumn->nId ){
+ sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
+ }else if( useTempTable ){
+ sqliteVdbeAddOp(v, OP_Column, srcTab, j);
+ }else if( pSelect ){
+ sqliteVdbeAddOp(v, OP_Dup, nColumn-j-1, 1);
+ }else{
+ sqliteExprCode(pParse, pList->a[j].pExpr);
+ }
+ }
+ sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
+
+ /* Fire BEFORE or INSTEAD OF triggers */
+ if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_BEFORE, pTab,
+ newIdx, -1, onError, endOfLoop) ){
+ goto insert_cleanup;
+ }
+ }
+
+ /* If any triggers exists, the opening of tables and indices is deferred
+ ** until now.
+ */
+ if( row_triggers_exist && !isView ){
+ base = pParse->nTab;
+ idx = sqliteOpenTableAndIndices(pParse, pTab, base);
+ pParse->nTab += idx;
+ }
+
+ /* Push the record number for the new entry onto the stack. The
+ ** record number is a randomly generate integer created by NewRecno
+ ** except when the table has an INTEGER PRIMARY KEY column, in which
+ ** case the record number is the same as that column.
+ */
+ if( !isView ){
+ if( keyColumn>=0 ){
+ if( useTempTable ){
+ sqliteVdbeAddOp(v, OP_Column, srcTab, keyColumn);
+ }else if( pSelect ){
+ sqliteVdbeAddOp(v, OP_Dup, nColumn - keyColumn - 1, 1);
+ }else{
+ sqliteExprCode(pParse, pList->a[keyColumn].pExpr);
+ }
+ /* If the PRIMARY KEY expression is NULL, then use OP_NewRecno
+ ** to generate a unique primary key value.
+ */
+ sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ sqliteVdbeAddOp(v, OP_NewRecno, base, 0);
+ sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
+ }else{
+ sqliteVdbeAddOp(v, OP_NewRecno, base, 0);
+ }
+
+ /* Push onto the stack, data for all columns of the new entry, beginning
+ ** with the first column.
+ */
+ for(i=0; i<pTab->nCol; i++){
+ if( i==pTab->iPKey ){
+ /* The value of the INTEGER PRIMARY KEY column is always a NULL.
+ ** Whenever this column is read, the record number will be substituted
+ ** in its place. So will fill this column with a NULL to avoid
+ ** taking up data space with information that will never be used. */
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ continue;
+ }
+ if( pColumn==0 ){
+ j = i;
+ }else{
+ for(j=0; j<pColumn->nId; j++){
+ if( pColumn->a[j].idx==i ) break;
+ }
+ }
+ if( pColumn && j>=pColumn->nId ){
+ sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
+ }else if( useTempTable ){
+ sqliteVdbeAddOp(v, OP_Column, srcTab, j);
+ }else if( pSelect ){
+ sqliteVdbeAddOp(v, OP_Dup, i+nColumn-j, 1);
+ }else{
+ sqliteExprCode(pParse, pList->a[j].pExpr);
+ }
+ }
+
+ /* Generate code to check constraints and generate index keys and
+ ** do the insertion.
+ */
+ sqliteGenerateConstraintChecks(pParse, pTab, base, 0, keyColumn>=0,
+ 0, onError, endOfLoop);
+ sqliteCompleteInsertion(pParse, pTab, base, 0,0,0,
+ after_triggers ? newIdx : -1);
+ }
+
+ /* Update the count of rows that are inserted
+ */
+ if( (db->flags & STQLITE_CountRows)!=0 ){
+ sqliteVdbeAddOp(v, OP_MemIncr, iCntMem, 0);
+ }
+
+ if( row_triggers_exist ){
+ /* Close all tables opened */
+ if( !isView ){
+ sqliteVdbeAddOp(v, OP_Close, base, 0);
+ for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
+ sqliteVdbeAddOp(v, OP_Close, idx+base, 0);
+ }
+ }
+
+ /* Code AFTER triggers */
+ if( sqliteCodeRowTrigger(pParse, TK_INSERT, 0, TK_AFTER, pTab, newIdx, -1,
+ onError, endOfLoop) ){
+ goto insert_cleanup;
+ }
+ }
+
+ /* The bottom of the loop, if the data source is a SELECT statement
+ */
+ sqliteVdbeResolveLabel(v, endOfLoop);
+ if( useTempTable ){
+ sqliteVdbeAddOp(v, OP_Next, srcTab, iCont);
+ sqliteVdbeResolveLabel(v, iBreak);
+ sqliteVdbeAddOp(v, OP_Close, srcTab, 0);
+ }else if( pSelect ){
+ sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
+ sqliteVdbeAddOp(v, OP_Return, 0, 0);
+ sqliteVdbeResolveLabel(v, iCleanup);
+ }
+
+ if( !row_triggers_exist ){
+ /* Close all tables opened */
+ sqliteVdbeAddOp(v, OP_Close, base, 0);
+ for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
+ sqliteVdbeAddOp(v, OP_Close, idx+base, 0);
+ }
+ }
+
+ sqliteVdbeAddOp(v, OP_SetCounts, 0, 0);
+ sqliteEndWriteOperation(pParse);
+
+ /*
+ ** Return the number of rows inserted.
+ */
+ if( db->flags & STQLITE_CountRows ){
+ sqliteVdbeOp3(v, OP_ColumnName, 0, 1, "rows inserted", P3_STATIC);
+ sqliteVdbeAddOp(v, OP_MemLoad, iCntMem, 0);
+ sqliteVdbeAddOp(v, OP_Callback, 1, 0);
+ }
+
+insert_cleanup:
+ sqliteSrcListDelete(pTabList);
+ if( pList ) sqliteExprListDelete(pList);
+ if( pSelect ) sqliteSelectDelete(pSelect);
+ sqliteIdListDelete(pColumn);
+}
+
+/*
+** Generate code to do a constraint check prior to an INSERT or an UPDATE.
+**
+** When this routine is called, the stack tqcontains (from bottom to top)
+** the following values:
+**
+** 1. The recno of the row to be updated before the update. This
+** value is omitted unless we are doing an UPDATE that involves a
+** change to the record number.
+**
+** 2. The recno of the row after the update.
+**
+** 3. The data in the first column of the entry after the update.
+**
+** i. Data from middle columns...
+**
+** N. The data in the last column of the entry after the update.
+**
+** The old recno shown as entry (1) above is omitted unless both isUpdate
+** and recnoChng are 1. isUpdate is true for UPDATEs and false for
+** INSERTs and recnoChng is true if the record number is being changed.
+**
+** The code generated by this routine pushes additional entries onto
+** the stack which are the keys for new index entries for the new record.
+** The order of index keys is the same as the order of the indices on
+** the pTable->pIndex list. A key is only created for index i if
+** aIdxUsed!=0 and aIdxUsed[i]!=0.
+**
+** This routine also generates code to check constraints. NOT NULL,
+** CHECK, and UNITQUE constraints are all checked. If a constraint fails,
+** then the appropriate action is performed. There are five possible
+** actions: ROLLBACK, ABORT, FAIL, REPLACE, and IGNORE.
+**
+** Constraint type Action What Happens
+** --------------- ---------- ----------------------------------------
+** any ROLLBACK The current transaction is rolled back and
+** sqlite_exec() returns immediately with a
+** return code of STQLITE_CONSTRAINT.
+**
+** any ABORT Back out changes from the current command
+** only (do not do a complete rollback) then
+** cause sqlite_exec() to return immediately
+** with STQLITE_CONSTRAINT.
+**
+** any FAIL Sqlite_exec() returns immediately with a
+** return code of STQLITE_CONSTRAINT. The
+** transaction is not rolled back and any
+** prior changes are retained.
+**
+** any IGNORE The record number and data is popped from
+** the stack and there is an immediate jump
+** to label ignoreDest.
+**
+** NOT NULL REPLACE The NULL value is tqreplace by the default
+** value for that column. If the default value
+** is NULL, the action is the same as ABORT.
+**
+** UNITQUE REPLACE The other row that conflicts with the row
+** being inserted is removed.
+**
+** CHECK REPLACE Illegal. The results in an exception.
+**
+** Which action to take is determined by the overrideError parameter.
+** Or if overrideError==OE_Default, then the pParse->onError parameter
+** is used. Or if pParse->onError==OE_Default then the onError value
+** for the constraint is used.
+**
+** The calling routine must open a read/write cursor for pTab with
+** cursor number "base". All indices of pTab must also have open
+** read/write cursors with cursor number base+i for the i-th cursor.
+** Except, if there is no possibility of a REPLACE action then
+** cursors do not need to be open for indices where aIdxUsed[i]==0.
+**
+** If the isUpdate flag is true, it means that the "base" cursor is
+** initially pointing to an entry that is being updated. The isUpdate
+** flag causes extra code to be generated so that the "base" cursor
+** is still pointing at the same entry after the routine returns.
+** Without the isUpdate flag, the "base" cursor might be moved.
+*/
+void sqliteGenerateConstraintChecks(
+ Parse *pParse, /* The parser context */
+ Table *pTab, /* the table into which we are inserting */
+ int base, /* Index of a read/write cursor pointing at pTab */
+ char *aIdxUsed, /* Which indices are used. NULL means all are used */
+ int recnoChng, /* True if the record number will change */
+ int isUpdate, /* True for UPDATE, False for INSERT */
+ int overrideError, /* Override onError to this if not OE_Default */
+ int ignoreDest /* Jump to this label on an OE_Ignore resolution */
+){
+ int i;
+ Vdbe *v;
+ int nCol;
+ int onError;
+ int addr;
+ int extra;
+ int iCur;
+ Index *pIdx;
+ int seenReplace = 0;
+ int jumpInst1, jumpInst2;
+ int contAddr;
+ int hasTwoRecnos = (isUpdate && recnoChng);
+
+ v = sqliteGetVdbe(pParse);
+ assert( v!=0 );
+ assert( pTab->pSelect==0 ); /* This table is not a VIEW */
+ nCol = pTab->nCol;
+
+ /* Test all NOT NULL constraints.
+ */
+ for(i=0; i<nCol; i++){
+ if( i==pTab->iPKey ){
+ continue;
+ }
+ onError = pTab->aCol[i].notNull;
+ if( onError==OE_None ) continue;
+ if( overrideError!=OE_Default ){
+ onError = overrideError;
+ }else if( pParse->db->onError!=OE_Default ){
+ onError = pParse->db->onError;
+ }else if( onError==OE_Default ){
+ onError = OE_Abort;
+ }
+ if( onError==OE_Replace && pTab->aCol[i].zDflt==0 ){
+ onError = OE_Abort;
+ }
+ sqliteVdbeAddOp(v, OP_Dup, nCol-1-i, 1);
+ addr = sqliteVdbeAddOp(v, OP_NotNull, 1, 0);
+ switch( onError ){
+ case OE_Rollback:
+ case OE_Abort:
+ case OE_Fail: {
+ char *zMsg = 0;
+ sqliteVdbeAddOp(v, OP_Halt, STQLITE_CONSTRAINT, onError);
+ sqliteSetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
+ " may not be NULL", (char*)0);
+ sqliteVdbeChangeP3(v, -1, zMsg, P3_DYNAMIC);
+ break;
+ }
+ case OE_Ignore: {
+ sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
+ break;
+ }
+ case OE_Replace: {
+ sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zDflt, P3_STATIC);
+ sqliteVdbeAddOp(v, OP_Push, nCol-i, 0);
+ break;
+ }
+ default: assert(0);
+ }
+ sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
+ }
+
+ /* Test all CHECK constraints
+ */
+ /**** TBD ****/
+
+ /* If we have an INTEGER PRIMARY KEY, make sure the primary key
+ ** of the new record does not previously exist. Except, if this
+ ** is an UPDATE and the primary key is not changing, that is OK.
+ */
+ if( recnoChng ){
+ onError = pTab->keyConf;
+ if( overrideError!=OE_Default ){
+ onError = overrideError;
+ }else if( pParse->db->onError!=OE_Default ){
+ onError = pParse->db->onError;
+ }else if( onError==OE_Default ){
+ onError = OE_Abort;
+ }
+
+ if( isUpdate ){
+ sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
+ sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
+ jumpInst1 = sqliteVdbeAddOp(v, OP_Eq, 0, 0);
+ }
+ sqliteVdbeAddOp(v, OP_Dup, nCol, 1);
+ jumpInst2 = sqliteVdbeAddOp(v, OP_NotExists, base, 0);
+ switch( onError ){
+ default: {
+ onError = OE_Abort;
+ /* Fall thru into the next case */
+ }
+ case OE_Rollback:
+ case OE_Abort:
+ case OE_Fail: {
+ sqliteVdbeOp3(v, OP_Halt, STQLITE_CONSTRAINT, onError,
+ "PRIMARY KEY must be unique", P3_STATIC);
+ break;
+ }
+ case OE_Replace: {
+ sqliteGenerateRowIndexDelete(pParse->db, v, pTab, base, 0);
+ if( isUpdate ){
+ sqliteVdbeAddOp(v, OP_Dup, nCol+hasTwoRecnos, 1);
+ sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
+ }
+ seenReplace = 1;
+ break;
+ }
+ case OE_Ignore: {
+ assert( seenReplace==0 );
+ sqliteVdbeAddOp(v, OP_Pop, nCol+1+hasTwoRecnos, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
+ break;
+ }
+ }
+ contAddr = sqliteVdbeCurrentAddr(v);
+ sqliteVdbeChangeP2(v, jumpInst2, contAddr);
+ if( isUpdate ){
+ sqliteVdbeChangeP2(v, jumpInst1, contAddr);
+ sqliteVdbeAddOp(v, OP_Dup, nCol+1, 1);
+ sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
+ }
+ }
+
+ /* Test all UNITQUE constraints by creating entries for each UNITQUE
+ ** index and making sure that duplicate entries do not already exist.
+ ** Add the new records to the indices as we go.
+ */
+ extra = -1;
+ for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
+ if( aIdxUsed && aIdxUsed[iCur]==0 ) continue; /* Skip unused indices */
+ extra++;
+
+ /* Create a key for accessing the index entry */
+ sqliteVdbeAddOp(v, OP_Dup, nCol+extra, 1);
+ for(i=0; i<pIdx->nColumn; i++){
+ int idx = pIdx->aiColumn[i];
+ if( idx==pTab->iPKey ){
+ sqliteVdbeAddOp(v, OP_Dup, i+extra+nCol+1, 1);
+ }else{
+ sqliteVdbeAddOp(v, OP_Dup, i+extra+nCol-idx, 1);
+ }
+ }
+ jumpInst1 = sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
+ if( pParse->db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
+
+ /* Find out what action to take in case there is an indexing conflict */
+ onError = pIdx->onError;
+ if( onError==OE_None ) continue; /* pIdx is not a UNITQUE index */
+ if( overrideError!=OE_Default ){
+ onError = overrideError;
+ }else if( pParse->db->onError!=OE_Default ){
+ onError = pParse->db->onError;
+ }else if( onError==OE_Default ){
+ onError = OE_Abort;
+ }
+ if( seenReplace ){
+ if( onError==OE_Ignore ) onError = OE_Replace;
+ else if( onError==OE_Fail ) onError = OE_Abort;
+ }
+
+
+ /* Check to see if the new index entry will be unique */
+ sqliteVdbeAddOp(v, OP_Dup, extra+nCol+1+hasTwoRecnos, 1);
+ jumpInst2 = sqliteVdbeAddOp(v, OP_IsUnique, base+iCur+1, 0);
+
+ /* Generate code that executes if the new index entry is not unique */
+ switch( onError ){
+ case OE_Rollback:
+ case OE_Abort:
+ case OE_Fail: {
+ int j, n1, n2;
+ char zErrMsg[200];
+ strcpy(zErrMsg, pIdx->nColumn>1 ? "columns " : "column ");
+ n1 = strlen(zErrMsg);
+ for(j=0; j<pIdx->nColumn && n1<sizeof(zErrMsg)-30; j++){
+ char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
+ n2 = strlen(zCol);
+ if( j>0 ){
+ strcpy(&zErrMsg[n1], ", ");
+ n1 += 2;
+ }
+ if( n1+n2>sizeof(zErrMsg)-30 ){
+ strcpy(&zErrMsg[n1], "...");
+ n1 += 3;
+ break;
+ }else{
+ strcpy(&zErrMsg[n1], zCol);
+ n1 += n2;
+ }
+ }
+ strcpy(&zErrMsg[n1],
+ pIdx->nColumn>1 ? " are not unique" : " is not unique");
+ sqliteVdbeOp3(v, OP_Halt, STQLITE_CONSTRAINT, onError, zErrMsg, 0);
+ break;
+ }
+ case OE_Ignore: {
+ assert( seenReplace==0 );
+ sqliteVdbeAddOp(v, OP_Pop, nCol+extra+3+hasTwoRecnos, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, ignoreDest);
+ break;
+ }
+ case OE_Replace: {
+ sqliteGenerateRowDelete(pParse->db, v, pTab, base, 0);
+ if( isUpdate ){
+ sqliteVdbeAddOp(v, OP_Dup, nCol+extra+1+hasTwoRecnos, 1);
+ sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
+ }
+ seenReplace = 1;
+ break;
+ }
+ default: assert(0);
+ }
+ contAddr = sqliteVdbeCurrentAddr(v);
+#if NULL_DISTINCT_FOR_UNITQUE
+ sqliteVdbeChangeP2(v, jumpInst1, contAddr);
+#endif
+ sqliteVdbeChangeP2(v, jumpInst2, contAddr);
+ }
+}
+
+/*
+** This routine generates code to finish the INSERT or UPDATE operation
+** that was started by a prior call to sqliteGenerateConstraintChecks.
+** The stack must contain keys for all active indices followed by data
+** and the recno for the new entry. This routine creates the new
+** entries in all indices and in the main table.
+**
+** The arguments to this routine should be the same as the first six
+** arguments to sqliteGenerateConstraintChecks.
+*/
+void sqliteCompleteInsertion(
+ Parse *pParse, /* The parser context */
+ Table *pTab, /* the table into which we are inserting */
+ int base, /* Index of a read/write cursor pointing at pTab */
+ char *aIdxUsed, /* Which indices are used. NULL means all are used */
+ int recnoChng, /* True if the record number will change */
+ int isUpdate, /* True for UPDATE, False for INSERT */
+ int newIdx /* Index of NEW table for triggers. -1 if none */
+){
+ int i;
+ Vdbe *v;
+ int nIdx;
+ Index *pIdx;
+
+ v = sqliteGetVdbe(pParse);
+ assert( v!=0 );
+ assert( pTab->pSelect==0 ); /* This table is not a VIEW */
+ for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
+ for(i=nIdx-1; i>=0; i--){
+ if( aIdxUsed && aIdxUsed[i]==0 ) continue;
+ sqliteVdbeAddOp(v, OP_IdxPut, base+i+1, 0);
+ }
+ sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
+ if( newIdx>=0 ){
+ sqliteVdbeAddOp(v, OP_Dup, 1, 0);
+ sqliteVdbeAddOp(v, OP_Dup, 1, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
+ }
+ sqliteVdbeAddOp(v, OP_PutIntKey, base,
+ (pParse->trigStack?0:OPFLAG_NCHANGE) |
+ (isUpdate?0:OPFLAG_LASTROWID) | OPFLAG_CSCHANGE);
+ if( isUpdate && recnoChng ){
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ }
+}
+
+/*
+** Generate code that will open write cursors for a table and for all
+** indices of that table. The "base" parameter is the cursor number used
+** for the table. Indices are opened on subsequent cursors.
+**
+** Return the total number of cursors opened. This is always at least
+** 1 (for the main table) plus more for each cursor.
+*/
+int sqliteOpenTableAndIndices(Parse *pParse, Table *pTab, int base){
+ int i;
+ Index *pIdx;
+ Vdbe *v = sqliteGetVdbe(pParse);
+ assert( v!=0 );
+ sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqliteVdbeOp3(v, OP_OpenWrite, base, pTab->tnum, pTab->zName, P3_STATIC);
+ for(i=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+ sqliteVdbeOp3(v, OP_OpenWrite, i+base, pIdx->tnum, pIdx->zName, P3_STATIC);
+ }
+ return i;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/main.c b/tqtinterface/qt4/src/3rdparty/sqlite/main.c
new file mode 100644
index 0000000..e420bac
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/main.c
@@ -0,0 +1,1136 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Main file for the STQLite library. The routines in this file
+** implement the programmer interface to the library. Routines in
+** other files are for internal use by STQLite and should not be
+** accessed by users of the library.
+**
+** $Id: main.c,v 1.162 2004/03/04 19:09:20 rdc Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+
+/*
+** A pointer to this structure is used to communicate information
+** from sqliteInit into the sqliteInitCallback.
+*/
+typedef struct {
+ sqlite *db; /* The database being initialized */
+ char **pzErrMsg; /* Error message stored here */
+} InitData;
+
+/*
+** Fill the InitData structure with an error message that indicates
+** that the database is corrupt.
+*/
+static void corruptSchema(InitData *pData, const char *zExtra){
+ sqliteSetString(pData->pzErrMsg, "malformed database schema",
+ zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
+}
+
+/*
+** This is the callback routine for the code that initializes the
+** database. See sqliteInit() below for additional information.
+**
+** Each callback tqcontains the following information:
+**
+** argv[0] = "file-format" or "schema-cookie" or "table" or "index"
+** argv[1] = table or index name or meta statement type.
+** argv[2] = root page number for table or index. NULL for meta.
+** argv[3] = SQL text for a CREATE TABLE or CREATE INDEX statement.
+** argv[4] = "1" for temporary files, "0" for main database, "2" or more
+** for auxiliary database files.
+**
+*/
+static
+int sqliteInitCallback(void *pInit, int argc, char **argv, char **azColName){
+ InitData *pData = (InitData*)pInit;
+ int nErr = 0;
+
+ assert( argc==5 );
+ if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */
+ if( argv[0]==0 ){
+ corruptSchema(pData, 0);
+ return 1;
+ }
+ switch( argv[0][0] ){
+ case 'v':
+ case 'i':
+ case 't': { /* CREATE TABLE, CREATE INDEX, or CREATE VIEW statements */
+ sqlite *db = pData->db;
+ if( argv[2]==0 || argv[4]==0 ){
+ corruptSchema(pData, 0);
+ return 1;
+ }
+ if( argv[3] && argv[3][0] ){
+ /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
+ ** But because db->init.busy is set to 1, no VDBE code is generated
+ ** or executed. All the parser does is build the internal data
+ ** structures that describe the table, index, or view.
+ */
+ char *zErr;
+ assert( db->init.busy );
+ db->init.iDb = atoi(argv[4]);
+ assert( db->init.iDb>=0 && db->init.iDb<db->nDb );
+ db->init.newTnum = atoi(argv[2]);
+ if( sqlite_exec(db, argv[3], 0, 0, &zErr) ){
+ corruptSchema(pData, zErr);
+ sqlite_freemem(zErr);
+ }
+ db->init.iDb = 0;
+ }else{
+ /* If the SQL column is blank it means this is an index that
+ ** was created to be the PRIMARY KEY or to fulfill a UNITQUE
+ ** constraint for a CREATE TABLE. The index should have already
+ ** been created when we processed the CREATE TABLE. All we have
+ ** to do here is record the root page number for that index.
+ */
+ int iDb;
+ Index *pIndex;
+
+ iDb = atoi(argv[4]);
+ assert( iDb>=0 && iDb<db->nDb );
+ pIndex = sqliteFindIndex(db, argv[1], db->aDb[iDb].zName);
+ if( pIndex==0 || pIndex->tnum!=0 ){
+ /* This can occur if there exists an index on a TEMP table which
+ ** has the same name as another index on a permanent index. Since
+ ** the permanent table is hidden by the TEMP table, we can also
+ ** safely ignore the index on the permanent table.
+ */
+ /* Do Nothing */;
+ }else{
+ pIndex->tnum = atoi(argv[2]);
+ }
+ }
+ break;
+ }
+ default: {
+ /* This can not happen! */
+ nErr = 1;
+ assert( nErr==0 );
+ }
+ }
+ return nErr;
+}
+
+/*
+** This is a callback procedure used to reconstruct a table. The
+** name of the table to be reconstructed is passed in as argv[0].
+**
+** This routine is used to automatically upgrade a database from
+** format version 1 or 2 to version 3. The correct operation of
+** this routine relys on the fact that no indices are used when
+** copying a table out to a temporary file.
+**
+** The change from version 2 to version 3 occurred between STQLite
+** version 2.5.6 and 2.6.0 on 2002-July-18.
+*/
+static
+int upgrade_3_callback(void *pInit, int argc, char **argv, char **NotUsed){
+ InitData *pData = (InitData*)pInit;
+ int rc;
+ Table *pTab;
+ Trigger *pTrig;
+ char *zErr = 0;
+
+ pTab = sqliteFindTable(pData->db, argv[0], 0);
+ assert( pTab!=0 );
+ assert( sqliteStrICmp(pTab->zName, argv[0])==0 );
+ if( pTab ){
+ pTrig = pTab->pTrigger;
+ pTab->pTrigger = 0; /* Disable all triggers before rebuilding the table */
+ }
+ rc = sqlite_exec_printf(pData->db,
+ "CREATE TEMP TABLE sqlite_x AS SELECT * FROM '%q'; "
+ "DELETE FROM '%q'; "
+ "INSERT INTO '%q' SELECT * FROM sqlite_x; "
+ "DROP TABLE sqlite_x;",
+ 0, 0, &zErr, argv[0], argv[0], argv[0]);
+ if( zErr ){
+ if( *pData->pzErrMsg ) sqlite_freemem(*pData->pzErrMsg);
+ *pData->pzErrMsg = zErr;
+ }
+
+ /* If an error occurred in the SQL above, then the transaction will
+ ** rollback which will delete the internal symbol tables. This will
+ ** cause the structure that pTab points to be deleted. In case that
+ ** happened, we need to refetch pTab.
+ */
+ pTab = sqliteFindTable(pData->db, argv[0], 0);
+ if( pTab ){
+ assert( sqliteStrICmp(pTab->zName, argv[0])==0 );
+ pTab->pTrigger = pTrig; /* Re-enable triggers */
+ }
+ return rc!=STQLITE_OK;
+}
+
+
+
+/*
+** Attempt to read the database schema and initialize internal
+** data structures for a single database file. The index of the
+** database file is given by iDb. iDb==0 is used for the main
+** database. iDb==1 should never be used. iDb>=2 is used for
+** auxiliary databases. Return one of the STQLITE_ error codes to
+** indicate success or failure.
+*/
+static int sqliteInitOne(sqlite *db, int iDb, char **pzErrMsg){
+ int rc;
+ BtCursor *curMain;
+ int size;
+ Table *pTab;
+ char *azArg[6];
+ char zDbNum[30];
+ int meta[STQLITE_N_BTREE_META];
+ InitData initData;
+
+ /*
+ ** The master database table has a structure like this
+ */
+ static char master_schema[] =
+ "CREATE TABLE sqlite_master(\n"
+ " type text,\n"
+ " name text,\n"
+ " tbl_name text,\n"
+ " rootpage integer,\n"
+ " sql text\n"
+ ")"
+ ;
+ static char temp_master_schema[] =
+ "CREATE TEMP TABLE sqlite_temp_master(\n"
+ " type text,\n"
+ " name text,\n"
+ " tbl_name text,\n"
+ " rootpage integer,\n"
+ " sql text\n"
+ ")"
+ ;
+
+ /* The following SQL will read the schema from the master tables.
+ ** The first version works with STQLite file formats 2 or greater.
+ ** The second version is for format 1 files.
+ **
+ ** Beginning with file format 2, the rowid for new table entries
+ ** (including entries in sqlite_master) is an increasing integer.
+ ** So for file format 2 and later, we can play back sqlite_master
+ ** and all the CREATE statements will appear in the right order.
+ ** But with file format 1, table entries were random and so we
+ ** have to make sure the CREATE TABLEs occur before their corresponding
+ ** CREATE INDEXs. (We don't have to deal with CREATE VIEW or
+ ** CREATE TRIGGER in file format 1 because those constructs did
+ ** not exist then.)
+ */
+ static char init_script[] =
+ "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
+ "UNION ALL "
+ "SELECT type, name, rootpage, sql, 0 FROM sqlite_master";
+ static char older_init_script[] =
+ "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
+ "UNION ALL "
+ "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
+ "WHERE type='table' "
+ "UNION ALL "
+ "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
+ "WHERE type='index'";
+
+
+ assert( iDb>=0 && iDb!=1 && iDb<db->nDb );
+
+ /* Construct the schema tables: sqlite_master and sqlite_temp_master
+ */
+ sqliteSafetyOff(db);
+ azArg[0] = "table";
+ azArg[1] = MASTER_NAME;
+ azArg[2] = "2";
+ azArg[3] = master_schema;
+ sprintf(zDbNum, "%d", iDb);
+ azArg[4] = zDbNum;
+ azArg[5] = 0;
+ initData.db = db;
+ initData.pzErrMsg = pzErrMsg;
+ sqliteInitCallback(&initData, 5, azArg, 0);
+ pTab = sqliteFindTable(db, MASTER_NAME, "main");
+ if( pTab ){
+ pTab->readOnly = 1;
+ }
+ if( iDb==0 ){
+ azArg[1] = TEMP_MASTER_NAME;
+ azArg[3] = temp_master_schema;
+ azArg[4] = "1";
+ sqliteInitCallback(&initData, 5, azArg, 0);
+ pTab = sqliteFindTable(db, TEMP_MASTER_NAME, "temp");
+ if( pTab ){
+ pTab->readOnly = 1;
+ }
+ }
+ sqliteSafetyOn(db);
+
+ /* Create a cursor to hold the database open
+ */
+ if( db->aDb[iDb].pBt==0 ) return STQLITE_OK;
+ rc = sqliteBtreeCursor(db->aDb[iDb].pBt, 2, 0, &curMain);
+ if( rc ){
+ sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
+ return rc;
+ }
+
+ /* Get the database meta information
+ */
+ rc = sqliteBtreeGetMeta(db->aDb[iDb].pBt, meta);
+ if( rc ){
+ sqliteSetString(pzErrMsg, sqlite_error_string(rc), (char*)0);
+ sqliteBtreeCloseCursor(curMain);
+ return rc;
+ }
+ db->aDb[iDb].schema_cookie = meta[1];
+ if( iDb==0 ){
+ db->next_cookie = meta[1];
+ db->file_format = meta[2];
+ size = meta[3];
+ if( size==0 ){ size = MAX_PAGES; }
+ db->cache_size = size;
+ db->safety_level = meta[4];
+ if( db->safety_level==0 ) db->safety_level = 2;
+
+ /*
+ ** file_format==1 Version 2.1.0.
+ ** file_format==2 Version 2.2.0. Add support for INTEGER PRIMARY KEY.
+ ** file_format==3 Version 2.6.0. Fix empty-string index bug.
+ ** file_format==4 Version 2.7.0. Add support for separate numeric and
+ ** text datatypes.
+ */
+ if( db->file_format==0 ){
+ /* This happens if the database was initially empty */
+ db->file_format = 4;
+ }else if( db->file_format>4 ){
+ sqliteBtreeCloseCursor(curMain);
+ sqliteSetString(pzErrMsg, "unsupported file format", (char*)0);
+ return STQLITE_ERROR;
+ }
+ }else if( db->file_format!=meta[2] || db->file_format<4 ){
+ assert( db->file_format>=4 );
+ if( meta[2]==0 ){
+ sqliteSetString(pzErrMsg, "cannot attach empty database: ",
+ db->aDb[iDb].zName, (char*)0);
+ }else{
+ sqliteSetString(pzErrMsg, "incompatible file format in auxiliary "
+ "database: ", db->aDb[iDb].zName, (char*)0);
+ }
+ sqliteBtreeClose(db->aDb[iDb].pBt);
+ db->aDb[iDb].pBt = 0;
+ return STQLITE_FORMAT;
+ }
+ sqliteBtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
+ sqliteBtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]);
+
+ /* Read the schema information out of the schema tables
+ */
+ assert( db->init.busy );
+ sqliteSafetyOff(db);
+ if( iDb==0 ){
+ rc = sqlite_exec(db,
+ db->file_format>=2 ? init_script : older_init_script,
+ sqliteInitCallback, &initData, 0);
+ }else{
+ char *zSql = 0;
+ sqliteSetString(&zSql,
+ "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
+ db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
+ rc = sqlite_exec(db, zSql, sqliteInitCallback, &initData, 0);
+ sqliteFree(zSql);
+ }
+ sqliteSafetyOn(db);
+ sqliteBtreeCloseCursor(curMain);
+ if( sqlite_malloc_failed ){
+ sqliteSetString(pzErrMsg, "out of memory", (char*)0);
+ rc = STQLITE_NOMEM;
+ sqliteResetInternalSchema(db, 0);
+ }
+ if( rc==STQLITE_OK ){
+ DbSetProperty(db, iDb, DB_SchemaLoaded);
+ if( iDb==0 ){
+ DbSetProperty(db, 1, DB_SchemaLoaded);
+ }
+ }else{
+ sqliteResetInternalSchema(db, iDb);
+ }
+ return rc;
+}
+
+/*
+** Initialize all database files - the main database file, the file
+** used to store temporary tables, and any additional database files
+** created using ATTACH statements. Return a success code. If an
+** error occurs, write an error message into *pzErrMsg.
+**
+** After the database is initialized, the STQLITE_Initialized
+** bit is set in the flags field of the sqlite structure. An
+** attempt is made to initialize the database as soon as it
+** is opened. If that fails (perhaps because another process
+** has the sqlite_master table locked) than another attempt
+** is made the first time the database is accessed.
+*/
+int sqliteInit(sqlite *db, char **pzErrMsg){
+ int i, rc;
+
+ if( db->init.busy ) return STQLITE_OK;
+ assert( (db->flags & STQLITE_Initialized)==0 );
+ rc = STQLITE_OK;
+ db->init.busy = 1;
+ for(i=0; rc==STQLITE_OK && i<db->nDb; i++){
+ if( DbHasProperty(db, i, DB_SchemaLoaded) ) continue;
+ assert( i!=1 ); /* Should have been initialized together with 0 */
+ rc = sqliteInitOne(db, i, pzErrMsg);
+ if( rc ){
+ sqliteResetInternalSchema(db, i);
+ }
+ }
+ db->init.busy = 0;
+ if( rc==STQLITE_OK ){
+ db->flags |= STQLITE_Initialized;
+ sqliteCommitInternalChanges(db);
+ }
+
+ /* If the database is in formats 1 or 2, then upgrade it to
+ ** version 3. This will reconstruct all indices. If the
+ ** upgrade fails for any reason (ex: out of disk space, database
+ ** is read only, interrupt received, etc.) then fail the init.
+ */
+ if( rc==STQLITE_OK && db->file_format<3 ){
+ char *zErr = 0;
+ InitData initData;
+ int meta[STQLITE_N_BTREE_META];
+
+ db->magic = STQLITE_MAGIC_OPEN;
+ initData.db = db;
+ initData.pzErrMsg = &zErr;
+ db->file_format = 3;
+ rc = sqlite_exec(db,
+ "BEGIN; SELECT name FROM sqlite_master WHERE type='table';",
+ upgrade_3_callback,
+ &initData,
+ &zErr);
+ if( rc==STQLITE_OK ){
+ sqliteBtreeGetMeta(db->aDb[0].pBt, meta);
+ meta[2] = 4;
+ sqliteBtreeUpdateMeta(db->aDb[0].pBt, meta);
+ sqlite_exec(db, "COMMIT", 0, 0, 0);
+ }
+ if( rc!=STQLITE_OK ){
+ sqliteSetString(pzErrMsg,
+ "unable to upgrade database to the version 2.6 format",
+ zErr ? ": " : 0, zErr, (char*)0);
+ }
+ sqlite_freemem(zErr);
+ }
+
+ if( rc!=STQLITE_OK ){
+ db->flags &= ~STQLITE_Initialized;
+ }
+ return rc;
+}
+
+/*
+** The version of the library
+*/
+const char rcsid[] = "@(#) \044Id: STQLite version " STQLITE_VERSION " $";
+const char sqlite_version[] = STQLITE_VERSION;
+
+/*
+** Does the library expect data to be encoded as UTF-8 or iso8859? The
+** following global constant always lets us know.
+*/
+#ifdef STQLITE_UTF8
+const char sqlite_encoding[] = "UTF-8";
+#else
+const char sqlite_encoding[] = "iso8859";
+#endif
+
+/*
+** Open a new STQLite database. Construct an "sqlite" structure to define
+** the state of this database and return a pointer to that structure.
+**
+** An attempt is made to initialize the in-memory data structures that
+** hold the database schema. But if this fails (because the schema file
+** is locked) then that step is deferred until the first call to
+** sqlite_exec().
+*/
+sqlite *sqlite_open(const char *zFilename, int mode, char **pzErrMsg){
+ sqlite *db;
+ int rc, i;
+
+ /* Allocate the sqlite data structure */
+ db = sqliteMalloc( sizeof(sqlite) );
+ if( pzErrMsg ) *pzErrMsg = 0;
+ if( db==0 ) goto no_mem_on_open;
+ db->onError = OE_Default;
+ db->priorNewRowid = 0;
+ db->magic = STQLITE_MAGIC_BUSY;
+ db->nDb = 2;
+ db->aDb = db->aDbStatic;
+ /* db->flags |= STQLITE_ShortColNames; */
+ sqliteHashInit(&db->aFunc, STQLITE_HASH_STRING, 1);
+ for(i=0; i<db->nDb; i++){
+ sqliteHashInit(&db->aDb[i].tblHash, STQLITE_HASH_STRING, 0);
+ sqliteHashInit(&db->aDb[i].idxHash, STQLITE_HASH_STRING, 0);
+ sqliteHashInit(&db->aDb[i].trigHash, STQLITE_HASH_STRING, 0);
+ sqliteHashInit(&db->aDb[i].aFKey, STQLITE_HASH_STRING, 1);
+ }
+
+ /* Open the backend database driver */
+ if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
+ db->temp_store = 2;
+ }
+ rc = sqliteBtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
+ if( rc!=STQLITE_OK ){
+ switch( rc ){
+ default: {
+ sqliteSetString(pzErrMsg, "unable to open database: ",
+ zFilename, (char*)0);
+ }
+ }
+ sqliteFree(db);
+ sqliteStrRealloc(pzErrMsg);
+ return 0;
+ }
+ db->aDb[0].zName = "main";
+ db->aDb[1].zName = "temp";
+
+ /* Attempt to read the schema */
+ sqliteRegisterBuiltinFunctions(db);
+ rc = sqliteInit(db, pzErrMsg);
+ db->magic = STQLITE_MAGIC_OPEN;
+ if( sqlite_malloc_failed ){
+ sqlite_close(db);
+ goto no_mem_on_open;
+ }else if( rc!=STQLITE_OK && rc!=STQLITE_BUSY ){
+ sqlite_close(db);
+ sqliteStrRealloc(pzErrMsg);
+ return 0;
+ }else if( pzErrMsg ){
+ sqliteFree(*pzErrMsg);
+ *pzErrMsg = 0;
+ }
+
+ /* Return a pointer to the newly opened database structure */
+ return db;
+
+no_mem_on_open:
+ sqliteSetString(pzErrMsg, "out of memory", (char*)0);
+ sqliteStrRealloc(pzErrMsg);
+ return 0;
+}
+
+/*
+** Return the ROWID of the most recent insert
+*/
+int sqlite_last_insert_rowid(sqlite *db){
+ return db->lastRowid;
+}
+
+/*
+** Return the number of changes in the most recent call to sqlite_exec().
+*/
+int sqlite_changes(sqlite *db){
+ return db->nChange;
+}
+
+/*
+** Return the number of changes produced by the last INSERT, UPDATE, or
+** DELETE statement to complete execution. The count does not include
+** changes due to SQL statements executed in trigger programs that were
+** triggered by that statement
+*/
+int sqlite_last_statement_changes(sqlite *db){
+ return db->lsChange;
+}
+
+/*
+** Close an existing STQLite database
+*/
+void sqlite_close(sqlite *db){
+ HashElem *i;
+ int j;
+ db->want_to_close = 1;
+ if( sqliteSafetyCheck(db) || sqliteSafetyOn(db) ){
+ /* printf("DID NOT CLOSE\n"); fflush(stdout); */
+ return;
+ }
+ db->magic = STQLITE_MAGIC_CLOSED;
+ for(j=0; j<db->nDb; j++){
+ struct Db *pDb = &db->aDb[j];
+ if( pDb->pBt ){
+ sqliteBtreeClose(pDb->pBt);
+ pDb->pBt = 0;
+ }
+ }
+ sqliteResetInternalSchema(db, 0);
+ assert( db->nDb<=2 );
+ assert( db->aDb==db->aDbStatic );
+ for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){
+ FuncDef *pFunc, *pNext;
+ for(pFunc = (FuncDef*)sqliteHashData(i); pFunc; pFunc=pNext){
+ pNext = pFunc->pNext;
+ sqliteFree(pFunc);
+ }
+ }
+ sqliteHashClear(&db->aFunc);
+ sqliteFree(db);
+}
+
+/*
+** Rollback all database files.
+*/
+void sqliteRollbackAll(sqlite *db){
+ int i;
+ for(i=0; i<db->nDb; i++){
+ if( db->aDb[i].pBt ){
+ sqliteBtreeRollback(db->aDb[i].pBt);
+ db->aDb[i].inTrans = 0;
+ }
+ }
+ sqliteResetInternalSchema(db, 0);
+ /* sqliteRollbackInternalChanges(db); */
+}
+
+/*
+** Execute SQL code. Return one of the STQLITE_ success/failure
+** codes. Also write an error message into memory obtained from
+** malloc() and make *pzErrMsg point to that message.
+**
+** If the SQL is a query, then for each row in the query result
+** the xCallback() function is called. pArg becomes the first
+** argument to xCallback(). If xCallback=NULL then no callback
+** is invoked, even for queries.
+*/
+int sqlite_exec(
+ sqlite *db, /* The database on which the SQL executes */
+ const char *zSql, /* The SQL to be executed */
+ sqlite_callback xCallback, /* Invoke this callback routine */
+ void *pArg, /* First argument to xCallback() */
+ char **pzErrMsg /* Write error messages here */
+){
+ int rc = STQLITE_OK;
+ const char *zLeftover;
+ sqlite_vm *pVm;
+ int nRetry = 0;
+ int nChange = 0;
+ int nCallback;
+
+ if( zSql==0 ) return STQLITE_OK;
+ while( rc==STQLITE_OK && zSql[0] ){
+ pVm = 0;
+ rc = sqlite_compile(db, zSql, &zLeftover, &pVm, pzErrMsg);
+ if( rc!=STQLITE_OK ){
+ assert( pVm==0 || sqlite_malloc_failed );
+ return rc;
+ }
+ if( pVm==0 ){
+ /* This happens if the zSql input contained only whitespace */
+ break;
+ }
+ db->nChange += nChange;
+ nCallback = 0;
+ while(1){
+ int nArg;
+ char **azArg, **azCol;
+ rc = sqlite_step(pVm, &nArg, (const char***)&azArg,(const char***)&azCol);
+ if( rc==STQLITE_ROW ){
+ if( xCallback!=0 && xCallback(pArg, nArg, azArg, azCol) ){
+ sqlite_finalize(pVm, 0);
+ return STQLITE_ABORT;
+ }
+ nCallback++;
+ }else{
+ if( rc==STQLITE_DONE && nCallback==0
+ && (db->flags & STQLITE_NullCallback)!=0 && xCallback!=0 ){
+ xCallback(pArg, nArg, azArg, azCol);
+ }
+ rc = sqlite_finalize(pVm, pzErrMsg);
+ if( rc==STQLITE_SCHEMA && nRetry<2 ){
+ nRetry++;
+ rc = STQLITE_OK;
+ break;
+ }
+ if( db->pVdbe==0 ){
+ nChange = db->nChange;
+ }
+ nRetry = 0;
+ zSql = zLeftover;
+ while( isspace(zSql[0]) ) zSql++;
+ break;
+ }
+ }
+ }
+ return rc;
+}
+
+
+/*
+** Compile a single statement of SQL into a virtual machine. Return one
+** of the STQLITE_ success/failure codes. Also write an error message into
+** memory obtained from malloc() and make *pzErrMsg point to that message.
+*/
+int sqlite_compile(
+ sqlite *db, /* The database on which the SQL executes */
+ const char *zSql, /* The SQL to be executed */
+ const char **pzTail, /* OUT: Next statement after the first */
+ sqlite_vm **ppVm, /* OUT: The virtual machine */
+ char **pzErrMsg /* OUT: Write error messages here */
+){
+ Parse sParse;
+
+ if( pzErrMsg ) *pzErrMsg = 0;
+ if( sqliteSafetyOn(db) ) goto exec_misuse;
+ if( !db->init.busy ){
+ if( (db->flags & STQLITE_Initialized)==0 ){
+ int rc, cnt = 1;
+ while( (rc = sqliteInit(db, pzErrMsg))==STQLITE_BUSY
+ && db->xBusyCallback
+ && db->xBusyCallback(db->pBusyArg, "", cnt++)!=0 ){}
+ if( rc!=STQLITE_OK ){
+ sqliteStrRealloc(pzErrMsg);
+ sqliteSafetyOff(db);
+ return rc;
+ }
+ if( pzErrMsg ){
+ sqliteFree(*pzErrMsg);
+ *pzErrMsg = 0;
+ }
+ }
+ if( db->file_format<3 ){
+ sqliteSafetyOff(db);
+ sqliteSetString(pzErrMsg, "obsolete database file format", (char*)0);
+ return STQLITE_ERROR;
+ }
+ }
+ assert( (db->flags & STQLITE_Initialized)!=0 || db->init.busy );
+ if( db->pVdbe==0 ){ db->nChange = 0; }
+ memset(&sParse, 0, sizeof(sParse));
+ sParse.db = db;
+ sqliteRunParser(&sParse, zSql, pzErrMsg);
+ if( db->xTrace ){
+ /* Trace only the statment that was compiled.
+ ** Make a copy of that part of the SQL string since zSQL is const
+ ** and we must pass a zero terminated string to the trace function
+ ** The copy is unnecessary if the tail pointer is pointing at the
+ ** beginnig or end of the SQL string.
+ */
+ if( sParse.zTail && sParse.zTail!=zSql && *sParse.zTail ){
+ char *tmpSql = sqliteStrNDup(zSql, sParse.zTail - zSql);
+ if( tmpSql ){
+ db->xTrace(db->pTraceArg, tmpSql);
+ free(tmpSql);
+ }else{
+ /* If a memory error occurred during the copy,
+ ** trace entire SQL string and fall through to the
+ ** sqlite_malloc_failed test to report the error.
+ */
+ db->xTrace(db->pTraceArg, zSql);
+ }
+ }else{
+ db->xTrace(db->pTraceArg, zSql);
+ }
+ }
+ if( sqlite_malloc_failed ){
+ sqliteSetString(pzErrMsg, "out of memory", (char*)0);
+ sParse.rc = STQLITE_NOMEM;
+ sqliteRollbackAll(db);
+ sqliteResetInternalSchema(db, 0);
+ db->flags &= ~STQLITE_InTrans;
+ }
+ if( sParse.rc==STQLITE_DONE ) sParse.rc = STQLITE_OK;
+ if( sParse.rc!=STQLITE_OK && pzErrMsg && *pzErrMsg==0 ){
+ sqliteSetString(pzErrMsg, sqlite_error_string(sParse.rc), (char*)0);
+ }
+ sqliteStrRealloc(pzErrMsg);
+ if( sParse.rc==STQLITE_SCHEMA ){
+ sqliteResetInternalSchema(db, 0);
+ }
+ assert( ppVm );
+ *ppVm = (sqlite_vm*)sParse.pVdbe;
+ if( pzTail ) *pzTail = sParse.zTail;
+ if( sqliteSafetyOff(db) ) goto exec_misuse;
+ return sParse.rc;
+
+exec_misuse:
+ if( pzErrMsg ){
+ *pzErrMsg = 0;
+ sqliteSetString(pzErrMsg, sqlite_error_string(STQLITE_MISUSE), (char*)0);
+ sqliteStrRealloc(pzErrMsg);
+ }
+ return STQLITE_MISUSE;
+}
+
+
+/*
+** The following routine destroys a virtual machine that is created by
+** the sqlite_compile() routine.
+**
+** The integer returned is an STQLITE_ success/failure code that describes
+** the result of executing the virtual machine. An error message is
+** written into memory obtained from malloc and *pzErrMsg is made to
+** point to that error if pzErrMsg is not NULL. The calling routine
+** should use sqlite_freemem() to delete the message when it has finished
+** with it.
+*/
+int sqlite_finalize(
+ sqlite_vm *pVm, /* The virtual machine to be destroyed */
+ char **pzErrMsg /* OUT: Write error messages here */
+){
+ int rc = sqliteVdbeFinalize((Vdbe*)pVm, pzErrMsg);
+ sqliteStrRealloc(pzErrMsg);
+ return rc;
+}
+
+/*
+** Terminate the current execution of a virtual machine then
+** reset the virtual machine back to its starting state so that it
+** can be reused. Any error message resulting from the prior execution
+** is written into *pzErrMsg. A success code from the prior execution
+** is returned.
+*/
+int sqlite_reset(
+ sqlite_vm *pVm, /* The virtual machine to be destroyed */
+ char **pzErrMsg /* OUT: Write error messages here */
+){
+ int rc = sqliteVdbeReset((Vdbe*)pVm, pzErrMsg);
+ sqliteVdbeMakeReady((Vdbe*)pVm, -1, 0);
+ sqliteStrRealloc(pzErrMsg);
+ return rc;
+}
+
+/*
+** Return a static string that describes the kind of error specified in the
+** argument.
+*/
+const char *sqlite_error_string(int rc){
+ const char *z;
+ switch( rc ){
+ case STQLITE_OK: z = "not an error"; break;
+ case STQLITE_ERROR: z = "SQL logic error or missing database"; break;
+ case STQLITE_INTERNAL: z = "internal STQLite implementation flaw"; break;
+ case STQLITE_PERM: z = "access permission denied"; break;
+ case STQLITE_ABORT: z = "callback requested query abort"; break;
+ case STQLITE_BUSY: z = "database is locked"; break;
+ case STQLITE_LOCKED: z = "database table is locked"; break;
+ case STQLITE_NOMEM: z = "out of memory"; break;
+ case STQLITE_READONLY: z = "attempt to write a readonly database"; break;
+ case STQLITE_INTERRUPT: z = "interrupted"; break;
+ case STQLITE_IOERR: z = "disk I/O error"; break;
+ case STQLITE_CORRUPT: z = "database disk image is malformed"; break;
+ case STQLITE_NOTFOUND: z = "table or record not found"; break;
+ case STQLITE_FULL: z = "database is full"; break;
+ case STQLITE_CANTOPEN: z = "unable to open database file"; break;
+ case STQLITE_PROTOCOL: z = "database locking protocol failure"; break;
+ case STQLITE_EMPTY: z = "table tqcontains no data"; break;
+ case STQLITE_SCHEMA: z = "database schema has changed"; break;
+ case STQLITE_TOOBIG: z = "too much data for one table row"; break;
+ case STQLITE_CONSTRAINT: z = "constraint failed"; break;
+ case STQLITE_MISMATCH: z = "datatype mismatch"; break;
+ case STQLITE_MISUSE: z = "library routine called out of sequence";break;
+ case STQLITE_NOLFS: z = "kernel lacks large file support"; break;
+ case STQLITE_AUTH: z = "authorization denied"; break;
+ case STQLITE_FORMAT: z = "auxiliary database format error"; break;
+ case STQLITE_RANGE: z = "bind index out of range"; break;
+ case STQLITE_NOTADB: z = "file is encrypted or is not a database";break;
+ default: z = "unknown error"; break;
+ }
+ return z;
+}
+
+/*
+** This routine implements a busy callback that sleeps and tries
+** again until a timeout value is reached. The timeout value is
+** an integer number of milliseconds passed in as the first
+** argument.
+*/
+static int sqliteDefaultBusyCallback(
+ void *Timeout, /* Maximum amount of time to wait */
+ const char *NotUsed, /* The name of the table that is busy */
+ int count /* Number of times table has been busy */
+){
+#if STQLITE_MIN_SLEEP_MS==1
+ static const char delays[] =
+ { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 50, 100};
+ static const short int totals[] =
+ { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228, 287};
+# define NDELAY (sizeof(delays)/sizeof(delays[0]))
+ int timeout = (int)Timeout;
+ int delay, prior;
+
+ if( count <= NDELAY ){
+ delay = delays[count-1];
+ prior = totals[count-1];
+ }else{
+ delay = delays[NDELAY-1];
+ prior = totals[NDELAY-1] + delay*(count-NDELAY-1);
+ }
+ if( prior + delay > timeout ){
+ delay = timeout - prior;
+ if( delay<=0 ) return 0;
+ }
+ sqliteOsSleep(delay);
+ return 1;
+#else
+ int timeout = (int)Timeout;
+ if( (count+1)*1000 > timeout ){
+ return 0;
+ }
+ sqliteOsSleep(1000);
+ return 1;
+#endif
+}
+
+/*
+** This routine sets the busy callback for an Sqlite database to the
+** given callback function with the given argument.
+*/
+void sqlite_busy_handler(
+ sqlite *db,
+ int (*xBusy)(void*,const char*,int),
+ void *pArg
+){
+ db->xBusyCallback = xBusy;
+ db->pBusyArg = pArg;
+}
+
+#ifndef STQLITE_OMIT_PROGRESS_CALLBACK
+/*
+** This routine sets the progress callback for an Sqlite database to the
+** given callback function with the given argument. The progress callback will
+** be invoked every nOps opcodes.
+*/
+void sqlite_progress_handler(
+ sqlite *db,
+ int nOps,
+ int (*xProgress)(void*),
+ void *pArg
+){
+ if( nOps>0 ){
+ db->xProgress = xProgress;
+ db->nProgressOps = nOps;
+ db->pProgressArg = pArg;
+ }else{
+ db->xProgress = 0;
+ db->nProgressOps = 0;
+ db->pProgressArg = 0;
+ }
+}
+#endif
+
+
+/*
+** This routine installs a default busy handler that waits for the
+** specified number of milliseconds before returning 0.
+*/
+void sqlite_busy_timeout(sqlite *db, int ms){
+ if( ms>0 ){
+ sqlite_busy_handler(db, sqliteDefaultBusyCallback, (void*)ms);
+ }else{
+ sqlite_busy_handler(db, 0, 0);
+ }
+}
+
+/*
+** Cause any pending operation to stop at its earliest opportunity.
+*/
+void sqlite_interrupt(sqlite *db){
+ db->flags |= STQLITE_Interrupt;
+}
+
+/*
+** Windows systems should call this routine to free memory that
+** is returned in the in the errmsg parameter of sqlite_open() when
+** STQLite is a DLL. For some reason, it does not work to call free()
+** directly.
+**
+** Note that we need to call free() not sqliteFree() here, since every
+** string that is exported from STQLite should have already passed through
+** sqliteStrRealloc().
+*/
+void sqlite_freemem(void *p){ free(p); }
+
+/*
+** Windows systems need functions to call to return the sqlite_version
+** and sqlite_encoding strings since they are unable to access constants
+** within DLLs.
+*/
+const char *sqlite_libversion(void){ return sqlite_version; }
+const char *sqlite_libencoding(void){ return sqlite_encoding; }
+
+/*
+** Create new user-defined functions. The sqlite_create_function()
+** routine creates a regular function and sqlite_create_aggregate()
+** creates an aggregate function.
+**
+** Passing a NULL xFunc argument or NULL xStep and xFinalize arguments
+** disables the function. Calling sqlite_create_function() with the
+** same name and number of arguments as a prior call to
+** sqlite_create_aggregate() disables the prior call to
+** sqlite_create_aggregate(), and vice versa.
+**
+** If nArg is -1 it means that this function will accept any number
+** of arguments, including 0. The maximum allowed value of nArg is 127.
+*/
+int sqlite_create_function(
+ sqlite *db, /* Add the function to this database connection */
+ const char *zName, /* Name of the function to add */
+ int nArg, /* Number of arguments */
+ void (*xFunc)(sqlite_func*,int,const char**), /* The implementation */
+ void *pUserData /* User data */
+){
+ FuncDef *p;
+ int nName;
+ if( db==0 || zName==0 || sqliteSafetyCheck(db) ) return 1;
+ if( nArg<-1 || nArg>127 ) return 1;
+ nName = strlen(zName);
+ if( nName>255 ) return 1;
+ p = sqliteFindFunction(db, zName, nName, nArg, 1);
+ if( p==0 ) return 1;
+ p->xFunc = xFunc;
+ p->xStep = 0;
+ p->xFinalize = 0;
+ p->pUserData = pUserData;
+ return 0;
+}
+int sqlite_create_aggregate(
+ sqlite *db, /* Add the function to this database connection */
+ const char *zName, /* Name of the function to add */
+ int nArg, /* Number of arguments */
+ void (*xStep)(sqlite_func*,int,const char**), /* The step function */
+ void (*xFinalize)(sqlite_func*), /* The finalizer */
+ void *pUserData /* User data */
+){
+ FuncDef *p;
+ int nName;
+ if( db==0 || zName==0 || sqliteSafetyCheck(db) ) return 1;
+ if( nArg<-1 || nArg>127 ) return 1;
+ nName = strlen(zName);
+ if( nName>255 ) return 1;
+ p = sqliteFindFunction(db, zName, nName, nArg, 1);
+ if( p==0 ) return 1;
+ p->xFunc = 0;
+ p->xStep = xStep;
+ p->xFinalize = xFinalize;
+ p->pUserData = pUserData;
+ return 0;
+}
+
+/*
+** Change the datatype for all functions with a given name. See the
+** header comment for the prototype of this function in sqlite.h for
+** additional information.
+*/
+int sqlite_function_type(sqlite *db, const char *zName, int dataType){
+ FuncDef *p = (FuncDef*)sqliteHashFind(&db->aFunc, zName, strlen(zName));
+ while( p ){
+ p->dataType = dataType;
+ p = p->pNext;
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Register a trace function. The pArg from the previously registered trace
+** is returned.
+**
+** A NULL trace function means that no tracing is executes. A non-NULL
+** trace is a pointer to a function that is invoked at the start of each
+** sqlite_exec().
+*/
+void *sqlite_trace(sqlite *db, void (*xTrace)(void*,const char*), void *pArg){
+ void *pOld = db->pTraceArg;
+ db->xTrace = xTrace;
+ db->pTraceArg = pArg;
+ return pOld;
+}
+
+/*** EXPERIMENTAL ***
+**
+** Register a function to be invoked when a transaction comments.
+** If either function returns non-zero, then the commit becomes a
+** rollback.
+*/
+void *sqlite_commit_hook(
+ sqlite *db, /* Attach the hook to this database */
+ int (*xCallback)(void*), /* Function to invoke on each commit */
+ void *pArg /* Argument to the function */
+){
+ void *pOld = db->pCommitArg;
+ db->xCommitCallback = xCallback;
+ db->pCommitArg = pArg;
+ return pOld;
+}
+
+
+/*
+** This routine is called to create a connection to a database BTree
+** driver. If zFilename is the name of a file, then that file is
+** opened and used. If zFilename is the magic name ":memory:" then
+** the database is stored in memory (and is thus forgotten as soon as
+** the connection is closed.) If zFilename is NULL then the database
+** is for temporary use only and is deleted as soon as the connection
+** is closed.
+**
+** A temporary database can be either a disk file (that is automatically
+** deleted when the file is closed) or a set of red-black trees held in memory,
+** depending on the values of the TEMP_STORE compile-time macro and the
+** db->temp_store variable, according to the following chart:
+**
+** TEMP_STORE db->temp_store Location of temporary database
+** ---------- -------------- ------------------------------
+** 0 any file
+** 1 1 file
+** 1 2 memory
+** 1 0 file
+** 2 1 file
+** 2 2 memory
+** 2 0 memory
+** 3 any memory
+*/
+int sqliteBtreeFactory(
+ const sqlite *db, /* Main database when opening aux otherwise 0 */
+ const char *zFilename, /* Name of the file containing the BTree database */
+ int omitJournal, /* if TRUE then do not journal this file */
+ int nCache, /* How many pages in the page cache */
+ Btree **ppBtree){ /* Pointer to new Btree object written here */
+
+ assert( ppBtree != 0);
+
+#ifndef STQLITE_OMIT_INMEMORYDB
+ if( zFilename==0 ){
+ if (TEMP_STORE == 0) {
+ /* Always use file based temporary DB */
+ return sqliteBtreeOpen(0, omitJournal, nCache, ppBtree);
+ } else if (TEMP_STORE == 1 || TEMP_STORE == 2) {
+ /* Switch depending on compile-time and/or runtime settings. */
+ int location = db->temp_store==0 ? TEMP_STORE : db->temp_store;
+
+ if (location == 1) {
+ return sqliteBtreeOpen(zFilename, omitJournal, nCache, ppBtree);
+ } else {
+ return sqliteRbtreeOpen(0, 0, 0, ppBtree);
+ }
+ } else {
+ /* Always use in-core DB */
+ return sqliteRbtreeOpen(0, 0, 0, ppBtree);
+ }
+ }else if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
+ return sqliteRbtreeOpen(0, 0, 0, ppBtree);
+ }else
+#endif
+ {
+ return sqliteBtreeOpen(zFilename, omitJournal, nCache, ppBtree);
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/opcodes.c b/tqtinterface/qt4/src/3rdparty/sqlite/opcodes.c
new file mode 100644
index 0000000..df5b3c8
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/opcodes.c
@@ -0,0 +1,138 @@
+/* Automatically generated file. Do not edit */
+char *sqliteOpcodeNames[] = { "???",
+ "Goto",
+ "Gosub",
+ "Return",
+ "Halt",
+ "Integer",
+ "String",
+ "Variable",
+ "Pop",
+ "Dup",
+ "Pull",
+ "Push",
+ "ColumnName",
+ "Callback",
+ "Concat",
+ "Add",
+ "Subtract",
+ "Multiply",
+ "Divide",
+ "Remainder",
+ "Function",
+ "BitAnd",
+ "BitOr",
+ "ShiftLeft",
+ "ShiftRight",
+ "AddImm",
+ "ForceInt",
+ "MustBeInt",
+ "Eq",
+ "Ne",
+ "Lt",
+ "Le",
+ "Gt",
+ "Ge",
+ "StrEq",
+ "StrNe",
+ "StrLt",
+ "StrLe",
+ "StrGt",
+ "StrGe",
+ "And",
+ "Or",
+ "Negative",
+ "AbsValue",
+ "Not",
+ "BitNot",
+ "Noop",
+ "If",
+ "IfNot",
+ "IsNull",
+ "NotNull",
+ "MakeRecord",
+ "MakeIdxKey",
+ "MakeKey",
+ "IncrKey",
+ "Checkpoint",
+ "Transaction",
+ "Commit",
+ "Rollback",
+ "ReadCookie",
+ "SetCookie",
+ "VerifyCookie",
+ "OpenRead",
+ "OpenWrite",
+ "OpenTemp",
+ "OpenPseudo",
+ "Close",
+ "MoveLt",
+ "MoveTo",
+ "Distinct",
+ "NotFound",
+ "Found",
+ "IsUnique",
+ "NotExists",
+ "NewRecno",
+ "PutIntKey",
+ "PutStrKey",
+ "Delete",
+ "SetCounts",
+ "KeyAsData",
+ "RowKey",
+ "RowData",
+ "Column",
+ "Recno",
+ "FullKey",
+ "NullRow",
+ "Last",
+ "Rewind",
+ "Prev",
+ "Next",
+ "IdxPut",
+ "IdxDelete",
+ "IdxRecno",
+ "IdxLT",
+ "IdxGT",
+ "IdxGE",
+ "IdxIsNull",
+ "Destroy",
+ "Clear",
+ "CreateIndex",
+ "CreateTable",
+ "IntegrityCk",
+ "ListWrite",
+ "ListRewind",
+ "ListRead",
+ "ListReset",
+ "ListPush",
+ "ListPop",
+ "ContextPush",
+ "ContextPop",
+ "SortPut",
+ "SortMakeRec",
+ "SortMakeKey",
+ "Sort",
+ "SortNext",
+ "SortCallback",
+ "SortReset",
+ "FileOpen",
+ "FileRead",
+ "FileColumn",
+ "MemStore",
+ "MemLoad",
+ "MemIncr",
+ "AggReset",
+ "AggInit",
+ "AggFunc",
+ "AggFocus",
+ "AggSet",
+ "AggGet",
+ "AggNext",
+ "SetInsert",
+ "SetFound",
+ "SetNotFound",
+ "SetFirst",
+ "SetNext",
+ "Vacuum",
+};
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/opcodes.h b/tqtinterface/qt4/src/3rdparty/sqlite/opcodes.h
new file mode 100644
index 0000000..a6bc6d4
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/opcodes.h
@@ -0,0 +1,136 @@
+/* Automatically generated file. Do not edit */
+#define OP_Goto 1
+#define OP_Gosub 2
+#define OP_Return 3
+#define OP_Halt 4
+#define OP_Integer 5
+#define OP_String 6
+#define OP_Variable 7
+#define OP_Pop 8
+#define OP_Dup 9
+#define OP_Pull 10
+#define OP_Push 11
+#define OP_ColumnName 12
+#define OP_Callback 13
+#define OP_Concat 14
+#define OP_Add 15
+#define OP_Subtract 16
+#define OP_Multiply 17
+#define OP_Divide 18
+#define OP_Remainder 19
+#define OP_Function 20
+#define OP_BitAnd 21
+#define OP_BitOr 22
+#define OP_ShiftLeft 23
+#define OP_ShiftRight 24
+#define OP_AddImm 25
+#define OP_ForceInt 26
+#define OP_MustBeInt 27
+#define OP_Eq 28
+#define OP_Ne 29
+#define OP_Lt 30
+#define OP_Le 31
+#define OP_Gt 32
+#define OP_Ge 33
+#define OP_StrEq 34
+#define OP_StrNe 35
+#define OP_StrLt 36
+#define OP_StrLe 37
+#define OP_StrGt 38
+#define OP_StrGe 39
+#define OP_And 40
+#define OP_Or 41
+#define OP_Negative 42
+#define OP_AbsValue 43
+#define OP_Not 44
+#define OP_BitNot 45
+#define OP_Noop 46
+#define OP_If 47
+#define OP_IfNot 48
+#define OP_IsNull 49
+#define OP_NotNull 50
+#define OP_MakeRecord 51
+#define OP_MakeIdxKey 52
+#define OP_MakeKey 53
+#define OP_IncrKey 54
+#define OP_Checkpoint 55
+#define OP_Transaction 56
+#define OP_Commit 57
+#define OP_Rollback 58
+#define OP_ReadCookie 59
+#define OP_SetCookie 60
+#define OP_VerifyCookie 61
+#define OP_OpenRead 62
+#define OP_OpenWrite 63
+#define OP_OpenTemp 64
+#define OP_OpenPseudo 65
+#define OP_Close 66
+#define OP_MoveLt 67
+#define OP_MoveTo 68
+#define OP_Distinct 69
+#define OP_NotFound 70
+#define OP_Found 71
+#define OP_IsUnique 72
+#define OP_NotExists 73
+#define OP_NewRecno 74
+#define OP_PutIntKey 75
+#define OP_PutStrKey 76
+#define OP_Delete 77
+#define OP_SetCounts 78
+#define OP_KeyAsData 79
+#define OP_RowKey 80
+#define OP_RowData 81
+#define OP_Column 82
+#define OP_Recno 83
+#define OP_FullKey 84
+#define OP_NullRow 85
+#define OP_Last 86
+#define OP_Rewind 87
+#define OP_Prev 88
+#define OP_Next 89
+#define OP_IdxPut 90
+#define OP_IdxDelete 91
+#define OP_IdxRecno 92
+#define OP_IdxLT 93
+#define OP_IdxGT 94
+#define OP_IdxGE 95
+#define OP_IdxIsNull 96
+#define OP_Destroy 97
+#define OP_Clear 98
+#define OP_CreateIndex 99
+#define OP_CreateTable 100
+#define OP_IntegrityCk 101
+#define OP_ListWrite 102
+#define OP_ListRewind 103
+#define OP_ListRead 104
+#define OP_ListReset 105
+#define OP_ListPush 106
+#define OP_ListPop 107
+#define OP_ContextPush 108
+#define OP_ContextPop 109
+#define OP_SortPut 110
+#define OP_SortMakeRec 111
+#define OP_SortMakeKey 112
+#define OP_Sort 113
+#define OP_SortNext 114
+#define OP_SortCallback 115
+#define OP_SortReset 116
+#define OP_FileOpen 117
+#define OP_FileRead 118
+#define OP_FileColumn 119
+#define OP_MemStore 120
+#define OP_MemLoad 121
+#define OP_MemIncr 122
+#define OP_AggReset 123
+#define OP_AggInit 124
+#define OP_AggFunc 125
+#define OP_AggFocus 126
+#define OP_AggSet 127
+#define OP_AggGet 128
+#define OP_AggNext 129
+#define OP_SetInsert 130
+#define OP_SetFound 131
+#define OP_SetNotFound 132
+#define OP_SetFirst 133
+#define OP_SetNext 134
+#define OP_Vacuum 135
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/os.c b/tqtinterface/qt4/src/3rdparty/sqlite/os.c
new file mode 100644
index 0000000..1a1b583
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/os.c
@@ -0,0 +1,1818 @@
+/*
+** 2001 September 16
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file tqcontains code that is specific to particular operating
+** systems. The purpose of this file is to provide a uniform abstraction
+** on which the rest of STQLite can operate.
+*/
+#include "os.h" /* Must be first to enable large file support */
+#include "sqliteInt.h"
+
+#if OS_UNIX
+# include <time.h>
+# include <errno.h>
+# include <unistd.h>
+# ifndef O_LARGEFILE
+# define O_LARGEFILE 0
+# endif
+# ifdef STQLITE_DISABLE_LFS
+# undef O_LARGEFILE
+# define O_LARGEFILE 0
+# endif
+# ifndef O_NOFOLLOW
+# define O_NOFOLLOW 0
+# endif
+# ifndef O_BINARY
+# define O_BINARY 0
+# endif
+#endif
+
+
+#if OS_WIN
+# include <winbase.h>
+#endif
+
+#if OS_MAC
+# include <extras.h>
+# include <path2fss.h>
+# include <TextUtils.h>
+# include <FinderRegistry.h>
+# include <Folders.h>
+# include <Timer.h>
+# include <OSUtils.h>
+#endif
+
+/*
+** The DJGPP compiler environment looks mostly like Unix, but it
+** lacks the fcntl() system call. So redefine fcntl() to be something
+** that always succeeds. This means that locking does not occur under
+** DJGPP. But its DOS - what did you expect?
+*/
+#ifdef __DJGPP__
+# define fcntl(A,B,C) 0
+#endif
+
+/*
+** Macros used to determine whether or not to use threads. The
+** STQLITE_UNIX_THREADS macro is defined if we are synchronizing for
+** Posix threads and STQLITE_W32_THREADS is defined if we are
+** synchronizing using Win32 threads.
+*/
+#if OS_UNIX && defined(THREADSAFE) && THREADSAFE
+# include <pthread.h>
+# define STQLITE_UNIX_THREADS 1
+#endif
+#if OS_WIN && defined(THREADSAFE) && THREADSAFE
+# define STQLITE_W32_THREADS 1
+#endif
+#if OS_MAC && defined(THREADSAFE) && THREADSAFE
+# include <Multiprocessing.h>
+# define STQLITE_MACOS_MULTITASKING 1
+#endif
+
+/*
+** Macros for performance tracing. Normally turned off
+*/
+#if 0
+static int last_page = 0;
+__inline__ unsigned long long int hwtime(void){
+ unsigned long long int x;
+ __asm__("rdtsc\n\t"
+ "mov %%edx, %%ecx\n\t"
+ :"=A" (x));
+ return x;
+}
+static unsigned long long int g_start;
+static unsigned int elapse;
+#define TIMER_START g_start=hwtime()
+#define TIMER_END elapse=hwtime()-g_start
+#define SEEK(X) last_page=(X)
+#define TRACE1(X) fprintf(stderr,X)
+#define TRACE2(X,Y) fprintf(stderr,X,Y)
+#define TRACE3(X,Y,Z) fprintf(stderr,X,Y,Z)
+#define TRACE4(X,Y,Z,A) fprintf(stderr,X,Y,Z,A)
+#define TRACE5(X,Y,Z,A,B) fprintf(stderr,X,Y,Z,A,B)
+#else
+#define TIMER_START
+#define TIMER_END
+#define SEEK(X)
+#define TRACE1(X)
+#define TRACE2(X,Y)
+#define TRACE3(X,Y,Z)
+#define TRACE4(X,Y,Z,A)
+#define TRACE5(X,Y,Z,A,B)
+#endif
+
+
+#if OS_UNIX
+/*
+** Here is the dirt on POSIX advisory locks: ANSI STD 1003.1 (1996)
+** section 6.5.2.2 lines 483 through 490 specify that when a process
+** sets or clears a lock, that operation overrides any prior locks set
+** by the same process. It does not explicitly say so, but this implies
+** that it overrides locks set by the same process using a different
+** file descriptor. Consider this test case:
+**
+** int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
+** int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
+**
+** Suppose ./file1 and ./file2 are really the same file (because
+** one is a hard or symbolic link to the other) then if you set
+** an exclusive lock on fd1, then try to get an exclusive lock
+** on fd2, it works. I would have expected the second lock to
+** fail since there was already a lock on the file due to fd1.
+** But not so. Since both locks came from the same process, the
+** second overrides the first, even though they were on different
+** file descriptors opened on different file names.
+**
+** Bummer. If you ask me, this is broken. Badly broken. It means
+** that we cannot use POSIX locks to synchronize file access among
+** competing threads of the same process. POSIX locks will work fine
+** to synchronize access for threads in separate processes, but not
+** threads within the same process.
+**
+** To work around the problem, STQLite has to manage file locks internally
+** on its own. Whenever a new database is opened, we have to tqfind the
+** specific inode of the database file (the inode is determined by the
+** st_dev and st_ino fields of the stat structure that fstat() fills in)
+** and check for locks already existing on that inode. When locks are
+** created or removed, we have to look at our own internal record of the
+** locks to see if another thread has previously set a lock on that same
+** inode.
+**
+** The OsFile structure for POSIX is no longer just an integer file
+** descriptor. It is now a structure that holds the integer file
+** descriptor and a pointer to a structure that describes the internal
+** locks on the corresponding inode. There is one locking structure
+** per inode, so if the same inode is opened twice, both OsFile structures
+** point to the same locking structure. The locking structure keeps
+** a reference count (so we will know when to delete it) and a "cnt"
+** field that tells us its internal lock status. cnt==0 means the
+** file is unlocked. cnt==-1 means the file has an exclusive lock.
+** cnt>0 means there are cnt shared locks on the file.
+**
+** Any attempt to lock or unlock a file first checks the locking
+** structure. The fcntl() system call is only invoked to set a
+** POSIX lock if the internal lock structure transitions between
+** a locked and an unlocked state.
+**
+** 2004-Jan-11:
+** More recent discoveries about POSIX advisory locks. (The more
+** I discover, the more I realize the a POSIX advisory locks are
+** an abomination.)
+**
+** If you close a file descriptor that points to a file that has locks,
+** all locks on that file that are owned by the current process are
+** released. To work around this problem, each OsFile structure tqcontains
+** a pointer to an openCnt structure. There is one openCnt structure
+** per open inode, which means that multiple OsFiles can point to a single
+** openCnt. When an attempt is made to close an OsFile, if there are
+** other OsFiles open on the same inode that are holding locks, the call
+** to close() the file descriptor is deferred until all of the locks clear.
+** The openCnt structure keeps a list of file descriptors that need to
+** be closed and that list is walked (and cleared) when the last lock
+** clears.
+**
+** First, under Linux threads, because each thread has a separate
+** process ID, lock operations in one thread do not override locks
+** to the same file in other threads. Linux threads behave like
+** separate processes in this respect. But, if you close a file
+** descriptor in linux threads, all locks are cleared, even locks
+** on other threads and even though the other threads have different
+** process IDs. Linux threads is inconsistent in this respect.
+** (I'm beginning to think that linux threads is an abomination too.)
+** The consequence of this all is that the hash table for the lockInfo
+** structure has to include the process id as part of its key because
+** locks in different threads are treated as distinct. But the
+** openCnt structure should not include the process id in its
+** key because close() clears lock on all threads, not just the current
+** thread. Were it not for this goofiness in linux threads, we could
+** combine the lockInfo and openCnt structures into a single structure.
+*/
+
+/*
+** An instance of the following structure serves as the key used
+** to locate a particular lockInfo structure given its inode. Note
+** that we have to include the process ID as part of the key. On some
+** threading implementations (ex: linux), each thread has a separate
+** process ID.
+*/
+struct lockKey {
+ dev_t dev; /* Device number */
+ ino_t ino; /* Inode number */
+ pid_t pid; /* Process ID */
+};
+
+/*
+** An instance of the following structure is allocated for each open
+** inode on each thread with a different process ID. (Threads have
+** different process IDs on linux, but not on most other unixes.)
+**
+** A single inode can have multiple file descriptors, so each OsFile
+** structure tqcontains a pointer to an instance of this object and this
+** object keeps a count of the number of OsFiles pointing to it.
+*/
+struct lockInfo {
+ struct lockKey key; /* The lookup key */
+ int cnt; /* 0: unlocked. -1: write lock. 1...: read lock. */
+ int nRef; /* Number of pointers to this structure */
+};
+
+/*
+** An instance of the following structure serves as the key used
+** to locate a particular openCnt structure given its inode. This
+** is the same as the lockKey except that the process ID is omitted.
+*/
+struct openKey {
+ dev_t dev; /* Device number */
+ ino_t ino; /* Inode number */
+};
+
+/*
+** An instance of the following structure is allocated for each open
+** inode. This structure keeps track of the number of locks on that
+** inode. If a close is attempted against an inode that is holding
+** locks, the close is deferred until all locks clear by adding the
+** file descriptor to be closed to the pending list.
+*/
+struct openCnt {
+ struct openKey key; /* The lookup key */
+ int nRef; /* Number of pointers to this structure */
+ int nLock; /* Number of outstanding locks */
+ int nPending; /* Number of pending close() operations */
+ int *aPending; /* Malloced space holding fd's awaiting a close() */
+};
+
+/*
+** These hash table maps inodes and process IDs into lockInfo and openCnt
+** structures. Access to these hash tables must be protected by a mutex.
+*/
+static Hash lockHash = { STQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
+static Hash openHash = { STQLITE_HASH_BINARY, 0, 0, 0, 0, 0 };
+
+/*
+** Release a lockInfo structure previously allocated by tqfindLockInfo().
+*/
+static void releaseLockInfo(struct lockInfo *pLock){
+ pLock->nRef--;
+ if( pLock->nRef==0 ){
+ sqliteHashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
+ sqliteFree(pLock);
+ }
+}
+
+/*
+** Release a openCnt structure previously allocated by tqfindLockInfo().
+*/
+static void releaseOpenCnt(struct openCnt *pOpen){
+ pOpen->nRef--;
+ if( pOpen->nRef==0 ){
+ sqliteHashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
+ sqliteFree(pOpen->aPending);
+ sqliteFree(pOpen);
+ }
+}
+
+/*
+** Given a file descriptor, locate lockInfo and openCnt structures that
+** describes that file descriptor. Create a new ones if necessary. The
+** return values might be unset if an error occurs.
+**
+** Return the number of errors.
+*/
+int tqfindLockInfo(
+ int fd, /* The file descriptor used in the key */
+ struct lockInfo **ppLock, /* Return the lockInfo structure here */
+ struct openCnt **ppOpen /* Return the openCnt structure here */
+){
+ int rc;
+ struct lockKey key1;
+ struct openKey key2;
+ struct stat statbuf;
+ struct lockInfo *pLock;
+ struct openCnt *pOpen;
+ rc = fstat(fd, &statbuf);
+ if( rc!=0 ) return 1;
+ memset(&key1, 0, sizeof(key1));
+ key1.dev = statbuf.st_dev;
+ key1.ino = statbuf.st_ino;
+ key1.pid = getpid();
+ memset(&key2, 0, sizeof(key2));
+ key2.dev = statbuf.st_dev;
+ key2.ino = statbuf.st_ino;
+ pLock = (struct lockInfo*)sqliteHashFind(&lockHash, &key1, sizeof(key1));
+ if( pLock==0 ){
+ struct lockInfo *pOld;
+ pLock = sqliteMallocRaw( sizeof(*pLock) );
+ if( pLock==0 ) return 1;
+ pLock->key = key1;
+ pLock->nRef = 1;
+ pLock->cnt = 0;
+ pOld = sqliteHashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
+ if( pOld!=0 ){
+ assert( pOld==pLock );
+ sqliteFree(pLock);
+ return 1;
+ }
+ }else{
+ pLock->nRef++;
+ }
+ *ppLock = pLock;
+ pOpen = (struct openCnt*)sqliteHashFind(&openHash, &key2, sizeof(key2));
+ if( pOpen==0 ){
+ struct openCnt *pOld;
+ pOpen = sqliteMallocRaw( sizeof(*pOpen) );
+ if( pOpen==0 ){
+ releaseLockInfo(pLock);
+ return 1;
+ }
+ pOpen->key = key2;
+ pOpen->nRef = 1;
+ pOpen->nLock = 0;
+ pOpen->nPending = 0;
+ pOpen->aPending = 0;
+ pOld = sqliteHashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
+ if( pOld!=0 ){
+ assert( pOld==pOpen );
+ sqliteFree(pOpen);
+ releaseLockInfo(pLock);
+ return 1;
+ }
+ }else{
+ pOpen->nRef++;
+ }
+ *ppOpen = pOpen;
+ return 0;
+}
+
+#endif /** POSIX advisory lock work-around **/
+
+/*
+** If we compile with the STQLITE_TEST macro set, then the following block
+** of code will give us the ability to simulate a disk I/O error. This
+** is used for testing the I/O recovery logic.
+*/
+#ifdef STQLITE_TEST
+int sqlite_io_error_pending = 0;
+#define SimulateIOError(A) \
+ if( sqlite_io_error_pending ) \
+ if( sqlite_io_error_pending-- == 1 ){ local_ioerr(); return A; }
+static void local_ioerr(){
+ sqlite_io_error_pending = 0; /* Really just a place to set a breakpoint */
+}
+#else
+#define SimulateIOError(A)
+#endif
+
+/*
+** When testing, keep a count of the number of open files.
+*/
+#ifdef STQLITE_TEST
+int sqlite_open_file_count = 0;
+#define OpenCounter(X) sqlite_open_file_count+=(X)
+#else
+#define OpenCounter(X)
+#endif
+
+
+/*
+** Delete the named file
+*/
+int sqliteOsDelete(const char *zFilename){
+#if OS_UNIX
+ unlink(zFilename);
+#endif
+#if OS_WIN
+ DeleteFile(zFilename);
+#endif
+#if OS_MAC
+ unlink(zFilename);
+#endif
+ return STQLITE_OK;
+}
+
+/*
+** Return TRUE if the named file exists.
+*/
+int sqliteOsFileExists(const char *zFilename){
+#if OS_UNIX
+ return access(zFilename, 0)==0;
+#endif
+#if OS_WIN
+ return GetFileAttributes(zFilename) != 0xffffffff;
+#endif
+#if OS_MAC
+ return access(zFilename, 0)==0;
+#endif
+}
+
+
+#if 0 /* NOT USED */
+/*
+** Change the name of an existing file.
+*/
+int sqliteOsFileRename(const char *zOldName, const char *zNewName){
+#if OS_UNIX
+ if( link(zOldName, zNewName) ){
+ return STQLITE_ERROR;
+ }
+ unlink(zOldName);
+ return STQLITE_OK;
+#endif
+#if OS_WIN
+ if( !MoveFile(zOldName, zNewName) ){
+ return STQLITE_ERROR;
+ }
+ return STQLITE_OK;
+#endif
+#if OS_MAC
+ /**** FIX ME ***/
+ return STQLITE_ERROR;
+#endif
+}
+#endif /* NOT USED */
+
+/*
+** Attempt to open a file for both reading and writing. If that
+** fails, try opening it read-only. If the file does not exist,
+** try to create it.
+**
+** On success, a handle for the open file is written to *id
+** and *pReadonly is set to 0 if the file was opened for reading and
+** writing or 1 if the file was opened read-only. The function returns
+** STQLITE_OK.
+**
+** On failure, the function returns STQLITE_CANTOPEN and leaves
+** *id and *pReadonly unchanged.
+*/
+int sqliteOsOpenReadWrite(
+ const char *zFilename,
+ OsFile *id,
+ int *pReadonly
+){
+#if OS_UNIX
+ int rc;
+ id->dirfd = -1;
+ id->fd = open(zFilename, O_RDWR|O_CREAT|O_LARGEFILE|O_BINARY, 0644);
+ if( id->fd<0 ){
+ id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
+ if( id->fd<0 ){
+ return STQLITE_CANTOPEN;
+ }
+ *pReadonly = 1;
+ }else{
+ *pReadonly = 0;
+ }
+ sqliteOsEnterMutex();
+ rc = tqfindLockInfo(id->fd, &id->pLock, &id->pOpen);
+ sqliteOsLeaveMutex();
+ if( rc ){
+ close(id->fd);
+ return STQLITE_NOMEM;
+ }
+ id->locked = 0;
+ TRACE3("OPEN %-3d %s\n", id->fd, zFilename);
+ OpenCounter(+1);
+ return STQLITE_OK;
+#endif
+#if OS_WIN
+ HANDLE h = CreateFile(zFilename,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+ NULL
+ );
+ if( h==INVALID_HANDLE_VALUE ){
+ h = CreateFile(zFilename,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+ NULL
+ );
+ if( h==INVALID_HANDLE_VALUE ){
+ return STQLITE_CANTOPEN;
+ }
+ *pReadonly = 1;
+ }else{
+ *pReadonly = 0;
+ }
+ id->h = h;
+ id->locked = 0;
+ OpenCounter(+1);
+ return STQLITE_OK;
+#endif
+#if OS_MAC
+ FSSpec fsSpec;
+# ifdef _LARGE_FILE
+ HFSUniStr255 dfName;
+ FSRef fsRef;
+ if( __path2fss(zFilename, &fsSpec) != noErr ){
+ if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'STQLI', cDocumentFile) != noErr )
+ return STQLITE_CANTOPEN;
+ }
+ if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
+ return STQLITE_CANTOPEN;
+ FSGetDataForkName(&dfName);
+ if( FSOpenFork(&fsRef, dfName.length, dfName.tqunicode,
+ fsRdWrShPerm, &(id->refNum)) != noErr ){
+ if( FSOpenFork(&fsRef, dfName.length, dfName.tqunicode,
+ fsRdWrPerm, &(id->refNum)) != noErr ){
+ if (FSOpenFork(&fsRef, dfName.length, dfName.tqunicode,
+ fsRdPerm, &(id->refNum)) != noErr )
+ return STQLITE_CANTOPEN;
+ else
+ *pReadonly = 1;
+ } else
+ *pReadonly = 0;
+ } else
+ *pReadonly = 0;
+# else
+ __path2fss(zFilename, &fsSpec);
+ if( !sqliteOsFileExists(zFilename) ){
+ if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'STQLI', cDocumentFile) != noErr )
+ return STQLITE_CANTOPEN;
+ }
+ if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNum)) != noErr ){
+ if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr ){
+ if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
+ return STQLITE_CANTOPEN;
+ else
+ *pReadonly = 1;
+ } else
+ *pReadonly = 0;
+ } else
+ *pReadonly = 0;
+# endif
+ if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
+ id->refNumRF = -1;
+ }
+ id->locked = 0;
+ id->delOnClose = 0;
+ OpenCounter(+1);
+ return STQLITE_OK;
+#endif
+}
+
+
+/*
+** Attempt to open a new file for exclusive access by this process.
+** The file will be opened for both reading and writing. To avoid
+** a potential security problem, we do not allow the file to have
+** previously existed. Nor do we allow the file to be a symbolic
+** link.
+**
+** If delFlag is true, then make arrangements to automatically delete
+** the file when it is closed.
+**
+** On success, write the file handle into *id and return STQLITE_OK.
+**
+** On failure, return STQLITE_CANTOPEN.
+*/
+int sqliteOsOpenExclusive(const char *zFilename, OsFile *id, int delFlag){
+#if OS_UNIX
+ int rc;
+ if( access(zFilename, 0)==0 ){
+ return STQLITE_CANTOPEN;
+ }
+ id->dirfd = -1;
+ id->fd = open(zFilename,
+ O_RDWR|O_CREAT|O_EXCL|O_NOFOLLOW|O_LARGEFILE|O_BINARY, 0600);
+ if( id->fd<0 ){
+ return STQLITE_CANTOPEN;
+ }
+ sqliteOsEnterMutex();
+ rc = tqfindLockInfo(id->fd, &id->pLock, &id->pOpen);
+ sqliteOsLeaveMutex();
+ if( rc ){
+ close(id->fd);
+ unlink(zFilename);
+ return STQLITE_NOMEM;
+ }
+ id->locked = 0;
+ if( delFlag ){
+ unlink(zFilename);
+ }
+ TRACE3("OPEN-EX %-3d %s\n", id->fd, zFilename);
+ OpenCounter(+1);
+ return STQLITE_OK;
+#endif
+#if OS_WIN
+ HANDLE h;
+ int fileflags;
+ if( delFlag ){
+ fileflags = FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_RANDOM_ACCESS
+ | FILE_FLAG_DELETE_ON_CLOSE;
+ }else{
+ fileflags = FILE_FLAG_RANDOM_ACCESS;
+ }
+ h = CreateFile(zFilename,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ CREATE_ALWAYS,
+ fileflags,
+ NULL
+ );
+ if( h==INVALID_HANDLE_VALUE ){
+ return STQLITE_CANTOPEN;
+ }
+ id->h = h;
+ id->locked = 0;
+ OpenCounter(+1);
+ return STQLITE_OK;
+#endif
+#if OS_MAC
+ FSSpec fsSpec;
+# ifdef _LARGE_FILE
+ HFSUniStr255 dfName;
+ FSRef fsRef;
+ __path2fss(zFilename, &fsSpec);
+ if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'STQLI', cDocumentFile) != noErr )
+ return STQLITE_CANTOPEN;
+ if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
+ return STQLITE_CANTOPEN;
+ FSGetDataForkName(&dfName);
+ if( FSOpenFork(&fsRef, dfName.length, dfName.tqunicode,
+ fsRdWrPerm, &(id->refNum)) != noErr )
+ return STQLITE_CANTOPEN;
+# else
+ __path2fss(zFilename, &fsSpec);
+ if( HCreate(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, 'STQLI', cDocumentFile) != noErr )
+ return STQLITE_CANTOPEN;
+ if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrPerm, &(id->refNum)) != noErr )
+ return STQLITE_CANTOPEN;
+# endif
+ id->refNumRF = -1;
+ id->locked = 0;
+ id->delOnClose = delFlag;
+ if (delFlag)
+ id->pathToDel = sqliteOsFullPathname(zFilename);
+ OpenCounter(+1);
+ return STQLITE_OK;
+#endif
+}
+
+/*
+** Attempt to open a new file for read-only access.
+**
+** On success, write the file handle into *id and return STQLITE_OK.
+**
+** On failure, return STQLITE_CANTOPEN.
+*/
+int sqliteOsOpenReadOnly(const char *zFilename, OsFile *id){
+#if OS_UNIX
+ int rc;
+ id->dirfd = -1;
+ id->fd = open(zFilename, O_RDONLY|O_LARGEFILE|O_BINARY);
+ if( id->fd<0 ){
+ return STQLITE_CANTOPEN;
+ }
+ sqliteOsEnterMutex();
+ rc = tqfindLockInfo(id->fd, &id->pLock, &id->pOpen);
+ sqliteOsLeaveMutex();
+ if( rc ){
+ close(id->fd);
+ return STQLITE_NOMEM;
+ }
+ id->locked = 0;
+ TRACE3("OPEN-RO %-3d %s\n", id->fd, zFilename);
+ OpenCounter(+1);
+ return STQLITE_OK;
+#endif
+#if OS_WIN
+ HANDLE h = CreateFile(zFilename,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
+ NULL
+ );
+ if( h==INVALID_HANDLE_VALUE ){
+ return STQLITE_CANTOPEN;
+ }
+ id->h = h;
+ id->locked = 0;
+ OpenCounter(+1);
+ return STQLITE_OK;
+#endif
+#if OS_MAC
+ FSSpec fsSpec;
+# ifdef _LARGE_FILE
+ HFSUniStr255 dfName;
+ FSRef fsRef;
+ if( __path2fss(zFilename, &fsSpec) != noErr )
+ return STQLITE_CANTOPEN;
+ if( FSpMakeFSRef(&fsSpec, &fsRef) != noErr )
+ return STQLITE_CANTOPEN;
+ FSGetDataForkName(&dfName);
+ if( FSOpenFork(&fsRef, dfName.length, dfName.tqunicode,
+ fsRdPerm, &(id->refNum)) != noErr )
+ return STQLITE_CANTOPEN;
+# else
+ __path2fss(zFilename, &fsSpec);
+ if( HOpenDF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdPerm, &(id->refNum)) != noErr )
+ return STQLITE_CANTOPEN;
+# endif
+ if( HOpenRF(fsSpec.vRefNum, fsSpec.parID, fsSpec.name, fsRdWrShPerm, &(id->refNumRF)) != noErr){
+ id->refNumRF = -1;
+ }
+ id->locked = 0;
+ id->delOnClose = 0;
+ OpenCounter(+1);
+ return STQLITE_OK;
+#endif
+}
+
+/*
+** Attempt to open a file descriptor for the directory that tqcontains a
+** file. This file descriptor can be used to fsync() the directory
+** in order to make sure the creation of a new file is actually written
+** to disk.
+**
+** This routine is only meaningful for Unix. It is a no-op under
+** windows since windows does not support hard links.
+**
+** On success, a handle for a previously open file is at *id is
+** updated with the new directory file descriptor and STQLITE_OK is
+** returned.
+**
+** On failure, the function returns STQLITE_CANTOPEN and leaves
+** *id unchanged.
+*/
+int sqliteOsOpenDirectory(
+ const char *zDirname,
+ OsFile *id
+){
+#if OS_UNIX
+ if( id->fd<0 ){
+ /* Do not open the directory if the corresponding file is not already
+ ** open. */
+ return STQLITE_CANTOPEN;
+ }
+ assert( id->dirfd<0 );
+ id->dirfd = open(zDirname, O_RDONLY|O_BINARY, 0644);
+ if( id->dirfd<0 ){
+ return STQLITE_CANTOPEN;
+ }
+ TRACE3("OPENDIR %-3d %s\n", id->dirfd, zDirname);
+#endif
+ return STQLITE_OK;
+}
+
+/*
+** Create a temporary file name in zBuf. zBuf must be big enough to
+** hold at least STQLITE_TEMPNAME_SIZE characters.
+*/
+int sqliteOsTempFileName(char *zBuf){
+#if OS_UNIX
+ static const char *azDirs[] = {
+ "/var/tmp",
+ "/usr/tmp",
+ "/tmp",
+ ".",
+ };
+ static unsigned char zChars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPTQRSTUVWXYZ"
+ "0123456789";
+ int i, j;
+ struct stat buf;
+ const char *zDir = ".";
+ for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
+ if( stat(azDirs[i], &buf) ) continue;
+ if( !S_ISDIR(buf.st_mode) ) continue;
+ if( access(azDirs[i], 07) ) continue;
+ zDir = azDirs[i];
+ break;
+ }
+ do{
+ sprintf(zBuf, "%s/"TEMP_FILE_PREFIX, zDir);
+ j = strlen(zBuf);
+ sqliteRandomness(15, &zBuf[j]);
+ for(i=0; i<15; i++, j++){
+ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+ }
+ zBuf[j] = 0;
+ }while( access(zBuf,0)==0 );
+#endif
+#if OS_WIN
+ static char zChars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPTQRSTUVWXYZ"
+ "0123456789";
+ int i, j;
+ char zTempPath[STQLITE_TEMPNAME_SIZE];
+ GetTempPath(STQLITE_TEMPNAME_SIZE-30, zTempPath);
+ for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
+ zTempPath[i] = 0;
+ for(;;){
+ sprintf(zBuf, "%s\\"TEMP_FILE_PREFIX, zTempPath);
+ j = strlen(zBuf);
+ sqliteRandomness(15, &zBuf[j]);
+ for(i=0; i<15; i++, j++){
+ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+ }
+ zBuf[j] = 0;
+ if( !sqliteOsFileExists(zBuf) ) break;
+ }
+#endif
+#if OS_MAC
+ static char zChars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPTQRSTUVWXYZ"
+ "0123456789";
+ int i, j;
+ char zTempPath[STQLITE_TEMPNAME_SIZE];
+ char zdirName[32];
+ CInfoPBRec infoRec;
+ Str31 dirName;
+ memset(&infoRec, 0, sizeof(infoRec));
+ memset(zTempPath, 0, STQLITE_TEMPNAME_SIZE);
+ if( FindFolder(kOnSystemDisk, kTemporaryFolderType, kCreateFolder,
+ &(infoRec.dirInfo.ioVRefNum), &(infoRec.dirInfo.ioDrParID)) == noErr ){
+ infoRec.dirInfo.ioNamePtr = dirName;
+ do{
+ infoRec.dirInfo.ioFDirIndex = -1;
+ infoRec.dirInfo.ioDrDirID = infoRec.dirInfo.ioDrParID;
+ if( PBGetCatInfoSync(&infoRec) == noErr ){
+ CopyPascalStringToC(dirName, zdirName);
+ i = strlen(zdirName);
+ memmove(&(zTempPath[i+1]), zTempPath, strlen(zTempPath));
+ strcpy(zTempPath, zdirName);
+ zTempPath[i] = ':';
+ }else{
+ *zTempPath = 0;
+ break;
+ }
+ } while( infoRec.dirInfo.ioDrDirID != fsRtDirID );
+ }
+ if( *zTempPath == 0 )
+ getcwd(zTempPath, STQLITE_TEMPNAME_SIZE-24);
+ for(;;){
+ sprintf(zBuf, "%s"TEMP_FILE_PREFIX, zTempPath);
+ j = strlen(zBuf);
+ sqliteRandomness(15, &zBuf[j]);
+ for(i=0; i<15; i++, j++){
+ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+ }
+ zBuf[j] = 0;
+ if( !sqliteOsFileExists(zBuf) ) break;
+ }
+#endif
+ return STQLITE_OK;
+}
+
+/*
+** Close a file.
+*/
+int sqliteOsClose(OsFile *id){
+#if OS_UNIX
+ sqliteOsUnlock(id);
+ if( id->dirfd>=0 ) close(id->dirfd);
+ id->dirfd = -1;
+ sqliteOsEnterMutex();
+ if( id->pOpen->nLock ){
+ /* If there are outstanding locks, do not actually close the file just
+ ** yet because that would clear those locks. Instead, add the file
+ ** descriptor to pOpen->aPending. It will be automatically closed when
+ ** the last lock is cleared.
+ */
+ int *aNew;
+ struct openCnt *pOpen = id->pOpen;
+ pOpen->nPending++;
+ aNew = sqliteRealloc( pOpen->aPending, pOpen->nPending*sizeof(int) );
+ if( aNew==0 ){
+ /* If a malloc fails, just leak the file descriptor */
+ }else{
+ pOpen->aPending = aNew;
+ pOpen->aPending[pOpen->nPending-1] = id->fd;
+ }
+ }else{
+ /* There are no outstanding locks so we can close the file immediately */
+ close(id->fd);
+ }
+ releaseLockInfo(id->pLock);
+ releaseOpenCnt(id->pOpen);
+ sqliteOsLeaveMutex();
+ TRACE2("CLOSE %-3d\n", id->fd);
+ OpenCounter(-1);
+ return STQLITE_OK;
+#endif
+#if OS_WIN
+ CloseHandle(id->h);
+ OpenCounter(-1);
+ return STQLITE_OK;
+#endif
+#if OS_MAC
+ if( id->refNumRF!=-1 )
+ FSClose(id->refNumRF);
+# ifdef _LARGE_FILE
+ FSCloseFork(id->refNum);
+# else
+ FSClose(id->refNum);
+# endif
+ if( id->delOnClose ){
+ unlink(id->pathToDel);
+ sqliteFree(id->pathToDel);
+ }
+ OpenCounter(-1);
+ return STQLITE_OK;
+#endif
+}
+
+/*
+** Read data from a file into a buffer. Return STQLITE_OK if all
+** bytes were read successfully and STQLITE_IOERR if anything goes
+** wrong.
+*/
+int sqliteOsRead(OsFile *id, void *pBuf, int amt){
+#if OS_UNIX
+ int got;
+ SimulateIOError(STQLITE_IOERR);
+ TIMER_START;
+ got = read(id->fd, pBuf, amt);
+ TIMER_END;
+ TRACE4("READ %-3d %7d %d\n", id->fd, last_page, elapse);
+ SEEK(0);
+ /* if( got<0 ) got = 0; */
+ if( got==amt ){
+ return STQLITE_OK;
+ }else{
+ return STQLITE_IOERR;
+ }
+#endif
+#if OS_WIN
+ DWORD got;
+ SimulateIOError(STQLITE_IOERR);
+ TRACE2("READ %d\n", last_page);
+ if( !ReadFile(id->h, pBuf, amt, &got, 0) ){
+ got = 0;
+ }
+ if( got==(DWORD)amt ){
+ return STQLITE_OK;
+ }else{
+ return STQLITE_IOERR;
+ }
+#endif
+#if OS_MAC
+ int got;
+ SimulateIOError(STQLITE_IOERR);
+ TRACE2("READ %d\n", last_page);
+# ifdef _LARGE_FILE
+ FSReadFork(id->refNum, fsAtMark, 0, (ByteCount)amt, pBuf, (ByteCount*)&got);
+# else
+ got = amt;
+ FSRead(id->refNum, &got, pBuf);
+# endif
+ if( got==amt ){
+ return STQLITE_OK;
+ }else{
+ return STQLITE_IOERR;
+ }
+#endif
+}
+
+/*
+** Write data from a buffer into a file. Return STQLITE_OK on success
+** or some other error code on failure.
+*/
+int sqliteOsWrite(OsFile *id, const void *pBuf, int amt){
+#if OS_UNIX
+ int wrote = 0;
+ SimulateIOError(STQLITE_IOERR);
+ TIMER_START;
+ while( amt>0 && (wrote = write(id->fd, pBuf, amt))>0 ){
+ amt -= wrote;
+ pBuf = &((char*)pBuf)[wrote];
+ }
+ TIMER_END;
+ TRACE4("WRITE %-3d %7d %d\n", id->fd, last_page, elapse);
+ SEEK(0);
+ if( amt>0 ){
+ return STQLITE_FULL;
+ }
+ return STQLITE_OK;
+#endif
+#if OS_WIN
+ int rc;
+ DWORD wrote;
+ SimulateIOError(STQLITE_IOERR);
+ TRACE2("WRITE %d\n", last_page);
+ while( amt>0 && (rc = WriteFile(id->h, pBuf, amt, &wrote, 0))!=0 && wrote>0 ){
+ amt -= wrote;
+ pBuf = &((char*)pBuf)[wrote];
+ }
+ if( !rc || amt>(int)wrote ){
+ return STQLITE_FULL;
+ }
+ return STQLITE_OK;
+#endif
+#if OS_MAC
+ OSErr oserr;
+ int wrote = 0;
+ SimulateIOError(STQLITE_IOERR);
+ TRACE2("WRITE %d\n", last_page);
+ while( amt>0 ){
+# ifdef _LARGE_FILE
+ oserr = FSWriteFork(id->refNum, fsAtMark, 0,
+ (ByteCount)amt, pBuf, (ByteCount*)&wrote);
+# else
+ wrote = amt;
+ oserr = FSWrite(id->refNum, &wrote, pBuf);
+# endif
+ if( wrote == 0 || oserr != noErr)
+ break;
+ amt -= wrote;
+ pBuf = &((char*)pBuf)[wrote];
+ }
+ if( oserr != noErr || amt>wrote ){
+ return STQLITE_FULL;
+ }
+ return STQLITE_OK;
+#endif
+}
+
+/*
+** Move the read/write pointer in a file.
+*/
+int sqliteOsSeek(OsFile *id, off_t offset){
+ SEEK(offset/1024 + 1);
+#if OS_UNIX
+ lseek(id->fd, offset, SEEK_SET);
+ return STQLITE_OK;
+#endif
+#if OS_WIN
+ {
+ LONG upperBits = offset>>32;
+ LONG lowerBits = offset & 0xffffffff;
+ DWORD rc;
+ rc = SetFilePointer(id->h, lowerBits, &upperBits, FILE_BEGIN);
+ /* TRACE3("SEEK rc=0x%x upper=0x%x\n", rc, upperBits); */
+ }
+ return STQLITE_OK;
+#endif
+#if OS_MAC
+ {
+ off_t curSize;
+ if( sqliteOsFileSize(id, &curSize) != STQLITE_OK ){
+ return STQLITE_IOERR;
+ }
+ if( offset >= curSize ){
+ if( sqliteOsTruncate(id, offset+1) != STQLITE_OK ){
+ return STQLITE_IOERR;
+ }
+ }
+# ifdef _LARGE_FILE
+ if( FSSetForkPosition(id->refNum, fsFromStart, offset) != noErr ){
+# else
+ if( SetFPos(id->refNum, fsFromStart, offset) != noErr ){
+# endif
+ return STQLITE_IOERR;
+ }else{
+ return STQLITE_OK;
+ }
+ }
+#endif
+}
+
+/*
+** Make sure all writes to a particular file are committed to disk.
+**
+** Under Unix, also make sure that the directory entry for the file
+** has been created by fsync-ing the directory that tqcontains the file.
+** If we do not do this and we encounter a power failure, the directory
+** entry for the journal might not exist after we reboot. The next
+** STQLite to access the file will not know that the journal exists (because
+** the directory entry for the journal was never created) and the transaction
+** will not roll back - possibly leading to database corruption.
+*/
+int sqliteOsSync(OsFile *id){
+#if OS_UNIX
+ SimulateIOError(STQLITE_IOERR);
+ TRACE2("SYNC %-3d\n", id->fd);
+ if( fsync(id->fd) ){
+ return STQLITE_IOERR;
+ }else{
+ if( id->dirfd>=0 ){
+ TRACE2("DIRSYNC %-3d\n", id->dirfd);
+ fsync(id->dirfd);
+ close(id->dirfd); /* Only need to sync once, so close the directory */
+ id->dirfd = -1; /* when we are done. */
+ }
+ return STQLITE_OK;
+ }
+#endif
+#if OS_WIN
+ if( FlushFileBuffers(id->h) ){
+ return STQLITE_OK;
+ }else{
+ return STQLITE_IOERR;
+ }
+#endif
+#if OS_MAC
+# ifdef _LARGE_FILE
+ if( FSFlushFork(id->refNum) != noErr ){
+# else
+ ParamBlockRec params;
+ memset(&params, 0, sizeof(ParamBlockRec));
+ params.ioParam.ioRefNum = id->refNum;
+ if( PBFlushFileSync(&params) != noErr ){
+# endif
+ return STQLITE_IOERR;
+ }else{
+ return STQLITE_OK;
+ }
+#endif
+}
+
+/*
+** Truncate an open file to a specified size
+*/
+int sqliteOsTruncate(OsFile *id, off_t nByte){
+ SimulateIOError(STQLITE_IOERR);
+#if OS_UNIX
+ return ftruncate(id->fd, nByte)==0 ? STQLITE_OK : STQLITE_IOERR;
+#endif
+#if OS_WIN
+ {
+ LONG upperBits = nByte>>32;
+ SetFilePointer(id->h, nByte, &upperBits, FILE_BEGIN);
+ SetEndOfFile(id->h);
+ }
+ return STQLITE_OK;
+#endif
+#if OS_MAC
+# ifdef _LARGE_FILE
+ if( FSSetForkSize(id->refNum, fsFromStart, nByte) != noErr){
+# else
+ if( SetEOF(id->refNum, nByte) != noErr ){
+# endif
+ return STQLITE_IOERR;
+ }else{
+ return STQLITE_OK;
+ }
+#endif
+}
+
+/*
+** Determine the current size of a file in bytes
+*/
+int sqliteOsFileSize(OsFile *id, off_t *pSize){
+#if OS_UNIX
+ struct stat buf;
+ SimulateIOError(STQLITE_IOERR);
+ if( fstat(id->fd, &buf)!=0 ){
+ return STQLITE_IOERR;
+ }
+ *pSize = buf.st_size;
+ return STQLITE_OK;
+#endif
+#if OS_WIN
+ DWORD upperBits, lowerBits;
+ SimulateIOError(STQLITE_IOERR);
+ lowerBits = GetFileSize(id->h, &upperBits);
+ *pSize = (((off_t)upperBits)<<32) + lowerBits;
+ return STQLITE_OK;
+#endif
+#if OS_MAC
+# ifdef _LARGE_FILE
+ if( FSGetForkSize(id->refNum, pSize) != noErr){
+# else
+ if( GetEOF(id->refNum, pSize) != noErr ){
+# endif
+ return STQLITE_IOERR;
+ }else{
+ return STQLITE_OK;
+ }
+#endif
+}
+
+#if OS_WIN
+/*
+** Return true (non-zero) if we are running under WinNT, Win2K or WinXP.
+** Return false (zero) for Win95, Win98, or WinME.
+**
+** Here is an interesting observation: Win95, Win98, and WinME lack
+** the LockFileEx() API. But we can still statically link against that
+** API as long as we don't call it win running Win95/98/ME. A call to
+** this routine is used to determine if the host is Win95/98/ME or
+** WinNT/2K/XP so that we will know whether or not we can safely call
+** the LockFileEx() API.
+*/
+int isNT(void){
+ static int osType = 0; /* 0=unknown 1=win95 2=winNT */
+ if( osType==0 ){
+ OSVERSIONINFO sInfo;
+ sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+ GetVersionEx(&sInfo);
+ osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1;
+ }
+ return osType==2;
+}
+#endif
+
+/*
+** Windows file locking notes: [similar issues apply to MacOS]
+**
+** We cannot use LockFileEx() or UnlockFileEx() on Win95/98/ME because
+** those functions are not available. So we use only LockFile() and
+** UnlockFile().
+**
+** LockFile() prevents not just writing but also reading by other processes.
+** (This is a design error on the part of Windows, but there is nothing
+** we can do about that.) So the region used for locking is at the
+** end of the file where it is unlikely to ever interfere with an
+** actual read attempt.
+**
+** A database read lock is obtained by locking a single randomly-chosen
+** byte out of a specific range of bytes. The lock byte is obtained at
+** random so two separate readers can probably access the file at the
+** same time, unless they are unlucky and choose the same lock byte.
+** A database write lock is obtained by locking all bytes in the range.
+** There can only be one writer.
+**
+** A lock is obtained on the first byte of the lock range before acquiring
+** either a read lock or a write lock. This prevents two processes from
+** attempting to get a lock at a same time. The semantics of
+** sqliteOsReadLock() require that if there is already a write lock, that
+** lock is converted into a read lock atomically. The lock on the first
+** byte allows us to drop the old write lock and get the read lock without
+** another process jumping into the middle and messing us up. The same
+** argument applies to sqliteOsWriteLock().
+**
+** On WinNT/2K/XP systems, LockFileEx() and UnlockFileEx() are available,
+** which means we can use reader/writer locks. When reader writer locks
+** are used, the lock is placed on the same range of bytes that is used
+** for probabilistic locking in Win95/98/ME. Hence, the locking scheme
+** will support two or more Win95 readers or two or more WinNT readers.
+** But a single Win95 reader will lock out all WinNT readers and a single
+** WinNT reader will lock out all other Win95 readers.
+**
+** Note: On MacOS we use the resource fork for locking.
+**
+** The following #defines specify the range of bytes used for locking.
+** N_LOCKBYTE is the number of bytes available for doing the locking.
+** The first byte used to hold the lock while the lock is changing does
+** not count toward this number. FIRST_LOCKBYTE is the address of
+** the first byte in the range of bytes used for locking.
+*/
+#define N_LOCKBYTE 10239
+#if OS_MAC
+# define FIRST_LOCKBYTE (0x000fffff - N_LOCKBYTE)
+#else
+# define FIRST_LOCKBYTE (0xffffffff - N_LOCKBYTE)
+#endif
+
+/*
+** Change the status of the lock on the file "id" to be a readlock.
+** If the file was write locked, then this reduces the lock to a read.
+** If the file was read locked, then this acquires a new read lock.
+**
+** Return STQLITE_OK on success and STQLITE_BUSY on failure. If this
+** library was compiled with large file support (LFS) but LFS is not
+** available on the host, then an STQLITE_NOLFS is returned.
+*/
+int sqliteOsReadLock(OsFile *id){
+#if OS_UNIX
+ int rc;
+ sqliteOsEnterMutex();
+ if( id->pLock->cnt>0 ){
+ if( !id->locked ){
+ id->pLock->cnt++;
+ id->locked = 1;
+ id->pOpen->nLock++;
+ }
+ rc = STQLITE_OK;
+ }else if( id->locked || id->pLock->cnt==0 ){
+ struct flock lock;
+ int s;
+ lock.l_type = F_RDLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = lock.l_len = 0L;
+ s = fcntl(id->fd, F_SETLK, &lock);
+ if( s!=0 ){
+ rc = (errno==EINVAL) ? STQLITE_NOLFS : STQLITE_BUSY;
+ }else{
+ rc = STQLITE_OK;
+ if( !id->locked ){
+ id->pOpen->nLock++;
+ id->locked = 1;
+ }
+ id->pLock->cnt = 1;
+ }
+ }else{
+ rc = STQLITE_BUSY;
+ }
+ sqliteOsLeaveMutex();
+ return rc;
+#endif
+#if OS_WIN
+ int rc;
+ if( id->locked>0 ){
+ rc = STQLITE_OK;
+ }else{
+ int lk;
+ int res;
+ int cnt = 100;
+ sqliteRandomness(sizeof(lk), &lk);
+ lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
+ while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
+ Sleep(1);
+ }
+ if( res ){
+ UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
+ if( isNT() ){
+ OVERLAPPED ovlp;
+ ovlp.Offset = FIRST_LOCKBYTE+1;
+ ovlp.OffsetHigh = 0;
+ ovlp.hEvent = 0;
+ res = LockFileEx(id->h, LOCKFILE_FAIL_IMMEDIATELY,
+ 0, N_LOCKBYTE, 0, &ovlp);
+ }else{
+ res = LockFile(id->h, FIRST_LOCKBYTE+lk, 0, 1, 0);
+ }
+ UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
+ }
+ if( res ){
+ id->locked = lk;
+ rc = STQLITE_OK;
+ }else{
+ rc = STQLITE_BUSY;
+ }
+ }
+ return rc;
+#endif
+#if OS_MAC
+ int rc;
+ if( id->locked>0 || id->refNumRF == -1 ){
+ rc = STQLITE_OK;
+ }else{
+ int lk;
+ OSErr res;
+ int cnt = 5;
+ ParamBlockRec params;
+ sqliteRandomness(sizeof(lk), &lk);
+ lk = (lk & 0x7fffffff)%N_LOCKBYTE + 1;
+ memset(&params, 0, sizeof(params));
+ params.ioParam.ioRefNum = id->refNumRF;
+ params.ioParam.ioPosMode = fsFromStart;
+ params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
+ params.ioParam.ioRetqCount = 1;
+ while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
+ UInt32 finalTicks;
+ Delay(1, &finalTicks); /* 1/60 sec */
+ }
+ if( res == noErr ){
+ params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
+ params.ioParam.ioRetqCount = N_LOCKBYTE;
+ PBUnlockRangeSync(&params);
+ params.ioParam.ioPosOffset = FIRST_LOCKBYTE+lk;
+ params.ioParam.ioRetqCount = 1;
+ res = PBLockRangeSync(&params);
+ params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
+ params.ioParam.ioRetqCount = 1;
+ PBUnlockRangeSync(&params);
+ }
+ if( res == noErr ){
+ id->locked = lk;
+ rc = STQLITE_OK;
+ }else{
+ rc = STQLITE_BUSY;
+ }
+ }
+ return rc;
+#endif
+}
+
+/*
+** Change the lock status to be an exclusive or write lock. Return
+** STQLITE_OK on success and STQLITE_BUSY on a failure. If this
+** library was compiled with large file support (LFS) but LFS is not
+** available on the host, then an STQLITE_NOLFS is returned.
+*/
+int sqliteOsWriteLock(OsFile *id){
+#if OS_UNIX
+ int rc;
+ sqliteOsEnterMutex();
+ if( id->pLock->cnt==0 || (id->pLock->cnt==1 && id->locked==1) ){
+ struct flock lock;
+ int s;
+ lock.l_type = F_WRLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = lock.l_len = 0L;
+ s = fcntl(id->fd, F_SETLK, &lock);
+ if( s!=0 ){
+ rc = (errno==EINVAL) ? STQLITE_NOLFS : STQLITE_BUSY;
+ }else{
+ rc = STQLITE_OK;
+ if( !id->locked ){
+ id->pOpen->nLock++;
+ id->locked = 1;
+ }
+ id->pLock->cnt = -1;
+ }
+ }else{
+ rc = STQLITE_BUSY;
+ }
+ sqliteOsLeaveMutex();
+ return rc;
+#endif
+#if OS_WIN
+ int rc;
+ if( id->locked<0 ){
+ rc = STQLITE_OK;
+ }else{
+ int res;
+ int cnt = 100;
+ while( cnt-->0 && (res = LockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0))==0 ){
+ Sleep(1);
+ }
+ if( res ){
+ if( id->locked>0 ){
+ if( isNT() ){
+ UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
+ }else{
+ res = UnlockFile(id->h, FIRST_LOCKBYTE + id->locked, 0, 1, 0);
+ }
+ }
+ if( res ){
+ res = LockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
+ }else{
+ res = 0;
+ }
+ UnlockFile(id->h, FIRST_LOCKBYTE, 0, 1, 0);
+ }
+ if( res ){
+ id->locked = -1;
+ rc = STQLITE_OK;
+ }else{
+ rc = STQLITE_BUSY;
+ }
+ }
+ return rc;
+#endif
+#if OS_MAC
+ int rc;
+ if( id->locked<0 || id->refNumRF == -1 ){
+ rc = STQLITE_OK;
+ }else{
+ OSErr res;
+ int cnt = 5;
+ ParamBlockRec params;
+ memset(&params, 0, sizeof(params));
+ params.ioParam.ioRefNum = id->refNumRF;
+ params.ioParam.ioPosMode = fsFromStart;
+ params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
+ params.ioParam.ioRetqCount = 1;
+ while( cnt-->0 && (res = PBLockRangeSync(&params))!=noErr ){
+ UInt32 finalTicks;
+ Delay(1, &finalTicks); /* 1/60 sec */
+ }
+ if( res == noErr ){
+ params.ioParam.ioPosOffset = FIRST_LOCKBYTE + id->locked;
+ params.ioParam.ioRetqCount = 1;
+ if( id->locked==0
+ || PBUnlockRangeSync(&params)==noErr ){
+ params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
+ params.ioParam.ioRetqCount = N_LOCKBYTE;
+ res = PBLockRangeSync(&params);
+ }else{
+ res = afpRangeNotLocked;
+ }
+ params.ioParam.ioPosOffset = FIRST_LOCKBYTE;
+ params.ioParam.ioRetqCount = 1;
+ PBUnlockRangeSync(&params);
+ }
+ if( res == noErr ){
+ id->locked = -1;
+ rc = STQLITE_OK;
+ }else{
+ rc = STQLITE_BUSY;
+ }
+ }
+ return rc;
+#endif
+}
+
+/*
+** Unlock the given file descriptor. If the file descriptor was
+** not previously locked, then this routine is a no-op. If this
+** library was compiled with large file support (LFS) but LFS is not
+** available on the host, then an STQLITE_NOLFS is returned.
+*/
+int sqliteOsUnlock(OsFile *id){
+#if OS_UNIX
+ int rc;
+ if( !id->locked ) return STQLITE_OK;
+ sqliteOsEnterMutex();
+ assert( id->pLock->cnt!=0 );
+ if( id->pLock->cnt>1 ){
+ id->pLock->cnt--;
+ rc = STQLITE_OK;
+ }else{
+ struct flock lock;
+ int s;
+ lock.l_type = F_UNLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = lock.l_len = 0L;
+ s = fcntl(id->fd, F_SETLK, &lock);
+ if( s!=0 ){
+ rc = (errno==EINVAL) ? STQLITE_NOLFS : STQLITE_BUSY;
+ }else{
+ rc = STQLITE_OK;
+ id->pLock->cnt = 0;
+ }
+ }
+ if( rc==STQLITE_OK ){
+ /* Decrement the count of locks against this same file. When the
+ ** count reaches zero, close any other file descriptors whose close
+ ** was deferred because of outstanding locks.
+ */
+ struct openCnt *pOpen = id->pOpen;
+ pOpen->nLock--;
+ assert( pOpen->nLock>=0 );
+ if( pOpen->nLock==0 && pOpen->nPending>0 ){
+ int i;
+ for(i=0; i<pOpen->nPending; i++){
+ close(pOpen->aPending[i]);
+ }
+ sqliteFree(pOpen->aPending);
+ pOpen->nPending = 0;
+ pOpen->aPending = 0;
+ }
+ }
+ sqliteOsLeaveMutex();
+ id->locked = 0;
+ return rc;
+#endif
+#if OS_WIN
+ int rc;
+ if( id->locked==0 ){
+ rc = STQLITE_OK;
+ }else if( isNT() || id->locked<0 ){
+ UnlockFile(id->h, FIRST_LOCKBYTE+1, 0, N_LOCKBYTE, 0);
+ rc = STQLITE_OK;
+ id->locked = 0;
+ }else{
+ UnlockFile(id->h, FIRST_LOCKBYTE+id->locked, 0, 1, 0);
+ rc = STQLITE_OK;
+ id->locked = 0;
+ }
+ return rc;
+#endif
+#if OS_MAC
+ int rc;
+ ParamBlockRec params;
+ memset(&params, 0, sizeof(params));
+ params.ioParam.ioRefNum = id->refNumRF;
+ params.ioParam.ioPosMode = fsFromStart;
+ if( id->locked==0 || id->refNumRF == -1 ){
+ rc = STQLITE_OK;
+ }else if( id->locked<0 ){
+ params.ioParam.ioPosOffset = FIRST_LOCKBYTE+1;
+ params.ioParam.ioRetqCount = N_LOCKBYTE;
+ PBUnlockRangeSync(&params);
+ rc = STQLITE_OK;
+ id->locked = 0;
+ }else{
+ params.ioParam.ioPosOffset = FIRST_LOCKBYTE+id->locked;
+ params.ioParam.ioRetqCount = 1;
+ PBUnlockRangeSync(&params);
+ rc = STQLITE_OK;
+ id->locked = 0;
+ }
+ return rc;
+#endif
+}
+
+/*
+** Get information to seed the random number generator. The seed
+** is written into the buffer zBuf[256]. The calling function must
+** supply a sufficiently large buffer.
+*/
+int sqliteOsRandomSeed(char *zBuf){
+ /* We have to initialize zBuf to prevent valgrind from reporting
+ ** errors. The reports issued by valgrind are incorrect - we would
+ ** prefer that the randomness be increased by making use of the
+ ** uninitialized space in zBuf - but valgrind errors tend to worry
+ ** some users. Rather than argue, it seems easier just to initialize
+ ** the whole array and silence valgrind, even if that means less randomness
+ ** in the random seed.
+ **
+ ** When testing, initializing zBuf[] to zero is all we do. That means
+ ** that we always use the same random number sequence.* This makes the
+ ** tests repeatable.
+ */
+ memset(zBuf, 0, 256);
+#if OS_UNIX && !defined(STQLITE_TEST)
+ {
+ int pid;
+ time((time_t*)zBuf);
+ pid = getpid();
+ memcpy(&zBuf[sizeof(time_t)], &pid, sizeof(pid));
+ }
+#endif
+#if OS_WIN && !defined(STQLITE_TEST)
+ GetSystemTime((LPSYSTEMTIME)zBuf);
+#endif
+#if OS_MAC
+ {
+ int pid;
+ Microseconds((UnsignedWide*)zBuf);
+ pid = getpid();
+ memcpy(&zBuf[sizeof(UnsignedWide)], &pid, sizeof(pid));
+ }
+#endif
+ return STQLITE_OK;
+}
+
+/*
+** Sleep for a little while. Return the amount of time slept.
+*/
+int sqliteOsSleep(int ms){
+#if OS_UNIX
+#if defined(HAVE_USLEEP) && HAVE_USLEEP
+ usleep(ms*1000);
+ return ms;
+#else
+ sleep((ms+999)/1000);
+ return 1000*((ms+999)/1000);
+#endif
+#endif
+#if OS_WIN
+ Sleep(ms);
+ return ms;
+#endif
+#if OS_MAC
+ UInt32 finalTicks;
+ UInt32 ticks = (((UInt32)ms+16)*3)/50; /* 1/60 sec per tick */
+ Delay(ticks, &finalTicks);
+ return (int)((ticks*50)/3);
+#endif
+}
+
+/*
+** Static variables used for thread synchronization
+*/
+static int inMutex = 0;
+#ifdef STQLITE_UNIX_THREADS
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+#ifdef STQLITE_W32_THREADS
+ static CRITICAL_SECTION cs;
+#endif
+#ifdef STQLITE_MACOS_MULTITASKING
+ static MPCriticalRegionID criticalRegion;
+#endif
+
+/*
+** The following pair of routine implement mutual exclusion for
+** multi-threaded processes. Only a single thread is allowed to
+** executed code that is surrounded by EnterMutex() and LeaveMutex().
+**
+** STQLite uses only a single Mutex. There is not much critical
+** code and what little there is executes quickly and without blocking.
+*/
+void sqliteOsEnterMutex(){
+#ifdef STQLITE_UNIX_THREADS
+ pthread_mutex_lock(&mutex);
+#endif
+#ifdef STQLITE_W32_THREADS
+ static int isInit = 0;
+ while( !isInit ){
+ static long lock = 0;
+ if( InterlockedIncrement(&lock)==1 ){
+ InitializeCriticalSection(&cs);
+ isInit = 1;
+ }else{
+ Sleep(1);
+ }
+ }
+ EnterCriticalSection(&cs);
+#endif
+#ifdef STQLITE_MACOS_MULTITASKING
+ static volatile int notInit = 1;
+ if( notInit ){
+ if( notInit == 2 ) /* as close as you can get to thread safe init */
+ MPYield();
+ else{
+ notInit = 2;
+ MPCreateCriticalRegion(&criticalRegion);
+ notInit = 0;
+ }
+ }
+ MPEnterCriticalRegion(criticalRegion, kDurationForever);
+#endif
+ assert( !inMutex );
+ inMutex = 1;
+}
+void sqliteOsLeaveMutex(){
+ assert( inMutex );
+ inMutex = 0;
+#ifdef STQLITE_UNIX_THREADS
+ pthread_mutex_unlock(&mutex);
+#endif
+#ifdef STQLITE_W32_THREADS
+ LeaveCriticalSection(&cs);
+#endif
+#ifdef STQLITE_MACOS_MULTITASKING
+ MPExitCriticalRegion(criticalRegion);
+#endif
+}
+
+/*
+** Turn a relative pathname into a full pathname. Return a pointer
+** to the full pathname stored in space obtained from sqliteMalloc().
+** The calling function is responsible for freeing this space once it
+** is no longer needed.
+*/
+char *sqliteOsFullPathname(const char *zRelative){
+#if OS_UNIX
+ char *zFull = 0;
+ if( zRelative[0]=='/' ){
+ sqliteSetString(&zFull, zRelative, (char*)0);
+ }else{
+ char zBuf[5000];
+ sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), "/", zRelative,
+ (char*)0);
+ }
+ return zFull;
+#endif
+#if OS_WIN
+ char *zNotUsed;
+ char *zFull;
+ int nByte;
+ nByte = GetFullPathName(zRelative, 0, 0, &zNotUsed) + 1;
+ zFull = sqliteMalloc( nByte );
+ if( zFull==0 ) return 0;
+ GetFullPathName(zRelative, nByte, zFull, &zNotUsed);
+ return zFull;
+#endif
+#if OS_MAC
+ char *zFull = 0;
+ if( zRelative[0]==':' ){
+ char zBuf[_MAX_PATH+1];
+ sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), &(zRelative[1]),
+ (char*)0);
+ }else{
+ if( strchr(zRelative, ':') ){
+ sqliteSetString(&zFull, zRelative, (char*)0);
+ }else{
+ char zBuf[_MAX_PATH+1];
+ sqliteSetString(&zFull, getcwd(zBuf, sizeof(zBuf)), zRelative, (char*)0);
+ }
+ }
+ return zFull;
+#endif
+}
+
+/*
+** The following variable, if set to a now-zero value, become the result
+** returned from sqliteOsCurrentTime(). This is used for testing.
+*/
+#ifdef STQLITE_TEST
+int sqlite_current_time = 0;
+#endif
+
+/*
+** Find the current time (in Universal Coordinated Time). Write the
+** current time and date as a Julian Day number into *prNow and
+** return 0. Return 1 if the time and date cannot be found.
+*/
+int sqliteOsCurrentTime(double *prNow){
+#if OS_UNIX
+ time_t t;
+ time(&t);
+ *prNow = t/86400.0 + 2440587.5;
+#endif
+#if OS_WIN
+ FILETIME ft;
+ /* FILETIME structure is a 64-bit value representing the number of
+ 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
+ */
+ double now;
+ GetSystemTimeAsFileTime( &ft );
+ now = ((double)ft.dwHighDateTime) * 4294967296.0;
+ *prNow = (now + ft.dwLowDateTime)/864000000000.0 + 2305813.5;
+#endif
+#ifdef STQLITE_TEST
+ if( sqlite_current_time ){
+ *prNow = sqlite_current_time/86400.0 + 2440587.5;
+ }
+#endif
+ return 0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/os.h b/tqtinterface/qt4/src/3rdparty/sqlite/os.h
new file mode 100644
index 0000000..14b8d6e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/os.h
@@ -0,0 +1,192 @@
+/*
+** 2001 September 16
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This header file (together with is companion C source-code file
+** "os.c") attempt to abstract the underlying operating system so that
+** the STQLite library will work on both POSIX and windows systems.
+*/
+#ifndef _STQLITE_OS_H_
+#define _STQLITE_OS_H_
+
+#include "config.h"
+/*
+** Helpful hint: To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE
+** to the compiler command line.
+*/
+
+/*
+** These #defines should enable >2GB file support on Posix if the
+** underlying operating system supports it. If the OS lacks
+** large file support, or if the OS is windows, these should be no-ops.
+**
+** Large file support can be disabled using the -DSTQLITE_DISABLE_LFS switch
+** on the compiler command line. This is necessary if you are compiling
+** on a recent machine (ex: RedHat 7.2) but you want your code to work
+** on an older machine (ex: RedHat 6.0). If you compile on RedHat 7.2
+** without this option, LFS is enable. But LFS does not exist in the kernel
+** in RedHat 6.0, so the code won't work. Hence, for maximum binary
+** portability you should omit LFS.
+**
+** Similar is true for MacOS. LFS is only supported on MacOS 9 and later.
+*/
+#ifndef STQLITE_DISABLE_LFS
+# define _LARGE_FILE 1
+# ifndef _FILE_OFFSET_BITS
+# define _FILE_OFFSET_BITS 64
+# endif
+# define _LARGEFILE_SOURCE 1
+#endif
+
+/*
+** Temporary files are named starting with this prefix followed by 16 random
+** alphanumeric characters, and no file extension. They are stored in the
+** OS's standard temporary file directory, and are deleted prior to exit.
+** If sqlite is being embedded in another program, you may wish to change the
+** prefix to reflect your program's name, so that if your program exits
+** prematurely, old temporary files can be easily identified. This can be done
+** using -DTEMP_FILE_PREFIX=myprefix_ on the compiler command line.
+*/
+#ifndef TEMP_FILE_PREFIX
+# define TEMP_FILE_PREFIX "sqlite_"
+#endif
+
+/*
+** Figure out if we are dealing with Unix, Windows or MacOS.
+**
+** N.B. MacOS means Mac Classic (or Carbon). Treat Darwin (OS X) as Unix.
+** The MacOS build is designed to use CodeWarrior (tested with v8)
+*/
+#ifndef OS_UNIX
+# ifndef OS_WIN
+# ifndef OS_MAC
+# if defined(__MACOS__)
+# define OS_MAC 1
+# define OS_WIN 0
+# define OS_UNIX 0
+# elif defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
+# define OS_MAC 0
+# define OS_WIN 1
+# define OS_UNIX 0
+# else
+# define OS_MAC 0
+# define OS_WIN 0
+# define OS_UNIX 1
+# endif
+# else
+# define OS_WIN 0
+# define OS_UNIX 0
+# endif
+# else
+# define OS_MAC 0
+# define OS_UNIX 0
+# endif
+#else
+# define OS_MAC 0
+# ifndef OS_WIN
+# define OS_WIN 0
+# endif
+#endif
+
+/*
+** A handle for an open file is stored in an OsFile object.
+*/
+#if OS_UNIX
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <fcntl.h>
+# include <unistd.h>
+ typedef struct OsFile OsFile;
+ struct OsFile {
+ struct openCnt *pOpen; /* Info about all open fd's on this inode */
+ struct lockInfo *pLock; /* Info about locks on this inode */
+ int fd; /* The file descriptor */
+ int locked; /* True if this instance holds the lock */
+ int dirfd; /* File descriptor for the directory */
+ };
+# define STQLITE_TEMPNAME_SIZE 200
+# if defined(HAVE_USLEEP) && HAVE_USLEEP
+# define STQLITE_MIN_SLEEP_MS 1
+# else
+# define STQLITE_MIN_SLEEP_MS 1000
+# endif
+#endif
+
+#if OS_WIN
+#include <windows.h>
+#include <winbase.h>
+ typedef struct OsFile OsFile;
+ struct OsFile {
+ HANDLE h; /* Handle for accessing the file */
+ int locked; /* 0: unlocked, <0: write lock, >0: read lock */
+ };
+# if defined(_MSC_VER) || defined(__BORLANDC__)
+ typedef __int64 off_t;
+# else
+# if !defined(_CYGWIN_TYPES_H)
+ typedef long long off_t;
+# if defined(__MINGW32__)
+# define _OFF_T_
+# endif
+# endif
+# endif
+# define STQLITE_TEMPNAME_SIZE (MAX_PATH+50)
+# define STQLITE_MIN_SLEEP_MS 1
+#endif
+
+#if OS_MAC
+# include <unistd.h>
+# include <Files.h>
+ typedef struct OsFile OsFile;
+ struct OsFile {
+ SInt16 refNum; /* Data fork/file reference number */
+ SInt16 refNumRF; /* Resource fork reference number (for locking) */
+ int locked; /* 0: unlocked, <0: write lock, >0: read lock */
+ int delOnClose; /* True if file is to be deleted on close */
+ char *pathToDel; /* Name of file to delete on close */
+ };
+# ifdef _LARGE_FILE
+ typedef SInt64 off_t;
+# else
+ typedef SInt32 off_t;
+# endif
+# define STQLITE_TEMPNAME_SIZE _MAX_PATH
+# define STQLITE_MIN_SLEEP_MS 17
+#endif
+
+int sqliteOsDelete(const char*);
+int sqliteOsFileExists(const char*);
+int sqliteOsFileRename(const char*, const char*);
+int sqliteOsOpenReadWrite(const char*, OsFile*, int*);
+int sqliteOsOpenExclusive(const char*, OsFile*, int);
+int sqliteOsOpenReadOnly(const char*, OsFile*);
+int sqliteOsOpenDirectory(const char*, OsFile*);
+int sqliteOsTempFileName(char*);
+int sqliteOsClose(OsFile*);
+int sqliteOsRead(OsFile*, void*, int amt);
+int sqliteOsWrite(OsFile*, const void*, int amt);
+int sqliteOsSeek(OsFile*, off_t offset);
+int sqliteOsSync(OsFile*);
+int sqliteOsTruncate(OsFile*, off_t size);
+int sqliteOsFileSize(OsFile*, off_t *pSize);
+int sqliteOsReadLock(OsFile*);
+int sqliteOsWriteLock(OsFile*);
+int sqliteOsUnlock(OsFile*);
+int sqliteOsRandomSeed(char*);
+int sqliteOsSleep(int ms);
+int sqliteOsCurrentTime(double*);
+void sqliteOsEnterMutex(void);
+void sqliteOsLeaveMutex(void);
+char *sqliteOsFullPathname(const char*);
+
+
+
+#endif /* _STQLITE_OS_H_ */
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/pager.c b/tqtinterface/qt4/src/3rdparty/sqlite/pager.c
new file mode 100644
index 0000000..631c387
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/pager.c
@@ -0,0 +1,2220 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This is the implementation of the page cache subsystem or "pager".
+**
+** The pager is used to access a database disk file. It implements
+** atomic commit and rollback through the use of a journal file that
+** is separate from the database file. The pager also implements file
+** locking to prevent two processes from writing the same database
+** file simultaneously, or one process from reading the database while
+** another is writing.
+**
+** @(#) $Id: pager.c,v 1.101 2004/02/25 02:20:41 drh Exp $
+*/
+#include "os.h" /* Must be first to enable large file support */
+#include "sqliteInt.h"
+#include "pager.h"
+#include <assert.h>
+#include <string.h>
+
+/*
+** Macros for troubleshooting. Normally turned off
+*/
+#if 0
+static Pager *mainPager = 0;
+#define SET_PAGER(X) if( mainPager==0 ) mainPager = (X)
+#define CLR_PAGER(X) if( mainPager==(X) ) mainPager = 0
+#define TRACE1(X) if( pPager==mainPager ) fprintf(stderr,X)
+#define TRACE2(X,Y) if( pPager==mainPager ) fprintf(stderr,X,Y)
+#define TRACE3(X,Y,Z) if( pPager==mainPager ) fprintf(stderr,X,Y,Z)
+#else
+#define SET_PAGER(X)
+#define CLR_PAGER(X)
+#define TRACE1(X)
+#define TRACE2(X,Y)
+#define TRACE3(X,Y,Z)
+#endif
+
+
+/*
+** The page cache as a whole is always in one of the following
+** states:
+**
+** STQLITE_UNLOCK The page cache is not currently reading or
+** writing the database file. There is no
+** data held in memory. This is the initial
+** state.
+**
+** STQLITE_READLOCK The page cache is reading the database.
+** Writing is not permitted. There can be
+** multiple readers accessing the same database
+** file at the same time.
+**
+** STQLITE_WRITELOCK The page cache is writing the database.
+** Access is exclusive. No other processes or
+** threads can be reading or writing while one
+** process is writing.
+**
+** The page cache comes up in STQLITE_UNLOCK. The first time a
+** sqlite_page_get() occurs, the state transitions to STQLITE_READLOCK.
+** After all pages have been released using sqlite_page_unref(),
+** the state transitions back to STQLITE_UNLOCK. The first time
+** that sqlite_page_write() is called, the state transitions to
+** STQLITE_WRITELOCK. (Note that sqlite_page_write() can only be
+** called on an outstanding page which means that the pager must
+** be in STQLITE_READLOCK before it transitions to STQLITE_WRITELOCK.)
+** The sqlite_page_rollback() and sqlite_page_commit() functions
+** transition the state from STQLITE_WRITELOCK back to STQLITE_READLOCK.
+*/
+#define STQLITE_UNLOCK 0
+#define STQLITE_READLOCK 1
+#define STQLITE_WRITELOCK 2
+
+
+/*
+** Each in-memory image of a page begins with the following header.
+** This header is only visible to this pager module. The client
+** code that calls pager sees only the data that follows the header.
+**
+** Client code should call sqlitepager_write() on a page prior to making
+** any modifications to that page. The first time sqlitepager_write()
+** is called, the original page contents are written into the rollback
+** journal and PgHdr.inJournal and PgHdr.needSync are set. Later, once
+** the journal page has made it onto the disk surface, PgHdr.needSync
+** is cleared. The modified page cannot be written back into the original
+** database file until the journal pages has been synced to disk and the
+** PgHdr.needSync has been cleared.
+**
+** The PgHdr.dirty flag is set when sqlitepager_write() is called and
+** is cleared again when the page content is written back to the original
+** database file.
+*/
+typedef struct PgHdr PgHdr;
+struct PgHdr {
+ Pager *pPager; /* The pager to which this page belongs */
+ Pgno pgno; /* The page number for this page */
+ PgHdr *pNextHash, *pPrevHash; /* Hash collision chain for PgHdr.pgno */
+ int nRef; /* Number of users of this page */
+ PgHdr *pNextFree, *pPrevFree; /* Freelist of pages where nRef==0 */
+ PgHdr *pNextAll, *pPrevAll; /* A list of all pages */
+ PgHdr *pNextCkpt, *pPrevCkpt; /* List of pages in the checkpoint journal */
+ u8 inJournal; /* TRUE if has been written to journal */
+ u8 inCkpt; /* TRUE if written to the checkpoint journal */
+ u8 dirty; /* TRUE if we need to write back changes */
+ u8 needSync; /* Sync journal before writing this page */
+ u8 alwaysRollback; /* Disable dont_rollback() for this page */
+ PgHdr *pDirty; /* Dirty pages sorted by PgHdr.pgno */
+ /* STQLITE_PAGE_SIZE bytes of page data follow this header */
+ /* Pager.nExtra bytes of local data follow the page data */
+};
+
+
+/*
+** A macro used for invoking the codec if there is one
+*/
+#ifdef STQLITE_HAS_CODEC
+# define CODEC(P,D,N,X) if( P->xCodec ){ P->xCodec(P->pCodecArg,D,N,X); }
+#else
+# define CODEC(P,D,N,X)
+#endif
+
+/*
+** Convert a pointer to a PgHdr into a pointer to its data
+** and back again.
+*/
+#define PGHDR_TO_DATA(P) ((void*)(&(P)[1]))
+#define DATA_TO_PGHDR(D) (&((PgHdr*)(D))[-1])
+#define PGHDR_TO_EXTRA(P) ((void*)&((char*)(&(P)[1]))[STQLITE_PAGE_SIZE])
+
+/*
+** How big to make the hash table used for locating in-memory pages
+** by page number.
+*/
+#define N_PG_HASH 2048
+
+/*
+** Hash a page number
+*/
+#define pager_hash(PN) ((PN)&(N_PG_HASH-1))
+
+/*
+** A open page cache is an instance of the following structure.
+*/
+struct Pager {
+ char *zFilename; /* Name of the database file */
+ char *zJournal; /* Name of the journal file */
+ char *zDirectory; /* Directory hold database and journal files */
+ OsFile fd, jfd; /* File descriptors for database and journal */
+ OsFile cpfd; /* File descriptor for the checkpoint journal */
+ int dbSize; /* Number of pages in the file */
+ int origDbSize; /* dbSize before the current change */
+ int ckptSize; /* Size of database (in pages) at ckpt_begin() */
+ off_t ckptJSize; /* Size of journal at ckpt_begin() */
+ int nRec; /* Number of pages written to the journal */
+ u32 cksumInit; /* Quasi-random value added to every checksum */
+ int ckptNRec; /* Number of records in the checkpoint journal */
+ int nExtra; /* Add this many bytes to each in-memory page */
+ void (*xDestructor)(void*); /* Call this routine when freeing pages */
+ int nPage; /* Total number of in-memory pages */
+ int nRef; /* Number of in-memory pages with PgHdr.nRef>0 */
+ int mxPage; /* Maximum number of pages to hold in cache */
+ int nHit, nMiss, nOvfl; /* Cache hits, missing, and LRU overflows */
+ void (*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
+ void *pCodecArg; /* First argument to xCodec() */
+ u8 journalOpen; /* True if journal file descriptors is valid */
+ u8 journalStarted; /* True if header of journal is synced */
+ u8 useJournal; /* Use a rollback journal on this file */
+ u8 ckptOpen; /* True if the checkpoint journal is open */
+ u8 ckptInUse; /* True we are in a checkpoint */
+ u8 ckptAutoopen; /* Open ckpt journal when main journal is opened*/
+ u8 noSync; /* Do not sync the journal if true */
+ u8 fullSync; /* Do extra syncs of the journal for robustness */
+ u8 state; /* STQLITE_UNLOCK, _READLOCK or _WRITELOCK */
+ u8 errMask; /* One of several kinds of errors */
+ u8 tempFile; /* zFilename is a temporary file */
+ u8 readOnly; /* True for a read-only database */
+ u8 needSync; /* True if an fsync() is needed on the journal */
+ u8 dirtyFile; /* True if database file has changed in any way */
+ u8 alwaysRollback; /* Disable dont_rollback() for all pages */
+ u8 *aInJournal; /* One bit for each page in the database file */
+ u8 *aInCkpt; /* One bit for each page in the database */
+ PgHdr *pFirst, *pLast; /* List of free pages */
+ PgHdr *pFirstSynced; /* First free page with PgHdr.needSync==0 */
+ PgHdr *pAll; /* List of all pages */
+ PgHdr *pCkpt; /* List of pages in the checkpoint journal */
+ PgHdr *aHash[N_PG_HASH]; /* Hash table to map page number of PgHdr */
+};
+
+/*
+** These are bits that can be set in Pager.errMask.
+*/
+#define PAGER_ERR_FULL 0x01 /* a write() failed */
+#define PAGER_ERR_MEM 0x02 /* malloc() failed */
+#define PAGER_ERR_LOCK 0x04 /* error in the locking protocol */
+#define PAGER_ERR_CORRUPT 0x08 /* database or journal corruption */
+#define PAGER_ERR_DISK 0x10 /* general disk I/O error - bad hard drive? */
+
+/*
+** The journal file tqcontains page records in the following
+** format.
+**
+** Actually, this structure is the complete page record for pager
+** formats less than 3. Beginning with format 3, this record is surrounded
+** by two checksums.
+*/
+typedef struct PageRecord PageRecord;
+struct PageRecord {
+ Pgno pgno; /* The page number */
+ char aData[STQLITE_PAGE_SIZE]; /* Original data for page pgno */
+};
+
+/*
+** Journal files begin with the following magic string. The data
+** was obtained from /dev/random. It is used only as a sanity check.
+**
+** There are three journal formats (so far). The 1st journal format writes
+** 32-bit integers in the byte-order of the host machine. New
+** formats writes integers as big-endian. All new journals use the
+** new format, but we have to be able to read an older journal in order
+** to rollback journals created by older versions of the library.
+**
+** The 3rd journal format (added for 2.8.0) adds additional sanity
+** checking information to the journal. If the power fails while the
+** journal is being written, semi-random garbage data might appear in
+** the journal file after power is restored. If an attempt is then made
+** to roll the journal back, the database could be corrupted. The additional
+** sanity checking data is an attempt to discover the garbage in the
+** journal and ignore it.
+**
+** The sanity checking information for the 3rd journal format consists
+** of a 32-bit checksum on each page of data. The checksum covers both
+** the page number and the STQLITE_PAGE_SIZE bytes of data for the page.
+** This cksum is initialized to a 32-bit random value that appears in the
+** journal file right after the header. The random initializer is important,
+** because garbage data that appears at the end of a journal is likely
+** data that was once in other files that have now been deleted. If the
+** garbage data came from an obsolete journal file, the checksums might
+** be correct. But by initializing the checksum to random value which
+** is different for every journal, we minimize that risk.
+*/
+static const unsigned char aJournalMagic1[] = {
+ 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd4,
+};
+static const unsigned char aJournalMagic2[] = {
+ 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd5,
+};
+static const unsigned char aJournalMagic3[] = {
+ 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd6,
+};
+#define JOURNAL_FORMAT_1 1
+#define JOURNAL_FORMAT_2 2
+#define JOURNAL_FORMAT_3 3
+
+/*
+** The following integer determines what format to use when creating
+** new primary journal files. By default we always use format 3.
+** When testing, we can set this value to older journal formats in order to
+** make sure that newer versions of the library are able to rollback older
+** journal files.
+**
+** Note that checkpoint journals always use format 2 and omit the header.
+*/
+#ifdef STQLITE_TEST
+int journal_format = 3;
+#else
+# define journal_format 3
+#endif
+
+/*
+** The size of the header and of each page in the journal varies according
+** to which journal format is being used. The following macros figure out
+** the sizes based on format numbers.
+*/
+#define JOURNAL_HDR_SZ(X) \
+ (sizeof(aJournalMagic1) + sizeof(Pgno) + ((X)>=3)*2*sizeof(u32))
+#define JOURNAL_PG_SZ(X) \
+ (STQLITE_PAGE_SIZE + sizeof(Pgno) + ((X)>=3)*sizeof(u32))
+
+/*
+** Enable reference count tracking here:
+*/
+#ifdef STQLITE_TEST
+ int pager_refinfo_enable = 0;
+ static void pager_refinfo(PgHdr *p){
+ static int cnt = 0;
+ if( !pager_refinfo_enable ) return;
+ printf(
+ "REFCNT: %4d addr=0x%08x nRef=%d\n",
+ p->pgno, (int)PGHDR_TO_DATA(p), p->nRef
+ );
+ cnt++; /* Something to set a breakpoint on */
+ }
+# define REFINFO(X) pager_refinfo(X)
+#else
+# define REFINFO(X)
+#endif
+
+/*
+** Read a 32-bit integer from the given file descriptor. Store the integer
+** that is read in *pRes. Return STQLITE_OK if everything worked, or an
+** error code is something goes wrong.
+**
+** If the journal format is 2 or 3, read a big-endian integer. If the
+** journal format is 1, read an integer in the native byte-order of the
+** host machine.
+*/
+static int read32bits(int format, OsFile *fd, u32 *pRes){
+ u32 res;
+ int rc;
+ rc = sqliteOsRead(fd, &res, sizeof(res));
+ if( rc==STQLITE_OK && format>JOURNAL_FORMAT_1 ){
+ unsigned char ac[4];
+ memcpy(ac, &res, 4);
+ res = (ac[0]<<24) | (ac[1]<<16) | (ac[2]<<8) | ac[3];
+ }
+ *pRes = res;
+ return rc;
+}
+
+/*
+** Write a 32-bit integer into the given file descriptor. Return STQLITE_OK
+** on success or an error code is something goes wrong.
+**
+** If the journal format is 2 or 3, write the integer as 4 big-endian
+** bytes. If the journal format is 1, write the integer in the native
+** byte order. In normal operation, only formats 2 and 3 are used.
+** Journal format 1 is only used for testing.
+*/
+static int write32bits(OsFile *fd, u32 val){
+ unsigned char ac[4];
+ if( journal_format<=1 ){
+ return sqliteOsWrite(fd, &val, 4);
+ }
+ ac[0] = (val>>24) & 0xff;
+ ac[1] = (val>>16) & 0xff;
+ ac[2] = (val>>8) & 0xff;
+ ac[3] = val & 0xff;
+ return sqliteOsWrite(fd, ac, 4);
+}
+
+/*
+** Write a 32-bit integer into a page header right before the
+** page data. This will overwrite the PgHdr.pDirty pointer.
+**
+** The integer is big-endian for formats 2 and 3 and native byte order
+** for journal format 1.
+*/
+static void store32bits(u32 val, PgHdr *p, int offset){
+ unsigned char *ac;
+ ac = &((unsigned char*)PGHDR_TO_DATA(p))[offset];
+ if( journal_format<=1 ){
+ memcpy(ac, &val, 4);
+ }else{
+ ac[0] = (val>>24) & 0xff;
+ ac[1] = (val>>16) & 0xff;
+ ac[2] = (val>>8) & 0xff;
+ ac[3] = val & 0xff;
+ }
+}
+
+
+/*
+** Convert the bits in the pPager->errMask into an approprate
+** return code.
+*/
+static int pager_errcode(Pager *pPager){
+ int rc = STQLITE_OK;
+ if( pPager->errMask & PAGER_ERR_LOCK ) rc = STQLITE_PROTOCOL;
+ if( pPager->errMask & PAGER_ERR_DISK ) rc = STQLITE_IOERR;
+ if( pPager->errMask & PAGER_ERR_FULL ) rc = STQLITE_FULL;
+ if( pPager->errMask & PAGER_ERR_MEM ) rc = STQLITE_NOMEM;
+ if( pPager->errMask & PAGER_ERR_CORRUPT ) rc = STQLITE_CORRUPT;
+ return rc;
+}
+
+/*
+** Add or remove a page from the list of all pages that are in the
+** checkpoint journal.
+**
+** The Pager keeps a separate list of pages that are currently in
+** the checkpoint journal. This helps the sqlitepager_ckpt_commit()
+** routine run MUCH faster for the common case where there are many
+** pages in memory but only a few are in the checkpoint journal.
+*/
+static void page_add_to_ckpt_list(PgHdr *pPg){
+ Pager *pPager = pPg->pPager;
+ if( pPg->inCkpt ) return;
+ assert( pPg->pPrevCkpt==0 && pPg->pNextCkpt==0 );
+ pPg->pPrevCkpt = 0;
+ if( pPager->pCkpt ){
+ pPager->pCkpt->pPrevCkpt = pPg;
+ }
+ pPg->pNextCkpt = pPager->pCkpt;
+ pPager->pCkpt = pPg;
+ pPg->inCkpt = 1;
+}
+static void page_remove_from_ckpt_list(PgHdr *pPg){
+ if( !pPg->inCkpt ) return;
+ if( pPg->pPrevCkpt ){
+ assert( pPg->pPrevCkpt->pNextCkpt==pPg );
+ pPg->pPrevCkpt->pNextCkpt = pPg->pNextCkpt;
+ }else{
+ assert( pPg->pPager->pCkpt==pPg );
+ pPg->pPager->pCkpt = pPg->pNextCkpt;
+ }
+ if( pPg->pNextCkpt ){
+ assert( pPg->pNextCkpt->pPrevCkpt==pPg );
+ pPg->pNextCkpt->pPrevCkpt = pPg->pPrevCkpt;
+ }
+ pPg->pNextCkpt = 0;
+ pPg->pPrevCkpt = 0;
+ pPg->inCkpt = 0;
+}
+
+/*
+** Find a page in the hash table given its page number. Return
+** a pointer to the page or NULL if not found.
+*/
+static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
+ PgHdr *p = pPager->aHash[pager_hash(pgno)];
+ while( p && p->pgno!=pgno ){
+ p = p->pNextHash;
+ }
+ return p;
+}
+
+/*
+** Unlock the database and clear the in-memory cache. This routine
+** sets the state of the pager back to what it was when it was first
+** opened. Any outstanding pages are invalidated and subsequent attempts
+** to access those pages will likely result in a coredump.
+*/
+static void pager_reset(Pager *pPager){
+ PgHdr *pPg, *pNext;
+ for(pPg=pPager->pAll; pPg; pPg=pNext){
+ pNext = pPg->pNextAll;
+ sqliteFree(pPg);
+ }
+ pPager->pFirst = 0;
+ pPager->pFirstSynced = 0;
+ pPager->pLast = 0;
+ pPager->pAll = 0;
+ memset(pPager->aHash, 0, sizeof(pPager->aHash));
+ pPager->nPage = 0;
+ if( pPager->state>=STQLITE_WRITELOCK ){
+ sqlitepager_rollback(pPager);
+ }
+ sqliteOsUnlock(&pPager->fd);
+ pPager->state = STQLITE_UNLOCK;
+ pPager->dbSize = -1;
+ pPager->nRef = 0;
+ assert( pPager->journalOpen==0 );
+}
+
+/*
+** When this routine is called, the pager has the journal file open and
+** a write lock on the database. This routine releases the database
+** write lock and acquires a read lock in its place. The journal file
+** is deleted and closed.
+**
+** TODO: Consider keeping the journal file open for temporary databases.
+** This might give a performance improvement on windows where opening
+** a file is an expensive operation.
+*/
+static int pager_unwritelock(Pager *pPager){
+ int rc;
+ PgHdr *pPg;
+ if( pPager->state<STQLITE_WRITELOCK ) return STQLITE_OK;
+ sqlitepager_ckpt_commit(pPager);
+ if( pPager->ckptOpen ){
+ sqliteOsClose(&pPager->cpfd);
+ pPager->ckptOpen = 0;
+ }
+ if( pPager->journalOpen ){
+ sqliteOsClose(&pPager->jfd);
+ pPager->journalOpen = 0;
+ sqliteOsDelete(pPager->zJournal);
+ sqliteFree( pPager->aInJournal );
+ pPager->aInJournal = 0;
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ pPg->inJournal = 0;
+ pPg->dirty = 0;
+ pPg->needSync = 0;
+ }
+ }else{
+ assert( pPager->dirtyFile==0 || pPager->useJournal==0 );
+ }
+ rc = sqliteOsReadLock(&pPager->fd);
+ if( rc==STQLITE_OK ){
+ pPager->state = STQLITE_READLOCK;
+ }else{
+ /* This can only happen if a process does a BEGIN, then forks and the
+ ** child process does the COMMIT. Because of the semantics of unix
+ ** file locking, the unlock will fail.
+ */
+ pPager->state = STQLITE_UNLOCK;
+ }
+ return rc;
+}
+
+/*
+** Compute and return a checksum for the page of data.
+**
+** This is not a real checksum. It is really just the sum of the
+** random initial value and the page number. We considered do a checksum
+** of the database, but that was found to be too slow.
+*/
+static u32 pager_cksum(Pager *pPager, Pgno pgno, const char *aData){
+ u32 cksum = pPager->cksumInit + pgno;
+ return cksum;
+}
+
+/*
+** Read a single page from the journal file opened on file descriptor
+** jfd. Playback this one page.
+**
+** There are three different journal formats. The format parameter determines
+** which format is used by the journal that is played back.
+*/
+static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int format){
+ int rc;
+ PgHdr *pPg; /* An existing page in the cache */
+ PageRecord pgRec;
+ u32 cksum;
+
+ rc = read32bits(format, jfd, &pgRec.pgno);
+ if( rc!=STQLITE_OK ) return rc;
+ rc = sqliteOsRead(jfd, &pgRec.aData, sizeof(pgRec.aData));
+ if( rc!=STQLITE_OK ) return rc;
+
+ /* Sanity checking on the page. This is more important that I originally
+ ** thought. If a power failure occurs while the journal is being written,
+ ** it could cause invalid data to be written into the journal. We need to
+ ** detect this invalid data (with high probability) and ignore it.
+ */
+ if( pgRec.pgno==0 ){
+ return STQLITE_DONE;
+ }
+ if( pgRec.pgno>(unsigned)pPager->dbSize ){
+ return STQLITE_OK;
+ }
+ if( format>=JOURNAL_FORMAT_3 ){
+ rc = read32bits(format, jfd, &cksum);
+ if( rc ) return rc;
+ if( pager_cksum(pPager, pgRec.pgno, pgRec.aData)!=cksum ){
+ return STQLITE_DONE;
+ }
+ }
+
+ /* Playback the page. Update the in-memory copy of the page
+ ** at the same time, if there is one.
+ */
+ pPg = pager_lookup(pPager, pgRec.pgno);
+ TRACE2("PLAYBACK %d\n", pgRec.pgno);
+ sqliteOsSeek(&pPager->fd, (pgRec.pgno-1)*(off_t)STQLITE_PAGE_SIZE);
+ rc = sqliteOsWrite(&pPager->fd, pgRec.aData, STQLITE_PAGE_SIZE);
+ if( pPg ){
+ /* No page should ever be rolled back that is in use, except for page
+ ** 1 which is held in use in order to keep the lock on the database
+ ** active.
+ */
+ assert( pPg->nRef==0 || pPg->pgno==1 );
+ memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, STQLITE_PAGE_SIZE);
+ memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
+ pPg->dirty = 0;
+ pPg->needSync = 0;
+ CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
+ }
+ return rc;
+}
+
+/*
+** Playback the journal and thus restore the database file to
+** the state it was in before we started making changes.
+**
+** The journal file format is as follows:
+**
+** * 8 byte prefix. One of the aJournalMagic123 vectors defined
+** above. The format of the journal file is determined by which
+** of the three prefix vectors is seen.
+** * 4 byte big-endian integer which is the number of valid page records
+** in the journal. If this value is 0xffffffff, then compute the
+** number of page records from the journal size. This field appears
+** in format 3 only.
+** * 4 byte big-endian integer which is the initial value for the
+** sanity checksum. This field appears in format 3 only.
+** * 4 byte integer which is the number of pages to truncate the
+** database to during a rollback.
+** * Zero or more pages instances, each as follows:
+** + 4 byte page number.
+** + STQLITE_PAGE_SIZE bytes of data.
+** + 4 byte checksum (format 3 only)
+**
+** When we speak of the journal header, we mean the first 4 bullets above.
+** Each entry in the journal is an instance of the 5th bullet. Note that
+** bullets 2 and 3 only appear in format-3 journals.
+**
+** Call the value from the second bullet "nRec". nRec is the number of
+** valid page entries in the journal. In most cases, you can compute the
+** value of nRec from the size of the journal file. But if a power
+** failure occurred while the journal was being written, it could be the
+** case that the size of the journal file had already been increased but
+** the extra entries had not yet made it safely to disk. In such a case,
+** the value of nRec computed from the file size would be too large. For
+** that reason, we always use the nRec value in the header.
+**
+** If the nRec value is 0xffffffff it means that nRec should be computed
+** from the file size. This value is used when the user selects the
+** no-sync option for the journal. A power failure could lead to corruption
+** in this case. But for things like temporary table (which will be
+** deleted when the power is restored) we don't care.
+**
+** Journal formats 1 and 2 do not have an nRec value in the header so we
+** have to compute nRec from the file size. This has risks (as described
+** above) which is why all persistent tables have been changed to use
+** format 3.
+**
+** If the file opened as the journal file is not a well-formed
+** journal file then the database will likely already be
+** corrupted, so the PAGER_ERR_CORRUPT bit is set in pPager->errMask
+** and STQLITE_CORRUPT is returned. If it all works, then this routine
+** returns STQLITE_OK.
+*/
+static int pager_playback(Pager *pPager, int useJournalSize){
+ off_t szJ; /* Size of the journal file in bytes */
+ int nRec; /* Number of Records in the journal */
+ int i; /* Loop counter */
+ Pgno mxPg = 0; /* Size of the original file in pages */
+ int format; /* Format of the journal file. */
+ unsigned char aMagic[sizeof(aJournalMagic1)];
+ int rc;
+
+ /* Figure out how many records are in the journal. Abort early if
+ ** the journal is empty.
+ */
+ assert( pPager->journalOpen );
+ sqliteOsSeek(&pPager->jfd, 0);
+ rc = sqliteOsFileSize(&pPager->jfd, &szJ);
+ if( rc!=STQLITE_OK ){
+ goto end_playback;
+ }
+
+ /* If the journal file is too small to contain a complete header,
+ ** it must mean that the process that created the journal was just
+ ** beginning to write the journal file when it died. In that case,
+ ** the database file should have still been completely unchanged.
+ ** Nothing needs to be rolled back. We can safely ignore this journal.
+ */
+ if( szJ < sizeof(aMagic)+sizeof(Pgno) ){
+ goto end_playback;
+ }
+
+ /* Read the beginning of the journal and truncate the
+ ** database file back to its original size.
+ */
+ rc = sqliteOsRead(&pPager->jfd, aMagic, sizeof(aMagic));
+ if( rc!=STQLITE_OK ){
+ rc = STQLITE_PROTOCOL;
+ goto end_playback;
+ }
+ if( memcmp(aMagic, aJournalMagic3, sizeof(aMagic))==0 ){
+ format = JOURNAL_FORMAT_3;
+ }else if( memcmp(aMagic, aJournalMagic2, sizeof(aMagic))==0 ){
+ format = JOURNAL_FORMAT_2;
+ }else if( memcmp(aMagic, aJournalMagic1, sizeof(aMagic))==0 ){
+ format = JOURNAL_FORMAT_1;
+ }else{
+ rc = STQLITE_PROTOCOL;
+ goto end_playback;
+ }
+ if( format>=JOURNAL_FORMAT_3 ){
+ if( szJ < sizeof(aMagic) + 3*sizeof(u32) ){
+ /* Ignore the journal if it is too small to contain a complete
+ ** header. We already did this test once above, but at the prior
+ ** test, we did not know the journal format and so we had to assume
+ ** the smallest possible header. Now we know the header is bigger
+ ** than the minimum so we test again.
+ */
+ goto end_playback;
+ }
+ rc = read32bits(format, &pPager->jfd, (u32*)&nRec);
+ if( rc ) goto end_playback;
+ rc = read32bits(format, &pPager->jfd, &pPager->cksumInit);
+ if( rc ) goto end_playback;
+ if( nRec==0xffffffff || useJournalSize ){
+ nRec = (szJ - JOURNAL_HDR_SZ(3))/JOURNAL_PG_SZ(3);
+ }
+ }else{
+ nRec = (szJ - JOURNAL_HDR_SZ(2))/JOURNAL_PG_SZ(2);
+ assert( nRec*JOURNAL_PG_SZ(2)+JOURNAL_HDR_SZ(2)==szJ );
+ }
+ rc = read32bits(format, &pPager->jfd, &mxPg);
+ if( rc!=STQLITE_OK ){
+ goto end_playback;
+ }
+ assert( pPager->origDbSize==0 || pPager->origDbSize==mxPg );
+ rc = sqliteOsTruncate(&pPager->fd, STQLITE_PAGE_SIZE*(off_t)mxPg);
+ if( rc!=STQLITE_OK ){
+ goto end_playback;
+ }
+ pPager->dbSize = mxPg;
+
+ /* Copy original pages out of the journal and back into the database file.
+ */
+ for(i=0; i<nRec; i++){
+ rc = pager_playback_one_page(pPager, &pPager->jfd, format);
+ if( rc!=STQLITE_OK ){
+ if( rc==STQLITE_DONE ){
+ rc = STQLITE_OK;
+ }
+ break;
+ }
+ }
+
+ /* Pages that have been written to the journal but never synced
+ ** where not restored by the loop above. We have to restore those
+ ** pages by reading them back from the original database.
+ */
+ if( rc==STQLITE_OK ){
+ PgHdr *pPg;
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ char zBuf[STQLITE_PAGE_SIZE];
+ if( !pPg->dirty ) continue;
+ if( (int)pPg->pgno <= pPager->origDbSize ){
+ sqliteOsSeek(&pPager->fd, STQLITE_PAGE_SIZE*(off_t)(pPg->pgno-1));
+ rc = sqliteOsRead(&pPager->fd, zBuf, STQLITE_PAGE_SIZE);
+ TRACE2("REFETCH %d\n", pPg->pgno);
+ CODEC(pPager, zBuf, pPg->pgno, 2);
+ if( rc ) break;
+ }else{
+ memset(zBuf, 0, STQLITE_PAGE_SIZE);
+ }
+ if( pPg->nRef==0 || memcmp(zBuf, PGHDR_TO_DATA(pPg), STQLITE_PAGE_SIZE) ){
+ memcpy(PGHDR_TO_DATA(pPg), zBuf, STQLITE_PAGE_SIZE);
+ memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
+ }
+ pPg->needSync = 0;
+ pPg->dirty = 0;
+ }
+ }
+
+end_playback:
+ if( rc!=STQLITE_OK ){
+ pager_unwritelock(pPager);
+ pPager->errMask |= PAGER_ERR_CORRUPT;
+ rc = STQLITE_CORRUPT;
+ }else{
+ rc = pager_unwritelock(pPager);
+ }
+ return rc;
+}
+
+/*
+** Playback the checkpoint journal.
+**
+** This is similar to playing back the transaction journal but with
+** a few extra twists.
+**
+** (1) The number of pages in the database file at the start of
+** the checkpoint is stored in pPager->ckptSize, not in the
+** journal file itself.
+**
+** (2) In addition to playing back the checkpoint journal, also
+** playback all pages of the transaction journal beginning
+** at offset pPager->ckptJSize.
+*/
+static int pager_ckpt_playback(Pager *pPager){
+ off_t szJ; /* Size of the full journal */
+ int nRec; /* Number of Records */
+ int i; /* Loop counter */
+ int rc;
+
+ /* Truncate the database back to its original size.
+ */
+ rc = sqliteOsTruncate(&pPager->fd, STQLITE_PAGE_SIZE*(off_t)pPager->ckptSize);
+ pPager->dbSize = pPager->ckptSize;
+
+ /* Figure out how many records are in the checkpoint journal.
+ */
+ assert( pPager->ckptInUse && pPager->journalOpen );
+ sqliteOsSeek(&pPager->cpfd, 0);
+ nRec = pPager->ckptNRec;
+
+ /* Copy original pages out of the checkpoint journal and back into the
+ ** database file. Note that the checkpoint journal always uses format
+ ** 2 instead of format 3 since it does not need to be concerned with
+ ** power failures corrupting the journal and can thus omit the checksums.
+ */
+ for(i=nRec-1; i>=0; i--){
+ rc = pager_playback_one_page(pPager, &pPager->cpfd, 2);
+ assert( rc!=STQLITE_DONE );
+ if( rc!=STQLITE_OK ) goto end_ckpt_playback;
+ }
+
+ /* Figure out how many pages need to be copied out of the transaction
+ ** journal.
+ */
+ rc = sqliteOsSeek(&pPager->jfd, pPager->ckptJSize);
+ if( rc!=STQLITE_OK ){
+ goto end_ckpt_playback;
+ }
+ rc = sqliteOsFileSize(&pPager->jfd, &szJ);
+ if( rc!=STQLITE_OK ){
+ goto end_ckpt_playback;
+ }
+ nRec = (szJ - pPager->ckptJSize)/JOURNAL_PG_SZ(journal_format);
+ for(i=nRec-1; i>=0; i--){
+ rc = pager_playback_one_page(pPager, &pPager->jfd, journal_format);
+ if( rc!=STQLITE_OK ){
+ assert( rc!=STQLITE_DONE );
+ goto end_ckpt_playback;
+ }
+ }
+
+end_ckpt_playback:
+ if( rc!=STQLITE_OK ){
+ pPager->errMask |= PAGER_ERR_CORRUPT;
+ rc = STQLITE_CORRUPT;
+ }
+ return rc;
+}
+
+/*
+** Change the maximum number of in-memory pages that are allowed.
+**
+** The maximum number is the absolute value of the mxPage parameter.
+** If mxPage is negative, the noSync flag is also set. noSync bypasses
+** calls to sqliteOsSync(). The pager runs much faster with noSync on,
+** but if the operating system crashes or there is an abrupt power
+** failure, the database file might be left in an inconsistent and
+** unrepairable state.
+*/
+void sqlitepager_set_cachesize(Pager *pPager, int mxPage){
+ if( mxPage>=0 ){
+ pPager->noSync = pPager->tempFile;
+ if( pPager->noSync==0 ) pPager->needSync = 0;
+ }else{
+ pPager->noSync = 1;
+ mxPage = -mxPage;
+ }
+ if( mxPage>10 ){
+ pPager->mxPage = mxPage;
+ }
+}
+
+/*
+** Adjust the robustness of the database to damage due to OS crashes
+** or power failures by changing the number of syncs()s when writing
+** the rollback journal. There are three levels:
+**
+** OFF sqliteOsSync() is never called. This is the default
+** for temporary and transient files.
+**
+** NORMAL The journal is synced once before writes begin on the
+** database. This is normally adequate protection, but
+** it is theoretically possible, though very unlikely,
+** that an inopertune power failure could leave the journal
+** in a state which would cause damage to the database
+** when it is rolled back.
+**
+** FULL The journal is synced twice before writes begin on the
+** database (with some additional information - the nRec field
+** of the journal header - being written in between the two
+** syncs). If we assume that writing a
+** single disk sector is atomic, then this mode provides
+** assurance that the journal will not be corrupted to the
+** point of causing damage to the database during rollback.
+**
+** Numeric values associated with these states are OFF==1, NORMAL=2,
+** and FULL=3.
+*/
+void sqlitepager_set_safety_level(Pager *pPager, int level){
+ pPager->noSync = level==1 || pPager->tempFile;
+ pPager->fullSync = level==3 && !pPager->tempFile;
+ if( pPager->noSync==0 ) pPager->needSync = 0;
+}
+
+/*
+** Open a temporary file. Write the name of the file into zName
+** (zName must be at least STQLITE_TEMPNAME_SIZE bytes long.) Write
+** the file descriptor into *fd. Return STQLITE_OK on success or some
+** other error code if we fail.
+**
+** The OS will automatically delete the temporary file when it is
+** closed.
+*/
+static int sqlitepager_opentemp(char *zFile, OsFile *fd){
+ int cnt = 8;
+ int rc;
+ do{
+ cnt--;
+ sqliteOsTempFileName(zFile);
+ rc = sqliteOsOpenExclusive(zFile, fd, 1);
+ }while( cnt>0 && rc!=STQLITE_OK );
+ return rc;
+}
+
+/*
+** Create a new page cache and put a pointer to the page cache in *ppPager.
+** The file to be cached need not exist. The file is not locked until
+** the first call to sqlitepager_get() and is only held open until the
+** last page is released using sqlitepager_unref().
+**
+** If zFilename is NULL then a randomly-named temporary file is created
+** and used as the file to be cached. The file will be deleted
+** automatically when it is closed.
+*/
+int sqlitepager_open(
+ Pager **ppPager, /* Return the Pager structure here */
+ const char *zFilename, /* Name of the database file to open */
+ int mxPage, /* Max number of in-memory cache pages */
+ int nExtra, /* Extra bytes append to each in-memory page */
+ int useJournal /* TRUE to use a rollback journal on this file */
+){
+ Pager *pPager;
+ char *zFullPathname;
+ int nameLen;
+ OsFile fd;
+ int rc, i;
+ int tempFile;
+ int readOnly = 0;
+ char zTemp[STQLITE_TEMPNAME_SIZE];
+
+ *ppPager = 0;
+ if( sqlite_malloc_failed ){
+ return STQLITE_NOMEM;
+ }
+ if( zFilename && zFilename[0] ){
+ zFullPathname = sqliteOsFullPathname(zFilename);
+ rc = sqliteOsOpenReadWrite(zFullPathname, &fd, &readOnly);
+ tempFile = 0;
+ }else{
+ rc = sqlitepager_opentemp(zTemp, &fd);
+ zFilename = zTemp;
+ zFullPathname = sqliteOsFullPathname(zFilename);
+ tempFile = 1;
+ }
+ if( sqlite_malloc_failed ){
+ return STQLITE_NOMEM;
+ }
+ if( rc!=STQLITE_OK ){
+ sqliteFree(zFullPathname);
+ return STQLITE_CANTOPEN;
+ }
+ nameLen = strlen(zFullPathname);
+ pPager = sqliteMalloc( sizeof(*pPager) + nameLen*3 + 30 );
+ if( pPager==0 ){
+ sqliteOsClose(&fd);
+ sqliteFree(zFullPathname);
+ return STQLITE_NOMEM;
+ }
+ SET_PAGER(pPager);
+ pPager->zFilename = (char*)&pPager[1];
+ pPager->zDirectory = &pPager->zFilename[nameLen+1];
+ pPager->zJournal = &pPager->zDirectory[nameLen+1];
+ strcpy(pPager->zFilename, zFullPathname);
+ strcpy(pPager->zDirectory, zFullPathname);
+ for(i=nameLen; i>0 && pPager->zDirectory[i-1]!='/'; i--){}
+ if( i>0 ) pPager->zDirectory[i-1] = 0;
+ strcpy(pPager->zJournal, zFullPathname);
+ sqliteFree(zFullPathname);
+ strcpy(&pPager->zJournal[nameLen], "-journal");
+ pPager->fd = fd;
+ pPager->journalOpen = 0;
+ pPager->useJournal = useJournal;
+ pPager->ckptOpen = 0;
+ pPager->ckptInUse = 0;
+ pPager->nRef = 0;
+ pPager->dbSize = -1;
+ pPager->ckptSize = 0;
+ pPager->ckptJSize = 0;
+ pPager->nPage = 0;
+ pPager->mxPage = mxPage>5 ? mxPage : 10;
+ pPager->state = STQLITE_UNLOCK;
+ pPager->errMask = 0;
+ pPager->tempFile = tempFile;
+ pPager->readOnly = readOnly;
+ pPager->needSync = 0;
+ pPager->noSync = pPager->tempFile || !useJournal;
+ pPager->pFirst = 0;
+ pPager->pFirstSynced = 0;
+ pPager->pLast = 0;
+ pPager->nExtra = nExtra;
+ memset(pPager->aHash, 0, sizeof(pPager->aHash));
+ *ppPager = pPager;
+ return STQLITE_OK;
+}
+
+/*
+** Set the destructor for this pager. If not NULL, the destructor is called
+** when the reference count on each page reaches zero. The destructor can
+** be used to clean up information in the extra segment appended to each page.
+**
+** The destructor is not called as a result sqlitepager_close().
+** Destructors are only called by sqlitepager_unref().
+*/
+void sqlitepager_set_destructor(Pager *pPager, void (*xDesc)(void*)){
+ pPager->xDestructor = xDesc;
+}
+
+/*
+** Return the total number of pages in the disk file associated with
+** pPager.
+*/
+int sqlitepager_pagecount(Pager *pPager){
+ off_t n;
+ assert( pPager!=0 );
+ if( pPager->dbSize>=0 ){
+ return pPager->dbSize;
+ }
+ if( sqliteOsFileSize(&pPager->fd, &n)!=STQLITE_OK ){
+ pPager->errMask |= PAGER_ERR_DISK;
+ return 0;
+ }
+ n /= STQLITE_PAGE_SIZE;
+ if( pPager->state!=STQLITE_UNLOCK ){
+ pPager->dbSize = n;
+ }
+ return n;
+}
+
+/*
+** Forward declaration
+*/
+static int syncJournal(Pager*);
+
+/*
+** Truncate the file to the number of pages specified.
+*/
+int sqlitepager_truncate(Pager *pPager, Pgno nPage){
+ int rc;
+ if( pPager->dbSize<0 ){
+ sqlitepager_pagecount(pPager);
+ }
+ if( pPager->errMask!=0 ){
+ rc = pager_errcode(pPager);
+ return rc;
+ }
+ if( nPage>=(unsigned)pPager->dbSize ){
+ return STQLITE_OK;
+ }
+ syncJournal(pPager);
+ rc = sqliteOsTruncate(&pPager->fd, STQLITE_PAGE_SIZE*(off_t)nPage);
+ if( rc==STQLITE_OK ){
+ pPager->dbSize = nPage;
+ }
+ return rc;
+}
+
+/*
+** Shutdown the page cache. Free all memory and close all files.
+**
+** If a transaction was in progress when this routine is called, that
+** transaction is rolled back. All outstanding pages are invalidated
+** and their memory is freed. Any attempt to use a page associated
+** with this page cache after this function returns will likely
+** result in a coredump.
+*/
+int sqlitepager_close(Pager *pPager){
+ PgHdr *pPg, *pNext;
+ switch( pPager->state ){
+ case STQLITE_WRITELOCK: {
+ sqlitepager_rollback(pPager);
+ sqliteOsUnlock(&pPager->fd);
+ assert( pPager->journalOpen==0 );
+ break;
+ }
+ case STQLITE_READLOCK: {
+ sqliteOsUnlock(&pPager->fd);
+ break;
+ }
+ default: {
+ /* Do nothing */
+ break;
+ }
+ }
+ for(pPg=pPager->pAll; pPg; pPg=pNext){
+ pNext = pPg->pNextAll;
+ sqliteFree(pPg);
+ }
+ sqliteOsClose(&pPager->fd);
+ assert( pPager->journalOpen==0 );
+ /* Temp files are automatically deleted by the OS
+ ** if( pPager->tempFile ){
+ ** sqliteOsDelete(pPager->zFilename);
+ ** }
+ */
+ CLR_PAGER(pPager);
+ if( pPager->zFilename!=(char*)&pPager[1] ){
+ assert( 0 ); /* Cannot happen */
+ sqliteFree(pPager->zFilename);
+ sqliteFree(pPager->zJournal);
+ sqliteFree(pPager->zDirectory);
+ }
+ sqliteFree(pPager);
+ return STQLITE_OK;
+}
+
+/*
+** Return the page number for the given page data.
+*/
+Pgno sqlitepager_pagenumber(void *pData){
+ PgHdr *p = DATA_TO_PGHDR(pData);
+ return p->pgno;
+}
+
+/*
+** Increment the reference count for a page. If the page is
+** currently on the freelist (the reference count is zero) then
+** remove it from the freelist.
+*/
+#define page_ref(P) ((P)->nRef==0?_page_ref(P):(void)(P)->nRef++)
+static void _page_ref(PgHdr *pPg){
+ if( pPg->nRef==0 ){
+ /* The page is currently on the freelist. Remove it. */
+ if( pPg==pPg->pPager->pFirstSynced ){
+ PgHdr *p = pPg->pNextFree;
+ while( p && p->needSync ){ p = p->pNextFree; }
+ pPg->pPager->pFirstSynced = p;
+ }
+ if( pPg->pPrevFree ){
+ pPg->pPrevFree->pNextFree = pPg->pNextFree;
+ }else{
+ pPg->pPager->pFirst = pPg->pNextFree;
+ }
+ if( pPg->pNextFree ){
+ pPg->pNextFree->pPrevFree = pPg->pPrevFree;
+ }else{
+ pPg->pPager->pLast = pPg->pPrevFree;
+ }
+ pPg->pPager->nRef++;
+ }
+ pPg->nRef++;
+ REFINFO(pPg);
+}
+
+/*
+** Increment the reference count for a page. The input pointer is
+** a reference to the page data.
+*/
+int sqlitepager_ref(void *pData){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ page_ref(pPg);
+ return STQLITE_OK;
+}
+
+/*
+** Sync the journal. In other words, make sure all the pages that have
+** been written to the journal have actually reached the surface of the
+** disk. It is not safe to modify the original database file until after
+** the journal has been synced. If the original database is modified before
+** the journal is synced and a power failure occurs, the unsynced journal
+** data would be lost and we would be unable to completely rollback the
+** database changes. Database corruption would occur.
+**
+** This routine also updates the nRec field in the header of the journal.
+** (See comments on the pager_playback() routine for additional information.)
+** If the sync mode is FULL, two syncs will occur. First the whole journal
+** is synced, then the nRec field is updated, then a second sync occurs.
+**
+** For temporary databases, we do not care if we are able to rollback
+** after a power failure, so sync occurs.
+**
+** This routine clears the needSync field of every page current held in
+** memory.
+*/
+static int syncJournal(Pager *pPager){
+ PgHdr *pPg;
+ int rc = STQLITE_OK;
+
+ /* Sync the journal before modifying the main database
+ ** (assuming there is a journal and it needs to be synced.)
+ */
+ if( pPager->needSync ){
+ if( !pPager->tempFile ){
+ assert( pPager->journalOpen );
+ /* assert( !pPager->noSync ); // noSync might be set if synchronous
+ ** was turned off after the transaction was started. Ticket #615 */
+#ifndef NDEBUG
+ {
+ /* Make sure the pPager->nRec counter we are keeping agrees
+ ** with the nRec computed from the size of the journal file.
+ */
+ off_t hdrSz, pgSz, jSz;
+ hdrSz = JOURNAL_HDR_SZ(journal_format);
+ pgSz = JOURNAL_PG_SZ(journal_format);
+ rc = sqliteOsFileSize(&pPager->jfd, &jSz);
+ if( rc!=0 ) return rc;
+ assert( pPager->nRec*pgSz+hdrSz==jSz );
+ }
+#endif
+ if( journal_format>=3 ){
+ /* Write the nRec value into the journal file header */
+ off_t szJ;
+ if( pPager->fullSync ){
+ TRACE1("SYNC\n");
+ rc = sqliteOsSync(&pPager->jfd);
+ if( rc!=0 ) return rc;
+ }
+ sqliteOsSeek(&pPager->jfd, sizeof(aJournalMagic1));
+ rc = write32bits(&pPager->jfd, pPager->nRec);
+ if( rc ) return rc;
+ szJ = JOURNAL_HDR_SZ(journal_format) +
+ pPager->nRec*JOURNAL_PG_SZ(journal_format);
+ sqliteOsSeek(&pPager->jfd, szJ);
+ }
+ TRACE1("SYNC\n");
+ rc = sqliteOsSync(&pPager->jfd);
+ if( rc!=0 ) return rc;
+ pPager->journalStarted = 1;
+ }
+ pPager->needSync = 0;
+
+ /* Erase the needSync flag from every page.
+ */
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ pPg->needSync = 0;
+ }
+ pPager->pFirstSynced = pPager->pFirst;
+ }
+
+#ifndef NDEBUG
+ /* If the Pager.needSync flag is clear then the PgHdr.needSync
+ ** flag must also be clear for all pages. Verify that this
+ ** invariant is true.
+ */
+ else{
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ assert( pPg->needSync==0 );
+ }
+ assert( pPager->pFirstSynced==pPager->pFirst );
+ }
+#endif
+
+ return rc;
+}
+
+/*
+** Given a list of pages (connected by the PgHdr.pDirty pointer) write
+** every one of those pages out to the database file and mark them all
+** as clean.
+*/
+static int pager_write_pagelist(PgHdr *pList){
+ Pager *pPager;
+ int rc;
+
+ if( pList==0 ) return STQLITE_OK;
+ pPager = pList->pPager;
+ while( pList ){
+ assert( pList->dirty );
+ sqliteOsSeek(&pPager->fd, (pList->pgno-1)*(off_t)STQLITE_PAGE_SIZE);
+ CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 6);
+ TRACE2("STORE %d\n", pList->pgno);
+ rc = sqliteOsWrite(&pPager->fd, PGHDR_TO_DATA(pList), STQLITE_PAGE_SIZE);
+ CODEC(pPager, PGHDR_TO_DATA(pList), pList->pgno, 0);
+ if( rc ) return rc;
+ pList->dirty = 0;
+ pList = pList->pDirty;
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Collect every dirty page into a dirty list and
+** return a pointer to the head of that list. All pages are
+** collected even if they are still in use.
+*/
+static PgHdr *pager_get_all_dirty_pages(Pager *pPager){
+ PgHdr *p, *pList;
+ pList = 0;
+ for(p=pPager->pAll; p; p=p->pNextAll){
+ if( p->dirty ){
+ p->pDirty = pList;
+ pList = p;
+ }
+ }
+ return pList;
+}
+
+/*
+** Acquire a page.
+**
+** A read lock on the disk file is obtained when the first page is acquired.
+** This read lock is dropped when the last page is released.
+**
+** A _get works for any page number greater than 0. If the database
+** file is smaller than the requested page, then no actual disk
+** read occurs and the memory image of the page is initialized to
+** all zeros. The extra data appended to a page is always initialized
+** to zeros the first time a page is loaded into memory.
+**
+** The acquisition might fail for several reasons. In all cases,
+** an appropriate error code is returned and *ppPage is set to NULL.
+**
+** See also sqlitepager_lookup(). Both this routine and _lookup() attempt
+** to tqfind a page in the in-memory cache first. If the page is not already
+** in memory, this routine goes to disk to read it in whereas _lookup()
+** just returns 0. This routine acquires a read-lock the first time it
+** has to go to disk, and could also playback an old journal if necessary.
+** Since _lookup() never goes to disk, it never has to deal with locks
+** or journal files.
+*/
+int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage){
+ PgHdr *pPg;
+ int rc;
+
+ /* Make sure we have not hit any critical errors.
+ */
+ assert( pPager!=0 );
+ assert( pgno!=0 );
+ *ppPage = 0;
+ if( pPager->errMask & ~(PAGER_ERR_FULL) ){
+ return pager_errcode(pPager);
+ }
+
+ /* If this is the first page accessed, then get a read lock
+ ** on the database file.
+ */
+ if( pPager->nRef==0 ){
+ rc = sqliteOsReadLock(&pPager->fd);
+ if( rc!=STQLITE_OK ){
+ return rc;
+ }
+ pPager->state = STQLITE_READLOCK;
+
+ /* If a journal file exists, try to play it back.
+ */
+ if( pPager->useJournal && sqliteOsFileExists(pPager->zJournal) ){
+ int rc;
+
+ /* Get a write lock on the database
+ */
+ rc = sqliteOsWriteLock(&pPager->fd);
+ if( rc!=STQLITE_OK ){
+ if( sqliteOsUnlock(&pPager->fd)!=STQLITE_OK ){
+ /* This should never happen! */
+ rc = STQLITE_INTERNAL;
+ }
+ return rc;
+ }
+ pPager->state = STQLITE_WRITELOCK;
+
+ /* Open the journal for reading only. Return STQLITE_BUSY if
+ ** we are unable to open the journal file.
+ **
+ ** The journal file does not need to be locked itself. The
+ ** journal file is never open unless the main database file holds
+ ** a write lock, so there is never any chance of two or more
+ ** processes opening the journal at the same time.
+ */
+ rc = sqliteOsOpenReadOnly(pPager->zJournal, &pPager->jfd);
+ if( rc!=STQLITE_OK ){
+ rc = sqliteOsUnlock(&pPager->fd);
+ assert( rc==STQLITE_OK );
+ return STQLITE_BUSY;
+ }
+ pPager->journalOpen = 1;
+ pPager->journalStarted = 0;
+
+ /* Playback and delete the journal. Drop the database write
+ ** lock and reacquire the read lock.
+ */
+ rc = pager_playback(pPager, 0);
+ if( rc!=STQLITE_OK ){
+ return rc;
+ }
+ }
+ pPg = 0;
+ }else{
+ /* Search for page in cache */
+ pPg = pager_lookup(pPager, pgno);
+ }
+ if( pPg==0 ){
+ /* The requested page is not in the page cache. */
+ int h;
+ pPager->nMiss++;
+ if( pPager->nPage<pPager->mxPage || pPager->pFirst==0 ){
+ /* Create a new page */
+ pPg = sqliteMallocRaw( sizeof(*pPg) + STQLITE_PAGE_SIZE
+ + sizeof(u32) + pPager->nExtra );
+ if( pPg==0 ){
+ pager_unwritelock(pPager);
+ pPager->errMask |= PAGER_ERR_MEM;
+ return STQLITE_NOMEM;
+ }
+ memset(pPg, 0, sizeof(*pPg));
+ pPg->pPager = pPager;
+ pPg->pNextAll = pPager->pAll;
+ if( pPager->pAll ){
+ pPager->pAll->pPrevAll = pPg;
+ }
+ pPg->pPrevAll = 0;
+ pPager->pAll = pPg;
+ pPager->nPage++;
+ }else{
+ /* Find a page to recycle. Try to locate a page that does not
+ ** require us to do an fsync() on the journal.
+ */
+ pPg = pPager->pFirstSynced;
+
+ /* If we could not tqfind a page that does not require an fsync()
+ ** on the journal file then fsync the journal file. This is a
+ ** very slow operation, so we work hard to avoid it. But sometimes
+ ** it can't be helped.
+ */
+ if( pPg==0 ){
+ int rc = syncJournal(pPager);
+ if( rc!=0 ){
+ sqlitepager_rollback(pPager);
+ return STQLITE_IOERR;
+ }
+ pPg = pPager->pFirst;
+ }
+ assert( pPg->nRef==0 );
+
+ /* Write the page to the database file if it is dirty.
+ */
+ if( pPg->dirty ){
+ assert( pPg->needSync==0 );
+ pPg->pDirty = 0;
+ rc = pager_write_pagelist( pPg );
+ if( rc!=STQLITE_OK ){
+ sqlitepager_rollback(pPager);
+ return STQLITE_IOERR;
+ }
+ }
+ assert( pPg->dirty==0 );
+
+ /* If the page we are recycling is marked as alwaysRollback, then
+ ** set the global alwaysRollback flag, thus disabling the
+ ** sqlite_dont_rollback() optimization for the rest of this transaction.
+ ** It is necessary to do this because the page marked alwaysRollback
+ ** might be reloaded at a later time but at that point we won't remember
+ ** that is was marked alwaysRollback. This means that all pages must
+ ** be marked as alwaysRollback from here on out.
+ */
+ if( pPg->alwaysRollback ){
+ pPager->alwaysRollback = 1;
+ }
+
+ /* Unlink the old page from the free list and the hash table
+ */
+ if( pPg==pPager->pFirstSynced ){
+ PgHdr *p = pPg->pNextFree;
+ while( p && p->needSync ){ p = p->pNextFree; }
+ pPager->pFirstSynced = p;
+ }
+ if( pPg->pPrevFree ){
+ pPg->pPrevFree->pNextFree = pPg->pNextFree;
+ }else{
+ assert( pPager->pFirst==pPg );
+ pPager->pFirst = pPg->pNextFree;
+ }
+ if( pPg->pNextFree ){
+ pPg->pNextFree->pPrevFree = pPg->pPrevFree;
+ }else{
+ assert( pPager->pLast==pPg );
+ pPager->pLast = pPg->pPrevFree;
+ }
+ pPg->pNextFree = pPg->pPrevFree = 0;
+ if( pPg->pNextHash ){
+ pPg->pNextHash->pPrevHash = pPg->pPrevHash;
+ }
+ if( pPg->pPrevHash ){
+ pPg->pPrevHash->pNextHash = pPg->pNextHash;
+ }else{
+ h = pager_hash(pPg->pgno);
+ assert( pPager->aHash[h]==pPg );
+ pPager->aHash[h] = pPg->pNextHash;
+ }
+ pPg->pNextHash = pPg->pPrevHash = 0;
+ pPager->nOvfl++;
+ }
+ pPg->pgno = pgno;
+ if( pPager->aInJournal && (int)pgno<=pPager->origDbSize ){
+ sqliteCheckMemory(pPager->aInJournal, pgno/8);
+ assert( pPager->journalOpen );
+ pPg->inJournal = (pPager->aInJournal[pgno/8] & (1<<(pgno&7)))!=0;
+ pPg->needSync = 0;
+ }else{
+ pPg->inJournal = 0;
+ pPg->needSync = 0;
+ }
+ if( pPager->aInCkpt && (int)pgno<=pPager->ckptSize
+ && (pPager->aInCkpt[pgno/8] & (1<<(pgno&7)))!=0 ){
+ page_add_to_ckpt_list(pPg);
+ }else{
+ page_remove_from_ckpt_list(pPg);
+ }
+ pPg->dirty = 0;
+ pPg->nRef = 1;
+ REFINFO(pPg);
+ pPager->nRef++;
+ h = pager_hash(pgno);
+ pPg->pNextHash = pPager->aHash[h];
+ pPager->aHash[h] = pPg;
+ if( pPg->pNextHash ){
+ assert( pPg->pNextHash->pPrevHash==0 );
+ pPg->pNextHash->pPrevHash = pPg;
+ }
+ if( pPager->nExtra>0 ){
+ memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
+ }
+ if( pPager->dbSize<0 ) sqlitepager_pagecount(pPager);
+ if( pPager->errMask!=0 ){
+ sqlitepager_unref(PGHDR_TO_DATA(pPg));
+ rc = pager_errcode(pPager);
+ return rc;
+ }
+ if( pPager->dbSize<(int)pgno ){
+ memset(PGHDR_TO_DATA(pPg), 0, STQLITE_PAGE_SIZE);
+ }else{
+ int rc;
+ sqliteOsSeek(&pPager->fd, (pgno-1)*(off_t)STQLITE_PAGE_SIZE);
+ rc = sqliteOsRead(&pPager->fd, PGHDR_TO_DATA(pPg), STQLITE_PAGE_SIZE);
+ TRACE2("FETCH %d\n", pPg->pgno);
+ CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
+ if( rc!=STQLITE_OK ){
+ off_t fileSize;
+ if( sqliteOsFileSize(&pPager->fd,&fileSize)!=STQLITE_OK
+ || fileSize>=pgno*STQLITE_PAGE_SIZE ){
+ sqlitepager_unref(PGHDR_TO_DATA(pPg));
+ return rc;
+ }else{
+ memset(PGHDR_TO_DATA(pPg), 0, STQLITE_PAGE_SIZE);
+ }
+ }
+ }
+ }else{
+ /* The requested page is in the page cache. */
+ pPager->nHit++;
+ page_ref(pPg);
+ }
+ *ppPage = PGHDR_TO_DATA(pPg);
+ return STQLITE_OK;
+}
+
+/*
+** Acquire a page if it is already in the in-memory cache. Do
+** not read the page from disk. Return a pointer to the page,
+** or 0 if the page is not in cache.
+**
+** See also sqlitepager_get(). The difference between this routine
+** and sqlitepager_get() is that _get() will go to the disk and read
+** in the page if the page is not already in cache. This routine
+** returns NULL if the page is not in cache or if a disk I/O error
+** has ever happened.
+*/
+void *sqlitepager_lookup(Pager *pPager, Pgno pgno){
+ PgHdr *pPg;
+
+ assert( pPager!=0 );
+ assert( pgno!=0 );
+ if( pPager->errMask & ~(PAGER_ERR_FULL) ){
+ return 0;
+ }
+ /* if( pPager->nRef==0 ){
+ ** return 0;
+ ** }
+ */
+ pPg = pager_lookup(pPager, pgno);
+ if( pPg==0 ) return 0;
+ page_ref(pPg);
+ return PGHDR_TO_DATA(pPg);
+}
+
+/*
+** Release a page.
+**
+** If the number of references to the page drop to zero, then the
+** page is added to the LRU list. When all references to all pages
+** are released, a rollback occurs and the lock on the database is
+** removed.
+*/
+int sqlitepager_unref(void *pData){
+ PgHdr *pPg;
+
+ /* Decrement the reference count for this page
+ */
+ pPg = DATA_TO_PGHDR(pData);
+ assert( pPg->nRef>0 );
+ pPg->nRef--;
+ REFINFO(pPg);
+
+ /* When the number of references to a page reach 0, call the
+ ** destructor and add the page to the freelist.
+ */
+ if( pPg->nRef==0 ){
+ Pager *pPager;
+ pPager = pPg->pPager;
+ pPg->pNextFree = 0;
+ pPg->pPrevFree = pPager->pLast;
+ pPager->pLast = pPg;
+ if( pPg->pPrevFree ){
+ pPg->pPrevFree->pNextFree = pPg;
+ }else{
+ pPager->pFirst = pPg;
+ }
+ if( pPg->needSync==0 && pPager->pFirstSynced==0 ){
+ pPager->pFirstSynced = pPg;
+ }
+ if( pPager->xDestructor ){
+ pPager->xDestructor(pData);
+ }
+
+ /* When all pages reach the freelist, drop the read lock from
+ ** the database file.
+ */
+ pPager->nRef--;
+ assert( pPager->nRef>=0 );
+ if( pPager->nRef==0 ){
+ pager_reset(pPager);
+ }
+ }
+ return STQLITE_OK;
+}
+
+/*
+** Create a journal file for pPager. There should already be a write
+** lock on the database file when this routine is called.
+**
+** Return STQLITE_OK if everything. Return an error code and release the
+** write lock if anything goes wrong.
+*/
+static int pager_open_journal(Pager *pPager){
+ int rc;
+ assert( pPager->state==STQLITE_WRITELOCK );
+ assert( pPager->journalOpen==0 );
+ assert( pPager->useJournal );
+ sqlitepager_pagecount(pPager);
+ pPager->aInJournal = sqliteMalloc( pPager->dbSize/8 + 1 );
+ if( pPager->aInJournal==0 ){
+ sqliteOsReadLock(&pPager->fd);
+ pPager->state = STQLITE_READLOCK;
+ return STQLITE_NOMEM;
+ }
+ rc = sqliteOsOpenExclusive(pPager->zJournal, &pPager->jfd,pPager->tempFile);
+ if( rc!=STQLITE_OK ){
+ sqliteFree(pPager->aInJournal);
+ pPager->aInJournal = 0;
+ sqliteOsReadLock(&pPager->fd);
+ pPager->state = STQLITE_READLOCK;
+ return STQLITE_CANTOPEN;
+ }
+ sqliteOsOpenDirectory(pPager->zDirectory, &pPager->jfd);
+ pPager->journalOpen = 1;
+ pPager->journalStarted = 0;
+ pPager->needSync = 0;
+ pPager->alwaysRollback = 0;
+ pPager->nRec = 0;
+ if( pPager->errMask!=0 ){
+ rc = pager_errcode(pPager);
+ return rc;
+ }
+ pPager->origDbSize = pPager->dbSize;
+ if( journal_format==JOURNAL_FORMAT_3 ){
+ rc = sqliteOsWrite(&pPager->jfd, aJournalMagic3, sizeof(aJournalMagic3));
+ if( rc==STQLITE_OK ){
+ rc = write32bits(&pPager->jfd, pPager->noSync ? 0xffffffff : 0);
+ }
+ if( rc==STQLITE_OK ){
+ sqliteRandomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
+ rc = write32bits(&pPager->jfd, pPager->cksumInit);
+ }
+ }else if( journal_format==JOURNAL_FORMAT_2 ){
+ rc = sqliteOsWrite(&pPager->jfd, aJournalMagic2, sizeof(aJournalMagic2));
+ }else{
+ assert( journal_format==JOURNAL_FORMAT_1 );
+ rc = sqliteOsWrite(&pPager->jfd, aJournalMagic1, sizeof(aJournalMagic1));
+ }
+ if( rc==STQLITE_OK ){
+ rc = write32bits(&pPager->jfd, pPager->dbSize);
+ }
+ if( pPager->ckptAutoopen && rc==STQLITE_OK ){
+ rc = sqlitepager_ckpt_begin(pPager);
+ }
+ if( rc!=STQLITE_OK ){
+ rc = pager_unwritelock(pPager);
+ if( rc==STQLITE_OK ){
+ rc = STQLITE_FULL;
+ }
+ }
+ return rc;
+}
+
+/*
+** Acquire a write-lock on the database. The lock is removed when
+** the any of the following happen:
+**
+** * sqlitepager_commit() is called.
+** * sqlitepager_rollback() is called.
+** * sqlitepager_close() is called.
+** * sqlitepager_unref() is called to on every outstanding page.
+**
+** The parameter to this routine is a pointer to any open page of the
+** database file. Nothing changes about the page - it is used merely
+** to acquire a pointer to the Pager structure and as proof that there
+** is already a read-lock on the database.
+**
+** A journal file is opened if this is not a temporary file. For
+** temporary files, the opening of the journal file is deferred until
+** there is an actual need to write to the journal.
+**
+** If the database is already write-locked, this routine is a no-op.
+*/
+int sqlitepager_begin(void *pData){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ Pager *pPager = pPg->pPager;
+ int rc = STQLITE_OK;
+ assert( pPg->nRef>0 );
+ assert( pPager->state!=STQLITE_UNLOCK );
+ if( pPager->state==STQLITE_READLOCK ){
+ assert( pPager->aInJournal==0 );
+ rc = sqliteOsWriteLock(&pPager->fd);
+ if( rc!=STQLITE_OK ){
+ return rc;
+ }
+ pPager->state = STQLITE_WRITELOCK;
+ pPager->dirtyFile = 0;
+ TRACE1("TRANSACTION\n");
+ if( pPager->useJournal && !pPager->tempFile ){
+ rc = pager_open_journal(pPager);
+ }
+ }
+ return rc;
+}
+
+/*
+** Mark a data page as writeable. The page is written into the journal
+** if it is not there already. This routine must be called before making
+** changes to a page.
+**
+** The first time this routine is called, the pager creates a new
+** journal and acquires a write lock on the database. If the write
+** lock could not be acquired, this routine returns STQLITE_BUSY. The
+** calling routine must check for that return value and be careful not to
+** change any page data until this routine returns STQLITE_OK.
+**
+** If the journal file could not be written because the disk is full,
+** then this routine returns STQLITE_FULL and does an immediate rollback.
+** All subsequent write attempts also return STQLITE_FULL until there
+** is a call to sqlitepager_commit() or sqlitepager_rollback() to
+** reset.
+*/
+int sqlitepager_write(void *pData){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ Pager *pPager = pPg->pPager;
+ int rc = STQLITE_OK;
+
+ /* Check for errors
+ */
+ if( pPager->errMask ){
+ return pager_errcode(pPager);
+ }
+ if( pPager->readOnly ){
+ return STQLITE_PERM;
+ }
+
+ /* Mark the page as dirty. If the page has already been written
+ ** to the journal then we can return right away.
+ */
+ pPg->dirty = 1;
+ if( pPg->inJournal && (pPg->inCkpt || pPager->ckptInUse==0) ){
+ pPager->dirtyFile = 1;
+ return STQLITE_OK;
+ }
+
+ /* If we get this far, it means that the page needs to be
+ ** written to the transaction journal or the ckeckpoint journal
+ ** or both.
+ **
+ ** First check to see that the transaction journal exists and
+ ** create it if it does not.
+ */
+ assert( pPager->state!=STQLITE_UNLOCK );
+ rc = sqlitepager_begin(pData);
+ if( rc!=STQLITE_OK ){
+ return rc;
+ }
+ assert( pPager->state==STQLITE_WRITELOCK );
+ if( !pPager->journalOpen && pPager->useJournal ){
+ rc = pager_open_journal(pPager);
+ if( rc!=STQLITE_OK ) return rc;
+ }
+ assert( pPager->journalOpen || !pPager->useJournal );
+ pPager->dirtyFile = 1;
+
+ /* The transaction journal now exists and we have a write lock on the
+ ** main database file. Write the current page to the transaction
+ ** journal if it is not there already.
+ */
+ if( !pPg->inJournal && pPager->useJournal ){
+ if( (int)pPg->pgno <= pPager->origDbSize ){
+ int szPg;
+ u32 saved;
+ if( journal_format>=JOURNAL_FORMAT_3 ){
+ u32 cksum = pager_cksum(pPager, pPg->pgno, pData);
+ saved = *(u32*)PGHDR_TO_EXTRA(pPg);
+ store32bits(cksum, pPg, STQLITE_PAGE_SIZE);
+ szPg = STQLITE_PAGE_SIZE+8;
+ }else{
+ szPg = STQLITE_PAGE_SIZE+4;
+ }
+ store32bits(pPg->pgno, pPg, -4);
+ CODEC(pPager, pData, pPg->pgno, 7);
+ rc = sqliteOsWrite(&pPager->jfd, &((char*)pData)[-4], szPg);
+ TRACE3("JOURNAL %d %d\n", pPg->pgno, pPg->needSync);
+ CODEC(pPager, pData, pPg->pgno, 0);
+ if( journal_format>=JOURNAL_FORMAT_3 ){
+ *(u32*)PGHDR_TO_EXTRA(pPg) = saved;
+ }
+ if( rc!=STQLITE_OK ){
+ sqlitepager_rollback(pPager);
+ pPager->errMask |= PAGER_ERR_FULL;
+ return rc;
+ }
+ pPager->nRec++;
+ assert( pPager->aInJournal!=0 );
+ pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ pPg->needSync = !pPager->noSync;
+ pPg->inJournal = 1;
+ if( pPager->ckptInUse ){
+ pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ page_add_to_ckpt_list(pPg);
+ }
+ }else{
+ pPg->needSync = !pPager->journalStarted && !pPager->noSync;
+ TRACE3("APPEND %d %d\n", pPg->pgno, pPg->needSync);
+ }
+ if( pPg->needSync ){
+ pPager->needSync = 1;
+ }
+ }
+
+ /* If the checkpoint journal is open and the page is not in it,
+ ** then write the current page to the checkpoint journal. Note that
+ ** the checkpoint journal always uses the simplier format 2 that lacks
+ ** checksums. The header is also omitted from the checkpoint journal.
+ */
+ if( pPager->ckptInUse && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){
+ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
+ store32bits(pPg->pgno, pPg, -4);
+ CODEC(pPager, pData, pPg->pgno, 7);
+ rc = sqliteOsWrite(&pPager->cpfd, &((char*)pData)[-4], STQLITE_PAGE_SIZE+4);
+ TRACE2("CKPT-JOURNAL %d\n", pPg->pgno);
+ CODEC(pPager, pData, pPg->pgno, 0);
+ if( rc!=STQLITE_OK ){
+ sqlitepager_rollback(pPager);
+ pPager->errMask |= PAGER_ERR_FULL;
+ return rc;
+ }
+ pPager->ckptNRec++;
+ assert( pPager->aInCkpt!=0 );
+ pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ page_add_to_ckpt_list(pPg);
+ }
+
+ /* Update the database size and return.
+ */
+ if( pPager->dbSize<(int)pPg->pgno ){
+ pPager->dbSize = pPg->pgno;
+ }
+ return rc;
+}
+
+/*
+** Return TRUE if the page given in the argument was previously passed
+** to sqlitepager_write(). In other words, return TRUE if it is ok
+** to change the content of the page.
+*/
+int sqlitepager_iswriteable(void *pData){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ return pPg->dirty;
+}
+
+/*
+** Replace the content of a single page with the information in the third
+** argument.
+*/
+int sqlitepager_overwrite(Pager *pPager, Pgno pgno, void *pData){
+ void *pPage;
+ int rc;
+
+ rc = sqlitepager_get(pPager, pgno, &pPage);
+ if( rc==STQLITE_OK ){
+ rc = sqlitepager_write(pPage);
+ if( rc==STQLITE_OK ){
+ memcpy(pPage, pData, STQLITE_PAGE_SIZE);
+ }
+ sqlitepager_unref(pPage);
+ }
+ return rc;
+}
+
+/*
+** A call to this routine tells the pager that it is not necessary to
+** write the information on page "pgno" back to the disk, even though
+** that page might be marked as dirty.
+**
+** The overlying software layer calls this routine when all of the data
+** on the given page is unused. The pager marks the page as clean so
+** that it does not get written to disk.
+**
+** Tests show that this optimization, together with the
+** sqlitepager_dont_rollback() below, more than double the speed
+** of large INSERT operations and quadruple the speed of large DELETEs.
+**
+** When this routine is called, set the alwaysRollback flag to true.
+** Subsequent calls to sqlitepager_dont_rollback() for the same page
+** will thereafter be ignored. This is necessary to avoid a problem
+** where a page with data is added to the freelist during one part of
+** a transaction then removed from the freelist during a later part
+** of the same transaction and reused for some other purpose. When it
+** is first added to the freelist, this routine is called. When reused,
+** the dont_rollback() routine is called. But because the page tqcontains
+** critical data, we still need to be sure it gets rolled back in spite
+** of the dont_rollback() call.
+*/
+void sqlitepager_dont_write(Pager *pPager, Pgno pgno){
+ PgHdr *pPg;
+
+ pPg = pager_lookup(pPager, pgno);
+ pPg->alwaysRollback = 1;
+ if( pPg && pPg->dirty ){
+ if( pPager->dbSize==(int)pPg->pgno && pPager->origDbSize<pPager->dbSize ){
+ /* If this pages is the last page in the file and the file has grown
+ ** during the current transaction, then do NOT mark the page as clean.
+ ** When the database file grows, we must make sure that the last page
+ ** gets written at least once so that the disk file will be the correct
+ ** size. If you do not write this page and the size of the file
+ ** on the disk ends up being too small, that can lead to database
+ ** corruption during the next transaction.
+ */
+ }else{
+ TRACE2("DONT_WRITE %d\n", pgno);
+ pPg->dirty = 0;
+ }
+ }
+}
+
+/*
+** A call to this routine tells the pager that if a rollback occurs,
+** it is not necessary to restore the data on the given page. This
+** means that the pager does not have to record the given page in the
+** rollback journal.
+*/
+void sqlitepager_dont_rollback(void *pData){
+ PgHdr *pPg = DATA_TO_PGHDR(pData);
+ Pager *pPager = pPg->pPager;
+
+ if( pPager->state!=STQLITE_WRITELOCK || pPager->journalOpen==0 ) return;
+ if( pPg->alwaysRollback || pPager->alwaysRollback ) return;
+ if( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ){
+ assert( pPager->aInJournal!=0 );
+ pPager->aInJournal[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ pPg->inJournal = 1;
+ if( pPager->ckptInUse ){
+ pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ page_add_to_ckpt_list(pPg);
+ }
+ TRACE2("DONT_ROLLBACK %d\n", pPg->pgno);
+ }
+ if( pPager->ckptInUse && !pPg->inCkpt && (int)pPg->pgno<=pPager->ckptSize ){
+ assert( pPg->inJournal || (int)pPg->pgno>pPager->origDbSize );
+ assert( pPager->aInCkpt!=0 );
+ pPager->aInCkpt[pPg->pgno/8] |= 1<<(pPg->pgno&7);
+ page_add_to_ckpt_list(pPg);
+ }
+}
+
+/*
+** Commit all changes to the database and release the write lock.
+**
+** If the commit fails for any reason, a rollback attempt is made
+** and an error code is returned. If the commit worked, STQLITE_OK
+** is returned.
+*/
+int sqlitepager_commit(Pager *pPager){
+ int rc;
+ PgHdr *pPg;
+
+ if( pPager->errMask==PAGER_ERR_FULL ){
+ rc = sqlitepager_rollback(pPager);
+ if( rc==STQLITE_OK ){
+ rc = STQLITE_FULL;
+ }
+ return rc;
+ }
+ if( pPager->errMask!=0 ){
+ rc = pager_errcode(pPager);
+ return rc;
+ }
+ if( pPager->state!=STQLITE_WRITELOCK ){
+ return STQLITE_ERROR;
+ }
+ TRACE1("COMMIT\n");
+ if( pPager->dirtyFile==0 ){
+ /* Exit early (without doing the time-consuming sqliteOsSync() calls)
+ ** if there have been no changes to the database file. */
+ assert( pPager->needSync==0 );
+ rc = pager_unwritelock(pPager);
+ pPager->dbSize = -1;
+ return rc;
+ }
+ assert( pPager->journalOpen );
+ rc = syncJournal(pPager);
+ if( rc!=STQLITE_OK ){
+ goto commit_abort;
+ }
+ pPg = pager_get_all_dirty_pages(pPager);
+ if( pPg ){
+ rc = pager_write_pagelist(pPg);
+ if( rc || (!pPager->noSync && sqliteOsSync(&pPager->fd)!=STQLITE_OK) ){
+ goto commit_abort;
+ }
+ }
+ rc = pager_unwritelock(pPager);
+ pPager->dbSize = -1;
+ return rc;
+
+ /* Jump here if anything goes wrong during the commit process.
+ */
+commit_abort:
+ rc = sqlitepager_rollback(pPager);
+ if( rc==STQLITE_OK ){
+ rc = STQLITE_FULL;
+ }
+ return rc;
+}
+
+/*
+** Rollback all changes. The database falls back to read-only mode.
+** All in-memory cache pages revert to their original data contents.
+** The journal is deleted.
+**
+** This routine cannot fail unless some other process is not following
+** the correct locking protocol (STQLITE_PROTOCOL) or unless some other
+** process is writing trash into the journal file (STQLITE_CORRUPT) or
+** unless a prior malloc() failed (STQLITE_NOMEM). Appropriate error
+** codes are returned for all these occasions. Otherwise,
+** STQLITE_OK is returned.
+*/
+int sqlitepager_rollback(Pager *pPager){
+ int rc;
+ TRACE1("ROLLBACK\n");
+ if( !pPager->dirtyFile || !pPager->journalOpen ){
+ rc = pager_unwritelock(pPager);
+ pPager->dbSize = -1;
+ return rc;
+ }
+
+ if( pPager->errMask!=0 && pPager->errMask!=PAGER_ERR_FULL ){
+ if( pPager->state>=STQLITE_WRITELOCK ){
+ pager_playback(pPager, 1);
+ }
+ return pager_errcode(pPager);
+ }
+ if( pPager->state!=STQLITE_WRITELOCK ){
+ return STQLITE_OK;
+ }
+ rc = pager_playback(pPager, 1);
+ if( rc!=STQLITE_OK ){
+ rc = STQLITE_CORRUPT;
+ pPager->errMask |= PAGER_ERR_CORRUPT;
+ }
+ pPager->dbSize = -1;
+ return rc;
+}
+
+/*
+** Return TRUE if the database file is opened read-only. Return FALSE
+** if the database is (in theory) writable.
+*/
+int sqlitepager_isreadonly(Pager *pPager){
+ return pPager->readOnly;
+}
+
+/*
+** This routine is used for testing and analysis only.
+*/
+int *sqlitepager_stats(Pager *pPager){
+ static int a[9];
+ a[0] = pPager->nRef;
+ a[1] = pPager->nPage;
+ a[2] = pPager->mxPage;
+ a[3] = pPager->dbSize;
+ a[4] = pPager->state;
+ a[5] = pPager->errMask;
+ a[6] = pPager->nHit;
+ a[7] = pPager->nMiss;
+ a[8] = pPager->nOvfl;
+ return a;
+}
+
+/*
+** Set the checkpoint.
+**
+** This routine should be called with the transaction journal already
+** open. A new checkpoint journal is created that can be used to rollback
+** changes of a single SQL command within a larger transaction.
+*/
+int sqlitepager_ckpt_begin(Pager *pPager){
+ int rc;
+ char zTemp[STQLITE_TEMPNAME_SIZE];
+ if( !pPager->journalOpen ){
+ pPager->ckptAutoopen = 1;
+ return STQLITE_OK;
+ }
+ assert( pPager->journalOpen );
+ assert( !pPager->ckptInUse );
+ pPager->aInCkpt = sqliteMalloc( pPager->dbSize/8 + 1 );
+ if( pPager->aInCkpt==0 ){
+ sqliteOsReadLock(&pPager->fd);
+ return STQLITE_NOMEM;
+ }
+#ifndef NDEBUG
+ rc = sqliteOsFileSize(&pPager->jfd, &pPager->ckptJSize);
+ if( rc ) goto ckpt_begin_failed;
+ assert( pPager->ckptJSize ==
+ pPager->nRec*JOURNAL_PG_SZ(journal_format)+JOURNAL_HDR_SZ(journal_format) );
+#endif
+ pPager->ckptJSize = pPager->nRec*JOURNAL_PG_SZ(journal_format)
+ + JOURNAL_HDR_SZ(journal_format);
+ pPager->ckptSize = pPager->dbSize;
+ if( !pPager->ckptOpen ){
+ rc = sqlitepager_opentemp(zTemp, &pPager->cpfd);
+ if( rc ) goto ckpt_begin_failed;
+ pPager->ckptOpen = 1;
+ pPager->ckptNRec = 0;
+ }
+ pPager->ckptInUse = 1;
+ return STQLITE_OK;
+
+ckpt_begin_failed:
+ if( pPager->aInCkpt ){
+ sqliteFree(pPager->aInCkpt);
+ pPager->aInCkpt = 0;
+ }
+ return rc;
+}
+
+/*
+** Commit a checkpoint.
+*/
+int sqlitepager_ckpt_commit(Pager *pPager){
+ if( pPager->ckptInUse ){
+ PgHdr *pPg, *pNext;
+ sqliteOsSeek(&pPager->cpfd, 0);
+ /* sqliteOsTruncate(&pPager->cpfd, 0); */
+ pPager->ckptNRec = 0;
+ pPager->ckptInUse = 0;
+ sqliteFree( pPager->aInCkpt );
+ pPager->aInCkpt = 0;
+ for(pPg=pPager->pCkpt; pPg; pPg=pNext){
+ pNext = pPg->pNextCkpt;
+ assert( pPg->inCkpt );
+ pPg->inCkpt = 0;
+ pPg->pPrevCkpt = pPg->pNextCkpt = 0;
+ }
+ pPager->pCkpt = 0;
+ }
+ pPager->ckptAutoopen = 0;
+ return STQLITE_OK;
+}
+
+/*
+** Rollback a checkpoint.
+*/
+int sqlitepager_ckpt_rollback(Pager *pPager){
+ int rc;
+ if( pPager->ckptInUse ){
+ rc = pager_ckpt_playback(pPager);
+ sqlitepager_ckpt_commit(pPager);
+ }else{
+ rc = STQLITE_OK;
+ }
+ pPager->ckptAutoopen = 0;
+ return rc;
+}
+
+/*
+** Return the full pathname of the database file.
+*/
+const char *sqlitepager_filename(Pager *pPager){
+ return pPager->zFilename;
+}
+
+/*
+** Set the codec for this pager
+*/
+void sqlitepager_set_codec(
+ Pager *pPager,
+ void (*xCodec)(void*,void*,Pgno,int),
+ void *pCodecArg
+){
+ pPager->xCodec = xCodec;
+ pPager->pCodecArg = pCodecArg;
+}
+
+#ifdef STQLITE_TEST
+/*
+** Print a listing of all referenced pages and their ref count.
+*/
+void sqlitepager_refdump(Pager *pPager){
+ PgHdr *pPg;
+ for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
+ if( pPg->nRef<=0 ) continue;
+ printf("PAGE %3d addr=0x%08x nRef=%d\n",
+ pPg->pgno, (int)PGHDR_TO_DATA(pPg), pPg->nRef);
+ }
+}
+#endif
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/pager.h b/tqtinterface/qt4/src/3rdparty/sqlite/pager.h
new file mode 100644
index 0000000..c015e78
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/pager.h
@@ -0,0 +1,107 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This header file defines the interface that the sqlite page cache
+** subsystem. The page cache subsystem reads and writes a file a page
+** at a time and provides a journal for rollback.
+**
+** @(#) $Id: pager.h,v 1.26 2004/02/11 02:18:07 drh Exp $
+*/
+
+/*
+** The size of one page
+**
+** You can change this value to another (reasonable) value you want.
+** It need not be a power of two, though the interface to the disk
+** will likely be faster if it is.
+**
+** Experiments show that a page size of 1024 gives the best speed
+** for common usages. The speed differences for different sizes
+** such as 512, 2048, 4096, an so forth, is minimal. Note, however,
+** that changing the page size results in a completely imcompatible
+** file format.
+*/
+#ifndef STQLITE_PAGE_SIZE
+#define STQLITE_PAGE_SIZE 1024
+#endif
+
+/*
+** Number of extra bytes of data allocated at the end of each page and
+** stored on disk but not used by the higher level btree layer. Changing
+** this value results in a completely incompatible file format.
+*/
+#ifndef STQLITE_PAGE_RESERVE
+#define STQLITE_PAGE_RESERVE 0
+#endif
+
+/*
+** The total number of usable bytes stored on disk for each page.
+** The usable bytes come at the beginning of the page and the reserve
+** bytes come at the end.
+*/
+#define STQLITE_USABLE_SIZE (STQLITE_PAGE_SIZE-STQLITE_PAGE_RESERVE)
+
+/*
+** Maximum number of pages in one database. (This is a limitation of
+** imposed by 4GB files size limits.)
+*/
+#define STQLITE_MAX_PAGE 1073741823
+
+/*
+** The type used to represent a page number. The first page in a file
+** is called page 1. 0 is used to represent "not a page".
+*/
+typedef unsigned int Pgno;
+
+/*
+** Each open file is managed by a separate instance of the "Pager" structure.
+*/
+typedef struct Pager Pager;
+
+/*
+** See source code comments for a detailed description of the following
+** routines:
+*/
+int sqlitepager_open(Pager **ppPager, const char *zFilename,
+ int nPage, int nExtra, int useJournal);
+void sqlitepager_set_destructor(Pager*, void(*)(void*));
+void sqlitepager_set_cachesize(Pager*, int);
+int sqlitepager_close(Pager *pPager);
+int sqlitepager_get(Pager *pPager, Pgno pgno, void **ppPage);
+void *sqlitepager_lookup(Pager *pPager, Pgno pgno);
+int sqlitepager_ref(void*);
+int sqlitepager_unref(void*);
+Pgno sqlitepager_pagenumber(void*);
+int sqlitepager_write(void*);
+int sqlitepager_iswriteable(void*);
+int sqlitepager_overwrite(Pager *pPager, Pgno pgno, void*);
+int sqlitepager_pagecount(Pager*);
+int sqlitepager_truncate(Pager*,Pgno);
+int sqlitepager_begin(void*);
+int sqlitepager_commit(Pager*);
+int sqlitepager_rollback(Pager*);
+int sqlitepager_isreadonly(Pager*);
+int sqlitepager_ckpt_begin(Pager*);
+int sqlitepager_ckpt_commit(Pager*);
+int sqlitepager_ckpt_rollback(Pager*);
+void sqlitepager_dont_rollback(void*);
+void sqlitepager_dont_write(Pager*, Pgno);
+int *sqlitepager_stats(Pager*);
+void sqlitepager_set_safety_level(Pager*,int);
+const char *sqlitepager_filename(Pager*);
+int sqlitepager_rename(Pager*, const char *zNewName);
+void sqlitepager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);
+
+#ifdef STQLITE_TEST
+void sqlitepager_refdump(Pager*);
+int pager_refinfo_enable;
+int journal_format;
+#endif
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/parse.c b/tqtinterface/qt4/src/3rdparty/sqlite/parse.c
new file mode 100644
index 0000000..31ed279
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/parse.c
@@ -0,0 +1,4035 @@
+/* Driver template for the LEMON parser generator.
+** The author disclaims copyright to this source code.
+*/
+/* First off, code is include which follows the "include" declaration
+** in the input file. */
+#include <stdio.h>
+#line 33 "parse.y"
+
+#include "sqliteInt.h"
+#include "parse.h"
+
+/*
+** An instance of this structure holds information about the
+** LIMIT clause of a SELECT statement.
+*/
+struct LimitVal {
+ int limit; /* The LIMIT value. -1 if there is no limit */
+ int offset; /* The OFFSET. 0 if there is none */
+};
+
+/*
+** An instance of the following structure describes the event of a
+** TRIGGER. "a" is the event type, one of TK_UPDATE, TK_INSERT,
+** TK_DELETE, or TK_INSTEAD. If the event is of the form
+**
+** UPDATE ON (a,b,c)
+**
+** Then the "b" IdList records the list "a,b,c".
+*/
+struct TrigEvent { int a; IdList * b; };
+
+
+#line 34 "parse.c"
+/* Next is all token values, in a form suitable for use by makeheaders.
+** This section will be null unless lemon is run with the -m switch.
+*/
+/*
+** These constants (all generated automatically by the parser generator)
+** specify the various kinds of tokens (terminals) that the parser
+** understands.
+**
+** Each symbol here is a terminal symbol in the grammar.
+*/
+/* Make sure the INTERFACE macro is defined.
+*/
+#ifndef INTERFACE
+# define INTERFACE 1
+#endif
+/* The next thing included is series of defines which control
+** various aspects of the generated parser.
+** YYCODETYPE is the data type used for storing terminal
+** and nonterminal numbers. "unsigned char" is
+** used if there are fewer than 250 terminals
+** and nonterminals. "int" is used otherwise.
+** YYNOCODE is a number of type YYCODETYPE which corresponds
+** to no legal terminal or nonterminal number. This
+** number is used to fill in empty Q_SLOTS of the hash
+** table.
+** YYFALLBACK If defined, this indicates that one or more tokens
+** have fall-back values which should be used if the
+** original value of the token will not parse.
+** YYACTIONTYPE is the data type used for storing terminal
+** and nonterminal numbers. "unsigned char" is
+** used if there are fewer than 250 rules and
+** states combined. "int" is used otherwise.
+** sqliteParserTOKENTYPE is the data type used for minor tokens given
+** directly to the parser from the tokenizer.
+** YYMINORTYPE is the data type used for all minor tokens.
+** This is typically a union of many types, one of
+** which is sqliteParserTOKENTYPE. The entry in the union
+** for base tokens is called "yy0".
+** YYSTACKDEPTH is the maximum depth of the parser's stack.
+** sqliteParserARG_SDECL A static variable declaration for the %extra_argument
+** sqliteParserARG_PDECL A parameter declaration for the %extra_argument
+** sqliteParserARG_STORE Code to store %extra_argument into yypParser
+** sqliteParserARG_FETCH Code to extract %extra_argument from yypParser
+** YYNSTATE the combined number of states.
+** YYNRULE the number of rules in the grammar
+** YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
+*/
+/*  */
+#define YYCODETYPE unsigned char
+#define YYNOCODE 221
+#define YYACTIONTYPE unsigned short int
+#define sqliteParserTOKENTYPE Token
+typedef union {
+ sqliteParserTOKENTYPE yy0;
+ TriggerStep * yy19;
+ struct LimitVal yy124;
+ Select* yy179;
+ Expr * yy182;
+ Expr* yy242;
+ struct TrigEvent yy290;
+ Token yy298;
+ SrcList* yy307;
+ IdList* yy320;
+ ExprList* yy322;
+ int yy372;
+ struct {int value; int tqmask;} yy407;
+ int yy441;
+} YYMINORTYPE;
+#define YYSTACKDEPTH 100
+#define sqliteParserARG_SDECL Parse *pParse;
+#define sqliteParserARG_PDECL ,Parse *pParse
+#define sqliteParserARG_FETCH Parse *pParse = yypParser->pParse
+#define sqliteParserARG_STORE yypParser->pParse = pParse
+#define YYNSTATE 563
+#define YYNRULE 293
+#define YYERRORSYMBOL 131
+#define YYERRSYMDT yy441
+#define YYFALLBACK 1
+#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
+#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
+#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
+
+/* Next are that tables used to determine what action to take based on the
+** current state and lookahead token. These tables are used to implement
+** functions that take a state number and lookahead value and return an
+** action integer.
+**
+** Suppose the action integer is N. Then the action is determined as
+** follows
+**
+** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
+** token onto the stack and goto state N.
+**
+** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
+**
+** N == YYNSTATE+YYNRULE A syntax error has occurred.
+**
+** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
+**
+** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
+** Q_SLOTS in the yy_action[] table.
+**
+** The action table is constructed as a single large table named yy_action[].
+** Given state S and lookahead X, the action is computed as
+**
+** yy_action[ yy_shift_ofst[S] + X ]
+**
+** If the index value yy_shift_ofst[S]+X is out of range or if the value
+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
+** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
+** and that yy_default[S] should be used instead.
+**
+** The formula above is for computing the action when the lookahead is
+** a terminal symbol. If the lookahead is a non-terminal (as occurs after
+** a reduce action) then the yy_reduce_ofst[] array is used in place of
+** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
+** YY_SHIFT_USE_DFLT.
+**
+** The following are the tables generated in this section:
+**
+** yy_action[] A single table containing all actions.
+** yy_lookahead[] A table containing the lookahead for each entry in
+** yy_action. Used to detect hash collisions.
+** yy_shift_ofst[] For each state, the offset into yy_action for
+** shifting terminals.
+** yy_reduce_ofst[] For each state, the offset into yy_action for
+** shifting non-terminals after a reduce.
+** yy_default[] Default action for each state.
+*/
+static YYACTIONTYPE yy_action[] = {
+ /* 0 */ 264, 5, 262, 119, 123, 117, 121, 129, 131, 133,
+ /* 10 */ 135, 144, 146, 148, 150, 152, 154, 568, 106, 106,
+ /* 20 */ 143, 857, 1, 562, 3, 142, 129, 131, 133, 135,
+ /* 30 */ 144, 146, 148, 150, 152, 154, 174, 103, 8, 115,
+ /* 40 */ 104, 139, 127, 125, 156, 161, 157, 162, 166, 119,
+ /* 50 */ 123, 117, 121, 129, 131, 133, 135, 144, 146, 148,
+ /* 60 */ 150, 152, 154, 31, 361, 392, 263, 143, 363, 369,
+ /* 70 */ 374, 97, 142, 148, 150, 152, 154, 68, 75, 377,
+ /* 80 */ 167, 64, 218, 46, 20, 289, 115, 104, 139, 127,
+ /* 90 */ 125, 156, 161, 157, 162, 166, 119, 123, 117, 121,
+ /* 100 */ 129, 131, 133, 135, 144, 146, 148, 150, 152, 154,
+ /* 110 */ 193, 41, 336, 563, 44, 54, 60, 62, 308, 331,
+ /* 120 */ 175, 20, 560, 561, 572, 333, 640, 18, 359, 144,
+ /* 130 */ 146, 148, 150, 152, 154, 143, 181, 179, 303, 18,
+ /* 140 */ 142, 84, 86, 20, 177, 66, 67, 111, 21, 22,
+ /* 150 */ 112, 105, 83, 792, 115, 104, 139, 127, 125, 156,
+ /* 160 */ 161, 157, 162, 166, 119, 123, 117, 121, 129, 131,
+ /* 170 */ 133, 135, 144, 146, 148, 150, 152, 154, 790, 560,
+ /* 180 */ 561, 46, 13, 113, 183, 21, 22, 534, 361, 2,
+ /* 190 */ 3, 14, 363, 369, 374, 338, 361, 690, 544, 542,
+ /* 200 */ 363, 369, 374, 377, 836, 143, 15, 21, 22, 16,
+ /* 210 */ 142, 377, 44, 54, 60, 62, 308, 331, 396, 535,
+ /* 220 */ 17, 9, 191, 333, 115, 104, 139, 127, 125, 156,
+ /* 230 */ 161, 157, 162, 166, 119, 123, 117, 121, 129, 131,
+ /* 240 */ 133, 135, 144, 146, 148, 150, 152, 154, 571, 230,
+ /* 250 */ 340, 343, 143, 20, 536, 537, 538, 142, 402, 337,
+ /* 260 */ 398, 339, 357, 68, 346, 347, 32, 64, 266, 391,
+ /* 270 */ 37, 115, 104, 139, 127, 125, 156, 161, 157, 162,
+ /* 280 */ 166, 119, 123, 117, 121, 129, 131, 133, 135, 144,
+ /* 290 */ 146, 148, 150, 152, 154, 839, 193, 651, 291, 298,
+ /* 300 */ 300, 221, 357, 43, 173, 689, 175, 251, 330, 36,
+ /* 310 */ 37, 106, 232, 40, 335, 58, 137, 21, 22, 330,
+ /* 320 */ 411, 143, 181, 179, 47, 59, 142, 358, 390, 174,
+ /* 330 */ 177, 66, 67, 111, 448, 49, 112, 105, 583, 213,
+ /* 340 */ 115, 104, 139, 127, 125, 156, 161, 157, 162, 166,
+ /* 350 */ 119, 123, 117, 121, 129, 131, 133, 135, 144, 146,
+ /* 360 */ 148, 150, 152, 154, 306, 301, 106, 249, 259, 113,
+ /* 370 */ 183, 793, 70, 253, 281, 219, 20, 106, 20, 11,
+ /* 380 */ 106, 482, 454, 444, 299, 143, 169, 10, 171, 172,
+ /* 390 */ 142, 169, 73, 171, 172, 103, 688, 69, 174, 169,
+ /* 400 */ 252, 171, 172, 12, 115, 104, 139, 127, 125, 156,
+ /* 410 */ 161, 157, 162, 166, 119, 123, 117, 121, 129, 131,
+ /* 420 */ 133, 135, 144, 146, 148, 150, 152, 154, 95, 237,
+ /* 430 */ 313, 20, 143, 295, 244, 424, 169, 142, 171, 172,
+ /* 440 */ 21, 22, 21, 22, 219, 386, 316, 323, 325, 837,
+ /* 450 */ 19, 115, 104, 139, 127, 125, 156, 161, 157, 162,
+ /* 460 */ 166, 119, 123, 117, 121, 129, 131, 133, 135, 144,
+ /* 470 */ 146, 148, 150, 152, 154, 106, 661, 20, 264, 143,
+ /* 480 */ 262, 844, 315, 169, 142, 171, 172, 333, 38, 842,
+ /* 490 */ 10, 356, 348, 184, 421, 21, 22, 282, 115, 104,
+ /* 500 */ 139, 127, 125, 156, 161, 157, 162, 166, 119, 123,
+ /* 510 */ 117, 121, 129, 131, 133, 135, 144, 146, 148, 150,
+ /* 520 */ 152, 154, 69, 254, 262, 251, 143, 639, 663, 35,
+ /* 530 */ 65, 142, 726, 313, 283, 259, 185, 417, 419, 418,
+ /* 540 */ 284, 21, 22, 690, 263, 115, 104, 139, 127, 125,
+ /* 550 */ 156, 161, 157, 162, 166, 119, 123, 117, 121, 129,
+ /* 560 */ 131, 133, 135, 144, 146, 148, 150, 152, 154, 256,
+ /* 570 */ 20, 791, 424, 143, 169, 52, 171, 172, 142, 169,
+ /* 580 */ 24, 171, 172, 247, 53, 315, 26, 169, 263, 171,
+ /* 590 */ 172, 253, 115, 164, 139, 127, 125, 156, 161, 157,
+ /* 600 */ 162, 166, 119, 123, 117, 121, 129, 131, 133, 135,
+ /* 610 */ 144, 146, 148, 150, 152, 154, 426, 349, 252, 425,
+ /* 620 */ 143, 262, 575, 297, 591, 142, 169, 296, 171, 172,
+ /* 630 */ 169, 471, 171, 172, 21, 22, 427, 221, 91, 115,
+ /* 640 */ 227, 139, 127, 125, 156, 161, 157, 162, 166, 119,
+ /* 650 */ 123, 117, 121, 129, 131, 133, 135, 144, 146, 148,
+ /* 660 */ 150, 152, 154, 388, 312, 106, 89, 143, 720, 376,
+ /* 670 */ 387, 170, 142, 487, 666, 248, 320, 216, 319, 217,
+ /* 680 */ 28, 459, 30, 305, 189, 263, 209, 104, 139, 127,
+ /* 690 */ 125, 156, 161, 157, 162, 166, 119, 123, 117, 121,
+ /* 700 */ 129, 131, 133, 135, 144, 146, 148, 150, 152, 154,
+ /* 710 */ 106, 106, 809, 494, 143, 489, 106, 816, 33, 142,
+ /* 720 */ 395, 234, 273, 217, 274, 420, 20, 545, 114, 481,
+ /* 730 */ 137, 429, 576, 321, 116, 139, 127, 125, 156, 161,
+ /* 740 */ 157, 162, 166, 119, 123, 117, 121, 129, 131, 133,
+ /* 750 */ 135, 144, 146, 148, 150, 152, 154, 7, 322, 23,
+ /* 760 */ 25, 27, 394, 68, 415, 416, 10, 64, 197, 477,
+ /* 770 */ 577, 533, 266, 548, 578, 831, 276, 201, 520, 4,
+ /* 780 */ 6, 245, 430, 557, 29, 266, 491, 106, 441, 497,
+ /* 790 */ 21, 22, 205, 168, 443, 195, 193, 531, 276, 448,
+ /* 800 */ 276, 808, 267, 272, 529, 174, 175, 318, 440, 341,
+ /* 810 */ 344, 106, 342, 345, 69, 286, 68, 582, 69, 69,
+ /* 820 */ 64, 540, 181, 179, 541, 328, 302, 366, 217, 118,
+ /* 830 */ 177, 66, 67, 111, 34, 143, 112, 105, 445, 510,
+ /* 840 */ 142, 215, 278, 800, 467, 276, 498, 503, 444, 193,
+ /* 850 */ 106, 219, 486, 443, 42, 73, 231, 73, 45, 175,
+ /* 860 */ 449, 39, 225, 229, 278, 451, 278, 68, 174, 113,
+ /* 870 */ 183, 64, 371, 55, 106, 181, 179, 292, 69, 276,
+ /* 880 */ 276, 69, 48, 177, 66, 67, 111, 224, 276, 112,
+ /* 890 */ 105, 106, 481, 393, 106, 106, 63, 106, 106, 106,
+ /* 900 */ 193, 653, 106, 467, 233, 51, 380, 437, 526, 120,
+ /* 910 */ 175, 278, 122, 124, 219, 126, 128, 130, 69, 453,
+ /* 920 */ 132, 106, 113, 183, 451, 106, 181, 179, 159, 106,
+ /* 930 */ 106, 106, 518, 106, 177, 66, 67, 111, 106, 134,
+ /* 940 */ 112, 105, 422, 136, 106, 278, 278, 138, 141, 145,
+ /* 950 */ 720, 147, 106, 329, 275, 274, 149, 106, 852, 158,
+ /* 960 */ 106, 106, 151, 106, 106, 351, 106, 352, 106, 464,
+ /* 970 */ 153, 106, 106, 113, 183, 155, 106, 106, 163, 165,
+ /* 980 */ 106, 176, 178, 106, 180, 106, 182, 106, 401, 190,
+ /* 990 */ 192, 106, 106, 293, 210, 212, 106, 367, 214, 274,
+ /* 1000 */ 372, 226, 274, 228, 381, 241, 274, 106, 106, 246,
+ /* 1010 */ 280, 290, 106, 69, 375, 438, 472, 274, 422, 832,
+ /* 1020 */ 106, 73, 474, 73, 458, 412, 462, 480, 464, 478,
+ /* 1030 */ 466, 690, 515, 519, 475, 478, 516, 50, 479, 221,
+ /* 1040 */ 690, 221, 56, 57, 61, 592, 71, 69, 593, 73,
+ /* 1050 */ 72, 74, 245, 242, 93, 81, 76, 69, 77, 240,
+ /* 1060 */ 78, 82, 79, 245, 85, 554, 80, 88, 87, 90,
+ /* 1070 */ 92, 94, 96, 102, 100, 99, 101, 107, 109, 160,
+ /* 1080 */ 154, 667, 98, 508, 108, 668, 110, 220, 211, 669,
+ /* 1090 */ 137, 140, 188, 194, 186, 196, 187, 199, 198, 200,
+ /* 1100 */ 203, 204, 202, 207, 206, 208, 221, 223, 222, 235,
+ /* 1110 */ 236, 239, 238, 217, 250, 258, 243, 261, 279, 270,
+ /* 1120 */ 271, 255, 257, 260, 269, 265, 285, 294, 277, 268,
+ /* 1130 */ 287, 304, 309, 307, 327, 312, 288, 354, 389, 314,
+ /* 1140 */ 364, 365, 370, 378, 379, 382, 310, 49, 311, 362,
+ /* 1150 */ 368, 373, 317, 324, 326, 332, 350, 355, 383, 400,
+ /* 1160 */ 353, 397, 399, 403, 404, 334, 405, 406, 407, 384,
+ /* 1170 */ 413, 409, 824, 414, 360, 385, 829, 423, 410, 431,
+ /* 1180 */ 428, 432, 830, 433, 434, 436, 439, 798, 799, 447,
+ /* 1190 */ 442, 450, 727, 728, 446, 823, 452, 838, 455, 445,
+ /* 1200 */ 456, 457, 408, 435, 460, 461, 463, 840, 465, 468,
+ /* 1210 */ 470, 469, 476, 841, 483, 485, 843, 660, 662, 493,
+ /* 1220 */ 806, 496, 473, 849, 499, 719, 501, 484, 488, 490,
+ /* 1230 */ 492, 502, 504, 495, 500, 507, 505, 506, 509, 722,
+ /* 1240 */ 513, 511, 512, 514, 517, 725, 528, 522, 524, 525,
+ /* 1250 */ 527, 523, 807, 530, 810, 532, 811, 812, 813, 814,
+ /* 1260 */ 817, 819, 539, 820, 818, 815, 521, 543, 546, 552,
+ /* 1270 */ 556, 550, 850, 547, 549, 851, 555, 558, 551, 855,
+ /* 1280 */ 553, 559,
+};
+static YYCODETYPE yy_lookahead[] = {
+ /* 0 */ 21, 9, 23, 70, 71, 72, 73, 74, 75, 76,
+ /* 10 */ 77, 78, 79, 80, 81, 82, 83, 9, 140, 140,
+ /* 20 */ 41, 132, 133, 134, 135, 46, 74, 75, 76, 77,
+ /* 30 */ 78, 79, 80, 81, 82, 83, 158, 158, 138, 60,
+ /* 40 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ /* 50 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ /* 60 */ 81, 82, 83, 19, 90, 21, 87, 41, 94, 95,
+ /* 70 */ 96, 192, 46, 80, 81, 82, 83, 19, 174, 105,
+ /* 80 */ 19, 23, 204, 62, 23, 181, 60, 61, 62, 63,
+ /* 90 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ /* 100 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ /* 110 */ 52, 90, 91, 0, 93, 94, 95, 96, 97, 98,
+ /* 120 */ 62, 23, 9, 10, 9, 104, 20, 12, 22, 78,
+ /* 130 */ 79, 80, 81, 82, 83, 41, 78, 79, 80, 12,
+ /* 140 */ 46, 78, 79, 23, 86, 87, 88, 89, 87, 88,
+ /* 150 */ 92, 93, 89, 127, 60, 61, 62, 63, 64, 65,
+ /* 160 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ /* 170 */ 76, 77, 78, 79, 80, 81, 82, 83, 14, 9,
+ /* 180 */ 10, 62, 15, 125, 126, 87, 88, 140, 90, 134,
+ /* 190 */ 135, 24, 94, 95, 96, 23, 90, 9, 78, 79,
+ /* 200 */ 94, 95, 96, 105, 11, 41, 39, 87, 88, 42,
+ /* 210 */ 46, 105, 93, 94, 95, 96, 97, 98, 17, 99,
+ /* 220 */ 53, 139, 128, 104, 60, 61, 62, 63, 64, 65,
+ /* 230 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ /* 240 */ 76, 77, 78, 79, 80, 81, 82, 83, 9, 19,
+ /* 250 */ 78, 79, 41, 23, 207, 208, 209, 46, 57, 87,
+ /* 260 */ 59, 89, 140, 19, 92, 93, 144, 23, 152, 147,
+ /* 270 */ 148, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ /* 280 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 290 */ 79, 80, 81, 82, 83, 14, 52, 9, 182, 20,
+ /* 300 */ 20, 113, 140, 156, 20, 20, 62, 22, 161, 147,
+ /* 310 */ 148, 140, 20, 155, 156, 26, 200, 87, 88, 161,
+ /* 320 */ 127, 41, 78, 79, 93, 36, 46, 165, 166, 158,
+ /* 330 */ 86, 87, 88, 89, 53, 104, 92, 93, 9, 128,
+ /* 340 */ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ /* 350 */ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ /* 360 */ 80, 81, 82, 83, 20, 194, 140, 183, 184, 125,
+ /* 370 */ 126, 127, 146, 88, 19, 204, 23, 140, 23, 31,
+ /* 380 */ 140, 100, 101, 102, 158, 41, 107, 99, 109, 110,
+ /* 390 */ 46, 107, 111, 109, 110, 158, 20, 171, 158, 107,
+ /* 400 */ 115, 109, 110, 170, 60, 61, 62, 63, 64, 65,
+ /* 410 */ 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
+ /* 420 */ 76, 77, 78, 79, 80, 81, 82, 83, 191, 192,
+ /* 430 */ 47, 23, 41, 80, 194, 140, 107, 46, 109, 110,
+ /* 440 */ 87, 88, 87, 88, 204, 62, 100, 101, 102, 11,
+ /* 450 */ 140, 60, 61, 62, 63, 64, 65, 66, 67, 68,
+ /* 460 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
+ /* 470 */ 79, 80, 81, 82, 83, 140, 9, 23, 21, 41,
+ /* 480 */ 23, 9, 99, 107, 46, 109, 110, 104, 149, 9,
+ /* 490 */ 99, 152, 153, 158, 199, 87, 88, 146, 60, 61,
+ /* 500 */ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ /* 510 */ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81,
+ /* 520 */ 82, 83, 171, 115, 23, 22, 41, 20, 9, 22,
+ /* 530 */ 19, 46, 9, 47, 183, 184, 201, 100, 101, 102,
+ /* 540 */ 189, 87, 88, 19, 87, 60, 61, 62, 63, 64,
+ /* 550 */ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ /* 560 */ 75, 76, 77, 78, 79, 80, 81, 82, 83, 115,
+ /* 570 */ 23, 14, 140, 41, 107, 34, 109, 110, 46, 107,
+ /* 580 */ 138, 109, 110, 22, 43, 99, 138, 107, 87, 109,
+ /* 590 */ 110, 88, 60, 61, 62, 63, 64, 65, 66, 67,
+ /* 600 */ 68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
+ /* 610 */ 78, 79, 80, 81, 82, 83, 25, 19, 115, 28,
+ /* 620 */ 41, 23, 9, 108, 113, 46, 107, 112, 109, 110,
+ /* 630 */ 107, 199, 109, 110, 87, 88, 45, 113, 22, 60,
+ /* 640 */ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ /* 650 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
+ /* 660 */ 81, 82, 83, 161, 162, 140, 50, 41, 9, 139,
+ /* 670 */ 168, 108, 46, 17, 111, 114, 91, 20, 93, 22,
+ /* 680 */ 138, 22, 142, 158, 127, 87, 129, 61, 62, 63,
+ /* 690 */ 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+ /* 700 */ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ /* 710 */ 140, 140, 9, 57, 41, 59, 140, 9, 145, 46,
+ /* 720 */ 143, 20, 20, 22, 22, 49, 23, 19, 158, 158,
+ /* 730 */ 200, 18, 9, 29, 158, 62, 63, 64, 65, 66,
+ /* 740 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
+ /* 750 */ 77, 78, 79, 80, 81, 82, 83, 11, 54, 13,
+ /* 760 */ 14, 15, 16, 19, 55, 56, 99, 23, 15, 198,
+ /* 770 */ 9, 63, 152, 27, 9, 99, 140, 24, 32, 136,
+ /* 780 */ 137, 122, 205, 37, 141, 152, 130, 140, 211, 146,
+ /* 790 */ 87, 88, 39, 146, 146, 42, 52, 51, 140, 53,
+ /* 800 */ 140, 9, 182, 167, 58, 158, 62, 103, 95, 89,
+ /* 810 */ 89, 140, 92, 92, 171, 182, 19, 9, 171, 171,
+ /* 820 */ 23, 89, 78, 79, 92, 167, 20, 167, 22, 158,
+ /* 830 */ 86, 87, 88, 89, 20, 41, 92, 93, 60, 196,
+ /* 840 */ 46, 194, 206, 130, 196, 140, 100, 101, 102, 52,
+ /* 850 */ 140, 204, 106, 146, 140, 111, 146, 111, 139, 62,
+ /* 860 */ 212, 150, 68, 69, 206, 217, 206, 19, 158, 125,
+ /* 870 */ 126, 23, 167, 48, 140, 78, 79, 80, 171, 140,
+ /* 880 */ 140, 171, 139, 86, 87, 88, 89, 93, 140, 92,
+ /* 890 */ 93, 140, 158, 146, 140, 140, 19, 140, 140, 140,
+ /* 900 */ 52, 123, 140, 196, 194, 44, 167, 167, 116, 158,
+ /* 910 */ 62, 206, 158, 158, 204, 158, 158, 158, 171, 212,
+ /* 920 */ 158, 140, 125, 126, 217, 140, 78, 79, 62, 140,
+ /* 930 */ 140, 140, 198, 140, 86, 87, 88, 89, 140, 158,
+ /* 940 */ 92, 93, 22, 158, 140, 206, 206, 158, 158, 158,
+ /* 950 */ 9, 158, 140, 20, 206, 22, 158, 140, 9, 93,
+ /* 960 */ 140, 140, 158, 140, 140, 20, 140, 22, 140, 140,
+ /* 970 */ 158, 140, 140, 125, 126, 158, 140, 140, 158, 158,
+ /* 980 */ 140, 158, 158, 140, 158, 140, 158, 140, 146, 158,
+ /* 990 */ 158, 140, 140, 140, 158, 158, 140, 20, 158, 22,
+ /* 1000 */ 20, 158, 22, 158, 20, 158, 22, 140, 140, 158,
+ /* 1010 */ 158, 158, 140, 171, 158, 20, 20, 22, 22, 99,
+ /* 1020 */ 140, 111, 146, 111, 195, 158, 158, 20, 140, 22,
+ /* 1030 */ 158, 103, 146, 20, 124, 22, 124, 164, 158, 113,
+ /* 1040 */ 114, 113, 157, 139, 139, 113, 172, 171, 113, 111,
+ /* 1050 */ 171, 173, 122, 119, 117, 180, 175, 171, 176, 120,
+ /* 1060 */ 177, 121, 178, 122, 89, 116, 179, 154, 89, 154,
+ /* 1070 */ 154, 118, 22, 151, 98, 157, 23, 113, 113, 93,
+ /* 1080 */ 83, 111, 193, 195, 140, 111, 140, 140, 127, 111,
+ /* 1090 */ 200, 200, 14, 19, 202, 20, 203, 140, 22, 20,
+ /* 1100 */ 140, 20, 22, 140, 22, 20, 113, 186, 140, 140,
+ /* 1110 */ 186, 157, 193, 22, 185, 115, 118, 186, 99, 116,
+ /* 1120 */ 19, 140, 140, 140, 188, 140, 20, 113, 157, 187,
+ /* 1130 */ 187, 20, 140, 139, 19, 162, 188, 20, 166, 140,
+ /* 1140 */ 48, 19, 19, 48, 19, 97, 159, 104, 160, 140,
+ /* 1150 */ 139, 139, 163, 163, 163, 151, 154, 152, 140, 21,
+ /* 1160 */ 154, 140, 140, 140, 213, 164, 214, 99, 140, 159,
+ /* 1170 */ 40, 215, 11, 38, 166, 160, 99, 140, 216, 130,
+ /* 1180 */ 49, 140, 99, 99, 140, 19, 139, 9, 130, 169,
+ /* 1190 */ 11, 14, 123, 123, 170, 9, 9, 14, 169, 60,
+ /* 1200 */ 140, 103, 186, 186, 140, 63, 176, 9, 63, 123,
+ /* 1210 */ 19, 140, 19, 9, 114, 176, 9, 9, 9, 186,
+ /* 1220 */ 9, 186, 197, 9, 114, 9, 186, 140, 140, 140,
+ /* 1230 */ 140, 176, 169, 140, 140, 103, 140, 186, 176, 9,
+ /* 1240 */ 186, 123, 140, 197, 19, 9, 87, 140, 114, 140,
+ /* 1250 */ 35, 186, 9, 140, 9, 152, 9, 9, 9, 9,
+ /* 1260 */ 9, 9, 210, 9, 9, 9, 169, 210, 140, 140,
+ /* 1270 */ 33, 152, 9, 20, 218, 9, 152, 218, 21, 9,
+ /* 1280 */ 219, 140,
+};
+#define YY_SHIFT_USE_DFLT (-68)
+static short yy_shift_ofst[] = {
+ /* 0 */ 170, 113, -68, 746, -8, -68, 8, 127, 288, 239,
+ /* 10 */ 348, 167, -68, -68, -68, -68, -68, -68, 547, -68,
+ /* 20 */ -68, -68, -68, 115, 613, 115, 723, 115, 761, 44,
+ /* 30 */ 765, 547, 507, 814, 808, 98, -68, 501, -68, 21,
+ /* 40 */ -68, 547, 119, -68, 667, -68, 231, 667, -68, 861,
+ /* 50 */ -68, 541, -68, -68, 825, 289, 667, -68, -68, -68,
+ /* 60 */ 667, -68, 877, 848, 511, 58, 932, 935, 744, -68,
+ /* 70 */ 279, 938, -68, 515, -68, 561, 930, 934, 939, 937,
+ /* 80 */ 940, -68, 63, -68, 975, -68, 979, -68, 616, 63,
+ /* 90 */ -68, 63, -68, 953, 848, 1050, 848, 976, 289, -68,
+ /* 100 */ 1053, -68, -68, 485, 848, -68, 964, 547, 965, 547,
+ /* 110 */ -68, -68, -68, -68, 673, 848, 626, 848, -48, 848,
+ /* 120 */ -48, 848, -48, 848, -48, 848, -67, 848, -67, 848,
+ /* 130 */ 51, 848, 51, 848, 51, 848, 51, 848, -67, 794,
+ /* 140 */ 848, -67, -68, -68, 848, -7, 848, -7, 848, 997,
+ /* 150 */ 848, 997, 848, 997, 848, -68, -68, 866, -68, 986,
+ /* 160 */ -68, -68, 848, 532, 848, -67, 61, 744, 284, 563,
+ /* 170 */ 970, 974, 978, -68, 485, 848, 673, 848, -68, 848,
+ /* 180 */ -68, 848, -68, 244, 26, 961, 557, 1078, -68, 848,
+ /* 190 */ 94, 848, 485, 1074, 753, 1075, -68, 1076, 547, 1079,
+ /* 200 */ -68, 1080, 547, 1081, -68, 1082, 547, 1085, -68, 848,
+ /* 210 */ 164, 848, 211, 848, 485, 657, -68, 848, -68, -68,
+ /* 220 */ 993, 547, -68, -68, -68, 848, 579, 848, 673, 230,
+ /* 230 */ 744, 292, -68, 701, -68, 993, -68, 976, 289, -68,
+ /* 240 */ 848, 485, 998, 848, 1091, 848, 485, -68, -68, 503,
+ /* 250 */ -68, -68, -68, 408, -68, 454, -68, 1000, -68, 355,
+ /* 260 */ 993, 457, -68, -68, 547, -68, -68, 1019, 1003, -68,
+ /* 270 */ 1101, 547, 702, -68, 547, -68, 289, -68, -68, 848,
+ /* 280 */ 485, 938, 376, 285, 1106, 457, 1019, 1003, -68, 797,
+ /* 290 */ -21, -68, -68, 1014, 353, -68, -68, -68, -68, 280,
+ /* 300 */ -68, 806, -68, 1111, -68, 344, 667, -68, 547, 1115,
+ /* 310 */ -68, 486, -68, 547, -68, 346, 704, -68, 585, -68,
+ /* 320 */ -68, -68, -68, 704, -68, 704, -68, 547, 933, -68,
+ /* 330 */ -68, 1053, -68, 861, -68, -68, 172, -68, -68, -68,
+ /* 340 */ 720, -68, -68, 721, -68, -68, -68, -68, 598, 63,
+ /* 350 */ 945, -68, 63, 1117, -68, -68, -68, -68, 106, -26,
+ /* 360 */ -68, 547, -68, 1092, 1122, 547, 977, 667, -68, 1123,
+ /* 370 */ 547, 980, 667, -68, 848, 391, -68, 1095, 1125, 547,
+ /* 380 */ 984, 1048, 547, 1115, -68, 383, 1043, -68, -68, -68,
+ /* 390 */ -68, -68, 938, 329, 713, 201, 547, -68, 547, 1138,
+ /* 400 */ 938, 467, 547, 591, 437, 1068, 547, 993, 1130, 193,
+ /* 410 */ 1161, 848, 438, 1135, 709, -68, -68, 1077, 1083, 676,
+ /* 420 */ 547, 920, 547, -68, -68, -68, -68, 1131, -68, -68,
+ /* 430 */ 1049, 547, 1084, 547, 524, 1166, 547, 995, 288, 1178,
+ /* 440 */ 1058, 1179, 281, 472, 778, 167, -68, 1069, 1070, 1177,
+ /* 450 */ 1186, 1187, 281, 1183, 1139, 547, 1098, 547, 659, 547,
+ /* 460 */ 1142, 848, 485, 1198, 1145, 848, 485, 1086, 547, 1191,
+ /* 470 */ 547, 996, -68, 910, 480, 1193, 848, 1007, 848, 485,
+ /* 480 */ 1204, 485, 1100, 547, 941, 1207, 656, 547, 1208, 547,
+ /* 490 */ 1209, 547, 188, 1211, 547, 188, 1214, 519, 1110, 547,
+ /* 500 */ 993, 941, 1216, 1139, 547, 928, 1132, 547, 659, 1230,
+ /* 510 */ 1118, 547, 993, 1191, 912, 523, 1225, 848, 1013, 1236,
+ /* 520 */ 1139, 547, 926, 1134, 547, 792, 1215, 1159, 1243, 703,
+ /* 530 */ 1245, 501, 708, 120, 1247, 1248, 1249, 1250, 732, 1251,
+ /* 540 */ 1252, 1254, 732, 1255, -68, 547, 1253, 1256, 1237, 501,
+ /* 550 */ 1257, 547, 949, 1263, 501, 1266, -68, 1237, 547, 1270,
+ /* 560 */ -68, -68, -68,
+};
+#define YY_REDUCE_USE_DFLT (-123)
+static short yy_reduce_ofst[] = {
+ /* 0 */ -111, 55, -123, 643, -123, -123, -123, -100, 82, -123,
+ /* 10 */ -123, 233, -123, -123, -123, -123, -123, -123, 310, -123,
+ /* 20 */ -123, -123, -123, 442, -123, 448, -123, 542, -123, 540,
+ /* 30 */ -123, 122, 573, -123, -123, 162, -123, 339, 711, 158,
+ /* 40 */ -123, 714, 147, -123, 719, -123, -123, 743, -123, 873,
+ /* 50 */ -123, -123, -123, -123, -123, 885, 904, -123, -123, -123,
+ /* 60 */ 905, -123, -123, 525, -123, 171, -123, -123, 226, -123,
+ /* 70 */ 874, 879, -123, 878, -96, 881, 882, 883, 884, 887,
+ /* 80 */ 875, -123, 913, -123, -123, -123, -123, -123, -123, 915,
+ /* 90 */ -123, 916, -123, -123, 237, -123, -121, 889, 918, -123,
+ /* 100 */ 922, -123, -123, 890, 570, -123, -123, 944, -123, 946,
+ /* 110 */ -123, -123, -123, -123, 890, 576, 890, 671, 890, 751,
+ /* 120 */ 890, 754, 890, 755, 890, 757, 890, 758, 890, 759,
+ /* 130 */ 890, 762, 890, 781, 890, 785, 890, 789, 890, 891,
+ /* 140 */ 790, 890, -123, -123, 791, 890, 793, 890, 798, 890,
+ /* 150 */ 804, 890, 812, 890, 817, 890, -123, -123, -123, -123,
+ /* 160 */ -123, -123, 820, 890, 821, 890, 947, 647, 874, -123,
+ /* 170 */ -123, -123, -123, -123, 890, 823, 890, 824, 890, 826,
+ /* 180 */ 890, 828, 890, 335, 890, 892, 893, -123, -123, 831,
+ /* 190 */ 890, 832, 890, -123, -123, -123, -123, -123, 957, -123,
+ /* 200 */ -123, -123, 960, -123, -123, -123, 963, -123, -123, 836,
+ /* 210 */ 890, 837, 890, 840, 890, -123, -123, -122, -123, -123,
+ /* 220 */ 921, 968, -123, -123, -123, 843, 890, 845, 890, 969,
+ /* 230 */ 710, 874, -123, -123, -123, 924, -123, 919, 954, -123,
+ /* 240 */ 847, 890, -123, 240, -123, 851, 890, -123, 184, 929,
+ /* 250 */ -123, -123, -123, 981, -123, 982, -123, -123, -123, 983,
+ /* 260 */ 931, 620, -123, -123, 985, -123, -123, 942, 936, -123,
+ /* 270 */ -123, 636, -123, -123, 748, -123, 971, -123, -123, 852,
+ /* 280 */ 890, 351, 874, 929, -123, 633, 943, 948, -123, 853,
+ /* 290 */ 116, -123, -123, -123, 944, -123, -123, -123, -123, 890,
+ /* 300 */ -123, -123, -123, -123, -123, 890, 994, -123, 992, 987,
+ /* 310 */ 988, 973, -123, 999, -123, -123, 989, -123, -123, -123,
+ /* 320 */ -123, -123, -123, 990, -123, 991, -123, 658, -123, -123,
+ /* 330 */ -123, 1004, -123, 1001, -123, -123, -123, -123, -123, -123,
+ /* 340 */ -123, -123, -123, -123, -123, -123, -123, -123, 1005, 1002,
+ /* 350 */ -123, -123, 1006, -123, -123, -123, -123, -123, 972, 1008,
+ /* 360 */ -123, 1009, -123, -123, -123, 660, -123, 1011, -123, -123,
+ /* 370 */ 705, -123, 1012, -123, 856, 530, -123, -123, -123, 739,
+ /* 380 */ -123, -123, 1018, 1010, 1015, 502, -123, -123, -123, -123,
+ /* 390 */ -123, -123, 747, 874, 577, -123, 1021, -123, 1022, -123,
+ /* 400 */ 842, 874, 1023, 951, 952, -123, 1028, 1016, 956, 962,
+ /* 410 */ -123, 867, 890, -123, -123, -123, -123, -123, -123, -123,
+ /* 420 */ 295, -123, 1037, -123, -123, -123, -123, -123, -123, -123,
+ /* 430 */ -123, 1041, -123, 1044, 1017, -123, 740, -123, 1047, -123,
+ /* 440 */ -123, -123, 648, 874, 1020, 1024, -123, -123, -123, -123,
+ /* 450 */ -123, -123, 707, -123, 1029, 1060, -123, 829, 1030, 1064,
+ /* 460 */ -123, 868, 890, -123, -123, 872, 890, -123, 1071, 1025,
+ /* 470 */ 432, -123, -123, 876, 874, -123, 571, -123, 880, 890,
+ /* 480 */ -123, 890, -123, 1087, 1039, -123, -123, 1088, -123, 1089,
+ /* 490 */ -123, 1090, 1033, -123, 1093, 1035, -123, 874, -123, 1094,
+ /* 500 */ 1040, 1055, -123, 1063, 1096, 1051, -123, 888, 1062, -123,
+ /* 510 */ -123, 1102, 1054, 1046, 886, 874, -123, 734, -123, -123,
+ /* 520 */ 1097, 1107, 1065, -123, 1109, -123, -123, -123, -123, 1113,
+ /* 530 */ -123, 1103, -123, 47, -123, -123, -123, -123, 1052, -123,
+ /* 540 */ -123, -123, 1057, -123, -123, 1128, -123, -123, 1056, 1119,
+ /* 550 */ -123, 1129, 1061, -123, 1124, -123, -123, 1059, 1141, -123,
+ /* 560 */ -123, -123, -123,
+};
+static YYACTIONTYPE yy_default[] = {
+ /* 0 */ 570, 570, 564, 856, 856, 566, 856, 572, 856, 856,
+ /* 10 */ 856, 856, 652, 655, 656, 657, 658, 659, 573, 574,
+ /* 20 */ 591, 592, 593, 856, 856, 856, 856, 856, 856, 856,
+ /* 30 */ 856, 856, 856, 856, 856, 856, 584, 594, 604, 586,
+ /* 40 */ 603, 856, 856, 605, 651, 616, 856, 651, 617, 636,
+ /* 50 */ 634, 856, 637, 638, 856, 708, 651, 618, 706, 707,
+ /* 60 */ 651, 619, 856, 856, 737, 797, 743, 738, 856, 664,
+ /* 70 */ 856, 856, 665, 673, 675, 682, 720, 711, 713, 701,
+ /* 80 */ 715, 670, 856, 600, 856, 601, 856, 602, 716, 856,
+ /* 90 */ 717, 856, 718, 856, 856, 702, 856, 709, 708, 703,
+ /* 100 */ 856, 588, 710, 705, 856, 736, 856, 856, 739, 856,
+ /* 110 */ 740, 741, 742, 744, 747, 856, 748, 856, 749, 856,
+ /* 120 */ 750, 856, 751, 856, 752, 856, 753, 856, 754, 856,
+ /* 130 */ 755, 856, 756, 856, 757, 856, 758, 856, 759, 856,
+ /* 140 */ 856, 760, 761, 762, 856, 763, 856, 764, 856, 765,
+ /* 150 */ 856, 766, 856, 767, 856, 768, 769, 856, 770, 856,
+ /* 160 */ 773, 771, 856, 856, 856, 779, 856, 797, 856, 856,
+ /* 170 */ 856, 856, 856, 782, 796, 856, 774, 856, 775, 856,
+ /* 180 */ 776, 856, 777, 856, 856, 856, 856, 856, 787, 856,
+ /* 190 */ 856, 856, 788, 856, 856, 856, 845, 856, 856, 856,
+ /* 200 */ 846, 856, 856, 856, 847, 856, 856, 856, 848, 856,
+ /* 210 */ 856, 856, 856, 856, 789, 856, 781, 797, 794, 795,
+ /* 220 */ 690, 856, 691, 785, 772, 856, 856, 856, 780, 856,
+ /* 230 */ 797, 856, 784, 856, 783, 690, 786, 709, 708, 704,
+ /* 240 */ 856, 714, 856, 797, 712, 856, 721, 674, 685, 683,
+ /* 250 */ 684, 692, 693, 856, 694, 856, 695, 856, 696, 856,
+ /* 260 */ 690, 681, 589, 590, 856, 679, 680, 698, 700, 686,
+ /* 270 */ 856, 856, 856, 699, 856, 803, 708, 805, 804, 856,
+ /* 280 */ 697, 685, 856, 856, 856, 681, 698, 700, 687, 856,
+ /* 290 */ 681, 676, 677, 856, 856, 678, 671, 672, 778, 856,
+ /* 300 */ 735, 856, 745, 856, 746, 856, 651, 620, 856, 801,
+ /* 310 */ 624, 621, 625, 856, 626, 856, 856, 627, 856, 630,
+ /* 320 */ 631, 632, 633, 856, 628, 856, 629, 856, 856, 802,
+ /* 330 */ 622, 856, 623, 636, 635, 606, 856, 607, 608, 609,
+ /* 340 */ 856, 610, 613, 856, 611, 614, 612, 615, 595, 856,
+ /* 350 */ 856, 596, 856, 856, 597, 599, 598, 587, 856, 856,
+ /* 360 */ 641, 856, 644, 856, 856, 856, 856, 651, 645, 856,
+ /* 370 */ 856, 856, 651, 646, 856, 651, 647, 856, 856, 856,
+ /* 380 */ 856, 856, 856, 801, 624, 649, 856, 648, 650, 642,
+ /* 390 */ 643, 585, 856, 856, 581, 856, 856, 579, 856, 856,
+ /* 400 */ 856, 856, 856, 828, 856, 856, 856, 690, 833, 856,
+ /* 410 */ 856, 856, 856, 856, 856, 834, 835, 856, 856, 856,
+ /* 420 */ 856, 856, 856, 733, 734, 825, 826, 856, 827, 580,
+ /* 430 */ 856, 856, 856, 856, 856, 856, 856, 856, 856, 856,
+ /* 440 */ 856, 856, 856, 856, 856, 856, 654, 856, 856, 856,
+ /* 450 */ 856, 856, 856, 856, 653, 856, 856, 856, 856, 856,
+ /* 460 */ 856, 856, 723, 856, 856, 856, 724, 856, 856, 731,
+ /* 470 */ 856, 856, 732, 856, 856, 856, 856, 856, 856, 729,
+ /* 480 */ 856, 730, 856, 856, 856, 856, 856, 856, 856, 856,
+ /* 490 */ 856, 856, 856, 856, 856, 856, 856, 856, 856, 856,
+ /* 500 */ 690, 856, 856, 653, 856, 856, 856, 856, 856, 856,
+ /* 510 */ 856, 856, 690, 731, 856, 856, 856, 856, 856, 856,
+ /* 520 */ 653, 856, 856, 856, 856, 856, 856, 856, 856, 856,
+ /* 530 */ 856, 856, 856, 822, 856, 856, 856, 856, 856, 856,
+ /* 540 */ 856, 856, 856, 856, 821, 856, 856, 856, 854, 856,
+ /* 550 */ 856, 856, 856, 856, 856, 856, 853, 854, 856, 856,
+ /* 560 */ 567, 569, 565,
+};
+#define YY_SZ_ACTTAB (sizeof(yy_action)/sizeof(yy_action[0]))
+
+/* The next table maps tokens into fallback tokens. If a construct
+** like the following:
+**
+** %fallback ID X Y Z.
+**
+** appears in the grammer, then ID becomes a fallback token for X, Y,
+** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
+** but it does not parse, the type of the token is changed to ID and
+** the parse is retried before an error is thrown.
+*/
+#ifdef YYFALLBACK
+static const YYCODETYPE yyFallback[] = {
+ 0, /* $ => nothing */
+ 0, /* END_OF_FILE => nothing */
+ 0, /* ILLEGAL => nothing */
+ 0, /* SPACE => nothing */
+ 0, /* UNCLOSED_STRING => nothing */
+ 0, /* COMMENT => nothing */
+ 0, /* FUNCTION => nothing */
+ 0, /* COLUMN => nothing */
+ 0, /* AGG_FUNCTION => nothing */
+ 0, /* SEMI => nothing */
+ 23, /* EXPLAIN => ID */
+ 23, /* BEGIN => ID */
+ 0, /* TRANSACTION => nothing */
+ 0, /* COMMIT => nothing */
+ 23, /* END => ID */
+ 0, /* ROLLBACK => nothing */
+ 0, /* CREATE => nothing */
+ 0, /* TABLE => nothing */
+ 23, /* TEMP => ID */
+ 0, /* LP => nothing */
+ 0, /* RP => nothing */
+ 0, /* AS => nothing */
+ 0, /* COMMA => nothing */
+ 0, /* ID => nothing */
+ 23, /* ABORT => ID */
+ 23, /* AFTER => ID */
+ 23, /* ASC => ID */
+ 23, /* ATTACH => ID */
+ 23, /* BEFORE => ID */
+ 23, /* CASCADE => ID */
+ 23, /* CLUSTER => ID */
+ 23, /* CONFLICT => ID */
+ 23, /* COPY => ID */
+ 23, /* DATABASE => ID */
+ 23, /* DEFERRED => ID */
+ 23, /* DELIMITERS => ID */
+ 23, /* DESC => ID */
+ 23, /* DETACH => ID */
+ 23, /* EACH => ID */
+ 23, /* FAIL => ID */
+ 23, /* FOR => ID */
+ 23, /* GLOB => ID */
+ 23, /* IGNORE => ID */
+ 23, /* IMMEDIATE => ID */
+ 23, /* INITIALLY => ID */
+ 23, /* INSTEAD => ID */
+ 23, /* LIKE => ID */
+ 23, /* MATCH => ID */
+ 23, /* KEY => ID */
+ 23, /* OF => ID */
+ 23, /* OFFSET => ID */
+ 23, /* PRAGMA => ID */
+ 23, /* RAISE => ID */
+ 23, /* REPLACE => ID */
+ 23, /* RESTRICT => ID */
+ 23, /* ROW => ID */
+ 23, /* STATEMENT => ID */
+ 23, /* TRIGGER => ID */
+ 23, /* VACUUM => ID */
+ 23, /* VIEW => ID */
+ 0, /* OR => nothing */
+ 0, /* AND => nothing */
+ 0, /* NOT => nothing */
+ 0, /* EQ => nothing */
+ 0, /* NE => nothing */
+ 0, /* ISNULL => nothing */
+ 0, /* NOTNULL => nothing */
+ 0, /* IS => nothing */
+ 0, /* BETWEEN => nothing */
+ 0, /* IN => nothing */
+ 0, /* GT => nothing */
+ 0, /* GE => nothing */
+ 0, /* LT => nothing */
+ 0, /* LE => nothing */
+ 0, /* BITAND => nothing */
+ 0, /* BITOR => nothing */
+ 0, /* LSHIFT => nothing */
+ 0, /* RSHIFT => nothing */
+ 0, /* PLUS => nothing */
+ 0, /* MINUS => nothing */
+ 0, /* STAR => nothing */
+ 0, /* SLASH => nothing */
+ 0, /* REM => nothing */
+ 0, /* CONCAT => nothing */
+ 0, /* UMINUS => nothing */
+ 0, /* UPLUS => nothing */
+ 0, /* BITNOT => nothing */
+ 0, /* STRING => nothing */
+ 0, /* JOIN_KW => nothing */
+ 0, /* INTEGER => nothing */
+ 0, /* CONSTRAINT => nothing */
+ 0, /* DEFAULT => nothing */
+ 0, /* FLOAT => nothing */
+ 0, /* NULL => nothing */
+ 0, /* PRIMARY => nothing */
+ 0, /* UNITQUE => nothing */
+ 0, /* CHECK => nothing */
+ 0, /* REFERENCES => nothing */
+ 0, /* COLLATE => nothing */
+ 0, /* ON => nothing */
+ 0, /* DELETE => nothing */
+ 0, /* UPDATE => nothing */
+ 0, /* INSERT => nothing */
+ 0, /* SET => nothing */
+ 0, /* DEFERRABLE => nothing */
+ 0, /* FOREIGN => nothing */
+ 0, /* DROP => nothing */
+ 0, /* UNION => nothing */
+ 0, /* ALL => nothing */
+ 0, /* INTERSECT => nothing */
+ 0, /* EXCEPT => nothing */
+ 0, /* SELECT => nothing */
+ 0, /* DISTINCT => nothing */
+ 0, /* DOT => nothing */
+ 0, /* FROM => nothing */
+ 0, /* JOIN => nothing */
+ 0, /* USING => nothing */
+ 0, /* ORDER => nothing */
+ 0, /* BY => nothing */
+ 0, /* GROUP => nothing */
+ 0, /* HAVING => nothing */
+ 0, /* LIMIT => nothing */
+ 0, /* WHERE => nothing */
+ 0, /* INTO => nothing */
+ 0, /* VALUES => nothing */
+ 0, /* VARIABLE => nothing */
+ 0, /* CASE => nothing */
+ 0, /* WHEN => nothing */
+ 0, /* THEN => nothing */
+ 0, /* ELSE => nothing */
+ 0, /* INDEX => nothing */
+};
+#endif /* YYFALLBACK */
+
+/* The following structure represents a single element of the
+** parser's stack. Information stored includes:
+**
+** + The state number for the parser at this level of the stack.
+**
+** + The value of the token stored at this level of the stack.
+** (In other words, the "major" token.)
+**
+** + The semantic value stored at this level of the stack. This is
+** the information used by the action routines in the grammar.
+** It is sometimes called the "minor" token.
+*/
+struct yyStackEntry {
+ int stateno; /* The state-number */
+ int major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ YYMINORTYPE minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+};
+typedef struct yyStackEntry yyStackEntry;
+
+/* The state of the parser is completely contained in an instance of
+** the following structure */
+struct yyParser {
+ int yyidx; /* Index of top element in stack */
+ int yyerrcnt; /* Shifts left before out of the error */
+ sqliteParserARG_SDECL /* A place to hold %extra_argument */
+ yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
+};
+typedef struct yyParser yyParser;
+
+#ifndef NDEBUG
+#include <stdio.h>
+static FILE *yyTraceFILE = 0;
+static char *yyTracePrompt = 0;
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/*
+** Turn parser tracing on by giving a stream to which to write the trace
+** and a prompt to preface each trace message. Tracing is turned off
+** by making either argument NULL
+**
+** Inputs:
+** <ul>
+** <li> A FILE* to which trace output should be written.
+** If NULL, then tracing is turned off.
+** <li> A prefix string written at the beginning of every
+** line of trace output. If NULL, then tracing is
+** turned off.
+** </ul>
+**
+** Outputs:
+** None.
+*/
+void sqliteParserTrace(FILE *TraceFILE, char *zTracePrompt){
+ yyTraceFILE = TraceFILE;
+ yyTracePrompt = zTracePrompt;
+ if( yyTraceFILE==0 ) yyTracePrompt = 0;
+ else if( yyTracePrompt==0 ) yyTraceFILE = 0;
+}
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/* For tracing shifts, the names of all terminals and nonterminals
+** are required. The following table supplies these names */
+static const char *yyTokenName[] = {
+ "$", "END_OF_FILE", "ILLEGAL", "SPACE",
+ "UNCLOSED_STRING", "COMMENT", "FUNCTION", "COLUMN",
+ "AGG_FUNCTION", "SEMI", "EXPLAIN", "BEGIN",
+ "TRANSACTION", "COMMIT", "END", "ROLLBACK",
+ "CREATE", "TABLE", "TEMP", "LP",
+ "RP", "AS", "COMMA", "ID",
+ "ABORT", "AFTER", "ASC", "ATTACH",
+ "BEFORE", "CASCADE", "CLUSTER", "CONFLICT",
+ "COPY", "DATABASE", "DEFERRED", "DELIMITERS",
+ "DESC", "DETACH", "EACH", "FAIL",
+ "FOR", "GLOB", "IGNORE", "IMMEDIATE",
+ "INITIALLY", "INSTEAD", "LIKE", "MATCH",
+ "KEY", "OF", "OFFSET", "PRAGMA",
+ "RAISE", "REPLACE", "RESTRICT", "ROW",
+ "STATEMENT", "TRIGGER", "VACUUM", "VIEW",
+ "OR", "AND", "NOT", "EQ",
+ "NE", "ISNULL", "NOTNULL", "IS",
+ "BETWEEN", "IN", "GT", "GE",
+ "LT", "LE", "BITAND", "BITOR",
+ "LSHIFT", "RSHIFT", "PLUS", "MINUS",
+ "STAR", "SLASH", "REM", "CONCAT",
+ "UMINUS", "UPLUS", "BITNOT", "STRING",
+ "JOIN_KW", "INTEGER", "CONSTRAINT", "DEFAULT",
+ "FLOAT", "NULL", "PRIMARY", "UNITQUE",
+ "CHECK", "REFERENCES", "COLLATE", "ON",
+ "DELETE", "UPDATE", "INSERT", "SET",
+ "DEFERRABLE", "FOREIGN", "DROP", "UNION",
+ "ALL", "INTERSECT", "EXCEPT", "SELECT",
+ "DISTINCT", "DOT", "FROM", "JOIN",
+ "USING", "ORDER", "BY", "GROUP",
+ "HAVING", "LIMIT", "WHERE", "INTO",
+ "VALUES", "VARIABLE", "CASE", "WHEN",
+ "THEN", "ELSE", "INDEX", "error",
+ "input", "cmdlist", "ecmd", "explain",
+ "cmdx", "cmd", "trans_opt", "onconf",
+ "nm", "create_table", "create_table_args", "temp",
+ "columnlist", "conslist_opt", "select", "column",
+ "columnid", "type", "carglist", "id",
+ "ids", "typename", "signed", "carg",
+ "ccons", "sortorder", "expr", "idxlist_opt",
+ "refargs", "defer_subclause", "refarg", "refact",
+ "init_deferred_pred_opt", "conslist", "tcons", "idxlist",
+ "defer_subclause_opt", "orconf", "resolvetype", "oneselect",
+ "multiselect_op", "distinct", "selcollist", "from",
+ "where_opt", "groupby_opt", "having_opt", "orderby_opt",
+ "limit_opt", "sclp", "as", "seltablist",
+ "stl_prefix", "joinop", "dbnm", "on_opt",
+ "using_opt", "seltablist_paren", "joinop2", "sortlist",
+ "sortitem", "collate", "exprlist", "setlist",
+ "insert_cmd", "inscollist_opt", "itemlist", "inscollist",
+ "likeop", "case_operand", "case_exprlist", "case_else",
+ "expritem", "uniqueflag", "idxitem", "plus_num",
+ "minus_num", "plus_opt", "number", "trigger_decl",
+ "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause",
+ "when_clause", "trigger_cmd", "database_kw_opt", "key_opt",
+};
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/* For tracing reduce actions, the names of all rules are required.
+*/
+static const char *yyRuleName[] = {
+ /* 0 */ "input ::= cmdlist",
+ /* 1 */ "cmdlist ::= cmdlist ecmd",
+ /* 2 */ "cmdlist ::= ecmd",
+ /* 3 */ "ecmd ::= explain cmdx SEMI",
+ /* 4 */ "ecmd ::= SEMI",
+ /* 5 */ "cmdx ::= cmd",
+ /* 6 */ "explain ::= EXPLAIN",
+ /* 7 */ "explain ::=",
+ /* 8 */ "cmd ::= BEGIN trans_opt onconf",
+ /* 9 */ "trans_opt ::=",
+ /* 10 */ "trans_opt ::= TRANSACTION",
+ /* 11 */ "trans_opt ::= TRANSACTION nm",
+ /* 12 */ "cmd ::= COMMIT trans_opt",
+ /* 13 */ "cmd ::= END trans_opt",
+ /* 14 */ "cmd ::= ROLLBACK trans_opt",
+ /* 15 */ "cmd ::= create_table create_table_args",
+ /* 16 */ "create_table ::= CREATE temp TABLE nm",
+ /* 17 */ "temp ::= TEMP",
+ /* 18 */ "temp ::=",
+ /* 19 */ "create_table_args ::= LP columnlist conslist_opt RP",
+ /* 20 */ "create_table_args ::= AS select",
+ /* 21 */ "columnlist ::= columnlist COMMA column",
+ /* 22 */ "columnlist ::= column",
+ /* 23 */ "column ::= columnid type carglist",
+ /* 24 */ "columnid ::= nm",
+ /* 25 */ "id ::= ID",
+ /* 26 */ "ids ::= ID",
+ /* 27 */ "ids ::= STRING",
+ /* 28 */ "nm ::= ID",
+ /* 29 */ "nm ::= STRING",
+ /* 30 */ "nm ::= JOIN_KW",
+ /* 31 */ "type ::=",
+ /* 32 */ "type ::= typename",
+ /* 33 */ "type ::= typename LP signed RP",
+ /* 34 */ "type ::= typename LP signed COMMA signed RP",
+ /* 35 */ "typename ::= ids",
+ /* 36 */ "typename ::= typename ids",
+ /* 37 */ "signed ::= INTEGER",
+ /* 38 */ "signed ::= PLUS INTEGER",
+ /* 39 */ "signed ::= MINUS INTEGER",
+ /* 40 */ "carglist ::= carglist carg",
+ /* 41 */ "carglist ::=",
+ /* 42 */ "carg ::= CONSTRAINT nm ccons",
+ /* 43 */ "carg ::= ccons",
+ /* 44 */ "carg ::= DEFAULT STRING",
+ /* 45 */ "carg ::= DEFAULT ID",
+ /* 46 */ "carg ::= DEFAULT INTEGER",
+ /* 47 */ "carg ::= DEFAULT PLUS INTEGER",
+ /* 48 */ "carg ::= DEFAULT MINUS INTEGER",
+ /* 49 */ "carg ::= DEFAULT FLOAT",
+ /* 50 */ "carg ::= DEFAULT PLUS FLOAT",
+ /* 51 */ "carg ::= DEFAULT MINUS FLOAT",
+ /* 52 */ "carg ::= DEFAULT NULL",
+ /* 53 */ "ccons ::= NULL onconf",
+ /* 54 */ "ccons ::= NOT NULL onconf",
+ /* 55 */ "ccons ::= PRIMARY KEY sortorder onconf",
+ /* 56 */ "ccons ::= UNITQUE onconf",
+ /* 57 */ "ccons ::= CHECK LP expr RP onconf",
+ /* 58 */ "ccons ::= REFERENCES nm idxlist_opt refargs",
+ /* 59 */ "ccons ::= defer_subclause",
+ /* 60 */ "ccons ::= COLLATE id",
+ /* 61 */ "refargs ::=",
+ /* 62 */ "refargs ::= refargs refarg",
+ /* 63 */ "refarg ::= MATCH nm",
+ /* 64 */ "refarg ::= ON DELETE refact",
+ /* 65 */ "refarg ::= ON UPDATE refact",
+ /* 66 */ "refarg ::= ON INSERT refact",
+ /* 67 */ "refact ::= SET NULL",
+ /* 68 */ "refact ::= SET DEFAULT",
+ /* 69 */ "refact ::= CASCADE",
+ /* 70 */ "refact ::= RESTRICT",
+ /* 71 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt",
+ /* 72 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt",
+ /* 73 */ "init_deferred_pred_opt ::=",
+ /* 74 */ "init_deferred_pred_opt ::= INITIALLY DEFERRED",
+ /* 75 */ "init_deferred_pred_opt ::= INITIALLY IMMEDIATE",
+ /* 76 */ "conslist_opt ::=",
+ /* 77 */ "conslist_opt ::= COMMA conslist",
+ /* 78 */ "conslist ::= conslist COMMA tcons",
+ /* 79 */ "conslist ::= conslist tcons",
+ /* 80 */ "conslist ::= tcons",
+ /* 81 */ "tcons ::= CONSTRAINT nm",
+ /* 82 */ "tcons ::= PRIMARY KEY LP idxlist RP onconf",
+ /* 83 */ "tcons ::= UNITQUE LP idxlist RP onconf",
+ /* 84 */ "tcons ::= CHECK expr onconf",
+ /* 85 */ "tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt",
+ /* 86 */ "defer_subclause_opt ::=",
+ /* 87 */ "defer_subclause_opt ::= defer_subclause",
+ /* 88 */ "onconf ::=",
+ /* 89 */ "onconf ::= ON CONFLICT resolvetype",
+ /* 90 */ "orconf ::=",
+ /* 91 */ "orconf ::= OR resolvetype",
+ /* 92 */ "resolvetype ::= ROLLBACK",
+ /* 93 */ "resolvetype ::= ABORT",
+ /* 94 */ "resolvetype ::= FAIL",
+ /* 95 */ "resolvetype ::= IGNORE",
+ /* 96 */ "resolvetype ::= REPLACE",
+ /* 97 */ "cmd ::= DROP TABLE nm",
+ /* 98 */ "cmd ::= CREATE temp VIEW nm AS select",
+ /* 99 */ "cmd ::= DROP VIEW nm",
+ /* 100 */ "cmd ::= select",
+ /* 101 */ "select ::= oneselect",
+ /* 102 */ "select ::= select multiselect_op oneselect",
+ /* 103 */ "multiselect_op ::= UNION",
+ /* 104 */ "multiselect_op ::= UNION ALL",
+ /* 105 */ "multiselect_op ::= INTERSECT",
+ /* 106 */ "multiselect_op ::= EXCEPT",
+ /* 107 */ "oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt",
+ /* 108 */ "distinct ::= DISTINCT",
+ /* 109 */ "distinct ::= ALL",
+ /* 110 */ "distinct ::=",
+ /* 111 */ "sclp ::= selcollist COMMA",
+ /* 112 */ "sclp ::=",
+ /* 113 */ "selcollist ::= sclp expr as",
+ /* 114 */ "selcollist ::= sclp STAR",
+ /* 115 */ "selcollist ::= sclp nm DOT STAR",
+ /* 116 */ "as ::= AS nm",
+ /* 117 */ "as ::= ids",
+ /* 118 */ "as ::=",
+ /* 119 */ "from ::=",
+ /* 120 */ "from ::= FROM seltablist",
+ /* 121 */ "stl_prefix ::= seltablist joinop",
+ /* 122 */ "stl_prefix ::=",
+ /* 123 */ "seltablist ::= stl_prefix nm dbnm as on_opt using_opt",
+ /* 124 */ "seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt",
+ /* 125 */ "seltablist_paren ::= select",
+ /* 126 */ "seltablist_paren ::= seltablist",
+ /* 127 */ "dbnm ::=",
+ /* 128 */ "dbnm ::= DOT nm",
+ /* 129 */ "joinop ::= COMMA",
+ /* 130 */ "joinop ::= JOIN",
+ /* 131 */ "joinop ::= JOIN_KW JOIN",
+ /* 132 */ "joinop ::= JOIN_KW nm JOIN",
+ /* 133 */ "joinop ::= JOIN_KW nm nm JOIN",
+ /* 134 */ "on_opt ::= ON expr",
+ /* 135 */ "on_opt ::=",
+ /* 136 */ "using_opt ::= USING LP idxlist RP",
+ /* 137 */ "using_opt ::=",
+ /* 138 */ "orderby_opt ::=",
+ /* 139 */ "orderby_opt ::= ORDER BY sortlist",
+ /* 140 */ "sortlist ::= sortlist COMMA sortitem collate sortorder",
+ /* 141 */ "sortlist ::= sortitem collate sortorder",
+ /* 142 */ "sortitem ::= expr",
+ /* 143 */ "sortorder ::= ASC",
+ /* 144 */ "sortorder ::= DESC",
+ /* 145 */ "sortorder ::=",
+ /* 146 */ "collate ::=",
+ /* 147 */ "collate ::= COLLATE id",
+ /* 148 */ "groupby_opt ::=",
+ /* 149 */ "groupby_opt ::= GROUP BY exprlist",
+ /* 150 */ "having_opt ::=",
+ /* 151 */ "having_opt ::= HAVING expr",
+ /* 152 */ "limit_opt ::=",
+ /* 153 */ "limit_opt ::= LIMIT signed",
+ /* 154 */ "limit_opt ::= LIMIT signed OFFSET signed",
+ /* 155 */ "limit_opt ::= LIMIT signed COMMA signed",
+ /* 156 */ "cmd ::= DELETE FROM nm dbnm where_opt",
+ /* 157 */ "where_opt ::=",
+ /* 158 */ "where_opt ::= WHERE expr",
+ /* 159 */ "cmd ::= UPDATE orconf nm dbnm SET setlist where_opt",
+ /* 160 */ "setlist ::= setlist COMMA nm EQ expr",
+ /* 161 */ "setlist ::= nm EQ expr",
+ /* 162 */ "cmd ::= insert_cmd INTO nm dbnm inscollist_opt VALUES LP itemlist RP",
+ /* 163 */ "cmd ::= insert_cmd INTO nm dbnm inscollist_opt select",
+ /* 164 */ "insert_cmd ::= INSERT orconf",
+ /* 165 */ "insert_cmd ::= REPLACE",
+ /* 166 */ "itemlist ::= itemlist COMMA expr",
+ /* 167 */ "itemlist ::= expr",
+ /* 168 */ "inscollist_opt ::=",
+ /* 169 */ "inscollist_opt ::= LP inscollist RP",
+ /* 170 */ "inscollist ::= inscollist COMMA nm",
+ /* 171 */ "inscollist ::= nm",
+ /* 172 */ "expr ::= LP expr RP",
+ /* 173 */ "expr ::= NULL",
+ /* 174 */ "expr ::= ID",
+ /* 175 */ "expr ::= JOIN_KW",
+ /* 176 */ "expr ::= nm DOT nm",
+ /* 177 */ "expr ::= nm DOT nm DOT nm",
+ /* 178 */ "expr ::= INTEGER",
+ /* 179 */ "expr ::= FLOAT",
+ /* 180 */ "expr ::= STRING",
+ /* 181 */ "expr ::= VARIABLE",
+ /* 182 */ "expr ::= ID LP exprlist RP",
+ /* 183 */ "expr ::= ID LP STAR RP",
+ /* 184 */ "expr ::= expr AND expr",
+ /* 185 */ "expr ::= expr OR expr",
+ /* 186 */ "expr ::= expr LT expr",
+ /* 187 */ "expr ::= expr GT expr",
+ /* 188 */ "expr ::= expr LE expr",
+ /* 189 */ "expr ::= expr GE expr",
+ /* 190 */ "expr ::= expr NE expr",
+ /* 191 */ "expr ::= expr EQ expr",
+ /* 192 */ "expr ::= expr BITAND expr",
+ /* 193 */ "expr ::= expr BITOR expr",
+ /* 194 */ "expr ::= expr LSHIFT expr",
+ /* 195 */ "expr ::= expr RSHIFT expr",
+ /* 196 */ "expr ::= expr likeop expr",
+ /* 197 */ "expr ::= expr NOT likeop expr",
+ /* 198 */ "likeop ::= LIKE",
+ /* 199 */ "likeop ::= GLOB",
+ /* 200 */ "expr ::= expr PLUS expr",
+ /* 201 */ "expr ::= expr MINUS expr",
+ /* 202 */ "expr ::= expr STAR expr",
+ /* 203 */ "expr ::= expr SLASH expr",
+ /* 204 */ "expr ::= expr REM expr",
+ /* 205 */ "expr ::= expr CONCAT expr",
+ /* 206 */ "expr ::= expr ISNULL",
+ /* 207 */ "expr ::= expr IS NULL",
+ /* 208 */ "expr ::= expr NOTNULL",
+ /* 209 */ "expr ::= expr NOT NULL",
+ /* 210 */ "expr ::= expr IS NOT NULL",
+ /* 211 */ "expr ::= NOT expr",
+ /* 212 */ "expr ::= BITNOT expr",
+ /* 213 */ "expr ::= MINUS expr",
+ /* 214 */ "expr ::= PLUS expr",
+ /* 215 */ "expr ::= LP select RP",
+ /* 216 */ "expr ::= expr BETWEEN expr AND expr",
+ /* 217 */ "expr ::= expr NOT BETWEEN expr AND expr",
+ /* 218 */ "expr ::= expr IN LP exprlist RP",
+ /* 219 */ "expr ::= expr IN LP select RP",
+ /* 220 */ "expr ::= expr NOT IN LP exprlist RP",
+ /* 221 */ "expr ::= expr NOT IN LP select RP",
+ /* 222 */ "expr ::= expr IN nm dbnm",
+ /* 223 */ "expr ::= expr NOT IN nm dbnm",
+ /* 224 */ "expr ::= CASE case_operand case_exprlist case_else END",
+ /* 225 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr",
+ /* 226 */ "case_exprlist ::= WHEN expr THEN expr",
+ /* 227 */ "case_else ::= ELSE expr",
+ /* 228 */ "case_else ::=",
+ /* 229 */ "case_operand ::= expr",
+ /* 230 */ "case_operand ::=",
+ /* 231 */ "exprlist ::= exprlist COMMA expritem",
+ /* 232 */ "exprlist ::= expritem",
+ /* 233 */ "expritem ::= expr",
+ /* 234 */ "expritem ::=",
+ /* 235 */ "cmd ::= CREATE uniqueflag INDEX nm ON nm dbnm LP idxlist RP onconf",
+ /* 236 */ "uniqueflag ::= UNITQUE",
+ /* 237 */ "uniqueflag ::=",
+ /* 238 */ "idxlist_opt ::=",
+ /* 239 */ "idxlist_opt ::= LP idxlist RP",
+ /* 240 */ "idxlist ::= idxlist COMMA idxitem",
+ /* 241 */ "idxlist ::= idxitem",
+ /* 242 */ "idxitem ::= nm sortorder",
+ /* 243 */ "cmd ::= DROP INDEX nm dbnm",
+ /* 244 */ "cmd ::= COPY orconf nm dbnm FROM nm USING DELIMITERS STRING",
+ /* 245 */ "cmd ::= COPY orconf nm dbnm FROM nm",
+ /* 246 */ "cmd ::= VACUUM",
+ /* 247 */ "cmd ::= VACUUM nm",
+ /* 248 */ "cmd ::= PRAGMA ids EQ nm",
+ /* 249 */ "cmd ::= PRAGMA ids EQ ON",
+ /* 250 */ "cmd ::= PRAGMA ids EQ plus_num",
+ /* 251 */ "cmd ::= PRAGMA ids EQ minus_num",
+ /* 252 */ "cmd ::= PRAGMA ids LP nm RP",
+ /* 253 */ "cmd ::= PRAGMA ids",
+ /* 254 */ "plus_num ::= plus_opt number",
+ /* 255 */ "minus_num ::= MINUS number",
+ /* 256 */ "number ::= INTEGER",
+ /* 257 */ "number ::= FLOAT",
+ /* 258 */ "plus_opt ::= PLUS",
+ /* 259 */ "plus_opt ::=",
+ /* 260 */ "cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END",
+ /* 261 */ "trigger_decl ::= temp TRIGGER nm trigger_time trigger_event ON nm dbnm foreach_clause when_clause",
+ /* 262 */ "trigger_time ::= BEFORE",
+ /* 263 */ "trigger_time ::= AFTER",
+ /* 264 */ "trigger_time ::= INSTEAD OF",
+ /* 265 */ "trigger_time ::=",
+ /* 266 */ "trigger_event ::= DELETE",
+ /* 267 */ "trigger_event ::= INSERT",
+ /* 268 */ "trigger_event ::= UPDATE",
+ /* 269 */ "trigger_event ::= UPDATE OF inscollist",
+ /* 270 */ "foreach_clause ::=",
+ /* 271 */ "foreach_clause ::= FOR EACH ROW",
+ /* 272 */ "foreach_clause ::= FOR EACH STATEMENT",
+ /* 273 */ "when_clause ::=",
+ /* 274 */ "when_clause ::= WHEN expr",
+ /* 275 */ "trigger_cmd_list ::= trigger_cmd SEMI trigger_cmd_list",
+ /* 276 */ "trigger_cmd_list ::=",
+ /* 277 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt",
+ /* 278 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP",
+ /* 279 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select",
+ /* 280 */ "trigger_cmd ::= DELETE FROM nm where_opt",
+ /* 281 */ "trigger_cmd ::= select",
+ /* 282 */ "expr ::= RAISE LP IGNORE RP",
+ /* 283 */ "expr ::= RAISE LP ROLLBACK COMMA nm RP",
+ /* 284 */ "expr ::= RAISE LP ABORT COMMA nm RP",
+ /* 285 */ "expr ::= RAISE LP FAIL COMMA nm RP",
+ /* 286 */ "cmd ::= DROP TRIGGER nm dbnm",
+ /* 287 */ "cmd ::= ATTACH database_kw_opt ids AS nm key_opt",
+ /* 288 */ "key_opt ::= USING ids",
+ /* 289 */ "key_opt ::=",
+ /* 290 */ "database_kw_opt ::= DATABASE",
+ /* 291 */ "database_kw_opt ::=",
+ /* 292 */ "cmd ::= DETACH database_kw_opt nm",
+};
+#endif /* NDEBUG */
+
+/*
+** This function returns the symbolic name associated with a token
+** value.
+*/
+const char *sqliteParserTokenName(int tokenType){
+#ifndef NDEBUG
+ if( tokenType>0 && tokenType<(sizeof(yyTokenName)/sizeof(yyTokenName[0])) ){
+ return yyTokenName[tokenType];
+ }else{
+ return "Unknown";
+ }
+#else
+ return "";
+#endif
+}
+
+/*
+** This function allocates a new parser.
+** The only argument is a pointer to a function which works like
+** malloc.
+**
+** Inputs:
+** A pointer to the function used to allocate memory.
+**
+** Outputs:
+** A pointer to a parser. This pointer is used in subsequent calls
+** to sqliteParser and sqliteParserFree.
+*/
+void *sqliteParserAlloc(void *(*mallocProc)(size_t)){
+ yyParser *pParser;
+ pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
+ if( pParser ){
+ pParser->yyidx = -1;
+ }
+ return pParser;
+}
+
+/* The following function deletes the value associated with a
+** symbol. The symbol can be either a terminal or nonterminal.
+** "yymajor" is the symbol code, and "yypminor" is a pointer to
+** the value.
+*/
+static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
+ switch( yymajor ){
+ /* Here is inserted the actions which take place when a
+ ** terminal or non-terminal is destroyed. This can happen
+ ** when the symbol is popped from the stack during a
+ ** reduce or during error processing or when a parser is
+ ** being destroyed before it is finished parsing.
+ **
+ ** Note: during a reduce, the only symbols destroyed are those
+ ** which appear on the RHS of the rule, but which are not used
+ ** inside the C code.
+ */
+ case 146:
+#line 286 "parse.y"
+{sqliteSelectDelete((yypminor->yy179));}
+#line 1235 "parse.c"
+ break;
+ case 158:
+#line 533 "parse.y"
+{sqliteExprDelete((yypminor->yy242));}
+#line 1240 "parse.c"
+ break;
+ case 159:
+#line 746 "parse.y"
+{sqliteIdListDelete((yypminor->yy320));}
+#line 1245 "parse.c"
+ break;
+ case 167:
+#line 744 "parse.y"
+{sqliteIdListDelete((yypminor->yy320));}
+#line 1250 "parse.c"
+ break;
+ case 171:
+#line 288 "parse.y"
+{sqliteSelectDelete((yypminor->yy179));}
+#line 1255 "parse.c"
+ break;
+ case 174:
+#line 322 "parse.y"
+{sqliteExprListDelete((yypminor->yy322));}
+#line 1260 "parse.c"
+ break;
+ case 175:
+#line 353 "parse.y"
+{sqliteSrcListDelete((yypminor->yy307));}
+#line 1265 "parse.c"
+ break;
+ case 176:
+#line 483 "parse.y"
+{sqliteExprDelete((yypminor->yy242));}
+#line 1270 "parse.c"
+ break;
+ case 177:
+#line 459 "parse.y"
+{sqliteExprListDelete((yypminor->yy322));}
+#line 1275 "parse.c"
+ break;
+ case 178:
+#line 464 "parse.y"
+{sqliteExprDelete((yypminor->yy242));}
+#line 1280 "parse.c"
+ break;
+ case 179:
+#line 431 "parse.y"
+{sqliteExprListDelete((yypminor->yy322));}
+#line 1285 "parse.c"
+ break;
+ case 181:
+#line 324 "parse.y"
+{sqliteExprListDelete((yypminor->yy322));}
+#line 1290 "parse.c"
+ break;
+ case 183:
+#line 349 "parse.y"
+{sqliteSrcListDelete((yypminor->yy307));}
+#line 1295 "parse.c"
+ break;
+ case 184:
+#line 351 "parse.y"
+{sqliteSrcListDelete((yypminor->yy307));}
+#line 1300 "parse.c"
+ break;
+ case 187:
+#line 420 "parse.y"
+{sqliteExprDelete((yypminor->yy242));}
+#line 1305 "parse.c"
+ break;
+ case 188:
+#line 425 "parse.y"
+{sqliteIdListDelete((yypminor->yy320));}
+#line 1310 "parse.c"
+ break;
+ case 189:
+#line 400 "parse.y"
+{sqliteSelectDelete((yypminor->yy179));}
+#line 1315 "parse.c"
+ break;
+ case 191:
+#line 433 "parse.y"
+{sqliteExprListDelete((yypminor->yy322));}
+#line 1320 "parse.c"
+ break;
+ case 192:
+#line 435 "parse.y"
+{sqliteExprDelete((yypminor->yy242));}
+#line 1325 "parse.c"
+ break;
+ case 194:
+#line 719 "parse.y"
+{sqliteExprListDelete((yypminor->yy322));}
+#line 1330 "parse.c"
+ break;
+ case 195:
+#line 489 "parse.y"
+{sqliteExprListDelete((yypminor->yy322));}
+#line 1335 "parse.c"
+ break;
+ case 197:
+#line 520 "parse.y"
+{sqliteIdListDelete((yypminor->yy320));}
+#line 1340 "parse.c"
+ break;
+ case 198:
+#line 514 "parse.y"
+{sqliteExprListDelete((yypminor->yy322));}
+#line 1345 "parse.c"
+ break;
+ case 199:
+#line 522 "parse.y"
+{sqliteIdListDelete((yypminor->yy320));}
+#line 1350 "parse.c"
+ break;
+ case 202:
+#line 702 "parse.y"
+{sqliteExprListDelete((yypminor->yy322));}
+#line 1355 "parse.c"
+ break;
+ case 204:
+#line 721 "parse.y"
+{sqliteExprDelete((yypminor->yy242));}
+#line 1360 "parse.c"
+ break;
+ case 212:
+#line 828 "parse.y"
+{sqliteDeleteTriggerStep((yypminor->yy19));}
+#line 1365 "parse.c"
+ break;
+ case 214:
+#line 812 "parse.y"
+{sqliteIdListDelete((yypminor->yy290).b);}
+#line 1370 "parse.c"
+ break;
+ case 217:
+#line 836 "parse.y"
+{sqliteDeleteTriggerStep((yypminor->yy19));}
+#line 1375 "parse.c"
+ break;
+ default: break; /* If no destructor action specified: do nothing */
+ }
+}
+
+/*
+** Pop the parser's stack once.
+**
+** If there is a destructor routine associated with the token which
+** is popped from the stack, then call it.
+**
+** Return the major token number for the symbol popped.
+*/
+static int yy_pop_parser_stack(yyParser *pParser){
+ YYCODETYPE yymajor;
+ yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
+
+ if( pParser->yyidx<0 ) return 0;
+#ifndef NDEBUG
+ if( yyTraceFILE && pParser->yyidx>=0 ){
+ fprintf(yyTraceFILE,"%sPopping %s\n",
+ yyTracePrompt,
+ yyTokenName[yytos->major]);
+ }
+#endif
+ yymajor = yytos->major;
+ yy_destructor( yymajor, &yytos->minor);
+ pParser->yyidx--;
+ return yymajor;
+}
+
+/*
+** Deallocate and destroy a parser. Destructors are all called for
+** all stack elements before shutting the parser down.
+**
+** Inputs:
+** <ul>
+** <li> A pointer to the parser. This should be a pointer
+** obtained from sqliteParserAlloc.
+** <li> A pointer to a function used to reclaim memory obtained
+** from malloc.
+** </ul>
+*/
+void sqliteParserFree(
+ void *p, /* The parser to be deleted */
+ void (*freeProc)(void*) /* Function used to reclaim memory */
+){
+ yyParser *pParser = (yyParser*)p;
+ if( pParser==0 ) return;
+ while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
+ (*freeProc)((void*)pParser);
+}
+
+/*
+** Find the appropriate action for a parser given the terminal
+** look-ahead token iLookAhead.
+**
+** If the look-ahead token is YYNOCODE, then check to see if the action is
+** independent of the look-ahead. If it is, return the action, otherwise
+** return YY_NO_ACTION.
+*/
+static int yy_tqfind_shift_action(
+ yyParser *pParser, /* The parser */
+ int iLookAhead /* The look-ahead token */
+){
+ int i;
+ int stateno = pParser->yystack[pParser->yyidx].stateno;
+
+ /* if( pParser->yyidx<0 ) return YY_NO_ACTION; */
+ i = yy_shift_ofst[stateno];
+ if( i==YY_SHIFT_USE_DFLT ){
+ return yy_default[stateno];
+ }
+ if( iLookAhead==YYNOCODE ){
+ return YY_NO_ACTION;
+ }
+ i += iLookAhead;
+ if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
+#ifdef YYFALLBACK
+ int iFallback; /* Fallback token */
+ if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
+ && (iFallback = yyFallback[iLookAhead])!=0 ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
+ }
+#endif
+ return yy_tqfind_shift_action(pParser, iFallback);
+ }
+#endif
+ return yy_default[stateno];
+ }else{
+ return yy_action[i];
+ }
+}
+
+/*
+** Find the appropriate action for a parser given the non-terminal
+** look-ahead token iLookAhead.
+**
+** If the look-ahead token is YYNOCODE, then check to see if the action is
+** independent of the look-ahead. If it is, return the action, otherwise
+** return YY_NO_ACTION.
+*/
+static int yy_tqfind_reduce_action(
+ yyParser *pParser, /* The parser */
+ int iLookAhead /* The look-ahead token */
+){
+ int i;
+ int stateno = pParser->yystack[pParser->yyidx].stateno;
+
+ i = yy_reduce_ofst[stateno];
+ if( i==YY_REDUCE_USE_DFLT ){
+ return yy_default[stateno];
+ }
+ if( iLookAhead==YYNOCODE ){
+ return YY_NO_ACTION;
+ }
+ i += iLookAhead;
+ if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){
+ return yy_default[stateno];
+ }else{
+ return yy_action[i];
+ }
+}
+
+/*
+** Perform a shift action.
+*/
+static void yy_shift(
+ yyParser *yypParser, /* The parser to be shifted */
+ int yyNewState, /* The new state to shift in */
+ int yyMajor, /* The major token to shift in */
+ YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */
+){
+ yyStackEntry *yytos;
+ yypParser->yyidx++;
+ if( yypParser->yyidx>=YYSTACKDEPTH ){
+ sqliteParserARG_FETCH;
+ yypParser->yyidx--;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will execute if the parser
+ ** stack every overflows */
+ sqliteParserARG_STORE; /* Suppress warning about unused %extra_argument var */
+ return;
+ }
+ yytos = &yypParser->yystack[yypParser->yyidx];
+ yytos->stateno = yyNewState;
+ yytos->major = yyMajor;
+ yytos->minor = *yypMinor;
+#ifndef NDEBUG
+ if( yyTraceFILE && yypParser->yyidx>0 ){
+ int i;
+ fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
+ fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
+ for(i=1; i<=yypParser->yyidx; i++)
+ fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
+ fprintf(yyTraceFILE,"\n");
+ }
+#endif
+}
+
+/* The following table tqcontains information about every rule that
+** is used during the reduce.
+*/
+static struct {
+ YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
+ unsigned char nrhs; /* Number of right-hand side symbols in the rule */
+} yyRuleInfo[] = {
+ { 132, 1 },
+ { 133, 2 },
+ { 133, 1 },
+ { 134, 3 },
+ { 134, 1 },
+ { 136, 1 },
+ { 135, 1 },
+ { 135, 0 },
+ { 137, 3 },
+ { 138, 0 },
+ { 138, 1 },
+ { 138, 2 },
+ { 137, 2 },
+ { 137, 2 },
+ { 137, 2 },
+ { 137, 2 },
+ { 141, 4 },
+ { 143, 1 },
+ { 143, 0 },
+ { 142, 4 },
+ { 142, 2 },
+ { 144, 3 },
+ { 144, 1 },
+ { 147, 3 },
+ { 148, 1 },
+ { 151, 1 },
+ { 152, 1 },
+ { 152, 1 },
+ { 140, 1 },
+ { 140, 1 },
+ { 140, 1 },
+ { 149, 0 },
+ { 149, 1 },
+ { 149, 4 },
+ { 149, 6 },
+ { 153, 1 },
+ { 153, 2 },
+ { 154, 1 },
+ { 154, 2 },
+ { 154, 2 },
+ { 150, 2 },
+ { 150, 0 },
+ { 155, 3 },
+ { 155, 1 },
+ { 155, 2 },
+ { 155, 2 },
+ { 155, 2 },
+ { 155, 3 },
+ { 155, 3 },
+ { 155, 2 },
+ { 155, 3 },
+ { 155, 3 },
+ { 155, 2 },
+ { 156, 2 },
+ { 156, 3 },
+ { 156, 4 },
+ { 156, 2 },
+ { 156, 5 },
+ { 156, 4 },
+ { 156, 1 },
+ { 156, 2 },
+ { 160, 0 },
+ { 160, 2 },
+ { 162, 2 },
+ { 162, 3 },
+ { 162, 3 },
+ { 162, 3 },
+ { 163, 2 },
+ { 163, 2 },
+ { 163, 1 },
+ { 163, 1 },
+ { 161, 3 },
+ { 161, 2 },
+ { 164, 0 },
+ { 164, 2 },
+ { 164, 2 },
+ { 145, 0 },
+ { 145, 2 },
+ { 165, 3 },
+ { 165, 2 },
+ { 165, 1 },
+ { 166, 2 },
+ { 166, 6 },
+ { 166, 5 },
+ { 166, 3 },
+ { 166, 10 },
+ { 168, 0 },
+ { 168, 1 },
+ { 139, 0 },
+ { 139, 3 },
+ { 169, 0 },
+ { 169, 2 },
+ { 170, 1 },
+ { 170, 1 },
+ { 170, 1 },
+ { 170, 1 },
+ { 170, 1 },
+ { 137, 3 },
+ { 137, 6 },
+ { 137, 3 },
+ { 137, 1 },
+ { 146, 1 },
+ { 146, 3 },
+ { 172, 1 },
+ { 172, 2 },
+ { 172, 1 },
+ { 172, 1 },
+ { 171, 9 },
+ { 173, 1 },
+ { 173, 1 },
+ { 173, 0 },
+ { 181, 2 },
+ { 181, 0 },
+ { 174, 3 },
+ { 174, 2 },
+ { 174, 4 },
+ { 182, 2 },
+ { 182, 1 },
+ { 182, 0 },
+ { 175, 0 },
+ { 175, 2 },
+ { 184, 2 },
+ { 184, 0 },
+ { 183, 6 },
+ { 183, 7 },
+ { 189, 1 },
+ { 189, 1 },
+ { 186, 0 },
+ { 186, 2 },
+ { 185, 1 },
+ { 185, 1 },
+ { 185, 2 },
+ { 185, 3 },
+ { 185, 4 },
+ { 187, 2 },
+ { 187, 0 },
+ { 188, 4 },
+ { 188, 0 },
+ { 179, 0 },
+ { 179, 3 },
+ { 191, 5 },
+ { 191, 3 },
+ { 192, 1 },
+ { 157, 1 },
+ { 157, 1 },
+ { 157, 0 },
+ { 193, 0 },
+ { 193, 2 },
+ { 177, 0 },
+ { 177, 3 },
+ { 178, 0 },
+ { 178, 2 },
+ { 180, 0 },
+ { 180, 2 },
+ { 180, 4 },
+ { 180, 4 },
+ { 137, 5 },
+ { 176, 0 },
+ { 176, 2 },
+ { 137, 7 },
+ { 195, 5 },
+ { 195, 3 },
+ { 137, 9 },
+ { 137, 6 },
+ { 196, 2 },
+ { 196, 1 },
+ { 198, 3 },
+ { 198, 1 },
+ { 197, 0 },
+ { 197, 3 },
+ { 199, 3 },
+ { 199, 1 },
+ { 158, 3 },
+ { 158, 1 },
+ { 158, 1 },
+ { 158, 1 },
+ { 158, 3 },
+ { 158, 5 },
+ { 158, 1 },
+ { 158, 1 },
+ { 158, 1 },
+ { 158, 1 },
+ { 158, 4 },
+ { 158, 4 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 4 },
+ { 200, 1 },
+ { 200, 1 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 3 },
+ { 158, 2 },
+ { 158, 3 },
+ { 158, 2 },
+ { 158, 3 },
+ { 158, 4 },
+ { 158, 2 },
+ { 158, 2 },
+ { 158, 2 },
+ { 158, 2 },
+ { 158, 3 },
+ { 158, 5 },
+ { 158, 6 },
+ { 158, 5 },
+ { 158, 5 },
+ { 158, 6 },
+ { 158, 6 },
+ { 158, 4 },
+ { 158, 5 },
+ { 158, 5 },
+ { 202, 5 },
+ { 202, 4 },
+ { 203, 2 },
+ { 203, 0 },
+ { 201, 1 },
+ { 201, 0 },
+ { 194, 3 },
+ { 194, 1 },
+ { 204, 1 },
+ { 204, 0 },
+ { 137, 11 },
+ { 205, 1 },
+ { 205, 0 },
+ { 159, 0 },
+ { 159, 3 },
+ { 167, 3 },
+ { 167, 1 },
+ { 206, 2 },
+ { 137, 4 },
+ { 137, 9 },
+ { 137, 6 },
+ { 137, 1 },
+ { 137, 2 },
+ { 137, 4 },
+ { 137, 4 },
+ { 137, 4 },
+ { 137, 4 },
+ { 137, 5 },
+ { 137, 2 },
+ { 207, 2 },
+ { 208, 2 },
+ { 210, 1 },
+ { 210, 1 },
+ { 209, 1 },
+ { 209, 0 },
+ { 137, 5 },
+ { 211, 10 },
+ { 213, 1 },
+ { 213, 1 },
+ { 213, 2 },
+ { 213, 0 },
+ { 214, 1 },
+ { 214, 1 },
+ { 214, 1 },
+ { 214, 3 },
+ { 215, 0 },
+ { 215, 3 },
+ { 215, 3 },
+ { 216, 0 },
+ { 216, 2 },
+ { 212, 3 },
+ { 212, 0 },
+ { 217, 6 },
+ { 217, 8 },
+ { 217, 5 },
+ { 217, 4 },
+ { 217, 1 },
+ { 158, 4 },
+ { 158, 6 },
+ { 158, 6 },
+ { 158, 6 },
+ { 137, 4 },
+ { 137, 6 },
+ { 219, 2 },
+ { 219, 0 },
+ { 218, 1 },
+ { 218, 0 },
+ { 137, 3 },
+};
+
+static void yy_accept(yyParser*); /* Forward Declaration */
+
+/*
+** Perform a reduce action and the shift that must immediately
+** follow the reduce.
+*/
+static void yy_reduce(
+ yyParser *yypParser, /* The parser */
+ int yyruleno /* Number of the rule by which to reduce */
+){
+ int yygoto; /* The next state */
+ int yyact; /* The next action */
+ YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
+ yyStackEntry *yymsp; /* The top of the parser's stack */
+ int yysize; /* Amount to pop the stack */
+ sqliteParserARG_FETCH;
+ yymsp = &yypParser->yystack[yypParser->yyidx];
+#ifndef NDEBUG
+ if( yyTraceFILE && yyruleno>=0
+ && yyruleno<sizeof(yyRuleName)/sizeof(yyRuleName[0]) ){
+ fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
+ yyRuleName[yyruleno]);
+ }
+#endif /* NDEBUG */
+
+ switch( yyruleno ){
+ /* Beginning here are the reduction cases. A typical example
+ ** follows:
+ ** case 0:
+ ** #line <lineno> <grammarfile>
+ ** { ... } // User supplied code
+ ** #line <lineno> <thisfile>
+ ** break;
+ */
+ case 0:
+ /* No destructor defined for cmdlist */
+ break;
+ case 1:
+ /* No destructor defined for cmdlist */
+ /* No destructor defined for ecmd */
+ break;
+ case 2:
+ /* No destructor defined for ecmd */
+ break;
+ case 3:
+ /* No destructor defined for explain */
+ /* No destructor defined for cmdx */
+ /* No destructor defined for SEMI */
+ break;
+ case 4:
+ /* No destructor defined for SEMI */
+ break;
+ case 5:
+#line 72 "parse.y"
+{ sqliteExec(pParse); }
+#line 1901 "parse.c"
+ /* No destructor defined for cmd */
+ break;
+ case 6:
+#line 73 "parse.y"
+{ sqliteBeginParse(pParse, 1); }
+#line 1907 "parse.c"
+ /* No destructor defined for EXPLAIN */
+ break;
+ case 7:
+#line 74 "parse.y"
+{ sqliteBeginParse(pParse, 0); }
+#line 1913 "parse.c"
+ break;
+ case 8:
+#line 79 "parse.y"
+{sqliteBeginTransaction(pParse,yymsp[0].minor.yy372);}
+#line 1918 "parse.c"
+ /* No destructor defined for BEGIN */
+ /* No destructor defined for trans_opt */
+ break;
+ case 9:
+ break;
+ case 10:
+ /* No destructor defined for TRANSACTION */
+ break;
+ case 11:
+ /* No destructor defined for TRANSACTION */
+ /* No destructor defined for nm */
+ break;
+ case 12:
+#line 83 "parse.y"
+{sqliteCommitTransaction(pParse);}
+#line 1934 "parse.c"
+ /* No destructor defined for COMMIT */
+ /* No destructor defined for trans_opt */
+ break;
+ case 13:
+#line 84 "parse.y"
+{sqliteCommitTransaction(pParse);}
+#line 1941 "parse.c"
+ /* No destructor defined for END */
+ /* No destructor defined for trans_opt */
+ break;
+ case 14:
+#line 85 "parse.y"
+{sqliteRollbackTransaction(pParse);}
+#line 1948 "parse.c"
+ /* No destructor defined for ROLLBACK */
+ /* No destructor defined for trans_opt */
+ break;
+ case 15:
+ /* No destructor defined for create_table */
+ /* No destructor defined for create_table_args */
+ break;
+ case 16:
+#line 90 "parse.y"
+{
+ sqliteStartTable(pParse,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy298,yymsp[-2].minor.yy372,0);
+}
+#line 1961 "parse.c"
+ /* No destructor defined for TABLE */
+ break;
+ case 17:
+#line 94 "parse.y"
+{yygotominor.yy372 = 1;}
+#line 1967 "parse.c"
+ /* No destructor defined for TEMP */
+ break;
+ case 18:
+#line 95 "parse.y"
+{yygotominor.yy372 = 0;}
+#line 1973 "parse.c"
+ break;
+ case 19:
+#line 96 "parse.y"
+{
+ sqliteEndTable(pParse,&yymsp[0].minor.yy0,0);
+}
+#line 1980 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for columnlist */
+ /* No destructor defined for conslist_opt */
+ break;
+ case 20:
+#line 99 "parse.y"
+{
+ sqliteEndTable(pParse,0,yymsp[0].minor.yy179);
+ sqliteSelectDelete(yymsp[0].minor.yy179);
+}
+#line 1991 "parse.c"
+ /* No destructor defined for AS */
+ break;
+ case 21:
+ /* No destructor defined for columnlist */
+ /* No destructor defined for COMMA */
+ /* No destructor defined for column */
+ break;
+ case 22:
+ /* No destructor defined for column */
+ break;
+ case 23:
+ /* No destructor defined for columnid */
+ /* No destructor defined for type */
+ /* No destructor defined for carglist */
+ break;
+ case 24:
+#line 111 "parse.y"
+{sqliteAddColumn(pParse,&yymsp[0].minor.yy298);}
+#line 2010 "parse.c"
+ break;
+ case 25:
+#line 117 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy0;}
+#line 2015 "parse.c"
+ break;
+ case 26:
+#line 149 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy0;}
+#line 2020 "parse.c"
+ break;
+ case 27:
+#line 150 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy0;}
+#line 2025 "parse.c"
+ break;
+ case 28:
+#line 155 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy0;}
+#line 2030 "parse.c"
+ break;
+ case 29:
+#line 156 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy0;}
+#line 2035 "parse.c"
+ break;
+ case 30:
+#line 157 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy0;}
+#line 2040 "parse.c"
+ break;
+ case 31:
+ break;
+ case 32:
+#line 160 "parse.y"
+{sqliteAddColumnType(pParse,&yymsp[0].minor.yy298,&yymsp[0].minor.yy298);}
+#line 2047 "parse.c"
+ break;
+ case 33:
+#line 161 "parse.y"
+{sqliteAddColumnType(pParse,&yymsp[-3].minor.yy298,&yymsp[0].minor.yy0);}
+#line 2052 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for signed */
+ break;
+ case 34:
+#line 163 "parse.y"
+{sqliteAddColumnType(pParse,&yymsp[-5].minor.yy298,&yymsp[0].minor.yy0);}
+#line 2059 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for signed */
+ /* No destructor defined for COMMA */
+ /* No destructor defined for signed */
+ break;
+ case 35:
+#line 165 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy298;}
+#line 2068 "parse.c"
+ break;
+ case 36:
+#line 166 "parse.y"
+{yygotominor.yy298 = yymsp[-1].minor.yy298;}
+#line 2073 "parse.c"
+ /* No destructor defined for ids */
+ break;
+ case 37:
+#line 168 "parse.y"
+{ yygotominor.yy372 = atoi(yymsp[0].minor.yy0.z); }
+#line 2079 "parse.c"
+ break;
+ case 38:
+#line 169 "parse.y"
+{ yygotominor.yy372 = atoi(yymsp[0].minor.yy0.z); }
+#line 2084 "parse.c"
+ /* No destructor defined for PLUS */
+ break;
+ case 39:
+#line 170 "parse.y"
+{ yygotominor.yy372 = -atoi(yymsp[0].minor.yy0.z); }
+#line 2090 "parse.c"
+ /* No destructor defined for MINUS */
+ break;
+ case 40:
+ /* No destructor defined for carglist */
+ /* No destructor defined for carg */
+ break;
+ case 41:
+ break;
+ case 42:
+ /* No destructor defined for CONSTRAINT */
+ /* No destructor defined for nm */
+ /* No destructor defined for ccons */
+ break;
+ case 43:
+ /* No destructor defined for ccons */
+ break;
+ case 44:
+#line 175 "parse.y"
+{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+#line 2110 "parse.c"
+ /* No destructor defined for DEFAULT */
+ break;
+ case 45:
+#line 176 "parse.y"
+{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+#line 2116 "parse.c"
+ /* No destructor defined for DEFAULT */
+ break;
+ case 46:
+#line 177 "parse.y"
+{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+#line 2122 "parse.c"
+ /* No destructor defined for DEFAULT */
+ break;
+ case 47:
+#line 178 "parse.y"
+{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+#line 2128 "parse.c"
+ /* No destructor defined for DEFAULT */
+ /* No destructor defined for PLUS */
+ break;
+ case 48:
+#line 179 "parse.y"
+{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,1);}
+#line 2135 "parse.c"
+ /* No destructor defined for DEFAULT */
+ /* No destructor defined for MINUS */
+ break;
+ case 49:
+#line 180 "parse.y"
+{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+#line 2142 "parse.c"
+ /* No destructor defined for DEFAULT */
+ break;
+ case 50:
+#line 181 "parse.y"
+{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,0);}
+#line 2148 "parse.c"
+ /* No destructor defined for DEFAULT */
+ /* No destructor defined for PLUS */
+ break;
+ case 51:
+#line 182 "parse.y"
+{sqliteAddDefaultValue(pParse,&yymsp[0].minor.yy0,1);}
+#line 2155 "parse.c"
+ /* No destructor defined for DEFAULT */
+ /* No destructor defined for MINUS */
+ break;
+ case 52:
+ /* No destructor defined for DEFAULT */
+ /* No destructor defined for NULL */
+ break;
+ case 53:
+ /* No destructor defined for NULL */
+ /* No destructor defined for onconf */
+ break;
+ case 54:
+#line 189 "parse.y"
+{sqliteAddNotNull(pParse, yymsp[0].minor.yy372);}
+#line 2170 "parse.c"
+ /* No destructor defined for NOT */
+ /* No destructor defined for NULL */
+ break;
+ case 55:
+#line 190 "parse.y"
+{sqliteAddPrimaryKey(pParse,0,yymsp[0].minor.yy372);}
+#line 2177 "parse.c"
+ /* No destructor defined for PRIMARY */
+ /* No destructor defined for KEY */
+ /* No destructor defined for sortorder */
+ break;
+ case 56:
+#line 191 "parse.y"
+{sqliteCreateIndex(pParse,0,0,0,yymsp[0].minor.yy372,0,0);}
+#line 2185 "parse.c"
+ /* No destructor defined for UNITQUE */
+ break;
+ case 57:
+ /* No destructor defined for CHECK */
+ /* No destructor defined for LP */
+ yy_destructor(158,&yymsp[-2].minor);
+ /* No destructor defined for RP */
+ /* No destructor defined for onconf */
+ break;
+ case 58:
+#line 194 "parse.y"
+{sqliteCreateForeignKey(pParse,0,&yymsp[-2].minor.yy298,yymsp[-1].minor.yy320,yymsp[0].minor.yy372);}
+#line 2198 "parse.c"
+ /* No destructor defined for REFERENCES */
+ break;
+ case 59:
+#line 195 "parse.y"
+{sqliteDeferForeignKey(pParse,yymsp[0].minor.yy372);}
+#line 2204 "parse.c"
+ break;
+ case 60:
+#line 196 "parse.y"
+{
+ sqliteAddCollateType(pParse, sqliteCollateType(yymsp[0].minor.yy298.z, yymsp[0].minor.yy298.n));
+}
+#line 2211 "parse.c"
+ /* No destructor defined for COLLATE */
+ break;
+ case 61:
+#line 206 "parse.y"
+{ yygotominor.yy372 = OE_Restrict * 0x010101; }
+#line 2217 "parse.c"
+ break;
+ case 62:
+#line 207 "parse.y"
+{ yygotominor.yy372 = (yymsp[-1].minor.yy372 & yymsp[0].minor.yy407.tqmask) | yymsp[0].minor.yy407.value; }
+#line 2222 "parse.c"
+ break;
+ case 63:
+#line 209 "parse.y"
+{ yygotominor.yy407.value = 0; yygotominor.yy407.tqmask = 0x000000; }
+#line 2227 "parse.c"
+ /* No destructor defined for MATCH */
+ /* No destructor defined for nm */
+ break;
+ case 64:
+#line 210 "parse.y"
+{ yygotominor.yy407.value = yymsp[0].minor.yy372; yygotominor.yy407.tqmask = 0x0000ff; }
+#line 2234 "parse.c"
+ /* No destructor defined for ON */
+ /* No destructor defined for DELETE */
+ break;
+ case 65:
+#line 211 "parse.y"
+{ yygotominor.yy407.value = yymsp[0].minor.yy372<<8; yygotominor.yy407.tqmask = 0x00ff00; }
+#line 2241 "parse.c"
+ /* No destructor defined for ON */
+ /* No destructor defined for UPDATE */
+ break;
+ case 66:
+#line 212 "parse.y"
+{ yygotominor.yy407.value = yymsp[0].minor.yy372<<16; yygotominor.yy407.tqmask = 0xff0000; }
+#line 2248 "parse.c"
+ /* No destructor defined for ON */
+ /* No destructor defined for INSERT */
+ break;
+ case 67:
+#line 214 "parse.y"
+{ yygotominor.yy372 = OE_SetNull; }
+#line 2255 "parse.c"
+ /* No destructor defined for SET */
+ /* No destructor defined for NULL */
+ break;
+ case 68:
+#line 215 "parse.y"
+{ yygotominor.yy372 = OE_SetDflt; }
+#line 2262 "parse.c"
+ /* No destructor defined for SET */
+ /* No destructor defined for DEFAULT */
+ break;
+ case 69:
+#line 216 "parse.y"
+{ yygotominor.yy372 = OE_Cascade; }
+#line 2269 "parse.c"
+ /* No destructor defined for CASCADE */
+ break;
+ case 70:
+#line 217 "parse.y"
+{ yygotominor.yy372 = OE_Restrict; }
+#line 2275 "parse.c"
+ /* No destructor defined for RESTRICT */
+ break;
+ case 71:
+#line 219 "parse.y"
+{yygotominor.yy372 = yymsp[0].minor.yy372;}
+#line 2281 "parse.c"
+ /* No destructor defined for NOT */
+ /* No destructor defined for DEFERRABLE */
+ break;
+ case 72:
+#line 220 "parse.y"
+{yygotominor.yy372 = yymsp[0].minor.yy372;}
+#line 2288 "parse.c"
+ /* No destructor defined for DEFERRABLE */
+ break;
+ case 73:
+#line 222 "parse.y"
+{yygotominor.yy372 = 0;}
+#line 2294 "parse.c"
+ break;
+ case 74:
+#line 223 "parse.y"
+{yygotominor.yy372 = 1;}
+#line 2299 "parse.c"
+ /* No destructor defined for INITIALLY */
+ /* No destructor defined for DEFERRED */
+ break;
+ case 75:
+#line 224 "parse.y"
+{yygotominor.yy372 = 0;}
+#line 2306 "parse.c"
+ /* No destructor defined for INITIALLY */
+ /* No destructor defined for IMMEDIATE */
+ break;
+ case 76:
+ break;
+ case 77:
+ /* No destructor defined for COMMA */
+ /* No destructor defined for conslist */
+ break;
+ case 78:
+ /* No destructor defined for conslist */
+ /* No destructor defined for COMMA */
+ /* No destructor defined for tcons */
+ break;
+ case 79:
+ /* No destructor defined for conslist */
+ /* No destructor defined for tcons */
+ break;
+ case 80:
+ /* No destructor defined for tcons */
+ break;
+ case 81:
+ /* No destructor defined for CONSTRAINT */
+ /* No destructor defined for nm */
+ break;
+ case 82:
+#line 236 "parse.y"
+{sqliteAddPrimaryKey(pParse,yymsp[-2].minor.yy320,yymsp[0].minor.yy372);}
+#line 2335 "parse.c"
+ /* No destructor defined for PRIMARY */
+ /* No destructor defined for KEY */
+ /* No destructor defined for LP */
+ /* No destructor defined for RP */
+ break;
+ case 83:
+#line 238 "parse.y"
+{sqliteCreateIndex(pParse,0,0,yymsp[-2].minor.yy320,yymsp[0].minor.yy372,0,0);}
+#line 2344 "parse.c"
+ /* No destructor defined for UNITQUE */
+ /* No destructor defined for LP */
+ /* No destructor defined for RP */
+ break;
+ case 84:
+ /* No destructor defined for CHECK */
+ yy_destructor(158,&yymsp[-1].minor);
+ /* No destructor defined for onconf */
+ break;
+ case 85:
+#line 241 "parse.y"
+{
+ sqliteCreateForeignKey(pParse, yymsp[-6].minor.yy320, &yymsp[-3].minor.yy298, yymsp[-2].minor.yy320, yymsp[-1].minor.yy372);
+ sqliteDeferForeignKey(pParse, yymsp[0].minor.yy372);
+}
+#line 2360 "parse.c"
+ /* No destructor defined for FOREIGN */
+ /* No destructor defined for KEY */
+ /* No destructor defined for LP */
+ /* No destructor defined for RP */
+ /* No destructor defined for REFERENCES */
+ break;
+ case 86:
+#line 246 "parse.y"
+{yygotominor.yy372 = 0;}
+#line 2370 "parse.c"
+ break;
+ case 87:
+#line 247 "parse.y"
+{yygotominor.yy372 = yymsp[0].minor.yy372;}
+#line 2375 "parse.c"
+ break;
+ case 88:
+#line 255 "parse.y"
+{ yygotominor.yy372 = OE_Default; }
+#line 2380 "parse.c"
+ break;
+ case 89:
+#line 256 "parse.y"
+{ yygotominor.yy372 = yymsp[0].minor.yy372; }
+#line 2385 "parse.c"
+ /* No destructor defined for ON */
+ /* No destructor defined for CONFLICT */
+ break;
+ case 90:
+#line 257 "parse.y"
+{ yygotominor.yy372 = OE_Default; }
+#line 2392 "parse.c"
+ break;
+ case 91:
+#line 258 "parse.y"
+{ yygotominor.yy372 = yymsp[0].minor.yy372; }
+#line 2397 "parse.c"
+ /* No destructor defined for OR */
+ break;
+ case 92:
+#line 259 "parse.y"
+{ yygotominor.yy372 = OE_Rollback; }
+#line 2403 "parse.c"
+ /* No destructor defined for ROLLBACK */
+ break;
+ case 93:
+#line 260 "parse.y"
+{ yygotominor.yy372 = OE_Abort; }
+#line 2409 "parse.c"
+ /* No destructor defined for ABORT */
+ break;
+ case 94:
+#line 261 "parse.y"
+{ yygotominor.yy372 = OE_Fail; }
+#line 2415 "parse.c"
+ /* No destructor defined for FAIL */
+ break;
+ case 95:
+#line 262 "parse.y"
+{ yygotominor.yy372 = OE_Ignore; }
+#line 2421 "parse.c"
+ /* No destructor defined for IGNORE */
+ break;
+ case 96:
+#line 263 "parse.y"
+{ yygotominor.yy372 = OE_Replace; }
+#line 2427 "parse.c"
+ /* No destructor defined for REPLACE */
+ break;
+ case 97:
+#line 267 "parse.y"
+{sqliteDropTable(pParse,&yymsp[0].minor.yy298,0);}
+#line 2433 "parse.c"
+ /* No destructor defined for DROP */
+ /* No destructor defined for TABLE */
+ break;
+ case 98:
+#line 271 "parse.y"
+{
+ sqliteCreateView(pParse, &yymsp[-5].minor.yy0, &yymsp[-2].minor.yy298, yymsp[0].minor.yy179, yymsp[-4].minor.yy372);
+}
+#line 2442 "parse.c"
+ /* No destructor defined for VIEW */
+ /* No destructor defined for AS */
+ break;
+ case 99:
+#line 274 "parse.y"
+{
+ sqliteDropTable(pParse, &yymsp[0].minor.yy298, 1);
+}
+#line 2451 "parse.c"
+ /* No destructor defined for DROP */
+ /* No destructor defined for VIEW */
+ break;
+ case 100:
+#line 280 "parse.y"
+{
+ sqliteSelect(pParse, yymsp[0].minor.yy179, SRT_Callback, 0, 0, 0, 0);
+ sqliteSelectDelete(yymsp[0].minor.yy179);
+}
+#line 2461 "parse.c"
+ break;
+ case 101:
+#line 290 "parse.y"
+{yygotominor.yy179 = yymsp[0].minor.yy179;}
+#line 2466 "parse.c"
+ break;
+ case 102:
+#line 291 "parse.y"
+{
+ if( yymsp[0].minor.yy179 ){
+ yymsp[0].minor.yy179->op = yymsp[-1].minor.yy372;
+ yymsp[0].minor.yy179->pPrior = yymsp[-2].minor.yy179;
+ }
+ yygotominor.yy179 = yymsp[0].minor.yy179;
+}
+#line 2477 "parse.c"
+ break;
+ case 103:
+#line 299 "parse.y"
+{yygotominor.yy372 = TK_UNION;}
+#line 2482 "parse.c"
+ /* No destructor defined for UNION */
+ break;
+ case 104:
+#line 300 "parse.y"
+{yygotominor.yy372 = TK_ALL;}
+#line 2488 "parse.c"
+ /* No destructor defined for UNION */
+ /* No destructor defined for ALL */
+ break;
+ case 105:
+#line 301 "parse.y"
+{yygotominor.yy372 = TK_INTERSECT;}
+#line 2495 "parse.c"
+ /* No destructor defined for INTERSECT */
+ break;
+ case 106:
+#line 302 "parse.y"
+{yygotominor.yy372 = TK_EXCEPT;}
+#line 2501 "parse.c"
+ /* No destructor defined for EXCEPT */
+ break;
+ case 107:
+#line 304 "parse.y"
+{
+ yygotominor.yy179 = sqliteSelectNew(yymsp[-6].minor.yy322,yymsp[-5].minor.yy307,yymsp[-4].minor.yy242,yymsp[-3].minor.yy322,yymsp[-2].minor.yy242,yymsp[-1].minor.yy322,yymsp[-7].minor.yy372,yymsp[0].minor.yy124.limit,yymsp[0].minor.yy124.offset);
+}
+#line 2509 "parse.c"
+ /* No destructor defined for SELECT */
+ break;
+ case 108:
+#line 312 "parse.y"
+{yygotominor.yy372 = 1;}
+#line 2515 "parse.c"
+ /* No destructor defined for DISTINCT */
+ break;
+ case 109:
+#line 313 "parse.y"
+{yygotominor.yy372 = 0;}
+#line 2521 "parse.c"
+ /* No destructor defined for ALL */
+ break;
+ case 110:
+#line 314 "parse.y"
+{yygotominor.yy372 = 0;}
+#line 2527 "parse.c"
+ break;
+ case 111:
+#line 325 "parse.y"
+{yygotominor.yy322 = yymsp[-1].minor.yy322;}
+#line 2532 "parse.c"
+ /* No destructor defined for COMMA */
+ break;
+ case 112:
+#line 326 "parse.y"
+{yygotominor.yy322 = 0;}
+#line 2538 "parse.c"
+ break;
+ case 113:
+#line 327 "parse.y"
+{
+ yygotominor.yy322 = sqliteExprListAppend(yymsp[-2].minor.yy322,yymsp[-1].minor.yy242,yymsp[0].minor.yy298.n?&yymsp[0].minor.yy298:0);
+}
+#line 2545 "parse.c"
+ break;
+ case 114:
+#line 330 "parse.y"
+{
+ yygotominor.yy322 = sqliteExprListAppend(yymsp[-1].minor.yy322, sqliteExpr(TK_ALL, 0, 0, 0), 0);
+}
+#line 2552 "parse.c"
+ /* No destructor defined for STAR */
+ break;
+ case 115:
+#line 333 "parse.y"
+{
+ Expr *pRight = sqliteExpr(TK_ALL, 0, 0, 0);
+ Expr *pLeft = sqliteExpr(TK_ID, 0, 0, &yymsp[-2].minor.yy298);
+ yygotominor.yy322 = sqliteExprListAppend(yymsp[-3].minor.yy322, sqliteExpr(TK_DOT, pLeft, pRight, 0), 0);
+}
+#line 2562 "parse.c"
+ /* No destructor defined for DOT */
+ /* No destructor defined for STAR */
+ break;
+ case 116:
+#line 343 "parse.y"
+{ yygotominor.yy298 = yymsp[0].minor.yy298; }
+#line 2569 "parse.c"
+ /* No destructor defined for AS */
+ break;
+ case 117:
+#line 344 "parse.y"
+{ yygotominor.yy298 = yymsp[0].minor.yy298; }
+#line 2575 "parse.c"
+ break;
+ case 118:
+#line 345 "parse.y"
+{ yygotominor.yy298.n = 0; }
+#line 2580 "parse.c"
+ break;
+ case 119:
+#line 357 "parse.y"
+{yygotominor.yy307 = sqliteMalloc(sizeof(*yygotominor.yy307));}
+#line 2585 "parse.c"
+ break;
+ case 120:
+#line 358 "parse.y"
+{yygotominor.yy307 = yymsp[0].minor.yy307;}
+#line 2590 "parse.c"
+ /* No destructor defined for FROM */
+ break;
+ case 121:
+#line 363 "parse.y"
+{
+ yygotominor.yy307 = yymsp[-1].minor.yy307;
+ if( yygotominor.yy307 && yygotominor.yy307->nSrc>0 ) yygotominor.yy307->a[yygotominor.yy307->nSrc-1].jointype = yymsp[0].minor.yy372;
+}
+#line 2599 "parse.c"
+ break;
+ case 122:
+#line 367 "parse.y"
+{yygotominor.yy307 = 0;}
+#line 2604 "parse.c"
+ break;
+ case 123:
+#line 368 "parse.y"
+{
+ yygotominor.yy307 = sqliteSrcListAppend(yymsp[-5].minor.yy307,&yymsp[-4].minor.yy298,&yymsp[-3].minor.yy298);
+ if( yymsp[-2].minor.yy298.n ) sqliteSrcListAddAlias(yygotominor.yy307,&yymsp[-2].minor.yy298);
+ if( yymsp[-1].minor.yy242 ){
+ if( yygotominor.yy307 && yygotominor.yy307->nSrc>1 ){ yygotominor.yy307->a[yygotominor.yy307->nSrc-2].pOn = yymsp[-1].minor.yy242; }
+ else { sqliteExprDelete(yymsp[-1].minor.yy242); }
+ }
+ if( yymsp[0].minor.yy320 ){
+ if( yygotominor.yy307 && yygotominor.yy307->nSrc>1 ){ yygotominor.yy307->a[yygotominor.yy307->nSrc-2].pUsing = yymsp[0].minor.yy320; }
+ else { sqliteIdListDelete(yymsp[0].minor.yy320); }
+ }
+}
+#line 2620 "parse.c"
+ break;
+ case 124:
+#line 381 "parse.y"
+{
+ yygotominor.yy307 = sqliteSrcListAppend(yymsp[-6].minor.yy307,0,0);
+ yygotominor.yy307->a[yygotominor.yy307->nSrc-1].pSelect = yymsp[-4].minor.yy179;
+ if( yymsp[-2].minor.yy298.n ) sqliteSrcListAddAlias(yygotominor.yy307,&yymsp[-2].minor.yy298);
+ if( yymsp[-1].minor.yy242 ){
+ if( yygotominor.yy307 && yygotominor.yy307->nSrc>1 ){ yygotominor.yy307->a[yygotominor.yy307->nSrc-2].pOn = yymsp[-1].minor.yy242; }
+ else { sqliteExprDelete(yymsp[-1].minor.yy242); }
+ }
+ if( yymsp[0].minor.yy320 ){
+ if( yygotominor.yy307 && yygotominor.yy307->nSrc>1 ){ yygotominor.yy307->a[yygotominor.yy307->nSrc-2].pUsing = yymsp[0].minor.yy320; }
+ else { sqliteIdListDelete(yymsp[0].minor.yy320); }
+ }
+}
+#line 2637 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for RP */
+ break;
+ case 125:
+#line 401 "parse.y"
+{yygotominor.yy179 = yymsp[0].minor.yy179;}
+#line 2644 "parse.c"
+ break;
+ case 126:
+#line 402 "parse.y"
+{
+ yygotominor.yy179 = sqliteSelectNew(0,yymsp[0].minor.yy307,0,0,0,0,0,-1,0);
+}
+#line 2651 "parse.c"
+ break;
+ case 127:
+#line 407 "parse.y"
+{yygotominor.yy298.z=0; yygotominor.yy298.n=0;}
+#line 2656 "parse.c"
+ break;
+ case 128:
+#line 408 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy298;}
+#line 2661 "parse.c"
+ /* No destructor defined for DOT */
+ break;
+ case 129:
+#line 412 "parse.y"
+{ yygotominor.yy372 = JT_INNER; }
+#line 2667 "parse.c"
+ /* No destructor defined for COMMA */
+ break;
+ case 130:
+#line 413 "parse.y"
+{ yygotominor.yy372 = JT_INNER; }
+#line 2673 "parse.c"
+ /* No destructor defined for JOIN */
+ break;
+ case 131:
+#line 414 "parse.y"
+{ yygotominor.yy372 = sqliteJoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
+#line 2679 "parse.c"
+ /* No destructor defined for JOIN */
+ break;
+ case 132:
+#line 415 "parse.y"
+{ yygotominor.yy372 = sqliteJoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy298,0); }
+#line 2685 "parse.c"
+ /* No destructor defined for JOIN */
+ break;
+ case 133:
+#line 417 "parse.y"
+{ yygotominor.yy372 = sqliteJoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy298,&yymsp[-1].minor.yy298); }
+#line 2691 "parse.c"
+ /* No destructor defined for JOIN */
+ break;
+ case 134:
+#line 421 "parse.y"
+{yygotominor.yy242 = yymsp[0].minor.yy242;}
+#line 2697 "parse.c"
+ /* No destructor defined for ON */
+ break;
+ case 135:
+#line 422 "parse.y"
+{yygotominor.yy242 = 0;}
+#line 2703 "parse.c"
+ break;
+ case 136:
+#line 426 "parse.y"
+{yygotominor.yy320 = yymsp[-1].minor.yy320;}
+#line 2708 "parse.c"
+ /* No destructor defined for USING */
+ /* No destructor defined for LP */
+ /* No destructor defined for RP */
+ break;
+ case 137:
+#line 427 "parse.y"
+{yygotominor.yy320 = 0;}
+#line 2716 "parse.c"
+ break;
+ case 138:
+#line 437 "parse.y"
+{yygotominor.yy322 = 0;}
+#line 2721 "parse.c"
+ break;
+ case 139:
+#line 438 "parse.y"
+{yygotominor.yy322 = yymsp[0].minor.yy322;}
+#line 2726 "parse.c"
+ /* No destructor defined for ORDER */
+ /* No destructor defined for BY */
+ break;
+ case 140:
+#line 439 "parse.y"
+{
+ yygotominor.yy322 = sqliteExprListAppend(yymsp[-4].minor.yy322,yymsp[-2].minor.yy242,0);
+ if( yygotominor.yy322 ) yygotominor.yy322->a[yygotominor.yy322->nExpr-1].sortOrder = yymsp[-1].minor.yy372+yymsp[0].minor.yy372;
+}
+#line 2736 "parse.c"
+ /* No destructor defined for COMMA */
+ break;
+ case 141:
+#line 443 "parse.y"
+{
+ yygotominor.yy322 = sqliteExprListAppend(0,yymsp[-2].minor.yy242,0);
+ if( yygotominor.yy322 ) yygotominor.yy322->a[0].sortOrder = yymsp[-1].minor.yy372+yymsp[0].minor.yy372;
+}
+#line 2745 "parse.c"
+ break;
+ case 142:
+#line 447 "parse.y"
+{yygotominor.yy242 = yymsp[0].minor.yy242;}
+#line 2750 "parse.c"
+ break;
+ case 143:
+#line 452 "parse.y"
+{yygotominor.yy372 = STQLITE_SO_ASC;}
+#line 2755 "parse.c"
+ /* No destructor defined for ASC */
+ break;
+ case 144:
+#line 453 "parse.y"
+{yygotominor.yy372 = STQLITE_SO_DESC;}
+#line 2761 "parse.c"
+ /* No destructor defined for DESC */
+ break;
+ case 145:
+#line 454 "parse.y"
+{yygotominor.yy372 = STQLITE_SO_ASC;}
+#line 2767 "parse.c"
+ break;
+ case 146:
+#line 455 "parse.y"
+{yygotominor.yy372 = STQLITE_SO_UNK;}
+#line 2772 "parse.c"
+ break;
+ case 147:
+#line 456 "parse.y"
+{yygotominor.yy372 = sqliteCollateType(yymsp[0].minor.yy298.z, yymsp[0].minor.yy298.n);}
+#line 2777 "parse.c"
+ /* No destructor defined for COLLATE */
+ break;
+ case 148:
+#line 460 "parse.y"
+{yygotominor.yy322 = 0;}
+#line 2783 "parse.c"
+ break;
+ case 149:
+#line 461 "parse.y"
+{yygotominor.yy322 = yymsp[0].minor.yy322;}
+#line 2788 "parse.c"
+ /* No destructor defined for GROUP */
+ /* No destructor defined for BY */
+ break;
+ case 150:
+#line 465 "parse.y"
+{yygotominor.yy242 = 0;}
+#line 2795 "parse.c"
+ break;
+ case 151:
+#line 466 "parse.y"
+{yygotominor.yy242 = yymsp[0].minor.yy242;}
+#line 2800 "parse.c"
+ /* No destructor defined for HAVING */
+ break;
+ case 152:
+#line 469 "parse.y"
+{yygotominor.yy124.limit = -1; yygotominor.yy124.offset = 0;}
+#line 2806 "parse.c"
+ break;
+ case 153:
+#line 470 "parse.y"
+{yygotominor.yy124.limit = yymsp[0].minor.yy372; yygotominor.yy124.offset = 0;}
+#line 2811 "parse.c"
+ /* No destructor defined for LIMIT */
+ break;
+ case 154:
+#line 472 "parse.y"
+{yygotominor.yy124.limit = yymsp[-2].minor.yy372; yygotominor.yy124.offset = yymsp[0].minor.yy372;}
+#line 2817 "parse.c"
+ /* No destructor defined for LIMIT */
+ /* No destructor defined for OFFSET */
+ break;
+ case 155:
+#line 474 "parse.y"
+{yygotominor.yy124.limit = yymsp[0].minor.yy372; yygotominor.yy124.offset = yymsp[-2].minor.yy372;}
+#line 2824 "parse.c"
+ /* No destructor defined for LIMIT */
+ /* No destructor defined for COMMA */
+ break;
+ case 156:
+#line 478 "parse.y"
+{
+ sqliteDeleteFrom(pParse, sqliteSrcListAppend(0,&yymsp[-2].minor.yy298,&yymsp[-1].minor.yy298), yymsp[0].minor.yy242);
+}
+#line 2833 "parse.c"
+ /* No destructor defined for DELETE */
+ /* No destructor defined for FROM */
+ break;
+ case 157:
+#line 485 "parse.y"
+{yygotominor.yy242 = 0;}
+#line 2840 "parse.c"
+ break;
+ case 158:
+#line 486 "parse.y"
+{yygotominor.yy242 = yymsp[0].minor.yy242;}
+#line 2845 "parse.c"
+ /* No destructor defined for WHERE */
+ break;
+ case 159:
+#line 494 "parse.y"
+{sqliteUpdate(pParse,sqliteSrcListAppend(0,&yymsp[-4].minor.yy298,&yymsp[-3].minor.yy298),yymsp[-1].minor.yy322,yymsp[0].minor.yy242,yymsp[-5].minor.yy372);}
+#line 2851 "parse.c"
+ /* No destructor defined for UPDATE */
+ /* No destructor defined for SET */
+ break;
+ case 160:
+#line 497 "parse.y"
+{yygotominor.yy322 = sqliteExprListAppend(yymsp[-4].minor.yy322,yymsp[0].minor.yy242,&yymsp[-2].minor.yy298);}
+#line 2858 "parse.c"
+ /* No destructor defined for COMMA */
+ /* No destructor defined for EQ */
+ break;
+ case 161:
+#line 498 "parse.y"
+{yygotominor.yy322 = sqliteExprListAppend(0,yymsp[0].minor.yy242,&yymsp[-2].minor.yy298);}
+#line 2865 "parse.c"
+ /* No destructor defined for EQ */
+ break;
+ case 162:
+#line 504 "parse.y"
+{sqliteInsert(pParse, sqliteSrcListAppend(0,&yymsp[-6].minor.yy298,&yymsp[-5].minor.yy298), yymsp[-1].minor.yy322, 0, yymsp[-4].minor.yy320, yymsp[-8].minor.yy372);}
+#line 2871 "parse.c"
+ /* No destructor defined for INTO */
+ /* No destructor defined for VALUES */
+ /* No destructor defined for LP */
+ /* No destructor defined for RP */
+ break;
+ case 163:
+#line 506 "parse.y"
+{sqliteInsert(pParse, sqliteSrcListAppend(0,&yymsp[-3].minor.yy298,&yymsp[-2].minor.yy298), 0, yymsp[0].minor.yy179, yymsp[-1].minor.yy320, yymsp[-5].minor.yy372);}
+#line 2880 "parse.c"
+ /* No destructor defined for INTO */
+ break;
+ case 164:
+#line 509 "parse.y"
+{yygotominor.yy372 = yymsp[0].minor.yy372;}
+#line 2886 "parse.c"
+ /* No destructor defined for INSERT */
+ break;
+ case 165:
+#line 510 "parse.y"
+{yygotominor.yy372 = OE_Replace;}
+#line 2892 "parse.c"
+ /* No destructor defined for REPLACE */
+ break;
+ case 166:
+#line 516 "parse.y"
+{yygotominor.yy322 = sqliteExprListAppend(yymsp[-2].minor.yy322,yymsp[0].minor.yy242,0);}
+#line 2898 "parse.c"
+ /* No destructor defined for COMMA */
+ break;
+ case 167:
+#line 517 "parse.y"
+{yygotominor.yy322 = sqliteExprListAppend(0,yymsp[0].minor.yy242,0);}
+#line 2904 "parse.c"
+ break;
+ case 168:
+#line 524 "parse.y"
+{yygotominor.yy320 = 0;}
+#line 2909 "parse.c"
+ break;
+ case 169:
+#line 525 "parse.y"
+{yygotominor.yy320 = yymsp[-1].minor.yy320;}
+#line 2914 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for RP */
+ break;
+ case 170:
+#line 526 "parse.y"
+{yygotominor.yy320 = sqliteIdListAppend(yymsp[-2].minor.yy320,&yymsp[0].minor.yy298);}
+#line 2921 "parse.c"
+ /* No destructor defined for COMMA */
+ break;
+ case 171:
+#line 527 "parse.y"
+{yygotominor.yy320 = sqliteIdListAppend(0,&yymsp[0].minor.yy298);}
+#line 2927 "parse.c"
+ break;
+ case 172:
+#line 535 "parse.y"
+{yygotominor.yy242 = yymsp[-1].minor.yy242; sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
+#line 2932 "parse.c"
+ break;
+ case 173:
+#line 536 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_NULL, 0, 0, &yymsp[0].minor.yy0);}
+#line 2937 "parse.c"
+ break;
+ case 174:
+#line 537 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+#line 2942 "parse.c"
+ break;
+ case 175:
+#line 538 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_ID, 0, 0, &yymsp[0].minor.yy0);}
+#line 2947 "parse.c"
+ break;
+ case 176:
+#line 539 "parse.y"
+{
+ Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &yymsp[-2].minor.yy298);
+ Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &yymsp[0].minor.yy298);
+ yygotominor.yy242 = sqliteExpr(TK_DOT, temp1, temp2, 0);
+}
+#line 2956 "parse.c"
+ /* No destructor defined for DOT */
+ break;
+ case 177:
+#line 544 "parse.y"
+{
+ Expr *temp1 = sqliteExpr(TK_ID, 0, 0, &yymsp[-4].minor.yy298);
+ Expr *temp2 = sqliteExpr(TK_ID, 0, 0, &yymsp[-2].minor.yy298);
+ Expr *temp3 = sqliteExpr(TK_ID, 0, 0, &yymsp[0].minor.yy298);
+ Expr *temp4 = sqliteExpr(TK_DOT, temp2, temp3, 0);
+ yygotominor.yy242 = sqliteExpr(TK_DOT, temp1, temp4, 0);
+}
+#line 2968 "parse.c"
+ /* No destructor defined for DOT */
+ /* No destructor defined for DOT */
+ break;
+ case 178:
+#line 551 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_INTEGER, 0, 0, &yymsp[0].minor.yy0);}
+#line 2975 "parse.c"
+ break;
+ case 179:
+#line 552 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_FLOAT, 0, 0, &yymsp[0].minor.yy0);}
+#line 2980 "parse.c"
+ break;
+ case 180:
+#line 553 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_STRING, 0, 0, &yymsp[0].minor.yy0);}
+#line 2985 "parse.c"
+ break;
+ case 181:
+#line 554 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_VARIABLE, 0, 0, &yymsp[0].minor.yy0);
+ if( yygotominor.yy242 ) yygotominor.yy242->iTable = ++pParse->nVar;
+}
+#line 2993 "parse.c"
+ break;
+ case 182:
+#line 558 "parse.y"
+{
+ yygotominor.yy242 = sqliteExprFunction(yymsp[-1].minor.yy322, &yymsp[-3].minor.yy0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+}
+#line 3001 "parse.c"
+ /* No destructor defined for LP */
+ break;
+ case 183:
+#line 562 "parse.y"
+{
+ yygotominor.yy242 = sqliteExprFunction(0, &yymsp[-3].minor.yy0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
+}
+#line 3010 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for STAR */
+ break;
+ case 184:
+#line 566 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_AND, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3017 "parse.c"
+ /* No destructor defined for AND */
+ break;
+ case 185:
+#line 567 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_OR, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3023 "parse.c"
+ /* No destructor defined for OR */
+ break;
+ case 186:
+#line 568 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_LT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3029 "parse.c"
+ /* No destructor defined for LT */
+ break;
+ case 187:
+#line 569 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_GT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3035 "parse.c"
+ /* No destructor defined for GT */
+ break;
+ case 188:
+#line 570 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_LE, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3041 "parse.c"
+ /* No destructor defined for LE */
+ break;
+ case 189:
+#line 571 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_GE, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3047 "parse.c"
+ /* No destructor defined for GE */
+ break;
+ case 190:
+#line 572 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_NE, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3053 "parse.c"
+ /* No destructor defined for NE */
+ break;
+ case 191:
+#line 573 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_EQ, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3059 "parse.c"
+ /* No destructor defined for EQ */
+ break;
+ case 192:
+#line 574 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_BITAND, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3065 "parse.c"
+ /* No destructor defined for BITAND */
+ break;
+ case 193:
+#line 575 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_BITOR, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3071 "parse.c"
+ /* No destructor defined for BITOR */
+ break;
+ case 194:
+#line 576 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_LSHIFT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3077 "parse.c"
+ /* No destructor defined for LSHIFT */
+ break;
+ case 195:
+#line 577 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_RSHIFT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3083 "parse.c"
+ /* No destructor defined for RSHIFT */
+ break;
+ case 196:
+#line 578 "parse.y"
+{
+ ExprList *pList = sqliteExprListAppend(0, yymsp[0].minor.yy242, 0);
+ pList = sqliteExprListAppend(pList, yymsp[-2].minor.yy242, 0);
+ yygotominor.yy242 = sqliteExprFunction(pList, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->op = yymsp[-1].minor.yy372;
+ sqliteExprSpan(yygotominor.yy242, &yymsp[-2].minor.yy242->span, &yymsp[0].minor.yy242->span);
+}
+#line 3095 "parse.c"
+ break;
+ case 197:
+#line 585 "parse.y"
+{
+ ExprList *pList = sqliteExprListAppend(0, yymsp[0].minor.yy242, 0);
+ pList = sqliteExprListAppend(pList, yymsp[-3].minor.yy242, 0);
+ yygotominor.yy242 = sqliteExprFunction(pList, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->op = yymsp[-1].minor.yy372;
+ yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy242->span,&yymsp[0].minor.yy242->span);
+}
+#line 3107 "parse.c"
+ /* No destructor defined for NOT */
+ break;
+ case 198:
+#line 594 "parse.y"
+{yygotominor.yy372 = TK_LIKE;}
+#line 3113 "parse.c"
+ /* No destructor defined for LIKE */
+ break;
+ case 199:
+#line 595 "parse.y"
+{yygotominor.yy372 = TK_GLOB;}
+#line 3119 "parse.c"
+ /* No destructor defined for GLOB */
+ break;
+ case 200:
+#line 596 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_PLUS, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3125 "parse.c"
+ /* No destructor defined for PLUS */
+ break;
+ case 201:
+#line 597 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_MINUS, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3131 "parse.c"
+ /* No destructor defined for MINUS */
+ break;
+ case 202:
+#line 598 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_STAR, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3137 "parse.c"
+ /* No destructor defined for STAR */
+ break;
+ case 203:
+#line 599 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_SLASH, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3143 "parse.c"
+ /* No destructor defined for SLASH */
+ break;
+ case 204:
+#line 600 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_REM, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3149 "parse.c"
+ /* No destructor defined for REM */
+ break;
+ case 205:
+#line 601 "parse.y"
+{yygotominor.yy242 = sqliteExpr(TK_CONCAT, yymsp[-2].minor.yy242, yymsp[0].minor.yy242, 0);}
+#line 3155 "parse.c"
+ /* No destructor defined for CONCAT */
+ break;
+ case 206:
+#line 602 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_ISNULL, yymsp[-1].minor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy242->span,&yymsp[0].minor.yy0);
+}
+#line 3164 "parse.c"
+ break;
+ case 207:
+#line 606 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_ISNULL, yymsp[-2].minor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy242->span,&yymsp[0].minor.yy0);
+}
+#line 3172 "parse.c"
+ /* No destructor defined for IS */
+ break;
+ case 208:
+#line 610 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_NOTNULL, yymsp[-1].minor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy242->span,&yymsp[0].minor.yy0);
+}
+#line 3181 "parse.c"
+ break;
+ case 209:
+#line 614 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_NOTNULL, yymsp[-2].minor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy242->span,&yymsp[0].minor.yy0);
+}
+#line 3189 "parse.c"
+ /* No destructor defined for NOT */
+ break;
+ case 210:
+#line 618 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_NOTNULL, yymsp[-3].minor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy242->span,&yymsp[0].minor.yy0);
+}
+#line 3198 "parse.c"
+ /* No destructor defined for IS */
+ /* No destructor defined for NOT */
+ break;
+ case 211:
+#line 622 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_NOT, yymsp[0].minor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
+}
+#line 3208 "parse.c"
+ break;
+ case 212:
+#line 626 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_BITNOT, yymsp[0].minor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
+}
+#line 3216 "parse.c"
+ break;
+ case 213:
+#line 630 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_UMINUS, yymsp[0].minor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
+}
+#line 3224 "parse.c"
+ break;
+ case 214:
+#line 634 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_UPLUS, yymsp[0].minor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy242->span);
+}
+#line 3232 "parse.c"
+ break;
+ case 215:
+#line 638 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_SELECT, 0, 0, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->pSelect = yymsp[-1].minor.yy179;
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);
+}
+#line 3241 "parse.c"
+ break;
+ case 216:
+#line 643 "parse.y"
+{
+ ExprList *pList = sqliteExprListAppend(0, yymsp[-2].minor.yy242, 0);
+ pList = sqliteExprListAppend(pList, yymsp[0].minor.yy242, 0);
+ yygotominor.yy242 = sqliteExpr(TK_BETWEEN, yymsp[-4].minor.yy242, 0, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->pList = pList;
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,&yymsp[0].minor.yy242->span);
+}
+#line 3252 "parse.c"
+ /* No destructor defined for BETWEEN */
+ /* No destructor defined for AND */
+ break;
+ case 217:
+#line 650 "parse.y"
+{
+ ExprList *pList = sqliteExprListAppend(0, yymsp[-2].minor.yy242, 0);
+ pList = sqliteExprListAppend(pList, yymsp[0].minor.yy242, 0);
+ yygotominor.yy242 = sqliteExpr(TK_BETWEEN, yymsp[-5].minor.yy242, 0, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->pList = pList;
+ yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-5].minor.yy242->span,&yymsp[0].minor.yy242->span);
+}
+#line 3266 "parse.c"
+ /* No destructor defined for NOT */
+ /* No destructor defined for BETWEEN */
+ /* No destructor defined for AND */
+ break;
+ case 218:
+#line 658 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-4].minor.yy242, 0, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->pList = yymsp[-1].minor.yy322;
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,&yymsp[0].minor.yy0);
+}
+#line 3278 "parse.c"
+ /* No destructor defined for IN */
+ /* No destructor defined for LP */
+ break;
+ case 219:
+#line 663 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-4].minor.yy242, 0, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->pSelect = yymsp[-1].minor.yy179;
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,&yymsp[0].minor.yy0);
+}
+#line 3289 "parse.c"
+ /* No destructor defined for IN */
+ /* No destructor defined for LP */
+ break;
+ case 220:
+#line 668 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-5].minor.yy242, 0, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->pList = yymsp[-1].minor.yy322;
+ yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-5].minor.yy242->span,&yymsp[0].minor.yy0);
+}
+#line 3301 "parse.c"
+ /* No destructor defined for NOT */
+ /* No destructor defined for IN */
+ /* No destructor defined for LP */
+ break;
+ case 221:
+#line 674 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-5].minor.yy242, 0, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->pSelect = yymsp[-1].minor.yy179;
+ yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-5].minor.yy242->span,&yymsp[0].minor.yy0);
+}
+#line 3314 "parse.c"
+ /* No destructor defined for NOT */
+ /* No destructor defined for IN */
+ /* No destructor defined for LP */
+ break;
+ case 222:
+#line 680 "parse.y"
+{
+ SrcList *pSrc = sqliteSrcListAppend(0, &yymsp[-1].minor.yy298, &yymsp[0].minor.yy298);
+ yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-3].minor.yy242, 0, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-3].minor.yy242->span,yymsp[0].minor.yy298.z?&yymsp[0].minor.yy298:&yymsp[-1].minor.yy298);
+}
+#line 3327 "parse.c"
+ /* No destructor defined for IN */
+ break;
+ case 223:
+#line 686 "parse.y"
+{
+ SrcList *pSrc = sqliteSrcListAppend(0, &yymsp[-1].minor.yy298, &yymsp[0].minor.yy298);
+ yygotominor.yy242 = sqliteExpr(TK_IN, yymsp[-4].minor.yy242, 0, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->pSelect = sqliteSelectNew(0,pSrc,0,0,0,0,0,-1,0);
+ yygotominor.yy242 = sqliteExpr(TK_NOT, yygotominor.yy242, 0, 0);
+ sqliteExprSpan(yygotominor.yy242,&yymsp[-4].minor.yy242->span,yymsp[0].minor.yy298.z?&yymsp[0].minor.yy298:&yymsp[-1].minor.yy298);
+}
+#line 3339 "parse.c"
+ /* No destructor defined for NOT */
+ /* No destructor defined for IN */
+ break;
+ case 224:
+#line 696 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_CASE, yymsp[-3].minor.yy242, yymsp[-1].minor.yy242, 0);
+ if( yygotominor.yy242 ) yygotominor.yy242->pList = yymsp[-2].minor.yy322;
+ sqliteExprSpan(yygotominor.yy242, &yymsp[-4].minor.yy0, &yymsp[0].minor.yy0);
+}
+#line 3350 "parse.c"
+ break;
+ case 225:
+#line 703 "parse.y"
+{
+ yygotominor.yy322 = sqliteExprListAppend(yymsp[-4].minor.yy322, yymsp[-2].minor.yy242, 0);
+ yygotominor.yy322 = sqliteExprListAppend(yygotominor.yy322, yymsp[0].minor.yy242, 0);
+}
+#line 3358 "parse.c"
+ /* No destructor defined for WHEN */
+ /* No destructor defined for THEN */
+ break;
+ case 226:
+#line 707 "parse.y"
+{
+ yygotominor.yy322 = sqliteExprListAppend(0, yymsp[-2].minor.yy242, 0);
+ yygotominor.yy322 = sqliteExprListAppend(yygotominor.yy322, yymsp[0].minor.yy242, 0);
+}
+#line 3368 "parse.c"
+ /* No destructor defined for WHEN */
+ /* No destructor defined for THEN */
+ break;
+ case 227:
+#line 712 "parse.y"
+{yygotominor.yy242 = yymsp[0].minor.yy242;}
+#line 3375 "parse.c"
+ /* No destructor defined for ELSE */
+ break;
+ case 228:
+#line 713 "parse.y"
+{yygotominor.yy242 = 0;}
+#line 3381 "parse.c"
+ break;
+ case 229:
+#line 715 "parse.y"
+{yygotominor.yy242 = yymsp[0].minor.yy242;}
+#line 3386 "parse.c"
+ break;
+ case 230:
+#line 716 "parse.y"
+{yygotominor.yy242 = 0;}
+#line 3391 "parse.c"
+ break;
+ case 231:
+#line 724 "parse.y"
+{yygotominor.yy322 = sqliteExprListAppend(yymsp[-2].minor.yy322,yymsp[0].minor.yy242,0);}
+#line 3396 "parse.c"
+ /* No destructor defined for COMMA */
+ break;
+ case 232:
+#line 725 "parse.y"
+{yygotominor.yy322 = sqliteExprListAppend(0,yymsp[0].minor.yy242,0);}
+#line 3402 "parse.c"
+ break;
+ case 233:
+#line 726 "parse.y"
+{yygotominor.yy242 = yymsp[0].minor.yy242;}
+#line 3407 "parse.c"
+ break;
+ case 234:
+#line 727 "parse.y"
+{yygotominor.yy242 = 0;}
+#line 3412 "parse.c"
+ break;
+ case 235:
+#line 732 "parse.y"
+{
+ SrcList *pSrc = sqliteSrcListAppend(0, &yymsp[-5].minor.yy298, &yymsp[-4].minor.yy298);
+ if( yymsp[-9].minor.yy372!=OE_None ) yymsp[-9].minor.yy372 = yymsp[0].minor.yy372;
+ if( yymsp[-9].minor.yy372==OE_Default) yymsp[-9].minor.yy372 = OE_Abort;
+ sqliteCreateIndex(pParse, &yymsp[-7].minor.yy298, pSrc, yymsp[-2].minor.yy320, yymsp[-9].minor.yy372, &yymsp[-10].minor.yy0, &yymsp[-1].minor.yy0);
+}
+#line 3422 "parse.c"
+ /* No destructor defined for INDEX */
+ /* No destructor defined for ON */
+ /* No destructor defined for LP */
+ break;
+ case 236:
+#line 740 "parse.y"
+{ yygotominor.yy372 = OE_Abort; }
+#line 3430 "parse.c"
+ /* No destructor defined for UNITQUE */
+ break;
+ case 237:
+#line 741 "parse.y"
+{ yygotominor.yy372 = OE_None; }
+#line 3436 "parse.c"
+ break;
+ case 238:
+#line 749 "parse.y"
+{yygotominor.yy320 = 0;}
+#line 3441 "parse.c"
+ break;
+ case 239:
+#line 750 "parse.y"
+{yygotominor.yy320 = yymsp[-1].minor.yy320;}
+#line 3446 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for RP */
+ break;
+ case 240:
+#line 751 "parse.y"
+{yygotominor.yy320 = sqliteIdListAppend(yymsp[-2].minor.yy320,&yymsp[0].minor.yy298);}
+#line 3453 "parse.c"
+ /* No destructor defined for COMMA */
+ break;
+ case 241:
+#line 752 "parse.y"
+{yygotominor.yy320 = sqliteIdListAppend(0,&yymsp[0].minor.yy298);}
+#line 3459 "parse.c"
+ break;
+ case 242:
+#line 753 "parse.y"
+{yygotominor.yy298 = yymsp[-1].minor.yy298;}
+#line 3464 "parse.c"
+ /* No destructor defined for sortorder */
+ break;
+ case 243:
+#line 758 "parse.y"
+{
+ sqliteDropIndex(pParse, sqliteSrcListAppend(0,&yymsp[-1].minor.yy298,&yymsp[0].minor.yy298));
+}
+#line 3472 "parse.c"
+ /* No destructor defined for DROP */
+ /* No destructor defined for INDEX */
+ break;
+ case 244:
+#line 766 "parse.y"
+{sqliteCopy(pParse,sqliteSrcListAppend(0,&yymsp[-6].minor.yy298,&yymsp[-5].minor.yy298),&yymsp[-3].minor.yy298,&yymsp[0].minor.yy0,yymsp[-7].minor.yy372);}
+#line 3479 "parse.c"
+ /* No destructor defined for COPY */
+ /* No destructor defined for FROM */
+ /* No destructor defined for USING */
+ /* No destructor defined for DELIMITERS */
+ break;
+ case 245:
+#line 768 "parse.y"
+{sqliteCopy(pParse,sqliteSrcListAppend(0,&yymsp[-3].minor.yy298,&yymsp[-2].minor.yy298),&yymsp[0].minor.yy298,0,yymsp[-4].minor.yy372);}
+#line 3488 "parse.c"
+ /* No destructor defined for COPY */
+ /* No destructor defined for FROM */
+ break;
+ case 246:
+#line 772 "parse.y"
+{sqliteVacuum(pParse,0);}
+#line 3495 "parse.c"
+ /* No destructor defined for VACUUM */
+ break;
+ case 247:
+#line 773 "parse.y"
+{sqliteVacuum(pParse,&yymsp[0].minor.yy298);}
+#line 3501 "parse.c"
+ /* No destructor defined for VACUUM */
+ break;
+ case 248:
+#line 777 "parse.y"
+{sqlitePragma(pParse,&yymsp[-2].minor.yy298,&yymsp[0].minor.yy298,0);}
+#line 3507 "parse.c"
+ /* No destructor defined for PRAGMA */
+ /* No destructor defined for EQ */
+ break;
+ case 249:
+#line 778 "parse.y"
+{sqlitePragma(pParse,&yymsp[-2].minor.yy298,&yymsp[0].minor.yy0,0);}
+#line 3514 "parse.c"
+ /* No destructor defined for PRAGMA */
+ /* No destructor defined for EQ */
+ break;
+ case 250:
+#line 779 "parse.y"
+{sqlitePragma(pParse,&yymsp[-2].minor.yy298,&yymsp[0].minor.yy298,0);}
+#line 3521 "parse.c"
+ /* No destructor defined for PRAGMA */
+ /* No destructor defined for EQ */
+ break;
+ case 251:
+#line 780 "parse.y"
+{sqlitePragma(pParse,&yymsp[-2].minor.yy298,&yymsp[0].minor.yy298,1);}
+#line 3528 "parse.c"
+ /* No destructor defined for PRAGMA */
+ /* No destructor defined for EQ */
+ break;
+ case 252:
+#line 781 "parse.y"
+{sqlitePragma(pParse,&yymsp[-3].minor.yy298,&yymsp[-1].minor.yy298,0);}
+#line 3535 "parse.c"
+ /* No destructor defined for PRAGMA */
+ /* No destructor defined for LP */
+ /* No destructor defined for RP */
+ break;
+ case 253:
+#line 782 "parse.y"
+{sqlitePragma(pParse,&yymsp[0].minor.yy298,&yymsp[0].minor.yy298,0);}
+#line 3543 "parse.c"
+ /* No destructor defined for PRAGMA */
+ break;
+ case 254:
+#line 783 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy298;}
+#line 3549 "parse.c"
+ /* No destructor defined for plus_opt */
+ break;
+ case 255:
+#line 784 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy298;}
+#line 3555 "parse.c"
+ /* No destructor defined for MINUS */
+ break;
+ case 256:
+#line 785 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy0;}
+#line 3561 "parse.c"
+ break;
+ case 257:
+#line 786 "parse.y"
+{yygotominor.yy298 = yymsp[0].minor.yy0;}
+#line 3566 "parse.c"
+ break;
+ case 258:
+ /* No destructor defined for PLUS */
+ break;
+ case 259:
+ break;
+ case 260:
+#line 792 "parse.y"
+{
+ Token all;
+ all.z = yymsp[-4].minor.yy0.z;
+ all.n = (yymsp[0].minor.yy0.z - yymsp[-4].minor.yy0.z) + yymsp[0].minor.yy0.n;
+ sqliteFinishTrigger(pParse, yymsp[-1].minor.yy19, &all);
+}
+#line 3581 "parse.c"
+ /* No destructor defined for trigger_decl */
+ /* No destructor defined for BEGIN */
+ break;
+ case 261:
+#line 800 "parse.y"
+{
+ SrcList *pTab = sqliteSrcListAppend(0, &yymsp[-3].minor.yy298, &yymsp[-2].minor.yy298);
+ sqliteBeginTrigger(pParse, &yymsp[-7].minor.yy298, yymsp[-6].minor.yy372, yymsp[-5].minor.yy290.a, yymsp[-5].minor.yy290.b, pTab, yymsp[-1].minor.yy372, yymsp[0].minor.yy182, yymsp[-9].minor.yy372);
+}
+#line 3591 "parse.c"
+ /* No destructor defined for TRIGGER */
+ /* No destructor defined for ON */
+ break;
+ case 262:
+#line 806 "parse.y"
+{ yygotominor.yy372 = TK_BEFORE; }
+#line 3598 "parse.c"
+ /* No destructor defined for BEFORE */
+ break;
+ case 263:
+#line 807 "parse.y"
+{ yygotominor.yy372 = TK_AFTER; }
+#line 3604 "parse.c"
+ /* No destructor defined for AFTER */
+ break;
+ case 264:
+#line 808 "parse.y"
+{ yygotominor.yy372 = TK_INSTEAD;}
+#line 3610 "parse.c"
+ /* No destructor defined for INSTEAD */
+ /* No destructor defined for OF */
+ break;
+ case 265:
+#line 809 "parse.y"
+{ yygotominor.yy372 = TK_BEFORE; }
+#line 3617 "parse.c"
+ break;
+ case 266:
+#line 813 "parse.y"
+{ yygotominor.yy290.a = TK_DELETE; yygotominor.yy290.b = 0; }
+#line 3622 "parse.c"
+ /* No destructor defined for DELETE */
+ break;
+ case 267:
+#line 814 "parse.y"
+{ yygotominor.yy290.a = TK_INSERT; yygotominor.yy290.b = 0; }
+#line 3628 "parse.c"
+ /* No destructor defined for INSERT */
+ break;
+ case 268:
+#line 815 "parse.y"
+{ yygotominor.yy290.a = TK_UPDATE; yygotominor.yy290.b = 0;}
+#line 3634 "parse.c"
+ /* No destructor defined for UPDATE */
+ break;
+ case 269:
+#line 816 "parse.y"
+{yygotominor.yy290.a = TK_UPDATE; yygotominor.yy290.b = yymsp[0].minor.yy320; }
+#line 3640 "parse.c"
+ /* No destructor defined for UPDATE */
+ /* No destructor defined for OF */
+ break;
+ case 270:
+#line 819 "parse.y"
+{ yygotominor.yy372 = TK_ROW; }
+#line 3647 "parse.c"
+ break;
+ case 271:
+#line 820 "parse.y"
+{ yygotominor.yy372 = TK_ROW; }
+#line 3652 "parse.c"
+ /* No destructor defined for FOR */
+ /* No destructor defined for EACH */
+ /* No destructor defined for ROW */
+ break;
+ case 272:
+#line 821 "parse.y"
+{ yygotominor.yy372 = TK_STATEMENT; }
+#line 3660 "parse.c"
+ /* No destructor defined for FOR */
+ /* No destructor defined for EACH */
+ /* No destructor defined for STATEMENT */
+ break;
+ case 273:
+#line 824 "parse.y"
+{ yygotominor.yy182 = 0; }
+#line 3668 "parse.c"
+ break;
+ case 274:
+#line 825 "parse.y"
+{ yygotominor.yy182 = yymsp[0].minor.yy242; }
+#line 3673 "parse.c"
+ /* No destructor defined for WHEN */
+ break;
+ case 275:
+#line 829 "parse.y"
+{
+ yymsp[-2].minor.yy19->pNext = yymsp[0].minor.yy19;
+ yygotominor.yy19 = yymsp[-2].minor.yy19;
+}
+#line 3682 "parse.c"
+ /* No destructor defined for SEMI */
+ break;
+ case 276:
+#line 833 "parse.y"
+{ yygotominor.yy19 = 0; }
+#line 3688 "parse.c"
+ break;
+ case 277:
+#line 839 "parse.y"
+{ yygotominor.yy19 = sqliteTriggerUpdateStep(&yymsp[-3].minor.yy298, yymsp[-1].minor.yy322, yymsp[0].minor.yy242, yymsp[-4].minor.yy372); }
+#line 3693 "parse.c"
+ /* No destructor defined for UPDATE */
+ /* No destructor defined for SET */
+ break;
+ case 278:
+#line 844 "parse.y"
+{yygotominor.yy19 = sqliteTriggerInsertStep(&yymsp[-5].minor.yy298, yymsp[-4].minor.yy320, yymsp[-1].minor.yy322, 0, yymsp[-7].minor.yy372);}
+#line 3700 "parse.c"
+ /* No destructor defined for INTO */
+ /* No destructor defined for VALUES */
+ /* No destructor defined for LP */
+ /* No destructor defined for RP */
+ break;
+ case 279:
+#line 847 "parse.y"
+{yygotominor.yy19 = sqliteTriggerInsertStep(&yymsp[-2].minor.yy298, yymsp[-1].minor.yy320, 0, yymsp[0].minor.yy179, yymsp[-4].minor.yy372);}
+#line 3709 "parse.c"
+ /* No destructor defined for INTO */
+ break;
+ case 280:
+#line 851 "parse.y"
+{yygotominor.yy19 = sqliteTriggerDeleteStep(&yymsp[-1].minor.yy298, yymsp[0].minor.yy242);}
+#line 3715 "parse.c"
+ /* No destructor defined for DELETE */
+ /* No destructor defined for FROM */
+ break;
+ case 281:
+#line 854 "parse.y"
+{yygotominor.yy19 = sqliteTriggerSelectStep(yymsp[0].minor.yy179); }
+#line 3722 "parse.c"
+ break;
+ case 282:
+#line 857 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, 0);
+ yygotominor.yy242->iColumn = OE_Ignore;
+ sqliteExprSpan(yygotominor.yy242, &yymsp[-3].minor.yy0, &yymsp[0].minor.yy0);
+}
+#line 3731 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for IGNORE */
+ break;
+ case 283:
+#line 862 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy298);
+ yygotominor.yy242->iColumn = OE_Rollback;
+ sqliteExprSpan(yygotominor.yy242, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+}
+#line 3742 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for ROLLBACK */
+ /* No destructor defined for COMMA */
+ break;
+ case 284:
+#line 867 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy298);
+ yygotominor.yy242->iColumn = OE_Abort;
+ sqliteExprSpan(yygotominor.yy242, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+}
+#line 3754 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for ABORT */
+ /* No destructor defined for COMMA */
+ break;
+ case 285:
+#line 872 "parse.y"
+{
+ yygotominor.yy242 = sqliteExpr(TK_RAISE, 0, 0, &yymsp[-1].minor.yy298);
+ yygotominor.yy242->iColumn = OE_Fail;
+ sqliteExprSpan(yygotominor.yy242, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
+}
+#line 3766 "parse.c"
+ /* No destructor defined for LP */
+ /* No destructor defined for FAIL */
+ /* No destructor defined for COMMA */
+ break;
+ case 286:
+#line 879 "parse.y"
+{
+ sqliteDropTrigger(pParse,sqliteSrcListAppend(0,&yymsp[-1].minor.yy298,&yymsp[0].minor.yy298));
+}
+#line 3776 "parse.c"
+ /* No destructor defined for DROP */
+ /* No destructor defined for TRIGGER */
+ break;
+ case 287:
+#line 884 "parse.y"
+{
+ sqliteAttach(pParse, &yymsp[-3].minor.yy298, &yymsp[-1].minor.yy298, &yymsp[0].minor.yy298);
+}
+#line 3785 "parse.c"
+ /* No destructor defined for ATTACH */
+ /* No destructor defined for database_kw_opt */
+ /* No destructor defined for AS */
+ break;
+ case 288:
+#line 888 "parse.y"
+{ yygotominor.yy298 = yymsp[0].minor.yy298; }
+#line 3793 "parse.c"
+ /* No destructor defined for USING */
+ break;
+ case 289:
+#line 889 "parse.y"
+{ yygotominor.yy298.z = 0; yygotominor.yy298.n = 0; }
+#line 3799 "parse.c"
+ break;
+ case 290:
+ /* No destructor defined for DATABASE */
+ break;
+ case 291:
+ break;
+ case 292:
+#line 895 "parse.y"
+{
+ sqliteDetach(pParse, &yymsp[0].minor.yy298);
+}
+#line 3811 "parse.c"
+ /* No destructor defined for DETACH */
+ /* No destructor defined for database_kw_opt */
+ break;
+ };
+ yygoto = yyRuleInfo[yyruleno].lhs;
+ yysize = yyRuleInfo[yyruleno].nrhs;
+ yypParser->yyidx -= yysize;
+ yyact = yy_tqfind_reduce_action(yypParser,yygoto);
+ if( yyact < YYNSTATE ){
+ yy_shift(yypParser,yyact,yygoto,&yygotominor);
+ }else if( yyact == YYNSTATE + YYNRULE + 1 ){
+ yy_accept(yypParser);
+ }
+}
+
+/*
+** The following code executes when the parse fails
+*/
+static void yy_parse_failed(
+ yyParser *yypParser /* The parser */
+){
+ sqliteParserARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser fails */
+ sqliteParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/*
+** The following code executes when a syntax error first occurs.
+*/
+static void yy_syntax_error(
+ yyParser *yypParser, /* The parser */
+ int yymajor, /* The major type of the error token */
+ YYMINORTYPE yyminor /* The minor type of the error token */
+){
+ sqliteParserARG_FETCH;
+#define TOKEN (yyminor.yy0)
+#line 23 "parse.y"
+
+ if( pParse->zErrMsg==0 ){
+ if( TOKEN.z[0] ){
+ sqliteErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
+ }else{
+ sqliteErrorMsg(pParse, "incomplete SQL statement");
+ }
+ }
+
+#line 3865 "parse.c"
+ sqliteParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/*
+** The following is executed when the parser accepts
+*/
+static void yy_accept(
+ yyParser *yypParser /* The parser */
+){
+ sqliteParserARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser accepts */
+ sqliteParserARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/* The main parser program.
+** The first argument is a pointer to a structure obtained from
+** "sqliteParserAlloc" which describes the current state of the parser.
+** The second argument is the major token number. The third is
+** the minor token. The fourth optional argument is whatever the
+** user wants (and specified in the grammar) and is available for
+** use by the action routines.
+**
+** Inputs:
+** <ul>
+** <li> A pointer to the parser (an opaque structure.)
+** <li> The major token number.
+** <li> The minor token number.
+** <li> An option argument of a grammar-specified type.
+** </ul>
+**
+** Outputs:
+** None.
+*/
+void sqliteParser(
+ void *yyp, /* The parser */
+ int yymajor, /* The major token code number */
+ sqliteParserTOKENTYPE yyminor /* The value for the token */
+ sqliteParserARG_PDECL /* Optional %extra_argument parameter */
+){
+ YYMINORTYPE yyminorunion;
+ int yyact; /* The parser action. */
+ int yyendofinput; /* True if we are at the end of input */
+ int yyerrorhit = 0; /* True if yymajor has invoked an error */
+ yyParser *yypParser; /* The parser */
+
+ /* (re)initialize the parser, if necessary */
+ yypParser = (yyParser*)yyp;
+ if( yypParser->yyidx<0 ){
+ if( yymajor==0 ) return;
+ yypParser->yyidx = 0;
+ yypParser->yyerrcnt = -1;
+ yypParser->yystack[0].stateno = 0;
+ yypParser->yystack[0].major = 0;
+ }
+ yyminorunion.yy0 = yyminor;
+ yyendofinput = (yymajor==0);
+ sqliteParserARG_STORE;
+
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
+ }
+#endif
+
+ do{
+ yyact = yy_tqfind_shift_action(yypParser,yymajor);
+ if( yyact<YYNSTATE ){
+ yy_shift(yypParser,yyact,yymajor,&yyminorunion);
+ yypParser->yyerrcnt--;
+ if( yyendofinput && yypParser->yyidx>=0 ){
+ yymajor = 0;
+ }else{
+ yymajor = YYNOCODE;
+ }
+ }else if( yyact < YYNSTATE + YYNRULE ){
+ yy_reduce(yypParser,yyact-YYNSTATE);
+ }else if( yyact == YY_ERROR_ACTION ){
+ int yymx;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
+ }
+#endif
+#ifdef YYERRORSYMBOL
+ /* A syntax error has occurred.
+ ** The response to an error depends upon whether or not the
+ ** grammar defines an error token "ERROR".
+ **
+ ** This is what we do if the grammar does define ERROR:
+ **
+ ** * Call the %syntax_error function.
+ **
+ ** * Begin popping the stack until we enter a state where
+ ** it is legal to shift the error symbol, then shift
+ ** the error symbol.
+ **
+ ** * Set the error count to three.
+ **
+ ** * Begin accepting and shifting new tokens. No new error
+ ** processing will occur until three tokens have been
+ ** shifted successfully.
+ **
+ */
+ if( yypParser->yyerrcnt<0 ){
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ }
+ yymx = yypParser->yystack[yypParser->yyidx].major;
+ if( yymx==YYERRORSYMBOL || yyerrorhit ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sDiscard input token %s\n",
+ yyTracePrompt,yyTokenName[yymajor]);
+ }
+#endif
+ yy_destructor(yymajor,&yyminorunion);
+ yymajor = YYNOCODE;
+ }else{
+ while(
+ yypParser->yyidx >= 0 &&
+ yymx != YYERRORSYMBOL &&
+ (yyact = yy_tqfind_shift_action(yypParser,YYERRORSYMBOL)) >= YYNSTATE
+ ){
+ yy_pop_parser_stack(yypParser);
+ }
+ if( yypParser->yyidx < 0 || yymajor==0 ){
+ yy_destructor(yymajor,&yyminorunion);
+ yy_parse_failed(yypParser);
+ yymajor = YYNOCODE;
+ }else if( yymx!=YYERRORSYMBOL ){
+ YYMINORTYPE u2;
+ u2.YYERRSYMDT = 0;
+ yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
+ }
+ }
+ yypParser->yyerrcnt = 3;
+ yyerrorhit = 1;
+#else /* YYERRORSYMBOL is not defined */
+ /* This is what we do if the grammar does not define ERROR:
+ **
+ ** * Report an error message, and throw away the input token.
+ **
+ ** * If the input token is $, then fail the parse.
+ **
+ ** As before, subsequent error messages are suppressed until
+ ** three input tokens have been successfully shifted.
+ */
+ if( yypParser->yyerrcnt<=0 ){
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ }
+ yypParser->yyerrcnt = 3;
+ yy_destructor(yymajor,&yyminorunion);
+ if( yyendofinput ){
+ yy_parse_failed(yypParser);
+ }
+ yymajor = YYNOCODE;
+#endif
+ }else{
+ yy_accept(yypParser);
+ yymajor = YYNOCODE;
+ }
+ }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
+ return;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/parse.h b/tqtinterface/qt4/src/3rdparty/sqlite/parse.h
new file mode 100644
index 0000000..3594928
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/parse.h
@@ -0,0 +1,130 @@
+#define TK_END_OF_FILE 1
+#define TK_ILLEGAL 2
+#define TK_SPACE 3
+#define TK_UNCLOSED_STRING 4
+#define TK_COMMENT 5
+#define TK_FUNCTION 6
+#define TK_COLUMN 7
+#define TK_AGG_FUNCTION 8
+#define TK_SEMI 9
+#define TK_EXPLAIN 10
+#define TK_BEGIN 11
+#define TK_TRANSACTION 12
+#define TK_COMMIT 13
+#define TK_END 14
+#define TK_ROLLBACK 15
+#define TK_CREATE 16
+#define TK_TABLE 17
+#define TK_TEMP 18
+#define TK_LP 19
+#define TK_RP 20
+#define TK_AS 21
+#define TK_COMMA 22
+#define TK_ID 23
+#define TK_ABORT 24
+#define TK_AFTER 25
+#define TK_ASC 26
+#define TK_ATTACH 27
+#define TK_BEFORE 28
+#define TK_CASCADE 29
+#define TK_CLUSTER 30
+#define TK_CONFLICT 31
+#define TK_COPY 32
+#define TK_DATABASE 33
+#define TK_DEFERRED 34
+#define TK_DELIMITERS 35
+#define TK_DESC 36
+#define TK_DETACH 37
+#define TK_EACH 38
+#define TK_FAIL 39
+#define TK_FOR 40
+#define TK_GLOB 41
+#define TK_IGNORE 42
+#define TK_IMMEDIATE 43
+#define TK_INITIALLY 44
+#define TK_INSTEAD 45
+#define TK_LIKE 46
+#define TK_MATCH 47
+#define TK_KEY 48
+#define TK_OF 49
+#define TK_OFFSET 50
+#define TK_PRAGMA 51
+#define TK_RAISE 52
+#define TK_REPLACE 53
+#define TK_RESTRICT 54
+#define TK_ROW 55
+#define TK_STATEMENT 56
+#define TK_TRIGGER 57
+#define TK_VACUUM 58
+#define TK_VIEW 59
+#define TK_OR 60
+#define TK_AND 61
+#define TK_NOT 62
+#define TK_EQ 63
+#define TK_NE 64
+#define TK_ISNULL 65
+#define TK_NOTNULL 66
+#define TK_IS 67
+#define TK_BETWEEN 68
+#define TK_IN 69
+#define TK_GT 70
+#define TK_GE 71
+#define TK_LT 72
+#define TK_LE 73
+#define TK_BITAND 74
+#define TK_BITOR 75
+#define TK_LSHIFT 76
+#define TK_RSHIFT 77
+#define TK_PLUS 78
+#define TK_MINUS 79
+#define TK_STAR 80
+#define TK_SLASH 81
+#define TK_REM 82
+#define TK_CONCAT 83
+#define TK_UMINUS 84
+#define TK_UPLUS 85
+#define TK_BITNOT 86
+#define TK_STRING 87
+#define TK_JOIN_KW 88
+#define TK_INTEGER 89
+#define TK_CONSTRAINT 90
+#define TK_DEFAULT 91
+#define TK_FLOAT 92
+#define TK_NULL 93
+#define TK_PRIMARY 94
+#define TK_UNITQUE 95
+#define TK_CHECK 96
+#define TK_REFERENCES 97
+#define TK_COLLATE 98
+#define TK_ON 99
+#define TK_DELETE 100
+#define TK_UPDATE 101
+#define TK_INSERT 102
+#define TK_SET 103
+#define TK_DEFERRABLE 104
+#define TK_FOREIGN 105
+#define TK_DROP 106
+#define TK_UNION 107
+#define TK_ALL 108
+#define TK_INTERSECT 109
+#define TK_EXCEPT 110
+#define TK_SELECT 111
+#define TK_DISTINCT 112
+#define TK_DOT 113
+#define TK_FROM 114
+#define TK_JOIN 115
+#define TK_USING 116
+#define TK_ORDER 117
+#define TK_BY 118
+#define TK_GROUP 119
+#define TK_HAVING 120
+#define TK_LIMIT 121
+#define TK_WHERE 122
+#define TK_INTO 123
+#define TK_VALUES 124
+#define TK_VARIABLE 125
+#define TK_CASE 126
+#define TK_WHEN 127
+#define TK_THEN 128
+#define TK_ELSE 129
+#define TK_INDEX 130
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/pragma.c b/tqtinterface/qt4/src/3rdparty/sqlite/pragma.c
new file mode 100644
index 0000000..a176972
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/pragma.c
@@ -0,0 +1,699 @@
+/*
+** 2003 April 6
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains code used to implement the PRAGMA command.
+**
+** $Id: pragma.c,v 1.18 2004/02/22 20:05:01 drh Exp $
+*/
+#include "sqliteInt.h"
+#include <ctype.h>
+
+/*
+** Interpret the given string as a boolean value.
+*/
+static int getBoolean(const char *z){
+ static char *azTrue[] = { "yes", "on", "true" };
+ int i;
+ if( z[0]==0 ) return 0;
+ if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){
+ return atoi(z);
+ }
+ for(i=0; i<sizeof(azTrue)/sizeof(azTrue[0]); i++){
+ if( sqliteStrICmp(z,azTrue[i])==0 ) return 1;
+ }
+ return 0;
+}
+
+/*
+** Interpret the given string as a safety level. Return 0 for OFF,
+** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or
+** unrecognized string argument.
+**
+** Note that the values returned are one less that the values that
+** should be passed into sqliteBtreeSetSafetyLevel(). The is done
+** to support legacy SQL code. The safety level used to be boolean
+** and older scripts may have used numbers 0 for OFF and 1 for ON.
+*/
+static int getSafetyLevel(char *z){
+ static const struct {
+ const char *zWord;
+ int val;
+ } aKey[] = {
+ { "no", 0 },
+ { "off", 0 },
+ { "false", 0 },
+ { "yes", 1 },
+ { "on", 1 },
+ { "true", 1 },
+ { "full", 2 },
+ };
+ int i;
+ if( z[0]==0 ) return 1;
+ if( isdigit(z[0]) || (z[0]=='-' && isdigit(z[1])) ){
+ return atoi(z);
+ }
+ for(i=0; i<sizeof(aKey)/sizeof(aKey[0]); i++){
+ if( sqliteStrICmp(z,aKey[i].zWord)==0 ) return aKey[i].val;
+ }
+ return 1;
+}
+
+/*
+** Interpret the given string as a temp db location. Return 1 for file
+** backed temporary databases, 2 for the Red-Black tree in memory database
+** and 0 to use the compile-time default.
+*/
+static int getTempStore(char *z){
+ if( z[0]>='0' || z[0]<='2' ){
+ return z[0] - '0';
+ }else if( sqliteStrICmp(z, "file")==0 ){
+ return 1;
+ }else if( sqliteStrICmp(z, "memory")==0 ){
+ return 2;
+ }else{
+ return 0;
+ }
+}
+
+/*
+** Check to see if zRight and zLeft refer to a pragma that queries
+** or changes one of the flags in db->flags. Return 1 if so and 0 if not.
+** Also, implement the pragma.
+*/
+static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){
+ static const struct {
+ const char *zName; /* Name of the pragma */
+ int tqmask; /* Mask for the db->flags value */
+ } aPragma[] = {
+ { "vdbe_trace", STQLITE_VdbeTrace },
+ { "full_column_names", STQLITE_FullColNames },
+ { "short_column_names", STQLITE_ShortColNames },
+ { "show_datatypes", STQLITE_ReportTypes },
+ { "count_changes", STQLITE_CountRows },
+ { "empty_result_callbacks", STQLITE_NullCallback },
+ };
+ int i;
+ for(i=0; i<sizeof(aPragma)/sizeof(aPragma[0]); i++){
+ if( sqliteStrICmp(zLeft, aPragma[i].zName)==0 ){
+ sqlite *db = pParse->db;
+ Vdbe *v;
+ if( strcmp(zLeft,zRight)==0 && (v = sqliteGetVdbe(pParse))!=0 ){
+ sqliteVdbeOp3(v, OP_ColumnName, 0, 1, aPragma[i].zName, P3_STATIC);
+ sqliteVdbeOp3(v, OP_ColumnName, 1, 0, "boolean", P3_STATIC);
+ sqliteVdbeCode(v, OP_Integer, (db->flags & aPragma[i].tqmask)!=0, 0,
+ OP_Callback, 1, 0,
+ 0);
+ }else if( getBoolean(zRight) ){
+ db->flags |= aPragma[i].tqmask;
+ }else{
+ db->flags &= ~aPragma[i].tqmask;
+ }
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+** Process a pragma statement.
+**
+** Pragmas are of this form:
+**
+** PRAGMA id = value
+**
+** The identifier might also be a string. The value is a string, and
+** identifier, or a number. If minusFlag is true, then the value is
+** a number that was preceded by a minus sign.
+*/
+void sqlitePragma(Parse *pParse, Token *pLeft, Token *pRight, int minusFlag){
+ char *zLeft = 0;
+ char *zRight = 0;
+ sqlite *db = pParse->db;
+ Vdbe *v = sqliteGetVdbe(pParse);
+ if( v==0 ) return;
+
+ zLeft = sqliteStrNDup(pLeft->z, pLeft->n);
+ sqliteDequote(zLeft);
+ if( minusFlag ){
+ zRight = 0;
+ sqliteSetNString(&zRight, "-", 1, pRight->z, pRight->n, 0);
+ }else{
+ zRight = sqliteStrNDup(pRight->z, pRight->n);
+ sqliteDequote(zRight);
+ }
+ if( sqliteAuthCheck(pParse, STQLITE_PRAGMA, zLeft, zRight, 0) ){
+ sqliteFree(zLeft);
+ sqliteFree(zRight);
+ return;
+ }
+
+ /*
+ ** PRAGMA default_cache_size
+ ** PRAGMA default_cache_size=N
+ **
+ ** The first form reports the current persistent setting for the
+ ** page cache size. The value returned is the maximum number of
+ ** pages in the page cache. The second form sets both the current
+ ** page cache size value and the persistent page cache size value
+ ** stored in the database file.
+ **
+ ** The default cache size is stored in meta-value 2 of page 1 of the
+ ** database file. The cache size is actually the absolute value of
+ ** this memory location. The sign of meta-value 2 determines the
+ ** synchronous setting. A negative value means synchronous is off
+ ** and a positive value means synchronous is on.
+ */
+ if( sqliteStrICmp(zLeft,"default_cache_size")==0 ){
+ static VdbeOpList getCacheSize[] = {
+ { OP_ReadCookie, 0, 2, 0},
+ { OP_AbsValue, 0, 0, 0},
+ { OP_Dup, 0, 0, 0},
+ { OP_Integer, 0, 0, 0},
+ { OP_Ne, 0, 6, 0},
+ { OP_Integer, 0, 0, 0}, /* 5 */
+ { OP_ColumnName, 0, 1, "cache_size"},
+ { OP_Callback, 1, 0, 0},
+ };
+ int addr;
+ if( pRight->z==pLeft->z ){
+ addr = sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
+ sqliteVdbeChangeP1(v, addr+5, MAX_PAGES);
+ }else{
+ int size = atoi(zRight);
+ if( size<0 ) size = -size;
+ sqliteBeginWriteOperation(pParse, 0, 0);
+ sqliteVdbeAddOp(v, OP_Integer, size, 0);
+ sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
+ addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+ sqliteVdbeAddOp(v, OP_Ge, 0, addr+3);
+ sqliteVdbeAddOp(v, OP_Negative, 0, 0);
+ sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
+ sqliteEndWriteOperation(pParse);
+ db->cache_size = db->cache_size<0 ? -size : size;
+ sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
+ }
+ }else
+
+ /*
+ ** PRAGMA cache_size
+ ** PRAGMA cache_size=N
+ **
+ ** The first form reports the current local setting for the
+ ** page cache size. The local setting can be different from
+ ** the persistent cache size value that is stored in the database
+ ** file itself. The value returned is the maximum number of
+ ** pages in the page cache. The second form sets the local
+ ** page cache size value. It does not change the persistent
+ ** cache size stored on the disk so the cache size will revert
+ ** to its default value when the database is closed and reopened.
+ ** N should be a positive integer.
+ */
+ if( sqliteStrICmp(zLeft,"cache_size")==0 ){
+ static VdbeOpList getCacheSize[] = {
+ { OP_ColumnName, 0, 1, "cache_size"},
+ { OP_Callback, 1, 0, 0},
+ };
+ if( pRight->z==pLeft->z ){
+ int size = db->cache_size;;
+ if( size<0 ) size = -size;
+ sqliteVdbeAddOp(v, OP_Integer, size, 0);
+ sqliteVdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize);
+ }else{
+ int size = atoi(zRight);
+ if( size<0 ) size = -size;
+ if( db->cache_size<0 ) size = -size;
+ db->cache_size = size;
+ sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
+ }
+ }else
+
+ /*
+ ** PRAGMA default_synchronous
+ ** PRAGMA default_synchronous=ON|OFF|NORMAL|FULL
+ **
+ ** The first form returns the persistent value of the "synchronous" setting
+ ** that is stored in the database. This is the synchronous setting that
+ ** is used whenever the database is opened unless overridden by a separate
+ ** "synchronous" pragma. The second form changes the persistent and the
+ ** local synchronous setting to the value given.
+ **
+ ** If synchronous is OFF, STQLite does not attempt any fsync() systems calls
+ ** to make sure data is committed to disk. Write operations are very fast,
+ ** but a power failure can leave the database in an inconsistent state.
+ ** If synchronous is ON or NORMAL, STQLite will do an fsync() system call to
+ ** make sure data is being written to disk. The risk of corruption due to
+ ** a power loss in this mode is negligible but non-zero. If synchronous
+ ** is FULL, extra fsync()s occur to reduce the risk of corruption to near
+ ** zero, but with a write performance penalty. The default mode is NORMAL.
+ */
+ if( sqliteStrICmp(zLeft,"default_synchronous")==0 ){
+ static VdbeOpList getSync[] = {
+ { OP_ColumnName, 0, 1, "synchronous"},
+ { OP_ReadCookie, 0, 3, 0},
+ { OP_Dup, 0, 0, 0},
+ { OP_If, 0, 0, 0}, /* 3 */
+ { OP_ReadCookie, 0, 2, 0},
+ { OP_Integer, 0, 0, 0},
+ { OP_Lt, 0, 5, 0},
+ { OP_AddImm, 1, 0, 0},
+ { OP_Callback, 1, 0, 0},
+ { OP_Halt, 0, 0, 0},
+ { OP_AddImm, -1, 0, 0}, /* 10 */
+ { OP_Callback, 1, 0, 0}
+ };
+ if( pRight->z==pLeft->z ){
+ int addr = sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
+ sqliteVdbeChangeP2(v, addr+3, addr+10);
+ }else{
+ int addr;
+ int size = db->cache_size;
+ if( size<0 ) size = -size;
+ sqliteBeginWriteOperation(pParse, 0, 0);
+ sqliteVdbeAddOp(v, OP_ReadCookie, 0, 2);
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
+ addr = sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+ sqliteVdbeAddOp(v, OP_Ne, 0, addr+3);
+ sqliteVdbeAddOp(v, OP_AddImm, MAX_PAGES, 0);
+ sqliteVdbeAddOp(v, OP_AbsValue, 0, 0);
+ db->safety_level = getSafetyLevel(zRight)+1;
+ if( db->safety_level==1 ){
+ sqliteVdbeAddOp(v, OP_Negative, 0, 0);
+ size = -size;
+ }
+ sqliteVdbeAddOp(v, OP_SetCookie, 0, 2);
+ sqliteVdbeAddOp(v, OP_Integer, db->safety_level, 0);
+ sqliteVdbeAddOp(v, OP_SetCookie, 0, 3);
+ sqliteEndWriteOperation(pParse);
+ db->cache_size = size;
+ sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
+ sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
+ }
+ }else
+
+ /*
+ ** PRAGMA synchronous
+ ** PRAGMA synchronous=OFF|ON|NORMAL|FULL
+ **
+ ** Return or set the local value of the synchronous flag. Changing
+ ** the local value does not make changes to the disk file and the
+ ** default value will be restored the next time the database is
+ ** opened.
+ */
+ if( sqliteStrICmp(zLeft,"synchronous")==0 ){
+ static VdbeOpList getSync[] = {
+ { OP_ColumnName, 0, 1, "synchronous"},
+ { OP_Callback, 1, 0, 0},
+ };
+ if( pRight->z==pLeft->z ){
+ sqliteVdbeAddOp(v, OP_Integer, db->safety_level-1, 0);
+ sqliteVdbeAddOpList(v, ArraySize(getSync), getSync);
+ }else{
+ int size = db->cache_size;
+ if( size<0 ) size = -size;
+ db->safety_level = getSafetyLevel(zRight)+1;
+ if( db->safety_level==1 ) size = -size;
+ db->cache_size = size;
+ sqliteBtreeSetCacheSize(db->aDb[0].pBt, db->cache_size);
+ sqliteBtreeSetSafetyLevel(db->aDb[0].pBt, db->safety_level);
+ }
+ }else
+
+#ifndef NDEBUG
+ if( sqliteStrICmp(zLeft, "trigger_overhead_test")==0 ){
+ if( getBoolean(zRight) ){
+ always_code_trigger_setup = 1;
+ }else{
+ always_code_trigger_setup = 0;
+ }
+ }else
+#endif
+
+ if( flagPragma(pParse, zLeft, zRight) ){
+ /* The flagPragma() call also generates any necessary code */
+ }else
+
+ if( sqliteStrICmp(zLeft, "table_info")==0 ){
+ Table *pTab;
+ pTab = sqliteFindTable(db, zRight, 0);
+ if( pTab ){
+ static VdbeOpList tableInfoPreface[] = {
+ { OP_ColumnName, 0, 0, "cid"},
+ { OP_ColumnName, 1, 0, "name"},
+ { OP_ColumnName, 2, 0, "type"},
+ { OP_ColumnName, 3, 0, "notnull"},
+ { OP_ColumnName, 4, 0, "dflt_value"},
+ { OP_ColumnName, 5, 1, "pk"},
+ };
+ int i;
+ sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
+ sqliteViewGetColumnNames(pParse, pTab);
+ for(i=0; i<pTab->nCol; i++){
+ sqliteVdbeAddOp(v, OP_Integer, i, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[i].zName, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0,
+ pTab->aCol[i].zType ? pTab->aCol[i].zType : "numeric", 0);
+ sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].notNull, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0,
+ pTab->aCol[i].zDflt, P3_STATIC);
+ sqliteVdbeAddOp(v, OP_Integer, pTab->aCol[i].isPrimKey, 0);
+ sqliteVdbeAddOp(v, OP_Callback, 6, 0);
+ }
+ }
+ }else
+
+ if( sqliteStrICmp(zLeft, "index_info")==0 ){
+ Index *pIdx;
+ Table *pTab;
+ pIdx = sqliteFindIndex(db, zRight, 0);
+ if( pIdx ){
+ static VdbeOpList tableInfoPreface[] = {
+ { OP_ColumnName, 0, 0, "seqno"},
+ { OP_ColumnName, 1, 0, "cid"},
+ { OP_ColumnName, 2, 1, "name"},
+ };
+ int i;
+ pTab = pIdx->pTable;
+ sqliteVdbeAddOpList(v, ArraySize(tableInfoPreface), tableInfoPreface);
+ for(i=0; i<pIdx->nColumn; i++){
+ int cnum = pIdx->aiColumn[i];
+ sqliteVdbeAddOp(v, OP_Integer, i, 0);
+ sqliteVdbeAddOp(v, OP_Integer, cnum, 0);
+ assert( pTab->nCol>cnum );
+ sqliteVdbeOp3(v, OP_String, 0, 0, pTab->aCol[cnum].zName, 0);
+ sqliteVdbeAddOp(v, OP_Callback, 3, 0);
+ }
+ }
+ }else
+
+ if( sqliteStrICmp(zLeft, "index_list")==0 ){
+ Index *pIdx;
+ Table *pTab;
+ pTab = sqliteFindTable(db, zRight, 0);
+ if( pTab ){
+ v = sqliteGetVdbe(pParse);
+ pIdx = pTab->pIndex;
+ }
+ if( pTab && pIdx ){
+ int i = 0;
+ static VdbeOpList indexListPreface[] = {
+ { OP_ColumnName, 0, 0, "seq"},
+ { OP_ColumnName, 1, 0, "name"},
+ { OP_ColumnName, 2, 1, "unique"},
+ };
+
+ sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
+ while(pIdx){
+ sqliteVdbeAddOp(v, OP_Integer, i, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0, pIdx->zName, 0);
+ sqliteVdbeAddOp(v, OP_Integer, pIdx->onError!=OE_None, 0);
+ sqliteVdbeAddOp(v, OP_Callback, 3, 0);
+ ++i;
+ pIdx = pIdx->pNext;
+ }
+ }
+ }else
+
+ if( sqliteStrICmp(zLeft, "foreign_key_list")==0 ){
+ FKey *pFK;
+ Table *pTab;
+ pTab = sqliteFindTable(db, zRight, 0);
+ if( pTab ){
+ v = sqliteGetVdbe(pParse);
+ pFK = pTab->pFKey;
+ }
+ if( pTab && pFK ){
+ int i = 0;
+ static VdbeOpList indexListPreface[] = {
+ { OP_ColumnName, 0, 0, "id"},
+ { OP_ColumnName, 1, 0, "seq"},
+ { OP_ColumnName, 2, 0, "table"},
+ { OP_ColumnName, 3, 0, "from"},
+ { OP_ColumnName, 4, 1, "to"},
+ };
+
+ sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
+ while(pFK){
+ int j;
+ for(j=0; j<pFK->nCol; j++){
+ sqliteVdbeAddOp(v, OP_Integer, i, 0);
+ sqliteVdbeAddOp(v, OP_Integer, j, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0, pFK->zTo, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0,
+ pTab->aCol[pFK->aCol[j].iFrom].zName, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0, pFK->aCol[j].zCol, 0);
+ sqliteVdbeAddOp(v, OP_Callback, 5, 0);
+ }
+ ++i;
+ pFK = pFK->pNextFrom;
+ }
+ }
+ }else
+
+ if( sqliteStrICmp(zLeft, "database_list")==0 ){
+ int i;
+ static VdbeOpList indexListPreface[] = {
+ { OP_ColumnName, 0, 0, "seq"},
+ { OP_ColumnName, 1, 0, "name"},
+ { OP_ColumnName, 2, 1, "file"},
+ };
+
+ sqliteVdbeAddOpList(v, ArraySize(indexListPreface), indexListPreface);
+ for(i=0; i<db->nDb; i++){
+ if( db->aDb[i].pBt==0 ) continue;
+ assert( db->aDb[i].zName!=0 );
+ sqliteVdbeAddOp(v, OP_Integer, i, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0, db->aDb[i].zName, 0);
+ sqliteVdbeOp3(v, OP_String, 0, 0,
+ sqliteBtreeGetFilename(db->aDb[i].pBt), 0);
+ sqliteVdbeAddOp(v, OP_Callback, 3, 0);
+ }
+ }else
+
+
+ /*
+ ** PRAGMA temp_store
+ ** PRAGMA temp_store = "default"|"memory"|"file"
+ **
+ ** Return or set the local value of the temp_store flag. Changing
+ ** the local value does not make changes to the disk file and the default
+ ** value will be restored the next time the database is opened.
+ **
+ ** Note that it is possible for the library compile-time options to
+ ** override this setting
+ */
+ if( sqliteStrICmp(zLeft, "temp_store")==0 ){
+ static VdbeOpList getTmpDbLoc[] = {
+ { OP_ColumnName, 0, 1, "temp_store"},
+ { OP_Callback, 1, 0, 0},
+ };
+ if( pRight->z==pLeft->z ){
+ sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
+ sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
+ }else{
+ if (&db->aDb[1].pBt != 0) {
+ sqliteErrorMsg(pParse, "The temporary database already exists - "
+ "its location cannot now be changed");
+ } else {
+ db->temp_store = getTempStore(zRight);
+ }
+ }
+ }else
+
+ /*
+ ** PRAGMA default_temp_store
+ ** PRAGMA default_temp_store = "default"|"memory"|"file"
+ **
+ ** Return or set the value of the persistent temp_store flag (as
+ ** well as the value currently in force).
+ **
+ ** Note that it is possible for the library compile-time options to
+ ** override this setting
+ */
+ if( sqliteStrICmp(zLeft, "default_temp_store")==0 ){
+ static VdbeOpList getTmpDbLoc[] = {
+ { OP_ColumnName, 0, 1, "temp_store"},
+ { OP_ReadCookie, 0, 5, 0},
+ { OP_Callback, 1, 0, 0}};
+ if( pRight->z==pLeft->z ){
+ sqliteVdbeAddOpList(v, ArraySize(getTmpDbLoc), getTmpDbLoc);
+ }else{
+ if (&db->aDb[1].pBt != 0) {
+ sqliteErrorMsg(pParse, "The temporary database already exists - "
+ "its location cannot now be changed");
+ } else {
+ sqliteBeginWriteOperation(pParse, 0, 0);
+ db->temp_store = getTempStore(zRight);
+ sqliteVdbeAddOp(v, OP_Integer, db->temp_store, 0);
+ sqliteVdbeAddOp(v, OP_SetCookie, 0, 5);
+ sqliteEndWriteOperation(pParse);
+ }
+ }
+ }else
+
+#ifndef NDEBUG
+ if( sqliteStrICmp(zLeft, "parser_trace")==0 ){
+ extern void sqliteParserTrace(FILE*, char *);
+ if( getBoolean(zRight) ){
+ sqliteParserTrace(stdout, "parser: ");
+ }else{
+ sqliteParserTrace(0, 0);
+ }
+ }else
+#endif
+
+ if( sqliteStrICmp(zLeft, "integrity_check")==0 ){
+ int i, j, addr;
+
+ /* Code that initializes the integrity check program. Set the
+ ** error count 0
+ */
+ static VdbeOpList initCode[] = {
+ { OP_Integer, 0, 0, 0},
+ { OP_MemStore, 0, 1, 0},
+ { OP_ColumnName, 0, 1, "integrity_check"},
+ };
+
+ /* Code to do an BTree integrity check on a single database file.
+ */
+ static VdbeOpList checkDb[] = {
+ { OP_SetInsert, 0, 0, "2"},
+ { OP_Integer, 0, 0, 0}, /* 1 */
+ { OP_OpenRead, 0, 2, 0},
+ { OP_Rewind, 0, 7, 0}, /* 3 */
+ { OP_Column, 0, 3, 0}, /* 4 */
+ { OP_SetInsert, 0, 0, 0},
+ { OP_Next, 0, 4, 0}, /* 6 */
+ { OP_IntegrityCk, 0, 0, 0}, /* 7 */
+ { OP_Dup, 0, 1, 0},
+ { OP_String, 0, 0, "ok"},
+ { OP_StrEq, 0, 12, 0}, /* 10 */
+ { OP_MemIncr, 0, 0, 0},
+ { OP_String, 0, 0, "*** in database "},
+ { OP_String, 0, 0, 0}, /* 13 */
+ { OP_String, 0, 0, " ***\n"},
+ { OP_Pull, 3, 0, 0},
+ { OP_Concat, 4, 1, 0},
+ { OP_Callback, 1, 0, 0},
+ };
+
+ /* Code that appears at the end of the integrity check. If no error
+ ** messages have been generated, output OK. Otherwise output the
+ ** error message
+ */
+ static VdbeOpList endCode[] = {
+ { OP_MemLoad, 0, 0, 0},
+ { OP_Integer, 0, 0, 0},
+ { OP_Ne, 0, 0, 0}, /* 2 */
+ { OP_String, 0, 0, "ok"},
+ { OP_Callback, 1, 0, 0},
+ };
+
+ /* Initialize the VDBE program */
+ sqliteVdbeAddOpList(v, ArraySize(initCode), initCode);
+
+ /* Do an integrity check on each database file */
+ for(i=0; i<db->nDb; i++){
+ HashElem *x;
+
+ /* Do an integrity check of the B-Tree
+ */
+ addr = sqliteVdbeAddOpList(v, ArraySize(checkDb), checkDb);
+ sqliteVdbeChangeP1(v, addr+1, i);
+ sqliteVdbeChangeP2(v, addr+3, addr+7);
+ sqliteVdbeChangeP2(v, addr+6, addr+4);
+ sqliteVdbeChangeP2(v, addr+7, i);
+ sqliteVdbeChangeP2(v, addr+10, addr+ArraySize(checkDb));
+ sqliteVdbeChangeP3(v, addr+13, db->aDb[i].zName, P3_STATIC);
+
+ /* Make sure all the indices are constructed correctly.
+ */
+ sqliteCodeVerifySchema(pParse, i);
+ for(x=sqliteHashFirst(&db->aDb[i].tblHash); x; x=sqliteHashNext(x)){
+ Table *pTab = sqliteHashData(x);
+ Index *pIdx;
+ int loopTop;
+
+ if( pTab->pIndex==0 ) continue;
+ sqliteVdbeAddOp(v, OP_Integer, i, 0);
+ sqliteVdbeOp3(v, OP_OpenRead, 1, pTab->tnum, pTab->zName, 0);
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ if( pIdx->tnum==0 ) continue;
+ sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+ sqliteVdbeOp3(v, OP_OpenRead, j+2, pIdx->tnum, pIdx->zName, 0);
+ }
+ sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+ sqliteVdbeAddOp(v, OP_MemStore, 1, 1);
+ loopTop = sqliteVdbeAddOp(v, OP_Rewind, 1, 0);
+ sqliteVdbeAddOp(v, OP_MemIncr, 1, 0);
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ int k, jmp2;
+ static VdbeOpList idxErr[] = {
+ { OP_MemIncr, 0, 0, 0},
+ { OP_String, 0, 0, "rowid "},
+ { OP_Recno, 1, 0, 0},
+ { OP_String, 0, 0, " missing from index "},
+ { OP_String, 0, 0, 0}, /* 4 */
+ { OP_Concat, 4, 0, 0},
+ { OP_Callback, 1, 0, 0},
+ };
+ sqliteVdbeAddOp(v, OP_Recno, 1, 0);
+ for(k=0; k<pIdx->nColumn; k++){
+ int idx = pIdx->aiColumn[k];
+ if( idx==pTab->iPKey ){
+ sqliteVdbeAddOp(v, OP_Recno, 1, 0);
+ }else{
+ sqliteVdbeAddOp(v, OP_Column, 1, idx);
+ }
+ }
+ sqliteVdbeAddOp(v, OP_MakeIdxKey, pIdx->nColumn, 0);
+ if( db->file_format>=4 ) sqliteAddIdxKeyType(v, pIdx);
+ jmp2 = sqliteVdbeAddOp(v, OP_Found, j+2, 0);
+ addr = sqliteVdbeAddOpList(v, ArraySize(idxErr), idxErr);
+ sqliteVdbeChangeP3(v, addr+4, pIdx->zName, P3_STATIC);
+ sqliteVdbeChangeP2(v, jmp2, sqliteVdbeCurrentAddr(v));
+ }
+ sqliteVdbeAddOp(v, OP_Next, 1, loopTop+1);
+ sqliteVdbeChangeP2(v, loopTop, sqliteVdbeCurrentAddr(v));
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ static VdbeOpList cntIdx[] = {
+ { OP_Integer, 0, 0, 0},
+ { OP_MemStore, 2, 1, 0},
+ { OP_Rewind, 0, 0, 0}, /* 2 */
+ { OP_MemIncr, 2, 0, 0},
+ { OP_Next, 0, 0, 0}, /* 4 */
+ { OP_MemLoad, 1, 0, 0},
+ { OP_MemLoad, 2, 0, 0},
+ { OP_Eq, 0, 0, 0}, /* 7 */
+ { OP_MemIncr, 0, 0, 0},
+ { OP_String, 0, 0, "wrong # of entries in index "},
+ { OP_String, 0, 0, 0}, /* 10 */
+ { OP_Concat, 2, 0, 0},
+ { OP_Callback, 1, 0, 0},
+ };
+ if( pIdx->tnum==0 ) continue;
+ addr = sqliteVdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
+ sqliteVdbeChangeP1(v, addr+2, j+2);
+ sqliteVdbeChangeP2(v, addr+2, addr+5);
+ sqliteVdbeChangeP1(v, addr+4, j+2);
+ sqliteVdbeChangeP2(v, addr+4, addr+3);
+ sqliteVdbeChangeP2(v, addr+7, addr+ArraySize(cntIdx));
+ sqliteVdbeChangeP3(v, addr+10, pIdx->zName, P3_STATIC);
+ }
+ }
+ }
+ addr = sqliteVdbeAddOpList(v, ArraySize(endCode), endCode);
+ sqliteVdbeChangeP2(v, addr+2, addr+ArraySize(endCode));
+ }else
+
+ {}
+ sqliteFree(zLeft);
+ sqliteFree(zRight);
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/printf.c b/tqtinterface/qt4/src/3rdparty/sqlite/printf.c
new file mode 100644
index 0000000..c9c3f95
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/printf.c
@@ -0,0 +1,855 @@
+/*
+** The "printf" code that follows dates from the 1980's. It is in
+** the public domain. The original comments are included here for
+** completeness. They are very out-of-date but might be useful as
+** an historical reference. Most of the "enhancements" have been backed
+** out so that the functionality is now the same as standard printf().
+**
+**************************************************************************
+**
+** The following modules is an enhanced tqreplacement for the "printf" subroutines
+** found in the standard C library. The following enhancements are
+** supported:
+**
+** + Additional functions. The standard set of "printf" functions
+** includes printf, fprintf, sprintf, vprintf, vfprintf, and
+** vsprintf. This module adds the following:
+**
+** * snprintf -- Works like sprintf, but has an extra argument
+** which is the size of the buffer written to.
+**
+** * mprintf -- Similar to sprintf. Writes output to memory
+** obtained from malloc.
+**
+** * xprintf -- Calls a function to dispose of output.
+**
+** * nprintf -- No output, but returns the number of characters
+** that would have been output by printf.
+**
+** * A v- version (ex: vsnprintf) of every function is also
+** supplied.
+**
+** + A few extensions to the formatting notation are supported:
+**
+** * The "=" flag (similar to "-") causes the output to be
+** be centered in the appropriately sized field.
+**
+** * The %b field outputs an integer in binary notation.
+**
+** * The %c field now accepts a precision. The character output
+** is repeated by the number of times the precision specifies.
+**
+** * The %' field works like %c, but takes as its character the
+** next character of the format string, instead of the next
+** argument. For example, printf("%.78'-") prints 78 minus
+** signs, the same as printf("%.78c",'-').
+**
+** + When compiled using GCC on a SPARC, this version of printf is
+** faster than the library printf for SUN OS 4.1.
+**
+** + All functions are fully reentrant.
+**
+*/
+#include "sqliteInt.h"
+
+/*
+** Conversion types fall into various categories as defined by the
+** following enumeration.
+*/
+#define etRADIX 1 /* Integer types. %d, %x, %o, and so forth */
+#define etFLOAT 2 /* Floating point. %f */
+#define etEXP 3 /* Exponentional notation. %e and %E */
+#define etGENERIC 4 /* Floating or exponential, depending on exponent. %g */
+#define etSIZE 5 /* Return number of characters processed so far. %n */
+#define etSTRING 6 /* Strings. %s */
+#define etDYNSTRING 7 /* Dynamically allocated strings. %z */
+#define etPERCENT 8 /* Percent symbol. %% */
+#define etCHARX 9 /* Characters. %c */
+#define etERROR 10 /* Used to indicate no such conversion type */
+/* The rest are extensions, not normally found in printf() */
+#define etCHARLIT 11 /* Literal characters. %' */
+#define etSTQLESCAPE 12 /* Strings with '\'' doubled. %q */
+#define etSTQLESCAPE2 13 /* Strings with '\'' doubled and enclosed in '',
+ NULL pointers tqreplaced by SQL NULL. %Q */
+#define etTOKEN 14 /* a pointer to a Token structure */
+#define etSRCLIST 15 /* a pointer to a SrcList */
+
+
+/*
+** An "etByte" is an 8-bit unsigned value.
+*/
+typedef unsigned char etByte;
+
+/*
+** Each builtin conversion character (ex: the 'd' in "%d") is described
+** by an instance of the following structure
+*/
+typedef struct et_info { /* Information about each format field */
+ char fmttype; /* The format field code letter */
+ etByte base; /* The base for radix conversion */
+ etByte flags; /* One or more of FLAG_ constants below */
+ etByte type; /* Conversion paradigm */
+ char *charset; /* The character set for conversion */
+ char *prefix; /* Prefix on non-zero values in alt format */
+} et_info;
+
+/*
+** Allowed values for et_info.flags
+*/
+#define FLAG_SIGNED 1 /* True if the value to convert is signed */
+#define FLAG_INTERN 2 /* True if for internal use only */
+
+
+/*
+** The following table is searched linearly, so it is good to put the
+** most frequently used conversion types first.
+*/
+static et_info fmtinfo[] = {
+ { 'd', 10, 1, etRADIX, "0123456789", 0 },
+ { 's', 0, 0, etSTRING, 0, 0 },
+ { 'z', 0, 2, etDYNSTRING, 0, 0 },
+ { 'q', 0, 0, etSTQLESCAPE, 0, 0 },
+ { 'Q', 0, 0, etSTQLESCAPE2, 0, 0 },
+ { 'c', 0, 0, etCHARX, 0, 0 },
+ { 'o', 8, 0, etRADIX, "01234567", "0" },
+ { 'u', 10, 0, etRADIX, "0123456789", 0 },
+ { 'x', 16, 0, etRADIX, "0123456789abcdef", "x0" },
+ { 'X', 16, 0, etRADIX, "0123456789ABCDEF", "X0" },
+ { 'f', 0, 1, etFLOAT, 0, 0 },
+ { 'e', 0, 1, etEXP, "e", 0 },
+ { 'E', 0, 1, etEXP, "E", 0 },
+ { 'g', 0, 1, etGENERIC, "e", 0 },
+ { 'G', 0, 1, etGENERIC, "E", 0 },
+ { 'i', 10, 1, etRADIX, "0123456789", 0 },
+ { 'n', 0, 0, etSIZE, 0, 0 },
+ { '%', 0, 0, etPERCENT, 0, 0 },
+ { 'p', 10, 0, etRADIX, "0123456789", 0 },
+ { 'T', 0, 2, etTOKEN, 0, 0 },
+ { 'S', 0, 2, etSRCLIST, 0, 0 },
+};
+#define etNINFO (sizeof(fmtinfo)/sizeof(fmtinfo[0]))
+
+/*
+** If NOFLOATINGPOINT is defined, then none of the floating point
+** conversions will work.
+*/
+#ifndef etNOFLOATINGPOINT
+/*
+** "*val" is a double such that 0.1 <= *val < 10.0
+** Return the ascii code for the leading digit of *val, then
+** multiply "*val" by 10.0 to renormalize.
+**
+** Example:
+** input: *val = 3.14159
+** output: *val = 1.4159 function return = '3'
+**
+** The counter *cnt is incremented each time. After counter exceeds
+** 16 (the number of significant digits in a 64-bit float) '0' is
+** always returned.
+*/
+static int et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
+ int digit;
+ LONGDOUBLE_TYPE d;
+ if( (*cnt)++ >= 16 ) return '0';
+ digit = (int)*val;
+ d = digit;
+ digit += '0';
+ *val = (*val - d)*10.0;
+ return digit;
+}
+#endif
+
+#define etBUFSIZE 1000 /* Size of the output buffer */
+
+/*
+** The root program. All variations call this core.
+**
+** INPUTS:
+** func This is a pointer to a function taking three arguments
+** 1. A pointer to anything. Same as the "arg" parameter.
+** 2. A pointer to the list of characters to be output
+** (Note, this list is NOT null terminated.)
+** 3. An integer number of characters to be output.
+** (Note: This number might be zero.)
+**
+** arg This is the pointer to anything which will be passed as the
+** first argument to "func". Use it for whatever you like.
+**
+** fmt This is the format string, as in the usual print.
+**
+** ap This is a pointer to a list of arguments. Same as in
+** vfprint.
+**
+** OUTPUTS:
+** The return value is the total number of characters sent to
+** the function "func". Returns -1 on a error.
+**
+** Note that the order in which automatic variables are declared below
+** seems to make a big difference in determining how fast this beast
+** will run.
+*/
+static int vxprintf(
+ void (*func)(void*,const char*,int), /* Consumer of text */
+ void *arg, /* First argument to the consumer */
+ int useExtended, /* Allow extended %-conversions */
+ const char *fmt, /* Format string */
+ va_list ap /* arguments */
+){
+ int c; /* Next character in the format string */
+ char *bufpt; /* Pointer to the conversion buffer */
+ int precision; /* Precision of the current field */
+ int length; /* Length of the field */
+ int idx; /* A general purpose loop counter */
+ int count; /* Total number of characters output */
+ int width; /* Width of the current field */
+ etByte flag_leftjustify; /* True if "-" flag is present */
+ etByte flag_plussign; /* True if "+" flag is present */
+ etByte flag_blanksign; /* True if " " flag is present */
+ etByte flag_alternateform; /* True if "#" flag is present */
+ etByte flag_zeropad; /* True if field width constant starts with zero */
+ etByte flag_long; /* True if "l" flag is present */
+ unsigned long longvalue; /* Value for integer types */
+ LONGDOUBLE_TYPE realvalue; /* Value for real types */
+ et_info *infop; /* Pointer to the appropriate info structure */
+ char buf[etBUFSIZE]; /* Conversion buffer */
+ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
+ etByte errorflag = 0; /* True if an error is encountered */
+ etByte xtype; /* Conversion paradigm */
+ char *zExtra; /* Extra memory used for etTCLESCAPE conversions */
+ static char spaces[] = " ";
+#define etSPACESIZE (sizeof(spaces)-1)
+#ifndef etNOFLOATINGPOINT
+ int exp; /* exponent of real numbers */
+ double rounder; /* Used for rounding floating point values */
+ etByte flag_dp; /* True if decimal point should be shown */
+ etByte flag_rtz; /* True if trailing zeros should be removed */
+ etByte flag_exp; /* True to force display of the exponent */
+ int nsd; /* Number of significant digits returned */
+#endif
+
+ count = length = 0;
+ bufpt = 0;
+ for(; (c=(*fmt))!=0; ++fmt){
+ if( c!='%' ){
+ int amt;
+ bufpt = (char *)fmt;
+ amt = 1;
+ while( (c=(*++fmt))!='%' && c!=0 ) amt++;
+ (*func)(arg,bufpt,amt);
+ count += amt;
+ if( c==0 ) break;
+ }
+ if( (c=(*++fmt))==0 ){
+ errorflag = 1;
+ (*func)(arg,"%",1);
+ count++;
+ break;
+ }
+ /* Find out what flags are present */
+ flag_leftjustify = flag_plussign = flag_blanksign =
+ flag_alternateform = flag_zeropad = 0;
+ do{
+ switch( c ){
+ case '-': flag_leftjustify = 1; c = 0; break;
+ case '+': flag_plussign = 1; c = 0; break;
+ case ' ': flag_blanksign = 1; c = 0; break;
+ case '#': flag_alternateform = 1; c = 0; break;
+ case '0': flag_zeropad = 1; c = 0; break;
+ default: break;
+ }
+ }while( c==0 && (c=(*++fmt))!=0 );
+ /* Get the field width */
+ width = 0;
+ if( c=='*' ){
+ width = va_arg(ap,int);
+ if( width<0 ){
+ flag_leftjustify = 1;
+ width = -width;
+ }
+ c = *++fmt;
+ }else{
+ while( c>='0' && c<='9' ){
+ width = width*10 + c - '0';
+ c = *++fmt;
+ }
+ }
+ if( width > etBUFSIZE-10 ){
+ width = etBUFSIZE-10;
+ }
+ /* Get the precision */
+ if( c=='.' ){
+ precision = 0;
+ c = *++fmt;
+ if( c=='*' ){
+ precision = va_arg(ap,int);
+ if( precision<0 ) precision = -precision;
+ c = *++fmt;
+ }else{
+ while( c>='0' && c<='9' ){
+ precision = precision*10 + c - '0';
+ c = *++fmt;
+ }
+ }
+ /* Limit the precision to prevent overflowing buf[] during conversion */
+ if( precision>etBUFSIZE-40 ) precision = etBUFSIZE-40;
+ }else{
+ precision = -1;
+ }
+ /* Get the conversion type modifier */
+ if( c=='l' ){
+ flag_long = 1;
+ c = *++fmt;
+ }else{
+ flag_long = 0;
+ }
+ /* Fetch the info entry for the field */
+ infop = 0;
+ xtype = etERROR;
+ for(idx=0; idx<etNINFO; idx++){
+ if( c==fmtinfo[idx].fmttype ){
+ infop = &fmtinfo[idx];
+ if( useExtended || (infop->flags & FLAG_INTERN)==0 ){
+ xtype = infop->type;
+ }
+ break;
+ }
+ }
+ zExtra = 0;
+
+ /*
+ ** At this point, variables are initialized as follows:
+ **
+ ** flag_alternateform TRUE if a '#' is present.
+ ** flag_plussign TRUE if a '+' is present.
+ ** flag_leftjustify TRUE if a '-' is present or if the
+ ** field width was negative.
+ ** flag_zeropad TRUE if the width began with 0.
+ ** flag_long TRUE if the letter 'l' (ell) prefixed
+ ** the conversion character.
+ ** flag_blanksign TRUE if a ' ' is present.
+ ** width The specified field width. This is
+ ** always non-negative. Zero is the default.
+ ** precision The specified precision. The default
+ ** is -1.
+ ** xtype The class of the conversion.
+ ** infop Pointer to the appropriate info struct.
+ */
+ switch( xtype ){
+ case etRADIX:
+ if( flag_long ) longvalue = va_arg(ap,long);
+ else longvalue = va_arg(ap,int);
+#if 1
+ /* For the format %#x, the value zero is printed "0" not "0x0".
+ ** I think this is stupid. */
+ if( longvalue==0 ) flag_alternateform = 0;
+#else
+ /* More sensible: turn off the prefix for octal (to prevent "00"),
+ ** but leave the prefix for hex. */
+ if( longvalue==0 && infop->base==8 ) flag_alternateform = 0;
+#endif
+ if( infop->flags & FLAG_SIGNED ){
+ if( *(long*)&longvalue<0 ){
+ longvalue = -*(long*)&longvalue;
+ prefix = '-';
+ }else if( flag_plussign ) prefix = '+';
+ else if( flag_blanksign ) prefix = ' ';
+ else prefix = 0;
+ }else prefix = 0;
+ if( flag_zeropad && precision<width-(prefix!=0) ){
+ precision = width-(prefix!=0);
+ }
+ bufpt = &buf[etBUFSIZE-1];
+ {
+ register char *cset; /* Use registers for speed */
+ register int base;
+ cset = infop->charset;
+ base = infop->base;
+ do{ /* Convert to ascii */
+ *(--bufpt) = cset[longvalue%base];
+ longvalue = longvalue/base;
+ }while( longvalue>0 );
+ }
+ length = &buf[etBUFSIZE-1]-bufpt;
+ for(idx=precision-length; idx>0; idx--){
+ *(--bufpt) = '0'; /* Zero pad */
+ }
+ if( prefix ) *(--bufpt) = prefix; /* Add sign */
+ if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
+ char *pre, x;
+ pre = infop->prefix;
+ if( *bufpt!=pre[0] ){
+ for(pre=infop->prefix; (x=(*pre))!=0; pre++) *(--bufpt) = x;
+ }
+ }
+ length = &buf[etBUFSIZE-1]-bufpt;
+ break;
+ case etFLOAT:
+ case etEXP:
+ case etGENERIC:
+ realvalue = va_arg(ap,double);
+#ifndef etNOFLOATINGPOINT
+ if( precision<0 ) precision = 6; /* Set default precision */
+ if( precision>etBUFSIZE-10 ) precision = etBUFSIZE-10;
+ if( realvalue<0.0 ){
+ realvalue = -realvalue;
+ prefix = '-';
+ }else{
+ if( flag_plussign ) prefix = '+';
+ else if( flag_blanksign ) prefix = ' ';
+ else prefix = 0;
+ }
+ if( infop->type==etGENERIC && precision>0 ) precision--;
+ rounder = 0.0;
+#if 0
+ /* Rounding works like BSD when the constant 0.4999 is used. Wierd! */
+ for(idx=precision, rounder=0.4999; idx>0; idx--, rounder*=0.1);
+#else
+ /* It makes more sense to use 0.5 */
+ for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1);
+#endif
+ if( infop->type==etFLOAT ) realvalue += rounder;
+ /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
+ exp = 0;
+ if( realvalue>0.0 ){
+ while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
+ while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
+ while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
+ while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
+ if( exp>350 || exp<-350 ){
+ bufpt = "NaN";
+ length = 3;
+ break;
+ }
+ }
+ bufpt = buf;
+ /*
+ ** If the field type is etGENERIC, then convert to either etEXP
+ ** or etFLOAT, as appropriate.
+ */
+ flag_exp = xtype==etEXP;
+ if( xtype!=etFLOAT ){
+ realvalue += rounder;
+ if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
+ }
+ if( xtype==etGENERIC ){
+ flag_rtz = !flag_alternateform;
+ if( exp<-4 || exp>precision ){
+ xtype = etEXP;
+ }else{
+ precision = precision - exp;
+ xtype = etFLOAT;
+ }
+ }else{
+ flag_rtz = 0;
+ }
+ /*
+ ** The "exp+precision" test causes output to be of type etEXP if
+ ** the precision is too large to fit in buf[].
+ */
+ nsd = 0;
+ if( xtype==etFLOAT && exp+precision<etBUFSIZE-30 ){
+ flag_dp = (precision>0 || flag_alternateform);
+ if( prefix ) *(bufpt++) = prefix; /* Sign */
+ if( exp<0 ) *(bufpt++) = '0'; /* Digits before "." */
+ else for(; exp>=0; exp--) *(bufpt++) = et_getdigit(&realvalue,&nsd);
+ if( flag_dp ) *(bufpt++) = '.'; /* The decimal point */
+ for(exp++; exp<0 && precision>0; precision--, exp++){
+ *(bufpt++) = '0';
+ }
+ while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
+ *(bufpt--) = 0; /* Null terminate */
+ if( flag_rtz && flag_dp ){ /* Remove trailing zeros and "." */
+ while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
+ if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
+ }
+ bufpt++; /* point to next free slot */
+ }else{ /* etEXP or etGENERIC */
+ flag_dp = (precision>0 || flag_alternateform);
+ if( prefix ) *(bufpt++) = prefix; /* Sign */
+ *(bufpt++) = et_getdigit(&realvalue,&nsd); /* First digit */
+ if( flag_dp ) *(bufpt++) = '.'; /* Decimal point */
+ while( (precision--)>0 ) *(bufpt++) = et_getdigit(&realvalue,&nsd);
+ bufpt--; /* point to last digit */
+ if( flag_rtz && flag_dp ){ /* Remove tail zeros */
+ while( bufpt>=buf && *bufpt=='0' ) *(bufpt--) = 0;
+ if( bufpt>=buf && *bufpt=='.' ) *(bufpt--) = 0;
+ }
+ bufpt++; /* point to next free slot */
+ if( exp || flag_exp ){
+ *(bufpt++) = infop->charset[0];
+ if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; } /* sign of exp */
+ else { *(bufpt++) = '+'; }
+ if( exp>=100 ){
+ *(bufpt++) = (exp/100)+'0'; /* 100's digit */
+ exp %= 100;
+ }
+ *(bufpt++) = exp/10+'0'; /* 10's digit */
+ *(bufpt++) = exp%10+'0'; /* 1's digit */
+ }
+ }
+ /* The converted number is in buf[] and zero terminated. Output it.
+ ** Note that the number is in the usual order, not reversed as with
+ ** integer conversions. */
+ length = bufpt-buf;
+ bufpt = buf;
+
+ /* Special case: Add leading zeros if the flag_zeropad flag is
+ ** set and we are not left justified */
+ if( flag_zeropad && !flag_leftjustify && length < width){
+ int i;
+ int nPad = width - length;
+ for(i=width; i>=nPad; i--){
+ bufpt[i] = bufpt[i-nPad];
+ }
+ i = prefix!=0;
+ while( nPad-- ) bufpt[i++] = '0';
+ length = width;
+ }
+#endif
+ break;
+ case etSIZE:
+ *(va_arg(ap,int*)) = count;
+ length = width = 0;
+ break;
+ case etPERCENT:
+ buf[0] = '%';
+ bufpt = buf;
+ length = 1;
+ break;
+ case etCHARLIT:
+ case etCHARX:
+ c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);
+ if( precision>=0 ){
+ for(idx=1; idx<precision; idx++) buf[idx] = c;
+ length = precision;
+ }else{
+ length =1;
+ }
+ bufpt = buf;
+ break;
+ case etSTRING:
+ case etDYNSTRING:
+ bufpt = va_arg(ap,char*);
+ if( bufpt==0 ){
+ bufpt = "";
+ }else if( xtype==etDYNSTRING ){
+ zExtra = bufpt;
+ }
+ length = strlen(bufpt);
+ if( precision>=0 && precision<length ) length = precision;
+ break;
+ case etSTQLESCAPE:
+ case etSTQLESCAPE2:
+ {
+ int i, j, n, c, isnull;
+ char *arg = va_arg(ap,char*);
+ isnull = arg==0;
+ if( isnull ) arg = (xtype==etSTQLESCAPE2 ? "NULL" : "(NULL)");
+ for(i=n=0; (c=arg[i])!=0; i++){
+ if( c=='\'' ) n++;
+ }
+ n += i + 1 + ((!isnull && xtype==etSTQLESCAPE2) ? 2 : 0);
+ if( n>etBUFSIZE ){
+ bufpt = zExtra = sqliteMalloc( n );
+ if( bufpt==0 ) return -1;
+ }else{
+ bufpt = buf;
+ }
+ j = 0;
+ if( !isnull && xtype==etSTQLESCAPE2 ) bufpt[j++] = '\'';
+ for(i=0; (c=arg[i])!=0; i++){
+ bufpt[j++] = c;
+ if( c=='\'' ) bufpt[j++] = c;
+ }
+ if( !isnull && xtype==etSTQLESCAPE2 ) bufpt[j++] = '\'';
+ bufpt[j] = 0;
+ length = j;
+ if( precision>=0 && precision<length ) length = precision;
+ }
+ break;
+ case etTOKEN: {
+ Token *pToken = va_arg(ap, Token*);
+ (*func)(arg, pToken->z, pToken->n);
+ length = width = 0;
+ break;
+ }
+ case etSRCLIST: {
+ SrcList *pSrc = va_arg(ap, SrcList*);
+ int k = va_arg(ap, int);
+ struct SrcList_item *pItem = &pSrc->a[k];
+ assert( k>=0 && k<pSrc->nSrc );
+ if( pItem->zDatabase && pItem->zDatabase[0] ){
+ (*func)(arg, pItem->zDatabase, strlen(pItem->zDatabase));
+ (*func)(arg, ".", 1);
+ }
+ (*func)(arg, pItem->zName, strlen(pItem->zName));
+ length = width = 0;
+ break;
+ }
+ case etERROR:
+ buf[0] = '%';
+ buf[1] = c;
+ errorflag = 0;
+ idx = 1+(c!=0);
+ (*func)(arg,"%",idx);
+ count += idx;
+ if( c==0 ) fmt--;
+ break;
+ }/* End switch over the format type */
+ /*
+ ** The text of the conversion is pointed to by "bufpt" and is
+ ** "length" characters long. The field width is "width". Do
+ ** the output.
+ */
+ if( !flag_leftjustify ){
+ register int nspace;
+ nspace = width-length;
+ if( nspace>0 ){
+ count += nspace;
+ while( nspace>=etSPACESIZE ){
+ (*func)(arg,spaces,etSPACESIZE);
+ nspace -= etSPACESIZE;
+ }
+ if( nspace>0 ) (*func)(arg,spaces,nspace);
+ }
+ }
+ if( length>0 ){
+ (*func)(arg,bufpt,length);
+ count += length;
+ }
+ if( flag_leftjustify ){
+ register int nspace;
+ nspace = width-length;
+ if( nspace>0 ){
+ count += nspace;
+ while( nspace>=etSPACESIZE ){
+ (*func)(arg,spaces,etSPACESIZE);
+ nspace -= etSPACESIZE;
+ }
+ if( nspace>0 ) (*func)(arg,spaces,nspace);
+ }
+ }
+ if( zExtra ){
+ sqliteFree(zExtra);
+ }
+ }/* End for loop over the format string */
+ return errorflag ? -1 : count;
+} /* End of function */
+
+
+/* This structure is used to store state information about the
+** write to memory that is currently in progress.
+*/
+struct sgMprintf {
+ char *zBase; /* A base allocation */
+ char *zText; /* The string collected so far */
+ int nChar; /* Length of the string so far */
+ int nTotal; /* Output size if unconstrained */
+ int nAlloc; /* Amount of space allocated in zText */
+ void *(*xRealloc)(void*,int); /* Function used to realloc memory */
+};
+
+/*
+** This function implements the callback from vxprintf.
+**
+** This routine add nNewChar characters of text in zNewText to
+** the sgMprintf structure pointed to by "arg".
+*/
+static void mout(void *arg, const char *zNewText, int nNewChar){
+ struct sgMprintf *pM = (struct sgMprintf*)arg;
+ pM->nTotal += nNewChar;
+ if( pM->nChar + nNewChar + 1 > pM->nAlloc ){
+ if( pM->xRealloc==0 ){
+ nNewChar = pM->nAlloc - pM->nChar - 1;
+ }else{
+ pM->nAlloc = pM->nChar + nNewChar*2 + 1;
+ if( pM->zText==pM->zBase ){
+ pM->zText = pM->xRealloc(0, pM->nAlloc);
+ if( pM->zText && pM->nChar ){
+ memcpy(pM->zText, pM->zBase, pM->nChar);
+ }
+ }else{
+ pM->zText = pM->xRealloc(pM->zText, pM->nAlloc);
+ }
+ }
+ }
+ if( pM->zText && nNewChar>0 ){
+ memcpy(&pM->zText[pM->nChar], zNewText, nNewChar);
+ pM->nChar += nNewChar;
+ pM->zText[pM->nChar] = 0;
+ }
+}
+
+/*
+** This routine is a wrapper around xprintf() that invokes mout() as
+** the consumer.
+*/
+static char *base_vprintf(
+ void *(*xRealloc)(void*,int), /* Routine to realloc memory. May be NULL */
+ int useInternal, /* Use internal %-conversions if true */
+ char *zInitBuf, /* Initially write here, before mallocing */
+ int nInitBuf, /* Size of zInitBuf[] */
+ const char *zFormat, /* format string */
+ va_list ap /* arguments */
+){
+ struct sgMprintf sM;
+ sM.zBase = sM.zText = zInitBuf;
+ sM.nChar = sM.nTotal = 0;
+ sM.nAlloc = nInitBuf;
+ sM.xRealloc = xRealloc;
+ vxprintf(mout, &sM, useInternal, zFormat, ap);
+ if( xRealloc ){
+ if( sM.zText==sM.zBase ){
+ sM.zText = xRealloc(0, sM.nChar+1);
+ memcpy(sM.zText, sM.zBase, sM.nChar+1);
+ }else if( sM.nAlloc>sM.nChar+10 ){
+ sM.zText = xRealloc(sM.zText, sM.nChar+1);
+ }
+ }
+ return sM.zText;
+}
+
+/*
+** Realloc that is a real function, not a macro.
+*/
+static void *printf_realloc(void *old, int size){
+ return sqliteRealloc(old,size);
+}
+
+/*
+** Print into memory obtained from sqliteMalloc(). Use the internal
+** %-conversion extensions.
+*/
+char *sqliteVMPrintf(const char *zFormat, va_list ap){
+ char zBase[1000];
+ return base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
+}
+
+/*
+** Print into memory obtained from sqliteMalloc(). Use the internal
+** %-conversion extensions.
+*/
+char *sqliteMPrintf(const char *zFormat, ...){
+ va_list ap;
+ char *z;
+ char zBase[1000];
+ va_start(ap, zFormat);
+ z = base_vprintf(printf_realloc, 1, zBase, sizeof(zBase), zFormat, ap);
+ va_end(ap);
+ return z;
+}
+
+/*
+** Print into memory obtained from malloc(). Do not use the internal
+** %-conversion extensions. This routine is for use by external users.
+*/
+char *sqlite_mprintf(const char *zFormat, ...){
+ va_list ap;
+ char *z;
+ char zBuf[200];
+
+ va_start(ap,zFormat);
+ z = base_vprintf((void*(*)(void*,int))realloc, 0,
+ zBuf, sizeof(zBuf), zFormat, ap);
+ va_end(ap);
+ return z;
+}
+
+/* This is the varargs version of sqlite_mprintf.
+*/
+char *sqlite_vmprintf(const char *zFormat, va_list ap){
+ char zBuf[200];
+ return base_vprintf((void*(*)(void*,int))realloc, 0,
+ zBuf, sizeof(zBuf), zFormat, ap);
+}
+
+/*
+** sqlite_snprintf() works like snprintf() except that it ignores the
+** current locale settings. This is important for STQLite because we
+** are not able to use a "," as the decimal point in place of "." as
+** specified by some locales.
+*/
+char *sqlite_snprintf(int n, char *zBuf, const char *zFormat, ...){
+ char *z;
+ va_list ap;
+
+ va_start(ap,zFormat);
+ z = base_vprintf(0, 0, zBuf, n, zFormat, ap);
+ va_end(ap);
+ return z;
+}
+
+/*
+** The following four routines implement the varargs versions of the
+** sqlite_exec() and sqlite_get_table() interfaces. See the sqlite.h
+** header files for a more detailed description of how these interfaces
+** work.
+**
+** These routines are all just simple wrappers.
+*/
+int sqlite_exec_printf(
+ sqlite *db, /* An open database */
+ const char *sqlFormat, /* printf-style format string for the SQL */
+ sqlite_callback xCallback, /* Callback function */
+ void *pArg, /* 1st argument to callback function */
+ char **errmsg, /* Error msg written here */
+ ... /* Arguments to the format string. */
+){
+ va_list ap;
+ int rc;
+
+ va_start(ap, errmsg);
+ rc = sqlite_exec_vprintf(db, sqlFormat, xCallback, pArg, errmsg, ap);
+ va_end(ap);
+ return rc;
+}
+int sqlite_exec_vprintf(
+ sqlite *db, /* An open database */
+ const char *sqlFormat, /* printf-style format string for the SQL */
+ sqlite_callback xCallback, /* Callback function */
+ void *pArg, /* 1st argument to callback function */
+ char **errmsg, /* Error msg written here */
+ va_list ap /* Arguments to the format string. */
+){
+ char *zSql;
+ int rc;
+
+ zSql = sqlite_vmprintf(sqlFormat, ap);
+ rc = sqlite_exec(db, zSql, xCallback, pArg, errmsg);
+ free(zSql);
+ return rc;
+}
+int sqlite_get_table_printf(
+ sqlite *db, /* An open database */
+ const char *sqlFormat, /* printf-style format string for the SQL */
+ char ***resultp, /* Result written to a char *[] that this points to */
+ int *nrow, /* Number of result rows written here */
+ int *ncol, /* Number of result columns written here */
+ char **errmsg, /* Error msg written here */
+ ... /* Arguments to the format string */
+){
+ va_list ap;
+ int rc;
+
+ va_start(ap, errmsg);
+ rc = sqlite_get_table_vprintf(db, sqlFormat, resultp, nrow, ncol, errmsg, ap);
+ va_end(ap);
+ return rc;
+}
+int sqlite_get_table_vprintf(
+ sqlite *db, /* An open database */
+ const char *sqlFormat, /* printf-style format string for the SQL */
+ char ***resultp, /* Result written to a char *[] that this points to */
+ int *nrow, /* Number of result rows written here */
+ int *ncolumn, /* Number of result columns written here */
+ char **errmsg, /* Error msg written here */
+ va_list ap /* Arguments to the format string */
+){
+ char *zSql;
+ int rc;
+
+ zSql = sqlite_vmprintf(sqlFormat, ap);
+ rc = sqlite_get_table(db, zSql, resultp, nrow, ncolumn, errmsg);
+ free(zSql);
+ return rc;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/random.c b/tqtinterface/qt4/src/3rdparty/sqlite/random.c
new file mode 100644
index 0000000..7182ad1
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/random.c
@@ -0,0 +1,97 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains code to implement a pseudo-random number
+** generator (PRNG) for STQLite.
+**
+** Random numbers are used by some of the database backends in order
+** to generate random integer keys for tables or random filenames.
+**
+** $Id: random.c,v 1.11 2004/02/11 09:46:33 drh Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+
+
+/*
+** Get a single 8-bit random value from the RC4 PRNG. The Mutex
+** must be held while executing this routine.
+**
+** Why not just use a library random generator like lrand48() for this?
+** Because the OP_NewRecno opcode in the VDBE depends on having a very
+** good source of random numbers. The lrand48() library function may
+** well be good enough. But maybe not. Or maybe lrand48() has some
+** subtle problems on some systems that could cause problems. It is hard
+** to know. To minimize the risk of problems due to bad lrand48()
+** implementations, STQLite uses this random number generator based
+** on RC4, which we know works very well.
+*/
+static int randomByte(){
+ unsigned char t;
+
+ /* All threads share a single random number generator.
+ ** This structure is the current state of the generator.
+ */
+ static struct {
+ unsigned char isInit; /* True if initialized */
+ unsigned char i, j; /* State variables */
+ unsigned char s[256]; /* State variables */
+ } prng;
+
+ /* Initialize the state of the random number generator once,
+ ** the first time this routine is called. The seed value does
+ ** not need to contain a lot of randomness since we are not
+ ** trying to do secure encryption or anything like that...
+ **
+ ** Nothing in this file or anywhere else in STQLite does any kind of
+ ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
+ ** number generator) not as an encryption tqdevice.
+ */
+ if( !prng.isInit ){
+ int i;
+ char k[256];
+ prng.j = 0;
+ prng.i = 0;
+ sqliteOsRandomSeed(k);
+ for(i=0; i<256; i++){
+ prng.s[i] = i;
+ }
+ for(i=0; i<256; i++){
+ prng.j += prng.s[i] + k[i];
+ t = prng.s[prng.j];
+ prng.s[prng.j] = prng.s[i];
+ prng.s[i] = t;
+ }
+ prng.isInit = 1;
+ }
+
+ /* Generate and return single random byte
+ */
+ prng.i++;
+ t = prng.s[prng.i];
+ prng.j += t;
+ prng.s[prng.i] = prng.s[prng.j];
+ prng.s[prng.j] = t;
+ t += prng.s[prng.i];
+ return prng.s[t];
+}
+
+/*
+** Return N random bytes.
+*/
+void sqliteRandomness(int N, void *pBuf){
+ unsigned char *zBuf = pBuf;
+ sqliteOsEnterMutex();
+ while( N-- ){
+ *(zBuf++) = randomByte();
+ }
+ sqliteOsLeaveMutex();
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/select.c b/tqtinterface/qt4/src/3rdparty/sqlite/select.c
new file mode 100644
index 0000000..1a34322
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/select.c
@@ -0,0 +1,2404 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains C code routines that are called by the parser
+** to handle SELECT statements in STQLite.
+**
+** $Id: select.c,v 1.160 2004/03/02 18:37:41 drh Exp $
+*/
+#include "sqliteInt.h"
+
+
+/*
+** Allocate a new Select structure and return a pointer to that
+** structure.
+*/
+Select *sqliteSelectNew(
+ ExprList *pEList, /* which columns to include in the result */
+ SrcList *pSrc, /* the FROM clause -- which tables to scan */
+ Expr *pWhere, /* the WHERE clause */
+ ExprList *pGroupBy, /* the GROUP BY clause */
+ Expr *pHaving, /* the HAVING clause */
+ ExprList *pOrderBy, /* the ORDER BY clause */
+ int isDistinct, /* true if the DISTINCT keyword is present */
+ int nLimit, /* LIMIT value. -1 means not used */
+ int nOffset /* OFFSET value. 0 means no offset */
+){
+ Select *pNew;
+ pNew = sqliteMalloc( sizeof(*pNew) );
+ if( pNew==0 ){
+ sqliteExprListDelete(pEList);
+ sqliteSrcListDelete(pSrc);
+ sqliteExprDelete(pWhere);
+ sqliteExprListDelete(pGroupBy);
+ sqliteExprDelete(pHaving);
+ sqliteExprListDelete(pOrderBy);
+ }else{
+ if( pEList==0 ){
+ pEList = sqliteExprListAppend(0, sqliteExpr(TK_ALL,0,0,0), 0);
+ }
+ pNew->pEList = pEList;
+ pNew->pSrc = pSrc;
+ pNew->pWhere = pWhere;
+ pNew->pGroupBy = pGroupBy;
+ pNew->pHaving = pHaving;
+ pNew->pOrderBy = pOrderBy;
+ pNew->isDistinct = isDistinct;
+ pNew->op = TK_SELECT;
+ pNew->nLimit = nLimit;
+ pNew->nOffset = nOffset;
+ pNew->iLimit = -1;
+ pNew->iOffset = -1;
+ }
+ return pNew;
+}
+
+/*
+** Given 1 to 3 identifiers preceeding the JOIN keyword, determine the
+** type of join. Return an integer constant that expresses that type
+** in terms of the following bit values:
+**
+** JT_INNER
+** JT_OUTER
+** JT_NATURAL
+** JT_LEFT
+** JT_RIGHT
+**
+** A full outer join is the combination of JT_LEFT and JT_RIGHT.
+**
+** If an illegal or unsupported join type is seen, then still return
+** a join type, but put an error in the pParse structure.
+*/
+int sqliteJoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){
+ int jointype = 0;
+ Token *apAll[3];
+ Token *p;
+ static struct {
+ const char *zKeyword;
+ int nChar;
+ int code;
+ } keywords[] = {
+ { "natural", 7, JT_NATURAL },
+ { "left", 4, JT_LEFT|JT_OUTER },
+ { "right", 5, JT_RIGHT|JT_OUTER },
+ { "full", 4, JT_LEFT|JT_RIGHT|JT_OUTER },
+ { "outer", 5, JT_OUTER },
+ { "inner", 5, JT_INNER },
+ { "cross", 5, JT_INNER },
+ };
+ int i, j;
+ apAll[0] = pA;
+ apAll[1] = pB;
+ apAll[2] = pC;
+ for(i=0; i<3 && apAll[i]; i++){
+ p = apAll[i];
+ for(j=0; j<sizeof(keywords)/sizeof(keywords[0]); j++){
+ if( p->n==keywords[j].nChar
+ && sqliteStrNICmp(p->z, keywords[j].zKeyword, p->n)==0 ){
+ jointype |= keywords[j].code;
+ break;
+ }
+ }
+ if( j>=sizeof(keywords)/sizeof(keywords[0]) ){
+ jointype |= JT_ERROR;
+ break;
+ }
+ }
+ if(
+ (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
+ (jointype & JT_ERROR)!=0
+ ){
+ static Token dummy = { 0, 0 };
+ char *zSp1 = " ", *zSp2 = " ";
+ if( pB==0 ){ pB = &dummy; zSp1 = 0; }
+ if( pC==0 ){ pC = &dummy; zSp2 = 0; }
+ sqliteSetNString(&pParse->zErrMsg, "unknown or unsupported join type: ", 0,
+ pA->z, pA->n, zSp1, 1, pB->z, pB->n, zSp2, 1, pC->z, pC->n, 0);
+ pParse->nErr++;
+ jointype = JT_INNER;
+ }else if( jointype & JT_RIGHT ){
+ sqliteErrorMsg(pParse,
+ "RIGHT and FULL OUTER JOINs are not currently supported");
+ jointype = JT_INNER;
+ }
+ return jointype;
+}
+
+/*
+** Return the index of a column in a table. Return -1 if the column
+** is not contained in the table.
+*/
+static int columnIndex(Table *pTab, const char *zCol){
+ int i;
+ for(i=0; i<pTab->nCol; i++){
+ if( sqliteStrICmp(pTab->aCol[i].zName, zCol)==0 ) return i;
+ }
+ return -1;
+}
+
+/*
+** Add a term to the WHERE expression in *ppExpr that requires the
+** zCol column to be equal in the two tables pTab1 and pTab2.
+*/
+static void addWhereTerm(
+ const char *zCol, /* Name of the column */
+ const Table *pTab1, /* First table */
+ const Table *pTab2, /* Second table */
+ Expr **ppExpr /* Add the equality term to this expression */
+){
+ Token dummy;
+ Expr *pE1a, *pE1b, *pE1c;
+ Expr *pE2a, *pE2b, *pE2c;
+ Expr *pE;
+
+ dummy.z = zCol;
+ dummy.n = strlen(zCol);
+ dummy.dyn = 0;
+ pE1a = sqliteExpr(TK_ID, 0, 0, &dummy);
+ pE2a = sqliteExpr(TK_ID, 0, 0, &dummy);
+ dummy.z = pTab1->zName;
+ dummy.n = strlen(dummy.z);
+ pE1b = sqliteExpr(TK_ID, 0, 0, &dummy);
+ dummy.z = pTab2->zName;
+ dummy.n = strlen(dummy.z);
+ pE2b = sqliteExpr(TK_ID, 0, 0, &dummy);
+ pE1c = sqliteExpr(TK_DOT, pE1b, pE1a, 0);
+ pE2c = sqliteExpr(TK_DOT, pE2b, pE2a, 0);
+ pE = sqliteExpr(TK_EQ, pE1c, pE2c, 0);
+ ExprSetProperty(pE, EP_FromJoin);
+ if( *ppExpr ){
+ *ppExpr = sqliteExpr(TK_AND, *ppExpr, pE, 0);
+ }else{
+ *ppExpr = pE;
+ }
+}
+
+/*
+** Set the EP_FromJoin property on all terms of the given expression.
+**
+** The EP_FromJoin property is used on terms of an expression to tell
+** the LEFT OUTER JOIN processing logic that this term is part of the
+** join restriction specified in the ON or USING clause and not a part
+** of the more general WHERE clause. These terms are moved over to the
+** WHERE clause during join processing but we need to remember that they
+** originated in the ON or USING clause.
+*/
+static void setJoinExpr(Expr *p){
+ while( p ){
+ ExprSetProperty(p, EP_FromJoin);
+ setJoinExpr(p->pLeft);
+ p = p->pRight;
+ }
+}
+
+/*
+** This routine processes the join information for a SELECT statement.
+** ON and USING clauses are converted into extra terms of the WHERE clause.
+** NATURAL joins also create extra WHERE clause terms.
+**
+** This routine returns the number of errors encountered.
+*/
+static int sqliteProcessJoin(Parse *pParse, Select *p){
+ SrcList *pSrc;
+ int i, j;
+ pSrc = p->pSrc;
+ for(i=0; i<pSrc->nSrc-1; i++){
+ struct SrcList_item *pTerm = &pSrc->a[i];
+ struct SrcList_item *pOther = &pSrc->a[i+1];
+
+ if( pTerm->pTab==0 || pOther->pTab==0 ) continue;
+
+ /* When the NATURAL keyword is present, add WHERE clause terms for
+ ** every column that the two tables have in common.
+ */
+ if( pTerm->jointype & JT_NATURAL ){
+ Table *pTab;
+ if( pTerm->pOn || pTerm->pUsing ){
+ sqliteErrorMsg(pParse, "a NATURAL join may not have "
+ "an ON or USING clause", 0);
+ return 1;
+ }
+ pTab = pTerm->pTab;
+ for(j=0; j<pTab->nCol; j++){
+ if( columnIndex(pOther->pTab, pTab->aCol[j].zName)>=0 ){
+ addWhereTerm(pTab->aCol[j].zName, pTab, pOther->pTab, &p->pWhere);
+ }
+ }
+ }
+
+ /* Disallow both ON and USING clauses in the same join
+ */
+ if( pTerm->pOn && pTerm->pUsing ){
+ sqliteErrorMsg(pParse, "cannot have both ON and USING "
+ "clauses in the same join");
+ return 1;
+ }
+
+ /* Add the ON clause to the end of the WHERE clause, connected by
+ ** and AND operator.
+ */
+ if( pTerm->pOn ){
+ setJoinExpr(pTerm->pOn);
+ if( p->pWhere==0 ){
+ p->pWhere = pTerm->pOn;
+ }else{
+ p->pWhere = sqliteExpr(TK_AND, p->pWhere, pTerm->pOn, 0);
+ }
+ pTerm->pOn = 0;
+ }
+
+ /* Create extra terms on the WHERE clause for each column named
+ ** in the USING clause. Example: If the two tables to be joined are
+ ** A and B and the USING clause names X, Y, and Z, then add this
+ ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z
+ ** Report an error if any column mentioned in the USING clause is
+ ** not contained in both tables to be joined.
+ */
+ if( pTerm->pUsing ){
+ IdList *pList;
+ int j;
+ assert( i<pSrc->nSrc-1 );
+ pList = pTerm->pUsing;
+ for(j=0; j<pList->nId; j++){
+ if( columnIndex(pTerm->pTab, pList->a[j].zName)<0 ||
+ columnIndex(pOther->pTab, pList->a[j].zName)<0 ){
+ sqliteErrorMsg(pParse, "cannot join using column %s - column "
+ "not present in both tables", pList->a[j].zName);
+ return 1;
+ }
+ addWhereTerm(pList->a[j].zName, pTerm->pTab, pOther->pTab, &p->pWhere);
+ }
+ }
+ }
+ return 0;
+}
+
+/*
+** Delete the given Select structure and all of its substructures.
+*/
+void sqliteSelectDelete(Select *p){
+ if( p==0 ) return;
+ sqliteExprListDelete(p->pEList);
+ sqliteSrcListDelete(p->pSrc);
+ sqliteExprDelete(p->pWhere);
+ sqliteExprListDelete(p->pGroupBy);
+ sqliteExprDelete(p->pHaving);
+ sqliteExprListDelete(p->pOrderBy);
+ sqliteSelectDelete(p->pPrior);
+ sqliteFree(p->zSelect);
+ sqliteFree(p);
+}
+
+/*
+** Delete the aggregate information from the parse structure.
+*/
+static void sqliteAggregateInfoReset(Parse *pParse){
+ sqliteFree(pParse->aAgg);
+ pParse->aAgg = 0;
+ pParse->nAgg = 0;
+ pParse->useAgg = 0;
+}
+
+/*
+** Insert code into "v" that will push the record on the top of the
+** stack into the sorter.
+*/
+static void pushOntoSorter(Parse *pParse, Vdbe *v, ExprList *pOrderBy){
+ char *zSortOrder;
+ int i;
+ zSortOrder = sqliteMalloc( pOrderBy->nExpr + 1 );
+ if( zSortOrder==0 ) return;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ int order = pOrderBy->a[i].sortOrder;
+ int type;
+ int c;
+ if( (order & STQLITE_SO_TYPEMASK)==STQLITE_SO_TEXT ){
+ type = STQLITE_SO_TEXT;
+ }else if( (order & STQLITE_SO_TYPEMASK)==STQLITE_SO_NUM ){
+ type = STQLITE_SO_NUM;
+ }else if( pParse->db->file_format>=4 ){
+ type = sqliteExprType(pOrderBy->a[i].pExpr);
+ }else{
+ type = STQLITE_SO_NUM;
+ }
+ if( (order & STQLITE_SO_DIRMASK)==STQLITE_SO_ASC ){
+ c = type==STQLITE_SO_TEXT ? 'A' : '+';
+ }else{
+ c = type==STQLITE_SO_TEXT ? 'D' : '-';
+ }
+ zSortOrder[i] = c;
+ sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
+ }
+ zSortOrder[pOrderBy->nExpr] = 0;
+ sqliteVdbeOp3(v, OP_SortMakeKey, pOrderBy->nExpr, 0, zSortOrder, P3_DYNAMIC);
+ sqliteVdbeAddOp(v, OP_SortPut, 0, 0);
+}
+
+/*
+** This routine adds a P3 argument to the last VDBE opcode that was
+** inserted. The P3 argument added is a string suitable for the
+** OP_MakeKey or OP_MakeIdxKey opcodes. The string consists of
+** characters 't' or 'n' depending on whether or not the various
+** fields of the key to be generated should be treated as numeric
+** or as text. See the OP_MakeKey and OP_MakeIdxKey opcode
+** documentation for additional information about the P3 string.
+** See also the sqliteAddIdxKeyType() routine.
+*/
+void sqliteAddKeyType(Vdbe *v, ExprList *pEList){
+ int nColumn = pEList->nExpr;
+ char *zType = sqliteMalloc( nColumn+1 );
+ int i;
+ if( zType==0 ) return;
+ for(i=0; i<nColumn; i++){
+ zType[i] = sqliteExprType(pEList->a[i].pExpr)==STQLITE_SO_NUM ? 'n' : 't';
+ }
+ zType[i] = 0;
+ sqliteVdbeChangeP3(v, -1, zType, P3_DYNAMIC);
+}
+
+/*
+** This routine generates the code for the inside of the inner loop
+** of a SELECT.
+**
+** If srcTab and nColumn are both zero, then the pEList expressions
+** are evaluated in order to get the data for this row. If nColumn>0
+** then data is pulled from srcTab and pEList is used only to get the
+** datatypes for each column.
+*/
+static int selectInnerLoop(
+ Parse *pParse, /* The parser context */
+ Select *p, /* The complete select statement being coded */
+ ExprList *pEList, /* List of values being extracted */
+ int srcTab, /* Pull data from this table */
+ int nColumn, /* Number of columns in the source table */
+ ExprList *pOrderBy, /* If not NULL, sort results using this key */
+ int distinct, /* If >=0, make sure results are distinct */
+ int eDest, /* How to dispose of the results */
+ int iParm, /* An argument to the disposal method */
+ int iContinue, /* Jump here to continue with next row */
+ int iBreak /* Jump here to break out of the inner loop */
+){
+ Vdbe *v = pParse->pVdbe;
+ int i;
+
+ if( v==0 ) return 0;
+ assert( pEList!=0 );
+
+ /* If there was a LIMIT clause on the SELECT statement, then do the check
+ ** to see if this row should be output.
+ */
+ if( pOrderBy==0 ){
+ if( p->iOffset>=0 ){
+ int addr = sqliteVdbeCurrentAddr(v);
+ sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+2);
+ sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
+ }
+ if( p->iLimit>=0 ){
+ sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, iBreak);
+ }
+ }
+
+ /* Pull the requested columns.
+ */
+ if( nColumn>0 ){
+ for(i=0; i<nColumn; i++){
+ sqliteVdbeAddOp(v, OP_Column, srcTab, i);
+ }
+ }else{
+ nColumn = pEList->nExpr;
+ for(i=0; i<pEList->nExpr; i++){
+ sqliteExprCode(pParse, pEList->a[i].pExpr);
+ }
+ }
+
+ /* If the DISTINCT keyword was present on the SELECT statement
+ ** and this row has been seen before, then do not make this row
+ ** part of the result.
+ */
+ if( distinct>=0 && pEList && pEList->nExpr>0 ){
+#if NULL_ALWAYS_DISTINCT
+ sqliteVdbeAddOp(v, OP_IsNull, -pEList->nExpr, sqliteVdbeCurrentAddr(v)+7);
+#endif
+ sqliteVdbeAddOp(v, OP_MakeKey, pEList->nExpr, 1);
+ if( pParse->db->file_format>=4 ) sqliteAddKeyType(v, pEList);
+ sqliteVdbeAddOp(v, OP_Distinct, distinct, sqliteVdbeCurrentAddr(v)+3);
+ sqliteVdbeAddOp(v, OP_Pop, pEList->nExpr+1, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, iContinue);
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ sqliteVdbeAddOp(v, OP_PutStrKey, distinct, 0);
+ }
+
+ switch( eDest ){
+ /* In this mode, write each query result to the key of the temporary
+ ** table iParm.
+ */
+ case SRT_Union: {
+ sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
+ break;
+ }
+
+ /* Store the result as data using a unique key.
+ */
+ case SRT_Table:
+ case SRT_TempTable: {
+ sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
+ if( pOrderBy ){
+ pushOntoSorter(pParse, v, pOrderBy);
+ }else{
+ sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0);
+ sqliteVdbeAddOp(v, OP_Pull, 1, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, iParm, 0);
+ }
+ break;
+ }
+
+ /* Construct a record from the query result, but instead of
+ ** saving that record, use it as a key to delete elements from
+ ** the temporary table iParm.
+ */
+ case SRT_Except: {
+ int addr;
+ addr = sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, NULL_ALWAYS_DISTINCT);
+ sqliteVdbeAddOp(v, OP_NotFound, iParm, addr+3);
+ sqliteVdbeAddOp(v, OP_Delete, iParm, 0);
+ break;
+ }
+
+ /* If we are creating a set for an "expr IN (SELECT ...)" construct,
+ ** then there should be a single item on the stack. Write this
+ ** item into the set table with bogus data.
+ */
+ case SRT_Set: {
+ int addr1 = sqliteVdbeCurrentAddr(v);
+ int addr2;
+ assert( nColumn==1 );
+ sqliteVdbeAddOp(v, OP_NotNull, -1, addr1+3);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ addr2 = sqliteVdbeAddOp(v, OP_Goto, 0, 0);
+ if( pOrderBy ){
+ pushOntoSorter(pParse, v, pOrderBy);
+ }else{
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
+ }
+ sqliteVdbeChangeP2(v, addr2, sqliteVdbeCurrentAddr(v));
+ break;
+ }
+
+ /* If this is a scalar select that is part of an expression, then
+ ** store the results in the appropriate memory cell and break out
+ ** of the scan loop.
+ */
+ case SRT_Mem: {
+ assert( nColumn==1 );
+ if( pOrderBy ){
+ pushOntoSorter(pParse, v, pOrderBy);
+ }else{
+ sqliteVdbeAddOp(v, OP_MemStore, iParm, 1);
+ sqliteVdbeAddOp(v, OP_Goto, 0, iBreak);
+ }
+ break;
+ }
+
+ /* Send the data to the callback function.
+ */
+ case SRT_Callback:
+ case SRT_Sorter: {
+ if( pOrderBy ){
+ sqliteVdbeAddOp(v, OP_SortMakeRec, nColumn, 0);
+ pushOntoSorter(pParse, v, pOrderBy);
+ }else{
+ assert( eDest==SRT_Callback );
+ sqliteVdbeAddOp(v, OP_Callback, nColumn, 0);
+ }
+ break;
+ }
+
+ /* Invoke a subroutine to handle the results. The subroutine itself
+ ** is responsible for popping the results off of the stack.
+ */
+ case SRT_Subroutine: {
+ if( pOrderBy ){
+ sqliteVdbeAddOp(v, OP_MakeRecord, nColumn, 0);
+ pushOntoSorter(pParse, v, pOrderBy);
+ }else{
+ sqliteVdbeAddOp(v, OP_Gosub, 0, iParm);
+ }
+ break;
+ }
+
+ /* Discard the results. This is used for SELECT statements inside
+ ** the body of a TRIGGER. The purpose of such selects is to call
+ ** user-defined functions that have side effects. We do not care
+ ** about the actual results of the select.
+ */
+ default: {
+ assert( eDest==SRT_Discard );
+ sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+** If the inner loop was generated using a non-null pOrderBy argument,
+** then the results were placed in a sorter. After the loop is terminated
+** we need to run the sorter and output the results. The following
+** routine generates the code needed to do that.
+*/
+static void generateSortTail(
+ Select *p, /* The SELECT statement */
+ Vdbe *v, /* Generate code into this VDBE */
+ int nColumn, /* Number of columns of data */
+ int eDest, /* Write the sorted results here */
+ int iParm /* Optional parameter associated with eDest */
+){
+ int end1 = sqliteVdbeMakeLabel(v);
+ int end2 = sqliteVdbeMakeLabel(v);
+ int addr;
+ if( eDest==SRT_Sorter ) return;
+ sqliteVdbeAddOp(v, OP_Sort, 0, 0);
+ addr = sqliteVdbeAddOp(v, OP_SortNext, 0, end1);
+ if( p->iOffset>=0 ){
+ sqliteVdbeAddOp(v, OP_MemIncr, p->iOffset, addr+4);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, addr);
+ }
+ if( p->iLimit>=0 ){
+ sqliteVdbeAddOp(v, OP_MemIncr, p->iLimit, end2);
+ }
+ switch( eDest ){
+ case SRT_Callback: {
+ sqliteVdbeAddOp(v, OP_SortCallback, nColumn, 0);
+ break;
+ }
+ case SRT_Table:
+ case SRT_TempTable: {
+ sqliteVdbeAddOp(v, OP_NewRecno, iParm, 0);
+ sqliteVdbeAddOp(v, OP_Pull, 1, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, iParm, 0);
+ break;
+ }
+ case SRT_Set: {
+ assert( nColumn==1 );
+ sqliteVdbeAddOp(v, OP_NotNull, -1, sqliteVdbeCurrentAddr(v)+3);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, sqliteVdbeCurrentAddr(v)+3);
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ sqliteVdbeAddOp(v, OP_PutStrKey, iParm, 0);
+ break;
+ }
+ case SRT_Mem: {
+ assert( nColumn==1 );
+ sqliteVdbeAddOp(v, OP_MemStore, iParm, 1);
+ sqliteVdbeAddOp(v, OP_Goto, 0, end1);
+ break;
+ }
+ case SRT_Subroutine: {
+ int i;
+ for(i=0; i<nColumn; i++){
+ sqliteVdbeAddOp(v, OP_Column, -1-i, i);
+ }
+ sqliteVdbeAddOp(v, OP_Gosub, 0, iParm);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ break;
+ }
+ default: {
+ /* Do nothing */
+ break;
+ }
+ }
+ sqliteVdbeAddOp(v, OP_Goto, 0, addr);
+ sqliteVdbeResolveLabel(v, end2);
+ sqliteVdbeAddOp(v, OP_Pop, 1, 0);
+ sqliteVdbeResolveLabel(v, end1);
+ sqliteVdbeAddOp(v, OP_SortReset, 0, 0);
+}
+
+/*
+** Generate code that will tell the VDBE the datatypes of
+** columns in the result set.
+**
+** This routine only generates code if the "PRAGMA show_datatypes=on"
+** has been executed. The datatypes are reported out in the azCol
+** parameter to the callback function. The first N azCol[] entries
+** are the names of the columns, and the second N entries are the
+** datatypes for the columns.
+**
+** The "datatype" for a result that is a column of a type is the
+** datatype definition extracted from the CREATE TABLE statement.
+** The datatype for an expression is either TEXT or NUMERIC. The
+** datatype for a ROWID field is INTEGER.
+*/
+static void generateColumnTypes(
+ Parse *pParse, /* Parser context */
+ SrcList *pTabList, /* List of tables */
+ ExprList *pEList /* Expressions defining the result set */
+){
+ Vdbe *v = pParse->pVdbe;
+ int i, j;
+ for(i=0; i<pEList->nExpr; i++){
+ Expr *p = pEList->a[i].pExpr;
+ char *zType = 0;
+ if( p==0 ) continue;
+ if( p->op==TK_COLUMN && pTabList ){
+ Table *pTab;
+ int iCol = p->iColumn;
+ for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
+ assert( j<pTabList->nSrc );
+ pTab = pTabList->a[j].pTab;
+ if( iCol<0 ) iCol = pTab->iPKey;
+ assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+ if( iCol<0 ){
+ zType = "INTEGER";
+ }else{
+ zType = pTab->aCol[iCol].zType;
+ }
+ }else{
+ if( sqliteExprType(p)==STQLITE_SO_TEXT ){
+ zType = "TEXT";
+ }else{
+ zType = "NUMERIC";
+ }
+ }
+ sqliteVdbeOp3(v, OP_ColumnName, i + pEList->nExpr, 0, zType, 0);
+ }
+}
+
+/*
+** Generate code that will tell the VDBE the names of columns
+** in the result set. This information is used to provide the
+** azCol[] values in the callback.
+*/
+static void generateColumnNames(
+ Parse *pParse, /* Parser context */
+ SrcList *pTabList, /* List of tables */
+ ExprList *pEList /* Expressions defining the result set */
+){
+ Vdbe *v = pParse->pVdbe;
+ int i, j;
+ sqlite *db = pParse->db;
+ int fullNames, shortNames;
+
+ assert( v!=0 );
+ if( pParse->colNamesSet || v==0 || sqlite_malloc_failed ) return;
+ pParse->colNamesSet = 1;
+ fullNames = (db->flags & STQLITE_FullColNames)!=0;
+ shortNames = (db->flags & STQLITE_ShortColNames)!=0;
+ for(i=0; i<pEList->nExpr; i++){
+ Expr *p;
+ int p2 = i==pEList->nExpr-1;
+ p = pEList->a[i].pExpr;
+ if( p==0 ) continue;
+ if( pEList->a[i].zName ){
+ char *zName = pEList->a[i].zName;
+ sqliteVdbeOp3(v, OP_ColumnName, i, p2, zName, 0);
+ continue;
+ }
+ if( p->op==TK_COLUMN && pTabList ){
+ Table *pTab;
+ char *zCol;
+ int iCol = p->iColumn;
+ for(j=0; j<pTabList->nSrc && pTabList->a[j].iCursor!=p->iTable; j++){}
+ assert( j<pTabList->nSrc );
+ pTab = pTabList->a[j].pTab;
+ if( iCol<0 ) iCol = pTab->iPKey;
+ assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
+ if( iCol<0 ){
+ zCol = "_ROWID_";
+ }else{
+ zCol = pTab->aCol[iCol].zName;
+ }
+ if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
+ int addr = sqliteVdbeOp3(v,OP_ColumnName, i, p2, p->span.z, p->span.n);
+ sqliteVdbeCompressSpace(v, addr);
+ }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
+ char *zName = 0;
+ char *zTab;
+
+ zTab = pTabList->a[j].zAlias;
+ if( fullNames || zTab==0 ) zTab = pTab->zName;
+ sqliteSetString(&zName, zTab, ".", zCol, 0);
+ sqliteVdbeOp3(v, OP_ColumnName, i, p2, zName, P3_DYNAMIC);
+ }else{
+ sqliteVdbeOp3(v, OP_ColumnName, i, p2, zCol, 0);
+ }
+ }else if( p->span.z && p->span.z[0] ){
+ int addr = sqliteVdbeOp3(v,OP_ColumnName, i, p2, p->span.z, p->span.n);
+ sqliteVdbeCompressSpace(v, addr);
+ }else{
+ char zName[30];
+ assert( p->op!=TK_COLUMN || pTabList==0 );
+ sprintf(zName, "column%d", i+1);
+ sqliteVdbeOp3(v, OP_ColumnName, i, p2, zName, 0);
+ }
+ }
+}
+
+/*
+** Name of the connection operator, used for error messages.
+*/
+static const char *selectOpName(int id){
+ char *z;
+ switch( id ){
+ case TK_ALL: z = "UNION ALL"; break;
+ case TK_INTERSECT: z = "INTERSECT"; break;
+ case TK_EXCEPT: z = "EXCEPT"; break;
+ default: z = "UNION"; break;
+ }
+ return z;
+}
+
+/*
+** Forward declaration
+*/
+static int fillInColumnList(Parse*, Select*);
+
+/*
+** Given a SELECT statement, generate a Table structure that describes
+** the result set of that SELECT.
+*/
+Table *sqliteResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
+ Table *pTab;
+ int i, j;
+ ExprList *pEList;
+ Column *aCol;
+
+ if( fillInColumnList(pParse, pSelect) ){
+ return 0;
+ }
+ pTab = sqliteMalloc( sizeof(Table) );
+ if( pTab==0 ){
+ return 0;
+ }
+ pTab->zName = zTabName ? sqliteStrDup(zTabName) : 0;
+ pEList = pSelect->pEList;
+ pTab->nCol = pEList->nExpr;
+ assert( pTab->nCol>0 );
+ pTab->aCol = aCol = sqliteMalloc( sizeof(pTab->aCol[0])*pTab->nCol );
+ for(i=0; i<pTab->nCol; i++){
+ Expr *p, *pR;
+ if( pEList->a[i].zName ){
+ aCol[i].zName = sqliteStrDup(pEList->a[i].zName);
+ }else if( (p=pEList->a[i].pExpr)->op==TK_DOT
+ && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){
+ int cnt;
+ sqliteSetNString(&aCol[i].zName, pR->token.z, pR->token.n, 0);
+ for(j=cnt=0; j<i; j++){
+ if( sqliteStrICmp(aCol[j].zName, aCol[i].zName)==0 ){
+ int n;
+ char zBuf[30];
+ sprintf(zBuf,"_%d",++cnt);
+ n = strlen(zBuf);
+ sqliteSetNString(&aCol[i].zName, pR->token.z, pR->token.n, zBuf, n,0);
+ j = -1;
+ }
+ }
+ }else if( p->span.z && p->span.z[0] ){
+ sqliteSetNString(&pTab->aCol[i].zName, p->span.z, p->span.n, 0);
+ }else{
+ char zBuf[30];
+ sprintf(zBuf, "column%d", i+1);
+ pTab->aCol[i].zName = sqliteStrDup(zBuf);
+ }
+ }
+ pTab->iPKey = -1;
+ return pTab;
+}
+
+/*
+** For the given SELECT statement, do three things.
+**
+** (1) Fill in the pTabList->a[].pTab fields in the SrcList that
+** defines the set of tables that should be scanned. For views,
+** fill pTabList->a[].pSelect with a copy of the SELECT statement
+** that implements the view. A copy is made of the view's SELECT
+** statement so that we can freely modify or delete that statement
+** without worrying about messing up the presistent representation
+** of the view.
+**
+** (2) Add terms to the WHERE clause to accomodate the NATURAL keyword
+** on joins and the ON and USING clause of joins.
+**
+** (3) Scan the list of columns in the result set (pEList) looking
+** for instances of the "*" operator or the TABLE.* operator.
+** If found, expand each "*" to be every column in every table
+** and TABLE.* to be every column in TABLE.
+**
+** Return 0 on success. If there are problems, leave an error message
+** in pParse and return non-zero.
+*/
+static int fillInColumnList(Parse *pParse, Select *p){
+ int i, j, k, rc;
+ SrcList *pTabList;
+ ExprList *pEList;
+ Table *pTab;
+
+ if( p==0 || p->pSrc==0 ) return 1;
+ pTabList = p->pSrc;
+ pEList = p->pEList;
+
+ /* Look up every table in the table list.
+ */
+ for(i=0; i<pTabList->nSrc; i++){
+ if( pTabList->a[i].pTab ){
+ /* This routine has run before! No need to continue */
+ return 0;
+ }
+ if( pTabList->a[i].zName==0 ){
+ /* A sub-query in the FROM clause of a SELECT */
+ assert( pTabList->a[i].pSelect!=0 );
+ if( pTabList->a[i].zAlias==0 ){
+ char zFakeName[60];
+ sprintf(zFakeName, "sqlite_subquery_%p_",
+ (void*)pTabList->a[i].pSelect);
+ sqliteSetString(&pTabList->a[i].zAlias, zFakeName, 0);
+ }
+ pTabList->a[i].pTab = pTab =
+ sqliteResultSetOfSelect(pParse, pTabList->a[i].zAlias,
+ pTabList->a[i].pSelect);
+ if( pTab==0 ){
+ return 1;
+ }
+ /* The isTransient flag indicates that the Table structure has been
+ ** dynamically allocated and may be freed at any time. In other words,
+ ** pTab is not pointing to a persistent table structure that defines
+ ** part of the schema. */
+ pTab->isTransient = 1;
+ }else{
+ /* An ordinary table or view name in the FROM clause */
+ pTabList->a[i].pTab = pTab =
+ sqliteLocateTable(pParse,pTabList->a[i].zName,pTabList->a[i].zDatabase);
+ if( pTab==0 ){
+ return 1;
+ }
+ if( pTab->pSelect ){
+ /* We reach here if the named table is a really a view */
+ if( sqliteViewGetColumnNames(pParse, pTab) ){
+ return 1;
+ }
+ /* If pTabList->a[i].pSelect!=0 it means we are dealing with a
+ ** view within a view. The SELECT structure has already been
+ ** copied by the outer view so we can skip the copy step here
+ ** in the inner view.
+ */
+ if( pTabList->a[i].pSelect==0 ){
+ pTabList->a[i].pSelect = sqliteSelectDup(pTab->pSelect);
+ }
+ }
+ }
+ }
+
+ /* Process NATURAL keywords, and ON and USING clauses of joins.
+ */
+ if( sqliteProcessJoin(pParse, p) ) return 1;
+
+ /* For every "*" that occurs in the column list, insert the names of
+ ** all columns in all tables. And for every TABLE.* insert the names
+ ** of all columns in TABLE. The parser inserted a special expression
+ ** with the TK_ALL operator for each "*" that it found in the column list.
+ ** The following code just has to locate the TK_ALL expressions and expand
+ ** each one to the list of all columns in all tables.
+ **
+ ** The first loop just checks to see if there are any "*" operators
+ ** that need expanding.
+ */
+ for(k=0; k<pEList->nExpr; k++){
+ Expr *pE = pEList->a[k].pExpr;
+ if( pE->op==TK_ALL ) break;
+ if( pE->op==TK_DOT && pE->pRight && pE->pRight->op==TK_ALL
+ && pE->pLeft && pE->pLeft->op==TK_ID ) break;
+ }
+ rc = 0;
+ if( k<pEList->nExpr ){
+ /*
+ ** If we get here it means the result set tqcontains one or more "*"
+ ** operators that need to be expanded. Loop through each expression
+ ** in the result set and expand them one by one.
+ */
+ struct ExprList_item *a = pEList->a;
+ ExprList *pNew = 0;
+ for(k=0; k<pEList->nExpr; k++){
+ Expr *pE = a[k].pExpr;
+ if( pE->op!=TK_ALL &&
+ (pE->op!=TK_DOT || pE->pRight==0 || pE->pRight->op!=TK_ALL) ){
+ /* This particular expression does not need to be expanded.
+ */
+ pNew = sqliteExprListAppend(pNew, a[k].pExpr, 0);
+ pNew->a[pNew->nExpr-1].zName = a[k].zName;
+ a[k].pExpr = 0;
+ a[k].zName = 0;
+ }else{
+ /* This expression is a "*" or a "TABLE.*" and needs to be
+ ** expanded. */
+ int tableSeen = 0; /* Set to 1 when TABLE matches */
+ Token *pName; /* text of name of TABLE */
+ if( pE->op==TK_DOT && pE->pLeft ){
+ pName = &pE->pLeft->token;
+ }else{
+ pName = 0;
+ }
+ for(i=0; i<pTabList->nSrc; i++){
+ Table *pTab = pTabList->a[i].pTab;
+ char *zTabName = pTabList->a[i].zAlias;
+ if( zTabName==0 || zTabName[0]==0 ){
+ zTabName = pTab->zName;
+ }
+ if( pName && (zTabName==0 || zTabName[0]==0 ||
+ sqliteStrNICmp(pName->z, zTabName, pName->n)!=0 ||
+ zTabName[pName->n]!=0) ){
+ continue;
+ }
+ tableSeen = 1;
+ for(j=0; j<pTab->nCol; j++){
+ Expr *pExpr, *pLeft, *pRight;
+ char *zName = pTab->aCol[j].zName;
+
+ if( i>0 && (pTabList->a[i-1].jointype & JT_NATURAL)!=0 &&
+ columnIndex(pTabList->a[i-1].pTab, zName)>=0 ){
+ /* In a NATURAL join, omit the join columns from the
+ ** table on the right */
+ continue;
+ }
+ if( i>0 && sqliteIdListIndex(pTabList->a[i-1].pUsing, zName)>=0 ){
+ /* In a join with a USING clause, omit columns in the
+ ** using clause from the table on the right. */
+ continue;
+ }
+ pRight = sqliteExpr(TK_ID, 0, 0, 0);
+ if( pRight==0 ) break;
+ pRight->token.z = zName;
+ pRight->token.n = strlen(zName);
+ pRight->token.dyn = 0;
+ if( zTabName && pTabList->nSrc>1 ){
+ pLeft = sqliteExpr(TK_ID, 0, 0, 0);
+ pExpr = sqliteExpr(TK_DOT, pLeft, pRight, 0);
+ if( pExpr==0 ) break;
+ pLeft->token.z = zTabName;
+ pLeft->token.n = strlen(zTabName);
+ pLeft->token.dyn = 0;
+ sqliteSetString((char**)&pExpr->span.z, zTabName, ".", zName, 0);
+ pExpr->span.n = strlen(pExpr->span.z);
+ pExpr->span.dyn = 1;
+ pExpr->token.z = 0;
+ pExpr->token.n = 0;
+ pExpr->token.dyn = 0;
+ }else{
+ pExpr = pRight;
+ pExpr->span = pExpr->token;
+ }
+ pNew = sqliteExprListAppend(pNew, pExpr, 0);
+ }
+ }
+ if( !tableSeen ){
+ if( pName ){
+ sqliteErrorMsg(pParse, "no such table: %T", pName);
+ }else{
+ sqliteErrorMsg(pParse, "no tables specified");
+ }
+ rc = 1;
+ }
+ }
+ }
+ sqliteExprListDelete(pEList);
+ p->pEList = pNew;
+ }
+ return rc;
+}
+
+/*
+** This routine recursively unlinks the Select.pSrc.a[].pTab pointers
+** in a select structure. It just sets the pointers to NULL. This
+** routine is recursive in the sense that if the Select.pSrc.a[].pSelect
+** pointer is not NULL, this routine is called recursively on that pointer.
+**
+** This routine is called on the Select structure that defines a
+** VIEW in order to undo any bindings to tables. This is necessary
+** because those tables might be DROPed by a subsequent SQL command.
+** If the bindings are not removed, then the Select.pSrc->a[].pTab field
+** will be left pointing to a deallocated Table structure after the
+** DROP and a coredump will occur the next time the VIEW is used.
+*/
+void sqliteSelectUnbind(Select *p){
+ int i;
+ SrcList *pSrc = p->pSrc;
+ Table *pTab;
+ if( p==0 ) return;
+ for(i=0; i<pSrc->nSrc; i++){
+ if( (pTab = pSrc->a[i].pTab)!=0 ){
+ if( pTab->isTransient ){
+ sqliteDeleteTable(0, pTab);
+ }
+ pSrc->a[i].pTab = 0;
+ if( pSrc->a[i].pSelect ){
+ sqliteSelectUnbind(pSrc->a[i].pSelect);
+ }
+ }
+ }
+}
+
+/*
+** This routine associates entries in an ORDER BY expression list with
+** columns in a result. For each ORDER BY expression, the opcode of
+** the top-level node is changed to TK_COLUMN and the iColumn value of
+** the top-level node is filled in with column number and the iTable
+** value of the top-level node is filled with iTable parameter.
+**
+** If there are prior SELECT clauses, they are processed first. A match
+** in an earlier SELECT takes precedence over a later SELECT.
+**
+** Any entry that does not match is flagged as an error. The number
+** of errors is returned.
+**
+** This routine does NOT correctly initialize the Expr.dataType field
+** of the ORDER BY expressions. The multiSelectSortOrder() routine
+** must be called to do that after the individual select statements
+** have all been analyzed. This routine is unable to compute Expr.dataType
+** because it must be called before the individual select statements
+** have been analyzed.
+*/
+static int matchOrderbyToColumn(
+ Parse *pParse, /* A place to leave error messages */
+ Select *pSelect, /* Match to result columns of this SELECT */
+ ExprList *pOrderBy, /* The ORDER BY values to match against columns */
+ int iTable, /* Insert this value in iTable */
+ int mustComplete /* If TRUE all ORDER BYs must match */
+){
+ int nErr = 0;
+ int i, j;
+ ExprList *pEList;
+
+ if( pSelect==0 || pOrderBy==0 ) return 1;
+ if( mustComplete ){
+ for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; }
+ }
+ if( fillInColumnList(pParse, pSelect) ){
+ return 1;
+ }
+ if( pSelect->pPrior ){
+ if( matchOrderbyToColumn(pParse, pSelect->pPrior, pOrderBy, iTable, 0) ){
+ return 1;
+ }
+ }
+ pEList = pSelect->pEList;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ Expr *pE = pOrderBy->a[i].pExpr;
+ int iCol = -1;
+ if( pOrderBy->a[i].done ) continue;
+ if( sqliteExprIsInteger(pE, &iCol) ){
+ if( iCol<=0 || iCol>pEList->nExpr ){
+ sqliteErrorMsg(pParse,
+ "ORDER BY position %d should be between 1 and %d",
+ iCol, pEList->nExpr);
+ nErr++;
+ break;
+ }
+ if( !mustComplete ) continue;
+ iCol--;
+ }
+ for(j=0; iCol<0 && j<pEList->nExpr; j++){
+ if( pEList->a[j].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){
+ char *zName, *zLabel;
+ zName = pEList->a[j].zName;
+ assert( pE->token.z );
+ zLabel = sqliteStrNDup(pE->token.z, pE->token.n);
+ sqliteDequote(zLabel);
+ if( sqliteStrICmp(zName, zLabel)==0 ){
+ iCol = j;
+ }
+ sqliteFree(zLabel);
+ }
+ if( iCol<0 && sqliteExprCompare(pE, pEList->a[j].pExpr) ){
+ iCol = j;
+ }
+ }
+ if( iCol>=0 ){
+ pE->op = TK_COLUMN;
+ pE->iColumn = iCol;
+ pE->iTable = iTable;
+ pOrderBy->a[i].done = 1;
+ }
+ if( iCol<0 && mustComplete ){
+ sqliteErrorMsg(pParse,
+ "ORDER BY term number %d does not match any result column", i+1);
+ nErr++;
+ break;
+ }
+ }
+ return nErr;
+}
+
+/*
+** Get a VDBE for the given parser context. Create a new one if necessary.
+** If an error occurs, return NULL and leave a message in pParse.
+*/
+Vdbe *sqliteGetVdbe(Parse *pParse){
+ Vdbe *v = pParse->pVdbe;
+ if( v==0 ){
+ v = pParse->pVdbe = sqliteVdbeCreate(pParse->db);
+ }
+ return v;
+}
+
+/*
+** This routine sets the Expr.dataType field on all elements of
+** the pOrderBy expression list. The pOrderBy list will have been
+** set up by matchOrderbyToColumn(). Hence each expression has
+** a TK_COLUMN as its root node. The Expr.iColumn refers to a
+** column in the result set. The datatype is set to STQLITE_SO_TEXT
+** if the corresponding column in p and every SELECT to the left of
+** p has a datatype of STQLITE_SO_TEXT. If the cooressponding column
+** in p or any of the left SELECTs is STQLITE_SO_NUM, then the datatype
+** of the order-by expression is set to STQLITE_SO_NUM.
+**
+** Examples:
+**
+** CREATE TABLE one(a INTEGER, b TEXT);
+** CREATE TABLE two(c VARCHAR(5), d FLOAT);
+**
+** SELECT b, b FROM one UNION SELECT d, c FROM two ORDER BY 1, 2;
+**
+** The primary sort key will use STQLITE_SO_NUM because the "d" in
+** the second SELECT is numeric. The 1st column of the first SELECT
+** is text but that does not matter because a numeric always overrides
+** a text.
+**
+** The secondary key will use the STQLITE_SO_TEXT sort order because
+** both the (second) "b" in the first SELECT and the "c" in the second
+** SELECT have a datatype of text.
+*/
+static void multiSelectSortOrder(Select *p, ExprList *pOrderBy){
+ int i;
+ ExprList *pEList;
+ if( pOrderBy==0 ) return;
+ if( p==0 ){
+ for(i=0; i<pOrderBy->nExpr; i++){
+ pOrderBy->a[i].pExpr->dataType = STQLITE_SO_TEXT;
+ }
+ return;
+ }
+ multiSelectSortOrder(p->pPrior, pOrderBy);
+ pEList = p->pEList;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ Expr *pE = pOrderBy->a[i].pExpr;
+ if( pE->dataType==STQLITE_SO_NUM ) continue;
+ assert( pE->iColumn>=0 );
+ if( pEList->nExpr>pE->iColumn ){
+ pE->dataType = sqliteExprType(pEList->a[pE->iColumn].pExpr);
+ }
+ }
+}
+
+/*
+** Compute the iLimit and iOffset fields of the SELECT based on the
+** nLimit and nOffset fields. nLimit and nOffset hold the integers
+** that appear in the original SQL statement after the LIMIT and OFFSET
+** keywords. Or that hold -1 and 0 if those keywords are omitted.
+** iLimit and iOffset are the integer memory register numbers for
+** counters used to compute the limit and offset. If there is no
+** limit and/or offset, then iLimit and iOffset are negative.
+**
+** This routine changes the values if iLimit and iOffset only if
+** a limit or offset is defined by nLimit and nOffset. iLimit and
+** iOffset should have been preset to appropriate default values
+** (usually but not always -1) prior to calling this routine.
+** Only if nLimit>=0 or nOffset>0 do the limit registers get
+** redefined. The UNION ALL operator uses this property to force
+** the reuse of the same limit and offset registers across multiple
+** SELECT statements.
+*/
+static void computeLimitRegisters(Parse *pParse, Select *p){
+ /*
+ ** If the comparison is p->nLimit>0 then "LIMIT 0" shows
+ ** all rows. It is the same as no limit. If the comparision is
+ ** p->nLimit>=0 then "LIMIT 0" show no rows at all.
+ ** "LIMIT -1" always shows all rows. There is some
+ ** contraversy about what the correct behavior should be.
+ ** The current implementation interprets "LIMIT 0" to mean
+ ** no rows.
+ */
+ if( p->nLimit>=0 ){
+ int iMem = pParse->nMem++;
+ Vdbe *v = sqliteGetVdbe(pParse);
+ if( v==0 ) return;
+ sqliteVdbeAddOp(v, OP_Integer, -p->nLimit, 0);
+ sqliteVdbeAddOp(v, OP_MemStore, iMem, 1);
+ p->iLimit = iMem;
+ }
+ if( p->nOffset>0 ){
+ int iMem = pParse->nMem++;
+ Vdbe *v = sqliteGetVdbe(pParse);
+ if( v==0 ) return;
+ sqliteVdbeAddOp(v, OP_Integer, -p->nOffset, 0);
+ sqliteVdbeAddOp(v, OP_MemStore, iMem, 1);
+ p->iOffset = iMem;
+ }
+}
+
+/*
+** This routine is called to process a query that is really the union
+** or intersection of two or more separate queries.
+**
+** "p" points to the right-most of the two queries. the query on the
+** left is p->pPrior. The left query could also be a compound query
+** in which case this routine will be called recursively.
+**
+** The results of the total query are to be written into a destination
+** of type eDest with parameter iParm.
+**
+** Example 1: Consider a three-way compound SQL statement.
+**
+** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3
+**
+** This statement is parsed up as follows:
+**
+** SELECT c FROM t3
+** |
+** `-----> SELECT b FROM t2
+** |
+** `------> SELECT a FROM t1
+**
+** The arrows in the diagram above represent the Select.pPrior pointer.
+** So if this routine is called with p equal to the t3 query, then
+** pPrior will be the t2 query. p->op will be TK_UNION in this case.
+**
+** Notice that because of the way STQLite parses compound SELECTs, the
+** individual selects always group from left to right.
+*/
+static int multiSelect(Parse *pParse, Select *p, int eDest, int iParm){
+ int rc; /* Success code from a subroutine */
+ Select *pPrior; /* Another SELECT immediately to our left */
+ Vdbe *v; /* Generate code to this VDBE */
+
+ /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only
+ ** the last SELECT in the series may have an ORDER BY or LIMIT.
+ */
+ if( p==0 || p->pPrior==0 ) return 1;
+ pPrior = p->pPrior;
+ if( pPrior->pOrderBy ){
+ sqliteErrorMsg(pParse,"ORDER BY clause should come after %s not before",
+ selectOpName(p->op));
+ return 1;
+ }
+ if( pPrior->nLimit>=0 || pPrior->nOffset>0 ){
+ sqliteErrorMsg(pParse,"LIMIT clause should come after %s not before",
+ selectOpName(p->op));
+ return 1;
+ }
+
+ /* Make sure we have a valid query engine. If not, create a new one.
+ */
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ) return 1;
+
+ /* Create the destination temporary table if necessary
+ */
+ if( eDest==SRT_TempTable ){
+ sqliteVdbeAddOp(v, OP_OpenTemp, iParm, 0);
+ eDest = SRT_Table;
+ }
+
+ /* Generate code for the left and right SELECT statements.
+ */
+ switch( p->op ){
+ case TK_ALL: {
+ if( p->pOrderBy==0 ){
+ pPrior->nLimit = p->nLimit;
+ pPrior->nOffset = p->nOffset;
+ rc = sqliteSelect(pParse, pPrior, eDest, iParm, 0, 0, 0);
+ if( rc ) return rc;
+ p->pPrior = 0;
+ p->iLimit = pPrior->iLimit;
+ p->iOffset = pPrior->iOffset;
+ p->nLimit = -1;
+ p->nOffset = 0;
+ rc = sqliteSelect(pParse, p, eDest, iParm, 0, 0, 0);
+ p->pPrior = pPrior;
+ if( rc ) return rc;
+ break;
+ }
+ /* For UNION ALL ... ORDER BY fall through to the next case */
+ }
+ case TK_EXCEPT:
+ case TK_UNION: {
+ int unionTab; /* Cursor number of the temporary table holding result */
+ int op; /* One of the SRT_ operations to apply to self */
+ int priorOp; /* The SRT_ operation to apply to prior selects */
+ int nLimit, nOffset; /* Saved values of p->nLimit and p->nOffset */
+ ExprList *pOrderBy; /* The ORDER BY clause for the right SELECT */
+
+ priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union;
+ if( eDest==priorOp && p->pOrderBy==0 && p->nLimit<0 && p->nOffset==0 ){
+ /* We can reuse a temporary table generated by a SELECT to our
+ ** right.
+ */
+ unionTab = iParm;
+ }else{
+ /* We will need to create our own temporary table to hold the
+ ** intermediate results.
+ */
+ unionTab = pParse->nTab++;
+ if( p->pOrderBy
+ && matchOrderbyToColumn(pParse, p, p->pOrderBy, unionTab, 1) ){
+ return 1;
+ }
+ if( p->op!=TK_ALL ){
+ sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 1);
+ sqliteVdbeAddOp(v, OP_KeyAsData, unionTab, 1);
+ }else{
+ sqliteVdbeAddOp(v, OP_OpenTemp, unionTab, 0);
+ }
+ }
+
+ /* Code the SELECT statements to our left
+ */
+ rc = sqliteSelect(pParse, pPrior, priorOp, unionTab, 0, 0, 0);
+ if( rc ) return rc;
+
+ /* Code the current SELECT statement
+ */
+ switch( p->op ){
+ case TK_EXCEPT: op = SRT_Except; break;
+ case TK_UNION: op = SRT_Union; break;
+ case TK_ALL: op = SRT_Table; break;
+ }
+ p->pPrior = 0;
+ pOrderBy = p->pOrderBy;
+ p->pOrderBy = 0;
+ nLimit = p->nLimit;
+ p->nLimit = -1;
+ nOffset = p->nOffset;
+ p->nOffset = 0;
+ rc = sqliteSelect(pParse, p, op, unionTab, 0, 0, 0);
+ p->pPrior = pPrior;
+ p->pOrderBy = pOrderBy;
+ p->nLimit = nLimit;
+ p->nOffset = nOffset;
+ if( rc ) return rc;
+
+ /* Convert the data in the temporary table into whatever form
+ ** it is that we currently need.
+ */
+ if( eDest!=priorOp || unionTab!=iParm ){
+ int iCont, iBreak, iStart;
+ assert( p->pEList );
+ if( eDest==SRT_Callback ){
+ generateColumnNames(pParse, 0, p->pEList);
+ generateColumnTypes(pParse, p->pSrc, p->pEList);
+ }
+ iBreak = sqliteVdbeMakeLabel(v);
+ iCont = sqliteVdbeMakeLabel(v);
+ sqliteVdbeAddOp(v, OP_Rewind, unionTab, iBreak);
+ computeLimitRegisters(pParse, p);
+ iStart = sqliteVdbeCurrentAddr(v);
+ multiSelectSortOrder(p, p->pOrderBy);
+ rc = selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
+ p->pOrderBy, -1, eDest, iParm,
+ iCont, iBreak);
+ if( rc ) return 1;
+ sqliteVdbeResolveLabel(v, iCont);
+ sqliteVdbeAddOp(v, OP_Next, unionTab, iStart);
+ sqliteVdbeResolveLabel(v, iBreak);
+ sqliteVdbeAddOp(v, OP_Close, unionTab, 0);
+ if( p->pOrderBy ){
+ generateSortTail(p, v, p->pEList->nExpr, eDest, iParm);
+ }
+ }
+ break;
+ }
+ case TK_INTERSECT: {
+ int tab1, tab2;
+ int iCont, iBreak, iStart;
+ int nLimit, nOffset;
+
+ /* INTERSECT is different from the others since it requires
+ ** two temporary tables. Hence it has its own case. Begin
+ ** by allocating the tables we will need.
+ */
+ tab1 = pParse->nTab++;
+ tab2 = pParse->nTab++;
+ if( p->pOrderBy && matchOrderbyToColumn(pParse,p,p->pOrderBy,tab1,1) ){
+ return 1;
+ }
+ sqliteVdbeAddOp(v, OP_OpenTemp, tab1, 1);
+ sqliteVdbeAddOp(v, OP_KeyAsData, tab1, 1);
+
+ /* Code the SELECTs to our left into temporary table "tab1".
+ */
+ rc = sqliteSelect(pParse, pPrior, SRT_Union, tab1, 0, 0, 0);
+ if( rc ) return rc;
+
+ /* Code the current SELECT into temporary table "tab2"
+ */
+ sqliteVdbeAddOp(v, OP_OpenTemp, tab2, 1);
+ sqliteVdbeAddOp(v, OP_KeyAsData, tab2, 1);
+ p->pPrior = 0;
+ nLimit = p->nLimit;
+ p->nLimit = -1;
+ nOffset = p->nOffset;
+ p->nOffset = 0;
+ rc = sqliteSelect(pParse, p, SRT_Union, tab2, 0, 0, 0);
+ p->pPrior = pPrior;
+ p->nLimit = nLimit;
+ p->nOffset = nOffset;
+ if( rc ) return rc;
+
+ /* Generate code to take the intersection of the two temporary
+ ** tables.
+ */
+ assert( p->pEList );
+ if( eDest==SRT_Callback ){
+ generateColumnNames(pParse, 0, p->pEList);
+ generateColumnTypes(pParse, p->pSrc, p->pEList);
+ }
+ iBreak = sqliteVdbeMakeLabel(v);
+ iCont = sqliteVdbeMakeLabel(v);
+ sqliteVdbeAddOp(v, OP_Rewind, tab1, iBreak);
+ computeLimitRegisters(pParse, p);
+ iStart = sqliteVdbeAddOp(v, OP_FullKey, tab1, 0);
+ sqliteVdbeAddOp(v, OP_NotFound, tab2, iCont);
+ multiSelectSortOrder(p, p->pOrderBy);
+ rc = selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
+ p->pOrderBy, -1, eDest, iParm,
+ iCont, iBreak);
+ if( rc ) return 1;
+ sqliteVdbeResolveLabel(v, iCont);
+ sqliteVdbeAddOp(v, OP_Next, tab1, iStart);
+ sqliteVdbeResolveLabel(v, iBreak);
+ sqliteVdbeAddOp(v, OP_Close, tab2, 0);
+ sqliteVdbeAddOp(v, OP_Close, tab1, 0);
+ if( p->pOrderBy ){
+ generateSortTail(p, v, p->pEList->nExpr, eDest, iParm);
+ }
+ break;
+ }
+ }
+ assert( p->pEList && pPrior->pEList );
+ if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
+ sqliteErrorMsg(pParse, "SELECTs to the left and right of %s"
+ " do not have the same number of result columns", selectOpName(p->op));
+ return 1;
+ }
+ return 0;
+}
+
+/*
+** Scan through the expression pExpr. Replace every reference to
+** a column in table number iTable with a copy of the iColumn-th
+** entry in pEList. (But leave references to the ROWID column
+** unchanged.)
+**
+** This routine is part of the flattening procedure. A subquery
+** whose result set is defined by pEList appears as entry in the
+** FROM clause of a SELECT such that the VDBE cursor assigned to that
+** FORM clause entry is iTable. This routine make the necessary
+** changes to pExpr so that it refers directly to the source table
+** of the subquery rather the result set of the subquery.
+*/
+static void substExprList(ExprList*,int,ExprList*); /* Forward Decl */
+static void substExpr(Expr *pExpr, int iTable, ExprList *pEList){
+ if( pExpr==0 ) return;
+ if( pExpr->op==TK_COLUMN && pExpr->iTable==iTable ){
+ if( pExpr->iColumn<0 ){
+ pExpr->op = TK_NULL;
+ }else{
+ Expr *pNew;
+ assert( pEList!=0 && pExpr->iColumn<pEList->nExpr );
+ assert( pExpr->pLeft==0 && pExpr->pRight==0 && pExpr->pList==0 );
+ pNew = pEList->a[pExpr->iColumn].pExpr;
+ assert( pNew!=0 );
+ pExpr->op = pNew->op;
+ pExpr->dataType = pNew->dataType;
+ assert( pExpr->pLeft==0 );
+ pExpr->pLeft = sqliteExprDup(pNew->pLeft);
+ assert( pExpr->pRight==0 );
+ pExpr->pRight = sqliteExprDup(pNew->pRight);
+ assert( pExpr->pList==0 );
+ pExpr->pList = sqliteExprListDup(pNew->pList);
+ pExpr->iTable = pNew->iTable;
+ pExpr->iColumn = pNew->iColumn;
+ pExpr->iAgg = pNew->iAgg;
+ sqliteTokenCopy(&pExpr->token, &pNew->token);
+ sqliteTokenCopy(&pExpr->span, &pNew->span);
+ }
+ }else{
+ substExpr(pExpr->pLeft, iTable, pEList);
+ substExpr(pExpr->pRight, iTable, pEList);
+ substExprList(pExpr->pList, iTable, pEList);
+ }
+}
+static void
+substExprList(ExprList *pList, int iTable, ExprList *pEList){
+ int i;
+ if( pList==0 ) return;
+ for(i=0; i<pList->nExpr; i++){
+ substExpr(pList->a[i].pExpr, iTable, pEList);
+ }
+}
+
+/*
+** This routine attempts to flatten subqueries in order to speed
+** execution. It returns 1 if it makes changes and 0 if no flattening
+** occurs.
+**
+** To understand the concept of flattening, consider the following
+** query:
+**
+** SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
+**
+** The default way of implementing this query is to execute the
+** subquery first and store the results in a temporary table, then
+** run the outer query on that temporary table. This requires two
+** passes over the data. Furthermore, because the temporary table
+** has no indices, the WHERE clause on the outer query cannot be
+** optimized.
+**
+** This routine attempts to rewrite queries such as the above into
+** a single flat select, like this:
+**
+** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
+**
+** The code generated for this simpification gives the same result
+** but only has to scan the data once. And because indices might
+** exist on the table t1, a complete scan of the data might be
+** avoided.
+**
+** Flattening is only attempted if all of the following are true:
+**
+** (1) The subquery and the outer query do not both use aggregates.
+**
+** (2) The subquery is not an aggregate or the outer query is not a join.
+**
+** (3) The subquery is not the right operand of a left outer join, or
+** the subquery is not itself a join. (Ticket #306)
+**
+** (4) The subquery is not DISTINCT or the outer query is not a join.
+**
+** (5) The subquery is not DISTINCT or the outer query does not use
+** aggregates.
+**
+** (6) The subquery does not use aggregates or the outer query is not
+** DISTINCT.
+**
+** (7) The subquery has a FROM clause.
+**
+** (8) The subquery does not use LIMIT or the outer query is not a join.
+**
+** (9) The subquery does not use LIMIT or the outer query does not use
+** aggregates.
+**
+** (10) The subquery does not use aggregates or the outer query does not
+** use LIMIT.
+**
+** (11) The subquery and the outer query do not both have ORDER BY clauses.
+**
+** (12) The subquery is not the right term of a LEFT OUTER JOIN or the
+** subquery has no WHERE clause. (added by ticket #350)
+**
+** In this routine, the "p" parameter is a pointer to the outer query.
+** The subquery is p->pSrc->a[iFrom]. isAgg is true if the outer query
+** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
+**
+** If flattening is not attempted, this routine is a no-op and returns 0.
+** If flattening is attempted this routine returns 1.
+**
+** All of the expression analysis must occur on both the outer query and
+** the subquery before this routine runs.
+*/
+static int flattenSubquery(
+ Parse *pParse, /* The parsing context */
+ Select *p, /* The tqparent or outer SELECT statement */
+ int iFrom, /* Index in p->pSrc->a[] of the inner subquery */
+ int isAgg, /* True if outer SELECT uses aggregate functions */
+ int subqueryIsAgg /* True if the subquery uses aggregate functions */
+){
+ Select *pSub; /* The inner query or "subquery" */
+ SrcList *pSrc; /* The FROM clause of the outer query */
+ SrcList *pSubSrc; /* The FROM clause of the subquery */
+ ExprList *pList; /* The result set of the outer query */
+ int iParent; /* VDBE cursor number of the pSub result set temp table */
+ int i;
+ Expr *pWhere;
+
+ /* Check to see if flattening is permitted. Return 0 if not.
+ */
+ if( p==0 ) return 0;
+ pSrc = p->pSrc;
+ assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
+ pSub = pSrc->a[iFrom].pSelect;
+ assert( pSub!=0 );
+ if( isAgg && subqueryIsAgg ) return 0;
+ if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;
+ pSubSrc = pSub->pSrc;
+ assert( pSubSrc );
+ if( pSubSrc->nSrc==0 ) return 0;
+ if( (pSub->isDistinct || pSub->nLimit>=0) && (pSrc->nSrc>1 || isAgg) ){
+ return 0;
+ }
+ if( (p->isDistinct || p->nLimit>=0) && subqueryIsAgg ) return 0;
+ if( p->pOrderBy && pSub->pOrderBy ) return 0;
+
+ /* Restriction 3: If the subquery is a join, make sure the subquery is
+ ** not used as the right operand of an outer join. Examples of why this
+ ** is not allowed:
+ **
+ ** t1 LEFT OUTER JOIN (t2 JOIN t3)
+ **
+ ** If we flatten the above, we would get
+ **
+ ** (t1 LEFT OUTER JOIN t2) JOIN t3
+ **
+ ** which is not at all the same thing.
+ */
+ if( pSubSrc->nSrc>1 && iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0 ){
+ return 0;
+ }
+
+ /* Restriction 12: If the subquery is the right operand of a left outer
+ ** join, make sure the subquery has no WHERE clause.
+ ** An examples of why this is not allowed:
+ **
+ ** t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
+ **
+ ** If we flatten the above, we would get
+ **
+ ** (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
+ **
+ ** But the t2.x>0 test will always fail on a NULL row of t2, which
+ ** effectively converts the OUTER JOIN into an INNER JOIN.
+ */
+ if( iFrom>0 && (pSrc->a[iFrom-1].jointype & JT_OUTER)!=0
+ && pSub->pWhere!=0 ){
+ return 0;
+ }
+
+ /* If we reach this point, it means flattening is permitted for the
+ ** iFrom-th entry of the FROM clause in the outer query.
+ */
+
+ /* Move all of the FROM elements of the subquery into the
+ ** the FROM clause of the outer query. Before doing this, remember
+ ** the cursor number for the original outer query FROM element in
+ ** iParent. The iParent cursor will never be used. Subsequent code
+ ** will scan expressions looking for iParent references and tqreplace
+ ** those references with expressions that resolve to the subquery FROM
+ ** elements we are now copying in.
+ */
+ iParent = pSrc->a[iFrom].iCursor;
+ {
+ int nSubSrc = pSubSrc->nSrc;
+ int jointype = pSrc->a[iFrom].jointype;
+
+ if( pSrc->a[iFrom].pTab && pSrc->a[iFrom].pTab->isTransient ){
+ sqliteDeleteTable(0, pSrc->a[iFrom].pTab);
+ }
+ sqliteFree(pSrc->a[iFrom].zDatabase);
+ sqliteFree(pSrc->a[iFrom].zName);
+ sqliteFree(pSrc->a[iFrom].zAlias);
+ if( nSubSrc>1 ){
+ int extra = nSubSrc - 1;
+ for(i=1; i<nSubSrc; i++){
+ pSrc = sqliteSrcListAppend(pSrc, 0, 0);
+ }
+ p->pSrc = pSrc;
+ for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){
+ pSrc->a[i] = pSrc->a[i-extra];
+ }
+ }
+ for(i=0; i<nSubSrc; i++){
+ pSrc->a[i+iFrom] = pSubSrc->a[i];
+ memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
+ }
+ pSrc->a[iFrom+nSubSrc-1].jointype = jointype;
+ }
+
+ /* Now begin substituting subquery result set expressions for
+ ** references to the iParent in the outer query.
+ **
+ ** Example:
+ **
+ ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
+ ** \ \_____________ subquery __________/ /
+ ** \_____________________ outer query ______________________________/
+ **
+ ** We look at every expression in the outer query and every place we see
+ ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
+ */
+ substExprList(p->pEList, iParent, pSub->pEList);
+ pList = p->pEList;
+ for(i=0; i<pList->nExpr; i++){
+ Expr *pExpr;
+ if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
+ pList->a[i].zName = sqliteStrNDup(pExpr->span.z, pExpr->span.n);
+ }
+ }
+ if( isAgg ){
+ substExprList(p->pGroupBy, iParent, pSub->pEList);
+ substExpr(p->pHaving, iParent, pSub->pEList);
+ }
+ if( pSub->pOrderBy ){
+ assert( p->pOrderBy==0 );
+ p->pOrderBy = pSub->pOrderBy;
+ pSub->pOrderBy = 0;
+ }else if( p->pOrderBy ){
+ substExprList(p->pOrderBy, iParent, pSub->pEList);
+ }
+ if( pSub->pWhere ){
+ pWhere = sqliteExprDup(pSub->pWhere);
+ }else{
+ pWhere = 0;
+ }
+ if( subqueryIsAgg ){
+ assert( p->pHaving==0 );
+ p->pHaving = p->pWhere;
+ p->pWhere = pWhere;
+ substExpr(p->pHaving, iParent, pSub->pEList);
+ if( pSub->pHaving ){
+ Expr *pHaving = sqliteExprDup(pSub->pHaving);
+ if( p->pHaving ){
+ p->pHaving = sqliteExpr(TK_AND, p->pHaving, pHaving, 0);
+ }else{
+ p->pHaving = pHaving;
+ }
+ }
+ assert( p->pGroupBy==0 );
+ p->pGroupBy = sqliteExprListDup(pSub->pGroupBy);
+ }else if( p->pWhere==0 ){
+ p->pWhere = pWhere;
+ }else{
+ substExpr(p->pWhere, iParent, pSub->pEList);
+ if( pWhere ){
+ p->pWhere = sqliteExpr(TK_AND, p->pWhere, pWhere, 0);
+ }
+ }
+
+ /* The flattened query is distinct if either the inner or the
+ ** outer query is distinct.
+ */
+ p->isDistinct = p->isDistinct || pSub->isDistinct;
+
+ /* Transfer the limit expression from the subquery to the outer
+ ** query.
+ */
+ if( pSub->nLimit>=0 ){
+ if( p->nLimit<0 ){
+ p->nLimit = pSub->nLimit;
+ }else if( p->nLimit+p->nOffset > pSub->nLimit+pSub->nOffset ){
+ p->nLimit = pSub->nLimit + pSub->nOffset - p->nOffset;
+ }
+ }
+ p->nOffset += pSub->nOffset;
+
+ /* Finially, delete what is left of the subquery and return
+ ** success.
+ */
+ sqliteSelectDelete(pSub);
+ return 1;
+}
+
+/*
+** Analyze the SELECT statement passed in as an argument to see if it
+** is a simple min() or max() query. If it is and this query can be
+** satisfied using a single seek to the beginning or end of an index,
+** then generate the code for this SELECT and return 1. If this is not a
+** simple min() or max() query, then return 0;
+**
+** A simply min() or max() query looks like this:
+**
+** SELECT min(a) FROM table;
+** SELECT max(a) FROM table;
+**
+** The query may have only a single table in its FROM argument. There
+** can be no GROUP BY or HAVING or WHERE clauses. The result set must
+** be the min() or max() of a single column of the table. The column
+** in the min() or max() function must be indexed.
+**
+** The parameters to this routine are the same as for sqliteSelect().
+** See the header comment on that routine for additional information.
+*/
+static int simpleMinMaxQuery(Parse *pParse, Select *p, int eDest, int iParm){
+ Expr *pExpr;
+ int iCol;
+ Table *pTab;
+ Index *pIdx;
+ int base;
+ Vdbe *v;
+ int seekOp;
+ int cont;
+ ExprList eList;
+ struct ExprList_item eListItem;
+
+ /* Check to see if this query is a simple min() or max() query. Return
+ ** zero if it is not.
+ */
+ if( p->pGroupBy || p->pHaving || p->pWhere ) return 0;
+ if( p->pSrc->nSrc!=1 ) return 0;
+ if( p->pEList->nExpr!=1 ) return 0;
+ pExpr = p->pEList->a[0].pExpr;
+ if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
+ if( pExpr->pList==0 || pExpr->pList->nExpr!=1 ) return 0;
+ if( pExpr->token.n!=3 ) return 0;
+ if( sqliteStrNICmp(pExpr->token.z,"min",3)==0 ){
+ seekOp = OP_Rewind;
+ }else if( sqliteStrNICmp(pExpr->token.z,"max",3)==0 ){
+ seekOp = OP_Last;
+ }else{
+ return 0;
+ }
+ pExpr = pExpr->pList->a[0].pExpr;
+ if( pExpr->op!=TK_COLUMN ) return 0;
+ iCol = pExpr->iColumn;
+ pTab = p->pSrc->a[0].pTab;
+
+ /* If we get to here, it means the query is of the correct form.
+ ** Check to make sure we have an index and make pIdx point to the
+ ** appropriate index. If the min() or max() is on an INTEGER PRIMARY
+ ** key column, no index is necessary so set pIdx to NULL. If no
+ ** usable index is found, return 0.
+ */
+ if( iCol<0 ){
+ pIdx = 0;
+ }else{
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ assert( pIdx->nColumn>=1 );
+ if( pIdx->aiColumn[0]==iCol ) break;
+ }
+ if( pIdx==0 ) return 0;
+ }
+
+ /* Identify column types if we will be using the callback. This
+ ** step is skipped if the output is going to a table or a memory cell.
+ ** The column names have already been generated in the calling function.
+ */
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ) return 0;
+ if( eDest==SRT_Callback ){
+ generateColumnTypes(pParse, p->pSrc, p->pEList);
+ }
+
+ /* If the output is destined for a temporary table, open that table.
+ */
+ if( eDest==SRT_TempTable ){
+ sqliteVdbeAddOp(v, OP_OpenTemp, iParm, 0);
+ }
+
+ /* Generating code to tqfind the min or the max. Basically all we have
+ ** to do is tqfind the first or the last entry in the chosen index. If
+ ** the min() or max() is on the INTEGER PRIMARY KEY, then tqfind the first
+ ** or last entry in the main table.
+ */
+ sqliteCodeVerifySchema(pParse, pTab->iDb);
+ base = p->pSrc->a[0].iCursor;
+ computeLimitRegisters(pParse, p);
+ sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqliteVdbeOp3(v, OP_OpenRead, base, pTab->tnum, pTab->zName, 0);
+ cont = sqliteVdbeMakeLabel(v);
+ if( pIdx==0 ){
+ sqliteVdbeAddOp(v, seekOp, base, 0);
+ }else{
+ sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+ sqliteVdbeOp3(v, OP_OpenRead, base+1, pIdx->tnum, pIdx->zName, P3_STATIC);
+ sqliteVdbeAddOp(v, seekOp, base+1, 0);
+ sqliteVdbeAddOp(v, OP_IdxRecno, base+1, 0);
+ sqliteVdbeAddOp(v, OP_Close, base+1, 0);
+ sqliteVdbeAddOp(v, OP_MoveTo, base, 0);
+ }
+ eList.nExpr = 1;
+ memset(&eListItem, 0, sizeof(eListItem));
+ eList.a = &eListItem;
+ eList.a[0].pExpr = pExpr;
+ selectInnerLoop(pParse, p, &eList, 0, 0, 0, -1, eDest, iParm, cont, cont);
+ sqliteVdbeResolveLabel(v, cont);
+ sqliteVdbeAddOp(v, OP_Close, base, 0);
+ return 1;
+}
+
+/*
+** Generate code for the given SELECT statement.
+**
+** The results are distributed in various ways depending on the
+** value of eDest and iParm.
+**
+** eDest Value Result
+** ------------ -------------------------------------------
+** SRT_Callback Invoke the callback for each row of the result.
+**
+** SRT_Mem Store first result in memory cell iParm
+**
+** SRT_Set Store results as keys of a table with cursor iParm
+**
+** SRT_Union Store results as a key in a temporary table iParm
+**
+** SRT_Except Remove results from the temporary table iParm.
+**
+** SRT_Table Store results in temporary table iParm
+**
+** The table above is incomplete. Additional eDist value have be added
+** since this comment was written. See the selectInnerLoop() function for
+** a complete listing of the allowed values of eDest and their meanings.
+**
+** This routine returns the number of errors. If any errors are
+** encountered, then an appropriate error message is left in
+** pParse->zErrMsg.
+**
+** This routine does NOT free the Select structure passed in. The
+** calling function needs to do that.
+**
+** The pParent, parentTab, and *pParentAgg fields are filled in if this
+** SELECT is a subquery. This routine may try to combine this SELECT
+** with its tqparent to form a single flat query. In so doing, it might
+** change the tqparent query from a non-aggregate to an aggregate query.
+** For that reason, the pParentAgg flag is passed as a pointer, so it
+** can be changed.
+**
+** Example 1: The meaning of the pParent parameter.
+**
+** SELECT * FROM t1 JOIN (SELECT x, count(*) FROM t2) JOIN t3;
+** \ \_______ subquery _______/ /
+** \ /
+** \____________________ outer query ___________________/
+**
+** This routine is called for the outer query first. For that call,
+** pParent will be NULL. During the processing of the outer query, this
+** routine is called recursively to handle the subquery. For the recursive
+** call, pParent will point to the outer query. Because the subquery is
+** the second element in a three-way join, the parentTab parameter will
+** be 1 (the 2nd value of a 0-indexed array.)
+*/
+int sqliteSelect(
+ Parse *pParse, /* The parser context */
+ Select *p, /* The SELECT statement being coded. */
+ int eDest, /* How to dispose of the results */
+ int iParm, /* A parameter used by the eDest disposal method */
+ Select *pParent, /* Another SELECT for which this is a sub-query */
+ int parentTab, /* Index in pParent->pSrc of this query */
+ int *pParentAgg /* True if pParent uses aggregate functions */
+){
+ int i;
+ WhereInfo *pWInfo;
+ Vdbe *v;
+ int isAgg = 0; /* True for select lists like "count(*)" */
+ ExprList *pEList; /* List of columns to extract. */
+ SrcList *pTabList; /* List of tables to select from */
+ Expr *pWhere; /* The WHERE clause. May be NULL */
+ ExprList *pOrderBy; /* The ORDER BY clause. May be NULL */
+ ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
+ Expr *pHaving; /* The HAVING clause. May be NULL */
+ int isDistinct; /* True if the DISTINCT keyword is present */
+ int distinct; /* Table to use for the distinct set */
+ int rc = 1; /* Value to return from this function */
+
+ if( sqlite_malloc_failed || pParse->nErr || p==0 ) return 1;
+ if( sqliteAuthCheck(pParse, STQLITE_SELECT, 0, 0, 0) ) return 1;
+
+ /* If there is are a sequence of queries, do the earlier ones first.
+ */
+ if( p->pPrior ){
+ return multiSelect(pParse, p, eDest, iParm);
+ }
+
+ /* Make local copies of the parameters for this query.
+ */
+ pTabList = p->pSrc;
+ pWhere = p->pWhere;
+ pOrderBy = p->pOrderBy;
+ pGroupBy = p->pGroupBy;
+ pHaving = p->pHaving;
+ isDistinct = p->isDistinct;
+
+ /* Allocate VDBE cursors for each table in the FROM clause
+ */
+ sqliteSrcListAssignCursors(pParse, pTabList);
+
+ /*
+ ** Do not even attempt to generate any code if we have already seen
+ ** errors before this routine starts.
+ */
+ if( pParse->nErr>0 ) goto select_end;
+
+ /* Expand any "*" terms in the result set. (For example the "*" in
+ ** "SELECT * FROM t1") The fillInColumnlist() routine also does some
+ ** other housekeeping - see the header comment for details.
+ */
+ if( fillInColumnList(pParse, p) ){
+ goto select_end;
+ }
+ pWhere = p->pWhere;
+ pEList = p->pEList;
+ if( pEList==0 ) goto select_end;
+
+ /* If writing to memory or generating a set
+ ** only a single column may be output.
+ */
+ if( (eDest==SRT_Mem || eDest==SRT_Set) && pEList->nExpr>1 ){
+ sqliteErrorMsg(pParse, "only a single result allowed for "
+ "a SELECT that is part of an expression");
+ goto select_end;
+ }
+
+ /* ORDER BY is ignored for some destinations.
+ */
+ switch( eDest ){
+ case SRT_Union:
+ case SRT_Except:
+ case SRT_Discard:
+ pOrderBy = 0;
+ break;
+ default:
+ break;
+ }
+
+ /* At this point, we should have allocated all the cursors that we
+ ** need to handle subquerys and temporary tables.
+ **
+ ** Resolve the column names and do a semantics check on all the expressions.
+ */
+ for(i=0; i<pEList->nExpr; i++){
+ if( sqliteExprResolveIds(pParse, pTabList, 0, pEList->a[i].pExpr) ){
+ goto select_end;
+ }
+ if( sqliteExprCheck(pParse, pEList->a[i].pExpr, 1, &isAgg) ){
+ goto select_end;
+ }
+ }
+ if( pWhere ){
+ if( sqliteExprResolveIds(pParse, pTabList, pEList, pWhere) ){
+ goto select_end;
+ }
+ if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
+ goto select_end;
+ }
+ }
+ if( pHaving ){
+ if( pGroupBy==0 ){
+ sqliteErrorMsg(pParse, "a GROUP BY clause is required before HAVING");
+ goto select_end;
+ }
+ if( sqliteExprResolveIds(pParse, pTabList, pEList, pHaving) ){
+ goto select_end;
+ }
+ if( sqliteExprCheck(pParse, pHaving, 1, &isAgg) ){
+ goto select_end;
+ }
+ }
+ if( pOrderBy ){
+ for(i=0; i<pOrderBy->nExpr; i++){
+ int iCol;
+ Expr *pE = pOrderBy->a[i].pExpr;
+ if( sqliteExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){
+ sqliteExprDelete(pE);
+ pE = pOrderBy->a[i].pExpr = sqliteExprDup(pEList->a[iCol-1].pExpr);
+ }
+ if( sqliteExprResolveIds(pParse, pTabList, pEList, pE) ){
+ goto select_end;
+ }
+ if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
+ goto select_end;
+ }
+ if( sqliteExprIsConstant(pE) ){
+ if( sqliteExprIsInteger(pE, &iCol)==0 ){
+ sqliteErrorMsg(pParse,
+ "ORDER BY terms must not be non-integer constants");
+ goto select_end;
+ }else if( iCol<=0 || iCol>pEList->nExpr ){
+ sqliteErrorMsg(pParse,
+ "ORDER BY column number %d out of range - should be "
+ "between 1 and %d", iCol, pEList->nExpr);
+ goto select_end;
+ }
+ }
+ }
+ }
+ if( pGroupBy ){
+ for(i=0; i<pGroupBy->nExpr; i++){
+ int iCol;
+ Expr *pE = pGroupBy->a[i].pExpr;
+ if( sqliteExprIsInteger(pE, &iCol) && iCol>0 && iCol<=pEList->nExpr ){
+ sqliteExprDelete(pE);
+ pE = pGroupBy->a[i].pExpr = sqliteExprDup(pEList->a[iCol-1].pExpr);
+ }
+ if( sqliteExprResolveIds(pParse, pTabList, pEList, pE) ){
+ goto select_end;
+ }
+ if( sqliteExprCheck(pParse, pE, isAgg, 0) ){
+ goto select_end;
+ }
+ if( sqliteExprIsConstant(pE) ){
+ if( sqliteExprIsInteger(pE, &iCol)==0 ){
+ sqliteErrorMsg(pParse,
+ "GROUP BY terms must not be non-integer constants");
+ goto select_end;
+ }else if( iCol<=0 || iCol>pEList->nExpr ){
+ sqliteErrorMsg(pParse,
+ "GROUP BY column number %d out of range - should be "
+ "between 1 and %d", iCol, pEList->nExpr);
+ goto select_end;
+ }
+ }
+ }
+ }
+
+ /* Begin generating code.
+ */
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ) goto select_end;
+
+ /* Identify column names if we will be using them in a callback. This
+ ** step is skipped if the output is going to some other destination.
+ */
+ if( eDest==SRT_Callback ){
+ generateColumnNames(pParse, pTabList, pEList);
+ }
+
+ /* Check for the special case of a min() or max() function by itself
+ ** in the result set.
+ */
+ if( simpleMinMaxQuery(pParse, p, eDest, iParm) ){
+ rc = 0;
+ goto select_end;
+ }
+
+ /* Generate code for all sub-queries in the FROM clause
+ */
+ for(i=0; i<pTabList->nSrc; i++){
+ const char *zSavedAuthContext;
+ int needRestoreContext;
+
+ if( pTabList->a[i].pSelect==0 ) continue;
+ if( pTabList->a[i].zName!=0 ){
+ zSavedAuthContext = pParse->zAuthContext;
+ pParse->zAuthContext = pTabList->a[i].zName;
+ needRestoreContext = 1;
+ }else{
+ needRestoreContext = 0;
+ }
+ sqliteSelect(pParse, pTabList->a[i].pSelect, SRT_TempTable,
+ pTabList->a[i].iCursor, p, i, &isAgg);
+ if( needRestoreContext ){
+ pParse->zAuthContext = zSavedAuthContext;
+ }
+ pTabList = p->pSrc;
+ pWhere = p->pWhere;
+ if( eDest!=SRT_Union && eDest!=SRT_Except && eDest!=SRT_Discard ){
+ pOrderBy = p->pOrderBy;
+ }
+ pGroupBy = p->pGroupBy;
+ pHaving = p->pHaving;
+ isDistinct = p->isDistinct;
+ }
+
+ /* Check to see if this is a subquery that can be "flattened" into its tqparent.
+ ** If flattening is a possiblity, do so and return immediately.
+ */
+ if( pParent && pParentAgg &&
+ flattenSubquery(pParse, pParent, parentTab, *pParentAgg, isAgg) ){
+ if( isAgg ) *pParentAgg = 1;
+ return rc;
+ }
+
+ /* Set the limiter.
+ */
+ computeLimitRegisters(pParse, p);
+
+ /* Identify column types if we will be using a callback. This
+ ** step is skipped if the output is going to a destination other
+ ** than a callback.
+ **
+ ** We have to do this separately from the creation of column names
+ ** above because if the pTabList tqcontains views then they will not
+ ** have been resolved and we will not know the column types until
+ ** now.
+ */
+ if( eDest==SRT_Callback ){
+ generateColumnTypes(pParse, pTabList, pEList);
+ }
+
+ /* If the output is destined for a temporary table, open that table.
+ */
+ if( eDest==SRT_TempTable ){
+ sqliteVdbeAddOp(v, OP_OpenTemp, iParm, 0);
+ }
+
+ /* Do an analysis of aggregate expressions.
+ */
+ sqliteAggregateInfoReset(pParse);
+ if( isAgg || pGroupBy ){
+ assert( pParse->nAgg==0 );
+ isAgg = 1;
+ for(i=0; i<pEList->nExpr; i++){
+ if( sqliteExprAnalyzeAggregates(pParse, pEList->a[i].pExpr) ){
+ goto select_end;
+ }
+ }
+ if( pGroupBy ){
+ for(i=0; i<pGroupBy->nExpr; i++){
+ if( sqliteExprAnalyzeAggregates(pParse, pGroupBy->a[i].pExpr) ){
+ goto select_end;
+ }
+ }
+ }
+ if( pHaving && sqliteExprAnalyzeAggregates(pParse, pHaving) ){
+ goto select_end;
+ }
+ if( pOrderBy ){
+ for(i=0; i<pOrderBy->nExpr; i++){
+ if( sqliteExprAnalyzeAggregates(pParse, pOrderBy->a[i].pExpr) ){
+ goto select_end;
+ }
+ }
+ }
+ }
+
+ /* Reset the aggregator
+ */
+ if( isAgg ){
+ sqliteVdbeAddOp(v, OP_AggReset, 0, pParse->nAgg);
+ for(i=0; i<pParse->nAgg; i++){
+ FuncDef *pFunc;
+ if( (pFunc = pParse->aAgg[i].pFunc)!=0 && pFunc->xFinalize!=0 ){
+ sqliteVdbeOp3(v, OP_AggInit, 0, i, (char*)pFunc, P3_POINTER);
+ }
+ }
+ if( pGroupBy==0 ){
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ sqliteVdbeAddOp(v, OP_AggFocus, 0, 0);
+ }
+ }
+
+ /* Initialize the memory cell to NULL
+ */
+ if( eDest==SRT_Mem ){
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ sqliteVdbeAddOp(v, OP_MemStore, iParm, 1);
+ }
+
+ /* Open a temporary table to use for the distinct set.
+ */
+ if( isDistinct ){
+ distinct = pParse->nTab++;
+ sqliteVdbeAddOp(v, OP_OpenTemp, distinct, 1);
+ }else{
+ distinct = -1;
+ }
+
+ /* Begin the database scan
+ */
+ pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 0,
+ pGroupBy ? 0 : &pOrderBy);
+ if( pWInfo==0 ) goto select_end;
+
+ /* Use the standard inner loop if we are not dealing with
+ ** aggregates
+ */
+ if( !isAgg ){
+ if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
+ iParm, pWInfo->iContinue, pWInfo->iBreak) ){
+ goto select_end;
+ }
+ }
+
+ /* If we are dealing with aggregates, then do the special aggregate
+ ** processing.
+ */
+ else{
+ AggExpr *pAgg;
+ if( pGroupBy ){
+ int lbl1;
+ for(i=0; i<pGroupBy->nExpr; i++){
+ sqliteExprCode(pParse, pGroupBy->a[i].pExpr);
+ }
+ sqliteVdbeAddOp(v, OP_MakeKey, pGroupBy->nExpr, 0);
+ if( pParse->db->file_format>=4 ) sqliteAddKeyType(v, pGroupBy);
+ lbl1 = sqliteVdbeMakeLabel(v);
+ sqliteVdbeAddOp(v, OP_AggFocus, 0, lbl1);
+ for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
+ if( pAgg->isAgg ) continue;
+ sqliteExprCode(pParse, pAgg->pExpr);
+ sqliteVdbeAddOp(v, OP_AggSet, 0, i);
+ }
+ sqliteVdbeResolveLabel(v, lbl1);
+ }
+ for(i=0, pAgg=pParse->aAgg; i<pParse->nAgg; i++, pAgg++){
+ Expr *pE;
+ int nExpr;
+ FuncDef *pDef;
+ if( !pAgg->isAgg ) continue;
+ assert( pAgg->pFunc!=0 );
+ assert( pAgg->pFunc->xStep!=0 );
+ pDef = pAgg->pFunc;
+ pE = pAgg->pExpr;
+ assert( pE!=0 );
+ assert( pE->op==TK_AGG_FUNCTION );
+ nExpr = sqliteExprCodeExprList(pParse, pE->pList, pDef->includeTypes);
+ sqliteVdbeAddOp(v, OP_Integer, i, 0);
+ sqliteVdbeOp3(v, OP_AggFunc, 0, nExpr, (char*)pDef, P3_POINTER);
+ }
+ }
+
+ /* End the database scan loop.
+ */
+ sqliteWhereEnd(pWInfo);
+
+ /* If we are processing aggregates, we need to set up a second loop
+ ** over all of the aggregate values and process them.
+ */
+ if( isAgg ){
+ int endagg = sqliteVdbeMakeLabel(v);
+ int startagg;
+ startagg = sqliteVdbeAddOp(v, OP_AggNext, 0, endagg);
+ pParse->useAgg = 1;
+ if( pHaving ){
+ sqliteExprIfFalse(pParse, pHaving, startagg, 1);
+ }
+ if( selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, distinct, eDest,
+ iParm, startagg, endagg) ){
+ goto select_end;
+ }
+ sqliteVdbeAddOp(v, OP_Goto, 0, startagg);
+ sqliteVdbeResolveLabel(v, endagg);
+ sqliteVdbeAddOp(v, OP_Noop, 0, 0);
+ pParse->useAgg = 0;
+ }
+
+ /* If there is an ORDER BY clause, then we need to sort the results
+ ** and send them to the callback one by one.
+ */
+ if( pOrderBy ){
+ generateSortTail(p, v, pEList->nExpr, eDest, iParm);
+ }
+
+ /* If this was a subquery, we have now converted the subquery into a
+ ** temporary table. So delete the subquery structure from the tqparent
+ ** to prevent this subquery from being evaluated again and to force the
+ ** the use of the temporary table.
+ */
+ if( pParent ){
+ assert( pParent->pSrc->nSrc>parentTab );
+ assert( pParent->pSrc->a[parentTab].pSelect==p );
+ sqliteSelectDelete(p);
+ pParent->pSrc->a[parentTab].pSelect = 0;
+ }
+
+ /* The SELECT was successfully coded. Set the return code to 0
+ ** to indicate no errors.
+ */
+ rc = 0;
+
+ /* Control jumps to here if an error is encountered above, or upon
+ ** successful coding of the SELECT.
+ */
+select_end:
+ sqliteAggregateInfoReset(pParse);
+ return rc;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/shell.c b/tqtinterface/qt4/src/3rdparty/sqlite/shell.c
new file mode 100644
index 0000000..c35f02f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/shell.c
@@ -0,0 +1,1350 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains code to implement the "sqlite" command line
+** utility for accessing STQLite databases.
+**
+** $Id: shell.c,v 1.91 2004/02/25 02:25:37 drh Exp $
+*/
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "sqlite.h"
+#include <ctype.h>
+
+#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
+# include <signal.h>
+# include <pwd.h>
+# include <unistd.h>
+# include <sys/types.h>
+#endif
+
+#ifdef __MACOS__
+# include <console.h>
+# include <signal.h>
+# include <unistd.h>
+# include <extras.h>
+# include <Files.h>
+# include <Folders.h>
+#endif
+
+#if defined(HAVE_READLINE) && HAVE_READLINE==1
+# include <readline/readline.h>
+# include <readline/history.h>
+#else
+# define readline(p) local_getline(p,stdin)
+# define add_history(X)
+# define read_history(X)
+# define write_history(X)
+# define stifle_history(X)
+#endif
+
+/* Make sure isatty() has a prototype.
+*/
+extern int isatty();
+
+/*
+** The following is the open STQLite database. We make a pointer
+** to this database a static variable so that it can be accessed
+** by the SIGINT handler to interrupt database processing.
+*/
+static sqlite *db = 0;
+
+/*
+** True if an interrupt (Control-C) has been received.
+*/
+static int seenInterrupt = 0;
+
+/*
+** This is the name of our program. It is set in main(), used
+** in a number of other places, mostly for error messages.
+*/
+static char *Argv0;
+
+/*
+** Prompt strings. Initialized in main. Settable with
+** .prompt main continue
+*/
+static char mainPrompt[20]; /* First line prompt. default: "sqlite> "*/
+static char continuePrompt[20]; /* Continuation prompt. default: " ...> " */
+
+
+/*
+** Determines if a string is a number of not.
+*/
+extern int sqliteIsNumber(const char*);
+
+/*
+** This routine reads a line of text from standard input, stores
+** the text in memory obtained from malloc() and returns a pointer
+** to the text. NULL is returned at end of file, or if malloc()
+** fails.
+**
+** The interface is like "readline" but no command-line editing
+** is done.
+*/
+static char *local_getline(char *zPrompt, FILE *in){
+ char *zLine;
+ int nLine;
+ int n;
+ int eol;
+
+ if( zPrompt && *zPrompt ){
+ printf("%s",zPrompt);
+ fflush(stdout);
+ }
+ nLine = 100;
+ zLine = malloc( nLine );
+ if( zLine==0 ) return 0;
+ n = 0;
+ eol = 0;
+ while( !eol ){
+ if( n+100>nLine ){
+ nLine = nLine*2 + 100;
+ zLine = realloc(zLine, nLine);
+ if( zLine==0 ) return 0;
+ }
+ if( fgets(&zLine[n], nLine - n, in)==0 ){
+ if( n==0 ){
+ free(zLine);
+ return 0;
+ }
+ zLine[n] = 0;
+ eol = 1;
+ break;
+ }
+ while( zLine[n] ){ n++; }
+ if( n>0 && zLine[n-1]=='\n' ){
+ n--;
+ zLine[n] = 0;
+ eol = 1;
+ }
+ }
+ zLine = realloc( zLine, n+1 );
+ return zLine;
+}
+
+/*
+** Retrieve a single line of input text. "isatty" is true if text
+** is coming from a terminal. In that case, we issue a prompt and
+** attempt to use "readline" for command-line editing. If "isatty"
+** is false, use "local_getline" instead of "readline" and issue no prompt.
+**
+** zPrior is a string of prior text retrieved. If not the empty
+** string, then issue a continuation prompt.
+*/
+static char *one_input_line(const char *zPrior, FILE *in){
+ char *zPrompt;
+ char *zResult;
+ if( in!=0 ){
+ return local_getline(0, in);
+ }
+ if( zPrior && zPrior[0] ){
+ zPrompt = continuePrompt;
+ }else{
+ zPrompt = mainPrompt;
+ }
+ zResult = readline(zPrompt);
+ if( zResult ) add_history(zResult);
+ return zResult;
+}
+
+struct previous_mode_data {
+ int valid; /* Is there legit data in here? */
+ int mode;
+ int showHeader;
+ int colWidth[100];
+};
+/*
+** An pointer to an instance of this structure is passed from
+** the main program to the callback. This is used to communicate
+** state and mode information.
+*/
+struct callback_data {
+ sqlite *db; /* The database */
+ int echoOn; /* True to echo input commands */
+ int cnt; /* Number of records displayed so far */
+ FILE *out; /* Write results here */
+ int mode; /* An output mode setting */
+ int showHeader; /* True to show column names in List or Column mode */
+ char *zDestTable; /* Name of destination table when MODE_Insert */
+ char separator[20]; /* Separator character for MODE_List */
+ int colWidth[100]; /* Requested width of each column when in column mode*/
+ int actualWidth[100]; /* Actual width of each column */
+ char nullvalue[20]; /* The text to print when a NULL comes back from
+ ** the database */
+ struct previous_mode_data explainPrev;
+ /* Holds the mode information just before
+ ** .explain ON */
+ char outfile[FILENAME_MAX]; /* Filename for *out */
+ const char *zDbFilename; /* name of the database file */
+ char *zKey; /* Encryption key */
+};
+
+/*
+** These are the allowed modes.
+*/
+#define MODE_Line 0 /* One column per line. Blank line between records */
+#define MODE_Column 1 /* One record per line in neat columns */
+#define MODE_List 2 /* One record per line with a separator */
+#define MODE_Semi 3 /* Same as MODE_List but append ";" to each line */
+#define MODE_Html 4 /* Generate an XHTML table */
+#define MODE_Insert 5 /* Generate SQL "insert" statements */
+#define MODE_NUM_OF 6 /* The number of modes (not a mode itself) */
+
+char *modeDescr[MODE_NUM_OF] = {
+ "line",
+ "column",
+ "list",
+ "semi",
+ "html",
+ "insert"
+};
+
+/*
+** Number of elements in an array
+*/
+#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
+
+/*
+** Output the given string as a quoted string using SQL quoting conventions.
+*/
+static void output_quoted_string(FILE *out, const char *z){
+ int i;
+ int nSingle = 0;
+ for(i=0; z[i]; i++){
+ if( z[i]=='\'' ) nSingle++;
+ }
+ if( nSingle==0 ){
+ fprintf(out,"'%s'",z);
+ }else{
+ fprintf(out,"'");
+ while( *z ){
+ for(i=0; z[i] && z[i]!='\''; i++){}
+ if( i==0 ){
+ fprintf(out,"''");
+ z++;
+ }else if( z[i]=='\'' ){
+ fprintf(out,"%.*s''",i,z);
+ z += i+1;
+ }else{
+ fprintf(out,"%s",z);
+ break;
+ }
+ }
+ fprintf(out,"'");
+ }
+}
+
+/*
+** Output the given string with characters that are special to
+** HTML escaped.
+*/
+static void output_html_string(FILE *out, const char *z){
+ int i;
+ while( *z ){
+ for(i=0; z[i] && z[i]!='<' && z[i]!='&'; i++){}
+ if( i>0 ){
+ fprintf(out,"%.*s",i,z);
+ }
+ if( z[i]=='<' ){
+ fprintf(out,"&lt;");
+ }else if( z[i]=='&' ){
+ fprintf(out,"&amp;");
+ }else{
+ break;
+ }
+ z += i + 1;
+ }
+}
+
+/*
+** This routine runs when the user presses Ctrl-C
+*/
+static void interrupt_handler(int NotUsed){
+ seenInterrupt = 1;
+ if( db ) sqlite_interrupt(db);
+}
+
+/*
+** This is the callback routine that the STQLite library
+** invokes for each row of a query result.
+*/
+static int callback(void *pArg, int nArg, char **azArg, char **azCol){
+ int i;
+ struct callback_data *p = (struct callback_data*)pArg;
+ switch( p->mode ){
+ case MODE_Line: {
+ int w = 5;
+ if( azArg==0 ) break;
+ for(i=0; i<nArg; i++){
+ int len = strlen(azCol[i]);
+ if( len>w ) w = len;
+ }
+ if( p->cnt++>0 ) fprintf(p->out,"\n");
+ for(i=0; i<nArg; i++){
+ fprintf(p->out,"%*s = %s\n", w, azCol[i],
+ azArg[i] ? azArg[i] : p->nullvalue);
+ }
+ break;
+ }
+ case MODE_Column: {
+ if( p->cnt++==0 ){
+ for(i=0; i<nArg; i++){
+ int w, n;
+ if( i<ArraySize(p->colWidth) ){
+ w = p->colWidth[i];
+ }else{
+ w = 0;
+ }
+ if( w<=0 ){
+ w = strlen(azCol[i] ? azCol[i] : "");
+ if( w<10 ) w = 10;
+ n = strlen(azArg && azArg[i] ? azArg[i] : p->nullvalue);
+ if( w<n ) w = n;
+ }
+ if( i<ArraySize(p->actualWidth) ){
+ p->actualWidth[i] = w;
+ }
+ if( p->showHeader ){
+ fprintf(p->out,"%-*.*s%s",w,w,azCol[i], i==nArg-1 ? "\n": " ");
+ }
+ }
+ if( p->showHeader ){
+ for(i=0; i<nArg; i++){
+ int w;
+ if( i<ArraySize(p->actualWidth) ){
+ w = p->actualWidth[i];
+ }else{
+ w = 10;
+ }
+ fprintf(p->out,"%-*.*s%s",w,w,"-----------------------------------"
+ "----------------------------------------------------------",
+ i==nArg-1 ? "\n": " ");
+ }
+ }
+ }
+ if( azArg==0 ) break;
+ for(i=0; i<nArg; i++){
+ int w;
+ if( i<ArraySize(p->actualWidth) ){
+ w = p->actualWidth[i];
+ }else{
+ w = 10;
+ }
+ fprintf(p->out,"%-*.*s%s",w,w,
+ azArg[i] ? azArg[i] : p->nullvalue, i==nArg-1 ? "\n": " ");
+ }
+ break;
+ }
+ case MODE_Semi:
+ case MODE_List: {
+ if( p->cnt++==0 && p->showHeader ){
+ for(i=0; i<nArg; i++){
+ fprintf(p->out,"%s%s",azCol[i], i==nArg-1 ? "\n" : p->separator);
+ }
+ }
+ if( azArg==0 ) break;
+ for(i=0; i<nArg; i++){
+ char *z = azArg[i];
+ if( z==0 ) z = p->nullvalue;
+ fprintf(p->out, "%s", z);
+ if( i<nArg-1 ){
+ fprintf(p->out, "%s", p->separator);
+ }else if( p->mode==MODE_Semi ){
+ fprintf(p->out, ";\n");
+ }else{
+ fprintf(p->out, "\n");
+ }
+ }
+ break;
+ }
+ case MODE_Html: {
+ if( p->cnt++==0 && p->showHeader ){
+ fprintf(p->out,"<TR>");
+ for(i=0; i<nArg; i++){
+ fprintf(p->out,"<TH>%s</TH>",azCol[i]);
+ }
+ fprintf(p->out,"</TR>\n");
+ }
+ if( azArg==0 ) break;
+ fprintf(p->out,"<TR>");
+ for(i=0; i<nArg; i++){
+ fprintf(p->out,"<TD>");
+ output_html_string(p->out, azArg[i] ? azArg[i] : p->nullvalue);
+ fprintf(p->out,"</TD>\n");
+ }
+ fprintf(p->out,"</TR>\n");
+ break;
+ }
+ case MODE_Insert: {
+ if( azArg==0 ) break;
+ fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
+ for(i=0; i<nArg; i++){
+ char *zSep = i>0 ? ",": "";
+ if( azArg[i]==0 ){
+ fprintf(p->out,"%sNULL",zSep);
+ }else if( sqliteIsNumber(azArg[i]) ){
+ fprintf(p->out,"%s%s",zSep, azArg[i]);
+ }else{
+ if( zSep[0] ) fprintf(p->out,"%s",zSep);
+ output_quoted_string(p->out, azArg[i]);
+ }
+ }
+ fprintf(p->out,");\n");
+ break;
+ }
+ }
+ return 0;
+}
+
+/*
+** Set the destination table field of the callback_data structure to
+** the name of the table given. Escape any quote characters in the
+** table name.
+*/
+static void set_table_name(struct callback_data *p, const char *zName){
+ int i, n;
+ int needQuote;
+ char *z;
+
+ if( p->zDestTable ){
+ free(p->zDestTable);
+ p->zDestTable = 0;
+ }
+ if( zName==0 ) return;
+ needQuote = !isalpha(*zName) && *zName!='_';
+ for(i=n=0; zName[i]; i++, n++){
+ if( !isalnum(zName[i]) && zName[i]!='_' ){
+ needQuote = 1;
+ if( zName[i]=='\'' ) n++;
+ }
+ }
+ if( needQuote ) n += 2;
+ z = p->zDestTable = malloc( n+1 );
+ if( z==0 ){
+ fprintf(stderr,"Out of memory!\n");
+ exit(1);
+ }
+ n = 0;
+ if( needQuote ) z[n++] = '\'';
+ for(i=0; zName[i]; i++){
+ z[n++] = zName[i];
+ if( zName[i]=='\'' ) z[n++] = '\'';
+ }
+ if( needQuote ) z[n++] = '\'';
+ z[n] = 0;
+}
+
+/*
+** This is a different callback routine used for dumping the database.
+** Each row received by this callback consists of a table name,
+** the table type ("index" or "table") and SQL to create the table.
+** This routine should print text sufficient to recreate the table.
+*/
+static int dump_callback(void *pArg, int nArg, char **azArg, char **azCol){
+ struct callback_data *p = (struct callback_data *)pArg;
+ if( nArg!=3 ) return 1;
+ fprintf(p->out, "%s;\n", azArg[2]);
+ if( strcmp(azArg[1],"table")==0 ){
+ struct callback_data d2;
+ d2 = *p;
+ d2.mode = MODE_Insert;
+ d2.zDestTable = 0;
+ set_table_name(&d2, azArg[0]);
+ sqlite_exec_printf(p->db,
+ "SELECT * FROM '%q'",
+ callback, &d2, 0, azArg[0]
+ );
+ set_table_name(&d2, 0);
+ }
+ return 0;
+}
+
+/*
+** Text of a help message
+*/
+static char zHelp[] =
+ ".databases List names and files of attached databases\n"
+ ".dump ?TABLE? ... Dump the database in a text format\n"
+ ".echo ON|OFF Turn command echo on or off\n"
+ ".exit Exit this program\n"
+ ".explain ON|OFF Turn output mode suitable for EXPLAIN on or off.\n"
+ ".header(s) ON|OFF Turn display of headers on or off\n"
+ ".help Show this message\n"
+ ".indices TABLE Show names of all indices on TABLE\n"
+ ".mode MODE Set mode to one of \"line(s)\", \"column(s)\", \n"
+ " \"insert\", \"list\", or \"html\"\n"
+ ".mode insert TABLE Generate SQL insert statements for TABLE\n"
+ ".nullvalue STRING Print STRING instead of nothing for NULL data\n"
+ ".output FILENAME Send output to FILENAME\n"
+ ".output stdout Send output to the screen\n"
+ ".prompt MAIN CONTINUE Replace the standard prompts\n"
+ ".quit Exit this program\n"
+ ".read FILENAME Execute SQL in FILENAME\n"
+#ifdef STQLITE_HAS_CODEC
+ ".rekey OLD NEW NEW Change the encryption key\n"
+#endif
+ ".schema ?TABLE? Show the CREATE statements\n"
+ ".separator STRING Change separator string for \"list\" mode\n"
+ ".show Show the current values for various settings\n"
+ ".tables ?PATTERN? List names of tables matching a pattern\n"
+ ".timeout MS Try opening locked tables for MS milliseconds\n"
+ ".width NUM NUM ... Set column widths for \"column\" mode\n"
+;
+
+/* Forward reference */
+static void process_input(struct callback_data *p, FILE *in);
+
+/*
+** Make sure the database is open. If it is not, then open it. If
+** the database fails to open, print an error message and exit.
+*/
+static void open_db(struct callback_data *p){
+ if( p->db==0 ){
+ char *zErrMsg = 0;
+#ifdef STQLITE_HAS_CODEC
+ int n = p->zKey ? strlen(p->zKey) : 0;
+ db = p->db = sqlite_open_encrypted(p->zDbFilename, p->zKey, n, 0, &zErrMsg);
+#else
+ db = p->db = sqlite_open(p->zDbFilename, 0, &zErrMsg);
+#endif
+ if( p->db==0 ){
+ if( zErrMsg ){
+ fprintf(stderr,"Unable to open database \"%s\": %s\n",
+ p->zDbFilename, zErrMsg);
+ }else{
+ fprintf(stderr,"Unable to open database %s\n", p->zDbFilename);
+ }
+ exit(1);
+ }
+ }
+}
+
+/*
+** If an input line begins with "." then invoke this routine to
+** process that line.
+**
+** Return 1 to exit and 0 to continue.
+*/
+static int do_meta_command(char *zLine, struct callback_data *p){
+ int i = 1;
+ int nArg = 0;
+ int n, c;
+ int rc = 0;
+ char *azArg[50];
+
+ /* Parse the input line into tokens.
+ */
+ while( zLine[i] && nArg<ArraySize(azArg) ){
+ while( isspace(zLine[i]) ){ i++; }
+ if( zLine[i]=='\'' || zLine[i]=='"' ){
+ int delim = zLine[i++];
+ azArg[nArg++] = &zLine[i];
+ while( zLine[i] && zLine[i]!=delim ){ i++; }
+ if( zLine[i]==delim ){
+ zLine[i++] = 0;
+ }
+ }else{
+ azArg[nArg++] = &zLine[i];
+ while( zLine[i] && !isspace(zLine[i]) ){ i++; }
+ if( zLine[i] ) zLine[i++] = 0;
+ }
+ }
+
+ /* Process the input line.
+ */
+ if( nArg==0 ) return rc;
+ n = strlen(azArg[0]);
+ c = azArg[0][0];
+ if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
+ struct callback_data data;
+ char *zErrMsg = 0;
+ open_db(p);
+ memcpy(&data, p, sizeof(data));
+ data.showHeader = 0;
+ data.mode = MODE_Column;
+ sqlite_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
+ if( zErrMsg ){
+ fprintf(stderr,"Error: %s\n", zErrMsg);
+ sqlite_freemem(zErrMsg);
+ }
+ }else
+
+ if( c=='d' && strncmp(azArg[0], "dump", n)==0 ){
+ char *zErrMsg = 0;
+ open_db(p);
+ fprintf(p->out, "BEGIN TRANSACTION;\n");
+ if( nArg==1 ){
+ sqlite_exec(p->db,
+ "SELECT name, type, sql FROM sqlite_master "
+ "WHERE type!='meta' AND sql NOT NULL "
+ "ORDER BY substr(type,2,1), name",
+ dump_callback, p, &zErrMsg
+ );
+ }else{
+ int i;
+ for(i=1; i<nArg && zErrMsg==0; i++){
+ sqlite_exec_printf(p->db,
+ "SELECT name, type, sql FROM sqlite_master "
+ "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOT NULL "
+ "ORDER BY substr(type,2,1), name",
+ dump_callback, p, &zErrMsg, azArg[i]
+ );
+ }
+ }
+ if( zErrMsg ){
+ fprintf(stderr,"Error: %s\n", zErrMsg);
+ sqlite_freemem(zErrMsg);
+ }else{
+ fprintf(p->out, "COMMIT;\n");
+ }
+ }else
+
+ if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 ){
+ int j;
+ char *z = azArg[1];
+ int val = atoi(azArg[1]);
+ for(j=0; z[j]; j++){
+ if( isupper(z[j]) ) z[j] = tolower(z[j]);
+ }
+ if( strcmp(z,"on")==0 ){
+ val = 1;
+ }else if( strcmp(z,"yes")==0 ){
+ val = 1;
+ }
+ p->echoOn = val;
+ }else
+
+ if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
+ rc = 1;
+ }else
+
+ if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
+ int j;
+ char *z = nArg>=2 ? azArg[1] : "1";
+ int val = atoi(z);
+ for(j=0; z[j]; j++){
+ if( isupper(z[j]) ) z[j] = tolower(z[j]);
+ }
+ if( strcmp(z,"on")==0 ){
+ val = 1;
+ }else if( strcmp(z,"yes")==0 ){
+ val = 1;
+ }
+ if(val == 1) {
+ if(!p->explainPrev.valid) {
+ p->explainPrev.valid = 1;
+ p->explainPrev.mode = p->mode;
+ p->explainPrev.showHeader = p->showHeader;
+ memcpy(p->explainPrev.colWidth,p->colWidth,sizeof(p->colWidth));
+ }
+ /* We could put this code under the !p->explainValid
+ ** condition so that it does not execute if we are already in
+ ** explain mode. However, always executing it allows us an easy
+ ** was to reset to explain mode in case the user previously
+ ** did an .explain followed by a .width, .mode or .header
+ ** command.
+ */
+ p->mode = MODE_Column;
+ p->showHeader = 1;
+ memset(p->colWidth,0,ArraySize(p->colWidth));
+ p->colWidth[0] = 4;
+ p->colWidth[1] = 12;
+ p->colWidth[2] = 10;
+ p->colWidth[3] = 10;
+ p->colWidth[4] = 35;
+ }else if (p->explainPrev.valid) {
+ p->explainPrev.valid = 0;
+ p->mode = p->explainPrev.mode;
+ p->showHeader = p->explainPrev.showHeader;
+ memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
+ }
+ }else
+
+ if( c=='h' && (strncmp(azArg[0], "header", n)==0
+ ||
+ strncmp(azArg[0], "headers", n)==0 )&& nArg>1 ){
+ int j;
+ char *z = azArg[1];
+ int val = atoi(azArg[1]);
+ for(j=0; z[j]; j++){
+ if( isupper(z[j]) ) z[j] = tolower(z[j]);
+ }
+ if( strcmp(z,"on")==0 ){
+ val = 1;
+ }else if( strcmp(z,"yes")==0 ){
+ val = 1;
+ }
+ p->showHeader = val;
+ }else
+
+ if( c=='h' && strncmp(azArg[0], "help", n)==0 ){
+ fprintf(stderr,zHelp);
+ }else
+
+ if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
+ struct callback_data data;
+ char *zErrMsg = 0;
+ open_db(p);
+ memcpy(&data, p, sizeof(data));
+ data.showHeader = 0;
+ data.mode = MODE_List;
+ sqlite_exec_printf(p->db,
+ "SELECT name FROM sqlite_master "
+ "WHERE type='index' AND tbl_name LIKE '%q' "
+ "UNION ALL "
+ "SELECT name FROM sqlite_temp_master "
+ "WHERE type='index' AND tbl_name LIKE '%q' "
+ "ORDER BY 1",
+ callback, &data, &zErrMsg, azArg[1], azArg[1]
+ );
+ if( zErrMsg ){
+ fprintf(stderr,"Error: %s\n", zErrMsg);
+ sqlite_freemem(zErrMsg);
+ }
+ }else
+
+ if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
+ int n2 = strlen(azArg[1]);
+ if( strncmp(azArg[1],"line",n2)==0
+ ||
+ strncmp(azArg[1],"lines",n2)==0 ){
+ p->mode = MODE_Line;
+ }else if( strncmp(azArg[1],"column",n2)==0
+ ||
+ strncmp(azArg[1],"columns",n2)==0 ){
+ p->mode = MODE_Column;
+ }else if( strncmp(azArg[1],"list",n2)==0 ){
+ p->mode = MODE_List;
+ }else if( strncmp(azArg[1],"html",n2)==0 ){
+ p->mode = MODE_Html;
+ }else if( strncmp(azArg[1],"insert",n2)==0 ){
+ p->mode = MODE_Insert;
+ if( nArg>=3 ){
+ set_table_name(p, azArg[2]);
+ }else{
+ set_table_name(p, "table");
+ }
+ }else {
+ fprintf(stderr,"mode should be on of: column html insert line list\n");
+ }
+ }else
+
+ if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 && nArg==2 ) {
+ sprintf(p->nullvalue, "%.*s", (int)ArraySize(p->nullvalue)-1, azArg[1]);
+ }else
+
+ if( c=='o' && strncmp(azArg[0], "output", n)==0 && nArg==2 ){
+ if( p->out!=stdout ){
+ fclose(p->out);
+ }
+ if( strcmp(azArg[1],"stdout")==0 ){
+ p->out = stdout;
+ strcpy(p->outfile,"stdout");
+ }else{
+ p->out = fopen(azArg[1], "wb");
+ if( p->out==0 ){
+ fprintf(stderr,"can't write to \"%s\"\n", azArg[1]);
+ p->out = stdout;
+ } else {
+ strcpy(p->outfile,azArg[1]);
+ }
+ }
+ }else
+
+ if( c=='p' && strncmp(azArg[0], "prompt", n)==0 && (nArg==2 || nArg==3)){
+ if( nArg >= 2) {
+ strncpy(mainPrompt,azArg[1],(int)ArraySize(mainPrompt)-1);
+ }
+ if( nArg >= 3) {
+ strncpy(continuePrompt,azArg[2],(int)ArraySize(continuePrompt)-1);
+ }
+ }else
+
+ if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
+ rc = 1;
+ }else
+
+ if( c=='r' && strncmp(azArg[0], "read", n)==0 && nArg==2 ){
+ FILE *alt = fopen(azArg[1], "rb");
+ if( alt==0 ){
+ fprintf(stderr,"can't open \"%s\"\n", azArg[1]);
+ }else{
+ process_input(p, alt);
+ fclose(alt);
+ }
+ }else
+
+#ifdef STQLITE_HAS_CODEC
+ if( c=='r' && strncmp(azArg[0],"rekey", n)==0 && nArg==4 ){
+ char *zOld = p->zKey;
+ if( zOld==0 ) zOld = "";
+ if( strcmp(azArg[1],zOld) ){
+ fprintf(stderr,"old key is incorrect\n");
+ }else if( strcmp(azArg[2], azArg[3]) ){
+ fprintf(stderr,"2nd copy of new key does not match the 1st\n");
+ }else{
+ sqlite_freemem(p->zKey);
+ p->zKey = sqlite_mprintf("%s", azArg[2]);
+ sqlite_rekey(p->db, p->zKey, strlen(p->zKey));
+ }
+ }else
+#endif
+
+ if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
+ struct callback_data data;
+ char *zErrMsg = 0;
+ open_db(p);
+ memcpy(&data, p, sizeof(data));
+ data.showHeader = 0;
+ data.mode = MODE_Semi;
+ if( nArg>1 ){
+ extern int sqliteStrICmp(const char*,const char*);
+ if( sqliteStrICmp(azArg[1],"sqlite_master")==0 ){
+ char *new_argv[2], *new_colv[2];
+ new_argv[0] = "CREATE TABLE sqlite_master (\n"
+ " type text,\n"
+ " name text,\n"
+ " tbl_name text,\n"
+ " rootpage integer,\n"
+ " sql text\n"
+ ")";
+ new_argv[1] = 0;
+ new_colv[0] = "sql";
+ new_colv[1] = 0;
+ callback(&data, 1, new_argv, new_colv);
+ }else if( sqliteStrICmp(azArg[1],"sqlite_temp_master")==0 ){
+ char *new_argv[2], *new_colv[2];
+ new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
+ " type text,\n"
+ " name text,\n"
+ " tbl_name text,\n"
+ " rootpage integer,\n"
+ " sql text\n"
+ ")";
+ new_argv[1] = 0;
+ new_colv[0] = "sql";
+ new_colv[1] = 0;
+ callback(&data, 1, new_argv, new_colv);
+ }else{
+ sqlite_exec_printf(p->db,
+ "SELECT sql FROM "
+ " (SELECT * FROM sqlite_master UNION ALL"
+ " SELECT * FROM sqlite_temp_master) "
+ "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOTNULL "
+ "ORDER BY substr(type,2,1), name",
+ callback, &data, &zErrMsg, azArg[1]);
+ }
+ }else{
+ sqlite_exec(p->db,
+ "SELECT sql FROM "
+ " (SELECT * FROM sqlite_master UNION ALL"
+ " SELECT * FROM sqlite_temp_master) "
+ "WHERE type!='meta' AND sql NOTNULL "
+ "ORDER BY substr(type,2,1), name",
+ callback, &data, &zErrMsg
+ );
+ }
+ if( zErrMsg ){
+ fprintf(stderr,"Error: %s\n", zErrMsg);
+ sqlite_freemem(zErrMsg);
+ }
+ }else
+
+ if( c=='s' && strncmp(azArg[0], "separator", n)==0 && nArg==2 ){
+ sprintf(p->separator, "%.*s", (int)ArraySize(p->separator)-1, azArg[1]);
+ }else
+
+ if( c=='s' && strncmp(azArg[0], "show", n)==0){
+ int i;
+ fprintf(p->out,"%9.9s: %s\n","echo", p->echoOn ? "on" : "off");
+ fprintf(p->out,"%9.9s: %s\n","explain", p->explainPrev.valid ? "on" :"off");
+ fprintf(p->out,"%9.9s: %s\n","headers", p->showHeader ? "on" : "off");
+ fprintf(p->out,"%9.9s: %s\n","mode", modeDescr[p->mode]);
+ fprintf(p->out,"%9.9s: %s\n","nullvalue", p->nullvalue);
+ fprintf(p->out,"%9.9s: %s\n","output",
+ strlen(p->outfile) ? p->outfile : "stdout");
+ fprintf(p->out,"%9.9s: %s\n","separator", p->separator);
+ fprintf(p->out,"%9.9s: ","width");
+ for (i=0;i<(int)ArraySize(p->colWidth) && p->colWidth[i] != 0;i++) {
+ fprintf(p->out,"%d ",p->colWidth[i]);
+ }
+ fprintf(p->out,"\n\n");
+ }else
+
+ if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
+ char **azResult;
+ int nRow, rc;
+ char *zErrMsg;
+ open_db(p);
+ if( nArg==1 ){
+ rc = sqlite_get_table(p->db,
+ "SELECT name FROM sqlite_master "
+ "WHERE type IN ('table','view') "
+ "UNION ALL "
+ "SELECT name FROM sqlite_temp_master "
+ "WHERE type IN ('table','view') "
+ "ORDER BY 1",
+ &azResult, &nRow, 0, &zErrMsg
+ );
+ }else{
+ rc = sqlite_get_table_printf(p->db,
+ "SELECT name FROM sqlite_master "
+ "WHERE type IN ('table','view') AND name LIKE '%%%q%%' "
+ "UNION ALL "
+ "SELECT name FROM sqlite_temp_master "
+ "WHERE type IN ('table','view') AND name LIKE '%%%q%%' "
+ "ORDER BY 1",
+ &azResult, &nRow, 0, &zErrMsg, azArg[1], azArg[1]
+ );
+ }
+ if( zErrMsg ){
+ fprintf(stderr,"Error: %s\n", zErrMsg);
+ sqlite_freemem(zErrMsg);
+ }
+ if( rc==STQLITE_OK ){
+ int len, maxlen = 0;
+ int i, j;
+ int nPrintCol, nPrintRow;
+ for(i=1; i<=nRow; i++){
+ if( azResult[i]==0 ) continue;
+ len = strlen(azResult[i]);
+ if( len>maxlen ) maxlen = len;
+ }
+ nPrintCol = 80/(maxlen+2);
+ if( nPrintCol<1 ) nPrintCol = 1;
+ nPrintRow = (nRow + nPrintCol - 1)/nPrintCol;
+ for(i=0; i<nPrintRow; i++){
+ for(j=i+1; j<=nRow; j+=nPrintRow){
+ char *zSp = j<=nPrintRow ? "" : " ";
+ printf("%s%-*s", zSp, maxlen, azResult[j] ? azResult[j] : "");
+ }
+ printf("\n");
+ }
+ }
+ sqlite_free_table(azResult);
+ }else
+
+ if( c=='t' && n>1 && strncmp(azArg[0], "timeout", n)==0 && nArg>=2 ){
+ open_db(p);
+ sqlite_busy_timeout(p->db, atoi(azArg[1]));
+ }else
+
+ if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
+ int j;
+ for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
+ p->colWidth[j-1] = atoi(azArg[j]);
+ }
+ }else
+
+ {
+ fprintf(stderr, "unknown command or invalid arguments: "
+ " \"%s\". Enter \".help\" for help\n", azArg[0]);
+ }
+
+ return rc;
+}
+
+/*
+** Return TRUE if the last non-whitespace character in z[] is a semicolon.
+** z[] is N characters long.
+*/
+static int _ends_with_semicolon(const char *z, int N){
+ while( N>0 && isspace(z[N-1]) ){ N--; }
+ return N>0 && z[N-1]==';';
+}
+
+/*
+** Test to see if a line consists entirely of whitespace.
+*/
+static int _all_whitespace(const char *z){
+ for(; *z; z++){
+ if( isspace(*z) ) continue;
+ if( *z=='/' && z[1]=='*' ){
+ z += 2;
+ while( *z && (*z!='*' || z[1]!='/') ){ z++; }
+ if( *z==0 ) return 0;
+ z++;
+ continue;
+ }
+ if( *z=='-' && z[1]=='-' ){
+ z += 2;
+ while( *z && *z!='\n' ){ z++; }
+ if( *z==0 ) return 1;
+ continue;
+ }
+ return 0;
+ }
+ return 1;
+}
+
+/*
+** Return TRUE if the line typed in is an SQL command terminator other
+** than a semi-colon. The SQL Server style "go" command is understood
+** as is the Oracle "/".
+*/
+static int _is_command_terminator(const char *zLine){
+ extern int sqliteStrNICmp(const char*,const char*,int);
+ while( isspace(*zLine) ){ zLine++; };
+ if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ) return 1; /* Oracle */
+ if( sqliteStrNICmp(zLine,"go",2)==0 && _all_whitespace(&zLine[2]) ){
+ return 1; /* SQL Server */
+ }
+ return 0;
+}
+
+/*
+** Read input from *in and process it. If *in==0 then input
+** is interactive - the user is typing it it. Otherwise, input
+** is coming from a file or tqdevice. A prompt is issued and history
+** is saved only if input is interactive. An interrupt signal will
+** cause this routine to exit immediately, unless input is interactive.
+*/
+static void process_input(struct callback_data *p, FILE *in){
+ char *zLine;
+ char *zSql = 0;
+ int nSql = 0;
+ char *zErrMsg;
+ int rc;
+ while( fflush(p->out), (zLine = one_input_line(zSql, in))!=0 ){
+ if( seenInterrupt ){
+ if( in!=0 ) break;
+ seenInterrupt = 0;
+ }
+ if( p->echoOn ) printf("%s\n", zLine);
+ if( (zSql==0 || zSql[0]==0) && _all_whitespace(zLine) ) continue;
+ if( zLine && zLine[0]=='.' && nSql==0 ){
+ int rc = do_meta_command(zLine, p);
+ free(zLine);
+ if( rc ) break;
+ continue;
+ }
+ if( _is_command_terminator(zLine) ){
+ strcpy(zLine,";");
+ }
+ if( zSql==0 ){
+ int i;
+ for(i=0; zLine[i] && isspace(zLine[i]); i++){}
+ if( zLine[i]!=0 ){
+ nSql = strlen(zLine);
+ zSql = malloc( nSql+1 );
+ strcpy(zSql, zLine);
+ }
+ }else{
+ int len = strlen(zLine);
+ zSql = realloc( zSql, nSql + len + 2 );
+ if( zSql==0 ){
+ fprintf(stderr,"%s: out of memory!\n", Argv0);
+ exit(1);
+ }
+ strcpy(&zSql[nSql++], "\n");
+ strcpy(&zSql[nSql], zLine);
+ nSql += len;
+ }
+ free(zLine);
+ if( zSql && _ends_with_semicolon(zSql, nSql) && sqlite_complete(zSql) ){
+ p->cnt = 0;
+ open_db(p);
+ rc = sqlite_exec(p->db, zSql, callback, p, &zErrMsg);
+ if( rc || zErrMsg ){
+ if( in!=0 && !p->echoOn ) printf("%s\n",zSql);
+ if( zErrMsg!=0 ){
+ printf("SQL error: %s\n", zErrMsg);
+ sqlite_freemem(zErrMsg);
+ zErrMsg = 0;
+ }else{
+ printf("SQL error: %s\n", sqlite_error_string(rc));
+ }
+ }
+ free(zSql);
+ zSql = 0;
+ nSql = 0;
+ }
+ }
+ if( zSql ){
+ if( !_all_whitespace(zSql) ) printf("Incomplete SQL: %s\n", zSql);
+ free(zSql);
+ }
+}
+
+/*
+** Return a pathname which is the user's home directory. A
+** 0 return indicates an error of some kind. Space to hold the
+** resulting string is obtained from malloc(). The calling
+** function should free the result.
+*/
+static char *tqfind_home_dir(void){
+ char *home_dir = NULL;
+
+#if !defined(_WIN32) && !defined(WIN32) && !defined(__MACOS__)
+ struct passwd *pwent;
+ uid_t uid = getuid();
+ if( (pwent=getpwuid(uid)) != NULL) {
+ home_dir = pwent->pw_dir;
+ }
+#endif
+
+#ifdef __MACOS__
+ char home_path[_MAX_PATH+1];
+ home_dir = getcwd(home_path, _MAX_PATH);
+#endif
+
+ if (!home_dir) {
+ home_dir = getenv("HOME");
+ if (!home_dir) {
+ home_dir = getenv("HOMEPATH"); /* Windows? */
+ }
+ }
+
+#if defined(_WIN32) || defined(WIN32)
+ if (!home_dir) {
+ home_dir = "c:";
+ }
+#endif
+
+ if( home_dir ){
+ char *z = malloc( strlen(home_dir)+1 );
+ if( z ) strcpy(z, home_dir);
+ home_dir = z;
+ }
+
+ return home_dir;
+}
+
+/*
+** Read input from the file given by sqliterc_override. Or if that
+** parameter is NULL, take input from ~/.sqliterc
+*/
+static void process_sqliterc(
+ struct callback_data *p, /* Configuration data */
+ const char *sqliterc_override /* Name of config file. NULL to use default */
+){
+ char *home_dir = NULL;
+ const char *sqliterc = sqliterc_override;
+ char *zBuf;
+ FILE *in = NULL;
+
+ if (sqliterc == NULL) {
+ home_dir = tqfind_home_dir();
+ if( home_dir==0 ){
+ fprintf(stderr,"%s: cannot locate your home directory!\n", Argv0);
+ return;
+ }
+ zBuf = malloc(strlen(home_dir) + 15);
+ if( zBuf==0 ){
+ fprintf(stderr,"%s: out of memory!\n", Argv0);
+ exit(1);
+ }
+ sprintf(zBuf,"%s/.sqliterc",home_dir);
+ free(home_dir);
+ sqliterc = (const char*)zBuf;
+ }
+ in = fopen(sqliterc,"rb");
+ if( in ){
+ if( isatty(fileno(stdout)) ){
+ printf("Loading resources from %s\n",sqliterc);
+ }
+ process_input(p,in);
+ fclose(in);
+ }
+ return;
+}
+
+/*
+** Show available command line options
+*/
+static const char zOptions[] =
+ " -init filename read/process named file\n"
+ " -echo print commands before execution\n"
+ " -[no]header turn headers on or off\n"
+ " -column set output mode to 'column'\n"
+ " -html set output mode to HTML\n"
+#ifdef STQLITE_HAS_CODEC
+ " -key KEY encryption key\n"
+#endif
+ " -line set output mode to 'line'\n"
+ " -list set output mode to 'list'\n"
+ " -separator 'x' set output field separator (|)\n"
+ " -nullvalue 'text' set text string for NULL values\n"
+ " -version show STQLite version\n"
+ " -help show this text, also show dot-commands\n"
+;
+static void usage(int showDetail){
+ fprintf(stderr, "Usage: %s [OPTIONS] FILENAME [SQL]\n", Argv0);
+ if( showDetail ){
+ fprintf(stderr, "Options are:\n%s", zOptions);
+ }else{
+ fprintf(stderr, "Use the -help option for additional information\n");
+ }
+ exit(1);
+}
+
+/*
+** Initialize the state information in data
+*/
+void main_init(struct callback_data *data) {
+ memset(data, 0, sizeof(*data));
+ data->mode = MODE_List;
+ strcpy(data->separator,"|");
+ data->showHeader = 0;
+ strcpy(mainPrompt,"sqlite> ");
+ strcpy(continuePrompt," ...> ");
+}
+
+int main(int argc, char **argv){
+ char *zErrMsg = 0;
+ struct callback_data data;
+ const char *zInitFile = 0;
+ char *zFirstCmd = 0;
+ int i;
+ extern int sqliteOsFileExists(const char*);
+
+#ifdef __MACOS__
+ argc = ccommand(&argv);
+#endif
+
+ Argv0 = argv[0];
+ main_init(&data);
+
+ /* Make sure we have a valid signal handler early, before anything
+ ** else is done.
+ */
+#ifdef SIGINT
+ signal(SIGINT, interrupt_handler);
+#endif
+
+ /* Do an initial pass through the command-line argument to locate
+ ** the name of the database file, the name of the initialization file,
+ ** and the first command to execute.
+ */
+ for(i=1; i<argc-1; i++){
+ if( argv[i][0]!='-' ) break;
+ if( strcmp(argv[i],"-separator")==0 || strcmp(argv[i],"-nullvalue")==0 ){
+ i++;
+ }else if( strcmp(argv[i],"-init")==0 ){
+ i++;
+ zInitFile = argv[i];
+ }else if( strcmp(argv[i],"-key")==0 ){
+ i++;
+ data.zKey = sqlite_mprintf("%s",argv[i]);
+ }
+ }
+ if( i<argc ){
+ data.zDbFilename = argv[i++];
+ }else{
+ data.zDbFilename = ":memory:";
+ }
+ if( i<argc ){
+ zFirstCmd = argv[i++];
+ }
+ data.out = stdout;
+
+ /* Go ahead and open the database file if it already exists. If the
+ ** file does not exist, delay opening it. This prevents empty database
+ ** files from being created if a user mistypes the database name argument
+ ** to the sqlite command-line tool.
+ */
+ if( sqliteOsFileExists(data.zDbFilename) ){
+ open_db(&data);
+ }
+
+ /* Process the initialization file if there is one. If no -init option
+ ** is given on the command line, look for a file named ~/.sqliterc and
+ ** try to process it.
+ */
+ process_sqliterc(&data,zInitFile);
+
+ /* Make a second pass through the command-line argument and set
+ ** options. This second pass is delayed until after the initialization
+ ** file is processed so that the command-line arguments will override
+ ** settings in the initialization file.
+ */
+ for(i=1; i<argc && argv[i][0]=='-'; i++){
+ char *z = argv[i];
+ if( strcmp(z,"-init")==0 || strcmp(z,"-key")==0 ){
+ i++;
+ }else if( strcmp(z,"-html")==0 ){
+ data.mode = MODE_Html;
+ }else if( strcmp(z,"-list")==0 ){
+ data.mode = MODE_List;
+ }else if( strcmp(z,"-line")==0 ){
+ data.mode = MODE_Line;
+ }else if( strcmp(z,"-column")==0 ){
+ data.mode = MODE_Column;
+ }else if( strcmp(z,"-separator")==0 ){
+ i++;
+ sprintf(data.separator,"%.*s",(int)sizeof(data.separator)-1,argv[i]);
+ }else if( strcmp(z,"-nullvalue")==0 ){
+ i++;
+ sprintf(data.nullvalue,"%.*s",(int)sizeof(data.nullvalue)-1,argv[i]);
+ }else if( strcmp(z,"-header")==0 ){
+ data.showHeader = 1;
+ }else if( strcmp(z,"-noheader")==0 ){
+ data.showHeader = 0;
+ }else if( strcmp(z,"-echo")==0 ){
+ data.echoOn = 1;
+ }else if( strcmp(z,"-version")==0 ){
+ printf("%s\n", sqlite_version);
+ return 1;
+ }else if( strcmp(z,"-help")==0 ){
+ usage(1);
+ }else{
+ fprintf(stderr,"%s: unknown option: %s\n", Argv0, z);
+ fprintf(stderr,"Use -help for a list of options.\n");
+ return 1;
+ }
+ }
+
+ if( zFirstCmd ){
+ /* Run just the command that follows the database name
+ */
+ if( zFirstCmd[0]=='.' ){
+ do_meta_command(zFirstCmd, &data);
+ exit(0);
+ }else{
+ int rc;
+ open_db(&data);
+ rc = sqlite_exec(data.db, zFirstCmd, callback, &data, &zErrMsg);
+ if( rc!=0 && zErrMsg!=0 ){
+ fprintf(stderr,"SQL error: %s\n", zErrMsg);
+ exit(1);
+ }
+ }
+ }else{
+ /* Run commands received from standard input
+ */
+ if( isatty(fileno(stdout)) && isatty(fileno(stdin)) ){
+ char *zHome;
+ char *zHistory = 0;
+ printf(
+ "STQLite version %s\n"
+ "Enter \".help\" for instructions\n",
+ sqlite_version
+ );
+ zHome = tqfind_home_dir();
+ if( zHome && (zHistory = malloc(strlen(zHome)+20))!=0 ){
+ sprintf(zHistory,"%s/.sqlite_history", zHome);
+ }
+ if( zHistory ) read_history(zHistory);
+ process_input(&data, 0);
+ if( zHistory ){
+ stifle_history(100);
+ write_history(zHistory);
+ }
+ }else{
+ process_input(&data, stdin);
+ }
+ }
+ set_table_name(&data, 0);
+ if( db ) sqlite_close(db);
+ return 0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/sqlite.h b/tqtinterface/qt4/src/3rdparty/sqlite/sqlite.h
new file mode 100644
index 0000000..b1f2942
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/sqlite.h
@@ -0,0 +1,834 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This header file defines the interface that the STQLite library
+** presents to client programs.
+**
+** @(#) $Id: sqlite.h.in,v 1.59 2004/02/25 22:51:06 rdc Exp $
+*/
+#ifndef _STQLITE_H_
+#define _STQLITE_H_
+#include <stdarg.h> /* Needed for the definition of va_list */
+
+/*
+** Make sure we can call this stuff from C++.
+*/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+** The version of the STQLite library.
+*/
+#define STQLITE_VERSION "2.8.13"
+
+/*
+** The version string is also compiled into the library so that a program
+** can check to make sure that the lib*.a file and the *.h file are from
+** the same version.
+*/
+extern const char sqlite_version[];
+
+/*
+** The STQLITE_UTF8 macro is defined if the library expects to see
+** UTF-8 encoded data. The STQLITE_ISO8859 macro is defined if the
+** iso8859 encoded should be used.
+*/
+#define STQLITE_ISO8859 1
+
+/*
+** The following constant holds one of two strings, "UTF-8" or "iso8859",
+** depending on which character encoding the STQLite library expects to
+** see. The character encoding makes a difference for the LIKE and GLOB
+** operators and for the LENGTH() and SUBSTR() functions.
+*/
+extern const char sqlite_encoding[];
+
+/*
+** Each open sqlite database is represented by an instance of the
+** following opaque structure.
+*/
+typedef struct sqlite sqlite;
+
+/*
+** A function to open a new sqlite database.
+**
+** If the database does not exist and mode indicates write
+** permission, then a new database is created. If the database
+** does not exist and mode does not indicate write permission,
+** then the open fails, an error message generated (if errmsg!=0)
+** and the function returns 0.
+**
+** If mode does not indicates user write permission, then the
+** database is opened read-only.
+**
+** The Truth: As currently implemented, all databases are opened
+** for writing all the time. Maybe someday we will provide the
+** ability to open a database readonly. The mode parameters is
+** provided in anticipation of that enhancement.
+*/
+sqlite *sqlite_open(const char *filename, int mode, char **errmsg);
+
+/*
+** A function to close the database.
+**
+** Call this function with a pointer to a structure that was previously
+** returned from sqlite_open() and the corresponding database will by closed.
+*/
+void sqlite_close(sqlite *);
+
+/*
+** The type for a callback function.
+*/
+typedef int (*sqlite_callback)(void*,int,char**, char**);
+
+/*
+** A function to executes one or more statements of SQL.
+**
+** If one or more of the SQL statements are queries, then
+** the callback function specified by the 3rd parameter is
+** invoked once for each row of the query result. This callback
+** should normally return 0. If the callback returns a non-zero
+** value then the query is aborted, all subsequent SQL statements
+** are skipped and the sqlite_exec() function returns the STQLITE_ABORT.
+**
+** The 4th parameter is an arbitrary pointer that is passed
+** to the callback function as its first parameter.
+**
+** The 2nd parameter to the callback function is the number of
+** columns in the query result. The 3rd parameter to the callback
+** is an array of strings holding the values for each column.
+** The 4th parameter to the callback is an array of strings holding
+** the names of each column.
+**
+** The callback function may be NULL, even for queries. A NULL
+** callback is not an error. It just means that no callback
+** will be invoked.
+**
+** If an error occurs while parsing or evaluating the SQL (but
+** not while executing the callback) then an appropriate error
+** message is written into memory obtained from malloc() and
+** *errmsg is made to point to that message. The calling function
+** is responsible for freeing the memory that holds the error
+** message. Use sqlite_freemem() for this. If errmsg==NULL,
+** then no error message is ever written.
+**
+** The return value is is STQLITE_OK if there are no errors and
+** some other return code if there is an error. The particular
+** return value depends on the type of error.
+**
+** If the query could not be executed because a database file is
+** locked or busy, then this function returns STQLITE_BUSY. (This
+** behavior can be modified somewhat using the sqlite_busy_handler()
+** and sqlite_busy_timeout() functions below.)
+*/
+int sqlite_exec(
+ sqlite*, /* An open database */
+ const char *sql, /* SQL to be executed */
+ sqlite_callback, /* Callback function */
+ void *, /* 1st argument to callback function */
+ char **errmsg /* Error msg written here */
+);
+
+/*
+** Return values for sqlite_exec() and sqlite_step()
+*/
+#define STQLITE_OK 0 /* Successful result */
+#define STQLITE_ERROR 1 /* SQL error or missing database */
+#define STQLITE_INTERNAL 2 /* An internal logic error in STQLite */
+#define STQLITE_PERM 3 /* Access permission denied */
+#define STQLITE_ABORT 4 /* Callback routine requested an abort */
+#define STQLITE_BUSY 5 /* The database file is locked */
+#define STQLITE_LOCKED 6 /* A table in the database is locked */
+#define STQLITE_NOMEM 7 /* A malloc() failed */
+#define STQLITE_READONLY 8 /* Attempt to write a readonly database */
+#define STQLITE_INTERRUPT 9 /* Operation terminated by sqlite_interrupt() */
+#define STQLITE_IOERR 10 /* Some kind of disk I/O error occurred */
+#define STQLITE_CORRUPT 11 /* The database disk image is malformed */
+#define STQLITE_NOTFOUND 12 /* (Internal Only) Table or record not found */
+#define STQLITE_FULL 13 /* Insertion failed because database is full */
+#define STQLITE_CANTOPEN 14 /* Unable to open the database file */
+#define STQLITE_PROTOCOL 15 /* Database lock protocol error */
+#define STQLITE_EMPTY 16 /* (Internal Only) Database table is empty */
+#define STQLITE_SCHEMA 17 /* The database schema changed */
+#define STQLITE_TOOBIG 18 /* Too much data for one row of a table */
+#define STQLITE_CONSTRAINT 19 /* Abort due to contraint violation */
+#define STQLITE_MISMATCH 20 /* Data type mismatch */
+#define STQLITE_MISUSE 21 /* Library used incorrectly */
+#define STQLITE_NOLFS 22 /* Uses OS features not supported on host */
+#define STQLITE_AUTH 23 /* Authorization denied */
+#define STQLITE_FORMAT 24 /* Auxiliary database format error */
+#define STQLITE_RANGE 25 /* 2nd parameter to sqlite_bind out of range */
+#define STQLITE_NOTADB 26 /* File opened that is not a database file */
+#define STQLITE_ROW 100 /* sqlite_step() has another row ready */
+#define STQLITE_DONE 101 /* sqlite_step() has finished executing */
+
+/*
+** Each entry in an STQLite table has a unique integer key. (The key is
+** the value of the INTEGER PRIMARY KEY column if there is such a column,
+** otherwise the key is generated at random. The unique key is always
+** available as the ROWID, OID, or _ROWID_ column.) The following routine
+** returns the integer key of the most recent insert in the database.
+**
+** This function is similar to the mysql_insert_id() function from MySQL.
+*/
+int sqlite_last_insert_rowid(sqlite*);
+
+/*
+** This function returns the number of database rows that were changed
+** (or inserted or deleted) by the most recent called sqlite_exec().
+**
+** All changes are counted, even if they were later undone by a
+** ROLLBACK or ABORT. Except, changes associated with creating and
+** dropping tables are not counted.
+**
+** If a callback invokes sqlite_exec() recursively, then the changes
+** in the inner, recursive call are counted together with the changes
+** in the outer call.
+**
+** STQLite implements the command "DELETE FROM table" without a WHERE clause
+** by dropping and recreating the table. (This is much faster than going
+** through and deleting individual elements form the table.) Because of
+** this optimization, the change count for "DELETE FROM table" will be
+** zero regardless of the number of elements that were originally in the
+** table. To get an accurate count of the number of rows deleted, use
+** "DELETE FROM table WHERE 1" instead.
+*/
+int sqlite_changes(sqlite*);
+
+/*
+** This function returns the number of database rows that were changed
+** by the last INSERT, UPDATE, or DELETE statment executed by sqlite_exec(),
+** or by the last VM to run to completion. The change count is not updated
+** by SQL statements other than INSERT, UPDATE or DELETE.
+**
+** Changes are counted, even if they are later undone by a ROLLBACK or
+** ABORT. Changes associated with trigger programs that execute as a
+** result of the INSERT, UPDATE, or DELETE statement are not counted.
+**
+** If a callback invokes sqlite_exec() recursively, then the changes
+** in the inner, recursive call are counted together with the changes
+** in the outer call.
+**
+** STQLite implements the command "DELETE FROM table" without a WHERE clause
+** by dropping and recreating the table. (This is much faster than going
+** through and deleting individual elements form the table.) Because of
+** this optimization, the change count for "DELETE FROM table" will be
+** zero regardless of the number of elements that were originally in the
+** table. To get an accurate count of the number of rows deleted, use
+** "DELETE FROM table WHERE 1" instead.
+**
+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+*/
+int sqlite_last_statement_changes(sqlite*);
+
+/* If the parameter to this routine is one of the return value constants
+** defined above, then this routine returns a constant text string which
+** descripts (in English) the meaning of the return value.
+*/
+const char *sqlite_error_string(int);
+#define sqliteErrStr sqlite_error_string /* Legacy. Do not use in new code. */
+
+/* This function causes any pending database operation to abort and
+** return at its earliest opportunity. This routine is typically
+** called in response to a user action such as pressing "Cancel"
+** or Ctrl-C where the user wants a long query operation to halt
+** immediately.
+*/
+void sqlite_interrupt(sqlite*);
+
+
+/* This function returns true if the given input string comprises
+** one or more complete SQL statements.
+**
+** The algorithm is simple. If the last token other than spaces
+** and comments is a semicolon, then return true. otherwise return
+** false.
+*/
+int sqlite_complete(const char *sql);
+
+/*
+** This routine identifies a callback function that is invoked
+** whenever an attempt is made to open a database table that is
+** currently locked by another process or thread. If the busy callback
+** is NULL, then sqlite_exec() returns STQLITE_BUSY immediately if
+** it tqfinds a locked table. If the busy callback is not NULL, then
+** sqlite_exec() invokes the callback with three arguments. The
+** second argument is the name of the locked table and the third
+** argument is the number of times the table has been busy. If the
+** busy callback returns 0, then sqlite_exec() immediately returns
+** STQLITE_BUSY. If the callback returns non-zero, then sqlite_exec()
+** tries to open the table again and the cycle repeats.
+**
+** The default busy callback is NULL.
+**
+** Sqlite is re-entrant, so the busy handler may start a new query.
+** (It is not clear why anyone would every want to do this, but it
+** is allowed, in theory.) But the busy handler may not close the
+** database. Closing the database from a busy handler will delete
+** data structures out from under the executing query and will
+** probably result in a coredump.
+*/
+void sqlite_busy_handler(sqlite*, int(*)(void*,const char*,int), void*);
+
+/*
+** This routine sets a busy handler that sleeps for a while when a
+** table is locked. The handler will sleep multiple times until
+** at least "ms" milleseconds of sleeping have been done. After
+** "ms" milleseconds of sleeping, the handler returns 0 which
+** causes sqlite_exec() to return STQLITE_BUSY.
+**
+** Calling this routine with an argument less than or equal to zero
+** turns off all busy handlers.
+*/
+void sqlite_busy_timeout(sqlite*, int ms);
+
+/*
+** This next routine is really just a wrapper around sqlite_exec().
+** Instead of invoking a user-supplied callback for each row of the
+** result, this routine remembers each row of the result in memory
+** obtained from malloc(), then returns all of the result after the
+** query has finished.
+**
+** As an example, suppose the query result where this table:
+**
+** Name | Age
+** -----------------------
+** Alice | 43
+** Bob | 28
+** Cindy | 21
+**
+** If the 3rd argument were &azResult then after the function returns
+** azResult will contain the following data:
+**
+** azResult[0] = "Name";
+** azResult[1] = "Age";
+** azResult[2] = "Alice";
+** azResult[3] = "43";
+** azResult[4] = "Bob";
+** azResult[5] = "28";
+** azResult[6] = "Cindy";
+** azResult[7] = "21";
+**
+** Notice that there is an extra row of data containing the column
+** headers. But the *nrow return value is still 3. *ncolumn is
+** set to 2. In general, the number of values inserted into azResult
+** will be ((*nrow) + 1)*(*ncolumn).
+**
+** After the calling function has finished using the result, it should
+** pass the result data pointer to sqlite_free_table() in order to
+** release the memory that was malloc-ed. Because of the way the
+** malloc() happens, the calling function must not try to call
+** malloc() directly. Only sqlite_free_table() is able to release
+** the memory properly and safely.
+**
+** The return value of this routine is the same as from sqlite_exec().
+*/
+int sqlite_get_table(
+ sqlite*, /* An open database */
+ const char *sql, /* SQL to be executed */
+ char ***resultp, /* Result written to a char *[] that this points to */
+ int *nrow, /* Number of result rows written here */
+ int *ncolumn, /* Number of result columns written here */
+ char **errmsg /* Error msg written here */
+);
+
+/*
+** Call this routine to free the memory that sqlite_get_table() allocated.
+*/
+void sqlite_free_table(char **result);
+
+/*
+** The following routines are wrappers around sqlite_exec() and
+** sqlite_get_table(). The only difference between the routines that
+** follow and the originals is that the second argument to the
+** routines that follow is really a printf()-style format
+** string describing the SQL to be executed. Arguments to the format
+** string appear at the end of the argument list.
+**
+** All of the usual printf formatting options apply. In addition, there
+** is a "%q" option. %q works like %s in that it substitutes a null-terminated
+** string from the argument list. But %q also doubles every '\'' character.
+** %q is designed for use inside a string literal. By doubling each '\''
+** character it escapes that character and allows it to be inserted into
+** the string.
+**
+** For example, so some string variable tqcontains text as follows:
+**
+** char *zText = "It's a happy day!";
+**
+** We can use this text in an SQL statement as follows:
+**
+** sqlite_exec_printf(db, "INSERT INTO table VALUES('%q')",
+** callback1, 0, 0, zText);
+**
+** Because the %q format string is used, the '\'' character in zText
+** is escaped and the SQL generated is as follows:
+**
+** INSERT INTO table1 VALUES('It''s a happy day!')
+**
+** This is correct. Had we used %s instead of %q, the generated SQL
+** would have looked like this:
+**
+** INSERT INTO table1 VALUES('It's a happy day!');
+**
+** This second example is an SQL syntax error. As a general rule you
+** should always use %q instead of %s when inserting text into a string
+** literal.
+*/
+int sqlite_exec_printf(
+ sqlite*, /* An open database */
+ const char *sqlFormat, /* printf-style format string for the SQL */
+ sqlite_callback, /* Callback function */
+ void *, /* 1st argument to callback function */
+ char **errmsg, /* Error msg written here */
+ ... /* Arguments to the format string. */
+);
+int sqlite_exec_vprintf(
+ sqlite*, /* An open database */
+ const char *sqlFormat, /* printf-style format string for the SQL */
+ sqlite_callback, /* Callback function */
+ void *, /* 1st argument to callback function */
+ char **errmsg, /* Error msg written here */
+ va_list ap /* Arguments to the format string. */
+);
+int sqlite_get_table_printf(
+ sqlite*, /* An open database */
+ const char *sqlFormat, /* printf-style format string for the SQL */
+ char ***resultp, /* Result written to a char *[] that this points to */
+ int *nrow, /* Number of result rows written here */
+ int *ncolumn, /* Number of result columns written here */
+ char **errmsg, /* Error msg written here */
+ ... /* Arguments to the format string */
+);
+int sqlite_get_table_vprintf(
+ sqlite*, /* An open database */
+ const char *sqlFormat, /* printf-style format string for the SQL */
+ char ***resultp, /* Result written to a char *[] that this points to */
+ int *nrow, /* Number of result rows written here */
+ int *ncolumn, /* Number of result columns written here */
+ char **errmsg, /* Error msg written here */
+ va_list ap /* Arguments to the format string */
+);
+char *sqlite_mprintf(const char*,...);
+char *sqlite_vmprintf(const char*, va_list);
+
+/*
+** Windows systems should call this routine to free memory that
+** is returned in the in the errmsg parameter of sqlite_open() when
+** STQLite is a DLL. For some reason, it does not work to call free()
+** directly.
+*/
+void sqlite_freemem(void *p);
+
+/*
+** Windows systems need functions to call to return the sqlite_version
+** and sqlite_encoding strings.
+*/
+const char *sqlite_libversion(void);
+const char *sqlite_libencoding(void);
+
+/*
+** A pointer to the following structure is used to communicate with
+** the implementations of user-defined functions.
+*/
+typedef struct sqlite_func sqlite_func;
+
+/*
+** Use the following routines to create new user-defined functions. See
+** the documentation for details.
+*/
+int sqlite_create_function(
+ sqlite*, /* Database where the new function is registered */
+ const char *zName, /* Name of the new function */
+ int nArg, /* Number of arguments. -1 means any number */
+ void (*xFunc)(sqlite_func*,int,const char**), /* C code to implement */
+ void *pUserData /* Available via the sqlite_user_data() call */
+);
+int sqlite_create_aggregate(
+ sqlite*, /* Database where the new function is registered */
+ const char *zName, /* Name of the function */
+ int nArg, /* Number of arguments */
+ void (*xStep)(sqlite_func*,int,const char**), /* Called for each row */
+ void (*xFinalize)(sqlite_func*), /* Called once to get final result */
+ void *pUserData /* Available via the sqlite_user_data() call */
+);
+
+/*
+** Use the following routine to define the datatype returned by a
+** user-defined function. The second argument can be one of the
+** constants STQLITE_NUMERIC, STQLITE_TEXT, or STQLITE_ARGS or it
+** can be an integer greater than or equal to zero. When the datatype
+** parameter is non-negative, the type of the result will be the
+** same as the datatype-th argument. If datatype==STQLITE_NUMERIC
+** then the result is always numeric. If datatype==STQLITE_TEXT then
+** the result is always text. If datatype==STQLITE_ARGS then the result
+** is numeric if any argument is numeric and is text otherwise.
+*/
+int sqlite_function_type(
+ sqlite *db, /* The database there the function is registered */
+ const char *zName, /* Name of the function */
+ int datatype /* The datatype for this function */
+);
+#define STQLITE_NUMERIC (-1)
+#define STQLITE_TEXT (-2)
+#define STQLITE_ARGS (-3)
+
+/*
+** The user function implementations call one of the following four routines
+** in order to return their results. The first parameter to each of these
+** routines is a copy of the first argument to xFunc() or xFinialize().
+** The second parameter to these routines is the result to be returned.
+** A NULL can be passed as the second parameter to sqlite_set_result_string()
+** in order to return a NULL result.
+**
+** The 3rd argument to _string and _error is the number of characters to
+** take from the string. If this argument is negative, then all characters
+** up to and including the first '\000' are used.
+**
+** The sqlite_set_result_string() function allocates a buffer to hold the
+** result and returns a pointer to this buffer. The calling routine
+** (that is, the implmentation of a user function) can alter the content
+** of this buffer if desired.
+*/
+char *sqlite_set_result_string(sqlite_func*,const char*,int);
+void sqlite_set_result_int(sqlite_func*,int);
+void sqlite_set_result_double(sqlite_func*,double);
+void sqlite_set_result_error(sqlite_func*,const char*,int);
+
+/*
+** The pUserData parameter to the sqlite_create_function() and
+** sqlite_create_aggregate() routines used to register user functions
+** is available to the implementation of the function using this
+** call.
+*/
+void *sqlite_user_data(sqlite_func*);
+
+/*
+** Aggregate functions use the following routine to allocate
+** a structure for storing their state. The first time this routine
+** is called for a particular aggregate, a new structure of size nBytes
+** is allocated, zeroed, and returned. On subsequent calls (for the
+** same aggregate instance) the same buffer is returned. The implementation
+** of the aggregate can use the returned buffer to accumulate data.
+**
+** The buffer allocated is freed automatically be STQLite.
+*/
+void *sqlite_aggregate_context(sqlite_func*, int nBytes);
+
+/*
+** The next routine returns the number of calls to xStep for a particular
+** aggregate function instance. The current call to xStep counts so this
+** routine always returns at least 1.
+*/
+int sqlite_aggregate_count(sqlite_func*);
+
+/*
+** This routine registers a callback with the STQLite library. The
+** callback is invoked (at compile-time, not at run-time) for each
+** attempt to access a column of a table in the database. The callback
+** returns STQLITE_OK if access is allowed, STQLITE_DENY if the entire
+** SQL statement should be aborted with an error and STQLITE_IGNORE
+** if the column should be treated as a NULL value.
+*/
+int sqlite_set_authorizer(
+ sqlite*,
+ int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
+ void *pUserData
+);
+
+/*
+** The second parameter to the access authorization function above will
+** be one of the values below. These values signify what kind of operation
+** is to be authorized. The 3rd and 4th parameters to the authorization
+** function will be parameters or NULL depending on which of the following
+** codes is used as the second parameter. The 5th parameter is the name
+** of the database ("main", "temp", etc.) if applicable. The 6th parameter
+** is the name of the inner-most trigger or view that is responsible for
+** the access attempt or NULL if this access attempt is directly from
+** input SQL code.
+**
+** Arg-3 Arg-4
+*/
+#define STQLITE_COPY 0 /* Table Name File Name */
+#define STQLITE_CREATE_INDEX 1 /* Index Name Table Name */
+#define STQLITE_CREATE_TABLE 2 /* Table Name NULL */
+#define STQLITE_CREATE_TEMP_INDEX 3 /* Index Name Table Name */
+#define STQLITE_CREATE_TEMP_TABLE 4 /* Table Name NULL */
+#define STQLITE_CREATE_TEMP_TRIGGER 5 /* Trigger Name Table Name */
+#define STQLITE_CREATE_TEMP_VIEW 6 /* View Name NULL */
+#define STQLITE_CREATE_TRIGGER 7 /* Trigger Name Table Name */
+#define STQLITE_CREATE_VIEW 8 /* View Name NULL */
+#define STQLITE_DELETE 9 /* Table Name NULL */
+#define STQLITE_DROP_INDEX 10 /* Index Name Table Name */
+#define STQLITE_DROP_TABLE 11 /* Table Name NULL */
+#define STQLITE_DROP_TEMP_INDEX 12 /* Index Name Table Name */
+#define STQLITE_DROP_TEMP_TABLE 13 /* Table Name NULL */
+#define STQLITE_DROP_TEMP_TRIGGER 14 /* Trigger Name Table Name */
+#define STQLITE_DROP_TEMP_VIEW 15 /* View Name NULL */
+#define STQLITE_DROP_TRIGGER 16 /* Trigger Name Table Name */
+#define STQLITE_DROP_VIEW 17 /* View Name NULL */
+#define STQLITE_INSERT 18 /* Table Name NULL */
+#define STQLITE_PRAGMA 19 /* Pragma Name 1st arg or NULL */
+#define STQLITE_READ 20 /* Table Name Column Name */
+#define STQLITE_SELECT 21 /* NULL NULL */
+#define STQLITE_TRANSACTION 22 /* NULL NULL */
+#define STQLITE_UPDATE 23 /* Table Name Column Name */
+#define STQLITE_ATTACH 24 /* Filename NULL */
+#define STQLITE_DETACH 25 /* Database Name NULL */
+
+
+/*
+** The return value of the authorization function should be one of the
+** following constants:
+*/
+/* #define STQLITE_OK 0 // Allow access (This is actually defined above) */
+#define STQLITE_DENY 1 /* Abort the SQL statement with an error */
+#define STQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */
+
+/*
+** Register a function that is called at every invocation of sqlite_exec()
+** or sqlite_compile(). This function can be used (for example) to generate
+** a log file of all SQL executed against a database.
+*/
+void *sqlite_trace(sqlite*, void(*xTrace)(void*,const char*), void*);
+
+/*** The Callback-Free API
+**
+** The following routines implement a new way to access STQLite that does not
+** involve the use of callbacks.
+**
+** An sqlite_vm is an opaque object that represents a single SQL statement
+** that is ready to be executed.
+*/
+typedef struct sqlite_vm sqlite_vm;
+
+/*
+** To execute an STQLite query without the use of callbacks, you first have
+** to compile the SQL using this routine. The 1st parameter "db" is a pointer
+** to an sqlite object obtained from sqlite_open(). The 2nd parameter
+** "zSql" is the text of the SQL to be compiled. The remaining parameters
+** are all outputs.
+**
+** *pzTail is made to point to the first character past the end of the first
+** SQL statement in zSql. This routine only compiles the first statement
+** in zSql, so *pzTail is left pointing to what remains uncompiled.
+**
+** *ppVm is left pointing to a "virtual machine" that can be used to execute
+** the compiled statement. Or if there is an error, *ppVm may be set to NULL.
+** If the input text contained no SQL (if the input is and empty string or
+** a comment) then *ppVm is set to NULL.
+**
+** If any errors are detected during compilation, an error message is written
+** into space obtained from malloc() and *pzErrMsg is made to point to that
+** error message. The calling routine is responsible for freeing the text
+** of this message when it has finished with it. Use sqlite_freemem() to
+** free the message. pzErrMsg may be NULL in which case no error message
+** will be generated.
+**
+** On success, STQLITE_OK is returned. Otherwise and error code is returned.
+*/
+int sqlite_compile(
+ sqlite *db, /* The open database */
+ const char *zSql, /* SQL statement to be compiled */
+ const char **pzTail, /* OUT: uncompiled tail of zSql */
+ sqlite_vm **ppVm, /* OUT: the virtual machine to execute zSql */
+ char **pzErrmsg /* OUT: Error message. */
+);
+
+/*
+** After an SQL statement has been compiled, it is handed to this routine
+** to be executed. This routine executes the statement as far as it can
+** go then returns. The return value will be one of STQLITE_DONE,
+** STQLITE_ERROR, STQLITE_BUSY, STQLITE_ROW, or STQLITE_MISUSE.
+**
+** STQLITE_DONE means that the execute of the SQL statement is complete
+** an no errors have occurred. sqlite_step() should not be called again
+** for the same virtual machine. *pN is set to the number of columns in
+** the result set and *pazColName is set to an array of strings that
+** describe the column names and datatypes. The name of the i-th column
+** is (*pazColName)[i] and the datatype of the i-th column is
+** (*pazColName)[i+*pN]. *pazValue is set to NULL.
+**
+** STQLITE_ERROR means that the virtual machine encountered a run-time
+** error. sqlite_step() should not be called again for the same
+** virtual machine. *pN is set to 0 and *pazColName and *pazValue are set
+** to NULL. Use sqlite_finalize() to obtain the specific error code
+** and the error message text for the error.
+**
+** STQLITE_BUSY means that an attempt to open the database failed because
+** another thread or process is holding a lock. The calling routine
+** can try again to open the database by calling sqlite_step() again.
+** The return code will only be STQLITE_BUSY if no busy handler is registered
+** using the sqlite_busy_handler() or sqlite_busy_timeout() routines. If
+** a busy handler callback has been registered but returns 0, then this
+** routine will return STQLITE_ERROR and sqltie_finalize() will return
+** STQLITE_BUSY when it is called.
+**
+** STQLITE_ROW means that a single row of the result is now available.
+** The data is contained in *pazValue. The value of the i-th column is
+** (*azValue)[i]. *pN and *pazColName are set as described in STQLITE_DONE.
+** Invoke sqlite_step() again to advance to the next row.
+**
+** STQLITE_MISUSE is returned if sqlite_step() is called incorrectly.
+** For example, if you call sqlite_step() after the virtual machine
+** has halted (after a prior call to sqlite_step() has returned STQLITE_DONE)
+** or if you call sqlite_step() with an incorrectly initialized virtual
+** machine or a virtual machine that has been deleted or that is associated
+** with an sqlite structure that has been closed.
+*/
+int sqlite_step(
+ sqlite_vm *pVm, /* The virtual machine to execute */
+ int *pN, /* OUT: Number of columns in result */
+ const char ***pazValue, /* OUT: Column data */
+ const char ***pazColName /* OUT: Column names and datatypes */
+);
+
+/*
+** This routine is called to delete a virtual machine after it has finished
+** executing. The return value is the result code. STQLITE_OK is returned
+** if the statement executed successfully and some other value is returned if
+** there was any kind of error. If an error occurred and pzErrMsg is not
+** NULL, then an error message is written into memory obtained from malloc()
+** and *pzErrMsg is made to point to that error message. The calling routine
+** should use sqlite_freemem() to delete this message when it has finished
+** with it.
+**
+** This routine can be called at any point during the execution of the
+** virtual machine. If the virtual machine has not completed execution
+** when this routine is called, that is like encountering an error or
+** an interrupt. (See sqlite_interrupt().) Incomplete updates may be
+** rolled back and transactions cancelled, depending on the circumstances,
+** and the result code returned will be STQLITE_ABORT.
+*/
+int sqlite_finalize(sqlite_vm*, char **pzErrMsg);
+
+/*
+** This routine deletes the virtual machine, writes any error message to
+** *pzErrMsg and returns an STQLite return code in the same way as the
+** sqlite_finalize() function.
+**
+** Additionally, if ppVm is not NULL, *ppVm is left pointing to a new virtual
+** machine loaded with the compiled version of the original query ready for
+** execution.
+**
+** If sqlite_reset() returns STQLITE_SCHEMA, then *ppVm is set to NULL.
+**
+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+*/
+int sqlite_reset(sqlite_vm*, char **pzErrMsg);
+
+/*
+** If the SQL that was handed to sqlite_compile tqcontains variables that
+** are represeted in the SQL text by a question mark ('?'). This routine
+** is used to assign values to those variables.
+**
+** The first parameter is a virtual machine obtained from sqlite_compile().
+** The 2nd "idx" parameter determines which variable in the SQL statement
+** to bind the value to. The left most '?' is 1. The 3rd parameter is
+** the value to assign to that variable. The 4th parameter is the number
+** of bytes in the value, including the terminating \000 for strings.
+** Finally, the 5th "copy" parameter is TRUE if STQLite should make its
+** own private copy of this value, or false if the space that the 3rd
+** parameter points to will be unchanging and can be used directly by
+** STQLite.
+**
+** Unbound variables are treated as having a value of NULL. To explicitly
+** set a variable to NULL, call this routine with the 3rd parameter as a
+** NULL pointer.
+**
+** If the 4th "len" parameter is -1, then strlen() is used to tqfind the
+** length.
+**
+** This routine can only be called immediately after sqlite_compile()
+** or sqlite_reset() and before any calls to sqlite_step().
+**
+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+*/
+int sqlite_bind(sqlite_vm*, int idx, const char *value, int len, int copy);
+
+/*
+** This routine configures a callback function - the progress callback - that
+** is invoked periodically during long running calls to sqlite_exec(),
+** sqlite_step() and sqlite_get_table(). An example use for this API is to keep
+** a GUI updated during a large query.
+**
+** The progress callback is invoked once for every N virtual machine opcodes,
+** where N is the second argument to this function. The progress callback
+** itself is identified by the third argument to this function. The fourth
+** argument to this function is a void pointer passed to the progress callback
+** function each time it is invoked.
+**
+** If a call to sqlite_exec(), sqlite_step() or sqlite_get_table() results
+** in less than N opcodes being executed, then the progress callback is not
+** invoked.
+**
+** Calling this routine overwrites any previously installed progress callback.
+** To remove the progress callback altogether, pass NULL as the third
+** argument to this function.
+**
+** If the progress callback returns a result other than 0, then the current
+** query is immediately terminated and any database changes rolled back. If the
+** query was part of a larger transaction, then the transaction is not rolled
+** back and remains active. The sqlite_exec() call returns STQLITE_ABORT.
+**
+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+*/
+void sqlite_progress_handler(sqlite*, int, int(*)(void*), void*);
+
+/*
+** Register a callback function to be invoked whenever a new transaction
+** is committed. The pArg argument is passed through to the callback.
+** callback. If the callback function returns non-zero, then the commit
+** is converted into a rollback.
+**
+** If another function was previously registered, its pArg value is returned.
+** Otherwise NULL is returned.
+**
+** Registering a NULL function disables the callback.
+**
+******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
+*/
+void *sqlite_commit_hook(sqlite*, int(*)(void*), void*);
+
+/*
+** Open an encrypted STQLite database. If pKey==0 or nKey==0, this routine
+** is the same as sqlite_open().
+**
+** The code to implement this API is not available in the public release
+** of STQLite.
+*/
+sqlite *sqlite_open_encrypted(
+ const char *zFilename, /* Name of the encrypted database */
+ const void *pKey, /* Pointer to the key */
+ int nKey, /* Number of bytes in the key */
+ int *pErrcode, /* Write error code here */
+ char **pzErrmsg /* Write error message here */
+);
+
+/*
+** Change the key on an open database. If the current database is not
+** encrypted, this routine will encrypt it. If pNew==0 or nNew==0, the
+** database is decrypted.
+**
+** The code to implement this API is not available in the public release
+** of STQLite.
+*/
+int sqlite_rekey(
+ sqlite *db, /* Database to be rekeyed */
+ const void *pKey, int nKey /* The new key */
+);
+
+#ifdef __cplusplus
+} /* End of the 'extern "C"' block */
+#endif
+
+#endif /* _STQLITE_H_ */
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/sqliteInt.h b/tqtinterface/qt4/src/3rdparty/sqlite/sqliteInt.h
new file mode 100644
index 0000000..e435a1d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/sqliteInt.h
@@ -0,0 +1,1266 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Internal interface definitions for STQLite.
+**
+** @(#) $Id: sqliteInt.h,v 1.220 2004/02/25 13:47:33 drh Exp $
+*/
+#include "config.h"
+#include "sqlite.h"
+#include "hash.h"
+#include "parse.h"
+#include "btree.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+/*
+** The maximum number of in-memory pages to use for the main database
+** table and for temporary tables.
+*/
+#define MAX_PAGES 2000
+#define TEMP_PAGES 500
+
+/*
+** If the following macro is set to 1, then NULL values are considered
+** distinct for the SELECT DISTINCT statement and for UNION or EXCEPT
+** compound queries. No other SQL database engine (among those tested)
+** works this way except for OCELOT. But the SQL92 spec implies that
+** this is how things should work.
+**
+** If the following macro is set to 0, then NULLs are indistinct for
+** SELECT DISTINCT and for UNION.
+*/
+#define NULL_ALWAYS_DISTINCT 0
+
+/*
+** If the following macro is set to 1, then NULL values are considered
+** distinct when determining whether or not two entries are the same
+** in a UNITQUE index. This is the way PostgreSQL, Oracle, DB2, MySQL,
+** OCELOT, and Firebird all work. The SQL92 spec explicitly says this
+** is the way things are suppose to work.
+**
+** If the following macro is set to 0, the NULLs are indistinct for
+** a UNITQUE index. In this mode, you can only have a single NULL entry
+** for a column declared UNITQUE. This is the way Informix and SQL Server
+** work.
+*/
+#define NULL_DISTINCT_FOR_UNITQUE 1
+
+/*
+** The maximum number of attached databases. This must be at least 2
+** in order to support the main database file (0) and the file used to
+** hold temporary tables (1). And it must be less than 256 because
+** an unsigned character is used to stored the database index.
+*/
+#define MAX_ATTACHED 10
+
+/*
+** The next macro is used to determine where TEMP tables and indices
+** are stored. Possible values:
+**
+** 0 Always use a temporary files
+** 1 Use a file unless overridden by "PRAGMA temp_store"
+** 2 Use memory unless overridden by "PRAGMA temp_store"
+** 3 Always use memory
+*/
+#ifndef TEMP_STORE
+# define TEMP_STORE 1
+#endif
+
+/*
+** When building STQLite for embedded systems where memory is scarce,
+** you can define one or more of the following macros to omit extra
+** features of the library and thus keep the size of the library to
+** a minimum.
+*/
+/* #define STQLITE_OMIT_AUTHORIZATION 1 */
+/* #define STQLITE_OMIT_INMEMORYDB 1 */
+/* #define STQLITE_OMIT_VACUUM 1 */
+/* #define STQLITE_OMIT_DATETIME_FUNCS 1 */
+/* #define STQLITE_OMIT_PROGRESS_CALLBACK 1 */
+
+/*
+** Integers of known sizes. These typedefs might change for architectures
+** where the sizes very. Preprocessor macros are available so that the
+** types can be conveniently redefined at compile-type. Like this:
+**
+** cc '-DUINTPTR_TYPE=long long int' ...
+*/
+#ifndef UINT32_TYPE
+# define UINT32_TYPE unsigned int
+#endif
+#ifndef UINT16_TYPE
+# define UINT16_TYPE unsigned short int
+#endif
+#ifndef UINT8_TYPE
+# define UINT8_TYPE unsigned char
+#endif
+#ifndef INT8_TYPE
+# define INT8_TYPE signed char
+#endif
+#ifndef INTPTR_TYPE
+# if STQLITE_PTR_SZ==4
+# define INTPTR_TYPE int
+# else
+# define INTPTR_TYPE long long
+# endif
+#endif
+typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
+typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
+typedef UINT8_TYPE u8; /* 1-byte unsigned integer */
+typedef UINT8_TYPE i8; /* 1-byte signed integer */
+typedef INTPTR_TYPE ptr; /* Big enough to hold a pointer */
+typedef unsigned INTPTR_TYPE uptr; /* Big enough to hold a pointer */
+
+/*
+** Defer sourcing vdbe.h until after the "u8" typedef is defined.
+*/
+#include "vdbe.h"
+
+/*
+** Most C compilers these days recognize "long double", don't they?
+** Just in case we encounter one that does not, we will create a macro
+** for long double so that it can be easily changed to just "double".
+*/
+#ifndef LONGDOUBLE_TYPE
+# define LONGDOUBLE_TYPE long double
+#endif
+
+/*
+** This macro casts a pointer to an integer. Useful for doing
+** pointer arithmetic.
+*/
+#define Addr(X) ((uptr)X)
+
+/*
+** The maximum number of bytes of data that can be put into a single
+** row of a single table. The upper bound on this limit is 16777215
+** bytes (or 16MB-1). We have arbitrarily set the limit to just 1MB
+** here because the overflow page chain is inefficient for really big
+** records and we want to discourage people from thinking that
+** multi-megabyte records are OK. If your needs are different, you can
+** change this define and recompile to increase or decrease the record
+** size.
+**
+** The 16777198 is computed as follows: 238 bytes of payload on the
+** original pages plus 16448 overflow pages each holding 1020 bytes of
+** data.
+*/
+#define MAX_BYTES_PER_ROW 1048576
+/* #define MAX_BYTES_PER_ROW 16777198 */
+
+/*
+** If memory allocation problems are found, recompile with
+**
+** -DMEMORY_DEBUG=1
+**
+** to enable some sanity checking on malloc() and free(). To
+** check for memory leaks, recompile with
+**
+** -DMEMORY_DEBUG=2
+**
+** and a line of text will be written to standard error for
+** each malloc() and free(). This output can be analyzed
+** by an AWK script to determine if there are any leaks.
+*/
+#ifdef MEMORY_DEBUG
+# define sqliteMalloc(X) sqliteMalloc_(X,1,__FILE__,__LINE__)
+# define sqliteMallocRaw(X) sqliteMalloc_(X,0,__FILE__,__LINE__)
+# define sqliteFree(X) sqliteFree_(X,__FILE__,__LINE__)
+# define sqliteRealloc(X,Y) sqliteRealloc_(X,Y,__FILE__,__LINE__)
+# define sqliteStrDup(X) sqliteStrDup_(X,__FILE__,__LINE__)
+# define sqliteStrNDup(X,Y) sqliteStrNDup_(X,Y,__FILE__,__LINE__)
+ void sqliteStrRealloc(char**);
+#else
+# define sqliteRealloc_(X,Y) sqliteRealloc(X,Y)
+# define sqliteStrRealloc(X)
+#endif
+
+/*
+** This variable gets set if malloc() ever fails. After it gets set,
+** the STQLite library shuts down permanently.
+*/
+extern int sqlite_malloc_failed;
+
+/*
+** The following global variables are used for testing and debugging
+** only. They only work if MEMORY_DEBUG is defined.
+*/
+#ifdef MEMORY_DEBUG
+extern int sqlite_nMalloc; /* Number of sqliteMalloc() calls */
+extern int sqlite_nFree; /* Number of sqliteFree() calls */
+extern int sqlite_iMallocFail; /* Fail sqliteMalloc() after this many calls */
+#endif
+
+/*
+** Name of the master database table. The master database table
+** is a special table that holds the names and attributes of all
+** user tables and indices.
+*/
+#define MASTER_NAME "sqlite_master"
+#define TEMP_MASTER_NAME "sqlite_temp_master"
+
+/*
+** The name of the schema table.
+*/
+#define SCHEMA_TABLE(x) (x?TEMP_MASTER_NAME:MASTER_NAME)
+
+/*
+** A convenience macro that returns the number of elements in
+** an array.
+*/
+#define ArraySize(X) (sizeof(X)/sizeof(X[0]))
+
+/*
+** Forward references to structures
+*/
+typedef struct Column Column;
+typedef struct Table Table;
+typedef struct Index Index;
+typedef struct Instruction Instruction;
+typedef struct Expr Expr;
+typedef struct ExprList ExprList;
+typedef struct Parse Parse;
+typedef struct Token Token;
+typedef struct IdList IdList;
+typedef struct SrcList SrcList;
+typedef struct WhereInfo WhereInfo;
+typedef struct WhereLevel WhereLevel;
+typedef struct Select Select;
+typedef struct AggExpr AggExpr;
+typedef struct FuncDef FuncDef;
+typedef struct Trigger Trigger;
+typedef struct TriggerStep TriggerStep;
+typedef struct TriggerStack TriggerStack;
+typedef struct FKey FKey;
+typedef struct Db Db;
+typedef struct AuthContext AuthContext;
+
+/*
+** Each database file to be accessed by the system is an instance
+** of the following structure. There are normally two of these structures
+** in the sqlite.aDb[] array. aDb[0] is the main database file and
+** aDb[1] is the database file used to hold temporary tables. Additional
+** databases may be attached.
+*/
+struct Db {
+ char *zName; /* Name of this database */
+ Btree *pBt; /* The B*Tree structure for this database file */
+ int schema_cookie; /* Database schema version number for this file */
+ Hash tblHash; /* All tables indexed by name */
+ Hash idxHash; /* All (named) indices indexed by name */
+ Hash trigHash; /* All triggers indexed by name */
+ Hash aFKey; /* Foreign keys indexed by to-table */
+ u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */
+ u16 flags; /* Flags associated with this database */
+ void *pAux; /* Auxiliary data. Usually NULL */
+ void (*xFreeAux)(void*); /* Routine to free pAux */
+};
+
+/*
+** These macros can be used to test, set, or clear bits in the
+** Db.flags field.
+*/
+#define DbHasProperty(D,I,P) (((D)->aDb[I].flags&(P))==(P))
+#define DbHasAnyProperty(D,I,P) (((D)->aDb[I].flags&(P))!=0)
+#define DbSetProperty(D,I,P) (D)->aDb[I].flags|=(P)
+#define DbClearProperty(D,I,P) (D)->aDb[I].flags&=~(P)
+
+/*
+** Allowed values for the DB.flags field.
+**
+** The DB_Locked flag is set when the first OP_Transaction or OP_Checkpoint
+** opcode is emitted for a database. This prevents multiple occurances
+** of those opcodes for the same database in the same program. Similarly,
+** the DB_Cookie flag is set when the OP_VerifyCookie opcode is emitted,
+** and prevents duplicate OP_VerifyCookies from taking up space and slowing
+** down execution.
+**
+** The DB_SchemaLoaded flag is set after the database schema has been
+** read into internal hash tables.
+**
+** DB_UnresetViews means that one or more views have column names that
+** have been filled out. If the schema changes, these column names might
+** changes and so the view will need to be reset.
+*/
+#define DB_Locked 0x0001 /* OP_Transaction opcode has been emitted */
+#define DB_Cookie 0x0002 /* OP_VerifyCookie opcode has been emiited */
+#define DB_SchemaLoaded 0x0004 /* The schema has been loaded */
+#define DB_UnresetViews 0x0008 /* Some views have defined column names */
+
+
+/*
+** Each database is an instance of the following structure.
+**
+** The sqlite.file_format is initialized by the database file
+** and helps determines how the data in the database file is
+** represented. This field allows newer versions of the library
+** to read and write older databases. The various file formats
+** are as follows:
+**
+** file_format==1 Version 2.1.0.
+** file_format==2 Version 2.2.0. Add support for INTEGER PRIMARY KEY.
+** file_format==3 Version 2.6.0. Fix empty-string index bug.
+** file_format==4 Version 2.7.0. Add support for separate numeric and
+** text datatypes.
+**
+** The sqlite.temp_store determines where temporary database files
+** are stored. If 1, then a file is created to hold those tables. If
+** 2, then they are held in memory. 0 means use the default value in
+** the TEMP_STORE macro.
+**
+** The sqlite.lastRowid records the last insert rowid generated by an
+** insert statement. Inserts on views do not affect its value. Each
+** trigger has its own context, so that lastRowid can be updated inside
+** triggers as usual. The previous value will be restored once the trigger
+** exits. Upon entering a before or instead of trigger, lastRowid is no
+** longer (since after version 2.8.12) reset to -1.
+**
+** The sqlite.nChange does not count changes within triggers and keeps no
+** context. It is reset at start of sqlite_exec.
+** The sqlite.lsChange represents the number of changes made by the last
+** insert, update, or delete statement. It remains constant throughout the
+** length of a statement and is then updated by OP_SetCounts. It keeps a
+** context stack just like lastRowid so that the count of changes
+** within a trigger is not seen outside the trigger. Changes to views do not
+** affect the value of lsChange.
+** The sqlite.csChange keeps track of the number of current changes (since
+** the last statement) and is used to update sqlite_lsChange.
+*/
+struct sqlite {
+ int nDb; /* Number of backends currently in use */
+ Db *aDb; /* All backends */
+ Db aDbStatic[2]; /* Static space for the 2 default backends */
+ int flags; /* Miscellanous flags. See below */
+ u8 file_format; /* What file format version is this database? */
+ u8 safety_level; /* How aggressive at synching data to disk */
+ u8 want_to_close; /* Close after all VDBEs are deallocated */
+ u8 temp_store; /* 1=file, 2=memory, 0=compile-time default */
+ u8 onError; /* Default conflict algorithm */
+ int next_cookie; /* Next value of aDb[0].schema_cookie */
+ int cache_size; /* Number of pages to use in the cache */
+ int nTable; /* Number of tables in the database */
+ void *pBusyArg; /* 1st Argument to the busy callback */
+ int (*xBusyCallback)(void *,const char*,int); /* The busy callback */
+ void *pCommitArg; /* Argument to xCommitCallback() */
+ int (*xCommitCallback)(void*);/* Invoked at every commit. */
+ Hash aFunc; /* All functions that can be in SQL exprs */
+ int lastRowid; /* ROWID of most recent insert (see above) */
+ int priorNewRowid; /* Last randomly generated ROWID */
+ int magic; /* Magic number for detect library misuse */
+ int nChange; /* Number of rows changed (see above) */
+ int lsChange; /* Last statement change count (see above) */
+ int csChange; /* Current statement change count (see above) */
+ struct sqliteInitInfo { /* Information used during initialization */
+ int iDb; /* When back is being initialized */
+ int newTnum; /* Rootpage of table being initialized */
+ u8 busy; /* TRUE if currently initializing */
+ } init;
+ struct Vdbe *pVdbe; /* List of active virtual machines */
+ void (*xTrace)(void*,const char*); /* Trace function */
+ void *pTraceArg; /* Argument to the trace function */
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
+ /* Access authorization function */
+ void *pAuthArg; /* 1st argument to the access auth function */
+#endif
+#ifndef STQLITE_OMIT_PROGRESS_CALLBACK
+ int (*xProgress)(void *); /* The progress callback */
+ void *pProgressArg; /* Argument to the progress callback */
+ int nProgressOps; /* Number of opcodes for progress callback */
+#endif
+};
+
+/*
+** Possible values for the sqlite.flags and or Db.flags fields.
+**
+** On sqlite.flags, the STQLITE_InTrans value means that we have
+** executed a BEGIN. On Db.flags, STQLITE_InTrans means a statement
+** transaction is active on that particular database file.
+*/
+#define STQLITE_VdbeTrace 0x00000001 /* True to trace VDBE execution */
+#define STQLITE_Initialized 0x00000002 /* True after initialization */
+#define STQLITE_Interrupt 0x00000004 /* Cancel current operation */
+#define STQLITE_InTrans 0x00000008 /* True if in a transaction */
+#define STQLITE_InternChanges 0x00000010 /* Uncommitted Hash table changes */
+#define STQLITE_FullColNames 0x00000020 /* Show full column names on SELECT */
+#define STQLITE_ShortColNames 0x00000040 /* Show short columns names */
+#define STQLITE_CountRows 0x00000080 /* Count rows changed by INSERT, */
+ /* DELETE, or UPDATE and return */
+ /* the count using a callback. */
+#define STQLITE_NullCallback 0x00000100 /* Invoke the callback once if the */
+ /* result set is empty */
+#define STQLITE_ReportTypes 0x00000200 /* Include information on datatypes */
+ /* in 4th argument of callback */
+
+/*
+** Possible values for the sqlite.magic field.
+** The numbers are obtained at random and have no special meaning, other
+** than being distinct from one another.
+*/
+#define STQLITE_MAGIC_OPEN 0xa029a697 /* Database is open */
+#define STQLITE_MAGIC_CLOSED 0x9f3c2d33 /* Database is closed */
+#define STQLITE_MAGIC_BUSY 0xf03b7906 /* Database currently in use */
+#define STQLITE_MAGIC_ERROR 0xb5357930 /* An STQLITE_MISUSE error occurred */
+
+/*
+** Each SQL function is defined by an instance of the following
+** structure. A pointer to this structure is stored in the sqlite.aFunc
+** hash table. When multiple functions have the same name, the hash table
+** points to a linked list of these structures.
+*/
+struct FuncDef {
+ void (*xFunc)(sqlite_func*,int,const char**); /* Regular function */
+ void (*xStep)(sqlite_func*,int,const char**); /* Aggregate function step */
+ void (*xFinalize)(sqlite_func*); /* Aggregate function finializer */
+ signed char nArg; /* Number of arguments. -1 means unlimited */
+ signed char dataType; /* Arg that determines datatype. -1=NUMERIC, */
+ /* -2=TEXT. -3=STQLITE_ARGS */
+ u8 includeTypes; /* Add datatypes to args of xFunc and xStep */
+ void *pUserData; /* User data parameter */
+ FuncDef *pNext; /* Next function with same name */
+};
+
+/*
+** information about each column of an SQL table is held in an instance
+** of this structure.
+*/
+struct Column {
+ char *zName; /* Name of this column */
+ char *zDflt; /* Default value of this column */
+ char *zType; /* Data type for this column */
+ u8 notNull; /* True if there is a NOT NULL constraint */
+ u8 isPrimKey; /* True if this column is part of the PRIMARY KEY */
+ u8 sortOrder; /* Some combination of STQLITE_SO_... values */
+ u8 dottedName; /* True if zName tqcontains a "." character */
+};
+
+/*
+** The allowed sort orders.
+**
+** The TEXT and NUM values use bits that do not overlap with DESC and ASC.
+** That way the two can be combined into a single number.
+*/
+#define STQLITE_SO_UNK 0 /* Use the default collating type. (SCT_NUM) */
+#define STQLITE_SO_TEXT 2 /* Sort using memcmp() */
+#define STQLITE_SO_NUM 4 /* Sort using sqliteCompare() */
+#define STQLITE_SO_TYPEMASK 6 /* Mask to extract the collating sequence */
+#define STQLITE_SO_ASC 0 /* Sort in ascending order */
+#define STQLITE_SO_DESC 1 /* Sort in descending order */
+#define STQLITE_SO_DIRMASK 1 /* Mask to extract the sort direction */
+
+/*
+** Each SQL table is represented in memory by an instance of the
+** following structure.
+**
+** Table.zName is the name of the table. The case of the original
+** CREATE TABLE statement is stored, but case is not significant for
+** comparisons.
+**
+** Table.nCol is the number of columns in this table. Table.aCol is a
+** pointer to an array of Column structures, one for each column.
+**
+** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of
+** the column that is that key. Otherwise Table.iPKey is negative. Note
+** that the datatype of the PRIMARY KEY must be INTEGER for this field to
+** be set. An INTEGER PRIMARY KEY is used as the rowid for each row of
+** the table. If a table has no INTEGER PRIMARY KEY, then a random rowid
+** is generated for each row of the table. Table.hasPrimKey is true if
+** the table has any PRIMARY KEY, INTEGER or otherwise.
+**
+** Table.tnum is the page number for the root BTree page of the table in the
+** database file. If Table.iDb is the index of the database table backend
+** in sqlite.aDb[]. 0 is for the main database and 1 is for the file that
+** holds temporary tables and indices. If Table.isTransient
+** is true, then the table is stored in a file that is automatically deleted
+** when the VDBE cursor to the table is closed. In this case Table.tnum
+** refers VDBE cursor number that holds the table open, not to the root
+** page number. Transient tables are used to hold the results of a
+** sub-query that appears instead of a real table name in the FROM clause
+** of a SELECT statement.
+*/
+struct Table {
+ char *zName; /* Name of the table */
+ int nCol; /* Number of columns in this table */
+ Column *aCol; /* Information about each column */
+ int iPKey; /* If not less then 0, use aCol[iPKey] as the primary key */
+ Index *pIndex; /* List of SQL indexes on this table. */
+ int tnum; /* Root BTree node for this table (see note above) */
+ Select *pSelect; /* NULL for tables. Points to definition if a view. */
+ u8 readOnly; /* True if this table should not be written by the user */
+ u8 iDb; /* Index into sqlite.aDb[] of the backend for this table */
+ u8 isTransient; /* True if automatically deleted when VDBE finishes */
+ u8 hasPrimKey; /* True if there exists a primary key */
+ u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
+ Trigger *pTrigger; /* List of SQL triggers on this table */
+ FKey *pFKey; /* Linked list of all foreign keys in this table */
+};
+
+/*
+** Each foreign key constraint is an instance of the following structure.
+**
+** A foreign key is associated with two tables. The "from" table is
+** the table that tqcontains the REFERENCES clause that creates the foreign
+** key. The "to" table is the table that is named in the REFERENCES clause.
+** Consider this example:
+**
+** CREATE TABLE ex1(
+** a INTEGER PRIMARY KEY,
+** b INTEGER CONSTRAINT fk1 REFERENCES ex2(x)
+** );
+**
+** For foreign key "fk1", the from-table is "ex1" and the to-table is "ex2".
+**
+** Each REFERENCES clause generates an instance of the following structure
+** which is attached to the from-table. The to-table need not exist when
+** the from-table is created. The existance of the to-table is not checked
+** until an attempt is made to insert data into the from-table.
+**
+** The sqlite.aFKey hash table stores pointers to this structure
+** given the name of a to-table. For each to-table, all foreign keys
+** associated with that table are on a linked list using the FKey.pNextTo
+** field.
+*/
+struct FKey {
+ Table *pFrom; /* The table that constains the REFERENCES clause */
+ FKey *pNextFrom; /* Next foreign key in pFrom */
+ char *zTo; /* Name of table that the key points to */
+ FKey *pNextTo; /* Next foreign key that points to zTo */
+ int nCol; /* Number of columns in this key */
+ struct sColMap { /* Mapping of columns in pFrom to columns in zTo */
+ int iFrom; /* Index of column in pFrom */
+ char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */
+ } *aCol; /* One entry for each of nCol column s */
+ u8 isDeferred; /* True if constraint checking is deferred till COMMIT */
+ u8 updateConf; /* How to resolve conflicts that occur on UPDATE */
+ u8 deleteConf; /* How to resolve conflicts that occur on DELETE */
+ u8 insertConf; /* How to resolve conflicts that occur on INSERT */
+};
+
+/*
+** STQLite supports many different ways to resolve a contraint
+** error. ROLLBACK processing means that a constraint violation
+** causes the operation in process to fail and for the current transaction
+** to be rolled back. ABORT processing means the operation in process
+** fails and any prior changes from that one operation are backed out,
+** but the transaction is not rolled back. FAIL processing means that
+** the operation in progress stops and returns an error code. But prior
+** changes due to the same operation are not backed out and no rollback
+** occurs. IGNORE means that the particular row that caused the constraint
+** error is not inserted or updated. Processing continues and no error
+** is returned. REPLACE means that preexisting database rows that caused
+** a UNITQUE constraint violation are removed so that the new insert or
+** update can proceed. Processing continues and no error is reported.
+**
+** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys.
+** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the
+** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign
+** key is set to NULL. CASCADE means that a DELETE or UPDATE of the
+** referenced table row is propagated into the row that holds the
+** foreign key.
+**
+** The following symbolic values are used to record which type
+** of action to take.
+*/
+#define OE_None 0 /* There is no constraint to check */
+#define OE_Rollback 1 /* Fail the operation and rollback the transaction */
+#define OE_Abort 2 /* Back out changes but do no rollback transaction */
+#define OE_Fail 3 /* Stop the operation but leave all prior changes */
+#define OE_Ignore 4 /* Ignore the error. Do not do the INSERT or UPDATE */
+#define OE_Replace 5 /* Delete existing record, then do INSERT or UPDATE */
+
+#define OE_Restrict 6 /* OE_Abort for IMMEDIATE, OE_Rollback for DEFERRED */
+#define OE_SetNull 7 /* Set the foreign key value to NULL */
+#define OE_SetDflt 8 /* Set the foreign key value to its default */
+#define OE_Cascade 9 /* Cascade the changes */
+
+#define OE_Default 99 /* Do whatever the default action is */
+
+/*
+** Each SQL index is represented in memory by an
+** instance of the following structure.
+**
+** The columns of the table that are to be indexed are described
+** by the aiColumn[] field of this structure. For example, suppose
+** we have the following table and index:
+**
+** CREATE TABLE Ex1(c1 int, c2 int, c3 text);
+** CREATE INDEX Ex2 ON Ex1(c3,c1);
+**
+** In the Table structure describing Ex1, nCol==3 because there are
+** three columns in the table. In the Index structure describing
+** Ex2, nColumn==2 since 2 of the 3 columns of Ex1 are indexed.
+** The value of aiColumn is {2, 0}. aiColumn[0]==2 because the
+** first column to be indexed (c3) has an index of 2 in Ex1.aCol[].
+** The second column to be indexed (c1) has an index of 0 in
+** Ex1.aCol[], hence Ex2.aiColumn[1]==0.
+**
+** The Index.onError field determines whether or not the indexed columns
+** must be unique and what to do if they are not. When Index.onError=OE_None,
+** it means this is not a unique index. Otherwise it is a unique index
+** and the value of Index.onError indicate the which conflict resolution
+** algorithm to employ whenever an attempt is made to insert a non-unique
+** element.
+*/
+struct Index {
+ char *zName; /* Name of this index */
+ int nColumn; /* Number of columns in the table used by this index */
+ int *aiColumn; /* Which columns are used by this index. 1st is 0 */
+ Table *pTable; /* The SQL table being indexed */
+ int tnum; /* Page containing root of this index in database file */
+ u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
+ u8 autoIndex; /* True if is automatically created (ex: by UNITQUE) */
+ u8 iDb; /* Index in sqlite.aDb[] of where this index is stored */
+ Index *pNext; /* The next index associated with the same table */
+};
+
+/*
+** Each token coming out of the lexer is an instance of
+** this structure. Tokens are also used as part of an expression.
+**
+** Note if Token.z==0 then Token.dyn and Token.n are undefined and
+** may contain random values. Do not make any assuptions about Token.dyn
+** and Token.n when Token.z==0.
+*/
+struct Token {
+ const char *z; /* Text of the token. Not NULL-terminated! */
+ unsigned dyn : 1; /* True for malloced memory, false for static */
+ unsigned n : 31; /* Number of characters in this token */
+};
+
+/*
+** Each node of an expression in the parse tree is an instance
+** of this structure.
+**
+** Expr.op is the opcode. The integer parser token codes are reused
+** as opcodes here. For example, the parser defines TK_GE to be an integer
+** code representing the ">=" operator. This same integer code is reused
+** to represent the greater-than-or-equal-to operator in the expression
+** tree.
+**
+** Expr.pRight and Expr.pLeft are subexpressions. Expr.pList is a list
+** of argument if the expression is a function.
+**
+** Expr.token is the operator token for this node. For some expressions
+** that have subexpressions, Expr.token can be the complete text that gave
+** rise to the Expr. In the latter case, the token is marked as being
+** a compound token.
+**
+** An expression of the form ID or ID.ID refers to a column in a table.
+** For such expressions, Expr.op is set to TK_COLUMN and Expr.iTable is
+** the integer cursor number of a VDBE cursor pointing to that table and
+** Expr.iColumn is the column number for the specific column. If the
+** expression is used as a result in an aggregate SELECT, then the
+** value is also stored in the Expr.iAgg column in the aggregate so that
+** it can be accessed after all aggregates are computed.
+**
+** If the expression is a function, the Expr.iTable is an integer code
+** representing which function. If the expression is an unbound variable
+** marker (a question mark character '?' in the original SQL) then the
+** Expr.iTable holds the index number for that variable.
+**
+** The Expr.pSelect field points to a SELECT statement. The SELECT might
+** be the right operand of an IN operator. Or, if a scalar SELECT appears
+** in an expression the opcode is TK_SELECT and Expr.pSelect is the only
+** operand.
+*/
+struct Expr {
+ u8 op; /* Operation performed by this node */
+ u8 dataType; /* Either STQLITE_SO_TEXT or STQLITE_SO_NUM */
+ u8 iDb; /* Database referenced by this expression */
+ u8 flags; /* Various flags. See below */
+ Expr *pLeft, *pRight; /* Left and right subnodes */
+ ExprList *pList; /* A list of expressions used as function arguments
+ ** or in "<expr> IN (<expr-list)" */
+ Token token; /* An operand token */
+ Token span; /* Complete text of the expression */
+ int iTable, iColumn; /* When op==TK_COLUMN, then this expr node means the
+ ** iColumn-th field of the iTable-th table. */
+ int iAgg; /* When op==TK_COLUMN and pParse->useAgg==TRUE, pull
+ ** result from the iAgg-th element of the aggregator */
+ Select *pSelect; /* When the expression is a sub-select. Also the
+ ** right side of "<expr> IN (<select>)" */
+};
+
+/*
+** The following are the meanings of bits in the Expr.flags field.
+*/
+#define EP_FromJoin 0x0001 /* Originated in ON or USING clause of a join */
+
+/*
+** These macros can be used to test, set, or clear bits in the
+** Expr.flags field.
+*/
+#define ExprHasProperty(E,P) (((E)->flags&(P))==(P))
+#define ExprHasAnyProperty(E,P) (((E)->flags&(P))!=0)
+#define ExprSetProperty(E,P) (E)->flags|=(P)
+#define ExprClearProperty(E,P) (E)->flags&=~(P)
+
+/*
+** A list of expressions. Each expression may optionally have a
+** name. An expr/name combination can be used in several ways, such
+** as the list of "expr AS ID" fields following a "SELECT" or in the
+** list of "ID = expr" items in an UPDATE. A list of expressions can
+** also be used as the argument to a function, in which case the a.zName
+** field is not used.
+*/
+struct ExprList {
+ int nExpr; /* Number of expressions on the list */
+ int nAlloc; /* Number of entries allocated below */
+ struct ExprList_item {
+ Expr *pExpr; /* The list of expressions */
+ char *zName; /* Token associated with this expression */
+ u8 sortOrder; /* 1 for DESC or 0 for ASC */
+ u8 isAgg; /* True if this is an aggregate like count(*) */
+ u8 done; /* A flag to indicate when processing is finished */
+ } *a; /* One entry for each expression */
+};
+
+/*
+** An instance of this structure can hold a simple list of identifiers,
+** such as the list "a,b,c" in the following statements:
+**
+** INSERT INTO t(a,b,c) VALUES ...;
+** CREATE INDEX idx ON t(a,b,c);
+** CREATE TRIGGER trig BEFORE UPDATE ON t(a,b,c) ...;
+**
+** The IdList.a.idx field is used when the IdList represents the list of
+** column names after a table name in an INSERT statement. In the statement
+**
+** INSERT INTO t(a,b,c) ...
+**
+** If "a" is the k-th column of table "t", then IdList.a[0].idx==k.
+*/
+struct IdList {
+ int nId; /* Number of identifiers on the list */
+ int nAlloc; /* Number of entries allocated for a[] below */
+ struct IdList_item {
+ char *zName; /* Name of the identifier */
+ int idx; /* Index in some Table.aCol[] of a column named zName */
+ } *a;
+};
+
+/*
+** The following structure describes the FROM clause of a SELECT statement.
+** Each table or subquery in the FROM clause is a separate element of
+** the SrcList.a[] array.
+**
+** With the addition of multiple database support, the following structure
+** can also be used to describe a particular table such as the table that
+** is modified by an INSERT, DELETE, or UPDATE statement. In standard SQL,
+** such a table must be a simple name: ID. But in STQLite, the table can
+** now be identified by a database name, a dot, then the table name: ID.ID.
+*/
+struct SrcList {
+ u16 nSrc; /* Number of tables or subqueries in the FROM clause */
+ u16 nAlloc; /* Number of entries allocated in a[] below */
+ struct SrcList_item {
+ char *zDatabase; /* Name of database holding this table */
+ char *zName; /* Name of the table */
+ char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */
+ Table *pTab; /* An SQL table corresponding to zName */
+ Select *pSelect; /* A SELECT statement used in place of a table name */
+ int jointype; /* Type of join between this table and the next */
+ int iCursor; /* The VDBE cursor number used to access this table */
+ Expr *pOn; /* The ON clause of a join */
+ IdList *pUsing; /* The USING clause of a join */
+ } a[1]; /* One entry for each identifier on the list */
+};
+
+/*
+** Permitted values of the SrcList.a.jointype field
+*/
+#define JT_INNER 0x0001 /* Any kind of inner or cross join */
+#define JT_NATURAL 0x0002 /* True for a "natural" join */
+#define JT_LEFT 0x0004 /* Left outer join */
+#define JT_RIGHT 0x0008 /* Right outer join */
+#define JT_OUTER 0x0010 /* The "OUTER" keyword is present */
+#define JT_ERROR 0x0020 /* unknown or unsupported join type */
+
+/*
+** For each nested loop in a WHERE clause implementation, the WhereInfo
+** structure tqcontains a single instance of this structure. This structure
+** is intended to be private the the where.c module and should not be
+** access or modified by other modules.
+*/
+struct WhereLevel {
+ int iMem; /* Memory cell used by this level */
+ Index *pIdx; /* Index used */
+ int iCur; /* Cursor number used for this index */
+ int score; /* How well this indexed scored */
+ int brk; /* Jump here to break out of the loop */
+ int cont; /* Jump here to continue with the next loop cycle */
+ int op, p1, p2; /* Opcode used to terminate the loop */
+ int iLeftJoin; /* Memory cell used to implement LEFT OUTER JOIN */
+ int top; /* First instruction of interior of the loop */
+ int inOp, inP1, inP2;/* Opcode used to implement an IN operator */
+ int bRev; /* Do the scan in the reverse direction */
+};
+
+/*
+** The WHERE clause processing routine has two halves. The
+** first part does the start of the WHERE loop and the second
+** half does the tail of the WHERE loop. An instance of
+** this structure is returned by the first half and passed
+** into the second half to give some continuity.
+*/
+struct WhereInfo {
+ Parse *pParse;
+ SrcList *pTabList; /* List of tables in the join */
+ int iContinue; /* Jump here to continue with next record */
+ int iBreak; /* Jump here to break out of the loop */
+ int nLevel; /* Number of nested loop */
+ int savedNTab; /* Value of pParse->nTab before WhereBegin() */
+ int peakNTab; /* Value of pParse->nTab after WhereBegin() */
+ WhereLevel a[1]; /* Information about each nest loop in the WHERE */
+};
+
+/*
+** An instance of the following structure tqcontains all information
+** needed to generate code for a single SELECT statement.
+**
+** The zSelect field is used when the Select structure must be persistent.
+** Normally, the expression tree points to tokens in the original input
+** string that encodes the select. But if the Select structure must live
+** longer than its input string (for example when it is used to describe
+** a VIEW) we have to make a copy of the input string so that the nodes
+** of the expression tree will have something to point to. zSelect is used
+** to hold that copy.
+**
+** nLimit is set to -1 if there is no LIMIT clause. nOffset is set to 0.
+** If there is a LIMIT clause, the parser sets nLimit to the value of the
+** limit and nOffset to the value of the offset (or 0 if there is not
+** offset). But later on, nLimit and nOffset become the memory locations
+** in the VDBE that record the limit and offset counters.
+*/
+struct Select {
+ ExprList *pEList; /* The fields of the result */
+ u8 op; /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
+ u8 isDistinct; /* True if the DISTINCT keyword is present */
+ SrcList *pSrc; /* The FROM clause */
+ Expr *pWhere; /* The WHERE clause */
+ ExprList *pGroupBy; /* The GROUP BY clause */
+ Expr *pHaving; /* The HAVING clause */
+ ExprList *pOrderBy; /* The ORDER BY clause */
+ Select *pPrior; /* Prior select in a compound select statement */
+ int nLimit, nOffset; /* LIMIT and OFFSET values. -1 means not used */
+ int iLimit, iOffset; /* Memory registers holding LIMIT & OFFSET counters */
+ char *zSelect; /* Complete text of the SELECT command */
+};
+
+/*
+** The results of a select can be distributed in several ways.
+*/
+#define SRT_Callback 1 /* Invoke a callback with each row of result */
+#define SRT_Mem 2 /* Store result in a memory cell */
+#define SRT_Set 3 /* Store result as unique keys in a table */
+#define SRT_Union 5 /* Store result as keys in a table */
+#define SRT_Except 6 /* Remove result from a UNION table */
+#define SRT_Table 7 /* Store result as data with a unique key */
+#define SRT_TempTable 8 /* Store result in a trasient table */
+#define SRT_Discard 9 /* Do not save the results anywhere */
+#define SRT_Sorter 10 /* Store results in the sorter */
+#define SRT_Subroutine 11 /* Call a subroutine to handle results */
+
+/*
+** When a SELECT uses aggregate functions (like "count(*)" or "avg(f1)")
+** we have to do some additional analysis of expressions. An instance
+** of the following structure holds information about a single subexpression
+** somewhere in the SELECT statement. An array of these structures holds
+** all the information we need to generate code for aggregate
+** expressions.
+**
+** Note that when analyzing a SELECT containing aggregates, both
+** non-aggregate field variables and aggregate functions are stored
+** in the AggExpr array of the Parser structure.
+**
+** The pExpr field points to an expression that is part of either the
+** field list, the GROUP BY clause, the HAVING clause or the ORDER BY
+** clause. The expression will be freed when those clauses are cleaned
+** up. Do not try to delete the expression attached to AggExpr.pExpr.
+**
+** If AggExpr.pExpr==0, that means the expression is "count(*)".
+*/
+struct AggExpr {
+ int isAgg; /* if TRUE tqcontains an aggregate function */
+ Expr *pExpr; /* The expression */
+ FuncDef *pFunc; /* Information about the aggregate function */
+};
+
+/*
+** An SQL parser context. A copy of this structure is passed through
+** the parser and down into all the parser action routine in order to
+** carry around information that is global to the entire parse.
+*/
+struct Parse {
+ sqlite *db; /* The main database structure */
+ int rc; /* Return code from execution */
+ char *zErrMsg; /* An error message */
+ Token sErrToken; /* The token at which the error occurred */
+ Token sFirstToken; /* The first token parsed */
+ Token sLastToken; /* The last token parsed */
+ const char *zTail; /* All SQL text past the last semicolon parsed */
+ Table *pNewTable; /* A table being constructed by CREATE TABLE */
+ Vdbe *pVdbe; /* An engine for executing database bytecode */
+ u8 colNamesSet; /* TRUE after OP_ColumnName has been issued to pVdbe */
+ u8 explain; /* True if the EXPLAIN flag is found on the query */
+ u8 nameClash; /* A permanent table name clashes with temp table name */
+ u8 useAgg; /* If true, extract field values from the aggregator
+ ** while generating expressions. Normally false */
+ int nErr; /* Number of errors seen */
+ int nTab; /* Number of previously allocated VDBE cursors */
+ int nMem; /* Number of memory cells used so far */
+ int nSet; /* Number of sets used so far */
+ int nAgg; /* Number of aggregate expressions */
+ int nVar; /* Number of '?' variables seen in the SQL so far */
+ AggExpr *aAgg; /* An array of aggregate expressions */
+ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */
+ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */
+ TriggerStack *trigStack; /* Trigger actions being coded */
+};
+
+/*
+** An instance of the following structure can be declared on a stack and used
+** to save the Parse.zAuthContext value so that it can be restored later.
+*/
+struct AuthContext {
+ const char *zAuthContext; /* Put saved Parse.zAuthContext here */
+ Parse *pParse; /* The Parse structure */
+};
+
+/*
+** Bitfield flags for P2 value in OP_PutIntKey and OP_Delete
+*/
+#define OPFLAG_NCHANGE 1 /* Set to update db->nChange */
+#define OPFLAG_LASTROWID 2 /* Set to update db->lastRowid */
+#define OPFLAG_CSCHANGE 4 /* Set to update db->csChange */
+
+/*
+ * Each trigger present in the database schema is stored as an instance of
+ * struct Trigger.
+ *
+ * Pointers to instances of struct Trigger are stored in two ways.
+ * 1. In the "trigHash" hash table (part of the sqlite* that represents the
+ * database). This allows Trigger structures to be retrieved by name.
+ * 2. All triggers associated with a single table form a linked list, using the
+ * pNext member of struct Trigger. A pointer to the first element of the
+ * linked list is stored as the "pTrigger" member of the associated
+ * struct Table.
+ *
+ * The "step_list" member points to the first element of a linked list
+ * containing the SQL statements specified as the trigger program.
+ */
+struct Trigger {
+ char *name; /* The name of the trigger */
+ char *table; /* The table or view to which the trigger applies */
+ u8 iDb; /* Database containing this trigger */
+ u8 iTabDb; /* Database containing Trigger.table */
+ u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */
+ u8 tr_tm; /* One of TK_BEFORE, TK_AFTER */
+ Expr *pWhen; /* The WHEN clause of the expresion (may be NULL) */
+ IdList *pColumns; /* If this is an UPDATE OF <column-list> trigger,
+ the <column-list> is stored here */
+ int foreach; /* One of TK_ROW or TK_STATEMENT */
+ Token nameToken; /* Token containing zName. Use during parsing only */
+
+ TriggerStep *step_list; /* Link list of trigger program steps */
+ Trigger *pNext; /* Next trigger associated with the table */
+};
+
+/*
+ * An instance of struct TriggerStep is used to store a single SQL statement
+ * that is a part of a trigger-program.
+ *
+ * Instances of struct TriggerStep are stored in a singly linked list (linked
+ * using the "pNext" member) referenced by the "step_list" member of the
+ * associated struct Trigger instance. The first element of the linked list is
+ * the first step of the trigger-program.
+ *
+ * The "op" member indicates whether this is a "DELETE", "INSERT", "UPDATE" or
+ * "SELECT" statement. The meanings of the other members is determined by the
+ * value of "op" as follows:
+ *
+ * (op == TK_INSERT)
+ * orconf -> stores the ON CONFLICT algorithm
+ * pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
+ * this stores a pointer to the SELECT statement. Otherwise NULL.
+ * target -> A token holding the name of the table to insert into.
+ * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
+ * this stores values to be inserted. Otherwise NULL.
+ * pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
+ * statement, then this stores the column-names to be
+ * inserted into.
+ *
+ * (op == TK_DELETE)
+ * target -> A token holding the name of the table to delete from.
+ * pWhere -> The WHERE clause of the DELETE statement if one is specified.
+ * Otherwise NULL.
+ *
+ * (op == TK_UPDATE)
+ * target -> A token holding the name of the table to update rows of.
+ * pWhere -> The WHERE clause of the UPDATE statement if one is specified.
+ * Otherwise NULL.
+ * pExprList -> A list of the columns to update and the expressions to update
+ * them to. See sqliteUpdate() documentation of "pChanges"
+ * argument.
+ *
+ */
+struct TriggerStep {
+ int op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
+ int orconf; /* OE_Rollback etc. */
+ Trigger *pTrig; /* The trigger that this step is a part of */
+
+ Select *pSelect; /* Valid for SELECT and sometimes
+ INSERT steps (when pExprList == 0) */
+ Token target; /* Valid for DELETE, UPDATE, INSERT steps */
+ Expr *pWhere; /* Valid for DELETE, UPDATE steps */
+ ExprList *pExprList; /* Valid for UPDATE statements and sometimes
+ INSERT steps (when pSelect == 0) */
+ IdList *pIdList; /* Valid for INSERT statements only */
+
+ TriggerStep * pNext; /* Next in the link-list */
+};
+
+/*
+ * An instance of struct TriggerStack stores information required during code
+ * generation of a single trigger program. While the trigger program is being
+ * coded, its associated TriggerStack instance is pointed to by the
+ * "pTriggerStack" member of the Parse structure.
+ *
+ * The pTab member points to the table that triggers are being coded on. The
+ * newIdx member tqcontains the index of the vdbe cursor that points at the temp
+ * table that stores the new.* references. If new.* references are not valid
+ * for the trigger being coded (for example an ON DELETE trigger), then newIdx
+ * is set to -1. The oldIdx member is analogous to newIdx, for old.* references.
+ *
+ * The ON CONFLICT policy to be used for the trigger program steps is stored
+ * as the orconf member. If this is OE_Default, then the ON CONFLICT clause
+ * specified for individual triggers steps is used.
+ *
+ * struct TriggerStack has a "pNext" member, to allow linked lists to be
+ * constructed. When coding nested triggers (triggers fired by other triggers)
+ * each nested trigger stores its tqparent trigger's TriggerStack as the "pNext"
+ * pointer. Once the nested trigger has been coded, the pNext value is restored
+ * to the pTriggerStack member of the Parse stucture and coding of the tqparent
+ * trigger continues.
+ *
+ * Before a nested trigger is coded, the linked list pointed to by the
+ * pTriggerStack is scanned to ensure that the trigger is not about to be coded
+ * recursively. If this condition is detected, the nested trigger is not coded.
+ */
+struct TriggerStack {
+ Table *pTab; /* Table that triggers are currently being coded on */
+ int newIdx; /* Index of vdbe cursor to "new" temp table */
+ int oldIdx; /* Index of vdbe cursor to "old" temp table */
+ int orconf; /* Current orconf policy */
+ int ignoreJump; /* where to jump to for a RAISE(IGNORE) */
+ Trigger *pTrigger; /* The trigger currently being coded */
+ TriggerStack *pNext; /* Next trigger down on the trigger stack */
+};
+
+/*
+** The following structure tqcontains information used by the sqliteFix...
+** routines as they walk the parse tree to make database references
+** explicit.
+*/
+typedef struct DbFixer DbFixer;
+struct DbFixer {
+ Parse *pParse; /* The parsing context. Error messages written here */
+ const char *zDb; /* Make sure all objects are contained in this database */
+ const char *zType; /* Type of the container - used for error messages */
+ const Token *pName; /* Name of the container - used for error messages */
+};
+
+/*
+ * This global flag is set for performance testing of triggers. When it is set
+ * STQLite will perform the overhead of building new and old trigger references
+ * even when no triggers exist
+ */
+extern int always_code_trigger_setup;
+
+/*
+** Internal function prototypes
+*/
+int sqliteStrICmp(const char *, const char *);
+int sqliteStrNICmp(const char *, const char *, int);
+int sqliteHashNoCase(const char *, int);
+int sqliteIsNumber(const char*);
+int sqliteCompare(const char *, const char *);
+int sqliteSortCompare(const char *, const char *);
+void sqliteRealToSortable(double r, char *);
+#ifdef MEMORY_DEBUG
+ void *sqliteMalloc_(int,int,char*,int);
+ void sqliteFree_(void*,char*,int);
+ void *sqliteRealloc_(void*,int,char*,int);
+ char *sqliteStrDup_(const char*,char*,int);
+ char *sqliteStrNDup_(const char*, int,char*,int);
+ void sqliteCheckMemory(void*,int);
+#else
+ void *sqliteMalloc(int);
+ void *sqliteMallocRaw(int);
+ void sqliteFree(void*);
+ void *sqliteRealloc(void*,int);
+ char *sqliteStrDup(const char*);
+ char *sqliteStrNDup(const char*, int);
+# define sqliteCheckMemory(a,b)
+#endif
+char *sqliteMPrintf(const char*, ...);
+char *sqliteVMPrintf(const char*, va_list);
+void sqliteSetString(char **, const char *, ...);
+void sqliteSetNString(char **, ...);
+void sqliteErrorMsg(Parse*, const char*, ...);
+void sqliteDequote(char*);
+int sqliteKeywordCode(const char*, int);
+int sqliteRunParser(Parse*, const char*, char **);
+void sqliteExec(Parse*);
+Expr *sqliteExpr(int, Expr*, Expr*, Token*);
+void sqliteExprSpan(Expr*,Token*,Token*);
+Expr *sqliteExprFunction(ExprList*, Token*);
+void sqliteExprDelete(Expr*);
+ExprList *sqliteExprListAppend(ExprList*,Expr*,Token*);
+void sqliteExprListDelete(ExprList*);
+int sqliteInit(sqlite*, char**);
+void sqlitePragma(Parse*,Token*,Token*,int);
+void sqliteResetInternalSchema(sqlite*, int);
+void sqliteBeginParse(Parse*,int);
+void sqliteRollbackInternalChanges(sqlite*);
+void sqliteCommitInternalChanges(sqlite*);
+Table *sqliteResultSetOfSelect(Parse*,char*,Select*);
+void sqliteOpenMasterTable(Vdbe *v, int);
+void sqliteStartTable(Parse*,Token*,Token*,int,int);
+void sqliteAddColumn(Parse*,Token*);
+void sqliteAddNotNull(Parse*, int);
+void sqliteAddPrimaryKey(Parse*, IdList*, int);
+void sqliteAddColumnType(Parse*,Token*,Token*);
+void sqliteAddDefaultValue(Parse*,Token*,int);
+int sqliteCollateType(const char*, int);
+void sqliteAddCollateType(Parse*, int);
+void sqliteEndTable(Parse*,Token*,Select*);
+void sqliteCreateView(Parse*,Token*,Token*,Select*,int);
+int sqliteViewGetColumnNames(Parse*,Table*);
+void sqliteDropTable(Parse*, Token*, int);
+void sqliteDeleteTable(sqlite*, Table*);
+void sqliteInsert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
+IdList *sqliteIdListAppend(IdList*, Token*);
+int sqliteIdListIndex(IdList*,const char*);
+SrcList *sqliteSrcListAppend(SrcList*, Token*, Token*);
+void sqliteSrcListAddAlias(SrcList*, Token*);
+void sqliteSrcListAssignCursors(Parse*, SrcList*);
+void sqliteIdListDelete(IdList*);
+void sqliteSrcListDelete(SrcList*);
+void sqliteCreateIndex(Parse*,Token*,SrcList*,IdList*,int,Token*,Token*);
+void sqliteDropIndex(Parse*, SrcList*);
+void sqliteAddKeyType(Vdbe*, ExprList*);
+void sqliteAddIdxKeyType(Vdbe*, Index*);
+int sqliteSelect(Parse*, Select*, int, int, Select*, int, int*);
+Select *sqliteSelectNew(ExprList*,SrcList*,Expr*,ExprList*,Expr*,ExprList*,
+ int,int,int);
+void sqliteSelectDelete(Select*);
+void sqliteSelectUnbind(Select*);
+Table *sqliteSrcListLookup(Parse*, SrcList*);
+int sqliteIsReadOnly(Parse*, Table*, int);
+void sqliteDeleteFrom(Parse*, SrcList*, Expr*);
+void sqliteUpdate(Parse*, SrcList*, ExprList*, Expr*, int);
+WhereInfo *sqliteWhereBegin(Parse*, SrcList*, Expr*, int, ExprList**);
+void sqliteWhereEnd(WhereInfo*);
+void sqliteExprCode(Parse*, Expr*);
+int sqliteExprCodeExprList(Parse*, ExprList*, int);
+void sqliteExprIfTrue(Parse*, Expr*, int, int);
+void sqliteExprIfFalse(Parse*, Expr*, int, int);
+Table *sqliteFindTable(sqlite*,const char*, const char*);
+Table *sqliteLocateTable(Parse*,const char*, const char*);
+Index *sqliteFindIndex(sqlite*,const char*, const char*);
+void sqliteUnlinkAndDeleteIndex(sqlite*,Index*);
+void sqliteCopy(Parse*, SrcList*, Token*, Token*, int);
+void sqliteVacuum(Parse*, Token*);
+int sqliteRunVacuum(char**, sqlite*);
+int sqliteGlobCompare(const unsigned char*,const unsigned char*);
+int sqliteLikeCompare(const unsigned char*,const unsigned char*);
+char *sqliteTableNameFromToken(Token*);
+int sqliteExprCheck(Parse*, Expr*, int, int*);
+int sqliteExprType(Expr*);
+int sqliteExprCompare(Expr*, Expr*);
+int sqliteFuncId(Token*);
+int sqliteExprResolveIds(Parse*, SrcList*, ExprList*, Expr*);
+int sqliteExprAnalyzeAggregates(Parse*, Expr*);
+Vdbe *sqliteGetVdbe(Parse*);
+void sqliteRandomness(int, void*);
+void sqliteRollbackAll(sqlite*);
+void sqliteCodeVerifySchema(Parse*, int);
+void sqliteBeginTransaction(Parse*, int);
+void sqliteCommitTransaction(Parse*);
+void sqliteRollbackTransaction(Parse*);
+int sqliteExprIsConstant(Expr*);
+int sqliteExprIsInteger(Expr*, int*);
+int sqliteIsRowid(const char*);
+void sqliteGenerateRowDelete(sqlite*, Vdbe*, Table*, int, int);
+void sqliteGenerateRowIndexDelete(sqlite*, Vdbe*, Table*, int, char*);
+void sqliteGenerateConstraintChecks(Parse*,Table*,int,char*,int,int,int,int);
+void sqliteCompleteInsertion(Parse*, Table*, int, char*, int, int, int);
+int sqliteOpenTableAndIndices(Parse*, Table*, int);
+void sqliteBeginWriteOperation(Parse*, int, int);
+void sqliteEndWriteOperation(Parse*);
+Expr *sqliteExprDup(Expr*);
+void sqliteTokenCopy(Token*, Token*);
+ExprList *sqliteExprListDup(ExprList*);
+SrcList *sqliteSrcListDup(SrcList*);
+IdList *sqliteIdListDup(IdList*);
+Select *sqliteSelectDup(Select*);
+FuncDef *sqliteFindFunction(sqlite*,const char*,int,int,int);
+void sqliteRegisterBuiltinFunctions(sqlite*);
+void sqliteRegisterDateTimeFunctions(sqlite*);
+int sqliteSafetyOn(sqlite*);
+int sqliteSafetyOff(sqlite*);
+int sqliteSafetyCheck(sqlite*);
+void sqliteChangeCookie(sqlite*, Vdbe*);
+void sqliteBeginTrigger(Parse*, Token*,int,int,IdList*,SrcList*,int,Expr*,int);
+void sqliteFinishTrigger(Parse*, TriggerStep*, Token*);
+void sqliteDropTrigger(Parse*, SrcList*);
+void sqliteDropTriggerPtr(Parse*, Trigger*, int);
+int sqliteTriggersExist(Parse* , Trigger* , int , int , int, ExprList*);
+int sqliteCodeRowTrigger(Parse*, int, ExprList*, int, Table *, int, int,
+ int, int);
+void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*);
+void sqliteDeleteTriggerStep(TriggerStep*);
+TriggerStep *sqliteTriggerSelectStep(Select*);
+TriggerStep *sqliteTriggerInsertStep(Token*, IdList*, ExprList*, Select*, int);
+TriggerStep *sqliteTriggerUpdateStep(Token*, ExprList*, Expr*, int);
+TriggerStep *sqliteTriggerDeleteStep(Token*, Expr*);
+void sqliteDeleteTrigger(Trigger*);
+int sqliteJoinType(Parse*, Token*, Token*, Token*);
+void sqliteCreateForeignKey(Parse*, IdList*, Token*, IdList*, int);
+void sqliteDeferForeignKey(Parse*, int);
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ void sqliteAuthRead(Parse*,Expr*,SrcList*);
+ int sqliteAuthCheck(Parse*,int, const char*, const char*, const char*);
+ void sqliteAuthContextPush(Parse*, AuthContext*, const char*);
+ void sqliteAuthContextPop(AuthContext*);
+#else
+# define sqliteAuthRead(a,b,c)
+# define sqliteAuthCheck(a,b,c,d,e) STQLITE_OK
+# define sqliteAuthContextPush(a,b,c)
+# define sqliteAuthContextPop(a) ((void)(a))
+#endif
+void sqliteAttach(Parse*, Token*, Token*, Token*);
+void sqliteDetach(Parse*, Token*);
+int sqliteBtreeFactory(const sqlite *db, const char *zFilename,
+ int mode, int nPg, Btree **ppBtree);
+int sqliteFixInit(DbFixer*, Parse*, int, const char*, const Token*);
+int sqliteFixSrcList(DbFixer*, SrcList*);
+int sqliteFixSelect(DbFixer*, Select*);
+int sqliteFixExpr(DbFixer*, Expr*);
+int sqliteFixExprList(DbFixer*, ExprList*);
+int sqliteFixTriggerStep(DbFixer*, TriggerStep*);
+double sqliteAtoF(const char *z, const char **);
+char *sqlite_snprintf(int,char*,const char*,...);
+int sqliteFitsIn32Bits(const char *);
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/table.c b/tqtinterface/qt4/src/3rdparty/sqlite/table.c
new file mode 100644
index 0000000..c01a195
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/table.c
@@ -0,0 +1,203 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains the sqlite_get_table() and sqlite_free_table()
+** interface routines. These are just wrappers around the main
+** interface routine of sqlite_exec().
+**
+** These routines are in a separate files so that they will not be linked
+** if they are not used.
+*/
+#include <stdlib.h>
+#include <string.h>
+#include "sqliteInt.h"
+
+/*
+** This structure is used to pass data from sqlite_get_table() through
+** to the callback function is uses to build the result.
+*/
+typedef struct TabResult {
+ char **azResult;
+ char *zErrMsg;
+ int nResult;
+ int nAlloc;
+ int nRow;
+ int nColumn;
+ int nData;
+ int rc;
+} TabResult;
+
+/*
+** This routine is called once for each row in the result table. Its job
+** is to fill in the TabResult structure appropriately, allocating new
+** memory as necessary.
+*/
+static int sqlite_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
+ TabResult *p = (TabResult*)pArg;
+ int need;
+ int i;
+ char *z;
+
+ /* Make sure there is enough space in p->azResult to hold everything
+ ** we need to remember from this invocation of the callback.
+ */
+ if( p->nRow==0 && argv!=0 ){
+ need = nCol*2;
+ }else{
+ need = nCol;
+ }
+ if( p->nData + need >= p->nAlloc ){
+ char **azNew;
+ p->nAlloc = p->nAlloc*2 + need + 1;
+ azNew = realloc( p->azResult, sizeof(char*)*p->nAlloc );
+ if( azNew==0 ){
+ p->rc = STQLITE_NOMEM;
+ return 1;
+ }
+ p->azResult = azNew;
+ }
+
+ /* If this is the first row, then generate an extra row containing
+ ** the names of all columns.
+ */
+ if( p->nRow==0 ){
+ p->nColumn = nCol;
+ for(i=0; i<nCol; i++){
+ if( colv[i]==0 ){
+ z = 0;
+ }else{
+ z = malloc( strlen(colv[i])+1 );
+ if( z==0 ){
+ p->rc = STQLITE_NOMEM;
+ return 1;
+ }
+ strcpy(z, colv[i]);
+ }
+ p->azResult[p->nData++] = z;
+ }
+ }else if( p->nColumn!=nCol ){
+ sqliteSetString(&p->zErrMsg,
+ "sqlite_get_table() called with two or more incompatible queries",
+ (char*)0);
+ p->rc = STQLITE_ERROR;
+ return 1;
+ }
+
+ /* Copy over the row data
+ */
+ if( argv!=0 ){
+ for(i=0; i<nCol; i++){
+ if( argv[i]==0 ){
+ z = 0;
+ }else{
+ z = malloc( strlen(argv[i])+1 );
+ if( z==0 ){
+ p->rc = STQLITE_NOMEM;
+ return 1;
+ }
+ strcpy(z, argv[i]);
+ }
+ p->azResult[p->nData++] = z;
+ }
+ p->nRow++;
+ }
+ return 0;
+}
+
+/*
+** Query the database. But instead of invoking a callback for each row,
+** malloc() for space to hold the result and return the entire results
+** at the conclusion of the call.
+**
+** The result that is written to ***pazResult is held in memory obtained
+** from malloc(). But the caller cannot free this memory directly.
+** Instead, the entire table should be passed to sqlite_free_table() when
+** the calling procedure is finished using it.
+*/
+int sqlite_get_table(
+ sqlite *db, /* The database on which the SQL executes */
+ const char *zSql, /* The SQL to be executed */
+ char ***pazResult, /* Write the result table here */
+ int *pnRow, /* Write the number of rows in the result here */
+ int *pnColumn, /* Write the number of columns of result here */
+ char **pzErrMsg /* Write error messages here */
+){
+ int rc;
+ TabResult res;
+ if( pazResult==0 ){ return STQLITE_ERROR; }
+ *pazResult = 0;
+ if( pnColumn ) *pnColumn = 0;
+ if( pnRow ) *pnRow = 0;
+ res.zErrMsg = 0;
+ res.nResult = 0;
+ res.nRow = 0;
+ res.nColumn = 0;
+ res.nData = 1;
+ res.nAlloc = 20;
+ res.rc = STQLITE_OK;
+ res.azResult = malloc( sizeof(char*)*res.nAlloc );
+ if( res.azResult==0 ){
+ return STQLITE_NOMEM;
+ }
+ res.azResult[0] = 0;
+ rc = sqlite_exec(db, zSql, sqlite_get_table_cb, &res, pzErrMsg);
+ if( res.azResult ){
+ res.azResult[0] = (char*)res.nData;
+ }
+ if( rc==STQLITE_ABORT ){
+ sqlite_free_table(&res.azResult[1]);
+ if( res.zErrMsg ){
+ if( pzErrMsg ){
+ free(*pzErrMsg);
+ *pzErrMsg = res.zErrMsg;
+ sqliteStrRealloc(pzErrMsg);
+ }else{
+ sqliteFree(res.zErrMsg);
+ }
+ }
+ return res.rc;
+ }
+ sqliteFree(res.zErrMsg);
+ if( rc!=STQLITE_OK ){
+ sqlite_free_table(&res.azResult[1]);
+ return rc;
+ }
+ if( res.nAlloc>res.nData ){
+ char **azNew;
+ azNew = realloc( res.azResult, sizeof(char*)*(res.nData+1) );
+ if( azNew==0 ){
+ sqlite_free_table(&res.azResult[1]);
+ return STQLITE_NOMEM;
+ }
+ res.nAlloc = res.nData+1;
+ res.azResult = azNew;
+ }
+ *pazResult = &res.azResult[1];
+ if( pnColumn ) *pnColumn = res.nColumn;
+ if( pnRow ) *pnRow = res.nRow;
+ return rc;
+}
+
+/*
+** This routine frees the space the sqlite_get_table() malloced.
+*/
+void sqlite_free_table(
+ char **azResult /* Result returned from from sqlite_get_table() */
+){
+ if( azResult ){
+ int i, n;
+ azResult--;
+ if( azResult==0 ) return;
+ n = (int)azResult[0];
+ for(i=1; i<n; i++){ if( azResult[i] ) free(azResult[i]); }
+ free(azResult);
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/tokenize.c b/tqtinterface/qt4/src/3rdparty/sqlite/tokenize.c
new file mode 100644
index 0000000..3f3e3cf
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/tokenize.c
@@ -0,0 +1,679 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** An tokenizer for SQL
+**
+** This file tqcontains C code that splits an SQL input string up into
+** individual tokens and sends those tokens one-by-one over to the
+** parser for analysis.
+**
+** $Id: tokenize.c,v 1.68 2004/02/14 23:59:58 drh Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+#include <stdlib.h>
+
+/*
+** All the keywords of the SQL language are stored as in a hash
+** table composed of instances of the following structure.
+*/
+typedef struct Keyword Keyword;
+struct Keyword {
+ char *zName; /* The keyword name */
+ u8 tokenType; /* Token value for this keyword */
+ u8 len; /* Length of this keyword */
+ u8 iNext; /* Index in aKeywordTable[] of next with same hash */
+};
+
+/*
+** These are the keywords
+*/
+static Keyword aKeywordTable[] = {
+ { "ABORT", TK_ABORT, },
+ { "AFTER", TK_AFTER, },
+ { "ALL", TK_ALL, },
+ { "AND", TK_AND, },
+ { "AS", TK_AS, },
+ { "ASC", TK_ASC, },
+ { "ATTACH", TK_ATTACH, },
+ { "BEFORE", TK_BEFORE, },
+ { "BEGIN", TK_BEGIN, },
+ { "BETWEEN", TK_BETWEEN, },
+ { "BY", TK_BY, },
+ { "CASCADE", TK_CASCADE, },
+ { "CASE", TK_CASE, },
+ { "CHECK", TK_CHECK, },
+ { "CLUSTER", TK_CLUSTER, },
+ { "COLLATE", TK_COLLATE, },
+ { "COMMIT", TK_COMMIT, },
+ { "CONFLICT", TK_CONFLICT, },
+ { "CONSTRAINT", TK_CONSTRAINT, },
+ { "COPY", TK_COPY, },
+ { "CREATE", TK_CREATE, },
+ { "CROSS", TK_JOIN_KW, },
+ { "DATABASE", TK_DATABASE, },
+ { "DEFAULT", TK_DEFAULT, },
+ { "DEFERRED", TK_DEFERRED, },
+ { "DEFERRABLE", TK_DEFERRABLE, },
+ { "DELETE", TK_DELETE, },
+ { "DELIMITERS", TK_DELIMITERS, },
+ { "DESC", TK_DESC, },
+ { "DETACH", TK_DETACH, },
+ { "DISTINCT", TK_DISTINCT, },
+ { "DROP", TK_DROP, },
+ { "END", TK_END, },
+ { "EACH", TK_EACH, },
+ { "ELSE", TK_ELSE, },
+ { "EXCEPT", TK_EXCEPT, },
+ { "EXPLAIN", TK_EXPLAIN, },
+ { "FAIL", TK_FAIL, },
+ { "FOR", TK_FOR, },
+ { "FOREIGN", TK_FOREIGN, },
+ { "FROM", TK_FROM, },
+ { "FULL", TK_JOIN_KW, },
+ { "GLOB", TK_GLOB, },
+ { "GROUP", TK_GROUP, },
+ { "HAVING", TK_HAVING, },
+ { "IGNORE", TK_IGNORE, },
+ { "IMMEDIATE", TK_IMMEDIATE, },
+ { "IN", TK_IN, },
+ { "INDEX", TK_INDEX, },
+ { "INITIALLY", TK_INITIALLY, },
+ { "INNER", TK_JOIN_KW, },
+ { "INSERT", TK_INSERT, },
+ { "INSTEAD", TK_INSTEAD, },
+ { "INTERSECT", TK_INTERSECT, },
+ { "INTO", TK_INTO, },
+ { "IS", TK_IS, },
+ { "ISNULL", TK_ISNULL, },
+ { "JOIN", TK_JOIN, },
+ { "KEY", TK_KEY, },
+ { "LEFT", TK_JOIN_KW, },
+ { "LIKE", TK_LIKE, },
+ { "LIMIT", TK_LIMIT, },
+ { "MATCH", TK_MATCH, },
+ { "NATURAL", TK_JOIN_KW, },
+ { "NOT", TK_NOT, },
+ { "NOTNULL", TK_NOTNULL, },
+ { "NULL", TK_NULL, },
+ { "OF", TK_OF, },
+ { "OFFSET", TK_OFFSET, },
+ { "ON", TK_ON, },
+ { "OR", TK_OR, },
+ { "ORDER", TK_ORDER, },
+ { "OUTER", TK_JOIN_KW, },
+ { "PRAGMA", TK_PRAGMA, },
+ { "PRIMARY", TK_PRIMARY, },
+ { "RAISE", TK_RAISE, },
+ { "REFERENCES", TK_REFERENCES, },
+ { "REPLACE", TK_REPLACE, },
+ { "RESTRICT", TK_RESTRICT, },
+ { "RIGHT", TK_JOIN_KW, },
+ { "ROLLBACK", TK_ROLLBACK, },
+ { "ROW", TK_ROW, },
+ { "SELECT", TK_SELECT, },
+ { "SET", TK_SET, },
+ { "STATEMENT", TK_STATEMENT, },
+ { "TABLE", TK_TABLE, },
+ { "TEMP", TK_TEMP, },
+ { "TEMPORARY", TK_TEMP, },
+ { "THEN", TK_THEN, },
+ { "TRANSACTION", TK_TRANSACTION, },
+ { "TRIGGER", TK_TRIGGER, },
+ { "UNION", TK_UNION, },
+ { "UNITQUE", TK_UNITQUE, },
+ { "UPDATE", TK_UPDATE, },
+ { "USING", TK_USING, },
+ { "VACUUM", TK_VACUUM, },
+ { "VALUES", TK_VALUES, },
+ { "VIEW", TK_VIEW, },
+ { "WHEN", TK_WHEN, },
+ { "WHERE", TK_WHERE, },
+};
+
+/*
+** This is the hash table
+*/
+#define KEY_HASH_SIZE 101
+static u8 aiHashTable[KEY_HASH_SIZE];
+
+
+/*
+** This function looks up an identifier to determine if it is a
+** keyword. If it is a keyword, the token code of that keyword is
+** returned. If the input is not a keyword, TK_ID is returned.
+*/
+int sqliteKeywordCode(const char *z, int n){
+ int h, i;
+ Keyword *p;
+ static char needInit = 1;
+ if( needInit ){
+ /* Initialize the keyword hash table */
+ sqliteOsEnterMutex();
+ if( needInit ){
+ int nk;
+ nk = sizeof(aKeywordTable)/sizeof(aKeywordTable[0]);
+ for(i=0; i<nk; i++){
+ aKeywordTable[i].len = strlen(aKeywordTable[i].zName);
+ h = sqliteHashNoCase(aKeywordTable[i].zName, aKeywordTable[i].len);
+ h %= KEY_HASH_SIZE;
+ aKeywordTable[i].iNext = aiHashTable[h];
+ aiHashTable[h] = i+1;
+ }
+ needInit = 0;
+ }
+ sqliteOsLeaveMutex();
+ }
+ h = sqliteHashNoCase(z, n) % KEY_HASH_SIZE;
+ for(i=aiHashTable[h]; i; i=p->iNext){
+ p = &aKeywordTable[i-1];
+ if( p->len==n && sqliteStrNICmp(p->zName, z, n)==0 ){
+ return p->tokenType;
+ }
+ }
+ return TK_ID;
+}
+
+
+/*
+** If X is a character that can be used in an identifier and
+** X&0x80==0 then isIdChar[X] will be 1. If X&0x80==0x80 then
+** X is always an identifier character. (Hence all UTF-8
+** characters can be part of an identifier). isIdChar[X] will
+** be 0 for every character in the lower 128 ASCII characters
+** that cannot be used as part of an identifier.
+**
+** In this implementation, an identifier can be a string of
+** alphabetic characters, digits, and "_" plus any character
+** with the high-order bit set. The latter rule means that
+** any sequence of UTF-8 characters or characters taken from
+** an extended ISO8859 character set can form an identifier.
+*/
+static const char isIdChar[] = {
+/* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 2x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 3x */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 4x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 5x */
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 6x */
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
+};
+
+
+/*
+** Return the length of the token that begins at z[0].
+** Store the token type in *tokenType before returning.
+*/
+static int sqliteGetToken(const unsigned char *z, int *tokenType){
+ int i;
+ switch( *z ){
+ case ' ': case '\t': case '\n': case '\f': case '\r': {
+ for(i=1; isspace(z[i]); i++){}
+ *tokenType = TK_SPACE;
+ return i;
+ }
+ case '-': {
+ if( z[1]=='-' ){
+ for(i=2; z[i] && z[i]!='\n'; i++){}
+ *tokenType = TK_COMMENT;
+ return i;
+ }
+ *tokenType = TK_MINUS;
+ return 1;
+ }
+ case '(': {
+ *tokenType = TK_LP;
+ return 1;
+ }
+ case ')': {
+ *tokenType = TK_RP;
+ return 1;
+ }
+ case ';': {
+ *tokenType = TK_SEMI;
+ return 1;
+ }
+ case '+': {
+ *tokenType = TK_PLUS;
+ return 1;
+ }
+ case '*': {
+ *tokenType = TK_STAR;
+ return 1;
+ }
+ case '/': {
+ if( z[1]!='*' || z[2]==0 ){
+ *tokenType = TK_SLASH;
+ return 1;
+ }
+ for(i=3; z[i] && (z[i]!='/' || z[i-1]!='*'); i++){}
+ if( z[i] ) i++;
+ *tokenType = TK_COMMENT;
+ return i;
+ }
+ case '%': {
+ *tokenType = TK_REM;
+ return 1;
+ }
+ case '=': {
+ *tokenType = TK_EQ;
+ return 1 + (z[1]=='=');
+ }
+ case '<': {
+ if( z[1]=='=' ){
+ *tokenType = TK_LE;
+ return 2;
+ }else if( z[1]=='>' ){
+ *tokenType = TK_NE;
+ return 2;
+ }else if( z[1]=='<' ){
+ *tokenType = TK_LSHIFT;
+ return 2;
+ }else{
+ *tokenType = TK_LT;
+ return 1;
+ }
+ }
+ case '>': {
+ if( z[1]=='=' ){
+ *tokenType = TK_GE;
+ return 2;
+ }else if( z[1]=='>' ){
+ *tokenType = TK_RSHIFT;
+ return 2;
+ }else{
+ *tokenType = TK_GT;
+ return 1;
+ }
+ }
+ case '!': {
+ if( z[1]!='=' ){
+ *tokenType = TK_ILLEGAL;
+ return 2;
+ }else{
+ *tokenType = TK_NE;
+ return 2;
+ }
+ }
+ case '|': {
+ if( z[1]!='|' ){
+ *tokenType = TK_BITOR;
+ return 1;
+ }else{
+ *tokenType = TK_CONCAT;
+ return 2;
+ }
+ }
+ case ',': {
+ *tokenType = TK_COMMA;
+ return 1;
+ }
+ case '&': {
+ *tokenType = TK_BITAND;
+ return 1;
+ }
+ case '~': {
+ *tokenType = TK_BITNOT;
+ return 1;
+ }
+ case '\'': case '"': {
+ int delim = z[0];
+ for(i=1; z[i]; i++){
+ if( z[i]==delim ){
+ if( z[i+1]==delim ){
+ i++;
+ }else{
+ break;
+ }
+ }
+ }
+ if( z[i] ) i++;
+ *tokenType = TK_STRING;
+ return i;
+ }
+ case '.': {
+ *tokenType = TK_DOT;
+ return 1;
+ }
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9': {
+ *tokenType = TK_INTEGER;
+ for(i=1; isdigit(z[i]); i++){}
+ if( z[i]=='.' && isdigit(z[i+1]) ){
+ i += 2;
+ while( isdigit(z[i]) ){ i++; }
+ *tokenType = TK_FLOAT;
+ }
+ if( (z[i]=='e' || z[i]=='E') &&
+ ( isdigit(z[i+1])
+ || ((z[i+1]=='+' || z[i+1]=='-') && isdigit(z[i+2]))
+ )
+ ){
+ i += 2;
+ while( isdigit(z[i]) ){ i++; }
+ *tokenType = TK_FLOAT;
+ }
+ return i;
+ }
+ case '[': {
+ for(i=1; z[i] && z[i-1]!=']'; i++){}
+ *tokenType = TK_ID;
+ return i;
+ }
+ case '?': {
+ *tokenType = TK_VARIABLE;
+ return 1;
+ }
+ default: {
+ if( (*z&0x80)==0 && !isIdChar[*z] ){
+ break;
+ }
+ for(i=1; (z[i]&0x80)!=0 || isIdChar[z[i]]; i++){}
+ *tokenType = sqliteKeywordCode((char*)z, i);
+ return i;
+ }
+ }
+ *tokenType = TK_ILLEGAL;
+ return 1;
+}
+
+/*
+** Run the parser on the given SQL string. The parser structure is
+** passed in. An STQLITE_ status code is returned. If an error occurs
+** and pzErrMsg!=NULL then an error message might be written into
+** memory obtained from malloc() and *pzErrMsg made to point to that
+** error message. Or maybe not.
+*/
+int sqliteRunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
+ int nErr = 0;
+ int i;
+ void *pEngine;
+ int tokenType;
+ int lastTokenParsed = -1;
+ sqlite *db = pParse->db;
+ extern void *sqliteParserAlloc(void*(*)(int));
+ extern void sqliteParserFree(void*, void(*)(void*));
+ extern int sqliteParser(void*, int, Token, Parse*);
+
+ db->flags &= ~STQLITE_Interrupt;
+ pParse->rc = STQLITE_OK;
+ i = 0;
+ pEngine = sqliteParserAlloc((void*(*)(int))malloc);
+ if( pEngine==0 ){
+ sqliteSetString(pzErrMsg, "out of memory", (char*)0);
+ return 1;
+ }
+ pParse->sLastToken.dyn = 0;
+ pParse->zTail = zSql;
+ while( sqlite_malloc_failed==0 && zSql[i]!=0 ){
+ assert( i>=0 );
+ pParse->sLastToken.z = &zSql[i];
+ assert( pParse->sLastToken.dyn==0 );
+ pParse->sLastToken.n = sqliteGetToken((unsigned char*)&zSql[i], &tokenType);
+ i += pParse->sLastToken.n;
+ switch( tokenType ){
+ case TK_SPACE:
+ case TK_COMMENT: {
+ if( (db->flags & STQLITE_Interrupt)!=0 ){
+ pParse->rc = STQLITE_INTERRUPT;
+ sqliteSetString(pzErrMsg, "interrupt", (char*)0);
+ goto abort_parse;
+ }
+ break;
+ }
+ case TK_ILLEGAL: {
+ sqliteSetNString(pzErrMsg, "unrecognized token: \"", -1,
+ pParse->sLastToken.z, pParse->sLastToken.n, "\"", 1, 0);
+ nErr++;
+ goto abort_parse;
+ }
+ case TK_SEMI: {
+ pParse->zTail = &zSql[i];
+ /* Fall thru into the default case */
+ }
+ default: {
+ sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse);
+ lastTokenParsed = tokenType;
+ if( pParse->rc!=STQLITE_OK ){
+ goto abort_parse;
+ }
+ break;
+ }
+ }
+ }
+abort_parse:
+ if( zSql[i]==0 && nErr==0 && pParse->rc==STQLITE_OK ){
+ if( lastTokenParsed!=TK_SEMI ){
+ sqliteParser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
+ pParse->zTail = &zSql[i];
+ }
+ sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
+ }
+ sqliteParserFree(pEngine, free);
+ if( pParse->rc!=STQLITE_OK && pParse->rc!=STQLITE_DONE && pParse->zErrMsg==0 ){
+ sqliteSetString(&pParse->zErrMsg, sqlite_error_string(pParse->rc),
+ (char*)0);
+ }
+ if( pParse->zErrMsg ){
+ if( pzErrMsg && *pzErrMsg==0 ){
+ *pzErrMsg = pParse->zErrMsg;
+ }else{
+ sqliteFree(pParse->zErrMsg);
+ }
+ pParse->zErrMsg = 0;
+ if( !nErr ) nErr++;
+ }
+ if( pParse->pVdbe && pParse->nErr>0 ){
+ sqliteVdbeDelete(pParse->pVdbe);
+ pParse->pVdbe = 0;
+ }
+ if( pParse->pNewTable ){
+ sqliteDeleteTable(pParse->db, pParse->pNewTable);
+ pParse->pNewTable = 0;
+ }
+ if( pParse->pNewTrigger ){
+ sqliteDeleteTrigger(pParse->pNewTrigger);
+ pParse->pNewTrigger = 0;
+ }
+ if( nErr>0 && (pParse->rc==STQLITE_OK || pParse->rc==STQLITE_DONE) ){
+ pParse->rc = STQLITE_ERROR;
+ }
+ return nErr;
+}
+
+/*
+** Token types used by the sqlite_complete() routine. See the header
+** comments on that procedure for additional information.
+*/
+#define tkEXPLAIN 0
+#define tkCREATE 1
+#define tkTEMP 2
+#define tkTRIGGER 3
+#define tkEND 4
+#define tkSEMI 5
+#define tkWS 6
+#define tkOTHER 7
+
+/*
+** Return TRUE if the given SQL string ends in a semicolon.
+**
+** Special handling is require for CREATE TRIGGER statements.
+** Whenever the CREATE TRIGGER keywords are seen, the statement
+** must end with ";END;".
+**
+** This implementation uses a state machine with 7 states:
+**
+** (0) START At the beginning or end of an SQL statement. This routine
+** returns 1 if it ends in the START state and 0 if it ends
+** in any other state.
+**
+** (1) EXPLAIN The keyword EXPLAIN has been seen at the beginning of
+** a statement.
+**
+** (2) CREATE The keyword CREATE has been seen at the beginning of a
+** statement, possibly preceeded by EXPLAIN and/or followed by
+** TEMP or TEMPORARY
+**
+** (3) NORMAL We are in the middle of statement which ends with a single
+** semicolon.
+**
+** (4) TRIGGER We are in the middle of a trigger definition that must be
+** ended by a semicolon, the keyword END, and another semicolon.
+**
+** (5) SEMI We've seen the first semicolon in the ";END;" that occurs at
+** the end of a trigger definition.
+**
+** (6) END We've seen the ";END" of the ";END;" that occurs at the end
+** of a trigger difinition.
+**
+** Transitions between states above are determined by tokens extracted
+** from the input. The following tokens are significant:
+**
+** (0) tkEXPLAIN The "explain" keyword.
+** (1) tkCREATE The "create" keyword.
+** (2) tkTEMP The "temp" or "temporary" keyword.
+** (3) tkTRIGGER The "trigger" keyword.
+** (4) tkEND The "end" keyword.
+** (5) tkSEMI A semicolon.
+** (6) tkWS Whitespace
+** (7) tkOTHER Any other SQL token.
+**
+** Whitespace never causes a state transition and is always ignored.
+*/
+int sqlite_complete(const char *zSql){
+ u8 state = 0; /* Current state, using numbers defined in header comment */
+ u8 token; /* Value of the next token */
+
+ /* The following matrix defines the transition from one state to another
+ ** according to what token is seen. trans[state][token] returns the
+ ** next state.
+ */
+ static const u8 trans[7][8] = {
+ /* Token: */
+ /* State: ** EXPLAIN CREATE TEMP TRIGGER END SEMI WS OTHER */
+ /* 0 START: */ { 1, 2, 3, 3, 3, 0, 0, 3, },
+ /* 1 EXPLAIN: */ { 3, 2, 3, 3, 3, 0, 1, 3, },
+ /* 2 CREATE: */ { 3, 3, 2, 4, 3, 0, 2, 3, },
+ /* 3 NORMAL: */ { 3, 3, 3, 3, 3, 0, 3, 3, },
+ /* 4 TRIGGER: */ { 4, 4, 4, 4, 4, 5, 4, 4, },
+ /* 5 SEMI: */ { 4, 4, 4, 4, 6, 5, 5, 4, },
+ /* 6 END: */ { 4, 4, 4, 4, 4, 0, 6, 4, },
+ };
+
+ while( *zSql ){
+ switch( *zSql ){
+ case ';': { /* A semicolon */
+ token = tkSEMI;
+ break;
+ }
+ case ' ':
+ case '\r':
+ case '\t':
+ case '\n':
+ case '\f': { /* White space is ignored */
+ token = tkWS;
+ break;
+ }
+ case '/': { /* C-style comments */
+ if( zSql[1]!='*' ){
+ token = tkOTHER;
+ break;
+ }
+ zSql += 2;
+ while( zSql[0] && (zSql[0]!='*' || zSql[1]!='/') ){ zSql++; }
+ if( zSql[0]==0 ) return 0;
+ zSql++;
+ token = tkWS;
+ break;
+ }
+ case '-': { /* SQL-style comments from "--" to end of line */
+ if( zSql[1]!='-' ){
+ token = tkOTHER;
+ break;
+ }
+ while( *zSql && *zSql!='\n' ){ zSql++; }
+ if( *zSql==0 ) return state==0;
+ token = tkWS;
+ break;
+ }
+ case '[': { /* Microsoft-style identifiers in [...] */
+ zSql++;
+ while( *zSql && *zSql!=']' ){ zSql++; }
+ if( *zSql==0 ) return 0;
+ token = tkOTHER;
+ break;
+ }
+ case '"': /* single- and double-quoted strings */
+ case '\'': {
+ int c = *zSql;
+ zSql++;
+ while( *zSql && *zSql!=c ){ zSql++; }
+ if( *zSql==0 ) return 0;
+ token = tkOTHER;
+ break;
+ }
+ default: {
+ if( isIdChar[(u8)*zSql] ){
+ /* Keywords and unquoted identifiers */
+ int nId;
+ for(nId=1; isIdChar[(u8)zSql[nId]]; nId++){}
+ switch( *zSql ){
+ case 'c': case 'C': {
+ if( nId==6 && sqliteStrNICmp(zSql, "create", 6)==0 ){
+ token = tkCREATE;
+ }else{
+ token = tkOTHER;
+ }
+ break;
+ }
+ case 't': case 'T': {
+ if( nId==7 && sqliteStrNICmp(zSql, "trigger", 7)==0 ){
+ token = tkTRIGGER;
+ }else if( nId==4 && sqliteStrNICmp(zSql, "temp", 4)==0 ){
+ token = tkTEMP;
+ }else if( nId==9 && sqliteStrNICmp(zSql, "temporary", 9)==0 ){
+ token = tkTEMP;
+ }else{
+ token = tkOTHER;
+ }
+ break;
+ }
+ case 'e': case 'E': {
+ if( nId==3 && sqliteStrNICmp(zSql, "end", 3)==0 ){
+ token = tkEND;
+ }else if( nId==7 && sqliteStrNICmp(zSql, "explain", 7)==0 ){
+ token = tkEXPLAIN;
+ }else{
+ token = tkOTHER;
+ }
+ break;
+ }
+ default: {
+ token = tkOTHER;
+ break;
+ }
+ }
+ zSql += nId-1;
+ }else{
+ /* Operators and special symbols */
+ token = tkOTHER;
+ }
+ break;
+ }
+ }
+ state = trans[state][token];
+ zSql++;
+ }
+ return state==0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/trigger.c b/tqtinterface/qt4/src/3rdparty/sqlite/trigger.c
new file mode 100644
index 0000000..781928f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/trigger.c
@@ -0,0 +1,764 @@
+/*
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+*
+*/
+#include "sqliteInt.h"
+
+/*
+** Delete a linked list of TriggerStep structures.
+*/
+void sqliteDeleteTriggerStep(TriggerStep *pTriggerStep){
+ while( pTriggerStep ){
+ TriggerStep * pTmp = pTriggerStep;
+ pTriggerStep = pTriggerStep->pNext;
+
+ if( pTmp->target.dyn ) sqliteFree((char*)pTmp->target.z);
+ sqliteExprDelete(pTmp->pWhere);
+ sqliteExprListDelete(pTmp->pExprList);
+ sqliteSelectDelete(pTmp->pSelect);
+ sqliteIdListDelete(pTmp->pIdList);
+
+ sqliteFree(pTmp);
+ }
+}
+
+/*
+** This is called by the parser when it sees a CREATE TRIGGER statement
+** up to the point of the BEGIN before the trigger actions. A Trigger
+** structure is generated based on the information available and stored
+** in pParse->pNewTrigger. After the trigger actions have been parsed, the
+** sqliteFinishTrigger() function is called to complete the trigger
+** construction process.
+*/
+void sqliteBeginTrigger(
+ Parse *pParse, /* The parse context of the CREATE TRIGGER statement */
+ Token *pName, /* The name of the trigger */
+ int tr_tm, /* One of TK_BEFORE, TK_AFTER, TK_INSTEAD */
+ int op, /* One of TK_INSERT, TK_UPDATE, TK_DELETE */
+ IdList *pColumns, /* column list if this is an UPDATE OF trigger */
+ SrcList *pTableName,/* The name of the table/view the trigger applies to */
+ int foreach, /* One of TK_ROW or TK_STATEMENT */
+ Expr *pWhen, /* WHEN clause */
+ int isTemp /* True if the TEMPORARY keyword is present */
+){
+ Trigger *nt;
+ Table *tab;
+ char *zName = 0; /* Name of the trigger */
+ sqlite *db = pParse->db;
+ int iDb; /* When database to store the trigger in */
+ DbFixer sFix;
+
+ /* Check that:
+ ** 1. the trigger name does not already exist.
+ ** 2. the table (or view) does exist in the same database as the trigger.
+ ** 3. that we are not trying to create a trigger on the sqlite_master table
+ ** 4. That we are not trying to create an INSTEAD OF trigger on a table.
+ ** 5. That we are not trying to create a BEFORE or AFTER trigger on a view.
+ */
+ if( sqlite_malloc_failed ) goto trigger_cleanup;
+ assert( pTableName->nSrc==1 );
+ if( db->init.busy
+ && sqliteFixInit(&sFix, pParse, db->init.iDb, "trigger", pName)
+ && sqliteFixSrcList(&sFix, pTableName)
+ ){
+ goto trigger_cleanup;
+ }
+ tab = sqliteSrcListLookup(pParse, pTableName);
+ if( !tab ){
+ goto trigger_cleanup;
+ }
+ iDb = isTemp ? 1 : tab->iDb;
+ if( iDb>=2 && !db->init.busy ){
+ sqliteErrorMsg(pParse, "triggers may not be added to auxiliary "
+ "database %s", db->aDb[tab->iDb].zName);
+ goto trigger_cleanup;
+ }
+
+ zName = sqliteStrNDup(pName->z, pName->n);
+ sqliteDequote(zName);
+ if( sqliteHashFind(&(db->aDb[iDb].trigHash), zName,pName->n+1) ){
+ sqliteErrorMsg(pParse, "trigger %T already exists", pName);
+ goto trigger_cleanup;
+ }
+ if( sqliteStrNICmp(tab->zName, "sqlite_", 7)==0 ){
+ sqliteErrorMsg(pParse, "cannot create trigger on system table");
+ pParse->nErr++;
+ goto trigger_cleanup;
+ }
+ if( tab->pSelect && tr_tm != TK_INSTEAD ){
+ sqliteErrorMsg(pParse, "cannot create %s trigger on view: %S",
+ (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0);
+ goto trigger_cleanup;
+ }
+ if( !tab->pSelect && tr_tm == TK_INSTEAD ){
+ sqliteErrorMsg(pParse, "cannot create INSTEAD OF"
+ " trigger on table: %S", pTableName, 0);
+ goto trigger_cleanup;
+ }
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ {
+ int code = STQLITE_CREATE_TRIGGER;
+ const char *zDb = db->aDb[tab->iDb].zName;
+ const char *zDbTrig = isTemp ? db->aDb[1].zName : zDb;
+ if( tab->iDb==1 || isTemp ) code = STQLITE_CREATE_TEMP_TRIGGER;
+ if( sqliteAuthCheck(pParse, code, zName, tab->zName, zDbTrig) ){
+ goto trigger_cleanup;
+ }
+ if( sqliteAuthCheck(pParse, STQLITE_INSERT, SCHEMA_TABLE(tab->iDb), 0, zDb)){
+ goto trigger_cleanup;
+ }
+ }
+#endif
+
+ /* INSTEAD OF triggers can only appear on views and BEGIN triggers
+ ** cannot appear on views. So we might as well translate every
+ ** INSTEAD OF trigger into a BEFORE trigger. It simplifies code
+ ** elsewhere.
+ */
+ if (tr_tm == TK_INSTEAD){
+ tr_tm = TK_BEFORE;
+ }
+
+ /* Build the Trigger object */
+ nt = (Trigger*)sqliteMalloc(sizeof(Trigger));
+ if( nt==0 ) goto trigger_cleanup;
+ nt->name = zName;
+ zName = 0;
+ nt->table = sqliteStrDup(pTableName->a[0].zName);
+ if( sqlite_malloc_failed ) goto trigger_cleanup;
+ nt->iDb = iDb;
+ nt->iTabDb = tab->iDb;
+ nt->op = op;
+ nt->tr_tm = tr_tm;
+ nt->pWhen = sqliteExprDup(pWhen);
+ nt->pColumns = sqliteIdListDup(pColumns);
+ nt->foreach = foreach;
+ sqliteTokenCopy(&nt->nameToken,pName);
+ assert( pParse->pNewTrigger==0 );
+ pParse->pNewTrigger = nt;
+
+trigger_cleanup:
+ sqliteFree(zName);
+ sqliteSrcListDelete(pTableName);
+ sqliteIdListDelete(pColumns);
+ sqliteExprDelete(pWhen);
+}
+
+/*
+** This routine is called after all of the trigger actions have been parsed
+** in order to complete the process of building the trigger.
+*/
+void sqliteFinishTrigger(
+ Parse *pParse, /* Parser context */
+ TriggerStep *pStepList, /* The triggered program */
+ Token *pAll /* Token that describes the complete CREATE TRIGGER */
+){
+ Trigger *nt = 0; /* The trigger whose construction is finishing up */
+ sqlite *db = pParse->db; /* The database */
+ DbFixer sFix;
+
+ if( pParse->nErr || pParse->pNewTrigger==0 ) goto triggerfinish_cleanup;
+ nt = pParse->pNewTrigger;
+ pParse->pNewTrigger = 0;
+ nt->step_list = pStepList;
+ while( pStepList ){
+ pStepList->pTrig = nt;
+ pStepList = pStepList->pNext;
+ }
+ if( sqliteFixInit(&sFix, pParse, nt->iDb, "trigger", &nt->nameToken)
+ && sqliteFixTriggerStep(&sFix, nt->step_list) ){
+ goto triggerfinish_cleanup;
+ }
+
+ /* if we are not initializing, and this trigger is not on a TEMP table,
+ ** build the sqlite_master entry
+ */
+ if( !db->init.busy ){
+ static VdbeOpList insertTrig[] = {
+ { OP_NewRecno, 0, 0, 0 },
+ { OP_String, 0, 0, "trigger" },
+ { OP_String, 0, 0, 0 }, /* 2: trigger name */
+ { OP_String, 0, 0, 0 }, /* 3: table name */
+ { OP_Integer, 0, 0, 0 },
+ { OP_String, 0, 0, 0 }, /* 5: SQL */
+ { OP_MakeRecord, 5, 0, 0 },
+ { OP_PutIntKey, 0, 0, 0 },
+ };
+ int addr;
+ Vdbe *v;
+
+ /* Make an entry in the sqlite_master table */
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ) goto triggerfinish_cleanup;
+ sqliteBeginWriteOperation(pParse, 0, 0);
+ sqliteOpenMasterTable(v, nt->iDb);
+ addr = sqliteVdbeAddOpList(v, ArraySize(insertTrig), insertTrig);
+ sqliteVdbeChangeP3(v, addr+2, nt->name, 0);
+ sqliteVdbeChangeP3(v, addr+3, nt->table, 0);
+ sqliteVdbeChangeP3(v, addr+5, pAll->z, pAll->n);
+ if( nt->iDb==0 ){
+ sqliteChangeCookie(db, v);
+ }
+ sqliteVdbeAddOp(v, OP_Close, 0, 0);
+ sqliteEndWriteOperation(pParse);
+ }
+
+ if( !pParse->explain ){
+ Table *pTab;
+ sqliteHashInsert(&db->aDb[nt->iDb].trigHash,
+ nt->name, strlen(nt->name)+1, nt);
+ pTab = sqliteLocateTable(pParse, nt->table, db->aDb[nt->iTabDb].zName);
+ assert( pTab!=0 );
+ nt->pNext = pTab->pTrigger;
+ pTab->pTrigger = nt;
+ nt = 0;
+ }
+
+triggerfinish_cleanup:
+ sqliteDeleteTrigger(nt);
+ sqliteDeleteTrigger(pParse->pNewTrigger);
+ pParse->pNewTrigger = 0;
+ sqliteDeleteTriggerStep(pStepList);
+}
+
+/*
+** Make a copy of all components of the given trigger step. This has
+** the effect of copying all Expr.token.z values into memory obtained
+** from sqliteMalloc(). As initially created, the Expr.token.z values
+** all point to the input string that was fed to the parser. But that
+** string is ephemeral - it will go away as soon as the sqlite_exec()
+** call that started the parser exits. This routine makes a persistent
+** copy of all the Expr.token.z strings so that the TriggerStep structure
+** will be valid even after the sqlite_exec() call returns.
+*/
+static void sqlitePersistTriggerStep(TriggerStep *p){
+ if( p->target.z ){
+ p->target.z = sqliteStrNDup(p->target.z, p->target.n);
+ p->target.dyn = 1;
+ }
+ if( p->pSelect ){
+ Select *pNew = sqliteSelectDup(p->pSelect);
+ sqliteSelectDelete(p->pSelect);
+ p->pSelect = pNew;
+ }
+ if( p->pWhere ){
+ Expr *pNew = sqliteExprDup(p->pWhere);
+ sqliteExprDelete(p->pWhere);
+ p->pWhere = pNew;
+ }
+ if( p->pExprList ){
+ ExprList *pNew = sqliteExprListDup(p->pExprList);
+ sqliteExprListDelete(p->pExprList);
+ p->pExprList = pNew;
+ }
+ if( p->pIdList ){
+ IdList *pNew = sqliteIdListDup(p->pIdList);
+ sqliteIdListDelete(p->pIdList);
+ p->pIdList = pNew;
+ }
+}
+
+/*
+** Turn a SELECT statement (that the pSelect parameter points to) into
+** a trigger step. Return a pointer to a TriggerStep structure.
+**
+** The parser calls this routine when it tqfinds a SELECT statement in
+** body of a TRIGGER.
+*/
+TriggerStep *sqliteTriggerSelectStep(Select *pSelect){
+ TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
+ if( pTriggerStep==0 ) return 0;
+
+ pTriggerStep->op = TK_SELECT;
+ pTriggerStep->pSelect = pSelect;
+ pTriggerStep->orconf = OE_Default;
+ sqlitePersistTriggerStep(pTriggerStep);
+
+ return pTriggerStep;
+}
+
+/*
+** Build a trigger step out of an INSERT statement. Return a pointer
+** to the new trigger step.
+**
+** The parser calls this routine when it sees an INSERT inside the
+** body of a trigger.
+*/
+TriggerStep *sqliteTriggerInsertStep(
+ Token *pTableName, /* Name of the table into which we insert */
+ IdList *pColumn, /* List of columns in pTableName to insert into */
+ ExprList *pEList, /* The VALUE clause: a list of values to be inserted */
+ Select *pSelect, /* A SELECT statement that supplies values */
+ int orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
+){
+ TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
+ if( pTriggerStep==0 ) return 0;
+
+ assert(pEList == 0 || pSelect == 0);
+ assert(pEList != 0 || pSelect != 0);
+
+ pTriggerStep->op = TK_INSERT;
+ pTriggerStep->pSelect = pSelect;
+ pTriggerStep->target = *pTableName;
+ pTriggerStep->pIdList = pColumn;
+ pTriggerStep->pExprList = pEList;
+ pTriggerStep->orconf = orconf;
+ sqlitePersistTriggerStep(pTriggerStep);
+
+ return pTriggerStep;
+}
+
+/*
+** Construct a trigger step that implements an UPDATE statement and return
+** a pointer to that trigger step. The parser calls this routine when it
+** sees an UPDATE statement inside the body of a CREATE TRIGGER.
+*/
+TriggerStep *sqliteTriggerUpdateStep(
+ Token *pTableName, /* Name of the table to be updated */
+ ExprList *pEList, /* The SET clause: list of column and new values */
+ Expr *pWhere, /* The WHERE clause */
+ int orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */
+){
+ TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
+ if( pTriggerStep==0 ) return 0;
+
+ pTriggerStep->op = TK_UPDATE;
+ pTriggerStep->target = *pTableName;
+ pTriggerStep->pExprList = pEList;
+ pTriggerStep->pWhere = pWhere;
+ pTriggerStep->orconf = orconf;
+ sqlitePersistTriggerStep(pTriggerStep);
+
+ return pTriggerStep;
+}
+
+/*
+** Construct a trigger step that implements a DELETE statement and return
+** a pointer to that trigger step. The parser calls this routine when it
+** sees a DELETE statement inside the body of a CREATE TRIGGER.
+*/
+TriggerStep *sqliteTriggerDeleteStep(Token *pTableName, Expr *pWhere){
+ TriggerStep *pTriggerStep = sqliteMalloc(sizeof(TriggerStep));
+ if( pTriggerStep==0 ) return 0;
+
+ pTriggerStep->op = TK_DELETE;
+ pTriggerStep->target = *pTableName;
+ pTriggerStep->pWhere = pWhere;
+ pTriggerStep->orconf = OE_Default;
+ sqlitePersistTriggerStep(pTriggerStep);
+
+ return pTriggerStep;
+}
+
+/*
+** Recursively delete a Trigger structure
+*/
+void sqliteDeleteTrigger(Trigger *pTrigger){
+ if( pTrigger==0 ) return;
+ sqliteDeleteTriggerStep(pTrigger->step_list);
+ sqliteFree(pTrigger->name);
+ sqliteFree(pTrigger->table);
+ sqliteExprDelete(pTrigger->pWhen);
+ sqliteIdListDelete(pTrigger->pColumns);
+ if( pTrigger->nameToken.dyn ) sqliteFree((char*)pTrigger->nameToken.z);
+ sqliteFree(pTrigger);
+}
+
+/*
+ * This function is called to drop a trigger from the database schema.
+ *
+ * This may be called directly from the parser and therefore identifies
+ * the trigger by name. The sqliteDropTriggerPtr() routine does the
+ * same job as this routine except it take a spointer to the trigger
+ * instead of the trigger name.
+ *
+ * Note that this function does not delete the trigger entirely. Instead it
+ * removes it from the internal schema and places it in the trigDrop hash
+ * table. This is so that the trigger can be restored into the database schema
+ * if the transaction is rolled back.
+ */
+void sqliteDropTrigger(Parse *pParse, SrcList *pName){
+ Trigger *pTrigger;
+ int i;
+ const char *zDb;
+ const char *zName;
+ int nName;
+ sqlite *db = pParse->db;
+
+ if( sqlite_malloc_failed ) goto drop_trigger_cleanup;
+ assert( pName->nSrc==1 );
+ zDb = pName->a[0].zDatabase;
+ zName = pName->a[0].zName;
+ nName = strlen(zName);
+ for(i=0; i<db->nDb; i++){
+ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */
+ if( zDb && sqliteStrICmp(db->aDb[j].zName, zDb) ) continue;
+ pTrigger = sqliteHashFind(&(db->aDb[j].trigHash), zName, nName+1);
+ if( pTrigger ) break;
+ }
+ if( !pTrigger ){
+ sqliteErrorMsg(pParse, "no such trigger: %S", pName, 0);
+ goto drop_trigger_cleanup;
+ }
+ sqliteDropTriggerPtr(pParse, pTrigger, 0);
+
+drop_trigger_cleanup:
+ sqliteSrcListDelete(pName);
+}
+
+/*
+** Drop a trigger given a pointer to that trigger. If nested is false,
+** then also generate code to remove the trigger from the STQLITE_MASTER
+** table.
+*/
+void sqliteDropTriggerPtr(Parse *pParse, Trigger *pTrigger, int nested){
+ Table *pTable;
+ Vdbe *v;
+ sqlite *db = pParse->db;
+
+ assert( pTrigger->iDb<db->nDb );
+ if( pTrigger->iDb>=2 ){
+ sqliteErrorMsg(pParse, "triggers may not be removed from "
+ "auxiliary database %s", db->aDb[pTrigger->iDb].zName);
+ return;
+ }
+ pTable = sqliteFindTable(db, pTrigger->table,db->aDb[pTrigger->iTabDb].zName);
+ assert(pTable);
+ assert( pTable->iDb==pTrigger->iDb || pTrigger->iDb==1 );
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ {
+ int code = STQLITE_DROP_TRIGGER;
+ const char *zDb = db->aDb[pTrigger->iDb].zName;
+ const char *zTab = SCHEMA_TABLE(pTrigger->iDb);
+ if( pTrigger->iDb ) code = STQLITE_DROP_TEMP_TRIGGER;
+ if( sqliteAuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) ||
+ sqliteAuthCheck(pParse, STQLITE_DELETE, zTab, 0, zDb) ){
+ return;
+ }
+ }
+#endif
+
+ /* Generate code to destroy the database record of the trigger.
+ */
+ if( pTable!=0 && !nested && (v = sqliteGetVdbe(pParse))!=0 ){
+ int base;
+ static VdbeOpList dropTrigger[] = {
+ { OP_Rewind, 0, ADDR(9), 0},
+ { OP_String, 0, 0, 0}, /* 1 */
+ { OP_Column, 0, 1, 0},
+ { OP_Ne, 0, ADDR(8), 0},
+ { OP_String, 0, 0, "trigger"},
+ { OP_Column, 0, 0, 0},
+ { OP_Ne, 0, ADDR(8), 0},
+ { OP_Delete, 0, 0, 0},
+ { OP_Next, 0, ADDR(1), 0}, /* 8 */
+ };
+
+ sqliteBeginWriteOperation(pParse, 0, 0);
+ sqliteOpenMasterTable(v, pTrigger->iDb);
+ base = sqliteVdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger);
+ sqliteVdbeChangeP3(v, base+1, pTrigger->name, 0);
+ if( pTrigger->iDb==0 ){
+ sqliteChangeCookie(db, v);
+ }
+ sqliteVdbeAddOp(v, OP_Close, 0, 0);
+ sqliteEndWriteOperation(pParse);
+ }
+
+ /*
+ * If this is not an "explain", then delete the trigger structure.
+ */
+ if( !pParse->explain ){
+ const char *zName = pTrigger->name;
+ int nName = strlen(zName);
+ if( pTable->pTrigger == pTrigger ){
+ pTable->pTrigger = pTrigger->pNext;
+ }else{
+ Trigger *cc = pTable->pTrigger;
+ while( cc ){
+ if( cc->pNext == pTrigger ){
+ cc->pNext = cc->pNext->pNext;
+ break;
+ }
+ cc = cc->pNext;
+ }
+ assert(cc);
+ }
+ sqliteHashInsert(&(db->aDb[pTrigger->iDb].trigHash), zName, nName+1, 0);
+ sqliteDeleteTrigger(pTrigger);
+ }
+}
+
+/*
+** pEList is the SET clause of an UPDATE statement. Each entry
+** in pEList is of the format <id>=<expr>. If any of the entries
+** in pEList have an <id> which matches an identifier in pIdList,
+** then return TRUE. If pIdList==NULL, then it is considered a
+** wildcard that matches anything. Likewise if pEList==NULL then
+** it matches anything so always return true. Return false only
+** if there is no match.
+*/
+static int checkColumnOverLap(IdList *pIdList, ExprList *pEList){
+ int e;
+ if( !pIdList || !pEList ) return 1;
+ for(e=0; e<pEList->nExpr; e++){
+ if( sqliteIdListIndex(pIdList, pEList->a[e].zName)>=0 ) return 1;
+ }
+ return 0;
+}
+
+/* A global variable that is TRUE if we should always set up temp tables for
+ * for triggers, even if there are no triggers to code. This is used to test
+ * how much overhead the triggers algorithm is causing.
+ *
+ * This flag can be set or cleared using the "trigger_overhead_test" pragma.
+ * The pragma is not documented since it is not really part of the interface
+ * to STQLite, just the test procedure.
+*/
+int always_code_trigger_setup = 0;
+
+/*
+ * Returns true if a trigger matching op, tr_tm and foreach that is NOT already
+ * on the Parse objects trigger-stack (to prevent recursive trigger firing) is
+ * found in the list specified as pTrigger.
+ */
+int sqliteTriggersExist(
+ Parse *pParse, /* Used to check for recursive triggers */
+ Trigger *pTrigger, /* A list of triggers associated with a table */
+ int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */
+ int tr_tm, /* one of TK_BEFORE, TK_AFTER */
+ int foreach, /* one of TK_ROW or TK_STATEMENT */
+ ExprList *pChanges /* Columns that change in an UPDATE statement */
+){
+ Trigger * pTriggerCursor;
+
+ if( always_code_trigger_setup ){
+ return 1;
+ }
+
+ pTriggerCursor = pTrigger;
+ while( pTriggerCursor ){
+ if( pTriggerCursor->op == op &&
+ pTriggerCursor->tr_tm == tr_tm &&
+ pTriggerCursor->foreach == foreach &&
+ checkColumnOverLap(pTriggerCursor->pColumns, pChanges) ){
+ TriggerStack * ss;
+ ss = pParse->trigStack;
+ while( ss && ss->pTrigger != pTrigger ){
+ ss = ss->pNext;
+ }
+ if( !ss )return 1;
+ }
+ pTriggerCursor = pTriggerCursor->pNext;
+ }
+
+ return 0;
+}
+
+/*
+** Convert the pStep->target token into a SrcList and return a pointer
+** to that SrcList.
+**
+** This routine adds a specific database name, if needed, to the target when
+** forming the SrcList. This prevents a trigger in one database from
+** referring to a target in another database. An exception is when the
+** trigger is in TEMP in which case it can refer to any other database it
+** wants.
+*/
+static SrcList *targetSrcList(
+ Parse *pParse, /* The parsing context */
+ TriggerStep *pStep /* The trigger containing the target token */
+){
+ Token sDb; /* Dummy database name token */
+ int iDb; /* Index of the database to use */
+ SrcList *pSrc; /* SrcList to be returned */
+
+ iDb = pStep->pTrig->iDb;
+ if( iDb==0 || iDb>=2 ){
+ assert( iDb<pParse->db->nDb );
+ sDb.z = pParse->db->aDb[iDb].zName;
+ sDb.n = strlen(sDb.z);
+ pSrc = sqliteSrcListAppend(0, &sDb, &pStep->target);
+ } else {
+ pSrc = sqliteSrcListAppend(0, &pStep->target, 0);
+ }
+ return pSrc;
+}
+
+/*
+** Generate VDBE code for zero or more statements inside the body of a
+** trigger.
+*/
+static int codeTriggerProgram(
+ Parse *pParse, /* The parser context */
+ TriggerStep *pStepList, /* List of statements inside the trigger body */
+ int orconfin /* Conflict algorithm. (OE_Abort, etc) */
+){
+ TriggerStep * pTriggerStep = pStepList;
+ int orconf;
+
+ while( pTriggerStep ){
+ int saveNTab = pParse->nTab;
+
+ orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin;
+ pParse->trigStack->orconf = orconf;
+ switch( pTriggerStep->op ){
+ case TK_SELECT: {
+ Select * ss = sqliteSelectDup(pTriggerStep->pSelect);
+ assert(ss);
+ assert(ss->pSrc);
+ sqliteSelect(pParse, ss, SRT_Discard, 0, 0, 0, 0);
+ sqliteSelectDelete(ss);
+ break;
+ }
+ case TK_UPDATE: {
+ SrcList *pSrc;
+ pSrc = targetSrcList(pParse, pTriggerStep);
+ sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
+ sqliteUpdate(pParse, pSrc,
+ sqliteExprListDup(pTriggerStep->pExprList),
+ sqliteExprDup(pTriggerStep->pWhere), orconf);
+ sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
+ break;
+ }
+ case TK_INSERT: {
+ SrcList *pSrc;
+ pSrc = targetSrcList(pParse, pTriggerStep);
+ sqliteInsert(pParse, pSrc,
+ sqliteExprListDup(pTriggerStep->pExprList),
+ sqliteSelectDup(pTriggerStep->pSelect),
+ sqliteIdListDup(pTriggerStep->pIdList), orconf);
+ break;
+ }
+ case TK_DELETE: {
+ SrcList *pSrc;
+ sqliteVdbeAddOp(pParse->pVdbe, OP_ListPush, 0, 0);
+ pSrc = targetSrcList(pParse, pTriggerStep);
+ sqliteDeleteFrom(pParse, pSrc, sqliteExprDup(pTriggerStep->pWhere));
+ sqliteVdbeAddOp(pParse->pVdbe, OP_ListPop, 0, 0);
+ break;
+ }
+ default:
+ assert(0);
+ }
+ pParse->nTab = saveNTab;
+ pTriggerStep = pTriggerStep->pNext;
+ }
+
+ return 0;
+}
+
+/*
+** This is called to code FOR EACH ROW triggers.
+**
+** When the code that this function generates is executed, the following
+** must be true:
+**
+** 1. No cursors may be open in the main database. (But newIdx and oldIdx
+** can be indices of cursors in temporary tables. See below.)
+**
+** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then
+** a temporary vdbe cursor (index newIdx) must be open and pointing at
+** a row containing values to be substituted for new.* expressions in the
+** trigger program(s).
+**
+** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then
+** a temporary vdbe cursor (index oldIdx) must be open and pointing at
+** a row containing values to be substituted for old.* expressions in the
+** trigger program(s).
+**
+*/
+int sqliteCodeRowTrigger(
+ Parse *pParse, /* Parse context */
+ int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */
+ ExprList *pChanges, /* Changes list for any UPDATE OF triggers */
+ int tr_tm, /* One of TK_BEFORE, TK_AFTER */
+ Table *pTab, /* The table to code triggers from */
+ int newIdx, /* The indice of the "new" row to access */
+ int oldIdx, /* The indice of the "old" row to access */
+ int orconf, /* ON CONFLICT policy */
+ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */
+){
+ Trigger * pTrigger;
+ TriggerStack * pTriggerStack;
+
+ assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE);
+ assert(tr_tm == TK_BEFORE || tr_tm == TK_AFTER );
+
+ assert(newIdx != -1 || oldIdx != -1);
+
+ pTrigger = pTab->pTrigger;
+ while( pTrigger ){
+ int fire_this = 0;
+
+ /* determine whether we should code this trigger */
+ if( pTrigger->op == op && pTrigger->tr_tm == tr_tm &&
+ pTrigger->foreach == TK_ROW ){
+ fire_this = 1;
+ pTriggerStack = pParse->trigStack;
+ while( pTriggerStack ){
+ if( pTriggerStack->pTrigger == pTrigger ){
+ fire_this = 0;
+ }
+ pTriggerStack = pTriggerStack->pNext;
+ }
+ if( op == TK_UPDATE && pTrigger->pColumns &&
+ !checkColumnOverLap(pTrigger->pColumns, pChanges) ){
+ fire_this = 0;
+ }
+ }
+
+ if( fire_this && (pTriggerStack = sqliteMalloc(sizeof(TriggerStack)))!=0 ){
+ int endTrigger;
+ SrcList dummyTablist;
+ Expr * whenExpr;
+ AuthContext sContext;
+
+ dummyTablist.nSrc = 0;
+
+ /* Push an entry on to the trigger stack */
+ pTriggerStack->pTrigger = pTrigger;
+ pTriggerStack->newIdx = newIdx;
+ pTriggerStack->oldIdx = oldIdx;
+ pTriggerStack->pTab = pTab;
+ pTriggerStack->pNext = pParse->trigStack;
+ pTriggerStack->ignoreJump = ignoreJump;
+ pParse->trigStack = pTriggerStack;
+ sqliteAuthContextPush(pParse, &sContext, pTrigger->name);
+
+ /* code the WHEN clause */
+ endTrigger = sqliteVdbeMakeLabel(pParse->pVdbe);
+ whenExpr = sqliteExprDup(pTrigger->pWhen);
+ if( sqliteExprResolveIds(pParse, &dummyTablist, 0, whenExpr) ){
+ pParse->trigStack = pParse->trigStack->pNext;
+ sqliteFree(pTriggerStack);
+ sqliteExprDelete(whenExpr);
+ return 1;
+ }
+ sqliteExprIfFalse(pParse, whenExpr, endTrigger, 1);
+ sqliteExprDelete(whenExpr);
+
+ sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPush, 0, 0);
+ codeTriggerProgram(pParse, pTrigger->step_list, orconf);
+ sqliteVdbeAddOp(pParse->pVdbe, OP_ContextPop, 0, 0);
+
+ /* Pop the entry off the trigger stack */
+ pParse->trigStack = pParse->trigStack->pNext;
+ sqliteAuthContextPop(&sContext);
+ sqliteFree(pTriggerStack);
+
+ sqliteVdbeResolveLabel(pParse->pVdbe, endTrigger);
+ }
+ pTrigger = pTrigger->pNext;
+ }
+
+ return 0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/trolltech.patch b/tqtinterface/qt4/src/3rdparty/sqlite/trolltech.patch
new file mode 100644
index 0000000..cbafffb
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/trolltech.patch
@@ -0,0 +1,39 @@
+diff -du ./config.h /home/harald/troll/qt-3.3/src/3rdparty/sqlite/config.h
+--- ./config.h 2004-03-30 19:13:22.000000000 +0200
++++ /home/harald/troll/qt-3.3/src/3rdparty/sqlite/config.h 2004-01-08 14:29:23.000000000 +0100
+@@ -1 +1,23 @@
+-#define SQLITE_PTR_SZ 4
++#include <qglobal.h>
++#include <qconfig.h>
++
++#ifndef QT_POINTER_SIZE
++# ifdef Q_OS_WIN32
++# define QT_POINTER_SIZE 4
++# elif Q_OS_WIN64
++# define QT_POINTER_SIZE 8
++# else
++# error This platform is unsupported
++# endif
++#endif /* QT_POINTER_SIZE */
++
++#define SQLITE_PTR_SZ QT_POINTER_SIZE
++
++#ifdef UNICODE
++# undef UNICODE
++#endif
++
++#ifdef Q_CC_MSVC
++# pragma warning(disable: 4018)
++# pragma warning(disable: 4761)
++#endif
+diff -du ./os.h /home/harald/troll/qt-3.3/src/3rdparty/sqlite/os.h
+--- ./os.h 2004-03-30 19:13:19.000000000 +0200
++++ /home/harald/troll/qt-3.3/src/3rdparty/sqlite/os.h 2004-01-08 14:29:23.000000000 +0100
+@@ -17,6 +17,7 @@
+ #ifndef _SQLITE_OS_H_
+ #define _SQLITE_OS_H_
+
++#include "config.h"
+ /*
+ ** Helpful hint: To get this to compile on HP/UX, add -D_INCLUDE_POSIX_SOURCE
+ ** to the compiler command line.
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/update.c b/tqtinterface/qt4/src/3rdparty/sqlite/update.c
new file mode 100644
index 0000000..2bb4129
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/update.c
@@ -0,0 +1,452 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains C code routines that are called by the parser
+** to handle UPDATE statements.
+**
+** $Id: update.c,v 1.70 2004/02/22 20:05:02 drh Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** Process an UPDATE statement.
+**
+** UPDATE OR IGNORE table_wxyz SET a=b, c=d WHERE e<5 AND f NOT NULL;
+** \_______/ \________/ \______/ \________________/
+* onError pTabList pChanges pWhere
+*/
+void sqliteUpdate(
+ Parse *pParse, /* The parser context */
+ SrcList *pTabList, /* The table in which we should change things */
+ ExprList *pChanges, /* Things to be changed */
+ Expr *pWhere, /* The WHERE clause. May be null */
+ int onError /* How to handle constraint errors */
+){
+ int i, j; /* Loop counters */
+ Table *pTab; /* The table to be updated */
+ int addr; /* VDBE instruction address of the start of the loop */
+ WhereInfo *pWInfo; /* Information about the WHERE clause */
+ Vdbe *v; /* The virtual database engine */
+ Index *pIdx; /* For looping over indices */
+ int nIdx; /* Number of indices that need updating */
+ int nIdxTotal; /* Total number of indices */
+ int iCur; /* VDBE Cursor number of pTab */
+ sqlite *db; /* The database structure */
+ Index **apIdx = 0; /* An array of indices that need updating too */
+ char *aIdxUsed = 0; /* aIdxUsed[i]==1 if the i-th index is used */
+ int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the
+ ** an expression for the i-th column of the table.
+ ** aXRef[i]==-1 if the i-th column is not changed. */
+ int chngRecno; /* True if the record number is being changed */
+ Expr *pRecnoExpr; /* Expression defining the new record number */
+ int openAll; /* True if all indices need to be opened */
+ int isView; /* Trying to update a view */
+ AuthContext sContext; /* The authorization context */
+
+ int before_triggers; /* True if there are any BEFORE triggers */
+ int after_triggers; /* True if there are any AFTER triggers */
+ int row_triggers_exist = 0; /* True if any row triggers exist */
+
+ int newIdx = -1; /* index of trigger "new" temp table */
+ int oldIdx = -1; /* index of trigger "old" temp table */
+
+ sContext.pParse = 0;
+ if( pParse->nErr || sqlite_malloc_failed ) goto update_cleanup;
+ db = pParse->db;
+ assert( pTabList->nSrc==1 );
+
+ /* Locate the table which we want to update.
+ */
+ pTab = sqliteSrcListLookup(pParse, pTabList);
+ if( pTab==0 ) goto update_cleanup;
+ before_triggers = sqliteTriggersExist(pParse, pTab->pTrigger,
+ TK_UPDATE, TK_BEFORE, TK_ROW, pChanges);
+ after_triggers = sqliteTriggersExist(pParse, pTab->pTrigger,
+ TK_UPDATE, TK_AFTER, TK_ROW, pChanges);
+ row_triggers_exist = before_triggers || after_triggers;
+ isView = pTab->pSelect!=0;
+ if( sqliteIsReadOnly(pParse, pTab, before_triggers) ){
+ goto update_cleanup;
+ }
+ if( isView ){
+ if( sqliteViewGetColumnNames(pParse, pTab) ){
+ goto update_cleanup;
+ }
+ }
+ aXRef = sqliteMalloc( sizeof(int) * pTab->nCol );
+ if( aXRef==0 ) goto update_cleanup;
+ for(i=0; i<pTab->nCol; i++) aXRef[i] = -1;
+
+ /* If there are FOR EACH ROW triggers, allocate cursors for the
+ ** special OLD and NEW tables
+ */
+ if( row_triggers_exist ){
+ newIdx = pParse->nTab++;
+ oldIdx = pParse->nTab++;
+ }
+
+ /* Allocate a cursors for the main database table and for all indices.
+ ** The index cursors might not be used, but if they are used they
+ ** need to occur right after the database cursor. So go ahead and
+ ** allocate enough space, just in case.
+ */
+ pTabList->a[0].iCursor = iCur = pParse->nTab++;
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ pParse->nTab++;
+ }
+
+ /* Resolve the column names in all the expressions of the
+ ** of the UPDATE statement. Also tqfind the column index
+ ** for each column to be updated in the pChanges array. For each
+ ** column to be updated, make sure we have authorization to change
+ ** that column.
+ */
+ chngRecno = 0;
+ for(i=0; i<pChanges->nExpr; i++){
+ if( sqliteExprResolveIds(pParse, pTabList, 0, pChanges->a[i].pExpr) ){
+ goto update_cleanup;
+ }
+ if( sqliteExprCheck(pParse, pChanges->a[i].pExpr, 0, 0) ){
+ goto update_cleanup;
+ }
+ for(j=0; j<pTab->nCol; j++){
+ if( sqliteStrICmp(pTab->aCol[j].zName, pChanges->a[i].zName)==0 ){
+ if( j==pTab->iPKey ){
+ chngRecno = 1;
+ pRecnoExpr = pChanges->a[i].pExpr;
+ }
+ aXRef[j] = i;
+ break;
+ }
+ }
+ if( j>=pTab->nCol ){
+ if( sqliteIsRowid(pChanges->a[i].zName) ){
+ chngRecno = 1;
+ pRecnoExpr = pChanges->a[i].pExpr;
+ }else{
+ sqliteErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName);
+ goto update_cleanup;
+ }
+ }
+#ifndef STQLITE_OMIT_AUTHORIZATION
+ {
+ int rc;
+ rc = sqliteAuthCheck(pParse, STQLITE_UPDATE, pTab->zName,
+ pTab->aCol[j].zName, db->aDb[pTab->iDb].zName);
+ if( rc==STQLITE_DENY ){
+ goto update_cleanup;
+ }else if( rc==STQLITE_IGNORE ){
+ aXRef[j] = -1;
+ }
+ }
+#endif
+ }
+
+ /* Allocate memory for the array apIdx[] and fill it with pointers to every
+ ** index that needs to be updated. Indices only need updating if their
+ ** key includes one of the columns named in pChanges or if the record
+ ** number of the original table entry is changing.
+ */
+ for(nIdx=nIdxTotal=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdxTotal++){
+ if( chngRecno ){
+ i = 0;
+ }else {
+ for(i=0; i<pIdx->nColumn; i++){
+ if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
+ }
+ }
+ if( i<pIdx->nColumn ) nIdx++;
+ }
+ if( nIdxTotal>0 ){
+ apIdx = sqliteMalloc( sizeof(Index*) * nIdx + nIdxTotal );
+ if( apIdx==0 ) goto update_cleanup;
+ aIdxUsed = (char*)&apIdx[nIdx];
+ }
+ for(nIdx=j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
+ if( chngRecno ){
+ i = 0;
+ }else{
+ for(i=0; i<pIdx->nColumn; i++){
+ if( aXRef[pIdx->aiColumn[i]]>=0 ) break;
+ }
+ }
+ if( i<pIdx->nColumn ){
+ apIdx[nIdx++] = pIdx;
+ aIdxUsed[j] = 1;
+ }else{
+ aIdxUsed[j] = 0;
+ }
+ }
+
+ /* Resolve the column names in all the expressions in the
+ ** WHERE clause.
+ */
+ if( pWhere ){
+ if( sqliteExprResolveIds(pParse, pTabList, 0, pWhere) ){
+ goto update_cleanup;
+ }
+ if( sqliteExprCheck(pParse, pWhere, 0, 0) ){
+ goto update_cleanup;
+ }
+ }
+
+ /* Start the view context
+ */
+ if( isView ){
+ sqliteAuthContextPush(pParse, &sContext, pTab->zName);
+ }
+
+ /* Begin generating code.
+ */
+ v = sqliteGetVdbe(pParse);
+ if( v==0 ) goto update_cleanup;
+ sqliteBeginWriteOperation(pParse, 1, pTab->iDb);
+
+ /* If we are trying to update a view, construct that view into
+ ** a temporary table.
+ */
+ if( isView ){
+ Select *pView;
+ pView = sqliteSelectDup(pTab->pSelect);
+ sqliteSelect(pParse, pView, SRT_TempTable, iCur, 0, 0, 0);
+ sqliteSelectDelete(pView);
+ }
+
+ /* Begin the database scan
+ */
+ pWInfo = sqliteWhereBegin(pParse, pTabList, pWhere, 1, 0);
+ if( pWInfo==0 ) goto update_cleanup;
+
+ /* Remember the index of every item to be updated.
+ */
+ sqliteVdbeAddOp(v, OP_ListWrite, 0, 0);
+
+ /* End the database scan loop.
+ */
+ sqliteWhereEnd(pWInfo);
+
+ /* Initialize the count of updated rows
+ */
+ if( db->flags & STQLITE_CountRows && !pParse->trigStack ){
+ sqliteVdbeAddOp(v, OP_Integer, 0, 0);
+ }
+
+ if( row_triggers_exist ){
+ /* Create pseudo-tables for NEW and OLD
+ */
+ sqliteVdbeAddOp(v, OP_OpenPseudo, oldIdx, 0);
+ sqliteVdbeAddOp(v, OP_OpenPseudo, newIdx, 0);
+
+ /* The top of the update loop for when there are triggers.
+ */
+ sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
+ addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
+
+ /* Open a cursor and make it point to the record that is
+ ** being updated.
+ */
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
+ if( !isView ){
+ sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqliteVdbeAddOp(v, OP_OpenRead, iCur, pTab->tnum);
+ }
+ sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
+
+ /* Generate the OLD table
+ */
+ sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
+ sqliteVdbeAddOp(v, OP_RowData, iCur, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, oldIdx, 0);
+
+ /* Generate the NEW table
+ */
+ if( chngRecno ){
+ sqliteExprCode(pParse, pRecnoExpr);
+ }else{
+ sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
+ }
+ for(i=0; i<pTab->nCol; i++){
+ if( i==pTab->iPKey ){
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ continue;
+ }
+ j = aXRef[i];
+ if( j<0 ){
+ sqliteVdbeAddOp(v, OP_Column, iCur, i);
+ }else{
+ sqliteExprCode(pParse, pChanges->a[j].pExpr);
+ }
+ }
+ sqliteVdbeAddOp(v, OP_MakeRecord, pTab->nCol, 0);
+ sqliteVdbeAddOp(v, OP_PutIntKey, newIdx, 0);
+ if( !isView ){
+ sqliteVdbeAddOp(v, OP_Close, iCur, 0);
+ }
+
+ /* Fire the BEFORE and INSTEAD OF triggers
+ */
+ if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_BEFORE, pTab,
+ newIdx, oldIdx, onError, addr) ){
+ goto update_cleanup;
+ }
+ }
+
+ if( !isView ){
+ /*
+ ** Open every index that needs updating. Note that if any
+ ** index could potentially invoke a REPLACE conflict resolution
+ ** action, then we need to open all indices because we might need
+ ** to be deleting some records.
+ */
+ sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqliteVdbeAddOp(v, OP_OpenWrite, iCur, pTab->tnum);
+ if( onError==OE_Replace ){
+ openAll = 1;
+ }else{
+ openAll = 0;
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ if( pIdx->onError==OE_Replace ){
+ openAll = 1;
+ break;
+ }
+ }
+ }
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ if( openAll || aIdxUsed[i] ){
+ sqliteVdbeAddOp(v, OP_Integer, pIdx->iDb, 0);
+ sqliteVdbeAddOp(v, OP_OpenWrite, iCur+i+1, pIdx->tnum);
+ assert( pParse->nTab>iCur+i+1 );
+ }
+ }
+
+ /* Loop over every record that needs updating. We have to load
+ ** the old data for each record to be updated because some columns
+ ** might not change and we will need to copy the old value.
+ ** Also, the old data is needed to delete the old index entires.
+ ** So make the cursor point at the old record.
+ */
+ if( !row_triggers_exist ){
+ sqliteVdbeAddOp(v, OP_ListRewind, 0, 0);
+ addr = sqliteVdbeAddOp(v, OP_ListRead, 0, 0);
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
+ }
+ sqliteVdbeAddOp(v, OP_NotExists, iCur, addr);
+
+ /* If the record number will change, push the record number as it
+ ** will be after the update. (The old record number is currently
+ ** on top of the stack.)
+ */
+ if( chngRecno ){
+ sqliteExprCode(pParse, pRecnoExpr);
+ sqliteVdbeAddOp(v, OP_MustBeInt, 0, 0);
+ }
+
+ /* Compute new data for this record.
+ */
+ for(i=0; i<pTab->nCol; i++){
+ if( i==pTab->iPKey ){
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ continue;
+ }
+ j = aXRef[i];
+ if( j<0 ){
+ sqliteVdbeAddOp(v, OP_Column, iCur, i);
+ }else{
+ sqliteExprCode(pParse, pChanges->a[j].pExpr);
+ }
+ }
+
+ /* Do constraint checks
+ */
+ sqliteGenerateConstraintChecks(pParse, pTab, iCur, aIdxUsed, chngRecno, 1,
+ onError, addr);
+
+ /* Delete the old indices for the current record.
+ */
+ sqliteGenerateRowIndexDelete(db, v, pTab, iCur, aIdxUsed);
+
+ /* If changing the record number, delete the old record.
+ */
+ if( chngRecno ){
+ sqliteVdbeAddOp(v, OP_Delete, iCur, 0);
+ }
+
+ /* Create the new index entries and the new record.
+ */
+ sqliteCompleteInsertion(pParse, pTab, iCur, aIdxUsed, chngRecno, 1, -1);
+ }
+
+ /* Increment the row counter
+ */
+ if( db->flags & STQLITE_CountRows && !pParse->trigStack){
+ sqliteVdbeAddOp(v, OP_AddImm, 1, 0);
+ }
+
+ /* If there are triggers, close all the cursors after each iteration
+ ** through the loop. The fire the after triggers.
+ */
+ if( row_triggers_exist ){
+ if( !isView ){
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ if( openAll || aIdxUsed[i] )
+ sqliteVdbeAddOp(v, OP_Close, iCur+i+1, 0);
+ }
+ sqliteVdbeAddOp(v, OP_Close, iCur, 0);
+ pParse->nTab = iCur;
+ }
+ if( sqliteCodeRowTrigger(pParse, TK_UPDATE, pChanges, TK_AFTER, pTab,
+ newIdx, oldIdx, onError, addr) ){
+ goto update_cleanup;
+ }
+ }
+
+ /* Repeat the above with the next record to be updated, until
+ ** all record selected by the WHERE clause have been updated.
+ */
+ sqliteVdbeAddOp(v, OP_Goto, 0, addr);
+ sqliteVdbeChangeP2(v, addr, sqliteVdbeCurrentAddr(v));
+ sqliteVdbeAddOp(v, OP_ListReset, 0, 0);
+
+ /* Close all tables if there were no FOR EACH ROW triggers */
+ if( !row_triggers_exist ){
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
+ if( openAll || aIdxUsed[i] ){
+ sqliteVdbeAddOp(v, OP_Close, iCur+i+1, 0);
+ }
+ }
+ sqliteVdbeAddOp(v, OP_Close, iCur, 0);
+ pParse->nTab = iCur;
+ }else{
+ sqliteVdbeAddOp(v, OP_Close, newIdx, 0);
+ sqliteVdbeAddOp(v, OP_Close, oldIdx, 0);
+ }
+
+ sqliteVdbeAddOp(v, OP_SetCounts, 0, 0);
+ sqliteEndWriteOperation(pParse);
+
+ /*
+ ** Return the number of rows that were changed.
+ */
+ if( db->flags & STQLITE_CountRows && !pParse->trigStack ){
+ sqliteVdbeOp3(v, OP_ColumnName, 0, 1, "rows updated", P3_STATIC);
+ sqliteVdbeAddOp(v, OP_Callback, 1, 0);
+ }
+
+update_cleanup:
+ sqliteAuthContextPop(&sContext);
+ sqliteFree(apIdx);
+ sqliteFree(aXRef);
+ sqliteSrcListDelete(pTabList);
+ sqliteExprListDelete(pChanges);
+ sqliteExprDelete(pWhere);
+ return;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/util.c b/tqtinterface/qt4/src/3rdparty/sqlite/util.c
new file mode 100644
index 0000000..1b32ed5
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/util.c
@@ -0,0 +1,1135 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Utility functions used throughout sqlite.
+**
+** This file tqcontains functions for allocating memory, comparing
+** strings, and stuff like that.
+**
+** $Id: util.c,v 1.74 2004/02/22 17:49:34 drh Exp $
+*/
+#include "sqliteInt.h"
+#include <stdarg.h>
+#include <ctype.h>
+
+/*
+** If malloc() ever fails, this global variable gets set to 1.
+** This causes the library to abort and never again function.
+*/
+int sqlite_malloc_failed = 0;
+
+/*
+** If MEMORY_DEBUG is defined, then use versions of malloc() and
+** free() that track memory usage and check for buffer overruns.
+*/
+#ifdef MEMORY_DEBUG
+
+/*
+** For keeping track of the number of mallocs and frees. This
+** is used to check for memory leaks.
+*/
+int sqlite_nMalloc; /* Number of sqliteMalloc() calls */
+int sqlite_nFree; /* Number of sqliteFree() calls */
+int sqlite_iMallocFail; /* Fail sqliteMalloc() after this many calls */
+#if MEMORY_DEBUG>1
+static int memcnt = 0;
+#endif
+
+/*
+** Number of 32-bit guard words
+*/
+#define N_GUARD 1
+
+/*
+** Allocate new memory and set it to zero. Return NULL if
+** no memory is available.
+*/
+void *sqliteMalloc_(int n, int bZero, char *zFile, int line){
+ void *p;
+ int *pi;
+ int i, k;
+ if( sqlite_iMallocFail>=0 ){
+ sqlite_iMallocFail--;
+ if( sqlite_iMallocFail==0 ){
+ sqlite_malloc_failed++;
+#if MEMORY_DEBUG>1
+ fprintf(stderr,"**** failed to allocate %d bytes at %s:%d\n",
+ n, zFile,line);
+#endif
+ sqlite_iMallocFail--;
+ return 0;
+ }
+ }
+ if( n==0 ) return 0;
+ k = (n+sizeof(int)-1)/sizeof(int);
+ pi = malloc( (N_GUARD*2+1+k)*sizeof(int));
+ if( pi==0 ){
+ sqlite_malloc_failed++;
+ return 0;
+ }
+ sqlite_nMalloc++;
+ for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
+ pi[N_GUARD] = n;
+ for(i=0; i<N_GUARD; i++) pi[k+1+N_GUARD+i] = 0xdead3344;
+ p = &pi[N_GUARD+1];
+ memset(p, bZero==0, n);
+#if MEMORY_DEBUG>1
+ fprintf(stderr,"%06d malloc %d bytes at 0x%x from %s:%d\n",
+ ++memcnt, n, (int)p, zFile,line);
+#endif
+ return p;
+}
+
+/*
+** Check to see if the given pointer was obtained from sqliteMalloc()
+** and is able to hold at least N bytes. Raise an exception if this
+** is not the case.
+**
+** This routine is used for testing purposes only.
+*/
+void sqliteCheckMemory(void *p, int N){
+ int *pi = p;
+ int n, i, k;
+ pi -= N_GUARD+1;
+ for(i=0; i<N_GUARD; i++){
+ assert( pi[i]==0xdead1122 );
+ }
+ n = pi[N_GUARD];
+ assert( N>=0 && N<n );
+ k = (n+sizeof(int)-1)/sizeof(int);
+ for(i=0; i<N_GUARD; i++){
+ assert( pi[k+N_GUARD+1+i]==0xdead3344 );
+ }
+}
+
+/*
+** Free memory previously obtained from sqliteMalloc()
+*/
+void sqliteFree_(void *p, char *zFile, int line){
+ if( p ){
+ int *pi, i, k, n;
+ pi = p;
+ pi -= N_GUARD+1;
+ sqlite_nFree++;
+ for(i=0; i<N_GUARD; i++){
+ if( pi[i]!=0xdead1122 ){
+ fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);
+ return;
+ }
+ }
+ n = pi[N_GUARD];
+ k = (n+sizeof(int)-1)/sizeof(int);
+ for(i=0; i<N_GUARD; i++){
+ if( pi[k+N_GUARD+1+i]!=0xdead3344 ){
+ fprintf(stderr,"High-end memory corruption at 0x%x\n", (int)p);
+ return;
+ }
+ }
+ memset(pi, 0xff, (k+N_GUARD*2+1)*sizeof(int));
+#if MEMORY_DEBUG>1
+ fprintf(stderr,"%06d free %d bytes at 0x%x from %s:%d\n",
+ ++memcnt, n, (int)p, zFile,line);
+#endif
+ free(pi);
+ }
+}
+
+/*
+** Resize a prior allocation. If p==0, then this routine
+** works just like sqliteMalloc(). If n==0, then this routine
+** works just like sqliteFree().
+*/
+void *sqliteRealloc_(void *oldP, int n, char *zFile, int line){
+ int *oldPi, *pi, i, k, oldN, oldK;
+ void *p;
+ if( oldP==0 ){
+ return sqliteMalloc_(n,1,zFile,line);
+ }
+ if( n==0 ){
+ sqliteFree_(oldP,zFile,line);
+ return 0;
+ }
+ oldPi = oldP;
+ oldPi -= N_GUARD+1;
+ if( oldPi[0]!=0xdead1122 ){
+ fprintf(stderr,"Low-end memory corruption in realloc at 0x%x\n", (int)oldP);
+ return 0;
+ }
+ oldN = oldPi[N_GUARD];
+ oldK = (oldN+sizeof(int)-1)/sizeof(int);
+ for(i=0; i<N_GUARD; i++){
+ if( oldPi[oldK+N_GUARD+1+i]!=0xdead3344 ){
+ fprintf(stderr,"High-end memory corruption in realloc at 0x%x\n",
+ (int)oldP);
+ return 0;
+ }
+ }
+ k = (n + sizeof(int) - 1)/sizeof(int);
+ pi = malloc( (k+N_GUARD*2+1)*sizeof(int) );
+ if( pi==0 ){
+ sqlite_malloc_failed++;
+ return 0;
+ }
+ for(i=0; i<N_GUARD; i++) pi[i] = 0xdead1122;
+ pi[N_GUARD] = n;
+ for(i=0; i<N_GUARD; i++) pi[k+N_GUARD+1+i] = 0xdead3344;
+ p = &pi[N_GUARD+1];
+ memcpy(p, oldP, n>oldN ? oldN : n);
+ if( n>oldN ){
+ memset(&((char*)p)[oldN], 0, n-oldN);
+ }
+ memset(oldPi, 0xab, (oldK+N_GUARD+2)*sizeof(int));
+ free(oldPi);
+#if MEMORY_DEBUG>1
+ fprintf(stderr,"%06d realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n",
+ ++memcnt, oldN, n, (int)oldP, (int)p, zFile, line);
+#endif
+ return p;
+}
+
+/*
+** Make a duplicate of a string into memory obtained from malloc()
+** Free the original string using sqliteFree().
+**
+** This routine is called on all strings that are passed outside of
+** the STQLite library. That way clients can free the string using free()
+** rather than having to call sqliteFree().
+*/
+void sqliteStrRealloc(char **pz){
+ char *zNew;
+ if( pz==0 || *pz==0 ) return;
+ zNew = malloc( strlen(*pz) + 1 );
+ if( zNew==0 ){
+ sqlite_malloc_failed++;
+ sqliteFree(*pz);
+ *pz = 0;
+ }
+ strcpy(zNew, *pz);
+ sqliteFree(*pz);
+ *pz = zNew;
+}
+
+/*
+** Make a copy of a string in memory obtained from sqliteMalloc()
+*/
+char *sqliteStrDup_(const char *z, char *zFile, int line){
+ char *zNew;
+ if( z==0 ) return 0;
+ zNew = sqliteMalloc_(strlen(z)+1, 0, zFile, line);
+ if( zNew ) strcpy(zNew, z);
+ return zNew;
+}
+char *sqliteStrNDup_(const char *z, int n, char *zFile, int line){
+ char *zNew;
+ if( z==0 ) return 0;
+ zNew = sqliteMalloc_(n+1, 0, zFile, line);
+ if( zNew ){
+ memcpy(zNew, z, n);
+ zNew[n] = 0;
+ }
+ return zNew;
+}
+#endif /* MEMORY_DEBUG */
+
+/*
+** The following versions of malloc() and free() are for use in a
+** normal build.
+*/
+#if !defined(MEMORY_DEBUG)
+
+/*
+** Allocate new memory and set it to zero. Return NULL if
+** no memory is available. See also sqliteMallocRaw().
+*/
+void *sqliteMalloc(int n){
+ void *p;
+ if( (p = malloc(n))==0 ){
+ if( n>0 ) sqlite_malloc_failed++;
+ }else{
+ memset(p, 0, n);
+ }
+ return p;
+}
+
+/*
+** Allocate new memory but do not set it to zero. Return NULL if
+** no memory is available. See also sqliteMalloc().
+*/
+void *sqliteMallocRaw(int n){
+ void *p;
+ if( (p = malloc(n))==0 ){
+ if( n>0 ) sqlite_malloc_failed++;
+ }
+ return p;
+}
+
+/*
+** Free memory previously obtained from sqliteMalloc()
+*/
+void sqliteFree(void *p){
+ if( p ){
+ free(p);
+ }
+}
+
+/*
+** Resize a prior allocation. If p==0, then this routine
+** works just like sqliteMalloc(). If n==0, then this routine
+** works just like sqliteFree().
+*/
+void *sqliteRealloc(void *p, int n){
+ void *p2;
+ if( p==0 ){
+ return sqliteMalloc(n);
+ }
+ if( n==0 ){
+ sqliteFree(p);
+ return 0;
+ }
+ p2 = realloc(p, n);
+ if( p2==0 ){
+ sqlite_malloc_failed++;
+ }
+ return p2;
+}
+
+/*
+** Make a copy of a string in memory obtained from sqliteMalloc()
+*/
+char *sqliteStrDup(const char *z){
+ char *zNew;
+ if( z==0 ) return 0;
+ zNew = sqliteMallocRaw(strlen(z)+1);
+ if( zNew ) strcpy(zNew, z);
+ return zNew;
+}
+char *sqliteStrNDup(const char *z, int n){
+ char *zNew;
+ if( z==0 ) return 0;
+ zNew = sqliteMallocRaw(n+1);
+ if( zNew ){
+ memcpy(zNew, z, n);
+ zNew[n] = 0;
+ }
+ return zNew;
+}
+#endif /* !defined(MEMORY_DEBUG) */
+
+/*
+** Create a string from the 2nd and subsequent arguments (up to the
+** first NULL argument), store the string in memory obtained from
+** sqliteMalloc() and make the pointer indicated by the 1st argument
+** point to that string. The 1st argument must either be NULL or
+** point to memory obtained from sqliteMalloc().
+*/
+void sqliteSetString(char **pz, const char *zFirst, ...){
+ va_list ap;
+ int nByte;
+ const char *z;
+ char *zResult;
+
+ if( pz==0 ) return;
+ nByte = strlen(zFirst) + 1;
+ va_start(ap, zFirst);
+ while( (z = va_arg(ap, const char*))!=0 ){
+ nByte += strlen(z);
+ }
+ va_end(ap);
+ sqliteFree(*pz);
+ *pz = zResult = sqliteMallocRaw( nByte );
+ if( zResult==0 ){
+ return;
+ }
+ strcpy(zResult, zFirst);
+ zResult += strlen(zResult);
+ va_start(ap, zFirst);
+ while( (z = va_arg(ap, const char*))!=0 ){
+ strcpy(zResult, z);
+ zResult += strlen(zResult);
+ }
+ va_end(ap);
+#ifdef MEMORY_DEBUG
+#if MEMORY_DEBUG>1
+ fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
+#endif
+#endif
+}
+
+/*
+** Works like sqliteSetString, but each string is now followed by
+** a length integer which specifies how much of the source string
+** to copy (in bytes). -1 means use the whole string. The 1st
+** argument must either be NULL or point to memory obtained from
+** sqliteMalloc().
+*/
+void sqliteSetNString(char **pz, ...){
+ va_list ap;
+ int nByte;
+ const char *z;
+ char *zResult;
+ int n;
+
+ if( pz==0 ) return;
+ nByte = 0;
+ va_start(ap, pz);
+ while( (z = va_arg(ap, const char*))!=0 ){
+ n = va_arg(ap, int);
+ if( n<=0 ) n = strlen(z);
+ nByte += n;
+ }
+ va_end(ap);
+ sqliteFree(*pz);
+ *pz = zResult = sqliteMallocRaw( nByte + 1 );
+ if( zResult==0 ) return;
+ va_start(ap, pz);
+ while( (z = va_arg(ap, const char*))!=0 ){
+ n = va_arg(ap, int);
+ if( n<=0 ) n = strlen(z);
+ strncpy(zResult, z, n);
+ zResult += n;
+ }
+ *zResult = 0;
+#ifdef MEMORY_DEBUG
+#if MEMORY_DEBUG>1
+ fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
+#endif
+#endif
+ va_end(ap);
+}
+
+/*
+** Add an error message to pParse->zErrMsg and increment pParse->nErr.
+** The following formatting characters are allowed:
+**
+** %s Insert a string
+** %z A string that should be freed after use
+** %d Insert an integer
+** %T Insert a token
+** %S Insert the first element of a SrcList
+*/
+void sqliteErrorMsg(Parse *pParse, const char *zFormat, ...){
+ va_list ap;
+ pParse->nErr++;
+ sqliteFree(pParse->zErrMsg);
+ va_start(ap, zFormat);
+ pParse->zErrMsg = sqliteVMPrintf(zFormat, ap);
+ va_end(ap);
+}
+
+/*
+** Convert an SQL-style quoted string into a normal string by removing
+** the quote characters. The conversion is done in-place. If the
+** input does not begin with a quote character, then this routine
+** is a no-op.
+**
+** 2002-Feb-14: This routine is extended to remove MS-Access style
+** brackets from around identifers. For example: "[a-b-c]" becomes
+** "a-b-c".
+*/
+void sqliteDequote(char *z){
+ int quote;
+ int i, j;
+ if( z==0 ) return;
+ quote = z[0];
+ switch( quote ){
+ case '\'': break;
+ case '"': break;
+ case '[': quote = ']'; break;
+ default: return;
+ }
+ for(i=1, j=0; z[i]; i++){
+ if( z[i]==quote ){
+ if( z[i+1]==quote ){
+ z[j++] = quote;
+ i++;
+ }else{
+ z[j++] = 0;
+ break;
+ }
+ }else{
+ z[j++] = z[i];
+ }
+ }
+}
+
+/* An array to map all upper-case characters into their corresponding
+** lower-case character.
+*/
+static unsigned char UpperToLower[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
+ 104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
+ 122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
+ 108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
+ 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+ 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
+ 162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
+ 180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
+ 198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
+ 216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
+ 234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
+ 252,253,254,255
+};
+
+/*
+** This function computes a hash on the name of a keyword.
+** Case is not significant.
+*/
+int sqliteHashNoCase(const char *z, int n){
+ int h = 0;
+ if( n<=0 ) n = strlen(z);
+ while( n > 0 ){
+ h = (h<<3) ^ h ^ UpperToLower[(unsigned char)*z++];
+ n--;
+ }
+ return h & 0x7fffffff;
+}
+
+/*
+** Some systems have stricmp(). Others have strcasecmp(). Because
+** there is no consistency, we will define our own.
+*/
+int sqliteStrICmp(const char *zLeft, const char *zRight){
+ register unsigned char *a, *b;
+ a = (unsigned char *)zLeft;
+ b = (unsigned char *)zRight;
+ while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
+ return *a - *b;
+}
+int sqliteStrNICmp(const char *zLeft, const char *zRight, int N){
+ register unsigned char *a, *b;
+ a = (unsigned char *)zLeft;
+ b = (unsigned char *)zRight;
+ while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
+ return N<0 ? 0 : *a - *b;
+}
+
+/*
+** Return TRUE if z is a pure numeric string. Return FALSE if the
+** string tqcontains any character which is not part of a number.
+**
+** Am empty string is considered non-numeric.
+*/
+int sqliteIsNumber(const char *z){
+ if( *z=='-' || *z=='+' ) z++;
+ if( !isdigit(*z) ){
+ return 0;
+ }
+ z++;
+ while( isdigit(*z) ){ z++; }
+ if( *z=='.' ){
+ z++;
+ if( !isdigit(*z) ) return 0;
+ while( isdigit(*z) ){ z++; }
+ }
+ if( *z=='e' || *z=='E' ){
+ z++;
+ if( *z=='+' || *z=='-' ) z++;
+ if( !isdigit(*z) ) return 0;
+ while( isdigit(*z) ){ z++; }
+ }
+ return *z==0;
+}
+
+/*
+** The string z[] is an ascii representation of a real number.
+** Convert this string to a double.
+**
+** This routine assumes that z[] really is a valid number. If it
+** is not, the result is undefined.
+**
+** This routine is used instead of the library atof() function because
+** the library atof() might want to use "," as the decimal point instead
+** of "." depending on how locale is set. But that would cause problems
+** for SQL. So this routine always uses "." regardless of locale.
+*/
+double sqliteAtoF(const char *z, const char **pzEnd){
+ int sign = 1;
+ LONGDOUBLE_TYPE v1 = 0.0;
+ if( *z=='-' ){
+ sign = -1;
+ z++;
+ }else if( *z=='+' ){
+ z++;
+ }
+ while( isdigit(*z) ){
+ v1 = v1*10.0 + (*z - '0');
+ z++;
+ }
+ if( *z=='.' ){
+ LONGDOUBLE_TYPE divisor = 1.0;
+ z++;
+ while( isdigit(*z) ){
+ v1 = v1*10.0 + (*z - '0');
+ divisor *= 10.0;
+ z++;
+ }
+ v1 /= divisor;
+ }
+ if( *z=='e' || *z=='E' ){
+ int esign = 1;
+ int eval = 0;
+ LONGDOUBLE_TYPE scale = 1.0;
+ z++;
+ if( *z=='-' ){
+ esign = -1;
+ z++;
+ }else if( *z=='+' ){
+ z++;
+ }
+ while( isdigit(*z) ){
+ eval = eval*10 + *z - '0';
+ z++;
+ }
+ while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; }
+ while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; }
+ while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; }
+ while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; }
+ if( esign<0 ){
+ v1 /= scale;
+ }else{
+ v1 *= scale;
+ }
+ }
+ if( pzEnd ) *pzEnd = z;
+ return sign<0 ? -v1 : v1;
+}
+
+/*
+** The string zNum represents an integer. There might be some other
+** information following the integer too, but that part is ignored.
+** If the integer that the prefix of zNum represents will fit in a
+** 32-bit signed integer, return TRUE. Otherwise return FALSE.
+**
+** This routine returns FALSE for the string -2147483648 even that
+** that number will, in theory fit in a 32-bit integer. But positive
+** 2147483648 will not fit in 32 bits. So it seems safer to return
+** false.
+*/
+int sqliteFitsIn32Bits(const char *zNum){
+ int i, c;
+ if( *zNum=='-' || *zNum=='+' ) zNum++;
+ for(i=0; (c=zNum[i])>='0' && c<='9'; i++){}
+ return i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0);
+}
+
+/* This comparison routine is what we use for comparison operations
+** between numeric values in an SQL expression. "Numeric" is a little
+** bit misleading here. What we mean is that the strings have a
+** type of "numeric" from the point of view of SQL. The strings
+** do not necessarily contain numbers. They could contain text.
+**
+** If the input strings both look like actual numbers then they
+** compare in numerical order. Numerical strings are always less
+** than non-numeric strings so if one input string looks like a
+** number and the other does not, then the one that looks like
+** a number is the smaller. Non-numeric strings compare in
+** lexigraphical order (the same order as strcmp()).
+*/
+int sqliteCompare(const char *atext, const char *btext){
+ int result;
+ int isNumA, isNumB;
+ if( atext==0 ){
+ return -1;
+ }else if( btext==0 ){
+ return 1;
+ }
+ isNumA = sqliteIsNumber(atext);
+ isNumB = sqliteIsNumber(btext);
+ if( isNumA ){
+ if( !isNumB ){
+ result = -1;
+ }else{
+ double rA, rB;
+ rA = sqliteAtoF(atext, 0);
+ rB = sqliteAtoF(btext, 0);
+ if( rA<rB ){
+ result = -1;
+ }else if( rA>rB ){
+ result = +1;
+ }else{
+ result = 0;
+ }
+ }
+ }else if( isNumB ){
+ result = +1;
+ }else {
+ result = strcmp(atext, btext);
+ }
+ return result;
+}
+
+/*
+** This routine is used for sorting. Each key is a list of one or more
+** null-terminated elements. The list is terminated by two nulls in
+** a row. For example, the following text is a key with three elements
+**
+** Aone\000Dtwo\000Athree\000\000
+**
+** All elements begin with one of the characters "+-AD" and end with "\000"
+** with zero or more text elements in between. Except, NULL elements
+** consist of the special two-character sequence "N\000".
+**
+** Both arguments will have the same number of elements. This routine
+** returns negative, zero, or positive if the first argument is less
+** than, equal to, or greater than the first. (Result is a-b).
+**
+** Each element begins with one of the characters "+", "-", "A", "D".
+** This character determines the sort order and collating sequence:
+**
+** + Sort numerically in ascending order
+** - Sort numerically in descending order
+** A Sort as strings in ascending order
+** D Sort as strings in descending order.
+**
+** For the "+" and "-" sorting, pure numeric strings (strings for which the
+** isNum() function above returns TRUE) always compare less than strings
+** that are not pure numerics. Non-numeric strings compare in memcmp()
+** order. This is the same sort order as the sqliteCompare() function
+** above generates.
+**
+** The last point is a change from version 2.6.3 to version 2.7.0. In
+** version 2.6.3 and earlier, substrings of digits compare in numerical
+** and case was used only to break a tie.
+**
+** Elements that begin with 'A' or 'D' compare in memcmp() order regardless
+** of whether or not they look like a number.
+**
+** Note that the sort order imposed by the rules above is the same
+** from the ordering defined by the "<", "<=", ">", and ">=" operators
+** of expressions and for indices. This was not the case for version
+** 2.6.3 and earlier.
+*/
+int sqliteSortCompare(const char *a, const char *b){
+ int res = 0;
+ int isNumA, isNumB;
+ int dir = 0;
+
+ while( res==0 && *a && *b ){
+ if( a[0]=='N' || b[0]=='N' ){
+ if( a[0]==b[0] ){
+ a += 2;
+ b += 2;
+ continue;
+ }
+ if( a[0]=='N' ){
+ dir = b[0];
+ res = -1;
+ }else{
+ dir = a[0];
+ res = +1;
+ }
+ break;
+ }
+ assert( a[0]==b[0] );
+ if( (dir=a[0])=='A' || a[0]=='D' ){
+ res = strcmp(&a[1],&b[1]);
+ if( res ) break;
+ }else{
+ isNumA = sqliteIsNumber(&a[1]);
+ isNumB = sqliteIsNumber(&b[1]);
+ if( isNumA ){
+ double rA, rB;
+ if( !isNumB ){
+ res = -1;
+ break;
+ }
+ rA = sqliteAtoF(&a[1], 0);
+ rB = sqliteAtoF(&b[1], 0);
+ if( rA<rB ){
+ res = -1;
+ break;
+ }
+ if( rA>rB ){
+ res = +1;
+ break;
+ }
+ }else if( isNumB ){
+ res = +1;
+ break;
+ }else{
+ res = strcmp(&a[1],&b[1]);
+ if( res ) break;
+ }
+ }
+ a += strlen(&a[1]) + 2;
+ b += strlen(&b[1]) + 2;
+ }
+ if( dir=='-' || dir=='D' ) res = -res;
+ return res;
+}
+
+/*
+** Some powers of 64. These constants are needed in the
+** sqliteRealToSortable() routine below.
+*/
+#define _64e3 (64.0 * 64.0 * 64.0)
+#define _64e4 (64.0 * 64.0 * 64.0 * 64.0)
+#define _64e15 (_64e3 * _64e4 * _64e4 * _64e4)
+#define _64e16 (_64e4 * _64e4 * _64e4 * _64e4)
+#define _64e63 (_64e15 * _64e16 * _64e16 * _64e16)
+#define _64e64 (_64e16 * _64e16 * _64e16 * _64e16)
+
+/*
+** The following procedure converts a double-precision floating point
+** number into a string. The resulting string has the property that
+** two such strings comparied using strcmp() or memcmp() will give the
+** same results as a numeric comparison of the original floating point
+** numbers.
+**
+** This routine is used to generate database keys from floating point
+** numbers such that the keys sort in the same order as the original
+** floating point numbers even though the keys are compared using
+** memcmp().
+**
+** The calling function should have allocated at least 14 characters
+** of space for the buffer z[].
+*/
+void sqliteRealToSortable(double r, char *z){
+ int neg;
+ int exp;
+ int cnt = 0;
+
+ /* This array maps integers between 0 and 63 into base-64 digits.
+ ** The digits must be chosen such at their ASCII codes are increasing.
+ ** This means we can not use the traditional base-64 digit set. */
+ static const char zDigit[] =
+ "0123456789"
+ "ABCDEFGHIJKLMNOPTQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "|~";
+ if( r<0.0 ){
+ neg = 1;
+ r = -r;
+ *z++ = '-';
+ } else {
+ neg = 0;
+ *z++ = '0';
+ }
+ exp = 0;
+
+ if( r==0.0 ){
+ exp = -1024;
+ }else if( r<(0.5/64.0) ){
+ while( r < 0.5/_64e64 && exp > -961 ){ r *= _64e64; exp -= 64; }
+ while( r < 0.5/_64e16 && exp > -1009 ){ r *= _64e16; exp -= 16; }
+ while( r < 0.5/_64e4 && exp > -1021 ){ r *= _64e4; exp -= 4; }
+ while( r < 0.5/64.0 && exp > -1024 ){ r *= 64.0; exp -= 1; }
+ }else if( r>=0.5 ){
+ while( r >= 0.5*_64e63 && exp < 960 ){ r *= 1.0/_64e64; exp += 64; }
+ while( r >= 0.5*_64e15 && exp < 1008 ){ r *= 1.0/_64e16; exp += 16; }
+ while( r >= 0.5*_64e3 && exp < 1020 ){ r *= 1.0/_64e4; exp += 4; }
+ while( r >= 0.5 && exp < 1023 ){ r *= 1.0/64.0; exp += 1; }
+ }
+ if( neg ){
+ exp = -exp;
+ r = -r;
+ }
+ exp += 1024;
+ r += 0.5;
+ if( exp<0 ) return;
+ if( exp>=2048 || r>=1.0 ){
+ strcpy(z, "~~~~~~~~~~~~");
+ return;
+ }
+ *z++ = zDigit[(exp>>6)&0x3f];
+ *z++ = zDigit[exp & 0x3f];
+ while( r>0.0 && cnt<10 ){
+ int digit;
+ r *= 64.0;
+ digit = (int)r;
+ assert( digit>=0 && digit<64 );
+ *z++ = zDigit[digit & 0x3f];
+ r -= digit;
+ cnt++;
+ }
+ *z = 0;
+}
+
+#ifdef STQLITE_UTF8
+/*
+** X is a pointer to the first byte of a UTF-8 character. Increment
+** X so that it points to the next character. This only works right
+** if X points to a well-formed UTF-8 string.
+*/
+#define sqliteNextChar(X) while( (0xc0&*++(X))==0x80 ){}
+#define sqliteCharVal(X) sqlite_utf8_to_int(X)
+
+#else /* !defined(STQLITE_UTF8) */
+/*
+** For iso8859 encoding, the next character is just the next byte.
+*/
+#define sqliteNextChar(X) (++(X));
+#define sqliteCharVal(X) ((int)*(X))
+
+#endif /* defined(STQLITE_UTF8) */
+
+
+#ifdef STQLITE_UTF8
+/*
+** Convert the UTF-8 character to which z points into a 31-bit
+** UCS character. This only works right if z points to a well-formed
+** UTF-8 string.
+*/
+static int sqlite_utf8_to_int(const unsigned char *z){
+ int c;
+ static const int initVal[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179,
+ 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 0, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 0,
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 0, 1, 254,
+ 255,
+ };
+ c = initVal[*(z++)];
+ while( (0xc0&*z)==0x80 ){
+ c = (c<<6) | (0x3f&*(z++));
+ }
+ return c;
+}
+#endif
+
+/*
+** Compare two UTF-8 strings for equality where the first string can
+** potentially be a "glob" expression. Return true (1) if they
+** are the same and false (0) if they are different.
+**
+** Globbing rules:
+**
+** '*' Matches any sequence of zero or more characters.
+**
+** '?' Matches exactly one character.
+**
+** [...] Matches one character from the enclosed list of
+** characters.
+**
+** [^...] Matches one character not in the enclosed list.
+**
+** With the [...] and [^...] matching, a ']' character can be included
+** in the list by making it the first character after '[' or '^'. A
+** range of characters can be specified using '-'. Example:
+** "[a-z]" matches any single lower-case letter. To match a '-', make
+** it the last character in the list.
+**
+** This routine is usually quick, but can be N**2 in the worst case.
+**
+** Hints: to match '*' or '?', put them in "[]". Like this:
+**
+** abc[*]xyz Matches "abc*xyz" only
+*/
+int
+sqliteGlobCompare(const unsigned char *zPattern, const unsigned char *zString){
+ register int c;
+ int invert;
+ int seen;
+ int c2;
+
+ while( (c = *zPattern)!=0 ){
+ switch( c ){
+ case '*':
+ while( (c=zPattern[1]) == '*' || c == '?' ){
+ if( c=='?' ){
+ if( *zString==0 ) return 0;
+ sqliteNextChar(zString);
+ }
+ zPattern++;
+ }
+ if( c==0 ) return 1;
+ if( c=='[' ){
+ while( *zString && sqliteGlobCompare(&zPattern[1],zString)==0 ){
+ sqliteNextChar(zString);
+ }
+ return *zString!=0;
+ }else{
+ while( (c2 = *zString)!=0 ){
+ while( c2 != 0 && c2 != c ){ c2 = *++zString; }
+ if( c2==0 ) return 0;
+ if( sqliteGlobCompare(&zPattern[1],zString) ) return 1;
+ sqliteNextChar(zString);
+ }
+ return 0;
+ }
+ case '?': {
+ if( *zString==0 ) return 0;
+ sqliteNextChar(zString);
+ zPattern++;
+ break;
+ }
+ case '[': {
+ int prior_c = 0;
+ seen = 0;
+ invert = 0;
+ c = sqliteCharVal(zString);
+ if( c==0 ) return 0;
+ c2 = *++zPattern;
+ if( c2=='^' ){ invert = 1; c2 = *++zPattern; }
+ if( c2==']' ){
+ if( c==']' ) seen = 1;
+ c2 = *++zPattern;
+ }
+ while( (c2 = sqliteCharVal(zPattern))!=0 && c2!=']' ){
+ if( c2=='-' && zPattern[1]!=']' && zPattern[1]!=0 && prior_c>0 ){
+ zPattern++;
+ c2 = sqliteCharVal(zPattern);
+ if( c>=prior_c && c<=c2 ) seen = 1;
+ prior_c = 0;
+ }else if( c==c2 ){
+ seen = 1;
+ prior_c = c2;
+ }else{
+ prior_c = c2;
+ }
+ sqliteNextChar(zPattern);
+ }
+ if( c2==0 || (seen ^ invert)==0 ) return 0;
+ sqliteNextChar(zString);
+ zPattern++;
+ break;
+ }
+ default: {
+ if( c != *zString ) return 0;
+ zPattern++;
+ zString++;
+ break;
+ }
+ }
+ }
+ return *zString==0;
+}
+
+/*
+** Compare two UTF-8 strings for equality using the "LIKE" operator of
+** SQL. The '%' character matches any sequence of 0 or more
+** characters and '_' matches any single character. Case is
+** not significant.
+**
+** This routine is just an adaptation of the sqliteGlobCompare()
+** routine above.
+*/
+int
+sqliteLikeCompare(const unsigned char *zPattern, const unsigned char *zString){
+ register int c;
+ int c2;
+
+ while( (c = UpperToLower[*zPattern])!=0 ){
+ switch( c ){
+ case '%': {
+ while( (c=zPattern[1]) == '%' || c == '_' ){
+ if( c=='_' ){
+ if( *zString==0 ) return 0;
+ sqliteNextChar(zString);
+ }
+ zPattern++;
+ }
+ if( c==0 ) return 1;
+ c = UpperToLower[c];
+ while( (c2=UpperToLower[*zString])!=0 ){
+ while( c2 != 0 && c2 != c ){ c2 = UpperToLower[*++zString]; }
+ if( c2==0 ) return 0;
+ if( sqliteLikeCompare(&zPattern[1],zString) ) return 1;
+ sqliteNextChar(zString);
+ }
+ return 0;
+ }
+ case '_': {
+ if( *zString==0 ) return 0;
+ sqliteNextChar(zString);
+ zPattern++;
+ break;
+ }
+ default: {
+ if( c != UpperToLower[*zString] ) return 0;
+ zPattern++;
+ zString++;
+ break;
+ }
+ }
+ }
+ return *zString==0;
+}
+
+/*
+** Change the sqlite.magic from STQLITE_MAGIC_OPEN to STQLITE_MAGIC_BUSY.
+** Return an error (non-zero) if the magic was not STQLITE_MAGIC_OPEN
+** when this routine is called.
+**
+** This routine is a attempt to detect if two threads use the
+** same sqlite* pointer at the same time. There is a race
+** condition so it is possible that the error is not detected.
+** But usually the problem will be seen. The result will be an
+** error which can be used to debug the application that is
+** using STQLite incorrectly.
+**
+** Ticket #202: If db->magic is not a valid open value, take care not
+** to modify the db structure at all. It could be that db is a stale
+** pointer. In other words, it could be that there has been a prior
+** call to sqlite_close(db) and db has been deallocated. And we do
+** not want to write into deallocated memory.
+*/
+int sqliteSafetyOn(sqlite *db){
+ if( db->magic==STQLITE_MAGIC_OPEN ){
+ db->magic = STQLITE_MAGIC_BUSY;
+ return 0;
+ }else if( db->magic==STQLITE_MAGIC_BUSY || db->magic==STQLITE_MAGIC_ERROR
+ || db->want_to_close ){
+ db->magic = STQLITE_MAGIC_ERROR;
+ db->flags |= STQLITE_Interrupt;
+ }
+ return 1;
+}
+
+/*
+** Change the magic from STQLITE_MAGIC_BUSY to STQLITE_MAGIC_OPEN.
+** Return an error (non-zero) if the magic was not STQLITE_MAGIC_BUSY
+** when this routine is called.
+*/
+int sqliteSafetyOff(sqlite *db){
+ if( db->magic==STQLITE_MAGIC_BUSY ){
+ db->magic = STQLITE_MAGIC_OPEN;
+ return 0;
+ }else if( db->magic==STQLITE_MAGIC_OPEN || db->magic==STQLITE_MAGIC_ERROR
+ || db->want_to_close ){
+ db->magic = STQLITE_MAGIC_ERROR;
+ db->flags |= STQLITE_Interrupt;
+ }
+ return 1;
+}
+
+/*
+** Check to make sure we are not currently executing an sqlite_exec().
+** If we are currently in an sqlite_exec(), return true and set
+** sqlite.magic to STQLITE_MAGIC_ERROR. This will cause a complete
+** shutdown of the database.
+**
+** This routine is used to try to detect when API routines are called
+** at the wrong time or in the wrong sequence.
+*/
+int sqliteSafetyCheck(sqlite *db){
+ if( db->pVdbe!=0 ){
+ db->magic = STQLITE_MAGIC_ERROR;
+ return 1;
+ }
+ return 0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/vacuum.c b/tqtinterface/qt4/src/3rdparty/sqlite/vacuum.c
new file mode 100644
index 0000000..b24f8bc
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/vacuum.c
@@ -0,0 +1,320 @@
+/*
+** 2003 April 6
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains code used to implement the VACUUM command.
+**
+** Most of the code in this file may be omitted by defining the
+** STQLITE_OMIT_VACUUM macro.
+**
+** $Id: vacuum.c,v 1.12 2004/02/25 02:33:35 drh Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+
+/*
+** A structure for holding a dynamic string - a string that can grow
+** without bound.
+*/
+typedef struct dynStr dynStr;
+struct dynStr {
+ char *z; /* Text of the string in space obtained from sqliteMalloc() */
+ int nAlloc; /* Amount of space allocated to z[] */
+ int nUsed; /* Next unused slot in z[] */
+};
+
+/*
+** A structure that holds the vacuum context
+*/
+typedef struct vacuumStruct vacuumStruct;
+struct vacuumStruct {
+ sqlite *dbOld; /* Original database */
+ sqlite *dbNew; /* New database */
+ char **pzErrMsg; /* Write errors here */
+ int rc; /* Set to non-zero on an error */
+ const char *zTable; /* Name of a table being copied */
+ const char *zPragma; /* Pragma to execute with results */
+ dynStr s1, s2; /* Two dynamic strings */
+};
+
+#if !defined(STQLITE_OMIT_VACUUM) || STQLITE_OMIT_VACUUM
+/*
+** Append text to a dynamic string
+*/
+static void appendText(dynStr *p, const char *zText, int nText){
+ if( nText<0 ) nText = strlen(zText);
+ if( p->z==0 || p->nUsed + nText + 1 >= p->nAlloc ){
+ char *zNew;
+ p->nAlloc = p->nUsed + nText + 1000;
+ zNew = sqliteRealloc(p->z, p->nAlloc);
+ if( zNew==0 ){
+ sqliteFree(p->z);
+ memset(p, 0, sizeof(*p));
+ return;
+ }
+ p->z = zNew;
+ }
+ memcpy(&p->z[p->nUsed], zText, nText+1);
+ p->nUsed += nText;
+}
+
+/*
+** Append text to a dynamic string, having first put the text in quotes.
+*/
+static void appendQuoted(dynStr *p, const char *zText){
+ int i, j;
+ appendText(p, "'", 1);
+ for(i=j=0; zText[i]; i++){
+ if( zText[i]=='\'' ){
+ appendText(p, &zText[j], i-j+1);
+ j = i + 1;
+ appendText(p, "'", 1);
+ }
+ }
+ if( j<i ){
+ appendText(p, &zText[j], i-j);
+ }
+ appendText(p, "'", 1);
+}
+
+/*
+** Execute statements of SQL. If an error occurs, write the error
+** message into *pzErrMsg and return non-zero.
+*/
+static int execsql(char **pzErrMsg, sqlite *db, const char *zSql){
+ char *zErrMsg = 0;
+ int rc;
+
+ /* printf("***** executing *****\n%s\n", zSql); */
+ rc = sqlite_exec(db, zSql, 0, 0, &zErrMsg);
+ if( zErrMsg ){
+ sqliteSetString(pzErrMsg, zErrMsg, (char*)0);
+ sqlite_freemem(zErrMsg);
+ }
+ return rc;
+}
+
+/*
+** This is the second stage callback. Each invocation tqcontains all the
+** data for a single row of a single table in the original database. This
+** routine must write that information into the new database.
+*/
+static int vacuumCallback2(void *pArg, int argc, char **argv, char **NotUsed){
+ vacuumStruct *p = (vacuumStruct*)pArg;
+ const char *zSep = "(";
+ int i;
+
+ if( argv==0 ) return 0;
+ p->s2.nUsed = 0;
+ appendText(&p->s2, "INSERT INTO ", -1);
+ appendQuoted(&p->s2, p->zTable);
+ appendText(&p->s2, " VALUES", -1);
+ for(i=0; i<argc; i++){
+ appendText(&p->s2, zSep, 1);
+ zSep = ",";
+ if( argv[i]==0 ){
+ appendText(&p->s2, "NULL", 4);
+ }else{
+ appendQuoted(&p->s2, argv[i]);
+ }
+ }
+ appendText(&p->s2,")", 1);
+ p->rc = execsql(p->pzErrMsg, p->dbNew, p->s2.z);
+ return p->rc;
+}
+
+/*
+** This is the first stage callback. Each invocation tqcontains three
+** arguments where are taken from the STQLITE_MASTER table of the original
+** database: (1) the entry type, (2) the entry name, and (3) the SQL for
+** the entry. In all cases, execute the SQL of the third argument.
+** For tables, run a query to select all entries in that table and
+** transfer them to the second-stage callback.
+*/
+static int vacuumCallback1(void *pArg, int argc, char **argv, char **NotUsed){
+ vacuumStruct *p = (vacuumStruct*)pArg;
+ int rc = 0;
+ assert( argc==3 );
+ if( argv==0 ) return 0;
+ assert( argv[0]!=0 );
+ assert( argv[1]!=0 );
+ assert( argv[2]!=0 );
+ rc = execsql(p->pzErrMsg, p->dbNew, argv[2]);
+ if( rc==STQLITE_OK && strcmp(argv[0],"table")==0 ){
+ char *zErrMsg = 0;
+ p->s1.nUsed = 0;
+ appendText(&p->s1, "SELECT * FROM ", -1);
+ appendQuoted(&p->s1, argv[1]);
+ p->zTable = argv[1];
+ rc = sqlite_exec(p->dbOld, p->s1.z, vacuumCallback2, p, &zErrMsg);
+ if( zErrMsg ){
+ sqliteSetString(p->pzErrMsg, zErrMsg, (char*)0);
+ sqlite_freemem(zErrMsg);
+ }
+ }
+ if( rc!=STQLITE_ABORT ) p->rc = rc;
+ return rc;
+}
+
+/*
+** This callback is used to transfer PRAGMA settings from one database
+** to the other. The value in argv[0] should be passed to a pragma
+** identified by ((vacuumStruct*)pArg)->zPragma.
+*/
+static int vacuumCallback3(void *pArg, int argc, char **argv, char **NotUsed){
+ vacuumStruct *p = (vacuumStruct*)pArg;
+ char zBuf[200];
+ assert( argc==1 );
+ if( argv==0 ) return 0;
+ assert( argv[0]!=0 );
+ assert( strlen(p->zPragma)<100 );
+ assert( strlen(argv[0])<30 );
+ sprintf(zBuf,"PRAGMA %s=%s;", p->zPragma, argv[0]);
+ p->rc = execsql(p->pzErrMsg, p->dbNew, zBuf);
+ return p->rc;
+}
+
+/*
+** Generate a random name of 20 character in length.
+*/
+static void randomName(unsigned char *zBuf){
+ static const unsigned char zChars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789";
+ int i;
+ sqliteRandomness(20, zBuf);
+ for(i=0; i<20; i++){
+ zBuf[i] = zChars[ zBuf[i]%(sizeof(zChars)-1) ];
+ }
+}
+#endif
+
+/*
+** The non-standard VACUUM command is used to clean up the database,
+** collapse free space, etc. It is modelled after the VACUUM command
+** in PostgreSQL.
+**
+** In version 1.0.x of STQLite, the VACUUM command would call
+** gdbm_reorganize() on all the database tables. But beginning
+** with 2.0.0, STQLite no longer uses GDBM so this command has
+** become a no-op.
+*/
+void sqliteVacuum(Parse *pParse, Token *pTableName){
+ Vdbe *v = sqliteGetVdbe(pParse);
+ sqliteVdbeAddOp(v, OP_Vacuum, 0, 0);
+ return;
+}
+
+/*
+** This routine implements the OP_Vacuum opcode of the VDBE.
+*/
+int sqliteRunVacuum(char **pzErrMsg, sqlite *db){
+#if !defined(STQLITE_OMIT_VACUUM) || STQLITE_OMIT_VACUUM
+ const char *zFilename; /* full pathname of the database file */
+ int nFilename; /* number of characters in zFilename[] */
+ char *zTemp = 0; /* a temporary file in same directory as zFilename */
+ sqlite *dbNew = 0; /* The new vacuumed database */
+ int rc = STQLITE_OK; /* Return code from service routines */
+ int i; /* Loop counter */
+ char *zErrMsg; /* Error message */
+ vacuumStruct sVac; /* Information passed to callbacks */
+
+ /* These are all of the pragmas that need to be transferred over
+ ** to the new database */
+ static const char *zPragma[] = {
+ "default_synchronous",
+ "default_cache_size",
+ /* "default_temp_store", */
+ };
+
+ if( db->flags & STQLITE_InTrans ){
+ sqliteSetString(pzErrMsg, "cannot VACUUM from within a transaction",
+ (char*)0);
+ return STQLITE_ERROR;
+ }
+ memset(&sVac, 0, sizeof(sVac));
+
+ /* Get the full pathname of the database file and create two
+ ** temporary filenames in the same directory as the original file.
+ */
+ zFilename = sqliteBtreeGetFilename(db->aDb[0].pBt);
+ if( zFilename==0 ){
+ /* This only happens with the in-memory database. VACUUM is a no-op
+ ** there, so just return */
+ return STQLITE_OK;
+ }
+ nFilename = strlen(zFilename);
+ zTemp = sqliteMalloc( nFilename+100 );
+ if( zTemp==0 ) return STQLITE_NOMEM;
+ strcpy(zTemp, zFilename);
+ for(i=0; i<10; i++){
+ zTemp[nFilename] = '-';
+ randomName(&zTemp[nFilename+1]);
+ if( !sqliteOsFileExists(zTemp) ) break;
+ }
+ if( i>=10 ){
+ sqliteSetString(pzErrMsg, "unable to create a temporary database file "
+ "in the same directory as the original database", (char*)0);
+ goto end_of_vacuum;
+ }
+
+
+ dbNew = sqlite_open(zTemp, 0, &zErrMsg);
+ if( dbNew==0 ){
+ sqliteSetString(pzErrMsg, "unable to open a temporary database at ",
+ zTemp, " - ", zErrMsg, (char*)0);
+ goto end_of_vacuum;
+ }
+ if( (rc = execsql(pzErrMsg, db, "BEGIN"))!=0 ) goto end_of_vacuum;
+ if( (rc = execsql(pzErrMsg, dbNew, "PRAGMA synchronous=off; BEGIN"))!=0 ){
+ goto end_of_vacuum;
+ }
+
+ sVac.dbOld = db;
+ sVac.dbNew = dbNew;
+ sVac.pzErrMsg = pzErrMsg;
+ for(i=0; rc==STQLITE_OK && i<sizeof(zPragma)/sizeof(zPragma[0]); i++){
+ char zBuf[200];
+ assert( strlen(zPragma[i])<100 );
+ sprintf(zBuf, "PRAGMA %s;", zPragma[i]);
+ sVac.zPragma = zPragma[i];
+ rc = sqlite_exec(db, zBuf, vacuumCallback3, &sVac, &zErrMsg);
+ }
+ if( rc==STQLITE_OK ){
+ rc = sqlite_exec(db,
+ "SELECT type, name, sql FROM sqlite_master "
+ "WHERE sql NOT NULL AND type!='view' "
+ "UNION ALL "
+ "SELECT type, name, sql FROM sqlite_master "
+ "WHERE sql NOT NULL AND type=='view'",
+ vacuumCallback1, &sVac, &zErrMsg);
+ }
+ if( rc==STQLITE_OK ){
+ rc = sqliteBtreeCopyFile(db->aDb[0].pBt, dbNew->aDb[0].pBt);
+ sqlite_exec(db, "COMMIT", 0, 0, 0);
+ sqliteResetInternalSchema(db, 0);
+ }
+
+end_of_vacuum:
+ if( rc && zErrMsg!=0 ){
+ sqliteSetString(pzErrMsg, "unable to vacuum database - ",
+ zErrMsg, (char*)0);
+ }
+ sqlite_exec(db, "ROLLBACK", 0, 0, 0);
+ if( dbNew ) sqlite_close(dbNew);
+ sqliteOsDelete(zTemp);
+ sqliteFree(zTemp);
+ sqliteFree(sVac.s1.z);
+ sqliteFree(sVac.s2.z);
+ if( zErrMsg ) sqlite_freemem(zErrMsg);
+ if( rc==STQLITE_ABORT ) sVac.rc = STQLITE_ERROR;
+ return sVac.rc;
+#endif
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/vdbe.c b/tqtinterface/qt4/src/3rdparty/sqlite/vdbe.c
new file mode 100644
index 0000000..3ba963d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/vdbe.c
@@ -0,0 +1,4885 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** The code in this file implements execution method of the
+** Virtual Database Engine (VDBE). A separate file ("vdbeaux.c")
+** handles housekeeping details such as creating and deleting
+** VDBE instances. This file is solely interested in executing
+** the VDBE program.
+**
+** In the external interface, an "sqlite_vm*" is an opaque pointer
+** to a VDBE.
+**
+** The SQL parser generates a program which is then executed by
+** the VDBE to do the work of the SQL statement. VDBE programs are
+** similar in form to assembly language. The program consists of
+** a linear sequence of operations. Each operation has an opcode
+** and 3 operands. Operands P1 and P2 are integers. Operand P3
+** is a null-terminated string. The P2 operand must be non-negative.
+** Opcodes will typically ignore one or more operands. Many opcodes
+** ignore all three operands.
+**
+** Computation results are stored on a stack. Each entry on the
+** stack is either an integer, a null-terminated string, a floating point
+** number, or the SQL "NULL" value. An inplicit conversion from one
+** type to the other occurs as necessary.
+**
+** Most of the code in this file is taken up by the sqliteVdbeExec()
+** function which does the work of interpreting a VDBE program.
+** But other routines are also provided to help in building up
+** a program instruction by instruction.
+**
+** Various scripts scan this source file in order to generate HTML
+** documentation, headers files, or other derived files. The formatting
+** of the code in this file is, therefore, important. See other comments
+** in this file for details. If in doubt, do not deviate from existing
+** commenting and indentation practices when changing or adding code.
+**
+** $Id: vdbe.c,v 1.268 2004/03/03 01:51:25 drh Exp $
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+#include "vdbeInt.h"
+
+/*
+** The following global variable is incremented every time a cursor
+** moves, either by the OP_MoveTo or the OP_Next opcode. The test
+** procedures use this information to make sure that indices are
+** working correctly. This variable has no function other than to
+** help verify the correct operation of the library.
+*/
+int sqlite_search_count = 0;
+
+/*
+** When this global variable is positive, it gets decremented once before
+** each instruction in the VDBE. When reaches zero, the STQLITE_Interrupt
+** of the db.flags field is set in order to simulate and interrupt.
+**
+** This facility is used for testing purposes only. It does not function
+** in an ordinary build.
+*/
+int sqlite_interrupt_count = 0;
+
+/*
+** Advance the virtual machine to the next output row.
+**
+** The return vale will be either STQLITE_BUSY, STQLITE_DONE,
+** STQLITE_ROW, STQLITE_ERROR, or STQLITE_MISUSE.
+**
+** STQLITE_BUSY means that the virtual machine attempted to open
+** a locked database and there is no busy callback registered.
+** Call sqlite_step() again to retry the open. *pN is set to 0
+** and *pazColName and *pazValue are both set to NULL.
+**
+** STQLITE_DONE means that the virtual machine has finished
+** executing. sqlite_step() should not be called again on this
+** virtual machine. *pN and *pazColName are set appropriately
+** but *pazValue is set to NULL.
+**
+** STQLITE_ROW means that the virtual machine has generated another
+** row of the result set. *pN is set to the number of columns in
+** the row. *pazColName is set to the names of the columns followed
+** by the column datatypes. *pazValue is set to the values of each
+** column in the row. The value of the i-th column is (*pazValue)[i].
+** The name of the i-th column is (*pazColName)[i] and the datatype
+** of the i-th column is (*pazColName)[i+*pN].
+**
+** STQLITE_ERROR means that a run-time error (such as a constraint
+** violation) has occurred. The details of the error will be returned
+** by the next call to sqlite_finalize(). sqlite_step() should not
+** be called again on the VM.
+**
+** STQLITE_MISUSE means that the this routine was called inappropriately.
+** Perhaps it was called on a virtual machine that had already been
+** finalized or on one that had previously returned STQLITE_ERROR or
+** STQLITE_DONE. Or it could be the case the the same database connection
+** is being used simulataneously by two or more threads.
+*/
+int sqlite_step(
+ sqlite_vm *pVm, /* The virtual machine to execute */
+ int *pN, /* OUT: Number of columns in result */
+ const char ***pazValue, /* OUT: Column data */
+ const char ***pazColName /* OUT: Column names and datatypes */
+){
+ Vdbe *p = (Vdbe*)pVm;
+ sqlite *db;
+ int rc;
+
+ if( p->magic!=VDBE_MAGIC_RUN ){
+ return STQLITE_MISUSE;
+ }
+ db = p->db;
+ if( sqliteSafetyOn(db) ){
+ p->rc = STQLITE_MISUSE;
+ return STQLITE_MISUSE;
+ }
+ if( p->explain ){
+ rc = sqliteVdbeList(p);
+ }else{
+ rc = sqliteVdbeExec(p);
+ }
+ if( rc==STQLITE_DONE || rc==STQLITE_ROW ){
+ if( pazColName ) *pazColName = (const char**)p->azColName;
+ if( pN ) *pN = p->nResColumn;
+ }else{
+ if( pazColName) *pazColName = 0;
+ if( pN ) *pN = 0;
+ }
+ if( pazValue ){
+ if( rc==STQLITE_ROW ){
+ *pazValue = (const char**)p->azResColumn;
+ }else{
+ *pazValue = 0;
+ }
+ }
+ if( sqliteSafetyOff(db) ){
+ return STQLITE_MISUSE;
+ }
+ return rc;
+}
+
+/*
+** Insert a new aggregate element and make it the element that
+** has focus.
+**
+** Return 0 on success and 1 if memory is exhausted.
+*/
+static int AggInsert(Agg *p, char *zKey, int nKey){
+ AggElem *pElem, *pOld;
+ int i;
+ Mem *pMem;
+ pElem = sqliteMalloc( sizeof(AggElem) + nKey +
+ (p->nMem-1)*sizeof(pElem->aMem[0]) );
+ if( pElem==0 ) return 1;
+ pElem->zKey = (char*)&pElem->aMem[p->nMem];
+ memcpy(pElem->zKey, zKey, nKey);
+ pElem->nKey = nKey;
+ pOld = sqliteHashInsert(&p->hash, pElem->zKey, pElem->nKey, pElem);
+ if( pOld!=0 ){
+ assert( pOld==pElem ); /* Malloc failed on insert */
+ sqliteFree(pOld);
+ return 0;
+ }
+ for(i=0, pMem=pElem->aMem; i<p->nMem; i++, pMem++){
+ pMem->flags = MEM_Null;
+ }
+ p->pCurrent = pElem;
+ return 0;
+}
+
+/*
+** Get the AggElem currently in focus
+*/
+#define AggInFocus(P) ((P).pCurrent ? (P).pCurrent : _AggInFocus(&(P)))
+static AggElem *_AggInFocus(Agg *p){
+ HashElem *pElem = sqliteHashFirst(&p->hash);
+ if( pElem==0 ){
+ AggInsert(p,"",1);
+ pElem = sqliteHashFirst(&p->hash);
+ }
+ return pElem ? sqliteHashData(pElem) : 0;
+}
+
+/*
+** Convert the given stack entity into a string if it isn't one
+** already.
+*/
+#define Stringify(P) if(((P)->flags & MEM_Str)==0){hardStringify(P);}
+static int hardStringify(Mem *pStack){
+ int fg = pStack->flags;
+ if( fg & MEM_Real ){
+ sqlite_snprintf(sizeof(pStack->zShort),pStack->zShort,"%.15g",pStack->r);
+ }else if( fg & MEM_Int ){
+ sqlite_snprintf(sizeof(pStack->zShort),pStack->zShort,"%d",pStack->i);
+ }else{
+ pStack->zShort[0] = 0;
+ }
+ pStack->z = pStack->zShort;
+ pStack->n = strlen(pStack->zShort)+1;
+ pStack->flags = MEM_Str | MEM_Short;
+ return 0;
+}
+
+/*
+** Convert the given stack entity into a string that has been obtained
+** from sqliteMalloc(). This is different from Stringify() above in that
+** Stringify() will use the NBFS bytes of static string space if the string
+** will fit but this routine always mallocs for space.
+** Return non-zero if we run out of memory.
+*/
+#define Dynamicify(P) (((P)->flags & MEM_Dyn)==0 ? hardDynamicify(P):0)
+static int hardDynamicify(Mem *pStack){
+ int fg = pStack->flags;
+ char *z;
+ if( (fg & MEM_Str)==0 ){
+ hardStringify(pStack);
+ }
+ assert( (fg & MEM_Dyn)==0 );
+ z = sqliteMallocRaw( pStack->n );
+ if( z==0 ) return 1;
+ memcpy(z, pStack->z, pStack->n);
+ pStack->z = z;
+ pStack->flags |= MEM_Dyn;
+ return 0;
+}
+
+/*
+** An ephemeral string value (signified by the MEM_Ephem flag) tqcontains
+** a pointer to a dynamically allocated string where some other entity
+** is responsible for deallocating that string. Because the stack entry
+** does not control the string, it might be deleted without the stack
+** entry knowing it.
+**
+** This routine converts an ephemeral string into a dynamically allocated
+** string that the stack entry itself controls. In other words, it
+** converts an MEM_Ephem string into an MEM_Dyn string.
+*/
+#define Deephemeralize(P) \
+ if( ((P)->flags&MEM_Ephem)!=0 && hardDeephem(P) ){ goto no_mem;}
+static int hardDeephem(Mem *pStack){
+ char *z;
+ assert( (pStack->flags & MEM_Ephem)!=0 );
+ z = sqliteMallocRaw( pStack->n );
+ if( z==0 ) return 1;
+ memcpy(z, pStack->z, pStack->n);
+ pStack->z = z;
+ pStack->flags &= ~MEM_Ephem;
+ pStack->flags |= MEM_Dyn;
+ return 0;
+}
+
+/*
+** Release the memory associated with the given stack level. This
+** leaves the Mem.flags field in an inconsistent state.
+*/
+#define Release(P) if((P)->flags&MEM_Dyn){ sqliteFree((P)->z); }
+
+/*
+** Pop the stack N times.
+*/
+static void popStack(Mem **ppTos, int N){
+ Mem *pTos = *ppTos;
+ while( N>0 ){
+ N--;
+ Release(pTos);
+ pTos--;
+ }
+ *ppTos = pTos;
+}
+
+/*
+** Return TRUE if zNum is a 32-bit signed integer and write
+** the value of the integer into *pNum. If zNum is not an integer
+** or is an integer that is too large to be expressed with just 32
+** bits, then return false.
+**
+** Under Linux (RedHat 7.2) this routine is much faster than atoi()
+** for converting strings into integers.
+*/
+static int toInt(const char *zNum, int *pNum){
+ int v = 0;
+ int neg;
+ int i, c;
+ if( *zNum=='-' ){
+ neg = 1;
+ zNum++;
+ }else if( *zNum=='+' ){
+ neg = 0;
+ zNum++;
+ }else{
+ neg = 0;
+ }
+ for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
+ v = v*10 + c - '0';
+ }
+ *pNum = neg ? -v : v;
+ return c==0 && i>0 && (i<10 || (i==10 && memcmp(zNum,"2147483647",10)<=0));
+}
+
+/*
+** Convert the given stack entity into a integer if it isn't one
+** already.
+**
+** Any prior string or real representation is invalidated.
+** NULLs are converted into 0.
+*/
+#define Integerify(P) if(((P)->flags&MEM_Int)==0){ hardIntegerify(P); }
+static void hardIntegerify(Mem *pStack){
+ if( pStack->flags & MEM_Real ){
+ pStack->i = (int)pStack->r;
+ Release(pStack);
+ }else if( pStack->flags & MEM_Str ){
+ toInt(pStack->z, &pStack->i);
+ Release(pStack);
+ }else{
+ pStack->i = 0;
+ }
+ pStack->flags = MEM_Int;
+}
+
+/*
+** Get a valid Real representation for the given stack element.
+**
+** Any prior string or integer representation is retained.
+** NULLs are converted into 0.0.
+*/
+#define Realify(P) if(((P)->flags&MEM_Real)==0){ hardRealify(P); }
+static void hardRealify(Mem *pStack){
+ if( pStack->flags & MEM_Str ){
+ pStack->r = sqliteAtoF(pStack->z, 0);
+ }else if( pStack->flags & MEM_Int ){
+ pStack->r = pStack->i;
+ }else{
+ pStack->r = 0.0;
+ }
+ pStack->flags |= MEM_Real;
+}
+
+/*
+** The parameters are pointers to the head of two sorted lists
+** of Sorter structures. Merge these two lists together and return
+** a single sorted list. This routine forms the core of the merge-sort
+** algorithm.
+**
+** In the case of a tie, left sorts in front of right.
+*/
+static Sorter *Merge(Sorter *pLeft, Sorter *pRight){
+ Sorter sHead;
+ Sorter *pTail;
+ pTail = &sHead;
+ pTail->pNext = 0;
+ while( pLeft && pRight ){
+ int c = sqliteSortCompare(pLeft->zKey, pRight->zKey);
+ if( c<=0 ){
+ pTail->pNext = pLeft;
+ pLeft = pLeft->pNext;
+ }else{
+ pTail->pNext = pRight;
+ pRight = pRight->pNext;
+ }
+ pTail = pTail->pNext;
+ }
+ if( pLeft ){
+ pTail->pNext = pLeft;
+ }else if( pRight ){
+ pTail->pNext = pRight;
+ }
+ return sHead.pNext;
+}
+
+/*
+** The following routine works like a tqreplacement for the standard
+** library routine fgets(). The difference is in how end-of-line (EOL)
+** is handled. Standard fgets() uses LF for EOL under unix, CRLF
+** under windows, and CR under mac. This routine accepts any of these
+** character sequences as an EOL mark. The EOL mark is tqreplaced by
+** a single LF character in zBuf.
+*/
+static char *vdbe_fgets(char *zBuf, int nBuf, FILE *in){
+ int i, c;
+ for(i=0; i<nBuf-1 && (c=getc(in))!=EOF; i++){
+ zBuf[i] = c;
+ if( c=='\r' || c=='\n' ){
+ if( c=='\r' ){
+ zBuf[i] = '\n';
+ c = getc(in);
+ if( c!=EOF && c!='\n' ) ungetc(c, in);
+ }
+ i++;
+ break;
+ }
+ }
+ zBuf[i] = 0;
+ return i>0 ? zBuf : 0;
+}
+
+/*
+** Make sure there is space in the Vdbe structure to hold at least
+** mxCursor cursors. If there is not currently enough space, then
+** allocate more.
+**
+** If a memory allocation error occurs, return 1. Return 0 if
+** everything works.
+*/
+static int expandCursorArraySize(Vdbe *p, int mxCursor){
+ if( mxCursor>=p->nCursor ){
+ Cursor *aCsr = sqliteRealloc( p->aCsr, (mxCursor+1)*sizeof(Cursor) );
+ if( aCsr==0 ) return 1;
+ p->aCsr = aCsr;
+ memset(&p->aCsr[p->nCursor], 0, sizeof(Cursor)*(mxCursor+1-p->nCursor));
+ p->nCursor = mxCursor+1;
+ }
+ return 0;
+}
+
+#ifdef VDBE_PROFILE
+/*
+** The following routine only works on pentium-class processors.
+** It uses the RDTSC opcode to read cycle count value out of the
+** processor and returns that value. This can be used for high-res
+** profiling.
+*/
+__inline__ unsigned long long int hwtime(void){
+ unsigned long long int x;
+ __asm__("rdtsc\n\t"
+ "mov %%edx, %%ecx\n\t"
+ :"=A" (x));
+ return x;
+}
+#endif
+
+/*
+** The CHECK_FOR_INTERRUPT macro defined here looks to see if the
+** sqlite_interrupt() routine has been called. If it has been, then
+** processing of the VDBE program is interrupted.
+**
+** This macro added to every instruction that does a jump in order to
+** implement a loop. This test used to be on every single instruction,
+** but that meant we more testing that we needed. By only testing the
+** flag on jump instructions, we get a (small) speed improvement.
+*/
+#define CHECK_FOR_INTERRUPT \
+ if( db->flags & STQLITE_Interrupt ) goto abort_due_to_interrupt;
+
+
+/*
+** Execute as much of a VDBE program as we can then return.
+**
+** sqliteVdbeMakeReady() must be called before this routine in order to
+** close the program with a final OP_Halt and to set up the callbacks
+** and the error message pointer.
+**
+** Whenever a row or result data is available, this routine will either
+** invoke the result callback (if there is one) or return with
+** STQLITE_ROW.
+**
+** If an attempt is made to open a locked database, then this routine
+** will either invoke the busy callback (if there is one) or it will
+** return STQLITE_BUSY.
+**
+** If an error occurs, an error message is written to memory obtained
+** from sqliteMalloc() and p->zErrMsg is made to point to that memory.
+** The error code is stored in p->rc and this routine returns STQLITE_ERROR.
+**
+** If the callback ever returns non-zero, then the program exits
+** immediately. There will be no error message but the p->rc field is
+** set to STQLITE_ABORT and this routine will return STQLITE_ERROR.
+**
+** A memory allocation error causes p->rc to be set to STQLITE_NOMEM and this
+** routine to return STQLITE_ERROR.
+**
+** Other fatal errors return STQLITE_ERROR.
+**
+** After this routine has finished, sqliteVdbeFinalize() should be
+** used to clean up the mess that was left behind.
+*/
+int sqliteVdbeExec(
+ Vdbe *p /* The VDBE */
+){
+ int pc; /* The program counter */
+ Op *pOp; /* Current operation */
+ int rc = STQLITE_OK; /* Value to return */
+ sqlite *db = p->db; /* The database */
+ Mem *pTos; /* Top entry in the operand stack */
+ char zBuf[100]; /* Space to sprintf() an integer */
+#ifdef VDBE_PROFILE
+ unsigned long long start; /* CPU clock count at start of opcode */
+ int origPc; /* Program counter at start of opcode */
+#endif
+#ifndef STQLITE_OMIT_PROGRESS_CALLBACK
+ int nProgressOps = 0; /* Opcodes executed since progress callback. */
+#endif
+
+ if( p->magic!=VDBE_MAGIC_RUN ) return STQLITE_MISUSE;
+ assert( db->magic==STQLITE_MAGIC_BUSY );
+ assert( p->rc==STQLITE_OK || p->rc==STQLITE_BUSY );
+ p->rc = STQLITE_OK;
+ assert( p->explain==0 );
+ if( sqlite_malloc_failed ) goto no_mem;
+ pTos = p->pTos;
+ if( p->popStack ){
+ popStack(&pTos, p->popStack);
+ p->popStack = 0;
+ }
+ CHECK_FOR_INTERRUPT;
+ for(pc=p->pc; rc==STQLITE_OK; pc++){
+ assert( pc>=0 && pc<p->nOp );
+ assert( pTos<=&p->aStack[pc] );
+#ifdef VDBE_PROFILE
+ origPc = pc;
+ start = hwtime();
+#endif
+ pOp = &p->aOp[pc];
+
+ /* Only allow tracing if NDEBUG is not defined.
+ */
+#ifndef NDEBUG
+ if( p->trace ){
+ sqliteVdbePrintOp(p->trace, pc, pOp);
+ }
+#endif
+
+ /* Check to see if we need to simulate an interrupt. This only happens
+ ** if we have a special test build.
+ */
+#ifdef STQLITE_TEST
+ if( sqlite_interrupt_count>0 ){
+ sqlite_interrupt_count--;
+ if( sqlite_interrupt_count==0 ){
+ sqlite_interrupt(db);
+ }
+ }
+#endif
+
+#ifndef STQLITE_OMIT_PROGRESS_CALLBACK
+ /* Call the progress callback if it is configured and the required number
+ ** of VDBE ops have been executed (either since this invocation of
+ ** sqliteVdbeExec() or since last time the progress callback was called).
+ ** If the progress callback returns non-zero, exit the virtual machine with
+ ** a return code STQLITE_ABORT.
+ */
+ if( db->xProgress ){
+ if( db->nProgressOps==nProgressOps ){
+ if( db->xProgress(db->pProgressArg)!=0 ){
+ rc = STQLITE_ABORT;
+ continue; /* skip to the next iteration of the for loop */
+ }
+ nProgressOps = 0;
+ }
+ nProgressOps++;
+ }
+#endif
+
+ switch( pOp->opcode ){
+
+/*****************************************************************************
+** What follows is a massive switch statement where each case implements a
+** separate instruction in the virtual machine. If we follow the usual
+** indentation conventions, each case should be indented by 6 spaces. But
+** that is a lot of wasted space on the left margin. So the code within
+** the switch statement will break with convention and be flush-left. Another
+** big comment (similar to this one) will mark the point in the code where
+** we transition back to normal indentation.
+**
+** The formatting of each case is important. The makefile for STQLite
+** generates two C files "opcodes.h" and "opcodes.c" by scanning this
+** file looking for lines that begin with "case OP_". The opcodes.h files
+** will be filled with #defines that give unique integer values to each
+** opcode and the opcodes.c file is filled with an array of strings where
+** each string is the symbolic name for the corresponding opcode.
+**
+** Documentation about VDBE opcodes is generated by scanning this file
+** for lines of that contain "Opcode:". That line and all subsequent
+** comment lines are used in the generation of the opcode.html documentation
+** file.
+**
+** SUMMARY:
+**
+** Formatting is important to scripts that scan this file.
+** Do not deviate from the formatting style currently in use.
+**
+*****************************************************************************/
+
+/* Opcode: Goto * P2 *
+**
+** An unconditional jump to address P2.
+** The next instruction executed will be
+** the one at index P2 from the beginning of
+** the program.
+*/
+case OP_Goto: {
+ CHECK_FOR_INTERRUPT;
+ pc = pOp->p2 - 1;
+ break;
+}
+
+/* Opcode: Gosub * P2 *
+**
+** Push the current address plus 1 onto the return address stack
+** and then jump to address P2.
+**
+** The return address stack is of limited depth. If too many
+** OP_Gosub operations occur without intervening OP_Returns, then
+** the return address stack will fill up and processing will abort
+** with a fatal error.
+*/
+case OP_Gosub: {
+ if( p->returnDepth>=sizeof(p->returnStack)/sizeof(p->returnStack[0]) ){
+ sqliteSetString(&p->zErrMsg, "return address stack overflow", (char*)0);
+ p->rc = STQLITE_INTERNAL;
+ return STQLITE_ERROR;
+ }
+ p->returnStack[p->returnDepth++] = pc+1;
+ pc = pOp->p2 - 1;
+ break;
+}
+
+/* Opcode: Return * * *
+**
+** Jump immediately to the next instruction after the last unreturned
+** OP_Gosub. If an OP_Return has occurred for all OP_Gosubs, then
+** processing aborts with a fatal error.
+*/
+case OP_Return: {
+ if( p->returnDepth<=0 ){
+ sqliteSetString(&p->zErrMsg, "return address stack underflow", (char*)0);
+ p->rc = STQLITE_INTERNAL;
+ return STQLITE_ERROR;
+ }
+ p->returnDepth--;
+ pc = p->returnStack[p->returnDepth] - 1;
+ break;
+}
+
+/* Opcode: Halt P1 P2 *
+**
+** Exit immediately. All open cursors, Lists, Sorts, etc are closed
+** automatically.
+**
+** P1 is the result code returned by sqlite_exec(). For a normal
+** halt, this should be STQLITE_OK (0). For errors, it can be some
+** other value. If P1!=0 then P2 will determine whether or not to
+** rollback the current transaction. Do not rollback if P2==OE_Fail.
+** Do the rollback if P2==OE_Rollback. If P2==OE_Abort, then back
+** out all changes that have occurred during this execution of the
+** VDBE, but do not rollback the transaction.
+**
+** There is an implied "Halt 0 0 0" instruction inserted at the very end of
+** every program. So a jump past the last instruction of the program
+** is the same as executing Halt.
+*/
+case OP_Halt: {
+ p->magic = VDBE_MAGIC_HALT;
+ p->pTos = pTos;
+ if( pOp->p1!=STQLITE_OK ){
+ p->rc = pOp->p1;
+ p->errorAction = pOp->p2;
+ if( pOp->p3 ){
+ sqliteSetString(&p->zErrMsg, pOp->p3, (char*)0);
+ }
+ return STQLITE_ERROR;
+ }else{
+ p->rc = STQLITE_OK;
+ return STQLITE_DONE;
+ }
+}
+
+/* Opcode: Integer P1 * P3
+**
+** The integer value P1 is pushed onto the stack. If P3 is not zero
+** then it is assumed to be a string representation of the same integer.
+*/
+case OP_Integer: {
+ pTos++;
+ pTos->i = pOp->p1;
+ pTos->flags = MEM_Int;
+ if( pOp->p3 ){
+ pTos->z = pOp->p3;
+ pTos->flags |= MEM_Str | MEM_Static;
+ pTos->n = strlen(pOp->p3)+1;
+ }
+ break;
+}
+
+/* Opcode: String * * P3
+**
+** The string value P3 is pushed onto the stack. If P3==0 then a
+** NULL is pushed onto the stack.
+*/
+case OP_String: {
+ char *z = pOp->p3;
+ pTos++;
+ if( z==0 ){
+ pTos->flags = MEM_Null;
+ }else{
+ pTos->z = z;
+ pTos->n = strlen(z) + 1;
+ pTos->flags = MEM_Str | MEM_Static;
+ }
+ break;
+}
+
+/* Opcode: Variable P1 * *
+**
+** Push the value of variable P1 onto the stack. A variable is
+** an unknown in the original SQL string as handed to sqlite_compile().
+** Any occurance of the '?' character in the original SQL is considered
+** a variable. Variables in the SQL string are number from left to
+** right beginning with 1. The values of variables are set using the
+** sqlite_bind() API.
+*/
+case OP_Variable: {
+ int j = pOp->p1 - 1;
+ pTos++;
+ if( j>=0 && j<p->nVar && p->azVar[j]!=0 ){
+ pTos->z = p->azVar[j];
+ pTos->n = p->anVar[j];
+ pTos->flags = MEM_Str | MEM_Static;
+ }else{
+ pTos->flags = MEM_Null;
+ }
+ break;
+}
+
+/* Opcode: Pop P1 * *
+**
+** P1 elements are popped off of the top of stack and discarded.
+*/
+case OP_Pop: {
+ assert( pOp->p1>=0 );
+ popStack(&pTos, pOp->p1);
+ assert( pTos>=&p->aStack[-1] );
+ break;
+}
+
+/* Opcode: Dup P1 P2 *
+**
+** A copy of the P1-th element of the stack
+** is made and pushed onto the top of the stack.
+** The top of the stack is element 0. So the
+** instruction "Dup 0 0 0" will make a copy of the
+** top of the stack.
+**
+** If the content of the P1-th element is a dynamically
+** allocated string, then a new copy of that string
+** is made if P2==0. If P2!=0, then just a pointer
+** to the string is copied.
+**
+** Also see the Pull instruction.
+*/
+case OP_Dup: {
+ Mem *pFrom = &pTos[-pOp->p1];
+ assert( pFrom<=pTos && pFrom>=p->aStack );
+ pTos++;
+ memcpy(pTos, pFrom, sizeof(*pFrom)-NBFS);
+ if( pTos->flags & MEM_Str ){
+ if( pOp->p2 && (pTos->flags & (MEM_Dyn|MEM_Ephem)) ){
+ pTos->flags &= ~MEM_Dyn;
+ pTos->flags |= MEM_Ephem;
+ }else if( pTos->flags & MEM_Short ){
+ memcpy(pTos->zShort, pFrom->zShort, pTos->n);
+ pTos->z = pTos->zShort;
+ }else if( (pTos->flags & MEM_Static)==0 ){
+ pTos->z = sqliteMallocRaw(pFrom->n);
+ if( sqlite_malloc_failed ) goto no_mem;
+ memcpy(pTos->z, pFrom->z, pFrom->n);
+ pTos->flags &= ~(MEM_Static|MEM_Ephem|MEM_Short);
+ pTos->flags |= MEM_Dyn;
+ }
+ }
+ break;
+}
+
+/* Opcode: Pull P1 * *
+**
+** The P1-th element is removed from its current location on
+** the stack and pushed back on top of the stack. The
+** top of the stack is element 0, so "Pull 0 0 0" is
+** a no-op. "Pull 1 0 0" swaps the top two elements of
+** the stack.
+**
+** See also the Dup instruction.
+*/
+case OP_Pull: {
+ Mem *pFrom = &pTos[-pOp->p1];
+ int i;
+ Mem ts;
+
+ ts = *pFrom;
+ Deephemeralize(pTos);
+ for(i=0; i<pOp->p1; i++, pFrom++){
+ Deephemeralize(&pFrom[1]);
+ *pFrom = pFrom[1];
+ assert( (pFrom->flags & MEM_Ephem)==0 );
+ if( pFrom->flags & MEM_Short ){
+ assert( pFrom->flags & MEM_Str );
+ assert( pFrom->z==pFrom[1].zShort );
+ pFrom->z = pFrom->zShort;
+ }
+ }
+ *pTos = ts;
+ if( pTos->flags & MEM_Short ){
+ assert( pTos->flags & MEM_Str );
+ assert( pTos->z==pTos[-pOp->p1].zShort );
+ pTos->z = pTos->zShort;
+ }
+ break;
+}
+
+/* Opcode: Push P1 * *
+**
+** Overwrite the value of the P1-th element down on the
+** stack (P1==0 is the top of the stack) with the value
+** of the top of the stack. Then pop the top of the stack.
+*/
+case OP_Push: {
+ Mem *pTo = &pTos[-pOp->p1];
+
+ assert( pTo>=p->aStack );
+ Deephemeralize(pTos);
+ Release(pTo);
+ *pTo = *pTos;
+ if( pTo->flags & MEM_Short ){
+ assert( pTo->z==pTos->zShort );
+ pTo->z = pTo->zShort;
+ }
+ pTos--;
+ break;
+}
+
+
+/* Opcode: ColumnName P1 P2 P3
+**
+** P3 becomes the P1-th column name (first is 0). An array of pointers
+** to all column names is passed as the 4th parameter to the callback.
+** If P2==1 then this is the last column in the result set and thus the
+** number of columns in the result set will be P1. There must be at least
+** one OP_ColumnName with a P2==1 before invoking OP_Callback and the
+** number of columns specified in OP_Callback must one more than the P1
+** value of the OP_ColumnName that has P2==1.
+*/
+case OP_ColumnName: {
+ assert( pOp->p1>=0 && pOp->p1<p->nOp );
+ p->azColName[pOp->p1] = pOp->p3;
+ p->nCallback = 0;
+ if( pOp->p2 ) p->nResColumn = pOp->p1+1;
+ break;
+}
+
+/* Opcode: Callback P1 * *
+**
+** Pop P1 values off the stack and form them into an array. Then
+** invoke the callback function using the newly formed array as the
+** 3rd parameter.
+*/
+case OP_Callback: {
+ int i;
+ char **azArgv = p->zArgv;
+ Mem *pCol;
+
+ pCol = &pTos[1-pOp->p1];
+ assert( pCol>=p->aStack );
+ for(i=0; i<pOp->p1; i++, pCol++){
+ if( pCol->flags & MEM_Null ){
+ azArgv[i] = 0;
+ }else{
+ Stringify(pCol);
+ azArgv[i] = pCol->z;
+ }
+ }
+ azArgv[i] = 0;
+ p->nCallback++;
+ p->azResColumn = azArgv;
+ assert( p->nResColumn==pOp->p1 );
+ p->popStack = pOp->p1;
+ p->pc = pc + 1;
+ p->pTos = pTos;
+ return STQLITE_ROW;
+}
+
+/* Opcode: Concat P1 P2 P3
+**
+** Look at the first P1 elements of the stack. Append them all
+** together with the lowest element first. Use P3 as a separator.
+** Put the result on the top of the stack. The original P1 elements
+** are popped from the stack if P2==0 and retained if P2==1. If
+** any element of the stack is NULL, then the result is NULL.
+**
+** If P3 is NULL, then use no separator. When P1==1, this routine
+** makes a copy of the top stack element into memory obtained
+** from sqliteMalloc().
+*/
+case OP_Concat: {
+ char *zNew;
+ int nByte;
+ int nField;
+ int i, j;
+ char *zSep;
+ int nSep;
+ Mem *pTerm;
+
+ nField = pOp->p1;
+ zSep = pOp->p3;
+ if( zSep==0 ) zSep = "";
+ nSep = strlen(zSep);
+ assert( &pTos[1-nField] >= p->aStack );
+ nByte = 1 - nSep;
+ pTerm = &pTos[1-nField];
+ for(i=0; i<nField; i++, pTerm++){
+ if( pTerm->flags & MEM_Null ){
+ nByte = -1;
+ break;
+ }else{
+ Stringify(pTerm);
+ nByte += pTerm->n - 1 + nSep;
+ }
+ }
+ if( nByte<0 ){
+ if( pOp->p2==0 ){
+ popStack(&pTos, nField);
+ }
+ pTos++;
+ pTos->flags = MEM_Null;
+ break;
+ }
+ zNew = sqliteMallocRaw( nByte );
+ if( zNew==0 ) goto no_mem;
+ j = 0;
+ pTerm = &pTos[1-nField];
+ for(i=j=0; i<nField; i++, pTerm++){
+ assert( pTerm->flags & MEM_Str );
+ memcpy(&zNew[j], pTerm->z, pTerm->n-1);
+ j += pTerm->n-1;
+ if( nSep>0 && i<nField-1 ){
+ memcpy(&zNew[j], zSep, nSep);
+ j += nSep;
+ }
+ }
+ zNew[j] = 0;
+ if( pOp->p2==0 ){
+ popStack(&pTos, nField);
+ }
+ pTos++;
+ pTos->n = nByte;
+ pTos->flags = MEM_Str|MEM_Dyn;
+ pTos->z = zNew;
+ break;
+}
+
+/* Opcode: Add * * *
+**
+** Pop the top two elements from the stack, add them together,
+** and push the result back onto the stack. If either element
+** is a string then it is converted to a double using the atof()
+** function before the addition.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: Multiply * * *
+**
+** Pop the top two elements from the stack, multiply them together,
+** and push the result back onto the stack. If either element
+** is a string then it is converted to a double using the atof()
+** function before the multiplication.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: Subtract * * *
+**
+** Pop the top two elements from the stack, subtract the
+** first (what was on top of the stack) from the second (the
+** next on stack)
+** and push the result back onto the stack. If either element
+** is a string then it is converted to a double using the atof()
+** function before the subtraction.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: Divide * * *
+**
+** Pop the top two elements from the stack, divide the
+** first (what was on top of the stack) from the second (the
+** next on stack)
+** and push the result back onto the stack. If either element
+** is a string then it is converted to a double using the atof()
+** function before the division. Division by zero returns NULL.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: Remainder * * *
+**
+** Pop the top two elements from the stack, divide the
+** first (what was on top of the stack) from the second (the
+** next on stack)
+** and push the remainder after division onto the stack. If either element
+** is a string then it is converted to a double using the atof()
+** function before the division. Division by zero returns NULL.
+** If either operand is NULL, the result is NULL.
+*/
+case OP_Add:
+case OP_Subtract:
+case OP_Multiply:
+case OP_Divide:
+case OP_Remainder: {
+ Mem *pNos = &pTos[-1];
+ assert( pNos>=p->aStack );
+ if( ((pTos->flags | pNos->flags) & MEM_Null)!=0 ){
+ Release(pTos);
+ pTos--;
+ Release(pTos);
+ pTos->flags = MEM_Null;
+ }else if( (pTos->flags & pNos->flags & MEM_Int)==MEM_Int ){
+ int a, b;
+ a = pTos->i;
+ b = pNos->i;
+ switch( pOp->opcode ){
+ case OP_Add: b += a; break;
+ case OP_Subtract: b -= a; break;
+ case OP_Multiply: b *= a; break;
+ case OP_Divide: {
+ if( a==0 ) goto divide_by_zero;
+ b /= a;
+ break;
+ }
+ default: {
+ if( a==0 ) goto divide_by_zero;
+ b %= a;
+ break;
+ }
+ }
+ Release(pTos);
+ pTos--;
+ Release(pTos);
+ pTos->i = b;
+ pTos->flags = MEM_Int;
+ }else{
+ double a, b;
+ Realify(pTos);
+ Realify(pNos);
+ a = pTos->r;
+ b = pNos->r;
+ switch( pOp->opcode ){
+ case OP_Add: b += a; break;
+ case OP_Subtract: b -= a; break;
+ case OP_Multiply: b *= a; break;
+ case OP_Divide: {
+ if( a==0.0 ) goto divide_by_zero;
+ b /= a;
+ break;
+ }
+ default: {
+ int ia = (int)a;
+ int ib = (int)b;
+ if( ia==0.0 ) goto divide_by_zero;
+ b = ib % ia;
+ break;
+ }
+ }
+ Release(pTos);
+ pTos--;
+ Release(pTos);
+ pTos->r = b;
+ pTos->flags = MEM_Real;
+ }
+ break;
+
+divide_by_zero:
+ Release(pTos);
+ pTos--;
+ Release(pTos);
+ pTos->flags = MEM_Null;
+ break;
+}
+
+/* Opcode: Function P1 * P3
+**
+** Invoke a user function (P3 is a pointer to a Function structure that
+** defines the function) with P1 string arguments taken from the stack.
+** Pop all arguments from the stack and push back the result.
+**
+** See also: AggFunc
+*/
+case OP_Function: {
+ int n, i;
+ Mem *pArg;
+ char **azArgv;
+ sqlite_func ctx;
+
+ n = pOp->p1;
+ pArg = &pTos[1-n];
+ azArgv = p->zArgv;
+ for(i=0; i<n; i++, pArg++){
+ if( pArg->flags & MEM_Null ){
+ azArgv[i] = 0;
+ }else{
+ Stringify(pArg);
+ azArgv[i] = pArg->z;
+ }
+ }
+ ctx.pFunc = (FuncDef*)pOp->p3;
+ ctx.s.flags = MEM_Null;
+ ctx.s.z = 0;
+ ctx.isError = 0;
+ ctx.isStep = 0;
+ if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
+ (*ctx.pFunc->xFunc)(&ctx, n, (const char**)azArgv);
+ if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
+ popStack(&pTos, n);
+ pTos++;
+ *pTos = ctx.s;
+ if( pTos->flags & MEM_Short ){
+ pTos->z = pTos->zShort;
+ }
+ if( ctx.isError ){
+ sqliteSetString(&p->zErrMsg,
+ (pTos->flags & MEM_Str)!=0 ? pTos->z : "user function error", (char*)0);
+ rc = STQLITE_ERROR;
+ }
+ break;
+}
+
+/* Opcode: BitAnd * * *
+**
+** Pop the top two elements from the stack. Convert both elements
+** to integers. Push back onto the stack the bit-wise AND of the
+** two elements.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: BitOr * * *
+**
+** Pop the top two elements from the stack. Convert both elements
+** to integers. Push back onto the stack the bit-wise OR of the
+** two elements.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: ShiftLeft * * *
+**
+** Pop the top two elements from the stack. Convert both elements
+** to integers. Push back onto the stack the top element shifted
+** left by N bits where N is the second element on the stack.
+** If either operand is NULL, the result is NULL.
+*/
+/* Opcode: ShiftRight * * *
+**
+** Pop the top two elements from the stack. Convert both elements
+** to integers. Push back onto the stack the top element shifted
+** right by N bits where N is the second element on the stack.
+** If either operand is NULL, the result is NULL.
+*/
+case OP_BitAnd:
+case OP_BitOr:
+case OP_ShiftLeft:
+case OP_ShiftRight: {
+ Mem *pNos = &pTos[-1];
+ int a, b;
+
+ assert( pNos>=p->aStack );
+ if( (pTos->flags | pNos->flags) & MEM_Null ){
+ popStack(&pTos, 2);
+ pTos++;
+ pTos->flags = MEM_Null;
+ break;
+ }
+ Integerify(pTos);
+ Integerify(pNos);
+ a = pTos->i;
+ b = pNos->i;
+ switch( pOp->opcode ){
+ case OP_BitAnd: a &= b; break;
+ case OP_BitOr: a |= b; break;
+ case OP_ShiftLeft: a <<= b; break;
+ case OP_ShiftRight: a >>= b; break;
+ default: /* CANT HAPPEN */ break;
+ }
+ assert( (pTos->flags & MEM_Dyn)==0 );
+ assert( (pNos->flags & MEM_Dyn)==0 );
+ pTos--;
+ Release(pTos);
+ pTos->i = a;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: AddImm P1 * *
+**
+** Add the value P1 to whatever is on top of the stack. The result
+** is always an integer.
+**
+** To force the top of the stack to be an integer, just add 0.
+*/
+case OP_AddImm: {
+ assert( pTos>=p->aStack );
+ Integerify(pTos);
+ pTos->i += pOp->p1;
+ break;
+}
+
+/* Opcode: ForceInt P1 P2 *
+**
+** Convert the top of the stack into an integer. If the current top of
+** the stack is not numeric (meaning that is is a NULL or a string that
+** does not look like an integer or floating point number) then pop the
+** stack and jump to P2. If the top of the stack is numeric then
+** convert it into the least integer that is greater than or equal to its
+** current value if P1==0, or to the least integer that is strictly
+** greater than its current value if P1==1.
+*/
+case OP_ForceInt: {
+ int v;
+ assert( pTos>=p->aStack );
+ if( (pTos->flags & (MEM_Int|MEM_Real))==0
+ && ((pTos->flags & MEM_Str)==0 || sqliteIsNumber(pTos->z)==0) ){
+ Release(pTos);
+ pTos--;
+ pc = pOp->p2 - 1;
+ break;
+ }
+ if( pTos->flags & MEM_Int ){
+ v = pTos->i + (pOp->p1!=0);
+ }else{
+ Realify(pTos);
+ v = (int)pTos->r;
+ if( pTos->r>(double)v ) v++;
+ if( pOp->p1 && pTos->r==(double)v ) v++;
+ }
+ Release(pTos);
+ pTos->i = v;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: MustBeInt P1 P2 *
+**
+** Force the top of the stack to be an integer. If the top of the
+** stack is not an integer and cannot be converted into an integer
+** with out data loss, then jump immediately to P2, or if P2==0
+** raise an STQLITE_MISMATCH exception.
+**
+** If the top of the stack is not an integer and P2 is not zero and
+** P1 is 1, then the stack is popped. In all other cases, the depth
+** of the stack is unchanged.
+*/
+case OP_MustBeInt: {
+ assert( pTos>=p->aStack );
+ if( pTos->flags & MEM_Int ){
+ /* Do nothing */
+ }else if( pTos->flags & MEM_Real ){
+ int i = (int)pTos->r;
+ double r = (double)i;
+ if( r!=pTos->r ){
+ goto mismatch;
+ }
+ pTos->i = i;
+ }else if( pTos->flags & MEM_Str ){
+ int v;
+ if( !toInt(pTos->z, &v) ){
+ double r;
+ if( !sqliteIsNumber(pTos->z) ){
+ goto mismatch;
+ }
+ Realify(pTos);
+ v = (int)pTos->r;
+ r = (double)v;
+ if( r!=pTos->r ){
+ goto mismatch;
+ }
+ }
+ pTos->i = v;
+ }else{
+ goto mismatch;
+ }
+ Release(pTos);
+ pTos->flags = MEM_Int;
+ break;
+
+mismatch:
+ if( pOp->p2==0 ){
+ rc = STQLITE_MISMATCH;
+ goto abort_due_to_error;
+ }else{
+ if( pOp->p1 ) popStack(&pTos, 1);
+ pc = pOp->p2 - 1;
+ }
+ break;
+}
+
+/* Opcode: Eq P1 P2 *
+**
+** Pop the top two elements from the stack. If they are equal, then
+** jump to instruction P2. Otherwise, continue to the next instruction.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** If both values are numeric, they are converted to doubles using atof()
+** and compared for equality that way. Otherwise the strcmp() library
+** routine is used for the comparison. For a pure text comparison
+** use OP_StrEq.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+/* Opcode: Ne P1 P2 *
+**
+** Pop the top two elements from the stack. If they are not equal, then
+** jump to instruction P2. Otherwise, continue to the next instruction.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** If both values are numeric, they are converted to doubles using atof()
+** and compared in that format. Otherwise the strcmp() library
+** routine is used for the comparison. For a pure text comparison
+** use OP_StrNe.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+/* Opcode: Lt P1 P2 *
+**
+** Pop the top two elements from the stack. If second element (the
+** next on stack) is less than the first (the top of stack), then
+** jump to instruction P2. Otherwise, continue to the next instruction.
+** In other words, jump if NOS<TOS.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** If both values are numeric, they are converted to doubles using atof()
+** and compared in that format. Numeric values are always less than
+** non-numeric values. If both operands are non-numeric, the strcmp() library
+** routine is used for the comparison. For a pure text comparison
+** use OP_StrLt.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+/* Opcode: Le P1 P2 *
+**
+** Pop the top two elements from the stack. If second element (the
+** next on stack) is less than or equal to the first (the top of stack),
+** then jump to instruction P2. In other words, jump if NOS<=TOS.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** If both values are numeric, they are converted to doubles using atof()
+** and compared in that format. Numeric values are always less than
+** non-numeric values. If both operands are non-numeric, the strcmp() library
+** routine is used for the comparison. For a pure text comparison
+** use OP_StrLe.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+/* Opcode: Gt P1 P2 *
+**
+** Pop the top two elements from the stack. If second element (the
+** next on stack) is greater than the first (the top of stack),
+** then jump to instruction P2. In other words, jump if NOS>TOS.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** If both values are numeric, they are converted to doubles using atof()
+** and compared in that format. Numeric values are always less than
+** non-numeric values. If both operands are non-numeric, the strcmp() library
+** routine is used for the comparison. For a pure text comparison
+** use OP_StrGt.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+/* Opcode: Ge P1 P2 *
+**
+** Pop the top two elements from the stack. If second element (the next
+** on stack) is greater than or equal to the first (the top of stack),
+** then jump to instruction P2. In other words, jump if NOS>=TOS.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** If both values are numeric, they are converted to doubles using atof()
+** and compared in that format. Numeric values are always less than
+** non-numeric values. If both operands are non-numeric, the strcmp() library
+** routine is used for the comparison. For a pure text comparison
+** use OP_StrGe.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+case OP_Eq:
+case OP_Ne:
+case OP_Lt:
+case OP_Le:
+case OP_Gt:
+case OP_Ge: {
+ Mem *pNos = &pTos[-1];
+ int c, v;
+ int ft, fn;
+ assert( pNos>=p->aStack );
+ ft = pTos->flags;
+ fn = pNos->flags;
+ if( (ft | fn) & MEM_Null ){
+ popStack(&pTos, 2);
+ if( pOp->p2 ){
+ if( pOp->p1 ) pc = pOp->p2-1;
+ }else{
+ pTos++;
+ pTos->flags = MEM_Null;
+ }
+ break;
+ }else if( (ft & fn & MEM_Int)==MEM_Int ){
+ c = pNos->i - pTos->i;
+ }else if( (ft & MEM_Int)!=0 && (fn & MEM_Str)!=0 && toInt(pNos->z,&v) ){
+ c = v - pTos->i;
+ }else if( (fn & MEM_Int)!=0 && (ft & MEM_Str)!=0 && toInt(pTos->z,&v) ){
+ c = pNos->i - v;
+ }else{
+ Stringify(pTos);
+ Stringify(pNos);
+ c = sqliteCompare(pNos->z, pTos->z);
+ }
+ switch( pOp->opcode ){
+ case OP_Eq: c = c==0; break;
+ case OP_Ne: c = c!=0; break;
+ case OP_Lt: c = c<0; break;
+ case OP_Le: c = c<=0; break;
+ case OP_Gt: c = c>0; break;
+ default: c = c>=0; break;
+ }
+ popStack(&pTos, 2);
+ if( pOp->p2 ){
+ if( c ) pc = pOp->p2-1;
+ }else{
+ pTos++;
+ pTos->i = c;
+ pTos->flags = MEM_Int;
+ }
+ break;
+}
+/* INSERT NO CODE HERE!
+**
+** The opcode numbers are extracted from this source file by doing
+**
+** grep '^case OP_' vdbe.c | ... >opcodes.h
+**
+** The opcodes are numbered in the order that they appear in this file.
+** But in order for the expression generating code to work right, the
+** string comparison operators that follow must be numbered exactly 6
+** greater than the numeric comparison opcodes above. So no other
+** cases can appear between the two.
+*/
+/* Opcode: StrEq P1 P2 *
+**
+** Pop the top two elements from the stack. If they are equal, then
+** jump to instruction P2. Otherwise, continue to the next instruction.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** The strcmp() library routine is used for the comparison. For a
+** numeric comparison, use OP_Eq.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+/* Opcode: StrNe P1 P2 *
+**
+** Pop the top two elements from the stack. If they are not equal, then
+** jump to instruction P2. Otherwise, continue to the next instruction.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** The strcmp() library routine is used for the comparison. For a
+** numeric comparison, use OP_Ne.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+/* Opcode: StrLt P1 P2 *
+**
+** Pop the top two elements from the stack. If second element (the
+** next on stack) is less than the first (the top of stack), then
+** jump to instruction P2. Otherwise, continue to the next instruction.
+** In other words, jump if NOS<TOS.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** The strcmp() library routine is used for the comparison. For a
+** numeric comparison, use OP_Lt.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+/* Opcode: StrLe P1 P2 *
+**
+** Pop the top two elements from the stack. If second element (the
+** next on stack) is less than or equal to the first (the top of stack),
+** then jump to instruction P2. In other words, jump if NOS<=TOS.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** The strcmp() library routine is used for the comparison. For a
+** numeric comparison, use OP_Le.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+/* Opcode: StrGt P1 P2 *
+**
+** Pop the top two elements from the stack. If second element (the
+** next on stack) is greater than the first (the top of stack),
+** then jump to instruction P2. In other words, jump if NOS>TOS.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** The strcmp() library routine is used for the comparison. For a
+** numeric comparison, use OP_Gt.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+/* Opcode: StrGe P1 P2 *
+**
+** Pop the top two elements from the stack. If second element (the next
+** on stack) is greater than or equal to the first (the top of stack),
+** then jump to instruction P2. In other words, jump if NOS>=TOS.
+**
+** If either operand is NULL (and thus if the result is unknown) then
+** take the jump if P1 is true.
+**
+** The strcmp() library routine is used for the comparison. For a
+** numeric comparison, use OP_Ge.
+**
+** If P2 is zero, do not jump. Instead, push an integer 1 onto the
+** stack if the jump would have been taken, or a 0 if not. Push a
+** NULL if either operand was NULL.
+*/
+case OP_StrEq:
+case OP_StrNe:
+case OP_StrLt:
+case OP_StrLe:
+case OP_StrGt:
+case OP_StrGe: {
+ Mem *pNos = &pTos[-1];
+ int c;
+ assert( pNos>=p->aStack );
+ if( (pNos->flags | pTos->flags) & MEM_Null ){
+ popStack(&pTos, 2);
+ if( pOp->p2 ){
+ if( pOp->p1 ) pc = pOp->p2-1;
+ }else{
+ pTos++;
+ pTos->flags = MEM_Null;
+ }
+ break;
+ }else{
+ Stringify(pTos);
+ Stringify(pNos);
+ c = strcmp(pNos->z, pTos->z);
+ }
+ /* The asserts on each case of the following switch are there to verify
+ ** that string comparison opcodes are always exactly 6 greater than the
+ ** corresponding numeric comparison opcodes. The code generator depends
+ ** on this fact.
+ */
+ switch( pOp->opcode ){
+ case OP_StrEq: c = c==0; assert( pOp->opcode-6==OP_Eq ); break;
+ case OP_StrNe: c = c!=0; assert( pOp->opcode-6==OP_Ne ); break;
+ case OP_StrLt: c = c<0; assert( pOp->opcode-6==OP_Lt ); break;
+ case OP_StrLe: c = c<=0; assert( pOp->opcode-6==OP_Le ); break;
+ case OP_StrGt: c = c>0; assert( pOp->opcode-6==OP_Gt ); break;
+ default: c = c>=0; assert( pOp->opcode-6==OP_Ge ); break;
+ }
+ popStack(&pTos, 2);
+ if( pOp->p2 ){
+ if( c ) pc = pOp->p2-1;
+ }else{
+ pTos++;
+ pTos->flags = MEM_Int;
+ pTos->i = c;
+ }
+ break;
+}
+
+/* Opcode: And * * *
+**
+** Pop two values off the stack. Take the logical AND of the
+** two values and push the resulting boolean value back onto the
+** stack.
+*/
+/* Opcode: Or * * *
+**
+** Pop two values off the stack. Take the logical OR of the
+** two values and push the resulting boolean value back onto the
+** stack.
+*/
+case OP_And:
+case OP_Or: {
+ Mem *pNos = &pTos[-1];
+ int v1, v2; /* 0==TRUE, 1==FALSE, 2==UNKNOWN or NULL */
+
+ assert( pNos>=p->aStack );
+ if( pTos->flags & MEM_Null ){
+ v1 = 2;
+ }else{
+ Integerify(pTos);
+ v1 = pTos->i==0;
+ }
+ if( pNos->flags & MEM_Null ){
+ v2 = 2;
+ }else{
+ Integerify(pNos);
+ v2 = pNos->i==0;
+ }
+ if( pOp->opcode==OP_And ){
+ static const unsigned char and_logic[] = { 0, 1, 2, 1, 1, 1, 2, 1, 2 };
+ v1 = and_logic[v1*3+v2];
+ }else{
+ static const unsigned char or_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 };
+ v1 = or_logic[v1*3+v2];
+ }
+ popStack(&pTos, 2);
+ pTos++;
+ if( v1==2 ){
+ pTos->flags = MEM_Null;
+ }else{
+ pTos->i = v1==0;
+ pTos->flags = MEM_Int;
+ }
+ break;
+}
+
+/* Opcode: Negative * * *
+**
+** Treat the top of the stack as a numeric quantity. Replace it
+** with its additive inverse. If the top of the stack is NULL
+** its value is unchanged.
+*/
+/* Opcode: AbsValue * * *
+**
+** Treat the top of the stack as a numeric quantity. Replace it
+** with its absolute value. If the top of the stack is NULL
+** its value is unchanged.
+*/
+case OP_Negative:
+case OP_AbsValue: {
+ assert( pTos>=p->aStack );
+ if( pTos->flags & MEM_Real ){
+ Release(pTos);
+ if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
+ pTos->r = -pTos->r;
+ }
+ pTos->flags = MEM_Real;
+ }else if( pTos->flags & MEM_Int ){
+ Release(pTos);
+ if( pOp->opcode==OP_Negative || pTos->i<0 ){
+ pTos->i = -pTos->i;
+ }
+ pTos->flags = MEM_Int;
+ }else if( pTos->flags & MEM_Null ){
+ /* Do nothing */
+ }else{
+ Realify(pTos);
+ Release(pTos);
+ if( pOp->opcode==OP_Negative || pTos->r<0.0 ){
+ pTos->r = -pTos->r;
+ }
+ pTos->flags = MEM_Real;
+ }
+ break;
+}
+
+/* Opcode: Not * * *
+**
+** Interpret the top of the stack as a boolean value. Replace it
+** with its complement. If the top of the stack is NULL its value
+** is unchanged.
+*/
+case OP_Not: {
+ assert( pTos>=p->aStack );
+ if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */
+ Integerify(pTos);
+ Release(pTos);
+ pTos->i = !pTos->i;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: BitNot * * *
+**
+** Interpret the top of the stack as an value. Replace it
+** with its ones-complement. If the top of the stack is NULL its
+** value is unchanged.
+*/
+case OP_BitNot: {
+ assert( pTos>=p->aStack );
+ if( pTos->flags & MEM_Null ) break; /* Do nothing to NULLs */
+ Integerify(pTos);
+ Release(pTos);
+ pTos->i = ~pTos->i;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: Noop * * *
+**
+** Do nothing. This instruction is often useful as a jump
+** destination.
+*/
+case OP_Noop: {
+ break;
+}
+
+/* Opcode: If P1 P2 *
+**
+** Pop a single boolean from the stack. If the boolean popped is
+** true, then jump to p2. Otherwise continue to the next instruction.
+** An integer is false if zero and true otherwise. A string is
+** false if it has zero length and true otherwise.
+**
+** If the value popped of the stack is NULL, then take the jump if P1
+** is true and fall through if P1 is false.
+*/
+/* Opcode: IfNot P1 P2 *
+**
+** Pop a single boolean from the stack. If the boolean popped is
+** false, then jump to p2. Otherwise continue to the next instruction.
+** An integer is false if zero and true otherwise. A string is
+** false if it has zero length and true otherwise.
+**
+** If the value popped of the stack is NULL, then take the jump if P1
+** is true and fall through if P1 is false.
+*/
+case OP_If:
+case OP_IfNot: {
+ int c;
+ assert( pTos>=p->aStack );
+ if( pTos->flags & MEM_Null ){
+ c = pOp->p1;
+ }else{
+ Integerify(pTos);
+ c = pTos->i;
+ if( pOp->opcode==OP_IfNot ) c = !c;
+ }
+ assert( (pTos->flags & MEM_Dyn)==0 );
+ pTos--;
+ if( c ) pc = pOp->p2-1;
+ break;
+}
+
+/* Opcode: IsNull P1 P2 *
+**
+** If any of the top abs(P1) values on the stack are NULL, then jump
+** to P2. Pop the stack P1 times if P1>0. If P1<0 leave the stack
+** unchanged.
+*/
+case OP_IsNull: {
+ int i, cnt;
+ Mem *pTerm;
+ cnt = pOp->p1;
+ if( cnt<0 ) cnt = -cnt;
+ pTerm = &pTos[1-cnt];
+ assert( pTerm>=p->aStack );
+ for(i=0; i<cnt; i++, pTerm++){
+ if( pTerm->flags & MEM_Null ){
+ pc = pOp->p2-1;
+ break;
+ }
+ }
+ if( pOp->p1>0 ) popStack(&pTos, cnt);
+ break;
+}
+
+/* Opcode: NotNull P1 P2 *
+**
+** Jump to P2 if the top P1 values on the stack are all not NULL. Pop the
+** stack if P1 times if P1 is greater than zero. If P1 is less than
+** zero then leave the stack unchanged.
+*/
+case OP_NotNull: {
+ int i, cnt;
+ cnt = pOp->p1;
+ if( cnt<0 ) cnt = -cnt;
+ assert( &pTos[1-cnt] >= p->aStack );
+ for(i=0; i<cnt && (pTos[1+i-cnt].flags & MEM_Null)==0; i++){}
+ if( i>=cnt ) pc = pOp->p2-1;
+ if( pOp->p1>0 ) popStack(&pTos, cnt);
+ break;
+}
+
+/* Opcode: MakeRecord P1 P2 *
+**
+** Convert the top P1 entries of the stack into a single entry
+** suitable for use as a data record in a database table. The
+** details of the format are irrelavant as long as the OP_Column
+** opcode can decode the record later. Refer to source code
+** comments for the details of the record format.
+**
+** If P2 is true (non-zero) and one or more of the P1 entries
+** that go into building the record is NULL, then add some extra
+** bytes to the record to make it distinct for other entries created
+** during the same run of the VDBE. The extra bytes added are a
+** counter that is reset with each run of the VDBE, so records
+** created this way will not necessarily be distinct across runs.
+** But they should be distinct for transient tables (created using
+** OP_OpenTemp) which is what they are intended for.
+**
+** (Later:) The P2==1 option was intended to make NULLs distinct
+** for the UNION operator. But I have since discovered that NULLs
+** are indistinct for UNION. So this option is never used.
+*/
+case OP_MakeRecord: {
+ char *zNewRecord;
+ int nByte;
+ int nField;
+ int i, j;
+ int idxWidth;
+ u32 addr;
+ Mem *pRec;
+ int addUnique = 0; /* True to cause bytes to be added to make the
+ ** generated record distinct */
+ char zTemp[NBFS]; /* Temp space for small records */
+
+ /* Assuming the record tqcontains N fields, the record format looks
+ ** like this:
+ **
+ ** -------------------------------------------------------------------
+ ** | idx0 | idx1 | ... | idx(N-1) | idx(N) | data0 | ... | data(N-1) |
+ ** -------------------------------------------------------------------
+ **
+ ** All data fields are converted to strings before being stored and
+ ** are stored with their null terminators. NULL entries omit the
+ ** null terminator. Thus an empty string uses 1 byte and a NULL uses
+ ** zero bytes. Data(0) is taken from the lowest element of the stack
+ ** and data(N-1) is the top of the stack.
+ **
+ ** Each of the idx() entries is either 1, 2, or 3 bytes depending on
+ ** how big the total record is. Idx(0) tqcontains the offset to the start
+ ** of data(0). Idx(k) tqcontains the offset to the start of data(k).
+ ** Idx(N) tqcontains the total number of bytes in the record.
+ */
+ nField = pOp->p1;
+ pRec = &pTos[1-nField];
+ assert( pRec>=p->aStack );
+ nByte = 0;
+ for(i=0; i<nField; i++, pRec++){
+ if( pRec->flags & MEM_Null ){
+ addUnique = pOp->p2;
+ }else{
+ Stringify(pRec);
+ nByte += pRec->n;
+ }
+ }
+ if( addUnique ) nByte += sizeof(p->uniqueCnt);
+ if( nByte + nField + 1 < 256 ){
+ idxWidth = 1;
+ }else if( nByte + 2*nField + 2 < 65536 ){
+ idxWidth = 2;
+ }else{
+ idxWidth = 3;
+ }
+ nByte += idxWidth*(nField + 1);
+ if( nByte>MAX_BYTES_PER_ROW ){
+ rc = STQLITE_TOOBIG;
+ goto abort_due_to_error;
+ }
+ if( nByte<=NBFS ){
+ zNewRecord = zTemp;
+ }else{
+ zNewRecord = sqliteMallocRaw( nByte );
+ if( zNewRecord==0 ) goto no_mem;
+ }
+ j = 0;
+ addr = idxWidth*(nField+1) + addUnique*sizeof(p->uniqueCnt);
+ for(i=0, pRec=&pTos[1-nField]; i<nField; i++, pRec++){
+ zNewRecord[j++] = addr & 0xff;
+ if( idxWidth>1 ){
+ zNewRecord[j++] = (addr>>8)&0xff;
+ if( idxWidth>2 ){
+ zNewRecord[j++] = (addr>>16)&0xff;
+ }
+ }
+ if( (pRec->flags & MEM_Null)==0 ){
+ addr += pRec->n;
+ }
+ }
+ zNewRecord[j++] = addr & 0xff;
+ if( idxWidth>1 ){
+ zNewRecord[j++] = (addr>>8)&0xff;
+ if( idxWidth>2 ){
+ zNewRecord[j++] = (addr>>16)&0xff;
+ }
+ }
+ if( addUnique ){
+ memcpy(&zNewRecord[j], &p->uniqueCnt, sizeof(p->uniqueCnt));
+ p->uniqueCnt++;
+ j += sizeof(p->uniqueCnt);
+ }
+ for(i=0, pRec=&pTos[1-nField]; i<nField; i++, pRec++){
+ if( (pRec->flags & MEM_Null)==0 ){
+ memcpy(&zNewRecord[j], pRec->z, pRec->n);
+ j += pRec->n;
+ }
+ }
+ popStack(&pTos, nField);
+ pTos++;
+ pTos->n = nByte;
+ if( nByte<=NBFS ){
+ assert( zNewRecord==zTemp );
+ memcpy(pTos->zShort, zTemp, nByte);
+ pTos->z = pTos->zShort;
+ pTos->flags = MEM_Str | MEM_Short;
+ }else{
+ assert( zNewRecord!=zTemp );
+ pTos->z = zNewRecord;
+ pTos->flags = MEM_Str | MEM_Dyn;
+ }
+ break;
+}
+
+/* Opcode: MakeKey P1 P2 P3
+**
+** Convert the top P1 entries of the stack into a single entry suitable
+** for use as the key in an index. The top P1 records are
+** converted to strings and merged. The null-terminators
+** are retained and used as separators.
+** The lowest entry in the stack is the first field and the top of the
+** stack becomes the last.
+**
+** If P2 is not zero, then the original entries remain on the stack
+** and the new key is pushed on top. If P2 is zero, the original
+** data is popped off the stack first then the new key is pushed
+** back in its place.
+**
+** P3 is a string that is P1 characters long. Each character is either
+** an 'n' or a 't' to indicates if the argument should be intepreted as
+** numeric or text type. The first character of P3 corresponds to the
+** lowest element on the stack. If P3 is NULL then all arguments are
+** assumed to be of the numeric type.
+**
+** The type makes a difference in that text-type fields may not be
+** introduced by 'b' (as described in the next paragraph). The
+** first character of a text-type field must be either 'a' (if it is NULL)
+** or 'c'. Numeric fields will be introduced by 'b' if their content
+** looks like a well-formed number. Otherwise the 'a' or 'c' will be
+** used.
+**
+** The key is a concatenation of fields. Each field is terminated by
+** a single 0x00 character. A NULL field is introduced by an 'a' and
+** is followed immediately by its 0x00 terminator. A numeric field is
+** introduced by a single character 'b' and is followed by a sequence
+** of characters that represent the number such that a comparison of
+** the character string using memcpy() sorts the numbers in numerical
+** order. The character strings for numbers are generated using the
+** sqliteRealToSortable() function. A text field is introduced by a
+** 'c' character and is followed by the exact text of the field. The
+** use of an 'a', 'b', or 'c' character at the beginning of each field
+** guarantees that NULLs sort before numbers and that numbers sort
+** before text. 0x00 characters do not occur except as separators
+** between fields.
+**
+** See also: MakeIdxKey, SortMakeKey
+*/
+/* Opcode: MakeIdxKey P1 P2 P3
+**
+** Convert the top P1 entries of the stack into a single entry suitable
+** for use as the key in an index. In addition, take one additional integer
+** off of the stack, treat that integer as a four-byte record number, and
+** append the four bytes to the key. Thus a total of P1+1 entries are
+** popped from the stack for this instruction and a single entry is pushed
+** back. The first P1 entries that are popped are strings and the last
+** entry (the lowest on the stack) is an integer record number.
+**
+** The converstion of the first P1 string entries occurs just like in
+** MakeKey. Each entry is separated from the others by a null.
+** The entire concatenation is null-terminated. The lowest entry
+** in the stack is the first field and the top of the stack becomes the
+** last.
+**
+** If P2 is not zero and one or more of the P1 entries that go into the
+** generated key is NULL, then jump to P2 after the new key has been
+** pushed on the stack. In other words, jump to P2 if the key is
+** guaranteed to be unique. This jump can be used to skip a subsequent
+** uniqueness test.
+**
+** P3 is a string that is P1 characters long. Each character is either
+** an 'n' or a 't' to indicates if the argument should be numeric or
+** text. The first character corresponds to the lowest element on the
+** stack. If P3 is null then all arguments are assumed to be numeric.
+**
+** See also: MakeKey, SortMakeKey
+*/
+case OP_MakeIdxKey:
+case OP_MakeKey: {
+ char *zNewKey;
+ int nByte;
+ int nField;
+ int addRowid;
+ int i, j;
+ int tqcontainsNull = 0;
+ Mem *pRec;
+ char zTemp[NBFS];
+
+ addRowid = pOp->opcode==OP_MakeIdxKey;
+ nField = pOp->p1;
+ pRec = &pTos[1-nField];
+ assert( pRec>=p->aStack );
+ nByte = 0;
+ for(j=0, i=0; i<nField; i++, j++, pRec++){
+ int flags = pRec->flags;
+ int len;
+ char *z;
+ if( flags & MEM_Null ){
+ nByte += 2;
+ tqcontainsNull = 1;
+ }else if( pOp->p3 && pOp->p3[j]=='t' ){
+ Stringify(pRec);
+ pRec->flags &= ~(MEM_Int|MEM_Real);
+ nByte += pRec->n+1;
+ }else if( (flags & (MEM_Real|MEM_Int))!=0 || sqliteIsNumber(pRec->z) ){
+ if( (flags & (MEM_Real|MEM_Int))==MEM_Int ){
+ pRec->r = pRec->i;
+ }else if( (flags & (MEM_Real|MEM_Int))==0 ){
+ pRec->r = sqliteAtoF(pRec->z, 0);
+ }
+ Release(pRec);
+ z = pRec->zShort;
+ sqliteRealToSortable(pRec->r, z);
+ len = strlen(z);
+ pRec->z = 0;
+ pRec->flags = MEM_Real;
+ pRec->n = len+1;
+ nByte += pRec->n+1;
+ }else{
+ nByte += pRec->n+1;
+ }
+ }
+ if( nByte+sizeof(u32)>MAX_BYTES_PER_ROW ){
+ rc = STQLITE_TOOBIG;
+ goto abort_due_to_error;
+ }
+ if( addRowid ) nByte += sizeof(u32);
+ if( nByte<=NBFS ){
+ zNewKey = zTemp;
+ }else{
+ zNewKey = sqliteMallocRaw( nByte );
+ if( zNewKey==0 ) goto no_mem;
+ }
+ j = 0;
+ pRec = &pTos[1-nField];
+ for(i=0; i<nField; i++, pRec++){
+ if( pRec->flags & MEM_Null ){
+ zNewKey[j++] = 'a';
+ zNewKey[j++] = 0;
+ }else if( pRec->flags==MEM_Real ){
+ zNewKey[j++] = 'b';
+ memcpy(&zNewKey[j], pRec->zShort, pRec->n);
+ j += pRec->n;
+ }else{
+ assert( pRec->flags & MEM_Str );
+ zNewKey[j++] = 'c';
+ memcpy(&zNewKey[j], pRec->z, pRec->n);
+ j += pRec->n;
+ }
+ }
+ if( addRowid ){
+ u32 iKey;
+ pRec = &pTos[-nField];
+ assert( pRec>=p->aStack );
+ Integerify(pRec);
+ iKey = intToKey(pRec->i);
+ memcpy(&zNewKey[j], &iKey, sizeof(u32));
+ popStack(&pTos, nField+1);
+ if( pOp->p2 && tqcontainsNull ) pc = pOp->p2 - 1;
+ }else{
+ if( pOp->p2==0 ) popStack(&pTos, nField);
+ }
+ pTos++;
+ pTos->n = nByte;
+ if( nByte<=NBFS ){
+ assert( zNewKey==zTemp );
+ pTos->z = pTos->zShort;
+ memcpy(pTos->zShort, zTemp, nByte);
+ pTos->flags = MEM_Str | MEM_Short;
+ }else{
+ pTos->z = zNewKey;
+ pTos->flags = MEM_Str | MEM_Dyn;
+ }
+ break;
+}
+
+/* Opcode: IncrKey * * *
+**
+** The top of the stack should contain an index key generated by
+** The MakeKey opcode. This routine increases the least significant
+** byte of that key by one. This is used so that the MoveTo opcode
+** will move to the first entry greater than the key rather than to
+** the key itself.
+*/
+case OP_IncrKey: {
+ assert( pTos>=p->aStack );
+ /* The IncrKey opcode is only applied to keys generated by
+ ** MakeKey or MakeIdxKey and the results of those operands
+ ** are always dynamic strings or zShort[] strings. So we
+ ** are always free to modify the string in place.
+ */
+ assert( pTos->flags & (MEM_Dyn|MEM_Short) );
+ pTos->z[pTos->n-1]++;
+ break;
+}
+
+/* Opcode: Checkpoint P1 * *
+**
+** Begin a checkpoint. A checkpoint is the beginning of a operation that
+** is part of a larger transaction but which might need to be rolled back
+** itself without effecting the containing transaction. A checkpoint will
+** be automatically committed or rollback when the VDBE halts.
+**
+** The checkpoint is begun on the database file with index P1. The main
+** database file has an index of 0 and the file used for temporary tables
+** has an index of 1.
+*/
+case OP_Checkpoint: {
+ int i = pOp->p1;
+ if( i>=0 && i<db->nDb && db->aDb[i].pBt && db->aDb[i].inTrans==1 ){
+ rc = sqliteBtreeBeginCkpt(db->aDb[i].pBt);
+ if( rc==STQLITE_OK ) db->aDb[i].inTrans = 2;
+ }
+ break;
+}
+
+/* Opcode: Transaction P1 * *
+**
+** Begin a transaction. The transaction ends when a Commit or Rollback
+** opcode is encountered. Depending on the ON CONFLICT setting, the
+** transaction might also be rolled back if an error is encountered.
+**
+** P1 is the index of the database file on which the transaction is
+** started. Index 0 is the main database file and index 1 is the
+** file used for temporary tables.
+**
+** A write lock is obtained on the database file when a transaction is
+** started. No other process can read or write the file while the
+** transaction is underway. Starting a transaction also creates a
+** rollback journal. A transaction must be started before any changes
+** can be made to the database.
+*/
+case OP_Transaction: {
+ int busy = 1;
+ int i = pOp->p1;
+ assert( i>=0 && i<db->nDb );
+ if( db->aDb[i].inTrans ) break;
+ while( db->aDb[i].pBt!=0 && busy ){
+ rc = sqliteBtreeBeginTrans(db->aDb[i].pBt);
+ switch( rc ){
+ case STQLITE_BUSY: {
+ if( db->xBusyCallback==0 ){
+ p->pc = pc;
+ p->undoTransOnError = 1;
+ p->rc = STQLITE_BUSY;
+ p->pTos = pTos;
+ return STQLITE_BUSY;
+ }else if( (*db->xBusyCallback)(db->pBusyArg, "", busy++)==0 ){
+ sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
+ busy = 0;
+ }
+ break;
+ }
+ case STQLITE_READONLY: {
+ rc = STQLITE_OK;
+ /* Fall thru into the next case */
+ }
+ case STQLITE_OK: {
+ p->inTempTrans = 0;
+ busy = 0;
+ break;
+ }
+ default: {
+ goto abort_due_to_error;
+ }
+ }
+ }
+ db->aDb[i].inTrans = 1;
+ p->undoTransOnError = 1;
+ break;
+}
+
+/* Opcode: Commit * * *
+**
+** Cause all modifications to the database that have been made since the
+** last Transaction to actually take effect. No additional modifications
+** are allowed until another transaction is started. The Commit instruction
+** deletes the journal file and releases the write lock on the database.
+** A read lock continues to be held if there are still cursors open.
+*/
+case OP_Commit: {
+ int i;
+ if( db->xCommitCallback!=0 ){
+ if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
+ if( db->xCommitCallback(db->pCommitArg)!=0 ){
+ rc = STQLITE_CONSTRAINT;
+ }
+ if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
+ }
+ for(i=0; rc==STQLITE_OK && i<db->nDb; i++){
+ if( db->aDb[i].inTrans ){
+ rc = sqliteBtreeCommit(db->aDb[i].pBt);
+ db->aDb[i].inTrans = 0;
+ }
+ }
+ if( rc==STQLITE_OK ){
+ sqliteCommitInternalChanges(db);
+ }else{
+ sqliteRollbackAll(db);
+ }
+ break;
+}
+
+/* Opcode: Rollback P1 * *
+**
+** Cause all modifications to the database that have been made since the
+** last Transaction to be undone. The database is restored to its state
+** before the Transaction opcode was executed. No additional modifications
+** are allowed until another transaction is started.
+**
+** P1 is the index of the database file that is committed. An index of 0
+** is used for the main database and an index of 1 is used for the file used
+** to hold temporary tables.
+**
+** This instruction automatically closes all cursors and releases both
+** the read and write locks on the indicated database.
+*/
+case OP_Rollback: {
+ sqliteRollbackAll(db);
+ break;
+}
+
+/* Opcode: ReadCookie P1 P2 *
+**
+** Read cookie number P2 from database P1 and push it onto the stack.
+** P2==0 is the schema version. P2==1 is the database format.
+** P2==2 is the recommended pager cache size, and so forth. P1==0 is
+** the main database file and P1==1 is the database file used to store
+** temporary tables.
+**
+** There must be a read-lock on the database (either a transaction
+** must be started or there must be an open cursor) before
+** executing this instruction.
+*/
+case OP_ReadCookie: {
+ int aMeta[STQLITE_N_BTREE_META];
+ assert( pOp->p2<STQLITE_N_BTREE_META );
+ assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ assert( db->aDb[pOp->p1].pBt!=0 );
+ rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
+ pTos++;
+ pTos->i = aMeta[1+pOp->p2];
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: SetCookie P1 P2 *
+**
+** Write the top of the stack into cookie number P2 of database P1.
+** P2==0 is the schema version. P2==1 is the database format.
+** P2==2 is the recommended pager cache size, and so forth. P1==0 is
+** the main database file and P1==1 is the database file used to store
+** temporary tables.
+**
+** A transaction must be started before executing this opcode.
+*/
+case OP_SetCookie: {
+ int aMeta[STQLITE_N_BTREE_META];
+ assert( pOp->p2<STQLITE_N_BTREE_META );
+ assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ assert( db->aDb[pOp->p1].pBt!=0 );
+ assert( pTos>=p->aStack );
+ Integerify(pTos)
+ rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
+ if( rc==STQLITE_OK ){
+ aMeta[1+pOp->p2] = pTos->i;
+ rc = sqliteBtreeUpdateMeta(db->aDb[pOp->p1].pBt, aMeta);
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: VerifyCookie P1 P2 *
+**
+** Check the value of global database parameter number 0 (the
+** schema version) and make sure it is equal to P2.
+** P1 is the database number which is 0 for the main database file
+** and 1 for the file holding temporary tables and some higher number
+** for auxiliary databases.
+**
+** The cookie changes its value whenever the database schema changes.
+** This operation is used to detect when that the cookie has changed
+** and that the current process needs to reread the schema.
+**
+** Either a transaction needs to have been started or an OP_Open needs
+** to be executed (to establish a read lock) before this opcode is
+** invoked.
+*/
+case OP_VerifyCookie: {
+ int aMeta[STQLITE_N_BTREE_META];
+ assert( pOp->p1>=0 && pOp->p1<db->nDb );
+ rc = sqliteBtreeGetMeta(db->aDb[pOp->p1].pBt, aMeta);
+ if( rc==STQLITE_OK && aMeta[1]!=pOp->p2 ){
+ sqliteSetString(&p->zErrMsg, "database schema has changed", (char*)0);
+ rc = STQLITE_SCHEMA;
+ }
+ break;
+}
+
+/* Opcode: OpenRead P1 P2 P3
+**
+** Open a read-only cursor for the database table whose root page is
+** P2 in a database file. The database file is determined by an
+** integer from the top of the stack. 0 means the main database and
+** 1 means the database used for temporary tables. Give the new
+** cursor an identifier of P1. The P1 values need not be contiguous
+** but all P1 values should be small integers. It is an error for
+** P1 to be negative.
+**
+** If P2==0 then take the root page number from the next of the stack.
+**
+** There will be a read lock on the database whenever there is an
+** open cursor. If the database was unlocked prior to this instruction
+** then a read lock is acquired as part of this instruction. A read
+** lock allows other processes to read the database but prohibits
+** any other process from modifying the database. The read lock is
+** released when all cursors are closed. If this instruction attempts
+** to get a read lock but fails, the script terminates with an
+** STQLITE_BUSY error code.
+**
+** The P3 value is the name of the table or index being opened.
+** The P3 value is not actually used by this opcode and may be
+** omitted. But the code generator usually inserts the index or
+** table name into P3 to make the code easier to read.
+**
+** See also OpenWrite.
+*/
+/* Opcode: OpenWrite P1 P2 P3
+**
+** Open a read/write cursor named P1 on the table or index whose root
+** page is P2. If P2==0 then take the root page number from the stack.
+**
+** The P3 value is the name of the table or index being opened.
+** The P3 value is not actually used by this opcode and may be
+** omitted. But the code generator usually inserts the index or
+** table name into P3 to make the code easier to read.
+**
+** This instruction works just like OpenRead except that it opens the cursor
+** in read/write mode. For a given table, there can be one or more read-only
+** cursors or a single read/write cursor but not both.
+**
+** See also OpenRead.
+*/
+case OP_OpenRead:
+case OP_OpenWrite: {
+ int busy = 0;
+ int i = pOp->p1;
+ int p2 = pOp->p2;
+ int wrFlag;
+ Btree *pX;
+ int iDb;
+
+ assert( pTos>=p->aStack );
+ Integerify(pTos);
+ iDb = pTos->i;
+ pTos--;
+ assert( iDb>=0 && iDb<db->nDb );
+ pX = db->aDb[iDb].pBt;
+ assert( pX!=0 );
+ wrFlag = pOp->opcode==OP_OpenWrite;
+ if( p2<=0 ){
+ assert( pTos>=p->aStack );
+ Integerify(pTos);
+ p2 = pTos->i;
+ pTos--;
+ if( p2<2 ){
+ sqliteSetString(&p->zErrMsg, "root page number less than 2", (char*)0);
+ rc = STQLITE_INTERNAL;
+ break;
+ }
+ }
+ assert( i>=0 );
+ if( expandCursorArraySize(p, i) ) goto no_mem;
+ sqliteVdbeCleanupCursor(&p->aCsr[i]);
+ memset(&p->aCsr[i], 0, sizeof(Cursor));
+ p->aCsr[i].nullRow = 1;
+ if( pX==0 ) break;
+ do{
+ rc = sqliteBtreeCursor(pX, p2, wrFlag, &p->aCsr[i].pCursor);
+ switch( rc ){
+ case STQLITE_BUSY: {
+ if( db->xBusyCallback==0 ){
+ p->pc = pc;
+ p->rc = STQLITE_BUSY;
+ p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
+ return STQLITE_BUSY;
+ }else if( (*db->xBusyCallback)(db->pBusyArg, pOp->p3, ++busy)==0 ){
+ sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
+ busy = 0;
+ }
+ break;
+ }
+ case STQLITE_OK: {
+ busy = 0;
+ break;
+ }
+ default: {
+ goto abort_due_to_error;
+ }
+ }
+ }while( busy );
+ break;
+}
+
+/* Opcode: OpenTemp P1 P2 *
+**
+** Open a new cursor to a transient table.
+** The transient cursor is always opened read/write even if
+** the main database is read-only. The transient table is deleted
+** automatically when the cursor is closed.
+**
+** The cursor points to a BTree table if P2==0 and to a BTree index
+** if P2==1. A BTree table must have an integer key and can have arbitrary
+** data. A BTree index has no data but can have an arbitrary key.
+**
+** This opcode is used for tables that exist for the duration of a single
+** SQL statement only. Tables created using CREATE TEMPORARY TABLE
+** are opened using OP_OpenRead or OP_OpenWrite. "Temporary" in the
+** context of this opcode means for the duration of a single SQL statement
+** whereas "Temporary" in the context of CREATE TABLE means for the duration
+** of the connection to the database. Same word; different meanings.
+*/
+case OP_OpenTemp: {
+ int i = pOp->p1;
+ Cursor *pCx;
+ assert( i>=0 );
+ if( expandCursorArraySize(p, i) ) goto no_mem;
+ pCx = &p->aCsr[i];
+ sqliteVdbeCleanupCursor(pCx);
+ memset(pCx, 0, sizeof(*pCx));
+ pCx->nullRow = 1;
+ rc = sqliteBtreeFactory(db, 0, 1, TEMP_PAGES, &pCx->pBt);
+
+ if( rc==STQLITE_OK ){
+ rc = sqliteBtreeBeginTrans(pCx->pBt);
+ }
+ if( rc==STQLITE_OK ){
+ if( pOp->p2 ){
+ int pgno;
+ rc = sqliteBtreeCreateIndex(pCx->pBt, &pgno);
+ if( rc==STQLITE_OK ){
+ rc = sqliteBtreeCursor(pCx->pBt, pgno, 1, &pCx->pCursor);
+ }
+ }else{
+ rc = sqliteBtreeCursor(pCx->pBt, 2, 1, &pCx->pCursor);
+ }
+ }
+ break;
+}
+
+/* Opcode: OpenPseudo P1 * *
+**
+** Open a new cursor that points to a fake table that tqcontains a single
+** row of data. Any attempt to write a second row of data causes the
+** first row to be deleted. All data is deleted when the cursor is
+** closed.
+**
+** A pseudo-table created by this opcode is useful for holding the
+** NEW or OLD tables in a trigger.
+*/
+case OP_OpenPseudo: {
+ int i = pOp->p1;
+ Cursor *pCx;
+ assert( i>=0 );
+ if( expandCursorArraySize(p, i) ) goto no_mem;
+ pCx = &p->aCsr[i];
+ sqliteVdbeCleanupCursor(pCx);
+ memset(pCx, 0, sizeof(*pCx));
+ pCx->nullRow = 1;
+ pCx->pseudoTable = 1;
+ break;
+}
+
+/* Opcode: Close P1 * *
+**
+** Close a cursor previously opened as P1. If P1 is not
+** currently open, this instruction is a no-op.
+*/
+case OP_Close: {
+ int i = pOp->p1;
+ if( i>=0 && i<p->nCursor ){
+ sqliteVdbeCleanupCursor(&p->aCsr[i]);
+ }
+ break;
+}
+
+/* Opcode: MoveTo P1 P2 *
+**
+** Pop the top of the stack and use its value as a key. Reposition
+** cursor P1 so that it points to an entry with a matching key. If
+** the table tqcontains no record with a matching key, then the cursor
+** is left pointing at the first record that is greater than the key.
+** If there are no records greater than the key and P2 is not zero,
+** then an immediate jump to P2 is made.
+**
+** See also: Found, NotFound, Distinct, MoveLt
+*/
+/* Opcode: MoveLt P1 P2 *
+**
+** Pop the top of the stack and use its value as a key. Reposition
+** cursor P1 so that it points to the entry with the largest key that is
+** less than the key popped from the stack.
+** If there are no records less than than the key and P2
+** is not zero then an immediate jump to P2 is made.
+**
+** See also: MoveTo
+*/
+case OP_MoveLt:
+case OP_MoveTo: {
+ int i = pOp->p1;
+ Cursor *pC;
+
+ assert( pTos>=p->aStack );
+ assert( i>=0 && i<p->nCursor );
+ pC = &p->aCsr[i];
+ if( pC->pCursor!=0 ){
+ int res, oc;
+ pC->nullRow = 0;
+ if( pTos->flags & MEM_Int ){
+ int iKey = intToKey(pTos->i);
+ if( pOp->p2==0 && pOp->opcode==OP_MoveTo ){
+ pC->movetoTarget = iKey;
+ pC->deferredMoveto = 1;
+ Release(pTos);
+ pTos--;
+ break;
+ }
+ sqliteBtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
+ pC->lastRecno = pTos->i;
+ pC->recnoIsValid = res==0;
+ }else{
+ Stringify(pTos);
+ sqliteBtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
+ pC->recnoIsValid = 0;
+ }
+ pC->deferredMoveto = 0;
+ sqlite_search_count++;
+ oc = pOp->opcode;
+ if( oc==OP_MoveTo && res<0 ){
+ sqliteBtreeNext(pC->pCursor, &res);
+ pC->recnoIsValid = 0;
+ if( res && pOp->p2>0 ){
+ pc = pOp->p2 - 1;
+ }
+ }else if( oc==OP_MoveLt ){
+ if( res>=0 ){
+ sqliteBtreePrevious(pC->pCursor, &res);
+ pC->recnoIsValid = 0;
+ }else{
+ /* res might be negative because the table is empty. Check to
+ ** see if this is the case.
+ */
+ int keysize;
+ res = sqliteBtreeKeySize(pC->pCursor,&keysize)!=0 || keysize==0;
+ }
+ if( res && pOp->p2>0 ){
+ pc = pOp->p2 - 1;
+ }
+ }
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: Distinct P1 P2 *
+**
+** Use the top of the stack as a string key. If a record with that key does
+** not exist in the table of cursor P1, then jump to P2. If the record
+** does already exist, then fall thru. The cursor is left pointing
+** at the record if it exists. The key is not popped from the stack.
+**
+** This operation is similar to NotFound except that this operation
+** does not pop the key from the stack.
+**
+** See also: Found, NotFound, MoveTo, IsUnique, NotExists
+*/
+/* Opcode: Found P1 P2 *
+**
+** Use the top of the stack as a string key. If a record with that key
+** does exist in table of P1, then jump to P2. If the record
+** does not exist, then fall thru. The cursor is left pointing
+** to the record if it exists. The key is popped from the stack.
+**
+** See also: Distinct, NotFound, MoveTo, IsUnique, NotExists
+*/
+/* Opcode: NotFound P1 P2 *
+**
+** Use the top of the stack as a string key. If a record with that key
+** does not exist in table of P1, then jump to P2. If the record
+** does exist, then fall thru. The cursor is left pointing to the
+** record if it exists. The key is popped from the stack.
+**
+** The difference between this operation and Distinct is that
+** Distinct does not pop the key from the stack.
+**
+** See also: Distinct, Found, MoveTo, NotExists, IsUnique
+*/
+case OP_Distinct:
+case OP_NotFound:
+case OP_Found: {
+ int i = pOp->p1;
+ int alreadyExists = 0;
+ Cursor *pC;
+ assert( pTos>=p->aStack );
+ assert( i>=0 && i<p->nCursor );
+ if( (pC = &p->aCsr[i])->pCursor!=0 ){
+ int res, rx;
+ Stringify(pTos);
+ rx = sqliteBtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
+ alreadyExists = rx==STQLITE_OK && res==0;
+ pC->deferredMoveto = 0;
+ }
+ if( pOp->opcode==OP_Found ){
+ if( alreadyExists ) pc = pOp->p2 - 1;
+ }else{
+ if( !alreadyExists ) pc = pOp->p2 - 1;
+ }
+ if( pOp->opcode!=OP_Distinct ){
+ Release(pTos);
+ pTos--;
+ }
+ break;
+}
+
+/* Opcode: IsUnique P1 P2 *
+**
+** The top of the stack is an integer record number. Call this
+** record number R. The next on the stack is an index key created
+** using MakeIdxKey. Call it K. This instruction pops R from the
+** stack but it leaves K unchanged.
+**
+** P1 is an index. So all but the last four bytes of K are an
+** index string. The last four bytes of K are a record number.
+**
+** This instruction asks if there is an entry in P1 where the
+** index string matches K but the record number is different
+** from R. If there is no such entry, then there is an immediate
+** jump to P2. If any entry does exist where the index string
+** matches K but the record number is not R, then the record
+** number for that entry is pushed onto the stack and control
+** falls through to the next instruction.
+**
+** See also: Distinct, NotFound, NotExists, Found
+*/
+case OP_IsUnique: {
+ int i = pOp->p1;
+ Mem *pNos = &pTos[-1];
+ BtCursor *pCrsr;
+ int R;
+
+ /* Pop the value R off the top of the stack
+ */
+ assert( pNos>=p->aStack );
+ Integerify(pTos);
+ R = pTos->i;
+ pTos--;
+ assert( i>=0 && i<=p->nCursor );
+ if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
+ int res, rc;
+ int v; /* The record number on the P1 entry that matches K */
+ char *zKey; /* The value of K */
+ int nKey; /* Number of bytes in K */
+
+ /* Make sure K is a string and make zKey point to K
+ */
+ Stringify(pNos);
+ zKey = pNos->z;
+ nKey = pNos->n;
+ assert( nKey >= 4 );
+
+ /* Search for an entry in P1 where all but the last four bytes match K.
+ ** If there is no such entry, jump immediately to P2.
+ */
+ assert( p->aCsr[i].deferredMoveto==0 );
+ rc = sqliteBtreeMoveto(pCrsr, zKey, nKey-4, &res);
+ if( rc!=STQLITE_OK ) goto abort_due_to_error;
+ if( res<0 ){
+ rc = sqliteBtreeNext(pCrsr, &res);
+ if( res ){
+ pc = pOp->p2 - 1;
+ break;
+ }
+ }
+ rc = sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &res);
+ if( rc!=STQLITE_OK ) goto abort_due_to_error;
+ if( res>0 ){
+ pc = pOp->p2 - 1;
+ break;
+ }
+
+ /* At this point, pCrsr is pointing to an entry in P1 where all but
+ ** the last for bytes of the key match K. Check to see if the last
+ ** four bytes of the key are different from R. If the last four
+ ** bytes equal R then jump immediately to P2.
+ */
+ sqliteBtreeKey(pCrsr, nKey - 4, 4, (char*)&v);
+ v = keyToInt(v);
+ if( v==R ){
+ pc = pOp->p2 - 1;
+ break;
+ }
+
+ /* The last four bytes of the key are different from R. Convert the
+ ** last four bytes of the key into an integer and push it onto the
+ ** stack. (These bytes are the record number of an entry that
+ ** violates a UNITQUE constraint.)
+ */
+ pTos++;
+ pTos->i = v;
+ pTos->flags = MEM_Int;
+ }
+ break;
+}
+
+/* Opcode: NotExists P1 P2 *
+**
+** Use the top of the stack as a integer key. If a record with that key
+** does not exist in table of P1, then jump to P2. If the record
+** does exist, then fall thru. The cursor is left pointing to the
+** record if it exists. The integer key is popped from the stack.
+**
+** The difference between this operation and NotFound is that this
+** operation assumes the key is an integer and NotFound assumes it
+** is a string.
+**
+** See also: Distinct, Found, MoveTo, NotFound, IsUnique
+*/
+case OP_NotExists: {
+ int i = pOp->p1;
+ BtCursor *pCrsr;
+ assert( pTos>=p->aStack );
+ assert( i>=0 && i<p->nCursor );
+ if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
+ int res, rx, iKey;
+ assert( pTos->flags & MEM_Int );
+ iKey = intToKey(pTos->i);
+ rx = sqliteBtreeMoveto(pCrsr, (char*)&iKey, sizeof(int), &res);
+ p->aCsr[i].lastRecno = pTos->i;
+ p->aCsr[i].recnoIsValid = res==0;
+ p->aCsr[i].nullRow = 0;
+ if( rx!=STQLITE_OK || res!=0 ){
+ pc = pOp->p2 - 1;
+ p->aCsr[i].recnoIsValid = 0;
+ }
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: NewRecno P1 * *
+**
+** Get a new integer record number used as the key to a table.
+** The record number is not previously used as a key in the database
+** table that cursor P1 points to. The new record number is pushed
+** onto the stack.
+*/
+case OP_NewRecno: {
+ int i = pOp->p1;
+ int v = 0;
+ Cursor *pC;
+ assert( i>=0 && i<p->nCursor );
+ if( (pC = &p->aCsr[i])->pCursor==0 ){
+ v = 0;
+ }else{
+ /* The next rowid or record number (different terms for the same
+ ** thing) is obtained in a two-step algorithm.
+ **
+ ** First we attempt to tqfind the largest existing rowid and add one
+ ** to that. But if the largest existing rowid is already the maximum
+ ** positive integer, we have to fall through to the second
+ ** probabilistic algorithm
+ **
+ ** The second algorithm is to select a rowid at random and see if
+ ** it already exists in the table. If it does not exist, we have
+ ** succeeded. If the random rowid does exist, we select a new one
+ ** and try again, up to 1000 times.
+ **
+ ** For a table with less than 2 billion entries, the probability
+ ** of not tqfinding a unused rowid is about 1.0e-300. This is a
+ ** non-zero probability, but it is still vanishingly small and should
+ ** never cause a problem. You are much, much more likely to have a
+ ** hardware failure than for this algorithm to fail.
+ **
+ ** The analysis in the previous paragraph assumes that you have a good
+ ** source of random numbers. Is a library function like lrand48()
+ ** good enough? Maybe. Maybe not. It's hard to know whether there
+ ** might be subtle bugs is some implementations of lrand48() that
+ ** could cause problems. To avoid uncertainty, STQLite uses its own
+ ** random number generator based on the RC4 algorithm.
+ **
+ ** To promote locality of reference for repetitive inserts, the
+ ** first few attempts at chosing a random rowid pick values just a little
+ ** larger than the previous rowid. This has been shown experimentally
+ ** to double the speed of the COPY operation.
+ */
+ int res, rx, cnt, x;
+ cnt = 0;
+ if( !pC->useRandomRowid ){
+ if( pC->nextRowidValid ){
+ v = pC->nextRowid;
+ }else{
+ rx = sqliteBtreeLast(pC->pCursor, &res);
+ if( res ){
+ v = 1;
+ }else{
+ sqliteBtreeKey(pC->pCursor, 0, sizeof(v), (void*)&v);
+ v = keyToInt(v);
+ if( v==0x7fffffff ){
+ pC->useRandomRowid = 1;
+ }else{
+ v++;
+ }
+ }
+ }
+ if( v<0x7fffffff ){
+ pC->nextRowidValid = 1;
+ pC->nextRowid = v+1;
+ }else{
+ pC->nextRowidValid = 0;
+ }
+ }
+ if( pC->useRandomRowid ){
+ v = db->priorNewRowid;
+ cnt = 0;
+ do{
+ if( v==0 || cnt>2 ){
+ sqliteRandomness(sizeof(v), &v);
+ if( cnt<5 ) v &= 0xffffff;
+ }else{
+ unsigned char r;
+ sqliteRandomness(1, &r);
+ v += r + 1;
+ }
+ if( v==0 ) continue;
+ x = intToKey(v);
+ rx = sqliteBtreeMoveto(pC->pCursor, &x, sizeof(int), &res);
+ cnt++;
+ }while( cnt<1000 && rx==STQLITE_OK && res==0 );
+ db->priorNewRowid = v;
+ if( rx==STQLITE_OK && res==0 ){
+ rc = STQLITE_FULL;
+ goto abort_due_to_error;
+ }
+ }
+ pC->recnoIsValid = 0;
+ pC->deferredMoveto = 0;
+ }
+ pTos++;
+ pTos->i = v;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: PutIntKey P1 P2 *
+**
+** Write an entry into the table of cursor P1. A new entry is
+** created if it doesn't already exist or the data for an existing
+** entry is overwritten. The data is the value on the top of the
+** stack. The key is the next value down on the stack. The key must
+** be an integer. The stack is popped twice by this instruction.
+**
+** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
+** incremented (otherwise not). If the OPFLAG_CSCHANGE flag is set,
+** then the current statement change count is incremented (otherwise not).
+** If the OPFLAG_LASTROWID flag of P2 is set, then rowid is
+** stored for subsequent return by the sqlite_last_insert_rowid() function
+** (otherwise it's unmodified).
+*/
+/* Opcode: PutStrKey P1 * *
+**
+** Write an entry into the table of cursor P1. A new entry is
+** created if it doesn't already exist or the data for an existing
+** entry is overwritten. The data is the value on the top of the
+** stack. The key is the next value down on the stack. The key must
+** be a string. The stack is popped twice by this instruction.
+**
+** P1 may not be a pseudo-table opened using the OpenPseudo opcode.
+*/
+case OP_PutIntKey:
+case OP_PutStrKey: {
+ Mem *pNos = &pTos[-1];
+ int i = pOp->p1;
+ Cursor *pC;
+ assert( pNos>=p->aStack );
+ assert( i>=0 && i<p->nCursor );
+ if( ((pC = &p->aCsr[i])->pCursor!=0 || pC->pseudoTable) ){
+ char *zKey;
+ int nKey, iKey;
+ if( pOp->opcode==OP_PutStrKey ){
+ Stringify(pNos);
+ nKey = pNos->n;
+ zKey = pNos->z;
+ }else{
+ assert( pNos->flags & MEM_Int );
+ nKey = sizeof(int);
+ iKey = intToKey(pNos->i);
+ zKey = (char*)&iKey;
+ if( pOp->p2 & OPFLAG_NCHANGE ) db->nChange++;
+ if( pOp->p2 & OPFLAG_LASTROWID ) db->lastRowid = pNos->i;
+ if( pOp->p2 & OPFLAG_CSCHANGE ) db->csChange++;
+ if( pC->nextRowidValid && pTos->i>=pC->nextRowid ){
+ pC->nextRowidValid = 0;
+ }
+ }
+ if( pTos->flags & MEM_Null ){
+ pTos->z = 0;
+ pTos->n = 0;
+ }else{
+ assert( pTos->flags & MEM_Str );
+ }
+ if( pC->pseudoTable ){
+ /* PutStrKey does not work for pseudo-tables.
+ ** The following assert makes sure we are not trying to use
+ ** PutStrKey on a pseudo-table
+ */
+ assert( pOp->opcode==OP_PutIntKey );
+ sqliteFree(pC->pData);
+ pC->iKey = iKey;
+ pC->nData = pTos->n;
+ if( pTos->flags & MEM_Dyn ){
+ pC->pData = pTos->z;
+ pTos->flags = MEM_Null;
+ }else{
+ pC->pData = sqliteMallocRaw( pC->nData );
+ if( pC->pData ){
+ memcpy(pC->pData, pTos->z, pC->nData);
+ }
+ }
+ pC->nullRow = 0;
+ }else{
+ rc = sqliteBtreeInsert(pC->pCursor, zKey, nKey, pTos->z, pTos->n);
+ }
+ pC->recnoIsValid = 0;
+ pC->deferredMoveto = 0;
+ }
+ popStack(&pTos, 2);
+ break;
+}
+
+/* Opcode: Delete P1 P2 *
+**
+** Delete the record at which the P1 cursor is currently pointing.
+**
+** The cursor will be left pointing at either the next or the previous
+** record in the table. If it is left pointing at the next record, then
+** the next Next instruction will be a no-op. Hence it is OK to delete
+** a record from within an Next loop.
+**
+** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
+** incremented (otherwise not). If OPFLAG_CSCHANGE flag is set,
+** then the current statement change count is incremented (otherwise not).
+**
+** If P1 is a pseudo-table, then this instruction is a no-op.
+*/
+case OP_Delete: {
+ int i = pOp->p1;
+ Cursor *pC;
+ assert( i>=0 && i<p->nCursor );
+ pC = &p->aCsr[i];
+ if( pC->pCursor!=0 ){
+ sqliteVdbeCursorMoveto(pC);
+ rc = sqliteBtreeDelete(pC->pCursor);
+ pC->nextRowidValid = 0;
+ }
+ if( pOp->p2 & OPFLAG_NCHANGE ) db->nChange++;
+ if( pOp->p2 & OPFLAG_CSCHANGE ) db->csChange++;
+ break;
+}
+
+/* Opcode: SetCounts * * *
+**
+** Called at end of statement. Updates lsChange (last statement change count)
+** and resets csChange (current statement change count) to 0.
+*/
+case OP_SetCounts: {
+ db->lsChange=db->csChange;
+ db->csChange=0;
+ break;
+}
+
+/* Opcode: KeyAsData P1 P2 *
+**
+** Turn the key-as-data mode for cursor P1 either on (if P2==1) or
+** off (if P2==0). In key-as-data mode, the OP_Column opcode pulls
+** data off of the key rather than the data. This is used for
+** processing compound selects.
+*/
+case OP_KeyAsData: {
+ int i = pOp->p1;
+ assert( i>=0 && i<p->nCursor );
+ p->aCsr[i].keyAsData = pOp->p2;
+ break;
+}
+
+/* Opcode: RowData P1 * *
+**
+** Push onto the stack the complete row data for cursor P1.
+** There is no interpretation of the data. It is just copied
+** onto the stack exactly as it is found in the database file.
+**
+** If the cursor is not pointing to a valid row, a NULL is pushed
+** onto the stack.
+*/
+/* Opcode: RowKey P1 * *
+**
+** Push onto the stack the complete row key for cursor P1.
+** There is no interpretation of the key. It is just copied
+** onto the stack exactly as it is found in the database file.
+**
+** If the cursor is not pointing to a valid row, a NULL is pushed
+** onto the stack.
+*/
+case OP_RowKey:
+case OP_RowData: {
+ int i = pOp->p1;
+ Cursor *pC;
+ int n;
+
+ pTos++;
+ assert( i>=0 && i<p->nCursor );
+ pC = &p->aCsr[i];
+ if( pC->nullRow ){
+ pTos->flags = MEM_Null;
+ }else if( pC->pCursor!=0 ){
+ BtCursor *pCrsr = pC->pCursor;
+ sqliteVdbeCursorMoveto(pC);
+ if( pC->nullRow ){
+ pTos->flags = MEM_Null;
+ break;
+ }else if( pC->keyAsData || pOp->opcode==OP_RowKey ){
+ sqliteBtreeKeySize(pCrsr, &n);
+ }else{
+ sqliteBtreeDataSize(pCrsr, &n);
+ }
+ pTos->n = n;
+ if( n<=NBFS ){
+ pTos->flags = MEM_Str | MEM_Short;
+ pTos->z = pTos->zShort;
+ }else{
+ char *z = sqliteMallocRaw( n );
+ if( z==0 ) goto no_mem;
+ pTos->flags = MEM_Str | MEM_Dyn;
+ pTos->z = z;
+ }
+ if( pC->keyAsData || pOp->opcode==OP_RowKey ){
+ sqliteBtreeKey(pCrsr, 0, n, pTos->z);
+ }else{
+ sqliteBtreeData(pCrsr, 0, n, pTos->z);
+ }
+ }else if( pC->pseudoTable ){
+ pTos->n = pC->nData;
+ pTos->z = pC->pData;
+ pTos->flags = MEM_Str|MEM_Ephem;
+ }else{
+ pTos->flags = MEM_Null;
+ }
+ break;
+}
+
+/* Opcode: Column P1 P2 *
+**
+** Interpret the data that cursor P1 points to as
+** a structure built using the MakeRecord instruction.
+** (See the MakeRecord opcode for additional information about
+** the format of the data.)
+** Push onto the stack the value of the P2-th column contained
+** in the data.
+**
+** If the KeyAsData opcode has previously executed on this cursor,
+** then the field might be extracted from the key rather than the
+** data.
+**
+** If P1 is negative, then the record is stored on the stack rather
+** than in a table. For P1==-1, the top of the stack is used.
+** For P1==-2, the next on the stack is used. And so forth. The
+** value pushed is always just a pointer into the record which is
+** stored further down on the stack. The column value is not copied.
+*/
+case OP_Column: {
+ int amt, offset, end, payloadSize;
+ int i = pOp->p1;
+ int p2 = pOp->p2;
+ Cursor *pC;
+ char *zRec;
+ BtCursor *pCrsr;
+ int idxWidth;
+ unsigned char aHdr[10];
+
+ assert( i<p->nCursor );
+ pTos++;
+ if( i<0 ){
+ assert( &pTos[i]>=p->aStack );
+ assert( pTos[i].flags & MEM_Str );
+ zRec = pTos[i].z;
+ payloadSize = pTos[i].n;
+ }else if( (pC = &p->aCsr[i])->pCursor!=0 ){
+ sqliteVdbeCursorMoveto(pC);
+ zRec = 0;
+ pCrsr = pC->pCursor;
+ if( pC->nullRow ){
+ payloadSize = 0;
+ }else if( pC->keyAsData ){
+ sqliteBtreeKeySize(pCrsr, &payloadSize);
+ }else{
+ sqliteBtreeDataSize(pCrsr, &payloadSize);
+ }
+ }else if( pC->pseudoTable ){
+ payloadSize = pC->nData;
+ zRec = pC->pData;
+ assert( payloadSize==0 || zRec!=0 );
+ }else{
+ payloadSize = 0;
+ }
+
+ /* Figure out how many bytes in the column data and where the column
+ ** data begins.
+ */
+ if( payloadSize==0 ){
+ pTos->flags = MEM_Null;
+ break;
+ }else if( payloadSize<256 ){
+ idxWidth = 1;
+ }else if( payloadSize<65536 ){
+ idxWidth = 2;
+ }else{
+ idxWidth = 3;
+ }
+
+ /* Figure out where the requested column is stored and how big it is.
+ */
+ if( payloadSize < idxWidth*(p2+1) ){
+ rc = STQLITE_CORRUPT;
+ goto abort_due_to_error;
+ }
+ if( zRec ){
+ memcpy(aHdr, &zRec[idxWidth*p2], idxWidth*2);
+ }else if( pC->keyAsData ){
+ sqliteBtreeKey(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
+ }else{
+ sqliteBtreeData(pCrsr, idxWidth*p2, idxWidth*2, (char*)aHdr);
+ }
+ offset = aHdr[0];
+ end = aHdr[idxWidth];
+ if( idxWidth>1 ){
+ offset |= aHdr[1]<<8;
+ end |= aHdr[idxWidth+1]<<8;
+ if( idxWidth>2 ){
+ offset |= aHdr[2]<<16;
+ end |= aHdr[idxWidth+2]<<16;
+ }
+ }
+ amt = end - offset;
+ if( amt<0 || offset<0 || end>payloadSize ){
+ rc = STQLITE_CORRUPT;
+ goto abort_due_to_error;
+ }
+
+ /* amt and offset now hold the offset to the start of data and the
+ ** amount of data. Go get the data and put it on the stack.
+ */
+ pTos->n = amt;
+ if( amt==0 ){
+ pTos->flags = MEM_Null;
+ }else if( zRec ){
+ pTos->flags = MEM_Str | MEM_Ephem;
+ pTos->z = &zRec[offset];
+ }else{
+ if( amt<=NBFS ){
+ pTos->flags = MEM_Str | MEM_Short;
+ pTos->z = pTos->zShort;
+ }else{
+ char *z = sqliteMallocRaw( amt );
+ if( z==0 ) goto no_mem;
+ pTos->flags = MEM_Str | MEM_Dyn;
+ pTos->z = z;
+ }
+ if( pC->keyAsData ){
+ sqliteBtreeKey(pCrsr, offset, amt, pTos->z);
+ }else{
+ sqliteBtreeData(pCrsr, offset, amt, pTos->z);
+ }
+ }
+ break;
+}
+
+/* Opcode: Recno P1 * *
+**
+** Push onto the stack an integer which is the first 4 bytes of the
+** the key to the current entry in a sequential scan of the database
+** file P1. The sequential scan should have been started using the
+** Next opcode.
+*/
+case OP_Recno: {
+ int i = pOp->p1;
+ Cursor *pC;
+ int v;
+
+ assert( i>=0 && i<p->nCursor );
+ pC = &p->aCsr[i];
+ sqliteVdbeCursorMoveto(pC);
+ pTos++;
+ if( pC->recnoIsValid ){
+ v = pC->lastRecno;
+ }else if( pC->pseudoTable ){
+ v = keyToInt(pC->iKey);
+ }else if( pC->nullRow || pC->pCursor==0 ){
+ pTos->flags = MEM_Null;
+ break;
+ }else{
+ assert( pC->pCursor!=0 );
+ sqliteBtreeKey(pC->pCursor, 0, sizeof(u32), (char*)&v);
+ v = keyToInt(v);
+ }
+ pTos->i = v;
+ pTos->flags = MEM_Int;
+ break;
+}
+
+/* Opcode: FullKey P1 * *
+**
+** Extract the complete key from the record that cursor P1 is currently
+** pointing to and push the key onto the stack as a string.
+**
+** Compare this opcode to Recno. The Recno opcode extracts the first
+** 4 bytes of the key and pushes those bytes onto the stack as an
+** integer. This instruction pushes the entire key as a string.
+**
+** This opcode may not be used on a pseudo-table.
+*/
+case OP_FullKey: {
+ int i = pOp->p1;
+ BtCursor *pCrsr;
+
+ assert( p->aCsr[i].keyAsData );
+ assert( !p->aCsr[i].pseudoTable );
+ assert( i>=0 && i<p->nCursor );
+ pTos++;
+ if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
+ int amt;
+ char *z;
+
+ sqliteVdbeCursorMoveto(&p->aCsr[i]);
+ sqliteBtreeKeySize(pCrsr, &amt);
+ if( amt<=0 ){
+ rc = STQLITE_CORRUPT;
+ goto abort_due_to_error;
+ }
+ if( amt>NBFS ){
+ z = sqliteMallocRaw( amt );
+ if( z==0 ) goto no_mem;
+ pTos->flags = MEM_Str | MEM_Dyn;
+ }else{
+ z = pTos->zShort;
+ pTos->flags = MEM_Str | MEM_Short;
+ }
+ sqliteBtreeKey(pCrsr, 0, amt, z);
+ pTos->z = z;
+ pTos->n = amt;
+ }
+ break;
+}
+
+/* Opcode: NullRow P1 * *
+**
+** Move the cursor P1 to a null row. Any OP_Column operations
+** that occur while the cursor is on the null row will always push
+** a NULL onto the stack.
+*/
+case OP_NullRow: {
+ int i = pOp->p1;
+
+ assert( i>=0 && i<p->nCursor );
+ p->aCsr[i].nullRow = 1;
+ p->aCsr[i].recnoIsValid = 0;
+ break;
+}
+
+/* Opcode: Last P1 P2 *
+**
+** The next use of the Recno or Column or Next instruction for P1
+** will refer to the last entry in the database table or index.
+** If the table or index is empty and P2>0, then jump immediately to P2.
+** If P2 is 0 or if the table or index is not empty, fall through
+** to the following instruction.
+*/
+case OP_Last: {
+ int i = pOp->p1;
+ Cursor *pC;
+ BtCursor *pCrsr;
+
+ assert( i>=0 && i<p->nCursor );
+ pC = &p->aCsr[i];
+ if( (pCrsr = pC->pCursor)!=0 ){
+ int res;
+ rc = sqliteBtreeLast(pCrsr, &res);
+ pC->nullRow = res;
+ pC->deferredMoveto = 0;
+ if( res && pOp->p2>0 ){
+ pc = pOp->p2 - 1;
+ }
+ }else{
+ pC->nullRow = 0;
+ }
+ break;
+}
+
+/* Opcode: Rewind P1 P2 *
+**
+** The next use of the Recno or Column or Next instruction for P1
+** will refer to the first entry in the database table or index.
+** If the table or index is empty and P2>0, then jump immediately to P2.
+** If P2 is 0 or if the table or index is not empty, fall through
+** to the following instruction.
+*/
+case OP_Rewind: {
+ int i = pOp->p1;
+ Cursor *pC;
+ BtCursor *pCrsr;
+
+ assert( i>=0 && i<p->nCursor );
+ pC = &p->aCsr[i];
+ if( (pCrsr = pC->pCursor)!=0 ){
+ int res;
+ rc = sqliteBtreeFirst(pCrsr, &res);
+ pC->atFirst = res==0;
+ pC->nullRow = res;
+ pC->deferredMoveto = 0;
+ if( res && pOp->p2>0 ){
+ pc = pOp->p2 - 1;
+ }
+ }else{
+ pC->nullRow = 0;
+ }
+ break;
+}
+
+/* Opcode: Next P1 P2 *
+**
+** Advance cursor P1 so that it points to the next key/data pair in its
+** table or index. If there are no more key/value pairs then fall through
+** to the following instruction. But if the cursor advance was successful,
+** jump immediately to P2.
+**
+** See also: Prev
+*/
+/* Opcode: Prev P1 P2 *
+**
+** Back up cursor P1 so that it points to the previous key/data pair in its
+** table or index. If there is no previous key/value pairs then fall through
+** to the following instruction. But if the cursor backup was successful,
+** jump immediately to P2.
+*/
+case OP_Prev:
+case OP_Next: {
+ Cursor *pC;
+ BtCursor *pCrsr;
+
+ CHECK_FOR_INTERRUPT;
+ assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+ pC = &p->aCsr[pOp->p1];
+ if( (pCrsr = pC->pCursor)!=0 ){
+ int res;
+ if( pC->nullRow ){
+ res = 1;
+ }else{
+ assert( pC->deferredMoveto==0 );
+ rc = pOp->opcode==OP_Next ? sqliteBtreeNext(pCrsr, &res) :
+ sqliteBtreePrevious(pCrsr, &res);
+ pC->nullRow = res;
+ }
+ if( res==0 ){
+ pc = pOp->p2 - 1;
+ sqlite_search_count++;
+ }
+ }else{
+ pC->nullRow = 1;
+ }
+ pC->recnoIsValid = 0;
+ break;
+}
+
+/* Opcode: IdxPut P1 P2 P3
+**
+** The top of the stack holds a SQL index key made using the
+** MakeIdxKey instruction. This opcode writes that key into the
+** index P1. Data for the entry is nil.
+**
+** If P2==1, then the key must be unique. If the key is not unique,
+** the program aborts with a STQLITE_CONSTRAINT error and the database
+** is rolled back. If P3 is not null, then it becomes part of the
+** error message returned with the STQLITE_CONSTRAINT.
+*/
+case OP_IdxPut: {
+ int i = pOp->p1;
+ BtCursor *pCrsr;
+ assert( pTos>=p->aStack );
+ assert( i>=0 && i<p->nCursor );
+ assert( pTos->flags & MEM_Str );
+ if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
+ int nKey = pTos->n;
+ const char *zKey = pTos->z;
+ if( pOp->p2 ){
+ int res, n;
+ assert( nKey >= 4 );
+ rc = sqliteBtreeMoveto(pCrsr, zKey, nKey-4, &res);
+ if( rc!=STQLITE_OK ) goto abort_due_to_error;
+ while( res!=0 ){
+ int c;
+ sqliteBtreeKeySize(pCrsr, &n);
+ if( n==nKey
+ && sqliteBtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &c)==STQLITE_OK
+ && c==0
+ ){
+ rc = STQLITE_CONSTRAINT;
+ if( pOp->p3 && pOp->p3[0] ){
+ sqliteSetString(&p->zErrMsg, pOp->p3, (char*)0);
+ }
+ goto abort_due_to_error;
+ }
+ if( res<0 ){
+ sqliteBtreeNext(pCrsr, &res);
+ res = +1;
+ }else{
+ break;
+ }
+ }
+ }
+ rc = sqliteBtreeInsert(pCrsr, zKey, nKey, "", 0);
+ assert( p->aCsr[i].deferredMoveto==0 );
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: IdxDelete P1 * *
+**
+** The top of the stack is an index key built using the MakeIdxKey opcode.
+** This opcode removes that entry from the index.
+*/
+case OP_IdxDelete: {
+ int i = pOp->p1;
+ BtCursor *pCrsr;
+ assert( pTos>=p->aStack );
+ assert( pTos->flags & MEM_Str );
+ assert( i>=0 && i<p->nCursor );
+ if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
+ int rx, res;
+ rx = sqliteBtreeMoveto(pCrsr, pTos->z, pTos->n, &res);
+ if( rx==STQLITE_OK && res==0 ){
+ rc = sqliteBtreeDelete(pCrsr);
+ }
+ assert( p->aCsr[i].deferredMoveto==0 );
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: IdxRecno P1 * *
+**
+** Push onto the stack an integer which is the last 4 bytes of the
+** the key to the current entry in index P1. These 4 bytes should
+** be the record number of the table entry to which this index entry
+** points.
+**
+** See also: Recno, MakeIdxKey.
+*/
+case OP_IdxRecno: {
+ int i = pOp->p1;
+ BtCursor *pCrsr;
+
+ assert( i>=0 && i<p->nCursor );
+ pTos++;
+ if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
+ int v;
+ int sz;
+ assert( p->aCsr[i].deferredMoveto==0 );
+ sqliteBtreeKeySize(pCrsr, &sz);
+ if( sz<sizeof(u32) ){
+ pTos->flags = MEM_Null;
+ }else{
+ sqliteBtreeKey(pCrsr, sz - sizeof(u32), sizeof(u32), (char*)&v);
+ v = keyToInt(v);
+ pTos->i = v;
+ pTos->flags = MEM_Int;
+ }
+ }else{
+ pTos->flags = MEM_Null;
+ }
+ break;
+}
+
+/* Opcode: IdxGT P1 P2 *
+**
+** Compare the top of the stack against the key on the index entry that
+** cursor P1 is currently pointing to. Ignore the last 4 bytes of the
+** index entry. If the index entry is greater than the top of the stack
+** then jump to P2. Otherwise fall through to the next instruction.
+** In either case, the stack is popped once.
+*/
+/* Opcode: IdxGE P1 P2 *
+**
+** Compare the top of the stack against the key on the index entry that
+** cursor P1 is currently pointing to. Ignore the last 4 bytes of the
+** index entry. If the index entry is greater than or equal to
+** the top of the stack
+** then jump to P2. Otherwise fall through to the next instruction.
+** In either case, the stack is popped once.
+*/
+/* Opcode: IdxLT P1 P2 *
+**
+** Compare the top of the stack against the key on the index entry that
+** cursor P1 is currently pointing to. Ignore the last 4 bytes of the
+** index entry. If the index entry is less than the top of the stack
+** then jump to P2. Otherwise fall through to the next instruction.
+** In either case, the stack is popped once.
+*/
+case OP_IdxLT:
+case OP_IdxGT:
+case OP_IdxGE: {
+ int i= pOp->p1;
+ BtCursor *pCrsr;
+
+ assert( i>=0 && i<p->nCursor );
+ assert( pTos>=p->aStack );
+ if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
+ int res, rc;
+
+ Stringify(pTos);
+ assert( p->aCsr[i].deferredMoveto==0 );
+ rc = sqliteBtreeKeyCompare(pCrsr, pTos->z, pTos->n, 4, &res);
+ if( rc!=STQLITE_OK ){
+ break;
+ }
+ if( pOp->opcode==OP_IdxLT ){
+ res = -res;
+ }else if( pOp->opcode==OP_IdxGE ){
+ res++;
+ }
+ if( res>0 ){
+ pc = pOp->p2 - 1 ;
+ }
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: IdxIsNull P1 P2 *
+**
+** The top of the stack tqcontains an index entry such as might be generated
+** by the MakeIdxKey opcode. This routine looks at the first P1 fields of
+** that key. If any of the first P1 fields are NULL, then a jump is made
+** to address P2. Otherwise we fall straight through.
+**
+** The index entry is always popped from the stack.
+*/
+case OP_IdxIsNull: {
+ int i = pOp->p1;
+ int k, n;
+ const char *z;
+
+ assert( pTos>=p->aStack );
+ assert( pTos->flags & MEM_Str );
+ z = pTos->z;
+ n = pTos->n;
+ for(k=0; k<n && i>0; i--){
+ if( z[k]=='a' ){
+ pc = pOp->p2-1;
+ break;
+ }
+ while( k<n && z[k] ){ k++; }
+ k++;
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: Destroy P1 P2 *
+**
+** Delete an entire database table or index whose root page in the database
+** file is given by P1.
+**
+** The table being destroyed is in the main database file if P2==0. If
+** P2==1 then the table to be clear is in the auxiliary database file
+** that is used to store tables create using CREATE TEMPORARY TABLE.
+**
+** See also: Clear
+*/
+case OP_Destroy: {
+ rc = sqliteBtreeDropTable(db->aDb[pOp->p2].pBt, pOp->p1);
+ break;
+}
+
+/* Opcode: Clear P1 P2 *
+**
+** Delete all contents of the database table or index whose root page
+** in the database file is given by P1. But, unlike Destroy, do not
+** remove the table or index from the database file.
+**
+** The table being clear is in the main database file if P2==0. If
+** P2==1 then the table to be clear is in the auxiliary database file
+** that is used to store tables create using CREATE TEMPORARY TABLE.
+**
+** See also: Destroy
+*/
+case OP_Clear: {
+ rc = sqliteBtreeClearTable(db->aDb[pOp->p2].pBt, pOp->p1);
+ break;
+}
+
+/* Opcode: CreateTable * P2 P3
+**
+** Allocate a new table in the main database file if P2==0 or in the
+** auxiliary database file if P2==1. Push the page number
+** for the root page of the new table onto the stack.
+**
+** The root page number is also written to a memory location that P3
+** points to. This is the mechanism is used to write the root page
+** number into the parser's internal data structures that describe the
+** new table.
+**
+** The difference between a table and an index is this: A table must
+** have a 4-byte integer key and can have arbitrary data. An index
+** has an arbitrary key but no data.
+**
+** See also: CreateIndex
+*/
+/* Opcode: CreateIndex * P2 P3
+**
+** Allocate a new index in the main database file if P2==0 or in the
+** auxiliary database file if P2==1. Push the page number of the
+** root page of the new index onto the stack.
+**
+** See documentation on OP_CreateTable for additional information.
+*/
+case OP_CreateIndex:
+case OP_CreateTable: {
+ int pgno;
+ assert( pOp->p3!=0 && pOp->p3type==P3_POINTER );
+ assert( pOp->p2>=0 && pOp->p2<db->nDb );
+ assert( db->aDb[pOp->p2].pBt!=0 );
+ if( pOp->opcode==OP_CreateTable ){
+ rc = sqliteBtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno);
+ }else{
+ rc = sqliteBtreeCreateIndex(db->aDb[pOp->p2].pBt, &pgno);
+ }
+ pTos++;
+ if( rc==STQLITE_OK ){
+ pTos->i = pgno;
+ pTos->flags = MEM_Int;
+ *(u32*)pOp->p3 = pgno;
+ pOp->p3 = 0;
+ }else{
+ pTos->flags = MEM_Null;
+ }
+ break;
+}
+
+/* Opcode: IntegrityCk P1 P2 *
+**
+** Do an analysis of the currently open database. Push onto the
+** stack the text of an error message describing any problems.
+** If there are no errors, push a "ok" onto the stack.
+**
+** P1 is the index of a set that tqcontains the root page numbers
+** for all tables and indices in the main database file. The set
+** is cleared by this opcode. In other words, after this opcode
+** has executed, the set will be empty.
+**
+** If P2 is not zero, the check is done on the auxiliary database
+** file, not the main database file.
+**
+** This opcode is used for testing purposes only.
+*/
+case OP_IntegrityCk: {
+ int nRoot;
+ int *aRoot;
+ int iSet = pOp->p1;
+ Set *pSet;
+ int j;
+ HashElem *i;
+ char *z;
+
+ assert( iSet>=0 && iSet<p->nSet );
+ pTos++;
+ pSet = &p->aSet[iSet];
+ nRoot = sqliteHashCount(&pSet->hash);
+ aRoot = sqliteMallocRaw( sizeof(int)*(nRoot+1) );
+ if( aRoot==0 ) goto no_mem;
+ for(j=0, i=sqliteHashFirst(&pSet->hash); i; i=sqliteHashNext(i), j++){
+ toInt((char*)sqliteHashKey(i), &aRoot[j]);
+ }
+ aRoot[j] = 0;
+ sqliteHashClear(&pSet->hash);
+ pSet->prev = 0;
+ z = sqliteBtreeIntegrityCheck(db->aDb[pOp->p2].pBt, aRoot, nRoot);
+ if( z==0 || z[0]==0 ){
+ if( z ) sqliteFree(z);
+ pTos->z = "ok";
+ pTos->n = 3;
+ pTos->flags = MEM_Str | MEM_Static;
+ }else{
+ pTos->z = z;
+ pTos->n = strlen(z) + 1;
+ pTos->flags = MEM_Str | MEM_Dyn;
+ }
+ sqliteFree(aRoot);
+ break;
+}
+
+/* Opcode: ListWrite * * *
+**
+** Write the integer on the top of the stack
+** into the temporary storage list.
+*/
+case OP_ListWrite: {
+ Keylist *pKeylist;
+ assert( pTos>=p->aStack );
+ pKeylist = p->pList;
+ if( pKeylist==0 || pKeylist->nUsed>=pKeylist->nKey ){
+ pKeylist = sqliteMallocRaw( sizeof(Keylist)+999*sizeof(pKeylist->aKey[0]) );
+ if( pKeylist==0 ) goto no_mem;
+ pKeylist->nKey = 1000;
+ pKeylist->nRead = 0;
+ pKeylist->nUsed = 0;
+ pKeylist->pNext = p->pList;
+ p->pList = pKeylist;
+ }
+ Integerify(pTos);
+ pKeylist->aKey[pKeylist->nUsed++] = pTos->i;
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: ListRewind * * *
+**
+** Rewind the temporary buffer back to the beginning.
+*/
+case OP_ListRewind: {
+ /* What this opcode codes, really, is reverse the order of the
+ ** linked list of Keylist structures so that they are read out
+ ** in the same order that they were read in. */
+ Keylist *pRev, *pTop;
+ pRev = 0;
+ while( p->pList ){
+ pTop = p->pList;
+ p->pList = pTop->pNext;
+ pTop->pNext = pRev;
+ pRev = pTop;
+ }
+ p->pList = pRev;
+ break;
+}
+
+/* Opcode: ListRead * P2 *
+**
+** Attempt to read an integer from the temporary storage buffer
+** and push it onto the stack. If the storage buffer is empty,
+** push nothing but instead jump to P2.
+*/
+case OP_ListRead: {
+ Keylist *pKeylist;
+ CHECK_FOR_INTERRUPT;
+ pKeylist = p->pList;
+ if( pKeylist!=0 ){
+ assert( pKeylist->nRead>=0 );
+ assert( pKeylist->nRead<pKeylist->nUsed );
+ assert( pKeylist->nRead<pKeylist->nKey );
+ pTos++;
+ pTos->i = pKeylist->aKey[pKeylist->nRead++];
+ pTos->flags = MEM_Int;
+ if( pKeylist->nRead>=pKeylist->nUsed ){
+ p->pList = pKeylist->pNext;
+ sqliteFree(pKeylist);
+ }
+ }else{
+ pc = pOp->p2 - 1;
+ }
+ break;
+}
+
+/* Opcode: ListReset * * *
+**
+** Reset the temporary storage buffer so that it holds nothing.
+*/
+case OP_ListReset: {
+ if( p->pList ){
+ sqliteVdbeKeylistFree(p->pList);
+ p->pList = 0;
+ }
+ break;
+}
+
+/* Opcode: ListPush * * *
+**
+** Save the current Vdbe list such that it can be restored by a ListPop
+** opcode. The list is empty after this is executed.
+*/
+case OP_ListPush: {
+ p->keylistStackDepth++;
+ assert(p->keylistStackDepth > 0);
+ p->keylistStack = sqliteRealloc(p->keylistStack,
+ sizeof(Keylist *) * p->keylistStackDepth);
+ if( p->keylistStack==0 ) goto no_mem;
+ p->keylistStack[p->keylistStackDepth - 1] = p->pList;
+ p->pList = 0;
+ break;
+}
+
+/* Opcode: ListPop * * *
+**
+** Restore the Vdbe list to the state it was in when ListPush was last
+** executed.
+*/
+case OP_ListPop: {
+ assert(p->keylistStackDepth > 0);
+ p->keylistStackDepth--;
+ sqliteVdbeKeylistFree(p->pList);
+ p->pList = p->keylistStack[p->keylistStackDepth];
+ p->keylistStack[p->keylistStackDepth] = 0;
+ if( p->keylistStackDepth == 0 ){
+ sqliteFree(p->keylistStack);
+ p->keylistStack = 0;
+ }
+ break;
+}
+
+/* Opcode: ContextPush * * *
+**
+** Save the current Vdbe context such that it can be restored by a ContextPop
+** opcode. The context stores the last insert row id, the last statement change
+** count, and the current statement change count.
+*/
+case OP_ContextPush: {
+ p->contextStackDepth++;
+ assert(p->contextStackDepth > 0);
+ p->contextStack = sqliteRealloc(p->contextStack,
+ sizeof(Context) * p->contextStackDepth);
+ if( p->contextStack==0 ) goto no_mem;
+ p->contextStack[p->contextStackDepth - 1].lastRowid = p->db->lastRowid;
+ p->contextStack[p->contextStackDepth - 1].lsChange = p->db->lsChange;
+ p->contextStack[p->contextStackDepth - 1].csChange = p->db->csChange;
+ break;
+}
+
+/* Opcode: ContextPop * * *
+**
+** Restore the Vdbe context to the state it was in when contextPush was last
+** executed. The context stores the last insert row id, the last statement
+** change count, and the current statement change count.
+*/
+case OP_ContextPop: {
+ assert(p->contextStackDepth > 0);
+ p->contextStackDepth--;
+ p->db->lastRowid = p->contextStack[p->contextStackDepth].lastRowid;
+ p->db->lsChange = p->contextStack[p->contextStackDepth].lsChange;
+ p->db->csChange = p->contextStack[p->contextStackDepth].csChange;
+ if( p->contextStackDepth == 0 ){
+ sqliteFree(p->contextStack);
+ p->contextStack = 0;
+ }
+ break;
+}
+
+/* Opcode: SortPut * * *
+**
+** The TOS is the key and the NOS is the data. Pop both from the stack
+** and put them on the sorter. The key and data should have been
+** made using SortMakeKey and SortMakeRec, respectively.
+*/
+case OP_SortPut: {
+ Mem *pNos = &pTos[-1];
+ Sorter *pSorter;
+ assert( pNos>=p->aStack );
+ if( Dynamicify(pTos) || Dynamicify(pNos) ) goto no_mem;
+ pSorter = sqliteMallocRaw( sizeof(Sorter) );
+ if( pSorter==0 ) goto no_mem;
+ pSorter->pNext = p->pSort;
+ p->pSort = pSorter;
+ assert( pTos->flags & MEM_Dyn );
+ pSorter->nKey = pTos->n;
+ pSorter->zKey = pTos->z;
+ assert( pNos->flags & MEM_Dyn );
+ pSorter->nData = pNos->n;
+ pSorter->pData = pNos->z;
+ pTos -= 2;
+ break;
+}
+
+/* Opcode: SortMakeRec P1 * *
+**
+** The top P1 elements are the arguments to a callback. Form these
+** elements into a single data entry that can be stored on a sorter
+** using SortPut and later fed to a callback using SortCallback.
+*/
+case OP_SortMakeRec: {
+ char *z;
+ char **azArg;
+ int nByte;
+ int nField;
+ int i;
+ Mem *pRec;
+
+ nField = pOp->p1;
+ pRec = &pTos[1-nField];
+ assert( pRec>=p->aStack );
+ nByte = 0;
+ for(i=0; i<nField; i++, pRec++){
+ if( (pRec->flags & MEM_Null)==0 ){
+ Stringify(pRec);
+ nByte += pRec->n;
+ }
+ }
+ nByte += sizeof(char*)*(nField+1);
+ azArg = sqliteMallocRaw( nByte );
+ if( azArg==0 ) goto no_mem;
+ z = (char*)&azArg[nField+1];
+ for(pRec=&pTos[1-nField], i=0; i<nField; i++, pRec++){
+ if( pRec->flags & MEM_Null ){
+ azArg[i] = 0;
+ }else{
+ azArg[i] = z;
+ memcpy(z, pRec->z, pRec->n);
+ z += pRec->n;
+ }
+ }
+ popStack(&pTos, nField);
+ pTos++;
+ pTos->n = nByte;
+ pTos->z = (char*)azArg;
+ pTos->flags = MEM_Str | MEM_Dyn;
+ break;
+}
+
+/* Opcode: SortMakeKey * * P3
+**
+** Convert the top few entries of the stack into a sort key. The
+** number of stack entries consumed is the number of characters in
+** the string P3. One character from P3 is prepended to each entry.
+** The first character of P3 is prepended to the element lowest in
+** the stack and the last character of P3 is prepended to the top of
+** the stack. All stack entries are separated by a \000 character
+** in the result. The whole key is terminated by two \000 characters
+** in a row.
+**
+** "N" is substituted in place of the P3 character for NULL values.
+**
+** See also the MakeKey and MakeIdxKey opcodes.
+*/
+case OP_SortMakeKey: {
+ char *zNewKey;
+ int nByte;
+ int nField;
+ int i, j, k;
+ Mem *pRec;
+
+ nField = strlen(pOp->p3);
+ pRec = &pTos[1-nField];
+ nByte = 1;
+ for(i=0; i<nField; i++, pRec++){
+ if( pRec->flags & MEM_Null ){
+ nByte += 2;
+ }else{
+ Stringify(pRec);
+ nByte += pRec->n+2;
+ }
+ }
+ zNewKey = sqliteMallocRaw( nByte );
+ if( zNewKey==0 ) goto no_mem;
+ j = 0;
+ k = 0;
+ for(pRec=&pTos[1-nField], i=0; i<nField; i++, pRec++){
+ if( pRec->flags & MEM_Null ){
+ zNewKey[j++] = 'N';
+ zNewKey[j++] = 0;
+ k++;
+ }else{
+ zNewKey[j++] = pOp->p3[k++];
+ memcpy(&zNewKey[j], pRec->z, pRec->n-1);
+ j += pRec->n-1;
+ zNewKey[j++] = 0;
+ }
+ }
+ zNewKey[j] = 0;
+ assert( j<nByte );
+ popStack(&pTos, nField);
+ pTos++;
+ pTos->n = nByte;
+ pTos->flags = MEM_Str|MEM_Dyn;
+ pTos->z = zNewKey;
+ break;
+}
+
+/* Opcode: Sort * * *
+**
+** Sort all elements on the sorter. The algorithm is a
+** mergesort.
+*/
+case OP_Sort: {
+ int i;
+ Sorter *pElem;
+ Sorter *apSorter[NSORT];
+ for(i=0; i<NSORT; i++){
+ apSorter[i] = 0;
+ }
+ while( p->pSort ){
+ pElem = p->pSort;
+ p->pSort = pElem->pNext;
+ pElem->pNext = 0;
+ for(i=0; i<NSORT-1; i++){
+ if( apSorter[i]==0 ){
+ apSorter[i] = pElem;
+ break;
+ }else{
+ pElem = Merge(apSorter[i], pElem);
+ apSorter[i] = 0;
+ }
+ }
+ if( i>=NSORT-1 ){
+ apSorter[NSORT-1] = Merge(apSorter[NSORT-1],pElem);
+ }
+ }
+ pElem = 0;
+ for(i=0; i<NSORT; i++){
+ pElem = Merge(apSorter[i], pElem);
+ }
+ p->pSort = pElem;
+ break;
+}
+
+/* Opcode: SortNext * P2 *
+**
+** Push the data for the topmost element in the sorter onto the
+** stack, then remove the element from the sorter. If the sorter
+** is empty, push nothing on the stack and instead jump immediately
+** to instruction P2.
+*/
+case OP_SortNext: {
+ Sorter *pSorter = p->pSort;
+ CHECK_FOR_INTERRUPT;
+ if( pSorter!=0 ){
+ p->pSort = pSorter->pNext;
+ pTos++;
+ pTos->z = pSorter->pData;
+ pTos->n = pSorter->nData;
+ pTos->flags = MEM_Str|MEM_Dyn;
+ sqliteFree(pSorter->zKey);
+ sqliteFree(pSorter);
+ }else{
+ pc = pOp->p2 - 1;
+ }
+ break;
+}
+
+/* Opcode: SortCallback P1 * *
+**
+** The top of the stack tqcontains a callback record built using
+** the SortMakeRec operation with the same P1 value as this
+** instruction. Pop this record from the stack and invoke the
+** callback on it.
+*/
+case OP_SortCallback: {
+ assert( pTos>=p->aStack );
+ assert( pTos->flags & MEM_Str );
+ p->nCallback++;
+ p->pc = pc+1;
+ p->azResColumn = (char**)pTos->z;
+ assert( p->nResColumn==pOp->p1 );
+ p->popStack = 1;
+ p->pTos = pTos;
+ return STQLITE_ROW;
+}
+
+/* Opcode: SortReset * * *
+**
+** Remove any elements that remain on the sorter.
+*/
+case OP_SortReset: {
+ sqliteVdbeSorterReset(p);
+ break;
+}
+
+/* Opcode: FileOpen * * P3
+**
+** Open the file named by P3 for reading using the FileRead opcode.
+** If P3 is "stdin" then open standard input for reading.
+*/
+case OP_FileOpen: {
+ assert( pOp->p3!=0 );
+ if( p->pFile ){
+ if( p->pFile!=stdin ) fclose(p->pFile);
+ p->pFile = 0;
+ }
+ if( sqliteStrICmp(pOp->p3,"stdin")==0 ){
+ p->pFile = stdin;
+ }else{
+ p->pFile = fopen(pOp->p3, "r");
+ }
+ if( p->pFile==0 ){
+ sqliteSetString(&p->zErrMsg,"unable to open file: ", pOp->p3, (char*)0);
+ rc = STQLITE_ERROR;
+ }
+ break;
+}
+
+/* Opcode: FileRead P1 P2 P3
+**
+** Read a single line of input from the open file (the file opened using
+** FileOpen). If we reach end-of-file, jump immediately to P2. If
+** we are able to get another line, split the line apart using P3 as
+** a delimiter. There should be P1 fields. If the input line tqcontains
+** more than P1 fields, ignore the excess. If the input line tqcontains
+** fewer than P1 fields, assume the remaining fields contain NULLs.
+**
+** Input ends if a line consists of just "\.". A field containing only
+** "\N" is a null field. The backslash \ character can be used be used
+** to escape newlines or the delimiter.
+*/
+case OP_FileRead: {
+ int n, eol, nField, i, c, nDelim;
+ char *zDelim, *z;
+ CHECK_FOR_INTERRUPT;
+ if( p->pFile==0 ) goto fileread_jump;
+ nField = pOp->p1;
+ if( nField<=0 ) goto fileread_jump;
+ if( nField!=p->nField || p->azField==0 ){
+ char **azField = sqliteRealloc(p->azField, sizeof(char*)*nField+1);
+ if( azField==0 ){ goto no_mem; }
+ p->azField = azField;
+ p->nField = nField;
+ }
+ n = 0;
+ eol = 0;
+ while( eol==0 ){
+ if( p->zLine==0 || n+200>p->nLineAlloc ){
+ char *zLine;
+ p->nLineAlloc = p->nLineAlloc*2 + 300;
+ zLine = sqliteRealloc(p->zLine, p->nLineAlloc);
+ if( zLine==0 ){
+ p->nLineAlloc = 0;
+ sqliteFree(p->zLine);
+ p->zLine = 0;
+ goto no_mem;
+ }
+ p->zLine = zLine;
+ }
+ if( vdbe_fgets(&p->zLine[n], p->nLineAlloc-n, p->pFile)==0 ){
+ eol = 1;
+ p->zLine[n] = 0;
+ }else{
+ int c;
+ while( (c = p->zLine[n])!=0 ){
+ if( c=='\\' ){
+ if( p->zLine[n+1]==0 ) break;
+ n += 2;
+ }else if( c=='\n' ){
+ p->zLine[n] = 0;
+ eol = 1;
+ break;
+ }else{
+ n++;
+ }
+ }
+ }
+ }
+ if( n==0 ) goto fileread_jump;
+ z = p->zLine;
+ if( z[0]=='\\' && z[1]=='.' && z[2]==0 ){
+ goto fileread_jump;
+ }
+ zDelim = pOp->p3;
+ if( zDelim==0 ) zDelim = "\t";
+ c = zDelim[0];
+ nDelim = strlen(zDelim);
+ p->azField[0] = z;
+ for(i=1; *z!=0 && i<=nField; i++){
+ int from, to;
+ from = to = 0;
+ if( z[0]=='\\' && z[1]=='N'
+ && (z[2]==0 || strncmp(&z[2],zDelim,nDelim)==0) ){
+ if( i<=nField ) p->azField[i-1] = 0;
+ z += 2 + nDelim;
+ if( i<nField ) p->azField[i] = z;
+ continue;
+ }
+ while( z[from] ){
+ if( z[from]=='\\' && z[from+1]!=0 ){
+ int tx = z[from+1];
+ switch( tx ){
+ case 'b': tx = '\b'; break;
+ case 'f': tx = '\f'; break;
+ case 'n': tx = '\n'; break;
+ case 'r': tx = '\r'; break;
+ case 't': tx = '\t'; break;
+ case 'v': tx = '\v'; break;
+ default: break;
+ }
+ z[to++] = tx;
+ from += 2;
+ continue;
+ }
+ if( z[from]==c && strncmp(&z[from],zDelim,nDelim)==0 ) break;
+ z[to++] = z[from++];
+ }
+ if( z[from] ){
+ z[to] = 0;
+ z += from + nDelim;
+ if( i<nField ) p->azField[i] = z;
+ }else{
+ z[to] = 0;
+ z = "";
+ }
+ }
+ while( i<nField ){
+ p->azField[i++] = 0;
+ }
+ break;
+
+ /* If we reach end-of-file, or if anything goes wrong, jump here.
+ ** This code will cause a jump to P2 */
+fileread_jump:
+ pc = pOp->p2 - 1;
+ break;
+}
+
+/* Opcode: FileColumn P1 * *
+**
+** Push onto the stack the P1-th column of the most recently read line
+** from the input file.
+*/
+case OP_FileColumn: {
+ int i = pOp->p1;
+ char *z;
+ assert( i>=0 && i<p->nField );
+ if( p->azField ){
+ z = p->azField[i];
+ }else{
+ z = 0;
+ }
+ pTos++;
+ if( z ){
+ pTos->n = strlen(z) + 1;
+ pTos->z = z;
+ pTos->flags = MEM_Str | MEM_Ephem;
+ }else{
+ pTos->flags = MEM_Null;
+ }
+ break;
+}
+
+/* Opcode: MemStore P1 P2 *
+**
+** Write the top of the stack into memory location P1.
+** P1 should be a small integer since space is allocated
+** for all memory locations between 0 and P1 inclusive.
+**
+** After the data is stored in the memory location, the
+** stack is popped once if P2 is 1. If P2 is zero, then
+** the original data remains on the stack.
+*/
+case OP_MemStore: {
+ int i = pOp->p1;
+ Mem *pMem;
+ assert( pTos>=p->aStack );
+ if( i>=p->nMem ){
+ int nOld = p->nMem;
+ Mem *aMem;
+ p->nMem = i + 5;
+ aMem = sqliteRealloc(p->aMem, p->nMem*sizeof(p->aMem[0]));
+ if( aMem==0 ) goto no_mem;
+ if( aMem!=p->aMem ){
+ int j;
+ for(j=0; j<nOld; j++){
+ if( aMem[j].flags & MEM_Short ){
+ aMem[j].z = aMem[j].zShort;
+ }
+ }
+ }
+ p->aMem = aMem;
+ if( nOld<p->nMem ){
+ memset(&p->aMem[nOld], 0, sizeof(p->aMem[0])*(p->nMem-nOld));
+ }
+ }
+ Deephemeralize(pTos);
+ pMem = &p->aMem[i];
+ Release(pMem);
+ *pMem = *pTos;
+ if( pMem->flags & MEM_Dyn ){
+ if( pOp->p2 ){
+ pTos->flags = MEM_Null;
+ }else{
+ pMem->z = sqliteMallocRaw( pMem->n );
+ if( pMem->z==0 ) goto no_mem;
+ memcpy(pMem->z, pTos->z, pMem->n);
+ }
+ }else if( pMem->flags & MEM_Short ){
+ pMem->z = pMem->zShort;
+ }
+ if( pOp->p2 ){
+ Release(pTos);
+ pTos--;
+ }
+ break;
+}
+
+/* Opcode: MemLoad P1 * *
+**
+** Push a copy of the value in memory location P1 onto the stack.
+**
+** If the value is a string, then the value pushed is a pointer to
+** the string that is stored in the memory location. If the memory
+** location is subsequently changed (using OP_MemStore) then the
+** value pushed onto the stack will change too.
+*/
+case OP_MemLoad: {
+ int i = pOp->p1;
+ assert( i>=0 && i<p->nMem );
+ pTos++;
+ memcpy(pTos, &p->aMem[i], sizeof(pTos[0])-NBFS);;
+ if( pTos->flags & MEM_Str ){
+ pTos->flags |= MEM_Ephem;
+ pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
+ }
+ break;
+}
+
+/* Opcode: MemIncr P1 P2 *
+**
+** Increment the integer valued memory cell P1 by 1. If P2 is not zero
+** and the result after the increment is greater than zero, then jump
+** to P2.
+**
+** This instruction throws an error if the memory cell is not initially
+** an integer.
+*/
+case OP_MemIncr: {
+ int i = pOp->p1;
+ Mem *pMem;
+ assert( i>=0 && i<p->nMem );
+ pMem = &p->aMem[i];
+ assert( pMem->flags==MEM_Int );
+ pMem->i++;
+ if( pOp->p2>0 && pMem->i>0 ){
+ pc = pOp->p2 - 1;
+ }
+ break;
+}
+
+/* Opcode: AggReset * P2 *
+**
+** Reset the aggregator so that it no longer tqcontains any data.
+** Future aggregator elements will contain P2 values each.
+*/
+case OP_AggReset: {
+ sqliteVdbeAggReset(&p->agg);
+ p->agg.nMem = pOp->p2;
+ p->agg.apFunc = sqliteMalloc( p->agg.nMem*sizeof(p->agg.apFunc[0]) );
+ if( p->agg.apFunc==0 ) goto no_mem;
+ break;
+}
+
+/* Opcode: AggInit * P2 P3
+**
+** Initialize the function parameters for an aggregate function.
+** The aggregate will operate out of aggregate column P2.
+** P3 is a pointer to the FuncDef structure for the function.
+*/
+case OP_AggInit: {
+ int i = pOp->p2;
+ assert( i>=0 && i<p->agg.nMem );
+ p->agg.apFunc[i] = (FuncDef*)pOp->p3;
+ break;
+}
+
+/* Opcode: AggFunc * P2 P3
+**
+** Execute the step function for an aggregate. The
+** function has P2 arguments. P3 is a pointer to the FuncDef
+** structure that specifies the function.
+**
+** The top of the stack must be an integer which is the index of
+** the aggregate column that corresponds to this aggregate function.
+** Ideally, this index would be another parameter, but there are
+** no free parameters left. The integer is popped from the stack.
+*/
+case OP_AggFunc: {
+ int n = pOp->p2;
+ int i;
+ Mem *pMem, *pRec;
+ char **azArgv = p->zArgv;
+ sqlite_func ctx;
+
+ assert( n>=0 );
+ assert( pTos->flags==MEM_Int );
+ pRec = &pTos[-n];
+ assert( pRec>=p->aStack );
+ for(i=0; i<n; i++, pRec++){
+ if( pRec->flags & MEM_Null ){
+ azArgv[i] = 0;
+ }else{
+ Stringify(pRec);
+ azArgv[i] = pRec->z;
+ }
+ }
+ i = pTos->i;
+ assert( i>=0 && i<p->agg.nMem );
+ ctx.pFunc = (FuncDef*)pOp->p3;
+ pMem = &p->agg.pCurrent->aMem[i];
+ ctx.s.z = pMem->zShort; /* Space used for small aggregate contexts */
+ ctx.pAgg = pMem->z;
+ ctx.cnt = ++pMem->i;
+ ctx.isError = 0;
+ ctx.isStep = 1;
+ (ctx.pFunc->xStep)(&ctx, n, (const char**)azArgv);
+ pMem->z = ctx.pAgg;
+ pMem->flags = MEM_AggCtx;
+ popStack(&pTos, n+1);
+ if( ctx.isError ){
+ rc = STQLITE_ERROR;
+ }
+ break;
+}
+
+/* Opcode: AggFocus * P2 *
+**
+** Pop the top of the stack and use that as an aggregator key. If
+** an aggregator with that same key already exists, then make the
+** aggregator the current aggregator and jump to P2. If no aggregator
+** with the given key exists, create one and make it current but
+** do not jump.
+**
+** The order of aggregator opcodes is important. The order is:
+** AggReset AggFocus AggNext. In other words, you must execute
+** AggReset first, then zero or more AggFocus operations, then
+** zero or more AggNext operations. You must not execute an AggFocus
+** in between an AggNext and an AggReset.
+*/
+case OP_AggFocus: {
+ AggElem *pElem;
+ char *zKey;
+ int nKey;
+
+ assert( pTos>=p->aStack );
+ Stringify(pTos);
+ zKey = pTos->z;
+ nKey = pTos->n;
+ pElem = sqliteHashFind(&p->agg.hash, zKey, nKey);
+ if( pElem ){
+ p->agg.pCurrent = pElem;
+ pc = pOp->p2 - 1;
+ }else{
+ AggInsert(&p->agg, zKey, nKey);
+ if( sqlite_malloc_failed ) goto no_mem;
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: AggSet * P2 *
+**
+** Move the top of the stack into the P2-th field of the current
+** aggregate. String values are duplicated into new memory.
+*/
+case OP_AggSet: {
+ AggElem *pFocus = AggInFocus(p->agg);
+ Mem *pMem;
+ int i = pOp->p2;
+ assert( pTos>=p->aStack );
+ if( pFocus==0 ) goto no_mem;
+ assert( i>=0 && i<p->agg.nMem );
+ Deephemeralize(pTos);
+ pMem = &pFocus->aMem[i];
+ Release(pMem);
+ *pMem = *pTos;
+ if( pMem->flags & MEM_Dyn ){
+ pTos->flags = MEM_Null;
+ }else if( pMem->flags & MEM_Short ){
+ pMem->z = pMem->zShort;
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: AggGet * P2 *
+**
+** Push a new entry onto the stack which is a copy of the P2-th field
+** of the current aggregate. Strings are not duplicated so
+** string values will be ephemeral.
+*/
+case OP_AggGet: {
+ AggElem *pFocus = AggInFocus(p->agg);
+ Mem *pMem;
+ int i = pOp->p2;
+ if( pFocus==0 ) goto no_mem;
+ assert( i>=0 && i<p->agg.nMem );
+ pTos++;
+ pMem = &pFocus->aMem[i];
+ *pTos = *pMem;
+ if( pTos->flags & MEM_Str ){
+ pTos->flags &= ~(MEM_Dyn|MEM_Static|MEM_Short);
+ pTos->flags |= MEM_Ephem;
+ }
+ break;
+}
+
+/* Opcode: AggNext * P2 *
+**
+** Make the next aggregate value the current aggregate. The prior
+** aggregate is deleted. If all aggregate values have been consumed,
+** jump to P2.
+**
+** The order of aggregator opcodes is important. The order is:
+** AggReset AggFocus AggNext. In other words, you must execute
+** AggReset first, then zero or more AggFocus operations, then
+** zero or more AggNext operations. You must not execute an AggFocus
+** in between an AggNext and an AggReset.
+*/
+case OP_AggNext: {
+ CHECK_FOR_INTERRUPT;
+ if( p->agg.pSearch==0 ){
+ p->agg.pSearch = sqliteHashFirst(&p->agg.hash);
+ }else{
+ p->agg.pSearch = sqliteHashNext(p->agg.pSearch);
+ }
+ if( p->agg.pSearch==0 ){
+ pc = pOp->p2 - 1;
+ } else {
+ int i;
+ sqlite_func ctx;
+ Mem *aMem;
+ p->agg.pCurrent = sqliteHashData(p->agg.pSearch);
+ aMem = p->agg.pCurrent->aMem;
+ for(i=0; i<p->agg.nMem; i++){
+ int freeCtx;
+ if( p->agg.apFunc[i]==0 ) continue;
+ if( p->agg.apFunc[i]->xFinalize==0 ) continue;
+ ctx.s.flags = MEM_Null;
+ ctx.s.z = aMem[i].zShort;
+ ctx.pAgg = (void*)aMem[i].z;
+ freeCtx = aMem[i].z && aMem[i].z!=aMem[i].zShort;
+ ctx.cnt = aMem[i].i;
+ ctx.isStep = 0;
+ ctx.pFunc = p->agg.apFunc[i];
+ (*p->agg.apFunc[i]->xFinalize)(&ctx);
+ if( freeCtx ){
+ sqliteFree( aMem[i].z );
+ }
+ aMem[i] = ctx.s;
+ if( aMem[i].flags & MEM_Short ){
+ aMem[i].z = aMem[i].zShort;
+ }
+ }
+ }
+ break;
+}
+
+/* Opcode: SetInsert P1 * P3
+**
+** If Set P1 does not exist then create it. Then insert value
+** P3 into that set. If P3 is NULL, then insert the top of the
+** stack into the set.
+*/
+case OP_SetInsert: {
+ int i = pOp->p1;
+ if( p->nSet<=i ){
+ int k;
+ Set *aSet = sqliteRealloc(p->aSet, (i+1)*sizeof(p->aSet[0]) );
+ if( aSet==0 ) goto no_mem;
+ p->aSet = aSet;
+ for(k=p->nSet; k<=i; k++){
+ sqliteHashInit(&p->aSet[k].hash, STQLITE_HASH_BINARY, 1);
+ }
+ p->nSet = i+1;
+ }
+ if( pOp->p3 ){
+ sqliteHashInsert(&p->aSet[i].hash, pOp->p3, strlen(pOp->p3)+1, p);
+ }else{
+ assert( pTos>=p->aStack );
+ Stringify(pTos);
+ sqliteHashInsert(&p->aSet[i].hash, pTos->z, pTos->n, p);
+ Release(pTos);
+ pTos--;
+ }
+ if( sqlite_malloc_failed ) goto no_mem;
+ break;
+}
+
+/* Opcode: SetFound P1 P2 *
+**
+** Pop the stack once and compare the value popped off with the
+** contents of set P1. If the element popped exists in set P1,
+** then jump to P2. Otherwise fall through.
+*/
+case OP_SetFound: {
+ int i = pOp->p1;
+ assert( pTos>=p->aStack );
+ Stringify(pTos);
+ if( i>=0 && i<p->nSet && sqliteHashFind(&p->aSet[i].hash, pTos->z, pTos->n)){
+ pc = pOp->p2 - 1;
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: SetNotFound P1 P2 *
+**
+** Pop the stack once and compare the value popped off with the
+** contents of set P1. If the element popped does not exists in
+** set P1, then jump to P2. Otherwise fall through.
+*/
+case OP_SetNotFound: {
+ int i = pOp->p1;
+ assert( pTos>=p->aStack );
+ Stringify(pTos);
+ if( i<0 || i>=p->nSet ||
+ sqliteHashFind(&p->aSet[i].hash, pTos->z, pTos->n)==0 ){
+ pc = pOp->p2 - 1;
+ }
+ Release(pTos);
+ pTos--;
+ break;
+}
+
+/* Opcode: SetFirst P1 P2 *
+**
+** Read the first element from set P1 and push it onto the stack. If the
+** set is empty, push nothing and jump immediately to P2. This opcode is
+** used in combination with OP_SetNext to loop over all elements of a set.
+*/
+/* Opcode: SetNext P1 P2 *
+**
+** Read the next element from set P1 and push it onto the stack. If there
+** are no more elements in the set, do not do the push and fall through.
+** Otherwise, jump to P2 after pushing the next set element.
+*/
+case OP_SetFirst:
+case OP_SetNext: {
+ Set *pSet;
+ CHECK_FOR_INTERRUPT;
+ if( pOp->p1<0 || pOp->p1>=p->nSet ){
+ if( pOp->opcode==OP_SetFirst ) pc = pOp->p2 - 1;
+ break;
+ }
+ pSet = &p->aSet[pOp->p1];
+ if( pOp->opcode==OP_SetFirst ){
+ pSet->prev = sqliteHashFirst(&pSet->hash);
+ if( pSet->prev==0 ){
+ pc = pOp->p2 - 1;
+ break;
+ }
+ }else{
+ assert( pSet->prev );
+ pSet->prev = sqliteHashNext(pSet->prev);
+ if( pSet->prev==0 ){
+ break;
+ }else{
+ pc = pOp->p2 - 1;
+ }
+ }
+ pTos++;
+ pTos->z = sqliteHashKey(pSet->prev);
+ pTos->n = sqliteHashKeysize(pSet->prev);
+ pTos->flags = MEM_Str | MEM_Ephem;
+ break;
+}
+
+/* Opcode: Vacuum * * *
+**
+** Vacuum the entire database. This opcode will cause other virtual
+** machines to be created and run. It may not be called from within
+** a transaction.
+*/
+case OP_Vacuum: {
+ if( sqliteSafetyOff(db) ) goto abort_due_to_misuse;
+ rc = sqliteRunVacuum(&p->zErrMsg, db);
+ if( sqliteSafetyOn(db) ) goto abort_due_to_misuse;
+ break;
+}
+
+/* An other opcode is illegal...
+*/
+default: {
+ sqlite_snprintf(sizeof(zBuf),zBuf,"%d",pOp->opcode);
+ sqliteSetString(&p->zErrMsg, "unknown opcode ", zBuf, (char*)0);
+ rc = STQLITE_INTERNAL;
+ break;
+}
+
+/*****************************************************************************
+** The cases of the switch statement above this line should all be indented
+** by 6 spaces. But the left-most 6 spaces have been removed to improve the
+** readability. From this point on down, the normal indentation rules are
+** restored.
+*****************************************************************************/
+ }
+
+#ifdef VDBE_PROFILE
+ {
+ long long elapse = hwtime() - start;
+ pOp->cycles += elapse;
+ pOp->cnt++;
+#if 0
+ fprintf(stdout, "%10lld ", elapse);
+ sqliteVdbePrintOp(stdout, origPc, &p->aOp[origPc]);
+#endif
+ }
+#endif
+
+ /* The following code adds nothing to the actual functionality
+ ** of the program. It is only here for testing and debugging.
+ ** On the other hand, it does burn CPU cycles every time through
+ ** the evaluator loop. So we can leave it out when NDEBUG is defined.
+ */
+#ifndef NDEBUG
+ /* Sanity checking on the top element of the stack */
+ if( pTos>=p->aStack ){
+ assert( pTos->flags!=0 ); /* Must define some type */
+ if( pTos->flags & MEM_Str ){
+ int x = pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short);
+ assert( x!=0 ); /* Strings must define a string subtype */
+ assert( (x & (x-1))==0 ); /* Only one string subtype can be defined */
+ assert( pTos->z!=0 ); /* Strings must have a value */
+ /* Mem.z points to Mem.zShort iff the subtype is MEM_Short */
+ assert( (pTos->flags & MEM_Short)==0 || pTos->z==pTos->zShort );
+ assert( (pTos->flags & MEM_Short)!=0 || pTos->z!=pTos->zShort );
+ }else{
+ /* Cannot define a string subtype for non-string objects */
+ assert( (pTos->flags & (MEM_Static|MEM_Dyn|MEM_Ephem|MEM_Short))==0 );
+ }
+ /* MEM_Null excludes all other types */
+ assert( pTos->flags==MEM_Null || (pTos->flags&MEM_Null)==0 );
+ }
+ if( pc<-1 || pc>=p->nOp ){
+ sqliteSetString(&p->zErrMsg, "jump destination out of range", (char*)0);
+ rc = STQLITE_INTERNAL;
+ }
+ if( p->trace && pTos>=p->aStack ){
+ int i;
+ fprintf(p->trace, "Stack:");
+ for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){
+ if( pTos[i].flags & MEM_Null ){
+ fprintf(p->trace, " NULL");
+ }else if( (pTos[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
+ fprintf(p->trace, " si:%d", pTos[i].i);
+ }else if( pTos[i].flags & MEM_Int ){
+ fprintf(p->trace, " i:%d", pTos[i].i);
+ }else if( pTos[i].flags & MEM_Real ){
+ fprintf(p->trace, " r:%g", pTos[i].r);
+ }else if( pTos[i].flags & MEM_Str ){
+ int j, k;
+ char zBuf[100];
+ zBuf[0] = ' ';
+ if( pTos[i].flags & MEM_Dyn ){
+ zBuf[1] = 'z';
+ assert( (pTos[i].flags & (MEM_Static|MEM_Ephem))==0 );
+ }else if( pTos[i].flags & MEM_Static ){
+ zBuf[1] = 't';
+ assert( (pTos[i].flags & (MEM_Dyn|MEM_Ephem))==0 );
+ }else if( pTos[i].flags & MEM_Ephem ){
+ zBuf[1] = 'e';
+ assert( (pTos[i].flags & (MEM_Static|MEM_Dyn))==0 );
+ }else{
+ zBuf[1] = 's';
+ }
+ zBuf[2] = '[';
+ k = 3;
+ for(j=0; j<20 && j<pTos[i].n; j++){
+ int c = pTos[i].z[j];
+ if( c==0 && j==pTos[i].n-1 ) break;
+ if( isprint(c) && !isspace(c) ){
+ zBuf[k++] = c;
+ }else{
+ zBuf[k++] = '.';
+ }
+ }
+ zBuf[k++] = ']';
+ zBuf[k++] = 0;
+ fprintf(p->trace, "%s", zBuf);
+ }else{
+ fprintf(p->trace, " ???");
+ }
+ }
+ if( rc!=0 ) fprintf(p->trace," rc=%d",rc);
+ fprintf(p->trace,"\n");
+ }
+#endif
+ } /* The end of the for(;;) loop the loops through opcodes */
+
+ /* If we reach this point, it means that execution is finished.
+ */
+vdbe_halt:
+ if( rc ){
+ p->rc = rc;
+ rc = STQLITE_ERROR;
+ }else{
+ rc = STQLITE_DONE;
+ }
+ p->magic = VDBE_MAGIC_HALT;
+ p->pTos = pTos;
+ return rc;
+
+ /* Jump to here if a malloc() fails. It's hard to get a malloc()
+ ** to fail on a modern VM computer, so this code is untested.
+ */
+no_mem:
+ sqliteSetString(&p->zErrMsg, "out of memory", (char*)0);
+ rc = STQLITE_NOMEM;
+ goto vdbe_halt;
+
+ /* Jump to here for an STQLITE_MISUSE error.
+ */
+abort_due_to_misuse:
+ rc = STQLITE_MISUSE;
+ /* Fall thru into abort_due_to_error */
+
+ /* Jump to here for any other kind of fatal error. The "rc" variable
+ ** should hold the error number.
+ */
+abort_due_to_error:
+ if( p->zErrMsg==0 ){
+ if( sqlite_malloc_failed ) rc = STQLITE_NOMEM;
+ sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
+ }
+ goto vdbe_halt;
+
+ /* Jump to here if the sqlite_interrupt() API sets the interrupt
+ ** flag.
+ */
+abort_due_to_interrupt:
+ assert( db->flags & STQLITE_Interrupt );
+ db->flags &= ~STQLITE_Interrupt;
+ if( db->magic!=STQLITE_MAGIC_BUSY ){
+ rc = STQLITE_MISUSE;
+ }else{
+ rc = STQLITE_INTERRUPT;
+ }
+ sqliteSetString(&p->zErrMsg, sqlite_error_string(rc), (char*)0);
+ goto vdbe_halt;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/vdbe.h b/tqtinterface/qt4/src/3rdparty/sqlite/vdbe.h
new file mode 100644
index 0000000..dd8a238
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/vdbe.h
@@ -0,0 +1,112 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** Header file for the Virtual DataBase Engine (VDBE)
+**
+** This header defines the interface to the virtual database engine
+** or VDBE. The VDBE implements an abstract machine that runs a
+** simple program to access and modify the underlying database.
+**
+** $Id: vdbe.h,v 1.71 2004/02/22 20:05:02 drh Exp $
+*/
+#ifndef _STQLITE_VDBE_H_
+#define _STQLITE_VDBE_H_
+#include <stdio.h>
+
+/*
+** A single VDBE is an opaque structure named "Vdbe". Only routines
+** in the source file sqliteVdbe.c are allowed to see the insides
+** of this structure.
+*/
+typedef struct Vdbe Vdbe;
+
+/*
+** A single instruction of the virtual machine has an opcode
+** and as many as three operands. The instruction is recorded
+** as an instance of the following structure:
+*/
+struct VdbeOp {
+ u8 opcode; /* What operation to perform */
+ int p1; /* First operand */
+ int p2; /* Second parameter (often the jump destination) */
+ char *p3; /* Third parameter */
+ int p3type; /* P3_STATIC, P3_DYNAMIC or P3_POINTER */
+#ifdef VDBE_PROFILE
+ int cnt; /* Number of times this instruction was executed */
+ long long cycles; /* Total time spend executing this instruction */
+#endif
+};
+typedef struct VdbeOp VdbeOp;
+
+/*
+** A smaller version of VdbeOp used for the VdbeAddOpList() function because
+** it takes up less space.
+*/
+struct VdbeOpList {
+ u8 opcode; /* What operation to perform */
+ signed char p1; /* First operand */
+ short int p2; /* Second parameter (often the jump destination) */
+ char *p3; /* Third parameter */
+};
+typedef struct VdbeOpList VdbeOpList;
+
+/*
+** Allowed values of VdbeOp.p3type
+*/
+#define P3_NOTUSED 0 /* The P3 parameter is not used */
+#define P3_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
+#define P3_STATIC (-2) /* Pointer to a static string */
+#define P3_POINTER (-3) /* P3 is a pointer to some structure or object */
+
+/*
+** The following macro converts a relative address in the p2 field
+** of a VdbeOp structure into a negative number so that
+** sqliteVdbeAddOpList() knows that the address is relative. Calling
+** the macro again restores the address.
+*/
+#define ADDR(X) (-1-(X))
+
+/*
+** The makefile scans the vdbe.c source file and creates the "opcodes.h"
+** header file that defines a number for each opcode used by the VDBE.
+*/
+#include "opcodes.h"
+
+/*
+** Prototypes for the VDBE interface. See comments on the implementation
+** for a description of what each of these routines does.
+*/
+Vdbe *sqliteVdbeCreate(sqlite*);
+void sqliteVdbeCreateCallback(Vdbe*, int*);
+int sqliteVdbeAddOp(Vdbe*,int,int,int);
+int sqliteVdbeOp3(Vdbe*,int,int,int,const char *zP3,int);
+int sqliteVdbeCode(Vdbe*,...);
+int sqliteVdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp);
+void sqliteVdbeChangeP1(Vdbe*, int addr, int P1);
+void sqliteVdbeChangeP2(Vdbe*, int addr, int P2);
+void sqliteVdbeChangeP3(Vdbe*, int addr, const char *zP1, int N);
+void sqliteVdbeDequoteP3(Vdbe*, int addr);
+int sqliteVdbeFindOp(Vdbe*, int, int);
+VdbeOp *sqliteVdbeGetOp(Vdbe*, int);
+int sqliteVdbeMakeLabel(Vdbe*);
+void sqliteVdbeDelete(Vdbe*);
+void sqliteVdbeMakeReady(Vdbe*,int,int);
+int sqliteVdbeExec(Vdbe*);
+int sqliteVdbeList(Vdbe*);
+int sqliteVdbeFinalize(Vdbe*,char**);
+void sqliteVdbeResolveLabel(Vdbe*, int);
+int sqliteVdbeCurrentAddr(Vdbe*);
+void sqliteVdbeTrace(Vdbe*,FILE*);
+void sqliteVdbeCompressSpace(Vdbe*,int);
+int sqliteVdbeReset(Vdbe*,char **);
+int sqliteVdbeSetVariables(Vdbe*,int,const char**);
+
+#endif
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/vdbeInt.h b/tqtinterface/qt4/src/3rdparty/sqlite/vdbeInt.h
new file mode 100644
index 0000000..5a9608a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/vdbeInt.h
@@ -0,0 +1,303 @@
+/*
+** 2003 September 6
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This is the header file for information that is private to the
+** VDBE. This information used to all be at the top of the single
+** source code file "vdbe.c". When that file became too big (over
+** 6000 lines long) it was split up into several smaller files and
+** this header information was factored out.
+*/
+
+/*
+** When converting from the native format to the key format and back
+** again, in addition to changing the byte order we invert the high-order
+** bit of the most significant byte. This causes negative numbers to
+** sort before positive numbers in the memcmp() function.
+*/
+#define keyToInt(X) (sqliteVdbeByteSwap(X) ^ 0x80000000)
+#define intToKey(X) (sqliteVdbeByteSwap((X) ^ 0x80000000))
+
+/*
+** The makefile scans this source file and creates the following
+** array of string constants which are the names of all VDBE opcodes.
+** This array is defined in a separate source code file named opcode.c
+** which is automatically generated by the makefile.
+*/
+extern char *sqliteOpcodeNames[];
+
+/*
+** SQL is translated into a sequence of instructions to be
+** executed by a virtual machine. Each instruction is an instance
+** of the following structure.
+*/
+typedef struct VdbeOp Op;
+
+/*
+** Boolean values
+*/
+typedef unsigned char Bool;
+
+/*
+** A cursor is a pointer into a single BTree within a database file.
+** The cursor can seek to a BTree entry with a particular key, or
+** loop over all entries of the Btree. You can also insert new BTree
+** entries or retrieve the key or data from the entry that the cursor
+** is currently pointing to.
+**
+** Every cursor that the virtual machine has open is represented by an
+** instance of the following structure.
+**
+** If the Cursor.isTriggerRow flag is set it means that this cursor is
+** really a single row that represents the NEW or OLD pseudo-table of
+** a row trigger. The data for the row is stored in Cursor.pData and
+** the rowid is in Cursor.iKey.
+*/
+struct Cursor {
+ BtCursor *pCursor; /* The cursor structure of the backend */
+ int lastRecno; /* Last recno from a Next or NextIdx operation */
+ int nextRowid; /* Next rowid returned by OP_NewRowid */
+ Bool recnoIsValid; /* True if lastRecno is valid */
+ Bool keyAsData; /* The OP_Column command works on key instead of data */
+ Bool atFirst; /* True if pointing to first entry */
+ Bool useRandomRowid; /* Generate new record numbers semi-randomly */
+ Bool nullRow; /* True if pointing to a row with no data */
+ Bool nextRowidValid; /* True if the nextRowid field is valid */
+ Bool pseudoTable; /* This is a NEW or OLD pseudo-tables of a trigger */
+ Bool deferredMoveto; /* A call to sqliteBtreeMoveto() is needed */
+ int movetoTarget; /* Argument to the deferred sqliteBtreeMoveto() */
+ Btree *pBt; /* Separate file holding temporary table */
+ int nData; /* Number of bytes in pData */
+ char *pData; /* Data for a NEW or OLD pseudo-table */
+ int iKey; /* Key for the NEW or OLD pseudo-table row */
+};
+typedef struct Cursor Cursor;
+
+/*
+** A sorter builds a list of elements to be sorted. Each element of
+** the list is an instance of the following structure.
+*/
+typedef struct Sorter Sorter;
+struct Sorter {
+ int nKey; /* Number of bytes in the key */
+ char *zKey; /* The key by which we will sort */
+ int nData; /* Number of bytes in the data */
+ char *pData; /* The data associated with this key */
+ Sorter *pNext; /* Next in the list */
+};
+
+/*
+** Number of buckets used for merge-sort.
+*/
+#define NSORT 30
+
+/*
+** Number of bytes of string storage space available to each stack
+** layer without having to malloc. NBFS is short for Number of Bytes
+** For Strings.
+*/
+#define NBFS 32
+
+/*
+** A single level of the stack or a single memory cell
+** is an instance of the following structure.
+*/
+struct Mem {
+ int i; /* Integer value */
+ int n; /* Number of characters in string value, including '\0' */
+ int flags; /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
+ double r; /* Real value */
+ char *z; /* String value */
+ char zShort[NBFS]; /* Space for short strings */
+};
+typedef struct Mem Mem;
+
+/*
+** Allowed values for Mem.flags
+*/
+#define MEM_Null 0x0001 /* Value is NULL */
+#define MEM_Str 0x0002 /* Value is a string */
+#define MEM_Int 0x0004 /* Value is an integer */
+#define MEM_Real 0x0008 /* Value is a real number */
+#define MEM_Dyn 0x0010 /* Need to call sqliteFree() on Mem.z */
+#define MEM_Static 0x0020 /* Mem.z points to a static string */
+#define MEM_Ephem 0x0040 /* Mem.z points to an ephemeral string */
+#define MEM_Short 0x0080 /* Mem.z points to Mem.zShort */
+
+/* The following MEM_ value appears only in AggElem.aMem.s.flag fields.
+** It indicates that the corresponding AggElem.aMem.z points to a
+** aggregate function context that needs to be finalized.
+*/
+#define MEM_AggCtx 0x0100 /* Mem.z points to an agg function context */
+
+/*
+** The "context" argument for a installable function. A pointer to an
+** instance of this structure is the first argument to the routines used
+** implement the SQL functions.
+**
+** There is a typedef for this structure in sqlite.h. So all routines,
+** even the public interface to STQLite, can use a pointer to this structure.
+** But this file is the only place where the internal details of this
+** structure are known.
+**
+** This structure is defined inside of vdbe.c because it uses substructures
+** (Mem) which are only defined there.
+*/
+struct sqlite_func {
+ FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
+ Mem s; /* The return value is stored here */
+ void *pAgg; /* Aggregate context */
+ u8 isError; /* Set to true for an error */
+ u8 isStep; /* Current in the step function */
+ int cnt; /* Number of times that the step function has been called */
+};
+
+/*
+** An Agg structure describes an Aggregator. Each Agg consists of
+** zero or more Aggregator elements (AggElem). Each AggElem tqcontains
+** a key and one or more values. The values are used in processing
+** aggregate functions in a SELECT. The key is used to implement
+** the GROUP BY clause of a select.
+*/
+typedef struct Agg Agg;
+typedef struct AggElem AggElem;
+struct Agg {
+ int nMem; /* Number of values stored in each AggElem */
+ AggElem *pCurrent; /* The AggElem currently in focus */
+ HashElem *pSearch; /* The hash element for pCurrent */
+ Hash hash; /* Hash table of all aggregate elements */
+ FuncDef **apFunc; /* Information about aggregate functions */
+};
+struct AggElem {
+ char *zKey; /* The key to this AggElem */
+ int nKey; /* Number of bytes in the key, including '\0' at end */
+ Mem aMem[1]; /* The values for this AggElem */
+};
+
+/*
+** A Set structure is used for quick testing to see if a value
+** is part of a small set. Sets are used to implement code like
+** this:
+** x.y IN ('hi','hoo','hum')
+*/
+typedef struct Set Set;
+struct Set {
+ Hash hash; /* A set is just a hash table */
+ HashElem *prev; /* Previously accessed hash elemen */
+};
+
+/*
+** A Keylist is a bunch of keys into a table. The keylist can
+** grow without bound. The keylist stores the ROWIDs of database
+** records that need to be deleted or updated.
+*/
+typedef struct Keylist Keylist;
+struct Keylist {
+ int nKey; /* Number of Q_SLOTS in aKey[] */
+ int nUsed; /* Next unwritten slot in aKey[] */
+ int nRead; /* Next unread slot in aKey[] */
+ Keylist *pNext; /* Next block of keys */
+ int aKey[1]; /* One or more keys. Extra space allocated as needed */
+};
+
+/*
+** A Context stores the last insert rowid, the last statement change count,
+** and the current statement change count (i.e. changes since last statement).
+** Elements of Context structure type make up the ContextStack, which is
+** updated by the ContextPush and ContextPop opcodes (used by triggers)
+*/
+typedef struct Context Context;
+struct Context {
+ int lastRowid; /* Last insert rowid (from db->lastRowid) */
+ int lsChange; /* Last statement change count (from db->lsChange) */
+ int csChange; /* Current statement change count (from db->csChange) */
+};
+
+/*
+** An instance of the virtual machine. This structure tqcontains the complete
+** state of the virtual machine.
+**
+** The "sqlite_vm" structure pointer that is returned by sqlite_compile()
+** is really a pointer to an instance of this structure.
+*/
+struct Vdbe {
+ sqlite *db; /* The whole database */
+ Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
+ FILE *trace; /* Write an execution trace here, if not NULL */
+ int nOp; /* Number of instructions in the program */
+ int nOpAlloc; /* Number of Q_SLOTS allocated for aOp[] */
+ Op *aOp; /* Space to hold the virtual machine's program */
+ int nLabel; /* Number of labels used */
+ int nLabelAlloc; /* Number of Q_SLOTS allocated in aLabel[] */
+ int *aLabel; /* Space to hold the labels */
+ Mem *aStack; /* The operand stack, except string values */
+ Mem *pTos; /* Top entry in the operand stack */
+ char **zArgv; /* Text values used by the callback */
+ char **azColName; /* Becomes the 4th parameter to callbacks */
+ int nCursor; /* Number of Q_SLOTS in aCsr[] */
+ Cursor *aCsr; /* One element of this array for each open cursor */
+ Sorter *pSort; /* A linked list of objects to be sorted */
+ FILE *pFile; /* At most one open file handler */
+ int nField; /* Number of file fields */
+ char **azField; /* Data for each file field */
+ int nVar; /* Number of entries in azVariable[] */
+ char **azVar; /* Values for the OP_Variable opcode */
+ int *anVar; /* Length of each value in azVariable[] */
+ u8 *abVar; /* TRUE if azVariable[i] needs to be sqliteFree()ed */
+ char *zLine; /* A single line from the input file */
+ int nLineAlloc; /* Number of spaces allocated for zLine */
+ int magic; /* Magic number for sanity checking */
+ int nMem; /* Number of memory locations currently allocated */
+ Mem *aMem; /* The memory locations */
+ Agg agg; /* Aggregate information */
+ int nSet; /* Number of sets allocated */
+ Set *aSet; /* An array of sets */
+ int nCallback; /* Number of callbacks invoked so far */
+ Keylist *pList; /* A list of ROWIDs */
+ int keylistStackDepth; /* The size of the "keylist" stack */
+ Keylist **keylistStack; /* The stack used by opcodes ListPush & ListPop */
+ int contextStackDepth; /* The size of the "context" stack */
+ Context *contextStack; /* Stack used by opcodes ContextPush & ContextPop*/
+ int pc; /* The program counter */
+ int rc; /* Value to return */
+ unsigned uniqueCnt; /* Used by OP_MakeRecord when P2!=0 */
+ int errorAction; /* Recovery action to do in case of an error */
+ int undoTransOnError; /* If error, either ROLLBACK or COMMIT */
+ int inTempTrans; /* True if temp database is transactioned */
+ int returnStack[100]; /* Return address stack for OP_Gosub & OP_Return */
+ int returnDepth; /* Next unused element in returnStack[] */
+ int nResColumn; /* Number of columns in one row of the result set */
+ char **azResColumn; /* Values for one row of result */
+ int popStack; /* Pop the stack this much on entry to VdbeExec() */
+ char *zErrMsg; /* Error message written here */
+ u8 explain; /* True if EXPLAIN present on SQL command */
+};
+
+/*
+** The following are allowed values for Vdbe.magic
+*/
+#define VDBE_MAGIC_INIT 0x26bceaa5 /* Building a VDBE program */
+#define VDBE_MAGIC_RUN 0xbdf20da3 /* VDBE is ready to execute */
+#define VDBE_MAGIC_HALT 0x519c2973 /* VDBE has completed execution */
+#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
+
+/*
+** Function prototypes
+*/
+void sqliteVdbeCleanupCursor(Cursor*);
+void sqliteVdbeSorterReset(Vdbe*);
+void sqliteVdbeAggReset(Agg*);
+void sqliteVdbeKeylistFree(Keylist*);
+void sqliteVdbePopStack(Vdbe*,int);
+int sqliteVdbeCursorMoveto(Cursor*);
+int sqliteVdbeByteSwap(int);
+#if !defined(NDEBUG) || defined(VDBE_PROFILE)
+void sqliteVdbePrintOp(FILE*, int, Op*);
+#endif
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/vdbeaux.c b/tqtinterface/qt4/src/3rdparty/sqlite/vdbeaux.c
new file mode 100644
index 0000000..6f74146
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/vdbeaux.c
@@ -0,0 +1,1061 @@
+/*
+** 2003 September 6
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file tqcontains code used for creating, destroying, and populating
+** a VDBE (or an "sqlite_vm" as it is known to the outside world.) Prior
+** to version 2.8.7, all this code was combined into the vdbe.c source file.
+** But that file was getting too big so this subroutines were split out.
+*/
+#include "sqliteInt.h"
+#include "os.h"
+#include <ctype.h>
+#include "vdbeInt.h"
+
+
+/*
+** When debugging the code generator in a symbolic debugger, one can
+** set the sqlite_vdbe_addop_trace to 1 and all opcodes will be printed
+** as they are added to the instruction stream.
+*/
+#ifndef NDEBUG
+int sqlite_vdbe_addop_trace = 0;
+#endif
+
+
+/*
+** Create a new virtual database engine.
+*/
+Vdbe *sqliteVdbeCreate(sqlite *db){
+ Vdbe *p;
+ p = sqliteMalloc( sizeof(Vdbe) );
+ if( p==0 ) return 0;
+ p->db = db;
+ if( db->pVdbe ){
+ db->pVdbe->pPrev = p;
+ }
+ p->pNext = db->pVdbe;
+ p->pPrev = 0;
+ db->pVdbe = p;
+ p->magic = VDBE_MAGIC_INIT;
+ return p;
+}
+
+/*
+** Turn tracing on or off
+*/
+void sqliteVdbeTrace(Vdbe *p, FILE *trace){
+ p->trace = trace;
+}
+
+/*
+** Add a new instruction to the list of instructions current in the
+** VDBE. Return the address of the new instruction.
+**
+** Parameters:
+**
+** p Pointer to the VDBE
+**
+** op The opcode for this instruction
+**
+** p1, p2 First two of the three possible operands.
+**
+** Use the sqliteVdbeResolveLabel() function to fix an address and
+** the sqliteVdbeChangeP3() function to change the value of the P3
+** operand.
+*/
+int sqliteVdbeAddOp(Vdbe *p, int op, int p1, int p2){
+ int i;
+ VdbeOp *pOp;
+
+ i = p->nOp;
+ p->nOp++;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( i>=p->nOpAlloc ){
+ int oldSize = p->nOpAlloc;
+ Op *aNew;
+ p->nOpAlloc = p->nOpAlloc*2 + 100;
+ aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
+ if( aNew==0 ){
+ p->nOpAlloc = oldSize;
+ return 0;
+ }
+ p->aOp = aNew;
+ memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
+ }
+ pOp = &p->aOp[i];
+ pOp->opcode = op;
+ pOp->p1 = p1;
+ if( p2<0 && (-1-p2)<p->nLabel && p->aLabel[-1-p2]>=0 ){
+ p2 = p->aLabel[-1-p2];
+ }
+ pOp->p2 = p2;
+ pOp->p3 = 0;
+ pOp->p3type = P3_NOTUSED;
+#ifndef NDEBUG
+ if( sqlite_vdbe_addop_trace ) sqliteVdbePrintOp(0, i, &p->aOp[i]);
+#endif
+ return i;
+}
+
+/*
+** Add an opcode that includes the p3 value.
+*/
+int sqliteVdbeOp3(Vdbe *p, int op, int p1, int p2, const char *zP3, int p3type){
+ int addr = sqliteVdbeAddOp(p, op, p1, p2);
+ sqliteVdbeChangeP3(p, addr, zP3, p3type);
+ return addr;
+}
+
+/*
+** Add multiple opcodes. The list is terminated by an opcode of 0.
+*/
+int sqliteVdbeCode(Vdbe *p, ...){
+ int addr;
+ va_list ap;
+ int opcode, p1, p2;
+ va_start(ap, p);
+ addr = p->nOp;
+ while( (opcode = va_arg(ap,int))!=0 ){
+ p1 = va_arg(ap,int);
+ p2 = va_arg(ap,int);
+ sqliteVdbeAddOp(p, opcode, p1, p2);
+ }
+ va_end(ap);
+ return addr;
+}
+
+
+
+/*
+** Create a new symbolic label for an instruction that has yet to be
+** coded. The symbolic label is really just a negative number. The
+** label can be used as the P2 value of an operation. Later, when
+** the label is resolved to a specific address, the VDBE will scan
+** through its operation list and change all values of P2 which match
+** the label into the resolved address.
+**
+** The VDBE knows that a P2 value is a label because labels are
+** always negative and P2 values are suppose to be non-negative.
+** Hence, a negative P2 value is a label that has yet to be resolved.
+*/
+int sqliteVdbeMakeLabel(Vdbe *p){
+ int i;
+ i = p->nLabel++;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( i>=p->nLabelAlloc ){
+ int *aNew;
+ p->nLabelAlloc = p->nLabelAlloc*2 + 10;
+ aNew = sqliteRealloc( p->aLabel, p->nLabelAlloc*sizeof(p->aLabel[0]));
+ if( aNew==0 ){
+ sqliteFree(p->aLabel);
+ }
+ p->aLabel = aNew;
+ }
+ if( p->aLabel==0 ){
+ p->nLabel = 0;
+ p->nLabelAlloc = 0;
+ return 0;
+ }
+ p->aLabel[i] = -1;
+ return -1-i;
+}
+
+/*
+** Resolve label "x" to be the address of the next instruction to
+** be inserted. The parameter "x" must have been obtained from
+** a prior call to sqliteVdbeMakeLabel().
+*/
+void sqliteVdbeResolveLabel(Vdbe *p, int x){
+ int j;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( x<0 && (-x)<=p->nLabel && p->aOp ){
+ if( p->aLabel[-1-x]==p->nOp ) return;
+ assert( p->aLabel[-1-x]<0 );
+ p->aLabel[-1-x] = p->nOp;
+ for(j=0; j<p->nOp; j++){
+ if( p->aOp[j].p2==x ) p->aOp[j].p2 = p->nOp;
+ }
+ }
+}
+
+/*
+** Return the address of the next instruction to be inserted.
+*/
+int sqliteVdbeCurrentAddr(Vdbe *p){
+ assert( p->magic==VDBE_MAGIC_INIT );
+ return p->nOp;
+}
+
+/*
+** Add a whole list of operations to the operation stack. Return the
+** address of the first operation added.
+*/
+int sqliteVdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
+ int addr;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( p->nOp + nOp >= p->nOpAlloc ){
+ int oldSize = p->nOpAlloc;
+ Op *aNew;
+ p->nOpAlloc = p->nOpAlloc*2 + nOp + 10;
+ aNew = sqliteRealloc(p->aOp, p->nOpAlloc*sizeof(Op));
+ if( aNew==0 ){
+ p->nOpAlloc = oldSize;
+ return 0;
+ }
+ p->aOp = aNew;
+ memset(&p->aOp[oldSize], 0, (p->nOpAlloc-oldSize)*sizeof(Op));
+ }
+ addr = p->nOp;
+ if( nOp>0 ){
+ int i;
+ VdbeOpList const *pIn = aOp;
+ for(i=0; i<nOp; i++, pIn++){
+ int p2 = pIn->p2;
+ VdbeOp *pOut = &p->aOp[i+addr];
+ pOut->opcode = pIn->opcode;
+ pOut->p1 = pIn->p1;
+ pOut->p2 = p2<0 ? addr + ADDR(p2) : p2;
+ pOut->p3 = pIn->p3;
+ pOut->p3type = pIn->p3 ? P3_STATIC : P3_NOTUSED;
+#ifndef NDEBUG
+ if( sqlite_vdbe_addop_trace ){
+ sqliteVdbePrintOp(0, i+addr, &p->aOp[i+addr]);
+ }
+#endif
+ }
+ p->nOp += nOp;
+ }
+ return addr;
+}
+
+/*
+** Change the value of the P1 operand for a specific instruction.
+** This routine is useful when a large program is loaded from a
+** static array using sqliteVdbeAddOpList but we want to make a
+** few minor changes to the program.
+*/
+void sqliteVdbeChangeP1(Vdbe *p, int addr, int val){
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( p && addr>=0 && p->nOp>addr && p->aOp ){
+ p->aOp[addr].p1 = val;
+ }
+}
+
+/*
+** Change the value of the P2 operand for a specific instruction.
+** This routine is useful for setting a jump destination.
+*/
+void sqliteVdbeChangeP2(Vdbe *p, int addr, int val){
+ assert( val>=0 );
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( p && addr>=0 && p->nOp>addr && p->aOp ){
+ p->aOp[addr].p2 = val;
+ }
+}
+
+/*
+** Change the value of the P3 operand for a specific instruction.
+** This routine is useful when a large program is loaded from a
+** static array using sqliteVdbeAddOpList but we want to make a
+** few minor changes to the program.
+**
+** If n>=0 then the P3 operand is dynamic, meaning that a copy of
+** the string is made into memory obtained from sqliteMalloc().
+** A value of n==0 means copy bytes of zP3 up to and including the
+** first null byte. If n>0 then copy n+1 bytes of zP3.
+**
+** If n==P3_STATIC it means that zP3 is a pointer to a constant static
+** string and we can just copy the pointer. n==P3_POINTER means zP3 is
+** a pointer to some object other than a string.
+**
+** If addr<0 then change P3 on the most recently inserted instruction.
+*/
+void sqliteVdbeChangeP3(Vdbe *p, int addr, const char *zP3, int n){
+ Op *pOp;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( p==0 || p->aOp==0 ) return;
+ if( addr<0 || addr>=p->nOp ){
+ addr = p->nOp - 1;
+ if( addr<0 ) return;
+ }
+ pOp = &p->aOp[addr];
+ if( pOp->p3 && pOp->p3type==P3_DYNAMIC ){
+ sqliteFree(pOp->p3);
+ pOp->p3 = 0;
+ }
+ if( zP3==0 ){
+ pOp->p3 = 0;
+ pOp->p3type = P3_NOTUSED;
+ }else if( n<0 ){
+ pOp->p3 = (char*)zP3;
+ pOp->p3type = n;
+ }else{
+ sqliteSetNString(&pOp->p3, zP3, n, 0);
+ pOp->p3type = P3_DYNAMIC;
+ }
+}
+
+/*
+** If the P3 operand to the specified instruction appears
+** to be a quoted string token, then this procedure removes
+** the quotes.
+**
+** The quoting operator can be either a grave ascent (ASCII 0x27)
+** or a double quote character (ASCII 0x22). Two quotes in a row
+** resolve to be a single actual quote character within the string.
+*/
+void sqliteVdbeDequoteP3(Vdbe *p, int addr){
+ Op *pOp;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( p->aOp==0 ) return;
+ if( addr<0 || addr>=p->nOp ){
+ addr = p->nOp - 1;
+ if( addr<0 ) return;
+ }
+ pOp = &p->aOp[addr];
+ if( pOp->p3==0 || pOp->p3[0]==0 ) return;
+ if( pOp->p3type==P3_POINTER ) return;
+ if( pOp->p3type!=P3_DYNAMIC ){
+ pOp->p3 = sqliteStrDup(pOp->p3);
+ pOp->p3type = P3_DYNAMIC;
+ }
+ sqliteDequote(pOp->p3);
+}
+
+/*
+** On the P3 argument of the given instruction, change all
+** strings of whitespace characters into a single space and
+** delete leading and trailing whitespace.
+*/
+void sqliteVdbeCompressSpace(Vdbe *p, int addr){
+ unsigned char *z;
+ int i, j;
+ Op *pOp;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ if( p->aOp==0 || addr<0 || addr>=p->nOp ) return;
+ pOp = &p->aOp[addr];
+ if( pOp->p3type==P3_POINTER ){
+ return;
+ }
+ if( pOp->p3type!=P3_DYNAMIC ){
+ pOp->p3 = sqliteStrDup(pOp->p3);
+ pOp->p3type = P3_DYNAMIC;
+ }
+ z = (unsigned char*)pOp->p3;
+ if( z==0 ) return;
+ i = j = 0;
+ while( isspace(z[i]) ){ i++; }
+ while( z[i] ){
+ if( isspace(z[i]) ){
+ z[j++] = ' ';
+ while( isspace(z[++i]) ){}
+ }else{
+ z[j++] = z[i++];
+ }
+ }
+ while( j>0 && isspace(z[j-1]) ){ j--; }
+ z[j] = 0;
+}
+
+/*
+** Search for the current program for the given opcode and P2
+** value. Return the address plus 1 if found and 0 if not found.
+*/
+int sqliteVdbeFindOp(Vdbe *p, int op, int p2){
+ int i;
+ assert( p->magic==VDBE_MAGIC_INIT );
+ for(i=0; i<p->nOp; i++){
+ if( p->aOp[i].opcode==op && p->aOp[i].p2==p2 ) return i+1;
+ }
+ return 0;
+}
+
+/*
+** Return the opcode for a given address.
+*/
+VdbeOp *sqliteVdbeGetOp(Vdbe *p, int addr){
+ assert( p->magic==VDBE_MAGIC_INIT );
+ assert( addr>=0 && addr<p->nOp );
+ return &p->aOp[addr];
+}
+
+/*
+** The following group or routines are employed by installable functions
+** to return their results.
+**
+** The sqlite_set_result_string() routine can be used to return a string
+** value or to return a NULL. To return a NULL, pass in NULL for zResult.
+** A copy is made of the string before this routine returns so it is safe
+** to pass in an ephemeral string.
+**
+** sqlite_set_result_error() works like sqlite_set_result_string() except
+** that it Q_SIGNALS a fatal error. The string argument, if any, is the
+** error message. If the argument is NULL a generic substitute error message
+** is used.
+**
+** The sqlite_set_result_int() and sqlite_set_result_double() set the return
+** value of the user function to an integer or a double.
+**
+** These routines are defined here in vdbe.c because they depend on knowing
+** the internals of the sqlite_func structure which is only defined in
+** this source file.
+*/
+char *sqlite_set_result_string(sqlite_func *p, const char *zResult, int n){
+ assert( !p->isStep );
+ if( p->s.flags & MEM_Dyn ){
+ sqliteFree(p->s.z);
+ }
+ if( zResult==0 ){
+ p->s.flags = MEM_Null;
+ n = 0;
+ p->s.z = 0;
+ p->s.n = 0;
+ }else{
+ if( n<0 ) n = strlen(zResult);
+ if( n<NBFS-1 ){
+ memcpy(p->s.zShort, zResult, n);
+ p->s.zShort[n] = 0;
+ p->s.flags = MEM_Str | MEM_Short;
+ p->s.z = p->s.zShort;
+ }else{
+ p->s.z = sqliteMallocRaw( n+1 );
+ if( p->s.z ){
+ memcpy(p->s.z, zResult, n);
+ p->s.z[n] = 0;
+ }
+ p->s.flags = MEM_Str | MEM_Dyn;
+ }
+ p->s.n = n+1;
+ }
+ return p->s.z;
+}
+void sqlite_set_result_int(sqlite_func *p, int iResult){
+ assert( !p->isStep );
+ if( p->s.flags & MEM_Dyn ){
+ sqliteFree(p->s.z);
+ }
+ p->s.i = iResult;
+ p->s.flags = MEM_Int;
+}
+void sqlite_set_result_double(sqlite_func *p, double rResult){
+ assert( !p->isStep );
+ if( p->s.flags & MEM_Dyn ){
+ sqliteFree(p->s.z);
+ }
+ p->s.r = rResult;
+ p->s.flags = MEM_Real;
+}
+void sqlite_set_result_error(sqlite_func *p, const char *zMsg, int n){
+ assert( !p->isStep );
+ sqlite_set_result_string(p, zMsg, n);
+ p->isError = 1;
+}
+
+/*
+** Extract the user data from a sqlite_func structure and return a
+** pointer to it.
+*/
+void *sqlite_user_data(sqlite_func *p){
+ assert( p && p->pFunc );
+ return p->pFunc->pUserData;
+}
+
+/*
+** Allocate or return the aggregate context for a user function. A new
+** context is allocated on the first call. Subsequent calls return the
+** same context that was returned on prior calls.
+**
+** This routine is defined here in vdbe.c because it depends on knowing
+** the internals of the sqlite_func structure which is only defined in
+** this source file.
+*/
+void *sqlite_aggregate_context(sqlite_func *p, int nByte){
+ assert( p && p->pFunc && p->pFunc->xStep );
+ if( p->pAgg==0 ){
+ if( nByte<=NBFS ){
+ p->pAgg = (void*)p->s.z;
+ memset(p->pAgg, 0, nByte);
+ }else{
+ p->pAgg = sqliteMalloc( nByte );
+ }
+ }
+ return p->pAgg;
+}
+
+/*
+** Return the number of times the Step function of a aggregate has been
+** called.
+**
+** This routine is defined here in vdbe.c because it depends on knowing
+** the internals of the sqlite_func structure which is only defined in
+** this source file.
+*/
+int sqlite_aggregate_count(sqlite_func *p){
+ assert( p && p->pFunc && p->pFunc->xStep );
+ return p->cnt;
+}
+
+#if !defined(NDEBUG) || defined(VDBE_PROFILE)
+/*
+** Print a single opcode. This routine is used for debugging only.
+*/
+void sqliteVdbePrintOp(FILE *pOut, int pc, Op *pOp){
+ char *zP3;
+ char zPtr[40];
+ if( pOp->p3type==P3_POINTER ){
+ sprintf(zPtr, "ptr(%#x)", (int)pOp->p3);
+ zP3 = zPtr;
+ }else{
+ zP3 = pOp->p3;
+ }
+ if( pOut==0 ) pOut = stdout;
+ fprintf(pOut,"%4d %-12s %4d %4d %s\n",
+ pc, sqliteOpcodeNames[pOp->opcode], pOp->p1, pOp->p2, zP3 ? zP3 : "");
+ fflush(pOut);
+}
+#endif
+
+/*
+** Give a listing of the program in the virtual machine.
+**
+** The interface is the same as sqliteVdbeExec(). But instead of
+** running the code, it invokes the callback once for each instruction.
+** This feature is used to implement "EXPLAIN".
+*/
+int sqliteVdbeList(
+ Vdbe *p /* The VDBE */
+){
+ sqlite *db = p->db;
+ int i;
+ int rc = STQLITE_OK;
+ static char *azColumnNames[] = {
+ "addr", "opcode", "p1", "p2", "p3",
+ "int", "text", "int", "int", "text",
+ 0
+ };
+
+ assert( p->popStack==0 );
+ assert( p->explain );
+ p->azColName = azColumnNames;
+ p->azResColumn = p->zArgv;
+ for(i=0; i<5; i++) p->zArgv[i] = p->aStack[i].zShort;
+ i = p->pc;
+ if( i>=p->nOp ){
+ p->rc = STQLITE_OK;
+ rc = STQLITE_DONE;
+ }else if( db->flags & STQLITE_Interrupt ){
+ db->flags &= ~STQLITE_Interrupt;
+ if( db->magic!=STQLITE_MAGIC_BUSY ){
+ p->rc = STQLITE_MISUSE;
+ }else{
+ p->rc = STQLITE_INTERRUPT;
+ }
+ rc = STQLITE_ERROR;
+ sqliteSetString(&p->zErrMsg, sqlite_error_string(p->rc), (char*)0);
+ }else{
+ sprintf(p->zArgv[0],"%d",i);
+ sprintf(p->zArgv[2],"%d", p->aOp[i].p1);
+ sprintf(p->zArgv[3],"%d", p->aOp[i].p2);
+ if( p->aOp[i].p3type==P3_POINTER ){
+ sprintf(p->aStack[4].zShort, "ptr(%#x)", (int)p->aOp[i].p3);
+ p->zArgv[4] = p->aStack[4].zShort;
+ }else{
+ p->zArgv[4] = p->aOp[i].p3;
+ }
+ p->zArgv[1] = sqliteOpcodeNames[p->aOp[i].opcode];
+ p->pc = i+1;
+ p->azResColumn = p->zArgv;
+ p->nResColumn = 5;
+ p->rc = STQLITE_OK;
+ rc = STQLITE_ROW;
+ }
+ return rc;
+}
+
+/*
+** Prepare a virtual machine for execution. This involves things such
+** as allocating stack space and initializing the program counter.
+** After the VDBE has be prepped, it can be executed by one or more
+** calls to sqliteVdbeExec().
+*/
+void sqliteVdbeMakeReady(
+ Vdbe *p, /* The VDBE */
+ int nVar, /* Number of '?' see in the SQL statement */
+ int isExplain /* True if the EXPLAIN keywords is present */
+){
+ int n;
+
+ assert( p!=0 );
+ assert( p->magic==VDBE_MAGIC_INIT );
+
+ /* Add a HALT instruction to the very end of the program.
+ */
+ if( p->nOp==0 || (p->aOp && p->aOp[p->nOp-1].opcode!=OP_Halt) ){
+ sqliteVdbeAddOp(p, OP_Halt, 0, 0);
+ }
+
+ /* No instruction ever pushes more than a single element onto the
+ ** stack. And the stack never grows on successive executions of the
+ ** same loop. So the total number of instructions is an upper bound
+ ** on the maximum stack depth required.
+ **
+ ** Allocation all the stack space we will ever need.
+ */
+ if( p->aStack==0 ){
+ p->nVar = nVar;
+ assert( nVar>=0 );
+ n = isExplain ? 10 : p->nOp;
+ p->aStack = sqliteMalloc(
+ n*(sizeof(p->aStack[0]) + 2*sizeof(char*)) /* aStack and zArgv */
+ + p->nVar*(sizeof(char*)+sizeof(int)+1) /* azVar, anVar, abVar */
+ );
+ p->zArgv = (char**)&p->aStack[n];
+ p->azColName = (char**)&p->zArgv[n];
+ p->azVar = (char**)&p->azColName[n];
+ p->anVar = (int*)&p->azVar[p->nVar];
+ p->abVar = (u8*)&p->anVar[p->nVar];
+ }
+
+ sqliteHashInit(&p->agg.hash, STQLITE_HASH_BINARY, 0);
+ p->agg.pSearch = 0;
+#ifdef MEMORY_DEBUG
+ if( sqliteOsFileExists("vdbe_trace") ){
+ p->trace = stdout;
+ }
+#endif
+ p->pTos = &p->aStack[-1];
+ p->pc = 0;
+ p->rc = STQLITE_OK;
+ p->uniqueCnt = 0;
+ p->returnDepth = 0;
+ p->errorAction = OE_Abort;
+ p->undoTransOnError = 0;
+ p->popStack = 0;
+ p->explain |= isExplain;
+ p->magic = VDBE_MAGIC_RUN;
+#ifdef VDBE_PROFILE
+ {
+ int i;
+ for(i=0; i<p->nOp; i++){
+ p->aOp[i].cnt = 0;
+ p->aOp[i].cycles = 0;
+ }
+ }
+#endif
+}
+
+
+/*
+** Remove any elements that remain on the sorter for the VDBE given.
+*/
+void sqliteVdbeSorterReset(Vdbe *p){
+ while( p->pSort ){
+ Sorter *pSorter = p->pSort;
+ p->pSort = pSorter->pNext;
+ sqliteFree(pSorter->zKey);
+ sqliteFree(pSorter->pData);
+ sqliteFree(pSorter);
+ }
+}
+
+/*
+** Reset an Agg structure. Delete all its contents.
+**
+** For installable aggregate functions, if the step function has been
+** called, make sure the finalizer function has also been called. The
+** finalizer might need to free memory that was allocated as part of its
+** private context. If the finalizer has not been called yet, call it
+** now.
+*/
+void sqliteVdbeAggReset(Agg *pAgg){
+ int i;
+ HashElem *p;
+ for(p = sqliteHashFirst(&pAgg->hash); p; p = sqliteHashNext(p)){
+ AggElem *pElem = sqliteHashData(p);
+ assert( pAgg->apFunc!=0 );
+ for(i=0; i<pAgg->nMem; i++){
+ Mem *pMem = &pElem->aMem[i];
+ if( pAgg->apFunc[i] && (pMem->flags & MEM_AggCtx)!=0 ){
+ sqlite_func ctx;
+ ctx.pFunc = pAgg->apFunc[i];
+ ctx.s.flags = MEM_Null;
+ ctx.pAgg = pMem->z;
+ ctx.cnt = pMem->i;
+ ctx.isStep = 0;
+ ctx.isError = 0;
+ (*pAgg->apFunc[i]->xFinalize)(&ctx);
+ if( pMem->z!=0 && pMem->z!=pMem->zShort ){
+ sqliteFree(pMem->z);
+ }
+ if( ctx.s.flags & MEM_Dyn ){
+ sqliteFree(ctx.s.z);
+ }
+ }else if( pMem->flags & MEM_Dyn ){
+ sqliteFree(pMem->z);
+ }
+ }
+ sqliteFree(pElem);
+ }
+ sqliteHashClear(&pAgg->hash);
+ sqliteFree(pAgg->apFunc);
+ pAgg->apFunc = 0;
+ pAgg->pCurrent = 0;
+ pAgg->pSearch = 0;
+ pAgg->nMem = 0;
+}
+
+/*
+** Delete a keylist
+*/
+void sqliteVdbeKeylistFree(Keylist *p){
+ while( p ){
+ Keylist *pNext = p->pNext;
+ sqliteFree(p);
+ p = pNext;
+ }
+}
+
+/*
+** Close a cursor and release all the resources that cursor happens
+** to hold.
+*/
+void sqliteVdbeCleanupCursor(Cursor *pCx){
+ if( pCx->pCursor ){
+ sqliteBtreeCloseCursor(pCx->pCursor);
+ }
+ if( pCx->pBt ){
+ sqliteBtreeClose(pCx->pBt);
+ }
+ sqliteFree(pCx->pData);
+ memset(pCx, 0, sizeof(Cursor));
+}
+
+/*
+** Close all cursors
+*/
+static void closeAllCursors(Vdbe *p){
+ int i;
+ for(i=0; i<p->nCursor; i++){
+ sqliteVdbeCleanupCursor(&p->aCsr[i]);
+ }
+ sqliteFree(p->aCsr);
+ p->aCsr = 0;
+ p->nCursor = 0;
+}
+
+/*
+** Clean up the VM after execution.
+**
+** This routine will automatically close any cursors, lists, and/or
+** sorters that were left open. It also deletes the values of
+** variables in the azVariable[] array.
+*/
+static void Cleanup(Vdbe *p){
+ int i;
+ if( p->aStack ){
+ Mem *pTos = p->pTos;
+ while( pTos>=p->aStack ){
+ if( pTos->flags & MEM_Dyn ){
+ sqliteFree(pTos->z);
+ }
+ pTos--;
+ }
+ p->pTos = pTos;
+ }
+ closeAllCursors(p);
+ if( p->aMem ){
+ for(i=0; i<p->nMem; i++){
+ if( p->aMem[i].flags & MEM_Dyn ){
+ sqliteFree(p->aMem[i].z);
+ }
+ }
+ }
+ sqliteFree(p->aMem);
+ p->aMem = 0;
+ p->nMem = 0;
+ if( p->pList ){
+ sqliteVdbeKeylistFree(p->pList);
+ p->pList = 0;
+ }
+ sqliteVdbeSorterReset(p);
+ if( p->pFile ){
+ if( p->pFile!=stdin ) fclose(p->pFile);
+ p->pFile = 0;
+ }
+ if( p->azField ){
+ sqliteFree(p->azField);
+ p->azField = 0;
+ }
+ p->nField = 0;
+ if( p->zLine ){
+ sqliteFree(p->zLine);
+ p->zLine = 0;
+ }
+ p->nLineAlloc = 0;
+ sqliteVdbeAggReset(&p->agg);
+ if( p->aSet ){
+ for(i=0; i<p->nSet; i++){
+ sqliteHashClear(&p->aSet[i].hash);
+ }
+ }
+ sqliteFree(p->aSet);
+ p->aSet = 0;
+ p->nSet = 0;
+ if( p->keylistStack ){
+ int ii;
+ for(ii = 0; ii < p->keylistStackDepth; ii++){
+ sqliteVdbeKeylistFree(p->keylistStack[ii]);
+ }
+ sqliteFree(p->keylistStack);
+ p->keylistStackDepth = 0;
+ p->keylistStack = 0;
+ }
+ sqliteFree(p->contextStack);
+ p->contextStack = 0;
+ sqliteFree(p->zErrMsg);
+ p->zErrMsg = 0;
+}
+
+/*
+** Clean up a VDBE after execution but do not delete the VDBE just yet.
+** Write any error messages into *pzErrMsg. Return the result code.
+**
+** After this routine is run, the VDBE should be ready to be executed
+** again.
+*/
+int sqliteVdbeReset(Vdbe *p, char **pzErrMsg){
+ sqlite *db = p->db;
+ int i;
+
+ if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
+ sqliteSetString(pzErrMsg, sqlite_error_string(STQLITE_MISUSE), (char*)0);
+ return STQLITE_MISUSE;
+ }
+ if( p->zErrMsg ){
+ if( pzErrMsg && *pzErrMsg==0 ){
+ *pzErrMsg = p->zErrMsg;
+ }else{
+ sqliteFree(p->zErrMsg);
+ }
+ p->zErrMsg = 0;
+ }else if( p->rc ){
+ sqliteSetString(pzErrMsg, sqlite_error_string(p->rc), (char*)0);
+ }
+ Cleanup(p);
+ if( p->rc!=STQLITE_OK ){
+ switch( p->errorAction ){
+ case OE_Abort: {
+ if( !p->undoTransOnError ){
+ for(i=0; i<db->nDb; i++){
+ if( db->aDb[i].pBt ){
+ sqliteBtreeRollbackCkpt(db->aDb[i].pBt);
+ }
+ }
+ break;
+ }
+ /* Fall through to ROLLBACK */
+ }
+ case OE_Rollback: {
+ sqliteRollbackAll(db);
+ db->flags &= ~STQLITE_InTrans;
+ db->onError = OE_Default;
+ break;
+ }
+ default: {
+ if( p->undoTransOnError ){
+ sqliteRollbackAll(db);
+ db->flags &= ~STQLITE_InTrans;
+ db->onError = OE_Default;
+ }
+ break;
+ }
+ }
+ sqliteRollbackInternalChanges(db);
+ }
+ for(i=0; i<db->nDb; i++){
+ if( db->aDb[i].pBt && db->aDb[i].inTrans==2 ){
+ sqliteBtreeCommitCkpt(db->aDb[i].pBt);
+ db->aDb[i].inTrans = 1;
+ }
+ }
+ assert( p->pTos<&p->aStack[p->pc] || sqlite_malloc_failed==1 );
+#ifdef VDBE_PROFILE
+ {
+ FILE *out = fopen("vdbe_profile.out", "a");
+ if( out ){
+ int i;
+ fprintf(out, "---- ");
+ for(i=0; i<p->nOp; i++){
+ fprintf(out, "%02x", p->aOp[i].opcode);
+ }
+ fprintf(out, "\n");
+ for(i=0; i<p->nOp; i++){
+ fprintf(out, "%6d %10lld %8lld ",
+ p->aOp[i].cnt,
+ p->aOp[i].cycles,
+ p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0
+ );
+ sqliteVdbePrintOp(out, i, &p->aOp[i]);
+ }
+ fclose(out);
+ }
+ }
+#endif
+ p->magic = VDBE_MAGIC_INIT;
+ return p->rc;
+}
+
+/*
+** Clean up and delete a VDBE after execution. Return an integer which is
+** the result code. Write any error message text into *pzErrMsg.
+*/
+int sqliteVdbeFinalize(Vdbe *p, char **pzErrMsg){
+ int rc;
+ sqlite *db;
+
+ if( p->magic!=VDBE_MAGIC_RUN && p->magic!=VDBE_MAGIC_HALT ){
+ sqliteSetString(pzErrMsg, sqlite_error_string(STQLITE_MISUSE), (char*)0);
+ return STQLITE_MISUSE;
+ }
+ db = p->db;
+ rc = sqliteVdbeReset(p, pzErrMsg);
+ sqliteVdbeDelete(p);
+ if( db->want_to_close && db->pVdbe==0 ){
+ sqlite_close(db);
+ }
+ if( rc==STQLITE_SCHEMA ){
+ sqliteResetInternalSchema(db, 0);
+ }
+ return rc;
+}
+
+/*
+** Set the values of all variables. Variable $1 in the original SQL will
+** be the string azValue[0]. $2 will have the value azValue[1]. And
+** so forth. If a value is out of range (for example $3 when nValue==2)
+** then its value will be NULL.
+**
+** This routine overrides any prior call.
+*/
+int sqlite_bind(sqlite_vm *pVm, int i, const char *zVal, int len, int copy){
+ Vdbe *p = (Vdbe*)pVm;
+ if( p->magic!=VDBE_MAGIC_RUN || p->pc!=0 ){
+ return STQLITE_MISUSE;
+ }
+ if( i<1 || i>p->nVar ){
+ return STQLITE_RANGE;
+ }
+ i--;
+ if( p->abVar[i] ){
+ sqliteFree(p->azVar[i]);
+ }
+ if( zVal==0 ){
+ copy = 0;
+ len = 0;
+ }
+ if( len<0 ){
+ len = strlen(zVal)+1;
+ }
+ if( copy ){
+ p->azVar[i] = sqliteMalloc( len );
+ if( p->azVar[i] ) memcpy(p->azVar[i], zVal, len);
+ }else{
+ p->azVar[i] = (char*)zVal;
+ }
+ p->abVar[i] = copy;
+ p->anVar[i] = len;
+ return STQLITE_OK;
+}
+
+
+/*
+** Delete an entire VDBE.
+*/
+void sqliteVdbeDelete(Vdbe *p){
+ int i;
+ if( p==0 ) return;
+ Cleanup(p);
+ if( p->pPrev ){
+ p->pPrev->pNext = p->pNext;
+ }else{
+ assert( p->db->pVdbe==p );
+ p->db->pVdbe = p->pNext;
+ }
+ if( p->pNext ){
+ p->pNext->pPrev = p->pPrev;
+ }
+ p->pPrev = p->pNext = 0;
+ if( p->nOpAlloc==0 ){
+ p->aOp = 0;
+ p->nOp = 0;
+ }
+ for(i=0; i<p->nOp; i++){
+ if( p->aOp[i].p3type==P3_DYNAMIC ){
+ sqliteFree(p->aOp[i].p3);
+ }
+ }
+ for(i=0; i<p->nVar; i++){
+ if( p->abVar[i] ) sqliteFree(p->azVar[i]);
+ }
+ sqliteFree(p->aOp);
+ sqliteFree(p->aLabel);
+ sqliteFree(p->aStack);
+ p->magic = VDBE_MAGIC_DEAD;
+ sqliteFree(p);
+}
+
+/*
+** Convert an integer in between the native integer format and
+** the bigEndian format used as the record number for tables.
+**
+** The bigEndian format (most significant byte first) is used for
+** record numbers so that records will sort into the correct order
+** even though memcmp() is used to compare the keys. On machines
+** whose native integer format is little endian (ex: i486) the
+** order of bytes is reversed. On native big-endian machines
+** (ex: Alpha, Sparc, Motorola) the byte order is the same.
+**
+** This function is its own inverse. In other words
+**
+** X == byteSwap(byteSwap(X))
+*/
+int sqliteVdbeByteSwap(int x){
+ union {
+ char zBuf[sizeof(int)];
+ int i;
+ } ux;
+ ux.zBuf[3] = x&0xff;
+ ux.zBuf[2] = (x>>8)&0xff;
+ ux.zBuf[1] = (x>>16)&0xff;
+ ux.zBuf[0] = (x>>24)&0xff;
+ return ux.i;
+}
+
+/*
+** If a MoveTo operation is pending on the given cursor, then do that
+** MoveTo now. Return an error code. If no MoveTo is pending, this
+** routine does nothing and returns STQLITE_OK.
+*/
+int sqliteVdbeCursorMoveto(Cursor *p){
+ if( p->deferredMoveto ){
+ int res;
+ extern int sqlite_search_count;
+ sqliteBtreeMoveto(p->pCursor, (char*)&p->movetoTarget, sizeof(int), &res);
+ p->lastRecno = keyToInt(p->movetoTarget);
+ p->recnoIsValid = res==0;
+ if( res<0 ){
+ sqliteBtreeNext(p->pCursor, &res);
+ }
+ sqlite_search_count++;
+ p->deferredMoveto = 0;
+ }
+ return STQLITE_OK;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/sqlite/where.c b/tqtinterface/qt4/src/3rdparty/sqlite/where.c
new file mode 100644
index 0000000..097ec5b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/sqlite/where.c
@@ -0,0 +1,1204 @@
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code. In place of
+** a legal notice, here is a blessing:
+**
+** May you do good and not evil.
+** May you tqfind forgiveness for yourself and forgive others.
+** May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This module tqcontains C code that generates VDBE code used to process
+** the WHERE clause of SQL statements.
+**
+** $Id: where.c,v 1.89 2004/02/22 20:05:02 drh Exp $
+*/
+#include "sqliteInt.h"
+
+/*
+** The query generator uses an array of instances of this structure to
+** help it analyze the subexpressions of the WHERE clause. Each WHERE
+** clause subexpression is separated from the others by an AND operator.
+*/
+typedef struct ExprInfo ExprInfo;
+struct ExprInfo {
+ Expr *p; /* Pointer to the subexpression */
+ u8 indexable; /* True if this subexprssion is usable by an index */
+ short int idxLeft; /* p->pLeft is a column in this table number. -1 if
+ ** p->pLeft is not the column of any table */
+ short int idxRight; /* p->pRight is a column in this table number. -1 if
+ ** p->pRight is not the column of any table */
+ unsigned prereqLeft; /* Bittqmask of tables referenced by p->pLeft */
+ unsigned prereqRight; /* Bittqmask of tables referenced by p->pRight */
+ unsigned prereqAll; /* Bittqmask of tables referenced by p */
+};
+
+/*
+** An instance of the following structure keeps track of a mapping
+** between VDBE cursor numbers and bitmasks. The VDBE cursor numbers
+** are small integers contained in SrcList_item.iCursor and Expr.iTable
+** fields. For any given WHERE clause, we want to track which cursors
+** are being used, so we assign a single bit in a 32-bit word to track
+** that cursor. Then a 32-bit integer is able to show the set of all
+** cursors being used.
+*/
+typedef struct ExprMaskSet ExprMaskSet;
+struct ExprMaskSet {
+ int n; /* Number of assigned cursor values */
+ int ix[32]; /* Cursor assigned to each bit */
+};
+
+/*
+** Determine the number of elements in an array.
+*/
+#define ARRAYSIZE(X) (sizeof(X)/sizeof(X[0]))
+
+/*
+** This routine is used to divide the WHERE expression into subexpressions
+** separated by the AND operator.
+**
+** aSlot[] is an array of subexpressions structures.
+** There are nSlot spaces left in this array. This routine attempts to
+** split pExpr into subexpressions and fills aSlot[] with those subexpressions.
+** The return value is the number of Q_SLOTS filled.
+*/
+static int exprSplit(int nSlot, ExprInfo *aSlot, Expr *pExpr){
+ int cnt = 0;
+ if( pExpr==0 || nSlot<1 ) return 0;
+ if( nSlot==1 || pExpr->op!=TK_AND ){
+ aSlot[0].p = pExpr;
+ return 1;
+ }
+ if( pExpr->pLeft->op!=TK_AND ){
+ aSlot[0].p = pExpr->pLeft;
+ cnt = 1 + exprSplit(nSlot-1, &aSlot[1], pExpr->pRight);
+ }else{
+ cnt = exprSplit(nSlot, aSlot, pExpr->pLeft);
+ cnt += exprSplit(nSlot-cnt, &aSlot[cnt], pExpr->pRight);
+ }
+ return cnt;
+}
+
+/*
+** Initialize an expression tqmask set
+*/
+#define initMaskSet(P) memset(P, 0, sizeof(*P))
+
+/*
+** Return the bittqmask for the given cursor. Assign a new bittqmask
+** if this is the first time the cursor has been seen.
+*/
+static int getMask(ExprMaskSet *pMaskSet, int iCursor){
+ int i;
+ for(i=0; i<pMaskSet->n; i++){
+ if( pMaskSet->ix[i]==iCursor ) return 1<<i;
+ }
+ if( i==pMaskSet->n && i<ARRAYSIZE(pMaskSet->ix) ){
+ pMaskSet->n++;
+ pMaskSet->ix[i] = iCursor;
+ return 1<<i;
+ }
+ return 0;
+}
+
+/*
+** Destroy an expression tqmask set
+*/
+#define freeMaskSet(P) /* NO-OP */
+
+/*
+** This routine walks (recursively) an expression tree and generates
+** a bittqmask indicating which tables are used in that expression
+** tree.
+**
+** In order for this routine to work, the calling function must have
+** previously invoked sqliteExprResolveIds() on the expression. See
+** the header comment on that routine for additional information.
+** The sqliteExprResolveIds() routines looks for column names and
+** sets their opcodes to TK_COLUMN and their Expr.iTable fields to
+** the VDBE cursor number of the table.
+*/
+static int exprTableUsage(ExprMaskSet *pMaskSet, Expr *p){
+ unsigned int tqmask = 0;
+ if( p==0 ) return 0;
+ if( p->op==TK_COLUMN ){
+ return getMask(pMaskSet, p->iTable);
+ }
+ if( p->pRight ){
+ tqmask = exprTableUsage(pMaskSet, p->pRight);
+ }
+ if( p->pLeft ){
+ tqmask |= exprTableUsage(pMaskSet, p->pLeft);
+ }
+ if( p->pList ){
+ int i;
+ for(i=0; i<p->pList->nExpr; i++){
+ tqmask |= exprTableUsage(pMaskSet, p->pList->a[i].pExpr);
+ }
+ }
+ return tqmask;
+}
+
+/*
+** Return TRUE if the given operator is one of the operators that is
+** allowed for an indexable WHERE clause. The allowed operators are
+** "=", "<", ">", "<=", ">=", and "IN".
+*/
+static int allowedOp(int op){
+ switch( op ){
+ case TK_LT:
+ case TK_LE:
+ case TK_GT:
+ case TK_GE:
+ case TK_EQ:
+ case TK_IN:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+/*
+** The input to this routine is an ExprInfo structure with only the
+** "p" field filled in. The job of this routine is to analyze the
+** subexpression and populate all the other fields of the ExprInfo
+** structure.
+*/
+static void exprAnalyze(ExprMaskSet *pMaskSet, ExprInfo *pInfo){
+ Expr *pExpr = pInfo->p;
+ pInfo->prereqLeft = exprTableUsage(pMaskSet, pExpr->pLeft);
+ pInfo->prereqRight = exprTableUsage(pMaskSet, pExpr->pRight);
+ pInfo->prereqAll = exprTableUsage(pMaskSet, pExpr);
+ pInfo->indexable = 0;
+ pInfo->idxLeft = -1;
+ pInfo->idxRight = -1;
+ if( allowedOp(pExpr->op) && (pInfo->prereqRight & pInfo->prereqLeft)==0 ){
+ if( pExpr->pRight && pExpr->pRight->op==TK_COLUMN ){
+ pInfo->idxRight = pExpr->pRight->iTable;
+ pInfo->indexable = 1;
+ }
+ if( pExpr->pLeft->op==TK_COLUMN ){
+ pInfo->idxLeft = pExpr->pLeft->iTable;
+ pInfo->indexable = 1;
+ }
+ }
+}
+
+/*
+** pOrderBy is an ORDER BY clause from a SELECT statement. pTab is the
+** left-most table in the FROM clause of that same SELECT statement and
+** the table has a cursor number of "base".
+**
+** This routine attempts to tqfind an index for pTab that generates the
+** correct record sequence for the given ORDER BY clause. The return value
+** is a pointer to an index that does the job. NULL is returned if the
+** table has no index that will generate the correct sort order.
+**
+** If there are two or more indices that generate the correct sort order
+** and pPreferredIdx is one of those indices, then return pPreferredIdx.
+**
+** nEqCol is the number of columns of pPreferredIdx that are used as
+** equality constraints. Any index returned must have exactly this same
+** set of columns. The ORDER BY clause only matches index columns beyond the
+** the first nEqCol columns.
+**
+** All terms of the ORDER BY clause must be either ASC or DESC. The
+** *pbRev value is set to 1 if the ORDER BY clause is all DESC and it is
+** set to 0 if the ORDER BY clause is all ASC.
+*/
+static Index *tqfindSortingIndex(
+ Table *pTab, /* The table to be sorted */
+ int base, /* Cursor number for pTab */
+ ExprList *pOrderBy, /* The ORDER BY clause */
+ Index *pPreferredIdx, /* Use this index, if possible and not NULL */
+ int nEqCol, /* Number of index columns used with == constraints */
+ int *pbRev /* Set to 1 if ORDER BY is DESC */
+){
+ int i, j;
+ Index *pMatch;
+ Index *pIdx;
+ int sortOrder;
+
+ assert( pOrderBy!=0 );
+ assert( pOrderBy->nExpr>0 );
+ sortOrder = pOrderBy->a[0].sortOrder & STQLITE_SO_DIRMASK;
+ for(i=0; i<pOrderBy->nExpr; i++){
+ Expr *p;
+ if( (pOrderBy->a[i].sortOrder & STQLITE_SO_DIRMASK)!=sortOrder ){
+ /* Indices can only be used if all ORDER BY terms are either
+ ** DESC or ASC. Indices cannot be used on a mixture. */
+ return 0;
+ }
+ if( (pOrderBy->a[i].sortOrder & STQLITE_SO_TYPEMASK)!=STQLITE_SO_UNK ){
+ /* Do not sort by index if there is a COLLATE clause */
+ return 0;
+ }
+ p = pOrderBy->a[i].pExpr;
+ if( p->op!=TK_COLUMN || p->iTable!=base ){
+ /* Can not use an index sort on anything that is not a column in the
+ ** left-most table of the FROM clause */
+ return 0;
+ }
+ }
+
+ /* If we get this far, it means the ORDER BY clause consists only of
+ ** ascending columns in the left-most table of the FROM clause. Now
+ ** check for a matching index.
+ */
+ pMatch = 0;
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ int nExpr = pOrderBy->nExpr;
+ if( pIdx->nColumn < nEqCol || pIdx->nColumn < nExpr ) continue;
+ for(i=j=0; i<nEqCol; i++){
+ if( pPreferredIdx->aiColumn[i]!=pIdx->aiColumn[i] ) break;
+ if( j<nExpr && pOrderBy->a[j].pExpr->iColumn==pIdx->aiColumn[i] ){ j++; }
+ }
+ if( i<nEqCol ) continue;
+ for(i=0; i+j<nExpr; i++){
+ if( pOrderBy->a[i+j].pExpr->iColumn!=pIdx->aiColumn[i+nEqCol] ) break;
+ }
+ if( i+j>=nExpr ){
+ pMatch = pIdx;
+ if( pIdx==pPreferredIdx ) break;
+ }
+ }
+ if( pMatch && pbRev ){
+ *pbRev = sortOrder==STQLITE_SO_DESC;
+ }
+ return pMatch;
+}
+
+/*
+** Generate the beginning of the loop used for WHERE clause processing.
+** The return value is a pointer to an (opaque) structure that tqcontains
+** information needed to terminate the loop. Later, the calling routine
+** should invoke sqliteWhereEnd() with the return value of this function
+** in order to complete the WHERE clause processing.
+**
+** If an error occurs, this routine returns NULL.
+**
+** The basic idea is to do a nested loop, one loop for each table in
+** the FROM clause of a select. (INSERT and UPDATE statements are the
+** same as a SELECT with only a single table in the FROM clause.) For
+** example, if the SQL is this:
+**
+** SELECT * FROM t1, t2, t3 WHERE ...;
+**
+** Then the code generated is conceptually like the following:
+**
+** foreach row1 in t1 do \ Code generated
+** foreach row2 in t2 do |-- by sqliteWhereBegin()
+** foreach row3 in t3 do /
+** ...
+** end \ Code generated
+** end |-- by sqliteWhereEnd()
+** end /
+**
+** There are Btree cursors associated with each table. t1 uses cursor
+** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor.
+** And so forth. This routine generates code to open those VDBE cursors
+** and sqliteWhereEnd() generates the code to close them.
+**
+** If the WHERE clause is empty, the foreach loops must each scan their
+** entire tables. Thus a three-way join is an O(N^3) operation. But if
+** the tables have indices and there are terms in the WHERE clause that
+** refer to those indices, a complete table scan can be avoided and the
+** code will run much faster. Most of the work of this routine is checking
+** to see if there are indices that can be used to speed up the loop.
+**
+** Terms of the WHERE clause are also used to limit which rows actually
+** make it to the "..." in the middle of the loop. After each "foreach",
+** terms of the WHERE clause that use only terms in that loop and outer
+** loops are evaluated and if false a jump is made around all subsequent
+** inner loops (or around the "..." if the test occurs within the inner-
+** most loop)
+**
+** OUTER JOINS
+**
+** An outer join of tables t1 and t2 is conceptally coded as follows:
+**
+** foreach row1 in t1 do
+** flag = 0
+** foreach row2 in t2 do
+** start:
+** ...
+** flag = 1
+** end
+** if flag==0 then
+** move the row2 cursor to a null row
+** goto start
+** fi
+** end
+**
+** ORDER BY CLAUSE PROCESSING
+**
+** *ppOrderBy is a pointer to the ORDER BY clause of a SELECT statement,
+** if there is one. If there is no ORDER BY clause or if this routine
+** is called from an UPDATE or DELETE statement, then ppOrderBy is NULL.
+**
+** If an index can be used so that the natural output order of the table
+** scan is correct for the ORDER BY clause, then that index is used and
+** *ppOrderBy is set to NULL. This is an optimization that prevents an
+** unnecessary sort of the result set if an index appropriate for the
+** ORDER BY clause already exists.
+**
+** If the where clause loops cannot be arranged to provide the correct
+** output order, then the *ppOrderBy is unchanged.
+*/
+WhereInfo *sqliteWhereBegin(
+ Parse *pParse, /* The parser context */
+ SrcList *pTabList, /* A list of all tables to be scanned */
+ Expr *pWhere, /* The WHERE clause */
+ int pushKey, /* If TRUE, leave the table key on the stack */
+ ExprList **ppOrderBy /* An ORDER BY clause, or NULL */
+){
+ int i; /* Loop counter */
+ WhereInfo *pWInfo; /* Will become the return value of this function */
+ Vdbe *v = pParse->pVdbe; /* The virtual database engine */
+ int brk, cont = 0; /* Addresses used during code generation */
+ int nExpr; /* Number of subexpressions in the WHERE clause */
+ int loopMask; /* One bit set for each outer loop */
+ int haveKey; /* True if KEY is on the stack */
+ ExprMaskSet maskSet; /* The expression tqmask set */
+ int iDirectEq[32]; /* Term of the form ROWID==X for the N-th table */
+ int iDirectLt[32]; /* Term of the form ROWID<X or ROWID<=X */
+ int iDirectGt[32]; /* Term of the form ROWID>X or ROWID>=X */
+ ExprInfo aExpr[101]; /* The WHERE clause is divided into these expressions */
+
+ /* pushKey is only allowed if there is a single table (as in an INSERT or
+ ** UPDATE statement)
+ */
+ assert( pushKey==0 || pTabList->nSrc==1 );
+
+ /* Split the WHERE clause into separate subexpressions where each
+ ** subexpression is separated by an AND operator. If the aExpr[]
+ ** array fills up, the last entry might point to an expression which
+ ** tqcontains additional unfactored AND operators.
+ */
+ initMaskSet(&maskSet);
+ memset(aExpr, 0, sizeof(aExpr));
+ nExpr = exprSplit(ARRAYSIZE(aExpr), aExpr, pWhere);
+ if( nExpr==ARRAYSIZE(aExpr) ){
+ sqliteErrorMsg(pParse, "WHERE clause too complex - no more "
+ "than %d terms allowed", (int)ARRAYSIZE(aExpr)-1);
+ return 0;
+ }
+
+ /* Allocate and initialize the WhereInfo structure that will become the
+ ** return value.
+ */
+ pWInfo = sqliteMalloc( sizeof(WhereInfo) + pTabList->nSrc*sizeof(WhereLevel));
+ if( sqlite_malloc_failed ){
+ sqliteFree(pWInfo);
+ return 0;
+ }
+ pWInfo->pParse = pParse;
+ pWInfo->pTabList = pTabList;
+ pWInfo->peakNTab = pWInfo->savedNTab = pParse->nTab;
+ pWInfo->iBreak = sqliteVdbeMakeLabel(v);
+
+ /* Special case: a WHERE clause that is constant. Evaluate the
+ ** expression and either jump over all of the code or fall thru.
+ */
+ if( pWhere && (pTabList->nSrc==0 || sqliteExprIsConstant(pWhere)) ){
+ sqliteExprIfFalse(pParse, pWhere, pWInfo->iBreak, 1);
+ pWhere = 0;
+ }
+
+ /* Analyze all of the subexpressions.
+ */
+ for(i=0; i<nExpr; i++){
+ exprAnalyze(&maskSet, &aExpr[i]);
+
+ /* If we are executing a trigger body, remove all references to
+ ** new.* and old.* tables from the prerequisite masks.
+ */
+ if( pParse->trigStack ){
+ int x;
+ if( (x = pParse->trigStack->newIdx) >= 0 ){
+ int tqmask = ~getMask(&maskSet, x);
+ aExpr[i].prereqRight &= tqmask;
+ aExpr[i].prereqLeft &= tqmask;
+ aExpr[i].prereqAll &= tqmask;
+ }
+ if( (x = pParse->trigStack->oldIdx) >= 0 ){
+ int tqmask = ~getMask(&maskSet, x);
+ aExpr[i].prereqRight &= tqmask;
+ aExpr[i].prereqLeft &= tqmask;
+ aExpr[i].prereqAll &= tqmask;
+ }
+ }
+ }
+
+ /* Figure out what index to use (if any) for each nested loop.
+ ** Make pWInfo->a[i].pIdx point to the index to use for the i-th nested
+ ** loop where i==0 is the outer loop and i==pTabList->nSrc-1 is the inner
+ ** loop.
+ **
+ ** If terms exist that use the ROWID of any table, then set the
+ ** iDirectEq[], iDirectLt[], or iDirectGt[] elements for that table
+ ** to the index of the term containing the ROWID. We always prefer
+ ** to use a ROWID which can directly access a table rather than an
+ ** index which requires reading an index first to get the rowid then
+ ** doing a second read of the actual database table.
+ **
+ ** Actually, if there are more than 32 tables in the join, only the
+ ** first 32 tables are candidates for indices. This is (again) due
+ ** to the limit of 32 bits in an integer bittqmask.
+ */
+ loopMask = 0;
+ for(i=0; i<pTabList->nSrc && i<ARRAYSIZE(iDirectEq); i++){
+ int j;
+ int iCur = pTabList->a[i].iCursor; /* The cursor for this table */
+ int tqmask = getMask(&maskSet, iCur); /* Cursor tqmask for this table */
+ Table *pTab = pTabList->a[i].pTab;
+ Index *pIdx;
+ Index *pBestIdx = 0;
+ int bestScore = 0;
+
+ /* Check to see if there is an expression that uses only the
+ ** ROWID field of this table. For terms of the form ROWID==expr
+ ** set iDirectEq[i] to the index of the term. For terms of the
+ ** form ROWID<expr or ROWID<=expr set iDirectLt[i] to the term index.
+ ** For terms like ROWID>expr or ROWID>=expr set iDirectGt[i].
+ **
+ ** (Added:) Treat ROWID IN expr like ROWID=expr.
+ */
+ pWInfo->a[i].iCur = -1;
+ iDirectEq[i] = -1;
+ iDirectLt[i] = -1;
+ iDirectGt[i] = -1;
+ for(j=0; j<nExpr; j++){
+ if( aExpr[j].idxLeft==iCur && aExpr[j].p->pLeft->iColumn<0
+ && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){
+ switch( aExpr[j].p->op ){
+ case TK_IN:
+ case TK_EQ: iDirectEq[i] = j; break;
+ case TK_LE:
+ case TK_LT: iDirectLt[i] = j; break;
+ case TK_GE:
+ case TK_GT: iDirectGt[i] = j; break;
+ }
+ }
+ if( aExpr[j].idxRight==iCur && aExpr[j].p->pRight->iColumn<0
+ && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ){
+ switch( aExpr[j].p->op ){
+ case TK_EQ: iDirectEq[i] = j; break;
+ case TK_LE:
+ case TK_LT: iDirectGt[i] = j; break;
+ case TK_GE:
+ case TK_GT: iDirectLt[i] = j; break;
+ }
+ }
+ }
+ if( iDirectEq[i]>=0 ){
+ loopMask |= tqmask;
+ pWInfo->a[i].pIdx = 0;
+ continue;
+ }
+
+ /* Do a search for usable indices. Leave pBestIdx pointing to
+ ** the "best" index. pBestIdx is left set to NULL if no indices
+ ** are usable.
+ **
+ ** The best index is determined as follows. For each of the
+ ** left-most terms that is fixed by an equality operator, add
+ ** 8 to the score. The right-most term of the index may be
+ ** constrained by an inequality. Add 1 if for an "x<..." constraint
+ ** and add 2 for an "x>..." constraint. Chose the index that
+ ** gives the best score.
+ **
+ ** This scoring system is designed so that the score can later be
+ ** used to determine how the index is used. If the score&7 is 0
+ ** then all constraints are equalities. If score&1 is not 0 then
+ ** there is an inequality used as a termination key. (ex: "x<...")
+ ** If score&2 is not 0 then there is an inequality used as the
+ ** start key. (ex: "x>..."). A score or 4 is the special case
+ ** of an IN operator constraint. (ex: "x IN ...").
+ **
+ ** The IN operator (as in "<expr> IN (...)") is treated the same as
+ ** an equality comparison except that it can only be used on the
+ ** left-most column of an index and other terms of the WHERE clause
+ ** cannot be used in conjunction with the IN operator to help satisfy
+ ** other columns of the index.
+ */
+ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
+ int eqMask = 0; /* Index columns covered by an x=... term */
+ int ltMask = 0; /* Index columns covered by an x<... term */
+ int gtMask = 0; /* Index columns covered by an x>... term */
+ int inMask = 0; /* Index columns covered by an x IN .. term */
+ int nEq, m, score;
+
+ if( pIdx->nColumn>32 ) continue; /* Ignore indices too many columns */
+ for(j=0; j<nExpr; j++){
+ if( aExpr[j].idxLeft==iCur
+ && (aExpr[j].prereqRight & loopMask)==aExpr[j].prereqRight ){
+ int iColumn = aExpr[j].p->pLeft->iColumn;
+ int k;
+ for(k=0; k<pIdx->nColumn; k++){
+ if( pIdx->aiColumn[k]==iColumn ){
+ switch( aExpr[j].p->op ){
+ case TK_IN: {
+ if( k==0 ) inMask |= 1;
+ break;
+ }
+ case TK_EQ: {
+ eqMask |= 1<<k;
+ break;
+ }
+ case TK_LE:
+ case TK_LT: {
+ ltMask |= 1<<k;
+ break;
+ }
+ case TK_GE:
+ case TK_GT: {
+ gtMask |= 1<<k;
+ break;
+ }
+ default: {
+ /* CANT_HAPPEN */
+ assert( 0 );
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ if( aExpr[j].idxRight==iCur
+ && (aExpr[j].prereqLeft & loopMask)==aExpr[j].prereqLeft ){
+ int iColumn = aExpr[j].p->pRight->iColumn;
+ int k;
+ for(k=0; k<pIdx->nColumn; k++){
+ if( pIdx->aiColumn[k]==iColumn ){
+ switch( aExpr[j].p->op ){
+ case TK_EQ: {
+ eqMask |= 1<<k;
+ break;
+ }
+ case TK_LE:
+ case TK_LT: {
+ gtMask |= 1<<k;
+ break;
+ }
+ case TK_GE:
+ case TK_GT: {
+ ltMask |= 1<<k;
+ break;
+ }
+ default: {
+ /* CANT_HAPPEN */
+ assert( 0 );
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ /* The following loop ends with nEq set to the number of columns
+ ** on the left of the index with == constraints.
+ */
+ for(nEq=0; nEq<pIdx->nColumn; nEq++){
+ m = (1<<(nEq+1))-1;
+ if( (m & eqMask)!=m ) break;
+ }
+ score = nEq*8; /* Base score is 8 times number of == constraints */
+ m = 1<<nEq;
+ if( m & ltMask ) score++; /* Increase score for a < constraint */
+ if( m & gtMask ) score+=2; /* Increase score for a > constraint */
+ if( score==0 && inMask ) score = 4; /* Default score for IN constraint */
+ if( score>bestScore ){
+ pBestIdx = pIdx;
+ bestScore = score;
+ }
+ }
+ pWInfo->a[i].pIdx = pBestIdx;
+ pWInfo->a[i].score = bestScore;
+ pWInfo->a[i].bRev = 0;
+ loopMask |= tqmask;
+ if( pBestIdx ){
+ pWInfo->a[i].iCur = pParse->nTab++;
+ pWInfo->peakNTab = pParse->nTab;
+ }
+ }
+
+ /* Check to see if the ORDER BY clause is or can be satisfied by the
+ ** use of an index on the first table.
+ */
+ if( ppOrderBy && *ppOrderBy && pTabList->nSrc>0 ){
+ Index *pSortIdx;
+ Index *pIdx;
+ Table *pTab;
+ int bRev = 0;
+
+ pTab = pTabList->a[0].pTab;
+ pIdx = pWInfo->a[0].pIdx;
+ if( pIdx && pWInfo->a[0].score==4 ){
+ /* If there is already an IN index on the left-most table,
+ ** it will not give the correct sort order.
+ ** So, pretend that no suitable index is found.
+ */
+ pSortIdx = 0;
+ }else if( iDirectEq[0]>=0 || iDirectLt[0]>=0 || iDirectGt[0]>=0 ){
+ /* If the left-most column is accessed using its ROWID, then do
+ ** not try to sort by index.
+ */
+ pSortIdx = 0;
+ }else{
+ int nEqCol = (pWInfo->a[0].score+4)/8;
+ pSortIdx = tqfindSortingIndex(pTab, pTabList->a[0].iCursor,
+ *ppOrderBy, pIdx, nEqCol, &bRev);
+ }
+ if( pSortIdx && (pIdx==0 || pIdx==pSortIdx) ){
+ if( pIdx==0 ){
+ pWInfo->a[0].pIdx = pSortIdx;
+ pWInfo->a[0].iCur = pParse->nTab++;
+ pWInfo->peakNTab = pParse->nTab;
+ }
+ pWInfo->a[0].bRev = bRev;
+ *ppOrderBy = 0;
+ }
+ }
+
+ /* Open all tables in the pTabList and all indices used by those tables.
+ */
+ for(i=0; i<pTabList->nSrc; i++){
+ Table *pTab;
+ Index *pIx;
+
+ pTab = pTabList->a[i].pTab;
+ if( pTab->isTransient || pTab->pSelect ) continue;
+ sqliteVdbeAddOp(v, OP_Integer, pTab->iDb, 0);
+ sqliteVdbeOp3(v, OP_OpenRead, pTabList->a[i].iCursor, pTab->tnum,
+ pTab->zName, P3_STATIC);
+ sqliteCodeVerifySchema(pParse, pTab->iDb);
+ if( (pIx = pWInfo->a[i].pIdx)!=0 ){
+ sqliteVdbeAddOp(v, OP_Integer, pIx->iDb, 0);
+ sqliteVdbeOp3(v, OP_OpenRead, pWInfo->a[i].iCur, pIx->tnum, pIx->zName,0);
+ }
+ }
+
+ /* Generate the code to do the search
+ */
+ loopMask = 0;
+ for(i=0; i<pTabList->nSrc; i++){
+ int j, k;
+ int iCur = pTabList->a[i].iCursor;
+ Index *pIdx;
+ WhereLevel *pLevel = &pWInfo->a[i];
+
+ /* If this is the right table of a LEFT OUTER JOIN, allocate and
+ ** initialize a memory cell that records if this table matches any
+ ** row of the left table of the join.
+ */
+ if( i>0 && (pTabList->a[i-1].jointype & JT_LEFT)!=0 ){
+ if( !pParse->nMem ) pParse->nMem++;
+ pLevel->iLeftJoin = pParse->nMem++;
+ sqliteVdbeAddOp(v, OP_String, 0, 0);
+ sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
+ }
+
+ pIdx = pLevel->pIdx;
+ pLevel->inOp = OP_Noop;
+ if( i<ARRAYSIZE(iDirectEq) && iDirectEq[i]>=0 ){
+ /* Case 1: We can directly reference a single row using an
+ ** equality comparison against the ROWID field. Or
+ ** we reference multiple rows using a "rowid IN (...)"
+ ** construct.
+ */
+ k = iDirectEq[i];
+ assert( k<nExpr );
+ assert( aExpr[k].p!=0 );
+ assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
+ brk = pLevel->brk = sqliteVdbeMakeLabel(v);
+ if( aExpr[k].idxLeft==iCur ){
+ Expr *pX = aExpr[k].p;
+ if( pX->op!=TK_IN ){
+ sqliteExprCode(pParse, aExpr[k].p->pRight);
+ }else if( pX->pList ){
+ sqliteVdbeAddOp(v, OP_SetFirst, pX->iTable, brk);
+ pLevel->inOp = OP_SetNext;
+ pLevel->inP1 = pX->iTable;
+ pLevel->inP2 = sqliteVdbeCurrentAddr(v);
+ }else{
+ assert( pX->pSelect );
+ sqliteVdbeAddOp(v, OP_Rewind, pX->iTable, brk);
+ sqliteVdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
+ pLevel->inP2 = sqliteVdbeAddOp(v, OP_FullKey, pX->iTable, 0);
+ pLevel->inOp = OP_Next;
+ pLevel->inP1 = pX->iTable;
+ }
+ }else{
+ sqliteExprCode(pParse, aExpr[k].p->pLeft);
+ }
+ aExpr[k].p = 0;
+ cont = pLevel->cont = sqliteVdbeMakeLabel(v);
+ sqliteVdbeAddOp(v, OP_MustBeInt, 1, brk);
+ haveKey = 0;
+ sqliteVdbeAddOp(v, OP_NotExists, iCur, brk);
+ pLevel->op = OP_Noop;
+ }else if( pIdx!=0 && pLevel->score>0 && pLevel->score%4==0 ){
+ /* Case 2: There is an index and all terms of the WHERE clause that
+ ** refer to the index use the "==" or "IN" operators.
+ */
+ int start;
+ int testOp;
+ int nColumn = (pLevel->score+4)/8;
+ brk = pLevel->brk = sqliteVdbeMakeLabel(v);
+ for(j=0; j<nColumn; j++){
+ for(k=0; k<nExpr; k++){
+ Expr *pX = aExpr[k].p;
+ if( pX==0 ) continue;
+ if( aExpr[k].idxLeft==iCur
+ && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
+ && pX->pLeft->iColumn==pIdx->aiColumn[j]
+ ){
+ if( pX->op==TK_EQ ){
+ sqliteExprCode(pParse, pX->pRight);
+ aExpr[k].p = 0;
+ break;
+ }
+ if( pX->op==TK_IN && nColumn==1 ){
+ if( pX->pList ){
+ sqliteVdbeAddOp(v, OP_SetFirst, pX->iTable, brk);
+ pLevel->inOp = OP_SetNext;
+ pLevel->inP1 = pX->iTable;
+ pLevel->inP2 = sqliteVdbeCurrentAddr(v);
+ }else{
+ assert( pX->pSelect );
+ sqliteVdbeAddOp(v, OP_Rewind, pX->iTable, brk);
+ sqliteVdbeAddOp(v, OP_KeyAsData, pX->iTable, 1);
+ pLevel->inP2 = sqliteVdbeAddOp(v, OP_FullKey, pX->iTable, 0);
+ pLevel->inOp = OP_Next;
+ pLevel->inP1 = pX->iTable;
+ }
+ aExpr[k].p = 0;
+ break;
+ }
+ }
+ if( aExpr[k].idxRight==iCur
+ && aExpr[k].p->op==TK_EQ
+ && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
+ && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
+ ){
+ sqliteExprCode(pParse, aExpr[k].p->pLeft);
+ aExpr[k].p = 0;
+ break;
+ }
+ }
+ }
+ pLevel->iMem = pParse->nMem++;
+ cont = pLevel->cont = sqliteVdbeMakeLabel(v);
+ sqliteVdbeAddOp(v, OP_NotNull, -nColumn, sqliteVdbeCurrentAddr(v)+3);
+ sqliteVdbeAddOp(v, OP_Pop, nColumn, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, brk);
+ sqliteVdbeAddOp(v, OP_MakeKey, nColumn, 0);
+ sqliteAddIdxKeyType(v, pIdx);
+ if( nColumn==pIdx->nColumn || pLevel->bRev ){
+ sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 0);
+ testOp = OP_IdxGT;
+ }else{
+ sqliteVdbeAddOp(v, OP_Dup, 0, 0);
+ sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
+ sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
+ testOp = OP_IdxGE;
+ }
+ if( pLevel->bRev ){
+ /* Scan in reverse order */
+ sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
+ sqliteVdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
+ start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
+ sqliteVdbeAddOp(v, OP_IdxLT, pLevel->iCur, brk);
+ pLevel->op = OP_Prev;
+ }else{
+ /* Scan in the forward order */
+ sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
+ start = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
+ sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk);
+ pLevel->op = OP_Next;
+ }
+ sqliteVdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
+ sqliteVdbeAddOp(v, OP_IdxIsNull, nColumn, cont);
+ sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
+ if( i==pTabList->nSrc-1 && pushKey ){
+ haveKey = 1;
+ }else{
+ sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
+ haveKey = 0;
+ }
+ pLevel->p1 = pLevel->iCur;
+ pLevel->p2 = start;
+ }else if( i<ARRAYSIZE(iDirectLt) && (iDirectLt[i]>=0 || iDirectGt[i]>=0) ){
+ /* Case 3: We have an inequality comparison against the ROWID field.
+ */
+ int testOp = OP_Noop;
+ int start;
+
+ brk = pLevel->brk = sqliteVdbeMakeLabel(v);
+ cont = pLevel->cont = sqliteVdbeMakeLabel(v);
+ if( iDirectGt[i]>=0 ){
+ k = iDirectGt[i];
+ assert( k<nExpr );
+ assert( aExpr[k].p!=0 );
+ assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
+ if( aExpr[k].idxLeft==iCur ){
+ sqliteExprCode(pParse, aExpr[k].p->pRight);
+ }else{
+ sqliteExprCode(pParse, aExpr[k].p->pLeft);
+ }
+ sqliteVdbeAddOp(v, OP_ForceInt,
+ aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT, brk);
+ sqliteVdbeAddOp(v, OP_MoveTo, iCur, brk);
+ aExpr[k].p = 0;
+ }else{
+ sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
+ }
+ if( iDirectLt[i]>=0 ){
+ k = iDirectLt[i];
+ assert( k<nExpr );
+ assert( aExpr[k].p!=0 );
+ assert( aExpr[k].idxLeft==iCur || aExpr[k].idxRight==iCur );
+ if( aExpr[k].idxLeft==iCur ){
+ sqliteExprCode(pParse, aExpr[k].p->pRight);
+ }else{
+ sqliteExprCode(pParse, aExpr[k].p->pLeft);
+ }
+ /* sqliteVdbeAddOp(v, OP_MustBeInt, 0, sqliteVdbeCurrentAddr(v)+1); */
+ pLevel->iMem = pParse->nMem++;
+ sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
+ if( aExpr[k].p->op==TK_LT || aExpr[k].p->op==TK_GT ){
+ testOp = OP_Ge;
+ }else{
+ testOp = OP_Gt;
+ }
+ aExpr[k].p = 0;
+ }
+ start = sqliteVdbeCurrentAddr(v);
+ pLevel->op = OP_Next;
+ pLevel->p1 = iCur;
+ pLevel->p2 = start;
+ if( testOp!=OP_Noop ){
+ sqliteVdbeAddOp(v, OP_Recno, iCur, 0);
+ sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
+ sqliteVdbeAddOp(v, testOp, 0, brk);
+ }
+ haveKey = 0;
+ }else if( pIdx==0 ){
+ /* Case 4: There is no usable index. We must do a complete
+ ** scan of the entire database table.
+ */
+ int start;
+
+ brk = pLevel->brk = sqliteVdbeMakeLabel(v);
+ cont = pLevel->cont = sqliteVdbeMakeLabel(v);
+ sqliteVdbeAddOp(v, OP_Rewind, iCur, brk);
+ start = sqliteVdbeCurrentAddr(v);
+ pLevel->op = OP_Next;
+ pLevel->p1 = iCur;
+ pLevel->p2 = start;
+ haveKey = 0;
+ }else{
+ /* Case 5: The WHERE clause term that refers to the right-most
+ ** column of the index is an inequality. For example, if
+ ** the index is on (x,y,z) and the WHERE clause is of the
+ ** form "x=5 AND y<10" then this case is used. Only the
+ ** right-most column can be an inequality - the rest must
+ ** use the "==" operator.
+ **
+ ** This case is also used when there are no WHERE clause
+ ** constraints but an index is selected anyway, in order
+ ** to force the output order to conform to an ORDER BY.
+ */
+ int score = pLevel->score;
+ int nEqColumn = score/8;
+ int start;
+ int leFlag, geFlag;
+ int testOp;
+
+ /* Evaluate the equality constraints
+ */
+ for(j=0; j<nEqColumn; j++){
+ for(k=0; k<nExpr; k++){
+ if( aExpr[k].p==0 ) continue;
+ if( aExpr[k].idxLeft==iCur
+ && aExpr[k].p->op==TK_EQ
+ && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
+ && aExpr[k].p->pLeft->iColumn==pIdx->aiColumn[j]
+ ){
+ sqliteExprCode(pParse, aExpr[k].p->pRight);
+ aExpr[k].p = 0;
+ break;
+ }
+ if( aExpr[k].idxRight==iCur
+ && aExpr[k].p->op==TK_EQ
+ && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
+ && aExpr[k].p->pRight->iColumn==pIdx->aiColumn[j]
+ ){
+ sqliteExprCode(pParse, aExpr[k].p->pLeft);
+ aExpr[k].p = 0;
+ break;
+ }
+ }
+ }
+
+ /* Duplicate the equality term values because they will all be
+ ** used twice: once to make the termination key and once to make the
+ ** start key.
+ */
+ for(j=0; j<nEqColumn; j++){
+ sqliteVdbeAddOp(v, OP_Dup, nEqColumn-1, 0);
+ }
+
+ /* Labels for the beginning and end of the loop
+ */
+ cont = pLevel->cont = sqliteVdbeMakeLabel(v);
+ brk = pLevel->brk = sqliteVdbeMakeLabel(v);
+
+ /* Generate the termination key. This is the key value that
+ ** will end the search. There is no termination key if there
+ ** are no equality terms and no "X<..." term.
+ **
+ ** 2002-Dec-04: On a reverse-order scan, the so-called "termination"
+ ** key computed here really ends up being the start key.
+ */
+ if( (score & 1)!=0 ){
+ for(k=0; k<nExpr; k++){
+ Expr *pExpr = aExpr[k].p;
+ if( pExpr==0 ) continue;
+ if( aExpr[k].idxLeft==iCur
+ && (pExpr->op==TK_LT || pExpr->op==TK_LE)
+ && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
+ && pExpr->pLeft->iColumn==pIdx->aiColumn[j]
+ ){
+ sqliteExprCode(pParse, pExpr->pRight);
+ leFlag = pExpr->op==TK_LE;
+ aExpr[k].p = 0;
+ break;
+ }
+ if( aExpr[k].idxRight==iCur
+ && (pExpr->op==TK_GT || pExpr->op==TK_GE)
+ && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
+ && pExpr->pRight->iColumn==pIdx->aiColumn[j]
+ ){
+ sqliteExprCode(pParse, pExpr->pLeft);
+ leFlag = pExpr->op==TK_GE;
+ aExpr[k].p = 0;
+ break;
+ }
+ }
+ testOp = OP_IdxGE;
+ }else{
+ testOp = nEqColumn>0 ? OP_IdxGE : OP_Noop;
+ leFlag = 1;
+ }
+ if( testOp!=OP_Noop ){
+ int nCol = nEqColumn + (score & 1);
+ pLevel->iMem = pParse->nMem++;
+ sqliteVdbeAddOp(v, OP_NotNull, -nCol, sqliteVdbeCurrentAddr(v)+3);
+ sqliteVdbeAddOp(v, OP_Pop, nCol, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, brk);
+ sqliteVdbeAddOp(v, OP_MakeKey, nCol, 0);
+ sqliteAddIdxKeyType(v, pIdx);
+ if( leFlag ){
+ sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
+ }
+ if( pLevel->bRev ){
+ sqliteVdbeAddOp(v, OP_MoveLt, pLevel->iCur, brk);
+ }else{
+ sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
+ }
+ }else if( pLevel->bRev ){
+ sqliteVdbeAddOp(v, OP_Last, pLevel->iCur, brk);
+ }
+
+ /* Generate the start key. This is the key that defines the lower
+ ** bound on the search. There is no start key if there are no
+ ** equality terms and if there is no "X>..." term. In
+ ** that case, generate a "Rewind" instruction in place of the
+ ** start key search.
+ **
+ ** 2002-Dec-04: In the case of a reverse-order search, the so-called
+ ** "start" key really ends up being used as the termination key.
+ */
+ if( (score & 2)!=0 ){
+ for(k=0; k<nExpr; k++){
+ Expr *pExpr = aExpr[k].p;
+ if( pExpr==0 ) continue;
+ if( aExpr[k].idxLeft==iCur
+ && (pExpr->op==TK_GT || pExpr->op==TK_GE)
+ && (aExpr[k].prereqRight & loopMask)==aExpr[k].prereqRight
+ && pExpr->pLeft->iColumn==pIdx->aiColumn[j]
+ ){
+ sqliteExprCode(pParse, pExpr->pRight);
+ geFlag = pExpr->op==TK_GE;
+ aExpr[k].p = 0;
+ break;
+ }
+ if( aExpr[k].idxRight==iCur
+ && (pExpr->op==TK_LT || pExpr->op==TK_LE)
+ && (aExpr[k].prereqLeft & loopMask)==aExpr[k].prereqLeft
+ && pExpr->pRight->iColumn==pIdx->aiColumn[j]
+ ){
+ sqliteExprCode(pParse, pExpr->pLeft);
+ geFlag = pExpr->op==TK_LE;
+ aExpr[k].p = 0;
+ break;
+ }
+ }
+ }else{
+ geFlag = 1;
+ }
+ if( nEqColumn>0 || (score&2)!=0 ){
+ int nCol = nEqColumn + ((score&2)!=0);
+ sqliteVdbeAddOp(v, OP_NotNull, -nCol, sqliteVdbeCurrentAddr(v)+3);
+ sqliteVdbeAddOp(v, OP_Pop, nCol, 0);
+ sqliteVdbeAddOp(v, OP_Goto, 0, brk);
+ sqliteVdbeAddOp(v, OP_MakeKey, nCol, 0);
+ sqliteAddIdxKeyType(v, pIdx);
+ if( !geFlag ){
+ sqliteVdbeAddOp(v, OP_IncrKey, 0, 0);
+ }
+ if( pLevel->bRev ){
+ pLevel->iMem = pParse->nMem++;
+ sqliteVdbeAddOp(v, OP_MemStore, pLevel->iMem, 1);
+ testOp = OP_IdxLT;
+ }else{
+ sqliteVdbeAddOp(v, OP_MoveTo, pLevel->iCur, brk);
+ }
+ }else if( pLevel->bRev ){
+ testOp = OP_Noop;
+ }else{
+ sqliteVdbeAddOp(v, OP_Rewind, pLevel->iCur, brk);
+ }
+
+ /* Generate the the top of the loop. If there is a termination
+ ** key we have to test for that key and abort at the top of the
+ ** loop.
+ */
+ start = sqliteVdbeCurrentAddr(v);
+ if( testOp!=OP_Noop ){
+ sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iMem, 0);
+ sqliteVdbeAddOp(v, testOp, pLevel->iCur, brk);
+ }
+ sqliteVdbeAddOp(v, OP_RowKey, pLevel->iCur, 0);
+ sqliteVdbeAddOp(v, OP_IdxIsNull, nEqColumn + (score & 1), cont);
+ sqliteVdbeAddOp(v, OP_IdxRecno, pLevel->iCur, 0);
+ if( i==pTabList->nSrc-1 && pushKey ){
+ haveKey = 1;
+ }else{
+ sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
+ haveKey = 0;
+ }
+
+ /* Record the instruction used to terminate the loop.
+ */
+ pLevel->op = pLevel->bRev ? OP_Prev : OP_Next;
+ pLevel->p1 = pLevel->iCur;
+ pLevel->p2 = start;
+ }
+ loopMask |= getMask(&maskSet, iCur);
+
+ /* Insert code to test every subexpression that can be completely
+ ** computed using the current set of tables.
+ */
+ for(j=0; j<nExpr; j++){
+ if( aExpr[j].p==0 ) continue;
+ if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue;
+ if( pLevel->iLeftJoin && !ExprHasProperty(aExpr[j].p,EP_FromJoin) ){
+ continue;
+ }
+ if( haveKey ){
+ haveKey = 0;
+ sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
+ }
+ sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1);
+ aExpr[j].p = 0;
+ }
+ brk = cont;
+
+ /* For a LEFT OUTER JOIN, generate code that will record the fact that
+ ** at least one row of the right table has matched the left table.
+ */
+ if( pLevel->iLeftJoin ){
+ pLevel->top = sqliteVdbeCurrentAddr(v);
+ sqliteVdbeAddOp(v, OP_Integer, 1, 0);
+ sqliteVdbeAddOp(v, OP_MemStore, pLevel->iLeftJoin, 1);
+ for(j=0; j<nExpr; j++){
+ if( aExpr[j].p==0 ) continue;
+ if( (aExpr[j].prereqAll & loopMask)!=aExpr[j].prereqAll ) continue;
+ if( haveKey ){
+ /* Cannot happen. "haveKey" can only be true if pushKey is true
+ ** an pushKey can only be true for DELETE and UPDATE and there are
+ ** no outer joins with DELETE and UPDATE.
+ */
+ haveKey = 0;
+ sqliteVdbeAddOp(v, OP_MoveTo, iCur, 0);
+ }
+ sqliteExprIfFalse(pParse, aExpr[j].p, cont, 1);
+ aExpr[j].p = 0;
+ }
+ }
+ }
+ pWInfo->iContinue = cont;
+ if( pushKey && !haveKey ){
+ sqliteVdbeAddOp(v, OP_Recno, pTabList->a[0].iCursor, 0);
+ }
+ freeMaskSet(&maskSet);
+ return pWInfo;
+}
+
+/*
+** Generate the end of the WHERE loop. See comments on
+** sqliteWhereBegin() for additional information.
+*/
+void sqliteWhereEnd(WhereInfo *pWInfo){
+ Vdbe *v = pWInfo->pParse->pVdbe;
+ int i;
+ WhereLevel *pLevel;
+ SrcList *pTabList = pWInfo->pTabList;
+
+ for(i=pTabList->nSrc-1; i>=0; i--){
+ pLevel = &pWInfo->a[i];
+ sqliteVdbeResolveLabel(v, pLevel->cont);
+ if( pLevel->op!=OP_Noop ){
+ sqliteVdbeAddOp(v, pLevel->op, pLevel->p1, pLevel->p2);
+ }
+ sqliteVdbeResolveLabel(v, pLevel->brk);
+ if( pLevel->inOp!=OP_Noop ){
+ sqliteVdbeAddOp(v, pLevel->inOp, pLevel->inP1, pLevel->inP2);
+ }
+ if( pLevel->iLeftJoin ){
+ int addr;
+ addr = sqliteVdbeAddOp(v, OP_MemLoad, pLevel->iLeftJoin, 0);
+ sqliteVdbeAddOp(v, OP_NotNull, 1, addr+4 + (pLevel->iCur>=0));
+ sqliteVdbeAddOp(v, OP_NullRow, pTabList->a[i].iCursor, 0);
+ if( pLevel->iCur>=0 ){
+ sqliteVdbeAddOp(v, OP_NullRow, pLevel->iCur, 0);
+ }
+ sqliteVdbeAddOp(v, OP_Goto, 0, pLevel->top);
+ }
+ }
+ sqliteVdbeResolveLabel(v, pWInfo->iBreak);
+ for(i=0; i<pTabList->nSrc; i++){
+ Table *pTab = pTabList->a[i].pTab;
+ assert( pTab!=0 );
+ if( pTab->isTransient || pTab->pSelect ) continue;
+ pLevel = &pWInfo->a[i];
+ sqliteVdbeAddOp(v, OP_Close, pTabList->a[i].iCursor, 0);
+ if( pLevel->pIdx!=0 ){
+ sqliteVdbeAddOp(v, OP_Close, pLevel->iCur, 0);
+ }
+ }
+#if 0 /* Never reuse a cursor */
+ if( pWInfo->pParse->nTab==pWInfo->peakNTab ){
+ pWInfo->pParse->nTab = pWInfo->savedNTab;
+ }
+#endif
+ sqliteFree(pWInfo);
+ return;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/ChangeLog b/tqtinterface/qt4/src/3rdparty/zlib/ChangeLog
new file mode 100644
index 0000000..b7e805a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/ChangeLog
@@ -0,0 +1,764 @@
+
+ ChangeLog file for zlib
+
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update contrib/minizip [Vollant]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Update contrib/minizip [Vollant]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+ contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+ dynamic blocks with only literals and no distance codes --
+ Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case.
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+ - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and tqreplace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+ - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+ the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+ [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+ and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+ [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+ [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+ INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+ [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+ of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+ parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+ to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+ 16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+ Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+ zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+ library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+ special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+ - Report 0 for huffman and rle strategies and for level == 0 or 1
+ - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+ - When Z_RLE requested, restrict matches to distance one
+ - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+ - Refine detection of Turbo C need for dummy returns
+ - Refine ZLIB_DLL compilation
+ - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+ write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+ - About 20% faster
+ - Does not allocate 32K window unless and until needed
+ - Automatically detects and decompresses gzip streams
+ - Raw inflate no longer needs an extra dummy byte at end
+ - Added inflateBack functions using a callback interface--even faster
+ than inflate, useful for file utilities (gzip, zip)
+ - Added inflateCopy() function to record state for random access on
+ externally generated deflate streams (e.g. in gzip files)
+ - More readable code (I hope)
+- New and improved crc32()
+ - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+ and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+ return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+ is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+ - Document raw deflate and inflate
+ - Update RFCs URL
+ - Point out that zlib and gzip formats are different
+ - Note that Z_BUF_ERROR is not fatal
+ - Document string limit for gzprintf() and possible buffer overflow
+ - Note requirement on avail_out when flushing
+ - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+ This creates a security problem described in
+ http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+ less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+ of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+ occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+ (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+ See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean" (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+ . zutil.c, zutil.h: added "const" for zmem*
+ . Make_vms.com: fixed some typos
+ . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+ . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+ . msdos/Makefile.*: use model-dependent name for the built zlib library
+ . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+ new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- tqreplace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+ See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+ completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+ (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+ compression ratio on some files. This also allows inlining _tr_tally for
+ matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+ on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transtqparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- tqreplace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+ the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+ them at run time (thanks to Ken Raeburn for this suggestion). To create
+ trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+ gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occuring only with compression level 0 (thanks to
+ Andy Buckler for tqfinding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+ (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+ (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+ inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+ contrib/asm386/ by Gilles Vollant <info@winimage.com>
+ 386 asm code replacing longest_match().
+ contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+ A C++ I/O streams interface to the zlib gz* functions
+ contrib/iostream2/ by Tyge Løvset <Tyge.Lovset@cmr.no>
+ Another C++ I/O streams interface
+ contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+ A very simple tar.gz file extractor using zlib
+ contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+ How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+ level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+ (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+ bit, so the decompressor could decompress all the correct data but went
+ on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+ small and medium models; this makes the library incompatible with previous
+ versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+ avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+ Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+ and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+ -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+ warning C4746: 'inflate_mask' : unsized array treated as '__far'
+ (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+ not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+ (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+ typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+ was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+ pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+ is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+ (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+ TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+ (one's complement) is now done inside crc32(). WARNING: this is
+ incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transtqparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+ not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+ Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+ if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+ user-provided history buffer. This is supported only in deflateInit2
+ and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/FAQ b/tqtinterface/qt4/src/3rdparty/zlib/FAQ
new file mode 100644
index 0000000..e10b71e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/FAQ
@@ -0,0 +1,337 @@
+
+ Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://www.zlib.org which may have more recent information.
+The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+ Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+ The zlib sources can be compiled without change to produce a DLL.
+ See the file win32/DLL_FAQ.txt in the zlib distribution.
+ Pointers to the precompiled DLL are found in the zlib web site at
+ http://www.zlib.org.
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+ See
+ * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm
+ * contrib/visual-basic.txt in the zlib distribution
+ * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+ Make sure that before the call of compress, the length of the compressed
+ buffer is equal to the total size of the compressed buffer and not
+ zero. For Visual Basic, check that this parameter is passed by reference
+ ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+ Before making the call, make sure that avail_in and avail_out are not
+ zero. When setting the parameter flush equal to Z_FINISH, also make sure
+ that avail_out is big enough to allow processing all pending input.
+ Note that a Z_BUF_ERROR is not fatal--another call to deflate() or
+ inflate() can be made with more input or output space. A Z_BUF_ERROR
+ may in fact be unavoidable depending on how the functions are used, since
+ it is not possible to tell whether or not there is more output pending
+ when strm.avail_out returns with zero.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+ It's in zlib.h for the moment, and Francis S. Lin has converted it to a
+ web page zlib.html. Volunteers to transform this to Unix-style man pages,
+ please contact us (zlib@gzip.org). Examples of zlib usage are in the files
+ example.c and minigzip.c.
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+ Because we would like to keep zlib as a very small and simple
+ package. zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+ Most of the time, such problems are due to an incorrect usage of
+ zlib. Please try to reproduce the problem with a small program and send
+ the corresponding source to us at zlib@gzip.org . Do not send
+ multi-megabyte data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+ If "make test" produces something like
+
+ example.o(.text+0x154): undefined reference to `gzputc'
+
+ check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+ /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+ See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+ Not by itself, no. See the directory contrib/minizip in the zlib
+ distribution.
+
+12. Can zlib handle .Z files?
+
+ No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt
+ the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+ make clean
+ ./configure -s
+ make
+
+14. How do I install a shared zlib library on Unix?
+
+ After the above, then:
+
+ make install
+
+ However, many flavors of Unix come with a shared zlib already installed.
+ Before going to the trouble of compiling a shared version of zlib and
+ trying to install it, you may want to check if it's already there! If you
+ can #include <zlib.h>, it's there. The -lz option will probably link to it.
+
+15. I have a question about OttoPDF.
+
+ We are not the authors of OttoPDF. The real author is on the OttoPDF web
+ site: Joel Hainley, jhainley@myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+ Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ .
+ To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+ After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+ generates an error such as:
+
+ ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+ symbol __register_frame_info: referenced symbol not found
+
+ The symbol __register_frame_info is not part of zlib, it is generated by
+ the C compiler (cc or gcc). You must recompile applications using zlib
+ which have this problem. This problem is specific to Solaris. See
+ http://www.sunfreeware.com for Solaris versions of zlib and applications
+ using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+ The compress and deflate functions produce data in the zlib format, which
+ is different and incompatible with the gzip format. The gz* functions in
+ zlib on the other hand use the gzip format. Both the zlib and gzip
+ formats use the same compressed data format internally, but have different
+ headers and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+ The gzip format was designed to retain the directory information about
+ a single file, such as the name and last modification date. The zlib
+ format on the other hand was designed for in-memory and communication
+ channel applications, and has a much more compact header and trailer and
+ uses a faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+ You can request that deflate write the gzip format instead of the zlib
+ format using deflateInit2(). You can also request that inflate decode
+ the gzip format using inflateInit2(). Read zlib.h for more details.
+
+ Note that you cannot specify special gzip header contents (e.g. a file
+ name or modification date), nor will inflate tell you what was in the
+ gzip header. If you need to customize the header or see what's in it,
+ you can use the raw deflate and inflate operations and the crc32()
+ function and roll your own gzip encoding and decoding. Read the gzip
+ RFC 1952 for details of the header and trailer format.
+
+21. Is zlib thread-safe?
+
+ Yes. However any library routines that zlib uses and any application-
+ provided memory allocation routines must also be thread-safe. zlib's gz*
+ functions use stdio library routines, and most of zlib's functions use the
+ library memory allocation routines by default. zlib's Init functions allow
+ for the application to provide custom memory allocation routines.
+
+ Of course, you should only operate on any given zlib or gzip stream from a
+ single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+ Yes. Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+ No. Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+ what exactly do I need to do to meet that requirement?
+
+ You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In
+ particular, the final version number needs to be changed to "f", and an
+ identification string should be appended to ZLIB_VERSION. Version numbers
+ x.x.x.f are reserved for modifications to zlib by others than the zlib
+ maintainers. For example, if the version of the base zlib you are altering
+ is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+ ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also
+ update the version strings in deflate.c and inftrees.c.
+
+ For altered source distributions, you should also note the origin and
+ nature of the changes in zlib.h, as well as in ChangeLog and README, along
+ with the dates of the alterations. The origin should include at least your
+ name (or your company's name), and an email address to contact for help or
+ issues with the library.
+
+ Note that distributing a compiled zlib library along with zlib.h and
+ zconf.h is also a source distribution, and so you should change
+ ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+ in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+ exchange compressed data between them?
+
+ Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+ It should. It has been tested on 64-bit machines, and has no dependence
+ on any data types being limited to 32-bits in length. If you have any
+ difficulties, please provide a complete problem report to zlib@gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+ No. The PKWare DCL uses a completely different compressed data format
+ than does PKZIP and zlib. However, you can look in zlib's contrib/blast
+ directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+ No, not without some preparation. If when compressing you periodically
+ use Z_FULL_FLUSH, carefully write all the pending data at those points,
+ and keep an index of those locations, then you can start decompression
+ at those points. You have to be careful to not use Z_FULL_FLUSH too
+ often, since it can significantly degrade compression.
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+ We don't know for sure. We have heard occasional reports of success on
+ these systems. If you do use it on one of these, please provide us with
+ a report, instructions, and patches that we can reference when we get
+ these questions. Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at
+ to understand the deflate format?
+
+ First off, you should read RFC 1951. Second, yes. Look in zlib's
+ contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+ As far as we know, no. In fact, that was originally the whole point behind
+ zlib. Look here for some more information:
+
+ http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+ Yes. inflate() and deflate() will process any amount of data correctly.
+ Each call of inflate() or deflate() is limited to input and output chunks
+ of the maximum value that can be stored in the compiler's "unsigned int"
+ type, but there is no limit to the number of chunks. Note however that the
+ strm.total_in and strm_total_out counters may be limited to 4 GB. These
+ counters are provided as a convenience and are not used internally by
+ inflate() or deflate(). The application can easily set up its own counters
+ updated after each call of inflate() or deflate() to count beyond 4 GB.
+ compress() and uncompress() may be limited to 4 GB, since they operate in a
+ single call. gzseek() and gztell() may be limited to 4 GB depending on how
+ zlib is compiled. See the zlibCompileFlags() function in zlib.h.
+
+ The word "may" appears several times above since there is a 4 GB limit
+ only if the compiler's "long" type is 32 bits. If the compiler's "long"
+ type is 64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+ The only one that we are aware of is potentially in gzprintf(). If zlib
+ is compiled to use sprintf() or vsprintf(), then there is no protection
+ against a buffer overflow of a 4K string space, other than the caller of
+ gzprintf() assuring that the output will not exceed 4K. On the other
+ hand, if zlib is compiled to use snprintf() or vsnprintf(), which should
+ normally be the case, then there is no vulnerability. The ./configure
+ script will display warnings if an insecure variation of sprintf() will
+ be used by gzprintf(). Also the zlibCompileFlags() function will return
+ information on what variant of sprintf() is used by gzprintf().
+
+ If you don't have snprintf() or vsnprintf() and would like one, you can
+ tqfind a portable implementation here:
+
+ http://www.ijs.si/software/snprintf/
+
+ Note that you should be using the most recent version of zlib. Versions
+ 1.1.3 and before were subject to a double-free vulnerability.
+
+34. Is there a Java version of zlib?
+
+ Probably what you want is to use zlib in Java. zlib is already included
+ as part of the Java SDK in the java.util.zip package. If you really want
+ a version of zlib written in the Java language, look on the zlib home
+ page for links: http://www.zlib.org/
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+ up to maximally-pedantic. Can't you guys write proper code?
+
+ Many years ago, we gave up attempting to avoid warnings on every compiler
+ in the universe. It just got to be a waste of time, and some compilers
+ were downright silly. So now, we simply make sure that the code always
+ works.
+
+36. Will zlib read the (insert any ancient or arcane format here) compressed
+ data format?
+
+ Probably not. Look in the comp.compression FAQ for pointers to various
+ formats and associated software.
+
+37. How can I encrypt/decrypt zip files with zlib?
+
+ zlib doesn't support encryption. The original PKZIP encryption is very weak
+ and can be broken with freely available programs. To get strong encryption,
+ use GnuPG, http://www.gnupg.org/ , which already includes zlib compression.
+ For PKZIP compatible "encryption", look at http://www.info-zip.org/
+
+38. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+ "gzip" is the gzip format, and "deflate" is the zlib format. They should
+ probably have called the second one "zlib" instead to avoid confusion
+ with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616
+ correctly points to the zlib specification in RFC 1950 for the "deflate"
+ transfer encoding, there have been reports of servers and browsers that
+ incorrectly produce or expect raw deflate data per the deflate
+ specficiation in RFC 1951, most notably Microsoft. So even though the
+ "deflate" transfer encoding using the zlib format would be the more
+ efficient approach (and in fact exactly what the zlib format was designed
+ for), using the "gzip" transfer encoding is probably more reliable due to
+ an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+ Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+39. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+ No. PKWare has apparently decided to keep that format proprietary, since
+ they have not documented it as they have previous compression formats.
+ In any case, the compression improvements are so modest compared to other
+ more modern approaches, that it's not worth the effort to implement.
+
+40. Can you please sign these lengthy legal documents and fax them back to us
+ so that we can use your software in our product?
+
+ No. Go away. Shoo.
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/INDEX b/tqtinterface/qt4/src/3rdparty/zlib/INDEX
new file mode 100644
index 0000000..0587e59
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/INDEX
@@ -0,0 +1,51 @@
+ChangeLog history of changes
+FAQ Frequently Asked Questions about zlib
+INDEX this file
+Makefile makefile for Unix (generated by configure)
+Makefile.in makefile for Unix (template for configure)
+README guess what
+algorithm.txt description of the (de)compression algorithm
+configure configure script for Unix
+zconf.in.h template for zconf.h (used by configure)
+
+amiga/ makefiles for Amiga SAS C
+as400/ makefiles for IBM AS/400
+msdos/ makefiles for MSDOS
+old/ makefiles for various architectures and zlib documentation
+ files that have not yet been updated for zlib 1.2.x
+projects/ projects for various Integrated Development Environments
+qnx/ makefiles for QNX
+win32/ makefiles for Windows
+
+ zlib public header files (must be kept):
+zconf.h
+zlib.h
+
+ private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+crc32.h
+deflate.c
+deflate.h
+gzio.c
+infback.c
+inffast.c
+inffast.h
+inffixed.h
+inflate.c
+inflate.h
+inftrees.c
+inftrees.h
+trees.c
+trees.h
+uncompr.c
+zutil.c
+zutil.h
+
+ source files for sample programs:
+example.c
+minigzip.c
+
+ unsupported contribution by third parties
+See contrib/README.contrib
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/Makefile.in b/tqtinterface/qt4/src/3rdparty/zlib/Makefile.in
new file mode 100644
index 0000000..a29e9bc
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/Makefile.in
@@ -0,0 +1,154 @@
+# Makefile for zlib
+# Copyright (C) 1995-2003 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+# ./configure; make test
+# The call of configure is optional if you don't have special requirements
+# If you wish to build zlib as a shared library, use: ./configure -s
+
+# To use the asm code, type:
+# cp contrib/asm?86/match.S ./match.S
+# make LOC=-DASMV OBJA=match.o
+
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+# make install
+# To install in $HOME instead of /usr/local, use:
+# make install prefix=$HOME
+
+CC=cc
+
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+# -Wstrict-prototypes -Wmissing-prototypes
+
+LDFLAGS=libz.a
+LDSHARED=$(CC)
+CPP=$(CC) -E
+
+LIBS=libz.a
+SHAREDLIB=libz.so
+SHAREDLIBV=libz.so.1.2.2
+SHAREDLIBM=libz.so.1
+
+AR=ar rc
+RANLIB=ranlib
+TAR=tar
+SHELL=/bin/sh
+EXE=
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+libdir = ${exec_prefix}/lib
+includedir = ${prefix}/include
+mandir = ${prefix}/share/man
+man3dir = ${mandir}/man3
+
+OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
+ zutil.o inflate.o infback.o inftrees.o inffast.o
+
+OBJA =
+# to use the asm code: make OBJA=match.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example$(EXE) minigzip$(EXE)
+
+check: test
+test: all
+ @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+ echo hello world | ./minigzip | ./minigzip -d || \
+ echo ' *** minigzip test FAILED ***' ; \
+ if ./example; then \
+ echo ' *** zlib test OK ***'; \
+ else \
+ echo ' *** zlib test FAILED ***'; \
+ fi
+
+libz.a: $(OBJS) $(OBJA)
+ $(AR) $@ $(OBJS) $(OBJA)
+ -@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+match.o: match.S
+ $(CPP) match.S > _match.s
+ $(CC) -c _match.s
+ mv _match.o match.o
+ rm -f _match.s
+
+$(SHAREDLIBV): $(OBJS)
+ $(LDSHARED) -o $@ $(OBJS)
+ rm -f $(SHAREDLIB) $(SHAREDLIBM)
+ ln -s $@ $(SHAREDLIB)
+ ln -s $@ $(SHAREDLIBM)
+
+example$(EXE): example.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
+
+minigzip$(EXE): minigzip.o $(LIBS)
+ $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
+
+install: $(LIBS)
+ -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi
+ -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi
+ -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi
+ -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi
+ cp zlib.h zconf.h $(includedir)
+ chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h
+ cp $(LIBS) $(libdir)
+ cd $(libdir); chmod 755 $(LIBS)
+ -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1
+ cd $(libdir); if test -f $(SHAREDLIBV); then \
+ rm -f $(SHAREDLIB) $(SHAREDLIBM); \
+ ln -s $(SHAREDLIBV) $(SHAREDLIB); \
+ ln -s $(SHAREDLIBV) $(SHAREDLIBM); \
+ (ldconfig || true) >/dev/null 2>&1; \
+ fi
+ cp zlib.3 $(man3dir)
+ chmod 644 $(man3dir)/zlib.3
+# The ranlib in install is needed on NeXTSTEP which checks file times
+# ldconfig is for Linux
+
+uninstall:
+ cd $(includedir); \
+ cd $(libdir); rm -f libz.a; \
+ if test -f $(SHAREDLIBV); then \
+ rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
+ fi
+ cd $(man3dir); rm -f zlib.3
+
+mostlyclean: clean
+clean:
+ rm -f *.o *~ example$(EXE) minigzip$(EXE) \
+ libz.* foo.gz so_locations \
+ _match.s maketree contrib/infback9/*.o
+
+maintainer-clean: distclean
+distclean: clean
+ cp -p Makefile.in Makefile
+ cp -p zconf.in.h zconf.h
+ rm -f .DS_Store
+
+tags:
+ etags *.[ch]
+
+depend:
+ makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzio.o: zutil.h zlib.h zconf.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/README b/tqtinterface/qt4/src/3rdparty/zlib/README
new file mode 100644
index 0000000..df95ae1
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/README
@@ -0,0 +1,126 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.2 is a general purpose data compression library. All the code is
+thread safe. The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format). These documents are also available in other
+formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org). A usage example
+of the library is given in the file example.c which also tests that the library
+is working correctly. Another example is given in the file minigzip.c. The
+compression library itself is composed of all source files except example.c and
+minigzip.c.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile. In short "make test; make install" should work for most
+machines. For Unix: "./configure; make test; make install" For MSDOS, use one
+of the special makefiles such as Makefile.msc. For VMS, use Make_vms.com or
+descrip.mms.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version. The zlib home page is
+http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem,
+please check this site to verify that you have the latest version of zlib;
+otherwise get the latest version and check whether the problem still exists or
+not.
+
+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking
+for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan. 1997
+issue of Dr. Dobb's Journal; a copy of the article is available in
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+
+The changes made in version 1.2.2 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory "contrib".
+
+A Java implementation of zlib is available in the Java Development Kit
+http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html
+See the zlib home page http://www.zlib.org for details.
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is in the
+CPAN (Comprehensive Perl Archive Network) sites
+http://www.cpan.org/modules/by-module/Compress/
+
+A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
+available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html
+
+A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com> is
+availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+ -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+ compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+ when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+ necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+ other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+- When building a shared, i.e. dynamic library on Mac OS X, the library must be
+ installed before testing (do "make install" before "make test"), since the
+ library location is specified in the library.
+
+
+Acknowledgments:
+
+ The deflate format used by zlib was defined by Phil Katz. The deflate
+ and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+ people who reported problems and suggested various improvements in zlib;
+ they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind. The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes. Please
+read the FAQ for more information on the distribution of modified source
+versions.
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/adler32.c b/tqtinterface/qt4/src/3rdparty/zlib/adler32.c
new file mode 100644
index 0000000..624a169
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/adler32.c
@@ -0,0 +1,74 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#define BASE 65521UL /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf) DO8(buf,0); DO8(buf,8);
+
+#ifdef NO_DIVIDE
+# define MOD(a) \
+ do { \
+ if (a >= (BASE << 16)) a -= (BASE << 16); \
+ if (a >= (BASE << 15)) a -= (BASE << 15); \
+ if (a >= (BASE << 14)) a -= (BASE << 14); \
+ if (a >= (BASE << 13)) a -= (BASE << 13); \
+ if (a >= (BASE << 12)) a -= (BASE << 12); \
+ if (a >= (BASE << 11)) a -= (BASE << 11); \
+ if (a >= (BASE << 10)) a -= (BASE << 10); \
+ if (a >= (BASE << 9)) a -= (BASE << 9); \
+ if (a >= (BASE << 8)) a -= (BASE << 8); \
+ if (a >= (BASE << 7)) a -= (BASE << 7); \
+ if (a >= (BASE << 6)) a -= (BASE << 6); \
+ if (a >= (BASE << 5)) a -= (BASE << 5); \
+ if (a >= (BASE << 4)) a -= (BASE << 4); \
+ if (a >= (BASE << 3)) a -= (BASE << 3); \
+ if (a >= (BASE << 2)) a -= (BASE << 2); \
+ if (a >= (BASE << 1)) a -= (BASE << 1); \
+ if (a >= BASE) a -= BASE; \
+ } while (0)
+#else
+# define MOD(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+ uLong adler;
+ const Bytef *buf;
+ uInt len;
+{
+ unsigned long s1 = adler & 0xffff;
+ unsigned long s2 = (adler >> 16) & 0xffff;
+ int k;
+
+ if (buf == Z_NULL) return 1L;
+
+ while (len > 0) {
+ k = len < NMAX ? (int)len : NMAX;
+ len -= k;
+ while (k >= 16) {
+ DO16(buf);
+ buf += 16;
+ k -= 16;
+ }
+ if (k != 0) do {
+ s1 += *buf++;
+ s2 += s1;
+ } while (--k);
+ MOD(s1);
+ MOD(s2);
+ }
+ return (s2 << 16) | s1;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/algorithm.txt b/tqtinterface/qt4/src/3rdparty/zlib/algorithm.txt
new file mode 100644
index 0000000..d454dcc
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/algorithm.txt
@@ -0,0 +1,209 @@
+1. Compression algorithm (deflate)
+
+The deflation algorithm used by gzip (also zip and zlib) is a variation of
+LZ77 (Lempel-Ziv 1977, see reference below). It tqfinds duplicated strings in
+the input data. The second occurrence of a string is tqreplaced by a
+pointer to the previous string, in the form of a pair (distance,
+length). Distances are limited to 32K bytes, and lengths are limited
+to 258 bytes. When a string does not occur anywhere in the previous
+32K bytes, it is emitted as a sequence of literal bytes. (In this
+description, `string' must be taken as an arbitrary sequence of bytes,
+and is not restricted to printable characters.)
+
+Literals or match lengths are compressed with one Huffman tree, and
+match distances are compressed with another tree. The trees are stored
+in a compact form at the start of each block. The blocks can have any
+size (except that the compressed data for one block must fit in
+available memory). A block is terminated when deflate() determines that
+it would be useful to start another block with fresh trees. (This is
+somewhat similar to the behavior of LZW-based _compress_.)
+
+Duplicated strings are found using a hash table. All input strings of
+length 3 are inserted in the hash table. A hash index is computed for
+the next 3 bytes. If the hash chain for this index is not empty, all
+strings in the chain are compared with the current input string, and
+the longest match is selected.
+
+The hash chains are searched starting with the most recent strings, to
+favor small distances and thus take advantage of the Huffman encoding.
+The hash chains are singly linked. There are no deletions from the
+hash chains, the algorithm simply discards matches that are too old.
+
+To avoid a worst-case situation, very long hash chains are arbitrarily
+truncated at a certain length, determined by a runtime option (level
+parameter of deflateInit). So deflate() does not always tqfind the longest
+possible match but generally tqfinds a match which is long enough.
+
+deflate() also defers the selection of matches with a lazy evaluation
+mechanism. After a match of length N has been found, deflate() searches for
+a longer match at the next input byte. If a longer match is found, the
+previous match is truncated to a length of one (thus producing a single
+literal byte) and the process of lazy evaluation begins again. Otherwise,
+the original match is kept, and the next match search is attempted only N
+steps later.
+
+The lazy match evaluation is also subject to a runtime parameter. If
+the current match is long enough, deflate() reduces the search for a longer
+match, thus speeding up the whole process. If compression ratio is more
+important than speed, deflate() attempts a complete second search even if
+the first match is already long enough.
+
+The lazy match evaluation is not performed for the fastest compression
+modes (level parameter 1 to 3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
+
+2. Decompression algorithm (inflate)
+
+2.1 Introduction
+
+The key question is how to represent a Huffman code (or any prefix code) so
+that you can decode fast. The most important characteristic is that shorter
+codes are much more common than longer codes, so pay attention to decoding the
+short codes fast, and let the long codes take longer to decode.
+
+inflate() sets up a first level table that covers some number of bits of
+input less than the length of longest code. It gets that many bits from the
+stream, and looks it up in the table. The table will tell if the next
+code is that many bits or less and how many, and if it is, it will tell
+the value, else it will point to the next level table for which inflate()
+grabs more bits and tries to decode a longer code.
+
+How many bits to make the first lookup is a tradeoff between the time it
+takes to decode and the time it takes to build the table. If building the
+table took no time (and if you had infinite memory), then there would only
+be a first level table to cover all the way to the longest code. However,
+building the table ends up taking a lot longer for more bits since short
+codes are replicated many times in such a table. What inflate() does is
+simply to make the number of bits in the first table a variable, and then
+to set that variable for the maximum speed.
+
+For inflate, which has 286 possible codes for the literal/length tree, the size
+of the first table is nine bits. Also the distance trees have 30 possible
+values, and the size of the first table is six bits. Note that for each of
+those cases, the table ended up one bit longer than the ``average'' code
+length, i.e. the code length of an approximately flat code which would be a
+little more than eight bits for 286 symbols and a little less than five bits
+for 30 symbols.
+
+
+2.2 More details on the inflate table lookup
+
+Ok, you want to know what this cleverly obfuscated inflate tree actually
+looks like. You are correct that it's not a Huffman tree. It is simply a
+lookup table for the first, let's say, nine bits of a Huffman symbol. The
+symbol could be as short as one bit or as long as 15 bits. If a particular
+symbol is shorter than nine bits, then that symbol's translation is duplicated
+in all those entries that start with that symbol's bits. For example, if the
+symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a
+symbol is nine bits long, it appears in the table once.
+
+If the symbol is longer than nine bits, then that entry in the table points
+to another similar table for the remaining bits. Again, there are duplicated
+entries as needed. The idea is that most of the time the symbol will be short
+and there will only be one table look up. (That's whole idea behind data
+compression in the first place.) For the less frequent long symbols, there
+will be two lookups. If you had a compression method with really long
+symbols, you could have as many levels of lookups as is efficient. For
+inflate, two is enough.
+
+So a table entry either points to another table (in which case nine bits in
+the above example are gobbled), or it tqcontains the translation for the symbol
+and the number of bits to gobble. Then you start again with the next
+ungobbled bit.
+
+You may wonder: why not just have one lookup table for how ever many bits the
+longest symbol is? The reason is that if you do that, you end up spending
+more time filling in duplicate symbol entries than you do actually decoding.
+At least for deflate's output that generates new trees every several 10's of
+kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code
+would take too long if you're only decoding several thousand symbols. At the
+other extreme, you could make a new table for every bit in the code. In fact,
+that's essentially a Huffman tree. But then you spend two much time
+traversing the tree while decoding, even for short symbols.
+
+So the number of bits for the first lookup table is a trade of the time to
+fill out the table vs. the time spent looking at the second level and above of
+the table.
+
+Here is an example, scaled down:
+
+The code being decoded, with 10 symbols, from 1 to 6 bits long:
+
+A: 0
+B: 10
+C: 1100
+D: 11010
+E: 11011
+F: 11100
+G: 11101
+H: 11110
+I: 111110
+J: 111111
+
+Let's make the first table three bits long (eight entries):
+
+000: A,1
+001: A,1
+010: A,1
+011: A,1
+100: B,2
+101: B,2
+110: -> table X (gobble 3 bits)
+111: -> table Y (gobble 3 bits)
+
+Each entry is what the bits decode as and how many bits that is, i.e. how
+many bits to gobble. Or the entry points to another table, with the number of
+bits to gobble implicit in the size of the table.
+
+Table X is two bits long since the longest code starting with 110 is five bits
+long:
+
+00: C,1
+01: C,1
+10: D,2
+11: E,2
+
+Table Y is three bits long since the longest code starting with 111 is six
+bits long:
+
+000: F,2
+001: F,2
+010: G,2
+011: G,2
+100: H,2
+101: H,2
+110: I,3
+111: J,3
+
+So what we have here are three tables with a total of 20 entries that had to
+be constructed. That's compared to 64 entries for a single table. Or
+compared to 16 entries for a Huffman tree (six two entry tables and one four
+entry table). Assuming that the code ideally represents the probability of
+the symbols, it takes on the average 1.25 lookups per symbol. That's compared
+to one lookup for the single table, or 1.66 lookups per symbol for the
+Huffman tree.
+
+There, I think that gives you a picture of what's going on. For inflate, the
+meaning of a particular symbol is often more than just a letter. It can be a
+byte (a "literal"), or it can be either a length or a distance which
+indicates a base value and a number of bits to fetch after the code that is
+added to the base value. Or it might be the special end-of-block code. The
+data structures created in inftrees.c try to encode all that information
+compactly in the tables.
+
+
+Jean-loup Gailly Mark Adler
+jloup@gzip.org madler@alumni.caltech.edu
+
+
+References:
+
+[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
+Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
+pp. 337-343.
+
+``DEFLATE Compressed Data Format Specification'' available in
+http://www.ietf.org/rfc/rfc1951.txt
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/compress.c b/tqtinterface/qt4/src/3rdparty/zlib/compress.c
new file mode 100644
index 0000000..4c096fa
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/compress.c
@@ -0,0 +1,79 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least 0.1% larger than sourceLen plus
+ 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+ int level;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+ stream.opaque = (voidpf)0;
+
+ err = deflateInit(&stream, level);
+ if (err != Z_OK) return err;
+
+ err = deflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ deflateEnd(&stream);
+ return err == Z_OK ? Z_BUF_ERROR : err;
+ }
+ *destLen = stream.total_out;
+
+ err = deflateEnd(&stream);
+ return err;
+}
+
+/* ===========================================================================
+ */
+int TQ_ZEXPORT compress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+ If the default memLevel or windowBits for deflateInit() is changed, then
+ this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+ uLong sourceLen;
+{
+ return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/configure b/tqtinterface/qt4/src/3rdparty/zlib/configure
new file mode 100755
index 0000000..c0ebb5d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/configure
@@ -0,0 +1,443 @@
+#!/bin/sh
+# configure script for zlib. This script is needed only if
+# you wish to build a shared library and your system supports them,
+# of if you need special compiler, flags or install directory.
+# Otherwise, you can just use directly "make test; make install"
+#
+# To create a shared library, use "configure --shared"; by default a static
+# library is created. If the primitive shared library support provided here
+# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz
+#
+# To impose specific compiler or flags or install directory, use for example:
+# prefix=$HOME CC=cc CFLAGS="-O4" ./configure
+# or for csh/tcsh users:
+# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
+# LDSHARED is the command to be used to create a shared library
+
+# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
+# If you have problems, try without defining CC and CFLAGS before reporting
+# an error.
+
+LIBS=libz.a
+LDFLAGS="-L. ${LIBS}"
+VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
+VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
+VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h`
+AR=${AR-"ar rc"}
+RANLIB=${RANLIB-"ranlib"}
+prefix=${prefix-/usr/local}
+exec_prefix=${exec_prefix-'${prefix}'}
+libdir=${libdir-'${exec_prefix}/lib'}
+includedir=${includedir-'${prefix}/include'}
+mandir=${mandir-'${prefix}/share/man'}
+shared_ext='.so'
+shared=0
+gcc=0
+old_cc="$CC"
+old_cflags="$CFLAGS"
+
+while test $# -ge 1
+do
+case "$1" in
+ -h* | --h*)
+ echo 'usage:'
+ echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]'
+ echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]'
+ exit 0;;
+ -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
+ -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
+ -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;;
+ -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;;
+ -p* | --p*) prefix="$2"; shift; shift;;
+ -e* | --e*) exec_prefix="$2"; shift; shift;;
+ -l* | --l*) libdir="$2"; shift; shift;;
+ -i* | --i*) includedir="$2"; shift; shift;;
+ -s* | --s*) shared=1; shift;;
+ *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1;;
+ esac
+done
+
+test=ztest$$
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+
+test -z "$CC" && echo Checking for gcc...
+cc=${CC-gcc}
+cflags=${CFLAGS-"-O3"}
+# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
+case "$cc" in
+ *gcc*) gcc=1;;
+esac
+
+if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then
+ CC="$cc"
+ SFLAGS=${CFLAGS-"-fPIC -O3"}
+ CFLAGS="$cflags"
+ case `(uname -s || echo unknown) 2>/dev/null` in
+ Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};;
+ CYGWIN* | Cygwin* | cygwin* | OS/2* )
+ EXE='.exe';;
+ QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
+ # (alain.bonnefoy@icbt.com)
+ LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"};;
+ HP-UX*) LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
+ shared_ext='.sl'
+ SHAREDLIB='libz.sl';;
+ Darwin*) shared_ext='.dylib'
+ SHAREDLIB=libz$shared_ext
+ SHAREDLIBV=libz.$VER$shared_ext
+ SHAREDLIBM=libz.$VER1$shared_ext
+ LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBV -compatibility_version $VER2 -current_version $VER"};;
+ *) LDSHARED=${LDSHARED-"$cc -shared"};;
+ esac
+else
+ # tqfind system name and corresponding cc options
+ CC=${CC-cc}
+ case `(uname -sr || echo unknown) 2>/dev/null` in
+ HP-UX*) SFLAGS=${CFLAGS-"-O +z"}
+ CFLAGS=${CFLAGS-"-O"}
+# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
+ LDSHARED=${LDSHARED-"ld -b"}
+ shared_ext='.sl'
+ SHAREDLIB='libz.sl';;
+ IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
+ CFLAGS=${CFLAGS-"-ansi -O2"}
+ LDSHARED=${LDSHARED-"cc -shared"};;
+ OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
+ CFLAGS=${CFLAGS-"-O -std1"}
+ LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};;
+ OSF1*) SFLAGS=${CFLAGS-"-O -std1"}
+ CFLAGS=${CFLAGS-"-O -std1"}
+ LDSHARED=${LDSHARED-"cc -shared"};;
+ QNX*) SFLAGS=${CFLAGS-"-4 -O"}
+ CFLAGS=${CFLAGS-"-4 -O"}
+ LDSHARED=${LDSHARED-"cc"}
+ RANLIB=${RANLIB-"true"}
+ AR="cc -A";;
+ SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
+ CFLAGS=${CFLAGS-"-O3"}
+ LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};;
+ SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."}
+ CFLAGS=${CFLAGS-"-fast -xcg89"}
+ LDSHARED=${LDSHARED-"cc -G"};;
+ SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
+ CFLAGS=${CFLAGS-"-O2"}
+ LDSHARED=${LDSHARED-"ld"};;
+ UNIX_System_V\ 4.2.0)
+ SFLAGS=${CFLAGS-"-KPIC -O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -G"};;
+ UNIX_SV\ 4.2MP)
+ SFLAGS=${CFLAGS-"-Kconform_pic -O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -G"};;
+ OpenUNIX\ 5)
+ SFLAGS=${CFLAGS-"-KPIC -O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -G"};;
+ AIX*) # Courtesy of dbakker@arrayasolutions.com
+ SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+ CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+ LDSHARED=${LDSHARED-"xlc -G"};;
+ # send working options for other systems to support@gzip.org
+ *) SFLAGS=${CFLAGS-"-O"}
+ CFLAGS=${CFLAGS-"-O"}
+ LDSHARED=${LDSHARED-"cc -shared"};;
+ esac
+fi
+
+SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
+SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
+SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
+
+if test $shared -eq 1; then
+ echo Checking for shared library support...
+ # we must test in two steps (cc then ld), required at least on SunOS 4.x
+ if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" &&
+ test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then
+ CFLAGS="$SFLAGS"
+ LIBS="$SHAREDLIBV"
+ echo Building shared library $SHAREDLIBV with $CC.
+ elif test -z "$old_cc" -a -z "$old_cflags"; then
+ echo No shared library support.
+ shared=0;
+ else
+ echo 'No shared library support; try without defining CC and CFLAGS'
+ shared=0;
+ fi
+fi
+if test $shared -eq 0; then
+ LDSHARED="$CC"
+ echo Building static library $LIBS version $VER with $CC.
+else
+ LDFLAGS="-L. ${SHAREDLIBV}"
+fi
+
+cat > $test.c <<EOF
+#include <unistd.h>
+int main() { return 0; }
+EOF
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ sed < zconf.in.h "/HAVE_UNISTD_H/s%0%1%" > zconf.h
+ echo "Checking for unistd.h... Yes."
+else
+ cp -p zconf.in.h zconf.h
+ echo "Checking for unistd.h... No."
+fi
+
+cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+#include "zconf.h"
+
+int main()
+{
+#ifndef STDC
+ choke me
+#endif
+
+ return 0;
+}
+EOF
+
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()"
+
+ cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+
+int mytest(char *fmt, ...)
+{
+ char buf[20];
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return 0;
+}
+
+int main()
+{
+ return (mytest("Hello%d\n", 1));
+}
+EOF
+
+ if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
+ echo "Checking for vsnprintf() in stdio.h... Yes."
+
+ cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+
+int mytest(char *fmt, ...)
+{
+ int n;
+ char buf[20];
+ va_list ap;
+
+ va_start(ap, fmt);
+ n = vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return n;
+}
+
+int main()
+{
+ return (mytest("Hello%d\n", 1));
+}
+EOF
+
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking for return value of vsnprintf()... Yes."
+ else
+ CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
+ echo "Checking for return value of vsnprintf()... No."
+ echo " WARNING: apparently vsnprintf() does not return a value. zlib"
+ echo " can build but will be open to possible string-format security"
+ echo " vulnerabilities."
+ fi
+ else
+ CFLAGS="$CFLAGS -DNO_vsnprintf"
+ echo "Checking for vsnprintf() in stdio.h... No."
+ echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib"
+ echo " can build but will be open to possible buffer-overflow security"
+ echo " vulnerabilities."
+
+ cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+
+int mytest(char *fmt, ...)
+{
+ int n;
+ char buf[20];
+ va_list ap;
+
+ va_start(ap, fmt);
+ n = vsprintf(buf, fmt, ap);
+ va_end(ap);
+ return n;
+}
+
+int main()
+{
+ return (mytest("Hello%d\n", 1));
+}
+EOF
+
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking for return value of vsprintf()... Yes."
+ else
+ CFLAGS="$CFLAGS -DHAS_vsprintf_void"
+ echo "Checking for return value of vsprintf()... No."
+ echo " WARNING: apparently vsprintf() does not return a value. zlib"
+ echo " can build but will be open to possible string-format security"
+ echo " vulnerabilities."
+ fi
+ fi
+else
+ echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()"
+
+ cat >$test.c <<EOF
+#include <stdio.h>
+
+int mytest()
+{
+ char buf[20];
+
+ snprintf(buf, sizeof(buf), "%s", "foo");
+ return 0;
+}
+
+int main()
+{
+ return (mytest());
+}
+EOF
+
+ if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then
+ echo "Checking for snprintf() in stdio.h... Yes."
+
+ cat >$test.c <<EOF
+#include <stdio.h>
+
+int mytest()
+{
+ char buf[20];
+
+ return snprintf(buf, sizeof(buf), "%s", "foo");
+}
+
+int main()
+{
+ return (mytest());
+}
+EOF
+
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking for return value of snprintf()... Yes."
+ else
+ CFLAGS="$CFLAGS -DHAS_snprintf_void"
+ echo "Checking for return value of snprintf()... No."
+ echo " WARNING: apparently snprintf() does not return a value. zlib"
+ echo " can build but will be open to possible string-format security"
+ echo " vulnerabilities."
+ fi
+ else
+ CFLAGS="$CFLAGS -DNO_snprintf"
+ echo "Checking for snprintf() in stdio.h... No."
+ echo " WARNING: snprintf() not found, falling back to sprintf(). zlib"
+ echo " can build but will be open to possible buffer-overflow security"
+ echo " vulnerabilities."
+
+ cat >$test.c <<EOF
+#include <stdio.h>
+
+int mytest()
+{
+ char buf[20];
+
+ return sprintf(buf, "%s", "foo");
+}
+
+int main()
+{
+ return (mytest());
+}
+EOF
+
+ if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking for return value of sprintf()... Yes."
+ else
+ CFLAGS="$CFLAGS -DHAS_sprintf_void"
+ echo "Checking for return value of sprintf()... No."
+ echo " WARNING: apparently sprintf() does not return a value. zlib"
+ echo " can build but will be open to possible string-format security"
+ echo " vulnerabilities."
+ fi
+ fi
+fi
+
+cat >$test.c <<EOF
+#include <errno.h>
+int main() { return 0; }
+EOF
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ echo "Checking for errno.h... Yes."
+else
+ echo "Checking for errno.h... No."
+ CFLAGS="$CFLAGS -DNO_ERRNO_H"
+fi
+
+cat > $test.c <<EOF
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+caddr_t hello() {
+ return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0);
+}
+EOF
+if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then
+ CFLAGS="$CFLAGS -DUSE_MMAP"
+ echo Checking for mmap support... Yes.
+else
+ echo Checking for mmap support... No.
+fi
+
+CPP=${CPP-"$CC -E"}
+case $CFLAGS in
+ *ASMV*)
+ if test "`nm $test.o | grep _hello`" = ""; then
+ CPP="$CPP -DNO_UNDERLINE"
+ echo Checking for underline in external names... No.
+ else
+ echo Checking for underline in external names... Yes.
+ fi;;
+esac
+
+rm -f $test.[co] $test $test$shared_ext
+
+# udpate Makefile
+sed < Makefile.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^CPP *=/s#=.*#=$CPP#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^LIBS *=/s#=.*#=$LIBS#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^EXE *=/s#=.*#=$EXE#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+" > Makefile
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/crc32.c b/tqtinterface/qt4/src/3rdparty/zlib/crc32.c
new file mode 100644
index 0000000..dfa6c4f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/crc32.c
@@ -0,0 +1,333 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors. This results about a factor
+ * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+ Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+ protection on the static variables used to control the first-use generation
+ of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+ first call get_crc_table() to initialize the tables before allowing more than
+ one thread to use crc32().
+ */
+
+#ifdef MAKECRCH
+# include <stdio.h>
+# ifndef DYNAMIC_CRC_TABLE
+# define DYNAMIC_CRC_TABLE
+# endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h" /* for STDC and FAR definitions */
+
+#define local static
+
+/* Find a four-byte integer type for crc32_little() and crc32_big(). */
+#ifndef NOBYFOUR
+# ifdef STDC /* need ANSI C limits.h to determine sizes */
+# include <limits.h>
+# define BYFOUR
+# if (UINT_MAX == 0xffffffffUL)
+ typedef unsigned int u4;
+# else
+# if (ULONG_MAX == 0xffffffffUL)
+ typedef unsigned long u4;
+# else
+# if (USHRT_MAX == 0xffffffffUL)
+ typedef unsigned short u4;
+# else
+# undef BYFOUR /* can't tqfind a four-byte integer type! */
+# endif
+# endif
+# endif
+# endif /* STDC */
+#endif /* !NOBYFOUR */
+
+/* Definitions for doing the crc four data bytes at a time. */
+#ifdef BYFOUR
+# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
+ (((w)&0xff00)<<8)+(((w)&0xff)<<24))
+ local unsigned long crc32_little OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+ local unsigned long crc32_big OF((unsigned long,
+ const unsigned char FAR *, unsigned));
+# define TBLS 8
+#else
+# define TBLS 1
+#endif /* BYFOUR */
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local unsigned long FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+ local void write_table OF((FILE *, const unsigned long FAR *));
+#endif /* MAKECRCH */
+
+/*
+ Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+ x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+ Polynomials over GF(2) are represented in binary, one bit per coefficient,
+ with the lowest powers in the most significant bit. Then adding polynomials
+ is just exclusive-or, and multiplying a polynomial by x is a right shift by
+ one. If we call the above polynomial p, and represent a byte as the
+ polynomial q, also with the lowest power in the most significant bit (so the
+ byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+ where a mod b means the remainder after dividing a by b.
+
+ This calculation is done using the shift-register method of multiplying and
+ taking the remainder. The register is initialized to zero, and for each
+ incoming bit, x^32 is added mod p to the register if the bit is a one (where
+ x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+ x (which is shifting right by one and adding x^32 mod p if the bit shifted
+ out is a one). We start with the highest power (least significant bit) of
+ q and repeat for all eight bits of q.
+
+ The first table is simply the CRC of all possible eight bit values. This is
+ all the information needed to generate CRCs on data a byte at a time for all
+ combinations of CRC register values and incoming bytes. The remaining tables
+ allow for word-at-a-time CRC calculation for both big-endian and little-
+ endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+ unsigned long c;
+ int n, k;
+ unsigned long poly; /* polynomial exclusive-or pattern */
+ /* terms of polynomial defining this crc (except x^32): */
+ static volatile int first = 1; /* flag to limit concurrent making */
+ static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+ /* See if another task is already doing this (not thread-safe, but better
+ than nothing -- significantly reduces duration of vulnerability in
+ case the advice about DYNAMIC_CRC_TABLE is ignored) */
+ if (first) {
+ first = 0;
+
+ /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+ poly = 0UL;
+ for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
+ poly |= 1UL << (31 - p[n]);
+
+ /* generate a crc for every 8-bit value */
+ for (n = 0; n < 256; n++) {
+ c = (unsigned long)n;
+ for (k = 0; k < 8; k++)
+ c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+ crc_table[0][n] = c;
+ }
+
+#ifdef BYFOUR
+ /* generate crc for each value followed by one, two, and three zeros,
+ and then the byte reversal of those as well as the first table */
+ for (n = 0; n < 256; n++) {
+ c = crc_table[0][n];
+ crc_table[4][n] = REV(c);
+ for (k = 1; k < 4; k++) {
+ c = crc_table[0][c & 0xff] ^ (c >> 8);
+ crc_table[k][n] = c;
+ crc_table[k + 4][n] = REV(c);
+ }
+ }
+#endif /* BYFOUR */
+
+ crc_table_empty = 0;
+ }
+ else { /* not first */
+ /* wait for the other guy to finish (not efficient, but rare) */
+ while (crc_table_empty)
+ ;
+ }
+
+#ifdef MAKECRCH
+ /* write out CRC tables to crc32.h */
+ {
+ FILE *out;
+
+ out = fopen("crc32.h", "w");
+ if (out == NULL) return;
+ fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+ fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+ fprintf(out, "local const unsigned long FAR ");
+ fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
+ write_table(out, crc_table[0]);
+# ifdef BYFOUR
+ fprintf(out, "#ifdef BYFOUR\n");
+ for (k = 1; k < 8; k++) {
+ fprintf(out, " },\n {\n");
+ write_table(out, crc_table[k]);
+ }
+ fprintf(out, "#endif\n");
+# endif /* BYFOUR */
+ fprintf(out, " }\n};\n");
+ fclose(out);
+ }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+ FILE *out;
+ const unsigned long FAR *table;
+{
+ int n;
+
+ for (n = 0; n < 256; n++)
+ fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
+ n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const unsigned long FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+ return (const unsigned long FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+ if (crc_table_empty)
+ make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+ if (sizeof(void *) == sizeof(ptrdiff_t)) {
+ u4 endian;
+
+ endian = 1;
+ if (*((unsigned char *)(&endian)))
+ return crc32_little(crc, buf, len);
+ else
+ return crc32_big(crc, buf, len);
+ }
+#endif /* BYFOUR */
+ crc = crc ^ 0xffffffffUL;
+ while (len >= 8) {
+ DO8;
+ len -= 8;
+ }
+ if (len) do {
+ DO1;
+ } while (--len);
+ return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register u4 c;
+ register const u4 FAR *buf4;
+
+ c = (u4)crc;
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ len--;
+ }
+
+ buf4 = (const u4 FAR *)buf;
+ while (len >= 32) {
+ DOLIT32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOLIT4;
+ len -= 4;
+ }
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+ unsigned long crc;
+ const unsigned char FAR *buf;
+ unsigned len;
+{
+ register u4 c;
+ register const u4 FAR *buf4;
+
+ c = REV((u4)crc);
+ c = ~c;
+ while (len && ((ptrdiff_t)buf & 3)) {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ len--;
+ }
+
+ buf4 = (const u4 FAR *)buf;
+ buf4--;
+ while (len >= 32) {
+ DOBIG32;
+ len -= 32;
+ }
+ while (len >= 4) {
+ DOBIG4;
+ len -= 4;
+ }
+ buf4++;
+ buf = (const unsigned char FAR *)buf4;
+
+ if (len) do {
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ } while (--len);
+ c = ~c;
+ return (unsigned long)(REV(c));
+}
+
+#endif /* BYFOUR */
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/crc32.h b/tqtinterface/qt4/src/3rdparty/zlib/crc32.h
new file mode 100644
index 0000000..8053b61
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const unsigned long FAR crc_table[TBLS][256] =
+{
+ {
+ 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+ 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+ 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+ 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+ 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+ 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+ 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+ 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+ 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+ 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+ 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+ 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+ 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+ 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+ 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+ 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+ 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+ 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+ 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+ 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+ 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+ 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+ 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+ 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+ 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+ 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+ 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+ 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+ 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+ 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+ 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+ 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+ 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+ 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+ 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+ 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+ 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+ 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+ 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+ 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+ 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+ 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+ 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+ 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+ 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+ 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+ 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+ 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+ 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+ 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+ 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+ 0x2d02ef8dUL
+#ifdef BYFOUR
+ },
+ {
+ 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+ 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+ 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+ 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+ 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+ 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+ 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+ 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+ 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+ 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+ 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+ 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+ 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+ 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+ 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+ 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+ 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+ 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+ 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+ 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+ 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+ 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+ 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+ 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+ 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+ 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+ 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+ 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+ 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+ 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+ 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+ 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+ 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+ 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+ 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+ 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+ 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+ 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+ 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+ 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+ 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+ 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+ 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+ 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+ 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+ 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+ 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+ 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+ 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+ 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+ 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+ 0x9324fd72UL
+ },
+ {
+ 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+ 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+ 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+ 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+ 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+ 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+ 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+ 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+ 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+ 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+ 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+ 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+ 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+ 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+ 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+ 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+ 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+ 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+ 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+ 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+ 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+ 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+ 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+ 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+ 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+ 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+ 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+ 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+ 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+ 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+ 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+ 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+ 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+ 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+ 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+ 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+ 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+ 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+ 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+ 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+ 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+ 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+ 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+ 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+ 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+ 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+ 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+ 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+ 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+ 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+ 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+ 0xbe9834edUL
+ },
+ {
+ 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+ 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+ 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+ 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+ 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+ 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+ 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+ 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+ 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+ 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+ 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+ 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+ 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+ 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+ 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+ 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+ 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+ 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+ 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+ 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+ 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+ 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+ 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+ 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+ 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+ 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+ 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+ 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+ 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+ 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+ 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+ 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+ 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+ 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+ 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+ 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+ 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+ 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+ 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+ 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+ 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+ 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+ 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+ 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+ 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+ 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+ 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+ 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+ 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+ 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+ 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+ 0xde0506f1UL
+ },
+ {
+ 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+ 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+ 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+ 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+ 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+ 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+ 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+ 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+ 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+ 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+ 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+ 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+ 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+ 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+ 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+ 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+ 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+ 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+ 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+ 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+ 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+ 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+ 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+ 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+ 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+ 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+ 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+ 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+ 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+ 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+ 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+ 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+ 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+ 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+ 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+ 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+ 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+ 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+ 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+ 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+ 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+ 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+ 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+ 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+ 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+ 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+ 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+ 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+ 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+ 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+ 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+ 0x8def022dUL
+ },
+ {
+ 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+ 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+ 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+ 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+ 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+ 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+ 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+ 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+ 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+ 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+ 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+ 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+ 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+ 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+ 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+ 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+ 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+ 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+ 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+ 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+ 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+ 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+ 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+ 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+ 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+ 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+ 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+ 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+ 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+ 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+ 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+ 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+ 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+ 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+ 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+ 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+ 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+ 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+ 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+ 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+ 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+ 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+ 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+ 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+ 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+ 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+ 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+ 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+ 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+ 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+ 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+ 0x72fd2493UL
+ },
+ {
+ 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+ 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+ 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+ 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+ 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+ 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+ 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+ 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+ 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+ 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+ 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+ 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+ 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+ 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+ 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+ 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+ 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+ 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+ 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+ 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+ 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+ 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+ 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+ 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+ 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+ 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+ 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+ 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+ 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+ 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+ 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+ 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+ 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+ 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+ 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+ 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+ 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+ 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+ 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+ 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+ 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+ 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+ 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+ 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+ 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+ 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+ 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+ 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+ 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+ 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+ 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+ 0xed3498beUL
+ },
+ {
+ 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+ 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+ 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+ 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+ 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+ 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+ 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+ 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+ 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+ 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+ 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+ 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+ 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+ 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+ 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+ 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+ 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+ 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+ 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+ 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+ 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+ 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+ 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+ 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+ 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+ 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+ 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+ 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+ 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+ 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+ 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+ 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+ 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+ 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+ 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+ 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+ 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+ 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+ 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+ 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+ 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+ 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+ 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+ 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+ 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+ 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+ 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+ 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+ 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+ 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+ 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+ 0xf10605deUL
+#endif
+ }
+};
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/deflate.c b/tqtinterface/qt4/src/3rdparty/zlib/deflate.c
new file mode 100644
index 0000000..1692d87
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/deflate.c
@@ -0,0 +1,1502 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process depends on being able to identify portions
+ * of the input text which are identical to earlier input (within a
+ * sliding window trailing behind the input currently being processed).
+ *
+ * The most straightforward technique turns out to be the fastest for
+ * most input files: try all possible matches and select the longest.
+ * The key feature of this algorithm is that insertions into the string
+ * dictionary are very simple and thus fast, and deletions are avoided
+ * completely. Insertions are performed at each input character, whereas
+ * string matches are performed only when the previous match ends. So it
+ * is preferable to spend more time in matches to allow very fast string
+ * insertions and avoid deletions. The matching algorithm for small
+ * strings is inspired from that of Rabin & Karp. A brute force approach
+ * is used to tqfind longer strings when a small match has been found.
+ * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ * (by Leonid Broukhis).
+ * A previous version of this file used a more sophisticated algorithm
+ * (by Fiala and Greene) which is guaranteed to run in linear amortized
+ * time, but has a larger average cost, uses more memory and is patented.
+ * However the F&G algorithm may be faster for some highly redundant
+ * files if the parameter max_chain_length (described below) is too large.
+ *
+ * ACKNOWLEDGEMENTS
+ *
+ * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ * I found it in 'freeze' written by Leonid Broukhis.
+ * Thanks to many people for bug reports and testing.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ * Available in http://www.ietf.org/rfc/rfc1951.txt
+ *
+ * A description of the Rabin and Karp algorithm is given in the book
+ * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ * Fiala,E.R., and Greene,D.H.
+ * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+ " deflate 1.2.2 Copyright 1995-2004 Jean-loup Gailly ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ * Function prototypes.
+ */
+typedef enum {
+ need_more, /* block not completed, need more input or more output */
+ block_done, /* block flush performed */
+ finish_started, /* finish started, need only more output at next deflate */
+ finish_done /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow OF((deflate_state *s, int flush));
+#endif
+local void lm_init OF((deflate_state *s));
+local void putShortMSB OF((deflate_state *s, uInt b));
+local void flush_pending OF((z_streamp strm));
+local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifndef FASTEST
+#ifdef ASMV
+ void match_init OF((void)); /* asm code initialization */
+ uInt longest_match OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match OF((deflate_state *s, IPos cur_match));
+#endif
+#endif
+local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
+
+#ifdef DEBUG
+local void check_match OF((deflate_state *s, IPos start, IPos match,
+ int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+# define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+ ush good_length; /* reduce lazy search above this match length */
+ ush max_lazy; /* do not perform lazy search above this match length */
+ ush nice_length; /* quit search above this match length */
+ ush max_chain;
+ compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/* good lazy nice chain */
+/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
+/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4, 5, 16, 8, deflate_fast},
+/* 3 */ {4, 6, 32, 32, deflate_fast},
+
+/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
+/* 5 */ {8, 16, 32, 32, deflate_slow},
+/* 6 */ {8, 16, 128, 128, deflate_slow},
+/* 7 */ {8, 32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define ETQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN assertion: all calls to to UPDATE_HASH are made with consecutive
+ * input characters, so that a running hash key can be computed from the
+ * previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN assertion: all calls to to INSERT_STRING are made with consecutive
+ * input characters and the first MIN_MATCH bytes of str are valid
+ * (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+ (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+ match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+ s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+ s->head[s->hash_size-1] = NIL; \
+ zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+ z_streamp strm;
+ int level;
+ const char *version;
+ int stream_size;
+{
+ return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+ Z_DEFAULT_STRATEGY, version, stream_size);
+ /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+ version, stream_size)
+ z_streamp strm;
+ int level;
+ int method;
+ int windowBits;
+ int memLevel;
+ int strategy;
+ const char *version;
+ int stream_size;
+{
+ deflate_state *s;
+ int wrap = 1;
+ static const char my_version[] = ZLIB_VERSION;
+
+ ushf *overlay;
+ /* We overlay pending_buf and d_buf+l_buf. This works since the average
+ * output size for (length,distance) codes is <= 24 bits.
+ */
+
+ if (version == Z_NULL || version[0] != my_version[0] ||
+ stream_size != sizeof(z_stream)) {
+ return Z_VERSION_ERROR;
+ }
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+ strm->msg = Z_NULL;
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+ if (windowBits < 0) { /* suppress zlib wrapper */
+ wrap = 0;
+ windowBits = -windowBits;
+ }
+#ifdef GZIP
+ else if (windowBits > 15) {
+ wrap = 2; /* write gzip wrapper instead */
+ windowBits -= 16;
+ }
+#endif
+ if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+ windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+ strategy < 0 || strategy > Z_RLE) {
+ return Z_STREAM_ERROR;
+ }
+ if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
+ s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+ if (s == Z_NULL) return Z_MEM_ERROR;
+ strm->state = (struct internal_state FAR *)s;
+ s->strm = strm;
+
+ s->wrap = wrap;
+ s->w_bits = windowBits;
+ s->w_size = 1 << s->w_bits;
+ s->w_mask = s->w_size - 1;
+
+ s->hash_bits = memLevel + 7;
+ s->hash_size = 1 << s->hash_bits;
+ s->hash_mask = s->hash_size - 1;
+ s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+ s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+ s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
+ s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+ s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+ overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+ s->pending_buf = (uchf *) overlay;
+ s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+ if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+ s->pending_buf == Z_NULL) {
+ s->status = FINISH_STATE;
+ strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+ deflateEnd (strm);
+ return Z_MEM_ERROR;
+ }
+ s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+ s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+ s->level = level;
+ s->strategy = strategy;
+ s->method = (Byte)method;
+
+ return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+ z_streamp strm;
+ const Bytef *dictionary;
+ uInt dictLength;
+{
+ deflate_state *s;
+ uInt length = dictLength;
+ uInt n;
+ IPos hash_head = 0;
+
+ if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+ strm->state->wrap == 2 ||
+ (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
+ return Z_STREAM_ERROR;
+
+ s = strm->state;
+ if (s->wrap)
+ strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+ if (length < MIN_MATCH) return Z_OK;
+ if (length > MAX_DIST(s)) {
+ length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+ dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+ }
+ zmemcpy(s->window, dictionary, length);
+ s->strstart = length;
+ s->block_start = (long)length;
+
+ /* Insert all strings in the hash table (except for the last two bytes).
+ * s->lookahead stays null, so s->ins_h will be recomputed at the next
+ * call of fill_window.
+ */
+ s->ins_h = s->window[0];
+ UPDATE_HASH(s, s->ins_h, s->window[1]);
+ for (n = 0; n <= length - MIN_MATCH; n++) {
+ INSERT_STRING(s, n, hash_head);
+ }
+ if (hash_head) hash_head = 0; /* to make compiler happy */
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+ z_streamp strm;
+{
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+ return Z_STREAM_ERROR;
+ }
+
+ strm->total_in = strm->total_out = 0;
+ strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+ strm->data_type = Z_UNKNOWN;
+
+ s = (deflate_state *)strm->state;
+ s->pending = 0;
+ s->pending_out = s->pending_buf;
+
+ if (s->wrap < 0) {
+ s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+ }
+ s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+ strm->adler =
+#ifdef GZIP
+ s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+ adler32(0L, Z_NULL, 0);
+ s->last_flush = Z_NO_FLUSH;
+
+ _tr_init(s);
+ lm_init(s);
+
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+ z_streamp strm;
+ int bits;
+ int value;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ strm->state->bi_valid = bits;
+ strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
+ return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+ z_streamp strm;
+ int level;
+ int strategy;
+{
+ deflate_state *s;
+ compress_func func;
+ int err = Z_OK;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ s = strm->state;
+
+#ifdef FASTEST
+ if (level != 0) level = 1;
+#else
+ if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+ if (level < 0 || level > 9 || strategy < 0 || strategy > Z_RLE) {
+ return Z_STREAM_ERROR;
+ }
+ func = configuration_table[s->level].func;
+
+ if (func != configuration_table[level].func && strm->total_in != 0) {
+ /* Flush the last buffer: */
+ err = deflate(strm, Z_PARTIAL_FLUSH);
+ }
+ if (s->level != level) {
+ s->level = level;
+ s->max_lazy_match = configuration_table[level].max_lazy;
+ s->good_match = configuration_table[level].good_length;
+ s->nice_match = configuration_table[level].nice_length;
+ s->max_chain_length = configuration_table[level].max_chain;
+ }
+ s->strategy = strategy;
+ return err;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well. The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds
+ * for every combination of windowBits and memLevel, as well as wrap.
+ * But even the conservative upper bound of about 14% expansion does not
+ * seem onerous for output buffer allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+ z_streamp strm;
+ uLong sourceLen;
+{
+ deflate_state *s;
+ uLong destLen;
+
+ /* conservative upper bound */
+ destLen = sourceLen +
+ ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
+
+ /* if can't get parameters, return conservative bound */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return destLen;
+
+ /* if not default parameters, return conservative bound */
+ s = strm->state;
+ if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+ return destLen;
+
+ /* default settings: return tight bound for that case */
+ return compressBound(sourceLen);
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+ deflate_state *s;
+ uInt b;
+{
+ put_byte(s, (Byte)(b >> 8));
+ put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+ z_streamp strm;
+{
+ unsigned len = strm->state->pending;
+
+ if (len > strm->avail_out) len = strm->avail_out;
+ if (len == 0) return;
+
+ zmemcpy(strm->next_out, strm->state->pending_out, len);
+ strm->next_out += len;
+ strm->state->pending_out += len;
+ strm->total_out += len;
+ strm->avail_out -= len;
+ strm->state->pending -= len;
+ if (strm->state->pending == 0) {
+ strm->state->pending_out = strm->state->pending_buf;
+ }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+ z_streamp strm;
+ int flush;
+{
+ int old_flush; /* value of flush param for previous deflate call */
+ deflate_state *s;
+
+ if (strm == Z_NULL || strm->state == Z_NULL ||
+ flush > Z_FINISH || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
+ s = strm->state;
+
+ if (strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+ (s->status == FINISH_STATE && flush != Z_FINISH)) {
+ ERR_RETURN(strm, Z_STREAM_ERROR);
+ }
+ if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+ s->strm = strm; /* just in case */
+ old_flush = s->last_flush;
+ s->last_flush = flush;
+
+ /* Write the header */
+ if (s->status == INIT_STATE) {
+#ifdef GZIP
+ if (s->wrap == 2) {
+ put_byte(s, 31);
+ put_byte(s, 139);
+ put_byte(s, 8);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, 0);
+ put_byte(s, s->level == 9 ? 2 :
+ (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+ 4 : 0));
+ put_byte(s, 255);
+ s->status = BUSY_STATE;
+ strm->adler = crc32(0L, Z_NULL, 0);
+ }
+ else
+#endif
+ {
+ uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+ uInt level_flags;
+
+ if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+ level_flags = 0;
+ else if (s->level < 6)
+ level_flags = 1;
+ else if (s->level == 6)
+ level_flags = 2;
+ else
+ level_flags = 3;
+ header |= (level_flags << 6);
+ if (s->strstart != 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
+
+ s->status = BUSY_STATE;
+ putShortMSB(s, header);
+
+ /* Save the adler32 of the preset dictionary: */
+ if (s->strstart != 0) {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ strm->adler = adler32(0L, Z_NULL, 0);
+ }
+ }
+
+ /* Flush as much pending output as possible */
+ if (s->pending != 0) {
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ /* Since avail_out is 0, deflate will be called again with
+ * more output space, but possibly with both pending and
+ * avail_in equal to zero. There won't be anything to do,
+ * but this is not an error situation so make sure we
+ * return OK instead of BUF_ERROR at next call of deflate:
+ */
+ s->last_flush = -1;
+ return Z_OK;
+ }
+
+ /* Make sure there is something to do and avoid duplicate consecutive
+ * flushes. For repeated and useless calls with Z_FINISH, we keep
+ * returning Z_STREAM_END instead of Z_BUF_ERROR.
+ */
+ } else if (strm->avail_in == 0 && flush <= old_flush &&
+ flush != Z_FINISH) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* User must not provide more input after the first FINISH: */
+ if (s->status == FINISH_STATE && strm->avail_in != 0) {
+ ERR_RETURN(strm, Z_BUF_ERROR);
+ }
+
+ /* Start a new block or continue the current one.
+ */
+ if (strm->avail_in != 0 || s->lookahead != 0 ||
+ (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+ block_state bstate;
+
+ bstate = (*(configuration_table[s->level].func))(s, flush);
+
+ if (bstate == finish_started || bstate == finish_done) {
+ s->status = FINISH_STATE;
+ }
+ if (bstate == need_more || bstate == finish_started) {
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+ }
+ return Z_OK;
+ /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+ * of deflate should use the same flush parameter to make sure
+ * that the flush is complete. So we don't have to output an
+ * empty block here, this will be done at next call. This also
+ * ensures that for a very small output buffer, we emit at most
+ * one empty block.
+ */
+ }
+ if (bstate == block_done) {
+ if (flush == Z_PARTIAL_FLUSH) {
+ _tr_align(s);
+ } else { /* FULL_FLUSH or SYNC_FLUSH */
+ _tr_stored_block(s, (char*)0, 0L, 0);
+ /* For a full flush, this empty block will be recognized
+ * as a special marker by inflate_sync().
+ */
+ if (flush == Z_FULL_FLUSH) {
+ CLEAR_HASH(s); /* forget history */
+ }
+ }
+ flush_pending(strm);
+ if (strm->avail_out == 0) {
+ s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+ return Z_OK;
+ }
+ }
+ }
+ Assert(strm->avail_out > 0, "bug2");
+
+ if (flush != Z_FINISH) return Z_OK;
+ if (s->wrap <= 0) return Z_STREAM_END;
+
+ /* Write the trailer */
+#ifdef GZIP
+ if (s->wrap == 2) {
+ put_byte(s, (Byte)(strm->adler & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+ put_byte(s, (Byte)(strm->total_in & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+ put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+ }
+ else
+#endif
+ {
+ putShortMSB(s, (uInt)(strm->adler >> 16));
+ putShortMSB(s, (uInt)(strm->adler & 0xffff));
+ }
+ flush_pending(strm);
+ /* If avail_out is zero, the application will call deflate again
+ * to flush the rest.
+ */
+ if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+ return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+ z_streamp strm;
+{
+ int status;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+ status = strm->state->status;
+ if (status != INIT_STATE && status != BUSY_STATE &&
+ status != FINISH_STATE) {
+ return Z_STREAM_ERROR;
+ }
+
+ /* Deallocate in reverse order of allocations: */
+ TRY_FREE(strm, strm->state->pending_buf);
+ TRY_FREE(strm, strm->state->head);
+ TRY_FREE(strm, strm->state->prev);
+ TRY_FREE(strm, strm->state->window);
+
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+
+ return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+ z_streamp dest;
+ z_streamp source;
+{
+#ifdef MAXSEG_64K
+ return Z_STREAM_ERROR;
+#else
+ deflate_state *ds;
+ deflate_state *ss;
+ ushf *overlay;
+
+
+ if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+ return Z_STREAM_ERROR;
+ }
+
+ ss = source->state;
+
+ *dest = *source;
+
+ ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+ if (ds == Z_NULL) return Z_MEM_ERROR;
+ dest->state = (struct internal_state FAR *) ds;
+ *ds = *ss;
+ ds->strm = dest;
+
+ ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+ ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
+ ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
+ overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+ ds->pending_buf = (uchf *) overlay;
+
+ if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+ ds->pending_buf == Z_NULL) {
+ deflateEnd (dest);
+ return Z_MEM_ERROR;
+ }
+ /* following zmemcpy do not work for 16-bit MSDOS */
+ zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+ zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+ zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+ zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+ ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+ ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+ ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+ ds->l_desc.dyn_tree = ds->dyn_ltree;
+ ds->d_desc.dyn_tree = ds->dyn_dtree;
+ ds->bl_desc.dyn_tree = ds->bl_tree;
+
+ return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read. All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+ z_streamp strm;
+ Bytef *buf;
+ unsigned size;
+{
+ unsigned len = strm->avail_in;
+
+ if (len > size) len = size;
+ if (len == 0) return 0;
+
+ strm->avail_in -= len;
+
+ if (strm->state->wrap == 1) {
+ strm->adler = adler32(strm->adler, strm->next_in, len);
+ }
+#ifdef GZIP
+ else if (strm->state->wrap == 2) {
+ strm->adler = crc32(strm->adler, strm->next_in, len);
+ }
+#endif
+ zmemcpy(buf, strm->next_in, len);
+ strm->next_in += len;
+ strm->total_in += len;
+
+ return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+ deflate_state *s;
+{
+ s->window_size = (ulg)2L*s->w_size;
+
+ CLEAR_HASH(s);
+
+ /* Set the default configuration parameters:
+ */
+ s->max_lazy_match = configuration_table[s->level].max_lazy;
+ s->good_match = configuration_table[s->level].good_length;
+ s->nice_match = configuration_table[s->level].nice_length;
+ s->max_chain_length = configuration_table[s->level].max_chain;
+
+ s->strstart = 0;
+ s->block_start = 0L;
+ s->lookahead = 0;
+ s->match_length = s->prev_length = MIN_MATCH-1;
+ s->match_available = 0;
+ s->ins_h = 0;
+#ifdef ASMV
+ match_init(); /* initialize the asm code */
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ unsigned chain_length = s->max_chain_length;/* max hash chain length */
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ int best_len = s->prev_length; /* best match length so far */
+ int nice_match = s->nice_match; /* stop if match long enough */
+ IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+ s->strstart - (IPos)MAX_DIST(s) : NIL;
+ /* Stop when cur_match becomes <= limit. To simplify the code,
+ * we prevent matches with the string of window index 0.
+ */
+ Posf *prev = s->prev;
+ uInt wtqmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+ /* Compare two bytes at a time. Note: this is not always beneficial.
+ * Try with and without -DUNALIGNED_OK to check.
+ */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+ register ush scan_start = *(ushf*)scan;
+ register ush scan_end = *(ushf*)(scan+best_len-1);
+#else
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+ register Byte scan_end1 = scan[best_len-1];
+ register Byte scan_end = scan[best_len];
+#endif
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ /* Do not waste too much time if we already have a good match: */
+ if (s->prev_length >= s->good_match) {
+ chain_length >>= 2;
+ }
+ /* Do not look for matches beyond the end of the input. This is necessary
+ * to make deflate deterministic.
+ */
+ if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ do {
+ Assert(cur_match < s->strstart, "no future");
+ match = s->window + cur_match;
+
+ /* Skip to next match if the match length cannot increase
+ * or if the match length is less than 2:
+ */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+ /* This code assumes sizeof(unsigned short) == 2. Do not use
+ * UNALIGNED_OK if your compiler uses a different size.
+ */
+ if (*(ushf*)(match+best_len-1) != scan_end ||
+ *(ushf*)match != scan_start) continue;
+
+ /* It is not necessary to compare scan[2] and match[2] since they are
+ * always equal when the other bytes match, given that the hash keys
+ * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+ * strstart+3, +5, ... up to strstart+257. We check for insufficient
+ * lookahead only every 4th comparison; the 128th check will be made
+ * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+ * necessary to put more guard bytes at the end of the window, or
+ * to check more often for insufficient lookahead.
+ */
+ Assert(scan[2] == match[2], "scan[2]?");
+ scan++, match++;
+ do {
+ } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+ scan < strend);
+ /* The funny "do {}" generates better code on most compilers */
+
+ /* Here, scan <= window+strstart+257 */
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+ if (*scan == *match) scan++;
+
+ len = (MAX_MATCH - 1) - (int)(strend-scan);
+ scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+ if (match[best_len] != scan_end ||
+ match[best_len-1] != scan_end1 ||
+ *match != *scan ||
+ *++match != scan[1]) continue;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match++;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+ scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+ if (len > best_len) {
+ s->match_start = cur_match;
+ best_len = len;
+ if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+ scan_end = *(ushf*)(scan+best_len-1);
+#else
+ scan_end1 = scan[best_len-1];
+ scan_end = scan[best_len];
+#endif
+ }
+ } while ((cur_match = prev[cur_match & wtqmask]) > limit
+ && --chain_length != 0);
+
+ if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+ return s->lookahead;
+}
+#endif /* ASMV */
+#endif /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 or strategy == Z_RLE only
+ */
+local uInt longest_match_fast(s, cur_match)
+ deflate_state *s;
+ IPos cur_match; /* current match */
+{
+ register Bytef *scan = s->window + s->strstart; /* current string */
+ register Bytef *match; /* matched string */
+ register int len; /* length of current match */
+ register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+ /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+ Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+ Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+ Assert(cur_match < s->strstart, "no future");
+
+ match = s->window + cur_match;
+
+ /* Return failure if the match length is less than 2:
+ */
+ if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+ /* The check at best_len-1 can be removed because it will be made
+ * again later. (This heuristic is not always a win.)
+ * It is not necessary to compare scan[2] and match[2] since they
+ * are always equal when the other bytes match, given that
+ * the hash keys are equal and that HASH_BITS >= 8.
+ */
+ scan += 2, match += 2;
+ Assert(*scan == *match, "match[2]?");
+
+ /* We check for insufficient lookahead only every 8th comparison;
+ * the 256th check will be made at strstart+258.
+ */
+ do {
+ } while (*++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ *++scan == *++match && *++scan == *++match &&
+ scan < strend);
+
+ Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+ len = MAX_MATCH - (int)(strend - scan);
+
+ if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+ s->match_start = cur_match;
+ return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+ deflate_state *s;
+ IPos start, match;
+ int length;
+{
+ /* check that the match is indeed a match */
+ if (zmemcmp(s->window + match,
+ s->window + start, length) != ETQUAL) {
+ fprintf(stderr, " start %u, match %u, length %d\n",
+ start, match, length);
+ do {
+ fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+ } while (--length != 0);
+ z_error("invalid match");
+ }
+ if (z_verbose > 1) {
+ fprintf(stderr,"\\[%d,%d]", start-match, length);
+ do { putc(s->window[start++], stderr); } while (--length != 0);
+ }
+}
+#else
+# define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ * At least one byte has been read, or avail_in == 0; reads are
+ * performed for at least two bytes (required for the zip translate_eol
+ * option -- not supported here).
+ */
+local void fill_window(s)
+ deflate_state *s;
+{
+ register unsigned n, m;
+ register Posf *p;
+ unsigned more; /* Amount of free space at the end of the window. */
+ uInt wsize = s->w_size;
+
+ do {
+ more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+ /* Deal with !@#$% 64K limit: */
+ if (sizeof(int) <= 2) {
+ if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+ more = wsize;
+
+ } else if (more == (unsigned)(-1)) {
+ /* Very unlikely, but possible on 16 bit machine if
+ * strstart == 0 && lookahead == 1 (input done a byte at time)
+ */
+ more--;
+ }
+ }
+
+ /* If the window is almost full and there is insufficient lookahead,
+ * move the upper half to the lower one to make room in the upper half.
+ */
+ if (s->strstart >= wsize+MAX_DIST(s)) {
+
+ zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+ s->match_start -= wsize;
+ s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
+ s->block_start -= (long) wsize;
+
+ /* Slide the hash table (could be avoided with 32 bit values
+ at the expense of memory usage). We slide even when level == 0
+ to keep the hash table consistent if we switch back to level > 0
+ later. (Using level 0 permanently is not an optimal usage of
+ zlib, so we don't care about this pathological case.)
+ */
+ n = s->hash_size;
+ p = &s->head[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ } while (--n);
+
+ n = wsize;
+#ifndef FASTEST
+ p = &s->prev[n];
+ do {
+ m = *--p;
+ *p = (Pos)(m >= wsize ? m-wsize : NIL);
+ /* If n is not on any hash chain, prev[n] is garbage but
+ * its value will never be used.
+ */
+ } while (--n);
+#endif
+ more += wsize;
+ }
+ if (s->strm->avail_in == 0) return;
+
+ /* If there was no sliding:
+ * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ * more == window_size - lookahead - strstart
+ * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ * => more >= window_size - 2*WSIZE + 2
+ * In the BIG_MEM or MMAP case (not yet supported),
+ * window_size == input_size + MIN_LOOKAHEAD &&
+ * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ * Otherwise, window_size == 2*WSIZE so more >= 2.
+ * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+ */
+ Assert(more >= 2, "more < 2");
+
+ n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+ s->lookahead += n;
+
+ /* Initialize the hash value now that we have some input: */
+ if (s->lookahead >= MIN_MATCH) {
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ }
+ /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+ * but this is not important since only literal bytes will be emitted.
+ */
+
+ } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+ _tr_flush_block(s, (s->block_start >= 0L ? \
+ (charf *)&s->window[(unsigned)s->block_start] : \
+ (charf *)Z_NULL), \
+ (ulg)((long)s->strstart - s->block_start), \
+ (eof)); \
+ s->block_start = s->strstart; \
+ flush_pending(s->strm); \
+ Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+ FLUSH_BLOCK_ONLY(s, eof); \
+ if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+ * to pending_buf_size, and each stored block has a 5 byte header:
+ */
+ ulg max_block_size = 0xffff;
+ ulg max_start;
+
+ if (max_block_size > s->pending_buf_size - 5) {
+ max_block_size = s->pending_buf_size - 5;
+ }
+
+ /* Copy as much as possible from input to output: */
+ for (;;) {
+ /* Fill the window as much as possible: */
+ if (s->lookahead <= 1) {
+
+ Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+ s->block_start >= (long)s->w_size, "slide too late");
+
+ fill_window(s);
+ if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+ Assert(s->block_start >= 0L, "block gone");
+
+ s->strstart += s->lookahead;
+ s->lookahead = 0;
+
+ /* Emit a stored block if pending_buf will be full: */
+ max_start = s->block_start + max_block_size;
+ if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+ /* strstart == 0 is possible when wraparound on 16-bit machine */
+ s->lookahead = (uInt)(s->strstart - max_start);
+ s->strstart = (uInt)max_start;
+ FLUSH_BLOCK(s, 0);
+ }
+ /* Flush if we may have to slide, otherwise block_start may become
+ * negative and the data will be gone:
+ */
+ if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+ FLUSH_BLOCK(s, 0);
+ }
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of the hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match_length < MIN_MATCH
+ */
+ if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+#ifdef FASTEST
+ if ((s->strategy < Z_HUFFMAN_ONLY) ||
+ (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#else
+ if (s->strategy < Z_HUFFMAN_ONLY) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+#endif
+ /* longest_match() or longest_match_fast() sets match_start */
+ }
+ if (s->match_length >= MIN_MATCH) {
+ check_match(s, s->strstart, s->match_start, s->match_length);
+
+ _tr_tally_dist(s, s->strstart - s->match_start,
+ s->match_length - MIN_MATCH, bflush);
+
+ s->lookahead -= s->match_length;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+#ifndef FASTEST
+ if (s->match_length <= s->max_insert_length &&
+ s->lookahead >= MIN_MATCH) {
+ s->match_length--; /* string at strstart already in table */
+ do {
+ s->strstart++;
+ INSERT_STRING(s, s->strstart, hash_head);
+ /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+ * always MIN_MATCH bytes ahead.
+ */
+ } while (--s->match_length != 0);
+ s->strstart++;
+ } else
+#endif
+ {
+ s->strstart += s->match_length;
+ s->match_length = 0;
+ s->ins_h = s->window[s->strstart];
+ UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+ Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+ /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ } else {
+ /* No match, output a literal byte */
+ Tracevv((stderr,"%c", s->window[s->strstart]));
+ _tr_tally_lit (s, s->window[s->strstart], bflush);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (bflush) FLUSH_BLOCK(s, 0);
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+ deflate_state *s;
+ int flush;
+{
+ IPos hash_head = NIL; /* head of hash chain */
+ int bflush; /* set if current block must be flushed */
+
+ /* Process the input block. */
+ for (;;) {
+ /* Make sure that we always have enough lookahead, except
+ * at the end of the input file. We need MAX_MATCH bytes
+ * for the next match, plus MIN_MATCH bytes to insert the
+ * string following the next match.
+ */
+ if (s->lookahead < MIN_LOOKAHEAD) {
+ fill_window(s);
+ if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+ return need_more;
+ }
+ if (s->lookahead == 0) break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= MIN_MATCH) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+
+ /* Find the longest match, discarding those <= prev_length.
+ */
+ s->prev_length = s->match_length, s->prev_match = s->match_start;
+ s->match_length = MIN_MATCH-1;
+
+ if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+ s->strstart - hash_head <= MAX_DIST(s)) {
+ /* To simplify the code, we prevent matches with the string
+ * of window index 0 (in particular we have to avoid a match
+ * of the string with itself at the start of the input file).
+ */
+ if (s->strategy < Z_HUFFMAN_ONLY) {
+ s->match_length = longest_match (s, hash_head);
+ } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
+ s->match_length = longest_match_fast (s, hash_head);
+ }
+ /* longest_match() or longest_match_fast() sets match_start */
+
+ if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+ || (s->match_length == MIN_MATCH &&
+ s->strstart - s->match_start > TOO_FAR)
+#endif
+ )) {
+
+ /* If prev_match is also MIN_MATCH, match_start is garbage
+ * but we will ignore the current match anyway.
+ */
+ s->match_length = MIN_MATCH-1;
+ }
+ }
+ /* If there was a match at the previous step and the current
+ * match is not better, output the previous match:
+ */
+ if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+ uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+ /* Do not insert strings in hash table beyond this. */
+
+ check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+ _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+ s->prev_length - MIN_MATCH, bflush);
+
+ /* Insert in hash table all strings up to the end of the match.
+ * strstart-1 and strstart are already inserted. If there is not
+ * enough lookahead, the last two strings are not inserted in
+ * the hash table.
+ */
+ s->lookahead -= s->prev_length-1;
+ s->prev_length -= 2;
+ do {
+ if (++s->strstart <= max_insert) {
+ INSERT_STRING(s, s->strstart, hash_head);
+ }
+ } while (--s->prev_length != 0);
+ s->match_available = 0;
+ s->match_length = MIN_MATCH-1;
+ s->strstart++;
+
+ if (bflush) FLUSH_BLOCK(s, 0);
+
+ } else if (s->match_available) {
+ /* If there was no match at the previous position, output a
+ * single literal. If there was a match but the current match
+ * is longer, truncate the previous match to a single literal.
+ */
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ if (bflush) {
+ FLUSH_BLOCK_ONLY(s, 0);
+ }
+ s->strstart++;
+ s->lookahead--;
+ if (s->strm->avail_out == 0) return need_more;
+ } else {
+ /* There is no previous match to compare with, wait for
+ * the next step to decide.
+ */
+ s->match_available = 1;
+ s->strstart++;
+ s->lookahead--;
+ }
+ }
+ Assert (flush != Z_NO_FLUSH, "no flush?");
+ if (s->match_available) {
+ Tracevv((stderr,"%c", s->window[s->strstart-1]));
+ _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+ s->match_available = 0;
+ }
+ FLUSH_BLOCK(s, flush == Z_FINISH);
+ return flush == Z_FINISH ? finish_done : block_done;
+}
+#endif /* FASTEST */
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/deflate.h b/tqtinterface/qt4/src/3rdparty/zlib/deflate.h
new file mode 100644
index 0000000..8632561
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/deflate.h
@@ -0,0 +1,325 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2002 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer creation by deflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip encoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS 256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES 30
+/* number of distance codes */
+
+#define BL_CODES 19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE 42
+#define BUSY_STATE 113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+ union {
+ ush freq; /* frequency count */
+ ush code; /* bit string */
+ } fc;
+ union {
+ ush dad; /* father node in Huffman tree */
+ ush len; /* length of bit string */
+ } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad dl.dad
+#define Len dl.len
+
+typedef struct static_tree_desc_s static_tree_desc;
+
+typedef struct tree_desc_s {
+ ct_data *dyn_tree; /* the dynamic tree */
+ int max_code; /* largest code with non zero frequency */
+ static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+ z_streamp strm; /* pointer back to this zlib stream */
+ int status; /* as the name implies */
+ Bytef *pending_buf; /* output still pending */
+ ulg pending_buf_size; /* size of pending_buf */
+ Bytef *pending_out; /* next pending byte to output to the stream */
+ int pending; /* nb of bytes in the pending buffer */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ Byte method; /* STORED (for zip only) or DEFLATED */
+ int last_flush; /* value of flush param for previous deflate call */
+
+ /* used by deflate.c: */
+
+ uInt w_size; /* LZ77 window size (32K by default) */
+ uInt w_bits; /* log2(w_size) (8..16) */
+ uInt w_mask; /* w_size - 1 */
+
+ Bytef *window;
+ /* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least wSize
+ * bytes. With this organization, matches are limited to a distance of
+ * wSize-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: use the user input buffer as sliding window.
+ */
+
+ ulg window_size;
+ /* Actual size of window: 2*wSize, except when the user input buffer
+ * is directly used as sliding window.
+ */
+
+ Posf *prev;
+ /* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+
+ Posf *head; /* Heads of the hash chains or NIL. */
+
+ uInt ins_h; /* hash index of string to be inserted */
+ uInt hash_size; /* number of elements in hash table */
+ uInt hash_bits; /* log2(hash_size) */
+ uInt hash_mask; /* hash_size-1 */
+
+ uInt hash_shift;
+ /* Number of bits by which ins_h must be shifted at each input
+ * step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * hash_shift * MIN_MATCH >= hash_bits
+ */
+
+ long block_start;
+ /* Window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+
+ uInt match_length; /* length of best match */
+ IPos prev_match; /* previous match */
+ int match_available; /* set if previous match exists */
+ uInt strstart; /* start of string to insert */
+ uInt match_start; /* start of matching string */
+ uInt lookahead; /* number of valid bytes ahead in window */
+
+ uInt prev_length;
+ /* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+ uInt max_chain_length;
+ /* To speed up deflation, hash chains are never searched beyond this
+ * length. A higher limit improves compression ratio but degrades the
+ * speed.
+ */
+
+ uInt max_lazy_match;
+ /* Attempt to tqfind a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+# define max_insert_length max_lazy_match
+ /* Insert new strings in the hash table only if the match length is not
+ * greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+ int level; /* compression level (1..9) */
+ int strategy; /* favor or force Huffman coding*/
+
+ uInt good_match;
+ /* Use a faster search when the previous match is longer than this */
+
+ int nice_match; /* Stop searching when current match exceeds this */
+
+ /* used by trees.c: */
+ /* Didn't use ct_data typedef below to supress compiler warning */
+ struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
+ struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+ struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
+
+ struct tree_desc_s l_desc; /* desc. for literal tree */
+ struct tree_desc_s d_desc; /* desc. for distance tree */
+ struct tree_desc_s bl_desc; /* desc. for bit length tree */
+
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
+ int heap_len; /* number of elements in the heap */
+ int heap_max; /* element of largest frequency */
+ /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+ uch depth[2*L_CODES+1];
+ /* Depth of each subtree used as tie breaker for trees of equal frequency
+ */
+
+ uchf *l_buf; /* buffer for literals or lengths */
+
+ uInt lit_bufsize;
+ /* Size of match buffer for literals/lengths. There are 4 reasons for
+ * limiting lit_bufsize to 64K:
+ * - frequencies can be kept in 16 bit counters
+ * - if compression is not successful for the first block, all input
+ * data is still in the window so we can still emit a stored block even
+ * when input comes from standard input. (This can also be done for
+ * all blocks if lit_bufsize is not greater than 32K.)
+ * - if compression is not successful for a file smaller than 64K, we can
+ * even emit a stored file instead of a stored block (saving 5 bytes).
+ * This is applicable only for zip (not gzip or zlib).
+ * - creating new Huffman trees less frequently may not provide fast
+ * adaptation to changes in the input data statistics. (Take for
+ * example a binary file with poorly compressible code followed by
+ * a highly compressible string table.) Smaller buffer sizes give
+ * fast adaptation but have of course the overhead of transmitting
+ * trees more frequently.
+ * - I can't count above 4
+ */
+
+ uInt last_lit; /* running index in l_buf */
+
+ ushf *d_buf;
+ /* Buffer for distances. To simplify the code, d_buf and l_buf have
+ * the same number of elements. To use different lengths, an extra flag
+ * array would be necessary.
+ */
+
+ ulg opt_len; /* bit length of current block with optimal trees */
+ ulg static_len; /* bit length of current block with static trees */
+ uInt matches; /* number of string matches in current block */
+ int last_eob_len; /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+ ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+ ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
+#endif
+
+ ush bi_buf;
+ /* Output buffer. bits are inserted starting at the bottom (least
+ * significant bits).
+ */
+ int bi_valid;
+ /* Number of valid bits in bi_buf. All bits above the last valid bit
+ * are always zero.
+ */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+ /* in trees.c */
+void _tr_init OF((deflate_state *s));
+int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+void _tr_align OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+ int eof));
+
+#define d_code(dist) \
+ ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+ extern uch _length_code[];
+ extern uch _dist_code[];
+#else
+ extern const uch _length_code[];
+ extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+ { uch cc = (c); \
+ s->d_buf[s->last_lit] = 0; \
+ s->l_buf[s->last_lit++] = cc; \
+ s->dyn_ltree[cc].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+# define _tr_tally_dist(s, distance, length, flush) \
+ { uch len = (length); \
+ ush dist = (distance); \
+ s->d_buf[s->last_lit] = dist; \
+ s->l_buf[s->last_lit++] = len; \
+ dist--; \
+ s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+ s->dyn_dtree[d_code(dist)].Freq++; \
+ flush = (s->last_lit == s->lit_bufsize-1); \
+ }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+ flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/example.c b/tqtinterface/qt4/src/3rdparty/zlib/example.c
new file mode 100644
index 0000000..c2361f9
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/example.c
@@ -0,0 +1,567 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+#else
+ extern void exit OF((int));
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+# define TESTFILE "foo-gz"
+#else
+# define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+ if (err != Z_OK) { \
+ fprintf(stderr, "%s error: %d\n", msg, err); \
+ exit(1); \
+ } \
+}
+
+const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_compress OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_gzio OF((const char *fname,
+ Byte *uncompr, uLong uncomprLen));
+void test_deflate OF((Byte *compr, uLong comprLen));
+void test_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_flush OF((Byte *compr, uLong *comprLen));
+void test_sync OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate OF((Byte *compr, uLong comprLen));
+void test_dict_inflate OF((Byte *compr, uLong comprLen,
+ Byte *uncompr, uLong uncomprLen));
+int main OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ err = compress(compr, &comprLen, (const Bytef*)hello, len);
+ CHECK_ERR(err, "compress");
+
+ strcpy((char*)uncompr, "garbage");
+
+ err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+ CHECK_ERR(err, "uncompress");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad uncompress\n");
+ exit(1);
+ } else {
+ printf("uncompress(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(fname, uncompr, uncomprLen)
+ const char *fname; /* compressed file name */
+ Byte *uncompr;
+ uLong uncomprLen;
+{
+#ifdef NO_GZCOMPRESS
+ fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+#else
+ int err;
+ int len = (int)strlen(hello)+1;
+ gzFile file;
+ z_off_t pos;
+
+ file = gzopen(fname, "wb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ gzputc(file, 'h');
+ if (gzputs(file, "ello") != 4) {
+ fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (gzprintf(file, ", %s!", "hello") != 8) {
+ fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+ gzclose(file);
+
+ file = gzopen(fname, "rb");
+ if (file == NULL) {
+ fprintf(stderr, "gzopen error\n");
+ exit(1);
+ }
+ strcpy((char*)uncompr, "garbage");
+
+ if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
+ fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+ exit(1);
+ } else {
+ printf("gzread(): %s\n", (char*)uncompr);
+ }
+
+ pos = gzseek(file, -8L, SEEK_CUR);
+ if (pos != 6 || gztell(file) != pos) {
+ fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+ (long)pos, (long)gztell(file));
+ exit(1);
+ }
+
+ if (gzgetc(file) != ' ') {
+ fprintf(stderr, "gzgetc error\n");
+ exit(1);
+ }
+
+ if (gzungetc(' ', file) != ' ') {
+ fprintf(stderr, "gzungetc error\n");
+ exit(1);
+ }
+
+ gzgets(file, (char*)uncompr, (int)uncomprLen);
+ if (strlen((char*)uncompr) != 7) { /* " hello!" */
+ fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+ exit(1);
+ }
+ if (strcmp((char*)uncompr, hello + 6)) {
+ fprintf(stderr, "bad gzgets after gzseek\n");
+ exit(1);
+ } else {
+ printf("gzgets() after gzseek: %s\n", (char*)uncompr);
+ }
+
+ gzclose(file);
+#endif
+}
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uLong len = (uLong)strlen(hello)+1;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (Bytef*)hello;
+ c_stream.next_out = compr;
+
+ while (c_stream.total_in != len && c_stream.total_out < comprLen) {
+ c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+ /* Finish the stream, still forcing small buffers: */
+ for (;;) {
+ c_stream.avail_out = 1;
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 0;
+ d_stream.next_out = uncompr;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+ d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate\n");
+ exit(1);
+ } else {
+ printf("inflate(): %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_SPEED);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ /* At this point, uncompr is still mostly zeroes, so it should compress
+ * very well:
+ */
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ if (c_stream.avail_in != 0) {
+ fprintf(stderr, "deflate not greedy\n");
+ exit(1);
+ }
+
+ /* Feed in already compressed data and switch to no compression: */
+ deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+ c_stream.next_in = compr;
+ c_stream.avail_in = (uInt)comprLen/2;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ /* Switch back to compressing mode: */
+ deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+ c_stream.next_in = uncompr;
+ c_stream.avail_in = (uInt)uncomprLen;
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ for (;;) {
+ d_stream.next_out = uncompr; /* discard the output */
+ d_stream.avail_out = (uInt)uncomprLen;
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "large inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+ fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+ exit(1);
+ } else {
+ printf("large_inflate(): OK\n");
+ }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+ Byte *compr;
+ uLong *comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+ uInt len = (uInt)strlen(hello)+1;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_in = (Bytef*)hello;
+ c_stream.next_out = compr;
+ c_stream.avail_in = 3;
+ c_stream.avail_out = (uInt)*comprLen;
+ err = deflate(&c_stream, Z_FULL_FLUSH);
+ CHECK_ERR(err, "deflate");
+
+ compr[3]++; /* force an error in first compressed block */
+ c_stream.avail_in = len - 3;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ CHECK_ERR(err, "deflate");
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = 2; /* just read the zlib header */
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ inflate(&d_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "inflate");
+
+ d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */
+ err = inflateSync(&d_stream); /* but skip the damaged part */
+ CHECK_ERR(err, "inflateSync");
+
+ err = inflate(&d_stream, Z_FINISH);
+ if (err != Z_DATA_ERROR) {
+ fprintf(stderr, "inflate should report DATA_ERROR\n");
+ /* Because of incorrect adler32 */
+ exit(1);
+ }
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+ Byte *compr;
+ uLong comprLen;
+{
+ z_stream c_stream; /* compression stream */
+ int err;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+ CHECK_ERR(err, "deflateInit");
+
+ err = deflateSetDictionary(&c_stream,
+ (const Bytef*)dictionary, sizeof(dictionary));
+ CHECK_ERR(err, "deflateSetDictionary");
+
+ dictId = c_stream.adler;
+ c_stream.next_out = compr;
+ c_stream.avail_out = (uInt)comprLen;
+
+ c_stream.next_in = (Bytef*)hello;
+ c_stream.avail_in = (uInt)strlen(hello)+1;
+
+ err = deflate(&c_stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ fprintf(stderr, "deflate should report Z_STREAM_END\n");
+ exit(1);
+ }
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+ Byte *compr, *uncompr;
+ uLong comprLen, uncomprLen;
+{
+ int err;
+ z_stream d_stream; /* decompression stream */
+
+ strcpy((char*)uncompr, "garbage");
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = compr;
+ d_stream.avail_in = (uInt)comprLen;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = uncompr;
+ d_stream.avail_out = (uInt)uncomprLen;
+
+ for (;;) {
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ if (err == Z_NEED_DICT) {
+ if (d_stream.adler != dictId) {
+ fprintf(stderr, "unexpected dictionary");
+ exit(1);
+ }
+ err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+ sizeof(dictionary));
+ }
+ CHECK_ERR(err, "inflate with dict");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ if (strcmp((char*)uncompr, hello)) {
+ fprintf(stderr, "bad inflate with dict\n");
+ exit(1);
+ } else {
+ printf("inflate with dictionary: %s\n", (char *)uncompr);
+ }
+}
+
+/* ===========================================================================
+ * Usage: example [output.gz [input.gz]]
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ Byte *compr, *uncompr;
+ uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+ uLong uncomprLen = comprLen;
+ static const char* myVersion = ZLIB_VERSION;
+
+ if (zlibVersion()[0] != myVersion[0]) {
+ fprintf(stderr, "incompatible zlib version\n");
+ exit(1);
+
+ } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+ fprintf(stderr, "warning: different zlib version\n");
+ }
+
+ printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
+ ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
+
+ compr = (Byte*)calloc((uInt)comprLen, 1);
+ uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
+ /* compr and uncompr are cleared to avoid reading uninitialized
+ * data and to ensure that uncompr compresses well.
+ */
+ if (compr == Z_NULL || uncompr == Z_NULL) {
+ printf("out of memory\n");
+ exit(1);
+ }
+ test_compress(compr, comprLen, uncompr, uncomprLen);
+
+ test_gzio((argc > 1 ? argv[1] : TESTFILE),
+ uncompr, uncomprLen);
+
+ test_deflate(compr, comprLen);
+ test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+ test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ test_flush(compr, &comprLen);
+ test_sync(compr, comprLen, uncompr, uncomprLen);
+ comprLen = uncomprLen;
+
+ test_dict_deflate(compr, comprLen);
+ test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+ free(compr);
+ free(uncompr);
+
+ return 0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/gzio.c b/tqtinterface/qt4/src/3rdparty/zlib/gzio.c
new file mode 100644
index 0000000..4b56f31
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/gzio.c
@@ -0,0 +1,1009 @@
+/* gzio.c -- IO on .gz files
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+#ifdef NO_DEFLATE /* for compatiblity with old definition */
+# define NO_GZCOMPRESS
+#endif
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+#ifndef Z_BUFSIZE
+# ifdef MAXSEG_64K
+# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
+# else
+# define Z_BUFSIZE 16384
+# endif
+#endif
+#ifndef Z_PRINTF_BUFSIZE
+# define Z_PRINTF_BUFSIZE 4096
+#endif
+
+#ifdef __MVS__
+# pragma map (fdopen , "\174\174FDOPEN")
+ FILE *fdopen(int, const char *);
+#endif
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+#define ALLOC(size) malloc(size)
+#define TRYFREE(p) {if (p) free(p);}
+
+static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
+#define COMMENT 0x10 /* bit 4 set: file comment present */
+#define RESERVED 0xE0 /* bits 5..7: reserved */
+
+typedef struct gz_stream {
+ z_stream stream;
+ int z_err; /* error code for last stream operation */
+ int z_eof; /* set if end of input file */
+ FILE *file; /* .gz file */
+ Byte *inbuf; /* input buffer */
+ Byte *outbuf; /* output buffer */
+ uLong crc; /* crc32 of uncompressed data */
+ char *msg; /* error message */
+ char *path; /* path name for debugging only */
+ int transtqparent; /* 1 if input file is not a .gz file */
+ char mode; /* 'w' or 'r' */
+ z_off_t start; /* start of compressed data in file (header skipped) */
+ z_off_t in; /* bytes into deflate or inflate */
+ z_off_t out; /* bytes out of deflate or inflate */
+ int back; /* one character push-back */
+ int last; /* true if push-back is last character */
+} gz_stream;
+
+
+local gzFile gz_open OF((const char *path, const char *mode, int fd));
+local int do_flush OF((gzFile file, int flush));
+local int get_byte OF((gz_stream *s));
+local void check_header OF((gz_stream *s));
+local int destroy OF((gz_stream *s));
+local void putLong OF((FILE *file, uLong x));
+local uLong getLong OF((gz_stream *s));
+
+/* ===========================================================================
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb"). The file is given either by file descriptor
+ or path name (if fd == -1).
+ gz_open returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR).
+*/
+local gzFile gz_open (path, mode, fd)
+ const char *path;
+ const char *mode;
+ int fd;
+{
+ int err;
+ int level = Z_DEFAULT_COMPRESSION; /* compression level */
+ int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
+ char *p = (char*)mode;
+ gz_stream *s;
+ char fmode[80]; /* copy of mode, without the compression level */
+ char *m = fmode;
+
+ if (!path || !mode) return Z_NULL;
+
+ s = (gz_stream *)ALLOC(sizeof(gz_stream));
+ if (!s) return Z_NULL;
+
+ s->stream.zalloc = (alloc_func)0;
+ s->stream.zfree = (free_func)0;
+ s->stream.opaque = (voidpf)0;
+ s->stream.next_in = s->inbuf = Z_NULL;
+ s->stream.next_out = s->outbuf = Z_NULL;
+ s->stream.avail_in = s->stream.avail_out = 0;
+ s->file = NULL;
+ s->z_err = Z_OK;
+ s->z_eof = 0;
+ s->in = 0;
+ s->out = 0;
+ s->back = EOF;
+ s->crc = crc32(0L, Z_NULL, 0);
+ s->msg = NULL;
+ s->transtqparent = 0;
+
+ s->path = (char*)ALLOC(strlen(path)+1);
+ if (s->path == NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ strcpy(s->path, path); /* do this early for debugging */
+
+ s->mode = '\0';
+ do {
+ if (*p == 'r') s->mode = 'r';
+ if (*p == 'w' || *p == 'a') s->mode = 'w';
+ if (*p >= '0' && *p <= '9') {
+ level = *p - '0';
+ } else if (*p == 'f') {
+ strategy = Z_FILTERED;
+ } else if (*p == 'h') {
+ strategy = Z_HUFFMAN_ONLY;
+ } else if (*p == 'R') {
+ strategy = Z_RLE;
+ } else {
+ *m++ = *p; /* copy the mode */
+ }
+ } while (*p++ && m != fmode + sizeof(fmode));
+ if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
+
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ err = Z_STREAM_ERROR;
+#else
+ err = deflateInit2(&(s->stream), level,
+ Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
+ /* windowBits is passed < 0 to suppress zlib header */
+
+ s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+#endif
+ if (err != Z_OK || s->outbuf == Z_NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ } else {
+ s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
+
+ err = inflateInit2(&(s->stream), -MAX_WBITS);
+ /* windowBits is passed < 0 to tell that there is no zlib header.
+ * Note that in this case inflate *requires* an extra "dummy" byte
+ * after the compressed stream in order to complete decompression and
+ * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
+ * present after the compressed stream.
+ */
+ if (err != Z_OK || s->inbuf == Z_NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+
+ errno = 0;
+ s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
+
+ if (s->file == NULL) {
+ return destroy(s), (gzFile)Z_NULL;
+ }
+ if (s->mode == 'w') {
+ /* Write a very simple .gz header:
+ */
+ fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
+ Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
+ s->start = 10L;
+ /* We use 10L instead of ftell(s->file) to because ftell causes an
+ * fflush on some systems. This version of the library doesn't use
+ * start anyway in write mode, so this initialization is not
+ * necessary.
+ */
+ } else {
+ check_header(s); /* skip the .gz header */
+ s->start = ftell(s->file) - s->stream.avail_in;
+ }
+
+ return (gzFile)s;
+}
+
+/* ===========================================================================
+ Opens a gzip (.gz) file for reading or writing.
+*/
+gzFile TQ_ZEXPORT gzopen (path, mode)
+ const char *path;
+ const char *mode;
+{
+ return gz_open (path, mode, -1);
+}
+
+/* ===========================================================================
+ Associate a gzFile with the file descriptor fd. fd is not dup'ed here
+ to mimic the behavio(u)r of fdopen.
+*/
+gzFile ZEXPORT gzdopen (fd, mode)
+ int fd;
+ const char *mode;
+{
+ char name[20];
+
+ if (fd < 0) return (gzFile)Z_NULL;
+ sprintf(name, "<fd:%d>", fd); /* for debugging */
+
+ return gz_open (name, mode, fd);
+}
+
+/* ===========================================================================
+ * Update the compression level and strategy
+ */
+int ZEXPORT gzsetparams (file, level, strategy)
+ gzFile file;
+ int level;
+ int strategy;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ /* Make room to allow flushing */
+ if (s->stream.avail_out == 0) {
+
+ s->stream.next_out = s->outbuf;
+ if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+ s->z_err = Z_ERRNO;
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+
+ return deflateParams (&(s->stream), level, strategy);
+}
+
+/* ===========================================================================
+ Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+ for end of file.
+ IN assertion: the stream s has been sucessfully opened for reading.
+*/
+local int get_byte(s)
+ gz_stream *s;
+{
+ if (s->z_eof) return EOF;
+ if (s->stream.avail_in == 0) {
+ errno = 0;
+ s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ if (s->stream.avail_in == 0) {
+ s->z_eof = 1;
+ if (ferror(s->file)) s->z_err = Z_ERRNO;
+ return EOF;
+ }
+ s->stream.next_in = s->inbuf;
+ }
+ s->stream.avail_in--;
+ return *(s->stream.next_in)++;
+}
+
+/* ===========================================================================
+ Check the gzip header of a gz_stream opened for reading. Set the stream
+ mode to transtqparent if the gzip magic header is not present; set s->err
+ to Z_DATA_ERROR if the magic header is present but the rest of the header
+ is incorrect.
+ IN assertion: the stream s has already been created sucessfully;
+ s->stream.avail_in is zero for the first time, but may be non-zero
+ for concatenated .gz files.
+*/
+local void check_header(s)
+ gz_stream *s;
+{
+ int method; /* method byte */
+ int flags; /* flags byte */
+ uInt len;
+ int c;
+
+ /* Assure two bytes in the buffer so we can peek ahead -- handle case
+ where first byte of header is at the end of the buffer after the last
+ gzip segment */
+ len = s->stream.avail_in;
+ if (len < 2) {
+ if (len) s->inbuf[0] = s->stream.next_in[0];
+ errno = 0;
+ len = fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
+ if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
+ s->stream.avail_in += len;
+ s->stream.next_in = s->inbuf;
+ if (s->stream.avail_in < 2) {
+ s->transtqparent = s->stream.avail_in;
+ return;
+ }
+ }
+
+ /* Peek ahead to check the gzip magic header */
+ if (s->stream.next_in[0] != gz_magic[0] ||
+ s->stream.next_in[1] != gz_magic[1]) {
+ s->transtqparent = 1;
+ return;
+ }
+ s->stream.avail_in -= 2;
+ s->stream.next_in += 2;
+
+ /* Check the rest of the gzip header */
+ method = get_byte(s);
+ flags = get_byte(s);
+ if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+ s->z_err = Z_DATA_ERROR;
+ return;
+ }
+
+ /* Discard time, xflags and OS code: */
+ for (len = 0; len < 6; len++) (void)get_byte(s);
+
+ if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+ len = (uInt)get_byte(s);
+ len += ((uInt)get_byte(s))<<8;
+ /* len is garbage if EOF but the loop below will quit anyway */
+ while (len-- != 0 && get_byte(s) != EOF) ;
+ }
+ if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
+ while ((c = get_byte(s)) != 0 && c != EOF) ;
+ }
+ if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
+ for (len = 0; len < 2; len++) (void)get_byte(s);
+ }
+ s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
+}
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+ Try freeing in the reverse order of allocations.
+ */
+local int destroy (s)
+ gz_stream *s;
+{
+ int err = Z_OK;
+
+ if (!s) return Z_STREAM_ERROR;
+
+ TRYFREE(s->msg);
+
+ if (s->stream.state != NULL) {
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ err = Z_STREAM_ERROR;
+#else
+ err = deflateEnd(&(s->stream));
+#endif
+ } else if (s->mode == 'r') {
+ err = inflateEnd(&(s->stream));
+ }
+ }
+ if (s->file != NULL && fclose(s->file)) {
+#ifdef ESPIPE
+ if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
+#endif
+ err = Z_ERRNO;
+ }
+ if (s->z_err < 0) err = s->z_err;
+
+ TRYFREE(s->inbuf);
+ TRYFREE(s->outbuf);
+ TRYFREE(s->path);
+ TRYFREE(s);
+ return err;
+}
+
+/* ===========================================================================
+ Reads the given number of uncompressed bytes from the compressed file.
+ gzread returns the number of bytes actually read (0 for end of file).
+*/
+int TQ_ZEXPORT gzread (file, buf, len)
+ gzFile file;
+ voidp buf;
+ unsigned len;
+{
+ gz_stream *s = (gz_stream*)file;
+ Bytef *start = (Bytef*)buf; /* starting point for crc computation */
+ Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
+
+ if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
+
+ if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
+ if (s->z_err == Z_STREAM_END) return 0; /* EOF */
+
+ next_out = (Byte*)buf;
+ s->stream.next_out = (Bytef*)buf;
+ s->stream.avail_out = len;
+
+ if (s->stream.avail_out && s->back != EOF) {
+ *next_out++ = s->back;
+ s->stream.next_out++;
+ s->stream.avail_out--;
+ s->back = EOF;
+ s->out++;
+ if (s->last) {
+ s->z_err = Z_STREAM_END;
+ return 1;
+ }
+ }
+
+ while (s->stream.avail_out != 0) {
+
+ if (s->transtqparent) {
+ /* Copy first the lookahead bytes: */
+ uInt n = s->stream.avail_in;
+ if (n > s->stream.avail_out) n = s->stream.avail_out;
+ if (n > 0) {
+ zmemcpy(s->stream.next_out, s->stream.next_in, n);
+ next_out += n;
+ s->stream.next_out = next_out;
+ s->stream.next_in += n;
+ s->stream.avail_out -= n;
+ s->stream.avail_in -= n;
+ }
+ if (s->stream.avail_out > 0) {
+ s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
+ s->file);
+ }
+ len -= s->stream.avail_out;
+ s->in += len;
+ s->out += len;
+ if (len == 0) s->z_eof = 1;
+ return (int)len;
+ }
+ if (s->stream.avail_in == 0 && !s->z_eof) {
+
+ errno = 0;
+ s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+ if (s->stream.avail_in == 0) {
+ s->z_eof = 1;
+ if (ferror(s->file)) {
+ s->z_err = Z_ERRNO;
+ break;
+ }
+ if (feof(s->file)) { /* avoid error for empty file */
+ s->z_err = Z_STREAM_END;
+ break;
+ }
+ }
+ s->stream.next_in = s->inbuf;
+ }
+ s->in += s->stream.avail_in;
+ s->out += s->stream.avail_out;
+ s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
+ s->in -= s->stream.avail_in;
+ s->out -= s->stream.avail_out;
+
+ if (s->z_err == Z_STREAM_END) {
+ /* Check CRC and original size */
+ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+ start = s->stream.next_out;
+
+ if (getLong(s) != s->crc) {
+ s->z_err = Z_DATA_ERROR;
+ } else {
+ (void)getLong(s);
+ /* The uncompressed length returned by above getlong() may be
+ * different from s->out in case of concatenated .gz files.
+ * Check for such files:
+ */
+ check_header(s);
+ if (s->z_err == Z_OK) {
+ inflateReset(&(s->stream));
+ s->crc = crc32(0L, Z_NULL, 0);
+ }
+ }
+ }
+ if (s->z_err != Z_OK || s->z_eof) break;
+ }
+ s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+
+ return (int)(len - s->stream.avail_out);
+}
+
+
+/* ===========================================================================
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+int ZEXPORT gzgetc(file)
+ gzFile file;
+{
+ unsigned char c;
+
+ return gzread(file, &c, 1) == 1 ? c : -1;
+}
+
+
+/* ===========================================================================
+ Push one byte back onto the stream.
+*/
+int ZEXPORT gzungetc(c, file)
+ int c;
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
+ s->back = c;
+ s->out--;
+ s->last = (s->z_err == Z_STREAM_END);
+ if (s->last) s->z_err = Z_OK;
+ s->z_eof = 0;
+ return c;
+}
+
+
+/* ===========================================================================
+ Reads bytes from the compressed file until len-1 characters are
+ read, or a newline character is read and transferred to buf, or an
+ end-of-file condition is encountered. The string is then terminated
+ with a null character.
+ gzgets returns buf, or Z_NULL in case of error.
+
+ The current implementation is not optimized at all.
+*/
+char * ZEXPORT gzgets(file, buf, len)
+ gzFile file;
+ char *buf;
+ int len;
+{
+ char *b = buf;
+ if (buf == Z_NULL || len <= 0) return Z_NULL;
+
+ while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
+ *buf = '\0';
+ return b == buf && len > 0 ? Z_NULL : b;
+}
+
+
+#ifndef NO_GZCOMPRESS
+/* ===========================================================================
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of bytes actually written (0 in case of error).
+*/
+int ZEXPORT gzwrite (file, buf, len)
+ gzFile file;
+ voidpc buf;
+ unsigned len;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ s->stream.next_in = (Bytef*)buf;
+ s->stream.avail_in = len;
+
+ while (s->stream.avail_in != 0) {
+
+ if (s->stream.avail_out == 0) {
+
+ s->stream.next_out = s->outbuf;
+ if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+ s->z_err = Z_ERRNO;
+ break;
+ }
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+ s->in += s->stream.avail_in;
+ s->out += s->stream.avail_out;
+ s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
+ s->in -= s->stream.avail_in;
+ s->out -= s->stream.avail_out;
+ if (s->z_err != Z_OK) break;
+ }
+ s->crc = crc32(s->crc, (const Bytef *)buf, len);
+
+ return (int)(len - s->stream.avail_in);
+}
+
+
+/* ===========================================================================
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error).
+*/
+#ifdef STDC
+#include <stdarg.h>
+
+int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
+{
+ char buf[Z_PRINTF_BUFSIZE];
+ va_list va;
+ int len;
+
+ buf[sizeof(buf) - 1] = 0;
+ va_start(va, format);
+#ifdef NO_vsnprintf
+# ifdef HAS_vsprintf_void
+ (void)vsprintf(buf, format, va);
+ va_end(va);
+ for (len = 0; len < sizeof(buf); len++)
+ if (buf[len] == 0) break;
+# else
+ len = vsprintf(buf, format, va);
+ va_end(va);
+# endif
+#else
+# ifdef HAS_vsnprintf_void
+ (void)vsnprintf(buf, sizeof(buf), format, va);
+ va_end(va);
+ len = strlen(buf);
+# else
+ len = vsnprintf(buf, sizeof(buf), format, va);
+ va_end(va);
+# endif
+#endif
+ if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
+ return 0;
+ return gzwrite(file, buf, (unsigned)len);
+}
+#else /* not ANSI C */
+
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+ gzFile file;
+ const char *format;
+ int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+ char buf[Z_PRINTF_BUFSIZE];
+ int len;
+
+ buf[sizeof(buf) - 1] = 0;
+#ifdef NO_snprintf
+# ifdef HAS_sprintf_void
+ sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ for (len = 0; len < sizeof(buf); len++)
+ if (buf[len] == 0) break;
+# else
+ len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#else
+# ifdef HAS_snprintf_void
+ snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+ len = strlen(buf);
+# else
+ len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+ a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+# endif
+#endif
+ if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
+ return 0;
+ return gzwrite(file, buf, len);
+}
+#endif
+
+/* ===========================================================================
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+int ZEXPORT gzputc(file, c)
+ gzFile file;
+ int c;
+{
+ unsigned char cc = (unsigned char) c; /* required for big endian systems */
+
+ return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
+}
+
+
+/* ===========================================================================
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+int ZEXPORT gzputs(file, s)
+ gzFile file;
+ const char *s;
+{
+ return gzwrite(file, (char*)s, (unsigned)strlen(s));
+}
+
+
+/* ===========================================================================
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function.
+*/
+local int do_flush (file, flush)
+ gzFile file;
+ int flush;
+{
+ uInt len;
+ int done = 0;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+ s->stream.avail_in = 0; /* should be zero already anyway */
+
+ for (;;) {
+ len = Z_BUFSIZE - s->stream.avail_out;
+
+ if (len != 0) {
+ if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
+ s->z_err = Z_ERRNO;
+ return Z_ERRNO;
+ }
+ s->stream.next_out = s->outbuf;
+ s->stream.avail_out = Z_BUFSIZE;
+ }
+ if (done) break;
+ s->out += s->stream.avail_out;
+ s->z_err = deflate(&(s->stream), flush);
+ s->out -= s->stream.avail_out;
+
+ /* Ignore the second of two consecutive flushes: */
+ if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
+
+ /* deflate has finished flushing only when it hasn't used up
+ * all the available space in the output buffer:
+ */
+ done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
+
+ if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
+ }
+ return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+
+int ZEXPORT gzflush (file, flush)
+ gzFile file;
+ int flush;
+{
+ gz_stream *s = (gz_stream*)file;
+ int err = do_flush (file, flush);
+
+ if (err) return err;
+ fflush(s->file);
+ return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+#endif /* NO_GZCOMPRESS */
+
+/* ===========================================================================
+ Sets the starting position for the next gzread or gzwrite on the given
+ compressed file. The offset represents a number of bytes in the
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error.
+ SEEK_END is not implemented, returns error.
+ In this version of the library, gzseek can be extremely slow.
+*/
+z_off_t ZEXPORT gzseek (file, offset, whence)
+ gzFile file;
+ z_off_t offset;
+ int whence;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || whence == SEEK_END ||
+ s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
+ return -1L;
+ }
+
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ return -1L;
+#else
+ if (whence == SEEK_SET) {
+ offset -= s->in;
+ }
+ if (offset < 0) return -1L;
+
+ /* At this point, offset is the number of zero bytes to write. */
+ if (s->inbuf == Z_NULL) {
+ s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
+ if (s->inbuf == Z_NULL) return -1L;
+ zmemzero(s->inbuf, Z_BUFSIZE);
+ }
+ while (offset > 0) {
+ uInt size = Z_BUFSIZE;
+ if (offset < Z_BUFSIZE) size = (uInt)offset;
+
+ size = gzwrite(file, s->inbuf, size);
+ if (size == 0) return -1L;
+
+ offset -= size;
+ }
+ return s->in;
+#endif
+ }
+ /* Rest of function is for reading only */
+
+ /* compute absolute position */
+ if (whence == SEEK_CUR) {
+ offset += s->out;
+ }
+ if (offset < 0) return -1L;
+
+ if (s->transtqparent) {
+ /* map to fseek */
+ s->back = EOF;
+ s->stream.avail_in = 0;
+ s->stream.next_in = s->inbuf;
+ if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
+
+ s->in = s->out = offset;
+ return offset;
+ }
+
+ /* For a negative seek, rewind and use positive seek */
+ if (offset >= s->out) {
+ offset -= s->out;
+ } else if (gzrewind(file) < 0) {
+ return -1L;
+ }
+ /* offset is now the number of bytes to skip. */
+
+ if (offset != 0 && s->outbuf == Z_NULL) {
+ s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+ if (s->outbuf == Z_NULL) return -1L;
+ }
+ if (offset && s->back != EOF) {
+ s->back = EOF;
+ s->out++;
+ offset--;
+ if (s->last) s->z_err = Z_STREAM_END;
+ }
+ while (offset > 0) {
+ int size = Z_BUFSIZE;
+ if (offset < Z_BUFSIZE) size = (int)offset;
+
+ size = gzread(file, s->outbuf, (uInt)size);
+ if (size <= 0) return -1L;
+ offset -= size;
+ }
+ return s->out;
+}
+
+/* ===========================================================================
+ Rewinds input file.
+*/
+int ZEXPORT gzrewind (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL || s->mode != 'r') return -1;
+
+ s->z_err = Z_OK;
+ s->z_eof = 0;
+ s->back = EOF;
+ s->stream.avail_in = 0;
+ s->stream.next_in = s->inbuf;
+ s->crc = crc32(0L, Z_NULL, 0);
+ if (!s->transtqparent) (void)inflateReset(&s->stream);
+ s->in = 0;
+ s->out = 0;
+ return fseek(s->file, s->start, SEEK_SET);
+}
+
+/* ===========================================================================
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+*/
+z_off_t ZEXPORT gztell (file)
+ gzFile file;
+{
+ return gzseek(file, 0L, SEEK_CUR);
+}
+
+/* ===========================================================================
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+int ZEXPORT gzeof (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ /* With concatenated compressed files that can have embedded
+ * crc trailers, z_eof is no longer the only/best indicator of EOF
+ * on a gz_stream. Handle end-of-stream error explicitly here.
+ */
+ if (s == NULL || s->mode != 'r') return 0;
+ if (s->z_eof) return 1;
+ return s->z_err == Z_STREAM_END;
+}
+
+/* ===========================================================================
+ Outputs a long in LSB order to the given file
+*/
+local void putLong (file, x)
+ FILE *file;
+ uLong x;
+{
+ int n;
+ for (n = 0; n < 4; n++) {
+ fputc((int)(x & 0xff), file);
+ x >>= 8;
+ }
+}
+
+/* ===========================================================================
+ Reads a long in LSB order from the given gz_stream. Sets z_err in case
+ of error.
+*/
+local uLong getLong (s)
+ gz_stream *s;
+{
+ uLong x = (uLong)get_byte(s);
+ int c;
+
+ x += ((uLong)get_byte(s))<<8;
+ x += ((uLong)get_byte(s))<<16;
+ c = get_byte(s);
+ if (c == EOF) s->z_err = Z_DATA_ERROR;
+ x += ((uLong)c)<<24;
+ return x;
+}
+
+/* ===========================================================================
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state.
+*/
+int TQ_ZEXPORT gzclose (file)
+ gzFile file;
+{
+ int err;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) return Z_STREAM_ERROR;
+
+ if (s->mode == 'w') {
+#ifdef NO_GZCOMPRESS
+ return Z_STREAM_ERROR;
+#else
+ err = do_flush (file, Z_FINISH);
+ if (err != Z_OK) return destroy((gz_stream*)file);
+
+ putLong (s->file, s->crc);
+ putLong (s->file, (uLong)(s->in & 0xffffffff));
+#endif
+ }
+ return destroy((gz_stream*)file);
+}
+
+/* ===========================================================================
+ Returns the error message for the last error which occured on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occured in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+const char * ZEXPORT gzerror (file, errnum)
+ gzFile file;
+ int *errnum;
+{
+ char *m;
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) {
+ *errnum = Z_STREAM_ERROR;
+ return (const char*)ERR_MSG(Z_STREAM_ERROR);
+ }
+ *errnum = s->z_err;
+ if (*errnum == Z_OK) return (const char*)"";
+
+ m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
+
+ if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
+
+ TRYFREE(s->msg);
+ s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
+ if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
+ strcpy(s->msg, s->path);
+ strcat(s->msg, ": ");
+ strcat(s->msg, m);
+ return (const char*)s->msg;
+}
+
+/* ===========================================================================
+ Clear the error and end-of-file flags, and do the same for the real file.
+*/
+void ZEXPORT gzclearerr (file)
+ gzFile file;
+{
+ gz_stream *s = (gz_stream*)file;
+
+ if (s == NULL) return;
+ if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
+ s->z_eof = 0;
+ clearerr(s->file);
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/infback.c b/tqtinterface/qt4/src/3rdparty/zlib/infback.c
new file mode 100644
index 0000000..8b2f431
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/infback.c
@@ -0,0 +1,622 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ This code is largely copied from inflate.c. Normally either infback.o or
+ inflate.o would be linked into an application--not both. The interface
+ with inffast.c is retained so that optimized assembler-coded versions of
+ inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+ strm provides memory allocation functions in zalloc and zfree, or
+ Z_NULL to use the library memory allocation functions.
+
+ windowBits is in the range 8..15, and window is a user-supplied
+ window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_stream FAR *strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL || window == Z_NULL ||
+ windowBits < 8 || windowBits > 15)
+ return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+ sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (voidpf)state;
+ state->wbits = windowBits;
+ state->wsize = 1U << windowBits;
+ state->window = window;
+ state->write = 0;
+ state->whave = 0;
+ return Z_OK;
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Assure that some input is available. If input is requested, but denied,
+ then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+ do { \
+ if (have == 0) { \
+ have = in(in_desc, &next); \
+ if (have == 0) { \
+ next = Z_NULL; \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+ with an error if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ PULL(); \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflateBack() with
+ an error. */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Assure that some output space is available, by writing out the window
+ if it's full. If the write fails, return from inflateBack() with a
+ Z_BUF_ERROR. */
+#define ROOM() \
+ do { \
+ if (left == 0) { \
+ put = state->window; \
+ left = state->wsize; \
+ state->whave = left; \
+ if (out(out_desc, put, left)) { \
+ ret = Z_BUF_ERROR; \
+ goto inf_leave; \
+ } \
+ } \
+ } while (0)
+
+/*
+ strm provides the memory allocation functions and window buffer on input,
+ and provides information on the unused input on return. For Z_DATA_ERROR
+ returns, strm will also provide an error message.
+
+ in() and out() are the call-back input and output functions. When
+ inflateBack() needs more input, it calls in(). When inflateBack() has
+ filled the window with output, or when it completes with data in the
+ window, it calls out() to write out the data. The application must not
+ change the provided input until in() is called again or inflateBack()
+ returns. The application must not change the window/output buffer until
+ inflateBack() returns.
+
+ in() and out() are called with a descriptor parameter provided in the
+ inflateBack() call. This parameter can be a structure that provides the
+ information required to do the read or write, as well as accumulated
+ information on the input and output such as totals and check values.
+
+ in() should return zero on failure. out() should return non-zero on
+ failure. If either in() or out() fails, than inflateBack() returns a
+ Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
+ was in() or out() that caused in the error. Otherwise, inflateBack()
+ returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+ error, or Z_MEM_ERROR if it could not allocate memory for the state.
+ inflateBack() can also return Z_STREAM_ERROR if the input parameters
+ are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_stream FAR *strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code this; /* current decoding table entry */
+ code last; /* tqparent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ /* Check that the strm exists and that the state was initialized */
+ if (strm == Z_NULL || strm->state == Z_NULL)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* Reset the state */
+ strm->msg = Z_NULL;
+ state->mode = TYPE;
+ state->last = 0;
+ state->whave = 0;
+ next = strm->next_in;
+ have = next != Z_NULL ? strm->avail_in : 0;
+ hold = 0;
+ bits = 0;
+ put = state->window;
+ left = state->wsize;
+
+ /* Inflate until end of block marked as last */
+ for (;;)
+ switch (state->mode) {
+ case TYPE:
+ /* determine and dispatch block type */
+ if (state->last) {
+ BYTEBITS();
+ state->mode = DONE;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+
+ case STORED:
+ /* get and verify stored block length */
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+
+ /* copy stored block from input to output */
+ while (state->length != 0) {
+ copy = state->length;
+ PULL();
+ ROOM();
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+
+ case TABLE:
+ /* get dynamic table entries descriptor */
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+
+ /* get code length code lengths (not a typo) */
+ state->have = 0;
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+
+ /* get length and distance code code lengths */
+ state->have = 0;
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.val < 16) {
+ NEEDBITS(this.bits);
+ DROPBITS(this.bits);
+ state->lens[state->have++] = this.val;
+ }
+ else {
+ if (this.val == 16) {
+ NEEDBITS(this.bits + 2);
+ DROPBITS(this.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = (unsigned)(state->lens[state->have - 1]);
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (this.val == 17) {
+ NEEDBITS(this.bits + 3);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(this.bits + 7);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* build code tables */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+
+ case LEN:
+ /* use inflate_fast() if we have enough input and output */
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ if (state->whave < state->wsize)
+ state->whave = state->wsize - left;
+ inflate_fast(strm, state->wsize);
+ LOAD();
+ break;
+ }
+
+ /* get a literal, length, or end-of-block code */
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.op && (this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ state->length = (unsigned)this.val;
+
+ /* process literal */
+ if (this.op == 0) {
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ ROOM();
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ }
+
+ /* process end of block */
+ if (this.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+
+ /* invalid code */
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+
+ /* length code -- get extra bits, if any */
+ state->extra = (unsigned)(this.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+
+ /* get distance code */
+ for (;;) {
+ this = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)this.val;
+
+ /* get distance extra bits, if any */
+ state->extra = (unsigned)(this.op) & 15;
+ if (state->extra != 0) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ if (state->offset > state->wsize - (state->whave < state->wsize ?
+ left : 0)) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+
+ /* copy match from window to output */
+ do {
+ ROOM();
+ copy = state->wsize - state->offset;
+ if (copy < left) {
+ from = put + copy;
+ copy = left - copy;
+ }
+ else {
+ from = put - state->offset;
+ copy = left;
+ }
+ if (copy > state->length) copy = state->length;
+ state->length -= copy;
+ left -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ } while (state->length != 0);
+ break;
+
+ case DONE:
+ /* inflate stream terminated properly -- write leftover output */
+ ret = Z_STREAM_END;
+ if (left < state->wsize) {
+ if (out(out_desc, state->window, state->wsize - left))
+ ret = Z_BUF_ERROR;
+ }
+ goto inf_leave;
+
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+
+ default: /* can't happen, but makes compilers happy */
+ ret = Z_STREAM_ERROR;
+ goto inf_leave;
+ }
+
+ /* Return unused input */
+ inf_leave:
+ strm->next_in = next;
+ strm->avail_in = have;
+ return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_stream FAR *strm;
+{
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/inffast.c b/tqtinterface/qt4/src/3rdparty/zlib/inffast.c
new file mode 100644
index 0000000..8f0930a
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/inffast.c
@@ -0,0 +1,305 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+ Based on testing to date,
+ Pre-increment preferred for:
+ - PowerPC G3 (Adler)
+ - MIPS R5000 (Randers-Pehrson)
+ Post-increment preferred for:
+ - none
+ No measurable difference:
+ - Pentium III (Anderson)
+ - M68060 (Nikl)
+ */
+#ifdef POSTINC
+# define OFF 0
+# define PUP(a) *(a)++
+#else
+# define OFF 1
+# define PUP(a) *++(a)
+#endif
+
+/*
+ Decode literal, length, and distance codes and write out the resulting
+ literal and match bytes until either not enough input or output is
+ available, an end-of-block is encountered, or a data error is encountered.
+ When large enough input and output buffers are supplied to inflate(), for
+ example, a 16K input buffer and a 64K output buffer, more than 95% of the
+ inflate execution time is spent in this routine.
+
+ Entry assumptions:
+
+ state->mode == LEN
+ strm->avail_in >= 6
+ strm->avail_out >= 258
+ start >= strm->avail_out
+ state->bits < 8
+
+ On return, state->mode is one of:
+
+ LEN -- ran out of enough output space or enough available input
+ TYPE -- reached end of block code, inflate() to interpret next block
+ BAD -- error in block data
+
+ Notes:
+
+ - The maximum input bits used by a length/distance pair is 15 bits for the
+ length code, 5 bits for the length extra, 15 bits for the distance code,
+ and 13 bits for the distance extra. This totals 48 bits, or six bytes.
+ Therefore if strm->avail_in >= 6, then there is enough input to avoid
+ checking for available input while decoding.
+
+ - The maximum bytes that a single length/distance pair can output is 258
+ bytes, which is the maximum length that can be coded. inflate_fast()
+ requires strm->avail_out >= 258 for each loop to avoid checking for
+ output space.
+ */
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start; /* inflate()'s starting value for strm->avail_out */
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *in; /* local strm->next_in */
+ unsigned char FAR *last; /* while in < last, enough input available */
+ unsigned char FAR *out; /* local strm->next_out */
+ unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
+ unsigned char FAR *end; /* while out < end, enough space available */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned write; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
+ unsigned long hold; /* local strm->hold */
+ unsigned bits; /* local strm->bits */
+ code const FAR *lcode; /* local strm->lencode */
+ code const FAR *dcode; /* local strm->distcode */
+ unsigned ltqmask; /* tqmask for first level of length codes */
+ unsigned dtqmask; /* tqmask for first level of distance codes */
+ code this; /* retrieved table entry */
+ unsigned op; /* code bits, operation, extra bits, or */
+ /* window position, window bytes to copy */
+ unsigned len; /* match length, unused bytes */
+ unsigned dist; /* match distance */
+ unsigned char FAR *from; /* where to copy match from */
+
+ /* copy state to local variables */
+ state = (struct inflate_state FAR *)strm->state;
+ in = strm->next_in - OFF;
+ last = in + (strm->avail_in - 5);
+ out = strm->next_out - OFF;
+ beg = out - (start - strm->avail_out);
+ end = out + (strm->avail_out - 257);
+ wsize = state->wsize;
+ whave = state->whave;
+ write = state->write;
+ window = state->window;
+ hold = state->hold;
+ bits = state->bits;
+ lcode = state->lencode;
+ dcode = state->distcode;
+ ltqmask = (1U << state->lenbits) - 1;
+ dtqmask = (1U << state->distbits) - 1;
+
+ /* decode literals and length/distances until end-of-block or not enough
+ input data or output space */
+ do {
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ this = lcode[hold & ltqmask];
+ dolen:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op == 0) { /* literal */
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ PUP(out) = (unsigned char)(this.val);
+ }
+ else if (op & 16) { /* length base */
+ len = (unsigned)(this.val);
+ op &= 15; /* number of extra bits */
+ if (op) {
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ len += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ }
+ Tracevv((stderr, "inflate: length %u\n", len));
+ if (bits < 15) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ this = dcode[hold & dtqmask];
+ dodist:
+ op = (unsigned)(this.bits);
+ hold >>= op;
+ bits -= op;
+ op = (unsigned)(this.op);
+ if (op & 16) { /* distance base */
+ dist = (unsigned)(this.val);
+ op &= 15; /* number of extra bits */
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ if (bits < op) {
+ hold += (unsigned long)(PUP(in)) << bits;
+ bits += 8;
+ }
+ }
+ dist += (unsigned)hold & ((1U << op) - 1);
+ hold >>= op;
+ bits -= op;
+ Tracevv((stderr, "inflate: distance %u\n", dist));
+ op = (unsigned)(out - beg); /* max distance in output */
+ if (dist > op) { /* see if copy from window */
+ op = dist - op; /* distance back in window */
+ if (op > whave) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ from = window - OFF;
+ if (write == 0) { /* very common case */
+ from += wsize - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ else if (write < op) { /* wrap around window */
+ from += wsize + write - op;
+ op -= write;
+ if (op < len) { /* some from end of window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = window - OFF;
+ if (write < len) { /* some from start of window */
+ op = write;
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ }
+ else { /* contiguous in window */
+ from += write - op;
+ if (op < len) { /* some from window */
+ len -= op;
+ do {
+ PUP(out) = PUP(from);
+ } while (--op);
+ from = out - dist; /* rest from output */
+ }
+ }
+ while (len > 2) {
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ }
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ else {
+ from = out - dist; /* copy direct from output */
+ do { /* minimum length is three */
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ PUP(out) = PUP(from);
+ len -= 3;
+ } while (len > 2);
+ if (len) {
+ PUP(out) = PUP(from);
+ if (len > 1)
+ PUP(out) = PUP(from);
+ }
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level distance code */
+ this = dcode[this.val + (hold & ((1U << op) - 1))];
+ goto dodist;
+ }
+ else {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ }
+ else if ((op & 64) == 0) { /* 2nd level length code */
+ this = lcode[this.val + (hold & ((1U << op) - 1))];
+ goto dolen;
+ }
+ else if (op & 32) { /* end-of-block */
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ else {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ } while (in < last && out < end);
+
+ /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+ len = bits >> 3;
+ in -= len;
+ bits -= len << 3;
+ hold &= (1U << bits) - 1;
+
+ /* update state and return */
+ strm->next_in = in + OFF;
+ strm->next_out = out + OFF;
+ strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+ strm->avail_out = (unsigned)(out < end ?
+ 257 + (end - out) : 257 - (out - end));
+ state->hold = hold;
+ state->bits = bits;
+ return;
+}
+
+/*
+ inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+ - Using bit fields for code structure
+ - Different op definition to avoid & for extra bits (do & for table bits)
+ - Three separate decoding do-loops for direct, window, and write == 0
+ - Special case for distance > 1 copies to do overlapped load and store copy
+ - Explicit branch predictions (based on measured branch probabilities)
+ - Deferring match copy and interspersed it with decoding subsequent codes
+ - Swapping literal/length else
+ - Swapping window/direct else
+ - Larger unrolled copy loops (three is about right)
+ - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/inffast.h b/tqtinterface/qt4/src/3rdparty/zlib/inffast.h
new file mode 100644
index 0000000..1e88d2d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+void inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/inffixed.h b/tqtinterface/qt4/src/3rdparty/zlib/inffixed.h
new file mode 100644
index 0000000..75ed4b5
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/inffixed.h
@@ -0,0 +1,94 @@
+ /* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by makefixed().
+ */
+
+ /* WARNING: this file should *not* be used by applications. It
+ is part of the implementation of the compression library and
+ is subject to change. Applications should only use zlib.h.
+ */
+
+ static const code lenfix[512] = {
+ {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+ {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+ {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+ {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+ {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+ {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+ {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+ {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+ {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+ {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+ {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+ {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+ {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+ {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+ {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+ {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+ {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+ {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+ {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+ {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+ {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+ {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+ {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+ {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+ {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+ {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+ {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+ {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+ {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+ {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+ {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+ {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+ {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+ {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+ {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+ {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+ {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+ {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+ {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+ {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+ {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+ {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+ {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+ {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+ {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+ {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+ {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+ {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+ {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+ {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+ {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+ {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+ {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+ {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+ {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+ {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+ {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+ {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+ {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+ {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+ {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+ {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+ {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+ {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+ {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+ {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+ {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+ {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+ {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+ {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+ {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+ {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+ {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+ {0,9,255}
+ };
+
+ static const code distfix[32] = {
+ {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+ {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+ {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+ {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+ {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+ {22,5,193},{64,5,0}
+ };
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/inflate.c b/tqtinterface/qt4/src/3rdparty/zlib/inflate.c
new file mode 100644
index 0000000..09a5e1e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/inflate.c
@@ -0,0 +1,1274 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0 24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ * creation of window when not needed, minimize use of window when it is
+ * needed, make inffast.c even faster, implement gzip decoding, and to
+ * improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1 25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2 4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ * to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3 22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ * buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4 1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common write == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ * source file infback.c to provide a call-back interface to inflate for
+ * programs like gzip and unzip -- uses window as output buffer to avoid
+ * window copying
+ *
+ * 1.2.beta5 1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ * input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6 4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ * make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7 27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0 9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ * for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ * and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+# ifndef BUILDFIXED
+# define BUILDFIXED
+# endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, unsigned out));
+#ifdef BUILDFIXED
+ void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+ unsigned len));
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ strm->total_in = strm->total_out = state->total = 0;
+ strm->msg = Z_NULL;
+ strm->adler = 1; /* to support ill-conceived Java test suite */
+ state->mode = HEAD;
+ state->last = 0;
+ state->havedict = 0;
+ state->wsize = 0;
+ state->whave = 0;
+ state->hold = 0;
+ state->bits = 0;
+ state->lencode = state->distcode = state->next = state->codes;
+ Tracev((stderr, "inflate: reset\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+ struct inflate_state FAR *state;
+
+ if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+ stream_size != (int)(sizeof(z_stream)))
+ return Z_VERSION_ERROR;
+ if (strm == Z_NULL) return Z_STREAM_ERROR;
+ strm->msg = Z_NULL; /* in case we return an error */
+ if (strm->zalloc == (alloc_func)0) {
+ strm->zalloc = zcalloc;
+ strm->opaque = (voidpf)0;
+ }
+ if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+ state = (struct inflate_state FAR *)
+ ZALLOC(strm, 1, sizeof(struct inflate_state));
+ if (state == Z_NULL) return Z_MEM_ERROR;
+ Tracev((stderr, "inflate: allocated\n"));
+ strm->state = (voidpf)state;
+ if (windowBits < 0) {
+ state->wrap = 0;
+ windowBits = -windowBits;
+ }
+ else {
+ state->wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+ if (windowBits < 48) windowBits &= 15;
+#endif
+ }
+ if (windowBits < 8 || windowBits > 15) {
+ ZFREE(strm, state);
+ strm->state = Z_NULL;
+ return Z_STREAM_ERROR;
+ }
+ state->wbits = (unsigned)windowBits;
+ state->window = Z_NULL;
+ return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+ return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+/*
+ Return state with length and distance decoding tables and index sizes set to
+ fixed code decoding. Normally this returns fixed tables from inffixed.h.
+ If BUILDFIXED is defined, then instead this routine builds the tables the
+ first time it's called, and returns those tables the first time and
+ thereafter. This reduces the size of the code by about 2K bytes, in
+ exchange for a little execution time. However, BUILDFIXED should not be
+ used for threaded applications, since the rewriting of the tables and virgin
+ may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+ static int virgin = 1;
+ static code *lenfix, *distfix;
+ static code fixed[544];
+
+ /* build fixed huffman tables if first call (may not be thread safe) */
+ if (virgin) {
+ unsigned sym, bits;
+ static code *next;
+
+ /* literal/length table */
+ sym = 0;
+ while (sym < 144) state->lens[sym++] = 8;
+ while (sym < 256) state->lens[sym++] = 9;
+ while (sym < 280) state->lens[sym++] = 7;
+ while (sym < 288) state->lens[sym++] = 8;
+ next = fixed;
+ lenfix = next;
+ bits = 9;
+ inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+ /* distance table */
+ sym = 0;
+ while (sym < 32) state->lens[sym++] = 5;
+ distfix = next;
+ bits = 5;
+ inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+ /* do this just once */
+ virgin = 0;
+ }
+#else /* !BUILDFIXED */
+# include "inffixed.h"
+#endif /* BUILDFIXED */
+ state->lencode = lenfix;
+ state->lenbits = 9;
+ state->distcode = distfix;
+ state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+ Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
+ defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
+ those tables to stdout, which would be piped to inffixed.h. A small program
+ can simply call makefixed to do this:
+
+ void makefixed(void);
+
+ int main(void)
+ {
+ makefixed();
+ return 0;
+ }
+
+ Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+ a.out > inffixed.h
+ */
+void makefixed()
+{
+ unsigned low, size;
+ struct inflate_state state;
+
+ fixedtables(&state);
+ puts(" /* inffixed.h -- table for decoding fixed codes");
+ puts(" * Generated automatically by makefixed().");
+ puts(" */");
+ puts("");
+ puts(" /* WARNING: this file should *not* be used by applications.");
+ puts(" It is part of the implementation of this library and is");
+ puts(" subject to change. Applications should only use zlib.h.");
+ puts(" */");
+ puts("");
+ size = 1U << 9;
+ printf(" static const code lenfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 7) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
+ state.lencode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+ size = 1U << 5;
+ printf("\n static const code distfix[%u] = {", size);
+ low = 0;
+ for (;;) {
+ if ((low % 6) == 0) printf("\n ");
+ printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+ state.distcode[low].val);
+ if (++low == size) break;
+ putchar(',');
+ }
+ puts("\n };");
+}
+#endif /* MAKEFIXED */
+
+/*
+ Update the window with the last wsize (normally 32K) bytes written before
+ returning. If window does not exist yet, create it. This is only called
+ when a window is already in use, or when output has been written during this
+ inflate call, but the end of the deflate stream has not been reached yet.
+ It is also called to create a window for dictionary data when a dictionary
+ is loaded.
+
+ Providing output buffers larger than 32K to inflate() should provide a speed
+ advantage, since only the last 32K of output is copied to the sliding window
+ upon return from inflate(), and since all distances after the first 32K of
+ output will fall in the output data, making match copies simpler and faster.
+ The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, out)
+z_streamp strm;
+unsigned out;
+{
+ struct inflate_state FAR *state;
+ unsigned copy, dist;
+
+ state = (struct inflate_state FAR *)strm->state;
+
+ /* if it hasn't been done already, allocate space for the window */
+ if (state->window == Z_NULL) {
+ state->window = (unsigned char FAR *)
+ ZALLOC(strm, 1U << state->wbits,
+ sizeof(unsigned char));
+ if (state->window == Z_NULL) return 1;
+ }
+
+ /* if window not in use yet, initialize */
+ if (state->wsize == 0) {
+ state->wsize = 1U << state->wbits;
+ state->write = 0;
+ state->whave = 0;
+ }
+
+ /* copy state->wsize or less output bytes into the circular window */
+ copy = out - strm->avail_out;
+ if (copy >= state->wsize) {
+ zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+ state->write = 0;
+ state->whave = state->wsize;
+ }
+ else {
+ dist = state->wsize - state->write;
+ if (dist > copy) dist = copy;
+ zmemcpy(state->window + state->write, strm->next_out - copy, dist);
+ copy -= dist;
+ if (copy) {
+ zmemcpy(state->window, strm->next_out - copy, copy);
+ state->write = copy;
+ state->whave = state->wsize;
+ }
+ else {
+ state->write += dist;
+ if (state->write == state->wsize) state->write = 0;
+ if (state->whave < state->wsize) state->whave += dist;
+ }
+ }
+ return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+# define UPDATE(check, buf, len) \
+ (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+# define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+# define CRC2(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ check = crc32(check, hbuf, 2); \
+ } while (0)
+
+# define CRC4(check, word) \
+ do { \
+ hbuf[0] = (unsigned char)(word); \
+ hbuf[1] = (unsigned char)((word) >> 8); \
+ hbuf[2] = (unsigned char)((word) >> 16); \
+ hbuf[3] = (unsigned char)((word) >> 24); \
+ check = crc32(check, hbuf, 4); \
+ } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+ do { \
+ put = strm->next_out; \
+ left = strm->avail_out; \
+ next = strm->next_in; \
+ have = strm->avail_in; \
+ hold = state->hold; \
+ bits = state->bits; \
+ } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+ do { \
+ strm->next_out = put; \
+ strm->avail_out = left; \
+ strm->next_in = next; \
+ strm->avail_in = have; \
+ state->hold = hold; \
+ state->bits = bits; \
+ } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+ do { \
+ hold = 0; \
+ bits = 0; \
+ } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+ if there is no input available. */
+#define PULLBYTE() \
+ do { \
+ if (have == 0) goto inf_leave; \
+ have--; \
+ hold += (unsigned long)(*next++) << bits; \
+ bits += 8; \
+ } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator. If there is
+ not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+ do { \
+ while (bits < (unsigned)(n)) \
+ PULLBYTE(); \
+ } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+ ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+ do { \
+ hold >>= (n); \
+ bits -= (unsigned)(n); \
+ } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+ do { \
+ hold >>= bits & 7; \
+ bits -= bits & 7; \
+ } while (0)
+
+/* Reverse the bytes in a 32-bit value */
+#define REVERSE(q) \
+ ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+ (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+/*
+ inflate() uses a state machine to process as much input data and generate as
+ much output data as possible before returning. The state machine is
+ structured roughly as follows:
+
+ for (;;) switch (state) {
+ ...
+ case STATEn:
+ if (not enough input data or output space to make progress)
+ return;
+ ... make progress ...
+ state = STATEm;
+ break;
+ ...
+ }
+
+ so when inflate() is called again, the same case is attempted again, and
+ if the appropriate resources are provided, the machine proceeds to the
+ next state. The NEEDBITS() macro is usually the way the state evaluates
+ whether it can proceed or should return. NEEDBITS() does the return if
+ the requested bits are not available. The typical use of the BITS macros
+ is:
+
+ NEEDBITS(n);
+ ... do something with BITS(n) ...
+ DROPBITS(n);
+
+ where NEEDBITS(n) either returns from inflate() if there isn't enough
+ input left to load n bits into the accumulator, or it continues. BITS(n)
+ gives the low n bits in the accumulator. When done, DROPBITS(n) drops
+ the low n bits off the accumulator. INITBITS() clears the accumulator
+ and sets the number of available bits to zero. BYTEBITS() discards just
+ enough bits to put the accumulator on a byte boundary. After BYTEBITS()
+ and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+ NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+ if there is no input available. The decoding of variable length codes uses
+ PULLBYTE() directly in order to pull just enough bytes to decode the next
+ code, and no more.
+
+ Some states loop until they get enough input, making sure that enough
+ state information is maintained to continue the loop where it left off
+ if NEEDBITS() returns in the loop. For example, want, need, and keep
+ would all have to actually be part of the saved state in case NEEDBITS()
+ returns:
+
+ case STATEw:
+ while (want < need) {
+ NEEDBITS(n);
+ keep[want++] = BITS(n);
+ DROPBITS(n);
+ }
+ state = STATEx;
+ case STATEx:
+
+ As shown above, if the next state is also the next case, then the break
+ is omitted.
+
+ A state may also return if there is not enough output space available to
+ complete that state. Those states are copying stored data, writing a
+ literal byte, and copying a matching string.
+
+ When returning, a "goto inf_leave" is used to update the total counters,
+ update the check value, and determine whether any progress has been made
+ during that inflate() call in order to return the proper return code.
+ Progress is defined as a change in either strm->avail_in or strm->avail_out.
+ When there is a window, goto inf_leave will update the window with the last
+ output written. If a goto inf_leave occurs in the middle of decompression
+ and there is no window currently, goto inf_leave will create one and copy
+ output to the window for the next call of inflate().
+
+ In this implementation, the flush parameter of inflate() only affects the
+ return code (per zlib.h). inflate() always writes as much as possible to
+ strm->next_out, given the space available and the provided input--the effect
+ documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
+ the allocation of and copying into a sliding window until necessary, which
+ provides the effect documented in zlib.h for Z_FINISH when the entire input
+ stream available. So the only thing the flush parameter actually does is:
+ when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
+ will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+ struct inflate_state FAR *state;
+ unsigned char FAR *next; /* next input */
+ unsigned char FAR *put; /* next output */
+ unsigned have, left; /* available input and output */
+ unsigned long hold; /* bit buffer */
+ unsigned bits; /* bits in bit buffer */
+ unsigned in, out; /* save starting available input and output */
+ unsigned copy; /* number of stored or match bytes to copy */
+ unsigned char FAR *from; /* where to copy match bytes from */
+ code this; /* current decoding table entry */
+ code last; /* tqparent table entry */
+ unsigned len; /* length to copy for repeats, bits to drop */
+ int ret; /* return code */
+#ifdef GUNZIP
+ unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
+#endif
+ static const unsigned short order[19] = /* permutation of code lengths */
+ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+ (strm->next_in == Z_NULL && strm->avail_in != 0))
+ return Z_STREAM_ERROR;
+
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
+ LOAD();
+ in = have;
+ out = left;
+ ret = Z_OK;
+ for (;;)
+ switch (state->mode) {
+ case HEAD:
+ if (state->wrap == 0) {
+ state->mode = TYPEDO;
+ break;
+ }
+ NEEDBITS(16);
+#ifdef GUNZIP
+ if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
+ state->check = crc32(0L, Z_NULL, 0);
+ CRC2(state->check, hold);
+ INITBITS();
+ state->mode = FLAGS;
+ break;
+ }
+ state->flags = 0; /* expect zlib header */
+ if (!(state->wrap & 1) || /* check if zlib header allowed */
+#else
+ if (
+#endif
+ ((BITS(8) << 8) + (hold >> 8)) % 31) {
+ strm->msg = (char *)"incorrect header check";
+ state->mode = BAD;
+ break;
+ }
+ if (BITS(4) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ DROPBITS(4);
+ if (BITS(4) + 8 > state->wbits) {
+ strm->msg = (char *)"invalid window size";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: zlib header ok\n"));
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = hold & 0x200 ? DICTID : TYPE;
+ INITBITS();
+ break;
+#ifdef GUNZIP
+ case FLAGS:
+ NEEDBITS(16);
+ state->flags = (int)(hold);
+ if ((state->flags & 0xff) != Z_DEFLATED) {
+ strm->msg = (char *)"unknown compression method";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0xe000) {
+ strm->msg = (char *)"unknown header flags set";
+ state->mode = BAD;
+ break;
+ }
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = TIME;
+ case TIME:
+ NEEDBITS(32);
+ if (state->flags & 0x0200) CRC4(state->check, hold);
+ INITBITS();
+ state->mode = OS;
+ case OS:
+ NEEDBITS(16);
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ state->mode = EXLEN;
+ case EXLEN:
+ if (state->flags & 0x0400) {
+ NEEDBITS(16);
+ state->length = (unsigned)(hold);
+ if (state->flags & 0x0200) CRC2(state->check, hold);
+ INITBITS();
+ }
+ state->mode = EXTRA;
+ case EXTRA:
+ if (state->flags & 0x0400) {
+ copy = state->length;
+ if (copy > have) copy = have;
+ if (copy) {
+ if (state->flags & 0x0200)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ state->length -= copy;
+ }
+ if (state->length) goto inf_leave;
+ }
+ state->mode = NAME;
+ case NAME:
+ if (state->flags & 0x0800) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ } while (len && copy < have);
+ if (state->flags & 0x02000)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ state->mode = COMMENT;
+ case COMMENT:
+ if (state->flags & 0x1000) {
+ if (have == 0) goto inf_leave;
+ copy = 0;
+ do {
+ len = (unsigned)(next[copy++]);
+ } while (len && copy < have);
+ if (state->flags & 0x02000)
+ state->check = crc32(state->check, next, copy);
+ have -= copy;
+ next += copy;
+ if (len) goto inf_leave;
+ }
+ state->mode = HCRC;
+ case HCRC:
+ if (state->flags & 0x0200) {
+ NEEDBITS(16);
+ if (hold != (state->check & 0xffff)) {
+ strm->msg = (char *)"header crc mismatch";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ }
+ strm->adler = state->check = crc32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ break;
+#endif
+ case DICTID:
+ NEEDBITS(32);
+ strm->adler = state->check = REVERSE(hold);
+ INITBITS();
+ state->mode = DICT;
+ case DICT:
+ if (state->havedict == 0) {
+ RESTORE();
+ return Z_NEED_DICT;
+ }
+ strm->adler = state->check = adler32(0L, Z_NULL, 0);
+ state->mode = TYPE;
+ case TYPE:
+ if (flush == Z_BLOCK) goto inf_leave;
+ case TYPEDO:
+ if (state->last) {
+ BYTEBITS();
+ state->mode = CHECK;
+ break;
+ }
+ NEEDBITS(3);
+ state->last = BITS(1);
+ DROPBITS(1);
+ switch (BITS(2)) {
+ case 0: /* stored block */
+ Tracev((stderr, "inflate: stored block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = STORED;
+ break;
+ case 1: /* fixed block */
+ fixedtables(state);
+ Tracev((stderr, "inflate: fixed codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = LEN; /* decode codes */
+ break;
+ case 2: /* dynamic block */
+ Tracev((stderr, "inflate: dynamic codes block%s\n",
+ state->last ? " (last)" : ""));
+ state->mode = TABLE;
+ break;
+ case 3:
+ strm->msg = (char *)"invalid block type";
+ state->mode = BAD;
+ }
+ DROPBITS(2);
+ break;
+ case STORED:
+ BYTEBITS(); /* go to byte boundary */
+ NEEDBITS(32);
+ if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+ strm->msg = (char *)"invalid stored block lengths";
+ state->mode = BAD;
+ break;
+ }
+ state->length = (unsigned)hold & 0xffff;
+ Tracev((stderr, "inflate: stored length %u\n",
+ state->length));
+ INITBITS();
+ state->mode = COPY;
+ case COPY:
+ copy = state->length;
+ if (copy) {
+ if (copy > have) copy = have;
+ if (copy > left) copy = left;
+ if (copy == 0) goto inf_leave;
+ zmemcpy(put, next, copy);
+ have -= copy;
+ next += copy;
+ left -= copy;
+ put += copy;
+ state->length -= copy;
+ break;
+ }
+ Tracev((stderr, "inflate: stored end\n"));
+ state->mode = TYPE;
+ break;
+ case TABLE:
+ NEEDBITS(14);
+ state->nlen = BITS(5) + 257;
+ DROPBITS(5);
+ state->ndist = BITS(5) + 1;
+ DROPBITS(5);
+ state->ncode = BITS(4) + 4;
+ DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+ if (state->nlen > 286 || state->ndist > 30) {
+ strm->msg = (char *)"too many length or distance symbols";
+ state->mode = BAD;
+ break;
+ }
+#endif
+ Tracev((stderr, "inflate: table sizes ok\n"));
+ state->have = 0;
+ state->mode = LENLENS;
+ case LENLENS:
+ while (state->have < state->ncode) {
+ NEEDBITS(3);
+ state->lens[order[state->have++]] = (unsigned short)BITS(3);
+ DROPBITS(3);
+ }
+ while (state->have < 19)
+ state->lens[order[state->have++]] = 0;
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 7;
+ ret = inflate_table(CODES, state->lens, 19, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid code lengths set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: code lengths ok\n"));
+ state->have = 0;
+ state->mode = CODELENS;
+ case CODELENS:
+ while (state->have < state->nlen + state->ndist) {
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.val < 16) {
+ NEEDBITS(this.bits);
+ DROPBITS(this.bits);
+ state->lens[state->have++] = this.val;
+ }
+ else {
+ if (this.val == 16) {
+ NEEDBITS(this.bits + 2);
+ DROPBITS(this.bits);
+ if (state->have == 0) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ len = state->lens[state->have - 1];
+ copy = 3 + BITS(2);
+ DROPBITS(2);
+ }
+ else if (this.val == 17) {
+ NEEDBITS(this.bits + 3);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 3 + BITS(3);
+ DROPBITS(3);
+ }
+ else {
+ NEEDBITS(this.bits + 7);
+ DROPBITS(this.bits);
+ len = 0;
+ copy = 11 + BITS(7);
+ DROPBITS(7);
+ }
+ if (state->have + copy > state->nlen + state->ndist) {
+ strm->msg = (char *)"invalid bit length repeat";
+ state->mode = BAD;
+ break;
+ }
+ while (copy--)
+ state->lens[state->have++] = (unsigned short)len;
+ }
+ }
+
+ /* handle error breaks in while */
+ if (state->mode == BAD) break;
+
+ /* build code tables */
+ state->next = state->codes;
+ state->lencode = (code const FAR *)(state->next);
+ state->lenbits = 9;
+ ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+ &(state->lenbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid literal/lengths set";
+ state->mode = BAD;
+ break;
+ }
+ state->distcode = (code const FAR *)(state->next);
+ state->distbits = 6;
+ ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+ &(state->next), &(state->distbits), state->work);
+ if (ret) {
+ strm->msg = (char *)"invalid distances set";
+ state->mode = BAD;
+ break;
+ }
+ Tracev((stderr, "inflate: codes ok\n"));
+ state->mode = LEN;
+ case LEN:
+ if (have >= 6 && left >= 258) {
+ RESTORE();
+ inflate_fast(strm, out);
+ LOAD();
+ break;
+ }
+ for (;;) {
+ this = state->lencode[BITS(state->lenbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if (this.op && (this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->lencode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ state->length = (unsigned)this.val;
+ if ((int)(this.op) == 0) {
+ Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
+ "inflate: literal '%c'\n" :
+ "inflate: literal 0x%02x\n", this.val));
+ state->mode = LIT;
+ break;
+ }
+ if (this.op & 32) {
+ Tracevv((stderr, "inflate: end of block\n"));
+ state->mode = TYPE;
+ break;
+ }
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid literal/length code";
+ state->mode = BAD;
+ break;
+ }
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = LENEXT;
+ case LENEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->length += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ Tracevv((stderr, "inflate: length %u\n", state->length));
+ state->mode = DIST;
+ case DIST:
+ for (;;) {
+ this = state->distcode[BITS(state->distbits)];
+ if ((unsigned)(this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ if ((this.op & 0xf0) == 0) {
+ last = this;
+ for (;;) {
+ this = state->distcode[last.val +
+ (BITS(last.bits + last.op) >> last.bits)];
+ if ((unsigned)(last.bits + this.bits) <= bits) break;
+ PULLBYTE();
+ }
+ DROPBITS(last.bits);
+ }
+ DROPBITS(this.bits);
+ if (this.op & 64) {
+ strm->msg = (char *)"invalid distance code";
+ state->mode = BAD;
+ break;
+ }
+ state->offset = (unsigned)this.val;
+ state->extra = (unsigned)(this.op) & 15;
+ state->mode = DISTEXT;
+ case DISTEXT:
+ if (state->extra) {
+ NEEDBITS(state->extra);
+ state->offset += BITS(state->extra);
+ DROPBITS(state->extra);
+ }
+ if (state->offset > state->whave + out - left) {
+ strm->msg = (char *)"invalid distance too far back";
+ state->mode = BAD;
+ break;
+ }
+ Tracevv((stderr, "inflate: distance %u\n", state->offset));
+ state->mode = MATCH;
+ case MATCH:
+ if (left == 0) goto inf_leave;
+ copy = out - left;
+ if (state->offset > copy) { /* copy from window */
+ copy = state->offset - copy;
+ if (copy > state->write) {
+ copy -= state->write;
+ from = state->window + (state->wsize - copy);
+ }
+ else
+ from = state->window + (state->write - copy);
+ if (copy > state->length) copy = state->length;
+ }
+ else { /* copy from output */
+ from = put - state->offset;
+ copy = state->length;
+ }
+ if (copy > left) copy = left;
+ left -= copy;
+ state->length -= copy;
+ do {
+ *put++ = *from++;
+ } while (--copy);
+ if (state->length == 0) state->mode = LEN;
+ break;
+ case LIT:
+ if (left == 0) goto inf_leave;
+ *put++ = (unsigned char)(state->length);
+ left--;
+ state->mode = LEN;
+ break;
+ case CHECK:
+ if (state->wrap) {
+ NEEDBITS(32);
+ out -= left;
+ strm->total_out += out;
+ state->total += out;
+ if (out)
+ strm->adler = state->check =
+ UPDATE(state->check, put - out, out);
+ out = left;
+ if ((
+#ifdef GUNZIP
+ state->flags ? hold :
+#endif
+ REVERSE(hold)) != state->check) {
+ strm->msg = (char *)"incorrect data check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: check matches trailer\n"));
+ }
+#ifdef GUNZIP
+ state->mode = LENGTH;
+ case LENGTH:
+ if (state->wrap && state->flags) {
+ NEEDBITS(32);
+ if (hold != (state->total & 0xffffffffUL)) {
+ strm->msg = (char *)"incorrect length check";
+ state->mode = BAD;
+ break;
+ }
+ INITBITS();
+ Tracev((stderr, "inflate: length matches trailer\n"));
+ }
+#endif
+ state->mode = DONE;
+ case DONE:
+ ret = Z_STREAM_END;
+ goto inf_leave;
+ case BAD:
+ ret = Z_DATA_ERROR;
+ goto inf_leave;
+ case MEM:
+ return Z_MEM_ERROR;
+ case SYNC:
+ default:
+ return Z_STREAM_ERROR;
+ }
+
+ /*
+ Return from inflate(), updating the total counts and the check value.
+ If there was no progress during the inflate() call, return a buffer
+ error. Call updatewindow() to create and/or update the window state.
+ Note: a memory error from inflate() is non-recoverable.
+ */
+ inf_leave:
+ RESTORE();
+ if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
+ if (updatewindow(strm, out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ in -= strm->avail_in;
+ out -= strm->avail_out;
+ strm->total_in += in;
+ strm->total_out += out;
+ state->total += out;
+ if (state->wrap && out)
+ strm->adler = state->check =
+ UPDATE(state->check, strm->next_out - out, out);
+ strm->data_type = state->bits + (state->last ? 64 : 0) +
+ (state->mode == TYPE ? 128 : 0);
+ if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+ ret = Z_BUF_ERROR;
+ return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+ if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->window != Z_NULL) ZFREE(strm, state->window);
+ ZFREE(strm, strm->state);
+ strm->state = Z_NULL;
+ Tracev((stderr, "inflate: end\n"));
+ return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+ struct inflate_state FAR *state;
+ unsigned long id;
+
+ /* check state */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (state->mode != DICT) return Z_STREAM_ERROR;
+
+ /* check for correct dictionary id */
+ id = adler32(0L, Z_NULL, 0);
+ id = adler32(id, dictionary, dictLength);
+ if (id != state->check) return Z_DATA_ERROR;
+
+ /* copy dictionary to window */
+ if (updatewindow(strm, strm->avail_out)) {
+ state->mode = MEM;
+ return Z_MEM_ERROR;
+ }
+ if (dictLength > state->wsize) {
+ zmemcpy(state->window, dictionary + dictLength - state->wsize,
+ state->wsize);
+ state->whave = state->wsize;
+ }
+ else {
+ zmemcpy(state->window + state->wsize - dictLength, dictionary,
+ dictLength);
+ state->whave = dictLength;
+ }
+ state->havedict = 1;
+ Tracev((stderr, "inflate: dictionary set\n"));
+ return Z_OK;
+}
+
+/*
+ Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
+ or when out of input. When called, *have is the number of pattern bytes
+ found in order so far, in 0..3. On return *have is updated to the new
+ state. If on return *have equals four, then the pattern was found and the
+ return value is how many bytes were read including the last byte of the
+ pattern. If *have is less than four, then the pattern has not been found
+ yet and the return value is len. In the latter case, syncsearch() can be
+ called again with more data and the *have state. *have is initialized to
+ zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+unsigned char FAR *buf;
+unsigned len;
+{
+ unsigned got;
+ unsigned next;
+
+ got = *have;
+ next = 0;
+ while (next < len && got < 4) {
+ if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+ got++;
+ else if (buf[next])
+ got = 0;
+ else
+ got = 4 - got;
+ next++;
+ }
+ *have = got;
+ return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+ unsigned len; /* number of bytes to look at or looked at */
+ unsigned long in, out; /* temporary to save total_in and total_out */
+ unsigned char buf[4]; /* to restore bit buffer to byte string */
+ struct inflate_state FAR *state;
+
+ /* check parameters */
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+ /* if first time, start search in bit buffer */
+ if (state->mode != SYNC) {
+ state->mode = SYNC;
+ state->hold <<= state->bits & 7;
+ state->bits -= state->bits & 7;
+ len = 0;
+ while (state->bits >= 8) {
+ buf[len++] = (unsigned char)(state->hold);
+ state->hold >>= 8;
+ state->bits -= 8;
+ }
+ state->have = 0;
+ syncsearch(&(state->have), buf, len);
+ }
+
+ /* search available input */
+ len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+ strm->avail_in -= len;
+ strm->next_in += len;
+ strm->total_in += len;
+
+ /* return no joy or set up to restart inflate() on a new block */
+ if (state->have != 4) return Z_DATA_ERROR;
+ in = strm->total_in; out = strm->total_out;
+ inflateReset(strm);
+ strm->total_in = in; strm->total_out = out;
+ state->mode = TYPE;
+ return Z_OK;
+}
+
+/*
+ Returns true if inflate is currently at the end of a block generated by
+ Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ implementation to provide an additional safety check. PPP uses
+ Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+ block. When decompressing, PPP checks that at the end of input packet,
+ inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+ struct inflate_state FAR *state;
+
+ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)strm->state;
+ return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+ struct inflate_state FAR *state;
+ struct inflate_state FAR *copy;
+ unsigned char FAR *window;
+
+ /* check input */
+ if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+ source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+ return Z_STREAM_ERROR;
+ state = (struct inflate_state FAR *)source->state;
+
+ /* allocate space */
+ copy = (struct inflate_state FAR *)
+ ZALLOC(source, 1, sizeof(struct inflate_state));
+ if (copy == Z_NULL) return Z_MEM_ERROR;
+ window = Z_NULL;
+ if (state->window != Z_NULL) {
+ window = (unsigned char FAR *)
+ ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+ if (window == Z_NULL) {
+ ZFREE(source, copy);
+ return Z_MEM_ERROR;
+ }
+ }
+
+ /* copy state */
+ *dest = *source;
+ *copy = *state;
+ copy->lencode = copy->codes + (state->lencode - state->codes);
+ copy->distcode = copy->codes + (state->distcode - state->codes);
+ copy->next = copy->codes + (state->next - state->codes);
+ if (window != Z_NULL)
+ zmemcpy(window, state->window, 1U << state->wbits);
+ copy->window = window;
+ dest->state = (voidpf)copy;
+ return Z_OK;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/inflate.h b/tqtinterface/qt4/src/3rdparty/zlib/inflate.h
new file mode 100644
index 0000000..9a12c8f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/inflate.h
@@ -0,0 +1,117 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+ trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
+ the crc code when it is not needed. For shared libraries, gzip decoding
+ should be left enabled. */
+#ifndef NO_GZIP
+# define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+ HEAD, /* i: waiting for magic header */
+#ifdef GUNZIP
+ FLAGS, /* i: waiting for method and flags (gzip) */
+ TIME, /* i: waiting for modification time (gzip) */
+ OS, /* i: waiting for extra flags and operating system (gzip) */
+ EXLEN, /* i: waiting for extra length (gzip) */
+ EXTRA, /* i: waiting for extra bytes (gzip) */
+ NAME, /* i: waiting for end of file name (gzip) */
+ COMMENT, /* i: waiting for end of comment (gzip) */
+ HCRC, /* i: waiting for header crc (gzip) */
+#endif
+ DICTID, /* i: waiting for dictionary check value */
+ DICT, /* waiting for inflateSetDictionary() call */
+ TYPE, /* i: waiting for type bits, including last-flag bit */
+ TYPEDO, /* i: same, but skip check to exit inflate on new block */
+ STORED, /* i: waiting for stored size (length and complement) */
+ COPY, /* i/o: waiting for input or output to copy stored block */
+ TABLE, /* i: waiting for dynamic block table lengths */
+ LENLENS, /* i: waiting for code length code lengths */
+ CODELENS, /* i: waiting for length/lit and distance code lengths */
+ LEN, /* i: waiting for length/lit code */
+ LENEXT, /* i: waiting for length extra bits */
+ DIST, /* i: waiting for distance code */
+ DISTEXT, /* i: waiting for distance extra bits */
+ MATCH, /* o: waiting for output space to copy string */
+ LIT, /* o: waiting for output space to write literal */
+ CHECK, /* i: waiting for 32-bit check value */
+#ifdef GUNZIP
+ LENGTH, /* i: waiting for 32-bit length (gzip) */
+#endif
+ DONE, /* finished check, done -- remain here until reset */
+ BAD, /* got a data error -- remain here until reset */
+ MEM, /* got an inflate() memory error -- remain here until reset */
+ SYNC /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+ State transitions between above modes -
+
+ (most modes can go to the BAD or MEM mode -- not shown for clarity)
+
+ Process header:
+ HEAD -> (gzip) or (zlib)
+ (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
+ NAME -> COMMENT -> HCRC -> TYPE
+ (zlib) -> DICTID or TYPE
+ DICTID -> DICT -> TYPE
+ Read deflate blocks:
+ TYPE -> STORED or TABLE or LEN or CHECK
+ STORED -> COPY -> TYPE
+ TABLE -> LENLENS -> CODELENS -> LEN
+ Read deflate codes:
+ LEN -> LENEXT or LIT or TYPE
+ LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+ LIT -> LEN
+ Process trailer:
+ CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls. Approximately 7K bytes. */
+struct inflate_state {
+ inflate_mode mode; /* current inflate mode */
+ int last; /* true if processing last block */
+ int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
+ int havedict; /* true if dictionary provided */
+ int flags; /* gzip header method and flags (0 if zlib) */
+ unsigned long check; /* protected copy of check value */
+ unsigned long total; /* protected copy of output count */
+ /* sliding window */
+ unsigned wbits; /* log base 2 of requested window size */
+ unsigned wsize; /* window size or zero if not using window */
+ unsigned whave; /* valid bytes in the window */
+ unsigned write; /* window write index */
+ unsigned char FAR *window; /* allocated sliding window, if needed */
+ /* bit accumulator */
+ unsigned long hold; /* input bit accumulator */
+ unsigned bits; /* number of bits in "in" */
+ /* for string and stored block copying */
+ unsigned length; /* literal or length of data to copy */
+ unsigned offset; /* distance back to copy string from */
+ /* for table and code decoding */
+ unsigned extra; /* extra bits needed */
+ /* fixed and dynamic code tables */
+ code const FAR *lencode; /* starting table for length/literal codes */
+ code const FAR *distcode; /* starting table for distance codes */
+ unsigned lenbits; /* index bits for lencode */
+ unsigned distbits; /* index bits for distcode */
+ /* dynamic table building */
+ unsigned ncode; /* number of code length code lengths */
+ unsigned nlen; /* number of length code lengths */
+ unsigned ndist; /* number of distance code lengths */
+ unsigned have; /* number of code lengths in lens[] */
+ code FAR *next; /* next available space in codes[] */
+ unsigned short lens[320]; /* temporary storage for code lengths */
+ unsigned short work[288]; /* work area for code table building */
+ code codes[ENOUGH]; /* space for code tables */
+};
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/inftrees.c b/tqtinterface/qt4/src/3rdparty/zlib/inftrees.c
new file mode 100644
index 0000000..760ef10
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/inftrees.c
@@ -0,0 +1,328 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2004 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+ " inflate 1.2.2 Copyright 1995-2004 Mark Adler ";
+/*
+ If you use the zlib library in a product, an acknowledgment is welcome
+ in the documentation of your product. If for some reason you cannot
+ include such an acknowledgment, I would appreciate that you keep this
+ copyright string in the executable of your product.
+ */
+
+/*
+ Build a set of tables to decode the provided canonical Huffman code.
+ The code lengths are lens[0..codes-1]. The result starts at *table,
+ whose indices are 0..2^bits-1. work is a writable array of at least
+ lens shorts, which is used as a work area. type is the type of code
+ to be generated, CODES, LENS, or DISTS. On return, zero is success,
+ -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
+ on return points to the next available entry's address. bits is the
+ requested root table index bits, and on return it is the actual root
+ table index bits. It will differ if the request is greater than the
+ longest code or if it is less than the shortest code.
+ */
+int inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+ unsigned len; /* a code's length in bits */
+ unsigned sym; /* index of code symbols */
+ unsigned min, max; /* minimum and maximum code lengths */
+ unsigned root; /* number of index bits for root table */
+ unsigned curr; /* number of index bits for current table */
+ unsigned drop; /* code bits to drop for sub-table */
+ int left; /* number of prefix codes available */
+ unsigned used; /* code entries in table used */
+ unsigned huff; /* Huffman code */
+ unsigned incr; /* for incrementing code, index */
+ unsigned fill; /* index for replicating entries */
+ unsigned low; /* low bits for current root entry */
+ unsigned tqmask; /* tqmask for low root bits */
+ code this; /* table entry for duplication */
+ code FAR *next; /* next available space in table */
+ const unsigned short FAR *base; /* base value table to use */
+ const unsigned short FAR *extra; /* extra bits table to use */
+ int end; /* use base and extra for symbol > end */
+ unsigned short count[MAXBITS+1]; /* number of codes of each length */
+ unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
+ static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+ 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+ 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 199, 198};
+ static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577, 0, 0};
+ static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+ 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+ 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+ 28, 28, 29, 29, 64, 64};
+
+ /*
+ Process a set of code lengths to create a canonical Huffman code. The
+ code lengths are lens[0..codes-1]. Each length corresponds to the
+ symbols 0..codes-1. The Huffman code is generated by first sorting the
+ symbols by length from short to long, and retaining the symbol order
+ for codes with equal lengths. Then the code starts with all zero bits
+ for the first code of the shortest length, and the codes are integer
+ increments for the same length, and zeros are appended as the length
+ increases. For the deflate format, these bits are stored backwards
+ from their more natural integer increment ordering, and so when the
+ decoding tables are built in the large loop below, the integer codes
+ are incremented backwards.
+
+ This routine assumes, but does not check, that all of the entries in
+ lens[] are in the range 0..MAXBITS. The caller must assure this.
+ 1..MAXBITS is interpreted as that code length. zero means that that
+ symbol does not occur in this code.
+
+ The codes are sorted by computing a count of codes for each length,
+ creating from that a table of starting indices for each length in the
+ sorted table, and then entering the symbols in order in the sorted
+ table. The sorted table is work[], with that space being provided by
+ the caller.
+
+ The length counts are used for other purposes as well, i.e. tqfinding
+ the minimum and maximum length codes, determining if there are any
+ codes at all, checking for a valid set of lengths, and looking ahead
+ at length counts to determine sub-table sizes when building the
+ decoding tables.
+ */
+
+ /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+ for (len = 0; len <= MAXBITS; len++)
+ count[len] = 0;
+ for (sym = 0; sym < codes; sym++)
+ count[lens[sym]]++;
+
+ /* bound code lengths, force root to be within code lengths */
+ root = *bits;
+ for (max = MAXBITS; max >= 1; max--)
+ if (count[max] != 0) break;
+ if (root > max) root = max;
+ if (max == 0) { /* no symbols to code at all */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)1;
+ this.val = (unsigned short)0;
+ *(*table)++ = this; /* make a table to force an error */
+ *(*table)++ = this;
+ *bits = 1;
+ return 0; /* no symbols, but wait for decoding to report error */
+ }
+ for (min = 1; min <= MAXBITS; min++)
+ if (count[min] != 0) break;
+ if (root < min) root = min;
+
+ /* check for an over-subscribed or incomplete set of lengths */
+ left = 1;
+ for (len = 1; len <= MAXBITS; len++) {
+ left <<= 1;
+ left -= count[len];
+ if (left < 0) return -1; /* over-subscribed */
+ }
+ if (left > 0 && (type == CODES || max != 1))
+ return -1; /* incomplete set */
+
+ /* generate offsets into symbol table for each length for sorting */
+ offs[1] = 0;
+ for (len = 1; len < MAXBITS; len++)
+ offs[len + 1] = offs[len] + count[len];
+
+ /* sort symbols by length, by symbol order within each length */
+ for (sym = 0; sym < codes; sym++)
+ if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+ /*
+ Create and fill in decoding tables. In this loop, the table being
+ filled is at next and has curr index bits. The code being used is huff
+ with length len. That code is converted to an index by dropping drop
+ bits off of the bottom. For codes where len is less than drop + curr,
+ those top drop + curr - len bits are incremented through all values to
+ fill the table with replicated entries.
+
+ root is the number of index bits for the root table. When len exceeds
+ root, sub-tables are created pointed to by the root entry with an index
+ of the low root bits of huff. This is saved in low to check for when a
+ new sub-table should be started. drop is zero when the root table is
+ being filled, and drop is root when sub-tables are being filled.
+
+ When a new sub-table is needed, it is necessary to look ahead in the
+ code lengths to determine what size sub-table is needed. The length
+ counts are used for this, and so count[] is decremented as codes are
+ entered in the tables.
+
+ used keeps track of how many table entries have been allocated from the
+ provided *table space. It is checked when a LENS table is being made
+ against the space in *table, ENOUGH, minus the maximum space needed by
+ the worst case distance code, MAXD. This should never happen, but the
+ sufficiency of ENOUGH has not been proven exhaustively, hence the check.
+ This assumes that when type == LENS, bits == 9.
+
+ sym increments through all symbols, and the loop terminates when
+ all codes of length max, i.e. all codes, have been processed. This
+ routine permits incomplete codes, so another loop after this one fills
+ in the rest of the decoding tables with invalid code markers.
+ */
+
+ /* set up for code type */
+ switch (type) {
+ case CODES:
+ base = extra = work; /* dummy value--not used */
+ end = 19;
+ break;
+ case LENS:
+ base = lbase;
+ base -= 257;
+ extra = lext;
+ extra -= 257;
+ end = 256;
+ break;
+ default: /* DISTS */
+ base = dbase;
+ extra = dext;
+ end = -1;
+ }
+
+ /* initialize state for loop */
+ huff = 0; /* starting code */
+ sym = 0; /* starting code symbol */
+ len = min; /* starting code length */
+ next = *table; /* current table to fill in */
+ curr = root; /* current table index bits */
+ drop = 0; /* current bits to drop from code for index */
+ low = (unsigned)(-1); /* trigger new sub-table when len > root */
+ used = 1U << root; /* use root table entries */
+ tqmask = used - 1; /* tqmask for comparing low */
+
+ /* check available table space */
+ if (type == LENS && used >= ENOUGH - MAXD)
+ return 1;
+
+ /* process all codes and make table entries */
+ for (;;) {
+ /* create table entry */
+ this.bits = (unsigned char)(len - drop);
+ if ((int)(work[sym]) < end) {
+ this.op = (unsigned char)0;
+ this.val = work[sym];
+ }
+ else if ((int)(work[sym]) > end) {
+ this.op = (unsigned char)(extra[work[sym]]);
+ this.val = base[work[sym]];
+ }
+ else {
+ this.op = (unsigned char)(32 + 64); /* end of block */
+ this.val = 0;
+ }
+
+ /* replicate for those indices with low len bits equal to huff */
+ incr = 1U << (len - drop);
+ fill = 1U << curr;
+ do {
+ fill -= incr;
+ next[(huff >> drop) + fill] = this;
+ } while (fill != 0);
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+
+ /* go to next symbol, update count, len */
+ sym++;
+ if (--(count[len]) == 0) {
+ if (len == max) break;
+ len = lens[work[sym]];
+ }
+
+ /* create new sub-table if needed */
+ if (len > root && (huff & tqmask) != low) {
+ /* if first time, transition to sub-tables */
+ if (drop == 0)
+ drop = root;
+
+ /* increment past last table */
+ next += 1U << curr;
+
+ /* determine length of next table */
+ curr = len - drop;
+ left = (int)(1 << curr);
+ while (curr + drop < max) {
+ left -= count[curr + drop];
+ if (left <= 0) break;
+ curr++;
+ left <<= 1;
+ }
+
+ /* check for enough space */
+ used += 1U << curr;
+ if (type == LENS && used >= ENOUGH - MAXD)
+ return 1;
+
+ /* point entry in root table to sub-table */
+ low = huff & tqmask;
+ (*table)[low].op = (unsigned char)curr;
+ (*table)[low].bits = (unsigned char)root;
+ (*table)[low].val = (unsigned short)(next - *table);
+ }
+ }
+
+ /*
+ Fill in rest of table for incomplete codes. This loop is similar to the
+ loop above in incrementing huff for table indices. It is assumed that
+ len is equal to curr + drop, so there is no loop needed to increment
+ through high index bits. When the current sub-table is filled, the loop
+ drops back to the root table to fill in any remaining entries there.
+ */
+ this.op = (unsigned char)64; /* invalid code marker */
+ this.bits = (unsigned char)(len - drop);
+ this.val = (unsigned short)0;
+ while (huff != 0) {
+ /* when done with sub-table, drop back to root table */
+ if (drop != 0 && (huff & tqmask) != low) {
+ drop = 0;
+ len = root;
+ next = *table;
+ this.bits = (unsigned char)len;
+ }
+
+ /* put invalid code marker in table */
+ next[huff >> drop] = this;
+
+ /* backwards increment the len-bit code huff */
+ incr = 1U << (len - 1);
+ while (huff & incr)
+ incr >>= 1;
+ if (incr != 0) {
+ huff &= incr - 1;
+ huff += incr;
+ }
+ else
+ huff = 0;
+ }
+
+ /* set return parameters */
+ *table += used;
+ *bits = root;
+ return 0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/inftrees.h b/tqtinterface/qt4/src/3rdparty/zlib/inftrees.h
new file mode 100644
index 0000000..424af17
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/inftrees.h
@@ -0,0 +1,55 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables. Each entry provides either the
+ information needed to do the operation requested by the code that
+ indexed that table entry, or it provides a pointer to another
+ table that indexes more bits of the code. op indicates whether
+ the entry is a pointer to another table, a literal, a length or
+ distance, an end-of-block, or an invalid code. For a table
+ pointer, the low four bits of op is the number of index bits of
+ that table. For a length or distance, the low four bits of op
+ is the number of extra bits to get after the code. bits is
+ the number of bits in this code or part of the code to drop off
+ of the bit buffer. val is the actual byte to output in the case
+ of a literal, the base length or distance, or the offset from
+ the current table to the next table. Each entry is four bytes. */
+typedef struct {
+ unsigned char op; /* operation, extra bits, table bits */
+ unsigned char bits; /* bits in this part of the code */
+ unsigned short val; /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+ 00000000 - literal
+ 0000tttt - table link, tttt != 0 is the number of table index bits
+ 0001eeee - length or distance, eeee is the number of extra bits
+ 01100000 - end of block
+ 01000000 - invalid code
+ */
+
+/* Maximum size of dynamic tree. The maximum found in a long but non-
+ exhaustive search was 1444 code structures (852 for length/literals
+ and 592 for distances, the latter actually the result of an
+ exhaustive search). The true maximum is not known, but the value
+ below is more than safe. */
+#define ENOUGH 2048
+#define MAXD 592
+
+/* Type of code to build for inftable() */
+typedef enum {
+ CODES,
+ LENS,
+ DISTS
+} codetype;
+
+extern int inflate_table OF((codetype type, unsigned short FAR *lens,
+ unsigned codes, code FAR * FAR *table,
+ unsigned FAR *bits, unsigned short FAR *work));
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/minigzip.c b/tqtinterface/qt4/src/3rdparty/zlib/minigzip.c
new file mode 100644
index 0000000..a21f0cb
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/minigzip.c
@@ -0,0 +1,322 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to tqreplace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $Id$ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+# include <string.h>
+# include <stdlib.h>
+#else
+ extern void exit OF((int));
+#endif
+
+#ifdef USE_MMAP
+# include <sys/types.h>
+# include <sys/mman.h>
+# include <sys/stat.h>
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+# include <fcntl.h>
+# include <io.h>
+# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+# define SET_BINARY_MODE(file)
+#endif
+
+#ifdef VMS
+# define unlink delete
+# define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+# define unlink remove
+# define GZ_SUFFIX "-gz"
+# define fileno(file) file->__file
+#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fileno */
+#endif
+
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+ extern int unlink OF((const char *));
+#endif
+
+#ifndef GZ_SUFFIX
+# define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN 16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+# define local static
+ /* Needed for systems with limitation on stack size. */
+#else
+# define local
+#endif
+
+char *prog;
+
+void error OF((const char *msg));
+void gz_compress OF((FILE *in, gzFile out));
+#ifdef USE_MMAP
+int gz_compress_mmap OF((FILE *in, gzFile out));
+#endif
+void gz_uncompress OF((gzFile in, FILE *out));
+void file_compress OF((char *file, char *mode));
+void file_uncompress OF((char *file));
+int main OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+ const char *msg;
+{
+ fprintf(stderr, "%s: %s\n", prog, msg);
+ exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+ FILE *in;
+ gzFile out;
+{
+ local char buf[BUFLEN];
+ int len;
+ int err;
+
+#ifdef USE_MMAP
+ /* Try first compressing with mmap. If mmap fails (minigzip used in a
+ * pipe), use the normal fread loop.
+ */
+ if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+ for (;;) {
+ len = (int)fread(buf, 1, sizeof(buf), in);
+ if (ferror(in)) {
+ perror("fread");
+ exit(1);
+ }
+ if (len == 0) break;
+
+ if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+ }
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+ FILE *in;
+ gzFile out;
+{
+ int len;
+ int err;
+ int ifd = fileno(in);
+ caddr_t buf; /* mmap'ed buffer for the entire input file */
+ off_t buf_len; /* length of the input file */
+ struct stat sb;
+
+ /* Determine the size of the file, needed for mmap: */
+ if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+ buf_len = sb.st_size;
+ if (buf_len <= 0) return Z_ERRNO;
+
+ /* Now do the actual mmap: */
+ buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+ if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+ /* Compress the whole file at once: */
+ len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+ if (len != (int)buf_len) error(gzerror(out, &err));
+
+ munmap(buf, buf_len);
+ fclose(in);
+ if (gzclose(out) != Z_OK) error("failed gzclose");
+ return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+ gzFile in;
+ FILE *out;
+{
+ local char buf[BUFLEN];
+ int len;
+ int err;
+
+ for (;;) {
+ len = gzread(in, buf, sizeof(buf));
+ if (len < 0) error (gzerror(in, &err));
+ if (len == 0) break;
+
+ if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+ error("failed fwrite");
+ }
+ }
+ if (fclose(out)) error("failed fclose");
+
+ if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+ char *file;
+ char *mode;
+{
+ local char outfile[MAX_NAME_LEN];
+ FILE *in;
+ gzFile out;
+
+ strcpy(outfile, file);
+ strcat(outfile, GZ_SUFFIX);
+
+ in = fopen(file, "rb");
+ if (in == NULL) {
+ perror(file);
+ exit(1);
+ }
+ out = gzopen(outfile, mode);
+ if (out == NULL) {
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+ exit(1);
+ }
+ gz_compress(in, out);
+
+ unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+ char *file;
+{
+ local char buf[MAX_NAME_LEN];
+ char *infile, *outfile;
+ FILE *out;
+ gzFile in;
+ uInt len = (uInt)strlen(file);
+
+ strcpy(buf, file);
+
+ if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+ infile = file;
+ outfile = buf;
+ outfile[len-3] = '\0';
+ } else {
+ outfile = file;
+ infile = buf;
+ strcat(infile, GZ_SUFFIX);
+ }
+ in = gzopen(infile, "rb");
+ if (in == NULL) {
+ fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+ exit(1);
+ }
+ out = fopen(outfile, "wb");
+ if (out == NULL) {
+ perror(file);
+ exit(1);
+ }
+
+ gz_uncompress(in, out);
+
+ unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...]
+ * -d : decompress
+ * -f : compress with Z_FILTERED
+ * -h : compress with Z_HUFFMAN_ONLY
+ * -r : compress with Z_RLE
+ * -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int uncompr = 0;
+ gzFile file;
+ char outmode[20];
+
+ strcpy(outmode, "wb6 ");
+
+ prog = argv[0];
+ argc--, argv++;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "-d") == 0)
+ uncompr = 1;
+ else if (strcmp(*argv, "-f") == 0)
+ outmode[3] = 'f';
+ else if (strcmp(*argv, "-h") == 0)
+ outmode[3] = 'h';
+ else if (strcmp(*argv, "-r") == 0)
+ outmode[3] = 'R';
+ else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+ (*argv)[2] == 0)
+ outmode[2] = (*argv)[1];
+ else
+ break;
+ argc--, argv++;
+ }
+ if (argc == 0) {
+ SET_BINARY_MODE(stdin);
+ SET_BINARY_MODE(stdout);
+ if (uncompr) {
+ file = gzdopen(fileno(stdin), "rb");
+ if (file == NULL) error("can't gzdopen stdin");
+ gz_uncompress(file, stdout);
+ } else {
+ file = gzdopen(fileno(stdout), outmode);
+ if (file == NULL) error("can't gzdopen stdout");
+ gz_compress(stdin, file);
+ }
+ } else {
+ do {
+ if (uncompr) {
+ file_uncompress(*argv);
+ } else {
+ file_compress(*argv, outmode);
+ }
+ } while (argv++, --argc);
+ }
+ return 0;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/projects/README.projects b/tqtinterface/qt4/src/3rdparty/zlib/projects/README.projects
new file mode 100644
index 0000000..e9baf2e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/projects/README.projects
@@ -0,0 +1,38 @@
+This directory tqcontains project files for building zlib under various
+Integrated Development Environments (IDE).
+
+If you wish to submit a new project to this directory, you should comply
+to the following requirements. Otherwise (e.g. if you wish to integrate
+a custom piece of code that changes the zlib interface or its behavior),
+please consider submitting the project to the contrib directory.
+
+
+Requirements
+============
+
+- The project must build zlib using exclusively the source files from
+ the official zlib distribution.
+
+- If there are "official" makefiles in the zlib distribution, the builds
+ given by the makefiles must be compatible with the builds given by the
+ project. These builds are called "official" builds.
+
+- It is possible to add non-official pieces of code to the project,
+ if the resulting build remains compatible with an official build.
+ For example, it is possible to add an "ASM build" target besides
+ the regular target, by including ASM source files from the contrib
+ directory.
+
+- If there are significant differences between the project files created
+ by different versions of an IDE (e.g. Visual C++ 6.0 vs. 7.0), the name
+ of the project directory should contain the version number of the IDE
+ for which the project is intended (e.g. "visualc6" for Visual C++ 6.0,
+ or "visualc7" for Visual C++ 7.0 and 7.1).
+
+
+Current projects
+================
+
+visualc6/ by Simon-Pierre Cadieux <methodex@methodex.ca>
+ and Cosmin Truta <cosmint@cs.ubbcluj.ro>
+ Project for Microsoft Visual C++ 6.0
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/README.txt b/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/README.txt
new file mode 100644
index 0000000..c79ae9f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/README.txt
@@ -0,0 +1,38 @@
+Microsoft Developer Studio Project Files, Format Version 6.00 for zlib.
+
+Copyright (C) 2000-2004 Simon-Pierre Cadieux.
+Copyright (C) 2004 Cosmin Truta.
+For conditions of distribution and use, see copyright notice in zlib.h.
+
+
+To use:
+
+1) On the main menu, select "File | Open Workspace".
+ Open "zlib.dsw".
+
+2) Select "Build | Set Active Configuration".
+ Choose the configuration you wish to build.
+
+3) Select "Build | Clean".
+
+4) Select "Build | Build ... (F7)". Ignore warning messages about
+ not being able to tqfind certain include files (e.g. alloc.h).
+
+5) If you built one of the sample programs (example or minigzip),
+ select "Build | Execute ... (Ctrl+F5)".
+
+
+This project builds the zlib binaries as follows:
+
+* Win32_DLL_Release\zlib1.dll DLL build
+* Win32_DLL_Debug\zlib1d.dll DLL build (debug version)
+* Win32_DLL_ASM_Release\zlib1.dll DLL build using ASM code
+* Win32_DLL_ASM_Debug\zlib1d.dll DLL build using ASM code (debug version)
+* Win32_LIB_Release\zlib.lib static build
+* Win32_LIB_Debug\zlibd.lib static build (debug version)
+* Win32_LIB_ASM_Release\zlib.lib static build using ASM code
+* Win32_LIB_ASM_Debug\zlibd.lib static build using ASM code (debug version)
+
+
+For more information regarding the DLL builds, please see the DLL FAQ
+in ..\..\win32\DLL_FAQ.txt.
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/example.dsp b/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/example.dsp
new file mode 100644
index 0000000..308a82c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/example.dsp
@@ -0,0 +1,278 @@
+# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=example - Win32 LIB Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "example.mak" CFG="example - Win32 LIB Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "example - Win32 DLL Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "example - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "example - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "example - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "example - Win32 LIB Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "example - Win32 LIB Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "example - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "example - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "example - Win32 DLL Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "example___Win32_DLL_Release"
+# PROP BASE Intermediate_Dir "example___Win32_DLL_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_DLL_Release"
+# PROP Intermediate_Dir "Win32_DLL_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 zlib1.lib /nologo /subsystem:console /machine:I386 /libpath:"Win32_DLL_Release"
+
+!ELSEIF "$(CFG)" == "example - Win32 DLL Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "example___Win32_DLL_Debug"
+# PROP BASE Intermediate_Dir "example___Win32_DLL_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_DLL_Debug"
+# PROP Intermediate_Dir "Win32_DLL_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 zlib1d.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"Win32_DLL_Debug"
+
+!ELSEIF "$(CFG)" == "example - Win32 DLL ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "example___Win32_DLL_ASM_Release"
+# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_DLL_ASM_Release"
+# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 zlib1.lib /nologo /subsystem:console /machine:I386 /libpath:"Win32_DLL_ASM_Release"
+
+!ELSEIF "$(CFG)" == "example - Win32 DLL ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "example___Win32_DLL_ASM_Debug"
+# PROP BASE Intermediate_Dir "example___Win32_DLL_ASM_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_DLL_ASM_Debug"
+# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 zlib1d.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"Win32_DLL_ASM_Debug"
+
+!ELSEIF "$(CFG)" == "example - Win32 LIB Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "example___Win32_LIB_Release"
+# PROP BASE Intermediate_Dir "example___Win32_LIB_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_LIB_Release"
+# PROP Intermediate_Dir "Win32_LIB_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 zlib.lib /nologo /subsystem:console /machine:I386 /libpath:"Win32_LIB_Release"
+
+!ELSEIF "$(CFG)" == "example - Win32 LIB Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "example___Win32_LIB_Debug"
+# PROP BASE Intermediate_Dir "example___Win32_LIB_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_LIB_Debug"
+# PROP Intermediate_Dir "Win32_LIB_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 zlibd.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"Win32_LIB_Debug"
+
+!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "example___Win32_LIB_ASM_Release"
+# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_LIB_ASM_Release"
+# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 zlib.lib /nologo /subsystem:console /machine:I386 /libpath:"Win32_LIB_ASM_Release"
+
+!ELSEIF "$(CFG)" == "example - Win32 LIB ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "example___Win32_LIB_ASM_Debug"
+# PROP BASE Intermediate_Dir "example___Win32_LIB_ASM_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_LIB_ASM_Debug"
+# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 zlibd.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"Win32_LIB_ASM_Debug"
+
+!ENDIF
+
+# Begin Target
+
+# Name "example - Win32 DLL Release"
+# Name "example - Win32 DLL Debug"
+# Name "example - Win32 DLL ASM Release"
+# Name "example - Win32 DLL ASM Debug"
+# Name "example - Win32 LIB Release"
+# Name "example - Win32 LIB Debug"
+# Name "example - Win32 LIB ASM Release"
+# Name "example - Win32 LIB ASM Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\example.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\zconf.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zlib.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/minigzip.dsp b/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/minigzip.dsp
new file mode 100644
index 0000000..91d981d
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/minigzip.dsp
@@ -0,0 +1,278 @@
+# Microsoft Developer Studio Project File - Name="minigzip" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=minigzip - Win32 LIB Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "minigzip.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "minigzip.mak" CFG="minigzip - Win32 LIB Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "minigzip - Win32 DLL Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "minigzip - Win32 DLL Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "minigzip - Win32 DLL ASM Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "minigzip - Win32 DLL ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "minigzip - Win32 LIB Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "minigzip - Win32 LIB Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE "minigzip - Win32 LIB ASM Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "minigzip - Win32 LIB ASM Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "minigzip - Win32 DLL Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "minigzip___Win32_DLL_Release"
+# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_DLL_Release"
+# PROP Intermediate_Dir "Win32_DLL_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 zlib1.lib /nologo /subsystem:console /machine:I386 /libpath:"Win32_DLL_Release"
+
+!ELSEIF "$(CFG)" == "minigzip - Win32 DLL Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "minigzip___Win32_DLL_Debug"
+# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_DLL_Debug"
+# PROP Intermediate_Dir "Win32_DLL_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 zlib1d.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"Win32_DLL_Debug"
+
+!ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Release"
+# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_DLL_ASM_Release"
+# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 zlib1.lib /nologo /subsystem:console /machine:I386 /libpath:"Win32_DLL_ASM_Release"
+
+!ELSEIF "$(CFG)" == "minigzip - Win32 DLL ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "minigzip___Win32_DLL_ASM_Debug"
+# PROP BASE Intermediate_Dir "minigzip___Win32_DLL_ASM_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_DLL_ASM_Debug"
+# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 zlib1d.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"Win32_DLL_ASM_Debug"
+
+!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "minigzip___Win32_LIB_Release"
+# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_LIB_Release"
+# PROP Intermediate_Dir "Win32_LIB_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 zlib.lib /nologo /subsystem:console /machine:I386 /libpath:"Win32_LIB_Release"
+
+!ELSEIF "$(CFG)" == "minigzip - Win32 LIB Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "minigzip___Win32_LIB_Debug"
+# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_LIB_Debug"
+# PROP Intermediate_Dir "Win32_LIB_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 zlibd.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"Win32_LIB_Debug"
+
+!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Release"
+# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_LIB_ASM_Release"
+# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 zlib.lib /nologo /subsystem:console /machine:I386 /libpath:"Win32_LIB_ASM_Release"
+
+!ELSEIF "$(CFG)" == "minigzip - Win32 LIB ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "minigzip___Win32_LIB_ASM_Debug"
+# PROP BASE Intermediate_Dir "minigzip___Win32_LIB_ASM_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_LIB_ASM_Debug"
+# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT CPP /YX
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 zlibd.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"Win32_LIB_ASM_Debug"
+
+!ENDIF
+
+# Begin Target
+
+# Name "minigzip - Win32 DLL Release"
+# Name "minigzip - Win32 DLL Debug"
+# Name "minigzip - Win32 DLL ASM Release"
+# Name "minigzip - Win32 DLL ASM Debug"
+# Name "minigzip - Win32 LIB Release"
+# Name "minigzip - Win32 LIB Debug"
+# Name "minigzip - Win32 LIB ASM Release"
+# Name "minigzip - Win32 LIB ASM Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\minigzip.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\zconf.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zlib.h
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/zlib.dsp b/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/zlib.dsp
new file mode 100644
index 0000000..8f16513
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/zlib.dsp
@@ -0,0 +1,609 @@
+# Microsoft Developer Studio Project File - Name="zlib" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+# TARGTYPE "Win32 (x86) Static Library" 0x0104
+
+CFG=zlib - Win32 LIB Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "zlib.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "zlib.mak" CFG="zlib - Win32 LIB Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "zlib - Win32 DLL Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlib - Win32 DLL Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlib - Win32 DLL ASM Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlib - Win32 DLL ASM Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "zlib - Win32 LIB Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "zlib - Win32 LIB Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE "zlib - Win32 LIB ASM Release" (based on "Win32 (x86) Static Library")
+!MESSAGE "zlib - Win32 LIB ASM Debug" (based on "Win32 (x86) Static Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+
+!IF "$(CFG)" == "zlib - Win32 DLL Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlib___Win32_DLL_Release"
+# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_DLL_Release"
+# PROP Intermediate_Dir "Win32_DLL_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX /Yc /Yu
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT CPP /YX /Yc /Yu
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_Release\zlib1.dll"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zlib___Win32_DLL_Debug"
+# PROP BASE Intermediate_Dir "zlib___Win32_DLL_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_DLL_Debug"
+# PROP Intermediate_Dir "Win32_DLL_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX /Yc /Yu
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT CPP /YX /Yc /Yu
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_Debug\zlib1d.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Release"
+# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_DLL_ASM_Release"
+# PROP Intermediate_Dir "Win32_DLL_ASM_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX /Yc /Yu
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c
+# SUBTRACT CPP /YX /Yc /Yu
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
+# ADD LINK32 /nologo /dll /machine:I386 /out:"Win32_DLL_ASM_Release\zlib1.dll"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zlib___Win32_DLL_ASM_Debug"
+# PROP BASE Intermediate_Dir "zlib___Win32_DLL_ASM_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_DLL_ASM_Debug"
+# PROP Intermediate_Dir "Win32_DLL_ASM_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX /Yc /Yu
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FD /GZ /c
+# SUBTRACT CPP /YX /Yc /Yu
+MTL=midl.exe
+# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Win32_DLL_ASM_Debug\zlib1d.dll" /pdbtype:sept
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlib___Win32_LIB_Release"
+# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_LIB_Release"
+# PROP Intermediate_Dir "Win32_LIB_Release"
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX /Yc /Yu
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT CPP /YX /Yc /Yu
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zlib___Win32_LIB_Debug"
+# PROP BASE Intermediate_Dir "zlib___Win32_LIB_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_LIB_Debug"
+# PROP Intermediate_Dir "Win32_LIB_Debug"
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX /Yc /Yu
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT CPP /YX /Yc /Yu
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"Win32_LIB_Debug\zlibd.lib"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Release"
+# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Win32_LIB_ASM_Release"
+# PROP Intermediate_Dir "Win32_LIB_ASM_Release"
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /FD /c
+# SUBTRACT BASE CPP /YX /Yc /Yu
+# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "ASMV" /D "ASMINF" /FD /c
+# SUBTRACT CPP /YX /Yc /Yu
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "zlib___Win32_LIB_ASM_Debug"
+# PROP BASE Intermediate_Dir "zlib___Win32_LIB_ASM_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Win32_LIB_ASM_Debug"
+# PROP Intermediate_Dir "Win32_LIB_ASM_Debug"
+# PROP Target_Dir ""
+CPP=cl.exe
+# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /FD /GZ /c
+# SUBTRACT BASE CPP /YX /Yc /Yu
+# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "ASMV" /D "ASMINF" /FD /GZ /c
+# SUBTRACT CPP /YX /Yc /Yu
+RSC=rc.exe
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LIB32=link.exe -lib
+# ADD BASE LIB32 /nologo
+# ADD LIB32 /nologo /out:"Win32_LIB_ASM_Debug\zlibd.lib"
+
+!ENDIF
+
+# Begin Target
+
+# Name "zlib - Win32 DLL Release"
+# Name "zlib - Win32 DLL Debug"
+# Name "zlib - Win32 DLL ASM Release"
+# Name "zlib - Win32 DLL ASM Debug"
+# Name "zlib - Win32 LIB Release"
+# Name "zlib - Win32 LIB Debug"
+# Name "zlib - Win32 LIB ASM Release"
+# Name "zlib - Win32 LIB ASM Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=..\..\adler32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\compress.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\crc32.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\deflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\gzio.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\infback.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\inffast.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\inflate.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\inftrees.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\trees.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\uncompr.c
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\win32\zlib.def
+
+!IF "$(CFG)" == "zlib - Win32 DLL Release"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
+
+# PROP Exclude_From_Build 1
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zutil.c
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=..\..\crc32.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\deflate.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\inffast.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\inffixed.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\inflate.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\inftrees.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\trees.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zconf.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zlib.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\zutil.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=..\..\win32\zlib1.rc
+# End Source File
+# End Group
+# Begin Group "Assembler Files (Unsupported)"
+
+# PROP Default_Filter "asm;obj;c;cpp;cxx;h;hpp;hxx"
+# Begin Source File
+
+SOURCE=..\..\contrib\masmx86\gvmat32.asm
+
+!IF "$(CFG)" == "zlib - Win32 DLL Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\Win32_DLL_ASM_Release
+InputPath=..\..\contrib\masmx86\gvmat32.asm
+InputName=gvmat32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\Win32_DLL_ASM_Debug
+InputPath=..\..\contrib\masmx86\gvmat32.asm
+InputName=gvmat32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\Win32_LIB_ASM_Release
+InputPath=..\..\contrib\masmx86\gvmat32.asm
+InputName=gvmat32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\Win32_LIB_ASM_Debug
+InputPath=..\..\contrib\masmx86\gvmat32.asm
+InputName=gvmat32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\contrib\masmx86\gvmat32c.c
+
+!IF "$(CFG)" == "zlib - Win32 DLL Release"
+
+# PROP Exclude_From_Build 1
+# ADD CPP /I "..\.."
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
+
+# PROP Exclude_From_Build 1
+# ADD CPP /I "..\.."
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
+
+# ADD CPP /I "..\.."
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
+
+# ADD CPP /I "..\.."
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
+
+# PROP Exclude_From_Build 1
+# ADD CPP /I "..\.."
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+# ADD CPP /I "..\.."
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
+
+# ADD CPP /I "..\.."
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
+
+# ADD CPP /I "..\.."
+
+!ENDIF
+
+# End Source File
+# Begin Source File
+
+SOURCE=..\..\contrib\masmx86\inffas32.asm
+
+!IF "$(CFG)" == "zlib - Win32 DLL Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\Win32_DLL_ASM_Release
+InputPath=..\..\contrib\masmx86\inffas32.asm
+InputName=inffas32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zlib - Win32 DLL ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\Win32_DLL_ASM_Debug
+InputPath=..\..\contrib\masmx86\inffas32.asm
+InputName=inffas32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Release"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB Debug"
+
+# PROP Exclude_From_Build 1
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Release"
+
+# Begin Custom Build - Assembling...
+IntDir=.\Win32_LIB_ASM_Release
+InputPath=..\..\contrib\masmx86\inffas32.asm
+InputName=inffas32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ELSEIF "$(CFG)" == "zlib - Win32 LIB ASM Debug"
+
+# Begin Custom Build - Assembling...
+IntDir=.\Win32_LIB_ASM_Debug
+InputPath=..\..\contrib\masmx86\inffas32.asm
+InputName=inffas32
+
+"$(IntDir)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
+ ml /nologo /c /Cx /coff /Zi /Fo"$(IntDir)\$(InputName).obj" "$(InputPath)"
+
+# End Custom Build
+
+!ENDIF
+
+# End Source File
+# End Group
+# Begin Source File
+
+SOURCE=.\README.txt
+# End Source File
+# End Target
+# End Project
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/zlib.dsw b/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/zlib.dsw
new file mode 100644
index 0000000..3a771fc
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/projects/visualc6/zlib.dsw
@@ -0,0 +1,59 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "example"=.\example.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "minigzip"=.\minigzip.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+ Begin Project Dependency
+ Project_Dep_Name zlib
+ End Project Dependency
+}}}
+
+###############################################################################
+
+Project: "zlib"=.\zlib.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/trees.c b/tqtinterface/qt4/src/3rdparty/zlib/trees.c
new file mode 100644
index 0000000..6a2e55b
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/trees.c
@@ -0,0 +1,1215 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2003 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * ALGORITHM
+ *
+ * The "deflation" process uses several Huffman trees. The more
+ * common source values are represented by shorter bit sequences.
+ *
+ * Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values). The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ * REFERENCES
+ *
+ * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ * Storer, James A.
+ * Data Compression: Methods and Theory, pp. 49-50.
+ * Computer Science Press, 1988. ISBN 0-7167-8156-5.
+ *
+ * Sedgewick, R.
+ * Algorithms, p290.
+ * Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+# include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6 16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10 17
+/* repeat a zero length 3-10 times (3 bits of repeat count) */
+
+#define REPZ_11_138 18
+/* repeat a zero length 11-138 times (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+ = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+ = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+ = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+ = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+# include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+ const ct_data *static_tree; /* static tree or NULL */
+ const intf *extra_bits; /* extra bits for each code or NULL */
+ int extra_base; /* base index for extra_bits */
+ int elems; /* max number of elements in the tree */
+ int max_length; /* max bit length for the codes */
+};
+
+local static_tree_desc static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc static_d_desc =
+{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
+
+local static_tree_desc static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block OF((deflate_state *s));
+local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
+local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree OF((deflate_state *s, tree_desc *desc));
+local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
+local int build_bl_tree OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+ int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+ ct_data *dtree));
+local void set_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup OF((deflate_state *s));
+local void bi_flush OF((deflate_state *s));
+local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
+ int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+ /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+# define send_code(s, c, tree) \
+ { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+ send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+ put_byte(s, (uch)((w) & 0xff)); \
+ put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+ deflate_state *s;
+ int value; /* value to send */
+ int length; /* number of bits */
+{
+ Tracevv((stderr," l %2d v %4x ", length, value));
+ Assert(length > 0 && length <= 15, "invalid length");
+ s->bits_sent += (ulg)length;
+
+ /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+ * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+ * unused bits in value.
+ */
+ if (s->bi_valid > (int)Buf_size - length) {
+ s->bi_buf |= (value << s->bi_valid);
+ put_short(s, s->bi_buf);
+ s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+ s->bi_valid += length - Buf_size;
+ } else {
+ s->bi_buf |= value << s->bi_valid;
+ s->bi_valid += length;
+ }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+ if (s->bi_valid > (int)Buf_size - len) {\
+ int val = value;\
+ s->bi_buf |= (val << s->bi_valid);\
+ put_short(s, s->bi_buf);\
+ s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+ s->bi_valid += len - Buf_size;\
+ } else {\
+ s->bi_buf |= (value) << s->bi_valid;\
+ s->bi_valid += len;\
+ }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+ static int static_init_done = 0;
+ int n; /* iterates over tree elements */
+ int bits; /* bit counter */
+ int length; /* length value */
+ int code; /* code value */
+ int dist; /* distance index */
+ ush bl_count[MAX_BITS+1];
+ /* number of codes at each bit length for an optimal tree */
+
+ if (static_init_done) return;
+
+ /* For some embedded targets, global variables are not initialized: */
+ static_l_desc.static_tree = static_ltree;
+ static_l_desc.extra_bits = extra_lbits;
+ static_d_desc.static_tree = static_dtree;
+ static_d_desc.extra_bits = extra_dbits;
+ static_bl_desc.extra_bits = extra_blbits;
+
+ /* Initialize the mapping length (0..255) -> length code (0..28) */
+ length = 0;
+ for (code = 0; code < LENGTH_CODES-1; code++) {
+ base_length[code] = length;
+ for (n = 0; n < (1<<extra_lbits[code]); n++) {
+ _length_code[length++] = (uch)code;
+ }
+ }
+ Assert (length == 256, "tr_static_init: length != 256");
+ /* Note that the length 255 (match length 258) can be represented
+ * in two different ways: code 284 + 5 bits or code 285, so we
+ * overwrite length_code[255] to use the best encoding:
+ */
+ _length_code[length-1] = (uch)code;
+
+ /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+ dist = 0;
+ for (code = 0 ; code < 16; code++) {
+ base_dist[code] = dist;
+ for (n = 0; n < (1<<extra_dbits[code]); n++) {
+ _dist_code[dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: dist != 256");
+ dist >>= 7; /* from now on, all distances are divided by 128 */
+ for ( ; code < D_CODES; code++) {
+ base_dist[code] = dist << 7;
+ for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+ _dist_code[256 + dist++] = (uch)code;
+ }
+ }
+ Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+ /* Construct the codes of the static literal tree */
+ for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+ n = 0;
+ while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+ while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+ while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+ while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+ /* Codes 286 and 287 do not exist, but we must include them in the
+ * tree construction to get a canonical Huffman tree (longest code
+ * all ones)
+ */
+ gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+ /* The static distance tree is trivial: */
+ for (n = 0; n < D_CODES; n++) {
+ static_dtree[n].Len = 5;
+ static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+ }
+ static_init_done = 1;
+
+# ifdef GEN_TREES_H
+ gen_trees_header();
+# endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+# ifndef DEBUG
+# include <stdio.h>
+# endif
+
+# define SEPARATOR(i, last, width) \
+ ((i) == (last)? "\n};\n\n" : \
+ ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+ FILE *header = fopen("trees.h", "w");
+ int i;
+
+ Assert (header != NULL, "Can't open trees.h");
+ fprintf(header,
+ "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+ fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+ for (i = 0; i < L_CODES+2; i++) {
+ fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+ static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+ }
+
+ fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+ static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+ }
+
+ fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+ for (i = 0; i < DIST_CODE_LEN; i++) {
+ fprintf(header, "%2u%s", _dist_code[i],
+ SEPARATOR(i, DIST_CODE_LEN-1, 20));
+ }
+
+ fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+ for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+ fprintf(header, "%2u%s", _length_code[i],
+ SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+ }
+
+ fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+ for (i = 0; i < LENGTH_CODES; i++) {
+ fprintf(header, "%1u%s", base_length[i],
+ SEPARATOR(i, LENGTH_CODES-1, 20));
+ }
+
+ fprintf(header, "local const int base_dist[D_CODES] = {\n");
+ for (i = 0; i < D_CODES; i++) {
+ fprintf(header, "%5u%s", base_dist[i],
+ SEPARATOR(i, D_CODES-1, 10));
+ }
+
+ fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+ deflate_state *s;
+{
+ tr_static_init();
+
+ s->l_desc.dyn_tree = s->dyn_ltree;
+ s->l_desc.stat_desc = &static_l_desc;
+
+ s->d_desc.dyn_tree = s->dyn_dtree;
+ s->d_desc.stat_desc = &static_d_desc;
+
+ s->bl_desc.dyn_tree = s->bl_tree;
+ s->bl_desc.stat_desc = &static_bl_desc;
+
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+ s->compressed_len = 0L;
+ s->bits_sent = 0L;
+#endif
+
+ /* Initialize the first block of the first file: */
+ init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+ deflate_state *s;
+{
+ int n; /* iterates over tree elements */
+
+ /* Initialize the trees. */
+ for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
+ for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
+ for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+ s->dyn_ltree[END_BLOCK].Freq = 1;
+ s->opt_len = s->static_len = 0L;
+ s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+ top = s->heap[SMALLEST]; \
+ s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+ pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+ (tree[n].Freq < tree[m].Freq || \
+ (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+ deflate_state *s;
+ ct_data *tree; /* the tree to restore */
+ int k; /* node to move down */
+{
+ int v = s->heap[k];
+ int j = k << 1; /* left son of k */
+ while (j <= s->heap_len) {
+ /* Set j to the smallest of the two sons: */
+ if (j < s->heap_len &&
+ smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+ j++;
+ }
+ /* Exit if v is smaller than both sons */
+ if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+ /* Exchange v with the smallest son */
+ s->heap[k] = s->heap[j]; k = j;
+
+ /* And continue down the tree, setting j to the left son of k */
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ * above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ * array bl_count tqcontains the frequencies for each bit length.
+ * The length opt_len is updated; static_len is also updated if stree is
+ * not null.
+ */
+local void gen_bitlen(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ int max_code = desc->max_code;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ const intf *extra = desc->stat_desc->extra_bits;
+ int base = desc->stat_desc->extra_base;
+ int max_length = desc->stat_desc->max_length;
+ int h; /* heap index */
+ int n, m; /* iterate over the tree elements */
+ int bits; /* bit length */
+ int xbits; /* extra bits */
+ ush f; /* frequency */
+ int overflow = 0; /* number of elements with bit length too large */
+
+ for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+ /* In a first pass, compute the optimal bit lengths (which may
+ * overflow in the case of the bit length tree).
+ */
+ tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+ for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+ n = s->heap[h];
+ bits = tree[tree[n].Dad].Len + 1;
+ if (bits > max_length) bits = max_length, overflow++;
+ tree[n].Len = (ush)bits;
+ /* We overwrite tree[n].Dad which is no longer needed */
+
+ if (n > max_code) continue; /* not a leaf node */
+
+ s->bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n-base];
+ f = tree[n].Freq;
+ s->opt_len += (ulg)f * (bits + xbits);
+ if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+ }
+ if (overflow == 0) return;
+
+ Trace((stderr,"\nbit length overflow\n"));
+ /* This happens for example on obj2 and pic of the Calgary corpus */
+
+ /* Find the first bit length which could increase: */
+ do {
+ bits = max_length-1;
+ while (s->bl_count[bits] == 0) bits--;
+ s->bl_count[bits]--; /* move one leaf down the tree */
+ s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+ s->bl_count[max_length]--;
+ /* The brother of the overflow item also moves one step up,
+ * but this does not affect bl_count[max_length]
+ */
+ overflow -= 2;
+ } while (overflow > 0);
+
+ /* Now recompute all bit lengths, scanning in increasing frequency.
+ * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+ * lengths instead of fixing only the wrong ones. This idea is taken
+ * from 'ar' written by Haruhiko Okumura.)
+ */
+ for (bits = max_length; bits != 0; bits--) {
+ n = s->bl_count[bits];
+ while (n != 0) {
+ m = s->heap[--h];
+ if (m > max_code) continue;
+ if (tree[m].Len != (unsigned) bits) {
+ Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+ s->opt_len += ((long)bits - (long)tree[m].Len)
+ *(long)tree[m].Freq;
+ tree[m].Len = (ush)bits;
+ }
+ n--;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count tqcontains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ * zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+ ct_data *tree; /* the tree to decorate */
+ int max_code; /* largest code with non zero frequency */
+ ushf *bl_count; /* number of codes at each bit length */
+{
+ ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+ ush code = 0; /* running code value */
+ int bits; /* bit index */
+ int n; /* code index */
+
+ /* The distribution counts are first used to generate the code values
+ * without bit reversal.
+ */
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+ }
+ /* Check that the bit counts in bl_count are consistent. The last code
+ * must be all ones.
+ */
+ Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+ "inconsistent bit counts");
+ Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+ for (n = 0; n <= max_code; n++) {
+ int len = tree[n].Len;
+ if (len == 0) continue;
+ /* Now reverse the bits */
+ tree[n].Code = bi_reverse(next_code[len]++, len);
+
+ Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+ n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+ }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ * and corresponding code. The length opt_len is updated; static_len is
+ * also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+ deflate_state *s;
+ tree_desc *desc; /* the tree descriptor */
+{
+ ct_data *tree = desc->dyn_tree;
+ const ct_data *stree = desc->stat_desc->static_tree;
+ int elems = desc->stat_desc->elems;
+ int n, m; /* iterate over heap elements */
+ int max_code = -1; /* largest code with non zero frequency */
+ int node; /* new node being created */
+
+ /* Construct the initial heap, with least frequent element in
+ * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ * heap[0] is not used.
+ */
+ s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n].Freq != 0) {
+ s->heap[++(s->heap_len)] = max_code = n;
+ s->depth[n] = 0;
+ } else {
+ tree[n].Len = 0;
+ }
+ }
+
+ /* The pkzip format requires that at least one distance code exists,
+ * and that at least one bit should be sent even if there is only one
+ * possible code. So to avoid special checks later on we force at least
+ * two codes of non zero frequency.
+ */
+ while (s->heap_len < 2) {
+ node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+ tree[node].Freq = 1;
+ s->depth[node] = 0;
+ s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+ /* node is 0 or 1 so it does not have extra bits */
+ }
+ desc->max_code = max_code;
+
+ /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ * establish sub-heaps of increasing lengths:
+ */
+ for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+ /* Construct the Huffman tree by repeatedly combining the least two
+ * frequent nodes.
+ */
+ node = elems; /* next internal node of the tree */
+ do {
+ pqremove(s, tree, n); /* n = node of least frequency */
+ m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+ s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+ s->heap[--(s->heap_max)] = m;
+
+ /* Create a new node father of n and m */
+ tree[node].Freq = tree[n].Freq + tree[m].Freq;
+ s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+ s->depth[n] : s->depth[m]) + 1);
+ tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+ if (tree == s->bl_tree) {
+ fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+ node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+ }
+#endif
+ /* and insert the new node in the heap */
+ s->heap[SMALLEST] = node++;
+ pqdownheap(s, tree, SMALLEST);
+
+ } while (s->heap_len >= 2);
+
+ s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+ /* At this point, the fields freq and dad are set. We can now
+ * generate the bit lengths.
+ */
+ gen_bitlen(s, (tree_desc *)desc);
+
+ /* The field len is now set, we can generate the bit codes */
+ gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ if (nextlen == 0) max_count = 138, min_count = 3;
+ tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ s->bl_tree[curlen].Freq += count;
+ } else if (curlen != 0) {
+ if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+ s->bl_tree[REP_3_6].Freq++;
+ } else if (count <= 10) {
+ s->bl_tree[REPZ_3_10].Freq++;
+ } else {
+ s->bl_tree[REPZ_11_138].Freq++;
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+ deflate_state *s;
+ ct_data *tree; /* the tree to be scanned */
+ int max_code; /* and its largest code of non zero frequency */
+{
+ int n; /* iterates over all tree elements */
+ int prevlen = -1; /* last emitted length */
+ int curlen; /* length of current code */
+ int nextlen = tree[0].Len; /* length of next code */
+ int count = 0; /* repeat count of the current code */
+ int max_count = 7; /* max repeat count */
+ int min_count = 4; /* min repeat count */
+
+ /* tree[max_code+1].Len = -1; */ /* guard already set */
+ if (nextlen == 0) max_count = 138, min_count = 3;
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen; nextlen = tree[n+1].Len;
+ if (++count < max_count && curlen == nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+ } else if (curlen != 0) {
+ if (curlen != prevlen) {
+ send_code(s, curlen, s->bl_tree); count--;
+ }
+ Assert(count >= 3 && count <= 6, " 3_6?");
+ send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+ } else if (count <= 10) {
+ send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+ } else {
+ send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+ }
+ count = 0; prevlen = curlen;
+ if (nextlen == 0) {
+ max_count = 138, min_count = 3;
+ } else if (curlen == nextlen) {
+ max_count = 6, min_count = 3;
+ } else {
+ max_count = 7, min_count = 4;
+ }
+ }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+ deflate_state *s;
+{
+ int max_blindex; /* index of last bit length code of non zero freq */
+
+ /* Determine the bit length frequencies for literal and distance trees */
+ scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+ scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+ /* Build the bit length tree: */
+ build_tree(s, (tree_desc *)(&(s->bl_desc)));
+ /* opt_len now includes the length of the tree representations, except
+ * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+ */
+
+ /* Determine the number of bit length codes to send. The pkzip format
+ * requires that at least 4 bit length codes be sent. (appnote.txt says
+ * 3 but the actual value used is 4.)
+ */
+ for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+ if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+ }
+ /* Update opt_len to include the bit length tree and counts */
+ s->opt_len += 3*(max_blindex+1) + 5+5+4;
+ Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+ s->opt_len, s->static_len));
+
+ return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+ deflate_state *s;
+ int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+ int rank; /* index in bl_order */
+
+ Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+ Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+ "too many codes");
+ Tracev((stderr, "\nbl counts: "));
+ send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+ send_bits(s, dcodes-1, 5);
+ send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
+ for (rank = 0; rank < blcodes; rank++) {
+ Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+ send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+ }
+ Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+ Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+ send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+ Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
+#ifdef DEBUG
+ s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+ s->compressed_len += (stored_len + 4) << 3;
+#endif
+ copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+ deflate_state *s;
+{
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+ bi_flush(s);
+ /* Of the 10 bits for the empty block, we have already sent
+ * (10 - bi_valid) bits. The lookahead for the last real code (before
+ * the EOB of the previous block) was thus at least one plus the length
+ * of the EOB plus what we have just sent of the empty static block.
+ */
+ if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+ send_bits(s, STATIC_TREES<<1, 3);
+ send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+ s->compressed_len += 10L;
+#endif
+ bi_flush(s);
+ }
+ s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(s, buf, stored_len, eof)
+ deflate_state *s;
+ charf *buf; /* input block, or NULL if too old */
+ ulg stored_len; /* length of input block */
+ int eof; /* true if this is the last block for a file */
+{
+ ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+ int max_blindex = 0; /* index of last bit length code of non zero freq */
+
+ /* Build the Huffman trees unless a stored block is forced */
+ if (s->level > 0) {
+
+ /* Check if the file is ascii or binary */
+ if (s->strm->data_type == Z_UNKNOWN) set_data_type(s);
+
+ /* Construct the literal and distance trees */
+ build_tree(s, (tree_desc *)(&(s->l_desc)));
+ Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+
+ build_tree(s, (tree_desc *)(&(s->d_desc)));
+ Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+ s->static_len));
+ /* At this point, opt_len and static_len are the total bit lengths of
+ * the compressed block data, excluding the tree representations.
+ */
+
+ /* Build the bit length tree for the above two trees, and get the index
+ * in bl_order of the last bit length code to send.
+ */
+ max_blindex = build_bl_tree(s);
+
+ /* Determine the best encoding. Compute the block lengths in bytes. */
+ opt_lenb = (s->opt_len+3+7)>>3;
+ static_lenb = (s->static_len+3+7)>>3;
+
+ Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+ opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+ s->last_lit));
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+ } else {
+ Assert(buf != (char*)0, "lost buf");
+ opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+ }
+
+#ifdef FORCE_STORED
+ if (buf != (char*)0) { /* force stored block */
+#else
+ if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+ /* 4: two words for the lengths */
+#endif
+ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ * Otherwise we can't have processed more than WSIZE input bytes since
+ * the last block flush, because compression would have been
+ * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ * transform a block into a stored block.
+ */
+ _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+ } else if (static_lenb >= 0) { /* force static trees */
+#else
+ } else if (static_lenb == opt_lenb) {
+#endif
+ send_bits(s, (STATIC_TREES<<1)+eof, 3);
+ compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->static_len;
+#endif
+ } else {
+ send_bits(s, (DYN_TREES<<1)+eof, 3);
+ send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+ max_blindex+1);
+ compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+ s->compressed_len += 3 + s->opt_len;
+#endif
+ }
+ Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+ /* The above check is made mod 2^32, for files larger than 512 MB
+ * and uLong implemented on 32 bits.
+ */
+ init_block(s);
+
+ if (eof) {
+ bi_windup(s);
+#ifdef DEBUG
+ s->compressed_len += 7; /* align on byte boundary */
+#endif
+ }
+ Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+ s->compressed_len-7*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+ deflate_state *s;
+ unsigned dist; /* distance of matched string */
+ unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+ s->d_buf[s->last_lit] = (ush)dist;
+ s->l_buf[s->last_lit++] = (uch)lc;
+ if (dist == 0) {
+ /* lc is the unmatched char */
+ s->dyn_ltree[lc].Freq++;
+ } else {
+ s->matches++;
+ /* Here, lc is the match length - MIN_MATCH */
+ dist--; /* dist = match distance - 1 */
+ Assert((ush)dist < (ush)MAX_DIST(s) &&
+ (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+ (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
+
+ s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+ s->dyn_dtree[d_code(dist)].Freq++;
+ }
+
+#ifdef TRUNCATE_BLOCK
+ /* Try to guess if it is profitable to stop the current block here */
+ if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+ /* Compute an upper bound for the compressed length */
+ ulg out_length = (ulg)s->last_lit*8L;
+ ulg in_length = (ulg)((long)s->strstart - s->block_start);
+ int dcode;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += (ulg)s->dyn_dtree[dcode].Freq *
+ (5L+extra_dbits[dcode]);
+ }
+ out_length >>= 3;
+ Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+ s->last_lit, in_length, out_length,
+ 100L - out_length*100L/in_length));
+ if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+ }
+#endif
+ return (s->last_lit == s->lit_bufsize-1);
+ /* We avoid equality with lit_bufsize because of wraparound at 64K
+ * on 16 bit machines and because stored blocks are restricted to
+ * 64K-1 bytes.
+ */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+ deflate_state *s;
+ ct_data *ltree; /* literal tree */
+ ct_data *dtree; /* distance tree */
+{
+ unsigned dist; /* distance of matched string */
+ int lc; /* match length or unmatched char (if dist == 0) */
+ unsigned lx = 0; /* running index in l_buf */
+ unsigned code; /* the code to send */
+ int extra; /* number of extra bits to send */
+
+ if (s->last_lit != 0) do {
+ dist = s->d_buf[lx];
+ lc = s->l_buf[lx++];
+ if (dist == 0) {
+ send_code(s, lc, ltree); /* send a literal byte */
+ Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+ } else {
+ /* Here, lc is the match length - MIN_MATCH */
+ code = _length_code[lc];
+ send_code(s, code+LITERALS+1, ltree); /* send the length code */
+ extra = extra_lbits[code];
+ if (extra != 0) {
+ lc -= base_length[code];
+ send_bits(s, lc, extra); /* send the extra length bits */
+ }
+ dist--; /* dist is now the match distance - 1 */
+ code = d_code(dist);
+ Assert (code < D_CODES, "bad d_code");
+
+ send_code(s, code, dtree); /* send the distance code */
+ extra = extra_dbits[code];
+ if (extra != 0) {
+ dist -= base_dist[code];
+ send_bits(s, dist, extra); /* send the extra distance bits */
+ }
+ } /* literal or match pair ? */
+
+ /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+ Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+ "pendingBuf overflow");
+
+ } while (lx < s->last_lit);
+
+ send_code(s, END_BLOCK, ltree);
+ s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+ deflate_state *s;
+{
+ int n = 0;
+ unsigned ascii_freq = 0;
+ unsigned bin_freq = 0;
+ while (n < 7) bin_freq += s->dyn_ltree[n++].Freq;
+ while (n < 128) ascii_freq += s->dyn_ltree[n++].Freq;
+ while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+ s->strm->data_type = bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+ unsigned code; /* the value to invert */
+ int len; /* its bit length */
+{
+ register unsigned res = 0;
+ do {
+ res |= code & 1;
+ code >>= 1, res <<= 1;
+ } while (--len > 0);
+ return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+ deflate_state *s;
+{
+ if (s->bi_valid == 16) {
+ put_short(s, s->bi_buf);
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+ } else if (s->bi_valid >= 8) {
+ put_byte(s, (Byte)s->bi_buf);
+ s->bi_buf >>= 8;
+ s->bi_valid -= 8;
+ }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+ deflate_state *s;
+{
+ if (s->bi_valid > 8) {
+ put_short(s, s->bi_buf);
+ } else if (s->bi_valid > 0) {
+ put_byte(s, (Byte)s->bi_buf);
+ }
+ s->bi_buf = 0;
+ s->bi_valid = 0;
+#ifdef DEBUG
+ s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+ deflate_state *s;
+ charf *buf; /* the input data */
+ unsigned len; /* its length */
+ int header; /* true if block header must be written */
+{
+ bi_windup(s); /* align on byte boundary */
+ s->last_eob_len = 8; /* enough lookahead for inflate */
+
+ if (header) {
+ put_short(s, (ush)len);
+ put_short(s, (ush)~len);
+#ifdef DEBUG
+ s->bits_sent += 2*16;
+#endif
+ }
+#ifdef DEBUG
+ s->bits_sent += (ulg)len<<3;
+#endif
+ while (len--) {
+ put_byte(s, *buf++);
+ }
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/trees.h b/tqtinterface/qt4/src/3rdparty/zlib/trees.h
new file mode 100644
index 0000000..72facf9
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
+{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
+{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
+{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
+{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
+{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
+{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
+{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
+{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
+{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
+{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
+{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
+{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
+{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
+{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
+{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
+{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
+{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
+{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
+{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
+{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
+{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
+{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
+{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
+{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
+{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
+{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
+{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
+{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
+{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
+{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
+{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
+{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
+{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
+{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
+{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
+{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
+{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
+{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
+{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
+{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
+{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
+{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
+{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
+{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
+{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
+{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
+{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
+{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
+{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
+{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
+{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
+{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
+{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
+{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
+{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
+{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
+{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
+ 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+ 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
+ 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
+ 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
+};
+
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/uncompr.c b/tqtinterface/qt4/src/3rdparty/zlib/uncompr.c
new file mode 100644
index 0000000..2bddc64
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/uncompr.c
@@ -0,0 +1,61 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int TQ_ZEXPORT uncompress (dest, destLen, source, sourceLen)
+ Bytef *dest;
+ uLongf *destLen;
+ const Bytef *source;
+ uLong sourceLen;
+{
+ z_stream stream;
+ int err;
+
+ stream.next_in = (Bytef*)source;
+ stream.avail_in = (uInt)sourceLen;
+ /* Check for source > 64K on 16-bit machine: */
+ if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+ stream.next_out = dest;
+ stream.avail_out = (uInt)*destLen;
+ if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+ stream.zalloc = (alloc_func)0;
+ stream.zfree = (free_func)0;
+
+ err = inflateInit(&stream);
+ if (err != Z_OK) return err;
+
+ err = inflate(&stream, Z_FINISH);
+ if (err != Z_STREAM_END) {
+ inflateEnd(&stream);
+ if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+ return Z_DATA_ERROR;
+ return err;
+ }
+ *destLen = stream.total_out;
+
+ err = inflateEnd(&stream);
+ return err;
+}
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/win32/DLL_FAQ.txt b/tqtinterface/qt4/src/3rdparty/zlib/win32/DLL_FAQ.txt
new file mode 100644
index 0000000..4951c48
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/win32/DLL_FAQ.txt
@@ -0,0 +1,370 @@
+
+ Frequently Asked Questions about ZLIB1.DLL
+
+
+This document describes the design, the rationale, and the usage
+of the official DLL build of zlib, named ZLIB1.DLL. If you have
+general questions about zlib, you should see the file "FAQ" found
+in the zlib distribution, or at the following location:
+ http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. What is ZLIB1.DLL, and how can I get it?
+
+ - ZLIB1.DLL is the official build of zlib as a DLL.
+ (Please remark the character '1' in the name.)
+
+ Pointers to a precompiled ZLIB1.DLL can be found in the zlib
+ web site at:
+ http://www.zlib.org/
+
+ Applications that link to ZLIB1.DLL can rely on the following
+ specification:
+
+ * The exported symbols are exclusively defined in the source
+ files "zlib.h" and "zlib.def", found in an official zlib
+ source distribution.
+ * The symbols are exported by name, not by ordinal.
+ * The exported names are undecorated.
+ * The calling convention of functions is "C" (CDECL).
+ * The ZLIB1.DLL binary is linked to MSVCRT.DLL.
+
+ The archive in which ZLIB1.DLL is bundled tqcontains compiled
+ test programs that must run with a valid build of ZLIB1.DLL.
+ It is recommended to download the prebuilt DLL from the zlib
+ web site, instead of building it yourself, to avoid potential
+ incompatibilities that could be introduced by your compiler
+ and build settings. If you do build the DLL yourself, please
+ make sure that it complies with all the above requirements,
+ and it runs with the precompiled test programs, bundled with
+ the original ZLIB1.DLL distribution.
+
+ If, for any reason, you need to build an incompatible DLL,
+ please use a different file name.
+
+
+ 2. Why did you change the name of the DLL to ZLIB1.DLL?
+ What happened to the old ZLIB.DLL?
+
+ - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
+ compilation settings that were incompatible to those used by
+ a static build. The DLL settings were supposed to be enabled
+ by defining the macro ZLIB_DLL, before including "zlib.h".
+ Incorrect handling of this macro was silently accepted at
+ build time, resulting in two major problems:
+
+ * ZLIB_DLL was missing from the old makefile. When building
+ the DLL, not all people added it to the build options. In
+ consequence, incompatible incarnations of ZLIB.DLL started
+ to circulate around the net.
+
+ * When switching from using the static library to using the
+ DLL, applications had to define the ZLIB_DLL macro and
+ to recompile all the sources that contained calls to zlib
+ functions. Failure to do so resulted in creating binaries
+ that were unable to run with the official ZLIB.DLL build.
+
+ The only possible solution that we could foresee was to make
+ a binary-incompatible change in the DLL interface, in order to
+ remove the dependency on the ZLIB_DLL macro, and to release
+ the new DLL under a different name.
+
+ We chose the name ZLIB1.DLL, where '1' indicates the major
+ zlib version number. We hope that we will not have to break
+ the binary compatibility again, at least not as long as the
+ zlib-1.x series will last.
+
+ There is still a ZLIB_DLL macro, that can trigger a more
+ efficient build and use of the DLL, but compatibility no
+ longer dependents on it.
+
+
+ 3. Can I build ZLIB.DLL from the new zlib sources, and tqreplace
+ an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier?
+
+ - In principle, you can do it by assigning calling convention
+ keywords to the macros ZEXPORT and ZEXPORTVA. In practice,
+ it depends on what you mean by "an old ZLIB.DLL", because the
+ old DLL exists in several mutually-incompatible versions.
+ You have to tqfind out first what kind of calling convention is
+ being used in your particular ZLIB.DLL build, and to use the
+ same one in the new build. If you don't know what this is all
+ about, you might be better off if you would just leave the old
+ DLL intact.
+
+
+ 4. Can I compile my application using the new zlib interface, and
+ link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or
+ earlier?
+
+ - The official answer is "no"; the real answer depends again on
+ what kind of ZLIB.DLL you have. Even if you are lucky, this
+ course of action is unreliable.
+
+ If you rebuild your application and you intend to use a newer
+ version of zlib (post- 1.1.4), it is strongly recommended to
+ link it to the new ZLIB1.DLL.
+
+
+ 5. Why are the zlib symbols exported by name, and not by ordinal?
+
+ - Although exporting symbols by ordinal is a little faster, it
+ is risky. Any single glitch in the maintenance or use of the
+ DEF file that tqcontains the ordinals can result in incompatible
+ builds and frustrating crashes. Simply put, the benefits of
+ exporting symbols by ordinal do not justify the risks.
+
+ Technically, it should be possible to maintain ordinals in
+ the DEF file, and still export the symbols by name. Ordinals
+ exist in every DLL, and even if the dynamic linking performed
+ at the DLL startup is searching for names, ordinals serve as
+ hints, for a faster name lookup. However, if the DEF file
+ tqcontains ordinals, the Microsoft linker automatically builds
+ an implib that will cause the executables linked to it to use
+ those ordinals, and not the names. It is interesting to
+ notice that the GNU linker for Win32 does not suffer from this
+ problem.
+
+ It is possible to avoid the DEF file if the exported symbols
+ are accompanied by a "__declspec(dllexport)" attribute in the
+ source files. You can do this in zlib by predefining the
+ ZLIB_DLL macro.
+
+
+ 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling
+ convention. Why not use the STDCALL convention?
+ STDCALL is the standard convention in Win32, and I need it in
+ my Visual Basic project!
+
+ (For readability, we use CDECL to refer to the convention
+ triggered by the "__cdecl" keyword, STDCALL to refer to
+ the convention triggered by "__stdcall", and FASTCALL to
+ refer to the convention triggered by "__fastcall".)
+
+ - Most of the native Windows API functions (without varargs) use
+ indeed the WINAPI convention (which translates to STDCALL in
+ Win32), but the standard C functions use CDECL. If a user
+ application is intrinsically tied to the Windows API (e.g.
+ it calls native Windows API functions such as CreateFile()),
+ sometimes it makes sense to decorate its own functions with
+ WINAPI. But if ANSI C or POSIX portability is a goal (e.g.
+ it calls standard C functions such as fopen()), it is not a
+ sound decision to request the inclusion of <windows.h>, or to
+ use non-ANSI constructs, for the sole purpose to make the user
+ functions STDCALL-able.
+
+ The functionality offered by zlib is not in the category of
+ "Windows functionality", but is more like "C functionality".
+
+ Technically, STDCALL is not bad; in fact, it is slightly
+ faster than CDECL, and it works with variable-argument
+ functions, just like CDECL. It is unfortunate that, in spite
+ of using STDCALL in the Windows API, it is not the default
+ convention used by the C compilers that run under Windows.
+ The roots of the problem reside deep inside the unsafety of
+ the K&R-style function prototypes, where the argument types
+ are not specified; but that is another story for another day.
+
+ The remaining fact is that CDECL is the default convention.
+ Even if an explicit convention is hard-coded into the function
+ prototypes inside C headers, problems may appear. The
+ necessity to expose the convention in users' callbacks is one
+ of these problems.
+
+ The calling convention issues are also important when using
+ zlib in other programming languages. Some of them, like Ada
+ (GNAT) and Fortran (GNU G77), have C bindings implemented
+ initially on Unix, and relying on the C calling convention.
+ On the other hand, the pre- .Net versions of Microsoft Visual
+ Basic require STDCALL, while Borland Delphi prefers, although
+ it does not require, FASTCALL.
+
+ In fairness to all possible uses of zlib outside the C
+ programming language, we choose the default "C" convention.
+ Anyone interested in different bindings or conventions is
+ encouraged to maintain specialized projects. The "contrib/"
+ directory from the zlib distribution already holds a couple
+ of foreign bindings, such as Ada, C++, and Delphi.
+
+
+ 7. I need a DLL for my Visual Basic project. What can I do?
+
+ - Define the ZLIB_WINAPI macro before including "zlib.h", when
+ building both the DLL and the user application (except that
+ you don't need to define anything when using the DLL in Visual
+ Basic). The ZLIB_WINAPI macro will switch on the WINAPI
+ (STDCALL) convention. The name of this DLL must be different
+ than the official ZLIB1.DLL.
+
+ Gilles Vollant has contributed a build named ZLIBWAPI.DLL,
+ with the ZLIB_WINAPI macro turned on, and with the minizip
+ functionality built in. For more information, please read
+ the notes inside "contrib/vstudio/readme.txt", found in the
+ zlib distribution.
+
+
+ 8. I need to use zlib in my Microsoft .Net project. What can I
+ do?
+
+ - Henrik Ravn has contributed a .Net wrapper around zlib. Look
+ into contrib/dotzlib/, inside the zlib distribution.
+
+
+ 9. If my application uses ZLIB1.DLL, should I link it to
+ MSVCRT.DLL? Why?
+
+ - It is not required, but it is recommended to link your
+ application to MSVCRT.DLL, if it uses ZLIB1.DLL.
+
+ The executables (.EXE, .DLL, etc.) that are involved in the
+ same process and are using the C run-time library (i.e. they
+ are calling standard C functions), must link to the same
+ library. There are several libraries in the Win32 system:
+ CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc.
+ Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that
+ depend on it should also be linked to MSVCRT.DLL.
+
+
+10. Why are you saying that ZLIB1.DLL and my application must be
+ linked to the same C run-time (CRT) library? I linked my
+ application and my DLLs to different C libraries (e.g. my
+ application to a static library, and my DLLs to MSVCRT.DLL),
+ and everything works fine.
+
+ - If a user library invokes only pure Win32 API (accessible via
+ <windows.h> and the related headers), its DLL build will work
+ in any context. But if this library invokes standard C API,
+ things get more complicated.
+
+ There is a single Win32 library in a Win32 system. Every
+ function in this library resides in a single DLL module, that
+ is safe to call from anywhere. On the other hand, there are
+ multiple versions of the C library, and each of them has its
+ own separate internal state. Standalone executables and user
+ DLLs that call standard C functions must link to a C run-time
+ (CRT) library, be it static or shared (DLL). Intermixing
+ occurs when an executable (not necessarily standalone) and a
+ DLL are linked to different CRTs, and both are running in the
+ same process.
+
+ Intermixing multiple CRTs is possible, as long as their
+ internal states are kept intact. The Microsoft Knowledge Base
+ articles KB94248 "HOWTO: Use the C Run-Time" and KB140584
+ "HOWTO: Link with the Correct C Run-Time (CRT) Library"
+ mention the potential problems raised by intermixing.
+
+ If intermixing works for you, it's because your application
+ and DLLs are avoiding the corruption of each of the CRTs'
+ internal states, maybe by careful design, or maybe by fortune.
+
+ Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
+ as those provided by Borland, raises similar problems.
+
+
+11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
+
+ - MSVCRT.DLL exists on every Windows 95 with a new service pack
+ installed, or with Microsoft Internet Explorer 4 or later, and
+ on all other Windows 4.x or later (Windows 98, Windows NT 4,
+ or later). It is freely distributable; if not present in the
+ system, it can be downloaded from Microsoft or from other
+ software provider for free.
+
+ The fact that MSVCRT.DLL does not exist on a virgin Windows 95
+ is not so problematic. Windows 95 is scarcely found nowadays,
+ Microsoft ended its support a long time ago, and many recent
+ applications from various vendors, including Microsoft, do not
+ even run on it. Furthermore, no serious user should run
+ Windows 95 without a proper update installed.
+
+ There is also the fact that the mainstream C compilers for
+ Windows are Microsoft Visual C++ 6.0, and gcc/MinGW. Both
+ are producing executables that link to MSVCRT.DLL by default,
+ without offering other dynamic CRTs as alternatives easy to
+ select by users.
+
+
+12. Why are you not linking ZLIB1.DLL to
+ <<my favorite C run-time library>> ?
+
+ - We considered and abandoned the following alternatives:
+
+ * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or
+ LIBCMT.LIB) is not a good option. People are using the DLL
+ mainly to save disk space. If you are linking your program
+ to a static C library, you may as well consider linking zlib
+ in statically, too.
+
+ * Linking ZLIB1.DLL to CRTDLL.DLL looks very appealing,
+ because CRTDLL.DLL is present on every Win32 installation.
+ Unfortunately, it has a series of problems: it raises
+ difficulties when using it with C++ code, it does not work
+ with 64-bit file offsets, (and so on...), and Microsoft
+ discontinued its support a long time ago.
+
+ * Linking ZLIB1.DLL to MSVCR70.DLL, supplied with the
+ Microsoft .NET platform and Visual C++ 7.0 or newer, is not
+ a good option. Although it is available for free download
+ and distribution, its presence is scarce on today's Win32
+ installations. If it will ever become more popular than
+ MSVCRT.DLL and will be pre-installed on the future Win32
+ systems, we will probably think again about it.
+
+ * Linking ZLIB1.DLL to NTDLL.DLL is not possible.
+ NTDLL.DLL exports only a part of the C library, and only on
+ Windows NT systems.
+
+
+13. I need to link my own DLL build to a CRT different than
+ MSVCRT.DLL. What can I do?
+
+ - Feel free to rebuild the DLL from the zlib sources, and link
+ it the way you want. You should, however, clearly state that
+ your build is unofficial. You should give it a different file
+ name, and/or install it in a private directory that can be
+ accessed by your application only, and is not visible to the
+ others (e.g. it's not in the SYSTEM or the SYSTEM32 directory,
+ and it's not in the PATH). Otherwise, your build may clash
+ with applications that link to the official build.
+
+ For example, in Cygwin, zlib is linked to the Cygwin runtime
+ CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
+
+
+14. May I include additional pieces of code that I tqfind useful,
+ link them in ZLIB1.DLL, and export them?
+
+ - No. A legitimate build of ZLIB1.DLL must not include code
+ that does not originate from the official zlib source code.
+ But you can make your own private DLL build, under a different
+ file name, as suggested in the previous answer.
+
+ For example, zlib is a part of the VCL library, distributed
+ with Borland Delphi and C++ Builder. The DLL build of VCL
+ is a redistributable file, named VCLxx.DLL.
+
+
+15. May I remove some functionality out of ZLIB1.DLL, by enabling
+ macros like NO_GZCOMPRESS or NO_GZIP at compile time?
+
+ - No. A legitimate build of ZLIB1.DLL must provide the complete
+ zlib functionality, as implemented in the official zlib source
+ code. But you can make your own private DLL build, under a
+ different file name, as suggested in the previous answer.
+
+
+16. I made my own ZLIB1.DLL build. Can I test it for compliance?
+
+ - We prefer that you download the official DLL from the zlib
+ web site. If you need something peculiar from this DLL, you
+ can send your suggestion to the zlib mailing list.
+
+ However, in case you do rebuild the DLL yourself, you can run
+ it with the test programs found in the DLL distribution.
+ Running these test programs is not a guarantee of compliance,
+ but a failure can imply a detected problem.
+
+**
+
+This document is written and maintained by
+Cosmin Truta <cosmint@cs.ubbcluj.ro>
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.bor b/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.bor
new file mode 100644
index 0000000..b802519
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.bor
@@ -0,0 +1,107 @@
+# Makefile for zlib
+# Borland C++ for Win32
+#
+# Updated for zlib 1.2.x by Cosmin Truta, 11-Mar-2003
+# Last updated: 28-Aug-2003
+#
+# Usage:
+# make -f win32/Makefile.bor
+# make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
+
+# ------------ Borland C++ ------------
+
+# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or
+# added to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+CC = bcc32
+AS = bcc32
+LD = bcc32
+AR = tlib
+CFLAGS = -a -d -k- -O2 $(LOC)
+ASFLAGS = $(LOC)
+LDFLAGS = $(LOC)
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj
+OBJ2 = inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+#OBJA =
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzio.obj+infback.obj
+OBJP2 = +inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+#OBJPA=
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $<
+
+.asm.obj:
+ $(AS) -c $(ASFLAGS) $<
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: example.c zlib.h zconf.h
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA)
+ -del $(ZLIB_LIB)
+ $(AR) $(ZLIB_LIB) $(OBJP1)
+ $(AR) $(ZLIB_LIB) $(OBJP2)
+ $(AR) $(ZLIB_LIB) $(OBJPA)
+
+
+# testing
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+ -del *.obj
+ -del *.lib
+ -del *.exe
+ -del *.tds
+ -del zlib.bak
+ -del foo.gz
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.emx b/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.emx
new file mode 100644
index 0000000..f40c58c
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.emx
@@ -0,0 +1,69 @@
+# Makefile for zlib. Modified for emx/rsxnt by Chr. Spieler, 6/16/98.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+# make -fmakefile.emx; make test -fmakefile.emx
+#
+
+CC=gcc -Zwin32
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DDEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+ -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, tqreplace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, tqreplace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f." If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lzlib
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=zlib.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
+ zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+test: all
+ ./example
+ echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+zlib.a: $(OBJS)
+ $(AR) $@ $(OBJS)
+
+%.exe : %.o $(LIBS)
+ $(LD) $@ $< $(LDLIBS)
+
+
+.PHONY : clean
+
+clean:
+ $(RM) *.d
+ $(RM) *.o
+ $(RM) *.exe
+ $(RM) zlib.a
+ $(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.gcc b/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.gcc
new file mode 100644
index 0000000..895193e
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.gcc
@@ -0,0 +1,141 @@
+# Makefile for zlib, derived from Makefile.dj2.
+# Modified for mingw32 by C. Spieler, 6/16/98.
+# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
+# Last updated: 1-Aug-2003.
+# Tested under Cygwin and MinGW.
+
+# Copyright (C) 1995-2003 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+# make -fmakefile.gcc; make test testdll -fmakefile.gcc
+#
+# To use the asm code, type:
+# cp contrib/asm?86/match.S ./match.S
+# make LOC=-DASMV OBJA=match.o -fmakefile.gcc
+#
+# To install libz.a, zconf.h and zlib.h in the system directories, type:
+#
+# make install -fmakefile.gcc
+
+# Note:
+# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
+# the DLL name should be changed from "zlib1.dll".
+
+STATICLIB = libz.a
+SHAREDLIB = zlib1.dll
+IMPLIB = libzdll.a
+
+#LOC = -DASMV
+#LOC = -DDEBUG -g
+
+CC = gcc
+CFLAGS = $(LOC) -O3 -Wall
+
+AS = $(CC)
+ASFLAGS = $(LOC) -Wall
+
+LD = $(CC)
+LDFLAGS = $(LOC) -s
+
+AR = ar
+ARFLAGS = rcs
+
+RC = windres
+RCFLAGS = --define GCC_WINDRES
+
+CP = cp -fp
+# If GNU install is available, tqreplace $(CP) with install.
+INSTALL = $(CP)
+RM = rm -f
+
+prefix = /usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o deflate.o gzio.o infback.o \
+ inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+OBJA =
+
+all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example minigzip example_d minigzip_d
+
+test: example minigzip
+ ./example
+ echo hello world | ./minigzip | ./minigzip -d
+
+testdll: example_d minigzip_d
+ ./example_d
+ echo hello world | ./minigzip_d | ./minigzip_d -d
+
+.c.o:
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+.S.o:
+ $(AS) $(ASFLAGS) -c -o $@ $<
+
+$(STATICLIB): $(OBJS) $(OBJA)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA)
+
+$(IMPLIB): $(SHAREDLIB)
+
+$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
+ dllwrap --driver-name $(CC) --def win32/zlib.def \
+ --implib $(IMPLIB) -o $@ $(OBJS) $(OBJA) zlibrc.o
+ strip $@
+
+example: example.o $(STATICLIB)
+ $(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB)
+
+minigzip: minigzip.o $(STATICLIB)
+ $(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB)
+
+example_d: example.o $(IMPLIB)
+ $(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB)
+
+minigzip_d: minigzip.o $(IMPLIB)
+ $(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)
+
+zlibrc.o: win32/zlib1.rc
+ $(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
+
+
+# INCLUDE_PATH and LIBRARY_PATH must be set.
+
+.PHONY: install uninstall clean
+
+install: zlib.h zconf.h $(LIB)
+ -@if not exist $(INCLUDE_PATH)/nul mkdir $(INCLUDE_PATH)
+ -@if not exist $(LIBRARY_PATH)/nul mkdir $(LIBRARY_PATH)
+ -$(INSTALL) zlib.h $(INCLUDE_PATH)
+ -$(INSTALL) zconf.h $(INCLUDE_PATH)
+ -$(INSTALL) $(STATICLIB) $(LIBRARY_PATH)
+ -$(INSTALL) $(IMPLIB) $(LIBRARY_PATH)
+
+uninstall:
+ -$(RM) $(INCLUDE_PATH)/zlib.h
+ -$(RM) $(INCLUDE_PATH)/zconf.h
+ -$(RM) $(LIBRARY_PATH)/$(STATICLIB)
+ -$(RM) $(LIBRARY_PATH)/$(IMPLIB)
+
+clean:
+ -$(RM) $(STATICLIB)
+ -$(RM) $(SHAREDLIB)
+ -$(RM) $(IMPLIB)
+ -$(RM) *.o
+ -$(RM) *.exe
+ -$(RM) foo.gz
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzio.o: zutil.h zlib.h zconf.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.msc b/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.msc
new file mode 100644
index 0000000..528ecaa
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/win32/Makefile.msc
@@ -0,0 +1,126 @@
+# Makefile for zlib -- Microsoft (Visual) C
+#
+# Authors:
+# Cosmin Truta, 11-Mar-2003
+# Christian Spieler, 19-Mar-2003
+#
+# Last updated:
+# Cosmin Truta, 27-Aug-2003
+#
+# Usage:
+# nmake -f win32/Makefile.msc (standard build)
+# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build)
+# nmake -f win32/Makefile.msc LOC=-DASMV OBJA=match.obj (use ASM code)
+
+
+# optional build flags
+LOC =
+
+
+# variables
+STATICLIB = zlib.lib
+SHAREDLIB = zlib1.dll
+IMPLIB = zdll.lib
+
+CC = cl
+AS = ml
+LD = link
+AR = lib
+RC = rc
+CFLAGS = -nologo -MD -O2 $(LOC)
+ASFLAGS = -coff
+LDFLAGS = -nologo -release
+ARFLAGS = -nologo
+RCFLAGS = /dWIN32 /r
+
+OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzio.obj infback.obj \
+ inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJA =
+
+
+# targets
+all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
+ example.exe minigzip.exe example_d.exe minigzip_d.exe
+
+$(STATICLIB): $(OBJS) $(OBJA)
+ $(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)
+
+$(IMPLIB): $(SHAREDLIB)
+
+$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlib1.res
+ $(LD) $(LDFLAGS) -def:win32/zlib.def -dll -implib:$(IMPLIB) \
+ -out:$@ $(OBJS) $(OBJA) zlib1.res
+
+example.exe: example.obj $(STATICLIB)
+ $(LD) $(LDFLAGS) example.obj $(STATICLIB)
+
+minigzip.exe: minigzip.obj $(STATICLIB)
+ $(LD) $(LDFLAGS) minigzip.obj $(STATICLIB)
+
+example_d.exe: example.obj $(IMPLIB)
+ $(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB)
+
+minigzip_d.exe: minigzip.obj $(IMPLIB)
+ $(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB)
+
+.c.obj:
+ $(CC) -c $(CFLAGS) $<
+
+.asm.obj:
+ $(AS) -c $(ASFLAGS) $<
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: example.c zlib.h zconf.h
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+
+zlib1.res: win32/zlib1.rc
+ $(RC) $(RCFLAGS) /fo$@ win32/zlib1.rc
+
+
+# testing
+test: example.exe minigzip.exe
+ example
+ echo hello world | minigzip | minigzip -d
+
+testdll: example_d.exe minigzip_d.exe
+ example_d
+ echo hello world | minigzip_d | minigzip_d -d
+
+
+# cleanup
+clean:
+ -del $(STATICLIB)
+ -del $(SHAREDLIB)
+ -del $(IMPLIB)
+ -del *.obj
+ -del *.res
+ -del *.exp
+ -del *.exe
+ -del foo.gz
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/win32/VisualC.txt b/tqtinterface/qt4/src/3rdparty/zlib/win32/VisualC.txt
new file mode 100644
index 0000000..579a5fc
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/win32/VisualC.txt
@@ -0,0 +1,3 @@
+
+To build zlib using the Microsoft Visual C++ environment,
+use the appropriate project from the projects/ directory.
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/win32/zlib.def b/tqtinterface/qt4/src/3rdparty/zlib/win32/zlib.def
new file mode 100644
index 0000000..a47cbc1
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/win32/zlib.def
@@ -0,0 +1,60 @@
+LIBRARY
+; zlib data compression library
+
+EXPORTS
+; basic functions
+ zlibVersion
+ deflate
+ deflateEnd
+ inflate
+ inflateEnd
+; advanced functions
+ deflateSetDictionary
+ deflateCopy
+ deflateReset
+ deflateParams
+ deflateBound
+ deflatePrime
+ inflateSetDictionary
+ inflateSync
+ inflateCopy
+ inflateReset
+ inflateBack
+ inflateBackEnd
+ zlibCompileFlags
+; utility functions
+ compress
+ compress2
+ compressBound
+ uncompress
+ gzopen
+ gzdopen
+ gzsetparams
+ gzread
+ gzwrite
+ gzprintf
+ gzputs
+ gzgets
+ gzputc
+ gzgetc
+ gzungetc
+ gzflush
+ gzseek
+ gzrewind
+ gztell
+ gzeof
+ gzclose
+ gzerror
+ gzclearerr
+; checksum functions
+ adler32
+ crc32
+; various hacks, don't look :)
+ deflateInit_
+ deflateInit2_
+ inflateInit_
+ inflateInit2_
+ inflateBackInit_
+ inflateSyncPoint
+ get_crc_table
+ zError
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/win32/zlib1.rc b/tqtinterface/qt4/src/3rdparty/zlib/win32/zlib1.rc
new file mode 100644
index 0000000..162ab8f
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/win32/zlib1.rc
@@ -0,0 +1,39 @@
+#include <windows.h>
+
+#ifdef GCC_WINDRES
+VS_VERSION_INFO VERSIONINFO
+#else
+VS_VERSION_INFO VERSIONINFO MOVEABLE IMPURE LOADONCALL DISCARDABLE
+#endif
+ FILEVERSION 1,2,2
+ PRODUCTVERSION 1,2,2
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS 1
+#else
+ FILEFLAGS 0
+#endif
+ FILEOS VOS_DOS_WINDOWS32
+ FILETYPE VFT_DLL
+ FILESUBTYPE 0 // not used
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904E4"
+ //language ID = U.S. English, char set = Windows, Multilingual
+ BEGIN
+ VALUE "FileDescription", "zlib data compression library\0"
+ VALUE "FileVersion", "1.2.2\0"
+ VALUE "InternalName", "zlib1.dll\0"
+ VALUE "LegalCopyright", "(C) 1995-2004 Jean-loup Gailly & Mark Adler\0"
+ VALUE "OriginalFilename", "zlib1.dll\0"
+ VALUE "ProductName", "zlib\0"
+ VALUE "ProductVersion", "1.2.2\0"
+ VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 1252
+ END
+END
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/zconf.h b/tqtinterface/qt4/src/3rdparty/zlib/zconf.h
new file mode 100644
index 0000000..3c21403
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/zconf.h
@@ -0,0 +1,326 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define deflateBound z_deflateBound
+# define deflatePrime z_deflatePrime
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateCopy z_inflateCopy
+# define inflateReset z_inflateReset
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+# define zError z_zError
+
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+# define WIN32
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
+# include <sys/types.h> /* for off_t */
+# include <unistd.h> /* for SEEK_* and off_t */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if defined(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+# ifdef FAR
+# undef FAR
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(deflateBound,"DEBND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(compressBound,"CMBND")
+# pragma map(inflate_table,"INTABL")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/zconf.in.h b/tqtinterface/qt4/src/3rdparty/zlib/zconf.in.h
new file mode 100644
index 0000000..3c21403
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/zconf.in.h
@@ -0,0 +1,326 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2004 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+# define deflateInit_ z_deflateInit_
+# define deflate z_deflate
+# define deflateEnd z_deflateEnd
+# define inflateInit_ z_inflateInit_
+# define inflate z_inflate
+# define inflateEnd z_inflateEnd
+# define deflateInit2_ z_deflateInit2_
+# define deflateSetDictionary z_deflateSetDictionary
+# define deflateCopy z_deflateCopy
+# define deflateReset z_deflateReset
+# define deflateParams z_deflateParams
+# define deflateBound z_deflateBound
+# define deflatePrime z_deflatePrime
+# define inflateInit2_ z_inflateInit2_
+# define inflateSetDictionary z_inflateSetDictionary
+# define inflateSync z_inflateSync
+# define inflateSyncPoint z_inflateSyncPoint
+# define inflateCopy z_inflateCopy
+# define inflateReset z_inflateReset
+# define inflateBack z_inflateBack
+# define inflateBackEnd z_inflateBackEnd
+# define compress z_compress
+# define compress2 z_compress2
+# define compressBound z_compressBound
+# define uncompress z_uncompress
+# define adler32 z_adler32
+# define crc32 z_crc32
+# define get_crc_table z_get_crc_table
+# define zError z_zError
+
+# define Byte z_Byte
+# define uInt z_uInt
+# define uLong z_uLong
+# define Bytef z_Bytef
+# define charf z_charf
+# define intf z_intf
+# define uIntf z_uIntf
+# define uLongf z_uLongf
+# define voidpf z_voidpf
+# define voidp z_voidp
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+# define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+# define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+# define WINDOWS
+#endif
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+# define WIN32
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+# ifndef SYS16BIT
+# define SYS16BIT
+# endif
+# endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+# define MAXSEG_64K
+#endif
+#ifdef MSDOS
+# define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+# ifndef STDC
+# define STDC
+# endif
+# if __STDC_VERSION__ >= 199901L
+# ifndef STDC99
+# define STDC99
+# endif
+# endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+# define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+# define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
+# define STDC
+#endif
+
+#ifndef STDC
+# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+# define const /* note: need a more gentle solution here */
+# endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+# define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+# ifdef MAXSEG_64K
+# define MAX_MEM_LEVEL 8
+# else
+# define MAX_MEM_LEVEL 9
+# endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+# define MAX_WBITS 15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+ (1 << (windowBits+2)) + (1 << (memLevel+9))
+ that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+ make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+ The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+ /* Type declarations */
+
+#ifndef OF /* function prototypes */
+# ifdef STDC
+# define OF(args) args
+# else
+# define OF(args) ()
+# endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+# if defined(M_I86SM) || defined(M_I86MM)
+ /* MSC small or medium model */
+# define SMALL_MEDIUM
+# ifdef _MSC_VER
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+# if (defined(__SMALL__) || defined(__MEDIUM__))
+ /* Turbo C small or medium model */
+# define SMALL_MEDIUM
+# ifdef __BORLANDC__
+# define FAR _far
+# else
+# define FAR far
+# endif
+# endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+ /* If building or using zlib as a DLL, define ZLIB_DLL.
+ * This is not mandatory, but it offers a little performance increase.
+ */
+# ifdef ZLIB_DLL
+# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+# ifdef ZLIB_INTERNAL
+# define ZEXTERN extern __declspec(dllexport)
+# else
+# define ZEXTERN extern __declspec(dllimport)
+# endif
+# endif
+# endif /* ZLIB_DLL */
+ /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+ * define ZLIB_WINAPI.
+ * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+ */
+# ifdef ZLIB_WINAPI
+# ifdef FAR
+# undef FAR
+# endif
+# include <windows.h>
+ /* No need for _export, use ZLIB.DEF instead. */
+ /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+# define ZEXPORT WINAPI
+# ifdef WIN32
+# define ZEXPORTVA WINAPIV
+# else
+# define ZEXPORTVA FAR CDECL
+# endif
+# endif
+#endif
+
+#if defined (__BEOS__)
+# ifdef ZLIB_DLL
+# ifdef ZLIB_INTERNAL
+# define ZEXPORT __declspec(dllexport)
+# define ZEXPORTVA __declspec(dllexport)
+# else
+# define ZEXPORT __declspec(dllimport)
+# define ZEXPORTVA __declspec(dllimport)
+# endif
+# endif
+#endif
+
+#ifndef ZEXTERN
+# define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+# define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+# define ZEXPORTVA
+#endif
+
+#ifndef FAR
+# define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char Byte; /* 8 bits */
+#endif
+typedef unsigned int uInt; /* 16 bits or more */
+typedef unsigned long uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+ /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+# define Bytef Byte FAR
+#else
+ typedef Byte FAR Bytef;
+#endif
+typedef char FAR charf;
+typedef int FAR intf;
+typedef uInt FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+ typedef void const *voidpc;
+ typedef void FAR *voidpf;
+ typedef void *voidp;
+#else
+ typedef Byte const *voidpc;
+ typedef Byte FAR *voidpf;
+ typedef Byte *voidp;
+#endif
+
+#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
+# include <sys/types.h> /* for off_t */
+# include <unistd.h> /* for SEEK_* and off_t */
+# ifdef VMS
+# include <unixio.h> /* for off_t */
+# endif
+# define z_off_t off_t
+#endif
+#ifndef SEEK_SET
+# define SEEK_SET 0 /* Seek from beginning of file. */
+# define SEEK_CUR 1 /* Seek from current position. */
+# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+# define z_off_t long
+#endif
+
+#if defined(__OS400__)
+# define NO_vsnprintf
+#endif
+
+#if defined(__MVS__)
+# define NO_vsnprintf
+# ifdef FAR
+# undef FAR
+# endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+# pragma map(deflateInit_,"DEIN")
+# pragma map(deflateInit2_,"DEIN2")
+# pragma map(deflateEnd,"DEEND")
+# pragma map(deflateBound,"DEBND")
+# pragma map(inflateInit_,"ININ")
+# pragma map(inflateInit2_,"ININ2")
+# pragma map(inflateEnd,"INEND")
+# pragma map(inflateSync,"INSY")
+# pragma map(inflateSetDictionary,"INSEDI")
+# pragma map(compressBound,"CMBND")
+# pragma map(inflate_table,"INTABL")
+# pragma map(inflate_fast,"INFA")
+# pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/zlib.3 b/tqtinterface/qt4/src/3rdparty/zlib/zlib.3
new file mode 100644
index 0000000..3139e24
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/zlib.3
@@ -0,0 +1,159 @@
+.TH ZLIB 3 "3 October 2004"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms will be added later
+and will have the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+(for example if an input file is mmap'ed),
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.IR gzip (1)
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler.
+The decoder checks the consistency of the compressed data,
+so the library should never crash even in case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h .
+The distribution source includes examples of use of the library
+in the files
+.I example.c
+and
+.IR minigzip.c .
+.LP
+Changes to this version are documented in the file
+.I ChangeLog
+that accompanies the source,
+and are concerned primarily with bug fixes and portability enhancements.
+.LP
+A Java implementation of
+.I zlib
+is available in the Java Development Kit 1.1:
+.IP
+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
+.LP
+A Perl interface to
+.IR zlib ,
+written by Paul Marquess (pmqs@cpan.org),
+is available at CPAN (Comprehensive Perl Archive Network) sites,
+including:
+.IP
+http://www.cpan.org/modules/by-module/Compress/
+.LP
+A Python interface to
+.IR zlib ,
+written by A.M. Kuchling (amk@magnet.com),
+is available in Python 1.5 and later versions:
+.IP
+http://www.python.org/doc/lib/module-zlib.html
+.LP
+A
+.I zlib
+binding for
+.IR tcl (1),
+written by Andreas Kupries (a.kupries@westend.com),
+is availlable at:
+.IP
+http://www.westend.com/~kupries/doc/trf/man/man.html
+.LP
+An experimental package to read and write files in .zip format,
+written on top of
+.I zlib
+by Gilles Vollant (info@winimage.com),
+is available at:
+.IP
+http://www.winimage.com/zLibDll/unzip.html
+and also in the
+.I contrib/minizip
+directory of the main
+.I zlib
+web site.
+.SH "SEE ALSO"
+The
+.I zlib
+web site can be found at either of these locations:
+.IP
+http://www.zlib.org
+.br
+http://www.gzip.org/zlib/
+.LP
+The data format used by the zlib library is described by RFC
+(Request for Comments) 1950 to 1952 in the files:
+.IP
+http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format)
+.br
+http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format)
+.br
+http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format)
+.LP
+These documents are also available in other formats from:
+.IP
+ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+.LP
+Mark Nelson (markn@ieee.org) wrote an article about
+.I zlib
+for the Jan. 1997 issue of Dr. Dobb's Journal;
+a copy of the article is available at:
+.IP
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+.SH "REPORTING PROBLEMS"
+Before reporting a problem,
+please check the
+.I zlib
+web site to verify that you have the latest version of
+.IR zlib ;
+otherwise,
+obtain the latest version and see if the problem still exists.
+Please read the
+.I zlib
+FAQ at:
+.IP
+http://www.gzip.org/zlib/zlib_faq.html
+.LP
+before asking for help.
+Send questions and/or comments to zlib@gzip.org,
+or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
+.SH AUTHORS
+Version 1.2.2
+Copyright (C) 1995-2004 Jean-loup Gailly (jloup@gzip.org)
+and Mark Adler (madler@alumni.caltech.edu).
+.LP
+This software is provided "as-is,"
+without any express or implied warranty.
+In no event will the authors be held liable for any damages
+arising from the use of this software.
+See the distribution directory with respect to requirements
+governing redistribution.
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers@nlm.nih.gov).
+.\" end of man page
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/zlib.h b/tqtinterface/qt4/src/3rdparty/zlib/zlib.h
new file mode 100644
index 0000000..4f88f62
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/zlib.h
@@ -0,0 +1,1213 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+ version 1.2.2, October 3rd, 2004
+
+ Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Jean-loup Gailly Mark Adler
+ jloup@gzip.org madler@alumni.caltech.edu
+
+
+ The data format used by the zlib library is described by RFCs (Request for
+ Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
+ (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.2"
+#define ZLIB_VERNUM 0x1220
+
+#ifdef TQT_MAKEDLL
+#define TQ_ZEXPORT __declspec(dllexport)
+#else
+#if defined(TQT_DLL) && !defined(TQT_PLUGIN)
+#define TQ_ZEXPORT __declspec(dllimport)
+#else
+#define TQ_ZEXPORT ZEXPORT
+#endif
+#endif
+#ifdef TQ_OS_TEMP
+#include <tqfunctions_wce.h>
+#endif
+
+/*
+ The 'zlib' compression library provides in-memory compression and
+ decompression functions, including integrity checks of the uncompressed
+ data. This version of the library supports only one compression method
+ (deflation) but other algorithms will be added later and will have the same
+ stream interface.
+
+ Compression can be done in a single step if the buffers are large
+ enough (for example if an input file is mmap'ed), or can be done by
+ repeated calls of the compression function. In the latter case, the
+ application must provide more input and/or consume the output
+ (providing more output space) before each call.
+
+ The compressed data format used by default by the in-memory functions is
+ the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+ around a deflate stream, which is itself documented in RFC 1951.
+
+ The library also supports reading and writing files in gzip (.gz) format
+ with an interface similar to that of stdio using the functions that start
+ with "gz". The gzip format is different from the zlib format. gzip is a
+ gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+ This library can optionally read and write gzip streams in memory as well.
+
+ The zlib format was designed to be compact and fast for use in memory
+ and on communications channels. The gzip format was designed for single-
+ file compression on file systems, has a larger header than zlib to maintain
+ directory information, and uses a different, slower check method than zlib.
+
+ The library does not install any signal handler. The decoder checks
+ the consistency of the compressed data, so the library should never
+ crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void (*free_func) OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+ Bytef *next_in; /* next input byte */
+ uInt avail_in; /* number of bytes available at next_in */
+ uLong total_in; /* total nb of input bytes read so far */
+
+ Bytef *next_out; /* next output byte should be put there */
+ uInt avail_out; /* remaining free space at next_out */
+ uLong total_out; /* total nb of bytes output so far */
+
+ char *msg; /* last error message, NULL if no error */
+ struct internal_state FAR *state; /* not visible by applications */
+
+ alloc_func zalloc; /* used to allocate the internal state */
+ free_func zfree; /* used to free the internal state */
+ voidpf opaque; /* private data object passed to zalloc and zfree */
+
+ int data_type; /* best guess about the data type: ascii or binary */
+ uLong adler; /* adler32 value of the uncompressed data */
+ uLong reserved; /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+ The application must update next_in and avail_in when avail_in has
+ dropped to zero. It must update next_out and avail_out when avail_out
+ has dropped to zero. The application must initialize zalloc, zfree and
+ opaque before calling the init function. All other fields are set by the
+ compression library and must not be updated by the application.
+
+ The opaque value provided by the application will be passed as the first
+ parameter for calls of zalloc and zfree. This can be useful for custom
+ memory management. The compression library attaches no meaning to the
+ opaque value.
+
+ zalloc must return Z_NULL if there is not enough memory for the object.
+ If zlib is used in a multi-threaded application, zalloc and zfree must be
+ thread safe.
+
+ On 16-bit systems, the functions zalloc and zfree must be able to allocate
+ exactly 65536 bytes, but will not be required to allocate more than this
+ if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+ pointers returned by zalloc for objects of exactly 65536 bytes *must*
+ have their offset normalized to zero. The default allocation function
+ provided by this library ensures this (see zutil.c). To reduce memory
+ requirements and avoid any allocation of 64K objects, at the expense of
+ compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+ The fields total_in and total_out can be used for statistics or
+ progress reports. After compression, total_in holds the total size of
+ the uncompressed data and may be saved for use in the decompressor
+ (particularly if the decompressor wants to decompress everything in
+ a single step).
+*/
+
+ /* constants */
+
+#define Z_NO_FLUSH 0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH 2
+#define Z_FULL_FLUSH 3
+#define Z_FINISH 4
+#define Z_BLOCK 5
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK 0
+#define Z_STREAM_END 1
+#define Z_NEED_DICT 2
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR (-3)
+#define Z_MEM_ERROR (-4)
+#define Z_BUF_ERROR (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION 0
+#define Z_BEST_SPEED 1
+#define Z_BEST_COMPRESSION 9
+#define Z_DEFAULT_COMPRESSION (-1)
+/* compression levels */
+
+#define Z_FILTERED 1
+#define Z_HUFFMAN_ONLY 2
+#define Z_RLE 3
+#define Z_DEFAULT_STRATEGY 0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY 0
+#define Z_ASCII 1
+#define Z_UNKNOWN 2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED 8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+ /* basic functions */
+
+ZEXTERN TQ_ZEXPORT const char * zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+ If the first character differs, the library code actually used is
+ not compatible with the zlib.h header file used by the application.
+ This check is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+ Initializes the internal stream state for compression. The fields
+ zalloc, zfree and opaque must be initialized before by the caller.
+ If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+ use default allocation functions.
+
+ The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+ 1 gives best speed, 9 gives best compression, 0 gives no compression at
+ all (the input data is simply copied a block at a time).
+ Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+ compression (currently equivalent to level 6).
+
+ deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+ Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+ with the version assumed by the caller (ZLIB_VERSION).
+ msg is set to null if there is no error message. deflateInit does not
+ perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int TQ_ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+ deflate compresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce some
+ output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. deflate performs one or both of the
+ following actions:
+
+ - Compress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in and avail_in are updated and
+ processing will resume at this point for the next call of deflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. This action is forced if the parameter flush is non zero.
+ Forcing flush frequently degrades the compression ratio, so this parameter
+ should be set only when necessary (in interactive applications).
+ Some output may be provided even if flush is not set.
+
+ Before the call of deflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating avail_in or avail_out accordingly; avail_out
+ should never be zero before the call. The application can consume the
+ compressed output when it wants, for example when the output buffer is full
+ (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+ and with zero avail_out, it must be called again after making room in the
+ output buffer because there might be more output pending.
+
+ If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+ flushed to the output buffer and the output is aligned on a byte boundary, so
+ that the decompressor can get all input data available so far. (In particular
+ avail_in is zero after the call if enough output space has been provided
+ before the call.) Flushing may degrade compression for some compression
+ algorithms and so it should be used only when necessary.
+
+ If flush is set to Z_FULL_FLUSH, all output is flushed as with
+ Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+ restart from this point if previous compressed data has been damaged or if
+ random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+ the compression.
+
+ If deflate returns with avail_out == 0, this function must be called again
+ with the same value of the flush parameter and more output space (updated
+ avail_out), until the flush is complete (deflate returns with non-zero
+ avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+ avail_out is greater than six to avoid repeated flush markers due to
+ avail_out == 0 on return.
+
+ If the parameter flush is set to Z_FINISH, pending input is processed,
+ pending output is flushed and deflate returns with Z_STREAM_END if there
+ was enough output space; if deflate returns with Z_OK, this function must be
+ called again with Z_FINISH and more output space (updated avail_out) but no
+ more input data, until it returns with Z_STREAM_END or an error. After
+ deflate has returned Z_STREAM_END, the only possible operations on the
+ stream are deflateReset or deflateEnd.
+
+ Z_FINISH can be used immediately after deflateInit if all the compression
+ is to be done in a single step. In this case, avail_out must be at least
+ the value returned by deflateBound (see below). If deflate does not return
+ Z_STREAM_END, then it must be called again as described above.
+
+ deflate() sets strm->adler to the adler32 checksum of all input read
+ so far (that is, total_in bytes).
+
+ deflate() may update data_type if it can make a good guess about
+ the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+ binary. This field is only for information purposes and does not affect
+ the compression algorithm in any manner.
+
+ deflate() returns Z_OK if some progress has been made (more input
+ processed or more output produced), Z_STREAM_END if all input has been
+ consumed and all output has been produced (only when flush is set to
+ Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+ if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+ (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
+ fatal, and deflate() can be called again with more input and more output
+ space to continue compressing.
+*/
+
+
+ZEXTERN int TQ_ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+ stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+ prematurely (some input or output was discarded). In the error case,
+ msg may be set but then points to a static string (which must not be
+ deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+ Initializes the internal stream state for decompression. The fields
+ next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+ the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+ value depends on the compression method), inflateInit determines the
+ compression method from the zlib header and allocates all data structures
+ accordingly; otherwise the allocation will be deferred to the first call of
+ inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+ use default allocation functions.
+
+ inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+ version assumed by the caller. msg is set to null if there is no error
+ message. inflateInit does not perform any decompression apart from reading
+ the zlib header if present: this will be done by inflate(). (So next_in and
+ avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int TQ_ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+ inflate decompresses as much data as possible, and stops when the input
+ buffer becomes empty or the output buffer becomes full. It may introduce
+ some output latency (reading input without producing any output) except when
+ forced to flush.
+
+ The detailed semantics are as follows. inflate performs one or both of the
+ following actions:
+
+ - Decompress more input starting at next_in and update next_in and avail_in
+ accordingly. If not all input can be processed (because there is not
+ enough room in the output buffer), next_in is updated and processing
+ will resume at this point for the next call of inflate().
+
+ - Provide more output starting at next_out and update next_out and avail_out
+ accordingly. inflate() provides as much output as possible, until there
+ is no more input data or no more space in the output buffer (see below
+ about the flush parameter).
+
+ Before the call of inflate(), the application should ensure that at least
+ one of the actions is possible, by providing more input and/or consuming
+ more output, and updating the next_* and avail_* values accordingly.
+ The application can consume the uncompressed output when it wants, for
+ example when the output buffer is full (avail_out == 0), or after each
+ call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+ must be called again after making room in the output buffer because there
+ might be more output pending.
+
+ The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
+ Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
+ output as possible to the output buffer. Z_BLOCK requests that inflate() stop
+ if and when it get to the next deflate block boundary. When decoding the zlib
+ or gzip format, this will cause inflate() to return immediately after the
+ header and before the first block. When doing a raw inflate, inflate() will
+ go ahead and process the first block, and will return when it gets to the end
+ of that block, or when it runs out of data.
+
+ The Z_BLOCK option assists in appending to or combining deflate streams.
+ Also to assist in this, on return inflate() will set strm->data_type to the
+ number of unused bits in the last byte taken from strm->next_in, plus 64
+ if inflate() is currently decoding the last block in the deflate stream,
+ plus 128 if inflate() returned immediately after decoding an end-of-block
+ code or decoding the complete header up to just before the first byte of the
+ deflate stream. The end-of-block will not be indicated until all of the
+ uncompressed data from that block has been written to strm->next_out. The
+ number of unused bits may in general be greater than seven, except when
+ bit 7 of data_type is set, in which case the number of unused bits will be
+ less than eight.
+
+ inflate() should normally be called until it returns Z_STREAM_END or an
+ error. However if all decompression is to be performed in a single step
+ (a single call of inflate), the parameter flush should be set to
+ Z_FINISH. In this case all pending input is processed and all pending
+ output is flushed; avail_out must be large enough to hold all the
+ uncompressed data. (The size of the uncompressed data may have been saved
+ by the compressor for this purpose.) The next operation on this stream must
+ be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+ is never required, but can be used to inform inflate that a faster approach
+ may be used for the single inflate() call.
+
+ In this implementation, inflate() always flushes as much output as
+ possible to the output buffer, and always uses the faster approach on the
+ first call. So the only effect of the flush parameter in this implementation
+ is on the return value of inflate(), as noted below, or when it returns early
+ because Z_BLOCK is used.
+
+ If a preset dictionary is needed after this call (see inflateSetDictionary
+ below), inflate sets strm->adler to the adler32 checksum of the dictionary
+ chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+ strm->adler to the adler32 checksum of all output produced so far (that is,
+ total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+ below. At the end of the stream, inflate() checks that its computed adler32
+ checksum is equal to that saved by the compressor and returns Z_STREAM_END
+ only if the checksum is correct.
+
+ inflate() will decompress and check either zlib-wrapped or gzip-wrapped
+ deflate data. The header type is detected automatically. Any information
+ contained in the gzip header is not retained, so applications that need that
+ information should instead use raw inflate, see inflateInit2() below, or
+ inflateBack() and perform their own processing of the gzip header and
+ trailer.
+
+ inflate() returns Z_OK if some progress has been made (more input processed
+ or more output produced), Z_STREAM_END if the end of the compressed data has
+ been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+ preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+ corrupted (input stream not conforming to the zlib format or incorrect check
+ value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+ if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
+ Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+ output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
+ inflate() can be called again with more input and more output space to
+ continue decompressing. If Z_DATA_ERROR is returned, the application may then
+ call inflateSync() to look for a good compression block if a partial recovery
+ of the data is desired.
+*/
+
+
+ZEXTERN int TQ_ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+ All dynamically allocated data structures for this stream are freed.
+ This function discards any unprocessed input and does not flush any
+ pending output.
+
+ inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+ was inconsistent. In the error case, msg may be set but then points to a
+ static string (which must not be deallocated).
+*/
+
+ /* Advanced functions */
+
+/*
+ The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+ int level,
+ int method,
+ int windowBits,
+ int memLevel,
+ int strategy));
+
+ This is another version of deflateInit with more compression options. The
+ fields next_in, zalloc, zfree and opaque must be initialized before by
+ the caller.
+
+ The method parameter is the compression method. It must be Z_DEFLATED in
+ this version of the library.
+
+ The windowBits parameter is the base two logarithm of the window size
+ (the size of the history buffer). It should be in the range 8..15 for this
+ version of the library. Larger values of this parameter result in better
+ compression at the expense of memory usage. The default value is 15 if
+ deflateInit is used instead.
+
+ windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
+ determines the window size. deflate() will then generate raw deflate data
+ with no zlib header or trailer, and will not compute an adler32 check value.
+
+ windowBits can also be greater than 15 for optional gzip encoding. Add
+ 16 to windowBits to write a simple gzip header and trailer around the
+ compressed data instead of a zlib wrapper. The gzip header will have no
+ file name, no extra data, no comment, no modification time (set to zero),
+ no header crc, and the operating system will be set to 255 (unknown). If a
+ gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+ The memLevel parameter specifies how much memory should be allocated
+ for the internal compression state. memLevel=1 uses minimum memory but
+ is slow and reduces compression ratio; memLevel=9 uses maximum memory
+ for optimal speed. The default value is 8. See zconf.h for total memory
+ usage as a function of windowBits and memLevel.
+
+ The strategy parameter is used to tune the compression algorithm. Use the
+ value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+ filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+ string match), or Z_RLE to limit match distances to one (run-length
+ encoding). Filtered data consists mostly of small values with a somewhat
+ random distribution. In this case, the compression algorithm is tuned to
+ compress them better. The effect of Z_FILTERED is to force more Huffman
+ coding and less string matching; it is somewhat intermediate between
+ Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
+ Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
+ parameter only affects the compression ratio but not the correctness of the
+ compressed output even if it is not set appropriately.
+
+ deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+ method). msg is set to null if there is no error message. deflateInit2 does
+ not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int TQ_ZEXPORT deflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the compression dictionary from the given byte sequence
+ without producing any compressed output. This function must be called
+ immediately after deflateInit, deflateInit2 or deflateReset, before any
+ call of deflate. The compressor and decompressor must use exactly the same
+ dictionary (see inflateSetDictionary).
+
+ The dictionary should consist of strings (byte sequences) that are likely
+ to be encountered later in the data to be compressed, with the most commonly
+ used strings preferably put towards the end of the dictionary. Using a
+ dictionary is most useful when the data to be compressed is short and can be
+ predicted with good accuracy; the data can then be compressed better than
+ with the default empty dictionary.
+
+ Depending on the size of the compression data structures selected by
+ deflateInit or deflateInit2, a part of the dictionary may in effect be
+ discarded, for example if the dictionary is larger than the window size in
+ deflate or deflate2. Thus the strings most likely to be useful should be
+ put at the end of the dictionary, not at the front.
+
+ Upon return of this function, strm->adler is set to the adler32 value
+ of the dictionary; the decompressor may later use this value to determine
+ which dictionary has been used by the compressor. (The adler32 value
+ applies to the whole dictionary even if only a subset of the dictionary is
+ actually used by the compressor.) If a raw deflate was requested, then the
+ adler32 value is not computed and strm->adler is not set.
+
+ deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent (for example if deflate has already been called for this stream
+ or if the compression method is bsort). deflateSetDictionary does not
+ perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int TQ_ZEXPORT deflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when several compression strategies will be
+ tried, for example when there are several ways of pre-processing the input
+ data with a filter. The streams that will be discarded should then be freed
+ by calling deflateEnd. Note that deflateCopy duplicates the internal
+ compression state which can be quite large, so this strategy is slow and
+ can consume lots of memory.
+
+ deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int TQ_ZEXPORT deflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to deflateEnd followed by deflateInit,
+ but does not free and reallocate all the internal compression state.
+ The stream will keep the same compression level and any other attributes
+ that may have been set by deflateInit2.
+
+ deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int TQ_ZEXPORT deflateParams OF((z_streamp strm,
+ int level,
+ int strategy));
+/*
+ Dynamically update the compression level and compression strategy. The
+ interpretation of level and strategy is as in deflateInit2. This can be
+ used to switch between compression and straight copy of the input data, or
+ to switch to a different kind of input data requiring a different
+ strategy. If the compression level is changed, the input available so far
+ is compressed with the old level (and may be flushed); the new level will
+ take effect only at the next call of deflate().
+
+ Before the call of deflateParams, the stream state must be set as for
+ a call of deflate(), since the currently available input may have to
+ be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+ deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+ stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+ if strm->avail_out was zero.
+*/
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+ uLong sourceLen));
+/*
+ deflateBound() returns an upper bound on the compressed size after
+ deflation of sourceLen bytes. It must be called after deflateInit()
+ or deflateInit2(). This would be used to allocate an output buffer
+ for deflation in a single pass, and so would be called before deflate().
+*/
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+ int bits,
+ int value));
+/*
+ deflatePrime() inserts bits in the deflate output stream. The intent
+ is that this function is used to start off the deflate output with the
+ bits leftover from a previous deflate stream when appending to it. As such,
+ this function can only be used for raw deflate, and must be used before the
+ first deflate() call after a deflateInit2() or deflateReset(). bits must be
+ less than or equal to 16, and that many of the least significant bits of
+ value will be inserted in the output.
+
+ deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+ int windowBits));
+
+ This is another version of inflateInit with an extra parameter. The
+ fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+ before by the caller.
+
+ The windowBits parameter is the base two logarithm of the maximum window
+ size (the size of the history buffer). It should be in the range 8..15 for
+ this version of the library. The default value is 15 if inflateInit is used
+ instead. windowBits must be greater than or equal to the windowBits value
+ provided to deflateInit2() while compressing, or it must be equal to 15 if
+ deflateInit2() was not used. If a compressed stream with a larger window
+ size is given as input, inflate() will return with the error code
+ Z_DATA_ERROR instead of trying to allocate a larger window.
+
+ windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
+ determines the window size. inflate() will then process raw deflate data,
+ not looking for a zlib or gzip header, not generating a check value, and not
+ looking for any check values for comparison at the end of the stream. This
+ is for use with other formats that use the deflate compressed data format
+ such as zip. Those formats provide their own check values. If a custom
+ format is developed using the raw deflate format for compressed data, it is
+ recommended that a check value such as an adler32 or a crc32 be applied to
+ the uncompressed data as is done in the zlib, gzip, and zip formats. For
+ most applications, the zlib format should be used as is. Note that comments
+ above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+ windowBits can also be greater than 15 for optional gzip decoding. Add
+ 32 to windowBits to enable zlib and gzip decoding with automatic header
+ detection, or add 16 to decode only the gzip format (the zlib format will
+ return a Z_DATA_ERROR. If a gzip stream is being decoded, strm->adler is
+ a crc32 instead of an adler32.
+
+ inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
+ memLevel). msg is set to null if there is no error message. inflateInit2
+ does not perform any decompression apart from reading the zlib header if
+ present: this will be done by inflate(). (So next_in and avail_in may be
+ modified, but next_out and avail_out are unchanged.)
+*/
+
+ZEXTERN int TQ_ZEXPORT inflateSetDictionary OF((z_streamp strm,
+ const Bytef *dictionary,
+ uInt dictLength));
+/*
+ Initializes the decompression dictionary from the given uncompressed byte
+ sequence. This function must be called immediately after a call of inflate
+ if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
+ can be determined from the adler32 value returned by this call of
+ inflate. The compressor and decompressor must use exactly the same
+ dictionary (see deflateSetDictionary).
+
+ inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+ parameter is invalid (such as NULL dictionary) or the stream state is
+ inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+ expected one (incorrect adler32 value). inflateSetDictionary does not
+ perform any decompression: this will be done by subsequent calls of
+ inflate().
+*/
+
+ZEXTERN int TQ_ZEXPORT inflateSync OF((z_streamp strm));
+/*
+ Skips invalid compressed data until a full flush point (see above the
+ description of deflate with Z_FULL_FLUSH) can be found, or until all
+ available input is skipped. No output is provided.
+
+ inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+ if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+ or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+ case, the application may save the current current value of total_in which
+ indicates where valid compressed data was found. In the error case, the
+ application may repeatedly call inflateSync, providing more input each time,
+ until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+ z_streamp source));
+/*
+ Sets the destination stream as a complete copy of the source stream.
+
+ This function can be useful when randomly accessing a large stream. The
+ first pass through the stream can periodically record the inflate state,
+ allowing restarting inflate at those points when randomly accessing the
+ stream.
+
+ inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+ (such as zalloc being NULL). msg is left unchanged in both source and
+ destination.
+*/
+
+ZEXTERN int TQ_ZEXPORT inflateReset OF((z_streamp strm));
+/*
+ This function is equivalent to inflateEnd followed by inflateInit,
+ but does not free and reallocate all the internal decompression state.
+ The stream will keep attributes that may have been set by inflateInit2.
+
+ inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+ stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_stream FAR *strm, int windowBits,
+ unsigned char FAR *window));
+
+ Initialize the internal stream state for decompression using inflateBack()
+ calls. The fields zalloc, zfree and opaque in strm must be initialized
+ before the call. If zalloc and zfree are Z_NULL, then the default library-
+ derived memory allocation routines are used. windowBits is the base two
+ logarithm of the window size, in the range 8..15. window is a caller
+ supplied buffer of that size. Except for special applications where it is
+ assured that deflate was used with small window sizes, windowBits must be 15
+ and a 32K byte window must be supplied to be able to decompress general
+ deflate streams.
+
+ See inflateBack() for the usage of these routines.
+
+ inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+ the paramaters are invalid, Z_MEM_ERROR if the internal state could not
+ be allocated, or Z_VERSION_ERROR if the version of the library does not
+ match the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_stream FAR *strm,
+ in_func in, void FAR *in_desc,
+ out_func out, void FAR *out_desc));
+/*
+ inflateBack() does a raw inflate with a single call using a call-back
+ interface for input and output. This is more efficient than inflate() for
+ file i/o applications in that it avoids copying between the output and the
+ sliding window by simply making the window itself the output buffer. This
+ function trusts the application to not change the output buffer passed by
+ the output function, at least until inflateBack() returns.
+
+ inflateBackInit() must be called first to allocate the internal state
+ and to initialize the state with the user-provided window buffer.
+ inflateBack() may then be used multiple times to inflate a complete, raw
+ deflate stream with each call. inflateBackEnd() is then called to free
+ the allocated state.
+
+ A raw deflate stream is one with no zlib or gzip header or trailer.
+ This routine would normally be used in a utility that reads zip or gzip
+ files and writes out uncompressed files. The utility would decode the
+ header and process the trailer on its own, hence this routine expects
+ only the raw deflate stream to decompress. This is different from the
+ normal behavior of inflate(), which expects either a zlib or gzip header and
+ trailer around the deflate stream.
+
+ inflateBack() uses two subroutines supplied by the caller that are then
+ called by inflateBack() for input and output. inflateBack() calls those
+ routines until it reads a complete deflate stream and writes out all of the
+ uncompressed data, or until it encounters an error. The function's
+ parameters and return types are defined above in the in_func and out_func
+ typedefs. inflateBack() will call in(in_desc, &buf) which should return the
+ number of bytes of provided input, and a pointer to that input in buf. If
+ there is no input available, in() must return zero--buf is ignored in that
+ case--and inflateBack() will return a buffer error. inflateBack() will call
+ out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
+ should return zero on success, or non-zero on failure. If out() returns
+ non-zero, inflateBack() will return with an error. Neither in() nor out()
+ are permitted to change the contents of the window provided to
+ inflateBackInit(), which is also the buffer that out() uses to write from.
+ The length written by out() will be at most the window size. Any non-zero
+ amount of input may be provided by in().
+
+ For convenience, inflateBack() can be provided input on the first call by
+ setting strm->next_in and strm->avail_in. If that input is exhausted, then
+ in() will be called. Therefore strm->next_in must be initialized before
+ calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
+ immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
+ must also be initialized, and then if strm->avail_in is not zero, input will
+ initially be taken from strm->next_in[0 .. strm->avail_in - 1].
+
+ The in_desc and out_desc parameters of inflateBack() is passed as the
+ first parameter of in() and out() respectively when they are called. These
+ descriptors can be optionally used to pass any information that the caller-
+ supplied in() and out() functions need to do their job.
+
+ On return, inflateBack() will set strm->next_in and strm->avail_in to
+ pass back any unused input that was provided by the last in() call. The
+ return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+ if in() or out() returned an error, Z_DATA_ERROR if there was a format
+ error in the deflate stream (in which case strm->msg is set to indicate the
+ nature of the error), or Z_STREAM_ERROR if the stream was not properly
+ initialized. In the case of Z_BUF_ERROR, an input or output error can be
+ distinguished using strm->next_in which will be Z_NULL only if in() returned
+ an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
+ out() returning non-zero. (in() will always be called before out(), so
+ strm->next_in is assured to be defined if out() returns non-zero.) Note
+ that inflateBack() cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_stream FAR *strm));
+/*
+ All memory allocated by inflateBackInit() is freed.
+
+ inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+ state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+ Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+ 1.0: size of uInt
+ 3.2: size of uLong
+ 5.4: size of voidpf (pointer)
+ 7.6: size of z_off_t
+
+ Compiler, assembler, and debug options:
+ 8: DEBUG
+ 9: ASMV or ASMINF -- use ASM code
+ 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+ 11: 0 (reserved)
+
+ One-time table building (smaller code, but not thread-safe if true):
+ 12: BUILDFIXED -- build static block decoding tables when needed
+ 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+ 14,15: 0 (reserved)
+
+ Library content (indicates missing functionality):
+ 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+ deflate code when not needed)
+ 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+ and decode gzip streams (to avoid linking crc code)
+ 18-19: 0 (reserved)
+
+ Operation variations (changes in library functionality):
+ 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+ 21: FASTEST -- deflate algorithm with only one, lowest compression level
+ 22,23: 0 (reserved)
+
+ The sprintf variant used by gzprintf (zero is best):
+ 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+ 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+ 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+ Remainder:
+ 27-31: 0 (reserved)
+ */
+
+
+ /* utility functions */
+
+/*
+ The following utility functions are implemented on top of the
+ basic stream-oriented functions. To simplify the interface, some
+ default options are assumed (compression level and memory usage,
+ standard memory allocation functions). The source code of these
+ utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int TQ_ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Compresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be at least the value returned
+ by compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+ This function can be used to compress a whole file at once if the
+ input file is mmap'ed.
+ compress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer.
+*/
+
+ZEXTERN int TQ_ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen,
+ int level));
+/*
+ Compresses the source buffer into the destination buffer. The level
+ parameter has the same meaning as in deflateInit. sourceLen is the byte
+ length of the source buffer. Upon entry, destLen is the total size of the
+ destination buffer, which must be at least the value returned by
+ compressBound(sourceLen). Upon exit, destLen is the actual size of the
+ compressed buffer.
+
+ compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+ memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+ Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+ compressBound() returns an upper bound on the compressed size after
+ compress() or compress2() on sourceLen bytes. It would be used before
+ a compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int TQ_ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
+ const Bytef *source, uLong sourceLen));
+/*
+ Decompresses the source buffer into the destination buffer. sourceLen is
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be large enough to hold the
+ entire uncompressed data. (The size of the uncompressed data must have
+ been saved previously by the compressor and transmitted to the decompressor
+ by some mechanism outside the scope of this compression library.)
+ Upon exit, destLen is the actual size of the compressed buffer.
+ This function can be used to decompress a whole file at once if the
+ input file is mmap'ed.
+
+ uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+ enough memory, Z_BUF_ERROR if there was not enough room in the output
+ buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile TQ_ZEXPORT gzopen OF((const char *path, const char *mode));
+/*
+ Opens a gzip (.gz) file for reading or writing. The mode parameter
+ is as in fopen ("rb" or "wb") but can also include a compression level
+ ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+ Huffman only compression as in "wb1h", or 'R' for run-length encoding
+ as in "wb1R". (See the description of deflateInit2 for more information
+ about the strategy parameter.)
+
+ gzopen can be used to read a file which is not in gzip format; in this
+ case gzread will directly read from the file without decompression.
+
+ gzopen returns NULL if the file could not be opened or if there was
+ insufficient memory to allocate the (de)compression state; errno
+ can be checked to distinguish the two cases (if errno is zero, the
+ zlib error is Z_MEM_ERROR). */
+
+ZEXTERN gzFile TQ_ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+ gzdopen() associates a gzFile with the file descriptor fd. File
+ descriptors are obtained from calls like open, dup, creat, pipe or
+ fileno (in the file has been previously opened with fopen).
+ The mode parameter is as in gzopen.
+ The next call of gzclose on the returned gzFile will also close the
+ file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+ descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+ gzdopen returns NULL if there was insufficient memory to allocate
+ the (de)compression state.
+*/
+
+ZEXTERN int TQ_ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+ Dynamically update the compression level or strategy. See the description
+ of deflateInit2 for the meaning of these parameters.
+ gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+ opened for writing.
+*/
+
+ZEXTERN int TQ_ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+ Reads the given number of uncompressed bytes from the compressed file.
+ If the input file was not in gzip format, gzread copies the given number
+ of bytes into the buffer.
+ gzread returns the number of uncompressed bytes actually read (0 for
+ end of file, -1 for error). */
+
+ZEXTERN int TQ_ZEXPORT gzwrite OF((gzFile file,
+ voidpc buf, unsigned len));
+/*
+ Writes the given number of uncompressed bytes into the compressed file.
+ gzwrite returns the number of uncompressed bytes actually written
+ (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
+/*
+ Converts, formats, and writes the args to the compressed file under
+ control of the format string, as in fprintf. gzprintf returns the number of
+ uncompressed bytes actually written (0 in case of error). The number of
+ uncompressed bytes written is limited to 4095. The caller should assure that
+ this limit is not exceeded. If it is exceeded, then gzprintf() will return
+ return an error (0) with nothing written. In this case, there may also be a
+ buffer overflow with unpredictable consequences, which is possible only if
+ zlib was compiled with the insecure functions sprintf() or vsprintf()
+ because the secure snprintf() or vsnprintf() functions were not available.
+*/
+
+ZEXTERN int TQ_ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+ Writes the given null-terminated string to the compressed file, excluding
+ the terminating null character.
+ gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN TQ_ZEXPORT char * gzgets OF((gzFile file, char *buf, int len));
+/*
+ Reads bytes from the compressed file until len-1 characters are read, or
+ a newline character is read and transferred to buf, or an end-of-file
+ condition is encountered. The string is then terminated with a null
+ character.
+ gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int TQ_ZEXPORT gzputc OF((gzFile file, int c));
+/*
+ Writes c, converted to an unsigned char, into the compressed file.
+ gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int TQ_ZEXPORT gzgetc OF((gzFile file));
+/*
+ Reads one byte from the compressed file. gzgetc returns this byte
+ or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+ Push one character back onto the stream to be read again later.
+ Only one character of push-back is allowed. gzungetc() returns the
+ character pushed, or -1 on failure. gzungetc() will fail if a
+ character has been pushed but not read yet, or if c is -1. The pushed
+ character will be discarded if the stream is repositioned with gzseek()
+ or gzrewind().
+*/
+
+ZEXTERN int TQ_ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+ Flushes all pending output into the compressed file. The parameter
+ flush is as in the deflate() function. The return value is the zlib
+ error number (see function gzerror below). gzflush returns Z_OK if
+ the flush parameter is Z_FINISH and all output could be flushed.
+ gzflush should be called only when strictly necessary because it can
+ degrade compression.
+*/
+
+ZEXTERN z_off_t TQ_ZEXPORT gzseek OF((gzFile file,
+ z_off_t offset, int whence));
+/*
+ Sets the starting position for the next gzread or gzwrite on the
+ given compressed file. The offset represents a number of bytes in the
+ uncompressed data stream. The whence parameter is defined as in lseek(2);
+ the value SEEK_END is not supported.
+ If the file is opened for reading, this function is emulated but can be
+ extremely slow. If the file is opened for writing, only forward seeks are
+ supported; gzseek then compresses a sequence of zeroes up to the new
+ starting position.
+
+ gzseek returns the resulting offset location as measured in bytes from
+ the beginning of the uncompressed stream, or -1 in case of error, in
+ particular if the file is opened for writing and the new starting position
+ would be before the current position.
+*/
+
+ZEXTERN int TQ_ZEXPORT gzrewind OF((gzFile file));
+/*
+ Rewinds the given file. This function is supported only for reading.
+
+ gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t TQ_ZEXPORT gztell OF((gzFile file));
+/*
+ Returns the starting position for the next gzread or gzwrite on the
+ given compressed file. This position represents a number of bytes in the
+ uncompressed data stream.
+
+ gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int TQ_ZEXPORT gzeof OF((gzFile file));
+/*
+ Returns 1 when EOF has previously been detected reading the given
+ input stream, otherwise zero.
+*/
+
+ZEXTERN int TQ_ZEXPORT gzclose OF((gzFile file));
+/*
+ Flushes all pending output if necessary, closes the compressed file
+ and deallocates all the (de)compression state. The return value is the zlib
+ error number (see function gzerror below).
+*/
+
+ZEXTERN TQ_ZEXPORT const char * gzerror OF((gzFile file, int *errnum));
+/*
+ Returns the error message for the last error which occurred on the
+ given compressed file. errnum is set to zlib error number. If an
+ error occurred in the file system and not in the compression library,
+ errnum is set to Z_ERRNO and the application may consult errno
+ to get the exact error code.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+ Clears the error and end-of-file flags for file. This is analogous to the
+ clearerr() function in stdio. This is useful for continuing to read a gzip
+ file that is being written concurrently.
+*/
+
+ /* checksum functions */
+
+/*
+ These functions are not related to compression but are exported
+ anyway because they might be useful in applications using the
+ compression library.
+*/
+
+ZEXTERN uLong TQ_ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+
+/*
+ Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+ return the updated checksum. If buf is NULL, this function returns
+ the required initial value for the checksum.
+ An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+ much faster. Usage example:
+
+ uLong adler = adler32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ adler = adler32(adler, buffer, length);
+ }
+ if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong TQ_ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
+/*
+ Update a running crc with the bytes buf[0..len-1] and return the updated
+ crc. If buf is NULL, this function returns the required initial value
+ for the crc. Pre- and post-conditioning (one's complement) is performed
+ within this function so it shouldn't be done by the application.
+ Usage example:
+
+ uLong crc = crc32(0L, Z_NULL, 0);
+
+ while (read_buffer(buffer, length) != EOF) {
+ crc = crc32(crc, buffer, length);
+ }
+ if (crc != original_crc) error();
+*/
+
+
+ /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int TQ_ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+ const char *version, int stream_size));
+ZEXTERN int TQ_ZEXPORT inflateInit_ OF((z_streamp strm,
+ const char *version, int stream_size));
+ZEXTERN int TQ_ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
+ int windowBits, int memLevel,
+ int strategy, const char *version,
+ int stream_size));
+ZEXTERN int TQ_ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
+ const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits,
+ unsigned char FAR *window,
+ const char *version,
+ int stream_size));
+#define deflateInit(strm, level) \
+ deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+ inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+ (strategy), ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+ inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+ inflateBackInit_((strm), (windowBits), (window), \
+ ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+ struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN TQ_ZEXPORT const char * zError OF((int));
+ZEXTERN int TQ_ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN TQ_ZEXPORT const uLongf * get_crc_table OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/zutil.c b/tqtinterface/qt4/src/3rdparty/zlib/zutil.c
new file mode 100644
index 0000000..0ef4f99
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/zutil.c
@@ -0,0 +1,319 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#ifndef NO_DUMMY_DECL
+struct internal_state {int dummy;}; /* for buggy compilers */
+#endif
+
+#ifndef STDC
+extern void exit OF((int));
+#endif
+
+const char * const z_errmsg[10] = {
+"need dictionary", /* Z_NEED_DICT 2 */
+"stream end", /* Z_STREAM_END 1 */
+"", /* Z_OK 0 */
+"file error", /* Z_ERRNO (-1) */
+"stream error", /* Z_STREAM_ERROR (-2) */
+"data error", /* Z_DATA_ERROR (-3) */
+"insufficient memory", /* Z_MEM_ERROR (-4) */
+"buffer error", /* Z_BUF_ERROR (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+ return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+ uLong flags;
+
+ flags = 0;
+ switch (sizeof(uInt)) {
+ case 2: break;
+ case 4: flags += 1; break;
+ case 8: flags += 2; break;
+ default: flags += 3;
+ }
+ switch (sizeof(uLong)) {
+ case 2: break;
+ case 4: flags += 1 << 2; break;
+ case 8: flags += 2 << 2; break;
+ default: flags += 3 << 2;
+ }
+ switch (sizeof(voidpf)) {
+ case 2: break;
+ case 4: flags += 1 << 4; break;
+ case 8: flags += 2 << 4; break;
+ default: flags += 3 << 4;
+ }
+ switch (sizeof(z_off_t)) {
+ case 2: break;
+ case 4: flags += 1 << 6; break;
+ case 8: flags += 2 << 6; break;
+ default: flags += 3 << 6;
+ }
+#ifdef DEBUG
+ flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+ flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+ flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+ flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+ flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+ flags += 1 << 16;
+#endif
+#ifdef NO_GZIP
+ flags += 1 << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+ flags += 1 << 20;
+#endif
+#ifdef FASTEST
+ flags += 1 << 21;
+#endif
+#ifdef STDC
+# ifdef NO_vsnprintf
+ flags += 1 << 25;
+# ifdef HAS_vsprintf_void
+ flags += 1 << 26;
+# endif
+# else
+# ifdef HAS_vsnprintf_void
+ flags += 1 << 26;
+# endif
+# endif
+#else
+ flags += 1 << 24;
+# ifdef NO_snprintf
+ flags += 1 << 25;
+# ifdef HAS_sprintf_void
+ flags += 1 << 26;
+# endif
+# else
+# ifdef HAS_snprintf_void
+ flags += 1 << 26;
+# endif
+# endif
+#endif
+ return flags;
+}
+
+#ifdef DEBUG
+
+# ifndef verbose
+# define verbose 0
+# endif
+int z_verbose = verbose;
+
+void z_error (m)
+ char *m;
+{
+ fprintf(stderr, "%s\n", m);
+ exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+ int err;
+{
+ return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+ /* does not exist on WCE */
+ int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+ Bytef* dest;
+ const Bytef* source;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = *source++; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+ const Bytef* s1;
+ const Bytef* s2;
+ uInt len;
+{
+ uInt j;
+
+ for (j = 0; j < len; j++) {
+ if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+ }
+ return 0;
+}
+
+void zmemzero(dest, len)
+ Bytef* dest;
+ uInt len;
+{
+ if (len == 0) return;
+ do {
+ *dest++ = 0; /* ??? to be unrolled */
+ } while (--len != 0);
+}
+#endif
+
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+ voidpf org_ptr;
+ voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ voidpf buf = opaque; /* just to make some compilers happy */
+ ulg bsize = (ulg)items*size;
+
+ /* If we allocate less than 65520 bytes, we assume that farmalloc
+ * will return a usable pointer which doesn't have to be normalized.
+ */
+ if (bsize < 65520L) {
+ buf = farmalloc(bsize);
+ if (*(ush*)&buf != 0) return buf;
+ } else {
+ buf = farmalloc(bsize + 16L);
+ }
+ if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+ table[next_ptr].org_ptr = buf;
+
+ /* Normalize the pointer to seg:0 */
+ *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+ *(ush*)&buf = 0;
+ table[next_ptr++].new_ptr = buf;
+ return buf;
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ int n;
+ if (*(ush*)&ptr != 0) { /* object < 64K */
+ farfree(ptr);
+ return;
+ }
+ /* Find the original pointer */
+ for (n = 0; n < next_ptr; n++) {
+ if (ptr != table[n].new_ptr) continue;
+
+ farfree(table[n].org_ptr);
+ while (++n < next_ptr) {
+ table[n-1] = table[n];
+ }
+ next_ptr--;
+ return;
+ }
+ ptr = opaque; /* just to make some compilers happy */
+ Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+# define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+# define _halloc halloc
+# define _hfree hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ return _halloc((long)items, size);
+}
+
+void zcfree (voidpf opaque, voidpf ptr)
+{
+ if (opaque) opaque = 0; /* to make compiler happy */
+ _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp malloc OF((uInt size));
+extern voidp calloc OF((uInt items, uInt size));
+extern void free OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+ voidpf opaque;
+ unsigned items;
+ unsigned size;
+{
+ if (opaque) items += size - size; /* make compiler happy */
+ return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+ (voidpf)calloc(items, size);
+}
+
+void zcfree (opaque, ptr)
+ voidpf opaque;
+ voidpf ptr;
+{
+ free(ptr);
+ if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/tqtinterface/qt4/src/3rdparty/zlib/zutil.h b/tqtinterface/qt4/src/3rdparty/zlib/zutil.h
new file mode 100644
index 0000000..fbf8652
--- /dev/null
+++ b/tqtinterface/qt4/src/3rdparty/zlib/zutil.h
@@ -0,0 +1,263 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+ part of the implementation of the compression library and is
+ subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+#ifdef STDC
+# include <stddef.h>
+# include <string.h>
+# include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+ extern int errno;
+#else
+# include <errno.h>
+#endif
+
+#ifndef local
+# define local static
+#endif
+/* compile with -Dlocal if your debugger can't tqfind static symbols */
+
+typedef unsigned char uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long ulg;
+
+extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+ return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+ /* common constants */
+
+#ifndef DEF_WBITS
+# define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+# define DEF_MEM_LEVEL 8
+#else
+# define DEF_MEM_LEVEL MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES 2
+/* The three kinds of block type */
+
+#define MIN_MATCH 3
+#define MAX_MATCH 258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+ /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+# define OS_CODE 0x00
+# if defined(__TURBOC__) || defined(__BORLANDC__)
+# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+ /* Allow compilation with ANSI keywords only enabled */
+ void _Cdecl farfree( void *block );
+ void *_Cdecl farmalloc( unsigned long nbytes );
+# else
+# include <alloc.h>
+# endif
+# else /* MSC or DJGPP */
+# include <malloc.h>
+# endif
+#endif
+
+#ifdef AMIGA
+# define OS_CODE 0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+# define OS_CODE 0x02
+# define F_OPEN(name, mode) \
+ fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+# define OS_CODE 0x05
+#endif
+
+#ifdef OS2
+# define OS_CODE 0x06
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+# define OS_CODE 0x07
+# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+# include <unix.h> /* for fdopen */
+# else
+# ifndef fdopen
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# endif
+# endif
+#endif
+
+#ifdef TOPS20
+# define OS_CODE 0x0a
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
+# define OS_CODE 0x0b
+# endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+# define OS_CODE 0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+# if defined(_WIN32_WCE)
+# define fdopen(fd,mode) NULL /* No fdopen() */
+# ifndef _PTRDIFF_T_DEFINED
+ typedef int ptrdiff_t;
+# define _PTRDIFF_T_DEFINED
+# endif
+# else
+# define fdopen(fd,type) _fdopen(fd,type)
+# endif
+#endif
+
+ /* common defaults */
+
+#ifndef OS_CODE
+# define OS_CODE 0x03 /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+# define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+ /* functions */
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+#if defined(__CYGWIN__)
+# ifndef HAVE_VSNPRINTF
+# define HAVE_VSNPRINTF
+# endif
+#endif
+#ifndef HAVE_VSNPRINTF
+# ifdef MSDOS
+ /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+ but for now we just assume it doesn't. */
+# define NO_vsnprintf
+# endif
+# ifdef __TURBOC__
+# define NO_vsnprintf
+# endif
+# ifdef WIN32
+ /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+# if !defined(vsnprintf) && !defined(NO_vsnprintf)
+# define vsnprintf _vsnprintf
+# endif
+# endif
+# ifdef __SASC
+# define NO_vsnprintf
+# endif
+#endif
+#ifdef VMS
+# define NO_vsnprintf
+#endif
+
+#ifdef HAVE_STRERROR
+# ifndef VMS
+ extern char *strerror OF((int));
+# endif
+# define zstrerror(errnum) strerror(errnum)
+#else
+# define zstrerror(errnum) ""
+#endif
+
+#if defined(pyr)
+# define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+ * You may have to use the same strategy for Borland C (untested).
+ * The __SC__ check is for Symantec.
+ */
+# define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+# define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+# define zmemcpy _fmemcpy
+# define zmemcmp _fmemcmp
+# define zmemzero(dest, len) _fmemset(dest, 0, len)
+# else
+# define zmemcpy memcpy
+# define zmemcmp memcmp
+# define zmemzero(dest, len) memset(dest, 0, len)
+# endif
+#else
+ extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+ extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+ extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+# include <stdio.h>
+ extern int z_verbose;
+ extern void z_error OF((char *m));
+# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+# define Trace(x) {if (z_verbose>=0) fprintf x ;}
+# define Tracev(x) {if (z_verbose>0) fprintf x ;}
+# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+# define Assert(cond,msg)
+# define Trace(x)
+# define Tracev(x)
+# define Tracevv(x)
+# define Tracec(c,x)
+# define Tracecv(c,x)
+#endif
+
+
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void zcfree OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+ (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* ZUTIL_H */
diff --git a/tqtinterface/qt4/src/attic/README b/tqtinterface/qt4/src/attic/README
new file mode 100644
index 0000000..1d75931
--- /dev/null
+++ b/tqtinterface/qt4/src/attic/README
@@ -0,0 +1,6 @@
+This directory tqcontains classes that has been obsoleted and moved out
+of the Qt API.
+
+To use these classes, simply include them in your project. Remember to
+rename the class references in your own code.
+
diff --git a/tqtinterface/qt4/src/attic/qtmultilineedit.cpp b/tqtinterface/qt4/src/attic/qtmultilineedit.cpp
new file mode 100644
index 0000000..203ed56
--- /dev/null
+++ b/tqtinterface/qt4/src/attic/qtmultilineedit.cpp
@@ -0,0 +1,4236 @@
+/**********************************************************************
+**
+** Implementation of TQtMultiLineEdit widget class
+**
+** Created : 961005
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file tqcontains a class moved out of the TQt GUI Toolkit API. It
+** may be used, distributed and modified without limitation.
+**
+**********************************************************************/
+
+#include "tqtmultilineedit.h"
+#ifndef TQT_NO_TQTMULTILINEEDIT
+#include "tqpainter.h"
+#include "tqscrollbar.h"
+#include "tqclipboard.h"
+#include "tqpixmap.h"
+#include "tqregexp.h"
+#include "tqapplication.h"
+#include "tqdragobject.h"
+#include "tqpopupmenu.h"
+#include "tqtimer.h"
+#include "tqdict.h"
+#include "tqcursor.h"
+#ifndef TQT_NO_COMPAT
+#include "tqstyle.h"
+#endif
+
+
+class TQtMultiLineEditCommand
+{
+public:
+ enum Commands { Invalid, Begin, End, Insert, Delete };
+ virtual ~TQtMultiLineEditCommand() {};
+ virtual Commands type() { return Invalid; };
+ virtual int terminator() { return 0; }
+
+ virtual bool merge( TQtMultiLineEditCommand* ) { return FALSE;}
+};
+
+class TQBeginCommand : public TQtMultiLineEditCommand
+{
+
+public:
+ TQBeginCommand() {}
+ int terminator() { return 1; }
+ Commands type() { return Begin; };
+};
+
+class TQEndCommand : public TQtMultiLineEditCommand
+{
+public:
+ TQEndCommand() {}
+ int terminator() { return -1; }
+ Commands type() { return End; };
+};
+
+// TQtMultiLineEditUndoRedo methods
+class TQDelTextCmd : public TQtMultiLineEditCommand
+{
+public:
+ int mOffset;
+ TQString mStr;
+
+ // have to handle deletion of current selection
+ TQDelTextCmd(int offset, const TQString &str )
+ : mOffset( offset ),
+ mStr ( str )
+ {
+ }
+ Commands type() { return Delete; };
+
+ bool merge( TQtMultiLineEditCommand* other)
+ {
+ if ( other->type() == type() ) {
+ TQDelTextCmd* o = (TQDelTextCmd*) other;
+ if ( mOffset + int(mStr.length()) == o->mOffset ) {
+ o->mStr.prepend( mStr );
+ o->mOffset = mOffset;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+
+
+};
+
+class TQInsTextCmd : public TQDelTextCmd
+{
+
+public:
+ TQInsTextCmd(int offset,const TQString &str )
+ : TQDelTextCmd( offset, str )
+ {
+ }
+
+ Commands type() { return Insert; };
+
+ bool merge( TQtMultiLineEditCommand* other)
+ {
+ if ( other->type() == type() ) {
+ TQInsTextCmd* o = (TQInsTextCmd*) other;
+ if ( mOffset == o->mOffset + int(o->mStr.length()) ) {
+ o->mStr += mStr;
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+};
+
+
+/*
+ \class TQtMultiLineEdit qtmultilineedit.h
+
+ \brief The TQtMultiLineEdit widget is a simple editor for inputting text.
+
+ \obsolete
+
+ The TQtMultiLineEdit widget provides multiple line text input and display.
+ It is intended for moderate amounts of text. There are no arbitrary
+ limitations, but if you try to handle megabytes of data, performance
+ will suffer.
+
+ Per default, the edit widget does not perform any word
+ wrapping. This can be adjusted by calling setWordWrap(). Both
+ dynamic wrapping according to the visible width or a fixed number of
+ character or pixels is supported.
+
+ The widget can be used to display text by calling setReadOnly(TRUE).
+
+ The default key bindings are described in keyPressEvent(); they cannot
+ be customized except by inheriting the class.
+
+ <img src=qmlined-m.png> <img src=qmlined-w.png>
+*/
+
+/*
+ \property TQtMultiLineEdit::numLines
+ \brief the number of lines in the multi-line edit
+
+ numLines() returns the number of lines in the editor. The count
+ includes any empty lines at top and bottom, so for an empty editor
+ this method will return 1.
+*/
+/*
+ \property TQtMultiLineEdit::atBeginning
+ \brief whether the cursor is at the beginning
+
+ atBeginning() returns TRUE if the cursor is placed at the
+ beginning of the text.
+*/
+/*
+ \property TQtMultiLineEdit::atEnd
+ \brief whether the cursor is at the end
+
+ atEnd() returns TRUE if the cursor is placed at the end of the text.
+*/
+/*
+ \property TQtMultiLineEdit::maxLineWidth
+ \brief the maximum line width in pixels
+ Returns the width in pixels of the longest text line in this editor.
+*/
+/*
+ \property TQtMultiLineEdit::tqalignment
+ \brief the tqalignment
+
+ Possible values are \c AlignLeft, \c Align(H)Center and \c
+ AlignRight.
+ \sa TQt::AlignmentFlags
+*/
+/*
+ \property TQtMultiLineEdit::edited
+ \brief whether the text had been edited
+
+edited() returns the edited flag of the line edit. If this returns FALSE,
+the contents has not been changed since the construction of the
+TQtMultiLineEdit (or the last call to setEdited( FALSE ), if any). If
+it returns TRUE, the contents have been edited, or setEdited( TRUE )
+has been called.
+
+setEdited() sets the edited flag of this line edit to \e e. The
+edited flag is never read by TQtMultiLineEdit, but is changed to TRUE
+whenever the user changes its contents.
+
+This is useful e.g. for things that need to provide a default value,
+but cannot tqfind the default at once. Just open the widget without the
+best default and when the default is known, check the edited() return
+value and set the line edit's contents if the user has not started
+editing the line edit. Another example is to detect whether the
+contents need saving.
+
+*/
+/*
+ \property TQtMultiLineEdit::echoMode
+ \brief the echo mode
+*/
+/*
+ \property TQtMultiLineEdit::maxLength
+ \brief the maximum length of the text
+
+ The currently set text length limit, or -1 if there is
+ no limit (this is the default).
+
+*/
+/*
+ \property TQtMultiLineEdit::maxLines
+ \brief the maximum number of lines
+ The currently set line limit, or -1 if there is
+ no limit (the default).
+
+ Note that excess lines are deleted from the \e bottom of the
+ lines. If you want teletype behaviour with lines disappearing
+ from the \e top as the limit is exceed, you probably just want
+ to use removeLine(0) prior to adding an excess line.
+
+*/
+/*
+ \property TQtMultiLineEdit::hMargin
+ \brief the horizontal margin
+ The horizontal margin current set. The default is 3.
+*/
+/*
+ \property TQtMultiLineEdit::wordWrap
+ \brief the word wrap mode
+
+ By default, wrapping keeps words intact. To allow breaking within
+ words, set the wrap policy to \c Anywhere (see setWrapPolicy() ).
+
+ The default wrap mode is \c NoWrap.
+
+ \sa wordWrap(), setWrapColumnOrWidth(), setWrapPolicy()
+*/
+/*
+ \property TQtMultiLineEdit::wrapColumnOrWidth
+ \brief the wrap width in columns or pixels
+ The wrap column or wrap width, depending on the word wrap
+ mode.
+ \sa setWordWrap(), setWrapColumnOrWidth()
+*/
+/*
+ \property TQtMultiLineEdit::wrapPolicy
+ \brief the wrap policy mode
+ The default is \c AtWhiteSpace.
+
+*/
+/*
+ \property TQtMultiLineEdit::autoUpdate
+ \brief whether auto update is enabled
+
+ autoUpdate() returns TRUE if the view updates itself automatically
+ whenever it is changed in some way.
+
+ If autoUpdate() is TRUE (this is the default) then the editor updates
+ itself automatically whenever it has changed in some way (generally,
+ when text has been inserted or deleted).
+
+ If autoUpdate() is FALSE, the view does NOT tqrepaint itself, or update
+ its internal state variables itself when it is changed. This can be
+ useful to avoid flicker during large changes, and is singularly
+ useless otherwise: Disable auto-update, do the changes, re-enable
+ auto-update, and call tqrepaint().
+
+ \warning Do not leave the view in this state for a long time
+ (i.e. between events ). If, for example, the user interacts with the
+ view when auto-update is off, strange things can happen.
+
+ Setting auto-update to TRUE does not tqrepaint the view, you must call
+ tqrepaint() to do this (preferable tqrepaint(FALSE) to avoid flicker).
+
+ \sa autoUpdate() tqrepaint()
+
+*/
+/*
+ \property TQtMultiLineEdit::undoEnabled
+ \brief whether undo is enabled
+*/
+/*
+ \property TQtMultiLineEdit::undoDepth
+ \brief the undo depth
+
+ The maximum number of operations that can be stored on the undo stack.
+
+ \sa setUndoDepth()
+*/
+/*
+ \property TQtMultiLineEdit::readOnly
+ \brief whether the multi-line edit is read-only
+*/
+/*
+ \property TQtMultiLineEdit::overWriteMode
+ \brief the overwrite mode
+*/
+/*
+ \property TQtMultiLineEdit::text
+ \brief the multi-line edit's text
+*/
+/*
+ \property TQtMultiLineEdit::length
+ \brief the length of the text
+*/
+
+static const char * const arrow_xpm[] = {
+ " 8 8 2 1",
+ ". c None",
+ "# c #000000",
+ "........",
+ "..####..",
+ "..#####.",
+ ".....##.",
+ ".#..###.",
+ ".#####..",
+ ".####...",
+ ".#####.."
+};
+
+enum {
+ IdUndo,
+ IdRedo,
+#ifndef TQT_NO_CLIPBOARD
+ IdCut,
+ IdCopy,
+ IdPaste,
+ IdPasteSpecial,
+#endif
+ IdClear,
+ IdSelectAll,
+ IdCount
+};
+
+struct TQtMultiLineData
+{
+ TQtMultiLineData() :
+ isHandlingEvent(FALSE),
+ edited(FALSE),
+ maxLineWidth(0),
+ align(TQt::AlignLeft),
+ maxlines(-1),
+ maxlinelen(-1),
+ maxlen(-1),
+ wordwrap( TQtMultiLineEdit::NoWrap ),
+ wrapcol( -1 ),
+ wrappolicy( TQtMultiLineEdit::AtWhiteSpace ),
+ // This doesn't use font bearings, as textWidthWithTabs does that.
+ // This is just an aesthetics value.
+ // It should probably be TQMAX(0,3-fontMetrics().minLeftBearing()) though,
+ // as bearings give some border anyway.
+ lr_marg(3),
+ marg_extra(0),
+ echomode(TQtMultiLineEdit::Normal),
+ val(0),
+ dnd_primed(FALSE),
+ dnd_forcecursor(FALSE),
+ undo( TRUE ),
+ undodepth( 256 )
+ {
+ undoList.setAutoDelete( TRUE );
+ redoList.setAutoDelete( TRUE );
+ clearChartable();
+ }
+ bool isHandlingEvent;
+ bool edited;
+ int maxLineWidth;
+ int scrollTime;
+ int scrollAccel;
+ int align;
+ int numlines;
+ int maxlines;
+ int maxlinelen;
+ int maxlen;
+ TQtMultiLineEdit::WordWrap wordwrap;
+ int wrapcol;
+ TQtMultiLineEdit::WrapPolicy wrappolicy;
+ int lr_marg;
+ int marg_extra;
+ TQtMultiLineEdit::EchoMode echomode;
+ const TQValidator* val;
+
+ bool dnd_primed; // If TRUE, user has pressed
+ bool dnd_forcecursor; // If TRUE show cursor for DND feedback,
+ // even if !hasFocus()
+ TQPtrList<TQtMultiLineEditCommand> undoList;
+ TQPtrList<TQtMultiLineEditCommand> redoList;
+ bool undo;
+ int undodepth;
+ short chartable[256];
+ void clearChartable()
+ {
+ int i = 256;
+ while ( i )
+ chartable[--i] = 0;
+ }
+ TQPixmap arrow;
+ TQPoint dnd_startpos;
+ TQTimer *blinkTimer, *scrollTimer;
+#ifndef TQT_NO_DRAGANDDROP
+ TQTimer *dnd_timer;
+#endif
+};
+
+
+#define CLEAR_UNDO {d->undoList.clear(); emit undoAvailable( FALSE );\
+ d->redoList.clear(); emit redoAvailable( FALSE );}
+
+void TQtMultiLineEdit::addUndoCmd(TQtMultiLineEditCommand* c)
+{
+ if ( d->undoList.isEmpty() )
+ emit undoAvailable(TRUE);
+ else if ( c->merge( d->undoList.last() ) ) {
+ delete c;
+ return;
+ }
+ if ( int(d->undoList.count()) >= d->undodepth )
+ d->undoList.removeFirst();
+ d->undoList.append(c);
+
+ if ( !d->redoList.isEmpty() ) {
+ d->redoList.clear();
+ emit redoAvailable( FALSE );
+ }
+}
+
+void TQtMultiLineEdit::addRedoCmd(TQtMultiLineEditCommand* c)
+{
+ if ( d->redoList.isEmpty() )
+ emit redoAvailable(TRUE);
+ d->redoList.append(c);
+}
+
+static const int initialScrollTime = 50; // mark text scroll time
+static const int initialScrollAccel = 5; // mark text scroll accel (0=fastest)
+static const int scroll_margin = 16; // auto-scroll edge in DND
+
+#define WORD_WRAP ( d->wordwrap != TQtMultiLineEdit::NoWrap )
+#define DYNAMIC_WRAP ( d->wordwrap == TQtMultiLineEdit::WidgetWidth )
+#define FIXED_WIDTH_WRAP ( d->wordwrap == TQtMultiLineEdit::FixedPixelWidth )
+#define FIXED_COLUMN_WRAP ( d->wordwrap == TQtMultiLineEdit::FixedColumnWidth )
+#define BREAK_WITHIN_WORDS ( d->wrappolicy == TQtMultiLineEdit::Anywhere )
+
+static int defTabStop = 8;
+
+static int tabStopDist( const TQFontMetrics &fm )
+{
+ int dist;
+ dist = fm.width( TQChar('x' ));
+ if( dist == 0 )
+ dist = fm.maxWidth();
+ return defTabStop*dist;
+}
+
+
+/*
+ Sets the distance between tab stops for all TQtMultiLineEdit instances
+ to \a ex, which is measured in multiples of the width of a lower case 'x'
+ in the widget's font. The initial value is 8.
+
+ \warning This function does not cause a redraw. It is best to call
+ it before any TQtMultiLineEdit widgets are shown.
+
+ \sa defaultTabStop()
+*/
+
+void TQtMultiLineEdit::setDefaultTabStop( int ex )
+{
+ defTabStop = ex;
+}
+
+
+
+/*
+ Returns the distance between tab stops.
+
+ \sa setDefaultTabStop();
+*/
+
+int TQtMultiLineEdit::defaultTabStop()
+{
+ return defTabStop;
+}
+
+
+
+
+static int textWidthWithTabs( const TQFontMetrics &fm, const TQString &s, uint start, uint nChars, int align )
+{
+ if ( s.isEmpty() )
+ return 0;
+
+ int dist = -fm.leftBearing( s[(int)start] );
+ int i = start;
+ int tabDist = -1; // lazy eval
+ while ( (uint)i < s.length() && (uint)i < start+nChars ) {
+ if ( s[i] == '\t' && align == TQt::AlignLeft ) {
+ if ( tabDist<0 )
+ tabDist = tabStopDist(fm);
+ dist = ( (dist+tabDist+1)/tabDist ) * tabDist;
+ i++;
+ } else {
+ int ii = i;
+ while ( (uint)i < s.length() && (uint)i < start + nChars && ( align != TQt::AlignLeft || s[i] != '\t' ) )
+ i++;
+ dist += fm.width( s.mid(ii,i-ii) );
+ }
+ }
+ return dist;
+}
+
+static int xPosToCursorPos( const TQString &s, const TQFontMetrics &fm,
+ int xPos, int width, int align )
+{
+ int i = 0;
+ int dist;
+ int tabDist;
+
+ if ( s.isEmpty() )
+ return 0;
+ if ( xPos > width )
+ xPos = width;
+ if ( xPos <= 0 )
+ return 0;
+
+ dist = -fm.leftBearing( s[0] );
+
+ if ( align == TQt::AlignCenter || align == TQt::AlignHCenter )
+ dist = ( width - textWidthWithTabs( fm, s, 0, s.length(), align ) ) / 2;
+ else if ( align == TQt::AlignRight )
+ dist = width - textWidthWithTabs( fm, s, 0, s.length(), align );
+
+ int distBeforeLastTab = dist;
+ tabDist = tabStopDist(fm);
+ while ( (uint)i < s.length() && dist < xPos ) {
+ if ( s[i] == '\t' && align == TQt::AlignLeft ) {
+ distBeforeLastTab = dist;
+ dist = (dist/tabDist + 1) * tabDist;
+ } else {
+ dist += fm.width( s[i] );
+ }
+ i++;
+ }
+ if ( dist > xPos ) {
+ if ( dist > width ) {
+ i--;
+ } else {
+ if ( s[i-1] == '\t' && align == TQt::AlignLeft ) { // dist equals a tab stop position
+ if ( xPos - distBeforeLastTab < (dist - distBeforeLastTab)/2 )
+ i--;
+ } else {
+ if ( fm.width(s[i-1])/2 < dist-xPos )
+ i--;
+ }
+ }
+ }
+ return i;
+}
+
+/*
+ Constructs a new, empty, TQtMultiLineEdit with tqparent \a tqparent and
+ called \a name.
+*/
+
+TQtMultiLineEdit::TQtMultiLineEdit( TQWidget *tqparent , const char *name )
+ :TQtTableView( tqparent, name, WStaticContents | WRepaintNoErase )
+{
+ d = new TQtMultiLineData;
+ TQFontMetrics fm( font() );
+ setCellHeight( fm.lineSpacing() );
+ setNumCols( 1 );
+
+ contents = new TQPtrList<TQtMultiLineEditRow>;
+ contents->setAutoDelete( TRUE );
+
+ cursorX = 0; cursorY = 0;
+ curXPos = 0;
+
+ setTableFlags( Tbl_autoVScrollBar|Tbl_autoHScrollBar|
+ Tbl_smoothVScrolling |
+ Tbl_clipCellPainting
+ );
+ setFrameStyle( TQFrame::WinPanel | TQFrame::Sunken );
+ setBackgroundMode( PaletteBase );
+ setWFlags( WResizeNoErase );
+ setKeyCompression( TRUE );
+ setFocusPolicy( WheelFocus );
+#ifndef TQT_NO_CURSOR
+ setCursor( ibeamCursor );
+ verticalScrollBar()->setCursor( arrowCursor );
+ horizontalScrollBar()->setCursor( arrowCursor );
+#endif
+ readOnly = FALSE;
+ cursorOn = FALSE;
+ markIsOn = FALSE;
+ dragScrolling = FALSE;
+ dragMarking = FALSE;
+ textDirty = FALSE;
+ wordMark = FALSE;
+ overWrite = FALSE;
+ markAnchorX = 0;
+ markAnchorY = 0;
+ markDragX = 0;
+ markDragY = 0;
+ d->blinkTimer = new TQTimer( this );
+ connect( d->blinkTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( blinkTimerTimeout() ) );
+ d->scrollTimer = new TQTimer( this );
+ connect( d->scrollTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( scrollTimerTimeout() ) );
+#ifndef TQT_NO_DRAGANDDROP
+ d->dnd_timer = new TQTimer( this );
+ connect( d->dnd_timer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( dndTimeout() ) );
+#endif
+ d->scrollTime = 0;
+
+ dummy = TRUE;
+
+ int w = textWidth( TQString::tqfromLatin1("") );
+ contents->append( new TQtMultiLineEditRow(TQString::tqfromLatin1(""), w) );
+ (void)setNumRowsAndTruncate();
+ setWidth( w );
+ setAcceptDrops(TRUE);
+ if ( d->maxlines >= 0 && d->maxlines <= 6 ) {
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
+ } else {
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) );
+ }
+}
+
+/*
+ \fn int TQtMultiLineEdit::lineLength( int line ) const
+ Returns the number of characters at line number \a line.
+*/
+
+/* \fn TQString *TQtMultiLineEdit::getString( int line ) const
+
+ Returns a pointer to the text at line \a line.
+*/
+
+/* \fn void TQtMultiLineEdit::textChanged()
+
+ This signal is emitted when the text is changed by an event or by a
+ slot. Note that the signal is not emitted when you call a non-slot
+ function such as insertLine().
+
+ \sa returnPressed()
+*/
+
+/* \fn void TQtMultiLineEdit::returnPressed()
+
+ This signal is emitted when the user presses the return or enter
+ key. It is not emitted if isReadOnly() is TRUE.
+
+ \sa textChanged()
+*/
+
+/*
+ \fn void TQtMultiLineEdit::undoAvailable (bool yes)
+
+ This signal is emitted when the availability of undo changes.
+ If \a yes is TRUE, then undo() will work until
+ undoAvailable( FALSE ) is next emitted.
+*/
+
+/*
+ \fn void TQtMultiLineEdit::redoAvailable (bool yes)
+
+ This signal is emitted when the availability of redo changes.
+ If \a yes is TRUE, then redo() will work until
+ redoAvailable( FALSE ) is next emitted.
+*/
+
+/*
+ \fn void TQtMultiLineEdit::copyAvailable (bool yes)
+
+ This signal is emitted when the availability of cut/copy changes.
+ If \a yes is TRUE, then cut() and copy() will work until
+ copyAvailable( FALSE ) is next emitted.
+*/
+
+
+/*
+ If \a on is FALSE, this multi line edit accepts text input.
+ Scrolling and cursor movements are accepted in any case.
+
+ \sa isReadOnly() TQWidget::setEnabled()
+*/
+
+void TQtMultiLineEdit::setReadOnly( bool on )
+{
+ if ( readOnly != on ) {
+ readOnly = on;
+#ifndef TQT_NO_CURSOR
+ setCursor( on ? arrowCursor : ibeamCursor );
+#endif
+ }
+}
+
+/*
+*/
+int TQtMultiLineEdit::maxLineWidth() const
+{
+ return d->maxLineWidth;
+}
+
+/*
+ Destroys the TQtMultiLineEdit
+*/
+
+TQtMultiLineEdit::~TQtMultiLineEdit()
+{
+ delete contents;
+ delete d;
+}
+
+static TQPixmap *buffer = 0;
+
+static void cleanupMLBuffer()
+{
+ delete buffer;
+ buffer = 0;
+}
+
+static TQPixmap *getCacheBuffer( TQSize sz )
+{
+ if ( !buffer ) {
+ qAddPostRoutine( cleanupMLBuffer );
+ buffer = new TQPixmap;
+ }
+
+ if ( buffer->width() < sz.width() || buffer->height() < sz.height() )
+ buffer->resize( sz );
+ return buffer;
+}
+
+/*
+ Implements the basic drawing logic. Paints the line at row \a row
+ using painter \a painter. The \a col parameter is ignored.
+*/
+void TQtMultiLineEdit::paintCell( TQPainter *painter, int row, int )
+{
+ const TQColorGroup & g = tqcolorGroup();
+ TQFontMetrics fm( painter->font() );
+ TQString s = stringShown(row);
+ if ( s.isNull() ) {
+ qWarning( "TQtMultiLineEdit::paintCell: (%s) no text at line %d",
+ name( "unnamed" ), row );
+ return;
+ }
+ TQRect updateR = cellUpdateRect();
+ TQPixmap *buffer = getCacheBuffer( updateR.size() );
+ ASSERT(buffer);
+ buffer->fill ( g.base() );
+
+ TQPainter p( buffer );
+ p.setFont( painter->font() );
+ p.translate( -updateR.left(), -updateR.top() );
+
+ p.setTabStops( tabStopDist(fm) );
+
+ int yPos = 0;
+ int markX1, markX2; // in x-coordinate pixels
+ markX1 = markX2 = 0; // avoid gcc warning
+ if ( markIsOn ) {
+ int markBeginX, markBeginY;
+ int markEndX, markEndY;
+ getMarkedRegion( &markBeginY, &markBeginX, &markEndY, &markEndX );
+ if ( row >= markBeginY && row <= markEndY ) {
+ if ( row == markBeginY ) {
+ markX1 = markBeginX;
+ if ( row == markEndY ) // both marks on same row
+ markX2 = markEndX;
+ else
+ markX2 = s.length(); // mark till end of line
+ } else {
+ if ( row == markEndY ) {
+ markX1 = 0;
+ markX2 = markEndX;
+ } else {
+ markX1 = 0; // whole line is marked
+ markX2 = s.length(); // whole line is marked
+ }
+ }
+ }
+ }
+ p.setPen( g.text() );
+ TQtMultiLineEditRow* r = contents->at( row );
+ int wcell = cellWidth() - 2*d->lr_marg;// - d->marg_extra;
+ int wrow = r->w;
+ int x = d->lr_marg - p.fontMetrics().leftBearing(s[0]);
+ if ( d->align == TQt::AlignCenter || d->align == TQt::AlignHCenter )
+ x += (wcell - wrow) / 2;
+ else if ( d->align == TQt::AlignRight )
+ x += wcell - wrow;
+ p.drawText( x, yPos, cellWidth()-d->lr_marg-x, cellHeight(),
+ d->align == AlignLeft?ExpandTabs:0, s );
+ if ( !r->newline && BREAK_WITHIN_WORDS )
+ p.drawPixmap( x + wrow - d->lr_marg - d->marg_extra, yPos, d->arrow );
+#if 0
+ if ( r->newline )
+ p.drawLine( d->lr_marg, yPos+cellHeight()-2, cellWidth() - d->lr_marg, yPos+cellHeight()-2);
+#endif
+ if ( markX1 != markX2 ) {
+ int sLength = s.length();
+ int xpos1 = mapToView( markX1, row );
+ int xpos2 = mapToView( markX2, row );
+ int fillxpos1 = xpos1;
+ int fillxpos2 = xpos2;
+ if ( markX1 == 0 )
+ fillxpos1 -= 2;
+ if ( markX2 == sLength )
+ fillxpos2 += 3;
+ p.setClipping( TRUE );
+ p.setClipRect( fillxpos1 - updateR.left(), 0,
+ fillxpos2 - fillxpos1, cellHeight(row) );
+ p.fillRect( fillxpos1, 0, fillxpos2 - fillxpos1, cellHeight(row),
+ g.brush( TQColorGroup::Highlight ) );
+ p.setPen( g.highlightedText() );
+ p.drawText( x, yPos, cellWidth()-d->lr_marg-x, cellHeight(),
+ d->align == AlignLeft?ExpandTabs:0, s );
+ p.setClipping( FALSE );
+ }
+
+ if ( row == cursorY && cursorOn && !readOnly ) {
+ int cursorPos = TQMIN( (int)s.length(), cursorX );
+ int cXPos = TQMAX( mapToView( cursorPos, row ), 0 );
+ int cYPos = 0;
+ if ( hasFocus() || d->dnd_forcecursor ) {
+ p.setPen( g.text() );
+ /* styled?
+ p.drawLine( cXPos - 2, cYPos,
+ cXPos + 2, cYPos );
+ */
+ p.drawLine( cXPos, cYPos,
+ cXPos, cYPos + fm.height() - 2);
+ /* styled?
+ p.drawLine( cXPos - 2, cYPos + fm.height() - 2,
+ cXPos + 2, cYPos + fm.height() - 2);
+ */
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ // TODO: set it other times, eg. when scrollbar moves view
+ TQWMatrix wm = painter->tqworldMatrix();
+ setMicroFocusHint( int(wm.dx()+cXPos),
+ int (wm.dy()+cYPos),
+ 1, fm.ascent() );
+#else
+ setMicroFocusHint( cXPos,
+ cYPos,
+ 1, fm.ascent() );
+#endif
+ }
+ }
+ p.end();
+ painter->drawPixmap( updateR.left(), updateR.top(), *buffer,
+ 0, 0, updateR.width(), updateR.height() );
+}
+
+
+/*
+ \overload
+ Returns the width in pixels of the string \a s.
+ NOTE: only appropriate for whole lines.
+*/
+
+int TQtMultiLineEdit::textWidth( const TQString &s )
+{
+ int w = 0;
+ if ( !s.isNull() ) {
+ w = textWidthWithTabs( TQFontMetrics( font() ), s, 0, s.length(),
+ d->align );
+ }
+ return w + 2 * d->lr_marg + d->marg_extra;
+}
+
+
+/*
+ Returns the width in pixels of the text at line \a line.
+*/
+
+int TQtMultiLineEdit::textWidth( int line )
+{
+ if ( d->echomode == Password) {
+ TQString s = stringShown(line);
+ return textWidth( s );
+ }
+ TQtMultiLineEditRow* r = contents->at(line);
+ return r?r->w:0;
+}
+
+/*
+ Starts the cursor blinking.
+*/
+
+void TQtMultiLineEdit::focusInEvent( TQFocusEvent * )
+{
+ stopAutoScroll();
+ if ( !d->blinkTimer->isActive() )
+ d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE );
+ cursorOn = TRUE;
+ updateCell( cursorY, 0, FALSE );
+}
+
+
+/*\reimp
+*/
+void TQtMultiLineEdit::leaveEvent( TQEvent * )
+{
+}
+
+
+/*\reimp
+*/
+void TQtMultiLineEdit::focusOutEvent( TQFocusEvent * )
+{
+ stopAutoScroll();
+ d->blinkTimer->stop();
+ if ( cursorOn ) {
+ cursorOn = FALSE;
+ updateCell( cursorY, 0, FALSE );
+ }
+}
+
+
+/*
+ \reimp
+ Present for binary compatibility only!
+*/
+
+void TQtMultiLineEdit::timerEvent( TQTimerEvent * )
+{
+ // ############ Remove in 3.0!!!!!!!!
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQtMultiLineEdit::doDrag()
+{
+ if ( d->dnd_timer ) {
+ d->dnd_timer->stop();
+ }
+ TQDragObject *drag_text = new TQTextDrag(markedText(), this);
+ if ( readOnly ) {
+ drag_text->dragCopy();
+ } else {
+ if ( drag_text->drag() && TQDragObject::target() != this ) {
+ del();
+ if ( textDirty && !d->isHandlingEvent )
+ emit textChanged();
+ }
+ }
+ d->dnd_primed = FALSE;
+}
+#endif
+
+/*
+ If there is marked text, sets \a line1, \a col1, \a line2 and \a col2
+ to the start and end of the marked region and returns TRUE. Returns
+ FALSE if there is no marked text.
+ */
+bool TQtMultiLineEdit::getMarkedRegion( int *line1, int *col1,
+ int *line2, int *col2 ) const
+{
+ if ( !markIsOn || !line1 || !line2 || !col1 || !col2 )
+ return FALSE;
+ if ( markAnchorY < markDragY ||
+ markAnchorY == markDragY && markAnchorX < markDragX) {
+ *line1 = markAnchorY;
+ *col1 = markAnchorX;
+ *line2 = markDragY;
+ *col2 = markDragX;
+ if ( *line2 > numLines() - 1 ) {
+ *line2 = numLines() - 1;
+ *col2 = lineLength( *line2 );
+ }
+ } else {
+ *line1 = markDragY;
+ *col1 = markDragX;
+ *line2 = markAnchorY;
+ *col2 = markAnchorX;
+ if ( *line2 > numLines() - 1 ) {
+ *line2 = numLines() - 1;
+ *col2 = lineLength( *line2 );
+ }
+ }
+ return markIsOn;
+}
+
+
+/*
+ Returns TRUE if there is marked text.
+*/
+
+bool TQtMultiLineEdit::hasMarkedText() const
+{
+ return markIsOn;
+}
+
+
+/*
+ Returns a copy of the marked text.
+*/
+
+TQString TQtMultiLineEdit::markedText() const
+{
+ int markBeginX, markBeginY;
+ int markEndX, markEndY;
+ if ( !getMarkedRegion( &markBeginY, &markBeginX, &markEndY, &markEndX ) )
+ return TQString();
+ if ( markBeginY == markEndY ) { //just one line
+ TQString *s = getString( markBeginY );
+ return s->mid( markBeginX, markEndX - markBeginX );
+ } else { //multiline
+ TQString *firstS, *lastS;
+ firstS = getString( markBeginY );
+ lastS = getString( markEndY );
+ int i;
+ TQString tmp;
+ if ( firstS )
+ tmp += firstS->mid(markBeginX);
+ if ( contents->at( markBeginY )->newline )
+ tmp += '\n';
+
+ for( i = markBeginY + 1; i < markEndY ; i++ ) {
+ tmp += *getString(i);
+ if ( contents->at( i )->newline )
+ tmp += '\n';
+ }
+
+ if ( lastS ) {
+ tmp += lastS->left(markEndX);
+ } else {
+ tmp.truncate(tmp.length()-1);
+ }
+
+ return tmp;
+ }
+}
+
+
+
+/*
+ Returns the text at line number \a line (possibly the empty string),
+ or a \link TQString::operator!() null string\endlink if \a line is invalid.
+*/
+
+TQString TQtMultiLineEdit::textLine( int line ) const
+{
+ TQString *s = getString(line);
+ if ( s ) {
+ if ( s->isNull() )
+ return TQString::tqfromLatin1("");
+ else
+ return *s;
+ } else
+ return TQString::null;
+}
+
+
+/*
+ Returns a copy of the whole text. If the multi line edit tqcontains no
+ text, a
+ \link TQString::operator!() null string\endlink
+ is returned.
+*/
+
+TQString TQtMultiLineEdit::text() const
+{
+ TQString tmp;
+ for( int i = 0 ; i < (int)contents->count() ; i++ ) {
+ tmp += *getString(i);
+ if ( i+1 < (int)contents->count() && contents->at(i)->newline )
+ tmp += '\n';
+ }
+ return tmp;
+}
+
+
+/*
+ Selects all text without moving the cursor.
+*/
+
+void TQtMultiLineEdit::selectAll()
+{
+ markAnchorX = 0;
+ markAnchorY = 0;
+ markDragY = numLines() - 1;
+ markDragX = lineLength( markDragY );
+ turnMark( markDragX != markAnchorX || markDragY != markAnchorY );
+ if ( autoUpdate() )
+ update();
+}
+
+
+
+/*
+ Deselects all text (i.e. removes marking) and leaves the cursor at the
+ current position.
+*/
+
+void TQtMultiLineEdit::deselect()
+{
+ turnMark( FALSE );
+}
+
+
+/*
+ Sets the text to \a s, removing old text, if any.
+*/
+
+void TQtMultiLineEdit::setText( const TQString &s )
+{
+ bool oldUndo = isUndoEnabled();
+ setUndoEnabled( FALSE );
+ bool oldAuto = autoUpdate();
+ setAutoUpdate( FALSE );
+ bool b = tqsignalsBlocked();
+ blockSignals( TRUE );
+ clear();
+ CLEAR_UNDO
+ blockSignals( b );
+ insertLine( s, -1 );
+ emit textChanged();
+ setAutoUpdate(oldAuto);
+ if ( autoUpdate() )
+ update();
+ setUndoEnabled( oldUndo );
+}
+
+
+/*
+ Appends \a s to the text.
+*/
+
+void TQtMultiLineEdit::append( const TQString &s )
+{
+ bool oldUndo = isUndoEnabled();
+ setUndoEnabled( FALSE );
+ insertLine( s, -1 );
+ setUndoEnabled( oldUndo );
+ emit textChanged();
+}
+
+/* \reimp
+Passes wheel events to the vertical scrollbar.
+*/
+void TQtMultiLineEdit::wheelEvent( TQWheelEvent *e ){
+ TQApplication::sendEvent( verticalScrollBar(), e);
+}
+
+
+/*
+ The key press event handler converts a key press in event \a e to
+ some line editor action.
+
+ Here are the default key bindings when isReadOnly() is FALSE:
+ \list
+ \i <i> Left Arrow </i> Move the cursor one character leftwards
+ \i <i> Right Arrow </i> Move the cursor one character rightwards
+ \i <i> Up Arrow </i> Move the cursor one line upwards
+ \i <i> Down Arrow </i> Move the cursor one line downwards
+ \i <i> Page Up </i> Move the cursor one page upwards
+ \i <i> Page Down </i> Move the cursor one page downwards
+ \i <i> Backspace </i> Delete the character to the left of the cursor
+ \i <i> Home </i> Move the cursor to the beginning of the line
+ \i <i> End </i> Move the cursor to the end of the line
+ \i <i> Delete </i> Delete the character to the right of the cursor
+ \i <i> Shift - Left Arrow </i> Mark text one character leftwards
+ \i <i> Shift - Right Arrow </i> Mark text one character rightwards
+ \i <i> Control-A </i> Move the cursor to the beginning of the line
+ \i <i> Control-B </i> Move the cursor one character leftwards
+ \i <i> Control-C </i> Copy the marked text to the clipboard
+ \i <i> Control-D </i> Delete the character to the right of the cursor
+ \i <i> Control-E </i> Move the cursor to the end of the line
+ \i <i> Control-F </i> Move the cursor one character rightwards
+ \i <i> Control-H </i> Delete the character to the left of the cursor
+ \i <i> Control-K </i> Delete to end of line
+ \i <i> Control-N </i> Move the cursor one line downwards
+ \i <i> Control-P </i> Move the cursor one line upwards
+ \i <i> Control-V </i> Paste the clipboard text into line edit
+ \i <i> Control-X </i> Cut the marked text, copy to clipboard
+ \i <i> Control-Z </i> Undo the last operation
+ \i <i> Control-Y </i> Redo the last operation
+ \i <i> Control - Left Arrow </i> Move the cursor one word leftwards
+ \i <i> Control - Right Arrow </i> Move the cursor one word rightwards
+ \i <i> Control - Up Arrow </i> Move the cursor one word upwards
+ \i <i> Control - Down Arrow </i> Move the cursor one word downwards
+ \i <i> Control - Home Arrow </i> Move the cursor to the beginning of the text
+ \i <i> Control - End Arrow </i> Move the cursor to the end of the text
+ \endlist
+ In addition, the following key bindings are used on Windows:
+ \list
+ \i <i> Shift - Delete </i> Cut the marked text, copy to clipboard
+ \i <i> Shift - Insert </i> Paste the clipboard text into line edit
+ \i <i> Control - Insert </i> Copy the marked text to the clipboard
+ \endlist
+ All other keys with valid ASCII codes insert themselves into the line.
+
+ Here are the default key bindings when isReadOnly() is TRUE:
+ \list
+ \i <i> Left Arrow </i> Scrolls the table rightwards
+ \i <i> Right Arrow </i> Scrolls the table rightwards
+ \i <i> Up Arrow </i> Scrolls the table one line downwards
+ \i <i> Down Arrow </i> Scrolls the table one line upwards
+ \i <i> Page Up </i> Scrolls the table one page downwards
+ \i <i> Page Down </i> Scrolls the table one page upwards
+ \i <i> Control-C </i> Copy the marked text to the clipboard
+ \endlist
+
+*/
+
+void TQtMultiLineEdit::keyPressEvent( TQKeyEvent *e )
+{
+ textDirty = FALSE;
+ d->isHandlingEvent = TRUE;
+ int unknown = 0;
+ if ( readOnly ) {
+ int pageSize = viewHeight() / cellHeight();
+
+ switch ( e->key() ) {
+ case Key_Left:
+ setXOffset( xOffset() - viewWidth()/10 );
+ break;
+ case Key_Right:
+ setXOffset( xOffset() + viewWidth()/10 );
+ break;
+ case Key_Up:
+ setTopCell( topCell() - 1 );
+ break;
+ case Key_Down:
+ setTopCell( topCell() + 1 );
+ break;
+ case Key_Home:
+ setCursorPosition(0,0, e->state() & ShiftButton );
+ break;
+ case Key_End:
+ setCursorPosition( numLines()-1, lineLength( numLines()-1 ),
+ e->state() & ShiftButton );
+ break;
+ case Key_Next:
+ setTopCell( topCell() + pageSize );
+ break;
+ case Key_Prior:
+ setTopCell( TQMAX( topCell() - pageSize, 0 ) );
+ break;
+#ifndef TQT_NO_CLIPBOARD
+ case Key_C:
+ if ( echoMode() == Normal && (e->state()&ControlButton) )
+ copy();
+ else
+ unknown++;
+ break;
+ case Key_F16: // Copy key on Sun keyboards
+ if ( echoMode() == Normal )
+ copy();
+ else
+ unknown++;
+ break;
+#endif
+ default:
+ unknown++;
+ }
+ if ( unknown )
+ e->ignore();
+ d->isHandlingEvent = FALSE;
+ return;
+ }
+ if ( e->text().length() &&
+ e->key() != Key_Return &&
+ e->key() != Key_Enter &&
+ e->key() != Key_Delete &&
+ e->key() != Key_Backspace &&
+ (!e->ascii() || e->ascii()>=32)
+ ) {
+ insert( e->text() );
+ //TQApplication::sendPostedEvents( this, TQEvent::Paint );
+ if ( textDirty )
+ emit textChanged();
+ d->isHandlingEvent = FALSE;
+ return;
+ }
+ if ( e->state() & ControlButton ) {
+ switch ( e->key() ) {
+ case Key_A:
+ home( e->state() & ShiftButton );
+ break;
+ case Key_B:
+ cursorLeft( e->state() & ShiftButton );
+ break;
+#ifndef TQT_NO_CLIPBOARD
+ case Key_C:
+ if ( echoMode() == Normal )
+ copy();
+ break;
+#endif
+ case Key_D:
+ del();
+ break;
+ case Key_E:
+ end( e->state() & ShiftButton );
+ break;
+ case Key_Left:
+ cursorWordBackward( e->state() & ShiftButton );
+ break;
+ case Key_Right:
+ cursorWordForward( e->state() & ShiftButton );
+ break;
+ case Key_Up:
+ cursorUp( e->state() & ShiftButton );
+ break;
+ case Key_Down:
+ cursorDown( e->state() & ShiftButton );
+ break;
+ case Key_Home:
+ setCursorPosition(0,0, e->state() & ShiftButton );
+ break;
+ case Key_End:
+ setCursorPosition( numLines()-1, lineLength( numLines()-1 ),
+ e->state() & ShiftButton );
+ break;
+ case Key_F:
+ cursorRight( e->state() & ShiftButton );
+ break;
+ case Key_H:
+ backspace();
+ break;
+ case Key_K:
+ killLine();
+ break;
+ case Key_N:
+ cursorDown( e->state() & ShiftButton );
+ break;
+ case Key_P:
+ cursorUp( e->state() & ShiftButton );
+ break;
+#ifndef TQT_NO_CLIPBOARD
+ case Key_V:
+ paste();
+ break;
+ case Key_X:
+ cut();
+ break;
+#endif
+ case Key_Z:
+ undo();
+ break;
+ case Key_Y:
+ redo();
+ break;
+#if defined (_WS_WIN_)
+ case Key_Insert:
+ copy();
+#endif
+ default:
+ unknown++;
+ }
+ } else {
+ switch ( e->key() ) {
+ case Key_Left:
+ cursorLeft( e->state() & ShiftButton );
+ break;
+ case Key_Right:
+ cursorRight( e->state() & ShiftButton );
+ break;
+ case Key_Up:
+ cursorUp( e->state() & ShiftButton );
+ break;
+ case Key_Down:
+ cursorDown( e->state() & ShiftButton );
+ break;
+ case Key_Backspace:
+ backspace();
+ break;
+ case Key_Home:
+ home( e->state() & ShiftButton );
+ break;
+ case Key_End:
+ end( e->state() & ShiftButton );
+ break;
+ case Key_Delete:
+#if defined (_WS_WIN_)
+ if ( e->state() & ShiftButton ) {
+ cut();
+ break;
+ }
+#endif
+ del();
+ break;
+ case Key_Next:
+ pageDown( e->state() & ShiftButton );
+ break;
+ case Key_Prior:
+ pageUp( e->state() & ShiftButton );
+ break;
+ case Key_Enter:
+ case Key_Return:
+ newLine();
+ emit returnPressed();
+ break;
+ case Key_Tab:
+ insert( e->text() );
+ break;
+#if defined (_WS_WIN_)
+ case Key_Insert:
+ if ( e->state() & ShiftButton )
+ paste();
+ else
+ unknown++;
+ break;
+#endif
+ case Key_F14: // Undo key on Sun keyboards
+ undo();
+ break;
+#ifndef TQT_NO_CLIPBOARD
+ case Key_F16: // Copy key on Sun keyboards
+ if ( echoMode() == Normal )
+ copy();
+ break;
+ case Key_F18: // Paste key on Sun keyboards
+ paste();
+ break;
+ case Key_F20: // Paste key on Sun keyboards
+ cut();
+ break;
+#endif
+ default:
+ unknown++;
+ }
+ }
+ if ( textDirty )
+ emit textChanged();
+
+ if ( unknown ) // unknown key
+ e->ignore();
+
+ d->isHandlingEvent = FALSE;
+}
+
+
+/*
+ Moves the cursor one page down. If \a mark is TRUE, the text
+ is marked.
+*/
+
+void TQtMultiLineEdit::pageDown( bool mark )
+{
+ bool oldAuto = autoUpdate();
+ if ( mark )
+ setAutoUpdate( FALSE );
+
+ if ( partiallyInvisible( cursorY ) )
+ cursorY = topCell();
+ int delta = cursorY - topCell();
+ int pageSize = viewHeight() / cellHeight();
+ int newTopCell = TQMIN( topCell() + pageSize, numLines() - 1 - pageSize );
+
+ if ( pageSize >= numLines() ) { // quick fix to handle small texts
+ newTopCell = topCell();
+ }
+ if ( !curXPos )
+ curXPos = mapToView( cursorX, cursorY );
+ int oldY = cursorY;
+
+ if ( mark && !hasMarkedText() ) {
+ markAnchorX = cursorX;
+ markAnchorY = cursorY;
+ }
+ if ( newTopCell != topCell() ) {
+ cursorY = newTopCell + delta;
+ cursorX = mapFromView( curXPos, cursorY );
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+ setTopCell( newTopCell );
+ } else if ( cursorY != (int)contents->count() - 1) { // just move the cursor
+ cursorY = TQMIN( cursorY + pageSize, numLines() - 1);
+ cursorX = mapFromView( curXPos, cursorY );
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+ makeVisible();
+ }
+ if ( oldAuto )
+ if ( mark ) {
+ setAutoUpdate( TRUE );
+ update();
+ } else {
+ updateCell( oldY, 0, FALSE );
+ }
+ if ( !mark )
+ turnMark( FALSE );
+}
+
+
+/*
+ Moves the cursor one page up. If \a mark is TRUE, the text
+ is marked.
+*/
+
+void TQtMultiLineEdit::pageUp( bool mark )
+{
+ bool oldAuto = autoUpdate();
+ if ( mark )
+ setAutoUpdate( FALSE );
+ if ( partiallyInvisible( cursorY ) )
+ cursorY = topCell();
+ int delta = cursorY - topCell();
+ int pageSize = viewHeight() / cellHeight();
+ bool partial = delta == pageSize && viewHeight() != pageSize * cellHeight();
+ int newTopCell = TQMAX( topCell() - pageSize, 0 );
+ if ( pageSize > numLines() ) { // quick fix to handle small texts
+ newTopCell = 0;
+ delta = 0;
+ }
+ if ( mark && !hasMarkedText() ) {
+ markAnchorX = cursorX;
+ markAnchorY = cursorY;
+ }
+ if ( !curXPos )
+ curXPos = mapToView( cursorX, cursorY );
+ int oldY = cursorY;
+ if ( newTopCell != topCell() ) {
+ cursorY = TQMIN( newTopCell + delta, numLines() - 1 );
+ if ( partial )
+ cursorY--;
+ cursorX = mapFromView( curXPos, cursorY );
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+ setTopCell( newTopCell );
+ } else { // just move the cursor
+ cursorY = TQMAX( cursorY - pageSize, 0 );
+ cursorX = mapFromView( curXPos, cursorY );
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+ }
+ if ( oldAuto )
+ if ( mark ) {
+ setAutoUpdate( TRUE );
+ update();
+ } else {
+ updateCell( oldY, 0, FALSE );
+ }
+ if ( !mark )
+ turnMark( FALSE );
+}
+
+// THE CORE INSERTION FUNCTION
+void TQtMultiLineEdit::insertAtAux( const TQString &txt, int line, int col, bool mark )
+{
+ dummy = FALSE;
+ d->blinkTimer->stop();
+ cursorOn = TRUE;
+ int oldw = contentsRect().width();
+
+ line = TQMAX( TQMIN( line, numLines() - 1), 0 );
+ col = TQMAX( TQMIN( col, lineLength( line )), 0 );
+
+ TQString itxt = txt;
+ TQtMultiLineEditRow *row = contents->at( line );
+ if ( d->maxlen >= 0 && length() + int(txt.length()) > d->maxlen )
+ itxt.truncate( d->maxlen - length() );
+
+ row->s.insert( uint(col), itxt );
+
+ if ( mark ) {
+ markAnchorX = col;
+ markAnchorY = line;
+ }
+ if ( cursorX == col && cursorY == line ) {
+ cursorX += itxt.length();
+ }
+ TQFontMetrics fm( font() );
+ if ( !WORD_WRAP || ( col == 0 && itxt.tqcontains('\n') == int(itxt.length())) )
+ wrapLine( line, 0 );
+ else if ( WORD_WRAP && itxt.tqfind('\n')<0 && itxt.tqfind('\t')<0
+ && (
+ ( DYNAMIC_WRAP && fm.width( itxt ) + row->w < contentsRect().width() - 2*d->lr_marg - d->marg_extra )
+ ||
+ ( FIXED_WIDTH_WRAP && ( d->wrapcol < 0 || fm.width( itxt ) + row->w < d->wrapcol ) )
+ ||
+ ( FIXED_COLUMN_WRAP && ( d->wrapcol < 0 || int(row->s.length()) < d->wrapcol ) )
+ )
+ && ( itxt.tqfind(' ') < 0 || row->s.tqfind(' ') >= 0 && row->s.tqfind(' ') < col ) ){
+ row->w = textWidth( row->s );
+ setWidth( TQMAX( maxLineWidth(), row->w) );
+ updateCell( line, 0, FALSE );
+ }
+ else {
+ if ( line > 0 && !contents->at( line-1)->newline )
+ rebreakParagraph( line-1 );
+ else
+ rebreakParagraph( line );
+ }
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+
+ setNumRowsAndTruncate();
+
+ textDirty = TRUE;
+ d->edited = TRUE;
+ if ( autoUpdate() ) {
+ makeVisible();
+ d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE );
+ if ( DYNAMIC_WRAP && oldw != contentsRect().width() ) {
+ setAutoUpdate( FALSE );
+ rebreakAll();
+ setAutoUpdate( TRUE );
+ update();
+ }
+ }
+}
+
+
+/*
+ Inserts \a txt at line number \a line. If \a line is less than zero,
+ or larger than the number of rows, the new text is put at the end.
+ If \a txt tqcontains newline characters, several lines are inserted.
+
+ The cursor position is not changed.
+*/
+
+void TQtMultiLineEdit::insertLine( const TQString &txt, int line )
+{
+ TQString s = txt;
+ int oldXPos = cursorX;
+ int oldYPos = cursorY;
+ if ( line < 0 || line >= int( contents->count() ) ) {
+ if ( !dummy )
+ contents->append( new TQtMultiLineEditRow(TQString::tqfromLatin1(""), 0) );
+ insertAt( s, numLines()-1, 0 );
+ } else {
+ s.append('\n');
+ insertAt( s, line, 0 );
+ }
+ cursorX = oldXPos;
+ cursorY = oldYPos;
+}
+
+/*
+ Deletes the line at line number \a line. If \a
+ line is less than zero, or larger than the number of lines,
+ no line is deleted.
+*/
+
+void TQtMultiLineEdit::removeLine( int line )
+{
+ CLEAR_UNDO
+ if ( line >= numLines() )
+ return;
+ if ( cursorY >= line && cursorY > 0 )
+ cursorY--;
+ bool updt = autoUpdate() && rowIsVisible( line );
+ TQtMultiLineEditRow* r = contents->at( line );
+ ASSERT( r );
+ bool recalc = r->w == maxLineWidth();
+ contents->remove( line );
+ if ( contents->count() == 0 ) {
+ int w = textWidth( TQString::tqfromLatin1("") );
+ contents->append( new TQtMultiLineEditRow(TQString::tqfromLatin1(""), w) );
+ setWidth( w );
+ dummy = TRUE;
+ }
+ if ( setNumRowsAndTruncate() )
+ recalc = updt = FALSE;
+ if ( recalc )
+ updateCellWidth();
+ makeVisible();
+ if (updt)
+ update();
+ textDirty = TRUE;
+ d->edited = TRUE;
+}
+
+/*
+ Inserts \a s at the current cursor position.
+*/
+void TQtMultiLineEdit::insert( const TQString& s )
+{
+ insert( s, FALSE );
+}
+
+/*
+ Inserts \a c at the current cursor position.
+ (this function is provided for backward compatibility -
+ it simply calls insert()).
+*/
+void TQtMultiLineEdit::insertChar( TQChar c )
+{
+ insert(c);
+}
+
+/*
+ \overload
+ Inserts string \a str at the current cursor position. If \a mark is
+ TRUE the string is marked.
+*/
+
+void TQtMultiLineEdit::insert( const TQString& str, bool mark )
+{
+ dummy = FALSE;
+ bool wasMarkedText = hasMarkedText();
+ if ( wasMarkedText )
+ addUndoCmd( new TQBeginCommand );
+ if ( wasMarkedText )
+ del(); // ## Will flicker
+ TQString *s = getString( cursorY );
+ if ( cursorX > (int)s->length() )
+ cursorX = s->length();
+ else if ( overWrite && !wasMarkedText && cursorX < (int)s->length() )
+ del(); // ## Will flicker
+ insertAt(str, cursorY, cursorX, mark );
+ makeVisible();
+
+ if ( wasMarkedText )
+ addUndoCmd( new TQEndCommand() );
+}
+
+/*
+ Makes a line break at the current cursor position.
+*/
+
+void TQtMultiLineEdit::newLine()
+{
+ insert("\n");
+}
+
+/*
+ Deletes text from the current cursor position to the end of the line.
+*/
+
+void TQtMultiLineEdit::killLineAux()
+{
+ deselect(); // -sanders Don't let del() delete marked region
+ TQtMultiLineEditRow* r = contents->at( cursorY );
+ if ( cursorX == (int)r->s.length() ) {
+ // if (r->newline) // -sanders Only del newlines!
+ del();
+ return;
+ } else {
+ bool recalc = r->w == maxLineWidth();
+ r->s.remove( cursorX, r->s.length() );
+ r->w = textWidth( r->s );
+ updateCell( cursorY, 0, FALSE );
+ if ( recalc )
+ updateCellWidth();
+ rebreakParagraph( cursorY ); // -sanders
+ textDirty = TRUE;
+ d->edited = TRUE;
+ }
+ curXPos = 0;
+ makeVisible();
+ turnMark( FALSE );
+}
+
+
+/*
+ Moves the cursor one character to the left. If \a mark is TRUE, the text
+ is marked. If \a wrap is TRUE, the cursor moves to the end of the
+ previous line if it is placed at the beginning of the current line.
+
+ \sa cursorRight() cursorUp() cursorDown()
+*/
+
+void TQtMultiLineEdit::cursorLeft( bool mark, bool wrap )
+{
+ cursorLeft(mark,!mark,wrap);
+}
+void TQtMultiLineEdit::cursorLeft( bool mark, bool clear_mark, bool wrap )
+{
+ if ( cursorX != 0 || cursorY != 0 && wrap ) {
+ if ( mark && !hasMarkedText() ) {
+ markAnchorX = cursorX;
+ markAnchorY = cursorY;
+ }
+ d->blinkTimer->stop();
+ int ll = lineLength( cursorY );
+ if ( cursorX > ll )
+ cursorX = ll;
+ cursorOn = TRUE;
+ cursorX--;
+ if ( cursorX < 0 ) {
+ int oldY = cursorY;
+ if ( cursorY > 0 ) {
+ cursorY--;
+ cursorX = lineLength( cursorY );
+ if ( cursorX > 1 && !isEndOfParagraph( cursorY ) )
+ cursorX--;
+ } else {
+ cursorY = 0; //### ?
+ cursorX = 0;
+ }
+ updateCell( oldY, 0, FALSE );
+ }
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+ d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE );
+ updateCell( cursorY, 0, FALSE );
+ }
+ curXPos = 0;
+ makeVisible();
+ if ( clear_mark )
+ turnMark( FALSE );
+}
+
+/*
+ Moves the cursor one character to the right. If \a mark is TRUE, the text
+ is marked. If \a wrap is TRUE, the cursor moves to the beginning of the next
+ line if it is placed at the end of the current line.
+ \sa cursorLeft() cursorUp() cursorDown()
+*/
+
+void TQtMultiLineEdit::cursorRight( bool mark, bool wrap )
+{
+ cursorRight(mark,!mark,wrap);
+}
+void TQtMultiLineEdit::cursorRight( bool mark, bool clear_mark, bool wrap )
+{
+ int strl = lineLength( cursorY );
+ if ( strl > 1 && !isEndOfParagraph( cursorY ) )
+ strl--;
+ if ( cursorX < strl || cursorY < (int)contents->count() - 1 && wrap ) {
+ if ( mark && !hasMarkedText() ) {
+ markAnchorX = cursorX;
+ markAnchorY = cursorY;
+ }
+ d->blinkTimer->stop();
+ cursorOn = TRUE;
+ cursorX++;
+ if ( cursorX > strl ) {
+ int oldY = cursorY;
+ if ( cursorY < (int) contents->count() - 1 ) {
+ cursorY++;
+ cursorX = 0;
+ } else {
+ cursorX = lineLength( cursorY );
+ }
+ updateCell( oldY, 0, FALSE );
+ }
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+ updateCell( cursorY, 0, FALSE );
+ d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE );
+ }
+ curXPos = 0;
+ makeVisible();
+ if ( clear_mark )
+ turnMark( FALSE );
+}
+
+/*
+ Moves the cursor up one line. If \a mark is TRUE, the text
+ is marked.
+ \sa cursorDown() cursorLeft() cursorRight()
+*/
+
+void TQtMultiLineEdit::cursorUp( bool mark )
+{
+ cursorUp(mark,!mark);
+}
+void TQtMultiLineEdit::cursorUp( bool mark, bool clear_mark )
+{
+ if ( cursorY != 0 ) {
+ if ( mark && !hasMarkedText() ) {
+ markAnchorX = cursorX;
+ markAnchorY = cursorY;
+ }
+ if ( !curXPos )
+ curXPos = mapToView( cursorX, cursorY );
+ int oldY = cursorY;
+ d->blinkTimer->stop();
+ cursorOn = TRUE;
+ cursorY--;
+ if ( cursorY < 0 ) {
+ cursorY = 0;
+ }
+ cursorX = mapFromView( curXPos, cursorY );
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+ updateCell( oldY, 0, FALSE );
+ updateCell( cursorY, 0, FALSE );
+ d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE );
+ }
+ makeVisible();
+ if ( clear_mark )
+ turnMark( FALSE );
+}
+
+/*
+ Moves the cursor one line down. If \a mark is TRUE, the text
+ is marked.
+ \sa cursorUp() cursorLeft() cursorRight()
+*/
+
+void TQtMultiLineEdit::cursorDown( bool mark )
+{
+ cursorDown(mark,!mark);
+}
+void TQtMultiLineEdit::cursorDown( bool mark, bool clear_mark )
+{
+ int lastLin = contents->count() - 1;
+ if ( cursorY != lastLin ) {
+ if ( mark && !hasMarkedText() ) {
+ markAnchorX = cursorX;
+ markAnchorY = cursorY;
+ }
+ if ( !curXPos )
+ curXPos = mapToView( cursorX, cursorY );
+ int oldY = cursorY;
+ d->blinkTimer->stop();
+ cursorOn = TRUE;
+ cursorY++;
+ if ( cursorY > lastLin ) {
+ cursorY = lastLin;
+ }
+ cursorX = mapFromView( curXPos, cursorY );
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+ updateCell( oldY, 0, FALSE );
+ updateCell( cursorY, 0, FALSE );
+ d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE );
+ }
+ makeVisible();
+ if ( clear_mark )
+ turnMark( FALSE );
+}
+
+/*
+ Turns off marked text
+*/
+void TQtMultiLineEdit::turnMark( bool on )
+{
+ if ( on != markIsOn ) {
+ markIsOn = on;
+ if ( echoMode() == Normal )
+ emit copyAvailable( on );
+ update();
+ }
+}
+
+
+
+
+/*
+ Deletes the character on the left side of the text cursor and moves
+ the cursor one position to the left. If a text has been marked by
+ the user (e.g. by clicking and dragging) the cursor is put at the
+ beginning of the marked text and the marked text is removed.
+ \sa del()
+*/
+
+void TQtMultiLineEdit::backspace()
+{
+ if ( hasMarkedText() ) {
+ del();
+ } else {
+ if ( !atBeginning() ) {
+ cursorLeft( FALSE );
+ del();
+ }
+ }
+ makeVisible();
+}
+
+void TQtMultiLineEdit::delAux()
+{
+ int markBeginX, markBeginY;
+ int markEndX, markEndY;
+ TQRect oldContents = contentsRect();
+ if ( getMarkedRegion( &markBeginY, &markBeginX, &markEndY, &markEndX ) ) {
+ turnMark( FALSE );
+ textDirty = TRUE;
+ d->edited = TRUE;
+ if ( markBeginY == markEndY ) { //just one line
+ TQtMultiLineEditRow *r = contents->at( markBeginY );
+ ASSERT(r);
+ bool recalc = r->w == maxLineWidth();
+ r->s.remove( markBeginX, markEndX - markBeginX );
+ r->w = textWidth( r->s );
+ cursorX = markBeginX;
+ cursorY = markBeginY;
+
+ if (autoUpdate() )
+ updateCell( cursorY, 0, FALSE );
+ if ( recalc )
+ updateCellWidth();
+ } else { //multiline
+ bool oldAuto = autoUpdate();
+ setAutoUpdate( FALSE );
+ ASSERT( markBeginY >= 0);
+ ASSERT( markEndY < (int)contents->count() );
+
+ TQtMultiLineEditRow *firstR, *lastR;
+ firstR = contents->at( markBeginY );
+ lastR = contents->at( markEndY );
+ ASSERT( firstR != lastR );
+ firstR->s.remove( markBeginX, firstR->s.length() - markBeginX );
+ lastR->s.remove( 0, markEndX );
+ firstR->s.append( lastR->s ); // lastS will be removed in loop below
+ firstR->newline = lastR->newline; // Don't forget this -sanders
+ firstR->w = textWidth( firstR->s );
+
+ for( int i = markBeginY + 1 ; i <= markEndY ; i++ )
+ contents->remove( markBeginY + 1 );
+
+ if ( contents->isEmpty() )
+ insertLine( TQString::tqfromLatin1(""), -1 );
+
+ cursorX = markBeginX;
+ cursorY = markBeginY;
+ curXPos = 0;
+
+ setNumRowsAndTruncate();
+ updateCellWidth();
+ setAutoUpdate( oldAuto );
+ if ( autoUpdate() )
+ update();
+ }
+ markAnchorY = markDragY = cursorY;
+ markAnchorX = markDragX = cursorX;
+ } else {
+ if ( !atEnd() ) {
+ textDirty = TRUE;
+ d->edited = TRUE;
+ TQtMultiLineEditRow *r = contents->at( cursorY );
+ if ( cursorX == (int) r->s.length() ) { // remove newline
+ TQtMultiLineEditRow* other = contents->at( cursorY + 1 );
+ if ( ! r->newline && cursorX )
+ r->s.truncate( r->s.length()-1 );
+
+ bool needBreak = !r->s.isEmpty();
+ r->s += other->s;
+ r->newline = other->newline;
+ contents->remove( cursorY + 1 );
+ if ( needBreak )
+ rebreakParagraph( cursorY, 1 );
+ else
+ wrapLine( cursorY, 1 );
+ } else {
+ bool recalc = r->w == maxLineWidth();
+ r->s.remove( cursorX, 1 );
+ rebreakParagraph( cursorY );
+ if ( recalc )
+ updateCellWidth();
+ }
+ }
+ }
+ if ( DYNAMIC_WRAP && oldContents != contentsRect() ) {
+ if ( oldContents.width() != contentsRect().width() ) {
+ bool oldAuto = autoUpdate();
+ setAutoUpdate( FALSE );
+ rebreakAll();
+ setAutoUpdate( oldAuto );
+ }
+ if ( autoUpdate() )
+ update();
+ }
+ curXPos = 0;
+ makeVisible();
+}
+
+/*
+ Moves the text cursor to the left end of the line. If \a mark is
+ TRUE, text is marked towards the first position. If it is FALSE and
+ the cursor is moved, all marked text is unmarked.
+
+ \sa end()
+*/
+
+void TQtMultiLineEdit::home( bool mark )
+{
+ if ( cursorX != 0 ) {
+ if ( mark && !hasMarkedText() ) {
+ markAnchorX = cursorX;
+ markAnchorY = cursorY;
+ }
+ d->blinkTimer->stop();
+ cursorX = 0;
+ cursorOn = TRUE;
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+ updateCell( cursorY, 0, FALSE );
+ d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE );
+ }
+ curXPos = 0;
+ if ( !mark )
+ turnMark( FALSE );
+ makeVisible();
+}
+
+/*
+ Moves the text cursor to the right end of the line. If \a mark is TRUE
+ text is marked towards the last position. If it is FALSE and the
+ cursor is moved, all marked text is unmarked.
+
+ \sa home()
+*/
+
+void TQtMultiLineEdit::end( bool mark )
+{
+ int tlen = lineLength( cursorY );
+ if ( cursorX != tlen ) {
+ if ( mark && !hasMarkedText() ) {
+ markAnchorX = cursorX;
+ markAnchorY = cursorY;
+ }
+ d->blinkTimer->stop();
+ cursorX = tlen;
+ cursorOn = TRUE;
+ if ( mark )
+ newMark( cursorX, cursorY, FALSE );
+ d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE );
+ updateCell( cursorY, 0, FALSE );
+ }
+ curXPos = 0;
+ makeVisible();
+ if ( !mark )
+ turnMark( FALSE );
+}
+
+/*\reimp
+*/
+void TQtMultiLineEdit::mousePressEvent( TQMouseEvent *e )
+{
+ stopAutoScroll();
+ d->dnd_startpos = e->pos();
+
+ if ( e->button() == RightButton ) {
+ TQPopupMenu *popup = new TQPopupMenu( this );
+ int id[ (int)IdCount ];
+ id[ IdUndo ] = popup->insertItem( tr( "Undo" ) );
+ id[ IdRedo ] = popup->insertItem( tr( "Redo" ) );
+ popup->insertSeparator();
+#ifndef TQT_NO_CLIPBOARD
+ id[ IdCut ] = popup->insertItem( tr( "Cut" ) );
+ id[ IdCopy ] = popup->insertItem( tr( "Copy" ) );
+ id[ IdPaste ] = popup->insertItem( tr( "Paste" ) );
+#ifndef TQT_NO_MIMECLIPBOARD
+ id[ IdPasteSpecial ] = popup->insertItem( tr( "Paste special..." ) );
+#endif
+#endif
+ id[ IdClear ] = popup->insertItem( tr( "Clear" ) );
+ popup->insertSeparator();
+ id[ IdSelectAll ] = popup->insertItem( tr( "Select All" ) );
+ popup->setItemEnabled( id[ IdUndo ],
+ !this->d->undoList.isEmpty() );
+ popup->setItemEnabled( id[ IdRedo ],
+ !this->d->redoList.isEmpty() );
+#ifndef TQT_NO_CLIPBOARD
+ popup->setItemEnabled( id[ IdCut ],
+ !isReadOnly() && hasMarkedText() );
+ popup->setItemEnabled( id[ IdCopy ], hasMarkedText() );
+ popup->setItemEnabled( id[ IdPaste ],
+ !isReadOnly() && (bool)TQApplication::clipboard()->text().length() );
+#ifndef TQT_NO_MIMECLIPBOARD
+ // Any non-plain types?
+ TQMimeSource* ms = TQApplication::clipboard()->data();
+ bool ps = FALSE;
+ if ( ms ) {
+ if ( !isReadOnly() ) {
+ const char* fmt;
+ for (int i=0; !ps && (fmt=ms->format(i)); i++) {
+ ps = qstrnicmp(fmt,"text/",5)==0
+ && qstrnicmp(fmt+5,"plain",5)!=0;
+ }
+ }
+ }
+ popup->setItemEnabled( id[ IdPasteSpecial ], ps );
+#endif
+#endif
+ popup->setItemEnabled( id[ IdClear ],
+ !isReadOnly() && (bool)text().length() );
+ int allSelected = markIsOn && markAnchorX == 0 && markAnchorY == 0 &&
+ markDragY == numLines() - 1 && markDragX == lineLength( markDragY );
+ popup->setItemEnabled( id[ IdSelectAll ],
+ (bool)text().length() && !allSelected );
+
+ int r = popup->exec( e->globalPos() );
+ delete popup;
+
+ if ( r == id[ IdUndo ] )
+ undo();
+ else if ( r == id[ IdRedo ] )
+ redo();
+#ifndef TQT_NO_CLIPBOARD
+ else if ( r == id[ IdCut ] )
+ cut();
+ else if ( r == id[ IdCopy ] )
+ copy();
+ else if ( r == id[ IdPaste ] )
+ paste();
+# ifndef TQT_NO_MIMECLIPBOARD
+ else if ( r == id[ IdPasteSpecial ] )
+ pasteSpecial(TQCursor::pos());
+# endif
+#endif
+ else if ( r == id[ IdClear ] )
+ clear();
+ else if ( r == id[ IdSelectAll ] )
+ selectAll();
+ return;
+ }
+
+ if ( e->button() != MidButton && e->button() != LeftButton)
+ return;
+
+ int newX, newY;
+ pixelPosToCursorPos( e->pos(), &newX, &newY );
+
+ if ( e->state() & ShiftButton ) {
+ wordMark = FALSE;
+ dragMarking = TRUE;
+ setCursorPosition( newY, newX, TRUE);
+ return;
+ }
+
+#ifndef TQT_NO_DRAGANDDROP
+ if (
+ inMark(newX, newY) // Click on highlighted text
+ && echoMode() == Normal // No DnD of passwords, etc.
+ && e->pos().y() < totalHeight() // Click past the end is not dragging
+ )
+ {
+ // The user might be trying to drag
+ d->dnd_primed = TRUE;
+ d->dnd_timer->start( TQApplication::startDragTime(), FALSE );
+ } else
+#endif
+ {
+ wordMark = FALSE;
+ dragMarking = TRUE;
+ setCursorPixelPosition(e->pos());
+ }
+}
+
+void TQtMultiLineEdit::pixelPosToCursorPos(TQPoint p, int* x, int* y) const
+{
+ *y = tqfindRow( p.y() );
+ if ( *y < 0 ) {
+ if ( p.y() < lineWidth() ) {
+ *y = topCell();
+ } else {
+ *y = lastRowVisible();
+ p.setX(cellWidth());
+ }
+ }
+ *y = TQMIN( (int)contents->count() - 1, *y );
+ TQFontMetrics fm( font() );
+ *x = xPosToCursorPos( stringShown( *y ), fm,
+ p.x() - d->lr_marg + xOffset(),
+ cellWidth() - 2 * d->lr_marg - d->marg_extra,
+ d->align );
+ TQtMultiLineEditRow* r = contents->at( *y );
+ if (r && !r->newline && ((unsigned int)*x == r->s.length()) && (*x > 0))
+ --*x;
+}
+
+void TQtMultiLineEdit::setCursorPixelPosition(TQPoint p, bool clear_mark)
+{
+ int newY;
+ pixelPosToCursorPos( p, &cursorX, &newY );
+ curXPos = 0;
+ if ( clear_mark ) {
+ markAnchorX = cursorX;
+ markAnchorY = newY;
+ bool markWasOn = markIsOn;
+ turnMark( FALSE );
+ if ( markWasOn ) {
+ cursorY = newY;
+ update();
+ d->isHandlingEvent = FALSE;
+ return;
+ }
+ }
+ if ( cursorY != newY ) {
+ int oldY = cursorY;
+ cursorY = newY;
+ updateCell( oldY, 0, FALSE );
+ }
+ updateCell( cursorY, 0, FALSE ); // ###
+}
+
+void TQtMultiLineEdit::startAutoScroll()
+{
+ if ( !dragScrolling ) {
+ d->scrollTime = initialScrollTime;
+ d->scrollAccel = initialScrollAccel;
+ d->scrollTimer->start( d->scrollTime, FALSE );
+ dragScrolling = TRUE;
+ }
+}
+
+void TQtMultiLineEdit::stopAutoScroll()
+{
+ if ( dragScrolling ) {
+ d->scrollTimer->stop();
+ dragScrolling = FALSE;
+ }
+}
+
+/*\reimp
+*/
+void TQtMultiLineEdit::mouseMoveEvent( TQMouseEvent *e )
+{
+#ifndef TQT_NO_DRAGANDDROP
+ d->dnd_timer->stop();
+ if ( d->dnd_primed &&
+ ( d->dnd_startpos - e->pos() ).manhattanLength() > TQApplication::startDragDistance() ) {
+ doDrag();
+ return;
+ }
+#endif
+ if ( !dragMarking )
+ return;
+ if ( rect().tqcontains( e->pos() ) ) {
+ stopAutoScroll();
+ } else if ( !dragScrolling ) {
+ startAutoScroll();
+ }
+
+ int newX, newY;
+ pixelPosToCursorPos(e->pos(), &newX, &newY);
+
+ if ( wordMark ) {
+ extendSelectionWord( newX, newY);
+ }
+
+ if ( markDragX == newX && markDragY == newY )
+ return;
+ int oldY = markDragY;
+ newMark( newX, newY, FALSE );
+ for ( int i = TQMIN(oldY,newY); i <= TQMAX(oldY,newY); i++ )
+ updateCell( i, 0, FALSE );
+}
+
+void TQtMultiLineEdit::extendSelectionWord( int &newX, int&newY)
+{
+ TQString s = stringShown( newY );
+ int lim = s.length();
+ if ( newX >= 0 && newX < lim ) {
+ int i = newX;
+ int startclass = charClass(s.at(i));
+ if ( markAnchorY < markDragY ||
+ ( markAnchorY == markDragY && markAnchorX < markDragX ) ) {
+ // going right
+ while ( i < lim && charClass(s.at(i)) == startclass )
+ i++;
+ } else {
+ // going left
+ while ( i >= 0 && charClass(s.at(i)) == startclass )
+ i--;
+ i++;
+ }
+ newX = i;
+ }
+}
+
+
+
+
+/*\reimp
+*/
+void TQtMultiLineEdit::mouseReleaseEvent( TQMouseEvent *e )
+{
+ stopAutoScroll();
+#ifndef TQT_NO_DRAGANDDROP
+ if ( d->dnd_timer->isActive() ) {
+ d->dnd_timer->stop();
+ d->dnd_primed = FALSE;
+ setCursorPixelPosition(e->pos());
+ }
+#endif
+ wordMark = FALSE;
+ dragMarking = FALSE;
+ textDirty = FALSE;
+ d->isHandlingEvent = TRUE;
+ if ( markAnchorY == markDragY && markAnchorX == markDragX )
+ turnMark( FALSE );
+
+#ifndef TQT_NO_CLIPBOARD
+#if defined(_WS_X11_)
+ else if ( echoMode() == Normal )
+ copy();
+#endif
+
+ if ( e->button() == MidButton && !readOnly ) {
+#if defined(_WS_X11_)
+ paste(); // Will tqrepaint the cursor line.
+#else
+#ifndef TQT_NO_COMPAT
+ if ( style().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle )
+ paste();
+#endif
+#endif
+ }
+#endif
+
+ d->isHandlingEvent = FALSE;
+
+ if ( !readOnly && textDirty )
+ emit textChanged();
+}
+
+
+/*\reimp
+*/
+void TQtMultiLineEdit::mouseDoubleClickEvent( TQMouseEvent *m )
+{
+ if ( m->button() == LeftButton ) {
+ if ( m->state() & ShiftButton ) {
+ int newX = cursorX;
+ int newY = cursorY;
+ extendSelectionWord( newX, newY);
+ newMark( newX, newY, FALSE );
+ } else {
+ markWord( cursorX, cursorY );
+ }
+ dragMarking = TRUE;
+ wordMark = TRUE;
+ updateCell( cursorY, 0, FALSE );
+
+ }
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*
+ \reimp
+*/
+
+void TQtMultiLineEdit::dragEnterEvent( TQDragEnterEvent * )
+{
+ cursorOn = TRUE;
+ updateCell( cursorY, 0, FALSE );
+}
+
+/*\reimp
+*/
+void TQtMultiLineEdit::dragMoveEvent( TQDragMoveEvent* event )
+{
+ if ( readOnly ) return;
+ event->accept( TQTextDrag::canDecode(event) );
+ d->dnd_forcecursor = TRUE;
+ setCursorPixelPosition(event->pos(), FALSE);
+ d->dnd_forcecursor = FALSE;
+ TQRect inside_margin(scroll_margin, scroll_margin,
+ width()-scroll_margin*2, height()-scroll_margin*2);
+ if ( !inside_margin.tqcontains(event->pos()) ) {
+ startAutoScroll();
+ }
+ if ( event->source() == this && event->action() == TQDropEvent::Move )
+ event->acceptAction();
+}
+
+/*\reimp
+*/
+void TQtMultiLineEdit::dragLeaveEvent( TQDragLeaveEvent* )
+{
+ if ( cursorOn ) {
+ cursorOn = FALSE;
+ updateCell( cursorY, 0, FALSE );
+ }
+ stopAutoScroll();
+}
+
+/*\reimp
+*/
+void TQtMultiLineEdit::dropEvent( TQDropEvent* event )
+{
+ if ( readOnly ) return;
+ TQString text;
+ TQCString fmt = pickSpecial(event,FALSE,event->pos());
+ if ( TQTextDrag::decode(event, text, fmt) ) {
+ int i = -1;
+ while ( ( i = text.tqfind( '\r' ) ) != -1 )
+ text.tqreplace( i,1,"" );
+ if ( event->source() == this && event->action() == TQDropEvent::Move ) {
+ event->acceptAction();
+ // Careful not to tread on my own feet
+ int newX, newY;
+ pixelPosToCursorPos( event->pos(), &newX, &newY );
+ if ( afterMark( newX, newY ) ) {
+ // The tricky case
+ int x1, y1, x2, y2;
+ getMarkedRegion( &y1, &x1, &y2, &x2 );
+ if ( newY == y2 ) {
+ newY = y1;
+ newX = x1 + newX - x2;
+ } else {
+ newY -= y2 - y1;
+ }
+ addUndoCmd( new TQBeginCommand );
+ del();
+ setCursorPosition(newY, newX);
+ insert(text, TRUE);
+ addUndoCmd( new TQEndCommand );
+ } else if ( beforeMark( newX, newY ) ) {
+ // Easy
+ addUndoCmd( new TQBeginCommand );
+ del();
+ setCursorPosition(newY, newX);
+ insert(text, TRUE);
+ addUndoCmd( new TQEndCommand );
+ } else {
+ // Do nothing.
+ }
+ } else {
+ setCursorPixelPosition(event->pos());
+ insert(text, TRUE);
+ }
+ update();
+ emit textChanged();
+ }
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+
+/*
+ Returns TRUE if line \a line is invisible or partially invisible.
+*/
+
+bool TQtMultiLineEdit::partiallyInvisible( int line )
+{
+ int y;
+ if ( !rowYPos( line, &y ) )
+ return TRUE;
+ if ( y < 0 )
+ return TRUE;
+ else if ( y + cellHeight() - 2 > viewHeight() )
+ return TRUE;
+
+ return FALSE;
+}
+
+/*
+ Scrolls such that the cursor is visible
+*/
+
+void TQtMultiLineEdit::makeVisible()
+{
+ if ( !autoUpdate() )
+ return;
+
+ if ( partiallyInvisible( cursorY ) ) {
+ if ( cursorY >= lastRowVisible() )
+ setBottomCell( cursorY );
+ else
+ setTopCell( cursorY );
+ }
+ int xPos = mapToView( cursorX, cursorY );
+ if ( xPos < xOffset() ) {
+ int of = xPos - 10; //###
+ setXOffset( of );
+ } else if ( xPos > xOffset() + viewWidth() ) {
+ int of = xPos - viewWidth() + 10; //###
+ setXOffset( of );
+ }
+}
+
+/*
+ Computes the character position in line \a line which corresponds
+ to pixel \a xPos
+*/
+
+int TQtMultiLineEdit::mapFromView( int xPos, int line )
+{
+ TQString s = stringShown( line );
+ if ( !s )
+ return 0;
+ TQFontMetrics fm( font() );
+ int index = xPosToCursorPos( s, fm,
+ xPos - d->lr_marg,
+ cellWidth() - 2 * d->lr_marg - d->marg_extra,
+ d->align );
+ TQtMultiLineEditRow* r = contents->at( line );
+ if (r && !r->newline && ((unsigned int)index == r->s.length()) && (index > 0))
+ --index;
+ return index;
+}
+
+/*
+ Computes the pixel position in line \a line which corresponds to
+ character position \a xIndex
+*/
+
+int TQtMultiLineEdit::mapToView( int xIndex, int line )
+{
+ TQString s = stringShown( line );
+ xIndex = TQMIN( (int)s.length(), xIndex );
+ TQFontMetrics fm( font() );
+ int wcell = cellWidth() - 2 * d->lr_marg;// - d->marg_extra;
+ int wrow = contents->at( line )->w;
+ int w = textWidthWithTabs( fm, s, 0, xIndex, d->align ) - 1;
+ if ( d->align == TQt::AlignCenter || d->align == TQt::AlignHCenter )
+ w += (wcell - wrow) / 2;
+ else if ( d->align == TQt::AlignRight )
+ w += wcell - wrow;
+ return d->lr_marg + w;
+}
+
+/*
+ Traverses the list and tqfinds an item with the maximum width, and
+ updates the internal list box structures accordingly.
+*/
+
+void TQtMultiLineEdit::updateCellWidth()
+{
+ TQtMultiLineEditRow* r = contents->first();
+ int maxW = 0;
+ int w;
+ switch ( d->echomode ) {
+ case Normal:
+ while ( r ) {
+ w = r->w;
+ if ( w > maxW )
+ maxW = w;
+ r = contents->next();
+ }
+ break;
+ case Password: {
+ uint l = 0;
+ while ( r ) {
+ l = TQMAX(l, r->s.length() );
+ r = contents->next();
+ }
+ TQString t;
+ t.fill(TQChar('*'), l);
+ maxW = textWidth(t);
+ }
+ break;
+ case NoEcho:
+ maxW = textWidth(TQString::tqfromLatin1(""));
+ }
+ setWidth( maxW );
+}
+
+
+/*
+ Sets the bottommost visible line to \a line.
+*/
+
+void TQtMultiLineEdit::setBottomCell( int line )
+{
+ int rowY = cellHeight() * line;
+ int newYPos = rowY + cellHeight() - viewHeight();
+ setYOffset( TQMAX( newYPos, 0 ) );
+}
+
+#ifndef TQT_NO_CLIPBOARD
+
+/*
+ Copies text in MIME subtype \a subtype from the clipboard onto the current
+ cursor position.
+ Any marked text is first deleted.
+*/
+void TQtMultiLineEdit::pasteSubType(const TQCString& subtype)
+{
+ TQCString st = subtype;
+ addUndoCmd( new TQBeginCommand );
+
+ if ( hasMarkedText() )
+ del();
+ TQString t = TQApplication::clipboard()->text(st);
+ if ( !t.isEmpty() ) {
+ if ( hasMarkedText() )
+ turnMark( FALSE );
+
+#if defined(_OS_WIN32_)
+ // Need to convert CRLF to NL
+ t.tqreplace( "\r\n", "\n" );
+#endif
+
+ for (int i=0; (uint)i<t.length(); i++) {
+ if ( t[i] < ' ' && t[i] != '\n' && t[i] != '\t' )
+ t[i] = ' ';
+ }
+ insertAt( t, cursorY, cursorX );
+ turnMark( FALSE );
+ curXPos = 0;
+ makeVisible();
+ }
+ if ( textDirty && !d->isHandlingEvent )
+ emit textChanged();
+
+ addUndoCmd( new TQEndCommand );
+}
+
+/*
+ Copies plain text from the clipboard onto the current cursor position.
+ Any marked text is first deleted.
+*/
+void TQtMultiLineEdit::paste()
+{
+ pasteSubType("plain");
+}
+
+#ifndef TQT_NO_MIMECLIPBOARD
+/*
+ Prompts the user for a type from a list of text types available,
+ Then copies text from the clipboard onto the current cursor position.
+ Any marked text is first deleted.
+*/
+void TQtMultiLineEdit::pasteSpecial(const TQPoint& pt)
+{
+ TQCString st = pickSpecial(TQApplication::clipboard()->data(),TRUE,pt);
+ if ( !st.isEmpty() )
+ pasteSubType(st);
+}
+#endif
+#ifndef TQT_NO_MIME
+TQCString TQtMultiLineEdit::pickSpecial(TQMimeSource* ms, bool always_ask, const TQPoint& pt)
+{
+ if ( ms ) {
+ TQPopupMenu popup(this);
+ TQString fmt;
+ int n=0;
+ TQDict<void> done;
+ for (int i=0; !(fmt=ms->format(i)).isNull(); i++) {
+ int semi=fmt.tqfind(";");
+ if ( semi >= 0 )
+ fmt = fmt.left(semi);
+ if ( fmt.left(5) == "text/" ) {
+ fmt = fmt.mid(5);
+ if ( !done.tqfind(fmt) ) {
+ done.insert(fmt,(void*)1);
+ popup.insertItem(fmt,i);
+ n++;
+ }
+ }
+ }
+ if ( n ) {
+ int i = n==1 && !always_ask ? popup.idAt(0) : popup.exec(pt);
+ if ( i >= 0 )
+ return popup.text(i).latin1();
+ }
+ }
+ return TQCString();
+}
+#endif // TQT_NO_MIME
+#endif // TQT_NO_CLIPBOARD
+
+
+/*
+ Removes all text.
+*/
+
+void TQtMultiLineEdit::clear()
+{
+ addUndoCmd( new TQDelTextCmd( 0, text() ) );
+ setEdited( TRUE );
+ contents->clear();
+ cursorX = cursorY = 0;
+ int w = textWidth( TQString::tqfromLatin1("") );
+ contents->append( new TQtMultiLineEditRow(TQString::tqfromLatin1(""), w) );
+ setNumRowsAndTruncate();
+ setWidth( w );
+ dummy = TRUE;
+ turnMark( FALSE );
+ if ( autoUpdate() )
+ update();
+ if ( !d->isHandlingEvent ) //# && not already empty
+ emit textChanged();
+ update();
+}
+
+
+/*\reimp
+*/
+
+void TQtMultiLineEdit::setFont( const TQFont &font )
+{
+ TQWidget::setFont( font );
+ d->clearChartable();
+ TQFontMetrics fm( font );
+ setCellHeight( fm.lineSpacing() );
+ for ( TQtMultiLineEditRow* r = contents->first(); r; r = contents->next() )
+ r->w = textWidth( r->s );
+ rebreakAll();
+ updateCellWidth();
+}
+
+/*
+ Sets a new marked text limit, does not tqrepaint the widget.
+*/
+
+void TQtMultiLineEdit::newMark( int posx, int posy, bool /*copy*/ )
+{
+ if ( markIsOn && markDragX == posx && markDragY == posy &&
+ cursorX == posx && cursorY == posy )
+ return;
+ markDragX = posx;
+ markDragY = posy;
+ cursorX = posx;
+ cursorY = posy;
+ turnMark( markDragX != markAnchorX || markDragY != markAnchorY );
+}
+
+bool TQtMultiLineEdit::beforeMark( int posx, int posy ) const
+{
+ int x1, y1, x2, y2;
+ if ( !getMarkedRegion( &y1, &x1, &y2, &x2 ) )
+ return FALSE;
+ return
+ (y1 > posy || y1 == posy && x1 > posx)
+ && (y2 > posy || y2 == posy && x2 > posx);
+}
+
+bool TQtMultiLineEdit::afterMark( int posx, int posy ) const
+{
+ int x1, y1, x2, y2;
+ if ( !getMarkedRegion( &y1, &x1, &y2, &x2 ) )
+ return FALSE;
+ return
+ (y1 < posy || y1 == posy && x1 < posx)
+ && (y2 < posy || y2 == posy && x2 < posx);
+}
+
+bool TQtMultiLineEdit::inMark( int posx, int posy ) const
+{
+ int x1, y1, x2, y2;
+ if ( !getMarkedRegion( &y1, &x1, &y2, &x2 ) )
+ return FALSE;
+ return
+ (y1 < posy || y1 == posy && x1 <= posx)
+ && (y2 > posy || y2 == posy && x2 >= posx);
+}
+
+/*
+ Marks the word at character position \a posx, \a posy.
+ */
+void TQtMultiLineEdit::markWord( int posx, int posy )
+{
+ TQString& s = contents->at( posy )->s;
+
+ int i = posx - 1;
+ while ( i >= 0 && s[i].isPrint() && !s[i].isSpace() )
+ i--;
+ i++;
+ markAnchorY = posy;
+ markAnchorX = i;
+
+ while ( s[i].isPrint() && !s[i].isSpace() )
+ i++;
+ markDragX = i;
+ markDragY = posy;
+ turnMark( markDragX != markAnchorX || markDragY != markAnchorY );
+
+#ifndef TQT_NO_CLIPBOARD
+#if defined(_WS_X11_)
+ if ( echoMode() == Normal )
+ copy();
+#endif
+#endif
+}
+
+/*
+ This may become a protected virtual member in a future TQt.
+ This implementation is an example of a useful classification
+ that aids selection of common units like filenames and URLs.
+*/
+int TQtMultiLineEdit::charClass( TQChar ch )
+{
+ if ( !ch.isPrint() || ch.isSpace() ) return 1;
+ else if ( ch.isLetter() || ch=='-' || ch=='+' || ch==':'
+ || ch=='.' || ch=='/' || ch=='\\'
+ || ch=='@' || ch=='$' || ch=='~' ) return 2;
+ else return 3;
+}
+
+#ifndef TQT_NO_CLIPBOARD
+/*
+ Copies the marked text to the clipboard. Will copy only
+ if echoMode() is Normal.
+*/
+
+void TQtMultiLineEdit::copy() const
+{
+ TQString t = markedText();
+ if ( !t.isEmpty() && echoMode() == Normal ) {
+#if defined(_WS_X11_)
+ disconnect( TQApplication::clipboard(), TQT_SIGNAL(dataChanged()), this, 0);
+#endif
+#if defined(_OS_WIN32_)
+ // Need to convert NL to CRLF
+ t.tqreplace( "\n", "\r\n" );
+#endif
+ TQApplication::clipboard()->setText( t );
+#if defined(_WS_X11_)
+ connect( TQApplication::clipboard(), TQT_SIGNAL(dataChanged()),
+ this, TQT_SLOT(clipboardChanged()) );
+#endif
+ }
+}
+
+/* \obsolete
+
+ Backward compatibility.
+*/
+void TQtMultiLineEdit::copyText() const
+{
+ copy();
+}
+
+/*
+ Copies the selected text to the clipboard and deletes the selected text.
+*/
+
+void TQtMultiLineEdit::cut()
+{
+ if ( hasMarkedText() ) {
+ if ( echoMode() == Normal )
+ copy();
+ del();
+ if ( textDirty && !d->isHandlingEvent )
+ emit textChanged();
+ }
+}
+
+#endif
+
+/*
+ This private slot is activated when this line edit owns the clipboard and
+ some other widget/application takes over the clipboard. (X11 only)
+*/
+
+void TQtMultiLineEdit::clipboardChanged()
+{
+#if defined(_WS_X11_)
+ disconnect( TQApplication::clipboard(), TQT_SIGNAL(dataChanged()),
+ this, TQT_SLOT(clipboardChanged()) );
+ turnMark( FALSE );
+ update();
+#endif
+}
+
+
+/*
+ Sets maxLineWidth() and maybe cellWidth() to \a w without updating the entire widget.
+ */
+
+void TQtMultiLineEdit::setWidth( int w )
+{
+ if ( w ==d->maxLineWidth )
+ return;
+ bool u = autoUpdate();
+ setAutoUpdate( FALSE );
+ d->maxLineWidth = w;
+ if ( d->align == AlignLeft )
+ setCellWidth( w );
+ else
+ setCellWidth( TQMAX( w, contentsRect().width() ) );
+ setAutoUpdate( u );
+ if ( autoUpdate() && d->align != AlignLeft )
+ update();
+}
+
+
+/*
+ Sets the cursor position to character number \a col in line number \a line.
+ The parameters are adjusted to lie within the legal range.
+
+ If \a mark is FALSE, the selection is cleared. otherwise it is extended
+
+ \sa cursorPosition()
+*/
+
+void TQtMultiLineEdit::setCursorPosition( int line, int col, bool mark )
+{
+ if ( mark && !hasMarkedText() ) {
+ markAnchorX = cursorX;
+ markAnchorY = cursorY;
+ }
+ int oldY = cursorY;
+ cursorY = TQMAX( TQMIN( line, numLines() - 1), 0 );
+ cursorX = TQMAX( TQMIN( col, lineLength( cursorY )), 0 );
+ curXPos = 0;
+ makeVisible();
+ if ( mark ) {
+ newMark( cursorX, cursorY, FALSE );
+ for ( int i = TQMIN(oldY,cursorY); i <= TQMAX(oldY,cursorY); i++ )
+ updateCell( i, 0, FALSE );
+ } else {
+ updateCell( oldY, 0, FALSE );
+ turnMark( FALSE );
+ }
+}
+
+
+
+/* \obsolete
+
+ Use getCursorPosition() instead.
+*/
+
+void TQtMultiLineEdit::cursorPosition( int *line, int *col ) const
+{
+ getCursorPosition(line,col);
+}
+
+
+/*
+ Returns the current line and character
+ position within that line, in the variables pointed to
+ by \a line and \a col respectively.
+
+ \sa setCursorPosition()
+*/
+
+void TQtMultiLineEdit::getCursorPosition( int *line, int *col ) const
+{
+ if ( line )
+ *line = cursorY;
+ if ( col )
+ *col = cursorX;
+}
+
+
+/*
+ \sa setAutoUpdate()
+*/
+
+bool TQtMultiLineEdit::autoUpdate() const
+{
+ return TQtTableView::autoUpdate();
+}
+
+
+/*
+ Sets the auto-update option of multi-line editor to \a enable.
+
+*/
+
+void TQtMultiLineEdit::setAutoUpdate( bool enable )
+{
+ TQtTableView::setAutoUpdate( enable );
+}
+
+/*
+ Sets the fixed height of the TQtMultiLineEdit so that \a lines text lines
+ are visible given the current font.
+
+ \sa setMaxLines(), setFixedHeight()
+ */
+void TQtMultiLineEdit::setFixedVisibleLines( int lines )
+{
+ int ls = fontMetrics().lineSpacing();
+ setFixedHeight( frameWidth()*2 + ls*lines );
+ return;
+}
+
+
+
+/*
+ Returns the top center point where the cursor is drawn
+*/
+
+TQPoint TQtMultiLineEdit::cursorPoint() const
+{
+ TQPoint cp( 0, 0 );
+
+ TQFontMetrics fm( font() );
+ int col, row;
+ col = row = 0;
+ cursorPosition( &row, &col );
+ TQString line = textLine( row );
+ ASSERT( line );
+ cp.setX( d->lr_marg + textWidthWithTabs( fm, line, 0, col, d->align ) - 1 );
+ cp.setY( (row * cellHeight()) + viewRect().y() );
+ return cp;
+}
+
+
+/* \reimp
+*/
+TQSizePolicy TQtMultiLineEdit::sizePolicy() const
+{
+ //### removeme 3.0
+ return TQWidget::sizePolicy();
+}
+
+
+/*\reimp
+*/
+TQSize TQtMultiLineEdit::tqsizeHint() const
+{
+ constPolish();
+ int expected_lines;
+ if ( d->maxlines >= 0 && d->maxlines <= 6 ) {
+ expected_lines = d->maxlines;
+ } else {
+ expected_lines = 6;
+ }
+ TQFontMetrics fm( font() );
+ int h = fm.lineSpacing()*(expected_lines-1)+fm.height() + frameWidth()*2;
+ int w = fm.width('x')*35;
+
+ int maxh = tqmaximumSize().height();
+ if ( maxh < TQWIDGETSIZE_MAX )
+ h = maxh;
+
+ return TQSize( w, h ).expandedTo( TQApplication::globalStrut() );
+}
+
+
+/*
+ Returns a size sufficient for one character, and scroll bars.
+*/
+
+TQSize TQtMultiLineEdit::tqminimumSizeHint() const
+{
+ constPolish();
+ TQFontMetrics fm( font() );
+ int h = fm.lineSpacing() + frameWidth()*2;
+ int w = fm.maxWidth();
+ h += frameWidth();
+ w += frameWidth();
+ if ( testTableFlags(Tbl_hScrollBar|Tbl_autoHScrollBar) )
+ w += verticalScrollBar()->tqsizeHint().width();
+ if ( testTableFlags(Tbl_vScrollBar|Tbl_autoVScrollBar) )
+ h += horizontalScrollBar()->tqsizeHint().height();
+ return TQSize(w,h);
+}
+
+
+
+/*\reimp
+*/
+
+void TQtMultiLineEdit::resizeEvent( TQResizeEvent *e )
+{
+ int oldw = contentsRect().width();
+ TQtTableView::resizeEvent( e );
+ if ( DYNAMIC_WRAP
+ && (e->oldSize().width() != width()
+ || oldw != contentsRect().width() ) ) {
+ bool oldAuto = autoUpdate();
+ setAutoUpdate( FALSE );
+ rebreakAll();
+ if ( oldw != contentsRect().width() )
+ rebreakAll();
+ setAutoUpdate( oldAuto );
+ if ( autoUpdate() )
+ tqrepaint( FALSE );
+ } else if ( d->align != AlignLeft ) {
+ d->maxLineWidth = 0; // trigger update
+ updateCellWidth();
+ }
+ if ( isVisible() )
+ deselect();
+}
+
+/*
+ Sets the tqalignment to \a flags. Possible values are \c AlignLeft, \c
+ Align(H)Center and \c AlignRight.
+
+ \sa tqalignment(), TQt::AlignmentFlags
+*/
+void TQtMultiLineEdit::tqsetAlignment( int flags )
+{
+ if ( d->align != flags ) {
+ d->align = flags;
+ update();
+ }
+}
+
+/*
+ Returns the tqalignment.
+
+*/
+int TQtMultiLineEdit::tqalignment() const
+{
+ return d->align;
+}
+
+
+/*
+ Not supported at this time.
+ \a v is the validator to set.
+*/
+void TQtMultiLineEdit::setValidator( const TQValidator *v )
+{
+ d->val = v;
+ // #### validate text now
+}
+
+/*
+ Not supported at this time.
+*/
+const TQValidator * TQtMultiLineEdit::validator() const
+{
+ return d->val;
+}
+
+/* \sa edited()
+*/
+void TQtMultiLineEdit::setEdited( bool e )
+{
+ d->edited = e;
+}
+
+/* \sa setEdited()
+*/
+bool TQtMultiLineEdit::edited() const
+{
+ return d->edited;
+}
+
+/* \enum TQtMultiLineEdit::EchoMode
+
+ This enum type describes the ways in which TQLineEdit can display its
+ contents. The currently defined values are: \list
+
+ \i Normal - display characters as they are entered. This is
+ the default.
+
+ \i NoEcho - do not display anything.
+
+ \i Password - display asterisks instead of the characters
+ actually entered.
+
+ \endlist
+
+ \sa setEchoMode() echoMode() TQLineEdit::EchoMode
+*/
+
+
+/*
+ Sets the echo mode to \a em. The default is \c Normal.
+
+ The display is updated according.
+
+ \sa setEchoMode()
+*/
+void TQtMultiLineEdit::setEchoMode( EchoMode em )
+{
+ if ( d->echomode != em ) {
+ d->echomode = em;
+ updateCellWidth();
+ update();
+ }
+}
+
+/*
+ Returns the currently set echo mode.
+
+ \sa setEchoMode()
+*/
+TQtMultiLineEdit::EchoMode TQtMultiLineEdit::echoMode() const
+{
+ return d->echomode;
+}
+
+
+/*
+ Returns the string shown at line \a row, including
+ processing of the echoMode().
+*/
+
+TQString TQtMultiLineEdit::stringShown(int row) const
+{
+ TQString* s = getString(row);
+ if ( !s ) return TQString::null;
+ switch ( d->echomode ) {
+ case Normal:
+ if (!*s) return TQString::tqfromLatin1("");
+ return *s;
+ case Password:
+ {
+ TQString r;
+ r.fill(TQChar('*'), (int)s->length());
+ if ( !r ) r = TQString::tqfromLatin1("");
+ return r;
+ }
+ case NoEcho:
+ return TQString::tqfromLatin1("");
+ }
+ return TQString::tqfromLatin1("");
+}
+
+/*
+
+ \sa maxLength()
+*/
+void TQtMultiLineEdit::setMaxLength(int m)
+{
+ d->maxlen = m;
+}
+
+/*
+ \sa setMaxLength()
+*/
+int TQtMultiLineEdit::maxLength() const
+{
+ return d->maxlen;
+}
+
+
+/*
+ Returns the length of the current text.
+
+ \sa setMaxLength()
+ */
+int TQtMultiLineEdit::length() const
+{
+ int l = 0;
+ for ( TQtMultiLineEditRow* r = contents->first(); r; r = contents->next() ) {
+ l += r->s.length();
+ if ( r->newline )
+ ++l;
+ }
+ return l-1;
+}
+
+
+/*
+ Sets the maximum length of lines to \a m. Use -1 for unlimited
+ (the default). Existing long lines will be truncated.
+
+ \sa maxLineLength()
+*/
+void TQtMultiLineEdit::setMaxLineLength(int m)
+{
+ bool trunc = d->maxlinelen < 0 || m < d->maxlinelen;
+ d->maxlinelen = m;
+ if ( trunc ) {
+ TQtMultiLineEditRow* r = contents->first();
+ while ( r ) {
+ r->s.truncate( m );
+ r = contents->next();
+ }
+ if ( cursorX > m ) cursorX = m;
+ if ( markAnchorX > m ) markAnchorX = m;
+ if ( markDragX > m ) markDragX = m;
+ update();
+ updateCellWidth();
+ }
+}
+
+/*
+ Returns the currently set line length limit, or -1 if there is
+ no limit (this is the default).
+
+ \sa setMaxLineLength()
+*/
+int TQtMultiLineEdit::maxLineLength() const
+{
+ return d->maxlinelen;
+}
+
+/*
+ Sets the maximum number of lines to \a m. Use -1 for unlimited
+ (the default). Existing excess lines will be deleted.
+
+ \sa maxLines(), numLines()
+*/
+void TQtMultiLineEdit::setMaxLines(int m)
+{
+ if ( m == 0 ) // bad value
+ m = -1;
+ d->maxlines = m;
+ if ( d->maxlines >= 0 && d->maxlines <= 6 ) {
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
+ } else {
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) );
+ }
+ if ( setNumRowsAndTruncate() ) {
+ updateCellWidth();
+ update();
+ }
+}
+
+/*
+ \sa setMaxLines()
+*/
+int TQtMultiLineEdit::maxLines() const
+{
+ return d->maxlines;
+}
+
+/*
+ Sets the horizontal margin to \a m.
+
+ \sa hMargin()
+*/
+void TQtMultiLineEdit::setHMargin(int m)
+{
+ if ( m != d->lr_marg ) {
+ d->lr_marg = m;
+ updateCellWidth();
+ update();
+ }
+}
+
+/*
+
+ \sa setHMargin()
+*/
+int TQtMultiLineEdit::hMargin() const
+{
+ return d->lr_marg;
+}
+
+/*
+ Marks the text starting at \a row_from, \a col_from and ending
+ at \a row_to, \a col_to.
+*/
+void TQtMultiLineEdit::setSelection( int row_from, int col_from,
+ int row_to, int col_to )
+{
+ setCursorPosition( row_from, col_from, FALSE );
+ setCursorPosition( row_to, col_to, TRUE );
+}
+
+
+/*
+ Moves the cursor one word to the right. If \a mark is TRUE, the text
+ is marked.
+ \sa cursorWordBackward()
+*/
+void TQtMultiLineEdit::cursorWordForward( bool mark )
+{
+ int x = cursorX;
+ int y = cursorY;
+
+ if ( x == lineLength( y ) || textLine(y).at(x).isSpace() ) {
+ while ( x < lineLength( y ) && textLine(y).at(x).isSpace() )
+ ++x;
+ if ( x == lineLength( y ) ) {
+ if ( y < (int)contents->count() - 1) {
+ ++y;
+ x = 0;
+ while ( x < lineLength( y ) && textLine(y).at(x).isSpace() )
+ ++x;
+ }
+ }
+ }
+ else {
+ while ( x < lineLength( y ) && !textLine(y).at(x).isSpace() )
+ ++x;
+ int xspace = x;
+ while ( xspace < lineLength( y ) && textLine(y).at(xspace).isSpace() )
+ ++xspace;
+ if ( xspace < lineLength( y ) )
+ x = xspace;
+ }
+ cursorOn = TRUE;
+ int oldY = cursorY;
+ setCursorPosition( y, x, mark );
+ if ( oldY != cursorY )
+ updateCell( oldY, 0, FALSE );
+ updateCell( cursorY, 0, FALSE );
+ d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE );
+}
+
+/*
+ Moves the cursor one word to the left. If \a mark is TRUE, the text
+ is marked.
+ \sa cursorWordForward()
+*/
+void TQtMultiLineEdit::cursorWordBackward( bool mark )
+{
+ int x = cursorX;
+ int y = cursorY;
+
+ while ( x > 0 && textLine(y).at(x-1).isSpace() )
+ --x;
+
+ if ( x == 0 ) {
+ if ( y > 0 ) {
+ --y;
+ x = lineLength( y );
+ while ( x > 0 && textLine(y).at(x-1).isSpace() )
+ --x;
+ }
+ }
+ else {
+ while ( x > 0 && !textLine(y).at(x-1).isSpace() )
+ --x;
+ }
+ cursorOn = TRUE;
+ int oldY = cursorY;
+ setCursorPosition( y, x, mark );
+ if ( oldY != cursorY )
+ updateCell( oldY, 0, FALSE );
+ updateCell( cursorY, 0, FALSE );
+ d->blinkTimer->start( TQApplication::cursorFlashTime() / 2, FALSE );
+}
+
+#define DO_BREAK {doBreak = TRUE; if ( lastSpace > a ) { \
+i = lastSpace; \
+linew = lastw; \
+} \
+else \
+i = TQMAX( a, i-1 );}
+
+void TQtMultiLineEdit::wrapLine( int line, int removed )
+{
+ TQtMultiLineEditRow* r = contents->at( line );
+ int yPos;
+ (void) rowYPos( line, &yPos );
+ TQFontMetrics fm( font() );
+ int i = 0;
+ TQString s = r->s;
+ int a = 0;
+ int l = line;
+ int w = 0;
+ int nlines = 0;
+ int lastSpace = -1;
+ bool doBreak = FALSE;
+ int linew = 0;
+ int lastw = 0;
+ int tabDist = -1; // lazy eval
+ while ( i < int(s.length()) ) {
+ doBreak = FALSE;
+ if ( s[i] == '\t' && d->align == TQt::AlignLeft ) {
+ if ( tabDist<0 )
+ tabDist = tabStopDist(fm);
+ linew = ( linew/tabDist + 1 ) * tabDist;
+ } else if ( s[i] != '\n' ) {
+ char c = s[i].latin1();
+ if ( c > 0 ) {
+ if ( !d->chartable[c] )
+ d->chartable[c] = fm.width( s[i] );
+ linew += d->chartable[c];
+ } else {
+ linew += fm.width( s[i] );
+ }
+ }
+ if ( WORD_WRAP &&
+ lastSpace >= a && s[i] != '\n' ) {
+ if ( DYNAMIC_WRAP ) {
+ if (linew >= contentsRect().width() - 2*d->lr_marg - d->marg_extra) {
+ DO_BREAK
+ }
+ } else if ( FIXED_COLUMN_WRAP ) {
+ if ( d->wrapcol >= 0 && i-a >= d->wrapcol ) {
+ DO_BREAK
+ }
+ } else if ( FIXED_WIDTH_WRAP ) {
+ if ( d->wrapcol >= 0 && linew > d->wrapcol - d->marg_extra ) {
+ DO_BREAK
+ }
+ }
+ }
+ if ( s[i] == '\n' || doBreak ) {
+ r->s = s.mid( a, i - a + (doBreak?1:0) );
+ r->w = linew - fm.leftBearing(r->s[0]) + 2 * d->lr_marg + d->marg_extra;
+ if ( r->w > w )
+ w = r->w;
+ if ( cursorY > l )
+ ++cursorY;
+ else if ( cursorY == line && cursorX >=a && cursorX <= i + (doBreak?1:0)) {
+ cursorY = l;
+ cursorX -= a;
+ }
+ if ( markAnchorY > l )
+ ++markAnchorY;
+ else if ( markAnchorY == line && markAnchorX >=a && markAnchorX <= i + (doBreak?1:0)) {
+ markAnchorY = l;
+ markAnchorX -= a;
+ }
+ a = i + 1;
+ lastSpace = a;
+ linew = 0;
+ bool oldnewline = r->newline;
+ r->newline = !doBreak;
+ r = new TQtMultiLineEditRow( TQString::null, 0, oldnewline );
+ ++nlines;
+ contents->insert( l + 1, r );
+ ++l;
+ }
+ if ( s[i].isSpace() || BREAK_WITHIN_WORDS ) {
+ lastSpace = i;
+ lastw = linew;
+ }
+ if ( lastSpace <= a )
+ lastw = linew;
+
+ ++i;
+ }
+ if ( a < int(s.length()) ){
+ r->s = s.mid( a, i - a );
+ r->w = linew - fm.leftBearing( r->s[0] ) + 2 * d->lr_marg + d->marg_extra;
+ }
+ if ( cursorY == line && cursorX >= a ) {
+ cursorY = l;
+ cursorX -= a;
+ }
+ if ( markAnchorY == line && markAnchorX >= a ) {
+ markAnchorY = l;
+ markAnchorX -= a;
+ }
+ if ( r->w > w )
+ w = r->w;
+
+ setWidth( TQMAX( maxLineWidth(), w ) );
+ bool oldAuto = autoUpdate();
+ setAutoUpdate( FALSE );
+ (void)setNumRowsAndTruncate();
+ setAutoUpdate( oldAuto );
+
+ yPos += (nlines+1) * cellHeight();
+ int sh = (nlines-removed) * cellHeight();
+ if ( autoUpdate() ) {
+ if ( sh && yPos >= contentsRect().top() && yPos < contentsRect().bottom() ) {
+ int h = contentsRect().bottom() - yPos + 1;
+ if ( d->maxlines >= 0 ) {
+ int maxy;
+ if ( rowYPos( d->maxlines-1, &maxy ) ) {
+ maxy += cellHeight();
+ if ( maxy < contentsRect().bottom() && maxy > yPos )
+ h = maxy - yPos + 1;
+ }
+ }
+ TQWidget::scroll( 0, sh, TQRect( contentsRect().left(), yPos,
+ contentsRect().width(),
+ h ) );
+ }
+ for (int ul = 0; ul <= nlines; ++ul )
+ updateCell( line + ul, 0, FALSE );
+ }
+}
+
+void TQtMultiLineEdit::rebreakParagraph( int line, int removed )
+{
+ TQtMultiLineEditRow* r = contents->at( line );
+ if ( WORD_WRAP ) {
+ TQtMultiLineEditRow* other = 0;
+ while (line < int(contents->count())-1 && !r->newline ) {
+ other = contents->at( line + 1 );
+ if ( cursorY > line ) {
+ --cursorY;
+ if ( cursorY == line ) {
+ cursorX += r->s.length();
+ }
+ }
+ if ( markAnchorY > line ) {
+ --markAnchorY;
+ if ( markAnchorY == line ) {
+ markAnchorX += r->s.length();
+ }
+ }
+ r->s.append( other->s );
+ r->newline = other->newline;
+ contents->remove( line + 1 );
+ ++removed;
+ }
+ }
+ wrapLine( line, removed );
+}
+
+void TQtMultiLineEdit::rebreakAll()
+{
+ if ( !WORD_WRAP )
+ return;
+ d->maxLineWidth = 0;
+ for (int i = 0; i < int(contents->count()); ++i ) {
+ if ( contents->at( i )->newline &&
+ contents->at( i )->w < contentsRect().width() - 2*d->lr_marg - d->marg_extra ) {
+ setWidth( TQMAX( d->maxLineWidth, contents->at( i )->w ) );
+ continue;
+ }
+ rebreakParagraph( i );
+ while ( i < int(contents->count() )
+ && !contents->at( i )->newline )
+ ++i;
+ }
+}
+
+
+/* \enum TQtMultiLineEdit::WordWrap
+
+ This enum describes the multiline edit's word wrap mode.
+
+ The following values are valid:
+ \list
+ \i NoWrap - no word wrap at all.
+ \i WidgetWidth - word wrap depending on the current
+ width of the editor widget
+ \i FixedPixelWidth - wrap according to a fix amount
+ of pixels ( see wrapColumnOrWidth() )
+ \i FixedColumnWidth - wrap according to a fix character
+ column. This is useful whenever you need formatted text that
+ can also be displayed gracefully on tqdevices with monospaced
+ fonts, for example a standard VT100 terminal. In that case
+ wrapColumnOrWidth() should typically be set to 80.
+ \endlist
+
+ \sa setWordWrap()
+*/
+
+/*
+ Sets the word wrap mode to \a mode.
+
+ */
+void TQtMultiLineEdit::setWordWrap( WordWrap mode )
+{
+ if ( mode == d->wordwrap )
+ return;
+ d->wordwrap = mode;
+
+ if ( BREAK_WITHIN_WORDS ) {
+ d->arrow = TQPixmap( (const char **)arrow_xpm );
+ d->marg_extra = 8;
+ if ( DYNAMIC_WRAP )
+ clearTableFlags( Tbl_autoHScrollBar );
+ else
+ setTableFlags( Tbl_autoHScrollBar );
+ } else {
+ d->marg_extra = 0;
+ setTableFlags( Tbl_autoHScrollBar );
+ }
+ if ( !text().isEmpty() )
+ setText( text() );
+}
+
+/*
+ Returns the current word wrap mode.
+
+ \sa setWordWrap()
+ */
+TQtMultiLineEdit::WordWrap TQtMultiLineEdit::wordWrap() const
+{
+ return d->wordwrap;
+}
+
+/*
+ Sets the wrap column or wrap width to \a value, depending on the
+ word wrap mode.
+
+ \sa setWordWrap()
+ */
+void TQtMultiLineEdit::setWrapColumnOrWidth( int value )
+{
+ if ( value == d->wrapcol )
+ return;
+ d->wrapcol = value;
+ if ( wordWrap() != NoWrap )
+ setText( text() );
+}
+
+/*
+ */
+int TQtMultiLineEdit::wrapColumnOrWidth() const
+{
+ return d->wrapcol;
+}
+
+
+/* \enum TQtMultiLineEdit::WrapPolicy
+
+ Defines where text can be wrapped in word wrap mode.
+
+ The following values are valid:
+ \list
+ \i AtWhiteSpace - break only after whitespace
+ \i Anywhere - break anywhere
+ \endlist
+
+ \sa setWrapPolicy()
+*/
+
+/*
+ Sets the wrap \a policy, i.e. where text can be wrapped in word wrap
+ mode.
+
+ \sa setWordWrap(), wrapPolicy()
+ */
+void TQtMultiLineEdit::setWrapPolicy( WrapPolicy policy )
+{
+ if ( d->wrappolicy == policy )
+ return;
+ d->wrappolicy = policy;
+ WordWrap m = d->wordwrap;
+ if ( m != NoWrap ) { // trigger update
+ d->wordwrap = NoWrap;
+ setWordWrap( m );
+ }
+}
+
+/*
+
+ Returns the current word wrap policy.
+
+ \sa setWrapPolicy()
+ */
+TQtMultiLineEdit::WrapPolicy TQtMultiLineEdit::wrapPolicy() const
+{
+ return d->wrappolicy;
+}
+
+/*
+ Returns wether \a row is the last row in a paragraph.
+
+ This function is only interesting in word wrap mode, otherwise its
+ return value is always TRUE.
+
+ \sa setWordWrap()
+ */
+bool TQtMultiLineEdit::isEndOfParagraph( int row ) const
+{
+ return contents->at( row )->newline;
+}
+
+int TQtMultiLineEdit::positionToOffsetInternal( int row, int col ) const
+{
+ row = TQMAX( TQMIN( row, numLines() - 1), 0 ); // Sanity check
+ col = TQMAX( TQMIN( col, lineLength( row )), 0 ); // Sanity check
+ if ( row == 0 )
+ return TQMIN( col, lineLength( 0 ));
+ else {
+ int lastI;
+ lastI = lineLength( row );
+ int i, tmp = 0;
+
+ for( i = 0; i < row ; i++ ) {
+ tmp += lineLength( i );
+ if ( contents->at( i )->newline )
+ ++tmp;
+ }
+
+ tmp += TQMIN( lastI, col );
+
+ return tmp;
+ }
+
+}
+
+// if position is <0 = returns row 0, col 0, if position >= amount of text
+// returns pointer to end of text.
+void TQtMultiLineEdit::offsetToPositionInternal( int position,
+ int *row, int *col ) const
+{
+ if (position <= 0) {
+ *row = 0;
+ *col = 0;
+ return;
+ }
+ else {
+ int charsLeft = position;
+ int i;
+
+ for( i = 0; contents->at( i ); ++i ) {
+ if (lineLength( i ) < charsLeft)
+ charsLeft -= lineLength( i );
+ else {
+ *row = i;
+ *col = charsLeft;
+ return;
+ }
+ if ( contents->at( i )->newline )
+ --charsLeft;
+ }
+
+ if (contents->at( i - 1) && !contents->at( i - 1 )->newline) {
+ *row = i - 1;
+ *col = lineLength( i - 1 );
+ }
+ else {
+ *row = i;
+ *col = 0;
+ }
+ return;
+ }
+}
+
+
+/*
+ Processes an undo/redo command \a cmd, depending on \a undo.
+ */
+void TQtMultiLineEdit::processCmd( TQtMultiLineEditCommand* cmd, bool undo)
+{
+ TQDelTextCmd* delcmd = (TQDelTextCmd*) cmd;
+ bool ins = TRUE;
+ if (cmd->type() == TQtMultiLineEditCommand::Delete )
+ ins = undo;
+ else if (cmd->type() == TQtMultiLineEditCommand::Insert )
+ ins = !undo;
+ else
+ return;
+
+ if ( ins ) {
+ int row, col;
+ offsetToPositionInternal( delcmd->mOffset, &row, &col );
+ setCursorPosition( row, col, FALSE );
+ insertAt( delcmd->mStr, row, col, FALSE );
+ offsetToPositionInternal( delcmd->mOffset+delcmd->mStr.length(), &row, &col );
+ setCursorPosition( row, col, FALSE );
+ } else { // del
+ int row, col, rowEnd, colEnd;
+ offsetToPositionInternal( delcmd->mOffset, &row, &col );
+ offsetToPositionInternal( delcmd->mOffset + delcmd->mStr.length(), &rowEnd, &colEnd );
+ markAnchorY = row;
+ markAnchorX = col;
+ setCursorPosition( rowEnd, colEnd, FALSE );
+ markDragY = rowEnd;
+ markDragX = colEnd;
+ turnMark( TRUE );
+ del();
+ }
+}
+
+/*
+ Undoes the last text operation.
+ */
+void TQtMultiLineEdit::undo()
+{
+ if ( d->undoList.isEmpty() || isReadOnly() )
+ return;
+ textDirty = FALSE;
+ int macroLevel = 0;
+ bool before = d->undo;
+ d->undo = FALSE;
+ do {
+ TQtMultiLineEditCommand *command = d->undoList.take();
+ if ( !command )
+ break;
+ processCmd( command, TRUE );
+ macroLevel += command->terminator();
+ if ( d->undoList.isEmpty() )
+ emit undoAvailable( FALSE );
+ addRedoCmd( command );
+ } while (macroLevel != 0);
+ d->undo = before;
+ if ( textDirty )
+ emit textChanged();
+ textDirty = FALSE;
+}
+
+/*
+ Redoes the last text operation.
+ */
+void TQtMultiLineEdit::redo()
+{
+ if ( d->redoList.isEmpty() || isReadOnly() )
+ return;
+ textDirty = FALSE;
+ int macroLevel = 0;
+ bool before = d->undo;
+ d->undo = FALSE;
+ do {
+ TQtMultiLineEditCommand *command = d->redoList.take();
+ if ( !command )
+ break;
+ processCmd( command, FALSE );
+ macroLevel += command->terminator();
+ if ( d->redoList.isEmpty() )
+ emit redoAvailable( FALSE );
+ if ( d->undoList.isEmpty() )
+ emit undoAvailable(TRUE);
+ d->undoList.append( command );
+ } while (macroLevel != 0);
+ d->undo = before;
+ if ( textDirty )
+ emit textChanged();
+ textDirty = FALSE;
+}
+
+/*
+ Inserts \a s at line number \a line, after character number \a col
+ in the line.
+ If \a s tqcontains newline characters, new lines are inserted.
+ If \a mark is TRUE the inserted text is selected.
+
+ The cursor position is adjusted. If the insertion position is equal to
+ the cursor position, the cursor is placed after the end of the new text.
+
+ */
+
+void TQtMultiLineEdit::insertAt( const TQString &s, int line, int col, bool mark )
+{
+ if ( d->undo ) {
+ d->undo = FALSE;
+ TQString itxt = s;
+ int offset = positionToOffsetInternal( line, col );
+ if ( d->maxlen >= 0 && length() + int(s.length()) > d->maxlen )
+ itxt.truncate( d->maxlen - length() );
+ addUndoCmd( new TQInsTextCmd( offset, itxt ) );
+ insertAtAux( s, line, col, mark ); // may perform del op
+ d->undo = TRUE;
+ }
+ else
+ insertAtAux( s, line, col, mark ); // may perform del op
+}
+
+void TQtMultiLineEdit::deleteNextChar( int offset, int row, int col )
+{
+ int row2, col2;
+ setCursorPosition( row, col, FALSE );
+ offsetToPositionInternal( offset + 1, &row2, &col2 );
+ setCursorPosition( row2, col2, TRUE );
+
+ TQString str = markedText();
+ addUndoCmd( new TQDelTextCmd( offset, str ) );
+
+ setCursorPosition( row, col, FALSE );
+}
+
+/*
+ Deletes text from the current cursor position to the end of the line.
+*/
+
+void TQtMultiLineEdit::killLine()
+{
+ if ( d->undo ) {
+ d->undo = FALSE;
+ int curY, curX;
+ cursorPosition( &curY, &curX );
+ int offset = positionToOffsetInternal( curY, curX );
+ TQtMultiLineEditRow* r = contents->at( curY );
+ deselect();
+
+ addUndoCmd( new TQBeginCommand );
+ if (curX == (int)r->s.length()) {
+ if ( ! atEnd() && r->newline )
+ deleteNextChar( offset, curY, curX );
+ }
+ else {
+ TQString str = r->s.mid( curX, r->s.length() );
+ addUndoCmd( new TQDelTextCmd( offset, str ) );
+ }
+
+ addUndoCmd( new TQEndCommand );
+ killLineAux();
+ d->undo = TRUE;
+ }
+ else
+ killLineAux();
+}
+
+/*
+ Deletes the character on the right side of the text cursor. If a
+ text has been marked by the user (e.g. by clicking and dragging) the
+ cursor is put at the beginning of the marked text and the marked
+ text is removed. \sa backspace()
+*/
+
+void TQtMultiLineEdit::del()
+{
+ if (d->undo ) {
+ d->undo = FALSE;
+ bool oldAuto = autoUpdate();
+ setAutoUpdate( FALSE );
+ int markBeginX, markBeginY;
+ int markEndX, markEndY;
+
+ if ( getMarkedRegion( &markBeginY, &markBeginX, &markEndY, &markEndX ) ) {
+ addUndoCmd( new TQBeginCommand );
+ int offset = positionToOffsetInternal( markBeginY, markBeginX );
+ TQString str = markedText();
+ d->undoList.append( new TQDelTextCmd( offset, str ) );
+ addUndoCmd( new TQEndCommand );
+ }
+ else if ( ! atEnd() ) {
+ int crsorY, crsorX;
+ cursorPosition( &crsorY, &crsorX );
+ int offset = positionToOffsetInternal( crsorY, crsorX );
+ TQtMultiLineEditRow* r = contents->at( crsorY );
+ if (r) {
+ if (crsorX != (int)r->s.length())
+ deleteNextChar( offset, crsorY, crsorX );
+ else if (r->newline)
+ deleteNextChar( offset, crsorY, crsorX );
+ // else noop
+ }
+ }
+ setAutoUpdate( oldAuto );
+ delAux();
+ d->undo = TRUE;
+ }
+ else
+ delAux();
+}
+
+/*
+ Sets undo enabled to \a enable.
+
+ \sa isUndoEnabled()
+*/
+void TQtMultiLineEdit::setUndoEnabled( bool enable )
+{
+ if ( d->undo == enable )
+ return;
+ d->undo = enable;
+ if ( !enable ) {
+ CLEAR_UNDO
+ }
+}
+
+
+/*
+ Returns whether the multilineedit is currently undo enabled or not.
+
+ \sa setUndoEnabled()
+ */
+bool TQtMultiLineEdit::isUndoEnabled() const
+{
+ return d->undo;
+}
+
+
+/*
+ Sets the maximum number of operations that can be stored on the undo
+ stack to \a depth.
+
+ \sa undoDepth()
+ */
+void TQtMultiLineEdit::setUndoDepth( int depth )
+{
+ d->undodepth = depth;
+}
+
+
+/*
+ */
+int TQtMultiLineEdit::undoDepth() const
+{
+ return d->undodepth;
+}
+
+void TQtMultiLineEdit::blinkTimerTimeout()
+{
+ cursorOn = !cursorOn;
+ updateCell( cursorY, 0, FALSE );
+}
+
+void TQtMultiLineEdit::scrollTimerTimeout()
+{
+ TQPoint p = mapFromGlobal( TQCursor::pos() );
+ if ( d->scrollAccel-- <= 0 && d->scrollTime ) {
+ d->scrollAccel = initialScrollAccel;
+ d->scrollTime--;
+ d->scrollTimer->stop();
+ d->scrollTimer->start( d->scrollTime );
+ }
+ int l = TQMAX(1,(initialScrollTime-d->scrollTime)/5);
+
+ // auto scrolling is dual-use - for highlighting and DND
+ int margin = d->dnd_primed ? scroll_margin : 0;
+ bool mark = !d->dnd_primed;
+ bool clear_mark = d->dnd_primed ? FALSE : !mark;
+
+ for (int i=0; i<l; i++) {
+ if ( p.y() < margin ) {
+ cursorUp( mark, clear_mark );
+ } else if ( p.y() > height()-margin ) {
+ cursorDown( mark, clear_mark );
+ } else if ( p.x() < margin ) {
+ cursorLeft( mark, clear_mark, FALSE );
+ } else if ( p.x() > width()-margin ) {
+ cursorRight( mark, clear_mark, FALSE );
+ } else {
+ stopAutoScroll();
+ break;
+ }
+ }
+}
+
+void TQtMultiLineEdit::dndTimeout()
+{
+#ifndef TQT_NO_DRAGANDDROP
+ doDrag();
+#endif
+}
+
+int TQtMultiLineEdit::setNumRowsAndTruncate()
+{
+ int n = contents->count();
+ int r = 0;
+ while ( d->maxlines >= 0 && n > d->maxlines ) {
+ // truncate
+ contents->at(n-2)->newline = TRUE;
+ contents->removeLast();
+ if ( markAnchorY == n-1 )
+ markAnchorY--;
+ if ( markDragY == n-1 )
+ markDragY--;
+ if ( cursorY == n-1 ) {
+ cursorY--;
+ cursorX = contents->at(cursorY)->s.length();
+ }
+ n--;
+ r++;
+ }
+ setNumRows( n );
+ return r;
+}
+
+/* \reimp
+*/
+bool TQtMultiLineEdit::event( TQEvent * e )
+{
+ if ( e->type() == TQEvent::AccelOverride && !isReadOnly() ) {
+ TQKeyEvent* ke = (TQKeyEvent*) e;
+ if ( ke->state() & ControlButton ) {
+ switch ( ke->key() ) {
+ case Key_A:
+ case Key_E:
+#if defined (_WS_WIN_)
+ case Key_Insert:
+#endif
+ case Key_X:
+ case Key_V:
+ case Key_C:
+ case Key_Left:
+ case Key_Right:
+ case Key_Up:
+ case Key_Down:
+ case Key_Home:
+ case Key_End:
+ ke->accept();
+ default:
+ break;
+ }
+ } else {
+ switch ( ke->key() ) {
+ case Key_Delete:
+ case Key_Home:
+ case Key_End:
+ case Key_Backspace:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ }
+ return TQWidget::event( e );
+}
+
+/* \reimp
+*/
+
+bool TQtMultiLineEdit::focusNextPrevChild( bool )
+{
+ return FALSE;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/attic/qtmultilineedit.h b/tqtinterface/qt4/src/attic/qtmultilineedit.h
new file mode 100644
index 0000000..2e539ee
--- /dev/null
+++ b/tqtinterface/qt4/src/attic/qtmultilineedit.h
@@ -0,0 +1,363 @@
+/**********************************************************************
+**
+** Definition of TQtMultiLineEdit widget class
+**
+** Created : 961005
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file tqcontains a class moved out of the TQt GUI Toolkit API. It
+** may be used, distributed and modified without limitation.
+**
+**********************************************************************/
+
+#ifndef TQTMULTILINEEDIT_H
+#define TQTMULTILINEEDIT_H
+
+#ifndef TQT_H
+#include "tqttableview.h"
+#include "tqstring.h"
+#include "tqptrlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TQTMULTILINEEDIT
+
+struct TQtMultiLineData;
+class TQtMultiLineEditCommand;
+class TQValidator;
+
+class TQtMultiLineEdit : public TQtTableView
+{
+ TQ_OBJECT
+ TQ_ENUMS( EchoMode WordWrap WrapPolicy )
+ Q_PROPERTY( int numLines READ numLines )
+ Q_PROPERTY( bool atBeginning READ atBeginning )
+ Q_PROPERTY( bool atEnd READ atEnd )
+ Q_PROPERTY( int maxLineWidth READ maxLineWidth )
+ Q_PROPERTY( Alignment tqalignment READ tqalignment WRITE tqsetAlignment )
+ Q_PROPERTY( bool edited READ edited WRITE setEdited DESIGNABLE false )
+ Q_PROPERTY( EchoMode echoMode READ echoMode WRITE setEchoMode )
+ Q_PROPERTY( int maxLength READ maxLength WRITE setMaxLength )
+ Q_PROPERTY( int maxLines READ maxLines WRITE setMaxLines )
+ Q_PROPERTY( int hMargin READ hMargin WRITE setHMargin )
+ Q_PROPERTY( WordWrap wordWrap READ wordWrap WRITE setWordWrap )
+ Q_PROPERTY( int wrapColumnOrWidth READ wrapColumnOrWidth WRITE setWrapColumnOrWidth )
+ Q_PROPERTY( WrapPolicy wrapPolicy READ wrapPolicy WRITE setWrapPolicy )
+ Q_PROPERTY( bool autoUpdate READ autoUpdate WRITE setAutoUpdate DESIGNABLE false )
+ Q_PROPERTY( bool undoEnabled READ isUndoEnabled WRITE setUndoEnabled )
+ Q_PROPERTY( int undoDepth READ undoDepth WRITE setUndoDepth )
+ Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly )
+ Q_PROPERTY( bool overWriteMode READ isOverwriteMode WRITE setOverwriteMode )
+ Q_PROPERTY( TQString text READ text WRITE setText )
+ Q_PROPERTY( int length READ length )
+
+public:
+ TQtMultiLineEdit( TQWidget *tqparent=0, const char *name=0 );
+ ~TQtMultiLineEdit();
+
+ TQString textLine( int line ) const;
+ int numLines() const;
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+ TQSizePolicy sizePolicy() const;
+
+ virtual void setFont( const TQFont &font );
+
+ virtual void insertLine( const TQString &s, int line = -1 );
+ virtual void insertAt( const TQString &s, int line, int col, bool mark = FALSE );
+ virtual void removeLine( int line );
+
+ void cursorPosition( int *line, int *col ) const;
+ virtual void setCursorPosition( int line, int col, bool mark = FALSE );
+ void getCursorPosition( int *line, int *col ) const;
+ bool atBeginning() const;
+ bool atEnd() const;
+
+ virtual void setFixedVisibleLines( int lines );
+
+ int maxLineWidth() const;
+
+ void tqsetAlignment( int flags );
+ int tqalignment() const;
+
+ virtual void setValidator( const TQValidator * );
+ const TQValidator * validator() const;
+
+ void setEdited( bool );
+ bool edited() const;
+
+ void cursorWordForward( bool mark );
+ void cursorWordBackward( bool mark );
+
+ enum EchoMode { Normal, NoEcho, Password };
+ virtual void setEchoMode( EchoMode );
+ EchoMode echoMode() const;
+
+ void setMaxLength(int);
+ int maxLength() const;
+ virtual void setMaxLineLength(int);
+ int maxLineLength() const;
+ virtual void setMaxLines(int);
+ int maxLines() const;
+ virtual void setHMargin(int);
+ int hMargin() const;
+
+ virtual void setSelection( int row_from, int col_from, int row_to, int col_t );
+
+ enum WordWrap {
+ NoWrap,
+ WidgetWidth,
+ FixedPixelWidth,
+ FixedColumnWidth
+ };
+ void setWordWrap( WordWrap mode );
+ WordWrap wordWrap() const;
+ void setWrapColumnOrWidth( int );
+ int wrapColumnOrWidth() const;
+
+ enum WrapPolicy {
+ AtWhiteSpace,
+ Anywhere
+ };
+ void setWrapPolicy( WrapPolicy policy );
+ WrapPolicy wrapPolicy() const;
+
+ bool autoUpdate() const;
+ virtual void setAutoUpdate( bool );
+
+ void setUndoEnabled( bool );
+ bool isUndoEnabled() const;
+ void setUndoDepth( int );
+ int undoDepth() const;
+
+ bool isReadOnly() const;
+ bool isOverwriteMode() const;
+
+ TQString text() const;
+
+ int length() const;
+
+ static void setDefaultTabStop( int ex );
+ static int defaultTabStop();
+public Q_SLOTS:
+ virtual void setText( const TQString &);
+ virtual void setReadOnly( bool );
+ virtual void setOverwriteMode( bool );
+
+ void clear();
+ void append( const TQString &);
+ void deselect();
+ void selectAll();
+#ifndef TQT_NO_CLIPBOARD
+ void paste();
+ void pasteSubType(const TQCString& subtype);
+ void copyText() const;
+ void copy() const;
+ void cut();
+#endif
+ void insert( const TQString& );
+ void undo();
+ void redo();
+
+Q_SIGNALS:
+ void textChanged();
+ void returnPressed();
+ void undoAvailable( bool );
+ void redoAvailable( bool );
+ void copyAvailable( bool );
+
+protected:
+ void paintCell( TQPainter *, int row, int col );
+ bool event( TQEvent * );
+
+ void mousePressEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseDoubleClickEvent( TQMouseEvent * );
+ void wheelEvent( TQWheelEvent * );
+ void keyPressEvent( TQKeyEvent * );
+ void focusInEvent( TQFocusEvent * );
+ void focusOutEvent( TQFocusEvent * );
+ void timerEvent( TQTimerEvent * );
+ void leaveEvent( TQEvent * );
+ void resizeEvent( TQResizeEvent * );
+
+ bool focusNextPrevChild( bool );
+
+#ifndef TQT_NO_DRAGANDDROP
+ void dragMoveEvent( TQDragMoveEvent* );
+ void dragEnterEvent( TQDragEnterEvent * );
+ void dropEvent( TQDropEvent* );
+ void dragLeaveEvent( TQDragLeaveEvent* );
+#endif
+
+ bool hasMarkedText() const;
+ TQString markedText() const;
+ int textWidth( int );
+ int textWidth( const TQString &);
+
+ TQPoint cursorPoint() const;
+
+protected:
+ virtual void insert( const TQString&, bool mark );
+ virtual void newLine();
+ virtual void killLine();
+ virtual void pageUp( bool mark=FALSE );
+ virtual void pageDown( bool mark=FALSE );
+ virtual void cursorLeft( bool mark=FALSE, bool wrap = TRUE );
+ virtual void cursorRight( bool mark=FALSE, bool wrap = TRUE );
+ virtual void cursorUp( bool mark=FALSE );
+ virtual void cursorDown( bool mark=FALSE );
+ virtual void backspace();
+ virtual void del();
+ virtual void home( bool mark=FALSE );
+ virtual void end( bool mark=FALSE );
+
+ bool getMarkedRegion( int *line1, int *col1,
+ int *line2, int *col2 ) const;
+ int lineLength( int row ) const;
+ TQString *getString( int row ) const;
+ bool isEndOfParagraph( int row ) const;
+ TQString stringShown( int row ) const;
+
+protected:
+ bool cursorOn;
+ void insertChar( TQChar );
+
+private Q_SLOTS:
+ void clipboardChanged();
+ void blinkTimerTimeout();
+ void scrollTimerTimeout();
+ void dndTimeout();
+
+private:
+#ifndef TQT_NO_MIME
+ TQCString pickSpecial(TQMimeSource* ms, bool always_ask, const TQPoint&);
+#endif
+#ifndef TQT_NO_MIMECLIPBOARD
+ void pasteSpecial(const TQPoint&);
+#endif
+ struct TQtMultiLineEditRow {
+ TQtMultiLineEditRow( TQString string, int width, bool nl = TRUE )
+ :s(string), w(width), newline( nl )
+ {
+ };
+ TQString s;
+ int w;
+ bool newline;
+ };
+ TQPtrList<TQtMultiLineEditRow> *contents;
+ TQtMultiLineData *d;
+
+ bool readOnly;
+ bool dummy;
+ bool markIsOn;
+ bool dragScrolling ;
+ bool dragMarking;
+ bool textDirty;
+ bool wordMark;
+ bool overWrite;
+
+ int cursorX;
+ int cursorY;
+ int markAnchorX;
+ int markAnchorY;
+ int markDragX;
+ int markDragY;
+ int curXPos; // cell coord of cursor
+ int blinkTimer; // #### not used anymore - remove in 3.0
+ int scrollTimer; // #### not used anymore - remove in 3.0
+
+ int mapFromView( int xPos, int row );
+ int mapToView( int xIndex, int row );
+
+ void pixelPosToCursorPos(TQPoint p, int* x, int* y) const;
+ void setCursorPixelPosition(TQPoint p, bool clear_mark=TRUE);
+
+ void setWidth( int );
+ void updateCellWidth();
+ bool partiallyInvisible( int row );
+ void makeVisible();
+ void setBottomCell( int row );
+
+ void newMark( int posx, int posy, bool copy=TRUE );
+ void markWord( int posx, int posy );
+ void extendSelectionWord( int &newX, int&newY);
+ int charClass( TQChar );
+ void turnMark( bool on );
+ bool inMark( int posx, int posy ) const;
+ bool beforeMark( int posx, int posy ) const;
+ bool afterMark( int posx, int posy ) const;
+ int setNumRowsAndTruncate();
+
+#ifndef TQT_NO_DRAGANDDROP
+ void doDrag();
+#endif
+ void startAutoScroll();
+ void stopAutoScroll();
+
+ void cursorLeft( bool mark, bool clear_mark, bool wrap );
+ void cursorRight( bool mark, bool clear_mark, bool wrap );
+ void cursorUp( bool mark, bool clear_mark );
+ void cursorDown( bool mark, bool clear_mark );
+
+ void wrapLine( int line, int removed = 0);
+ void rebreakParagraph( int line, int removed = 0 );
+ void rebreakAll();
+ void insertAtAux( const TQString &s, int line, int col, bool mark = FALSE );
+ void killLineAux();
+ void delAux();
+ int positionToOffsetInternal( int row, int col ) const;
+ void offsetToPositionInternal( int position, int *row, int *col ) const;
+ void deleteNextChar( int offset, int row, int col );
+
+ void addUndoCmd( TQtMultiLineEditCommand* );
+ void addRedoCmd( TQtMultiLineEditCommand* );
+ void processCmd( TQtMultiLineEditCommand*, bool );
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQtMultiLineEdit( const TQtMultiLineEdit & );
+ TQtMultiLineEdit &operator=( const TQtMultiLineEdit & );
+#endif
+};
+
+inline bool TQtMultiLineEdit::isReadOnly() const { return readOnly; }
+
+inline bool TQtMultiLineEdit::isOverwriteMode() const { return overWrite; }
+
+inline void TQtMultiLineEdit::setOverwriteMode( bool on )
+{
+ overWrite = on;
+ }
+
+inline int TQtMultiLineEdit::lineLength( int row ) const
+{
+ return contents->at( row )->s.length();
+}
+
+inline bool TQtMultiLineEdit::atEnd() const
+{
+ return cursorY == (int)contents->count() - 1
+ && cursorX == lineLength( cursorY ) ;
+}
+
+inline bool TQtMultiLineEdit::atBeginning() const
+{
+ return cursorY == 0 && cursorX == 0;
+}
+
+inline TQString *TQtMultiLineEdit::getString( int row ) const
+{
+ return &(contents->at( row )->s);
+}
+
+inline int TQtMultiLineEdit::numLines() const
+{
+ return contents->count();
+}
+
+#endif // TQT_NO_TQTMULTILINEEDIT
+
+#endif // TQTMULTILINEDIT_H
diff --git a/tqtinterface/qt4/src/attic/qttableview.cpp b/tqtinterface/qt4/src/attic/qttableview.cpp
new file mode 100644
index 0000000..0872fa6
--- /dev/null
+++ b/tqtinterface/qt4/src/attic/qttableview.cpp
@@ -0,0 +1,2272 @@
+/**********************************************************************
+**
+** Implementation of TQtTableView class
+**
+** Created : 941115
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file tqcontains a class moved out of the TQt GUI Toolkit API. It
+** may be used, distributed and modified without limitation.
+**
+**********************************************************************/
+
+#include "tqttableview.h"
+#ifndef TQT_NO_TQTTABLEVIEW
+#include "tqscrollbar.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include <limits.h>
+
+enum ScrollBarDirtyFlags {
+ verGeometry = 0x01,
+ verSteps = 0x02,
+ verRange = 0x04,
+ verValue = 0x08,
+ horGeometry = 0x10,
+ horSteps = 0x20,
+ horRange = 0x40,
+ horValue = 0x80,
+ verMask = 0x0F,
+ horMask = 0xF0
+};
+
+
+#define HSBEXT horizontalScrollBar()->tqsizeHint().height()
+#define VSBEXT verticalScrollBar()->tqsizeHint().width()
+
+
+class TQCornerSquare : public TQWidget // internal class
+{
+public:
+ TQCornerSquare( TQWidget *, const char* = 0 );
+ void paintEvent( TQPaintEvent * );
+};
+
+TQCornerSquare::TQCornerSquare( TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name )
+{
+}
+
+void TQCornerSquare::paintEvent( TQPaintEvent * )
+{
+}
+
+
+// NOT REVISED
+/*
+ \class TQtTableView qttableview.h
+ \brief The TQtTableView class provides an abstract base for tables.
+
+ \obsolete
+
+ A table view consists of a number of abstract cells organized in rows
+ and columns, and a visible part called a view. The cells are identified
+ with a row index and a column index. The top-left cell is in row 0,
+ column 0.
+
+ The behavior of the widget can be finely tuned using
+ setTableFlags(); a typical subclass will consist of little more than a
+ call to setTableFlags(), some table content manipulation and an
+ implementation of paintCell(). Subclasses that need cells with
+ variable width or height must reimplement cellHeight() and/or
+ cellWidth(). Use updateTableSize() to tell TQtTableView when the
+ width or height has changed.
+
+ When you read this documentation, it is important to understand the
+ distinctions among the four pixel coordinate systems involved.
+
+ \list 1
+ \i The \e cell coordinates. (0,0) is the top-left corner of a cell.
+ Cell coordinates are used by functions such as paintCell().
+
+ \i The \e table coordinates. (0,0) is the top-left corner of the cell at
+ row 0 and column 0. These coordinates are absolute; that is, they are
+ independent of what part of the table is visible at the moment. They are
+ used by functions such as setXOffset() or maxYOffset().
+
+ \i The \e widget coordinates. (0,0) is the top-left corner of the widget,
+ \e including the frame. They are used by functions such as tqrepaint().
+
+ \i The \e view coordinates. (0,0) is the top-left corner of the view, \e
+ excluding the frame. This is the least-used coordinate system; it is used by
+ functions such as viewWidth(). \endlist
+
+ It is rather unfortunate that we have to use four different
+ coordinate systems, but there was no alternative to provide a flexible and
+ powerful base class.
+
+ Note: The row,column indices are always given in that order,
+ i.e., first the vertical (row), then the horizontal (column). This is
+ the opposite order of all pixel operations, which take first the
+ horizontal (x) and then the vertical (y).
+
+ <img src=qtablevw-m.png> <img src=qtablevw-w.png>
+
+ \warning the functions setNumRows(), setNumCols(), setCellHeight(),
+ setCellWidth(), setTableFlags() and clearTableFlags() may cause
+ virtual functions such as cellWidth() and cellHeight() to be called,
+ even if autoUpdate() is FALSE. This may cause errors if relevant
+ state variables are not initialized.
+
+ \warning Experience has shown that use of this widget tends to cause
+ more bugs than expected and our analysis indicates that the widget's
+ very flexibility is the problem. If TQScrollView or TQListBox can
+ easily be made to do the job you need, we recommend subclassing
+ those widgets rather than TQtTableView. In addition, TQScrollView makes
+ it easy to have child widgets inside tables, which TQtTableView
+ doesn't support at all.
+
+ \sa TQScrollView
+ \link guibooks.html#fowler GUI Design Handbook: Table\endlink
+*/
+
+
+/*
+ Constructs a table view. The \a tqparent, \a name and \f arguments
+ are passed to the TQFrame constructor.
+
+ The \link setTableFlags() table flags\endlink are all cleared (set to 0).
+ Set \c Tbl_autoVScrollBar or \c Tbl_autoHScrollBar to get automatic scroll
+ bars and \c Tbl_clipCellPainting to get safe clipping.
+
+ The \link setCellHeight() cell height\endlink and \link setCellWidth()
+ cell width\endlink are set to 0.
+
+ Frame line tqshapes (TQFrame::HLink and TQFrame::VLine) are disallowed;
+ see TQFrame::setFrameStyle().
+
+ Note that the \a f argument is \e not \link setTableFlags() table
+ flags \endlink but rather \link TQWidget::TQWidget() widget
+ flags. \endlink
+
+*/
+
+TQtTableView::TQtTableView( TQWidget *tqparent, const char *name, WFlags f )
+ : TQFrame( tqparent, name, f )
+{
+ nRows = nCols = 0; // zero rows/cols
+ xCellOffs = yCellOffs = 0; // zero offset
+ xCellDelta = yCellDelta = 0; // zero cell offset
+ xOffs = yOffs = 0; // zero total pixel offset
+ cellH = cellW = 0; // user defined cell size
+ tFlags = 0;
+ vScrollBar = hScrollBar = 0; // no scroll bars
+ cornerSquare = 0;
+ sbDirty = 0;
+ eraseInPaint = FALSE;
+ verSliding = FALSE;
+ verSnappingOff = FALSE;
+ horSliding = FALSE;
+ horSnappingOff = FALSE;
+ coveringCornerSquare = FALSE;
+ inSbUpdate = FALSE;
+}
+
+/*
+ Destroys the table view.
+*/
+
+TQtTableView::~TQtTableView()
+{
+ delete vScrollBar;
+ delete hScrollBar;
+ delete cornerSquare;
+}
+
+
+/*
+ \internal
+ Reimplements TQWidget::setBackgroundColor() for binary compatibility.
+ \sa setPalette()
+*/
+
+void TQtTableView::setBackgroundColor( const TQColor &c )
+{
+ TQWidget::setBackgroundColor( c );
+}
+
+/*\reimp
+*/
+
+void TQtTableView::setPalette( const TQPalette &p )
+{
+ TQWidget::setPalette( p );
+}
+
+/*\reimp
+*/
+
+void TQtTableView::show()
+{
+ showOrHideScrollBars();
+ TQWidget::show();
+}
+
+
+/*
+ \overload void TQtTableView::tqrepaint( bool erase )
+ Repaints the entire view.
+*/
+
+/*
+ Repaints the table view directly by calling paintEvent() directly
+ unless updates are disabled.
+
+ Erases the view area \a (x,y,w,h) if \a erase is TRUE. Parameters \a
+ (x,y) are in \e widget coordinates.
+
+ If \a w is negative, it is tqreplaced with <code>width() - x</code>.
+ If \a h is negative, it is tqreplaced with <code>height() - y</code>.
+
+ Doing a tqrepaint() usually is faster than doing an update(), but
+ calling update() many times in a row will generate a single paint
+ event.
+
+ At present, TQtTableView is the only widget that reimplements \link
+ TQWidget::tqrepaint() tqrepaint()\endlink. It does this because by
+ clearing and then repainting one cell at at time, it can make the
+ screen flicker less than it would otherwise. */
+
+void TQtTableView::tqrepaint( int x, int y, int w, int h, bool erase )
+{
+ if ( !isVisible() || testWState(WState_BlockUpdates) )
+ return;
+ if ( w < 0 )
+ w = width() - x;
+ if ( h < 0 )
+ h = height() - y;
+ TQRect r( x, y, w, h );
+ if ( r.isEmpty() )
+ return; // nothing to do
+ TQPaintEvent e( r );
+ if ( erase && backgroundMode() != NoBackground )
+ eraseInPaint = TRUE; // erase when painting
+ paintEvent( &e );
+ eraseInPaint = FALSE;
+}
+
+/*
+ \overload void TQtTableView::tqrepaint( const TQRect &r, bool erase )
+ Replaints rectangle \a r. If \a erase is TRUE draws the background
+ using the palette's background.
+*/
+
+
+/*
+ \fn int TQtTableView::numRows() const
+ Returns the number of rows in the table.
+ \sa numCols(), setNumRows()
+*/
+
+/*
+ Sets the number of rows of the table to \a rows (must be non-negative).
+ Does not change topCell().
+
+ The table repaints itself automatically if autoUpdate() is set.
+
+ \sa numCols(), setNumCols(), numRows()
+*/
+
+void TQtTableView::setNumRows( int rows )
+{
+ if ( rows < 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQtTableView::setNumRows: (%s) Negative argument %d.",
+ name( "unnamed" ), rows );
+#endif
+ return;
+ }
+ if ( nRows == rows )
+ return;
+
+ if ( autoUpdate() && isVisible() ) {
+ int oldLastVisible = lastRowVisible();
+ int oldTopCell = topCell();
+ nRows = rows;
+ if ( autoUpdate() && isVisible() &&
+ ( oldLastVisible != lastRowVisible() || oldTopCell != topCell() ) )
+ tqrepaint( oldTopCell != topCell() );
+ } else {
+ // Be more careful - if destructing, bad things might happen.
+ nRows = rows;
+ }
+ updateScrollBars( verRange );
+ updateFrameSize();
+}
+
+/*
+ \fn int TQtTableView::numCols() const
+ Returns the number of columns in the table.
+ \sa numRows(), setNumCols()
+*/
+
+/*
+ Sets the number of columns of the table to \a cols (must be non-negative).
+ Does not change leftCell().
+
+ The table repaints itself automatically if autoUpdate() is set.
+
+ \sa numCols(), numRows(), setNumRows()
+*/
+
+void TQtTableView::setNumCols( int cols )
+{
+ if ( cols < 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQtTableView::setNumCols: (%s) Negative argument %d.",
+ name( "unnamed" ), cols );
+#endif
+ return;
+ }
+ if ( nCols == cols )
+ return;
+ int oldCols = nCols;
+ nCols = cols;
+ if ( autoUpdate() && isVisible() ) {
+ int maxCol = lastColVisible();
+ if ( maxCol >= oldCols || maxCol >= nCols )
+ tqrepaint();
+ }
+ updateScrollBars( horRange );
+ updateFrameSize();
+}
+
+
+/*
+ \fn int TQtTableView::topCell() const
+ Returns the index of the first row in the table that is visible in
+ the view. The index of the first row is 0.
+ \sa leftCell(), setTopCell()
+*/
+
+/*
+ Scrolls the table so that \a row becomes the top row.
+ The index of the very first row is 0.
+ \sa setYOffset(), setTopLeftCell(), setLeftCell()
+*/
+
+void TQtTableView::setTopCell( int row )
+{
+ setTopLeftCell( row, -1 );
+ return;
+}
+
+/*
+ \fn int TQtTableView::leftCell() const
+ Returns the index of the first column in the table that is visible in
+ the view. The index of the very leftmost column is 0.
+ \sa topCell(), setLeftCell()
+*/
+
+/*
+ Scrolls the table so that \a col becomes the leftmost
+ column. The index of the leftmost column is 0.
+ \sa setXOffset(), setTopLeftCell(), setTopCell()
+*/
+
+void TQtTableView::setLeftCell( int col )
+{
+ setTopLeftCell( -1, col );
+ return;
+}
+
+/*
+ Scrolls the table so that the cell at row \a row and colum \a
+ col becomes the top-left cell in the view. The cell at the extreme
+ top left of the table is at position (0,0).
+ \sa setLeftCell(), setTopCell(), setOffset()
+*/
+
+void TQtTableView::setTopLeftCell( int row, int col )
+{
+ int newX = xOffs;
+ int newY = yOffs;
+
+ if ( col >= 0 ) {
+ if ( cellW ) {
+ newX = col*cellW;
+ if ( newX > maxXOffset() )
+ newX = maxXOffset();
+ } else {
+ newX = 0;
+ while ( col )
+ newX += cellWidth( --col ); // optimize using current! ###
+ }
+ }
+ if ( row >= 0 ) {
+ if ( cellH ) {
+ newY = row*cellH;
+ if ( newY > maxYOffset() )
+ newY = maxYOffset();
+ } else {
+ newY = 0;
+ while ( row )
+ newY += cellHeight( --row ); // optimize using current! ###
+ }
+ }
+ setOffset( newX, newY );
+}
+
+
+/*
+ \fn int TQtTableView::xOffset() const
+
+ Returns the x coordinate in \e table coordinates of the pixel that is
+ currently on the left edge of the view.
+
+ \sa setXOffset(), yOffset(), leftCell() */
+
+/*
+ Scrolls the table so that \a x becomes the leftmost pixel in the view.
+ The \a x parameter is in \e table coordinates.
+
+ The interaction with \link setTableFlags() Tbl_snapToHGrid
+ \endlink is tricky.
+
+ \sa xOffset(), setYOffset(), setOffset(), setLeftCell()
+*/
+
+void TQtTableView::setXOffset( int x )
+{
+ setOffset( x, yOffset() );
+}
+
+/*
+ \fn int TQtTableView::yOffset() const
+
+ Returns the y coordinate in \e table coordinates of the pixel that is
+ currently on the top edge of the view.
+
+ \sa setYOffset(), xOffset(), topCell()
+*/
+
+
+/*
+ Scrolls the table so that \a y becomes the top pixel in the view.
+ The \a y parameter is in \e table coordinates.
+
+ The interaction with \link setTableFlags() Tbl_snapToVGrid
+ \endlink is tricky.
+
+ \sa yOffset(), setXOffset(), setOffset(), setTopCell()
+*/
+
+void TQtTableView::setYOffset( int y )
+{
+ setOffset( xOffset(), y );
+}
+
+/*
+ Scrolls the table so that \a (x,y) becomes the top-left pixel
+ in the view. Parameters \a (x,y) are in \e table coordinates.
+
+ The interaction with \link setTableFlags() Tbl_snapTo*Grid \endlink
+ is tricky. If \a updateScrBars is TRUE, the scroll bars are
+ updated.
+
+ \sa xOffset(), yOffset(), setXOffset(), setYOffset(), setTopLeftCell()
+*/
+
+void TQtTableView::setOffset( int x, int y, bool updateScrBars )
+{
+ if ( (!testTableFlags(Tbl_snapToHGrid) || xCellDelta == 0) &&
+ (!testTableFlags(Tbl_snapToVGrid) || yCellDelta == 0) &&
+ (x == xOffs && y == yOffs) )
+ return;
+
+ if ( x < 0 )
+ x = 0;
+ if ( y < 0 )
+ y = 0;
+
+ if ( cellW ) {
+ if ( x > maxXOffset() )
+ x = maxXOffset();
+ xCellOffs = x / cellW;
+ if ( !testTableFlags(Tbl_snapToHGrid) ) {
+ xCellDelta = (short)(x % cellW);
+ } else {
+ x = xCellOffs*cellW;
+ xCellDelta = 0;
+ }
+ } else {
+ int xn=0, xcd=0, col = 0;
+ while ( col < nCols-1 && x >= xn+(xcd=cellWidth(col)) ) {
+ xn += xcd;
+ col++;
+ }
+ xCellOffs = col;
+ if ( testTableFlags(Tbl_snapToHGrid) ) {
+ xCellDelta = 0;
+ x = xn;
+ } else {
+ xCellDelta = (short)(x-xn);
+ }
+ }
+ if ( cellH ) {
+ if ( y > maxYOffset() )
+ y = maxYOffset();
+ yCellOffs = y / cellH;
+ if ( !testTableFlags(Tbl_snapToVGrid) ) {
+ yCellDelta = (short)(y % cellH);
+ } else {
+ y = yCellOffs*cellH;
+ yCellDelta = 0;
+ }
+ } else {
+ int yn=0, yrd=0, row=0;
+ while ( row < nRows-1 && y >= yn+(yrd=cellHeight(row)) ) {
+ yn += yrd;
+ row++;
+ }
+ yCellOffs = row;
+ if ( testTableFlags(Tbl_snapToVGrid) ) {
+ yCellDelta = 0;
+ y = yn;
+ } else {
+ yCellDelta = (short)(y-yn);
+ }
+ }
+ int dx = (x - xOffs);
+ int dy = (y - yOffs);
+ xOffs = x;
+ yOffs = y;
+ if ( autoUpdate() && isVisible() )
+ scroll( dx, dy );
+ if ( updateScrBars )
+ updateScrollBars( verValue | horValue );
+}
+
+
+/*
+ \overload int TQtTableView::cellWidth() const
+
+ Returns the column width in pixels. Returns 0 if the columns have
+ variable widths.
+
+ \sa setCellWidth(), cellHeight()
+*/
+
+/*
+ Returns the width of column \a col in pixels.
+
+ This function is virtual and must be reimplemented by subclasses that
+ have variable cell widths. Note that if the total table width
+ changes, updateTableSize() must be called.
+
+ \sa setCellWidth(), cellHeight(), totalWidth(), updateTableSize()
+*/
+
+int TQtTableView::cellWidth( int )
+{
+ return cellW;
+}
+
+
+/*
+ Sets the width in pixels of the table cells to \a cellWidth.
+
+ Setting it to 0 means that the column width is variable. When
+ set to 0 (this is the default) TQtTableView calls the virtual function
+ cellWidth() to get the width.
+
+ \sa cellWidth(), setCellHeight(), totalWidth(), numCols()
+*/
+
+void TQtTableView::setCellWidth( int cellWidth )
+{
+ if ( cellW == cellWidth )
+ return;
+#if defined(TQT_CHECK_RANGE)
+ if ( cellWidth < 0 || cellWidth > SHRT_MAX ) {
+ qWarning( "TQtTableView::setCellWidth: (%s) Argument out of range (%d)",
+ name( "unnamed" ), cellWidth );
+ return;
+ }
+#endif
+ cellW = (short)cellWidth;
+
+ updateScrollBars( horSteps | horRange );
+ if ( autoUpdate() && isVisible() )
+ tqrepaint();
+
+}
+
+/*
+ \overload int TQtTableView::cellHeight() const
+
+ Returns the row height, in pixels. Returns 0 if the rows have
+ variable heights.
+
+ \sa setCellHeight(), cellWidth()
+*/
+
+
+/*
+ Returns the height of row \a row in pixels.
+
+ This function is virtual and must be reimplemented by subclasses that
+ have variable cell heights. Note that if the total table height
+ changes, updateTableSize() must be called.
+
+ \sa setCellHeight(), cellWidth(), totalHeight()
+*/
+
+int TQtTableView::cellHeight( int )
+{
+ return cellH;
+}
+
+/*
+ Sets the height in pixels of the table cells to \a cellHeight.
+
+ Setting it to 0 means that the row height is variable. When set
+ to 0 (this is the default), TQtTableView calls the virtual function
+ cellHeight() to get the height.
+
+ \sa cellHeight(), setCellWidth(), totalHeight(), numRows()
+*/
+
+void TQtTableView::setCellHeight( int cellHeight )
+{
+ if ( cellH == cellHeight )
+ return;
+#if defined(TQT_CHECK_RANGE)
+ if ( cellHeight < 0 || cellHeight > SHRT_MAX ) {
+ qWarning( "TQtTableView::setCellHeight: (%s) Argument out of range (%d)",
+ name( "unnamed" ), cellHeight );
+ return;
+ }
+#endif
+ cellH = (short)cellHeight;
+ if ( autoUpdate() && isVisible() )
+ tqrepaint();
+ updateScrollBars( verSteps | verRange );
+}
+
+
+/*
+ Returns the total width of the table in pixels.
+
+ This function is virtual and should be reimplemented by subclasses that
+ have variable cell widths and a non-trivial cellWidth() function, or a
+ large number of columns in the table.
+
+ The default implementation may be slow for very wide tables.
+
+ \sa cellWidth(), totalHeight() */
+
+int TQtTableView::totalWidth()
+{
+ if ( cellW ) {
+ return cellW*nCols;
+ } else {
+ int tw = 0;
+ for( int i = 0 ; i < nCols ; i++ )
+ tw += cellWidth( i );
+ return tw;
+ }
+}
+
+/*
+ Returns the total height of the table in pixels.
+
+ This function is virtual and should be reimplemented by subclasses that
+ have variable cell heights and a non-trivial cellHeight() function, or a
+ large number of rows in the table.
+
+ The default implementation may be slow for very tall tables.
+
+ \sa cellHeight(), totalWidth()
+*/
+
+int TQtTableView::totalHeight()
+{
+ if ( cellH ) {
+ return cellH*nRows;
+ } else {
+ int th = 0;
+ for( int i = 0 ; i < nRows ; i++ )
+ th += cellHeight( i );
+ return th;
+ }
+}
+
+
+/*
+ \fn uint TQtTableView::tableFlags() const
+
+ Returns the union of the table flags that are currently set.
+
+ \sa setTableFlags(), clearTableFlags(), testTableFlags()
+*/
+
+/*
+ \fn bool TQtTableView::testTableFlags( uint f ) const
+
+ Returns TRUE if any of the table flags in \a f are currently set,
+ otherwise FALSE.
+
+ \sa setTableFlags(), clearTableFlags(), tableFlags()
+*/
+
+/*
+ Sets the table flags to \a f.
+
+ If a flag setting changes the appearance of the table, the table is
+ repainted if - and only if - autoUpdate() is TRUE.
+
+ The table flags are mostly single bits, though there are some multibit
+ flags for convenience. Here is a complete list:
+
+ <dl compact>
+ <dt> Tbl_vScrollBar <dd> - The table has a vertical scroll bar.
+ <dt> Tbl_hScrollBar <dd> - The table has a horizontal scroll bar.
+ <dt> Tbl_autoVScrollBar <dd> - The table has a vertical scroll bar if
+ - and only if - the table is taller than the view.
+ <dt> Tbl_autoHScrollBar <dd> The table has a horizontal scroll bar if
+ - and only if - the table is wider than the view.
+ <dt> Tbl_autoScrollBars <dd> - The union of the previous two flags.
+ <dt> Tbl_clipCellPainting <dd> - The table uses TQPainter::setClipRect() to
+ make sure that paintCell() will not draw outside the cell
+ boundaries.
+ <dt> Tbl_cutCellsV <dd> - The table will never show part of a
+ cell at the bottom of the table; if there is not space for all of
+ a cell, the space is left blank.
+ <dt> Tbl_cutCellsH <dd> - The table will never show part of a
+ cell at the right side of the table; if there is not space for all of
+ a cell, the space is left blank.
+ <dt> Tbl_cutCells <dd> - The union of the previous two flags.
+ <dt> Tbl_scrollLastHCell <dd> - When the user scrolls horizontally,
+ let him/her scroll the last cell left until it is at the left
+ edge of the view. If this flag is not set, the user can only scroll
+ to the point where the last cell is completely visible.
+ <dt> Tbl_scrollLastVCell <dd> - When the user scrolls vertically, let
+ him/her scroll the last cell up until it is at the top edge of
+ the view. If this flag is not set, the user can only scroll to the
+ point where the last cell is completely visible.
+ <dt> Tbl_scrollLastCell <dd> - The union of the previous two flags.
+ <dt> Tbl_smoothHScrolling <dd> - The table scrolls as smoothly as
+ possible when the user scrolls horizontally. When this flag is not
+ set, scrolling is done one cell at a time.
+ <dt> Tbl_smoothVScrolling <dd> - The table scrolls as smoothly as
+ possible when scrolling vertically. When this flag is not set,
+ scrolling is done one cell at a time.
+ <dt> Tbl_smoothScrolling <dd> - The union of the previous two flags.
+ <dt> Tbl_snapToHGrid <dd> - Except when the user is actually scrolling,
+ the leftmost column shown snaps to the leftmost edge of the view.
+ <dt> Tbl_snapToVGrid <dd> - Except when the user is actually
+ scrolling, the top row snaps to the top edge of the view.
+ <dt> Tbl_snapToGrid <dd> - The union of the previous two flags.
+ </dl>
+
+ You can specify more than one flag at a time using bitwise OR.
+
+ Example:
+ \code
+ setTableFlags( Tbl_smoothScrolling | Tbl_autoScrollBars );
+ \endcode
+
+ \warning The cutCells options (\c Tbl_cutCells, \c Tbl_cutCellsH and
+ Tbl_cutCellsV) may cause painting problems when scrollbars are
+ enabled. Do not combine cutCells and scrollbars.
+
+
+ \sa clearTableFlags(), testTableFlags(), tableFlags()
+*/
+
+void TQtTableView::setTableFlags( uint f )
+{
+ f = (f ^ tFlags) & f; // clear flags already set
+ tFlags |= f;
+
+ bool updateOn = autoUpdate();
+ setAutoUpdate( FALSE );
+
+ uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
+
+ if ( f & Tbl_vScrollBar ) {
+ setVerScrollBar( TRUE );
+ }
+ if ( f & Tbl_hScrollBar ) {
+ setHorScrollBar( TRUE );
+ }
+ if ( f & Tbl_autoVScrollBar ) {
+ updateScrollBars( verRange );
+ }
+ if ( f & Tbl_autoHScrollBar ) {
+ updateScrollBars( horRange );
+ }
+ if ( f & Tbl_scrollLastHCell ) {
+ updateScrollBars( horRange );
+ }
+ if ( f & Tbl_scrollLastVCell ) {
+ updateScrollBars( verRange );
+ }
+ if ( f & Tbl_snapToHGrid ) {
+ updateScrollBars( horRange );
+ }
+ if ( f & Tbl_snapToVGrid ) {
+ updateScrollBars( verRange );
+ }
+ if ( f & Tbl_snapToGrid ) { // Note: checks for 2 flags
+ if ( (f & Tbl_snapToHGrid) != 0 && xCellDelta != 0 || //have to scroll?
+ (f & Tbl_snapToVGrid) != 0 && yCellDelta != 0 ) {
+ snapToGrid( (f & Tbl_snapToHGrid) != 0, // do snapping
+ (f & Tbl_snapToVGrid) != 0 );
+ repaintMask |= Tbl_snapToGrid; // tqrepaint table
+ }
+ }
+
+ if ( updateOn ) {
+ setAutoUpdate( TRUE );
+ updateScrollBars();
+ if ( isVisible() && (f & repaintMask) )
+ tqrepaint();
+ }
+
+}
+
+/*
+ Clears the \link setTableFlags() table flags\endlink that are set
+ in \a f.
+
+ Example (clears a single flag):
+ \code
+ clearTableFlags( Tbl_snapToGrid );
+ \endcode
+
+ The default argument clears all flags.
+
+ \sa setTableFlags(), testTableFlags(), tableFlags()
+*/
+
+void TQtTableView::clearTableFlags( uint f )
+{
+ f = (f ^ ~tFlags) & f; // clear flags that are already 0
+ tFlags &= ~f;
+
+ bool updateOn = autoUpdate();
+ setAutoUpdate( FALSE );
+
+ uint repaintMask = Tbl_cutCellsV | Tbl_cutCellsH;
+
+ if ( f & Tbl_vScrollBar ) {
+ setVerScrollBar( FALSE );
+ }
+ if ( f & Tbl_hScrollBar ) {
+ setHorScrollBar( FALSE );
+ }
+ if ( f & Tbl_scrollLastHCell ) {
+ int maxX = maxXOffset();
+ if ( xOffs > maxX ) {
+ setOffset( maxX, yOffs );
+ repaintMask |= Tbl_scrollLastHCell;
+ }
+ updateScrollBars( horRange );
+ }
+ if ( f & Tbl_scrollLastVCell ) {
+ int maxY = maxYOffset();
+ if ( yOffs > maxY ) {
+ setOffset( xOffs, maxY );
+ repaintMask |= Tbl_scrollLastVCell;
+ }
+ updateScrollBars( verRange );
+ }
+ if ( f & Tbl_smoothScrolling ) { // Note: checks for 2 flags
+ if ((f & Tbl_smoothHScrolling) != 0 && xCellDelta != 0 ||//must scroll?
+ (f & Tbl_smoothVScrolling) != 0 && yCellDelta != 0 ) {
+ snapToGrid( (f & Tbl_smoothHScrolling) != 0, // do snapping
+ (f & Tbl_smoothVScrolling) != 0 );
+ repaintMask |= Tbl_smoothScrolling; // tqrepaint table
+ }
+ }
+ if ( f & Tbl_snapToHGrid ) {
+ updateScrollBars( horRange );
+ }
+ if ( f & Tbl_snapToVGrid ) {
+ updateScrollBars( verRange );
+ }
+ if ( updateOn ) {
+ setAutoUpdate( TRUE );
+ updateScrollBars(); // returns immediately if nothing to do
+ if ( isVisible() && (f & repaintMask) )
+ tqrepaint();
+ }
+
+}
+
+
+/*
+ \fn bool TQtTableView::autoUpdate() const
+
+ Returns TRUE if the view updates itself automatically whenever it
+ is changed in some way.
+
+ \sa setAutoUpdate()
+*/
+
+/*
+ Sets the auto-update option of the table view to \a enable.
+
+ If \a enable is TRUE (this is the default), the view updates itself
+ automatically whenever it has changed in some way (for example, when a
+ \link setTableFlags() flag\endlink is changed).
+
+ If \a enable is FALSE, the view does NOT tqrepaint itself or update
+ its internal state variables when it is changed. This can be
+ useful to avoid flicker during large changes and is singularly
+ useless otherwise. Disable auto-update, do the changes, re-enable
+ auto-update and call tqrepaint().
+
+ \warning Do not leave the view in this state for a long time
+ (i.e., between events). If, for example, the user interacts with the
+ view when auto-update is off, strange things can happen.
+
+ Setting auto-update to TRUE does not tqrepaint the view; you must call
+ tqrepaint() to do this.
+
+ \sa autoUpdate(), tqrepaint()
+*/
+
+void TQtTableView::setAutoUpdate( bool enable )
+{
+ if ( isUpdatesEnabled() == enable )
+ return;
+ setUpdatesEnabled( enable );
+ if ( enable ) {
+ showOrHideScrollBars();
+ updateScrollBars();
+ }
+}
+
+
+/*
+ Repaints the cell at row \a row, column \a col if it is inside the view.
+
+ If \a erase is TRUE, the relevant part of the view is cleared to the
+ background color/pixmap before the contents are repainted.
+
+ \sa isVisible()
+*/
+
+void TQtTableView::updateCell( int row, int col, bool erase )
+{
+ int xPos, yPos;
+ if ( !colXPos( col, &xPos ) )
+ return;
+ if ( !rowYPos( row, &yPos ) )
+ return;
+ TQRect uR = TQRect( xPos, yPos,
+ cellW ? cellW : cellWidth(col),
+ cellH ? cellH : cellHeight(row) );
+ tqrepaint( uR.intersect(viewRect()), erase );
+}
+
+
+/*
+ \fn TQRect TQtTableView::cellUpdateRect() const
+
+ This function should be called only from the paintCell() function in
+ subclasses. It returns the portion of a cell that actually needs to be
+ updated in \e cell coordinates. This is useful only for non-trivial
+ paintCell().
+
+*/
+
+/*
+ Returns the rectangle that is the actual table, excluding any
+ frame, in \e widget coordinates.
+*/
+
+TQRect TQtTableView::viewRect() const
+{
+ return TQRect( frameWidth(), frameWidth(), viewWidth(), viewHeight() );
+}
+
+
+/*
+ Returns the index of the last (bottom) row in the view.
+ The index of the first row is 0.
+
+ If no rows are visible it returns -1. This can happen if the
+ view is too small for the first row and Tbl_cutCellsV is set.
+
+ \sa lastColVisible()
+*/
+
+int TQtTableView::lastRowVisible() const
+{
+ int cellMaxY;
+ int row = tqfindRawRow( maxViewY(), &cellMaxY );
+ if ( row == -1 || row >= nRows ) { // maxViewY() past end?
+ row = nRows - 1; // yes: return last row
+ } else {
+ if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() ) {
+ if ( row == yCellOffs ) // cut by right margin?
+ return -1; // yes, nothing in the view
+ else
+ row = row - 1; // cut by margin, one back
+ }
+ }
+ return row;
+}
+
+/*
+ Returns the index of the last (right) column in the view.
+ The index of the first column is 0.
+
+ If no columns are visible it returns -1. This can happen if the
+ view is too narrow for the first column and Tbl_cutCellsH is set.
+
+ \sa lastRowVisible()
+*/
+
+int TQtTableView::lastColVisible() const
+{
+ int cellMaxX;
+ int col = tqfindRawCol( maxViewX(), &cellMaxX );
+ if ( col == -1 || col >= nCols ) { // maxViewX() past end?
+ col = nCols - 1; // yes: return last col
+ } else {
+ if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() ) {
+ if ( col == xCellOffs ) // cut by bottom margin?
+ return -1; // yes, nothing in the view
+ else
+ col = col - 1; // cell by margin, one back
+ }
+ }
+ return col;
+}
+
+/*
+ Returns TRUE if \a row is at least partially visible.
+ \sa colIsVisible()
+*/
+
+bool TQtTableView::rowIsVisible( int row ) const
+{
+ return rowYPos( row, 0 );
+}
+
+/*
+ Returns TRUE if \a col is at least partially visible.
+ \sa rowIsVisible()
+*/
+
+bool TQtTableView::colIsVisible( int col ) const
+{
+ return colXPos( col, 0 );
+}
+
+
+/*
+ \internal
+ Called when both scroll bars are active at the same time. Covers the
+ bottom left corner between the two scroll bars with an empty widget.
+*/
+
+void TQtTableView::coverCornerSquare( bool enable )
+{
+ coveringCornerSquare = enable;
+ if ( !cornerSquare && enable ) {
+ cornerSquare = new TQCornerSquare( this );
+ TQ_CHECK_PTR( cornerSquare );
+ cornerSquare->setGeometry( maxViewX() + frameWidth() + 1,
+ maxViewY() + frameWidth() + 1,
+ VSBEXT,
+ HSBEXT);
+ }
+ if ( autoUpdate() && cornerSquare ) {
+ if ( enable )
+ cornerSquare->show();
+ else
+ cornerSquare->hide();
+ }
+}
+
+
+/*
+ \internal
+ Scroll the view to a position such that:
+
+ If \a horizontal is TRUE, the leftmost column shown fits snugly
+ with the left edge of the view.
+
+ If \a vertical is TRUE, the top row shown fits snugly with the top
+ of the view.
+
+ You can achieve the same effect automatically by setting any of the
+ \link setTableFlags() Tbl_snapTo*Grid \endlink table flags.
+*/
+
+void TQtTableView::snapToGrid( bool horizontal, bool vertical )
+{
+ int newXCell = -1;
+ int newYCell = -1;
+ if ( horizontal && xCellDelta != 0 ) {
+ int w = cellW ? cellW : cellWidth( xCellOffs );
+ if ( xCellDelta >= w/2 )
+ newXCell = xCellOffs + 1;
+ else
+ newXCell = xCellOffs;
+ }
+ if ( vertical && yCellDelta != 0 ) {
+ int h = cellH ? cellH : cellHeight( yCellOffs );
+ if ( yCellDelta >= h/2 )
+ newYCell = yCellOffs + 1;
+ else
+ newYCell = yCellOffs;
+ }
+ setTopLeftCell( newYCell, newXCell ); //row,column
+}
+
+/*
+ \internal
+ This internal slot is connected to the horizontal scroll bar's
+ TQScrollBar::valueChanged() signal.
+
+ Moves the table horizontally to offset \a val without updating the
+ scroll bar.
+*/
+
+void TQtTableView::horSbValue( int val )
+{
+ if ( horSliding ) {
+ horSliding = FALSE;
+ if ( horSnappingOff ) {
+ horSnappingOff = FALSE;
+ tFlags |= Tbl_snapToHGrid;
+ }
+ }
+ setOffset( val, yOffs, FALSE );
+}
+
+/*
+ \internal
+ This internal slot is connected to the horizontal scroll bar's
+ TQScrollBar::sliderMoved() signal.
+
+ Scrolls the table smoothly horizontally even if \c Tbl_snapToHGrid is set.
+*/
+
+void TQtTableView::horSbSliding( int val )
+{
+ if ( testTableFlags(Tbl_snapToHGrid) &&
+ testTableFlags(Tbl_smoothHScrolling) ) {
+ tFlags &= ~Tbl_snapToHGrid; // turn off snapping while sliding
+ setOffset( val, yOffs, FALSE );
+ tFlags |= Tbl_snapToHGrid; // turn on snapping again
+ } else {
+ setOffset( val, yOffs, FALSE );
+ }
+}
+
+/*
+ \internal
+ This internal slot is connected to the horizontal scroll bar's
+ TQScrollBar::sliderReleased() signal.
+*/
+
+void TQtTableView::horSbSlidingDone( )
+{
+ if ( testTableFlags(Tbl_snapToHGrid) &&
+ testTableFlags(Tbl_smoothHScrolling) )
+ snapToGrid( TRUE, FALSE );
+}
+
+/*
+ \internal
+ This internal slot is connected to the vertical scroll bar's
+ TQScrollBar::valueChanged() signal.
+
+ Moves the table vertically to offset \a val without updating the
+ scroll bar.
+*/
+
+void TQtTableView::verSbValue( int val )
+{
+ if ( verSliding ) {
+ verSliding = FALSE;
+ if ( verSnappingOff ) {
+ verSnappingOff = FALSE;
+ tFlags |= Tbl_snapToVGrid;
+ }
+ }
+ setOffset( xOffs, val, FALSE );
+}
+
+/*
+ \internal
+ This internal slot is connected to the vertical scroll bar's
+ TQScrollBar::sliderMoved() signal.
+
+ Scrolls the table smoothly vertically even if \c Tbl_snapToVGrid is set.
+*/
+
+void TQtTableView::verSbSliding( int val )
+{
+ if ( testTableFlags(Tbl_snapToVGrid) &&
+ testTableFlags(Tbl_smoothVScrolling) ) {
+ tFlags &= ~Tbl_snapToVGrid; // turn off snapping while sliding
+ setOffset( xOffs, val, FALSE );
+ tFlags |= Tbl_snapToVGrid; // turn on snapping again
+ } else {
+ setOffset( xOffs, val, FALSE );
+ }
+}
+
+/*
+ \internal
+ This internal slot is connected to the vertical scroll bar's
+ TQScrollBar::sliderReleased() signal.
+*/
+
+void TQtTableView::verSbSlidingDone( )
+{
+ if ( testTableFlags(Tbl_snapToVGrid) &&
+ testTableFlags(Tbl_smoothVScrolling) )
+ snapToGrid( FALSE, TRUE );
+}
+
+
+/*
+ This virtual function is called before painting of table cells
+ is started. It can be reimplemented by subclasses that want to
+ to set up the painter in a special way and that do not want to
+ do so for each cell.
+*/
+
+void TQtTableView::setupPainter( TQPainter * )
+{
+}
+
+/*
+ \fn void TQtTableView::paintCell( TQPainter *p, int row, int col )
+
+ This pure virtual function is called to paint the single cell at \a
+ (row,col) using \a p, which is open when paintCell() is called and
+ must remain open.
+
+ The coordinate system is \link TQPainter::translate() translated \endlink
+ so that the origin is at the top-left corner of the cell to be
+ painted, i.e. \e cell coordinates. Do not scale or shear the coordinate
+ system (or if you do, restore the transformation matrix before you
+ return).
+
+ The painter is not clipped by default and for maximum efficiency. For safety,
+ call setTableFlags(Tbl_clipCellPainting) to enable clipping.
+
+ \sa paintEvent(), setTableFlags() */
+
+
+/*
+ Handles paint events, \a e, for the table view.
+
+ Calls paintCell() for the cells that needs to be repainted.
+*/
+
+void TQtTableView::paintEvent( TQPaintEvent *e )
+{
+ TQRect updateR = e->rect(); // update rectangle
+ if ( sbDirty ) {
+ bool e = eraseInPaint;
+ updateScrollBars();
+ eraseInPaint = e;
+ }
+
+ TQPainter paint( this );
+
+ if ( !contentsRect().tqcontains( updateR, TRUE ) ) {// update frame ?
+ drawFrame( &paint );
+ if ( updateR.left() < frameWidth() ) //###
+ updateR.setLeft( frameWidth() );
+ if ( updateR.top() < frameWidth() )
+ updateR.setTop( frameWidth() );
+ }
+
+ int maxWX = maxViewX();
+ int maxWY = maxViewY();
+ if ( updateR.right() > maxWX )
+ updateR.setRight( maxWX );
+ if ( updateR.bottom() > maxWY )
+ updateR.setBottom( maxWY );
+
+ setupPainter( &paint ); // prepare for painting table
+
+ int firstRow = tqfindRow( updateR.y() );
+ int firstCol = tqfindCol( updateR.x() );
+ int xStart, yStart;
+ if ( !colXPos( firstCol, &xStart ) || !rowYPos( firstRow, &yStart ) ) {
+ paint.eraseRect( updateR ); // erase area outside cells but in view
+ return;
+ }
+ int maxX = updateR.right();
+ int maxY = updateR.bottom();
+ int row = firstRow;
+ int col;
+ int yPos = yStart;
+ int xPos = maxX+1; // in case the while() is empty
+ int nextX;
+ int nextY;
+ TQRect winR = viewRect();
+ TQRect cellR;
+ TQRect cellUR;
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix matrix;
+#endif
+
+ while ( yPos <= maxY && row < nRows ) {
+ nextY = yPos + (cellH ? cellH : cellHeight( row ));
+ if ( testTableFlags( Tbl_cutCellsV ) && nextY > ( maxWY + 1 ) )
+ break;
+ col = firstCol;
+ xPos = xStart;
+ while ( xPos <= maxX && col < nCols ) {
+ nextX = xPos + (cellW ? cellW : cellWidth( col ));
+ if ( testTableFlags( Tbl_cutCellsH ) && nextX > ( maxWX + 1 ) )
+ break;
+
+ cellR.setRect( xPos, yPos, cellW ? cellW : cellWidth(col),
+ cellH ? cellH : cellHeight(row) );
+ cellUR = cellR.intersect( updateR );
+ if ( cellUR.isValid() ) {
+ cellUpdateR = cellUR;
+ cellUpdateR.moveBy( -xPos, -yPos ); // cell coordinates
+ if ( eraseInPaint )
+ paint.eraseRect( cellUR );
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ matrix.translate( xPos, yPos );
+ paint.setWorldMatrix( matrix );
+ if ( testTableFlags(Tbl_clipCellPainting) ||
+ frameWidth() > 0 && !winR.tqcontains( cellR ) ) { //##arnt
+ paint.setClipRect( cellUR );
+ paintCell( &paint, row, col );
+ paint.setClipping( FALSE );
+ } else {
+ paintCell( &paint, row, col );
+ }
+ matrix.reset();
+ paint.setWorldMatrix( matrix );
+#else
+ paint.translate( xPos, yPos );
+ if ( testTableFlags(Tbl_clipCellPainting) ||
+ frameWidth() > 0 && !winR.tqcontains( cellR ) ) { //##arnt
+ paint.setClipRect( cellUR );
+ paintCell( &paint, row, col );
+ paint.setClipping( FALSE );
+ } else {
+ paintCell( &paint, row, col );
+ }
+ paint.translate( -xPos, -yPos );
+#endif
+ }
+ col++;
+ xPos = nextX;
+ }
+ row++;
+ yPos = nextY;
+ }
+
+ // while painting we have to erase any areas in the view that
+ // are not covered by cells but are covered by the paint event
+ // rectangle these must be erased. We know that xPos is the last
+ // x pixel updated + 1 and that yPos is the last y pixel updated + 1.
+
+ // Note that this needs to be done regardless whether we do
+ // eraseInPaint or not. Reason: a subclass may implement
+ // flicker-freeness and encourage the use of tqrepaint(FALSE).
+ // The subclass, however, cannot draw all pixels, just those
+ // inside the cells. So TQtTableView is reponsible for all pixels
+ // outside the cells.
+
+ TQRect viewR = viewRect();
+ const TQColorGroup g = tqcolorGroup();
+
+ if ( xPos <= maxX ) {
+ TQRect r = viewR;
+ r.setLeft( xPos );
+ r.setBottom( yPos<maxY?yPos:maxY );
+ if ( inherits( "TQMultiLineEdit" ) )
+ paint.fillRect( r.intersect( updateR ), g.base() );
+ else
+ paint.eraseRect( r.intersect( updateR ) );
+ }
+ if ( yPos <= maxY ) {
+ TQRect r = viewR;
+ r.setTop( yPos );
+ if ( inherits( "TQMultiLineEdit" ) )
+ paint.fillRect( r.intersect( updateR ), g.base() );
+ else
+ paint.eraseRect( r.intersect( updateR ) );
+ }
+}
+
+/*\reimp
+*/
+void TQtTableView::resizeEvent( TQResizeEvent * )
+{
+ updateScrollBars( horValue | verValue | horSteps | horGeometry | horRange |
+ verSteps | verGeometry | verRange );
+ showOrHideScrollBars();
+ updateFrameSize();
+ int maxX = TQMIN( xOffs, maxXOffset() ); // ### can be slow
+ int maxY = TQMIN( yOffs, maxYOffset() );
+ setOffset( maxX, maxY );
+}
+
+
+/*
+ Redraws all visible cells in the table view.
+*/
+
+void TQtTableView::updateView()
+{
+ tqrepaint( viewRect() );
+}
+
+/*
+ Returns a pointer to the vertical scroll bar mainly so you can
+ connect() to its Q_SIGNALS. Note that the scroll bar works in pixel
+ values; use tqfindRow() to translate to cell numbers.
+*/
+
+TQScrollBar *TQtTableView::verticalScrollBar() const
+{
+ TQtTableView *that = (TQtTableView*)this; // semantic const
+ if ( !vScrollBar ) {
+ TQScrollBar *sb = new TQScrollBar( TQScrollBar::Vertical, that );
+#ifndef TQT_NO_CURSOR
+ sb->setCursor( arrowCursor );
+#endif
+ sb->resize( sb->tqsizeHint() ); // height is irrelevant
+ TQ_CHECK_PTR(sb);
+ sb->setTracking( FALSE );
+ sb->setFocusPolicy( NoFocus );
+ connect( sb, TQT_SIGNAL(valueChanged(int)),
+ TQT_SLOT(verSbValue(int)));
+ connect( sb, TQT_SIGNAL(sliderMoved(int)),
+ TQT_SLOT(verSbSliding(int)));
+ connect( sb, TQT_SIGNAL(sliderReleased()),
+ TQT_SLOT(verSbSlidingDone()));
+ sb->hide();
+ that->vScrollBar = sb;
+ return sb;
+ }
+ return vScrollBar;
+}
+
+/*
+ Returns a pointer to the horizontal scroll bar mainly so you can
+ connect() to its Q_SIGNALS. Note that the scroll bar works in pixel
+ values; use tqfindCol() to translate to cell numbers.
+*/
+
+TQScrollBar *TQtTableView::horizontalScrollBar() const
+{
+ TQtTableView *that = (TQtTableView*)this; // semantic const
+ if ( !hScrollBar ) {
+ TQScrollBar *sb = new TQScrollBar( TQScrollBar::Horizontal, that );
+#ifndef TQT_NO_CURSOR
+ sb->setCursor( arrowCursor );
+#endif
+ sb->resize( sb->tqsizeHint() ); // width is irrelevant
+ sb->setFocusPolicy( NoFocus );
+ TQ_CHECK_PTR(sb);
+ sb->setTracking( FALSE );
+ connect( sb, TQT_SIGNAL(valueChanged(int)),
+ TQT_SLOT(horSbValue(int)));
+ connect( sb, TQT_SIGNAL(sliderMoved(int)),
+ TQT_SLOT(horSbSliding(int)));
+ connect( sb, TQT_SIGNAL(sliderReleased()),
+ TQT_SLOT(horSbSlidingDone()));
+ sb->hide();
+ that->hScrollBar = sb;
+ return sb;
+ }
+ return hScrollBar;
+}
+
+/*
+ Enables or disables the horizontal scroll bar, as required by
+ setAutoUpdate() and the \link setTableFlags() table flags\endlink.
+*/
+
+void TQtTableView::setHorScrollBar( bool on, bool update )
+{
+ if ( on ) {
+ tFlags |= Tbl_hScrollBar;
+ horizontalScrollBar(); // created
+ if ( update )
+ updateScrollBars( horMask | verMask );
+ else
+ sbDirty = sbDirty | (horMask | verMask);
+ if ( testTableFlags( Tbl_vScrollBar ) )
+ coverCornerSquare( TRUE );
+ if ( autoUpdate() )
+ sbDirty = sbDirty | horMask;
+ } else {
+ tFlags &= ~Tbl_hScrollBar;
+ if ( !hScrollBar )
+ return;
+ coverCornerSquare( FALSE );
+ bool hideScrollBar = autoUpdate() && hScrollBar->isVisible();
+ if ( hideScrollBar )
+ hScrollBar->hide();
+ if ( update )
+ updateScrollBars( verMask );
+ else
+ sbDirty = sbDirty | verMask;
+ if ( hideScrollBar && isVisible() )
+ tqrepaint( hScrollBar->x(), hScrollBar->y(),
+ width() - hScrollBar->x(), hScrollBar->height() );
+ }
+ if ( update )
+ updateFrameSize();
+}
+
+
+/*
+ Enables or disables the vertical scroll bar, as required by
+ setAutoUpdate() and the \link setTableFlags() table flags\endlink.
+*/
+
+void TQtTableView::setVerScrollBar( bool on, bool update )
+{
+ if ( on ) {
+ tFlags |= Tbl_vScrollBar;
+ verticalScrollBar(); // created
+ if ( update )
+ updateScrollBars( verMask | horMask );
+ else
+ sbDirty = sbDirty | (horMask | verMask);
+ if ( testTableFlags( Tbl_hScrollBar ) )
+ coverCornerSquare( TRUE );
+ if ( autoUpdate() )
+ sbDirty = sbDirty | verMask;
+ } else {
+ tFlags &= ~Tbl_vScrollBar;
+ if ( !vScrollBar )
+ return;
+ coverCornerSquare( FALSE );
+ bool hideScrollBar = autoUpdate() && vScrollBar->isVisible();
+ if ( hideScrollBar )
+ vScrollBar->hide();
+ if ( update )
+ updateScrollBars( horMask );
+ else
+ sbDirty = sbDirty | horMask;
+ if ( hideScrollBar && isVisible() )
+ tqrepaint( vScrollBar->x(), vScrollBar->y(),
+ vScrollBar->width(), height() - vScrollBar->y() );
+ }
+ if ( update )
+ updateFrameSize();
+}
+
+
+
+
+int TQtTableView::tqfindRawRow( int yPos, int *cellMaxY, int *cellMinY,
+ bool goOutsideView ) const
+{
+ int r = -1;
+ if ( nRows == 0 )
+ return r;
+ if ( goOutsideView || yPos >= minViewY() && yPos <= maxViewY() ) {
+ if ( yPos < minViewY() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQtTableView::tqfindRawRow: (%s) internal error: "
+ "yPos < minViewY() && goOutsideView "
+ "not supported. (%d,%d)",
+ name( "unnamed" ), yPos, yOffs );
+#endif
+ return -1;
+ }
+ if ( cellH ) { // uniform cell height
+ r = (yPos - minViewY() + yCellDelta)/cellH; // cell offs from top
+ if ( cellMaxY )
+ *cellMaxY = (r + 1)*cellH + minViewY() - yCellDelta - 1;
+ if ( cellMinY )
+ *cellMinY = r*cellH + minViewY() - yCellDelta;
+ r += yCellOffs; // absolute cell index
+ } else { // variable cell height
+ TQtTableView *tw = (TQtTableView *)this;
+ r = yCellOffs;
+ int h = minViewY() - yCellDelta; //##arnt3
+ int oldH = h;
+ TQ_ASSERT( r < nRows );
+ while ( r < nRows ) {
+ oldH = h;
+ h += tw->cellHeight( r ); // Start of next cell
+ if ( yPos < h )
+ break;
+ r++;
+ }
+ if ( cellMaxY )
+ *cellMaxY = h - 1;
+ if ( cellMinY )
+ *cellMinY = oldH;
+ }
+ }
+ return r;
+
+}
+
+
+int TQtTableView::tqfindRawCol( int xPos, int *cellMaxX, int *cellMinX ,
+ bool goOutsideView ) const
+{
+ int c = -1;
+ if ( nCols == 0 )
+ return c;
+ if ( goOutsideView || xPos >= minViewX() && xPos <= maxViewX() ) {
+ if ( xPos < minViewX() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQtTableView::tqfindRawCol: (%s) internal error: "
+ "xPos < minViewX() && goOutsideView "
+ "not supported. (%d,%d)",
+ name( "unnamed" ), xPos, xOffs );
+#endif
+ return -1;
+ }
+ if ( cellW ) { // uniform cell width
+ c = (xPos - minViewX() + xCellDelta)/cellW; //cell offs from left
+ if ( cellMaxX )
+ *cellMaxX = (c + 1)*cellW + minViewX() - xCellDelta - 1;
+ if ( cellMinX )
+ *cellMinX = c*cellW + minViewX() - xCellDelta;
+ c += xCellOffs; // absolute cell index
+ } else { // variable cell width
+ TQtTableView *tw = (TQtTableView *)this;
+ c = xCellOffs;
+ int w = minViewX() - xCellDelta; //##arnt3
+ int oldW = w;
+ TQ_ASSERT( c < nCols );
+ while ( c < nCols ) {
+ oldW = w;
+ w += tw->cellWidth( c ); // Start of next cell
+ if ( xPos < w )
+ break;
+ c++;
+ }
+ if ( cellMaxX )
+ *cellMaxX = w - 1;
+ if ( cellMinX )
+ *cellMinX = oldW;
+ }
+ }
+ return c;
+}
+
+
+/*
+ Returns the index of the row at position \a yPos, where \a yPos is in
+ \e widget coordinates. Returns -1 if \a yPos is outside the valid
+ range.
+
+ \sa tqfindCol(), rowYPos()
+*/
+
+int TQtTableView::tqfindRow( int yPos ) const
+{
+ int cellMaxY;
+ int row = tqfindRawRow( yPos, &cellMaxY );
+ if ( testTableFlags(Tbl_cutCellsV) && cellMaxY > maxViewY() )
+ row = - 1; // cell cut by bottom margin
+ if ( row >= nRows )
+ row = -1;
+ return row;
+}
+
+
+/*
+ Returns the index of the column at position \a xPos, where \a xPos is
+ in \e widget coordinates. Returns -1 if \a xPos is outside the valid
+ range.
+
+ \sa tqfindRow(), colXPos()
+*/
+
+int TQtTableView::tqfindCol( int xPos ) const
+{
+ int cellMaxX;
+ int col = tqfindRawCol( xPos, &cellMaxX );
+ if ( testTableFlags(Tbl_cutCellsH) && cellMaxX > maxViewX() )
+ col = - 1; // cell cut by right margin
+ if ( col >= nCols )
+ col = -1;
+ return col;
+}
+
+
+/*
+ Computes the position in the widget of row \a row.
+
+ Returns TRUE and stores the result in \a *yPos (in \e widget
+ coordinates) if the row is visible. Returns FALSE and does not modify
+ \a *yPos if \a row is invisible or invalid.
+
+ \sa colXPos(), tqfindRow()
+*/
+
+bool TQtTableView::rowYPos( int row, int *yPos ) const
+{
+ int y;
+ if ( row >= yCellOffs ) {
+ if ( cellH ) {
+ int lastVisible = lastRowVisible();
+ if ( row > lastVisible || lastVisible == -1 )
+ return FALSE;
+ y = (row - yCellOffs)*cellH + minViewY() - yCellDelta;
+ } else {
+ //##arnt3
+ y = minViewY() - yCellDelta; // y of leftmost cell in view
+ int r = yCellOffs;
+ TQtTableView *tw = (TQtTableView *)this;
+ int maxY = maxViewY();
+ while ( r < row && y <= maxY )
+ y += tw->cellHeight( r++ );
+ if ( y > maxY )
+ return FALSE;
+
+ }
+ } else {
+ return FALSE;
+ }
+ if ( yPos )
+ *yPos = y;
+ return TRUE;
+}
+
+
+/*
+ Computes the position in the widget of column \a col.
+
+ Returns TRUE and stores the result in \a *xPos (in \e widget
+ coordinates) if the column is visible. Returns FALSE and does not
+ modify \a *xPos if \a col is invisible or invalid.
+
+ \sa rowYPos(), tqfindCol()
+*/
+
+bool TQtTableView::colXPos( int col, int *xPos ) const
+{
+ int x;
+ if ( col >= xCellOffs ) {
+ if ( cellW ) {
+ int lastVisible = lastColVisible();
+ if ( col > lastVisible || lastVisible == -1 )
+ return FALSE;
+ x = (col - xCellOffs)*cellW + minViewX() - xCellDelta;
+ } else {
+ //##arnt3
+ x = minViewX() - xCellDelta; // x of uppermost cell in view
+ int c = xCellOffs;
+ TQtTableView *tw = (TQtTableView *)this;
+ int maxX = maxViewX();
+ while ( c < col && x <= maxX )
+ x += tw->cellWidth( c++ );
+ if ( x > maxX )
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+ if ( xPos )
+ *xPos = x;
+ return TRUE;
+}
+
+
+/*
+ Moves the visible area of the table right by \a xPixels and
+ down by \a yPixels pixels. Both may be negative.
+
+ \warning You might tqfind that TQScrollView offers a higher-level of
+ functionality than using TQtTableView and this function.
+
+ This function is \e not the same as TQWidget::scroll(); in particular,
+ the signs of \a xPixels and \a yPixels have the reverse semantics.
+
+ \sa setXOffset(), setYOffset(), setOffset(), setTopCell(),
+ setLeftCell()
+*/
+
+void TQtTableView::scroll( int xPixels, int yPixels )
+{
+ TQWidget::scroll( -xPixels, -yPixels, contentsRect() );
+}
+
+
+/*
+ Returns the leftmost pixel of the table view in \e view
+ coordinates. This excludes the frame and any header.
+
+ \sa maxViewY(), viewWidth(), contentsRect()
+*/
+
+int TQtTableView::minViewX() const
+{
+ return frameWidth();
+}
+
+
+/*
+ Returns the top pixel of the table view in \e view
+ coordinates. This excludes the frame and any header.
+
+ \sa maxViewX(), viewHeight(), contentsRect()
+*/
+
+int TQtTableView::minViewY() const
+{
+ return frameWidth();
+}
+
+
+/*
+ Returns the rightmost pixel of the table view in \e view
+ coordinates. This excludes the frame and any scroll bar, but
+ includes blank pixels to the right of the visible table data.
+
+ \sa maxViewY(), viewWidth(), contentsRect()
+*/
+
+int TQtTableView::maxViewX() const
+{
+ return width() - 1 - frameWidth()
+ - (tFlags & Tbl_vScrollBar ? VSBEXT
+ : 0);
+}
+
+
+/*
+ Returns the bottom pixel of the table view in \e view
+ coordinates. This excludes the frame and any scroll bar, but
+ includes blank pixels below the visible table data.
+
+ \sa maxViewX(), viewHeight(), contentsRect()
+*/
+
+int TQtTableView::maxViewY() const
+{
+ return height() - 1 - frameWidth()
+ - (tFlags & Tbl_hScrollBar ? HSBEXT
+ : 0);
+}
+
+
+/*
+ Returns the width of the table view, as such, in \e view
+ coordinates. This does not include any header, scroll bar or frame,
+ but it does include background pixels to the right of the table data.
+
+ \sa minViewX() maxViewX(), viewHeight(), contentsRect() viewRect()
+*/
+
+int TQtTableView::viewWidth() const
+{
+ return maxViewX() - minViewX() + 1;
+}
+
+
+/*
+ Returns the height of the table view, as such, in \e view
+ coordinates. This does not include any header, scroll bar or frame,
+ but it does include background pixels below the table data.
+
+ \sa minViewY() maxViewY() viewWidth() contentsRect() viewRect()
+*/
+
+int TQtTableView::viewHeight() const
+{
+ return maxViewY() - minViewY() + 1;
+}
+
+
+void TQtTableView::doAutoScrollBars()
+{
+ int viewW = width() - frameWidth() - minViewX();
+ int viewH = height() - frameWidth() - minViewY();
+ bool vScrollOn = testTableFlags(Tbl_vScrollBar);
+ bool hScrollOn = testTableFlags(Tbl_hScrollBar);
+ int w = 0;
+ int h = 0;
+ int i;
+
+ if ( testTableFlags(Tbl_autoHScrollBar) ) {
+ if ( cellW ) {
+ w = cellW*nCols;
+ } else {
+ i = 0;
+ while ( i < nCols && w <= viewW )
+ w += cellWidth( i++ );
+ }
+ if ( w > viewW )
+ hScrollOn = TRUE;
+ else
+ hScrollOn = FALSE;
+ }
+
+ if ( testTableFlags(Tbl_autoVScrollBar) ) {
+ if ( cellH ) {
+ h = cellH*nRows;
+ } else {
+ i = 0;
+ while ( i < nRows && h <= viewH )
+ h += cellHeight( i++ );
+ }
+
+ if ( h > viewH )
+ vScrollOn = TRUE;
+ else
+ vScrollOn = FALSE;
+ }
+
+ if ( testTableFlags(Tbl_autoHScrollBar) && vScrollOn && !hScrollOn )
+ if ( w > viewW - VSBEXT )
+ hScrollOn = TRUE;
+
+ if ( testTableFlags(Tbl_autoVScrollBar) && hScrollOn && !vScrollOn )
+ if ( h > viewH - HSBEXT )
+ vScrollOn = TRUE;
+
+ setHorScrollBar( hScrollOn, FALSE );
+ setVerScrollBar( vScrollOn, FALSE );
+ updateFrameSize();
+}
+
+
+/*
+ \fn void TQtTableView::updateScrollBars()
+
+ Updates the scroll bars' contents and presence to match the table's
+ state. Generally, you should not need to call this.
+
+ \sa setTableFlags()
+*/
+
+/*
+ Updates the scroll bars' contents and presence to match the table's
+ state \c or \a f.
+
+ \sa setTableFlags()
+*/
+
+void TQtTableView::updateScrollBars( uint f )
+{
+ sbDirty = sbDirty | f;
+ if ( inSbUpdate )
+ return;
+ inSbUpdate = TRUE;
+
+ if ( testTableFlags(Tbl_autoHScrollBar) && (sbDirty & horRange) ||
+ testTableFlags(Tbl_autoVScrollBar) && (sbDirty & verRange) )
+ // if range change and auto
+ doAutoScrollBars(); // turn scroll bars on/off if needed
+
+ if ( !autoUpdate() ) {
+ inSbUpdate = FALSE;
+ return;
+ }
+ if ( yOffset() > 0 && testTableFlags( Tbl_autoVScrollBar ) &&
+ !testTableFlags( Tbl_vScrollBar ) ) {
+ setYOffset( 0 );
+ }
+ if ( xOffset() > 0 && testTableFlags( Tbl_autoHScrollBar ) &&
+ !testTableFlags( Tbl_hScrollBar ) ) {
+ setXOffset( 0 );
+ }
+ if ( !isVisible() ) {
+ inSbUpdate = FALSE;
+ return;
+ }
+
+ if ( testTableFlags(Tbl_hScrollBar) && (sbDirty & horMask) != 0 ) {
+ if ( sbDirty & horGeometry )
+ hScrollBar->setGeometry( 0,height() - HSBEXT,
+ viewWidth() + frameWidth()*2,
+ HSBEXT);
+
+ if ( sbDirty & horSteps ) {
+ if ( cellW )
+ hScrollBar->setSteps( TQMIN(cellW,viewWidth()/2), viewWidth() );
+ else
+ hScrollBar->setSteps( 16, viewWidth() );
+ }
+
+ if ( sbDirty & horRange )
+ hScrollBar->setRange( 0, maxXOffset() );
+
+ if ( sbDirty & horValue )
+ hScrollBar->setValue( xOffs );
+
+ // show scrollbar only when it has a sane tqgeometry
+ if ( !hScrollBar->isVisible() )
+ hScrollBar->show();
+ }
+
+ if ( testTableFlags(Tbl_vScrollBar) && (sbDirty & verMask) != 0 ) {
+ if ( sbDirty & verGeometry )
+ vScrollBar->setGeometry( width() - VSBEXT, 0,
+ VSBEXT,
+ viewHeight() + frameWidth()*2 );
+
+ if ( sbDirty & verSteps ) {
+ if ( cellH )
+ vScrollBar->setSteps( TQMIN(cellH,viewHeight()/2), viewHeight() );
+ else
+ vScrollBar->setSteps( 16, viewHeight() ); // fttb! ###
+ }
+
+ if ( sbDirty & verRange )
+ vScrollBar->setRange( 0, maxYOffset() );
+
+ if ( sbDirty & verValue )
+ vScrollBar->setValue( yOffs );
+
+ // show scrollbar only when it has a sane tqgeometry
+ if ( !vScrollBar->isVisible() )
+ vScrollBar->show();
+ }
+ if ( coveringCornerSquare &&
+ ( (sbDirty & verGeometry ) || (sbDirty & horGeometry)) )
+ cornerSquare->move( maxViewX() + frameWidth() + 1,
+ maxViewY() + frameWidth() + 1 );
+
+ sbDirty = 0;
+ inSbUpdate = FALSE;
+}
+
+
+void TQtTableView::updateFrameSize()
+{
+ int rw = width() - ( testTableFlags(Tbl_vScrollBar) ?
+ VSBEXT : 0 );
+ int rh = height() - ( testTableFlags(Tbl_hScrollBar) ?
+ HSBEXT : 0 );
+ if ( rw < 0 )
+ rw = 0;
+ if ( rh < 0 )
+ rh = 0;
+
+ if ( autoUpdate() ) {
+ int fh = frameRect().height();
+ int fw = frameRect().width();
+ setFrameRect( TQRect(0,0,rw,rh) );
+
+ if ( rw != fw )
+ update( TQMIN(fw,rw) - frameWidth() - 2, 0, frameWidth()+4, rh );
+ if ( rh != fh )
+ update( 0, TQMIN(fh,rh) - frameWidth() - 2, rw, frameWidth()+4 );
+ }
+}
+
+
+/*
+ Returns the maximum horizontal offset within the table of the
+ view's left edge in \e table coordinates.
+
+ This is used mainly to set the horizontal scroll bar's range.
+
+ \sa maxColOffset(), maxYOffset(), totalWidth()
+*/
+
+int TQtTableView::maxXOffset()
+{
+ int tw = totalWidth();
+ int maxOffs;
+ if ( testTableFlags(Tbl_scrollLastHCell) ) {
+ if ( nCols != 1)
+ maxOffs = tw - ( cellW ? cellW : cellWidth( nCols - 1 ) );
+ else
+ maxOffs = tw - viewWidth();
+ } else {
+ if ( testTableFlags(Tbl_snapToHGrid) ) {
+ if ( cellW ) {
+ maxOffs = tw - (viewWidth()/cellW)*cellW;
+ } else {
+ int goal = tw - viewWidth();
+ int pos = tw;
+ int nextCol = nCols - 1;
+ int nextCellWidth = cellWidth( nextCol );
+ while( nextCol > 0 && pos > goal + nextCellWidth ) {
+ pos -= nextCellWidth;
+ nextCellWidth = cellWidth( --nextCol );
+ }
+ if ( goal + nextCellWidth == pos )
+ maxOffs = goal;
+ else if ( goal < pos )
+ maxOffs = pos;
+ else
+ maxOffs = 0;
+ }
+ } else {
+ maxOffs = tw - viewWidth();
+ }
+ }
+ return maxOffs > 0 ? maxOffs : 0;
+}
+
+
+/*
+ Returns the maximum vertical offset within the table of the
+ view's top edge in \e table coordinates.
+
+ This is used mainly to set the vertical scroll bar's range.
+
+ \sa maxRowOffset(), maxXOffset(), totalHeight()
+*/
+
+int TQtTableView::maxYOffset()
+{
+ int th = totalHeight();
+ int maxOffs;
+ if ( testTableFlags(Tbl_scrollLastVCell) ) {
+ if ( nRows != 1)
+ maxOffs = th - ( cellH ? cellH : cellHeight( nRows - 1 ) );
+ else
+ maxOffs = th - viewHeight();
+ } else {
+ if ( testTableFlags(Tbl_snapToVGrid) ) {
+ if ( cellH ) {
+ maxOffs = th - (viewHeight()/cellH)*cellH;
+ } else {
+ int goal = th - viewHeight();
+ int pos = th;
+ int nextRow = nRows - 1;
+ int nextCellHeight = cellHeight( nextRow );
+ while( nextRow > 0 && pos > goal + nextCellHeight ) {
+ pos -= nextCellHeight;
+ nextCellHeight = cellHeight( --nextRow );
+ }
+ if ( goal + nextCellHeight == pos )
+ maxOffs = goal;
+ else if ( goal < pos )
+ maxOffs = pos;
+ else
+ maxOffs = 0;
+ }
+ } else {
+ maxOffs = th - viewHeight();
+ }
+ }
+ return maxOffs > 0 ? maxOffs : 0;
+}
+
+
+/*
+ Returns the index of the last column, which may be at the left edge
+ of the view.
+
+ Depending on the \link setTableFlags() Tbl_scrollLastHCell\endlink flag,
+ this may or may not be the last column.
+
+ \sa maxXOffset(), maxRowOffset()
+*/
+
+int TQtTableView::maxColOffset()
+{
+ int mx = maxXOffset();
+ if ( cellW )
+ return mx/cellW;
+ else {
+ int xcd=0, col=0;
+ while ( col < nCols && mx > (xcd=cellWidth(col)) ) {
+ mx -= xcd;
+ col++;
+ }
+ return col;
+ }
+}
+
+
+/*
+ Returns the index of the last row, which may be at the top edge of
+ the view.
+
+ Depending on the \link setTableFlags() Tbl_scrollLastVCell\endlink flag,
+ this may or may not be the last row.
+
+ \sa maxYOffset(), maxColOffset()
+*/
+
+int TQtTableView::maxRowOffset()
+{
+ int my = maxYOffset();
+ if ( cellH )
+ return my/cellH;
+ else {
+ int ycd=0, row=0;
+ while ( row < nRows && my > (ycd=cellHeight(row)) ) {
+ my -= ycd;
+ row++;
+ }
+ return row;
+ }
+}
+
+
+void TQtTableView::showOrHideScrollBars()
+{
+ if ( !autoUpdate() )
+ return;
+ if ( vScrollBar ) {
+ if ( testTableFlags(Tbl_vScrollBar) ) {
+ if ( !vScrollBar->isVisible() )
+ sbDirty = sbDirty | verMask;
+ } else {
+ if ( vScrollBar->isVisible() )
+ vScrollBar->hide();
+ }
+ }
+ if ( hScrollBar ) {
+ if ( testTableFlags(Tbl_hScrollBar) ) {
+ if ( !hScrollBar->isVisible() )
+ sbDirty = sbDirty | horMask;
+ } else {
+ if ( hScrollBar->isVisible() )
+ hScrollBar->hide();
+ }
+ }
+ if ( cornerSquare ) {
+ if ( testTableFlags(Tbl_hScrollBar) &&
+ testTableFlags(Tbl_vScrollBar) ) {
+ if ( !cornerSquare->isVisible() )
+ cornerSquare->show();
+ } else {
+ if ( cornerSquare->isVisible() )
+ cornerSquare->hide();
+ }
+ }
+}
+
+
+/*
+ Updates the scroll bars and internal state.
+
+ Call this function when the table view's total size is changed;
+ typically because the result of cellHeight() or cellWidth() have changed.
+
+ This function does not tqrepaint the widget.
+*/
+
+void TQtTableView::updateTableSize()
+{
+ bool updateOn = autoUpdate();
+ setAutoUpdate( FALSE );
+ int xofs = xOffset();
+ xOffs++; //so that setOffset will not return immediately
+ setOffset(xofs,yOffset(),FALSE); //to calculate internal state correctly
+ setAutoUpdate(updateOn);
+
+ updateScrollBars( horSteps | horRange |
+ verSteps | verRange );
+ showOrHideScrollBars();
+}
+
+
+#endif
diff --git a/tqtinterface/qt4/src/attic/qttableview.h b/tqtinterface/qt4/src/attic/qttableview.h
new file mode 100644
index 0000000..5ba8a17
--- /dev/null
+++ b/tqtinterface/qt4/src/attic/qttableview.h
@@ -0,0 +1,250 @@
+/**********************************************************************
+**
+** Definition of TQtTableView class
+**
+** Created : 941115
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file tqcontains a class moved out of the TQt GUI Toolkit API. It
+** may be used, distributed and modified without limitation.
+**
+**********************************************************************/
+
+#ifndef TQTTABLEVIEW_H
+#define TQTTABLEVIEW_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TQTTABLEVIEW
+
+class TQScrollBar;
+class TQCornerSquare;
+
+
+class TQtTableView : public TQFrame
+{
+ TQ_OBJECT
+public:
+ virtual void setBackgroundColor( const TQColor & );
+ virtual void setPalette( const TQPalette & );
+ void show();
+
+ void tqrepaint( bool erase=TRUE );
+ void tqrepaint( int x, int y, int w, int h, bool erase=TRUE );
+ void tqrepaint( const TQRect &, bool erase=TRUE );
+
+protected:
+ TQtTableView( TQWidget *tqparent=0, const char *name=0, WFlags f=0 );
+ ~TQtTableView();
+
+ int numRows() const;
+ virtual void setNumRows( int );
+ int numCols() const;
+ virtual void setNumCols( int );
+
+ int topCell() const;
+ virtual void setTopCell( int row );
+ int leftCell() const;
+ virtual void setLeftCell( int col );
+ virtual void setTopLeftCell( int row, int col );
+
+ int xOffset() const;
+ virtual void setXOffset( int );
+ int yOffset() const;
+ virtual void setYOffset( int );
+ virtual void setOffset( int x, int y, bool updateScrBars = TRUE );
+
+ virtual int cellWidth( int col );
+ virtual int cellHeight( int row );
+ int cellWidth() const;
+ int cellHeight() const;
+ virtual void setCellWidth( int );
+ virtual void setCellHeight( int );
+
+ virtual int totalWidth();
+ virtual int totalHeight();
+
+ uint tableFlags() const;
+ bool testTableFlags( uint f ) const;
+ virtual void setTableFlags( uint f );
+ void clearTableFlags( uint f = ~0 );
+
+ bool autoUpdate() const;
+ virtual void setAutoUpdate( bool );
+
+ void updateCell( int row, int column, bool erase=TRUE );
+
+ TQRect cellUpdateRect() const;
+ TQRect viewRect() const;
+
+ int lastRowVisible() const;
+ int lastColVisible() const;
+
+ bool rowIsVisible( int row ) const;
+ bool colIsVisible( int col ) const;
+
+ TQScrollBar *verticalScrollBar() const;
+ TQScrollBar *horizontalScrollBar() const;
+
+private Q_SLOTS:
+ void horSbValue( int );
+ void horSbSliding( int );
+ void horSbSlidingDone();
+ void verSbValue( int );
+ void verSbSliding( int );
+ void verSbSlidingDone();
+
+protected:
+ virtual void paintCell( TQPainter *, int row, int col ) = 0;
+ virtual void setupPainter( TQPainter * );
+
+ void paintEvent( TQPaintEvent * );
+ void resizeEvent( TQResizeEvent * );
+
+ int tqfindRow( int yPos ) const;
+ int tqfindCol( int xPos ) const;
+
+ bool rowYPos( int row, int *yPos ) const;
+ bool colXPos( int col, int *xPos ) const;
+
+ int maxXOffset();
+ int maxYOffset();
+ int maxColOffset();
+ int maxRowOffset();
+
+ int minViewX() const;
+ int minViewY() const;
+ int maxViewX() const;
+ int maxViewY() const;
+ int viewWidth() const;
+ int viewHeight() const;
+
+ void scroll( int xPixels, int yPixels );
+ void updateScrollBars();
+ void updateTableSize();
+
+private:
+ void coverCornerSquare( bool );
+ void snapToGrid( bool horizontal, bool vertical );
+ virtual void setHorScrollBar( bool on, bool update = TRUE );
+ virtual void setVerScrollBar( bool on, bool update = TRUE );
+ void updateView();
+ int tqfindRawRow( int yPos, int *cellMaxY, int *cellMinY = 0,
+ bool goOutsideView = FALSE ) const;
+ int tqfindRawCol( int xPos, int *cellMaxX, int *cellMinX = 0,
+ bool goOutsideView = FALSE ) const;
+ int maxColsVisible() const;
+
+ void updateScrollBars( uint );
+ void updateFrameSize();
+
+ void doAutoScrollBars();
+ void showOrHideScrollBars();
+
+ int nRows;
+ int nCols;
+ int xOffs, yOffs;
+ int xCellOffs, yCellOffs;
+ short xCellDelta, yCellDelta;
+ short cellH, cellW;
+
+ uint eraseInPaint : 1;
+ uint verSliding : 1;
+ uint verSnappingOff : 1;
+ uint horSliding : 1;
+ uint horSnappingOff : 1;
+ uint coveringCornerSquare : 1;
+ uint sbDirty : 8;
+ uint inSbUpdate : 1;
+
+ uint tFlags;
+ TQRect cellUpdateR;
+
+ TQScrollBar *vScrollBar;
+ TQScrollBar *hScrollBar;
+ TQCornerSquare *cornerSquare;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQtTableView( const TQtTableView & );
+ TQtTableView &operator=( const TQtTableView & );
+#endif
+};
+
+
+const uint Tbl_vScrollBar = 0x00000001;
+const uint Tbl_hScrollBar = 0x00000002;
+const uint Tbl_autoVScrollBar = 0x00000004;
+const uint Tbl_autoHScrollBar = 0x00000008;
+const uint Tbl_autoScrollBars = 0x0000000C;
+
+const uint Tbl_clipCellPainting = 0x00000100;
+const uint Tbl_cutCellsV = 0x00000200;
+const uint Tbl_cutCellsH = 0x00000400;
+const uint Tbl_cutCells = 0x00000600;
+
+const uint Tbl_scrollLastHCell = 0x00000800;
+const uint Tbl_scrollLastVCell = 0x00001000;
+const uint Tbl_scrollLastCell = 0x00001800;
+
+const uint Tbl_smoothHScrolling = 0x00002000;
+const uint Tbl_smoothVScrolling = 0x00004000;
+const uint Tbl_smoothScrolling = 0x00006000;
+
+const uint Tbl_snapToHGrid = 0x00008000;
+const uint Tbl_snapToVGrid = 0x00010000;
+const uint Tbl_snapToGrid = 0x00018000;
+
+
+inline int TQtTableView::numRows() const
+{ return nRows; }
+
+inline int TQtTableView::numCols() const
+{ return nCols; }
+
+inline int TQtTableView::topCell() const
+{ return yCellOffs; }
+
+inline int TQtTableView::leftCell() const
+{ return xCellOffs; }
+
+inline int TQtTableView::xOffset() const
+{ return xOffs; }
+
+inline int TQtTableView::yOffset() const
+{ return yOffs; }
+
+inline int TQtTableView::cellHeight() const
+{ return cellH; }
+
+inline int TQtTableView::cellWidth() const
+{ return cellW; }
+
+inline uint TQtTableView::tableFlags() const
+{ return tFlags; }
+
+inline bool TQtTableView::testTableFlags( uint f ) const
+{ return (tFlags & f) != 0; }
+
+inline TQRect TQtTableView::cellUpdateRect() const
+{ return cellUpdateR; }
+
+inline bool TQtTableView::autoUpdate() const
+{ return isUpdatesEnabled(); }
+
+inline void TQtTableView::tqrepaint( bool erase )
+{ tqrepaint( 0, 0, width(), height(), erase ); }
+
+inline void TQtTableView::tqrepaint( const TQRect &r, bool erase )
+{ tqrepaint( r.x(), r.y(), r.width(), r.height(), erase ); }
+
+inline void TQtTableView::updateScrollBars()
+{ updateScrollBars( 0 ); }
+
+
+#endif // TQT_NO_TQTTABLEVIEW
+
+#endif // TQTTABLEVIEW_H
diff --git a/tqtinterface/qt4/src/canvas/qt_canvas.pri b/tqtinterface/qt4/src/canvas/qt_canvas.pri
new file mode 100644
index 0000000..d875b58
--- /dev/null
+++ b/tqtinterface/qt4/src/canvas/qt_canvas.pri
@@ -0,0 +1,6 @@
+# Qt canvas module
+
+canvas {
+ HEADERS += $$CANVAS_H/tqcanvas.h
+ SOURCES += $$CANVAS_CPP/tqcanvas.cpp
+}
diff --git a/tqtinterface/qt4/src/canvas/tqcanvas.cpp b/tqtinterface/qt4/src/canvas/tqcanvas.cpp
new file mode 100644
index 0000000..22ee9f4
--- /dev/null
+++ b/tqtinterface/qt4/src/canvas/tqcanvas.cpp
@@ -0,0 +1,5415 @@
+/**********************************************************************
+**
+** Implementation of TQCanvas and associated classes
+**
+** Created : 991211
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the canvas module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcanvas.h"
+#ifndef TQT_NO_CANVAS
+#include "tqapplication.h"
+#include "tqbitmap.h"
+#include "tqimage.h"
+#include "tqptrdict.h"
+#include "tqpainter.h"
+#include "tqpolygonscanner.h"
+#include "tqtimer.h"
+#include "tqtl.h"
+
+#include <stdlib.h>
+
+class TQCanvasData {
+public:
+ TQCanvasData() :
+ itemDict(1013), animDict(503)
+ {
+ }
+
+ TQPtrList<TQCanvasView> viewList;
+ TQPtrDict<void> itemDict;
+ TQPtrDict<void> animDict;
+};
+
+class TQCanvasViewData {
+public:
+ TQCanvasViewData() : repaint_from_moving( FALSE ) {}
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix xform;
+ TQWMatrix ixform;
+#endif
+ bool repaint_from_moving;
+};
+
+// clusterizer
+
+class TQCanvasClusterizer {
+public:
+ TQCanvasClusterizer(int maxclusters);
+ ~TQCanvasClusterizer();
+
+ void add(int x, int y); // 1x1 rectangle (point)
+ void add(int x, int y, int w, int h);
+ void add(const TQRect& rect);
+
+ void clear();
+ int clusters() { return count; }
+ const TQRect& operator[](int i);
+
+private:
+ TQRect* cluster;
+ int count;
+ const int maxcl;
+};
+
+static
+void include(TQRect& r, const TQRect& rect)
+{
+ if (rect.left()<r.left()) {
+ r.setLeft(rect.left());
+ }
+ if (rect.right()>r.right()) {
+ r.setRight(rect.right());
+ }
+ if (rect.top()<r.top()) {
+ r.setTop(rect.top());
+ }
+ if (rect.bottom()>r.bottom()) {
+ r.setBottom(rect.bottom());
+ }
+}
+
+/*
+A TQCanvasClusterizer groups rectangles (TQRects) into non-overlapping rectangles
+by a merging heuristic.
+*/
+TQCanvasClusterizer::TQCanvasClusterizer(int maxclusters) :
+ cluster(new TQRect[maxclusters]),
+ count(0),
+ maxcl(maxclusters)
+{ }
+
+TQCanvasClusterizer::~TQCanvasClusterizer()
+{
+ delete [] cluster;
+}
+
+void TQCanvasClusterizer::clear()
+{
+ count=0;
+}
+
+void TQCanvasClusterizer::add(int x, int y)
+{
+ add(TQRect(x,y,1,1));
+}
+
+void TQCanvasClusterizer::add(int x, int y, int w, int h)
+{
+ add(TQRect(x,y,w,h));
+}
+
+void TQCanvasClusterizer::add(const TQRect& rect)
+{
+ TQRect biggerrect(rect.x()-1,rect.y()-1,rect.width()+2,rect.height()+2);
+
+ //assert(rect.width()>0 && rect.height()>0);
+
+ int cursor;
+
+ for (cursor=0; cursor<count; cursor++) {
+ if (cluster[cursor].tqcontains(rect)) {
+ // Wholly contained already.
+ return;
+ }
+ }
+
+ int lowestcost=9999999;
+ int cheapest=-1;
+ cursor = 0;
+ while( cursor<count ) {
+ if (cluster[cursor].intersects(biggerrect)) {
+ TQRect larger=cluster[cursor];
+ include(larger,rect);
+ int cost = larger.width()*larger.height() -
+ cluster[cursor].width()*cluster[cursor].height();
+
+ if (cost < lowestcost) {
+ bool bad=FALSE;
+ for (int c=0; c<count && !bad; c++) {
+ bad=cluster[c].intersects(larger) && c!=cursor;
+ }
+ if (!bad) {
+ cheapest=cursor;
+ lowestcost=cost;
+ }
+ }
+ }
+ cursor++;
+ }
+
+ if (cheapest>=0) {
+ include(cluster[cheapest],rect);
+ return;
+ }
+
+ if (count < maxcl) {
+ cluster[count++]=rect;
+ return;
+ }
+
+ // Do cheapest of:
+ // add to closest cluster
+ // do cheapest cluster merge, add to new cluster
+
+ lowestcost=9999999;
+ cheapest=-1;
+ cursor=0;
+ while( cursor<count ) {
+ TQRect larger=cluster[cursor];
+ include(larger,rect);
+ int cost=larger.width()*larger.height()
+ - cluster[cursor].width()*cluster[cursor].height();
+ if (cost < lowestcost) {
+ bool bad=FALSE;
+ for (int c=0; c<count && !bad; c++) {
+ bad=cluster[c].intersects(larger) && c!=cursor;
+ }
+ if (!bad) {
+ cheapest=cursor;
+ lowestcost=cost;
+ }
+ }
+ cursor++;
+ }
+
+ // ###
+ // could make an heuristic guess as to whether we need to bother
+ // looking for a cheap merge.
+
+ int cheapestmerge1 = -1;
+ int cheapestmerge2 = -1;
+
+ int merge1 = 0;
+ while( merge1 < count ) {
+ int merge2=0;
+ while( merge2 < count ) {
+ if( merge1!=merge2) {
+ TQRect larger=cluster[merge1];
+ include(larger,cluster[merge2]);
+ int cost=larger.width()*larger.height()
+ - cluster[merge1].width()*cluster[merge1].height()
+ - cluster[merge2].width()*cluster[merge2].height();
+ if (cost < lowestcost) {
+ bool bad=FALSE;
+ for (int c=0; c<count && !bad; c++) {
+ bad=cluster[c].intersects(larger) && c!=cursor;
+ }
+ if (!bad) {
+ cheapestmerge1=merge1;
+ cheapestmerge2=merge2;
+ lowestcost=cost;
+ }
+ }
+ }
+ merge2++;
+ }
+ merge1++;
+ }
+
+ if (cheapestmerge1>=0) {
+ include(cluster[cheapestmerge1],cluster[cheapestmerge2]);
+ cluster[cheapestmerge2]=cluster[count--];
+ } else {
+ // if (!cheapest) debugRectangles(rect);
+ include(cluster[cheapest],rect);
+ }
+
+ // NB: clusters do not intersect (or intersection will
+ // overwrite). This is a result of the above algorithm,
+ // given the assumption that (x,y) are ordered topleft
+ // to bottomright.
+
+ // ###
+ //
+ // add explicit x/y ordering to that comment, move it to the top
+ // and rephrase it as pre-/post-conditions.
+}
+
+const TQRect& TQCanvasClusterizer::operator[](int i)
+{
+ return cluster[i];
+}
+
+// end of clusterizer
+
+
+
+class TQM_EXPORT_CANVAS TQCanvasItemPtr {
+public:
+ TQCanvasItemPtr() : ptr(0) { }
+ TQCanvasItemPtr( TQCanvasItem* p ) : ptr(p) { }
+
+ bool operator<=(const TQCanvasItemPtr& that) const
+ {
+ // Order same-z objects by identity.
+ if (that.ptr->z()==ptr->z())
+ return that.ptr <= ptr;
+ return that.ptr->z() <= ptr->z();
+ }
+ bool operator<(const TQCanvasItemPtr& that) const
+ {
+ // Order same-z objects by identity.
+ if (that.ptr->z()==ptr->z())
+ return that.ptr < ptr;
+ return that.ptr->z() < ptr->z();
+ }
+ bool operator>(const TQCanvasItemPtr& that) const
+ {
+ // Order same-z objects by identity.
+ if (that.ptr->z()==ptr->z())
+ return that.ptr > ptr;
+ return that.ptr->z() > ptr->z();
+ }
+ bool operator==(const TQCanvasItemPtr& that) const
+ {
+ return that.ptr == ptr;
+ }
+ operator TQCanvasItem*() const { return ptr; }
+
+private:
+ TQCanvasItem* ptr;
+};
+
+
+/*!
+ \class TQCanvasItemList
+ \brief The TQCanvasItemList class is a list of TQCanvasItems.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ TQCanvasItemList is a TQValueList of pointers to \l{TQCanvasItem}s.
+ This class is used by some methods in TQCanvas that need to return
+ a list of canvas items.
+
+ The \l TQValueList documentation describes how to use this list.
+*/
+
+/*!
+ \internal
+*/
+void TQCanvasItemList::sort()
+{
+ qHeapSort(*((TQValueList<TQCanvasItemPtr>*)this));
+}
+
+/*!
+ \internal
+*/
+void TQCanvasItemList::drawUnique( TQPainter& painter )
+{
+ TQCanvasItem* prev=0;
+ for (Iterator it=fromLast(); it!=end(); --it) {
+ TQCanvasItem *g=*it;
+ if (g!=prev) {
+ g->draw(painter);
+ prev=g;
+ }
+ }
+}
+
+/*!
+ Returns the concatenation of this list and list \a l.
+*/
+TQCanvasItemList TQCanvasItemList::operator+(const TQCanvasItemList &l) const
+{
+ TQCanvasItemList l2(*this);
+ for(const_iterator it = l.begin(); it != l.end(); ++it)
+ l2.append(*it);
+ return l2;
+}
+
+class TQCanvasChunk {
+public:
+ TQCanvasChunk() : changed(TRUE) { }
+ // Other code assumes lists are not deleted. Assignment is also
+ // done on ChunkRecs. So don't add that sort of thing here.
+
+ void sort()
+ {
+ list.sort();
+ }
+
+ const TQCanvasItemList* listPtr() const
+ {
+ return &list;
+ }
+
+ void add(TQCanvasItem* item)
+ {
+ list.prepend(item);
+ changed = TRUE;
+ }
+
+ void remove(TQCanvasItem* item)
+ {
+ list.remove(item);
+ changed = TRUE;
+ }
+
+ void change()
+ {
+ changed = TRUE;
+ }
+
+ bool hasChanged() const
+ {
+ return changed;
+ }
+
+ bool takeChange()
+ {
+ bool y = changed;
+ changed = FALSE;
+ return y;
+ }
+
+private:
+ TQCanvasItemList list;
+ bool changed;
+};
+
+
+static int gcd(int a, int b)
+{
+ int r;
+ while ( (r = a%b) ) {
+ a=b;
+ b=r;
+ }
+ return b;
+}
+
+static int scm(int a, int b)
+{
+ int g = gcd(a,b);
+ return a/g*b;
+}
+
+
+
+/*!
+ \class TQCanvas tqcanvas.h
+ \brief The TQCanvas class provides a 2D area that can contain TQCanvasItem objects.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup abstractwidgets
+ \ingroup graphics
+ \ingroup images
+ \mainclass
+ \module canvas
+
+ The TQCanvas class manages its 2D graphic area and all the canvas
+ items the area tqcontains. The canvas has no visual appearance of
+ its own. Instead, it is displayed on screen using a TQCanvasView.
+ Multiple TQCanvasView widgets may be associated with a canvas to
+ provide multiple views of the same canvas.
+
+ The canvas is optimized for large numbers of items, particularly
+ where only a small percentage of the items change at any
+ one time. If the entire display changes very frequently, you should
+ consider using your own custom TQScrollView subclass.
+
+ TQt provides a rich
+ set of canvas item classes, e.g. TQCanvasEllipse, TQCanvasLine,
+ TQCanvasPolygon, TQCanvasPolygonalItem, TQCanvasRectangle, TQCanvasSpline,
+ TQCanvasSprite and TQCanvasText. You can subclass to create your own
+ canvas items; TQCanvasPolygonalItem is the most common base class used
+ for this purpose.
+
+ Items appear on the canvas after their \link TQCanvasItem::show()
+ show()\endlink function has been called (or \link
+ TQCanvasItem::tqsetVisible() tqsetVisible(TRUE)\endlink), and \e after
+ update() has been called. The canvas only shows items that are
+ \link TQCanvasItem::tqsetVisible() visible\endlink, and then only if
+ \l update() is called. (By default the canvas is white and so are
+ canvas items, so if nothing appears try changing colors.)
+
+ If you created the canvas without passing a width and height to
+ the constructor you must also call resize().
+
+ Although a canvas may appear to be similar to a widget with child
+ widgets, there are several notable differences:
+
+ \list
+ \i Canvas items are usually much faster to manipulate and redraw than
+ child widgets, with the speed advantage becoming especially great when
+ there are \e many canvas items and non-rectangular items. In most
+ situations canvas items are also a lot more memory efficient than child
+ widgets.
+
+ \i It's easy to detect overlapping items (collision detection).
+
+ \i The canvas can be larger than a widget. A million-by-million canvas
+ is perfectly possible. At such a size a widget might be very
+ inefficient, and some window systems might not support it at all,
+ whereas TQCanvas scales well. Even with a billion pixels and a million
+ items, tqfinding a particular canvas item, detecting collisions, etc.,
+ is still fast (though the memory consumption may be prohibitive
+ at such extremes).
+
+ \i Two or more TQCanvasView objects can view the same canvas.
+
+ \i An arbitrary transformation matrix can be set on each TQCanvasView
+ which makes it easy to zoom, rotate or shear the viewed canvas.
+
+ \i Widgets provide a lot more functionality, such as input (TQKeyEvent,
+ TQMouseEvent etc.) and tqlayout management (TQGridLayout etc.).
+
+ \endlist
+
+ A canvas consists of a background, a number of canvas items organized by
+ x, y and z coordinates, and a foreground. A canvas item's z coordinate
+ can be treated as a layer number -- canvas items with a higher z
+ coordinate appear in front of canvas items with a lower z coordinate.
+
+ The background is white by default, but can be set to a different color
+ using setBackgroundColor(), or to a repeated pixmap using
+ setBackgroundPixmap() or to a mosaic of smaller pixmaps using
+ setTiles(). Individual tiles can be set with setTile(). There
+ are corresponding get functions, e.g. backgroundColor() and
+ backgroundPixmap().
+
+ Note that TQCanvas does not inherit from TQWidget, even though it has some
+ functions which provide the same functionality as those in TQWidget. One
+ of these is setBackgroundPixmap(); some others are resize(), size(),
+ width() and height(). \l TQCanvasView is the widget used to display a
+ canvas on the screen.
+
+ Canvas items are added to a canvas by constructing them and passing the
+ canvas to the canvas item's constructor. An item can be moved to a
+ different canvas using TQCanvasItem::setCanvas().
+
+ Canvas items are movable (and in the case of TQCanvasSprites, animated)
+ objects that inherit TQCanvasItem. Each canvas item has a position on the
+ canvas (x, y coordinates) and a height (z coordinate), all of which are
+ held as floating-point numbers. Moving canvas items also have x and y
+ velocities. It's possible for a canvas item to be outside the canvas
+ (for example TQCanvasItem::x() is greater than width()). When a canvas
+ item is off the canvas, onCanvas() returns FALSE and the canvas
+ disregards the item. (Canvas items off the canvas do not slow down any
+ of the common operations on the canvas.)
+
+ Canvas items can be moved with TQCanvasItem::move(). The advance()
+ function moves all TQCanvasItem::animated() canvas items and
+ setAdvancePeriod() makes TQCanvas move them automatically on a periodic
+ basis. In the context of the TQCanvas classes, to `animate' a canvas item
+ is to set it in motion, i.e. using TQCanvasItem::setVelocity(). Animation
+ of a canvas item itself, i.e. items which change over time, is enabled
+ by calling TQCanvasSprite::setFrameAnimation(), or more generally by
+ subclassing and reimplementing TQCanvasItem::advance(). To detect collisions
+ use one of the TQCanvasItem::collisions() functions.
+
+ The changed parts of the canvas are redrawn (if they are visible in a
+ canvas view) whenever update() is called. You can either call update()
+ manually after having changed the contents of the canvas, or force
+ periodic updates using setUpdatePeriod(). If you have moving objects on
+ the canvas, you must call advance() every time the objects should
+ move one step further. Periodic calls to advance() can be forced using
+ setAdvancePeriod(). The advance() function will call
+ TQCanvasItem::advance() on every item that is \link
+ TQCanvasItem::animated() animated\endlink and trigger an update of the
+ affected areas afterwards. (A canvas item that is `animated' is simply
+ a canvas item that is in motion.)
+
+ TQCanvas organizes its canvas items into \e chunks; these are areas on
+ the canvas that are used to speed up most operations. Many operations
+ start by eliminating most chunks (i.e. those which haven't changed)
+ and then process only the canvas items that are in the few interesting
+ (i.e. changed) chunks. A valid chunk, validChunk(), is one which is on
+ the canvas.
+
+ The chunk size is a key factor to TQCanvas's speed: if there are too many
+ chunks, the speed benefit of grouping canvas items into chunks is
+ reduced. If the chunks are too large, it takes too long to process each
+ one. The TQCanvas constructor tries to pick a suitable size, but you
+ can call retune() to change it at any time. The chunkSize() function
+ returns the current chunk size. The canvas items always make sure
+ they're in the right chunks; all you need to make sure of is that
+ the canvas uses the right chunk size. A good rule of thumb is that
+ the size should be a bit smaller than the average canvas item
+ size. If you have moving objects, the chunk size should be a bit
+ smaller than the average size of the moving items.
+
+ The foreground is normally nothing, but if you reimplement
+ drawForeground(), you can draw things in front of all the canvas
+ items.
+
+ Areas can be set as changed with setChanged() and set unchanged with
+ setUnchanged(). The entire canvas can be set as changed with
+ setAllChanged(). A list of all the items on the canvas is returned by
+ allItems().
+
+ An area can be copied (painted) to a TQPainter with drawArea().
+
+ If the canvas is resized it emits the resized() signal.
+
+ The examples/canvas application and the 2D graphics page of the
+ examples/demo application demonstrate many of TQCanvas's facilities.
+
+ \sa TQCanvasView TQCanvasItem
+*/
+void TQCanvas::init(int w, int h, int chunksze, int mxclusters)
+{
+ d = new TQCanvasData;
+ awidth=w;
+ aheight=h;
+ chunksize=chunksze;
+ maxclusters=mxclusters;
+ chwidth=(w+chunksize-1)/chunksize;
+ chheight=(h+chunksize-1)/chunksize;
+ chunks=new TQCanvasChunk[chwidth*chheight];
+ update_timer = 0;
+ bgcolor = Qt::white;
+ grid = 0;
+ htiles = 0;
+ vtiles = 0;
+ dblbuf = TRUE;
+ debug_redraw_areas = FALSE;
+}
+
+/*!
+ Create a TQCanvas with no size. \a tqparent and \a name are passed to
+ the TQObject superclass.
+
+ \warning You \e must call resize() at some time after creation to
+ be able to use the canvas.
+*/
+TQCanvas::TQCanvas( TQObject* tqparent, const char* name )
+ : TQObject( tqparent, name )
+{
+ init(0,0);
+}
+
+/*!
+ Constructs a TQCanvas that is \a w pixels wide and \a h pixels high.
+*/
+TQCanvas::TQCanvas(int w, int h)
+{
+ init(w,h);
+}
+
+/*!
+ Constructs a TQCanvas which will be composed of \a h tiles
+ horizontally and \a v tiles vertically. Each tile will be an image
+ \a tilewidth by \a tileheight pixels taken from pixmap \a p.
+
+ The pixmap \a p is a list of tiles, arranged left to right, (and
+ in the case of pixmaps that have multiple rows of tiles, top to
+ bottom), with tile 0 in the top-left corner, tile 1 next to the
+ right, and so on, e.g.
+
+ \table
+ \row \i 0 \i 1 \i 2 \i 3
+ \row \i 4 \i 5 \i 6 \i 7
+ \endtable
+
+ The TQCanvas is initially sized to show exactly the given number of
+ tiles horizontally and vertically. If it is resized to be larger,
+ the entire matrix of tiles will be repeated as often as necessary
+ to cover the area. If it is smaller, tiles to the right and bottom
+ will not be visible.
+
+ \sa setTiles()
+*/
+TQCanvas::TQCanvas( TQPixmap p,
+ int h, int v, int tilewidth, int tileheight )
+{
+ init(h*tilewidth, v*tileheight, scm(tilewidth,tileheight) );
+ setTiles( p, h, v, tilewidth, tileheight );
+}
+
+void qt_unview(TQCanvas* c)
+{
+ for (TQCanvasView* view=c->d->viewList.first(); view != 0; view=c->d->viewList.next()) {
+ view->viewing = 0;
+ }
+}
+
+/*!
+ Destroys the canvas and all the canvas's canvas items.
+*/
+TQCanvas::~TQCanvas()
+{
+ qt_unview(this);
+ TQCanvasItemList all = allItems();
+ for (TQCanvasItemList::Iterator it=all.begin(); it!=all.end(); ++it)
+ delete *it;
+ delete [] chunks;
+ delete [] grid;
+ delete d;
+}
+
+/*!
+\internal
+Returns the chunk at a chunk position \a i, \a j.
+*/
+TQCanvasChunk& TQCanvas::chunk(int i, int j) const
+{
+ return chunks[i+chwidth*j];
+}
+
+/*!
+\internal
+Returns the chunk at a pixel position \a x, \a y.
+*/
+TQCanvasChunk& TQCanvas::chunkContaining(int x, int y) const
+{
+ return chunk(x/chunksize,y/chunksize);
+}
+
+/*!
+ Returns a list of all the items in the canvas.
+*/
+TQCanvasItemList TQCanvas::allItems()
+{
+ TQCanvasItemList list;
+ for (TQPtrDictIterator<void> it=d->itemDict; it.currentKey(); ++it) {
+ list.prepend((TQCanvasItem*)it.currentKey());
+ }
+ return list;
+}
+
+
+/*!
+ Changes the size of the canvas to have a width of \a w and a
+ height of \a h. This is a slow operation.
+*/
+void TQCanvas::resize(int w, int h)
+{
+ if (awidth==w && aheight==h)
+ return;
+
+ TQCanvasItem* item;
+ TQPtrList<TQCanvasItem> hidden;
+ for (TQPtrDictIterator<void> it=d->itemDict; it.currentKey(); ++it) {
+ if (((TQCanvasItem*)it.currentKey())->isVisible()) {
+ ((TQCanvasItem*)it.currentKey())->hide();
+ hidden.append(((TQCanvasItem*)it.currentKey()));
+ }
+ }
+
+ int nchwidth=(w+chunksize-1)/chunksize;
+ int nchheight=(h+chunksize-1)/chunksize;
+
+ TQCanvasChunk* newchunks = new TQCanvasChunk[nchwidth*nchheight];
+
+ // Commit the new values.
+ //
+ awidth=w;
+ aheight=h;
+ chwidth=nchwidth;
+ chheight=nchheight;
+ delete [] chunks;
+ chunks=newchunks;
+
+ for (item=hidden.first(); item != 0; item=hidden.next()) {
+ item->show();
+ }
+
+ setAllChanged();
+
+ emit resized();
+}
+
+/*!
+ \fn void TQCanvas::resized()
+
+ This signal is emitted whenever the canvas is resized. Each
+ TQCanvasView connects to this signal to keep the scrollview's size
+ correct.
+*/
+
+/*!
+ Change the efficiency tuning parameters to \a mxclusters clusters,
+ each of size \a chunksze. This is a slow operation if there are
+ many objects on the canvas.
+
+ The canvas is divided into chunks which are rectangular areas \a
+ chunksze wide by \a chunksze high. Use a chunk size which is about
+ the average size of the canvas items. If you choose a chunk size
+ which is too small it will increase the amount of calculation
+ required when drawing since each change will affect many chunks.
+ If you choose a chunk size which is too large the amount of
+ drawing required will increase because for each change, a lot of
+ drawing will be required since there will be many (unchanged)
+ canvas items which are in the same chunk as the changed canvas
+ items.
+
+ Internally, a canvas uses a low-resolution "chunk matrix" to keep
+ track of all the items in the canvas. A 64x64 chunk matrix is the
+ default for a 1024x1024 pixel canvas, where each chunk collects
+ canvas items in a 16x16 pixel square. This default is also
+ affected by setTiles(). You can tune this default using this
+ function. For example if you have a very large canvas and want to
+ trade off speed for memory then you might set the chunk size to 32
+ or 64.
+
+ The \a mxclusters argument is the number of rectangular groups of
+ chunks that will be separately drawn. If the canvas has a large
+ number of small, dispersed items, this should be about that
+ number. Our testing suggests that a large number of clusters is
+ almost always best.
+
+*/
+void TQCanvas::retune(int chunksze, int mxclusters)
+{
+ maxclusters=mxclusters;
+
+ if ( chunksize!=chunksze ) {
+ TQPtrList<TQCanvasItem> hidden;
+ for (TQPtrDictIterator<void> it=d->itemDict; it.currentKey(); ++it) {
+ if (((TQCanvasItem*)it.currentKey())->isVisible()) {
+ ((TQCanvasItem*)it.currentKey())->hide();
+ hidden.append(((TQCanvasItem*)it.currentKey()));
+ }
+ }
+
+ chunksize=chunksze;
+
+ int nchwidth=(awidth+chunksize-1)/chunksize;
+ int nchheight=(aheight+chunksize-1)/chunksize;
+
+ TQCanvasChunk* newchunks = new TQCanvasChunk[nchwidth*nchheight];
+
+ // Commit the new values.
+ //
+ chwidth=nchwidth;
+ chheight=nchheight;
+ delete [] chunks;
+ chunks=newchunks;
+
+ for (TQCanvasItem* item=hidden.first(); item != 0; item=hidden.next()) {
+ item->show();
+ }
+ }
+}
+
+/*!
+ \fn int TQCanvas::width() const
+
+ Returns the width of the canvas, in pixels.
+*/
+
+/*!
+ \fn int TQCanvas::height() const
+
+ Returns the height of the canvas, in pixels.
+*/
+
+/*!
+ \fn TQSize TQCanvas::size() const
+
+ Returns the size of the canvas, in pixels.
+*/
+
+/*!
+ \fn TQRect TQCanvas::rect() const
+
+ Returns a rectangle the size of the canvas.
+*/
+
+
+/*!
+ \fn bool TQCanvas::onCanvas( int x, int y ) const
+
+ Returns TRUE if the pixel position (\a x, \a y) is on the canvas;
+ otherwise returns FALSE.
+
+ \sa validChunk()
+*/
+
+/*!
+ \fn bool TQCanvas::onCanvas( const TQPoint& p ) const
+ \overload
+
+ Returns TRUE if the pixel position \a p is on the canvas;
+ otherwise returns FALSE.
+
+ \sa validChunk()
+*/
+
+/*!
+ \fn bool TQCanvas::validChunk( int x, int y ) const
+
+ Returns TRUE if the chunk position (\a x, \a y) is on the canvas;
+ otherwise returns FALSE.
+
+ \sa onCanvas()
+*/
+
+/*!
+ \fn bool TQCanvas::validChunk( const TQPoint& p ) const
+ \overload
+
+ Returns TRUE if the chunk position \a p is on the canvas; otherwise
+ returns FALSE.
+
+ \sa onCanvas()
+*/
+
+/*!
+ \fn int TQCanvas::chunkSize() const
+
+ Returns the chunk size of the canvas.
+
+ \sa retune()
+*/
+
+/*!
+\fn bool TQCanvas::sameChunk(int x1, int y1, int x2, int y2) const
+\internal
+Tells if the points ( \a x1, \a y1 ) and ( \a x2, \a y2 ) are within the same chunk.
+*/
+
+/*!
+\internal
+This method adds an the item \a item to the list of TQCanvasItem objects
+in the TQCanvas. The TQCanvasItem class calls this.
+*/
+void TQCanvas::addItem(TQCanvasItem* item)
+{
+ d->itemDict.insert((void*)item,(void*)1);
+}
+
+/*!
+\internal
+This method adds the item \a item to the list of TQCanvasItem objects
+to be moved. The TQCanvasItem class calls this.
+*/
+void TQCanvas::addAnimation(TQCanvasItem* item)
+{
+ d->animDict.insert((void*)item,(void*)1);
+}
+
+/*!
+\internal
+This method adds the item \a item to the list of TQCanvasItem objects
+which are no longer to be moved. The TQCanvasItem class calls this.
+*/
+void TQCanvas::removeAnimation(TQCanvasItem* item)
+{
+ d->animDict.remove((void*)item);
+}
+
+/*!
+\internal
+This method removes the item \a item from the list of TQCanvasItem objects
+in this TQCanvas. The TQCanvasItem class calls this.
+*/
+void TQCanvas::removeItem(TQCanvasItem* item)
+{
+ d->itemDict.remove((void*)item);
+}
+
+/*!
+\internal
+This method adds the view \a view to the list of TQCanvasView objects
+viewing this TQCanvas. The TQCanvasView class calls this.
+*/
+void TQCanvas::addView(TQCanvasView* view)
+{
+ d->viewList.append(view);
+ if ( htiles>1 || vtiles>1 || pm.isNull() )
+ view->viewport()->setBackgroundColor(backgroundColor());
+}
+
+/*!
+\internal
+This method removes the view \a view from the list of TQCanvasView objects
+viewing this TQCanvas. The TQCanvasView class calls this.
+*/
+void TQCanvas::removeView(TQCanvasView* view)
+{
+ d->viewList.removeRef(view);
+}
+
+/*!
+ Sets the canvas to call advance() every \a ms milliseconds. Any
+ previous setting by setAdvancePeriod() or setUpdatePeriod() is
+ overridden.
+
+ If \a ms is less than 0 advancing will be stopped.
+*/
+void TQCanvas::setAdvancePeriod(int ms)
+{
+ if ( ms<0 ) {
+ if ( update_timer )
+ update_timer->stop();
+ } else {
+ if ( update_timer )
+ delete update_timer;
+ update_timer = new TQTimer(this);
+ connect(update_timer,TQT_SIGNAL(timeout()),this,TQT_SLOT(advance()));
+ update_timer->start(ms);
+ }
+}
+
+/*!
+ Sets the canvas to call update() every \a ms milliseconds. Any
+ previous setting by setAdvancePeriod() or setUpdatePeriod() is
+ overridden.
+
+ If \a ms is less than 0 automatic updating will be stopped.
+*/
+void TQCanvas::setUpdatePeriod(int ms)
+{
+ if ( ms<0 ) {
+ if ( update_timer )
+ update_timer->stop();
+ } else {
+ if ( update_timer )
+ delete update_timer;
+ update_timer = new TQTimer(this);
+ connect(update_timer,TQT_SIGNAL(timeout()),this,TQT_SLOT(update()));
+ update_timer->start(ms);
+ }
+}
+
+/*!
+ Moves all TQCanvasItem::animated() canvas items on the canvas and
+ refreshes all changes to all views of the canvas. (An `animated'
+ item is an item that is in motion; see setVelocity().)
+
+ The advance takes place in two phases. In phase 0, the
+ TQCanvasItem::advance() function of each TQCanvasItem::animated()
+ canvas item is called with paramater 0. Then all these canvas
+ items are called again, with parameter 1. In phase 0, the canvas
+ items should not change position, merely examine other items on
+ the canvas for which special processing is required, such as
+ collisions between items. In phase 1, all canvas items should
+ change positions, ignoring any other items on the canvas. This
+ two-phase approach allows for considerations of "fairness",
+ although no TQCanvasItem subclasses supplied with TQt do anything
+ interesting in phase 0.
+
+ The canvas can be configured to call this function periodically
+ with setAdvancePeriod().
+
+ \sa update()
+*/
+void TQCanvas::advance()
+{
+ TQPtrDictIterator<void> it=d->animDict;
+ while ( it.current() ) {
+ TQCanvasItem* i = (TQCanvasItem*)(void*)it.currentKey();
+ ++it;
+ if ( i )
+ i->advance(0);
+ }
+ // we expect the dict tqcontains the exact same items as in the
+ // first pass.
+ it.toFirst();
+ while ( it.current() ) {
+ TQCanvasItem* i = (TQCanvasItem*)(void*)it.currentKey();
+ ++it;
+ if ( i )
+ i->advance(1);
+ }
+ update();
+}
+
+// Don't call this unless you know what you're doing.
+// p is in the content's co-ordinate example.
+/*!
+ \internal
+*/
+void TQCanvas::drawViewArea( TQCanvasView* view, TQPainter* p, const TQRect& vr, bool dbuf )
+{
+ TQPoint tl = view->contentsToViewport(TQPoint(0,0));
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix wm = view->tqworldMatrix();
+ TQWMatrix iwm = wm.invert();
+ // ivr = covers all chunks in vr
+ TQRect ivr = iwm.map(vr);
+ ivr.addCoords(-1, -1, 1, 1);
+ TQWMatrix twm;
+ twm.translate(tl.x(),tl.y());
+#else
+ TQRect ivr = vr;
+#endif
+
+ TQRect all(0,0,width(),height());
+
+ if ( !all.tqcontains(ivr) ) {
+ // Need to clip with edge of canvas.
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ // For translation-only transformation, it is safe to include the right
+ // and bottom edges, but otherwise, these must be excluded since they
+ // are not precisely defined (different bresenham paths).
+ TQPointArray a;
+ if ( wm.m12()==0.0 && wm.m21()==0.0 && wm.m11() == 1.0 && wm.m22() == 1.0 )
+ a = TQPointArray( TQRect(all.x(),all.y(),all.width()+1,all.height()+1) );
+ else
+ a = TQPointArray( all );
+
+ a = (wm*twm).map(a);
+#else
+ TQPointArray a( TQRect(all.x(),all.y(),all.width()+1,all.height()+1) );
+#endif
+ if ( view->viewport()->backgroundMode() == TQt::NoBackground ) {
+ TQRect cvr = vr; cvr.moveBy(tl.x(),tl.y());
+ p->setClipRegion(TQRegion(cvr)-TQRegion(a));
+ p->fillRect(vr,view->viewport()->palette()
+ .brush(TQPalette::Active,TQColorGroup::Background));
+ }
+ p->setClipRegion(a);
+ }
+
+ if ( dbuf ) {
+ offscr = TQPixmap(vr.size().expandedTo(TQSize(1, 1)));
+#ifdef TQ_WS_X11
+ offscr.x11SetScreen(p->tqdevice()->x11Screen());
+#endif
+ TQPainter dbp(&offscr);
+#ifndef TQT_NO_TRANSFORMATIONS
+ twm.translate(-vr.x(),-vr.y());
+ twm.translate(-tl.x(),-tl.y());
+ dbp.setWorldMatrix( wm*twm, TRUE );
+#else
+ dbp.translate(-vr.x()-tl.x(),-vr.y()-tl.y());
+#endif
+ dbp.setClipRect(0,0,vr.width(), vr.height());
+ drawCanvasArea(ivr,&dbp,FALSE);
+ dbp.end();
+ p->drawPixmap(vr.x(), vr.y(), offscr, 0, 0, vr.width(), vr.height());
+ } else {
+ TQRect r = vr; r.moveBy(tl.x(),tl.y()); // move to untransformed co-ords
+ if ( !all.tqcontains(ivr) ) {
+ TQRegion inside = p->clipRegion() & r;
+ //TQRegion outside = p->clipRegion() - r;
+ //p->setClipRegion(outside);
+ //p->fillRect(outside.boundingRect(),red);
+ p->setClipRegion(inside);
+ } else {
+ p->setClipRect(r);
+ }
+#ifndef TQT_NO_TRANSFORMATIONS
+ p->setWorldMatrix( wm*twm );
+#else
+#endif
+ p->setBrushOrigin(tl.x(), tl.y());
+ drawCanvasArea(ivr,p,FALSE);
+ }
+}
+
+/*!
+ Repaints changed areas in all views of the canvas.
+
+ \sa advance()
+*/
+void TQCanvas::update()
+{
+ TQCanvasClusterizer clusterizer(d->viewList.count());
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQPtrList<TQRect> doneareas;
+ doneareas.setAutoDelete(TRUE);
+#endif
+
+ TQPtrListIterator<TQCanvasView> it(d->viewList);
+ TQCanvasView* view;
+ while( (view=it.current()) != 0 ) {
+ ++it;
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix wm = view->tqworldMatrix();
+#endif
+ TQRect area(view->contentsX(),view->contentsY(),
+ view->visibleWidth(),view->visibleHeight());
+ if (area.width()>0 && area.height()>0) {
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( !wm.isIdentity() ) {
+ // r = Visible area of the canvas where there are changes
+ TQRect r = changeBounds(view->inverseWorldMatrix().map(area));
+ if ( !r.isEmpty() ) {
+ TQPainter p(view->viewport());
+ // Translate to the coordinate system of drawViewArea().
+ TQPoint tl = view->contentsToViewport(TQPoint(0,0));
+ p.translate(tl.x(),tl.y());
+ drawViewArea( view, &p, wm.map(r), dblbuf );
+ doneareas.append(new TQRect(r));
+ }
+ } else
+#endif
+ {
+ clusterizer.add(area);
+ }
+ }
+ }
+
+ for (int i=0; i<clusterizer.clusters(); i++)
+ drawChanges(clusterizer[i]);
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ for ( TQRect* r=doneareas.first(); r != 0; r=doneareas.next() )
+ setUnchanged(*r);
+#endif
+}
+
+
+// ### warwick - setAllChanged() is not a set function. please rename
+// it. ditto setChanged(). markChanged(), perhaps?
+// ### unfortunately this function is virtual, which makes renaming more difficult. Lars
+
+/*!
+ Marks the whole canvas as changed.
+ All views of the canvas will be entirely redrawn when
+ update() is called next.
+*/
+void TQCanvas::setAllChanged()
+{
+ setChanged(TQRect(0,0,width(),height()));
+}
+
+/*!
+ Marks \a area as changed. This \a area will be redrawn in all
+ views that are showing it when update() is called next.
+*/
+void TQCanvas::setChanged(const TQRect& area)
+{
+ TQRect thearea = area.intersect(TQRect(0,0,width(),height()));
+
+ int mx = (thearea.x()+thearea.width()+chunksize)/chunksize;
+ int my = (thearea.y()+thearea.height()+chunksize)/chunksize;
+ if (mx>chwidth)
+ mx=chwidth;
+ if (my>chheight)
+ my=chheight;
+
+ int x=thearea.x()/chunksize;
+ while( x<mx) {
+ int y = thearea.y()/chunksize;
+ while( y<my ) {
+ chunk(x,y).change();
+ y++;
+ }
+ x++;
+ }
+}
+
+/*!
+ Marks \a area as \e unchanged. The area will \e not be redrawn in
+ the views for the next update(), unless it is marked or changed
+ again before the next call to update().
+*/
+void TQCanvas::setUnchanged(const TQRect& area)
+{
+ TQRect thearea = area.intersect(TQRect(0,0,width(),height()));
+
+ int mx = (thearea.x()+thearea.width()+chunksize)/chunksize;
+ int my = (thearea.y()+thearea.height()+chunksize)/chunksize;
+ if (mx>chwidth)
+ mx=chwidth;
+ if (my>chheight)
+ my=chheight;
+
+ int x=thearea.x()/chunksize;
+ while( x<mx) {
+ int y = thearea.y()/chunksize;
+ while( y<my ) {
+ chunk(x,y).takeChange();
+ y++;
+ }
+ x++;
+ }
+}
+
+
+/*!
+ \internal
+*/
+TQRect TQCanvas::changeBounds(const TQRect& inarea)
+{
+ TQRect area=inarea.intersect(TQRect(0,0,width(),height()));
+
+ int mx = (area.x()+area.width()+chunksize)/chunksize;
+ int my = (area.y()+area.height()+chunksize)/chunksize;
+ if (mx > chwidth)
+ mx=chwidth;
+ if (my > chheight)
+ my=chheight;
+
+ TQRect result;
+
+ int x=area.x()/chunksize;
+ while( x<mx ) {
+ int y=area.y()/chunksize;
+ while( y<my ) {
+ TQCanvasChunk& ch=chunk(x,y);
+ if ( ch.hasChanged() )
+ result |= TQRect(x,y,1,1);
+ y++;
+ }
+ x++;
+ }
+
+ if ( !result.isEmpty() ) {
+ result.rLeft() *= chunksize;
+ result.rTop() *= chunksize;
+ result.rRight() *= chunksize;
+ result.rBottom() *= chunksize;
+ result.rRight() += chunksize;
+ result.rBottom() += chunksize;
+ }
+
+ return result;
+}
+
+/*!
+\internal
+Redraws the area \a inarea of the TQCanvas.
+*/
+void TQCanvas::drawChanges(const TQRect& inarea)
+{
+ TQRect area=inarea.intersect(TQRect(0,0,width(),height()));
+
+ TQCanvasClusterizer clusters(maxclusters);
+
+ int mx = (area.x()+area.width()+chunksize)/chunksize;
+ int my = (area.y()+area.height()+chunksize)/chunksize;
+ if (mx > chwidth)
+ mx=chwidth;
+ if (my > chheight)
+ my=chheight;
+
+ int x=area.x()/chunksize;
+ while( x<mx ) {
+ int y=area.y()/chunksize;
+ while( y<my ) {
+ TQCanvasChunk& ch=chunk(x,y);
+ if ( ch.hasChanged() )
+ clusters.add(x,y);
+ y++;
+ }
+ x++;
+ }
+
+ for (int i=0; i<clusters.clusters(); i++) {
+ TQRect elarea=clusters[i];
+ elarea.setRect(
+ elarea.left()*chunksize,
+ elarea.top()*chunksize,
+ elarea.width()*chunksize,
+ elarea.height()*chunksize
+ );
+ drawCanvasArea(elarea);
+ }
+}
+
+/*!
+ Paints all canvas items that are in the area \a clip to \a
+ painter, using double-buffering if \a dbuf is TRUE.
+
+ e.g. to print the canvas to a printer:
+ \code
+ TQPrinter pr;
+ if ( pr.setup() ) {
+ TQPainter p(&pr);
+ canvas.drawArea( canvas.rect(), &p );
+ }
+ \endcode
+*/
+void TQCanvas::drawArea(const TQRect& clip, TQPainter* painter, bool dbuf)
+{
+ if ( painter )
+ drawCanvasArea( clip, painter, dbuf );
+}
+
+/*!
+ \internal
+*/
+void TQCanvas::drawCanvasArea(const TQRect& inarea, TQPainter* p, bool double_buffer)
+{
+ TQRect area=inarea.intersect(TQRect(0,0,width(),height()));
+
+ if ( !dblbuf )
+ double_buffer = FALSE;
+
+ if (!d->viewList.first() && !p) return; // Nothing to do.
+
+ int lx=area.x()/chunksize;
+ int ly=area.y()/chunksize;
+ int mx=area.right()/chunksize;
+ int my=area.bottom()/chunksize;
+ if (mx>=chwidth)
+ mx=chwidth-1;
+ if (my>=chheight)
+ my=chheight-1;
+
+ TQCanvasItemList allvisible;
+
+ // Stores the region within area that need to be drawn. It is relative
+ // to area.topLeft() (so as to keep within bounds of 16-bit XRegions)
+ TQRegion rgn;
+
+ for (int x=lx; x<=mx; x++) {
+ for (int y=ly; y<=my; y++) {
+ // Only reset change if all views updating, and
+ // wholy within area. (conservative: ignore entire boundary)
+ //
+ // Disable this to help debugging.
+ //
+ if (!p) {
+ if ( chunk(x,y).takeChange() ) {
+ // ### should at least make bands
+ rgn |= TQRegion(x*chunksize-area.x(),y*chunksize-area.y(),
+ chunksize,chunksize);
+ allvisible += *chunk(x,y).listPtr();
+ }
+ } else {
+ allvisible += *chunk(x,y).listPtr();
+ }
+ }
+ }
+ allvisible.sort();
+
+ if ( double_buffer ) {
+ offscr = TQPixmap(area.size().expandedTo(TQSize(1, 1)));
+#ifdef TQ_WS_X11
+ if (p)
+ offscr.x11SetScreen(p->tqdevice()->x11Screen());
+#endif
+ }
+
+ if ( double_buffer && !offscr.isNull() ) {
+ TQPainter painter;
+ painter.begin(&offscr);
+ painter.translate(-area.x(),-area.y());
+ painter.setBrushOrigin(-area.x(),-area.y());
+ if ( p ) {
+ painter.setClipRect(TQRect(0,0,area.width(),area.height()));
+ } else {
+ painter.setClipRegion(rgn);
+ }
+ drawBackground(painter,area);
+ allvisible.drawUnique(painter);
+ drawForeground(painter,area);
+ painter.end();
+ if ( p ) {
+ p->drawPixmap( area.x(), area.y(), offscr,
+ 0, 0, area.width(), area.height() );
+ return;
+ }
+ } else if ( p ) {
+ drawBackground(*p,area);
+ allvisible.drawUnique(*p);
+ drawForeground(*p,area);
+ return;
+ }
+
+ TQPoint trtr; // keeps track of total translation of rgn
+
+ trtr -= area.topLeft();
+
+ for (TQCanvasView* view=d->viewList.first(); view; view=d->viewList.next()) {
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( !view->tqworldMatrix().isIdentity() )
+ continue; // Cannot paint those here (see callers).
+#endif
+ TQPainter painter(view->viewport());
+ TQPoint tr = view->contentsToViewport(area.topLeft());
+ TQPoint nrtr = view->contentsToViewport(TQPoint(0,0)); // new translation
+ TQPoint rtr = nrtr - trtr; // extra translation of rgn
+ trtr += rtr; // add to total
+ if (double_buffer) {
+ rgn.translate(rtr.x(),rtr.y());
+ painter.setClipRegion(rgn);
+ painter.drawPixmap(tr,offscr, TQRect(TQPoint(0,0),area.size()));
+ } else {
+ painter.translate(nrtr.x(),nrtr.y());
+ rgn.translate(rtr.x(),rtr.y());
+ painter.setClipRegion(rgn);
+ drawBackground(painter,area);
+ allvisible.drawUnique(painter);
+ drawForeground(painter,area);
+ painter.translate(-nrtr.x(),-nrtr.y());
+ }
+ }
+}
+
+/*!
+\internal
+This method to informs the TQCanvas that a given chunk is
+`dirty' and needs to be redrawn in the next Update.
+
+(\a x,\a y) is a chunk location.
+
+The sprite classes call this. Any new derived class of TQCanvasItem
+must do so too. SetChangedChunkContaining can be used instead.
+*/
+void TQCanvas::setChangedChunk(int x, int y)
+{
+ if (validChunk(x,y)) {
+ TQCanvasChunk& ch=chunk(x,y);
+ ch.change();
+ }
+}
+
+/*!
+\internal
+This method to informs the TQCanvas that the chunk containing a given
+pixel is `dirty' and needs to be redrawn in the next Update.
+
+(\a x,\a y) is a pixel location.
+
+The item classes call this. Any new derived class of TQCanvasItem must
+do so too. SetChangedChunk can be used instead.
+*/
+void TQCanvas::setChangedChunkContaining(int x, int y)
+{
+ if (x>=0 && x<width() && y>=0 && y<height()) {
+ TQCanvasChunk& chunk=chunkContaining(x,y);
+ chunk.change();
+ }
+}
+
+/*!
+\internal
+This method adds the TQCanvasItem \a g to the list of those which need to be
+drawn if the given chunk at location ( \a x, \a y ) is redrawn. Like
+SetChangedChunk and SetChangedChunkContaining, this method marks the
+chunk as `dirty'.
+*/
+void TQCanvas::addItemToChunk(TQCanvasItem* g, int x, int y)
+{
+ if (validChunk(x,y)) {
+ chunk(x,y).add(g);
+ }
+}
+
+/*!
+\internal
+This method removes the TQCanvasItem \a g from the list of those which need to
+be drawn if the given chunk at location ( \a x, \a y ) is redrawn. Like
+SetChangedChunk and SetChangedChunkContaining, this method marks the chunk
+as `dirty'.
+*/
+void TQCanvas::removeItemFromChunk(TQCanvasItem* g, int x, int y)
+{
+ if (validChunk(x,y)) {
+ chunk(x,y).remove(g);
+ }
+}
+
+
+/*!
+\internal
+This method adds the TQCanvasItem \a g to the list of those which need to be
+drawn if the chunk containing the given pixel ( \a x, \a y ) is redrawn. Like
+SetChangedChunk and SetChangedChunkContaining, this method marks the
+chunk as `dirty'.
+*/
+void TQCanvas::addItemToChunkContaining(TQCanvasItem* g, int x, int y)
+{
+ if (x>=0 && x<width() && y>=0 && y<height()) {
+ chunkContaining(x,y).add(g);
+ }
+}
+
+/*!
+\internal
+This method removes the TQCanvasItem \a g from the list of those which need to
+be drawn if the chunk containing the given pixel ( \a x, \a y ) is redrawn.
+Like SetChangedChunk and SetChangedChunkContaining, this method
+marks the chunk as `dirty'.
+*/
+void TQCanvas::removeItemFromChunkContaining(TQCanvasItem* g, int x, int y)
+{
+ if (x>=0 && x<width() && y>=0 && y<height()) {
+ chunkContaining(x,y).remove(g);
+ }
+}
+
+/*!
+ Returns the color set by setBackgroundColor(). By default, this is
+ white.
+
+ This function is not a reimplementation of
+ TQWidget::backgroundColor() (TQCanvas is not a subclass of TQWidget),
+ but all TQCanvasViews that are viewing the canvas will set their
+ backgrounds to this color.
+
+ \sa setBackgroundColor(), backgroundPixmap()
+*/
+TQColor TQCanvas::backgroundColor() const
+{
+ return bgcolor;
+}
+
+/*!
+ Sets the solid background to be the color \a c.
+
+ \sa backgroundColor(), setBackgroundPixmap(), setTiles()
+*/
+void TQCanvas::setBackgroundColor( const TQColor& c )
+{
+ if ( bgcolor != c ) {
+ bgcolor = c;
+ TQCanvasView* view=d->viewList.first();
+ while ( view != 0 ) {
+ /* XXX this doesn't look right. Shouldn't this
+ be more like setBackgroundPixmap? : Ian */
+ view->viewport()->setEraseColor( bgcolor );
+ view=d->viewList.next();
+ }
+ setAllChanged();
+ }
+}
+
+/*!
+ Returns the pixmap set by setBackgroundPixmap(). By default,
+ this is a null pixmap.
+
+ \sa setBackgroundPixmap(), backgroundColor()
+*/
+TQPixmap TQCanvas::backgroundPixmap() const
+{
+ return pm;
+}
+
+/*!
+ Sets the solid background to be the pixmap \a p repeated as
+ necessary to cover the entire canvas.
+
+ \sa backgroundPixmap(), setBackgroundColor(), setTiles()
+*/
+void TQCanvas::tqsetBackgroundPixmap( const TQPixmap& p )
+{
+ setTiles(p, 1, 1, p.width(), p.height());
+ TQCanvasView* view = d->viewList.first();
+ while ( view != 0 ) {
+ view->updateContents();
+ view = d->viewList.next();
+ }
+}
+
+/*!
+ This virtual function is called for all updates of the canvas. It
+ renders any background graphics using the painter \a painter, in
+ the area \a clip. If the canvas has a background pixmap or a tiled
+ background, that graphic is used, otherwise the canvas is cleared
+ using the background color.
+
+ If the graphics for an area change, you must explicitly call
+ setChanged(const TQRect&) for the result to be visible when
+ update() is next called.
+
+ \sa setBackgroundColor(), setBackgroundPixmap(), setTiles()
+*/
+void TQCanvas::drawBackground(TQPainter& painter, const TQRect& clip)
+{
+ if ( pm.isNull() ) {
+ painter.fillRect(clip,bgcolor);
+ } else if ( !grid ) {
+ for (int x=clip.x()/pm.width();
+ x<(clip.x()+clip.width()+pm.width()-1)/pm.width(); x++)
+ {
+ for (int y=clip.y()/pm.height();
+ y<(clip.y()+clip.height()+pm.height()-1)/pm.height(); y++)
+ {
+ painter.drawPixmap(x*pm.width(), y*pm.height(),pm);
+ }
+ }
+ } else {
+ const int x1 = clip.left()/tilew;
+ int x2 = clip.right()/tilew;
+ const int y1 = clip.top()/tileh;
+ int y2 = clip.bottom()/tileh;
+
+ const int roww = pm.width()/tilew;
+
+ for (int j=y1; j<=y2; j++) {
+ int jj = j%tilesVertically();
+ for (int i=x1; i<=x2; i++) {
+ int t = tile(i%tilesHorizontally(), jj);
+ int tx = t % roww;
+ int ty = t / roww;
+ painter.drawPixmap( i*tilew, j*tileh, pm,
+ tx*tilew, ty*tileh, tilew, tileh );
+ }
+ }
+ }
+}
+
+/*!
+ This virtual function is called for all updates of the canvas. It
+ renders any foreground graphics using the painter \a painter, in
+ the area \a clip.
+
+ If the graphics for an area change, you must explicitly call
+ setChanged(const TQRect&) for the result to be visible when
+ update() is next called.
+
+ The default is to draw nothing.
+*/
+void TQCanvas::drawForeground(TQPainter& painter, const TQRect& clip)
+{
+ if ( debug_redraw_areas ) {
+ painter.setPen(Qt::red);
+ painter.setBrush(TQt::NoBrush);
+ painter.drawRect(clip);
+ }
+}
+
+/*!
+ If \a y is TRUE (the default) double-buffering is switched on;
+ otherwise double-buffering is switched off.
+
+ Turning off double-buffering causes the redrawn areas to flicker a
+ little and also gives a (usually small) performance improvement.
+*/
+void TQCanvas::setDoubleBuffering(bool y)
+{
+ dblbuf = y;
+}
+
+
+/*!
+ Sets the TQCanvas to be composed of \a h tiles horizontally and \a
+ v tiles vertically. Each tile will be an image \a tilewidth by \a
+ tileheight pixels from pixmap \a p.
+
+ The pixmap \a p is a list of tiles, arranged left to right, (and
+ in the case of pixmaps that have multiple rows of tiles, top to
+ bottom), with tile 0 in the top-left corner, tile 1 next to the
+ right, and so on, e.g.
+
+ \table
+ \row \i 0 \i 1 \i 2 \i 3
+ \row \i 4 \i 5 \i 6 \i 7
+ \endtable
+
+ If the canvas is larger than the matrix of tiles, the entire
+ matrix is repeated as necessary to cover the whole canvas. If it
+ is smaller, tiles to the right and bottom are not visible.
+
+ The width and height of \a p must be a multiple of \a tilewidth
+ and \a tileheight. If they are not the function will do nothing.
+
+ If you want to unset any tiling set, then just pass in a null
+ pixmap and 0 for \a h, \a v, \a tilewidth, and
+ \a tileheight.
+*/
+void TQCanvas::setTiles( TQPixmap p,
+ int h, int v, int tilewidth, int tileheight )
+{
+ if ( !p.isNull() && (!tilewidth || !tileheight ||
+ p.width() % tilewidth != 0 || p.height() % tileheight != 0 ) )
+ return;
+
+ htiles = h;
+ vtiles = v;
+ delete[] grid;
+ pm = p;
+ if ( h && v && !p.isNull() ) {
+ grid = new ushort[h*v];
+ memset( grid, 0, h*v*sizeof(ushort) );
+ tilew = tilewidth;
+ tileh = tileheight;
+ } else {
+ grid = 0;
+ }
+ if ( h + v > 10 ) {
+ int s = scm(tilewidth,tileheight);
+ retune( s < 128 ? s : TQMAX(tilewidth,tileheight) );
+ }
+ setAllChanged();
+}
+
+/*!
+ \fn int TQCanvas::tile( int x, int y ) const
+
+ Returns the tile at position (\a x, \a y). Initially, all tiles
+ are 0.
+
+ The parameters must be within range, i.e.
+ 0 \< \a x \< tilesHorizontally() and
+ 0 \< \a y \< tilesVertically().
+
+ \sa setTile()
+*/
+
+/*!
+ \fn int TQCanvas::tilesHorizontally() const
+
+ Returns the number of tiles horizontally.
+*/
+
+/*!
+ \fn int TQCanvas::tilesVertically() const
+
+ Returns the number of tiles vertically.
+*/
+
+/*!
+ \fn int TQCanvas::tileWidth() const
+
+ Returns the width of each tile.
+*/
+
+/*!
+ \fn int TQCanvas::tileHeight() const
+
+ Returns the height of each tile.
+*/
+
+
+/*!
+ Sets the tile at (\a x, \a y) to use tile number \a tilenum, which
+ is an index into the tile pixmaps. The canvas will update
+ appropriately when update() is next called.
+
+ The images are taken from the pixmap set by setTiles() and are
+ arranged left to right, (and in the case of pixmaps that have
+ multiple rows of tiles, top to bottom), with tile 0 in the
+ top-left corner, tile 1 next to the right, and so on, e.g.
+
+ \table
+ \row \i 0 \i 1 \i 2 \i 3
+ \row \i 4 \i 5 \i 6 \i 7
+ \endtable
+
+ \sa tile() setTiles()
+*/
+void TQCanvas::setTile( int x, int y, int tilenum )
+{
+ ushort& t = grid[x+y*htiles];
+ if ( t != tilenum ) {
+ t = tilenum;
+ if ( tilew == tileh && tilew == chunksize )
+ setChangedChunk( x, y ); // common case
+ else
+ setChanged( TQRect(x*tilew,y*tileh,tilew,tileh) );
+ }
+}
+
+
+// lesser-used data in canvas item, plus room for extension.
+// Be careful adding to this - check all usages.
+class TQCanvasItemExtra {
+ TQCanvasItemExtra() : vx(0.0), vy(0.0) { }
+ double vx,vy;
+ friend class TQCanvasItem;
+};
+
+
+/*!
+ \class TQCanvasItem tqcanvas.h
+ \brief The TQCanvasItem class provides an abstract graphic object on a TQCanvas.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ A variety of TQCanvasItem subclasses provide immediately usable
+ behaviour. This class is a pure abstract superclass providing the
+ behaviour that is shared among all the concrete canvas item classes.
+ TQCanvasItem is not intended for direct subclassing. It is much easier
+ to subclass one of its subclasses, e.g. TQCanvasPolygonalItem (the
+ commonest base class), TQCanvasRectangle, TQCanvasSprite, TQCanvasEllipse
+ or TQCanvasText.
+
+ Canvas items are added to a canvas by constructing them and passing the
+ canvas to the canvas item's constructor. An item can be moved to a
+ different canvas using setCanvas().
+
+ Items appear on the canvas after their \link show() show()\endlink
+ function has been called (or \link tqsetVisible()
+ tqsetVisible(TRUE)\endlink), and \e after update() has been called. The
+ canvas only shows items that are \link tqsetVisible() visible\endlink,
+ and then only if \l update() is called. If you created the canvas
+ without passing a width and height to the constructor you'll also need
+ to call \link TQCanvas::resize() resize()\endlink. Since the canvas
+ background defaults to white and canvas items default to white,
+ you may need to change colors to see your items.
+
+ A TQCanvasItem object can be moved in the x(), y() and z() dimensions
+ using functions such as move(), moveBy(), setX(), setY() and setZ(). A
+ canvas item can be set in motion, `animated', using setAnimated() and
+ given a velocity in the x and y directions with setXVelocity() and
+ setYVelocity() -- the same effect can be achieved by calling
+ setVelocity(). Use the collidesWith() function to see if the canvas item
+ will collide on the \e next advance(1) and use collisions() to see what
+ collisions have occurred.
+
+ Use TQCanvasSprite or your own subclass of TQCanvasSprite to create canvas
+ items which are animated, i.e. which change over time.
+
+ The size of a canvas item is given by boundingRect(). Use
+ boundingRectAdvanced() to see what the size of the canvas item will be
+ \e after the next advance(1) call.
+
+ The rtti() function is used for identifying subclasses of TQCanvasItem.
+ The canvas() function returns a pointer to the canvas which tqcontains the
+ canvas item.
+
+ TQCanvasItem provides the show() and isVisible() functions like those in
+ TQWidget.
+
+ TQCanvasItem also provides the setEnabled(), setActive() and
+ setSelected() functions; these functions set the relevant boolean and
+ cause a tqrepaint but the boolean values they set are not used in
+ TQCanvasItem itself. You can make use of these booleans in your subclasses.
+
+ By default, canvas items have no velocity, no size, and are not in
+ motion. The subclasses provided in TQt do not change these defaults
+ except where noted.
+
+*/
+
+/*!
+ \enum TQCanvasItem::RttiValues
+
+ This enum is used to name the different types of canvas item.
+
+ \value Rtti_Item Canvas item abstract base class
+ \value Rtti_Ellipse
+ \value Rtti_Line
+ \value Rtti_Polygon
+ \value Rtti_PolygonalItem
+ \value Rtti_Rectangle
+ \value Rtti_Spline
+ \value Rtti_Sprite
+ \value Rtti_Text
+
+*/
+
+/*!
+ \fn void TQCanvasItem::update()
+
+ Call this function to tqrepaint the canvas's changed chunks.
+*/
+
+/*!
+ Constructs a TQCanvasItem on canvas \a canvas.
+
+ \sa setCanvas()
+*/
+TQCanvasItem::TQCanvasItem(TQCanvas* canvas) :
+ cnv(canvas),
+ myx(0),myy(0),myz(0)
+{
+ ani=0;
+ vis=0;
+ val=0;
+ sel=0;
+ ena=0;
+ act=0;
+
+ ext = 0;
+ if (cnv) cnv->addItem(this);
+}
+
+/*!
+ Destroys the TQCanvasItem and removes it from its canvas.
+*/
+TQCanvasItem::~TQCanvasItem()
+{
+ if (cnv) {
+ cnv->removeItem(this);
+ cnv->removeAnimation(this);
+ }
+ delete ext;
+}
+
+TQCanvasItemExtra& TQCanvasItem::extra()
+{
+ if ( !ext )
+ ext = new TQCanvasItemExtra;
+ return *ext;
+}
+
+/*!
+ \fn double TQCanvasItem::x() const
+
+ Returns the horizontal position of the canvas item. Note that
+ subclasses often have an origin other than the top-left corner.
+*/
+
+/*!
+ \fn double TQCanvasItem::y() const
+
+ Returns the vertical position of the canvas item. Note that
+ subclasses often have an origin other than the top-left corner.
+*/
+
+/*!
+ \fn double TQCanvasItem::z() const
+
+ Returns the z index of the canvas item, which is used for visual
+ order: higher-z items obscure (are in front of) lower-z items.
+*/
+
+/*!
+ \fn void TQCanvasItem::setX(double x)
+
+ Moves the canvas item so that its x-position is \a x.
+
+ \sa x(), move()
+*/
+
+/*!
+ \fn void TQCanvasItem::setY(double y)
+
+ Moves the canvas item so that its y-position is \a y.
+
+ \sa y(), move()
+*/
+
+/*!
+ \fn void TQCanvasItem::setZ(double z)
+
+ Sets the z index of the canvas item to \a z. Higher-z items
+ obscure (are in front of) lower-z items.
+
+ \sa z(), move()
+*/
+
+
+/*!
+ Moves the canvas item relative to its current position by (\a dx,
+ \a dy).
+*/
+void TQCanvasItem::moveBy( double dx, double dy )
+{
+ if ( dx || dy ) {
+ removeFromChunks();
+ myx += dx;
+ myy += dy;
+ addToChunks();
+ }
+}
+
+
+/*!
+ Moves the canvas item to the absolute position (\a x, \a y).
+*/
+void TQCanvasItem::move( double x, double y )
+{
+ moveBy( x-myx, y-myy );
+}
+
+
+/*!
+ Returns TRUE if the canvas item is in motion; otherwise returns
+ FALSE.
+
+ \sa setVelocity(), setAnimated()
+*/
+bool TQCanvasItem::animated() const
+{
+ return (bool)ani;
+}
+
+/*!
+ Sets the canvas item to be in motion if \a y is TRUE, or not if \a
+ y is FALSE. The speed and direction of the motion is set with
+ setVelocity(), or with setXVelocity() and setYVelocity().
+
+ \sa advance(), TQCanvas::advance()
+*/
+void TQCanvasItem::setAnimated(bool y)
+{
+ if ( y != (bool)ani ) {
+ ani = (uint)y;
+ if ( y ) {
+ cnv->addAnimation(this);
+ } else {
+ cnv->removeAnimation(this);
+ }
+ }
+}
+
+/*!
+ \fn void TQCanvasItem::setXVelocity( double vx )
+
+ Sets the horizontal component of the canvas item's velocity to \a vx.
+
+ \sa setYVelocity() setVelocity()
+*/
+
+/*!
+ \fn void TQCanvasItem::setYVelocity( double vy )
+
+ Sets the vertical component of the canvas item's velocity to \a vy.
+
+ \sa setXVelocity() setVelocity()
+*/
+
+/*!
+ Sets the canvas item to be in motion, moving by \a vx and \a vy
+ pixels in the horizontal and vertical directions respectively.
+
+ \sa advance() setXVelocity() setYVelocity()
+*/
+void TQCanvasItem::setVelocity( double vx, double vy)
+{
+ if ( ext || vx!=0.0 || vy!=0.0 ) {
+ if ( !ani )
+ setAnimated(TRUE);
+ extra().vx = vx;
+ extra().vy = vy;
+ }
+}
+
+/*!
+ Returns the horizontal velocity component of the canvas item.
+*/
+double TQCanvasItem::xVelocity() const
+{
+ return ext ? ext->vx : 0;
+}
+
+/*!
+ Returns the vertical velocity component of the canvas item.
+*/
+double TQCanvasItem::yVelocity() const
+{
+ return ext ? ext->vy : 0;
+}
+
+/*!
+ The default implementation moves the canvas item, if it is
+ animated(), by the preset velocity if \a phase is 1, and does
+ nothing if \a phase is 0.
+
+ Note that if you reimplement this function, the reimplementation
+ must not change the canvas in any way, for example it must not add
+ or remove items.
+
+ \sa TQCanvas::advance() setVelocity()
+*/
+void TQCanvasItem::advance(int phase)
+{
+ if ( ext && phase==1 )
+ moveBy(ext->vx,ext->vy);
+}
+
+/*!
+ \fn void TQCanvasItem::draw(TQPainter& painter)
+
+ This abstract virtual function draws the canvas item using \a painter.
+
+ \warning When you reimplement this function, make sure that you
+ leave the painter in the same state as you found it. For example,
+ if you start by calling TQPainter::translate(50, 50), end your
+ code by calling TQPainter::translate(-50, -50). Be also aware that
+ the painter might already have some transformations set (i.e.,
+ don't call TQPainter::resetXForm() when you're done).
+*/
+
+/*!
+ Sets the TQCanvas upon which the canvas item is to be drawn to \a c.
+
+ \sa canvas()
+*/
+void TQCanvasItem::setCanvas(TQCanvas* c)
+{
+ bool v=isVisible();
+ tqsetVisible(FALSE);
+ if (cnv) {
+ if (ext)
+ cnv->removeAnimation(this);
+ cnv->removeItem(this);
+ }
+ cnv=c;
+ if (cnv) {
+ cnv->addItem(this);
+ if ( ext )
+ cnv->addAnimation(this);
+ }
+ tqsetVisible(v);
+}
+
+/*!
+ \fn TQCanvas* TQCanvasItem::canvas() const
+
+ Returns the canvas containing the canvas item.
+*/
+
+/*! Shorthand for tqsetVisible(TRUE). */
+void TQCanvasItem::show()
+{
+ tqsetVisible(TRUE);
+}
+
+/*! Shorthand for tqsetVisible(FALSE). */
+void TQCanvasItem::hide()
+{
+ tqsetVisible(FALSE);
+}
+
+/*!
+ Makes the canvas item visible if \a yes is TRUE, or invisible if
+ \a yes is FALSE. The change takes effect when TQCanvas::update() is
+ next called.
+*/
+void TQCanvasItem::tqsetVisible(bool yes)
+{
+ if ((bool)vis!=yes) {
+ if (yes) {
+ vis=(uint)yes;
+ addToChunks();
+ } else {
+ removeFromChunks();
+ vis=(uint)yes;
+ }
+ }
+}
+/*!
+ \obsolete
+ \fn bool TQCanvasItem::visible() const
+ Use isVisible() instead.
+*/
+
+/*!
+ \fn bool TQCanvasItem::isVisible() const
+
+ Returns TRUE if the canvas item is visible; otherwise returns
+ FALSE.
+
+ Note that in this context TRUE does \e not mean that the canvas
+ item is currently in a view, merely that if a view is showing the
+ area where the canvas item is positioned, and the item is not
+ obscured by items with higher z values, and the view is not
+ obscured by overlaying windows, it would be visible.
+
+ \sa tqsetVisible(), z()
+*/
+
+/*!
+ \obsolete
+ \fn bool TQCanvasItem::selected() const
+ Use isSelected() instead.
+*/
+
+/*!
+ \fn bool TQCanvasItem::isSelected() const
+
+ Returns TRUE if the canvas item is selected; otherwise returns FALSE.
+*/
+
+/*!
+ Sets the selected flag of the item to \a yes. If this changes the
+ item's selected state the item will be redrawn when
+ TQCanvas::update() is next called.
+
+ The TQCanvas, TQCanvasItem and the TQt-supplied TQCanvasItem
+ subclasses do not make use of this value. The setSelected()
+ function is supplied because many applications need it, but it is
+ up to you how you use the isSelected() value.
+*/
+void TQCanvasItem::setSelected(bool yes)
+{
+ if ((bool)sel!=yes) {
+ sel=(uint)yes;
+ changeChunks();
+ }
+}
+
+/*!
+ \obsolete
+ \fn bool TQCanvasItem::enabled() const
+ Use isEnabled() instead.
+*/
+
+/*!
+ \fn bool TQCanvasItem::isEnabled() const
+
+ Returns TRUE if the TQCanvasItem is enabled; otherwise returns FALSE.
+*/
+
+/*!
+ Sets the enabled flag of the item to \a yes. If this changes the
+ item's enabled state the item will be redrawn when
+ TQCanvas::update() is next called.
+
+ The TQCanvas, TQCanvasItem and the TQt-supplied TQCanvasItem
+ subclasses do not make use of this value. The setEnabled()
+ function is supplied because many applications need it, but it is
+ up to you how you use the isEnabled() value.
+*/
+void TQCanvasItem::setEnabled(bool yes)
+{
+ if (ena!=(uint)yes) {
+ ena=(uint)yes;
+ changeChunks();
+ }
+}
+
+/*!
+ \obsolete
+ \fn bool TQCanvasItem::active() const
+ Use isActive() instead.
+*/
+
+/*!
+ \fn bool TQCanvasItem::isActive() const
+
+ Returns TRUE if the TQCanvasItem is active; otherwise returns FALSE.
+*/
+
+/*!
+ Sets the active flag of the item to \a yes. If this changes the
+ item's active state the item will be redrawn when
+ TQCanvas::update() is next called.
+
+ The TQCanvas, TQCanvasItem and the TQt-supplied TQCanvasItem
+ subclasses do not make use of this value. The setActive() function
+ is supplied because many applications need it, but it is up to you
+ how you use the isActive() value.
+*/
+void TQCanvasItem::setActive(bool yes)
+{
+ if (act!=(uint)yes) {
+ act=(uint)yes;
+ changeChunks();
+ }
+}
+
+bool qt_testCollision(const TQCanvasSprite* s1, const TQCanvasSprite* s2)
+{
+ const TQImage* s2image = s2->imageAdvanced()->collision_mask;
+ TQRect s2area = s2->boundingRectAdvanced();
+
+ TQRect cyourarea(s2area.x(),s2area.y(),
+ s2area.width(),s2area.height());
+
+ TQImage* s1image=s1->imageAdvanced()->collision_mask;
+
+ TQRect s1area = s1->boundingRectAdvanced();
+
+ TQRect ourarea = s1area.intersect(cyourarea);
+
+ if ( ourarea.isEmpty() )
+ return FALSE;
+
+ int x2=ourarea.x()-cyourarea.x();
+ int y2=ourarea.y()-cyourarea.y();
+ int x1=ourarea.x()-s1area.x();
+ int y1=ourarea.y()-s1area.y();
+ int w=ourarea.width();
+ int h=ourarea.height();
+
+ if ( !s2image ) {
+ if ( !s1image )
+ return w>0 && h>0;
+ // swap everything around
+ int t;
+ t=x1; x1=x2; x2=t;
+ t=y1; x1=y2; y2=t;
+ s2image = s1image;
+ s1image = 0;
+ }
+
+ // s2image != 0
+
+ // A non-linear search may be more efficient.
+ // Perhaps spiralling out from the center, or a simpler
+ // vertical expansion from the centreline.
+
+ // We assume that sprite masks don't have
+ // different bit orders.
+ //
+ // TQ_ASSERT(s1image->bitOrder()==s2image->bitOrder());
+
+ if (s1image) {
+ if (s1image->bitOrder() == TQImage::LittleEndian) {
+ for (int j=0; j<h; j++) {
+ const uchar* ml = s1image->scanLine(y1+j);
+ const uchar* yl = s2image->scanLine(y2+j);
+ for (int i=0; i<w; i++) {
+ if (*(yl + ((x2+i) >> 3)) & (1 << ((x2+i) & 7))
+ && *(ml + ((x1+i) >> 3)) & (1 << ((x1+i) & 7)))
+ {
+ return TRUE;
+ }
+ }
+ }
+ } else {
+ for (int j=0; j<h; j++) {
+ const uchar* ml = s1image->scanLine(y1+j);
+ const uchar* yl = s2image->scanLine(y2+j);
+ for (int i=0; i<w; i++) {
+ if (*(yl + ((x2+i) >> 3)) & (1 << (7-((x2+i) & 7)))
+ && *(ml + ((x1+i) >> 3)) & (1 << (7-((x1+i) & 7))))
+ {
+ return TRUE;
+ }
+ }
+ }
+ }
+ } else {
+ if (s2image->bitOrder() == TQImage::LittleEndian) {
+ for (int j=0; j<h; j++) {
+ const uchar* yl = s2image->scanLine(y2+j);
+ for (int i=0; i<w; i++) {
+ if (*(yl + ((x2+i) >> 3)) & (1 << ((x2+i) & 7)))
+ {
+ return TRUE;
+ }
+ }
+ }
+ } else {
+ for (int j=0; j<h; j++) {
+ const uchar* yl = s2image->scanLine(y2+j);
+ for (int i=0; i<w; i++) {
+ if (*(yl + ((x2+i) >> 3)) & (1 << (7-((x2+i) & 7))))
+ {
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+static bool collision_double_dispatch( const TQCanvasSprite* s1,
+ const TQCanvasPolygonalItem* p1,
+ const TQCanvasRectangle* r1,
+ const TQCanvasEllipse* e1,
+ const TQCanvasText* t1,
+ const TQCanvasSprite* s2,
+ const TQCanvasPolygonalItem* p2,
+ const TQCanvasRectangle* r2,
+ const TQCanvasEllipse* e2,
+ const TQCanvasText* t2 )
+{
+ const TQCanvasItem* i1 = s1 ?
+ (const TQCanvasItem*)s1 : p1 ?
+ (const TQCanvasItem*)p1 : r1 ?
+ (const TQCanvasItem*)r1 : e1 ?
+ (const TQCanvasItem*)e1 : (const TQCanvasItem*)t1;
+ const TQCanvasItem* i2 = s2 ?
+ (const TQCanvasItem*)s2 : p2 ?
+ (const TQCanvasItem*)p2 : r2 ?
+ (const TQCanvasItem*)r2 : e2 ?
+ (const TQCanvasItem*)e2 : (const TQCanvasItem*)t2;
+
+ if ( s1 && s2 ) {
+ // a
+ return qt_testCollision(s1,s2);
+ } else if ( (r1 || t1 || s1) && (r2 || t2 || s2) ) {
+ // b
+ TQRect rc1 = i1->boundingRectAdvanced();
+ TQRect rc2 = i2->boundingRectAdvanced();
+ return rc1.intersects(rc2);
+ } else if ( e1 && e2
+ && e1->angleLength()>=360*16 && e2->angleLength()>=360*16
+ && e1->width()==e1->height()
+ && e2->width()==e2->height() ) {
+ // c
+ double xd = (e1->x()+e1->xVelocity())-(e2->x()+e1->xVelocity());
+ double yd = (e1->y()+e1->yVelocity())-(e2->y()+e1->yVelocity());
+ double rd = (e1->width()+e2->width())/2;
+ return xd*xd+yd*yd <= rd*rd;
+ } else if ( p1 && (p2 || s2 || t2) ) {
+ // d
+ TQPointArray pa1 = p1->areaPointsAdvanced();
+ TQPointArray pa2 = p2 ? p2->areaPointsAdvanced()
+ : TQPointArray(i2->boundingRectAdvanced());
+ bool col= !(TQRegion(pa1) & TQRegion(pa2,TRUE)).isEmpty();
+
+ return col;
+ } else {
+ return collision_double_dispatch(s2,p2,r2,e2,t2,
+ s1,p1,r1,e1,t1);
+ }
+}
+
+/*!
+ \fn bool TQCanvasItem::collidesWith( const TQCanvasItem* other ) const
+
+ Returns TRUE if the canvas item will collide with the \a other
+ item \e after they have moved by their current velocities;
+ otherwise returns FALSE.
+
+ \sa collisions()
+*/
+
+
+/*!
+ \class TQCanvasSprite tqcanvas.h
+ \brief The TQCanvasSprite class provides an animated canvas item on a TQCanvas.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ A canvas sprite is an object which can contain any number of images
+ (referred to as frames), only one of which is current, i.e.
+ displayed, at any one time. The images can be passed in the
+ constructor or set or changed later with setSequence(). If you
+ subclass TQCanvasSprite you can change the frame that is displayed
+ periodically, e.g. whenever TQCanvasItem::advance(1) is called to
+ create the effect of animation.
+
+ The current frame can be set with setFrame() or with move(). The
+ number of frames available is given by frameCount(). The bounding
+ rectangle of the current frame is returned by boundingRect().
+
+ The current frame's image can be retrieved with image(); use
+ imageAdvanced() to retrieve the image for the frame that will be
+ shown after advance(1) is called. Use the image() overload passing
+ it an integer index to retrieve a particular image from the list of
+ frames.
+
+ Use width() and height() to retrieve the dimensions of the current
+ frame.
+
+ Use leftEdge() and rightEdge() to retrieve the current frame's
+ left-hand and right-hand x-coordinates respectively. Use
+ bottomEdge() and topEdge() to retrieve the current frame's bottom
+ and top y-coordinates respectively. These functions have an overload
+ which will accept an integer frame number to retrieve the
+ coordinates of a particular frame.
+
+ TQCanvasSprite draws very quickly, at the expense of memory.
+
+ The current frame's image can be drawn on a painter with draw().
+
+ Like any other canvas item, canvas sprites can be moved with
+ move() which sets the x and y coordinates and the frame number, as
+ well as with TQCanvasItem::move() and TQCanvasItem::moveBy(), or by
+ setting coordinates with TQCanvasItem::setX(), TQCanvasItem::setY()
+ and TQCanvasItem::setZ().
+
+*/
+
+
+/*!
+ \reimp
+*/
+bool TQCanvasSprite::collidesWith( const TQCanvasItem* i ) const
+{
+ return i->collidesWith(this,0,0,0,0);
+}
+
+/*!
+ Returns TRUE if the canvas item collides with any of the given
+ items; otherwise returns FALSE. The parameters, \a s, \a p, \a r,
+ \a e and \a t, are all the same object, this is just a type
+ resolution trick.
+*/
+bool TQCanvasSprite::collidesWith( const TQCanvasSprite* s,
+ const TQCanvasPolygonalItem* p,
+ const TQCanvasRectangle* r,
+ const TQCanvasEllipse* e,
+ const TQCanvasText* t ) const
+{
+ return collision_double_dispatch(s,p,r,e,t,this,0,0,0,0);
+}
+
+/*!
+ \reimp
+*/
+bool TQCanvasPolygonalItem::collidesWith( const TQCanvasItem* i ) const
+{
+ return i->collidesWith(0,this,0,0,0);
+}
+
+bool TQCanvasPolygonalItem::collidesWith( const TQCanvasSprite* s,
+ const TQCanvasPolygonalItem* p,
+ const TQCanvasRectangle* r,
+ const TQCanvasEllipse* e,
+ const TQCanvasText* t ) const
+{
+ return collision_double_dispatch(s,p,r,e,t,0,this,0,0,0);
+}
+
+/*!
+ \reimp
+*/
+bool TQCanvasRectangle::collidesWith( const TQCanvasItem* i ) const
+{
+ return i->collidesWith(0,this,this,0,0);
+}
+
+bool TQCanvasRectangle::collidesWith( const TQCanvasSprite* s,
+ const TQCanvasPolygonalItem* p,
+ const TQCanvasRectangle* r,
+ const TQCanvasEllipse* e,
+ const TQCanvasText* t ) const
+{
+ return collision_double_dispatch(s,p,r,e,t,0,this,this,0,0);
+}
+
+
+/*!
+ \reimp
+*/
+bool TQCanvasEllipse::collidesWith( const TQCanvasItem* i ) const
+{
+ return i->collidesWith(0,this,0,this,0);
+}
+
+bool TQCanvasEllipse::collidesWith( const TQCanvasSprite* s,
+ const TQCanvasPolygonalItem* p,
+ const TQCanvasRectangle* r,
+ const TQCanvasEllipse* e,
+ const TQCanvasText* t ) const
+{
+ return collision_double_dispatch(s,p,r,e,t,0,this,0,this,0);
+}
+
+/*!
+ \reimp
+*/
+bool TQCanvasText::collidesWith( const TQCanvasItem* i ) const
+{
+ return i->collidesWith(0,0,0,0,this);
+}
+
+bool TQCanvasText::collidesWith( const TQCanvasSprite* s,
+ const TQCanvasPolygonalItem* p,
+ const TQCanvasRectangle* r,
+ const TQCanvasEllipse* e,
+ const TQCanvasText* t ) const
+{
+ return collision_double_dispatch(s,p,r,e,t,0,0,0,0,this);
+}
+
+/*!
+ Returns the list of canvas items that this canvas item has
+ collided with.
+
+ A collision is generally defined as occurring when the pixels of
+ one item draw on the pixels of another item, but not all
+ subclasses are so precise. Also, since pixel-wise collision
+ detection can be slow, this function works in either exact or
+ inexact mode, according to the \a exact parameter.
+
+ If \a exact is TRUE, the canvas items returned have been
+ accurately tested for collision with the canvas item.
+
+ If \a exact is FALSE, the canvas items returned are \e near the
+ canvas item. You can test the canvas items returned using
+ collidesWith() if any are interesting collision candidates. By
+ using this approach, you can ignore some canvas items for which
+ collisions are not relevant.
+
+ The returned list is a list of TQCanvasItems, but often you will
+ need to cast the items to their subclass types. The safe way to do
+ this is to use rtti() before casting. This provides some of the
+ functionality of the standard C++ dynamic cast operation even on
+ compilers where dynamic casts are not available.
+
+ Note that a canvas item may be `on' a canvas, e.g. it was created
+ with the canvas as parameter, even though its coordinates place it
+ beyond the edge of the canvas's area. Collision detection only
+ works for canvas items which are wholly or partly within the
+ canvas's area.
+
+ Note that if items have a velocity (see \l setVelocity()), then
+ collision testing is done based on where the item \e will be when
+ it moves, not its current location. For example, a "ball" item
+ doesn't need to actually embed into a "wall" item before a
+ collision is detected. For items without velocity, plain
+ intersection is used.
+*/
+TQCanvasItemList TQCanvasItem::collisions(bool exact) const
+{
+ return canvas()->collisions(chunks(),this,exact);
+}
+
+/*!
+ Returns a list of canvas items that collide with the point \a p.
+ The list is ordered by z coordinates, from highest z coordinate
+ (front-most item) to lowest z coordinate (rear-most item).
+*/
+TQCanvasItemList TQCanvas::collisions(const TQPoint& p) const
+{
+ return collisions(TQRect(p,TQSize(1,1)));
+}
+
+/*!
+ \overload
+
+ Returns a list of items which collide with the rectangle \a r. The
+ list is ordered by z coordinates, from highest z coordinate
+ (front-most item) to lowest z coordinate (rear-most item).
+*/
+TQCanvasItemList TQCanvas::collisions(const TQRect& r) const
+{
+ TQCanvasRectangle i(r,(TQCanvas*)this);
+ i.setPen(Qt::NoPen);
+ i.show(); // doesn't actually show, since we destroy it
+ TQCanvasItemList l = i.collisions(TRUE);
+ l.sort();
+ return l;
+}
+
+/*!
+ \overload
+
+ Returns a list of canvas items which intersect with the chunks
+ listed in \a chunklist, excluding \a item. If \a exact is TRUE,
+ only those which actually \link TQCanvasItem::collidesWith()
+ collide with\endlink \a item are returned; otherwise canvas items
+ are included just for being in the chunks.
+
+ This is a utility function mainly used to implement the simpler
+ TQCanvasItem::collisions() function.
+*/
+TQCanvasItemList TQCanvas::collisions(const TQPointArray& chunklist,
+ const TQCanvasItem* item, bool exact) const
+{
+ TQPtrDict<void> seen;
+ TQCanvasItemList result;
+ for (int i=0; i<(int)chunklist.count(); i++) {
+ int x = chunklist[i].x();
+ int y = chunklist[i].y();
+ if ( validChunk(x,y) ) {
+ const TQCanvasItemList* l = chunk(x,y).listPtr();
+ for (TQCanvasItemList::ConstIterator it=l->begin(); it!=l->end(); ++it) {
+ TQCanvasItem *g=*it;
+ if ( g != item ) {
+ if ( !seen.tqfind(g) ) {
+ seen.tqreplace(g,(void*)1);
+ if ( !exact || item->collidesWith(g) )
+ result.append(g);
+ }
+ }
+ }
+ }
+ }
+ return result;
+}
+
+/*!
+ \internal
+ Adds the item to all the chunks it covers.
+*/
+void TQCanvasItem::addToChunks()
+{
+ if (isVisible() && canvas()) {
+ TQPointArray pa = chunks();
+ for (int i=0; i<(int)pa.count(); i++)
+ canvas()->addItemToChunk(this,pa[i].x(),pa[i].y());
+ val=(uint)TRUE;
+ }
+}
+
+/*!
+ \internal
+ Removes the item from all the chunks it covers.
+*/
+void TQCanvasItem::removeFromChunks()
+{
+ if (isVisible() && canvas()) {
+ TQPointArray pa = chunks();
+ for (int i=0; i<(int)pa.count(); i++)
+ canvas()->removeItemFromChunk(this,pa[i].x(),pa[i].y());
+ }
+}
+
+/*!
+ \internal
+ Sets all the chunks covered by the item to be refreshed with TQCanvas::update()
+ is next called.
+*/
+void TQCanvasItem::changeChunks()
+{
+ if (isVisible() && canvas()) {
+ if (!val)
+ addToChunks();
+ TQPointArray pa = chunks();
+ for (int i=0; i<(int)pa.count(); i++)
+ canvas()->setChangedChunk(pa[i].x(),pa[i].y());
+ }
+}
+
+/*!
+ \fn TQRect TQCanvasItem::boundingRect() const
+
+ Returns the bounding rectangle in pixels that the canvas item covers.
+
+ \sa boundingRectAdvanced()
+*/
+
+/*!
+ Returns the bounding rectangle of pixels that the canvas item \e
+ will cover after advance(1) is called.
+
+ \sa boundingRect()
+*/
+TQRect TQCanvasItem::boundingRectAdvanced() const
+{
+ int dx = int(x()+xVelocity())-int(x());
+ int dy = int(y()+yVelocity())-int(y());
+ TQRect r = boundingRect();
+ r.moveBy(dx,dy);
+ return r;
+}
+
+/*!
+ \class TQCanvasPixmap tqcanvas.h
+ \brief The TQCanvasPixmap class provides pixmaps for TQCanvasSprites.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ If you want to show a single pixmap on a TQCanvas use a
+ TQCanvasSprite with just one pixmap.
+
+ When pixmaps are inserted into a TQCanvasPixmapArray they are held
+ as TQCanvasPixmaps. \l{TQCanvasSprite}s are used to show pixmaps on
+ \l{TQCanvas}es and hold their pixmaps in a TQCanvasPixmapArray. If
+ you retrieve a frame (pixmap) from a TQCanvasSprite it will be
+ returned as a TQCanvasPixmap.
+
+ The pixmap is a TQPixmap and can only be set in the constructor.
+ There are three different constructors, one taking a TQPixmap, one
+ a TQImage and one a file name that refers to a file in any
+ supported file format (see TQImageIO).
+
+ TQCanvasPixmap can have a hotspot which is defined in terms of an (x,
+ y) offset. When you create a TQCanvasPixmap from a PNG file or from
+ a TQImage that has a TQImage::offset(), the offset() is initialized
+ appropriately, otherwise the constructor leaves it at (0, 0). You
+ can set it later using setOffset(). When the TQCanvasPixmap is used
+ in a TQCanvasSprite, the offset position is the point at
+ TQCanvasItem::x() and TQCanvasItem::y(), not the top-left corner of
+ the pixmap.
+
+ Note that for TQCanvasPixmap objects created by a TQCanvasSprite, the
+ position of each TQCanvasPixmap object is set so that the hotspot
+ stays in the same position.
+
+ \sa TQCanvasPixmapArray TQCanvasItem TQCanvasSprite
+*/
+
+#ifndef TQT_NO_IMAGEIO
+
+/*!
+ Constructs a TQCanvasPixmap that uses the image stored in \a
+ datafilename.
+*/
+TQCanvasPixmap::TQCanvasPixmap(const TQString& datafilename)
+{
+ TQImage image(datafilename);
+ init(image);
+}
+
+#endif
+
+/*!
+ Constructs a TQCanvasPixmap from the image \a image.
+*/
+TQCanvasPixmap::TQCanvasPixmap(const TQImage& image)
+{
+ init(image);
+}
+/*!
+ Constructs a TQCanvasPixmap from the pixmap \a pm using the offset
+ \a offset.
+*/
+TQCanvasPixmap::TQCanvasPixmap(const TQPixmap& pm, const TQPoint& offset)
+{
+ init(pm,offset.x(),offset.y());
+}
+
+void TQCanvasPixmap::init(const TQImage& image)
+{
+ convertFromImage(image);
+ hotx = image.offset().x();
+ hoty = image.offset().y();
+#ifndef TQT_NO_IMAGE_DITHER_TO_1
+ if( image.hasAlphaBuffer() ) {
+ TQImage i = image.createAlphaMask();
+ collision_mask = new TQImage(i);
+ } else
+#endif
+ collision_mask = 0;
+}
+
+void TQCanvasPixmap::init(const TQPixmap& pixmap, int hx, int hy)
+{
+ (TQPixmap&)*this = pixmap;
+ hotx = hx;
+ hoty = hy;
+ if( pixmap.tqmask() ) {
+ TQImage i = tqmask()->convertToImage();
+ collision_mask = new TQImage(i);
+ } else
+ collision_mask = 0;
+}
+
+/*!
+ Destroys the pixmap.
+*/
+TQCanvasPixmap::~TQCanvasPixmap()
+{
+ delete collision_mask;
+}
+
+/*!
+ \fn int TQCanvasPixmap::offsetX() const
+
+ Returns the x-offset of the pixmap's hotspot.
+
+ \sa setOffset()
+*/
+
+/*!
+ \fn int TQCanvasPixmap::offsetY() const
+
+ Returns the y-offset of the pixmap's hotspot.
+
+ \sa setOffset()
+*/
+
+/*!
+ \fn void TQCanvasPixmap::setOffset(int x, int y)
+
+ Sets the offset of the pixmap's hotspot to (\a x, \a y).
+
+ \warning Do not call this function if any TQCanvasSprites are
+ currently showing this pixmap.
+*/
+
+/*!
+ \class TQCanvasPixmapArray tqcanvas.h
+ \brief The TQCanvasPixmapArray class provides an array of TQCanvasPixmaps.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+
+ This class is used by TQCanvasSprite to hold an array of pixmaps.
+ It is used to implement animated sprites, i.e. images that change
+ over time, with each pixmap in the array holding one frame.
+
+ Depending on the constructor you use you can load multiple pixmaps
+ into the array either from a directory (specifying a wildcard
+ pattern for the files), or from a list of TQPixmaps. You can also
+ read in a set of pixmaps after construction using readPixmaps().
+
+ Individual pixmaps can be set with setImage() and retrieved with
+ image(). The number of pixmaps in the array is returned by
+ count().
+
+ TQCanvasSprite uses an image's tqmask for collision detection. You
+ can change this by reading in a separate set of image masks using
+ readCollisionMasks().
+
+*/
+
+/*!
+ Constructs an invalid array (i.e. isValid() will return FALSE).
+ You must call readPixmaps() before being able to use this
+ TQCanvasPixmapArray.
+*/
+TQCanvasPixmapArray::TQCanvasPixmapArray()
+: framecount( 0 ), img( 0 )
+{
+}
+
+#ifndef TQT_NO_IMAGEIO
+/*!
+ Constructs a TQCanvasPixmapArray from files.
+
+ The \a fc parameter sets the number of frames to be loaded for
+ this image.
+
+ If \a fc is not 0, \a datafilenamepattern should contain "%1",
+ e.g. "foo%1.png". The actual filenames are formed by replacing the
+ %1 with four-digit integers from 0 to (fc - 1), e.g. foo0000.png,
+ foo0001.png, foo0002.png, etc.
+
+ If \a fc is 0, \a datafilenamepattern is asssumed to be a
+ filename, and the image contained in this file will be loaded as
+ the first (and only) frame.
+
+ If \a datafilenamepattern does not exist, is not readable, isn't
+ an image, or some other error occurs, the array ends up empty and
+ isValid() returns FALSE.
+*/
+
+TQCanvasPixmapArray::TQCanvasPixmapArray( const TQString& datafilenamepattern,
+ int fc )
+: framecount( 0 ), img( 0 )
+{
+ readPixmaps(datafilenamepattern,fc);
+}
+#endif
+
+/*!
+ \obsolete
+ Use TQCanvasPixmapArray::TQCanvasPixmapArray( TQValueList<TQPixmap>, TQPointArray )
+ instead.
+
+ Constructs a TQCanvasPixmapArray from the list of TQPixmaps \a
+ list. The \a hotspots list has to be of the same size as \a list.
+*/
+TQCanvasPixmapArray::TQCanvasPixmapArray(TQPtrList<TQPixmap> list, TQPtrList<TQPoint> hotspots) :
+ framecount(list.count()),
+ img(new TQCanvasPixmap*[list.count()])
+{
+ if (list.count() != hotspots.count()) {
+ qWarning("TQCanvasPixmapArray: lists have different lengths");
+ reset();
+ img = 0;
+ } else {
+ list.first();
+ hotspots.first();
+ for (int i=0; i<framecount; i++) {
+ img[i]=new TQCanvasPixmap(*list.current(), *hotspots.current());
+ list.next();
+ hotspots.next();
+ }
+ }
+}
+
+/*!
+ Constructs a TQCanvasPixmapArray from the list of TQPixmaps in the
+ \a list. Each pixmap will get a hotspot according to the \a
+ hotspots array. If no hotspots are specified, each one is set to
+ be at position (0, 0).
+
+ If an error occurs, isValid() will return FALSE.
+*/
+TQCanvasPixmapArray::TQCanvasPixmapArray(TQValueList<TQPixmap> list, TQPointArray hotspots) :
+ framecount((int)list.size()),
+ img(new TQCanvasPixmap*[list.size()])
+{
+ bool have_hotspots = ( hotspots.size() != 0 );
+ if (have_hotspots && list.count() != hotspots.count()) {
+ qWarning("TQCanvasPixmapArray: lists have different lengths");
+ reset();
+ img = 0;
+ } else {
+ TQValueList<TQPixmap>::iterator it;
+ it = list.begin();
+ for (int i=0; i<framecount; i++) {
+ TQPoint hs = have_hotspots ? hotspots[i] : TQPoint( 0, 0 );
+ img[i]=new TQCanvasPixmap( *it, hs );
+ ++it;
+ }
+ }
+}
+
+/*!
+ Destroys the pixmap array and all the pixmaps it tqcontains.
+*/
+TQCanvasPixmapArray::~TQCanvasPixmapArray()
+{
+ reset();
+}
+
+void TQCanvasPixmapArray::reset()
+{
+ for (int i=0; i<framecount; i++)
+ delete img[i];
+ delete [] img;
+ img = 0;
+ framecount = 0;
+}
+
+#ifndef TQT_NO_IMAGEIO
+/*!
+ Reads one or more pixmaps into the pixmap array.
+
+ If \a fc is not 0, \a filenamepattern should contain "%1", e.g.
+ "foo%1.png". The actual filenames are formed by replacing the %1
+ with four-digit integers from 0 to (fc - 1), e.g. foo0000.png,
+ foo0001.png, foo0002.png, etc.
+
+ If \a fc is 0, \a filenamepattern is asssumed to be a filename,
+ and the image contained in this file will be loaded as the first
+ (and only) frame.
+
+ If \a filenamepattern does not exist, is not readable, isn't an
+ image, or some other error occurs, this function will return
+ FALSE, and isValid() will return FALSE; otherwise this function
+ will return TRUE.
+
+ \sa isValid()
+*/
+bool TQCanvasPixmapArray::readPixmaps( const TQString& filenamepattern,
+ int fc)
+{
+ return readPixmaps(filenamepattern,fc,FALSE);
+}
+
+/*!
+ Reads new collision masks for the array.
+
+ By default, TQCanvasSprite uses the image tqmask of a sprite to
+ detect collisions. Use this function to set your own collision
+ image masks.
+
+ If count() is 1 \a filename must specify a real filename to read
+ the tqmask from. If count() is greater than 1, the \a filename must
+ contain a "%1" that will get tqreplaced by the number of the tqmask to
+ be loaded, just like TQCanvasPixmapArray::readPixmaps().
+
+ All collision masks must be 1-bit images or this function call
+ will fail.
+
+ If the file isn't readable, tqcontains the wrong number of images,
+ or there is some other error, this function will return FALSE, and
+ the array will be flagged as invalid; otherwise this function
+ returns TRUE.
+
+ \sa isValid()
+*/
+bool TQCanvasPixmapArray::readCollisionMasks(const TQString& filename)
+{
+ return readPixmaps(filename,framecount,TRUE);
+}
+
+
+bool TQCanvasPixmapArray::readPixmaps( const TQString& datafilenamepattern,
+ int fc, bool maskonly)
+{
+ if ( !maskonly ) {
+ reset();
+ framecount = fc;
+ if ( !framecount )
+ framecount=1;
+ img = new TQCanvasPixmap*[framecount];
+ }
+ if (!img)
+ return FALSE;
+ bool ok = TRUE;
+ bool arg = fc > 1;
+ if ( !arg )
+ framecount=1;
+ for (int i=0; i<framecount; i++) {
+ TQString r;
+ r.sprintf("%04d",i);
+ if ( maskonly ) {
+ if (!img[i]->collision_mask)
+ img[i]->collision_mask = new TQImage();
+ img[i]->collision_mask->load(
+ arg ? TQT_TQSTRING(datafilenamepattern.arg(r)) : datafilenamepattern);
+ ok = ok
+ && !img[i]->collision_mask->isNull()
+ && img[i]->collision_mask->depth()==1;
+ } else {
+ img[i]=new TQCanvasPixmap(
+ arg ? TQT_TQSTRING(datafilenamepattern.arg(r)) : datafilenamepattern);
+ ok = ok && !img[i]->isNull();
+ }
+ }
+ if ( !ok ) {
+ reset();
+ }
+ return ok;
+}
+#endif
+
+/*!
+ \obsolete
+
+ Use isValid() instead.
+
+ This returns FALSE if the array is valid, and TRUE if it is not.
+*/
+bool TQCanvasPixmapArray::operator!()
+{
+ return img==0;
+}
+
+/*!
+ Returns TRUE if the pixmap array is valid; otherwise returns
+ FALSE.
+*/
+bool TQCanvasPixmapArray::isValid() const
+{
+ return (img != 0);
+}
+
+/*!
+ \fn TQCanvasPixmap* TQCanvasPixmapArray::image(int i) const
+
+ Returns pixmap \a i in the array, if \a i is non-negative and less
+ than than count(), and returns an unspecified value otherwise.
+*/
+
+// ### wouldn't it be better to put empty TQCanvasPixmaps in there instead of
+// initializing the additional elements in the array to 0? Lars
+/*!
+ Replaces the pixmap at index \a i with pixmap \a p.
+
+ The array takes ownership of \a p and will delete \a p when the
+ array itself is deleted.
+
+ If \a i is beyond the end of the array the array is extended to at
+ least i+1 elements, with elements count() to i-1 being initialized
+ to 0.
+*/
+void TQCanvasPixmapArray::setImage(int i, TQCanvasPixmap* p)
+{
+ if ( i >= framecount ) {
+ TQCanvasPixmap** newimg = new TQCanvasPixmap*[i+1];
+ memcpy(newimg, img, sizeof( TQCanvasPixmap * )*framecount);
+ memset(newimg + framecount, 0, sizeof( TQCanvasPixmap * )*( i+1 - framecount ) );
+ framecount = i+1;
+ delete [] img;
+ img = newimg;
+ }
+ delete img[i]; img[i]=p;
+}
+
+/*!
+ \fn uint TQCanvasPixmapArray::count() const
+
+ Returns the number of pixmaps in the array.
+*/
+
+/*!
+ Returns the x-coordinate of the current left edge of the sprite.
+ (This may change as the sprite animates since different frames may
+ have different left edges.)
+
+ \sa rightEdge() bottomEdge() topEdge()
+*/
+int TQCanvasSprite::leftEdge() const
+{
+ return int(x()) - image()->hotx;
+}
+
+/*!
+ \overload
+
+ Returns what the x-coordinate of the left edge of the sprite would
+ be if the sprite (actually its hotspot) were moved to x-position
+ \a nx.
+
+ \sa rightEdge() bottomEdge() topEdge()
+*/
+int TQCanvasSprite::leftEdge(int nx) const
+{
+ return nx - image()->hotx;
+}
+
+/*!
+ Returns the y-coordinate of the top edge of the sprite. (This may
+ change as the sprite animates since different frames may have
+ different top edges.)
+
+ \sa leftEdge() rightEdge() bottomEdge()
+*/
+int TQCanvasSprite::topEdge() const
+{
+ return int(y()) - image()->hoty;
+}
+
+/*!
+ \overload
+
+ Returns what the y-coordinate of the top edge of the sprite would
+ be if the sprite (actually its hotspot) were moved to y-position
+ \a ny.
+
+ \sa leftEdge() rightEdge() bottomEdge()
+*/
+int TQCanvasSprite::topEdge(int ny) const
+{
+ return ny - image()->hoty;
+}
+
+/*!
+ Returns the x-coordinate of the current right edge of the sprite.
+ (This may change as the sprite animates since different frames may
+ have different right edges.)
+
+ \sa leftEdge() bottomEdge() topEdge()
+*/
+int TQCanvasSprite::rightEdge() const
+{
+ return leftEdge() + image()->width()-1;
+}
+
+/*!
+ \overload
+
+ Returns what the x-coordinate of the right edge of the sprite
+ would be if the sprite (actually its hotspot) were moved to
+ x-position \a nx.
+
+ \sa leftEdge() bottomEdge() topEdge()
+*/
+int TQCanvasSprite::rightEdge(int nx) const
+{
+ return leftEdge(nx) + image()->width()-1;
+}
+
+/*!
+ Returns the y-coordinate of the current bottom edge of the sprite.
+ (This may change as the sprite animates since different frames may
+ have different bottom edges.)
+
+ \sa leftEdge() rightEdge() topEdge()
+*/
+int TQCanvasSprite::bottomEdge() const
+{
+ return topEdge() + image()->height()-1;
+}
+
+/*!
+ \overload
+
+ Returns what the y-coordinate of the top edge of the sprite would
+ be if the sprite (actually its hotspot) were moved to y-position
+ \a ny.
+
+ \sa leftEdge() rightEdge() topEdge()
+*/
+int TQCanvasSprite::bottomEdge(int ny) const
+{
+ return topEdge(ny) + image()->height()-1;
+}
+
+/*!
+ \fn TQCanvasPixmap* TQCanvasSprite::image() const
+
+ Returns the current frame's image.
+
+ \sa frame(), setFrame()
+*/
+
+/*!
+ \fn TQCanvasPixmap* TQCanvasSprite::image(int f) const
+ \overload
+
+ Returns the image for frame \a f. Does not do any bounds checking on \a f.
+*/
+
+/*!
+ Returns the image the sprite \e will have after advance(1) is
+ called. By default this is the same as image().
+*/
+TQCanvasPixmap* TQCanvasSprite::imageAdvanced() const
+{
+ return image();
+}
+
+/*!
+ Returns the bounding rectangle for the image in the sprite's
+ current frame. This assumes that the images are tightly cropped
+ (i.e. do not have transtqparent pixels all along a side).
+*/
+TQRect TQCanvasSprite::boundingRect() const
+{
+ return TQRect(leftEdge(), topEdge(), width(), height());
+}
+
+
+/*!
+ \internal
+ Returns the chunks covered by the item.
+*/
+TQPointArray TQCanvasItem::chunks() const
+{
+ TQPointArray r;
+ int n=0;
+ TQRect br = boundingRect();
+ if (isVisible() && canvas()) {
+ int chunksize=canvas()->chunkSize();
+ br &= TQRect(0,0,canvas()->width(),canvas()->height());
+ if ( br.isValid() ) {
+ r.resize((br.width()/chunksize+2)*(br.height()/chunksize+2));
+ for (int j=br.top()/chunksize; j<=br.bottom()/chunksize; j++) {
+ for (int i=br.left()/chunksize; i<=br.right()/chunksize; i++) {
+ r[n++] = TQPoint(i,j);
+ }
+ }
+ }
+ }
+ r.resize(n);
+ return r;
+}
+
+
+/*!
+ \internal
+ Add the sprite to the chunks in its TQCanvas which it overlaps.
+*/
+void TQCanvasSprite::addToChunks()
+{
+ if (isVisible() && canvas()) {
+ int chunksize=canvas()->chunkSize();
+ for (int j=topEdge()/chunksize; j<=bottomEdge()/chunksize; j++) {
+ for (int i=leftEdge()/chunksize; i<=rightEdge()/chunksize; i++) {
+ canvas()->addItemToChunk(this,i,j);
+ }
+ }
+ }
+}
+
+/*!
+ \internal
+ Remove the sprite from the chunks in its TQCanvas which it overlaps.
+
+ \sa addToChunks()
+*/
+void TQCanvasSprite::removeFromChunks()
+{
+ if (isVisible() && canvas()) {
+ int chunksize=canvas()->chunkSize();
+ for (int j=topEdge()/chunksize; j<=bottomEdge()/chunksize; j++) {
+ for (int i=leftEdge()/chunksize; i<=rightEdge()/chunksize; i++) {
+ canvas()->removeItemFromChunk(this,i,j);
+ }
+ }
+ }
+}
+
+/*!
+ The width of the sprite for the current frame's image.
+
+ \sa frame()
+*/
+//### mark: Why don't we have width(int) and height(int) to be
+//consistent with leftEdge() and leftEdge(int)?
+int TQCanvasSprite::width() const
+{
+ return image()->width();
+}
+
+/*!
+ The height of the sprite for the current frame's image.
+
+ \sa frame()
+*/
+int TQCanvasSprite::height() const
+{
+ return image()->height();
+}
+
+
+/*!
+ Draws the current frame's image at the sprite's current position
+ on painter \a painter.
+*/
+void TQCanvasSprite::draw(TQPainter& painter)
+{
+ painter.drawPixmap(leftEdge(),topEdge(),*image());
+}
+
+/*!
+ \class TQCanvasView tqcanvas.h
+ \brief The TQCanvasView class provides an on-screen view of a TQCanvas.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ A TQCanvasView is widget which provides a view of a TQCanvas.
+
+ If you want users to be able to interact with a canvas view,
+ subclass TQCanvasView. You might then reimplement
+ TQScrollView::contentsMousePressEvent(). For example, assuming no
+ transformation matrix is set:
+
+ \code
+ void MyCanvasView::contentsMousePressEvent( TQMouseEvent* e )
+ {
+ TQCanvasItemList l = canvas()->collisions(e->pos());
+ for (TQCanvasItemList::Iterator it=l.begin(); it!=l.end(); ++it) {
+ if ( (*it)->rtti() == TQCanvasRectangle::RTTI )
+ qDebug("A TQCanvasRectangle lies somewhere at this point");
+ }
+ }
+ \endcode
+
+ The canvas view shows canvas canvas(); this can be changed using
+ setCanvas().
+
+ A transformation matrix can be used to transform the view of the
+ canvas in various ways, for example, zooming in or out or rotating.
+ For example:
+
+ \code
+ TQWMatrix wm;
+ wm.scale( 2, 2 ); // Zooms in by 2 times
+ wm.rotate( 90 ); // Rotates 90 degrees counter clockwise
+ // around the origin.
+ wm.translate( 0, -canvas->height() );
+ // moves the canvas down so what was visible
+ // before is still visible.
+ myCanvasView->setWorldMatrix( wm );
+ \endcode
+
+ Use setWorldMatrix() to set the canvas view's world matrix: you must
+ ensure that the world matrix is invertible. The current world matrix
+ is retrievable with tqworldMatrix(), and its inversion is retrievable
+ with inverseWorldMatrix().
+
+ Example:
+
+ The following code tqfinds the part of the canvas that is visible in
+ this view, i.e. the bounding rectangle of the view in canvas coordinates.
+
+ \code
+ TQRect rc = TQRect( myCanvasView->contentsX(), myCanvasView->contentsY(),
+ myCanvasView->visibleWidth(), myCanvasView->visibleHeight() );
+ TQRect canvasRect = myCanvasView->inverseWorldMatrix().mapRect(rc);
+ \endcode
+
+ \sa TQWMatrix TQPainter::setWorldMatrix()
+
+*/
+
+/*!
+ Constructs a TQCanvasView with tqparent \a tqparent, and name \a name,
+ using the widget flags \a f. The canvas view is not associated
+ with a canvas, so you must to call setCanvas() to view a
+ canvas.
+*/
+TQCanvasView::TQCanvasView(TQWidget* tqparent, const char* name, WFlags f) :
+ TQScrollView(tqparent,name,(WFlags)(f|TQt::WResizeNoErase|TQt::WStaticContents))
+{
+ d = new TQCanvasViewData;
+ viewing = 0;
+ setCanvas(0);
+ connect(this,TQT_SIGNAL(contentsMoving(int,int)),this,TQT_SLOT(cMoving(int,int)));
+}
+
+/*!
+ \overload
+
+ Constructs a TQCanvasView which views canvas \a canvas, with tqparent
+ \a tqparent, and name \a name, using the widget flags \a f.
+*/
+TQCanvasView::TQCanvasView(TQCanvas* canvas, TQWidget* tqparent, const char* name, WFlags f) :
+ TQScrollView(tqparent,name,(WFlags)(f|TQt::WResizeNoErase|TQt::WStaticContents))
+{
+ d = new TQCanvasViewData;
+ viewing = 0;
+ setCanvas(canvas);
+
+ connect(this,TQT_SIGNAL(contentsMoving(int,int)),this,TQT_SLOT(cMoving(int,int)));
+}
+
+/*!
+ Destroys the canvas view. The associated canvas is \e not deleted.
+*/
+TQCanvasView::~TQCanvasView()
+{
+ delete d;
+ d = 0;
+ setCanvas(0);
+}
+
+/*!
+ \fn TQCanvas* TQCanvasView::canvas() const
+
+ Returns a pointer to the canvas which the TQCanvasView is currently
+ showing.
+*/
+
+
+/*!
+ Sets the canvas that the TQCanvasView is showing to the canvas \a
+ canvas.
+*/
+void TQCanvasView::setCanvas(TQCanvas* canvas)
+{
+ if (viewing) {
+ disconnect(viewing);
+ viewing->removeView(this);
+ }
+ viewing=canvas;
+ if (viewing) {
+ connect(viewing,TQT_SIGNAL(resized()), this, TQT_SLOT(updateContentsSize()));
+ viewing->addView(this);
+ }
+ if ( d ) // called by d'tor
+ updateContentsSize();
+}
+
+#ifndef TQT_NO_TRANSFORMATIONS
+/*!
+ Returns a reference to the canvas view's current transformation matrix.
+
+ \sa setWorldMatrix() inverseWorldMatrix()
+*/
+const TQWMatrix &TQCanvasView::tqworldMatrix() const
+{
+ return d->xform;
+}
+
+/*!
+ Returns a reference to the inverse of the canvas view's current
+ transformation matrix.
+
+ \sa setWorldMatrix() tqworldMatrix()
+*/
+const TQWMatrix &TQCanvasView::inverseWorldMatrix() const
+{
+ return d->ixform;
+}
+
+/*!
+ Sets the transformation matrix of the TQCanvasView to \a wm. The
+ matrix must be invertible (i.e. if you create a world matrix that
+ zooms out by 2 times, then the inverse of this matrix is one that
+ will zoom in by 2 times).
+
+ When you use this, you should note that the performance of the
+ TQCanvasView will decrease considerably.
+
+ Returns FALSE if \a wm is not invertable; otherwise returns TRUE.
+
+ \sa tqworldMatrix() inverseWorldMatrix() TQWMatrix::isInvertible()
+*/
+bool TQCanvasView::setWorldMatrix( const TQWMatrix & wm )
+{
+ bool ok = wm.isInvertible();
+ if ( ok ) {
+ d->xform = wm;
+ d->ixform = wm.invert();
+ updateContentsSize();
+ viewport()->update();
+ }
+ return ok;
+}
+#endif
+
+void TQCanvasView::updateContentsSize()
+{
+ if ( viewing ) {
+ TQRect br;
+#ifndef TQT_NO_TRANSFORMATIONS
+ br = d->xform.map(TQRect(0,0,viewing->width(),viewing->height()));
+#else
+ br = TQRect(0,0,viewing->width(),viewing->height());
+#endif
+
+ if ( br.width() < contentsWidth() ) {
+ TQRect r(contentsToViewport(TQPoint(br.width(),0)),
+ TQSize(contentsWidth()-br.width(),contentsHeight()));
+ viewport()->erase(r);
+ }
+ if ( br.height() < contentsHeight() ) {
+ TQRect r(contentsToViewport(TQPoint(0,br.height())),
+ TQSize(contentsWidth(),contentsHeight()-br.height()));
+ viewport()->erase(r);
+ }
+
+ resizeContents(br.width(),br.height());
+ } else {
+ viewport()->erase();
+ resizeContents(1,1);
+ }
+}
+
+void TQCanvasView::cMoving(int x, int y)
+{
+ // A little kludge to smooth up repaints when scrolling
+ int dx = x - contentsX();
+ int dy = y - contentsY();
+ d->repaint_from_moving = TQABS(dx) < width()/8 && TQABS(dy) < height()/8;
+}
+
+/*!
+ Repaints part of the TQCanvas that the canvas view is showing
+ starting at \a cx by \a cy, with a width of \a cw and a height of \a
+ ch using the painter \a p.
+
+ \warning When double buffering is enabled, drawContents() will
+ not respect the current settings of the painter when setting up
+ the painter for the double buffer (e.g., viewport() and
+ window()). Also, be aware that TQCanvas::update() bypasses
+ drawContents(), which means any reimplementation of
+ drawContents() is not called.
+
+ \sa TQCanvas::setDoubleBuffering()
+*/
+void TQCanvasView::drawContents(TQPainter *p, int cx, int cy, int cw, int ch)
+{
+ TQRect r(cx,cy,cw,ch);
+ if (viewing) {
+ //viewing->drawViewArea(this,p,r,TRUE);
+ viewing->drawViewArea(this,p,r,!d->repaint_from_moving);
+ d->repaint_from_moving = FALSE;
+ } else {
+ p->eraseRect(r);
+ }
+}
+
+/*!
+ \reimp
+ \internal
+
+ (Implemented to get rid of a compiler warning.)
+*/
+void TQCanvasView::drawContents( TQPainter * )
+{
+}
+
+/*!
+ Suggests a size sufficient to view the entire canvas.
+*/
+TQSize TQCanvasView::tqsizeHint() const
+{
+ if ( !canvas() )
+ return TQScrollView::tqsizeHint();
+ // should maybe take transformations into account
+ return ( canvas()->size() + 2 * TQSize(frameWidth(), frameWidth()) )
+ .boundedTo( 3 * TQApplication::desktop()->size() / 4 );
+}
+
+// ### TQt 4.0 customer request: operate on doubles rather than int.
+// ### I know, almost impossible due to the use of TQRegion etc.
+/*!
+ \class TQCanvasPolygonalItem tqcanvas.h
+ \brief The TQCanvasPolygonalItem class provides a polygonal canvas item
+ on a TQCanvas.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ The mostly rectangular classes, such as TQCanvasSprite and
+ TQCanvasText, use the object's bounding rectangle for movement,
+ repainting and collision calculations. For most other items, the
+ bounding rectangle can be far too large -- a diagonal line being
+ the worst case, and there are many other cases which are also bad.
+ TQCanvasPolygonalItem provides polygon-based bounding rectangle
+ handling, etc., which is much faster for non-rectangular items.
+
+ Derived classes should try to define as small an area as possible
+ to maximize efficiency, but the polygon must \e definitely be
+ contained completely within the polygonal area. Calculating the
+ exact requirements is usually difficult, but if you allow a small
+ overestimate it can be easy and quick, while still getting almost
+ all of TQCanvasPolygonalItem's speed.
+
+ Note that all subclasses \e must call hide() in their destructor
+ since hide() needs to be able to access areaPoints().
+
+ Normally, TQCanvasPolygonalItem uses the odd-even algorithm for
+ determining whether an object intersects this object. You can
+ change this to the winding algorithm using setWinding().
+
+ The bounding rectangle is available using boundingRect(). The
+ points bounding the polygonal item are retrieved with
+ areaPoints(). Use areaPointsAdvanced() to retrieve the bounding
+ points the polygonal item \e will have after
+ TQCanvasItem::advance(1) has been called.
+
+ If the tqshape of the polygonal item is about to change while the
+ item is visible, call tqinvalidate() before updating with a
+ different result from \l areaPoints().
+
+ By default, TQCanvasPolygonalItem objects have a black pen and no
+ brush (the default TQPen and TQBrush constructors). You can change
+ this with setPen() and setBrush(), but note that some
+ TQCanvasPolygonalItem subclasses only use the brush, ignoring the
+ pen setting.
+
+ The polygonal item can be drawn on a painter with draw().
+ Subclasses must reimplement drawShape() to draw themselves.
+
+ Like any other canvas item polygonal items can be moved with
+ TQCanvasItem::move() and TQCanvasItem::moveBy(), or by setting coordinates
+ with TQCanvasItem::setX(), TQCanvasItem::setY() and TQCanvasItem::setZ().
+
+*/
+
+
+/*
+ Since most polygonal items don't have a pen, the default is
+ NoPen and a black brush.
+*/
+static const TQPen& defaultPolygonPen()
+{
+ static TQPen* dp=0;
+ if ( !dp )
+ dp = new TQPen;
+ return *dp;
+}
+
+static const TQBrush& defaultPolygonBrush()
+{
+ static TQBrush* db=0;
+ if ( !db )
+ db = new TQBrush;
+ return *db;
+}
+
+/*!
+ Constructs a TQCanvasPolygonalItem on the canvas \a canvas.
+*/
+TQCanvasPolygonalItem::TQCanvasPolygonalItem(TQCanvas* canvas) :
+ TQCanvasItem(canvas),
+ br(defaultPolygonBrush()),
+ pn(defaultPolygonPen())
+{
+ wind=0;
+}
+
+/*!
+ Note that all subclasses \e must call hide() in their destructor
+ since hide() needs to be able to access areaPoints().
+*/
+TQCanvasPolygonalItem::~TQCanvasPolygonalItem()
+{
+}
+
+/*!
+ Returns TRUE if the polygonal item uses the winding algorithm to
+ determine the "inside" of the polygon. Returns FALSE if it uses
+ the odd-even algorithm.
+
+ The default is to use the odd-even algorithm.
+
+ \sa setWinding()
+*/
+bool TQCanvasPolygonalItem::winding() const
+{
+ return wind;
+}
+
+/*!
+ If \a enable is TRUE, the polygonal item will use the winding
+ algorithm to determine the "inside" of the polygon; otherwise the
+ odd-even algorithm will be used.
+
+ The default is to use the odd-even algorithm.
+
+ \sa winding()
+*/
+void TQCanvasPolygonalItem::setWinding(bool enable)
+{
+ wind = enable;
+}
+
+/*!
+ Invalidates all information about the area covered by the canvas
+ item. The item will be updated automatically on the next call that
+ changes the item's status, for example, move() or update(). Call
+ this function if you are going to change the tqshape of the item (as
+ returned by areaPoints()) while the item is visible.
+*/
+void TQCanvasPolygonalItem::tqinvalidate()
+{
+ val = (uint)FALSE;
+ removeFromChunks();
+}
+
+/*!
+ \fn TQCanvasPolygonalItem::isValid() const
+
+ Returns TRUE if the polygonal item's area information has not been
+ invalidated; otherwise returns FALSE.
+
+ \sa tqinvalidate()
+*/
+
+/*!
+ Returns the points the polygonal item \e will have after
+ TQCanvasItem::advance(1) is called, i.e. what the points are when
+ advanced by the current xVelocity() and yVelocity().
+*/
+TQPointArray TQCanvasPolygonalItem::areaPointsAdvanced() const
+{
+ int dx = int(x()+xVelocity())-int(x());
+ int dy = int(y()+yVelocity())-int(y());
+ TQPointArray r = areaPoints();
+ r.detach(); // Explicit sharing is stupid.
+ if ( dx || dy )
+ r.translate(dx,dy);
+ return r;
+}
+
+//#define TQCANVAS_POLYGONS_DEBUG
+#ifdef TQCANVAS_POLYGONS_DEBUG
+static TQWidget* dbg_wid=0;
+static TQPainter* dbg_ptr=0;
+#endif
+
+class TQPolygonalProcessor {
+public:
+ TQPolygonalProcessor(TQCanvas* c, const TQPointArray& pa) :
+ canvas(c)
+ {
+ TQRect pixelbounds = pa.boundingRect();
+ int cs = canvas->chunkSize();
+ TQRect canvasbounds = pixelbounds.intersect(canvas->rect());
+ bounds.setLeft(canvasbounds.left()/cs);
+ bounds.setRight(canvasbounds.right()/cs);
+ bounds.setTop(canvasbounds.top()/cs);
+ bounds.setBottom(canvasbounds.bottom()/cs);
+ bitmap = TQImage(bounds.width() + 1, bounds.height(), 1, 2, TQImage::LittleEndian);
+ pnt = 0;
+ bitmap.fill(0);
+#ifdef TQCANVAS_POLYGONS_DEBUG
+ dbg_start();
+#endif
+ }
+
+ inline void add(int x, int y)
+ {
+ if ( pnt >= (int)result.size() ) {
+ result.resize(pnt*2+10);
+ }
+ result[pnt++] = TQPoint(x+bounds.x(),y+bounds.y());
+#ifdef TQCANVAS_POLYGONS_DEBUG
+ if ( dbg_ptr ) {
+ int cs = canvas->chunkSize();
+ TQRect r(x*cs+bounds.x()*cs,y*cs+bounds.y()*cs,cs-1,cs-1);
+ dbg_ptr->setPen(TQt::blue);
+ dbg_ptr->drawRect(r);
+ }
+#endif
+ }
+
+ inline void addBits(int x1, int x2, uchar newbits, int xo, int yo)
+ {
+ for (int i=x1; i<=x2; i++)
+ if ( newbits & (1<<i) )
+ add(xo+i,yo);
+ }
+
+#ifdef TQCANVAS_POLYGONS_DEBUG
+ void dbg_start()
+ {
+ if ( !dbg_wid ) {
+ dbg_wid = new TQWidget;
+ dbg_wid->resize(800,600);
+ dbg_wid->show();
+ dbg_ptr = new TQPainter(dbg_wid);
+ dbg_ptr->setBrush(TQt::NoBrush);
+ }
+ dbg_ptr->fillRect(dbg_wid->rect(),TQt::white);
+ }
+#endif
+
+ void doSpans(int n, TQPoint* pt, int* w)
+ {
+ int cs = canvas->chunkSize();
+ for (int j=0; j<n; j++) {
+ int y = pt[j].y()/cs-bounds.y();
+ if (y >= bitmap.height() || y < 0) continue;
+ uchar* l = bitmap.scanLine(y);
+ int x = pt[j].x();
+ int x1 = x/cs-bounds.x();
+ if (x1 > bounds.width()) continue;
+ x1 = TQMAX(0,x1);
+ int x2 = (x+w[j])/cs-bounds.x();
+ if (x2 < 0) continue;
+ x2 = TQMIN(bounds.width(), x2);
+ int x1q = x1/8;
+ int x1r = x1%8;
+ int x2q = x2/8;
+ int x2r = x2%8;
+#ifdef TQCANVAS_POLYGONS_DEBUG
+ if ( dbg_ptr ) dbg_ptr->setPen(TQt::yellow);
+#endif
+ if ( x1q == x2q ) {
+ uchar newbits = (~l[x1q]) & (((2<<(x2r-x1r))-1)<<x1r);
+ if ( newbits ) {
+#ifdef TQCANVAS_POLYGONS_DEBUG
+ if ( dbg_ptr ) dbg_ptr->setPen(TQt::darkGreen);
+#endif
+ addBits(x1r,x2r,newbits,x1q*8,y);
+ l[x1q] |= newbits;
+ }
+ } else {
+#ifdef TQCANVAS_POLYGONS_DEBUG
+ if ( dbg_ptr ) dbg_ptr->setPen(TQt::blue);
+#endif
+ uchar newbits1 = (~l[x1q]) & (0xff<<x1r);
+ if ( newbits1 ) {
+#ifdef TQCANVAS_POLYGONS_DEBUG
+ if ( dbg_ptr ) dbg_ptr->setPen(TQt::green);
+#endif
+ addBits(x1r,7,newbits1,x1q*8,y);
+ l[x1q] |= newbits1;
+ }
+ for (int i=x1q+1; i<x2q; i++) {
+ if ( l[i] != 0xff ) {
+ addBits(0,7,~l[i],i*8,y);
+ l[i]=0xff;
+ }
+ }
+ uchar newbits2 = (~l[x2q]) & (0xff>>(7-x2r));
+ if ( newbits2 ) {
+#ifdef TQCANVAS_POLYGONS_DEBUG
+ if ( dbg_ptr ) dbg_ptr->setPen(TQt::red);
+#endif
+ addBits(0,x2r,newbits2,x2q*8,y);
+ l[x2q] |= newbits2;
+ }
+ }
+#ifdef TQCANVAS_POLYGONS_DEBUG
+ if ( dbg_ptr ) {
+ dbg_ptr->drawLine(pt[j],pt[j]+TQPoint(w[j],0));
+ }
+#endif
+ }
+ result.resize(pnt);
+ }
+
+ int pnt;
+ TQPointArray result;
+ TQCanvas* canvas;
+ TQRect bounds;
+ TQImage bitmap;
+};
+
+
+TQPointArray TQCanvasPolygonalItem::chunks() const
+{
+ TQPointArray pa = areaPoints();
+
+ if ( !pa.size() ) {
+ pa.detach(); // Explicit sharing is stupid.
+ return pa;
+ }
+
+ TQPolygonalProcessor processor(canvas(),pa);
+
+ scanPolygon(pa, wind, processor);
+
+ return processor.result;
+}
+/*!
+ Simply calls TQCanvasItem::chunks().
+*/
+TQPointArray TQCanvasRectangle::chunks() const
+{
+ // No need to do a polygon scan!
+ return TQCanvasItem::chunks();
+}
+
+/*!
+ Returns the bounding rectangle of the polygonal item, based on
+ areaPoints().
+*/
+TQRect TQCanvasPolygonalItem::boundingRect() const
+{
+ return areaPoints().boundingRect();
+}
+
+/*!
+ Reimplemented from TQCanvasItem, this draws the polygonal item by
+ setting the pen and brush for the item on the painter \a p and
+ calling drawShape().
+*/
+void TQCanvasPolygonalItem::draw(TQPainter & p)
+{
+ p.setPen(pn);
+ p.setBrush(br);
+ drawShape(p);
+}
+
+/*!
+ \fn void TQCanvasPolygonalItem::drawShape(TQPainter & p)
+
+ Subclasses must reimplement this function to draw their tqshape. The
+ pen and brush of \a p are already set to pen() and brush() prior
+ to calling this function.
+
+ \warning When you reimplement this function, make sure that you
+ leave the painter in the same state as you found it. For example,
+ if you start by calling TQPainter::translate(50, 50), end your
+ code by calling TQPainter::translate(-50, -50). Be also aware that
+ the painter might already have some transformations set (i.e.,
+ don't call TQPainter::resetXForm() when you're done).
+
+ \sa draw()
+*/
+
+/*!
+ \fn TQPen TQCanvasPolygonalItem::pen() const
+
+ Returns the TQPen used to draw the outline of the item, if any.
+
+ \sa setPen()
+*/
+
+/*!
+ \fn TQBrush TQCanvasPolygonalItem::brush() const
+
+ Returns the TQBrush used to fill the item, if filled.
+
+ \sa setBrush()
+*/
+
+/*!
+ Sets the TQPen used when drawing the item to the pen \a p.
+ Note that many TQCanvasPolygonalItems do not use the pen value.
+
+ \sa setBrush(), pen(), drawShape()
+*/
+void TQCanvasPolygonalItem::setPen(TQPen p)
+{
+ if ( pn != p ) {
+ removeFromChunks();
+ pn = p;
+ addToChunks();
+ }
+}
+
+/*!
+ Sets the TQBrush used when drawing the polygonal item to the brush \a b.
+
+ \sa setPen(), brush(), drawShape()
+*/
+void TQCanvasPolygonalItem::setBrush(TQBrush b)
+{
+ if ( br != b) {
+ br = b;
+ changeChunks();
+ }
+}
+
+
+/*!
+ \class TQCanvasPolygon tqcanvas.h
+ \brief The TQCanvasPolygon class provides a polygon on a TQCanvas.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ Paints a polygon with a TQBrush. The polygon's points can be set in
+ the constructor or set or changed later using setPoints(). Use
+ points() to retrieve the points, or areaPoints() to retrieve the
+ points relative to the canvas's origin.
+
+ The polygon can be drawn on a painter with drawShape().
+
+ Like any other canvas item polygons can be moved with
+ TQCanvasItem::move() and TQCanvasItem::moveBy(), or by setting
+ coordinates with TQCanvasItem::setX(), TQCanvasItem::setY() and
+ TQCanvasItem::setZ().
+
+ Note: TQCanvasPolygon does not use the pen.
+*/
+
+/*!
+ Constructs a point-less polygon on the canvas \a canvas. You
+ should call setPoints() before using it further.
+*/
+TQCanvasPolygon::TQCanvasPolygon(TQCanvas* canvas) :
+ TQCanvasPolygonalItem(canvas)
+{
+}
+
+/*!
+ Destroys the polygon.
+*/
+TQCanvasPolygon::~TQCanvasPolygon()
+{
+ hide();
+}
+
+/*!
+ Draws the polygon using the painter \a p.
+
+ Note that TQCanvasPolygon does not support an outline (the pen is
+ always NoPen).
+*/
+void TQCanvasPolygon::drawShape(TQPainter & p)
+{
+ // ### why can't we draw outlines? We could use drawPolyline for it. Lars
+ // ### see other message. Warwick
+
+ p.setPen(NoPen); // since TQRegion(TQPointArray) excludes outline :-( )-:
+ p.drawPolygon(poly);
+}
+
+/*!
+ Sets the points of the polygon to be \a pa. These points will have
+ their x and y coordinates automatically translated by x(), y() as
+ the polygon is moved.
+*/
+void TQCanvasPolygon::setPoints(TQPointArray pa)
+{
+ removeFromChunks();
+ poly = pa;
+ poly.detach(); // Explicit sharing is stupid.
+ poly.translate((int)x(),(int)y());
+ addToChunks();
+}
+
+/*!
+ \reimp
+*/
+void TQCanvasPolygon::moveBy(double dx, double dy)
+{
+ // Note: does NOT call TQCanvasPolygonalItem::moveBy(), since that
+ // only does half this work.
+ //
+ int idx = int(x()+dx)-int(x());
+ int idy = int(y()+dy)-int(y());
+ if ( idx || idy ) {
+ removeFromChunks();
+ poly.translate(idx,idy);
+ }
+ myx+=dx;
+ myy+=dy;
+ if ( idx || idy ) {
+ addToChunks();
+ }
+}
+
+/*!
+ \class TQCanvasSpline tqcanvas.h
+ \brief The TQCanvasSpline class provides multi-bezier splines on a TQCanvas.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ A TQCanvasSpline is a sequence of 4-point bezier curves joined
+ together to make a curved tqshape.
+
+ You set the control points of the spline with setControlPoints().
+
+ If the bezier is closed(), then the first control point will be
+ re-used as the last control point. Therefore, a closed bezier must
+ have a multiple of 3 control points and an open bezier must have
+ one extra point.
+
+ The beziers are not necessarily joined "smoothly". To ensure this,
+ set control points appropriately (general reference texts about
+ beziers will explain this in detail).
+
+ Like any other canvas item splines can be moved with
+ TQCanvasItem::move() and TQCanvasItem::moveBy(), or by setting
+ coordinates with TQCanvasItem::setX(), TQCanvasItem::setY() and
+ TQCanvasItem::setZ().
+
+*/
+
+/*!
+ Create a spline with no control points on the canvas \a canvas.
+
+ \sa setControlPoints()
+*/
+TQCanvasSpline::TQCanvasSpline(TQCanvas* canvas) :
+ TQCanvasPolygon(canvas),
+ cl(TRUE)
+{
+}
+
+/*!
+ Destroy the spline.
+*/
+TQCanvasSpline::~TQCanvasSpline()
+{
+}
+
+// ### shouldn't we handle errors more gracefully than with an assert? Lars
+// ### no, since it's a programming error. Warwick
+/*!
+ Set the spline control points to \a ctrl.
+
+ If \a close is TRUE, then the first point in \a ctrl will be
+ re-used as the last point, and the number of control points must
+ be a multiple of 3. If \a close is FALSE, one additional control
+ point is required, and the number of control points must be one of
+ (4, 7, 10, 13, ...).
+
+ If the number of control points doesn't meet the above conditions,
+ the number of points will be truncated to the largest number of
+ points that do meet the requirement.
+*/
+void TQCanvasSpline::setControlPoints(TQPointArray ctrl, bool close)
+{
+ if ( (int)ctrl.count() % 3 != (close ? 0 : 1) ) {
+ qWarning( "TQCanvasSpline::setControlPoints(): Number of points doesn't fit." );
+ int numCurves = (ctrl.count() - (close ? 0 : 1 ))/ 3;
+ ctrl.resize( numCurves*3 + ( close ? 0 : 1 ) );
+ }
+
+ cl = close;
+ bez = ctrl;
+ recalcPoly();
+}
+
+/*!
+ Returns the current set of control points.
+
+ \sa setControlPoints(), closed()
+*/
+TQPointArray TQCanvasSpline::controlPoints() const
+{
+ return bez;
+}
+
+/*!
+ Returns TRUE if the control points are a closed set; otherwise
+ returns FALSE.
+*/
+bool TQCanvasSpline::closed() const
+{
+ return cl;
+}
+
+void TQCanvasSpline::recalcPoly()
+{
+ TQPtrList<TQPointArray> segs;
+ segs.setAutoDelete(TRUE);
+ int n=0;
+ for (int i=0; i<(int)bez.count()-1; i+=3) {
+ TQPointArray ctrl(4);
+ ctrl[0] = bez[i+0];
+ ctrl[1] = bez[i+1];
+ ctrl[2] = bez[i+2];
+ if ( cl )
+ ctrl[3] = bez[(i+3)%(int)bez.count()];
+ else
+ ctrl[3] = bez[i+3];
+ TQPointArray *seg = new TQPointArray(ctrl.cubicBezier());
+ n += seg->count()-1;
+ segs.append(seg);
+ }
+ TQPointArray p(n+1);
+ n=0;
+ for (TQPointArray* seg = segs.first(); seg; seg = segs.next()) {
+ for (int i=0; i<(int)seg->count()-1; i++)
+ p[n++] = seg->point(i);
+ if ( n == (int)p.count()-1 )
+ p[n] = seg->point(seg->count()-1);
+ }
+ TQCanvasPolygon::setPoints(p);
+}
+
+/*!
+ \fn TQPointArray TQCanvasPolygonalItem::areaPoints() const
+
+ This function must be reimplemented by subclasses. It \e must
+ return the points bounding (i.e. outside and not touching) the
+ tqshape or drawing errors will occur.
+*/
+
+/*!
+ \fn TQPointArray TQCanvasPolygon::points() const
+
+ Returns the vertices of the polygon, not translated by the position.
+
+ \sa setPoints(), areaPoints()
+*/
+TQPointArray TQCanvasPolygon::points() const
+{
+ TQPointArray pa = areaPoints();
+ pa.translate(int(-x()),int(-y()));
+ return pa;
+}
+
+/*!
+ Returns the vertices of the polygon translated by the polygon's
+ current x(), y() position, i.e. relative to the canvas's origin.
+
+ \sa setPoints(), points()
+*/
+TQPointArray TQCanvasPolygon::areaPoints() const
+{
+ return poly.copy();
+}
+
+// ### mark: Why don't we offer a constructor that lets the user set the
+// points -- that way for some uses just the constructor call would be
+// required?
+/*!
+ \class TQCanvasLine tqcanvas.h
+ \brief The TQCanvasLine class provides a line on a TQCanvas.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ The line inherits functionality from TQCanvasPolygonalItem, for
+ example the setPen() function. The start and end points of the
+ line are set with setPoints().
+
+ Like any other canvas item lines can be moved with
+ TQCanvasItem::move() and TQCanvasItem::moveBy(), or by setting
+ coordinates with TQCanvasItem::setX(), TQCanvasItem::setY() and
+ TQCanvasItem::setZ().
+*/
+
+/*!
+ Constructs a line from (0,0) to (0,0) on \a canvas.
+
+ \sa setPoints().
+*/
+TQCanvasLine::TQCanvasLine(TQCanvas* canvas) :
+ TQCanvasPolygonalItem(canvas)
+{
+ x1 = y1 = x2 = y2 = 0;
+}
+
+/*!
+ Destroys the line.
+*/
+TQCanvasLine::~TQCanvasLine()
+{
+ hide();
+}
+
+/*!
+ \reimp
+*/
+void TQCanvasLine::setPen(TQPen p)
+{
+ TQCanvasPolygonalItem::setPen(p);
+}
+
+/*!
+ \fn TQPoint TQCanvasLine::startPoint () const
+
+ Returns the start point of the line.
+
+ \sa setPoints(), endPoint()
+*/
+
+/*!
+ \fn TQPoint TQCanvasLine::endPoint () const
+
+ Returns the end point of the line.
+
+ \sa setPoints(), startPoint()
+*/
+
+/*!
+ Sets the line's start point to (\a xa, \a ya) and its end point to
+ (\a xb, \a yb).
+*/
+void TQCanvasLine::setPoints(int xa, int ya, int xb, int yb)
+{
+ if ( x1 != xa || x2 != xb || y1 != ya || y2 != yb ) {
+ removeFromChunks();
+ x1 = xa;
+ y1 = ya;
+ x2 = xb;
+ y2 = yb;
+ addToChunks();
+ }
+}
+
+/*!
+ \reimp
+*/
+void TQCanvasLine::drawShape(TQPainter &p)
+{
+ p.drawLine((int)(x()+x1), (int)(y()+y1), (int)(x()+x2), (int)(y()+y2));
+}
+
+/*!
+ \reimp
+
+ Note that the area defined by the line is somewhat thicker than
+ the line that is actually drawn.
+*/
+TQPointArray TQCanvasLine::areaPoints() const
+{
+ TQPointArray p(4);
+ int xi = int(x());
+ int yi = int(y());
+ int pw = pen().width();
+ int dx = TQABS(x1-x2);
+ int dy = TQABS(y1-y2);
+ pw = pw*4/3+2; // approx pw*sqrt(2)
+ int px = x1<x2 ? -pw : pw ;
+ int py = y1<y2 ? -pw : pw ;
+ if ( dx && dy && (dx > dy ? (dx*2/dy <= 2) : (dy*2/dx <= 2)) ) {
+ // steep
+ if ( px == py ) {
+ p[0] = TQPoint(x1+xi ,y1+yi+py);
+ p[1] = TQPoint(x2+xi-px,y2+yi );
+ p[2] = TQPoint(x2+xi ,y2+yi-py);
+ p[3] = TQPoint(x1+xi+px,y1+yi );
+ } else {
+ p[0] = TQPoint(x1+xi+px,y1+yi );
+ p[1] = TQPoint(x2+xi ,y2+yi-py);
+ p[2] = TQPoint(x2+xi-px,y2+yi );
+ p[3] = TQPoint(x1+xi ,y1+yi+py);
+ }
+ } else if ( dx > dy ) {
+ // horizontal
+ p[0] = TQPoint(x1+xi+px,y1+yi+py);
+ p[1] = TQPoint(x2+xi-px,y2+yi+py);
+ p[2] = TQPoint(x2+xi-px,y2+yi-py);
+ p[3] = TQPoint(x1+xi+px,y1+yi-py);
+ } else {
+ // vertical
+ p[0] = TQPoint(x1+xi+px,y1+yi+py);
+ p[1] = TQPoint(x2+xi+px,y2+yi-py);
+ p[2] = TQPoint(x2+xi-px,y2+yi-py);
+ p[3] = TQPoint(x1+xi-px,y1+yi+py);
+ }
+ return p;
+}
+
+/*!
+ \reimp
+
+*/
+
+void TQCanvasLine::moveBy(double dx, double dy)
+{
+ TQCanvasPolygonalItem::moveBy(dx, dy);
+}
+
+/*!
+ \class TQCanvasRectangle tqcanvas.h
+ \brief The TQCanvasRectangle class provides a rectangle on a TQCanvas.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ This item paints a single rectangle which may have any pen() and
+ brush(), but may not be tilted/rotated. For rotated rectangles,
+ use TQCanvasPolygon.
+
+ The rectangle's size and initial position can be set in the
+ constructor. The size can be set or changed later using setSize().
+ Use height() and width() to retrieve the rectangle's dimensions.
+
+ The rectangle can be drawn on a painter with drawShape().
+
+ Like any other canvas item rectangles can be moved with
+ TQCanvasItem::move() and TQCanvasItem::moveBy(), or by setting
+ coordinates with TQCanvasItem::setX(), TQCanvasItem::setY() and
+ TQCanvasItem::setZ().
+
+*/
+
+/*!
+ Constructs a rectangle at position (0,0) with both width and
+ height set to 32 pixels on \a canvas.
+*/
+TQCanvasRectangle::TQCanvasRectangle(TQCanvas* canvas) :
+ TQCanvasPolygonalItem(canvas),
+ w(32), h(32)
+{
+}
+
+/*!
+ Constructs a rectangle positioned and sized by \a r on \a canvas.
+*/
+TQCanvasRectangle::TQCanvasRectangle(const TQRect& r, TQCanvas* canvas) :
+ TQCanvasPolygonalItem(canvas),
+ w(r.width()), h(r.height())
+{
+ move(r.x(),r.y());
+}
+
+/*!
+ Constructs a rectangle at position (\a x, \a y) and size \a width
+ by \a height, on \a canvas.
+*/
+TQCanvasRectangle::TQCanvasRectangle(int x, int y, int width, int height,
+ TQCanvas* canvas) :
+ TQCanvasPolygonalItem(canvas),
+ w(width), h(height)
+{
+ move(x,y);
+}
+
+/*!
+ Destroys the rectangle.
+*/
+TQCanvasRectangle::~TQCanvasRectangle()
+{
+ hide();
+}
+
+
+/*!
+ Returns the width of the rectangle.
+*/
+int TQCanvasRectangle::width() const
+{
+ return w;
+}
+
+/*!
+ Returns the height of the rectangle.
+*/
+int TQCanvasRectangle::height() const
+{
+ return h;
+}
+
+/*!
+ Sets the \a width and \a height of the rectangle.
+*/
+void TQCanvasRectangle::setSize(int width, int height)
+{
+ if ( w != width || h != height ) {
+ removeFromChunks();
+ w = width;
+ h = height;
+ addToChunks();
+ }
+}
+
+/*!
+ \fn TQSize TQCanvasRectangle::size() const
+
+ Returns the width() and height() of the rectangle.
+
+ \sa rect(), setSize()
+*/
+
+/*!
+ \fn TQRect TQCanvasRectangle::rect() const
+
+ Returns the integer-converted x(), y() position and size() of the
+ rectangle as a TQRect.
+*/
+
+/*!
+ \reimp
+*/
+TQPointArray TQCanvasRectangle::areaPoints() const
+{
+ TQPointArray pa(4);
+ int pw = (pen().width()+1)/2;
+ if ( pw < 1 ) pw = 1;
+ if ( pen() == Qt::NoPen ) pw = 0;
+ pa[0] = TQPoint((int)x()-pw,(int)y()-pw);
+ pa[1] = pa[0] + TQPoint(w+pw*2,0);
+ pa[2] = pa[1] + TQPoint(0,h+pw*2);
+ pa[3] = pa[0] + TQPoint(0,h+pw*2);
+ return pa;
+}
+
+/*!
+ Draws the rectangle on painter \a p.
+*/
+void TQCanvasRectangle::drawShape(TQPainter & p)
+{
+ p.drawRect((int)x(), (int)y(), w, h);
+}
+
+
+/*!
+ \class TQCanvasEllipse tqcanvas.h
+ \brief The TQCanvasEllipse class provides an ellipse or ellipse segment on a TQCanvas.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ A canvas item that paints an ellipse or ellipse segment with a TQBrush.
+ The ellipse's height, width, start angle and angle length can be set
+ at construction time. The size can be changed at runtime with
+ setSize(), and the angles can be changed (if you're displaying an
+ ellipse segment rather than a whole ellipse) with setAngles().
+
+ Note that angles are specified in 16ths of a degree.
+
+ \target anglediagram
+ \img qcanvasellipse.png Ellipse
+
+ If a start angle and length angle are set then an ellipse segment
+ will be drawn. The start angle is the angle that goes from zero in a
+ counter-clockwise direction (shown in green in the diagram). The
+ length angle is the angle from the start angle in a
+ counter-clockwise direction (shown in blue in the diagram). The blue
+ segment is the segment of the ellipse that would be drawn. If no
+ start angle and length angle are specified the entire ellipse is
+ drawn.
+
+ The ellipse can be drawn on a painter with drawShape().
+
+ Like any other canvas item ellipses can be moved with move() and
+ moveBy(), or by setting coordinates with setX(), setY() and setZ().
+
+ Note: TQCanvasEllipse does not use the pen.
+*/
+
+/*!
+ Constructs a 32x32 ellipse, centered at (0, 0) on \a canvas.
+*/
+TQCanvasEllipse::TQCanvasEllipse(TQCanvas* canvas) :
+ TQCanvasPolygonalItem(canvas),
+ w(32), h(32),
+ a1(0), a2(360*16)
+{
+}
+
+/*!
+ Constructs a \a width by \a height pixel ellipse, centered at
+ (0, 0) on \a canvas.
+*/
+TQCanvasEllipse::TQCanvasEllipse(int width, int height, TQCanvas* canvas) :
+ TQCanvasPolygonalItem(canvas),
+ w(width),h(height),
+ a1(0),a2(360*16)
+{
+}
+
+// ### add a constructor taking degrees in float. 1/16 degrees is stupid. Lars
+// ### it's how TQPainter does it, so TQCanvas does too for consistency. If it's
+// ### a good idea, it should be added to TQPainter, not just to TQCanvas. Warwick
+/*!
+ Constructs a \a width by \a height pixel ellipse, centered at
+ (0, 0) on \a canvas. Only a segment of the ellipse is drawn,
+ starting at angle \a startangle, and extending for angle \a angle
+ (the angle length).
+
+ Note that angles are specified in
+ <small><sup>1</sup>/<sub>16</sub></small>ths of a degree.
+*/
+TQCanvasEllipse::TQCanvasEllipse(int width, int height,
+ int startangle, int angle, TQCanvas* canvas) :
+ TQCanvasPolygonalItem(canvas),
+ w(width),h(height),
+ a1(startangle),a2(angle)
+{
+}
+
+/*!
+ Destroys the ellipse.
+*/
+TQCanvasEllipse::~TQCanvasEllipse()
+{
+ hide();
+}
+
+/*!
+ Returns the width of the ellipse.
+*/
+int TQCanvasEllipse::width() const
+{
+ return w;
+}
+
+/*!
+ Returns the height of the ellipse.
+*/
+int TQCanvasEllipse::height() const
+{
+ return h;
+}
+
+/*!
+ Sets the \a width and \a height of the ellipse.
+*/
+void TQCanvasEllipse::setSize(int width, int height)
+{
+ if ( w != width || h != height ) {
+ removeFromChunks();
+ w = width;
+ h = height;
+ addToChunks();
+ }
+}
+
+/*!
+ \fn int TQCanvasEllipse::angleStart() const
+
+ Returns the start angle in 16ths of a degree. Initially
+ this will be 0.
+
+ \sa setAngles(), angleLength()
+*/
+
+/*!
+ \fn int TQCanvasEllipse::angleLength() const
+
+ Returns the length angle (the extent of the ellipse segment) in
+ 16ths of a degree. Initially this will be 360 * 16 (a complete
+ ellipse).
+
+ \sa setAngles(), angleStart()
+*/
+
+/*!
+ Sets the angles for the ellipse. The start angle is \a start and
+ the extent of the segment is \a length (the angle length) from the
+ \a start. The angles are specified in 16ths of a degree. By
+ default the ellipse will start at 0 and have an angle length of
+ 360 * 16 (a complete ellipse).
+
+ \sa angleStart(), angleLength()
+*/
+void TQCanvasEllipse::setAngles(int start, int length)
+{
+ if ( a1 != start || a2 != length ) {
+ removeFromChunks();
+ a1 = start;
+ a2 = length;
+ addToChunks();
+ }
+}
+
+/*!
+ \reimp
+*/
+TQPointArray TQCanvasEllipse::areaPoints() const
+{
+ TQPointArray r;
+ // makeArc at 0,0, then translate so that fixed point math doesn't overflow
+ r.makeArc(int(x()-w/2.0+0.5)-1, int(y()-h/2.0+0.5)-1, w+3, h+3, a1, a2);
+ r.resize(r.size()+1);
+ r.setPoint(r.size()-1,int(x()),int(y()));
+ return r;
+}
+
+// ### support outlines! Lars
+// ### TQRegion doesn't, so we cannot (try it). Warwick
+/*!
+ Draws the ellipse, centered at x(), y() using the painter \a p.
+
+ Note that TQCanvasEllipse does not support an outline (the pen is
+ always NoPen).
+*/
+void TQCanvasEllipse::drawShape(TQPainter & p)
+{
+ p.setPen(NoPen); // since TQRegion(TQPointArray) excludes outline :-( )-:
+ if ( !a1 && a2 == 360*16 ) {
+ p.drawEllipse(int(x()-w/2.0+0.5), int(y()-h/2.0+0.5), w, h);
+ } else {
+ p.drawPie(int(x()-w/2.0+0.5), int(y()-h/2.0+0.5), w, h, a1, a2);
+ }
+}
+
+
+/*!
+ \class TQCanvasText tqcanvas.h
+ \brief The TQCanvasText class provides a text object on a TQCanvas.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module canvas
+ \ingroup graphics
+ \ingroup images
+
+ A canvas text item has text with font, color and tqalignment
+ attributes. The text and font can be set in the constructor or set
+ or changed later with setText() and setFont(). The color is set
+ with setColor() and the tqalignment with setTextFlags(). The text
+ item's bounding rectangle is retrieved with boundingRect().
+
+ The text can be drawn on a painter with draw().
+
+ Like any other canvas item text items can be moved with
+ TQCanvasItem::move() and TQCanvasItem::moveBy(), or by setting
+ coordinates with TQCanvasItem::setX(), TQCanvasItem::setY() and
+ TQCanvasItem::setZ().
+*/
+
+/*!
+ Constructs a TQCanvasText with the text "\<text\>", on \a canvas.
+*/
+TQCanvasText::TQCanvasText(TQCanvas* canvas) :
+ TQCanvasItem(canvas),
+ txt("<text>"), flags(0)
+{
+ setRect();
+}
+
+// ### add textflags to the constructor? Lars
+/*!
+ Constructs a TQCanvasText with the text \a t, on canvas \a canvas.
+*/
+TQCanvasText::TQCanvasText(const TQString& t, TQCanvas* canvas) :
+ TQCanvasItem(canvas),
+ txt(t), flags(0)
+{
+ setRect();
+}
+
+// ### see above
+/*!
+ Constructs a TQCanvasText with the text \a t and font \a f, on the
+ canvas \a canvas.
+*/
+TQCanvasText::TQCanvasText(const TQString& t, TQFont f, TQCanvas* canvas) :
+ TQCanvasItem(canvas),
+ txt(t), flags(0),
+ fnt(f)
+{
+ setRect();
+}
+
+/*!
+ Destroys the canvas text item.
+*/
+TQCanvasText::~TQCanvasText()
+{
+ removeFromChunks();
+}
+
+/*!
+ Returns the bounding rectangle of the text.
+*/
+TQRect TQCanvasText::boundingRect() const { return brect; }
+
+void TQCanvasText::setRect()
+{
+ brect = TQFontMetrics(fnt).boundingRect(int(x()), int(y()), 0, 0, flags, txt);
+ brect.setWidth(brect.width()+1);
+}
+
+/*!
+ \fn int TQCanvasText::textFlags() const
+
+ Returns the currently set tqalignment flags.
+
+ \sa setTextFlags() TQt::AlignmentFlags
+*/
+
+
+/*!
+ Sets the tqalignment flags to \a f. These are a bitwise OR of the
+ flags available to TQPainter::drawText() -- see the
+ \l{TQt::AlignmentFlags}.
+
+ \sa setFont() setColor()
+*/
+void TQCanvasText::setTextFlags(int f)
+{
+ if ( flags != f ) {
+ removeFromChunks();
+ flags = f;
+ setRect();
+ addToChunks();
+ }
+}
+
+/*!
+ Returns the text item's text.
+
+ \sa setText()
+*/
+TQString TQCanvasText::text() const
+{
+ return txt;
+}
+
+
+/*!
+ Sets the text item's text to \a t. The text may contain newlines.
+
+ \sa text(), setFont(), setColor() setTextFlags()
+*/
+void TQCanvasText::setText( const TQString& t )
+{
+ if ( txt != t ) {
+ removeFromChunks();
+ txt = t;
+ setRect();
+ addToChunks();
+ }
+}
+
+/*!
+ Returns the font in which the text is drawn.
+
+ \sa setFont()
+*/
+TQFont TQCanvasText::font() const
+{
+ return fnt;
+}
+
+/*!
+ Sets the font in which the text is drawn to font \a f.
+
+ \sa font()
+*/
+void TQCanvasText::setFont( const TQFont& f )
+{
+ if ( f != fnt ) {
+ removeFromChunks();
+ fnt = f;
+ setRect();
+ addToChunks();
+ }
+}
+
+/*!
+ Returns the color of the text.
+
+ \sa setColor()
+*/
+TQColor TQCanvasText::color() const
+{
+ return col;
+}
+
+/*!
+ Sets the color of the text to the color \a c.
+
+ \sa color(), setFont()
+*/
+void TQCanvasText::setColor(const TQColor& c)
+{
+ col=c;
+ changeChunks();
+}
+
+
+/*!
+ \reimp
+*/
+void TQCanvasText::moveBy(double dx, double dy)
+{
+ int idx = int(x()+dx)-int(x());
+ int idy = int(y()+dy)-int(y());
+ if ( idx || idy ) {
+ removeFromChunks();
+ }
+ myx+=dx;
+ myy+=dy;
+ if ( idx || idy ) {
+ brect.moveBy(idx,idy);
+ addToChunks();
+ }
+}
+
+/*!
+ Draws the text using the painter \a painter.
+*/
+void TQCanvasText::draw(TQPainter& painter)
+{
+ painter.setFont(fnt);
+ painter.setPen(col);
+ painter.drawText(brect, flags, txt);
+}
+
+/*!
+ \reimp
+*/
+void TQCanvasText::changeChunks()
+{
+ if (isVisible() && canvas()) {
+ int chunksize=canvas()->chunkSize();
+ for (int j=brect.top()/chunksize; j<=brect.bottom()/chunksize; j++) {
+ for (int i=brect.left()/chunksize; i<=brect.right()/chunksize; i++) {
+ canvas()->setChangedChunk(i,j);
+ }
+ }
+ }
+}
+
+/*!
+ Adds the text item to the appropriate chunks.
+*/
+void TQCanvasText::addToChunks()
+{
+ if (isVisible() && canvas()) {
+ int chunksize=canvas()->chunkSize();
+ for (int j=brect.top()/chunksize; j<=brect.bottom()/chunksize; j++) {
+ for (int i=brect.left()/chunksize; i<=brect.right()/chunksize; i++) {
+ canvas()->addItemToChunk(this,i,j);
+ }
+ }
+ }
+}
+
+/*!
+ Removes the text item from the appropriate chunks.
+*/
+void TQCanvasText::removeFromChunks()
+{
+ if (isVisible() && canvas()) {
+ int chunksize=canvas()->chunkSize();
+ for (int j=brect.top()/chunksize; j<=brect.bottom()/chunksize; j++) {
+ for (int i=brect.left()/chunksize; i<=brect.right()/chunksize; i++) {
+ canvas()->removeItemFromChunk(this,i,j);
+ }
+ }
+ }
+}
+
+
+/*!
+ Returns 0 (TQCanvasItem::Rtti_Item).
+
+ Make your derived classes return their own values for rtti(), so
+ that you can distinguish between objects returned by
+ TQCanvas::at(). You should use values greater than 1000 to allow
+ for extensions to this class.
+
+ Overuse of this functionality can damage it's extensibility. For
+ example, once you have identified a base class of a TQCanvasItem
+ found by TQCanvas::at(), cast it to that type and call meaningful
+ methods rather than acting upon the object based on its rtti
+ value.
+
+ For example:
+
+ \code
+ TQCanvasItem* item;
+ // Find an item, e.g. with TQCanvasItem::collisions().
+ ...
+ if (item->rtti() == MySprite::RTTI ) {
+ MySprite* s = (MySprite*)item;
+ if (s->isDamagable()) s->loseHitPoints(1000);
+ if (s->isHot()) myself->loseHitPoints(1000);
+ ...
+ }
+ \endcode
+*/
+int TQCanvasItem::rtti() const { return RTTI; }
+int TQCanvasItem::RTTI = Rtti_Item;
+
+/*!
+ Returns 1 (TQCanvasItem::Rtti_Sprite).
+
+ \sa TQCanvasItem::rtti()
+*/
+int TQCanvasSprite::rtti() const { return RTTI; }
+int TQCanvasSprite::RTTI = Rtti_Sprite;
+
+/*!
+ Returns 2 (TQCanvasItem::Rtti_PolygonalItem).
+
+ \sa TQCanvasItem::rtti()
+*/
+int TQCanvasPolygonalItem::rtti() const { return RTTI; }
+int TQCanvasPolygonalItem::RTTI = Rtti_PolygonalItem;
+
+/*!
+ Returns 3 (TQCanvasItem::Rtti_Text).
+
+ \sa TQCanvasItem::rtti()
+*/
+int TQCanvasText::rtti() const { return RTTI; }
+int TQCanvasText::RTTI = Rtti_Text;
+
+/*!
+ Returns 4 (TQCanvasItem::Rtti_Polygon).
+
+ \sa TQCanvasItem::rtti()
+*/
+int TQCanvasPolygon::rtti() const { return RTTI; }
+int TQCanvasPolygon::RTTI = Rtti_Polygon;
+
+/*!
+ Returns 5 (TQCanvasItem::Rtti_Rectangle).
+
+ \sa TQCanvasItem::rtti()
+*/
+int TQCanvasRectangle::rtti() const { return RTTI; }
+int TQCanvasRectangle::RTTI = Rtti_Rectangle;
+
+/*!
+ Returns 6 (TQCanvasItem::Rtti_Ellipse).
+
+ \sa TQCanvasItem::rtti()
+*/
+int TQCanvasEllipse::rtti() const { return RTTI; }
+int TQCanvasEllipse::RTTI = Rtti_Ellipse;
+
+/*!
+ Returns 7 (TQCanvasItem::Rtti_Line).
+
+ \sa TQCanvasItem::rtti()
+*/
+int TQCanvasLine::rtti() const { return RTTI; }
+int TQCanvasLine::RTTI = Rtti_Line;
+
+/*!
+ Returns 8 (TQCanvasItem::Rtti_Spline).
+
+ \sa TQCanvasItem::rtti()
+*/
+int TQCanvasSpline::rtti() const { return RTTI; }
+int TQCanvasSpline::RTTI = Rtti_Spline;
+
+/*!
+ Constructs a TQCanvasSprite which uses images from the
+ TQCanvasPixmapArray \a a.
+
+ The sprite in initially positioned at (0, 0) on \a canvas, using
+ frame 0.
+*/
+TQCanvasSprite::TQCanvasSprite(TQCanvasPixmapArray* a, TQCanvas* canvas) :
+ TQCanvasItem(canvas),
+ frm(0),
+ anim_val(0),
+ anim_state(0),
+ anim_type(0),
+ images(a)
+{
+}
+
+
+/*!
+ Set the array of images used for displaying the sprite to the
+ TQCanvasPixmapArray \a a.
+
+ If the current frame() is larger than the number of images in \a
+ a, the current frame will be reset to 0.
+*/
+void TQCanvasSprite::setSequence(TQCanvasPixmapArray* a)
+{
+ bool isvisible = isVisible();
+ if ( isvisible && images )
+ hide();
+ images = a;
+ if ( frm >= (int)images->count() )
+ frm = 0;
+ if ( isvisible )
+ show();
+}
+
+/*!
+\internal
+
+Marks any chunks the sprite touches as changed.
+*/
+void TQCanvasSprite::changeChunks()
+{
+ if (isVisible() && canvas()) {
+ int chunksize=canvas()->chunkSize();
+ for (int j=topEdge()/chunksize; j<=bottomEdge()/chunksize; j++) {
+ for (int i=leftEdge()/chunksize; i<=rightEdge()/chunksize; i++) {
+ canvas()->setChangedChunk(i,j);
+ }
+ }
+ }
+}
+
+/*!
+ Destroys the sprite and removes it from the canvas. Does \e not
+ delete the images.
+*/
+TQCanvasSprite::~TQCanvasSprite()
+{
+ removeFromChunks();
+}
+
+/*!
+ Sets the animation frame used for displaying the sprite to \a f,
+ an index into the TQCanvasSprite's TQCanvasPixmapArray. The call
+ will be ignored if \a f is larger than frameCount() or smaller
+ than 0.
+
+ \sa frame() move()
+*/
+void TQCanvasSprite::setFrame(int f)
+{
+ move(x(),y(),f);
+}
+
+/*!
+ \enum TQCanvasSprite::FrameAnimationType
+
+ This enum is used to identify the different types of frame
+ animation offered by TQCanvasSprite.
+
+ \value Cycle at each advance the frame number will be incremented by
+ 1 (modulo the frame count).
+ \value Oscillate at each advance the frame number will be
+ incremented by 1 up to the frame count then decremented to by 1 to
+ 0, repeating this sequence forever.
+*/
+
+/*!
+ Sets the animation characteristics for the sprite.
+
+ For \a type == \c Cycle, the frames will increase by \a step
+ at each advance, modulo the frameCount().
+
+ For \a type == \c Oscillate, the frames will increase by \a step
+ at each advance, up to the frameCount(), then decrease by \a step
+ back to 0, repeating forever.
+
+ The \a state parameter is for internal use.
+*/
+void TQCanvasSprite::setFrameAnimation(FrameAnimationType type, int step, int state)
+{
+ anim_val = step;
+ anim_type = type;
+ anim_state = state;
+ setAnimated(TRUE);
+}
+
+/*!
+ Extends the default TQCanvasItem implementation to provide the
+ functionality of setFrameAnimation().
+
+ The \a phase is 0 or 1: see TQCanvasItem::advance() for details.
+
+ \sa TQCanvasItem::advance() setVelocity()
+*/
+void TQCanvasSprite::advance(int phase)
+{
+ if ( phase==1 ) {
+ int nf = frame();
+ if ( anim_type == Oscillate ) {
+ if ( anim_state )
+ nf += anim_val;
+ else
+ nf -= anim_val;
+ if ( nf < 0 ) {
+ nf = abs(anim_val);
+ anim_state = !anim_state;
+ } else if ( nf >= frameCount() ) {
+ nf = frameCount()-1-abs(anim_val);
+ anim_state = !anim_state;
+ }
+ } else {
+ nf = (nf + anim_val + frameCount()) % frameCount();
+ }
+ move(x()+xVelocity(),y()+yVelocity(),nf);
+ }
+}
+
+
+/*!
+ \fn int TQCanvasSprite::frame() const
+
+ Returns the index of the current animation frame in the
+ TQCanvasSprite's TQCanvasPixmapArray.
+
+ \sa setFrame(), move()
+*/
+
+/*!
+ \fn int TQCanvasSprite::frameCount() const
+
+ Returns the number of frames in the TQCanvasSprite's
+ TQCanvasPixmapArray.
+*/
+
+
+/*!
+ \reimp
+ \internal
+ Moves the sprite to the position \a x, \a y.
+ Keep it visible.
+*/
+void TQCanvasSprite::move(double x, double y) { TQCanvasItem::move(x,y); }
+
+/*!
+ \fn void TQCanvasSprite::move(double nx, double ny, int nf)
+
+ Set the position of the sprite to \a nx, \a ny and the current
+ frame to \a nf. \a nf will be ignored if it is larger than
+ frameCount() or smaller than 0.
+*/
+void TQCanvasSprite::move(double nx, double ny, int nf)
+{
+ if (isVisible() && canvas()) {
+ hide();
+ TQCanvasItem::move(nx,ny);
+ if ( nf >= 0 && nf < frameCount() )
+ frm=nf;
+ show();
+ } else {
+ TQCanvasItem::move(nx,ny);
+ if ( nf >= 0 && nf < frameCount() )
+ frm=nf;
+ }
+}
+
+class TQCanvasPolygonScanner : public TQPolygonScanner {
+ TQPolygonalProcessor& processor;
+public:
+ TQCanvasPolygonScanner(TQPolygonalProcessor& p) :
+ processor(p)
+ {
+ }
+ void processSpans( int n, TQPoint* point, int* width )
+ {
+ processor.doSpans(n,point,width);
+ }
+};
+
+void TQCanvasPolygonalItem::scanPolygon(const TQPointArray& pa, int winding, TQPolygonalProcessor& process) const
+{
+ TQCanvasPolygonScanner scanner(process);
+ scanner.scan(pa,winding);
+}
+
+
+#endif // TQT_NO_CANVAS
diff --git a/tqtinterface/qt4/src/canvas/tqcanvas.h b/tqtinterface/qt4/src/canvas/tqcanvas.h
new file mode 100644
index 0000000..2aaba6e
--- /dev/null
+++ b/tqtinterface/qt4/src/canvas/tqcanvas.h
@@ -0,0 +1,818 @@
+/**********************************************************************
+**
+** Definition of TQCanvas classes
+**
+** Created : 991211
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the canvas module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCANVAS_H
+#define TQCANVAS_H
+
+#ifndef TQT_H
+#include "tqscrollview.h"
+#include "tqpixmap.h"
+#include "tqptrlist.h"
+#include "tqbrush.h"
+#include "tqpen.h"
+#include "tqvaluelist.h"
+#include "tqpointarray.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_CANVAS ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_CANVAS )
+#define TQM_EXPORT_CANVAS
+#define TQM_TEMPLATE_EXTERN_CANVAS
+#else
+#define TQM_EXPORT_CANVAS TQ_EXPORT
+#define TQM_TEMPLATE_EXTERN_CANVAS TQ_TEMPLATE_EXTERN
+#endif
+
+#ifndef TQT_NO_CANVAS
+
+
+class TQCanvasSprite;
+class TQCanvasPolygonalItem;
+class TQCanvasRectangle;
+class TQCanvasPolygon;
+class TQCanvasEllipse;
+class TQCanvasText;
+class TQCanvasLine;
+class TQCanvasChunk;
+class TQCanvas;
+class TQCanvasItem;
+class TQCanvasView;
+class TQCanvasPixmap;
+
+#if defined(TQ_TEMPLATEDLL) && ( !defined(TQ_CC_BOR) || !defined(TQT_MAKEDLL) || defined(TQ_EXPORT_TEMPLATES) )
+// TQMOC_SKIP_BEGIN
+TQM_TEMPLATE_EXTERN_CANVAS template class TQM_EXPORT_CANVAS TQValueListIterator< TQCanvasItem* >;
+TQM_TEMPLATE_EXTERN_CANVAS template class TQM_EXPORT_CANVAS TQValueList< TQCanvasItem* >;
+// TQMOC_SKIP_END
+#endif
+
+class TQM_EXPORT_CANVAS TQCanvasItemList : public TQValueList<TQCanvasItem*> {
+public:
+ void sort();
+ void drawUnique( TQPainter& painter );
+ TQCanvasItemList operator+(const TQCanvasItemList &l) const;
+};
+
+
+class TQCanvasItemExtra;
+
+class TQM_EXPORT_CANVAS TQCanvasItem : public TQt
+{
+public:
+ TQCanvasItem(TQCanvas* canvas);
+ virtual ~TQCanvasItem();
+
+ double x() const
+ { return myx; }
+ double y() const
+ { return myy; }
+ double z() const
+ { return myz; } // (depth)
+
+ virtual void moveBy(double dx, double dy);
+ void move(double x, double y);
+ void setX(double a) { move(a,y()); }
+ void setY(double a) { move(x(),a); }
+ void setZ(double a) { myz=a; changeChunks(); }
+
+ bool animated() const;
+ virtual void setAnimated(bool y);
+ virtual void setVelocity( double vx, double vy);
+ void setXVelocity( double vx ) { setVelocity(vx,yVelocity()); }
+ void setYVelocity( double vy ) { setVelocity(xVelocity(),vy); }
+ double xVelocity() const;
+ double yVelocity() const;
+ virtual void advance(int stage);
+
+ virtual bool collidesWith( const TQCanvasItem* ) const=0;
+
+ TQCanvasItemList collisions(bool exact /* NO DEFAULT */ ) const;
+
+ virtual void setCanvas(TQCanvas*);
+
+ virtual void draw(TQPainter&)=0;
+
+ void show();
+ void hide();
+
+ virtual void tqsetVisible(bool yes);
+ bool isVisible() const
+ { return (bool)vis; }
+ virtual void setSelected(bool yes);
+ bool isSelected() const
+ { return (bool)sel; }
+ virtual void setEnabled(bool yes);
+ bool isEnabled() const
+ { return (bool)ena; }
+ virtual void setActive(bool yes);
+ bool isActive() const
+ { return (bool)act; }
+#ifndef TQT_NO_COMPAT
+ bool visible() const
+ { return (bool)vis; }
+ bool selected() const
+ { return (bool)sel; }
+ bool enabled() const
+ { return (bool)ena; }
+ bool active() const
+ { return (bool)act; }
+#endif
+
+ enum RttiValues {
+ Rtti_Item = 0,
+ Rtti_Sprite = 1,
+ Rtti_PolygonalItem = 2,
+ Rtti_Text = 3,
+ Rtti_Polygon = 4,
+ Rtti_Rectangle = 5,
+ Rtti_Ellipse = 6,
+ Rtti_Line = 7,
+ Rtti_Spline = 8
+ };
+
+ virtual int rtti() const;
+ static int RTTI;
+
+ virtual TQRect boundingRect() const=0;
+ virtual TQRect boundingRectAdvanced() const;
+
+ TQCanvas* canvas() const
+ { return cnv; }
+
+protected:
+ void update() { changeChunks(); }
+
+private:
+ // For friendly subclasses...
+
+ friend class TQCanvasPolygonalItem;
+ friend class TQCanvasSprite;
+ friend class TQCanvasRectangle;
+ friend class TQCanvasPolygon;
+ friend class TQCanvasEllipse;
+ friend class TQCanvasText;
+ friend class TQCanvasLine;
+
+ virtual TQPointArray chunks() const;
+ virtual void addToChunks();
+ virtual void removeFromChunks();
+ virtual void changeChunks();
+ virtual bool collidesWith( const TQCanvasSprite*,
+ const TQCanvasPolygonalItem*,
+ const TQCanvasRectangle*,
+ const TQCanvasEllipse*,
+ const TQCanvasText* ) const = 0;
+ // End of friend stuff
+
+ TQCanvas* cnv;
+ static TQCanvas* current_canvas;
+ double myx,myy,myz;
+ TQCanvasItemExtra *ext;
+ TQCanvasItemExtra& extra();
+ uint ani:1;
+ uint vis:1;
+ uint val:1;
+ uint sel:1;
+ uint ena:1;
+ uint act:1;
+};
+
+
+class TQCanvasData;
+
+class TQM_EXPORT_CANVAS TQCanvas : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQCanvas( TQObject* tqparent = 0, const char* name = 0 );
+ TQCanvas(int w, int h);
+ TQCanvas( TQPixmap p, int h, int v, int tilewidth, int tileheight );
+
+ virtual ~TQCanvas();
+
+ virtual void setTiles( TQPixmap tiles, int h, int v,
+ int tilewidth, int tileheight );
+ virtual void tqsetBackgroundPixmap( const TQPixmap& p );
+ TQPixmap backgroundPixmap() const;
+
+ virtual void setBackgroundColor( const TQColor& c );
+ TQColor backgroundColor() const;
+
+ virtual void setTile( int x, int y, int tilenum );
+ int tile( int x, int y ) const
+ { return grid[x+y*htiles]; }
+
+ int tilesHorizontally() const
+ { return htiles; }
+ int tilesVertically() const
+ { return vtiles; }
+
+ int tileWidth() const
+ { return tilew; }
+ int tileHeight() const
+ { return tileh; }
+
+ virtual void resize(int width, int height);
+ int width() const
+ { return awidth; }
+ int height() const
+ { return aheight; }
+ TQSize size() const
+ { return TQSize(awidth,aheight); }
+ TQRect rect() const
+ { return TQRect( 0, 0, awidth, aheight ); }
+ bool onCanvas( int x, int y ) const
+ { return x>=0 && y>=0 && x<awidth && y<aheight; }
+ bool onCanvas( const TQPoint& p ) const
+ { return onCanvas(p.x(),p.y()); }
+ bool validChunk( int x, int y ) const
+ { return x>=0 && y>=0 && x<chwidth && y<chheight; }
+ bool validChunk( const TQPoint& p ) const
+ { return validChunk(p.x(),p.y()); }
+
+ int chunkSize() const
+ { return chunksize; }
+ virtual void retune(int chunksize, int maxclusters=100);
+
+ bool sameChunk(int x1, int y1, int x2, int y2) const
+ { return x1/chunksize==x2/chunksize && y1/chunksize==y2/chunksize; }
+ virtual void setChangedChunk(int i, int j);
+ virtual void setChangedChunkContaining(int x, int y);
+ virtual void setAllChanged();
+ virtual void setChanged(const TQRect& area);
+ virtual void setUnchanged(const TQRect& area);
+
+ // These call setChangedChunk.
+ void addItemToChunk(TQCanvasItem*, int i, int j);
+ void removeItemFromChunk(TQCanvasItem*, int i, int j);
+ void addItemToChunkContaining(TQCanvasItem*, int x, int y);
+ void removeItemFromChunkContaining(TQCanvasItem*, int x, int y);
+
+ TQCanvasItemList allItems();
+ TQCanvasItemList collisions( const TQPoint&) const;
+ TQCanvasItemList collisions( const TQRect&) const;
+ TQCanvasItemList collisions( const TQPointArray& pa, const TQCanvasItem* item,
+ bool exact) const;
+
+ void drawArea(const TQRect&, TQPainter* p, bool double_buffer=FALSE);
+
+ // These are for TQCanvasView to call
+ virtual void addView(TQCanvasView*);
+ virtual void removeView(TQCanvasView*);
+ void drawCanvasArea(const TQRect&, TQPainter* p=0, bool double_buffer=TRUE);
+ void drawViewArea( TQCanvasView* view, TQPainter* p, const TQRect& r, bool dbuf );
+
+ // These are for TQCanvasItem to call
+ virtual void addItem(TQCanvasItem*);
+ virtual void addAnimation(TQCanvasItem*);
+ virtual void removeItem(TQCanvasItem*);
+ virtual void removeAnimation(TQCanvasItem*);
+
+ virtual void setAdvancePeriod(int ms);
+ virtual void setUpdatePeriod(int ms);
+
+ virtual void setDoubleBuffering(bool y);
+
+Q_SIGNALS:
+ void resized();
+
+public Q_SLOTS:
+ virtual void advance();
+ virtual void update();
+
+protected:
+ virtual void drawBackground(TQPainter&, const TQRect& area);
+ virtual void drawForeground(TQPainter&, const TQRect& area);
+
+private:
+ void init(int w, int h, int chunksze=16, int maxclust=100);
+
+ TQCanvasChunk& chunk(int i, int j) const;
+ TQCanvasChunk& chunkContaining(int x, int y) const;
+
+ TQRect changeBounds(const TQRect& inarea);
+ void drawChanges(const TQRect& inarea);
+
+ TQPixmap offscr;
+ int awidth,aheight;
+ int chunksize;
+ int maxclusters;
+ int chwidth,chheight;
+ TQCanvasChunk* chunks;
+
+ TQCanvasData* d;
+
+ void initTiles(TQPixmap p, int h, int v, int tilewidth, int tileheight);
+ ushort *grid;
+ ushort htiles;
+ ushort vtiles;
+ ushort tilew;
+ ushort tileh;
+ bool oneone;
+ TQPixmap pm;
+ TQTimer* update_timer;
+ TQColor bgcolor;
+ bool debug_redraw_areas;
+ bool dblbuf;
+
+ friend void qt_unview(TQCanvas* c);
+
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQCanvas( const TQCanvas & );
+ TQCanvas &operator=( const TQCanvas & );
+#endif
+};
+
+class TQCanvasViewData;
+
+class TQM_EXPORT_CANVAS TQCanvasView : public TQScrollView
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+
+ TQCanvasView(TQWidget* tqparent=0, const char* name=0, WFlags f=0);
+ TQCanvasView(TQCanvas* viewing, TQWidget* tqparent=0, const char* name=0, WFlags f=0);
+ ~TQCanvasView();
+
+ TQCanvas* canvas() const
+ { return viewing; }
+ void setCanvas(TQCanvas* v);
+
+ const TQWMatrix &tqworldMatrix() const;
+ const TQWMatrix &inverseWorldMatrix() const;
+ bool setWorldMatrix( const TQWMatrix & );
+
+protected:
+ void drawContents( TQPainter*, int cx, int cy, int cw, int ch );
+ TQSize tqsizeHint() const;
+
+private:
+ void drawContents( TQPainter* );
+ TQCanvas* viewing;
+ TQCanvasViewData* d;
+ friend void qt_unview(TQCanvas* c);
+
+private Q_SLOTS:
+ void cMoving(int,int);
+ void updateContentsSize();
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQCanvasView( const TQCanvasView & );
+ TQCanvasView &operator=( const TQCanvasView & );
+#endif
+};
+
+
+class TQM_EXPORT_CANVAS TQCanvasPixmap : public TQPixmap
+{
+public:
+#ifndef TQT_NO_IMAGEIO
+ TQCanvasPixmap(const TQString& datafilename);
+#endif
+ TQCanvasPixmap(const TQImage& image);
+ TQCanvasPixmap(const TQPixmap&, const TQPoint& hotspot);
+ ~TQCanvasPixmap();
+
+ int offsetX() const
+ { return hotx; }
+ int offsetY() const
+ { return hoty; }
+ void setOffset(int x, int y) { hotx = x; hoty = y; }
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQCanvasPixmap( const TQCanvasPixmap & );
+ TQCanvasPixmap &operator=( const TQCanvasPixmap & );
+#endif
+ void init(const TQImage&);
+ void init(const TQPixmap& pixmap, int hx, int hy);
+
+ friend class TQCanvasSprite;
+ friend class TQCanvasPixmapArray;
+ friend bool qt_testCollision(const TQCanvasSprite* s1, const TQCanvasSprite* s2);
+
+ int hotx,hoty;
+
+ TQImage* collision_mask;
+};
+
+
+class TQM_EXPORT_CANVAS TQCanvasPixmapArray
+{
+public:
+ TQCanvasPixmapArray();
+#ifndef TQT_NO_IMAGEIO
+ TQCanvasPixmapArray(const TQString& datafilenamepattern, int framecount=0);
+#endif
+ // this form is deprecated
+ TQCanvasPixmapArray(TQPtrList<TQPixmap>, TQPtrList<TQPoint> hotspots);
+
+ TQCanvasPixmapArray(TQValueList<TQPixmap>, TQPointArray hotspots = TQPointArray() );
+ ~TQCanvasPixmapArray();
+
+#ifndef TQT_NO_IMAGEIO
+ bool readPixmaps(const TQString& datafilenamepattern, int framecount=0);
+ bool readCollisionMasks(const TQString& filenamepattern);
+#endif
+
+ // deprecated
+ bool operator!(); // Failure check.
+ bool isValid() const;
+
+ TQCanvasPixmap* image(int i) const
+ { return img ? img[i] : 0; }
+ void setImage(int i, TQCanvasPixmap* p);
+ uint count() const
+ { return (uint)framecount; }
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQCanvasPixmapArray( const TQCanvasPixmapArray & );
+ TQCanvasPixmapArray &operator=( const TQCanvasPixmapArray & );
+#endif
+#ifndef TQT_NO_IMAGEIO
+ bool readPixmaps(const TQString& datafilenamepattern, int framecount, bool maskonly);
+#endif
+
+ void reset();
+ int framecount;
+ TQCanvasPixmap** img;
+};
+
+
+class TQM_EXPORT_CANVAS TQCanvasSprite : public TQCanvasItem
+{
+public:
+ TQCanvasSprite(TQCanvasPixmapArray* array, TQCanvas* canvas);
+
+ void setSequence(TQCanvasPixmapArray* seq);
+
+ virtual ~TQCanvasSprite();
+
+ void move(double x, double y);
+ virtual void move(double x, double y, int frame);
+ void setFrame(int);
+ enum FrameAnimationType { Cycle, Oscillate };
+ virtual void setFrameAnimation(FrameAnimationType=Cycle, int step=1, int state=0);
+ int frame() const
+ { return frm; }
+ int frameCount() const
+ { return images->count(); }
+
+ int rtti() const;
+ static int RTTI;
+
+ bool collidesWith( const TQCanvasItem* ) const;
+
+ TQRect boundingRect() const;
+
+ // is there a reason for these to be protected? Lars
+//protected:
+
+ int width() const;
+ int height() const;
+
+ int leftEdge() const;
+ int topEdge() const;
+ int rightEdge() const;
+ int bottomEdge() const;
+
+ int leftEdge(int nx) const;
+ int topEdge(int ny) const;
+ int rightEdge(int nx) const;
+ int bottomEdge(int ny) const;
+ TQCanvasPixmap* image() const
+ { return images->image(frm); }
+ virtual TQCanvasPixmap* imageAdvanced() const;
+ TQCanvasPixmap* image(int f) const
+ { return images->image(f); }
+ virtual void advance(int stage);
+
+public:
+ void draw(TQPainter& painter);
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQCanvasSprite( const TQCanvasSprite & );
+ TQCanvasSprite &operator=( const TQCanvasSprite & );
+#endif
+ void addToChunks();
+ void removeFromChunks();
+ void changeChunks();
+
+ int frm;
+ ushort anim_val;
+ uint anim_state:2;
+ uint anim_type:14;
+ bool collidesWith( const TQCanvasSprite*,
+ const TQCanvasPolygonalItem*,
+ const TQCanvasRectangle*,
+ const TQCanvasEllipse*,
+ const TQCanvasText* ) const;
+
+ friend bool qt_testCollision( const TQCanvasSprite* s1,
+ const TQCanvasSprite* s2 );
+
+ TQCanvasPixmapArray* images;
+};
+
+class TQPolygonalProcessor;
+
+class TQM_EXPORT_CANVAS TQCanvasPolygonalItem : public TQCanvasItem
+{
+public:
+ TQCanvasPolygonalItem(TQCanvas* canvas);
+ virtual ~TQCanvasPolygonalItem();
+
+ bool collidesWith( const TQCanvasItem* ) const;
+
+ virtual void setPen(TQPen p);
+ virtual void setBrush(TQBrush b);
+
+ TQPen pen() const
+ { return pn; }
+ TQBrush brush() const
+ { return br; }
+
+ virtual TQPointArray areaPoints() const=0;
+ virtual TQPointArray areaPointsAdvanced() const;
+ TQRect boundingRect() const;
+
+ int rtti() const;
+ static int RTTI;
+
+protected:
+ void draw(TQPainter &);
+ virtual void drawShape(TQPainter &) = 0;
+
+ bool winding() const;
+ void setWinding(bool);
+
+ void tqinvalidate();
+ bool isValid() const
+ { return (bool)val; }
+
+private:
+ void scanPolygon( const TQPointArray& pa, int winding,
+ TQPolygonalProcessor& process ) const;
+ TQPointArray chunks() const;
+
+ bool collidesWith( const TQCanvasSprite*,
+ const TQCanvasPolygonalItem*,
+ const TQCanvasRectangle*,
+ const TQCanvasEllipse*,
+ const TQCanvasText* ) const;
+
+ TQBrush br;
+ TQPen pn;
+ uint wind:1;
+};
+
+
+class TQM_EXPORT_CANVAS TQCanvasRectangle : public TQCanvasPolygonalItem
+{
+public:
+ TQCanvasRectangle(TQCanvas* canvas);
+ TQCanvasRectangle(const TQRect&, TQCanvas* canvas);
+ TQCanvasRectangle(int x, int y, int width, int height, TQCanvas* canvas);
+
+ ~TQCanvasRectangle();
+
+ int width() const;
+ int height() const;
+ void setSize(int w, int h);
+ TQSize size() const
+ { return TQSize(w,h); }
+ TQPointArray areaPoints() const;
+ TQRect rect() const
+ { return TQRect(int(x()),int(y()),w,h); }
+
+ bool collidesWith( const TQCanvasItem* ) const;
+
+ int rtti() const;
+ static int RTTI;
+
+protected:
+ void drawShape(TQPainter &);
+ TQPointArray chunks() const;
+
+private:
+ bool collidesWith( const TQCanvasSprite*,
+ const TQCanvasPolygonalItem*,
+ const TQCanvasRectangle*,
+ const TQCanvasEllipse*,
+ const TQCanvasText* ) const;
+
+ int w, h;
+};
+
+
+class TQM_EXPORT_CANVAS TQCanvasPolygon : public TQCanvasPolygonalItem
+{
+public:
+ TQCanvasPolygon(TQCanvas* canvas);
+ ~TQCanvasPolygon();
+ void setPoints(TQPointArray);
+ TQPointArray points() const;
+ void moveBy(double dx, double dy);
+
+ TQPointArray areaPoints() const;
+
+ int rtti() const;
+ static int RTTI;
+
+protected:
+ void drawShape(TQPainter &);
+ TQPointArray poly;
+};
+
+
+class TQM_EXPORT_CANVAS TQCanvasSpline : public TQCanvasPolygon
+{
+public:
+ TQCanvasSpline(TQCanvas* canvas);
+ ~TQCanvasSpline();
+
+ void setControlPoints(TQPointArray, bool closed=TRUE);
+ TQPointArray controlPoints() const;
+ bool closed() const;
+
+ int rtti() const;
+ static int RTTI;
+
+private:
+ void recalcPoly();
+ TQPointArray bez;
+ bool cl;
+};
+
+
+class TQM_EXPORT_CANVAS TQCanvasLine : public TQCanvasPolygonalItem
+{
+public:
+ TQCanvasLine(TQCanvas* canvas);
+ ~TQCanvasLine();
+ void setPoints(int x1, int y1, int x2, int y2);
+
+ TQPoint startPoint() const
+ { return TQPoint(x1,y1); }
+ TQPoint endPoint() const
+ { return TQPoint(x2,y2); }
+
+ int rtti() const;
+ static int RTTI;
+
+ void setPen(TQPen p);
+ void moveBy(double dx, double dy);
+
+protected:
+ void drawShape(TQPainter &);
+ TQPointArray areaPoints() const;
+
+private:
+ int x1,y1,x2,y2;
+};
+
+
+class TQM_EXPORT_CANVAS TQCanvasEllipse : public TQCanvasPolygonalItem
+{
+
+public:
+ TQCanvasEllipse( TQCanvas* canvas );
+ TQCanvasEllipse( int width, int height, TQCanvas* canvas );
+ TQCanvasEllipse( int width, int height, int startangle, int angle,
+ TQCanvas* canvas );
+
+ ~TQCanvasEllipse();
+
+ int width() const;
+ int height() const;
+ void setSize(int w, int h);
+ void setAngles(int start, int length);
+ int angleStart() const
+ { return a1; }
+ int angleLength() const
+ { return a2; }
+ TQPointArray areaPoints() const;
+
+ bool collidesWith( const TQCanvasItem* ) const;
+
+ int rtti() const;
+ static int RTTI;
+
+protected:
+ void drawShape(TQPainter &);
+
+private:
+ bool collidesWith( const TQCanvasSprite*,
+ const TQCanvasPolygonalItem*,
+ const TQCanvasRectangle*,
+ const TQCanvasEllipse*,
+ const TQCanvasText* ) const;
+ int w, h;
+ int a1, a2;
+};
+
+
+class TQCanvasTextExtra;
+
+class TQM_EXPORT_CANVAS TQCanvasText : public TQCanvasItem
+{
+public:
+ TQCanvasText(TQCanvas* canvas);
+ TQCanvasText(const TQString&, TQCanvas* canvas);
+ TQCanvasText(const TQString&, TQFont, TQCanvas* canvas);
+
+ virtual ~TQCanvasText();
+
+ void setText( const TQString& );
+ void setFont( const TQFont& );
+ void setColor( const TQColor& );
+ TQString text() const;
+ TQFont font() const;
+ TQColor color() const;
+
+ void moveBy(double dx, double dy);
+
+ int textFlags() const
+ { return flags; }
+ void setTextFlags(int);
+
+ TQRect boundingRect() const;
+
+ bool collidesWith( const TQCanvasItem* ) const;
+
+ int rtti() const;
+ static int RTTI;
+
+protected:
+ virtual void draw(TQPainter&);
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQCanvasText( const TQCanvasText & );
+ TQCanvasText &operator=( const TQCanvasText & );
+#endif
+ void addToChunks();
+ void removeFromChunks();
+ void changeChunks();
+
+ void setRect();
+ TQRect brect;
+ TQString txt;
+ int flags;
+ TQFont fnt;
+ TQColor col;
+ TQCanvasTextExtra* extra;
+
+ bool collidesWith( const TQCanvasSprite*,
+ const TQCanvasPolygonalItem*,
+ const TQCanvasRectangle*,
+ const TQCanvasEllipse*,
+ const TQCanvasText* ) const;
+};
+
+#define TQ_DEFINED_TQCANVAS
+#include "tqwinexport.h"
+#endif // TQT_NO_CANVAS
+
+#endif // TQCANVAS_H
diff --git a/tqtinterface/qt4/src/codecs/qt_codecs.pri b/tqtinterface/qt4/src/codecs/qt_codecs.pri
new file mode 100644
index 0000000..800c9af
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/qt_codecs.pri
@@ -0,0 +1,48 @@
+# Qt codecs module
+
+!bigcodecs:DEFINES += TQT_NO_BIG_CODECS
+tools {
+ CODECS_P = codecs
+ HEADERS += \
+#$$CODECS_H/tqastqmocodec.h \
+ $$CODECS_H/tqbig5codec.h \
+ $$CODECS_H/tqeucjpcodec.h \
+ $$CODECS_H/tqeuckrcodec.h \
+ $$CODECS_P/tqisciicodec_p.h \
+ $$CODECS_H/tqgb18030codec.h \
+ $$CODECS_H/tqjiscodec.h \
+ $$CODECS_H/tqjpunicode.h \
+ $$CODECS_H/tqrtlcodec.h \
+ $$CODECS_H/tqsjiscodec.h \
+ $$CODECS_H/tqtextcodec.h \
+ $$CODECS_H/tqtsciicodec.h \
+ $$CODECS_H/tqutfcodec.h \
+ $$CODECS_P/tqtextcodecinterface_p.h \
+ $$CODECS_H/tqtextcodecfactory.h \
+ $$CODECS_H/tqtextcodecplugin.h
+
+ SOURCES += \
+#$$CODECS_CPP/tqastqmocodec.cpp \
+ $$CODECS_CPP/tqbig5codec.cpp \
+ $$CODECS_CPP/tqeucjpcodec.cpp \
+ $$CODECS_CPP/tqeuckrcodec.cpp \
+ $$CODECS_CPP/tqisciicodec.cpp \
+ $$CODECS_CPP/tqgb18030codec.cpp \
+ $$CODECS_CPP/tqjiscodec.cpp \
+ $$CODECS_CPP/tqjpunicode.cpp \
+ $$CODECS_CPP/tqrtlcodec.cpp \
+ $$CODECS_CPP/tqsjiscodec.cpp \
+ $$CODECS_CPP/tqtextcodec.cpp \
+ $$CODECS_CPP/tqtsciicodec.cpp \
+ $$CODECS_CPP/tqutfcodec.cpp \
+ $$CODECS_CPP/tqtextcodecfactory.cpp \
+ $$CODECS_CPP/tqtextcodecplugin.cpp
+
+ x11:SOURCES += $$CODECS_CPP/tqfontcncodec.cpp \
+ $$CODECS_CPP/tqfonthkcodec.cpp \
+ $$CODECS_CPP/tqfontjpcodec.cpp \
+ $$CODECS_CPP/tqfontkrcodec.cpp \
+ $$CODECS_CPP/tqfontlaocodec.cpp \
+ $$CODECS_CPP/tqfonttwcodec.cpp
+ x11:HEADERS += $$CODECS_P/tqfontcodecs_p.h
+}
diff --git a/tqtinterface/qt4/src/codecs/tqbig5codec.cpp b/tqtinterface/qt4/src/codecs/tqbig5codec.cpp
new file mode 100644
index 0000000..bdab025
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqbig5codec.cpp
@@ -0,0 +1,11766 @@
+/****************************************************************************
+**
+** Implementation of TQBig5Codec class
+**
+** Created : 990713
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/*!
+ \class TQBig5Codec tqbig5codec.h
+ \ingroup i18n
+
+ \brief The TQBig5Codec class provides conversion to and from the Big5 encoding.
+
+ TQBig5Codec was originally contributed by Ming-Che Chuang
+ \<mingche@cobra.ee.ntu.edu.tw\> for the Big-5+ encoding, and was
+ included in TQt with the author's permission, and the grateful
+ thanks of the Trolltech team. (Note: Ming-Che's code is TQPL'd, as
+ per an mail to info@trolltech.com.)
+
+ However, since Big-5+ was never formally approved, and was never
+ used by anyone, the Taiwan Free Software community and the Li18nux
+ Big5 Standard Subgroup agree that the de-facto standard Big5-ETen
+ (zh_TW.Big5 or zh_TW.TW-Big5) be used instead.
+
+ TQBig5Codec is currently implemented as a pure subset of
+ TQBig5hkscsCodec, so more fine-tuning is needed to make it
+ identical to the standard Big5 mapping as determined by
+ Li18nux-Big5. See \l{http://www.autrijus.org/xml/} for the draft
+ Big5 (2002) standard.
+
+ James Su \<suzhe@turbolinux.com.cn\> \<suzhe@gnuchina.org\>
+ generated the Big5-HKSCS\<-\>Unicode tables with a very
+ space-efficient algorithm. He generously donated his code to glibc
+ in May 2002. Subsequently, James has kindly allowed Anthony Fok
+ \<anthony@thizlinux.com\> \<foka@debian.org\> to adapt the code
+ for TQt.
+
+ \legalese
+
+ Copyright (C) 2000 Ming-Che Chuang
+ Copyright (C) 2002 James Su, Turbolinux Inc.
+ Copyright (C) 2002 Anthony Fok, ThizLinux Laboratory Ltd.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ \list 1
+ \i Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ \i Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ \endlist
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+#include "tqbig5codec.h"
+
+#ifndef TQT_NO_BIG_CODECS
+
+static int qt_Big5hkscsToUnicode(const uchar *s, uint *pwc);
+int qt_UnicodeToBig5hkscs(uint wc, uchar *r);
+
+#define InRange(c, lower, upper) (((c) >= (lower)) && ((c) <= (upper)))
+#define IsLatin(c) ((c) < 0x80)
+#define IsFirstByte(c) (InRange((c), 0x81, 0xFE))
+#define IsSecondByteRange1(c) (InRange((c), 0x40, 0x7E))
+#define IsSecondByteRange2(c) (InRange((c), 0xA1, 0xFE))
+#define IsSecondByte(c) (IsSecondByteRange1(c) || IsSecondByteRange2(c))
+
+#define TQValidChar(u) ((u) ? TQChar((ushort)(u)) : TQChar::tqreplacement)
+
+struct B5Map {
+ ushort x;
+ ushort y;
+};
+
+static const B5Map b5_to_uc_map[] = {
+ { 0xc6a1, 0xf6b1 },
+ { 0xc6a2, 0xf6b2 },
+ { 0xc6a3, 0xf6b3 },
+ { 0xc6a4, 0xf6b4 },
+ { 0xc6a5, 0xf6b5 },
+ { 0xc6a6, 0xf6b6 },
+ { 0xc6a7, 0xf6b7 },
+ { 0xc6a8, 0xf6b8 },
+ { 0xc6a9, 0xf6b9 },
+ { 0xc6aa, 0xf6ba },
+ { 0xc6ab, 0xf6bb },
+ { 0xc6ac, 0xf6bc },
+ { 0xc6ad, 0xf6bd },
+ { 0xc6ae, 0xf6be },
+ { 0xc6af, 0xf6bf },
+ { 0xc6b0, 0xf6c0 },
+ { 0xc6b1, 0xf6c1 },
+ { 0xc6b2, 0xf6c2 },
+ { 0xc6b3, 0xf6c3 },
+ { 0xc6b4, 0xf6c4 },
+ { 0xc6b5, 0xf6c5 },
+ { 0xc6b6, 0xf6c6 },
+ { 0xc6b7, 0xf6c7 },
+ { 0xc6b8, 0xf6c8 },
+ { 0xc6b9, 0xf6c9 },
+ { 0xc6ba, 0xf6ca },
+ { 0xc6bb, 0xf6cb },
+ { 0xc6bc, 0xf6cc },
+ { 0xc6bd, 0xf6cd },
+ { 0xc6be, 0xf6ce },
+ { 0xc6bf, 0xf6cf },
+ { 0xc6c0, 0xf6d0 },
+ { 0xc6c1, 0xf6d1 },
+ { 0xc6c2, 0xf6d2 },
+ { 0xc6c3, 0xf6d3 },
+ { 0xc6c4, 0xf6d4 },
+ { 0xc6c5, 0xf6d5 },
+ { 0xc6c6, 0xf6d6 },
+ { 0xc6c7, 0xf6d7 },
+ { 0xc6c8, 0xf6d8 },
+ { 0xc6c9, 0xf6d9 },
+ { 0xc6ca, 0xf6da },
+ { 0xc6cb, 0xf6db },
+ { 0xc6cc, 0xf6dc },
+ { 0xc6cd, 0xf6dd },
+ { 0xc6ce, 0xf6de },
+ { 0xc6d0, 0xf6e0 },
+ { 0xc6d1, 0xf6e1 },
+ { 0xc6d2, 0xf6e2 },
+ { 0xc6d4, 0xf6e4 },
+ { 0xc6d6, 0xf6e6 },
+ { 0xc6d8, 0xf6e8 },
+ { 0xc6d9, 0xf6e9 },
+ { 0xc6da, 0xf6ea },
+ { 0xc6db, 0xf6eb },
+ { 0xc6dc, 0xf6ec },
+ { 0xc6dd, 0xf6ed },
+ { 0xc6e0, 0xf6f0 },
+ { 0xc6e1, 0xf6f1 },
+ { 0xc6e2, 0xf6f2 },
+ { 0xc6e3, 0xf6f3 },
+ { 0xc6e4, 0xf6f4 },
+ { 0xc6e5, 0xf6f5 },
+ { 0xc6e6, 0xf6f6 },
+ { 0xc6e7, 0xf6f7 },
+ { 0xc6e8, 0xf6f8 },
+ { 0xc6e9, 0xf6f9 },
+ { 0xc6ea, 0xf6fa },
+ { 0xc6eb, 0xf6fb },
+ { 0xc6ec, 0xf6fc },
+ { 0xc6ed, 0xf6fd },
+ { 0xc6ee, 0xf6fe },
+ { 0xc6ef, 0xf6ff },
+ { 0xc6f0, 0xf700 },
+ { 0xc6f1, 0xf701 },
+ { 0xc6f2, 0xf702 },
+ { 0xc6f3, 0xf703 },
+ { 0xc6f4, 0xf704 },
+ { 0xc6f5, 0xf705 },
+ { 0xc6f6, 0xf706 },
+ { 0xc6f7, 0xf707 },
+ { 0xc6f8, 0xf708 },
+ { 0xc6f9, 0xf709 },
+ { 0xc6fa, 0xf70a },
+ { 0xc6fb, 0xf70b },
+ { 0xc6fc, 0xf70c },
+ { 0xc6fd, 0xf70d },
+ { 0xc6fe, 0xf70e },
+ { 0xc740, 0xf70f },
+ { 0xc741, 0xf710 },
+ { 0xc742, 0xf711 },
+ { 0xc743, 0xf712 },
+ { 0xc744, 0xf713 },
+ { 0xc745, 0xf714 },
+ { 0xc746, 0xf715 },
+ { 0xc747, 0xf716 },
+ { 0xc748, 0xf717 },
+ { 0xc749, 0xf718 },
+ { 0xc74a, 0xf719 },
+ { 0xc74b, 0xf71a },
+ { 0xc74c, 0xf71b },
+ { 0xc74d, 0xf71c },
+ { 0xc74e, 0xf71d },
+ { 0xc74f, 0xf71e },
+ { 0xc750, 0xf71f },
+ { 0xc751, 0xf720 },
+ { 0xc752, 0xf721 },
+ { 0xc753, 0xf722 },
+ { 0xc754, 0xf723 },
+ { 0xc755, 0xf724 },
+ { 0xc756, 0xf725 },
+ { 0xc757, 0xf726 },
+ { 0xc758, 0xf727 },
+ { 0xc759, 0xf728 },
+ { 0xc75a, 0xf729 },
+ { 0xc75b, 0xf72a },
+ { 0xc75c, 0xf72b },
+ { 0xc75d, 0xf72c },
+ { 0xc75e, 0xf72d },
+ { 0xc75f, 0xf72e },
+ { 0xc760, 0xf72f },
+ { 0xc761, 0xf730 },
+ { 0xc762, 0xf731 },
+ { 0xc763, 0xf732 },
+ { 0xc764, 0xf733 },
+ { 0xc765, 0xf734 },
+ { 0xc766, 0xf735 },
+ { 0xc767, 0xf736 },
+ { 0xc768, 0xf737 },
+ { 0xc769, 0xf738 },
+ { 0xc76a, 0xf739 },
+ { 0xc76b, 0xf73a },
+ { 0xc76c, 0xf73b },
+ { 0xc76d, 0xf73c },
+ { 0xc76e, 0xf73d },
+ { 0xc76f, 0xf73e },
+ { 0xc770, 0xf73f },
+ { 0xc771, 0xf740 },
+ { 0xc772, 0xf741 },
+ { 0xc773, 0xf742 },
+ { 0xc774, 0xf743 },
+ { 0xc775, 0xf744 },
+ { 0xc776, 0xf745 },
+ { 0xc777, 0xf746 },
+ { 0xc778, 0xf747 },
+ { 0xc779, 0xf748 },
+ { 0xc77a, 0xf749 },
+ { 0xc77b, 0xf74a },
+ { 0xc77c, 0xf74b },
+ { 0xc77d, 0xf74c },
+ { 0xc77e, 0xf74d },
+ { 0xc7a1, 0xf74e },
+ { 0xc7a2, 0xf74f },
+ { 0xc7a3, 0xf750 },
+ { 0xc7a4, 0xf751 },
+ { 0xc7a5, 0xf752 },
+ { 0xc7a6, 0xf753 },
+ { 0xc7a7, 0xf754 },
+ { 0xc7a8, 0xf755 },
+ { 0xc7a9, 0xf756 },
+ { 0xc7aa, 0xf757 },
+ { 0xc7ab, 0xf758 },
+ { 0xc7ac, 0xf759 },
+ { 0xc7ad, 0xf75a },
+ { 0xc7ae, 0xf75b },
+ { 0xc7af, 0xf75c },
+ { 0xc7b0, 0xf75d },
+ { 0xc7b1, 0xf75e },
+ { 0xc7b2, 0xf75f },
+ { 0xc7b3, 0xf760 },
+ { 0xc7b4, 0xf761 },
+ { 0xc7b5, 0xf762 },
+ { 0xc7b6, 0xf763 },
+ { 0xc7b7, 0xf764 },
+ { 0xc7b8, 0xf765 },
+ { 0xc7b9, 0xf766 },
+ { 0xc7ba, 0xf767 },
+ { 0xc7bb, 0xf768 },
+ { 0xc7bc, 0xf769 },
+ { 0xc7bd, 0xf76a },
+ { 0xc7be, 0xf76b },
+ { 0xc7bf, 0xf76c },
+ { 0xc7c0, 0xf76d },
+ { 0xc7c1, 0xf76e },
+ { 0xc7c2, 0xf76f },
+ { 0xc7c3, 0xf770 },
+ { 0xc7c4, 0xf771 },
+ { 0xc7c5, 0xf772 },
+ { 0xc7c6, 0xf773 },
+ { 0xc7c7, 0xf774 },
+ { 0xc7c8, 0xf775 },
+ { 0xc7c9, 0xf776 },
+ { 0xc7ca, 0xf777 },
+ { 0xc7cb, 0xf778 },
+ { 0xc7cc, 0xf779 },
+ { 0xc7cd, 0xf77a },
+ { 0xc7ce, 0xf77b },
+ { 0xc7cf, 0xf77c },
+ { 0xc7d0, 0xf77d },
+ { 0xc7d1, 0xf77e },
+ { 0xc7d2, 0xf77f },
+ { 0xc7d3, 0xf780 },
+ { 0xc7d4, 0xf781 },
+ { 0xc7d5, 0xf782 },
+ { 0xc7d6, 0xf783 },
+ { 0xc7d7, 0xf784 },
+ { 0xc7d8, 0xf785 },
+ { 0xc7d9, 0xf786 },
+ { 0xc7da, 0xf787 },
+ { 0xc7db, 0xf788 },
+ { 0xc7dc, 0xf789 },
+ { 0xc7dd, 0xf78a },
+ { 0xc7de, 0xf78b },
+ { 0xc7df, 0xf78c },
+ { 0xc7e0, 0xf78d },
+ { 0xc7e1, 0xf78e },
+ { 0xc7e2, 0xf78f },
+ { 0xc7e3, 0xf790 },
+ { 0xc7e4, 0xf791 },
+ { 0xc7e5, 0xf792 },
+ { 0xc7e6, 0xf793 },
+ { 0xc7e7, 0xf794 },
+ { 0xc7e8, 0xf795 },
+ { 0xc7e9, 0xf796 },
+ { 0xc7ea, 0xf797 },
+ { 0xc7eb, 0xf798 },
+ { 0xc7ec, 0xf799 },
+ { 0xc7ed, 0xf79a },
+ { 0xc7ee, 0xf79b },
+ { 0xc7ef, 0xf79c },
+ { 0xc7f0, 0xf79d },
+ { 0xc7f1, 0xf79e },
+ { 0xc7f2, 0xf79f },
+ { 0xc7f3, 0xf7a0 },
+ { 0xc7f4, 0xf7a1 },
+ { 0xc7f5, 0xf7a2 },
+ { 0xc7f6, 0xf7a3 },
+ { 0xc7f7, 0xf7a4 },
+ { 0xc7f8, 0xf7a5 },
+ { 0xc7f9, 0xf7a6 },
+ { 0xc7fa, 0xf7a7 },
+ { 0xc7fb, 0xf7a8 },
+ { 0xc7fc, 0xf7a9 },
+ { 0xc7fd, 0xf7aa },
+ { 0xc7fe, 0xf7ab },
+ { 0xc840, 0xf7ac },
+ { 0xc841, 0xf7ad },
+ { 0xc842, 0xf7ae },
+ { 0xc843, 0xf7af },
+ { 0xc844, 0xf7b0 },
+ { 0xc845, 0xf7b1 },
+ { 0xc846, 0xf7b2 },
+ { 0xc847, 0xf7b3 },
+ { 0xc848, 0xf7b4 },
+ { 0xc849, 0xf7b5 },
+ { 0xc84a, 0xf7b6 },
+ { 0xc84b, 0xf7b7 },
+ { 0xc84c, 0xf7b8 },
+ { 0xc84d, 0xf7b9 },
+ { 0xc84e, 0xf7ba },
+ { 0xc84f, 0xf7bb },
+ { 0xc850, 0xf7bc },
+ { 0xc851, 0xf7bd },
+ { 0xc852, 0xf7be },
+ { 0xc853, 0xf7bf },
+ { 0xc854, 0xf7c0 },
+ { 0xc855, 0xf7c1 },
+ { 0xc856, 0xf7c2 },
+ { 0xc857, 0xf7c3 },
+ { 0xc858, 0xf7c4 },
+ { 0xc859, 0xf7c5 },
+ { 0xc85a, 0xf7c6 },
+ { 0xc85b, 0xf7c7 },
+ { 0xc85c, 0xf7c8 },
+ { 0xc85d, 0xf7c9 },
+ { 0xc85e, 0xf7ca },
+ { 0xc85f, 0xf7cb },
+ { 0xc860, 0xf7cc },
+ { 0xc861, 0xf7cd },
+ { 0xc862, 0xf7ce },
+ { 0xc863, 0xf7cf },
+ { 0xc864, 0xf7d0 },
+ { 0xc865, 0xf7d1 },
+ { 0xc866, 0xf7d2 },
+ { 0xc867, 0xf7d3 },
+ { 0xc868, 0xf7d4 },
+ { 0xc869, 0xf7d5 },
+ { 0xc86a, 0xf7d6 },
+ { 0xc86b, 0xf7d7 },
+ { 0xc86c, 0xf7d8 },
+ { 0xc86d, 0xf7d9 },
+ { 0xc86e, 0xf7da },
+ { 0xc86f, 0xf7db },
+ { 0xc870, 0xf7dc },
+ { 0xc871, 0xf7dd },
+ { 0xc872, 0xf7de },
+ { 0xc873, 0xf7df },
+ { 0xc874, 0xf7e0 },
+ { 0xc875, 0xf7e1 },
+ { 0xc876, 0xf7e2 },
+ { 0xc877, 0xf7e3 },
+ { 0xc878, 0xf7e4 },
+ { 0xc87b, 0xf7e7 },
+ { 0xc87d, 0xf7e9 },
+ { 0xc8a2, 0xf7ec },
+ { 0xc8cd, 0xf817 },
+ { 0xc8ce, 0xf818 },
+ { 0xc8cf, 0xf819 },
+ { 0xc8d0, 0xf81a },
+ { 0xc8d1, 0xf81b },
+ { 0xc8d2, 0xf81c },
+ { 0xc8d3, 0xf81d },
+ { 0xc8d4, 0xf81e },
+ { 0xc8d5, 0xf81f },
+ { 0xc8d6, 0xf820 },
+ { 0xc8d7, 0xf821 },
+ { 0xc8d8, 0xf822 },
+ { 0xc8d9, 0xf823 },
+ { 0xc8da, 0xf824 },
+ { 0xc8db, 0xf825 },
+ { 0xc8dc, 0xf826 },
+ { 0xc8dd, 0xf827 },
+ { 0xc8de, 0xf828 },
+ { 0xc8df, 0xf829 },
+ { 0xc8e0, 0xf82a },
+ { 0xc8e1, 0xf82b },
+ { 0xc8e2, 0xf82c },
+ { 0xc8e3, 0xf82d },
+ { 0xc8e4, 0xf82e },
+ { 0xc8e5, 0xf82f },
+ { 0xc8e6, 0xf830 },
+ { 0xc8e7, 0xf831 },
+ { 0xc8e8, 0xf832 },
+ { 0xc8e9, 0xf833 },
+ { 0xc8ea, 0xf834 },
+ { 0xc8eb, 0xf835 },
+ { 0xc8ec, 0xf836 },
+ { 0xc8ed, 0xf837 },
+ { 0xc8ee, 0xf838 },
+ { 0xc8ef, 0xf839 },
+ { 0xc8f0, 0xf83a },
+ { 0xc8f1, 0xf83b },
+ { 0xc8f5, 0xf83f },
+ { 0xc8f6, 0xf840 },
+ { 0xc8f7, 0xf841 },
+ { 0xc8f8, 0xf842 },
+ { 0xc8f9, 0xf843 },
+ { 0xc8fa, 0xf844 },
+ { 0xc8fb, 0xf845 },
+ { 0xc8fc, 0xf846 },
+ { 0xc8fd, 0xf847 },
+ { 0xc8fe, 0xf848 },
+ { 0xf9fe, 0x2593 }
+};
+
+static const B5Map uc_to_b5_map[] = {
+ { 0x2550, 0xa2a4 },
+ { 0x255e, 0xa2a5 },
+ { 0x2561, 0xa2a7 },
+ { 0x256a, 0xa2a6 },
+ { 0x256d, 0xa27e },
+ { 0x256e, 0xa2a1 },
+ { 0x256f, 0xa2a3 },
+ { 0x2570, 0xa2a2 },
+};
+
+static int qt_Big5ToUnicode(const uchar *buf, uint *u)
+{
+ int start = 0;
+ int end = sizeof(b5_to_uc_map)/sizeof(B5Map) - 1;
+
+ uint b5 = (buf[0] << 8) + buf[1];
+ while (start <= end) {
+ int middle = (end + start + 1)/2;
+ if (b5_to_uc_map[middle].x == b5) {
+ *u = b5_to_uc_map[middle].y;
+ return 2;
+ } else if (b5_to_uc_map[middle].x > b5) {
+ end = middle - 1;
+ } else {
+ start = middle + 1;
+ }
+ }
+ return qt_Big5hkscsToUnicode(buf, u);
+}
+
+static int qt_UnicodeToBig5(ushort ch, uchar *buf)
+{
+ int start = 0;
+ int end = sizeof(uc_to_b5_map)/sizeof(B5Map) - 1;
+
+ while (start <= end) {
+ int middle = (end + start + 1)/2;
+ if (uc_to_b5_map[middle].x == ch) {
+ buf[0] = uc_to_b5_map[middle].y >> 8;
+ buf[1] = uc_to_b5_map[middle].y & 0xff;
+ return 2;
+ } else if (uc_to_b5_map[middle].x > ch) {
+ end = middle - 1;
+ } else {
+ start = middle + 1;
+ }
+ }
+ return qt_UnicodeToBig5hkscs(ch, buf);
+}
+
+
+/*! \reimp */
+int TQBig5Codec::mibEnum() const
+{
+ /* See http://www.iana.org/assignments/character-sets */
+ //qDebug("TQBig5Codec::mibEnum() = 2026");
+ return 2026;
+}
+
+
+/*! \reimp */
+const char* TQBig5Codec::name() const
+{
+ //qDebug("TQBig5Codec::name() = \"Big5\"");
+ return "Big5";
+}
+
+
+class TQBig5Decoder : public TQTextDecoder {
+ uchar buf[2];
+ int nbuf;
+public:
+ TQBig5Decoder() : nbuf(0)
+ {
+ }
+
+ TQString toUnicode(const char* chars, int len)
+ {
+ //qDebug("TQBig5Decoder::toUnicode(const char* chars = \"%s\", int len = %d)", chars, len);
+ TQString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ switch (nbuf) {
+ case 0:
+ if ( IsLatin(ch) ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( IsFirstByte(ch) ) {
+ // Big5-ETen
+ buf[0] = ch;
+ nbuf = 1;
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ break;
+ case 1:
+ if ( IsSecondByte(ch) ) {
+ // Big5-ETen
+ uint u;
+ buf[1] = ch;
+ if ( qt_Big5ToUnicode( buf, &u ) == 2 )
+ result += TQValidChar(u);
+ else {
+ // Error
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ // Error
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ break;
+ }
+ }
+ return result;
+ }
+};
+
+
+/*! \reimp */
+TQTextDecoder* TQBig5Codec::makeDecoder() const
+{
+ //qDebug("TQBig5Codec::makeDecoder()");
+ return new TQBig5Decoder();
+}
+
+
+/*! \reimp */
+TQCString TQBig5Codec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ //qDebug("TQBig5Codec::fromUnicode(const TQString& uc, int& lenInOut = %d)", lenInOut);
+ int l = TQMIN((int)uc.length(),lenInOut);
+ int rlen = l*3+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+ for (int i=0; i<l; i++) {
+ TQChar ch = uc[i];
+ uchar c[2];
+ if ( ch.row() == 0x00 && ch.cell() < 0x80 ) {
+ // ASCII
+ *cursor++ = ch.cell();
+ } else if ( qt_UnicodeToBig5( ch.tqunicode(), c ) == 2
+ && c[0] >= 0xa1 && c[0] <= 0xf9 ) {
+ // Note to self: This needs better fine-tuning so it is
+ // identical to the orthodox Big5-ETen. (Anthony)
+ // Big5-ETen
+ *cursor++ = c[0];
+ *cursor++ = c[1];
+ } else {
+ // Error
+ *cursor++ = '?'; // unknown char
+ }
+ }
+ lenInOut = cursor - (uchar*)rstr.data();
+ rstr.truncate(lenInOut);
+ return rstr;
+}
+
+
+/*! \reimp */
+TQString TQBig5Codec::toUnicode(const char* chars, int len) const
+{
+ //qDebug("TQBig5Codec::toUnicode(const char* chars \"%s\", int len = %d)", chars, len);
+ TQString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ if ( IsLatin(ch) ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( IsFirstByte(ch) ) {
+ // Big5-ETen
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( IsSecondByte(c2) ) {
+ uint u;
+ if ( qt_Big5ToUnicode( (const uchar*)(chars + i - 1), &u ) == 2 )
+ result += TQValidChar(u);
+ else {
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ i--;
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ // Bad String
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ }
+ return result;
+}
+
+
+/*! \reimp */
+int TQBig5Codec::heuristicContentMatch(const char* chars, int len) const
+{
+ //qDebug("TQBig5Codec::heuristicContentMatch(const char* chars, int len = %d)", len);
+ int score = 0;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ // No nulls allowed.
+ if ( !ch )
+ return -1;
+ if ( ch < 32 && ch != '\t' && ch != '\n' && ch != '\r' ) {
+ // Suspicious
+ if ( score )
+ score--;
+ } else if ( ch < 0x80 ) {
+ // Inconclusive
+ score++;
+ } else if ( IsFirstByte(ch) ) {
+ // Big5-HKSCS
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( !IsSecondByte(c2) )
+ return -1;
+ score += 2;
+ }
+ score++;
+ } else {
+ // Invalid
+ return -1;
+ }
+ }
+ //qDebug("TQBig5Codec::heuristicContentMatch() score = %d", score);
+ return score;
+}
+
+
+/*! \reimp */
+int TQBig5Codec::heuristicNameMatch(const char* hint) const
+{
+ //qDebug("TQBig5hkscsCodec::heuristicNameMatch(const char* hint = \"%s\")", hint);
+ int score = 0;
+ bool zh = FALSE;
+ if (qstrnicmp(hint, "zh_TW", 5) == 0) {
+ score += 16;
+ zh = TRUE;
+ }
+ else if ( qstrnicmp(hint, "zh", 2) == 0 ||
+ qstrnicmp(hint, "chinese", 7) == 0) {
+ score += 2;
+ zh = TRUE;
+ }
+ const char *p;
+ if (zh) {
+ p = strchr(hint, '.');
+ if (p == 0)
+ return score;
+ p++;
+ } else {
+ p = hint;
+ }
+ if (p) {
+ if ( qstricmp(p, "Big5") == 0 ||
+ qstricmp(p, "TW-Big5") == 0 ) {
+ return score + 10;
+ }
+ else if ( qstrnicmp(p, "Big5", 4) == 0 )
+ return score + 2;
+ }
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+
+/*! \class TQBig5hkscsCodec
+
+ \brief The TQBig5hkscsCodec class provides conversion to and from the Big5-HKSCS encoding.
+
+ TQBig5hkscsCodec grew out of the TQBig5Codec originally contributed by
+ Ming-Che Chuang \<mingche@cobra.ee.ntu.edu.tw\>. James Su
+ \<suzhe@turbolinux.com.cn\> \<suzhe@gnuchina.org\> and Anthony Fok
+ \<anthony@thizlinux.com\> \<foka@debian.org\> implemented HKSCS-1999
+ TQBig5hkscsCodec for TQt-2.3.x, but it was too late in TQt development
+ schedule to be officially included in the TQt-2.3.x series.
+
+ Wu Yi \<wuyi@hancom.com\> ported the HKSCS-1999 TQBig5hkscsCodec to
+ TQt-3.0.1 in March 2002.
+
+ With the advent of the new HKSCS-2001 standard, James Su
+ \<suzhe@turbolinux.com.cn\> \<suzhe@gnuchina.org\> generated the
+ Big5-HKSCS<->Unicode tables with a very space-efficient algorithm.
+ He generously donated his code to glibc in May 2002. Subsequently,
+ James has generously allowed Anthony Fok to adapt the code for
+ TQt-3.0.5.
+
+ Currently, the Big5-HKSCS tables are generated from the following
+ sources, and with the Euro character added:
+ \list 1
+ \i \l{http://www.microsoft.com/typography/tqunicode/950.txt}
+ \i \l{http://www.info.gov.hk/digital21/chi/hkscs/download/big5-iso.txt}
+ \i \l{http://www.info.gov.hk/digital21/chi/hkscs/download/big5cmp.txt}
+ \endlist
+
+ There may be more fine-tuning to the TQBig5hkscsCodec to maximize its
+ compatibility with the standard Big5 (2002) mapping as determined by
+ Li18nux Big5 Standard Subgroup. See \l{http://www.autrijus.org/xml/}
+ for the various Big5 CharMapML tables.
+
+ \legalese
+
+ Copyright (C) 2000 Ming-Che Chuang
+ Copyright (C) 2001, 2002 James Su, Turbolinux Inc.
+ Copyright (C) 2002 WU Yi, HancomLinux Inc.
+ Copyright (C) 2001, 2002 Anthony Fok, ThizLinux Laboratory Ltd.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ \list 1
+ \i Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ \i Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ \endlist
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+
+/*! \reimp */
+int TQBig5hkscsCodec::mibEnum() const
+{
+ /* See http://www.iana.org/assignments/character-sets */
+ /* http://www.iana.org/assignments/charset-reg/Big5-HKSCS */
+ //qDebug("TQBig5hkscsCodec::mibEnum() = 2101");
+ return 2101;
+}
+
+
+/*! \reimp */
+const char* TQBig5hkscsCodec::name() const
+{
+ //qDebug("TQBig5hkscsCodec::name() = \"Big5-HKSCS\"");
+ return "Big5-HKSCS";
+}
+
+
+class TQBig5hkscsDecoder : public TQTextDecoder {
+ uchar buf[2];
+ int nbuf;
+public:
+ TQBig5hkscsDecoder() : nbuf(0)
+ {
+ }
+
+ TQString toUnicode(const char* chars, int len)
+ {
+ //qDebug("TQBig5hkscsDecoder::toUnicode(const char* chars = \"%s\", int len = %d)", chars, len);
+ TQString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ switch (nbuf) {
+ case 0:
+ if ( IsLatin(ch) ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( IsFirstByte(ch) ) {
+ // Big5-HKSCS
+ buf[0] = ch;
+ nbuf = 1;
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ break;
+ case 1:
+ if ( IsSecondByte(ch) ) {
+ // Big5-HKSCS
+ uint u;
+ buf[1] = ch;
+ if ( qt_Big5hkscsToUnicode( buf, &u ) == 2 )
+ result += TQValidChar(u);
+ else {
+ // Error
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ // Error
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ break;
+ }
+ }
+ return result;
+ }
+};
+
+
+/*! \reimp */
+TQTextDecoder* TQBig5hkscsCodec::makeDecoder() const
+{
+ //qDebug("TQBig5hkscsCodec::makeDecoder()");
+ return new TQBig5hkscsDecoder();
+}
+
+
+/*! \reimp */
+TQCString TQBig5hkscsCodec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ //qDebug("TQBig5hkscsCodec::fromUnicode(const TQString& uc, int& lenInOut = %d)", lenInOut);
+ int l = TQMIN((int)uc.length(),lenInOut);
+ int rlen = l*3+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+ for (int i=0; i<l; i++) {
+ TQChar ch = uc[i];
+ uchar c[2];
+ if ( ch.row() == 0x00 && ch.cell() < 0x80 ) {
+ // ASCII
+ *cursor++ = ch.cell();
+ } else if ( qt_UnicodeToBig5hkscs( ch.tqunicode(), c ) == 2 ) {
+ // Big5-HKSCS
+ *cursor++ = c[0];
+ *cursor++ = c[1];
+ } else {
+ // Error
+ *cursor++ = '?'; // unknown char
+ }
+ }
+ lenInOut = cursor - (uchar*)rstr.data();
+ rstr.truncate(lenInOut);
+ return rstr;
+}
+
+
+/*! \reimp */
+TQString TQBig5hkscsCodec::toUnicode(const char* chars, int len) const
+{
+ //qDebug("TQBig5hkscsCodec::toUnicode(const char* chars = \"%s\", int len = %d)", chars, len);
+ TQString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ if ( IsLatin(ch) ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( IsFirstByte(ch) ) {
+ // Big5-HKSCS
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( IsSecondByte(c2) ) {
+ uint u;
+ if ( qt_Big5hkscsToUnicode( (const uchar*)(chars + i - 1), &u ) == 2 )
+ result += TQValidChar(u);
+ else {
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ i--;
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ // Bad String
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ }
+ return result;
+}
+
+
+/*! \reimp */
+int TQBig5hkscsCodec::heuristicNameMatch(const char* hint) const
+{
+ //qDebug("TQBig5hkscsCodec::heuristicNameMatch(const char* hint = \"%s\")", hint);
+ int score = 0;
+ bool zh = FALSE;
+ if (qstrnicmp(hint, "zh_HK", 5) == 0) {
+ score += 16;
+ zh = TRUE;
+ }
+ else if ( qstrnicmp(hint, "zh", 2) == 0 ||
+ qstrnicmp(hint, "chinese", 7) == 0) {
+ score += 2;
+ zh = TRUE;
+ }
+ const char *p;
+ if (zh) {
+ p = strchr(hint, '.');
+ if (p == 0)
+ return score;
+ p++;
+ } else {
+ p = hint;
+ }
+ if (p) {
+ if ( qstricmp(p, "Big5-HKSCS") == 0 ||
+ qstricmp(p, "HKSCS-Big5") == 0 ||
+ qstricmp(p, "Big5HKSCS") == 0 ||
+ qstricmp(p, "hkbig5") == 0 ) {
+ return score + 10;
+ }
+ else if (qstrnicmp(p, "Big5", 4) == 0) {
+ return score + 2;
+ }
+ }
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+
+/*! \reimp */
+int TQBig5hkscsCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ //qDebug("TQBig5hkscsCodec::heuristicContentMatch(const char* chars, int len = %d)", len);
+ int score = 0;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ // No nulls allowed.
+ if ( !ch )
+ return -1;
+ if ( ch < 32 && ch != '\t' && ch != '\n' && ch != '\r' ) {
+ // Suspicious
+ if ( score )
+ score--;
+ } else if ( ch < 0x80 ) {
+ // Inconclusive
+ score++;
+ } else if ( IsFirstByte(ch) ) {
+ // Big5-HKSCS
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( !IsSecondByte(c2) )
+ return -1;
+ score += 2;
+ }
+ score++;
+ } else {
+ // Invalid
+ return -1;
+ }
+ }
+ //qDebug("TQBig5hkscsCodec::heuristicContentMatch() score = %d", score);
+ return score;
+}
+
+
+/* ====================================================================== */
+
+/*
+ * big5hkscs to ucs4 convert routing
+ */
+
+static ushort const big5hkscs_to_ucs[] = {
+ /* Big5-HKSCS 0x8140 .. 0x817E */
+ 0xEEB8, 0xEEB9, 0xEEBA, 0xEEBB, 0xEEBC, 0xEEBD, 0xEEBE, 0xEEBF,
+ 0xEEC0, 0xEEC1, 0xEEC2, 0xEEC3, 0xEEC4, 0xEEC5, 0xEEC6, 0xEEC7,
+ 0xEEC8, 0xEEC9, 0xEECA, 0xEECB, 0xEECC, 0xEECD, 0xEECE, 0xEECF,
+ 0xEED0, 0xEED1, 0xEED2, 0xEED3, 0xEED4, 0xEED5, 0xEED6, 0xEED7,
+ 0xEED8, 0xEED9, 0xEEDA, 0xEEDB, 0xEEDC, 0xEEDD, 0xEEDE, 0xEEDF,
+ 0xEEE0, 0xEEE1, 0xEEE2, 0xEEE3, 0xEEE4, 0xEEE5, 0xEEE6, 0xEEE7,
+ 0xEEE8, 0xEEE9, 0xEEEA, 0xEEEB, 0xEEEC, 0xEEED, 0xEEEE, 0xEEEF,
+ 0xEEF0, 0xEEF1, 0xEEF2, 0xEEF3, 0xEEF4, 0xEEF5, 0xEEF6,
+ /* Big5-HKSCS 0x81A1 .. 0x81FE */
+ 0xEEF7, 0xEEF8, 0xEEF9, 0xEEFA, 0xEEFB, 0xEEFC, 0xEEFD,
+ 0xEEFE, 0xEEFF, 0xEF00, 0xEF01, 0xEF02, 0xEF03, 0xEF04, 0xEF05,
+ 0xEF06, 0xEF07, 0xEF08, 0xEF09, 0xEF0A, 0xEF0B, 0xEF0C, 0xEF0D,
+ 0xEF0E, 0xEF0F, 0xEF10, 0xEF11, 0xEF12, 0xEF13, 0xEF14, 0xEF15,
+ 0xEF16, 0xEF17, 0xEF18, 0xEF19, 0xEF1A, 0xEF1B, 0xEF1C, 0xEF1D,
+ 0xEF1E, 0xEF1F, 0xEF20, 0xEF21, 0xEF22, 0xEF23, 0xEF24, 0xEF25,
+ 0xEF26, 0xEF27, 0xEF28, 0xEF29, 0xEF2A, 0xEF2B, 0xEF2C, 0xEF2D,
+ 0xEF2E, 0xEF2F, 0xEF30, 0xEF31, 0xEF32, 0xEF33, 0xEF34, 0xEF35,
+ 0xEF36, 0xEF37, 0xEF38, 0xEF39, 0xEF3A, 0xEF3B, 0xEF3C, 0xEF3D,
+ 0xEF3E, 0xEF3F, 0xEF40, 0xEF41, 0xEF42, 0xEF43, 0xEF44, 0xEF45,
+ 0xEF46, 0xEF47, 0xEF48, 0xEF49, 0xEF4A, 0xEF4B, 0xEF4C, 0xEF4D,
+ 0xEF4E, 0xEF4F, 0xEF50, 0xEF51, 0xEF52, 0xEF53, 0xEF54,
+ /* Big5-HKSCS 0x8240 .. 0x827E */
+ 0xEF55, 0xEF56, 0xEF57, 0xEF58, 0xEF59, 0xEF5A, 0xEF5B, 0xEF5C,
+ 0xEF5D, 0xEF5E, 0xEF5F, 0xEF60, 0xEF61, 0xEF62, 0xEF63, 0xEF64,
+ 0xEF65, 0xEF66, 0xEF67, 0xEF68, 0xEF69, 0xEF6A, 0xEF6B, 0xEF6C,
+ 0xEF6D, 0xEF6E, 0xEF6F, 0xEF70, 0xEF71, 0xEF72, 0xEF73, 0xEF74,
+ 0xEF75, 0xEF76, 0xEF77, 0xEF78, 0xEF79, 0xEF7A, 0xEF7B, 0xEF7C,
+ 0xEF7D, 0xEF7E, 0xEF7F, 0xEF80, 0xEF81, 0xEF82, 0xEF83, 0xEF84,
+ 0xEF85, 0xEF86, 0xEF87, 0xEF88, 0xEF89, 0xEF8A, 0xEF8B, 0xEF8C,
+ 0xEF8D, 0xEF8E, 0xEF8F, 0xEF90, 0xEF91, 0xEF92, 0xEF93,
+ /* Big5-HKSCS 0x82A1 .. 0x82FE */
+ 0xEF94, 0xEF95, 0xEF96, 0xEF97, 0xEF98, 0xEF99, 0xEF9A,
+ 0xEF9B, 0xEF9C, 0xEF9D, 0xEF9E, 0xEF9F, 0xEFA0, 0xEFA1, 0xEFA2,
+ 0xEFA3, 0xEFA4, 0xEFA5, 0xEFA6, 0xEFA7, 0xEFA8, 0xEFA9, 0xEFAA,
+ 0xEFAB, 0xEFAC, 0xEFAD, 0xEFAE, 0xEFAF, 0xEFB0, 0xEFB1, 0xEFB2,
+ 0xEFB3, 0xEFB4, 0xEFB5, 0xEFB6, 0xEFB7, 0xEFB8, 0xEFB9, 0xEFBA,
+ 0xEFBB, 0xEFBC, 0xEFBD, 0xEFBE, 0xEFBF, 0xEFC0, 0xEFC1, 0xEFC2,
+ 0xEFC3, 0xEFC4, 0xEFC5, 0xEFC6, 0xEFC7, 0xEFC8, 0xEFC9, 0xEFCA,
+ 0xEFCB, 0xEFCC, 0xEFCD, 0xEFCE, 0xEFCF, 0xEFD0, 0xEFD1, 0xEFD2,
+ 0xEFD3, 0xEFD4, 0xEFD5, 0xEFD6, 0xEFD7, 0xEFD8, 0xEFD9, 0xEFDA,
+ 0xEFDB, 0xEFDC, 0xEFDD, 0xEFDE, 0xEFDF, 0xEFE0, 0xEFE1, 0xEFE2,
+ 0xEFE3, 0xEFE4, 0xEFE5, 0xEFE6, 0xEFE7, 0xEFE8, 0xEFE9, 0xEFEA,
+ 0xEFEB, 0xEFEC, 0xEFED, 0xEFEE, 0xEFEF, 0xEFF0, 0xEFF1,
+ /* Big5-HKSCS 0x8340 .. 0x837E */
+ 0xEFF2, 0xEFF3, 0xEFF4, 0xEFF5, 0xEFF6, 0xEFF7, 0xEFF8, 0xEFF9,
+ 0xEFFA, 0xEFFB, 0xEFFC, 0xEFFD, 0xEFFE, 0xEFFF, 0xF000, 0xF001,
+ 0xF002, 0xF003, 0xF004, 0xF005, 0xF006, 0xF007, 0xF008, 0xF009,
+ 0xF00A, 0xF00B, 0xF00C, 0xF00D, 0xF00E, 0xF00F, 0xF010, 0xF011,
+ 0xF012, 0xF013, 0xF014, 0xF015, 0xF016, 0xF017, 0xF018, 0xF019,
+ 0xF01A, 0xF01B, 0xF01C, 0xF01D, 0xF01E, 0xF01F, 0xF020, 0xF021,
+ 0xF022, 0xF023, 0xF024, 0xF025, 0xF026, 0xF027, 0xF028, 0xF029,
+ 0xF02A, 0xF02B, 0xF02C, 0xF02D, 0xF02E, 0xF02F, 0xF030,
+ /* Big5-HKSCS 0x83A1 .. 0x83FE */
+ 0xF031, 0xF032, 0xF033, 0xF034, 0xF035, 0xF036, 0xF037,
+ 0xF038, 0xF039, 0xF03A, 0xF03B, 0xF03C, 0xF03D, 0xF03E, 0xF03F,
+ 0xF040, 0xF041, 0xF042, 0xF043, 0xF044, 0xF045, 0xF046, 0xF047,
+ 0xF048, 0xF049, 0xF04A, 0xF04B, 0xF04C, 0xF04D, 0xF04E, 0xF04F,
+ 0xF050, 0xF051, 0xF052, 0xF053, 0xF054, 0xF055, 0xF056, 0xF057,
+ 0xF058, 0xF059, 0xF05A, 0xF05B, 0xF05C, 0xF05D, 0xF05E, 0xF05F,
+ 0xF060, 0xF061, 0xF062, 0xF063, 0xF064, 0xF065, 0xF066, 0xF067,
+ 0xF068, 0xF069, 0xF06A, 0xF06B, 0xF06C, 0xF06D, 0xF06E, 0xF06F,
+ 0xF070, 0xF071, 0xF072, 0xF073, 0xF074, 0xF075, 0xF076, 0xF077,
+ 0xF078, 0xF079, 0xF07A, 0xF07B, 0xF07C, 0xF07D, 0xF07E, 0xF07F,
+ 0xF080, 0xF081, 0xF082, 0xF083, 0xF084, 0xF085, 0xF086, 0xF087,
+ 0xF088, 0xF089, 0xF08A, 0xF08B, 0xF08C, 0xF08D, 0xF08E,
+ /* Big5-HKSCS 0x8440 .. 0x847E */
+ 0xF08F, 0xF090, 0xF091, 0xF092, 0xF093, 0xF094, 0xF095, 0xF096,
+ 0xF097, 0xF098, 0xF099, 0xF09A, 0xF09B, 0xF09C, 0xF09D, 0xF09E,
+ 0xF09F, 0xF0A0, 0xF0A1, 0xF0A2, 0xF0A3, 0xF0A4, 0xF0A5, 0xF0A6,
+ 0xF0A7, 0xF0A8, 0xF0A9, 0xF0AA, 0xF0AB, 0xF0AC, 0xF0AD, 0xF0AE,
+ 0xF0AF, 0xF0B0, 0xF0B1, 0xF0B2, 0xF0B3, 0xF0B4, 0xF0B5, 0xF0B6,
+ 0xF0B7, 0xF0B8, 0xF0B9, 0xF0BA, 0xF0BB, 0xF0BC, 0xF0BD, 0xF0BE,
+ 0xF0BF, 0xF0C0, 0xF0C1, 0xF0C2, 0xF0C3, 0xF0C4, 0xF0C5, 0xF0C6,
+ 0xF0C7, 0xF0C8, 0xF0C9, 0xF0CA, 0xF0CB, 0xF0CC, 0xF0CD,
+ /* Big5-HKSCS 0x84A1 .. 0x84FE */
+ 0xF0CE, 0xF0CF, 0xF0D0, 0xF0D1, 0xF0D2, 0xF0D3, 0xF0D4,
+ 0xF0D5, 0xF0D6, 0xF0D7, 0xF0D8, 0xF0D9, 0xF0DA, 0xF0DB, 0xF0DC,
+ 0xF0DD, 0xF0DE, 0xF0DF, 0xF0E0, 0xF0E1, 0xF0E2, 0xF0E3, 0xF0E4,
+ 0xF0E5, 0xF0E6, 0xF0E7, 0xF0E8, 0xF0E9, 0xF0EA, 0xF0EB, 0xF0EC,
+ 0xF0ED, 0xF0EE, 0xF0EF, 0xF0F0, 0xF0F1, 0xF0F2, 0xF0F3, 0xF0F4,
+ 0xF0F5, 0xF0F6, 0xF0F7, 0xF0F8, 0xF0F9, 0xF0FA, 0xF0FB, 0xF0FC,
+ 0xF0FD, 0xF0FE, 0xF0FF, 0xF100, 0xF101, 0xF102, 0xF103, 0xF104,
+ 0xF105, 0xF106, 0xF107, 0xF108, 0xF109, 0xF10A, 0xF10B, 0xF10C,
+ 0xF10D, 0xF10E, 0xF10F, 0xF110, 0xF111, 0xF112, 0xF113, 0xF114,
+ 0xF115, 0xF116, 0xF117, 0xF118, 0xF119, 0xF11A, 0xF11B, 0xF11C,
+ 0xF11D, 0xF11E, 0xF11F, 0xF120, 0xF121, 0xF122, 0xF123, 0xF124,
+ 0xF125, 0xF126, 0xF127, 0xF128, 0xF129, 0xF12A, 0xF12B,
+ /* Big5-HKSCS 0x8540 .. 0x857E */
+ 0xF12C, 0xF12D, 0xF12E, 0xF12F, 0xF130, 0xF131, 0xF132, 0xF133,
+ 0xF134, 0xF135, 0xF136, 0xF137, 0xF138, 0xF139, 0xF13A, 0xF13B,
+ 0xF13C, 0xF13D, 0xF13E, 0xF13F, 0xF140, 0xF141, 0xF142, 0xF143,
+ 0xF144, 0xF145, 0xF146, 0xF147, 0xF148, 0xF149, 0xF14A, 0xF14B,
+ 0xF14C, 0xF14D, 0xF14E, 0xF14F, 0xF150, 0xF151, 0xF152, 0xF153,
+ 0xF154, 0xF155, 0xF156, 0xF157, 0xF158, 0xF159, 0xF15A, 0xF15B,
+ 0xF15C, 0xF15D, 0xF15E, 0xF15F, 0xF160, 0xF161, 0xF162, 0xF163,
+ 0xF164, 0xF165, 0xF166, 0xF167, 0xF168, 0xF169, 0xF16A,
+ /* Big5-HKSCS 0x85A1 .. 0x85FE */
+ 0xF16B, 0xF16C, 0xF16D, 0xF16E, 0xF16F, 0xF170, 0xF171,
+ 0xF172, 0xF173, 0xF174, 0xF175, 0xF176, 0xF177, 0xF178, 0xF179,
+ 0xF17A, 0xF17B, 0xF17C, 0xF17D, 0xF17E, 0xF17F, 0xF180, 0xF181,
+ 0xF182, 0xF183, 0xF184, 0xF185, 0xF186, 0xF187, 0xF188, 0xF189,
+ 0xF18A, 0xF18B, 0xF18C, 0xF18D, 0xF18E, 0xF18F, 0xF190, 0xF191,
+ 0xF192, 0xF193, 0xF194, 0xF195, 0xF196, 0xF197, 0xF198, 0xF199,
+ 0xF19A, 0xF19B, 0xF19C, 0xF19D, 0xF19E, 0xF19F, 0xF1A0, 0xF1A1,
+ 0xF1A2, 0xF1A3, 0xF1A4, 0xF1A5, 0xF1A6, 0xF1A7, 0xF1A8, 0xF1A9,
+ 0xF1AA, 0xF1AB, 0xF1AC, 0xF1AD, 0xF1AE, 0xF1AF, 0xF1B0, 0xF1B1,
+ 0xF1B2, 0xF1B3, 0xF1B4, 0xF1B5, 0xF1B6, 0xF1B7, 0xF1B8, 0xF1B9,
+ 0xF1BA, 0xF1BB, 0xF1BC, 0xF1BD, 0xF1BE, 0xF1BF, 0xF1C0, 0xF1C1,
+ 0xF1C2, 0xF1C3, 0xF1C4, 0xF1C5, 0xF1C6, 0xF1C7, 0xF1C8,
+ /* Big5-HKSCS 0x8640 .. 0x867E */
+ 0xF1C9, 0xF1CA, 0xF1CB, 0xF1CC, 0xF1CD, 0xF1CE, 0xF1CF, 0xF1D0,
+ 0xF1D1, 0xF1D2, 0xF1D3, 0xF1D4, 0xF1D5, 0xF1D6, 0xF1D7, 0xF1D8,
+ 0xF1D9, 0xF1DA, 0xF1DB, 0xF1DC, 0xF1DD, 0xF1DE, 0xF1DF, 0xF1E0,
+ 0xF1E1, 0xF1E2, 0xF1E3, 0xF1E4, 0xF1E5, 0xF1E6, 0xF1E7, 0xF1E8,
+ 0xF1E9, 0xF1EA, 0xF1EB, 0xF1EC, 0xF1ED, 0xF1EE, 0xF1EF, 0xF1F0,
+ 0xF1F1, 0xF1F2, 0xF1F3, 0xF1F4, 0xF1F5, 0xF1F6, 0xF1F7, 0xF1F8,
+ 0xF1F9, 0xF1FA, 0xF1FB, 0xF1FC, 0xF1FD, 0xF1FE, 0xF1FF, 0xF200,
+ 0xF201, 0xF202, 0xF203, 0xF204, 0xF205, 0xF206, 0xF207,
+ /* Big5-HKSCS 0x86A1 .. 0x86FE */
+ 0xF208, 0xF209, 0xF20A, 0xF20B, 0xF20C, 0xF20D, 0xF20E,
+ 0xF20F, 0xF210, 0xF211, 0xF212, 0xF213, 0xF214, 0xF215, 0xF216,
+ 0xF217, 0xF218, 0xF219, 0xF21A, 0xF21B, 0xF21C, 0xF21D, 0xF21E,
+ 0xF21F, 0xF220, 0xF221, 0xF222, 0xF223, 0xF224, 0xF225, 0xF226,
+ 0xF227, 0xF228, 0xF229, 0xF22A, 0xF22B, 0xF22C, 0xF22D, 0xF22E,
+ 0xF22F, 0xF230, 0xF231, 0xF232, 0xF233, 0xF234, 0xF235, 0xF236,
+ 0xF237, 0xF238, 0xF239, 0xF23A, 0xF23B, 0xF23C, 0xF23D, 0xF23E,
+ 0xF23F, 0xF240, 0xF241, 0xF242, 0xF243, 0xF244, 0xF245, 0xF246,
+ 0xF247, 0xF248, 0xF249, 0xF24A, 0xF24B, 0xF24C, 0xF24D, 0xF24E,
+ 0xF24F, 0xF250, 0xF251, 0xF252, 0xF253, 0xF254, 0xF255, 0xF256,
+ 0xF257, 0xF258, 0xF259, 0xF25A, 0xF25B, 0xF25C, 0xF25D, 0xF25E,
+ 0xF25F, 0xF260, 0xF261, 0xF262, 0xF263, 0xF264, 0xF265,
+ /* Big5-HKSCS 0x8740 .. 0x877E */
+ 0xF266, 0xF267, 0xF268, 0xF269, 0xF26A, 0xF26B, 0xF26C, 0xF26D,
+ 0xF26E, 0xF26F, 0xF270, 0xF271, 0xF272, 0xF273, 0xF274, 0xF275,
+ 0xF276, 0xF277, 0xF278, 0xF279, 0xF27A, 0xF27B, 0xF27C, 0xF27D,
+ 0xF27E, 0xF27F, 0xF280, 0xF281, 0xF282, 0xF283, 0xF284, 0xF285,
+ 0xF286, 0xF287, 0xF288, 0xF289, 0xF28A, 0xF28B, 0xF28C, 0xF28D,
+ 0xF28E, 0xF28F, 0xF290, 0xF291, 0xF292, 0xF293, 0xF294, 0xF295,
+ 0xF296, 0xF297, 0xF298, 0xF299, 0xF29A, 0xF29B, 0xF29C, 0xF29D,
+ 0xF29E, 0xF29F, 0xF2A0, 0xF2A1, 0xF2A2, 0xF2A3, 0xF2A4,
+ /* Big5-HKSCS 0x87A1 .. 0x87FE */
+ 0xF2A5, 0xF2A6, 0xF2A7, 0xF2A8, 0xF2A9, 0xF2AA, 0xF2AB,
+ 0xF2AC, 0xF2AD, 0xF2AE, 0xF2AF, 0xF2B0, 0xF2B1, 0xF2B2, 0xF2B3,
+ 0xF2B4, 0xF2B5, 0xF2B6, 0xF2B7, 0xF2B8, 0xF2B9, 0xF2BA, 0xF2BB,
+ 0xF2BC, 0xF2BD, 0xF2BE, 0xF2BF, 0xF2C0, 0xF2C1, 0xF2C2, 0xF2C3,
+ 0xF2C4, 0xF2C5, 0xF2C6, 0xF2C7, 0xF2C8, 0xF2C9, 0xF2CA, 0xF2CB,
+ 0xF2CC, 0xF2CD, 0xF2CE, 0xF2CF, 0xF2D0, 0xF2D1, 0xF2D2, 0xF2D3,
+ 0xF2D4, 0xF2D5, 0xF2D6, 0xF2D7, 0xF2D8, 0xF2D9, 0xF2DA, 0xF2DB,
+ 0xF2DC, 0xF2DD, 0xF2DE, 0xF2DF, 0xF2E0, 0xF2E1, 0xF2E2, 0xF2E3,
+ 0xF2E4, 0xF2E5, 0xF2E6, 0xF2E7, 0xF2E8, 0xF2E9, 0xF2EA, 0xF2EB,
+ 0xF2EC, 0xF2ED, 0xF2EE, 0xF2EF, 0xF2F0, 0xF2F1, 0xF2F2, 0xF2F3,
+ 0xF2F4, 0xF2F5, 0xF2F6, 0xF2F7, 0xF2F8, 0xF2F9, 0xF2FA, 0xF2FB,
+ 0xF2FC, 0xF2FD, 0xF2FE, 0xF2FF, 0xF300, 0xF301, 0xF302,
+ /* Big5-HKSCS 0x8840 .. 0x887E */
+ 0xF303, 0xF304, 0xF305, 0xF306, 0xF307, 0xF308, 0xF309, 0xF30A,
+ 0xF30B, 0xF30C, 0xF30D, 0xF30E, 0xF30F, 0xF310, 0xF311, 0xF312,
+ 0xF313, 0xF314, 0xF315, 0xF316, 0xF317, 0xF318, 0x0100, 0x00C1,
+ 0x01CD, 0x00C0, 0x0112, 0x00C9, 0x011A, 0x00C8, 0x014C, 0x00D3,
+ 0x01D1, 0x00D2, 0xF325, 0x1EBE, 0xF327, 0x1EC0, 0x00CA, 0x0101,
+ 0x00E1, 0x01CE, 0x00E0, 0x0251, 0x0113, 0x00E9, 0x011B, 0x00E8,
+ 0x012B, 0x00ED, 0x01D0, 0x00EC, 0x014D, 0x00F3, 0x01D2, 0x00F2,
+ 0x016B, 0x00FA, 0x01D4, 0x00F9, 0x01D6, 0x01D8, 0x01DA,
+ /* Big5-HKSCS 0x88A1 .. 0x88FE */
+ 0x01DC, 0x00FC, 0xF344, 0x1EBF, 0xF346, 0x1EC1, 0x00EA,
+ 0x0261, 0xF34A, 0xF34B, 0xF34C, 0xF34D, 0xF34E, 0xF34F, 0xF350,
+ 0xF351, 0xF352, 0xF353, 0xF354, 0xF355, 0xF356, 0xF357, 0xF358,
+ 0xF359, 0xF35A, 0xF35B, 0xF35C, 0xF35D, 0xF35E, 0xF35F, 0xF360,
+ 0xF361, 0xF362, 0xF363, 0xF364, 0xF365, 0xF366, 0xF367, 0xF368,
+ 0xF369, 0xF36A, 0xF36B, 0xF36C, 0xF36D, 0xF36E, 0xF36F, 0xF370,
+ 0xF371, 0xF372, 0xF373, 0xF374, 0xF375, 0xF376, 0xF377, 0xF378,
+ 0xF379, 0xF37A, 0xF37B, 0xF37C, 0xF37D, 0xF37E, 0xF37F, 0xF380,
+ 0xF381, 0xF382, 0xF383, 0xF384, 0xF385, 0xF386, 0xF387, 0xF388,
+ 0xF389, 0xF38A, 0xF38B, 0xF38C, 0xF38D, 0xF38E, 0xF38F, 0xF390,
+ 0xF391, 0xF392, 0xF393, 0xF394, 0xF395, 0xF396, 0xF397, 0xF398,
+ 0xF399, 0xF39A, 0xF39B, 0xF39C, 0xF39D, 0xF39E, 0xF39F,
+ /* Big5-HKSCS 0x8940 .. 0x897E */
+ 0xF3A0, 0xF3A1, 0xF3A2, 0x650A, 0xF3A4, 0xF3A5, 0x4E3D, 0x6EDD,
+ 0x9D4E, 0x91DF, 0xF3AA, 0xF3AB, 0xF3AC, 0x6491, 0x4F1A, 0x4F28,
+ 0x4FA8, 0x5156, 0x5174, 0x519C, 0x51E4, 0x52A1, 0x52A8, 0x533B,
+ 0x534E, 0x53D1, 0x53D8, 0x56E2, 0x58F0, 0x5904, 0x5907, 0x5932,
+ 0x5934, 0x5B66, 0x5B9E, 0x5B9F, 0x5C9A, 0x5E86, 0x603B, 0x6589,
+ 0x67FE, 0x6804, 0x6865, 0x6D4E, 0x70BC, 0x7535, 0x7EA4, 0x7EAC,
+ 0x7EBA, 0x7EC7, 0x7ECF, 0x7EDF, 0x7F06, 0x7F37, 0x827A, 0x82CF,
+ 0x836F, 0x89C6, 0x8BBE, 0x8BE2, 0x8F66, 0x8F67, 0x8F6E,
+ /* Big5-HKSCS 0x89A1 .. 0x89FE */
+ 0x7411, 0x7CFC, 0x7DCD, 0x6946, 0x7AC9, 0x5227, 0xF3E5,
+ 0xF3E6, 0xF3E7, 0xF3E8, 0x918C, 0x78B8, 0x915E, 0x80BC, 0xF3ED,
+ 0x8D0B, 0x80F6, 0xF3F0, 0xF3F1, 0xF3F2, 0x809F, 0x9EC7, 0x4CCD,
+ 0x9DC9, 0x9E0C, 0x4C3E, 0xF3F9, 0xF3FA, 0x9E0A, 0xF3FC, 0x35C1,
+ 0xF3FE, 0x6E9A, 0x823E, 0x7519, 0xF402, 0x4911, 0x9A6C, 0x9A8F,
+ 0x9F99, 0x7987, 0xF408, 0xF409, 0xF40A, 0xF40B, 0x4E24, 0x4E81,
+ 0x4E80, 0x4E87, 0x4EBF, 0x4EEB, 0x4F37, 0x344C, 0x4FBD, 0x3E48,
+ 0x5003, 0x5088, 0x347D, 0x3493, 0x34A5, 0x5186, 0x5905, 0x51DB,
+ 0x51FC, 0x5205, 0x4E89, 0x5279, 0x5290, 0x5327, 0x35C7, 0x53A9,
+ 0x3551, 0x53B0, 0x3553, 0x53C2, 0x5423, 0x356D, 0x3572, 0x3681,
+ 0x5493, 0x54A3, 0x54B4, 0x54B9, 0x54D0, 0x54EF, 0x5518, 0x5523,
+ 0x5528, 0x3598, 0x553F, 0x35A5, 0x35BF, 0x55D7, 0x35C5,
+ /* Big5-HKSCS 0x8A40 .. 0x8A7E */
+ 0xF43D, 0x5525, 0xF43F, 0xF440, 0xF441, 0xF442, 0x5590, 0xF444,
+ 0x39EC, 0xF446, 0x8E46, 0xF448, 0xF449, 0x4053, 0xF44B, 0x777A,
+ 0xF44D, 0x3A34, 0x47D5, 0xF450, 0xF451, 0xF452, 0x64DD, 0xF454,
+ 0xF455, 0xF456, 0xF457, 0x648D, 0x8E7E, 0xF45A, 0xF45B, 0xF45C,
+ 0xF45D, 0xF45E, 0xF45F, 0xF460, 0xF461, 0xF462, 0xF463, 0x47F4,
+ 0xF465, 0xF466, 0x9AB2, 0x3A67, 0xF469, 0x3FED, 0x3506, 0xF46C,
+ 0xF46D, 0xF46E, 0xF46F, 0x9D6E, 0x9815, 0xF472, 0x43D9, 0xF474,
+ 0x64B4, 0x54E3, 0xF477, 0xF478, 0xF479, 0x39FB, 0xF47B,
+ /* Big5-HKSCS 0x8AA1 .. 0x8AFE */
+ 0xF47C, 0xF47D, 0xF47E, 0x64EA, 0xF480, 0xF481, 0x8E68,
+ 0xF483, 0xF484, 0xF485, 0xF486, 0x480B, 0xF488, 0x3FFA, 0x5873,
+ 0xF48B, 0xF48C, 0xF48D, 0xF48E, 0xF48F, 0xF490, 0xF491, 0x5579,
+ 0x40BB, 0x43BA, 0xF495, 0x4AB4, 0xF497, 0xF498, 0x81AA, 0x98F5,
+ 0xF49B, 0x6379, 0x39FE, 0xF49E, 0x8DC0, 0x56A1, 0x647C, 0x3E43,
+ 0xF4A3, 0xF4A4, 0xF4A5, 0xF4A6, 0xF4A7, 0xF4A8, 0xF4A9, 0xF4AA,
+ 0x3992, 0x3A06, 0xF4AD, 0x3578, 0xF4AF, 0xF4B0, 0x5652, 0xF4B2,
+ 0xF4B3, 0xF4B4, 0x34BC, 0x6C3D, 0xF4B7, 0xF4B8, 0xF4B9, 0xF4BA,
+ 0xF4BB, 0xF4BC, 0xF4BD, 0xF4BE, 0xF4BF, 0xF4C0, 0xF4C1, 0x7F93,
+ 0xF4C3, 0xF4C4, 0xF4C5, 0x35FB, 0xF4C7, 0xF4C8, 0xF4C9, 0xF4CA,
+ 0x3F93, 0xF4CC, 0xF4CD, 0xF4CE, 0xF4CF, 0xF4D0, 0xF4D1, 0xF4D2,
+ 0xF4D3, 0xF4D4, 0xF4D5, 0x3FF9, 0xF4D7, 0x6432, 0xF4D9,
+ /* Big5-HKSCS 0x8B40 .. 0x8B7E */
+ 0xF4DA, 0xF4DB, 0xF4DC, 0xF4DD, 0xF4DE, 0xF4DF, 0xF4E0, 0x3A18,
+ 0xF4E2, 0xF4E3, 0xF4E4, 0xF4E5, 0xF4E6, 0xF4E7, 0xF4E8, 0xF4E9,
+ 0x95AA, 0x54CC, 0x82C4, 0x55B9, 0xF4EE, 0xF4EF, 0x9C26, 0x9AB6,
+ 0xF4F2, 0xF4F3, 0x7140, 0x816D, 0x80EC, 0x5C1C, 0xF4F8, 0x8134,
+ 0x3797, 0x535F, 0xF4FC, 0x91B6, 0xF4FE, 0xF4FF, 0xF500, 0xF501,
+ 0x35DD, 0xF503, 0x3609, 0xF505, 0x56AF, 0xF507, 0xF508, 0xF509,
+ 0xF50A, 0xF50B, 0xF50C, 0xF50D, 0xF50E, 0xF50F, 0xF510, 0xF511,
+ 0x5A54, 0xF513, 0xF514, 0xF515, 0xF516, 0x579C, 0xF518,
+ /* Big5-HKSCS 0x8BA1 .. 0x8BFE */
+ 0xF519, 0xF51A, 0xF51B, 0xF51C, 0xF51D, 0x3703, 0xF51F,
+ 0xF520, 0xF521, 0xF522, 0xF523, 0xF524, 0xF525, 0xF526, 0x5899,
+ 0x5268, 0x361A, 0xF52A, 0x7BB2, 0x5B68, 0x4800, 0x4B2C, 0x9F27,
+ 0x49E7, 0x9C1F, 0x9B8D, 0xF533, 0xF534, 0x55FB, 0x35F2, 0x5689,
+ 0x4E28, 0x5902, 0xF53A, 0xF53B, 0x9751, 0xF53D, 0x4E5B, 0x4EBB,
+ 0x353E, 0x5C23, 0x5F51, 0x5FC4, 0x38FA, 0x624C, 0x6535, 0x6B7A,
+ 0x6C35, 0x6C3A, 0x706C, 0x722B, 0x4E2C, 0x72AD, 0xF54E, 0x7F52,
+ 0x793B, 0x7CF9, 0x7F53, 0xF553, 0x34C1, 0xF555, 0xF556, 0x8002,
+ 0x8080, 0xF559, 0xF55A, 0x535D, 0x8864, 0x89C1, 0xF55E, 0x8BA0,
+ 0x8D1D, 0x9485, 0x9578, 0x957F, 0x95E8, 0xF565, 0x97E6, 0x9875,
+ 0x98CE, 0x98DE, 0x9963, 0xF56B, 0x9C7C, 0x9E1F, 0x9EC4, 0x6B6F,
+ 0xF907, 0x4E37, 0xF572, 0x961D, 0x6237, 0x94A2, 0xF576,
+ /* Big5-HKSCS 0x8C40 .. 0x8C7E */
+ 0x503B, 0x6DFE, 0xF579, 0xF57A, 0x3DC9, 0x888F, 0xF57D, 0x7077,
+ 0x5CF5, 0x4B20, 0xF581, 0x3559, 0xF583, 0x6122, 0xF585, 0x8FA7,
+ 0x91F6, 0x7191, 0x6719, 0x73BA, 0xF58B, 0xF58C, 0x3C8B, 0xF58E,
+ 0x4B10, 0x78E4, 0x7402, 0x51AE, 0xF593, 0x4009, 0x6A63, 0xF596,
+ 0x4223, 0x860F, 0xF599, 0x7A2A, 0xF59B, 0xF59C, 0x9755, 0x704D,
+ 0x5324, 0xF5A0, 0x93F4, 0x76D9, 0xF5A3, 0xF5A4, 0x77DD, 0x4EA3,
+ 0x4FF0, 0x50BC, 0x4E2F, 0x4F17, 0xF5AB, 0x5434, 0x7D8B, 0x5892,
+ 0x58D0, 0xF5B0, 0x5E92, 0x5E99, 0x5FC2, 0xF5B4, 0x658B,
+ /* Big5-HKSCS 0x8CA1 .. 0x8CFE */
+ 0xF5B6, 0x6919, 0x6A43, 0xF5B9, 0x6CFF, 0xF5BB, 0x7200,
+ 0xF5BD, 0x738C, 0x3EDB, 0xF5C0, 0x5B15, 0x74B9, 0x8B83, 0xF5C4,
+ 0xF5C5, 0x7A93, 0x7BEC, 0x7CC3, 0x7E6C, 0x82F8, 0x8597, 0xF5CC,
+ 0x8890, 0xF5CE, 0x8EB9, 0xF5D0, 0x8FCF, 0x855F, 0x99E0, 0x9221,
+ 0xF5D5, 0xF5D6, 0xF5D7, 0x4071, 0x42A2, 0x5A1A, 0xF5DB, 0xF5DC,
+ 0xF5DD, 0x9868, 0x676B, 0x4276, 0x573D, 0xF5E2, 0x85D6, 0xF5E4,
+ 0x82BF, 0xF5E6, 0x4C81, 0xF5E8, 0x5D7B, 0xF5EA, 0xF5EB, 0xF5EC,
+ 0xF5ED, 0x5B96, 0xF5EF, 0xF5F0, 0x7E5B, 0xF5F2, 0xF5F3, 0xF5F4,
+ 0xF5F5, 0xF5F6, 0xF5F7, 0xF5F8, 0xF5F9, 0xF5FA, 0xF5FB, 0xF5FC,
+ 0xF5FD, 0xF5FE, 0xF5FF, 0xF600, 0xF601, 0xF602, 0xF603, 0xF604,
+ 0xF605, 0xF606, 0xF607, 0xF608, 0xF609, 0xF60A, 0xF60B, 0xF60C,
+ 0xF60D, 0xF60E, 0xF60F, 0xF610, 0xF611, 0xF612, 0xF613,
+ /* Big5-HKSCS 0x8D40 .. 0x8D7E */
+ 0xF614, 0xF615, 0xF616, 0xF617, 0xF618, 0xF619, 0xF61A, 0xF61B,
+ 0xF61C, 0xF61D, 0xF61E, 0xF61F, 0xF620, 0xF621, 0xF622, 0xF623,
+ 0xF624, 0xF625, 0xF626, 0xF627, 0xF628, 0xF629, 0xF62A, 0xF62B,
+ 0xF62C, 0xF62D, 0xF62E, 0xF62F, 0xF630, 0xF631, 0xF632, 0xF633,
+ 0x5D3E, 0x5D48, 0x5D56, 0x3DFC, 0x380F, 0x5DA4, 0x5DB9, 0x3820,
+ 0x3838, 0x5E42, 0x5EBD, 0x5F25, 0x5F83, 0x3908, 0x3914, 0x393F,
+ 0x394D, 0x60D7, 0x613D, 0x5CE5, 0x3989, 0x61B7, 0x61B9, 0x61CF,
+ 0x39B8, 0x622C, 0x6290, 0x62E5, 0x6318, 0x39F8, 0x56B1,
+ /* Big5-HKSCS 0x8DA1 .. 0x8DFE */
+ 0x3A03, 0x63E2, 0x63FB, 0x6407, 0x645A, 0x3A4B, 0x64C0,
+ 0x5D15, 0x5621, 0x9F9F, 0x3A97, 0x6586, 0x3ABD, 0x65FF, 0x6653,
+ 0x3AF2, 0x6692, 0x3B22, 0x6716, 0x3B42, 0x67A4, 0x6800, 0x3B58,
+ 0x684A, 0x6884, 0x3B72, 0x3B71, 0x3B7B, 0x6909, 0x6943, 0x725C,
+ 0x6964, 0x699F, 0x6985, 0x3BBC, 0x69D6, 0x3BDD, 0x6A65, 0x6A74,
+ 0x6A71, 0x6A82, 0x3BEC, 0x6A99, 0x3BF2, 0x6AAB, 0x6AB5, 0x6AD4,
+ 0x6AF6, 0x6B81, 0x6BC1, 0x6BEA, 0x6C75, 0x6CAA, 0x3CCB, 0x6D02,
+ 0x6D06, 0x6D26, 0x6D81, 0x3CEF, 0x6DA4, 0x6DB1, 0x6E15, 0x6E18,
+ 0x6E29, 0x6E86, 0xF694, 0x6EBB, 0x6EE2, 0x6EDA, 0x9F7F, 0x6EE8,
+ 0x6EE9, 0x6F24, 0x6F34, 0x3D46, 0xF69E, 0x6F81, 0x6FBE, 0x3D6A,
+ 0x3D75, 0x71B7, 0x5C99, 0x3D8A, 0x702C, 0x3D91, 0x7050, 0x7054,
+ 0x706F, 0x707F, 0x7089, 0xF6AD, 0x43C1, 0x35F1, 0xF6B0,
+ /* Big5-HKSCS 0x8E40 .. 0x8E7E */
+ 0xE311, 0x57BE, 0xE313, 0x713E, 0xE315, 0x364E, 0x69A2, 0xE318,
+ 0x5B74, 0x7A49, 0xE31B, 0xE31C, 0x7A65, 0x7A7D, 0xE31F, 0x7ABB,
+ 0x7AB0, 0x7AC2, 0x7AC3, 0x71D1, 0xE325, 0x41CA, 0x7ADA, 0x7ADD,
+ 0x7AEA, 0x41EF, 0x54B2, 0xE32C, 0x7B0B, 0x7B55, 0x7B29, 0xE330,
+ 0xE331, 0x7BA2, 0x7B6F, 0x839C, 0xE335, 0xE336, 0x7BD0, 0x8421,
+ 0x7B92, 0x7BB8, 0xE33B, 0x3DAD, 0xE33D, 0x8492, 0x7BFA, 0x7C06,
+ 0x7C35, 0xE342, 0x7C44, 0x7C83, 0xE345, 0x7CA6, 0x667D, 0xE348,
+ 0x7CC9, 0x7CC7, 0x7CE6, 0x7C74, 0x7CF3, 0x7CF5, 0x7CCE,
+ /* Big5-HKSCS 0x8EA1 .. 0x8EFE */
+ 0x7E67, 0x451D, 0xE352, 0x7D5D, 0xE354, 0x748D, 0x7D89,
+ 0x7DAB, 0x7135, 0x7DB3, 0x7DD2, 0xE35B, 0xE35C, 0x7DE4, 0x3D13,
+ 0x7DF5, 0xE360, 0x7DE5, 0xE362, 0x7E1D, 0xE364, 0xE365, 0x7E6E,
+ 0x7E92, 0x432B, 0x946C, 0x7E27, 0x7F40, 0x7F41, 0x7F47, 0x7936,
+ 0xE36F, 0x99E1, 0x7F97, 0xE372, 0x7FA3, 0xE374, 0xE375, 0x455C,
+ 0xE377, 0x4503, 0xE379, 0x7FFA, 0xE37B, 0x8005, 0x8008, 0x801D,
+ 0x8028, 0x802F, 0xE381, 0xE382, 0x803B, 0x803C, 0x8061, 0xE386,
+ 0x4989, 0xE388, 0xE389, 0xE38A, 0x6725, 0x80A7, 0xE38D, 0x8107,
+ 0x811A, 0x58B0, 0xE391, 0x6C7F, 0xE393, 0xE394, 0x64E7, 0xE396,
+ 0x8218, 0xE398, 0x6A53, 0xE39A, 0xE39B, 0x447A, 0x8229, 0xE39E,
+ 0xE39F, 0xE3A0, 0x4FF9, 0xE3A2, 0x84E2, 0x8362, 0xE3A5, 0xE3A6,
+ 0xE3A7, 0xE3A8, 0xE3A9, 0x82AA, 0x691B, 0xE3AC, 0x41DB,
+ /* Big5-HKSCS 0x8F40 .. 0x8F7E */
+ 0x854B, 0x82D0, 0x831A, 0xE3B1, 0xE3B2, 0x36C1, 0xE3B4, 0xE3B5,
+ 0x827B, 0x82E2, 0x8318, 0xE3B9, 0xE3BA, 0xE3BB, 0xE3BC, 0xE3BD,
+ 0x3DBF, 0x831D, 0x55EC, 0x8385, 0x450B, 0xE3C3, 0x83AC, 0x83C1,
+ 0x83D3, 0x347E, 0xE3C8, 0x6A57, 0x855A, 0x3496, 0xE3CC, 0xE3CD,
+ 0x8458, 0xE3CF, 0x8471, 0x3DD3, 0x44E4, 0x6AA7, 0x844A, 0xE3D5,
+ 0x7958, 0x84A8, 0xE3D8, 0xE3D9, 0xE3DA, 0x84DE, 0x840F, 0x8391,
+ 0x44A0, 0x8493, 0x84E4, 0xE3E1, 0x4240, 0xE3E3, 0x4543, 0x8534,
+ 0x5AF2, 0xE3E7, 0x4527, 0x8573, 0x4516, 0x67BF, 0x8616,
+ /* Big5-HKSCS 0x8FA1 .. 0x8FFE */
+ 0xE3ED, 0xE3EE, 0x85C1, 0xE3F0, 0x8602, 0xE3F2, 0xE3F3,
+ 0xE3F4, 0x456A, 0x8628, 0x3648, 0xE3F8, 0x53F7, 0xE3FA, 0x867E,
+ 0x8771, 0xE3FD, 0x87EE, 0xE3FF, 0x87B1, 0x87DA, 0x880F, 0x5661,
+ 0x866C, 0x6856, 0x460F, 0x8845, 0x8846, 0xE409, 0xE40A, 0xE40B,
+ 0x885E, 0x889C, 0x465B, 0x88B4, 0x88B5, 0x63C1, 0x88C5, 0x7777,
+ 0xE414, 0x8987, 0x898A, 0x89A6, 0x89A9, 0x89A7, 0x89BC, 0xE41B,
+ 0x89E7, 0xE41D, 0xE41E, 0x8A9C, 0x7793, 0x91FE, 0x8A90, 0xE423,
+ 0x7AE9, 0xE425, 0xE426, 0x4713, 0xE428, 0x717C, 0x8B0C, 0x8B1F,
+ 0xE42C, 0xE42D, 0x8B3F, 0x8B4C, 0x8B4D, 0x8AA9, 0xE432, 0x8B90,
+ 0x8B9B, 0x8AAF, 0xE436, 0x4615, 0x884F, 0x8C9B, 0xE43A, 0xE43B,
+ 0xE43C, 0x3725, 0xE43E, 0x8CD6, 0xE440, 0xE441, 0x8D12, 0x8D03,
+ 0xE444, 0x8CDB, 0x705C, 0x8D11, 0xE448, 0x3ED0, 0x8D77,
+ /* Big5-HKSCS 0x9040 .. 0x907E */
+ 0x8DA9, 0xE44C, 0xE44D, 0xE44E, 0x3B7C, 0xE450, 0xE451, 0x7AE7,
+ 0x8EAD, 0x8EB6, 0x8EC3, 0x92D4, 0x8F19, 0x8F2D, 0xE459, 0xE45A,
+ 0x8FA5, 0x9303, 0xE45D, 0xE45E, 0x8FB3, 0x492A, 0xE461, 0xE462,
+ 0xE463, 0x5EF8, 0xE465, 0x8FF9, 0xE467, 0xE468, 0xE469, 0xE46A,
+ 0x3980, 0xE46C, 0x9037, 0xE46E, 0xE46F, 0x9061, 0xE471, 0xE472,
+ 0x90A8, 0xE474, 0x90C4, 0xE476, 0x90AE, 0x90FD, 0x9167, 0x3AF0,
+ 0x91A9, 0x91C4, 0x7CAC, 0xE47E, 0xE47F, 0x920E, 0x6C9F, 0x9241,
+ 0x9262, 0xE484, 0x92B9, 0xE486, 0xE487, 0xE488, 0xE489,
+ /* Big5-HKSCS 0x90A1 .. 0x90FE */
+ 0xE48A, 0x932C, 0x936B, 0xE48D, 0xE48E, 0x708F, 0x5AC3,
+ 0xE491, 0xE492, 0x4965, 0x9244, 0xE495, 0xE496, 0xE497, 0x9373,
+ 0x945B, 0x8EBC, 0x9585, 0x95A6, 0x9426, 0x95A0, 0x6FF6, 0x42B9,
+ 0xE4A1, 0xE4A2, 0xE4A3, 0xE4A4, 0x49DF, 0x6C1C, 0x967B, 0x9696,
+ 0x416C, 0x96A3, 0xE4AB, 0x61DA, 0x96B6, 0x78F5, 0xE4AF, 0x96BD,
+ 0x53CC, 0x49A1, 0xE4B3, 0xE4B4, 0xE4B5, 0xE4B6, 0xE4B7, 0xE4B8,
+ 0xE4B9, 0xE4BA, 0x9731, 0x8642, 0x9736, 0x4A0F, 0x453D, 0x4585,
+ 0xE4C1, 0x7075, 0x5B41, 0x971B, 0x975C, 0xE4C6, 0x9757, 0x5B4A,
+ 0xE4C9, 0x975F, 0x9425, 0x50D0, 0xE4CD, 0xE4CE, 0x9789, 0x979F,
+ 0x97B1, 0x97BE, 0x97C0, 0x97D2, 0x97E0, 0xE4D6, 0x97EE, 0x741C,
+ 0xE4D9, 0x97FF, 0x97F5, 0xE4DC, 0xE4DD, 0x4AD1, 0x9834, 0x9833,
+ 0x984B, 0x9866, 0x3B0E, 0xE4E4, 0x3D51, 0xE4E6, 0xE4E7,
+ /* Big5-HKSCS 0x9140 .. 0x917E */
+ 0xE4E8, 0x98CA, 0x98B7, 0x98C8, 0x98C7, 0x4AFF, 0xE4EE, 0xE4EF,
+ 0x55B0, 0x98E1, 0x98E6, 0x98EC, 0x9378, 0x9939, 0xE4F6, 0x4B72,
+ 0xE4F8, 0xE4F9, 0x99F5, 0x9A0C, 0x9A3B, 0x9A10, 0x9A58, 0xE4FF,
+ 0x36C4, 0xE501, 0xE502, 0x9AE0, 0x9AE2, 0xE505, 0x9AF4, 0x4C0E,
+ 0x9B14, 0x9B2D, 0xE50A, 0x5034, 0x9B34, 0xE50D, 0x38C3, 0xE50F,
+ 0x9B50, 0x9B40, 0xE512, 0x5A45, 0xE514, 0x9B8E, 0xE516, 0x9C02,
+ 0x9BFF, 0x9C0C, 0xE51A, 0x9DD4, 0xE51C, 0xE51D, 0xE51E, 0xE51F,
+ 0xE520, 0xE521, 0x9D7E, 0x9D83, 0xE524, 0x9E0E, 0x6888,
+ /* Big5-HKSCS 0x91A1 .. 0x91FE */
+ 0x9DC4, 0xE528, 0xE529, 0xE52A, 0xE52B, 0xE52C, 0x9D39,
+ 0xE52E, 0xE52F, 0x9E90, 0x9E95, 0x9E9E, 0x9EA2, 0x4D34, 0x9EAA,
+ 0x9EAF, 0xE537, 0x9EC1, 0x3B60, 0x39E5, 0x3D1D, 0x4F32, 0x37BE,
+ 0xE53E, 0x9F02, 0x9F08, 0x4B96, 0x9424, 0xE543, 0x9F17, 0x9F16,
+ 0x9F39, 0x569F, 0x568A, 0x9F45, 0x99B8, 0xE54B, 0x97F2, 0x847F,
+ 0x9F62, 0x9F69, 0x7ADC, 0x9F8E, 0x7216, 0x4BBE, 0xE554, 0xE555,
+ 0x7177, 0xE557, 0xE558, 0xE559, 0x739E, 0xE55B, 0xE55C, 0x799F,
+ 0xE55E, 0xE55F, 0x9369, 0x93F3, 0xE562, 0x92EC, 0x9381, 0x93CB,
+ 0xE566, 0xE567, 0x7217, 0x3EEB, 0x7772, 0x7A43, 0x70D0, 0xE56D,
+ 0xE56E, 0x717E, 0xE570, 0x70A3, 0xE572, 0xE573, 0x3EC7, 0xE575,
+ 0xE576, 0xE577, 0x3722, 0xE579, 0xE57A, 0x36E1, 0xE57C, 0xE57D,
+ 0xE57E, 0x3723, 0xE580, 0x575B, 0xE582, 0xE583, 0xE584,
+ /* Big5-HKSCS 0x9240 .. 0x927E */
+ 0xE585, 0xE586, 0x8503, 0xE588, 0x8503, 0x8455, 0xE58B, 0xE58C,
+ 0xE58D, 0xE58E, 0xE58F, 0xE590, 0x44F4, 0xE592, 0xE593, 0xE594,
+ 0x67F9, 0x3733, 0x3C15, 0x3DE7, 0x586C, 0xE59A, 0x6810, 0x4057,
+ 0xE59D, 0xE59E, 0xE59F, 0xE5A0, 0xE5A1, 0x54CB, 0x569E, 0xE5A4,
+ 0x5692, 0xE5A6, 0xE5A7, 0xE5A8, 0x93C6, 0xE5AA, 0x939C, 0x4EF8,
+ 0x512B, 0x3819, 0xE5AF, 0x4EBC, 0xE5B1, 0xE5B2, 0x4F4B, 0x4F8A,
+ 0xE5B5, 0x5A68, 0xE5B7, 0xE5B8, 0x3999, 0xE5BA, 0xE5BB, 0x3435,
+ 0x4F29, 0xE5BE, 0xE5BF, 0xE5C0, 0x8ADA, 0xE5C2, 0x4E98,
+ /* Big5-HKSCS 0x92A1 .. 0x92FE */
+ 0x50CD, 0x510D, 0x4FA2, 0x4F03, 0xE5C8, 0xE5C9, 0x4F42,
+ 0x502E, 0x506C, 0x5081, 0x4FCC, 0x4FE5, 0x5058, 0x50FC, 0x5159,
+ 0x515B, 0x515D, 0x515E, 0x6E76, 0xE5D7, 0xE5D8, 0xE5D9, 0x6D72,
+ 0xE5DB, 0xE5DC, 0x51A8, 0x51C3, 0xE5DF, 0x44DD, 0xE5E1, 0xE5E2,
+ 0xE5E3, 0x8D7A, 0xE5E5, 0xE5E6, 0x5259, 0x52A4, 0xE5E9, 0x52E1,
+ 0x936E, 0x467A, 0x718C, 0xE5EE, 0xE5EF, 0xE5F0, 0xE5F1, 0x69D1,
+ 0xE5F3, 0x7479, 0x3EDE, 0x7499, 0x7414, 0x7456, 0x7398, 0x4B8E,
+ 0xE5FB, 0xE5FC, 0x53D0, 0x3584, 0x720F, 0xE600, 0x55B4, 0xE602,
+ 0x54CD, 0xE604, 0x571D, 0x925D, 0x96F4, 0x9366, 0x57DD, 0x578D,
+ 0x577F, 0x363E, 0x58CB, 0x5A99, 0xE60F, 0xE610, 0xE611, 0xE612,
+ 0x5A2C, 0x59B8, 0x928F, 0x5A7E, 0x5ACF, 0x5A12, 0xE619, 0xE61A,
+ 0xE61B, 0xE61C, 0x36F5, 0x6D05, 0x7443, 0x5A21, 0xE621,
+ /* Big5-HKSCS 0x9340 .. 0x937E */
+ 0x5A81, 0xE623, 0xE624, 0x93E0, 0x748C, 0xE627, 0x7105, 0x4972,
+ 0x9408, 0xE62B, 0x93BD, 0x37A0, 0x5C1E, 0x5C9E, 0x5E5E, 0x5E48,
+ 0xE632, 0xE633, 0xE634, 0x5ECD, 0x5B4F, 0xE637, 0xE638, 0x3701,
+ 0xE63A, 0x36DD, 0xE63C, 0x36D3, 0x812A, 0xE63F, 0xE640, 0xE641,
+ 0xE642, 0x5F0C, 0x5F0E, 0xE645, 0xE646, 0x5A6B, 0xE648, 0x5B44,
+ 0x8614, 0xE64B, 0x8860, 0x607E, 0xE64E, 0xE64F, 0x5FDB, 0x3EB8,
+ 0xE652, 0xE653, 0xE654, 0xE655, 0x61C0, 0xE657, 0xE658, 0xE659,
+ 0x6199, 0x6198, 0x6075, 0xE65D, 0xE65E, 0xE65F, 0xE660,
+ /* Big5-HKSCS 0x93A1 .. 0x93FE */
+ 0x6471, 0xE662, 0xE663, 0x3A29, 0xE665, 0xE666, 0xE667,
+ 0xE668, 0x6337, 0xE66A, 0x64B6, 0x6331, 0x63D1, 0xE66E, 0xE66F,
+ 0x62A4, 0xE671, 0x643B, 0x656B, 0x6972, 0x3BF4, 0xE676, 0xE677,
+ 0xE678, 0xE679, 0x550D, 0xE67B, 0xE67C, 0xE67D, 0x66CE, 0xE67F,
+ 0xE680, 0x3AE0, 0x4190, 0xE683, 0xE684, 0xE685, 0xE686, 0xE687,
+ 0xE688, 0x78EE, 0xE68A, 0xE68B, 0xE68C, 0x3464, 0xE68E, 0xE68F,
+ 0xE690, 0x668E, 0xE692, 0x666B, 0x4B93, 0x6630, 0xE696, 0xE697,
+ 0x6663, 0xE699, 0xE69A, 0x661E, 0xE69C, 0x38D1, 0xE69E, 0xE69F,
+ 0x3B99, 0xE6A1, 0xE6A2, 0x74D0, 0x3B96, 0x678F, 0xE6A6, 0x68B6,
+ 0x681E, 0x3BC4, 0x6ABE, 0x3863, 0xE6AC, 0xE6AD, 0x6A33, 0x6A52,
+ 0x6AC9, 0x6B05, 0xE6B2, 0x6511, 0x6898, 0x6A4C, 0x3BD7, 0x6A7A,
+ 0x6B57, 0xE6B9, 0xE6BA, 0x93A0, 0x92F2, 0xE6BD, 0xE6BE,
+ /* Big5-HKSCS 0x9440 .. 0x947E */
+ 0x9289, 0xE6C0, 0xE6C1, 0x9467, 0x6DA5, 0x6F0B, 0xE6C5, 0x6D67,
+ 0xE6C7, 0x3D8F, 0x6E04, 0xE6CA, 0x5A3D, 0x6E0A, 0x5847, 0x6D24,
+ 0x7842, 0x713B, 0xE6D1, 0xE6D2, 0x70F1, 0x7250, 0x7287, 0x7294,
+ 0xE6D7, 0xE6D8, 0x5179, 0xE6DA, 0xE6DB, 0x747A, 0xE6DD, 0xE6DE,
+ 0xE6DF, 0xE6E0, 0xE6E1, 0x3F06, 0x3EB1, 0xE6E4, 0xE6E5, 0xE6E6,
+ 0x60A7, 0x3EF3, 0x74CC, 0x743C, 0x9387, 0x7437, 0x449F, 0xE6EE,
+ 0x4551, 0x7583, 0x3F63, 0xE6F2, 0xE6F3, 0x3F58, 0x7555, 0x7673,
+ 0xE6F7, 0x3B19, 0x7468, 0xE6FA, 0xE6FB, 0xE6FC, 0x3AFB,
+ /* Big5-HKSCS 0x94A1 .. 0x94FE */
+ 0x3DCD, 0xE6FF, 0x3EFF, 0xE701, 0xE702, 0x91FA, 0x5732,
+ 0x9342, 0xE706, 0xE707, 0x50DF, 0xE709, 0xE70A, 0x7778, 0xE70C,
+ 0x770E, 0x770F, 0x777B, 0xE710, 0xE711, 0x3A5E, 0xE713, 0x7438,
+ 0x749B, 0x3EBF, 0xE717, 0xE718, 0x40C8, 0xE71A, 0xE71B, 0x9307,
+ 0xE71D, 0x781E, 0x788D, 0x7888, 0x78D2, 0x73D0, 0x7959, 0xE724,
+ 0xE725, 0x410E, 0x799B, 0x8496, 0x79A5, 0x6A2D, 0xE72B, 0x7A3A,
+ 0x79F4, 0x416E, 0xE72F, 0x4132, 0x9235, 0x79F1, 0xE733, 0xE734,
+ 0xE735, 0xE736, 0xE737, 0x3597, 0x556B, 0x3570, 0x36AA, 0xE73C,
+ 0xE73D, 0x7AE2, 0x5A59, 0xE740, 0xE741, 0xE742, 0x5A0D, 0xE744,
+ 0x78F0, 0x5A2A, 0xE747, 0x7AFE, 0x41F9, 0x7C5D, 0x7C6D, 0x4211,
+ 0xE74D, 0xE74E, 0xE74F, 0x7CCD, 0xE751, 0xE752, 0x7C8E, 0x7C7C,
+ 0x7CAE, 0x6AB2, 0x7DDC, 0x7E07, 0x7DD3, 0x7F4E, 0xE75B,
+ /* Big5-HKSCS 0x9540 .. 0x957E */
+ 0xE75C, 0xE75D, 0x7D97, 0xE75F, 0x426A, 0xE761, 0xE762, 0x67D6,
+ 0xE764, 0xE765, 0x57C4, 0xE767, 0xE768, 0xE769, 0x7FDD, 0x7B27,
+ 0xE76C, 0xE76D, 0xE76E, 0x7B0C, 0xE770, 0x99E6, 0x8645, 0x9A63,
+ 0x6A1C, 0xE775, 0x39E2, 0xE777, 0xE778, 0x9A1F, 0xE77A, 0x8480,
+ 0xE77C, 0xE77D, 0x44EA, 0x8137, 0x4402, 0x80C6, 0x8109, 0x8142,
+ 0xE784, 0x98C3, 0xE786, 0x8262, 0x8265, 0xE789, 0x8453, 0xE78B,
+ 0x8610, 0xE78D, 0x5A86, 0x417F, 0xE790, 0x5B2B, 0xE792, 0x5AE4,
+ 0xE794, 0x86A0, 0xE796, 0xE797, 0x882D, 0xE799, 0x5A02,
+ /* Big5-HKSCS 0x95A1 .. 0x95FE */
+ 0x886E, 0x4F45, 0x8887, 0x88BF, 0x88E6, 0x8965, 0x894D,
+ 0xE7A2, 0x8954, 0xE7A4, 0xE7A5, 0xE7A6, 0xE7A7, 0xE7A8, 0xE7A9,
+ 0x3EAD, 0x84A3, 0x46F5, 0x46CF, 0x37F2, 0x8A3D, 0x8A1C, 0xE7B1,
+ 0x5F4D, 0x922B, 0xE7B4, 0x65D4, 0x7129, 0x70C4, 0xE7B8, 0x9D6D,
+ 0x8C9F, 0x8CE9, 0xE7BC, 0x599A, 0x77C3, 0x59F0, 0x436E, 0x36D4,
+ 0x8E2A, 0x8EA7, 0xE7C4, 0x8F30, 0x8F4A, 0x42F4, 0x6C58, 0x6FBB,
+ 0xE7CA, 0x489B, 0x6F79, 0x6E8B, 0xE7CE, 0x9BE9, 0x36B5, 0xE7D1,
+ 0x90BB, 0x9097, 0x5571, 0x4906, 0x91BB, 0x9404, 0xE7D8, 0x4062,
+ 0xE7DA, 0x9427, 0xE7DC, 0xE7DD, 0x84E5, 0x8A2B, 0x9599, 0x95A7,
+ 0x9597, 0x9596, 0xE7E4, 0x7445, 0x3EC2, 0xE7E7, 0xE7E8, 0xE7E9,
+ 0x3EE7, 0xE7EB, 0x968F, 0xE7ED, 0xE7EE, 0xE7EF, 0x3ECC, 0xE7F1,
+ 0xE7F2, 0xE7F3, 0x7412, 0x746B, 0x3EFC, 0x9741, 0xE7F8,
+ /* Big5-HKSCS 0x9640 .. 0x967E */
+ 0x6847, 0x4A1D, 0xE7FB, 0xE7FC, 0x975D, 0x9368, 0xE7FF, 0xE800,
+ 0xE801, 0xE802, 0x92BA, 0x5B11, 0x8B69, 0x493C, 0x73F9, 0xE808,
+ 0x979B, 0x9771, 0x9938, 0xE80C, 0x5DC1, 0xE80E, 0xE80F, 0x981F,
+ 0xE811, 0x92F6, 0xE813, 0x91E5, 0x44C0, 0xE816, 0xE817, 0xE818,
+ 0x98DC, 0xE81A, 0x3F00, 0x922A, 0x4925, 0x8414, 0x993B, 0x994D,
+ 0xE821, 0x3DFD, 0x999B, 0x4B6F, 0x99AA, 0x9A5C, 0xE827, 0xE828,
+ 0x6A8F, 0x9A21, 0x5AFE, 0x9A2F, 0xE82D, 0x4B90, 0xE82F, 0x99BC,
+ 0x4BBD, 0x4B97, 0x937D, 0x5872, 0xE835, 0x5822, 0xE837,
+ /* Big5-HKSCS 0x96A1 .. 0x96FE */
+ 0xE838, 0x7844, 0xE83A, 0xE83B, 0x68C5, 0x3D7D, 0x9458,
+ 0x3927, 0x6150, 0xE841, 0xE842, 0x6107, 0x9C4F, 0x9C53, 0x9C7B,
+ 0x9C35, 0x9C10, 0x9B7F, 0x9BCF, 0xE84B, 0x9B9F, 0xE84D, 0xE84E,
+ 0x9D21, 0x4CAE, 0xE851, 0x9E18, 0x4CB0, 0x9D0C, 0xE855, 0xE856,
+ 0xE857, 0xE858, 0x9DA5, 0x84BD, 0xE85B, 0xE85C, 0xE85D, 0x85FC,
+ 0x4533, 0xE860, 0xE861, 0xE862, 0x8420, 0x85EE, 0xE865, 0xE866,
+ 0xE867, 0x79E2, 0xE869, 0xE86A, 0x492D, 0xE86C, 0x3D62, 0x93DB,
+ 0x92BE, 0x9348, 0xE871, 0x78B9, 0x9277, 0x944D, 0x4FE4, 0x3440,
+ 0x9064, 0xE878, 0x783D, 0x7854, 0x78B6, 0x784B, 0xE87D, 0xE87E,
+ 0xE87F, 0x369A, 0x4F72, 0x6FDA, 0x6FD9, 0x701E, 0x701E, 0x5414,
+ 0xE887, 0x57BB, 0x58F3, 0x578A, 0x9D16, 0x57D7, 0x7134, 0x34AF,
+ 0xE88F, 0x71EB, 0xE891, 0xE892, 0x5B28, 0xE894, 0xE895,
+ /* Big5-HKSCS 0x9740 .. 0x977E */
+ 0x610C, 0x5ACE, 0x5A0B, 0x42BC, 0xE89A, 0x372C, 0x4B7B, 0xE89D,
+ 0x93BB, 0x93B8, 0xE8A0, 0xE8A1, 0x8472, 0xE8A3, 0xE8A4, 0xE8A5,
+ 0xE8A6, 0xE8A7, 0x5994, 0xE8A9, 0xE8AA, 0x7DA8, 0xE8AC, 0xE8AD,
+ 0xE8AE, 0xE8AF, 0xE8B0, 0x92E5, 0x73E2, 0x3EE9, 0x74B4, 0xE8B5,
+ 0xE8B6, 0x3EE1, 0xE8B8, 0x6AD8, 0x73F3, 0x73FB, 0x3ED6, 0xE8BD,
+ 0xE8BE, 0xE8BF, 0xE8C0, 0xE8C1, 0xE8C2, 0xE8C3, 0x7448, 0xE8C5,
+ 0x70A5, 0xE8C7, 0x9284, 0x73E6, 0x935F, 0xE8CB, 0x9331, 0xE8CD,
+ 0xE8CE, 0x9386, 0xE8D0, 0xE8D1, 0x4935, 0xE8D3, 0x716B,
+ /* Big5-HKSCS 0x97A1 .. 0x97FE */
+ 0xE8D5, 0xE8D6, 0x56A4, 0xE8D8, 0xE8D9, 0xE8DA, 0x5502,
+ 0x79C4, 0xE8DD, 0x7DFE, 0xE8DF, 0xE8E0, 0xE8E1, 0x452E, 0x9401,
+ 0x370A, 0xE8E5, 0xE8E6, 0x59B0, 0xE8E8, 0xE8E9, 0xE8EA, 0x5AA1,
+ 0x36E2, 0xE8ED, 0x36B0, 0x925F, 0x5A79, 0xE8F1, 0xE8F2, 0x9374,
+ 0x3CCD, 0xE8F5, 0x4A96, 0x398A, 0x50F4, 0x3D69, 0x3D4C, 0xE8FB,
+ 0x7175, 0x42FB, 0xE8FE, 0x6E0F, 0xE900, 0x44EB, 0x6D57, 0xE903,
+ 0x7067, 0x6CAF, 0x3CD6, 0xE907, 0xE908, 0x6E02, 0x6F0C, 0x3D6F,
+ 0xE90C, 0x7551, 0x36BC, 0x34C8, 0x4680, 0x3EDA, 0x4871, 0x59C4,
+ 0x926E, 0x493E, 0x8F41, 0xE917, 0xE918, 0x5812, 0x57C8, 0x36D6,
+ 0xE91C, 0x70FE, 0xE91E, 0xE91F, 0xE920, 0xE921, 0xE922, 0x68B9,
+ 0x6967, 0xE925, 0xE926, 0xE927, 0xE928, 0xE929, 0xE92A, 0xE92B,
+ 0xE92C, 0x6A1A, 0xE92E, 0xE92F, 0x843E, 0x44DF, 0x44CE,
+ /* Big5-HKSCS 0x9840 .. 0x987E */
+ 0xE933, 0xE934, 0xE935, 0xE936, 0x6F17, 0xE938, 0x833D, 0xE93A,
+ 0x83ED, 0xE93C, 0xE93D, 0xE93E, 0x5989, 0x5A82, 0xE941, 0x5A61,
+ 0x5A71, 0xE944, 0xE945, 0x372D, 0x59EF, 0xE948, 0x36C7, 0x718E,
+ 0x9390, 0x669A, 0xE94D, 0x5A6E, 0x5A2B, 0xE950, 0x6A2B, 0xE952,
+ 0xE953, 0xE954, 0xE955, 0x711D, 0xE957, 0xE958, 0x4FB0, 0xE95A,
+ 0x5CC2, 0xE95C, 0xE95D, 0xE95E, 0x6A0C, 0xE960, 0xE961, 0x70A6,
+ 0x7133, 0xE964, 0x3DA5, 0x6CDF, 0xE967, 0xE968, 0x7E65, 0x59EB,
+ 0x5D2F, 0x3DF3, 0x5F5C, 0xE96E, 0xE96F, 0x7DA4, 0x8426,
+ /* Big5-HKSCS 0x98A1 .. 0x98FE */
+ 0x5485, 0xE973, 0xE974, 0xE975, 0x577E, 0xE977, 0xE978,
+ 0x3FE5, 0xE97A, 0xE97B, 0x7003, 0xE97D, 0x5D70, 0x738F, 0x7CD3,
+ 0xE981, 0xE982, 0x4FC8, 0x7FE7, 0x72CD, 0x7310, 0xE987, 0x7338,
+ 0x7339, 0xE98A, 0x7341, 0x7348, 0x3EA9, 0xE98E, 0x906C, 0x71F5,
+ 0xE991, 0x73E1, 0x81F6, 0x3ECA, 0x770C, 0x3ED1, 0x6CA2, 0x56FD,
+ 0x7419, 0x741E, 0x741F, 0x3EE2, 0x3EF0, 0x3EF4, 0x3EFA, 0x74D3,
+ 0x3F0E, 0x3F53, 0x7542, 0x756D, 0x7572, 0x758D, 0x3F7C, 0x75C8,
+ 0x75DC, 0x3FC0, 0x764D, 0x3FD7, 0x7674, 0x3FDC, 0x767A, 0xE9B0,
+ 0x7188, 0x5623, 0x8980, 0x5869, 0x401D, 0x7743, 0x4039, 0x6761,
+ 0x4045, 0x35DB, 0x7798, 0x406A, 0x406F, 0x5C5E, 0x77BE, 0x77CB,
+ 0x58F2, 0x7818, 0x70B9, 0x781C, 0x40A8, 0x7839, 0x7847, 0x7851,
+ 0x7866, 0x8448, 0xE9CB, 0x7933, 0x6803, 0x7932, 0x4103,
+ /* Big5-HKSCS 0x9940 .. 0x997E */
+ 0x4109, 0x7991, 0x7999, 0x8FBB, 0x7A06, 0x8FBC, 0x4167, 0x7A91,
+ 0x41B2, 0x7ABC, 0x8279, 0x41C4, 0x7ACF, 0x7ADB, 0x41CF, 0x4E21,
+ 0x7B62, 0x7B6C, 0x7B7B, 0x7C12, 0x7C1B, 0x4260, 0x427A, 0x7C7B,
+ 0x7C9C, 0x428C, 0x7CB8, 0x4294, 0x7CED, 0x8F93, 0x70C0, 0xE9EF,
+ 0x7DCF, 0x7DD4, 0x7DD0, 0x7DFD, 0x7FAE, 0x7FB4, 0x729F, 0x4397,
+ 0x8020, 0x8025, 0x7B39, 0x802E, 0x8031, 0x8054, 0x3DCC, 0x57B4,
+ 0x70A0, 0x80B7, 0x80E9, 0x43ED, 0x810C, 0x732A, 0x810E, 0x8112,
+ 0x7560, 0x8114, 0x4401, 0x3B39, 0x8156, 0x8159, 0x815A,
+ /* Big5-HKSCS 0x99A1 .. 0x99FE */
+ 0x4413, 0x583A, 0x817C, 0x8184, 0x4425, 0x8193, 0x442D,
+ 0x81A5, 0x57EF, 0x81C1, 0x81E4, 0x8254, 0x448F, 0x82A6, 0x8276,
+ 0x82CA, 0x82D8, 0x82FF, 0x44B0, 0x8357, 0x9669, 0x698A, 0x8405,
+ 0x70F5, 0x8464, 0x60E3, 0x8488, 0x4504, 0x84BE, 0x84E1, 0x84F8,
+ 0x8510, 0x8538, 0x8552, 0x453B, 0x856F, 0x8570, 0x85E0, 0x4577,
+ 0x8672, 0x8692, 0x86B2, 0x86EF, 0x9645, 0x878B, 0x4606, 0x4617,
+ 0x88AE, 0x88FF, 0x8924, 0x8947, 0x8991, 0xEA43, 0x8A29, 0x8A38,
+ 0x8A94, 0x8AB4, 0x8C51, 0x8CD4, 0x8CF2, 0x8D1C, 0x4798, 0x585F,
+ 0x8DC3, 0x47ED, 0x4EEE, 0x8E3A, 0x55D8, 0x5754, 0x8E71, 0x55F5,
+ 0x8EB0, 0x4837, 0x8ECE, 0x8EE2, 0x8EE4, 0x8EED, 0x8EF2, 0x8FB7,
+ 0x8FC1, 0x8FCA, 0x8FCC, 0x9033, 0x99C4, 0x48AD, 0x98E0, 0x9213,
+ 0x491E, 0x9228, 0x9258, 0x926B, 0x92B1, 0x92AE, 0x92BF,
+ /* Big5-HKSCS 0x9A40 .. 0x9A7E */
+ 0x92E3, 0x92EB, 0x92F3, 0x92F4, 0x92FD, 0x9343, 0x9384, 0x93AD,
+ 0x4945, 0x4951, 0x9EBF, 0x9417, 0x5301, 0x941D, 0x942D, 0x943E,
+ 0x496A, 0x9454, 0x9479, 0x952D, 0x95A2, 0x49A7, 0x95F4, 0x9633,
+ 0x49E5, 0x67A0, 0x4A24, 0x9740, 0x4A35, 0x97B2, 0x97C2, 0x5654,
+ 0x4AE4, 0x60E8, 0x98B9, 0x4B19, 0x98F1, 0x5844, 0x990E, 0x9919,
+ 0x51B4, 0x991C, 0x9937, 0x9942, 0x995D, 0x9962, 0x4B70, 0x99C5,
+ 0x4B9D, 0x9A3C, 0x9B0F, 0x7A83, 0x9B69, 0x9B81, 0x9BDD, 0x9BF1,
+ 0x9BF4, 0x4C6D, 0x9C20, 0x376F, 0xEAA9, 0x9D49, 0x9C3A,
+ /* Big5-HKSCS 0x9AA1 .. 0x9AFE */
+ 0x9EFE, 0x5650, 0x9D93, 0x9DBD, 0x9DC0, 0x9DFC, 0x94F6,
+ 0x8FB6, 0x9E7B, 0x9EAC, 0x9EB1, 0x9EBD, 0x9EC6, 0x94DC, 0x9EE2,
+ 0x9EF1, 0x9EF8, 0x7AC8, 0x9F44, 0xEABF, 0xEAC0, 0xEAC1, 0x691A,
+ 0x94C3, 0x59AC, 0xEAC5, 0x5840, 0x94C1, 0x37B9, 0xEAC9, 0xEACA,
+ 0xEACB, 0xEACC, 0x5757, 0x7173, 0xEACF, 0xEAD0, 0xEAD1, 0x546A,
+ 0xEAD3, 0xEAD4, 0x549E, 0xEAD6, 0xEAD7, 0xEAD8, 0xEAD9, 0xEADA,
+ 0x60E7, 0xEADC, 0x567A, 0xEADE, 0xEADF, 0xEAE0, 0xEAE1, 0xEAE2,
+ 0xEAE3, 0x6955, 0x9C2F, 0x87A5, 0xEAE7, 0xEAE8, 0xEAE9, 0xEAEA,
+ 0xEAEB, 0xEAEC, 0x5C20, 0xEAEE, 0x5E0B, 0xEAF0, 0xEAF1, 0xEAF2,
+ 0x671E, 0xEAF4, 0xEAF5, 0xEAF6, 0x3647, 0xEAF8, 0xEAF9, 0xEAFA,
+ 0xEAFB, 0x5364, 0x84AD, 0xEAFE, 0xEAFF, 0xEB00, 0x8B81, 0xEB02,
+ 0xEB03, 0xEB04, 0xEB05, 0x4E78, 0x70BB, 0xEB08, 0xEB09,
+ /* Big5-HKSCS 0x9B40 .. 0x9B7E */
+ 0xEB0A, 0xEB0B, 0xEB0C, 0xEB0D, 0xEB0E, 0xEB0F, 0x62C3, 0xEB11,
+ 0xEB12, 0x7198, 0x6855, 0xEB15, 0x69E9, 0x36C8, 0xEB18, 0xEB19,
+ 0xEB1A, 0xEB1B, 0xEB1C, 0xEB1D, 0x82FD, 0xEB1F, 0xEB20, 0xEB21,
+ 0x89A5, 0xEB23, 0x8FA0, 0xEB25, 0x97B8, 0xEB27, 0x9847, 0x9ABD,
+ 0xEB2A, 0xEB2B, 0xEB2C, 0xEB2D, 0xEB2E, 0xEB2F, 0xEB30, 0xEB31,
+ 0xEB32, 0xEB33, 0xEB34, 0xEB35, 0xEB36, 0xEB37, 0xEB38, 0xEB39,
+ 0x5FB1, 0x6648, 0x66BF, 0xEB3D, 0xEB3E, 0xEB3F, 0x7201, 0xEB41,
+ 0x77D7, 0xEB43, 0xEB44, 0x7E87, 0xEB46, 0x58B5, 0x670E,
+ /* Big5-HKSCS 0x9BA1 .. 0x9BFE */
+ 0x6918, 0xEB4A, 0xEB4B, 0xEB4C, 0xEB4D, 0xEB4E, 0xEB4F,
+ 0xEB50, 0x48D0, 0x4AB8, 0xEB53, 0xEB54, 0xEB55, 0xEB56, 0xEB57,
+ 0xEB58, 0xEB59, 0xEB5A, 0xEB5B, 0x51D2, 0xEB5D, 0x599F, 0xEB5F,
+ 0x3BBE, 0xEB61, 0xEB62, 0xEB63, 0x5788, 0xEB65, 0x399B, 0xEB67,
+ 0xEB68, 0xEB69, 0x3762, 0xEB6B, 0x8B5E, 0xEB6D, 0x99D6, 0xEB6F,
+ 0xEB70, 0xEB71, 0x7209, 0xEB73, 0xEB74, 0x5965, 0xEB76, 0xEB77,
+ 0xEB78, 0x8EDA, 0xEB7A, 0x528F, 0x573F, 0x7171, 0xEB7E, 0xEB7F,
+ 0xEB80, 0xEB81, 0x55BC, 0xEB83, 0xEB84, 0xEB85, 0x91D4, 0x3473,
+ 0xEB88, 0xEB89, 0xEB8A, 0x4718, 0xEB8C, 0xEB8D, 0xEB8E, 0xEB8F,
+ 0xEB90, 0x5066, 0x34FB, 0xEB93, 0x60DE, 0xEB95, 0x477C, 0xEB97,
+ 0xEB98, 0xEB99, 0xEB9A, 0xEB9B, 0x57A1, 0x7151, 0x6FB6, 0xEB9F,
+ 0xEBA0, 0x9056, 0xEBA2, 0xEBA3, 0x8B62, 0xEBA5, 0xEBA6,
+ /* Big5-HKSCS 0x9C40 .. 0x9C7E */
+ 0x5D5B, 0xEBA8, 0x8F36, 0xEBAA, 0xEBAB, 0x8AEA, 0xEBAD, 0xEBAE,
+ 0xEBAF, 0xEBB0, 0x4BC0, 0xEBB2, 0xEBB3, 0xEBB4, 0x9465, 0xEBB6,
+ 0x6195, 0x5A27, 0xEBB9, 0x4FBB, 0x56B9, 0xEBBC, 0xEBBD, 0x4E6A,
+ 0xEBBF, 0x9656, 0x6D8F, 0xEBC2, 0x3618, 0x8977, 0xEBC5, 0xEBC6,
+ 0xEBC7, 0xEBC8, 0x71DF, 0xEBCA, 0x7B42, 0xEBCC, 0xEBCD, 0xEBCE,
+ 0x9104, 0xEBD0, 0x7A45, 0x9DF0, 0xEBD3, 0x9A26, 0xEBD5, 0x365F,
+ 0xEBD7, 0xEBD8, 0x7983, 0xEBDA, 0xEBDB, 0x5D2C, 0xEBDD, 0x83CF,
+ 0xEBDF, 0x46D0, 0xEBE1, 0x753B, 0x8865, 0xEBE4, 0x58B6,
+ /* Big5-HKSCS 0x9CA1 .. 0x9CFE */
+ 0x371C, 0xEBE7, 0xEBE8, 0xEBE9, 0x3C54, 0xEBEB, 0xEBEC,
+ 0x9281, 0xEBEE, 0xEBEF, 0x9330, 0xEBF1, 0xEBF2, 0x6C39, 0x949F,
+ 0xEBF5, 0xEBF6, 0x8827, 0x88F5, 0xEBF9, 0xEBFA, 0xEBFB, 0x6EB8,
+ 0xEBFD, 0xEBFE, 0x39A4, 0x36B9, 0x5C10, 0x79E3, 0x453F, 0x66B6,
+ 0xEC05, 0xEC06, 0x8943, 0xEC08, 0xEC09, 0x56D6, 0x40DF, 0xEC0C,
+ 0x39A1, 0xEC0E, 0xEC0F, 0xEC10, 0x71AD, 0x8366, 0xEC13, 0xEC14,
+ 0x5A67, 0x4CB7, 0xEC17, 0xEC18, 0xEC19, 0xEC1A, 0xEC1B, 0xEC1C,
+ 0xEC1D, 0x7B43, 0x797E, 0xEC20, 0x6FB5, 0xEC22, 0x6A03, 0xEC24,
+ 0x53A2, 0xEC26, 0x93BF, 0x6836, 0x975D, 0xEC2A, 0xEC2B, 0xEC2C,
+ 0xEC2D, 0xEC2E, 0xEC2F, 0x5D85, 0xEC31, 0xEC32, 0x5715, 0x9823,
+ 0xEC35, 0x5DAB, 0xEC37, 0x65BE, 0x69D5, 0x53D2, 0xEC3B, 0xEC3C,
+ 0x3C11, 0x6736, 0xEC3F, 0xEC40, 0xEC41, 0xEC42, 0xEC43,
+ /* Big5-HKSCS 0x9D40 .. 0x9D7E */
+ 0xEC44, 0xEC45, 0xEC46, 0xEC47, 0xEC48, 0xEC49, 0x35CA, 0xEC4B,
+ 0xEC4C, 0x48FA, 0x63E6, 0xEC4F, 0x7808, 0x9255, 0xEC52, 0x43F2,
+ 0xEC54, 0x43DF, 0xEC56, 0xEC57, 0xEC58, 0x59F8, 0xEC5A, 0x8F0B,
+ 0xEC5C, 0xEC5D, 0x7B51, 0xEC5F, 0xEC60, 0x3DF7, 0xEC62, 0xEC63,
+ 0x8FD0, 0x728F, 0x568B, 0xEC67, 0xEC68, 0xEC69, 0xEC6A, 0xEC6B,
+ 0xEC6C, 0xEC6D, 0xEC6E, 0xEC6F, 0xEC70, 0xEC71, 0xEC72, 0xEC73,
+ 0x7E9F, 0xEC75, 0xEC76, 0x4CA4, 0x9547, 0xEC79, 0x71A2, 0xEC7B,
+ 0x4D91, 0x9012, 0xEC7E, 0x4D9C, 0xEC80, 0x8FBE, 0x55C1,
+ /* Big5-HKSCS 0x9DA1 .. 0x9DFE */
+ 0x8FBA, 0xEC84, 0x8FB9, 0xEC86, 0x4509, 0x7E7F, 0x6F56,
+ 0x6AB1, 0x4EEA, 0x34E4, 0xEC8D, 0xEC8E, 0x373A, 0x8E80, 0xEC91,
+ 0xEC92, 0xEC93, 0xEC94, 0xEC95, 0xEC96, 0x3DEB, 0xEC98, 0xEC99,
+ 0xEC9A, 0xEC9B, 0x4E9A, 0xEC9D, 0xEC9E, 0x56BF, 0xECA0, 0x8E0E,
+ 0x5B6D, 0xECA3, 0xECA4, 0x63DE, 0x62D0, 0xECA7, 0xECA8, 0x6530,
+ 0x562D, 0xECAB, 0x541A, 0xECAD, 0x3DC6, 0xECAF, 0x4C7D, 0x5622,
+ 0x561E, 0x7F49, 0xECB4, 0x5975, 0xECB6, 0x8770, 0x4E1C, 0xECB9,
+ 0xECBA, 0xECBB, 0x8117, 0x9D5E, 0x8D18, 0x763B, 0x9C45, 0x764E,
+ 0x77B9, 0x9345, 0x5432, 0x8148, 0x82F7, 0x5625, 0x8132, 0x8418,
+ 0x80BD, 0x55EA, 0x7962, 0x5643, 0x5416, 0xECCF, 0x35CE, 0x5605,
+ 0x55F1, 0x66F1, 0xECD4, 0x362D, 0x7534, 0x55F0, 0x55BA, 0x5497,
+ 0x5572, 0xECDB, 0xECDC, 0x5ED0, 0xECDE, 0xECDF, 0xECE0,
+ /* Big5-HKSCS 0x9E40 .. 0x9E7E */
+ 0xECE1, 0x9EAB, 0x7D5A, 0x55DE, 0xECE5, 0x629D, 0x976D, 0x5494,
+ 0x8CCD, 0x71F6, 0x9176, 0x63FC, 0x63B9, 0x63FE, 0x5569, 0xECF0,
+ 0x9C72, 0xECF2, 0x519A, 0x34DF, 0xECF5, 0x51A7, 0x544D, 0x551E,
+ 0x5513, 0x7666, 0x8E2D, 0xECFC, 0x75B1, 0x80B6, 0x8804, 0x8786,
+ 0x88C7, 0x81B6, 0x841C, 0xED04, 0x44EC, 0x7304, 0xED07, 0x5B90,
+ 0x830B, 0xED0A, 0x567B, 0xED0C, 0xED0D, 0xED0E, 0xED0F, 0xED10,
+ 0xED11, 0x9170, 0xED13, 0x9208, 0xED15, 0xED16, 0xED17, 0xED18,
+ 0x7266, 0xED1A, 0x474E, 0xED1C, 0xED1D, 0xED1E, 0x40FA,
+ /* Big5-HKSCS 0x9EA1 .. 0x9EFE */
+ 0x9C5D, 0x651F, 0xED22, 0x48F3, 0xED24, 0xED25, 0xED26,
+ 0xED27, 0x6062, 0xED29, 0xED2A, 0xED2B, 0xED2C, 0xED2D, 0x71A3,
+ 0x7E8E, 0x9D50, 0x4E1A, 0x4E04, 0x3577, 0x5B0D, 0x6CB2, 0x5367,
+ 0x36AC, 0x39DC, 0x537D, 0x36A5, 0xED3B, 0x589A, 0xED3D, 0x822D,
+ 0x544B, 0x57AA, 0xED41, 0xED42, 0xED43, 0x3A52, 0xED45, 0x7374,
+ 0xED47, 0x4D09, 0x9BED, 0xED4A, 0xED4B, 0x4C5B, 0xED4D, 0xED4E,
+ 0xED4F, 0x845C, 0xED51, 0xED52, 0xED53, 0xED54, 0x632E, 0x7D25,
+ 0xED57, 0xED58, 0x3A2A, 0x9008, 0x52CC, 0x3E74, 0x367A, 0x45E9,
+ 0xED5F, 0x7640, 0x5AF0, 0xED62, 0x787A, 0x47B6, 0x58A7, 0x40BF,
+ 0x567C, 0x9B8B, 0x5D74, 0x7654, 0xED6B, 0x9E85, 0x4CE1, 0x75F9,
+ 0x37FB, 0x6119, 0xED71, 0xED72, 0xED73, 0x565D, 0xED75, 0x57A7,
+ 0xED77, 0xED78, 0x5234, 0xED7A, 0x35AD, 0x6C4A, 0x9D7C,
+ /* Big5-HKSCS 0x9F40 .. 0x9F7E */
+ 0x7C56, 0x9B39, 0x57DE, 0xED81, 0x5C53, 0x64D3, 0xED84, 0xED85,
+ 0xED86, 0x86AD, 0xED88, 0xED89, 0xED8A, 0xED8B, 0xED8C, 0x51FE,
+ 0xED8E, 0x5D8E, 0x9703, 0xED91, 0x9E81, 0x904C, 0x7B1F, 0x9B02,
+ 0x5CD1, 0x7BA3, 0x6268, 0x6335, 0x9AFF, 0x7BCF, 0x9B2A, 0x7C7E,
+ 0x9B2E, 0x7C42, 0x7C86, 0x9C15, 0x7BFC, 0x9B09, 0x9F17, 0x9C1B,
+ 0xEDA6, 0x9F5A, 0x5573, 0x5BC3, 0x4FFD, 0x9E98, 0x4FF2, 0x5260,
+ 0x3E06, 0x52D1, 0x5767, 0x5056, 0x59B7, 0x5E12, 0x97C8, 0x9DAB,
+ 0x8F5C, 0x5469, 0x97B4, 0x9940, 0x97BA, 0x532C, 0x6130,
+ /* Big5-HKSCS 0x9FA1 .. 0x9FFE */
+ 0x692C, 0x53DA, 0x9C0A, 0x9D02, 0x4C3B, 0x9641, 0x6980,
+ 0x50A6, 0x7546, 0xEDC6, 0x99DA, 0x5273, 0xEDC9, 0x9159, 0x9681,
+ 0x915C, 0xEDCD, 0x9151, 0xEDCF, 0x637F, 0xEDD1, 0x6ACA, 0x5611,
+ 0x918E, 0x757A, 0x6285, 0xEDD7, 0x734F, 0x7C70, 0xEDDA, 0xEDDB,
+ 0xEDDC, 0xEDDD, 0x76D6, 0x9B9D, 0x4E2A, 0xEDE1, 0x83BE, 0x8842,
+ 0xEDE4, 0x5C4A, 0x69C0, 0x50ED, 0x577A, 0x521F, 0x5DF5, 0x4ECE,
+ 0x6C31, 0xEDED, 0x4F39, 0x549C, 0x54DA, 0x529A, 0x8D82, 0x35FE,
+ 0x5F0C, 0x35F3, 0xEDF6, 0x6B52, 0x917C, 0x9FA5, 0x9B97, 0x982E,
+ 0x98B4, 0x9ABA, 0x9EA8, 0x9E84, 0x717A, 0x7B14, 0xEE02, 0x6BFA,
+ 0x8818, 0x7F78, 0xEE06, 0x5620, 0xEE08, 0x8E77, 0x9F53, 0xEE0B,
+ 0x8DD4, 0x8E4F, 0x9E1C, 0x8E01, 0x6282, 0xEE11, 0x8E28, 0x8E75,
+ 0x7AD3, 0xEE15, 0x7A3E, 0x78D8, 0x6CEA, 0x8A67, 0x7607,
+ /* Big5-HKSCS 0xA040 .. 0xA07E */
+ 0xEE1B, 0x9F26, 0x6CCE, 0x87D6, 0x75C3, 0xEE20, 0x7853, 0xEE22,
+ 0x8D0C, 0x72E2, 0x7371, 0x8B2D, 0x7302, 0x74F1, 0x8CEB, 0xEE2A,
+ 0x862F, 0x5FBA, 0x88A0, 0x44B7, 0xEE2F, 0xEE30, 0xEE31, 0xEE32,
+ 0x8A7E, 0xEE34, 0xEE35, 0x60FD, 0x7667, 0x9AD7, 0x9D44, 0x936E,
+ 0x9B8F, 0x87F5, 0xEE3D, 0x880F, 0x8CF7, 0x732C, 0x9721, 0x9BB0,
+ 0x35D6, 0x72B2, 0x4C07, 0x7C51, 0x994A, 0xEE48, 0x6159, 0x4C04,
+ 0x9E96, 0x617D, 0xEE4D, 0x575F, 0x616F, 0x62A6, 0x6239, 0x62CE,
+ 0x3A5C, 0x61E2, 0x53AA, 0xEE56, 0x6364, 0x6802, 0x35D2,
+ /* Big5-HKSCS 0xA0A1 .. 0xA0FE */
+ 0x5D57, 0xEE5B, 0x8FDA, 0xEE5D, 0xEE5E, 0x50D9, 0xEE60,
+ 0x7906, 0x5332, 0x9638, 0xEE64, 0x4065, 0xEE66, 0x77FE, 0xEE68,
+ 0x7CC2, 0xEE6A, 0x7CDA, 0x7A2D, 0x8066, 0x8063, 0x7D4D, 0x7505,
+ 0x74F2, 0x8994, 0x821A, 0x670C, 0x8062, 0xEE76, 0x805B, 0x74F0,
+ 0x8103, 0x7724, 0x8989, 0xEE7C, 0x7553, 0xEE7E, 0x87A9, 0x87CE,
+ 0x81C8, 0x878C, 0x8A49, 0x8CAD, 0x8B43, 0x772B, 0x74F8, 0x84DA,
+ 0x3635, 0x69B2, 0x8DA6, 0xEE8C, 0x89A9, 0x7468, 0x6DB9, 0x87C1,
+ 0xEE91, 0x74E7, 0x3DDB, 0x7176, 0x60A4, 0x619C, 0x3CD1, 0x7162,
+ 0x6077, 0xEE9A, 0x7F71, 0xEE9C, 0x7250, 0x60E9, 0x4B7E, 0x5220,
+ 0x3C18, 0xEEA2, 0xEEA3, 0xEEA4, 0xEEA5, 0xEEA6, 0xEEA7, 0xEEA8,
+ 0xEEA9, 0xEEAA, 0x5CC1, 0xEEAC, 0xEEAD, 0xEEAE, 0xEEAF, 0xEEB0,
+ 0xEEB1, 0x4562, 0x5B1F, 0xEEB4, 0x9F50, 0x9EA6, 0xEEB7,
+ /* Big5-HKSCS 0xA140 .. 0xA17E */
+ 0x3000, 0xFF0C, 0x3001, 0x3002, 0xFF0E, 0x2027, 0xFF1B, 0xFF1A,
+ 0xFF1F, 0xFF01, 0xFE30, 0x2026, 0x2025, 0xFE50, 0xFE51, 0xFE52,
+ 0x00B7, 0xFE54, 0xFE55, 0xFE56, 0xFE57, 0xFF5C, 0x2013, 0xFE31,
+ 0x2014, 0xFE33, 0x2574, 0xFE34, 0xFE4F, 0xFF08, 0xFF09, 0xFE35,
+ 0xFE36, 0xFF5B, 0xFF5D, 0xFE37, 0xFE38, 0x3014, 0x3015, 0xFE39,
+ 0xFE3A, 0x3010, 0x3011, 0xFE3B, 0xFE3C, 0x300A, 0x300B, 0xFE3D,
+ 0xFE3E, 0x3008, 0x3009, 0xFE3F, 0xFE40, 0x300C, 0x300D, 0xFE41,
+ 0xFE42, 0x300E, 0x300F, 0xFE43, 0xFE44, 0xFE59, 0xFE5A,
+ /* Big5-HKSCS 0xA1A1 .. 0xA1FE */
+ 0xFE5B, 0xFE5C, 0xFE5D, 0xFE5E, 0x2018, 0x2019, 0x201C,
+ 0x201D, 0x301D, 0x301E, 0x2035, 0x2032, 0xFF03, 0xFF06, 0xFF0A,
+ 0x203B, 0x00A7, 0x3003, 0x25CB, 0x25CF, 0x25B3, 0x25B2, 0x25CE,
+ 0x2606, 0x2605, 0x25C7, 0x25C6, 0x25A1, 0x25A0, 0x25BD, 0x25BC,
+ 0x32A3, 0x2105, 0x00AF, 0xFFE3, 0xFF3F, 0x02CD, 0xFE49, 0xFE4A,
+ 0xFE4D, 0xFE4E, 0xFE4B, 0xFE4C, 0xFE5F, 0xFE60, 0xFE61, 0xFF0B,
+ 0xFF0D, 0x00D7, 0x00F7, 0x00B1, 0x221A, 0xFF1C, 0xFF1E, 0xFF1D,
+ 0x2266, 0x2267, 0x2260, 0x221E, 0x2252, 0x2261, 0xFE62, 0xFE63,
+ 0xFE64, 0xFE65, 0xFE66, 0xFF5E, 0x2229, 0x222A, 0x22A5, 0x2220,
+ 0x221F, 0x22BF, 0x33D2, 0x33D1, 0x222B, 0x222E, 0x2235, 0x2234,
+ 0x2640, 0x2642, 0x2295, 0x2299, 0x2191, 0x2193, 0x2190, 0x2192,
+ 0x2196, 0x2197, 0x2199, 0x2198, 0x2225, 0x2223, 0xFF0F,
+ /* Big5-HKSCS 0xA240 .. 0xA27E */
+ 0xFF3C, 0x2215, 0xFE68, 0xFF04, 0xFFE5, 0x3012, 0xFFE0, 0xFFE1,
+ 0xFF05, 0xFF20, 0x2103, 0x2109, 0xFE69, 0xFE6A, 0xFE6B, 0x33D5,
+ 0x339C, 0x339D, 0x339E, 0x33CE, 0x33A1, 0x338E, 0x338F, 0x33C4,
+ 0x00B0, 0x5159, 0x515B, 0x515E, 0x515D, 0x5161, 0x5163, 0x55E7,
+ 0x74E9, 0x7CCE, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586,
+ 0x2587, 0x2588, 0x258F, 0x258E, 0x258D, 0x258C, 0x258B, 0x258A,
+ 0x2589, 0x253C, 0x2534, 0x252C, 0x2524, 0x251C, 0x2594, 0x2500,
+ 0x2502, 0x2595, 0x250C, 0x2510, 0x2514, 0x2518, 0x256D,
+ /* Big5-HKSCS 0xA2A1 .. 0xA2FE */
+ 0x256E, 0x2570, 0x256F, 0x2550, 0x255E, 0x256A, 0x2561,
+ 0x25E2, 0x25E3, 0x25E5, 0x25E4, 0x2571, 0x2572, 0x2573, 0xFF10,
+ 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18,
+ 0xFF19, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166,
+ 0x2167, 0x2168, 0x2169, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025,
+ 0x3026, 0x3027, 0x3028, 0x3029, 0x5341, 0x5344, 0x5345, 0xFF21,
+ 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29,
+ 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31,
+ 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39,
+ 0xFF3A, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,
+ 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
+ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56,
+ /* Big5-HKSCS 0xA340 .. 0xA37E */
+ 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0x0391, 0x0392, 0x0393, 0x0394,
+ 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C,
+ 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5,
+ 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x03B1, 0x03B2, 0x03B3, 0x03B4,
+ 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC,
+ 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5,
+ 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x3105, 0x3106, 0x3107, 0x3108,
+ 0x3109, 0x310A, 0x310B, 0x310C, 0x310D, 0x310E, 0x310F,
+ /* Big5-HKSCS 0xA3A1 .. 0xA3FE */
+ 0x3110, 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116,
+ 0x3117, 0x3118, 0x3119, 0x311A, 0x311B, 0x311C, 0x311D, 0x311E,
+ 0x311F, 0x3120, 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126,
+ 0x3127, 0x3128, 0x3129, 0x02D9, 0x02C9, 0x02CA, 0x02C7, 0x02CB,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x20AC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ /* Big5-HKSCS 0xA440 .. 0xA47E */
+ 0x4E00, 0x4E59, 0x4E01, 0x4E03, 0x4E43, 0x4E5D, 0x4E86, 0x4E8C,
+ 0x4EBA, 0x513F, 0x5165, 0x516B, 0x51E0, 0x5200, 0x5201, 0x529B,
+ 0x5315, 0x5341, 0x535C, 0x53C8, 0x4E09, 0x4E0B, 0x4E08, 0x4E0A,
+ 0x4E2B, 0x4E38, 0x51E1, 0x4E45, 0x4E48, 0x4E5F, 0x4E5E, 0x4E8E,
+ 0x4EA1, 0x5140, 0x5203, 0x52FA, 0x5343, 0x53C9, 0x53E3, 0x571F,
+ 0x58EB, 0x5915, 0x5927, 0x5973, 0x5B50, 0x5B51, 0x5B53, 0x5BF8,
+ 0x5C0F, 0x5C22, 0x5C38, 0x5C71, 0x5DDD, 0x5DE5, 0x5DF1, 0x5DF2,
+ 0x5DF3, 0x5DFE, 0x5E72, 0x5EFE, 0x5F0B, 0x5F13, 0x624D,
+ /* Big5-HKSCS 0xA4A1 .. 0xA4FE */
+ 0x4E11, 0x4E10, 0x4E0D, 0x4E2D, 0x4E30, 0x4E39, 0x4E4B,
+ 0x5C39, 0x4E88, 0x4E91, 0x4E95, 0x4E92, 0x4E94, 0x4EA2, 0x4EC1,
+ 0x4EC0, 0x4EC3, 0x4EC6, 0x4EC7, 0x4ECD, 0x4ECA, 0x4ECB, 0x4EC4,
+ 0x5143, 0x5141, 0x5167, 0x516D, 0x516E, 0x516C, 0x5197, 0x51F6,
+ 0x5206, 0x5207, 0x5208, 0x52FB, 0x52FE, 0x52FF, 0x5316, 0x5339,
+ 0x5348, 0x5347, 0x5345, 0x535E, 0x5384, 0x53CB, 0x53CA, 0x53CD,
+ 0x58EC, 0x5929, 0x592B, 0x592A, 0x592D, 0x5B54, 0x5C11, 0x5C24,
+ 0x5C3A, 0x5C6F, 0x5DF4, 0x5E7B, 0x5EFF, 0x5F14, 0x5F15, 0x5FC3,
+ 0x6208, 0x6236, 0x624B, 0x624E, 0x652F, 0x6587, 0x6597, 0x65A4,
+ 0x65B9, 0x65E5, 0x66F0, 0x6708, 0x6728, 0x6B20, 0x6B62, 0x6B79,
+ 0x6BCB, 0x6BD4, 0x6BDB, 0x6C0F, 0x6C34, 0x706B, 0x722A, 0x7236,
+ 0x723B, 0x7247, 0x7259, 0x725B, 0x72AC, 0x738B, 0x4E19,
+ /* Big5-HKSCS 0xA540 .. 0xA57E */
+ 0x4E16, 0x4E15, 0x4E14, 0x4E18, 0x4E3B, 0x4E4D, 0x4E4F, 0x4E4E,
+ 0x4EE5, 0x4ED8, 0x4ED4, 0x4ED5, 0x4ED6, 0x4ED7, 0x4EE3, 0x4EE4,
+ 0x4ED9, 0x4EDE, 0x5145, 0x5144, 0x5189, 0x518A, 0x51AC, 0x51F9,
+ 0x51FA, 0x51F8, 0x520A, 0x52A0, 0x529F, 0x5305, 0x5306, 0x5317,
+ 0x531D, 0x4EDF, 0x534A, 0x5349, 0x5361, 0x5360, 0x536F, 0x536E,
+ 0x53BB, 0x53EF, 0x53E4, 0x53F3, 0x53EC, 0x53EE, 0x53E9, 0x53E8,
+ 0x53FC, 0x53F8, 0x53F5, 0x53EB, 0x53E6, 0x53EA, 0x53F2, 0x53F1,
+ 0x53F0, 0x53E5, 0x53ED, 0x53FB, 0x56DB, 0x56DA, 0x5916,
+ /* Big5-HKSCS 0xA5A1 .. 0xA5FE */
+ 0x592E, 0x5931, 0x5974, 0x5976, 0x5B55, 0x5B83, 0x5C3C,
+ 0x5DE8, 0x5DE7, 0x5DE6, 0x5E02, 0x5E03, 0x5E73, 0x5E7C, 0x5F01,
+ 0x5F18, 0x5F17, 0x5FC5, 0x620A, 0x6253, 0x6254, 0x6252, 0x6251,
+ 0x65A5, 0x65E6, 0x672E, 0x672C, 0x672A, 0x672B, 0x672D, 0x6B63,
+ 0x6BCD, 0x6C11, 0x6C10, 0x6C38, 0x6C41, 0x6C40, 0x6C3E, 0x72AF,
+ 0x7384, 0x7389, 0x74DC, 0x74E6, 0x7518, 0x751F, 0x7528, 0x7529,
+ 0x7530, 0x7531, 0x7532, 0x7533, 0x758B, 0x767D, 0x76AE, 0x76BF,
+ 0x76EE, 0x77DB, 0x77E2, 0x77F3, 0x793A, 0x79BE, 0x7A74, 0x7ACB,
+ 0x4E1E, 0x4E1F, 0x4E52, 0x4E53, 0x4E69, 0x4E99, 0x4EA4, 0x4EA6,
+ 0x4EA5, 0x4EFF, 0x4F09, 0x4F19, 0x4F0A, 0x4F15, 0x4F0D, 0x4F10,
+ 0x4F11, 0x4F0F, 0x4EF2, 0x4EF6, 0x4EFB, 0x4EF0, 0x4EF3, 0x4EFD,
+ 0x4F01, 0x4F0B, 0x5149, 0x5147, 0x5146, 0x5148, 0x5168,
+ /* Big5-HKSCS 0xA640 .. 0xA67E */
+ 0x5171, 0x518D, 0x51B0, 0x5217, 0x5211, 0x5212, 0x520E, 0x5216,
+ 0x52A3, 0x5308, 0x5321, 0x5320, 0x5370, 0x5371, 0x5409, 0x540F,
+ 0x540C, 0x540A, 0x5410, 0x5401, 0x540B, 0x5404, 0x5411, 0x540D,
+ 0x5408, 0x5403, 0x540E, 0x5406, 0x5412, 0x56E0, 0x56DE, 0x56DD,
+ 0x5733, 0x5730, 0x5728, 0x572D, 0x572C, 0x572F, 0x5729, 0x5919,
+ 0x591A, 0x5937, 0x5938, 0x5984, 0x5978, 0x5983, 0x597D, 0x5979,
+ 0x5982, 0x5981, 0x5B57, 0x5B58, 0x5B87, 0x5B88, 0x5B85, 0x5B89,
+ 0x5BFA, 0x5C16, 0x5C79, 0x5DDE, 0x5E06, 0x5E76, 0x5E74,
+ /* Big5-HKSCS 0xA6A1 .. 0xA6FE */
+ 0x5F0F, 0x5F1B, 0x5FD9, 0x5FD6, 0x620E, 0x620C, 0x620D,
+ 0x6210, 0x6263, 0x625B, 0x6258, 0x6536, 0x65E9, 0x65E8, 0x65EC,
+ 0x65ED, 0x66F2, 0x66F3, 0x6709, 0x673D, 0x6734, 0x6731, 0x6735,
+ 0x6B21, 0x6B64, 0x6B7B, 0x6C16, 0x6C5D, 0x6C57, 0x6C59, 0x6C5F,
+ 0x6C60, 0x6C50, 0x6C55, 0x6C61, 0x6C5B, 0x6C4D, 0x6C4E, 0x7070,
+ 0x725F, 0x725D, 0x767E, 0x7AF9, 0x7C73, 0x7CF8, 0x7F36, 0x7F8A,
+ 0x7FBD, 0x8001, 0x8003, 0x800C, 0x8012, 0x8033, 0x807F, 0x8089,
+ 0x808B, 0x808C, 0x81E3, 0x81EA, 0x81F3, 0x81FC, 0x820C, 0x821B,
+ 0x821F, 0x826E, 0x8272, 0x827E, 0x866B, 0x8840, 0x884C, 0x8863,
+ 0x897F, 0x9621, 0x4E32, 0x4EA8, 0x4F4D, 0x4F4F, 0x4F47, 0x4F57,
+ 0x4F5E, 0x4F34, 0x4F5B, 0x4F55, 0x4F30, 0x4F50, 0x4F51, 0x4F3D,
+ 0x4F3A, 0x4F38, 0x4F43, 0x4F54, 0x4F3C, 0x4F46, 0x4F63,
+ /* Big5-HKSCS 0xA740 .. 0xA77E */
+ 0x4F5C, 0x4F60, 0x4F2F, 0x4F4E, 0x4F36, 0x4F59, 0x4F5D, 0x4F48,
+ 0x4F5A, 0x514C, 0x514B, 0x514D, 0x5175, 0x51B6, 0x51B7, 0x5225,
+ 0x5224, 0x5229, 0x522A, 0x5228, 0x52AB, 0x52A9, 0x52AA, 0x52AC,
+ 0x5323, 0x5373, 0x5375, 0x541D, 0x542D, 0x541E, 0x543E, 0x5426,
+ 0x544E, 0x5427, 0x5446, 0x5443, 0x5433, 0x5448, 0x5442, 0x541B,
+ 0x5429, 0x544A, 0x5439, 0x543B, 0x5438, 0x542E, 0x5435, 0x5436,
+ 0x5420, 0x543C, 0x5440, 0x5431, 0x542B, 0x541F, 0x542C, 0x56EA,
+ 0x56F0, 0x56E4, 0x56EB, 0x574A, 0x5751, 0x5740, 0x574D,
+ /* Big5-HKSCS 0xA7A1 .. 0xA7FE */
+ 0x5747, 0x574E, 0x573E, 0x5750, 0x574F, 0x573B, 0x58EF,
+ 0x593E, 0x599D, 0x5992, 0x59A8, 0x599E, 0x59A3, 0x5999, 0x5996,
+ 0x598D, 0x59A4, 0x5993, 0x598A, 0x59A5, 0x5B5D, 0x5B5C, 0x5B5A,
+ 0x5B5B, 0x5B8C, 0x5B8B, 0x5B8F, 0x5C2C, 0x5C40, 0x5C41, 0x5C3F,
+ 0x5C3E, 0x5C90, 0x5C91, 0x5C94, 0x5C8C, 0x5DEB, 0x5E0C, 0x5E8F,
+ 0x5E87, 0x5E8A, 0x5EF7, 0x5F04, 0x5F1F, 0x5F64, 0x5F62, 0x5F77,
+ 0x5F79, 0x5FD8, 0x5FCC, 0x5FD7, 0x5FCD, 0x5FF1, 0x5FEB, 0x5FF8,
+ 0x5FEA, 0x6212, 0x6211, 0x6284, 0x6297, 0x6296, 0x6280, 0x6276,
+ 0x6289, 0x626D, 0x628A, 0x627C, 0x627E, 0x6279, 0x6273, 0x6292,
+ 0x626F, 0x6298, 0x626E, 0x6295, 0x6293, 0x6291, 0x6286, 0x6539,
+ 0x653B, 0x6538, 0x65F1, 0x66F4, 0x675F, 0x674E, 0x674F, 0x6750,
+ 0x6751, 0x675C, 0x6756, 0x675E, 0x6749, 0x6746, 0x6760,
+ /* Big5-HKSCS 0xA840 .. 0xA87E */
+ 0x6753, 0x6757, 0x6B65, 0x6BCF, 0x6C42, 0x6C5E, 0x6C99, 0x6C81,
+ 0x6C88, 0x6C89, 0x6C85, 0x6C9B, 0x6C6A, 0x6C7A, 0x6C90, 0x6C70,
+ 0x6C8C, 0x6C68, 0x6C96, 0x6C92, 0x6C7D, 0x6C83, 0x6C72, 0x6C7E,
+ 0x6C74, 0x6C86, 0x6C76, 0x6C8D, 0x6C94, 0x6C98, 0x6C82, 0x7076,
+ 0x707C, 0x707D, 0x7078, 0x7262, 0x7261, 0x7260, 0x72C4, 0x72C2,
+ 0x7396, 0x752C, 0x752B, 0x7537, 0x7538, 0x7682, 0x76EF, 0x77E3,
+ 0x79C1, 0x79C0, 0x79BF, 0x7A76, 0x7CFB, 0x7F55, 0x8096, 0x8093,
+ 0x809D, 0x8098, 0x809B, 0x809A, 0x80B2, 0x826F, 0x8292,
+ /* Big5-HKSCS 0xA8A1 .. 0xA8FE */
+ 0x828B, 0x828D, 0x898B, 0x89D2, 0x8A00, 0x8C37, 0x8C46,
+ 0x8C55, 0x8C9D, 0x8D64, 0x8D70, 0x8DB3, 0x8EAB, 0x8ECA, 0x8F9B,
+ 0x8FB0, 0x8FC2, 0x8FC6, 0x8FC5, 0x8FC4, 0x5DE1, 0x9091, 0x90A2,
+ 0x90AA, 0x90A6, 0x90A3, 0x9149, 0x91C6, 0x91CC, 0x9632, 0x962E,
+ 0x9631, 0x962A, 0x962C, 0x4E26, 0x4E56, 0x4E73, 0x4E8B, 0x4E9B,
+ 0x4E9E, 0x4EAB, 0x4EAC, 0x4F6F, 0x4F9D, 0x4F8D, 0x4F73, 0x4F7F,
+ 0x4F6C, 0x4F9B, 0x4F8B, 0x4F86, 0x4F83, 0x4F70, 0x4F75, 0x4F88,
+ 0x4F69, 0x4F7B, 0x4F96, 0x4F7E, 0x4F8F, 0x4F91, 0x4F7A, 0x5154,
+ 0x5152, 0x5155, 0x5169, 0x5177, 0x5176, 0x5178, 0x51BD, 0x51FD,
+ 0x523B, 0x5238, 0x5237, 0x523A, 0x5230, 0x522E, 0x5236, 0x5241,
+ 0x52BE, 0x52BB, 0x5352, 0x5354, 0x5353, 0x5351, 0x5366, 0x5377,
+ 0x5378, 0x5379, 0x53D6, 0x53D4, 0x53D7, 0x5473, 0x5475,
+ /* Big5-HKSCS 0xA940 .. 0xA97E */
+ 0x5496, 0x5478, 0x5495, 0x5480, 0x547B, 0x5477, 0x5484, 0x5492,
+ 0x5486, 0x547C, 0x5490, 0x5471, 0x5476, 0x548C, 0x549A, 0x5462,
+ 0x5468, 0x548B, 0x547D, 0x548E, 0x56FA, 0x5783, 0x5777, 0x576A,
+ 0x5769, 0x5761, 0x5766, 0x5764, 0x577C, 0x591C, 0x5949, 0x5947,
+ 0x5948, 0x5944, 0x5954, 0x59BE, 0x59BB, 0x59D4, 0x59B9, 0x59AE,
+ 0x59D1, 0x59C6, 0x59D0, 0x59CD, 0x59CB, 0x59D3, 0x59CA, 0x59AF,
+ 0x59B3, 0x59D2, 0x59C5, 0x5B5F, 0x5B64, 0x5B63, 0x5B97, 0x5B9A,
+ 0x5B98, 0x5B9C, 0x5B99, 0x5B9B, 0x5C1A, 0x5C48, 0x5C45,
+ /* Big5-HKSCS 0xA9A1 .. 0xA9FE */
+ 0x5C46, 0x5CB7, 0x5CA1, 0x5CB8, 0x5CA9, 0x5CAB, 0x5CB1,
+ 0x5CB3, 0x5E18, 0x5E1A, 0x5E16, 0x5E15, 0x5E1B, 0x5E11, 0x5E78,
+ 0x5E9A, 0x5E97, 0x5E9C, 0x5E95, 0x5E96, 0x5EF6, 0x5F26, 0x5F27,
+ 0x5F29, 0x5F80, 0x5F81, 0x5F7F, 0x5F7C, 0x5FDD, 0x5FE0, 0x5FFD,
+ 0x5FF5, 0x5FFF, 0x600F, 0x6014, 0x602F, 0x6035, 0x6016, 0x602A,
+ 0x6015, 0x6021, 0x6027, 0x6029, 0x602B, 0x601B, 0x6216, 0x6215,
+ 0x623F, 0x623E, 0x6240, 0x627F, 0x62C9, 0x62CC, 0x62C4, 0x62BF,
+ 0x62C2, 0x62B9, 0x62D2, 0x62DB, 0x62AB, 0x62D3, 0x62D4, 0x62CB,
+ 0x62C8, 0x62A8, 0x62BD, 0x62BC, 0x62D0, 0x62D9, 0x62C7, 0x62CD,
+ 0x62B5, 0x62DA, 0x62B1, 0x62D8, 0x62D6, 0x62D7, 0x62C6, 0x62AC,
+ 0x62CE, 0x653E, 0x65A7, 0x65BC, 0x65FA, 0x6614, 0x6613, 0x660C,
+ 0x6606, 0x6602, 0x660E, 0x6600, 0x660F, 0x6615, 0x660A,
+ /* Big5-HKSCS 0xAA40 .. 0xAA7E */
+ 0x6607, 0x670D, 0x670B, 0x676D, 0x678B, 0x6795, 0x6771, 0x679C,
+ 0x6773, 0x6777, 0x6787, 0x679D, 0x6797, 0x676F, 0x6770, 0x677F,
+ 0x6789, 0x677E, 0x6790, 0x6775, 0x679A, 0x6793, 0x677C, 0x676A,
+ 0x6772, 0x6B23, 0x6B66, 0x6B67, 0x6B7F, 0x6C13, 0x6C1B, 0x6CE3,
+ 0x6CE8, 0x6CF3, 0x6CB1, 0x6CCC, 0x6CE5, 0x6CB3, 0x6CBD, 0x6CBE,
+ 0x6CBC, 0x6CE2, 0x6CAB, 0x6CD5, 0x6CD3, 0x6CB8, 0x6CC4, 0x6CB9,
+ 0x6CC1, 0x6CAE, 0x6CD7, 0x6CC5, 0x6CF1, 0x6CBF, 0x6CBB, 0x6CE1,
+ 0x6CDB, 0x6CCA, 0x6CAC, 0x6CEF, 0x6CDC, 0x6CD6, 0x6CE0,
+ /* Big5-HKSCS 0xAAA1 .. 0xAAFE */
+ 0x7095, 0x708E, 0x7092, 0x708A, 0x7099, 0x722C, 0x722D,
+ 0x7238, 0x7248, 0x7267, 0x7269, 0x72C0, 0x72CE, 0x72D9, 0x72D7,
+ 0x72D0, 0x73A9, 0x73A8, 0x739F, 0x73AB, 0x73A5, 0x753D, 0x759D,
+ 0x7599, 0x759A, 0x7684, 0x76C2, 0x76F2, 0x76F4, 0x77E5, 0x77FD,
+ 0x793E, 0x7940, 0x7941, 0x79C9, 0x79C8, 0x7A7A, 0x7A79, 0x7AFA,
+ 0x7CFE, 0x7F54, 0x7F8C, 0x7F8B, 0x8005, 0x80BA, 0x80A5, 0x80A2,
+ 0x80B1, 0x80A1, 0x80AB, 0x80A9, 0x80B4, 0x80AA, 0x80AF, 0x81E5,
+ 0x81FE, 0x820D, 0x82B3, 0x829D, 0x8299, 0x82AD, 0x82BD, 0x829F,
+ 0x82B9, 0x82B1, 0x82AC, 0x82A5, 0x82AF, 0x82B8, 0x82A3, 0x82B0,
+ 0x82BE, 0x82B7, 0x864E, 0x8671, 0x521D, 0x8868, 0x8ECB, 0x8FCE,
+ 0x8FD4, 0x8FD1, 0x90B5, 0x90B8, 0x90B1, 0x90B6, 0x91C7, 0x91D1,
+ 0x9577, 0x9580, 0x961C, 0x9640, 0x963F, 0x963B, 0x9644,
+ /* Big5-HKSCS 0xAB40 .. 0xAB7E */
+ 0x9642, 0x96B9, 0x96E8, 0x9752, 0x975E, 0x4E9F, 0x4EAD, 0x4EAE,
+ 0x4FE1, 0x4FB5, 0x4FAF, 0x4FBF, 0x4FE0, 0x4FD1, 0x4FCF, 0x4FDD,
+ 0x4FC3, 0x4FB6, 0x4FD8, 0x4FDF, 0x4FCA, 0x4FD7, 0x4FAE, 0x4FD0,
+ 0x4FC4, 0x4FC2, 0x4FDA, 0x4FCE, 0x4FDE, 0x4FB7, 0x5157, 0x5192,
+ 0x5191, 0x51A0, 0x524E, 0x5243, 0x524A, 0x524D, 0x524C, 0x524B,
+ 0x5247, 0x52C7, 0x52C9, 0x52C3, 0x52C1, 0x530D, 0x5357, 0x537B,
+ 0x539A, 0x53DB, 0x54AC, 0x54C0, 0x54A8, 0x54CE, 0x54C9, 0x54B8,
+ 0x54A6, 0x54B3, 0x54C7, 0x54C2, 0x54BD, 0x54AA, 0x54C1,
+ /* Big5-HKSCS 0xABA1 .. 0xABFE */
+ 0x54C4, 0x54C8, 0x54AF, 0x54AB, 0x54B1, 0x54BB, 0x54A9,
+ 0x54A7, 0x54BF, 0x56FF, 0x5782, 0x578B, 0x57A0, 0x57A3, 0x57A2,
+ 0x57CE, 0x57AE, 0x5793, 0x5955, 0x5951, 0x594F, 0x594E, 0x5950,
+ 0x59DC, 0x59D8, 0x59FF, 0x59E3, 0x59E8, 0x5A03, 0x59E5, 0x59EA,
+ 0x59DA, 0x59E6, 0x5A01, 0x59FB, 0x5B69, 0x5BA3, 0x5BA6, 0x5BA4,
+ 0x5BA2, 0x5BA5, 0x5C01, 0x5C4E, 0x5C4F, 0x5C4D, 0x5C4B, 0x5CD9,
+ 0x5CD2, 0x5DF7, 0x5E1D, 0x5E25, 0x5E1F, 0x5E7D, 0x5EA0, 0x5EA6,
+ 0x5EFA, 0x5F08, 0x5F2D, 0x5F65, 0x5F88, 0x5F85, 0x5F8A, 0x5F8B,
+ 0x5F87, 0x5F8C, 0x5F89, 0x6012, 0x601D, 0x6020, 0x6025, 0x600E,
+ 0x6028, 0x604D, 0x6070, 0x6068, 0x6062, 0x6046, 0x6043, 0x606C,
+ 0x606B, 0x606A, 0x6064, 0x6241, 0x62DC, 0x6316, 0x6309, 0x62FC,
+ 0x62ED, 0x6301, 0x62EE, 0x62FD, 0x6307, 0x62F1, 0x62F7,
+ /* Big5-HKSCS 0xAC40 .. 0xAC7E */
+ 0x62EF, 0x62EC, 0x62FE, 0x62F4, 0x6311, 0x6302, 0x653F, 0x6545,
+ 0x65AB, 0x65BD, 0x65E2, 0x6625, 0x662D, 0x6620, 0x6627, 0x662F,
+ 0x661F, 0x6628, 0x6631, 0x6624, 0x66F7, 0x67FF, 0x67D3, 0x67F1,
+ 0x67D4, 0x67D0, 0x67EC, 0x67B6, 0x67AF, 0x67F5, 0x67E9, 0x67EF,
+ 0x67C4, 0x67D1, 0x67B4, 0x67DA, 0x67E5, 0x67B8, 0x67CF, 0x67DE,
+ 0x67F3, 0x67B0, 0x67D9, 0x67E2, 0x67DD, 0x67D2, 0x6B6A, 0x6B83,
+ 0x6B86, 0x6BB5, 0x6BD2, 0x6BD7, 0x6C1F, 0x6CC9, 0x6D0B, 0x6D32,
+ 0x6D2A, 0x6D41, 0x6D25, 0x6D0C, 0x6D31, 0x6D1E, 0x6D17,
+ /* Big5-HKSCS 0xACA1 .. 0xACFE */
+ 0x6D3B, 0x6D3D, 0x6D3E, 0x6D36, 0x6D1B, 0x6CF5, 0x6D39,
+ 0x6D27, 0x6D38, 0x6D29, 0x6D2E, 0x6D35, 0x6D0E, 0x6D2B, 0x70AB,
+ 0x70BA, 0x70B3, 0x70AC, 0x70AF, 0x70AD, 0x70B8, 0x70AE, 0x70A4,
+ 0x7230, 0x7272, 0x726F, 0x7274, 0x72E9, 0x72E0, 0x72E1, 0x73B7,
+ 0x73CA, 0x73BB, 0x73B2, 0x73CD, 0x73C0, 0x73B3, 0x751A, 0x752D,
+ 0x754F, 0x754C, 0x754E, 0x754B, 0x75AB, 0x75A4, 0x75A5, 0x75A2,
+ 0x75A3, 0x7678, 0x7686, 0x7687, 0x7688, 0x76C8, 0x76C6, 0x76C3,
+ 0x76C5, 0x7701, 0x76F9, 0x76F8, 0x7709, 0x770B, 0x76FE, 0x76FC,
+ 0x7707, 0x77DC, 0x7802, 0x7814, 0x780C, 0x780D, 0x7946, 0x7949,
+ 0x7948, 0x7947, 0x79B9, 0x79BA, 0x79D1, 0x79D2, 0x79CB, 0x7A7F,
+ 0x7A81, 0x7AFF, 0x7AFD, 0x7C7D, 0x7D02, 0x7D05, 0x7D00, 0x7D09,
+ 0x7D07, 0x7D04, 0x7D06, 0x7F38, 0x7F8E, 0x7FBF, 0x8004,
+ /* Big5-HKSCS 0xAD40 .. 0xAD7E */
+ 0x8010, 0x800D, 0x8011, 0x8036, 0x80D6, 0x80E5, 0x80DA, 0x80C3,
+ 0x80C4, 0x80CC, 0x80E1, 0x80DB, 0x80CE, 0x80DE, 0x80E4, 0x80DD,
+ 0x81F4, 0x8222, 0x82E7, 0x8303, 0x8305, 0x82E3, 0x82DB, 0x82E6,
+ 0x8304, 0x82E5, 0x8302, 0x8309, 0x82D2, 0x82D7, 0x82F1, 0x8301,
+ 0x82DC, 0x82D4, 0x82D1, 0x82DE, 0x82D3, 0x82DF, 0x82EF, 0x8306,
+ 0x8650, 0x8679, 0x867B, 0x867A, 0x884D, 0x886B, 0x8981, 0x89D4,
+ 0x8A08, 0x8A02, 0x8A03, 0x8C9E, 0x8CA0, 0x8D74, 0x8D73, 0x8DB4,
+ 0x8ECD, 0x8ECC, 0x8FF0, 0x8FE6, 0x8FE2, 0x8FEA, 0x8FE5,
+ /* Big5-HKSCS 0xADA1 .. 0xADFE */
+ 0x8FED, 0x8FEB, 0x8FE4, 0x8FE8, 0x90CA, 0x90CE, 0x90C1,
+ 0x90C3, 0x914B, 0x914A, 0x91CD, 0x9582, 0x9650, 0x964B, 0x964C,
+ 0x964D, 0x9762, 0x9769, 0x97CB, 0x97ED, 0x97F3, 0x9801, 0x98A8,
+ 0x98DB, 0x98DF, 0x9996, 0x9999, 0x4E58, 0x4EB3, 0x500C, 0x500D,
+ 0x5023, 0x4FEF, 0x5026, 0x5025, 0x4FF8, 0x5029, 0x5016, 0x5006,
+ 0x503C, 0x501F, 0x501A, 0x5012, 0x5011, 0x4FFA, 0x5000, 0x5014,
+ 0x5028, 0x4FF1, 0x5021, 0x500B, 0x5019, 0x5018, 0x4FF3, 0x4FEE,
+ 0x502D, 0x502A, 0x4FFE, 0x502B, 0x5009, 0x517C, 0x51A4, 0x51A5,
+ 0x51A2, 0x51CD, 0x51CC, 0x51C6, 0x51CB, 0x5256, 0x525C, 0x5254,
+ 0x525B, 0x525D, 0x532A, 0x537F, 0x539F, 0x539D, 0x53DF, 0x54E8,
+ 0x5510, 0x5501, 0x5537, 0x54FC, 0x54E5, 0x54F2, 0x5506, 0x54FA,
+ 0x5514, 0x54E9, 0x54ED, 0x54E1, 0x5509, 0x54EE, 0x54EA,
+ /* Big5-HKSCS 0xAE40 .. 0xAE7E */
+ 0x54E6, 0x5527, 0x5507, 0x54FD, 0x550F, 0x5703, 0x5704, 0x57C2,
+ 0x57D4, 0x57CB, 0x57C3, 0x5809, 0x590F, 0x5957, 0x5958, 0x595A,
+ 0x5A11, 0x5A18, 0x5A1C, 0x5A1F, 0x5A1B, 0x5A13, 0x59EC, 0x5A20,
+ 0x5A23, 0x5A29, 0x5A25, 0x5A0C, 0x5A09, 0x5B6B, 0x5C58, 0x5BB0,
+ 0x5BB3, 0x5BB6, 0x5BB4, 0x5BAE, 0x5BB5, 0x5BB9, 0x5BB8, 0x5C04,
+ 0x5C51, 0x5C55, 0x5C50, 0x5CED, 0x5CFD, 0x5CFB, 0x5CEA, 0x5CE8,
+ 0x5CF0, 0x5CF6, 0x5D01, 0x5CF4, 0x5DEE, 0x5E2D, 0x5E2B, 0x5EAB,
+ 0x5EAD, 0x5EA7, 0x5F31, 0x5F92, 0x5F91, 0x5F90, 0x6059,
+ /* Big5-HKSCS 0xAEA1 .. 0xAEFE */
+ 0x6063, 0x6065, 0x6050, 0x6055, 0x606D, 0x6069, 0x606F,
+ 0x6084, 0x609F, 0x609A, 0x608D, 0x6094, 0x608C, 0x6085, 0x6096,
+ 0x6247, 0x62F3, 0x6308, 0x62FF, 0x634E, 0x633E, 0x632F, 0x6355,
+ 0x6342, 0x6346, 0x634F, 0x6349, 0x633A, 0x6350, 0x633D, 0x632A,
+ 0x632B, 0x6328, 0x634D, 0x634C, 0x6548, 0x6549, 0x6599, 0x65C1,
+ 0x65C5, 0x6642, 0x6649, 0x664F, 0x6643, 0x6652, 0x664C, 0x6645,
+ 0x6641, 0x66F8, 0x6714, 0x6715, 0x6717, 0x6821, 0x6838, 0x6848,
+ 0x6846, 0x6853, 0x6839, 0x6842, 0x6854, 0x6829, 0x68B3, 0x6817,
+ 0x684C, 0x6851, 0x683D, 0x67F4, 0x6850, 0x6840, 0x683C, 0x6843,
+ 0x682A, 0x6845, 0x6813, 0x6818, 0x6841, 0x6B8A, 0x6B89, 0x6BB7,
+ 0x6C23, 0x6C27, 0x6C28, 0x6C26, 0x6C24, 0x6CF0, 0x6D6A, 0x6D95,
+ 0x6D88, 0x6D87, 0x6D66, 0x6D78, 0x6D77, 0x6D59, 0x6D93,
+ /* Big5-HKSCS 0xAF40 .. 0xAF7E */
+ 0x6D6C, 0x6D89, 0x6D6E, 0x6D5A, 0x6D74, 0x6D69, 0x6D8C, 0x6D8A,
+ 0x6D79, 0x6D85, 0x6D65, 0x6D94, 0x70CA, 0x70D8, 0x70E4, 0x70D9,
+ 0x70C8, 0x70CF, 0x7239, 0x7279, 0x72FC, 0x72F9, 0x72FD, 0x72F8,
+ 0x72F7, 0x7386, 0x73ED, 0x7409, 0x73EE, 0x73E0, 0x73EA, 0x73DE,
+ 0x7554, 0x755D, 0x755C, 0x755A, 0x7559, 0x75BE, 0x75C5, 0x75C7,
+ 0x75B2, 0x75B3, 0x75BD, 0x75BC, 0x75B9, 0x75C2, 0x75B8, 0x768B,
+ 0x76B0, 0x76CA, 0x76CD, 0x76CE, 0x7729, 0x771F, 0x7720, 0x7728,
+ 0x77E9, 0x7830, 0x7827, 0x7838, 0x781D, 0x7834, 0x7837,
+ /* Big5-HKSCS 0xAFA1 .. 0xAFFE */
+ 0x7825, 0x782D, 0x7820, 0x781F, 0x7832, 0x7955, 0x7950,
+ 0x7960, 0x795F, 0x7956, 0x795E, 0x795D, 0x7957, 0x795A, 0x79E4,
+ 0x79E3, 0x79E7, 0x79DF, 0x79E6, 0x79E9, 0x79D8, 0x7A84, 0x7A88,
+ 0x7AD9, 0x7B06, 0x7B11, 0x7C89, 0x7D21, 0x7D17, 0x7D0B, 0x7D0A,
+ 0x7D20, 0x7D22, 0x7D14, 0x7D10, 0x7D15, 0x7D1A, 0x7D1C, 0x7D0D,
+ 0x7D19, 0x7D1B, 0x7F3A, 0x7F5F, 0x7F94, 0x7FC5, 0x7FC1, 0x8006,
+ 0x8018, 0x8015, 0x8019, 0x8017, 0x803D, 0x803F, 0x80F1, 0x8102,
+ 0x80F0, 0x8105, 0x80ED, 0x80F4, 0x8106, 0x80F8, 0x80F3, 0x8108,
+ 0x80FD, 0x810A, 0x80FC, 0x80EF, 0x81ED, 0x81EC, 0x8200, 0x8210,
+ 0x822A, 0x822B, 0x8228, 0x822C, 0x82BB, 0x832B, 0x8352, 0x8354,
+ 0x834A, 0x8338, 0x8350, 0x8349, 0x8335, 0x8334, 0x834F, 0x8332,
+ 0x8339, 0x8336, 0x8317, 0x8340, 0x8331, 0x8328, 0x8343,
+ /* Big5-HKSCS 0xB040 .. 0xB07E */
+ 0x8654, 0x868A, 0x86AA, 0x8693, 0x86A4, 0x86A9, 0x868C, 0x86A3,
+ 0x869C, 0x8870, 0x8877, 0x8881, 0x8882, 0x887D, 0x8879, 0x8A18,
+ 0x8A10, 0x8A0E, 0x8A0C, 0x8A15, 0x8A0A, 0x8A17, 0x8A13, 0x8A16,
+ 0x8A0F, 0x8A11, 0x8C48, 0x8C7A, 0x8C79, 0x8CA1, 0x8CA2, 0x8D77,
+ 0x8EAC, 0x8ED2, 0x8ED4, 0x8ECF, 0x8FB1, 0x9001, 0x9006, 0x8FF7,
+ 0x9000, 0x8FFA, 0x8FF4, 0x9003, 0x8FFD, 0x9005, 0x8FF8, 0x9095,
+ 0x90E1, 0x90DD, 0x90E2, 0x9152, 0x914D, 0x914C, 0x91D8, 0x91DD,
+ 0x91D7, 0x91DC, 0x91D9, 0x9583, 0x9662, 0x9663, 0x9661,
+ /* Big5-HKSCS 0xB0A1 .. 0xB0FE */
+ 0x965B, 0x965D, 0x9664, 0x9658, 0x965E, 0x96BB, 0x98E2,
+ 0x99AC, 0x9AA8, 0x9AD8, 0x9B25, 0x9B32, 0x9B3C, 0x4E7E, 0x507A,
+ 0x507D, 0x505C, 0x5047, 0x5043, 0x504C, 0x505A, 0x5049, 0x5065,
+ 0x5076, 0x504E, 0x5055, 0x5075, 0x5074, 0x5077, 0x504F, 0x500F,
+ 0x506F, 0x506D, 0x515C, 0x5195, 0x51F0, 0x526A, 0x526F, 0x52D2,
+ 0x52D9, 0x52D8, 0x52D5, 0x5310, 0x530F, 0x5319, 0x533F, 0x5340,
+ 0x533E, 0x53C3, 0x66FC, 0x5546, 0x556A, 0x5566, 0x5544, 0x555E,
+ 0x5561, 0x5543, 0x554A, 0x5531, 0x5556, 0x554F, 0x5555, 0x552F,
+ 0x5564, 0x5538, 0x552E, 0x555C, 0x552C, 0x5563, 0x5533, 0x5541,
+ 0x5557, 0x5708, 0x570B, 0x5709, 0x57DF, 0x5805, 0x580A, 0x5806,
+ 0x57E0, 0x57E4, 0x57FA, 0x5802, 0x5835, 0x57F7, 0x57F9, 0x5920,
+ 0x5962, 0x5A36, 0x5A41, 0x5A49, 0x5A66, 0x5A6A, 0x5A40,
+ /* Big5-HKSCS 0xB140 .. 0xB17E */
+ 0x5A3C, 0x5A62, 0x5A5A, 0x5A46, 0x5A4A, 0x5B70, 0x5BC7, 0x5BC5,
+ 0x5BC4, 0x5BC2, 0x5BBF, 0x5BC6, 0x5C09, 0x5C08, 0x5C07, 0x5C60,
+ 0x5C5C, 0x5C5D, 0x5D07, 0x5D06, 0x5D0E, 0x5D1B, 0x5D16, 0x5D22,
+ 0x5D11, 0x5D29, 0x5D14, 0x5D19, 0x5D24, 0x5D27, 0x5D17, 0x5DE2,
+ 0x5E38, 0x5E36, 0x5E33, 0x5E37, 0x5EB7, 0x5EB8, 0x5EB6, 0x5EB5,
+ 0x5EBE, 0x5F35, 0x5F37, 0x5F57, 0x5F6C, 0x5F69, 0x5F6B, 0x5F97,
+ 0x5F99, 0x5F9E, 0x5F98, 0x5FA1, 0x5FA0, 0x5F9C, 0x607F, 0x60A3,
+ 0x6089, 0x60A0, 0x60A8, 0x60CB, 0x60B4, 0x60E6, 0x60BD,
+ /* Big5-HKSCS 0xB1A1 .. 0xB1FE */
+ 0x60C5, 0x60BB, 0x60B5, 0x60DC, 0x60BC, 0x60D8, 0x60D5,
+ 0x60C6, 0x60DF, 0x60B8, 0x60DA, 0x60C7, 0x621A, 0x621B, 0x6248,
+ 0x63A0, 0x63A7, 0x6372, 0x6396, 0x63A2, 0x63A5, 0x6377, 0x6367,
+ 0x6398, 0x63AA, 0x6371, 0x63A9, 0x6389, 0x6383, 0x639B, 0x636B,
+ 0x63A8, 0x6384, 0x6388, 0x6399, 0x63A1, 0x63AC, 0x6392, 0x638F,
+ 0x6380, 0x637B, 0x6369, 0x6368, 0x637A, 0x655D, 0x6556, 0x6551,
+ 0x6559, 0x6557, 0x555F, 0x654F, 0x6558, 0x6555, 0x6554, 0x659C,
+ 0x659B, 0x65AC, 0x65CF, 0x65CB, 0x65CC, 0x65CE, 0x665D, 0x665A,
+ 0x6664, 0x6668, 0x6666, 0x665E, 0x66F9, 0x52D7, 0x671B, 0x6881,
+ 0x68AF, 0x68A2, 0x6893, 0x68B5, 0x687F, 0x6876, 0x68B1, 0x68A7,
+ 0x6897, 0x68B0, 0x6883, 0x68C4, 0x68AD, 0x6886, 0x6885, 0x6894,
+ 0x689D, 0x68A8, 0x689F, 0x68A1, 0x6882, 0x6B32, 0x6BBA,
+ /* Big5-HKSCS 0xB240 .. 0xB27E */
+ 0x6BEB, 0x6BEC, 0x6C2B, 0x6D8E, 0x6DBC, 0x6DF3, 0x6DD9, 0x6DB2,
+ 0x6DE1, 0x6DCC, 0x6DE4, 0x6DFB, 0x6DFA, 0x6E05, 0x6DC7, 0x6DCB,
+ 0x6DAF, 0x6DD1, 0x6DAE, 0x6DDE, 0x6DF9, 0x6DB8, 0x6DF7, 0x6DF5,
+ 0x6DC5, 0x6DD2, 0x6E1A, 0x6DB5, 0x6DDA, 0x6DEB, 0x6DD8, 0x6DEA,
+ 0x6DF1, 0x6DEE, 0x6DE8, 0x6DC6, 0x6DC4, 0x6DAA, 0x6DEC, 0x6DBF,
+ 0x6DE6, 0x70F9, 0x7109, 0x710A, 0x70FD, 0x70EF, 0x723D, 0x727D,
+ 0x7281, 0x731C, 0x731B, 0x7316, 0x7313, 0x7319, 0x7387, 0x7405,
+ 0x740A, 0x7403, 0x7406, 0x73FE, 0x740D, 0x74E0, 0x74F6,
+ /* Big5-HKSCS 0xB2A1 .. 0xB2FE */
+ 0x74F7, 0x751C, 0x7522, 0x7565, 0x7566, 0x7562, 0x7570,
+ 0x758F, 0x75D4, 0x75D5, 0x75B5, 0x75CA, 0x75CD, 0x768E, 0x76D4,
+ 0x76D2, 0x76DB, 0x7737, 0x773E, 0x773C, 0x7736, 0x7738, 0x773A,
+ 0x786B, 0x7843, 0x784E, 0x7965, 0x7968, 0x796D, 0x79FB, 0x7A92,
+ 0x7A95, 0x7B20, 0x7B28, 0x7B1B, 0x7B2C, 0x7B26, 0x7B19, 0x7B1E,
+ 0x7B2E, 0x7C92, 0x7C97, 0x7C95, 0x7D46, 0x7D43, 0x7D71, 0x7D2E,
+ 0x7D39, 0x7D3C, 0x7D40, 0x7D30, 0x7D33, 0x7D44, 0x7D2F, 0x7D42,
+ 0x7D32, 0x7D31, 0x7F3D, 0x7F9E, 0x7F9A, 0x7FCC, 0x7FCE, 0x7FD2,
+ 0x801C, 0x804A, 0x8046, 0x812F, 0x8116, 0x8123, 0x812B, 0x8129,
+ 0x8130, 0x8124, 0x8202, 0x8235, 0x8237, 0x8236, 0x8239, 0x838E,
+ 0x839E, 0x8398, 0x8378, 0x83A2, 0x8396, 0x83BD, 0x83AB, 0x8392,
+ 0x838A, 0x8393, 0x8389, 0x83A0, 0x8377, 0x837B, 0x837C,
+ /* Big5-HKSCS 0xB340 .. 0xB37E */
+ 0x8386, 0x83A7, 0x8655, 0x5F6A, 0x86C7, 0x86C0, 0x86B6, 0x86C4,
+ 0x86B5, 0x86C6, 0x86CB, 0x86B1, 0x86AF, 0x86C9, 0x8853, 0x889E,
+ 0x8888, 0x88AB, 0x8892, 0x8896, 0x888D, 0x888B, 0x8993, 0x898F,
+ 0x8A2A, 0x8A1D, 0x8A23, 0x8A25, 0x8A31, 0x8A2D, 0x8A1F, 0x8A1B,
+ 0x8A22, 0x8C49, 0x8C5A, 0x8CA9, 0x8CAC, 0x8CAB, 0x8CA8, 0x8CAA,
+ 0x8CA7, 0x8D67, 0x8D66, 0x8DBE, 0x8DBA, 0x8EDB, 0x8EDF, 0x9019,
+ 0x900D, 0x901A, 0x9017, 0x9023, 0x901F, 0x901D, 0x9010, 0x9015,
+ 0x901E, 0x9020, 0x900F, 0x9022, 0x9016, 0x901B, 0x9014,
+ /* Big5-HKSCS 0xB3A1 .. 0xB3FE */
+ 0x90E8, 0x90ED, 0x90FD, 0x9157, 0x91CE, 0x91F5, 0x91E6,
+ 0x91E3, 0x91E7, 0x91ED, 0x91E9, 0x9589, 0x966A, 0x9675, 0x9673,
+ 0x9678, 0x9670, 0x9674, 0x9676, 0x9677, 0x966C, 0x96C0, 0x96EA,
+ 0x96E9, 0x7AE0, 0x7ADF, 0x9802, 0x9803, 0x9B5A, 0x9CE5, 0x9E75,
+ 0x9E7F, 0x9EA5, 0x9EBB, 0x50A2, 0x508D, 0x5085, 0x5099, 0x5091,
+ 0x5080, 0x5096, 0x5098, 0x509A, 0x6700, 0x51F1, 0x5272, 0x5274,
+ 0x5275, 0x5269, 0x52DE, 0x52DD, 0x52DB, 0x535A, 0x53A5, 0x557B,
+ 0x5580, 0x55A7, 0x557C, 0x558A, 0x559D, 0x5598, 0x5582, 0x559C,
+ 0x55AA, 0x5594, 0x5587, 0x558B, 0x5583, 0x55B3, 0x55AE, 0x559F,
+ 0x553E, 0x55B2, 0x559A, 0x55BB, 0x55AC, 0x55B1, 0x557E, 0x5589,
+ 0x55AB, 0x5599, 0x570D, 0x582F, 0x582A, 0x5834, 0x5824, 0x5830,
+ 0x5831, 0x5821, 0x581D, 0x5820, 0x58F9, 0x58FA, 0x5960,
+ /* Big5-HKSCS 0xB440 .. 0xB47E */
+ 0x5A77, 0x5A9A, 0x5A7F, 0x5A92, 0x5A9B, 0x5AA7, 0x5B73, 0x5B71,
+ 0x5BD2, 0x5BCC, 0x5BD3, 0x5BD0, 0x5C0A, 0x5C0B, 0x5C31, 0x5D4C,
+ 0x5D50, 0x5D34, 0x5D47, 0x5DFD, 0x5E45, 0x5E3D, 0x5E40, 0x5E43,
+ 0x5E7E, 0x5ECA, 0x5EC1, 0x5EC2, 0x5EC4, 0x5F3C, 0x5F6D, 0x5FA9,
+ 0x5FAA, 0x5FA8, 0x60D1, 0x60E1, 0x60B2, 0x60B6, 0x60E0, 0x611C,
+ 0x6123, 0x60FA, 0x6115, 0x60F0, 0x60FB, 0x60F4, 0x6168, 0x60F1,
+ 0x610E, 0x60F6, 0x6109, 0x6100, 0x6112, 0x621F, 0x6249, 0x63A3,
+ 0x638C, 0x63CF, 0x63C0, 0x63E9, 0x63C9, 0x63C6, 0x63CD,
+ /* Big5-HKSCS 0xB4A1 .. 0xB4FE */
+ 0x63D2, 0x63E3, 0x63D0, 0x63E1, 0x63D6, 0x63ED, 0x63EE,
+ 0x6376, 0x63F4, 0x63EA, 0x63DB, 0x6452, 0x63DA, 0x63F9, 0x655E,
+ 0x6566, 0x6562, 0x6563, 0x6591, 0x6590, 0x65AF, 0x666E, 0x6670,
+ 0x6674, 0x6676, 0x666F, 0x6691, 0x667A, 0x667E, 0x6677, 0x66FE,
+ 0x66FF, 0x671F, 0x671D, 0x68FA, 0x68D5, 0x68E0, 0x68D8, 0x68D7,
+ 0x6905, 0x68DF, 0x68F5, 0x68EE, 0x68E7, 0x68F9, 0x68D2, 0x68F2,
+ 0x68E3, 0x68CB, 0x68CD, 0x690D, 0x6912, 0x690E, 0x68C9, 0x68DA,
+ 0x696E, 0x68FB, 0x6B3E, 0x6B3A, 0x6B3D, 0x6B98, 0x6B96, 0x6BBC,
+ 0x6BEF, 0x6C2E, 0x6C2F, 0x6C2C, 0x6E2F, 0x6E38, 0x6E54, 0x6E21,
+ 0x6E32, 0x6E67, 0x6E4A, 0x6E20, 0x6E25, 0x6E23, 0x6E1B, 0x6E5B,
+ 0x6E58, 0x6E24, 0x6E56, 0x6E6E, 0x6E2D, 0x6E26, 0x6E6F, 0x6E34,
+ 0x6E4D, 0x6E3A, 0x6E2C, 0x6E43, 0x6E1D, 0x6E3E, 0x6ECB,
+ /* Big5-HKSCS 0xB540 .. 0xB57E */
+ 0x6E89, 0x6E19, 0x6E4E, 0x6E63, 0x6E44, 0x6E72, 0x6E69, 0x6E5F,
+ 0x7119, 0x711A, 0x7126, 0x7130, 0x7121, 0x7136, 0x716E, 0x711C,
+ 0x724C, 0x7284, 0x7280, 0x7336, 0x7325, 0x7334, 0x7329, 0x743A,
+ 0x742A, 0x7433, 0x7422, 0x7425, 0x7435, 0x7436, 0x7434, 0x742F,
+ 0x741B, 0x7426, 0x7428, 0x7525, 0x7526, 0x756B, 0x756A, 0x75E2,
+ 0x75DB, 0x75E3, 0x75D9, 0x75D8, 0x75DE, 0x75E0, 0x767B, 0x767C,
+ 0x7696, 0x7693, 0x76B4, 0x76DC, 0x774F, 0x77ED, 0x785D, 0x786C,
+ 0x786F, 0x7A0D, 0x7A08, 0x7A0B, 0x7A05, 0x7A00, 0x7A98,
+ /* Big5-HKSCS 0xB5A1 .. 0xB5FE */
+ 0x7A97, 0x7A96, 0x7AE5, 0x7AE3, 0x7B49, 0x7B56, 0x7B46,
+ 0x7B50, 0x7B52, 0x7B54, 0x7B4D, 0x7B4B, 0x7B4F, 0x7B51, 0x7C9F,
+ 0x7CA5, 0x7D5E, 0x7D50, 0x7D68, 0x7D55, 0x7D2B, 0x7D6E, 0x7D72,
+ 0x7D61, 0x7D66, 0x7D62, 0x7D70, 0x7D73, 0x5584, 0x7FD4, 0x7FD5,
+ 0x800B, 0x8052, 0x8085, 0x8155, 0x8154, 0x814B, 0x8151, 0x814E,
+ 0x8139, 0x8146, 0x813E, 0x814C, 0x8153, 0x8174, 0x8212, 0x821C,
+ 0x83E9, 0x8403, 0x83F8, 0x840D, 0x83E0, 0x83C5, 0x840B, 0x83C1,
+ 0x83EF, 0x83F1, 0x83F4, 0x8457, 0x840A, 0x83F0, 0x840C, 0x83CC,
+ 0x83FD, 0x83F2, 0x83CA, 0x8438, 0x840E, 0x8404, 0x83DC, 0x8407,
+ 0x83D4, 0x83DF, 0x865B, 0x86DF, 0x86D9, 0x86ED, 0x86D4, 0x86DB,
+ 0x86E4, 0x86D0, 0x86DE, 0x8857, 0x88C1, 0x88C2, 0x88B1, 0x8983,
+ 0x8996, 0x8A3B, 0x8A60, 0x8A55, 0x8A5E, 0x8A3C, 0x8A41,
+ /* Big5-HKSCS 0xB640 .. 0xB67E */
+ 0x8A54, 0x8A5B, 0x8A50, 0x8A46, 0x8A34, 0x8A3A, 0x8A36, 0x8A56,
+ 0x8C61, 0x8C82, 0x8CAF, 0x8CBC, 0x8CB3, 0x8CBD, 0x8CC1, 0x8CBB,
+ 0x8CC0, 0x8CB4, 0x8CB7, 0x8CB6, 0x8CBF, 0x8CB8, 0x8D8A, 0x8D85,
+ 0x8D81, 0x8DCE, 0x8DDD, 0x8DCB, 0x8DDA, 0x8DD1, 0x8DCC, 0x8DDB,
+ 0x8DC6, 0x8EFB, 0x8EF8, 0x8EFC, 0x8F9C, 0x902E, 0x9035, 0x9031,
+ 0x9038, 0x9032, 0x9036, 0x9102, 0x90F5, 0x9109, 0x90FE, 0x9163,
+ 0x9165, 0x91CF, 0x9214, 0x9215, 0x9223, 0x9209, 0x921E, 0x920D,
+ 0x9210, 0x9207, 0x9211, 0x9594, 0x958F, 0x958B, 0x9591,
+ /* Big5-HKSCS 0xB6A1 .. 0xB6FE */
+ 0x9593, 0x9592, 0x958E, 0x968A, 0x968E, 0x968B, 0x967D,
+ 0x9685, 0x9686, 0x968D, 0x9672, 0x9684, 0x96C1, 0x96C5, 0x96C4,
+ 0x96C6, 0x96C7, 0x96EF, 0x96F2, 0x97CC, 0x9805, 0x9806, 0x9808,
+ 0x98E7, 0x98EA, 0x98EF, 0x98E9, 0x98F2, 0x98ED, 0x99AE, 0x99AD,
+ 0x9EC3, 0x9ECD, 0x9ED1, 0x4E82, 0x50AD, 0x50B5, 0x50B2, 0x50B3,
+ 0x50C5, 0x50BE, 0x50AC, 0x50B7, 0x50BB, 0x50AF, 0x50C7, 0x527F,
+ 0x5277, 0x527D, 0x52DF, 0x52E6, 0x52E4, 0x52E2, 0x52E3, 0x532F,
+ 0x55DF, 0x55E8, 0x55D3, 0x55E6, 0x55CE, 0x55DC, 0x55C7, 0x55D1,
+ 0x55E3, 0x55E4, 0x55EF, 0x55DA, 0x55E1, 0x55C5, 0x55C6, 0x55E5,
+ 0x55C9, 0x5712, 0x5713, 0x585E, 0x5851, 0x5858, 0x5857, 0x585A,
+ 0x5854, 0x586B, 0x584C, 0x586D, 0x584A, 0x5862, 0x5852, 0x584B,
+ 0x5967, 0x5AC1, 0x5AC9, 0x5ACC, 0x5ABE, 0x5ABD, 0x5ABC,
+ /* Big5-HKSCS 0xB740 .. 0xB77E */
+ 0x5AB3, 0x5AC2, 0x5AB2, 0x5D69, 0x5D6F, 0x5E4C, 0x5E79, 0x5EC9,
+ 0x5EC8, 0x5F12, 0x5F59, 0x5FAC, 0x5FAE, 0x611A, 0x610F, 0x6148,
+ 0x611F, 0x60F3, 0x611B, 0x60F9, 0x6101, 0x6108, 0x614E, 0x614C,
+ 0x6144, 0x614D, 0x613E, 0x6134, 0x6127, 0x610D, 0x6106, 0x6137,
+ 0x6221, 0x6222, 0x6413, 0x643E, 0x641E, 0x642A, 0x642D, 0x643D,
+ 0x642C, 0x640F, 0x641C, 0x6414, 0x640D, 0x6436, 0x6416, 0x6417,
+ 0x6406, 0x656C, 0x659F, 0x65B0, 0x6697, 0x6689, 0x6687, 0x6688,
+ 0x6696, 0x6684, 0x6698, 0x668D, 0x6703, 0x6994, 0x696D,
+ /* Big5-HKSCS 0xB7A1 .. 0xB7FE */
+ 0x695A, 0x6977, 0x6960, 0x6954, 0x6975, 0x6930, 0x6982,
+ 0x694A, 0x6968, 0x696B, 0x695E, 0x6953, 0x6979, 0x6986, 0x695D,
+ 0x6963, 0x695B, 0x6B47, 0x6B72, 0x6BC0, 0x6BBF, 0x6BD3, 0x6BFD,
+ 0x6EA2, 0x6EAF, 0x6ED3, 0x6EB6, 0x6EC2, 0x6E90, 0x6E9D, 0x6EC7,
+ 0x6EC5, 0x6EA5, 0x6E98, 0x6EBC, 0x6EBA, 0x6EAB, 0x6ED1, 0x6E96,
+ 0x6E9C, 0x6EC4, 0x6ED4, 0x6EAA, 0x6EA7, 0x6EB4, 0x714E, 0x7159,
+ 0x7169, 0x7164, 0x7149, 0x7167, 0x715C, 0x716C, 0x7166, 0x714C,
+ 0x7165, 0x715E, 0x7146, 0x7168, 0x7156, 0x723A, 0x7252, 0x7337,
+ 0x7345, 0x733F, 0x733E, 0x746F, 0x745A, 0x7455, 0x745F, 0x745E,
+ 0x7441, 0x743F, 0x7459, 0x745B, 0x745C, 0x7576, 0x7578, 0x7600,
+ 0x75F0, 0x7601, 0x75F2, 0x75F1, 0x75FA, 0x75FF, 0x75F4, 0x75F3,
+ 0x76DE, 0x76DF, 0x775B, 0x776B, 0x7766, 0x775E, 0x7763,
+ /* Big5-HKSCS 0xB840 .. 0xB87E */
+ 0x7779, 0x776A, 0x776C, 0x775C, 0x7765, 0x7768, 0x7762, 0x77EE,
+ 0x788E, 0x78B0, 0x7897, 0x7898, 0x788C, 0x7889, 0x787C, 0x7891,
+ 0x7893, 0x787F, 0x797A, 0x797F, 0x7981, 0x842C, 0x79BD, 0x7A1C,
+ 0x7A1A, 0x7A20, 0x7A14, 0x7A1F, 0x7A1E, 0x7A9F, 0x7AA0, 0x7B77,
+ 0x7BC0, 0x7B60, 0x7B6E, 0x7B67, 0x7CB1, 0x7CB3, 0x7CB5, 0x7D93,
+ 0x7D79, 0x7D91, 0x7D81, 0x7D8F, 0x7D5B, 0x7F6E, 0x7F69, 0x7F6A,
+ 0x7F72, 0x7FA9, 0x7FA8, 0x7FA4, 0x8056, 0x8058, 0x8086, 0x8084,
+ 0x8171, 0x8170, 0x8178, 0x8165, 0x816E, 0x8173, 0x816B,
+ /* Big5-HKSCS 0xB8A1 .. 0xB8FE */
+ 0x8179, 0x817A, 0x8166, 0x8205, 0x8247, 0x8482, 0x8477,
+ 0x843D, 0x8431, 0x8475, 0x8466, 0x846B, 0x8449, 0x846C, 0x845B,
+ 0x843C, 0x8435, 0x8461, 0x8463, 0x8469, 0x846D, 0x8446, 0x865E,
+ 0x865C, 0x865F, 0x86F9, 0x8713, 0x8708, 0x8707, 0x8700, 0x86FE,
+ 0x86FB, 0x8702, 0x8703, 0x8706, 0x870A, 0x8859, 0x88DF, 0x88D4,
+ 0x88D9, 0x88DC, 0x88D8, 0x88DD, 0x88E1, 0x88CA, 0x88D5, 0x88D2,
+ 0x899C, 0x89E3, 0x8A6B, 0x8A72, 0x8A73, 0x8A66, 0x8A69, 0x8A70,
+ 0x8A87, 0x8A7C, 0x8A63, 0x8AA0, 0x8A71, 0x8A85, 0x8A6D, 0x8A62,
+ 0x8A6E, 0x8A6C, 0x8A79, 0x8A7B, 0x8A3E, 0x8A68, 0x8C62, 0x8C8A,
+ 0x8C89, 0x8CCA, 0x8CC7, 0x8CC8, 0x8CC4, 0x8CB2, 0x8CC3, 0x8CC2,
+ 0x8CC5, 0x8DE1, 0x8DDF, 0x8DE8, 0x8DEF, 0x8DF3, 0x8DFA, 0x8DEA,
+ 0x8DE4, 0x8DE6, 0x8EB2, 0x8F03, 0x8F09, 0x8EFE, 0x8F0A,
+ /* Big5-HKSCS 0xB940 .. 0xB97E */
+ 0x8F9F, 0x8FB2, 0x904B, 0x904A, 0x9053, 0x9042, 0x9054, 0x903C,
+ 0x9055, 0x9050, 0x9047, 0x904F, 0x904E, 0x904D, 0x9051, 0x903E,
+ 0x9041, 0x9112, 0x9117, 0x916C, 0x916A, 0x9169, 0x91C9, 0x9237,
+ 0x9257, 0x9238, 0x923D, 0x9240, 0x923E, 0x925B, 0x924B, 0x9264,
+ 0x9251, 0x9234, 0x9249, 0x924D, 0x9245, 0x9239, 0x923F, 0x925A,
+ 0x9598, 0x9698, 0x9694, 0x9695, 0x96CD, 0x96CB, 0x96C9, 0x96CA,
+ 0x96F7, 0x96FB, 0x96F9, 0x96F6, 0x9756, 0x9774, 0x9776, 0x9810,
+ 0x9811, 0x9813, 0x980A, 0x9812, 0x980C, 0x98FC, 0x98F4,
+ /* Big5-HKSCS 0xB9A1 .. 0xB9FE */
+ 0x98FD, 0x98FE, 0x99B3, 0x99B1, 0x99B4, 0x9AE1, 0x9CE9,
+ 0x9E82, 0x9F0E, 0x9F13, 0x9F20, 0x50E7, 0x50EE, 0x50E5, 0x50D6,
+ 0x50ED, 0x50DA, 0x50D5, 0x50CF, 0x50D1, 0x50F1, 0x50CE, 0x50E9,
+ 0x5162, 0x51F3, 0x5283, 0x5282, 0x5331, 0x53AD, 0x55FE, 0x5600,
+ 0x561B, 0x5617, 0x55FD, 0x5614, 0x5606, 0x5609, 0x560D, 0x560E,
+ 0x55F7, 0x5616, 0x561F, 0x5608, 0x5610, 0x55F6, 0x5718, 0x5716,
+ 0x5875, 0x587E, 0x5883, 0x5893, 0x588A, 0x5879, 0x5885, 0x587D,
+ 0x58FD, 0x5925, 0x5922, 0x5924, 0x596A, 0x5969, 0x5AE1, 0x5AE6,
+ 0x5AE9, 0x5AD7, 0x5AD6, 0x5AD8, 0x5AE3, 0x5B75, 0x5BDE, 0x5BE7,
+ 0x5BE1, 0x5BE5, 0x5BE6, 0x5BE8, 0x5BE2, 0x5BE4, 0x5BDF, 0x5C0D,
+ 0x5C62, 0x5D84, 0x5D87, 0x5E5B, 0x5E63, 0x5E55, 0x5E57, 0x5E54,
+ 0x5ED3, 0x5ED6, 0x5F0A, 0x5F46, 0x5F70, 0x5FB9, 0x6147,
+ /* Big5-HKSCS 0xBA40 .. 0xBA7E */
+ 0x613F, 0x614B, 0x6177, 0x6162, 0x6163, 0x615F, 0x615A, 0x6158,
+ 0x6175, 0x622A, 0x6487, 0x6458, 0x6454, 0x64A4, 0x6478, 0x645F,
+ 0x647A, 0x6451, 0x6467, 0x6434, 0x646D, 0x647B, 0x6572, 0x65A1,
+ 0x65D7, 0x65D6, 0x66A2, 0x66A8, 0x669D, 0x699C, 0x69A8, 0x6995,
+ 0x69C1, 0x69AE, 0x69D3, 0x69CB, 0x699B, 0x69B7, 0x69BB, 0x69AB,
+ 0x69B4, 0x69D0, 0x69CD, 0x69AD, 0x69CC, 0x69A6, 0x69C3, 0x69A3,
+ 0x6B49, 0x6B4C, 0x6C33, 0x6F33, 0x6F14, 0x6EFE, 0x6F13, 0x6EF4,
+ 0x6F29, 0x6F3E, 0x6F20, 0x6F2C, 0x6F0F, 0x6F02, 0x6F22,
+ /* Big5-HKSCS 0xBAA1 .. 0xBAFE */
+ 0x6EFF, 0x6EEF, 0x6F06, 0x6F31, 0x6F38, 0x6F32, 0x6F23,
+ 0x6F15, 0x6F2B, 0x6F2F, 0x6F88, 0x6F2A, 0x6EEC, 0x6F01, 0x6EF2,
+ 0x6ECC, 0x6EF7, 0x7194, 0x7199, 0x717D, 0x718A, 0x7184, 0x7192,
+ 0x723E, 0x7292, 0x7296, 0x7344, 0x7350, 0x7464, 0x7463, 0x746A,
+ 0x7470, 0x746D, 0x7504, 0x7591, 0x7627, 0x760D, 0x760B, 0x7609,
+ 0x7613, 0x76E1, 0x76E3, 0x7784, 0x777D, 0x777F, 0x7761, 0x78C1,
+ 0x789F, 0x78A7, 0x78B3, 0x78A9, 0x78A3, 0x798E, 0x798F, 0x798D,
+ 0x7A2E, 0x7A31, 0x7AAA, 0x7AA9, 0x7AED, 0x7AEF, 0x7BA1, 0x7B95,
+ 0x7B8B, 0x7B75, 0x7B97, 0x7B9D, 0x7B94, 0x7B8F, 0x7BB8, 0x7B87,
+ 0x7B84, 0x7CB9, 0x7CBD, 0x7CBE, 0x7DBB, 0x7DB0, 0x7D9C, 0x7DBD,
+ 0x7DBE, 0x7DA0, 0x7DCA, 0x7DB4, 0x7DB2, 0x7DB1, 0x7DBA, 0x7DA2,
+ 0x7DBF, 0x7DB5, 0x7DB8, 0x7DAD, 0x7DD2, 0x7DC7, 0x7DAC,
+ /* Big5-HKSCS 0xBB40 .. 0xBB7E */
+ 0x7F70, 0x7FE0, 0x7FE1, 0x7FDF, 0x805E, 0x805A, 0x8087, 0x8150,
+ 0x8180, 0x818F, 0x8188, 0x818A, 0x817F, 0x8182, 0x81E7, 0x81FA,
+ 0x8207, 0x8214, 0x821E, 0x824B, 0x84C9, 0x84BF, 0x84C6, 0x84C4,
+ 0x8499, 0x849E, 0x84B2, 0x849C, 0x84CB, 0x84B8, 0x84C0, 0x84D3,
+ 0x8490, 0x84BC, 0x84D1, 0x84CA, 0x873F, 0x871C, 0x873B, 0x8722,
+ 0x8725, 0x8734, 0x8718, 0x8755, 0x8737, 0x8729, 0x88F3, 0x8902,
+ 0x88F4, 0x88F9, 0x88F8, 0x88FD, 0x88E8, 0x891A, 0x88EF, 0x8AA6,
+ 0x8A8C, 0x8A9E, 0x8AA3, 0x8A8D, 0x8AA1, 0x8A93, 0x8AA4,
+ /* Big5-HKSCS 0xBBA1 .. 0xBBFE */
+ 0x8AAA, 0x8AA5, 0x8AA8, 0x8A98, 0x8A91, 0x8A9A, 0x8AA7,
+ 0x8C6A, 0x8C8D, 0x8C8C, 0x8CD3, 0x8CD1, 0x8CD2, 0x8D6B, 0x8D99,
+ 0x8D95, 0x8DFC, 0x8F14, 0x8F12, 0x8F15, 0x8F13, 0x8FA3, 0x9060,
+ 0x9058, 0x905C, 0x9063, 0x9059, 0x905E, 0x9062, 0x905D, 0x905B,
+ 0x9119, 0x9118, 0x911E, 0x9175, 0x9178, 0x9177, 0x9174, 0x9278,
+ 0x9280, 0x9285, 0x9298, 0x9296, 0x927B, 0x9293, 0x929C, 0x92A8,
+ 0x927C, 0x9291, 0x95A1, 0x95A8, 0x95A9, 0x95A3, 0x95A5, 0x95A4,
+ 0x9699, 0x969C, 0x969B, 0x96CC, 0x96D2, 0x9700, 0x977C, 0x9785,
+ 0x97F6, 0x9817, 0x9818, 0x98AF, 0x98B1, 0x9903, 0x9905, 0x990C,
+ 0x9909, 0x99C1, 0x9AAF, 0x9AB0, 0x9AE6, 0x9B41, 0x9B42, 0x9CF4,
+ 0x9CF6, 0x9CF3, 0x9EBC, 0x9F3B, 0x9F4A, 0x5104, 0x5100, 0x50FB,
+ 0x50F5, 0x50F9, 0x5102, 0x5108, 0x5109, 0x5105, 0x51DC,
+ /* Big5-HKSCS 0xBC40 .. 0xBC7E */
+ 0x5287, 0x5288, 0x5289, 0x528D, 0x528A, 0x52F0, 0x53B2, 0x562E,
+ 0x563B, 0x5639, 0x5632, 0x563F, 0x5634, 0x5629, 0x5653, 0x564E,
+ 0x5657, 0x5674, 0x5636, 0x562F, 0x5630, 0x5880, 0x589F, 0x589E,
+ 0x58B3, 0x589C, 0x58AE, 0x58A9, 0x58A6, 0x596D, 0x5B09, 0x5AFB,
+ 0x5B0B, 0x5AF5, 0x5B0C, 0x5B08, 0x5BEE, 0x5BEC, 0x5BE9, 0x5BEB,
+ 0x5C64, 0x5C65, 0x5D9D, 0x5D94, 0x5E62, 0x5E5F, 0x5E61, 0x5EE2,
+ 0x5EDA, 0x5EDF, 0x5EDD, 0x5EE3, 0x5EE0, 0x5F48, 0x5F71, 0x5FB7,
+ 0x5FB5, 0x6176, 0x6167, 0x616E, 0x615D, 0x6155, 0x6182,
+ /* Big5-HKSCS 0xBCA1 .. 0xBCFE */
+ 0x617C, 0x6170, 0x616B, 0x617E, 0x61A7, 0x6190, 0x61AB,
+ 0x618E, 0x61AC, 0x619A, 0x61A4, 0x6194, 0x61AE, 0x622E, 0x6469,
+ 0x646F, 0x6479, 0x649E, 0x64B2, 0x6488, 0x6490, 0x64B0, 0x64A5,
+ 0x6493, 0x6495, 0x64A9, 0x6492, 0x64AE, 0x64AD, 0x64AB, 0x649A,
+ 0x64AC, 0x6499, 0x64A2, 0x64B3, 0x6575, 0x6577, 0x6578, 0x66AE,
+ 0x66AB, 0x66B4, 0x66B1, 0x6A23, 0x6A1F, 0x69E8, 0x6A01, 0x6A1E,
+ 0x6A19, 0x69FD, 0x6A21, 0x6A13, 0x6A0A, 0x69F3, 0x6A02, 0x6A05,
+ 0x69ED, 0x6A11, 0x6B50, 0x6B4E, 0x6BA4, 0x6BC5, 0x6BC6, 0x6F3F,
+ 0x6F7C, 0x6F84, 0x6F51, 0x6F66, 0x6F54, 0x6F86, 0x6F6D, 0x6F5B,
+ 0x6F78, 0x6F6E, 0x6F8E, 0x6F7A, 0x6F70, 0x6F64, 0x6F97, 0x6F58,
+ 0x6ED5, 0x6F6F, 0x6F60, 0x6F5F, 0x719F, 0x71AC, 0x71B1, 0x71A8,
+ 0x7256, 0x729B, 0x734E, 0x7357, 0x7469, 0x748B, 0x7483,
+ /* Big5-HKSCS 0xBD40 .. 0xBD7E */
+ 0x747E, 0x7480, 0x757F, 0x7620, 0x7629, 0x761F, 0x7624, 0x7626,
+ 0x7621, 0x7622, 0x769A, 0x76BA, 0x76E4, 0x778E, 0x7787, 0x778C,
+ 0x7791, 0x778B, 0x78CB, 0x78C5, 0x78BA, 0x78CA, 0x78BE, 0x78D5,
+ 0x78BC, 0x78D0, 0x7A3F, 0x7A3C, 0x7A40, 0x7A3D, 0x7A37, 0x7A3B,
+ 0x7AAF, 0x7AAE, 0x7BAD, 0x7BB1, 0x7BC4, 0x7BB4, 0x7BC6, 0x7BC7,
+ 0x7BC1, 0x7BA0, 0x7BCC, 0x7CCA, 0x7DE0, 0x7DF4, 0x7DEF, 0x7DFB,
+ 0x7DD8, 0x7DEC, 0x7DDD, 0x7DE8, 0x7DE3, 0x7DDA, 0x7DDE, 0x7DE9,
+ 0x7D9E, 0x7DD9, 0x7DF2, 0x7DF9, 0x7F75, 0x7F77, 0x7FAF,
+ /* Big5-HKSCS 0xBDA1 .. 0xBDFE */
+ 0x7FE9, 0x8026, 0x819B, 0x819C, 0x819D, 0x81A0, 0x819A,
+ 0x8198, 0x8517, 0x853D, 0x851A, 0x84EE, 0x852C, 0x852D, 0x8513,
+ 0x8511, 0x8523, 0x8521, 0x8514, 0x84EC, 0x8525, 0x84FF, 0x8506,
+ 0x8782, 0x8774, 0x8776, 0x8760, 0x8766, 0x8778, 0x8768, 0x8759,
+ 0x8757, 0x874C, 0x8753, 0x885B, 0x885D, 0x8910, 0x8907, 0x8912,
+ 0x8913, 0x8915, 0x890A, 0x8ABC, 0x8AD2, 0x8AC7, 0x8AC4, 0x8A95,
+ 0x8ACB, 0x8AF8, 0x8AB2, 0x8AC9, 0x8AC2, 0x8ABF, 0x8AB0, 0x8AD6,
+ 0x8ACD, 0x8AB6, 0x8AB9, 0x8ADB, 0x8C4C, 0x8C4E, 0x8C6C, 0x8CE0,
+ 0x8CDE, 0x8CE6, 0x8CE4, 0x8CEC, 0x8CED, 0x8CE2, 0x8CE3, 0x8CDC,
+ 0x8CEA, 0x8CE1, 0x8D6D, 0x8D9F, 0x8DA3, 0x8E2B, 0x8E10, 0x8E1D,
+ 0x8E22, 0x8E0F, 0x8E29, 0x8E1F, 0x8E21, 0x8E1E, 0x8EBA, 0x8F1D,
+ 0x8F1B, 0x8F1F, 0x8F29, 0x8F26, 0x8F2A, 0x8F1C, 0x8F1E,
+ /* Big5-HKSCS 0xBE40 .. 0xBE7E */
+ 0x8F25, 0x9069, 0x906E, 0x9068, 0x906D, 0x9077, 0x9130, 0x912D,
+ 0x9127, 0x9131, 0x9187, 0x9189, 0x918B, 0x9183, 0x92C5, 0x92BB,
+ 0x92B7, 0x92EA, 0x92AC, 0x92E4, 0x92C1, 0x92B3, 0x92BC, 0x92D2,
+ 0x92C7, 0x92F0, 0x92B2, 0x95AD, 0x95B1, 0x9704, 0x9706, 0x9707,
+ 0x9709, 0x9760, 0x978D, 0x978B, 0x978F, 0x9821, 0x982B, 0x981C,
+ 0x98B3, 0x990A, 0x9913, 0x9912, 0x9918, 0x99DD, 0x99D0, 0x99DF,
+ 0x99DB, 0x99D1, 0x99D5, 0x99D2, 0x99D9, 0x9AB7, 0x9AEE, 0x9AEF,
+ 0x9B27, 0x9B45, 0x9B44, 0x9B77, 0x9B6F, 0x9D06, 0x9D09,
+ /* Big5-HKSCS 0xBEA1 .. 0xBEFE */
+ 0x9D03, 0x9EA9, 0x9EBE, 0x9ECE, 0x58A8, 0x9F52, 0x5112,
+ 0x5118, 0x5114, 0x5110, 0x5115, 0x5180, 0x51AA, 0x51DD, 0x5291,
+ 0x5293, 0x52F3, 0x5659, 0x566B, 0x5679, 0x5669, 0x5664, 0x5678,
+ 0x566A, 0x5668, 0x5665, 0x5671, 0x566F, 0x566C, 0x5662, 0x5676,
+ 0x58C1, 0x58BE, 0x58C7, 0x58C5, 0x596E, 0x5B1D, 0x5B34, 0x5B78,
+ 0x5BF0, 0x5C0E, 0x5F4A, 0x61B2, 0x6191, 0x61A9, 0x618A, 0x61CD,
+ 0x61B6, 0x61BE, 0x61CA, 0x61C8, 0x6230, 0x64C5, 0x64C1, 0x64CB,
+ 0x64BB, 0x64BC, 0x64DA, 0x64C4, 0x64C7, 0x64C2, 0x64CD, 0x64BF,
+ 0x64D2, 0x64D4, 0x64BE, 0x6574, 0x66C6, 0x66C9, 0x66B9, 0x66C4,
+ 0x66C7, 0x66B8, 0x6A3D, 0x6A38, 0x6A3A, 0x6A59, 0x6A6B, 0x6A58,
+ 0x6A39, 0x6A44, 0x6A62, 0x6A61, 0x6A4B, 0x6A47, 0x6A35, 0x6A5F,
+ 0x6A48, 0x6B59, 0x6B77, 0x6C05, 0x6FC2, 0x6FB1, 0x6FA1,
+ /* Big5-HKSCS 0xBF40 .. 0xBF7E */
+ 0x6FC3, 0x6FA4, 0x6FC1, 0x6FA7, 0x6FB3, 0x6FC0, 0x6FB9, 0x6FB6,
+ 0x6FA6, 0x6FA0, 0x6FB4, 0x71BE, 0x71C9, 0x71D0, 0x71D2, 0x71C8,
+ 0x71D5, 0x71B9, 0x71CE, 0x71D9, 0x71DC, 0x71C3, 0x71C4, 0x7368,
+ 0x749C, 0x74A3, 0x7498, 0x749F, 0x749E, 0x74E2, 0x750C, 0x750D,
+ 0x7634, 0x7638, 0x763A, 0x76E7, 0x76E5, 0x77A0, 0x779E, 0x779F,
+ 0x77A5, 0x78E8, 0x78DA, 0x78EC, 0x78E7, 0x79A6, 0x7A4D, 0x7A4E,
+ 0x7A46, 0x7A4C, 0x7A4B, 0x7ABA, 0x7BD9, 0x7C11, 0x7BC9, 0x7BE4,
+ 0x7BDB, 0x7BE1, 0x7BE9, 0x7BE6, 0x7CD5, 0x7CD6, 0x7E0A,
+ /* Big5-HKSCS 0xBFA1 .. 0xBFFE */
+ 0x7E11, 0x7E08, 0x7E1B, 0x7E23, 0x7E1E, 0x7E1D, 0x7E09,
+ 0x7E10, 0x7F79, 0x7FB2, 0x7FF0, 0x7FF1, 0x7FEE, 0x8028, 0x81B3,
+ 0x81A9, 0x81A8, 0x81FB, 0x8208, 0x8258, 0x8259, 0x854A, 0x8559,
+ 0x8548, 0x8568, 0x8569, 0x8543, 0x8549, 0x856D, 0x856A, 0x855E,
+ 0x8783, 0x879F, 0x879E, 0x87A2, 0x878D, 0x8861, 0x892A, 0x8932,
+ 0x8925, 0x892B, 0x8921, 0x89AA, 0x89A6, 0x8AE6, 0x8AFA, 0x8AEB,
+ 0x8AF1, 0x8B00, 0x8ADC, 0x8AE7, 0x8AEE, 0x8AFE, 0x8B01, 0x8B02,
+ 0x8AF7, 0x8AED, 0x8AF3, 0x8AF6, 0x8AFC, 0x8C6B, 0x8C6D, 0x8C93,
+ 0x8CF4, 0x8E44, 0x8E31, 0x8E34, 0x8E42, 0x8E39, 0x8E35, 0x8F3B,
+ 0x8F2F, 0x8F38, 0x8F33, 0x8FA8, 0x8FA6, 0x9075, 0x9074, 0x9078,
+ 0x9072, 0x907C, 0x907A, 0x9134, 0x9192, 0x9320, 0x9336, 0x92F8,
+ 0x9333, 0x932F, 0x9322, 0x92FC, 0x932B, 0x9304, 0x931A,
+ /* Big5-HKSCS 0xC040 .. 0xC07E */
+ 0x9310, 0x9326, 0x9321, 0x9315, 0x932E, 0x9319, 0x95BB, 0x96A7,
+ 0x96A8, 0x96AA, 0x96D5, 0x970E, 0x9711, 0x9716, 0x970D, 0x9713,
+ 0x970F, 0x975B, 0x975C, 0x9766, 0x9798, 0x9830, 0x9838, 0x983B,
+ 0x9837, 0x982D, 0x9839, 0x9824, 0x9910, 0x9928, 0x991E, 0x991B,
+ 0x9921, 0x991A, 0x99ED, 0x99E2, 0x99F1, 0x9AB8, 0x9ABC, 0x9AFB,
+ 0x9AED, 0x9B28, 0x9B91, 0x9D15, 0x9D23, 0x9D26, 0x9D28, 0x9D12,
+ 0x9D1B, 0x9ED8, 0x9ED4, 0x9F8D, 0x9F9C, 0x512A, 0x511F, 0x5121,
+ 0x5132, 0x52F5, 0x568E, 0x5680, 0x5690, 0x5685, 0x5687,
+ /* Big5-HKSCS 0xC0A1 .. 0xC0FE */
+ 0x568F, 0x58D5, 0x58D3, 0x58D1, 0x58CE, 0x5B30, 0x5B2A,
+ 0x5B24, 0x5B7A, 0x5C37, 0x5C68, 0x5DBC, 0x5DBA, 0x5DBD, 0x5DB8,
+ 0x5E6B, 0x5F4C, 0x5FBD, 0x61C9, 0x61C2, 0x61C7, 0x61E6, 0x61CB,
+ 0x6232, 0x6234, 0x64CE, 0x64CA, 0x64D8, 0x64E0, 0x64F0, 0x64E6,
+ 0x64EC, 0x64F1, 0x64E2, 0x64ED, 0x6582, 0x6583, 0x66D9, 0x66D6,
+ 0x6A80, 0x6A94, 0x6A84, 0x6AA2, 0x6A9C, 0x6ADB, 0x6AA3, 0x6A7E,
+ 0x6A97, 0x6A90, 0x6AA0, 0x6B5C, 0x6BAE, 0x6BDA, 0x6C08, 0x6FD8,
+ 0x6FF1, 0x6FDF, 0x6FE0, 0x6FDB, 0x6FE4, 0x6FEB, 0x6FEF, 0x6F80,
+ 0x6FEC, 0x6FE1, 0x6FE9, 0x6FD5, 0x6FEE, 0x6FF0, 0x71E7, 0x71DF,
+ 0x71EE, 0x71E6, 0x71E5, 0x71ED, 0x71EC, 0x71F4, 0x71E0, 0x7235,
+ 0x7246, 0x7370, 0x7372, 0x74A9, 0x74B0, 0x74A6, 0x74A8, 0x7646,
+ 0x7642, 0x764C, 0x76EA, 0x77B3, 0x77AA, 0x77B0, 0x77AC,
+ /* Big5-HKSCS 0xC140 .. 0xC17E */
+ 0x77A7, 0x77AD, 0x77EF, 0x78F7, 0x78FA, 0x78F4, 0x78EF, 0x7901,
+ 0x79A7, 0x79AA, 0x7A57, 0x7ABF, 0x7C07, 0x7C0D, 0x7BFE, 0x7BF7,
+ 0x7C0C, 0x7BE0, 0x7CE0, 0x7CDC, 0x7CDE, 0x7CE2, 0x7CDF, 0x7CD9,
+ 0x7CDD, 0x7E2E, 0x7E3E, 0x7E46, 0x7E37, 0x7E32, 0x7E43, 0x7E2B,
+ 0x7E3D, 0x7E31, 0x7E45, 0x7E41, 0x7E34, 0x7E39, 0x7E48, 0x7E35,
+ 0x7E3F, 0x7E2F, 0x7F44, 0x7FF3, 0x7FFC, 0x8071, 0x8072, 0x8070,
+ 0x806F, 0x8073, 0x81C6, 0x81C3, 0x81BA, 0x81C2, 0x81C0, 0x81BF,
+ 0x81BD, 0x81C9, 0x81BE, 0x81E8, 0x8209, 0x8271, 0x85AA,
+ /* Big5-HKSCS 0xC1A1 .. 0xC1FE */
+ 0x8584, 0x857E, 0x859C, 0x8591, 0x8594, 0x85AF, 0x859B,
+ 0x8587, 0x85A8, 0x858A, 0x8667, 0x87C0, 0x87D1, 0x87B3, 0x87D2,
+ 0x87C6, 0x87AB, 0x87BB, 0x87BA, 0x87C8, 0x87CB, 0x893B, 0x8936,
+ 0x8944, 0x8938, 0x893D, 0x89AC, 0x8B0E, 0x8B17, 0x8B19, 0x8B1B,
+ 0x8B0A, 0x8B20, 0x8B1D, 0x8B04, 0x8B10, 0x8C41, 0x8C3F, 0x8C73,
+ 0x8CFA, 0x8CFD, 0x8CFC, 0x8CF8, 0x8CFB, 0x8DA8, 0x8E49, 0x8E4B,
+ 0x8E48, 0x8E4A, 0x8F44, 0x8F3E, 0x8F42, 0x8F45, 0x8F3F, 0x907F,
+ 0x907D, 0x9084, 0x9081, 0x9082, 0x9080, 0x9139, 0x91A3, 0x919E,
+ 0x919C, 0x934D, 0x9382, 0x9328, 0x9375, 0x934A, 0x9365, 0x934B,
+ 0x9318, 0x937E, 0x936C, 0x935B, 0x9370, 0x935A, 0x9354, 0x95CA,
+ 0x95CB, 0x95CC, 0x95C8, 0x95C6, 0x96B1, 0x96B8, 0x96D6, 0x971C,
+ 0x971E, 0x97A0, 0x97D3, 0x9846, 0x98B6, 0x9935, 0x9A01,
+ /* Big5-HKSCS 0xC240 .. 0xC27E */
+ 0x99FF, 0x9BAE, 0x9BAB, 0x9BAA, 0x9BAD, 0x9D3B, 0x9D3F, 0x9E8B,
+ 0x9ECF, 0x9EDE, 0x9EDC, 0x9EDD, 0x9EDB, 0x9F3E, 0x9F4B, 0x53E2,
+ 0x5695, 0x56AE, 0x58D9, 0x58D8, 0x5B38, 0x5F5D, 0x61E3, 0x6233,
+ 0x64F4, 0x64F2, 0x64FE, 0x6506, 0x64FA, 0x64FB, 0x64F7, 0x65B7,
+ 0x66DC, 0x6726, 0x6AB3, 0x6AAC, 0x6AC3, 0x6ABB, 0x6AB8, 0x6AC2,
+ 0x6AAE, 0x6AAF, 0x6B5F, 0x6B78, 0x6BAF, 0x7009, 0x700B, 0x6FFE,
+ 0x7006, 0x6FFA, 0x7011, 0x700F, 0x71FB, 0x71FC, 0x71FE, 0x71F8,
+ 0x7377, 0x7375, 0x74A7, 0x74BF, 0x7515, 0x7656, 0x7658,
+ /* Big5-HKSCS 0xC2A1 .. 0xC2FE */
+ 0x7652, 0x77BD, 0x77BF, 0x77BB, 0x77BC, 0x790E, 0x79AE,
+ 0x7A61, 0x7A62, 0x7A60, 0x7AC4, 0x7AC5, 0x7C2B, 0x7C27, 0x7C2A,
+ 0x7C1E, 0x7C23, 0x7C21, 0x7CE7, 0x7E54, 0x7E55, 0x7E5E, 0x7E5A,
+ 0x7E61, 0x7E52, 0x7E59, 0x7F48, 0x7FF9, 0x7FFB, 0x8077, 0x8076,
+ 0x81CD, 0x81CF, 0x820A, 0x85CF, 0x85A9, 0x85CD, 0x85D0, 0x85C9,
+ 0x85B0, 0x85BA, 0x85B9, 0x85A6, 0x87EF, 0x87EC, 0x87F2, 0x87E0,
+ 0x8986, 0x89B2, 0x89F4, 0x8B28, 0x8B39, 0x8B2C, 0x8B2B, 0x8C50,
+ 0x8D05, 0x8E59, 0x8E63, 0x8E66, 0x8E64, 0x8E5F, 0x8E55, 0x8EC0,
+ 0x8F49, 0x8F4D, 0x9087, 0x9083, 0x9088, 0x91AB, 0x91AC, 0x91D0,
+ 0x9394, 0x938A, 0x9396, 0x93A2, 0x93B3, 0x93AE, 0x93AC, 0x93B0,
+ 0x9398, 0x939A, 0x9397, 0x95D4, 0x95D6, 0x95D0, 0x95D5, 0x96E2,
+ 0x96DC, 0x96D9, 0x96DB, 0x96DE, 0x9724, 0x97A3, 0x97A6,
+ /* Big5-HKSCS 0xC340 .. 0xC37E */
+ 0x97AD, 0x97F9, 0x984D, 0x984F, 0x984C, 0x984E, 0x9853, 0x98BA,
+ 0x993E, 0x993F, 0x993D, 0x992E, 0x99A5, 0x9A0E, 0x9AC1, 0x9B03,
+ 0x9B06, 0x9B4F, 0x9B4E, 0x9B4D, 0x9BCA, 0x9BC9, 0x9BFD, 0x9BC8,
+ 0x9BC0, 0x9D51, 0x9D5D, 0x9D60, 0x9EE0, 0x9F15, 0x9F2C, 0x5133,
+ 0x56A5, 0x58DE, 0x58DF, 0x58E2, 0x5BF5, 0x9F90, 0x5EEC, 0x61F2,
+ 0x61F7, 0x61F6, 0x61F5, 0x6500, 0x650F, 0x66E0, 0x66DD, 0x6AE5,
+ 0x6ADD, 0x6ADA, 0x6AD3, 0x701B, 0x701F, 0x7028, 0x701A, 0x701D,
+ 0x7015, 0x7018, 0x7206, 0x720D, 0x7258, 0x72A2, 0x7378,
+ /* Big5-HKSCS 0xC3A1 .. 0xC3FE */
+ 0x737A, 0x74BD, 0x74CA, 0x74E3, 0x7587, 0x7586, 0x765F,
+ 0x7661, 0x77C7, 0x7919, 0x79B1, 0x7A6B, 0x7A69, 0x7C3E, 0x7C3F,
+ 0x7C38, 0x7C3D, 0x7C37, 0x7C40, 0x7E6B, 0x7E6D, 0x7E79, 0x7E69,
+ 0x7E6A, 0x7F85, 0x7E73, 0x7FB6, 0x7FB9, 0x7FB8, 0x81D8, 0x85E9,
+ 0x85DD, 0x85EA, 0x85D5, 0x85E4, 0x85E5, 0x85F7, 0x87FB, 0x8805,
+ 0x880D, 0x87F9, 0x87FE, 0x8960, 0x895F, 0x8956, 0x895E, 0x8B41,
+ 0x8B5C, 0x8B58, 0x8B49, 0x8B5A, 0x8B4E, 0x8B4F, 0x8B46, 0x8B59,
+ 0x8D08, 0x8D0A, 0x8E7C, 0x8E72, 0x8E87, 0x8E76, 0x8E6C, 0x8E7A,
+ 0x8E74, 0x8F54, 0x8F4E, 0x8FAD, 0x908A, 0x908B, 0x91B1, 0x91AE,
+ 0x93E1, 0x93D1, 0x93DF, 0x93C3, 0x93C8, 0x93DC, 0x93DD, 0x93D6,
+ 0x93E2, 0x93CD, 0x93D8, 0x93E4, 0x93D7, 0x93E8, 0x95DC, 0x96B4,
+ 0x96E3, 0x972A, 0x9727, 0x9761, 0x97DC, 0x97FB, 0x985E,
+ /* Big5-HKSCS 0xC440 .. 0xC47E */
+ 0x9858, 0x985B, 0x98BC, 0x9945, 0x9949, 0x9A16, 0x9A19, 0x9B0D,
+ 0x9BE8, 0x9BE7, 0x9BD6, 0x9BDB, 0x9D89, 0x9D61, 0x9D72, 0x9D6A,
+ 0x9D6C, 0x9E92, 0x9E97, 0x9E93, 0x9EB4, 0x52F8, 0x56A8, 0x56B7,
+ 0x56B6, 0x56B4, 0x56BC, 0x58E4, 0x5B40, 0x5B43, 0x5B7D, 0x5BF6,
+ 0x5DC9, 0x61F8, 0x61FA, 0x6518, 0x6514, 0x6519, 0x66E6, 0x6727,
+ 0x6AEC, 0x703E, 0x7030, 0x7032, 0x7210, 0x737B, 0x74CF, 0x7662,
+ 0x7665, 0x7926, 0x792A, 0x792C, 0x792B, 0x7AC7, 0x7AF6, 0x7C4C,
+ 0x7C43, 0x7C4D, 0x7CEF, 0x7CF0, 0x8FAE, 0x7E7D, 0x7E7C,
+ /* Big5-HKSCS 0xC4A1 .. 0xC4FE */
+ 0x7E82, 0x7F4C, 0x8000, 0x81DA, 0x8266, 0x85FB, 0x85F9,
+ 0x8611, 0x85FA, 0x8606, 0x860B, 0x8607, 0x860A, 0x8814, 0x8815,
+ 0x8964, 0x89BA, 0x89F8, 0x8B70, 0x8B6C, 0x8B66, 0x8B6F, 0x8B5F,
+ 0x8B6B, 0x8D0F, 0x8D0D, 0x8E89, 0x8E81, 0x8E85, 0x8E82, 0x91B4,
+ 0x91CB, 0x9418, 0x9403, 0x93FD, 0x95E1, 0x9730, 0x98C4, 0x9952,
+ 0x9951, 0x99A8, 0x9A2B, 0x9A30, 0x9A37, 0x9A35, 0x9C13, 0x9C0D,
+ 0x9E79, 0x9EB5, 0x9EE8, 0x9F2F, 0x9F5F, 0x9F63, 0x9F61, 0x5137,
+ 0x5138, 0x56C1, 0x56C0, 0x56C2, 0x5914, 0x5C6C, 0x5DCD, 0x61FC,
+ 0x61FE, 0x651D, 0x651C, 0x6595, 0x66E9, 0x6AFB, 0x6B04, 0x6AFA,
+ 0x6BB2, 0x704C, 0x721B, 0x72A7, 0x74D6, 0x74D4, 0x7669, 0x77D3,
+ 0x7C50, 0x7E8F, 0x7E8C, 0x7FBC, 0x8617, 0x862D, 0x861A, 0x8823,
+ 0x8822, 0x8821, 0x881F, 0x896A, 0x896C, 0x89BD, 0x8B74,
+ /* Big5-HKSCS 0xC540 .. 0xC57E */
+ 0x8B77, 0x8B7D, 0x8D13, 0x8E8A, 0x8E8D, 0x8E8B, 0x8F5F, 0x8FAF,
+ 0x91BA, 0x942E, 0x9433, 0x9435, 0x943A, 0x9438, 0x9432, 0x942B,
+ 0x95E2, 0x9738, 0x9739, 0x9732, 0x97FF, 0x9867, 0x9865, 0x9957,
+ 0x9A45, 0x9A43, 0x9A40, 0x9A3E, 0x9ACF, 0x9B54, 0x9B51, 0x9C2D,
+ 0x9C25, 0x9DAF, 0x9DB4, 0x9DC2, 0x9DB8, 0x9E9D, 0x9EEF, 0x9F19,
+ 0x9F5C, 0x9F66, 0x9F67, 0x513C, 0x513B, 0x56C8, 0x56CA, 0x56C9,
+ 0x5B7F, 0x5DD4, 0x5DD2, 0x5F4E, 0x61FF, 0x6524, 0x6B0A, 0x6B61,
+ 0x7051, 0x7058, 0x7380, 0x74E4, 0x758A, 0x766E, 0x766C,
+ /* Big5-HKSCS 0xC5A1 .. 0xC5FE */
+ 0x79B3, 0x7C60, 0x7C5F, 0x807E, 0x807D, 0x81DF, 0x8972,
+ 0x896F, 0x89FC, 0x8B80, 0x8D16, 0x8D17, 0x8E91, 0x8E93, 0x8F61,
+ 0x9148, 0x9444, 0x9451, 0x9452, 0x973D, 0x973E, 0x97C3, 0x97C1,
+ 0x986B, 0x9955, 0x9A55, 0x9A4D, 0x9AD2, 0x9B1A, 0x9C49, 0x9C31,
+ 0x9C3E, 0x9C3B, 0x9DD3, 0x9DD7, 0x9F34, 0x9F6C, 0x9F6A, 0x9F94,
+ 0x56CC, 0x5DD6, 0x6200, 0x6523, 0x652B, 0x652A, 0x66EC, 0x6B10,
+ 0x74DA, 0x7ACA, 0x7C64, 0x7C63, 0x7C65, 0x7E93, 0x7E96, 0x7E94,
+ 0x81E2, 0x8638, 0x863F, 0x8831, 0x8B8A, 0x9090, 0x908F, 0x9463,
+ 0x9460, 0x9464, 0x9768, 0x986F, 0x995C, 0x9A5A, 0x9A5B, 0x9A57,
+ 0x9AD3, 0x9AD4, 0x9AD1, 0x9C54, 0x9C57, 0x9C56, 0x9DE5, 0x9E9F,
+ 0x9EF4, 0x56D1, 0x58E9, 0x652C, 0x705E, 0x7671, 0x7672, 0x77D7,
+ 0x7F50, 0x7F88, 0x8836, 0x8839, 0x8862, 0x8B93, 0x8B92,
+ /* Big5-HKSCS 0xC640 .. 0xC67E */
+ 0x8B96, 0x8277, 0x8D1B, 0x91C0, 0x946A, 0x9742, 0x9748, 0x9744,
+ 0x97C6, 0x9870, 0x9A5F, 0x9B22, 0x9B58, 0x9C5F, 0x9DF9, 0x9DFA,
+ 0x9E7C, 0x9E7D, 0x9F07, 0x9F77, 0x9F72, 0x5EF3, 0x6B16, 0x7063,
+ 0x7C6C, 0x7C6E, 0x883B, 0x89C0, 0x8EA1, 0x91C1, 0x9472, 0x9470,
+ 0x9871, 0x995E, 0x9AD6, 0x9B23, 0x9ECC, 0x7064, 0x77DA, 0x8B9A,
+ 0x9477, 0x97C9, 0x9A62, 0x9A65, 0x7E9C, 0x8B9C, 0x8EAA, 0x91C5,
+ 0x947D, 0x947E, 0x947C, 0x9C77, 0x9C78, 0x9EF7, 0x8C54, 0x947F,
+ 0x9E1A, 0x7228, 0x9A6A, 0x9B31, 0x9E1B, 0x9E1E, 0x7C72,
+ /* Big5-HKSCS 0xC6A1 .. 0xC6FE */
+ 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466,
+ 0x2467, 0x2468, 0x2469, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478,
+ 0x2479, 0x247A, 0x247B, 0x247C, 0x247D, 0x2170, 0x2171, 0x2172,
+ 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x4E36,
+ 0x4E3F, 0x4E85, 0x4EA0, 0x5182, 0x5196, 0x51AB, 0x52F9, 0x5338,
+ 0x5369, 0x53B6, 0x590A, 0x5B80, 0x5DDB, 0x2F33, 0x5E7F, 0xF6DF,
+ 0x5F50, 0x5F61, 0x6534, 0xF6E3, 0x7592, 0xF6E5, 0x8FB5, 0xF6E7,
+ 0x00A8, 0x02C6, 0x30FD, 0x30FE, 0x309D, 0x309E, 0xF6EE, 0xF6EF,
+ 0x3005, 0x3006, 0x3007, 0x30FC, 0xFF3B, 0xFF3D, 0x273D, 0x3041,
+ 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049,
+ 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, 0x3050, 0x3051,
+ 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058,
+ /* Big5-HKSCS 0xC740 .. 0xC77E */
+ 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, 0x3060,
+ 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068,
+ 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, 0x3070,
+ 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078,
+ 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, 0x3080,
+ 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088,
+ 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F, 0x3090,
+ 0x3091, 0x3092, 0x3093, 0x30A1, 0x30A2, 0x30A3, 0x30A4,
+ /* Big5-HKSCS 0xC7A1 .. 0xC7FE */
+ 0x30A5, 0x30A6, 0x30A7, 0x30A8, 0x30A9, 0x30AA, 0x30AB,
+ 0x30AC, 0x30AD, 0x30AE, 0x30AF, 0x30B0, 0x30B1, 0x30B2, 0x30B3,
+ 0x30B4, 0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, 0x30BB,
+ 0x30BC, 0x30BD, 0x30BE, 0x30BF, 0x30C0, 0x30C1, 0x30C2, 0x30C3,
+ 0x30C4, 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB,
+ 0x30CC, 0x30CD, 0x30CE, 0x30CF, 0x30D0, 0x30D1, 0x30D2, 0x30D3,
+ 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, 0x30D9, 0x30DA, 0x30DB,
+ 0x30DC, 0x30DD, 0x30DE, 0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E3,
+ 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, 0x30E9, 0x30EA, 0x30EB,
+ 0x30EC, 0x30ED, 0x30EE, 0x30EF, 0x30F0, 0x30F1, 0x30F2, 0x30F3,
+ 0x30F4, 0x30F5, 0x30F6, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414,
+ 0x0415, 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A,
+ /* Big5-HKSCS 0xC840 .. 0xC87E */
+ 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422,
+ 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A,
+ 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0430, 0x0431, 0x0432,
+ 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, 0x0437, 0x0438, 0x0439,
+ 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, 0x0440, 0x0441,
+ 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449,
+ 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x21E7, 0x21B8,
+ 0x21B9, 0xF7E5, 0xF7E6, 0x4E5A, 0xF7E8, 0x5202, 0xF7EA,
+ /* Big5-HKSCS 0xC8A1 .. 0xC8FE */
+ 0xF7EB, 0x5188, 0xF7ED, 0xF7EE, 0xF7EF, 0xF7F0, 0xF7F1,
+ 0xF7F2, 0xF7F3, 0xF7F4, 0xF7F5, 0xF7F6, 0xF7F7, 0xF7F8, 0xF7F9,
+ 0xF7FA, 0xF7FB, 0xF7FC, 0xF7FD, 0xF7FE, 0xF7FF, 0xF800, 0xF801,
+ 0xF802, 0xF803, 0xF804, 0xF805, 0xF806, 0xF807, 0xF808, 0xF809,
+ 0xF80A, 0xF80B, 0xF80C, 0xF80D, 0xF80E, 0xF80F, 0xF810, 0xF811,
+ 0xF812, 0xF813, 0xF814, 0xF815, 0xF816, 0xFFE2, 0xFFE4, 0xFF07,
+ 0xFF02, 0x3231, 0x2116, 0x2121, 0x309B, 0x309C, 0x2E80, 0x2E84,
+ 0x2E86, 0x2E87, 0x2E88, 0x2E8A, 0x2E8C, 0x2E8D, 0x2E95, 0x2E9C,
+ 0x2E9D, 0x2EA5, 0x2EA7, 0x2EAA, 0x2EAC, 0x2EAE, 0x2EB6, 0x2EBC,
+ 0x2EBE, 0x2EC6, 0x2ECA, 0x2ECC, 0x2ECD, 0x2ECF, 0x2ED6, 0x2ED7,
+ 0x2EDE, 0x2EE3, 0xF83C, 0xF83D, 0xF83E, 0x0283, 0x0250, 0x025B,
+ 0x0254, 0x0275, 0x0153, 0x00F8, 0x014B, 0x028A, 0x026A,
+ /* Big5-HKSCS 0xC940 .. 0xC97E */
+ 0x4E42, 0x4E5C, 0x51F5, 0x531A, 0x5382, 0x4E07, 0x4E0C, 0x4E47,
+ 0x4E8D, 0x56D7, 0xFA0C, 0x5C6E, 0x5F73, 0x4E0F, 0x5187, 0x4E0E,
+ 0x4E2E, 0x4E93, 0x4EC2, 0x4EC9, 0x4EC8, 0x5198, 0x52FC, 0x536C,
+ 0x53B9, 0x5720, 0x5903, 0x592C, 0x5C10, 0x5DFF, 0x65E1, 0x6BB3,
+ 0x6BCC, 0x6C14, 0x723F, 0x4E31, 0x4E3C, 0x4EE8, 0x4EDC, 0x4EE9,
+ 0x4EE1, 0x4EDD, 0x4EDA, 0x520C, 0x531C, 0x534C, 0x5722, 0x5723,
+ 0x5917, 0x592F, 0x5B81, 0x5B84, 0x5C12, 0x5C3B, 0x5C74, 0x5C73,
+ 0x5E04, 0x5E80, 0x5E82, 0x5FC9, 0x6209, 0x6250, 0x6C15,
+ /* Big5-HKSCS 0xC9A1 .. 0xC9FE */
+ 0x6C36, 0x6C43, 0x6C3F, 0x6C3B, 0x72AE, 0x72B0, 0x738A,
+ 0x79B8, 0x808A, 0x961E, 0x4F0E, 0x4F18, 0x4F2C, 0x4EF5, 0x4F14,
+ 0x4EF1, 0x4F00, 0x4EF7, 0x4F08, 0x4F1D, 0x4F02, 0x4F05, 0x4F22,
+ 0x4F13, 0x4F04, 0x4EF4, 0x4F12, 0x51B1, 0x5213, 0x5209, 0x5210,
+ 0x52A6, 0x5322, 0x531F, 0x534D, 0x538A, 0x5407, 0x56E1, 0x56DF,
+ 0x572E, 0x572A, 0x5734, 0x593C, 0x5980, 0x597C, 0x5985, 0x597B,
+ 0x597E, 0x5977, 0x597F, 0x5B56, 0x5C15, 0x5C25, 0x5C7C, 0x5C7A,
+ 0x5C7B, 0x5C7E, 0x5DDF, 0x5E75, 0x5E84, 0x5F02, 0x5F1A, 0x5F74,
+ 0x5FD5, 0x5FD4, 0x5FCF, 0x625C, 0x625E, 0x6264, 0x6261, 0x6266,
+ 0x6262, 0x6259, 0x6260, 0x625A, 0x6265, 0x65EF, 0x65EE, 0x673E,
+ 0x6739, 0x6738, 0x673B, 0x673A, 0x673F, 0x673C, 0x6733, 0x6C18,
+ 0x6C46, 0x6C52, 0x6C5C, 0x6C4F, 0x6C4A, 0x6C54, 0x6C4B,
+ /* Big5-HKSCS 0xCA40 .. 0xCA7E */
+ 0x6C4C, 0x7071, 0x725E, 0x72B4, 0x72B5, 0x738E, 0x752A, 0x767F,
+ 0x7A75, 0x7F51, 0x8278, 0x827C, 0x8280, 0x827D, 0x827F, 0x864D,
+ 0x897E, 0x9099, 0x9097, 0x9098, 0x909B, 0x9094, 0x9622, 0x9624,
+ 0x9620, 0x9623, 0x4F56, 0x4F3B, 0x4F62, 0x4F49, 0x4F53, 0x4F64,
+ 0x4F3E, 0x4F67, 0x4F52, 0x4F5F, 0x4F41, 0x4F58, 0x4F2D, 0x4F33,
+ 0x4F3F, 0x4F61, 0x518F, 0x51B9, 0x521C, 0x521E, 0x5221, 0x52AD,
+ 0x52AE, 0x5309, 0x5363, 0x5372, 0x538E, 0x538F, 0x5430, 0x5437,
+ 0x542A, 0x5454, 0x5445, 0x5419, 0x541C, 0x5425, 0x5418,
+ /* Big5-HKSCS 0xCAA1 .. 0xCAFE */
+ 0x543D, 0x544F, 0x5441, 0x5428, 0x5424, 0x5447, 0x56EE,
+ 0x56E7, 0x56E5, 0x5741, 0x5745, 0x574C, 0x5749, 0x574B, 0x5752,
+ 0x5906, 0x5940, 0x59A6, 0x5998, 0x59A0, 0x5997, 0x598E, 0x59A2,
+ 0x5990, 0x598F, 0x59A7, 0x59A1, 0x5B8E, 0x5B92, 0x5C28, 0x5C2A,
+ 0x5C8D, 0x5C8F, 0x5C88, 0x5C8B, 0x5C89, 0x5C92, 0x5C8A, 0x5C86,
+ 0x5C93, 0x5C95, 0x5DE0, 0x5E0A, 0x5E0E, 0x5E8B, 0x5E89, 0x5E8C,
+ 0x5E88, 0x5E8D, 0x5F05, 0x5F1D, 0x5F78, 0x5F76, 0x5FD2, 0x5FD1,
+ 0x5FD0, 0x5FED, 0x5FE8, 0x5FEE, 0x5FF3, 0x5FE1, 0x5FE4, 0x5FE3,
+ 0x5FFA, 0x5FEF, 0x5FF7, 0x5FFB, 0x6000, 0x5FF4, 0x623A, 0x6283,
+ 0x628C, 0x628E, 0x628F, 0x6294, 0x6287, 0x6271, 0x627B, 0x627A,
+ 0x6270, 0x6281, 0x6288, 0x6277, 0x627D, 0x6272, 0x6274, 0x6537,
+ 0x65F0, 0x65F4, 0x65F3, 0x65F2, 0x65F5, 0x6745, 0x6747,
+ /* Big5-HKSCS 0xCB40 .. 0xCB7E */
+ 0x6759, 0x6755, 0x674C, 0x6748, 0x675D, 0x674D, 0x675A, 0x674B,
+ 0x6BD0, 0x6C19, 0x6C1A, 0x6C78, 0x6C67, 0x6C6B, 0x6C84, 0x6C8B,
+ 0x6C8F, 0x6C71, 0x6C6F, 0x6C69, 0x6C9A, 0x6C6D, 0x6C87, 0x6C95,
+ 0x6C9C, 0x6C66, 0x6C73, 0x6C65, 0x6C7B, 0x6C8E, 0x7074, 0x707A,
+ 0x7263, 0x72BF, 0x72BD, 0x72C3, 0x72C6, 0x72C1, 0x72BA, 0x72C5,
+ 0x7395, 0x7397, 0x7393, 0x7394, 0x7392, 0x753A, 0x7539, 0x7594,
+ 0x7595, 0x7681, 0x793D, 0x8034, 0x8095, 0x8099, 0x8090, 0x8092,
+ 0x809C, 0x8290, 0x828F, 0x8285, 0x828E, 0x8291, 0x8293,
+ /* Big5-HKSCS 0xCBA1 .. 0xCBFE */
+ 0x828A, 0x8283, 0x8284, 0x8C78, 0x8FC9, 0x8FBF, 0x909F,
+ 0x90A1, 0x90A5, 0x909E, 0x90A7, 0x90A0, 0x9630, 0x9628, 0x962F,
+ 0x962D, 0x4E33, 0x4F98, 0x4F7C, 0x4F85, 0x4F7D, 0x4F80, 0x4F87,
+ 0x4F76, 0x4F74, 0x4F89, 0x4F84, 0x4F77, 0x4F4C, 0x4F97, 0x4F6A,
+ 0x4F9A, 0x4F79, 0x4F81, 0x4F78, 0x4F90, 0x4F9C, 0x4F94, 0x4F9E,
+ 0x4F92, 0x4F82, 0x4F95, 0x4F6B, 0x4F6E, 0x519E, 0x51BC, 0x51BE,
+ 0x5235, 0x5232, 0x5233, 0x5246, 0x5231, 0x52BC, 0x530A, 0x530B,
+ 0x533C, 0x5392, 0x5394, 0x5487, 0x547F, 0x5481, 0x5491, 0x5482,
+ 0x5488, 0x546B, 0x547A, 0x547E, 0x5465, 0x546C, 0x5474, 0x5466,
+ 0x548D, 0x546F, 0x5461, 0x5460, 0x5498, 0x5463, 0x5467, 0x5464,
+ 0x56F7, 0x56F9, 0x576F, 0x5772, 0x576D, 0x576B, 0x5771, 0x5770,
+ 0x5776, 0x5780, 0x5775, 0x577B, 0x5773, 0x5774, 0x5762,
+ /* Big5-HKSCS 0xCC40 .. 0xCC7E */
+ 0x5768, 0x577D, 0x590C, 0x5945, 0x59B5, 0x59BA, 0x59CF, 0x59CE,
+ 0x59B2, 0x59CC, 0x59C1, 0x59B6, 0x59BC, 0x59C3, 0x59D6, 0x59B1,
+ 0x59BD, 0x59C0, 0x59C8, 0x59B4, 0x59C7, 0x5B62, 0x5B65, 0x5B93,
+ 0x5B95, 0x5C44, 0x5C47, 0x5CAE, 0x5CA4, 0x5CA0, 0x5CB5, 0x5CAF,
+ 0x5CA8, 0x5CAC, 0x5C9F, 0x5CA3, 0x5CAD, 0x5CA2, 0x5CAA, 0x5CA7,
+ 0x5C9D, 0x5CA5, 0x5CB6, 0x5CB0, 0x5CA6, 0x5E17, 0x5E14, 0x5E19,
+ 0x5F28, 0x5F22, 0x5F23, 0x5F24, 0x5F54, 0x5F82, 0x5F7E, 0x5F7D,
+ 0x5FDE, 0x5FE5, 0x602D, 0x6026, 0x6019, 0x6032, 0x600B,
+ /* Big5-HKSCS 0xCCA1 .. 0xCCFE */
+ 0x6034, 0x600A, 0x6017, 0x6033, 0x601A, 0x601E, 0x602C,
+ 0x6022, 0x600D, 0x6010, 0x602E, 0x6013, 0x6011, 0x600C, 0x6009,
+ 0x601C, 0x6214, 0x623D, 0x62AD, 0x62B4, 0x62D1, 0x62BE, 0x62AA,
+ 0x62B6, 0x62CA, 0x62AE, 0x62B3, 0x62AF, 0x62BB, 0x62A9, 0x62B0,
+ 0x62B8, 0x653D, 0x65A8, 0x65BB, 0x6609, 0x65FC, 0x6604, 0x6612,
+ 0x6608, 0x65FB, 0x6603, 0x660B, 0x660D, 0x6605, 0x65FD, 0x6611,
+ 0x6610, 0x66F6, 0x670A, 0x6785, 0x676C, 0x678E, 0x6792, 0x6776,
+ 0x677B, 0x6798, 0x6786, 0x6784, 0x6774, 0x678D, 0x678C, 0x677A,
+ 0x679F, 0x6791, 0x6799, 0x6783, 0x677D, 0x6781, 0x6778, 0x6779,
+ 0x6794, 0x6B25, 0x6B80, 0x6B7E, 0x6BDE, 0x6C1D, 0x6C93, 0x6CEC,
+ 0x6CEB, 0x6CEE, 0x6CD9, 0x6CB6, 0x6CD4, 0x6CAD, 0x6CE7, 0x6CB7,
+ 0x6CD0, 0x6CC2, 0x6CBA, 0x6CC3, 0x6CC6, 0x6CED, 0x6CF2,
+ /* Big5-HKSCS 0xCD40 .. 0xCD7E */
+ 0x6CD2, 0x6CDD, 0x6CB4, 0x6C8A, 0x6C9D, 0x6C80, 0x6CDE, 0x6CC0,
+ 0x6D30, 0x6CCD, 0x6CC7, 0x6CB0, 0x6CF9, 0x6CCF, 0x6CE9, 0x6CD1,
+ 0x7094, 0x7098, 0x7085, 0x7093, 0x7086, 0x7084, 0x7091, 0x7096,
+ 0x7082, 0x709A, 0x7083, 0x726A, 0x72D6, 0x72CB, 0x72D8, 0x72C9,
+ 0x72DC, 0x72D2, 0x72D4, 0x72DA, 0x72CC, 0x72D1, 0x73A4, 0x73A1,
+ 0x73AD, 0x73A6, 0x73A2, 0x73A0, 0x73AC, 0x739D, 0x74DD, 0x74E8,
+ 0x753F, 0x7540, 0x753E, 0x758C, 0x7598, 0x76AF, 0x76F3, 0x76F1,
+ 0x76F0, 0x76F5, 0x77F8, 0x77FC, 0x77F9, 0x77FB, 0x77FA,
+ /* Big5-HKSCS 0xCDA1 .. 0xCDFE */
+ 0x77F7, 0x7942, 0x793F, 0x79C5, 0x7A78, 0x7A7B, 0x7AFB,
+ 0x7C75, 0x7CFD, 0x8035, 0x808F, 0x80AE, 0x80A3, 0x80B8, 0x80B5,
+ 0x80AD, 0x8220, 0x82A0, 0x82C0, 0x82AB, 0x829A, 0x8298, 0x829B,
+ 0x82B5, 0x82A7, 0x82AE, 0x82BC, 0x829E, 0x82BA, 0x82B4, 0x82A8,
+ 0x82A1, 0x82A9, 0x82C2, 0x82A4, 0x82C3, 0x82B6, 0x82A2, 0x8670,
+ 0x866F, 0x866D, 0x866E, 0x8C56, 0x8FD2, 0x8FCB, 0x8FD3, 0x8FCD,
+ 0x8FD6, 0x8FD5, 0x8FD7, 0x90B2, 0x90B4, 0x90AF, 0x90B3, 0x90B0,
+ 0x9639, 0x963D, 0x963C, 0x963A, 0x9643, 0x4FCD, 0x4FC5, 0x4FD3,
+ 0x4FB2, 0x4FC9, 0x4FCB, 0x4FC1, 0x4FD4, 0x4FDC, 0x4FD9, 0x4FBB,
+ 0x4FB3, 0x4FDB, 0x4FC7, 0x4FD6, 0x4FBA, 0x4FC0, 0x4FB9, 0x4FEC,
+ 0x5244, 0x5249, 0x52C0, 0x52C2, 0x533D, 0x537C, 0x5397, 0x5396,
+ 0x5399, 0x5398, 0x54BA, 0x54A1, 0x54AD, 0x54A5, 0x54CF,
+ /* Big5-HKSCS 0xCE40 .. 0xCE7E */
+ 0x54C3, 0x830D, 0x54B7, 0x54AE, 0x54D6, 0x54B6, 0x54C5, 0x54C6,
+ 0x54A0, 0x5470, 0x54BC, 0x54A2, 0x54BE, 0x5472, 0x54DE, 0x54B0,
+ 0x57B5, 0x579E, 0x579F, 0x57A4, 0x578C, 0x5797, 0x579D, 0x579B,
+ 0x5794, 0x5798, 0x578F, 0x5799, 0x57A5, 0x579A, 0x5795, 0x58F4,
+ 0x590D, 0x5953, 0x59E1, 0x59DE, 0x59EE, 0x5A00, 0x59F1, 0x59DD,
+ 0x59FA, 0x59FD, 0x59FC, 0x59F6, 0x59E4, 0x59F2, 0x59F7, 0x59DB,
+ 0x59E9, 0x59F3, 0x59F5, 0x59E0, 0x59FE, 0x59F4, 0x59ED, 0x5BA8,
+ 0x5C4C, 0x5CD0, 0x5CD8, 0x5CCC, 0x5CD7, 0x5CCB, 0x5CDB,
+ /* Big5-HKSCS 0xCEA1 .. 0xCEFE */
+ 0x5CDE, 0x5CDA, 0x5CC9, 0x5CC7, 0x5CCA, 0x5CD6, 0x5CD3,
+ 0x5CD4, 0x5CCF, 0x5CC8, 0x5CC6, 0x5CCE, 0x5CDF, 0x5CF8, 0x5DF9,
+ 0x5E21, 0x5E22, 0x5E23, 0x5E20, 0x5E24, 0x5EB0, 0x5EA4, 0x5EA2,
+ 0x5E9B, 0x5EA3, 0x5EA5, 0x5F07, 0x5F2E, 0x5F56, 0x5F86, 0x6037,
+ 0x6039, 0x6054, 0x6072, 0x605E, 0x6045, 0x6053, 0x6047, 0x6049,
+ 0x605B, 0x604C, 0x6040, 0x6042, 0x605F, 0x6024, 0x6044, 0x6058,
+ 0x6066, 0x606E, 0x6242, 0x6243, 0x62CF, 0x630D, 0x630B, 0x62F5,
+ 0x630E, 0x6303, 0x62EB, 0x62F9, 0x630F, 0x630C, 0x62F8, 0x62F6,
+ 0x6300, 0x6313, 0x6314, 0x62FA, 0x6315, 0x62FB, 0x62F0, 0x6541,
+ 0x6543, 0x65AA, 0x65BF, 0x6636, 0x6621, 0x6632, 0x6635, 0x661C,
+ 0x6626, 0x6622, 0x6633, 0x662B, 0x663A, 0x661D, 0x6634, 0x6639,
+ 0x662E, 0x670F, 0x6710, 0x67C1, 0x67F2, 0x67C8, 0x67BA,
+ /* Big5-HKSCS 0xCF40 .. 0xCF7E */
+ 0x67DC, 0x67BB, 0x67F8, 0x67D8, 0x67C0, 0x67B7, 0x67C5, 0x67EB,
+ 0x67E4, 0x67DF, 0x67B5, 0x67CD, 0x67B3, 0x67F7, 0x67F6, 0x67EE,
+ 0x67E3, 0x67C2, 0x67B9, 0x67CE, 0x67E7, 0x67F0, 0x67B2, 0x67FC,
+ 0x67C6, 0x67ED, 0x67CC, 0x67AE, 0x67E6, 0x67DB, 0x67FA, 0x67C9,
+ 0x67CA, 0x67C3, 0x67EA, 0x67CB, 0x6B28, 0x6B82, 0x6B84, 0x6BB6,
+ 0x6BD6, 0x6BD8, 0x6BE0, 0x6C20, 0x6C21, 0x6D28, 0x6D34, 0x6D2D,
+ 0x6D1F, 0x6D3C, 0x6D3F, 0x6D12, 0x6D0A, 0x6CDA, 0x6D33, 0x6D04,
+ 0x6D19, 0x6D3A, 0x6D1A, 0x6D11, 0x6D00, 0x6D1D, 0x6D42,
+ /* Big5-HKSCS 0xCFA1 .. 0xCFFE */
+ 0x6D01, 0x6D18, 0x6D37, 0x6D03, 0x6D0F, 0x6D40, 0x6D07,
+ 0x6D20, 0x6D2C, 0x6D08, 0x6D22, 0x6D09, 0x6D10, 0x70B7, 0x709F,
+ 0x70BE, 0x70B1, 0x70B0, 0x70A1, 0x70B4, 0x70B5, 0x70A9, 0x7241,
+ 0x7249, 0x724A, 0x726C, 0x7270, 0x7273, 0x726E, 0x72CA, 0x72E4,
+ 0x72E8, 0x72EB, 0x72DF, 0x72EA, 0x72E6, 0x72E3, 0x7385, 0x73CC,
+ 0x73C2, 0x73C8, 0x73C5, 0x73B9, 0x73B6, 0x73B5, 0x73B4, 0x73EB,
+ 0x73BF, 0x73C7, 0x73BE, 0x73C3, 0x73C6, 0x73B8, 0x73CB, 0x74EC,
+ 0x74EE, 0x752E, 0x7547, 0x7548, 0x75A7, 0x75AA, 0x7679, 0x76C4,
+ 0x7708, 0x7703, 0x7704, 0x7705, 0x770A, 0x76F7, 0x76FB, 0x76FA,
+ 0x77E7, 0x77E8, 0x7806, 0x7811, 0x7812, 0x7805, 0x7810, 0x780F,
+ 0x780E, 0x7809, 0x7803, 0x7813, 0x794A, 0x794C, 0x794B, 0x7945,
+ 0x7944, 0x79D5, 0x79CD, 0x79CF, 0x79D6, 0x79CE, 0x7A80,
+ /* Big5-HKSCS 0xD040 .. 0xD07E */
+ 0x7A7E, 0x7AD1, 0x7B00, 0x7B01, 0x7C7A, 0x7C78, 0x7C79, 0x7C7F,
+ 0x7C80, 0x7C81, 0x7D03, 0x7D08, 0x7D01, 0x7F58, 0x7F91, 0x7F8D,
+ 0x7FBE, 0x8007, 0x800E, 0x800F, 0x8014, 0x8037, 0x80D8, 0x80C7,
+ 0x80E0, 0x80D1, 0x80C8, 0x80C2, 0x80D0, 0x80C5, 0x80E3, 0x80D9,
+ 0x80DC, 0x80CA, 0x80D5, 0x80C9, 0x80CF, 0x80D7, 0x80E6, 0x80CD,
+ 0x81FF, 0x8221, 0x8294, 0x82D9, 0x82FE, 0x82F9, 0x8307, 0x82E8,
+ 0x8300, 0x82D5, 0x833A, 0x82EB, 0x82D6, 0x82F4, 0x82EC, 0x82E1,
+ 0x82F2, 0x82F5, 0x830C, 0x82FB, 0x82F6, 0x82F0, 0x82EA,
+ /* Big5-HKSCS 0xD0A1 .. 0xD0FE */
+ 0x82E4, 0x82E0, 0x82FA, 0x82F3, 0x82ED, 0x8677, 0x8674,
+ 0x867C, 0x8673, 0x8841, 0x884E, 0x8867, 0x886A, 0x8869, 0x89D3,
+ 0x8A04, 0x8A07, 0x8D72, 0x8FE3, 0x8FE1, 0x8FEE, 0x8FE0, 0x90F1,
+ 0x90BD, 0x90BF, 0x90D5, 0x90C5, 0x90BE, 0x90C7, 0x90CB, 0x90C8,
+ 0x91D4, 0x91D3, 0x9654, 0x964F, 0x9651, 0x9653, 0x964A, 0x964E,
+ 0x501E, 0x5005, 0x5007, 0x5013, 0x5022, 0x5030, 0x501B, 0x4FF5,
+ 0x4FF4, 0x5033, 0x5037, 0x502C, 0x4FF6, 0x4FF7, 0x5017, 0x501C,
+ 0x5020, 0x5027, 0x5035, 0x502F, 0x5031, 0x500E, 0x515A, 0x5194,
+ 0x5193, 0x51CA, 0x51C4, 0x51C5, 0x51C8, 0x51CE, 0x5261, 0x525A,
+ 0x5252, 0x525E, 0x525F, 0x5255, 0x5262, 0x52CD, 0x530E, 0x539E,
+ 0x5526, 0x54E2, 0x5517, 0x5512, 0x54E7, 0x54F3, 0x54E4, 0x551A,
+ 0x54FF, 0x5504, 0x5508, 0x54EB, 0x5511, 0x5505, 0x54F1,
+ /* Big5-HKSCS 0xD140 .. 0xD17E */
+ 0x550A, 0x54FB, 0x54F7, 0x54F8, 0x54E0, 0x550E, 0x5503, 0x550B,
+ 0x5701, 0x5702, 0x57CC, 0x5832, 0x57D5, 0x57D2, 0x57BA, 0x57C6,
+ 0x57BD, 0x57BC, 0x57B8, 0x57B6, 0x57BF, 0x57C7, 0x57D0, 0x57B9,
+ 0x57C1, 0x590E, 0x594A, 0x5A19, 0x5A16, 0x5A2D, 0x5A2E, 0x5A15,
+ 0x5A0F, 0x5A17, 0x5A0A, 0x5A1E, 0x5A33, 0x5B6C, 0x5BA7, 0x5BAD,
+ 0x5BAC, 0x5C03, 0x5C56, 0x5C54, 0x5CEC, 0x5CFF, 0x5CEE, 0x5CF1,
+ 0x5CF7, 0x5D00, 0x5CF9, 0x5E29, 0x5E28, 0x5EA8, 0x5EAE, 0x5EAA,
+ 0x5EAC, 0x5F33, 0x5F30, 0x5F67, 0x605D, 0x605A, 0x6067,
+ /* Big5-HKSCS 0xD1A1 .. 0xD1FE */
+ 0x6041, 0x60A2, 0x6088, 0x6080, 0x6092, 0x6081, 0x609D,
+ 0x6083, 0x6095, 0x609B, 0x6097, 0x6087, 0x609C, 0x608E, 0x6219,
+ 0x6246, 0x62F2, 0x6310, 0x6356, 0x632C, 0x6344, 0x6345, 0x6336,
+ 0x6343, 0x63E4, 0x6339, 0x634B, 0x634A, 0x633C, 0x6329, 0x6341,
+ 0x6334, 0x6358, 0x6354, 0x6359, 0x632D, 0x6347, 0x6333, 0x635A,
+ 0x6351, 0x6338, 0x6357, 0x6340, 0x6348, 0x654A, 0x6546, 0x65C6,
+ 0x65C3, 0x65C4, 0x65C2, 0x664A, 0x665F, 0x6647, 0x6651, 0x6712,
+ 0x6713, 0x681F, 0x681A, 0x6849, 0x6832, 0x6833, 0x683B, 0x684B,
+ 0x684F, 0x6816, 0x6831, 0x681C, 0x6835, 0x682B, 0x682D, 0x682F,
+ 0x684E, 0x6844, 0x6834, 0x681D, 0x6812, 0x6814, 0x6826, 0x6828,
+ 0x682E, 0x684D, 0x683A, 0x6825, 0x6820, 0x6B2C, 0x6B2F, 0x6B2D,
+ 0x6B31, 0x6B34, 0x6B6D, 0x8082, 0x6B88, 0x6BE6, 0x6BE4,
+ /* Big5-HKSCS 0xD240 .. 0xD27E */
+ 0x6BE8, 0x6BE3, 0x6BE2, 0x6BE7, 0x6C25, 0x6D7A, 0x6D63, 0x6D64,
+ 0x6D76, 0x6D0D, 0x6D61, 0x6D92, 0x6D58, 0x6D62, 0x6D6D, 0x6D6F,
+ 0x6D91, 0x6D8D, 0x6DEF, 0x6D7F, 0x6D86, 0x6D5E, 0x6D67, 0x6D60,
+ 0x6D97, 0x6D70, 0x6D7C, 0x6D5F, 0x6D82, 0x6D98, 0x6D2F, 0x6D68,
+ 0x6D8B, 0x6D7E, 0x6D80, 0x6D84, 0x6D16, 0x6D83, 0x6D7B, 0x6D7D,
+ 0x6D75, 0x6D90, 0x70DC, 0x70D3, 0x70D1, 0x70DD, 0x70CB, 0x7F39,
+ 0x70E2, 0x70D7, 0x70D2, 0x70DE, 0x70E0, 0x70D4, 0x70CD, 0x70C5,
+ 0x70C6, 0x70C7, 0x70DA, 0x70CE, 0x70E1, 0x7242, 0x7278,
+ /* Big5-HKSCS 0xD2A1 .. 0xD2FE */
+ 0x7277, 0x7276, 0x7300, 0x72FA, 0x72F4, 0x72FE, 0x72F6,
+ 0x72F3, 0x72FB, 0x7301, 0x73D3, 0x73D9, 0x73E5, 0x73D6, 0x73BC,
+ 0x73E7, 0x73E3, 0x73E9, 0x73DC, 0x73D2, 0x73DB, 0x73D4, 0x73DD,
+ 0x73DA, 0x73D7, 0x73D8, 0x73E8, 0x74DE, 0x74DF, 0x74F4, 0x74F5,
+ 0x7521, 0x755B, 0x755F, 0x75B0, 0x75C1, 0x75BB, 0x75C4, 0x75C0,
+ 0x75BF, 0x75B6, 0x75BA, 0x768A, 0x76C9, 0x771D, 0x771B, 0x7710,
+ 0x7713, 0x7712, 0x7723, 0x7711, 0x7715, 0x7719, 0x771A, 0x7722,
+ 0x7727, 0x7823, 0x782C, 0x7822, 0x7835, 0x782F, 0x7828, 0x782E,
+ 0x782B, 0x7821, 0x7829, 0x7833, 0x782A, 0x7831, 0x7954, 0x795B,
+ 0x794F, 0x795C, 0x7953, 0x7952, 0x7951, 0x79EB, 0x79EC, 0x79E0,
+ 0x79EE, 0x79ED, 0x79EA, 0x79DC, 0x79DE, 0x79DD, 0x7A86, 0x7A89,
+ 0x7A85, 0x7A8B, 0x7A8C, 0x7A8A, 0x7A87, 0x7AD8, 0x7B10,
+ /* Big5-HKSCS 0xD340 .. 0xD37E */
+ 0x7B04, 0x7B13, 0x7B05, 0x7B0F, 0x7B08, 0x7B0A, 0x7B0E, 0x7B09,
+ 0x7B12, 0x7C84, 0x7C91, 0x7C8A, 0x7C8C, 0x7C88, 0x7C8D, 0x7C85,
+ 0x7D1E, 0x7D1D, 0x7D11, 0x7D0E, 0x7D18, 0x7D16, 0x7D13, 0x7D1F,
+ 0x7D12, 0x7D0F, 0x7D0C, 0x7F5C, 0x7F61, 0x7F5E, 0x7F60, 0x7F5D,
+ 0x7F5B, 0x7F96, 0x7F92, 0x7FC3, 0x7FC2, 0x7FC0, 0x8016, 0x803E,
+ 0x8039, 0x80FA, 0x80F2, 0x80F9, 0x80F5, 0x8101, 0x80FB, 0x8100,
+ 0x8201, 0x822F, 0x8225, 0x8333, 0x832D, 0x8344, 0x8319, 0x8351,
+ 0x8325, 0x8356, 0x833F, 0x8341, 0x8326, 0x831C, 0x8322,
+ /* Big5-HKSCS 0xD3A1 .. 0xD3FE */
+ 0x8342, 0x834E, 0x831B, 0x832A, 0x8308, 0x833C, 0x834D,
+ 0x8316, 0x8324, 0x8320, 0x8337, 0x832F, 0x8329, 0x8347, 0x8345,
+ 0x834C, 0x8353, 0x831E, 0x832C, 0x834B, 0x8327, 0x8348, 0x8653,
+ 0x8652, 0x86A2, 0x86A8, 0x8696, 0x868D, 0x8691, 0x869E, 0x8687,
+ 0x8697, 0x8686, 0x868B, 0x869A, 0x8685, 0x86A5, 0x8699, 0x86A1,
+ 0x86A7, 0x8695, 0x8698, 0x868E, 0x869D, 0x8690, 0x8694, 0x8843,
+ 0x8844, 0x886D, 0x8875, 0x8876, 0x8872, 0x8880, 0x8871, 0x887F,
+ 0x886F, 0x8883, 0x887E, 0x8874, 0x887C, 0x8A12, 0x8C47, 0x8C57,
+ 0x8C7B, 0x8CA4, 0x8CA3, 0x8D76, 0x8D78, 0x8DB5, 0x8DB7, 0x8DB6,
+ 0x8ED1, 0x8ED3, 0x8FFE, 0x8FF5, 0x9002, 0x8FFF, 0x8FFB, 0x9004,
+ 0x8FFC, 0x8FF6, 0x90D6, 0x90E0, 0x90D9, 0x90DA, 0x90E3, 0x90DF,
+ 0x90E5, 0x90D8, 0x90DB, 0x90D7, 0x90DC, 0x90E4, 0x9150,
+ /* Big5-HKSCS 0xD440 .. 0xD47E */
+ 0x914E, 0x914F, 0x91D5, 0x91E2, 0x91DA, 0x965C, 0x965F, 0x96BC,
+ 0x98E3, 0x9ADF, 0x9B2F, 0x4E7F, 0x5070, 0x506A, 0x5061, 0x505E,
+ 0x5060, 0x5053, 0x504B, 0x505D, 0x5072, 0x5048, 0x504D, 0x5041,
+ 0x505B, 0x504A, 0x5062, 0x5015, 0x5045, 0x505F, 0x5069, 0x506B,
+ 0x5063, 0x5064, 0x5046, 0x5040, 0x506E, 0x5073, 0x5057, 0x5051,
+ 0x51D0, 0x526B, 0x526D, 0x526C, 0x526E, 0x52D6, 0x52D3, 0x532D,
+ 0x539C, 0x5575, 0x5576, 0x553C, 0x554D, 0x5550, 0x5534, 0x552A,
+ 0x5551, 0x5562, 0x5536, 0x5535, 0x5530, 0x5552, 0x5545,
+ /* Big5-HKSCS 0xD4A1 .. 0xD4FE */
+ 0x550C, 0x5532, 0x5565, 0x554E, 0x5539, 0x5548, 0x552D,
+ 0x553B, 0x5540, 0x554B, 0x570A, 0x5707, 0x57FB, 0x5814, 0x57E2,
+ 0x57F6, 0x57DC, 0x57F4, 0x5800, 0x57ED, 0x57FD, 0x5808, 0x57F8,
+ 0x580B, 0x57F3, 0x57CF, 0x5807, 0x57EE, 0x57E3, 0x57F2, 0x57E5,
+ 0x57EC, 0x57E1, 0x580E, 0x57FC, 0x5810, 0x57E7, 0x5801, 0x580C,
+ 0x57F1, 0x57E9, 0x57F0, 0x580D, 0x5804, 0x595C, 0x5A60, 0x5A58,
+ 0x5A55, 0x5A67, 0x5A5E, 0x5A38, 0x5A35, 0x5A6D, 0x5A50, 0x5A5F,
+ 0x5A65, 0x5A6C, 0x5A53, 0x5A64, 0x5A57, 0x5A43, 0x5A5D, 0x5A52,
+ 0x5A44, 0x5A5B, 0x5A48, 0x5A8E, 0x5A3E, 0x5A4D, 0x5A39, 0x5A4C,
+ 0x5A70, 0x5A69, 0x5A47, 0x5A51, 0x5A56, 0x5A42, 0x5A5C, 0x5B72,
+ 0x5B6E, 0x5BC1, 0x5BC0, 0x5C59, 0x5D1E, 0x5D0B, 0x5D1D, 0x5D1A,
+ 0x5D20, 0x5D0C, 0x5D28, 0x5D0D, 0x5D26, 0x5D25, 0x5D0F,
+ /* Big5-HKSCS 0xD540 .. 0xD57E */
+ 0x5D30, 0x5D12, 0x5D23, 0x5D1F, 0x5D2E, 0x5E3E, 0x5E34, 0x5EB1,
+ 0x5EB4, 0x5EB9, 0x5EB2, 0x5EB3, 0x5F36, 0x5F38, 0x5F9B, 0x5F96,
+ 0x5F9F, 0x608A, 0x6090, 0x6086, 0x60BE, 0x60B0, 0x60BA, 0x60D3,
+ 0x60D4, 0x60CF, 0x60E4, 0x60D9, 0x60DD, 0x60C8, 0x60B1, 0x60DB,
+ 0x60B7, 0x60CA, 0x60BF, 0x60C3, 0x60CD, 0x60C0, 0x6332, 0x6365,
+ 0x638A, 0x6382, 0x637D, 0x63BD, 0x639E, 0x63AD, 0x639D, 0x6397,
+ 0x63AB, 0x638E, 0x636F, 0x6387, 0x6390, 0x636E, 0x63AF, 0x6375,
+ 0x639C, 0x636D, 0x63AE, 0x637C, 0x63A4, 0x633B, 0x639F,
+ /* Big5-HKSCS 0xD5A1 .. 0xD5FE */
+ 0x6378, 0x6385, 0x6381, 0x6391, 0x638D, 0x6370, 0x6553,
+ 0x65CD, 0x6665, 0x6661, 0x665B, 0x6659, 0x665C, 0x6662, 0x6718,
+ 0x6879, 0x6887, 0x6890, 0x689C, 0x686D, 0x686E, 0x68AE, 0x68AB,
+ 0x6956, 0x686F, 0x68A3, 0x68AC, 0x68A9, 0x6875, 0x6874, 0x68B2,
+ 0x688F, 0x6877, 0x6892, 0x687C, 0x686B, 0x6872, 0x68AA, 0x6880,
+ 0x6871, 0x687E, 0x689B, 0x6896, 0x688B, 0x68A0, 0x6889, 0x68A4,
+ 0x6878, 0x687B, 0x6891, 0x688C, 0x688A, 0x687D, 0x6B36, 0x6B33,
+ 0x6B37, 0x6B38, 0x6B91, 0x6B8F, 0x6B8D, 0x6B8E, 0x6B8C, 0x6C2A,
+ 0x6DC0, 0x6DAB, 0x6DB4, 0x6DB3, 0x6E74, 0x6DAC, 0x6DE9, 0x6DE2,
+ 0x6DB7, 0x6DF6, 0x6DD4, 0x6E00, 0x6DC8, 0x6DE0, 0x6DDF, 0x6DD6,
+ 0x6DBE, 0x6DE5, 0x6DDC, 0x6DDD, 0x6DDB, 0x6DF4, 0x6DCA, 0x6DBD,
+ 0x6DED, 0x6DF0, 0x6DBA, 0x6DD5, 0x6DC2, 0x6DCF, 0x6DC9,
+ /* Big5-HKSCS 0xD640 .. 0xD67E */
+ 0x6DD0, 0x6DF2, 0x6DD3, 0x6DFD, 0x6DD7, 0x6DCD, 0x6DE3, 0x6DBB,
+ 0x70FA, 0x710D, 0x70F7, 0x7117, 0x70F4, 0x710C, 0x70F0, 0x7104,
+ 0x70F3, 0x7110, 0x70FC, 0x70FF, 0x7106, 0x7113, 0x7100, 0x70F8,
+ 0x70F6, 0x710B, 0x7102, 0x710E, 0x727E, 0x727B, 0x727C, 0x727F,
+ 0x731D, 0x7317, 0x7307, 0x7311, 0x7318, 0x730A, 0x7308, 0x72FF,
+ 0x730F, 0x731E, 0x7388, 0x73F6, 0x73F8, 0x73F5, 0x7404, 0x7401,
+ 0x73FD, 0x7407, 0x7400, 0x73FA, 0x73FC, 0x73FF, 0x740C, 0x740B,
+ 0x73F4, 0x7408, 0x7564, 0x7563, 0x75CE, 0x75D2, 0x75CF,
+ /* Big5-HKSCS 0xD6A1 .. 0xD6FE */
+ 0x75CB, 0x75CC, 0x75D1, 0x75D0, 0x768F, 0x7689, 0x76D3,
+ 0x7739, 0x772F, 0x772D, 0x7731, 0x7732, 0x7734, 0x7733, 0x773D,
+ 0x7725, 0x773B, 0x7735, 0x7848, 0x7852, 0x7849, 0x784D, 0x784A,
+ 0x784C, 0x7826, 0x7845, 0x7850, 0x7964, 0x7967, 0x7969, 0x796A,
+ 0x7963, 0x796B, 0x7961, 0x79BB, 0x79FA, 0x79F8, 0x79F6, 0x79F7,
+ 0x7A8F, 0x7A94, 0x7A90, 0x7B35, 0x7B47, 0x7B34, 0x7B25, 0x7B30,
+ 0x7B22, 0x7B24, 0x7B33, 0x7B18, 0x7B2A, 0x7B1D, 0x7B31, 0x7B2B,
+ 0x7B2D, 0x7B2F, 0x7B32, 0x7B38, 0x7B1A, 0x7B23, 0x7C94, 0x7C98,
+ 0x7C96, 0x7CA3, 0x7D35, 0x7D3D, 0x7D38, 0x7D36, 0x7D3A, 0x7D45,
+ 0x7D2C, 0x7D29, 0x7D41, 0x7D47, 0x7D3E, 0x7D3F, 0x7D4A, 0x7D3B,
+ 0x7D28, 0x7F63, 0x7F95, 0x7F9C, 0x7F9D, 0x7F9B, 0x7FCA, 0x7FCB,
+ 0x7FCD, 0x7FD0, 0x7FD1, 0x7FC7, 0x7FCF, 0x7FC9, 0x801F,
+ /* Big5-HKSCS 0xD740 .. 0xD77E */
+ 0x801E, 0x801B, 0x8047, 0x8043, 0x8048, 0x8118, 0x8125, 0x8119,
+ 0x811B, 0x812D, 0x811F, 0x812C, 0x811E, 0x8121, 0x8115, 0x8127,
+ 0x811D, 0x8122, 0x8211, 0x8238, 0x8233, 0x823A, 0x8234, 0x8232,
+ 0x8274, 0x8390, 0x83A3, 0x83A8, 0x838D, 0x837A, 0x8373, 0x83A4,
+ 0x8374, 0x838F, 0x8381, 0x8395, 0x8399, 0x8375, 0x8394, 0x83A9,
+ 0x837D, 0x8383, 0x838C, 0x839D, 0x839B, 0x83AA, 0x838B, 0x837E,
+ 0x83A5, 0x83AF, 0x8388, 0x8397, 0x83B0, 0x837F, 0x83A6, 0x8387,
+ 0x83AE, 0x8376, 0x839A, 0x8659, 0x8656, 0x86BF, 0x86B7,
+ /* Big5-HKSCS 0xD7A1 .. 0xD7FE */
+ 0x86C2, 0x86C1, 0x86C5, 0x86BA, 0x86B0, 0x86C8, 0x86B9,
+ 0x86B3, 0x86B8, 0x86CC, 0x86B4, 0x86BB, 0x86BC, 0x86C3, 0x86BD,
+ 0x86BE, 0x8852, 0x8889, 0x8895, 0x88A8, 0x88A2, 0x88AA, 0x889A,
+ 0x8891, 0x88A1, 0x889F, 0x8898, 0x88A7, 0x8899, 0x889B, 0x8897,
+ 0x88A4, 0x88AC, 0x888C, 0x8893, 0x888E, 0x8982, 0x89D6, 0x89D9,
+ 0x89D5, 0x8A30, 0x8A27, 0x8A2C, 0x8A1E, 0x8C39, 0x8C3B, 0x8C5C,
+ 0x8C5D, 0x8C7D, 0x8CA5, 0x8D7D, 0x8D7B, 0x8D79, 0x8DBC, 0x8DC2,
+ 0x8DB9, 0x8DBF, 0x8DC1, 0x8ED8, 0x8EDE, 0x8EDD, 0x8EDC, 0x8ED7,
+ 0x8EE0, 0x8EE1, 0x9024, 0x900B, 0x9011, 0x901C, 0x900C, 0x9021,
+ 0x90EF, 0x90EA, 0x90F0, 0x90F4, 0x90F2, 0x90F3, 0x90D4, 0x90EB,
+ 0x90EC, 0x90E9, 0x9156, 0x9158, 0x915A, 0x9153, 0x9155, 0x91EC,
+ 0x91F4, 0x91F1, 0x91F3, 0x91F8, 0x91E4, 0x91F9, 0x91EA,
+ /* Big5-HKSCS 0xD840 .. 0xD87E */
+ 0x91EB, 0x91F7, 0x91E8, 0x91EE, 0x957A, 0x9586, 0x9588, 0x967C,
+ 0x966D, 0x966B, 0x9671, 0x966F, 0x96BF, 0x976A, 0x9804, 0x98E5,
+ 0x9997, 0x509B, 0x5095, 0x5094, 0x509E, 0x508B, 0x50A3, 0x5083,
+ 0x508C, 0x508E, 0x509D, 0x5068, 0x509C, 0x5092, 0x5082, 0x5087,
+ 0x515F, 0x51D4, 0x5312, 0x5311, 0x53A4, 0x53A7, 0x5591, 0x55A8,
+ 0x55A5, 0x55AD, 0x5577, 0x5645, 0x55A2, 0x5593, 0x5588, 0x558F,
+ 0x55B5, 0x5581, 0x55A3, 0x5592, 0x55A4, 0x557D, 0x558C, 0x55A6,
+ 0x557F, 0x5595, 0x55A1, 0x558E, 0x570C, 0x5829, 0x5837,
+ /* Big5-HKSCS 0xD8A1 .. 0xD8FE */
+ 0x5819, 0x581E, 0x5827, 0x5823, 0x5828, 0x57F5, 0x5848,
+ 0x5825, 0x581C, 0x581B, 0x5833, 0x583F, 0x5836, 0x582E, 0x5839,
+ 0x5838, 0x582D, 0x582C, 0x583B, 0x5961, 0x5AAF, 0x5A94, 0x5A9F,
+ 0x5A7A, 0x5AA2, 0x5A9E, 0x5A78, 0x5AA6, 0x5A7C, 0x5AA5, 0x5AAC,
+ 0x5A95, 0x5AAE, 0x5A37, 0x5A84, 0x5A8A, 0x5A97, 0x5A83, 0x5A8B,
+ 0x5AA9, 0x5A7B, 0x5A7D, 0x5A8C, 0x5A9C, 0x5A8F, 0x5A93, 0x5A9D,
+ 0x5BEA, 0x5BCD, 0x5BCB, 0x5BD4, 0x5BD1, 0x5BCA, 0x5BCE, 0x5C0C,
+ 0x5C30, 0x5D37, 0x5D43, 0x5D6B, 0x5D41, 0x5D4B, 0x5D3F, 0x5D35,
+ 0x5D51, 0x5D4E, 0x5D55, 0x5D33, 0x5D3A, 0x5D52, 0x5D3D, 0x5D31,
+ 0x5D59, 0x5D42, 0x5D39, 0x5D49, 0x5D38, 0x5D3C, 0x5D32, 0x5D36,
+ 0x5D40, 0x5D45, 0x5E44, 0x5E41, 0x5F58, 0x5FA6, 0x5FA5, 0x5FAB,
+ 0x60C9, 0x60B9, 0x60CC, 0x60E2, 0x60CE, 0x60C4, 0x6114,
+ /* Big5-HKSCS 0xD940 .. 0xD97E */
+ 0x60F2, 0x610A, 0x6116, 0x6105, 0x60F5, 0x6113, 0x60F8, 0x60FC,
+ 0x60FE, 0x60C1, 0x6103, 0x6118, 0x611D, 0x6110, 0x60FF, 0x6104,
+ 0x610B, 0x624A, 0x6394, 0x63B1, 0x63B0, 0x63CE, 0x63E5, 0x63E8,
+ 0x63EF, 0x63C3, 0x649D, 0x63F3, 0x63CA, 0x63E0, 0x63F6, 0x63D5,
+ 0x63F2, 0x63F5, 0x6461, 0x63DF, 0x63BE, 0x63DD, 0x63DC, 0x63C4,
+ 0x63D8, 0x63D3, 0x63C2, 0x63C7, 0x63CC, 0x63CB, 0x63C8, 0x63F0,
+ 0x63D7, 0x63D9, 0x6532, 0x6567, 0x656A, 0x6564, 0x655C, 0x6568,
+ 0x6565, 0x658C, 0x659D, 0x659E, 0x65AE, 0x65D0, 0x65D2,
+ /* Big5-HKSCS 0xD9A1 .. 0xD9FE */
+ 0x667C, 0x666C, 0x667B, 0x6680, 0x6671, 0x6679, 0x666A,
+ 0x6672, 0x6701, 0x690C, 0x68D3, 0x6904, 0x68DC, 0x692A, 0x68EC,
+ 0x68EA, 0x68F1, 0x690F, 0x68D6, 0x68F7, 0x68EB, 0x68E4, 0x68F6,
+ 0x6913, 0x6910, 0x68F3, 0x68E1, 0x6907, 0x68CC, 0x6908, 0x6970,
+ 0x68B4, 0x6911, 0x68EF, 0x68C6, 0x6914, 0x68F8, 0x68D0, 0x68FD,
+ 0x68FC, 0x68E8, 0x690B, 0x690A, 0x6917, 0x68CE, 0x68C8, 0x68DD,
+ 0x68DE, 0x68E6, 0x68F4, 0x68D1, 0x6906, 0x68D4, 0x68E9, 0x6915,
+ 0x6925, 0x68C7, 0x6B39, 0x6B3B, 0x6B3F, 0x6B3C, 0x6B94, 0x6B97,
+ 0x6B99, 0x6B95, 0x6BBD, 0x6BF0, 0x6BF2, 0x6BF3, 0x6C30, 0x6DFC,
+ 0x6E46, 0x6E47, 0x6E1F, 0x6E49, 0x6E88, 0x6E3C, 0x6E3D, 0x6E45,
+ 0x6E62, 0x6E2B, 0x6E3F, 0x6E41, 0x6E5D, 0x6E73, 0x6E1C, 0x6E33,
+ 0x6E4B, 0x6E40, 0x6E51, 0x6E3B, 0x6E03, 0x6E2E, 0x6E5E,
+ /* Big5-HKSCS 0xDA40 .. 0xDA7E */
+ 0x6E68, 0x6E5C, 0x6E61, 0x6E31, 0x6E28, 0x6E60, 0x6E71, 0x6E6B,
+ 0x6E39, 0x6E22, 0x6E30, 0x6E53, 0x6E65, 0x6E27, 0x6E78, 0x6E64,
+ 0x6E77, 0x6E55, 0x6E79, 0x6E52, 0x6E66, 0x6E35, 0x6E36, 0x6E5A,
+ 0x7120, 0x711E, 0x712F, 0x70FB, 0x712E, 0x7131, 0x7123, 0x7125,
+ 0x7122, 0x7132, 0x711F, 0x7128, 0x713A, 0x711B, 0x724B, 0x725A,
+ 0x7288, 0x7289, 0x7286, 0x7285, 0x728B, 0x7312, 0x730B, 0x7330,
+ 0x7322, 0x7331, 0x7333, 0x7327, 0x7332, 0x732D, 0x7326, 0x7323,
+ 0x7335, 0x730C, 0x742E, 0x742C, 0x7430, 0x742B, 0x7416,
+ /* Big5-HKSCS 0xDAA1 .. 0xDAFE */
+ 0x741A, 0x7421, 0x742D, 0x7431, 0x7424, 0x7423, 0x741D,
+ 0x7429, 0x7420, 0x7432, 0x74FB, 0x752F, 0x756F, 0x756C, 0x75E7,
+ 0x75DA, 0x75E1, 0x75E6, 0x75DD, 0x75DF, 0x75E4, 0x75D7, 0x7695,
+ 0x7692, 0x76DA, 0x7746, 0x7747, 0x7744, 0x774D, 0x7745, 0x774A,
+ 0x774E, 0x774B, 0x774C, 0x77DE, 0x77EC, 0x7860, 0x7864, 0x7865,
+ 0x785C, 0x786D, 0x7871, 0x786A, 0x786E, 0x7870, 0x7869, 0x7868,
+ 0x785E, 0x7862, 0x7974, 0x7973, 0x7972, 0x7970, 0x7A02, 0x7A0A,
+ 0x7A03, 0x7A0C, 0x7A04, 0x7A99, 0x7AE6, 0x7AE4, 0x7B4A, 0x7B3B,
+ 0x7B44, 0x7B48, 0x7B4C, 0x7B4E, 0x7B40, 0x7B58, 0x7B45, 0x7CA2,
+ 0x7C9E, 0x7CA8, 0x7CA1, 0x7D58, 0x7D6F, 0x7D63, 0x7D53, 0x7D56,
+ 0x7D67, 0x7D6A, 0x7D4F, 0x7D6D, 0x7D5C, 0x7D6B, 0x7D52, 0x7D54,
+ 0x7D69, 0x7D51, 0x7D5F, 0x7D4E, 0x7F3E, 0x7F3F, 0x7F65,
+ /* Big5-HKSCS 0xDB40 .. 0xDB7E */
+ 0x7F66, 0x7FA2, 0x7FA0, 0x7FA1, 0x7FD7, 0x8051, 0x804F, 0x8050,
+ 0x80FE, 0x80D4, 0x8143, 0x814A, 0x8152, 0x814F, 0x8147, 0x813D,
+ 0x814D, 0x813A, 0x81E6, 0x81EE, 0x81F7, 0x81F8, 0x81F9, 0x8204,
+ 0x823C, 0x823D, 0x823F, 0x8275, 0x833B, 0x83CF, 0x83F9, 0x8423,
+ 0x83C0, 0x83E8, 0x8412, 0x83E7, 0x83E4, 0x83FC, 0x83F6, 0x8410,
+ 0x83C6, 0x83C8, 0x83EB, 0x83E3, 0x83BF, 0x8401, 0x83DD, 0x83E5,
+ 0x83D8, 0x83FF, 0x83E1, 0x83CB, 0x83CE, 0x83D6, 0x83F5, 0x83C9,
+ 0x8409, 0x840F, 0x83DE, 0x8411, 0x8406, 0x83C2, 0x83F3,
+ /* Big5-HKSCS 0xDBA1 .. 0xDBFE */
+ 0x83D5, 0x83FA, 0x83C7, 0x83D1, 0x83EA, 0x8413, 0x83C3,
+ 0x83EC, 0x83EE, 0x83C4, 0x83FB, 0x83D7, 0x83E2, 0x841B, 0x83DB,
+ 0x83FE, 0x86D8, 0x86E2, 0x86E6, 0x86D3, 0x86E3, 0x86DA, 0x86EA,
+ 0x86DD, 0x86EB, 0x86DC, 0x86EC, 0x86E9, 0x86D7, 0x86E8, 0x86D1,
+ 0x8848, 0x8856, 0x8855, 0x88BA, 0x88D7, 0x88B9, 0x88B8, 0x88C0,
+ 0x88BE, 0x88B6, 0x88BC, 0x88B7, 0x88BD, 0x88B2, 0x8901, 0x88C9,
+ 0x8995, 0x8998, 0x8997, 0x89DD, 0x89DA, 0x89DB, 0x8A4E, 0x8A4D,
+ 0x8A39, 0x8A59, 0x8A40, 0x8A57, 0x8A58, 0x8A44, 0x8A45, 0x8A52,
+ 0x8A48, 0x8A51, 0x8A4A, 0x8A4C, 0x8A4F, 0x8C5F, 0x8C81, 0x8C80,
+ 0x8CBA, 0x8CBE, 0x8CB0, 0x8CB9, 0x8CB5, 0x8D84, 0x8D80, 0x8D89,
+ 0x8DD8, 0x8DD3, 0x8DCD, 0x8DC7, 0x8DD6, 0x8DDC, 0x8DCF, 0x8DD5,
+ 0x8DD9, 0x8DC8, 0x8DD7, 0x8DC5, 0x8EEF, 0x8EF7, 0x8EFA,
+ /* Big5-HKSCS 0xDC40 .. 0xDC7E */
+ 0x8EF9, 0x8EE6, 0x8EEE, 0x8EE5, 0x8EF5, 0x8EE7, 0x8EE8, 0x8EF6,
+ 0x8EEB, 0x8EF1, 0x8EEC, 0x8EF4, 0x8EE9, 0x902D, 0x9034, 0x902F,
+ 0x9106, 0x912C, 0x9104, 0x90FF, 0x90FC, 0x9108, 0x90F9, 0x90FB,
+ 0x9101, 0x9100, 0x9107, 0x9105, 0x9103, 0x9161, 0x9164, 0x915F,
+ 0x9162, 0x9160, 0x9201, 0x920A, 0x9225, 0x9203, 0x921A, 0x9226,
+ 0x920F, 0x920C, 0x9200, 0x9212, 0x91FF, 0x91FD, 0x9206, 0x9204,
+ 0x9227, 0x9202, 0x921C, 0x9224, 0x9219, 0x9217, 0x9205, 0x9216,
+ 0x957B, 0x958D, 0x958C, 0x9590, 0x9687, 0x967E, 0x9688,
+ /* Big5-HKSCS 0xDCA1 .. 0xDCFE */
+ 0x9689, 0x9683, 0x9680, 0x96C2, 0x96C8, 0x96C3, 0x96F1,
+ 0x96F0, 0x976C, 0x9770, 0x976E, 0x9807, 0x98A9, 0x98EB, 0x9CE6,
+ 0x9EF9, 0x4E83, 0x4E84, 0x4EB6, 0x50BD, 0x50BF, 0x50C6, 0x50AE,
+ 0x50C4, 0x50CA, 0x50B4, 0x50C8, 0x50C2, 0x50B0, 0x50C1, 0x50BA,
+ 0x50B1, 0x50CB, 0x50C9, 0x50B6, 0x50B8, 0x51D7, 0x527A, 0x5278,
+ 0x527B, 0x527C, 0x55C3, 0x55DB, 0x55CC, 0x55D0, 0x55CB, 0x55CA,
+ 0x55DD, 0x55C0, 0x55D4, 0x55C4, 0x55E9, 0x55BF, 0x55D2, 0x558D,
+ 0x55CF, 0x55D5, 0x55E2, 0x55D6, 0x55C8, 0x55F2, 0x55CD, 0x55D9,
+ 0x55C2, 0x5714, 0x5853, 0x5868, 0x5864, 0x584F, 0x584D, 0x5849,
+ 0x586F, 0x5855, 0x584E, 0x585D, 0x5859, 0x5865, 0x585B, 0x583D,
+ 0x5863, 0x5871, 0x58FC, 0x5AC7, 0x5AC4, 0x5ACB, 0x5ABA, 0x5AB8,
+ 0x5AB1, 0x5AB5, 0x5AB0, 0x5ABF, 0x5AC8, 0x5ABB, 0x5AC6,
+ /* Big5-HKSCS 0xDD40 .. 0xDD7E */
+ 0x5AB7, 0x5AC0, 0x5ACA, 0x5AB4, 0x5AB6, 0x5ACD, 0x5AB9, 0x5A90,
+ 0x5BD6, 0x5BD8, 0x5BD9, 0x5C1F, 0x5C33, 0x5D71, 0x5D63, 0x5D4A,
+ 0x5D65, 0x5D72, 0x5D6C, 0x5D5E, 0x5D68, 0x5D67, 0x5D62, 0x5DF0,
+ 0x5E4F, 0x5E4E, 0x5E4A, 0x5E4D, 0x5E4B, 0x5EC5, 0x5ECC, 0x5EC6,
+ 0x5ECB, 0x5EC7, 0x5F40, 0x5FAF, 0x5FAD, 0x60F7, 0x6149, 0x614A,
+ 0x612B, 0x6145, 0x6136, 0x6132, 0x612E, 0x6146, 0x612F, 0x614F,
+ 0x6129, 0x6140, 0x6220, 0x9168, 0x6223, 0x6225, 0x6224, 0x63C5,
+ 0x63F1, 0x63EB, 0x6410, 0x6412, 0x6409, 0x6420, 0x6424,
+ /* Big5-HKSCS 0xDDA1 .. 0xDDFE */
+ 0x6433, 0x6443, 0x641F, 0x6415, 0x6418, 0x6439, 0x6437,
+ 0x6422, 0x6423, 0x640C, 0x6426, 0x6430, 0x6428, 0x6441, 0x6435,
+ 0x642F, 0x640A, 0x641A, 0x6440, 0x6425, 0x6427, 0x640B, 0x63E7,
+ 0x641B, 0x642E, 0x6421, 0x640E, 0x656F, 0x6592, 0x65D3, 0x6686,
+ 0x668C, 0x6695, 0x6690, 0x668B, 0x668A, 0x6699, 0x6694, 0x6678,
+ 0x6720, 0x6966, 0x695F, 0x6938, 0x694E, 0x6962, 0x6971, 0x693F,
+ 0x6945, 0x696A, 0x6939, 0x6942, 0x6957, 0x6959, 0x697A, 0x6948,
+ 0x6949, 0x6935, 0x696C, 0x6933, 0x693D, 0x6965, 0x68F0, 0x6978,
+ 0x6934, 0x6969, 0x6940, 0x696F, 0x6944, 0x6976, 0x6958, 0x6941,
+ 0x6974, 0x694C, 0x693B, 0x694B, 0x6937, 0x695C, 0x694F, 0x6951,
+ 0x6932, 0x6952, 0x692F, 0x697B, 0x693C, 0x6B46, 0x6B45, 0x6B43,
+ 0x6B42, 0x6B48, 0x6B41, 0x6B9B, 0xFA0D, 0x6BFB, 0x6BFC,
+ /* Big5-HKSCS 0xDE40 .. 0xDE7E */
+ 0x6BF9, 0x6BF7, 0x6BF8, 0x6E9B, 0x6ED6, 0x6EC8, 0x6E8F, 0x6EC0,
+ 0x6E9F, 0x6E93, 0x6E94, 0x6EA0, 0x6EB1, 0x6EB9, 0x6EC6, 0x6ED2,
+ 0x6EBD, 0x6EC1, 0x6E9E, 0x6EC9, 0x6EB7, 0x6EB0, 0x6ECD, 0x6EA6,
+ 0x6ECF, 0x6EB2, 0x6EBE, 0x6EC3, 0x6EDC, 0x6ED8, 0x6E99, 0x6E92,
+ 0x6E8E, 0x6E8D, 0x6EA4, 0x6EA1, 0x6EBF, 0x6EB3, 0x6ED0, 0x6ECA,
+ 0x6E97, 0x6EAE, 0x6EA3, 0x7147, 0x7154, 0x7152, 0x7163, 0x7160,
+ 0x7141, 0x715D, 0x7162, 0x7172, 0x7178, 0x716A, 0x7161, 0x7142,
+ 0x7158, 0x7143, 0x714B, 0x7170, 0x715F, 0x7150, 0x7153,
+ /* Big5-HKSCS 0xDEA1 .. 0xDEFE */
+ 0x7144, 0x714D, 0x715A, 0x724F, 0x728D, 0x728C, 0x7291,
+ 0x7290, 0x728E, 0x733C, 0x7342, 0x733B, 0x733A, 0x7340, 0x734A,
+ 0x7349, 0x7444, 0x744A, 0x744B, 0x7452, 0x7451, 0x7457, 0x7440,
+ 0x744F, 0x7450, 0x744E, 0x7442, 0x7446, 0x744D, 0x7454, 0x74E1,
+ 0x74FF, 0x74FE, 0x74FD, 0x751D, 0x7579, 0x7577, 0x6983, 0x75EF,
+ 0x760F, 0x7603, 0x75F7, 0x75FE, 0x75FC, 0x75F9, 0x75F8, 0x7610,
+ 0x75FB, 0x75F6, 0x75ED, 0x75F5, 0x75FD, 0x7699, 0x76B5, 0x76DD,
+ 0x7755, 0x775F, 0x7760, 0x7752, 0x7756, 0x775A, 0x7769, 0x7767,
+ 0x7754, 0x7759, 0x776D, 0x77E0, 0x7887, 0x789A, 0x7894, 0x788F,
+ 0x7884, 0x7895, 0x7885, 0x7886, 0x78A1, 0x7883, 0x7879, 0x7899,
+ 0x7880, 0x7896, 0x787B, 0x797C, 0x7982, 0x797D, 0x7979, 0x7A11,
+ 0x7A18, 0x7A19, 0x7A12, 0x7A17, 0x7A15, 0x7A22, 0x7A13,
+ /* Big5-HKSCS 0xDF40 .. 0xDF7E */
+ 0x7A1B, 0x7A10, 0x7AA3, 0x7AA2, 0x7A9E, 0x7AEB, 0x7B66, 0x7B64,
+ 0x7B6D, 0x7B74, 0x7B69, 0x7B72, 0x7B65, 0x7B73, 0x7B71, 0x7B70,
+ 0x7B61, 0x7B78, 0x7B76, 0x7B63, 0x7CB2, 0x7CB4, 0x7CAF, 0x7D88,
+ 0x7D86, 0x7D80, 0x7D8D, 0x7D7F, 0x7D85, 0x7D7A, 0x7D8E, 0x7D7B,
+ 0x7D83, 0x7D7C, 0x7D8C, 0x7D94, 0x7D84, 0x7D7D, 0x7D92, 0x7F6D,
+ 0x7F6B, 0x7F67, 0x7F68, 0x7F6C, 0x7FA6, 0x7FA5, 0x7FA7, 0x7FDB,
+ 0x7FDC, 0x8021, 0x8164, 0x8160, 0x8177, 0x815C, 0x8169, 0x815B,
+ 0x8162, 0x8172, 0x6721, 0x815E, 0x8176, 0x8167, 0x816F,
+ /* Big5-HKSCS 0xDFA1 .. 0xDFFE */
+ 0x8144, 0x8161, 0x821D, 0x8249, 0x8244, 0x8240, 0x8242,
+ 0x8245, 0x84F1, 0x843F, 0x8456, 0x8476, 0x8479, 0x848F, 0x848D,
+ 0x8465, 0x8451, 0x8440, 0x8486, 0x8467, 0x8430, 0x844D, 0x847D,
+ 0x845A, 0x8459, 0x8474, 0x8473, 0x845D, 0x8507, 0x845E, 0x8437,
+ 0x843A, 0x8434, 0x847A, 0x8443, 0x8478, 0x8432, 0x8445, 0x8429,
+ 0x83D9, 0x844B, 0x842F, 0x8442, 0x842D, 0x845F, 0x8470, 0x8439,
+ 0x844E, 0x844C, 0x8452, 0x846F, 0x84C5, 0x848E, 0x843B, 0x8447,
+ 0x8436, 0x8433, 0x8468, 0x847E, 0x8444, 0x842B, 0x8460, 0x8454,
+ 0x846E, 0x8450, 0x870B, 0x8704, 0x86F7, 0x870C, 0x86FA, 0x86D6,
+ 0x86F5, 0x874D, 0x86F8, 0x870E, 0x8709, 0x8701, 0x86F6, 0x870D,
+ 0x8705, 0x88D6, 0x88CB, 0x88CD, 0x88CE, 0x88DE, 0x88DB, 0x88DA,
+ 0x88CC, 0x88D0, 0x8985, 0x899B, 0x89DF, 0x89E5, 0x89E4,
+ /* Big5-HKSCS 0xE040 .. 0xE07E */
+ 0x89E1, 0x89E0, 0x89E2, 0x89DC, 0x89E6, 0x8A76, 0x8A86, 0x8A7F,
+ 0x8A61, 0x8A3F, 0x8A77, 0x8A82, 0x8A84, 0x8A75, 0x8A83, 0x8A81,
+ 0x8A74, 0x8A7A, 0x8C3C, 0x8C4B, 0x8C4A, 0x8C65, 0x8C64, 0x8C66,
+ 0x8C86, 0x8C84, 0x8C85, 0x8CCC, 0x8D68, 0x8D69, 0x8D91, 0x8D8C,
+ 0x8D8E, 0x8D8F, 0x8D8D, 0x8D93, 0x8D94, 0x8D90, 0x8D92, 0x8DF0,
+ 0x8DE0, 0x8DEC, 0x8DF1, 0x8DEE, 0x8DD0, 0x8DE9, 0x8DE3, 0x8DE2,
+ 0x8DE7, 0x8DF2, 0x8DEB, 0x8DF4, 0x8F06, 0x8EFF, 0x8F01, 0x8F00,
+ 0x8F05, 0x8F07, 0x8F08, 0x8F02, 0x8F0B, 0x9052, 0x903F,
+ /* Big5-HKSCS 0xE0A1 .. 0xE0FE */
+ 0x9044, 0x9049, 0x903D, 0x9110, 0x910D, 0x910F, 0x9111,
+ 0x9116, 0x9114, 0x910B, 0x910E, 0x916E, 0x916F, 0x9248, 0x9252,
+ 0x9230, 0x923A, 0x9266, 0x9233, 0x9265, 0x925E, 0x9283, 0x922E,
+ 0x924A, 0x9246, 0x926D, 0x926C, 0x924F, 0x9260, 0x9267, 0x926F,
+ 0x9236, 0x9261, 0x9270, 0x9231, 0x9254, 0x9263, 0x9250, 0x9272,
+ 0x924E, 0x9253, 0x924C, 0x9256, 0x9232, 0x959F, 0x959C, 0x959E,
+ 0x959B, 0x9692, 0x9693, 0x9691, 0x9697, 0x96CE, 0x96FA, 0x96FD,
+ 0x96F8, 0x96F5, 0x9773, 0x9777, 0x9778, 0x9772, 0x980F, 0x980D,
+ 0x980E, 0x98AC, 0x98F6, 0x98F9, 0x99AF, 0x99B2, 0x99B0, 0x99B5,
+ 0x9AAD, 0x9AAB, 0x9B5B, 0x9CEA, 0x9CED, 0x9CE7, 0x9E80, 0x9EFD,
+ 0x50E6, 0x50D4, 0x50D7, 0x50E8, 0x50F3, 0x50DB, 0x50EA, 0x50DD,
+ 0x50E4, 0x50D3, 0x50EC, 0x50F0, 0x50EF, 0x50E3, 0x50E0,
+ /* Big5-HKSCS 0xE140 .. 0xE17E */
+ 0x51D8, 0x5280, 0x5281, 0x52E9, 0x52EB, 0x5330, 0x53AC, 0x5627,
+ 0x5615, 0x560C, 0x5612, 0x55FC, 0x560F, 0x561C, 0x5601, 0x5613,
+ 0x5602, 0x55FA, 0x561D, 0x5604, 0x55FF, 0x55F9, 0x5889, 0x587C,
+ 0x5890, 0x5898, 0x5886, 0x5881, 0x587F, 0x5874, 0x588B, 0x587A,
+ 0x5887, 0x5891, 0x588E, 0x5876, 0x5882, 0x5888, 0x587B, 0x5894,
+ 0x588F, 0x58FE, 0x596B, 0x5ADC, 0x5AEE, 0x5AE5, 0x5AD5, 0x5AEA,
+ 0x5ADA, 0x5AED, 0x5AEB, 0x5AF3, 0x5AE2, 0x5AE0, 0x5ADB, 0x5AEC,
+ 0x5ADE, 0x5ADD, 0x5AD9, 0x5AE8, 0x5ADF, 0x5B77, 0x5BE0,
+ /* Big5-HKSCS 0xE1A1 .. 0xE1FE */
+ 0x5BE3, 0x5C63, 0x5D82, 0x5D80, 0x5D7D, 0x5D86, 0x5D7A,
+ 0x5D81, 0x5D77, 0x5D8A, 0x5D89, 0x5D88, 0x5D7E, 0x5D7C, 0x5D8D,
+ 0x5D79, 0x5D7F, 0x5E58, 0x5E59, 0x5E53, 0x5ED8, 0x5ED1, 0x5ED7,
+ 0x5ECE, 0x5EDC, 0x5ED5, 0x5ED9, 0x5ED2, 0x5ED4, 0x5F44, 0x5F43,
+ 0x5F6F, 0x5FB6, 0x612C, 0x6128, 0x6141, 0x615E, 0x6171, 0x6173,
+ 0x6152, 0x6153, 0x6172, 0x616C, 0x6180, 0x6174, 0x6154, 0x617A,
+ 0x615B, 0x6165, 0x613B, 0x616A, 0x6161, 0x6156, 0x6229, 0x6227,
+ 0x622B, 0x642B, 0x644D, 0x645B, 0x645D, 0x6474, 0x6476, 0x6472,
+ 0x6473, 0x647D, 0x6475, 0x6466, 0x64A6, 0x644E, 0x6482, 0x645E,
+ 0x645C, 0x644B, 0x6453, 0x6460, 0x6450, 0x647F, 0x643F, 0x646C,
+ 0x646B, 0x6459, 0x6465, 0x6477, 0x6573, 0x65A0, 0x66A1, 0x66A0,
+ 0x669F, 0x6705, 0x6704, 0x6722, 0x69B1, 0x69B6, 0x69C9,
+ /* Big5-HKSCS 0xE240 .. 0xE27E */
+ 0x69A0, 0x69CE, 0x6996, 0x69B0, 0x69AC, 0x69BC, 0x6991, 0x6999,
+ 0x698E, 0x69A7, 0x698D, 0x69A9, 0x69BE, 0x69AF, 0x69BF, 0x69C4,
+ 0x69BD, 0x69A4, 0x69D4, 0x69B9, 0x69CA, 0x699A, 0x69CF, 0x69B3,
+ 0x6993, 0x69AA, 0x69A1, 0x699E, 0x69D9, 0x6997, 0x6990, 0x69C2,
+ 0x69B5, 0x69A5, 0x69C6, 0x6B4A, 0x6B4D, 0x6B4B, 0x6B9E, 0x6B9F,
+ 0x6BA0, 0x6BC3, 0x6BC4, 0x6BFE, 0x6ECE, 0x6EF5, 0x6EF1, 0x6F03,
+ 0x6F25, 0x6EF8, 0x6F37, 0x6EFB, 0x6F2E, 0x6F09, 0x6F4E, 0x6F19,
+ 0x6F1A, 0x6F27, 0x6F18, 0x6F3B, 0x6F12, 0x6EED, 0x6F0A,
+ /* Big5-HKSCS 0xE2A1 .. 0xE2FE */
+ 0x6F36, 0x6F73, 0x6EF9, 0x6EEE, 0x6F2D, 0x6F40, 0x6F30,
+ 0x6F3C, 0x6F35, 0x6EEB, 0x6F07, 0x6F0E, 0x6F43, 0x6F05, 0x6EFD,
+ 0x6EF6, 0x6F39, 0x6F1C, 0x6EFC, 0x6F3A, 0x6F1F, 0x6F0D, 0x6F1E,
+ 0x6F08, 0x6F21, 0x7187, 0x7190, 0x7189, 0x7180, 0x7185, 0x7182,
+ 0x718F, 0x717B, 0x7186, 0x7181, 0x7197, 0x7244, 0x7253, 0x7297,
+ 0x7295, 0x7293, 0x7343, 0x734D, 0x7351, 0x734C, 0x7462, 0x7473,
+ 0x7471, 0x7475, 0x7472, 0x7467, 0x746E, 0x7500, 0x7502, 0x7503,
+ 0x757D, 0x7590, 0x7616, 0x7608, 0x760C, 0x7615, 0x7611, 0x760A,
+ 0x7614, 0x76B8, 0x7781, 0x777C, 0x7785, 0x7782, 0x776E, 0x7780,
+ 0x776F, 0x777E, 0x7783, 0x78B2, 0x78AA, 0x78B4, 0x78AD, 0x78A8,
+ 0x787E, 0x78AB, 0x789E, 0x78A5, 0x78A0, 0x78AC, 0x78A2, 0x78A4,
+ 0x7998, 0x798A, 0x798B, 0x7996, 0x7995, 0x7994, 0x7993,
+ /* Big5-HKSCS 0xE340 .. 0xE37E */
+ 0x7997, 0x7988, 0x7992, 0x7990, 0x7A2B, 0x7A4A, 0x7A30, 0x7A2F,
+ 0x7A28, 0x7A26, 0x7AA8, 0x7AAB, 0x7AAC, 0x7AEE, 0x7B88, 0x7B9C,
+ 0x7B8A, 0x7B91, 0x7B90, 0x7B96, 0x7B8D, 0x7B8C, 0x7B9B, 0x7B8E,
+ 0x7B85, 0x7B98, 0x5284, 0x7B99, 0x7BA4, 0x7B82, 0x7CBB, 0x7CBF,
+ 0x7CBC, 0x7CBA, 0x7DA7, 0x7DB7, 0x7DC2, 0x7DA3, 0x7DAA, 0x7DC1,
+ 0x7DC0, 0x7DC5, 0x7D9D, 0x7DCE, 0x7DC4, 0x7DC6, 0x7DCB, 0x7DCC,
+ 0x7DAF, 0x7DB9, 0x7D96, 0x7DBC, 0x7D9F, 0x7DA6, 0x7DAE, 0x7DA9,
+ 0x7DA1, 0x7DC9, 0x7F73, 0x7FE2, 0x7FE3, 0x7FE5, 0x7FDE,
+ /* Big5-HKSCS 0xE3A1 .. 0xE3FE */
+ 0x8024, 0x805D, 0x805C, 0x8189, 0x8186, 0x8183, 0x8187,
+ 0x818D, 0x818C, 0x818B, 0x8215, 0x8497, 0x84A4, 0x84A1, 0x849F,
+ 0x84BA, 0x84CE, 0x84C2, 0x84AC, 0x84AE, 0x84AB, 0x84B9, 0x84B4,
+ 0x84C1, 0x84CD, 0x84AA, 0x849A, 0x84B1, 0x84D0, 0x849D, 0x84A7,
+ 0x84BB, 0x84A2, 0x8494, 0x84C7, 0x84CC, 0x849B, 0x84A9, 0x84AF,
+ 0x84A8, 0x84D6, 0x8498, 0x84B6, 0x84CF, 0x84A0, 0x84D7, 0x84D4,
+ 0x84D2, 0x84DB, 0x84B0, 0x8491, 0x8661, 0x8733, 0x8723, 0x8728,
+ 0x876B, 0x8740, 0x872E, 0x871E, 0x8721, 0x8719, 0x871B, 0x8743,
+ 0x872C, 0x8741, 0x873E, 0x8746, 0x8720, 0x8732, 0x872A, 0x872D,
+ 0x873C, 0x8712, 0x873A, 0x8731, 0x8735, 0x8742, 0x8726, 0x8727,
+ 0x8738, 0x8724, 0x871A, 0x8730, 0x8711, 0x88F7, 0x88E7, 0x88F1,
+ 0x88F2, 0x88FA, 0x88FE, 0x88EE, 0x88FC, 0x88F6, 0x88FB,
+ /* Big5-HKSCS 0xE440 .. 0xE47E */
+ 0x88F0, 0x88EC, 0x88EB, 0x899D, 0x89A1, 0x899F, 0x899E, 0x89E9,
+ 0x89EB, 0x89E8, 0x8AAB, 0x8A99, 0x8A8B, 0x8A92, 0x8A8F, 0x8A96,
+ 0x8C3D, 0x8C68, 0x8C69, 0x8CD5, 0x8CCF, 0x8CD7, 0x8D96, 0x8E09,
+ 0x8E02, 0x8DFF, 0x8E0D, 0x8DFD, 0x8E0A, 0x8E03, 0x8E07, 0x8E06,
+ 0x8E05, 0x8DFE, 0x8E00, 0x8E04, 0x8F10, 0x8F11, 0x8F0E, 0x8F0D,
+ 0x9123, 0x911C, 0x9120, 0x9122, 0x911F, 0x911D, 0x911A, 0x9124,
+ 0x9121, 0x911B, 0x917A, 0x9172, 0x9179, 0x9173, 0x92A5, 0x92A4,
+ 0x9276, 0x929B, 0x927A, 0x92A0, 0x9294, 0x92AA, 0x928D,
+ /* Big5-HKSCS 0xE4A1 .. 0xE4FE */
+ 0x92A6, 0x929A, 0x92AB, 0x9279, 0x9297, 0x927F, 0x92A3,
+ 0x92EE, 0x928E, 0x9282, 0x9295, 0x92A2, 0x927D, 0x9288, 0x92A1,
+ 0x928A, 0x9286, 0x928C, 0x9299, 0x92A7, 0x927E, 0x9287, 0x92A9,
+ 0x929D, 0x928B, 0x922D, 0x969E, 0x96A1, 0x96FF, 0x9758, 0x977D,
+ 0x977A, 0x977E, 0x9783, 0x9780, 0x9782, 0x977B, 0x9784, 0x9781,
+ 0x977F, 0x97CE, 0x97CD, 0x9816, 0x98AD, 0x98AE, 0x9902, 0x9900,
+ 0x9907, 0x999D, 0x999C, 0x99C3, 0x99B9, 0x99BB, 0x99BA, 0x99C2,
+ 0x99BD, 0x99C7, 0x9AB1, 0x9AE3, 0x9AE7, 0x9B3E, 0x9B3F, 0x9B60,
+ 0x9B61, 0x9B5F, 0x9CF1, 0x9CF2, 0x9CF5, 0x9EA7, 0x50FF, 0x5103,
+ 0x5130, 0x50F8, 0x5106, 0x5107, 0x50F6, 0x50FE, 0x510B, 0x510C,
+ 0x50FD, 0x510A, 0x528B, 0x528C, 0x52F1, 0x52EF, 0x5648, 0x5642,
+ 0x564C, 0x5635, 0x5641, 0x564A, 0x5649, 0x5646, 0x5658,
+ /* Big5-HKSCS 0xE540 .. 0xE57E */
+ 0x565A, 0x5640, 0x5633, 0x563D, 0x562C, 0x563E, 0x5638, 0x562A,
+ 0x563A, 0x571A, 0x58AB, 0x589D, 0x58B1, 0x58A0, 0x58A3, 0x58AF,
+ 0x58AC, 0x58A5, 0x58A1, 0x58FF, 0x5AFF, 0x5AF4, 0x5AFD, 0x5AF7,
+ 0x5AF6, 0x5B03, 0x5AF8, 0x5B02, 0x5AF9, 0x5B01, 0x5B07, 0x5B05,
+ 0x5B0F, 0x5C67, 0x5D99, 0x5D97, 0x5D9F, 0x5D92, 0x5DA2, 0x5D93,
+ 0x5D95, 0x5DA0, 0x5D9C, 0x5DA1, 0x5D9A, 0x5D9E, 0x5E69, 0x5E5D,
+ 0x5E60, 0x5E5C, 0x7DF3, 0x5EDB, 0x5EDE, 0x5EE1, 0x5F49, 0x5FB2,
+ 0x618B, 0x6183, 0x6179, 0x61B1, 0x61B0, 0x61A2, 0x6189,
+ /* Big5-HKSCS 0xE5A1 .. 0xE5FE */
+ 0x619B, 0x6193, 0x61AF, 0x61AD, 0x619F, 0x6192, 0x61AA,
+ 0x61A1, 0x618D, 0x6166, 0x61B3, 0x622D, 0x646E, 0x6470, 0x6496,
+ 0x64A0, 0x6485, 0x6497, 0x649C, 0x648F, 0x648B, 0x648A, 0x648C,
+ 0x64A3, 0x649F, 0x6468, 0x64B1, 0x6498, 0x6576, 0x657A, 0x6579,
+ 0x657B, 0x65B2, 0x65B3, 0x66B5, 0x66B0, 0x66A9, 0x66B2, 0x66B7,
+ 0x66AA, 0x66AF, 0x6A00, 0x6A06, 0x6A17, 0x69E5, 0x69F8, 0x6A15,
+ 0x69F1, 0x69E4, 0x6A20, 0x69FF, 0x69EC, 0x69E2, 0x6A1B, 0x6A1D,
+ 0x69FE, 0x6A27, 0x69F2, 0x69EE, 0x6A14, 0x69F7, 0x69E7, 0x6A40,
+ 0x6A08, 0x69E6, 0x69FB, 0x6A0D, 0x69FC, 0x69EB, 0x6A09, 0x6A04,
+ 0x6A18, 0x6A25, 0x6A0F, 0x69F6, 0x6A26, 0x6A07, 0x69F4, 0x6A16,
+ 0x6B51, 0x6BA5, 0x6BA3, 0x6BA2, 0x6BA6, 0x6C01, 0x6C00, 0x6BFF,
+ 0x6C02, 0x6F41, 0x6F26, 0x6F7E, 0x6F87, 0x6FC6, 0x6F92,
+ /* Big5-HKSCS 0xE640 .. 0xE67E */
+ 0x6F8D, 0x6F89, 0x6F8C, 0x6F62, 0x6F4F, 0x6F85, 0x6F5A, 0x6F96,
+ 0x6F76, 0x6F6C, 0x6F82, 0x6F55, 0x6F72, 0x6F52, 0x6F50, 0x6F57,
+ 0x6F94, 0x6F93, 0x6F5D, 0x6F00, 0x6F61, 0x6F6B, 0x6F7D, 0x6F67,
+ 0x6F90, 0x6F53, 0x6F8B, 0x6F69, 0x6F7F, 0x6F95, 0x6F63, 0x6F77,
+ 0x6F6A, 0x6F7B, 0x71B2, 0x71AF, 0x719B, 0x71B0, 0x71A0, 0x719A,
+ 0x71A9, 0x71B5, 0x719D, 0x71A5, 0x719E, 0x71A4, 0x71A1, 0x71AA,
+ 0x719C, 0x71A7, 0x71B3, 0x7298, 0x729A, 0x7358, 0x7352, 0x735E,
+ 0x735F, 0x7360, 0x735D, 0x735B, 0x7361, 0x735A, 0x7359,
+ /* Big5-HKSCS 0xE6A1 .. 0xE6FE */
+ 0x7362, 0x7487, 0x7489, 0x748A, 0x7486, 0x7481, 0x747D,
+ 0x7485, 0x7488, 0x747C, 0x7479, 0x7508, 0x7507, 0x757E, 0x7625,
+ 0x761E, 0x7619, 0x761D, 0x761C, 0x7623, 0x761A, 0x7628, 0x761B,
+ 0x769C, 0x769D, 0x769E, 0x769B, 0x778D, 0x778F, 0x7789, 0x7788,
+ 0x78CD, 0x78BB, 0x78CF, 0x78CC, 0x78D1, 0x78CE, 0x78D4, 0x78C8,
+ 0x78C3, 0x78C4, 0x78C9, 0x799A, 0x79A1, 0x79A0, 0x799C, 0x79A2,
+ 0x799B, 0x6B76, 0x7A39, 0x7AB2, 0x7AB4, 0x7AB3, 0x7BB7, 0x7BCB,
+ 0x7BBE, 0x7BAC, 0x7BCE, 0x7BAF, 0x7BB9, 0x7BCA, 0x7BB5, 0x7CC5,
+ 0x7CC8, 0x7CCC, 0x7CCB, 0x7DF7, 0x7DDB, 0x7DEA, 0x7DE7, 0x7DD7,
+ 0x7DE1, 0x7E03, 0x7DFA, 0x7DE6, 0x7DF6, 0x7DF1, 0x7DF0, 0x7DEE,
+ 0x7DDF, 0x7F76, 0x7FAC, 0x7FB0, 0x7FAD, 0x7FED, 0x7FEB, 0x7FEA,
+ 0x7FEC, 0x7FE6, 0x7FE8, 0x8064, 0x8067, 0x81A3, 0x819F,
+ /* Big5-HKSCS 0xE740 .. 0xE77E */
+ 0x819E, 0x8195, 0x81A2, 0x8199, 0x8197, 0x8216, 0x824F, 0x8253,
+ 0x8252, 0x8250, 0x824E, 0x8251, 0x8524, 0x853B, 0x850F, 0x8500,
+ 0x8529, 0x850E, 0x8509, 0x850D, 0x851F, 0x850A, 0x8527, 0x851C,
+ 0x84FB, 0x852B, 0x84FA, 0x8508, 0x850C, 0x84F4, 0x852A, 0x84F2,
+ 0x8515, 0x84F7, 0x84EB, 0x84F3, 0x84FC, 0x8512, 0x84EA, 0x84E9,
+ 0x8516, 0x84FE, 0x8528, 0x851D, 0x852E, 0x8502, 0x84FD, 0x851E,
+ 0x84F6, 0x8531, 0x8526, 0x84E7, 0x84E8, 0x84F0, 0x84EF, 0x84F9,
+ 0x8518, 0x8520, 0x8530, 0x850B, 0x8519, 0x852F, 0x8662,
+ /* Big5-HKSCS 0xE7A1 .. 0xE7FE */
+ 0x8756, 0x8763, 0x8764, 0x8777, 0x87E1, 0x8773, 0x8758,
+ 0x8754, 0x875B, 0x8752, 0x8761, 0x875A, 0x8751, 0x875E, 0x876D,
+ 0x876A, 0x8750, 0x874E, 0x875F, 0x875D, 0x876F, 0x876C, 0x877A,
+ 0x876E, 0x875C, 0x8765, 0x874F, 0x877B, 0x8775, 0x8762, 0x8767,
+ 0x8769, 0x885A, 0x8905, 0x890C, 0x8914, 0x890B, 0x8917, 0x8918,
+ 0x8919, 0x8906, 0x8916, 0x8911, 0x890E, 0x8909, 0x89A2, 0x89A4,
+ 0x89A3, 0x89ED, 0x89F0, 0x89EC, 0x8ACF, 0x8AC6, 0x8AB8, 0x8AD3,
+ 0x8AD1, 0x8AD4, 0x8AD5, 0x8ABB, 0x8AD7, 0x8ABE, 0x8AC0, 0x8AC5,
+ 0x8AD8, 0x8AC3, 0x8ABA, 0x8ABD, 0x8AD9, 0x8C3E, 0x8C4D, 0x8C8F,
+ 0x8CE5, 0x8CDF, 0x8CD9, 0x8CE8, 0x8CDA, 0x8CDD, 0x8CE7, 0x8DA0,
+ 0x8D9C, 0x8DA1, 0x8D9B, 0x8E20, 0x8E23, 0x8E25, 0x8E24, 0x8E2E,
+ 0x8E15, 0x8E1B, 0x8E16, 0x8E11, 0x8E19, 0x8E26, 0x8E27,
+ /* Big5-HKSCS 0xE840 .. 0xE87E */
+ 0x8E14, 0x8E12, 0x8E18, 0x8E13, 0x8E1C, 0x8E17, 0x8E1A, 0x8F2C,
+ 0x8F24, 0x8F18, 0x8F1A, 0x8F20, 0x8F23, 0x8F16, 0x8F17, 0x9073,
+ 0x9070, 0x906F, 0x9067, 0x906B, 0x912F, 0x912B, 0x9129, 0x912A,
+ 0x9132, 0x9126, 0x912E, 0x9185, 0x9186, 0x918A, 0x9181, 0x9182,
+ 0x9184, 0x9180, 0x92D0, 0x92C3, 0x92C4, 0x92C0, 0x92D9, 0x92B6,
+ 0x92CF, 0x92F1, 0x92DF, 0x92D8, 0x92E9, 0x92D7, 0x92DD, 0x92CC,
+ 0x92EF, 0x92C2, 0x92E8, 0x92CA, 0x92C8, 0x92CE, 0x92E6, 0x92CD,
+ 0x92D5, 0x92C9, 0x92E0, 0x92DE, 0x92E7, 0x92D1, 0x92D3,
+ /* Big5-HKSCS 0xE8A1 .. 0xE8FE */
+ 0x92B5, 0x92E1, 0x92C6, 0x92B4, 0x957C, 0x95AC, 0x95AB,
+ 0x95AE, 0x95B0, 0x96A4, 0x96A2, 0x96D3, 0x9705, 0x9708, 0x9702,
+ 0x975A, 0x978A, 0x978E, 0x9788, 0x97D0, 0x97CF, 0x981E, 0x981D,
+ 0x9826, 0x9829, 0x9828, 0x9820, 0x981B, 0x9827, 0x98B2, 0x9908,
+ 0x98FA, 0x9911, 0x9914, 0x9916, 0x9917, 0x9915, 0x99DC, 0x99CD,
+ 0x99CF, 0x99D3, 0x99D4, 0x99CE, 0x99C9, 0x99D6, 0x99D8, 0x99CB,
+ 0x99D7, 0x99CC, 0x9AB3, 0x9AEC, 0x9AEB, 0x9AF3, 0x9AF2, 0x9AF1,
+ 0x9B46, 0x9B43, 0x9B67, 0x9B74, 0x9B71, 0x9B66, 0x9B76, 0x9B75,
+ 0x9B70, 0x9B68, 0x9B64, 0x9B6C, 0x9CFC, 0x9CFA, 0x9CFD, 0x9CFF,
+ 0x9CF7, 0x9D07, 0x9D00, 0x9CF9, 0x9CFB, 0x9D08, 0x9D05, 0x9D04,
+ 0x9E83, 0x9ED3, 0x9F0F, 0x9F10, 0x511C, 0x5113, 0x5117, 0x511A,
+ 0x5111, 0x51DE, 0x5334, 0x53E1, 0x5670, 0x5660, 0x566E,
+ /* Big5-HKSCS 0xE940 .. 0xE97E */
+ 0x5673, 0x5666, 0x5663, 0x566D, 0x5672, 0x565E, 0x5677, 0x571C,
+ 0x571B, 0x58C8, 0x58BD, 0x58C9, 0x58BF, 0x58BA, 0x58C2, 0x58BC,
+ 0x58C6, 0x5B17, 0x5B19, 0x5B1B, 0x5B21, 0x5B14, 0x5B13, 0x5B10,
+ 0x5B16, 0x5B28, 0x5B1A, 0x5B20, 0x5B1E, 0x5BEF, 0x5DAC, 0x5DB1,
+ 0x5DA9, 0x5DA7, 0x5DB5, 0x5DB0, 0x5DAE, 0x5DAA, 0x5DA8, 0x5DB2,
+ 0x5DAD, 0x5DAF, 0x5DB4, 0x5E67, 0x5E68, 0x5E66, 0x5E6F, 0x5EE9,
+ 0x5EE7, 0x5EE6, 0x5EE8, 0x5EE5, 0x5F4B, 0x5FBC, 0x619D, 0x61A8,
+ 0x6196, 0x61C5, 0x61B4, 0x61C6, 0x61C1, 0x61CC, 0x61BA,
+ /* Big5-HKSCS 0xE9A1 .. 0xE9FE */
+ 0x61BF, 0x61B8, 0x618C, 0x64D7, 0x64D6, 0x64D0, 0x64CF,
+ 0x64C9, 0x64BD, 0x6489, 0x64C3, 0x64DB, 0x64F3, 0x64D9, 0x6533,
+ 0x657F, 0x657C, 0x65A2, 0x66C8, 0x66BE, 0x66C0, 0x66CA, 0x66CB,
+ 0x66CF, 0x66BD, 0x66BB, 0x66BA, 0x66CC, 0x6723, 0x6A34, 0x6A66,
+ 0x6A49, 0x6A67, 0x6A32, 0x6A68, 0x6A3E, 0x6A5D, 0x6A6D, 0x6A76,
+ 0x6A5B, 0x6A51, 0x6A28, 0x6A5A, 0x6A3B, 0x6A3F, 0x6A41, 0x6A6A,
+ 0x6A64, 0x6A50, 0x6A4F, 0x6A54, 0x6A6F, 0x6A69, 0x6A60, 0x6A3C,
+ 0x6A5E, 0x6A56, 0x6A55, 0x6A4D, 0x6A4E, 0x6A46, 0x6B55, 0x6B54,
+ 0x6B56, 0x6BA7, 0x6BAA, 0x6BAB, 0x6BC8, 0x6BC7, 0x6C04, 0x6C03,
+ 0x6C06, 0x6FAD, 0x6FCB, 0x6FA3, 0x6FC7, 0x6FBC, 0x6FCE, 0x6FC8,
+ 0x6F5E, 0x6FC4, 0x6FBD, 0x6F9E, 0x6FCA, 0x6FA8, 0x7004, 0x6FA5,
+ 0x6FAE, 0x6FBA, 0x6FAC, 0x6FAA, 0x6FCF, 0x6FBF, 0x6FB8,
+ /* Big5-HKSCS 0xEA40 .. 0xEA7E */
+ 0x6FA2, 0x6FC9, 0x6FAB, 0x6FCD, 0x6FAF, 0x6FB2, 0x6FB0, 0x71C5,
+ 0x71C2, 0x71BF, 0x71B8, 0x71D6, 0x71C0, 0x71C1, 0x71CB, 0x71D4,
+ 0x71CA, 0x71C7, 0x71CF, 0x71BD, 0x71D8, 0x71BC, 0x71C6, 0x71DA,
+ 0x71DB, 0x729D, 0x729E, 0x7369, 0x7366, 0x7367, 0x736C, 0x7365,
+ 0x736B, 0x736A, 0x747F, 0x749A, 0x74A0, 0x7494, 0x7492, 0x7495,
+ 0x74A1, 0x750B, 0x7580, 0x762F, 0x762D, 0x7631, 0x763D, 0x7633,
+ 0x763C, 0x7635, 0x7632, 0x7630, 0x76BB, 0x76E6, 0x779A, 0x779D,
+ 0x77A1, 0x779C, 0x779B, 0x77A2, 0x77A3, 0x7795, 0x7799,
+ /* Big5-HKSCS 0xEAA1 .. 0xEAFE */
+ 0x7797, 0x78DD, 0x78E9, 0x78E5, 0x78EA, 0x78DE, 0x78E3,
+ 0x78DB, 0x78E1, 0x78E2, 0x78ED, 0x78DF, 0x78E0, 0x79A4, 0x7A44,
+ 0x7A48, 0x7A47, 0x7AB6, 0x7AB8, 0x7AB5, 0x7AB1, 0x7AB7, 0x7BDE,
+ 0x7BE3, 0x7BE7, 0x7BDD, 0x7BD5, 0x7BE5, 0x7BDA, 0x7BE8, 0x7BF9,
+ 0x7BD4, 0x7BEA, 0x7BE2, 0x7BDC, 0x7BEB, 0x7BD8, 0x7BDF, 0x7CD2,
+ 0x7CD4, 0x7CD7, 0x7CD0, 0x7CD1, 0x7E12, 0x7E21, 0x7E17, 0x7E0C,
+ 0x7E1F, 0x7E20, 0x7E13, 0x7E0E, 0x7E1C, 0x7E15, 0x7E1A, 0x7E22,
+ 0x7E0B, 0x7E0F, 0x7E16, 0x7E0D, 0x7E14, 0x7E25, 0x7E24, 0x7F43,
+ 0x7F7B, 0x7F7C, 0x7F7A, 0x7FB1, 0x7FEF, 0x802A, 0x8029, 0x806C,
+ 0x81B1, 0x81A6, 0x81AE, 0x81B9, 0x81B5, 0x81AB, 0x81B0, 0x81AC,
+ 0x81B4, 0x81B2, 0x81B7, 0x81A7, 0x81F2, 0x8255, 0x8256, 0x8257,
+ 0x8556, 0x8545, 0x856B, 0x854D, 0x8553, 0x8561, 0x8558,
+ /* Big5-HKSCS 0xEB40 .. 0xEB7E */
+ 0x8540, 0x8546, 0x8564, 0x8541, 0x8562, 0x8544, 0x8551, 0x8547,
+ 0x8563, 0x853E, 0x855B, 0x8571, 0x854E, 0x856E, 0x8575, 0x8555,
+ 0x8567, 0x8560, 0x858C, 0x8566, 0x855D, 0x8554, 0x8565, 0x856C,
+ 0x8663, 0x8665, 0x8664, 0x879B, 0x878F, 0x8797, 0x8793, 0x8792,
+ 0x8788, 0x8781, 0x8796, 0x8798, 0x8779, 0x8787, 0x87A3, 0x8785,
+ 0x8790, 0x8791, 0x879D, 0x8784, 0x8794, 0x879C, 0x879A, 0x8789,
+ 0x891E, 0x8926, 0x8930, 0x892D, 0x892E, 0x8927, 0x8931, 0x8922,
+ 0x8929, 0x8923, 0x892F, 0x892C, 0x891F, 0x89F1, 0x8AE0,
+ /* Big5-HKSCS 0xEBA1 .. 0xEBFE */
+ 0x8AE2, 0x8AF2, 0x8AF4, 0x8AF5, 0x8ADD, 0x8B14, 0x8AE4,
+ 0x8ADF, 0x8AF0, 0x8AC8, 0x8ADE, 0x8AE1, 0x8AE8, 0x8AFF, 0x8AEF,
+ 0x8AFB, 0x8C91, 0x8C92, 0x8C90, 0x8CF5, 0x8CEE, 0x8CF1, 0x8CF0,
+ 0x8CF3, 0x8D6C, 0x8D6E, 0x8DA5, 0x8DA7, 0x8E33, 0x8E3E, 0x8E38,
+ 0x8E40, 0x8E45, 0x8E36, 0x8E3C, 0x8E3D, 0x8E41, 0x8E30, 0x8E3F,
+ 0x8EBD, 0x8F36, 0x8F2E, 0x8F35, 0x8F32, 0x8F39, 0x8F37, 0x8F34,
+ 0x9076, 0x9079, 0x907B, 0x9086, 0x90FA, 0x9133, 0x9135, 0x9136,
+ 0x9193, 0x9190, 0x9191, 0x918D, 0x918F, 0x9327, 0x931E, 0x9308,
+ 0x931F, 0x9306, 0x930F, 0x937A, 0x9338, 0x933C, 0x931B, 0x9323,
+ 0x9312, 0x9301, 0x9346, 0x932D, 0x930E, 0x930D, 0x92CB, 0x931D,
+ 0x92FA, 0x9325, 0x9313, 0x92F9, 0x92F7, 0x9334, 0x9302, 0x9324,
+ 0x92FF, 0x9329, 0x9339, 0x9335, 0x932A, 0x9314, 0x930C,
+ /* Big5-HKSCS 0xEC40 .. 0xEC7E */
+ 0x930B, 0x92FE, 0x9309, 0x9300, 0x92FB, 0x9316, 0x95BC, 0x95CD,
+ 0x95BE, 0x95B9, 0x95BA, 0x95B6, 0x95BF, 0x95B5, 0x95BD, 0x96A9,
+ 0x96D4, 0x970B, 0x9712, 0x9710, 0x9799, 0x9797, 0x9794, 0x97F0,
+ 0x97F8, 0x9835, 0x982F, 0x9832, 0x9924, 0x991F, 0x9927, 0x9929,
+ 0x999E, 0x99EE, 0x99EC, 0x99E5, 0x99E4, 0x99F0, 0x99E3, 0x99EA,
+ 0x99E9, 0x99E7, 0x9AB9, 0x9ABF, 0x9AB4, 0x9ABB, 0x9AF6, 0x9AFA,
+ 0x9AF9, 0x9AF7, 0x9B33, 0x9B80, 0x9B85, 0x9B87, 0x9B7C, 0x9B7E,
+ 0x9B7B, 0x9B82, 0x9B93, 0x9B92, 0x9B90, 0x9B7A, 0x9B95,
+ /* Big5-HKSCS 0xECA1 .. 0xECFE */
+ 0x9B7D, 0x9B88, 0x9D25, 0x9D17, 0x9D20, 0x9D1E, 0x9D14,
+ 0x9D29, 0x9D1D, 0x9D18, 0x9D22, 0x9D10, 0x9D19, 0x9D1F, 0x9E88,
+ 0x9E86, 0x9E87, 0x9EAE, 0x9EAD, 0x9ED5, 0x9ED6, 0x9EFA, 0x9F12,
+ 0x9F3D, 0x5126, 0x5125, 0x5122, 0x5124, 0x5120, 0x5129, 0x52F4,
+ 0x5693, 0x568C, 0x568D, 0x5686, 0x5684, 0x5683, 0x567E, 0x5682,
+ 0x567F, 0x5681, 0x58D6, 0x58D4, 0x58CF, 0x58D2, 0x5B2D, 0x5B25,
+ 0x5B32, 0x5B23, 0x5B2C, 0x5B27, 0x5B26, 0x5B2F, 0x5B2E, 0x5B7B,
+ 0x5BF1, 0x5BF2, 0x5DB7, 0x5E6C, 0x5E6A, 0x5FBE, 0x5FBB, 0x61C3,
+ 0x61B5, 0x61BC, 0x61E7, 0x61E0, 0x61E5, 0x61E4, 0x61E8, 0x61DE,
+ 0x64EF, 0x64E9, 0x64E3, 0x64EB, 0x64E4, 0x64E8, 0x6581, 0x6580,
+ 0x65B6, 0x65DA, 0x66D2, 0x6A8D, 0x6A96, 0x6A81, 0x6AA5, 0x6A89,
+ 0x6A9F, 0x6A9B, 0x6AA1, 0x6A9E, 0x6A87, 0x6A93, 0x6A8E,
+ /* Big5-HKSCS 0xED40 .. 0xED7E */
+ 0x6A95, 0x6A83, 0x6AA8, 0x6AA4, 0x6A91, 0x6A7F, 0x6AA6, 0x6A9A,
+ 0x6A85, 0x6A8C, 0x6A92, 0x6B5B, 0x6BAD, 0x6C09, 0x6FCC, 0x6FA9,
+ 0x6FF4, 0x6FD4, 0x6FE3, 0x6FDC, 0x6FED, 0x6FE7, 0x6FE6, 0x6FDE,
+ 0x6FF2, 0x6FDD, 0x6FE2, 0x6FE8, 0x71E1, 0x71F1, 0x71E8, 0x71F2,
+ 0x71E4, 0x71F0, 0x71E2, 0x7373, 0x736E, 0x736F, 0x7497, 0x74B2,
+ 0x74AB, 0x7490, 0x74AA, 0x74AD, 0x74B1, 0x74A5, 0x74AF, 0x7510,
+ 0x7511, 0x7512, 0x750F, 0x7584, 0x7643, 0x7648, 0x7649, 0x7647,
+ 0x76A4, 0x76E9, 0x77B5, 0x77AB, 0x77B2, 0x77B7, 0x77B6,
+ /* Big5-HKSCS 0xEDA1 .. 0xEDFE */
+ 0x77B4, 0x77B1, 0x77A8, 0x77F0, 0x78F3, 0x78FD, 0x7902,
+ 0x78FB, 0x78FC, 0x78F2, 0x7905, 0x78F9, 0x78FE, 0x7904, 0x79AB,
+ 0x79A8, 0x7A5C, 0x7A5B, 0x7A56, 0x7A58, 0x7A54, 0x7A5A, 0x7ABE,
+ 0x7AC0, 0x7AC1, 0x7C05, 0x7C0F, 0x7BF2, 0x7C00, 0x7BFF, 0x7BFB,
+ 0x7C0E, 0x7BF4, 0x7C0B, 0x7BF3, 0x7C02, 0x7C09, 0x7C03, 0x7C01,
+ 0x7BF8, 0x7BFD, 0x7C06, 0x7BF0, 0x7BF1, 0x7C10, 0x7C0A, 0x7CE8,
+ 0x7E2D, 0x7E3C, 0x7E42, 0x7E33, 0x9848, 0x7E38, 0x7E2A, 0x7E49,
+ 0x7E40, 0x7E47, 0x7E29, 0x7E4C, 0x7E30, 0x7E3B, 0x7E36, 0x7E44,
+ 0x7E3A, 0x7F45, 0x7F7F, 0x7F7E, 0x7F7D, 0x7FF4, 0x7FF2, 0x802C,
+ 0x81BB, 0x81C4, 0x81CC, 0x81CA, 0x81C5, 0x81C7, 0x81BC, 0x81E9,
+ 0x825B, 0x825A, 0x825C, 0x8583, 0x8580, 0x858F, 0x85A7, 0x8595,
+ 0x85A0, 0x858B, 0x85A3, 0x857B, 0x85A4, 0x859A, 0x859E,
+ /* Big5-HKSCS 0xEE40 .. 0xEE7E */
+ 0x8577, 0x857C, 0x8589, 0x85A1, 0x857A, 0x8578, 0x8557, 0x858E,
+ 0x8596, 0x8586, 0x858D, 0x8599, 0x859D, 0x8581, 0x85A2, 0x8582,
+ 0x8588, 0x8585, 0x8579, 0x8576, 0x8598, 0x8590, 0x859F, 0x8668,
+ 0x87BE, 0x87AA, 0x87AD, 0x87C5, 0x87B0, 0x87AC, 0x87B9, 0x87B5,
+ 0x87BC, 0x87AE, 0x87C9, 0x87C3, 0x87C2, 0x87CC, 0x87B7, 0x87AF,
+ 0x87C4, 0x87CA, 0x87B4, 0x87B6, 0x87BF, 0x87B8, 0x87BD, 0x87DE,
+ 0x87B2, 0x8935, 0x8933, 0x893C, 0x893E, 0x8941, 0x8952, 0x8937,
+ 0x8942, 0x89AD, 0x89AF, 0x89AE, 0x89F2, 0x89F3, 0x8B1E,
+ /* Big5-HKSCS 0xEEA1 .. 0xEEFE */
+ 0x8B18, 0x8B16, 0x8B11, 0x8B05, 0x8B0B, 0x8B22, 0x8B0F,
+ 0x8B12, 0x8B15, 0x8B07, 0x8B0D, 0x8B08, 0x8B06, 0x8B1C, 0x8B13,
+ 0x8B1A, 0x8C4F, 0x8C70, 0x8C72, 0x8C71, 0x8C6F, 0x8C95, 0x8C94,
+ 0x8CF9, 0x8D6F, 0x8E4E, 0x8E4D, 0x8E53, 0x8E50, 0x8E4C, 0x8E47,
+ 0x8F43, 0x8F40, 0x9085, 0x907E, 0x9138, 0x919A, 0x91A2, 0x919B,
+ 0x9199, 0x919F, 0x91A1, 0x919D, 0x91A0, 0x93A1, 0x9383, 0x93AF,
+ 0x9364, 0x9356, 0x9347, 0x937C, 0x9358, 0x935C, 0x9376, 0x9349,
+ 0x9350, 0x9351, 0x9360, 0x936D, 0x938F, 0x934C, 0x936A, 0x9379,
+ 0x9357, 0x9355, 0x9352, 0x934F, 0x9371, 0x9377, 0x937B, 0x9361,
+ 0x935E, 0x9363, 0x9367, 0x9380, 0x934E, 0x9359, 0x95C7, 0x95C0,
+ 0x95C9, 0x95C3, 0x95C5, 0x95B7, 0x96AE, 0x96B0, 0x96AC, 0x9720,
+ 0x971F, 0x9718, 0x971D, 0x9719, 0x979A, 0x97A1, 0x979C,
+ /* Big5-HKSCS 0xEF40 .. 0xEF7E */
+ 0x979E, 0x979D, 0x97D5, 0x97D4, 0x97F1, 0x9841, 0x9844, 0x984A,
+ 0x9849, 0x9845, 0x9843, 0x9925, 0x992B, 0x992C, 0x992A, 0x9933,
+ 0x9932, 0x992F, 0x992D, 0x9931, 0x9930, 0x9998, 0x99A3, 0x99A1,
+ 0x9A02, 0x99FA, 0x99F4, 0x99F7, 0x99F9, 0x99F8, 0x99F6, 0x99FB,
+ 0x99FD, 0x99FE, 0x99FC, 0x9A03, 0x9ABE, 0x9AFE, 0x9AFD, 0x9B01,
+ 0x9AFC, 0x9B48, 0x9B9A, 0x9BA8, 0x9B9E, 0x9B9B, 0x9BA6, 0x9BA1,
+ 0x9BA5, 0x9BA4, 0x9B86, 0x9BA2, 0x9BA0, 0x9BAF, 0x9D33, 0x9D41,
+ 0x9D67, 0x9D36, 0x9D2E, 0x9D2F, 0x9D31, 0x9D38, 0x9D30,
+ /* Big5-HKSCS 0xEFA1 .. 0xEFFE */
+ 0x9D45, 0x9D42, 0x9D43, 0x9D3E, 0x9D37, 0x9D40, 0x9D3D,
+ 0x7FF5, 0x9D2D, 0x9E8A, 0x9E89, 0x9E8D, 0x9EB0, 0x9EC8, 0x9EDA,
+ 0x9EFB, 0x9EFF, 0x9F24, 0x9F23, 0x9F22, 0x9F54, 0x9FA0, 0x5131,
+ 0x512D, 0x512E, 0x5698, 0x569C, 0x5697, 0x569A, 0x569D, 0x5699,
+ 0x5970, 0x5B3C, 0x5C69, 0x5C6A, 0x5DC0, 0x5E6D, 0x5E6E, 0x61D8,
+ 0x61DF, 0x61ED, 0x61EE, 0x61F1, 0x61EA, 0x61F0, 0x61EB, 0x61D6,
+ 0x61E9, 0x64FF, 0x6504, 0x64FD, 0x64F8, 0x6501, 0x6503, 0x64FC,
+ 0x6594, 0x65DB, 0x66DA, 0x66DB, 0x66D8, 0x6AC5, 0x6AB9, 0x6ABD,
+ 0x6AE1, 0x6AC6, 0x6ABA, 0x6AB6, 0x6AB7, 0x6AC7, 0x6AB4, 0x6AAD,
+ 0x6B5E, 0x6BC9, 0x6C0B, 0x7007, 0x700C, 0x700D, 0x7001, 0x7005,
+ 0x7014, 0x700E, 0x6FFF, 0x7000, 0x6FFB, 0x7026, 0x6FFC, 0x6FF7,
+ 0x700A, 0x7201, 0x71FF, 0x71F9, 0x7203, 0x71FD, 0x7376,
+ /* Big5-HKSCS 0xF040 .. 0xF07E */
+ 0x74B8, 0x74C0, 0x74B5, 0x74C1, 0x74BE, 0x74B6, 0x74BB, 0x74C2,
+ 0x7514, 0x7513, 0x765C, 0x7664, 0x7659, 0x7650, 0x7653, 0x7657,
+ 0x765A, 0x76A6, 0x76BD, 0x76EC, 0x77C2, 0x77BA, 0x78FF, 0x790C,
+ 0x7913, 0x7914, 0x7909, 0x7910, 0x7912, 0x7911, 0x79AD, 0x79AC,
+ 0x7A5F, 0x7C1C, 0x7C29, 0x7C19, 0x7C20, 0x7C1F, 0x7C2D, 0x7C1D,
+ 0x7C26, 0x7C28, 0x7C22, 0x7C25, 0x7C30, 0x7E5C, 0x7E50, 0x7E56,
+ 0x7E63, 0x7E58, 0x7E62, 0x7E5F, 0x7E51, 0x7E60, 0x7E57, 0x7E53,
+ 0x7FB5, 0x7FB3, 0x7FF7, 0x7FF8, 0x8075, 0x81D1, 0x81D2,
+ /* Big5-HKSCS 0xF0A1 .. 0xF0FE */
+ 0x81D0, 0x825F, 0x825E, 0x85B4, 0x85C6, 0x85C0, 0x85C3,
+ 0x85C2, 0x85B3, 0x85B5, 0x85BD, 0x85C7, 0x85C4, 0x85BF, 0x85CB,
+ 0x85CE, 0x85C8, 0x85C5, 0x85B1, 0x85B6, 0x85D2, 0x8624, 0x85B8,
+ 0x85B7, 0x85BE, 0x8669, 0x87E7, 0x87E6, 0x87E2, 0x87DB, 0x87EB,
+ 0x87EA, 0x87E5, 0x87DF, 0x87F3, 0x87E4, 0x87D4, 0x87DC, 0x87D3,
+ 0x87ED, 0x87D8, 0x87E3, 0x87A4, 0x87D7, 0x87D9, 0x8801, 0x87F4,
+ 0x87E8, 0x87DD, 0x8953, 0x894B, 0x894F, 0x894C, 0x8946, 0x8950,
+ 0x8951, 0x8949, 0x8B2A, 0x8B27, 0x8B23, 0x8B33, 0x8B30, 0x8B35,
+ 0x8B47, 0x8B2F, 0x8B3C, 0x8B3E, 0x8B31, 0x8B25, 0x8B37, 0x8B26,
+ 0x8B36, 0x8B2E, 0x8B24, 0x8B3B, 0x8B3D, 0x8B3A, 0x8C42, 0x8C75,
+ 0x8C99, 0x8C98, 0x8C97, 0x8CFE, 0x8D04, 0x8D02, 0x8D00, 0x8E5C,
+ 0x8E62, 0x8E60, 0x8E57, 0x8E56, 0x8E5E, 0x8E65, 0x8E67,
+ /* Big5-HKSCS 0xF140 .. 0xF17E */
+ 0x8E5B, 0x8E5A, 0x8E61, 0x8E5D, 0x8E69, 0x8E54, 0x8F46, 0x8F47,
+ 0x8F48, 0x8F4B, 0x9128, 0x913A, 0x913B, 0x913E, 0x91A8, 0x91A5,
+ 0x91A7, 0x91AF, 0x91AA, 0x93B5, 0x938C, 0x9392, 0x93B7, 0x939B,
+ 0x939D, 0x9389, 0x93A7, 0x938E, 0x93AA, 0x939E, 0x93A6, 0x9395,
+ 0x9388, 0x9399, 0x939F, 0x938D, 0x93B1, 0x9391, 0x93B2, 0x93A4,
+ 0x93A8, 0x93B4, 0x93A3, 0x93A5, 0x95D2, 0x95D3, 0x95D1, 0x96B3,
+ 0x96D7, 0x96DA, 0x5DC2, 0x96DF, 0x96D8, 0x96DD, 0x9723, 0x9722,
+ 0x9725, 0x97AC, 0x97AE, 0x97A8, 0x97AB, 0x97A4, 0x97AA,
+ /* Big5-HKSCS 0xF1A1 .. 0xF1FE */
+ 0x97A2, 0x97A5, 0x97D7, 0x97D9, 0x97D6, 0x97D8, 0x97FA,
+ 0x9850, 0x9851, 0x9852, 0x98B8, 0x9941, 0x993C, 0x993A, 0x9A0F,
+ 0x9A0B, 0x9A09, 0x9A0D, 0x9A04, 0x9A11, 0x9A0A, 0x9A05, 0x9A07,
+ 0x9A06, 0x9AC0, 0x9ADC, 0x9B08, 0x9B04, 0x9B05, 0x9B29, 0x9B35,
+ 0x9B4A, 0x9B4C, 0x9B4B, 0x9BC7, 0x9BC6, 0x9BC3, 0x9BBF, 0x9BC1,
+ 0x9BB5, 0x9BB8, 0x9BD3, 0x9BB6, 0x9BC4, 0x9BB9, 0x9BBD, 0x9D5C,
+ 0x9D53, 0x9D4F, 0x9D4A, 0x9D5B, 0x9D4B, 0x9D59, 0x9D56, 0x9D4C,
+ 0x9D57, 0x9D52, 0x9D54, 0x9D5F, 0x9D58, 0x9D5A, 0x9E8E, 0x9E8C,
+ 0x9EDF, 0x9F01, 0x9F00, 0x9F16, 0x9F25, 0x9F2B, 0x9F2A, 0x9F29,
+ 0x9F28, 0x9F4C, 0x9F55, 0x5134, 0x5135, 0x5296, 0x52F7, 0x53B4,
+ 0x56AB, 0x56AD, 0x56A6, 0x56A7, 0x56AA, 0x56AC, 0x58DA, 0x58DD,
+ 0x58DB, 0x5912, 0x5B3D, 0x5B3E, 0x5B3F, 0x5DC3, 0x5E70,
+ /* Big5-HKSCS 0xF240 .. 0xF27E */
+ 0x5FBF, 0x61FB, 0x6507, 0x6510, 0x650D, 0x6509, 0x650C, 0x650E,
+ 0x6584, 0x65DE, 0x65DD, 0x66DE, 0x6AE7, 0x6AE0, 0x6ACC, 0x6AD1,
+ 0x6AD9, 0x6ACB, 0x6ADF, 0x6ADC, 0x6AD0, 0x6AEB, 0x6ACF, 0x6ACD,
+ 0x6ADE, 0x6B60, 0x6BB0, 0x6C0C, 0x7019, 0x7027, 0x7020, 0x7016,
+ 0x702B, 0x7021, 0x7022, 0x7023, 0x7029, 0x7017, 0x7024, 0x701C,
+ 0x702A, 0x720C, 0x720A, 0x7207, 0x7202, 0x7205, 0x72A5, 0x72A6,
+ 0x72A4, 0x72A3, 0x72A1, 0x74CB, 0x74C5, 0x74B7, 0x74C3, 0x7516,
+ 0x7660, 0x77C9, 0x77CA, 0x77C4, 0x77F1, 0x791D, 0x791B,
+ /* Big5-HKSCS 0xF2A1 .. 0xF2FE */
+ 0x7921, 0x791C, 0x7917, 0x791E, 0x79B0, 0x7A67, 0x7A68,
+ 0x7C33, 0x7C3C, 0x7C39, 0x7C2C, 0x7C3B, 0x7CEC, 0x7CEA, 0x7E76,
+ 0x7E75, 0x7E78, 0x7E70, 0x7E77, 0x7E6F, 0x7E7A, 0x7E72, 0x7E74,
+ 0x7E68, 0x7F4B, 0x7F4A, 0x7F83, 0x7F86, 0x7FB7, 0x7FFD, 0x7FFE,
+ 0x8078, 0x81D7, 0x81D5, 0x8264, 0x8261, 0x8263, 0x85EB, 0x85F1,
+ 0x85ED, 0x85D9, 0x85E1, 0x85E8, 0x85DA, 0x85D7, 0x85EC, 0x85F2,
+ 0x85F8, 0x85D8, 0x85DF, 0x85E3, 0x85DC, 0x85D1, 0x85F0, 0x85E6,
+ 0x85EF, 0x85DE, 0x85E2, 0x8800, 0x87FA, 0x8803, 0x87F6, 0x87F7,
+ 0x8809, 0x880C, 0x880B, 0x8806, 0x87FC, 0x8808, 0x87FF, 0x880A,
+ 0x8802, 0x8962, 0x895A, 0x895B, 0x8957, 0x8961, 0x895C, 0x8958,
+ 0x895D, 0x8959, 0x8988, 0x89B7, 0x89B6, 0x89F6, 0x8B50, 0x8B48,
+ 0x8B4A, 0x8B40, 0x8B53, 0x8B56, 0x8B54, 0x8B4B, 0x8B55,
+ /* Big5-HKSCS 0xF340 .. 0xF37E */
+ 0x8B51, 0x8B42, 0x8B52, 0x8B57, 0x8C43, 0x8C77, 0x8C76, 0x8C9A,
+ 0x8D06, 0x8D07, 0x8D09, 0x8DAC, 0x8DAA, 0x8DAD, 0x8DAB, 0x8E6D,
+ 0x8E78, 0x8E73, 0x8E6A, 0x8E6F, 0x8E7B, 0x8EC2, 0x8F52, 0x8F51,
+ 0x8F4F, 0x8F50, 0x8F53, 0x8FB4, 0x9140, 0x913F, 0x91B0, 0x91AD,
+ 0x93DE, 0x93C7, 0x93CF, 0x93C2, 0x93DA, 0x93D0, 0x93F9, 0x93EC,
+ 0x93CC, 0x93D9, 0x93A9, 0x93E6, 0x93CA, 0x93D4, 0x93EE, 0x93E3,
+ 0x93D5, 0x93C4, 0x93CE, 0x93C0, 0x93D2, 0x93E7, 0x957D, 0x95DA,
+ 0x95DB, 0x96E1, 0x9729, 0x972B, 0x972C, 0x9728, 0x9726,
+ /* Big5-HKSCS 0xF3A1 .. 0xF3FE */
+ 0x97B3, 0x97B7, 0x97B6, 0x97DD, 0x97DE, 0x97DF, 0x985C,
+ 0x9859, 0x985D, 0x9857, 0x98BF, 0x98BD, 0x98BB, 0x98BE, 0x9948,
+ 0x9947, 0x9943, 0x99A6, 0x99A7, 0x9A1A, 0x9A15, 0x9A25, 0x9A1D,
+ 0x9A24, 0x9A1B, 0x9A22, 0x9A20, 0x9A27, 0x9A23, 0x9A1E, 0x9A1C,
+ 0x9A14, 0x9AC2, 0x9B0B, 0x9B0A, 0x9B0E, 0x9B0C, 0x9B37, 0x9BEA,
+ 0x9BEB, 0x9BE0, 0x9BDE, 0x9BE4, 0x9BE6, 0x9BE2, 0x9BF0, 0x9BD4,
+ 0x9BD7, 0x9BEC, 0x9BDC, 0x9BD9, 0x9BE5, 0x9BD5, 0x9BE1, 0x9BDA,
+ 0x9D77, 0x9D81, 0x9D8A, 0x9D84, 0x9D88, 0x9D71, 0x9D80, 0x9D78,
+ 0x9D86, 0x9D8B, 0x9D8C, 0x9D7D, 0x9D6B, 0x9D74, 0x9D75, 0x9D70,
+ 0x9D69, 0x9D85, 0x9D73, 0x9D7B, 0x9D82, 0x9D6F, 0x9D79, 0x9D7F,
+ 0x9D87, 0x9D68, 0x9E94, 0x9E91, 0x9EC0, 0x9EFC, 0x9F2D, 0x9F40,
+ 0x9F41, 0x9F4D, 0x9F56, 0x9F57, 0x9F58, 0x5337, 0x56B2,
+ /* Big5-HKSCS 0xF440 .. 0xF47E */
+ 0x56B5, 0x56B3, 0x58E3, 0x5B45, 0x5DC6, 0x5DC7, 0x5EEE, 0x5EEF,
+ 0x5FC0, 0x5FC1, 0x61F9, 0x6517, 0x6516, 0x6515, 0x6513, 0x65DF,
+ 0x66E8, 0x66E3, 0x66E4, 0x6AF3, 0x6AF0, 0x6AEA, 0x6AE8, 0x6AF9,
+ 0x6AF1, 0x6AEE, 0x6AEF, 0x703C, 0x7035, 0x702F, 0x7037, 0x7034,
+ 0x7031, 0x7042, 0x7038, 0x703F, 0x703A, 0x7039, 0x7040, 0x703B,
+ 0x7033, 0x7041, 0x7213, 0x7214, 0x72A8, 0x737D, 0x737C, 0x74BA,
+ 0x76AB, 0x76AA, 0x76BE, 0x76ED, 0x77CC, 0x77CE, 0x77CF, 0x77CD,
+ 0x77F2, 0x7925, 0x7923, 0x7927, 0x7928, 0x7924, 0x7929,
+ /* Big5-HKSCS 0xF4A1 .. 0xF4FE */
+ 0x79B2, 0x7A6E, 0x7A6C, 0x7A6D, 0x7AF7, 0x7C49, 0x7C48,
+ 0x7C4A, 0x7C47, 0x7C45, 0x7CEE, 0x7E7B, 0x7E7E, 0x7E81, 0x7E80,
+ 0x7FBA, 0x7FFF, 0x8079, 0x81DB, 0x81D9, 0x820B, 0x8268, 0x8269,
+ 0x8622, 0x85FF, 0x8601, 0x85FE, 0x861B, 0x8600, 0x85F6, 0x8604,
+ 0x8609, 0x8605, 0x860C, 0x85FD, 0x8819, 0x8810, 0x8811, 0x8817,
+ 0x8813, 0x8816, 0x8963, 0x8966, 0x89B9, 0x89F7, 0x8B60, 0x8B6A,
+ 0x8B5D, 0x8B68, 0x8B63, 0x8B65, 0x8B67, 0x8B6D, 0x8DAE, 0x8E86,
+ 0x8E88, 0x8E84, 0x8F59, 0x8F56, 0x8F57, 0x8F55, 0x8F58, 0x8F5A,
+ 0x908D, 0x9143, 0x9141, 0x91B7, 0x91B5, 0x91B2, 0x91B3, 0x940B,
+ 0x9413, 0x93FB, 0x9420, 0x940F, 0x9414, 0x93FE, 0x9415, 0x9410,
+ 0x9428, 0x9419, 0x940D, 0x93F5, 0x9400, 0x93F7, 0x9407, 0x940E,
+ 0x9416, 0x9412, 0x93FA, 0x9409, 0x93F8, 0x940A, 0x93FF,
+ /* Big5-HKSCS 0xF540 .. 0xF57E */
+ 0x93FC, 0x940C, 0x93F6, 0x9411, 0x9406, 0x95DE, 0x95E0, 0x95DF,
+ 0x972E, 0x972F, 0x97B9, 0x97BB, 0x97FD, 0x97FE, 0x9860, 0x9862,
+ 0x9863, 0x985F, 0x98C1, 0x98C2, 0x9950, 0x994E, 0x9959, 0x994C,
+ 0x994B, 0x9953, 0x9A32, 0x9A34, 0x9A31, 0x9A2C, 0x9A2A, 0x9A36,
+ 0x9A29, 0x9A2E, 0x9A38, 0x9A2D, 0x9AC7, 0x9ACA, 0x9AC6, 0x9B10,
+ 0x9B12, 0x9B11, 0x9C0B, 0x9C08, 0x9BF7, 0x9C05, 0x9C12, 0x9BF8,
+ 0x9C40, 0x9C07, 0x9C0E, 0x9C06, 0x9C17, 0x9C14, 0x9C09, 0x9D9F,
+ 0x9D99, 0x9DA4, 0x9D9D, 0x9D92, 0x9D98, 0x9D90, 0x9D9B,
+ /* Big5-HKSCS 0xF5A1 .. 0xF5FE */
+ 0x9DA0, 0x9D94, 0x9D9C, 0x9DAA, 0x9D97, 0x9DA1, 0x9D9A,
+ 0x9DA2, 0x9DA8, 0x9D9E, 0x9DA3, 0x9DBF, 0x9DA9, 0x9D96, 0x9DA6,
+ 0x9DA7, 0x9E99, 0x9E9B, 0x9E9A, 0x9EE5, 0x9EE4, 0x9EE7, 0x9EE6,
+ 0x9F30, 0x9F2E, 0x9F5B, 0x9F60, 0x9F5E, 0x9F5D, 0x9F59, 0x9F91,
+ 0x513A, 0x5139, 0x5298, 0x5297, 0x56C3, 0x56BD, 0x56BE, 0x5B48,
+ 0x5B47, 0x5DCB, 0x5DCF, 0x5EF1, 0x61FD, 0x651B, 0x6B02, 0x6AFC,
+ 0x6B03, 0x6AF8, 0x6B00, 0x7043, 0x7044, 0x704A, 0x7048, 0x7049,
+ 0x7045, 0x7046, 0x721D, 0x721A, 0x7219, 0x737E, 0x7517, 0x766A,
+ 0x77D0, 0x792D, 0x7931, 0x792F, 0x7C54, 0x7C53, 0x7CF2, 0x7E8A,
+ 0x7E87, 0x7E88, 0x7E8B, 0x7E86, 0x7E8D, 0x7F4D, 0x7FBB, 0x8030,
+ 0x81DD, 0x8618, 0x862A, 0x8626, 0x861F, 0x8623, 0x861C, 0x8619,
+ 0x8627, 0x862E, 0x8621, 0x8620, 0x8629, 0x861E, 0x8625,
+ /* Big5-HKSCS 0xF640 .. 0xF67E */
+ 0x8829, 0x881D, 0x881B, 0x8820, 0x8824, 0x881C, 0x882B, 0x884A,
+ 0x896D, 0x8969, 0x896E, 0x896B, 0x89FA, 0x8B79, 0x8B78, 0x8B45,
+ 0x8B7A, 0x8B7B, 0x8D10, 0x8D14, 0x8DAF, 0x8E8E, 0x8E8C, 0x8F5E,
+ 0x8F5B, 0x8F5D, 0x9146, 0x9144, 0x9145, 0x91B9, 0x943F, 0x943B,
+ 0x9436, 0x9429, 0x943D, 0x943C, 0x9430, 0x9439, 0x942A, 0x9437,
+ 0x942C, 0x9440, 0x9431, 0x95E5, 0x95E4, 0x95E3, 0x9735, 0x973A,
+ 0x97BF, 0x97E1, 0x9864, 0x98C9, 0x98C6, 0x98C0, 0x9958, 0x9956,
+ 0x9A39, 0x9A3D, 0x9A46, 0x9A44, 0x9A42, 0x9A41, 0x9A3A,
+ /* Big5-HKSCS 0xF6A1 .. 0xF6FE */
+ 0x9A3F, 0x9ACD, 0x9B15, 0x9B17, 0x9B18, 0x9B16, 0x9B3A,
+ 0x9B52, 0x9C2B, 0x9C1D, 0x9C1C, 0x9C2C, 0x9C23, 0x9C28, 0x9C29,
+ 0x9C24, 0x9C21, 0x9DB7, 0x9DB6, 0x9DBC, 0x9DC1, 0x9DC7, 0x9DCA,
+ 0x9DCF, 0x9DBE, 0x9DC5, 0x9DC3, 0x9DBB, 0x9DB5, 0x9DCE, 0x9DB9,
+ 0x9DBA, 0x9DAC, 0x9DC8, 0x9DB1, 0x9DAD, 0x9DCC, 0x9DB3, 0x9DCD,
+ 0x9DB2, 0x9E7A, 0x9E9C, 0x9EEB, 0x9EEE, 0x9EED, 0x9F1B, 0x9F18,
+ 0x9F1A, 0x9F31, 0x9F4E, 0x9F65, 0x9F64, 0x9F92, 0x4EB9, 0x56C6,
+ 0x56C5, 0x56CB, 0x5971, 0x5B4B, 0x5B4C, 0x5DD5, 0x5DD1, 0x5EF2,
+ 0x6521, 0x6520, 0x6526, 0x6522, 0x6B0B, 0x6B08, 0x6B09, 0x6C0D,
+ 0x7055, 0x7056, 0x7057, 0x7052, 0x721E, 0x721F, 0x72A9, 0x737F,
+ 0x74D8, 0x74D5, 0x74D9, 0x74D7, 0x766D, 0x76AD, 0x7935, 0x79B4,
+ 0x7A70, 0x7A71, 0x7C57, 0x7C5C, 0x7C59, 0x7C5B, 0x7C5A,
+ /* Big5-HKSCS 0xF740 .. 0xF77E */
+ 0x7CF4, 0x7CF1, 0x7E91, 0x7F4F, 0x7F87, 0x81DE, 0x826B, 0x8634,
+ 0x8635, 0x8633, 0x862C, 0x8632, 0x8636, 0x882C, 0x8828, 0x8826,
+ 0x882A, 0x8825, 0x8971, 0x89BF, 0x89BE, 0x89FB, 0x8B7E, 0x8B84,
+ 0x8B82, 0x8B86, 0x8B85, 0x8B7F, 0x8D15, 0x8E95, 0x8E94, 0x8E9A,
+ 0x8E92, 0x8E90, 0x8E96, 0x8E97, 0x8F60, 0x8F62, 0x9147, 0x944C,
+ 0x9450, 0x944A, 0x944B, 0x944F, 0x9447, 0x9445, 0x9448, 0x9449,
+ 0x9446, 0x973F, 0x97E3, 0x986A, 0x9869, 0x98CB, 0x9954, 0x995B,
+ 0x9A4E, 0x9A53, 0x9A54, 0x9A4C, 0x9A4F, 0x9A48, 0x9A4A,
+ /* Big5-HKSCS 0xF7A1 .. 0xF7FE */
+ 0x9A49, 0x9A52, 0x9A50, 0x9AD0, 0x9B19, 0x9B2B, 0x9B3B,
+ 0x9B56, 0x9B55, 0x9C46, 0x9C48, 0x9C3F, 0x9C44, 0x9C39, 0x9C33,
+ 0x9C41, 0x9C3C, 0x9C37, 0x9C34, 0x9C32, 0x9C3D, 0x9C36, 0x9DDB,
+ 0x9DD2, 0x9DDE, 0x9DDA, 0x9DCB, 0x9DD0, 0x9DDC, 0x9DD1, 0x9DDF,
+ 0x9DE9, 0x9DD9, 0x9DD8, 0x9DD6, 0x9DF5, 0x9DD5, 0x9DDD, 0x9EB6,
+ 0x9EF0, 0x9F35, 0x9F33, 0x9F32, 0x9F42, 0x9F6B, 0x9F95, 0x9FA2,
+ 0x513D, 0x5299, 0x58E8, 0x58E7, 0x5972, 0x5B4D, 0x5DD8, 0x882F,
+ 0x5F4F, 0x6201, 0x6203, 0x6204, 0x6529, 0x6525, 0x6596, 0x66EB,
+ 0x6B11, 0x6B12, 0x6B0F, 0x6BCA, 0x705B, 0x705A, 0x7222, 0x7382,
+ 0x7381, 0x7383, 0x7670, 0x77D4, 0x7C67, 0x7C66, 0x7E95, 0x826C,
+ 0x863A, 0x8640, 0x8639, 0x863C, 0x8631, 0x863B, 0x863E, 0x8830,
+ 0x8832, 0x882E, 0x8833, 0x8976, 0x8974, 0x8973, 0x89FE,
+ /* Big5-HKSCS 0xF840 .. 0xF87E */
+ 0x8B8C, 0x8B8E, 0x8B8B, 0x8B88, 0x8C45, 0x8D19, 0x8E98, 0x8F64,
+ 0x8F63, 0x91BC, 0x9462, 0x9455, 0x945D, 0x9457, 0x945E, 0x97C4,
+ 0x97C5, 0x9800, 0x9A56, 0x9A59, 0x9B1E, 0x9B1F, 0x9B20, 0x9C52,
+ 0x9C58, 0x9C50, 0x9C4A, 0x9C4D, 0x9C4B, 0x9C55, 0x9C59, 0x9C4C,
+ 0x9C4E, 0x9DFB, 0x9DF7, 0x9DEF, 0x9DE3, 0x9DEB, 0x9DF8, 0x9DE4,
+ 0x9DF6, 0x9DE1, 0x9DEE, 0x9DE6, 0x9DF2, 0x9DF0, 0x9DE2, 0x9DEC,
+ 0x9DF4, 0x9DF3, 0x9DE8, 0x9DED, 0x9EC2, 0x9ED0, 0x9EF2, 0x9EF3,
+ 0x9F06, 0x9F1C, 0x9F38, 0x9F37, 0x9F36, 0x9F43, 0x9F4F,
+ /* Big5-HKSCS 0xF8A1 .. 0xF8FE */
+ 0x9F71, 0x9F70, 0x9F6E, 0x9F6F, 0x56D3, 0x56CD, 0x5B4E,
+ 0x5C6D, 0x652D, 0x66ED, 0x66EE, 0x6B13, 0x705F, 0x7061, 0x705D,
+ 0x7060, 0x7223, 0x74DB, 0x74E5, 0x77D5, 0x7938, 0x79B7, 0x79B6,
+ 0x7C6A, 0x7E97, 0x7F89, 0x826D, 0x8643, 0x8838, 0x8837, 0x8835,
+ 0x884B, 0x8B94, 0x8B95, 0x8E9E, 0x8E9F, 0x8EA0, 0x8E9D, 0x91BE,
+ 0x91BD, 0x91C2, 0x946B, 0x9468, 0x9469, 0x96E5, 0x9746, 0x9743,
+ 0x9747, 0x97C7, 0x97E5, 0x9A5E, 0x9AD5, 0x9B59, 0x9C63, 0x9C67,
+ 0x9C66, 0x9C62, 0x9C5E, 0x9C60, 0x9E02, 0x9DFE, 0x9E07, 0x9E03,
+ 0x9E06, 0x9E05, 0x9E00, 0x9E01, 0x9E09, 0x9DFF, 0x9DFD, 0x9E04,
+ 0x9EA0, 0x9F1E, 0x9F46, 0x9F74, 0x9F75, 0x9F76, 0x56D4, 0x652E,
+ 0x65B8, 0x6B18, 0x6B19, 0x6B17, 0x6B1A, 0x7062, 0x7226, 0x72AA,
+ 0x77D8, 0x77D9, 0x7939, 0x7C69, 0x7C6B, 0x7CF6, 0x7E9A,
+ /* Big5-HKSCS 0xF940 .. 0xF97E */
+ 0x7E98, 0x7E9B, 0x7E99, 0x81E0, 0x81E1, 0x8646, 0x8647, 0x8648,
+ 0x8979, 0x897A, 0x897C, 0x897B, 0x89FF, 0x8B98, 0x8B99, 0x8EA5,
+ 0x8EA4, 0x8EA3, 0x946E, 0x946D, 0x946F, 0x9471, 0x9473, 0x9749,
+ 0x9872, 0x995F, 0x9C68, 0x9C6E, 0x9C6D, 0x9E0B, 0x9E0D, 0x9E10,
+ 0x9E0F, 0x9E12, 0x9E11, 0x9EA1, 0x9EF5, 0x9F09, 0x9F47, 0x9F78,
+ 0x9F7B, 0x9F7A, 0x9F79, 0x571E, 0x7066, 0x7C6F, 0x883C, 0x8DB2,
+ 0x8EA6, 0x91C3, 0x9474, 0x9478, 0x9476, 0x9475, 0x9A60, 0x9C74,
+ 0x9C73, 0x9C71, 0x9C75, 0x9E14, 0x9E13, 0x9EF6, 0x9F0A,
+ /* Big5-HKSCS 0xF9A1 .. 0xF9FE */
+ 0x9FA4, 0x7068, 0x7065, 0x7CF7, 0x866A, 0x883E, 0x883D,
+ 0x883F, 0x8B9E, 0x8C9C, 0x8EA9, 0x8EC9, 0x974B, 0x9873, 0x9874,
+ 0x98CC, 0x9961, 0x99AB, 0x9A64, 0x9A66, 0x9A67, 0x9B24, 0x9E15,
+ 0x9E17, 0x9F48, 0x6207, 0x6B1E, 0x7227, 0x864C, 0x8EA8, 0x9482,
+ 0x9480, 0x9481, 0x9A69, 0x9A68, 0x9B2E, 0x9E19, 0x7229, 0x864B,
+ 0x8B9F, 0x9483, 0x9C79, 0x9EB7, 0x7675, 0x9A6B, 0x9C7A, 0x9E1D,
+ 0x7069, 0x706A, 0x9EA4, 0x9F7E, 0x9F49, 0x9F98, 0x7881, 0x92B9,
+ 0x88CF, 0x58BB, 0x6052, 0x7CA7, 0x5AFA, 0x2554, 0x2566, 0x2557,
+ 0x2560, 0x256C, 0x2563, 0x255A, 0x2569, 0x255D, 0x2552, 0x2564,
+ 0x2555, 0x255E, 0x256A, 0x2561, 0x2558, 0x2567, 0x255B, 0x2553,
+ 0x2565, 0x2556, 0x255F, 0x256B, 0x2562, 0x2559, 0x2568, 0x255C,
+ 0x2551, 0x2550, 0x256D, 0x256E, 0x2570, 0x256F, 0xFFED,
+ /* Big5-HKSCS 0xFA40 .. 0xFA7E */
+ 0xE000, 0x92DB, 0xE002, 0xE003, 0x854C, 0x42B5, 0x73EF, 0x51B5,
+ 0x3649, 0xE009, 0xE00A, 0x9344, 0xE00C, 0x82EE, 0xE00E, 0x783C,
+ 0x6744, 0x62DF, 0xE012, 0xE013, 0xE014, 0xE015, 0xE016, 0x4FAB,
+ 0xE018, 0x5008, 0xE01A, 0xE01B, 0xE01C, 0xE01D, 0xE01E, 0x5029,
+ 0xE020, 0x5FA4, 0xE022, 0xE023, 0x6EDB, 0xE025, 0x507D, 0x5101,
+ 0x347A, 0x510E, 0x986C, 0x3743, 0x8416, 0xE02D, 0xE02E, 0x5160,
+ 0xE030, 0x516A, 0xE032, 0xE033, 0xE034, 0xE035, 0xE036, 0xE037,
+ 0xE038, 0x5B82, 0x877D, 0xE03B, 0xE03C, 0x51B2, 0x51B8,
+ /* Big5-HKSCS 0xFAA1 .. 0xFAFE */
+ 0x9D34, 0x51C9, 0x51CF, 0x51D1, 0x3CDC, 0x51D3, 0xE045,
+ 0x51B3, 0x51E2, 0x5342, 0x51ED, 0x83CD, 0x693E, 0xE04C, 0x5F7B,
+ 0x520B, 0x5226, 0x523C, 0x52B5, 0x5257, 0x5294, 0x52B9, 0x52C5,
+ 0x7C15, 0x8542, 0x52E0, 0x860D, 0xE05A, 0x5305, 0xE05C, 0x5549,
+ 0x6ED9, 0xE05F, 0xE060, 0xE061, 0x5333, 0x5344, 0xE064, 0x6CCB,
+ 0xE066, 0x681B, 0x73D5, 0x604A, 0x3EAA, 0x38CC, 0xE06C, 0x71DD,
+ 0x44A2, 0x536D, 0x5374, 0xE071, 0x537E, 0x537F, 0xE074, 0xE075,
+ 0x77E6, 0x5393, 0xE078, 0x53A0, 0x53AB, 0x53AE, 0x73A7, 0xE07D,
+ 0x3F59, 0x739C, 0x53C1, 0x53C5, 0x6C49, 0x4E49, 0x57FE, 0x53D9,
+ 0x3AAB, 0xE087, 0x53E0, 0xE089, 0xE08A, 0x53F6, 0xE08C, 0x5413,
+ 0x7079, 0x552B, 0x6657, 0x6D5B, 0x546D, 0xE093, 0xE094, 0x555D,
+ 0x548F, 0x54A4, 0x47A6, 0xE099, 0xE09A, 0x3DB4, 0xE09C,
+ /* Big5-HKSCS 0xFB40 .. 0xFB7E */
+ 0xE09D, 0xE09E, 0x5547, 0x4CED, 0x542F, 0x7417, 0x5586, 0x55A9,
+ 0x5605, 0xE0A6, 0xE0A7, 0x4552, 0xE0A9, 0x66B3, 0xE0AB, 0x5637,
+ 0x66CD, 0xE0AE, 0x66A4, 0x66AD, 0x564D, 0x564F, 0x78F1, 0x56F1,
+ 0x9787, 0x53FE, 0x5700, 0x56EF, 0x56ED, 0xE0BA, 0x3623, 0xE0BC,
+ 0x5746, 0xE0BE, 0x6C6E, 0x708B, 0x5742, 0x36B1, 0xE0C3, 0x57E6,
+ 0xE0C5, 0x5803, 0xE0C7, 0xE0C8, 0x5826, 0xE0CA, 0x585C, 0x58AA,
+ 0x3561, 0x58E0, 0x58DC, 0xE0D0, 0x58FB, 0x5BFF, 0x5743, 0xE0D4,
+ 0xE0D5, 0x93D3, 0x35A1, 0x591F, 0x68A6, 0x36C3, 0x6E59,
+ /* Big5-HKSCS 0xFBA1 .. 0xFBFE */
+ 0xE0DC, 0x5A24, 0x5553, 0xE0DF, 0x8505, 0x59C9, 0xE0E2,
+ 0xE0E3, 0xE0E4, 0xE0E5, 0x59D9, 0xE0E7, 0xE0E8, 0xE0E9, 0x6D71,
+ 0xE0EB, 0xE0EC, 0x59F9, 0xE0EE, 0x5AAB, 0x5A63, 0x36E6, 0xE0F2,
+ 0x5A77, 0x3708, 0x5A96, 0x7465, 0x5AD3, 0xE0F8, 0xE0F9, 0x3D85,
+ 0xE0FB, 0x3732, 0xE0FD, 0x5E83, 0x52D0, 0x5B76, 0x6588, 0x5B7C,
+ 0xE103, 0x4004, 0x485D, 0xE106, 0x5BD5, 0x6160, 0xE109, 0xE10A,
+ 0xE10B, 0x5BF3, 0x5B9D, 0x4D10, 0x5C05, 0xE110, 0x5C13, 0x73CE,
+ 0x5C14, 0xE114, 0xE115, 0x5C49, 0x48DD, 0x5C85, 0x5CE9, 0x5CEF,
+ 0x5D8B, 0xE11C, 0xE11D, 0x5D10, 0x5D18, 0x5D46, 0xE121, 0x5CBA,
+ 0x5DD7, 0x82FC, 0x382D, 0xE126, 0xE127, 0xE128, 0x8287, 0x3836,
+ 0x3BC2, 0x5E2E, 0x6A8A, 0x5E75, 0x5E7A, 0xE130, 0xE131, 0x53A6,
+ 0x4EB7, 0x5ED0, 0x53A8, 0xE136, 0x5E09, 0x5EF4, 0xE139,
+ /* Big5-HKSCS 0xFC40 .. 0xFC7E */
+ 0x5EF9, 0x5EFB, 0x38A0, 0x5EFC, 0x683E, 0x941B, 0x5F0D, 0xE141,
+ 0xE142, 0x3ADE, 0x48AE, 0xE145, 0x5F3A, 0xE147, 0xE148, 0x5F58,
+ 0xE14A, 0x5F63, 0x97BD, 0xE14D, 0x5F72, 0x9340, 0xE150, 0x5FA7,
+ 0x5DB6, 0x3D5F, 0xE154, 0xE155, 0xE156, 0xE157, 0x91D6, 0xE159,
+ 0xE15A, 0x6031, 0x6685, 0xE15D, 0x3963, 0x3DC7, 0x3639, 0x5790,
+ 0xE162, 0x7971, 0x3E40, 0x609E, 0x60A4, 0x60B3, 0xE168, 0xE169,
+ 0xE16A, 0x74A4, 0x50E1, 0x5AA0, 0x6164, 0x8424, 0x6142, 0xE171,
+ 0xE172, 0x6181, 0x51F4, 0xE175, 0x6187, 0x5BAA, 0xE178,
+ /* Big5-HKSCS 0xFCA1 .. 0xFCFE */
+ 0xE179, 0x61D3, 0xE17B, 0xE17C, 0x61D0, 0x3932, 0xE17F,
+ 0xE180, 0x6023, 0x615C, 0x651E, 0x638B, 0xE185, 0x62C5, 0xE187,
+ 0x62D5, 0xE189, 0x636C, 0xE18B, 0x3A17, 0x6438, 0x63F8, 0xE18F,
+ 0xE190, 0x6490, 0x6F8A, 0xE193, 0x9814, 0xE195, 0xE196, 0x64E1,
+ 0x64E5, 0x947B, 0x3A66, 0x643A, 0x3A57, 0x654D, 0x6F16, 0xE19F,
+ 0xE1A0, 0x6585, 0x656D, 0x655F, 0xE1A4, 0x65B5, 0xE1A6, 0x4B37,
+ 0x65D1, 0x40D8, 0xE1AA, 0x65E0, 0x65E3, 0x5FDF, 0xE1AE, 0x6618,
+ 0xE1B0, 0xE1B1, 0x6644, 0xE1B3, 0xE1B4, 0x664B, 0xE1B6, 0x6667,
+ 0xE1B8, 0x6673, 0x6674, 0xE1BB, 0xE1BC, 0xE1BD, 0xE1BE, 0xE1BF,
+ 0x77C5, 0xE1C1, 0x99A4, 0x6702, 0xE1C4, 0xE1C5, 0x3B2B, 0x69FA,
+ 0xE1C8, 0x675E, 0x6767, 0x6762, 0xE1CC, 0xE1CD, 0x67D7, 0x44E9,
+ 0x6822, 0x6E50, 0x923C, 0x6801, 0xE1D4, 0xE1D5, 0x685D,
+ /* Big5-HKSCS 0xFD40 .. 0xFD7E */
+ 0xE1D7, 0x69E1, 0x6A0B, 0xE1DA, 0x6973, 0x68C3, 0xE1DD, 0x6901,
+ 0x6900, 0x3D32, 0x3A01, 0xE1E2, 0x3B80, 0x67AC, 0x6961, 0xE1E6,
+ 0x42FC, 0x6936, 0x6998, 0x3BA1, 0xE1EB, 0x8363, 0x5090, 0x69F9,
+ 0xE1EF, 0xE1F0, 0x6A45, 0xE1F2, 0x6A9D, 0x3BF3, 0x67B1, 0x6AC8,
+ 0xE1F7, 0x3C0D, 0x6B1D, 0xE1FA, 0x60DE, 0x6B35, 0x6B74, 0xE1FE,
+ 0x6EB5, 0xE200, 0xE201, 0xE202, 0x3740, 0x5421, 0xE205, 0x6BE1,
+ 0xE207, 0x6BDC, 0x6C37, 0xE20A, 0xE20B, 0xE20C, 0x6C5A, 0x8226,
+ 0x6C79, 0xE210, 0x44C5, 0xE212, 0xE213, 0xE214, 0xE215,
+ /* Big5-HKSCS 0xFDA1 .. 0xFDFE */
+ 0xE216, 0x36E5, 0x3CEB, 0xE219, 0x9B83, 0xE21B, 0xE21C,
+ 0x7F8F, 0x6837, 0xE21F, 0xE220, 0xE221, 0x6D96, 0x6D5C, 0x6E7C,
+ 0x6F04, 0xE226, 0xE227, 0xE228, 0x8533, 0xE22A, 0x51C7, 0x6C9C,
+ 0x6E1D, 0x842E, 0xE22F, 0x6E2F, 0xE231, 0x7453, 0xE233, 0x79CC,
+ 0x6E4F, 0x5A91, 0xE237, 0x6FF8, 0x370D, 0x6F9D, 0xE23B, 0x6EFA,
+ 0xE23D, 0xE23E, 0x4555, 0x93F0, 0x6F44, 0x6F5C, 0x3D4E, 0x6F74,
+ 0xE245, 0x3D3B, 0x6F9F, 0xE248, 0x6FD3, 0xE24A, 0xE24B, 0xE24C,
+ 0xE24D, 0xE24E, 0xE24F, 0x51DF, 0xE251, 0xE252, 0xE253, 0xE254,
+ 0x704B, 0x707E, 0x70A7, 0x7081, 0x70CC, 0x70D5, 0x70D6, 0x70DF,
+ 0x4104, 0x3DE8, 0x71B4, 0x7196, 0xE261, 0x712B, 0x7145, 0x5A88,
+ 0x714A, 0x716E, 0x5C9C, 0xE268, 0x714F, 0x9362, 0xE26B, 0x712C,
+ 0xE26D, 0xE26E, 0xE26F, 0x71BA, 0xE271, 0x70BD, 0x720E,
+ /* Big5-HKSCS 0xFE40 .. 0xFE7E */
+ 0x9442, 0x7215, 0x5911, 0x9443, 0x7224, 0x9341, 0xE27A, 0x722E,
+ 0x7240, 0xE27D, 0x68BD, 0x7255, 0x7257, 0x3E55, 0xE282, 0x680D,
+ 0x6F3D, 0x7282, 0x732A, 0x732B, 0xE288, 0xE289, 0x48ED, 0xE28B,
+ 0x7328, 0x732E, 0x73CF, 0x73AA, 0xE290, 0xE291, 0x73C9, 0x7449,
+ 0xE294, 0xE295, 0xE296, 0x6623, 0x36C5, 0xE299, 0xE29A, 0xE29B,
+ 0x73F7, 0x7415, 0x6903, 0xE29F, 0x7439, 0xE2A1, 0x3ED7, 0x745C,
+ 0xE2A4, 0x7460, 0xE2A6, 0x7447, 0x73E4, 0x7476, 0x83B9, 0x746C,
+ 0x3730, 0x7474, 0x93F1, 0x6A2C, 0x7482, 0x4953, 0xE2B2,
+ /* Big5-HKSCS 0xFEA1 .. 0xFEFE */
+ 0xE2B3, 0xE2B4, 0xE2B5, 0x5B46, 0xE2B7, 0xE2B8, 0x74C8,
+ 0xE2BA, 0x750E, 0x74E9, 0x751E, 0xE2BE, 0xE2BF, 0x5BD7, 0xE2C1,
+ 0x9385, 0x754D, 0x754A, 0x7567, 0x756E, 0xE2C7, 0x3F04, 0xE2C9,
+ 0x758E, 0x745D, 0x759E, 0x75B4, 0x7602, 0x762C, 0x7651, 0x764F,
+ 0x766F, 0x7676, 0xE2D4, 0x7690, 0x81EF, 0x37F8, 0xE2D8, 0xE2D9,
+ 0x76A1, 0x76A5, 0x76B7, 0x76CC, 0xE2DE, 0x8462, 0xE2E0, 0xE2E1,
+ 0xE2E2, 0x771E, 0x7726, 0x7740, 0x64AF, 0xE2E7, 0x7758, 0xE2E9,
+ 0x77AF, 0xE2EB, 0xE2EC, 0xE2ED, 0x77F4, 0x7809, 0xE2F0, 0xE2F1,
+ 0x68CA, 0x78AF, 0x78C7, 0x78D3, 0x96A5, 0x792E, 0xE2F8, 0x78D7,
+ 0x7934, 0x78B1, 0xE2FC, 0x8FB8, 0x8884, 0xE2FF, 0xE300, 0xE301,
+ 0x7986, 0x8900, 0x6902, 0x7980, 0xE306, 0x799D, 0xE308, 0x793C,
+ 0x79A9, 0x6E2A, 0xE30C, 0x3EA8, 0x79C6, 0xE30F, 0x79D4,
+};
+
+
+/* Returns the number of bytes of Bytes consumed. */
+static int qt_Big5hkscsToUnicode(const uchar *s, uint *pwc)
+{
+ uchar c1 = s[0];
+ if ((c1 >= 0x81 && c1 <= 0xfe)) {
+ uchar c2 = s[1];
+ if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) {
+ uint i = 157 * (c1 - 0x81) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40));
+ ushort wc = 0xfffd;
+ if (i < 19782)
+ wc = big5hkscs_to_ucs[i];
+ if (wc != 0xfffd) {
+ *pwc = (uint) wc;
+ return 2;
+ }
+ }
+ return 0;
+ } else if (c1 < 0x80) {
+ *pwc = (uint) c1;
+ return 1;
+ }
+ return 0;
+}
+
+//---------------------------------------------------------------------------
+
+/*
+ * ucs4 to big5hkscs convert routing
+ */
+
+typedef struct {
+ ushort index; /* index into big table */
+ ushort used; /* bittqmask of used entries */
+} Summary16;
+
+/* UCS4 to big5hkscs convert table */
+static const uchar big5hkscs_to_charset[24908][2] = {
+ {0x21,0x00}, {0xA2,0x46}, {0xA2,0x47}, {0xA2,0x44},
+ {0x7C,0x00}, {0xA1,0xB1}, {0xC6,0xD8}, {0x63,0x00},
+ {0x61,0x00}, {0x2D,0x00}, {0x52,0x00}, {0xA1,0xC2},
+ {0xA2,0x58}, {0xA1,0xD3}, {0x32,0x00}, {0x33,0x00},
+ {0xA1,0xA6}, {0xA3,0x67}, {0xA1,0x50}, {0xA1,0x4D},
+ {0x31,0x00}, {0x6F,0x00}, {0x3F,0x00}, {0x88,0x59},
+ {0x88,0x57}, {0x41,0x00}, {0x41,0x00}, {0x41,0x00},
+ {0x41,0x00}, {0x41,0x00}, {0x43,0x00}, {0x88,0x5D},
+ {0x88,0x5B}, {0x88,0x66}, {0x45,0x00}, {0x49,0x00},
+ {0x49,0x00}, {0x49,0x00}, {0x49,0x00}, {0x44,0x00},
+ {0x4E,0x00}, {0x88,0x61}, {0x88,0x5F}, {0x4F,0x00},
+ {0x4F,0x00}, {0x4F,0x00}, {0xA1,0xD1}, {0x4F,0x00},
+ {0x55,0x00}, {0x55,0x00}, {0x55,0x00}, {0x55,0x00},
+ {0x59,0x00}, {0x54,0x00}, {0x73,0x00}, {0x88,0x6A},
+ {0x88,0x68}, {0x61,0x00}, {0x61,0x00}, {0x61,0x00},
+ {0x61,0x00}, {0x61,0x00}, {0x63,0x00}, {0x88,0x6F},
+ {0x88,0x6D}, {0x88,0xA7}, {0x65,0x00}, {0x88,0x73},
+ {0x88,0x71}, {0x69,0x00}, {0x69,0x00}, {0x65,0x00},
+ {0x6E,0x00}, {0x88,0x77}, {0x88,0x75}, {0x6F,0x00},
+ {0x6F,0x00}, {0x6F,0x00}, {0xA1,0xD2}, {0xC8,0xFB},
+ {0x88,0x7B}, {0x88,0x79}, {0x75,0x00}, {0x88,0xA2},
+ {0x79,0x00}, {0x74,0x00}, {0x79,0x00}, {0x88,0x56},
+ {0x88,0x67}, {0x88,0x5A}, {0x88,0x6C}, {0x88,0x5C},
+ {0x88,0x6E}, {0x88,0x70}, {0xC8,0xFC}, {0x88,0x5E},
+ {0x88,0x74}, {0xC8,0xFA}, {0x88,0x78}, {0x88,0x58},
+ {0x88,0x69}, {0x88,0x72}, {0x88,0x60}, {0x88,0x76},
+ {0x88,0x7A}, {0x88,0x7C}, {0x88,0x7D}, {0x88,0x7E},
+ {0x88,0xA1}, {0xC8,0xF6}, {0x88,0x6B}, {0xC8,0xF8},
+ {0xC8,0xF7}, {0x88,0xA8}, {0xC8,0xFE}, {0xC8,0xF9},
+ {0xC8,0xF5}, {0xC8,0xFD}, {0xC6,0xD9}, {0xA3,0xBE},
+ {0xA3,0xBC}, {0xA3,0xBD}, {0xA3,0xBF}, {0xA1,0xC5},
+ {0xA3,0xBB}, {0xA1,0xC2}, {0xA3,0x44}, {0xA3,0x45},
+ {0xA3,0x46}, {0xA3,0x47}, {0xA3,0x48}, {0xA3,0x49},
+ {0xA3,0x4A}, {0xA3,0x4B}, {0xA3,0x4C}, {0xA3,0x4D},
+ {0xA3,0x4E}, {0xA3,0x4F}, {0xA3,0x50}, {0xA3,0x51},
+ {0xA3,0x52}, {0xA3,0x53}, {0xA3,0x54}, {0xA3,0x55},
+ {0xA3,0x56}, {0xA3,0x57}, {0xA3,0x58}, {0xA3,0x59},
+ {0xA3,0x5A}, {0xA3,0x5B}, {0xA3,0x5C}, {0xA3,0x5D},
+ {0xA3,0x5E}, {0xA3,0x5F}, {0xA3,0x60}, {0xA3,0x61},
+ {0xA3,0x62}, {0xA3,0x63}, {0xA3,0x64}, {0xA3,0x65},
+ {0xA3,0x66}, {0xA3,0x67}, {0xA3,0x68}, {0xA3,0x69},
+ {0xA3,0x6A}, {0xA3,0x6B}, {0xA3,0x6C}, {0xA3,0x6D},
+ {0xA3,0x6E}, {0xA3,0x6F}, {0xA3,0x70}, {0xA3,0x71},
+ {0xA3,0x72}, {0xA3,0x73}, {0xC7,0xF9}, {0xC7,0xF3},
+ {0xC7,0xF4}, {0xC7,0xF5}, {0xC7,0xF6}, {0xC7,0xF7},
+ {0xC7,0xF8}, {0xC7,0xFA}, {0xC7,0xFB}, {0xC7,0xFC},
+ {0xC7,0xFD}, {0xC7,0xFE}, {0xC8,0x40}, {0xC8,0x41},
+ {0xC8,0x42}, {0xC8,0x43}, {0xC8,0x44}, {0xC8,0x45},
+ {0xC8,0x46}, {0xC8,0x47}, {0xC8,0x48}, {0xC8,0x49},
+ {0xC8,0x4A}, {0xC8,0x4B}, {0xC8,0x4C}, {0xC8,0x4D},
+ {0xC8,0x4E}, {0xC8,0x4F}, {0xC8,0x50}, {0xC8,0x51},
+ {0xC8,0x52}, {0xC8,0x53}, {0xC8,0x54}, {0xC8,0x55},
+ {0xC8,0x56}, {0xC8,0x57}, {0xC8,0x58}, {0xC8,0x59},
+ {0xC8,0x5A}, {0xC8,0x5C}, {0xC8,0x5D}, {0xC8,0x5E},
+ {0xC8,0x5F}, {0xC8,0x60}, {0xC8,0x61}, {0xC8,0x62},
+ {0xC8,0x63}, {0xC8,0x64}, {0xC8,0x65}, {0xC8,0x66},
+ {0xC8,0x67}, {0xC8,0x68}, {0xC8,0x69}, {0xC8,0x6A},
+ {0xC8,0x6B}, {0xC8,0x6C}, {0xC8,0x6D}, {0xC8,0x6E},
+ {0xC8,0x6F}, {0xC8,0x70}, {0xC8,0x71}, {0xC8,0x72},
+ {0xC8,0x73}, {0xC8,0x74}, {0xC8,0x75}, {0xC8,0x5B},
+ {0x88,0x63}, {0x88,0xA4}, {0x88,0x65}, {0x88,0xA6},
+ {0xA1,0x56}, {0xA1,0x58}, {0xA2,0x77}, {0xA1,0xFC},
+ {0xA1,0xA5}, {0xA1,0xA6}, {0xA1,0xA7}, {0xA1,0xA8},
+ {0xA1,0x45}, {0xA3,0xBB}, {0xA1,0x4C}, {0xA1,0x4B},
+ {0xA1,0x45}, {0xA1,0xAC}, {0xA1,0xB2}, {0xA1,0xAB},
+ {0xA1,0xB0}, {0xA1,0xC3}, {0xA3,0xE1}, {0xA2,0x4A},
+ {0xA1,0xC1}, {0xA2,0x4B}, {0xC8,0xD2}, {0xC8,0xD3},
+ {0xA2,0xB9}, {0xA2,0xBA}, {0xA2,0xBB}, {0xA2,0xBC},
+ {0xA2,0xBD}, {0xA2,0xBE}, {0xA2,0xBF}, {0xA2,0xC0},
+ {0xA2,0xC1}, {0xA2,0xC2}, {0xC6,0xB5}, {0xC6,0xB6},
+ {0xC6,0xB7}, {0xC6,0xB8}, {0xC6,0xB9}, {0xC6,0xBA},
+ {0xC6,0xBB}, {0xC6,0xBC}, {0xC6,0xBD}, {0xC6,0xBE},
+ {0xA1,0xF6}, {0xA1,0xF4}, {0xA1,0xF7}, {0xA1,0xF5},
+ {0xA1,0xF8}, {0xA1,0xF9}, {0xA1,0xFB}, {0xA1,0xFA},
+ {0xC8,0x77}, {0xC8,0x78}, {0xC8,0x76}, {0xA2,0x41},
+ {0xA2,0x42}, {0xA2,0x58}, {0xA1,0xD4}, {0xA1,0xDB},
+ {0xA1,0xE8}, {0xA1,0xE7}, {0xA1,0xFD}, {0xA1,0xFC},
+ {0xA1,0xE4}, {0xA1,0xE5}, {0xA1,0xEC}, {0xA1,0xED},
+ {0xA1,0xEF}, {0xA1,0xEE}, {0xA1,0xDC}, {0xA1,0xDA},
+ {0xA1,0xDD}, {0xA1,0xDD}, {0xA1,0xD8}, {0xA1,0xD9},
+ {0xA1,0xF2}, {0xA1,0xF3}, {0xA1,0xE6}, {0xA1,0xE9},
+ {0xA1,0x5B}, {0xC6,0xA1}, {0xC6,0xA2}, {0xC6,0xA3},
+ {0xC6,0xA4}, {0xC6,0xA5}, {0xC6,0xA6}, {0xC6,0xA7},
+ {0xC6,0xA8}, {0xC6,0xA9}, {0xC6,0xAA}, {0xC6,0xAB},
+ {0xC6,0xAC}, {0xC6,0xAD}, {0xC6,0xAE}, {0xC6,0xAF},
+ {0xC6,0xB0}, {0xC6,0xB1}, {0xC6,0xB2}, {0xC6,0xB3},
+ {0xC6,0xB4}, {0xA2,0x77}, {0xA2,0x78}, {0xA2,0x7A},
+ {0xA2,0x7B}, {0xA2,0x7C}, {0xA2,0x7D}, {0xA2,0x75},
+ {0xA2,0x74}, {0xA2,0x73}, {0xA2,0x72}, {0xA2,0x71},
+ {0xF9,0xF9}, {0xF9,0xF8}, {0xF9,0xE6}, {0xF9,0xEF},
+ {0xF9,0xDD}, {0xF9,0xE8}, {0xF9,0xF1}, {0xF9,0xDF},
+ {0xF9,0xEC}, {0xF9,0xF5}, {0xF9,0xE3}, {0xF9,0xEE},
+ {0xF9,0xF7}, {0xF9,0xE5}, {0xF9,0xE9}, {0xF9,0xF2},
+ {0xF9,0xE0}, {0xF9,0xEB}, {0xF9,0xF4}, {0xF9,0xE2},
+ {0xF9,0xE7}, {0xF9,0xF0}, {0xF9,0xDE}, {0xF9,0xED},
+ {0xF9,0xF6}, {0xF9,0xE4}, {0xF9,0xEA}, {0xF9,0xF3},
+ {0xF9,0xE1}, {0xF9,0xFA}, {0xF9,0xFB}, {0xF9,0xFD},
+ {0xF9,0xFC}, {0xA2,0xAC}, {0xA2,0xAD}, {0xA2,0xAE},
+ {0xA1,0x5A}, {0xA2,0x62}, {0xA2,0x63}, {0xA2,0x64},
+ {0xA2,0x65}, {0xA2,0x66}, {0xA2,0x67}, {0xA2,0x68},
+ {0xA2,0x69}, {0xA2,0x70}, {0xA2,0x6F}, {0xA2,0x6E},
+ {0xA2,0x6D}, {0xA2,0x6C}, {0xA2,0x6B}, {0xA2,0x6A},
+ {0xF9,0xFE}, {0xA2,0x76}, {0xA2,0x79}, {0xA1,0xBD},
+ {0xA1,0xBC}, {0xA1,0xB6}, {0xA1,0xB5}, {0xA1,0xBF},
+ {0xA1,0xBE}, {0xA1,0xBB}, {0xA1,0xBA}, {0xA1,0xB3},
+ {0xA1,0xB7}, {0xA1,0xB4}, {0xA2,0xA8}, {0xA2,0xA9},
+ {0xA2,0xAB}, {0xA2,0xAA}, {0xA1,0xB9}, {0xA1,0xB8},
+ {0xA1,0xF3}, {0xA1,0xF0}, {0xA1,0xF2}, {0xA1,0xF1},
+ {0xC6,0xE6}, {0xC8,0xD6}, {0xC8,0xD7}, {0xC8,0xD8},
+ {0xC8,0xD9}, {0xC8,0xDA}, {0xC8,0xDB}, {0xC8,0xDC},
+ {0xC8,0xDD}, {0xC8,0xDE}, {0xC8,0xDF}, {0xC8,0xE0},
+ {0xC8,0xE1}, {0xC8,0xE2}, {0xC8,0xE3}, {0xC8,0xE4},
+ {0xC8,0xE5}, {0xC8,0xE6}, {0xC8,0xE7}, {0xC8,0xE8},
+ {0xC8,0xE9}, {0xC8,0xEA}, {0xC8,0xEB}, {0xC8,0xEC},
+ {0xC8,0xED}, {0xC8,0xEE}, {0xC8,0xEF}, {0xC8,0xF0},
+ {0xC8,0xF1}, {0xC6,0xCD}, {0xA1,0x40}, {0xA1,0x42},
+ {0xA1,0x43}, {0xA1,0xB2}, {0xC6,0xE0}, {0xC6,0xE1},
+ {0xC6,0xE2}, {0xA1,0x71}, {0xA1,0x72}, {0xA1,0x6D},
+ {0xA1,0x6E}, {0xA1,0x75}, {0xA1,0x76}, {0xA1,0x79},
+ {0xA1,0x7A}, {0xA1,0x69}, {0xA1,0x6A}, {0xA2,0x45},
+ {0xA1,0x65}, {0xA1,0x66}, {0xA1,0xE3}, {0xA1,0xA9},
+ {0xA1,0xAA}, {0xA2,0xC3}, {0xA2,0xC4}, {0xA2,0xC5},
+ {0xA2,0xC6}, {0xA2,0xC7}, {0xA2,0xC8}, {0xA2,0xC9},
+ {0xA2,0xCA}, {0xA2,0xCB}, {0xA1,0xCA}, {0xC6,0xE7},
+ {0xC6,0xE8}, {0xC6,0xE9}, {0xC6,0xEA}, {0xC6,0xEB},
+ {0xC6,0xEC}, {0xC6,0xED}, {0xC6,0xEE}, {0xC6,0xEF},
+ {0xC6,0xF0}, {0xC6,0xF1}, {0xC6,0xF2}, {0xC6,0xF3},
+ {0xC6,0xF4}, {0xC6,0xF5}, {0xC6,0xF6}, {0xC6,0xF7},
+ {0xC6,0xF8}, {0xC6,0xF9}, {0xC6,0xFA}, {0xC6,0xFB},
+ {0xC6,0xFC}, {0xC6,0xFD}, {0xC6,0xFE}, {0xC7,0x40},
+ {0xC7,0x41}, {0xC7,0x42}, {0xC7,0x43}, {0xC7,0x44},
+ {0xC7,0x45}, {0xC7,0x46}, {0xC7,0x47}, {0xC7,0x48},
+ {0xC7,0x49}, {0xC7,0x4A}, {0xC7,0x4B}, {0xC7,0x4C},
+ {0xC7,0x4D}, {0xC7,0x4E}, {0xC7,0x4F}, {0xC7,0x50},
+ {0xC7,0x51}, {0xC7,0x52}, {0xC7,0x53}, {0xC7,0x54},
+ {0xC7,0x55}, {0xC7,0x56}, {0xC7,0x57}, {0xC7,0x58},
+ {0xC7,0x59}, {0xC7,0x5A}, {0xC7,0x5B}, {0xC7,0x5C},
+ {0xC7,0x5D}, {0xC7,0x5E}, {0xC7,0x5F}, {0xC7,0x60},
+ {0xC7,0x61}, {0xC7,0x62}, {0xC7,0x63}, {0xC7,0x64},
+ {0xC7,0x65}, {0xC7,0x66}, {0xC7,0x67}, {0xC7,0x68},
+ {0xC7,0x69}, {0xC7,0x6A}, {0xC7,0x6B}, {0xC7,0x6C},
+ {0xC7,0x6D}, {0xC7,0x6E}, {0xC7,0x6F}, {0xC7,0x70},
+ {0xC7,0x71}, {0xC7,0x72}, {0xC7,0x73}, {0xC7,0x74},
+ {0xC7,0x75}, {0xC7,0x76}, {0xC7,0x77}, {0xC7,0x78},
+ {0xC7,0x79}, {0xC7,0x7A}, {0xC8,0xD4}, {0xC8,0xD5},
+ {0xC6,0xDC}, {0xC6,0xDD}, {0xC7,0x7B}, {0xC7,0x7C},
+ {0xC7,0x7D}, {0xC7,0x7E}, {0xC7,0xA1}, {0xC7,0xA2},
+ {0xC7,0xA3}, {0xC7,0xA4}, {0xC7,0xA5}, {0xC7,0xA6},
+ {0xC7,0xA7}, {0xC7,0xA8}, {0xC7,0xA9}, {0xC7,0xAA},
+ {0xC7,0xAB}, {0xC7,0xAC}, {0xC7,0xAD}, {0xC7,0xAE},
+ {0xC7,0xAF}, {0xC7,0xB0}, {0xC7,0xB1}, {0xC7,0xB2},
+ {0xC7,0xB3}, {0xC7,0xB4}, {0xC7,0xB5}, {0xC7,0xB6},
+ {0xC7,0xB7}, {0xC7,0xB8}, {0xC7,0xB9}, {0xC7,0xBA},
+ {0xC7,0xBB}, {0xC7,0xBC}, {0xC7,0xBD}, {0xC7,0xBE},
+ {0xC7,0xBF}, {0xC7,0xC0}, {0xC7,0xC1}, {0xC7,0xC2},
+ {0xC7,0xC3}, {0xC7,0xC4}, {0xC7,0xC5}, {0xC7,0xC6},
+ {0xC7,0xC7}, {0xC7,0xC8}, {0xC7,0xC9}, {0xC7,0xCA},
+ {0xC7,0xCB}, {0xC7,0xCC}, {0xC7,0xCD}, {0xC7,0xCE},
+ {0xC7,0xCF}, {0xC7,0xD0}, {0xC7,0xD1}, {0xC7,0xD2},
+ {0xC7,0xD3}, {0xC7,0xD4}, {0xC7,0xD5}, {0xC7,0xD6},
+ {0xC7,0xD7}, {0xC7,0xD8}, {0xC7,0xD9}, {0xC7,0xDA},
+ {0xC7,0xDB}, {0xC7,0xDC}, {0xC7,0xDD}, {0xC7,0xDE},
+ {0xC7,0xDF}, {0xC7,0xE0}, {0xC7,0xE1}, {0xC7,0xE2},
+ {0xC7,0xE3}, {0xC7,0xE4}, {0xC7,0xE5}, {0xC7,0xE6},
+ {0xC7,0xE7}, {0xC7,0xE8}, {0xC7,0xE9}, {0xC7,0xEA},
+ {0xC7,0xEB}, {0xC7,0xEC}, {0xC7,0xED}, {0xC7,0xEE},
+ {0xC7,0xEF}, {0xC7,0xF0}, {0xC7,0xF1}, {0xC7,0xF2},
+ {0xC6,0xE3}, {0xC6,0xDA}, {0xC6,0xDB}, {0xA3,0x74},
+ {0xA3,0x75}, {0xA3,0x76}, {0xA3,0x77}, {0xA3,0x78},
+ {0xA3,0x79}, {0xA3,0x7A}, {0xA3,0x7B}, {0xA3,0x7C},
+ {0xA3,0x7D}, {0xA3,0x7E}, {0xA3,0xA1}, {0xA3,0xA2},
+ {0xA3,0xA3}, {0xA3,0xA4}, {0xA3,0xA5}, {0xA3,0xA6},
+ {0xA3,0xA7}, {0xA3,0xA8}, {0xA3,0xA9}, {0xA3,0xAA},
+ {0xA3,0xAB}, {0xA3,0xAC}, {0xA3,0xAD}, {0xA3,0xAE},
+ {0xA3,0xAF}, {0xA3,0xB0}, {0xA3,0xB1}, {0xA3,0xB2},
+ {0xA3,0xB3}, {0xA3,0xB4}, {0xA3,0xB5}, {0xA3,0xB6},
+ {0xA3,0xB7}, {0xA3,0xB8}, {0xA3,0xB9}, {0xA3,0xBA},
+ {0xA4,0x40}, {0xA4,0x47}, {0xA4,0x54}, {0xA5,0x7C},
+ {0xA4,0x57}, {0xA4,0xA4}, {0xA4,0x55}, {0xA5,0xD2},
+ {0xA4,0x41}, {0xA4,0xFE}, {0xA4,0x42}, {0xA4,0xD1},
+ {0xA6,0x61}, {0xA4,0x48}, {0xA4,0x40}, {0xA4,0x47},
+ {0xA4,0x54}, {0xA5,0x7C}, {0xA4,0xAD}, {0xA4,0xBB},
+ {0xA4,0x43}, {0xA4,0x4B}, {0xA4,0x45}, {0xA4,0x51},
+ {0xA4,0xEB}, {0xA4,0xF5}, {0xA4,0xF4}, {0xA4,0xEC},
+ {0xAA,0xF7}, {0xA4,0x67}, {0xA4,0xE9}, {0xC8,0xD1},
+ {0xA6,0xB3}, {0xAA,0xC0}, {0xA6,0x57}, {0xAF,0x53},
+ {0xB0,0x5D}, {0xAF,0xAC}, {0xB3,0xD2}, {0xA5,0x4E},
+ {0xA9,0x49}, {0xBE,0xC7}, {0xBA,0xCA}, {0xA5,0xF8},
+ {0xB8,0xEA}, {0xA8,0xF3}, {0xB2,0xBD}, {0xA5,0xF0},
+ {0xA6,0xDB}, {0xA6,0xDC}, {0xA4,0x40}, {0xA4,0x47},
+ {0xA4,0x54}, {0xA5,0x7C}, {0xA4,0xAD}, {0xA4,0xBB},
+ {0xA4,0x43}, {0xA4,0x4B}, {0xA4,0x45}, {0xA4,0x51},
+ {0xA4,0xEB}, {0xA4,0xF5}, {0xA4,0xF4}, {0xA4,0xEC},
+ {0xAA,0xF7}, {0xA4,0x67}, {0xA4,0xE9}, {0xAE,0xE8},
+ {0xA6,0xB3}, {0xAA,0xC0}, {0xA6,0x57}, {0xAF,0x53},
+ {0xB0,0x5D}, {0xAF,0xAC}, {0xB3,0xD2}, {0xAF,0xB5},
+ {0xA8,0x6B}, {0xA4,0x6B}, {0xBE,0x41}, {0xC0,0x75},
+ {0xA6,0x4C}, {0xAA,0x60}, {0xB6,0xB5}, {0xA5,0xF0},
+ {0xBC,0x67}, {0xA1,0xC0}, {0xA4,0x57}, {0xA4,0xA4},
+ {0xA4,0x55}, {0xA5,0xAA}, {0xA5,0x6B}, {0xC2,0xE5},
+ {0xA9,0x76}, {0xBE,0xC7}, {0xBA,0xCA}, {0xA5,0xF8},
+ {0xB8,0xEA}, {0xA8,0xF3}, {0xA9,0x5D}, {0xA2,0x55},
+ {0xA2,0x56}, {0xA2,0x50}, {0xA2,0x51}, {0xA2,0x52},
+ {0xA2,0x54}, {0xA2,0x57}, {0xA2,0x53}, {0xA1,0xEB},
+ {0xA1,0xEA}, {0xA2,0x4F}, {0x92,0x77}, {0x96,0xDF},
+ {0x89,0xD5}, {0x93,0xCD}, {0x9B,0xDF}, {0xFA,0x68},
+ {0x89,0xDA}, {0x8F,0x59}, {0x89,0xDB}, {0x8F,0x5D},
+ {0x89,0xDC}, {0x96,0xF7}, {0x8A,0xDA}, {0x8B,0xDC},
+ {0x97,0xDB}, {0x9E,0x53}, {0x9D,0xAA}, {0x9B,0xEA},
+ {0x8A,0x6E}, {0x8B,0xC8}, {0x89,0xE8}, {0x89,0xEA},
+ {0x8C,0x4B}, {0xFB,0x70}, {0x89,0xED}, {0x94,0xDD},
+ {0x89,0xEE}, {0x9E,0xB4}, {0x8A,0xD3}, {0x92,0xDB},
+ {0x94,0xDB}, {0x89,0xF9}, {0xFB,0x7A}, {0x89,0xFB},
+ {0x9E,0xFC}, {0x89,0xFC}, {0x89,0xBF}, {0x89,0xFE},
+ {0x89,0xE6}, {0x9D,0x46}, {0x9D,0xEE}, {0xA0,0x7E},
+ {0xA0,0x68}, {0x98,0xE9}, {0x8B,0x68}, {0x8D,0xFD},
+ {0x8B,0xBE}, {0x9F,0xD9}, {0x8A,0xEB}, {0x9F,0xD7},
+ {0x8B,0x6A}, {0x9C,0x5C}, {0x8B,0xB1}, {0xFB,0x5E},
+ {0x9D,0xF3}, {0xA0,0xD0}, {0xFC,0x66}, {0x92,0xE9},
+ {0x9A,0xEC}, {0x8F,0xAB}, {0xFA,0x48}, {0x8E,0x45},
+ {0x9C,0x6F}, {0x9E,0xDE}, {0x89,0xEF}, {0x96,0xE9},
+ {0x9E,0xBB}, {0x94,0xDE}, {0x9E,0xB8}, {0x97,0xBA},
+ {0xFB,0x65}, {0x95,0xD6}, {0x9C,0xBB}, {0x97,0xDA},
+ {0x8F,0x45}, {0xFB,0x7D}, {0x91,0x58}, {0xFE,0x64},
+ {0x98,0x56}, {0x9B,0x4D}, {0x93,0x5B}, {0x95,0xC7},
+ {0x97,0xE7}, {0x93,0x59}, {0x91,0xF5}, {0x97,0xB8},
+ {0xFD,0xA2}, {0xFB,0xB6}, {0x92,0xFA}, {0x93,0x57},
+ {0x8B,0xA6}, {0xFB,0xB9}, {0x97,0xB0}, {0xFD,0xC4},
+ {0x9C,0xA1}, {0x91,0xF2}, {0x91,0xF9}, {0x8F,0xF1},
+ {0x97,0x45}, {0x98,0x53}, {0xFE,0x78}, {0xFB,0xC1},
+ {0x92,0x51}, {0x9D,0xAD}, {0xFD,0x6C}, {0xFA,0x6B},
+ {0x9B,0xC2}, {0x9A,0x7B}, {0x8B,0x60}, {0x93,0x4B},
+ {0x9A,0xBD}, {0x91,0xB7}, {0x95,0xB4}, {0xFE,0xC5},
+ {0x9E,0xF0}, {0x8D,0x64}, {0x92,0x69}, {0x8D,0x67},
+ {0xFB,0xEA}, {0xFB,0xEF}, {0x8D,0x68}, {0x93,0xEB},
+ {0xFC,0x42}, {0x91,0x66}, {0xFA,0xCD}, {0x93,0xDD},
+ {0x8B,0xCC}, {0x8D,0x6D}, {0x8D,0x6E}, {0x96,0xA8},
+ {0xFC,0xA6}, {0x8D,0x6F}, {0x8D,0x70}, {0xFC,0x64},
+ {0x90,0x60}, {0x8D,0x74}, {0x97,0xC3}, {0x8A,0xD0},
+ {0x92,0x74}, {0x9B,0xBE}, {0x9C,0xC8}, {0x9C,0xBA},
+ {0x8D,0x78}, {0x9E,0xB9}, {0x95,0x5A}, {0x91,0xB4},
+ {0x8A,0x48}, {0x8D,0x7D}, {0x8A,0x7D}, {0x8A,0xC2},
+ {0xFD,0x4A}, {0x8D,0xA1}, {0x8A,0xD1}, {0xFC,0xB4},
+ {0x8B,0x47}, {0x93,0xA4}, {0x9E,0xDA}, {0x8A,0x51},
+ {0x8D,0xA6}, {0x9E,0xC5}, {0xFC,0xC4}, {0xA0,0x78},
+ {0x94,0xB5}, {0xFC,0xC2}, {0x8A,0x6B}, {0x8D,0xAB},
+ {0xFA,0xE8}, {0x8D,0xAD}, {0xFC,0x49}, {0x93,0xC1},
+ {0x90,0x6F}, {0x8D,0xB0}, {0x94,0x7E}, {0x90,0xFA},
+ {0x94,0x79}, {0x8D,0xB2}, {0xFC,0xEE}, {0x99,0x7B},
+ {0x8D,0xB4}, {0x8D,0xB7}, {0x91,0xB3}, {0x8D,0xBB},
+ {0x8D,0xBA}, {0x8D,0xBC}, {0x90,0x44}, {0xFD,0x4C},
+ {0x93,0xE4}, {0x93,0xE0}, {0xFD,0x53}, {0x8D,0xC3},
+ {0x9B,0xB8}, {0xFB,0xF0}, {0x93,0xE9}, {0x93,0xF6},
+ {0x8D,0xC5}, {0x8D,0xCA}, {0x8D,0xCC}, {0xFD,0x5D},
+ {0x93,0xB5}, {0xFD,0x61}, {0x9C,0xF8}, {0x92,0x52},
+ {0xA0,0xE8}, {0x9C,0xA5}, {0x8C,0x56}, {0x8D,0xD6},
+ {0x97,0xC0}, {0xA0,0xDE}, {0x97,0xD2}, {0xFA,0xA5},
+ {0xFD,0xA3}, {0x8D,0xDB}, {0x8E,0xAF}, {0x91,0xB5},
+ {0xFD,0x49}, {0xFD,0xD1}, {0x8D,0xEB}, {0x97,0xC6},
+ {0xFD,0xCE}, {0x90,0xFC}, {0xFC,0x59}, {0x96,0xD6},
+ {0x97,0xC5}, {0x8D,0xEF}, {0x97,0xD7}, {0x8D,0xF0},
+ {0x96,0xA6}, {0xFB,0xBF}, {0x8D,0xF3}, {0x94,0x49},
+ {0x8D,0xF5}, {0x98,0x72}, {0x8E,0x6B}, {0xFA,0xFD},
+ {0x8F,0x50}, {0x9D,0xCC}, {0xFC,0x65}, {0x8C,0x44},
+ {0x99,0x6E}, {0x94,0xA1}, {0x8F,0x63}, {0xA0,0xDA},
+ {0x92,0x53}, {0xFD,0xE9}, {0x9D,0xB5}, {0x98,0x79},
+ {0x9D,0x5D}, {0x8D,0x63}, {0x96,0x69}, {0x9F,0x70},
+ {0xFC,0x6A}, {0x8A,0xC7}, {0x89,0xD7}, {0xFE,0x4D},
+ {0x9E,0xDD}, {0xFE,0xFB}, {0x98,0xBC}, {0xFA,0xCC},
+ {0x95,0xB0}, {0x94,0x64}, {0x93,0x6F}, {0x94,0xB9},
+ {0x95,0xEC}, {0x91,0xEE}, {0x98,0xC3}, {0x95,0xF6},
+ {0x8F,0xFD}, {0x98,0xC5}, {0x97,0x66}, {0xFE,0x6E},
+ {0x97,0xDD}, {0x8C,0xAA}, {0x92,0xD2}, {0x97,0x61},
+ {0x98,0xCB}, {0x95,0xF0}, {0x97,0x5D}, {0x91,0xE3},
+ {0x98,0xCC}, {0x94,0x69}, {0x98,0xCD}, {0x98,0xCE},
+ {0x95,0xFC}, {0x94,0xA3}, {0x96,0x62}, {0xFE,0xB6},
+ {0x94,0x63}, {0x98,0xD0}, {0x98,0xD1}, {0x94,0x75},
+ {0xFA,0xE0}, {0x94,0x72}, {0x98,0xD6}, {0x8A,0xF0},
+ {0x98,0xD9}, {0x98,0xDB}, {0x98,0xDD}, {0x98,0xA8},
+ {0x8A,0x6D}, {0x8A,0xFB}, {0x8A,0xAE}, {0xFB,0xC9},
+ {0x8C,0x5D}, {0x98,0xE4}, {0x98,0xE6}, {0x98,0xE8},
+ {0x8A,0x4D}, {0x92,0x57}, {0x95,0xDF}, {0xA0,0xAC},
+ {0x98,0xEB}, {0x98,0xEC}, {0x8C,0xC3}, {0x98,0xF4},
+ {0x8A,0xB8}, {0x9E,0xE7}, {0x94,0xBC}, {0xFC,0xD1},
+ {0x9C,0xC6}, {0x9E,0x7E}, {0x98,0xFE}, {0xFD,0xE8},
+ {0x99,0x40}, {0x94,0xC9}, {0x94,0xD3}, {0x99,0x46},
+ {0x90,0xC0}, {0x94,0xD1}, {0x95,0x73}, {0x93,0xC2},
+ {0x99,0x48}, {0x99,0x4B}, {0x8E,0x55}, {0x99,0x4E},
+ {0x8E,0xFE}, {0x8E,0x59}, {0x94,0xEC}, {0x94,0xEF},
+ {0x8C,0x60}, {0x8F,0x74}, {0x99,0x55}, {0x95,0x44},
+ {0x8C,0xCB}, {0x99,0x56}, {0x99,0x59}, {0x99,0x5B},
+ {0x8C,0xC4}, {0xFA,0x45}, {0x90,0xB7}, {0x97,0x43},
+ {0x95,0xCD}, {0x97,0xC9}, {0xFD,0x50}, {0x8E,0xB9},
+ {0x95,0xC6}, {0x99,0x67}, {0x8A,0xB9}, {0x8D,0xFC},
+ {0x8A,0x76}, {0x9D,0x51}, {0x99,0x73}, {0x9D,0x4F},
+ {0x99,0x7A}, {0x95,0x64}, {0x99,0xA1}, {0x99,0xA5},
+ {0x99,0xA7}, {0x8E,0xED}, {0x99,0xAD}, {0x94,0x6E},
+ {0x8F,0x70}, {0xFA,0xD0}, {0x99,0xB3}, {0xA0,0x53},
+ {0x96,0x5C}, {0xFD,0x7A}, {0x97,0xFE}, {0x92,0xBD},
+ {0x97,0xFD}, {0x8F,0x64}, {0xFC,0xF7}, {0x95,0x62},
+ {0x97,0xCD}, {0x9E,0x64}, {0x92,0x4C}, {0x8E,0xC9},
+ {0x99,0xBC}, {0x9D,0xA5}, {0x8F,0x54}, {0x8F,0x7C},
+ {0x8E,0xA2}, {0x8F,0x7A}, {0x97,0xAE}, {0x96,0xC8},
+ {0x99,0xC3}, {0x90,0xD6}, {0x9C,0xBE}, {0x8F,0x76},
+ {0x94,0x70}, {0xFB,0x4B}, {0xFD,0xCA}, {0x8E,0xC7},
+ {0xA0,0xF9}, {0x8F,0xA9}, {0x99,0xC7}, {0x90,0xD7},
+ {0x9E,0xDF}, {0x99,0xCE}, {0x8F,0xBA}, {0x8F,0xEB},
+ {0x99,0xCF}, {0x8F,0xC2}, {0x92,0xC9}, {0x97,0xDC},
+ {0x95,0xB3}, {0x9C,0x79}, {0x95,0xB2}, {0x8F,0xDB},
+ {0x9B,0xE3}, {0x9E,0x7A}, {0x9B,0xEE}, {0x99,0xDE},
+ {0xFA,0xFA}, {0x9E,0xE5}, {0x8A,0x52}, {0x99,0xE1},
+ {0x8A,0x67}, {0x8B,0xB5}, {0x8A,0xAC}, {0x99,0xE9},
+ {0xFB,0xCA}, {0x97,0xDE}, {0x95,0xD1}, {0x99,0xF5},
+ {0xFC,0x4A}, {0x9B,0xA9}, {0xFB,0xDC}, {0xFE,0x56},
+ {0x9E,0xA4}, {0x9D,0x49}, {0x95,0xDB}, {0x89,0xC5},
+ {0x99,0xF8}, {0x96,0x64}, {0x90,0x55}, {0x96,0xD4},
+ {0x97,0x7C}, {0x96,0x4D}, {0x97,0xE1}, {0x9A,0x48},
+ {0x9A,0x49}, {0xFE,0x7D}, {0x90,0xAA}, {0x9A,0x50},
+ {0x93,0x47}, {0x8E,0xD8}, {0x90,0xC9}, {0x9A,0x55},
+ {0x90,0xBC}, {0x9A,0x58}, {0x8B,0xB8}, {0x90,0xD5},
+ {0x96,0x41}, {0x9A,0x5A}, {0x9A,0x5C}, {0x97,0xC2},
+ {0x8A,0xBB}, {0x9B,0xAA}, {0x90,0xF5}, {0x9A,0x60},
+ {0x91,0x45}, {0x8C,0x58}, {0x9A,0x63}, {0x8C,0x49},
+ {0x8B,0xB6}, {0xFC,0xCF}, {0x96,0x6B}, {0x9A,0x6E},
+ {0x91,0x4F}, {0x97,0x46}, {0xA0,0xE6}, {0x92,0xD7},
+ {0x96,0x75}, {0x93,0xD4}, {0x91,0xBB}, {0x96,0x79},
+ {0x9A,0x70}, {0x96,0x78}, {0x91,0xCD}, {0x9C,0x4A},
+ {0xA0,0x6F}, {0xA0,0x6A}, {0x91,0x5F}, {0x9F,0xA5},
+ {0x89,0xBA}, {0x9E,0xCD}, {0x9A,0x79}, {0x9D,0xCE},
+ {0x8C,0xD2}, {0x9D,0x73}, {0x96,0xB9}, {0x96,0xBC},
+ {0x9C,0xD1}, {0x89,0xB7}, {0x9E,0xEE}, {0xFB,0x43},
+ {0x9E,0xC9}, {0xFB,0xD3}, {0x91,0xAE}, {0x9D,0x78},
+ {0x9D,0x7B}, {0xA4,0x40}, {0xA4,0x42}, {0xA4,0x43},
+ {0x9E,0xB3}, {0xC9,0x45}, {0xA4,0x56}, {0xA4,0x54},
+ {0xA4,0x57}, {0xA4,0x55}, {0xC9,0x46}, {0xA4,0xA3},
+ {0xC9,0x4F}, {0xC9,0x4D}, {0xA4,0xA2}, {0xA4,0xA1},
+ {0xA5,0x42}, {0xA5,0x41}, {0xA5,0x40}, {0xA5,0x43},
+ {0xA4,0xFE}, {0x9E,0xB2}, {0x9D,0xD6}, {0xA5,0xE0},
+ {0xA5,0xE1}, {0x99,0x4F}, {0x89,0xCE}, {0xA8,0xC3},
+ {0x8B,0xC0}, {0x9F,0xC4}, {0xA4,0x58}, {0x8B,0xD4},
+ {0xA4,0xA4}, {0xC9,0x50}, {0x8C,0x72}, {0xA4,0xA5},
+ {0xC9,0x63}, {0xA6,0xEA}, {0xCB,0xB1}, {0xC6,0xBF},
+ {0x8B,0xF9}, {0xA4,0x59}, {0xA4,0xA6}, {0xA5,0x44},
+ {0xC9,0x64}, {0x89,0x46}, {0xC6,0xC0}, {0xC9,0x40},
+ {0xA4,0x44}, {0xA4,0x5B}, {0xC9,0x47}, {0xA4,0x5C},
+ {0xFA,0xE5}, {0xA4,0xA7}, {0xA5,0x45}, {0xA5,0x47},
+ {0xA5,0x46}, {0xA5,0xE2}, {0xA5,0xE3}, {0xA8,0xC4},
+ {0xAD,0xBC}, {0xA4,0x41}, {0xC8,0x7B}, {0x8B,0xC6},
+ {0xC9,0x41}, {0xA4,0x45}, {0xA4,0x5E}, {0xA4,0x5D},
+ {0xA5,0xE4}, {0x9C,0x57}, {0xA8,0xC5}, {0x9A,0xFB},
+ {0xB0,0xAE}, {0xD4,0x4B}, {0x89,0xD0}, {0x89,0xCF},
+ {0xB6,0xC3}, {0xDC,0xB1}, {0xDC,0xB2}, {0xC6,0xC1},
+ {0xA4,0x46}, {0x89,0xD1}, {0xA4,0xA9}, {0x89,0xE2},
+ {0xA8,0xC6}, {0xA4,0x47}, {0xC9,0x48}, {0xA4,0x5F},
+ {0xA4,0xAA}, {0xA4,0xAC}, {0xC9,0x51}, {0xA4,0xAD},
+ {0xA4,0xAB}, {0x92,0x7E}, {0xA5,0xE5}, {0x9D,0xBA},
+ {0xA8,0xC7}, {0xA8,0xC8}, {0xAB,0x45}, {0xC6,0xC2},
+ {0xA4,0x60}, {0xA4,0xAE}, {0x8C,0x6F}, {0xA5,0xE6},
+ {0xA5,0xE8}, {0xA5,0xE7}, {0xA6,0xEB}, {0xA8,0xC9},
+ {0xA8,0xCA}, {0xAB,0x46}, {0xAB,0x47}, {0xAD,0xBD},
+ {0xDC,0xB3}, {0xFB,0xF8}, {0xF6,0xD6}, {0xA4,0x48},
+ {0x8B,0xC7}, {0x92,0x6B}, {0x89,0xD2}, {0xA4,0xB0},
+ {0xA4,0xAF}, {0xC9,0x52}, {0xA4,0xB1}, {0xA4,0xB7},
+ {0xA4,0xB2}, {0xA4,0xB3}, {0xC9,0x54}, {0xC9,0x53},
+ {0xA4,0xB5}, {0xA4,0xB6}, {0xA4,0xB4}, {0x9F,0xCF},
+ {0xA5,0x4A}, {0xA5,0x4B}, {0xA5,0x4C}, {0xA5,0x4D},
+ {0xA5,0x49}, {0xA5,0x50}, {0xC9,0x6A}, {0xC9,0x66},
+ {0xC9,0x69}, {0xA5,0x51}, {0xA5,0x61}, {0xC9,0x68},
+ {0xA5,0x4E}, {0xA5,0x4F}, {0xA5,0x48}, {0xC9,0x65},
+ {0xC9,0x67}, {0x9D,0xA9}, {0x89,0xD3}, {0x99,0xE2},
+ {0xA5,0xF5}, {0xC9,0xB0}, {0xA5,0xF2}, {0xA5,0xF6},
+ {0xC9,0xBA}, {0xC9,0xAE}, {0xA5,0xF3}, {0xC9,0xB2},
+ {0x92,0x67}, {0xA5,0xF4}, {0xA5,0xF7}, {0xA5,0xE9},
+ {0xC9,0xB1}, {0xA5,0xF8}, {0xC9,0xB5}, {0x92,0xA4},
+ {0xC9,0xB9}, {0xC9,0xB6}, {0xC9,0xB3}, {0xA5,0xEA},
+ {0xA5,0xEC}, {0xA5,0xF9}, {0xA5,0xEE}, {0xC9,0xAB},
+ {0xA5,0xF1}, {0xA5,0xEF}, {0xA5,0xF0}, {0xC9,0xBB},
+ {0xC9,0xB8}, {0xC9,0xAF}, {0xA5,0xED}, {0x8C,0x73},
+ {0xC9,0xAC}, {0xA5,0xEB}, {0x89,0x4E}, {0xC9,0xB4},
+ {0xC9,0xB7}, {0x89,0x4F}, {0x92,0x78}, {0xC9,0xAD},
+ {0xCA,0x66}, {0xA7,0x42}, {0xA6,0xF4}, {0x91,0xB6},
+ {0xCA,0x67}, {0xA6,0xF1}, {0xA7,0x44}, {0x89,0xD4},
+ {0xA6,0xF9}, {0x9F,0xD2}, {0xA6,0xF8}, {0xCA,0x5B},
+ {0xA6,0xFC}, {0xA6,0xF7}, {0xCA,0x60}, {0xCA,0x68},
+ {0xCA,0x64}, {0x92,0xA7}, {0xA6,0xFA}, {0x95,0xA2},
+ {0xA6,0xFD}, {0xA6,0xEE}, {0xA7,0x47}, {0xCA,0x5D},
+ {0x92,0x6E}, {0xCB,0xBD}, {0xA6,0xEC}, {0xA7,0x43},
+ {0xA6,0xED}, {0xA6,0xF5}, {0xA6,0xF6}, {0xCA,0x62},
+ {0xCA,0x5E}, {0xA6,0xFB}, {0xA6,0xF3}, {0xCA,0x5A},
+ {0xA6,0xEF}, {0xCA,0x65}, {0xA7,0x45}, {0xA7,0x48},
+ {0xA6,0xF2}, {0xA7,0x40}, {0xA7,0x46}, {0xA6,0xF0},
+ {0xCA,0x63}, {0xA7,0x41}, {0xCA,0x69}, {0xCA,0x5C},
+ {0xA6,0xFE}, {0xCA,0x5F}, {0xCA,0x61}, {0xA8,0xD8},
+ {0xCB,0xBF}, {0xCB,0xCB}, {0xA8,0xD0}, {0xCB,0xCC},
+ {0xA8,0xCB}, {0xA8,0xD5}, {0x96,0xEA}, {0xA8,0xCE},
+ {0xCB,0xB9}, {0xA8,0xD6}, {0xCB,0xB8}, {0xCB,0xBC},
+ {0xCB,0xC3}, {0xCB,0xC1}, {0xA8,0xDE}, {0xA8,0xD9},
+ {0xCB,0xB3}, {0xCB,0xB5}, {0xA8,0xDB}, {0xA8,0xCF},
+ {0xCB,0xB6}, {0xCB,0xC2}, {0xCB,0xC9}, {0xA8,0xD4},
+ {0xCB,0xBB}, {0xCB,0xB4}, {0xA8,0xD3}, {0xCB,0xB7},
+ {0xA8,0xD7}, {0xCB,0xBA}, {0x92,0x6F}, {0xA8,0xD2},
+ {0xA8,0xCD}, {0xA8,0xDC}, {0xCB,0xC4}, {0xA8,0xDD},
+ {0xCB,0xC8}, {0xCB,0xC6}, {0xCB,0xCA}, {0xA8,0xDA},
+ {0xCB,0xBE}, {0xCB,0xB2}, {0xCB,0xC0}, {0xA8,0xD1},
+ {0xCB,0xC5}, {0xA8,0xCC}, {0xCB,0xC7}, {0x92,0xA3},
+ {0x89,0x50}, {0xFA,0x57}, {0xAB,0x56}, {0xAB,0x4A},
+ {0x98,0x66}, {0xCD,0xE0}, {0xCD,0xE8}, {0xAB,0x49},
+ {0xAB,0x51}, {0xAB,0x5D}, {0xCD,0xEE}, {0xCD,0xEC},
+ {0xCD,0xE7}, {0x89,0xD6}, {0xAB,0x4B}, {0xCD,0xED},
+ {0xCD,0xE3}, {0xAB,0x59}, {0xAB,0x50}, {0xAB,0x58},
+ {0xCD,0xDE}, {0xCD,0xEA}, {0x98,0xB2}, {0xCD,0xE1},
+ {0xAB,0x54}, {0xCD,0xE2}, {0x92,0xAB}, {0xCD,0xDD},
+ {0xAB,0x5B}, {0xAB,0x4E}, {0xAB,0x57}, {0xAB,0x4D},
+ {0xCD,0xDF}, {0xCD,0xE4}, {0xCD,0xEB}, {0xAB,0x55},
+ {0xAB,0x52}, {0xCD,0xE6}, {0xAB,0x5A}, {0xCD,0xE9},
+ {0xCD,0xE5}, {0xAB,0x4F}, {0xAB,0x5C}, {0xAB,0x53},
+ {0xAB,0x4C}, {0xAB,0x48}, {0x96,0xDE}, {0x92,0xAC},
+ {0xCD,0xEF}, {0xAD,0xD7}, {0xAD,0xC1}, {0x8C,0x70},
+ {0xAD,0xD1}, {0x9F,0x6E}, {0xAD,0xD6}, {0xD0,0xD0},
+ {0xD0,0xCF}, {0xD0,0xD4}, {0xD0,0xD5}, {0xAD,0xC4},
+ {0x8E,0xF2}, {0xAD,0xCD}, {0x9F,0x6C}, {0xAD,0xDA},
+ {0xAD,0xCE}, {0x89,0xD8}, {0xD0,0xC9}, {0xAD,0xC7},
+ {0xD0,0xCA}, {0xFA,0x59}, {0xAD,0xDC}, {0xAD,0xD3},
+ {0xAD,0xBE}, {0xAD,0xBF}, {0xD0,0xDD}, {0xB0,0xBF},
+ {0xAD,0xCC}, {0xAD,0xCB}, {0xD0,0xCB}, {0xAD,0xCF},
+ {0xD4,0x5B}, {0xAD,0xC6}, {0xD0,0xD6}, {0xAD,0xD5},
+ {0xAD,0xD4}, {0xAD,0xCA}, {0xD0,0xCE}, {0xD0,0xD7},
+ {0xD0,0xC8}, {0xAD,0xC9}, {0xD0,0xD8}, {0xAD,0xD2},
+ {0xD0,0xCC}, {0xAD,0xC0}, {0xAD,0xC3}, {0xAD,0xC2},
+ {0xD0,0xD9}, {0xAD,0xD0}, {0xAD,0xC5}, {0xAD,0xD9},
+ {0xAD,0xDB}, {0xD0,0xD3}, {0xAD,0xD8}, {0x92,0xA8},
+ {0xD0,0xDB}, {0xD0,0xCD}, {0xD0,0xDC}, {0xD0,0xD1},
+ {0x91,0x63}, {0xD0,0xDA}, {0xD0,0xD2}, {0x8C,0x40},
+ {0xAD,0xC8}, {0xD4,0x63}, {0xD4,0x57}, {0xB0,0xB3},
+ {0xD4,0x5C}, {0xD4,0x62}, {0xB0,0xB2}, {0xD4,0x55},
+ {0xB0,0xB6}, {0xD4,0x59}, {0xD4,0x52}, {0xB0,0xB4},
+ {0xD4,0x56}, {0xB0,0xB9}, {0xB0,0xBE}, {0xD4,0x67},
+ {0xD4,0x51}, {0xB0,0xBA}, {0x9F,0x73}, {0xD4,0x66},
+ {0x92,0xAD}, {0xB0,0xB5}, {0xD4,0x58}, {0xB0,0xB1},
+ {0xD4,0x53}, {0xD4,0x4F}, {0xD4,0x5D}, {0xD4,0x50},
+ {0xD4,0x4E}, {0xD4,0x5A}, {0xD4,0x60}, {0xD4,0x61},
+ {0xB0,0xB7}, {0x9B,0xE9}, {0xD8,0x5B}, {0xD4,0x5E},
+ {0xD4,0x4D}, {0xD4,0x5F}, {0x92,0xA9}, {0xB0,0xC1},
+ {0xD4,0x64}, {0xB0,0xC0}, {0xD4,0x4C}, {0xD4,0x54},
+ {0xD4,0x65}, {0xB0,0xBC}, {0xB0,0xBB}, {0xB0,0xB8},
+ {0xB0,0xBD}, {0xB0,0xAF}, {0xB0,0xB0}, {0xB3,0xC8},
+ {0x92,0xAA}, {0xD8,0x5E}, {0xD8,0x57}, {0xB3,0xC5},
+ {0xD8,0x5F}, {0x89,0xD9}, {0xD8,0x55}, {0xD8,0x58},
+ {0xB3,0xC4}, {0xD8,0x59}, {0xFD,0x56}, {0xB3,0xC7},
+ {0xD8,0x5D}, {0xD8,0x53}, {0xD8,0x52}, {0xB3,0xC9},
+ {0xB3,0xCA}, {0xB3,0xC6}, {0xB3,0xCB}, {0xD8,0x51},
+ {0xD8,0x5C}, {0xD8,0x5A}, {0xD8,0x54}, {0xB3,0xC3},
+ {0xD8,0x56}, {0x9F,0xA8}, {0xB6,0xCA}, {0xB6,0xC4},
+ {0xDC,0xB7}, {0xB6,0xCD}, {0xDC,0xBD}, {0xDC,0xC0},
+ {0xB6,0xC6}, {0xB6,0xC7}, {0xDC,0xBA}, {0xB6,0xC5},
+ {0xDC,0xC3}, {0xB6,0xCB}, {0xDC,0xC4}, {0xDC,0xBF},
+ {0xB6,0xCC}, {0x8C,0x71}, {0xDC,0xB4}, {0xB6,0xC9},
+ {0xDC,0xB5}, {0xDC,0xBE}, {0xDC,0xBC}, {0xDC,0xB8},
+ {0xB6,0xC8}, {0xDC,0xB6}, {0xB6,0xCE}, {0xDC,0xBB},
+ {0xDC,0xC2}, {0xDC,0xB9}, {0xDC,0xC1}, {0x92,0xA1},
+ {0xB9,0xB6}, {0xB9,0xB3}, {0x90,0xE3}, {0xB9,0xB4},
+ {0xE0,0xF9}, {0xE0,0xF1}, {0xB9,0xB2}, {0xB9,0xAF},
+ {0xE0,0xF2}, {0xA0,0xA6}, {0xB9,0xB1}, {0xE0,0xF5},
+ {0xE0,0xF7}, {0x94,0xAB}, {0xE0,0xFE}, {0xFC,0x72},
+ {0xE0,0xFD}, {0xE0,0xF8}, {0xB9,0xAE}, {0xE0,0xF0},
+ {0xB9,0xAC}, {0xE0,0xF3}, {0xB9,0xB7}, {0xE0,0xF6},
+ {0xE0,0xFA}, {0xB9,0xB0}, {0xB9,0xAD}, {0xE0,0xFC},
+ {0xE0,0xFB}, {0xB9,0xB5}, {0xE0,0xF4}, {0x97,0xC4},
+ {0xBB,0xF8}, {0xE4,0xEC}, {0xE4,0xE9}, {0xBB,0xF9},
+ {0xBB,0xF7}, {0x92,0xAE}, {0xE4,0xF0}, {0xE4,0xED},
+ {0xE4,0xE6}, {0xBB,0xF6}, {0xFA,0x67}, {0xBB,0xFA},
+ {0xE4,0xE7}, {0xBB,0xF5}, {0xBB,0xFD}, {0xE4,0xEA},
+ {0xE4,0xEB}, {0xBB,0xFB}, {0xBB,0xFC}, {0xE4,0xF1},
+ {0xE4,0xEE}, {0xE4,0xEF}, {0x92,0xA2}, {0xFA,0x69},
+ {0xBE,0xAA}, {0xE8,0xF8}, {0xBE,0xA7}, {0xE8,0xF5},
+ {0xBE,0xA9}, {0xBE,0xAB}, {0xE8,0xF6}, {0xBE,0xA8},
+ {0xE8,0xF7}, {0xE8,0xF4}, {0xC0,0x76}, {0xEC,0xBD},
+ {0xC0,0x77}, {0xEC,0xBB}, {0xEC,0xBC}, {0xEC,0xBA},
+ {0xEC,0xB9}, {0xEC,0xBE}, {0xC0,0x75}, {0x92,0x68},
+ {0xEF,0xB8}, {0xEF,0xB9}, {0xE4,0xE8}, {0xEF,0xB7},
+ {0xC0,0x78}, {0xC3,0x5F}, {0xF1,0xEB}, {0xF1,0xEC},
+ {0xC4,0xD7}, {0xC4,0xD8}, {0xF5,0xC1}, {0xF5,0xC0},
+ {0xC5,0x6C}, {0xC5,0x6B}, {0xF7,0xD0}, {0xA4,0x49},
+ {0xA4,0x61}, {0xA4,0xB9}, {0xA4,0xB8}, {0xA5,0x53},
+ {0xA5,0x52}, {0xA5,0xFC}, {0xA5,0xFB}, {0xA5,0xFD},
+ {0xA5,0xFA}, {0xA7,0x4A}, {0xA7,0x49}, {0xA7,0x4B},
+ {0xA8,0xE0}, {0xA8,0xDF}, {0xA8,0xE1}, {0x89,0x51},
+ {0xAB,0x5E}, {0xA2,0x59}, {0xD0,0xDE}, {0xA2,0x5A},
+ {0xB0,0xC2}, {0xA2,0x5C}, {0xA2,0x5B}, {0xD8,0x60},
+ {0xFA,0x6F}, {0xA2,0x5D}, {0xB9,0xB8}, {0xA2,0x5E},
+ {0xA4,0x4A}, {0xA4,0xBA}, {0xA5,0xFE}, {0xA8,0xE2},
+ {0xFA,0x71}, {0xA4,0x4B}, {0xA4,0xBD}, {0xA4,0xBB},
+ {0xA4,0xBC}, {0xA6,0x40}, {0x89,0x52}, {0xA7,0x4C},
+ {0xA8,0xE4}, {0xA8,0xE3}, {0xA8,0xE5}, {0x94,0x5A},
+ {0xAD,0xDD}, {0xBE,0xAC}, {0xC6,0xC3}, {0x89,0xDD},
+ {0xC9,0x4E}, {0xC8,0xA2}, {0xA5,0x54}, {0xA5,0x55},
+ {0xA6,0x41}, {0xCA,0x6A}, {0xAB,0x60}, {0xAB,0x5F},
+ {0xD0,0xE0}, {0xD0,0xDF}, {0xB0,0xC3}, {0xC6,0xC4},
+ {0xA4,0xBE}, {0xC9,0x55}, {0x9E,0x52}, {0x89,0x53},
+ {0xCB,0xCD}, {0xAB,0x61}, {0xAD,0xE0}, {0xAD,0xDE},
+ {0xAD,0xDF}, {0x9E,0x55}, {0x92,0xBA}, {0xBE,0xAD},
+ {0xC6,0xC5}, {0xA5,0x56}, {0x8C,0x5B}, {0xA6,0x42},
+ {0xC9,0xBC}, {0xFA,0x7D}, {0xFA,0xA8}, {0x9A,0x68},
+ {0xFA,0x47}, {0xA7,0x4D}, {0xA7,0x4E}, {0xFA,0x7E},
+ {0xCA,0x6B}, {0xCB,0xCE}, {0xA8,0xE6}, {0xCB,0xCF},
+ {0x92,0xBB}, {0xD0,0xE2}, {0xD0,0xE3}, {0xAD,0xE3},
+ {0xFD,0xB6}, {0xD0,0xE4}, {0xFA,0xA2}, {0xD0,0xE1},
+ {0xAD,0xE4}, {0xAD,0xE2}, {0xAD,0xE1}, {0xD0,0xE5},
+ {0xFA,0xA3}, {0xD4,0x68}, {0xFA,0xA4}, {0x9B,0xB4},
+ {0xFA,0xA6}, {0xD8,0x61}, {0xDC,0xC5}, {0xE1,0x40},
+ {0x89,0xDF}, {0xBB,0xFE}, {0xBE,0xAE}, {0xE8,0xF9},
+ {0xFD,0xDB}, {0xA4,0x4C}, {0xA4,0x5A}, {0xFA,0xA9},
+ {0x89,0x54}, {0xFA,0xAB}, {0xB0,0xC4}, {0xB3,0xCD},
+ {0xB9,0xB9}, {0xFC,0x7A}, {0xC9,0x42}, {0xA4,0xBF},
+ {0xA5,0x59}, {0xA5,0x57}, {0xA5,0x58}, {0x89,0xE0},
+ {0xA8,0xE7}, {0x9F,0x4F}, {0xA4,0x4D}, {0xA4,0x4E},
+ {0xC8,0x7D}, {0xA4,0x62}, {0x89,0xE1}, {0xA4,0xC0},
+ {0xA4,0xC1}, {0xA4,0xC2}, {0xC9,0xBE}, {0xA5,0x5A},
+ {0xFA,0xB0}, {0xC9,0x6B}, {0xA6,0x46}, {0xC9,0xBF},
+ {0xA6,0x44}, {0xA6,0x45}, {0xC9,0xBD}, {0xA6,0x47},
+ {0xA6,0x43}, {0xCA,0x6C}, {0xAA,0xEC}, {0xCA,0x6D},
+ {0x9F,0xCD}, {0xA0,0xE7}, {0xCA,0x6E}, {0xA7,0x50},
+ {0xA7,0x4F}, {0xFA,0xB1}, {0x89,0xA6}, {0xA7,0x53},
+ {0xA7,0x51}, {0xA7,0x52}, {0xA8,0xED}, {0xA8,0xEC},
+ {0xCB,0xD4}, {0xCB,0xD1}, {0xCB,0xD2}, {0x9E,0xFA},
+ {0xCB,0xD0}, {0xA8,0xEE}, {0xA8,0xEA}, {0xA8,0xE9},
+ {0xA8,0xEB}, {0xA8,0xE8}, {0xFA,0xB2}, {0xA8,0xEF},
+ {0xAB,0x63}, {0xCD,0xF0}, {0xCB,0xD3}, {0xAB,0x68},
+ {0xCD,0xF1}, {0xAB,0x64}, {0xAB,0x67}, {0xAB,0x66},
+ {0xAB,0x65}, {0xAB,0x62}, {0xD0,0xE8}, {0xAD,0xE7},
+ {0xD0,0xEB}, {0xAD,0xE5}, {0xFA,0xB4}, {0x92,0xC4},
+ {0xD0,0xE7}, {0xAD,0xE8}, {0xAD,0xE6}, {0xAD,0xE9},
+ {0xD0,0xE9}, {0xD0,0xEA}, {0x9F,0x6F}, {0xD0,0xE6},
+ {0xD0,0xEC}, {0x8B,0xB0}, {0xB3,0xD1}, {0xB0,0xC5},
+ {0xD4,0x69}, {0xD4,0x6B}, {0xD4,0x6A}, {0xD4,0x6C},
+ {0xB0,0xC6}, {0xB3,0xCE}, {0x9F,0xAC}, {0xB3,0xCF},
+ {0xB3,0xD0}, {0xB6,0xD0}, {0xDC,0xC7}, {0x89,0xE3},
+ {0xDC,0xC6}, {0xDC,0xC8}, {0xDC,0xC9}, {0xB6,0xD1},
+ {0xB6,0xCF}, {0xE1,0x41}, {0xE1,0x42}, {0xB9,0xBB},
+ {0xB9,0xBA}, {0xE3,0x5A}, {0xBC,0x40}, {0xBC,0x41},
+ {0xBC,0x42}, {0xBC,0x44}, {0xE4,0xF2}, {0xE4,0xF3},
+ {0xBC,0x43}, {0x9B,0xD3}, {0x89,0xE4}, {0xBE,0xAF},
+ {0xBE,0xB0}, {0xFA,0xB5}, {0xF1,0xED}, {0xF5,0xC3},
+ {0xF5,0xC2}, {0xF7,0xD1}, {0x9F,0xD5}, {0xA4,0x4F},
+ {0xA5,0x5C}, {0xA5,0x5B}, {0x89,0x55}, {0xA6,0x48},
+ {0x92,0xC5}, {0xC9,0xC0}, {0x89,0x56}, {0xA7,0x55},
+ {0xA7,0x56}, {0xA7,0x54}, {0xA7,0x57}, {0xCA,0x6F},
+ {0xCA,0x70}, {0xFA,0xB3}, {0xFA,0xB6}, {0xA8,0xF1},
+ {0xCB,0xD5}, {0xA8,0xF0}, {0xCD,0xF2}, {0xAB,0x6C},
+ {0xCD,0xF3}, {0xAB,0x6B}, {0xFA,0xB7}, {0xAB,0x69},
+ {0xAB,0x6A}, {0x9E,0xDC}, {0xD0,0xED}, {0xFB,0xC4},
+ {0x9F,0x71}, {0xB0,0xC7}, {0xD4,0x6E}, {0xB0,0xCA},
+ {0xD4,0x6D}, {0xB1,0xE5}, {0xB0,0xC9}, {0xB0,0xC8},
+ {0xB3,0xD4}, {0xB3,0xD3}, {0xB3,0xD2}, {0xB6,0xD2},
+ {0xFA,0xBA}, {0x92,0xC7}, {0xB6,0xD5}, {0xB6,0xD6},
+ {0xB6,0xD4}, {0xB6,0xD3}, {0xE1,0x43}, {0xE1,0x44},
+ {0xE4,0xF5}, {0xBC,0x45}, {0xE4,0xF4}, {0xBE,0xB1},
+ {0xEC,0xBF}, {0xC0,0x79}, {0xF1,0xEE}, {0xC4,0x55},
+ {0xC6,0xC6}, {0xA4,0x63}, {0xA4,0xC3}, {0xC9,0x56},
+ {0xA4,0xC4}, {0xA4,0xC5}, {0x9A,0x4C}, {0xA5,0x5D},
+ {0xA5,0x5E}, {0xA6,0x49}, {0xCA,0x71}, {0xCB,0xD6},
+ {0xCB,0xD7}, {0xAB,0x6D}, {0xD0,0xEE}, {0xB0,0xCC},
+ {0xB0,0xCB}, {0xD8,0x63}, {0xD8,0x62}, {0xA4,0x50},
+ {0xA4,0xC6}, {0xA5,0x5F}, {0xB0,0xCD}, {0xC9,0x43},
+ {0xC9,0x6C}, {0xA5,0x60}, {0xC9,0xC2}, {0xA6,0x4B},
+ {0xA6,0x4A}, {0xC9,0xC1}, {0xA7,0x58}, {0x8C,0x68},
+ {0x89,0xE5}, {0xAD,0xEA}, {0x9F,0x7D}, {0xD4,0x6F},
+ {0xB6,0xD7}, {0xE1,0x45}, {0xB9,0xBC}, {0xA0,0xA9},
+ {0xFA,0xC4}, {0xE8,0xFA}, {0xF3,0xFD}, {0xC6,0xC7},
+ {0xA4,0xC7}, {0x89,0x57}, {0xCB,0xD8}, {0xCD,0xF4},
+ {0xB0,0xD0}, {0xB0,0xCE}, {0xB0,0xCF}, {0xA4,0x51},
+ {0xFA,0xAA}, {0xA4,0x64}, {0xA2,0xCD}, {0xA4,0xCA},
+ {0xA4,0xC9}, {0xA4,0xC8}, {0xA5,0x63}, {0xA5,0x62},
+ {0xC9,0x6D}, {0xC9,0xC3}, {0x89,0x58}, {0xA8,0xF5},
+ {0xA8,0xF2}, {0xA8,0xF4}, {0xA8,0xF3}, {0xAB,0x6E},
+ {0xB3,0xD5}, {0xA4,0x52}, {0x8B,0xE3}, {0xA4,0xCB},
+ {0x8B,0x61}, {0xA5,0x65}, {0xA5,0x64}, {0xCA,0x72},
+ {0x9A,0xF1}, {0xA8,0xF6}, {0x9E,0xB7}, {0xC6,0xC8},
+ {0xC9,0x57}, {0xFA,0xD1}, {0xA5,0x67}, {0xA5,0x66},
+ {0xA6,0x4C}, {0xA6,0x4D}, {0xCA,0x73}, {0xA7,0x59},
+ {0xFA,0xD2}, {0xA7,0x5A}, {0xA8,0xF7}, {0xA8,0xF8},
+ {0xA8,0xF9}, {0xAB,0x6F}, {0xCD,0xF5}, {0x9E,0xBA},
+ {0xFA,0xD4}, {0xAD,0xEB}, {0xC9,0x44}, {0xA4,0xCC},
+ {0xC9,0xC4}, {0xCA,0x74}, {0xCA,0x75}, {0xCB,0xD9},
+ {0xFA,0xD9}, {0xCB,0xDA}, {0xCD,0xF7}, {0xCD,0xF6},
+ {0xCD,0xF9}, {0xCD,0xF8}, {0xAB,0x70}, {0xD4,0x70},
+ {0xAD,0xED}, {0xD0,0xEF}, {0xAD,0xEC}, {0xFA,0xDB},
+ {0x9C,0xE0}, {0xD8,0x64}, {0xB3,0xD6}, {0xFB,0xF7},
+ {0xD8,0x65}, {0xFB,0xFA}, {0x89,0xE7}, {0xA0,0x7A},
+ {0xFA,0xDC}, {0xE1,0x46}, {0xB9,0xBD}, {0xFA,0xDD},
+ {0x89,0xE9}, {0xBC,0x46}, {0xF1,0xEF}, {0xC6,0xC9},
+ {0xC9,0x58}, {0xA5,0x68}, {0xFA,0xE2}, {0x89,0xEB},
+ {0xB0,0xD1}, {0xFA,0xE3}, {0xA4,0x53}, {0xA4,0x65},
+ {0xA4,0xCE}, {0xA4,0xCD}, {0x90,0xC8}, {0xA4,0xCF},
+ {0x92,0xDA}, {0x89,0x59}, {0x9C,0xF5}, {0xA8,0xFB},
+ {0xA8,0xFA}, {0xA8,0xFC}, {0x89,0x5A}, {0xFA,0xE7},
+ {0x9F,0xA2}, {0xAB,0x71}, {0xAD,0xEE}, {0xFA,0xEA},
+ {0xE8,0xFB}, {0xC2,0x4F}, {0xA4,0x66}, {0xA5,0x6A},
+ {0xA5,0x79}, {0xA5,0x74}, {0xA5,0x6F}, {0xA5,0x6E},
+ {0xA5,0x75}, {0xA5,0x73}, {0xA5,0x6C}, {0xA5,0x7A},
+ {0xA5,0x6D}, {0xA5,0x69}, {0xA5,0x78}, {0xA5,0x77},
+ {0xA5,0x76}, {0xA5,0x6B}, {0xA5,0x72}, {0xFA,0xED},
+ {0x8F,0xAD}, {0xA5,0x71}, {0xA5,0x7B}, {0xA5,0x70},
+ {0xFB,0x59}, {0xA6,0x53}, {0xA6,0x59}, {0xA6,0x55},
+ {0xA6,0x5B}, {0xC9,0xC5}, {0xA6,0x58}, {0xA6,0x4E},
+ {0xA6,0x51}, {0xA6,0x54}, {0xA6,0x50}, {0xA6,0x57},
+ {0xA6,0x5A}, {0xA6,0x4F}, {0xA6,0x52}, {0xA6,0x56},
+ {0xA6,0x5C}, {0xFA,0xEF}, {0x96,0xEF}, {0x9D,0xEC},
+ {0xCA,0x7E}, {0xCA,0x7B}, {0x9D,0xCA}, {0xA7,0x67},
+ {0xCA,0x7C}, {0xA7,0x5B}, {0xA7,0x5D}, {0xA7,0x75},
+ {0xA7,0x70}, {0xFD,0x6D}, {0x89,0xEC}, {0xCA,0xA5},
+ {0xCA,0x7D}, {0xA7,0x5F}, {0xA7,0x61}, {0xCA,0xA4},
+ {0xA7,0x68}, {0xCA,0x78}, {0xA7,0x74}, {0xA7,0x76},
+ {0xA7,0x5C}, {0xA7,0x6D}, {0xFB,0x44}, {0xCA,0x76},
+ {0xA7,0x73}, {0x9D,0xE2}, {0xA7,0x64}, {0x8C,0x75},
+ {0xA7,0x6E}, {0xA7,0x6F}, {0xCA,0x77}, {0xA7,0x6C},
+ {0xA7,0x6A}, {0xA7,0x6B}, {0xA7,0x71}, {0xCA,0xA1},
+ {0xA7,0x5E}, {0xA7,0x72}, {0xCA,0xA3}, {0xA7,0x66},
+ {0xA7,0x63}, {0xCA,0x7A}, {0xA7,0x62}, {0xCA,0xA6},
+ {0xA7,0x65}, {0xA7,0x69}, {0x9E,0xC0}, {0x9E,0x56},
+ {0xA7,0x60}, {0xCA,0xA2}, {0xCA,0x79}, {0xCB,0xEB},
+ {0xCB,0xEA}, {0xA9,0x4F}, {0xCB,0xED}, {0xCB,0xEF},
+ {0xCB,0xE4}, {0xCB,0xE7}, {0xCB,0xEE}, {0xA9,0x50},
+ {0x9F,0x79}, {0x9A,0xC7}, {0xCB,0xE1}, {0xCB,0xE5},
+ {0xFA,0xF4}, {0xCB,0xE9}, {0xCE,0x49}, {0xA9,0x4B},
+ {0xCE,0x4D}, {0xA8,0xFD}, {0xCB,0xE6}, {0xA8,0xFE},
+ {0xA9,0x4C}, {0xA9,0x45}, {0xA9,0x41}, {0xCB,0xE2},
+ {0xA9,0x44}, {0xA9,0x49}, {0xA9,0x52}, {0xCB,0xE3},
+ {0xCB,0xDC}, {0xA9,0x43}, {0xCB,0xDD}, {0xCB,0xDF},
+ {0xA9,0x46}, {0x98,0xA1}, {0xA9,0x48}, {0xCB,0xDB},
+ {0xCB,0xE0}, {0xA9,0x51}, {0xA9,0x4D}, {0xCB,0xE8},
+ {0xA9,0x53}, {0xFA,0xF8}, {0xA9,0x4A}, {0xCB,0xDE},
+ {0xA9,0x47}, {0x89,0xF0}, {0x9E,0x47}, {0xA9,0x42},
+ {0xA9,0x40}, {0x9D,0xF7}, {0xCB,0xEC}, {0xA9,0x4E},
+ {0x9F,0xD3}, {0x9A,0xCA}, {0xCE,0x48}, {0xCD,0xFB},
+ {0xCE,0x4B}, {0x89,0xF1}, {0xFA,0xF9}, {0xCD,0xFD},
+ {0xAB,0x78}, {0xAB,0xA8}, {0xAB,0x74}, {0xAB,0xA7},
+ {0xAB,0x7D}, {0xAB,0xA4}, {0xAB,0x72}, {0xCD,0xFC},
+ {0xCE,0x43}, {0xAB,0xA3}, {0xCE,0x4F}, {0xAB,0xA5},
+ {0x8E,0x5A}, {0xAB,0x79}, {0x89,0xF2}, {0xCE,0x45},
+ {0xCE,0x42}, {0xAB,0x77}, {0x89,0xF3}, {0xCD,0xFA},
+ {0xAB,0xA6}, {0xCE,0x4A}, {0xAB,0x7C}, {0xCE,0x4C},
+ {0xAB,0xA9}, {0xAB,0x73}, {0xAB,0x7E}, {0xAB,0x7B},
+ {0xCE,0x40}, {0xAB,0xA1}, {0xCE,0x46}, {0xCE,0x47},
+ {0xAB,0x7A}, {0xAB,0xA2}, {0xAB,0x76}, {0x92,0x5D},
+ {0x8B,0x51}, {0x92,0xE0}, {0xAB,0x75}, {0xCD,0xFE},
+ {0x89,0xF4}, {0xCE,0x44}, {0x9F,0xD4}, {0xCE,0x4E},
+ {0xD1,0x44}, {0xAD,0xFB}, {0xD0,0xF1}, {0x8A,0x79},
+ {0xD0,0xF6}, {0xAD,0xF4}, {0xAE,0x40}, {0xD0,0xF4},
+ {0xAD,0xEF}, {0xAD,0xF9}, {0xAD,0xFE}, {0xD0,0xFB},
+ {0xAD,0xFA}, {0xAD,0xFD}, {0x89,0xF5}, {0xD0,0xFE},
+ {0xAD,0xF5}, {0xD0,0xF5}, {0xD1,0x42}, {0xD1,0x43},
+ {0xAD,0xF7}, {0xD1,0x41}, {0xAD,0xF3}, {0xAE,0x43},
+ {0xD0,0xF8}, {0xAD,0xF1}, {0x97,0xA7}, {0xD1,0x46},
+ {0xD0,0xF9}, {0xD0,0xFD}, {0xAD,0xF6}, {0xAE,0x42},
+ {0xD0,0xFA}, {0xAD,0xFC}, {0xD1,0x40}, {0xD1,0x47},
+ {0xD4,0xA1}, {0x93,0xBA}, {0xD1,0x45}, {0xAE,0x44},
+ {0xAD,0xF0}, {0xD0,0xFC}, {0xD0,0xF3}, {0x9E,0x58},
+ {0xAD,0xF8}, {0xD0,0xF2}, {0x89,0xF6}, {0xD0,0xF7},
+ {0x9E,0x57}, {0x89,0xF7}, {0x8A,0x41}, {0xD0,0xF0},
+ {0xAE,0x41}, {0x89,0xF8}, {0xD4,0x77}, {0xFA,0xF1},
+ {0xB0,0xE4}, {0xD4,0xA7}, {0xB0,0xE2}, {0xB0,0xDF},
+ {0xD4,0x7C}, {0xB0,0xDB}, {0xD4,0xA2}, {0xB0,0xE6},
+ {0xD4,0x76}, {0xD4,0x7B}, {0xD4,0x7A}, {0xAD,0xF2},
+ {0xB0,0xE1}, {0xD4,0xA5}, {0xD4,0xA8}, {0xD4,0x73},
+ {0xB3,0xE8}, {0x89,0xFA}, {0xD4,0xA9}, {0xB0,0xE7},
+ {0xB0,0xD9}, {0xB0,0xD6}, {0xD4,0x7E}, {0xB0,0xD3},
+ {0xFB,0x42}, {0xD4,0xA6}, {0xFA,0xBF}, {0xB0,0xDA},
+ {0xD4,0xAA}, {0xD4,0x74}, {0xD4,0xA4}, {0xB0,0xDD},
+ {0xD4,0x75}, {0xD4,0x78}, {0xD4,0x7D}, {0xFB,0xA3},
+ {0xB0,0xDE}, {0xB0,0xDC}, {0xB0,0xE8}, {0xB0,0xE3},
+ {0xFA,0xF7}, {0xB0,0xD7}, {0xB1,0xD2}, {0xB0,0xD8},
+ {0xD4,0x79}, {0xB0,0xE5}, {0xB0,0xE0}, {0xD4,0xA3},
+ {0xB0,0xD5}, {0x9E,0x4E}, {0xB0,0xD4}, {0x94,0xDC},
+ {0x95,0xDA}, {0x9D,0xF8}, {0x9F,0x6A}, {0xD4,0x71},
+ {0xD4,0x72}, {0xD8,0x6A}, {0x8A,0xB7}, {0xB3,0xD7},
+ {0xB3,0xDA}, {0xD8,0x75}, {0xB3,0xEE}, {0xD8,0x78},
+ {0xB3,0xD8}, {0xD8,0x71}, {0xB3,0xDE}, {0xB3,0xE4},
+ {0xB5,0xBD}, {0xFB,0x46}, {0xB3,0xE2}, {0xD8,0x6E},
+ {0xB3,0xEF}, {0xB3,0xDB}, {0xB3,0xE3}, {0xD8,0x76},
+ {0xDC,0xD7}, {0xD8,0x7B}, {0xD8,0x6F}, {0x8A,0x46},
+ {0xD8,0x66}, {0xD8,0x73}, {0xD8,0x6D}, {0xB3,0xE1},
+ {0xD8,0x79}, {0xB3,0xDD}, {0xB3,0xF1}, {0xB3,0xEA},
+ {0xB3,0xDF}, {0xB3,0xDC}, {0xB3,0xE7}, {0xD8,0x7A},
+ {0xD8,0x6C}, {0xD8,0x72}, {0xD8,0x74}, {0xD8,0x68},
+ {0xD8,0x77}, {0xB3,0xD9}, {0xD8,0x67}, {0xFB,0x47},
+ {0xB3,0xE0}, {0xB3,0xF0}, {0xB3,0xEC}, {0xD8,0x69},
+ {0xB3,0xE6}, {0x91,0x48}, {0xB3,0xED}, {0xB3,0xE9},
+ {0xB3,0xE5}, {0x92,0xDE}, {0xD8,0x70}, {0x8B,0x53},
+ {0x9D,0xF6}, {0xB3,0xEB}, {0x9B,0xDA}, {0xDC,0xD5},
+ {0xDC,0xD1}, {0x9D,0x7E}, {0xDC,0xE0}, {0xDC,0xCA},
+ {0xDC,0xD3}, {0xB6,0xE5}, {0xB6,0xE6}, {0xB6,0xDE},
+ {0xDC,0xDC}, {0xB6,0xE8}, {0xDC,0xCF}, {0xDC,0xCE},
+ {0xDC,0xCC}, {0xDC,0xDE}, {0xB6,0xDC}, {0xDC,0xD8},
+ {0xDC,0xCD}, {0xB6,0xDF}, {0xDC,0xD6}, {0xB6,0xDA},
+ {0xDC,0xD2}, {0xDC,0xD9}, {0xDC,0xDB}, {0x89,0xFD},
+ {0x99,0xE4}, {0xDC,0xDF}, {0xB6,0xE3}, {0xDC,0xCB},
+ {0xB6,0xDD}, {0xDC,0xD0}, {0x9E,0x43}, {0xB6,0xD8},
+ {0xB6,0xE4}, {0xDC,0xDA}, {0xB6,0xE0}, {0xB6,0xE1},
+ {0xB6,0xE7}, {0xB6,0xDB}, {0xA2,0x5F}, {0xB6,0xD9},
+ {0xDC,0xD4}, {0x9D,0xE9}, {0x8F,0x52}, {0xB6,0xE2},
+ {0x9D,0xF5}, {0x9D,0xF0}, {0xDC,0xDD}, {0x99,0xE7},
+ {0xB9,0xCD}, {0xB9,0xC8}, {0xE1,0x55}, {0xE1,0x51},
+ {0x8B,0xBD}, {0xE1,0x4B}, {0xB9,0xC2}, {0xB9,0xBE},
+ {0xE1,0x54}, {0xB9,0xBF}, {0xE1,0x4E}, {0xE1,0x50},
+ {0xE1,0x53}, {0x9D,0xEF}, {0xB9,0xC4}, {0xB9,0xCB},
+ {0xB9,0xC5}, {0xE1,0x49}, {0xB9,0xC6}, {0xB9,0xC7},
+ {0xE1,0x4C}, {0xB9,0xCC}, {0x9F,0xB7}, {0xE1,0x4A},
+ {0xE1,0x4F}, {0xB9,0xC3}, {0xE1,0x48}, {0xB9,0xC9},
+ {0xB9,0xC1}, {0xB9,0xC0}, {0xE1,0x4D}, {0xE1,0x52},
+ {0x9D,0xD0}, {0xB9,0xCA}, {0x9F,0xEB}, {0x8D,0xA9},
+ {0x9D,0xCF}, {0x98,0xE1}, {0x9D,0xE5}, {0xE1,0x47},
+ {0xBC,0x4D}, {0xE5,0x47}, {0xE5,0x44}, {0x9D,0xC8},
+ {0xBC,0x47}, {0xBC,0x53}, {0xBC,0x54}, {0xBC,0x4A},
+ {0xE5,0x42}, {0xBC,0x4C}, {0xE4,0xF9}, {0xBC,0x52},
+ {0xFB,0x4F}, {0xE5,0x46}, {0xBC,0x49}, {0xE5,0x48},
+ {0xBC,0x48}, {0xE5,0x43}, {0xE5,0x45}, {0xBC,0x4B},
+ {0xE5,0x41}, {0xE4,0xFA}, {0xE4,0xF7}, {0x9D,0xEB},
+ {0xD8,0x6B}, {0xE4,0xFD}, {0xE4,0xF6}, {0xE4,0xFC},
+ {0xE4,0xFB}, {0xE4,0xF8}, {0xFB,0x54}, {0xBC,0x4F},
+ {0xFB,0x55}, {0x9A,0xA2}, {0x8A,0xD6}, {0xBC,0x4E},
+ {0x9A,0x5F}, {0xBC,0x50}, {0xE4,0xFE}, {0xBE,0xB2},
+ {0xE5,0x40}, {0x9E,0xF5}, {0xE9,0x45}, {0xE8,0xFD},
+ {0x8F,0xB7}, {0xBE,0xBE}, {0xE9,0x42}, {0xBE,0xB6},
+ {0xBE,0xBA}, {0xE9,0x41}, {0xBE,0xB9}, {0xBE,0xB5},
+ {0xBE,0xB8}, {0xBE,0xB3}, {0xBE,0xBD}, {0xE9,0x43},
+ {0xE8,0xFE}, {0xBE,0xBC}, {0xE8,0xFC}, {0xBE,0xBB},
+ {0xE9,0x44}, {0xE9,0x40}, {0xBC,0x51}, {0xBE,0xBF},
+ {0xE9,0x46}, {0xBE,0xB7}, {0xBE,0xB4}, {0x9A,0xD2},
+ {0x9E,0x6A}, {0x9E,0xE8}, {0xEC,0xC6}, {0xEC,0xC8},
+ {0xC0,0x7B}, {0xEC,0xC9}, {0xEC,0xC7}, {0xEC,0xC5},
+ {0xEC,0xC4}, {0xC0,0x7D}, {0xEC,0xC3}, {0xC0,0x7E},
+ {0x8B,0xBF}, {0x91,0xC2}, {0x9D,0x62}, {0xEC,0xC1},
+ {0xEC,0xC2}, {0xC0,0x7A}, {0xC0,0xA1}, {0xC0,0x7C},
+ {0x92,0x60}, {0xEC,0xC0}, {0xC2,0x50}, {0xEF,0xBC},
+ {0xEF,0xBA}, {0xEF,0xBF}, {0xEF,0xBD}, {0xEF,0xBB},
+ {0xEF,0xBE}, {0x92,0x5E}, {0x91,0xC1}, {0x8A,0xC5},
+ {0x97,0xA3}, {0xC3,0x60}, {0xF1,0xF2}, {0xF1,0xF3},
+ {0xC4,0x56}, {0xF1,0xF4}, {0xF1,0xF0}, {0xF1,0xF5},
+ {0xF1,0xF1}, {0xC2,0x51}, {0x8B,0x6C}, {0x8D,0x7E},
+ {0xF3,0xFE}, {0xF4,0x41}, {0xC4,0x59}, {0xF4,0x40},
+ {0xC4,0x58}, {0xC4,0x57}, {0x9C,0x54}, {0xC4,0x5A},
+ {0xF5,0xC5}, {0xF5,0xC6}, {0x9D,0xBD}, {0xC4,0xDA},
+ {0xC4,0xD9}, {0xC4,0xDB}, {0xF5,0xC4}, {0xF6,0xD8},
+ {0xF6,0xD7}, {0xC5,0x6D}, {0xC5,0x6F}, {0xC5,0x6E},
+ {0xF6,0xD9}, {0xC5,0xC8}, {0xF8,0xA6}, {0xC5,0xF1},
+ {0xF8,0xA5}, {0xF8,0xEE}, {0x9C,0xC5}, {0xC9,0x49},
+ {0xA5,0x7D}, {0xA5,0x7C}, {0xA6,0x5F}, {0xA6,0x5E},
+ {0xC9,0xC7}, {0xA6,0x5D}, {0xC9,0xC6}, {0x89,0x5B},
+ {0xA7,0x79}, {0xCA,0xA9}, {0xCA,0xA8}, {0xA7,0x77},
+ {0xA7,0x7A}, {0xFB,0x5C}, {0xCA,0xA7}, {0xFB,0x5B},
+ {0xA7,0x78}, {0xFB,0x57}, {0xCB,0xF0}, {0xCB,0xF1},
+ {0xA9,0x54}, {0x98,0xC7}, {0xAB,0xAA}, {0xFB,0x5A},
+ {0xD1,0x48}, {0xD1,0x49}, {0xAE,0x45}, {0xAE,0x46},
+ {0xD4,0xAC}, {0xB0,0xE9}, {0xB0,0xEB}, {0xD4,0xAB},
+ {0xB0,0xEA}, {0xD8,0x7C}, {0xB3,0xF2}, {0xB6,0xE9},
+ {0xB6,0xEA}, {0xDC,0xE1}, {0x9C,0xEE}, {0xB9,0xCF},
+ {0xB9,0xCE}, {0xE5,0x49}, {0xE9,0x48}, {0xE9,0x47},
+ {0x92,0xE2}, {0xF9,0x6B}, {0xA4,0x67}, {0xC9,0x59},
+ {0xC9,0x6E}, {0xC9,0x6F}, {0xA6,0x62}, {0xA6,0x66},
+ {0xC9,0xC9}, {0xA6,0x64}, {0xA6,0x63}, {0xC9,0xC8},
+ {0xA6,0x65}, {0xA6,0x61}, {0x94,0xA7}, {0xA6,0x60},
+ {0xC9,0xCA}, {0xA7,0xA6}, {0x8C,0xCC}, {0xA7,0xA3},
+ {0x9B,0xD4}, {0xA7,0x7D}, {0xCA,0xAA}, {0xFB,0x64},
+ {0xFB,0x76}, {0xCA,0xAB}, {0xFB,0x60}, {0xA7,0xA1},
+ {0xCA,0xAD}, {0xA7,0x7B}, {0xCA,0xAE}, {0xCA,0xAC},
+ {0xA7,0x7E}, {0xA7,0xA2}, {0xA7,0xA5}, {0xA7,0xA4},
+ {0xA7,0x7C}, {0xCA,0xAF}, {0x99,0xE5}, {0x9A,0xC2},
+ {0x91,0xFB}, {0xA0,0x73}, {0xA9,0x59}, {0xCB,0xFE},
+ {0xA9,0x5B}, {0xA9,0x5A}, {0x9F,0x72}, {0xCC,0x40},
+ {0xA9,0x58}, {0xA9,0x57}, {0xCB,0xF5}, {0xCB,0xF4},
+ {0xCB,0xF2}, {0xCB,0xF7}, {0xCB,0xF6}, {0xCB,0xF3},
+ {0xCB,0xFC}, {0xCB,0xFD}, {0xCB,0xFA}, {0xCB,0xF8},
+ {0xA9,0x56}, {0x9F,0xCC}, {0xCB,0xFB}, {0xA9,0x5C},
+ {0xCC,0x41}, {0x98,0xA5}, {0x92,0xE8}, {0xCB,0xF9},
+ {0xAB,0xAB}, {0xA9,0x55}, {0x9B,0xBC}, {0x96,0xF3},
+ {0xAB,0xAC}, {0xCE,0x54}, {0x92,0xE7}, {0xCE,0x5A},
+ {0xFC,0x67}, {0xAB,0xB2}, {0xCE,0x58}, {0xCE,0x5E},
+ {0xCE,0x55}, {0xCE,0x59}, {0xCE,0x5B}, {0xCE,0x5D},
+ {0xCE,0x57}, {0x8B,0x7D}, {0xCE,0x56}, {0xCE,0x51},
+ {0xCE,0x52}, {0xAB,0xAD}, {0x9B,0xF4}, {0xAB,0xAF},
+ {0xAB,0xAE}, {0xCE,0x53}, {0xCE,0x5C}, {0x9E,0xF7},
+ {0x9E,0xC1}, {0xAB,0xB1}, {0x99,0x6F}, {0xCE,0x50},
+ {0xD1,0x53}, {0xD1,0x52}, {0xD1,0x57}, {0xD1,0x4E},
+ {0x96,0xF1}, {0xD1,0x51}, {0xD1,0x50}, {0x8E,0x41},
+ {0xD1,0x54}, {0xD1,0x58}, {0xAE,0x47}, {0xAE,0x4A},
+ {0x95,0x4A}, {0xD1,0x4F}, {0xD1,0x55}, {0x97,0xE6},
+ {0xAE,0x49}, {0xD1,0x4A}, {0xAB,0xB0}, {0xD4,0xBA},
+ {0xD1,0x56}, {0xD1,0x4D}, {0xAE,0x48}, {0xD1,0x4C},
+ {0x96,0xF5}, {0xD4,0xB1}, {0x92,0xE6}, {0x9F,0x42},
+ {0xB0,0xEC}, {0xB0,0xF0}, {0xD4,0xC1}, {0xD4,0xAF},
+ {0xD4,0xBD}, {0xB0,0xF1}, {0xD4,0xBF}, {0xFB,0x67},
+ {0xD4,0xC5}, {0xD4,0xC9}, {0xD4,0xC0}, {0xD4,0xB4},
+ {0xD4,0xBC}, {0x99,0xA9}, {0xD4,0xCA}, {0xD4,0xC8},
+ {0xD4,0xBE}, {0xD4,0xB9}, {0xD4,0xB2}, {0xD8,0xA6},
+ {0xD4,0xB0}, {0xB0,0xF5}, {0xD4,0xB7}, {0xB0,0xF6},
+ {0xB0,0xF2}, {0xD4,0xAD}, {0xD4,0xC3}, {0xD4,0xB5},
+ {0xFA,0xE6}, {0xD4,0xB3}, {0xD4,0xC6}, {0xB0,0xF3},
+ {0xFB,0x69}, {0xD4,0xCC}, {0xB0,0xED}, {0xB0,0xEF},
+ {0xD4,0xBB}, {0xD4,0xB6}, {0xAE,0x4B}, {0xB0,0xEE},
+ {0xD4,0xB8}, {0xD4,0xC7}, {0xD4,0xCB}, {0xD4,0xC2},
+ {0xD4,0xC4}, {0x97,0xE5}, {0xD4,0xAE}, {0xD8,0xA1},
+ {0xD8,0xAA}, {0xD8,0xA9}, {0xB3,0xFA}, {0xD8,0xA2},
+ {0xB3,0xFB}, {0xB3,0xF9}, {0x96,0x7D}, {0xD8,0xA4},
+ {0xB3,0xF6}, {0xD8,0xA8}, {0xFB,0x6C}, {0xD8,0xA3},
+ {0xD8,0xA5}, {0xD8,0x7D}, {0xB3,0xF4}, {0xD8,0xB2},
+ {0xD8,0xB1}, {0xD8,0xAE}, {0xB3,0xF3}, {0xB3,0xF7},
+ {0xB3,0xF8}, {0xD1,0x4B}, {0xD8,0xAB}, {0xB3,0xF5},
+ {0xB0,0xF4}, {0xD8,0xAD}, {0xD8,0x7E}, {0xD8,0xB0},
+ {0xD8,0xAF}, {0x99,0xA2}, {0xD8,0xB3}, {0xDC,0xEF},
+ {0xD8,0xAC}, {0x9A,0xBB}, {0x9A,0x65}, {0x94,0x4E},
+ {0xD8,0xA7}, {0xDC,0xE7}, {0xB6,0xF4}, {0xB6,0xF7},
+ {0xB6,0xF2}, {0xDC,0xE6}, {0xDC,0xEA}, {0xDC,0xE5},
+ {0xB6,0xEC}, {0xB6,0xF6}, {0xDC,0xE2}, {0xB6,0xF0},
+ {0xDC,0xE9}, {0xB6,0xEE}, {0xB6,0xED}, {0xDC,0xEC},
+ {0xB6,0xEF}, {0xDC,0xEE}, {0xFB,0x6E}, {0xDC,0xEB},
+ {0xB6,0xEB}, {0x99,0xDF}, {0xB6,0xF5}, {0xDC,0xF0},
+ {0xDC,0xE4}, {0xDC,0xED}, {0xDC,0xE3}, {0x98,0xE3},
+ {0xB6,0xF1}, {0x92,0x54}, {0xB6,0xF3}, {0xDC,0xE8},
+ {0xDC,0xF1}, {0x96,0x7B}, {0x8A,0xAF}, {0xE1,0x5D},
+ {0xB9,0xD0}, {0xE1,0x63}, {0xB9,0xD5}, {0xE1,0x5F},
+ {0xE1,0x66}, {0xE1,0x57}, {0xB9,0xD7}, {0xB9,0xD1},
+ {0xE1,0x5C}, {0xBC,0x55}, {0xE1,0x5B}, {0xE1,0x64},
+ {0xB9,0xD2}, {0xB9,0xD6}, {0xE1,0x5A}, {0xE1,0x60},
+ {0xE1,0x65}, {0xE1,0x56}, {0xB9,0xD4}, {0xE1,0x5E},
+ {0xE1,0x62}, {0xE1,0x68}, {0xE1,0x58}, {0xE1,0x61},
+ {0x8C,0x77}, {0xB9,0xD3}, {0xE1,0x67}, {0xE1,0x59},
+ {0x8B,0xAF}, {0x9E,0xBD}, {0xBC,0x59}, {0xE5,0x4B},
+ {0xBC,0x57}, {0xBC,0x56}, {0xE5,0x4D}, {0xE5,0x52},
+ {0xE5,0x4E}, {0xE5,0x51}, {0xBC,0x5C}, {0x9E,0xE6},
+ {0xBE,0xA5}, {0xBC,0x5B}, {0xFB,0x6F}, {0xE5,0x4A},
+ {0xE5,0x50}, {0xBC,0x5A}, {0xE5,0x4F}, {0x8E,0xE1},
+ {0xE5,0x4C}, {0xBC,0x58}, {0x9B,0x7D}, {0x9C,0x7E},
+ {0xE9,0x4D}, {0xF9,0xD9}, {0xE9,0x4F}, {0xE9,0x4A},
+ {0xBE,0xC1}, {0xE9,0x4C}, {0xBE,0xC0}, {0xE9,0x4E},
+ {0xBE,0xC3}, {0xE9,0x50}, {0xBE,0xC2}, {0xE9,0x49},
+ {0xE9,0x4B}, {0x92,0xEA}, {0xC0,0xA5}, {0xEC,0xCC},
+ {0x8C,0x78}, {0xC0,0xA4}, {0xEC,0xCD}, {0xC0,0xA3},
+ {0xEC,0xCB}, {0xC0,0xA2}, {0xEC,0xCA}, {0xC2,0x53},
+ {0xC2,0x52}, {0xF1,0xF6}, {0xF1,0xF8}, {0xFB,0x72},
+ {0xF1,0xF7}, {0xC3,0x61}, {0xC3,0x62}, {0xFB,0x71},
+ {0xC3,0x63}, {0xF4,0x42}, {0xC4,0x5B}, {0xF7,0xD3},
+ {0xF7,0xD2}, {0xC5,0xF2}, {0xA4,0x68}, {0xA4,0xD0},
+ {0xA7,0xA7}, {0x89,0x5C}, {0x98,0xF0}, {0x96,0xF2},
+ {0xCE,0x5F}, {0xB3,0xFC}, {0xB3,0xFD}, {0xFB,0x74},
+ {0xDC,0xF2}, {0xB9,0xD8}, {0xE1,0x69}, {0xE5,0x53},
+ {0x8B,0xC1}, {0xC9,0x5A}, {0x89,0x5D}, {0x89,0xDE},
+ {0xCA,0xB0}, {0x89,0x5E}, {0xC6,0xCA}, {0xCC,0x42},
+ {0xCE,0x60}, {0xD1,0x59}, {0xAE,0x4C}, {0xFE,0x42},
+ {0xF1,0xF9}, {0xC4,0xDC}, {0xA4,0x69}, {0xA5,0x7E},
+ {0xC9,0x70}, {0xA6,0x67}, {0xA6,0x68}, {0xA9,0x5D},
+ {0xFB,0x7B}, {0xB0,0xF7}, {0xB9,0xDA}, {0xB9,0xDB},
+ {0xB9,0xD9}, {0xA4,0x6A}, {0xA4,0xD1}, {0xA4,0xD3},
+ {0xA4,0xD2}, {0xC9,0x5B}, {0xA4,0xD4}, {0xA5,0xA1},
+ {0xC9,0x71}, {0xA5,0xA2}, {0x89,0x5F}, {0x89,0x60},
+ {0xA6,0x69}, {0xA6,0x6A}, {0xC9,0xCB}, {0xA7,0xA8},
+ {0xCA,0xB1}, {0xA9,0x61}, {0xCC,0x43}, {0xA9,0x5F},
+ {0xA9,0x60}, {0xA9,0x5E}, {0xD1,0x5A}, {0xAB,0xB6},
+ {0xAB,0xB5}, {0xAB,0xB7}, {0xAB,0xB4}, {0xCE,0x61},
+ {0xA9,0x62}, {0xAB,0xB3}, {0xAE,0x4D}, {0xAE,0x4E},
+ {0xAE,0x4F}, {0xD4,0xCD}, {0xB3,0xFE}, {0xD8,0xB4},
+ {0xB0,0xF8}, {0x9B,0xCD}, {0xB6,0xF8}, {0xB9,0xDD},
+ {0xB9,0xDC}, {0xE1,0x6A}, {0xBC,0x5D}, {0xBE,0xC4},
+ {0xEF,0xC0}, {0xF6,0xDA}, {0xF7,0xD4}, {0xA4,0x6B},
+ {0xA5,0xA3}, {0x9D,0xD3}, {0xA5,0xA4}, {0xC9,0xD1},
+ {0xA6,0x6C}, {0xA6,0x6F}, {0xC9,0xCF}, {0xC9,0xCD},
+ {0xA6,0x6E}, {0xC9,0xD0}, {0xC9,0xD2}, {0xC9,0xCC},
+ {0xA6,0x71}, {0xA6,0x70}, {0xA6,0x6D}, {0xA6,0x6B},
+ {0xC9,0xCE}, {0x98,0x4C}, {0xA7,0xB3}, {0xA7,0xB0},
+ {0xCA,0xB6}, {0xCA,0xB9}, {0xCA,0xB8}, {0xA7,0xAA},
+ {0xA7,0xB2}, {0x97,0x52}, {0xA7,0xAF}, {0xCA,0xB5},
+ {0xCA,0xB3}, {0xA7,0xAE}, {0x95,0xC3}, {0xA7,0xA9},
+ {0xA7,0xAC}, {0x9B,0xB6}, {0xCA,0xB4}, {0xCA,0xBB},
+ {0xCA,0xB7}, {0xA7,0xAD}, {0xA7,0xB1}, {0xA7,0xB4},
+ {0xCA,0xB2}, {0xCA,0xBA}, {0xA7,0xAB}, {0x9A,0xB9},
+ {0xA9,0x67}, {0xA9,0x6F}, {0x97,0xB3}, {0xCC,0x4F},
+ {0xCC,0x48}, {0xA9,0x70}, {0xCC,0x53}, {0xCC,0x44},
+ {0xCC,0x4B}, {0x9F,0x74}, {0x92,0xF1}, {0xA9,0x66},
+ {0xCC,0x45}, {0xA9,0x64}, {0xCC,0x4C}, {0xCC,0x50},
+ {0xA9,0x63}, {0xCC,0x51}, {0xCC,0x4A}, {0xCC,0x4D},
+ {0x97,0xDF}, {0xA9,0x72}, {0xA9,0x69}, {0xCC,0x54},
+ {0xCC,0x52}, {0xFB,0xA6}, {0xA9,0x6E}, {0xA9,0x6C},
+ {0xCC,0x49}, {0xA9,0x6B}, {0xCC,0x47}, {0xCC,0x46},
+ {0xA9,0x6A}, {0xA9,0x68}, {0xA9,0x71}, {0xA9,0x6D},
+ {0xA9,0x65}, {0xCC,0x4E}, {0xAB,0xB9}, {0xFB,0xAB},
+ {0xAB,0xC0}, {0xCE,0x6F}, {0xAB,0xB8}, {0xCE,0x67},
+ {0xCE,0x63}, {0xCE,0x73}, {0xCE,0x62}, {0xAB,0xBB},
+ {0xCE,0x6C}, {0xAB,0xBE}, {0xAB,0xC1}, {0xAB,0xBC},
+ {0xCE,0x70}, {0xAB,0xBF}, {0x98,0x77}, {0xAE,0x56},
+ {0xCE,0x76}, {0xCE,0x64}, {0x98,0x54}, {0x95,0xC5},
+ {0xCE,0x66}, {0xCE,0x6D}, {0xCE,0x71}, {0xCE,0x75},
+ {0xCE,0x72}, {0xCE,0x6B}, {0xCE,0x6E}, {0x9D,0x55},
+ {0xFB,0xB2}, {0xCE,0x68}, {0xAB,0xC3}, {0xCE,0x6A},
+ {0xCE,0x69}, {0xCE,0x74}, {0xAB,0xBA}, {0xCE,0x65},
+ {0xAB,0xC2}, {0x95,0x7E}, {0xAB,0xBD}, {0xAE,0x5C},
+ {0xD1,0x62}, {0x97,0x42}, {0xAE,0x5B}, {0x94,0xE6},
+ {0xD1,0x60}, {0xAE,0x50}, {0x92,0xF5}, {0xAE,0x55},
+ {0xD1,0x5F}, {0xD1,0x5C}, {0xD1,0x61}, {0xAE,0x51},
+ {0xD1,0x5B}, {0x8C,0xC5}, {0xAE,0x54}, {0xAE,0x52},
+ {0xD1,0x63}, {0xAE,0x53}, {0xAE,0x57}, {0x92,0xFD},
+ {0xAE,0x58}, {0xFB,0xA2}, {0xAE,0x5A}, {0x9C,0x51},
+ {0xAE,0x59}, {0x94,0xE9}, {0x98,0x5C}, {0x92,0xF0},
+ {0xD1,0x5D}, {0xD1,0x5E}, {0xD1,0x64}, {0xD4,0xD4},
+ {0xB0,0xF9}, {0xD8,0xC2}, {0xD4,0xD3}, {0xD4,0xE6},
+ {0xB1,0x40}, {0x94,0x4C}, {0xD4,0xE4}, {0xB0,0xFE},
+ {0xB0,0xFA}, {0xD4,0xED}, {0xD4,0xDD}, {0xD4,0xE0},
+ {0x91,0x6B}, {0xB1,0x43}, {0xD4,0xEA}, {0xD4,0xE2},
+ {0xB0,0xFB}, {0xB1,0x44}, {0xD4,0xE7}, {0xD4,0xE5},
+ {0xD4,0xD6}, {0xD4,0xEB}, {0xD4,0xDF}, {0xD4,0xDA},
+ {0x8B,0x78}, {0xD4,0xD0}, {0xD4,0xEC}, {0xD4,0xDC},
+ {0xD4,0xCF}, {0x94,0xE2}, {0xB1,0x42}, {0xD4,0xE1},
+ {0xD4,0xEE}, {0xD4,0xDE}, {0xD4,0xD2}, {0xD4,0xD7},
+ {0xD4,0xCE}, {0x98,0x4F}, {0xB1,0x41}, {0xFB,0xB5},
+ {0xD4,0xDB}, {0xD4,0xD8}, {0xB0,0xFC}, {0xD4,0xD1},
+ {0x92,0x71}, {0xD4,0xE9}, {0xB0,0xFD}, {0x93,0x65},
+ {0xD4,0xD9}, {0xD4,0xD5}, {0x98,0x5B}, {0xD4,0xE8},
+ {0x98,0x50}, {0xB4,0x40}, {0xD8,0xBB}, {0x97,0xBC},
+ {0xD8,0xB8}, {0xD8,0xC9}, {0xD8,0xBD}, {0xD8,0xCA},
+ {0x92,0xF3}, {0xB4,0x42}, {0x93,0x40}, {0x98,0x4D},
+ {0xD8,0xC6}, {0xD8,0xC3}, {0x95,0x72}, {0xFD,0xEF},
+ {0xD8,0xC4}, {0xD8,0xC7}, {0xD8,0xCB}, {0xD4,0xE3},
+ {0xD8,0xCD}, {0xDD,0x47}, {0xFD,0xC1}, {0xB4,0x43},
+ {0xD8,0xCE}, {0xD8,0xB6}, {0xD8,0xC0}, {0xFB,0xBA},
+ {0xD8,0xC5}, {0x92,0xEB}, {0xB4,0x41}, {0xB4,0x44},
+ {0xD8,0xCC}, {0xD8,0xCF}, {0xD8,0xBA}, {0xD8,0xB7},
+ {0xFC,0x73}, {0x97,0xB7}, {0xD8,0xB9}, {0xD8,0xBE},
+ {0xD8,0xBC}, {0xB4,0x45}, {0xD8,0xC8}, {0xFB,0xB4},
+ {0xD8,0xBF}, {0xD8,0xC1}, {0xD8,0xB5}, {0xDC,0xFA},
+ {0xDC,0xF8}, {0xB7,0x42}, {0xB7,0x40}, {0xDD,0x43},
+ {0xDC,0xF9}, {0xDD,0x44}, {0xDD,0x40}, {0xDC,0xF7},
+ {0xDD,0x46}, {0xDC,0xF6}, {0xDC,0xFD}, {0xB6,0xFE},
+ {0xB6,0xFD}, {0xB6,0xFC}, {0xDC,0xFB}, {0xDD,0x41},
+ {0xB6,0xF9}, {0xB7,0x41}, {0x90,0xA7}, {0xDC,0xF4},
+ {0xDC,0xFE}, {0xDC,0xF3}, {0xDC,0xFC}, {0xB6,0xFA},
+ {0xDD,0x42}, {0xDC,0xF5}, {0xB6,0xFB}, {0xDD,0x45},
+ {0x97,0x41}, {0x92,0xF4}, {0xFB,0xBC}, {0xE1,0x6E},
+ {0xB9,0xE2}, {0xB9,0xE1}, {0xB9,0xE3}, {0xE1,0x7A},
+ {0xE1,0x70}, {0xE1,0x76}, {0xE1,0x6B}, {0xE1,0x79},
+ {0xE1,0x78}, {0xE1,0x7C}, {0xE1,0x75}, {0xB9,0xDE},
+ {0xE1,0x74}, {0xB9,0xE4}, {0x95,0x77}, {0xE1,0x6D},
+ {0xB9,0xDF}, {0xE1,0x7B}, {0xB9,0xE0}, {0xE1,0x6F},
+ {0xE1,0x72}, {0xE1,0x77}, {0xE1,0x71}, {0xE1,0x6C},
+ {0x9E,0xE2}, {0x8F,0x78}, {0xE1,0x73}, {0xE5,0x55},
+ {0xBC,0x61}, {0xE5,0x58}, {0xE5,0x57}, {0xE5,0x5A},
+ {0xE5,0x5C}, {0xF9,0xDC}, {0xBC,0x5F}, {0xE5,0x56},
+ {0x96,0x72}, {0xE5,0x54}, {0xE5,0x5D}, {0xE5,0x5B},
+ {0xE5,0x59}, {0xE5,0x5F}, {0xE5,0x5E}, {0xBC,0x63},
+ {0xBC,0x5E}, {0xBC,0x60}, {0xBC,0x62}, {0x9E,0xB5},
+ {0xE5,0x60}, {0xE9,0x57}, {0x96,0x4B}, {0xE9,0x56},
+ {0xE9,0x55}, {0x8C,0xAC}, {0xE9,0x58}, {0xE9,0x51},
+ {0xE9,0x52}, {0xE9,0x5A}, {0xE9,0x53}, {0xBE,0xC5},
+ {0xE9,0x5C}, {0xA0,0xFA}, {0xE9,0x5B}, {0xE9,0x54},
+ {0xEC,0xD1}, {0xC0,0xA8}, {0xEC,0xCF}, {0xEC,0xD4},
+ {0xEC,0xD3}, {0xE9,0x59}, {0xC0,0xA7}, {0x95,0x75},
+ {0xEC,0xD2}, {0xEC,0xCE}, {0xEC,0xD6}, {0xEC,0xD5},
+ {0xC0,0xA6}, {0xEC,0xD0}, {0xBE,0xC6}, {0xC2,0x54},
+ {0xEF,0xC1}, {0xF1,0xFA}, {0xF1,0xFB}, {0xF1,0xFC},
+ {0xC4,0x5C}, {0x90,0xDA}, {0xC4,0x5D}, {0x93,0x67},
+ {0xF4,0x43}, {0xFE,0xA4}, {0xF5,0xC8}, {0xF5,0xC7},
+ {0x90,0xDF}, {0xF6,0xDB}, {0xF6,0xDC}, {0xF7,0xD5},
+ {0xF8,0xA7}, {0x93,0x54}, {0xA4,0x6C}, {0xA4,0x6D},
+ {0xA4,0x6E}, {0xA4,0xD5}, {0xA5,0xA5}, {0xC9,0xD3},
+ {0xA6,0x72}, {0xA6,0x73}, {0xA7,0xB7}, {0xA7,0xB8},
+ {0xA7,0xB6}, {0xA7,0xB5}, {0xA9,0x73}, {0xCC,0x55},
+ {0xA9,0x75}, {0xA9,0x74}, {0xCC,0x56}, {0x89,0x61},
+ {0x8B,0xB4}, {0xAB,0xC4}, {0xAE,0x5D}, {0xD1,0x65},
+ {0x9D,0xC0}, {0xD4,0xF0}, {0xB1,0x45}, {0xB4,0x47},
+ {0xD4,0xEF}, {0xB4,0x46}, {0x8E,0x48}, {0xB9,0xE5},
+ {0xFB,0xC5}, {0xE1,0x7D}, {0xBE,0xC7}, {0xC0,0xA9},
+ {0xEC,0xD7}, {0xFB,0xC7}, {0xC4,0x5E}, {0xC5,0x70},
+ {0xC6,0xCB}, {0xC9,0x72}, {0xFA,0x79}, {0xA5,0xA6},
+ {0xC9,0x73}, {0xA6,0x76}, {0xA6,0x74}, {0xA6,0x75},
+ {0xA6,0x77}, {0xA7,0xBA}, {0xA7,0xB9}, {0xCA,0xBC},
+ {0xA7,0xBB}, {0x9E,0x67}, {0xCA,0xBD}, {0xCC,0x57},
+ {0xCC,0x58}, {0x8C,0xD9}, {0xA9,0x76}, {0xA9,0x78},
+ {0xA9,0x7A}, {0xA9,0x77}, {0xA9,0x7B}, {0xA9,0x79},
+ {0xFB,0xD2}, {0x89,0x62}, {0x89,0x63}, {0xAB,0xC8},
+ {0xAB,0xC5}, {0xAB,0xC7}, {0xAB,0xC9}, {0xAB,0xC6},
+ {0xD1,0x66}, {0xCE,0x77}, {0xFC,0x7D}, {0xD1,0x68},
+ {0xD1,0x67}, {0xAE,0x63}, {0xAE,0x5F}, {0xAE,0x60},
+ {0xAE,0x62}, {0xAE,0x64}, {0xAE,0x61}, {0xAE,0x66},
+ {0xAE,0x65}, {0xB1,0x4A}, {0xD4,0xF2}, {0xD4,0xF1},
+ {0xB1,0x49}, {0x9F,0x6B}, {0xB1,0x48}, {0xB1,0x47},
+ {0xB1,0x4B}, {0xB1,0x46}, {0xD8,0xD5}, {0xD8,0xD2},
+ {0xB4,0x49}, {0xD8,0xD1}, {0xD8,0xD6}, {0xB4,0x4B},
+ {0xD8,0xD4}, {0xB4,0x48}, {0xB4,0x4A}, {0xD8,0xD3},
+ {0xFB,0xCC}, {0xDD,0x48}, {0xFE,0xAE}, {0xDD,0x49},
+ {0xDD,0x4A}, {0xB9,0xE6}, {0xB9,0xEE}, {0xE1,0x7E},
+ {0xB9,0xE8}, {0xB9,0xEC}, {0xE1,0xA1}, {0xB9,0xED},
+ {0xB9,0xE9}, {0xB9,0xEA}, {0xB9,0xE7}, {0xB9,0xEB},
+ {0xBC,0x66}, {0xD8,0xD0}, {0xBC,0x67}, {0xBC,0x65},
+ {0xBC,0x64}, {0xE9,0x5D}, {0xBE,0xC8}, {0xEC,0xD8},
+ {0xEC,0xD9}, {0xFB,0xD1}, {0xC3,0x64}, {0xC4,0x5F},
+ {0xA4,0x6F}, {0xA6,0x78}, {0xFB,0x75}, {0xAB,0xCA},
+ {0xD1,0x69}, {0xAE,0x67}, {0xFB,0xD4}, {0xB1,0x4E},
+ {0xB1,0x4D}, {0xB1,0x4C}, {0xB4,0x4C}, {0xB4,0x4D},
+ {0xD8,0xD7}, {0xB9,0xEF}, {0xBE,0xC9}, {0xA4,0x70},
+ {0xC9,0x5C}, {0xA4,0xD6}, {0xC9,0x74}, {0xFB,0xD6},
+ {0xFB,0xD8}, {0xC9,0xD4}, {0xA6,0x79}, {0xA9,0x7C},
+ {0x8B,0x5D}, {0x93,0x4C}, {0xDD,0x4B}, {0x9A,0xE2},
+ {0xA4,0x71}, {0x8B,0xC9}, {0xA4,0xD7}, {0xC9,0xD5},
+ {0xCA,0xBE}, {0xCA,0xBF}, {0xA7,0xBC}, {0xD8,0xD8},
+ {0xB4,0x4E}, {0xDD,0x4C}, {0xC0,0xAA}, {0xA4,0x72},
+ {0xA4,0xA8}, {0xA4,0xD8}, {0xC9,0x75}, {0xA5,0xA7},
+ {0xA7,0xC0}, {0xA7,0xBF}, {0xA7,0xBD}, {0xA7,0xBE},
+ {0xCC,0x59}, {0xA9,0x7E}, {0xA9,0xA1}, {0xCC,0x5A},
+ {0xA9,0x7D}, {0xFB,0xDB}, {0x9F,0xC9}, {0xAB,0xCE},
+ {0xCE,0x78}, {0xAB,0xCD}, {0xAB,0xCB}, {0xAB,0xCC},
+ {0xAE,0x6A}, {0xAE,0x68}, {0x9F,0x44}, {0xD1,0x6B},
+ {0xAE,0x69}, {0xD1,0x6A}, {0xAE,0x5E}, {0xD4,0xF3},
+ {0xB1,0x50}, {0xB1,0x51}, {0x98,0xED}, {0xB1,0x4F},
+ {0xB9,0xF0}, {0xE1,0xA2}, {0xBC,0x68}, {0xBC,0x69},
+ {0xE5,0x61}, {0xC0,0xAB}, {0xEF,0xC2}, {0xEF,0xC3},
+ {0xC4,0xDD}, {0xF8,0xA8}, {0xC9,0x4B}, {0xA4,0xD9},
+ {0xA4,0x73}, {0xC9,0x77}, {0xC9,0x76}, {0xA6,0x7A},
+ {0xC9,0xD7}, {0xC9,0xD8}, {0xC9,0xD6}, {0xC9,0xD9},
+ {0xFB,0xDD}, {0xCA,0xC7}, {0xCA,0xC2}, {0xCA,0xC4},
+ {0xCA,0xC6}, {0xCA,0xC3}, {0xA7,0xC4}, {0xCA,0xC0},
+ {0xCA,0xC1}, {0xA7,0xC1}, {0xA7,0xC2}, {0xCA,0xC5},
+ {0xCA,0xC8}, {0xA7,0xC3}, {0xCA,0xC9}, {0x8D,0xF2},
+ {0x89,0x64}, {0xFD,0xF2}, {0xCC,0x68}, {0x93,0x4D},
+ {0xCC,0x62}, {0xCC,0x5D}, {0xA9,0xA3}, {0xCC,0x65},
+ {0xCC,0x63}, {0xCC,0x5C}, {0xCC,0x69}, {0xCC,0x6C},
+ {0xCC,0x67}, {0xCC,0x60}, {0xA9,0xA5}, {0xCC,0x66},
+ {0xA9,0xA6}, {0xCC,0x61}, {0xCC,0x64}, {0xCC,0x5B},
+ {0xCC,0x5F}, {0xCC,0x6B}, {0xA9,0xA7}, {0xA9,0xA8},
+ {0xCC,0x5E}, {0xCC,0x6A}, {0xA9,0xA2}, {0xA9,0xA4},
+ {0xFB,0xE7}, {0xA0,0xF2}, {0x98,0x68}, {0xCE,0xAB},
+ {0xCE,0xA4}, {0xCE,0xAA}, {0xCE,0xA3}, {0xCE,0xA5},
+ {0xCE,0x7D}, {0xCE,0x7B}, {0xCE,0xAC}, {0xCE,0xA9},
+ {0xCE,0x79}, {0x9F,0x58}, {0xAB,0xD0}, {0xCE,0xA7},
+ {0xCE,0xA8}, {0xCE,0xA6}, {0xCE,0x7C}, {0xCE,0x7A},
+ {0xAB,0xCF}, {0xCE,0xA2}, {0xCE,0x7E}, {0xCE,0xA1},
+ {0xCE,0xAD}, {0x8D,0x73}, {0xAE,0x6F}, {0xFB,0xDE},
+ {0xAE,0x6E}, {0xD1,0x6C}, {0xAE,0x6B}, {0xD1,0x6E},
+ {0xFB,0xDF}, {0xAE,0x70}, {0xD1,0x6F}, {0xAE,0x73},
+ {0x8C,0x48}, {0xAE,0x71}, {0xD1,0x70}, {0xCE,0xAE},
+ {0xD1,0x72}, {0xAE,0x6D}, {0xAE,0x6C}, {0xD1,0x6D},
+ {0xD1,0x71}, {0xAE,0x72}, {0xB1,0x53}, {0xB1,0x52},
+ {0xD4,0xF5}, {0xD4,0xF9}, {0xD4,0xFB}, {0xB1,0x54},
+ {0xD4,0xFE}, {0xFB,0xE3}, {0xB1,0x58}, {0xD5,0x41},
+ {0xB1,0x5A}, {0x8D,0xA8}, {0xB1,0x56}, {0xB1,0x5E},
+ {0xFB,0xE4}, {0xB1,0x5B}, {0xD4,0xF7}, {0xB1,0x55},
+ {0xD4,0xF6}, {0xD4,0xF4}, {0xD5,0x43}, {0xD4,0xF8},
+ {0xB1,0x57}, {0xD5,0x42}, {0xB1,0x5C}, {0xD4,0xFD},
+ {0xD4,0xFC}, {0xB1,0x5D}, {0xD4,0xFA}, {0xB1,0x59},
+ {0x9C,0x75}, {0xD5,0x44}, {0x98,0x78}, {0xD5,0x40},
+ {0xD8,0xE7}, {0xD8,0xEE}, {0xD8,0xE3}, {0xB4,0x51},
+ {0xD8,0xDF}, {0xD8,0xEF}, {0xD8,0xD9}, {0xD8,0xEC},
+ {0xD8,0xEA}, {0xD8,0xE4}, {0xD8,0xED}, {0xD8,0xE6},
+ {0x8D,0x60}, {0xD8,0xDE}, {0xD8,0xF0}, {0xD8,0xDC},
+ {0xD8,0xE9}, {0xD8,0xDA}, {0xD8,0xF1}, {0xFB,0xE5},
+ {0xB4,0x52}, {0x8D,0x61}, {0xD8,0xEB}, {0xDD,0x4F},
+ {0xD8,0xDD}, {0xB4,0x4F}, {0xD8,0xE1}, {0xB4,0x50},
+ {0xD8,0xE0}, {0xD8,0xE5}, {0xD8,0xE2}, {0x8D,0x62},
+ {0xA0,0xA1}, {0xD8,0xE8}, {0x9C,0x40}, {0xDD,0x53},
+ {0xDD,0x56}, {0xDD,0x4E}, {0xDD,0x50}, {0xDD,0x55},
+ {0xDD,0x54}, {0xB7,0x43}, {0xD8,0xDB}, {0xDD,0x52},
+ {0xB7,0x44}, {0x98,0xAD}, {0xDD,0x4D}, {0xDD,0x51},
+ {0x9E,0xEA}, {0xE1,0xA9}, {0xE1,0xB0}, {0xE1,0xA7},
+ {0x8C,0xD4}, {0xE1,0xAE}, {0xE1,0xA5}, {0xE1,0xAD},
+ {0xE1,0xB1}, {0xE1,0xA4}, {0xE1,0xA8}, {0xE1,0xA3},
+ {0xB9,0xF1}, {0x9C,0xEB}, {0xE1,0xA6}, {0xB9,0xF2},
+ {0xE1,0xAC}, {0xE1,0xAB}, {0xE1,0xAA}, {0xFB,0xE0},
+ {0xE1,0xAF}, {0x9F,0x51}, {0xE5,0x65}, {0xE5,0x67},
+ {0xBC,0x6B}, {0xE5,0x68}, {0xE5,0x63}, {0xE5,0x62},
+ {0xE5,0x6C}, {0xE5,0x6A}, {0xBC,0x6A}, {0xE5,0x6D},
+ {0xE5,0x64}, {0xE5,0x69}, {0xE5,0x6B}, {0xE5,0x66},
+ {0x8D,0x65}, {0xE9,0x61}, {0xE9,0x66}, {0xE9,0x60},
+ {0xE9,0x65}, {0x9C,0xF1}, {0xE9,0x5E}, {0xE9,0x68},
+ {0xE9,0x64}, {0xE9,0x69}, {0xE9,0x63}, {0xE9,0x5F},
+ {0xE9,0x67}, {0xE9,0x6A}, {0xE9,0x62}, {0xFC,0x58},
+ {0xEC,0xDA}, {0xC0,0xAF}, {0x8D,0x66}, {0xC0,0xAD},
+ {0xC0,0xAC}, {0xC0,0xAE}, {0xEF,0xC4}, {0x96,0x54},
+ {0xF1,0x72}, {0xF1,0xFD}, {0xF4,0x44}, {0xF4,0x45},
+ {0xC4,0x60}, {0xF5,0xC9}, {0xC4,0xDE}, {0xF5,0xCA},
+ {0xF6,0xDE}, {0xC5,0x72}, {0xC5,0x71}, {0xF6,0xDD},
+ {0xC5,0xC9}, {0xFB,0xE8}, {0xF7,0xD6}, {0xC6,0xCC},
+ {0xA4,0x74}, {0xA6,0x7B}, {0xC9,0xDA}, {0xCA,0xCA},
+ {0xA8,0xB5}, {0xB1,0x5F}, {0xA4,0x75}, {0xA5,0xAA},
+ {0xA5,0xA9}, {0xA5,0xA8}, {0xA7,0xC5}, {0xAE,0x74},
+ {0xDD,0x57}, {0xA4,0x76}, {0xA4,0x77}, {0xA4,0x78},
+ {0xA4,0xDA}, {0x9F,0xCE}, {0xAB,0xD1}, {0xCE,0xAF},
+ {0xB4,0x53}, {0xA4,0x79}, {0xC9,0x5D}, {0xA5,0xAB},
+ {0xA5,0xAC}, {0xC9,0x78}, {0xA6,0x7C}, {0xFB,0xFC},
+ {0xCA,0xCB}, {0x9A,0xE4}, {0xA7,0xC6}, {0xCA,0xCC},
+ {0xA9,0xAE}, {0x9F,0x75}, {0xCC,0x6E}, {0xA9,0xAC},
+ {0xA9,0xAB}, {0xCC,0x6D}, {0xA9,0xA9}, {0xCC,0x6F},
+ {0xA9,0xAA}, {0xA9,0xAD}, {0xAB,0xD2}, {0xAB,0xD4},
+ {0xCE,0xB3}, {0xCE,0xB0}, {0xCE,0xB1}, {0xCE,0xB2},
+ {0xCE,0xB4}, {0xAB,0xD3}, {0xD1,0x74}, {0xD1,0x73},
+ {0xAE,0x76}, {0xAE,0x75}, {0xFB,0xF1}, {0xB1,0x62},
+ {0xD5,0x46}, {0xB1,0x61}, {0xB1,0x63}, {0xB1,0x60},
+ {0xB4,0x55}, {0xD5,0x45}, {0xB4,0x56}, {0xD8,0xF3},
+ {0x8D,0x69}, {0xB4,0x57}, {0xD8,0xF2}, {0xB4,0x54},
+ {0x93,0x4F}, {0xDD,0x5A}, {0xDD,0x5C}, {0xB7,0x45},
+ {0xDD,0x5B}, {0xDD,0x59}, {0xDD,0x58}, {0xE1,0xB4},
+ {0xB9,0xF7}, {0xB9,0xF5}, {0xB9,0xF6}, {0xE1,0xB2},
+ {0xE1,0xB3}, {0xB9,0xF3}, {0xE5,0x71}, {0xE5,0x6F},
+ {0x93,0x4E}, {0xBC,0x6D}, {0xE5,0x70}, {0xBC,0x6E},
+ {0xBC,0x6C}, {0xB9,0xF4}, {0xE9,0x6D}, {0xE9,0x6B},
+ {0xE9,0x6C}, {0xE5,0x6E}, {0xEC,0xDC}, {0xC0,0xB0},
+ {0xEC,0xDB}, {0xEF,0xC5}, {0xEF,0xC6}, {0xE9,0x6E},
+ {0xF1,0xFE}, {0xA4,0x7A}, {0xA5,0xAD}, {0xA6,0x7E},
+ {0xC9,0xDB}, {0xA6,0x7D}, {0xA9,0xAF}, {0xB7,0x46},
+ {0xFB,0xF4}, {0xA4,0xDB}, {0xA5,0xAE}, {0xAB,0xD5},
+ {0xB4,0x58}, {0xC6,0xCE}, {0xC9,0x79}, {0xC9,0x7A},
+ {0xFB,0xC3}, {0xC9,0xDC}, {0x89,0x65}, {0xA7,0xC8},
+ {0xCA,0xD0}, {0xCA,0xCE}, {0xA7,0xC9}, {0xCA,0xCD},
+ {0xCA,0xCF}, {0xCA,0xD1}, {0xA7,0xC7}, {0x8C,0x7A},
+ {0xA9,0xB3}, {0xA9,0xB4}, {0xA9,0xB1}, {0x8C,0x7B},
+ {0xA9,0xB0}, {0xCE,0xB8}, {0xA9,0xB2}, {0xAB,0xD6},
+ {0xCE,0xB7}, {0xCE,0xB9}, {0xCE,0xB6}, {0xCE,0xBA},
+ {0xAB,0xD7}, {0xAE,0x79}, {0xD1,0x75}, {0xD1,0x77},
+ {0xAE,0x77}, {0xD1,0x78}, {0xAE,0x78}, {0xD1,0x76},
+ {0xCE,0xB5}, {0xD5,0x47}, {0xD5,0x4A}, {0xD5,0x4B},
+ {0xD5,0x48}, {0xB1,0x67}, {0xB1,0x66}, {0xB1,0x64},
+ {0xB1,0x65}, {0xD5,0x49}, {0x8D,0x6A}, {0xB1,0x68},
+ {0xB4,0x5A}, {0xB4,0x5B}, {0xB4,0x5C}, {0xDD,0x5D},
+ {0xDD,0x5F}, {0xDD,0x61}, {0xB7,0x48}, {0xB7,0x47},
+ {0xB4,0x59}, {0xDD,0x60}, {0xDD,0x5E}, {0x93,0x53},
+ {0xE1,0xB8}, {0x9D,0xFB}, {0xE1,0xB6}, {0xE1,0xBC},
+ {0xB9,0xF8}, {0xE1,0xBD}, {0xE1,0xBA}, {0xB9,0xF9},
+ {0xE1,0xB7}, {0xE1,0xB5}, {0xE1,0xBB}, {0xBC,0x70},
+ {0xE5,0x73}, {0xE1,0xB9}, {0xBC,0x72}, {0xE5,0x74},
+ {0xBC,0x71}, {0xBC,0x74}, {0xE5,0x75}, {0xBC,0x6F},
+ {0xBC,0x73}, {0xE9,0x73}, {0xE9,0x71}, {0xE9,0x70},
+ {0xE9,0x72}, {0xE9,0x6F}, {0xC3,0x66}, {0xF4,0x46},
+ {0xF4,0x47}, {0xF5,0xCB}, {0xF6,0xDF}, {0xC6,0x55},
+ {0xFB,0xFD}, {0xA9,0xB5}, {0xA7,0xCA}, {0x90,0x59},
+ {0xFC,0x40}, {0xAB,0xD8}, {0xFC,0x41}, {0xFC,0x43},
+ {0xA4,0x7B}, {0xA4,0xDC}, {0xA5,0xAF}, {0xC9,0xDD},
+ {0xA7,0xCB}, {0xCA,0xD2}, {0xCE,0xBB}, {0xAB,0xD9},
+ {0xB9,0xFA}, {0xA4,0x7C}, {0x93,0x61}, {0xFC,0x46},
+ {0x93,0x62}, {0xA6,0xA1}, {0xB7,0x49}, {0xA4,0x7D},
+ {0xA4,0xDD}, {0xA4,0xDE}, {0xA5,0xB1}, {0xA5,0xB0},
+ {0xC9,0xDE}, {0xA6,0xA2}, {0xCA,0xD3}, {0xA7,0xCC},
+ {0xCC,0x71}, {0xCC,0x72}, {0xCC,0x73}, {0x8D,0x6B},
+ {0xA9,0xB6}, {0xA9,0xB7}, {0xCC,0x70}, {0xA9,0xB8},
+ {0xAB,0xDA}, {0xCE,0xBC}, {0xD1,0x7A}, {0xAE,0x7A},
+ {0xD1,0x79}, {0xB1,0x69}, {0xD5,0x4C}, {0xB1,0x6A},
+ {0xD5,0x4D}, {0xFC,0x4C}, {0xB4,0x5D}, {0xDD,0x62},
+ {0xE1,0xBF}, {0xE1,0xBE}, {0xB9,0xFB}, {0xBC,0x75},
+ {0xE5,0x76}, {0xBE,0xCA}, {0xE9,0x74}, {0xC0,0xB1},
+ {0x95,0xB8}, {0xC5,0x73}, {0xF7,0xD8}, {0xC6,0xD0},
+ {0x8B,0xCA}, {0xCC,0x74}, {0xCE,0xBD}, {0xB1,0x6B},
+ {0xD8,0xF4}, {0xB7,0x4A}, {0x98,0x7A}, {0xC2,0x55},
+ {0xC6,0xD1}, {0xA7,0xCE}, {0xFC,0x51}, {0xA7,0xCD},
+ {0xAB,0xDB}, {0xD1,0x7B}, {0xB1,0x6D}, {0xB3,0x43},
+ {0xB1,0x6E}, {0xB1,0x6C}, {0xB4,0x5E}, {0xE1,0xC0},
+ {0xB9,0xFC}, {0xBC,0x76}, {0xFC,0x54}, {0xC9,0x4C},
+ {0xC9,0xDF}, {0xCA,0xD5}, {0xA7,0xCF}, {0xCA,0xD4},
+ {0xA7,0xD0}, {0xFA,0xAF}, {0xA9,0xBC}, {0xCC,0x77},
+ {0xCC,0x76}, {0xA9,0xBB}, {0xA9,0xB9}, {0xA9,0xBA},
+ {0xCC,0x75}, {0x8D,0x6C}, {0xAB,0xDD}, {0xCE,0xBE},
+ {0xAB,0xE0}, {0xAB,0xDC}, {0xAB,0xE2}, {0xAB,0xDE},
+ {0xAB,0xDF}, {0xAB,0xE1}, {0xAE,0x7D}, {0xAE,0x7C},
+ {0xAE,0x7B}, {0xD5,0x4F}, {0xB1,0x6F}, {0xB1,0x72},
+ {0xB1,0x70}, {0xD5,0x4E}, {0xB1,0x75}, {0xB1,0x71},
+ {0xD5,0x50}, {0xB1,0x74}, {0xB1,0x73}, {0xFA,0x61},
+ {0xD8,0xF6}, {0xD8,0xF5}, {0xFC,0x57}, {0xB4,0x61},
+ {0xB4,0x5F}, {0xB4,0x60}, {0xD8,0xF7}, {0xB7,0x4B},
+ {0xDD,0x64}, {0xB7,0x4C}, {0xDD,0x63}, {0x9B,0x70},
+ {0xE5,0x77}, {0xBC,0x78}, {0xE1,0xC1}, {0xBC,0x77},
+ {0xB9,0xFD}, {0xA0,0x51}, {0xEC,0xDE}, {0xE9,0x75},
+ {0xC0,0xB2}, {0xEC,0xDD}, {0xF2,0x40}, {0xF4,0x48},
+ {0xF4,0x49}, {0x8C,0x7C}, {0xA4,0xDF}, {0x8B,0xCB},
+ {0xA5,0xB2}, {0xC9,0x7B}, {0xA7,0xD2}, {0xA7,0xD4},
+ {0xC9,0xE2}, {0xCA,0xD8}, {0xCA,0xD7}, {0xCA,0xD6},
+ {0xC9,0xE1}, {0xC9,0xE0}, {0xA6,0xA4}, {0xA7,0xD3},
+ {0xA7,0xD1}, {0xA6,0xA3}, {0x93,0x6E}, {0xA9,0xBD},
+ {0xCC,0x78}, {0xFC,0xD5}, {0xA9,0xBE}, {0xCA,0xDD},
+ {0xCA,0xDF}, {0xCA,0xDE}, {0xCC,0x79}, {0xCA,0xDA},
+ {0xA7,0xD8}, {0xA7,0xD6}, {0xCA,0xD9}, {0xCA,0xDB},
+ {0xCA,0xE1}, {0xA7,0xD5}, {0xCA,0xDC}, {0xCA,0xE5},
+ {0xA9,0xC0}, {0xCA,0xE2}, {0xA7,0xD7}, {0xCA,0xE0},
+ {0xCA,0xE3}, {0xA9,0xBF}, {0xA9,0xC1}, {0xCA,0xE4},
+ {0xCC,0xAF}, {0xCC,0xA2}, {0xCC,0x7E}, {0xCC,0xAE},
+ {0xCC,0xA9}, {0xAB,0xE7}, {0xA9,0xC2}, {0xCC,0xAA},
+ {0xCC,0xAD}, {0xAB,0xE3}, {0xCC,0xAC}, {0xA9,0xC3},
+ {0xA9,0xC8}, {0xA9,0xC6}, {0xCC,0xA3}, {0xCC,0x7C},
+ {0xCC,0xA5}, {0xA9,0xCD}, {0xCC,0xB0}, {0xAB,0xE4},
+ {0xCC,0xA6}, {0xAB,0xE5}, {0xA9,0xC9}, {0xCC,0xA8},
+ {0xFC,0xA9}, {0xCE,0xCD}, {0xAB,0xE6}, {0xCC,0x7B},
+ {0xA9,0xCA}, {0xAB,0xE8}, {0xA9,0xCB}, {0xA9,0xC7},
+ {0xA9,0xCC}, {0xCC,0xA7}, {0xCC,0x7A}, {0xCC,0xAB},
+ {0xA9,0xC4}, {0xFC,0x61}, {0xCC,0x7D}, {0xCC,0xA4},
+ {0xCC,0xA1}, {0xA9,0xC5}, {0xCE,0xBF}, {0xCE,0xC0},
+ {0x89,0x66}, {0xCE,0xCA}, {0xD1,0xA1}, {0xCE,0xCB},
+ {0xAB,0xEE}, {0xCE,0xCE}, {0xCE,0xC4}, {0xAB,0xED},
+ {0xCE,0xC6}, {0xCE,0xC7}, {0xFA,0xCB}, {0xCE,0xC9},
+ {0xAB,0xE9}, {0xAE,0xA3}, {0xF9,0xDA}, {0xCE,0xC5},
+ {0xCE,0xC1}, {0xAE,0xA4}, {0xCE,0xCF}, {0xAE,0x7E},
+ {0xD1,0x7D}, {0xCE,0xC8}, {0xD1,0x7C}, {0xCE,0xC3},
+ {0xCE,0xCC}, {0xAB,0xEC}, {0xAE,0xA1}, {0xAB,0xF2},
+ {0xAE,0xA2}, {0xCE,0xD0}, {0xD1,0x7E}, {0xAB,0xEB},
+ {0xAE,0xA6}, {0xAB,0xF1}, {0xAB,0xF0}, {0xAB,0xEF},
+ {0xAE,0xA5}, {0xCE,0xD1}, {0xAE,0xA7}, {0xAB,0xEA},
+ {0xCE,0xC2}, {0x93,0x7A}, {0xA0,0xE0}, {0x93,0x6B},
+ {0xB1,0x76}, {0xD1,0xA4}, {0xD1,0xA6}, {0xD1,0xA8},
+ {0xAE,0xA8}, {0xAE,0xAE}, {0xD5,0x53}, {0xD1,0xAC},
+ {0xD1,0xA3}, {0xB1,0x78}, {0xD5,0x51}, {0xAE,0xAD},
+ {0xAE,0xAB}, {0xD1,0xAE}, {0xD5,0x52}, {0xD1,0xA5},
+ {0xAE,0xAC}, {0xD1,0xA9}, {0xAE,0xAF}, {0xD1,0xAB},
+ {0xAE,0xAA}, {0xD1,0xAA}, {0xD1,0xAD}, {0xD1,0xA7},
+ {0xFC,0x6B}, {0xAE,0xA9}, {0xB1,0x79}, {0xD1,0xA2},
+ {0xB1,0x77}, {0xA0,0xDC}, {0x94,0x68}, {0xB1,0x7A},
+ {0xD5,0x55}, {0xD5,0x5E}, {0xB4,0x64}, {0xFC,0x6D},
+ {0xB1,0x7C}, {0xB1,0xA3}, {0xB4,0x65}, {0xD5,0x60},
+ {0xB1,0xAA}, {0xD8,0xF9}, {0xD5,0x56}, {0xB1,0xA2},
+ {0xB1,0xA5}, {0xB1,0x7E}, {0xD5,0x54}, {0xD5,0x62},
+ {0xD5,0x65}, {0xD9,0x49}, {0xD5,0x63}, {0xD8,0xFD},
+ {0xB1,0xA1}, {0xB1,0xA8}, {0xB1,0xAC}, {0xD5,0x5D},
+ {0xD8,0xF8}, {0xD5,0x61}, {0xB1,0x7B}, {0xD8,0xFA},
+ {0xD5,0x64}, {0xD8,0xFC}, {0xD5,0x59}, {0xB4,0x62},
+ {0xD5,0x57}, {0xD5,0x58}, {0xB1,0xA7}, {0x8D,0x71},
+ {0xB1,0xA6}, {0xD5,0x5B}, {0xB1,0xAB}, {0xD5,0x5F},
+ {0xB1,0xA4}, {0xD5,0x5C}, {0xFD,0x64}, {0xB1,0xA9},
+ {0xB4,0x66}, {0xB4,0x63}, {0xD8,0xFB}, {0x99,0xBA},
+ {0xD5,0x5A}, {0xB1,0x7D}, {0x9A,0xD0}, {0x9A,0x61},
+ {0xA0,0xE5}, {0xB4,0x6B}, {0xB4,0x6F}, {0xD9,0x40},
+ {0xB7,0x51}, {0xB4,0x6D}, {0xD9,0x44}, {0xB4,0x71},
+ {0xDD,0x65}, {0xD9,0x46}, {0xB7,0x53}, {0xB4,0x69},
+ {0xB4,0x6C}, {0xD9,0x47}, {0xA0,0x5B}, {0xD9,0x48},
+ {0xD9,0x4E}, {0xB4,0x73}, {0xB7,0x54}, {0xD9,0x4A},
+ {0xD9,0x4F}, {0xD9,0x43}, {0xB7,0x5E}, {0x96,0xAC},
+ {0xB7,0x55}, {0xB4,0x72}, {0xD9,0x41}, {0xD9,0x50},
+ {0x97,0x40}, {0xB7,0x5D}, {0xB4,0x70}, {0xB7,0x4E},
+ {0xD9,0x4D}, {0xB4,0x74}, {0xD9,0x45}, {0xD8,0xFE},
+ {0xB4,0x6A}, {0xD9,0x42}, {0xD9,0x4B}, {0x9E,0xF1},
+ {0xB7,0x4D}, {0xB7,0x52}, {0xB4,0x67}, {0xD9,0x4C},
+ {0xB7,0x50}, {0x8C,0x4D}, {0xB4,0x68}, {0xB7,0x5C},
+ {0xE1,0xC3}, {0xDD,0x70}, {0xDD,0x68}, {0xE1,0xC2},
+ {0xDD,0x6C}, {0xDD,0x6E}, {0x9F,0x7E}, {0xDD,0x6B},
+ {0xB7,0x5B}, {0xDD,0x6A}, {0xB7,0x5F}, {0xE1,0xD2},
+ {0x8D,0x72}, {0xB7,0x5A}, {0xBA,0x40}, {0xDD,0x71},
+ {0xE1,0xC4}, {0xFC,0x76}, {0xB7,0x58}, {0xDD,0x69},
+ {0xDD,0x6D}, {0xB9,0xFE}, {0xB7,0x4F}, {0xDD,0x66},
+ {0xDD,0x67}, {0xBA,0x41}, {0xB7,0x57}, {0xB7,0x59},
+ {0xB7,0x56}, {0xDD,0x6F}, {0x96,0xA9}, {0xE1,0xC8},
+ {0xE1,0xC9}, {0xE1,0xCE}, {0xBC,0x7D}, {0xE1,0xD5},
+ {0xBA,0x47}, {0xA0,0x6E}, {0xBA,0x46}, {0xE1,0xD0},
+ {0xFC,0xAA}, {0xBC,0x7C}, {0xE1,0xC5}, {0xBA,0x45},
+ {0xFB,0xCD}, {0xE1,0xD4}, {0xBA,0x43}, {0xBA,0x44},
+ {0xFC,0x74}, {0xE1,0xD1}, {0xE5,0xAA}, {0xBC,0x7A},
+ {0xB4,0x6E}, {0xE1,0xD3}, {0xBC,0xA3}, {0xE1,0xCB},
+ {0xBC,0x7B}, {0xA0,0x74}, {0xBC,0xA2}, {0xE1,0xC6},
+ {0xE1,0xCA}, {0xE1,0xC7}, {0xE1,0xCD}, {0xBA,0x48},
+ {0xBC,0x79}, {0xBA,0x42}, {0xE5,0x7A}, {0xE1,0xCF},
+ {0xBC,0xA1}, {0xA0,0x71}, {0xBC,0xA4}, {0xE1,0xCC},
+ {0xFC,0x79}, {0xBC,0x7E}, {0xE5,0x79}, {0xFC,0x7C},
+ {0xE5,0x7E}, {0xBE,0xCE}, {0xE5,0x78}, {0xE9,0xA3},
+ {0xE5,0xA9}, {0xBC,0xA8}, {0xBC,0xA6}, {0xBE,0xCC},
+ {0xE5,0xA6}, {0xE5,0xA2}, {0xBC,0xAC}, {0x9C,0x50},
+ {0xE9,0x78}, {0x93,0x79}, {0x93,0x78}, {0xBC,0xAA},
+ {0xE5,0xA1}, {0xA0,0xDD}, {0xE9,0x76}, {0xE5,0xA5},
+ {0xE5,0xA8}, {0xE5,0x7D}, {0xBC,0xAB}, {0xBC,0xA5},
+ {0xE9,0x77}, {0xBE,0xCD}, {0xE5,0xA7}, {0xBC,0xA7},
+ {0xBC,0xA9}, {0xE5,0xA4}, {0xBC,0xAD}, {0xE5,0xA3},
+ {0xE5,0x7C}, {0xE5,0x7B}, {0xBE,0xCB}, {0xE5,0xAB},
+ {0xE9,0x7A}, {0xEC,0xE0}, {0xBE,0xD0}, {0x8D,0x75},
+ {0xE9,0xA2}, {0x8D,0x76}, {0xE9,0x7E}, {0xEC,0xE1},
+ {0xBE,0xD1}, {0xE9,0xA1}, {0x93,0x74}, {0xE9,0x7C},
+ {0xC0,0xB4}, {0xEC,0xDF}, {0xE9,0x79}, {0xE9,0x7B},
+ {0xC0,0xB5}, {0xBE,0xD3}, {0xC0,0xB3}, {0xBE,0xD2},
+ {0xC0,0xB7}, {0xE9,0x7D}, {0xBE,0xCF}, {0x8D,0x77},
+ {0xFC,0xA5}, {0xFC,0xA2}, {0xEF,0xCF}, {0xEF,0xC7},
+ {0x90,0xC3}, {0xEC,0xE7}, {0xEF,0xC8}, {0xEC,0xE3},
+ {0xA0,0x79}, {0xC2,0x56}, {0xEC,0xE5}, {0xEC,0xE4},
+ {0xC0,0xB6}, {0xEC,0xE2}, {0xEC,0xE6}, {0xEF,0xD0},
+ {0xEF,0xCC}, {0xEF,0xCE}, {0xEF,0xC9}, {0xEF,0xCA},
+ {0xEF,0xCD}, {0xEF,0xCB}, {0xC3,0x67}, {0xC3,0x6A},
+ {0xC3,0x69}, {0xC3,0x68}, {0xC4,0x61}, {0xF4,0x4A},
+ {0xC4,0x62}, {0xF2,0x41}, {0xC4,0xDF}, {0xF5,0xCC},
+ {0xC4,0xE0}, {0xC5,0x74}, {0xC5,0xCA}, {0xF7,0xD9},
+ {0xF7,0xDA}, {0xF7,0xDB}, {0xF9,0xBA}, {0xA4,0xE0},
+ {0xC9,0x7C}, {0xA5,0xB3}, {0xA6,0xA6}, {0xA6,0xA7},
+ {0xA6,0xA5}, {0xA6,0xA8}, {0xA7,0xDA}, {0xA7,0xD9},
+ {0xCC,0xB1}, {0xA9,0xCF}, {0xA9,0xCE}, {0xD1,0xAF},
+ {0xB1,0xAD}, {0xB1,0xAE}, {0xB4,0x75}, {0xDD,0x72},
+ {0xB7,0x60}, {0xB7,0x61}, {0xDD,0x74}, {0xDD,0x76},
+ {0xDD,0x75}, {0xE1,0xD7}, {0xE1,0xD6}, {0xBA,0x49},
+ {0xE1,0xD8}, {0x8D,0x79}, {0xE5,0xAC}, {0xBC,0xAE},
+ {0xBE,0xD4}, {0xC0,0xB8}, {0xC2,0x57}, {0xC0,0xB9},
+ {0xA4,0xE1}, {0x8B,0xFC}, {0xA0,0x76}, {0xCA,0xE6},
+ {0xCC,0xB2}, {0xA9,0xD1}, {0xA9,0xD0}, {0xA9,0xD2},
+ {0xAB,0xF3}, {0xCE,0xD2}, {0xCE,0xD3}, {0xD1,0xB0},
+ {0xAE,0xB0}, {0xB1,0xAF}, {0xB4,0x76}, {0xD9,0x51},
+ {0xA4,0xE2}, {0x8B,0xCD}, {0xA4,0x7E}, {0xA4,0xE3},
+ {0xC9,0x7D}, {0xA5,0xB7}, {0xA5,0xB6}, {0xA5,0xB4},
+ {0xA5,0xB5}, {0xA6,0xAB}, {0xC9,0xE9}, {0xC9,0xEB},
+ {0xA6,0xAA}, {0xC9,0xE3}, {0xC9,0xE4}, {0xC9,0xEA},
+ {0xC9,0xE6}, {0xC9,0xE8}, {0xA6,0xA9}, {0xC9,0xE5},
+ {0xC9,0xEC}, {0xC9,0xE7}, {0x9F,0x5A}, {0xA7,0xE1},
+ {0xA7,0xEA}, {0xA7,0xE8}, {0xCA,0xF0}, {0xCA,0xED},
+ {0xCA,0xF5}, {0xA7,0xE6}, {0xCA,0xF6}, {0xA7,0xDF},
+ {0xCA,0xF3}, {0xA7,0xE5}, {0xCA,0xEF}, {0xCA,0xEE},
+ {0xA7,0xE3}, {0xCA,0xF4}, {0xA7,0xE4}, {0xA9,0xD3},
+ {0xA7,0xDE}, {0xCA,0xF1}, {0x9F,0xF4}, {0xCA,0xE7},
+ {0xA7,0xDB}, {0x9F,0xBA}, {0xA7,0xEE}, {0xCA,0xEC},
+ {0xCA,0xF2}, {0xA7,0xE0}, {0xA7,0xE2}, {0xCA,0xE8},
+ {0xCA,0xE9}, {0xCA,0xEA}, {0x8D,0x7A}, {0xA7,0xED},
+ {0xA7,0xE7}, {0xA7,0xEC}, {0xCA,0xEB}, {0xA7,0xEB},
+ {0xA7,0xDD}, {0xA7,0xDC}, {0xA7,0xE9}, {0x9E,0x45},
+ {0x93,0xB0}, {0xA0,0x75}, {0xA9,0xE1}, {0xCC,0xBE},
+ {0xCC,0xB7}, {0xA9,0xDC}, {0xA9,0xEF}, {0xCC,0xB3},
+ {0xCC,0xBA}, {0xCC,0xBC}, {0xCC,0xBF}, {0xA9,0xEA},
+ {0xCC,0xBB}, {0xCC,0xB4}, {0xA9,0xE8}, {0xCC,0xB8},
+ {0xCC,0xC0}, {0xA9,0xD9}, {0xCC,0xBD}, {0xA9,0xE3},
+ {0xA9,0xE2}, {0xCC,0xB6}, {0xA9,0xD7}, {0xA9,0xD8},
+ {0x9B,0x46}, {0xA9,0xD6}, {0xFC,0xAE}, {0xA9,0xEE},
+ {0xA9,0xE6}, {0xA9,0xE0}, {0xA9,0xD4}, {0xCC,0xB9},
+ {0xA9,0xDF}, {0xA9,0xD5}, {0xA9,0xE7}, {0xA9,0xF0},
+ {0xCE,0xD4}, {0xA9,0xE4}, {0xCC,0xB5}, {0xA9,0xDA},
+ {0xA9,0xDD}, {0xA9,0xDE}, {0xFC,0xB0}, {0xA9,0xEC},
+ {0xA9,0xED}, {0xA9,0xEB}, {0xA9,0xE5}, {0xA9,0xE9},
+ {0xA9,0xDB}, {0xAB,0xF4}, {0xFA,0x51}, {0x8D,0x7B},
+ {0xCE,0xDA}, {0xAC,0x41}, {0xAB,0xF8}, {0xAB,0xFA},
+ {0xAC,0x40}, {0xCE,0xE6}, {0xAB,0xFD}, {0xD1,0xB1},
+ {0xAE,0xB1}, {0xAC,0x43}, {0xCE,0xD7}, {0xCE,0xDF},
+ {0xAB,0xFE}, {0xCE,0xDE}, {0xCE,0xDB}, {0xCE,0xE3},
+ {0xCE,0xE5}, {0xAB,0xF7}, {0xAB,0xFB}, {0xAC,0x42},
+ {0xAE,0xB3}, {0xCE,0xE0}, {0xAB,0xF9}, {0xAC,0x45},
+ {0xCE,0xD9}, {0xAB,0xFC}, {0xAE,0xB2}, {0xAB,0xF6},
+ {0xCE,0xD6}, {0xCE,0xDD}, {0xCE,0xD5}, {0xCE,0xD8},
+ {0xCE,0xDC}, {0xD1,0xB2}, {0xAC,0x44}, {0xCE,0xE1},
+ {0xCE,0xE2}, {0xCE,0xE4}, {0xAB,0xF5}, {0x8D,0x7C},
+ {0xAE,0xC1}, {0xD1,0xBE}, {0xAE,0xBF}, {0xAE,0xC0},
+ {0xD1,0xB4}, {0xD1,0xC4}, {0x9E,0xD6}, {0xAE,0xB6},
+ {0x93,0xAC}, {0xD5,0x66}, {0xD1,0xC6}, {0xD1,0xC0},
+ {0x9F,0x5B}, {0xD1,0xB7}, {0x93,0xA9}, {0xD1,0xC9},
+ {0xD1,0xBA}, {0xAE,0xBC}, {0xD5,0x7D}, {0xD1,0xBD},
+ {0xAE,0xBE}, {0xAE,0xB5}, {0xD1,0xCB}, {0xD1,0xBF},
+ {0xAE,0xB8}, {0xD1,0xB8}, {0xD1,0xB5}, {0xD1,0xB6},
+ {0xAE,0xB9}, {0xD1,0xC5}, {0xD1,0xCC}, {0xAE,0xBB},
+ {0xD1,0xBC}, {0xD1,0xBB}, {0xAE,0xC3}, {0xAE,0xC2},
+ {0xAE,0xB4}, {0xAE,0xBA}, {0xAE,0xBD}, {0xD1,0xC8},
+ {0xD1,0xC2}, {0xAE,0xB7}, {0xD1,0xB3}, {0xD1,0xCA},
+ {0xD1,0xC1}, {0xD1,0xC3}, {0xD1,0xC7}, {0xA0,0x7C},
+ {0xD5,0x67}, {0xB1,0xB7}, {0xB1,0xCB}, {0xB1,0xCA},
+ {0xB1,0xBF}, {0xFC,0xB2}, {0xD5,0x79}, {0xD5,0x75},
+ {0xD5,0x72}, {0xD5,0xA6}, {0xB1,0xBA}, {0xB1,0xB2},
+ {0xD5,0x77}, {0xB4,0xA8}, {0xB1,0xB6}, {0xD5,0xA1},
+ {0x8A,0xC1}, {0xB1,0xCC}, {0xB1,0xC9}, {0xD5,0x7B},
+ {0xD5,0x6A}, {0x9F,0xB4}, {0xB1,0xC8}, {0xD5,0xA3},
+ {0xD5,0x69}, {0xB1,0xBD}, {0xB1,0xC1}, {0xD5,0xA2},
+ {0xD5,0x73}, {0xB1,0xC2}, {0xB1,0xBC}, {0xD5,0x68},
+ {0xFC,0xAC}, {0xB4,0x78}, {0xD5,0xA5}, {0xD5,0x71},
+ {0xB1,0xC7}, {0xD5,0x74}, {0xD5,0xA4}, {0xB1,0xC6},
+ {0xD9,0x52}, {0xB1,0xB3}, {0xD5,0x6F}, {0xB1,0xB8},
+ {0xB1,0xC3}, {0xB1,0xBE}, {0xD5,0x78}, {0xD5,0x6E},
+ {0xD5,0x6C}, {0xD5,0x7E}, {0xB1,0xB0}, {0xB1,0xC4},
+ {0xB1,0xB4}, {0xB4,0x77}, {0xD5,0x7C}, {0xB1,0xB5},
+ {0xB1,0xB1}, {0xB1,0xC0}, {0xB1,0xBB}, {0xB1,0xB9},
+ {0xD5,0x70}, {0xB1,0xC5}, {0xD5,0x6D}, {0xD5,0x7A},
+ {0xD5,0x76}, {0xD9,0x54}, {0xD9,0x53}, {0x9E,0x4C},
+ {0xD5,0x6B}, {0xD9,0x64}, {0xB4,0x7A}, {0x8F,0xC5},
+ {0xD9,0x6A}, {0xD9,0x59}, {0xD9,0x67}, {0xDD,0x77},
+ {0xB4,0x7D}, {0xD9,0x6B}, {0xD9,0x6E}, {0xB4,0x7C},
+ {0xD9,0x5C}, {0xD9,0x6D}, {0xD9,0x6C}, {0xB4,0x7E},
+ {0xD9,0x55}, {0xB4,0x79}, {0xB4,0xA3}, {0x93,0xAD},
+ {0xB4,0xA1}, {0xD9,0x69}, {0xD9,0x5F}, {0xB4,0xA5},
+ {0xD9,0x70}, {0xD9,0x68}, {0xD9,0x71}, {0xB4,0xAD},
+ {0xB4,0xAB}, {0xD9,0x66}, {0xD9,0x65}, {0x9D,0xC3},
+ {0xD9,0x63}, {0xD9,0x5D}, {0xB4,0xA4}, {0x8D,0xA2},
+ {0xB4,0xA2}, {0xD1,0xB9}, {0xD9,0x56}, {0x9D,0x4A},
+ {0xDD,0xB7}, {0xD9,0x57}, {0xB4,0x7B}, {0xB4,0xAA},
+ {0xDD,0x79}, {0xB4,0xA6}, {0xB4,0xA7}, {0xD9,0x58},
+ {0xD9,0x6F}, {0xDD,0x78}, {0xD9,0x60}, {0xD9,0x5B},
+ {0xB4,0xA9}, {0xD9,0x61}, {0xD9,0x5E}, {0xFC,0xB6},
+ {0xB4,0xAE}, {0x8D,0xA3}, {0x9E,0x4B}, {0x9E,0x4D},
+ {0xB7,0x70}, {0x8D,0xA4}, {0xDD,0x7C}, {0xDD,0xB1},
+ {0xDD,0xB6}, {0xDD,0xAA}, {0xB7,0x6C}, {0xDD,0xBB},
+ {0xB7,0x69}, {0xDD,0x7A}, {0xDD,0x7B}, {0xB7,0x62},
+ {0xB7,0x6B}, {0xDD,0xA4}, {0xB7,0x6E}, {0xB7,0x6F},
+ {0xDD,0xA5}, {0xDD,0xB2}, {0xDD,0xB8}, {0xB7,0x6A},
+ {0xB7,0x64}, {0xDD,0xA3}, {0xDD,0x7D}, {0xDD,0xBA},
+ {0xDD,0xA8}, {0xDD,0xA9}, {0xDD,0x7E}, {0xDD,0xB4},
+ {0xDD,0xAB}, {0xDD,0xB5}, {0xDD,0xAD}, {0xB7,0x65},
+ {0xE1,0xD9}, {0xB7,0x68}, {0xB7,0x66}, {0xDD,0xB9},
+ {0xDD,0xB0}, {0xDD,0xAC}, {0x8A,0xFD}, {0xDD,0xA1},
+ {0xBA,0x53}, {0xDD,0xAF}, {0xB7,0x6D}, {0xDD,0xA7},
+ {0xFC,0xB5}, {0xDD,0xA6}, {0xFC,0xC3}, {0x93,0xB2},
+ {0xB7,0x67}, {0xB7,0x63}, {0xE1,0xEE}, {0xDD,0xB3},
+ {0xDD,0xAE}, {0xDD,0xA2}, {0xE1,0xE9}, {0xE1,0xDA},
+ {0xE1,0xE5}, {0xE1,0xEC}, {0xBA,0x51}, {0xB4,0xAC},
+ {0xE1,0xEA}, {0xBA,0x4C}, {0xBA,0x4B}, {0xE1,0xF1},
+ {0x8D,0xA5}, {0xE1,0xDB}, {0xE1,0xE8}, {0xE1,0xDC},
+ {0xE1,0xE7}, {0xBA,0x4F}, {0xE1,0xEB}, {0xD9,0x62},
+ {0xE1,0xF2}, {0xE1,0xE3}, {0xBA,0x52}, {0xE5,0xBA},
+ {0xBC,0xAF}, {0xE1,0xF0}, {0xE1,0xEF}, {0xBA,0x54},
+ {0xE5,0xAD}, {0xBC,0xB0}, {0xE5,0xAE}, {0x93,0xA1},
+ {0xE1,0xDF}, {0xE1,0xE0}, {0xE1,0xDD}, {0xE1,0xE2},
+ {0xE1,0xDE}, {0xE1,0xF3}, {0xBA,0x4E}, {0xBC,0xB1},
+ {0xBA,0x50}, {0xBA,0x55}, {0x8A,0xC6}, {0xE1,0xE1},
+ {0xE1,0xED}, {0xE1,0xE6}, {0xE5,0xB1}, {0xBA,0x4A},
+ {0xBC,0xB4}, {0xE9,0xAA}, {0xE5,0xB6}, {0xE5,0xB5},
+ {0xE5,0xB7}, {0x8A,0x5B}, {0xE5,0xB4}, {0xBC,0xB5},
+ {0x89,0x4D}, {0xBC,0xBB}, {0xBC,0xB8}, {0xBC,0xB9},
+ {0xE5,0xAF}, {0xE5,0xB2}, {0xE5,0xBC}, {0xBC,0xC1},
+ {0xBC,0xBF}, {0xE5,0xB3}, {0xD9,0x5A}, {0xBC,0xB2},
+ {0xE5,0xB9}, {0xE5,0xB0}, {0xBC,0xC2}, {0xE5,0xB8},
+ {0xBA,0x4D}, {0xBC,0xB7}, {0xE1,0xE4}, {0xBC,0xBA},
+ {0xBC,0xBE}, {0xBC,0xC0}, {0xBC,0xBD}, {0xBC,0xBC},
+ {0xFE,0xD4}, {0xBC,0xB6}, {0xE5,0xBB}, {0xBC,0xB3},
+ {0xBC,0xC3}, {0x8A,0x78}, {0x93,0xAB}, {0xBE,0xD8},
+ {0xBE,0xD9}, {0xE9,0xA9}, {0xBE,0xE2}, {0xBE,0xDF},
+ {0x8D,0xA7}, {0xBE,0xD6}, {0xBE,0xDD}, {0xE9,0xAB},
+ {0xBE,0xDB}, {0xBE,0xD5}, {0xBE,0xDC}, {0xE9,0xA8},
+ {0xC0,0xBB}, {0xBE,0xD7}, {0xBE,0xDE}, {0xC0,0xBA},
+ {0xE9,0xA7}, {0xE9,0xA6}, {0xBE,0xE0}, {0x9F,0x45},
+ {0xBE,0xE1}, {0xE9,0xA5}, {0xE9,0xA4}, {0xC0,0xBC},
+ {0xE9,0xAE}, {0xBE,0xDA}, {0xE9,0xAC}, {0x8A,0x56},
+ {0xC0,0xBD}, {0xFC,0xBF}, {0xC0,0xC2}, {0xEC,0xEA},
+ {0xEC,0xEC}, {0xFC,0xC0}, {0xC0,0xBF}, {0x8E,0xE6},
+ {0xEC,0xED}, {0xEC,0xE9}, {0x8A,0xA4}, {0xEC,0xEB},
+ {0xC0,0xC0}, {0xC0,0xC3}, {0xEC,0xE8}, {0xC0,0xBE},
+ {0xC0,0xC1}, {0xC2,0x59}, {0xE9,0xAD}, {0xC2,0x58},
+ {0xC2,0x5E}, {0xEF,0xD4}, {0xC2,0x5C}, {0xC2,0x5D},
+ {0xEF,0xD7}, {0xEF,0xD3}, {0xC2,0x5A}, {0xEF,0xD1},
+ {0xC3,0x6B}, {0xEF,0xD5}, {0xEF,0xD6}, {0xEF,0xD2},
+ {0xC2,0x5B}, {0xF2,0x42}, {0xF2,0x45}, {0x89,0x43},
+ {0xF2,0x46}, {0xF2,0x44}, {0xF2,0x47}, {0xC3,0x6C},
+ {0xF2,0x43}, {0x93,0xF3}, {0xF4,0x4E}, {0xC4,0x64},
+ {0xF4,0x4D}, {0xF4,0x4C}, {0xF4,0x4B}, {0xC4,0x63},
+ {0xC4,0x65}, {0xF5,0xCD}, {0xC4,0xE2}, {0xC4,0xE1},
+ {0xFC,0xAB}, {0x9E,0xA2}, {0xF6,0xE1}, {0xF6,0xE0},
+ {0xF6,0xE3}, {0xC5,0xCB}, {0xC5,0x75}, {0xF7,0xDD},
+ {0xF6,0xE2}, {0xF7,0xDC}, {0xC5,0xCD}, {0xC5,0xCC},
+ {0xC5,0xF3}, {0xF8,0xA9}, {0xF8,0xEF}, {0xA4,0xE4},
+ {0x9D,0xC7}, {0xD9,0x72}, {0xE9,0xAF}, {0xC6,0xD2},
+ {0x8B,0xCE}, {0xA6,0xAC}, {0xCA,0xF7}, {0xA7,0xF1},
+ {0xA7,0xEF}, {0xA7,0xF0}, {0xCC,0xC1}, {0xA9,0xF1},
+ {0xAC,0x46}, {0xCE,0xE7}, {0xCE,0xE8}, {0xAC,0x47},
+ {0xD1,0xCE}, {0xAE,0xC4}, {0xAE,0xC5}, {0xD1,0xCD},
+ {0xFC,0xC5}, {0xB1,0xD3}, {0xB1,0xCF}, {0xD5,0xA7},
+ {0xB1,0xD6}, {0xB1,0xD5}, {0xB1,0xCE}, {0xB1,0xD1},
+ {0xB1,0xD4}, {0xB1,0xD0}, {0xD9,0x76}, {0xB1,0xCD},
+ {0xB4,0xAF}, {0xFC,0xCB}, {0xB4,0xB1}, {0xB4,0xB2},
+ {0xD9,0x75}, {0xD9,0x78}, {0xB4,0xB0}, {0xD9,0x73},
+ {0xD9,0x77}, {0xD9,0x74}, {0x93,0xB3}, {0xB7,0x71},
+ {0xFC,0xCA}, {0xDD,0xBC}, {0xBA,0x56}, {0xE1,0xF4},
+ {0xBE,0xE3}, {0xBC,0xC4}, {0xE5,0xBD}, {0xBC,0xC5},
+ {0xBC,0xC6}, {0xE5,0xBF}, {0xE5,0xBE}, {0xE5,0xC0},
+ {0xE9,0xB1}, {0xE9,0xB0}, {0xEC,0xEF}, {0xEC,0xEE},
+ {0xC0,0xC4}, {0xC0,0xC5}, {0xF2,0x48}, {0xFC,0xC9},
+ {0x8D,0xAC}, {0xA4,0xE5}, {0xFB,0xC6}, {0x89,0x67},
+ {0x8C,0x7E}, {0xD9,0x79}, {0xB4,0xB4}, {0xB4,0xB3},
+ {0xDD,0xBD}, {0xEF,0xD8}, {0xC4,0xE3}, {0xF7,0xDE},
+ {0xA4,0xE6}, {0xAE,0xC6}, {0xB1,0xD8}, {0xB1,0xD7},
+ {0xD9,0x7A}, {0xD9,0x7B}, {0xB7,0x72}, {0xE1,0xF5},
+ {0xBA,0x57}, {0xE9,0xB2}, {0xA4,0xE7}, {0xA5,0xB8},
+ {0xA9,0xF2}, {0xCC,0xC2}, {0xCE,0xE9}, {0xAC,0x48},
+ {0xB1,0xD9}, {0xD9,0x7C}, {0xB4,0xB5}, {0xB7,0x73},
+ {0xE5,0xC1}, {0xE5,0xC2}, {0xFC,0xCD}, {0xEC,0xF0},
+ {0xC2,0x5F}, {0xF8,0xF0}, {0xA4,0xE8}, {0xCC,0xC3},
+ {0xA9,0xF3}, {0xAC,0x49}, {0x9C,0xF3}, {0xCE,0xEA},
+ {0xAE,0xC7}, {0xD1,0xD2}, {0xD1,0xD0}, {0xD1,0xD1},
+ {0xAE,0xC8}, {0xD1,0xCF}, {0xB1,0xDB}, {0xB1,0xDC},
+ {0xD5,0xA8}, {0xB1,0xDD}, {0xB1,0xDA}, {0xD9,0x7D},
+ {0xFC,0xD0}, {0xD9,0x7E}, {0xDD,0xBE}, {0x95,0xBB},
+ {0xBA,0x59}, {0xBA,0x58}, {0xEC,0xF1}, {0xEF,0xD9},
+ {0xF2,0x4A}, {0xF2,0x49}, {0xF4,0x4F}, {0xFC,0xD3},
+ {0xC9,0x5E}, {0xAC,0x4A}, {0xFC,0xD4}, {0xA4,0xE9},
+ {0xA5,0xB9}, {0xA6,0xAE}, {0xA6,0xAD}, {0xA6,0xAF},
+ {0xA6,0xB0}, {0xC9,0xEE}, {0xC9,0xED}, {0xCA,0xF8},
+ {0xA7,0xF2}, {0xCA,0xFB}, {0xCA,0xFA}, {0xCA,0xF9},
+ {0xCA,0xFC}, {0xA9,0xF4}, {0xCC,0xC9}, {0xCC,0xC5},
+ {0xCC,0xCE}, {0x8D,0xAE}, {0xA9,0xFB}, {0xA9,0xF9},
+ {0xCC,0xCA}, {0xCC,0xC6}, {0xCC,0xCD}, {0xA9,0xF8},
+ {0xAA,0x40}, {0xCC,0xC8}, {0xCC,0xC4}, {0xA9,0xFE},
+ {0xCC,0xCB}, {0xA9,0xF7}, {0xCC,0xCC}, {0xA9,0xFA},
+ {0xA9,0xFC}, {0xCC,0xD0}, {0xCC,0xCF}, {0xCC,0xC7},
+ {0xA9,0xF6}, {0xA9,0xF5}, {0xA9,0xFD}, {0xFC,0xD7},
+ {0xCE,0xEF}, {0xCE,0xF5}, {0x93,0xDB}, {0xAC,0x50},
+ {0xAC,0x4D}, {0xCE,0xEC}, {0xCE,0xF1}, {0xFE,0x63},
+ {0xAC,0x53}, {0xAC,0x4B}, {0xCE,0xF0}, {0xAC,0x4E},
+ {0xAC,0x51}, {0xCE,0xF3}, {0xAC,0x4C}, {0xCE,0xF8},
+ {0xAC,0x4F}, {0x93,0xD5}, {0xAC,0x52}, {0xCE,0xED},
+ {0xCE,0xF2}, {0xCE,0xF6}, {0xCE,0xEE}, {0xCE,0xEB},
+ {0xCE,0xF7}, {0xCE,0xF4}, {0xAE,0xD0}, {0xAE,0xC9},
+ {0xAE,0xCC}, {0xFC,0xDA}, {0xAE,0xCF}, {0xD1,0xD5},
+ {0x9B,0x71}, {0xAE,0xCA}, {0xD1,0xD3}, {0xFC,0xDD},
+ {0xAE,0xCE}, {0xAE,0xCB}, {0xD1,0xD6}, {0xAE,0xCD},
+ {0x8D,0xAF}, {0xFA,0xF2}, {0xD5,0xAC}, {0xB1,0xDF},
+ {0xD5,0xAB}, {0xD5,0xAD}, {0xB1,0xDE}, {0xB1,0xE3},
+ {0xD1,0xD4}, {0xD5,0xAA}, {0xD5,0xAE}, {0x93,0xD8},
+ {0xB1,0xE0}, {0xD5,0xA9}, {0xB1,0xE2}, {0xFC,0xDF},
+ {0xB1,0xE1}, {0xD9,0xA7}, {0x93,0xD3}, {0xD9,0xA2},
+ {0xB4,0xB6}, {0xB4,0xBA}, {0xB4,0xB7}, {0xD9,0xA5},
+ {0xD9,0xA8}, {0xFC,0xE1}, {0xB4,0xB8}, {0xB4,0xB9},
+ {0xB4,0xBE}, {0xDD,0xC7}, {0xD9,0xA6}, {0xB4,0xBC},
+ {0xD9,0xA3}, {0xD9,0xA1}, {0x8E,0x76}, {0xB4,0xBD},
+ {0xD9,0xA4}, {0xB7,0x79}, {0xFC,0x62}, {0xDD,0xBF},
+ {0xB7,0x76}, {0xB7,0x77}, {0xB7,0x75}, {0xDD,0xC4},
+ {0xDD,0xC3}, {0xDD,0xC0}, {0xB7,0x7B}, {0x93,0xD1},
+ {0xDD,0xC2}, {0xB4,0xBB}, {0x8D,0xB1}, {0xDD,0xC6},
+ {0xDD,0xC1}, {0xB7,0x78}, {0xB7,0x74}, {0xB7,0x7A},
+ {0xDD,0xC5}, {0x98,0x59}, {0xBA,0x5C}, {0xE1,0xF8},
+ {0xE1,0xF7}, {0xE1,0xF6}, {0xBA,0x5A}, {0xFB,0x52},
+ {0xBA,0x5B}, {0xE5,0xC5}, {0xE5,0xC8}, {0xBC,0xC8},
+ {0xFB,0x53}, {0xBC,0xC7}, {0xE5,0xC9}, {0xE5,0xC4},
+ {0xBC,0xCA}, {0xE5,0xC6}, {0xFB,0x4D}, {0xBC,0xC9},
+ {0xE5,0xC3}, {0x9C,0xBF}, {0xE5,0xC7}, {0xBE,0xE9},
+ {0xBE,0xE6}, {0xE9,0xBB}, {0xE9,0xBA}, {0xE9,0xB9},
+ {0xE9,0xB4}, {0x9B,0x72}, {0xE9,0xB5}, {0xBE,0xE7},
+ {0xBE,0xE4}, {0xBE,0xE8}, {0xE9,0xB3}, {0xBE,0xE5},
+ {0xE9,0xB6}, {0xE9,0xB7}, {0xE9,0xBC}, {0xFB,0x50},
+ {0x93,0xBE}, {0xE9,0xB8}, {0xEC,0xF2}, {0xC0,0xC7},
+ {0xEF,0xDC}, {0xC0,0xC6}, {0xEF,0xDA}, {0xEF,0xDB},
+ {0xC2,0x60}, {0xC3,0x6E}, {0xF2,0x4B}, {0xC3,0x6D},
+ {0xF4,0x51}, {0xF4,0x52}, {0xC4,0x66}, {0xF4,0x50},
+ {0xC4,0xE4}, {0xF7,0xDF}, {0xC5,0xCE}, {0xF8,0xAA},
+ {0xF8,0xAB}, {0xA4,0xEA}, {0x9D,0xF1}, {0xA6,0xB1},
+ {0xA6,0xB2}, {0xA7,0xF3}, {0xCC,0xD1}, {0xAC,0x54},
+ {0xAE,0xD1}, {0xB1,0xE4}, {0xB0,0xD2}, {0xB4,0xBF},
+ {0xB4,0xC0}, {0xB3,0xCC}, {0xD9,0xA9}, {0xFC,0xEB},
+ {0xB7,0x7C}, {0xE1,0xFA}, {0xE1,0xF9}, {0xA4,0xEB},
+ {0xA6,0xB3}, {0xCC,0xD2}, {0xAA,0x42}, {0xA0,0xBB},
+ {0xAA,0x41}, {0x9B,0x7E}, {0xCE,0xF9}, {0xCE,0xFA},
+ {0xD1,0xD7}, {0xD1,0xD8}, {0xAE,0xD2}, {0xAE,0xD3},
+ {0x8D,0xB3}, {0xAE,0xD4}, {0xD5,0xAF}, {0x8C,0x52},
+ {0xB1,0xE6}, {0xB4,0xC2}, {0x9A,0xE8}, {0xB4,0xC1},
+ {0xDD,0xC8}, {0xDF,0x7A}, {0xE1,0xFB}, {0xE9,0xBD},
+ {0x8E,0xDC}, {0xC2,0x61}, {0xC4,0x67}, {0xA4,0xEC},
+ {0xA5,0xBC}, {0xA5,0xBD}, {0xA5,0xBB}, {0xA5,0xBE},
+ {0xA5,0xBA}, {0xA6,0xB6}, {0xC9,0xF6}, {0xA6,0xB5},
+ {0xA6,0xB7}, {0x9C,0xF9}, {0xC9,0xF1}, {0xC9,0xF0},
+ {0xC9,0xF3}, {0xC9,0xF2}, {0xC9,0xF5}, {0xA6,0xB4},
+ {0xC9,0xEF}, {0xC9,0xF4}, {0xFA,0x50}, {0xCA,0xFD},
+ {0xA7,0xFD}, {0xCA,0xFE}, {0xCB,0x43}, {0xA7,0xFC},
+ {0xCB,0x47}, {0xCB,0x42}, {0xCB,0x45}, {0xA7,0xF5},
+ {0xA7,0xF6}, {0xA7,0xF7}, {0xA7,0xF8}, {0xA8,0x40},
+ {0xCB,0x41}, {0xA7,0xFA}, {0xA8,0x41}, {0xCB,0x40},
+ {0xCB,0x46}, {0xA7,0xF9}, {0xCB,0x44}, {0xA7,0xFB},
+ {0xA7,0xF4}, {0xA7,0xFE}, {0x98,0xE7}, {0xFC,0xF3},
+ {0xFC,0xF2}, {0xAA,0x57}, {0x8C,0xCA}, {0xCC,0xD4},
+ {0xAA,0x43}, {0xAA,0x4D}, {0xAA,0x4E}, {0xAA,0x46},
+ {0xAA,0x58}, {0xAA,0x48}, {0xCC,0xDC}, {0xAA,0x53},
+ {0xCC,0xD7}, {0xAA,0x49}, {0xCC,0xE6}, {0xCC,0xE7},
+ {0xCC,0xDF}, {0xCC,0xD8}, {0xAA,0x56}, {0xCC,0xE4},
+ {0xAA,0x51}, {0xAA,0x4F}, {0xCC,0xE5}, {0xCC,0xE3},
+ {0xCC,0xDB}, {0xCC,0xD3}, {0xCC,0xDA}, {0xAA,0x4A},
+ {0xAA,0x50}, {0xAA,0x44}, {0xCC,0xDE}, {0xCC,0xDD},
+ {0xCC,0xD5}, {0x93,0xE5}, {0xAA,0x52}, {0xCC,0xE1},
+ {0xCC,0xD6}, {0xAA,0x55}, {0xCC,0xE8}, {0xAA,0x45},
+ {0xAA,0x4C}, {0xCC,0xD9}, {0xCC,0xE2}, {0xAA,0x54},
+ {0xAA,0x47}, {0xAA,0x4B}, {0xCC,0xE0}, {0x9A,0x59},
+ {0x8D,0xB5}, {0xFD,0x4D}, {0xCF,0x5B}, {0xAC,0x5C},
+ {0xAC,0x69}, {0xFD,0x5E}, {0xCF,0x56}, {0xCF,0x4C},
+ {0xAC,0x62}, {0xCF,0x4A}, {0xAC,0x5B}, {0xCF,0x45},
+ {0xAC,0x65}, {0xCF,0x52}, {0xCE,0xFE}, {0xCF,0x41},
+ {0x8F,0x7D}, {0xCF,0x44}, {0xCE,0xFB}, {0xCF,0x51},
+ {0xCF,0x61}, {0xAC,0x60}, {0xCF,0x46}, {0xCF,0x58},
+ {0xCE,0xFD}, {0xCF,0x5F}, {0xCF,0x60}, {0xCF,0x63},
+ {0xCF,0x5A}, {0xCF,0x4B}, {0xCF,0x53}, {0xAC,0x66},
+ {0xAC,0x59}, {0xAC,0x61}, {0xAC,0x6D}, {0xAC,0x56},
+ {0xAC,0x58}, {0x95,0x47}, {0xFC,0xF6}, {0xCF,0x43},
+ {0xAC,0x6A}, {0xAC,0x63}, {0xCF,0x5D}, {0xCF,0x40},
+ {0xAC,0x6C}, {0xAC,0x67}, {0xCF,0x49}, {0xAC,0x6B},
+ {0xCF,0x50}, {0xCF,0x48}, {0xAC,0x64}, {0xCF,0x5C},
+ {0xCF,0x54}, {0xAC,0x5E}, {0xCF,0x62}, {0xCF,0x47},
+ {0xAC,0x5A}, {0xCF,0x59}, {0xCF,0x4F}, {0xAC,0x5F},
+ {0xCF,0x55}, {0xAC,0x57}, {0xCE,0xFC}, {0xAC,0x68},
+ {0xAE,0xE3}, {0xAC,0x5D}, {0xCF,0x4E}, {0xCF,0x4D},
+ {0xCF,0x42}, {0x92,0x50}, {0xCF,0x5E}, {0xCF,0x57},
+ {0x89,0x68}, {0xAC,0x55}, {0x8D,0xB6}, {0xFC,0xFB},
+ {0xA0,0x7D}, {0x98,0xFC}, {0x89,0x69}, {0xFE,0x4F},
+ {0x92,0x56}, {0xD1,0xEC}, {0xAE,0xEA}, {0xD1,0xED},
+ {0xD1,0xE1}, {0xAE,0xDF}, {0xAE,0xEB}, {0xD1,0xDA},
+ {0xFA,0xC9}, {0xD1,0xE3}, {0xD1,0xEB}, {0x93,0xE8},
+ {0xD1,0xD9}, {0xD1,0xF4}, {0xAE,0xD5}, {0xFC,0xF8},
+ {0xD1,0xF3}, {0xD1,0xEE}, {0xD1,0xEF}, {0xAE,0xDD},
+ {0xAE,0xE8}, {0xD1,0xE5}, {0xD1,0xE6}, {0xD1,0xF0},
+ {0xD1,0xE7}, {0xD1,0xE2}, {0xD1,0xDC}, {0xD1,0xDD},
+ {0xD1,0xEA}, {0xD1,0xE4}, {0x9C,0xE3}, {0xFD,0xA9},
+ {0xAE,0xD6}, {0xAE,0xDA}, {0xD1,0xF2}, {0xD1,0xDE},
+ {0xAE,0xE6}, {0xAE,0xE2}, {0xFC,0x44}, {0xAE,0xE5},
+ {0xAE,0xEC}, {0xAE,0xDB}, {0xAE,0xE7}, {0xD1,0xE9},
+ {0xAE,0xE9}, {0xAE,0xD8}, {0x96,0x40}, {0xAE,0xD7},
+ {0xD1,0xDB}, {0x8D,0xB8}, {0xD1,0xDF}, {0xAE,0xE0},
+ {0xD1,0xF1}, {0xD1,0xE8}, {0xD1,0xE0}, {0xAE,0xE4},
+ {0xAE,0xE1}, {0xAE,0xD9}, {0xAE,0xDC}, {0x9B,0x4A},
+ {0x8F,0xB9}, {0xFC,0xFE}, {0x89,0x6A}, {0xD5,0xC4},
+ {0xD5,0xB4}, {0xD5,0xB5}, {0xD5,0xB9}, {0xD5,0xC8},
+ {0xD5,0xC5}, {0xD5,0xBE}, {0xD5,0xBD}, {0xB1,0xED},
+ {0xD5,0xC1}, {0xD5,0xD0}, {0xD5,0xB0}, {0xD5,0xD1},
+ {0xD5,0xC3}, {0xD5,0xD5}, {0xD5,0xC9}, {0xB1,0xEC},
+ {0xD5,0xC7}, {0xB1,0xE7}, {0xB1,0xFC}, {0xB1,0xF2},
+ {0x8D,0xB9}, {0xB1,0xF6}, {0xB1,0xF5}, {0xD5,0xB1},
+ {0x91,0x7E}, {0xD5,0xCE}, {0xD5,0xD4}, {0xD5,0xCC},
+ {0xD5,0xD3}, {0xD5,0xC0}, {0xD5,0xB2}, {0xD5,0xD2},
+ {0xD5,0xC2}, {0xB1,0xEA}, {0xB1,0xF7}, {0xD5,0xCB},
+ {0xB1,0xF0}, {0x93,0xF4}, {0xD5,0xCA}, {0xD5,0xB3},
+ {0xB1,0xF8}, {0xB1,0xFA}, {0xD5,0xCD}, {0xB1,0xFB},
+ {0xB1,0xE9}, {0xD5,0xBA}, {0xD5,0xCF}, {0xFB,0x7C},
+ {0xB1,0xEF}, {0xB1,0xF9}, {0xD5,0xBC}, {0xD5,0xC6},
+ {0xD5,0xB7}, {0xD5,0xBB}, {0xB1,0xF4}, {0xD5,0xB6},
+ {0xB1,0xE8}, {0xB1,0xF1}, {0xB1,0xEE}, {0xD5,0xBF},
+ {0xAE,0xDE}, {0xD9,0xC0}, {0xB1,0xEB}, {0x93,0xE7},
+ {0x97,0xEF}, {0xFE,0x4A}, {0xFD,0x45}, {0xB1,0xF3},
+ {0x96,0xA5}, {0xD9,0xC3}, {0xD9,0xD9}, {0xD9,0xCE},
+ {0xB4,0xD6}, {0xFE,0xE0}, {0xB4,0xD1}, {0xD9,0xBD},
+ {0xB4,0xD2}, {0xD9,0xCD}, {0xD9,0xC6}, {0xD9,0xD3},
+ {0xB4,0xCE}, {0xD9,0xAB}, {0xD9,0xD5}, {0xB4,0xC4},
+ {0xD9,0xB3}, {0xB4,0xC7}, {0xB4,0xC6}, {0xB4,0xD7},
+ {0xD9,0xAD}, {0xD9,0xCF}, {0xD9,0xD0}, {0xB4,0xC9},
+ {0xB4,0xC5}, {0xD9,0xBB}, {0xB4,0xD0}, {0xD9,0xB6},
+ {0xD9,0xD1}, {0xB4,0xCC}, {0xD9,0xC9}, {0xD9,0xD6},
+ {0xD9,0xB0}, {0xD9,0xB5}, {0xD9,0xAF}, {0xB4,0xCB},
+ {0xD9,0xC2}, {0xDD,0xDE}, {0xD9,0xB1}, {0xB4,0xCF},
+ {0xD9,0xBA}, {0xD9,0xD2}, {0xB4,0xCA}, {0xD9,0xB7},
+ {0xD9,0xB4}, {0xD9,0xC5}, {0xB4,0xCD}, {0xB4,0xC3},
+ {0xB4,0xD9}, {0xD9,0xC8}, {0xD9,0xC7}, {0xFD,0x48},
+ {0xFD,0x47}, {0xFE,0xF2}, {0xFE,0x6A}, {0xD9,0xAC},
+ {0xB4,0xC8}, {0xD9,0xD4}, {0xD9,0xBC}, {0xD9,0xBE},
+ {0x8D,0xBD}, {0xD9,0xCB}, {0xD9,0xCA}, {0xD9,0xAA},
+ {0xB4,0xD3}, {0xB4,0xD5}, {0xD9,0xB2}, {0xD9,0xB9},
+ {0xD9,0xC1}, {0xB4,0xD4}, {0xD9,0xB8}, {0xD9,0xC4},
+ {0xD9,0xD7}, {0xD9,0xCC}, {0x9B,0xA1}, {0x8C,0xA2},
+ {0x9A,0xB7}, {0x8E,0xFC}, {0xD9,0xD8}, {0xD9,0xAE},
+ {0x9F,0xA1}, {0xDD,0xF2}, {0xB7,0xA6}, {0xDD,0xF0},
+ {0xDD,0xDB}, {0xDD,0xE0}, {0xDD,0xD9}, {0xFD,0x51},
+ {0xDD,0xEC}, {0xDD,0xCB}, {0xDD,0xD2}, {0xDD,0xEA},
+ {0xDD,0xF4}, {0xDD,0xDC}, {0xFA,0xAD}, {0xDD,0xCF},
+ {0xDD,0xE2}, {0xDD,0xE7}, {0xDD,0xD3}, {0x8D,0xBE},
+ {0xDD,0xE4}, {0xDD,0xD0}, {0x89,0xA4}, {0xDD,0xD7},
+ {0xDD,0xD8}, {0xB7,0xA8}, {0xDD,0xEB}, {0xDD,0xE9},
+ {0xDD,0xCC}, {0xDD,0xEE}, {0xDD,0xEF}, {0xDD,0xF1},
+ {0xB7,0xAC}, {0xB7,0xA4}, {0x9A,0xD9}, {0xD5,0xB8},
+ {0xDD,0xD4}, {0xDD,0xE6}, {0xDD,0xD5}, {0xB7,0xA1},
+ {0xB7,0xB1}, {0xDD,0xED}, {0xB7,0xAF}, {0xB7,0xAB},
+ {0xDD,0xCA}, {0xB7,0xA3}, {0xFD,0x4E}, {0xDD,0xCD},
+ {0xB7,0xB0}, {0x8D,0xC0}, {0xDD,0xDD}, {0xDD,0xC9},
+ {0x97,0xF0}, {0xB7,0xA9}, {0xDD,0xE1}, {0xDD,0xD1},
+ {0xB7,0xAA}, {0xDD,0xDA}, {0xB7,0x7E}, {0xB4,0xD8},
+ {0xDD,0xE3}, {0xD9,0xBF}, {0xDD,0xCE}, {0x93,0xB4},
+ {0xFD,0x44}, {0xDD,0xE8}, {0xB7,0xA5}, {0xDD,0xE5},
+ {0xB7,0xA2}, {0xDD,0xDF}, {0xB7,0xAD}, {0xDD,0xD6},
+ {0xDD,0xF3}, {0x9F,0xA7}, {0xB7,0xA7}, {0xDE,0xC6},
+ {0x8D,0xC2}, {0xB7,0xAE}, {0x99,0xB6}, {0xE2,0x4A},
+ {0xE2,0x48}, {0xE2,0x5E}, {0xE2,0x46}, {0xE2,0x58},
+ {0xB7,0x7D}, {0xBA,0x5F}, {0xE2,0x42}, {0xE2,0x5D},
+ {0xFD,0x52}, {0xE2,0x47}, {0xE2,0x55}, {0xBA,0x64},
+ {0xBA,0x5D}, {0xE2,0x5B}, {0x8D,0xC1}, {0xE2,0x40},
+ {0xE2,0x5A}, {0x8E,0x46}, {0xBA,0x6F}, {0xE2,0x51},
+ {0xE2,0x61}, {0xBA,0x6D}, {0xE2,0x49}, {0xBA,0x5E},
+ {0xE2,0x4B}, {0xE2,0x59}, {0xBA,0x67}, {0xE2,0x44},
+ {0xBA,0x6B}, {0xBA,0x61}, {0xE2,0x4D}, {0xE2,0x43},
+ {0xE1,0xFC}, {0xA0,0xD1}, {0xE2,0x57}, {0xBA,0x68},
+ {0xE2,0x60}, {0xE1,0xFD}, {0xBA,0x65}, {0xE2,0x53},
+ {0xBA,0x66}, {0xE2,0x45}, {0xE2,0x50}, {0xE2,0x4C},
+ {0xE2,0x4E}, {0x9F,0xCA}, {0xBA,0x60}, {0xE2,0x5F},
+ {0xBA,0x6E}, {0xE2,0x4F}, {0xE2,0x62}, {0xE1,0xFE},
+ {0xE2,0x54}, {0xBA,0x63}, {0xBA,0x6C}, {0xBA,0x6A},
+ {0xE2,0x41}, {0xE2,0x56}, {0xBA,0x69}, {0x92,0xCF},
+ {0xBA,0x62}, {0xE2,0x52}, {0x9C,0xF4}, {0x8D,0xC4},
+ {0xE2,0x5C}, {0xFD,0x41}, {0xE5,0xD5}, {0xE5,0xD1},
+ {0xE5,0xCD}, {0xE5,0xE1}, {0xE5,0xDE}, {0xBC,0xCD},
+ {0x9B,0x4C}, {0xE5,0xE5}, {0xE5,0xD4}, {0xBC,0xD8},
+ {0xE5,0xDB}, {0xE5,0xD0}, {0xE5,0xDA}, {0xBC,0xD5},
+ {0xE5,0xEE}, {0xE5,0xEB}, {0xE5,0xDD}, {0xE5,0xCE},
+ {0xFD,0x57}, {0xFC,0xEF}, {0xE5,0xE2}, {0xE5,0xE4},
+ {0xBC,0xD1}, {0xE5,0xD8}, {0xE5,0xD3}, {0xE5,0xCA},
+ {0xBC,0xCE}, {0xBC,0xD6}, {0x9C,0xDE}, {0xE5,0xE7},
+ {0xBC,0xD7}, {0xE5,0xCB}, {0xE5,0xED}, {0xE5,0xE0},
+ {0xE5,0xE6}, {0xBC,0xD4}, {0xFD,0x42}, {0x98,0x6C},
+ {0xE5,0xE3}, {0xE5,0xEA}, {0xBC,0xD9}, {0xBC,0xD3},
+ {0xE5,0xDC}, {0xE5,0xCF}, {0xE5,0xEF}, {0xE5,0xCC},
+ {0xE5,0xE8}, {0xBC,0xD0}, {0x97,0xF9}, {0xE5,0xD6},
+ {0x95,0x58}, {0xE5,0xD7}, {0xBC,0xCF}, {0xBC,0xCC},
+ {0xE5,0xD2}, {0xBC,0xD2}, {0xBC,0xCB}, {0xE5,0xE9},
+ {0xE5,0xEC}, {0xE5,0xD9}, {0xE9,0xCA}, {0x98,0x5E},
+ {0xFE,0x7B}, {0x94,0xCD}, {0xE9,0xC2}, {0x93,0xEE},
+ {0xE9,0xBE}, {0xBE,0xF6}, {0xBE,0xEB}, {0xBE,0xF0},
+ {0xBE,0xEC}, {0xE9,0xCC}, {0xE9,0xD7}, {0xBE,0xEA},
+ {0xE9,0xC4}, {0xE9,0xCD}, {0xE5,0xDF}, {0xE9,0xCE},
+ {0x8C,0xA3}, {0xBE,0xF1}, {0xFD,0x5A}, {0xE9,0xDD},
+ {0xBE,0xF5}, {0xBE,0xF8}, {0xE9,0xC0}, {0xBE,0xF4},
+ {0x93,0xF5}, {0xE9,0xDB}, {0xE9,0xDC}, {0xE9,0xD2},
+ {0xE9,0xD1}, {0xE9,0xC9}, {0x93,0xEF}, {0x8E,0xEA},
+ {0xE9,0xD3}, {0xE9,0xDA}, {0xE9,0xD9}, {0x8F,0x5B},
+ {0xBE,0xEF}, {0xBE,0xED}, {0xE9,0xCB}, {0xE9,0xC8},
+ {0xE9,0xC5}, {0xE9,0xD8}, {0xBE,0xF7}, {0xE9,0xD6},
+ {0xBE,0xF3}, {0xBE,0xF2}, {0x8C,0x5E}, {0xE9,0xD0},
+ {0x8D,0xC6}, {0xE9,0xBF}, {0xE9,0xC1}, {0xE9,0xC3},
+ {0xE9,0xD5}, {0xE9,0xCF}, {0xBE,0xEE}, {0xE9,0xC6},
+ {0xE9,0xD4}, {0x8D,0xC8}, {0x8D,0xC7}, {0xE9,0xC7},
+ {0x93,0xF7}, {0xC0,0xCF}, {0xED,0x45}, {0xC0,0xC8},
+ {0xEC,0xF5}, {0x8D,0xC9}, {0xED,0x41}, {0xC0,0xCA},
+ {0xED,0x48}, {0xEC,0xFC}, {0xEC,0xF7}, {0xFB,0xF2},
+ {0xED,0x49}, {0xEC,0xF3}, {0xEC,0xFE}, {0x96,0x70},
+ {0xC0,0xD1}, {0xED,0x44}, {0xED,0x4A}, {0xEC,0xFD},
+ {0xC0,0xC9}, {0xED,0x40}, {0xEC,0xF4}, {0xC0,0xD0},
+ {0x8D,0xCB}, {0xED,0x47}, {0xEC,0xF9}, {0xC0,0xCC},
+ {0xFD,0x5C}, {0xEC,0xFB}, {0xEC,0xF8}, {0xC0,0xD2},
+ {0xEC,0xFA}, {0xC0,0xCB}, {0xC0,0xCE}, {0xED,0x43},
+ {0xEC,0xF6}, {0xED,0x46}, {0x8F,0x65}, {0xED,0x42},
+ {0x8D,0xCD}, {0xC2,0x63}, {0xEF,0xE7}, {0xC2,0x68},
+ {0xC2,0x69}, {0x9D,0xA8}, {0x94,0xF9}, {0xC2,0x62},
+ {0xEF,0xE6}, {0x8D,0xCE}, {0xEF,0xE3}, {0xEF,0xE4},
+ {0xC2,0x66}, {0xEF,0xDE}, {0xEF,0xE2}, {0xC2,0x65},
+ {0xEF,0xDF}, {0x93,0xEA}, {0xC2,0x67}, {0xC2,0x64},
+ {0xEF,0xDD}, {0xEF,0xE1}, {0xEF,0xE5}, {0xFD,0x5F},
+ {0x93,0xF0}, {0x9F,0xB6}, {0xF2,0x51}, {0xF2,0x4E},
+ {0xF2,0x57}, {0xF2,0x56}, {0xF2,0x54}, {0xF2,0x4F},
+ {0xC3,0x72}, {0x8D,0xCF}, {0x97,0x63}, {0xF2,0x50},
+ {0xC3,0x71}, {0xC0,0xCD}, {0xF2,0x53}, {0xC3,0x70},
+ {0xF2,0x58}, {0xF2,0x52}, {0xF2,0x4D}, {0xEF,0xE0},
+ {0xC3,0x6F}, {0xF2,0x4C}, {0xF4,0x56}, {0xF4,0x55},
+ {0xF2,0x55}, {0xC4,0x68}, {0xF4,0x59}, {0xF4,0x5A},
+ {0xF4,0x54}, {0xF4,0x58}, {0xF4,0x53}, {0x8D,0xD0},
+ {0xF5,0xD1}, {0xF4,0x57}, {0xC4,0xE7}, {0xC4,0xE5},
+ {0xF5,0xCF}, {0xF5,0xD2}, {0xF5,0xCE}, {0xF5,0xD0},
+ {0xC4,0xE6}, {0x93,0xF1}, {0xF6,0xE5}, {0xF6,0xE6},
+ {0xC5,0x76}, {0xF6,0xE4}, {0xF7,0xE2}, {0xC5,0xCF},
+ {0xF7,0xE0}, {0xF7,0xE1}, {0xF8,0xAC}, {0xC6,0x56},
+ {0xF8,0xF3}, {0xF8,0xF1}, {0xF8,0xF2}, {0xF8,0xF4},
+ {0xFD,0x62}, {0xF9,0xBB}, {0xA4,0xED}, {0xA6,0xB8},
+ {0xAA,0x59}, {0xCC,0xE9}, {0xCF,0x64}, {0xD1,0xF5},
+ {0xD1,0xF7}, {0xD1,0xF6}, {0xD1,0xF8}, {0xB1,0xFD},
+ {0xD5,0xD7}, {0xD1,0xF9}, {0xFD,0x65}, {0xD5,0xD6},
+ {0xD5,0xD8}, {0xD5,0xD9}, {0xD9,0xDA}, {0xB4,0xDB},
+ {0xD9,0xDB}, {0xD9,0xDD}, {0xB4,0xDC}, {0xB4,0xDA},
+ {0xD9,0xDC}, {0xDD,0xFA}, {0xDD,0xF8}, {0xDD,0xF7},
+ {0xDD,0xF6}, {0xDD,0xF5}, {0xB7,0xB2}, {0xDD,0xF9},
+ {0xBA,0x70}, {0xE2,0x63}, {0xE2,0x65}, {0xBA,0x71},
+ {0xE2,0x64}, {0xBC,0xDB}, {0xBC,0xDA}, {0xE5,0xF0},
+ {0x9F,0xDB}, {0xE9,0xDF}, {0xE9,0xDE}, {0xE9,0xE0},
+ {0x93,0xF8}, {0xBE,0xF9}, {0xED,0x4B}, {0xC0,0xD3},
+ {0xEF,0xE8}, {0xC2,0x6A}, {0xF2,0x59}, {0xC5,0x77},
+ {0xA4,0xEE}, {0xA5,0xBF}, {0xA6,0xB9}, {0xA8,0x42},
+ {0xAA,0x5A}, {0xAA,0x5B}, {0xAC,0x6E}, {0xD1,0xFA},
+ {0x8B,0xF7}, {0xB7,0xB3}, {0xFD,0x66}, {0xE6,0xD1},
+ {0xBE,0xFA}, {0xC2,0x6B}, {0xA4,0xEF}, {0x8B,0xCF},
+ {0xA6,0xBA}, {0xCC,0xEB}, {0xAA,0x5C}, {0xCC,0xEA},
+ {0x8D,0xD1}, {0xCF,0x65}, {0xAC,0x6F}, {0xCF,0x66},
+ {0xAC,0x70}, {0xD1,0xFC}, {0xAE,0xEE}, {0xAE,0xED},
+ {0xD5,0xDE}, {0xD5,0xDC}, {0xD5,0xDD}, {0xD5,0xDB},
+ {0xD5,0xDA}, {0xD9,0xDE}, {0xD9,0xE1}, {0xB4,0xDE},
+ {0xD9,0xDF}, {0xB4,0xDD}, {0xD9,0xE0}, {0xDD,0xFB},
+ {0xE2,0x66}, {0xE2,0x67}, {0xE2,0x68}, {0xE5,0xF3},
+ {0xE5,0xF2}, {0xBC,0xDC}, {0xE5,0xF1}, {0xE5,0xF4},
+ {0xE9,0xE1}, {0xE9,0xE2}, {0xE9,0xE3}, {0xED,0x4C},
+ {0xC0,0xD4}, {0xC2,0x6C}, {0xF2,0x5A}, {0xC4,0xE8},
+ {0xC9,0x5F}, {0xAC,0x71}, {0xCF,0x67}, {0xAE,0xEF},
+ {0xB1,0xFE}, {0xB4,0xDF}, {0xD9,0xE2}, {0xB7,0xB5},
+ {0xB7,0xB4}, {0x8D,0xD2}, {0xE2,0x69}, {0xE2,0x6A},
+ {0xBC,0xDD}, {0xBC,0xDE}, {0xE9,0xE5}, {0xE9,0xE4},
+ {0xEF,0xE9}, {0xF7,0xE3}, {0xA4,0xF0}, {0xC9,0x60},
+ {0xA5,0xC0}, {0xA8,0x43}, {0xCB,0x48}, {0xAC,0x72},
+ {0xB7,0xB6}, {0xA4,0xF1}, {0xCF,0x68}, {0xAC,0x73},
+ {0xCF,0x69}, {0xC0,0xD5}, {0xA4,0xF2}, {0xFD,0x71},
+ {0xCC,0xEC}, {0xCF,0x6A}, {0xFD,0x6F}, {0xD2,0x42},
+ {0xD2,0x41}, {0xD1,0xFE}, {0xD1,0xFD}, {0xD2,0x43},
+ {0xD2,0x40}, {0x8D,0xD3}, {0xB2,0x40}, {0xB2,0x41},
+ {0xB4,0xE0}, {0xD9,0xE3}, {0xD9,0xE4}, {0xD9,0xE5},
+ {0xDE,0x41}, {0xDE,0x42}, {0xDE,0x40}, {0x9F,0xE7},
+ {0xDD,0xFD}, {0xDD,0xFE}, {0xB7,0xB7}, {0xE2,0x6B},
+ {0xE5,0xF7}, {0xE5,0xF6}, {0xE5,0xF5}, {0xE5,0xF8},
+ {0xE9,0xE7}, {0xE9,0xE6}, {0xBE,0xFB}, {0xE9,0xE8},
+ {0xC0,0xD6}, {0xED,0x4D}, {0xEF,0xEA}, {0xF2,0x5B},
+ {0xF6,0xE7}, {0xA4,0xF3}, {0xA5,0xC2}, {0xA5,0xC1},
+ {0xAA,0x5D}, {0xC9,0x61}, {0xC9,0x7E}, {0xA6,0xBB},
+ {0xC9,0xF7}, {0xCB,0x49}, {0xCB,0x4A}, {0xAA,0x5E},
+ {0x90,0xBD}, {0xCC,0xED}, {0xAC,0x74}, {0xCF,0x6B},
+ {0xCF,0x6C}, {0xAE,0xF0}, {0xAE,0xF4}, {0xD2,0x44},
+ {0xAE,0xF3}, {0xAE,0xF1}, {0xAE,0xF2}, {0xD5,0xDF},
+ {0xB2,0x42}, {0xB4,0xE3}, {0xB4,0xE1}, {0xB4,0xE2},
+ {0xD9,0xE6}, {0x9F,0xD0}, {0xBA,0x72}, {0xA4,0xF4},
+ {0x8B,0xD0}, {0xC9,0xA1}, {0xFD,0x72}, {0xA5,0xC3},
+ {0x9C,0xAE}, {0x8B,0xD1}, {0xC9,0xA4}, {0x8A,0xDB},
+ {0xA5,0xC6}, {0xC9,0xA3}, {0xA5,0xC5}, {0xA5,0xC4},
+ {0xA8,0x44}, {0xC9,0xA2}, {0xC9,0xF8}, {0xFA,0xE4},
+ {0xC9,0xFC}, {0xC9,0xFE}, {0xCA,0x40}, {0xA6,0xC5},
+ {0xA6,0xC6}, {0xC9,0xFB}, {0xA6,0xC1}, {0xC9,0xF9},
+ {0xC9,0xFD}, {0xA6,0xC2}, {0xA6,0xBD}, {0x95,0xCE},
+ {0xA6,0xBE}, {0xFD,0x76}, {0xA6,0xC4}, {0xC9,0xFA},
+ {0xA6,0xBC}, {0xA8,0x45}, {0xA6,0xBF}, {0xA6,0xC0},
+ {0xA6,0xC3}, {0xCB,0x5B}, {0xCB,0x59}, {0xCB,0x4C},
+ {0xA8,0x51}, {0xCB,0x53}, {0xA8,0x4C}, {0xCB,0x4D},
+ {0xCB,0x55}, {0xFB,0x62}, {0xCB,0x52}, {0xA8,0x4F},
+ {0xCB,0x51}, {0xA8,0x56}, {0xCB,0x5A}, {0xA8,0x58},
+ {0x8D,0xD4}, {0xA8,0x5A}, {0xCB,0x4B}, {0xFD,0x78},
+ {0xA8,0x4D}, {0xCB,0x5C}, {0xA8,0x54}, {0xA8,0x57},
+ {0x8E,0xE3}, {0xCD,0x45}, {0xA8,0x47}, {0xA8,0x5E},
+ {0xA8,0x55}, {0xCB,0x4E}, {0xA8,0x4A}, {0xA8,0x59},
+ {0xCB,0x56}, {0xA8,0x48}, {0xA8,0x49}, {0xCD,0x43},
+ {0xCB,0x4F}, {0xA8,0x50}, {0xA8,0x5B}, {0xCB,0x5D},
+ {0xCB,0x50}, {0xA8,0x4E}, {0xA8,0x53}, {0xCC,0xEE},
+ {0xA8,0x5C}, {0xCB,0x57}, {0xA8,0x52}, {0xA8,0x5D},
+ {0xA8,0x46}, {0xCB,0x54}, {0xA8,0x4B}, {0xCB,0x58},
+ {0xCD,0x44}, {0x90,0x76}, {0x98,0xC6}, {0x8D,0xD5},
+ {0xAA,0x6A}, {0xAA,0x7A}, {0xCC,0xF5}, {0xAA,0x71},
+ {0x97,0xD1}, {0xCD,0x4B}, {0xAA,0x62}, {0x9E,0xB6},
+ {0xAA,0x65}, {0xCD,0x42}, {0xCC,0xF3}, {0xCC,0xF7},
+ {0xAA,0x6D}, {0xAA,0x6F}, {0xCC,0xFA}, {0xAA,0x76},
+ {0xAA,0x68}, {0xAA,0x66}, {0xAA,0x67}, {0xAA,0x75},
+ {0xCD,0x47}, {0xAA,0x70}, {0xCC,0xF9}, {0xCC,0xFB},
+ {0xAA,0x6E}, {0xAA,0x73}, {0xCC,0xFC}, {0xCD,0x4A},
+ {0xAC,0x75}, {0xAA,0x79}, {0xFA,0xC7}, {0xAA,0x63},
+ {0xCD,0x49}, {0xA0,0x42}, {0xCD,0x4D}, {0xCC,0xF8},
+ {0xCD,0x4F}, {0xCD,0x40}, {0xAA,0x6C}, {0xCC,0xF4},
+ {0xAA,0x6B}, {0xAA,0x7D}, {0xAA,0x72}, {0xCC,0xF2},
+ {0xCF,0x75}, {0xAA,0x78}, {0xAA,0x7C}, {0xCD,0x41},
+ {0xCD,0x46}, {0x98,0x73}, {0xAA,0x7E}, {0xAA,0x77},
+ {0xAA,0x69}, {0xAA,0x5F}, {0xAA,0x64}, {0xCC,0xF6},
+ {0xAA,0x60}, {0xCD,0x4E}, {0x9F,0xFC}, {0xCC,0xF0},
+ {0xCC,0xEF}, {0xCC,0xFD}, {0xCC,0xF1}, {0xAA,0x7B},
+ {0xAE,0xF5}, {0xAA,0x74}, {0xCC,0xFE}, {0xAA,0x61},
+ {0xAC,0xA6}, {0xCD,0x4C}, {0x8C,0xA5}, {0xCF,0x7C},
+ {0xCF,0xA1}, {0x8D,0xD7}, {0xCF,0xA4}, {0xCF,0x77},
+ {0x92,0xFB}, {0x8D,0xD8}, {0xCF,0xA7}, {0xCF,0xAA},
+ {0xCF,0xAC}, {0xCF,0x74}, {0xAC,0x76}, {0xAC,0x7B},
+ {0xD2,0x49}, {0xAC,0xAD}, {0xCF,0xA5}, {0xCF,0xAD},
+ {0xCF,0x7B}, {0xCF,0x73}, {0xD2,0x64}, {0xAC,0x7E},
+ {0xCF,0xA2}, {0xCF,0x78}, {0xCF,0x7A}, {0xAC,0xA5},
+ {0xCF,0x7D}, {0xAC,0x7D}, {0xCF,0x70}, {0xCF,0xA8},
+ {0xCF,0xAB}, {0x94,0x4F}, {0xAC,0x7A}, {0x8D,0xD9},
+ {0xAC,0xA8}, {0xCF,0x6D}, {0xAC,0xAA}, {0xAC,0x78},
+ {0xAC,0xAE}, {0xCF,0xA9}, {0xCF,0x6F}, {0xAC,0xAB},
+ {0xD2,0x5E}, {0xCD,0x48}, {0xAC,0x7C}, {0xAC,0x77},
+ {0xCF,0x76}, {0xCF,0x6E}, {0xAC,0xAC}, {0xAC,0xA4},
+ {0xCF,0xA3}, {0xAC,0xA9}, {0xAC,0xA7}, {0xCF,0x79},
+ {0xAC,0xA1}, {0xCF,0x71}, {0xAC,0xA2}, {0xAC,0xA3},
+ {0xCF,0x72}, {0xCF,0xA6}, {0xAC,0x79}, {0xCF,0x7E},
+ {0x89,0x6B}, {0x97,0xCE}, {0xD2,0x4C}, {0xAE,0xFD},
+ {0xAF,0x43}, {0xFA,0xF3}, {0xFD,0xAE}, {0xD2,0x55},
+ {0xD2,0x5B}, {0xD2,0x57}, {0xD2,0x4A}, {0xD2,0x4D},
+ {0xD2,0x46}, {0xD2,0x47}, {0xAF,0x4A}, {0xAE,0xFA},
+ {0xD2,0x56}, {0xD2,0x5F}, {0xAF,0x45}, {0xAE,0xF6},
+ {0xAF,0x40}, {0xD2,0x4E}, {0xAF,0x42}, {0xD2,0x4F},
+ {0xD2,0x59}, {0xFB,0xAF}, {0x92,0xB7}, {0xAF,0x44},
+ {0xD2,0x68}, {0xD2,0x48}, {0xAE,0xFC}, {0xAE,0xFB},
+ {0xAF,0x48}, {0xD2,0x45}, {0xD2,0x66}, {0xD2,0x5A},
+ {0xD2,0x67}, {0xD2,0x61}, {0xD2,0x53}, {0xD2,0x62},
+ {0x8D,0xDA}, {0xD2,0x5C}, {0xD2,0x65}, {0xD2,0x63},
+ {0xAF,0x49}, {0xD2,0x54}, {0xAE,0xF9}, {0xAE,0xF8},
+ {0xAF,0x41}, {0xAF,0x47}, {0xD2,0x60}, {0xAF,0x46},
+ {0xD2,0x51}, {0xB2,0x43}, {0x9C,0x5A}, {0xD2,0x69},
+ {0xD2,0x50}, {0xD2,0x4B}, {0xAE,0xFE}, {0xAF,0x4B},
+ {0xAE,0xF7}, {0xFD,0xAD}, {0xD2,0x58}, {0xD2,0x5D},
+ {0x8D,0xDC}, {0x94,0x44}, {0xB2,0x65}, {0xD5,0xE1},
+ {0xD5,0xE5}, {0xB2,0x52}, {0xB2,0x50}, {0x8D,0xDD},
+ {0xB2,0x47}, {0xD5,0xE3}, {0xD5,0xE2}, {0xB2,0x5B},
+ {0xD5,0xE8}, {0xB2,0x55}, {0xA0,0xD6}, {0xD5,0xFA},
+ {0xD6,0x47}, {0xB2,0x44}, {0xD5,0xF7}, {0xD5,0xF0},
+ {0xB2,0x67}, {0xD5,0xE0}, {0xD5,0xFC}, {0xB2,0x64},
+ {0xB2,0x58}, {0xB2,0x63}, {0xB2,0x4E}, {0xD5,0xEC},
+ {0xD5,0xFE}, {0xD5,0xF6}, {0xB2,0x4F}, {0xB2,0x49},
+ {0xD6,0x45}, {0xD5,0xFD}, {0xD6,0x40}, {0xB2,0x51},
+ {0xB2,0x59}, {0xD6,0x42}, {0xD5,0xEA}, {0xD5,0xFB},
+ {0xD5,0xEF}, {0xD6,0x44}, {0xB2,0x5E}, {0xB2,0x46},
+ {0xB2,0x5C}, {0xD5,0xF4}, {0xD5,0xF2}, {0xD5,0xF3},
+ {0xB2,0x53}, {0xD5,0xEE}, {0xD5,0xED}, {0xB2,0x48},
+ {0xD5,0xE7}, {0xD6,0x46}, {0xB2,0x4A}, {0xD5,0xF1},
+ {0xB2,0x68}, {0xB2,0x62}, {0xD5,0xE6}, {0xB2,0x5F},
+ {0xB2,0x5D}, {0xB2,0x66}, {0xD5,0xF8}, {0xB2,0x61},
+ {0xD2,0x52}, {0xD5,0xF9}, {0xB2,0x60}, {0xD6,0x41},
+ {0xB2,0x45}, {0xD5,0xF5}, {0xB2,0x57}, {0xD5,0xE9},
+ {0xB2,0x56}, {0xB2,0x54}, {0xB2,0x4C}, {0xB2,0x4B},
+ {0xD9,0xE7}, {0xD6,0x43}, {0x8C,0x41}, {0xD5,0xEB},
+ {0x97,0xD5}, {0xD9,0xFC}, {0x94,0x4A}, {0xB2,0x4D},
+ {0x94,0x4D}, {0x97,0xCB}, {0x8D,0xDE}, {0x8D,0xDF},
+ {0xB5,0x41}, {0xB2,0x5A}, {0xB4,0xEE}, {0xD9,0xF6},
+ {0xB4,0xFC}, {0xD9,0xEA}, {0xB4,0xEB}, {0xB4,0xE7},
+ {0xDA,0x49}, {0xB4,0xED}, {0xB4,0xF1}, {0xB4,0xEC},
+ {0xB4,0xF5}, {0xDA,0x4D}, {0xDA,0x44}, {0x8D,0xE0},
+ {0xFE,0xF9}, {0xD9,0xF1}, {0xB4,0xFA}, {0xB4,0xF4},
+ {0xD9,0xFD}, {0xB4,0xE4}, {0xDA,0x4A}, {0xDA,0x43},
+ {0xB4,0xE8}, {0xD9,0xF7}, {0xB4,0xF7}, {0xDA,0x55},
+ {0xDA,0x56}, {0xB4,0xE5}, {0xDA,0x48}, {0xB4,0xF9},
+ {0xD9,0xFB}, {0xD9,0xED}, {0xD9,0xEE}, {0xB4,0xFD},
+ {0xD9,0xF2}, {0xD9,0xF9}, {0xD9,0xF3}, {0xB4,0xFB},
+ {0xB5,0x44}, {0xD9,0xEF}, {0xD9,0xE8}, {0xD9,0xE9},
+ {0xD9,0xEB}, {0xB4,0xEA}, {0xD9,0xF8}, {0xB4,0xF8},
+ {0xB5,0x42}, {0xFD,0xC0}, {0xFC,0xF9}, {0xD9,0xFA},
+ {0xDA,0x53}, {0xDA,0x4B}, {0xB4,0xE6}, {0xDA,0x51},
+ {0xB4,0xF2}, {0xB4,0xF0}, {0xFB,0x7E}, {0xDA,0x57},
+ {0xB4,0xEF}, {0xDA,0x41}, {0xD9,0xF4}, {0xD9,0xFE},
+ {0xB5,0x47}, {0xDA,0x45}, {0xDA,0x42}, {0xD9,0xF0},
+ {0xB5,0x43}, {0xDA,0x4F}, {0xDA,0x4C}, {0xDA,0x54},
+ {0xB4,0xE9}, {0xDA,0x40}, {0xB5,0x46}, {0xDA,0x47},
+ {0xB4,0xF3}, {0xB4,0xF6}, {0xDA,0x46}, {0xB5,0x45},
+ {0xD9,0xF5}, {0xD5,0xE4}, {0x92,0xB3}, {0xDA,0x50},
+ {0xDA,0x4E}, {0xDA,0x52}, {0xFD,0xAF}, {0x8D,0xE1},
+ {0xD9,0xEC}, {0xB5,0x40}, {0x95,0xD3}, {0xDE,0x61},
+ {0xDE,0x60}, {0xDE,0x46}, {0xB7,0xBD}, {0xDE,0x5F},
+ {0xDE,0x49}, {0xDE,0x4A}, {0xB7,0xC7}, {0xDE,0x68},
+ {0xB7,0xC2}, {0xDE,0x5E}, {0x89,0xC1}, {0xDE,0x43},
+ {0xB7,0xC8}, {0xB7,0xBE}, {0xDE,0x52}, {0xDE,0x48},
+ {0xDE,0x4B}, {0xDE,0x63}, {0xB7,0xB8}, {0xDE,0x6A},
+ {0xDE,0x62}, {0xB7,0xC1}, {0xDE,0x57}, {0xB7,0xCC},
+ {0xB7,0xCB}, {0xB7,0xC5}, {0xDE,0x69}, {0xB7,0xB9},
+ {0xDE,0x55}, {0xDE,0x4C}, {0xDE,0x59}, {0xDE,0x65},
+ {0xB7,0xCD}, {0xFD,0x68}, {0xB7,0xBB}, {0xDE,0x54},
+ {0x9C,0xB7}, {0xDE,0x4D}, {0xB7,0xC4}, {0x8D,0xE3},
+ {0xB7,0xC3}, {0xDE,0x50}, {0xDE,0x5A}, {0xDE,0x64},
+ {0xDE,0x47}, {0xDE,0x51}, {0xB7,0xBC}, {0xDE,0x5B},
+ {0xB7,0xC9}, {0xB7,0xC0}, {0xDE,0x4E}, {0xB7,0xBF},
+ {0xDE,0x45}, {0xDE,0x53}, {0xDE,0x67}, {0xB4,0xFE},
+ {0xBA,0xB0}, {0xDE,0x56}, {0xE2,0x6C}, {0xDE,0x58},
+ {0xDE,0x66}, {0xB7,0xC6}, {0xDE,0x4F}, {0xB7,0xBA},
+ {0xB7,0xCA}, {0xBC,0xF0}, {0xDE,0x44}, {0xDE,0x5D},
+ {0xFA,0xC0}, {0x8D,0xE5}, {0xFA,0x64}, {0xDE,0x5C},
+ {0x89,0x47}, {0x8D,0xE4}, {0x8D,0xE7}, {0x8D,0xE8},
+ {0xE2,0xAA}, {0xBA,0xAD}, {0xE2,0x7D}, {0xE2,0xA4},
+ {0xBA,0xA2}, {0xE2,0x6E}, {0xBA,0xAF}, {0xBA,0x77},
+ {0xE2,0x6D}, {0xE2,0xB0}, {0xBA,0xB1}, {0xE2,0x71},
+ {0xE2,0xA3}, {0xFD,0xC7}, {0xE2,0x73}, {0xE2,0xB3},
+ {0xE2,0xAF}, {0xBA,0x75}, {0xBA,0xA1}, {0xE6,0x53},
+ {0xBA,0xAE}, {0xBA,0x7D}, {0xE2,0x6F}, {0xFD,0xB0},
+ {0xE2,0xAE}, {0xBA,0xA3}, {0xE2,0xAB}, {0xE2,0xB8},
+ {0xE2,0x75}, {0xE2,0x7E}, {0x94,0x45}, {0x97,0xD6},
+ {0xE2,0xB6}, {0xE2,0xAC}, {0xBA,0x7C}, {0xE2,0x7C},
+ {0xBA,0x76}, {0xBA,0x74}, {0xBA,0xA8}, {0xFC,0xC6},
+ {0x98,0x44}, {0xE2,0x7A}, {0xE2,0x77}, {0xE2,0x78},
+ {0xE2,0xB2}, {0xE2,0xB7}, {0xE2,0xB5}, {0xBA,0x7A},
+ {0xE2,0xB9}, {0xBA,0x7E}, {0xBA,0xA7}, {0x8D,0xE9},
+ {0xE2,0x70}, {0xE5,0xFA}, {0xE2,0x79}, {0xBA,0x78},
+ {0xBA,0xAC}, {0xBA,0xA9}, {0xBA,0x7B}, {0xE2,0xA5},
+ {0xE2,0x74}, {0xBA,0xAA}, {0xE2,0xA7}, {0xBA,0xA4},
+ {0xBA,0xA6}, {0xBA,0x73}, {0x8D,0xEA}, {0xE2,0xA9},
+ {0xE2,0xA1}, {0xE2,0x72}, {0xBA,0xA5}, {0xE2,0xB1},
+ {0xE2,0xB4}, {0xE2,0x7B}, {0xE2,0xA8}, {0xFE,0x50},
+ {0xBA,0x79}, {0xBC,0xDF}, {0xE2,0xA6}, {0xE5,0xF9},
+ {0xE2,0xAD}, {0xFD,0xCC}, {0xE2,0x76}, {0xE6,0x44},
+ {0xE6,0x4E}, {0xBC,0xE2}, {0xE6,0x4D}, {0xE6,0x59},
+ {0xBC,0xE4}, {0xE6,0x4B}, {0x9D,0xA7}, {0xE6,0x4F},
+ {0xBC,0xEF}, {0xE6,0x46}, {0xBC,0xE7}, {0xFD,0xCD},
+ {0xE6,0x52}, {0xE9,0xF0}, {0xBC,0xF3}, {0xBC,0xF2},
+ {0xE6,0x54}, {0xE6,0x43}, {0xE6,0x5E}, {0xBC,0xED},
+ {0xBC,0xE3}, {0xE6,0x57}, {0xE6,0x5B}, {0xE6,0x60},
+ {0xE6,0x55}, {0xE6,0x49}, {0xBC,0xE6}, {0xBC,0xE9},
+ {0xBC,0xF1}, {0xBC,0xEC}, {0xE6,0x4C}, {0xE2,0xA2},
+ {0xFD,0xCF}, {0xE6,0x48}, {0xE6,0x5F}, {0xBC,0xE8},
+ {0x95,0xD2}, {0xBC,0xEB}, {0xE6,0x61}, {0xBC,0xE0},
+ {0xE6,0x56}, {0xE5,0xFB}, {0xE6,0x5C}, {0xC0,0xDF},
+ {0x8D,0xED}, {0xE6,0x4A}, {0xBC,0xE1}, {0xE6,0x45},
+ {0xBC,0xE5}, {0xE5,0xFC}, {0xBA,0xAB}, {0xE6,0x41},
+ {0xFC,0xBA}, {0xE6,0x5A}, {0xE6,0x42}, {0xE6,0x40},
+ {0xBC,0xEA}, {0xE6,0x58}, {0xE5,0xFE}, {0xE6,0x51},
+ {0xE6,0x50}, {0xE6,0x5D}, {0xE6,0x47}, {0xBC,0xEE},
+ {0xFD,0xC5}, {0xE9,0xF3}, {0xFD,0xD2}, {0xBF,0x49},
+ {0xBE,0xFE}, {0xEA,0x40}, {0xE9,0xEB}, {0xBF,0x41},
+ {0xE9,0xF7}, {0xBF,0x48}, {0xBF,0x43}, {0xE9,0xF5},
+ {0xED,0x4F}, {0xE9,0xFB}, {0xEA,0x42}, {0xE9,0xFA},
+ {0xE9,0xE9}, {0xE9,0xF8}, {0xEA,0x44}, {0xEA,0x46},
+ {0xBE,0xFD}, {0xEA,0x45}, {0xBF,0x44}, {0xBF,0x4A},
+ {0x9C,0xDC}, {0xBF,0x47}, {0xE9,0xFE}, {0xBF,0x46},
+ {0xE9,0xF9}, {0x95,0xCF}, {0xE9,0xED}, {0xE9,0xF2},
+ {0x8D,0xEE}, {0xE9,0xFD}, {0xBF,0x45}, {0xBF,0x42},
+ {0xBE,0xFC}, {0xBF,0x40}, {0xE9,0xF1}, {0xE5,0xFD},
+ {0xE9,0xEC}, {0xE9,0xEF}, {0xEA,0x41}, {0xE9,0xF4},
+ {0xE9,0xEA}, {0xED,0x4E}, {0xEA,0x43}, {0xE9,0xEE},
+ {0xE9,0xFC}, {0xFD,0xD4}, {0xED,0x51}, {0xC0,0xE3},
+ {0xC0,0xD7}, {0x96,0xEC}, {0x96,0xEB}, {0xC0,0xDB},
+ {0xED,0x53}, {0xED,0x59}, {0xED,0x57}, {0xC0,0xD9},
+ {0xC0,0xDA}, {0xC0,0xE1}, {0xED,0x5A}, {0xED,0x52},
+ {0xC0,0xDC}, {0xED,0x56}, {0xED,0x55}, {0xED,0x5B},
+ {0xC0,0xE2}, {0xC0,0xDD}, {0xC0,0xE0}, {0xED,0x54},
+ {0xC0,0xE4}, {0xC0,0xDE}, {0xC0,0xE5}, {0xC0,0xD8},
+ {0xED,0x58}, {0xED,0x50}, {0x90,0xB6}, {0xEF,0xF7},
+ {0xFD,0xC3}, {0xC2,0x71}, {0xEF,0xF4}, {0xEF,0xF6},
+ {0xC2,0x6F}, {0xEF,0xF2}, {0xEF,0xF3}, {0xEF,0xEE},
+ {0x98,0xAB}, {0xE9,0xF6}, {0xEF,0xEF}, {0xC2,0x70},
+ {0xEF,0xEB}, {0xC2,0x6D}, {0xEF,0xF8}, {0xC2,0x6E},
+ {0xEF,0xEC}, {0xEF,0xED}, {0xEF,0xF1}, {0xC2,0x73},
+ {0xC2,0x72}, {0xEF,0xF0}, {0xC3,0x78}, {0xF2,0x5F},
+ {0xF2,0x65}, {0xC3,0x79}, {0xF2,0x5C}, {0xC3,0x76},
+ {0xC3,0x73}, {0xF2,0x67}, {0xC3,0x77}, {0x96,0xEE},
+ {0xC3,0x74}, {0xF2,0x5E}, {0xF2,0x61}, {0xF2,0x62},
+ {0xF2,0x63}, {0xF2,0x66}, {0xEF,0xF5}, {0xF2,0x5D},
+ {0xC3,0x75}, {0xF2,0x64}, {0xF2,0x68}, {0xF2,0x60},
+ {0x8D,0xF4}, {0xF4,0x5D}, {0xC4,0x6A}, {0xF4,0x60},
+ {0xC4,0x6B}, {0xF4,0x68}, {0xF4,0x5F}, {0xF4,0x5C},
+ {0xF4,0x5E}, {0xF4,0x62}, {0xF4,0x65}, {0xF4,0x64},
+ {0xF4,0x67}, {0xF4,0x5B}, {0xC4,0x69}, {0xF4,0x63},
+ {0xF4,0x66}, {0xF4,0x69}, {0xF4,0x61}, {0xF5,0xD3},
+ {0xF5,0xD4}, {0xF5,0xD8}, {0xF5,0xD9}, {0xF5,0xD6},
+ {0xF5,0xD7}, {0xF5,0xD5}, {0xFD,0xE0}, {0xC4,0xE9},
+ {0x8C,0x67}, {0x8D,0xF6}, {0xC5,0x78}, {0xF6,0xEB},
+ {0x8D,0xF7}, {0xF6,0xE8}, {0xF6,0xE9}, {0xF6,0xEA},
+ {0xC5,0x79}, {0xF7,0xE5}, {0xF7,0xE4}, {0x8F,0xFA},
+ {0xF8,0xAF}, {0xC5,0xF4}, {0xF8,0xAD}, {0xF8,0xB0},
+ {0xF8,0xAE}, {0xF8,0xF5}, {0xC6,0x57}, {0xC6,0x65},
+ {0xF9,0xA3}, {0xF9,0x6C}, {0x97,0xD0}, {0xF9,0xA2},
+ {0xF9,0xD0}, {0xF9,0xD1}, {0xA4,0xF5}, {0x8B,0xD2},
+ {0x8D,0xF8}, {0xA6,0xC7}, {0xCA,0x41}, {0xCB,0x5E},
+ {0x90,0xD9}, {0xA8,0x5F}, {0x8C,0x47}, {0xA8,0x62},
+ {0xFA,0xF0}, {0xCB,0x5F}, {0xA8,0x60}, {0xA8,0x61},
+ {0xFD,0xE1}, {0x8D,0xF9}, {0xFD,0xE3}, {0xCD,0x58},
+ {0xCD,0x5A}, {0xCD,0x55}, {0xCD,0x52}, {0xCD,0x54},
+ {0x8D,0xFA}, {0xAA,0xA4}, {0xFB,0x63}, {0xAA,0xA2},
+ {0x90,0xA6}, {0xCD,0x56}, {0xAA,0xA3}, {0xCD,0x53},
+ {0xCD,0x50}, {0xAA,0xA1}, {0xCD,0x57}, {0xCD,0x51},
+ {0xAA,0xA5}, {0xCD,0x59}, {0xCF,0xAF}, {0x99,0x70},
+ {0xCF,0xB3}, {0x91,0xEB}, {0xAC,0xB7}, {0x97,0x70},
+ {0x98,0x6F}, {0xFD,0xE2}, {0xCF,0xB6}, {0xAC,0xAF},
+ {0xAC,0xB2}, {0xAC,0xB4}, {0xAC,0xB6}, {0xAC,0xB3},
+ {0xCF,0xB2}, {0xCF,0xB1}, {0xAC,0xB1}, {0xCF,0xB4},
+ {0xCF,0xB5}, {0xCF,0xAE}, {0xAC,0xB5}, {0x98,0xF2},
+ {0xAC,0xB0}, {0x9A,0xFC}, {0x89,0x6C}, {0xFD,0xFD},
+ {0xCF,0xB0}, {0x99,0x5E}, {0x95,0xBD}, {0xD2,0x77},
+ {0xD2,0x78}, {0xD2,0x79}, {0xAF,0x50}, {0xAF,0x4C},
+ {0xD2,0x6E}, {0xFD,0xE4}, {0xD2,0x76}, {0xD2,0x7B},
+ {0xAF,0x51}, {0x91,0xE6}, {0xD2,0x6C}, {0xD2,0x72},
+ {0xD2,0x6B}, {0xD2,0x75}, {0xFD,0xE5}, {0xFD,0xE6},
+ {0xD2,0x71}, {0xAF,0x4D}, {0xAF,0x4F}, {0xD2,0x7A},
+ {0xD2,0x6A}, {0xD2,0x6D}, {0xD2,0x73}, {0xFD,0xE7},
+ {0xD2,0x74}, {0xD2,0x7C}, {0xD2,0x70}, {0xAF,0x4E},
+ {0xB2,0x6D}, {0xD6,0x4E}, {0x94,0x54}, {0xD6,0x50},
+ {0xD6,0x4C}, {0x99,0xB8}, {0xD6,0x58}, {0xD6,0x4A},
+ {0xD6,0x57}, {0xB2,0x69}, {0xD6,0x48}, {0xDA,0x5B},
+ {0xD6,0x52}, {0xB2,0x6C}, {0x97,0xE9}, {0xD6,0x53},
+ {0xD6,0x56}, {0xD6,0x5A}, {0xD6,0x4F}, {0x93,0x46},
+ {0xD6,0x54}, {0xB2,0x6A}, {0xB2,0x6B}, {0xD6,0x59},
+ {0xD6,0x4D}, {0xD6,0x49}, {0xD6,0x5B}, {0xD6,0x51},
+ {0xD6,0x55}, {0xD6,0x4B}, {0xB5,0x48}, {0xB5,0x49},
+ {0xDA,0x65}, {0xB5,0x4F}, {0x98,0x63}, {0xDA,0x59},
+ {0xDA,0x62}, {0xDA,0x58}, {0xB5,0x4C}, {0xDA,0x60},
+ {0xDA,0x5E}, {0xDA,0x5F}, {0xB5,0x4A}, {0xDA,0x63},
+ {0x95,0xBC}, {0xFD,0xED}, {0xFD,0xF7}, {0xDA,0x5C},
+ {0xDA,0x5A}, {0xB5,0x4B}, {0xDA,0x5D}, {0xDA,0x61},
+ {0x98,0x70}, {0x96,0xF6}, {0x8E,0xA9}, {0xB5,0x4D},
+ {0xDA,0x64}, {0x94,0x51}, {0x8E,0x43}, {0x8B,0x5A},
+ {0xDE,0x70}, {0xDE,0x77}, {0xDE,0x79}, {0xDE,0xA1},
+ {0xFD,0xEE}, {0xB7,0xDA}, {0xDE,0x6B}, {0xB7,0xD2},
+ {0xFD,0xF0}, {0xDE,0x7A}, {0xB7,0xD7}, {0xDE,0xA2},
+ {0xB7,0xCE}, {0xFD,0xF4}, {0xDE,0x7D}, {0x9B,0xF5},
+ {0xDE,0x6D}, {0xDE,0x7E}, {0xDE,0x6C}, {0xB7,0xDC},
+ {0xDE,0x78}, {0xB7,0xCF}, {0xDE,0xA3}, {0xB7,0xD4},
+ {0xDE,0x71}, {0xB7,0xD9}, {0xDE,0x7C}, {0xDE,0x6F},
+ {0xDE,0x76}, {0xDE,0x72}, {0xDE,0x6E}, {0xB7,0xD1},
+ {0xB7,0xD8}, {0xB7,0xD6}, {0xB7,0xD3}, {0xB7,0xDB},
+ {0xB7,0xD0}, {0xDE,0x75}, {0x97,0x7E}, {0xB7,0xD5},
+ {0xB5,0x4E}, {0xDE,0x7B}, {0x9B,0xD5}, {0xDE,0x73},
+ {0x9A,0xC3}, {0x97,0xC8}, {0xA0,0xDB}, {0x91,0xD0},
+ {0xDE,0x74}, {0x9F,0xE4}, {0xE2,0xC1}, {0x8F,0xDD},
+ {0xBA,0xB4}, {0x91,0xE9}, {0xE2,0xBD}, {0xE2,0xC3},
+ {0xE2,0xBF}, {0xBA,0xB6}, {0xE2,0xBE}, {0xE2,0xC2},
+ {0xE2,0xBA}, {0x98,0xE0}, {0xE2,0xBC}, {0xBA,0xB5},
+ {0x92,0xCA}, {0x98,0x57}, {0xE2,0xC0}, {0xE2,0xBB},
+ {0x8C,0x51}, {0xBA,0xB7}, {0xBA,0xB2}, {0xFD,0xEB},
+ {0xE2,0xC4}, {0x9B,0x49}, {0xBA,0xB3}, {0xE6,0x67},
+ {0xE6,0x64}, {0xE6,0x70}, {0xE6,0x6A}, {0xE6,0x6C},
+ {0xBC,0xF4}, {0xE6,0x66}, {0xE6,0x6E}, {0x9D,0x76},
+ {0x9E,0xAF}, {0xE6,0x6D}, {0xE6,0x6B}, {0xE6,0x71},
+ {0xBC,0xF7}, {0xE6,0x68}, {0xE6,0x6F}, {0xBC,0xF5},
+ {0x9C,0xCC}, {0xE6,0x63}, {0xE6,0x65}, {0xBC,0xF6},
+ {0xE6,0x62}, {0xE6,0x72}, {0xFD,0xEA}, {0xE6,0x69},
+ {0x8D,0xF1}, {0xEA,0x4A}, {0xBF,0x51}, {0xFD,0xFB},
+ {0xEA,0x55}, {0xEA,0x53}, {0xBF,0x4B}, {0xEA,0x49},
+ {0xEA,0x4C}, {0xEA,0x4D}, {0xEA,0x48}, {0xBF,0x55},
+ {0xBF,0x56}, {0xEA,0x47}, {0xEA,0x56}, {0xEA,0x51},
+ {0xBF,0x4F}, {0xBF,0x4C}, {0xEA,0x50}, {0xEA,0x4E},
+ {0xBF,0x52}, {0xEA,0x52}, {0xBF,0x4D}, {0x8E,0x53},
+ {0xBF,0x4E}, {0xEA,0x4F}, {0xBF,0x50}, {0xEA,0x4B},
+ {0xEA,0x54}, {0xBF,0x53}, {0xEA,0x57}, {0xEA,0x58},
+ {0xBF,0x54}, {0xFA,0xCF}, {0xC0,0xE7}, {0xC0,0xEE},
+ {0xED,0x5C}, {0xED,0x62}, {0xED,0x60}, {0xC0,0xEA},
+ {0xC0,0xE9}, {0xC0,0xE6}, {0xED,0x5E}, {0x96,0xF9},
+ {0xC0,0xEC}, {0xC0,0xEB}, {0xC0,0xE8}, {0xED,0x61},
+ {0xED,0x5D}, {0xED,0x5F}, {0xC0,0xED}, {0x98,0xBF},
+ {0x9E,0x49}, {0xC2,0x77}, {0xEF,0xFB}, {0xC2,0x74},
+ {0xC2,0x75}, {0xEF,0xFD}, {0xC2,0x76}, {0xEF,0xFA},
+ {0x8C,0xA7}, {0xEF,0xF9}, {0xF2,0x6C}, {0xEF,0xFC},
+ {0xF2,0x6D}, {0xC3,0x7A}, {0xF2,0x6B}, {0x9B,0xCA},
+ {0xF2,0x6A}, {0xF2,0x69}, {0xC3,0x7B}, {0xFD,0xFE},
+ {0x92,0xDC}, {0xC4,0x6C}, {0xF4,0x6A}, {0xF4,0x6B},
+ {0xFE,0x41}, {0x91,0xCC}, {0x91,0xE2}, {0xF5,0xDC},
+ {0xF5,0xDB}, {0xC4,0xEA}, {0xF5,0xDA}, {0xF6,0xEC},
+ {0xF6,0xED}, {0xF7,0xE6}, {0xF8,0xB1}, {0xFE,0x44},
+ {0xF8,0xF6}, {0xF9,0xBC}, {0xC6,0x79}, {0xF9,0xC6},
+ {0xA4,0xF6}, {0x8B,0xD3}, {0xAA,0xA6}, {0xAA,0xA7},
+ {0xFE,0x47}, {0xAC,0xB8}, {0xC0,0xEF}, {0xA4,0xF7},
+ {0xAA,0xA8}, {0xAF,0x52}, {0xB7,0xDD}, {0xA4,0xF8},
+ {0xB2,0x6E}, {0xBA,0xB8}, {0xC9,0x62}, {0xFE,0x48},
+ {0xCF,0xB7}, {0xD2,0x7D}, {0xE2,0xC5}, {0xC0,0xF0},
+ {0xA4,0xF9}, {0xAA,0xA9}, {0xCF,0xB8}, {0xCF,0xB9},
+ {0xDA,0x66}, {0xB5,0x50}, {0xDE,0xA4}, {0x94,0x55},
+ {0xB7,0xDE}, {0xE2,0xC6}, {0xFE,0x4B}, {0xBC,0xF8},
+ {0xFE,0x4C}, {0xC3,0x7C}, {0xA4,0xFA}, {0xDA,0x67},
+ {0xA4,0xFB}, {0x8D,0xBF}, {0xA6,0xC9}, {0xCA,0x42},
+ {0xA6,0xC8}, {0xA8,0x65}, {0xA8,0x64}, {0xA8,0x63},
+ {0xCB,0x60}, {0x9E,0x78}, {0xAA,0xAA}, {0xAA,0xAB},
+ {0xCD,0x5B}, {0xCF,0xBA}, {0xCF,0xBD}, {0xAC,0xBA},
+ {0xCF,0xBB}, {0xAC,0xB9}, {0xCF,0xBC}, {0xAC,0xBB},
+ {0xD2,0xA2}, {0xD2,0xA1}, {0xD2,0x7E}, {0xAF,0x53},
+ {0xD6,0x5D}, {0xD6,0x5E}, {0xB2,0x6F}, {0xD6,0x5C},
+ {0xD6,0x5F}, {0xB5,0x52}, {0xB2,0x70}, {0xFE,0x51},
+ {0xB5,0x51}, {0xDA,0x6B}, {0xDA,0x6A}, {0x94,0x56},
+ {0xDA,0x68}, {0xDA,0x69}, {0xDA,0x6C}, {0xDE,0xA6},
+ {0xDE,0xA5}, {0xDE,0xA9}, {0x9D,0x61}, {0xDE,0xA8},
+ {0xDE,0xA7}, {0xBA,0xB9}, {0xE2,0xC9}, {0x94,0x57},
+ {0xE2,0xC8}, {0xBA,0xBA}, {0xE2,0xC7}, {0xE6,0x73},
+ {0xE6,0x74}, {0xBC,0xF9}, {0xEA,0x59}, {0xEA,0x5A},
+ {0x99,0x66}, {0xF2,0x72}, {0xC3,0x7D}, {0xF2,0x71},
+ {0xF2,0x70}, {0xF2,0x6E}, {0xF2,0x6F}, {0xC4,0xEB},
+ {0xF4,0x6C}, {0xF6,0xEE}, {0xF8,0xF7}, {0xA4,0xFC},
+ {0x8B,0xD5}, {0xC9,0xA5}, {0xA5,0xC7}, {0xC9,0xA6},
+ {0xA0,0x69}, {0xCA,0x43}, {0xCA,0x44}, {0xCB,0x66},
+ {0xCB,0x62}, {0xCB,0x61}, {0xAA,0xAC}, {0xCB,0x65},
+ {0xA8,0x67}, {0xCB,0x63}, {0xA8,0x66}, {0xCB,0x67},
+ {0xCB,0x64}, {0xCD,0x5F}, {0xCF,0xBE}, {0xCD,0x5D},
+ {0xCD,0x64}, {0x98,0xB4}, {0xAA,0xAD}, {0xAA,0xB0},
+ {0xCD,0x65}, {0xCD,0x61}, {0xCD,0x62}, {0xCD,0x5C},
+ {0xAA,0xAF}, {0xCD,0x5E}, {0xAA,0xAE}, {0xCD,0x63},
+ {0xCD,0x60}, {0xCF,0xC2}, {0xAC,0xBD}, {0xAC,0xBE},
+ {0xA0,0x49}, {0xCF,0xC5}, {0xCF,0xBF}, {0xCF,0xC4},
+ {0xCF,0xC0}, {0xAC,0xBC}, {0xCF,0xC3}, {0xCF,0xC1},
+ {0xD2,0xA8}, {0xD2,0xA5}, {0xD2,0xA7}, {0xAF,0x58},
+ {0xAF,0x57}, {0xAF,0x55}, {0xD2,0xA4}, {0xD2,0xA9},
+ {0xAF,0x54}, {0xAF,0x56}, {0xD2,0xA6}, {0xD6,0x67},
+ {0xD2,0xA3}, {0xD2,0xAA}, {0xA0,0x4C}, {0x9E,0x65},
+ {0xD6,0x62}, {0xD6,0x66}, {0xD6,0x65}, {0xDA,0x6E},
+ {0xDA,0x79}, {0xD6,0x68}, {0x98,0xB5}, {0xD6,0x63},
+ {0xDA,0x6D}, {0xB2,0x74}, {0xB2,0x73}, {0xD6,0x61},
+ {0xD6,0x64}, {0xB2,0x75}, {0xB2,0x72}, {0xB2,0x71},
+ {0xD6,0x60}, {0xD6,0x69}, {0xDA,0x70}, {0xDA,0x77},
+ {0xB5,0x54}, {0xDA,0x76}, {0xDA,0x73}, {0xFE,0x58},
+ {0xB5,0x56}, {0x99,0x75}, {0xFE,0x53}, {0xA0,0x65},
+ {0xDA,0x75}, {0xFE,0x59}, {0xDA,0x6F}, {0xDA,0x71},
+ {0xDA,0x74}, {0xDA,0x72}, {0xB5,0x55}, {0xDA,0x78},
+ {0xB5,0x53}, {0xB7,0xDF}, {0x98,0xB7}, {0x98,0xB8},
+ {0xDE,0xAD}, {0xDE,0xAC}, {0xDE,0xAA}, {0xB7,0xE2},
+ {0xB7,0xE1}, {0xDE,0xAE}, {0x98,0xBA}, {0xDE,0xAB},
+ {0xE2,0xCA}, {0xBA,0xBB}, {0xB7,0xE0}, {0x98,0xBB},
+ {0xDE,0xB0}, {0xDE,0xAF}, {0xE2,0xCD}, {0xE2,0xCB},
+ {0xBC,0xFA}, {0x9F,0xBC}, {0xBA,0xBC}, {0xE2,0xCC},
+ {0xE6,0x76}, {0xBC,0xFB}, {0xE6,0x75}, {0xE6,0x7E},
+ {0xE6,0x7D}, {0xE6,0x7B}, {0xE6,0x7A}, {0xE6,0x77},
+ {0xE6,0x78}, {0xE6,0x79}, {0xE6,0x7C}, {0xE6,0xA1},
+ {0xEA,0x5F}, {0xEA,0x5C}, {0xEA,0x5D}, {0xBF,0x57},
+ {0xEA,0x5B}, {0xEA,0x61}, {0xEA,0x60}, {0xEA,0x5E},
+ {0xED,0x64}, {0xED,0x65}, {0xC0,0xF1}, {0xA0,0x4A},
+ {0xC0,0xF2}, {0xED,0x63}, {0x9E,0xC7}, {0xC2,0x79},
+ {0xEF,0xFE}, {0xC2,0x78}, {0xC3,0x7E}, {0xC3,0xA1},
+ {0xC4,0x6D}, {0xF4,0x6E}, {0xF4,0x6D}, {0xF5,0xDD},
+ {0xF6,0xEF}, {0xC5,0x7A}, {0xF7,0xE8}, {0xF7,0xE7},
+ {0xF7,0xE9}, {0xA5,0xC8}, {0xCF,0xC6}, {0xAF,0x59},
+ {0xB2,0x76}, {0xD6,0x6A}, {0xA5,0xC9}, {0xC9,0xA7},
+ {0xA4,0xFD}, {0x8C,0xA9}, {0xCA,0x45}, {0x98,0xAE},
+ {0xCB,0x6C}, {0xCB,0x6A}, {0xCB,0x6B}, {0xCB,0x68},
+ {0xA8,0x68}, {0xCB,0x69}, {0x92,0xD6}, {0xFA,0xE1},
+ {0xCD,0x6D}, {0x91,0xD4}, {0xAA,0xB3}, {0xCD,0x6B},
+ {0xCD,0x67}, {0xCD,0x6A}, {0xCD,0x66}, {0xAA,0xB5},
+ {0xCD,0x69}, {0xFA,0xDE}, {0xAA,0xB2}, {0xAA,0xB1},
+ {0xFE,0x5B}, {0xAA,0xB4}, {0xCD,0x6C}, {0xCD,0x68},
+ {0xAC,0xC2}, {0xAC,0xC5}, {0xCF,0xCE}, {0xCF,0xCD},
+ {0xCF,0xCC}, {0xAC,0xBF}, {0xCF,0xD5}, {0xCF,0xCB},
+ {0x8C,0x53}, {0xAC,0xC1}, {0xD2,0xAF}, {0xCF,0xD2},
+ {0xCF,0xD0}, {0xAC,0xC4}, {0xCF,0xC8}, {0xCF,0xD3},
+ {0xCF,0xCA}, {0xCF,0xD4}, {0xCF,0xD1}, {0xCF,0xC9},
+ {0xFE,0x5E}, {0xAC,0xC0}, {0xCF,0xD6}, {0xCF,0xC7},
+ {0xAC,0xC3}, {0xFB,0xD7}, {0xFE,0x5A}, {0x94,0xC5},
+ {0xD2,0xB4}, {0xD2,0xAB}, {0xD2,0xB6}, {0xFA,0xCA},
+ {0xD2,0xAE}, {0xD2,0xB9}, {0xD2,0xBA}, {0xD2,0xAC},
+ {0xD2,0xB8}, {0xD2,0xB5}, {0xD2,0xB3}, {0xD2,0xB7},
+ {0xAF,0x5F}, {0xAF,0x5D}, {0x98,0xC1}, {0x97,0x5C},
+ {0xD2,0xB1}, {0xFE,0x74}, {0xD2,0xAD}, {0x97,0x73},
+ {0xD2,0xB0}, {0xD2,0xBB}, {0xD2,0xB2}, {0xAF,0x5E},
+ {0xCF,0xCF}, {0xAF,0x5A}, {0xAF,0x5C}, {0xFA,0x46},
+ {0x97,0x64}, {0xD6,0x78}, {0xD6,0x6D}, {0xD6,0x6B},
+ {0xFE,0x68}, {0xD6,0x6C}, {0x96,0x4E}, {0xD6,0x73},
+ {0x97,0x65}, {0xD6,0x74}, {0xD6,0x70}, {0xB2,0x7B},
+ {0xD6,0x75}, {0xD6,0x72}, {0xD6,0x6F}, {0x8C,0x5A},
+ {0xB2,0x79}, {0xD6,0x6E}, {0xB2,0x77}, {0xB2,0x7A},
+ {0xD6,0x71}, {0xD6,0x79}, {0xAF,0x5B}, {0xB2,0x78},
+ {0xD6,0x77}, {0xD6,0x76}, {0xB2,0x7C}, {0x89,0xA1},
+ {0x95,0xFA}, {0x92,0xD4}, {0xFE,0x69}, {0xDA,0x7E},
+ {0xFB,0x45}, {0x98,0xC8}, {0xDA,0xA1}, {0xB5,0x60},
+ {0x90,0xEF}, {0xDA,0xA7}, {0x98,0xC9}, {0x98,0xCA},
+ {0xDA,0xA9}, {0xDA,0xA2}, {0xB5,0x5A}, {0xDA,0xA6},
+ {0xDA,0xA5}, {0xB5,0x5B}, {0xB5,0x61}, {0xB5,0x62},
+ {0xDA,0xA8}, {0xB5,0x58}, {0xDA,0x7D}, {0xDA,0x7B},
+ {0xDA,0xA3}, {0xDA,0x7A}, {0xB5,0x5F}, {0xDA,0x7C},
+ {0xDA,0xA4}, {0xDA,0xAA}, {0xB5,0x59}, {0xB5,0x5E},
+ {0xB5,0x5C}, {0xB5,0x5D}, {0x94,0x6D}, {0x94,0xB7},
+ {0xFE,0x6C}, {0xB5,0x57}, {0x94,0x6B}, {0xB7,0xE9},
+ {0xDE,0xB7}, {0xB7,0xE8}, {0xDE,0xBB}, {0x92,0xFC},
+ {0xDE,0xB1}, {0x95,0xEB}, {0xDE,0xBC}, {0xFE,0x73},
+ {0x97,0x6E}, {0xFE,0x5F}, {0xDE,0xB2}, {0xDE,0xB3},
+ {0xDE,0xBD}, {0xDE,0xBA}, {0xDE,0xB8}, {0xDE,0xB9},
+ {0xDE,0xB5}, {0xDE,0xB4}, {0xFD,0xBD}, {0xDE,0xBE},
+ {0xB7,0xE5}, {0x92,0xD5}, {0xDE,0xB6}, {0xB7,0xEA},
+ {0xB7,0xE4}, {0xB7,0xEB}, {0xB7,0xEC}, {0xFE,0xB9},
+ {0xB7,0xE7}, {0xB7,0xE6}, {0xFE,0x71}, {0xE2,0xCE},
+ {0xBA,0xBE}, {0xBA,0xBD}, {0xFB,0xBB}, {0xE2,0xD3},
+ {0x94,0x7A}, {0xBC,0xFC}, {0xBA,0xBF}, {0x95,0xFB},
+ {0xFE,0x77}, {0xBA,0xC1}, {0xE2,0xD4}, {0xB7,0xE3},
+ {0xBA,0xC0}, {0xE2,0xD0}, {0xE2,0xD2}, {0xE2,0xCF},
+ {0xFE,0x79}, {0xE2,0xD1}, {0xFE,0x75}, {0xE6,0xAB},
+ {0x94,0x5D}, {0xE6,0xAA}, {0xE6,0xA7}, {0xBD,0x40},
+ {0xEA,0x62}, {0xBD,0x41}, {0xE6,0xA6}, {0xFE,0x7C},
+ {0xBC,0xFE}, {0xE6,0xA8}, {0xE6,0xA5}, {0xE6,0xA2},
+ {0xE6,0xA9}, {0xE6,0xA3}, {0xE6,0xA4}, {0xBC,0xFD},
+ {0x93,0x44}, {0x8E,0xA6}, {0xED,0x69}, {0xEA,0x66},
+ {0xEA,0x65}, {0xEA,0x67}, {0xED,0x66}, {0xBF,0x5A},
+ {0x92,0xD3}, {0xEA,0x63}, {0x94,0xB8}, {0xBF,0x58},
+ {0xBF,0x5C}, {0xBF,0x5B}, {0xEA,0x64}, {0xEA,0x68},
+ {0xBF,0x59}, {0xFC,0x71}, {0xED,0x6D}, {0xC0,0xF5},
+ {0xC2,0x7A}, {0xC0,0xF6}, {0xC0,0xF3}, {0xED,0x6A},
+ {0xED,0x68}, {0xED,0x6B}, {0xED,0x6E}, {0xC0,0xF4},
+ {0xED,0x6C}, {0xED,0x67}, {0x97,0x5E}, {0xF0,0x42},
+ {0xF0,0x45}, {0xF2,0x75}, {0xF0,0x40}, {0x8C,0xAD},
+ {0xF4,0x6F}, {0xF0,0x46}, {0xC3,0xA2}, {0xF0,0x44},
+ {0xC2,0x7B}, {0xF0,0x41}, {0xF0,0x43}, {0xF0,0x47},
+ {0xF2,0x76}, {0xF2,0x74}, {0xFE,0xA7}, {0xC3,0xA3},
+ {0xF2,0x73}, {0x94,0x6A}, {0xC4,0x6E}, {0x93,0xE3},
+ {0x98,0xCF}, {0xC4,0xED}, {0xF6,0xF1}, {0xC4,0xEC},
+ {0xF6,0xF3}, {0xF6,0xF0}, {0xF6,0xF2}, {0xC5,0xD0},
+ {0xF8,0xB2}, {0xA5,0xCA}, {0xCD,0x6E}, {0xD2,0xBC},
+ {0xD2,0xBD}, {0xB2,0x7D}, {0xDE,0xBF}, {0xBF,0x5D},
+ {0xC3,0xA4}, {0xC5,0x7B}, {0xF8,0xB3}, {0xA5,0xCB},
+ {0xA0,0xD9}, {0xCD,0x6F}, {0xA2,0x60}, {0xCF,0xD7},
+ {0xCF,0xD8}, {0xA0,0xBF}, {0xA0,0x4D}, {0xA0,0xB8},
+ {0xD2,0xBE}, {0xD2,0xBF}, {0xB2,0x7E}, {0xB2,0xA1},
+ {0xA0,0xCE}, {0xDA,0xAB}, {0xDE,0xC2}, {0xDE,0xC1},
+ {0xDE,0xC0}, {0xE2,0xD5}, {0xE2,0xD6}, {0xE2,0xD7},
+ {0xBA,0xC2}, {0xA0,0xB7}, {0xE6,0xAD}, {0xE6,0xAC},
+ {0xEA,0x69}, {0xBF,0x5E}, {0xBF,0x5F}, {0xFE,0xA9},
+ {0xED,0x72}, {0xED,0x6F}, {0xED,0x70}, {0xED,0x71},
+ {0xF0,0x49}, {0xF0,0x48}, {0xC2,0x7C}, {0xF2,0x77},
+ {0xF5,0xDE}, {0xA5,0xCC}, {0x89,0xC3}, {0xAC,0xC6},
+ {0xB2,0xA2}, {0xDE,0xC3}, {0xFE,0xAB}, {0xA5,0xCD},
+ {0xD2,0xC0}, {0xB2,0xA3}, {0xB5,0x63}, {0xB5,0x64},
+ {0xA5,0xCE}, {0xA5,0xCF}, {0xCA,0x46}, {0xA8,0x6A},
+ {0xA8,0x69}, {0xAC,0xC7}, {0xCF,0xD9}, {0xDA,0xAC},
+ {0xA5,0xD0}, {0xA5,0xD1}, {0xA5,0xD2}, {0xA5,0xD3},
+ {0x9D,0xF4}, {0x89,0x6D}, {0xA8,0x6B}, {0xA8,0x6C},
+ {0xCB,0x6E}, {0xCB,0x6D}, {0x9C,0x7B}, {0xAA,0xB6},
+ {0xCD,0x72}, {0xCD,0x70}, {0xCD,0x71}, {0x98,0xD2},
+ {0x9F,0xA9}, {0xCF,0xDA}, {0xCF,0xDB}, {0xFE,0xB2},
+ {0xAC,0xCB}, {0xAC,0xC9}, {0xFE,0xB1}, {0xAC,0xCA},
+ {0xAC,0xC8}, {0x97,0xD9}, {0xA0,0xC4}, {0xAF,0x60},
+ {0x94,0x76}, {0xAF,0x64}, {0xAF,0x63}, {0xD2,0xC1},
+ {0xAF,0x62}, {0xAF,0x61}, {0xD2,0xC2}, {0x99,0x78},
+ {0xB2,0xA6}, {0xD6,0x7B}, {0xD6,0x7A}, {0xB2,0xA4},
+ {0xB2,0xA5}, {0xFE,0xB3}, {0xB5,0x66}, {0xB5,0x65},
+ {0xDA,0xAE}, {0x98,0xD3}, {0xFE,0xB4}, {0xDA,0xAD},
+ {0xB2,0xA7}, {0x98,0xD4}, {0xB7,0xED}, {0xDE,0xC5},
+ {0xB7,0xEE}, {0xDE,0xC4}, {0x9F,0xB9}, {0xE2,0xD8},
+ {0xE6,0xAE}, {0xBD,0x42}, {0xEA,0x6A}, {0x94,0x71},
+ {0xED,0x73}, {0xC3,0xA6}, {0xC3,0xA5}, {0xC5,0x7C},
+ {0xA5,0xD4}, {0xCD,0x73}, {0x98,0xD5}, {0xFE,0xB8},
+ {0xB2,0xA8}, {0xE2,0xD9}, {0xBA,0xC3}, {0xC6,0xD4},
+ {0xCB,0x6F}, {0xCB,0x70}, {0xCD,0x74}, {0xAA,0xB8},
+ {0xAA,0xB9}, {0xAA,0xB7}, {0xFE,0xBA}, {0xAC,0xCF},
+ {0xAC,0xD0}, {0xAC,0xCD}, {0xAC,0xCE}, {0xCF,0xDC},
+ {0xCF,0xDD}, {0xAC,0xCC}, {0xD2,0xC3}, {0x9E,0x5C},
+ {0xAF,0x68}, {0xAF,0x69}, {0xFE,0xBB}, {0xB2,0xAB},
+ {0xD2,0xC9}, {0xAF,0x6E}, {0xAF,0x6C}, {0xD2,0xCA},
+ {0xD2,0xC5}, {0xAF,0x6B}, {0xAF,0x6A}, {0xAF,0x65},
+ {0xD2,0xC8}, {0xD2,0xC7}, {0xD2,0xC4}, {0xAF,0x6D},
+ {0xA0,0x44}, {0xD2,0xC6}, {0xAF,0x66}, {0xAF,0x67},
+ {0x98,0xD7}, {0xB2,0xAC}, {0xD6,0xA1}, {0xD6,0xA2},
+ {0xB2,0xAD}, {0xD6,0x7C}, {0xD6,0x7E}, {0xD6,0xA4},
+ {0xD6,0xA3}, {0xD6,0x7D}, {0xB2,0xA9}, {0xB2,0xAA},
+ {0xDA,0xB6}, {0xB5,0x6B}, {0xB5,0x6A}, {0xDA,0xB0},
+ {0xB5,0x68}, {0x98,0xD8}, {0xDA,0xB3}, {0xB5,0x6C},
+ {0xDA,0xB4}, {0xB5,0x6D}, {0xDA,0xB1}, {0xB5,0x67},
+ {0xB5,0x69}, {0xDA,0xB5}, {0xDA,0xB2}, {0xDA,0xAF},
+ {0xDE,0xD2}, {0xDE,0xC7}, {0xB7,0xF0}, {0xB7,0xF3},
+ {0xB7,0xF2}, {0xB7,0xF7}, {0xB7,0xF6}, {0xDE,0xD3},
+ {0xDE,0xD1}, {0xDE,0xCA}, {0xDE,0xCE}, {0xDE,0xCD},
+ {0xB7,0xF4}, {0xDE,0xD0}, {0xDE,0xCC}, {0xDE,0xD4},
+ {0xDE,0xCB}, {0xB7,0xF5}, {0xB7,0xEF}, {0xB7,0xF1},
+ {0xFE,0xBC}, {0xDE,0xC9}, {0x9F,0xFE}, {0xE2,0xDB},
+ {0xBA,0xC7}, {0xE2,0xDF}, {0xBA,0xC6}, {0xE2,0xDC},
+ {0xBA,0xC5}, {0xDE,0xC8}, {0xDE,0xCF}, {0xE2,0xDE},
+ {0xBA,0xC8}, {0xE2,0xE0}, {0xE2,0xDD}, {0xE2,0xDA},
+ {0xE6,0xB1}, {0xE6,0xB5}, {0xE6,0xB7}, {0xE6,0xB3},
+ {0xE6,0xB2}, {0xE6,0xB0}, {0xBD,0x45}, {0xBD,0x43},
+ {0xBD,0x48}, {0xBD,0x49}, {0xE6,0xB4}, {0xBD,0x46},
+ {0xE6,0xAF}, {0xBD,0x47}, {0xBA,0xC4}, {0xE6,0xB6},
+ {0xBD,0x44}, {0xFE,0xBD}, {0xEA,0x6C}, {0xEA,0x6B},
+ {0xEA,0x73}, {0xEA,0x6D}, {0xEA,0x72}, {0xEA,0x6F},
+ {0xBF,0x60}, {0xEA,0x71}, {0xBF,0x61}, {0xBF,0x62},
+ {0x9D,0xDD}, {0xEA,0x70}, {0xEA,0x6E}, {0x9E,0xE1},
+ {0xC0,0xF8}, {0xED,0x74}, {0xC0,0xF7}, {0xED,0x77},
+ {0xED,0x75}, {0xED,0x76}, {0xC0,0xF9}, {0x98,0xDA},
+ {0x9D,0xDF}, {0xFE,0xBF}, {0xF0,0x4D}, {0xFE,0xBE},
+ {0xC2,0xA1}, {0xF0,0x4E}, {0x9E,0xEB}, {0xC2,0x7D},
+ {0xF0,0x4F}, {0xC2,0x7E}, {0xF0,0x4C}, {0xF0,0x50},
+ {0xF0,0x4A}, {0xC3,0xA7}, {0xF2,0x78}, {0xC3,0xA8},
+ {0xC4,0x6F}, {0xF0,0x4B}, {0xC4,0x70}, {0x9E,0x59},
+ {0xA0,0x5C}, {0xC4,0xEE}, {0xF5,0xDF}, {0xC5,0x7E},
+ {0xF6,0xF4}, {0xC5,0x7D}, {0xFE,0xC0}, {0xF7,0xEA},
+ {0xC5,0xF5}, {0xC5,0xF6}, {0x94,0x77}, {0x98,0xDC},
+ {0xF9,0xCC}, {0xFE,0xC1}, {0xAC,0xD1}, {0xCF,0xDE},
+ {0x98,0xDE}, {0xB5,0x6E}, {0xB5,0x6F}, {0xA5,0xD5},
+ {0xA6,0xCA}, {0xCA,0x47}, {0xCB,0x71}, {0xA8,0x6D},
+ {0xAA,0xBA}, {0xAC,0xD2}, {0xAC,0xD3}, {0xAC,0xD4},
+ {0xD6,0xA6}, {0xD2,0xCB}, {0xAF,0x6F}, {0xB2,0xAE},
+ {0xD6,0xA5}, {0xFE,0xC3}, {0xDA,0xB8}, {0xB5,0x71},
+ {0xDA,0xB7}, {0xB5,0x70}, {0xDE,0xD5}, {0xBD,0x4A},
+ {0xE6,0xBB}, {0xE6,0xB8}, {0xE6,0xB9}, {0xE6,0xBA},
+ {0xFE,0xC8}, {0xED,0x78}, {0xFE,0xC9}, {0xF0,0x51},
+ {0xF4,0x71}, {0xF4,0x70}, {0xF6,0xF5}, {0xA5,0xD6},
+ {0xCD,0x75}, {0xAF,0x70}, {0xB5,0x72}, {0xDE,0xD6},
+ {0xFE,0xCA}, {0xE2,0xE1}, {0xBD,0x4B}, {0xEA,0x74},
+ {0xF0,0x52}, {0xF4,0x72}, {0xA5,0xD7}, {0xAA,0xBB},
+ {0xAC,0xD7}, {0xCF,0xDF}, {0xAC,0xD8}, {0xAC,0xD6},
+ {0xAC,0xD5}, {0xD2,0xCC}, {0xAF,0x71}, {0xFE,0xCB},
+ {0xAF,0x72}, {0xAF,0x73}, {0xB2,0xB0}, {0xD6,0xA7},
+ {0xB2,0xAF}, {0x9F,0xC2}, {0x8C,0x6B}, {0xDA,0xB9},
+ {0xB2,0xB1}, {0xB5,0x73}, {0xDE,0xD7}, {0xB7,0xF8},
+ {0xB7,0xF9}, {0xBA,0xC9}, {0xBA,0xCA}, {0xBD,0x4C},
+ {0xBF,0x64}, {0xEA,0x75}, {0xBF,0x63}, {0xED,0x79},
+ {0xC0,0xFA}, {0xF0,0x53}, {0xF4,0x73}, {0xA5,0xD8},
+ {0xA8,0x6E}, {0xCD,0x78}, {0xCD,0x77}, {0xAA,0xBC},
+ {0xCD,0x76}, {0xAA,0xBD}, {0xCD,0x79}, {0xCF,0xE5},
+ {0xAC,0xDB}, {0xAC,0xDA}, {0xCF,0xE7}, {0xCF,0xE6},
+ {0xAC,0xDF}, {0xAC,0xDE}, {0xAC,0xD9}, {0xCF,0xE1},
+ {0xCF,0xE2}, {0xCF,0xE3}, {0xAC,0xE0}, {0xCF,0xE0},
+ {0xAC,0xDC}, {0xCF,0xE4}, {0xAC,0xDD}, {0x98,0xC4},
+ {0x94,0xB0}, {0x94,0xB1}, {0xD2,0xCF}, {0xD2,0xD3},
+ {0xD2,0xD1}, {0xD2,0xD0}, {0xD2,0xD4}, {0xD2,0xD5},
+ {0xD2,0xD6}, {0xD2,0xCE}, {0xD2,0xCD}, {0xFE,0xD1},
+ {0xAF,0x75}, {0xAF,0x76}, {0xD2,0xD7}, {0xD2,0xD2},
+ {0xA0,0xC1}, {0xD6,0xB0}, {0xFE,0xD2}, {0xD2,0xD8},
+ {0xAF,0x77}, {0xAF,0x74}, {0xA0,0xCD}, {0xD6,0xAA},
+ {0xD6,0xA9}, {0xD6,0xAB}, {0xD6,0xAC}, {0xD6,0xAE},
+ {0xD6,0xAD}, {0xD6,0xB2}, {0xB2,0xB5}, {0xB2,0xB2},
+ {0xB2,0xB6}, {0xD6,0xA8}, {0xB2,0xB7}, {0xD6,0xB1},
+ {0xB2,0xB4}, {0xD6,0xAF}, {0xB2,0xB3}, {0xFE,0xD3},
+ {0x98,0xE5}, {0xDA,0xBC}, {0xDA,0xBE}, {0xDA,0xBA},
+ {0xDA,0xBB}, {0xDA,0xBF}, {0xDA,0xC1}, {0xDA,0xC2},
+ {0xDA,0xBD}, {0xDA,0xC0}, {0xB5,0x74}, {0xDE,0xDB},
+ {0xDE,0xE0}, {0xDE,0xD8}, {0xDE,0xDC}, {0xFE,0xD6},
+ {0xDE,0xE1}, {0xDE,0xDD}, {0xB7,0xFA}, {0xB8,0x43},
+ {0xB7,0xFD}, {0xDE,0xD9}, {0xDE,0xDA}, {0xBA,0xCE},
+ {0xB8,0x46}, {0xB7,0xFE}, {0xB8,0x44}, {0xB7,0xFC},
+ {0xDE,0xDF}, {0xB8,0x45}, {0xDE,0xDE}, {0xB8,0x41},
+ {0xB7,0xFB}, {0xB8,0x42}, {0xDE,0xE2}, {0xE2,0xE6},
+ {0xE2,0xE8}, {0x91,0xE4}, {0x8F,0xC7}, {0x94,0xAE},
+ {0xB8,0x40}, {0x8A,0x4F}, {0x94,0xB2}, {0xE2,0xE3},
+ {0xBA,0xCC}, {0xE2,0xE9}, {0xBA,0xCD}, {0xE2,0xE7},
+ {0xE2,0xE2}, {0xE2,0xE5}, {0xE2,0xEA}, {0xBA,0xCB},
+ {0xE2,0xE4}, {0xBD,0x4E}, {0xE6,0xBF}, {0xE6,0xBE},
+ {0xBD,0x51}, {0xBD,0x4F}, {0xE6,0xBC}, {0xBD,0x4D},
+ {0xE6,0xBD}, {0xBD,0x50}, {0x8F,0xD4}, {0xEA,0x7D},
+ {0xEA,0xA1}, {0x98,0xEA}, {0xEA,0x7E}, {0xEA,0x76},
+ {0xEA,0x7A}, {0xEA,0x79}, {0xEA,0x77}, {0xBF,0x66},
+ {0xBF,0x67}, {0xBF,0x65}, {0xEA,0x78}, {0xEA,0x7B},
+ {0xEA,0x7C}, {0xBF,0x68}, {0xC1,0x40}, {0xED,0xA3},
+ {0xC0,0xFC}, {0xED,0x7B}, {0xC0,0xFE}, {0xC1,0x41},
+ {0xFE,0xD8}, {0xC0,0xFD}, {0xED,0xA2}, {0xED,0x7C},
+ {0xC0,0xFB}, {0xED,0xA1}, {0xED,0x7A}, {0xED,0x7E},
+ {0xED,0x7D}, {0x9D,0xE0}, {0xF0,0x55}, {0xC2,0xA4},
+ {0xC2,0xA5}, {0xC2,0xA2}, {0x98,0xEE}, {0xC2,0xA3},
+ {0xF0,0x54}, {0x95,0xC4}, {0xF2,0x7B}, {0xFC,0xE8},
+ {0xC3,0xA9}, {0xF2,0x79}, {0xF2,0x7A}, {0x98,0xEF},
+ {0xF4,0x74}, {0xF4,0x77}, {0xF4,0x75}, {0xF4,0x76},
+ {0xF5,0xE0}, {0xC4,0xEF}, {0xF7,0xEB}, {0xF8,0xB4},
+ {0xC5,0xF7}, {0xF8,0xF8}, {0xF8,0xF9}, {0xC6,0x66},
+ {0xA5,0xD9}, {0xAC,0xE1}, {0x8C,0x6E}, {0xDA,0xC3},
+ {0xDE,0xE3}, {0xA5,0xDA}, {0xA8,0x6F}, {0xAA,0xBE},
+ {0xFA,0xD8}, {0xCF,0xE8}, {0xCF,0xE9}, {0xAF,0x78},
+ {0xDA,0xC4}, {0xB5,0x75}, {0xB8,0x47}, {0xC1,0x42},
+ {0xED,0xA4}, {0xF2,0x7C}, {0xF4,0x78}, {0xA5,0xDB},
+ {0xFE,0xDC}, {0xCD,0xA1}, {0xCD,0x7A}, {0xCD,0x7C},
+ {0xCD,0x7E}, {0xCD,0x7D}, {0xCD,0x7B}, {0xAA,0xBF},
+ {0xA0,0xAE}, {0xAC,0xE2}, {0xCF,0xF2}, {0xCF,0xED},
+ {0xCF,0xEA}, {0x9D,0x4C}, {0xCF,0xF1}, {0xAC,0xE4},
+ {0xAC,0xE5}, {0xCF,0xF0}, {0xCF,0xEF}, {0xCF,0xEE},
+ {0xCF,0xEB}, {0xCF,0xEC}, {0xCF,0xF3}, {0xAC,0xE3},
+ {0x98,0xF1}, {0x98,0xF3}, {0xAF,0x7C}, {0x94,0xC1},
+ {0xAF,0xA4}, {0xAF,0xA3}, {0xD2,0xE1}, {0xD2,0xDB},
+ {0xD2,0xD9}, {0xAF,0xA1}, {0xD6,0xB9}, {0xAF,0x7A},
+ {0xD2,0xDE}, {0xD2,0xE2}, {0xD2,0xE4}, {0xD2,0xE0},
+ {0xD2,0xDA}, {0xAF,0xA2}, {0xD2,0xDF}, {0xD2,0xDD},
+ {0xAF,0x79}, {0xD2,0xE5}, {0xAF,0xA5}, {0xD2,0xE3},
+ {0xAF,0x7D}, {0xD2,0xDC}, {0xAF,0x7E}, {0xAF,0x7B},
+ {0x98,0xF5}, {0xFA,0x4F}, {0x96,0xE2}, {0x94,0x50},
+ {0xB2,0xB9}, {0x96,0xA2}, {0xD6,0xBA}, {0x98,0xF6},
+ {0xD6,0xB3}, {0xD6,0xB5}, {0xD6,0xB7}, {0x96,0xE5},
+ {0xD6,0xB8}, {0xD6,0xB6}, {0xB2,0xBA}, {0xD6,0xBB},
+ {0x98,0xF7}, {0xD6,0xB4}, {0xA0,0x46}, {0x96,0xE3},
+ {0xDA,0xC8}, {0xB5,0x76}, {0xDA,0xD0}, {0xDA,0xC5},
+ {0xDA,0xD1}, {0xDA,0xC6}, {0xDA,0xC7}, {0x98,0xF8},
+ {0xDA,0xCF}, {0xDA,0xCE}, {0xDA,0xCB}, {0xB2,0xB8},
+ {0xB5,0x77}, {0xDA,0xC9}, {0xDA,0xCC}, {0xB5,0x78},
+ {0xDA,0xCD}, {0xDA,0xCA}, {0xDE,0xEE}, {0x9E,0xE4},
+ {0xDE,0xF2}, {0xB8,0x4E}, {0xE2,0xF0}, {0xB8,0x51},
+ {0xDE,0xF0}, {0xF9,0xD6}, {0xDE,0xED}, {0xDE,0xE8},
+ {0xDE,0xEA}, {0xDE,0xEB}, {0xDE,0xE4}, {0x94,0xC3},
+ {0xB8,0x4D}, {0xB8,0x4C}, {0x94,0xC2}, {0xB8,0x48},
+ {0xDE,0xE7}, {0xB8,0x4F}, {0xB8,0x50}, {0xDE,0xE6},
+ {0xDE,0xE9}, {0xDE,0xF1}, {0xB8,0x4A}, {0xB8,0x4B},
+ {0xDE,0xEF}, {0xDE,0xE5}, {0xE2,0xF2}, {0xBA,0xD0},
+ {0xE2,0xF4}, {0xDE,0xEC}, {0xE2,0xF6}, {0xBA,0xD4},
+ {0xE2,0xF7}, {0xE2,0xF3}, {0xBA,0xD1}, {0xE2,0xEF},
+ {0xBA,0xD3}, {0xE2,0xEC}, {0xE2,0xF1}, {0xE2,0xF5},
+ {0xE2,0xEE}, {0xFE,0xE1}, {0xB8,0x49}, {0xFE,0xE9},
+ {0xE2,0xEB}, {0xBA,0xD2}, {0xE2,0xED}, {0x96,0xE4},
+ {0x89,0xAC}, {0x96,0xDB}, {0xBD,0x54}, {0xE6,0xC1},
+ {0xBD,0x58}, {0xBD,0x56}, {0xBA,0xCF}, {0xE6,0xC8},
+ {0xE6,0xC9}, {0xBD,0x53}, {0xFE,0xE2}, {0xE6,0xC7},
+ {0xE6,0xCA}, {0xBD,0x55}, {0xBD,0x52}, {0xE6,0xC3},
+ {0xE6,0xC0}, {0xE6,0xC5}, {0xE6,0xC2}, {0xBD,0x59},
+ {0xE6,0xC4}, {0x94,0xC4}, {0xFE,0xE3}, {0xE6,0xC6},
+ {0xBD,0x57}, {0xFE,0xE7}, {0x9F,0xFB}, {0xBF,0x6A},
+ {0xEA,0xA8}, {0xEA,0xA2}, {0xEA,0xA6}, {0xEA,0xAC},
+ {0xEA,0xAD}, {0xEA,0xA9}, {0xEA,0xAA}, {0xEA,0xA7},
+ {0x8C,0x59}, {0xEA,0xA4}, {0xBF,0x6C}, {0xBF,0x69},
+ {0xEA,0xA3}, {0xEA,0xA5}, {0xBF,0x6B}, {0xEA,0xAB},
+ {0x93,0xC9}, {0xC1,0x46}, {0x94,0xE8}, {0xFB,0x56},
+ {0xED,0xAA}, {0xED,0xA5}, {0xC1,0x45}, {0x90,0xC5},
+ {0xC1,0x43}, {0xED,0xAC}, {0xC1,0x44}, {0xED,0xA8},
+ {0xED,0xA9}, {0xED,0xA6}, {0xED,0xAD}, {0xF0,0x56},
+ {0xC1,0x47}, {0xED,0xA7}, {0xED,0xAE}, {0xED,0xAB},
+ {0xA0,0xA8}, {0xF0,0x5A}, {0xF0,0x57}, {0xC2,0xA6},
+ {0xF0,0x5B}, {0xF0,0x5D}, {0xF0,0x5C}, {0xF0,0x58},
+ {0xF0,0x59}, {0xF2,0xA3}, {0xC3,0xAA}, {0xF2,0x7E},
+ {0xF2,0xA2}, {0xF2,0x7D}, {0xF2,0xA4}, {0xF2,0xA1},
+ {0xF4,0x7A}, {0xF4,0x7D}, {0xF4,0x79}, {0xC4,0x71},
+ {0xF4,0x7B}, {0xF4,0x7C}, {0xF4,0x7E}, {0xC4,0x72},
+ {0xC4,0x74}, {0xC4,0x73}, {0xF5,0xE1}, {0xFE,0xE5},
+ {0xF5,0xE3}, {0xF5,0xE2}, {0x98,0xFD}, {0x98,0xFB},
+ {0xFE,0xE8}, {0xF6,0xF6}, {0x8E,0xBF}, {0xF8,0xB5},
+ {0xF8,0xFA}, {0xA5,0xDC}, {0x8B,0xD8}, {0xFE,0xF7},
+ {0xCB,0x72}, {0xAA,0xC0}, {0xCD,0xA3}, {0xAA,0xC1},
+ {0xAA,0xC2}, {0xCD,0xA2}, {0xCF,0xF8}, {0xCF,0xF7},
+ {0xAC,0xE6}, {0xAC,0xE9}, {0xAC,0xE8}, {0xAC,0xE7},
+ {0xCF,0xF4}, {0xCF,0xF6}, {0xCF,0xF5}, {0xD2,0xE8},
+ {0xAF,0xA7}, {0xD2,0xEC}, {0xD2,0xEB}, {0xD2,0xEA},
+ {0xD2,0xE6}, {0xAF,0xA6}, {0xAF,0xAA}, {0xAF,0xAD},
+ {0x8F,0x68}, {0x94,0xC6}, {0xAF,0xAE}, {0xD2,0xE7},
+ {0xD2,0xE9}, {0xAF,0xAC}, {0xAF,0xAB}, {0xAF,0xA9},
+ {0xAF,0xA8}, {0xD6,0xC2}, {0x9D,0xEA}, {0xD6,0xC0},
+ {0xD6,0xBC}, {0xB2,0xBB}, {0xD6,0xBD}, {0xB2,0xBC},
+ {0xD6,0xBE}, {0xD6,0xBF}, {0xD6,0xC1}, {0xB2,0xBD},
+ {0xDA,0xD5}, {0xFC,0x69}, {0xDA,0xD4}, {0xDA,0xD3},
+ {0xDA,0xD2}, {0xDE,0xF6}, {0xB8,0x52}, {0xDE,0xF3},
+ {0xDE,0xF5}, {0x9C,0xDA}, {0xB8,0x53}, {0xFE,0xF3},
+ {0xB8,0x54}, {0xDE,0xF4}, {0x9C,0x72}, {0xFE,0xF0},
+ {0x89,0xC9}, {0xE3,0x41}, {0xE2,0xF9}, {0xE2,0xFA},
+ {0xBA,0xD7}, {0xBA,0xD5}, {0xBA,0xD6}, {0xE3,0x43},
+ {0x99,0x41}, {0xE3,0x42}, {0xE2,0xFE}, {0xE2,0xFD},
+ {0xE2,0xFC}, {0xE2,0xFB}, {0xE3,0x40}, {0xE2,0xF8},
+ {0x99,0x42}, {0xE6,0xCB}, {0xE6,0xD0}, {0xE6,0xCE},
+ {0xFE,0xF5}, {0x91,0xD7}, {0xE6,0xCD}, {0xE6,0xCC},
+ {0xE6,0xCF}, {0xEA,0xAE}, {0x94,0xCC}, {0xBF,0x6D},
+ {0xC1,0x48}, {0xED,0xB0}, {0xFE,0xF8}, {0xC1,0x49},
+ {0xED,0xAF}, {0xF0,0x5F}, {0xF0,0x5E}, {0xC2,0xA7},
+ {0xF2,0xA5}, {0xC3,0xAB}, {0xF4,0xA1}, {0xC5,0xA1},
+ {0xF6,0xF7}, {0xF8,0xB7}, {0xF8,0xB6}, {0xC9,0xA8},
+ {0xAC,0xEA}, {0xAC,0xEB}, {0xD6,0xC3}, {0xB8,0x56},
+ {0xA5,0xDD}, {0xA8,0x72}, {0xA8,0x71}, {0xA8,0x70},
+ {0x97,0xA8}, {0xCD,0xA4}, {0xFE,0xFC}, {0xAA,0xC4},
+ {0xAA,0xC3}, {0xAC,0xEE}, {0xFD,0xBF}, {0xCF,0xFA},
+ {0xCF,0xFD}, {0xCF,0xFB}, {0xAC,0xEC}, {0xAC,0xED},
+ {0xFE,0xFE}, {0xCF,0xF9}, {0xCF,0xFC}, {0xAF,0xB5},
+ {0xD2,0xF3}, {0xD2,0xF5}, {0xD2,0xF4}, {0xAF,0xB2},
+ {0xD2,0xEF}, {0x96,0xD1}, {0xAF,0xB0}, {0xAF,0xAF},
+ {0xAF,0xB3}, {0xAF,0xB1}, {0xAF,0xB4}, {0xD2,0xF2},
+ {0xD2,0xED}, {0xD2,0xEE}, {0xD2,0xF1}, {0xD2,0xF0},
+ {0x94,0xD5}, {0x94,0xD0}, {0xD6,0xC6}, {0xD6,0xC7},
+ {0xD6,0xC5}, {0xD6,0xC4}, {0xB2,0xBE}, {0xB5,0x7D},
+ {0xDA,0xD6}, {0xDA,0xD8}, {0xDA,0xDA}, {0xB5,0x7C},
+ {0x99,0x44}, {0xB5,0x7A}, {0xDA,0xD7}, {0xB5,0x7B},
+ {0xDA,0xD9}, {0xB5,0x79}, {0xDF,0x41}, {0xDE,0xF7},
+ {0xDE,0xFA}, {0xDE,0xFE}, {0xB8,0x5A}, {0xDE,0xFC},
+ {0xDE,0xFB}, {0xDE,0xF8}, {0xDE,0xF9}, {0xB8,0x58},
+ {0xDF,0x40}, {0xB8,0x57}, {0xB8,0x5C}, {0xB8,0x5B},
+ {0xB8,0x59}, {0xDE,0xFD}, {0xE3,0x49}, {0xE3,0x48},
+ {0x8C,0x63}, {0xE3,0x44}, {0xA0,0xB3}, {0xBA,0xD8},
+ {0xE3,0x47}, {0xE3,0x46}, {0xBA,0xD9}, {0xBD,0x5E},
+ {0xE6,0xD2}, {0x94,0xCF}, {0xBD,0x5F}, {0xBD,0x5B},
+ {0xBD,0x5D}, {0x9F,0xFA}, {0xBD,0x5A}, {0xBD,0x5C},
+ {0x91,0xE5}, {0xEA,0xAF}, {0x9C,0x6A}, {0xBF,0x70},
+ {0xEA,0xB1}, {0xEA,0xB0}, {0x8E,0x49}, {0xE3,0x45},
+ {0xBF,0x72}, {0xBF,0x71}, {0xBF,0x6E}, {0xBF,0x6F},
+ {0xED,0xB5}, {0xED,0xB3}, {0xC1,0x4A}, {0xED,0xB4},
+ {0xED,0xB6}, {0xED,0xB2}, {0xED,0xB1}, {0xF0,0x60},
+ {0xC2,0xAA}, {0xC2,0xA8}, {0xC2,0xA9}, {0x8E,0x4C},
+ {0xF2,0xA6}, {0xF2,0xA7}, {0xC3,0xAD}, {0xC3,0xAC},
+ {0xF4,0xA3}, {0xF4,0xA4}, {0xF4,0xA2}, {0xF6,0xF8},
+ {0xF6,0xF9}, {0xA5,0xDE}, {0xCA,0x48}, {0xA8,0x73},
+ {0xCD,0xA5}, {0xAA,0xC6}, {0xAA,0xC5}, {0xCD,0xA6},
+ {0x8E,0x4D}, {0xD0,0x40}, {0xAC,0xEF}, {0xCF,0xFE},
+ {0xAC,0xF0}, {0x9A,0x73}, {0xAF,0xB6}, {0xD2,0xF8},
+ {0xD2,0xF6}, {0xD2,0xFC}, {0xAF,0xB7}, {0xD2,0xF7},
+ {0xD2,0xFB}, {0xD2,0xF9}, {0xD2,0xFA}, {0xD6,0xC8},
+ {0xD6,0xCA}, {0x99,0x47}, {0xB2,0xBF}, {0x8C,0xB1},
+ {0xD6,0xC9}, {0xB2,0xC0}, {0xB5,0xA2}, {0xB5,0xA1},
+ {0xB5,0x7E}, {0xDA,0xDB}, {0xDF,0x44}, {0xB8,0x5D},
+ {0xB8,0x5E}, {0xDF,0x43}, {0xDF,0x42}, {0xE3,0x4A},
+ {0xBA,0xDB}, {0xBA,0xDA}, {0xE3,0x4B}, {0xE3,0x4C},
+ {0xBD,0x61}, {0xBD,0x60}, {0x8E,0x50}, {0xEA,0xB5},
+ {0xE6,0xD3}, {0xE6,0xD5}, {0xE6,0xD4}, {0xEA,0xB4},
+ {0xEA,0xB2}, {0xEA,0xB6}, {0xEA,0xB3}, {0xBF,0x73},
+ {0x8E,0x4F}, {0x99,0x49}, {0xED,0xB7}, {0xC1,0x4B},
+ {0xED,0xB8}, {0xED,0xB9}, {0x8E,0x51}, {0x8E,0x52},
+ {0xC2,0xAB}, {0xC2,0xAC}, {0xC4,0x75}, {0x9A,0xB2},
+ {0x89,0xA5}, {0xC5,0xD1}, {0xA5,0xDF}, {0x99,0x4C},
+ {0xD0,0x41}, {0x9F,0xF8}, {0xD2,0xFD}, {0xAF,0xB8},
+ {0x8E,0x56}, {0x99,0x4D}, {0x91,0xCA}, {0x8E,0x57},
+ {0xB3,0xBA}, {0xB3,0xB9}, {0x94,0xE1}, {0xB5,0xA4},
+ {0xDA,0xDD}, {0xB5,0xA3}, {0xDA,0xDC}, {0x90,0x47},
+ {0x8F,0xD8}, {0x8E,0x58}, {0xDF,0x45}, {0xBA,0xDC},
+ {0xE3,0x4D}, {0xBA,0xDD}, {0xC4,0x76}, {0xF4,0xA5},
+ {0xA6,0xCB}, {0xAA,0xC7}, {0xCD,0xA7}, {0xAC,0xF2},
+ {0x94,0xEB}, {0xAC,0xF1}, {0xD0,0x42}, {0xD0,0x43},
+ {0xD3,0x40}, {0xD3,0x42}, {0xAF,0xB9}, {0xD3,0x44},
+ {0xD3,0x47}, {0xD3,0x45}, {0x8E,0x5C}, {0x95,0x53},
+ {0xD3,0x46}, {0xD3,0x43}, {0xD2,0xFE}, {0xAF,0xBA},
+ {0xD3,0x48}, {0xD3,0x41}, {0x9F,0xE5}, {0xD6,0xD3},
+ {0xB2,0xC6}, {0xD6,0xDC}, {0xB2,0xC3}, {0xD6,0xD5},
+ {0xB2,0xC7}, {0x9F,0x56}, {0xB2,0xC1}, {0xD6,0xD0},
+ {0xD6,0xDD}, {0xD6,0xD1}, {0xD6,0xCE}, {0xB2,0xC5},
+ {0x95,0x4F}, {0xB2,0xC2}, {0x8E,0x5E}, {0xD6,0xD4},
+ {0xD6,0xD7}, {0xB2,0xC4}, {0xD6,0xD8}, {0xB2,0xC8},
+ {0xD6,0xD9}, {0xD6,0xCF}, {0xD6,0xD6}, {0xD6,0xDA},
+ {0xD6,0xD2}, {0xD6,0xCD}, {0xD6,0xCB}, {0xD6,0xDB},
+ {0x99,0x6A}, {0xDA,0xDF}, {0xDA,0xE4}, {0x9C,0x64},
+ {0x9C,0xD9}, {0xDA,0xE0}, {0xDA,0xE6}, {0xB5,0xA7},
+ {0xD6,0xCC}, {0xDA,0xE1}, {0xB5,0xA5}, {0xDA,0xDE},
+ {0xB5,0xAC}, {0xDA,0xE2}, {0xB5,0xAB}, {0xDA,0xE3},
+ {0xB5,0xAD}, {0xB5,0xA8}, {0xB5,0xAE}, {0xB5,0xA9},
+ {0xB5,0xAA}, {0x8E,0x5D}, {0xB5,0xA6}, {0xDA,0xE5},
+ {0xB8,0x61}, {0xDF,0x50}, {0x99,0x50}, {0xDF,0x53},
+ {0xDF,0x47}, {0xDF,0x4C}, {0xDF,0x46}, {0xB8,0x63},
+ {0xDF,0x4A}, {0x99,0x51}, {0xDF,0x48}, {0xB8,0x62},
+ {0x8E,0x62}, {0xDF,0x4F}, {0xDF,0x4E}, {0xDF,0x4B},
+ {0xDF,0x4D}, {0xDF,0x49}, {0xBA,0xE1}, {0xDF,0x52},
+ {0xB8,0x5F}, {0xDF,0x51}, {0x99,0x52}, {0xE3,0x5D},
+ {0xBA,0xE8}, {0xE3,0x58}, {0xBA,0xE7}, {0xE3,0x4E},
+ {0xE3,0x50}, {0xBA,0xE0}, {0xE3,0x55}, {0xE3,0x54},
+ {0xE3,0x57}, {0xBA,0xE5}, {0xE3,0x52}, {0xE3,0x51},
+ {0x8E,0x68}, {0xBA,0xE4}, {0xBA,0xDF}, {0xE3,0x53},
+ {0xBA,0xE2}, {0xE3,0x59}, {0xE3,0x5B}, {0xE3,0x56},
+ {0xE3,0x4F}, {0xBA,0xE3}, {0xBD,0x69}, {0xBA,0xDE},
+ {0x8E,0x61}, {0x9F,0x59}, {0xE3,0x5C}, {0xE6,0xD9},
+ {0xBD,0x62}, {0xE6,0xDB}, {0xBD,0x63}, {0x8B,0xB3},
+ {0xBD,0x65}, {0xE6,0xDE}, {0xE6,0xD6}, {0xBA,0xE6},
+ {0xE6,0xDC}, {0xE6,0xD8}, {0xB8,0x60}, {0xBD,0x68},
+ {0xBD,0x64}, {0xBD,0x66}, {0xBD,0x67}, {0xBF,0x76},
+ {0xE6,0xDD}, {0xE6,0xD7}, {0xBD,0x6A}, {0xE6,0xDA},
+ {0x9F,0x5D}, {0x8E,0x66}, {0xEA,0xC0}, {0xEA,0xBB},
+ {0xEA,0xC5}, {0xBF,0x74}, {0xEA,0xBD}, {0xBF,0x78},
+ {0xEA,0xC3}, {0xEA,0xBA}, {0xEA,0xB7}, {0xEA,0xC6},
+ {0xC1,0x51}, {0xBF,0x79}, {0xEA,0xC2}, {0xEA,0xB8},
+ {0xBF,0x77}, {0xEA,0xBC}, {0xBF,0x7B}, {0xEA,0xB9},
+ {0xEA,0xBE}, {0xBF,0x7A}, {0xEA,0xC1}, {0xEA,0xC4},
+ {0x8C,0xB2}, {0xED,0xCB}, {0xED,0xCC}, {0xED,0xBC},
+ {0xED,0xC3}, {0xED,0xC1}, {0xC1,0x4F}, {0xED,0xC8},
+ {0xEA,0xBF}, {0x8E,0x6E}, {0xED,0xBF}, {0x9F,0x64},
+ {0xED,0xC9}, {0xC1,0x4E}, {0xED,0xBE}, {0xED,0xBD},
+ {0xED,0xC7}, {0xED,0xC4}, {0xED,0xC6}, {0xED,0xBA},
+ {0xED,0xCA}, {0xC1,0x4C}, {0xED,0xC5}, {0xED,0xCE},
+ {0xED,0xC2}, {0xC1,0x50}, {0xC1,0x4D}, {0xED,0xC0},
+ {0xED,0xBB}, {0xED,0xCD}, {0xBF,0x75}, {0x99,0x53},
+ {0xFA,0xB8}, {0xF0,0x63}, {0x99,0x54}, {0xF0,0x61},
+ {0xF0,0x67}, {0xC2,0xB0}, {0xF0,0x65}, {0xF0,0x64},
+ {0xC2,0xB2}, {0xF0,0x6A}, {0xC2,0xB1}, {0xF0,0x6B},
+ {0xF0,0x68}, {0xC2,0xAE}, {0xF0,0x69}, {0xF0,0x62},
+ {0xC2,0xAF}, {0xC2,0xAD}, {0xF2,0xAB}, {0xF0,0x66},
+ {0xF0,0x6C}, {0xF2,0xA8}, {0x8E,0x70}, {0xC3,0xB2},
+ {0xC3,0xB0}, {0xF2,0xAA}, {0xF2,0xAC}, {0xF2,0xA9},
+ {0xC3,0xB1}, {0xC3,0xAE}, {0xC3,0xAF}, {0xC3,0xB3},
+ {0x9F,0x61}, {0xC4,0x78}, {0x8E,0x72}, {0xF4,0xAA},
+ {0xF4,0xA9}, {0xF4,0xA7}, {0xF4,0xA6}, {0xF4,0xA8},
+ {0xC4,0x77}, {0xC4,0x79}, {0xC4,0xF0}, {0xA0,0x6B},
+ {0xF5,0xE5}, {0xF5,0xE4}, {0x9F,0x40}, {0xF6,0xFA},
+ {0xF6,0xFC}, {0xF6,0xFE}, {0xF6,0xFD}, {0xF6,0xFB},
+ {0x94,0xED}, {0xC5,0xA3}, {0xC5,0xA2}, {0xC5,0xD3},
+ {0xC5,0xD2}, {0xC5,0xD4}, {0xF7,0xED}, {0xF7,0xEC},
+ {0xF8,0xFB}, {0xF8,0xB8}, {0xF8,0xFC}, {0xC6,0x58},
+ {0x94,0xEE}, {0xC6,0x59}, {0xF9,0x6D}, {0x9F,0xBD},
+ {0xC6,0x7E}, {0xA6,0xCC}, {0x8E,0x7B}, {0xCD,0xA8},
+ {0xD0,0x45}, {0xD0,0x46}, {0xD0,0x44}, {0x99,0x57},
+ {0x94,0xF7}, {0xAC,0xF3}, {0x9F,0x5F}, {0xD0,0x47},
+ {0xD0,0x48}, {0xD0,0x49}, {0x8E,0x73}, {0xD3,0x49},
+ {0xD3,0x4F}, {0x9F,0x62}, {0xD3,0x4D}, {0xAF,0xBB},
+ {0xD3,0x4B}, {0xD3,0x4C}, {0xD3,0x4E}, {0x94,0xF6},
+ {0xD3,0x4A}, {0xB2,0xC9}, {0xD6,0xDE}, {0xB2,0xCB},
+ {0xD6,0xE0}, {0xB2,0xCA}, {0xD6,0xDF}, {0x99,0x58},
+ {0xDA,0xE8}, {0xB5,0xAF}, {0xDA,0xEA}, {0xDA,0xE7},
+ {0xD6,0xE1}, {0xB5,0xB0}, {0x8E,0x75}, {0xF9,0xDB},
+ {0xDA,0xE9}, {0x90,0x72}, {0x94,0xF8}, {0xDF,0x56},
+ {0xB8,0x64}, {0xDF,0x54}, {0xB8,0x65}, {0xDF,0x55},
+ {0xB8,0x66}, {0x99,0x5A}, {0xBA,0xE9}, {0xE3,0x61},
+ {0xE3,0x5E}, {0xE3,0x60}, {0xBA,0xEA}, {0xBA,0xEB},
+ {0xE3,0x5F}, {0xA0,0xB0}, {0x8C,0xB3}, {0xE6,0xDF},
+ {0x8E,0x79}, {0xE6,0xE0}, {0x8E,0x78}, {0xBD,0x6B},
+ {0xE6,0xE2}, {0xE6,0xE1}, {0x94,0xF3}, {0xA2,0x61},
+ {0xEA,0xCA}, {0xEA,0xCB}, {0xEA,0xC7}, {0x98,0xAF},
+ {0xEA,0xC8}, {0xBF,0x7C}, {0xBF,0x7D}, {0xEA,0xC9},
+ {0xC1,0x57}, {0xA0,0xB2}, {0xC1,0x53}, {0xC1,0x58},
+ {0xC1,0x54}, {0xC1,0x56}, {0xC1,0x52}, {0xC1,0x55},
+ {0x8E,0x7A}, {0xC2,0xB3}, {0xED,0xCF}, {0xF2,0xAE},
+ {0xF2,0xAD}, {0x99,0x5C}, {0xF4,0xAB}, {0xC4,0x7A},
+ {0xC4,0x7B}, {0xF7,0x41}, {0xF5,0xE6}, {0x8E,0x7C},
+ {0xF7,0x40}, {0x8E,0x7D}, {0xF8,0xFD}, {0xF9,0xA4},
+ {0xA6,0xCD}, {0x8B,0xD9}, {0xA8,0x74}, {0x89,0xA2},
+ {0xCD,0xA9}, {0xAA,0xC8}, {0xAC,0xF6}, {0xD0,0x4C},
+ {0xAC,0xF4}, {0xD0,0x4A}, {0xAC,0xF9}, {0xAC,0xF5},
+ {0xAC,0xFA}, {0xAC,0xF8}, {0xD0,0x4B}, {0xAC,0xF7},
+ {0xAF,0xBF}, {0xAF,0xBE}, {0xD3,0x5A}, {0xAF,0xC7},
+ {0xD3,0x53}, {0xD3,0x59}, {0xAF,0xC3}, {0xD3,0x52},
+ {0xD3,0x58}, {0xD3,0x56}, {0xAF,0xC2}, {0xAF,0xC4},
+ {0xD3,0x55}, {0xAF,0xBD}, {0xD3,0x54}, {0xAF,0xC8},
+ {0xAF,0xC5}, {0xAF,0xC9}, {0xAF,0xC6}, {0xD3,0x51},
+ {0xD3,0x50}, {0xD3,0x57}, {0xAF,0xC0}, {0xAF,0xBC},
+ {0xAF,0xC1}, {0x9E,0xD7}, {0xD6,0xF0}, {0xD6,0xE9},
+ {0xB5,0xB5}, {0xD6,0xE8}, {0xB2,0xCF}, {0xB2,0xD6},
+ {0xB2,0xD3}, {0xB2,0xD9}, {0xB2,0xD8}, {0xB2,0xD4},
+ {0xD6,0xE2}, {0xD6,0xE5}, {0xD6,0xE4}, {0xB2,0xD0},
+ {0xD6,0xE6}, {0xD6,0xEF}, {0xB2,0xD1}, {0xD6,0xE3},
+ {0xD6,0xEC}, {0xD6,0xED}, {0xB2,0xD2}, {0xD6,0xEA},
+ {0xB2,0xD7}, {0xB2,0xCD}, {0xB2,0xD5}, {0xD6,0xE7},
+ {0xB2,0xCC}, {0xD6,0xEB}, {0xD6,0xEE}, {0xA0,0xB6},
+ {0xDA,0xFB}, {0xDA,0xF2}, {0xB5,0xB2}, {0xDA,0xF9},
+ {0xDA,0xF6}, {0xDA,0xEE}, {0xDA,0xF7}, {0xB5,0xB4},
+ {0xDA,0xEF}, {0xDA,0xEB}, {0x9E,0x42}, {0xB8,0x6C},
+ {0xDA,0xF4}, {0x8E,0xA4}, {0xB5,0xB1}, {0xDA,0xFA},
+ {0xB5,0xB8}, {0xB5,0xBA}, {0xDA,0xED}, {0xB5,0xB9},
+ {0xDA,0xF0}, {0xB5,0xB3}, {0xDA,0xF8}, {0xDA,0xF1},
+ {0xDA,0xF5}, {0xDA,0xF3}, {0xB5,0xB6}, {0xDA,0xEC},
+ {0xB5,0xBB}, {0xB2,0xCE}, {0xB5,0xB7}, {0xB5,0xBC},
+ {0xB8,0x68}, {0xDF,0x5D}, {0xDF,0x5F}, {0xDF,0x61},
+ {0xDF,0x65}, {0xDF,0x5B}, {0xDF,0x59}, {0xB8,0x6A},
+ {0xDF,0x60}, {0xDF,0x64}, {0xDF,0x5C}, {0xDF,0x58},
+ {0xDF,0x57}, {0x8E,0xA7}, {0x8C,0x76}, {0xDF,0x62},
+ {0xDF,0x5A}, {0xDF,0x5E}, {0xB8,0x6B}, {0xB8,0x69},
+ {0xDF,0x66}, {0xB8,0x67}, {0xDF,0x63}, {0xE3,0x72},
+ {0x95,0x42}, {0xBA,0xEE}, {0xE3,0x6A}, {0xBD,0x78},
+ {0xE3,0x74}, {0xBA,0xF1}, {0xE3,0x78}, {0xBA,0xF7},
+ {0xE3,0x65}, {0x98,0x7D}, {0xE3,0x75}, {0xE3,0x62},
+ {0x97,0x55}, {0xE3,0x77}, {0xE3,0x66}, {0x8E,0xA8},
+ {0xBA,0xFE}, {0xBA,0xFB}, {0xE3,0x76}, {0xE3,0x70},
+ {0xBA,0xED}, {0xBA,0xF5}, {0xBA,0xF4}, {0x8E,0xAA},
+ {0xBA,0xF3}, {0xBA,0xF9}, {0xE3,0x63}, {0xBA,0xFA},
+ {0xE3,0x71}, {0xBA,0xF6}, {0xBA,0xEC}, {0xE3,0x73},
+ {0xBA,0xEF}, {0xBA,0xF0}, {0xBA,0xF8}, {0xE3,0x68},
+ {0xE3,0x67}, {0xE3,0x64}, {0xE3,0x6C}, {0xE3,0x69},
+ {0xE3,0x6D}, {0xBA,0xFD}, {0xE3,0x79}, {0xBA,0xF2},
+ {0xE3,0x6E}, {0xE3,0x6F}, {0x89,0xA3}, {0xE3,0x6B},
+ {0x99,0x60}, {0x99,0x62}, {0xBA,0xFC}, {0x94,0xFC},
+ {0x99,0x61}, {0xE6,0xE7}, {0xBD,0x70}, {0xBD,0x79},
+ {0xBD,0x75}, {0xE6,0xE4}, {0x94,0xFA}, {0xBD,0x72},
+ {0xBD,0x76}, {0xE6,0xF0}, {0xBD,0x6C}, {0xE6,0xE8},
+ {0xBD,0x74}, {0x8E,0xAE}, {0x8E,0xB2}, {0xE6,0xEB},
+ {0xE6,0xE6}, {0xBD,0x73}, {0xBD,0x77}, {0xE6,0xE5},
+ {0xBD,0x71}, {0xE6,0xEF}, {0xBD,0x6E}, {0xE6,0xEE},
+ {0xE6,0xED}, {0xBD,0x7A}, {0xE5,0x72}, {0xBD,0x6D},
+ {0x8E,0xB0}, {0xE6,0xEC}, {0xE6,0xE3}, {0xBD,0x7B},
+ {0xE6,0xEA}, {0xBD,0x6F}, {0x99,0x63}, {0x97,0xAA},
+ {0xE6,0xE9}, {0x94,0xFB}, {0xBF,0xA2}, {0xBF,0xA7},
+ {0xBF,0x7E}, {0xEA,0xD8}, {0xEA,0xCF}, {0xEA,0xDB},
+ {0xEA,0xD3}, {0xEA,0xD9}, {0xBF,0xA8}, {0xBF,0xA1},
+ {0xEA,0xCC}, {0xEA,0xD2}, {0xEA,0xDC}, {0xEA,0xD5},
+ {0xEA,0xDA}, {0xEA,0xCE}, {0xEA,0xD6}, {0xBF,0xA3},
+ {0xEA,0xD4}, {0xBF,0xA6}, {0xBF,0xA5}, {0xEA,0xD0},
+ {0xEA,0xD1}, {0xEA,0xCD}, {0xEA,0xD7}, {0xBF,0xA4},
+ {0xEA,0xDE}, {0xEA,0xDD}, {0x8E,0xBB}, {0xED,0xDA},
+ {0xED,0xD6}, {0xC1,0x5F}, {0xED,0xD0}, {0xC1,0x59},
+ {0xC1,0x69}, {0xED,0xDC}, {0xC1,0x61}, {0xC1,0x5D},
+ {0xED,0xD3}, {0xC1,0x64}, {0xC1,0x67}, {0xED,0xDE},
+ {0xC1,0x5C}, {0xED,0xD5}, {0xC1,0x65}, {0xED,0xE0},
+ {0xED,0xDD}, {0xED,0xD1}, {0xC1,0x60}, {0xC1,0x5A},
+ {0xC1,0x68}, {0xED,0xD8}, {0xC1,0x63}, {0xED,0xD2},
+ {0xC1,0x5E}, {0xED,0xDF}, {0xC1,0x62}, {0xC1,0x5B},
+ {0xED,0xD9}, {0xC1,0x66}, {0xED,0xD7}, {0xED,0xDB},
+ {0xF0,0x6E}, {0xF0,0x74}, {0xC2,0xB9}, {0xF0,0x77},
+ {0xC2,0xB4}, {0xC2,0xB5}, {0xF0,0x6F}, {0xF0,0x76},
+ {0xF0,0x71}, {0xC2,0xBA}, {0xC2,0xB7}, {0x8C,0xDC},
+ {0xF0,0x6D}, {0xC2,0xB6}, {0xF0,0x73}, {0xF0,0x75},
+ {0xC2,0xB8}, {0xF0,0x72}, {0xF0,0x70}, {0x98,0x76},
+ {0x8E,0xA1}, {0xF2,0xB8}, {0xC3,0xB7}, {0xC3,0xB8},
+ {0xC3,0xB4}, {0x8C,0xB4}, {0xC3,0xB5}, {0x8E,0xB7},
+ {0xF2,0xB4}, {0xF2,0xB2}, {0xF2,0xB6}, {0xC3,0xBA},
+ {0xF2,0xB7}, {0xF2,0xB0}, {0xF2,0xAF}, {0xF2,0xB3},
+ {0xF2,0xB1}, {0xC3,0xB6}, {0xF2,0xB5}, {0xF4,0xAC},
+ {0xC4,0x7E}, {0xC4,0x7D}, {0xF4,0xAD}, {0x9D,0xA6},
+ {0xF4,0xAF}, {0xF4,0xAE}, {0xC4,0xA1}, {0xF5,0xEB},
+ {0xF5,0xE8}, {0xF5,0xE9}, {0xF5,0xE7}, {0xF5,0xEA},
+ {0xC4,0xF2}, {0xF5,0xEC}, {0x9E,0xB0}, {0xC4,0xF1},
+ {0xF7,0x42}, {0x8E,0xB8}, {0xC5,0xD5}, {0xC5,0xD7},
+ {0xF7,0xEE}, {0xC5,0xD6}, {0xF8,0xB9}, {0xF9,0x40},
+ {0xF9,0x42}, {0xF8,0xFE}, {0xF9,0x41}, {0xC6,0x6C},
+ {0x9D,0x70}, {0x89,0x6E}, {0x89,0x6F}, {0x89,0x70},
+ {0x89,0x71}, {0x89,0x72}, {0x89,0x73}, {0x89,0x74},
+ {0xA6,0xCE}, {0x89,0x75}, {0xAC,0xFB}, {0xD2,0x6F},
+ {0xAF,0xCA}, {0xB2,0xDA}, {0xDA,0xFC}, {0xDA,0xFD},
+ {0x8E,0xBC}, {0x8E,0xBD}, {0xEA,0xDF}, {0xC1,0x6A},
+ {0xED,0xE1}, {0x8E,0xBE}, {0xC2,0xBB}, {0x9D,0xD1},
+ {0xF2,0xBA}, {0xF2,0xB9}, {0xC4,0xA2}, {0xF5,0xED},
+ {0x94,0xFD}, {0xF7,0x43}, {0xC5,0xF8}, {0xCA,0x49},
+ {0x8B,0xD7}, {0x8B,0xDA}, {0xAA,0xC9}, {0xA8,0x75},
+ {0xD0,0x4D}, {0xD3,0x60}, {0xD3,0x5B}, {0xD3,0x5F},
+ {0xD3,0x5D}, {0xAF,0xCB}, {0xD3,0x5E}, {0xD3,0x5C},
+ {0xD6,0xF1}, {0xDA,0xFE}, {0xDB,0x40}, {0xDF,0x69},
+ {0xDF,0x6A}, {0xB8,0x6E}, {0xB8,0x6F}, {0xDF,0x68},
+ {0xDF,0x6B}, {0xDF,0x67}, {0xB8,0x6D}, {0xBB,0x40},
+ {0xA0,0xE2}, {0xB8,0x70}, {0xE3,0x7A}, {0xBD,0x7C},
+ {0xE6,0xF1}, {0xBD,0x7D}, {0x9F,0xE9}, {0xBF,0xA9},
+ {0xEA,0xE2}, {0xEA,0xE0}, {0xEA,0xE1}, {0xED,0xE4},
+ {0xED,0xE3}, {0xED,0xE2}, {0xF2,0xBB}, {0xC3,0xB9},
+ {0xF2,0xBC}, {0xF7,0x44}, {0xC5,0xF9}, {0xF8,0xBA},
+ {0xA6,0xCF}, {0xAA,0xCB}, {0xAA,0xCA}, {0xD0,0x4F},
+ {0xAC,0xFC}, {0xFD,0xA8}, {0xD0,0x4E}, {0xD3,0x62},
+ {0x8A,0xE7}, {0xAF,0xCC}, {0xD6,0xF2}, {0xD3,0x61},
+ {0x8E,0xC2}, {0xB2,0xDC}, {0xD6,0xF5}, {0xD6,0xF3},
+ {0xD6,0xF4}, {0xB2,0xDB}, {0xDB,0x42}, {0xDB,0x43},
+ {0xDB,0x41}, {0x8E,0xC4}, {0xB8,0x73}, {0xDF,0x6D},
+ {0xDF,0x6C}, {0xDF,0x6E}, {0xB8,0x72}, {0xB8,0x71},
+ {0xE6,0xF2}, {0xE6,0xF4}, {0x99,0x64}, {0xBD,0x7E},
+ {0xE6,0xF3}, {0xEA,0xE3}, {0xBF,0xAA}, {0xF0,0x79},
+ {0x99,0x65}, {0xF0,0x78}, {0xC3,0xBB}, {0xF2,0xBD},
+ {0xC3,0xBD}, {0xC3,0xBC}, {0xF4,0xB0}, {0xF5,0xEE},
+ {0xC4,0xF3}, {0xA6,0xD0}, {0xD0,0x50}, {0xAC,0xFD},
+ {0xD3,0x65}, {0xAF,0xCE}, {0xD3,0x64}, {0xD3,0x63},
+ {0xAF,0xCD}, {0xD6,0xFB}, {0xD6,0xFD}, {0xD6,0xF6},
+ {0xD6,0xF7}, {0xB2,0xDD}, {0xD6,0xF8}, {0xB2,0xDE},
+ {0xD6,0xFC}, {0xD6,0xF9}, {0xD6,0xFA}, {0xB2,0xDF},
+ {0xB5,0xBE}, {0xB5,0xBF}, {0xDB,0x44}, {0xDF,0x6F},
+ {0xDF,0x70}, {0x95,0x4E}, {0xE3,0x7E}, {0xBB,0x43},
+ {0xBB,0x41}, {0xBB,0x42}, {0xE3,0x7B}, {0xE3,0x7C},
+ {0xE3,0x7D}, {0xE6,0xF9}, {0x98,0xB3}, {0xE6,0xFA},
+ {0xBD,0xA1}, {0xE6,0xF7}, {0xE6,0xF6}, {0xE6,0xF8},
+ {0xE6,0xF5}, {0xBF,0xAD}, {0xEA,0xE4}, {0xBF,0xAB},
+ {0xBF,0xAC}, {0xED,0xE6}, {0xC1,0x6B}, {0xED,0xE5},
+ {0xEF,0xA8}, {0xF0,0x7A}, {0xF0,0x7B}, {0xC2,0xBC},
+ {0x8E,0xCB}, {0xC2,0xBD}, {0xC1,0x6C}, {0xF2,0xBE},
+ {0xF2,0xBF}, {0xF4,0xB1}, {0xC4,0xA3}, {0xA6,0xD1},
+ {0x8B,0xDF}, {0xA6,0xD2}, {0xAC,0xFE}, {0xAA,0xCC},
+ {0xAF,0xCF}, {0xD0,0x51}, {0x8E,0xCE}, {0xB5,0xC0},
+ {0xA6,0xD3}, {0xAD,0x41}, {0xD0,0x52}, {0xD0,0x53},
+ {0xAD,0x40}, {0xAD,0x42}, {0xA6,0xD4}, {0xD0,0x54},
+ {0xAF,0xD1}, {0xD3,0x66}, {0xAF,0xD3}, {0xAF,0xD0},
+ {0xAF,0xD2}, {0xD7,0x41}, {0xB2,0xE0}, {0x8E,0xCF},
+ {0xD7,0x40}, {0xD6,0xFE}, {0x99,0x68}, {0xDF,0x71},
+ {0xE3,0xA1}, {0x99,0x69}, {0xBD,0xA2}, {0xBF,0xAE},
+ {0xEA,0xE6}, {0xEA,0xE5}, {0xED,0xE7}, {0x99,0x6B},
+ {0x8E,0xD1}, {0xF5,0xEF}, {0x99,0x6C}, {0xA6,0xD5},
+ {0xCB,0x73}, {0xCD,0xAA}, {0xAD,0x43}, {0xD0,0x55},
+ {0xD3,0x68}, {0x8E,0xD4}, {0x8E,0xD5}, {0xAF,0xD4},
+ {0xD3,0x67}, {0xAF,0xD5}, {0xD7,0x43}, {0xB2,0xE2},
+ {0xD7,0x42}, {0xD7,0x44}, {0xB2,0xE1}, {0xDB,0x46},
+ {0xDB,0x47}, {0xDB,0x45}, {0xB5,0xC1}, {0x99,0x6D},
+ {0xB8,0x74}, {0xB8,0x75}, {0xBB,0x45}, {0xA0,0xBE},
+ {0xE3,0xA3}, {0xE3,0xA2}, {0xBB,0x44}, {0x8E,0xD6},
+ {0xA0,0xBC}, {0xA0,0xB5}, {0xE6,0xFB}, {0xA0,0xB4},
+ {0xE6,0xFC}, {0xEA,0xE7}, {0xC1,0x70}, {0xC1,0x6F},
+ {0xC1,0x6D}, {0xC1,0x6E}, {0xC1,0x71}, {0xF0,0x7C},
+ {0xC2,0xBF}, {0xC2,0xBE}, {0xF2,0xC0}, {0xF4,0xB2},
+ {0xC5,0xA5}, {0xC5,0xA4}, {0xA6,0xD6}, {0x8B,0xE0},
+ {0xD1,0xFB}, {0xB8,0x77}, {0xB5,0xC2}, {0xB8,0x76},
+ {0xBB,0x46}, {0xA6,0xD7}, {0xC9,0xA9}, {0xA6,0xD8},
+ {0xA6,0xD9}, {0xCD,0xAB}, {0xCB,0x76}, {0xCB,0x77},
+ {0xA8,0x77}, {0xCB,0x74}, {0xA8,0x76}, {0xA8,0x79},
+ {0xCB,0x75}, {0xA8,0x7B}, {0xA8,0x7A}, {0xCB,0x78},
+ {0xA8,0x78}, {0x89,0xB5}, {0xAA,0xD1}, {0xAA,0xCF},
+ {0xCD,0xAD}, {0xAA,0xCE}, {0x8E,0xDD}, {0xAA,0xD3},
+ {0xAA,0xD5}, {0xAA,0xD2}, {0xCD,0xB0}, {0xCD,0xAC},
+ {0xAA,0xD6}, {0xAA,0xD0}, {0xA8,0x7C}, {0xAA,0xD4},
+ {0xCD,0xAF}, {0x9E,0x5D}, {0x99,0x71}, {0xCD,0xAE},
+ {0xAA,0xCD}, {0x89,0xAE}, {0x9D,0xE8}, {0xD0,0x5B},
+ {0xAD,0x47}, {0xAD,0x48}, {0xD0,0x5D}, {0x95,0x65},
+ {0xD0,0x57}, {0xD0,0x5A}, {0xD0,0x63}, {0xD0,0x61},
+ {0xAD,0x49}, {0xD0,0x67}, {0xAD,0x4C}, {0xD0,0x64},
+ {0xD0,0x5C}, {0xD0,0x59}, {0xDB,0x49}, {0xD0,0x62},
+ {0xAD,0x44}, {0xD0,0x65}, {0xD0,0x56}, {0xD0,0x5F},
+ {0xAD,0x46}, {0xAD,0x4B}, {0xD0,0x60}, {0xAD,0x4F},
+ {0xAD,0x4D}, {0xD0,0x58}, {0xAD,0x4A}, {0xD0,0x5E},
+ {0xAD,0x4E}, {0xAD,0x45}, {0xD0,0x66}, {0x99,0x72},
+ {0x8B,0x5C}, {0xAF,0xDA}, {0xAF,0xE3}, {0xAF,0xD8},
+ {0xAF,0xD6}, {0xD3,0x6A}, {0xAF,0xDE}, {0xAF,0xDB},
+ {0xD3,0x6C}, {0x89,0xB1}, {0xAF,0xDD}, {0xD3,0x6B},
+ {0xD3,0x69}, {0xD3,0x6E}, {0xAF,0xE2}, {0xAF,0xE0},
+ {0xDB,0x48}, {0xD3,0x6F}, {0xD3,0x6D}, {0xAF,0xD7},
+ {0xA0,0xC0}, {0xAF,0xD9}, {0xAF,0xDC}, {0x8E,0xDF},
+ {0xAF,0xDF}, {0x95,0x66}, {0xAF,0xE1}, {0x99,0x74},
+ {0x99,0x76}, {0x99,0x77}, {0x99,0x79}, {0xD7,0x4E},
+ {0xB2,0xE4}, {0x9D,0xDA}, {0xD7,0x45}, {0xD7,0x47},
+ {0x8E,0xE0}, {0xD7,0x48}, {0xD7,0x50}, {0xD7,0x4C},
+ {0xD7,0x4A}, {0xD7,0x4D}, {0xD7,0x51}, {0xB2,0xE5},
+ {0xB2,0xE9}, {0xD7,0x46}, {0xD7,0x4F}, {0xB2,0xE7},
+ {0x93,0x5C}, {0xB2,0xE6}, {0xD7,0x4B}, {0xD7,0x49},
+ {0xB2,0xE3}, {0xB2,0xE8}, {0x9D,0xE6}, {0x8B,0x5F},
+ {0x95,0x63}, {0xB5,0xC8}, {0xDB,0x51}, {0xDB,0x4F},
+ {0xB5,0xCA}, {0x95,0x67}, {0xDB,0x4A}, {0xDF,0xA1},
+ {0xB5,0xC9}, {0xDB,0x4E}, {0x9D,0xE3}, {0xDB,0x4B},
+ {0xB5,0xC5}, {0xB5,0xCB}, {0xDB,0x50}, {0xB5,0xC7},
+ {0xDB,0x4D}, {0xBB,0x47}, {0xB5,0xC6}, {0xDB,0x4C},
+ {0xB5,0xCC}, {0xB5,0xC4}, {0xB5,0xC3}, {0x99,0x7C},
+ {0x99,0x7D}, {0x99,0x7E}, {0xDF,0x77}, {0xDF,0x75},
+ {0xDF,0x7B}, {0xDF,0x73}, {0xDF,0xA2}, {0xDF,0x78},
+ {0xDF,0x72}, {0xB8,0x7B}, {0xB8,0xA3}, {0xDF,0x7D},
+ {0xDF,0x76}, {0xB8,0x7E}, {0x8B,0x5B}, {0xB8,0x7C},
+ {0xDF,0x7E}, {0xB8,0x79}, {0xB8,0x78}, {0xDF,0x79},
+ {0xB8,0x7D}, {0xB5,0xCD}, {0xDF,0x7C}, {0xDF,0x74},
+ {0xB8,0x7A}, {0xB8,0xA1}, {0xB8,0xA2}, {0x99,0xA3},
+ {0xBB,0x4C}, {0xBB,0x48}, {0xBB,0x4D}, {0xE3,0xA6},
+ {0x99,0xA4}, {0xE3,0xA5}, {0xE3,0xA7}, {0xBB,0x4A},
+ {0xE3,0xA4}, {0xBB,0x4B}, {0xE3,0xAA}, {0xE3,0xA9},
+ {0xE3,0xA8}, {0xBB,0x49}, {0x99,0xA6}, {0xE7,0x41},
+ {0xE7,0x44}, {0xBD,0xA8}, {0xE7,0x43}, {0xBD,0xA7},
+ {0xBD,0xA3}, {0xBD,0xA4}, {0xBD,0xA5}, {0xE7,0x40},
+ {0xE6,0xFE}, {0xBD,0xA6}, {0xE7,0x42}, {0xE6,0xFD},
+ {0x99,0xA8}, {0xEA,0xE9}, {0xEA,0xF3}, {0xBF,0xB1},
+ {0xBF,0xB0}, {0x8A,0xBE}, {0xEA,0xED}, {0xEA,0xEF},
+ {0xEA,0xEA}, {0xEA,0xEE}, {0xEA,0xE8}, {0xEA,0xF1},
+ {0xBF,0xAF}, {0xEA,0xF0}, {0xEA,0xEC}, {0x9E,0x61},
+ {0xEA,0xF2}, {0xEA,0xEB}, {0xC1,0x74}, {0xED,0xE8},
+ {0xED,0xEE}, {0xC1,0x78}, {0xC1,0x7A}, {0xC1,0x77},
+ {0xC1,0x76}, {0x99,0xAA}, {0xC1,0x75}, {0xC1,0x73},
+ {0xED,0xE9}, {0xED,0xEC}, {0xC1,0x72}, {0xED,0xED},
+ {0xA0,0xC8}, {0xC1,0x79}, {0xED,0xEB}, {0xED,0xEA},
+ {0xC2,0xC0}, {0xC2,0xC1}, {0xF0,0xA1}, {0xF0,0x7D},
+ {0xF0,0x7E}, {0xF2,0xC2}, {0xF2,0xC1}, {0xC3,0xBE},
+ {0xF4,0xB4}, {0xC4,0xA4}, {0xF4,0xB3}, {0xF5,0xF0},
+ {0xF7,0x45}, {0xC5,0xA6}, {0xF9,0x43}, {0xF9,0x44},
+ {0xC5,0xD8}, {0xA6,0xDA}, {0x99,0xAB}, {0xAA,0xD7},
+ {0xDB,0x52}, {0xBB,0x4E}, {0xC1,0x7B}, {0xED,0xEF},
+ {0xA6,0xDB}, {0xAF,0xE5}, {0xAF,0xE4}, {0xDB,0x53},
+ {0xFE,0xC4}, {0xEA,0xF4}, {0xA6,0xDC}, {0xAD,0x50},
+ {0x98,0xC2}, {0xDB,0x54}, {0xDB,0x55}, {0xDB,0x56},
+ {0xBB,0x4F}, {0xBF,0xB2}, {0xA6,0xDD}, {0xAA,0xD8},
+ {0xD0,0x68}, {0xAF,0xE6}, {0xD3,0x70}, {0xB2,0xEA},
+ {0xDB,0x57}, {0xB8,0xA4}, {0xBB,0x50}, {0xBF,0xB3},
+ {0xC1,0x7C}, {0xC2,0xC2}, {0xF4,0xB5}, {0xA6,0xDE},
+ {0xAA,0xD9}, {0xAF,0xE7}, {0xD7,0x52}, {0xB5,0xCE},
+ {0xBB,0x51}, {0xE3,0xAB}, {0xE7,0x45}, {0x8E,0xE8},
+ {0xA0,0xBA}, {0xA6,0xDF}, {0xB5,0xCF}, {0xDF,0xA3},
+ {0xBB,0x52}, {0xA6,0xE0}, {0xCD,0xB1}, {0xD0,0x69},
+ {0xAD,0x51}, {0xD3,0x72}, {0xFD,0x77}, {0xAF,0xEA},
+ {0x8E,0xEE}, {0xAF,0xE8}, {0xAF,0xE9}, {0xAF,0xEB},
+ {0x9E,0xBF}, {0xD3,0x71}, {0xD7,0x57}, {0xD7,0x54},
+ {0xD7,0x56}, {0xB2,0xEB}, {0xB2,0xED}, {0xB2,0xEC},
+ {0xD7,0x53}, {0xB2,0xEE}, {0xD7,0x55}, {0xDB,0x58},
+ {0xDB,0x59}, {0x89,0xC2}, {0xDB,0x5A}, {0xDF,0xA6},
+ {0xDF,0xA7}, {0xDF,0xA5}, {0xDF,0xA8}, {0xB8,0xA5},
+ {0xDF,0xA4}, {0xBB,0x53}, {0xE7,0x4A}, {0xE7,0x46},
+ {0xE7,0x49}, {0xE7,0x4B}, {0xE7,0x48}, {0xE7,0x47},
+ {0x99,0xAC}, {0xEA,0xF5}, {0xEA,0xF6}, {0xEA,0xF7},
+ {0xBF,0xB4}, {0xBF,0xB5}, {0xED,0xF1}, {0xED,0xF0},
+ {0xED,0xF2}, {0xF0,0xA3}, {0xF0,0xA2}, {0xF2,0xC4},
+ {0x95,0x6B}, {0xF2,0xC5}, {0xF2,0xC3}, {0x95,0x6C},
+ {0xC4,0xA5}, {0xF4,0xB6}, {0xF4,0xB7}, {0xF7,0x46},
+ {0xF7,0xEF}, {0xF8,0xBB}, {0xA6,0xE1}, {0xA8,0x7D},
+ {0xC1,0x7D}, {0xA6,0xE2}, {0xD7,0x58}, {0xDB,0x5B},
+ {0x99,0xAF}, {0xC6,0x41}, {0xCA,0x4A}, {0x99,0x4A},
+ {0x89,0x76}, {0x8F,0x48}, {0xCA,0x4B}, {0xCA,0x4D},
+ {0xA6,0xE3}, {0xCA,0x4E}, {0xCA,0x4C}, {0xCB,0xA2},
+ {0xCB,0xA3}, {0xCB,0x7B}, {0xFB,0xEE}, {0xCB,0xA1},
+ {0xA8,0xA1}, {0xA8,0xA2}, {0xCB,0x7C}, {0xCB,0x7A},
+ {0xCB,0x79}, {0xCB,0x7D}, {0xA8,0x7E}, {0xCB,0x7E},
+ {0xD0,0x6A}, {0xCD,0xB6}, {0xAA,0xDC}, {0xCD,0xB5},
+ {0xCD,0xB7}, {0xAA,0xDB}, {0xCD,0xBC}, {0xAA,0xDF},
+ {0xCD,0xB2}, {0xCD,0xC0}, {0xCD,0xC6}, {0xAA,0xE6},
+ {0xCD,0xC3}, {0xAA,0xE3}, {0x99,0xAE}, {0xCD,0xB9},
+ {0xCD,0xBF}, {0xCD,0xC1}, {0x8E,0xFB}, {0xCD,0xB4},
+ {0xAA,0xE2}, {0xAA,0xDD}, {0xCD,0xBA}, {0xAA,0xE4},
+ {0xAA,0xE7}, {0xAA,0xE1}, {0xAA,0xDA}, {0xCD,0xBE},
+ {0xCD,0xB8}, {0xCD,0xC5}, {0xAA,0xE9}, {0xAA,0xE5},
+ {0xAA,0xE0}, {0xCD,0xBD}, {0xAF,0xEC}, {0xCD,0xBB},
+ {0xAA,0xDE}, {0xAA,0xE8}, {0x8C,0xD0}, {0xCD,0xB3},
+ {0xCD,0xC2}, {0xCD,0xC4}, {0x8B,0x52}, {0x99,0xB0},
+ {0x89,0x77}, {0x8F,0x41}, {0xAD,0x62}, {0xAD,0x5C},
+ {0xAD,0x64}, {0xAD,0x61}, {0xD0,0x71}, {0xD0,0x74},
+ {0xAD,0x5D}, {0x99,0xB1}, {0xD0,0x6B}, {0xAD,0x56},
+ {0xAD,0x60}, {0xAD,0x63}, {0xAD,0x65}, {0xD0,0xA2},
+ {0xD0,0x77}, {0x8F,0x49}, {0xAD,0x55}, {0xD0,0xA1},
+ {0xAD,0x59}, {0xAD,0x57}, {0xAD,0x52}, {0xD0,0x6F},
+ {0xD0,0x7E}, {0xD0,0x73}, {0xD0,0x76}, {0xD0,0xA5},
+ {0xFA,0x4D}, {0xAD,0x66}, {0xD0,0x7D}, {0xAD,0x5E},
+ {0xD0,0x78}, {0xD0,0xA4}, {0xD0,0x75}, {0xD0,0x79},
+ {0xD0,0x7C}, {0x9D,0xE4}, {0x8C,0xB5}, {0xD0,0x6D},
+ {0xD0,0xA3}, {0xD0,0x7B}, {0xFB,0xE9}, {0x9B,0x54},
+ {0xD0,0x6C}, {0x99,0xB2}, {0xD0,0x70}, {0xAD,0x5F},
+ {0xAD,0x5A}, {0xAD,0x53}, {0xAD,0x58}, {0xAD,0x54},
+ {0xAD,0x67}, {0xD0,0x6E}, {0xD3,0xA5}, {0xAD,0x5B},
+ {0x9E,0x68}, {0xD0,0x7A}, {0xCE,0x41}, {0xD3,0xA8},
+ {0xAF,0xFA}, {0x8F,0x4A}, {0xD3,0x76}, {0x8F,0x42},
+ {0xD3,0xA3}, {0xD3,0x7D}, {0x8F,0x51}, {0xD3,0xB2},
+ {0xD3,0xAA}, {0xD3,0x7E}, {0xD3,0xA9}, {0xD3,0x78},
+ {0xD3,0x7C}, {0xD3,0xB5}, {0xAF,0xFD}, {0xD3,0xAD},
+ {0xD3,0xA4}, {0xAF,0xED}, {0xD3,0xB3}, {0xD3,0x74},
+ {0xD3,0xAC}, {0xAF,0xFC}, {0xAF,0xF7}, {0xD3,0x73},
+ {0xAF,0xF5}, {0xAF,0xF4}, {0xAF,0xF9}, {0xD3,0xAB},
+ {0xAF,0xF1}, {0xAF,0xF8}, {0xD0,0x72}, {0xDB,0x5C},
+ {0xD3,0xA6}, {0x98,0x46}, {0xD3,0x7A}, {0xAF,0xFB},
+ {0xD3,0x7B}, {0xD3,0xA1}, {0xAF,0xFE}, {0xD3,0x75},
+ {0xD3,0xAF}, {0xD3,0xAE}, {0xD3,0xB6}, {0xAF,0xF3},
+ {0xAF,0xF0}, {0xD3,0xB4}, {0xD3,0xB0}, {0xD3,0xA7},
+ {0xD3,0xA2}, {0xAF,0xF6}, {0xAF,0xF2}, {0xD3,0x77},
+ {0xAF,0xEE}, {0xD3,0xB1}, {0xAF,0xEF}, {0xD3,0x79},
+ {0x99,0xB4}, {0x8E,0xF5}, {0xFD,0x55}, {0x9C,0xCD},
+ {0x89,0x78}, {0xD7,0x5E}, {0xD7,0x60}, {0xD7,0x65},
+ {0xD7,0x79}, {0xB2,0xFC}, {0xB2,0xF2}, {0xD7,0x5D},
+ {0xB2,0xFD}, {0xB2,0xFE}, {0xD7,0x68}, {0xD7,0x6F},
+ {0xD7,0x75}, {0xD7,0x62}, {0xD7,0x69}, {0x8F,0x53},
+ {0xB3,0x40}, {0xD7,0x77}, {0xD7,0x72}, {0xB2,0xFA},
+ {0xB2,0xF8}, {0xD7,0x6E}, {0xD7,0x6A}, {0xD7,0x5C},
+ {0xB2,0xEF}, {0xD7,0x61}, {0xD7,0x59}, {0x8F,0x6F},
+ {0xB2,0xF7}, {0xB2,0xF9}, {0xD7,0x66}, {0xD7,0x63},
+ {0xB2,0xF4}, {0xD7,0x73}, {0xB2,0xF1}, {0xD7,0x64},
+ {0xD7,0x7A}, {0xD7,0x6C}, {0x8E,0x63}, {0xD7,0x6B},
+ {0xB2,0xF0}, {0xB2,0xFB}, {0xB2,0xF3}, {0xD7,0x5A},
+ {0xD7,0x5F}, {0xD7,0x70}, {0xD7,0x76}, {0xB3,0x41},
+ {0xD7,0x5B}, {0xD7,0x67}, {0xD7,0x6D}, {0xB2,0xF6},
+ {0x8F,0x56}, {0xD7,0x78}, {0xD7,0x71}, {0xD7,0x74},
+ {0xFE,0x76}, {0xB2,0xF5}, {0x9F,0xC6}, {0xDB,0x6C},
+ {0xDB,0x60}, {0xB5,0xD7}, {0xDB,0x7D}, {0xDB,0xA7},
+ {0xDB,0xAA}, {0xB5,0xD5}, {0xDB,0x68}, {0xDB,0xA3},
+ {0xDB,0x69}, {0xDB,0x77}, {0xB5,0xE2}, {0xDB,0x73},
+ {0xB5,0xDF}, {0xFA,0xAC}, {0xDB,0x74}, {0xDB,0x5D},
+ {0xDB,0xA4}, {0x8F,0x58}, {0xB5,0xE8}, {0xDB,0xA1},
+ {0xDB,0x75}, {0xDB,0xAC}, {0xDB,0x70}, {0xDF,0xC8},
+ {0xDB,0xAF}, {0xB5,0xE6}, {0xDB,0x6E}, {0xDB,0x7A},
+ {0xB5,0xE9}, {0xB5,0xD4}, {0xDB,0x72}, {0xDB,0xAD},
+ {0xDB,0x6B}, {0xDB,0x64}, {0xDB,0x6F}, {0xDB,0x63},
+ {0xDB,0x61}, {0xB5,0xD0}, {0xDB,0xA5}, {0xDB,0x6A},
+ {0xDB,0xA8}, {0x98,0x48}, {0xDB,0xA9}, {0xB5,0xD8},
+ {0xB5,0xDD}, {0xB5,0xD9}, {0xB5,0xE1}, {0xDB,0x7E},
+ {0xB5,0xDA}, {0xDB,0x76}, {0xDB,0x66}, {0xB5,0xD2},
+ {0xDB,0x5E}, {0xDB,0xA2}, {0xDB,0xAB}, {0xDB,0x65},
+ {0xB5,0xE0}, {0xDB,0xB0}, {0xDB,0x71}, {0xDB,0x6D},
+ {0xB5,0xD1}, {0xB5,0xE5}, {0x99,0xB7}, {0xDB,0x7C},
+ {0xB5,0xE7}, {0xDB,0x78}, {0xB5,0xDC}, {0xB5,0xD6},
+ {0xB5,0xDE}, {0xB5,0xD3}, {0xB5,0xE4}, {0xDB,0x79},
+ {0xDB,0x67}, {0xDB,0x7B}, {0xDB,0x62}, {0xDB,0xA6},
+ {0x96,0x65}, {0xFA,0x6C}, {0x9D,0xE7}, {0xDB,0xAE},
+ {0x9E,0x62}, {0x96,0xCC}, {0x8E,0x67}, {0xDB,0x5F},
+ {0xFC,0x75}, {0x98,0x7E}, {0xDF,0xC7}, {0xDF,0xDD},
+ {0xB8,0x55}, {0xDF,0xCC}, {0xFD,0xB9}, {0xDF,0xCA},
+ {0xDF,0xB5}, {0xB8,0xA9}, {0xDF,0xC5}, {0xDF,0xD9},
+ {0xDF,0xC1}, {0xB8,0xB1}, {0xDF,0xD8}, {0xDF,0xBF},
+ {0xB5,0xE3}, {0xDF,0xCF}, {0xDF,0xC0}, {0xDF,0xD6},
+ {0xB8,0xB0}, {0xB8,0xA8}, {0x97,0xFC}, {0xDF,0xAA},
+ {0xDF,0xB2}, {0xDF,0xCB}, {0xDF,0xC3}, {0xDF,0xDC},
+ {0xDF,0xC6}, {0xB8,0xB6}, {0xDF,0xD7}, {0x98,0xF9},
+ {0xB8,0xAD}, {0x8F,0x66}, {0xDF,0xC9}, {0xDF,0xD1},
+ {0xDF,0xB6}, {0xDF,0xD0}, {0xDF,0xE1}, {0xDF,0xB1},
+ {0xDF,0xD2}, {0x95,0x6E}, {0xDF,0xDF}, {0x92,0x45},
+ {0xDF,0xAB}, {0xB5,0xDB}, {0x8F,0x60}, {0xDF,0xB9},
+ {0xDF,0xB8}, {0xB8,0xAF}, {0x9E,0xD1}, {0xDF,0xBC},
+ {0xDF,0xBE}, {0xDF,0xCD}, {0xDF,0xDE}, {0xB8,0xB2},
+ {0xFE,0xCD}, {0xB8,0xB3}, {0x99,0xB9}, {0xDF,0xB0},
+ {0xB8,0xAB}, {0xDF,0xB4}, {0xDF,0xDA}, {0xB8,0xB4},
+ {0xB8,0xAC}, {0xB8,0xAE}, {0xB8,0xB5}, {0xDF,0xE0},
+ {0xDF,0xD3}, {0xDF,0xCE}, {0x8F,0x62}, {0x97,0x4C},
+ {0xDF,0xBB}, {0xDF,0xBA}, {0xB8,0xAA}, {0xDF,0xAC},
+ {0xB8,0xA7}, {0xDF,0xC4}, {0xDF,0xAD}, {0xDF,0xC2},
+ {0xDF,0xB7}, {0xDF,0xDB}, {0x91,0xC7}, {0x95,0x5F},
+ {0xB8,0xA6}, {0xDF,0xB3}, {0x99,0xBB}, {0xDF,0xAF},
+ {0xDF,0xD5}, {0xDF,0xAE}, {0xBB,0x60}, {0xE3,0xD3},
+ {0x8E,0x6D}, {0x8F,0x71}, {0xE3,0xC2}, {0x94,0xCB},
+ {0xE3,0xAC}, {0xE3,0xCA}, {0xBB,0x58}, {0xE3,0xBB},
+ {0xE3,0xC5}, {0xBB,0x5B}, {0xE3,0xBE}, {0xBB,0x59},
+ {0xE3,0xAF}, {0xE3,0xCD}, {0xE3,0xAE}, {0xE3,0xC1},
+ {0x95,0xB1}, {0xE3,0xAD}, {0xE3,0xBF}, {0xE3,0xC8},
+ {0xE3,0xC6}, {0xE3,0xBA}, {0xE3,0xB5}, {0xE3,0xB3},
+ {0x9A,0xF2}, {0xE3,0xB4}, {0xE3,0xC7}, {0xE3,0xD2},
+ {0xE3,0xBC}, {0xBB,0x5A}, {0xE3,0xB7}, {0xE3,0xCB},
+ {0xBB,0x5D}, {0xE3,0xB6}, {0xE3,0xB0}, {0xE3,0xC0},
+ {0xBB,0x61}, {0x96,0xC3}, {0x99,0xBD}, {0xBB,0x55},
+ {0xBB,0x5E}, {0xE3,0xB8}, {0xE3,0xB2}, {0xBB,0x57},
+ {0xDF,0xD4}, {0xBB,0x56}, {0xE3,0xC3}, {0xBB,0x54},
+ {0xBB,0x63}, {0xBB,0x5C}, {0xE3,0xC4}, {0xE3,0xB9},
+ {0xE3,0xB1}, {0xE3,0xCC}, {0xE3,0xBD}, {0xBB,0x62},
+ {0xE3,0xD0}, {0xBB,0x5F}, {0xE3,0xCF}, {0xE3,0xC9},
+ {0xE3,0xCE}, {0xA0,0xCF}, {0xE3,0xD1}, {0x8F,0x6D},
+ {0x99,0xBE}, {0x8E,0xF4}, {0x8F,0x72}, {0x95,0xE4},
+ {0xE7,0x73}, {0xE7,0x74}, {0xE7,0x67}, {0xE7,0x66},
+ {0xE7,0x62}, {0xBD,0xB4}, {0xBD,0xAC}, {0xE7,0x76},
+ {0xE7,0x75}, {0xDF,0xA9}, {0xE7,0x5F}, {0xE7,0x63},
+ {0xE7,0x5D}, {0xE7,0x70}, {0xE7,0x61}, {0x99,0xBF},
+ {0xE7,0x77}, {0xE7,0x5A}, {0xE7,0x58}, {0xE7,0x64},
+ {0xE7,0x6E}, {0xE7,0x69}, {0xBD,0xB6}, {0xE7,0x4F},
+ {0xE7,0x6D}, {0x92,0x42}, {0xFB,0xA5}, {0xBD,0xB7},
+ {0xDF,0xBD}, {0xE7,0x5B}, {0xE7,0x52}, {0xE7,0x55},
+ {0xE7,0x7B}, {0xE7,0x5C}, {0xE7,0x53}, {0xE7,0x51},
+ {0xE7,0x4E}, {0x99,0xC0}, {0xBD,0xB0}, {0xE7,0x65},
+ {0xBD,0xAF}, {0xBD,0xB3}, {0xE7,0x60}, {0xE7,0x68},
+ {0xBD,0xA9}, {0xE7,0x78}, {0xE7,0x7C}, {0xBD,0xAB},
+ {0xE7,0x57}, {0xE7,0x6B}, {0xE7,0x6F}, {0xE7,0x54},
+ {0xE7,0x79}, {0xBD,0xB2}, {0xBD,0xB1}, {0xE7,0x4C},
+ {0xBD,0xB5}, {0xE7,0x72}, {0xE7,0x56}, {0xE7,0x6A},
+ {0xE7,0x50}, {0xE7,0x5E}, {0xE7,0x59}, {0xBD,0xAD},
+ {0xBD,0xAE}, {0xE7,0x6C}, {0xE7,0x7D}, {0xE7,0x7A},
+ {0xE7,0x71}, {0xFD,0xB4}, {0x8F,0x77}, {0x99,0xC1},
+ {0xE7,0x4D}, {0xBD,0xAA}, {0xEB,0x49}, {0xEB,0x40},
+ {0xEB,0x43}, {0xFA,0xB9}, {0xBF,0xBB}, {0xEB,0x45},
+ {0xEA,0xF9}, {0xEB,0x41}, {0xEB,0x47}, {0xBF,0xB8},
+ {0xBF,0xBC}, {0xBF,0xB6}, {0x8F,0x40}, {0xFA,0x44},
+ {0xEA,0xFB}, {0xEB,0x4C}, {0xEB,0x46}, {0x99,0xC2},
+ {0xEA,0xFC}, {0xEB,0x55}, {0xEB,0x4F}, {0xEA,0xF8},
+ {0xEE,0x46}, {0xEA,0xFE}, {0xBF,0xB7}, {0x8F,0x5C},
+ {0xEB,0x4A}, {0xEB,0x54}, {0xBF,0xBF}, {0x8C,0xBD},
+ {0xEB,0x51}, {0xEA,0xFD}, {0xEB,0x44}, {0xEB,0x48},
+ {0xEB,0x42}, {0xEB,0x56}, {0xEB,0x53}, {0xEB,0x50},
+ {0xBF,0xB9}, {0xBF,0xBA}, {0xBF,0xBE}, {0xEA,0xFA},
+ {0xEB,0x57}, {0xBF,0xBD}, {0xEB,0x4D}, {0x99,0xC4},
+ {0x99,0xC5}, {0xEB,0x4B}, {0x8F,0x7B}, {0xEB,0x4E},
+ {0xEE,0x53}, {0xEE,0x40}, {0xEE,0x45}, {0xEE,0x52},
+ {0xEE,0x44}, {0xED,0xFB}, {0xEE,0x41}, {0xC1,0xA2},
+ {0xED,0xF4}, {0xEE,0x4D}, {0xEE,0x4F}, {0xED,0xF3},
+ {0xC1,0xA1}, {0xEE,0x51}, {0xEE,0x49}, {0xC1,0xA8},
+ {0xEE,0x50}, {0xEE,0x42}, {0xC1,0xAA}, {0xED,0xF9},
+ {0xEB,0x52}, {0xEE,0x4A}, {0xEE,0x47}, {0xED,0xF5},
+ {0xEE,0x55}, {0xC1,0xA4}, {0xC1,0xA5}, {0xED,0xF7},
+ {0xEE,0x48}, {0x8C,0xB6}, {0xEE,0x54}, {0xEE,0x4B},
+ {0xED,0xFD}, {0xC1,0xA7}, {0xC1,0xA3}, {0xEE,0x4C},
+ {0xED,0xFE}, {0xEE,0x56}, {0xED,0xF8}, {0xEE,0x43},
+ {0xEE,0x4E}, {0xED,0xFA}, {0xED,0xFC}, {0xC2,0xCB},
+ {0xED,0xF6}, {0xC1,0xA9}, {0xC2,0xC4}, {0xC1,0x7E},
+ {0xC1,0xA6}, {0xC2,0xC8}, {0xF0,0xB3}, {0xF0,0xA9},
+ {0xF0,0xA4}, {0xF0,0xAA}, {0xF0,0xB4}, {0xF0,0xB8},
+ {0xF0,0xB7}, {0xC2,0xCA}, {0xC2,0xC9}, {0xF0,0xAB},
+ {0xF0,0xB9}, {0xF0,0xAE}, {0xF0,0xA6}, {0x8F,0xA3},
+ {0xF0,0xA8}, {0xF0,0xA7}, {0xF0,0xAD}, {0xF0,0xB2},
+ {0xF0,0xA5}, {0xF0,0xAC}, {0xF0,0xB1}, {0xC2,0xC7},
+ {0xF0,0xAF}, {0xC2,0xC5}, {0xF0,0xB0}, {0xC2,0xC3},
+ {0xC2,0xC6}, {0xF2,0xD5}, {0xF0,0xB5}, {0xC3,0xC2},
+ {0x8C,0xCE}, {0xF2,0xCD}, {0xF2,0xD1}, {0xF2,0xC9},
+ {0xF2,0xCC}, {0xF2,0xD4}, {0xC3,0xC0}, {0xF2,0xD9},
+ {0xF2,0xD2}, {0x99,0xC6}, {0xF2,0xCA}, {0xF2,0xDA},
+ {0xF2,0xD3}, {0xC3,0xC3}, {0xC3,0xC4}, {0xF2,0xD7},
+ {0xF2,0xCB}, {0xC3,0xBF}, {0xC3,0xC1}, {0xF2,0xC6},
+ {0xF2,0xCE}, {0xF2,0xC8}, {0x96,0xCD}, {0xF2,0xD8},
+ {0xF2,0xD6}, {0xF2,0xC7}, {0xF2,0xCF}, {0xF4,0xBE},
+ {0xC3,0xC5}, {0xF2,0xD0}, {0xC4,0xA7}, {0xC4,0xA9},
+ {0xC4,0xA6}, {0x96,0xC7}, {0xF4,0xC3}, {0xF4,0xBB},
+ {0xF4,0xB9}, {0xF4,0xBD}, {0xF4,0xBA}, {0x8F,0xA5},
+ {0xF4,0xBF}, {0xF4,0xC1}, {0xC4,0xAA}, {0xC4,0xAC},
+ {0xF4,0xC0}, {0xC4,0xAD}, {0xC4,0xAB}, {0xF4,0xC2},
+ {0xFA,0xBB}, {0x8C,0x61}, {0x95,0x70}, {0xC4,0xA8},
+ {0x93,0x68}, {0x8F,0x7E}, {0xC4,0xF4}, {0xF5,0xF1},
+ {0xF5,0xF7}, {0xC4,0xF6}, {0xF4,0xBC}, {0xF5,0xF6},
+ {0xF5,0xFD}, {0xF5,0xF4}, {0xF5,0xFB}, {0xF5,0xFA},
+ {0xF4,0xB8}, {0xF5,0xF5}, {0xF0,0xB6}, {0xF5,0xFE},
+ {0xF5,0xF3}, {0xF5,0xF8}, {0x8F,0xAA}, {0xF5,0xFC},
+ {0xF5,0xF2}, {0xF7,0x4A}, {0xC4,0xF5}, {0xF5,0xF9},
+ {0xA0,0x50}, {0xF7,0xF4}, {0xF7,0x4B}, {0xF7,0x49},
+ {0xF7,0x47}, {0xF7,0x48}, {0xF7,0x4C}, {0xC5,0xD9},
+ {0xF7,0xF2}, {0xF7,0xF0}, {0xF7,0xF5}, {0xF7,0xF3},
+ {0xF7,0xF6}, {0xC5,0xDA}, {0xF7,0xF1}, {0x90,0xD3},
+ {0xF8,0xBC}, {0x95,0x56}, {0xF9,0x45}, {0xF9,0x46},
+ {0xF9,0x47}, {0xF9,0xC7}, {0xF9,0xBD}, {0xCA,0x4F},
+ {0xAA,0xEA}, {0xAD,0x68}, {0xD3,0xB8}, {0xD3,0xB7},
+ {0xB0,0x40}, {0xB3,0x42}, {0xD7,0x7C}, {0xD7,0x7B},
+ {0xB5,0xEA}, {0xB8,0xB8}, {0xB8,0xB7}, {0xB8,0xB9},
+ {0xE3,0xD4}, {0xE7,0x7E}, {0xEB,0x58}, {0xEB,0x5A},
+ {0xEB,0x59}, {0xC1,0xAB}, {0xEE,0x57}, {0xF0,0xBA},
+ {0xF9,0xA5}, {0xA6,0xE4}, {0x8F,0xB8}, {0xCD,0xC9},
+ {0xCD,0xCA}, {0xCD,0xC8}, {0xCD,0xC7}, {0xAA,0xEB},
+ {0x99,0xC8}, {0xD0,0xA9}, {0xD0,0xA7}, {0xD0,0xA6},
+ {0xAD,0x69}, {0xAD,0x6B}, {0xAD,0x6A}, {0xD0,0xA8},
+ {0x8F,0xAF}, {0xD3,0xC4}, {0xD3,0xC1}, {0xD3,0xBF},
+ {0xB0,0x41}, {0xD3,0xC2}, {0xB0,0x46}, {0xD3,0xBC},
+ {0xD3,0xCB}, {0xD3,0xCD}, {0xD3,0xBD}, {0x99,0xC9},
+ {0xB0,0x43}, {0xD3,0xCE}, {0xD3,0xC9}, {0xD3,0xBB},
+ {0xD3,0xC0}, {0xD3,0xCA}, {0xD3,0xC6}, {0xD3,0xC3},
+ {0xB0,0x48}, {0xD3,0xCC}, {0xD3,0xBE}, {0x95,0x79},
+ {0xD3,0xC7}, {0xD3,0xB9}, {0xB0,0x47}, {0xB0,0x44},
+ {0xD3,0xC5}, {0xD3,0xC8}, {0xD3,0xBA}, {0xB0,0x45},
+ {0xB0,0x42}, {0x9F,0x49}, {0xB3,0x4C}, {0xD7,0xA5},
+ {0xB3,0x4B}, {0x99,0xCA}, {0xD7,0xA8}, {0xD7,0xAB},
+ {0xB3,0x48}, {0xB3,0x46}, {0xD7,0x7E}, {0xD7,0xA9},
+ {0xD7,0xA7}, {0xD7,0xA4}, {0xD7,0xAC}, {0xD7,0xAD},
+ {0xD7,0xAF}, {0xD7,0xB0}, {0xD7,0x7D}, {0xB3,0x45},
+ {0xD7,0xA2}, {0xD7,0xA1}, {0xD7,0xAE}, {0xB3,0x47},
+ {0xD7,0xA3}, {0xB3,0x49}, {0xB3,0x44}, {0xD7,0xA6},
+ {0xB3,0x4D}, {0xB3,0x4A}, {0xD7,0xAA}, {0xB5,0xF1},
+ {0xDB,0xBF}, {0xDB,0xB4}, {0xB5,0xEE}, {0xDF,0xE7},
+ {0xDB,0xBD}, {0xDB,0xB1}, {0xB5,0xEC}, {0xDB,0xB6},
+ {0xB5,0xEF}, {0xDB,0xBA}, {0xDB,0xB8}, {0xB5,0xF2},
+ {0xB5,0xEB}, {0xDB,0xB2}, {0xDB,0xB5}, {0xB5,0xF0},
+ {0xDB,0xB3}, {0xDB,0xBE}, {0xDB,0xBC}, {0xDB,0xB7},
+ {0xDB,0xB9}, {0xDB,0xBB}, {0xB5,0xED}, {0x99,0xCB},
+ {0xDF,0xE8}, {0xDF,0xEE}, {0xDF,0xE4}, {0xDF,0xEA},
+ {0xB8,0xBA}, {0xDF,0xE6}, {0xB8,0xC0}, {0xB8,0xBF},
+ {0xB8,0xBE}, {0xDF,0xED}, {0xB8,0xC1}, {0xB8,0xC2},
+ {0xDF,0xE3}, {0xDF,0xF0}, {0xB8,0xC3}, {0xB8,0xBD},
+ {0xB8,0xBC}, {0xDF,0xEC}, {0xB8,0xC4}, {0xDF,0xE2},
+ {0xDF,0xE5}, {0xDF,0xEF}, {0xDF,0xEB}, {0xE3,0xF4},
+ {0xE3,0xE9}, {0xB8,0xBB}, {0xBB,0x6A}, {0xE3,0xDD},
+ {0xE3,0xF2}, {0xE3,0xDE}, {0xBB,0x65}, {0xE3,0xDB},
+ {0xE3,0xE4}, {0xE3,0xDC}, {0xBB,0x67}, {0xE3,0xD6},
+ {0xE3,0xF1}, {0xBB,0x68}, {0xE3,0xEE}, {0xE3,0xEF},
+ {0xE3,0xD7}, {0xBB,0x6D}, {0xE3,0xE6}, {0xE3,0xE0},
+ {0xE3,0xE7}, {0xE3,0xDA}, {0xE3,0xF3}, {0xE3,0xEB},
+ {0xE3,0xE5}, {0xE3,0xD5}, {0xBB,0x69}, {0xE3,0xEC},
+ {0xBB,0x6C}, {0xE3,0xF0}, {0xE3,0xEA}, {0xBB,0x66},
+ {0xE3,0xE8}, {0xE3,0xE2}, {0xBB,0x64}, {0xE3,0xD9},
+ {0xE3,0xE1}, {0xE3,0xED}, {0xE3,0xDF}, {0xE3,0xE3},
+ {0xBD,0xC1}, {0xDF,0xE9}, {0xE7,0xB2}, {0xE7,0xBB},
+ {0xE7,0xB1}, {0xE7,0xAD}, {0xE7,0xAA}, {0xBD,0xC2},
+ {0xE7,0xA8}, {0xBB,0x6B}, {0xE7,0xA1}, {0xBD,0xC0},
+ {0xE7,0xA7}, {0xBD,0xBF}, {0xE7,0xAC}, {0xE7,0xA9},
+ {0xE7,0xB9}, {0xE7,0xB4}, {0xE7,0xAE}, {0xE7,0xB3},
+ {0xBD,0xBB}, {0xE7,0xAB}, {0xE7,0xBE}, {0xE7,0xA2},
+ {0xE7,0xA3}, {0xE7,0xBA}, {0xBD,0xBC}, {0xE7,0xBF},
+ {0xBD,0xBE}, {0xE7,0xC0}, {0xE7,0xB0}, {0xE3,0xD8},
+ {0xE7,0xB6}, {0xE7,0xAF}, {0xE7,0xB8}, {0xE7,0xB5},
+ {0x9D,0xD5}, {0x8F,0xB0}, {0xE7,0xA6}, {0xBD,0xB9},
+ {0xE7,0xBD}, {0xBD,0xBA}, {0xE7,0xA4}, {0xBD,0xBD},
+ {0xEB,0x64}, {0xE7,0xB7}, {0xE7,0xBC}, {0xFA,0x7A},
+ {0xEB,0x61}, {0xBD,0xB8}, {0xBF,0xC0}, {0xEB,0x6B},
+ {0xEB,0x67}, {0x9E,0x5F}, {0xEB,0x65}, {0xEB,0x60},
+ {0xEB,0x6F}, {0x99,0xCD}, {0xA0,0xC9}, {0xBF,0xC4},
+ {0xEB,0x5C}, {0xEB,0x68}, {0xEB,0x69}, {0xEB,0x5F},
+ {0xEB,0x5E}, {0xEB,0x6C}, {0xEB,0x62}, {0xEB,0x5D},
+ {0xEB,0x63}, {0xEB,0x6E}, {0xEB,0x5B}, {0xEB,0x6D},
+ {0xEB,0x6A}, {0xBF,0xC2}, {0xBF,0xC1}, {0xBF,0xC3},
+ {0xEB,0x66}, {0xF0,0xCB}, {0x9A,0xDB}, {0xA0,0xC6},
+ {0xEE,0x59}, {0xC1,0xB1}, {0xEE,0x5D}, {0xEE,0x5A},
+ {0xEE,0x61}, {0xEE,0x67}, {0xEE,0x5C}, {0x8F,0xB4},
+ {0xEE,0x70}, {0xC1,0xAE}, {0xEE,0x6A}, {0xEE,0x5F},
+ {0xEE,0x6B}, {0xEE,0x66}, {0xEE,0x6D}, {0xEE,0x5E},
+ {0xC1,0xB3}, {0xC1,0xB2}, {0xEE,0x60}, {0xEE,0x6E},
+ {0xEE,0x58}, {0xEE,0x6C}, {0xC1,0xAC}, {0xA0,0xD7},
+ {0xEE,0x64}, {0xEE,0x63}, {0xEE,0x68}, {0xEE,0x5B},
+ {0xC1,0xB0}, {0xC1,0xB4}, {0xEE,0x62}, {0xEE,0x69},
+ {0xC1,0xB5}, {0xEE,0x65}, {0xA0,0xC7}, {0xC1,0xAD},
+ {0xC1,0xAF}, {0xF0,0xC7}, {0xF0,0xC5}, {0xA0,0x43},
+ {0xF0,0xCC}, {0xF0,0xC9}, {0xF0,0xCD}, {0x8F,0xB5},
+ {0xF0,0xBE}, {0xF0,0xC6}, {0xF0,0xD1}, {0xEE,0x6F},
+ {0xF0,0xC2}, {0xC2,0xCF}, {0xE7,0xA5}, {0xF0,0xBD},
+ {0xF0,0xCA}, {0xF0,0xC4}, {0xF0,0xC1}, {0xF0,0xBC},
+ {0xF0,0xBB}, {0xF0,0xD0}, {0xF0,0xC0}, {0xF0,0xBF},
+ {0xC2,0xCD}, {0xF0,0xC8}, {0x8F,0xB2}, {0xC2,0xCC},
+ {0xC2,0xCE}, {0xF0,0xC3}, {0xF0,0xCF}, {0xA0,0x61},
+ {0xF2,0xDE}, {0xF2,0xDF}, {0xC3,0xC9}, {0xF2,0xDC},
+ {0xC3,0xC6}, {0xF2,0xE4}, {0xC3,0xCA}, {0xF2,0xE6},
+ {0xF2,0xDB}, {0xF0,0xCE}, {0xF2,0xE8}, {0xF2,0xDD},
+ {0x9E,0x5E}, {0xC3,0xC7}, {0xF2,0xE3}, {0xF2,0xE5},
+ {0xF2,0xE0}, {0xF2,0xE7}, {0xF2,0xE2}, {0xF2,0xE1},
+ {0xC3,0xC8}, {0x8F,0xB6}, {0xF4,0xC5}, {0xF4,0xC6},
+ {0xF4,0xC8}, {0xC4,0xAE}, {0xC4,0xAF}, {0xF4,0xC9},
+ {0xF4,0xC7}, {0x9F,0xE8}, {0xF4,0xC4}, {0xF6,0x42},
+ {0xF6,0x45}, {0xF6,0x41}, {0xC4,0xFA}, {0xF6,0x43},
+ {0xC4,0xF9}, {0xC4,0xF8}, {0xC4,0xF7}, {0xF6,0x44},
+ {0xF7,0x51}, {0xF7,0x4F}, {0x9C,0xB2}, {0xF7,0x4E},
+ {0xF6,0x40}, {0xF7,0x50}, {0xF6,0x46}, {0xF7,0x4D},
+ {0x95,0x7C}, {0xF7,0xF9}, {0xF7,0xD7}, {0xF7,0xF7},
+ {0xC5,0xDB}, {0xF7,0xF8}, {0xF7,0xFA}, {0xF8,0xBF},
+ {0xC5,0xFA}, {0xF8,0xBE}, {0xF8,0xBD}, {0xC5,0xFB},
+ {0xC6,0x5A}, {0xF9,0x6E}, {0xF9,0xA7}, {0xF9,0xA6},
+ {0xF9,0xA8}, {0xA6,0xE5}, {0xD0,0xAA}, {0x9F,0xC7},
+ {0xD3,0xCF}, {0xD3,0xD0}, {0x8F,0xBB}, {0x8F,0xBC},
+ {0xDB,0xC0}, {0xF6,0x47}, {0xF8,0xC0}, {0xA6,0xE6},
+ {0xAD,0x6C}, {0xD0,0xAB}, {0x8F,0xEC}, {0xD7,0xB1},
+ {0xB3,0x4E}, {0xDB,0xC2}, {0xDB,0xC1}, {0xB5,0xF3},
+ {0xB8,0xC5}, {0xE7,0xC1}, {0xBD,0xC3}, {0xBD,0xC4},
+ {0x8F,0xC0}, {0x93,0x6A}, {0xBF,0xC5}, {0xC5,0xFC},
+ {0xA6,0xE7}, {0x8B,0xE4}, {0x9C,0x7C}, {0xD0,0xAC},
+ {0xAA,0xED}, {0xD0,0xAE}, {0xD0,0xAD}, {0xAD,0x6D},
+ {0xD3,0xD1}, {0x95,0xA1}, {0xD3,0xD8}, {0xB0,0x49},
+ {0xD3,0xD6}, {0xD3,0xD4}, {0xD3,0xDB}, {0xD3,0xD2},
+ {0xD3,0xD3}, {0xB0,0x4A}, {0xB0,0x4E}, {0xD3,0xDC},
+ {0xB0,0x4D}, {0xD3,0xDA}, {0xD3,0xD7}, {0xD3,0xD5},
+ {0xB0,0x4B}, {0xB0,0x4C}, {0xD3,0xD9}, {0xFE,0xEC},
+ {0x95,0xA3}, {0xB3,0x50}, {0xD7,0xB2}, {0xB3,0x55},
+ {0xD7,0xC2}, {0xB3,0x54}, {0xD7,0xC4}, {0x8C,0x45},
+ {0x8C,0xB8}, {0xD7,0xB8}, {0xB3,0x52}, {0xD7,0xC3},
+ {0xD7,0xB3}, {0xB3,0x53}, {0xD7,0xBF}, {0xD7,0xBB},
+ {0xD7,0xBD}, {0xD7,0xB7}, {0xD7,0xBE}, {0x8F,0xC1},
+ {0xB3,0x4F}, {0xD7,0xBA}, {0xA0,0x52}, {0xD7,0xB9},
+ {0xD7,0xB5}, {0xD7,0xC0}, {0xD7,0xBC}, {0xD7,0xB4},
+ {0xD7,0xB6}, {0xB3,0x51}, {0xD7,0xC1}, {0x99,0xD0},
+ {0xB5,0xF6}, {0xDB,0xCD}, {0x8F,0xC3}, {0x8F,0xC4},
+ {0xDB,0xC9}, {0xDB,0xCB}, {0xDB,0xC6}, {0xDB,0xC5},
+ {0xDB,0xC3}, {0xDB,0xCA}, {0xDB,0xCC}, {0xDB,0xC8},
+ {0x95,0xA4}, {0xDB,0xC7}, {0xB5,0xF4}, {0xB5,0xF5},
+ {0x8F,0xC6}, {0x9E,0x60}, {0xDB,0xCF}, {0xB8,0xCD},
+ {0xDF,0xF2}, {0xDF,0xF8}, {0xDF,0xF3}, {0xDF,0xF4},
+ {0xF9,0xD8}, {0xDF,0xF9}, {0xB8,0xCF}, {0xB8,0xC7},
+ {0xB8,0xCE}, {0xDF,0xF1}, {0xDB,0xC4}, {0xB8,0xCA},
+ {0xB8,0xC8}, {0xDF,0xF7}, {0xDF,0xF6}, {0xB8,0xC9},
+ {0xB8,0xCB}, {0xDF,0xF5}, {0xB8,0xC6}, {0xB8,0xCC},
+ {0x95,0xA5}, {0xE3,0xF6}, {0xBB,0x74}, {0xE4,0x42},
+ {0xE4,0x41}, {0xE3,0xFB}, {0xBB,0x76}, {0xE4,0x40},
+ {0xE3,0xF7}, {0xE3,0xF8}, {0xBB,0x6E}, {0xBB,0x70},
+ {0x9C,0xB3}, {0xE3,0xFD}, {0xE3,0xF5}, {0xBB,0x72},
+ {0xBB,0x71}, {0xE3,0xF9}, {0xE3,0xFE}, {0xE3,0xFC},
+ {0xBB,0x73}, {0xE3,0xFA}, {0x99,0xD1}, {0xFE,0xF1},
+ {0xDB,0xCE}, {0xBB,0x6F}, {0xE7,0xC2}, {0xE7,0xC9},
+ {0xBD,0xC6}, {0xE7,0xCD}, {0xBD,0xCA}, {0xE7,0xC5},
+ {0xE7,0xC3}, {0xE7,0xCC}, {0xBD,0xC5}, {0xE7,0xCB},
+ {0xBD,0xC7}, {0xBD,0xC8}, {0xE7,0xC4}, {0xBD,0xC9},
+ {0xE7,0xCA}, {0xE7,0xC6}, {0xE7,0xC7}, {0xE7,0xC8},
+ {0xBB,0x75}, {0xEB,0x70}, {0xEB,0x7C}, {0xBF,0xCA},
+ {0xEB,0x77}, {0xEB,0x79}, {0x99,0xD2}, {0xBF,0xC8},
+ {0xEB,0x71}, {0xEB,0x75}, {0xEB,0x78}, {0xBF,0xC6},
+ {0xBF,0xC9}, {0xEB,0x7B}, {0xEB,0x73}, {0xEB,0x74},
+ {0xEB,0x7A}, {0xEB,0x72}, {0xEB,0x76}, {0xBF,0xC7},
+ {0xEE,0x72}, {0xEE,0x71}, {0xC1,0xB7}, {0xEE,0x77},
+ {0xC1,0xB9}, {0xC1,0xB6}, {0xEE,0x73}, {0xC1,0xBA},
+ {0xEE,0x74}, {0xEE,0x75}, {0xEE,0x78}, {0x9C,0xC2},
+ {0xC1,0xB8}, {0xF0,0xD6}, {0x99,0xD3}, {0xF0,0xD9},
+ {0xF0,0xD3}, {0xF0,0xD5}, {0x95,0xA7}, {0xF0,0xD4},
+ {0xF0,0xD7}, {0xF0,0xD8}, {0xEE,0x76}, {0xF0,0xD2},
+ {0x95,0xA9}, {0xC3,0xCD}, {0xF2,0xEC}, {0xF2,0xEF},
+ {0xF2,0xF1}, {0xF2,0xEA}, {0xF2,0xEB}, {0xF2,0xEE},
+ {0xF2,0xF0}, {0xC3,0xCE}, {0xC3,0xCC}, {0xC3,0xCB},
+ {0xF2,0xED}, {0xF2,0xE9}, {0xF4,0xCA}, {0xC4,0xB0},
+ {0x95,0xA6}, {0xF4,0xCB}, {0xF6,0x49}, {0xC4,0xFB},
+ {0xF6,0x4B}, {0xC4,0xFC}, {0xF6,0x48}, {0xF6,0x4A},
+ {0xC5,0xA8}, {0xF7,0x52}, {0xC5,0xA7}, {0xF7,0xFD},
+ {0xF7,0xFC}, {0xF7,0xFB}, {0x9C,0x5D}, {0xF9,0x48},
+ {0xF9,0x49}, {0xF9,0x4B}, {0xF9,0x4A}, {0xCA,0x50},
+ {0xA6,0xE8}, {0x98,0xE2}, {0xAD,0x6E}, {0xD7,0xC5},
+ {0xB5,0xF7}, {0xDF,0xFA}, {0xC2,0xD0}, {0x8F,0xC9},
+ {0xF2,0xF2}, {0xA0,0xC2}, {0x8F,0xCA}, {0xA8,0xA3},
+ {0xB3,0x57}, {0x99,0xD4}, {0xB3,0x56}, {0xA0,0xB9},
+ {0xDB,0xD0}, {0xB5,0xF8}, {0xDB,0xD2}, {0xDB,0xD1},
+ {0xDF,0xFB}, {0xB8,0xD0}, {0xE4,0x43}, {0xE4,0x46},
+ {0xE4,0x45}, {0xE4,0x44}, {0xE7,0xCE}, {0xE7,0xD0},
+ {0xE7,0xCF}, {0x9B,0x58}, {0xBF,0xCC}, {0x8F,0xCD},
+ {0xA0,0xD4}, {0xBF,0xCB}, {0xC1,0xBB}, {0xEE,0x79},
+ {0xEE,0x7B}, {0xEE,0x7A}, {0xC2,0xD1}, {0xF2,0xF4},
+ {0xF2,0xF3}, {0xF4,0xCC}, {0xC4,0xB1}, {0x8F,0xCE},
+ {0xC4,0xFD}, {0xF7,0x54}, {0xF7,0x53}, {0xC6,0x5B},
+ {0x8B,0xE5}, {0x89,0x79}, {0xA8,0xA4}, {0xD0,0xAF},
+ {0xAD,0x6F}, {0xD7,0xC8}, {0xD7,0xC6}, {0xD7,0xC7},
+ {0xDB,0xD4}, {0xDB,0xD5}, {0xE0,0x43}, {0xDB,0xD3},
+ {0xDF,0xFC}, {0xE0,0x41}, {0xE0,0x40}, {0xE0,0x42},
+ {0xB8,0xD1}, {0xDF,0xFE}, {0xDF,0xFD}, {0xE0,0x44},
+ {0x8F,0xD0}, {0xE4,0x49}, {0xE4,0x47}, {0xE4,0x48},
+ {0xE7,0xD3}, {0xE7,0xD1}, {0xE7,0xD2}, {0xEB,0x7D},
+ {0xEE,0x7C}, {0xEE,0x7D}, {0xC2,0xD2}, {0xF2,0xF5},
+ {0xF4,0xCD}, {0xC4,0xB2}, {0xF6,0x4C}, {0xF7,0x55},
+ {0xC5,0xA9}, {0xF7,0xFE}, {0xF9,0x4C}, {0xA8,0xA5},
+ {0xAD,0x71}, {0xAD,0x72}, {0xD0,0xB0}, {0xD0,0xB1},
+ {0xAD,0x70}, {0xB0,0x54}, {0xB0,0x52}, {0xB0,0x51},
+ {0xB0,0x58}, {0xB0,0x50}, {0xB0,0x59}, {0xD3,0xDD},
+ {0xB0,0x56}, {0xB0,0x53}, {0xB0,0x57}, {0xB0,0x55},
+ {0xB0,0x4F}, {0xB3,0x5F}, {0x95,0xB6}, {0xB3,0x59},
+ {0xD7,0xCC}, {0xB3,0x5E}, {0xB3,0x60}, {0xB3,0x5A},
+ {0xB3,0x5B}, {0xD7,0xCA}, {0x99,0xD6}, {0xB3,0x58},
+ {0x95,0xE5}, {0xD7,0xCB}, {0xB3,0x5D}, {0xD7,0xC9},
+ {0xB3,0x5C}, {0xB6,0x44}, {0xB6,0x46}, {0x99,0xD7},
+ {0xDB,0xD8}, {0xB6,0x45}, {0xB5,0xF9}, {0xB5,0xFD},
+ {0x95,0xB5}, {0xB8,0xE4}, {0xE0,0x49}, {0xDB,0xDA},
+ {0xB5,0xFE}, {0xDB,0xDD}, {0xDB,0xDE}, {0xB6,0x43},
+ {0xDB,0xE0}, {0xA0,0xCA}, {0xDB,0xE2}, {0xDB,0xE3},
+ {0xDB,0xD7}, {0xDB,0xD6}, {0xDB,0xE4}, {0xB6,0x42},
+ {0xDB,0xE1}, {0xDB,0xDF}, {0xB6,0x40}, {0xB5,0xFB},
+ {0xB6,0x47}, {0xDB,0xDB}, {0xDB,0xDC}, {0xDB,0xD9},
+ {0xB6,0x41}, {0xB5,0xFC}, {0xB5,0xFA}, {0xE0,0x48},
+ {0xB8,0xDF}, {0xB8,0xDA}, {0xB8,0xD5}, {0x9F,0xFD},
+ {0xB8,0xE5}, {0xB8,0xD6}, {0xB8,0xD2}, {0xB8,0xE1},
+ {0xB8,0xDE}, {0xB8,0xE0}, {0xB8,0xD7}, {0xB8,0xDC},
+ {0xB8,0xD3}, {0xB8,0xD4}, {0xE0,0x50}, {0xE0,0x4D},
+ {0xE0,0x45}, {0xE0,0x4A}, {0xB8,0xE2}, {0xE0,0x51},
+ {0xB8,0xE3}, {0xB8,0xD9}, {0xA0,0x58}, {0xE0,0x47},
+ {0xE0,0x4F}, {0xE0,0x4B}, {0xE0,0x4E}, {0xE0,0x4C},
+ {0xB8,0xDD}, {0xE0,0x46}, {0xB8,0xD8}, {0xE4,0x4C},
+ {0xBB,0x78}, {0xBB,0x7B}, {0xE4,0x4E}, {0x8F,0xD6},
+ {0xBB,0xA5}, {0xE4,0x4D}, {0xBB,0x7D}, {0x99,0xD8},
+ {0xBD,0xCF}, {0xE4,0x4F}, {0xBB,0xA4}, {0xE4,0x4B},
+ {0xBB,0xA6}, {0x8F,0xD3}, {0xBB,0x79}, {0xB8,0xDB},
+ {0xBB,0x7C}, {0xBB,0x7A}, {0xBB,0x7E}, {0xBB,0xA2},
+ {0xBB,0x77}, {0xBB,0xA7}, {0xBB,0xA3}, {0x8F,0xE5},
+ {0xBB,0xA1}, {0xE4,0x4A}, {0x8F,0xE9}, {0xBD,0xD6},
+ {0xBD,0xD2}, {0x99,0xD9}, {0xBD,0xD9}, {0xE7,0xD6},
+ {0xBD,0xDA}, {0xE7,0xE2}, {0xE7,0xDB}, {0xBD,0xCB},
+ {0xE7,0xE3}, {0xE7,0xDD}, {0xBD,0xD5}, {0xE7,0xDE},
+ {0xBD,0xD4}, {0xE7,0xE1}, {0xBD,0xCE}, {0xE7,0xDF},
+ {0xE7,0xD5}, {0xBD,0xCD}, {0xEB,0xAA}, {0xBD,0xD3},
+ {0xBD,0xD0}, {0xBD,0xD8}, {0xE7,0xD4}, {0xE7,0xD8},
+ {0xBD,0xCC}, {0xE7,0xD7}, {0xE7,0xD9}, {0xE7,0xDA},
+ {0xBD,0xD7}, {0xE7,0xDC}, {0xE7,0xE0}, {0xE7,0xE4},
+ {0x92,0x7C}, {0xBD,0xDB}, {0xBF,0xD2}, {0xEB,0xA5},
+ {0xEB,0xAB}, {0xEB,0xA8}, {0xEB,0x7E}, {0xEB,0xAC},
+ {0xEB,0xA1}, {0xEB,0xA7}, {0xBF,0xCD}, {0xBF,0xD3},
+ {0xEB,0xAD}, {0x9C,0x45}, {0xBF,0xCF}, {0xBF,0xD9},
+ {0xBF,0xD4}, {0xEB,0xAF}, {0xEB,0xA9}, {0xBF,0xD0},
+ {0xEB,0xA2}, {0xBF,0xDA}, {0xEB,0xA3}, {0xEB,0xA4},
+ {0xBF,0xDB}, {0xBF,0xD8}, {0xBD,0xD1}, {0xBF,0xCE},
+ {0xEB,0xB0}, {0xBF,0xDC}, {0xBF,0xD5}, {0xEB,0xAE},
+ {0xBF,0xD1}, {0xBF,0xD6}, {0xBF,0xD7}, {0xC1,0xC3},
+ {0xEE,0xA4}, {0xEE,0xAD}, {0xEE,0xAA}, {0xEE,0xAC},
+ {0xC1,0xC0}, {0xEE,0xA5}, {0x8F,0xDE}, {0xEE,0xAB},
+ {0xC1,0xBC}, {0xEE,0xA7}, {0xC1,0xC4}, {0xEE,0xA3},
+ {0xEE,0xA8}, {0xEE,0xAF}, {0xEB,0xA6}, {0xEE,0xA9},
+ {0xEE,0xA2}, {0xC1,0xBD}, {0xEE,0xA1}, {0xC1,0xBE},
+ {0xEE,0xB0}, {0xC1,0xBF}, {0xEE,0xAE}, {0xC1,0xC2},
+ {0xEE,0x7E}, {0x8F,0xDF}, {0xC1,0xC1}, {0xEE,0xA6},
+ {0xF0,0xDC}, {0xF0,0xEA}, {0xF0,0xE5}, {0xF0,0xE7},
+ {0xF0,0xDB}, {0xC2,0xD3}, {0xF0,0xDA}, {0xC2,0xD6},
+ {0xC2,0xD5}, {0xA0,0x4B}, {0xF0,0xE9}, {0xF0,0xE1},
+ {0xF0,0xDE}, {0xF0,0xE4}, {0xF0,0xDD}, {0xF0,0xDF},
+ {0xF0,0xE8}, {0xF0,0xE6}, {0xC2,0xD4}, {0xF0,0xED},
+ {0xF0,0xEB}, {0xF0,0xE2}, {0xF0,0xEC}, {0xF0,0xE3},
+ {0x8F,0xE2}, {0xF2,0xF9}, {0xC3,0xCF}, {0xF3,0x41},
+ {0xA0,0xCC}, {0xF6,0x4F}, {0xC3,0xD6}, {0xF0,0xE0},
+ {0xF2,0xF7}, {0xC3,0xD2}, {0xF2,0xF8}, {0xF2,0xFD},
+ {0x8F,0xE3}, {0x8F,0xE4}, {0xC3,0xD4}, {0xC3,0xD5},
+ {0xF2,0xF6}, {0xF3,0x40}, {0xF3,0x42}, {0xF2,0xFA},
+ {0xF2,0xFC}, {0xF2,0xFE}, {0xF2,0xFB}, {0xF3,0x43},
+ {0xC3,0xD1}, {0xC3,0xD7}, {0xC3,0xD3}, {0xC3,0xD0},
+ {0xF4,0xD0}, {0x9B,0xC4}, {0xC4,0xB7}, {0xF4,0xCE},
+ {0x9B,0xFC}, {0xF4,0xD2}, {0xF4,0xD3}, {0xC4,0xB5},
+ {0xF4,0xD4}, {0xF4,0xD1}, {0x96,0x4C}, {0xF4,0xCF},
+ {0xC4,0xB8}, {0xC4,0xB4}, {0xF4,0xD5}, {0xC4,0xB6},
+ {0xC4,0xB3}, {0xC4,0xFE}, {0xC5,0x40}, {0xF6,0x4E},
+ {0xF6,0x4D}, {0xF6,0x50}, {0xF6,0x51}, {0xC5,0x41},
+ {0xF7,0x56}, {0xF7,0x5B}, {0xC5,0xAA}, {0x9A,0xF6},
+ {0xF7,0x58}, {0x8C,0xAE}, {0xF7,0x57}, {0xF7,0x5A},
+ {0xF7,0x59}, {0xF8,0x43}, {0xC5,0xDC}, {0xF8,0x42},
+ {0xF8,0x40}, {0xF8,0x41}, {0x8F,0xE7}, {0xC5,0xFE},
+ {0xC5,0xFD}, {0xF8,0xC1}, {0xF8,0xC2}, {0xC6,0x40},
+ {0xF9,0x4D}, {0xF9,0x4E}, {0xC6,0x67}, {0x8F,0xE8},
+ {0xC6,0x6D}, {0xF9,0xA9}, {0xF9,0xC8}, {0x8B,0xE7},
+ {0x89,0x7A}, {0x89,0x7B}, {0xA8,0xA6}, {0xD7,0xCD},
+ {0xD7,0xCE}, {0xE0,0x52}, {0xE4,0x50}, {0xE7,0xE5},
+ {0xC1,0xC6}, {0xC1,0xC5}, {0xF0,0xEE}, {0xF3,0x44},
+ {0xF8,0x44}, {0xA8,0xA7}, {0xD3,0xDE}, {0xB0,0x5A},
+ {0xB3,0x61}, {0xE0,0x54}, {0xE0,0x53}, {0xBD,0xDC},
+ {0xE7,0xE6}, {0xBD,0xDD}, {0xEE,0xB1}, {0xC2,0xD7},
+ {0x99,0xDA}, {0xC6,0x76}, {0xA8,0xA8}, {0xCD,0xCB},
+ {0xD3,0xDF}, {0xB3,0x62}, {0xD7,0xCF}, {0xD7,0xD0},
+ {0xDB,0xE5}, {0xB6,0x48}, {0xB8,0xE6}, {0xE0,0x56},
+ {0xE0,0x55}, {0xE0,0x57}, {0xE4,0x51}, {0xE4,0x52},
+ {0xBB,0xA8}, {0xBF,0xDD}, {0xBD,0xDE}, {0xBF,0xDE},
+ {0xEE,0xB5}, {0xEE,0xB2}, {0xEE,0xB4}, {0xEE,0xB3},
+ {0xC1,0xC7}, {0xF0,0xEF}, {0xF3,0x46}, {0xF3,0x45},
+ {0xCB,0xA4}, {0xB0,0x5C}, {0xB0,0x5B}, {0xD3,0xE0},
+ {0xD7,0xD1}, {0xDB,0xE7}, {0xDB,0xE6}, {0xB6,0x49},
+ {0xE0,0x59}, {0xE0,0x5A}, {0xE0,0x58}, {0xB8,0xE8},
+ {0xB8,0xE7}, {0xBB,0xAA}, {0xBB,0xA9}, {0xE7,0xE7},
+ {0xEB,0xB3}, {0xEB,0xB1}, {0xEB,0xB2}, {0xBF,0xDF},
+ {0xEE,0xB7}, {0xEE,0xB6}, {0xF0,0xF2}, {0xF0,0xF1},
+ {0xF0,0xF0}, {0xF3,0x47}, {0x8F,0xED}, {0xF9,0xAA},
+ {0xA8,0xA9}, {0xAD,0x73}, {0x95,0xC0}, {0xAD,0x74},
+ {0xB0,0x5D}, {0xB0,0x5E}, {0xD3,0xE2}, {0xD3,0xE1},
+ {0xD7,0xD2}, {0xB3,0x68}, {0xB3,0x66}, {0xB3,0x63},
+ {0xB3,0x67}, {0xB3,0x65}, {0xB3,0x64}, {0xA0,0xCB},
+ {0xB6,0x4A}, {0xDB,0xEA}, {0xB8,0xED}, {0xB6,0x4C},
+ {0xB6,0x51}, {0xDB,0xEC}, {0xB6,0x53}, {0xB6,0x52},
+ {0xB6,0x55}, {0xDB,0xEB}, {0xDB,0xE8}, {0xB6,0x4F},
+ {0xB6,0x4B}, {0xB6,0x4D}, {0xDB,0xE9}, {0xB6,0x54},
+ {0xB6,0x50}, {0xB6,0x4E}, {0xB8,0xEF}, {0xB8,0xEE},
+ {0xB8,0xEC}, {0xB8,0xF0}, {0xB8,0xEA}, {0xB8,0xEB},
+ {0xB8,0xE9}, {0xE0,0x5B}, {0x9E,0x48}, {0xE4,0x54},
+ {0xBB,0xAC}, {0xBB,0xAD}, {0xBB,0xAB}, {0x99,0xDB},
+ {0xE4,0x53}, {0x8F,0xF3}, {0xE4,0x55}, {0xE7,0xEA},
+ {0xE7,0xEC}, {0x8F,0xF9}, {0xBD,0xE7}, {0xE7,0xED},
+ {0xBD,0xE0}, {0xE7,0xE9}, {0xBD,0xDF}, {0xBD,0xE9},
+ {0xBD,0xE5}, {0xBD,0xE6}, {0xBD,0xE2}, {0xE7,0xE8},
+ {0xBD,0xE1}, {0xE7,0xEE}, {0xE7,0xEB}, {0x95,0xC1},
+ {0xBD,0xE8}, {0xA0,0x4E}, {0xBD,0xE3}, {0xBD,0xE4},
+ {0xEB,0xB5}, {0xEB,0xB7}, {0xEB,0xB6}, {0x99,0xDC},
+ {0xEB,0xB8}, {0xBF,0xE0}, {0xEB,0xB4}, {0xA0,0x64},
+ {0xC1,0xCB}, {0xEE,0xB8}, {0xC1,0xC8}, {0xC1,0xCC},
+ {0xC1,0xCA}, {0xC1,0xC9}, {0xF0,0xF3}, {0xF0,0xF6},
+ {0xF0,0xF5}, {0x8F,0xF7}, {0xF0,0xF4}, {0xC2,0xD8},
+ {0xF3,0x48}, {0xF3,0x49}, {0xC3,0xD8}, {0xF3,0x4A},
+ {0xC3,0xD9}, {0x89,0xB0}, {0xA0,0x48}, {0xC4,0xBA},
+ {0xC4,0xB9}, {0xF6,0x52}, {0x8F,0xFB}, {0x8F,0xF6},
+ {0xC5,0x42}, {0xF6,0x53}, {0xF7,0x5C}, {0xC5,0xAB},
+ {0xC5,0xAC}, {0x9D,0xDC}, {0xF8,0x45}, {0xC6,0x42},
+ {0x99,0xDD}, {0x8B,0xE8}, {0xA8,0xAA}, {0xB3,0x6A},
+ {0xB3,0x69}, {0xE0,0x5C}, {0xE0,0x5D}, {0xBB,0xAE},
+ {0xEB,0xB9}, {0xBD,0xEA}, {0xEB,0xBA}, {0xEE,0xB9},
+ {0xA8,0xAB}, {0xD0,0xB2}, {0xAD,0x76}, {0xAD,0x75},
+ {0xD3,0xE3}, {0xB0,0x5F}, {0xD3,0xE4}, {0xD7,0xD5},
+ {0x92,0xC1}, {0xD7,0xD4}, {0xD7,0xD3}, {0xDB,0xEE},
+ {0xB6,0x58}, {0x9F,0xD6}, {0xDB,0xED}, {0xB6,0x57},
+ {0xDB,0xEF}, {0xB6,0x56}, {0xE0,0x5F}, {0xE0,0x62},
+ {0xE0,0x60}, {0xE0,0x61}, {0xE0,0x65}, {0xE0,0x5E},
+ {0xE0,0x66}, {0xE0,0x63}, {0xE0,0x64}, {0xBB,0xB0},
+ {0xE4,0x56}, {0xBB,0xAF}, {0xE7,0xF2}, {0xE7,0xF0},
+ {0xBD,0xEB}, {0xE7,0xEF}, {0xE7,0xF1}, {0xBD,0xEC},
+ {0xEB,0xBB}, {0xA0,0xD2}, {0xEB,0xBC}, {0xC1,0xCD},
+ {0x90,0x40}, {0xF3,0x4C}, {0xF3,0x4E}, {0xF3,0x4B},
+ {0xF3,0x4D}, {0xF4,0xD6}, {0xF6,0x54}, {0xF9,0x6F},
+ {0xA8,0xAC}, {0xAD,0x77}, {0xD3,0xE5}, {0xD3,0xE7},
+ {0xD3,0xE6}, {0xD7,0xD8}, {0xB3,0x6C}, {0xD7,0xD6},
+ {0xB3,0x6B}, {0xD7,0xD9}, {0x8A,0xC4}, {0xD7,0xDA},
+ {0xD7,0xD7}, {0x99,0xE0}, {0xDB,0xFB}, {0xB6,0x60},
+ {0xDB,0xF3}, {0xDB,0xF9}, {0xB6,0x5B}, {0xB6,0x5E},
+ {0xDB,0xF2}, {0xB6,0x59}, {0xDB,0xF6}, {0xE0,0x6C},
+ {0xB6,0x5D}, {0xDB,0xF1}, {0x9F,0xF0}, {0xDB,0xF7},
+ {0xDB,0xF4}, {0xDB,0xFA}, {0xDB,0xF0}, {0xDB,0xF8},
+ {0xB6,0x5C}, {0xB6,0x5F}, {0xDB,0xF5}, {0xB6,0x5A},
+ {0xB8,0xF2}, {0xE0,0x68}, {0xB8,0xF1}, {0xE0,0x6F},
+ {0xE0,0x6E}, {0xB8,0xF8}, {0xB8,0xF9}, {0xE0,0x70},
+ {0xB8,0xF3}, {0xE0,0x6D}, {0xB8,0xF7}, {0xE0,0x72},
+ {0xE0,0x69}, {0xE0,0x6B}, {0xB8,0xF4}, {0xE0,0x67},
+ {0xE0,0x6A}, {0xE0,0x71}, {0xB8,0xF5}, {0xE0,0x73},
+ {0xB8,0xF6}, {0xBB,0xB1}, {0xE4,0x5B}, {0xE4,0x61},
+ {0xE4,0x59}, {0xE4,0x62}, {0x9F,0xF3}, {0xE4,0x58},
+ {0xE4,0x5D}, {0xE4,0x63}, {0xE4,0x60}, {0xE4,0x5F},
+ {0xE4,0x5E}, {0xE4,0x57}, {0xE4,0x5C}, {0xE4,0x5A},
+ {0x9D,0xBF}, {0xBD,0xF1}, {0xBD,0xEE}, {0xE7,0xFB},
+ {0xE8,0x41}, {0xE8,0x43}, {0xE8,0x40}, {0xE7,0xF8},
+ {0xE7,0xFA}, {0xE8,0x45}, {0xE8,0x42}, {0xE7,0xFC},
+ {0xE8,0x46}, {0xE7,0xF9}, {0xE8,0x44}, {0xBD,0xEF},
+ {0xBD,0xF5}, {0xBD,0xF3}, {0xE7,0xF3}, {0xBD,0xF4},
+ {0xBD,0xF0}, {0xE7,0xF4}, {0xE7,0xF6}, {0xE7,0xF5},
+ {0xE7,0xFD}, {0xE7,0xFE}, {0x9F,0xF6}, {0xBD,0xF2},
+ {0x95,0xC8}, {0xBD,0xED}, {0x9E,0x5A}, {0xE7,0xF7},
+ {0xEB,0xC6}, {0xBF,0xE2}, {0xEB,0xBD}, {0xBF,0xE3},
+ {0xBF,0xE6}, {0xEB,0xC2}, {0xEB,0xBF}, {0xBF,0xE5},
+ {0x99,0xE3}, {0xEB,0xC3}, {0xEB,0xC4}, {0xEB,0xBE},
+ {0xEB,0xC7}, {0xEB,0xC0}, {0xEB,0xC5}, {0xBF,0xE4},
+ {0xBF,0xE1}, {0xEB,0xC1}, {0x8A,0x4A}, {0xEE,0xBF},
+ {0xC1,0xD0}, {0xC1,0xCE}, {0xC1,0xD1}, {0xC1,0xCF},
+ {0xEE,0xBE}, {0xEE,0xBB}, {0xEE,0xBA}, {0x9F,0xF1},
+ {0xEE,0xBD}, {0xEE,0xBC}, {0xF1,0x45}, {0xC2,0xDE},
+ {0xF0,0xFB}, {0xF0,0xFA}, {0xC2,0xD9}, {0xF1,0x41},
+ {0xF1,0x40}, {0xF0,0xF7}, {0xF1,0x43}, {0xF0,0xFC},
+ {0xC2,0xDD}, {0xF0,0xF9}, {0xF1,0x42}, {0xF0,0xF8},
+ {0xC2,0xDA}, {0xC2,0xDC}, {0xF0,0xFD}, {0xC2,0xDB},
+ {0xF0,0xFE}, {0x8A,0xA7}, {0xF1,0x44}, {0xF3,0x52},
+ {0xC3,0xDE}, {0xF3,0x4F}, {0xF3,0x53}, {0x99,0xE6},
+ {0xC3,0xDB}, {0xF3,0x51}, {0xC3,0xE0}, {0x9F,0xF7},
+ {0xC3,0xDD}, {0x9F,0xED}, {0xF3,0x50}, {0xC3,0xDF},
+ {0xF3,0x54}, {0xC3,0xDA}, {0x8A,0x5C}, {0x9D,0xAE},
+ {0xC4,0xBC}, {0xC4,0xBE}, {0xF4,0xD9}, {0xC4,0xBD},
+ {0xF4,0xD7}, {0xC3,0xDC}, {0xF4,0xD8}, {0xC4,0xBB},
+ {0xC5,0x43}, {0xC5,0x45}, {0xF6,0x56}, {0xC5,0x44},
+ {0xF6,0x55}, {0xF7,0x61}, {0xC5,0xAD}, {0xF7,0x60},
+ {0xC5,0xAE}, {0xF7,0x5E}, {0xF7,0x5D}, {0xF7,0x62},
+ {0xF7,0x63}, {0xF8,0x46}, {0xF7,0x5F}, {0xF8,0xC6},
+ {0xF8,0xC3}, {0xF8,0xC4}, {0xF8,0xC5}, {0xC6,0x5C},
+ {0xF9,0x51}, {0xF9,0x50}, {0xF9,0x4F}, {0xF9,0x70},
+ {0x95,0xC9}, {0xF9,0xBE}, {0xF9,0xAB}, {0xC6,0x6E},
+ {0xA8,0xAD}, {0xB0,0x60}, {0x90,0x48}, {0x99,0xE8},
+ {0xB8,0xFA}, {0x90,0x49}, {0x8C,0xBA}, {0xBD,0xF6},
+ {0x90,0xB1}, {0xEB,0xC8}, {0xC2,0xDF}, {0xF3,0x55},
+ {0x90,0x4A}, {0xF9,0xAC}, {0xA8,0xAE}, {0xAA,0xEE},
+ {0xAD,0x79}, {0xAD,0x78}, {0x99,0xEA}, {0xB0,0x63},
+ {0xD3,0xE8}, {0xB0,0x61}, {0xD3,0xE9}, {0xB0,0x62},
+ {0xD7,0xDF}, {0xD7,0xDB}, {0x9B,0xD1}, {0xB3,0x6D},
+ {0xD7,0xDE}, {0xD7,0xDD}, {0xD7,0xDC}, {0xB3,0x6E},
+ {0xD7,0xE0}, {0xD7,0xE1}, {0x99,0xEB}, {0x99,0xEC},
+ {0xDC,0x43}, {0xDC,0x41}, {0xDC,0x45}, {0xDC,0x46},
+ {0xDC,0x4C}, {0xDC,0x48}, {0xDC,0x4A}, {0x99,0xED},
+ {0xDC,0x42}, {0xDB,0xFC}, {0xDC,0x49}, {0x99,0xEE},
+ {0xDC,0x4B}, {0xDC,0x44}, {0xDC,0x47}, {0xDB,0xFD},
+ {0xB6,0x62}, {0xDC,0x40}, {0xDB,0xFE}, {0xB6,0x61},
+ {0xB6,0x63}, {0xB8,0xFD}, {0xE0,0x75}, {0xE0,0x77},
+ {0xE0,0x76}, {0xE0,0x7B}, {0xB8,0xFB}, {0xE0,0x78},
+ {0xE0,0x74}, {0xE0,0x79}, {0xE0,0x7A}, {0xB8,0xFC},
+ {0xB8,0xFE}, {0xE0,0x7C}, {0xE4,0x67}, {0xE4,0x66},
+ {0xE4,0x64}, {0xE4,0x65}, {0xBB,0xB3}, {0xBB,0xB5},
+ {0xBB,0xB2}, {0xBB,0xB4}, {0xE8,0x4D}, {0xE8,0x4E},
+ {0xE8,0x49}, {0x90,0x4C}, {0xE8,0x4A}, {0xBD,0xF8},
+ {0xBD,0xFD}, {0xBD,0xF7}, {0xBD,0xFE}, {0xBD,0xF9},
+ {0xE8,0x4B}, {0xE8,0x4C}, {0xE8,0x48}, {0xBE,0x40},
+ {0xBD,0xFB}, {0xBD,0xFA}, {0xBD,0xFC}, {0xE8,0x47},
+ {0x90,0x4D}, {0xEB,0xCA}, {0xBF,0xE8}, {0x95,0xCB},
+ {0xEB,0xCC}, {0xBF,0xEA}, {0xEB,0xCF}, {0xEB,0xCB},
+ {0xEB,0xC9}, {0xEB,0xCE}, {0xBF,0xE9}, {0xEB,0xCD},
+ {0xBF,0xE7}, {0xC1,0xD3}, {0xC1,0xD6}, {0xEE,0xC1},
+ {0x97,0xE2}, {0xC1,0xD4}, {0xEE,0xC0}, {0xC1,0xD2},
+ {0xC1,0xD5}, {0xF1,0x46}, {0xF1,0x47}, {0xF1,0x48},
+ {0xC2,0xE0}, {0x95,0xCC}, {0xF1,0x49}, {0xC2,0xE1},
+ {0xC3,0xE2}, {0xF3,0x58}, {0xF3,0x59}, {0xF3,0x57},
+ {0xF3,0x56}, {0xF3,0x5A}, {0xC3,0xE1}, {0xF4,0xDD},
+ {0xF4,0xDB}, {0xF4,0xDC}, {0xF4,0xDE}, {0xF4,0xDA},
+ {0xF4,0xDF}, {0xF6,0x58}, {0x9F,0x78}, {0xF6,0x59},
+ {0xF6,0x57}, {0xC5,0x46}, {0xF7,0x64}, {0xC5,0xAF},
+ {0xF7,0x65}, {0xF8,0x48}, {0xF8,0x47}, {0x89,0x7C},
+ {0x89,0x7D}, {0x89,0x7E}, {0x99,0x5D}, {0xA8,0xAF},
+ {0xB6,0x64}, {0xB9,0x40}, {0x9B,0x5A}, {0xBB,0xB6},
+ {0x90,0x50}, {0xBF,0xEC}, {0x8C,0x4F}, {0xBF,0xEB},
+ {0xC3,0xE3}, {0xC4,0x7C}, {0xC5,0x47}, {0xA8,0xB0},
+ {0xB0,0x64}, {0xB9,0x41}, {0x90,0x54}, {0xF3,0x5B},
+ {0xC6,0xD6}, {0x9A,0xA8}, {0x99,0xEF}, {0xFE,0xEB},
+ {0x9D,0xA3}, {0x9D,0xA1}, {0x99,0x43}, {0x99,0x45},
+ {0x9D,0x7D}, {0xCB,0xA6}, {0x99,0xF0}, {0xA8,0xB1},
+ {0xA8,0xB4}, {0xA8,0xB3}, {0xA8,0xB2}, {0xCB,0xA5},
+ {0x99,0xF1}, {0xCD,0xCD}, {0x99,0xF2}, {0xCD,0xCF},
+ {0xAA,0xEF}, {0x8C,0xBC}, {0x9D,0x60}, {0xAA,0xF1},
+ {0xCD,0xCC}, {0xCD,0xCE}, {0xAA,0xF0}, {0xCD,0xD1},
+ {0xCD,0xD0}, {0xCD,0xD2}, {0xA0,0xA3}, {0xD0,0xB6},
+ {0xD0,0xB4}, {0xAD,0x7C}, {0xD0,0xB3}, {0xAD,0xA3},
+ {0xAD,0x7E}, {0xAD,0x7B}, {0xAD,0xA4}, {0xAD,0x7D},
+ {0xAD,0xA2}, {0xAD,0xA1}, {0xD0,0xB5}, {0xAD,0x7A},
+ {0xB0,0x6A}, {0xD3,0xEB}, {0xD3,0xF1}, {0xB0,0x67},
+ {0xB0,0x6E}, {0x90,0x5B}, {0xB0,0x69}, {0xD3,0xEE},
+ {0xD3,0xF0}, {0xB0,0x6C}, {0xD3,0xEA}, {0xD3,0xED},
+ {0xB0,0x68}, {0xB0,0x65}, {0xD3,0xEC}, {0xB0,0x6B},
+ {0xD3,0xEF}, {0xB0,0x6D}, {0xB0,0x66}, {0x9E,0xDB},
+ {0xD7,0xE3}, {0xD7,0xE6}, {0xB3,0x70}, {0xB3,0x7A},
+ {0xB3,0x76}, {0xD7,0xE4}, {0x9D,0x79}, {0xB3,0x7E},
+ {0xB3,0x77}, {0xB3,0x7C}, {0xB3,0x72}, {0xB3,0x6F},
+ {0xB3,0x71}, {0xB3,0x7D}, {0xD7,0xE5}, {0xB3,0x75},
+ {0xB3,0x78}, {0xB3,0x74}, {0xB3,0x79}, {0xD7,0xE7},
+ {0xB3,0x7B}, {0xB3,0x73}, {0xD7,0xE2}, {0xDC,0x4D},
+ {0xB6,0x65}, {0xDC,0x4F}, {0xB6,0x67}, {0xB6,0x69},
+ {0x99,0xF3}, {0xDC,0x4E}, {0xB6,0x66}, {0xB6,0x6A},
+ {0x90,0x62}, {0xB6,0x68}, {0xB9,0x47}, {0xE0,0xA3},
+ {0xB9,0x4F}, {0xE0,0x7E}, {0xB9,0x50}, {0xB9,0x45},
+ {0xE0,0xA1}, {0xB9,0x4A}, {0xE0,0xA2}, {0xB9,0x43},
+ {0xB9,0x42}, {0x9F,0x55}, {0xB9,0x4D}, {0xB9,0x4C},
+ {0xB9,0x4B}, {0xB9,0x49}, {0xB9,0x4E}, {0xE0,0x7D},
+ {0xB9,0x44}, {0xB9,0x46}, {0xB9,0x48}, {0x9B,0xF9},
+ {0xBB,0xB8}, {0xBB,0xBB}, {0xBB,0xBF}, {0xBB,0xB9},
+ {0xBB,0xBE}, {0xBB,0xBC}, {0xBB,0xB7}, {0x90,0x65},
+ {0xBB,0xBD}, {0xBB,0xBA}, {0x96,0xE0}, {0xE8,0x52},
+ {0xBE,0x43}, {0xBE,0x41}, {0xE8,0x53}, {0x98,0xBE},
+ {0xBE,0x44}, {0xBE,0x42}, {0xE8,0x51}, {0xE8,0x50},
+ {0xBF,0xF0}, {0xE8,0x4F}, {0xBF,0xEE}, {0xBF,0xED},
+ {0xEB,0xD0}, {0xBE,0x45}, {0xBF,0xEF}, {0xEB,0xD1},
+ {0xBF,0xF2}, {0xEB,0xD2}, {0xBF,0xF1}, {0xC1,0xD8},
+ {0xEE,0xC3}, {0xC1,0xD7}, {0xC1,0xDC}, {0xC1,0xDA},
+ {0xC1,0xDB}, {0xC2,0xE3}, {0xC1,0xD9}, {0xEE,0xC2},
+ {0xEB,0xD3}, {0xC2,0xE2}, {0xC2,0xE4}, {0xC3,0xE4},
+ {0xC3,0xE5}, {0xF4,0xE0}, {0xC5,0xDE}, {0xC5,0xDD},
+ {0xA8,0xB6}, {0xCA,0x55}, {0xB0,0x6F}, {0xCA,0x52},
+ {0xCA,0x53}, {0xCA,0x51}, {0xCA,0x54}, {0xCB,0xAA},
+ {0xCB,0xA7}, {0xCB,0xAC}, {0xCB,0xA8}, {0xA8,0xB7},
+ {0xA8,0xBA}, {0xCB,0xA9}, {0xA8,0xB9}, {0xCB,0xAB},
+ {0x90,0x68}, {0xA8,0xB8}, {0x90,0x6C}, {0xCD,0xD5},
+ {0xCD,0xD7}, {0xAA,0xF4}, {0xCD,0xD3}, {0xCD,0xD6},
+ {0xCD,0xD4}, {0xAA,0xF2}, {0xAA,0xF5}, {0xAA,0xF3},
+ {0x95,0xD8}, {0xD0,0xB8}, {0xD0,0xBC}, {0xD0,0xB9},
+ {0xAD,0xA7}, {0xAD,0xA8}, {0x90,0x6A}, {0xD0,0xBB},
+ {0xD0,0xBD}, {0xD0,0xBF}, {0xAD,0xA5}, {0xD0,0xBE},
+ {0xAD,0xA6}, {0xD7,0xEE}, {0xD0,0xBA}, {0xD3,0xF2},
+ {0xD3,0xFB}, {0xD3,0xF9}, {0xD3,0xF4}, {0xD3,0xF5},
+ {0xD3,0xFA}, {0xD3,0xFC}, {0xB0,0x71}, {0xD3,0xF7},
+ {0xD3,0xF3}, {0xB0,0x70}, {0xB0,0x72}, {0xD3,0xF6},
+ {0xD3,0xFD}, {0xD3,0xF8}, {0xB3,0xA1}, {0xD7,0xF1},
+ {0xD7,0xE9}, {0xD7,0xEF}, {0xD7,0xF0}, {0xB3,0xA2},
+ {0xD7,0xE8}, {0xD7,0xEA}, {0xD0,0xB7}, {0xD7,0xEC},
+ {0xD7,0xED}, {0xD7,0xEB}, {0xB6,0x6C}, {0xDC,0x56},
+ {0xEB,0xD4}, {0xDC,0x57}, {0xDC,0x54}, {0xB3,0xA3},
+ {0xB6,0x6E}, {0xDC,0x53}, {0xDC,0x59}, {0xDC,0x58},
+ {0xB6,0x6B}, {0xDC,0x5C}, {0xDC,0x52}, {0xDC,0x5B},
+ {0xDC,0x50}, {0xDC,0x5A}, {0xDC,0x55}, {0xB6,0x6D},
+ {0xE0,0xAA}, {0xE0,0xA5}, {0xE0,0xAB}, {0xE0,0xA6},
+ {0xE0,0xA4}, {0xE0,0xA7}, {0xB9,0x51}, {0xE0,0xA9},
+ {0xE0,0xA8}, {0xB9,0x52}, {0xBB,0xC1}, {0xBB,0xC0},
+ {0xE4,0x6E}, {0xE4,0x71}, {0xE4,0x69}, {0xE4,0x6D},
+ {0xBB,0xC2}, {0xE4,0x6C}, {0xE4,0x6A}, {0xE4,0x70},
+ {0xE4,0x6B}, {0xE4,0x68}, {0xE4,0x6F}, {0xE8,0x59},
+ {0xBE,0x48}, {0xF1,0x4A}, {0xE8,0x56}, {0xE8,0x57},
+ {0xE8,0x55}, {0xDC,0x51}, {0xBE,0x47}, {0xE8,0x5A},
+ {0xE8,0x54}, {0xBE,0x46}, {0xBE,0x49}, {0xE8,0x58},
+ {0xEB,0xD5}, {0xBF,0xF3}, {0xEB,0xD6}, {0xEB,0xD7},
+ {0xEE,0xC4}, {0xC1,0xDD}, {0xF1,0x4B}, {0xF1,0x4C},
+ {0xF1,0x4D}, {0xF3,0x5D}, {0xF3,0x5C}, {0xF4,0xE2},
+ {0xF4,0xE1}, {0xF6,0x5B}, {0xF6,0x5C}, {0xF6,0x5A},
+ {0xF7,0x66}, {0xC5,0xB0}, {0xA8,0xBB}, {0xAD,0xAA},
+ {0xAD,0xA9}, {0xB0,0x75}, {0xB0,0x74}, {0xD4,0x40},
+ {0xD4,0x41}, {0xD3,0xFE}, {0x9F,0xB2}, {0xB0,0x73},
+ {0xD7,0xF5}, {0xD7,0xF6}, {0xD7,0xF2}, {0xB3,0xA4},
+ {0xD7,0xF3}, {0x9F,0xAE}, {0xD7,0xF4}, {0x9F,0xB0},
+ {0x89,0xAD}, {0xDC,0x5F}, {0xDC,0x61}, {0xDC,0x5D},
+ {0xDC,0x60}, {0xB6,0x6F}, {0xDC,0x5E}, {0xB6,0x70},
+ {0x90,0x6E}, {0xDD,0x73}, {0xB9,0x55}, {0xB9,0x54},
+ {0xB9,0x53}, {0xE0,0xAC}, {0xE0,0xAD}, {0x9E,0x71},
+ {0xE4,0x73}, {0xE4,0x75}, {0xBB,0xC6}, {0xBB,0xC3},
+ {0x9E,0x4A}, {0xBB,0xC5}, {0xBB,0xC4}, {0xE4,0x74},
+ {0xE4,0x72}, {0x9F,0xDC}, {0xE8,0x61}, {0xE8,0x5E},
+ {0xE8,0x5F}, {0xBE,0x4D}, {0xE8,0x60}, {0xE8,0x5B},
+ {0xE8,0x5C}, {0xBE,0x4A}, {0xBE,0x4B}, {0xE8,0x5D},
+ {0xBE,0x4C}, {0x89,0xAB}, {0xEB,0xDB}, {0x9F,0xB8},
+ {0xEB,0xDC}, {0xEB,0xD9}, {0xEB,0xDA}, {0xBF,0xF4},
+ {0xEB,0xD8}, {0xEE,0xC8}, {0xEE,0xC5}, {0xEE,0xC7},
+ {0xC1,0xE0}, {0xEE,0xCB}, {0xC1,0xDF}, {0xEE,0xC9},
+ {0xEE,0xCC}, {0xEE,0xCA}, {0xEE,0xC6}, {0xC1,0xDE},
+ {0xF1,0x4F}, {0xF1,0x50}, {0xF1,0x4E}, {0x90,0x70},
+ {0xF1,0x52}, {0xC2,0xE5}, {0xC2,0xE6}, {0xF3,0x5F},
+ {0xC3,0xE7}, {0xF1,0x51}, {0xF3,0x5E}, {0xC3,0xE6},
+ {0xF4,0xE5}, {0xF4,0xE6}, {0xC4,0xBF}, {0xF4,0xE4},
+ {0x8B,0x63}, {0xF4,0xE3}, {0xF6,0x5D}, {0xC5,0x48},
+ {0x95,0xDC}, {0xF8,0x49}, {0xF8,0xC8}, {0xF8,0xC7},
+ {0xC6,0x43}, {0xC6,0x5D}, {0xF8,0xC9}, {0xF9,0x71},
+ {0x90,0x71}, {0xC6,0x6F}, {0xA8,0xBC}, {0xAA,0xF6},
+ {0xB9,0x56}, {0xC4,0xC0}, {0xA8,0xBD}, {0xAD,0xAB},
+ {0xB3,0xA5}, {0xB6,0x71}, {0xC2,0xE7}, {0xAA,0xF7},
+ {0xD0,0xC1}, {0xD0,0xC0}, {0xD4,0x42}, {0xFC,0x5E},
+ {0xB0,0x78}, {0xB0,0x76}, {0xB0,0x7A}, {0xD4,0x44},
+ {0xB0,0x79}, {0xB0,0x77}, {0x89,0x49}, {0xD4,0x43},
+ {0xB3,0xA8}, {0xD7,0xFC}, {0x96,0x5B}, {0xB3,0xA7},
+ {0xB3,0xA9}, {0xD8,0x42}, {0xB3,0xAB}, {0xD7,0xFE},
+ {0xD8,0x40}, {0xD7,0xF7}, {0xB3,0xAA}, {0xD8,0x43},
+ {0xD7,0xF9}, {0xD7,0xFA}, {0xD7,0xF8}, {0xB3,0xA6},
+ {0x8C,0x50}, {0xD8,0x41}, {0xD7,0xFB}, {0xD7,0xFD},
+ {0x94,0xA6}, {0xDC,0x6D}, {0x8F,0xD5}, {0xDC,0x6C},
+ {0xDC,0x6A}, {0xDC,0x62}, {0xDC,0x71}, {0xDC,0x65},
+ {0xDC,0x6F}, {0xDC,0x76}, {0xDC,0x6E}, {0xB6,0x79},
+ {0x9E,0x73}, {0xB6,0x75}, {0xDC,0x63}, {0xDC,0x69},
+ {0xB6,0x77}, {0x90,0x75}, {0xDC,0x68}, {0xB6,0x78},
+ {0xB6,0x7A}, {0xDC,0x6B}, {0x99,0xF7}, {0xB6,0x72},
+ {0xB6,0x73}, {0xDC,0x77}, {0xDC,0x75}, {0xDC,0x74},
+ {0xDC,0x66}, {0xDC,0x72}, {0xB6,0x76}, {0x8C,0xBF},
+ {0xB6,0x74}, {0xDC,0x73}, {0xDC,0x64}, {0xDC,0x67},
+ {0xDC,0x70}, {0x99,0xF9}, {0x96,0x63}, {0x95,0xB9},
+ {0xE4,0xBA}, {0xE0,0xB7}, {0xE0,0xB0}, {0xE0,0xC3},
+ {0xE0,0xCC}, {0xE0,0xB3}, {0xB9,0x61}, {0x94,0xD4},
+ {0xE0,0xC0}, {0xB9,0x57}, {0xB9,0x59}, {0xB9,0x65},
+ {0xE0,0xB1}, {0xFC,0xFA}, {0xB9,0x5A}, {0xB9,0x5C},
+ {0xB9,0x66}, {0xB9,0x5B}, {0x90,0x77}, {0x90,0xAB},
+ {0xB9,0x64}, {0xE0,0xB9}, {0xE0,0xAE}, {0xB9,0x62},
+ {0xE0,0xB8}, {0xB9,0x5E}, {0xE0,0xCA}, {0xB9,0x63},
+ {0xE0,0xC8}, {0xE0,0xBC}, {0xE0,0xC6}, {0xB9,0x60},
+ {0xE0,0xAF}, {0xE0,0xC9}, {0xE0,0xC4}, {0x9D,0x4D},
+ {0xE0,0xCB}, {0xB9,0x58}, {0x99,0xFA}, {0xB9,0x67},
+ {0xB9,0x5D}, {0x92,0xE3}, {0xE0,0xB5}, {0x97,0xBB},
+ {0xE0,0xBD}, {0xE0,0xC1}, {0x90,0x78}, {0xE0,0xC5},
+ {0xB9,0x5F}, {0xE0,0xB4}, {0xE0,0xB2}, {0xE0,0xBE},
+ {0x99,0xFB}, {0xE0,0xBB}, {0xE0,0xBA}, {0x97,0xE0},
+ {0xE0,0xBF}, {0xE0,0xC2}, {0xE0,0xC7}, {0xE4,0x78},
+ {0x96,0xDC}, {0xBB,0xC7}, {0xE4,0xA4}, {0xE4,0x7A},
+ {0xBB,0xCC}, {0xBB,0xD0}, {0xE4,0xAD}, {0xE4,0xB5},
+ {0xE4,0xA6}, {0xBB,0xC8}, {0x9C,0xA8}, {0xE4,0xAA},
+ {0xE0,0xB6}, {0x97,0x72}, {0xBB,0xC9}, {0xE4,0xB1},
+ {0xE4,0xB6}, {0xE4,0xAE}, {0x94,0x40}, {0xE4,0xB0},
+ {0xE4,0xB9}, {0xE4,0xB2}, {0xE4,0x7E}, {0xE4,0xA9},
+ {0x92,0xF2}, {0xBB,0xD1}, {0xBB,0xCD}, {0xE4,0x7C},
+ {0xE4,0xAB}, {0xBB,0xCB}, {0xE4,0xA5}, {0xBB,0xCA},
+ {0xE4,0xB3}, {0xE4,0xA2}, {0xE4,0x79}, {0xBB,0xCE},
+ {0xE4,0xB8}, {0xE4,0x7B}, {0xE4,0xAF}, {0xE4,0xAC},
+ {0xE4,0xA7}, {0xE4,0x77}, {0xE4,0x76}, {0xE4,0xA1},
+ {0xE4,0xB4}, {0xBB,0xCF}, {0xE4,0xB7}, {0xE4,0x7D},
+ {0xE4,0xA3}, {0xBE,0x52}, {0x99,0xFD}, {0x99,0xFC},
+ {0xBE,0x5A}, {0xBE,0x55}, {0xE8,0xA4}, {0xE8,0xA1},
+ {0xE8,0x67}, {0xBE,0x50}, {0xF9,0xD7}, {0x96,0x4A},
+ {0xBE,0x4F}, {0xBE,0x56}, {0x96,0xD8}, {0x99,0xFE},
+ {0xE8,0x65}, {0xBE,0x54}, {0xE8,0x71}, {0xE8,0x63},
+ {0xE8,0x64}, {0xBE,0x4E}, {0xE8,0xA3}, {0xBE,0x58},
+ {0xE8,0x74}, {0xE8,0x79}, {0xE8,0x73}, {0xEB,0xEE},
+ {0xE8,0x6F}, {0xE8,0x77}, {0xE8,0x75}, {0xE8,0x68},
+ {0xE8,0x62}, {0xE8,0x7D}, {0xBE,0x57}, {0xE8,0x7E},
+ {0x90,0x4B}, {0xE8,0x78}, {0xE8,0x6D}, {0xE8,0x6B},
+ {0xE8,0x66}, {0xFA,0x41}, {0xE8,0x6E}, {0xE8,0x7B},
+ {0xE8,0x6A}, {0xE8,0x7A}, {0xE8,0xA2}, {0x9A,0x40},
+ {0xBE,0x53}, {0x97,0x5B}, {0xE8,0x76}, {0xE8,0x7C},
+ {0xE8,0x72}, {0xE8,0x6C}, {0xBE,0x51}, {0x9A,0x41},
+ {0x91,0xDD}, {0xE4,0xA8}, {0xE8,0x70}, {0xBE,0x59},
+ {0xE8,0x69}, {0x93,0xFC}, {0x9A,0x42}, {0x9A,0x43},
+ {0x96,0x59}, {0xEB,0xF4}, {0xBF,0xF7}, {0xEB,0xF3},
+ {0xEB,0xF0}, {0xEC,0x44}, {0xBF,0xFB}, {0x9A,0x44},
+ {0xEC,0x41}, {0xEB,0xF8}, {0xEC,0x43}, {0xEB,0xE9},
+ {0xEB,0xF6}, {0x90,0x51}, {0xBF,0xFD}, {0xEB,0xE1},
+ {0x94,0xBF}, {0xEB,0xDF}, {0xEC,0x42}, {0xEC,0x40},
+ {0xEB,0xFE}, {0xEB,0xED}, {0xEB,0xEC}, {0xEB,0xE2},
+ {0xC0,0x40}, {0xEB,0xE8}, {0xEB,0xF2}, {0xEB,0xFD},
+ {0xC0,0x43}, {0xEC,0x45}, {0xC1,0xE8}, {0xC0,0x45},
+ {0xBF,0xFE}, {0xEB,0xE6}, {0xEB,0xEF}, {0xEB,0xDE},
+ {0xEB,0xE0}, {0xBF,0xF5}, {0xC0,0x42}, {0xBF,0xFA},
+ {0xEB,0xE7}, {0xEB,0xF7}, {0xEB,0xF1}, {0xC0,0x41},
+ {0xEB,0xDD}, {0xC1,0xE3}, {0xEB,0xF9}, {0xEB,0xFC},
+ {0xBF,0xFC}, {0x90,0xA2}, {0xEB,0xEB}, {0xC0,0x44},
+ {0xBF,0xF9}, {0x9C,0xAB}, {0x97,0x76}, {0xBF,0xF8},
+ {0xEB,0xF5}, {0xEB,0xFB}, {0xBF,0xF6}, {0xEB,0xE4},
+ {0xEB,0xFA}, {0xEB,0xE5}, {0xFC,0x55}, {0xFE,0x45},
+ {0x94,0xA8}, {0x9A,0x45}, {0xFA,0x4B}, {0x9D,0xE1},
+ {0xEB,0xEA}, {0xEE,0xD2}, {0x96,0xD9}, {0xEE,0xD7},
+ {0xC1,0xE5}, {0xC1,0xE7}, {0xEE,0xDD}, {0xC1,0xE1},
+ {0xEE,0xEC}, {0xEE,0xE3}, {0xEE,0xD8}, {0xEE,0xD9},
+ {0xEE,0xE2}, {0xC1,0xEE}, {0xEE,0xE1}, {0xEE,0xD1},
+ {0xEE,0xE0}, {0xEE,0xD4}, {0xEE,0xED}, {0xC1,0xED},
+ {0xC1,0xEB}, {0xEE,0xD5}, {0xEE,0xE8}, {0x97,0x74},
+ {0xEE,0xDA}, {0xEE,0xE7}, {0xFD,0xF5}, {0xEE,0xE9},
+ {0xEE,0xD0}, {0xC1,0xE6}, {0x92,0xE5}, {0xEE,0xEA},
+ {0x96,0x45}, {0x91,0xDA}, {0xEE,0xDE}, {0x90,0xA3},
+ {0xC1,0xEA}, {0xEE,0xDB}, {0xA0,0x5F}, {0xC1,0xEC},
+ {0xEE,0xE4}, {0x90,0xAF}, {0x97,0xBF}, {0xC1,0xE4},
+ {0xEE,0xD6}, {0xEE,0xE5}, {0x91,0x4C}, {0xEE,0xDF},
+ {0xEB,0xE3}, {0xEE,0xE6}, {0xEE,0xD3}, {0x96,0x7A},
+ {0xC1,0xE9}, {0xEE,0xEB}, {0x91,0xDE}, {0xC1,0xE2},
+ {0xEE,0xCE}, {0x9A,0x46}, {0xFE,0xB0}, {0x97,0x79},
+ {0x94,0x6C}, {0xF1,0x60}, {0xF1,0x59}, {0xC2,0xE9},
+ {0xF1,0x54}, {0xF1,0x63}, {0xF1,0x5B}, {0xEE,0xDC},
+ {0x98,0x58}, {0xF1,0x65}, {0xF1,0x55}, {0xC2,0xE8},
+ {0xF1,0x5F}, {0xC2,0xEA}, {0xC2,0xF2}, {0xC2,0xF0},
+ {0xF1,0x61}, {0xC2,0xF1}, {0xF1,0x57}, {0x92,0x66},
+ {0xF1,0x58}, {0xF1,0x5D}, {0xF1,0x62}, {0x93,0xFB},
+ {0xEE,0xCD}, {0xC2,0xEB}, {0xF1,0x6A}, {0xF1,0x67},
+ {0xF1,0x6B}, {0xF1,0x5E}, {0xF1,0x5A}, {0xF1,0x68},
+ {0xF3,0x6A}, {0xF1,0x5C}, {0xC2,0xEE}, {0x9A,0x47},
+ {0xC2,0xED}, {0xEE,0xCF}, {0xC2,0xEF}, {0xF1,0x64},
+ {0xF1,0x66}, {0xC2,0xEC}, {0xF1,0x69}, {0xF1,0x53},
+ {0xF1,0x56}, {0x97,0x49}, {0x97,0x48}, {0x93,0x4A},
+ {0x9C,0xE2}, {0xF3,0x73}, {0xF3,0x63}, {0xC3,0xEB},
+ {0xF3,0x71}, {0x92,0x64}, {0xF3,0x61}, {0xC3,0xEC},
+ {0xF3,0x6C}, {0x91,0xDF}, {0xF3,0x68}, {0xC3,0xF1},
+ {0xF3,0x72}, {0xF3,0x62}, {0xF3,0x65}, {0xC3,0xE9},
+ {0xF3,0x74}, {0xFB,0x79}, {0xF3,0x6D}, {0xF3,0x70},
+ {0xC3,0xEF}, {0xC3,0xF4}, {0xC3,0xF2}, {0xF3,0x69},
+ {0xF3,0x64}, {0x96,0xD7}, {0xC3,0xED}, {0xC3,0xEE},
+ {0xF3,0x60}, {0xC3,0xEA}, {0x93,0x43}, {0xC3,0xE8},
+ {0xC3,0xF0}, {0xF3,0x6F}, {0xC3,0xF3}, {0xF3,0x6B},
+ {0xF3,0x75}, {0xC3,0xF5}, {0xF3,0x67}, {0xF3,0x6E},
+ {0xFD,0xCB}, {0xFE,0x7A}, {0x91,0xDB}, {0x8C,0x6A},
+ {0xF4,0xF3}, {0xF5,0x42}, {0xF4,0xF5}, {0xF4,0xFC},
+ {0xF3,0x66}, {0xF4,0xFA}, {0xF4,0xE9}, {0xF5,0x40},
+ {0xC4,0xC3}, {0xF4,0xED}, {0xF4,0xFE}, {0xF4,0xF4},
+ {0x97,0xAF}, {0xC4,0xC2}, {0x95,0xDD}, {0xF5,0x44},
+ {0xF4,0xF6}, {0x93,0x48}, {0xF4,0xFB}, {0xF4,0xFD},
+ {0xF4,0xE7}, {0xF5,0x41}, {0xF4,0xF2}, {0xF4,0xF7},
+ {0xF4,0xEB}, {0xF4,0xEF}, {0xF5,0x43}, {0xF4,0xF9},
+ {0xF4,0xE8}, {0xF4,0xEC}, {0xF4,0xEE}, {0xF4,0xF8},
+ {0x9A,0x4B}, {0xC4,0xC1}, {0xF4,0xF1}, {0xFC,0x45},
+ {0x9A,0x4D}, {0xF4,0xEA}, {0x91,0xBC}, {0x90,0xE2},
+ {0x90,0xB4}, {0x95,0xE1}, {0xF4,0xF0}, {0xF6,0x61},
+ {0xF6,0x66}, {0xC5,0x4F}, {0xF6,0x68}, {0x9A,0x4E},
+ {0xC5,0x49}, {0xF6,0x64}, {0xF6,0x6A}, {0xC5,0x4E},
+ {0xC5,0x4A}, {0xC5,0x4B}, {0xF6,0x60}, {0xF6,0x67},
+ {0xC5,0x4D}, {0xF6,0x65}, {0xC5,0x4C}, {0xF6,0x5F},
+ {0xF6,0x63}, {0xF6,0x62}, {0x9A,0x4F}, {0xF6,0x5E},
+ {0xF6,0x69}, {0xFE,0x40}, {0xFE,0x43}, {0xC5,0xB1},
+ {0xF7,0x6D}, {0xF7,0x70}, {0xF7,0x6C}, {0xF7,0x6E},
+ {0xF7,0x6F}, {0xF7,0x69}, {0xF7,0x6A}, {0xF7,0x67},
+ {0x96,0xDD}, {0xF7,0x6B}, {0xF7,0x68}, {0xC5,0xB2},
+ {0xC5,0xB3}, {0x9A,0x51}, {0xF8,0x4B}, {0xF8,0x4D},
+ {0x96,0xA7}, {0x90,0xB0}, {0xF8,0x4C}, {0xF8,0x4E},
+ {0xC5,0xE0}, {0xF8,0x4A}, {0xC5,0xDF}, {0xC5,0xE1},
+ {0x9C,0x4E}, {0x94,0x43}, {0xF8,0xCB}, {0xF8,0xCC},
+ {0xC6,0x44}, {0xF8,0xCA}, {0x8E,0xBA}, {0xF9,0x53},
+ {0xF9,0x52}, {0xF9,0x54}, {0xC6,0x5F}, {0xF9,0x55},
+ {0xC6,0x5E}, {0xF9,0x56}, {0xF9,0x72}, {0xF9,0x75},
+ {0xF9,0x74}, {0xC6,0x68}, {0xF9,0x73}, {0x9A,0x52},
+ {0xFC,0xC1}, {0xC6,0x72}, {0xC6,0x70}, {0xC6,0x71},
+ {0xC6,0x77}, {0xF9,0xC0}, {0xF9,0xC1}, {0xF9,0xBF},
+ {0xF9,0xC9}, {0x8B,0xE9}, {0x9C,0xAF}, {0x8B,0xFD},
+ {0x9A,0xBC}, {0x9A,0xB8}, {0x9A,0xAE}, {0x9A,0xA7},
+ {0x9A,0x53}, {0x9D,0x74}, {0xAA,0xF8}, {0x8B,0xEA},
+ {0xD8,0x44}, {0xDC,0x78}, {0xE8,0xA5}, {0xF3,0x76},
+ {0x8B,0xEB}, {0xAA,0xF9}, {0xAD,0xAC}, {0xB0,0x7B},
+ {0x90,0xB2}, {0xD8,0x45}, {0xD8,0x46}, {0xB3,0xAC},
+ {0xB6,0x7D}, {0xDC,0x7A}, {0xDC,0x79}, {0xB6,0xA3},
+ {0xB6,0x7C}, {0xDC,0x7B}, {0xB6,0x7E}, {0xB6,0xA2},
+ {0xB6,0xA1}, {0xB6,0x7B}, {0x95,0xE9}, {0x95,0xE8},
+ {0xB9,0x68}, {0x95,0xE6}, {0xE0,0xD0}, {0xE0,0xCE},
+ {0xE0,0xCF}, {0xE0,0xCD}, {0x90,0xB5}, {0xBB,0xD2},
+ {0x9A,0x54}, {0xBB,0xD5}, {0xBB,0xD7}, {0xBB,0xD6},
+ {0x90,0xB3}, {0x95,0xE7}, {0xBB,0xD3}, {0xBB,0xD4},
+ {0x8B,0x50}, {0xE8,0xA7}, {0xE8,0xA6}, {0xBE,0x5B},
+ {0xE8,0xA8}, {0xE8,0xA9}, {0xBE,0x5C}, {0xEC,0x4D},
+ {0xEC,0x4B}, {0xEE,0xF3}, {0xEC,0x49}, {0xEC,0x4A},
+ {0xC0,0x46}, {0xEC,0x46}, {0xEC,0x4E}, {0xEC,0x48},
+ {0xEC,0x4C}, {0xEE,0xEF}, {0xEE,0xF1}, {0xEE,0xF2},
+ {0xC1,0xF3}, {0xEE,0xEE}, {0xC1,0xF2}, {0xEE,0xF0},
+ {0xC1,0xEF}, {0xC1,0xF0}, {0xC1,0xF1}, {0xEC,0x47},
+ {0xC2,0xF5}, {0xF1,0x6E}, {0xF1,0x6C}, {0xF1,0x6D},
+ {0xC2,0xF3}, {0xC2,0xF6}, {0xC2,0xF4}, {0xF3,0x77},
+ {0xF3,0x78}, {0xC3,0xF6}, {0xF5,0x45}, {0xF5,0x47},
+ {0xF5,0x46}, {0xC4,0xC4}, {0xC5,0x50}, {0xF6,0x6D},
+ {0xF6,0x6C}, {0xF6,0x6B}, {0x8B,0xEC}, {0x9A,0x56},
+ {0xAA,0xFA}, {0x8B,0xFB}, {0xC9,0xAA}, {0xCA,0x58},
+ {0xA6,0xE9}, {0xCA,0x56}, {0xCA,0x59}, {0xCA,0x57},
+ {0xCB,0xAE}, {0xA8,0xC1}, {0xA8,0xC2}, {0xCB,0xB0},
+ {0xA8,0xBF}, {0xCB,0xAF}, {0xCB,0xAD}, {0xA8,0xC0},
+ {0xA8,0xBE}, {0x9A,0x57}, {0xA0,0xAA}, {0xCD,0xD8},
+ {0xCD,0xDB}, {0xAA,0xFD}, {0xCD,0xDA}, {0xCD,0xD9},
+ {0xAA,0xFC}, {0xAA,0xFB}, {0x9F,0xA6}, {0xAB,0x40},
+ {0xCD,0xDC}, {0xAA,0xFE}, {0x99,0xCC}, {0xD0,0xC6},
+ {0xAD,0xAE}, {0xAD,0xAF}, {0xAD,0xB0}, {0xD0,0xC7},
+ {0xD0,0xC3}, {0xAD,0xAD}, {0xD0,0xC4}, {0xD0,0xC5},
+ {0xD0,0xC2}, {0x9C,0x59}, {0xB0,0xA4}, {0xB0,0xA1},
+ {0xD4,0x45}, {0xB0,0xA2}, {0xB0,0xA5}, {0xD4,0x46},
+ {0xB0,0x7E}, {0xB0,0x7C}, {0xB0,0x7D}, {0xB0,0xA3},
+ {0x99,0xB5}, {0xB3,0xAD}, {0xD8,0x49}, {0xB3,0xB5},
+ {0xD8,0x48}, {0xD8,0x4B}, {0xB3,0xB1}, {0xD8,0x4A},
+ {0xB6,0xAB}, {0xB3,0xAF}, {0xB3,0xB2}, {0xB3,0xAE},
+ {0xB3,0xB3}, {0xB3,0xB4}, {0xB3,0xB0}, {0x90,0xBE},
+ {0xD8,0x47}, {0xB6,0xA7}, {0xDC,0x7D}, {0xDC,0xA3},
+ {0x9F,0xAF}, {0xDC,0xA2}, {0xB6,0xAC}, {0xB6,0xA8},
+ {0xB6,0xA9}, {0xDC,0x7C}, {0xDC,0x7E}, {0xDC,0xA1},
+ {0xB6,0xA4}, {0xB6,0xA6}, {0xB6,0xAA}, {0xB6,0xA5},
+ {0x95,0xF2}, {0xE0,0xD3}, {0xE0,0xD1}, {0xE0,0xD2},
+ {0xB9,0x6A}, {0xB9,0x6B}, {0x90,0xBF}, {0xE0,0xD4},
+ {0xB9,0x69}, {0xBB,0xD8}, {0xBB,0xDA}, {0xBB,0xD9},
+ {0xE4,0xBB}, {0xE4,0xBC}, {0xE8,0xAB}, {0x90,0xC1},
+ {0xE8,0xAA}, {0xFE,0xE4}, {0xC0,0x47}, {0xC0,0x48},
+ {0xEC,0x4F}, {0xC0,0x49}, {0xEE,0xF6}, {0xEE,0xF4},
+ {0xEE,0xF5}, {0xC1,0xF4}, {0xF1,0x6F}, {0xC3,0xF7},
+ {0x90,0xC4}, {0xC1,0xF5}, {0xAB,0x41}, {0xB0,0xA6},
+ {0xD4,0x47}, {0x90,0xC7}, {0xD8,0x4C}, {0xB3,0xB6},
+ {0xB6,0xAD}, {0xDC,0xA4}, {0xDC,0xA6}, {0xB6,0xAF},
+ {0xB6,0xAE}, {0xB6,0xB0}, {0xB6,0xB1}, {0xDC,0xA5},
+ {0xB9,0x6E}, {0xB9,0x6F}, {0xB9,0x6D}, {0xBB,0xDB},
+ {0xB9,0x6C}, {0xE0,0xD5}, {0xBB,0xDC}, {0xE8,0xAC},
+ {0xEC,0x50}, {0xC0,0x4A}, {0xC1,0xF6}, {0xF1,0x70},
+ {0xF1,0x74}, {0xC2,0xF9}, {0xF1,0x71}, {0xC2,0xFA},
+ {0xC2,0xF8}, {0xF1,0x75}, {0xC2,0xFB}, {0xF1,0x73},
+ {0xF3,0x79}, {0xC2,0xF7}, {0xC3,0xF8}, {0xF8,0xCD},
+ {0xAB,0x42}, {0xB3,0xB8}, {0xB3,0xB7}, {0xB6,0xB2},
+ {0xDC,0xA8}, {0xDC,0xA7}, {0xB6,0xB3}, {0x92,0xE4},
+ {0xE0,0xD9}, {0xB9,0x73}, {0xB9,0x70}, {0xE0,0xD8},
+ {0xB9,0x72}, {0xE0,0xD6}, {0xB9,0x71}, {0xE0,0xD7},
+ {0xE4,0xBD}, {0xBB,0xDD}, {0xE8,0xAF}, {0x9F,0x52},
+ {0xBE,0x5D}, {0xE8,0xAD}, {0xBE,0x5E}, {0xBE,0x5F},
+ {0xE8,0xAE}, {0xBE,0x60}, {0xEC,0x51}, {0xC0,0x4E},
+ {0xC0,0x4B}, {0xC0,0x50}, {0xEC,0x53}, {0xC0,0x4C},
+ {0xEC,0x52}, {0xC0,0x4F}, {0xC0,0x4D}, {0xEE,0xF9},
+ {0xEE,0xFB}, {0x90,0xDB}, {0xC1,0xF7}, {0xEE,0xFA},
+ {0xC1,0xF8}, {0xEE,0xF8}, {0xEE,0xF7}, {0xA0,0x66},
+ {0xF1,0x77}, {0xF1,0x76}, {0xC2,0xFC}, {0xF1,0x78},
+ {0xF3,0x7E}, {0xC3,0xFA}, {0xF3,0x7D}, {0xF3,0x7A},
+ {0xC3,0xF9}, {0xF3,0x7B}, {0xF3,0x7C}, {0xF5,0x48},
+ {0xF5,0x49}, {0xC4,0xC5}, {0x90,0xD2}, {0xC5,0x53},
+ {0xF6,0x6E}, {0x90,0xD4}, {0xC5,0x51}, {0xC5,0x52},
+ {0xF6,0x6F}, {0xC5,0xB4}, {0xC5,0xB5}, {0xF7,0x71},
+ {0x9A,0x5B}, {0x95,0xFD}, {0xC6,0x45}, {0xF8,0xCF},
+ {0xC6,0x47}, {0xF8,0xCE}, {0xF8,0xD0}, {0xC6,0x46},
+ {0xF9,0x57}, {0xF9,0xAD}, {0x8B,0xC4}, {0xAB,0x43},
+ {0x8C,0x66}, {0xB9,0x74}, {0x90,0xDE}, {0xE4,0xBE},
+ {0xE8,0xB0}, {0xC0,0x51}, {0xC0,0x52}, {0x9C,0xE4},
+ {0xAB,0x44}, {0x90,0xE1}, {0xBE,0x61}, {0xC3,0xFB},
+ {0xAD,0xB1}, {0xC0,0x53}, {0xC5,0xE2}, {0xAD,0xB2},
+ {0xD8,0x4D}, {0xDC,0xA9}, {0x9E,0x46}, {0xDC,0xAB},
+ {0xDC,0xAA}, {0x96,0x51}, {0xE0,0xDD}, {0xE0,0xDA},
+ {0xB9,0x75}, {0xB9,0x76}, {0xE0,0xDB}, {0xE0,0xDC},
+ {0xE4,0xC0}, {0xE4,0xC5}, {0xBB,0xDE}, {0xE4,0xBF},
+ {0xE4,0xC1}, {0xE4,0xC8}, {0xE4,0xC3}, {0xE4,0xC7},
+ {0xE4,0xC4}, {0xE4,0xC2}, {0xE4,0xC6}, {0xBB,0xDF},
+ {0xFB,0x58}, {0xE8,0xB3}, {0x90,0xE6}, {0xE8,0xB1},
+ {0xBE,0x63}, {0xBE,0x62}, {0xE8,0xB2}, {0xBE,0x64},
+ {0xEC,0x56}, {0xEC,0x55}, {0xC0,0x54}, {0xEC,0x54},
+ {0xEE,0xFC}, {0x96,0x50}, {0xEE,0xFE}, {0xEF,0x41},
+ {0xEF,0x40}, {0x90,0xE7}, {0xC1,0xF9}, {0xEE,0xFD},
+ {0xF1,0xA1}, {0xC2,0xFD}, {0xF1,0x7D}, {0xF1,0xA2},
+ {0xC2,0xFE}, {0xF1,0x7B}, {0xF1,0x7E}, {0xF1,0x7C},
+ {0xF1,0x79}, {0xC3,0x40}, {0xF1,0x7A}, {0x90,0xE8},
+ {0x9A,0x5D}, {0xF3,0xA1}, {0x9F,0x7A}, {0xF3,0xA3},
+ {0xF3,0xA2}, {0x9B,0x5C}, {0xF5,0x4A}, {0x9F,0x7C},
+ {0xF5,0x4B}, {0xFC,0x52}, {0x90,0xE9}, {0xF6,0x70},
+ {0x90,0xEA}, {0xC5,0xB7}, {0x9A,0x5E}, {0xC5,0xB6},
+ {0xF8,0x4F}, {0xF8,0x50}, {0xC6,0x48}, {0xF8,0xD1},
+ {0x9F,0x76}, {0xC6,0x69}, {0xAD,0xB3}, {0xB6,0xB4},
+ {0xE4,0xCA}, {0xE4,0xC9}, {0xE8,0xB5}, {0xE8,0xB4},
+ {0x90,0xEB}, {0xC1,0xFA}, {0xEF,0x43}, {0xEF,0x42},
+ {0xF1,0xA5}, {0xF1,0xA3}, {0xF1,0xA6}, {0xF1,0xA4},
+ {0xC3,0xFC}, {0xF3,0xA4}, {0xF3,0xA5}, {0xF3,0xA6},
+ {0x90,0xEC}, {0xF6,0x71}, {0xF7,0x72}, {0xF8,0xD2},
+ {0x8B,0xEE}, {0xAD,0xB4}, {0x90,0xEE}, {0xEC,0x57},
+ {0xEF,0x44}, {0x91,0xC6}, {0xAD,0xB5}, {0x90,0xF2},
+ {0xBB,0xE0}, {0xEC,0x58}, {0xC3,0x41}, {0xF1,0xA7},
+ {0xC3,0xFD}, {0xF5,0x4C}, {0xF5,0x4D}, {0xC5,0x54},
+ {0xF8,0x51}, {0xAD,0xB6}, {0xB3,0xBB}, {0xB3,0xBC},
+ {0xD8,0x4E}, {0xB6,0xB5}, {0xB6,0xB6}, {0xDC,0xAC},
+ {0xB6,0xB7}, {0xB9,0x7A}, {0xB9,0x7C}, {0xE0,0xDF},
+ {0xE0,0xE0}, {0xE0,0xDE}, {0xB9,0x77}, {0xB9,0x78},
+ {0xB9,0x7B}, {0xB9,0x79}, {0xFC,0xBC}, {0x8A,0x74},
+ {0xE4,0xCB}, {0xBB,0xE1}, {0xBB,0xE2}, {0xE8,0xBC},
+ {0xBE,0x67}, {0xE8,0xB7}, {0xE8,0xB6}, {0x96,0x57},
+ {0xE8,0xBB}, {0xBE,0x65}, {0x9C,0xEF}, {0xC0,0x5B},
+ {0xE8,0xB8}, {0xE8,0xBD}, {0xE8,0xBA}, {0xE8,0xB9},
+ {0xBE,0x66}, {0xC0,0x59}, {0x9F,0xDF}, {0xEC,0x5A},
+ {0xC0,0x55}, {0xEC,0x5B}, {0x90,0xF7}, {0x90,0xF6},
+ {0xEC,0x59}, {0xC0,0x58}, {0xC0,0x56}, {0xC0,0x5A},
+ {0xC0,0x57}, {0xEF,0x45}, {0xEF,0x4A}, {0xEF,0x46},
+ {0xEF,0x49}, {0xC1,0xFB}, {0x9B,0x5E}, {0xED,0xD4},
+ {0xEF,0x48}, {0xEF,0x47}, {0x90,0xF8}, {0xC3,0x44},
+ {0xC3,0x42}, {0xC3,0x45}, {0xC3,0x43}, {0xF1,0xA8},
+ {0xF1,0xA9}, {0xF1,0xAA}, {0xC3,0x46}, {0xF3,0xAA},
+ {0xC4,0x40}, {0xF3,0xA8}, {0xC4,0x41}, {0xF3,0xA7},
+ {0xF3,0xA9}, {0xC3,0xFE}, {0xF5,0x51}, {0xF5,0x4E},
+ {0xF5,0x4F}, {0xF5,0x50}, {0xF6,0x72}, {0xC5,0x56},
+ {0x90,0xF9}, {0xC5,0x55}, {0x8C,0xC9}, {0xF7,0x74},
+ {0xF7,0x73}, {0xC5,0xB8}, {0xFA,0x6A}, {0xC5,0xE3},
+ {0xC6,0x49}, {0xC6,0x60}, {0xF9,0x58}, {0xF9,0xAE},
+ {0xF9,0xAF}, {0x8B,0xEF}, {0xAD,0xB7}, {0xDC,0xAD},
+ {0xE0,0xE1}, {0xE4,0xCC}, {0xE4,0xCD}, {0xBB,0xE3},
+ {0xBB,0xE4}, {0xE8,0xBE}, {0xBE,0x68}, {0x9F,0xE0},
+ {0xC1,0xFC}, {0x91,0x42}, {0xF1,0xAB}, {0x9A,0x62},
+ {0xC3,0x47}, {0xF3,0xAD}, {0xC4,0x42}, {0xF3,0xAC},
+ {0xF3,0xAE}, {0xF3,0xAB}, {0xF6,0x75}, {0xF5,0x52},
+ {0xF5,0x53}, {0x95,0x69}, {0xC4,0xC6}, {0xF6,0x74},
+ {0x91,0x44}, {0x91,0x43}, {0xF6,0x73}, {0x91,0x41},
+ {0xF7,0x75}, {0xF9,0xB0}, {0x8B,0xF0}, {0xAD,0xB8},
+ {0x96,0x60}, {0x8B,0xF1}, {0xAD,0xB9}, {0x99,0xF6},
+ {0x91,0x49}, {0xB0,0xA7}, {0xD4,0x48}, {0xD8,0x4F},
+ {0x91,0x4A}, {0xB6,0xB8}, {0xB6,0xBB}, {0xB6,0xB9},
+ {0xDC,0xAE}, {0x91,0x4B}, {0xB6,0xBD}, {0xB6,0xBA},
+ {0x9A,0x64}, {0xB6,0xBC}, {0xB9,0x7E}, {0x8A,0xBF},
+ {0xE0,0xE2}, {0xE0,0xE3}, {0xE8,0xC0}, {0xB9,0x7D},
+ {0xB9,0xA1}, {0xB9,0xA2}, {0xE4,0xCF}, {0xE4,0xCE},
+ {0xBB,0xE5}, {0xBB,0xE6}, {0xE4,0xD0}, {0xE8,0xBF},
+ {0xBB,0xE8}, {0xBE,0x69}, {0xBB,0xE7}, {0x9A,0x66},
+ {0xC0,0x5C}, {0xE8,0xC1}, {0xBE,0x6B}, {0xBE,0x6A},
+ {0xE8,0xC2}, {0xE8,0xC5}, {0xE8,0xC3}, {0xE8,0xC4},
+ {0xBE,0x6C}, {0x9A,0x67}, {0xC0,0x61}, {0xC0,0x5F},
+ {0x9A,0x69}, {0xC0,0x5E}, {0xEC,0x5D}, {0xC0,0x60},
+ {0xEC,0x5C}, {0xEF,0x4B}, {0xEC,0x5E}, {0xC0,0x5D},
+ {0xEC,0x5F}, {0xEF,0x4E}, {0xEF,0x4C}, {0xEF,0x4D},
+ {0xEF,0x52}, {0xC3,0x4B}, {0xEF,0x51}, {0xEF,0x54},
+ {0xEF,0x53}, {0xEF,0x50}, {0xEF,0x4F}, {0xC1,0xFD},
+ {0x9A,0x6A}, {0x96,0x52}, {0x91,0x4D}, {0xF1,0xAE},
+ {0x96,0x66}, {0xF1,0xAD}, {0xC3,0x4A}, {0xC3,0x48},
+ {0xC3,0x49}, {0x9F,0x7B}, {0xF1,0xAC}, {0x9A,0x6B},
+ {0xF3,0xB1}, {0xC4,0x43}, {0xF3,0xB0}, {0xF3,0xAF},
+ {0xC4,0x44}, {0xA0,0x6C}, {0xF5,0x58}, {0xF5,0x57},
+ {0x96,0x67}, {0xF5,0x55}, {0xF5,0x54}, {0xC4,0xC8},
+ {0xC4,0xC7}, {0xF5,0x59}, {0xF7,0x76}, {0xC5,0xB9},
+ {0xF6,0x77}, {0xC5,0x57}, {0xF6,0x76}, {0xF5,0x56},
+ {0xF7,0x77}, {0xC5,0xE4}, {0x9A,0x6C}, {0xC6,0x61},
+ {0xF9,0x59}, {0xF9,0xB1}, {0x9A,0x6D}, {0x8B,0xF2},
+ {0xAD,0xBA}, {0xD8,0x50}, {0xEF,0x55}, {0xAD,0xBB},
+ {0x96,0x6A}, {0xE4,0xD2}, {0xE4,0xD1}, {0xEC,0x60},
+ {0xEF,0x57}, {0xEF,0x56}, {0xFC,0xEA}, {0xC3,0x4C},
+ {0xF3,0xB2}, {0xF3,0xB3}, {0xC4,0xC9}, {0x96,0x6C},
+ {0xF9,0xB2}, {0xB0,0xA8}, {0xB6,0xBF}, {0xB6,0xBE},
+ {0xE0,0xE4}, {0xE0,0xE6}, {0xB9,0xA4}, {0xE0,0xE5},
+ {0xB9,0xA3}, {0xB9,0xA5}, {0xE0,0xE7}, {0x91,0xC4},
+ {0xE4,0xD4}, {0xE4,0xD6}, {0xE4,0xD5}, {0x96,0x77},
+ {0xE4,0xD8}, {0xBB,0xE9}, {0xE4,0xD7}, {0xE4,0xD3},
+ {0x99,0xF4}, {0x9A,0x6F}, {0xE4,0xD9}, {0xE8,0xCC},
+ {0xE8,0xCF}, {0xE8,0xD1}, {0xE8,0xC7}, {0xE8,0xCB},
+ {0xE8,0xC8}, {0xBE,0x6E}, {0xBE,0x71}, {0xBE,0x73},
+ {0xE8,0xC9}, {0xE8,0xCA}, {0xBE,0x72}, {0xE8,0xCD},
+ {0xE8,0xD0}, {0xE8,0xCE}, {0xBE,0x74}, {0x9F,0xAB},
+ {0xBE,0x70}, {0xE8,0xC6}, {0xBE,0x6D}, {0xBE,0x6F},
+ {0x8C,0xBE}, {0x8E,0xC1}, {0xC0,0x63}, {0xEC,0x66},
+ {0xEC,0x64}, {0xEC,0x63}, {0x95,0x55}, {0xEC,0x69},
+ {0xEC,0x68}, {0xEC,0x67}, {0xEC,0x62}, {0xC0,0x62},
+ {0xEC,0x61}, {0xEC,0x65}, {0xC0,0x64}, {0xEF,0x5A},
+ {0x91,0x52}, {0xEF,0x5E}, {0xEF,0x5B}, {0xEF,0x5D},
+ {0xEF,0x5C}, {0xEF,0x59}, {0xEF,0x5F}, {0xEF,0x62},
+ {0xEF,0x60}, {0xEF,0x61}, {0xC2,0x40}, {0xC1,0xFE},
+ {0xEF,0x58}, {0xEF,0x63}, {0xF1,0xB3}, {0xF1,0xB6},
+ {0xF1,0xB8}, {0xF1,0xB7}, {0xF1,0xB1}, {0xF1,0xB5},
+ {0xF1,0xB0}, {0x91,0x53}, {0xF1,0xB2}, {0xC3,0x4D},
+ {0xF1,0xAF}, {0x91,0x55}, {0xF1,0xB4}, {0xF3,0xC0},
+ {0xF3,0xB5}, {0xC4,0x45}, {0xC4,0x46}, {0xF3,0xB4},
+ {0xF3,0xB9}, {0xF3,0xBF}, {0xF3,0xB7}, {0xF3,0xBE},
+ {0x95,0x5D}, {0xF3,0xBB}, {0x96,0x71}, {0xF3,0xBA},
+ {0xF3,0xBD}, {0xF3,0xB8}, {0xF3,0xB6}, {0x9C,0x6D},
+ {0xF3,0xBC}, {0xF5,0x60}, {0xF5,0x5E}, {0xC4,0xCA},
+ {0xF5,0x5D}, {0xF5,0x63}, {0xF5,0x61}, {0x96,0x73},
+ {0xC4,0xCB}, {0xF5,0x5C}, {0xF5,0x5A}, {0xF5,0x5B},
+ {0xC4,0xCD}, {0xF5,0x5F}, {0xC4,0xCC}, {0xF5,0x62},
+ {0xF6,0x78}, {0xF6,0x7E}, {0x91,0x54}, {0x9A,0x71},
+ {0xF6,0x79}, {0xC5,0x5B}, {0xF6,0xA1}, {0xC5,0x5A},
+ {0xF6,0x7D}, {0xF6,0x7C}, {0xC5,0x59}, {0xF6,0x7B},
+ {0xC5,0x58}, {0xF6,0x7A}, {0xF7,0x7D}, {0xF7,0xA1},
+ {0xF7,0x7E}, {0xF7,0x7B}, {0xC5,0xBB}, {0xF7,0x78},
+ {0xF7,0x7C}, {0xF7,0xA3}, {0xF7,0xA2}, {0xF7,0x79},
+ {0xF7,0x7A}, {0xC5,0xBA}, {0xF8,0x52}, {0xC5,0xE7},
+ {0x91,0x56}, {0xF8,0x53}, {0xC5,0xE5}, {0xC5,0xE6},
+ {0x96,0x6D}, {0xF8,0xD3}, {0xC6,0x4A}, {0xF9,0x76},
+ {0xC6,0x6A}, {0x95,0x57}, {0xF9,0xB3}, {0xC6,0x6B},
+ {0xF9,0xB4}, {0xF9,0xB5}, {0xF9,0xC3}, {0xF9,0xC2},
+ {0xC6,0x7A}, {0xF9,0xCD}, {0x89,0xC6}, {0x89,0xC7},
+ {0xB0,0xA9}, {0xE0,0xE9}, {0xE0,0xE8}, {0xBB,0xEA},
+ {0xBB,0xEB}, {0xE4,0xDA}, {0x8A,0x6A}, {0xE8,0xD2},
+ {0xEC,0x6C}, {0x8B,0x57}, {0xBE,0x75}, {0xC0,0x65},
+ {0xEC,0x6A}, {0x9F,0xE1}, {0xEC,0x6D}, {0xC0,0x66},
+ {0x9B,0x5F}, {0xEF,0x64}, {0xEC,0x6B}, {0xF1,0xB9},
+ {0xC3,0x4E}, {0xF3,0xC1}, {0xF5,0x66}, {0xF5,0x64},
+ {0xF5,0x65}, {0xF6,0xA2}, {0xC5,0x5C}, {0xF7,0xA4},
+ {0xC5,0xEA}, {0xC5,0xBC}, {0xC5,0xE8}, {0xC5,0xE9},
+ {0xF8,0xD4}, {0xC6,0x62}, {0xA0,0x5D}, {0xB0,0xAA},
+ {0xF1,0xBA}, {0xD4,0x49}, {0x91,0x5B}, {0xB9,0xA6},
+ {0x91,0x5C}, {0xE4,0xDB}, {0xBB,0xEC}, {0xE4,0xDC},
+ {0xE8,0xD4}, {0xE8,0xD3}, {0xC0,0x68}, {0xBE,0x76},
+ {0xBE,0x77}, {0xE8,0xD7}, {0xE8,0xD6}, {0xE8,0xD5},
+ {0x91,0x5E}, {0xEC,0x6E}, {0xEC,0x71}, {0xEC,0x70},
+ {0xEC,0x6F}, {0xC0,0x67}, {0xEF,0x68}, {0xEF,0x66},
+ {0xEF,0x65}, {0x9F,0x5C}, {0xEF,0x67}, {0x9F,0x57},
+ {0xC3,0x4F}, {0xF1,0xBC}, {0xF1,0xBD}, {0xC3,0x50},
+ {0xF1,0xBB}, {0x9F,0x65}, {0xF3,0xC3}, {0xF3,0xC2},
+ {0xF3,0xC5}, {0xC4,0x47}, {0xF3,0xC4}, {0x9A,0x72},
+ {0xF5,0x67}, {0xF5,0x69}, {0xF5,0x68}, {0x91,0x60},
+ {0xF6,0xA3}, {0xF6,0xA6}, {0xF6,0xA4}, {0xF6,0xA5},
+ {0xF7,0xA5}, {0xC5,0xBD}, {0xF8,0x54}, {0xF8,0x55},
+ {0xF8,0x56}, {0xC6,0x4B}, {0xC6,0x63}, {0xF9,0xB6},
+ {0xB0,0xAB}, {0xBE,0x78}, {0xC0,0x69}, {0xF1,0xBE},
+ {0x9F,0x5E}, {0xF7,0xA6}, {0x91,0x61}, {0xF9,0xC4},
+ {0xD4,0x4A}, {0xC6,0x7B}, {0xB0,0xAC}, {0xEC,0x72},
+ {0x91,0x64}, {0xF1,0xBF}, {0xF3,0xC6}, {0x9F,0x41},
+ {0xF6,0xA7}, {0xF7,0xA7}, {0xB0,0xAD}, {0xE4,0xDD},
+ {0xE4,0xDE}, {0x91,0x69}, {0xBB,0xED}, {0xBB,0xEE},
+ {0xE8,0xD9}, {0xBE,0x7A}, {0xBE,0x79}, {0xE8,0xD8},
+ {0xEF,0x69}, {0xF1,0xC0}, {0xF1,0xC2}, {0xF1,0xC1},
+ {0xC3,0x53}, {0xC3,0x52}, {0xC3,0x51}, {0x91,0x68},
+ {0xC5,0x5E}, {0xF6,0xA8}, {0xC5,0x5D}, {0xF7,0xA9},
+ {0xF7,0xA8}, {0xC6,0x4C}, {0xF8,0xD5}, {0xB3,0xBD},
+ {0xE0,0xEA}, {0xE4,0xE1}, {0xE4,0xDF}, {0xE4,0xE0},
+ {0xE8,0xE2}, {0xE8,0xDD}, {0xE8,0xDA}, {0xE8,0xE1},
+ {0x9A,0x74}, {0xE8,0xE3}, {0xBE,0x7C}, {0xE8,0xE0},
+ {0xE8,0xDC}, {0xE8,0xDB}, {0xE8,0xDF}, {0xE8,0xDE},
+ {0xBE,0x7B}, {0xEC,0x7D}, {0xEC,0x78}, {0xEC,0x76},
+ {0xEC,0xA1}, {0xEC,0x77}, {0x96,0xB2}, {0xEC,0x73},
+ {0x9A,0x75}, {0xEC,0x79}, {0xFD,0xA5}, {0xEC,0x74},
+ {0xEF,0x72}, {0xEC,0x75}, {0xEC,0xA2}, {0x9E,0xE9},
+ {0x8B,0xBA}, {0x91,0x6D}, {0xA0,0x60}, {0xEC,0x7C},
+ {0xC0,0x6A}, {0xEC,0x7B}, {0xEC,0x7A}, {0xEC,0x7E},
+ {0x9F,0xDE}, {0xEF,0x6A}, {0xEF,0x6D}, {0x9F,0xC3},
+ {0xEF,0x6C}, {0x96,0xB5}, {0xEF,0x74}, {0xEF,0x6F},
+ {0xEF,0x73}, {0xEF,0x71}, {0xEF,0x70}, {0xEF,0x6E},
+ {0xEF,0x6B}, {0xC2,0x43}, {0xC2,0x42}, {0xC2,0x44},
+ {0xC2,0x41}, {0xEF,0x75}, {0xA0,0x67}, {0xF1,0xC8},
+ {0xF1,0xCB}, {0xF1,0xC9}, {0xF1,0xCD}, {0xF1,0xCE},
+ {0xF1,0xC6}, {0xC3,0x58}, {0xF1,0xC7}, {0xF1,0xC5},
+ {0xF1,0xCC}, {0xF1,0xC4}, {0xF1,0xC3}, {0xC3,0x57},
+ {0xC3,0x55}, {0xC3,0x54}, {0x96,0xB3}, {0xF1,0xCA},
+ {0xF3,0xCF}, {0xF3,0xD5}, {0xC4,0x4A}, {0xF3,0xD0},
+ {0xF3,0xD3}, {0xF3,0xD7}, {0xC4,0x4B}, {0xF3,0xD2},
+ {0x9A,0x76}, {0xF3,0xCA}, {0xF3,0xC9}, {0xF3,0xD6},
+ {0xF3,0xCD}, {0xF3,0xCB}, {0xF3,0xD4}, {0xF3,0xCC},
+ {0xC4,0x49}, {0xC4,0x48}, {0x95,0xD5}, {0xF3,0xC7},
+ {0xF3,0xC8}, {0xF3,0xD1}, {0x9E,0xCA}, {0xF3,0xCE},
+ {0x9A,0x77}, {0x9A,0x78}, {0xF5,0x6C}, {0xF5,0x6F},
+ {0xC3,0x56}, {0x91,0x70}, {0x91,0x6F}, {0xF5,0x6D},
+ {0xF5,0x73}, {0xF5,0x71}, {0xF5,0x6B}, {0xF5,0x76},
+ {0x9F,0xA3}, {0xF5,0x6A}, {0x91,0x71}, {0xC4,0xCF},
+ {0xF5,0x72}, {0x96,0xB1}, {0xF5,0x6E}, {0xC4,0xCE},
+ {0xF5,0x75}, {0x9F,0x63}, {0xF5,0x74}, {0x9F,0x67},
+ {0xF6,0xAB}, {0xF6,0xAA}, {0x8B,0xB9}, {0x9A,0x7A},
+ {0xF6,0xB1}, {0xF6,0xAD}, {0xF6,0xB0}, {0xC5,0x60},
+ {0x8B,0x56}, {0xF6,0xAE}, {0xF6,0xAF}, {0xF6,0xA9},
+ {0xF6,0xAC}, {0xC5,0x5F}, {0x9A,0xDA}, {0xC5,0xBF},
+ {0xF7,0xB4}, {0xF7,0xAF}, {0xF7,0xB3}, {0x96,0xB0},
+ {0xF7,0xB6}, {0xF7,0xB2}, {0xF7,0xAE}, {0x9A,0x7E},
+ {0xC5,0xC1}, {0xF7,0xB1}, {0xF7,0xB5}, {0xC5,0xC0},
+ {0xF7,0xAC}, {0xF5,0x70}, {0xF7,0xB0}, {0xF7,0xAD},
+ {0x9D,0xDE}, {0xF7,0xAA}, {0xF7,0xAB}, {0xC5,0xBE},
+ {0xF8,0x5A}, {0xF8,0x5C}, {0xF8,0x5F}, {0xF8,0x5B},
+ {0xF8,0x60}, {0x96,0xAD}, {0xF8,0x59}, {0xF8,0x57},
+ {0x96,0xAE}, {0xC5,0xEB}, {0xF8,0x5D}, {0xC5,0xED},
+ {0xC5,0xEC}, {0xF8,0x58}, {0xF8,0x5E}, {0x9E,0xA1},
+ {0xF8,0xDA}, {0xC6,0x4D}, {0xF8,0xDB}, {0xF8,0xD9},
+ {0xF8,0xD6}, {0xF8,0xD8}, {0xF8,0xD7}, {0xF9,0x5A},
+ {0xF9,0x5C}, {0xF9,0x5B}, {0xF9,0x79}, {0x9E,0x50},
+ {0xF9,0x78}, {0xF9,0x77}, {0xF9,0x7A}, {0xC6,0x73},
+ {0xC6,0x74}, {0xF9,0xCA}, {0xF9,0xCE}, {0x96,0xAF},
+ {0x8B,0xF4}, {0xB3,0xBE}, {0xDC,0xAF}, {0xE0,0xED},
+ {0xB9,0xA7}, {0xE0,0xEB}, {0xE0,0xEC}, {0xE4,0xE2},
+ {0xE4,0xE3}, {0xBB,0xF1}, {0xBB,0xEF}, {0xE4,0xE4},
+ {0xBB,0xF0}, {0xE8,0xE8}, {0xE8,0xEB}, {0xE8,0xE5},
+ {0xE8,0xEC}, {0xE8,0xE4}, {0xE8,0xE6}, {0xE8,0xE7},
+ {0xE8,0xEA}, {0x9F,0xA4}, {0xBE,0xA1}, {0xE8,0xEF},
+ {0xE8,0xEE}, {0xBE,0x7D}, {0xE8,0xE9}, {0xE8,0xED},
+ {0xBE,0x7E}, {0x96,0xBD}, {0xEC,0xAC}, {0xC0,0x6F},
+ {0xEC,0xA7}, {0xC0,0x6B}, {0x96,0xF4}, {0xEC,0xA4},
+ {0xEC,0xAA}, {0xEC,0xAD}, {0xC0,0x70}, {0xEC,0xA9},
+ {0xEC,0xA6}, {0xEC,0xAE}, {0xEC,0xA5}, {0x96,0xB8},
+ {0xEC,0xAB}, {0xC0,0x6C}, {0xEC,0xA3}, {0xC0,0x6D},
+ {0xC0,0x6E}, {0xEC,0xA8}, {0xEF,0xA9}, {0xEF,0x7A},
+ {0xEF,0x7B}, {0xEF,0x7E}, {0xEF,0x7C}, {0xEF,0x76},
+ {0xFA,0xA1}, {0xEF,0x79}, {0xEF,0xA5}, {0xEF,0x7D},
+ {0x91,0xA7}, {0xC2,0x45}, {0xEF,0xA7}, {0xEF,0xA4},
+ {0xC2,0x46}, {0xEF,0xA6}, {0xEF,0x77}, {0xEF,0xA2},
+ {0xEF,0xA3}, {0xA0,0x5E}, {0xEF,0xA1}, {0x9A,0x7D},
+ {0xF1,0xD2}, {0xF1,0xD4}, {0xF1,0xD7}, {0x89,0x48},
+ {0xF1,0xD1}, {0x9E,0xB1}, {0xC3,0x59}, {0xF1,0xD9},
+ {0xF1,0xD0}, {0xF1,0xDA}, {0xF1,0xD6}, {0xF1,0xD8},
+ {0xF1,0xDC}, {0xF1,0xD5}, {0xF1,0xDD}, {0xF1,0xD3},
+ {0xF1,0xCF}, {0xC3,0x5A}, {0x9D,0xDB}, {0xF1,0xDB},
+ {0xC3,0x5B}, {0xC4,0x4D}, {0xEF,0x78}, {0xF3,0xF1},
+ {0xF3,0xE8}, {0xC4,0x4F}, {0xF3,0xE4}, {0xC4,0x50},
+ {0x95,0xBF}, {0x8A,0x73}, {0xF3,0xED}, {0xF3,0xE7},
+ {0xF3,0xDD}, {0xC4,0x4E}, {0xF3,0xEA}, {0xF3,0xE5},
+ {0xF3,0xE6}, {0xF3,0xD8}, {0xF3,0xDF}, {0xF3,0xEE},
+ {0xF3,0xEB}, {0x9E,0xFE}, {0xF3,0xE3}, {0x91,0x7A},
+ {0xF3,0xEF}, {0xF3,0xDE}, {0xF3,0xD9}, {0xF3,0xEC},
+ {0x91,0x7B}, {0xF3,0xDB}, {0xF3,0xE9}, {0xF3,0xE0},
+ {0xF3,0xF0}, {0xF3,0xDC}, {0xC4,0x4C}, {0xF3,0xDA},
+ {0xF3,0xE1}, {0xF3,0xE2}, {0xF5,0x7D}, {0xF5,0x7B},
+ {0x9A,0xA3}, {0xF5,0xA2}, {0xF5,0xAE}, {0xF5,0xA5},
+ {0xF5,0x7C}, {0xF5,0x78}, {0xF5,0xA7}, {0xF5,0x7E},
+ {0xF5,0xA3}, {0xF5,0x7A}, {0xF5,0xAA}, {0xF5,0x77},
+ {0xF5,0xA1}, {0xF5,0xA6}, {0xF5,0xA8}, {0xF5,0xAB},
+ {0xF5,0x79}, {0x96,0xC2}, {0xF5,0xAF}, {0xF5,0xB0},
+ {0xF5,0xA9}, {0xF5,0xAD}, {0xF5,0xA4}, {0x9F,0x77},
+ {0xF6,0xC1}, {0xF6,0xC4}, {0xC5,0x61}, {0xF6,0xC3},
+ {0xF6,0xC8}, {0xF6,0xC6}, {0xC5,0x62}, {0xF6,0xBD},
+ {0xF6,0xB3}, {0xF6,0xB2}, {0xC5,0x64}, {0xF6,0xBF},
+ {0xF6,0xC0}, {0xF6,0xBC}, {0xF6,0xB4}, {0x9A,0xA4},
+ {0xF6,0xB9}, {0xF5,0xAC}, {0x9A,0xA5}, {0xF6,0xB5},
+ {0xC5,0x63}, {0xF6,0xBB}, {0x91,0xA1}, {0xF6,0xBA},
+ {0xF6,0xB6}, {0xF6,0xC2}, {0x89,0xB8}, {0xF6,0xB7},
+ {0xF7,0xBB}, {0xF6,0xC5}, {0xF6,0xC7}, {0xF6,0xBE},
+ {0xF6,0xB8}, {0xF7,0xBC}, {0xF7,0xBE}, {0xF7,0xB8},
+ {0xC5,0xC2}, {0x91,0x73}, {0xF7,0xC5}, {0xF7,0xC3},
+ {0xC5,0xC3}, {0xF7,0xC2}, {0xF7,0xC1}, {0xF7,0xBA},
+ {0xF7,0xB7}, {0xF7,0xBD}, {0xF7,0xC6}, {0xF7,0xB9},
+ {0xF7,0xBF}, {0xF8,0x69}, {0xF8,0x6E}, {0xF8,0x64},
+ {0xF8,0x67}, {0xC5,0xEE}, {0xF8,0x6B}, {0xF8,0x72},
+ {0xF7,0xC0}, {0xF8,0x65}, {0xF8,0x6F}, {0xF8,0x73},
+ {0xF8,0x6A}, {0xF8,0x63}, {0xF8,0x6D}, {0xF8,0x6C},
+ {0xF8,0x71}, {0xF8,0x70}, {0xF7,0xC4}, {0xF8,0x68},
+ {0xF8,0x62}, {0xF8,0x66}, {0xC6,0x4E}, {0xC6,0x4F},
+ {0xF8,0x61}, {0x9A,0xA6}, {0xF8,0xE6}, {0xF8,0xDD},
+ {0xF8,0xE5}, {0xF8,0xE2}, {0xF8,0xE3}, {0xF8,0xDC},
+ {0xF8,0xDF}, {0xF8,0xE7}, {0xF8,0xE1}, {0xF8,0xE0},
+ {0xF8,0xDE}, {0xF8,0xE4}, {0x89,0xBD}, {0xF9,0x5D},
+ {0x89,0xB9}, {0xF9,0x5E}, {0x91,0x7D}, {0xF9,0x60},
+ {0xF9,0x5F}, {0xF9,0x62}, {0xF9,0x61}, {0xF9,0x7C},
+ {0xF9,0x7B}, {0xF9,0xB7}, {0xF9,0xB8}, {0x96,0xBB},
+ {0xF9,0xC5}, {0xC6,0x78}, {0xC6,0x7C}, {0x9F,0xF2},
+ {0xF9,0xCF}, {0xC6,0x7D}, {0x8B,0xF5}, {0xB3,0xBF},
+ {0xC4,0xD0}, {0xF6,0xC9}, {0x9A,0xA9}, {0xC6,0x50},
+ {0xC6,0x51}, {0xB3,0xC0}, {0xE0,0xEE}, {0x9F,0x54},
+ {0xB9,0xA8}, {0xE8,0xF0}, {0x9F,0xE3}, {0x9E,0xED},
+ {0xEC,0xB0}, {0xEC,0xB1}, {0xEC,0xAF}, {0xEF,0xAB},
+ {0xEF,0xAA}, {0xC2,0x47}, {0xF1,0xDF}, {0xEF,0xAC},
+ {0xF1,0xDE}, {0x91,0xAA}, {0xF3,0xF3}, {0xC4,0x51},
+ {0xC4,0x53}, {0xF3,0xF2}, {0x91,0xAB}, {0xA0,0x70},
+ {0xC4,0x52}, {0x9F,0x6D}, {0xF5,0xB1}, {0xF5,0xB3},
+ {0xF5,0xB2}, {0xF6,0xCA}, {0xC5,0x65}, {0x91,0xAC},
+ {0xC5,0xEF}, {0xF8,0xE8}, {0xF9,0x63}, {0x91,0xAD},
+ {0xF9,0xD2}, {0xB3,0xC1}, {0xA0,0xFD}, {0xE4,0xE5},
+ {0x9F,0xE2}, {0xBE,0xA2}, {0x91,0xAF}, {0x9E,0x41},
+ {0x9A,0xAA}, {0xEC,0xB3}, {0xEC,0xB2}, {0x91,0xB0},
+ {0xEF,0xAD}, {0x9A,0xAB}, {0xC4,0x54}, {0xC4,0xD1},
+ {0xF7,0xC7}, {0xF9,0xCB}, {0xB3,0xC2}, {0xBB,0xF2},
+ {0x9A,0xAC}, {0xBE,0xA3}, {0x9A,0x4A}, {0xF3,0xF4},
+ {0x91,0xB2}, {0xF8,0x74}, {0xB6,0xC0}, {0x8B,0xF6},
+ {0x9A,0xAD}, {0x89,0xB6}, {0xEF,0xAE}, {0xC6,0x64},
+ {0xB6,0xC1}, {0xBE,0xA4}, {0xC2,0x48}, {0xF8,0x75},
+ {0xB6,0xC2}, {0xE8,0xF1}, {0xC0,0x72}, {0xEC,0xB4},
+ {0xEC,0xB5}, {0xC0,0x71}, {0xEF,0xAF}, {0xC2,0x4C},
+ {0xC2,0x4A}, {0xC2,0x4B}, {0xC2,0x49}, {0xF1,0xE0},
+ {0xC3,0x5C}, {0x9A,0xAF}, {0xF5,0xB5}, {0xF5,0xB4},
+ {0xF5,0xB7}, {0xF5,0xB6}, {0xC4,0xD2}, {0xF6,0xCB},
+ {0xF6,0xCD}, {0xF6,0xCC}, {0xC5,0x66}, {0xF7,0xC8},
+ {0x9A,0xB0}, {0xF8,0x76}, {0xF8,0x77}, {0xC5,0xF0},
+ {0xF9,0x64}, {0xF9,0x7D}, {0xC6,0x75}, {0x9A,0xB1},
+ {0xDC,0xB0}, {0xEC,0xB6}, {0xEF,0xB0}, {0xF3,0xF5},
+ {0xE0,0xEF}, {0x9A,0xA1}, {0xEF,0xB1}, {0xF1,0xE2},
+ {0xF1,0xE1}, {0x91,0xB9}, {0xF8,0x78}, {0xC6,0x52},
+ {0x91,0xBA}, {0xF9,0x65}, {0xF9,0x7E}, {0xB9,0xA9},
+ {0xE8,0xF2}, {0xE8,0xF3}, {0xEC,0xB7}, {0xB9,0xAA},
+ {0xC3,0x5D}, {0xF1,0xE3}, {0x91,0xBE}, {0xF6,0xCF},
+ {0xC5,0x67}, {0xF6,0xD0}, {0xF6,0xCE}, {0xF8,0x79},
+ {0xF8,0xE9}, {0xB9,0xAB}, {0xEF,0xB4}, {0xEF,0xB3},
+ {0xEF,0xB2}, {0xF1,0xE4}, {0xA0,0x41}, {0x8B,0xB7},
+ {0xF1,0xE8}, {0xF1,0xE7}, {0xF1,0xE6}, {0xF1,0xE5},
+ {0xC3,0x5E}, {0xF3,0xF6}, {0xF5,0xB9}, {0xC4,0xD3},
+ {0xF5,0xB8}, {0xF6,0xD1}, {0xF7,0xCB}, {0xF7,0xCA},
+ {0xC5,0xC4}, {0xF7,0xC9}, {0xF8,0x7C}, {0xF8,0x7B},
+ {0xF8,0x7A}, {0x91,0xC0}, {0xBB,0xF3}, {0xEC,0xB8},
+ {0xC2,0x4D}, {0xF3,0xF7}, {0xF3,0xF8}, {0xF7,0xCC},
+ {0xF8,0x7D}, {0x9A,0xB3}, {0x91,0xC3}, {0xF8,0xEA},
+ {0xF9,0x66}, {0xF9,0xB9}, {0xF9,0xD4}, {0xBB,0xF4},
+ {0xC2,0x4E}, {0xF1,0xE9}, {0xF3,0xF9}, {0xF6,0xD2},
+ {0xF8,0x7E}, {0xA0,0xFC}, {0xBE,0xA6}, {0x9F,0xEE},
+ {0xEF,0xB5}, {0xF1,0xEA}, {0xF3,0xFA}, {0xF3,0xFB},
+ {0xF3,0xFC}, {0xF5,0xBE}, {0x9F,0x69}, {0xF5,0xBA},
+ {0xC5,0x68}, {0xF5,0xBD}, {0xF5,0xBC}, {0xC4,0xD4},
+ {0xF5,0xBB}, {0xC4,0xD6}, {0x91,0xC8}, {0xC4,0xD5},
+ {0xF6,0xD4}, {0xF6,0xD3}, {0xC5,0x69}, {0xC5,0x6A},
+ {0x91,0xC9}, {0xC5,0xC6}, {0xF7,0xCD}, {0xC5,0xC5},
+ {0xF8,0xA3}, {0xF8,0xA4}, {0xF8,0xA2}, {0xF8,0xA1},
+ {0xC6,0x54}, {0xF8,0xEB}, {0xF8,0xEC}, {0xF8,0xED},
+ {0xC6,0x53}, {0xF9,0x67}, {0xF9,0x6A}, {0xF9,0x69},
+ {0xF9,0x68}, {0xF9,0xD3}, {0x8D,0xE6}, {0xC0,0x73},
+ {0x91,0xCB}, {0xC3,0x65}, {0xF5,0xBF}, {0xF6,0xD5},
+ {0xC5,0xC7}, {0xF7,0xCE}, {0xF9,0xD5}, {0x89,0xC8},
+ {0xC0,0x74}, {0x8D,0xAA}, {0xEF,0xB6}, {0xF7,0xCF},
+ {0xF9,0xA1}, {0x9F,0xDD}, {0xFA,0x40}, {0xFA,0x41},
+ {0xFA,0x42}, {0xFA,0x43}, {0xFA,0x44}, {0xFA,0x45},
+ {0xFA,0x46}, {0xFA,0x47}, {0xFA,0x48}, {0xFA,0x49},
+ {0xFA,0x4A}, {0xFA,0x4B}, {0xFA,0x4C}, {0xFA,0x4D},
+ {0xFA,0x4E}, {0xFA,0x4F}, {0xFA,0x50}, {0xFA,0x51},
+ {0xFA,0x52}, {0xFA,0x53}, {0xFA,0x54}, {0xFA,0x55},
+ {0xFA,0x56}, {0xFA,0x57}, {0xFA,0x58}, {0xFA,0x59},
+ {0xFA,0x5A}, {0xFA,0x5B}, {0xFA,0x5C}, {0xFA,0x5D},
+ {0xFA,0x5E}, {0xAD,0xC5}, {0xFA,0x60}, {0xFA,0x61},
+ {0xFA,0x62}, {0xFA,0x63}, {0xFA,0x64}, {0xFA,0x65},
+ {0xB0,0xB0}, {0xFA,0x67}, {0xFA,0x68}, {0xFA,0x69},
+ {0xFA,0x6A}, {0xFA,0x6B}, {0xFA,0x6C}, {0xFA,0x6D},
+ {0xFA,0x6E}, {0xFA,0x6F}, {0xFA,0x70}, {0xFA,0x71},
+ {0xFA,0x72}, {0xFA,0x73}, {0xFA,0x74}, {0xFA,0x75},
+ {0xFA,0x76}, {0xFA,0x77}, {0xFA,0x78}, {0xFA,0x79},
+ {0xFA,0x7A}, {0xFA,0x7B}, {0xFA,0x7C}, {0xFA,0x7D},
+ {0xFA,0x7E}, {0xFA,0xA1}, {0xFA,0xA2}, {0xFA,0xA3},
+ {0xFA,0xA4}, {0xFA,0xA5}, {0xFA,0xA6}, {0xFA,0xA7},
+ {0xFA,0xA8}, {0xFA,0xA9}, {0xFA,0xAA}, {0xFA,0xAB},
+ {0xFA,0xAC}, {0xFA,0xAD}, {0xFA,0xAE}, {0xFA,0xAF},
+ {0xFA,0xB0}, {0xFA,0xB1}, {0xFA,0xB2}, {0xFA,0xB3},
+ {0xFA,0xB4}, {0xFA,0xB5}, {0xFA,0xB6}, {0xFA,0xB7},
+ {0xFA,0xB8}, {0xFA,0xB9}, {0xFA,0xBA}, {0xFA,0xBB},
+ {0xFA,0xBC}, {0xA5,0x5D}, {0xFA,0xBE}, {0xFA,0xBF},
+ {0xFA,0xC0}, {0xFA,0xC1}, {0xFA,0xC2}, {0xFA,0xC3},
+ {0xFA,0xC4}, {0xA2,0xCD}, {0xFA,0xC6}, {0xFA,0xC7},
+ {0xFA,0xC8}, {0xFA,0xC9}, {0xFA,0xCA}, {0xFA,0xCB},
+ {0xFA,0xCC}, {0xFA,0xCD}, {0xFA,0xCE}, {0xFA,0xCF},
+ {0xFA,0xD0}, {0xFA,0xD1}, {0xFA,0xD2}, {0xFA,0xD3},
+ {0xFA,0xD4}, {0xAD,0xEB}, {0xFA,0xD6}, {0xFA,0xD7},
+ {0xFA,0xD8}, {0xFA,0xD9}, {0xFA,0xDA}, {0xFA,0xDB},
+ {0xFA,0xDC}, {0xFA,0xDD}, {0xFA,0xDE}, {0xFA,0xDF},
+ {0xFA,0xE0}, {0xFA,0xE1}, {0xFA,0xE2}, {0xFA,0xE3},
+ {0xFA,0xE4}, {0xFA,0xE5}, {0xFA,0xE6}, {0xFA,0xE7},
+ {0xFA,0xE8}, {0xFA,0xE9}, {0xFA,0xEA}, {0xFA,0xEB},
+ {0xFA,0xEC}, {0xFA,0xED}, {0xFA,0xEE}, {0xFA,0xEF},
+ {0xFA,0xF0}, {0xFA,0xF1}, {0xFA,0xF2}, {0xFA,0xF3},
+ {0xFA,0xF4}, {0xFA,0xF5}, {0xFA,0xF6}, {0xFA,0xF7},
+ {0xFA,0xF8}, {0xFA,0xF9}, {0xFA,0xFA}, {0xFA,0xFB},
+ {0xFA,0xFC}, {0xFA,0xFD}, {0xFA,0xFE}, {0xFB,0x40},
+ {0xFB,0x41}, {0xFB,0x42}, {0xFB,0x43}, {0xFB,0x44},
+ {0xFB,0x45}, {0xFB,0x46}, {0xFB,0x47}, {0x9D,0xEF},
+ {0xFB,0x49}, {0xFB,0x4A}, {0xFB,0x4B}, {0xFB,0x4C},
+ {0xFB,0x4D}, {0xFB,0x4E}, {0xFB,0x4F}, {0xFB,0x50},
+ {0xFB,0x51}, {0xFB,0x52}, {0xFB,0x53}, {0xFB,0x54},
+ {0xFB,0x55}, {0xFB,0x56}, {0xFB,0x57}, {0xFB,0x58},
+ {0xFB,0x59}, {0xFB,0x5A}, {0xFB,0x5B}, {0xFB,0x5C},
+ {0xFB,0x5D}, {0xFB,0x5E}, {0xFB,0x5F}, {0xFB,0x60},
+ {0xFB,0x61}, {0xFB,0x62}, {0xFB,0x63}, {0xFB,0x64},
+ {0xFB,0x65}, {0xFB,0x66}, {0xFB,0x67}, {0xFB,0x68},
+ {0xFB,0x69}, {0xFB,0x6A}, {0xFB,0x6B}, {0xFB,0x6C},
+ {0xFB,0x6D}, {0xFB,0x6E}, {0xFB,0x6F}, {0xFB,0x70},
+ {0xFB,0x71}, {0xFB,0x72}, {0xFB,0x73}, {0xFB,0x74},
+ {0xFB,0x75}, {0xFB,0x76}, {0xFB,0x77}, {0xFB,0x78},
+ {0xFB,0x79}, {0xFB,0x7A}, {0xFB,0x7B}, {0xFB,0x7C},
+ {0xFB,0x7D}, {0xFB,0x7E}, {0xFB,0xA1}, {0xFB,0xA2},
+ {0xFB,0xA3}, {0xFB,0xA4}, {0xFB,0xA5}, {0xFB,0xA6},
+ {0xFB,0xA7}, {0xFB,0xA8}, {0xFB,0xA9}, {0xFB,0xAA},
+ {0xFB,0xAB}, {0xFB,0xAC}, {0xFB,0xAD}, {0xFB,0xAE},
+ {0xFB,0xAF}, {0xFB,0xB0}, {0xFB,0xB1}, {0xFB,0xB2},
+ {0xFB,0xB3}, {0xFB,0xB4}, {0xFB,0xB5}, {0xFB,0xB6},
+ {0xFB,0xB7}, {0xB4,0x40}, {0xFB,0xB9}, {0xFB,0xBA},
+ {0xFB,0xBB}, {0xFB,0xBC}, {0xFB,0xBD}, {0xFB,0xBE},
+ {0xFB,0xBF}, {0xFB,0xC0}, {0xFB,0xC1}, {0xFB,0xC2},
+ {0xFB,0xC3}, {0xFB,0xC4}, {0xFB,0xC5}, {0xFB,0xC6},
+ {0xFB,0xC7}, {0xFB,0xC8}, {0xFB,0xC9}, {0xFB,0xCA},
+ {0xFB,0xCB}, {0xFB,0xCC}, {0xFB,0xCD}, {0xFB,0xCE},
+ {0xFB,0xCF}, {0xFB,0xD0}, {0xFB,0xD1}, {0xFB,0xD2},
+ {0xFB,0xD3}, {0xFB,0xD4}, {0xFB,0xD5}, {0xFB,0xD6},
+ {0xFB,0xD7}, {0xFB,0xD8}, {0xFB,0xD9}, {0xFB,0xDA},
+ {0xFB,0xDB}, {0xFB,0xDC}, {0xFB,0xDD}, {0xFB,0xDE},
+ {0xFB,0xDF}, {0xFB,0xE0}, {0xFB,0xE1}, {0xFB,0xE2},
+ {0xFB,0xE3}, {0xFB,0xE4}, {0xFB,0xE5}, {0xFB,0xE6},
+ {0xFB,0xE7}, {0xFB,0xE8}, {0xFB,0xE9}, {0xFB,0xEA},
+ {0xFB,0xEB}, {0xFB,0xEC}, {0xFB,0xED}, {0xFB,0xEE},
+ {0xFB,0xEF}, {0xFB,0xF0}, {0xFB,0xF1}, {0xFB,0xF2},
+ {0xC9,0xDB}, {0xFB,0xF4}, {0xFB,0xF5}, {0xFB,0xF6},
+ {0xFB,0xF7}, {0xFB,0xF8}, {0x9D,0xFB}, {0xFB,0xFA},
+ {0xFB,0xFB}, {0xFB,0xFC}, {0xFB,0xFD}, {0xFB,0xFE},
+ {0xFC,0x40}, {0xFC,0x41}, {0xFC,0x42}, {0xFC,0x43},
+ {0xFC,0x44}, {0xFC,0x45}, {0xFC,0x46}, {0xFC,0x47},
+ {0xFC,0x48}, {0xFC,0x49}, {0xFC,0x4A}, {0xFC,0x4B},
+ {0xFC,0x4C}, {0xFC,0x4D}, {0xFC,0x4E}, {0xD8,0xF4},
+ {0xFC,0x50}, {0xFC,0x51}, {0xFC,0x52}, {0xFC,0x53},
+ {0xFC,0x54}, {0xFC,0x55}, {0xFC,0x56}, {0xFC,0x57},
+ {0xFC,0x58}, {0xFC,0x59}, {0xFC,0x5A}, {0xFC,0x5B},
+ {0xFC,0x5C}, {0xFC,0x5D}, {0xFC,0x5E}, {0xFC,0x5F},
+ {0xFC,0x60}, {0xFC,0x61}, {0xFC,0x62}, {0xFC,0x63},
+ {0xFC,0x64}, {0xFC,0x65}, {0xFC,0x66}, {0xFC,0x67},
+ {0xFC,0x68}, {0xFC,0x69}, {0xFC,0x6A}, {0xFC,0x6B},
+ {0xA0,0xDC}, {0xFC,0x6D}, {0xFC,0x6E}, {0xFC,0x6F},
+ {0xFC,0x70}, {0xFC,0x71}, {0xFC,0x72}, {0xFC,0x73},
+ {0xFC,0x74}, {0xFC,0x75}, {0xFC,0x76}, {0xFC,0x77},
+ {0xFC,0x78}, {0xFC,0x79}, {0xFC,0x7A}, {0xFC,0x7B},
+ {0xFC,0x7C}, {0xFC,0x7D}, {0xFC,0x7E}, {0xFC,0xA1},
+ {0xFC,0xA2}, {0xFC,0xA3}, {0xFC,0xA4}, {0xFC,0xA5},
+ {0xFC,0xA6}, {0xFC,0xA7}, {0xFC,0xA8}, {0xFC,0xA9},
+ {0xFC,0xAA}, {0xFC,0xAB}, {0xFC,0xAC}, {0xFC,0xAD},
+ {0xFC,0xAE}, {0xFC,0xAF}, {0xFC,0xB0}, {0xFC,0xB1},
+ {0xFC,0xB2}, {0xFC,0xB3}, {0xFC,0xB4}, {0xFC,0xB5},
+ {0xFC,0xB6}, {0xFC,0xB7}, {0xFC,0xB8}, {0xBC,0xB5},
+ {0xFC,0xBA}, {0xFC,0xBB}, {0xFC,0xBC}, {0xFC,0xBD},
+ {0xFC,0xBE}, {0xFC,0xBF}, {0xFC,0xC0}, {0xFC,0xC1},
+ {0xFC,0xC2}, {0xFC,0xC3}, {0xFC,0xC4}, {0xFC,0xC5},
+ {0xFC,0xC6}, {0xFC,0xC7}, {0xFC,0xC8}, {0xFC,0xC9},
+ {0xFC,0xCA}, {0xFC,0xCB}, {0xFC,0xCC}, {0xFC,0xCD},
+ {0xFC,0xCE}, {0xFC,0xCF}, {0xFC,0xD0}, {0xFC,0xD1},
+ {0xFC,0xD2}, {0xFC,0xD3}, {0xFC,0xD4}, {0xFC,0xD5},
+ {0xFC,0xD6}, {0xFC,0xD7}, {0xFC,0xD8}, {0xFC,0xD9},
+ {0xFC,0xDA}, {0xFC,0xDB}, {0xFC,0xDC}, {0xFC,0xDD},
+ {0xFC,0xDE}, {0xFC,0xDF}, {0xFC,0xE0}, {0xFC,0xE1},
+ {0xB4,0xB8}, {0xFC,0xE3}, {0xFC,0xE4}, {0xFC,0xE5},
+ {0xFC,0xE6}, {0xFC,0xE7}, {0xFC,0xE8}, {0xFC,0xE9},
+ {0xFC,0xEA}, {0xFC,0xEB}, {0xFC,0xEC}, {0xFC,0xED},
+ {0xFC,0xEE}, {0xFC,0xEF}, {0xFC,0xF0}, {0xA7,0xFB},
+ {0xFC,0xF2}, {0xFC,0xF3}, {0xFC,0xF4}, {0xFC,0xF5},
+ {0xFC,0xF6}, {0xFC,0xF7}, {0xFC,0xF8}, {0xFC,0xF9},
+ {0xFC,0xFA}, {0xFC,0xFB}, {0xFC,0xFC}, {0xFC,0xFD},
+ {0xFC,0xFE}, {0xFD,0x40}, {0xFD,0x41}, {0xFD,0x42},
+ {0xFD,0x43}, {0xFD,0x44}, {0xFD,0x45}, {0xFD,0x46},
+ {0xFD,0x47}, {0xFD,0x48}, {0xFD,0x49}, {0xFD,0x4A},
+ {0xFD,0x4B}, {0xFD,0x4C}, {0xFD,0x4D}, {0xFD,0x4E},
+ {0xFD,0x4F}, {0xFD,0x50}, {0xFD,0x51}, {0xFD,0x52},
+ {0xFD,0x53}, {0xFD,0x54}, {0xFD,0x55}, {0xFD,0x56},
+ {0xFD,0x57}, {0xFD,0x58}, {0xFD,0x59}, {0xFD,0x5A},
+ {0xFD,0x5B}, {0xFD,0x5C}, {0xFD,0x5D}, {0xFD,0x5E},
+ {0xFD,0x5F}, {0xFD,0x60}, {0xFD,0x61}, {0xFD,0x62},
+ {0xFD,0x63}, {0xFD,0x64}, {0xFD,0x65}, {0xFD,0x66},
+ {0xFD,0x67}, {0xFD,0x68}, {0xFD,0x69}, {0xFD,0x6A},
+ {0xFD,0x6B}, {0xFD,0x6C}, {0xFD,0x6D}, {0xFD,0x6E},
+ {0xFD,0x6F}, {0xFD,0x70}, {0xFD,0x71}, {0xFD,0x72},
+ {0xFD,0x73}, {0xFD,0x74}, {0xFD,0x75}, {0xFD,0x76},
+ {0xFD,0x77}, {0xFD,0x78}, {0xFD,0x79}, {0xFD,0x7A},
+ {0xFD,0x7B}, {0xFD,0x7C}, {0xFD,0x7D}, {0xFD,0x7E},
+ {0xFD,0xA1}, {0xFD,0xA2}, {0xFD,0xA3}, {0xFD,0xA4},
+ {0xFD,0xA5}, {0xFD,0xA6}, {0xFD,0xA7}, {0xFD,0xA8},
+ {0xFD,0xA9}, {0xFD,0xAA}, {0xFD,0xAB}, {0xFD,0xAC},
+ {0xFD,0xAD}, {0xFD,0xAE}, {0xFD,0xAF}, {0xFD,0xB0},
+ {0xFD,0xB1}, {0xFD,0xB2}, {0xFD,0xB3}, {0xFD,0xB4},
+ {0xFD,0xB5}, {0xFD,0xB6}, {0xCB,0x58}, {0xB4,0xFC},
+ {0xFD,0xB9}, {0xFD,0xBA}, {0xB4,0xE4}, {0xFD,0xBC},
+ {0xFD,0xBD}, {0xFD,0xBE}, {0xFD,0xBF}, {0xFD,0xC0},
+ {0xFD,0xC1}, {0xFD,0xC2}, {0xFD,0xC3}, {0xFD,0xC4},
+ {0xFD,0xC5}, {0xFD,0xC6}, {0xFD,0xC7}, {0xFD,0xC8},
+ {0xFD,0xC9}, {0xFD,0xCA}, {0xFD,0xCB}, {0xFD,0xCC},
+ {0xFD,0xCD}, {0xFD,0xCE}, {0xFD,0xCF}, {0xFD,0xD0},
+ {0xFD,0xD1}, {0xFD,0xD2}, {0xFD,0xD3}, {0xFD,0xD4},
+ {0xFD,0xD5}, {0xFD,0xD6}, {0xFD,0xD7}, {0xFD,0xD8},
+ {0xFD,0xD9}, {0xFD,0xDA}, {0xFD,0xDB}, {0xFD,0xDC},
+ {0xFD,0xDD}, {0xFD,0xDE}, {0xFD,0xDF}, {0xFD,0xE0},
+ {0xFD,0xE1}, {0xFD,0xE2}, {0xFD,0xE3}, {0xFD,0xE4},
+ {0xFD,0xE5}, {0xFD,0xE6}, {0xFD,0xE7}, {0xFD,0xE8},
+ {0xFD,0xE9}, {0xFD,0xEA}, {0xFD,0xEB}, {0xFD,0xEC},
+ {0xFD,0xED}, {0xFD,0xEE}, {0xFD,0xEF}, {0xFD,0xF0},
+ {0xB5,0x4E}, {0xFD,0xF2}, {0xFD,0xF3}, {0xFD,0xF4},
+ {0xFD,0xF5}, {0xFD,0xF6}, {0xFD,0xF7}, {0xFD,0xF8},
+ {0xFD,0xF9}, {0xFD,0xFA}, {0xFD,0xFB}, {0xFD,0xFC},
+ {0xFD,0xFD}, {0xFD,0xFE}, {0xFE,0x40}, {0xFE,0x41},
+ {0xFE,0x42}, {0xFE,0x43}, {0xFE,0x44}, {0xFE,0x45},
+ {0xFE,0x46}, {0xFE,0x47}, {0xFE,0x48}, {0xFE,0x49},
+ {0xFE,0x4A}, {0xFE,0x4B}, {0xFE,0x4C}, {0xFE,0x4D},
+ {0xFE,0x4E}, {0xFE,0x4F}, {0xFE,0x50}, {0xFE,0x51},
+ {0x99,0x75}, {0xFE,0x53}, {0xFE,0x54}, {0xFE,0x55},
+ {0xFE,0x56}, {0xFE,0x57}, {0xFE,0x58}, {0xFE,0x59},
+ {0xFE,0x5A}, {0xFE,0x5B}, {0xFE,0x5C}, {0xFE,0x5D},
+ {0xFE,0x5E}, {0xFE,0x5F}, {0xFE,0x60}, {0xFE,0x61},
+ {0xFE,0x62}, {0xFE,0x63}, {0xFE,0x64}, {0xFE,0x65},
+ {0xFE,0x66}, {0xFE,0x67}, {0xFE,0x68}, {0xFE,0x69},
+ {0xFE,0x6A}, {0xFE,0x6B}, {0xFE,0x6C}, {0xFE,0x6D},
+ {0xFE,0x6E}, {0xB7,0xEC}, {0xFE,0x70}, {0xFE,0x71},
+ {0xFE,0x72}, {0xFE,0x73}, {0xFE,0x74}, {0xFE,0x75},
+ {0xFE,0x76}, {0xFE,0x77}, {0xFE,0x78}, {0xFE,0x79},
+ {0xFE,0x7A}, {0xFE,0x7B}, {0xFE,0x7C}, {0xFE,0x7D},
+ {0xFE,0x7E}, {0xFE,0xA1}, {0xFE,0xA2}, {0xFE,0xA3},
+ {0xFE,0xA4}, {0xFE,0xA5}, {0xFE,0xA6}, {0xFE,0xA7},
+ {0xFE,0xA8}, {0xFE,0xA9}, {0xA2,0x60}, {0xFE,0xAB},
+ {0xFE,0xAC}, {0xFE,0xAD}, {0xFE,0xAE}, {0xFE,0xAF},
+ {0xFE,0xB0}, {0xFE,0xB1}, {0xFE,0xB2}, {0xFE,0xB3},
+ {0xFE,0xB4}, {0xFE,0xB5}, {0xFE,0xB6}, {0xFE,0xB7},
+ {0xFE,0xB8}, {0xFE,0xB9}, {0xFE,0xBA}, {0xFE,0xBB},
+ {0xFE,0xBC}, {0xFE,0xBD}, {0xFE,0xBE}, {0xFE,0xBF},
+ {0xFE,0xC0}, {0xFE,0xC1}, {0xFE,0xC2}, {0xFE,0xC3},
+ {0xFE,0xC4}, {0xFE,0xC5}, {0xFE,0xC6}, {0xFE,0xC7},
+ {0xFE,0xC8}, {0xFE,0xC9}, {0xFE,0xCA}, {0xFE,0xCB},
+ {0xFE,0xCC}, {0xFE,0xCD}, {0xFE,0xCE}, {0xFE,0xCF},
+ {0xFE,0xD0}, {0xFE,0xD1}, {0xFE,0xD2}, {0xFE,0xD3},
+ {0xFE,0xD4}, {0xFE,0xD5}, {0xFE,0xD6}, {0xFE,0xD7},
+ {0xFE,0xD8}, {0xFE,0xD9}, {0xFE,0xDA}, {0xFE,0xDB},
+ {0xFE,0xDC}, {0xCF,0xF1}, {0xFE,0xDE}, {0xFE,0xDF},
+ {0xFE,0xE0}, {0xFE,0xE1}, {0xFE,0xE2}, {0xFE,0xE3},
+ {0xFE,0xE4}, {0xFE,0xE5}, {0xFE,0xE6}, {0xFE,0xE7},
+ {0xFE,0xE8}, {0xFE,0xE9}, {0xFE,0xEA}, {0xFE,0xEB},
+ {0xFE,0xEC}, {0xFE,0xED}, {0xFE,0xEE}, {0xFE,0xEF},
+ {0xFE,0xF0}, {0xFE,0xF1}, {0xFE,0xF2}, {0xFE,0xF3},
+ {0xFE,0xF4}, {0xFE,0xF5}, {0xFE,0xF6}, {0xFE,0xF7},
+ {0xFE,0xF8}, {0xFE,0xF9}, {0xFE,0xFA}, {0xFE,0xFB},
+ {0xFE,0xFC}, {0xFE,0xFD}, {0xFE,0xFE}, {0x8E,0x40},
+ {0x8E,0x41}, {0x8E,0x42}, {0x8E,0x43}, {0x8E,0x44},
+ {0x8E,0x45}, {0x8E,0x46}, {0x8E,0x47}, {0x8E,0x48},
+ {0x8E,0x49}, {0x8E,0x4A}, {0x8E,0x4B}, {0x8E,0x4C},
+ {0x8E,0x4D}, {0x8E,0x4E}, {0x8E,0x4F}, {0x8E,0x50},
+ {0x8E,0x51}, {0x8E,0x52}, {0x8E,0x53}, {0x8E,0x54},
+ {0x8E,0x55}, {0x8E,0x56}, {0x8E,0x57}, {0x8E,0x58},
+ {0x8E,0x59}, {0x8E,0x5A}, {0x8E,0x5B}, {0x8E,0x5C},
+ {0x8E,0x5D}, {0x8E,0x5E}, {0x8E,0x5F}, {0x8E,0x60},
+ {0x8E,0x61}, {0x8E,0x62}, {0x8E,0x63}, {0x8E,0x64},
+ {0x8E,0x65}, {0x8E,0x66}, {0x8E,0x67}, {0x8E,0x68},
+ {0xBA,0xE6}, {0x8E,0x6A}, {0x8E,0x6B}, {0x8E,0x6C},
+ {0x8E,0x6D}, {0x8E,0x6E}, {0xED,0xCA}, {0x8E,0x70},
+ {0x8E,0x71}, {0x8E,0x72}, {0x8E,0x73}, {0x8E,0x74},
+ {0x8E,0x75}, {0x8E,0x76}, {0x8E,0x77}, {0x8E,0x78},
+ {0x8E,0x79}, {0x8E,0x7A}, {0x8E,0x7B}, {0x8E,0x7C},
+ {0x8E,0x7D}, {0xA2,0x61}, {0x8E,0xA1}, {0x8E,0xA2},
+ {0x8E,0xA3}, {0x8E,0xA4}, {0x8E,0xA5}, {0x8E,0xA6},
+ {0x8E,0xA7}, {0x8E,0xA8}, {0x8E,0xA9}, {0x8E,0xAA},
+ {0xBA,0xFC}, {0x8E,0xAC}, {0x8E,0xAD}, {0x8E,0xAE},
+ {0x8E,0xAF}, {0x8E,0xB0}, {0x8E,0xB1}, {0x8E,0xB2},
+ {0x8E,0xB3}, {0xBF,0xA6}, {0x8E,0xB5}, {0x8E,0xB6},
+ {0x8E,0xB7}, {0x8E,0xB8}, {0x8E,0xB9}, {0x8E,0xBA},
+ {0x8E,0xBB}, {0x8E,0xBC}, {0x8E,0xBD}, {0x8E,0xBE},
+ {0x8E,0xBF}, {0x8E,0xC0}, {0x8E,0xC1}, {0x8E,0xC2},
+ {0x8E,0xC3}, {0x8E,0xC4}, {0x8E,0xC5}, {0x8E,0xC6},
+ {0x8E,0xC7}, {0x8E,0xC8}, {0x8E,0xC9}, {0x8E,0xCA},
+ {0x8E,0xCB}, {0x8E,0xCC}, {0xAA,0xCC}, {0x8E,0xCE},
+ {0x8E,0xCF}, {0xBF,0xAE}, {0x8E,0xD1}, {0x8E,0xD2},
+ {0x8E,0xD3}, {0x8E,0xD4}, {0x8E,0xD5}, {0x8E,0xD6},
+ {0x8E,0xD7}, {0x8E,0xD8}, {0x8E,0xD9}, {0x8E,0xDA},
+ {0x8E,0xDB}, {0x8E,0xDC}, {0x8E,0xDD}, {0x8E,0xDE},
+ {0x8E,0xDF}, {0x8E,0xE0}, {0x8E,0xE1}, {0x8E,0xE2},
+ {0x8E,0xE3}, {0x8E,0xE4}, {0x8E,0xE5}, {0x8E,0xE6},
+ {0x8E,0xE7}, {0x8E,0xE8}, {0x8E,0xE9}, {0x8E,0xEA},
+ {0x8E,0xEB}, {0x8E,0xEC}, {0x8E,0xED}, {0x8E,0xEE},
+ {0x8E,0xEF}, {0x8E,0xF0}, {0x8E,0xF1}, {0x8E,0xF2},
+ {0x8E,0xF3}, {0x8E,0xF4}, {0x8E,0xF5}, {0x8E,0xF6},
+ {0x8E,0xF7}, {0x8E,0xF8}, {0x8E,0xF9}, {0x8E,0xFA},
+ {0x8E,0xFB}, {0x8E,0xFC}, {0x8E,0xFD}, {0x8E,0xFE},
+ {0x8F,0x40}, {0x8F,0x41}, {0x8F,0x42}, {0x8F,0x43},
+ {0x8F,0x44}, {0x8F,0x45}, {0x8F,0x46}, {0x8F,0x47},
+ {0x8F,0x48}, {0x8F,0x49}, {0x8F,0x4A}, {0x8F,0x4B},
+ {0x8F,0x4C}, {0x8F,0x4D}, {0x8F,0x4E}, {0x8F,0x4F},
+ {0x8F,0x50}, {0x8F,0x51}, {0x8F,0x52}, {0x8F,0x53},
+ {0x8F,0x54}, {0x8F,0x55}, {0x8F,0x56}, {0xB5,0xD7},
+ {0x8F,0x58}, {0x8F,0x59}, {0x8F,0x5A}, {0x8F,0x5B},
+ {0x8F,0x5C}, {0x8F,0x5D}, {0x8F,0x5E}, {0x8F,0x5F},
+ {0x8F,0x60}, {0x8F,0x61}, {0x8F,0x62}, {0x8F,0x63},
+ {0x8F,0x64}, {0x8F,0x65}, {0x8F,0x66}, {0x8F,0x67},
+ {0x8F,0x68}, {0xE3,0xC8}, {0x8F,0x6A}, {0x8F,0x6B},
+ {0x8F,0x6C}, {0x8F,0x6D}, {0xDB,0x79}, {0x8F,0x6F},
+ {0x8F,0x70}, {0x8F,0x71}, {0x8F,0x72}, {0x8F,0x73},
+ {0x8F,0x74}, {0x8F,0x75}, {0x8F,0x76}, {0x8F,0x77},
+ {0x8F,0x78}, {0x8F,0x79}, {0x8F,0x7A}, {0x8F,0x7B},
+ {0x8F,0x7C}, {0x8F,0x7D}, {0x8F,0x7E}, {0x8F,0xA1},
+ {0x8F,0xA2}, {0x8F,0xA3}, {0x8F,0xA4}, {0x8F,0xA5},
+ {0x8F,0xA6}, {0x8F,0xA7}, {0x8F,0xA8}, {0x8F,0xA9},
+ {0x8F,0xAA}, {0x8F,0xAB}, {0x8F,0xAC}, {0x8F,0xAD},
+ {0x8F,0xAE}, {0x8F,0xAF}, {0x8F,0xB0}, {0x8F,0xB1},
+ {0x8F,0xB2}, {0x8F,0xB3}, {0x8F,0xB4}, {0x8F,0xB5},
+ {0x8F,0xB6}, {0x8F,0xB7}, {0x8F,0xB8}, {0x8F,0xB9},
+ {0x8F,0xBA}, {0x8F,0xBB}, {0x8F,0xBC}, {0x8F,0xBD},
+ {0x8F,0xBE}, {0x8F,0xBF}, {0x8F,0xC0}, {0x8F,0xC1},
+ {0x8F,0xC2}, {0x8F,0xC3}, {0x8F,0xC4}, {0x8F,0xC5},
+ {0x8F,0xC6}, {0x8F,0xC7}, {0x8F,0xC8}, {0x8F,0xC9},
+ {0x8F,0xCA}, {0xBF,0xCC}, {0xA0,0xD4}, {0x8F,0xCD},
+ {0x8F,0xCE}, {0x8F,0xCF}, {0x8F,0xD0}, {0x8F,0xD1},
+ {0x8F,0xD2}, {0x8F,0xD3}, {0x8F,0xD4}, {0x8F,0xD5},
+ {0x8F,0xD6}, {0x8F,0xD7}, {0x8F,0xD8}, {0x8F,0xD9},
+ {0x8F,0xDA}, {0x8F,0xDB}, {0x8F,0xDC}, {0x8F,0xDD},
+ {0x8F,0xDE}, {0x8F,0xDF}, {0x8F,0xE0}, {0x8F,0xE1},
+ {0x8F,0xE2}, {0x8F,0xE3}, {0x8F,0xE4}, {0x8F,0xE5},
+ {0x8F,0xE6}, {0x8F,0xE7}, {0x8F,0xE8}, {0x8F,0xE9},
+ {0x8F,0xEA}, {0x8F,0xEB}, {0x8F,0xEC}, {0x8F,0xED},
+ {0x8F,0xEE}, {0x8F,0xEF}, {0x8F,0xF0}, {0x8F,0xF1},
+ {0x8F,0xF2}, {0x8F,0xF3}, {0x8F,0xF4}, {0x8F,0xF5},
+ {0x8F,0xF6}, {0x8F,0xF7}, {0x8F,0xF8}, {0x8F,0xF9},
+ {0x8F,0xFA}, {0x8F,0xFB}, {0x8F,0xFC}, {0x8F,0xFD},
+ {0xB0,0x5F}, {0x90,0x40}, {0x90,0x41}, {0x90,0x42},
+ {0x90,0x43}, {0x90,0x44}, {0x90,0x45}, {0x90,0x46},
+ {0x90,0x47}, {0x90,0x48}, {0x90,0x49}, {0x90,0x4A},
+ {0x90,0x4B}, {0x90,0x4C}, {0x90,0x4D}, {0x90,0x4E},
+ {0x90,0x4F}, {0x90,0x50}, {0x90,0x51}, {0x90,0x52},
+ {0x90,0x53}, {0x90,0x54}, {0x90,0x55}, {0x90,0x56},
+ {0x90,0x57}, {0x90,0x58}, {0x90,0x59}, {0x90,0x5A},
+ {0x90,0x5B}, {0x90,0x5C}, {0x90,0x5D}, {0x90,0x5E},
+ {0x90,0x5F}, {0x90,0x60}, {0x90,0x61}, {0x90,0x62},
+ {0x90,0x63}, {0x90,0x64}, {0x90,0x65}, {0x90,0x66},
+ {0x90,0x67}, {0x90,0x68}, {0x90,0x69}, {0x90,0x6A},
+ {0x90,0x6B}, {0x90,0x6C}, {0xB3,0xA3}, {0x90,0x6E},
+ {0x90,0x6F}, {0x90,0x70}, {0x90,0x71}, {0x90,0x72},
+ {0x90,0x73}, {0x90,0x74}, {0x90,0x75}, {0x90,0x76},
+ {0x90,0x77}, {0x90,0x78}, {0x90,0x79}, {0xF9,0xD7},
+ {0x90,0x7B}, {0x90,0x7C}, {0x90,0x7D}, {0x90,0x7E},
+ {0x90,0xA1}, {0x90,0xA2}, {0x90,0xA3}, {0x90,0xA4},
+ {0x90,0xA5}, {0x90,0xA6}, {0x90,0xA7}, {0x90,0xA8},
+ {0x90,0xA9}, {0x90,0xAA}, {0x90,0xAB}, {0x90,0xAC},
+ {0x90,0xAD}, {0x90,0xAE}, {0x90,0xAF}, {0x90,0xB0},
+ {0x90,0xB1}, {0x90,0xB2}, {0x90,0xB3}, {0x90,0xB4},
+ {0x90,0xB5}, {0x90,0xB6}, {0x90,0xB7}, {0x90,0xB8},
+ {0x90,0xB9}, {0x90,0xBA}, {0x90,0xBB}, {0x90,0xBC},
+ {0x90,0xBD}, {0x90,0xBE}, {0x90,0xBF}, {0x90,0xC0},
+ {0x90,0xC1}, {0x90,0xC2}, {0x90,0xC3}, {0x90,0xC4},
+ {0x90,0xC5}, {0x90,0xC6}, {0x90,0xC7}, {0x90,0xC8},
+ {0x90,0xC9}, {0x90,0xCA}, {0x90,0xCB}, {0x90,0xCC},
+ {0x90,0xCD}, {0x90,0xCE}, {0x90,0xCF}, {0x90,0xD0},
+ {0x90,0xD1}, {0x90,0xD2}, {0x90,0xD3}, {0x90,0xD4},
+ {0x90,0xD5}, {0x90,0xD6}, {0x90,0xD7}, {0x90,0xD8},
+ {0x90,0xD9}, {0x90,0xDA}, {0x90,0xDB}, {0xC0,0x52},
+ {0x90,0xDD}, {0x90,0xDE}, {0x90,0xDF}, {0x90,0xE0},
+ {0x90,0xE1}, {0x90,0xE2}, {0x90,0xE3}, {0x90,0xE4},
+ {0x90,0xE5}, {0x90,0xE6}, {0x90,0xE7}, {0x90,0xE8},
+ {0x90,0xE9}, {0x90,0xEA}, {0x90,0xEB}, {0x90,0xEC},
+ {0x90,0xED}, {0x90,0xEE}, {0x90,0xEF}, {0x90,0xF0},
+ {0xC5,0x54}, {0x90,0xF2}, {0x90,0xF3}, {0x90,0xF4},
+ {0x90,0xF5}, {0x90,0xF6}, {0x90,0xF7}, {0x90,0xF8},
+ {0x90,0xF9}, {0x90,0xFA}, {0x90,0xFB}, {0x90,0xFC},
+ {0x90,0xFD}, {0x90,0xFE}, {0x91,0x40}, {0x91,0x41},
+ {0x91,0x42}, {0x91,0x43}, {0x91,0x44}, {0x91,0x45},
+ {0x91,0x46}, {0x91,0x47}, {0x91,0x48}, {0x91,0x49},
+ {0x91,0x4A}, {0x91,0x4B}, {0x91,0x4C}, {0x91,0x4D},
+ {0x91,0x4E}, {0x91,0x4F}, {0x91,0x50}, {0x91,0x51},
+ {0x91,0x52}, {0x91,0x53}, {0x91,0x54}, {0x91,0x55},
+ {0x91,0x56}, {0x91,0x57}, {0x91,0x58}, {0x91,0x59},
+ {0x91,0x5A}, {0x91,0x5B}, {0x91,0x5C}, {0x91,0x5D},
+ {0x91,0x5E}, {0x91,0x5F}, {0x91,0x60}, {0x91,0x61},
+ {0x91,0x62}, {0x91,0x63}, {0x91,0x64}, {0x91,0x65},
+ {0x91,0x66}, {0x91,0x67}, {0x91,0x68}, {0x91,0x69},
+ {0x91,0x6A}, {0x91,0x6B}, {0x91,0x6C}, {0x91,0x6D},
+ {0x91,0x6E}, {0x91,0x6F}, {0x91,0x70}, {0x91,0x71},
+ {0x91,0x72}, {0x91,0x73}, {0x91,0x74}, {0x91,0x75},
+ {0x91,0x76}, {0x91,0x77}, {0x91,0x78}, {0x91,0x79},
+ {0x91,0x7A}, {0x91,0x7B}, {0x91,0x7C}, {0x91,0x7D},
+ {0x91,0x7E}, {0x91,0xA1}, {0x91,0xA2}, {0x91,0xA3},
+ {0x91,0xA4}, {0x91,0xA5}, {0x91,0xA6}, {0x91,0xA7},
+ {0x91,0xA8}, {0x91,0xA9}, {0x91,0xAA}, {0x91,0xAB},
+ {0x91,0xAC}, {0x91,0xAD}, {0x91,0xAE}, {0x91,0xAF},
+ {0x91,0xB0}, {0x91,0xB1}, {0x91,0xB2}, {0x91,0xB3},
+ {0x91,0xB4}, {0x91,0xB5}, {0x91,0xB6}, {0x91,0xB7},
+ {0x91,0xB8}, {0x91,0xB9}, {0x91,0xBA}, {0x91,0xBB},
+ {0x91,0xBC}, {0x91,0xBD}, {0x91,0xBE}, {0xF1,0xE3},
+ {0x91,0xC0}, {0x91,0xC1}, {0x91,0xC2}, {0x91,0xC3},
+ {0x91,0xC4}, {0x91,0xC5}, {0x91,0xC6}, {0x91,0xC7},
+ {0x91,0xC8}, {0x91,0xC9}, {0x91,0xCA}, {0x91,0xCB},
+ {0x91,0xCC}, {0x91,0xCD}, {0x91,0xCE}, {0x91,0xCF},
+ {0x91,0xD0}, {0x91,0xD1}, {0x91,0xD2}, {0x91,0xD3},
+ {0x91,0xD4}, {0x91,0xD5}, {0x91,0xD6}, {0x91,0xD7},
+ {0x91,0xD8}, {0x91,0xD9}, {0x91,0xDA}, {0x91,0xDB},
+ {0x91,0xDC}, {0x91,0xDD}, {0x91,0xDE}, {0x91,0xDF},
+ {0x91,0xE0}, {0x91,0xE1}, {0x91,0xE2}, {0x91,0xE3},
+ {0x91,0xE4}, {0x91,0xE5}, {0x91,0xE6}, {0x91,0xE7},
+ {0x91,0xE8}, {0x91,0xE9}, {0x91,0xEA}, {0x91,0xEB},
+ {0x91,0xEC}, {0x91,0xED}, {0x91,0xEE}, {0x91,0xEF},
+ {0x91,0xF0}, {0x91,0xF1}, {0x91,0xF2}, {0x91,0xF3},
+ {0x91,0xF4}, {0x91,0xF5}, {0x91,0xF6}, {0x91,0xF7},
+ {0x91,0xF8}, {0x91,0xF9}, {0x91,0xFA}, {0x91,0xFB},
+ {0x91,0xFC}, {0x91,0xFD}, {0x91,0xFE}, {0x92,0x40},
+ {0x92,0x41}, {0x92,0x42}, {0x92,0x43}, {0x92,0x42},
+ {0x92,0x45}, {0x92,0x46}, {0x92,0x47}, {0x92,0x48},
+ {0x92,0x49}, {0x92,0x4A}, {0x92,0x4B}, {0x92,0x4C},
+ {0x92,0x4D}, {0x92,0x4E}, {0x92,0x4F}, {0x92,0x50},
+ {0x92,0x51}, {0x92,0x52}, {0x92,0x53}, {0x92,0x54},
+ {0x92,0x55}, {0x92,0x56}, {0x92,0x57}, {0x92,0x58},
+ {0x92,0x59}, {0x92,0x5A}, {0x92,0x5B}, {0x92,0x5C},
+ {0x92,0x5D}, {0x92,0x5E}, {0x92,0x5F}, {0x92,0x60},
+ {0x92,0x61}, {0x92,0x62}, {0x92,0x63}, {0x92,0x64},
+ {0x92,0x65}, {0x92,0x66}, {0x92,0x67}, {0x92,0x68},
+ {0x92,0x69}, {0x92,0x6A}, {0x92,0x6B}, {0x92,0x6C},
+ {0x92,0x6D}, {0x92,0x6E}, {0x92,0x6F}, {0x92,0x70},
+ {0x92,0x71}, {0x92,0x72}, {0x92,0x73}, {0x92,0x74},
+ {0x92,0x75}, {0x92,0x76}, {0x92,0x77}, {0x92,0x78},
+ {0x92,0x79}, {0x92,0x7A}, {0x92,0x7B}, {0x92,0x7C},
+ {0x92,0x7D}, {0x92,0x7E}, {0x92,0xA1}, {0x92,0xA2},
+ {0x92,0xA3}, {0x92,0xA4}, {0x92,0xA5}, {0x92,0xA6},
+ {0x92,0xA7}, {0x92,0xA8}, {0x92,0xA9}, {0x92,0xAA},
+ {0x92,0xAB}, {0x92,0xAC}, {0x92,0xAD}, {0x92,0xAE},
+ {0xA2,0x59}, {0xA2,0x5A}, {0xA2,0x5C}, {0xA2,0x5B},
+ {0x92,0xB3}, {0x92,0xB4}, {0x92,0xB5}, {0x92,0xB6},
+ {0x92,0xB7}, {0x92,0xB8}, {0x92,0xB9}, {0x92,0xBA},
+ {0x92,0xBB}, {0x92,0xBC}, {0x92,0xBD}, {0x92,0xBE},
+ {0x92,0xBF}, {0x92,0xC0}, {0x92,0xC1}, {0x92,0xC2},
+ {0x92,0xC3}, {0x92,0xC4}, {0x92,0xC5}, {0x92,0xC6},
+ {0x92,0xC7}, {0xA0,0x5F}, {0x92,0xC9}, {0x92,0xCA},
+ {0x92,0xCB}, {0x92,0xCC}, {0x92,0xCD}, {0x92,0xCE},
+ {0x92,0xCF}, {0x92,0xD0}, {0xE6,0xAB}, {0x92,0xD2},
+ {0x92,0xD3}, {0x92,0xD4}, {0x92,0xD5}, {0x92,0xD6},
+ {0x92,0xD7}, {0x92,0xD8}, {0x92,0xD9}, {0x92,0xDA},
+ {0x92,0xDB}, {0x92,0xDC}, {0x92,0xDD}, {0x92,0xDE},
+ {0x92,0xDF}, {0x92,0xE0}, {0x92,0xE1}, {0x92,0xE2},
+ {0x92,0xE3}, {0x92,0xE4}, {0x92,0xE5}, {0x92,0xE6},
+ {0x92,0xE7}, {0x92,0xE8}, {0x92,0xE9}, {0x92,0xEA},
+ {0x92,0xEB}, {0x92,0xEC}, {0x92,0xED}, {0x92,0xEE},
+ {0x92,0xEF}, {0x92,0xF0}, {0x92,0xF1}, {0x92,0xF2},
+ {0x92,0xF3}, {0x92,0xF4}, {0x92,0xF5}, {0x92,0xF6},
+ {0x92,0xF7}, {0x92,0xF8}, {0x92,0xF9}, {0x92,0xFA},
+ {0x92,0xFB}, {0x92,0xFC}, {0x92,0xFD}, {0x92,0xFE},
+ {0x93,0x40}, {0x93,0x41}, {0x93,0x42}, {0x93,0x43},
+ {0x93,0x44}, {0x93,0x45}, {0x93,0x46}, {0x93,0x47},
+ {0x93,0x48}, {0x93,0x49}, {0x93,0x4A}, {0x93,0x4B},
+ {0x93,0x4C}, {0x93,0x4D}, {0x93,0x4E}, {0x93,0x4F},
+ {0x93,0x50}, {0x93,0x51}, {0x93,0x52}, {0x93,0x53},
+ {0x93,0x54}, {0x93,0x55}, {0x93,0x56}, {0x93,0x57},
+ {0x93,0x58}, {0x93,0x59}, {0x93,0x5A}, {0x93,0x5B},
+ {0x93,0x5C}, {0x93,0x5D}, {0x93,0x5E}, {0x93,0x5F},
+ {0x93,0x60}, {0x93,0x61}, {0x93,0x62}, {0x93,0x63},
+ {0x93,0x64}, {0x93,0x65}, {0x93,0x66}, {0x93,0x67},
+ {0x93,0x68}, {0x93,0x69}, {0x93,0x6A}, {0x93,0x6B},
+ {0x93,0x6C}, {0x93,0x6D}, {0x93,0x6E}, {0x93,0x6F},
+ {0x93,0x70}, {0x93,0x71}, {0x93,0x72}, {0x93,0x73},
+ {0x93,0x74}, {0x93,0x75}, {0x93,0x76}, {0x93,0x77},
+ {0x93,0x78}, {0x93,0x79}, {0x93,0x7A}, {0x93,0x7B},
+ {0x93,0x7C}, {0x93,0x7D}, {0x93,0x7E}, {0x93,0xA1},
+ {0x93,0xA2}, {0x93,0xA3}, {0x93,0xA4}, {0x93,0xA5},
+ {0x93,0xA6}, {0x93,0xA7}, {0x93,0xA8}, {0x93,0xA9},
+ {0x93,0xAA}, {0x93,0xAB}, {0x93,0xAC}, {0x93,0xAD},
+ {0x93,0xAE}, {0x93,0xAF}, {0x93,0xB0}, {0x93,0xB1},
+ {0x93,0xB2}, {0x93,0xB3}, {0x93,0xB4}, {0x93,0xB5},
+ {0x93,0xB6}, {0x93,0xB7}, {0x93,0xB8}, {0x93,0xB9},
+ {0x93,0xBA}, {0x93,0xBB}, {0x93,0xBC}, {0x93,0xBD},
+ {0x93,0xBE}, {0x93,0xBF}, {0x93,0xC0}, {0x93,0xC1},
+ {0x93,0xC2}, {0x93,0xC3}, {0x93,0xC4}, {0x93,0xC5},
+ {0x93,0xC6}, {0x93,0xC7}, {0x93,0xC8}, {0x93,0xC9},
+ {0x93,0xCA}, {0x93,0xCB}, {0x93,0xCC}, {0x93,0xCD},
+ {0x93,0xCE}, {0x93,0xCF}, {0x93,0xD0}, {0x93,0xD1},
+ {0x93,0xD2}, {0x93,0xD3}, {0x93,0xD4}, {0x93,0xD5},
+ {0x93,0xD6}, {0x93,0xD7}, {0x93,0xD8}, {0x93,0xD9},
+ {0x93,0xDA}, {0x93,0xDB}, {0x93,0xDC}, {0x93,0xDD},
+ {0x93,0xDE}, {0x93,0xDF}, {0x93,0xE0}, {0x93,0xE1},
+ {0x93,0xE2}, {0x93,0xE3}, {0x93,0xE4}, {0x93,0xE5},
+ {0x93,0xE6}, {0x93,0xE7}, {0x93,0xE8}, {0x93,0xE9},
+ {0x93,0xEA}, {0x93,0xEB}, {0x93,0xEC}, {0x93,0xED},
+ {0x93,0xEE}, {0x93,0xEF}, {0x93,0xF0}, {0x93,0xF1},
+ {0x93,0xF2}, {0x93,0xF3}, {0x93,0xF4}, {0x93,0xF5},
+ {0x93,0xF6}, {0x93,0xF7}, {0x93,0xF8}, {0x93,0xF9},
+ {0x93,0xFA}, {0x93,0xFB}, {0x93,0xFC}, {0x93,0xFD},
+ {0x93,0xFE}, {0x94,0x40}, {0x94,0x41}, {0x94,0x42},
+ {0x94,0x43}, {0x94,0x44}, {0x94,0x45}, {0x94,0x46},
+ {0xD2,0x56}, {0x94,0x48}, {0x94,0x49}, {0x94,0x4A},
+ {0x94,0x4B}, {0x94,0x4C}, {0x94,0x4D}, {0x94,0x4E},
+ {0x94,0x4F}, {0x94,0x50}, {0x94,0x51}, {0x94,0x52},
+ {0x94,0x53}, {0x94,0x54}, {0x94,0x55}, {0x94,0x56},
+ {0x94,0x57}, {0x94,0x58}, {0x94,0x59}, {0x94,0x5A},
+ {0x94,0x5B}, {0x94,0x5C}, {0x94,0x5D}, {0x94,0x5E},
+ {0x94,0x5F}, {0x94,0x60}, {0x94,0x61}, {0x94,0x62},
+ {0x94,0x63}, {0x94,0x64}, {0x94,0x65}, {0x94,0x66},
+ {0x94,0x67}, {0x94,0x68}, {0x94,0x69}, {0x94,0x6A},
+ {0x94,0x6B}, {0x94,0x6C}, {0x94,0x6D}, {0x94,0x6E},
+ {0x94,0x6F}, {0x94,0x70}, {0x94,0x71}, {0x94,0x72},
+ {0x94,0x73}, {0x94,0x74}, {0x94,0x75}, {0x94,0x76},
+ {0x94,0x77}, {0x94,0x78}, {0x94,0x79}, {0x94,0x7A},
+ {0x94,0x7B}, {0x94,0x7C}, {0x94,0x7D}, {0x94,0x7E},
+ {0x94,0xA1}, {0x94,0xA2}, {0x94,0xA3}, {0x94,0xA4},
+ {0x94,0xA5}, {0x94,0xA6}, {0x94,0xA7}, {0x94,0xA8},
+ {0x94,0xA9}, {0x94,0xAA}, {0x94,0xAB}, {0x94,0xAC},
+ {0x94,0xAD}, {0x94,0xAE}, {0x94,0xAF}, {0x94,0xB0},
+ {0x94,0xB1}, {0x94,0xB2}, {0x94,0xB3}, {0x94,0xB4},
+ {0x94,0xB5}, {0x94,0xB6}, {0x94,0xB7}, {0x94,0xB8},
+ {0x94,0xB9}, {0x94,0xBA}, {0x94,0xBB}, {0x94,0xBC},
+ {0x94,0xBD}, {0x94,0xBE}, {0x94,0xBF}, {0x94,0xC0},
+ {0x94,0xC1}, {0x94,0xC2}, {0x94,0xC3}, {0x94,0xC4},
+ {0x94,0xC5}, {0x94,0xC6}, {0x94,0xC7}, {0x94,0xC8},
+ {0x94,0xC9}, {0xE6,0xD0}, {0x94,0xCB}, {0x94,0xCC},
+ {0x94,0xCD}, {0x94,0xCE}, {0x94,0xCF}, {0x94,0xD0},
+ {0x94,0xD1}, {0x94,0xD2}, {0x94,0xD3}, {0x94,0xD4},
+ {0x94,0xD5}, {0x94,0xD6}, {0x94,0xD7}, {0x94,0xD8},
+ {0x94,0xD9}, {0x94,0xDA}, {0x94,0xDB}, {0x94,0xDC},
+ {0x94,0xDD}, {0x94,0xDE}, {0x94,0xDF}, {0x94,0xE0},
+ {0x94,0xE1}, {0x94,0xE2}, {0x94,0xE3}, {0x94,0xE4},
+ {0x94,0xE5}, {0x94,0xE6}, {0x94,0xE7}, {0x94,0xE8},
+ {0x94,0xE9}, {0x94,0xEA}, {0x94,0xEB}, {0x94,0xEC},
+ {0x94,0xED}, {0x94,0xEE}, {0x94,0xEF}, {0x94,0xF0},
+ {0x94,0xF1}, {0x94,0xF2}, {0x94,0xF3}, {0x94,0xF4},
+ {0x94,0xF5}, {0x94,0xF6}, {0x94,0xF7}, {0x94,0xF8},
+ {0x94,0xF9}, {0x94,0xFA}, {0x94,0xFB}, {0x94,0xFC},
+ {0x94,0xFD}, {0x94,0xFE}, {0x95,0x40}, {0x95,0x41},
+ {0x95,0x42}, {0x95,0x43}, {0x95,0x44}, {0x95,0x45},
+ {0x95,0x46}, {0x95,0x47}, {0x95,0x48}, {0x95,0x49},
+ {0x95,0x4A}, {0x95,0x4B}, {0x95,0x4C}, {0x95,0x4D},
+ {0x95,0x4E}, {0x95,0x4F}, {0x95,0x50}, {0x95,0x51},
+ {0x95,0x52}, {0x95,0x53}, {0x95,0x54}, {0x95,0x55},
+ {0x95,0x56}, {0x95,0x57}, {0x95,0x58}, {0x95,0x59},
+ {0x95,0x5A}, {0x95,0x5B}, {0x95,0x5C}, {0x95,0x5D},
+ {0x95,0x5E}, {0x95,0x5F}, {0x95,0x60}, {0x95,0x61},
+ {0x95,0x62}, {0x95,0x63}, {0x95,0x64}, {0x95,0x65},
+ {0x95,0x66}, {0x95,0x67}, {0x95,0x68}, {0x95,0x69},
+ {0x95,0x6A}, {0x95,0x6B}, {0x95,0x6C}, {0x95,0x6D},
+ {0x95,0x6E}, {0x95,0x6F}, {0x95,0x70}, {0x95,0x71},
+ {0x95,0x72}, {0x95,0x73}, {0x95,0x74}, {0x95,0x75},
+ {0x95,0x76}, {0x95,0x77}, {0x95,0x78}, {0x95,0x79},
+ {0x95,0x7A}, {0x95,0x7B}, {0x95,0x7C}, {0x95,0x7D},
+ {0x95,0x7E}, {0x95,0xA1}, {0x95,0xA2}, {0x95,0xA3},
+ {0x95,0xA4}, {0x95,0xA5}, {0x95,0xA6}, {0x95,0xA7},
+ {0x95,0xA8}, {0x95,0xA9}, {0x95,0xAA}, {0x95,0xAB},
+ {0x95,0xAC}, {0x95,0xAD}, {0x95,0xAE}, {0x95,0xAF},
+ {0x95,0xB0}, {0x95,0xB1}, {0x95,0xB2}, {0x95,0xB3},
+ {0x95,0xB4}, {0x95,0xB5}, {0x95,0xB6}, {0x95,0xB7},
+ {0x95,0xB8}, {0x95,0xB9}, {0x95,0xBA}, {0x95,0xBB},
+ {0x95,0xBC}, {0x95,0xBD}, {0x95,0xBE}, {0x95,0xBF},
+ {0x95,0xC0}, {0x95,0xC1}, {0x95,0xC2}, {0x95,0xC3},
+ {0x95,0xC4}, {0x95,0xC5}, {0x95,0xC6}, {0x95,0xC7},
+ {0x95,0xC8}, {0x95,0xC9}, {0x95,0xCA}, {0x95,0xCB},
+ {0x95,0xCC}, {0x95,0xCD}, {0x95,0xCE}, {0x95,0xCF},
+ {0x95,0xD0}, {0x95,0xD1}, {0x95,0xD2}, {0x95,0xD3},
+ {0x95,0xD4}, {0x95,0xD5}, {0x95,0xD6}, {0x95,0xD7},
+ {0x95,0xD8}, {0xCA,0x52}, {0x95,0xDA}, {0x95,0xDB},
+ {0x95,0xDC}, {0x95,0xDD}, {0x95,0xDE}, {0x95,0xDF},
+ {0x95,0xE0}, {0x95,0xE1}, {0x95,0xE2}, {0x95,0xE3},
+ {0x95,0xE4}, {0x95,0xE5}, {0x95,0xE6}, {0x95,0xE7},
+ {0x95,0xE8}, {0x95,0xE9}, {0x95,0xEA}, {0x95,0xEB},
+ {0x95,0xEC}, {0x95,0xED}, {0x95,0xEE}, {0x95,0xEF},
+ {0x95,0xF0}, {0x95,0xF1}, {0x95,0xF2}, {0x95,0xF3},
+ {0x95,0xF4}, {0x95,0xF5}, {0x95,0xF6}, {0x95,0xF7},
+ {0x95,0xF8}, {0x95,0xF9}, {0x95,0xFA}, {0x95,0xFB},
+ {0x95,0xFC}, {0x95,0xFD}, {0x95,0xFE}, {0x96,0x40},
+ {0x96,0x41}, {0x96,0x42}, {0x96,0x43}, {0x9C,0xE4},
+ {0x96,0x45}, {0x96,0x46}, {0x96,0x47}, {0x96,0x48},
+ {0x96,0x49}, {0x96,0x4A}, {0x96,0x4B}, {0x96,0x4C},
+ {0x96,0x4D}, {0x96,0x4E}, {0x96,0x4F}, {0x96,0x50},
+ {0x96,0x51}, {0x96,0x52}, {0x96,0x53}, {0x96,0x54},
+ {0x96,0x55}, {0x96,0x56}, {0x96,0x57}, {0x96,0x58},
+ {0x96,0x59}, {0x96,0x5A}, {0x96,0x5B}, {0x96,0x5C},
+ {0x96,0x5D}, {0x96,0x5E}, {0x96,0x5F}, {0x96,0x60},
+ {0x96,0x61}, {0x96,0x62}, {0x96,0x63}, {0x96,0x64},
+ {0x96,0x65}, {0x96,0x66}, {0x96,0x67}, {0x96,0x68},
+ {0x96,0x69}, {0x96,0x6A}, {0x96,0x6B}, {0x96,0x6C},
+ {0x96,0x6D}, {0x96,0x6E}, {0x96,0x6F}, {0x96,0x70},
+ {0x96,0x71}, {0x96,0x72}, {0x96,0x73}, {0x96,0x74},
+ {0x96,0x75}, {0x96,0x76}, {0x96,0x77}, {0x96,0x78},
+ {0x96,0x79}, {0x96,0x7A}, {0x96,0x7B}, {0x96,0x7C},
+ {0x96,0x7D}, {0x96,0x7E}, {0x96,0xA1}, {0x96,0xA2},
+ {0x96,0xA3}, {0x96,0xA4}, {0x96,0xA5}, {0x96,0xA6},
+ {0x96,0xA7}, {0x96,0xA8}, {0x96,0xA9}, {0x96,0xAA},
+ {0x96,0xAB}, {0x96,0xAC}, {0x96,0xAD}, {0x96,0xAE},
+ {0x96,0xAF}, {0x96,0xB0}, {0x96,0xB1}, {0x96,0xB2},
+ {0x96,0xB3}, {0x96,0xB4}, {0x96,0xB5}, {0x96,0xB6},
+ {0x96,0xB7}, {0x96,0xB8}, {0x96,0xB9}, {0x96,0xBA},
+ {0x96,0xBB}, {0x96,0xBC}, {0x96,0xBD}, {0x96,0xBE},
+ {0x96,0xBF}, {0x96,0xC0}, {0x96,0xC1}, {0x96,0xC2},
+ {0x96,0xC3}, {0x96,0xC4}, {0x96,0xC5}, {0x96,0xC6},
+ {0x96,0xC7}, {0x96,0xC8}, {0x96,0xC9}, {0x96,0xCA},
+ {0x96,0xCB}, {0x96,0xCC}, {0x96,0xCD}, {0x96,0xCE},
+ {0x96,0xCF}, {0x96,0xD0}, {0x96,0xD1}, {0x96,0xD2},
+ {0x96,0xD3}, {0x96,0xD4}, {0x96,0xD5}, {0x96,0xD6},
+ {0x96,0xD7}, {0x96,0xD8}, {0x96,0xD9}, {0x96,0xDA},
+ {0x96,0xDB}, {0x96,0xDC}, {0x96,0xDD}, {0x96,0xDE},
+ {0x96,0xDF}, {0x96,0xE0}, {0x96,0xE1}, {0x96,0xE2},
+ {0x96,0xE3}, {0x96,0xE4}, {0x96,0xE5}, {0x96,0xE6},
+ {0x96,0xE7}, {0x96,0xE8}, {0x96,0xE9}, {0x96,0xEA},
+ {0x96,0xEB}, {0x96,0xEC}, {0x96,0xEE}, {0x96,0xEE},
+ {0x96,0xEF}, {0x96,0xF0}, {0x96,0xF1}, {0x96,0xF2},
+ {0x96,0xF3}, {0x96,0xF4}, {0x96,0xF5}, {0x96,0xF6},
+ {0x96,0xF7}, {0x96,0xF8}, {0x96,0xF9}, {0x96,0xFA},
+ {0x96,0xFB}, {0xE9,0x59}, {0x96,0xFD}, {0x96,0xFE},
+ {0x97,0x40}, {0x97,0x41}, {0x97,0x42}, {0x97,0x43},
+ {0x97,0x44}, {0x97,0x45}, {0x97,0x46}, {0x97,0x47},
+ {0x97,0x48}, {0x97,0x49}, {0x97,0x4A}, {0x97,0x4B},
+ {0x97,0x4C}, {0x97,0x4D}, {0x97,0x4E}, {0x97,0x4F},
+ {0x97,0x50}, {0x97,0x51}, {0x97,0x52}, {0x97,0x53},
+ {0x97,0x54}, {0x97,0x55}, {0x97,0x56}, {0x97,0x57},
+ {0x97,0x58}, {0x97,0x59}, {0x97,0x5A}, {0x97,0x5B},
+ {0x97,0x5C}, {0x97,0x5D}, {0x97,0x5E}, {0x97,0x5F},
+ {0x97,0x60}, {0x97,0x61}, {0x97,0x62}, {0x97,0x63},
+ {0x97,0x64}, {0x97,0x65}, {0x97,0x66}, {0x97,0x67},
+ {0x97,0x68}, {0x97,0x69}, {0x97,0x6A}, {0x97,0x6B},
+ {0x97,0x6C}, {0x97,0x6D}, {0x97,0x6E}, {0x97,0x6F},
+ {0x97,0x70}, {0x97,0x71}, {0x97,0x72}, {0x97,0x73},
+ {0x97,0x74}, {0x97,0x75}, {0x97,0x76}, {0x97,0x77},
+ {0x97,0x78}, {0x97,0x79}, {0x97,0x7A}, {0x97,0x7B},
+ {0x97,0x7C}, {0x97,0x7D}, {0x97,0x7E}, {0x97,0xA1},
+ {0x97,0xA2}, {0x97,0xA3}, {0x97,0xA4}, {0x97,0xA5},
+ {0x97,0xA6}, {0x97,0xA7}, {0x97,0xA8}, {0x97,0xA9},
+ {0x97,0xAA}, {0x97,0xAB}, {0x97,0xAC}, {0x97,0xAD},
+ {0x97,0xAE}, {0x97,0xAF}, {0x97,0xB0}, {0x97,0xB1},
+ {0x97,0xB2}, {0x97,0xB3}, {0x97,0xB4}, {0x97,0xB5},
+ {0x97,0xB6}, {0x97,0xB7}, {0x97,0xB8}, {0x97,0xB9},
+ {0x97,0xBA}, {0x97,0xBB}, {0x97,0xBC}, {0x97,0xBD},
+ {0x97,0xBE}, {0x97,0xBF}, {0x97,0xC0}, {0x97,0xC1},
+ {0x97,0xC2}, {0x97,0xC3}, {0x97,0xC4}, {0x97,0xC5},
+ {0x97,0xC6}, {0x97,0xC7}, {0x97,0xC8}, {0x97,0xC9},
+ {0x97,0xCA}, {0x97,0xCB}, {0x97,0xCC}, {0x97,0xCD},
+ {0x97,0xCE}, {0x97,0xCF}, {0x97,0xD0}, {0x97,0xD1},
+ {0x97,0xD2}, {0x97,0xD3}, {0x97,0xD4}, {0x97,0xD5},
+ {0x97,0xD6}, {0x97,0xD7}, {0x97,0xD8}, {0x97,0xD9},
+ {0x97,0xDA}, {0x97,0xDB}, {0x97,0xDC}, {0x97,0xDD},
+ {0x97,0xDE}, {0x97,0xDF}, {0x97,0xE0}, {0x97,0xE1},
+ {0x97,0xE2}, {0x97,0xE3}, {0x97,0xE4}, {0x97,0xE5},
+ {0x97,0xE6}, {0x97,0xE7}, {0x97,0xE8}, {0x97,0xE9},
+ {0x97,0xEA}, {0x97,0xEB}, {0x97,0xEC}, {0x97,0xED},
+ {0x97,0xEE}, {0x97,0xEF}, {0x97,0xF0}, {0x97,0xF1},
+ {0x97,0xF2}, {0x97,0xF3}, {0x97,0xF4}, {0x97,0xF5},
+ {0x97,0xF6}, {0x97,0xF7}, {0x97,0xF8}, {0x97,0xF9},
+ {0x97,0xFA}, {0x97,0xFB}, {0x97,0xFC}, {0x97,0xFD},
+ {0x97,0xFE}, {0x98,0x40}, {0x98,0x41}, {0x98,0x42},
+ {0x98,0x43}, {0x98,0x44}, {0x98,0x45}, {0x98,0x46},
+ {0x98,0x47}, {0x98,0x48}, {0x98,0x49}, {0x98,0x4A},
+ {0x98,0x4B}, {0x98,0x4C}, {0x98,0x4D}, {0x98,0x4E},
+ {0x98,0x4F}, {0x98,0x50}, {0x98,0x51}, {0x98,0x52},
+ {0x98,0x53}, {0x98,0x54}, {0x98,0x55}, {0x98,0x56},
+ {0x98,0x57}, {0x98,0x58}, {0x98,0x59}, {0x98,0x5A},
+ {0x98,0x5B}, {0x98,0x5C}, {0x98,0x5D}, {0x98,0x5E},
+ {0x98,0x5F}, {0x98,0x60}, {0x98,0x61}, {0x98,0x62},
+ {0x98,0x63}, {0x98,0x64}, {0x98,0x65}, {0x98,0x66},
+ {0x98,0x67}, {0x98,0x68}, {0x98,0x69}, {0x98,0x6A},
+ {0x98,0x6B}, {0x98,0x6C}, {0x98,0x6D}, {0x98,0x6E},
+ {0x98,0x6F}, {0x98,0x70}, {0x98,0x71}, {0x98,0x72},
+ {0x98,0x73}, {0x98,0x74}, {0x98,0x75}, {0x98,0x76},
+ {0x98,0x77}, {0x98,0x78}, {0x98,0x79}, {0x98,0x7A},
+ {0x98,0x7B}, {0x98,0x7C}, {0x98,0x7D}, {0x98,0x7E},
+ {0x98,0xA1}, {0x98,0xA2}, {0x98,0xA3}, {0x98,0xA4},
+ {0x98,0xA5}, {0x98,0xA6}, {0x98,0xA7}, {0x98,0xA8},
+ {0x98,0xA9}, {0x98,0xAA}, {0x98,0xAB}, {0x98,0xAC},
+ {0x98,0xAD}, {0x98,0xAE}, {0x98,0xAF}, {0x98,0xB0},
+ {0x98,0xB1}, {0x98,0xB2}, {0x98,0xB3}, {0x98,0xB4},
+ {0x98,0xB5}, {0x98,0xB6}, {0x98,0xB7}, {0x98,0xB8},
+ {0x98,0xB9}, {0x98,0xBA}, {0x98,0xBB}, {0x98,0xBC},
+ {0x98,0xBD}, {0x98,0xBE}, {0x98,0xBF}, {0x98,0xC0},
+ {0x98,0xC1}, {0x98,0xC2}, {0x98,0xC3}, {0x98,0xC4},
+ {0x98,0xC5}, {0x98,0xC6}, {0x98,0xC7}, {0x98,0xC8},
+ {0x98,0xC9}, {0x98,0xCA}, {0x98,0xCB}, {0x98,0xCC},
+ {0x98,0xCD}, {0x98,0xCE}, {0x98,0xCF}, {0x98,0xD0},
+ {0x98,0xD1}, {0x98,0xD2}, {0x98,0xD3}, {0x98,0xD4},
+ {0x98,0xD5}, {0x98,0xD6}, {0x98,0xD7}, {0x98,0xD8},
+ {0x98,0xD9}, {0x98,0xDA}, {0x98,0xDB}, {0x98,0xDC},
+ {0x98,0xDD}, {0x98,0xDE}, {0x98,0xDF}, {0x98,0xE0},
+ {0x98,0xE1}, {0x98,0xE2}, {0x98,0xE3}, {0x98,0xE4},
+ {0x98,0xE5}, {0x98,0xE6}, {0x98,0xE7}, {0x98,0xE8},
+ {0x98,0xE9}, {0x98,0xEA}, {0x98,0xEB}, {0x98,0xEC},
+ {0x98,0xED}, {0x98,0xEE}, {0x98,0xEF}, {0x98,0xF0},
+ {0x98,0xF1}, {0x98,0xF2}, {0x98,0xF3}, {0x98,0xF4},
+ {0x98,0xF5}, {0x98,0xF6}, {0x98,0xF7}, {0x98,0xF8},
+ {0x98,0xF9}, {0x98,0xFA}, {0x98,0xFB}, {0x98,0xFC},
+ {0x98,0xFD}, {0x98,0xFE}, {0x99,0x40}, {0x99,0x41},
+ {0x99,0x42}, {0x99,0x43}, {0x99,0x44}, {0x99,0x45},
+ {0x99,0x46}, {0x99,0x47}, {0x99,0x48}, {0x99,0x49},
+ {0x99,0x4A}, {0x99,0x4B}, {0x99,0x4C}, {0x99,0x4D},
+ {0x99,0x4E}, {0x99,0x4F}, {0x99,0x50}, {0x99,0x51},
+ {0x99,0x52}, {0x99,0x53}, {0x99,0x54}, {0x99,0x55},
+ {0x99,0x56}, {0x99,0x57}, {0x99,0x58}, {0x99,0x59},
+ {0x99,0x5A}, {0x99,0x5B}, {0x99,0x5C}, {0x99,0x5D},
+ {0x99,0x5E}, {0x99,0x5F}, {0x99,0x60}, {0x99,0x61},
+ {0x99,0x62}, {0x99,0x63}, {0x99,0x64}, {0x99,0x65},
+ {0x99,0x66}, {0x99,0x67}, {0x99,0x68}, {0x99,0x69},
+ {0x99,0x6A}, {0x99,0x6B}, {0x99,0x6C}, {0x99,0x6D},
+ {0x99,0x6E}, {0x99,0x6F}, {0x99,0x70}, {0x99,0x71},
+ {0x99,0x72}, {0x99,0x73}, {0x99,0x74}, {0x99,0x75},
+ {0x99,0x76}, {0x99,0x77}, {0x99,0x78}, {0x99,0x79},
+ {0x99,0x7A}, {0x99,0x7B}, {0x99,0x7C}, {0x99,0x7D},
+ {0x99,0x7E}, {0x99,0xA1}, {0x99,0xA2}, {0x99,0xA3},
+ {0x99,0xA4}, {0x99,0xA5}, {0x99,0xA6}, {0x99,0xA7},
+ {0x99,0xA8}, {0x99,0xA9}, {0x99,0xAA}, {0x99,0xAB},
+ {0x99,0xAC}, {0x99,0xAD}, {0x99,0xAE}, {0x99,0xAF},
+ {0x99,0xB0}, {0x99,0xB1}, {0x99,0xB2}, {0x99,0xB3},
+ {0x99,0xB4}, {0x99,0xB5}, {0x99,0xB6}, {0x99,0xB7},
+ {0x99,0xB8}, {0x99,0xB9}, {0x99,0xBA}, {0x99,0xBB},
+ {0x99,0xBC}, {0x99,0xBD}, {0x99,0xBE}, {0x99,0xBF},
+ {0x99,0xC0}, {0x99,0xC1}, {0x99,0xC2}, {0x99,0xC3},
+ {0x99,0xC4}, {0x99,0xC5}, {0x99,0xC6}, {0x99,0xC7},
+ {0x99,0xC8}, {0x99,0xC9}, {0x99,0xCA}, {0x99,0xCB},
+ {0x99,0xCC}, {0x99,0xCD}, {0x99,0xCE}, {0x99,0xCF},
+ {0x99,0xD0}, {0x99,0xD1}, {0x99,0xD2}, {0x99,0xD3},
+ {0x99,0xD4}, {0x99,0xD5}, {0x99,0xD6}, {0x99,0xD7},
+ {0x99,0xD8}, {0x99,0xD9}, {0x99,0xDA}, {0x99,0xDB},
+ {0x99,0xDC}, {0x99,0xDD}, {0x99,0xDE}, {0x99,0xDF},
+ {0x99,0xE0}, {0x99,0xE1}, {0x99,0xE2}, {0x99,0xE3},
+ {0x99,0xE4}, {0x99,0xE5}, {0x99,0xE6}, {0x99,0xE7},
+ {0x99,0xE8}, {0x99,0xE9}, {0x99,0xEA}, {0x99,0xEB},
+ {0x99,0xEC}, {0x99,0xED}, {0x99,0xEE}, {0x99,0xEF},
+ {0x99,0xF0}, {0x99,0xF1}, {0x99,0xF2}, {0x99,0xF3},
+ {0x99,0xF4}, {0x99,0xF5}, {0x99,0xF6}, {0x99,0xF7},
+ {0x99,0xF8}, {0x99,0xF9}, {0x99,0xFA}, {0x99,0xFB},
+ {0x99,0xFC}, {0x99,0xFD}, {0x99,0xFE}, {0x9A,0x40},
+ {0x9A,0x41}, {0x9A,0x42}, {0x9A,0x43}, {0x9A,0x44},
+ {0x9A,0x45}, {0x9A,0x46}, {0x9A,0x47}, {0x9A,0x48},
+ {0x9A,0x49}, {0x9A,0x4A}, {0x9A,0x4B}, {0x9A,0x4C},
+ {0x9A,0x4D}, {0x9A,0x4E}, {0x9A,0x4F}, {0x9A,0x50},
+ {0x9A,0x51}, {0x9A,0x52}, {0x9A,0x53}, {0x9A,0x54},
+ {0x9A,0x55}, {0x9A,0x56}, {0x9A,0x57}, {0x9A,0x58},
+ {0x9A,0x59}, {0x9A,0x5A}, {0x9A,0x5B}, {0x9A,0x5C},
+ {0x9A,0x5D}, {0x9A,0x5E}, {0x9A,0x5F}, {0x9A,0x60},
+ {0x9A,0x61}, {0x9A,0x62}, {0x9A,0x63}, {0x9A,0x64},
+ {0x9A,0x65}, {0x9A,0x66}, {0x9A,0x67}, {0x9A,0x68},
+ {0x9A,0x69}, {0x9A,0x6A}, {0x9A,0x6B}, {0x9A,0x6C},
+ {0x9A,0x6D}, {0x9A,0x6E}, {0x9A,0x6F}, {0x9A,0x70},
+ {0x9A,0x71}, {0x9A,0x72}, {0x9A,0x73}, {0x9A,0x74},
+ {0x9A,0x75}, {0x9A,0x76}, {0x9A,0x77}, {0x9A,0x78},
+ {0x9A,0x79}, {0x9A,0x7A}, {0x9A,0x7B}, {0x9A,0x7C},
+ {0x9A,0x7D}, {0x9A,0x7E}, {0x9A,0xA1}, {0x9A,0xA2},
+ {0x9A,0xA3}, {0x9A,0xA4}, {0x9A,0xA5}, {0x9A,0xA6},
+ {0x9A,0xA7}, {0x9A,0xA8}, {0x9A,0xA9}, {0x9A,0xAA},
+ {0x9A,0xAB}, {0x9A,0xAC}, {0x9A,0xAD}, {0x9A,0xAE},
+ {0x9A,0xAF}, {0x9A,0xB0}, {0x9A,0xB1}, {0x9A,0xB2},
+ {0x9A,0xB3}, {0x9A,0xB4}, {0x9A,0xB5}, {0x9A,0xB6},
+ {0x9A,0xB7}, {0x9A,0xB8}, {0x9A,0xB9}, {0x9A,0xBA},
+ {0x9A,0xBB}, {0x9A,0xBC}, {0x9A,0xBD}, {0x9A,0xBE},
+ {0x9A,0xBF}, {0x9A,0xC0}, {0x9A,0xC1}, {0x9A,0xC2},
+ {0x9A,0xC3}, {0x9A,0xC4}, {0x9A,0xC5}, {0x9A,0xC6},
+ {0x9A,0xC7}, {0x9A,0xC8}, {0x9A,0xC9}, {0x9A,0xCA},
+ {0x9A,0xCB}, {0x9A,0xCC}, {0x9A,0xCD}, {0x9A,0xCE},
+ {0x9A,0xCF}, {0x9A,0xD0}, {0x9A,0xD1}, {0x9A,0xD2},
+ {0x9A,0xD3}, {0x9A,0xD4}, {0x9A,0xD5}, {0x9A,0xD6},
+ {0x9A,0xD7}, {0x9A,0xD8}, {0x9A,0xD9}, {0x9A,0xDA},
+ {0x9A,0xDB}, {0x9A,0xDC}, {0x9A,0xDD}, {0x9A,0xDE},
+ {0x9A,0xDF}, {0x9A,0xE0}, {0x9A,0xE1}, {0x9A,0xE2},
+ {0x9A,0xE3}, {0x9A,0xE4}, {0x9A,0xE5}, {0x9A,0xE6},
+ {0x9A,0xE7}, {0x9A,0xE8}, {0x9A,0xE9}, {0x9A,0xEA},
+ {0x9A,0xEB}, {0x9A,0xEC}, {0x9A,0xED}, {0x9A,0xEE},
+ {0x9A,0xEF}, {0x9A,0xF0}, {0x9A,0xF1}, {0x9A,0xF2},
+ {0x9A,0xF3}, {0x9A,0xF4}, {0x9A,0xF5}, {0x9A,0xF6},
+ {0x9A,0xF7}, {0x9A,0xF8}, {0x9A,0xF9}, {0x9A,0xFA},
+ {0x9A,0xFB}, {0x9A,0xFC}, {0x9A,0xFD}, {0x9A,0xFE},
+ {0x9B,0x40}, {0x9B,0x41}, {0x9B,0x42}, {0x9B,0x43},
+ {0x9B,0x44}, {0x9B,0x45}, {0x9B,0x46}, {0x9B,0x47},
+ {0x9B,0x48}, {0x9B,0x49}, {0x9B,0x4A}, {0x9B,0x4B},
+ {0x9B,0x4C}, {0x9B,0x4D}, {0x9B,0x4E}, {0x9B,0x4F},
+ {0x9B,0x50}, {0x9B,0x51}, {0x9B,0x52}, {0x9B,0x53},
+ {0x9B,0x54}, {0x9B,0x55}, {0x9B,0x56}, {0x9B,0x57},
+ {0x9B,0x58}, {0x9B,0x59}, {0x9B,0x5A}, {0x9B,0x5B},
+ {0x9B,0x5C}, {0x9B,0x5D}, {0x9B,0x5E}, {0x9B,0x5F},
+ {0x9B,0x60}, {0x9B,0x61}, {0x9B,0x62}, {0x9B,0x63},
+ {0x9B,0x64}, {0x9B,0x65}, {0x9B,0x66}, {0x9B,0x67},
+ {0x9B,0x68}, {0x9B,0x69}, {0x9B,0x6A}, {0x9B,0x6B},
+ {0x9B,0x6C}, {0x9B,0x6D}, {0x9B,0x6E}, {0x9B,0x6F},
+ {0x9B,0x70}, {0x9B,0x71}, {0x9B,0x72}, {0x9B,0x73},
+ {0x9B,0x74}, {0x9B,0x75}, {0xEF,0xF9}, {0x9B,0x77},
+ {0xC5,0xF7}, {0x9B,0x79}, {0x9B,0x7A}, {0xF5,0xE8},
+ {0x9B,0x7C}, {0x9B,0x7D}, {0x9B,0x7E}, {0x9B,0xA1},
+ {0x9B,0xA2}, {0x9B,0xA3}, {0x9B,0xA4}, {0x9B,0xA5},
+ {0x9B,0xA6}, {0x9B,0xA7}, {0x9B,0xA8}, {0x9B,0xA9},
+ {0x9B,0xAA}, {0x9B,0xAB}, {0x9B,0xAC}, {0x9B,0xAD},
+ {0x9B,0xAE}, {0x9B,0xAF}, {0x9B,0xB0}, {0x9B,0xB1},
+ {0x9B,0xB2}, {0x9B,0xB3}, {0x9B,0xB4}, {0x9B,0xB5},
+ {0x9B,0xB6}, {0x9B,0xB7}, {0x9B,0xB8}, {0x9B,0xB9},
+ {0x9B,0xBA}, {0x9B,0xBB}, {0x9B,0xBC}, {0x9B,0xBD},
+ {0x9B,0xBE}, {0x9B,0xBF}, {0x9B,0xC0}, {0x9B,0xC1},
+ {0x9B,0xC2}, {0x9B,0xC3}, {0x9B,0xC4}, {0x9B,0xC5},
+ {0xE8,0xCD}, {0x9B,0xC7}, {0x9B,0xC8}, {0x9B,0xC9},
+ {0x9B,0xCA}, {0x9B,0xCB}, {0x9B,0xCC}, {0x9B,0xCD},
+ {0x9B,0xCE}, {0x9B,0xCF}, {0x9B,0xD0}, {0x9B,0xD1},
+ {0x9B,0xD2}, {0x9B,0xD3}, {0x9B,0xD4}, {0x9B,0xD5},
+ {0x9B,0xD6}, {0x9B,0xD7}, {0x9B,0xD8}, {0x9B,0xD9},
+ {0x9B,0xDA}, {0x9B,0xDB}, {0x9B,0xDC}, {0x9B,0xDD},
+ {0xD0,0xC0}, {0x9B,0xDF}, {0x9B,0xE0}, {0x9B,0xE1},
+ {0x9B,0xE2}, {0x9B,0xE3}, {0x9B,0xE4}, {0x9B,0xE5},
+ {0x9B,0xE6}, {0x9B,0xE7}, {0x9B,0xE8}, {0x9B,0xE9},
+ {0x9B,0xEA}, {0x9B,0xEB}, {0xFD,0x64}, {0x9B,0xED},
+ {0x9B,0xEE}, {0x9B,0xEF}, {0x9B,0xF0}, {0x9B,0xF1},
+ {0x9B,0xF2}, {0x9B,0xF3}, {0x9B,0xF4}, {0x9B,0xF5},
+ {0xBF,0x47}, {0x9B,0xF7}, {0x9B,0xF8}, {0x9B,0xF9},
+ {0x9B,0xFA}, {0x9B,0xFB}, {0x9B,0xFC}, {0x9B,0xFD},
+ {0x9B,0xFE}, {0x9C,0x40}, {0x9C,0x41}, {0xEB,0xC9},
+ {0x9C,0x43}, {0x9C,0x44}, {0x9C,0x45}, {0x9C,0x46},
+ {0x9C,0x47}, {0x9C,0x48}, {0x9C,0x49}, {0x9C,0x4A},
+ {0x9C,0x4B}, {0x9C,0x4C}, {0x9C,0x4D}, {0x9C,0x4E},
+ {0x9C,0x4F}, {0x9C,0x50}, {0x9C,0x51}, {0x9C,0x52},
+ {0xCD,0xE7}, {0x9C,0x54}, {0x9C,0x55}, {0x9C,0x56},
+ {0x9C,0x57}, {0x9C,0x58}, {0x9C,0x59}, {0x9C,0x5A},
+ {0x9C,0x5B}, {0x9C,0x5C}, {0x9C,0x5D}, {0x9C,0x5E},
+ {0x9C,0x5F}, {0x9C,0x60}, {0x9C,0x61}, {0xC0,0xE7},
+ {0x9C,0x63}, {0x9C,0x64}, {0x9C,0x65}, {0x9C,0x66},
+ {0x9C,0x67}, {0xDC,0x52}, {0x9C,0x69}, {0x9C,0x6A},
+ {0xF8,0x6D}, {0x9C,0x6C}, {0x9C,0x6D}, {0x9C,0x6E},
+ {0x9C,0x6F}, {0x9C,0x70}, {0x9C,0x71}, {0x9C,0x72},
+ {0x9C,0x73}, {0x9C,0x74}, {0x9C,0x75}, {0x9C,0x76},
+ {0xDB,0x5D}, {0x9C,0x78}, {0x9C,0x79}, {0x9C,0x7A},
+ {0x9C,0x7B}, {0x9C,0x7C}, {0x9C,0x7D}, {0x9C,0x7E},
+ {0x9C,0xA1}, {0x9C,0xA2}, {0x9C,0xA3}, {0x9C,0xA4},
+ {0x9C,0xA5}, {0x9C,0xA6}, {0x9C,0xA7}, {0x9C,0xA8},
+ {0x9C,0xA9}, {0x9C,0xAA}, {0x9C,0xAB}, {0x9C,0xAC},
+ {0x9C,0xAD}, {0x9C,0xAE}, {0x9C,0xAF}, {0x9C,0xB0},
+ {0x9C,0xB1}, {0x9C,0xB2}, {0x9C,0xB3}, {0x9C,0xB4},
+ {0x9C,0xB5}, {0x9C,0xB6}, {0x9C,0xB7}, {0x9C,0xB8},
+ {0x9C,0xB9}, {0x9C,0xBA}, {0x9C,0xBB}, {0xC9,0x5C},
+ {0xAF,0xB0}, {0x9C,0xBE}, {0x9C,0xBF}, {0x9C,0xC0},
+ {0x9C,0xC1}, {0x9C,0xC2}, {0x9C,0xC3}, {0x9C,0xC4},
+ {0x9C,0xC5}, {0x9C,0xC6}, {0x9C,0xC7}, {0x9C,0xC8},
+ {0x9C,0xC9}, {0x9C,0xCA}, {0x9C,0xCB}, {0x9C,0xCC},
+ {0x9C,0xCD}, {0x9C,0xCE}, {0x9C,0xCF}, {0xD4,0xD1},
+ {0x9C,0xD1}, {0x9C,0xD2}, {0x9C,0xD3}, {0x9C,0xD4},
+ {0x9C,0xD5}, {0x9C,0xD6}, {0x9C,0xD7}, {0x9C,0xD8},
+ {0x9C,0xD9}, {0x9C,0xDA}, {0x9C,0xDB}, {0x9C,0xDC},
+ {0x9C,0xDD}, {0x9C,0xDE}, {0x9C,0xDF}, {0x9C,0xE0},
+ {0x9C,0xE1}, {0x9C,0xE2}, {0x9C,0xE3}, {0x9C,0xE4},
+ {0x9C,0xE5}, {0x9C,0xE6}, {0x9C,0xE7}, {0x9C,0xE8},
+ {0x9C,0xE9}, {0x9C,0xEA}, {0x9C,0xEB}, {0x9C,0xEC},
+ {0x9C,0xED}, {0x9C,0xEE}, {0x9C,0xEF}, {0x9C,0xF0},
+ {0x9C,0xF1}, {0x9C,0xF2}, {0x9C,0xF3}, {0x9C,0xF4},
+ {0x9C,0xF5}, {0x9C,0xF6}, {0x9C,0xF7}, {0x9C,0xF8},
+ {0x9C,0xF9}, {0x9C,0xFA}, {0x9C,0xFB}, {0x9C,0xFC},
+ {0x9C,0xFD}, {0x9C,0xFE}, {0x9D,0x40}, {0x9D,0x41},
+ {0x9D,0x42}, {0x9D,0x43}, {0x9D,0x44}, {0x9D,0x45},
+ {0x9D,0x46}, {0x9D,0x47}, {0x9D,0x48}, {0x9D,0x49},
+ {0x9D,0x4A}, {0x9D,0x4B}, {0x9D,0x4C}, {0x9D,0x4D},
+ {0x9D,0x4E}, {0x9D,0x4F}, {0x9D,0x50}, {0x9D,0x51},
+ {0x9D,0x52}, {0x9D,0x53}, {0x9D,0x54}, {0x9D,0x55},
+ {0x9D,0x56}, {0xE0,0x7C}, {0x9D,0x58}, {0x9D,0x59},
+ {0xB5,0xAE}, {0x9D,0x5B}, {0x9D,0x5C}, {0x9D,0x5D},
+ {0x9D,0x5E}, {0x9D,0x5F}, {0x9D,0x60}, {0x9D,0x61},
+ {0x9D,0x62}, {0x9D,0x63}, {0x9D,0x64}, {0x9D,0x65},
+ {0x9D,0x66}, {0x9D,0x67}, {0x9D,0x68}, {0x9D,0x69},
+ {0x9D,0x6A}, {0x9D,0x6B}, {0x9D,0x6C}, {0x9D,0x6D},
+ {0x9D,0x6E}, {0x9D,0x6F}, {0x9D,0x70}, {0x9D,0x71},
+ {0x9D,0x72}, {0x9D,0x73}, {0x9D,0x74}, {0x9D,0x75},
+ {0x9D,0x76}, {0x9D,0x77}, {0x9D,0x78}, {0x9D,0x79},
+ {0x9D,0x7A}, {0x9D,0x7B}, {0x9D,0x7C}, {0x9D,0x7D},
+ {0x9D,0x7E}, {0x9D,0xA1}, {0x9D,0xA2}, {0x9D,0xA3},
+ {0x9D,0xA4}, {0x9D,0xA5}, {0x9D,0xA6}, {0x9D,0xA7},
+ {0x9D,0xA8}, {0x9D,0xA9}, {0x9D,0xAA}, {0x9D,0xAB},
+ {0x9D,0xAC}, {0x9D,0xAD}, {0x9D,0xAE}, {0x9D,0xAF},
+ {0x9D,0xB0}, {0x9D,0xB1}, {0x9D,0xB2}, {0x9D,0xB3},
+ {0x9D,0xB4}, {0x9D,0xB5}, {0x9D,0xB6}, {0x9D,0xB7},
+ {0x9D,0xB8}, {0x9D,0xB9}, {0x9D,0xBA}, {0x9D,0xBB},
+ {0x9D,0xBC}, {0x9D,0xBD}, {0x9D,0xBE}, {0x9D,0xBF},
+ {0x9D,0xC0}, {0x9D,0xC1}, {0x9D,0xC2}, {0x9D,0xC3},
+ {0xA9,0xE4}, {0x9D,0xC5}, {0x9D,0xC6}, {0x9D,0xC7},
+ {0x9D,0xC8}, {0x9D,0xC9}, {0x9D,0xCA}, {0x9D,0xCB},
+ {0x9D,0xCC}, {0x9D,0xCD}, {0x9D,0xCE}, {0x9D,0xCF},
+ {0x9D,0xD0}, {0x9D,0xD1}, {0x9D,0xD2}, {0x9D,0xD3},
+ {0x9D,0xD4}, {0x9D,0xD5}, {0x9D,0xD6}, {0x9D,0xD7},
+ {0x9D,0xD8}, {0x9D,0xD9}, {0x9D,0xDA}, {0x9D,0xDB},
+ {0x9D,0xDC}, {0x9D,0xDD}, {0x9D,0xDE}, {0x9D,0xDF},
+ {0x9D,0xE0}, {0x9D,0xE1}, {0x9D,0xE2}, {0x9D,0xE3},
+ {0x9D,0xE4}, {0x9D,0xE5}, {0x9D,0xE6}, {0x9D,0xE7},
+ {0x9D,0xE8}, {0x9D,0xE9}, {0x9D,0xEA}, {0x9D,0xEB},
+ {0x9D,0xEC}, {0x9D,0xED}, {0x9D,0xEE}, {0x9D,0xEF},
+ {0x9D,0xF0}, {0x9D,0xF1}, {0x9D,0xF2}, {0x9D,0xF3},
+ {0x9D,0xF4}, {0x9D,0xF5}, {0x9D,0xF6}, {0x9D,0xF7},
+ {0x9D,0xF8}, {0x9D,0xF9}, {0x9D,0xFA}, {0x9D,0xFB},
+ {0x9D,0xFC}, {0x9D,0xFD}, {0x9D,0xFE}, {0x9E,0x40},
+ {0x9E,0x41}, {0x9E,0x42}, {0x9E,0x43}, {0x9E,0x44},
+ {0x9E,0x45}, {0x9E,0x46}, {0x9E,0x47}, {0x9E,0x48},
+ {0x9E,0x49}, {0x9E,0x4A}, {0x9E,0x4B}, {0x9E,0x4C},
+ {0x9E,0x4D}, {0x9E,0x4E}, {0x9E,0x4F}, {0x9E,0x50},
+ {0x9E,0x51}, {0x9E,0x52}, {0x9E,0x53}, {0x9E,0x54},
+ {0x9E,0x55}, {0x9E,0x56}, {0x9E,0x57}, {0x9E,0x58},
+ {0x9E,0x59}, {0x9E,0x5A}, {0x9E,0x5B}, {0x9E,0x5C},
+ {0x9E,0x5D}, {0x9E,0x5E}, {0x9E,0x5F}, {0x9E,0x60},
+ {0x9E,0x61}, {0x9E,0x62}, {0x9E,0x63}, {0x9E,0x64},
+ {0x9E,0x65}, {0x9E,0x66}, {0x9E,0x67}, {0x9E,0x68},
+ {0x9E,0x69}, {0x9E,0x6A}, {0x9E,0x6B}, {0x9E,0x6C},
+ {0x9E,0x6D}, {0x9E,0x6E}, {0x9E,0x6F}, {0x9E,0x70},
+ {0x9E,0x71}, {0x9E,0x72}, {0x9E,0x73}, {0x9E,0x74},
+ {0x9E,0x75}, {0x9E,0x76}, {0x9E,0x77}, {0x9E,0x78},
+ {0x9E,0x79}, {0x9E,0x7A}, {0x9E,0x7B}, {0x9E,0x7C},
+ {0x9E,0x7D}, {0x9E,0x7E}, {0x9E,0xA1}, {0x9E,0xA2},
+ {0x9E,0xA3}, {0x9E,0xA4}, {0x9E,0xA5}, {0x9E,0xA6},
+ {0x9E,0xA7}, {0x9E,0xA8}, {0xAB,0xEC}, {0x9E,0xAA},
+ {0x9E,0xAB}, {0x9E,0xAC}, {0x9E,0xAD}, {0x9E,0xAE},
+ {0x9E,0xAF}, {0x9E,0xB0}, {0x9E,0xB1}, {0x9E,0xB2},
+ {0x9E,0xB3}, {0x9E,0xB4}, {0x9E,0xB5}, {0x9E,0xB6},
+ {0x9E,0xB7}, {0x9E,0xB8}, {0x9E,0xB9}, {0x9E,0xBA},
+ {0x9E,0xBB}, {0x9E,0xBC}, {0x9E,0xBD}, {0x9E,0xBE},
+ {0x9E,0xBF}, {0x9E,0xC0}, {0x9E,0xC1}, {0x9E,0xC2},
+ {0x9E,0xC3}, {0x9E,0xC4}, {0x9E,0xC5}, {0x9E,0xC6},
+ {0x9E,0xC7}, {0x9E,0xC8}, {0x9E,0xC9}, {0x9E,0xCA},
+ {0x9E,0xCB}, {0x9E,0xCC}, {0x9E,0xCD}, {0x9E,0xCE},
+ {0x9E,0xCF}, {0x9E,0xD0}, {0x9E,0xD1}, {0x9E,0xD2},
+ {0x9E,0xD3}, {0x9E,0xD4}, {0x9E,0xD5}, {0x9E,0xD6},
+ {0x9E,0xD7}, {0x9E,0xD8}, {0x9E,0xD9}, {0x9E,0xDA},
+ {0x9E,0xDB}, {0x9E,0xDC}, {0x9E,0xDD}, {0x9E,0xDE},
+ {0x9E,0xDF}, {0x9E,0xE0}, {0x9E,0xE1}, {0x9E,0xE2},
+ {0x9E,0xE3}, {0x9E,0xE4}, {0x9E,0xE5}, {0x9E,0xE6},
+ {0x9E,0xE7}, {0x9E,0xE8}, {0x9E,0xE9}, {0x9E,0xEA},
+ {0x9E,0xEB}, {0x9E,0xEC}, {0x9E,0xED}, {0x9E,0xEE},
+ {0xDE,0xCD}, {0x9E,0xF0}, {0x9E,0xF1}, {0x9E,0xF2},
+ {0x9E,0xF3}, {0x9E,0xF4}, {0x9E,0xF5}, {0x9E,0xF6},
+ {0x9E,0xF7}, {0x9E,0xF8}, {0x9E,0xF9}, {0x9E,0xFA},
+ {0x9E,0xFB}, {0x9E,0xFC}, {0xC9,0xFC}, {0x9E,0xFE},
+ {0x9F,0x40}, {0x9F,0x41}, {0x9F,0x42}, {0x9F,0x43},
+ {0x9F,0x44}, {0x9F,0x45}, {0x9F,0x46}, {0x9F,0x47},
+ {0x9F,0x48}, {0x9F,0x49}, {0x9F,0x4A}, {0x9F,0x4B},
+ {0x9F,0x4C}, {0x9F,0x4D}, {0x9F,0x4E}, {0x9F,0x4F},
+ {0x9F,0x50}, {0x9F,0x51}, {0x9F,0x52}, {0x9F,0x53},
+ {0x9F,0x54}, {0x9F,0x55}, {0x9F,0x56}, {0x9F,0x57},
+ {0x9F,0x58}, {0x9F,0x59}, {0x9F,0x5A}, {0x9F,0x5B},
+ {0x9F,0x5C}, {0x9F,0x5D}, {0x9F,0x5E}, {0x9F,0x5F},
+ {0xF9,0xC4}, {0x9F,0x61}, {0x9F,0x62}, {0x9F,0x63},
+ {0x9F,0x64}, {0x9F,0x65}, {0x91,0xBE}, {0x9F,0x67},
+ {0x9F,0x68}, {0x9F,0x69}, {0x9F,0x6A}, {0x9F,0x6B},
+ {0x9F,0x6C}, {0x9F,0x6D}, {0x9F,0x6E}, {0x9F,0x6F},
+ {0x9F,0x70}, {0x9F,0x71}, {0x9F,0x72}, {0x9F,0x73},
+ {0x9F,0x74}, {0x9F,0x75}, {0x9F,0x76}, {0x9F,0x77},
+ {0x9F,0x78}, {0x9F,0x79}, {0x9F,0x7A}, {0x9F,0x7B},
+ {0x9F,0x7C}, {0x9F,0x7D}, {0x9F,0x7E}, {0x9F,0xA1},
+ {0x9F,0xA2}, {0x9F,0xA3}, {0x9F,0xA4}, {0x9F,0xA5},
+ {0x9F,0xA6}, {0x9F,0xA7}, {0x9F,0xA8}, {0x9F,0xA9},
+ {0x9F,0xAA}, {0x9F,0xAB}, {0x9F,0xAC}, {0x9F,0xAD},
+ {0x9F,0xAE}, {0x9F,0xAF}, {0x9F,0xB0}, {0x9F,0xB1},
+ {0x9F,0xB2}, {0x9F,0xB3}, {0x9F,0xB4}, {0x9F,0xB5},
+ {0x9F,0xB6}, {0x9F,0xB7}, {0x9F,0xB8}, {0x9F,0xB9},
+ {0x9F,0xBA}, {0x9F,0xBB}, {0x9F,0xBC}, {0x9F,0xBD},
+ {0x9F,0xBE}, {0x9F,0xBF}, {0x9F,0xC0}, {0x9F,0xC1},
+ {0x9F,0xC2}, {0x9F,0xC3}, {0x9F,0xC4}, {0x9F,0xC5},
+ {0x9F,0xC6}, {0x9F,0xC7}, {0x9F,0xC8}, {0x9F,0xC9},
+ {0x9F,0xCA}, {0xB9,0xB0}, {0x9F,0xCC}, {0x9F,0xCD},
+ {0x9F,0xCE}, {0x9F,0xCF}, {0x9F,0xD0}, {0x9F,0xD1},
+ {0x9F,0xD2}, {0x9F,0xD3}, {0x9F,0xD4}, {0x9F,0xD5},
+ {0x9F,0xD6}, {0x9F,0xD7}, {0x93,0x61}, {0x9F,0xD9},
+ {0x9F,0xDA}, {0x9F,0xDB}, {0x9F,0xDC}, {0x9F,0xDD},
+ {0x9F,0xDE}, {0x9F,0xDF}, {0x9F,0xE0}, {0x9F,0xE1},
+ {0x9F,0xE2}, {0x9F,0xE3}, {0x9F,0xE4}, {0x9F,0xE5},
+ {0x9F,0xE6}, {0x9F,0xE7}, {0x9F,0xE8}, {0x9F,0xE9},
+ {0x9F,0xEA}, {0x9F,0xEB}, {0x9F,0xEC}, {0x9F,0xED},
+ {0x9F,0xEE}, {0x9F,0xEF}, {0x9F,0xF0}, {0x9F,0xF1},
+ {0x9F,0xF2}, {0x9F,0xF3}, {0x9F,0xF4}, {0x9F,0xF5},
+ {0x9F,0xF6}, {0x9F,0xF7}, {0x9F,0xF8}, {0x9F,0xF9},
+ {0x9F,0xFA}, {0x9F,0xFB}, {0x9F,0xFC}, {0x9F,0xFD},
+ {0x9F,0xFE}, {0xA0,0x40}, {0xA0,0x41}, {0xA0,0x42},
+ {0xA0,0x43}, {0xA0,0x44}, {0xA0,0x45}, {0xA0,0x46},
+ {0xA0,0x47}, {0xA0,0x48}, {0xA0,0x49}, {0xA0,0x4A},
+ {0xA0,0x4B}, {0xA0,0x4C}, {0xA0,0x4D}, {0xA0,0x4E},
+ {0xA0,0x4F}, {0xA0,0x50}, {0xA0,0x51}, {0xA0,0x52},
+ {0xA0,0x53}, {0xA0,0x54}, {0xA0,0x55}, {0xA0,0x56},
+ {0xA0,0x57}, {0xA0,0x58}, {0xA0,0x59}, {0xA0,0x5A},
+ {0xA0,0x5B}, {0xA0,0x5C}, {0xA0,0x5D}, {0xA0,0x5E},
+ {0xA0,0x5F}, {0xA0,0x60}, {0xA0,0x61}, {0xA0,0x62},
+ {0x8F,0xB6}, {0xA0,0x64}, {0xA0,0x65}, {0xA0,0x66},
+ {0xA0,0x67}, {0xA0,0x68}, {0xA0,0x69}, {0xA0,0x6A},
+ {0xA0,0x6B}, {0xA0,0x6C}, {0xA0,0x6D}, {0xA0,0x6E},
+ {0xA0,0x6F}, {0xA0,0x70}, {0xA0,0x71}, {0xA0,0x72},
+ {0xA0,0x73}, {0xA0,0x74}, {0xA0,0x75}, {0xA0,0x76},
+ {0xA9,0xF0}, {0xA0,0x78}, {0xA0,0x79}, {0xA0,0x7A},
+ {0xA0,0x7B}, {0xA0,0x7C}, {0xA0,0x7D}, {0xA0,0x7E},
+ {0xA0,0xA1}, {0xA0,0xA2}, {0xA0,0xA3}, {0xA0,0xA4},
+ {0xA0,0xA5}, {0xA0,0xA6}, {0xA0,0xA7}, {0xA0,0xA8},
+ {0xA0,0xA9}, {0xA0,0xAA}, {0xA0,0xAB}, {0xA0,0xAC},
+ {0xA0,0xAD}, {0xA0,0xAE}, {0xA0,0xAF}, {0xA0,0xB0},
+ {0xA0,0xB1}, {0xA0,0xB2}, {0xA0,0xB3}, {0xA0,0xB4},
+ {0xA0,0xB5}, {0xA0,0xB6}, {0xA0,0xB7}, {0xA0,0xB8},
+ {0xA0,0xB9}, {0xA0,0xBA}, {0xA0,0xBB}, {0xA0,0xBC},
+ {0xA0,0xBD}, {0xA0,0xBE}, {0xA0,0xBF}, {0xA0,0xC0},
+ {0xA0,0xC1}, {0xA0,0xC2}, {0xA0,0xC3}, {0xA0,0xC4},
+ {0xA0,0xC5}, {0xA0,0xC6}, {0xA0,0xC7}, {0xA0,0xC8},
+ {0xA0,0xC9}, {0xA0,0xCA}, {0xA0,0xCB}, {0xA0,0xCC},
+ {0xA0,0xCD}, {0xA0,0xCE}, {0xA0,0xCF}, {0xA0,0xD0},
+ {0xA0,0xD1}, {0xA0,0xD2}, {0xA0,0xD3}, {0xA0,0xD4},
+ {0x94,0x7A}, {0xA0,0xD6}, {0xA0,0xD7}, {0xA0,0xD8},
+ {0xA0,0xD9}, {0xA0,0xDA}, {0xA0,0xDB}, {0xA0,0xDC},
+ {0xA0,0xDD}, {0xA0,0xDE}, {0xDE,0x72}, {0xA0,0xE0},
+ {0xA0,0xE1}, {0xA0,0xE2}, {0xA0,0xE3}, {0x94,0x55},
+ {0xA0,0xE5}, {0xA0,0xE6}, {0xA0,0xE7}, {0xA0,0xE8},
+ {0xA0,0xE9}, {0xA0,0xEA}, {0xA0,0xEB}, {0xA0,0xEC},
+ {0xA0,0xED}, {0xA0,0xEE}, {0xA0,0xEF}, {0xA0,0xF0},
+ {0xA0,0xF1}, {0xA0,0xF2}, {0xA0,0xF3}, {0xA0,0xF4},
+ {0xA0,0xF5}, {0xA0,0xF6}, {0xA0,0xF7}, {0xA0,0xF8},
+ {0xA0,0xF9}, {0xA0,0xFA}, {0xA0,0xFB}, {0xA0,0xFC},
+ {0xA0,0xFD}, {0xA0,0xFE}, {0x81,0x40}, {0x81,0x41},
+ {0x81,0x42}, {0x81,0x43}, {0x81,0x44}, {0x81,0x45},
+ {0x81,0x46}, {0x81,0x47}, {0x81,0x48}, {0x81,0x49},
+ {0x81,0x4A}, {0x81,0x4B}, {0x81,0x4C}, {0x81,0x4D},
+ {0x81,0x4E}, {0x81,0x4F}, {0x81,0x50}, {0x81,0x51},
+ {0x81,0x52}, {0x81,0x53}, {0x81,0x54}, {0x81,0x55},
+ {0x81,0x56}, {0x81,0x57}, {0x81,0x58}, {0x81,0x59},
+ {0x81,0x5A}, {0x81,0x5B}, {0x81,0x5C}, {0x81,0x5D},
+ {0x81,0x5E}, {0x81,0x5F}, {0x81,0x60}, {0x81,0x61},
+ {0x81,0x62}, {0x81,0x63}, {0x81,0x64}, {0x81,0x65},
+ {0x81,0x66}, {0x81,0x67}, {0x81,0x68}, {0x81,0x69},
+ {0x81,0x6A}, {0x81,0x6B}, {0x81,0x6C}, {0x81,0x6D},
+ {0x81,0x6E}, {0x81,0x6F}, {0x81,0x70}, {0x81,0x71},
+ {0x81,0x72}, {0x81,0x73}, {0x81,0x74}, {0x81,0x75},
+ {0x81,0x76}, {0x81,0x77}, {0x81,0x78}, {0x81,0x79},
+ {0x81,0x7A}, {0x81,0x7B}, {0x81,0x7C}, {0x81,0x7D},
+ {0x81,0x7E}, {0x81,0xA1}, {0x81,0xA2}, {0x81,0xA3},
+ {0x81,0xA4}, {0x81,0xA5}, {0x81,0xA6}, {0x81,0xA7},
+ {0x81,0xA8}, {0x81,0xA9}, {0x81,0xAA}, {0x81,0xAB},
+ {0x81,0xAC}, {0x81,0xAD}, {0x81,0xAE}, {0x81,0xAF},
+ {0x81,0xB0}, {0x81,0xB1}, {0x81,0xB2}, {0x81,0xB3},
+ {0x81,0xB4}, {0x81,0xB5}, {0x81,0xB6}, {0x81,0xB7},
+ {0x81,0xB8}, {0x81,0xB9}, {0x81,0xBA}, {0x81,0xBB},
+ {0x81,0xBC}, {0x81,0xBD}, {0x81,0xBE}, {0x81,0xBF},
+ {0x81,0xC0}, {0x81,0xC1}, {0x81,0xC2}, {0x81,0xC3},
+ {0x81,0xC4}, {0x81,0xC5}, {0x81,0xC6}, {0x81,0xC7},
+ {0x81,0xC8}, {0x81,0xC9}, {0x81,0xCA}, {0x81,0xCB},
+ {0x81,0xCC}, {0x81,0xCD}, {0x81,0xCE}, {0x81,0xCF},
+ {0x81,0xD0}, {0x81,0xD1}, {0x81,0xD2}, {0x81,0xD3},
+ {0x81,0xD4}, {0x81,0xD5}, {0x81,0xD6}, {0x81,0xD7},
+ {0x81,0xD8}, {0x81,0xD9}, {0x81,0xDA}, {0x81,0xDB},
+ {0x81,0xDC}, {0x81,0xDD}, {0x81,0xDE}, {0x81,0xDF},
+ {0x81,0xE0}, {0x81,0xE1}, {0x81,0xE2}, {0x81,0xE3},
+ {0x81,0xE4}, {0x81,0xE5}, {0x81,0xE6}, {0x81,0xE7},
+ {0x81,0xE8}, {0x81,0xE9}, {0x81,0xEA}, {0x81,0xEB},
+ {0x81,0xEC}, {0x81,0xED}, {0x81,0xEE}, {0x81,0xEF},
+ {0x81,0xF0}, {0x81,0xF1}, {0x81,0xF2}, {0x81,0xF3},
+ {0x81,0xF4}, {0x81,0xF5}, {0x81,0xF6}, {0x81,0xF7},
+ {0x81,0xF8}, {0x81,0xF9}, {0x81,0xFA}, {0x81,0xFB},
+ {0x81,0xFC}, {0x81,0xFD}, {0x81,0xFE}, {0x82,0x40},
+ {0x82,0x41}, {0x82,0x42}, {0x82,0x43}, {0x82,0x44},
+ {0x82,0x45}, {0x82,0x46}, {0x82,0x47}, {0x82,0x48},
+ {0x82,0x49}, {0x82,0x4A}, {0x82,0x4B}, {0x82,0x4C},
+ {0x82,0x4D}, {0x82,0x4E}, {0x82,0x4F}, {0x82,0x50},
+ {0x82,0x51}, {0x82,0x52}, {0x82,0x53}, {0x82,0x54},
+ {0x82,0x55}, {0x82,0x56}, {0x82,0x57}, {0x82,0x58},
+ {0x82,0x59}, {0x82,0x5A}, {0x82,0x5B}, {0x82,0x5C},
+ {0x82,0x5D}, {0x82,0x5E}, {0x82,0x5F}, {0x82,0x60},
+ {0x82,0x61}, {0x82,0x62}, {0x82,0x63}, {0x82,0x64},
+ {0x82,0x65}, {0x82,0x66}, {0x82,0x67}, {0x82,0x68},
+ {0x82,0x69}, {0x82,0x6A}, {0x82,0x6B}, {0x82,0x6C},
+ {0x82,0x6D}, {0x82,0x6E}, {0x82,0x6F}, {0x82,0x70},
+ {0x82,0x71}, {0x82,0x72}, {0x82,0x73}, {0x82,0x74},
+ {0x82,0x75}, {0x82,0x76}, {0x82,0x77}, {0x82,0x78},
+ {0x82,0x79}, {0x82,0x7A}, {0x82,0x7B}, {0x82,0x7C},
+ {0x82,0x7D}, {0x82,0x7E}, {0x82,0xA1}, {0x82,0xA2},
+ {0x82,0xA3}, {0x82,0xA4}, {0x82,0xA5}, {0x82,0xA6},
+ {0x82,0xA7}, {0x82,0xA8}, {0x82,0xA9}, {0x82,0xAA},
+ {0x82,0xAB}, {0x82,0xAC}, {0x82,0xAD}, {0x82,0xAE},
+ {0x82,0xAF}, {0x82,0xB0}, {0x82,0xB1}, {0x82,0xB2},
+ {0x82,0xB3}, {0x82,0xB4}, {0x82,0xB5}, {0x82,0xB6},
+ {0x82,0xB7}, {0x82,0xB8}, {0x82,0xB9}, {0x82,0xBA},
+ {0x82,0xBB}, {0x82,0xBC}, {0x82,0xBD}, {0x82,0xBE},
+ {0x82,0xBF}, {0x82,0xC0}, {0x82,0xC1}, {0x82,0xC2},
+ {0x82,0xC3}, {0x82,0xC4}, {0x82,0xC5}, {0x82,0xC6},
+ {0x82,0xC7}, {0x82,0xC8}, {0x82,0xC9}, {0x82,0xCA},
+ {0x82,0xCB}, {0x82,0xCC}, {0x82,0xCD}, {0x82,0xCE},
+ {0x82,0xCF}, {0x82,0xD0}, {0x82,0xD1}, {0x82,0xD2},
+ {0x82,0xD3}, {0x82,0xD4}, {0x82,0xD5}, {0x82,0xD6},
+ {0x82,0xD7}, {0x82,0xD8}, {0x82,0xD9}, {0x82,0xDA},
+ {0x82,0xDB}, {0x82,0xDC}, {0x82,0xDD}, {0x82,0xDE},
+ {0x82,0xDF}, {0x82,0xE0}, {0x82,0xE1}, {0x82,0xE2},
+ {0x82,0xE3}, {0x82,0xE4}, {0x82,0xE5}, {0x82,0xE6},
+ {0x82,0xE7}, {0x82,0xE8}, {0x82,0xE9}, {0x82,0xEA},
+ {0x82,0xEB}, {0x82,0xEC}, {0x82,0xED}, {0x82,0xEE},
+ {0x82,0xEF}, {0x82,0xF0}, {0x82,0xF1}, {0x82,0xF2},
+ {0x82,0xF3}, {0x82,0xF4}, {0x82,0xF5}, {0x82,0xF6},
+ {0x82,0xF7}, {0x82,0xF8}, {0x82,0xF9}, {0x82,0xFA},
+ {0x82,0xFB}, {0x82,0xFC}, {0x82,0xFD}, {0x82,0xFE},
+ {0x83,0x40}, {0x83,0x41}, {0x83,0x42}, {0x83,0x43},
+ {0x83,0x44}, {0x83,0x45}, {0x83,0x46}, {0x83,0x47},
+ {0x83,0x48}, {0x83,0x49}, {0x83,0x4A}, {0x83,0x4B},
+ {0x83,0x4C}, {0x83,0x4D}, {0x83,0x4E}, {0x83,0x4F},
+ {0x83,0x50}, {0x83,0x51}, {0x83,0x52}, {0x83,0x53},
+ {0x83,0x54}, {0x83,0x55}, {0x83,0x56}, {0x83,0x57},
+ {0x83,0x58}, {0x83,0x59}, {0x83,0x5A}, {0x83,0x5B},
+ {0x83,0x5C}, {0x83,0x5D}, {0x83,0x5E}, {0x83,0x5F},
+ {0x83,0x60}, {0x83,0x61}, {0x83,0x62}, {0x83,0x63},
+ {0x83,0x64}, {0x83,0x65}, {0x83,0x66}, {0x83,0x67},
+ {0x83,0x68}, {0x83,0x69}, {0x83,0x6A}, {0x83,0x6B},
+ {0x83,0x6C}, {0x83,0x6D}, {0x83,0x6E}, {0x83,0x6F},
+ {0x83,0x70}, {0x83,0x71}, {0x83,0x72}, {0x83,0x73},
+ {0x83,0x74}, {0x83,0x75}, {0x83,0x76}, {0x83,0x77},
+ {0x83,0x78}, {0x83,0x79}, {0x83,0x7A}, {0x83,0x7B},
+ {0x83,0x7C}, {0x83,0x7D}, {0x83,0x7E}, {0x83,0xA1},
+ {0x83,0xA2}, {0x83,0xA3}, {0x83,0xA4}, {0x83,0xA5},
+ {0x83,0xA6}, {0x83,0xA7}, {0x83,0xA8}, {0x83,0xA9},
+ {0x83,0xAA}, {0x83,0xAB}, {0x83,0xAC}, {0x83,0xAD},
+ {0x83,0xAE}, {0x83,0xAF}, {0x83,0xB0}, {0x83,0xB1},
+ {0x83,0xB2}, {0x83,0xB3}, {0x83,0xB4}, {0x83,0xB5},
+ {0x83,0xB6}, {0x83,0xB7}, {0x83,0xB8}, {0x83,0xB9},
+ {0x83,0xBA}, {0x83,0xBB}, {0x83,0xBC}, {0x83,0xBD},
+ {0x83,0xBE}, {0x83,0xBF}, {0x83,0xC0}, {0x83,0xC1},
+ {0x83,0xC2}, {0x83,0xC3}, {0x83,0xC4}, {0x83,0xC5},
+ {0x83,0xC6}, {0x83,0xC7}, {0x83,0xC8}, {0x83,0xC9},
+ {0x83,0xCA}, {0x83,0xCB}, {0x83,0xCC}, {0x83,0xCD},
+ {0x83,0xCE}, {0x83,0xCF}, {0x83,0xD0}, {0x83,0xD1},
+ {0x83,0xD2}, {0x83,0xD3}, {0x83,0xD4}, {0x83,0xD5},
+ {0x83,0xD6}, {0x83,0xD7}, {0x83,0xD8}, {0x83,0xD9},
+ {0x83,0xDA}, {0x83,0xDB}, {0x83,0xDC}, {0x83,0xDD},
+ {0x83,0xDE}, {0x83,0xDF}, {0x83,0xE0}, {0x83,0xE1},
+ {0x83,0xE2}, {0x83,0xE3}, {0x83,0xE4}, {0x83,0xE5},
+ {0x83,0xE6}, {0x83,0xE7}, {0x83,0xE8}, {0x83,0xE9},
+ {0x83,0xEA}, {0x83,0xEB}, {0x83,0xEC}, {0x83,0xED},
+ {0x83,0xEE}, {0x83,0xEF}, {0x83,0xF0}, {0x83,0xF1},
+ {0x83,0xF2}, {0x83,0xF3}, {0x83,0xF4}, {0x83,0xF5},
+ {0x83,0xF6}, {0x83,0xF7}, {0x83,0xF8}, {0x83,0xF9},
+ {0x83,0xFA}, {0x83,0xFB}, {0x83,0xFC}, {0x83,0xFD},
+ {0x83,0xFE}, {0x84,0x40}, {0x84,0x41}, {0x84,0x42},
+ {0x84,0x43}, {0x84,0x44}, {0x84,0x45}, {0x84,0x46},
+ {0x84,0x47}, {0x84,0x48}, {0x84,0x49}, {0x84,0x4A},
+ {0x84,0x4B}, {0x84,0x4C}, {0x84,0x4D}, {0x84,0x4E},
+ {0x84,0x4F}, {0x84,0x50}, {0x84,0x51}, {0x84,0x52},
+ {0x84,0x53}, {0x84,0x54}, {0x84,0x55}, {0x84,0x56},
+ {0x84,0x57}, {0x84,0x58}, {0x84,0x59}, {0x84,0x5A},
+ {0x84,0x5B}, {0x84,0x5C}, {0x84,0x5D}, {0x84,0x5E},
+ {0x84,0x5F}, {0x84,0x60}, {0x84,0x61}, {0x84,0x62},
+ {0x84,0x63}, {0x84,0x64}, {0x84,0x65}, {0x84,0x66},
+ {0x84,0x67}, {0x84,0x68}, {0x84,0x69}, {0x84,0x6A},
+ {0x84,0x6B}, {0x84,0x6C}, {0x84,0x6D}, {0x84,0x6E},
+ {0x84,0x6F}, {0x84,0x70}, {0x84,0x71}, {0x84,0x72},
+ {0x84,0x73}, {0x84,0x74}, {0x84,0x75}, {0x84,0x76},
+ {0x84,0x77}, {0x84,0x78}, {0x84,0x79}, {0x84,0x7A},
+ {0x84,0x7B}, {0x84,0x7C}, {0x84,0x7D}, {0x84,0x7E},
+ {0x84,0xA1}, {0x84,0xA2}, {0x84,0xA3}, {0x84,0xA4},
+ {0x84,0xA5}, {0x84,0xA6}, {0x84,0xA7}, {0x84,0xA8},
+ {0x84,0xA9}, {0x84,0xAA}, {0x84,0xAB}, {0x84,0xAC},
+ {0x84,0xAD}, {0x84,0xAE}, {0x84,0xAF}, {0x84,0xB0},
+ {0x84,0xB1}, {0x84,0xB2}, {0x84,0xB3}, {0x84,0xB4},
+ {0x84,0xB5}, {0x84,0xB6}, {0x84,0xB7}, {0x84,0xB8},
+ {0x84,0xB9}, {0x84,0xBA}, {0x84,0xBB}, {0x84,0xBC},
+ {0x84,0xBD}, {0x84,0xBE}, {0x84,0xBF}, {0x84,0xC0},
+ {0x84,0xC1}, {0x84,0xC2}, {0x84,0xC3}, {0x84,0xC4},
+ {0x84,0xC5}, {0x84,0xC6}, {0x84,0xC7}, {0x84,0xC8},
+ {0x84,0xC9}, {0x84,0xCA}, {0x84,0xCB}, {0x84,0xCC},
+ {0x84,0xCD}, {0x84,0xCE}, {0x84,0xCF}, {0x84,0xD0},
+ {0x84,0xD1}, {0x84,0xD2}, {0x84,0xD3}, {0x84,0xD4},
+ {0x84,0xD5}, {0x84,0xD6}, {0x84,0xD7}, {0x84,0xD8},
+ {0x84,0xD9}, {0x84,0xDA}, {0x84,0xDB}, {0x84,0xDC},
+ {0x84,0xDD}, {0x84,0xDE}, {0x84,0xDF}, {0x84,0xE0},
+ {0x84,0xE1}, {0x84,0xE2}, {0x84,0xE3}, {0x84,0xE4},
+ {0x84,0xE5}, {0x84,0xE6}, {0x84,0xE7}, {0x84,0xE8},
+ {0x84,0xE9}, {0x84,0xEA}, {0x84,0xEB}, {0x84,0xEC},
+ {0x84,0xED}, {0x84,0xEE}, {0x84,0xEF}, {0x84,0xF0},
+ {0x84,0xF1}, {0x84,0xF2}, {0x84,0xF3}, {0x84,0xF4},
+ {0x84,0xF5}, {0x84,0xF6}, {0x84,0xF7}, {0x84,0xF8},
+ {0x84,0xF9}, {0x84,0xFA}, {0x84,0xFB}, {0x84,0xFC},
+ {0x84,0xFD}, {0x84,0xFE}, {0x85,0x40}, {0x85,0x41},
+ {0x85,0x42}, {0x85,0x43}, {0x85,0x44}, {0x85,0x45},
+ {0x85,0x46}, {0x85,0x47}, {0x85,0x48}, {0x85,0x49},
+ {0x85,0x4A}, {0x85,0x4B}, {0x85,0x4C}, {0x85,0x4D},
+ {0x85,0x4E}, {0x85,0x4F}, {0x85,0x50}, {0x85,0x51},
+ {0x85,0x52}, {0x85,0x53}, {0x85,0x54}, {0x85,0x55},
+ {0x85,0x56}, {0x85,0x57}, {0x85,0x58}, {0x85,0x59},
+ {0x85,0x5A}, {0x85,0x5B}, {0x85,0x5C}, {0x85,0x5D},
+ {0x85,0x5E}, {0x85,0x5F}, {0x85,0x60}, {0x85,0x61},
+ {0x85,0x62}, {0x85,0x63}, {0x85,0x64}, {0x85,0x65},
+ {0x85,0x66}, {0x85,0x67}, {0x85,0x68}, {0x85,0x69},
+ {0x85,0x6A}, {0x85,0x6B}, {0x85,0x6C}, {0x85,0x6D},
+ {0x85,0x6E}, {0x85,0x6F}, {0x85,0x70}, {0x85,0x71},
+ {0x85,0x72}, {0x85,0x73}, {0x85,0x74}, {0x85,0x75},
+ {0x85,0x76}, {0x85,0x77}, {0x85,0x78}, {0x85,0x79},
+ {0x85,0x7A}, {0x85,0x7B}, {0x85,0x7C}, {0x85,0x7D},
+ {0x85,0x7E}, {0x85,0xA1}, {0x85,0xA2}, {0x85,0xA3},
+ {0x85,0xA4}, {0x85,0xA5}, {0x85,0xA6}, {0x85,0xA7},
+ {0x85,0xA8}, {0x85,0xA9}, {0x85,0xAA}, {0x85,0xAB},
+ {0x85,0xAC}, {0x85,0xAD}, {0x85,0xAE}, {0x85,0xAF},
+ {0x85,0xB0}, {0x85,0xB1}, {0x85,0xB2}, {0x85,0xB3},
+ {0x85,0xB4}, {0x85,0xB5}, {0x85,0xB6}, {0x85,0xB7},
+ {0x85,0xB8}, {0x85,0xB9}, {0x85,0xBA}, {0x85,0xBB},
+ {0x85,0xBC}, {0x85,0xBD}, {0x85,0xBE}, {0x85,0xBF},
+ {0x85,0xC0}, {0x85,0xC1}, {0x85,0xC2}, {0x85,0xC3},
+ {0x85,0xC4}, {0x85,0xC5}, {0x85,0xC6}, {0x85,0xC7},
+ {0x85,0xC8}, {0x85,0xC9}, {0x85,0xCA}, {0x85,0xCB},
+ {0x85,0xCC}, {0x85,0xCD}, {0x85,0xCE}, {0x85,0xCF},
+ {0x85,0xD0}, {0x85,0xD1}, {0x85,0xD2}, {0x85,0xD3},
+ {0x85,0xD4}, {0x85,0xD5}, {0x85,0xD6}, {0x85,0xD7},
+ {0x85,0xD8}, {0x85,0xD9}, {0x85,0xDA}, {0x85,0xDB},
+ {0x85,0xDC}, {0x85,0xDD}, {0x85,0xDE}, {0x85,0xDF},
+ {0x85,0xE0}, {0x85,0xE1}, {0x85,0xE2}, {0x85,0xE3},
+ {0x85,0xE4}, {0x85,0xE5}, {0x85,0xE6}, {0x85,0xE7},
+ {0x85,0xE8}, {0x85,0xE9}, {0x85,0xEA}, {0x85,0xEB},
+ {0x85,0xEC}, {0x85,0xED}, {0x85,0xEE}, {0x85,0xEF},
+ {0x85,0xF0}, {0x85,0xF1}, {0x85,0xF2}, {0x85,0xF3},
+ {0x85,0xF4}, {0x85,0xF5}, {0x85,0xF6}, {0x85,0xF7},
+ {0x85,0xF8}, {0x85,0xF9}, {0x85,0xFA}, {0x85,0xFB},
+ {0x85,0xFC}, {0x85,0xFD}, {0x85,0xFE}, {0x86,0x40},
+ {0x86,0x41}, {0x86,0x42}, {0x86,0x43}, {0x86,0x44},
+ {0x86,0x45}, {0x86,0x46}, {0x86,0x47}, {0x86,0x48},
+ {0x86,0x49}, {0x86,0x4A}, {0x86,0x4B}, {0x86,0x4C},
+ {0x86,0x4D}, {0x86,0x4E}, {0x86,0x4F}, {0x86,0x50},
+ {0x86,0x51}, {0x86,0x52}, {0x86,0x53}, {0x86,0x54},
+ {0x86,0x55}, {0x86,0x56}, {0x86,0x57}, {0x86,0x58},
+ {0x86,0x59}, {0x86,0x5A}, {0x86,0x5B}, {0x86,0x5C},
+ {0x86,0x5D}, {0x86,0x5E}, {0x86,0x5F}, {0x86,0x60},
+ {0x86,0x61}, {0x86,0x62}, {0x86,0x63}, {0x86,0x64},
+ {0x86,0x65}, {0x86,0x66}, {0x86,0x67}, {0x86,0x68},
+ {0x86,0x69}, {0x86,0x6A}, {0x86,0x6B}, {0x86,0x6C},
+ {0x86,0x6D}, {0x86,0x6E}, {0x86,0x6F}, {0x86,0x70},
+ {0x86,0x71}, {0x86,0x72}, {0x86,0x73}, {0x86,0x74},
+ {0x86,0x75}, {0x86,0x76}, {0x86,0x77}, {0x86,0x78},
+ {0x86,0x79}, {0x86,0x7A}, {0x86,0x7B}, {0x86,0x7C},
+ {0x86,0x7D}, {0x86,0x7E}, {0x86,0xA1}, {0x86,0xA2},
+ {0x86,0xA3}, {0x86,0xA4}, {0x86,0xA5}, {0x86,0xA6},
+ {0x86,0xA7}, {0x86,0xA8}, {0x86,0xA9}, {0x86,0xAA},
+ {0x86,0xAB}, {0x86,0xAC}, {0x86,0xAD}, {0x86,0xAE},
+ {0x86,0xAF}, {0x86,0xB0}, {0x86,0xB1}, {0x86,0xB2},
+ {0x86,0xB3}, {0x86,0xB4}, {0x86,0xB5}, {0x86,0xB6},
+ {0x86,0xB7}, {0x86,0xB8}, {0x86,0xB9}, {0x86,0xBA},
+ {0x86,0xBB}, {0x86,0xBC}, {0x86,0xBD}, {0x86,0xBE},
+ {0x86,0xBF}, {0x86,0xC0}, {0x86,0xC1}, {0x86,0xC2},
+ {0x86,0xC3}, {0x86,0xC4}, {0x86,0xC5}, {0x86,0xC6},
+ {0x86,0xC7}, {0x86,0xC8}, {0x86,0xC9}, {0x86,0xCA},
+ {0x86,0xCB}, {0x86,0xCC}, {0x86,0xCD}, {0x86,0xCE},
+ {0x86,0xCF}, {0x86,0xD0}, {0x86,0xD1}, {0x86,0xD2},
+ {0x86,0xD3}, {0x86,0xD4}, {0x86,0xD5}, {0x86,0xD6},
+ {0x86,0xD7}, {0x86,0xD8}, {0x86,0xD9}, {0x86,0xDA},
+ {0x86,0xDB}, {0x86,0xDC}, {0x86,0xDD}, {0x86,0xDE},
+ {0x86,0xDF}, {0x86,0xE0}, {0x86,0xE1}, {0x86,0xE2},
+ {0x86,0xE3}, {0x86,0xE4}, {0x86,0xE5}, {0x86,0xE6},
+ {0x86,0xE7}, {0x86,0xE8}, {0x86,0xE9}, {0x86,0xEA},
+ {0x86,0xEB}, {0x86,0xEC}, {0x86,0xED}, {0x86,0xEE},
+ {0x86,0xEF}, {0x86,0xF0}, {0x86,0xF1}, {0x86,0xF2},
+ {0x86,0xF3}, {0x86,0xF4}, {0x86,0xF5}, {0x86,0xF6},
+ {0x86,0xF7}, {0x86,0xF8}, {0x86,0xF9}, {0x86,0xFA},
+ {0x86,0xFB}, {0x86,0xFC}, {0x86,0xFD}, {0x86,0xFE},
+ {0x87,0x40}, {0x87,0x41}, {0x87,0x42}, {0x87,0x43},
+ {0x87,0x44}, {0x87,0x45}, {0x87,0x46}, {0x87,0x47},
+ {0x87,0x48}, {0x87,0x49}, {0x87,0x4A}, {0x87,0x4B},
+ {0x87,0x4C}, {0x87,0x4D}, {0x87,0x4E}, {0x87,0x4F},
+ {0x87,0x50}, {0x87,0x51}, {0x87,0x52}, {0x87,0x53},
+ {0x87,0x54}, {0x87,0x55}, {0x87,0x56}, {0x87,0x57},
+ {0x87,0x58}, {0x87,0x59}, {0x87,0x5A}, {0x87,0x5B},
+ {0x87,0x5C}, {0x87,0x5D}, {0x87,0x5E}, {0x87,0x5F},
+ {0x87,0x60}, {0x87,0x61}, {0x87,0x62}, {0x87,0x63},
+ {0x87,0x64}, {0x87,0x65}, {0x87,0x66}, {0x87,0x67},
+ {0x87,0x68}, {0x87,0x69}, {0x87,0x6A}, {0x87,0x6B},
+ {0x87,0x6C}, {0x87,0x6D}, {0x87,0x6E}, {0x87,0x6F},
+ {0x87,0x70}, {0x87,0x71}, {0x87,0x72}, {0x87,0x73},
+ {0x87,0x74}, {0x87,0x75}, {0x87,0x76}, {0x87,0x77},
+ {0x87,0x78}, {0x87,0x79}, {0x87,0x7A}, {0x87,0x7B},
+ {0x87,0x7C}, {0x87,0x7D}, {0x87,0x7E}, {0x87,0xA1},
+ {0x87,0xA2}, {0x87,0xA3}, {0x87,0xA4}, {0x87,0xA5},
+ {0x87,0xA6}, {0x87,0xA7}, {0x87,0xA8}, {0x87,0xA9},
+ {0x87,0xAA}, {0x87,0xAB}, {0x87,0xAC}, {0x87,0xAD},
+ {0x87,0xAE}, {0x87,0xAF}, {0x87,0xB0}, {0x87,0xB1},
+ {0x87,0xB2}, {0x87,0xB3}, {0x87,0xB4}, {0x87,0xB5},
+ {0x87,0xB6}, {0x87,0xB7}, {0x87,0xB8}, {0x87,0xB9},
+ {0x87,0xBA}, {0x87,0xBB}, {0x87,0xBC}, {0x87,0xBD},
+ {0x87,0xBE}, {0x87,0xBF}, {0x87,0xC0}, {0x87,0xC1},
+ {0x87,0xC2}, {0x87,0xC3}, {0x87,0xC4}, {0x87,0xC5},
+ {0x87,0xC6}, {0x87,0xC7}, {0x87,0xC8}, {0x87,0xC9},
+ {0x87,0xCA}, {0x87,0xCB}, {0x87,0xCC}, {0x87,0xCD},
+ {0x87,0xCE}, {0x87,0xCF}, {0x87,0xD0}, {0x87,0xD1},
+ {0x87,0xD2}, {0x87,0xD3}, {0x87,0xD4}, {0x87,0xD5},
+ {0x87,0xD6}, {0x87,0xD7}, {0x87,0xD8}, {0x87,0xD9},
+ {0x87,0xDA}, {0x87,0xDB}, {0x87,0xDC}, {0x87,0xDD},
+ {0x87,0xDE}, {0x87,0xDF}, {0x87,0xE0}, {0x87,0xE1},
+ {0x87,0xE2}, {0x87,0xE3}, {0x87,0xE4}, {0x87,0xE5},
+ {0x87,0xE6}, {0x87,0xE7}, {0x87,0xE8}, {0x87,0xE9},
+ {0x87,0xEA}, {0x87,0xEB}, {0x87,0xEC}, {0x87,0xED},
+ {0x87,0xEE}, {0x87,0xEF}, {0x87,0xF0}, {0x87,0xF1},
+ {0x87,0xF2}, {0x87,0xF3}, {0x87,0xF4}, {0x87,0xF5},
+ {0x87,0xF6}, {0x87,0xF7}, {0x87,0xF8}, {0x87,0xF9},
+ {0x87,0xFA}, {0x87,0xFB}, {0x87,0xFC}, {0x87,0xFD},
+ {0x87,0xFE}, {0x88,0x40}, {0x88,0x41}, {0x88,0x42},
+ {0x88,0x43}, {0x88,0x44}, {0x88,0x45}, {0x88,0x46},
+ {0x88,0x47}, {0x88,0x48}, {0x88,0x49}, {0x88,0x4A},
+ {0x88,0x4B}, {0x88,0x4C}, {0x88,0x4D}, {0x88,0x4E},
+ {0x88,0x4F}, {0x88,0x50}, {0x88,0x51}, {0x88,0x52},
+ {0x88,0x53}, {0x88,0x54}, {0x88,0x55}, {0x88,0x56},
+ {0x88,0x57}, {0x88,0x58}, {0x88,0x59}, {0x88,0x5A},
+ {0x88,0x5B}, {0x88,0x5C}, {0x88,0x5D}, {0x88,0x5E},
+ {0x88,0x5F}, {0x88,0x60}, {0x88,0x61}, {0x88,0x62},
+ {0x88,0x63}, {0x88,0x64}, {0x88,0x65}, {0x88,0x66},
+ {0x88,0x67}, {0x88,0x68}, {0x88,0x69}, {0x88,0x6A},
+ {0x88,0x6B}, {0x88,0x6C}, {0x88,0x6D}, {0x88,0x6E},
+ {0x88,0x6F}, {0x88,0x70}, {0x88,0x71}, {0x88,0x72},
+ {0x88,0x73}, {0x88,0x74}, {0x88,0x75}, {0x88,0x76},
+ {0x88,0x77}, {0x88,0x78}, {0x88,0x79}, {0x88,0x7A},
+ {0x88,0x7B}, {0x88,0x7C}, {0x88,0x7D}, {0x88,0x7E},
+ {0x88,0xA1}, {0x88,0xA2}, {0x88,0xA3}, {0x88,0xA4},
+ {0x88,0xA5}, {0x88,0xA6}, {0x88,0xA7}, {0x88,0xA8},
+ {0x88,0xA9}, {0x88,0xAA}, {0x88,0xAB}, {0x88,0xAC},
+ {0x88,0xAD}, {0x88,0xAE}, {0x88,0xAF}, {0x88,0xB0},
+ {0x88,0xB1}, {0x88,0xB2}, {0x88,0xB3}, {0x88,0xB4},
+ {0x88,0xB5}, {0x88,0xB6}, {0x88,0xB7}, {0x88,0xB8},
+ {0x88,0xB9}, {0x88,0xBA}, {0x88,0xBB}, {0x88,0xBC},
+ {0x88,0xBD}, {0x88,0xBE}, {0x88,0xBF}, {0x88,0xC0},
+ {0x88,0xC1}, {0x88,0xC2}, {0x88,0xC3}, {0x88,0xC4},
+ {0x88,0xC5}, {0x88,0xC6}, {0x88,0xC7}, {0x88,0xC8},
+ {0x88,0xC9}, {0x88,0xCA}, {0x88,0xCB}, {0x88,0xCC},
+ {0x88,0xCD}, {0x88,0xCE}, {0x88,0xCF}, {0x88,0xD0},
+ {0x88,0xD1}, {0x88,0xD2}, {0x88,0xD3}, {0x88,0xD4},
+ {0x88,0xD5}, {0x88,0xD6}, {0x88,0xD7}, {0x88,0xD8},
+ {0x88,0xD9}, {0x88,0xDA}, {0x88,0xDB}, {0x88,0xDC},
+ {0x88,0xDD}, {0x88,0xDE}, {0x88,0xDF}, {0x88,0xE0},
+ {0x88,0xE1}, {0x88,0xE2}, {0x88,0xE3}, {0x88,0xE4},
+ {0x88,0xE5}, {0x88,0xE6}, {0x88,0xE7}, {0x88,0xE8},
+ {0x88,0xE9}, {0x88,0xEA}, {0x88,0xEB}, {0x88,0xEC},
+ {0x88,0xED}, {0x88,0xEE}, {0x88,0xEF}, {0x88,0xF0},
+ {0x88,0xF1}, {0x88,0xF2}, {0x88,0xF3}, {0x88,0xF4},
+ {0x88,0xF5}, {0x88,0xF6}, {0x88,0xF7}, {0x88,0xF8},
+ {0x88,0xF9}, {0x88,0xFA}, {0x88,0xFB}, {0x88,0xFC},
+ {0x88,0xFD}, {0x88,0xFE}, {0x89,0x40}, {0x89,0x41},
+ {0x89,0x42}, {0x89,0x43}, {0x89,0x44}, {0x89,0x45},
+ {0x89,0x46}, {0x89,0x47}, {0x89,0x48}, {0x89,0x49},
+ {0x89,0x4A}, {0x89,0x4B}, {0x89,0x4C}, {0x89,0x4D},
+ {0x89,0x4E}, {0x89,0x4F}, {0x89,0x50}, {0x89,0x51},
+ {0x89,0x52}, {0x89,0x53}, {0x89,0x54}, {0x89,0x55},
+ {0x89,0x56}, {0x89,0x57}, {0x89,0x58}, {0x89,0x59},
+ {0x89,0x5A}, {0x89,0x5B}, {0x89,0x5C}, {0x89,0x5D},
+ {0x89,0x5E}, {0x89,0x5F}, {0x89,0x60}, {0x89,0x61},
+ {0x89,0x62}, {0x89,0x63}, {0x89,0x64}, {0x89,0x65},
+ {0x89,0x66}, {0x89,0x67}, {0x89,0x68}, {0x89,0x69},
+ {0x89,0x6A}, {0x89,0x6B}, {0x89,0x6C}, {0x89,0x6D},
+ {0x89,0x6E}, {0x89,0x6F}, {0x89,0x70}, {0x89,0x71},
+ {0x89,0x72}, {0x89,0x73}, {0x89,0x74}, {0x89,0x75},
+ {0x89,0x76}, {0x89,0x77}, {0x89,0x78}, {0x89,0x79},
+ {0x89,0x7A}, {0x89,0x7B}, {0x89,0x7C}, {0x89,0x7D},
+ {0x89,0x7E}, {0x89,0xA1}, {0x89,0xA2}, {0x89,0xA3},
+ {0x89,0xA4}, {0x89,0xA5}, {0x89,0xA6}, {0x89,0xA7},
+ {0x89,0xA8}, {0x89,0xA9}, {0x89,0xAA}, {0x89,0xAB},
+ {0x89,0xAC}, {0x89,0xAD}, {0x89,0xAE}, {0x89,0xAF},
+ {0x89,0xB0}, {0x89,0xB1}, {0x89,0xB2}, {0x89,0xB3},
+ {0x89,0xB4}, {0x89,0xB5}, {0x89,0xB6}, {0x89,0xB7},
+ {0x89,0xB8}, {0x89,0xB9}, {0x89,0xBA}, {0x89,0xBB},
+ {0x89,0xBC}, {0x89,0xBD}, {0x89,0xBE}, {0x89,0xBF},
+ {0x89,0xC0}, {0x89,0xC1}, {0x89,0xC2}, {0x89,0xC3},
+ {0x89,0xC4}, {0x89,0xC5}, {0x89,0xC6}, {0x89,0xC7},
+ {0x89,0xC8}, {0x89,0xC9}, {0x89,0xCA}, {0x89,0xCB},
+ {0x89,0xCC}, {0x89,0xCD}, {0x89,0xCE}, {0x89,0xCF},
+ {0x89,0xD0}, {0x89,0xD1}, {0x89,0xD2}, {0x89,0xD3},
+ {0x89,0xD4}, {0x89,0xD5}, {0x89,0xD6}, {0x89,0xD7},
+ {0x89,0xD8}, {0x89,0xD9}, {0x89,0xDA}, {0x89,0xDB},
+ {0x89,0xDC}, {0x89,0xDD}, {0x89,0xDE}, {0x89,0xDF},
+ {0x89,0xE0}, {0x89,0xE1}, {0x89,0xE2}, {0x89,0xE3},
+ {0x89,0xE4}, {0x89,0xE5}, {0x89,0xE6}, {0x89,0xE7},
+ {0x89,0xE8}, {0x89,0xE9}, {0x89,0xEA}, {0x89,0xEB},
+ {0x89,0xEC}, {0x89,0xED}, {0x89,0xEE}, {0x89,0xEF},
+ {0x89,0xF0}, {0x89,0xF1}, {0x89,0xF2}, {0x89,0xF3},
+ {0x89,0xF4}, {0x89,0xF5}, {0x89,0xF6}, {0x89,0xF7},
+ {0x89,0xF8}, {0x89,0xF9}, {0x89,0xFA}, {0x89,0xFB},
+ {0x89,0xFC}, {0x89,0xFD}, {0x89,0xFE}, {0x8A,0x40},
+ {0x8A,0x41}, {0x8A,0x42}, {0x8A,0x43}, {0x8A,0x44},
+ {0x8A,0x45}, {0x8A,0x46}, {0x8A,0x47}, {0x8A,0x48},
+ {0x8A,0x49}, {0x8A,0x4A}, {0x8A,0x4B}, {0x8A,0x4C},
+ {0x8A,0x4D}, {0x8A,0x4E}, {0x8A,0x4F}, {0x8A,0x50},
+ {0x8A,0x51}, {0x8A,0x52}, {0x8A,0x53}, {0x8A,0x54},
+ {0x8A,0x55}, {0x8A,0x56}, {0x8A,0x57}, {0x8A,0x58},
+ {0x8A,0x59}, {0x8A,0x5A}, {0x8A,0x5B}, {0x8A,0x5C},
+ {0x8A,0x5D}, {0x8A,0x5E}, {0x8A,0x5F}, {0x8A,0x60},
+ {0x8A,0x61}, {0x8A,0x62}, {0x8A,0x63}, {0x8A,0x64},
+ {0x8A,0x65}, {0x8A,0x66}, {0x8A,0x67}, {0x8A,0x68},
+ {0x8A,0x69}, {0x8A,0x6A}, {0x8A,0x6B}, {0x8A,0x6C},
+ {0x8A,0x6D}, {0x8A,0x6E}, {0x8A,0x6F}, {0x8A,0x70},
+ {0x8A,0x71}, {0x8A,0x72}, {0x8A,0x73}, {0x8A,0x74},
+ {0x8A,0x75}, {0x8A,0x76}, {0x8A,0x77}, {0x8A,0x78},
+ {0x8A,0x79}, {0x8A,0x7A}, {0x8A,0x7B}, {0x8A,0x7C},
+ {0x8A,0x7D}, {0x8A,0x7E}, {0x8A,0xA1}, {0x8A,0xA2},
+ {0x8A,0xA3}, {0x8A,0xA4}, {0x8A,0xA5}, {0x8A,0xA6},
+ {0x8A,0xA7}, {0x8A,0xA8}, {0x8A,0xA9}, {0x8A,0xAA},
+ {0x8A,0xAB}, {0x8A,0xAC}, {0x8A,0xAD}, {0x8A,0xAE},
+ {0x8A,0xAF}, {0x8A,0xB0}, {0x8A,0xB1}, {0x8A,0xB2},
+ {0x8A,0xB3}, {0x8A,0xB4}, {0x8A,0xB5}, {0x8A,0xB6},
+ {0x8A,0xB7}, {0x8A,0xB8}, {0x8A,0xB9}, {0x8A,0xBA},
+ {0x8A,0xBB}, {0x8A,0xBC}, {0x8A,0xBD}, {0x8A,0xBE},
+ {0x8A,0xBF}, {0x8A,0xC0}, {0x8A,0xC1}, {0x8A,0xC2},
+ {0x8A,0xC3}, {0x8A,0xC4}, {0x8A,0xC5}, {0x8A,0xC6},
+ {0x8A,0xC7}, {0x8A,0xC8}, {0x8A,0xC9}, {0x8A,0xCA},
+ {0x8A,0xCB}, {0x8A,0xCC}, {0x8A,0xCD}, {0x8A,0xCE},
+ {0x8A,0xCF}, {0x8A,0xD0}, {0x8A,0xD1}, {0x8A,0xD2},
+ {0x8A,0xD3}, {0x8A,0xD4}, {0x8A,0xD5}, {0x8A,0xD6},
+ {0x8A,0xD7}, {0x8A,0xD8}, {0x8A,0xD9}, {0x8A,0xDA},
+ {0x8A,0xDB}, {0x8A,0xDC}, {0x8A,0xDD}, {0x8A,0xDE},
+ {0x8A,0xDF}, {0x8A,0xE0}, {0x8A,0xE1}, {0x8A,0xE2},
+ {0x8A,0xE3}, {0x8A,0xE4}, {0x8A,0xE5}, {0x8A,0xE6},
+ {0x8A,0xE7}, {0x8A,0xE8}, {0x8A,0xE9}, {0x8A,0xEA},
+ {0x8A,0xEB}, {0x8A,0xEC}, {0x8A,0xED}, {0x8A,0xEE},
+ {0x8A,0xEF}, {0x8A,0xF0}, {0x8A,0xF1}, {0x8A,0xF2},
+ {0x8A,0xF3}, {0x8A,0xF4}, {0x8A,0xF5}, {0x8A,0xF6},
+ {0x8A,0xF7}, {0x8A,0xF8}, {0x8A,0xF9}, {0x8A,0xFA},
+ {0x8A,0xFB}, {0x8A,0xFC}, {0x8A,0xFD}, {0x8A,0xFE},
+ {0x8B,0x40}, {0x8B,0x41}, {0x8B,0x42}, {0x8B,0x43},
+ {0x8B,0x44}, {0x8B,0x45}, {0x8B,0x46}, {0x8B,0x47},
+ {0x8B,0x48}, {0x8B,0x49}, {0x8B,0x4A}, {0x8B,0x4B},
+ {0x8B,0x4C}, {0x8B,0x4D}, {0x8B,0x4E}, {0x8B,0x4F},
+ {0x8B,0x50}, {0x8B,0x51}, {0x8B,0x52}, {0x8B,0x53},
+ {0x8B,0x54}, {0x8B,0x55}, {0x8B,0x56}, {0x8B,0x57},
+ {0x8B,0x58}, {0x8B,0x59}, {0x8B,0x5A}, {0x8B,0x5B},
+ {0x8B,0x5C}, {0x8B,0x5D}, {0x8B,0x5E}, {0x8B,0x5F},
+ {0x8B,0x60}, {0x8B,0x61}, {0x8B,0x62}, {0x8B,0x63},
+ {0x8B,0x64}, {0x8B,0x65}, {0x8B,0x66}, {0x8B,0x67},
+ {0x8B,0x68}, {0x8B,0x69}, {0x8B,0x6A}, {0x8B,0x6B},
+ {0x8B,0x6C}, {0x8B,0x6D}, {0x8B,0x6E}, {0x8B,0x6F},
+ {0x8B,0x70}, {0x8B,0x71}, {0x8B,0x72}, {0x8B,0x73},
+ {0x8B,0x74}, {0x8B,0x75}, {0x8B,0x76}, {0x8B,0x77},
+ {0x8B,0x78}, {0x8B,0x79}, {0x8B,0x7A}, {0x8B,0x7B},
+ {0x8B,0x7C}, {0x8B,0x7D}, {0x8B,0x7E}, {0x8B,0xA1},
+ {0x8B,0xA2}, {0x8B,0xA3}, {0x8B,0xA4}, {0x8B,0xA5},
+ {0x8B,0xA6}, {0x8B,0xA7}, {0x8B,0xA8}, {0x8B,0xA9},
+ {0x8B,0xAA}, {0x8B,0xAB}, {0x8B,0xAC}, {0x8B,0xAD},
+ {0x8B,0xAE}, {0x8B,0xAF}, {0x8B,0xB0}, {0x8B,0xB1},
+ {0x8B,0xB2}, {0x8B,0xB3}, {0x8B,0xB4}, {0x8B,0xB5},
+ {0x8B,0xB6}, {0x8B,0xB7}, {0x8B,0xB8}, {0x8B,0xB9},
+ {0x8B,0xBA}, {0x8B,0xBB}, {0x8B,0xBC}, {0x8B,0xBD},
+ {0x8B,0xBE}, {0x8B,0xBF}, {0x8B,0xC0}, {0x8B,0xC1},
+ {0x8B,0xC2}, {0x8B,0xC3}, {0x8B,0xC4}, {0x8B,0xC5},
+ {0x8B,0xC6}, {0x8B,0xC7}, {0x8B,0xC8}, {0x8B,0xC9},
+ {0x8B,0xCA}, {0x8B,0xCB}, {0x8B,0xCC}, {0x8B,0xCD},
+ {0x8B,0xCE}, {0x8B,0xCF}, {0x8B,0xD0}, {0x8B,0xD1},
+ {0x8B,0xD2}, {0x8B,0xD3}, {0x8B,0xD4}, {0x8B,0xD5},
+ {0x8B,0xD6}, {0x8B,0xD7}, {0x8B,0xD8}, {0x8B,0xD9},
+ {0x8B,0xDA}, {0x8B,0xDB}, {0x8B,0xDC}, {0x8B,0xDD},
+ {0x8B,0xDE}, {0x8B,0xDF}, {0x8B,0xE0}, {0x8B,0xE1},
+ {0x8B,0xE2}, {0x8B,0xE3}, {0x8B,0xE4}, {0x8B,0xE5},
+ {0x8B,0xE6}, {0x8B,0xE7}, {0x8B,0xE8}, {0x8B,0xE9},
+ {0x8B,0xEA}, {0x8B,0xEB}, {0x8B,0xEC}, {0x8B,0xED},
+ {0x8B,0xEE}, {0x8B,0xEF}, {0x8B,0xF0}, {0x8B,0xF1},
+ {0x8B,0xF2}, {0x8B,0xF3}, {0x8B,0xF4}, {0x8B,0xF5},
+ {0x8B,0xF6}, {0x8B,0xF7}, {0x8B,0xF8}, {0x8B,0xF9},
+ {0x8B,0xFA}, {0x8B,0xFB}, {0x8B,0xFC}, {0x8B,0xFD},
+ {0x8B,0xFE}, {0x8C,0x40}, {0x8C,0x41}, {0x8C,0x42},
+ {0x8C,0x43}, {0x8C,0x44}, {0x8C,0x45}, {0x8C,0x46},
+ {0x8C,0x47}, {0x8C,0x48}, {0x8C,0x49}, {0x8C,0x4A},
+ {0x8C,0x4B}, {0x8C,0x4C}, {0x8C,0x4D}, {0x8C,0x4E},
+ {0x8C,0x4F}, {0x8C,0x50}, {0x8C,0x51}, {0x8C,0x52},
+ {0x8C,0x53}, {0x8C,0x54}, {0x8C,0x55}, {0x8C,0x56},
+ {0x8C,0x57}, {0x8C,0x58}, {0x8C,0x59}, {0x8C,0x5A},
+ {0x8C,0x5B}, {0x8C,0x5C}, {0x8C,0x5D}, {0x8C,0x5E},
+ {0x8C,0x5F}, {0x8C,0x60}, {0x8C,0x61}, {0x8C,0x62},
+ {0x8C,0x63}, {0x8C,0x64}, {0x8C,0x65}, {0x8C,0x66},
+ {0x8C,0x67}, {0x8C,0x68}, {0x8C,0x69}, {0x8C,0x6A},
+ {0x8C,0x6B}, {0x8C,0x6C}, {0x8C,0x6D}, {0x8C,0x6E},
+ {0x8C,0x6F}, {0x8C,0x70}, {0x8C,0x71}, {0x8C,0x72},
+ {0x8C,0x73}, {0x8C,0x74}, {0x8C,0x75}, {0x8C,0x76},
+ {0x8C,0x77}, {0x8C,0x78}, {0x8C,0x79}, {0x8C,0x7A},
+ {0x8C,0x7B}, {0x8C,0x7C}, {0x8C,0x7D}, {0x8C,0x7E},
+ {0x8C,0xA1}, {0x8C,0xA2}, {0x8C,0xA3}, {0x8C,0xA4},
+ {0x8C,0xA5}, {0x8C,0xA6}, {0x8C,0xA7}, {0x8C,0xA8},
+ {0x8C,0xA9}, {0x8C,0xAA}, {0x8C,0xAB}, {0x8C,0xAC},
+ {0x8C,0xAD}, {0x8C,0xAE}, {0x8C,0xAF}, {0x8C,0xB0},
+ {0x8C,0xB1}, {0x8C,0xB2}, {0x8C,0xB3}, {0x8C,0xB4},
+ {0x8C,0xB5}, {0x8C,0xB6}, {0x8C,0xB7}, {0x8C,0xB8},
+ {0x8C,0xB9}, {0x8C,0xBA}, {0x8C,0xBB}, {0x8C,0xBC},
+ {0x8C,0xBD}, {0x8C,0xBE}, {0x8C,0xBF}, {0x8C,0xC0},
+ {0x8C,0xC1}, {0x8C,0xC2}, {0x8C,0xC3}, {0x8C,0xC4},
+ {0x8C,0xC5}, {0x8C,0xC6}, {0x8C,0xC7}, {0x8C,0xC8},
+ {0x8C,0xC9}, {0x8C,0xCA}, {0x8C,0xCB}, {0x8C,0xCC},
+ {0x8C,0xCD}, {0x8C,0xCE}, {0x8C,0xCF}, {0x8C,0xD0},
+ {0x8C,0xD1}, {0x8C,0xD2}, {0x8C,0xD3}, {0x8C,0xD4},
+ {0x8C,0xD5}, {0x8C,0xD6}, {0x8C,0xD7}, {0x8C,0xD8},
+ {0x8C,0xD9}, {0x8C,0xDA}, {0x8C,0xDB}, {0x8C,0xDC},
+ {0x8C,0xDD}, {0x8C,0xDE}, {0x8C,0xDF}, {0x8C,0xE0},
+ {0x8C,0xE1}, {0x8C,0xE2}, {0x8C,0xE3}, {0x8C,0xE4},
+ {0x8C,0xE5}, {0x8C,0xE6}, {0x8C,0xE7}, {0x8C,0xE8},
+ {0x8C,0xE9}, {0x8C,0xEA}, {0x8C,0xEB}, {0x8C,0xEC},
+ {0x8C,0xED}, {0x8C,0xEE}, {0x8C,0xEF}, {0x8C,0xF0},
+ {0x8C,0xF1}, {0x8C,0xF2}, {0x8C,0xF3}, {0x8C,0xF4},
+ {0x8C,0xF5}, {0x8C,0xF6}, {0x8C,0xF7}, {0x8C,0xF8},
+ {0x8C,0xF9}, {0x8C,0xFA}, {0x8C,0xFB}, {0x8C,0xFC},
+ {0x8C,0xFD}, {0x8C,0xFE}, {0x8D,0x40}, {0x8D,0x41},
+ {0x8D,0x42}, {0x8D,0x43}, {0x8D,0x44}, {0x8D,0x45},
+ {0x8D,0x46}, {0x8D,0x47}, {0x8D,0x48}, {0x8D,0x49},
+ {0x8D,0x4A}, {0x8D,0x4B}, {0x8D,0x4C}, {0x8D,0x4D},
+ {0x8D,0x4E}, {0x8D,0x4F}, {0x8D,0x50}, {0x8D,0x51},
+ {0x8D,0x52}, {0x8D,0x53}, {0x8D,0x54}, {0x8D,0x55},
+ {0x8D,0x56}, {0x8D,0x57}, {0x8D,0x58}, {0x8D,0x59},
+ {0x8D,0x5A}, {0x8D,0x5B}, {0x8D,0x5C}, {0x8D,0x5D},
+ {0x8D,0x5E}, {0x8D,0x5F}, {0x8D,0x60}, {0x8D,0x61},
+ {0x8D,0x62}, {0x8D,0x63}, {0x8D,0x64}, {0x8D,0x65},
+ {0x8D,0x66}, {0x8D,0x67}, {0x8D,0x68}, {0x8D,0x69},
+ {0x8D,0x6A}, {0x8D,0x6B}, {0x8D,0x6C}, {0x8D,0x6D},
+ {0x8D,0x6E}, {0x8D,0x6F}, {0x8D,0x70}, {0x8D,0x71},
+ {0x8D,0x72}, {0x8D,0x73}, {0x8D,0x74}, {0x8D,0x75},
+ {0x8D,0x76}, {0x8D,0x77}, {0x8D,0x78}, {0x8D,0x79},
+ {0x8D,0x7A}, {0x8D,0x7B}, {0x8D,0x7C}, {0x8D,0x7D},
+ {0x8D,0x7E}, {0x8D,0xA1}, {0x8D,0xA2}, {0x8D,0xA3},
+ {0x8D,0xA4}, {0x8D,0xA5}, {0x8D,0xA6}, {0x8D,0xA7},
+ {0x8D,0xA8}, {0x8D,0xA9}, {0x8D,0xAA}, {0x8D,0xAB},
+ {0x8D,0xAC}, {0x8D,0xAD}, {0x8D,0xAE}, {0x8D,0xAF},
+ {0x8D,0xB0}, {0x8D,0xB1}, {0x8D,0xB2}, {0x8D,0xB3},
+ {0x8D,0xB4}, {0x8D,0xB5}, {0x8D,0xB6}, {0x8D,0xB7},
+ {0x8D,0xB8}, {0x8D,0xB9}, {0x8D,0xBA}, {0x8D,0xBB},
+ {0x8D,0xBC}, {0x8D,0xBD}, {0x8D,0xBE}, {0x8D,0xBF},
+ {0x8D,0xC0}, {0x8D,0xC1}, {0x8D,0xC2}, {0x8D,0xC3},
+ {0x8D,0xC4}, {0x8D,0xC5}, {0x8D,0xC6}, {0x8D,0xC7},
+ {0x8D,0xC8}, {0x8D,0xC9}, {0x8D,0xCA}, {0x8D,0xCB},
+ {0x8D,0xCC}, {0x8D,0xCD}, {0x8D,0xCE}, {0x8D,0xCF},
+ {0x8D,0xD0}, {0x8D,0xD1}, {0x8D,0xD2}, {0x8D,0xD3},
+ {0x8D,0xD4}, {0x8D,0xD5}, {0x8D,0xD6}, {0x8D,0xD7},
+ {0x8D,0xD8}, {0x8D,0xD9}, {0x8D,0xDA}, {0x8D,0xDB},
+ {0x8D,0xDC}, {0x8D,0xDD}, {0x8D,0xDE}, {0x8D,0xDF},
+ {0x8D,0xE0}, {0x8D,0xE1}, {0x8D,0xE2}, {0x8D,0xE3},
+ {0x8D,0xE4}, {0x8D,0xE5}, {0x8D,0xE6}, {0x8D,0xE7},
+ {0x8D,0xE8}, {0x8D,0xE9}, {0x8D,0xEA}, {0x8D,0xEB},
+ {0x8D,0xEC}, {0x8D,0xED}, {0x8D,0xEE}, {0x8D,0xEF},
+ {0x8D,0xF0}, {0x8D,0xF1}, {0x8D,0xF2}, {0x8D,0xF3},
+ {0x8D,0xF4}, {0x8D,0xF5}, {0x8D,0xF6}, {0x8D,0xF7},
+ {0x8D,0xF8}, {0x8D,0xF9}, {0x8D,0xFA}, {0x8D,0xFB},
+ {0x8D,0xFC}, {0x8D,0xFD}, {0x8D,0xFE}, {0xC6,0xA1},
+ {0xC6,0xA2}, {0xC6,0xA3}, {0xC6,0xA4}, {0xC6,0xA5},
+ {0xC6,0xA6}, {0xC6,0xA7}, {0xC6,0xA8}, {0xC6,0xA9},
+ {0xC6,0xAA}, {0xC6,0xAB}, {0xC6,0xAC}, {0xC6,0xAD},
+ {0xC6,0xAE}, {0xC6,0xAF}, {0xC6,0xB0}, {0xC6,0xB1},
+ {0xC6,0xB2}, {0xC6,0xB3}, {0xC6,0xB4}, {0xC6,0xB5},
+ {0xC6,0xB6}, {0xC6,0xB7}, {0xC6,0xB8}, {0xC6,0xB9},
+ {0xC6,0xBA}, {0xC6,0xBB}, {0xC6,0xBC}, {0xC6,0xBD},
+ {0xC6,0xBE}, {0xC6,0xBF}, {0xC6,0xC0}, {0xC6,0xC1},
+ {0xC6,0xC2}, {0xC6,0xC3}, {0xC6,0xC4}, {0xC6,0xC5},
+ {0xC6,0xC6}, {0xC6,0xC7}, {0xC6,0xC8}, {0xC6,0xC9},
+ {0xC6,0xCA}, {0xC6,0xCB}, {0xC6,0xCC}, {0xC6,0xCD},
+ {0xC6,0xCE}, {0xC6,0xCF}, {0xC6,0xD0}, {0xC6,0xD1},
+ {0xC6,0xD2}, {0xC6,0xD3}, {0xC6,0xD4}, {0xC6,0xD5},
+ {0xC6,0xD6}, {0xC6,0xD7}, {0xC6,0xD8}, {0xC6,0xD9},
+ {0xC6,0xDA}, {0xC6,0xDB}, {0xC6,0xDC}, {0xC6,0xDD},
+ {0xC6,0xDE}, {0xC6,0xDF}, {0xC6,0xE0}, {0xC6,0xE1},
+ {0xC6,0xE2}, {0xC6,0xE3}, {0xC6,0xE4}, {0xC6,0xE5},
+ {0xC6,0xE6}, {0xC6,0xE7}, {0xC6,0xE8}, {0xC6,0xE9},
+ {0xC6,0xEA}, {0xC6,0xEB}, {0xC6,0xEC}, {0xC6,0xED},
+ {0xC6,0xEE}, {0xC6,0xEF}, {0xC6,0xF0}, {0xC6,0xF1},
+ {0xC6,0xF2}, {0xC6,0xF3}, {0xC6,0xF4}, {0xC6,0xF5},
+ {0xC6,0xF6}, {0xC6,0xF7}, {0xC6,0xF8}, {0xC6,0xF9},
+ {0xC6,0xFA}, {0xC6,0xFB}, {0xC6,0xFC}, {0xC6,0xFD},
+ {0xC6,0xFE}, {0xC7,0x40}, {0xC7,0x41}, {0xC7,0x42},
+ {0xC7,0x43}, {0xC7,0x44}, {0xC7,0x45}, {0xC7,0x46},
+ {0xC7,0x47}, {0xC7,0x48}, {0xC7,0x49}, {0xC7,0x4A},
+ {0xC7,0x4B}, {0xC7,0x4C}, {0xC7,0x4D}, {0xC7,0x4E},
+ {0xC7,0x4F}, {0xC7,0x50}, {0xC7,0x51}, {0xC7,0x52},
+ {0xC7,0x53}, {0xC7,0x54}, {0xC7,0x55}, {0xC7,0x56},
+ {0xC7,0x57}, {0xC7,0x58}, {0xC7,0x59}, {0xC7,0x5A},
+ {0xC7,0x5B}, {0xC7,0x5C}, {0xC7,0x5D}, {0xC7,0x5E},
+ {0xC7,0x5F}, {0xC7,0x60}, {0xC7,0x61}, {0xC7,0x62},
+ {0xC7,0x63}, {0xC7,0x64}, {0xC7,0x65}, {0xC7,0x66},
+ {0xC7,0x67}, {0xC7,0x68}, {0xC7,0x69}, {0xC7,0x6A},
+ {0xC7,0x6B}, {0xC7,0x6C}, {0xC7,0x6D}, {0xC7,0x6E},
+ {0xC7,0x6F}, {0xC7,0x70}, {0xC7,0x71}, {0xC7,0x72},
+ {0xC7,0x73}, {0xC7,0x74}, {0xC7,0x75}, {0xC7,0x76},
+ {0xC7,0x77}, {0xC7,0x78}, {0xC7,0x79}, {0xC7,0x7A},
+ {0xC7,0x7B}, {0xC7,0x7C}, {0xC7,0x7D}, {0xC7,0x7E},
+ {0xC7,0xA1}, {0xC7,0xA2}, {0xC7,0xA3}, {0xC7,0xA4},
+ {0xC7,0xA5}, {0xC7,0xA6}, {0xC7,0xA7}, {0xC7,0xA8},
+ {0xC7,0xA9}, {0xC7,0xAA}, {0xC7,0xAB}, {0xC7,0xAC},
+ {0xC7,0xAD}, {0xC7,0xAE}, {0xC7,0xAF}, {0xC7,0xB0},
+ {0xC7,0xB1}, {0xC7,0xB2}, {0xC7,0xB3}, {0xC7,0xB4},
+ {0xC7,0xB5}, {0xC7,0xB6}, {0xC7,0xB7}, {0xC7,0xB8},
+ {0xC7,0xB9}, {0xC7,0xBA}, {0xC7,0xBB}, {0xC7,0xBC},
+ {0xC7,0xBD}, {0xC7,0xBE}, {0xC7,0xBF}, {0xC7,0xC0},
+ {0xC7,0xC1}, {0xC7,0xC2}, {0xC7,0xC3}, {0xC7,0xC4},
+ {0xC7,0xC5}, {0xC7,0xC6}, {0xC7,0xC7}, {0xC7,0xC8},
+ {0xC7,0xC9}, {0xC7,0xCA}, {0xC7,0xCB}, {0xC7,0xCC},
+ {0xC7,0xCD}, {0xC7,0xCE}, {0xC7,0xCF}, {0xC7,0xD0},
+ {0xC7,0xD1}, {0xC7,0xD2}, {0xC7,0xD3}, {0xC7,0xD4},
+ {0xC7,0xD5}, {0xC7,0xD6}, {0xC7,0xD7}, {0xC7,0xD8},
+ {0xC7,0xD9}, {0xC7,0xDA}, {0xC7,0xDB}, {0xC7,0xDC},
+ {0xC7,0xDD}, {0xC7,0xDE}, {0xC7,0xDF}, {0xC7,0xE0},
+ {0xC7,0xE1}, {0xC7,0xE2}, {0xC7,0xE3}, {0xC7,0xE4},
+ {0xC7,0xE5}, {0xC7,0xE6}, {0xC7,0xE7}, {0xC7,0xE8},
+ {0xC7,0xE9}, {0xC7,0xEA}, {0xC7,0xEB}, {0xC7,0xEC},
+ {0xC7,0xED}, {0xC7,0xEE}, {0xC7,0xEF}, {0xC7,0xF0},
+ {0xC7,0xF1}, {0xC7,0xF2}, {0xC7,0xF3}, {0xC7,0xF4},
+ {0xC7,0xF5}, {0xC7,0xF6}, {0xC7,0xF7}, {0xC7,0xF8},
+ {0xC7,0xF9}, {0xC7,0xFA}, {0xC7,0xFB}, {0xC7,0xFC},
+ {0xC7,0xFD}, {0xC7,0xFE}, {0xC8,0x40}, {0xC8,0x41},
+ {0xC8,0x42}, {0xC8,0x43}, {0xC8,0x44}, {0xC8,0x45},
+ {0xC8,0x46}, {0xC8,0x47}, {0xC8,0x48}, {0xC8,0x49},
+ {0xC8,0x4A}, {0xC8,0x4B}, {0xC8,0x4C}, {0xC8,0x4D},
+ {0xC8,0x4E}, {0xC8,0x4F}, {0xC8,0x50}, {0xC8,0x51},
+ {0xC8,0x52}, {0xC8,0x53}, {0xC8,0x54}, {0xC8,0x55},
+ {0xC8,0x56}, {0xC8,0x57}, {0xC8,0x58}, {0xC8,0x59},
+ {0xC8,0x5A}, {0xC8,0x5B}, {0xC8,0x5C}, {0xC8,0x5D},
+ {0xC8,0x5E}, {0xC8,0x5F}, {0xC8,0x60}, {0xC8,0x61},
+ {0xC8,0x62}, {0xC8,0x63}, {0xC8,0x64}, {0xC8,0x65},
+ {0xC8,0x66}, {0xC8,0x67}, {0xC8,0x68}, {0xC8,0x69},
+ {0xC8,0x6A}, {0xC8,0x6B}, {0xC8,0x6C}, {0xC8,0x6D},
+ {0xC8,0x6E}, {0xC8,0x6F}, {0xC8,0x70}, {0xC8,0x71},
+ {0xC8,0x72}, {0xC8,0x73}, {0xC8,0x74}, {0xC8,0x75},
+ {0xC8,0x76}, {0xC8,0x77}, {0xC8,0x78}, {0xC8,0x79},
+ {0xC8,0x7A}, {0xC8,0x7B}, {0xC8,0x7C}, {0xC8,0x7D},
+ {0xC8,0x7E}, {0xC8,0xA1}, {0xC8,0xA2}, {0xC8,0xA3},
+ {0xC8,0xA4}, {0xC8,0xA5}, {0xC8,0xA6}, {0xC8,0xA7},
+ {0xC8,0xA8}, {0xC8,0xA9}, {0xC8,0xAA}, {0xC8,0xAB},
+ {0xC8,0xAC}, {0xC8,0xAD}, {0xC8,0xAE}, {0xC8,0xAF},
+ {0xC8,0xB0}, {0xC8,0xB1}, {0xC8,0xB2}, {0xC8,0xB3},
+ {0xC8,0xB4}, {0xC8,0xB5}, {0xC8,0xB6}, {0xC8,0xB7},
+ {0xC8,0xB8}, {0xC8,0xB9}, {0xC8,0xBA}, {0xC8,0xBB},
+ {0xC8,0xBC}, {0xC8,0xBD}, {0xC8,0xBE}, {0xC8,0xBF},
+ {0xC8,0xC0}, {0xC8,0xC1}, {0xC8,0xC2}, {0xC8,0xC3},
+ {0xC8,0xC4}, {0xC8,0xC5}, {0xC8,0xC6}, {0xC8,0xC7},
+ {0xC8,0xC8}, {0xC8,0xC9}, {0xC8,0xCA}, {0xC8,0xCB},
+ {0xC8,0xCC}, {0xC8,0xCD}, {0xC8,0xCE}, {0xC8,0xCF},
+ {0xC8,0xD0}, {0xC8,0xD1}, {0xC8,0xD2}, {0xC8,0xD3},
+ {0xC8,0xD4}, {0xC8,0xD5}, {0xC8,0xD6}, {0xC8,0xD7},
+ {0xC8,0xD8}, {0xC8,0xD9}, {0xC8,0xDA}, {0xC8,0xDB},
+ {0xC8,0xDC}, {0xC8,0xDD}, {0xC8,0xDE}, {0xC8,0xDF},
+ {0xC8,0xE0}, {0xC8,0xE1}, {0xC8,0xE2}, {0xC8,0xE3},
+ {0xC8,0xE4}, {0xC8,0xE5}, {0xC8,0xE6}, {0xC8,0xE7},
+ {0xC8,0xE8}, {0xC8,0xE9}, {0xC8,0xEA}, {0xC8,0xEB},
+ {0xC8,0xEC}, {0xC8,0xED}, {0xC8,0xEE}, {0xC8,0xEF},
+ {0xC8,0xF0}, {0xC8,0xF1}, {0xC8,0xF2}, {0xC8,0xF3},
+ {0xC8,0xF4}, {0xC8,0xF5}, {0xC8,0xF6}, {0xC8,0xF7},
+ {0xC8,0xF8}, {0xC8,0xF9}, {0xC8,0xFA}, {0xC8,0xFB},
+ {0xC8,0xFC}, {0xC8,0xFD}, {0xC8,0xFE}, {0xFF,0x00},
+ {0xB0,0x5A}, {0xA7,0xF3}, {0xA8,0xAE}, {0xB8,0xEB},
+ {0xB7,0xC6}, {0xA6,0xEA}, {0xA5,0x79}, {0x8B,0xF8},
+ {0xC0,0x74}, {0xAB,0xB4}, {0xAA,0xF7}, {0xB3,0xE2},
+ {0xA9,0x60}, {0xC3,0x69}, {0xC4,0xEE}, {0xC3,0xB9},
+ {0xC5,0xDA}, {0xC1,0xB3}, {0xBB,0x72}, {0xC5,0xDE},
+ {0xBC,0xD6}, {0xAC,0xA5}, {0xAF,0x4F}, {0xAF,0x5F},
+ {0xB8,0xA8}, {0xB9,0x54}, {0xC0,0x64}, {0xB6,0xC3},
+ {0xA7,0x5A}, {0xC4,0xE6}, {0xC4,0xEA}, {0xC4,0xF5},
+ {0xC6,0x7D}, {0xB4,0x50}, {0xC0,0xDD}, {0xC2,0xC5},
+ {0xC4,0xB0}, {0xA9,0xD4}, {0xC3,0xBE}, {0xC4,0xFA},
+ {0xB4,0x59}, {0xAE,0xD4}, {0xAE,0xF6}, {0xAF,0x54},
+ {0xA8,0xD3}, {0xA7,0x4E}, {0xB3,0xD2}, {0xBE,0xDB},
+ {0xC3,0x72}, {0xC4,0x6C}, {0xBF,0x63}, {0xA6,0xD1},
+ {0xC4,0xAA}, {0xB8,0xB8}, {0xB8,0xF4}, {0xC5,0x53},
+ {0xBE,0x7C}, {0xC6,0x4F}, {0xB8,0x4C}, {0xB8,0x53},
+ {0xBA,0xF1}, {0xDB,0x77}, {0xBF,0xFD}, {0xB3,0xC0},
+ {0xBD,0xD7}, {0xC3,0x62}, {0xA7,0xCB}, {0xC5,0xA2},
+ {0xC5,0xA4}, {0xA8,0x63}, {0xBD,0x55}, {0xB8,0xEF},
+ {0xB9,0x70}, {0xC2,0x53}, {0xB9,0xF0}, {0xBC,0xD3},
+ {0xB2,0x5C}, {0xBA,0x7C}, {0xB2,0xD6}, {0xC1,0x5C},
+ {0xAD,0xAE}, {0xB0,0xC7}, {0xA6,0xD8}, {0xBB,0xFE},
+ {0xAD,0xE2}, {0xB8,0x57}, {0xBA,0xF0}, {0xB5,0xD9},
+ {0xB3,0xAE}, {0xC5,0xAA}, {0xCE,0xD4}, {0xBC,0xD6},
+ {0xBF,0xD5}, {0xA4,0xA6}, {0xB9,0xE7}, {0xAB,0xE3},
+ {0xB2,0x76}, {0xB2,0xA7}, {0xA5,0x5F}, {0xED,0xA8},
+ {0xAB,0x4B}, {0xB4,0x5F}, {0xA4,0xA3}, {0xAA,0x63},
+ {0xBC,0xC6}, {0xAF,0xC1}, {0xB0,0xD1}, {0xB6,0xEB},
+ {0xAC,0xD9}, {0xB8,0xAD}, {0xBB,0xA1}, {0xB1,0xFE},
+ {0xA8,0xB0}, {0xA8,0x48}, {0xAC,0x42}, {0xAD,0x59},
+ {0xB1,0xB0}, {0xB2,0xA4}, {0xAB,0x47}, {0xA8,0xE2},
+ {0xB1,0xE7}, {0xC2,0xB3}, {0xA8,0x7D}, {0xBD,0xCC},
+ {0xB6,0x71}, {0xC0,0x79}, {0xA7,0x66}, {0xA4,0x6B},
+ {0xC3,0x66}, {0xAE,0xC8}, {0xC2,0x6F}, {0xC4,0x72},
+ {0xBE,0x5B}, {0xC6,0x7A}, {0xC4,0x52}, {0xBE,0xA4},
+ {0xA4,0x4F}, {0xBE,0xE4}, {0xBE,0xFA}, {0xF7,0x65},
+ {0xA6,0x7E}, {0xBC,0xA6}, {0xC5,0xCA}, {0xBC,0xBF},
+ {0xBA,0xA7}, {0xB7,0xD2}, {0xE6,0xA3}, {0xBD,0x6D},
+ {0xC1,0x70}, {0xBD,0xFB}, {0xBD,0xAC}, {0xB3,0x73},
+ {0xC1,0xE5}, {0xA6,0x43}, {0xA6,0x48}, {0xAB,0x7C},
+ {0xAF,0x50}, {0xB5,0xF5}, {0xBB,0xA1}, {0xB7,0x47},
+ {0xA9,0xC0}, {0xB1,0xC9}, {0xC0,0xD4}, {0xC3,0xAE},
+ {0xC2,0x79}, {0xA5,0x4F}, {0xCB,0xF1}, {0xB9,0xE7},
+ {0xC0,0xAD}, {0xCC,0xB0}, {0xAC,0xC2}, {0xBC,0xFC},
+ {0xB2,0xDC}, {0xB2,0xE2}, {0xB9,0x61}, {0xB9,0x73},
+ {0xC6,0x46}, {0xBB,0xE2}, {0xA8,0xD2}, {0xC2,0xA7},
+ {0xC4,0xBF}, {0xC1,0xF5}, {0xB4,0x63}, {0xA4,0x46},
+ {0xB9,0xB1}, {0xBC,0x64}, {0xA7,0xBF}, {0xAE,0xC6},
+ {0xBC,0xD6}, {0xBF,0x52}, {0xC0,0xF8}, {0xE7,0x64},
+ {0xBF,0xF1}, {0xC0,0x73}, {0xB7,0x77}, {0xA8,0xBF},
+ {0xBC,0x42}, {0xCC,0xD8}, {0xAC,0x68}, {0xAC,0x79},
+ {0xB7,0xC8}, {0xAF,0x5B}, {0xAF,0x64}, {0xB2,0xB8},
+ {0xAF,0xC3}, {0xC3,0xFE}, {0xA4,0xBB}, {0xBC,0xAE},
+ {0xB3,0xB0}, {0xAD,0xDB}, {0xB1,0x5B}, {0xB2,0x5F},
+ {0xBD,0xFC}, {0xAB,0xDF}, {0xB7,0x58}, {0xAE,0xDF},
+ {0xB2,0x76}, {0xB6,0xA9}, {0xA7,0x51}, {0xA6,0x4F},
+ {0xBC,0x69}, {0xA9,0xF6}, {0xA7,0xF5}, {0xB1,0xF9},
+ {0xAA,0x64}, {0xB2,0x7A}, {0xB5,0x67}, {0xBF,0xA9},
+ {0xB8,0xCC}, {0xA8,0xBD}, {0xC2,0xF7}, {0xB0,0xCE},
+ {0xB7,0xC4}, {0xA7,0x5B}, {0xBF,0x4D}, {0xBF,0x5A},
+ {0xC4,0xA9}, {0xC5,0xEC}, {0xC5,0xEF}, {0xAA,0x4C},
+ {0xB2,0x4F}, {0xC1,0x7B}, {0xA5,0xDF}, {0xB2,0xC1},
+ {0xB2,0xC9}, {0xAA,0xAC}, {0xAA,0xA5}, {0xC3,0xD1},
+ {0xA4,0xB0}, {0xAF,0xF9}, {0xA8,0xEB}, {0xA4,0xC1},
+ {0xAB,0xD7}, {0xA9,0xDD}, {0xBF,0x7D}, {0xA6,0x76},
+ {0xAC,0x7D}, {0xBC,0xC9}, {0xBF,0xE7}, {0xA6,0xE6},
+ {0xAD,0xB0}, {0xA8,0xA3}, {0xB9,0xF8}, {0xC9,0x4A},
+ {0xDD,0xFC}, {0xB6,0xEF}, {0xB4,0xB8}, {0xE8,0xF9},
+ {0xBD,0xDE}, {0xAF,0x71}, {0xAF,0xAB}, {0xB2,0xBB},
+ {0xBA,0xD6}, {0xB9,0x74}, {0xBA,0xEB}, {0xA6,0xD0},
+ {0xBD,0xD1}, {0xB6,0x68}, {0xB3,0xA3}, {0xB6,0xBA},
+ {0xB9,0x7D}, {0xC0,0x5D}, {0xC5,0x62}, {0xA1,0x4A},
+ {0xA1,0x57}, {0xA1,0x59}, {0xA1,0x5B}, {0xA1,0x5F},
+ {0xA1,0x60}, {0xA1,0x63}, {0xA1,0x64}, {0xA1,0x67},
+ {0xA1,0x68}, {0xA1,0x6B}, {0xA1,0x6C}, {0xA1,0x6F},
+ {0xA1,0x70}, {0xA1,0x73}, {0xA1,0x74}, {0xA1,0x77},
+ {0xA1,0x78}, {0xA1,0x7B}, {0xA1,0x7C}, {0xA1,0xC6},
+ {0xA1,0xC7}, {0xA1,0xCA}, {0xA1,0xCB}, {0xA1,0xC8},
+ {0xA1,0xC9}, {0xA1,0x5C}, {0xA1,0x4D}, {0xA1,0x4E},
+ {0xA1,0x4F}, {0xA1,0x51}, {0xA1,0x52}, {0xA1,0x53},
+ {0xA1,0x54}, {0xA1,0x7D}, {0xA1,0x7E}, {0xA1,0xA1},
+ {0xA1,0xA2}, {0xA1,0xA3}, {0xA1,0xA4}, {0xA1,0xCC},
+ {0xA1,0xCD}, {0xA1,0xCE}, {0xA1,0xDE}, {0xA1,0xDF},
+ {0xA1,0xE0}, {0xA1,0xE1}, {0xA1,0xE2}, {0xA2,0x42},
+ {0xA2,0x4C}, {0xA2,0x4D}, {0xA2,0x4E}, {0xA1,0x49},
+ {0xC8,0xD0}, {0xA1,0xAD}, {0xA2,0x43}, {0xA2,0x48},
+ {0xA1,0xAE}, {0xC8,0xCF}, {0xA1,0x5D}, {0xA1,0x5E},
+ {0xA1,0xAF}, {0xA1,0xCF}, {0xA1,0x41}, {0xA1,0xD0},
+ {0xA1,0x44}, {0xA1,0xFE}, {0xA2,0xAF}, {0xA2,0xB0},
+ {0xA2,0xB1}, {0xA2,0xB2}, {0xA2,0xB3}, {0xA2,0xB4},
+ {0xA2,0xB5}, {0xA2,0xB6}, {0xA2,0xB7}, {0xA2,0xB8},
+ {0xA1,0x47}, {0xA1,0x46}, {0xA1,0xD5}, {0xA1,0xD7},
+ {0xA1,0xD6}, {0xA1,0x48}, {0xA2,0x49}, {0xA2,0xCF},
+ {0xA2,0xD0}, {0xA2,0xD1}, {0xA2,0xD2}, {0xA2,0xD3},
+ {0xA2,0xD4}, {0xA2,0xD5}, {0xA2,0xD6}, {0xA2,0xD7},
+ {0xA2,0xD8}, {0xA2,0xD9}, {0xA2,0xDA}, {0xA2,0xDB},
+ {0xA2,0xDC}, {0xA2,0xDD}, {0xA2,0xDE}, {0xA2,0xDF},
+ {0xA2,0xE0}, {0xA2,0xE1}, {0xA2,0xE2}, {0xA2,0xE3},
+ {0xA2,0xE4}, {0xA2,0xE5}, {0xA2,0xE6}, {0xA2,0xE7},
+ {0xA2,0xE8}, {0xC6,0xE4}, {0xA2,0x40}, {0xC6,0xE5},
+ {0xA1,0x73}, {0xA1,0xC4}, {0xA1,0xA5}, {0xA2,0xE9},
+ {0xA2,0xEA}, {0xA2,0xEB}, {0xA2,0xEC}, {0xA2,0xED},
+ {0xA2,0xEE}, {0xA2,0xEF}, {0xA2,0xF0}, {0xA2,0xF1},
+ {0xA2,0xF2}, {0xA2,0xF3}, {0xA2,0xF4}, {0xA2,0xF5},
+ {0xA2,0xF6}, {0xA2,0xF7}, {0xA2,0xF8}, {0xA2,0xF9},
+ {0xA2,0xFA}, {0xA2,0xFB}, {0xA2,0xFC}, {0xA2,0xFD},
+ {0xA2,0xFE}, {0xA3,0x40}, {0xA3,0x41}, {0xA3,0x42},
+ {0xA3,0x43}, {0xA1,0x61}, {0xA1,0x55}, {0xA1,0x62},
+ {0xA1,0xE3}, {0xA1,0x4E}, {0xA2,0x46}, {0xA2,0x47},
+ {0xC8,0xCD}, {0xA1,0xC3}, {0xC8,0xCE}, {0xA2,0x44},
+ {0xF9,0xFE}, {0x9C,0x71}, {0x93,0x75}, {0x93,0x76},
+ {0x95,0x48}, {0x8E,0xC6}, {0x8B,0xC5}, {0x8B,0xFA},
+ {0xC8,0x7C}, {0x9A,0xB4}, {0x88,0x4E}, {0x88,0x4B},
+ {0xC8,0x7A}, {0x88,0x48}, {0x88,0x47}, {0xA0,0xF6},
+ {0x88,0x45}, {0x88,0x53}, {0xFC,0xAD}, {0x8A,0xAD},
+ {0x92,0x72}, {0xFC,0x47}, {0x94,0xDF}, {0x9F,0xD1},
+ {0xFB,0xCB}, {0x92,0x7D}, {0x98,0xA4}, {0x94,0xE7},
+ {0x90,0xCB}, {0x92,0x7B}, {0x94,0xD8}, {0xFC,0x5F},
+ {0xFA,0x54}, {0x9A,0xB5}, {0x96,0xDA}, {0x92,0x79},
+ {0xFA,0x74}, {0x92,0x75}, {0x8D,0xFB}, {0x8A,0x49},
+ {0x92,0xDF}, {0x9B,0x7C}, {0xFA,0x63}, {0xFA,0x60},
+ {0x92,0x6D}, {0xFA,0x62}, {0x9A,0xB6}, {0x97,0x6B},
+ {0xFD,0x6A}, {0xFD,0x54}, {0x92,0x73}, {0x97,0xD8},
+ {0x9F,0xBB}, {0x93,0x42}, {0x92,0x76}, {0xFA,0x65},
+ {0x92,0x6C}, {0xFA,0x6E}, {0x9E,0xE0}, {0x92,0xC0},
+ {0x92,0xBF}, {0x92,0xBE}, {0x9A,0xBA}, {0x8A,0xB3},
+ {0x97,0x75}, {0xFA,0x40}, {0xFA,0x76}, {0xFB,0xD0},
+ {0xFA,0x7B}, {0xFE,0x6D}, {0x9B,0xB3}, {0x89,0xCC},
+ {0x9A,0xBE}, {0xFA,0x42}, {0x92,0xBC}, {0x94,0x5C},
+ {0x9B,0xB5}, {0x9A,0xBF}, {0x98,0xA7}, {0x97,0xA4},
+ {0x90,0xFD}, {0xFC,0x7B}, {0x9A,0xC0}, {0x92,0xC3},
+ {0x8A,0xAA}, {0x9B,0xD0}, {0x95,0x50}, {0x92,0xC6},
+ {0x98,0xA6}, {0x95,0x46}, {0xFD,0x63}, {0xFA,0xC2},
+ {0x9E,0xC3}, {0x89,0xB2}, {0x9C,0x66}, {0x90,0x53},
+ {0x97,0xC1}, {0x9A,0xC4}, {0x9A,0xC5}, {0x8E,0xEF},
+ {0xFA,0xE9}, {0x92,0x62}, {0x8A,0xF7}, {0x9A,0xC6},
+ {0x92,0xE1}, {0x9A,0xC9}, {0xFA,0xC6}, {0x97,0xA5},
+ {0x9A,0xCB}, {0xFA,0x72}, {0x8A,0x5E}, {0x94,0xE0},
+ {0x92,0xCC}, {0x8A,0xE5}, {0xFE,0x5C}, {0x9A,0xCC},
+ {0x9D,0xF9}, {0x8A,0x43}, {0x8A,0xA6}, {0x9A,0xCD},
+ {0x9A,0xCE}, {0xFA,0xEE}, {0x9B,0xCC}, {0x9A,0xCF},
+ {0x9A,0xD1}, {0x9D,0xFA}, {0x9D,0x7C}, {0x9A,0xD3},
+ {0x97,0xA6}, {0x99,0x5F}, {0xFB,0xF6}, {0x9F,0xC5},
+ {0x8A,0x59}, {0x8B,0x6B}, {0x9A,0xD4}, {0x9A,0xD5},
+ {0x97,0xA2}, {0x8A,0x44}, {0x9F,0x4A}, {0x90,0xA1},
+ {0xFD,0xA4}, {0x8A,0x64}, {0x8A,0xF2}, {0x8A,0xF8},
+ {0x9D,0xD8}, {0x94,0xD6}, {0xFA,0xFE}, {0xFB,0xA7},
+ {0x9A,0xD6}, {0x9F,0x4D}, {0xFA,0xF6}, {0x8A,0x57},
+ {0x8B,0x43}, {0x8B,0x44}, {0x8A,0xB6}, {0x8A,0xC0},
+ {0x9E,0x54}, {0x9A,0xD7}, {0x9A,0xD8}, {0x9A,0xDC},
+ {0x8A,0xCA}, {0x9E,0xA8}, {0x92,0x63}, {0x9A,0xDD},
+ {0x8B,0x65}, {0x8B,0x6F}, {0x8B,0x7E}, {0x8F,0x43},
+ {0x92,0xD0}, {0x8A,0xF4}, {0x9D,0xBE}, {0x9A,0xE1},
+ {0xFC,0xDE}, {0x9D,0xFD}, {0x8B,0x66}, {0x8B,0x70},
+ {0x8B,0x75}, {0x8A,0xE4}, {0x8B,0xA4}, {0x8A,0xED},
+ {0x8A,0x5D}, {0x8B,0x48}, {0x9D,0xED}, {0x9E,0x40},
+ {0x8A,0xEF}, {0x8A,0xF6}, {0x9E,0x76}, {0x9E,0xE3},
+ {0x9A,0xDE}, {0x8D,0xFE}, {0xFA,0xFC}, {0x9C,0xB1},
+ {0x9E,0x77}, {0x8B,0x64}, {0x8B,0x67}, {0x97,0x4B},
+ {0x96,0x53}, {0x9A,0xE0}, {0x8B,0x4A}, {0x8A,0xF1},
+ {0x8A,0xD7}, {0xA0,0xAB}, {0x8A,0xB5}, {0x8A,0x5F},
+ {0x8A,0xEE}, {0x9A,0xDF}, {0x8A,0xFE}, {0x8A,0x58},
+ {0x8B,0xA3}, {0x8B,0xA7}, {0x9A,0xE3}, {0x92,0x61},
+ {0x9D,0xD7}, {0x9E,0x7D}, {0x9E,0xA7}, {0x9E,0xAB},
+ {0x90,0x42}, {0x8B,0x79}, {0x8B,0x7A}, {0x9A,0xE6},
+ {0x9A,0xE5}, {0x8A,0x7E}, {0x9E,0x44}, {0x9A,0xE7},
+ {0x8A,0x7C}, {0x8B,0x71}, {0x9A,0xE9}, {0x9A,0xEA},
+ {0x9A,0xEB}, {0x8A,0xBD}, {0xFB,0x4E}, {0x9A,0xED},
+ {0x8A,0xF9}, {0x9E,0x63}, {0x8B,0x49}, {0x8A,0xCE},
+ {0x8B,0x6E}, {0x8A,0xE8}, {0x9A,0xEE}, {0x92,0xCE},
+ {0x8A,0x5A}, {0x8B,0x7B}, {0x8B,0x7C}, {0x9A,0xEF},
+ {0x9A,0xF0}, {0x8A,0xFA}, {0x89,0x41}, {0x8B,0x72},
+ {0x8A,0xF3}, {0x8B,0xA8}, {0x9E,0xAE}, {0x9E,0x72},
+ {0xFB,0x73}, {0xFB,0x5F}, {0x90,0xBA}, {0x91,0xFE},
+ {0x9E,0xF6}, {0x97,0xED}, {0x9A,0xF3}, {0xA0,0xEE},
+ {0x96,0x7C}, {0x93,0x45}, {0x98,0x6E}, {0xFA,0x56},
+ {0x9A,0xF5}, {0xFC,0x4B}, {0x9A,0xF4}, {0xFE,0xDE},
+ {0xFC,0xB7}, {0x97,0xF1}, {0x97,0xC7}, {0x9C,0xCB},
+ {0x92,0x40}, {0x9C,0xE8}, {0x91,0xFD}, {0x97,0x4E},
+ {0xFB,0x68}, {0x97,0x6C}, {0x8C,0xC2}, {0x97,0xE8},
+ {0xFB,0x6A}, {0x8B,0x74}, {0x8E,0xE7}, {0xFD,0xC8},
+ {0x92,0x41}, {0x96,0xA1}, {0x8E,0xF3}, {0x9A,0xF7},
+ {0x8F,0xA6}, {0xFA,0xD6}, {0x9C,0xC7}, {0xFA,0xD7},
+ {0x9A,0xF8}, {0xFB,0xA1}, {0x8E,0xC5}, {0xFB,0xA4},
+ {0xFB,0xC2}, {0x9A,0xC1}, {0x91,0xFA}, {0xFE,0xDB},
+ {0x97,0xAB}, {0x91,0x47}, {0xFB,0xB1}, {0x8F,0xEA},
+ {0x94,0xD2}, {0xFE,0x61}, {0xFA,0xCE}, {0x92,0xED},
+ {0x91,0xF3}, {0x93,0xC6}, {0x93,0x5A}, {0xFA,0xFB},
+ {0x92,0xEF}, {0xFA,0xC8}, {0x98,0x47}, {0x93,0x66},
+ {0x98,0x55}, {0x96,0xE6}, {0x9F,0x43}, {0x9F,0xAA},
+ {0x94,0xDA}, {0x92,0xEE}, {0xFC,0xAF}, {0xFB,0xFB},
+ {0x8E,0xF9}, {0x91,0xF6}, {0x93,0x64}, {0x94,0xF5},
+ {0x9C,0xB6}, {0xFB,0xAD}, {0x98,0x4E}, {0x8F,0x44},
+ {0x96,0xFD}, {0x9A,0xF9}, {0x9A,0xFA}, {0x97,0x69},
+ {0x95,0xD4}, {0x98,0x4B}, {0xFB,0xAA}, {0x98,0x7C},
+ {0x91,0xEA}, {0x9D,0xAF}, {0x9D,0xC5}, {0x91,0xF1},
+ {0x8E,0xB1}, {0x97,0xA9}, {0xFB,0xAC}, {0xFC,0xB8},
+ {0x9C,0xB9}, {0xFB,0xB0}, {0xFC,0xD2}, {0x93,0xCB},
+ {0x9A,0xFD}, {0x91,0xF4}, {0x8B,0xAC}, {0xA0,0x55},
+ {0x95,0x74}, {0x95,0xBE}, {0x97,0xAD}, {0x8E,0xE9},
+ {0x92,0xF8}, {0x97,0xBE}, {0x91,0x6C}, {0x94,0xAA},
+ {0xFC,0x63}, {0x9D,0xC6}, {0x97,0xB5}, {0x92,0xB8},
+ {0x91,0xEF}, {0xFE,0xA6}, {0x97,0x60}, {0x93,0x58},
+ {0x95,0x76}, {0x8F,0xAC}, {0x91,0xEC}, {0x97,0xB4},
+ {0x91,0xF7}, {0x97,0x4A}, {0xFB,0x49}, {0x95,0x78},
+ {0x93,0xBC}, {0x91,0xD6}, {0x93,0x55}, {0x93,0x56},
+ {0x98,0x51}, {0x8F,0xF8}, {0xFB,0xC0}, {0x93,0xF2},
+ {0x90,0xD0}, {0x9C,0x44}, {0x92,0x55}, {0x93,0x63},
+ {0x91,0xA5}, {0xA0,0xED}, {0xFD,0x6B}, {0x9A,0xFE},
+ {0x93,0x51}, {0x8C,0x57}, {0xFA,0x78}, {0xFE,0xA8},
+ {0x93,0x50}, {0xFA,0x4C}, {0x92,0xF7}, {0x9B,0x40},
+ {0xFB,0xCE}, {0x9B,0x41}, {0xFE,0xAD}, {0xFB,0xD5},
+ {0x8B,0xC2}, {0x9A,0x7C}, {0x9B,0x42}, {0x9B,0x43},
+ {0x9E,0x79}, {0xFB,0xD9}, {0x9B,0x44}, {0xA0,0xA7},
+ {0x9B,0xF3}, {0x8C,0x79}, {0x93,0x5E}, {0x89,0xCB},
+ {0x9F,0x53}, {0x93,0xD7}, {0xFB,0xE1}, {0xFE,0xD0},
+ {0xFB,0xE2}, {0xFC,0xE3}, {0x90,0x74}, {0xFB,0xE6},
+ {0x9B,0xB7}, {0x9B,0x45}, {0x9B,0x47}, {0x9F,0x50},
+ {0x9B,0x48}, {0xFC,0x5B}, {0x98,0xA9}, {0x9C,0xFD},
+ {0x88,0x4C}, {0x9B,0x4B}, {0xFB,0xEC}, {0x8C,0x69},
+ {0x9B,0xA8}, {0x8A,0xD5}, {0xFA,0x73}, {0xFD,0x59},
+ {0x91,0xA2}, {0xFB,0xED}, {0x9C,0xA9}, {0x8A,0xA8},
+ {0x9B,0xC3}, {0x8A,0xE1}, {0x9B,0x4E}, {0x95,0xD0},
+ {0x90,0x5F}, {0x97,0xEE}, {0xFC,0x4E}, {0x9B,0x4F},
+ {0x9B,0x50}, {0x9E,0xC6}, {0xFC,0x50}, {0xFD,0x73},
+ {0xFD,0xA7}, {0x9D,0xA2}, {0xFA,0x58}, {0xFA,0x5E},
+ {0xA0,0x59}, {0xFA,0x75}, {0xFB,0xBE}, {0x9C,0xA2},
+ {0x93,0x70}, {0x93,0x71}, {0x93,0x77}, {0xFE,0xEF},
+ {0x93,0x6D}, {0xFC,0x5D}, {0x90,0xB8}, {0x8A,0xFC},
+ {0xFB,0x41}, {0x9E,0x6B}, {0x94,0xE3}, {0x8E,0xE2},
+ {0x8C,0x7D}, {0x8E,0xD7}, {0x9C,0x4D}, {0x96,0xA3},
+ {0x9B,0x51}, {0x8A,0xC3}, {0x96,0xAA}, {0xFC,0x68},
+ {0x8B,0x6D}, {0xFD,0x67}, {0x8A,0xE9}, {0xFC,0xA1},
+ {0x93,0x6C}, {0x9B,0x52}, {0xFE,0x70}, {0xFC,0xA8},
+ {0xFC,0xE9}, {0x9C,0xB4}, {0x8A,0xEA}, {0x9B,0x53},
+ {0x9B,0x55}, {0x96,0xAB}, {0xFC,0xA7}, {0x9B,0x56},
+ {0x8A,0xBC}, {0x8A,0xCB}, {0x9B,0x57}, {0x89,0xCD},
+ {0x9B,0x59}, {0x9B,0x5B}, {0x93,0xA5}, {0x9B,0x5D},
+ {0x9E,0x4F}, {0x93,0xA3}, {0x8A,0x7B}, {0x8B,0x42},
+ {0x97,0x50}, {0x8F,0xB3}, {0x8A,0x50}, {0x9B,0x60},
+ {0x8B,0x45}, {0x8B,0x46}, {0x9D,0xFE}, {0x9B,0x62},
+ {0x93,0x7B}, {0x93,0xB1}, {0x8A,0x60}, {0x8A,0xD8},
+ {0x9B,0x63}, {0x8A,0x69}, {0x8A,0x47}, {0x8A,0xCC},
+ {0x93,0x7C}, {0x9B,0x65}, {0x9B,0x66}, {0x8A,0x72},
+ {0x8A,0x7A}, {0x93,0xAF}, {0x8A,0xB0}, {0x9B,0x68},
+ {0x9E,0xA3}, {0xFA,0xEC}, {0x8B,0x77}, {0x9B,0x67},
+ {0x8B,0x59}, {0xFC,0xB1}, {0xFC,0xBB}, {0x9B,0x69},
+ {0x93,0xA8}, {0x8A,0xE0}, {0x9E,0x51}, {0x8F,0x5F},
+ {0x9B,0x6A}, {0x9B,0x6B}, {0x97,0xEC}, {0x9B,0x6C},
+ {0xFE,0x4E}, {0xFD,0xC2}, {0x9B,0x6D}, {0x91,0x67},
+ {0xFC,0xCC}, {0x93,0xB6}, {0x90,0xE4}, {0x90,0xE5},
+ {0x9E,0xF2}, {0x93,0xCA}, {0x8B,0xBC}, {0x8F,0x46},
+ {0x93,0xCF}, {0xFC,0xDB}, {0xFC,0xDC}, {0x93,0xC0},
+ {0xFC,0xE6}, {0x96,0xE7}, {0xFC,0xD8}, {0xFC,0xD9},
+ {0xFD,0xA6}, {0x93,0xCE}, {0x95,0xF1}, {0x9C,0xE9},
+ {0xFC,0xE4}, {0x94,0xAF}, {0xFA,0x77}, {0x93,0xCC},
+ {0x90,0x5A}, {0x8C,0x54}, {0x93,0xBF}, {0xFB,0x51},
+ {0x93,0xB9}, {0xFE,0xD7}, {0x93,0xB7}, {0x93,0xD9},
+ {0x93,0xBB}, {0x93,0xDA}, {0x98,0xA3}, {0x90,0xD1},
+ {0x9B,0x6E}, {0xFA,0x70}, {0x9B,0xEB}, {0x9B,0x6F},
+ {0xFC,0xFC}, {0x8B,0x40}, {0xA0,0x7B}, {0x8C,0xA1},
+ {0x97,0xF7}, {0x93,0xE2}, {0xFC,0xD6}, {0x95,0x59},
+ {0x93,0xA6}, {0xFD,0x40}, {0x93,0x5F}, {0x97,0xF2},
+ {0x9C,0x76}, {0x8E,0xF8}, {0x8F,0x47}, {0x9B,0x74},
+ {0x92,0xB4}, {0x91,0xED}, {0x96,0xD2}, {0xFD,0x46},
+ {0x8F,0x4F}, {0x95,0x49}, {0x9B,0x75}, {0xFA,0x5C},
+ {0x9B,0x79}, {0xFD,0x4B}, {0x96,0xD3}, {0xFD,0x58},
+ {0x94,0x5F}, {0xA0,0xF5}, {0x92,0x43}, {0x97,0xFA},
+ {0x9D,0xD9}, {0x97,0xF4}, {0x92,0x4D}, {0xFD,0x5B},
+ {0x9B,0x7A}, {0x9E,0xD5}, {0xFA,0xAE}, {0x9C,0xC9},
+ {0x92,0x58}, {0x8E,0xC8}, {0x94,0xB4}, {0x93,0xE1},
+ {0x93,0xDF}, {0xFC,0xF0}, {0x93,0xEC}, {0x97,0xF6},
+ {0x96,0xCF}, {0x93,0xDE}, {0x8A,0xCF}, {0x9B,0xA2},
+ {0xFD,0x69}, {0x93,0x52}, {0x98,0xA2}, {0xFD,0x6E},
+ {0x8C,0xA4}, {0xFA,0x7C}, {0x93,0xFA}, {0x90,0x7C},
+ {0x8F,0x67}, {0x9D,0xB7}, {0xA0,0xE9}, {0xFA,0x4E},
+ {0xFD,0xA1}, {0x9E,0x74}, {0x9F,0xBF}, {0x9E,0xCB},
+ {0x9B,0xB9}, {0x9D,0xD4}, {0x97,0xB9}, {0x8E,0xF1},
+ {0x95,0x7B}, {0x9E,0xD2}, {0x97,0x53}, {0x96,0xA4},
+ {0x8F,0xBE}, {0x94,0xD9}, {0x90,0x58}, {0xFD,0x79},
+ {0xFD,0x7B}, {0x8E,0xDA}, {0x8E,0xFA}, {0x9B,0xA5},
+ {0x9E,0xD9}, {0x97,0xD4}, {0x90,0xBB}, {0xFD,0xBC},
+ {0xFD,0xC6}, {0x92,0x48}, {0x92,0xB5}, {0x9D,0xC1},
+ {0x92,0xB9}, {0x92,0xA6}, {0x8F,0x4B}, {0x9B,0xA6},
+ {0x92,0xB6}, {0x8E,0x40}, {0x9E,0xD8}, {0x94,0x5E},
+ {0x98,0x5F}, {0x94,0xCE}, {0x92,0x4A}, {0xFD,0x70},
+ {0x94,0x67}, {0x8D,0xEC}, {0x9B,0xD8}, {0x94,0x48},
+ {0xFA,0xC1}, {0x9C,0xF7}, {0xFD,0xBE}, {0x8F,0xDA},
+ {0xFD,0xD9}, {0xFC,0x7E}, {0x93,0xF9}, {0xFA,0x43},
+ {0xFA,0xEB}, {0xFA,0xC3}, {0x97,0xD3}, {0x95,0xF9},
+ {0x9C,0x48}, {0xFD,0xD8}, {0xA0,0xD8}, {0xFD,0xD7},
+ {0xFB,0x4A}, {0x9B,0xAF}, {0x94,0x4B}, {0xFD,0xC9},
+ {0x8E,0xAC}, {0xFD,0xB2}, {0x92,0x5A}, {0xFC,0xBD},
+ {0x92,0xD9}, {0xFD,0xD5}, {0x92,0xDD}, {0x92,0x59},
+ {0x96,0xBA}, {0x92,0x5B}, {0x9B,0xAB}, {0xFD,0xDA},
+ {0xFD,0xDE}, {0xFD,0xD3}, {0x8C,0x46}, {0xFD,0xD6},
+ {0xFD,0xDC}, {0xFD,0xDD}, {0x90,0xFE}, {0xFE,0xA1},
+ {0x8B,0xAD}, {0x9C,0xD8}, {0x9E,0x6D}, {0xFD,0x7C},
+ {0xFB,0x61}, {0x96,0xF8}, {0x96,0xF0}, {0xFC,0xF4},
+ {0xFE,0x60}, {0x98,0x52}, {0x96,0x4F}, {0x91,0x6E},
+ {0x98,0x6D}, {0x98,0x64}, {0x94,0x53}, {0xFD,0xEC},
+ {0xFB,0x78}, {0x95,0xBA}, {0x98,0x5D}, {0x92,0xF9},
+ {0x98,0x5A}, {0xFD,0xF6}, {0x93,0xD0}, {0x98,0x62},
+ {0x9B,0xAD}, {0x97,0x4F}, {0x9B,0xAE}, {0x94,0x52},
+ {0x9B,0xB0}, {0x91,0xD2}, {0x97,0xEA}, {0xFB,0x6B},
+ {0x91,0xB1}, {0xFD,0xF3}, {0x92,0xCB}, {0x9B,0xB1},
+ {0xFC,0xEC}, {0x98,0x6B}, {0x97,0x51}, {0x98,0x71},
+ {0x95,0xEF}, {0x9E,0xF3}, {0x91,0xE8}, {0x9B,0xBA},
+ {0xFB,0x4C}, {0x92,0x6A}, {0xFD,0xF8}, {0x98,0x61},
+ {0x91,0xE7}, {0x93,0xED}, {0x97,0x44}, {0x91,0xE1},
+ {0xFB,0xF5}, {0x98,0x69}, {0x8A,0x62}, {0x9B,0xBB},
+ {0x8C,0xA8}, {0x9C,0x55}, {0x8E,0x77}, {0x8A,0xB2},
+ {0x9E,0xBC}, {0x93,0xE6}, {0x93,0xA2}, {0x9B,0xBD},
+ {0x94,0xB3}, {0x93,0x7D}, {0x9E,0x66}, {0x94,0x59},
+ {0x9B,0xBF}, {0x94,0x58}, {0x9E,0xA5}, {0x9B,0xC7},
+ {0xFE,0x54}, {0x8E,0x74}, {0x8B,0xD6}, {0x94,0xB6},
+ {0xFD,0x74}, {0x98,0xC0}, {0x94,0xA5}, {0x9B,0xC8},
+ {0x95,0xED}, {0xFD,0x7E}, {0xFB,0xEB}, {0xFD,0x7D},
+ {0x97,0x6F}, {0x94,0x61}, {0x9F,0xC1}, {0x95,0xD7},
+ {0xFA,0x52}, {0x9C,0x58}, {0x9F,0x68}, {0x9B,0xE7},
+ {0xFC,0xCE}, {0x96,0xE8}, {0xFA,0x49}, {0x97,0xA1},
+ {0x95,0x4D}, {0x9E,0xF8}, {0xFE,0x49}, {0x91,0xCE},
+ {0x97,0x71}, {0x8C,0xCF}, {0xFD,0xB1}, {0xFC,0x6E},
+ {0x9C,0xF2}, {0x93,0xB8}, {0x90,0x43}, {0x97,0x59},
+ {0x94,0xD7}, {0xFE,0x66}, {0x94,0x7D}, {0xFC,0x6F},
+ {0x92,0x46}, {0xFA,0x6D}, {0x8E,0xF7}, {0xFB,0xB7},
+ {0x94,0x7C}, {0x92,0xCD}, {0x97,0xB2}, {0xFE,0x65},
+ {0x96,0x7E}, {0x97,0x58}, {0x9B,0x77}, {0x91,0xCF},
+ {0x94,0xA4}, {0x9C,0xAD}, {0x8B,0xAB}, {0x96,0xD5},
+ {0xFC,0xB3}, {0x93,0xAE}, {0x97,0x6D}, {0x94,0x46},
+ {0x95,0xF7}, {0x9C,0x46}, {0x95,0x5B}, {0x91,0xD1},
+ {0x94,0xF4}, {0xFE,0x67}, {0x92,0xA5}, {0xFE,0xDF},
+ {0x8C,0xAB}, {0x9B,0xC9}, {0xFC,0xED}, {0xFD,0xFA},
+ {0xFC,0xC8}, {0xFE,0x62}, {0x91,0xFC}, {0xFE,0x6B},
+ {0xFD,0xF9}, {0xFC,0xC7}, {0x91,0x4E}, {0x9C,0xB8},
+ {0x97,0x67}, {0x95,0xEE}, {0x9B,0xB2}, {0x94,0x60},
+ {0x94,0xA2}, {0x98,0x75}, {0x97,0xAC}, {0x91,0xD3},
+ {0x98,0x7B}, {0x8E,0xEB}, {0x97,0x6A}, {0x96,0x5E},
+ {0x97,0xEB}, {0x9F,0xF9}, {0x95,0xF8}, {0xFE,0xA2},
+ {0x8F,0xE6}, {0xFE,0x7E}, {0x9D,0xA4}, {0x97,0x68},
+ {0x8E,0xEC}, {0x94,0xBD}, {0x94,0x5B}, {0x9C,0xF6},
+ {0xFA,0xA7}, {0x9B,0xD9}, {0xFA,0x5D}, {0x96,0x56},
+ {0x97,0x62}, {0x94,0xBA}, {0xA0,0x4F}, {0x92,0xD8},
+ {0x9B,0xCB}, {0x94,0xBB}, {0x9D,0x5F}, {0x90,0xCF},
+ {0x94,0x65}, {0x9F,0x4C}, {0x90,0xD8}, {0x9E,0xBE},
+ {0xFB,0x6D}, {0x95,0xCA}, {0x9D,0xC2}, {0x97,0xF8},
+ {0x8F,0xFC}, {0x94,0x73}, {0x94,0x74}, {0xFE,0xB7},
+ {0x8A,0x4B}, {0x8A,0x55}, {0x8B,0x69}, {0x8A,0xDC},
+ {0x8B,0x76}, {0x9B,0xCE}, {0x8A,0x68}, {0xA0,0xF8},
+ {0x98,0xDF}, {0xFE,0xB5}, {0x9B,0xCF}, {0x96,0xFB},
+ {0x9B,0xFB}, {0x9E,0xCE}, {0x8E,0xE5}, {0x9E,0x7B},
+ {0x9B,0xD2}, {0x8A,0xA5}, {0xFE,0xCE}, {0x8A,0x45},
+ {0x9D,0xFC}, {0xFE,0xCF}, {0x8B,0xA5}, {0x8C,0x4A},
+ {0x8A,0xEC}, {0xFC,0xE0}, {0x94,0xAD}, {0xFE,0xD5},
+ {0x94,0xAC}, {0xFC,0x5A}, {0x9B,0xD6}, {0x8A,0x6F},
+ {0x8B,0xA9}, {0x8E,0x5F}, {0x9D,0xCB}, {0xFC,0xE7},
+ {0x9B,0xD7}, {0x93,0xC8}, {0x91,0xF0}, {0x8F,0xE0},
+ {0x9B,0xDB}, {0x90,0xED}, {0x9B,0xDC}, {0xA0,0xEC},
+ {0x98,0xFA}, {0x9B,0xE0}, {0x93,0xC7}, {0x92,0x49},
+ {0x96,0xE1}, {0x9B,0xE2}, {0x9B,0xE4}, {0x8F,0xE1},
+ {0x9B,0xE5}, {0x94,0xC0}, {0x93,0xC3}, {0x93,0xC5},
+ {0x90,0x79}, {0x97,0x7B}, {0x90,0x7E}, {0xFE,0xE6},
+ {0xFE,0x46}, {0x9D,0xB8}, {0x92,0x70}, {0x95,0xA8},
+ {0x8C,0xB0}, {0x94,0xC8}, {0x98,0xB9}, {0x91,0x40},
+ {0xFC,0xBE}, {0x91,0x57}, {0x8B,0xB2}, {0xFA,0xDF},
+ {0x9B,0xE6}, {0x96,0x43}, {0x8E,0x44}, {0x9C,0x4F},
+ {0xFE,0xF4}, {0x9B,0xE8}, {0x93,0xDC}, {0x96,0x6F},
+ {0x8E,0x4A}, {0x9B,0xED}, {0x92,0xF6}, {0x9D,0xB9},
+ {0x8E,0x4E}, {0xFB,0xCF}, {0x9E,0xC2}, {0x94,0xE5},
+ {0x9B,0xF0}, {0x94,0xE4}, {0x95,0x51}, {0x8B,0xBB},
+ {0x9B,0xF1}, {0x94,0xF0}, {0x8E,0x64}, {0x94,0xEA},
+ {0x8F,0x61}, {0x9B,0x64}, {0x8E,0x5B}, {0x9B,0xF2},
+ {0x9F,0xBE}, {0x9D,0xC9}, {0x8E,0x6C}, {0x8F,0x73},
+ {0x8C,0xAF}, {0x8F,0x75}, {0x8E,0x71}, {0x8E,0x60},
+ {0x8E,0x6A}, {0x8C,0x4C}, {0x95,0x52}, {0x95,0x54},
+ {0x8A,0xD4}, {0x9D,0xBB}, {0x95,0x43}, {0x92,0xFE},
+ {0x94,0xF2}, {0x94,0xF1}, {0xA0,0xEA}, {0x9D,0xD2},
+ {0xA0,0xB1}, {0x91,0xF8}, {0x94,0x62}, {0x9B,0xA4},
+ {0x8E,0xAD}, {0x9E,0xAD}, {0x96,0xD0}, {0xFE,0xEE},
+ {0x8A,0xB4}, {0x97,0x57}, {0x8A,0x77}, {0x9B,0xF7},
+ {0x8E,0xB5}, {0xA0,0x6D}, {0x8E,0xB6}, {0x97,0x56},
+ {0x95,0x40}, {0xA0,0xF3}, {0x94,0xBE}, {0x9B,0xFA},
+ {0xFD,0xDF}, {0x9D,0xBC}, {0x94,0xFE}, {0x8B,0xDB},
+ {0xA0,0xFE}, {0x8E,0xC0}, {0x9F,0x47}, {0x8B,0xDE},
+ {0xA0,0xFB}, {0x8E,0xC3}, {0x96,0x49}, {0xFE,0xC2},
+ {0x95,0x4C}, {0x9B,0xFD}, {0x90,0xCC}, {0x9C,0x60},
+ {0x95,0x4B}, {0x9B,0xFE}, {0x9C,0x70}, {0x9C,0x43},
+ {0x9C,0x47}, {0x8E,0xCC}, {0x8E,0x54}, {0x8E,0xE4},
+ {0x9C,0x49}, {0x8B,0x5E}, {0x95,0x5E}, {0x95,0x5C},
+ {0x9C,0x4B}, {0x8B,0xE1}, {0x8E,0xD9}, {0x9D,0xB4},
+ {0x92,0x5F}, {0x9C,0x4C}, {0x8A,0xA1}, {0x8E,0xDB},
+ {0x9C,0x56}, {0x8A,0xA2}, {0x97,0x54}, {0x9C,0x5E},
+ {0x9E,0xD4}, {0x95,0x68}, {0xA0,0xC3}, {0x8A,0xE6},
+ {0xA0,0xF7}, {0x9C,0x61}, {0x9C,0x5F}, {0xFC,0x4D},
+ {0x9E,0x5B}, {0x9E,0x69}, {0x9C,0x63}, {0xFE,0xC7},
+ {0xFE,0xC6}, {0x9C,0x67}, {0x9C,0x69}, {0x8B,0xE2},
+ {0x91,0x65}, {0x9C,0xE7}, {0x8A,0x54}, {0x9C,0x6C},
+ {0x9C,0x6E}, {0xFE,0x5D}, {0x9C,0x73}, {0x95,0x6A},
+ {0x95,0x6D}, {0x8E,0xF0}, {0x8F,0x4D}, {0x8E,0xF6},
+ {0xFA,0xBC}, {0x8C,0xD5}, {0xFB,0xDA}, {0x8B,0x4C},
+ {0xFD,0x75}, {0x9B,0xDD}, {0xFA,0xF5}, {0x9C,0x74},
+ {0x95,0x45}, {0x96,0xC6}, {0x8F,0x6A}, {0x8F,0x4E},
+ {0x9C,0x78}, {0xFA,0x55}, {0x97,0xE4}, {0x9C,0x41},
+ {0x92,0x5C}, {0x96,0xFA}, {0xFB,0x66}, {0x8E,0x65},
+ {0x98,0x49}, {0xFB,0xA8}, {0x98,0x42}, {0x9C,0x7A},
+ {0x97,0xFB}, {0x90,0xCA}, {0x9C,0x5B}, {0x97,0x4D},
+ {0x8E,0xD3}, {0x95,0x61}, {0x9F,0x4B}, {0x9F,0xB5},
+ {0x93,0xD2}, {0xFD,0xAA}, {0x98,0x40}, {0x91,0x46},
+ {0x98,0x67}, {0xFA,0x5A}, {0xFB,0xA9}, {0x98,0x41},
+ {0x8C,0xD3}, {0xFC,0xFD}, {0xFD,0xAB}, {0x91,0xBD},
+ {0x8F,0x4C}, {0x96,0xC9}, {0x8F,0x55}, {0xFB,0xAE},
+ {0x95,0x6F}, {0x9C,0x7D}, {0xA0,0xF0}, {0x94,0x6F},
+ {0xFD,0xAC}, {0x96,0xCB}, {0x96,0xCE}, {0xA0,0x56},
+ {0x9C,0xE1}, {0x96,0xC4}, {0x8F,0x5E}, {0x8F,0x6C},
+ {0x8E,0xA3}, {0xFB,0xB3}, {0xFC,0x53}, {0xFD,0xB3},
+ {0x8F,0x6B}, {0x96,0xCA}, {0x8F,0x79}, {0x9E,0x6F},
+ {0xA0,0xC5}, {0xFC,0x78}, {0x8E,0x42}, {0x8F,0x5A},
+ {0x90,0xC2}, {0x8E,0xA5}, {0x90,0x61}, {0x92,0x4F},
+ {0x93,0x73}, {0xFD,0xB5}, {0xFE,0xCC}, {0xFB,0xBD},
+ {0x8C,0xD6}, {0x98,0x43}, {0x96,0xC5}, {0x89,0xBC},
+ {0x9C,0xA3}, {0x92,0x4B}, {0x98,0x4A}, {0x8F,0xA4},
+ {0xA0,0xF1}, {0x9E,0xFB}, {0x9C,0xD2}, {0x8F,0xA7},
+ {0xFC,0x5C}, {0x98,0x45}, {0x90,0x46}, {0x8C,0xD1},
+ {0xFE,0xFA}, {0x95,0x60}, {0x9F,0x48}, {0x92,0x47},
+ {0x90,0xFB}, {0x9C,0xA4}, {0x95,0x71}, {0x9C,0xA6},
+ {0x9C,0xA7}, {0x9C,0xAA}, {0x9E,0xD3}, {0x9E,0x70},
+ {0x9C,0xAC}, {0x8F,0xAE}, {0x95,0x7D}, {0x9C,0xB0},
+ {0x97,0xB6}, {0xA0,0xBD}, {0x8A,0xDF}, {0x9E,0xAA},
+ {0x8F,0xBD}, {0x8F,0xBF}, {0x93,0x69}, {0x9B,0xA7},
+ {0xC8,0xA4}, {0xFE,0xEA}, {0x9B,0xE1}, {0x8B,0x41},
+ {0x9D,0xB6}, {0xA0,0xEB}, {0x9B,0xA3}, {0x8B,0xA1},
+ {0x8F,0xC8}, {0x89,0x4C}, {0x98,0x60}, {0x94,0xC7},
+ {0x8B,0x58}, {0x95,0xAB}, {0x95,0xAA}, {0x9C,0xC3},
+ {0x9C,0xC4}, {0x93,0xD6}, {0x9D,0xAC}, {0x8B,0xE6},
+ {0x8A,0x71}, {0x8F,0xD1}, {0x99,0xD5}, {0x90,0xF4},
+ {0x8A,0xA3}, {0x9C,0xCE}, {0x9C,0xD4}, {0x9C,0xD5},
+ {0xFB,0xC8}, {0x9D,0xB3}, {0xFC,0x70}, {0x8F,0xD7},
+ {0x9B,0x73}, {0xFA,0x5B}, {0x8F,0xD2}, {0x90,0x64},
+ {0x98,0xB6}, {0x96,0x68}, {0x9C,0xD6}, {0x98,0xBD},
+ {0x8F,0xDC}, {0xFE,0xF6}, {0x8F,0xD9}, {0x95,0x41},
+ {0x97,0xF3}, {0x9B,0xF8}, {0x9E,0x6C}, {0x8F,0xF2},
+ {0x8F,0xEE}, {0x9C,0xD7}, {0x9E,0x6E}, {0x8A,0x40},
+ {0x8F,0xEF}, {0x8F,0xF4}, {0x8F,0xF5}, {0x95,0xC2},
+ {0x98,0x6A}, {0x97,0xCF}, {0x9E,0x7C}, {0x90,0x41},
+ {0x9C,0xDB}, {0x94,0x41}, {0x9C,0xE6}, {0x9D,0xB0},
+ {0x9C,0xEA}, {0x9C,0xED}, {0x9C,0xFA}, {0x8B,0x62},
+ {0x8A,0x4E}, {0x9C,0xCA}, {0x8A,0x66}, {0x9C,0xFB},
+ {0x9C,0xFC}, {0x9C,0xFE}, {0x8A,0x53}, {0x9C,0xE5},
+ {0x9D,0x40}, {0x9D,0x41}, {0x90,0x45}, {0x8B,0x73},
+ {0x97,0xCA}, {0x9D,0x42}, {0x8A,0x61}, {0x8B,0xAE},
+ {0x8A,0xD2}, {0x8B,0xA2}, {0x9D,0xF2}, {0x9D,0x43},
+ {0x9C,0xDF}, {0x9D,0x44}, {0x8E,0xCA}, {0x90,0x4E},
+ {0x8E,0xB3}, {0x9F,0xF5}, {0x9D,0x45}, {0x90,0x4F},
+ {0x9D,0x47}, {0x89,0xCA}, {0x9C,0xB5}, {0xFB,0xFE},
+ {0x90,0x5E}, {0x90,0x63}, {0x90,0x57}, {0x90,0x66},
+ {0x9B,0xC0}, {0xFC,0xE5}, {0x91,0x62}, {0x90,0x67},
+ {0x8F,0xA1}, {0x8F,0xA2}, {0x9D,0x48}, {0xFA,0xD3},
+ {0x90,0x5D}, {0x90,0xB9}, {0x90,0x6B}, {0x8C,0x5C},
+ {0x90,0x69}, {0xFE,0x57}, {0xFE,0x55}, {0x90,0x73},
+ {0x9B,0xEF}, {0x9C,0xF0}, {0x9D,0x4B}, {0xFE,0xD9},
+ {0xFE,0xDA}, {0x91,0xE0}, {0x91,0xD8}, {0x96,0x46},
+ {0x93,0x60}, {0xFA,0x53}, {0x9C,0xD3}, {0x9D,0x4E},
+ {0xFB,0x40}, {0x8D,0xE2}, {0x94,0x42}, {0x90,0x56},
+ {0x98,0x65}, {0x8C,0x6C}, {0xFA,0x4A}, {0x9D,0x50},
+ {0x9D,0x52}, {0x95,0xAF}, {0x97,0x5A}, {0x93,0x49},
+ {0x97,0x47}, {0xA0,0xF4}, {0x97,0x78}, {0x8F,0xCF},
+ {0xFC,0x60}, {0x8C,0x4E}, {0xFC,0x56}, {0x91,0xDC},
+ {0x96,0x61}, {0x92,0xEC}, {0x93,0x5D}, {0x8E,0xDE},
+ {0x96,0xFE}, {0xFD,0x4F}, {0x95,0xDE}, {0x98,0xB0},
+ {0xA0,0x40}, {0x97,0xBD}, {0x97,0x7D}, {0x97,0xF5},
+ {0x9B,0xAC}, {0xFA,0xDA}, {0x92,0xC2}, {0x97,0xB1},
+ {0x90,0x7B}, {0x93,0xFE}, {0x94,0x7B}, {0x97,0x77},
+ {0xFA,0xBE}, {0xFD,0x43}, {0x90,0xC6}, {0x90,0xA4},
+ {0x90,0xA8}, {0x94,0xA9}, {0x90,0xA9}, {0x8C,0x65},
+ {0x95,0xE0}, {0x90,0x7D}, {0x92,0x65}, {0xFD,0xBA},
+ {0x93,0xC4}, {0xFE,0xED}, {0x9D,0xAB}, {0xA0,0xE3},
+ {0x96,0x48}, {0x9D,0x53}, {0x8A,0xA9}, {0x9B,0xC5},
+ {0x96,0x5D}, {0x97,0x5F}, {0x96,0x5F}, {0x96,0x6E},
+ {0xFB,0x5D}, {0x9D,0xB1}, {0xFE,0xA3}, {0x9D,0xB2},
+ {0x95,0xAE}, {0xFC,0xA3}, {0xA0,0xA2}, {0x96,0x55},
+ {0x9D,0x54}, {0x93,0x41}, {0x95,0xAD}, {0x91,0xD5},
+ {0x97,0x7A}, {0xFD,0xFC}, {0x8E,0x47}, {0x93,0xFD},
+ {0x90,0xA5}, {0x90,0xAC}, {0x95,0xAC}, {0x90,0xAE},
+ {0xFE,0xA5}, {0x9D,0x56}, {0x97,0xE3}, {0x95,0xE2},
+ {0x94,0x66}, {0x96,0x47}, {0x91,0xB8}, {0x9C,0xEC},
+ {0x90,0xAD}, {0x95,0xE3}, {0x8B,0x4F}, {0x8A,0xE3},
+ {0x8B,0x4D}, {0x95,0xEA}, {0x8B,0x4E}, {0x8C,0xC1},
+ {0x8B,0xED}, {0x91,0xD9}, {0xA0,0xA4}, {0x95,0xF5},
+ {0x95,0xF4}, {0x9F,0xB3}, {0xFE,0xAF}, {0xFE,0x72},
+ {0x92,0x7A}, {0xFE,0xAC}, {0x95,0xF3}, {0x9D,0x58},
+ {0x93,0x72}, {0x91,0xC5}, {0x96,0x42}, {0x90,0xCD},
+ {0x95,0xFE}, {0x91,0x59}, {0x9C,0x65}, {0x97,0xCC},
+ {0x90,0xCE}, {0x9D,0x59}, {0xFC,0xF5}, {0xFE,0xFD},
+ {0x9D,0x5B}, {0x9D,0x5C}, {0x93,0x7E}, {0x98,0xAC},
+ {0x9D,0x5E}, {0xFD,0xD0}, {0xFD,0x60}, {0x9C,0xCF},
+ {0x90,0xDD}, {0x90,0xE0}, {0x90,0xF3}, {0x98,0xB1},
+ {0x90,0xF0}, {0x93,0xBD}, {0x95,0xB7}, {0x9F,0x46},
+ {0x8E,0x4B}, {0x96,0x58}, {0x8A,0x4C}, {0x9D,0x63},
+ {0x9E,0xCF}, {0x9D,0x65}, {0x9D,0x66}, {0x96,0x5A},
+ {0x9D,0x64}, {0x8A,0x6C}, {0x8A,0xD9}, {0x9D,0x67},
+ {0x8A,0x70}, {0x8B,0xF3}, {0x91,0x50}, {0x9C,0xC1},
+ {0x9D,0x68}, {0x93,0xA7}, {0x96,0x74}, {0xA0,0xEF},
+ {0x91,0x51}, {0x96,0xC1}, {0x8C,0x64}, {0x96,0x76},
+ {0x9D,0x69}, {0xFC,0xA4}, {0x9D,0x6A}, {0x92,0x4E},
+ {0x9D,0x6B}, {0x9B,0xC1}, {0x9D,0x6C}, {0x8A,0x65},
+ {0x91,0x5D}, {0x9D,0x6D}, {0x91,0x5A}, {0x8C,0x42},
+ {0x9C,0xC0}, {0x91,0x6A}, {0x9D,0x6E}, {0x9E,0xA6},
+ {0x9D,0xCD}, {0x9D,0x6F}, {0x89,0xBB}, {0x9E,0xF9},
+ {0x96,0xB4}, {0x91,0x72}, {0x9E,0xC8}, {0x8B,0x55},
+ {0x9D,0x71}, {0x9D,0x72}, {0x9E,0xCC}, {0x91,0x74},
+ {0x9E,0xD0}, {0x90,0x5C}, {0x8E,0xD2}, {0x91,0xA8},
+ {0x91,0x77}, {0x96,0xBF}, {0x96,0xC0}, {0x8F,0xB1},
+ {0x96,0xB7}, {0x8C,0x55}, {0x91,0x78}, {0x89,0xBE},
+ {0x91,0x7C}, {0xFB,0x77}, {0x91,0x75}, {0x91,0xA3},
+ {0x91,0x76}, {0x96,0xBE}, {0x91,0x79}, {0x96,0xB6},
+ {0x91,0xA4}, {0x91,0xA6}, {0x9D,0x75}, {0x90,0x52},
+ {0xA0,0x45}, {0x91,0xA9}, {0x98,0xAA}, {0x8C,0x5F},
+ {0x8B,0xAA}, {0x9C,0xDD}, {0x9D,0x77}, {0x89,0x40},
+ {0x9E,0xEC}, {0x93,0xAA}, {0x94,0x78}, {0x9D,0x7A},
+ {0x8A,0xC9}, {0x8B,0x4B}, {0x9F,0xEC}, {0x8A,0xE2},
+ {0x9E,0x75}, {0x98,0x74}, {0x9A,0xC8}, {0xA0,0x47},
+ {0x8B,0xC3}, {0xFC,0x48}, {0xFC,0x77}, {0x9C,0x52},
+ {0x8E,0xFD}, {0x8F,0xA8}, {0x95,0x7A}, {0x8F,0xF0},
+};
+
+/* Index of the convert table */
+static const Summary16 big5hkscs_uni2index_page00[70] = {
+ /* 0x0000 */
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 },
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 },
+ { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0xE7EE }, { 12, 0x87BF },
+ { 23, 0xFFFF }, { 39, 0xFFFF }, { 55, 0xFFFF }, { 71, 0xFFFF },
+ /* 0x0100 */
+ { 87, 0x0003 }, { 89, 0x0C0C }, { 93, 0x0800 }, { 94, 0x0000 },
+ { 94, 0x3800 }, { 97, 0x0008 }, { 98, 0x0800 }, { 99, 0x0000 },
+ { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0x0000 },
+ { 99, 0x6000 }, { 101, 0x1557 }, { 109, 0x0000 }, { 109, 0x0000 },
+ /* 0x0200 */
+ { 109, 0x0000 }, { 109, 0x0000 }, { 109, 0x0000 }, { 109, 0x0000 },
+ { 109, 0x0000 }, { 109, 0x0813 }, { 113, 0x0402 }, { 115, 0x0020 },
+ { 116, 0x0408 }, { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0000 },
+ { 118, 0x2EC0 }, { 124, 0x0200 }, { 125, 0x0000 }, { 125, 0x0000 },
+ /* 0x0300 */
+ { 125, 0x0020 }, { 126, 0x0000 }, { 126, 0x0000 }, { 126, 0x0000 },
+ { 126, 0x0000 }, { 126, 0x0000 }, { 126, 0x0000 }, { 126, 0x0000 },
+ { 126, 0x0000 }, { 126, 0xFFFE }, { 141, 0x03FB }, { 150, 0xFFFE },
+ { 165, 0x03FB }, { 174, 0x0000 }, { 174, 0x0000 }, { 174, 0x0000 },
+ /* 0x0400 */
+ { 174, 0x0002 }, { 175, 0xFFFF }, { 191, 0xFFFF }, { 207, 0xFFFF },
+ { 223, 0xFFFF }, { 239, 0x0002 },
+};
+static const Summary16 big5hkscs_uni2index_page1e[13] = {
+ /* 0x1E00 */
+ { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0x0000 },
+ { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0x0000 },
+ { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0x0000 }, { 240, 0xC000 },
+ { 242, 0x0003 },
+};
+static const Summary16 big5hkscs_uni2index_page20[116] = {
+ /* 0x2000 */
+ { 244, 0x0000 }, { 244, 0x3378 }, { 252, 0x00F4 }, { 257, 0x482C },
+ { 262, 0x0000 }, { 262, 0x0000 }, { 262, 0x0000 }, { 262, 0x0000 },
+ { 262, 0x0000 }, { 262, 0x0000 }, { 262, 0x1000 }, { 263, 0x0000 },
+ { 263, 0x0000 }, { 263, 0x0000 }, { 263, 0x0000 }, { 263, 0x0000 },
+ /* 0x2100 */
+ { 263, 0x0228 }, { 266, 0x0040 }, { 267, 0x0002 }, { 268, 0x0000 },
+ { 268, 0x0000 }, { 268, 0x0000 }, { 268, 0x03FF }, { 278, 0x03FF },
+ { 288, 0x0000 }, { 288, 0x03CF }, { 296, 0x0000 }, { 296, 0x0300 },
+ { 298, 0x0000 }, { 298, 0x0000 }, { 298, 0x0080 }, { 299, 0x0000 },
+ /* 0x2200 */
+ { 299, 0x0000 }, { 299, 0xC560 }, { 305, 0x4E29 }, { 312, 0x0030 },
+ { 314, 0x0000 }, { 314, 0x0004 }, { 315, 0x00CB }, { 320, 0x0000 },
+ { 320, 0x0000 }, { 320, 0x0220 }, { 322, 0x0020 }, { 323, 0x8000 },
+ { 324, 0x0000 }, { 324, 0x0000 }, { 324, 0x0000 }, { 324, 0x0000 },
+ /* 0x2300 */
+ { 324, 0x0080 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 },
+ { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 },
+ { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 },
+ { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 },
+ /* 0x2400 */
+ { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 },
+ { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x03FF }, { 335, 0x3FF0 },
+ { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 },
+ { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 },
+ /* 0x2500 */
+ { 345, 0x1005 }, { 348, 0x1111 }, { 352, 0x1010 }, { 354, 0x1010 },
+ { 356, 0x0000 }, { 356, 0xFFFF }, { 372, 0xFFFF }, { 388, 0x001F },
+ { 393, 0xFFFE }, { 408, 0x0038 }, { 411, 0x0003 }, { 413, 0x300C },
+ { 417, 0xC8C0 }, { 422, 0x0000 }, { 422, 0x003C }, { 426, 0x0000 },
+ /* 0x2600 */
+ { 426, 0x0260 }, { 429, 0x0000 }, { 429, 0x0000 }, { 429, 0x0000 },
+ { 429, 0x0007 }, { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 },
+ { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 },
+ { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 },
+ /* 0x2700 */
+ { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x0000 }, { 432, 0x2000 },
+};
+static const Summary16 big5hkscs_uni2index_page2e[1819] = {
+ /* 0x2E00 */
+ { 433, 0x0000 }, { 433, 0x0000 }, { 433, 0x0000 }, { 433, 0x0000 },
+ { 433, 0x0000 }, { 433, 0x0000 }, { 433, 0x0000 }, { 433, 0x0000 },
+ { 433, 0x35D1 }, { 441, 0x3020 }, { 444, 0x54A0 }, { 449, 0x5040 },
+ { 452, 0xB440 }, { 457, 0x40C0 }, { 460, 0x0008 }, { 461, 0x0000 },
+ /* 0x2F00 */
+ { 461, 0x0000 }, { 461, 0x0000 }, { 461, 0x0000 }, { 461, 0x0008 },
+ { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 },
+ { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 },
+ { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 }, { 462, 0x0000 },
+ /* 0x3000 */
+ { 462, 0xFFEF }, { 477, 0x7037 }, { 485, 0x03FE }, { 494, 0x0001 },
+ { 495, 0xFFFE }, { 510, 0xFFFF }, { 526, 0xFFFF }, { 542, 0xFFFF },
+ { 558, 0xFFFF }, { 574, 0x780F }, { 582, 0xFFFE }, { 597, 0xFFFF },
+ { 613, 0xFFFF }, { 629, 0xFFFF }, { 645, 0xFFFF }, { 661, 0x707F },
+ /* 0x3100 */
+ { 671, 0xFFE0 }, { 682, 0xFFFF }, { 698, 0x03FF }, { 708, 0x0000 },
+ { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 },
+ { 708, 0x0000 }, { 708, 0xFFFC }, { 722, 0x0000 }, { 722, 0x0000 },
+ { 722, 0x0000 }, { 722, 0x0000 }, { 722, 0x0000 }, { 722, 0x0000 },
+ /* 0x3200 */
+ { 722, 0x0000 }, { 722, 0x0000 }, { 722, 0xFFFF }, { 738, 0xFFFF },
+ { 754, 0x000F }, { 758, 0x0000 }, { 758, 0x0000 }, { 758, 0x0000 },
+ { 758, 0xFFFF }, { 774, 0xFFFF }, { 790, 0xFFFF }, { 806, 0x0001 },
+ { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 },
+ /* 0x3300 */
+ { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 },
+ { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 }, { 807, 0x0000 },
+ { 807, 0xC000 }, { 809, 0x7000 }, { 812, 0x0002 }, { 813, 0x0000 },
+ { 813, 0x4010 }, { 815, 0x0026 }, { 818, 0x0000 }, { 818, 0x0000 },
+ /* 0x3400 */
+ { 818, 0x0000 }, { 818, 0x0000 }, { 818, 0x0000 }, { 818, 0x0020 },
+ { 819, 0x1001 }, { 821, 0x0000 }, { 821, 0x0010 }, { 822, 0x6408 },
+ { 826, 0x0000 }, { 826, 0x0048 }, { 828, 0x8020 }, { 830, 0x1000 },
+ { 831, 0x0102 }, { 833, 0x8000 }, { 834, 0x0010 }, { 835, 0x0800 },
+ /* 0x3500 */
+ { 836, 0x0040 }, { 837, 0x0000 }, { 837, 0x0000 }, { 837, 0x4000 },
+ { 838, 0x0000 }, { 838, 0x020A }, { 841, 0x2002 }, { 843, 0x0185 },
+ { 847, 0x0010 }, { 848, 0x0180 }, { 850, 0x2022 }, { 853, 0x8000 },
+ { 854, 0x44A2 }, { 859, 0x2844 }, { 863, 0x0000 }, { 863, 0x480E },
+ /* 0x3600 */
+ { 868, 0x0200 }, { 869, 0x0500 }, { 871, 0x2008 }, { 873, 0x4220 },
+ { 876, 0x4380 }, { 880, 0x8000 }, { 881, 0x0000 }, { 881, 0x0400 },
+ { 882, 0x0002 }, { 883, 0x0400 }, { 884, 0x1420 }, { 887, 0x1223 },
+ { 892, 0x01BA }, { 898, 0x2058 }, { 902, 0x0066 }, { 906, 0x0020 },
+ /* 0x3700 */
+ { 907, 0x250A }, { 912, 0x1000 }, { 913, 0x302C }, { 918, 0x040D },
+ { 922, 0x0009 }, { 924, 0x0000 }, { 924, 0x8004 }, { 926, 0x0000 },
+ { 926, 0x0000 }, { 926, 0x0080 }, { 927, 0x0001 }, { 928, 0x4200 },
+ { 930, 0x0000 }, { 930, 0x0000 }, { 930, 0x0000 }, { 930, 0x0904 },
+ /* 0x3800 */
+ { 933, 0x8000 }, { 934, 0x0200 }, { 935, 0x2001 }, { 937, 0x0140 },
+ { 939, 0x0000 }, { 939, 0x0000 }, { 939, 0x0008 }, { 940, 0x0000 },
+ { 940, 0x0000 }, { 940, 0x0000 }, { 940, 0x0001 }, { 941, 0x0000 },
+ { 941, 0x1008 }, { 943, 0x0002 }, { 944, 0x0000 }, { 944, 0x0400 },
+ /* 0x3900 */
+ { 945, 0x0100 }, { 946, 0x0010 }, { 947, 0x0080 }, { 948, 0x8004 },
+ { 950, 0x2000 }, { 951, 0x0000 }, { 951, 0x0008 }, { 952, 0x0000 },
+ { 952, 0x0601 }, { 955, 0x0A04 }, { 958, 0x0012 }, { 960, 0x0100 },
+ { 961, 0x0000 }, { 961, 0x1000 }, { 962, 0x1024 }, { 965, 0x4900 },
+ /* 0x3A00 */
+ { 968, 0x004A }, { 971, 0x0180 }, { 973, 0x0600 }, { 975, 0x0010 },
+ { 976, 0x0800 }, { 977, 0x5084 }, { 981, 0x00C0 }, { 983, 0x0000 },
+ { 983, 0x0000 }, { 983, 0x0080 }, { 984, 0x0800 }, { 985, 0x2000 },
+ { 986, 0x0000 }, { 986, 0x4000 }, { 987, 0x0001 }, { 988, 0x0805 },
+ /* 0x3B00 */
+ { 991, 0x4000 }, { 992, 0x0200 }, { 993, 0x0804 }, { 995, 0x0200 },
+ { 996, 0x0004 }, { 997, 0x0100 }, { 998, 0x0001 }, { 999, 0x1806 },
+ { 1003, 0x0001 }, { 1004, 0x0240 }, { 1006, 0x0002 }, { 1007, 0x5000 },
+ { 1009, 0x0014 }, { 1011, 0x2080 }, { 1013, 0x1000 }, { 1014, 0x001C },
+ /* 0x3C00 */
+ { 1017, 0x2000 }, { 1018, 0x0122 }, { 1021, 0x0000 }, { 1021, 0x0000 },
+ { 1021, 0x0000 }, { 1021, 0x0010 }, { 1022, 0x0000 }, { 1022, 0x0000 },
+ { 1022, 0x0800 }, { 1023, 0x0000 }, { 1023, 0x0000 }, { 1023, 0x0000 },
+ { 1023, 0x2800 }, { 1025, 0x1042 }, { 1028, 0x8800 }, { 1030, 0x0000 },
+ /* 0x3D00 */
+ { 1030, 0x0000 }, { 1030, 0x2008 }, { 1032, 0x0000 }, { 1032, 0x0804 },
+ { 1034, 0x5040 }, { 1037, 0x8002 }, { 1039, 0x8604 }, { 1043, 0x2020 },
+ { 1045, 0x8420 }, { 1048, 0x0002 }, { 1049, 0x2020 }, { 1051, 0x8010 },
+ { 1053, 0x32C0 }, { 1058, 0x0808 }, { 1060, 0x0980 }, { 1063, 0x3088 },
+ /* 0x3E00 */
+ { 1067, 0x0040 }, { 1068, 0x0000 }, { 1068, 0x0000 }, { 1068, 0x0000 },
+ { 1068, 0x0109 }, { 1071, 0x0020 }, { 1072, 0x0000 }, { 1072, 0x0010 },
+ { 1073, 0x0000 }, { 1073, 0x0000 }, { 1073, 0x2700 }, { 1077, 0x8102 },
+ { 1080, 0x1484 }, { 1084, 0x4CC3 }, { 1091, 0x0A86 }, { 1096, 0x9419 },
+ /* 0x3F00 */
+ { 1102, 0x4051 }, { 1106, 0x0000 }, { 1106, 0x0000 }, { 1106, 0x0000 },
+ { 1106, 0x0000 }, { 1106, 0x0308 }, { 1109, 0x0008 }, { 1110, 0x1000 },
+ { 1111, 0x0000 }, { 1111, 0x0008 }, { 1112, 0x0000 }, { 1112, 0x0000 },
+ { 1112, 0x0001 }, { 1113, 0x1080 }, { 1115, 0x2020 }, { 1117, 0x0600 },
+ /* 0x4000 */
+ { 1119, 0x0210 }, { 1121, 0x2000 }, { 1122, 0x0000 }, { 1122, 0x0200 },
+ { 1123, 0x0020 }, { 1124, 0x0088 }, { 1126, 0x8424 }, { 1130, 0x0002 },
+ { 1131, 0x0000 }, { 1131, 0x0000 }, { 1131, 0x0100 }, { 1132, 0x8800 },
+ { 1134, 0x0100 }, { 1135, 0x8100 }, { 1137, 0x0000 }, { 1137, 0x0400 },
+ /* 0x4100 */
+ { 1138, 0x4218 }, { 1142, 0x0000 }, { 1142, 0x0000 }, { 1142, 0x0004 },
+ { 1143, 0x0000 }, { 1143, 0x0000 }, { 1143, 0x5080 }, { 1146, 0x8000 },
+ { 1147, 0x0000 }, { 1147, 0x0001 }, { 1148, 0x0000 }, { 1148, 0x0004 },
+ { 1149, 0x8410 }, { 1152, 0x0800 }, { 1153, 0x8000 }, { 1154, 0x0200 },
+ /* 0x4200 */
+ { 1155, 0x0000 }, { 1155, 0x0002 }, { 1156, 0x0008 }, { 1157, 0x0000 },
+ { 1157, 0x0001 }, { 1158, 0x0000 }, { 1158, 0x0401 }, { 1160, 0x0440 },
+ { 1162, 0x1000 }, { 1163, 0x0010 }, { 1164, 0x0004 }, { 1165, 0x1220 },
+ { 1168, 0x0000 }, { 1168, 0x0000 }, { 1168, 0x0000 }, { 1168, 0x1810 },
+ /* 0x4300 */
+ { 1171, 0x0000 }, { 1171, 0x0000 }, { 1171, 0x0800 }, { 1172, 0x0000 },
+ { 1172, 0x0000 }, { 1172, 0x0000 }, { 1172, 0x4000 }, { 1173, 0x0000 },
+ { 1173, 0x0000 }, { 1173, 0x0080 }, { 1174, 0x0000 }, { 1174, 0x0400 },
+ { 1175, 0x0002 }, { 1176, 0x8200 }, { 1178, 0x2000 }, { 1179, 0x0004 },
+ /* 0x4400 */
+ { 1180, 0x0006 }, { 1182, 0x0008 }, { 1183, 0x2020 }, { 1185, 0x0000 },
+ { 1185, 0x0000 }, { 1185, 0x0000 }, { 1185, 0x0000 }, { 1185, 0x0400 },
+ { 1186, 0x8000 }, { 1187, 0x8000 }, { 1188, 0x0005 }, { 1190, 0x0081 },
+ { 1192, 0x4021 }, { 1195, 0xA000 }, { 1197, 0x1E10 }, { 1202, 0x0010 },
+ /* 0x4500 */
+ { 1203, 0x0A18 }, { 1207, 0x2040 }, { 1209, 0x4080 }, { 1211, 0xA808 },
+ { 1215, 0x0008 }, { 1216, 0x1026 }, { 1220, 0x0404 }, { 1222, 0x0080 },
+ { 1223, 0x0020 }, { 1224, 0x0000 }, { 1224, 0x0000 }, { 1224, 0x0000 },
+ { 1224, 0x0000 }, { 1224, 0x0000 }, { 1224, 0x0200 }, { 1225, 0x0000 },
+ /* 0x4600 */
+ { 1225, 0x8040 }, { 1227, 0x00A0 }, { 1229, 0x0000 }, { 1229, 0x0000 },
+ { 1229, 0x0000 }, { 1229, 0x0800 }, { 1230, 0x0000 }, { 1230, 0x0400 },
+ { 1231, 0x0001 }, { 1232, 0x0000 }, { 1232, 0x0000 }, { 1232, 0x0000 },
+ { 1232, 0x8000 }, { 1233, 0x0001 }, { 1234, 0x0000 }, { 1234, 0x0020 },
+ /* 0x4700 */
+ { 1235, 0x0000 }, { 1235, 0x0108 }, { 1237, 0x0000 }, { 1237, 0x0000 },
+ { 1237, 0x4000 }, { 1238, 0x0000 }, { 1238, 0x0000 }, { 1238, 0x1000 },
+ { 1239, 0x0000 }, { 1239, 0x0100 }, { 1240, 0x0040 }, { 1241, 0x0040 },
+ { 1242, 0x0000 }, { 1242, 0x0020 }, { 1243, 0x2000 }, { 1244, 0x0010 },
+ /* 0x4800 */
+ { 1245, 0x0801 }, { 1247, 0x0000 }, { 1247, 0x0000 }, { 1247, 0x0080 },
+ { 1248, 0x0000 }, { 1248, 0x2000 }, { 1249, 0x0000 }, { 1249, 0x0002 },
+ { 1250, 0x0000 }, { 1250, 0x0800 }, { 1251, 0x6000 }, { 1253, 0x0000 },
+ { 1253, 0x0000 }, { 1253, 0x2001 }, { 1255, 0x2000 }, { 1256, 0x0408 },
+ /* 0x4900 */
+ { 1258, 0x0040 }, { 1259, 0x4002 }, { 1261, 0x2420 }, { 1264, 0x5020 },
+ { 1267, 0x0020 }, { 1268, 0x000A }, { 1270, 0x0420 }, { 1272, 0x0004 },
+ { 1273, 0x0200 }, { 1274, 0x0000 }, { 1274, 0x0082 }, { 1276, 0x0000 },
+ { 1276, 0x0000 }, { 1276, 0x8000 }, { 1277, 0x00A0 }, { 1279, 0x0000 },
+ /* 0x4A00 */
+ { 1279, 0x8000 }, { 1280, 0x2000 }, { 1281, 0x0010 }, { 1282, 0x0020 },
+ { 1283, 0x0000 }, { 1283, 0x0000 }, { 1283, 0x0000 }, { 1283, 0x0000 },
+ { 1283, 0x0000 }, { 1283, 0x0040 }, { 1284, 0x0000 }, { 1284, 0x0110 },
+ { 1286, 0x0000 }, { 1286, 0x0002 }, { 1287, 0x0010 }, { 1288, 0x8000 },
+ /* 0x4B00 */
+ { 1289, 0x0000 }, { 1289, 0x0201 }, { 1291, 0x1001 }, { 1293, 0x0080 },
+ { 1294, 0x0000 }, { 1294, 0x0000 }, { 1294, 0x8000 }, { 1295, 0x4805 },
+ { 1299, 0x4000 }, { 1300, 0x20C9 }, { 1305, 0x0000 }, { 1305, 0x6000 },
+ { 1307, 0x0001 }, { 1308, 0x0000 }, { 1308, 0x0000 }, { 1308, 0x0000 },
+ /* 0x4C00 */
+ { 1308, 0x4090 }, { 1311, 0x0000 }, { 1311, 0x0000 }, { 1311, 0x4800 },
+ { 1313, 0x0000 }, { 1313, 0x0800 }, { 1314, 0x2000 }, { 1315, 0x2000 },
+ { 1316, 0x0002 }, { 1317, 0x0000 }, { 1317, 0x4010 }, { 1319, 0x0081 },
+ { 1321, 0x2000 }, { 1322, 0x0000 }, { 1322, 0x2002 }, { 1324, 0x0000 },
+ /* 0x4D00 */
+ { 1324, 0x0200 }, { 1325, 0x0001 }, { 1326, 0x0000 }, { 1326, 0x0010 },
+ { 1327, 0x0000 }, { 1327, 0x0000 }, { 1327, 0x0000 }, { 1327, 0x0000 },
+ { 1327, 0x0000 }, { 1327, 0x1002 }, { 1329, 0x0000 }, { 1329, 0x0000 },
+ { 1329, 0x0000 }, { 1329, 0x0000 }, { 1329, 0x0000 }, { 1329, 0x0000 },
+ /* 0x4E00 */
+ { 1329, 0xFF9B }, { 1342, 0xD773 }, { 1353, 0xFD52 }, { 1363, 0xBBCF },
+ { 1375, 0xEBAC }, { 1385, 0xFF4C }, { 1396, 0x0600 }, { 1398, 0xC108 },
+ { 1402, 0x7BFF }, { 1416, 0xCF3E }, { 1427, 0x797F }, { 1439, 0x9EC8 },
+ { 1447, 0x6FDF }, { 1460, 0xF7F0 }, { 1471, 0x4F3A }, { 1480, 0xA9FF },
+ /* 0x4F00 */
+ { 1492, 0xEF3F }, { 1505, 0x27BF }, { 1516, 0xB304 }, { 1522, 0xFFDD },
+ { 1536, 0xFBEE }, { 1549, 0xFFFF }, { 1565, 0xDE9F }, { 1577, 0xFFFD },
+ { 1592, 0xAFFF }, { 1606, 0x7DF7 }, { 1619, 0xC904 }, { 1624, 0xAEED },
+ { 1635, 0xFFBF }, { 1650, 0xFFDB }, { 1664, 0xD033 }, { 1671, 0x67FF },
+ /* 0x5000 */
+ { 1684, 0xFBE9 }, { 1696, 0xDFFE }, { 1710, 0xFFEF }, { 1725, 0x18BB },
+ { 1733, 0xFFEB }, { 1747, 0xFDEA }, { 1759, 0xFF7F }, { 1774, 0x24FD },
+ { 1783, 0x79AF }, { 1794, 0x7F77 }, { 1807, 0xF04C }, { 1814, 0xFDFF },
+ { 1829, 0xEFF6 }, { 1842, 0xAEFB }, { 1854, 0xF7FB }, { 1868, 0xFB7B },
+ /* 0x5100 */
+ { 1881, 0x7FFF }, { 1896, 0x95BF }, { 1907, 0x6E77 }, { 1918, 0xBFBF },
+ { 1932, 0x3BFB }, { 1944, 0xFEF4 }, { 1956, 0x7FAF }, { 1969, 0x13F2 },
+ { 1977, 0xA7C5 }, { 1986, 0x55FE }, { 1997, 0x5DB5 }, { 2007, 0x73FF },
+ { 2020, 0xFFF8 }, { 2033, 0xF99F }, { 2045, 0x2017 }, { 2050, 0x777B },
+ /* 0x5200 */
+ { 2062, 0x5FEF }, { 2075, 0xF0CF }, { 2085, 0x47F3 }, { 2095, 0x1DFF },
+ { 2107, 0x7EDA }, { 2118, 0xFEF4 }, { 2130, 0xFF07 }, { 2141, 0xBFBC },
+ { 2153, 0xBF9F }, { 2166, 0x8FDB }, { 2177, 0x7F5B }, { 2189, 0x5A20 },
+ { 2194, 0x32AF }, { 2203, 0xEBEF }, { 2216, 0x8A5F }, { 2225, 0xDFBB },
+ /* 0x5300 */
+ { 2238, 0xEF62 }, { 2248, 0xB6E7 }, { 2259, 0xB49F }, { 2269, 0xFB9F },
+ { 2282, 0x77BF }, { 2295, 0xF49E }, { 2305, 0xF2DB }, { 2316, 0xFBBF },
+ { 2330, 0xC414 }, { 2335, 0xF7DC }, { 2347, 0x7FF5 }, { 2360, 0x0A55 },
+ { 2366, 0x3F2E }, { 2376, 0x8FD7 }, { 2387, 0xFF7F }, { 2402, 0x59EF },
+ /* 0x5400 */
+ { 2413, 0xFFDA }, { 2426, 0xFF5F }, { 2440, 0xFFFB }, { 2455, 0x7BFF },
+ { 2469, 0xEDEF }, { 2482, 0x0010 }, { 2483, 0xBFFF }, { 2498, 0xFDFF },
+ { 2513, 0xF9F7 }, { 2526, 0x55FF }, { 2538, 0xFFFF }, { 2554, 0xFFDF },
+ { 2569, 0xFBFF }, { 2584, 0x4441 }, { 2588, 0xEFFF }, { 2603, 0xBD8E },
+ /* 0x5500 */
+ { 2613, 0xFFFE }, { 2628, 0x459F }, { 2637, 0xFDE8 }, { 2648, 0xDBFF },
+ { 2662, 0xEFFB }, { 2676, 0xF0EF }, { 2687, 0x0E7E }, { 2696, 0xFAEE },
+ { 2708, 0xFFDF }, { 2723, 0xB73F }, { 2735, 0x7FFE }, { 2749, 0x9E3F },
+ { 2760, 0xFFFF }, { 2776, 0xFFFF }, { 2792, 0x97FE }, { 2804, 0xFEE7 },
+ /* 0x5600 */
+ { 2817, 0xF377 }, { 2829, 0xF8FF }, { 2842, 0xF6AF }, { 2854, 0xEFFD },
+ { 2868, 0xF76F }, { 2881, 0x679D }, { 2891, 0xFF7F }, { 2906, 0xDFDF },
+ { 2920, 0xFEFF }, { 2935, 0xF7AD }, { 2947, 0xFDF2 }, { 2959, 0xF2FE },
+ { 2971, 0x3F6F }, { 2983, 0xECDA }, { 2993, 0xECB7 }, { 3004, 0xA683 },
+ /* 0x5700 */
+ { 3011, 0x3F9F }, { 3023, 0xFD7C }, { 3035, 0xF70D }, { 3045, 0xE81D },
+ { 3053, 0xFEEF }, { 3067, 0x8897 }, { 3074, 0xAFD6 }, { 3085, 0xFCFF },
+ { 3099, 0xBD0D }, { 3108, 0xFFB9 }, { 3121, 0x44BF }, { 3130, 0xFF70 },
+ { 3141, 0xD9DE }, { 3152, 0xF0B5 }, { 3161, 0xF2FF }, { 3174, 0x7FFF },
+ /* 0x5800 */
+ { 3189, 0x7FFF }, { 3204, 0x7A15 }, { 3212, 0xF7FF }, { 3227, 0xAFFF },
+ { 3241, 0xFF91 }, { 3252, 0xFFBE }, { 3266, 0xBB3C }, { 3276, 0xFE7E },
+ { 3289, 0xCFEF }, { 3302, 0xF71F }, { 3314, 0xDFEB }, { 3327, 0xFC6B },
+ { 3338, 0xCBE6 }, { 3348, 0xFF7F }, { 3363, 0x9B9D }, { 3373, 0xFE1D },
+ /* 0x5900 */
+ { 3384, 0xF4FC }, { 3395, 0x96F6 }, { 3405, 0xFEB5 }, { 3417, 0x5196 },
+ { 3424, 0xC7B1 }, { 3433, 0x15BB }, { 3442, 0x6EA7 }, { 3452, 0xFBFF },
+ { 3467, 0xE63F }, { 3478, 0xE7DD }, { 3490, 0xD1FF }, { 3502, 0x7FFF },
+ { 3517, 0xFFFB }, { 3532, 0x7F5F }, { 3545, 0xFF7B }, { 3559, 0xFFFF },
+ /* 0x5A00 */
+ { 3575, 0xBE0F }, { 3585, 0xDFEE }, { 3598, 0x7EBB }, { 3610, 0x73E8 },
+ { 3619, 0x37FF }, { 3632, 0xFFFF }, { 3648, 0x7FFF }, { 3663, 0xFF83 },
+ { 3674, 0xDD5E }, { 3685, 0xFEFF }, { 3700, 0xDAE7 }, { 3711, 0xFFFF },
+ { 3727, 0xFFDF }, { 3742, 0xFFE8 }, { 3754, 0x7F7F }, { 3768, 0xEFFD },
+ /* 0x5B00 */
+ { 3782, 0xBBAE }, { 3793, 0xEEFB }, { 3806, 0xFDFB }, { 3820, 0xF115 },
+ { 3828, 0xFDFB }, { 3842, 0xBDFB }, { 3855, 0x7B7C }, { 3866, 0xBDFF },
+ { 3880, 0xDBBF }, { 3893, 0xFFED }, { 3907, 0x75FC }, { 3918, 0x8379 },
+ { 3926, 0x7CFF }, { 3939, 0xC3FF }, { 3951, 0xDFFF }, { 3966, 0x856F },
+ /* 0x5C00 */
+ { 3975, 0xFFBA }, { 3988, 0xD47F }, { 3999, 0x153D }, { 4007, 0xDF8B },
+ { 4018, 0xFFF3 }, { 4032, 0x737B }, { 4043, 0xF7BD }, { 4056, 0x5E1A },
+ { 4064, 0xBF60 }, { 4073, 0xF63F }, { 4085, 0xFFFF }, { 4101, 0x05EB },
+ { 4109, 0xDFC6 }, { 4120, 0xCFDF }, { 4133, 0xF720 }, { 4141, 0xABF3 },
+ /* 0x5D00 */
+ { 4152, 0xF8C3 }, { 4161, 0xEFF7 }, { 4175, 0xD3FD }, { 4187, 0xF7FF },
+ { 4202, 0x5FEF }, { 4215, 0x4AE7 }, { 4224, 0x9BAC }, { 4233, 0xFE97 },
+ { 4245, 0x6FF7 }, { 4258, 0xF6BC }, { 4269, 0xFF97 }, { 4282, 0x37F7 },
+ { 4294, 0xAACF }, { 4304, 0xE9F6 }, { 4315, 0x49E7 }, { 4324, 0xE2BF },
+ /* 0x5E00 */
+ { 4335, 0x5E5C }, { 4344, 0xAFF6 }, { 4356, 0x6B3F }, { 4367, 0x61D8 },
+ { 4374, 0xFD3F }, { 4387, 0xFBB8 }, { 4398, 0xFFCF }, { 4412, 0xFF7D },
+ { 4426, 0xBFDD }, { 4439, 0x1EE4 }, { 4447, 0x7DFD }, { 4460, 0x63FF },
+ { 4472, 0x7FF6 }, { 4485, 0xFFFF }, { 4501, 0xD3EF }, { 4513, 0xDFDE },
+ /* 0x5F00 */
+ { 4526, 0xFDB6 }, { 4538, 0xADBC }, { 4548, 0x63FC }, { 4558, 0x15EB },
+ { 4567, 0xFF59 }, { 4579, 0x33D3 }, { 4588, 0xBEBE }, { 4600, 0xFBDF },
+ { 4614, 0x1FEF }, { 4626, 0xDBC7 }, { 4637, 0xFFF3 }, { 4651, 0xFEE6 },
+ { 4663, 0xB23F }, { 4673, 0xEBF7 }, { 4686, 0xED3B }, { 4697, 0xADBA },
+ /* 0x6000 */
+ { 4707, 0xFE01 }, { 4715, 0x7EFF }, { 4729, 0xFFFF }, { 4745, 0x0ABE },
+ { 4753, 0x36FF }, { 4765, 0xEF3D }, { 4777, 0xFFFC }, { 4791, 0xC0A5 },
+ { 4797, 0x77FB }, { 4810, 0xFCF5 }, { 4822, 0x019D }, { 4828, 0xFFFF },
+ { 4844, 0xFFFB }, { 4859, 0xFFBA }, { 4872, 0x03DF }, { 4881, 0xFFFF },
+ /* 0x6100 */
+ { 4897, 0xFFFB }, { 4912, 0xBF7D }, { 4925, 0xDB8C }, { 4934, 0xE8D5 },
+ { 4943, 0xFFF7 }, { 4958, 0xFF7D }, { 4972, 0xDDFF }, { 4986, 0x76FF },
+ { 4999, 0x7E8F }, { 5010, 0xBF7F }, { 5024, 0xFF96 }, { 5036, 0xD7FF },
+ { 5050, 0xBFEF }, { 5064, 0xC549 }, { 5071, 0x6FFD }, { 5084, 0xFFE7 },
+ /* 0x6200 */
+ { 5098, 0x779B }, { 5109, 0x8E77 }, { 5119, 0x7EBF }, { 5132, 0xE6DD },
+ { 5143, 0x7FCF }, { 5156, 0x5F1F }, { 5167, 0xE17F }, { 5178, 0xFEDF },
+ { 5192, 0xD7FF }, { 5206, 0x21FF }, { 5216, 0xFF50 }, { 5226, 0xFB7B },
+ { 5239, 0xFFFC }, { 5253, 0x9FFF }, { 5267, 0xF820 }, { 5273, 0xFFFF },
+ /* 0x6300 */
+ { 5289, 0xFB8F }, { 5301, 0x017B }, { 5308, 0xFF00 }, { 5316, 0x7FFE },
+ { 5330, 0xFFFF }, { 5346, 0x07F3 }, { 5355, 0xFBB0 }, { 5365, 0xBFE7 },
+ { 5378, 0xFFBF }, { 5393, 0xFBD7 }, { 5406, 0xFFBF }, { 5421, 0x6203 },
+ { 5426, 0xFFFF }, { 5442, 0xFFEF }, { 5457, 0xEFFF }, { 5472, 0x5B7F },
+ /* 0x6400 */
+ { 5484, 0xFEC0 }, { 5493, 0xDDFD }, { 5506, 0xFDFF }, { 5521, 0xEFFD },
+ { 5535, 0x680B }, { 5541, 0xFF1F }, { 5554, 0xFBE3 }, { 5566, 0xBFFF },
+ { 5581, 0xBFA4 }, { 5591, 0xF7EF }, { 5605, 0xFA7D }, { 5617, 0xF85F },
+ { 5628, 0xEEBF }, { 5641, 0x2FDD }, { 5652, 0xBFFF }, { 5667, 0xFD9F },
+ /* 0x6500 */
+ { 5680, 0xF6DB }, { 5692, 0xFBFB }, { 5706, 0xFE7F }, { 5720, 0xEBFD },
+ { 5733, 0xA76A }, { 5742, 0xF3FA }, { 5754, 0xBDFC }, { 5766, 0x9FFC },
+ { 5778, 0x1BFF }, { 5790, 0xFAF7 }, { 5803, 0xDDB7 }, { 5815, 0xFBED },
+ { 5828, 0xF87E }, { 5839, 0xECDF }, { 5851, 0xF36F }, { 5863, 0xBC3F },
+ /* 0x6600 */
+ { 5874, 0xFFFD }, { 5889, 0xF13F }, { 5900, 0xE9FF }, { 5913, 0x067F },
+ { 5922, 0x9FBE }, { 5934, 0xFE8E }, { 5945, 0xDDFE }, { 5958, 0x7FDF },
+ { 5972, 0x7FF1 }, { 5984, 0xA7F7 }, { 5996, 0xEF17 }, { 6007, 0xEFFF },
+ { 6022, 0xFFD1 }, { 6034, 0x7F44 }, { 6043, 0x7B59 }, { 6053, 0xD3DF },
+ /* 0x6700 */
+ { 6065, 0xFF3F }, { 6079, 0xEBFD }, { 6092, 0x7DEF }, { 6105, 0xFF7A },
+ { 6118, 0xFBF0 }, { 6129, 0xF6EB }, { 6141, 0xBC87 }, { 6150, 0xFFFF },
+ { 6166, 0xFAFA }, { 6178, 0xB7BF }, { 6191, 0xD011 }, { 6196, 0x8FFF },
+ { 6209, 0xFF7F }, { 6224, 0xFFDF }, { 6239, 0xFEFC }, { 6252, 0xD7FF },
+ /* 0x6800 */
+ { 6266, 0x201F }, { 6272, 0xFDDD }, { 6285, 0xEF67 }, { 6297, 0x7FFE },
+ { 6311, 0xFFFF }, { 6327, 0x207B }, { 6334, 0xE820 }, { 6339, 0xFBF6 },
+ { 6352, 0x9FFF }, { 6366, 0xB9DF }, { 6378, 0xFFDF }, { 6393, 0x227F },
+ { 6402, 0x7FF8 }, { 6414, 0xF5FF }, { 6428, 0xDFDB }, { 6441, 0x3FFF },
+ /* 0x6900 */
+ { 6455, 0xFFFF }, { 6471, 0x0FBF }, { 6482, 0x9420 }, { 6486, 0xFBFD },
+ { 6500, 0xDF7F }, { 6514, 0xFFFE }, { 6529, 0xFFFF }, { 6545, 0x0FFF },
+ { 6557, 0x646D }, { 6565, 0xDFFB }, { 6579, 0xFFFF }, { 6595, 0xFAFF },
+ { 6609, 0xFE5F }, { 6622, 0x027B }, { 6629, 0x7BF6 }, { 6641, 0xFFDE },
+ /* 0x6A00 */
+ { 6655, 0xBFFF }, { 6670, 0xFFFA }, { 6684, 0x39EB }, { 6694, 0xFF3C },
+ { 6706, 0xFBFB }, { 6720, 0xEFFF }, { 6735, 0xAFFF }, { 6749, 0xC452 },
+ { 6755, 0xF6BF }, { 6768, 0xFEFF }, { 6783, 0xF9FF }, { 6797, 0x6FFE },
+ { 6810, 0xBFEC }, { 6822, 0xFF1B }, { 6834, 0xDDA3 }, { 6844, 0x1F4B },
+ /* 0x6B00 */
+ { 6853, 0x8F3D }, { 6863, 0x67CF }, { 6874, 0xB12B }, { 6882, 0xFFFE },
+ { 6897, 0x7FEE }, { 6910, 0xDAF7 }, { 6922, 0xA4FF }, { 6933, 0xCFD4 },
+ { 6943, 0xF75F }, { 6956, 0xCBF2 }, { 6966, 0xECFD }, { 6978, 0xB4ED },
+ { 6988, 0xBFFB }, { 7002, 0x5DDD }, { 7013, 0x9DDF }, { 7025, 0xFF8D },
+ /* 0x6C00 */
+ { 7037, 0xBB7F }, { 7050, 0xBF7B }, { 7063, 0xDDFB }, { 7076, 0xEFFB },
+ { 7090, 0xFE4F }, { 7102, 0xFFB5 }, { 7115, 0xEFE3 }, { 7127, 0xEF7F },
+ { 7141, 0xFFFF }, { 7157, 0xBF7D }, { 7170, 0xFC04 }, { 7177, 0xFFDF },
+ { 7192, 0xFEFF }, { 7207, 0xFEFF }, { 7222, 0xFFAF }, { 7236, 0x822F },
+ /* 0x6D00 */
+ { 7243, 0xFFFF }, { 7259, 0xEFC7 }, { 7271, 0xFFF5 }, { 7285, 0xFFFF },
+ { 7301, 0x4007 }, { 7305, 0xDF80 }, { 7313, 0xF7FF }, { 7328, 0xFFF7 },
+ { 7343, 0xFFFF }, { 7359, 0x01FF }, { 7368, 0xDC30 }, { 7375, 0xFFBE },
+ { 7389, 0xBFF5 }, { 7402, 0xFFFF }, { 7418, 0xFF7F }, { 7433, 0x7EFF },
+ /* 0x6E00 */
+ { 7447, 0x843D }, { 7454, 0xBF20 }, { 7462, 0xFFFF }, { 7478, 0xFF7F },
+ { 7493, 0xEEFB }, { 7506, 0xFF7F }, { 7521, 0xCBFF }, { 7534, 0x13DE },
+ { 7543, 0xEB40 }, { 7550, 0xFFDD }, { 7564, 0xCCFF }, { 7576, 0xFFFF },
+ { 7592, 0xFFFF }, { 7608, 0x3F7F }, { 7621, 0xFB04 }, { 7629, 0xFFF6 },
+ /* 0x6F00 */
+ { 7643, 0xFFFF }, { 7659, 0xD7FC }, { 7671, 0xFEFF }, { 7686, 0xFFFF },
+ { 7702, 0xC01B }, { 7708, 0xFDFF }, { 7723, 0xFEDF }, { 7737, 0xFFDD },
+ { 7751, 0x7FF7 }, { 7765, 0xE0FD }, { 7775, 0xFFFF }, { 7791, 0xFF7F },
+ { 7806, 0xFFDF }, { 7821, 0xFF38 }, { 7832, 0xFBDF }, { 7846, 0xDDD7 },
+ /* 0x7000 */
+ { 7858, 0xFEFB }, { 7872, 0xFFF2 }, { 7885, 0x9FDF }, { 7898, 0xDFBF },
+ { 7912, 0x3F7F }, { 7925, 0xFDF7 }, { 7939, 0x9FFF }, { 7953, 0xF7F3 },
+ { 7966, 0xCE7E }, { 7977, 0x877E }, { 7987, 0xFAFB }, { 8000, 0x7FBB },
+ { 8013, 0xFDF1 }, { 8025, 0xF7FF }, { 8040, 0x8017 }, { 8045, 0xFFFB },
+ /* 0x7100 */
+ { 8060, 0x7E75 }, { 8071, 0xFE89 }, { 8081, 0xDB6F }, { 8093, 0x4C7F },
+ { 8103, 0xFEFF }, { 8118, 0xF75F }, { 8131, 0x5FFF }, { 8145, 0x7DEF },
+ { 8158, 0xD7F7 }, { 8171, 0xFFD7 }, { 8185, 0xB7BF }, { 8198, 0xF7BF },
+ { 8212, 0xCFFF }, { 8226, 0xBF77 }, { 8239, 0x79F7 }, { 8251, 0xFB77 },
+ /* 0x7200 */
+ { 8264, 0xF6EF }, { 8277, 0xEEF9 }, { 8289, 0x7FDC }, { 8301, 0xEF61 },
+ { 8311, 0x9FD7 }, { 8323, 0xFFED }, { 8337, 0xD6CF }, { 8348, 0xFBDD },
+ { 8361, 0xFBF7 }, { 8375, 0xEDFF }, { 8389, 0xF7FE }, { 8403, 0xA435 },
+ { 8410, 0x7E7F }, { 8423, 0x97D7 }, { 8434, 0x0F5F }, { 8444, 0xFFD8 },
+ /* 0x7300 */
+ { 8456, 0x9D97 }, { 8466, 0x7BCF }, { 8478, 0x7FEC }, { 8490, 0xDFFF },
+ { 8505, 0xF73F }, { 8518, 0xEF87 }, { 8529, 0xDFE7 }, { 8542, 0xFDFF },
+ { 8557, 0xDFFF }, { 8572, 0xF1FC }, { 8583, 0x3FF7 }, { 8596, 0xDFFC },
+ { 8609, 0xFFED }, { 8623, 0x7FFD }, { 8637, 0xEFFF }, { 8652, 0xFFF8 },
+ /* 0x7400 */
+ { 8665, 0x3FFF }, { 8679, 0xFEF6 }, { 8692, 0xFF7F }, { 8707, 0x97FF },
+ { 8720, 0xEFFF }, { 8735, 0xFEFF }, { 8750, 0xFFBD }, { 8764, 0xF67F },
+ { 8777, 0x3FEF }, { 8790, 0xDFB5 }, { 8802, 0xAFFB }, { 8815, 0xEFF7 },
+ { 8829, 0x9D2F }, { 8839, 0xFFF9 }, { 8853, 0x53FF }, { 8865, 0xE9F7 },
+ /* 0x7500 */
+ { 8877, 0xF9BD }, { 8889, 0xF7FF }, { 8904, 0xFF66 }, { 8916, 0xEFBF },
+ { 8930, 0xFDC5 }, { 8941, 0xBE3A }, { 8951, 0xFCFD }, { 8964, 0xE7C5 },
+ { 8974, 0xFCD9 }, { 8985, 0x6737 }, { 8995, 0x0CBC }, { 9002, 0xFF7F },
+ { 9017, 0xFDBF }, { 9031, 0xFFB7 }, { 9045, 0xA0DF }, { 9054, 0xFFFF },
+ /* 0x7600 */
+ { 9070, 0xBF8F }, { 9082, 0xFE7B }, { 9095, 0xB3FF }, { 9108, 0x3D3F },
+ { 9119, 0xF3CD }, { 9130, 0x97DF }, { 9142, 0xF6F7 }, { 9155, 0xFF7F },
+ { 9170, 0xCFD6 }, { 9181, 0x7E6D }, { 9192, 0xEC72 }, { 9201, 0xEDB1 },
+ { 9211, 0x777C }, { 9222, 0xFE5C }, { 9233, 0xF6FA }, { 9245, 0x5FBF },
+ /* 0x7700 */
+ { 9258, 0xDFBA }, { 9270, 0xEE2F }, { 9281, 0xABFD }, { 9293, 0x7FFE },
+ { 9307, 0xFCF9 }, { 9319, 0xDF74 }, { 9330, 0xFFEF }, { 9345, 0xFF84 },
+ { 9355, 0xFBBF }, { 9369, 0xFFAA }, { 9381, 0xBDAF }, { 9393, 0xFEFF },
+ { 9408, 0xFEBC }, { 9420, 0x7FB9 }, { 9432, 0xF3ED }, { 9444, 0x7F9F },
+ /* 0x7800 */
+ { 9457, 0xF36C }, { 9467, 0xF11F }, { 9477, 0xFFEF }, { 9492, 0x33BF },
+ { 9503, 0x7FBC }, { 9515, 0x701F }, { 9523, 0xFF75 }, { 9536, 0xDE03 },
+ { 9544, 0xF3FB }, { 9557, 0xC7FA }, { 9568, 0xBFBF }, { 9582, 0x5F5F },
+ { 9594, 0xFFBA }, { 9607, 0xEDBF }, { 9620, 0xF7BF }, { 9634, 0xFEBF },
+ /* 0x7900 */
+ { 9648, 0x5276 }, { 9656, 0x7A9F }, { 9667, 0xFFFA }, { 9681, 0xFF7E },
+ { 9695, 0x9FF7 }, { 9708, 0xFFFF }, { 9724, 0x2FBF }, { 9736, 0xF61F },
+ { 9747, 0xEDCF }, { 9759, 0xBFFF }, { 9774, 0x7FF7 }, { 9788, 0xEFDF },
+ { 9802, 0xFB73 }, { 9814, 0xF176 }, { 9824, 0x7EDD }, { 9836, 0x0DD2 },
+ /* 0x7A00 */
+ { 9843, 0x3D7D }, { 9854, 0xDFBF }, { 9868, 0xED45 }, { 9877, 0xFE83 },
+ { 9887, 0x7FF9 }, { 9900, 0x9DD0 }, { 9908, 0x7BA7 }, { 9919, 0xEF73 },
+ { 9931, 0x9FFB }, { 9944, 0xC3FF }, { 9956, 0xDF0D }, { 9966, 0xDDFF },
+ { 9980, 0x8FBF }, { 9992, 0xBF0A }, { 10001, 0xEEFD }, { 10014, 0xEEC0 },
+ /* 0x7B00 */
+ { 10022, 0xDF73 }, { 10034, 0xEF1F }, { 10046, 0xFFFD }, { 10061, 0x0B3F },
+ { 10070, 0xFFFD }, { 10085, 0x0177 }, { 10092, 0xF2FF }, { 10105, 0x09FF },
+ { 10115, 0xFDB4 }, { 10126, 0x3BF7 }, { 10138, 0xB01F }, { 10146, 0x43B6 },
+ { 10154, 0xDED3 }, { 10165, 0xFF31 }, { 10176, 0x1FFF }, { 10189, 0xFF9F },
+ /* 0x7C00 */
+ { 10203, 0xFEEF }, { 10217, 0xFA27 }, { 10227, 0x3FEF }, { 10240, 0xFBA9 },
+ { 10251, 0x37BD }, { 10262, 0xBEDB }, { 10274, 0xFEF9 }, { 10287, 0xFF3D },
+ { 10300, 0x777B }, { 10312, 0xD1F6 }, { 10322, 0xD1EE }, { 10332, 0xFF3E },
+ { 10345, 0x7FAC }, { 10356, 0xF6FF }, { 10370, 0xF5C5 }, { 10380, 0x7BFF },
+ /* 0x7D00 */
+ { 10394, 0xFFFF }, { 10410, 0xFFFF }, { 10426, 0xDB27 }, { 10436, 0xFF6F },
+ { 10450, 0xE4FF }, { 10462, 0xFD7F }, { 10476, 0xEFCE }, { 10488, 0xBE0F },
+ { 10498, 0xFB7B }, { 10511, 0xF0DE }, { 10521, 0xFFDF }, { 10536, 0xFFBF },
+ { 10551, 0xFEF7 }, { 10565, 0xFF9D }, { 10578, 0xD7FB }, { 10591, 0x6EFF },
+ /* 0x7E00 */
+ { 10604, 0xFF88 }, { 10614, 0xFCFF }, { 10628, 0xEEBF }, { 10641, 0xFFFF },
+ { 10657, 0x13FF }, { 10668, 0xDFFF }, { 10683, 0xFFAF }, { 10697, 0xFFFD },
+ { 10712, 0xFDC7 }, { 10724, 0x9FFE }, { 10737, 0x1010 }, { 10739, 0x0400 },
+ { 10740, 0x8080 }, { 10742, 0x8000 }, { 10743, 0x0000 }, { 10743, 0x0000 },
+ /* 0x7F00 */
+ { 10743, 0x0040 }, { 10744, 0x0000 }, { 10744, 0x0000 }, { 10744, 0xE7C0 },
+ { 10752, 0xFFBB }, { 10766, 0xF93F }, { 10778, 0x7FEB }, { 10791, 0xFFEF },
+ { 10806, 0xFFE8 }, { 10818, 0x7CFE }, { 10830, 0xF3FF }, { 10844, 0xFFFF },
+ { 10860, 0xFEAF }, { 10873, 0xF8B7 }, { 10884, 0xFFEF }, { 10899, 0xFFBF },
+ /* 0x8000 */
+ { 10914, 0xF9FF }, { 10928, 0xFBF7 }, { 10942, 0xD773 }, { 10953, 0xFAFB },
+ { 10966, 0x85C8 }, { 10972, 0x7D57 }, { 10983, 0x90DE }, { 10991, 0xE3EF },
+ { 11003, 0x9EF5 }, { 11014, 0xBF6D }, { 11026, 0xEEAE }, { 11037, 0x35F6 },
+ { 11047, 0xF7FC }, { 11060, 0x7FF3 }, { 11073, 0xB27B }, { 11083, 0x7F7F },
+ /* 0x8100 */
+ { 11097, 0x57EF }, { 11109, 0xEFF4 }, { 11121, 0xBEBE }, { 11133, 0x6695 },
+ { 11141, 0xFDDC }, { 11153, 0x5E7F }, { 11165, 0xEAF7 }, { 11177, 0x97DF },
+ { 11189, 0xBFDD }, { 11202, 0xFFA8 }, { 11213, 0x5FED }, { 11225, 0xFEFF },
+ { 11240, 0xB7FF }, { 11254, 0xEFA7 }, { 11266, 0xF7FF }, { 11281, 0xDFDC },
+ /* 0x8200 */
+ { 11293, 0x3FB7 }, { 11305, 0xFD77 }, { 11318, 0xBF67 }, { 11330, 0xF7FC },
+ { 11343, 0xCAB5 }, { 11352, 0xDFFF }, { 11367, 0xFB7E }, { 11380, 0xFFF6 },
+ { 11394, 0xECB9 }, { 11404, 0xEF1F }, { 11416, 0xFFFF }, { 11432, 0xFFFB },
+ { 11447, 0x841D }, { 11453, 0xDBFF }, { 11467, 0xFDFF }, { 11482, 0xFFFF },
+ /* 0x8300 */
+ { 11498, 0x3BFF }, { 11511, 0x7FC0 }, { 11520, 0xBFF5 }, { 11533, 0xBFFE },
+ { 11547, 0xFFBF }, { 11562, 0x00DF }, { 11569, 0x804C }, { 11573, 0xFDF8 },
+ { 11585, 0xFFEA }, { 11598, 0x7FFF }, { 11613, 0xDFFD }, { 11627, 0xE201 },
+ { 11632, 0xFFFF }, { 11648, 0xFBFA }, { 11661, 0xFFBF }, { 11676, 0xFF7F },
+ /* 0x8400 */
+ { 11691, 0xFEFA }, { 11704, 0x195F }, { 11713, 0xFA5B }, { 11724, 0xFFFF },
+ { 11740, 0x7FFD }, { 11754, 0xFFFF }, { 11770, 0xFBFF }, { 11785, 0xE7FF },
+ { 11799, 0xE145 }, { 11806, 0xFFDF }, { 11821, 0xFF9F }, { 11835, 0xFF57 },
+ { 11848, 0xFEF7 }, { 11862, 0x4CDF }, { 11872, 0xDFB6 }, { 11884, 0xFFDF },
+ /* 0x8500 */
+ { 11899, 0xFFED }, { 11913, 0xF7FF }, { 11928, 0xFFFB }, { 11943, 0x691B },
+ { 11951, 0x7FFF }, { 11966, 0xEFFE }, { 11980, 0xFFFF }, { 11996, 0x5FEB },
+ { 12008, 0xFFFF }, { 12024, 0xFFF3 }, { 12038, 0x87DF }, { 12049, 0xE7FB },
+ { 12062, 0xEBFF }, { 12076, 0xF7E7 }, { 12089, 0xFF7F }, { 12104, 0xFFC7 },
+ /* 0x8600 */
+ { 12117, 0xBEF7 }, { 12130, 0xDFD3 }, { 12142, 0xF7FF }, { 12157, 0xDF7E },
+ { 12170, 0x79ED }, { 12181, 0xDA7D }, { 12192, 0xFFBE }, { 12206, 0x5E9F },
+ { 12217, 0x7CE0 }, { 12225, 0x77FF }, { 12239, 0xA7BF }, { 12251, 0xFFFF },
+ { 12267, 0x1BFF }, { 12279, 0xFFDB }, { 12293, 0xBF5C }, { 12304, 0x4FE0 },
+ /* 0x8700 */
+ { 12312, 0x7FFF }, { 12327, 0x5F0E }, { 12336, 0x77FF }, { 12350, 0xDDBF },
+ { 12363, 0xF04F }, { 12372, 0xFFFF }, { 12388, 0xFFFF }, { 12404, 0x2FFB },
+ { 12416, 0xBBFE }, { 12429, 0xFDDF }, { 12443, 0xFE3C }, { 12454, 0xFFFF },
+ { 12470, 0x5F7F }, { 12483, 0xFFDE }, { 12497, 0xFDFF }, { 12512, 0xDEFC },
+ /* 0x8800 */
+ { 12524, 0xBF7F }, { 12538, 0xBBFB }, { 12551, 0xFFFF }, { 12567, 0xFBEF },
+ { 12581, 0xFD7F }, { 12595, 0x6EEC }, { 12605, 0xEFBF }, { 12619, 0xF2F7 },
+ { 12631, 0xFB9F }, { 12644, 0xDFEF }, { 12658, 0x5D97 }, { 12668, 0xF7F6 },
+ { 12681, 0xFEA7 }, { 12693, 0xFFF5 }, { 12707, 0xD9C2 }, { 12715, 0xFFFF },
+ /* 0x8900 */
+ { 12731, 0x5EE7 }, { 12742, 0xC7FF }, { 12755, 0xFEFE }, { 12769, 0x79EF },
+ { 12781, 0xBADE }, { 12792, 0xFFDF }, { 12807, 0xFE7F }, { 12821, 0xDEDE },
+ { 12833, 0x8FEF }, { 12845, 0xF9FA }, { 12857, 0xF6FE }, { 12870, 0xF6C4 },
+ { 12879, 0x0043 }, { 12882, 0xBE7C }, { 12893, 0x3BFF }, { 12906, 0xDDDF },
+ /* 0x8A00 */
+ { 12919, 0xD59D }, { 12929, 0xF9EF }, { 12942, 0x3EAC }, { 12951, 0xFF53 },
+ { 12963, 0xF773 }, { 12975, 0x4BF7 }, { 12986, 0x7BCF }, { 12998, 0xDEFF },
+ { 13012, 0xB8FE }, { 13023, 0x577F }, { 13035, 0x8FFB }, { 13047, 0xFF55 },
+ { 13059, 0xABFD }, { 13071, 0xFFFE }, { 13086, 0xEDD7 }, { 13098, 0xDDFF },
+ /* 0x8B00 */
+ { 13112, 0xFDF7 }, { 13126, 0xFFFF }, { 13142, 0xFDFD }, { 13156, 0xFEEB },
+ { 13169, 0xFFEF }, { 13184, 0xF7FF }, { 13199, 0xBFED }, { 13212, 0xEF91 },
+ { 13222, 0x5D7F }, { 13234, 0xDF7D }, { 13247, 0x0001 }, { 13248, 0x4000 },
+ { 13249, 0x0000 }, { 13249, 0x0000 }, { 13249, 0x0004 }, { 13250, 0x0000 },
+ /* 0x8C00 */
+ { 13250, 0x0000 }, { 13250, 0x0000 }, { 13250, 0x0000 }, { 13250, 0xFA80 },
+ { 13257, 0xFFEE }, { 13271, 0xB4F3 }, { 13281, 0xBF76 }, { 13293, 0x2FEF },
+ { 13305, 0xB677 }, { 13316, 0xFFBF }, { 13331, 0xBFBF }, { 13345, 0xFFFD },
+ { 13360, 0xB5BF }, { 13372, 0xFEFE }, { 13386, 0x7FFF }, { 13401, 0x7FBF },
+ /* 0x8D00 */
+ { 13415, 0xBFFD }, { 13429, 0x3BFF }, { 13442, 0x0000 }, { 13442, 0x0000 },
+ { 13442, 0x0000 }, { 13442, 0x0000 }, { 13442, 0xFBD0 }, { 13452, 0x2FDD },
+ { 13463, 0xF637 }, { 13474, 0x9A7F }, { 13485, 0xFFEB }, { 13499, 0xD6FC },
+ { 13510, 0xF9EF }, { 13523, 0xBFFB }, { 13537, 0xDFDF }, { 13551, 0xF41F },
+ /* 0x8E00 */
+ { 13561, 0xE6FF }, { 13574, 0xFFFF }, { 13590, 0x6FFF }, { 13604, 0xF77B },
+ { 13617, 0xFFF7 }, { 13632, 0xFEF9 }, { 13645, 0xB7FF }, { 13659, 0x5DFE },
+ { 13671, 0x7FF7 }, { 13685, 0xE5FF }, { 13698, 0x3FFB }, { 13711, 0x3645 },
+ { 13718, 0xFE0D }, { 13728, 0xFD9E }, { 13740, 0xFBF7 }, { 13754, 0xDFF6 },
+ /* 0x8F00 */
+ { 13767, 0x6FEF }, { 13780, 0xFFFF }, { 13796, 0xF679 }, { 13807, 0xCBFD },
+ { 13819, 0xEFFF }, { 13834, 0xFFFF }, { 13850, 0x40DF }, { 13858, 0x0000 },
+ { 13858, 0x0000 }, { 13858, 0x9808 }, { 13862, 0xE1E9 }, { 13871, 0xDFFF },
+ { 13886, 0xFE76 }, { 13898, 0x04FF }, { 13907, 0x6D7F }, { 13919, 0xFFF1 },
+ /* 0x9000 */
+ { 13932, 0xB97F }, { 13944, 0xFEF7 }, { 13958, 0xE01F }, { 13966, 0xF1FE },
+ { 13978, 0xFE96 }, { 13989, 0x7B7F }, { 14002, 0xFB9F }, { 14015, 0xFFFD },
+ { 14030, 0xADFF }, { 14043, 0xCBB3 }, { 14053, 0xC5EF }, { 14064, 0xE97F },
+ { 14076, 0x4DBA }, { 14085, 0xBFF0 }, { 14096, 0xBF3F }, { 14109, 0xFE3F },
+ /* 0x9100 */
+ { 14122, 0xEBFF }, { 14136, 0xFFD7 }, { 14150, 0xFFDF }, { 14165, 0xCF7F },
+ { 14178, 0xFFFB }, { 14193, 0xD7EF }, { 14206, 0xD7BF }, { 14219, 0x17FD },
+ { 14230, 0xFEFF }, { 14245, 0xFE0F }, { 14256, 0xFFAF }, { 14270, 0x7EFF },
+ { 14284, 0xFAFF }, { 14298, 0xB7FB }, { 14311, 0x7FFC }, { 14324, 0xE7FA },
+ /* 0x9200 */
+ { 14336, 0xF7FF }, { 14351, 0x56FF }, { 14363, 0x6DFA }, { 14374, 0xF7FF },
+ { 14389, 0xFF73 }, { 14402, 0xEDFF }, { 14416, 0xF8FF }, { 14429, 0xFFC5 },
+ { 14441, 0xFFFF }, { 14457, 0x3FFA }, { 14469, 0x5FFF }, { 14483, 0xDEFE },
+ { 14496, 0xFFFF }, { 14512, 0xEBBF }, { 14525, 0xDFFB }, { 14539, 0xFFDF },
+ /* 0x9300 */
+ { 14554, 0xFBDF }, { 14568, 0xEF7D }, { 14581, 0xFFFF }, { 14597, 0x137B },
+ { 14606, 0xFFFF }, { 14622, 0xDFF7 }, { 14636, 0x7FFF }, { 14651, 0x7FFB },
+ { 14665, 0xF7FF }, { 14680, 0xFFF7 }, { 14695, 0xF7FF }, { 14710, 0xA9BF },
+ { 14721, 0xFDDD }, { 14734, 0xFFFF }, { 14750, 0x51DF }, { 14760, 0xFFFB },
+ /* 0x9400 */
+ { 14775, 0xFFDB }, { 14789, 0x2BFF }, { 14801, 0x7FF1 }, { 14813, 0xFFEF },
+ { 14828, 0xBFFD }, { 14842, 0x69B7 }, { 14852, 0xFFBD }, { 14866, 0xFBFF },
+ { 14881, 0x002F }, { 14886, 0x8000 }, { 14887, 0x0004 }, { 14888, 0x0000 },
+ { 14888, 0x000A }, { 14890, 0x1000 }, { 14891, 0x0000 }, { 14891, 0x0040 },
+ /* 0x9500 */
+ { 14892, 0x0000 }, { 14892, 0x0000 }, { 14892, 0x2000 }, { 14893, 0x0000 },
+ { 14893, 0x0080 }, { 14894, 0x0000 }, { 14894, 0x0000 }, { 14894, 0xBD80 },
+ { 14901, 0xFB6D }, { 14913, 0xDBDF }, { 14926, 0x7FFF }, { 14941, 0xFEE3 },
+ { 14953, 0x3FE9 }, { 14964, 0xDC7F }, { 14976, 0x013F }, { 14983, 0x0010 },
+ /* 0x9600 */
+ { 14984, 0x0000 }, { 14984, 0x7000 }, { 14987, 0xF51F }, { 14998, 0xBF0F },
+ { 15009, 0xFC3F }, { 15021, 0xF95B }, { 15032, 0xBE1E }, { 15042, 0x79FF },
+ { 15055, 0xEFFB }, { 15069, 0x5BFE }, { 15081, 0x57BE }, { 15092, 0xBB5B },
+ { 15103, 0x7FFF }, { 15118, 0xFFFC }, { 15132, 0x872E }, { 15140, 0xAFF7 },
+ /* 0x9700 */
+ { 15153, 0xEBFD }, { 15166, 0xFB4F }, { 15178, 0xDFFF }, { 15193, 0xE767 },
+ { 15204, 0x0BDF }, { 15214, 0xFDE6 }, { 15226, 0x7747 }, { 15236, 0xFDDF },
+ { 15250, 0xEFBF }, { 15264, 0xFF90 }, { 15274, 0x7D7F }, { 15287, 0xEFDE },
+ { 15300, 0xFBFF }, { 15315, 0xF3FD }, { 15328, 0x606B }, { 15335, 0xEF6F },
+ /* 0x9800 */
+ { 15348, 0xF5FF }, { 15362, 0xF9FF }, { 15376, 0xEBDB }, { 15388, 0x0BBD },
+ { 15397, 0xFFFA }, { 15411, 0xFB8F }, { 15423, 0x9FFD }, { 15436, 0x003F },
+ { 15442, 0x0000 }, { 15442, 0x0000 }, { 15442, 0xF300 }, { 15448, 0xFFDE },
+ { 15462, 0x5FDF }, { 15475, 0xD800 }, { 15479, 0xBEEF }, { 15492, 0x7676 },
+ /* 0x9900 */
+ { 15502, 0x57AD }, { 15512, 0xDFFF }, { 15527, 0xFFB2 }, { 15539, 0xFFAF },
+ { 15553, 0x7FAF }, { 15566, 0xFBFF }, { 15581, 0x000E }, { 15584, 0x0000 },
+ { 15584, 0x0000 }, { 15584, 0x7BC0 }, { 15592, 0xFDFA }, { 15605, 0x3F3F },
+ { 15617, 0xFABE }, { 15629, 0xBFFF }, { 15644, 0x76FF }, { 15657, 0xFFF3 },
+ /* 0x9A00 */
+ { 15671, 0xFEFE }, { 15685, 0xFE73 }, { 15697, 0xFEFF }, { 15712, 0xFFF7 },
+ { 15727, 0xF77F }, { 15741, 0xDFFD }, { 15755, 0x1FFD }, { 15767, 0x0000 },
+ { 15767, 0x8000 }, { 15768, 0x0000 }, { 15768, 0xA900 }, { 15772, 0xFFDF },
+ { 15787, 0xA4C7 }, { 15795, 0x91FF }, { 15806, 0xF8CF }, { 15817, 0xFEDE },
+ /* 0x9B00 */
+ { 15830, 0xFF7E }, { 15844, 0xC7F7 }, { 15856, 0xEFBD }, { 15869, 0xDEBE },
+ { 15881, 0xFD7F }, { 15895, 0x8F77 }, { 15906, 0x93D3 }, { 15915, 0xFCF3 },
+ { 15927, 0xE9EF }, { 15939, 0xECAF }, { 15950, 0xED77 }, { 15962, 0xA361 },
+ { 15969, 0x87DB }, { 15979, 0x7EF8 }, { 15990, 0x3FF7 }, { 16003, 0xA193 },
+ /* 0x9C00 */
+ { 16010, 0x7FE4 }, { 16021, 0xB8BD }, { 16031, 0xBB7B }, { 16043, 0xFEFE },
+ { 16057, 0xFF73 }, { 16070, 0xE3FD }, { 16082, 0x61CD }, { 16090, 0x1FBE },
+ { 16101, 0x0000 }, { 16101, 0x0000 }, { 16101, 0x0000 }, { 16101, 0x0000 },
+ { 16101, 0x0000 }, { 16101, 0x0000 }, { 16101, 0x26E0 }, { 16107, 0xBEFE },
+ /* 0x9D00 */
+ { 16120, 0x13FD }, { 16130, 0xEBF5 }, { 16142, 0xE36F }, { 16153, 0xEBDB },
+ { 16165, 0xDE3F }, { 16177, 0xFFDF }, { 16192, 0xFF83 }, { 16203, 0xFBBF },
+ { 16217, 0x1FFF }, { 16230, 0xFFDD }, { 16244, 0xBFFF }, { 16259, 0xFFFE },
+ { 16274, 0xFFBF }, { 16289, 0xFFFF }, { 16305, 0xFB7E }, { 16318, 0xFFFD },
+ /* 0x9E00 */
+ { 16333, 0xFEFF }, { 16348, 0xFFBF }, { 16363, 0x0000 }, { 16363, 0x0000 },
+ { 16363, 0x0000 }, { 16363, 0x0000 }, { 16363, 0x0000 }, { 16363, 0xBE20 },
+ { 16370, 0x7FFF }, { 16385, 0xFFFF }, { 16401, 0xFFF7 }, { 16416, 0xF8F3 },
+ { 16427, 0xF1DF }, { 16439, 0xFD7B }, { 16452, 0xE9F5 }, { 16463, 0xFFFF },
+ /* 0x9F00 */
+ { 16479, 0xC7C7 }, { 16489, 0x5FED }, { 16501, 0xFFFD }, { 16516, 0x6BFF },
+ { 16529, 0xFFFF }, { 16545, 0xFFFD }, { 16560, 0xDEFF }, { 16574, 0xCFF7 },
+ { 16587, 0x6000 }, { 16589, 0x9337 }, { 16598, 0x0035 },
+};
+static const Summary16 big5hkscs_uni2index_pagee0[419] = {
+ /* 0xE000 */
+ { 16602, 0xFFFF }, { 16618, 0xFFFF }, { 16634, 0xFFFF }, { 16650, 0xFFFF },
+ { 16666, 0xFFFF }, { 16682, 0xFFFF }, { 16698, 0xFFFF }, { 16714, 0xFFFF },
+ { 16730, 0xFFFF }, { 16746, 0xFFFF }, { 16762, 0xFFFF }, { 16778, 0xFFFF },
+ { 16794, 0xFFFF }, { 16810, 0xFFFF }, { 16826, 0xFFFF }, { 16842, 0xFFFF },
+ /* 0xE100 */
+ { 16858, 0xFFFF }, { 16874, 0xFFFF }, { 16890, 0xFFFF }, { 16906, 0xFFFF },
+ { 16922, 0xFFFF }, { 16938, 0xFFFF }, { 16954, 0xFFFF }, { 16970, 0xFFFF },
+ { 16986, 0xFFFF }, { 17002, 0xFFFF }, { 17018, 0xFFFF }, { 17034, 0xFFFF },
+ { 17050, 0xFFFF }, { 17066, 0xFFFF }, { 17082, 0xFFFF }, { 17098, 0xFFFF },
+ /* 0xE200 */
+ { 17114, 0xFFFF }, { 17130, 0xFFFF }, { 17146, 0xFFFF }, { 17162, 0xFFFF },
+ { 17178, 0xFFFF }, { 17194, 0xFFFF }, { 17210, 0xFFFF }, { 17226, 0xFFFF },
+ { 17242, 0xFFFF }, { 17258, 0xFFFF }, { 17274, 0xFFFF }, { 17290, 0xFFFF },
+ { 17306, 0xFFFF }, { 17322, 0xFFFF }, { 17338, 0xFFFF }, { 17354, 0xFFFF },
+ /* 0xE300 */
+ { 17370, 0xFFFF }, { 17386, 0xFFFF }, { 17402, 0xFFFF }, { 17418, 0xFFFF },
+ { 17434, 0xFFFF }, { 17450, 0xFFFF }, { 17466, 0xFFFF }, { 17482, 0xFFFF },
+ { 17498, 0xFFFF }, { 17514, 0xFFFF }, { 17530, 0xFFFF }, { 17546, 0xFFFF },
+ { 17562, 0xFFFF }, { 17578, 0xFFFF }, { 17594, 0xFFFF }, { 17610, 0xFFFF },
+ /* 0xE400 */
+ { 17626, 0xFFFF }, { 17642, 0xFFFF }, { 17658, 0xFFFF }, { 17674, 0xFFFF },
+ { 17690, 0xFFFF }, { 17706, 0xFFFF }, { 17722, 0xFFFF }, { 17738, 0xFFFF },
+ { 17754, 0xFFFF }, { 17770, 0xFFFF }, { 17786, 0xFFFF }, { 17802, 0xFFFF },
+ { 17818, 0xFFFF }, { 17834, 0xFFFF }, { 17850, 0xFFFF }, { 17866, 0xFFFF },
+ /* 0xE500 */
+ { 17882, 0xFFFF }, { 17898, 0xFFFF }, { 17914, 0xFFFF }, { 17930, 0xFFFF },
+ { 17946, 0xFFFF }, { 17962, 0xFFFF }, { 17978, 0xFFFF }, { 17994, 0xFFFF },
+ { 18010, 0xFFFF }, { 18026, 0xFFFF }, { 18042, 0xFFFF }, { 18058, 0xFFFF },
+ { 18074, 0xFFFF }, { 18090, 0xFFFF }, { 18106, 0xFFFF }, { 18122, 0xFFFF },
+ /* 0xE600 */
+ { 18138, 0xFFFF }, { 18154, 0xFFFF }, { 18170, 0xFFFF }, { 18186, 0xFFFF },
+ { 18202, 0xFFFF }, { 18218, 0xFFFF }, { 18234, 0xFFFF }, { 18250, 0xFFFF },
+ { 18266, 0xFFFF }, { 18282, 0xFFFF }, { 18298, 0xFFFF }, { 18314, 0xFFFF },
+ { 18330, 0xFFFF }, { 18346, 0xFFFF }, { 18362, 0xFFFF }, { 18378, 0xFFFF },
+ /* 0xE700 */
+ { 18394, 0xFFFF }, { 18410, 0xFFFF }, { 18426, 0xFFFF }, { 18442, 0xFFFF },
+ { 18458, 0xFFFF }, { 18474, 0xFFFF }, { 18490, 0xFFFF }, { 18506, 0xFFFF },
+ { 18522, 0xFFFF }, { 18538, 0xFFFF }, { 18554, 0xFFFF }, { 18570, 0xFFFF },
+ { 18586, 0xFFFF }, { 18602, 0xFFFF }, { 18618, 0xFFFF }, { 18634, 0xFFFF },
+ /* 0xE800 */
+ { 18650, 0xFFFF }, { 18666, 0xFFFF }, { 18682, 0xFFFF }, { 18698, 0xFFFF },
+ { 18714, 0xFFFF }, { 18730, 0xFFFF }, { 18746, 0xFFFF }, { 18762, 0xFFFF },
+ { 18778, 0xFFFF }, { 18794, 0xFFFF }, { 18810, 0xFFFF }, { 18826, 0xFFFF },
+ { 18842, 0xFFFF }, { 18858, 0xFFFF }, { 18874, 0xFFFF }, { 18890, 0xFFFF },
+ /* 0xE900 */
+ { 18906, 0xFFFF }, { 18922, 0xFFFF }, { 18938, 0xFFFF }, { 18954, 0xFFFF },
+ { 18970, 0xFFFF }, { 18986, 0xFFFF }, { 19002, 0xFFFF }, { 19018, 0xFFFF },
+ { 19034, 0xFFFF }, { 19050, 0xFFFF }, { 19066, 0xFFFF }, { 19082, 0xFFFF },
+ { 19098, 0xFFFF }, { 19114, 0xFFFF }, { 19130, 0xFFFF }, { 19146, 0xFFFF },
+ /* 0xEA00 */
+ { 19162, 0xFFFF }, { 19178, 0xFFFF }, { 19194, 0xFFFF }, { 19210, 0xFFFF },
+ { 19226, 0xFFFF }, { 19242, 0xFFFF }, { 19258, 0xFFFF }, { 19274, 0xFFFF },
+ { 19290, 0xFFFF }, { 19306, 0xFFFF }, { 19322, 0xFFFF }, { 19338, 0xFFFF },
+ { 19354, 0xFFFF }, { 19370, 0xFFFF }, { 19386, 0xFFFF }, { 19402, 0xFFFF },
+ /* 0xEB00 */
+ { 19418, 0xFFFF }, { 19434, 0xFFFF }, { 19450, 0xFFFF }, { 19466, 0xFFFF },
+ { 19482, 0xFFFF }, { 19498, 0xFFFF }, { 19514, 0xFFFF }, { 19530, 0xFFFF },
+ { 19546, 0xFFFF }, { 19562, 0xFFFF }, { 19578, 0xFFFF }, { 19594, 0xFFFF },
+ { 19610, 0xFFFF }, { 19626, 0xFFFF }, { 19642, 0xFFFF }, { 19658, 0xFFFF },
+ /* 0xEC00 */
+ { 19674, 0xFFFF }, { 19690, 0xFFFF }, { 19706, 0xFFFF }, { 19722, 0xFFFF },
+ { 19738, 0xFFFF }, { 19754, 0xFFFF }, { 19770, 0xFFFF }, { 19786, 0xFFFF },
+ { 19802, 0xFFFF }, { 19818, 0xFFFF }, { 19834, 0xFFFF }, { 19850, 0xFFFF },
+ { 19866, 0xFFFF }, { 19882, 0xFFFF }, { 19898, 0xFFFF }, { 19914, 0xFFFF },
+ /* 0xED00 */
+ { 19930, 0xFFFF }, { 19946, 0xFFFF }, { 19962, 0xFFFF }, { 19978, 0xFFFF },
+ { 19994, 0xFFFF }, { 20010, 0xFFFF }, { 20026, 0xFFFF }, { 20042, 0xFFFF },
+ { 20058, 0xFFFF }, { 20074, 0xFFFF }, { 20090, 0xFFFF }, { 20106, 0xFFFF },
+ { 20122, 0xFFFF }, { 20138, 0xFFFF }, { 20154, 0xFFFF }, { 20170, 0xFFFF },
+ /* 0xEE00 */
+ { 20186, 0xFFFF }, { 20202, 0xFFFF }, { 20218, 0xFFFF }, { 20234, 0xFFFF },
+ { 20250, 0xFFFF }, { 20266, 0xFFFF }, { 20282, 0xFFFF }, { 20298, 0xFFFF },
+ { 20314, 0xFFFF }, { 20330, 0xFFFF }, { 20346, 0xFFFF }, { 20362, 0xFFFF },
+ { 20378, 0xFFFF }, { 20394, 0xFFFF }, { 20410, 0xFFFF }, { 20426, 0xFFFF },
+ /* 0xEF00 */
+ { 20442, 0xFFFF }, { 20458, 0xFFFF }, { 20474, 0xFFFF }, { 20490, 0xFFFF },
+ { 20506, 0xFFFF }, { 20522, 0xFFFF }, { 20538, 0xFFFF }, { 20554, 0xFFFF },
+ { 20570, 0xFFFF }, { 20586, 0xFFFF }, { 20602, 0xFFFF }, { 20618, 0xFFFF },
+ { 20634, 0xFFFF }, { 20650, 0xFFFF }, { 20666, 0xFFFF }, { 20682, 0xFFFF },
+ /* 0xF000 */
+ { 20698, 0xFFFF }, { 20714, 0xFFFF }, { 20730, 0xFFFF }, { 20746, 0xFFFF },
+ { 20762, 0xFFFF }, { 20778, 0xFFFF }, { 20794, 0xFFFF }, { 20810, 0xFFFF },
+ { 20826, 0xFFFF }, { 20842, 0xFFFF }, { 20858, 0xFFFF }, { 20874, 0xFFFF },
+ { 20890, 0xFFFF }, { 20906, 0xFFFF }, { 20922, 0xFFFF }, { 20938, 0xFFFF },
+ /* 0xF100 */
+ { 20954, 0xFFFF }, { 20970, 0xFFFF }, { 20986, 0xFFFF }, { 21002, 0xFFFF },
+ { 21018, 0xFFFF }, { 21034, 0xFFFF }, { 21050, 0xFFFF }, { 21066, 0xFFFF },
+ { 21082, 0xFFFF }, { 21098, 0xFFFF }, { 21114, 0xFFFF }, { 21130, 0xFFFF },
+ { 21146, 0xFFFF }, { 21162, 0xFFFF }, { 21178, 0xFFFF }, { 21194, 0xFFFF },
+ /* 0xF200 */
+ { 21210, 0xFFFF }, { 21226, 0xFFFF }, { 21242, 0xFFFF }, { 21258, 0xFFFF },
+ { 21274, 0xFFFF }, { 21290, 0xFFFF }, { 21306, 0xFFFF }, { 21322, 0xFFFF },
+ { 21338, 0xFFFF }, { 21354, 0xFFFF }, { 21370, 0xFFFF }, { 21386, 0xFFFF },
+ { 21402, 0xFFFF }, { 21418, 0xFFFF }, { 21434, 0xFFFF }, { 21450, 0xFFFF },
+ /* 0xF300 */
+ { 21466, 0xFFFF }, { 21482, 0xFFFF }, { 21498, 0xFFFF }, { 21514, 0xFFFF },
+ { 21530, 0xFFFF }, { 21546, 0xFFFF }, { 21562, 0xFFFF }, { 21578, 0xFFFF },
+ { 21594, 0xFFFF }, { 21610, 0xFFFF }, { 21626, 0xFFFF }, { 21642, 0xFFFF },
+ { 21658, 0xFFFF }, { 21674, 0xFFFF }, { 21690, 0xFFFF }, { 21706, 0xFFFF },
+ /* 0xF400 */
+ { 21722, 0xFFFF }, { 21738, 0xFFFF }, { 21754, 0xFFFF }, { 21770, 0xFFFF },
+ { 21786, 0xFFFF }, { 21802, 0xFFFF }, { 21818, 0xFFFF }, { 21834, 0xFFFF },
+ { 21850, 0xFFFF }, { 21866, 0xFFFF }, { 21882, 0xFFFF }, { 21898, 0xFFFF },
+ { 21914, 0xFFFF }, { 21930, 0xFFFF }, { 21946, 0xFFFF }, { 21962, 0xFFFF },
+ /* 0xF500 */
+ { 21978, 0xFFFF }, { 21994, 0xFFFF }, { 22010, 0xFFFF }, { 22026, 0xFFFF },
+ { 22042, 0xFFFF }, { 22058, 0xFFFF }, { 22074, 0xFFFF }, { 22090, 0xFFFF },
+ { 22106, 0xFFFF }, { 22122, 0xFFFF }, { 22138, 0xFFFF }, { 22154, 0xFFFF },
+ { 22170, 0xFFFF }, { 22186, 0xFFFF }, { 22202, 0xFFFF }, { 22218, 0xFFFF },
+ /* 0xF600 */
+ { 22234, 0xFFFF }, { 22250, 0xFFFF }, { 22266, 0xFFFF }, { 22282, 0xFFFF },
+ { 22298, 0xFFFF }, { 22314, 0xFFFF }, { 22330, 0xFFFF }, { 22346, 0xFFFF },
+ { 22362, 0xFFFF }, { 22378, 0xFFFF }, { 22394, 0xFFFF }, { 22410, 0xFFFF },
+ { 22426, 0xFFFF }, { 22442, 0xFFFF }, { 22458, 0xFFFF }, { 22474, 0xFFFF },
+ /* 0xF700 */
+ { 22490, 0xFFFF }, { 22506, 0xFFFF }, { 22522, 0xFFFF }, { 22538, 0xFFFF },
+ { 22554, 0xFFFF }, { 22570, 0xFFFF }, { 22586, 0xFFFF }, { 22602, 0xFFFF },
+ { 22618, 0xFFFF }, { 22634, 0xFFFF }, { 22650, 0xFFFF }, { 22666, 0xFFFF },
+ { 22682, 0xFFFF }, { 22698, 0xFFFF }, { 22714, 0xFFFF }, { 22730, 0xFFFF },
+ /* 0xF800 */
+ { 22746, 0xFFFF }, { 22762, 0xFFFF }, { 22778, 0xFFFF }, { 22794, 0xFFFF },
+ { 22810, 0x01FF }, { 22819, 0x0000 }, { 22819, 0x0000 }, { 22819, 0x0000 },
+ { 22819, 0x0000 }, { 22819, 0x0000 }, { 22819, 0x0000 }, { 22819, 0x0000 },
+ { 22819, 0x0000 }, { 22819, 0x0000 }, { 22819, 0x0000 }, { 22819, 0x0100 },
+ /* 0xF900 */
+ { 22820, 0xFFFF }, { 22836, 0xFFFF }, { 22852, 0xEFFF }, { 22867, 0xFFFF },
+ { 22883, 0xFFFF }, { 22899, 0xFFFF }, { 22915, 0xFFFF }, { 22931, 0xFDFF },
+ { 22946, 0xFFFF }, { 22962, 0xFFDF }, { 22977, 0xFFFF }, { 22993, 0xFFFF },
+ { 23009, 0xFFFF }, { 23025, 0xFFFF }, { 23041, 0xFF7F }, { 23056, 0xFFFD },
+ /* 0xFA00 */
+ { 23071, 0x3FFF }, { 23085, 0x7EE5 }, { 23096, 0x3C64 },
+};
+static const Summary16 big5hkscs_uni2index_pagefe[31] = {
+ /* 0xFE00 */
+ { 23103, 0x0000 }, { 23103, 0x0000 }, { 23103, 0x0000 }, { 23103, 0xFFFB },
+ { 23118, 0xFE1F }, { 23130, 0xFEF7 }, { 23144, 0x0F7F }, { 23155, 0x0000 },
+ { 23155, 0x0000 }, { 23155, 0x0000 }, { 23155, 0x0000 }, { 23155, 0x0000 },
+ { 23155, 0x0000 }, { 23155, 0x0000 }, { 23155, 0x0000 }, { 23155, 0x0000 },
+ /* 0xFF00 */
+ { 23155, 0xFFFE }, { 23170, 0xFFFF }, { 23186, 0xFFFF }, { 23202, 0xFFFF },
+ { 23218, 0xFFFF }, { 23234, 0x7FFF }, { 23249, 0x0010 }, { 23250, 0x0000 },
+ { 23250, 0x0000 }, { 23250, 0x0000 }, { 23250, 0x0000 }, { 23250, 0x0000 },
+ { 23250, 0x0000 }, { 23250, 0x0000 }, { 23250, 0x203F },
+};
+static const Summary16 big5hkscs_uni2index_page200[2335] = {
+ /* 0x20000 */
+ { 23257, 0x0000 }, { 23257, 0x0000 }, { 23257, 0x0002 }, { 23258, 0x4000 },
+ { 23259, 0x4040 }, { 23261, 0x0000 }, { 23261, 0x0100 }, { 23262, 0x0000 },
+ { 23262, 0x04C0 }, { 23265, 0x0010 }, { 23266, 0x0000 }, { 23266, 0x0000 },
+ { 23266, 0x3C00 }, { 23270, 0x0002 }, { 23271, 0x4000 }, { 23272, 0x0000 },
+ /* 0x20100 */
+ { 23272, 0x5000 }, { 23274, 0x0100 }, { 23275, 0x0000 }, { 23275, 0x0000 },
+ { 23275, 0x0000 }, { 23275, 0x0000 }, { 23275, 0x0000 }, { 23275, 0x0000 },
+ { 23275, 0x0000 }, { 23275, 0x0000 }, { 23275, 0x0A00 }, { 23277, 0x0000 },
+ { 23277, 0x0002 }, { 23278, 0x0010 }, { 23279, 0x0000 }, { 23279, 0x0004 },
+ /* 0x20200 */
+ { 23280, 0x1010 }, { 23282, 0x0010 }, { 23283, 0x0000 }, { 23283, 0x0000 },
+ { 23283, 0x0000 }, { 23283, 0x0800 }, { 23284, 0x0000 }, { 23284, 0x0030 },
+ { 23286, 0x0000 }, { 23286, 0x4200 }, { 23288, 0x0001 }, { 23289, 0x8080 },
+ { 23291, 0x0001 }, { 23292, 0x0000 }, { 23292, 0x0020 }, { 23293, 0x0000 },
+ /* 0x20300 */
+ { 23293, 0x0400 }, { 23294, 0x0000 }, { 23294, 0x0020 }, { 23295, 0x0000 },
+ { 23295, 0x00E2 }, { 23299, 0x0000 }, { 23299, 0x0000 }, { 23299, 0xC000 },
+ { 23301, 0x0001 }, { 23302, 0x0000 }, { 23302, 0x0081 }, { 23304, 0x0020 },
+ { 23305, 0x0A00 }, { 23307, 0x0000 }, { 23307, 0x0000 }, { 23307, 0x1020 },
+ /* 0x20400 */
+ { 23309, 0x0000 }, { 23309, 0x8018 }, { 23312, 0x0000 }, { 23312, 0x0000 },
+ { 23312, 0x0000 }, { 23312, 0x0000 }, { 23312, 0x0020 }, { 23313, 0x0000 },
+ { 23313, 0x4080 }, { 23315, 0x0006 }, { 23317, 0x0008 }, { 23318, 0x0000 },
+ { 23318, 0x0000 }, { 23318, 0x0080 }, { 23319, 0x0000 }, { 23319, 0x5000 },
+ /* 0x20500 */
+ { 23321, 0x0000 }, { 23321, 0x0000 }, { 23321, 0x0000 }, { 23321, 0x0000 },
+ { 23321, 0x0080 }, { 23322, 0x0000 }, { 23322, 0x0000 }, { 23322, 0x0000 },
+ { 23322, 0x4000 }, { 23323, 0x0000 }, { 23323, 0x0020 }, { 23324, 0x0008 },
+ { 23325, 0x0408 }, { 23327, 0x8021 }, { 23330, 0x0801 }, { 23332, 0x0000 },
+ /* 0x20600 */
+ { 23332, 0x0000 }, { 23332, 0x0622 }, { 23336, 0x0000 }, { 23336, 0x0001 },
+ { 23337, 0x0000 }, { 23337, 0x0040 }, { 23338, 0x0000 }, { 23338, 0x0040 },
+ { 23339, 0x0000 }, { 23339, 0x0000 }, { 23339, 0x0000 }, { 23339, 0x0000 },
+ { 23339, 0x0000 }, { 23339, 0x0000 }, { 23339, 0x0000 }, { 23339, 0x0000 },
+ /* 0x20700 */
+ { 23339, 0x4000 }, { 23340, 0x0000 }, { 23340, 0x0000 }, { 23340, 0x0002 },
+ { 23341, 0x0000 }, { 23341, 0x0000 }, { 23341, 0x0000 }, { 23341, 0x0200 },
+ { 23342, 0x0000 }, { 23342, 0x0000 }, { 23342, 0x0000 }, { 23342, 0x0000 },
+ { 23342, 0x0000 }, { 23342, 0x0000 }, { 23342, 0x0000 }, { 23342, 0x0000 },
+ /* 0x20800 */
+ { 23342, 0x0000 }, { 23342, 0x0000 }, { 23342, 0x1000 }, { 23343, 0x0000 },
+ { 23343, 0x0000 }, { 23343, 0x0000 }, { 23343, 0x0000 }, { 23343, 0x0008 },
+ { 23344, 0x0000 }, { 23344, 0x0000 }, { 23344, 0x0000 }, { 23344, 0x0000 },
+ { 23344, 0x0000 }, { 23344, 0x0020 }, { 23345, 0x0000 }, { 23345, 0x0000 },
+ /* 0x20900 */
+ { 23345, 0x0000 }, { 23345, 0x0040 }, { 23346, 0x0008 }, { 23347, 0x0000 },
+ { 23347, 0x0000 }, { 23347, 0x0010 }, { 23348, 0x0000 }, { 23348, 0x0200 },
+ { 23349, 0x0000 }, { 23349, 0x0000 }, { 23349, 0x0000 }, { 23349, 0x0000 },
+ { 23349, 0x0000 }, { 23349, 0x0000 }, { 23349, 0x0080 }, { 23350, 0x0000 },
+ /* 0x20A00 */
+ { 23350, 0x0000 }, { 23350, 0x0002 }, { 23351, 0x0000 }, { 23351, 0x0000 },
+ { 23351, 0x0000 }, { 23351, 0x0001 }, { 23352, 0x0000 }, { 23352, 0x0000 },
+ { 23352, 0x0000 }, { 23352, 0x0000 }, { 23352, 0x0000 }, { 23352, 0x0010 },
+ { 23353, 0x2004 }, { 23355, 0x0000 }, { 23355, 0x0000 }, { 23355, 0x0000 },
+ /* 0x20B00 */
+ { 23355, 0x2000 }, { 23356, 0x0000 }, { 23356, 0x0000 }, { 23356, 0x0000 },
+ { 23356, 0x0000 }, { 23356, 0x0000 }, { 23356, 0x0000 }, { 23356, 0x0000 },
+ { 23356, 0x8000 }, { 23357, 0x0000 }, { 23357, 0x0300 }, { 23359, 0x8000 },
+ { 23360, 0x0840 }, { 23362, 0x0000 }, { 23362, 0x0804 }, { 23364, 0x8800 },
+ /* 0x20C00 */
+ { 23366, 0x2800 }, { 23368, 0x0000 }, { 23368, 0x0001 }, { 23369, 0x0C10 },
+ { 23372, 0x000E }, { 23375, 0x0008 }, { 23376, 0x0020 }, { 23377, 0x1180 },
+ { 23380, 0x2000 }, { 23381, 0x1040 }, { 23383, 0x0000 }, { 23383, 0x0120 },
+ { 23385, 0x8000 }, { 23386, 0x2078 }, { 23391, 0x2000 }, { 23392, 0x8000 },
+ /* 0x20D00 */
+ { 23393, 0x0000 }, { 23393, 0x0020 }, { 23394, 0x0100 }, { 23395, 0x0006 },
+ { 23397, 0x73C0 }, { 23404, 0x0000 }, { 23404, 0x8000 }, { 23405, 0xD012 },
+ { 23410, 0x0000 }, { 23410, 0x1040 }, { 23412, 0x0080 }, { 23413, 0x0004 },
+ { 23414, 0x0100 }, { 23415, 0x0000 }, { 23415, 0x0000 }, { 23415, 0x0000 },
+ /* 0x20E00 */
+ { 23415, 0xE610 }, { 23421, 0x2043 }, { 23425, 0x0000 }, { 23425, 0x0000 },
+ { 23425, 0x1000 }, { 23426, 0x0000 }, { 23426, 0x2000 }, { 23427, 0x0FE8 },
+ { 23435, 0x1000 }, { 23436, 0x2140 }, { 23439, 0x1C04 }, { 23443, 0x0040 },
+ { 23444, 0x0000 }, { 23444, 0x2180 }, { 23447, 0x0000 }, { 23447, 0x0F00 },
+ /* 0x20F00 */
+ { 23451, 0x0000 }, { 23451, 0x2000 }, { 23452, 0x6040 }, { 23455, 0x0803 },
+ { 23458, 0x1000 }, { 23459, 0x0000 }, { 23459, 0x0010 }, { 23460, 0x0000 },
+ { 23460, 0x2000 }, { 23461, 0x0001 }, { 23462, 0x2000 }, { 23463, 0x1070 },
+ { 23467, 0x0000 }, { 23467, 0x8000 }, { 23468, 0x3C00 }, { 23472, 0x0000 },
+ /* 0x21000 */
+ { 23472, 0x0000 }, { 23472, 0x6010 }, { 23475, 0x0000 }, { 23475, 0x0000 },
+ { 23475, 0x8000 }, { 23476, 0x1000 }, { 23477, 0x8000 }, { 23478, 0x09E0 },
+ { 23483, 0x0100 }, { 23484, 0x2040 }, { 23486, 0x0000 }, { 23486, 0x8010 },
+ { 23488, 0x8383 }, { 23494, 0x0008 }, { 23495, 0x0010 }, { 23496, 0x0070 },
+ /* 0x21100 */
+ { 23499, 0x0000 }, { 23499, 0x0000 }, { 23499, 0x8000 }, { 23500, 0x2800 },
+ { 23502, 0x8120 }, { 23505, 0x0000 }, { 23505, 0x0000 }, { 23505, 0x0000 },
+ { 23505, 0x0081 }, { 23507, 0x0000 }, { 23507, 0x0000 }, { 23507, 0x0000 },
+ { 23507, 0x0000 }, { 23507, 0x0200 }, { 23508, 0x0000 }, { 23508, 0x0000 },
+ /* 0x21200 */
+ { 23508, 0x0000 }, { 23508, 0x0000 }, { 23508, 0x0000 }, { 23508, 0x1000 },
+ { 23509, 0x8000 }, { 23510, 0x0000 }, { 23510, 0x0000 }, { 23510, 0x1000 },
+ { 23511, 0x0000 }, { 23511, 0x0000 }, { 23511, 0x0300 }, { 23513, 0x0001 },
+ { 23514, 0x0000 }, { 23514, 0x0000 }, { 23514, 0x0008 }, { 23515, 0x4000 },
+ /* 0x21300 */
+ { 23516, 0x003C }, { 23520, 0x0000 }, { 23520, 0x0000 }, { 23520, 0x0440 },
+ { 23522, 0x0000 }, { 23522, 0x0000 }, { 23522, 0x0000 }, { 23522, 0x0060 },
+ { 23524, 0x4000 }, { 23525, 0x1100 }, { 23527, 0x0000 }, { 23527, 0x0000 },
+ { 23527, 0x0060 }, { 23529, 0x0000 }, { 23529, 0x2000 }, { 23530, 0x4000 },
+ /* 0x21400 */
+ { 23531, 0x0000 }, { 23531, 0x0048 }, { 23533, 0x0010 }, { 23534, 0x8000 },
+ { 23535, 0x0000 }, { 23535, 0x0034 }, { 23538, 0x0000 }, { 23538, 0x0000 },
+ { 23538, 0x0400 }, { 23539, 0x0080 }, { 23540, 0x0000 }, { 23540, 0x0040 },
+ { 23541, 0x0000 }, { 23541, 0x0000 }, { 23541, 0x0100 }, { 23542, 0x2000 },
+ /* 0x21500 */
+ { 23543, 0x0000 }, { 23543, 0x0000 }, { 23543, 0x0000 }, { 23543, 0x0000 },
+ { 23543, 0x0000 }, { 23543, 0x0000 }, { 23543, 0x0000 }, { 23543, 0x0080 },
+ { 23544, 0x0004 }, { 23545, 0x0040 }, { 23546, 0x0000 }, { 23546, 0x0000 },
+ { 23546, 0x0000 }, { 23546, 0x0000 }, { 23546, 0x0000 }, { 23546, 0x0000 },
+ /* 0x21600 */
+ { 23546, 0x0400 }, { 23547, 0x0208 }, { 23549, 0x0000 }, { 23549, 0x4000 },
+ { 23550, 0x0000 }, { 23550, 0x0000 }, { 23550, 0x0002 }, { 23551, 0x0000 },
+ { 23551, 0x0000 }, { 23551, 0x0004 }, { 23552, 0x0000 }, { 23552, 0x0500 },
+ { 23554, 0x0007 }, { 23557, 0x8028 }, { 23560, 0x01C0 }, { 23563, 0x5C00 },
+ /* 0x21700 */
+ { 23567, 0x2000 }, { 23568, 0x0001 }, { 23569, 0x0040 }, { 23570, 0x1C00 },
+ { 23573, 0x0000 }, { 23573, 0x0080 }, { 23574, 0xF000 }, { 23578, 0x001B },
+ { 23582, 0x0000 }, { 23582, 0x0000 }, { 23582, 0x0800 }, { 23583, 0x003F },
+ { 23589, 0x0088 }, { 23591, 0x9E00 }, { 23596, 0x8000 }, { 23597, 0x1F60 },
+ /* 0x21800 */
+ { 23604, 0x0000 }, { 23604, 0x0000 }, { 23604, 0x2701 }, { 23609, 0x0E00 },
+ { 23612, 0x0021 }, { 23614, 0x4004 }, { 23616, 0x001E }, { 23620, 0x0880 },
+ { 23622, 0x0038 }, { 23625, 0xC000 }, { 23627, 0x0007 }, { 23630, 0xC000 },
+ { 23632, 0x0000 }, { 23632, 0x03C2 }, { 23637, 0x0000 }, { 23637, 0x0400 },
+ /* 0x21900 */
+ { 23638, 0x0038 }, { 23641, 0x1027 }, { 23646, 0x0084 }, { 23648, 0x0800 },
+ { 23649, 0x0010 }, { 23650, 0x0100 }, { 23651, 0x0400 }, { 23652, 0x1000 },
+ { 23653, 0x0109 }, { 23656, 0x0040 }, { 23657, 0x0000 }, { 23657, 0x0000 },
+ { 23657, 0x0000 }, { 23657, 0x0800 }, { 23658, 0x0000 }, { 23658, 0x0008 },
+ /* 0x21A00 */
+ { 23659, 0x0000 }, { 23659, 0x0000 }, { 23659, 0x2000 }, { 23660, 0x0010 },
+ { 23661, 0x0820 }, { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 },
+ { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 },
+ { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 },
+ /* 0x21B00 */
+ { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 }, { 23663, 0x0000 },
+ { 23663, 0x0010 }, { 23664, 0x0000 }, { 23664, 0x0000 }, { 23664, 0x0000 },
+ { 23664, 0x0000 }, { 23664, 0x0000 }, { 23664, 0x0000 }, { 23664, 0x0000 },
+ { 23664, 0x0006 }, { 23666, 0x0000 }, { 23666, 0x0000 }, { 23666, 0x0000 },
+ /* 0x21C00 */
+ { 23666, 0x0000 }, { 23666, 0x0000 }, { 23666, 0x0400 }, { 23667, 0x0000 },
+ { 23667, 0x0000 }, { 23667, 0x0000 }, { 23667, 0x0000 }, { 23667, 0x0001 },
+ { 23668, 0x0000 }, { 23668, 0x0000 }, { 23668, 0x1024 }, { 23671, 0x0000 },
+ { 23671, 0x0000 }, { 23671, 0x0000 }, { 23671, 0x0000 }, { 23671, 0x0000 },
+ /* 0x21D00 */
+ { 23671, 0x0000 }, { 23671, 0x0000 }, { 23671, 0x0000 }, { 23671, 0x0000 },
+ { 23671, 0x0040 }, { 23672, 0x0000 }, { 23672, 0x0000 }, { 23672, 0x0000 },
+ { 23672, 0x0000 }, { 23672, 0x0001 }, { 23673, 0x0000 }, { 23673, 0x0440 },
+ { 23675, 0x0400 }, { 23676, 0x0002 }, { 23677, 0x0800 }, { 23678, 0x0200 },
+ /* 0x21E00 */
+ { 23679, 0x0000 }, { 23679, 0x1000 }, { 23680, 0x0000 }, { 23680, 0x2080 },
+ { 23682, 0x0000 }, { 23682, 0x0000 }, { 23682, 0x0000 }, { 23682, 0x0000 },
+ { 23682, 0x0200 }, { 23683, 0x0000 }, { 23683, 0x0110 }, { 23685, 0x0000 },
+ { 23685, 0x0100 }, { 23686, 0x0020 }, { 23687, 0x0000 }, { 23687, 0x0000 },
+ /* 0x21F00 */
+ { 23687, 0x8000 }, { 23688, 0x0020 }, { 23689, 0x0000 }, { 23689, 0x0000 },
+ { 23689, 0x0000 }, { 23689, 0x0000 }, { 23689, 0x0400 }, { 23690, 0x0000 },
+ { 23690, 0x0000 }, { 23690, 0x4000 }, { 23691, 0x0002 }, { 23692, 0x0000 },
+ { 23692, 0x0000 }, { 23692, 0x0000 }, { 23692, 0x0100 }, { 23693, 0x0000 },
+ /* 0x22000 */
+ { 23693, 0x0000 }, { 23693, 0x0000 }, { 23693, 0x0000 }, { 23693, 0x0000 },
+ { 23693, 0x0220 }, { 23695, 0x0000 }, { 23695, 0x0000 }, { 23695, 0x4000 },
+ { 23696, 0x0000 }, { 23696, 0x0400 }, { 23697, 0x0000 }, { 23697, 0x0000 },
+ { 23697, 0x0080 }, { 23698, 0x0000 }, { 23698, 0x0000 }, { 23698, 0x1000 },
+ /* 0x22100 */
+ { 23699, 0x0000 }, { 23699, 0x0000 }, { 23699, 0x0400 }, { 23700, 0x0000 },
+ { 23700, 0x0000 }, { 23700, 0x0800 }, { 23701, 0x0000 }, { 23701, 0x0408 },
+ { 23703, 0x0000 }, { 23703, 0x0000 }, { 23703, 0x0002 }, { 23704, 0x0000 },
+ { 23704, 0x0008 }, { 23705, 0x0000 }, { 23705, 0x0000 }, { 23705, 0x0000 },
+ /* 0x22200 */
+ { 23705, 0x0100 }, { 23706, 0x0000 }, { 23706, 0x0000 }, { 23706, 0x0000 },
+ { 23706, 0x0000 }, { 23706, 0x0000 }, { 23706, 0x0000 }, { 23706, 0x1000 },
+ { 23707, 0x0000 }, { 23707, 0x0000 }, { 23707, 0x0000 }, { 23707, 0x0000 },
+ { 23707, 0x0000 }, { 23707, 0x0000 }, { 23707, 0x0000 }, { 23707, 0x0000 },
+ /* 0x22300 */
+ { 23707, 0x0000 }, { 23707, 0x0000 }, { 23707, 0x0022 }, { 23709, 0x0000 },
+ { 23709, 0x0000 }, { 23709, 0x0000 }, { 23709, 0x0000 }, { 23709, 0x0000 },
+ { 23709, 0x0000 }, { 23709, 0x0000 }, { 23709, 0x0000 }, { 23709, 0x2000 },
+ { 23710, 0x0000 }, { 23710, 0x0081 }, { 23712, 0x0000 }, { 23712, 0x0400 },
+ /* 0x22400 */
+ { 23713, 0x0000 }, { 23713, 0x0000 }, { 23713, 0x0000 }, { 23713, 0x0000 },
+ { 23713, 0x0000 }, { 23713, 0x0000 }, { 23713, 0x0020 }, { 23714, 0x0002 },
+ { 23715, 0x0800 }, { 23716, 0x0002 }, { 23717, 0x0000 }, { 23717, 0x0001 },
+ { 23718, 0x0000 }, { 23718, 0x0000 }, { 23718, 0x2000 }, { 23719, 0x0000 },
+ /* 0x22500 */
+ { 23719, 0x0000 }, { 23719, 0x0808 }, { 23721, 0x0000 }, { 23721, 0x0001 },
+ { 23722, 0x0000 }, { 23722, 0x0010 }, { 23723, 0x0000 }, { 23723, 0x0000 },
+ { 23723, 0x2000 }, { 23724, 0x0000 }, { 23724, 0x8000 }, { 23725, 0x4000 },
+ { 23726, 0x0000 }, { 23726, 0x0000 }, { 23726, 0x0000 }, { 23726, 0x0000 },
+ /* 0x22600 */
+ { 23726, 0x0000 }, { 23726, 0x1800 }, { 23728, 0x0800 }, { 23729, 0x0000 },
+ { 23729, 0x0000 }, { 23729, 0x0000 }, { 23729, 0x0100 }, { 23730, 0x0400 },
+ { 23731, 0x0000 }, { 23731, 0x0140 }, { 23733, 0x0000 }, { 23733, 0x0000 },
+ { 23733, 0x0000 }, { 23733, 0x0000 }, { 23733, 0x0000 }, { 23733, 0x0070 },
+ /* 0x22700 */
+ { 23736, 0x0000 }, { 23736, 0x8814 }, { 23740, 0x0400 }, { 23741, 0x0000 },
+ { 23741, 0x0000 }, { 23741, 0x0000 }, { 23741, 0x0000 }, { 23741, 0x0020 },
+ { 23742, 0x0002 }, { 23743, 0x0000 }, { 23743, 0x0000 }, { 23743, 0x0030 },
+ { 23745, 0x2000 }, { 23746, 0x0000 }, { 23746, 0x0000 }, { 23746, 0x0000 },
+ /* 0x22800 */
+ { 23746, 0x0008 }, { 23747, 0x0000 }, { 23747, 0x0000 }, { 23747, 0x0000 },
+ { 23747, 0x0000 }, { 23747, 0x8000 }, { 23748, 0x0001 }, { 23749, 0x0002 },
+ { 23750, 0x0000 }, { 23750, 0x0000 }, { 23750, 0x2000 }, { 23751, 0x0000 },
+ { 23751, 0x0002 }, { 23752, 0x0000 }, { 23752, 0x0000 }, { 23752, 0x0080 },
+ /* 0x22900 */
+ { 23753, 0x0000 }, { 23753, 0x0000 }, { 23753, 0x0040 }, { 23754, 0x0200 },
+ { 23755, 0x8000 }, { 23756, 0x0000 }, { 23756, 0x0880 }, { 23758, 0x0000 },
+ { 23758, 0x0001 }, { 23759, 0x0008 }, { 23760, 0x0000 }, { 23760, 0x0000 },
+ { 23760, 0x0000 }, { 23760, 0x0000 }, { 23760, 0x0000 }, { 23760, 0x0000 },
+ /* 0x22A00 */
+ { 23760, 0x0000 }, { 23760, 0x0000 }, { 23760, 0x0000 }, { 23760, 0x0000 },
+ { 23760, 0x0000 }, { 23760, 0x0000 }, { 23760, 0x0040 }, { 23761, 0x0000 },
+ { 23761, 0x0000 }, { 23761, 0x0000 }, { 23761, 0x0000 }, { 23761, 0x0000 },
+ { 23761, 0x8000 }, { 23762, 0x0020 }, { 23763, 0x0140 }, { 23765, 0x0000 },
+ /* 0x22B00 */
+ { 23765, 0x4000 }, { 23766, 0x0000 }, { 23766, 0x0004 }, { 23767, 0x8000 },
+ { 23768, 0x0008 }, { 23769, 0x0000 }, { 23769, 0x0400 }, { 23770, 0x0000 },
+ { 23770, 0x0000 }, { 23770, 0x0000 }, { 23770, 0x0000 }, { 23770, 0x0000 },
+ { 23770, 0x4400 }, { 23772, 0x0000 }, { 23772, 0x0000 }, { 23772, 0x0000 },
+ /* 0x22C00 */
+ { 23772, 0x0000 }, { 23772, 0x0000 }, { 23772, 0x00C0 }, { 23774, 0x0100 },
+ { 23775, 0x1000 }, { 23776, 0x0022 }, { 23778, 0x0004 }, { 23779, 0x0000 },
+ { 23779, 0x0100 }, { 23780, 0x0800 }, { 23781, 0x0202 }, { 23783, 0x0084 },
+ { 23785, 0x0244 }, { 23788, 0x0000 }, { 23788, 0x0000 }, { 23788, 0x0000 },
+ /* 0x22D00 */
+ { 23788, 0x0180 }, { 23790, 0x0004 }, { 23791, 0x0000 }, { 23791, 0x0000 },
+ { 23791, 0x1010 }, { 23793, 0x0000 }, { 23793, 0x0080 }, { 23794, 0x0000 },
+ { 23794, 0x2000 }, { 23795, 0x0020 }, { 23796, 0x0019 }, { 23799, 0x0080 },
+ { 23800, 0x0000 }, { 23800, 0x0000 }, { 23800, 0x4000 }, { 23801, 0x0000 },
+ /* 0x22E00 */
+ { 23801, 0x2000 }, { 23802, 0x0000 }, { 23802, 0x0000 }, { 23802, 0x0040 },
+ { 23803, 0x0004 }, { 23804, 0x0000 }, { 23804, 0x0000 }, { 23804, 0x0100 },
+ { 23805, 0x0800 }, { 23806, 0x0000 }, { 23806, 0x0000 }, { 23806, 0x0008 },
+ { 23807, 0x0000 }, { 23807, 0x0000 }, { 23807, 0x8000 }, { 23808, 0x0000 },
+ /* 0x22F00 */
+ { 23808, 0x0000 }, { 23808, 0x0000 }, { 23808, 0x0000 }, { 23808, 0x0000 },
+ { 23808, 0x0000 }, { 23808, 0x0000 }, { 23808, 0x0000 }, { 23808, 0x0010 },
+ { 23809, 0x0000 }, { 23809, 0x0000 }, { 23809, 0x0000 }, { 23809, 0x0000 },
+ { 23809, 0x1000 }, { 23810, 0x0000 }, { 23810, 0x0008 }, { 23811, 0x0000 },
+ /* 0x23000 */
+ { 23811, 0x0000 }, { 23811, 0x0000 }, { 23811, 0x0000 }, { 23811, 0x0008 },
+ { 23812, 0x0810 }, { 23814, 0x0000 }, { 23814, 0x0040 }, { 23815, 0x6000 },
+ { 23817, 0x4000 }, { 23818, 0x0000 }, { 23818, 0x0000 }, { 23818, 0x1080 },
+ { 23820, 0x0000 }, { 23820, 0x0400 }, { 23821, 0x0000 }, { 23821, 0x0000 },
+ /* 0x23100 */
+ { 23821, 0x0008 }, { 23822, 0x0000 }, { 23822, 0x0000 }, { 23822, 0x2000 },
+ { 23823, 0x0000 }, { 23823, 0x0000 }, { 23823, 0x0000 }, { 23823, 0x2000 },
+ { 23824, 0x0004 }, { 23825, 0x0000 }, { 23825, 0x0030 }, { 23827, 0x0008 },
+ { 23828, 0x0300 }, { 23830, 0x0000 }, { 23830, 0x0000 }, { 23830, 0x0380 },
+ /* 0x23200 */
+ { 23833, 0x8000 }, { 23834, 0x0000 }, { 23834, 0x8020 }, { 23836, 0x001E },
+ { 23840, 0x0000 }, { 23840, 0x0000 }, { 23840, 0x0004 }, { 23841, 0x0000 },
+ { 23841, 0x0602 }, { 23844, 0x0000 }, { 23844, 0x3800 }, { 23847, 0x0000 },
+ { 23847, 0x0000 }, { 23847, 0x0004 }, { 23848, 0x0003 }, { 23850, 0x0000 },
+ /* 0x23300 */
+ { 23850, 0x0401 }, { 23852, 0x8000 }, { 23853, 0x0000 }, { 23853, 0x0000 },
+ { 23853, 0x0000 }, { 23853, 0x0000 }, { 23853, 0x0000 }, { 23853, 0x0000 },
+ { 23853, 0x0000 }, { 23853, 0x0000 }, { 23853, 0x0000 }, { 23853, 0x0010 },
+ { 23854, 0x1000 }, { 23855, 0x4000 }, { 23856, 0x0040 }, { 23857, 0x4630 },
+ /* 0x23400 */
+ { 23862, 0x0001 }, { 23863, 0x0000 }, { 23863, 0x0000 }, { 23863, 0x8000 },
+ { 23864, 0x0000 }, { 23864, 0x0001 }, { 23865, 0x8000 }, { 23866, 0x0004 },
+ { 23867, 0x0000 }, { 23867, 0x0000 }, { 23867, 0x0000 }, { 23867, 0x0000 },
+ { 23867, 0x0000 }, { 23867, 0x0000 }, { 23867, 0x0020 }, { 23868, 0x0000 },
+ /* 0x23500 */
+ { 23868, 0x0000 }, { 23868, 0x0200 }, { 23869, 0x0000 }, { 23869, 0x0001 },
+ { 23870, 0x0000 }, { 23870, 0x0400 }, { 23871, 0x0080 }, { 23872, 0x0000 },
+ { 23872, 0x0000 }, { 23872, 0x1220 }, { 23875, 0x0000 }, { 23875, 0x0000 },
+ { 23875, 0xE000 }, { 23878, 0x0000 }, { 23878, 0x0000 }, { 23878, 0x0008 },
+ /* 0x23600 */
+ { 23879, 0x0001 }, { 23880, 0x0400 }, { 23881, 0x0000 }, { 23881, 0x1000 },
+ { 23882, 0x0001 }, { 23883, 0x8200 }, { 23885, 0x0000 }, { 23885, 0x0080 },
+ { 23886, 0x0000 }, { 23886, 0x0000 }, { 23886, 0x2040 }, { 23888, 0x0400 },
+ { 23889, 0x0000 }, { 23889, 0x8000 }, { 23890, 0x4000 }, { 23891, 0x0000 },
+ /* 0x23700 */
+ { 23891, 0x0008 }, { 23892, 0x0040 }, { 23893, 0xA001 }, { 23896, 0x8000 },
+ { 23897, 0x0000 }, { 23897, 0x0000 }, { 23897, 0x0040 }, { 23898, 0x0000 },
+ { 23898, 0x0002 }, { 23899, 0x0000 }, { 23899, 0x0004 }, { 23900, 0x1000 },
+ { 23901, 0x0004 }, { 23902, 0x00E0 }, { 23905, 0x0000 }, { 23905, 0x0000 },
+ /* 0x23800 */
+ { 23905, 0x0000 }, { 23905, 0x0000 }, { 23905, 0x0000 }, { 23905, 0x0400 },
+ { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 },
+ { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 },
+ { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 },
+ /* 0x23900 */
+ { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 },
+ { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 },
+ { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 }, { 23906, 0x0000 },
+ { 23906, 0x0004 }, { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0000 },
+ /* 0x23A00 */
+ { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0000 },
+ { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0000 },
+ { 23907, 0x0000 }, { 23907, 0x0000 }, { 23907, 0x0080 }, { 23908, 0x0000 },
+ { 23908, 0x0000 }, { 23908, 0x0800 }, { 23909, 0x4000 }, { 23910, 0x0400 },
+ /* 0x23B00 */
+ { 23911, 0x0000 }, { 23911, 0x0000 }, { 23911, 0x0000 }, { 23911, 0x0000 },
+ { 23911, 0x0000 }, { 23911, 0x0400 }, { 23912, 0x0000 }, { 23912, 0x0000 },
+ { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 },
+ { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 },
+ /* 0x23C00 */
+ { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0000 },
+ { 23912, 0x0000 }, { 23912, 0x0000 }, { 23912, 0x0008 }, { 23913, 0x0000 },
+ { 23913, 0x0000 }, { 23913, 0x0E00 }, { 23916, 0x0000 }, { 23916, 0x00A0 },
+ { 23918, 0x0380 }, { 23921, 0x0000 }, { 23921, 0x0000 }, { 23921, 0xF000 },
+ /* 0x23D00 */
+ { 23925, 0x0000 }, { 23925, 0x0000 }, { 23925, 0x0000 }, { 23925, 0x0000 },
+ { 23925, 0x0001 }, { 23926, 0x0800 }, { 23927, 0x0000 }, { 23927, 0x4000 },
+ { 23928, 0x8000 }, { 23929, 0x0000 }, { 23929, 0x0000 }, { 23929, 0x3FC0 },
+ { 23937, 0x0000 }, { 23937, 0x0000 }, { 23937, 0x0008 }, { 23938, 0x0100 },
+ /* 0x23E00 */
+ { 23939, 0x0000 }, { 23939, 0x0002 }, { 23940, 0xF000 }, { 23944, 0x0203 },
+ { 23947, 0x0000 }, { 23947, 0x0000 }, { 23947, 0x0000 }, { 23947, 0x0000 },
+ { 23947, 0x0F00 }, { 23951, 0x0000 }, { 23951, 0x0000 }, { 23951, 0x8200 },
+ { 23953, 0x0000 }, { 23953, 0x0080 }, { 23954, 0x0000 }, { 23954, 0x1F80 },
+ /* 0x23F00 */
+ { 23960, 0x0000 }, { 23960, 0x0000 }, { 23960, 0x0000 }, { 23960, 0x0020 },
+ { 23961, 0x0402 }, { 23963, 0x0000 }, { 23963, 0x0000 }, { 23963, 0x8000 },
+ { 23964, 0x8007 }, { 23968, 0x0000 }, { 23968, 0x0000 }, { 23968, 0x0090 },
+ { 23970, 0x0021 }, { 23972, 0x0000 }, { 23972, 0xF800 }, { 23977, 0x0001 },
+ /* 0x24000 */
+ { 23978, 0x0000 }, { 23978, 0x0002 }, { 23979, 0x0000 }, { 23979, 0x3E00 },
+ { 23984, 0x0000 }, { 23984, 0x0080 }, { 23985, 0x0000 }, { 23985, 0x0000 },
+ { 23985, 0x3820 }, { 23989, 0x0002 }, { 23990, 0x0000 }, { 23990, 0x0000 },
+ { 23990, 0x0200 }, { 23991, 0x0000 }, { 23991, 0x0002 }, { 23992, 0x0000 },
+ /* 0x24100 */
+ { 23992, 0x8010 }, { 23994, 0x0200 }, { 23995, 0x0000 }, { 23995, 0x8000 },
+ { 23996, 0x4011 }, { 23999, 0x90E0 }, { 24004, 0x0000 }, { 24004, 0x0480 },
+ { 24006, 0x0000 }, { 24006, 0x0000 }, { 24006, 0x1038 }, { 24010, 0x0020 },
+ { 24011, 0x2000 }, { 24012, 0x0000 }, { 24012, 0x0004 }, { 24013, 0x1000 },
+ /* 0x24200 */
+ { 24014, 0x0000 }, { 24014, 0x0800 }, { 24015, 0x0000 }, { 24015, 0x0000 },
+ { 24015, 0x0800 }, { 24016, 0x0240 }, { 24018, 0x0000 }, { 24018, 0x01C0 },
+ { 24021, 0x0010 }, { 24022, 0x0028 }, { 24024, 0x0020 }, { 24025, 0x0000 },
+ { 24025, 0x0602 }, { 24028, 0x0000 }, { 24028, 0x4000 }, { 24029, 0x0400 },
+ /* 0x24300 */
+ { 24030, 0x2000 }, { 24031, 0x0400 }, { 24032, 0x0000 }, { 24032, 0x0010 },
+ { 24033, 0x0100 }, { 24034, 0x0000 }, { 24034, 0x003C }, { 24038, 0x0000 },
+ { 24038, 0x1000 }, { 24039, 0x1040 }, { 24041, 0x0000 }, { 24041, 0x2000 },
+ { 24042, 0x0002 }, { 24043, 0x0000 }, { 24043, 0x0600 }, { 24045, 0x0104 },
+ /* 0x24400 */
+ { 24047, 0x0010 }, { 24048, 0x0000 }, { 24048, 0x0000 }, { 24048, 0x0060 },
+ { 24050, 0x0000 }, { 24050, 0x0C00 }, { 24052, 0x0000 }, { 24052, 0x0008 },
+ { 24053, 0x0180 }, { 24055, 0x0000 }, { 24055, 0x0000 }, { 24055, 0x1200 },
+ { 24057, 0x4000 }, { 24058, 0x0048 }, { 24060, 0x0000 }, { 24060, 0x0000 },
+ /* 0x24500 */
+ { 24060, 0x0020 }, { 24061, 0x0000 }, { 24061, 0x0002 }, { 24062, 0x0000 },
+ { 24062, 0x0000 }, { 24062, 0x0000 }, { 24062, 0x0000 }, { 24062, 0x0100 },
+ { 24063, 0x0000 }, { 24063, 0x0000 }, { 24063, 0x0000 }, { 24063, 0x0000 },
+ { 24063, 0x0100 }, { 24064, 0x0000 }, { 24064, 0x0000 }, { 24064, 0x0000 },
+ /* 0x24600 */
+ { 24064, 0x0000 }, { 24064, 0x0100 }, { 24065, 0x0400 }, { 24066, 0x0000 },
+ { 24066, 0x0000 }, { 24066, 0x0000 }, { 24066, 0x0020 }, { 24067, 0x0010 },
+ { 24068, 0x0000 }, { 24068, 0x0080 }, { 24069, 0x0000 }, { 24069, 0x0000 },
+ { 24069, 0x0000 }, { 24069, 0x0010 }, { 24070, 0x0000 }, { 24070, 0x0000 },
+ /* 0x24700 */
+ { 24070, 0x0040 }, { 24071, 0x0000 }, { 24071, 0x8020 }, { 24073, 0x0000 },
+ { 24073, 0x0000 }, { 24073, 0x0000 }, { 24073, 0x0000 }, { 24073, 0x0000 },
+ { 24073, 0x8000 }, { 24074, 0x0000 }, { 24074, 0x0000 }, { 24074, 0x0000 },
+ { 24074, 0x0000 }, { 24074, 0x0000 }, { 24074, 0x0001 }, { 24075, 0x0000 },
+ /* 0x24800 */
+ { 24075, 0x0000 }, { 24075, 0x0004 }, { 24076, 0x0008 }, { 24077, 0x0000 },
+ { 24077, 0x0000 }, { 24077, 0x0000 }, { 24077, 0x0000 }, { 24077, 0x0000 },
+ { 24077, 0x0004 }, { 24078, 0x0000 }, { 24078, 0x0000 }, { 24078, 0x0000 },
+ { 24078, 0x0000 }, { 24078, 0x0000 }, { 24078, 0x0200 }, { 24079, 0x880F },
+ /* 0x24900 */
+ { 24085, 0x1003 }, { 24088, 0x02C0 }, { 24091, 0x8000 }, { 24092, 0xC018 },
+ { 24096, 0x000F }, { 24100, 0x0000 }, { 24100, 0x000C }, { 24102, 0x8870 },
+ { 24107, 0xFF04 }, { 24116, 0x0010 }, { 24117, 0x3A90 }, { 24123, 0x0F80 },
+ { 24128, 0x0020 }, { 24129, 0xC401 }, { 24133, 0x3028 }, { 24137, 0x0BC0 },
+ /* 0x24A00 */
+ { 24142, 0x4000 }, { 24143, 0x002C }, { 24146, 0x07FE }, { 24156, 0x4000 },
+ { 24157, 0xC424 }, { 24162, 0x2003 }, { 24165, 0x00E0 }, { 24168, 0x0782 },
+ { 24173, 0x1000 }, { 24174, 0x0078 }, { 24178, 0x00F0 }, { 24182, 0x1C0E },
+ { 24188, 0x0481 }, { 24191, 0x8002 }, { 24193, 0x0204 }, { 24195, 0x0000 },
+ /* 0x24B00 */
+ { 24195, 0x0000 }, { 24195, 0x0000 }, { 24195, 0x0000 }, { 24195, 0x0000 },
+ { 24195, 0x0000 }, { 24195, 0x0000 }, { 24195, 0x4000 }, { 24196, 0x0000 },
+ { 24196, 0x0000 }, { 24196, 0x0000 }, { 24196, 0x0000 }, { 24196, 0x0000 },
+ { 24196, 0x0000 }, { 24196, 0x0000 }, { 24196, 0x0000 }, { 24196, 0x0020 },
+ /* 0x24C00 */
+ { 24197, 0x0200 }, { 24198, 0x0000 }, { 24198, 0x0000 }, { 24198, 0x0000 },
+ { 24198, 0x0000 }, { 24198, 0x0000 }, { 24198, 0x0000 }, { 24198, 0x0000 },
+ { 24198, 0x0000 }, { 24198, 0xC000 }, { 24200, 0x0000 }, { 24200, 0x0000 },
+ { 24200, 0x0200 }, { 24201, 0x0200 }, { 24202, 0x0000 }, { 24202, 0x0000 },
+ /* 0x24D00 */
+ { 24202, 0x0040 }, { 24203, 0x0008 }, { 24204, 0x0000 }, { 24204, 0x0000 },
+ { 24204, 0x0000 }, { 24204, 0x0000 }, { 24204, 0x0000 }, { 24204, 0x0000 },
+ { 24204, 0x0000 }, { 24204, 0x0000 }, { 24204, 0x0000 }, { 24204, 0x0100 },
+ { 24205, 0x0000 }, { 24205, 0x0000 }, { 24205, 0x0C00 }, { 24207, 0x0000 },
+ /* 0x24E00 */
+ { 24207, 0x0000 }, { 24207, 0x0000 }, { 24207, 0x0000 }, { 24207, 0x0800 },
+ { 24208, 0x0000 }, { 24208, 0x0001 }, { 24209, 0x0000 }, { 24209, 0x0000 },
+ { 24209, 0x0000 }, { 24209, 0x0000 }, { 24209, 0x00A0 }, { 24211, 0x0000 },
+ { 24211, 0x0000 }, { 24211, 0x0000 }, { 24211, 0x0000 }, { 24211, 0x0000 },
+ /* 0x24F00 */
+ { 24211, 0x4000 }, { 24212, 0x0000 }, { 24212, 0x0000 }, { 24212, 0x0000 },
+ { 24212, 0x0000 }, { 24212, 0x1000 }, { 24213, 0x0000 }, { 24213, 0x0000 },
+ { 24213, 0x0044 }, { 24215, 0x0480 }, { 24217, 0x0200 }, { 24218, 0x0100 },
+ { 24219, 0x0004 }, { 24220, 0x0000 }, { 24220, 0x0000 }, { 24220, 0x0000 },
+ /* 0x25000 */
+ { 24220, 0x0000 }, { 24220, 0x0000 }, { 24220, 0x1000 }, { 24221, 0x0000 },
+ { 24221, 0x0000 }, { 24221, 0x0004 }, { 24222, 0x0000 }, { 24222, 0x0000 },
+ { 24222, 0x0000 }, { 24222, 0x2000 }, { 24223, 0x0000 }, { 24223, 0x0000 },
+ { 24223, 0x0000 }, { 24223, 0x0000 }, { 24223, 0x0000 }, { 24223, 0x0000 },
+ /* 0x25100 */
+ { 24223, 0x0000 }, { 24223, 0x0000 }, { 24223, 0x0800 }, { 24224, 0x0000 },
+ { 24224, 0x0100 }, { 24225, 0x0000 }, { 24225, 0x0000 }, { 24225, 0x6000 },
+ { 24227, 0x0000 }, { 24227, 0x0000 }, { 24227, 0x0000 }, { 24227, 0x0000 },
+ { 24227, 0x2000 }, { 24228, 0x0000 }, { 24228, 0x00C8 }, { 24231, 0x0000 },
+ /* 0x25200 */
+ { 24231, 0x0000 }, { 24231, 0x0000 }, { 24231, 0x0003 }, { 24233, 0x0000 },
+ { 24233, 0x0000 }, { 24233, 0x0001 }, { 24234, 0x0000 }, { 24234, 0x0000 },
+ { 24234, 0x0000 }, { 24234, 0x0200 }, { 24235, 0x0000 }, { 24235, 0x0000 },
+ { 24235, 0x0080 }, { 24236, 0x0100 }, { 24237, 0x0000 }, { 24237, 0x0000 },
+ /* 0x25300 */
+ { 24237, 0x4000 }, { 24238, 0x000A }, { 24240, 0x0000 }, { 24240, 0x0000 },
+ { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 },
+ { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 },
+ { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 }, { 24240, 0x0000 },
+ /* 0x25400 */
+ { 24240, 0x0000 }, { 24240, 0x0200 }, { 24241, 0x8020 }, { 24243, 0x0001 },
+ { 24244, 0x0040 }, { 24245, 0x0000 }, { 24245, 0x5000 }, { 24247, 0x0000 },
+ { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x0000 },
+ { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x0000 },
+ /* 0x25500 */
+ { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x0000 }, { 24247, 0x8022 },
+ { 24250, 0x0000 }, { 24250, 0x7800 }, { 24254, 0x0064 }, { 24257, 0x0000 },
+ { 24257, 0x8012 }, { 24260, 0x0000 }, { 24260, 0x0000 }, { 24260, 0x0200 },
+ { 24261, 0x0000 }, { 24261, 0x0820 }, { 24263, 0x0001 }, { 24264, 0x0000 },
+ /* 0x25600 */
+ { 24264, 0x0020 }, { 24265, 0x0000 }, { 24265, 0x0000 }, { 24265, 0x0020 },
+ { 24266, 0x0000 }, { 24266, 0x0002 }, { 24267, 0x0000 }, { 24267, 0x0000 },
+ { 24267, 0x0008 }, { 24268, 0x0020 }, { 24269, 0x0000 }, { 24269, 0x0000 },
+ { 24269, 0x0000 }, { 24269, 0x0000 }, { 24269, 0x0008 }, { 24270, 0x0040 },
+ /* 0x25700 */
+ { 24271, 0x0040 }, { 24272, 0x2000 }, { 24273, 0x0020 }, { 24274, 0x2000 },
+ { 24275, 0x0000 }, { 24275, 0x0000 }, { 24275, 0x0000 }, { 24275, 0x0004 },
+ { 24276, 0x0000 }, { 24276, 0x0000 }, { 24276, 0x0000 }, { 24276, 0x0000 },
+ { 24276, 0x0080 }, { 24277, 0x8000 }, { 24278, 0x0003 }, { 24280, 0x0000 },
+ /* 0x25800 */
+ { 24280, 0x0000 }, { 24280, 0x0000 }, { 24280, 0x0000 }, { 24280, 0x0000 },
+ { 24280, 0x0000 }, { 24280, 0x2080 }, { 24282, 0x0000 }, { 24282, 0x0004 },
+ { 24283, 0x0000 }, { 24283, 0x0000 }, { 24283, 0x0000 }, { 24283, 0x0000 },
+ { 24283, 0x0100 }, { 24284, 0x0000 }, { 24284, 0x0002 }, { 24285, 0x0000 },
+ /* 0x25900 */
+ { 24285, 0x0008 }, { 24286, 0x0000 }, { 24286, 0x0000 }, { 24286, 0x0000 },
+ { 24286, 0x0040 }, { 24287, 0x0040 }, { 24288, 0x0000 }, { 24288, 0x0000 },
+ { 24288, 0x0000 }, { 24288, 0x0000 }, { 24288, 0x1000 }, { 24289, 0x0000 },
+ { 24289, 0x1000 }, { 24290, 0x0000 }, { 24290, 0x0000 }, { 24290, 0x0000 },
+ /* 0x25A00 */
+ { 24290, 0x0000 }, { 24290, 0x0000 }, { 24290, 0x0000 }, { 24290, 0x0000 },
+ { 24290, 0x0000 }, { 24290, 0x0000 }, { 24290, 0x0000 }, { 24290, 0x0000 },
+ { 24290, 0x0000 }, { 24290, 0x1020 }, { 24292, 0xC000 }, { 24294, 0x0000 },
+ { 24294, 0x0000 }, { 24294, 0x0000 }, { 24294, 0x0200 }, { 24295, 0x0000 },
+ /* 0x25B00 */
+ { 24295, 0x0000 }, { 24295, 0x0000 }, { 24295, 0x0000 }, { 24295, 0x0000 },
+ { 24295, 0x0000 }, { 24295, 0x0000 }, { 24295, 0x0000 }, { 24295, 0x0010 },
+ { 24296, 0x0200 }, { 24297, 0x0000 }, { 24297, 0x0000 }, { 24297, 0x0018 },
+ { 24299, 0x0040 }, { 24300, 0x0000 }, { 24300, 0x0110 }, { 24302, 0x0000 },
+ /* 0x25C00 */
+ { 24302, 0x0042 }, { 24304, 0x0000 }, { 24304, 0x0002 }, { 24305, 0x0000 },
+ { 24305, 0x0400 }, { 24306, 0x0000 }, { 24306, 0x0020 }, { 24307, 0x0000 },
+ { 24307, 0x0000 }, { 24307, 0x0002 }, { 24308, 0x0010 }, { 24309, 0x0000 },
+ { 24309, 0x0003 }, { 24311, 0x0000 }, { 24311, 0x0000 }, { 24311, 0x4000 },
+ /* 0x25D00 */
+ { 24312, 0x0000 }, { 24312, 0x0000 }, { 24312, 0x0001 }, { 24313, 0x0001 },
+ { 24314, 0x0008 }, { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 },
+ { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 },
+ { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 },
+ /* 0x25E00 */
+ { 24315, 0x4000 }, { 24316, 0x0000 }, { 24316, 0x0000 }, { 24316, 0x0000 },
+ { 24316, 0x0200 }, { 24317, 0x0000 }, { 24317, 0x0000 }, { 24317, 0x0000 },
+ { 24317, 0x000E }, { 24320, 0x0000 }, { 24320, 0x0040 }, { 24321, 0x1000 },
+ { 24322, 0x0000 }, { 24322, 0x0180 }, { 24324, 0x0000 }, { 24324, 0x0000 },
+ /* 0x25F00 */
+ { 24324, 0x0000 }, { 24324, 0x0400 }, { 24325, 0x0000 }, { 24325, 0x0000 },
+ { 24325, 0x0800 }, { 24326, 0x0000 }, { 24326, 0x0000 }, { 24326, 0x0000 },
+ { 24326, 0x0000 }, { 24326, 0x0000 }, { 24326, 0x0000 }, { 24326, 0x0000 },
+ { 24326, 0x0000 }, { 24326, 0x0000 }, { 24326, 0x0006 }, { 24328, 0x0000 },
+ /* 0x26000 */
+ { 24328, 0x0000 }, { 24328, 0x0000 }, { 24328, 0x0200 }, { 24329, 0x0000 },
+ { 24329, 0x0100 }, { 24330, 0x0000 }, { 24330, 0x0010 }, { 24331, 0x0000 },
+ { 24331, 0x0008 }, { 24332, 0x0080 }, { 24333, 0x0030 }, { 24335, 0x0000 },
+ { 24335, 0x0000 }, { 24335, 0x0000 }, { 24335, 0x0000 }, { 24335, 0x0000 },
+ /* 0x26100 */
+ { 24335, 0x0004 }, { 24336, 0x0000 }, { 24336, 0x0002 }, { 24337, 0x0000 },
+ { 24337, 0x0000 }, { 24337, 0x1E00 }, { 24341, 0x0000 }, { 24341, 0x0000 },
+ { 24341, 0x0000 }, { 24341, 0x0000 }, { 24341, 0x6000 }, { 24343, 0x0004 },
+ { 24344, 0x0000 }, { 24344, 0x2000 }, { 24345, 0x0000 }, { 24345, 0x0000 },
+ /* 0x26200 */
+ { 24345, 0x0000 }, { 24345, 0x0000 }, { 24345, 0x0000 }, { 24345, 0x0000 },
+ { 24345, 0x0000 }, { 24345, 0x0100 }, { 24346, 0x0C02 }, { 24349, 0x0000 },
+ { 24349, 0x0000 }, { 24349, 0x0000 }, { 24349, 0x0000 }, { 24349, 0x0000 },
+ { 24349, 0x0000 }, { 24349, 0x0001 }, { 24350, 0x0000 }, { 24350, 0x0000 },
+ /* 0x26300 */
+ { 24350, 0x0000 }, { 24350, 0x0000 }, { 24350, 0x0000 }, { 24350, 0x0020 },
+ { 24351, 0x1800 }, { 24353, 0x0002 }, { 24354, 0x0000 }, { 24354, 0x0000 },
+ { 24354, 0x0000 }, { 24354, 0x0000 }, { 24354, 0x0000 }, { 24354, 0x4000 },
+ { 24355, 0x0000 }, { 24355, 0x0000 }, { 24355, 0x0000 }, { 24355, 0x0120 },
+ /* 0x26400 */
+ { 24357, 0x0004 }, { 24358, 0x0007 }, { 24361, 0x0000 }, { 24361, 0x0000 },
+ { 24361, 0x0400 }, { 24362, 0x0000 }, { 24362, 0x0200 }, { 24363, 0x0000 },
+ { 24363, 0x2310 }, { 24367, 0x0100 }, { 24368, 0x0000 }, { 24368, 0x0000 },
+ { 24368, 0x0000 }, { 24368, 0x0000 }, { 24368, 0x0000 }, { 24368, 0x0000 },
+ /* 0x26500 */
+ { 24368, 0x0000 }, { 24368, 0x0004 }, { 24369, 0x0000 }, { 24369, 0x0000 },
+ { 24369, 0x0000 }, { 24369, 0x0000 }, { 24369, 0x0000 }, { 24369, 0x0004 },
+ { 24370, 0x0000 }, { 24370, 0x0000 }, { 24370, 0x2001 }, { 24372, 0x8000 },
+ { 24373, 0x0000 }, { 24373, 0x0000 }, { 24373, 0x0000 }, { 24373, 0x0000 },
+ /* 0x26600 */
+ { 24373, 0x0000 }, { 24373, 0x0004 }, { 24374, 0x0040 }, { 24375, 0x0000 },
+ { 24375, 0x0000 }, { 24375, 0x0000 }, { 24375, 0x0000 }, { 24375, 0x0000 },
+ { 24375, 0x0000 }, { 24375, 0x0000 }, { 24375, 0x8000 }, { 24376, 0x0022 },
+ { 24378, 0x0000 }, { 24378, 0x0400 }, { 24379, 0x0100 }, { 24380, 0x1000 },
+ /* 0x26700 */
+ { 24381, 0x0000 }, { 24381, 0x0040 }, { 24382, 0x0000 }, { 24382, 0x0000 },
+ { 24382, 0x0002 }, { 24383, 0x0000 }, { 24383, 0x0000 }, { 24383, 0x0000 },
+ { 24383, 0x0000 }, { 24383, 0x0200 }, { 24384, 0x0000 }, { 24384, 0x0018 },
+ { 24386, 0x1000 }, { 24387, 0x0000 }, { 24387, 0x0000 }, { 24387, 0x0000 },
+ /* 0x26800 */
+ { 24387, 0x0000 }, { 24387, 0x1000 }, { 24388, 0x0000 }, { 24388, 0x0000 },
+ { 24388, 0x0040 }, { 24389, 0x4000 }, { 24390, 0x4000 }, { 24391, 0x0000 },
+ { 24391, 0x0500 }, { 24393, 0x0008 }, { 24394, 0x0000 }, { 24394, 0x0000 },
+ { 24394, 0x0080 }, { 24395, 0x0000 }, { 24395, 0x0000 }, { 24395, 0x0000 },
+ /* 0x26900 */
+ { 24395, 0x4000 }, { 24396, 0x0002 }, { 24397, 0x0040 }, { 24398, 0x0200 },
+ { 24399, 0x0000 }, { 24399, 0x0002 }, { 24400, 0x0000 }, { 24400, 0x0000 },
+ { 24400, 0x0000 }, { 24400, 0x0000 }, { 24400, 0x0100 }, { 24401, 0x0020 },
+ { 24402, 0x0000 }, { 24402, 0x0000 }, { 24402, 0x0000 }, { 24402, 0x0404 },
+ /* 0x26A00 */
+ { 24404, 0x0000 }, { 24404, 0x0000 }, { 24404, 0x6000 }, { 24406, 0x0010 },
+ { 24407, 0x0004 }, { 24408, 0x0006 }, { 24410, 0x0000 }, { 24410, 0x0000 },
+ { 24410, 0x0000 }, { 24410, 0x0000 }, { 24410, 0x0000 }, { 24410, 0x0000 },
+ { 24410, 0x0000 }, { 24410, 0x0000 }, { 24410, 0x0000 }, { 24410, 0x0000 },
+ /* 0x26B00 */
+ { 24410, 0x0420 }, { 24412, 0x0028 }, { 24414, 0x0100 }, { 24415, 0x0000 },
+ { 24415, 0x0000 }, { 24415, 0x080F }, { 24420, 0x0000 }, { 24420, 0x0020 },
+ { 24421, 0x0004 }, { 24422, 0x20C0 }, { 24425, 0x0000 }, { 24425, 0x0008 },
+ { 24426, 0x0001 }, { 24427, 0x0000 }, { 24427, 0x0000 }, { 24427, 0x0080 },
+ /* 0x26C00 */
+ { 24428, 0x0000 }, { 24428, 0x0000 }, { 24428, 0x0002 }, { 24429, 0x0000 },
+ { 24429, 0x0001 }, { 24430, 0x0000 }, { 24430, 0x0000 }, { 24430, 0xC000 },
+ { 24432, 0x0007 }, { 24435, 0x0000 }, { 24435, 0x0010 }, { 24436, 0x2180 },
+ { 24439, 0x0009 }, { 24441, 0x0002 }, { 24442, 0x0000 }, { 24442, 0x0000 },
+ /* 0x26D00 */
+ { 24442, 0x0000 }, { 24442, 0x0000 }, { 24442, 0x07FC }, { 24451, 0x0000 },
+ { 24451, 0x0000 }, { 24451, 0x0002 }, { 24452, 0x0000 }, { 24452, 0x0010 },
+ { 24453, 0x0000 }, { 24453, 0x0000 }, { 24453, 0x40FF }, { 24462, 0x0000 },
+ { 24462, 0x0000 }, { 24462, 0x1000 }, { 24463, 0x0C00 }, { 24465, 0x0001 },
+ /* 0x26E00 */
+ { 24466, 0x00A1 }, { 24469, 0x0004 }, { 24470, 0x0000 }, { 24470, 0x0000 },
+ { 24470, 0x003C }, { 24474, 0x0000 }, { 24474, 0x4000 }, { 24475, 0x0084 },
+ { 24477, 0x0010 }, { 24478, 0x0200 }, { 24479, 0x0000 }, { 24479, 0x0000 },
+ { 24479, 0x0000 }, { 24479, 0x00FF }, { 24487, 0x0000 }, { 24487, 0x0000 },
+ /* 0x26F00 */
+ { 24487, 0x0000 }, { 24487, 0x0000 }, { 24487, 0x0040 }, { 24488, 0x0000 },
+ { 24488, 0x0000 }, { 24488, 0x0000 }, { 24488, 0x0000 }, { 24488, 0x0018 },
+ { 24490, 0x0000 }, { 24490, 0x8000 }, { 24491, 0x0002 }, { 24492, 0x4000 },
+ { 24493, 0x0000 }, { 24493, 0xC000 }, { 24495, 0x0000 }, { 24495, 0x0000 },
+ /* 0x27000 */
+ { 24495, 0x4000 }, { 24496, 0x0000 }, { 24496, 0x0000 }, { 24496, 0x0000 },
+ { 24496, 0x0800 }, { 24497, 0x000C }, { 24499, 0x0000 }, { 24499, 0x0000 },
+ { 24499, 0x0100 }, { 24500, 0x0000 }, { 24500, 0xE000 }, { 24503, 0x0000 },
+ { 24503, 0x2000 }, { 24504, 0x0000 }, { 24504, 0x0000 }, { 24504, 0x0100 },
+ /* 0x27100 */
+ { 24505, 0x3200 }, { 24508, 0x0000 }, { 24508, 0x00C0 }, { 24510, 0x0000 },
+ { 24510, 0x0000 }, { 24510, 0x0000 }, { 24510, 0x0030 }, { 24512, 0x0020 },
+ { 24513, 0x0000 }, { 24513, 0x0000 }, { 24513, 0x0000 }, { 24513, 0x0000 },
+ { 24513, 0x2000 }, { 24514, 0x0000 }, { 24514, 0x0000 }, { 24514, 0x0000 },
+ /* 0x27200 */
+ { 24514, 0x0000 }, { 24514, 0x0800 }, { 24515, 0x0000 }, { 24515, 0x0000 },
+ { 24515, 0x0000 }, { 24515, 0x0000 }, { 24515, 0x0000 }, { 24515, 0x0000 },
+ { 24515, 0x0821 }, { 24518, 0x0000 }, { 24518, 0x0000 }, { 24518, 0x0044 },
+ { 24520, 0x0000 }, { 24520, 0x0000 }, { 24520, 0x0040 }, { 24521, 0x0000 },
+ /* 0x27300 */
+ { 24521, 0x0000 }, { 24521, 0x0000 }, { 24521, 0x0000 }, { 24521, 0x0000 },
+ { 24521, 0x0000 }, { 24521, 0x0000 }, { 24521, 0x0000 }, { 24521, 0x0000 },
+ { 24521, 0x0000 }, { 24521, 0x0400 }, { 24522, 0x0000 }, { 24522, 0x0000 },
+ { 24522, 0x0000 }, { 24522, 0x0000 }, { 24522, 0x0000 }, { 24522, 0x0000 },
+ /* 0x27400 */
+ { 24522, 0x0000 }, { 24522, 0x0000 }, { 24522, 0x0004 }, { 24523, 0x0000 },
+ { 24523, 0x0000 }, { 24523, 0x0001 }, { 24524, 0x0000 }, { 24524, 0x0000 },
+ { 24524, 0x0050 }, { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 },
+ { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 },
+ /* 0x27500 */
+ { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 },
+ { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0000 }, { 24526, 0x0010 },
+ { 24527, 0x0000 }, { 24527, 0x0000 }, { 24527, 0x0008 }, { 24528, 0x0000 },
+ { 24528, 0x0000 }, { 24528, 0x0000 }, { 24528, 0x0011 }, { 24530, 0x6000 },
+ /* 0x27600 */
+ { 24532, 0x1080 }, { 24534, 0x0000 }, { 24534, 0x0000 }, { 24534, 0x0204 },
+ { 24536, 0x0000 }, { 24536, 0x00E0 }, { 24539, 0x0000 }, { 24539, 0x0000 },
+ { 24539, 0x0000 }, { 24539, 0x0010 }, { 24540, 0x0000 }, { 24540, 0x0000 },
+ { 24540, 0x0000 }, { 24540, 0x0000 }, { 24540, 0x0000 }, { 24540, 0x0000 },
+ /* 0x27700 */
+ { 24540, 0x8000 }, { 24541, 0x0000 }, { 24541, 0x0000 }, { 24541, 0x0060 },
+ { 24543, 0x0002 }, { 24544, 0x4000 }, { 24545, 0x0000 }, { 24545, 0x0000 },
+ { 24545, 0x0030 }, { 24547, 0x0000 }, { 24547, 0x0000 }, { 24547, 0x0000 },
+ { 24547, 0x1000 }, { 24548, 0x0000 }, { 24548, 0x0000 }, { 24548, 0x0000 },
+ /* 0x27800 */
+ { 24548, 0x0000 }, { 24548, 0x0000 }, { 24548, 0x0000 }, { 24548, 0x0000 },
+ { 24548, 0x0000 }, { 24548, 0x0100 }, { 24549, 0x0000 }, { 24549, 0x0001 },
+ { 24550, 0x0000 }, { 24550, 0x2000 }, { 24551, 0x0000 }, { 24551, 0x0004 },
+ { 24552, 0x0100 }, { 24553, 0x0000 }, { 24553, 0x0000 }, { 24553, 0x0000 },
+ /* 0x27900 */
+ { 24553, 0x0000 }, { 24553, 0x0000 }, { 24553, 0x0010 }, { 24554, 0x0000 },
+ { 24554, 0x0000 }, { 24554, 0x0000 }, { 24554, 0x0080 }, { 24555, 0x0400 },
+ { 24556, 0x0000 }, { 24556, 0x0000 }, { 24556, 0x0001 }, { 24557, 0x0000 },
+ { 24557, 0x0000 }, { 24557, 0x2000 }, { 24558, 0x0000 }, { 24558, 0x2000 },
+ /* 0x27A00 */
+ { 24559, 0x4400 }, { 24561, 0x0000 }, { 24561, 0x0000 }, { 24561, 0x4000 },
+ { 24562, 0x0000 }, { 24562, 0x0208 }, { 24564, 0x0000 }, { 24564, 0x0200 },
+ { 24565, 0x0010 }, { 24566, 0x0000 }, { 24566, 0x0000 }, { 24566, 0x6000 },
+ { 24568, 0x0000 }, { 24568, 0x0000 }, { 24568, 0x0000 }, { 24568, 0x0010 },
+ /* 0x27B00 */
+ { 24569, 0x0840 }, { 24571, 0x0100 }, { 24572, 0x0000 }, { 24572, 0x0700 },
+ { 24575, 0x0100 }, { 24576, 0x0000 }, { 24576, 0x0000 }, { 24576, 0x0000 },
+ { 24576, 0x0000 }, { 24576, 0x0000 }, { 24576, 0x0000 }, { 24576, 0x0000 },
+ { 24576, 0x0000 }, { 24576, 0x0000 }, { 24576, 0x0000 }, { 24576, 0x0010 },
+ /* 0x27C00 */
+ { 24577, 0x0000 }, { 24577, 0x0004 }, { 24578, 0x0000 }, { 24578, 0x0000 },
+ { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 },
+ { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 },
+ { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x0000 },
+ /* 0x27D00 */
+ { 24578, 0x0000 }, { 24578, 0x0000 }, { 24578, 0x8000 }, { 24579, 0x0000 },
+ { 24579, 0x0000 }, { 24579, 0x0018 }, { 24581, 0x0040 }, { 24582, 0x0008 },
+ { 24583, 0x8010 }, { 24585, 0x0100 }, { 24586, 0x0000 }, { 24586, 0x2000 },
+ { 24587, 0x0000 }, { 24587, 0x1000 }, { 24588, 0x0000 }, { 24588, 0x0000 },
+ /* 0x27E00 */
+ { 24588, 0x0000 }, { 24588, 0x0000 }, { 24588, 0x0000 }, { 24588, 0x0000 },
+ { 24588, 0xA000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 },
+ { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 },
+ { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 },
+ /* 0x27F00 */
+ { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 },
+ { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 },
+ { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 },
+ { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0000 }, { 24590, 0x0200 },
+ /* 0x28000 */
+ { 24591, 0x0204 }, { 24593, 0x4000 }, { 24594, 0x0018 }, { 24596, 0x0000 },
+ { 24596, 0x0100 }, { 24597, 0x0000 }, { 24597, 0x0000 }, { 24597, 0x0000 },
+ { 24597, 0x0008 }, { 24598, 0x0001 }, { 24599, 0x0000 }, { 24599, 0x6000 },
+ { 24601, 0x0000 }, { 24601, 0x0000 }, { 24601, 0x0300 }, { 24603, 0x0010 },
+ /* 0x28100 */
+ { 24604, 0x0000 }, { 24604, 0x0000 }, { 24604, 0x4000 }, { 24605, 0x0000 },
+ { 24605, 0x8000 }, { 24606, 0x2000 }, { 24607, 0x8000 }, { 24608, 0x0000 },
+ { 24608, 0x0200 }, { 24609, 0x0000 }, { 24609, 0x8000 }, { 24610, 0x1000 },
+ { 24611, 0x0000 }, { 24611, 0x0000 }, { 24611, 0x0000 }, { 24611, 0x0000 },
+ /* 0x28200 */
+ { 24611, 0x0080 }, { 24612, 0x0500 }, { 24614, 0x0000 }, { 24614, 0x0000 },
+ { 24614, 0x0000 }, { 24614, 0x0040 }, { 24615, 0x0000 }, { 24615, 0x1000 },
+ { 24616, 0x0000 }, { 24616, 0x0800 }, { 24617, 0x0000 }, { 24617, 0x0000 },
+ { 24617, 0x2000 }, { 24618, 0x0000 }, { 24618, 0x0004 }, { 24619, 0x0000 },
+ /* 0x28300 */
+ { 24619, 0x0040 }, { 24620, 0x0100 }, { 24621, 0x8000 }, { 24622, 0x0400 },
+ { 24623, 0x0000 }, { 24623, 0x0000 }, { 24623, 0x2020 }, { 24625, 0x2000 },
+ { 24626, 0x0400 }, { 24627, 0x0000 }, { 24627, 0x0000 }, { 24627, 0x0000 },
+ { 24627, 0x0000 }, { 24627, 0x0000 }, { 24627, 0x0000 }, { 24627, 0x0000 },
+ /* 0x28400 */
+ { 24627, 0x0000 }, { 24627, 0x0004 }, { 24628, 0x0000 }, { 24628, 0x0000 },
+ { 24628, 0x0000 }, { 24628, 0x0000 }, { 24628, 0x1100 }, { 24630, 0x0008 },
+ { 24631, 0x0004 }, { 24632, 0x0000 }, { 24632, 0x0000 }, { 24632, 0x0000 },
+ { 24632, 0x0000 }, { 24632, 0x0000 }, { 24632, 0x0000 }, { 24632, 0x0000 },
+ /* 0x28500 */
+ { 24632, 0x0002 }, { 24633, 0x0000 }, { 24633, 0x0000 }, { 24633, 0x3000 },
+ { 24635, 0x0000 }, { 24635, 0x0000 }, { 24635, 0x1000 }, { 24636, 0x0000 },
+ { 24636, 0x0000 }, { 24636, 0x0000 }, { 24636, 0x0000 }, { 24636, 0x0000 },
+ { 24636, 0x0000 }, { 24636, 0x0000 }, { 24636, 0x0100 }, { 24637, 0x0010 },
+ /* 0x28600 */
+ { 24638, 0x0801 }, { 24640, 0x0000 }, { 24640, 0x0020 }, { 24641, 0x0800 },
+ { 24642, 0x0000 }, { 24642, 0x0000 }, { 24642, 0x0000 }, { 24642, 0x0000 },
+ { 24642, 0x0000 }, { 24642, 0x0000 }, { 24642, 0x0C00 }, { 24644, 0x1000 },
+ { 24645, 0x0000 }, { 24645, 0x0100 }, { 24646, 0x0040 }, { 24647, 0x0000 },
+ /* 0x28700 */
+ { 24647, 0x8000 }, { 24648, 0x0008 }, { 24649, 0x0000 }, { 24649, 0x0000 },
+ { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 },
+ { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 },
+ { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 }, { 24649, 0x0000 },
+ /* 0x28800 */
+ { 24649, 0x0010 }, { 24650, 0x0000 }, { 24650, 0x0800 }, { 24651, 0x0000 },
+ { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 },
+ { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 },
+ { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 },
+ /* 0x28900 */
+ { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0000 }, { 24651, 0x0008 },
+ { 24652, 0x0300 }, { 24654, 0x0040 }, { 24655, 0x1110 }, { 24658, 0x4000 },
+ { 24659, 0x0200 }, { 24660, 0x0000 }, { 24660, 0x0D00 }, { 24663, 0x1100 },
+ { 24665, 0x0001 }, { 24666, 0x5000 }, { 24668, 0x019A }, { 24673, 0x1E00 },
+ /* 0x28A00 */
+ { 24677, 0x8000 }, { 24678, 0x0040 }, { 24679, 0x0220 }, { 24681, 0x0044 },
+ { 24683, 0x0FF0 }, { 24691, 0x0600 }, { 24693, 0x0000 }, { 24693, 0x0000 },
+ { 24693, 0x000E }, { 24696, 0x1C00 }, { 24699, 0x0000 }, { 24699, 0x0000 },
+ { 24699, 0x5841 }, { 24704, 0xC000 }, { 24706, 0x042F }, { 24712, 0x1000 },
+ /* 0x28B00 */
+ { 24713, 0x1000 }, { 24714, 0x0008 }, { 24715, 0xB806 }, { 24721, 0x0000 },
+ { 24721, 0x5040 }, { 24724, 0x0001 }, { 24725, 0x1078 }, { 24730, 0x0000 },
+ { 24730, 0x8000 }, { 24731, 0x3200 }, { 24734, 0x0000 }, { 24734, 0x0000 },
+ { 24734, 0x0024 }, { 24736, 0x0690 }, { 24740, 0x1F80 }, { 24746, 0x8020 },
+ /* 0x28C00 */
+ { 24748, 0x0208 }, { 24750, 0x3000 }, { 24752, 0x0848 }, { 24755, 0x0A01 },
+ { 24758, 0x0000 }, { 24758, 0x0000 }, { 24758, 0x0000 }, { 24758, 0x0000 },
+ { 24758, 0x0000 }, { 24758, 0x0000 }, { 24758, 0x0000 }, { 24758, 0x0000 },
+ { 24758, 0x2400 }, { 24760, 0x0004 }, { 24761, 0x0000 }, { 24761, 0x0000 },
+ /* 0x28D00 */
+ { 24761, 0x0000 }, { 24761, 0x0000 }, { 24761, 0x0000 }, { 24761, 0x0010 },
+ { 24762, 0x0000 }, { 24762, 0x0000 }, { 24762, 0x0000 }, { 24762, 0x0000 },
+ { 24762, 0x0000 }, { 24762, 0x0200 }, { 24763, 0x0000 }, { 24763, 0x0200 },
+ { 24764, 0x0000 }, { 24764, 0x0000 }, { 24764, 0x0000 }, { 24764, 0x0000 },
+ /* 0x28E00 */
+ { 24764, 0x8000 }, { 24765, 0x0000 }, { 24765, 0x0000 }, { 24765, 0x0240 },
+ { 24767, 0x0000 }, { 24767, 0x0000 }, { 24767, 0x0060 }, { 24769, 0x0000 },
+ { 24769, 0x0000 }, { 24769, 0x0080 }, { 24770, 0x1000 }, { 24771, 0x000C },
+ { 24773, 0x0000 }, { 24773, 0x0200 }, { 24774, 0x0080 }, { 24775, 0x0000 },
+ /* 0x28F00 */
+ { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 },
+ { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 },
+ { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 }, { 24775, 0x0000 },
+ { 24775, 0x0020 }, { 24776, 0x0000 }, { 24776, 0x0000 }, { 24776, 0x0000 },
+ /* 0x29000 */
+ { 24776, 0x0000 }, { 24776, 0x0000 }, { 24776, 0x0000 }, { 24776, 0x0000 },
+ { 24776, 0x0000 }, { 24776, 0x0000 }, { 24776, 0x0000 }, { 24776, 0x0000 },
+ { 24776, 0x0900 }, { 24778, 0x0008 }, { 24779, 0x8000 }, { 24780, 0x0003 },
+ { 24782, 0x0001 }, { 24783, 0x0000 }, { 24783, 0x3030 }, { 24787, 0x0000 },
+ /* 0x29100 */
+ { 24787, 0x2000 }, { 24788, 0x0001 }, { 24789, 0x0000 }, { 24789, 0x1000 },
+ { 24790, 0x2000 }, { 24791, 0x4800 }, { 24793, 0x0000 }, { 24793, 0x0001 },
+ { 24794, 0x0000 }, { 24794, 0x1000 }, { 24795, 0x0100 }, { 24796, 0x0000 },
+ { 24796, 0x0000 }, { 24796, 0x0020 }, { 24797, 0x0800 },
+};
+static const Summary16 big5hkscs_uni2index_page294[32] = {
+ /* 0x29400 */
+ { 24798, 0x0000 }, { 24798, 0x2000 }, { 24799, 0x0001 }, { 24800, 0x8008 },
+ { 24802, 0x0100 }, { 24803, 0x0000 }, { 24803, 0x0000 }, { 24803, 0x0000 },
+ { 24803, 0x0000 }, { 24803, 0x0000 }, { 24803, 0x0000 }, { 24803, 0x0000 },
+ { 24803, 0x0000 }, { 24803, 0x0601 }, { 24806, 0x00A0 }, { 24808, 0x0000 },
+ /* 0x29500 */
+ { 24808, 0x0000 }, { 24808, 0x0000 }, { 24808, 0x0000 }, { 24808, 0x0000 },
+ { 24808, 0x0000 }, { 24808, 0x0000 }, { 24808, 0x0000 }, { 24808, 0x0000 },
+ { 24808, 0x0000 }, { 24808, 0x4000 }, { 24809, 0x0000 }, { 24809, 0x0101 },
+ { 24811, 0x0000 }, { 24811, 0x0080 }, { 24812, 0x0200 }, { 24813, 0x0010 },
+};
+static const Summary16 big5hkscs_uni2index_page297[251] = {
+ /* 0x29700 */
+ { 24814, 0x0000 }, { 24814, 0x0000 }, { 24814, 0x0001 }, { 24815, 0x0004 },
+ { 24816, 0x0000 }, { 24816, 0x0000 }, { 24816, 0x0000 }, { 24816, 0x0000 },
+ { 24816, 0x0000 }, { 24816, 0x0000 }, { 24816, 0x0000 }, { 24816, 0x0000 },
+ { 24816, 0x0000 }, { 24816, 0x0010 }, { 24817, 0x0000 }, { 24817, 0x0000 },
+ /* 0x29800 */
+ { 24817, 0x0000 }, { 24817, 0x0001 }, { 24818, 0x0000 }, { 24818, 0x0000 },
+ { 24818, 0x0000 }, { 24818, 0x0080 }, { 24819, 0x0000 }, { 24819, 0x0000 },
+ { 24819, 0x0000 }, { 24819, 0x0000 }, { 24819, 0x0010 }, { 24820, 0x0000 },
+ { 24820, 0x0000 }, { 24820, 0x0002 }, { 24821, 0x0400 }, { 24822, 0x0002 },
+ /* 0x29900 */
+ { 24823, 0x0028 }, { 24825, 0x0000 }, { 24825, 0x8000 }, { 24826, 0x0000 },
+ { 24826, 0x0380 }, { 24829, 0x2000 }, { 24830, 0x0400 }, { 24831, 0x0000 },
+ { 24831, 0x0000 }, { 24831, 0x2000 }, { 24832, 0x0000 }, { 24832, 0x0000 },
+ { 24832, 0x0208 }, { 24834, 0x0000 }, { 24834, 0x0000 }, { 24834, 0x0000 },
+ /* 0x29A00 */
+ { 24834, 0x0000 }, { 24834, 0x0000 }, { 24834, 0x0100 }, { 24835, 0x0000 },
+ { 24835, 0x2000 }, { 24836, 0x0000 }, { 24836, 0x0000 }, { 24836, 0x0000 },
+ { 24836, 0x0000 }, { 24836, 0x0000 }, { 24836, 0x0000 }, { 24836, 0x0000 },
+ { 24836, 0x0000 }, { 24836, 0x0000 }, { 24836, 0x0000 }, { 24836, 0x0000 },
+ /* 0x29B00 */
+ { 24836, 0x4020 }, { 24838, 0x0000 }, { 24838, 0x0000 }, { 24838, 0x0000 },
+ { 24838, 0x0000 }, { 24838, 0x0000 }, { 24838, 0x0000 }, { 24838, 0x0000 },
+ { 24838, 0x0000 }, { 24838, 0x0000 }, { 24838, 0x0000 }, { 24838, 0x0000 },
+ { 24838, 0x0000 }, { 24838, 0x0020 }, { 24839, 0x0000 }, { 24839, 0x0000 },
+ /* 0x29C00 */
+ { 24839, 0x0000 }, { 24839, 0x0000 }, { 24839, 0x0000 }, { 24839, 0x0000 },
+ { 24839, 0x0000 }, { 24839, 0x0000 }, { 24839, 0x0000 }, { 24839, 0x0008 },
+ { 24840, 0x0000 }, { 24840, 0x0000 }, { 24840, 0x2000 }, { 24841, 0x0000 },
+ { 24841, 0x0000 }, { 24841, 0x0000 }, { 24841, 0x0000 }, { 24841, 0x0000 },
+ /* 0x29D00 */
+ { 24841, 0x0000 }, { 24841, 0x0000 }, { 24841, 0x0000 }, { 24841, 0x4000 },
+ { 24842, 0x0000 }, { 24842, 0x0400 }, { 24843, 0x0000 }, { 24843, 0x1000 },
+ { 24844, 0x0000 }, { 24844, 0x0900 }, { 24846, 0x0000 }, { 24846, 0x0000 },
+ { 24846, 0x0000 }, { 24846, 0x0000 }, { 24846, 0x0000 }, { 24846, 0x0040 },
+ /* 0x29E00 */
+ { 24847, 0x0040 }, { 24848, 0x0000 }, { 24848, 0x2000 }, { 24849, 0x0000 },
+ { 24849, 0x0000 }, { 24849, 0x0000 }, { 24849, 0x0100 }, { 24850, 0x0000 },
+ { 24850, 0x0000 }, { 24850, 0x0000 }, { 24850, 0x1000 }, { 24851, 0x0000 },
+ { 24851, 0x0008 }, { 24852, 0x0000 }, { 24852, 0x0000 }, { 24852, 0x0100 },
+ /* 0x29F00 */
+ { 24853, 0x0000 }, { 24853, 0x0000 }, { 24853, 0x0008 }, { 24854, 0x0001 },
+ { 24855, 0x0000 }, { 24855, 0x0000 }, { 24855, 0x0000 }, { 24855, 0x0000 },
+ { 24855, 0x0000 }, { 24855, 0x0000 }, { 24855, 0x0000 }, { 24855, 0x0080 },
+ { 24856, 0x0000 }, { 24856, 0x4000 }, { 24857, 0x0000 }, { 24857, 0x0000 },
+ /* 0x2A000 */
+ { 24857, 0x0000 }, { 24857, 0x0010 }, { 24858, 0x0000 }, { 24858, 0x0000 },
+ { 24858, 0x0000 }, { 24858, 0x0000 }, { 24858, 0x0000 }, { 24858, 0x0000 },
+ { 24858, 0x0080 }, { 24859, 0x0000 }, { 24859, 0x0000 }, { 24859, 0x0200 },
+ { 24860, 0x0000 }, { 24860, 0x0000 }, { 24860, 0x2002 }, { 24862, 0x4108 },
+ /* 0x2A100 */
+ { 24865, 0x0080 }, { 24866, 0x0000 }, { 24866, 0x0008 }, { 24867, 0x0018 },
+ { 24869, 0x0000 }, { 24869, 0x0001 }, { 24870, 0x0000 }, { 24870, 0x0000 },
+ { 24870, 0x0000 }, { 24870, 0x000C }, { 24872, 0x0800 }, { 24873, 0x0010 },
+ { 24874, 0x0000 }, { 24874, 0x8000 }, { 24875, 0x0000 }, { 24875, 0x0020 },
+ /* 0x2A200 */
+ { 24876, 0x0000 }, { 24876, 0x0000 }, { 24876, 0x0001 }, { 24877, 0x0008 },
+ { 24878, 0x0000 }, { 24878, 0x0000 }, { 24878, 0x0000 }, { 24878, 0x0000 },
+ { 24878, 0x0000 }, { 24878, 0x8008 }, { 24880, 0x0000 }, { 24880, 0x2454 },
+ { 24885, 0x0000 }, { 24885, 0x8000 }, { 24886, 0x0000 }, { 24886, 0x8000 },
+ /* 0x2A300 */
+ { 24887, 0x0000 }, { 24887, 0x0000 }, { 24887, 0x0000 }, { 24887, 0x0000 },
+ { 24887, 0x0000 }, { 24887, 0x0000 }, { 24887, 0x0000 }, { 24887, 0x0000 },
+ { 24887, 0x0000 }, { 24887, 0x0000 }, { 24887, 0x0200 }, { 24888, 0x0000 },
+ { 24888, 0x0000 }, { 24888, 0x0000 }, { 24888, 0x0000 }, { 24888, 0x0000 },
+ /* 0x2A400 */
+ { 24888, 0x0000 }, { 24888, 0x0000 }, { 24888, 0x0000 }, { 24888, 0x0010 },
+ { 24889, 0x0000 }, { 24889, 0x0800 }, { 24890, 0x0000 }, { 24890, 0x0000 },
+ { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 },
+ { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 },
+ /* 0x2A500 */
+ { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 },
+ { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 },
+ { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 }, { 24890, 0x0000 },
+ { 24890, 0x0840 }, { 24892, 0x0000 }, { 24892, 0x0000 }, { 24892, 0x0000 },
+ /* 0x2A600 */
+ { 24892, 0x0002 }, { 24893, 0x0000 }, { 24893, 0x0000 }, { 24893, 0x0004 },
+ { 24894, 0x0400 }, { 24895, 0x0800 }, { 24896, 0x0000 }, { 24896, 0x0000 },
+ { 24896, 0x0000 }, { 24896, 0x0000 }, { 24896, 0x0200 },
+};
+static const Summary16 big5hkscs_uni2index_page2f8[30] = {
+ /* 0x2F800 */
+ { 24897, 0x0000 }, { 24897, 0x0000 }, { 24897, 0x0020 }, { 24898, 0x0800 },
+ { 24899, 0x0001 }, { 24900, 0x0000 }, { 24900, 0x0000 }, { 24900, 0x0100 },
+ { 24901, 0x0000 }, { 24901, 0x0010 }, { 24902, 0x0040 }, { 24903, 0x0000 },
+ { 24903, 0x2000 }, { 24904, 0x0000 }, { 24904, 0x0000 }, { 24904, 0x0000 },
+ /* 0x2F900 */
+ { 24904, 0x0000 }, { 24904, 0x0000 }, { 24904, 0x0000 }, { 24904, 0x0000 },
+ { 24904, 0x0000 }, { 24904, 0x0000 }, { 24904, 0x0000 }, { 24904, 0x0000 },
+ { 24904, 0x0000 }, { 24904, 0x0010 }, { 24905, 0x0000 }, { 24905, 0x1004 },
+ { 24907, 0x0000 }, { 24907, 0x0010 },
+};
+
+int qt_UnicodeToBig5hkscs (uint wc, uchar *r)
+{
+ const Summary16 *summary = NULL;
+ if (wc < 0x80) {
+ r[0] = (uchar) wc;
+ return 1;
+ }
+ if (wc < 0x0460)
+ summary = &big5hkscs_uni2index_page00[(wc>>4)];
+ else if (wc >= 0x1e00 && wc < 0x1ed0)
+ summary = &big5hkscs_uni2index_page1e[(wc>>4)-0x1e0];
+ else if (wc >= 0x2000 && wc < 0x2740)
+ summary = &big5hkscs_uni2index_page20[(wc>>4)-0x200];
+ else if (wc >= 0x2e00 && wc < 0x9fb0)
+ summary = &big5hkscs_uni2index_page2e[(wc>>4)-0x2e0];
+ else if (wc >= 0xe000 && wc < 0xfa30)
+ summary = &big5hkscs_uni2index_pagee0[(wc>>4)-0xe00];
+ else if (wc >= 0xfe00 && wc < 0xfff0)
+ summary = &big5hkscs_uni2index_pagefe[(wc>>4)-0xfe0];
+ else if (wc >= 0x20000 && wc < 0x291f0)
+ summary = &big5hkscs_uni2index_page200[(wc>>4)-0x2000];
+ else if (wc >= 0x29400 && wc < 0x29600)
+ summary = &big5hkscs_uni2index_page294[(wc>>4)-0x2940];
+ else if (wc >= 0x29700 && wc < 0x2a6b0)
+ summary = &big5hkscs_uni2index_page297[(wc>>4)-0x2970];
+ else if (wc >= 0x2f800 && wc < 0x2f9e0)
+ summary = &big5hkscs_uni2index_page2f8[(wc>>4)-0x2f80];
+ if (summary) {
+ ushort used = summary->used;
+ uint i = wc & 0x0f;
+ if (used & ((ushort) 1 << i)) {
+ const uchar *c;
+ /* Keep in `used' only the bits 0..i-1. */
+ used &= ((ushort) 1 << i) - 1;
+ /* Add `summary->index' and the number of bits set in `used'. */
+ used = (used & 0x5555) + ((used & 0xaaaa) >> 1);
+ used = (used & 0x3333) + ((used & 0xcccc) >> 2);
+ used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4);
+ used = (used & 0x00ff) + (used >> 8);
+ c = big5hkscs_to_charset[summary->index + used];
+ if (c [1] != 0) {
+ r[0] = c[0];
+ r[1] = c[1];
+ return 2;
+ } else { // (c [1] == 0)
+ r[0] = c[0];
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/* ====================================================================== */
+
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqbig5codec.h b/tqtinterface/qt4/src/codecs/tqbig5codec.h
new file mode 100644
index 0000000..9c1f38a
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqbig5codec.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Definition of TQBig5Codec class
+**
+** Created : 990713
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Most of the code here was originally written by Ming-Che Chuang and
+// is included in TQt with the author's permission, and the grateful
+// thanks of the Trolltech team.
+
+#ifndef TQBIG5CODEC_H
+#define TQBIG5CODEC_H
+
+#ifndef TQT_H
+#include "tqtextcodec.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_BIG_CODECS
+
+class TQBig5Codec : public TQTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+};
+
+class TQBig5hkscsCodec : public TQTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+};
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqeucjpcodec.cpp b/tqtinterface/qt4/src/codecs/tqeucjpcodec.cpp
new file mode 100644
index 0000000..416ad78
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqeucjpcodec.cpp
@@ -0,0 +1,485 @@
+/****************************************************************************
+**
+** Implementation of TQEucJpCodec class
+**
+** Created : 990225
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Most of the code here was originally written by Serika Kurusugawa
+// a.k.a. Junji Takagi, and is included in TQt with the author's permission,
+// and the grateful thanks of the Trolltech team.
+
+/*! \class TQEucJpCodec tqeucjpcodec.h
+ \reentrant
+ \ingroup i18n
+
+ \brief The TQEucJpCodec class provides conversion to and from EUC-JP character sets.
+
+ More precisely, the TQEucJpCodec class subclasses TQTextCodec to
+ provide support for EUC-JP, the main legacy encoding for Unix
+ machines in Japan.
+
+ The environment variable \c UNICODEMAP_JP can be used to fine-tune
+ TQJisCodec, TQSjisCodec and TQEucJpCodec. The \l TQJisCodec
+ documentation describes how to use this variable.
+
+ Most of the code here was written by Serika Kurusugawa,
+ a.k.a. Junji Takagi, and is included in TQt with the author's
+ permission and the grateful thanks of the Trolltech team. Here is
+ the copyright statement for that code:
+
+ \legalese
+
+ Copyright (C) 1999 Serika Kurusugawa. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ \list 1
+ \i Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ \i Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ \endlist
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS".
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+/*
+ * Copyright (C) 1999 Serika Kurusugawa, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "tqeucjpcodec.h"
+
+#ifndef TQT_NO_BIG_CODECS
+
+static const uchar Esc = 0x1b;
+static const uchar Ss2 = 0x8e; // Single Shift 2
+static const uchar Ss3 = 0x8f; // Single Shift 3
+
+#define IsKana(c) (((c) >= 0xa1) && ((c) <= 0xdf))
+#define IsEucChar(c) (((c) >= 0xa1) && ((c) <= 0xfe))
+
+#define TQValidChar(u) ((u) ? TQChar((ushort)(u)) : TQChar::tqreplacement)
+
+/*!
+ Constructs a TQEucJpCodec.
+*/
+TQEucJpCodec::TQEucJpCodec() : conv(TQJpUnicodeConv::newConverter( TQJpUnicodeConv::Default ))
+{
+}
+
+/*!
+ Destroys the codec.
+*/
+TQEucJpCodec::~TQEucJpCodec()
+{
+ delete (TQJpUnicodeConv*)conv;
+ conv = 0;
+}
+
+/*!
+ Returns 18.
+*/
+int TQEucJpCodec::mibEnum() const
+{
+ /*
+ Name: Extended_UNIX_Code_Packed_Format_for_Japanese
+ MIBenum: 18
+ Source: Standardized by OSF, UNIX International, and UNIX Systems
+ Laboratories Pacific. Uses ISO 2022 rules to select
+ code set 0: US-ASCII (a single 7-bit byte set)
+ code set 1: JIS X0208-1990 (a double 8-bit byte set)
+ restricted to A0-FF in both bytes
+ code set 2: Half Width Katakana (a single 7-bit byte set)
+ requiring SS2 as the character prefix
+ code set 3: JIS X0212-1990 (a double 7-bit byte set)
+ restricted to A0-FF in both bytes
+ requiring SS3 as the character prefix
+ Alias: csEUCPkdFmtJapanese
+ Alias: EUC-JP (preferred MIME name)
+ */
+ return 18;
+}
+
+/*!
+ \reimp
+*/
+TQCString TQEucJpCodec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ int l = TQMIN((int)uc.length(),lenInOut);
+ int rlen = l*3+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+ for (int i=0; i<l; i++) {
+ TQChar ch = uc[i];
+ uint j;
+ if ( ch.row() == 0x00 && ch.cell() < 0x80 ) {
+ // ASCII
+ *cursor++ = ch.cell();
+ } else if ((j = conv->tqunicodeToJisx0201(ch.row(), ch.cell())) != 0) {
+ if (j < 0x80) {
+ // JIS X 0201 Latin ?
+ *cursor++ = j;
+ } else {
+ // JIS X 0201 Kana
+ *cursor++ = Ss2;
+ *cursor++ = j;
+ }
+ } else if ((j = conv->tqunicodeToJisx0208(ch.row(), ch.cell())) != 0) {
+ // JIS X 0208
+ *cursor++ = (j >> 8) | 0x80;
+ *cursor++ = (j & 0xff) | 0x80;
+ } else if ((j = conv->tqunicodeToJisx0212(ch.row(), ch.cell())) != 0) {
+ // JIS X 0212
+ *cursor++ = Ss3;
+ *cursor++ = (j >> 8) | 0x80;
+ *cursor++ = (j & 0xff) | 0x80;
+ } else {
+ // Error
+ *cursor++ = '?'; // unknown char
+ }
+ }
+ lenInOut = cursor - (uchar*)rstr.data();
+ rstr.truncate(lenInOut);
+ return rstr;
+}
+
+/*!
+ \reimp
+*/
+TQString TQEucJpCodec::toUnicode(const char* chars, int len) const
+{
+ TQString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ if ( ch < 0x80 ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( ch == Ss2 ) {
+ // JIS X 0201 Kana
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( IsKana(c2) ) {
+ uint u = conv->jisx0201ToUnicode(c2);
+ result += TQValidChar(u);
+ } else {
+ i--;
+ result += TQChar::tqreplacement;
+ }
+ }
+ } else if ( ch == Ss3 ) {
+ // JIS X 0212
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( IsEucChar(c2) ) {
+ if ( i < len-1 ) {
+ uchar c3 = chars[++i];
+ if ( IsEucChar(c3) ) {
+ uint u = conv->jisx0212ToUnicode(c2 & 0x7f, c3 & 0x7f);
+ result += TQValidChar(u);
+ } else {
+ i--;
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ i--;
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ } else if ( IsEucChar(ch) ) {
+ // JIS X 0208
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( IsEucChar(c2) ) {
+ uint u = conv->jisx0208ToUnicode(ch & 0x7f, c2 & 0x7f);
+ result += TQValidChar(u);
+ } else {
+ i--;
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ }
+ return result;
+}
+
+/*!
+ \reimp
+*/
+const char* TQEucJpCodec::name() const
+{
+ return "eucJP";
+}
+
+/*!
+ Returns the codec's mime name.
+*/
+const char* TQEucJpCodec::mimeName() const
+{
+ return "EUC-JP";
+}
+
+/*!
+ \reimp
+*/
+int TQEucJpCodec::heuristicNameMatch(const char* hint) const
+{
+ int score = 0;
+ bool ja = FALSE;
+ if (qstrnicmp(hint, "ja_JP", 5) == 0 || qstrnicmp(hint, "japan", 5) == 0) {
+ score += 3;
+ ja = TRUE;
+ } else if (qstrnicmp(hint, "ja", 2) == 0) {
+ score += 2;
+ ja = TRUE;
+ }
+ const char *p;
+ if (ja) {
+ p = strchr(hint, '.');
+ if (p == 0) {
+ return score;
+ }
+ p++;
+ } else {
+ p = hint;
+ }
+ if (p) {
+ if ((qstricmp(p, "AJEC") == 0) ||
+ (qstricmp(p, "eucJP") == 0) ||
+ (qstricmp(p, "ujis") == 0) ||
+ (simpleHeuristicNameMatch(p, "eucJP") > 0) ||
+ (simpleHeuristicNameMatch(p, "x-euc-jp") > 0)) {
+ return score + 4;
+ }
+ // there exists ja_JP.EUC, ko_KR.EUC, zh_CN.EUC and zh_TW.EUC
+ // so "euc" may or may not be Japanese EUC.
+ if (qstricmp(p, "euc") == 0 && ja) {
+ return score + 4;
+ }
+ }
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+/*!
+ \reimp
+*/
+int TQEucJpCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ int score = 0;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ // No nulls allowed.
+ if ( !ch || ch == Esc )
+ return -1;
+ if ( ch < 32 && ch != '\t' && ch != '\n' && ch != '\r' ) {
+ // Suspicious
+ if ( score )
+ score--;
+ } else if ( ch < 0x80 ) {
+ // Inconclusive
+ score++;
+ } else if ( ch == Ss2 ) {
+ // JIS X 0201 Kana
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( !IsKana(c2) )
+ return -1;
+ score+=2;
+ }
+ score++;
+ } else if ( ch == Ss3 ) {
+ // JIS X 0212
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( !IsEucChar(c2) )
+ return -1;
+ if ( i < len-1 ) {
+ uchar c3 = chars[++i];
+ if ( !IsEucChar(c3) )
+ return -1;
+ score++;
+ }
+ score+=2;
+ }
+ score++;
+ } else if ( IsEucChar(ch) ) {
+ // JIS X 0208-1990
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( !IsEucChar(c2) )
+ return -1;
+ score+=2;
+ }
+ score++;
+ } else {
+ // Invalid
+ return -1;
+ }
+ }
+ return score;
+}
+
+class TQEucJpDecoder : public TQTextDecoder {
+ uchar buf[2];
+ int nbuf;
+ const TQJpUnicodeConv * const conv;
+public:
+ TQEucJpDecoder(const TQJpUnicodeConv *c) : nbuf(0), conv(c)
+ {
+ }
+
+ TQString toUnicode(const char* chars, int len)
+ {
+ TQString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ switch (nbuf) {
+ case 0:
+ if ( ch < 0x80 ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( ch == Ss2 || ch == Ss3 ) {
+ // JIS X 0201 Kana or JIS X 0212
+ buf[0] = ch;
+ nbuf = 1;
+ } else if ( IsEucChar(ch) ) {
+ // JIS X 0208
+ buf[0] = ch;
+ nbuf = 1;
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ break;
+ case 1:
+ if ( buf[0] == Ss2 ) {
+ // JIS X 0201 Kana
+ if ( IsKana(ch) ) {
+ uint u = conv->jisx0201ToUnicode(ch);
+ result += TQValidChar(u);
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ } else if ( buf[0] == Ss3 ) {
+ // JIS X 0212-1990
+ if ( IsEucChar(ch) ) {
+ buf[1] = ch;
+ nbuf = 2;
+ } else {
+ // Error
+ result += TQChar::tqreplacement;
+ nbuf = 0;
+ }
+ } else {
+ // JIS X 0208-1990
+ if ( IsEucChar(ch) ) {
+ uint u = conv->jisx0208ToUnicode(buf[0] & 0x7f, ch & 0x7f);
+ result += TQValidChar(u);
+ } else {
+ // Error
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ }
+ break;
+ case 2:
+ // JIS X 0212
+ if ( IsEucChar(ch) ) {
+ uint u = conv->jisx0212ToUnicode(buf[1] & 0x7f, ch & 0x7f);
+ result += TQValidChar(u);
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ }
+ }
+ return result;
+ }
+};
+
+/*!
+ \reimp
+*/
+TQTextDecoder* TQEucJpCodec::makeDecoder() const
+{
+ return new TQEucJpDecoder(conv);
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqeucjpcodec.h b/tqtinterface/qt4/src/codecs/tqeucjpcodec.h
new file mode 100644
index 0000000..c612514
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqeucjpcodec.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Definition of TQEucJpCodec class
+**
+** Created : 990225
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Most of the code here was originally written by Serika Kurusugawa
+// a.k.a. Junji Takagi, and is included in TQt with the author's permission,
+// and the grateful thanks of the Trolltech team.
+
+/*
+ * Copyright (C) 1999 Serika Kurusugawa, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef TQEUCJPCODEC_H
+#define TQEUCJPCODEC_H
+
+#ifndef TQT_H
+#include "tqtextcodec.h"
+#include "tqjpunicode.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_BIG_CODECS
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_CODECS_JP
+#else
+#define TQ_EXPORT_CODECS_JP TQ_EXPORT
+#endif
+
+class TQ_EXPORT_CODECS_JP TQEucJpCodec : public TQTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+ const char* mimeName() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+
+ TQEucJpCodec();
+ ~TQEucJpCodec();
+
+protected:
+ const TQJpUnicodeConv *conv;
+};
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqeuckrcodec.cpp b/tqtinterface/qt4/src/codecs/tqeuckrcodec.cpp
new file mode 100644
index 0000000..67ac98e
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqeuckrcodec.cpp
@@ -0,0 +1,3486 @@
+/****************************************************************************
+**
+** Implementation of TQEucKrCodec class
+**
+** Created : 990225
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/*! \class TQEucKrCodec tqeuckrcodec.h
+ \reentrant
+ \ingroup i18n
+
+ \brief The TQEucKrCodec class provides conversion to and from EUC-KR character sets.
+
+ The TQEucKrCodec class subclasses TQTextCodec to provide support for
+ EUC-KR, the main legacy encoding for UNIX machines in Korea.
+
+ It was largely written by Mizi Research Inc. Here is the copyright
+ statement for the code as it was at the point of contribution.
+ Trolltech's subsequent modifications are covered by the usual
+ copyright for TQt.
+
+ \legalese
+
+ Copyright (C) 1999-2000 Mizi Research Inc. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met: <ol>
+ <li> Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ <li> Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ </ol>
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+/* these must be made \internal
+ virtual int mibEnum() const;
+ const char* name() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+*/
+
+#include "tqeuckrcodec.h"
+
+#ifndef TQT_NO_BIG_CODECS
+
+unsigned int qt_Ksc5601ToUnicode(unsigned int code);
+
+unsigned int qt_UnicodeToKsc5601(unsigned int tqunicode);
+
+#define IsEucChar(c) (((c) >= 0xa1) && ((c) <= 0xfe))
+#define TQValidChar(u) ((u) ? TQChar((ushort)(u)) : TQChar::tqreplacement)
+
+/*!
+ \reimp
+*/
+
+int TQEucKrCodec::mibEnum() const
+{
+ /*
+ * Name: EUC-KR (preferred MIME name) [RFC1557,Choi]
+ * MIBenum: 38
+ * Source: RFC-1557 (see also KS_C_5861-1992)
+ * Alias: csEUCKR
+ */
+ /* mibEnum for other codeset related with Korean.
+ KS_C_5601-1987 36, ISO2022-KRi 37 */
+
+ return 38;
+}
+
+/*!
+ \reimp
+*/
+
+TQCString TQEucKrCodec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ int l = TQMIN((int)uc.length(),lenInOut);
+ int rlen = l*3+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+ for (int i=0; i<l; i++) {
+ TQChar ch = uc[i];
+ uint j;
+ if ( ch.row() == 0x00 && ch.cell() < 0x80 ) {
+ // ASCII
+ *cursor++ = ch.cell();
+ } else if ((j = qt_UnicodeToKsc5601((ch.row() << 8) | ch.cell())) ) {
+ // KSC 5601
+ *cursor++ = (j >> 8) | 0x80;
+ *cursor++ = (j & 0xff) | 0x80;
+ } else {
+ // Error
+ *cursor++ = '?'; // unknown char
+ }
+ }
+ lenInOut = cursor - (uchar*)rstr.data();
+ rstr.truncate(lenInOut);
+ return rstr;
+}
+
+/*!
+ \reimp
+*/
+
+TQString TQEucKrCodec::toUnicode(const char* chars, int len) const
+{
+ TQString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ if (ch == 0)
+ break;
+ if ( ch < 0x80 ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( IsEucChar(ch) ) {
+ // KSC 5601
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( IsEucChar(c2) ) {
+ uint u = qt_Ksc5601ToUnicode((ch << 8) | c2);
+ result += TQValidChar(u);
+ } else {
+ i--;
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ }
+ return result;
+}
+
+/*!
+ \reimp
+*/
+
+const char* TQEucKrCodec::name() const
+{
+ return "eucKR";
+}
+
+/*!
+ Returns the codec's mime name.
+*/
+const char* TQEucKrCodec::mimeName() const
+{
+ return "EUC-KR";
+}
+
+/*!
+ \reimp
+*/
+
+int TQEucKrCodec::heuristicNameMatch(const char* hint) const
+{
+ int score = 0;
+ bool ko = FALSE;
+ if (qstrnicmp(hint, "ko_KR", 5) == 0 ||
+ qstrnicmp(hint, "korean", 5) == 0) {
+ score += 3;
+ ko = TRUE;
+ } else if (qstrnicmp(hint, "ko", 2) == 0) {
+ score += 2;
+ ko = TRUE;
+ }
+ const char *p;
+ if (ko) {
+ p = strchr(hint, '.');
+ if (p == 0) {
+ return score;
+ }
+ p++;
+ } else {
+ p = hint;
+ }
+ if (p) {
+ if (qstricmp(p, "eucKR") == 0) {
+ return score + 4;
+ }
+ else if (qstricmp(p, "euc") == 0 && ko) {
+ return score + 4;
+ }
+ }
+ score = TQTextCodec::simpleHeuristicNameMatch( "ks_c_5601-1987", hint );
+ if ( score ) return score;
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+/*!
+ \reimp
+*/
+
+int TQEucKrCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ int score = 0;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ // No nulls allowed.
+ if ( !ch )
+ return -1;
+ if ( ch < 32 && ch != '\t' && ch != '\n' && ch != '\r' ) {
+ // Suspicious
+ if ( score )
+ score--;
+ } else if ( ch < 0x80 ) {
+ // Inconclusive
+ } else if ( IsEucChar(ch) ) {
+ // KSC 5601
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( !IsEucChar(c2) )
+ return -1;
+ score++;
+ }
+ score++;
+ } else {
+ // Invalid
+ return -1;
+ }
+ }
+ return score;
+}
+
+class TQEucKrDecoder : public TQTextDecoder {
+ uchar buf[2];
+ int nbuf;
+public:
+ TQEucKrDecoder() : nbuf(0)
+ {
+ }
+
+ TQString toUnicode(const char* chars, int len)
+ {
+ TQString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ if (ch == 0)
+ break;
+ switch (nbuf) {
+ case 0:
+ if ( ch < 0x80 ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( IsEucChar(ch) ) {
+ // KSC 5601
+ buf[0] = ch;
+ nbuf = 1;
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ break;
+ case 1:
+ // KSC 5601
+ if ( IsEucChar(ch) ) {
+ uint u = qt_Ksc5601ToUnicode((buf[0] << 8) | ch);
+ result += TQValidChar(u);
+ } else {
+ // Error
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ break;
+ }
+ }
+ return result;
+ }
+};
+
+/*!
+ \reimp
+*/
+
+TQTextDecoder* TQEucKrCodec::makeDecoder() const
+{
+ return new TQEucKrDecoder;
+}
+
+// code converter wrapper
+
+static unsigned short ksc2tqunicode ( unsigned short code );
+
+static unsigned short tqunicode2ksc ( unsigned short code );
+
+unsigned int qt_Ksc5601ToUnicode(unsigned int code)
+{
+#if 0
+ printf("qt_Ksc5601ToUnicode : code = %x, tqunicode = %x\n",
+ code, ksc2tqunicode((unsigned short)code));
+#endif
+ return ksc2tqunicode((unsigned short)code);
+}
+
+unsigned int qt_UnicodeToKsc5601(unsigned int tqunicode)
+{
+#if 0
+ printf("qt_UnicodeToKsc5601 : tqunicode = %x, %x\n",
+ tqunicode, tqunicode2ksc((unsigned short)tqunicode));
+#endif
+ return tqunicode2ksc((unsigned short)tqunicode);
+}
+
+/* Table including ksc5601 hangul to tqunicode */
+static const unsigned short ksc5601_hangul_to_tqunicode[2350]=
+{
+ 0xac00, 0xac01, 0xac04, 0xac07, 0xac08, 0xac09, 0xac0a, 0xac10,
+ 0xac11, 0xac12, 0xac13, 0xac14, 0xac15, 0xac16, 0xac17, 0xac19,
+ 0xac1a, 0xac1b, 0xac1c, 0xac1d, 0xac20, 0xac24, 0xac2c, 0xac2d,
+ 0xac2f, 0xac30, 0xac31, 0xac38, 0xac39, 0xac3c, 0xac40, 0xac4b,
+ 0xac4d, 0xac54, 0xac58, 0xac5c, 0xac70, 0xac71, 0xac74, 0xac77,
+ 0xac78, 0xac7a, 0xac80, 0xac81, 0xac83, 0xac84, 0xac85, 0xac86,
+ 0xac89, 0xac8a, 0xac8b, 0xac8c, 0xac90, 0xac94, 0xac9c, 0xac9d,
+ 0xac9f, 0xaca0, 0xaca1, 0xaca8, 0xaca9, 0xacaa, 0xacac, 0xacaf,
+ 0xacb0, 0xacb8, 0xacb9, 0xacbb, 0xacbc, 0xacbd, 0xacc1, 0xacc4,
+ 0xacc8, 0xaccc, 0xacd5, 0xacd7, 0xace0, 0xace1, 0xace4, 0xace7,
+ 0xace8, 0xacea, 0xacec, 0xacef, 0xacf0, 0xacf1, 0xacf3, 0xacf5,
+ 0xacf6, 0xacfc, 0xacfd, 0xad00, 0xad04, 0xad06, 0xad0c, 0xad0d,
+ 0xad0f, 0xad11, 0xad18, 0xad1c, 0xad20, 0xad29, 0xad2c, 0xad2d,
+ 0xad34, 0xad35, 0xad38, 0xad3c, 0xad44, 0xad45, 0xad47, 0xad49,
+ 0xad50, 0xad54, 0xad58, 0xad61, 0xad63, 0xad6c, 0xad6d, 0xad70,
+ 0xad73, 0xad74, 0xad75, 0xad76, 0xad7b, 0xad7c, 0xad7d, 0xad7f,
+ 0xad81, 0xad82, 0xad88, 0xad89, 0xad8c, 0xad90, 0xad9c, 0xad9d,
+ 0xada4, 0xadb7, 0xadc0, 0xadc1, 0xadc4, 0xadc8, 0xadd0, 0xadd1,
+ 0xadd3, 0xaddc, 0xade0, 0xade4, 0xadf8, 0xadf9, 0xadfc, 0xadff,
+ 0xae00, 0xae01, 0xae08, 0xae09, 0xae0b, 0xae0d, 0xae14, 0xae30,
+ 0xae31, 0xae34, 0xae37, 0xae38, 0xae3a, 0xae40, 0xae41, 0xae43,
+ 0xae45, 0xae46, 0xae4a, 0xae4c, 0xae4d, 0xae4e, 0xae50, 0xae54,
+ 0xae56, 0xae5c, 0xae5d, 0xae5f, 0xae60, 0xae61, 0xae65, 0xae68,
+ 0xae69, 0xae6c, 0xae70, 0xae78, 0xae79, 0xae7b, 0xae7c, 0xae7d,
+ 0xae84, 0xae85, 0xae8c, 0xaebc, 0xaebd, 0xaebe, 0xaec0, 0xaec4,
+ 0xaecc, 0xaecd, 0xaecf, 0xaed0, 0xaed1, 0xaed8, 0xaed9, 0xaedc,
+ 0xaee8, 0xaeeb, 0xaeed, 0xaef4, 0xaef8, 0xaefc, 0xaf07, 0xaf08,
+ 0xaf0d, 0xaf10, 0xaf2c, 0xaf2d, 0xaf30, 0xaf32, 0xaf34, 0xaf3c,
+ 0xaf3d, 0xaf3f, 0xaf41, 0xaf42, 0xaf43, 0xaf48, 0xaf49, 0xaf50,
+ 0xaf5c, 0xaf5d, 0xaf64, 0xaf65, 0xaf79, 0xaf80, 0xaf84, 0xaf88,
+ 0xaf90, 0xaf91, 0xaf95, 0xaf9c, 0xafb8, 0xafb9, 0xafbc, 0xafc0,
+ 0xafc7, 0xafc8, 0xafc9, 0xafcb, 0xafcd, 0xafce, 0xafd4, 0xafdc,
+ 0xafe8, 0xafe9, 0xaff0, 0xaff1, 0xaff4, 0xaff8, 0xb000, 0xb001,
+ 0xb004, 0xb00c, 0xb010, 0xb014, 0xb01c, 0xb01d, 0xb028, 0xb044,
+ 0xb045, 0xb048, 0xb04a, 0xb04c, 0xb04e, 0xb053, 0xb054, 0xb055,
+ 0xb057, 0xb059, 0xb05d, 0xb07c, 0xb07d, 0xb080, 0xb084, 0xb08c,
+ 0xb08d, 0xb08f, 0xb091, 0xb098, 0xb099, 0xb09a, 0xb09c, 0xb09f,
+ 0xb0a0, 0xb0a1, 0xb0a2, 0xb0a8, 0xb0a9, 0xb0ab, 0xb0ac, 0xb0ad,
+ 0xb0ae, 0xb0af, 0xb0b1, 0xb0b3, 0xb0b4, 0xb0b5, 0xb0b8, 0xb0bc,
+ 0xb0c4, 0xb0c5, 0xb0c7, 0xb0c8, 0xb0c9, 0xb0d0, 0xb0d1, 0xb0d4,
+ 0xb0d8, 0xb0e0, 0xb0e5, 0xb108, 0xb109, 0xb10b, 0xb10c, 0xb110,
+ 0xb112, 0xb113, 0xb118, 0xb119, 0xb11b, 0xb11c, 0xb11d, 0xb123,
+ 0xb124, 0xb125, 0xb128, 0xb12c, 0xb134, 0xb135, 0xb137, 0xb138,
+ 0xb139, 0xb140, 0xb141, 0xb144, 0xb148, 0xb150, 0xb151, 0xb154,
+ 0xb155, 0xb158, 0xb15c, 0xb160, 0xb178, 0xb179, 0xb17c, 0xb180,
+ 0xb182, 0xb188, 0xb189, 0xb18b, 0xb18d, 0xb192, 0xb193, 0xb194,
+ 0xb198, 0xb19c, 0xb1a8, 0xb1cc, 0xb1d0, 0xb1d4, 0xb1dc, 0xb1dd,
+ 0xb1df, 0xb1e8, 0xb1e9, 0xb1ec, 0xb1f0, 0xb1f9, 0xb1fb, 0xb1fd,
+ 0xb204, 0xb205, 0xb208, 0xb20b, 0xb20c, 0xb214, 0xb215, 0xb217,
+ 0xb219, 0xb220, 0xb234, 0xb23c, 0xb258, 0xb25c, 0xb260, 0xb268,
+ 0xb269, 0xb274, 0xb275, 0xb27c, 0xb284, 0xb285, 0xb289, 0xb290,
+ 0xb291, 0xb294, 0xb298, 0xb299, 0xb29a, 0xb2a0, 0xb2a1, 0xb2a3,
+ 0xb2a5, 0xb2a6, 0xb2aa, 0xb2ac, 0xb2b0, 0xb2b4, 0xb2c8, 0xb2c9,
+ 0xb2cc, 0xb2d0, 0xb2d2, 0xb2d8, 0xb2d9, 0xb2db, 0xb2dd, 0xb2e2,
+ 0xb2e4, 0xb2e5, 0xb2e6, 0xb2e8, 0xb2eb, 0xb2ec, 0xb2ed, 0xb2ee,
+ 0xb2ef, 0xb2f3, 0xb2f4, 0xb2f5, 0xb2f7, 0xb2f8, 0xb2f9, 0xb2fa,
+ 0xb2fb, 0xb2ff, 0xb300, 0xb301, 0xb304, 0xb308, 0xb310, 0xb311,
+ 0xb313, 0xb314, 0xb315, 0xb31c, 0xb354, 0xb355, 0xb356, 0xb358,
+ 0xb35b, 0xb35c, 0xb35e, 0xb35f, 0xb364, 0xb365, 0xb367, 0xb369,
+ 0xb36b, 0xb36e, 0xb370, 0xb371, 0xb374, 0xb378, 0xb380, 0xb381,
+ 0xb383, 0xb384, 0xb385, 0xb38c, 0xb390, 0xb394, 0xb3a0, 0xb3a1,
+ 0xb3a8, 0xb3ac, 0xb3c4, 0xb3c5, 0xb3c8, 0xb3cb, 0xb3cc, 0xb3ce,
+ 0xb3d0, 0xb3d4, 0xb3d5, 0xb3d7, 0xb3d9, 0xb3db, 0xb3dd, 0xb3e0,
+ 0xb3e4, 0xb3e8, 0xb3fc, 0xb410, 0xb418, 0xb41c, 0xb420, 0xb428,
+ 0xb429, 0xb42b, 0xb434, 0xb450, 0xb451, 0xb454, 0xb458, 0xb460,
+ 0xb461, 0xb463, 0xb465, 0xb46c, 0xb480, 0xb488, 0xb49d, 0xb4a4,
+ 0xb4a8, 0xb4ac, 0xb4b5, 0xb4b7, 0xb4b9, 0xb4c0, 0xb4c4, 0xb4c8,
+ 0xb4d0, 0xb4d5, 0xb4dc, 0xb4dd, 0xb4e0, 0xb4e3, 0xb4e4, 0xb4e6,
+ 0xb4ec, 0xb4ed, 0xb4ef, 0xb4f1, 0xb4f8, 0xb514, 0xb515, 0xb518,
+ 0xb51b, 0xb51c, 0xb524, 0xb525, 0xb527, 0xb528, 0xb529, 0xb52a,
+ 0xb530, 0xb531, 0xb534, 0xb538, 0xb540, 0xb541, 0xb543, 0xb544,
+ 0xb545, 0xb54b, 0xb54c, 0xb54d, 0xb550, 0xb554, 0xb55c, 0xb55d,
+ 0xb55f, 0xb560, 0xb561, 0xb5a0, 0xb5a1, 0xb5a4, 0xb5a8, 0xb5aa,
+ 0xb5ab, 0xb5b0, 0xb5b1, 0xb5b3, 0xb5b4, 0xb5b5, 0xb5bb, 0xb5bc,
+ 0xb5bd, 0xb5c0, 0xb5c4, 0xb5cc, 0xb5cd, 0xb5cf, 0xb5d0, 0xb5d1,
+ 0xb5d8, 0xb5ec, 0xb610, 0xb611, 0xb614, 0xb618, 0xb625, 0xb62c,
+ 0xb634, 0xb648, 0xb664, 0xb668, 0xb69c, 0xb69d, 0xb6a0, 0xb6a4,
+ 0xb6ab, 0xb6ac, 0xb6b1, 0xb6d4, 0xb6f0, 0xb6f4, 0xb6f8, 0xb700,
+ 0xb701, 0xb705, 0xb728, 0xb729, 0xb72c, 0xb72f, 0xb730, 0xb738,
+ 0xb739, 0xb73b, 0xb744, 0xb748, 0xb74c, 0xb754, 0xb755, 0xb760,
+ 0xb764, 0xb768, 0xb770, 0xb771, 0xb773, 0xb775, 0xb77c, 0xb77d,
+ 0xb780, 0xb784, 0xb78c, 0xb78d, 0xb78f, 0xb790, 0xb791, 0xb792,
+ 0xb796, 0xb797, 0xb798, 0xb799, 0xb79c, 0xb7a0, 0xb7a8, 0xb7a9,
+ 0xb7ab, 0xb7ac, 0xb7ad, 0xb7b4, 0xb7b5, 0xb7b8, 0xb7c7, 0xb7c9,
+ 0xb7ec, 0xb7ed, 0xb7f0, 0xb7f4, 0xb7fc, 0xb7fd, 0xb7ff, 0xb800,
+ 0xb801, 0xb807, 0xb808, 0xb809, 0xb80c, 0xb810, 0xb818, 0xb819,
+ 0xb81b, 0xb81d, 0xb824, 0xb825, 0xb828, 0xb82c, 0xb834, 0xb835,
+ 0xb837, 0xb838, 0xb839, 0xb840, 0xb844, 0xb851, 0xb853, 0xb85c,
+ 0xb85d, 0xb860, 0xb864, 0xb86c, 0xb86d, 0xb86f, 0xb871, 0xb878,
+ 0xb87c, 0xb88d, 0xb8a8, 0xb8b0, 0xb8b4, 0xb8b8, 0xb8c0, 0xb8c1,
+ 0xb8c3, 0xb8c5, 0xb8cc, 0xb8d0, 0xb8d4, 0xb8dd, 0xb8df, 0xb8e1,
+ 0xb8e8, 0xb8e9, 0xb8ec, 0xb8f0, 0xb8f8, 0xb8f9, 0xb8fb, 0xb8fd,
+ 0xb904, 0xb918, 0xb920, 0xb93c, 0xb93d, 0xb940, 0xb944, 0xb94c,
+ 0xb94f, 0xb951, 0xb958, 0xb959, 0xb95c, 0xb960, 0xb968, 0xb969,
+ 0xb96b, 0xb96d, 0xb974, 0xb975, 0xb978, 0xb97c, 0xb984, 0xb985,
+ 0xb987, 0xb989, 0xb98a, 0xb98d, 0xb98e, 0xb9ac, 0xb9ad, 0xb9b0,
+ 0xb9b4, 0xb9bc, 0xb9bd, 0xb9bf, 0xb9c1, 0xb9c8, 0xb9c9, 0xb9cc,
+ 0xb9ce, 0xb9cf, 0xb9d0, 0xb9d1, 0xb9d2, 0xb9d8, 0xb9d9, 0xb9db,
+ 0xb9dd, 0xb9de, 0xb9e1, 0xb9e3, 0xb9e4, 0xb9e5, 0xb9e8, 0xb9ec,
+ 0xb9f4, 0xb9f5, 0xb9f7, 0xb9f8, 0xb9f9, 0xb9fa, 0xba00, 0xba01,
+ 0xba08, 0xba15, 0xba38, 0xba39, 0xba3c, 0xba40, 0xba42, 0xba48,
+ 0xba49, 0xba4b, 0xba4d, 0xba4e, 0xba53, 0xba54, 0xba55, 0xba58,
+ 0xba5c, 0xba64, 0xba65, 0xba67, 0xba68, 0xba69, 0xba70, 0xba71,
+ 0xba74, 0xba78, 0xba83, 0xba84, 0xba85, 0xba87, 0xba8c, 0xbaa8,
+ 0xbaa9, 0xbaab, 0xbaac, 0xbab0, 0xbab2, 0xbab8, 0xbab9, 0xbabb,
+ 0xbabd, 0xbac4, 0xbac8, 0xbad8, 0xbad9, 0xbafc, 0xbb00, 0xbb04,
+ 0xbb0d, 0xbb0f, 0xbb11, 0xbb18, 0xbb1c, 0xbb20, 0xbb29, 0xbb2b,
+ 0xbb34, 0xbb35, 0xbb36, 0xbb38, 0xbb3b, 0xbb3c, 0xbb3d, 0xbb3e,
+ 0xbb44, 0xbb45, 0xbb47, 0xbb49, 0xbb4d, 0xbb4f, 0xbb50, 0xbb54,
+ 0xbb58, 0xbb61, 0xbb63, 0xbb6c, 0xbb88, 0xbb8c, 0xbb90, 0xbba4,
+ 0xbba8, 0xbbac, 0xbbb4, 0xbbb7, 0xbbc0, 0xbbc4, 0xbbc8, 0xbbd0,
+ 0xbbd3, 0xbbf8, 0xbbf9, 0xbbfc, 0xbbff, 0xbc00, 0xbc02, 0xbc08,
+ 0xbc09, 0xbc0b, 0xbc0c, 0xbc0d, 0xbc0f, 0xbc11, 0xbc14, 0xbc15,
+ 0xbc16, 0xbc17, 0xbc18, 0xbc1b, 0xbc1c, 0xbc1d, 0xbc1e, 0xbc1f,
+ 0xbc24, 0xbc25, 0xbc27, 0xbc29, 0xbc2d, 0xbc30, 0xbc31, 0xbc34,
+ 0xbc38, 0xbc40, 0xbc41, 0xbc43, 0xbc44, 0xbc45, 0xbc49, 0xbc4c,
+ 0xbc4d, 0xbc50, 0xbc5d, 0xbc84, 0xbc85, 0xbc88, 0xbc8b, 0xbc8c,
+ 0xbc8e, 0xbc94, 0xbc95, 0xbc97, 0xbc99, 0xbc9a, 0xbca0, 0xbca1,
+ 0xbca4, 0xbca7, 0xbca8, 0xbcb0, 0xbcb1, 0xbcb3, 0xbcb4, 0xbcb5,
+ 0xbcbc, 0xbcbd, 0xbcc0, 0xbcc4, 0xbccd, 0xbccf, 0xbcd0, 0xbcd1,
+ 0xbcd5, 0xbcd8, 0xbcdc, 0xbcf4, 0xbcf5, 0xbcf6, 0xbcf8, 0xbcfc,
+ 0xbd04, 0xbd05, 0xbd07, 0xbd09, 0xbd10, 0xbd14, 0xbd24, 0xbd2c,
+ 0xbd40, 0xbd48, 0xbd49, 0xbd4c, 0xbd50, 0xbd58, 0xbd59, 0xbd64,
+ 0xbd68, 0xbd80, 0xbd81, 0xbd84, 0xbd87, 0xbd88, 0xbd89, 0xbd8a,
+ 0xbd90, 0xbd91, 0xbd93, 0xbd95, 0xbd99, 0xbd9a, 0xbd9c, 0xbda4,
+ 0xbdb0, 0xbdb8, 0xbdd4, 0xbdd5, 0xbdd8, 0xbddc, 0xbde9, 0xbdf0,
+ 0xbdf4, 0xbdf8, 0xbe00, 0xbe03, 0xbe05, 0xbe0c, 0xbe0d, 0xbe10,
+ 0xbe14, 0xbe1c, 0xbe1d, 0xbe1f, 0xbe44, 0xbe45, 0xbe48, 0xbe4c,
+ 0xbe4e, 0xbe54, 0xbe55, 0xbe57, 0xbe59, 0xbe5a, 0xbe5b, 0xbe60,
+ 0xbe61, 0xbe64, 0xbe68, 0xbe6a, 0xbe70, 0xbe71, 0xbe73, 0xbe74,
+ 0xbe75, 0xbe7b, 0xbe7c, 0xbe7d, 0xbe80, 0xbe84, 0xbe8c, 0xbe8d,
+ 0xbe8f, 0xbe90, 0xbe91, 0xbe98, 0xbe99, 0xbea8, 0xbed0, 0xbed1,
+ 0xbed4, 0xbed7, 0xbed8, 0xbee0, 0xbee3, 0xbee4, 0xbee5, 0xbeec,
+ 0xbf01, 0xbf08, 0xbf09, 0xbf18, 0xbf19, 0xbf1b, 0xbf1c, 0xbf1d,
+ 0xbf40, 0xbf41, 0xbf44, 0xbf48, 0xbf50, 0xbf51, 0xbf55, 0xbf94,
+ 0xbfb0, 0xbfc5, 0xbfcc, 0xbfcd, 0xbfd0, 0xbfd4, 0xbfdc, 0xbfdf,
+ 0xbfe1, 0xc03c, 0xc051, 0xc058, 0xc05c, 0xc060, 0xc068, 0xc069,
+ 0xc090, 0xc091, 0xc094, 0xc098, 0xc0a0, 0xc0a1, 0xc0a3, 0xc0a5,
+ 0xc0ac, 0xc0ad, 0xc0af, 0xc0b0, 0xc0b3, 0xc0b4, 0xc0b5, 0xc0b6,
+ 0xc0bc, 0xc0bd, 0xc0bf, 0xc0c0, 0xc0c1, 0xc0c5, 0xc0c8, 0xc0c9,
+ 0xc0cc, 0xc0d0, 0xc0d8, 0xc0d9, 0xc0db, 0xc0dc, 0xc0dd, 0xc0e4,
+ 0xc0e5, 0xc0e8, 0xc0ec, 0xc0f4, 0xc0f5, 0xc0f7, 0xc0f9, 0xc100,
+ 0xc104, 0xc108, 0xc110, 0xc115, 0xc11c, 0xc11d, 0xc11e, 0xc11f,
+ 0xc120, 0xc123, 0xc124, 0xc126, 0xc127, 0xc12c, 0xc12d, 0xc12f,
+ 0xc130, 0xc131, 0xc136, 0xc138, 0xc139, 0xc13c, 0xc140, 0xc148,
+ 0xc149, 0xc14b, 0xc14c, 0xc14d, 0xc154, 0xc155, 0xc158, 0xc15c,
+ 0xc164, 0xc165, 0xc167, 0xc168, 0xc169, 0xc170, 0xc174, 0xc178,
+ 0xc185, 0xc18c, 0xc18d, 0xc18e, 0xc190, 0xc194, 0xc196, 0xc19c,
+ 0xc19d, 0xc19f, 0xc1a1, 0xc1a5, 0xc1a8, 0xc1a9, 0xc1ac, 0xc1b0,
+ 0xc1bd, 0xc1c4, 0xc1c8, 0xc1cc, 0xc1d4, 0xc1d7, 0xc1d8, 0xc1e0,
+ 0xc1e4, 0xc1e8, 0xc1f0, 0xc1f1, 0xc1f3, 0xc1fc, 0xc1fd, 0xc200,
+ 0xc204, 0xc20c, 0xc20d, 0xc20f, 0xc211, 0xc218, 0xc219, 0xc21c,
+ 0xc21f, 0xc220, 0xc228, 0xc229, 0xc22b, 0xc22d, 0xc22f, 0xc231,
+ 0xc232, 0xc234, 0xc248, 0xc250, 0xc251, 0xc254, 0xc258, 0xc260,
+ 0xc265, 0xc26c, 0xc26d, 0xc270, 0xc274, 0xc27c, 0xc27d, 0xc27f,
+ 0xc281, 0xc288, 0xc289, 0xc290, 0xc298, 0xc29b, 0xc29d, 0xc2a4,
+ 0xc2a5, 0xc2a8, 0xc2ac, 0xc2ad, 0xc2b4, 0xc2b5, 0xc2b7, 0xc2b9,
+ 0xc2dc, 0xc2dd, 0xc2e0, 0xc2e3, 0xc2e4, 0xc2eb, 0xc2ec, 0xc2ed,
+ 0xc2ef, 0xc2f1, 0xc2f6, 0xc2f8, 0xc2f9, 0xc2fb, 0xc2fc, 0xc300,
+ 0xc308, 0xc309, 0xc30c, 0xc30d, 0xc313, 0xc314, 0xc315, 0xc318,
+ 0xc31c, 0xc324, 0xc325, 0xc328, 0xc329, 0xc345, 0xc368, 0xc369,
+ 0xc36c, 0xc370, 0xc372, 0xc378, 0xc379, 0xc37c, 0xc37d, 0xc384,
+ 0xc388, 0xc38c, 0xc3c0, 0xc3d8, 0xc3d9, 0xc3dc, 0xc3df, 0xc3e0,
+ 0xc3e2, 0xc3e8, 0xc3e9, 0xc3ed, 0xc3f4, 0xc3f5, 0xc3f8, 0xc408,
+ 0xc410, 0xc424, 0xc42c, 0xc430, 0xc434, 0xc43c, 0xc43d, 0xc448,
+ 0xc464, 0xc465, 0xc468, 0xc46c, 0xc474, 0xc475, 0xc479, 0xc480,
+ 0xc494, 0xc49c, 0xc4b8, 0xc4bc, 0xc4e9, 0xc4f0, 0xc4f1, 0xc4f4,
+ 0xc4f8, 0xc4fa, 0xc4ff, 0xc500, 0xc501, 0xc50c, 0xc510, 0xc514,
+ 0xc51c, 0xc528, 0xc529, 0xc52c, 0xc530, 0xc538, 0xc539, 0xc53b,
+ 0xc53d, 0xc544, 0xc545, 0xc548, 0xc549, 0xc54a, 0xc54c, 0xc54d,
+ 0xc54e, 0xc553, 0xc554, 0xc555, 0xc557, 0xc558, 0xc559, 0xc55d,
+ 0xc55e, 0xc560, 0xc561, 0xc564, 0xc568, 0xc570, 0xc571, 0xc573,
+ 0xc574, 0xc575, 0xc57c, 0xc57d, 0xc580, 0xc584, 0xc587, 0xc58c,
+ 0xc58d, 0xc58f, 0xc591, 0xc595, 0xc597, 0xc598, 0xc59c, 0xc5a0,
+ 0xc5a9, 0xc5b4, 0xc5b5, 0xc5b8, 0xc5b9, 0xc5bb, 0xc5bc, 0xc5bd,
+ 0xc5be, 0xc5c4, 0xc5c5, 0xc5c6, 0xc5c7, 0xc5c8, 0xc5c9, 0xc5ca,
+ 0xc5cc, 0xc5ce, 0xc5d0, 0xc5d1, 0xc5d4, 0xc5d8, 0xc5e0, 0xc5e1,
+ 0xc5e3, 0xc5e5, 0xc5ec, 0xc5ed, 0xc5ee, 0xc5f0, 0xc5f4, 0xc5f6,
+ 0xc5f7, 0xc5fc, 0xc5fd, 0xc5fe, 0xc5ff, 0xc600, 0xc601, 0xc605,
+ 0xc606, 0xc607, 0xc608, 0xc60c, 0xc610, 0xc618, 0xc619, 0xc61b,
+ 0xc61c, 0xc624, 0xc625, 0xc628, 0xc62c, 0xc62d, 0xc62e, 0xc630,
+ 0xc633, 0xc634, 0xc635, 0xc637, 0xc639, 0xc63b, 0xc640, 0xc641,
+ 0xc644, 0xc648, 0xc650, 0xc651, 0xc653, 0xc654, 0xc655, 0xc65c,
+ 0xc65d, 0xc660, 0xc66c, 0xc66f, 0xc671, 0xc678, 0xc679, 0xc67c,
+ 0xc680, 0xc688, 0xc689, 0xc68b, 0xc68d, 0xc694, 0xc695, 0xc698,
+ 0xc69c, 0xc6a4, 0xc6a5, 0xc6a7, 0xc6a9, 0xc6b0, 0xc6b1, 0xc6b4,
+ 0xc6b8, 0xc6b9, 0xc6ba, 0xc6c0, 0xc6c1, 0xc6c3, 0xc6c5, 0xc6cc,
+ 0xc6cd, 0xc6d0, 0xc6d4, 0xc6dc, 0xc6dd, 0xc6e0, 0xc6e1, 0xc6e8,
+ 0xc6e9, 0xc6ec, 0xc6f0, 0xc6f8, 0xc6f9, 0xc6fd, 0xc704, 0xc705,
+ 0xc708, 0xc70c, 0xc714, 0xc715, 0xc717, 0xc719, 0xc720, 0xc721,
+ 0xc724, 0xc728, 0xc730, 0xc731, 0xc733, 0xc735, 0xc737, 0xc73c,
+ 0xc73d, 0xc740, 0xc744, 0xc74a, 0xc74c, 0xc74d, 0xc74f, 0xc751,
+ 0xc752, 0xc753, 0xc754, 0xc755, 0xc756, 0xc757, 0xc758, 0xc75c,
+ 0xc760, 0xc768, 0xc76b, 0xc774, 0xc775, 0xc778, 0xc77c, 0xc77d,
+ 0xc77e, 0xc783, 0xc784, 0xc785, 0xc787, 0xc788, 0xc789, 0xc78a,
+ 0xc78e, 0xc790, 0xc791, 0xc794, 0xc796, 0xc797, 0xc798, 0xc79a,
+ 0xc7a0, 0xc7a1, 0xc7a3, 0xc7a4, 0xc7a5, 0xc7a6, 0xc7ac, 0xc7ad,
+ 0xc7b0, 0xc7b4, 0xc7bc, 0xc7bd, 0xc7bf, 0xc7c0, 0xc7c1, 0xc7c8,
+ 0xc7c9, 0xc7cc, 0xc7ce, 0xc7d0, 0xc7d8, 0xc7dd, 0xc7e4, 0xc7e8,
+ 0xc7ec, 0xc800, 0xc801, 0xc804, 0xc808, 0xc80a, 0xc810, 0xc811,
+ 0xc813, 0xc815, 0xc816, 0xc81c, 0xc81d, 0xc820, 0xc824, 0xc82c,
+ 0xc82d, 0xc82f, 0xc831, 0xc838, 0xc83c, 0xc840, 0xc848, 0xc849,
+ 0xc84c, 0xc84d, 0xc854, 0xc870, 0xc871, 0xc874, 0xc878, 0xc87a,
+ 0xc880, 0xc881, 0xc883, 0xc885, 0xc886, 0xc887, 0xc88b, 0xc88c,
+ 0xc88d, 0xc894, 0xc89d, 0xc89f, 0xc8a1, 0xc8a8, 0xc8bc, 0xc8bd,
+ 0xc8c4, 0xc8c8, 0xc8cc, 0xc8d4, 0xc8d5, 0xc8d7, 0xc8d9, 0xc8e0,
+ 0xc8e1, 0xc8e4, 0xc8f5, 0xc8fc, 0xc8fd, 0xc900, 0xc904, 0xc905,
+ 0xc906, 0xc90c, 0xc90d, 0xc90f, 0xc911, 0xc918, 0xc92c, 0xc934,
+ 0xc950, 0xc951, 0xc954, 0xc958, 0xc960, 0xc961, 0xc963, 0xc96c,
+ 0xc970, 0xc974, 0xc97c, 0xc988, 0xc989, 0xc98c, 0xc990, 0xc998,
+ 0xc999, 0xc99b, 0xc99d, 0xc9c0, 0xc9c1, 0xc9c4, 0xc9c7, 0xc9c8,
+ 0xc9ca, 0xc9d0, 0xc9d1, 0xc9d3, 0xc9d5, 0xc9d6, 0xc9d9, 0xc9da,
+ 0xc9dc, 0xc9dd, 0xc9e0, 0xc9e2, 0xc9e4, 0xc9e7, 0xc9ec, 0xc9ed,
+ 0xc9ef, 0xc9f0, 0xc9f1, 0xc9f8, 0xc9f9, 0xc9fc, 0xca00, 0xca08,
+ 0xca09, 0xca0b, 0xca0c, 0xca0d, 0xca14, 0xca18, 0xca29, 0xca4c,
+ 0xca4d, 0xca50, 0xca54, 0xca5c, 0xca5d, 0xca5f, 0xca60, 0xca61,
+ 0xca68, 0xca7d, 0xca84, 0xca98, 0xcabc, 0xcabd, 0xcac0, 0xcac4,
+ 0xcacc, 0xcacd, 0xcacf, 0xcad1, 0xcad3, 0xcad8, 0xcad9, 0xcae0,
+ 0xcaec, 0xcaf4, 0xcb08, 0xcb10, 0xcb14, 0xcb18, 0xcb20, 0xcb21,
+ 0xcb41, 0xcb48, 0xcb49, 0xcb4c, 0xcb50, 0xcb58, 0xcb59, 0xcb5d,
+ 0xcb64, 0xcb78, 0xcb79, 0xcb9c, 0xcbb8, 0xcbd4, 0xcbe4, 0xcbe7,
+ 0xcbe9, 0xcc0c, 0xcc0d, 0xcc10, 0xcc14, 0xcc1c, 0xcc1d, 0xcc21,
+ 0xcc22, 0xcc27, 0xcc28, 0xcc29, 0xcc2c, 0xcc2e, 0xcc30, 0xcc38,
+ 0xcc39, 0xcc3b, 0xcc3c, 0xcc3d, 0xcc3e, 0xcc44, 0xcc45, 0xcc48,
+ 0xcc4c, 0xcc54, 0xcc55, 0xcc57, 0xcc58, 0xcc59, 0xcc60, 0xcc64,
+ 0xcc66, 0xcc68, 0xcc70, 0xcc75, 0xcc98, 0xcc99, 0xcc9c, 0xcca0,
+ 0xcca8, 0xcca9, 0xccab, 0xccac, 0xccad, 0xccb4, 0xccb5, 0xccb8,
+ 0xccbc, 0xccc4, 0xccc5, 0xccc7, 0xccc9, 0xccd0, 0xccd4, 0xcce4,
+ 0xccec, 0xccf0, 0xcd01, 0xcd08, 0xcd09, 0xcd0c, 0xcd10, 0xcd18,
+ 0xcd19, 0xcd1b, 0xcd1d, 0xcd24, 0xcd28, 0xcd2c, 0xcd39, 0xcd5c,
+ 0xcd60, 0xcd64, 0xcd6c, 0xcd6d, 0xcd6f, 0xcd71, 0xcd78, 0xcd88,
+ 0xcd94, 0xcd95, 0xcd98, 0xcd9c, 0xcda4, 0xcda5, 0xcda7, 0xcda9,
+ 0xcdb0, 0xcdc4, 0xcdcc, 0xcdd0, 0xcde8, 0xcdec, 0xcdf0, 0xcdf8,
+ 0xcdf9, 0xcdfb, 0xcdfd, 0xce04, 0xce08, 0xce0c, 0xce14, 0xce19,
+ 0xce20, 0xce21, 0xce24, 0xce28, 0xce30, 0xce31, 0xce33, 0xce35,
+ 0xce58, 0xce59, 0xce5c, 0xce5f, 0xce60, 0xce61, 0xce68, 0xce69,
+ 0xce6b, 0xce6d, 0xce74, 0xce75, 0xce78, 0xce7c, 0xce84, 0xce85,
+ 0xce87, 0xce89, 0xce90, 0xce91, 0xce94, 0xce98, 0xcea0, 0xcea1,
+ 0xcea3, 0xcea4, 0xcea5, 0xceac, 0xcead, 0xcec1, 0xcee4, 0xcee5,
+ 0xcee8, 0xceeb, 0xceec, 0xcef4, 0xcef5, 0xcef7, 0xcef8, 0xcef9,
+ 0xcf00, 0xcf01, 0xcf04, 0xcf08, 0xcf10, 0xcf11, 0xcf13, 0xcf15,
+ 0xcf1c, 0xcf20, 0xcf24, 0xcf2c, 0xcf2d, 0xcf2f, 0xcf30, 0xcf31,
+ 0xcf38, 0xcf54, 0xcf55, 0xcf58, 0xcf5c, 0xcf64, 0xcf65, 0xcf67,
+ 0xcf69, 0xcf70, 0xcf71, 0xcf74, 0xcf78, 0xcf80, 0xcf85, 0xcf8c,
+ 0xcfa1, 0xcfa8, 0xcfb0, 0xcfc4, 0xcfe0, 0xcfe1, 0xcfe4, 0xcfe8,
+ 0xcff0, 0xcff1, 0xcff3, 0xcff5, 0xcffc, 0xd000, 0xd004, 0xd011,
+ 0xd018, 0xd02d, 0xd034, 0xd035, 0xd038, 0xd03c, 0xd044, 0xd045,
+ 0xd047, 0xd049, 0xd050, 0xd054, 0xd058, 0xd060, 0xd06c, 0xd06d,
+ 0xd070, 0xd074, 0xd07c, 0xd07d, 0xd081, 0xd0a4, 0xd0a5, 0xd0a8,
+ 0xd0ac, 0xd0b4, 0xd0b5, 0xd0b7, 0xd0b9, 0xd0c0, 0xd0c1, 0xd0c4,
+ 0xd0c8, 0xd0c9, 0xd0d0, 0xd0d1, 0xd0d3, 0xd0d4, 0xd0d5, 0xd0dc,
+ 0xd0dd, 0xd0e0, 0xd0e4, 0xd0ec, 0xd0ed, 0xd0ef, 0xd0f0, 0xd0f1,
+ 0xd0f8, 0xd10d, 0xd130, 0xd131, 0xd134, 0xd138, 0xd13a, 0xd140,
+ 0xd141, 0xd143, 0xd144, 0xd145, 0xd14c, 0xd14d, 0xd150, 0xd154,
+ 0xd15c, 0xd15d, 0xd15f, 0xd161, 0xd168, 0xd16c, 0xd17c, 0xd184,
+ 0xd188, 0xd1a0, 0xd1a1, 0xd1a4, 0xd1a8, 0xd1b0, 0xd1b1, 0xd1b3,
+ 0xd1b5, 0xd1ba, 0xd1bc, 0xd1c0, 0xd1d8, 0xd1f4, 0xd1f8, 0xd207,
+ 0xd209, 0xd210, 0xd22c, 0xd22d, 0xd230, 0xd234, 0xd23c, 0xd23d,
+ 0xd23f, 0xd241, 0xd248, 0xd25c, 0xd264, 0xd280, 0xd281, 0xd284,
+ 0xd288, 0xd290, 0xd291, 0xd295, 0xd29c, 0xd2a0, 0xd2a4, 0xd2ac,
+ 0xd2b1, 0xd2b8, 0xd2b9, 0xd2bc, 0xd2bf, 0xd2c0, 0xd2c2, 0xd2c8,
+ 0xd2c9, 0xd2cb, 0xd2d4, 0xd2d8, 0xd2dc, 0xd2e4, 0xd2e5, 0xd2f0,
+ 0xd2f1, 0xd2f4, 0xd2f8, 0xd300, 0xd301, 0xd303, 0xd305, 0xd30c,
+ 0xd30d, 0xd30e, 0xd310, 0xd314, 0xd316, 0xd31c, 0xd31d, 0xd31f,
+ 0xd320, 0xd321, 0xd325, 0xd328, 0xd329, 0xd32c, 0xd330, 0xd338,
+ 0xd339, 0xd33b, 0xd33c, 0xd33d, 0xd344, 0xd345, 0xd37c, 0xd37d,
+ 0xd380, 0xd384, 0xd38c, 0xd38d, 0xd38f, 0xd390, 0xd391, 0xd398,
+ 0xd399, 0xd39c, 0xd3a0, 0xd3a8, 0xd3a9, 0xd3ab, 0xd3ad, 0xd3b4,
+ 0xd3b8, 0xd3bc, 0xd3c4, 0xd3c5, 0xd3c8, 0xd3c9, 0xd3d0, 0xd3d8,
+ 0xd3e1, 0xd3e3, 0xd3ec, 0xd3ed, 0xd3f0, 0xd3f4, 0xd3fc, 0xd3fd,
+ 0xd3ff, 0xd401, 0xd408, 0xd41d, 0xd440, 0xd444, 0xd45c, 0xd460,
+ 0xd464, 0xd46d, 0xd46f, 0xd478, 0xd479, 0xd47c, 0xd47f, 0xd480,
+ 0xd482, 0xd488, 0xd489, 0xd48b, 0xd48d, 0xd494, 0xd4a9, 0xd4cc,
+ 0xd4d0, 0xd4d4, 0xd4dc, 0xd4df, 0xd4e8, 0xd4ec, 0xd4f0, 0xd4f8,
+ 0xd4fb, 0xd4fd, 0xd504, 0xd508, 0xd50c, 0xd514, 0xd515, 0xd517,
+ 0xd53c, 0xd53d, 0xd540, 0xd544, 0xd54c, 0xd54d, 0xd54f, 0xd551,
+ 0xd558, 0xd559, 0xd55c, 0xd560, 0xd565, 0xd568, 0xd569, 0xd56b,
+ 0xd56d, 0xd574, 0xd575, 0xd578, 0xd57c, 0xd584, 0xd585, 0xd587,
+ 0xd588, 0xd589, 0xd590, 0xd5a5, 0xd5c8, 0xd5c9, 0xd5cc, 0xd5d0,
+ 0xd5d2, 0xd5d8, 0xd5d9, 0xd5db, 0xd5dd, 0xd5e4, 0xd5e5, 0xd5e8,
+ 0xd5ec, 0xd5f4, 0xd5f5, 0xd5f7, 0xd5f9, 0xd600, 0xd601, 0xd604,
+ 0xd608, 0xd610, 0xd611, 0xd613, 0xd614, 0xd615, 0xd61c, 0xd620,
+ 0xd624, 0xd62d, 0xd638, 0xd639, 0xd63c, 0xd640, 0xd645, 0xd648,
+ 0xd649, 0xd64b, 0xd64d, 0xd651, 0xd654, 0xd655, 0xd658, 0xd65c,
+ 0xd667, 0xd669, 0xd670, 0xd671, 0xd674, 0xd683, 0xd685, 0xd68c,
+ 0xd68d, 0xd690, 0xd694, 0xd69d, 0xd69f, 0xd6a1, 0xd6a8, 0xd6ac,
+ 0xd6b0, 0xd6b9, 0xd6bb, 0xd6c4, 0xd6c5, 0xd6c8, 0xd6cc, 0xd6d1,
+ 0xd6d4, 0xd6d7, 0xd6d9, 0xd6e0, 0xd6e4, 0xd6e8, 0xd6f0, 0xd6f5,
+ 0xd6fc, 0xd6fd, 0xd700, 0xd704, 0xd711, 0xd718, 0xd719, 0xd71c,
+ 0xd720, 0xd728, 0xd729, 0xd72b, 0xd72d, 0xd734, 0xd735, 0xd738,
+ 0xd73c, 0xd744, 0xd747, 0xd749, 0xd750, 0xd751, 0xd754, 0xd756,
+ 0xd757, 0xd758, 0xd759, 0xd760, 0xd761, 0xd763, 0xd765, 0xd769,
+ 0xd76c, 0xd770, 0xd774, 0xd77c, 0xd77d, 0xd781, 0xd788, 0xd789,
+ 0xd78c, 0xd790, 0xd798, 0xd799, 0xd79b, 0xd79d
+};
+
+/* Table including ksc5601 symbol to tqunicode */
+static const unsigned short ksc5601_symbol_to_tqunicode[1115]=
+{
+ 0x3000, 0x3001, 0x3002, 0x00b7, 0x2025, 0x2026, 0x00a8, 0x3003,
+ 0x00ad, 0x2015, 0x2225, 0xff3c, 0x223c, 0x2018, 0x2019, 0x201c,
+ 0x201d, 0x3014, 0x3015, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c,
+ 0x300d, 0x300e, 0x300f, 0x3010, 0x3011, 0x00b1, 0x00d7, 0x00f7,
+ 0x2260, 0x2264, 0x2265, 0x221e, 0x2234, 0x00b0, 0x2032, 0x2033,
+ 0x2103, 0x212b, 0xffe0, 0xffe1, 0xffe5, 0x2642, 0x2640, 0x2220,
+ 0x22a5, 0x2312, 0x2202, 0x2207, 0x2261, 0x2252, 0x00a7, 0x203b,
+ 0x2606, 0x2605, 0x25cb, 0x25cf, 0x25ce, 0x25c7, 0x25c6, 0x25a1,
+ 0x25a0, 0x25b3, 0x25b2, 0x25bd, 0x25bc, 0x2192, 0x2190, 0x2191,
+ 0x2193, 0x2194, 0x3013, 0x226a, 0x226b, 0x221a, 0x223d, 0x221d,
+ 0x2235, 0x222b, 0x222c, 0x2208, 0x220b, 0x2286, 0x2287, 0x2282,
+ 0x2283, 0x222a, 0x2229, 0x2227, 0x2228, 0xffe2, 0x21d2, 0x21d4,
+ 0x2200, 0x2203, 0x00b4, 0xff5e, 0x02c7, 0x02d8, 0x02dd, 0x02da,
+ 0x02d9, 0x00b8, 0x02db, 0x00a1, 0x00bf, 0x02d0, 0x222e, 0x2211,
+ 0x220f, 0x00a4, 0x2109, 0x2030, 0x25c1, 0x25c0, 0x25b7, 0x25b6,
+ 0x2664, 0x2660, 0x2661, 0x2665, 0x2667, 0x2663, 0x2299, 0x25c8,
+ 0x25a3, 0x25d0, 0x25d1, 0x2592, 0x25a4, 0x25a5, 0x25a8, 0x25a7,
+ 0x25a6, 0x25a9, 0x2668, 0x260f, 0x260e, 0x261c, 0x261e, 0x00b6,
+ 0x2020, 0x2021, 0x2195, 0x2197, 0x2199, 0x2196, 0x2198, 0x266d,
+ 0x2669, 0x266a, 0x266c, 0x327f, 0x321c, 0x2116, 0x33c7, 0x2122,
+ 0x33c2, 0x33d8, 0x2121, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0xff01, 0xff02, 0xff03, 0xff04,
+ 0xff05, 0xff06, 0xff07, 0xff08, 0xff09, 0xff0a, 0xff0b, 0xff0c,
+ 0xff0d, 0xff0e, 0xff0f, 0xff10, 0xff11, 0xff12, 0xff13, 0xff14,
+ 0xff15, 0xff16, 0xff17, 0xff18, 0xff19, 0xff1a, 0xff1b, 0xff1c,
+ 0xff1d, 0xff1e, 0xff1f, 0xff20, 0xff21, 0xff22, 0xff23, 0xff24,
+ 0xff25, 0xff26, 0xff27, 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c,
+ 0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, 0xff32, 0xff33, 0xff34,
+ 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, 0xff3a, 0xff3b, 0xffe6,
+ 0xff3d, 0xff3e, 0xff3f, 0xff40, 0xff41, 0xff42, 0xff43, 0xff44,
+ 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c,
+ 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54,
+ 0xff55, 0xff56, 0xff57, 0xff58, 0xff59, 0xff5a, 0xff5b, 0xff5c,
+ 0xff5d, 0xffe3, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136,
+ 0x3137, 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e,
+ 0x313f, 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146,
+ 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e,
+ 0x314f, 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156,
+ 0x3157, 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e,
+ 0x315f, 0x3160, 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, 0x3166,
+ 0x3167, 0x3168, 0x3169, 0x316a, 0x316b, 0x316c, 0x316d, 0x316e,
+ 0x316f, 0x3170, 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, 0x3176,
+ 0x3177, 0x3178, 0x3179, 0x317a, 0x317b, 0x317c, 0x317d, 0x317e,
+ 0x317f, 0x3180, 0x3181, 0x3182, 0x3183, 0x3184, 0x3185, 0x3186,
+ 0x3187, 0x3188, 0x3189, 0x318a, 0x318b, 0x318c, 0x318d, 0x318e,
+ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
+ 0x2178, 0x2179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2160,
+ 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168,
+ 0x2169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398,
+ 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0,
+ 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8,
+ 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0,
+ 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2500, 0x2502,
+ 0x250c, 0x2510, 0x2518, 0x2514, 0x251c, 0x252c, 0x2524, 0x2534,
+ 0x253c, 0x2501, 0x2503, 0x250f, 0x2513, 0x251b, 0x2517, 0x2523,
+ 0x2533, 0x252b, 0x253b, 0x254b, 0x2520, 0x252f, 0x2528, 0x2537,
+ 0x253f, 0x251d, 0x2530, 0x2525, 0x2538, 0x2542, 0x2512, 0x2511,
+ 0x251a, 0x2519, 0x2516, 0x2515, 0x250e, 0x250d, 0x251e, 0x251f,
+ 0x2521, 0x2522, 0x2526, 0x2527, 0x2529, 0x252a, 0x252d, 0x252e,
+ 0x2531, 0x2532, 0x2535, 0x2536, 0x2539, 0x253a, 0x253d, 0x253e,
+ 0x2540, 0x2541, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, 0x2548,
+ 0x2549, 0x254a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3395, 0x3396, 0x3397, 0x2113,
+ 0x3398, 0x33c4, 0x33a3, 0x33a4, 0x33a5, 0x33a6, 0x3399, 0x339a,
+ 0x339b, 0x339c, 0x339d, 0x339e, 0x339f, 0x33a0, 0x33a1, 0x33a2,
+ 0x33ca, 0x338d, 0x338e, 0x338f, 0x33cf, 0x3388, 0x3389, 0x33c8,
+ 0x33a7, 0x33a8, 0x33b0, 0x33b1, 0x33b2, 0x33b3, 0x33b4, 0x33b5,
+ 0x33b6, 0x33b7, 0x33b8, 0x33b9, 0x3380, 0x3381, 0x3382, 0x3383,
+ 0x3384, 0x33ba, 0x33bb, 0x33bc, 0x33bd, 0x33be, 0x33bf, 0x3390,
+ 0x3391, 0x3392, 0x3393, 0x3394, 0x2126, 0x33c0, 0x33c1, 0x338a,
+ 0x338b, 0x338c, 0x33d6, 0x33c5, 0x33ad, 0x33ae, 0x33af, 0x33db,
+ 0x33a9, 0x33aa, 0x33ab, 0x33ac, 0x33dd, 0x33d0, 0x33d3, 0x33c3,
+ 0x33c9, 0x33dc, 0x33c6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x00c6, 0x00d0, 0x00aa, 0x0126, 0x0000, 0x0132,
+ 0x0000, 0x013f, 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166,
+ 0x014a, 0x0000, 0x3260, 0x3261, 0x3262, 0x3263, 0x3264, 0x3265,
+ 0x3266, 0x3267, 0x3268, 0x3269, 0x326a, 0x326b, 0x326c, 0x326d,
+ 0x326e, 0x326f, 0x3270, 0x3271, 0x3272, 0x3273, 0x3274, 0x3275,
+ 0x3276, 0x3277, 0x3278, 0x3279, 0x327a, 0x327b, 0x24d0, 0x24d1,
+ 0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9,
+ 0x24da, 0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1,
+ 0x24e2, 0x24e3, 0x24e4, 0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9,
+ 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467,
+ 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x00bd,
+ 0x2153, 0x2154, 0x00bc, 0x00be, 0x215b, 0x215c, 0x215d, 0x215e,
+ 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0138, 0x0140,
+ 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x0149,
+ 0x3200, 0x3201, 0x3202, 0x3203, 0x3204, 0x3205, 0x3206, 0x3207,
+ 0x3208, 0x3209, 0x320a, 0x320b, 0x320c, 0x320d, 0x320e, 0x320f,
+ 0x3210, 0x3211, 0x3212, 0x3213, 0x3214, 0x3215, 0x3216, 0x3217,
+ 0x3218, 0x3219, 0x321a, 0x321b, 0x249c, 0x249d, 0x249e, 0x249f,
+ 0x24a0, 0x24a1, 0x24a2, 0x24a3, 0x24a4, 0x24a5, 0x24a6, 0x24a7,
+ 0x24a8, 0x24a9, 0x24aa, 0x24ab, 0x24ac, 0x24ad, 0x24ae, 0x24af,
+ 0x24b0, 0x24b1, 0x24b2, 0x24b3, 0x24b4, 0x24b5, 0x2474, 0x2475,
+ 0x2476, 0x2477, 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d,
+ 0x247e, 0x247f, 0x2480, 0x2481, 0x2482, 0x00b9, 0x00b2, 0x00b3,
+ 0x2074, 0x207f, 0x2081, 0x2082, 0x2083, 0x2084, 0x3041, 0x3042,
+ 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, 0x304a,
+ 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, 0x3051, 0x3052,
+ 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, 0x3059, 0x305a,
+ 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, 0x3061, 0x3062,
+ 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, 0x3069, 0x306a,
+ 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, 0x3071, 0x3072,
+ 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079, 0x307a,
+ 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, 0x3081, 0x3082,
+ 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, 0x3089, 0x308a,
+ 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, 0x3091, 0x3092,
+ 0x3093, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x30a1, 0x30a2, 0x30a3, 0x30a4,
+ 0x30a5, 0x30a6, 0x30a7, 0x30a8, 0x30a9, 0x30aa, 0x30ab, 0x30ac,
+ 0x30ad, 0x30ae, 0x30af, 0x30b0, 0x30b1, 0x30b2, 0x30b3, 0x30b4,
+ 0x30b5, 0x30b6, 0x30b7, 0x30b8, 0x30b9, 0x30ba, 0x30bb, 0x30bc,
+ 0x30bd, 0x30be, 0x30bf, 0x30c0, 0x30c1, 0x30c2, 0x30c3, 0x30c4,
+ 0x30c5, 0x30c6, 0x30c7, 0x30c8, 0x30c9, 0x30ca, 0x30cb, 0x30cc,
+ 0x30cd, 0x30ce, 0x30cf, 0x30d0, 0x30d1, 0x30d2, 0x30d3, 0x30d4,
+ 0x30d5, 0x30d6, 0x30d7, 0x30d8, 0x30d9, 0x30da, 0x30db, 0x30dc,
+ 0x30dd, 0x30de, 0x30df, 0x30e0, 0x30e1, 0x30e2, 0x30e3, 0x30e4,
+ 0x30e5, 0x30e6, 0x30e7, 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec,
+ 0x30ed, 0x30ee, 0x30ef, 0x30f0, 0x30f1, 0x30f2, 0x30f3, 0x30f4,
+ 0x30f5, 0x30f6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
+ 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c,
+ 0x041d, 0x041e, 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424,
+ 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c,
+ 0x042d, 0x042e, 0x042f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435,
+ 0x0451, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c,
+ 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444,
+ 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c,
+ 0x044d, 0x044e, 0x044f
+};
+
+struct map
+{
+ unsigned short tqunicode;
+ unsigned short kscode;
+};
+
+/* Map Table including tqunicode to ksc5601 symbol */
+static const struct map tqunicode_to_ksc5601_symbol[986]=
+{
+ {0x00a1, 0x222e}, {0x00a4, 0x2234}, {0x00a7, 0x2157},
+ {0x00a8, 0x2127}, {0x00aa, 0x2823}, {0x00ad, 0x2129},
+ {0x00b0, 0x2146}, {0x00b1, 0x213e}, {0x00b2, 0x2977},
+ {0x00b3, 0x2978}, {0x00b4, 0x2225}, {0x00b6, 0x2252},
+ {0x00b7, 0x2124}, {0x00b8, 0x222c}, {0x00b9, 0x2976},
+ {0x00ba, 0x282c}, {0x00bc, 0x2879}, {0x00bd, 0x2876},
+ {0x00be, 0x287a}, {0x00bf, 0x222f}, {0x00c6, 0x2821},
+ {0x00d0, 0x2822}, {0x00d7, 0x213f}, {0x00d8, 0x282a},
+ {0x00de, 0x282d}, {0x00df, 0x292c}, {0x00e6, 0x2921},
+ {0x00f0, 0x2923}, {0x00f7, 0x2140}, {0x00f8, 0x292a},
+ {0x00fe, 0x292d}, {0x0111, 0x2922}, {0x0126, 0x2824},
+ {0x0127, 0x2924}, {0x0131, 0x2925}, {0x0132, 0x2826},
+ {0x0133, 0x2926}, {0x0138, 0x2927}, {0x013f, 0x2828},
+ {0x0140, 0x2928}, {0x0141, 0x2829}, {0x0142, 0x2929},
+ {0x0149, 0x2930}, {0x014a, 0x282f}, {0x014b, 0x292f},
+ {0x0152, 0x282b}, {0x0153, 0x292b}, {0x0166, 0x282e},
+ {0x0167, 0x292e}, {0x02c7, 0x2227}, {0x02d0, 0x2230},
+ {0x02d8, 0x2228}, {0x02d9, 0x222b}, {0x02da, 0x222a},
+ {0x02db, 0x222d}, {0x02dd, 0x2229}, {0x0391, 0x2541},
+ {0x0392, 0x2542}, {0x0393, 0x2543}, {0x0394, 0x2544},
+ {0x0395, 0x2545}, {0x0396, 0x2546}, {0x0397, 0x2547},
+ {0x0398, 0x2548}, {0x0399, 0x2549}, {0x039a, 0x254a},
+ {0x039b, 0x254b}, {0x039c, 0x254c}, {0x039d, 0x254d},
+ {0x039e, 0x254e}, {0x039f, 0x254f}, {0x03a0, 0x2550},
+ {0x03a1, 0x2551}, {0x03a3, 0x2552}, {0x03a4, 0x2553},
+ {0x03a5, 0x2554}, {0x03a6, 0x2555}, {0x03a7, 0x2556},
+ {0x03a8, 0x2557}, {0x03a9, 0x2558}, {0x03b1, 0x2561},
+ {0x03b2, 0x2562}, {0x03b3, 0x2563}, {0x03b4, 0x2564},
+ {0x03b5, 0x2565}, {0x03b6, 0x2566}, {0x03b7, 0x2567},
+ {0x03b8, 0x2568}, {0x03b9, 0x2569}, {0x03ba, 0x256a},
+ {0x03bb, 0x256b}, {0x03bc, 0x256c}, {0x03bd, 0x256d},
+ {0x03be, 0x256e}, {0x03bf, 0x256f}, {0x03c0, 0x2570},
+ {0x03c1, 0x2571}, {0x03c3, 0x2572}, {0x03c4, 0x2573},
+ {0x03c5, 0x2574}, {0x03c6, 0x2575}, {0x03c7, 0x2576},
+ {0x03c8, 0x2577}, {0x03c9, 0x2578}, {0x0401, 0x2c27},
+ {0x0410, 0x2c21}, {0x0411, 0x2c22}, {0x0412, 0x2c23},
+ {0x0413, 0x2c24}, {0x0414, 0x2c25}, {0x0415, 0x2c26},
+ {0x0416, 0x2c28}, {0x0417, 0x2c29}, {0x0418, 0x2c2a},
+ {0x0419, 0x2c2b}, {0x041a, 0x2c2c}, {0x041b, 0x2c2d},
+ {0x041c, 0x2c2e}, {0x041d, 0x2c2f}, {0x041e, 0x2c30},
+ {0x041f, 0x2c31}, {0x0420, 0x2c32}, {0x0421, 0x2c33},
+ {0x0422, 0x2c34}, {0x0423, 0x2c35}, {0x0424, 0x2c36},
+ {0x0425, 0x2c37}, {0x0426, 0x2c38}, {0x0427, 0x2c39},
+ {0x0428, 0x2c3a}, {0x0429, 0x2c3b}, {0x042a, 0x2c3c},
+ {0x042b, 0x2c3d}, {0x042c, 0x2c3e}, {0x042d, 0x2c3f},
+ {0x042e, 0x2c40}, {0x042f, 0x2c41}, {0x0430, 0x2c51},
+ {0x0431, 0x2c52}, {0x0432, 0x2c53}, {0x0433, 0x2c54},
+ {0x0434, 0x2c55}, {0x0435, 0x2c56}, {0x0436, 0x2c58},
+ {0x0437, 0x2c59}, {0x0438, 0x2c5a}, {0x0439, 0x2c5b},
+ {0x043a, 0x2c5c}, {0x043b, 0x2c5d}, {0x043c, 0x2c5e},
+ {0x043d, 0x2c5f}, {0x043e, 0x2c60}, {0x043f, 0x2c61},
+ {0x0440, 0x2c62}, {0x0441, 0x2c63}, {0x0442, 0x2c64},
+ {0x0443, 0x2c65}, {0x0444, 0x2c66}, {0x0445, 0x2c67},
+ {0x0446, 0x2c68}, {0x0447, 0x2c69}, {0x0448, 0x2c6a},
+ {0x0449, 0x2c6b}, {0x044a, 0x2c6c}, {0x044b, 0x2c6d},
+ {0x044c, 0x2c6e}, {0x044d, 0x2c6f}, {0x044e, 0x2c70},
+ {0x044f, 0x2c71}, {0x0451, 0x2c57}, {0x2015, 0x212a},
+ {0x2018, 0x212e}, {0x2019, 0x212f}, {0x201c, 0x2130},
+ {0x201d, 0x2131}, {0x2020, 0x2253}, {0x2021, 0x2254},
+ {0x2025, 0x2125}, {0x2026, 0x2126}, {0x2030, 0x2236},
+ {0x2032, 0x2147}, {0x2033, 0x2148}, {0x203b, 0x2158},
+ {0x2074, 0x2979}, {0x207f, 0x297a}, {0x2081, 0x297b},
+ {0x2082, 0x297c}, {0x2083, 0x297d}, {0x2084, 0x297e},
+ {0x2103, 0x2149}, {0x2109, 0x2235}, {0x2113, 0x2724},
+ {0x2116, 0x2260}, {0x2121, 0x2265}, {0x2122, 0x2262},
+ {0x2126, 0x2759}, {0x212b, 0x214a}, {0x2153, 0x2877},
+ {0x2154, 0x2878}, {0x215b, 0x287b}, {0x215c, 0x287c},
+ {0x215d, 0x287d}, {0x215e, 0x287e}, {0x2160, 0x2530},
+ {0x2161, 0x2531}, {0x2162, 0x2532}, {0x2163, 0x2533},
+ {0x2164, 0x2534}, {0x2165, 0x2535}, {0x2166, 0x2536},
+ {0x2167, 0x2537}, {0x2168, 0x2538}, {0x2169, 0x2539},
+ {0x2170, 0x2521}, {0x2171, 0x2522}, {0x2172, 0x2523},
+ {0x2173, 0x2524}, {0x2174, 0x2525}, {0x2175, 0x2526},
+ {0x2176, 0x2527}, {0x2177, 0x2528}, {0x2178, 0x2529},
+ {0x2179, 0x252a}, {0x2190, 0x2167}, {0x2191, 0x2168},
+ {0x2192, 0x2166}, {0x2193, 0x2169}, {0x2194, 0x216a},
+ {0x2195, 0x2255}, {0x2196, 0x2258}, {0x2197, 0x2256},
+ {0x2198, 0x2259}, {0x2199, 0x2257}, {0x21d2, 0x2221},
+ {0x21d4, 0x2222}, {0x2200, 0x2223}, {0x2202, 0x2153},
+ {0x2203, 0x2224}, {0x2207, 0x2154}, {0x2208, 0x2174},
+ {0x220b, 0x2175}, {0x220f, 0x2233}, {0x2211, 0x2232},
+ {0x221a, 0x216e}, {0x221d, 0x2170}, {0x221e, 0x2144},
+ {0x2220, 0x2150}, {0x2225, 0x212b}, {0x2227, 0x217c},
+ {0x2228, 0x217d}, {0x2229, 0x217b}, {0x222a, 0x217a},
+ {0x222b, 0x2172}, {0x222c, 0x2173}, {0x222e, 0x2231},
+ {0x2234, 0x2145}, {0x2235, 0x2171}, {0x223c, 0x212d},
+ {0x223d, 0x216f}, {0x2252, 0x2156}, {0x2260, 0x2141},
+ {0x2261, 0x2155}, {0x2264, 0x2142}, {0x2265, 0x2143},
+ {0x226a, 0x216c}, {0x226b, 0x216d}, {0x2282, 0x2178},
+ {0x2283, 0x2179}, {0x2286, 0x2176}, {0x2287, 0x2177},
+ {0x2299, 0x2241}, {0x22a5, 0x2151}, {0x2312, 0x2152},
+ {0x2460, 0x2867}, {0x2461, 0x2868}, {0x2462, 0x2869},
+ {0x2463, 0x286a}, {0x2464, 0x286b}, {0x2465, 0x286c},
+ {0x2466, 0x286d}, {0x2467, 0x286e}, {0x2468, 0x286f},
+ {0x2469, 0x2870}, {0x246a, 0x2871}, {0x246b, 0x2872},
+ {0x246c, 0x2873}, {0x246d, 0x2874}, {0x246e, 0x2875},
+ {0x2474, 0x2967}, {0x2475, 0x2968}, {0x2476, 0x2969},
+ {0x2477, 0x296a}, {0x2478, 0x296b}, {0x2479, 0x296c},
+ {0x247a, 0x296d}, {0x247b, 0x296e}, {0x247c, 0x296f},
+ {0x247d, 0x2970}, {0x247e, 0x2971}, {0x247f, 0x2972},
+ {0x2480, 0x2973}, {0x2481, 0x2974}, {0x2482, 0x2975},
+ {0x249c, 0x294d}, {0x249d, 0x294e}, {0x249e, 0x294f},
+ {0x249f, 0x2950}, {0x24a0, 0x2951}, {0x24a1, 0x2952},
+ {0x24a2, 0x2953}, {0x24a3, 0x2954}, {0x24a4, 0x2955},
+ {0x24a5, 0x2956}, {0x24a6, 0x2957}, {0x24a7, 0x2958},
+ {0x24a8, 0x2959}, {0x24a9, 0x295a}, {0x24aa, 0x295b},
+ {0x24ab, 0x295c}, {0x24ac, 0x295d}, {0x24ad, 0x295e},
+ {0x24ae, 0x295f}, {0x24af, 0x2960}, {0x24b0, 0x2961},
+ {0x24b1, 0x2962}, {0x24b2, 0x2963}, {0x24b3, 0x2964},
+ {0x24b4, 0x2965}, {0x24b5, 0x2966}, {0x24d0, 0x284d},
+ {0x24d1, 0x284e}, {0x24d2, 0x284f}, {0x24d3, 0x2850},
+ {0x24d4, 0x2851}, {0x24d5, 0x2852}, {0x24d6, 0x2853},
+ {0x24d7, 0x2854}, {0x24d8, 0x2855}, {0x24d9, 0x2856},
+ {0x24da, 0x2857}, {0x24db, 0x2858}, {0x24dc, 0x2859},
+ {0x24dd, 0x285a}, {0x24de, 0x285b}, {0x24df, 0x285c},
+ {0x24e0, 0x285d}, {0x24e1, 0x285e}, {0x24e2, 0x285f},
+ {0x24e3, 0x2860}, {0x24e4, 0x2861}, {0x24e5, 0x2862},
+ {0x24e6, 0x2863}, {0x24e7, 0x2864}, {0x24e8, 0x2865},
+ {0x24e9, 0x2866}, {0x2500, 0x2621}, {0x2501, 0x262c},
+ {0x2502, 0x2622}, {0x2503, 0x262d}, {0x250c, 0x2623},
+ {0x250d, 0x2648}, {0x250e, 0x2647}, {0x250f, 0x262e},
+ {0x2510, 0x2624}, {0x2511, 0x2642}, {0x2512, 0x2641},
+ {0x2513, 0x262f}, {0x2514, 0x2626}, {0x2515, 0x2646},
+ {0x2516, 0x2645}, {0x2517, 0x2631}, {0x2518, 0x2625},
+ {0x2519, 0x2644}, {0x251a, 0x2643}, {0x251b, 0x2630},
+ {0x251c, 0x2627}, {0x251d, 0x263c}, {0x251e, 0x2649},
+ {0x251f, 0x264a}, {0x2520, 0x2637}, {0x2521, 0x264b},
+ {0x2522, 0x264c}, {0x2523, 0x2632}, {0x2524, 0x2629},
+ {0x2525, 0x263e}, {0x2526, 0x264d}, {0x2527, 0x264e},
+ {0x2528, 0x2639}, {0x2529, 0x264f}, {0x252a, 0x2650},
+ {0x252b, 0x2634}, {0x252c, 0x2628}, {0x252d, 0x2651},
+ {0x252e, 0x2652}, {0x252f, 0x2638}, {0x2530, 0x263d},
+ {0x2531, 0x2653}, {0x2532, 0x2654}, {0x2533, 0x2633},
+ {0x2534, 0x262a}, {0x2535, 0x2655}, {0x2536, 0x2656},
+ {0x2537, 0x263a}, {0x2538, 0x263f}, {0x2539, 0x2657},
+ {0x253a, 0x2658}, {0x253b, 0x2635}, {0x253c, 0x262b},
+ {0x253d, 0x2659}, {0x253e, 0x265a}, {0x253f, 0x263b},
+ {0x2540, 0x265b}, {0x2541, 0x265c}, {0x2542, 0x2640},
+ {0x2543, 0x265d}, {0x2544, 0x265e}, {0x2545, 0x265f},
+ {0x2546, 0x2660}, {0x2547, 0x2661}, {0x2548, 0x2662},
+ {0x2549, 0x2663}, {0x254a, 0x2664}, {0x254b, 0x2636},
+ {0x2592, 0x2246}, {0x25a0, 0x2161}, {0x25a1, 0x2160},
+ {0x25a3, 0x2243}, {0x25a4, 0x2247}, {0x25a5, 0x2248},
+ {0x25a6, 0x224b}, {0x25a7, 0x224a}, {0x25a8, 0x2249},
+ {0x25a9, 0x224c}, {0x25b2, 0x2163}, {0x25b3, 0x2162},
+ {0x25b6, 0x223a}, {0x25b7, 0x2239}, {0x25bc, 0x2165},
+ {0x25bd, 0x2164}, {0x25c0, 0x2238}, {0x25c1, 0x2237},
+ {0x25c6, 0x215f}, {0x25c7, 0x215e}, {0x25c8, 0x2242},
+ {0x25cb, 0x215b}, {0x25ce, 0x215d}, {0x25cf, 0x215c},
+ {0x25d0, 0x2244}, {0x25d1, 0x2245}, {0x2605, 0x215a},
+ {0x2606, 0x2159}, {0x260e, 0x224f}, {0x260f, 0x224e},
+ {0x261c, 0x2250}, {0x261e, 0x2251}, {0x2640, 0x214f},
+ {0x2642, 0x214e}, {0x2660, 0x223c}, {0x2661, 0x223d},
+ {0x2663, 0x2240}, {0x2664, 0x223b}, {0x2665, 0x223e},
+ {0x2667, 0x223f}, {0x2668, 0x224d}, {0x2669, 0x225b},
+ {0x266a, 0x225c}, {0x266c, 0x225d}, {0x266d, 0x225a},
+ {0x3000, 0x2121}, {0x3001, 0x2122}, {0x3002, 0x2123},
+ {0x3003, 0x2128}, {0x3008, 0x2134}, {0x3009, 0x2135},
+ {0x300a, 0x2136}, {0x300b, 0x2137}, {0x300c, 0x2138},
+ {0x300d, 0x2139}, {0x300e, 0x213a}, {0x300f, 0x213b},
+ {0x3010, 0x213c}, {0x3011, 0x213d}, {0x3013, 0x216b},
+ {0x3014, 0x2132}, {0x3015, 0x2133}, {0x3041, 0x2a21},
+ {0x3042, 0x2a22}, {0x3043, 0x2a23}, {0x3044, 0x2a24},
+ {0x3045, 0x2a25}, {0x3046, 0x2a26}, {0x3047, 0x2a27},
+ {0x3048, 0x2a28}, {0x3049, 0x2a29}, {0x304a, 0x2a2a},
+ {0x304b, 0x2a2b}, {0x304c, 0x2a2c}, {0x304d, 0x2a2d},
+ {0x304e, 0x2a2e}, {0x304f, 0x2a2f}, {0x3050, 0x2a30},
+ {0x3051, 0x2a31}, {0x3052, 0x2a32}, {0x3053, 0x2a33},
+ {0x3054, 0x2a34}, {0x3055, 0x2a35}, {0x3056, 0x2a36},
+ {0x3057, 0x2a37}, {0x3058, 0x2a38}, {0x3059, 0x2a39},
+ {0x305a, 0x2a3a}, {0x305b, 0x2a3b}, {0x305c, 0x2a3c},
+ {0x305d, 0x2a3d}, {0x305e, 0x2a3e}, {0x305f, 0x2a3f},
+ {0x3060, 0x2a40}, {0x3061, 0x2a41}, {0x3062, 0x2a42},
+ {0x3063, 0x2a43}, {0x3064, 0x2a44}, {0x3065, 0x2a45},
+ {0x3066, 0x2a46}, {0x3067, 0x2a47}, {0x3068, 0x2a48},
+ {0x3069, 0x2a49}, {0x306a, 0x2a4a}, {0x306b, 0x2a4b},
+ {0x306c, 0x2a4c}, {0x306d, 0x2a4d}, {0x306e, 0x2a4e},
+ {0x306f, 0x2a4f}, {0x3070, 0x2a50}, {0x3071, 0x2a51},
+ {0x3072, 0x2a52}, {0x3073, 0x2a53}, {0x3074, 0x2a54},
+ {0x3075, 0x2a55}, {0x3076, 0x2a56}, {0x3077, 0x2a57},
+ {0x3078, 0x2a58}, {0x3079, 0x2a59}, {0x307a, 0x2a5a},
+ {0x307b, 0x2a5b}, {0x307c, 0x2a5c}, {0x307d, 0x2a5d},
+ {0x307e, 0x2a5e}, {0x307f, 0x2a5f}, {0x3080, 0x2a60},
+ {0x3081, 0x2a61}, {0x3082, 0x2a62}, {0x3083, 0x2a63},
+ {0x3084, 0x2a64}, {0x3085, 0x2a65}, {0x3086, 0x2a66},
+ {0x3087, 0x2a67}, {0x3088, 0x2a68}, {0x3089, 0x2a69},
+ {0x308a, 0x2a6a}, {0x308b, 0x2a6b}, {0x308c, 0x2a6c},
+ {0x308d, 0x2a6d}, {0x308e, 0x2a6e}, {0x308f, 0x2a6f},
+ {0x3090, 0x2a70}, {0x3091, 0x2a71}, {0x3092, 0x2a72},
+ {0x3093, 0x2a73}, {0x30a1, 0x2b21}, {0x30a2, 0x2b22},
+ {0x30a3, 0x2b23}, {0x30a4, 0x2b24}, {0x30a5, 0x2b25},
+ {0x30a6, 0x2b26}, {0x30a7, 0x2b27}, {0x30a8, 0x2b28},
+ {0x30a9, 0x2b29}, {0x30aa, 0x2b2a}, {0x30ab, 0x2b2b},
+ {0x30ac, 0x2b2c}, {0x30ad, 0x2b2d}, {0x30ae, 0x2b2e},
+ {0x30af, 0x2b2f}, {0x30b0, 0x2b30}, {0x30b1, 0x2b31},
+ {0x30b2, 0x2b32}, {0x30b3, 0x2b33}, {0x30b4, 0x2b34},
+ {0x30b5, 0x2b35}, {0x30b6, 0x2b36}, {0x30b7, 0x2b37},
+ {0x30b8, 0x2b38}, {0x30b9, 0x2b39}, {0x30ba, 0x2b3a},
+ {0x30bb, 0x2b3b}, {0x30bc, 0x2b3c}, {0x30bd, 0x2b3d},
+ {0x30be, 0x2b3e}, {0x30bf, 0x2b3f}, {0x30c0, 0x2b40},
+ {0x30c1, 0x2b41}, {0x30c2, 0x2b42}, {0x30c3, 0x2b43},
+ {0x30c4, 0x2b44}, {0x30c5, 0x2b45}, {0x30c6, 0x2b46},
+ {0x30c7, 0x2b47}, {0x30c8, 0x2b48}, {0x30c9, 0x2b49},
+ {0x30ca, 0x2b4a}, {0x30cb, 0x2b4b}, {0x30cc, 0x2b4c},
+ {0x30cd, 0x2b4d}, {0x30ce, 0x2b4e}, {0x30cf, 0x2b4f},
+ {0x30d0, 0x2b50}, {0x30d1, 0x2b51}, {0x30d2, 0x2b52},
+ {0x30d3, 0x2b53}, {0x30d4, 0x2b54}, {0x30d5, 0x2b55},
+ {0x30d6, 0x2b56}, {0x30d7, 0x2b57}, {0x30d8, 0x2b58},
+ {0x30d9, 0x2b59}, {0x30da, 0x2b5a}, {0x30db, 0x2b5b},
+ {0x30dc, 0x2b5c}, {0x30dd, 0x2b5d}, {0x30de, 0x2b5e},
+ {0x30df, 0x2b5f}, {0x30e0, 0x2b60}, {0x30e1, 0x2b61},
+ {0x30e2, 0x2b62}, {0x30e3, 0x2b63}, {0x30e4, 0x2b64},
+ {0x30e5, 0x2b65}, {0x30e6, 0x2b66}, {0x30e7, 0x2b67},
+ {0x30e8, 0x2b68}, {0x30e9, 0x2b69}, {0x30ea, 0x2b6a},
+ {0x30eb, 0x2b6b}, {0x30ec, 0x2b6c}, {0x30ed, 0x2b6d},
+ {0x30ee, 0x2b6e}, {0x30ef, 0x2b6f}, {0x30f0, 0x2b70},
+ {0x30f1, 0x2b71}, {0x30f2, 0x2b72}, {0x30f3, 0x2b73},
+ {0x30f4, 0x2b74}, {0x30f5, 0x2b75}, {0x30f6, 0x2b76},
+ {0x3131, 0x2421}, {0x3132, 0x2422}, {0x3133, 0x2423},
+ {0x3134, 0x2424}, {0x3135, 0x2425}, {0x3136, 0x2426},
+ {0x3137, 0x2427}, {0x3138, 0x2428}, {0x3139, 0x2429},
+ {0x313a, 0x242a}, {0x313b, 0x242b}, {0x313c, 0x242c},
+ {0x313d, 0x242d}, {0x313e, 0x242e}, {0x313f, 0x242f},
+ {0x3140, 0x2430}, {0x3141, 0x2431}, {0x3142, 0x2432},
+ {0x3143, 0x2433}, {0x3144, 0x2434}, {0x3145, 0x2435},
+ {0x3146, 0x2436}, {0x3147, 0x2437}, {0x3148, 0x2438},
+ {0x3149, 0x2439}, {0x314a, 0x243a}, {0x314b, 0x243b},
+ {0x314c, 0x243c}, {0x314d, 0x243d}, {0x314e, 0x243e},
+ {0x314f, 0x243f}, {0x3150, 0x2440}, {0x3151, 0x2441},
+ {0x3152, 0x2442}, {0x3153, 0x2443}, {0x3154, 0x2444},
+ {0x3155, 0x2445}, {0x3156, 0x2446}, {0x3157, 0x2447},
+ {0x3158, 0x2448}, {0x3159, 0x2449}, {0x315a, 0x244a},
+ {0x315b, 0x244b}, {0x315c, 0x244c}, {0x315d, 0x244d},
+ {0x315e, 0x244e}, {0x315f, 0x244f}, {0x3160, 0x2450},
+ {0x3161, 0x2451}, {0x3162, 0x2452}, {0x3163, 0x2453},
+ {0x3164, 0x2454}, {0x3165, 0x2455}, {0x3166, 0x2456},
+ {0x3167, 0x2457}, {0x3168, 0x2458}, {0x3169, 0x2459},
+ {0x316a, 0x245a}, {0x316b, 0x245b}, {0x316c, 0x245c},
+ {0x316d, 0x245d}, {0x316e, 0x245e}, {0x316f, 0x245f},
+ {0x3170, 0x2460}, {0x3171, 0x2461}, {0x3172, 0x2462},
+ {0x3173, 0x2463}, {0x3174, 0x2464}, {0x3175, 0x2465},
+ {0x3176, 0x2466}, {0x3177, 0x2467}, {0x3178, 0x2468},
+ {0x3179, 0x2469}, {0x317a, 0x246a}, {0x317b, 0x246b},
+ {0x317c, 0x246c}, {0x317d, 0x246d}, {0x317e, 0x246e},
+ {0x317f, 0x246f}, {0x3180, 0x2470}, {0x3181, 0x2471},
+ {0x3182, 0x2472}, {0x3183, 0x2473}, {0x3184, 0x2474},
+ {0x3185, 0x2475}, {0x3186, 0x2476}, {0x3187, 0x2477},
+ {0x3188, 0x2478}, {0x3189, 0x2479}, {0x318a, 0x247a},
+ {0x318b, 0x247b}, {0x318c, 0x247c}, {0x318d, 0x247d},
+ {0x318e, 0x247e}, {0x3200, 0x2931}, {0x3201, 0x2932},
+ {0x3202, 0x2933}, {0x3203, 0x2934}, {0x3204, 0x2935},
+ {0x3205, 0x2936}, {0x3206, 0x2937}, {0x3207, 0x2938},
+ {0x3208, 0x2939}, {0x3209, 0x293a}, {0x320a, 0x293b},
+ {0x320b, 0x293c}, {0x320c, 0x293d}, {0x320d, 0x293e},
+ {0x320e, 0x293f}, {0x320f, 0x2940}, {0x3210, 0x2941},
+ {0x3211, 0x2942}, {0x3212, 0x2943}, {0x3213, 0x2944},
+ {0x3214, 0x2945}, {0x3215, 0x2946}, {0x3216, 0x2947},
+ {0x3217, 0x2948}, {0x3218, 0x2949}, {0x3219, 0x294a},
+ {0x321a, 0x294b}, {0x321b, 0x294c}, {0x321c, 0x225f},
+ {0x3260, 0x2831}, {0x3261, 0x2832}, {0x3262, 0x2833},
+ {0x3263, 0x2834}, {0x3264, 0x2835}, {0x3265, 0x2836},
+ {0x3266, 0x2837}, {0x3267, 0x2838}, {0x3268, 0x2839},
+ {0x3269, 0x283a}, {0x326a, 0x283b}, {0x326b, 0x283c},
+ {0x326c, 0x283d}, {0x326d, 0x283e}, {0x326e, 0x283f},
+ {0x326f, 0x2840}, {0x3270, 0x2841}, {0x3271, 0x2842},
+ {0x3272, 0x2843}, {0x3273, 0x2844}, {0x3274, 0x2845},
+ {0x3275, 0x2846}, {0x3276, 0x2847}, {0x3277, 0x2848},
+ {0x3278, 0x2849}, {0x3279, 0x284a}, {0x327a, 0x284b},
+ {0x327b, 0x284c}, {0x327f, 0x225e}, {0x3380, 0x2749},
+ {0x3381, 0x274a}, {0x3382, 0x274b}, {0x3383, 0x274c},
+ {0x3384, 0x274d}, {0x3388, 0x273a}, {0x3389, 0x273b},
+ {0x338a, 0x275c}, {0x338b, 0x275d}, {0x338c, 0x275e},
+ {0x338d, 0x2736}, {0x338e, 0x2737}, {0x338f, 0x2738},
+ {0x3390, 0x2754}, {0x3391, 0x2755}, {0x3392, 0x2756},
+ {0x3393, 0x2757}, {0x3394, 0x2758}, {0x3395, 0x2721},
+ {0x3396, 0x2722}, {0x3397, 0x2723}, {0x3398, 0x2725},
+ {0x3399, 0x272b}, {0x339a, 0x272c}, {0x339b, 0x272d},
+ {0x339c, 0x272e}, {0x339d, 0x272f}, {0x339e, 0x2730},
+ {0x339f, 0x2731}, {0x33a0, 0x2732}, {0x33a1, 0x2733},
+ {0x33a2, 0x2734}, {0x33a3, 0x2727}, {0x33a4, 0x2728},
+ {0x33a5, 0x2729}, {0x33a6, 0x272a}, {0x33a7, 0x273d},
+ {0x33a8, 0x273e}, {0x33a9, 0x2765}, {0x33aa, 0x2766},
+ {0x33ab, 0x2767}, {0x33ac, 0x2768}, {0x33ad, 0x2761},
+ {0x33ae, 0x2762}, {0x33af, 0x2763}, {0x33b0, 0x273f},
+ {0x33b1, 0x2740}, {0x33b2, 0x2741}, {0x33b3, 0x2742},
+ {0x33b4, 0x2743}, {0x33b5, 0x2744}, {0x33b6, 0x2745},
+ {0x33b7, 0x2746}, {0x33b8, 0x2747}, {0x33b9, 0x2748},
+ {0x33ba, 0x274e}, {0x33bb, 0x274f}, {0x33bc, 0x2750},
+ {0x33bd, 0x2751}, {0x33be, 0x2752}, {0x33bf, 0x2753},
+ {0x33c0, 0x275a}, {0x33c1, 0x275b}, {0x33c2, 0x2263},
+ {0x33c3, 0x276c}, {0x33c4, 0x2726}, {0x33c5, 0x2760},
+ {0x33c6, 0x276f}, {0x33c7, 0x2261}, {0x33c8, 0x273c},
+ {0x33c9, 0x276d}, {0x33ca, 0x2735}, {0x33cf, 0x2739},
+ {0x33d0, 0x276a}, {0x33d3, 0x276b}, {0x33d6, 0x275f},
+ {0x33d8, 0x2264}, {0x33db, 0x2764}, {0x33dc, 0x276e},
+ {0x33dd, 0x2769}, {0xff01, 0x2321}, {0xff02, 0x2322},
+ {0xff03, 0x2323}, {0xff04, 0x2324}, {0xff05, 0x2325},
+ {0xff06, 0x2326}, {0xff07, 0x2327}, {0xff08, 0x2328},
+ {0xff09, 0x2329}, {0xff0a, 0x232a}, {0xff0b, 0x232b},
+ {0xff0c, 0x232c}, {0xff0d, 0x232d}, {0xff0e, 0x232e},
+ {0xff0f, 0x232f}, {0xff10, 0x2330}, {0xff11, 0x2331},
+ {0xff12, 0x2332}, {0xff13, 0x2333}, {0xff14, 0x2334},
+ {0xff15, 0x2335}, {0xff16, 0x2336}, {0xff17, 0x2337},
+ {0xff18, 0x2338}, {0xff19, 0x2339}, {0xff1a, 0x233a},
+ {0xff1b, 0x233b}, {0xff1c, 0x233c}, {0xff1d, 0x233d},
+ {0xff1e, 0x233e}, {0xff1f, 0x233f}, {0xff20, 0x2340},
+ {0xff21, 0x2341}, {0xff22, 0x2342}, {0xff23, 0x2343},
+ {0xff24, 0x2344}, {0xff25, 0x2345}, {0xff26, 0x2346},
+ {0xff27, 0x2347}, {0xff28, 0x2348}, {0xff29, 0x2349},
+ {0xff2a, 0x234a}, {0xff2b, 0x234b}, {0xff2c, 0x234c},
+ {0xff2d, 0x234d}, {0xff2e, 0x234e}, {0xff2f, 0x234f},
+ {0xff30, 0x2350}, {0xff31, 0x2351}, {0xff32, 0x2352},
+ {0xff33, 0x2353}, {0xff34, 0x2354}, {0xff35, 0x2355},
+ {0xff36, 0x2356}, {0xff37, 0x2357}, {0xff38, 0x2358},
+ {0xff39, 0x2359}, {0xff3a, 0x235a}, {0xff3b, 0x235b},
+ {0xff3c, 0x212c}, {0xff3d, 0x235d}, {0xff3e, 0x235e},
+ {0xff3f, 0x235f}, {0xff40, 0x2360}, {0xff41, 0x2361},
+ {0xff42, 0x2362}, {0xff43, 0x2363}, {0xff44, 0x2364},
+ {0xff45, 0x2365}, {0xff46, 0x2366}, {0xff47, 0x2367},
+ {0xff48, 0x2368}, {0xff49, 0x2369}, {0xff4a, 0x236a},
+ {0xff4b, 0x236b}, {0xff4c, 0x236c}, {0xff4d, 0x236d},
+ {0xff4e, 0x236e}, {0xff4f, 0x236f}, {0xff50, 0x2370},
+ {0xff51, 0x2371}, {0xff52, 0x2372}, {0xff53, 0x2373},
+ {0xff54, 0x2374}, {0xff55, 0x2375}, {0xff56, 0x2376},
+ {0xff57, 0x2377}, {0xff58, 0x2378}, {0xff59, 0x2379},
+ {0xff5a, 0x237a}, {0xff5b, 0x237b}, {0xff5c, 0x237c},
+ {0xff5d, 0x237d}, {0xff5e, 0x2226}, {0xffe0, 0x214b},
+ {0xffe1, 0x214c}, {0xffe2, 0x217e}, {0xffe3, 0x237e},
+ {0xffe5, 0x214d}, {0xffe6, 0x235c}
+};
+
+/* Table including ksc5601 hanja to tqunicode */
+static const unsigned short ksc5601_hanja_to_tqunicode[4888]=
+{
+ 0x4f3d, 0x4f73, 0x5047, 0x50f9, 0x52a0, 0x53ef, 0x5475, 0x54e5,
+ 0x5609, 0x5ac1, 0x5bb6, 0x6687, 0x67b6, 0x67b7, 0x67ef, 0x6b4c,
+ 0x73c2, 0x75c2, 0x7a3c, 0x82db, 0x8304, 0x8857, 0x8888, 0x8a36,
+ 0x8cc8, 0x8dcf, 0x8efb, 0x8fe6, 0x99d5, 0x523b, 0x5374, 0x5404,
+ 0x606a, 0x6164, 0x6bbc, 0x73cf, 0x811a, 0x89ba, 0x89d2, 0x95a3,
+ 0x4f83, 0x520a, 0x58be, 0x5978, 0x59e6, 0x5e72, 0x5e79, 0x61c7,
+ 0x63c0, 0x6746, 0x67ec, 0x687f, 0x6f97, 0x764e, 0x770b, 0x78f5,
+ 0x7a08, 0x7aff, 0x7c21, 0x809d, 0x826e, 0x8271, 0x8aeb, 0x9593,
+ 0x4e6b, 0x559d, 0x66f7, 0x6e34, 0x78a3, 0x7aed, 0x845b, 0x8910,
+ 0x874e, 0x97a8, 0x52d8, 0x574e, 0x582a, 0x5d4c, 0x611f, 0x61be,
+ 0x6221, 0x6562, 0x67d1, 0x6a44, 0x6e1b, 0x7518, 0x75b3, 0x76e3,
+ 0x77b0, 0x7d3a, 0x90af, 0x9451, 0x9452, 0x9f95, 0x5323, 0x5cac,
+ 0x7532, 0x80db, 0x9240, 0x9598, 0x525b, 0x5808, 0x59dc, 0x5ca1,
+ 0x5d17, 0x5eb7, 0x5f3a, 0x5f4a, 0x6177, 0x6c5f, 0x757a, 0x7586,
+ 0x7ce0, 0x7d73, 0x7db1, 0x7f8c, 0x8154, 0x8221, 0x8591, 0x8941,
+ 0x8b1b, 0x92fc, 0x964d, 0x9c47, 0x4ecb, 0x4ef7, 0x500b, 0x51f1,
+ 0x584f, 0x6137, 0x613e, 0x6168, 0x6539, 0x69ea, 0x6f11, 0x75a5,
+ 0x7686, 0x76d6, 0x7b87, 0x82a5, 0x84cb, 0xf900, 0x93a7, 0x958b,
+ 0x5580, 0x5ba2, 0x5751, 0xf901, 0x7cb3, 0x7fb9, 0x91b5, 0x5028,
+ 0x53bb, 0x5c45, 0x5de8, 0x62d2, 0x636e, 0x64da, 0x64e7, 0x6e20,
+ 0x70ac, 0x795b, 0x8ddd, 0x8e1e, 0xf902, 0x907d, 0x9245, 0x92f8,
+ 0x4e7e, 0x4ef6, 0x5065, 0x5dfe, 0x5efa, 0x6106, 0x6957, 0x8171,
+ 0x8654, 0x8e47, 0x9375, 0x9a2b, 0x4e5e, 0x5091, 0x6770, 0x6840,
+ 0x5109, 0x528d, 0x5292, 0x6aa2, 0x77bc, 0x9210, 0x9ed4, 0x52ab,
+ 0x602f, 0x8ff2, 0x5048, 0x61a9, 0x63ed, 0x64ca, 0x683c, 0x6a84,
+ 0x6fc0, 0x8188, 0x89a1, 0x9694, 0x5805, 0x727d, 0x72ac, 0x7504,
+ 0x7d79, 0x7e6d, 0x80a9, 0x898b, 0x8b74, 0x9063, 0x9d51, 0x6289,
+ 0x6c7a, 0x6f54, 0x7d50, 0x7f3a, 0x8a23, 0x517c, 0x614a, 0x7b9d,
+ 0x8b19, 0x9257, 0x938c, 0x4eac, 0x4fd3, 0x501e, 0x50be, 0x5106,
+ 0x52c1, 0x52cd, 0x537f, 0x5770, 0x5883, 0x5e9a, 0x5f91, 0x6176,
+ 0x61ac, 0x64ce, 0x656c, 0x666f, 0x66bb, 0x66f4, 0x6897, 0x6d87,
+ 0x7085, 0x70f1, 0x749f, 0x74a5, 0x74ca, 0x75d9, 0x786c, 0x78ec,
+ 0x7adf, 0x7af6, 0x7d45, 0x7d93, 0x8015, 0x803f, 0x811b, 0x8396,
+ 0x8b66, 0x8f15, 0x9015, 0x93e1, 0x9803, 0x9838, 0x9a5a, 0x9be8,
+ 0x4fc2, 0x5553, 0x583a, 0x5951, 0x5b63, 0x5c46, 0x60b8, 0x6212,
+ 0x6842, 0x68b0, 0x68e8, 0x6eaa, 0x754c, 0x7678, 0x78ce, 0x7a3d,
+ 0x7cfb, 0x7e6b, 0x7e7c, 0x8a08, 0x8aa1, 0x8c3f, 0x968e, 0x9dc4,
+ 0x53e4, 0x53e9, 0x544a, 0x5471, 0x56fa, 0x59d1, 0x5b64, 0x5c3b,
+ 0x5eab, 0x62f7, 0x6537, 0x6545, 0x6572, 0x66a0, 0x67af, 0x69c1,
+ 0x6cbd, 0x75fc, 0x7690, 0x777e, 0x7a3f, 0x7f94, 0x8003, 0x80a1,
+ 0x818f, 0x82e6, 0x82fd, 0x83f0, 0x85c1, 0x8831, 0x88b4, 0x8aa5,
+ 0xf903, 0x8f9c, 0x932e, 0x96c7, 0x9867, 0x9ad8, 0x9f13, 0x54ed,
+ 0x659b, 0x66f2, 0x688f, 0x7a40, 0x8c37, 0x9d60, 0x56f0, 0x5764,
+ 0x5d11, 0x6606, 0x68b1, 0x68cd, 0x6efe, 0x7428, 0x889e, 0x9be4,
+ 0x6c68, 0xf904, 0x9aa8, 0x4f9b, 0x516c, 0x5171, 0x529f, 0x5b54,
+ 0x5de5, 0x6050, 0x606d, 0x62f1, 0x63a7, 0x653b, 0x73d9, 0x7a7a,
+ 0x86a3, 0x8ca2, 0x978f, 0x4e32, 0x5be1, 0x6208, 0x679c, 0x74dc,
+ 0x79d1, 0x83d3, 0x8a87, 0x8ab2, 0x8de8, 0x904e, 0x934b, 0x9846,
+ 0x5ed3, 0x69e8, 0x85ff, 0x90ed, 0xf905, 0x51a0, 0x5b98, 0x5bec,
+ 0x6163, 0x68fa, 0x6b3e, 0x704c, 0x742f, 0x74d8, 0x7ba1, 0x7f50,
+ 0x83c5, 0x89c0, 0x8cab, 0x95dc, 0x9928, 0x522e, 0x605d, 0x62ec,
+ 0x9002, 0x4f8a, 0x5149, 0x5321, 0x58d9, 0x5ee3, 0x66e0, 0x6d38,
+ 0x709a, 0x72c2, 0x73d6, 0x7b50, 0x80f1, 0x945b, 0x5366, 0x639b,
+ 0x7f6b, 0x4e56, 0x5080, 0x584a, 0x58de, 0x602a, 0x6127, 0x62d0,
+ 0x69d0, 0x9b41, 0x5b8f, 0x7d18, 0x80b1, 0x8f5f, 0x4ea4, 0x50d1,
+ 0x54ac, 0x55ac, 0x5b0c, 0x5da0, 0x5de7, 0x652a, 0x654e, 0x6821,
+ 0x6a4b, 0x72e1, 0x768e, 0x77ef, 0x7d5e, 0x7ff9, 0x81a0, 0x854e,
+ 0x86df, 0x8f03, 0x8f4e, 0x90ca, 0x9903, 0x9a55, 0x9bab, 0x4e18,
+ 0x4e45, 0x4e5d, 0x4ec7, 0x4ff1, 0x5177, 0x52fe, 0x5340, 0x53e3,
+ 0x53e5, 0x548e, 0x5614, 0x5775, 0x57a2, 0x5bc7, 0x5d87, 0x5ed0,
+ 0x61fc, 0x62d8, 0x6551, 0x67b8, 0x67e9, 0x69cb, 0x6b50, 0x6bc6,
+ 0x6bec, 0x6c42, 0x6e9d, 0x7078, 0x72d7, 0x7396, 0x7403, 0x77bf,
+ 0x77e9, 0x7a76, 0x7d7f, 0x8009, 0x81fc, 0x8205, 0x820a, 0x82df,
+ 0x8862, 0x8b33, 0x8cfc, 0x8ec0, 0x9011, 0x90b1, 0x9264, 0x92b6,
+ 0x99d2, 0x9a45, 0x9ce9, 0x9dd7, 0x9f9c, 0x570b, 0x5c40, 0x83ca,
+ 0x97a0, 0x97ab, 0x9eb4, 0x541b, 0x7a98, 0x7fa4, 0x88d9, 0x8ecd,
+ 0x90e1, 0x5800, 0x5c48, 0x6398, 0x7a9f, 0x5bae, 0x5f13, 0x7a79,
+ 0x7aae, 0x828e, 0x8eac, 0x5026, 0x5238, 0x52f8, 0x5377, 0x5708,
+ 0x62f3, 0x6372, 0x6b0a, 0x6dc3, 0x7737, 0x53a5, 0x7357, 0x8568,
+ 0x8e76, 0x95d5, 0x673a, 0x6ac3, 0x6f70, 0x8a6d, 0x8ecc, 0x994b,
+ 0xf906, 0x6677, 0x6b78, 0x8cb4, 0x9b3c, 0xf907, 0x53eb, 0x572d,
+ 0x594e, 0x63c6, 0x69fb, 0x73ea, 0x7845, 0x7aba, 0x7ac5, 0x7cfe,
+ 0x8475, 0x898f, 0x8d73, 0x9035, 0x95a8, 0x52fb, 0x5747, 0x7547,
+ 0x7b60, 0x83cc, 0x921e, 0xf908, 0x6a58, 0x514b, 0x524b, 0x5287,
+ 0x621f, 0x68d8, 0x6975, 0x9699, 0x50c5, 0x52a4, 0x52e4, 0x61c3,
+ 0x65a4, 0x6839, 0x69ff, 0x747e, 0x7b4b, 0x82b9, 0x83eb, 0x89b2,
+ 0x8b39, 0x8fd1, 0x9949, 0xf909, 0x4eca, 0x5997, 0x64d2, 0x6611,
+ 0x6a8e, 0x7434, 0x7981, 0x79bd, 0x82a9, 0x887e, 0x887f, 0x895f,
+ 0xf90a, 0x9326, 0x4f0b, 0x53ca, 0x6025, 0x6271, 0x6c72, 0x7d1a,
+ 0x7d66, 0x4e98, 0x5162, 0x77dc, 0x80af, 0x4f01, 0x4f0e, 0x5176,
+ 0x5180, 0x55dc, 0x5668, 0x573b, 0x57fa, 0x57fc, 0x5914, 0x5947,
+ 0x5993, 0x5bc4, 0x5c90, 0x5d0e, 0x5df1, 0x5e7e, 0x5fcc, 0x6280,
+ 0x65d7, 0x65e3, 0x671e, 0x671f, 0x675e, 0x68cb, 0x68c4, 0x6a5f,
+ 0x6b3a, 0x6c23, 0x6c7d, 0x6c82, 0x6dc7, 0x7398, 0x7426, 0x742a,
+ 0x7482, 0x74a3, 0x7578, 0x757f, 0x7881, 0x78ef, 0x7941, 0x7947,
+ 0x7948, 0x797a, 0x7b95, 0x7d00, 0x7dba, 0x7f88, 0x8006, 0x802d,
+ 0x808c, 0x8a18, 0x8b4f, 0x8c48, 0x8d77, 0x9321, 0x9324, 0x98e2,
+ 0x9951, 0x9a0e, 0x9a0f, 0x9a65, 0x9e92, 0x7dca, 0x4f76, 0x5409,
+ 0x62ee, 0x6854, 0x91d1, 0x55ab, 0x513a, 0xf90b, 0xf90c, 0x5a1c,
+ 0x61e6, 0xf90d, 0x62cf, 0x62ff, 0xf90e, 0xf90f, 0xf910, 0xf911,
+ 0xf912, 0xf913, 0x90a3, 0xf914, 0xf915, 0xf916, 0xf917, 0xf918,
+ 0x8afe, 0xf919, 0xf91a, 0xf91b, 0xf91c, 0x6696, 0xf91d, 0x7156,
+ 0xf91e, 0xf91f, 0x96e3, 0xf920, 0x634f, 0x637a, 0x5357, 0xf921,
+ 0x678f, 0x6960, 0x6e73, 0xf922, 0x7537, 0xf923, 0xf924, 0xf925,
+ 0x7d0d, 0xf926, 0xf927, 0x8872, 0x56ca, 0x5a18, 0xf928, 0xf929,
+ 0xf92a, 0xf92b, 0xf92c, 0x4e43, 0xf92d, 0x5167, 0x5948, 0x67f0,
+ 0x8010, 0xf92e, 0x5973, 0x5e74, 0x649a, 0x79ca, 0x5ff5, 0x606c,
+ 0x62c8, 0x637b, 0x5be7, 0x5bd7, 0x52aa, 0xf92f, 0x5974, 0x5f29,
+ 0x6012, 0xf930, 0xf931, 0xf932, 0x7459, 0xf933, 0xf934, 0xf935,
+ 0xf936, 0xf937, 0xf938, 0x99d1, 0xf939, 0xf93a, 0xf93b, 0xf93c,
+ 0xf93d, 0xf93e, 0xf93f, 0xf940, 0xf941, 0xf942, 0xf943, 0x6fc3,
+ 0xf944, 0xf945, 0x81bf, 0x8fb2, 0x60f1, 0xf946, 0xf947, 0x8166,
+ 0xf948, 0xf949, 0x5c3f, 0xf94a, 0xf94b, 0xf94c, 0xf94d, 0xf94e,
+ 0xf94f, 0xf950, 0xf951, 0x5ae9, 0x8a25, 0x677b, 0x7d10, 0xf952,
+ 0xf953, 0xf954, 0xf955, 0xf956, 0xf957, 0x80fd, 0xf958, 0xf959,
+ 0x5c3c, 0x6ce5, 0x533f, 0x6eba, 0x591a, 0x8336, 0x4e39, 0x4eb6,
+ 0x4f46, 0x55ae, 0x5718, 0x58c7, 0x5f56, 0x65b7, 0x65e6, 0x6a80,
+ 0x6bb5, 0x6e4d, 0x77ed, 0x7aef, 0x7c1e, 0x7dde, 0x86cb, 0x8892,
+ 0x9132, 0x935b, 0x64bb, 0x6fbe, 0x737a, 0x75b8, 0x9054, 0x5556,
+ 0x574d, 0x61ba, 0x64d4, 0x66c7, 0x6de1, 0x6e5b, 0x6f6d, 0x6fb9,
+ 0x75f0, 0x8043, 0x81bd, 0x8541, 0x8983, 0x8ac7, 0x8b5a, 0x931f,
+ 0x6c93, 0x7553, 0x7b54, 0x8e0f, 0x905d, 0x5510, 0x5802, 0x5858,
+ 0x5e62, 0x6207, 0x649e, 0x68e0, 0x7576, 0x7cd6, 0x87b3, 0x9ee8,
+ 0x4ee3, 0x5788, 0x576e, 0x5927, 0x5c0d, 0x5cb1, 0x5e36, 0x5f85,
+ 0x6234, 0x64e1, 0x73b3, 0x81fa, 0x888b, 0x8cb8, 0x968a, 0x9edb,
+ 0x5b85, 0x5fb7, 0x60b3, 0x5012, 0x5200, 0x5230, 0x5716, 0x5835,
+ 0x5857, 0x5c0e, 0x5c60, 0x5cf6, 0x5d8b, 0x5ea6, 0x5f92, 0x60bc,
+ 0x6311, 0x6389, 0x6417, 0x6843, 0x68f9, 0x6ac2, 0x6dd8, 0x6e21,
+ 0x6ed4, 0x6fe4, 0x71fe, 0x76dc, 0x7779, 0x79b1, 0x7a3b, 0x8404,
+ 0x89a9, 0x8ced, 0x8df3, 0x8e48, 0x9003, 0x9014, 0x9053, 0x90fd,
+ 0x934d, 0x9676, 0x97dc, 0x6bd2, 0x7006, 0x7258, 0x72a2, 0x7368,
+ 0x7763, 0x79bf, 0x7be4, 0x7e9b, 0x8b80, 0x58a9, 0x60c7, 0x6566,
+ 0x65fd, 0x66be, 0x6c8c, 0x711e, 0x71c9, 0x8c5a, 0x9813, 0x4e6d,
+ 0x7a81, 0x4edd, 0x51ac, 0x51cd, 0x52d5, 0x540c, 0x61a7, 0x6771,
+ 0x6850, 0x68df, 0x6d1e, 0x6f7c, 0x75bc, 0x77b3, 0x7ae5, 0x80f4,
+ 0x8463, 0x9285, 0x515c, 0x6597, 0x675c, 0x6793, 0x75d8, 0x7ac7,
+ 0x8373, 0xf95a, 0x8c46, 0x9017, 0x982d, 0x5c6f, 0x81c0, 0x829a,
+ 0x9041, 0x906f, 0x920d, 0x5f97, 0x5d9d, 0x6a59, 0x71c8, 0x767b,
+ 0x7b49, 0x85e4, 0x8b04, 0x9127, 0x9a30, 0x5587, 0x61f6, 0xf95b,
+ 0x7669, 0x7f85, 0x863f, 0x87ba, 0x88f8, 0x908f, 0xf95c, 0x6d1b,
+ 0x70d9, 0x73de, 0x7d61, 0x843d, 0xf95d, 0x916a, 0x99f1, 0xf95e,
+ 0x4e82, 0x5375, 0x6b04, 0x6b12, 0x703e, 0x721b, 0x862d, 0x9e1e,
+ 0x524c, 0x8fa3, 0x5d50, 0x64e5, 0x652c, 0x6b16, 0x6feb, 0x7c43,
+ 0x7e9c, 0x85cd, 0x8964, 0x89bd, 0x62c9, 0x81d8, 0x881f, 0x5eca,
+ 0x6717, 0x6d6a, 0x72fc, 0x7405, 0x746f, 0x8782, 0x90de, 0x4f86,
+ 0x5d0d, 0x5fa0, 0x840a, 0x51b7, 0x63a0, 0x7565, 0x4eae, 0x5006,
+ 0x5169, 0x51c9, 0x6881, 0x6a11, 0x7cae, 0x7cb1, 0x7ce7, 0x826f,
+ 0x8ad2, 0x8f1b, 0x91cf, 0x4fb6, 0x5137, 0x52f5, 0x5442, 0x5eec,
+ 0x616e, 0x623e, 0x65c5, 0x6ada, 0x6ffe, 0x792a, 0x85dc, 0x8823,
+ 0x95ad, 0x9a62, 0x9a6a, 0x9e97, 0x9ece, 0x529b, 0x66c6, 0x6b77,
+ 0x701d, 0x792b, 0x8f62, 0x9742, 0x6190, 0x6200, 0x6523, 0x6f23,
+ 0x7149, 0x7489, 0x7df4, 0x806f, 0x84ee, 0x8f26, 0x9023, 0x934a,
+ 0x51bd, 0x5217, 0x52a3, 0x6d0c, 0x70c8, 0x88c2, 0x5ec9, 0x6582,
+ 0x6bae, 0x6fc2, 0x7c3e, 0x7375, 0x4ee4, 0x4f36, 0x56f9, 0xf95f,
+ 0x5cba, 0x5dba, 0x601c, 0x73b2, 0x7b2d, 0x7f9a, 0x7fce, 0x8046,
+ 0x901e, 0x9234, 0x96f6, 0x9748, 0x9818, 0x9f61, 0x4f8b, 0x6fa7,
+ 0x79ae, 0x91b4, 0x96b7, 0x52de, 0xf960, 0x6488, 0x64c4, 0x6ad3,
+ 0x6f5e, 0x7018, 0x7210, 0x76e7, 0x8001, 0x8606, 0x865c, 0x8def,
+ 0x8f05, 0x9732, 0x9b6f, 0x9dfa, 0x9e75, 0x788c, 0x797f, 0x7da0,
+ 0x83c9, 0x9304, 0x9e7f, 0x9e93, 0x8ad6, 0x58df, 0x5f04, 0x6727,
+ 0x7027, 0x74cf, 0x7c60, 0x807e, 0x5121, 0x7028, 0x7262, 0x78ca,
+ 0x8cc2, 0x8cda, 0x8cf4, 0x96f7, 0x4e86, 0x50da, 0x5bee, 0x5ed6,
+ 0x6599, 0x71ce, 0x7642, 0x77ad, 0x804a, 0x84fc, 0x907c, 0x9b27,
+ 0x9f8d, 0x58d8, 0x5a41, 0x5c62, 0x6a13, 0x6dda, 0x6f0f, 0x763b,
+ 0x7d2f, 0x7e37, 0x851e, 0x8938, 0x93e4, 0x964b, 0x5289, 0x65d2,
+ 0x67f3, 0x69b4, 0x6d41, 0x6e9c, 0x700f, 0x7409, 0x7460, 0x7559,
+ 0x7624, 0x786b, 0x8b2c, 0x985e, 0x516d, 0x622e, 0x9678, 0x4f96,
+ 0x502b, 0x5d19, 0x6dea, 0x7db8, 0x8f2a, 0x5f8b, 0x6144, 0x6817,
+ 0xf961, 0x9686, 0x52d2, 0x808b, 0x51dc, 0x51cc, 0x695e, 0x7a1c,
+ 0x7dbe, 0x83f1, 0x9675, 0x4fda, 0x5229, 0x5398, 0x540f, 0x550e,
+ 0x5c65, 0x60a7, 0x674e, 0x68a8, 0x6d6c, 0x7281, 0x72f8, 0x7406,
+ 0x7483, 0xf962, 0x75e2, 0x7c6c, 0x7f79, 0x7fb8, 0x8389, 0x88cf,
+ 0x88e1, 0x91cc, 0x91d0, 0x96e2, 0x9bc9, 0x541d, 0x6f7e, 0x71d0,
+ 0x7498, 0x85fa, 0x8eaa, 0x96a3, 0x9c57, 0x9e9f, 0x6797, 0x6dcb,
+ 0x7433, 0x81e8, 0x9716, 0x782c, 0x7acb, 0x7b20, 0x7c92, 0x6469,
+ 0x746a, 0x75f2, 0x78bc, 0x78e8, 0x99ac, 0x9b54, 0x9ebb, 0x5bde,
+ 0x5e55, 0x6f20, 0x819c, 0x83ab, 0x9088, 0x4e07, 0x534d, 0x5a29,
+ 0x5dd2, 0x5f4e, 0x6162, 0x633d, 0x6669, 0x66fc, 0x6eff, 0x6f2b,
+ 0x7063, 0x779e, 0x842c, 0x8513, 0x883b, 0x8f13, 0x9945, 0x9c3b,
+ 0x551c, 0x62b9, 0x672b, 0x6cab, 0x8309, 0x896a, 0x977a, 0x4ea1,
+ 0x5984, 0x5fd8, 0x5fd9, 0x671b, 0x7db2, 0x7f54, 0x8292, 0x832b,
+ 0x83bd, 0x8f1e, 0x9099, 0x57cb, 0x59b9, 0x5a92, 0x5bd0, 0x6627,
+ 0x679a, 0x6885, 0x6bcf, 0x7164, 0x7f75, 0x8cb7, 0x8ce3, 0x9081,
+ 0x9b45, 0x8108, 0x8c8a, 0x964c, 0x9a40, 0x9ea5, 0x5b5f, 0x6c13,
+ 0x731b, 0x76f2, 0x76df, 0x840c, 0x51aa, 0x8993, 0x514d, 0x5195,
+ 0x52c9, 0x68c9, 0x6c94, 0x7704, 0x7720, 0x7dbf, 0x7dec, 0x9762,
+ 0x9eb5, 0x6ec5, 0x8511, 0x51a5, 0x540d, 0x547d, 0x660e, 0x669d,
+ 0x6927, 0x6e9f, 0x76bf, 0x7791, 0x8317, 0x84c2, 0x879f, 0x9169,
+ 0x9298, 0x9cf4, 0x8882, 0x4fae, 0x5192, 0x52df, 0x59c6, 0x5e3d,
+ 0x6155, 0x6478, 0x6479, 0x66ae, 0x67d0, 0x6a21, 0x6bcd, 0x6bdb,
+ 0x725f, 0x7261, 0x7441, 0x7738, 0x77db, 0x8017, 0x82bc, 0x8305,
+ 0x8b00, 0x8b28, 0x8c8c, 0x6728, 0x6c90, 0x7267, 0x76ee, 0x7766,
+ 0x7a46, 0x9da9, 0x6b7f, 0x6c92, 0x5922, 0x6726, 0x8499, 0x536f,
+ 0x5893, 0x5999, 0x5edf, 0x63cf, 0x6634, 0x6773, 0x6e3a, 0x732b,
+ 0x7ad7, 0x82d7, 0x9328, 0x52d9, 0x5deb, 0x61ae, 0x61cb, 0x620a,
+ 0x62c7, 0x64ab, 0x65e0, 0x6959, 0x6b66, 0x6bcb, 0x7121, 0x73f7,
+ 0x755d, 0x7e46, 0x821e, 0x8302, 0x856a, 0x8aa3, 0x8cbf, 0x9727,
+ 0x9d61, 0x58a8, 0x9ed8, 0x5011, 0x520e, 0x543b, 0x554f, 0x6587,
+ 0x6c76, 0x7d0a, 0x7d0b, 0x805e, 0x868a, 0x9580, 0x96ef, 0x52ff,
+ 0x6c95, 0x7269, 0x5473, 0x5a9a, 0x5c3e, 0x5d4b, 0x5f4c, 0x5fae,
+ 0x672a, 0x68b6, 0x6963, 0x6e3c, 0x6e44, 0x7709, 0x7c73, 0x7f8e,
+ 0x8587, 0x8b0e, 0x8ff7, 0x9761, 0x9ef4, 0x5cb7, 0x60b6, 0x610d,
+ 0x61ab, 0x654f, 0x65fb, 0x65fc, 0x6c11, 0x6cef, 0x739f, 0x73c9,
+ 0x7de1, 0x9594, 0x5bc6, 0x871c, 0x8b10, 0x525d, 0x535a, 0x62cd,
+ 0x640f, 0x64b2, 0x6734, 0x6a38, 0x6cca, 0x73c0, 0x749e, 0x7b94,
+ 0x7c95, 0x7e1b, 0x818a, 0x8236, 0x8584, 0x8feb, 0x96f9, 0x99c1,
+ 0x4f34, 0x534a, 0x53cd, 0x53db, 0x62cc, 0x642c, 0x6500, 0x6591,
+ 0x69c3, 0x6cee, 0x6f58, 0x73ed, 0x7554, 0x7622, 0x76e4, 0x76fc,
+ 0x78d0, 0x78fb, 0x792c, 0x7d46, 0x822c, 0x87e0, 0x8fd4, 0x9812,
+ 0x98ef, 0x52c3, 0x62d4, 0x64a5, 0x6e24, 0x6f51, 0x767c, 0x8dcb,
+ 0x91b1, 0x9262, 0x9aee, 0x9b43, 0x5023, 0x508d, 0x574a, 0x59a8,
+ 0x5c28, 0x5e47, 0x5f77, 0x623f, 0x653e, 0x65b9, 0x65c1, 0x6609,
+ 0x678b, 0x699c, 0x6ec2, 0x78c5, 0x7d21, 0x80aa, 0x8180, 0x822b,
+ 0x82b3, 0x84a1, 0x868c, 0x8a2a, 0x8b17, 0x90a6, 0x9632, 0x9f90,
+ 0x500d, 0x4ff3, 0xf963, 0x57f9, 0x5f98, 0x62dc, 0x6392, 0x676f,
+ 0x6e43, 0x7119, 0x76c3, 0x80cc, 0x80da, 0x88f4, 0x88f5, 0x8919,
+ 0x8ce0, 0x8f29, 0x914d, 0x966a, 0x4f2f, 0x4f70, 0x5e1b, 0x67cf,
+ 0x6822, 0x767d, 0x767e, 0x9b44, 0x5e61, 0x6a0a, 0x7169, 0x71d4,
+ 0x756a, 0xf964, 0x7e41, 0x8543, 0x85e9, 0x98dc, 0x4f10, 0x7b4f,
+ 0x7f70, 0x95a5, 0x51e1, 0x5e06, 0x68b5, 0x6c3e, 0x6c4e, 0x6cdb,
+ 0x72af, 0x7bc4, 0x8303, 0x6cd5, 0x743a, 0x50fb, 0x5288, 0x58c1,
+ 0x64d8, 0x6a97, 0x74a7, 0x7656, 0x78a7, 0x8617, 0x95e2, 0x9739,
+ 0xf965, 0x535e, 0x5f01, 0x8b8a, 0x8fa8, 0x8faf, 0x908a, 0x5225,
+ 0x77a5, 0x9c49, 0x9f08, 0x4e19, 0x5002, 0x5175, 0x5c5b, 0x5e77,
+ 0x661e, 0x663a, 0x67c4, 0x68c5, 0x70b3, 0x7501, 0x75c5, 0x79c9,
+ 0x7add, 0x8f27, 0x9920, 0x9a08, 0x4fdd, 0x5821, 0x5831, 0x5bf6,
+ 0x666e, 0x6b65, 0x6d11, 0x6e7a, 0x6f7d, 0x73e4, 0x752b, 0x83e9,
+ 0x88dc, 0x8913, 0x8b5c, 0x8f14, 0x4f0f, 0x50d5, 0x5310, 0x535c,
+ 0x5b93, 0x5fa9, 0x670d, 0x798f, 0x8179, 0x832f, 0x8514, 0x8907,
+ 0x8986, 0x8f39, 0x8f3b, 0x99a5, 0x9c12, 0x672c, 0x4e76, 0x4ff8,
+ 0x5949, 0x5c01, 0x5cef, 0x5cf0, 0x6367, 0x68d2, 0x70fd, 0x71a2,
+ 0x742b, 0x7e2b, 0x84ec, 0x8702, 0x9022, 0x92d2, 0x9cf3, 0x4e0d,
+ 0x4ed8, 0x4fef, 0x5085, 0x5256, 0x526f, 0x5426, 0x5490, 0x57e0,
+ 0x592b, 0x5a66, 0x5b5a, 0x5b75, 0x5bcc, 0x5e9c, 0xf966, 0x6276,
+ 0x6577, 0x65a7, 0x6d6e, 0x6ea5, 0x7236, 0x7b26, 0x7c3f, 0x7f36,
+ 0x8150, 0x8151, 0x819a, 0x8240, 0x8299, 0x83a9, 0x8a03, 0x8ca0,
+ 0x8ce6, 0x8cfb, 0x8d74, 0x8dba, 0x90e8, 0x91dc, 0x961c, 0x9644,
+ 0x99d9, 0x9ce7, 0x5317, 0x5206, 0x5429, 0x5674, 0x58b3, 0x5954,
+ 0x596e, 0x5fff, 0x61a4, 0x626e, 0x6610, 0x6c7e, 0x711a, 0x76c6,
+ 0x7c89, 0x7cde, 0x7d1b, 0x82ac, 0x8cc1, 0x96f0, 0xf967, 0x4f5b,
+ 0x5f17, 0x5f7f, 0x62c2, 0x5d29, 0x670b, 0x68da, 0x787c, 0x7e43,
+ 0x9d6c, 0x4e15, 0x5099, 0x5315, 0x532a, 0x5351, 0x5983, 0x5a62,
+ 0x5e87, 0x60b2, 0x618a, 0x6249, 0x6279, 0x6590, 0x6787, 0x69a7,
+ 0x6bd4, 0x6bd6, 0x6bd7, 0x6bd8, 0x6cb8, 0xf968, 0x7435, 0x75fa,
+ 0x7812, 0x7891, 0x79d5, 0x79d8, 0x7c83, 0x7dcb, 0x7fe1, 0x80a5,
+ 0x813e, 0x81c2, 0x83f2, 0x871a, 0x88e8, 0x8ab9, 0x8b6c, 0x8cbb,
+ 0x9119, 0x975e, 0x98db, 0x9f3b, 0x56ac, 0x5b2a, 0x5f6c, 0x658c,
+ 0x6ab3, 0x6baf, 0x6d5c, 0x6ff1, 0x7015, 0x725d, 0x73ad, 0x8ca7,
+ 0x8cd3, 0x983b, 0x6191, 0x6c37, 0x8058, 0x9a01, 0x4e4d, 0x4e8b,
+ 0x4e9b, 0x4ed5, 0x4f3a, 0x4f3c, 0x4f7f, 0x4fdf, 0x50ff, 0x53f2,
+ 0x53f8, 0x5506, 0x55e3, 0x56db, 0x58eb, 0x5962, 0x5a11, 0x5beb,
+ 0x5bfa, 0x5c04, 0x5df3, 0x5e2b, 0x5f99, 0x601d, 0x6368, 0x659c,
+ 0x65af, 0x67f6, 0x67fb, 0x68ad, 0x6b7b, 0x6c99, 0x6cd7, 0x6e23,
+ 0x7009, 0x7345, 0x7802, 0x793e, 0x7940, 0x7960, 0x79c1, 0x7be9,
+ 0x7d17, 0x7d72, 0x8086, 0x820d, 0x838e, 0x84d1, 0x86c7, 0x88df,
+ 0x8a50, 0x8a5e, 0x8b1d, 0x8cdc, 0x8d66, 0x8fad, 0x90aa, 0x98fc,
+ 0x99df, 0x9e9d, 0x524a, 0xf969, 0x6714, 0xf96a, 0x5098, 0x522a,
+ 0x5c71, 0x6563, 0x6c55, 0x73ca, 0x7523, 0x759d, 0x7b97, 0x849c,
+ 0x9178, 0x9730, 0x4e77, 0x6492, 0x6bba, 0x715e, 0x85a9, 0x4e09,
+ 0xf96b, 0x6749, 0x68ee, 0x6e17, 0x829f, 0x8518, 0x886b, 0x63f7,
+ 0x6f81, 0x9212, 0x98af, 0x4e0a, 0x50b7, 0x50cf, 0x511f, 0x5546,
+ 0x55aa, 0x5617, 0x5b40, 0x5c19, 0x5ce0, 0x5e38, 0x5e8a, 0x5ea0,
+ 0x5ec2, 0x60f3, 0x6851, 0x6a61, 0x6e58, 0x723d, 0x7240, 0x72c0,
+ 0x76f8, 0x7965, 0x7bb1, 0x7fd4, 0x88f3, 0x89f4, 0x8a73, 0x8c61,
+ 0x8cde, 0x971c, 0x585e, 0x74bd, 0x8cfd, 0x55c7, 0xf96c, 0x7a61,
+ 0x7d22, 0x8272, 0x7272, 0x751f, 0x7525, 0xf96d, 0x7b19, 0x5885,
+ 0x58fb, 0x5dbc, 0x5e8f, 0x5eb6, 0x5f90, 0x6055, 0x6292, 0x637f,
+ 0x654d, 0x6691, 0x66d9, 0x66f8, 0x6816, 0x68f2, 0x7280, 0x745e,
+ 0x7b6e, 0x7d6e, 0x7dd6, 0x7f72, 0x80e5, 0x8212, 0x85af, 0x897f,
+ 0x8a93, 0x901d, 0x92e4, 0x9ecd, 0x9f20, 0x5915, 0x596d, 0x5e2d,
+ 0x60dc, 0x6614, 0x6673, 0x6790, 0x6c50, 0x6dc5, 0x6f5f, 0x77f3,
+ 0x78a9, 0x84c6, 0x91cb, 0x932b, 0x4ed9, 0x50ca, 0x5148, 0x5584,
+ 0x5b0b, 0x5ba3, 0x6247, 0x657e, 0x65cb, 0x6e32, 0x717d, 0x7401,
+ 0x7444, 0x7487, 0x74bf, 0x766c, 0x79aa, 0x7dda, 0x7e55, 0x7fa8,
+ 0x817a, 0x81b3, 0x8239, 0x861a, 0x87ec, 0x8a75, 0x8de3, 0x9078,
+ 0x9291, 0x9425, 0x994d, 0x9bae, 0x5368, 0x5c51, 0x6954, 0x6cc4,
+ 0x6d29, 0x6e2b, 0x820c, 0x859b, 0x893b, 0x8a2d, 0x8aaa, 0x96ea,
+ 0x9f67, 0x5261, 0x66b9, 0x6bb2, 0x7e96, 0x87fe, 0x8d0d, 0x9583,
+ 0x965d, 0x651d, 0x6d89, 0x71ee, 0xf96e, 0x57ce, 0x59d3, 0x5bac,
+ 0x6027, 0x60fa, 0x6210, 0x661f, 0x665f, 0x7329, 0x73f9, 0x76db,
+ 0x7701, 0x7b6c, 0x8056, 0x8072, 0x8165, 0x8aa0, 0x9192, 0x4e16,
+ 0x52e2, 0x6b72, 0x6d17, 0x7a05, 0x7b39, 0x7d30, 0xf96f, 0x8cb0,
+ 0x53ec, 0x562f, 0x5851, 0x5bb5, 0x5c0f, 0x5c11, 0x5de2, 0x6240,
+ 0x6383, 0x6414, 0x662d, 0x68b3, 0x6cbc, 0x6d88, 0x6eaf, 0x701f,
+ 0x70a4, 0x71d2, 0x7526, 0x758f, 0x758e, 0x7619, 0x7b11, 0x7be0,
+ 0x7c2b, 0x7d20, 0x7d39, 0x852c, 0x856d, 0x8607, 0x8a34, 0x900d,
+ 0x9061, 0x90b5, 0x92b7, 0x97f6, 0x9a37, 0x4fd7, 0x5c6c, 0x675f,
+ 0x6d91, 0x7c9f, 0x7e8c, 0x8b16, 0x8d16, 0x901f, 0x5b6b, 0x5dfd,
+ 0x640d, 0x84c0, 0x905c, 0x98e1, 0x7387, 0x5b8b, 0x609a, 0x677e,
+ 0x6dde, 0x8a1f, 0x8aa6, 0x9001, 0x980c, 0x5237, 0xf970, 0x7051,
+ 0x788e, 0x9396, 0x8870, 0x91d7, 0x4fee, 0x53d7, 0x55fd, 0x56da,
+ 0x5782, 0x58fd, 0x5ac2, 0x5b88, 0x5cab, 0x5cc0, 0x5e25, 0x6101,
+ 0x620d, 0x624b, 0x6388, 0x641c, 0x6536, 0x6578, 0x6a39, 0x6b8a,
+ 0x6c34, 0x6d19, 0x6f31, 0x71e7, 0x72e9, 0x7378, 0x7407, 0x74b2,
+ 0x7626, 0x7761, 0x79c0, 0x7a57, 0x7aea, 0x7cb9, 0x7d8f, 0x7dac,
+ 0x7e61, 0x7f9e, 0x8129, 0x8331, 0x8490, 0x84da, 0x85ea, 0x8896,
+ 0x8ab0, 0x8b90, 0x8f38, 0x9042, 0x9083, 0x916c, 0x9296, 0x92b9,
+ 0x968b, 0x96a7, 0x96a8, 0x96d6, 0x9700, 0x9808, 0x9996, 0x9ad3,
+ 0x9b1a, 0x53d4, 0x587e, 0x5919, 0x5b70, 0x5bbf, 0x6dd1, 0x6f5a,
+ 0x719f, 0x7421, 0x74b9, 0x8085, 0x83fd, 0x5de1, 0x5f87, 0x5faa,
+ 0x6042, 0x65ec, 0x6812, 0x696f, 0x6a53, 0x6b89, 0x6d35, 0x6df3,
+ 0x73e3, 0x76fe, 0x77ac, 0x7b4d, 0x7d14, 0x8123, 0x821c, 0x8340,
+ 0x84f4, 0x8563, 0x8a62, 0x8ac4, 0x9187, 0x931e, 0x9806, 0x99b4,
+ 0x620c, 0x8853, 0x8ff0, 0x9265, 0x5d07, 0x5d27, 0x5d69, 0x745f,
+ 0x819d, 0x8768, 0x6fd5, 0x62fe, 0x7fd2, 0x8936, 0x8972, 0x4e1e,
+ 0x4e58, 0x50e7, 0x52dd, 0x5347, 0x627f, 0x6607, 0x7e69, 0x8805,
+ 0x965e, 0x4f8d, 0x5319, 0x5636, 0x59cb, 0x5aa4, 0x5c38, 0x5c4e,
+ 0x5c4d, 0x5e02, 0x5f11, 0x6043, 0x65bd, 0x662f, 0x6642, 0x67be,
+ 0x67f4, 0x731c, 0x77e2, 0x793a, 0x7fc5, 0x8494, 0x84cd, 0x8996,
+ 0x8a66, 0x8a69, 0x8ae1, 0x8c55, 0x8c7a, 0x57f4, 0x5bd4, 0x5f0f,
+ 0x606f, 0x62ed, 0x690d, 0x6b96, 0x6e5c, 0x7184, 0x7bd2, 0x8755,
+ 0x8b58, 0x8efe, 0x98df, 0x98fe, 0x4f38, 0x4f81, 0x4fe1, 0x547b,
+ 0x5a20, 0x5bb8, 0x613c, 0x65b0, 0x6668, 0x71fc, 0x7533, 0x795e,
+ 0x7d33, 0x814e, 0x81e3, 0x8398, 0x85aa, 0x85ce, 0x8703, 0x8a0a,
+ 0x8eab, 0x8f9b, 0xf971, 0x8fc5, 0x5931, 0x5ba4, 0x5be6, 0x6089,
+ 0x5be9, 0x5c0b, 0x5fc3, 0x6c81, 0xf972, 0x6df1, 0x700b, 0x751a,
+ 0x82af, 0x8af6, 0x4ec0, 0x5341, 0xf973, 0x96d9, 0x6c0f, 0x4e9e,
+ 0x4fc4, 0x5152, 0x555e, 0x5a25, 0x5ce8, 0x6211, 0x7259, 0x82bd,
+ 0x83aa, 0x86fe, 0x8859, 0x8a1d, 0x963f, 0x96c5, 0x9913, 0x9d09,
+ 0x9d5d, 0x580a, 0x5cb3, 0x5dbd, 0x5e44, 0x60e1, 0x6115, 0x63e1,
+ 0x6a02, 0x6e25, 0x9102, 0x9354, 0x984e, 0x9c10, 0x9f77, 0x5b89,
+ 0x5cb8, 0x6309, 0x664f, 0x6848, 0x773c, 0x96c1, 0x978d, 0x9854,
+ 0x9b9f, 0x65a1, 0x8b01, 0x8ecb, 0x95bc, 0x5535, 0x5ca9, 0x5dd6,
+ 0x5eb5, 0x6697, 0x764c, 0x83f4, 0x95c7, 0x58d3, 0x62bc, 0x72ce,
+ 0x9d28, 0x4ef0, 0x592e, 0x600f, 0x663b, 0x6b83, 0x79e7, 0x9d26,
+ 0x5393, 0x54c0, 0x57c3, 0x5d16, 0x611b, 0x66d6, 0x6daf, 0x788d,
+ 0x827e, 0x9698, 0x9744, 0x5384, 0x627c, 0x6396, 0x6db2, 0x7e0a,
+ 0x814b, 0x984d, 0x6afb, 0x7f4c, 0x9daf, 0x9e1a, 0x4e5f, 0x503b,
+ 0x51b6, 0x591c, 0x60f9, 0x63f6, 0x6930, 0x723a, 0x8036, 0xf974,
+ 0x91ce, 0x5f31, 0xf975, 0xf976, 0x7d04, 0x82e5, 0x846f, 0x84bb,
+ 0x85e5, 0x8e8d, 0xf977, 0x4f6f, 0xf978, 0xf979, 0x58e4, 0x5b43,
+ 0x6059, 0x63da, 0x6518, 0x656d, 0x6698, 0xf97a, 0x694a, 0x6a23,
+ 0x6d0b, 0x7001, 0x716c, 0x75d2, 0x760d, 0x79b3, 0x7a70, 0xf97b,
+ 0x7f8a, 0xf97c, 0x8944, 0xf97d, 0x8b93, 0x91c0, 0x967d, 0xf97e,
+ 0x990a, 0x5704, 0x5fa1, 0x65bc, 0x6f01, 0x7600, 0x79a6, 0x8a9e,
+ 0x99ad, 0x9b5a, 0x9f6c, 0x5104, 0x61b6, 0x6291, 0x6a8d, 0x81c6,
+ 0x5043, 0x5830, 0x5f66, 0x7109, 0x8a00, 0x8afa, 0x5b7c, 0x8616,
+ 0x4ffa, 0x513c, 0x56b4, 0x5944, 0x63a9, 0x6df9, 0x5daa, 0x696d,
+ 0x5186, 0x4e88, 0x4f59, 0xf97f, 0xf980, 0xf981, 0x5982, 0xf982,
+ 0xf983, 0x6b5f, 0x6c5d, 0xf984, 0x74b5, 0x7916, 0xf985, 0x8207,
+ 0x8245, 0x8339, 0x8f3f, 0x8f5d, 0xf986, 0x9918, 0xf987, 0xf988,
+ 0xf989, 0x4ea6, 0xf98a, 0x57df, 0x5f79, 0x6613, 0xf98b, 0xf98c,
+ 0x75ab, 0x7e79, 0x8b6f, 0xf98d, 0x9006, 0x9a5b, 0x56a5, 0x5827,
+ 0x59f8, 0x5a1f, 0x5bb4, 0xf98e, 0x5ef6, 0xf98f, 0xf990, 0x6350,
+ 0x633b, 0xf991, 0x693d, 0x6c87, 0x6cbf, 0x6d8e, 0x6d93, 0x6df5,
+ 0x6f14, 0xf992, 0x70df, 0x7136, 0x7159, 0xf993, 0x71c3, 0x71d5,
+ 0xf994, 0x784f, 0x786f, 0xf995, 0x7b75, 0x7de3, 0xf996, 0x7e2f,
+ 0xf997, 0x884d, 0x8edf, 0xf998, 0xf999, 0xf99a, 0x925b, 0xf99b,
+ 0x9cf6, 0xf99c, 0xf99d, 0xf99e, 0x6085, 0x6d85, 0xf99f, 0x71b1,
+ 0xf9a0, 0xf9a1, 0x95b1, 0x53ad, 0xf9a2, 0xf9a3, 0xf9a4, 0x67d3,
+ 0xf9a5, 0x708e, 0x7130, 0x7430, 0x8276, 0x82d2, 0xf9a6, 0x95bb,
+ 0x9ae5, 0x9e7d, 0x66c4, 0xf9a7, 0x71c1, 0x8449, 0xf9a8, 0xf9a9,
+ 0x584b, 0xf9aa, 0xf9ab, 0x5db8, 0x5f71, 0xf9ac, 0x6620, 0x668e,
+ 0x6979, 0x69ae, 0x6c38, 0x6cf3, 0x6e36, 0x6f41, 0x6fda, 0x701b,
+ 0x702f, 0x7150, 0x71df, 0x7370, 0xf9ad, 0x745b, 0xf9ae, 0x74d4,
+ 0x76c8, 0x7a4e, 0x7e93, 0xf9af, 0xf9b0, 0x82f1, 0x8a60, 0x8fce,
+ 0xf9b1, 0x9348, 0xf9b2, 0x9719, 0xf9b3, 0xf9b4, 0x4e42, 0x502a,
+ 0xf9b5, 0x5208, 0x53e1, 0x66f3, 0x6c6d, 0x6fca, 0x730a, 0x777f,
+ 0x7a62, 0x82ae, 0x85dd, 0x8602, 0xf9b6, 0x88d4, 0x8a63, 0x8b7d,
+ 0x8c6b, 0xf9b7, 0x92b3, 0xf9b8, 0x9713, 0x9810, 0x4e94, 0x4f0d,
+ 0x4fc9, 0x50b2, 0x5348, 0x543e, 0x5433, 0x55da, 0x5862, 0x58ba,
+ 0x5967, 0x5a1b, 0x5be4, 0x609f, 0xf9b9, 0x61ca, 0x6556, 0x65ff,
+ 0x6664, 0x68a7, 0x6c5a, 0x6fb3, 0x70cf, 0x71ac, 0x7352, 0x7b7d,
+ 0x8708, 0x8aa4, 0x9c32, 0x9f07, 0x5c4b, 0x6c83, 0x7344, 0x7389,
+ 0x923a, 0x6eab, 0x7465, 0x761f, 0x7a69, 0x7e15, 0x860a, 0x5140,
+ 0x58c5, 0x64c1, 0x74ee, 0x7515, 0x7670, 0x7fc1, 0x9095, 0x96cd,
+ 0x9954, 0x6e26, 0x74e6, 0x7aa9, 0x7aaa, 0x81e5, 0x86d9, 0x8778,
+ 0x8a1b, 0x5a49, 0x5b8c, 0x5b9b, 0x68a1, 0x6900, 0x6d63, 0x73a9,
+ 0x7413, 0x742c, 0x7897, 0x7de9, 0x7feb, 0x8118, 0x8155, 0x839e,
+ 0x8c4c, 0x962e, 0x9811, 0x66f0, 0x5f80, 0x65fa, 0x6789, 0x6c6a,
+ 0x738b, 0x502d, 0x5a03, 0x6b6a, 0x77ee, 0x5916, 0x5d6c, 0x5dcd,
+ 0x7325, 0x754f, 0xf9ba, 0xf9bb, 0x50e5, 0x51f9, 0x582f, 0x592d,
+ 0x5996, 0x59da, 0x5be5, 0xf9bc, 0xf9bd, 0x5da2, 0x62d7, 0x6416,
+ 0x6493, 0x64fe, 0xf9be, 0x66dc, 0xf9bf, 0x6a48, 0xf9c0, 0x71ff,
+ 0x7464, 0xf9c1, 0x7a88, 0x7aaf, 0x7e47, 0x7e5e, 0x8000, 0x8170,
+ 0xf9c2, 0x87ef, 0x8981, 0x8b20, 0x9059, 0xf9c3, 0x9080, 0x9952,
+ 0x617e, 0x6b32, 0x6d74, 0x7e1f, 0x8925, 0x8fb1, 0x4fd1, 0x50ad,
+ 0x5197, 0x52c7, 0x57c7, 0x5889, 0x5bb9, 0x5eb8, 0x6142, 0x6995,
+ 0x6d8c, 0x6e67, 0x6eb6, 0x7194, 0x7462, 0x7528, 0x752c, 0x8073,
+ 0x8338, 0x84c9, 0x8e0a, 0x9394, 0x93de, 0xf9c4, 0x4e8e, 0x4f51,
+ 0x5076, 0x512a, 0x53c8, 0x53cb, 0x53f3, 0x5b87, 0x5bd3, 0x5c24,
+ 0x611a, 0x6182, 0x65f4, 0x725b, 0x7397, 0x7440, 0x76c2, 0x7950,
+ 0x7991, 0x79b9, 0x7d06, 0x7fbd, 0x828b, 0x85d5, 0x865e, 0x8fc2,
+ 0x9047, 0x90f5, 0x91ea, 0x9685, 0x96e8, 0x96e9, 0x52d6, 0x5f67,
+ 0x65ed, 0x6631, 0x682f, 0x715c, 0x7a36, 0x90c1, 0x980a, 0x4e91,
+ 0xf9c5, 0x6a52, 0x6b9e, 0x6f90, 0x7189, 0x8018, 0x82b8, 0x8553,
+ 0x904b, 0x9695, 0x96f2, 0x97fb, 0x851a, 0x9b31, 0x4e90, 0x718a,
+ 0x96c4, 0x5143, 0x539f, 0x54e1, 0x5713, 0x5712, 0x57a3, 0x5a9b,
+ 0x5ac4, 0x5bc3, 0x6028, 0x613f, 0x63f4, 0x6c85, 0x6d39, 0x6e72,
+ 0x6e90, 0x7230, 0x733f, 0x7457, 0x82d1, 0x8881, 0x8f45, 0x9060,
+ 0xf9c6, 0x9662, 0x9858, 0x9d1b, 0x6708, 0x8d8a, 0x925e, 0x4f4d,
+ 0x5049, 0x50de, 0x5371, 0x570d, 0x59d4, 0x5a01, 0x5c09, 0x6170,
+ 0x6690, 0x6e2d, 0x7232, 0x744b, 0x7def, 0x80c3, 0x840e, 0x8466,
+ 0x853f, 0x875f, 0x885b, 0x8918, 0x8b02, 0x9055, 0x97cb, 0x9b4f,
+ 0x4e73, 0x4f91, 0x5112, 0x516a, 0xf9c7, 0x552f, 0x55a9, 0x5b7a,
+ 0x5ba5, 0x5e7c, 0x5e7d, 0x5ebe, 0x60a0, 0x60df, 0x6108, 0x6109,
+ 0x63c4, 0x6538, 0x6709, 0xf9c8, 0x67d4, 0x67da, 0xf9c9, 0x6961,
+ 0x6962, 0x6cb9, 0x6d27, 0xf9ca, 0x6e38, 0xf9cb, 0x6fe1, 0x7336,
+ 0x7337, 0xf9cc, 0x745c, 0x7531, 0xf9cd, 0x7652, 0xf9ce, 0xf9cf,
+ 0x7dad, 0x81fe, 0x8438, 0x88d5, 0x8a98, 0x8adb, 0x8aed, 0x8e30,
+ 0x8e42, 0x904a, 0x903e, 0x907a, 0x9149, 0x91c9, 0x936e, 0xf9d0,
+ 0xf9d1, 0x5809, 0xf9d2, 0x6bd3, 0x8089, 0x80b2, 0xf9d3, 0xf9d4,
+ 0x5141, 0x596b, 0x5c39, 0xf9d5, 0xf9d6, 0x6f64, 0x73a7, 0x80e4,
+ 0x8d07, 0xf9d7, 0x9217, 0x958f, 0xf9d8, 0xf9d9, 0xf9da, 0xf9db,
+ 0x807f, 0x620e, 0x701c, 0x7d68, 0x878d, 0xf9dc, 0x57a0, 0x6069,
+ 0x6147, 0x6bb7, 0x8abe, 0x9280, 0x96b1, 0x4e59, 0x541f, 0x6deb,
+ 0x852d, 0x9670, 0x97f3, 0x98ee, 0x63d6, 0x6ce3, 0x9091, 0x51dd,
+ 0x61c9, 0x81ba, 0x9df9, 0x4f9d, 0x501a, 0x5100, 0x5b9c, 0x610f,
+ 0x61ff, 0x64ec, 0x6905, 0x6bc5, 0x7591, 0x77e3, 0x7fa9, 0x8264,
+ 0x858f, 0x87fb, 0x8863, 0x8abc, 0x8b70, 0x91ab, 0x4e8c, 0x4ee5,
+ 0x4f0a, 0xf9dd, 0xf9de, 0x5937, 0x59e8, 0xf9df, 0x5df2, 0x5f1b,
+ 0x5f5b, 0x6021, 0xf9e0, 0xf9e1, 0xf9e2, 0xf9e3, 0x723e, 0x73e5,
+ 0xf9e4, 0x7570, 0x75cd, 0xf9e5, 0x79fb, 0xf9e6, 0x800c, 0x8033,
+ 0x8084, 0x82e1, 0x8351, 0xf9e7, 0xf9e8, 0x8cbd, 0x8cb3, 0x9087,
+ 0xf9e9, 0xf9ea, 0x98f4, 0x990c, 0xf9eb, 0xf9ec, 0x7037, 0x76ca,
+ 0x7fca, 0x7fcc, 0x7ffc, 0x8b1a, 0x4eba, 0x4ec1, 0x5203, 0x5370,
+ 0xf9ed, 0x54bd, 0x56e0, 0x59fb, 0x5bc5, 0x5f15, 0x5fcd, 0x6e6e,
+ 0xf9ee, 0xf9ef, 0x7d6a, 0x8335, 0xf9f0, 0x8693, 0x8a8d, 0xf9f1,
+ 0x976d, 0x9777, 0xf9f2, 0xf9f3, 0x4e00, 0x4f5a, 0x4f7e, 0x58f9,
+ 0x65e5, 0x6ea2, 0x9038, 0x93b0, 0x99b9, 0x4efb, 0x58ec, 0x598a,
+ 0x59d9, 0x6041, 0xf9f4, 0xf9f5, 0x7a14, 0xf9f6, 0x834f, 0x8cc3,
+ 0x5165, 0x5344, 0xf9f7, 0xf9f8, 0xf9f9, 0x4ecd, 0x5269, 0x5b55,
+ 0x82bf, 0x4ed4, 0x523a, 0x54a8, 0x59c9, 0x59ff, 0x5b50, 0x5b57,
+ 0x5b5c, 0x6063, 0x6148, 0x6ecb, 0x7099, 0x716e, 0x7386, 0x74f7,
+ 0x75b5, 0x78c1, 0x7d2b, 0x8005, 0x81ea, 0x8328, 0x8517, 0x85c9,
+ 0x8aee, 0x8cc7, 0x96cc, 0x4f5c, 0x52fa, 0x56bc, 0x65ab, 0x6628,
+ 0x707c, 0x70b8, 0x7235, 0x7dbd, 0x828d, 0x914c, 0x96c0, 0x9d72,
+ 0x5b71, 0x68e7, 0x6b98, 0x6f7a, 0x76de, 0x5c91, 0x66ab, 0x6f5b,
+ 0x7bb4, 0x7c2a, 0x8836, 0x96dc, 0x4e08, 0x4ed7, 0x5320, 0x5834,
+ 0x58bb, 0x58ef, 0x596c, 0x5c07, 0x5e33, 0x5e84, 0x5f35, 0x638c,
+ 0x66b2, 0x6756, 0x6a1f, 0x6aa3, 0x6b0c, 0x6f3f, 0x7246, 0xf9fa,
+ 0x7350, 0x748b, 0x7ae0, 0x7ca7, 0x8178, 0x81df, 0x81e7, 0x838a,
+ 0x846c, 0x8523, 0x8594, 0x85cf, 0x88dd, 0x8d13, 0x91ac, 0x9577,
+ 0x969c, 0x518d, 0x54c9, 0x5728, 0x5bb0, 0x624d, 0x6750, 0x683d,
+ 0x6893, 0x6e3d, 0x6ed3, 0x707d, 0x7e21, 0x88c1, 0x8ca1, 0x8f09,
+ 0x9f4b, 0x9f4e, 0x722d, 0x7b8f, 0x8acd, 0x931a, 0x4f47, 0x4f4e,
+ 0x5132, 0x5480, 0x59d0, 0x5e95, 0x62b5, 0x6775, 0x696e, 0x6a17,
+ 0x6cae, 0x6e1a, 0x72d9, 0x732a, 0x75bd, 0x7bb8, 0x7d35, 0x82e7,
+ 0x83f9, 0x8457, 0x85f7, 0x8a5b, 0x8caf, 0x8e87, 0x9019, 0x90b8,
+ 0x96ce, 0x9f5f, 0x52e3, 0x540a, 0x5ae1, 0x5bc2, 0x6458, 0x6575,
+ 0x6ef4, 0x72c4, 0xf9fb, 0x7684, 0x7a4d, 0x7b1b, 0x7c4d, 0x7e3e,
+ 0x7fdf, 0x837b, 0x8b2b, 0x8cca, 0x8d64, 0x8de1, 0x8e5f, 0x8fea,
+ 0x8ff9, 0x9069, 0x93d1, 0x4f43, 0x4f7a, 0x50b3, 0x5168, 0x5178,
+ 0x524d, 0x526a, 0x5861, 0x587c, 0x5960, 0x5c08, 0x5c55, 0x5edb,
+ 0x609b, 0x6230, 0x6813, 0x6bbf, 0x6c08, 0x6fb1, 0x714e, 0x7420,
+ 0x7530, 0x7538, 0x7551, 0x7672, 0x7b4c, 0x7b8b, 0x7bad, 0x7bc6,
+ 0x7e8f, 0x8a6e, 0x8f3e, 0x8f49, 0x923f, 0x9293, 0x9322, 0x942b,
+ 0x96fb, 0x985a, 0x986b, 0x991e, 0x5207, 0x622a, 0x6298, 0x6d59,
+ 0x7664, 0x7aca, 0x7bc0, 0x7d76, 0x5360, 0x5cbe, 0x5e97, 0x6f38,
+ 0x70b9, 0x7c98, 0x9711, 0x9b8e, 0x9ede, 0x63a5, 0x647a, 0x8776,
+ 0x4e01, 0x4e95, 0x4ead, 0x505c, 0x5075, 0x5448, 0x59c3, 0x5b9a,
+ 0x5e40, 0x5ead, 0x5ef7, 0x5f81, 0x60c5, 0x633a, 0x653f, 0x6574,
+ 0x65cc, 0x6676, 0x6678, 0x67fe, 0x6968, 0x6a89, 0x6b63, 0x6c40,
+ 0x6dc0, 0x6de8, 0x6e1f, 0x6e5e, 0x701e, 0x70a1, 0x738e, 0x73fd,
+ 0x753a, 0x775b, 0x7887, 0x798e, 0x7a0b, 0x7a7d, 0x7cbe, 0x7d8e,
+ 0x8247, 0x8a02, 0x8aea, 0x8c9e, 0x912d, 0x914a, 0x91d8, 0x9266,
+ 0x92cc, 0x9320, 0x9706, 0x9756, 0x975c, 0x9802, 0x9f0e, 0x5236,
+ 0x5291, 0x557c, 0x5824, 0x5e1d, 0x5f1f, 0x608c, 0x63d0, 0x68af,
+ 0x6fdf, 0x796d, 0x7b2c, 0x81cd, 0x85ba, 0x88fd, 0x8af8, 0x8e44,
+ 0x918d, 0x9664, 0x969b, 0x973d, 0x984c, 0x9f4a, 0x4fce, 0x5146,
+ 0x51cb, 0x52a9, 0x5632, 0x5f14, 0x5f6b, 0x63aa, 0x64cd, 0x65e9,
+ 0x6641, 0x66fa, 0x66f9, 0x671d, 0x689d, 0x68d7, 0x69fd, 0x6f15,
+ 0x6f6e, 0x7167, 0x71e5, 0x722a, 0x74aa, 0x773a, 0x7956, 0x795a,
+ 0x79df, 0x7a20, 0x7a95, 0x7c97, 0x7cdf, 0x7d44, 0x7e70, 0x8087,
+ 0x85fb, 0x86a4, 0x8a54, 0x8abf, 0x8d99, 0x8e81, 0x9020, 0x906d,
+ 0x91e3, 0x963b, 0x96d5, 0x9ce5, 0x65cf, 0x7c07, 0x8db3, 0x93c3,
+ 0x5b58, 0x5c0a, 0x5352, 0x62d9, 0x731d, 0x5027, 0x5b97, 0x5f9e,
+ 0x60b0, 0x616b, 0x68d5, 0x6dd9, 0x742e, 0x7a2e, 0x7d42, 0x7d9c,
+ 0x7e31, 0x816b, 0x8e2a, 0x8e35, 0x937e, 0x9418, 0x4f50, 0x5750,
+ 0x5de6, 0x5ea7, 0x632b, 0x7f6a, 0x4e3b, 0x4f4f, 0x4f8f, 0x505a,
+ 0x59dd, 0x80c4, 0x546a, 0x5468, 0x55fe, 0x594f, 0x5b99, 0x5dde,
+ 0x5eda, 0x665d, 0x6731, 0x67f1, 0x682a, 0x6ce8, 0x6d32, 0x6e4a,
+ 0x6f8d, 0x70b7, 0x73e0, 0x7587, 0x7c4c, 0x7d02, 0x7d2c, 0x7da2,
+ 0x821f, 0x86db, 0x8a3b, 0x8a85, 0x8d70, 0x8e8a, 0x8f33, 0x9031,
+ 0x914e, 0x9152, 0x9444, 0x99d0, 0x7af9, 0x7ca5, 0x4fca, 0x5101,
+ 0x51c6, 0x57c8, 0x5bef, 0x5cfb, 0x6659, 0x6a3d, 0x6d5a, 0x6e96,
+ 0x6fec, 0x710c, 0x756f, 0x7ae3, 0x8822, 0x9021, 0x9075, 0x96cb,
+ 0x99ff, 0x8301, 0x4e2d, 0x4ef2, 0x8846, 0x91cd, 0x537d, 0x6adb,
+ 0x696b, 0x6c41, 0x847a, 0x589e, 0x618e, 0x66fe, 0x62ef, 0x70dd,
+ 0x7511, 0x75c7, 0x7e52, 0x84b8, 0x8b49, 0x8d08, 0x4e4b, 0x53ea,
+ 0x54ab, 0x5730, 0x5740, 0x5fd7, 0x6301, 0x6307, 0x646f, 0x652f,
+ 0x65e8, 0x667a, 0x679d, 0x67b3, 0x6b62, 0x6c60, 0x6c9a, 0x6f2c,
+ 0x77e5, 0x7825, 0x7949, 0x7957, 0x7d19, 0x80a2, 0x8102, 0x81f3,
+ 0x829d, 0x82b7, 0x8718, 0x8a8c, 0xf9fc, 0x8d04, 0x8dbe, 0x9072,
+ 0x76f4, 0x7a19, 0x7a37, 0x7e54, 0x8077, 0x5507, 0x55d4, 0x5875,
+ 0x632f, 0x6422, 0x6649, 0x664b, 0x686d, 0x699b, 0x6b84, 0x6d25,
+ 0x6eb1, 0x73cd, 0x7468, 0x74a1, 0x755b, 0x75b9, 0x76e1, 0x771e,
+ 0x778b, 0x79e6, 0x7e09, 0x7e1d, 0x81fb, 0x852f, 0x8897, 0x8a3a,
+ 0x8cd1, 0x8eeb, 0x8fb0, 0x9032, 0x93ad, 0x9663, 0x9673, 0x9707,
+ 0x4f84, 0x53f1, 0x59ea, 0x5ac9, 0x5e19, 0x684e, 0x74c6, 0x75be,
+ 0x79e9, 0x7a92, 0x81a3, 0x86ed, 0x8cea, 0x8dcc, 0x8fed, 0x659f,
+ 0x6715, 0xf9fd, 0x57f7, 0x6f57, 0x7ddd, 0x8f2f, 0x93f6, 0x96c6,
+ 0x5fb5, 0x61f2, 0x6f84, 0x4e14, 0x4f98, 0x501f, 0x53c9, 0x55df,
+ 0x5d6f, 0x5dee, 0x6b21, 0x6b64, 0x78cb, 0x7b9a, 0xf9fe, 0x8e49,
+ 0x8eca, 0x906e, 0x6349, 0x643e, 0x7740, 0x7a84, 0x932f, 0x947f,
+ 0x9f6a, 0x64b0, 0x6faf, 0x71e6, 0x74a8, 0x74da, 0x7ac4, 0x7c12,
+ 0x7e82, 0x7cb2, 0x7e98, 0x8b9a, 0x8d0a, 0x947d, 0x9910, 0x994c,
+ 0x5239, 0x5bdf, 0x64e6, 0x672d, 0x7d2e, 0x50ed, 0x53c3, 0x5879,
+ 0x6158, 0x6159, 0x61fa, 0x65ac, 0x7ad9, 0x8b92, 0x8b96, 0x5009,
+ 0x5021, 0x5275, 0x5531, 0x5a3c, 0x5ee0, 0x5f70, 0x6134, 0x655e,
+ 0x660c, 0x6636, 0x66a2, 0x69cd, 0x6ec4, 0x6f32, 0x7316, 0x7621,
+ 0x7a93, 0x8139, 0x8259, 0x83d6, 0x84bc, 0x50b5, 0x57f0, 0x5bc0,
+ 0x5be8, 0x5f69, 0x63a1, 0x7826, 0x7db5, 0x83dc, 0x8521, 0x91c7,
+ 0x91f5, 0x518a, 0x67f5, 0x7b56, 0x8cac, 0x51c4, 0x59bb, 0x60bd,
+ 0x8655, 0x501c, 0xf9ff, 0x5254, 0x5c3a, 0x617d, 0x621a, 0x62d3,
+ 0x64f2, 0x65a5, 0x6ecc, 0x7620, 0x810a, 0x8e60, 0x965f, 0x96bb,
+ 0x4edf, 0x5343, 0x5598, 0x5929, 0x5ddd, 0x64c5, 0x6cc9, 0x6dfa,
+ 0x7394, 0x7a7f, 0x821b, 0x85a6, 0x8ce4, 0x8e10, 0x9077, 0x91e7,
+ 0x95e1, 0x9621, 0x97c6, 0x51f8, 0x54f2, 0x5586, 0x5fb9, 0x64a4,
+ 0x6f88, 0x7db4, 0x8f1f, 0x8f4d, 0x9435, 0x50c9, 0x5c16, 0x6cbe,
+ 0x6dfb, 0x751b, 0x77bb, 0x7c3d, 0x7c64, 0x8a79, 0x8ac2, 0x581e,
+ 0x59be, 0x5e16, 0x6377, 0x7252, 0x758a, 0x776b, 0x8adc, 0x8cbc,
+ 0x8f12, 0x5ef3, 0x6674, 0x6df8, 0x807d, 0x83c1, 0x8acb, 0x9751,
+ 0x9bd6, 0xfa00, 0x5243, 0x66ff, 0x6d95, 0x6eef, 0x7de0, 0x8ae6,
+ 0x902e, 0x905e, 0x9ad4, 0x521d, 0x527f, 0x54e8, 0x6194, 0x6284,
+ 0x62db, 0x68a2, 0x6912, 0x695a, 0x6a35, 0x7092, 0x7126, 0x785d,
+ 0x7901, 0x790e, 0x79d2, 0x7a0d, 0x8096, 0x8278, 0x82d5, 0x8349,
+ 0x8549, 0x8c82, 0x8d85, 0x9162, 0x918b, 0x91ae, 0x4fc3, 0x56d1,
+ 0x71ed, 0x77d7, 0x8700, 0x89f8, 0x5bf8, 0x5fd6, 0x6751, 0x90a8,
+ 0x53e2, 0x585a, 0x5bf5, 0x60a4, 0x6181, 0x6460, 0x7e3d, 0x8070,
+ 0x8525, 0x9283, 0x64ae, 0x50ac, 0x5d14, 0x6700, 0x589c, 0x62bd,
+ 0x63a8, 0x690e, 0x6978, 0x6a1e, 0x6e6b, 0x76ba, 0x79cb, 0x82bb,
+ 0x8429, 0x8acf, 0x8da8, 0x8ffd, 0x9112, 0x914b, 0x919c, 0x9310,
+ 0x9318, 0x939a, 0x96db, 0x9a36, 0x9c0d, 0x4e11, 0x755c, 0x795d,
+ 0x7afa, 0x7b51, 0x7bc9, 0x7e2e, 0x84c4, 0x8e59, 0x8e74, 0x8ef8,
+ 0x9010, 0x6625, 0x693f, 0x7443, 0x51fa, 0x672e, 0x9edc, 0x5145,
+ 0x5fe0, 0x6c96, 0x87f2, 0x885d, 0x8877, 0x60b4, 0x81b5, 0x8403,
+ 0x8d05, 0x53d6, 0x5439, 0x5634, 0x5a36, 0x5c31, 0x708a, 0x7fe0,
+ 0x805a, 0x8106, 0x81ed, 0x8da3, 0x9189, 0x9a5f, 0x9df2, 0x5074,
+ 0x4ec4, 0x53a0, 0x60fb, 0x6e2c, 0x5c64, 0x4f88, 0x5024, 0x55e4,
+ 0x5cd9, 0x5e5f, 0x6065, 0x6894, 0x6cbb, 0x6dc4, 0x71be, 0x75d4,
+ 0x75f4, 0x7661, 0x7a1a, 0x7a49, 0x7dc7, 0x7dfb, 0x7f6e, 0x81f4,
+ 0x86a9, 0x8f1c, 0x96c9, 0x99b3, 0x9f52, 0x5247, 0x52c5, 0x98ed,
+ 0x89aa, 0x4e03, 0x67d2, 0x6f06, 0x4fb5, 0x5be2, 0x6795, 0x6c88,
+ 0x6d78, 0x741b, 0x7827, 0x91dd, 0x937c, 0x87c4, 0x79e4, 0x7a31,
+ 0x5feb, 0x4ed6, 0x54a4, 0x553e, 0x58ae, 0x59a5, 0x60f0, 0x6253,
+ 0x62d6, 0x6736, 0x6955, 0x8235, 0x9640, 0x99b1, 0x99dd, 0x502c,
+ 0x5353, 0x5544, 0x577c, 0xfa01, 0x6258, 0xfa02, 0x64e2, 0x666b,
+ 0x67dd, 0x6fc1, 0x6fef, 0x7422, 0x7438, 0x8a17, 0x9438, 0x5451,
+ 0x5606, 0x5766, 0x5f48, 0x619a, 0x6b4e, 0x7058, 0x70ad, 0x7dbb,
+ 0x8a95, 0x596a, 0x812b, 0x63a2, 0x7708, 0x803d, 0x8caa, 0x5854,
+ 0x642d, 0x69bb, 0x5b95, 0x5e11, 0x6e6f, 0xfa03, 0x8569, 0x514c,
+ 0x53f0, 0x592a, 0x6020, 0x614b, 0x6b86, 0x6c70, 0x6cf0, 0x7b1e,
+ 0x80ce, 0x82d4, 0x8dc6, 0x90b0, 0x98b1, 0xfa04, 0x64c7, 0x6fa4,
+ 0x6491, 0x6504, 0x514e, 0x5410, 0x571f, 0x8a0e, 0x615f, 0x6876,
+ 0xfa05, 0x75db, 0x7b52, 0x7d71, 0x901a, 0x5806, 0x69cc, 0x817f,
+ 0x892a, 0x9000, 0x9839, 0x5078, 0x5957, 0x59ac, 0x6295, 0x900f,
+ 0x9b2a, 0x615d, 0x7279, 0x95d6, 0x5761, 0x5a46, 0x5df4, 0x628a,
+ 0x64ad, 0x64fa, 0x6777, 0x6ce2, 0x6d3e, 0x722c, 0x7436, 0x7834,
+ 0x7f77, 0x82ad, 0x8ddb, 0x9817, 0x5224, 0x5742, 0x677f, 0x7248,
+ 0x74e3, 0x8ca9, 0x8fa6, 0x9211, 0x962a, 0x516b, 0x53ed, 0x634c,
+ 0x4f69, 0x5504, 0x6096, 0x6557, 0x6c9b, 0x6d7f, 0x724c, 0x72fd,
+ 0x7a17, 0x8987, 0x8c9d, 0x5f6d, 0x6f8e, 0x70f9, 0x81a8, 0x610e,
+ 0x4fbf, 0x504f, 0x6241, 0x7247, 0x7bc7, 0x7de8, 0x7fe9, 0x904d,
+ 0x97ad, 0x9a19, 0x8cb6, 0x576a, 0x5e73, 0x67b0, 0x840d, 0x8a55,
+ 0x5420, 0x5b16, 0x5e63, 0x5ee2, 0x5f0a, 0x6583, 0x80ba, 0x853d,
+ 0x9589, 0x965b, 0x4f48, 0x5305, 0x530d, 0x530f, 0x5486, 0x54fa,
+ 0x5703, 0x5e03, 0x6016, 0x629b, 0x62b1, 0x6355, 0xfa06, 0x6ce1,
+ 0x6d66, 0x75b1, 0x7832, 0x80de, 0x812f, 0x82de, 0x8461, 0x84b2,
+ 0x888d, 0x8912, 0x900b, 0x92ea, 0x98fd, 0x9b91, 0x5e45, 0x66b4,
+ 0x66dd, 0x7011, 0x7206, 0xfa07, 0x4ff5, 0x527d, 0x5f6a, 0x6153,
+ 0x6753, 0x6a19, 0x6f02, 0x74e2, 0x7968, 0x8868, 0x8c79, 0x98c7,
+ 0x98c4, 0x9a43, 0x54c1, 0x7a1f, 0x6953, 0x8af7, 0x8c4a, 0x98a8,
+ 0x99ae, 0x5f7c, 0x62ab, 0x75b2, 0x76ae, 0x88ab, 0x907f, 0x9642,
+ 0x5339, 0x5f3c, 0x5fc5, 0x6ccc, 0x73cc, 0x7562, 0x758b, 0x7b46,
+ 0x82fe, 0x999d, 0x4e4f, 0x903c, 0x4e0b, 0x4f55, 0x53a6, 0x590f,
+ 0x5ec8, 0x6630, 0x6cb3, 0x7455, 0x8377, 0x8766, 0x8cc0, 0x9050,
+ 0x971e, 0x9c15, 0x58d1, 0x5b78, 0x8650, 0x8b14, 0x9db4, 0x5bd2,
+ 0x6068, 0x608d, 0x65f1, 0x6c57, 0x6f22, 0x6fa3, 0x701a, 0x7f55,
+ 0x7ff0, 0x9591, 0x9592, 0x9650, 0x97d3, 0x5272, 0x8f44, 0x51fd,
+ 0x542b, 0x54b8, 0x5563, 0x558a, 0x6abb, 0x6db5, 0x7dd8, 0x8266,
+ 0x929c, 0x9677, 0x9e79, 0x5408, 0x54c8, 0x76d2, 0x86e4, 0x95a4,
+ 0x95d4, 0x965c, 0x4ea2, 0x4f09, 0x59ee, 0x5ae6, 0x5df7, 0x6052,
+ 0x6297, 0x676d, 0x6841, 0x6c86, 0x6e2f, 0x7f38, 0x809b, 0x822a,
+ 0xfa08, 0xfa09, 0x9805, 0x4ea5, 0x5055, 0x54b3, 0x5793, 0x595a,
+ 0x5b69, 0x5bb3, 0x61c8, 0x6977, 0x6d77, 0x7023, 0x87f9, 0x89e3,
+ 0x8a72, 0x8ae7, 0x9082, 0x99ed, 0x9ab8, 0x52be, 0x6838, 0x5016,
+ 0x5e78, 0x674f, 0x8347, 0x884c, 0x4eab, 0x5411, 0x56ae, 0x73e6,
+ 0x9115, 0x97ff, 0x9909, 0x9957, 0x9999, 0x5653, 0x589f, 0x865b,
+ 0x8a31, 0x61b2, 0x6af6, 0x737b, 0x8ed2, 0x6b47, 0x96aa, 0x9a57,
+ 0x5955, 0x7200, 0x8d6b, 0x9769, 0x4fd4, 0x5cf4, 0x5f26, 0x61f8,
+ 0x665b, 0x6ceb, 0x70ab, 0x7384, 0x73b9, 0x73fe, 0x7729, 0x774d,
+ 0x7d43, 0x7d62, 0x7e23, 0x8237, 0x8852, 0xfa0a, 0x8ce2, 0x9249,
+ 0x986f, 0x5b51, 0x7a74, 0x8840, 0x9801, 0x5acc, 0x4fe0, 0x5354,
+ 0x593e, 0x5cfd, 0x633e, 0x6d79, 0x72f9, 0x8105, 0x8107, 0x83a2,
+ 0x92cf, 0x9830, 0x4ea8, 0x5144, 0x5211, 0x578b, 0x5f62, 0x6cc2,
+ 0x6ece, 0x7005, 0x7050, 0x70af, 0x7192, 0x73e9, 0x7469, 0x834a,
+ 0x87a2, 0x8861, 0x9008, 0x90a2, 0x93a3, 0x99a8, 0x516e, 0x5f57,
+ 0x60e0, 0x6167, 0x66b3, 0x8559, 0x8e4a, 0x91af, 0x978b, 0x4e4e,
+ 0x4e92, 0x547c, 0x58d5, 0x58fa, 0x597d, 0x5cb5, 0x5f27, 0x6236,
+ 0x6248, 0x660a, 0x6667, 0x6beb, 0x6d69, 0x6dcf, 0x6e56, 0x6ef8,
+ 0x6f94, 0x6fe0, 0x6fe9, 0x705d, 0x72d0, 0x7425, 0x745a, 0x74e0,
+ 0x7693, 0x795c, 0x7cca, 0x7e1e, 0x80e1, 0x82a6, 0x846b, 0x84bf,
+ 0x864e, 0x865f, 0x8774, 0x8b77, 0x8c6a, 0x93ac, 0x9800, 0x9865,
+ 0x60d1, 0x6216, 0x9177, 0x5a5a, 0x660f, 0x6df7, 0x6e3e, 0x743f,
+ 0x9b42, 0x5ffd, 0x60da, 0x7b0f, 0x54c4, 0x5f18, 0x6c5e, 0x6cd3,
+ 0x6d2a, 0x70d8, 0x7d05, 0x8679, 0x8a0c, 0x9d3b, 0x5316, 0x548c,
+ 0x5b05, 0x6a3a, 0x706b, 0x7575, 0x798d, 0x79be, 0x82b1, 0x83ef,
+ 0x8a71, 0x8b41, 0x8ca8, 0x9774, 0xfa0b, 0x64f4, 0x652b, 0x78ba,
+ 0x78bb, 0x7a6b, 0x4e38, 0x559a, 0x5950, 0x5ba6, 0x5e7b, 0x60a3,
+ 0x63db, 0x6b61, 0x6665, 0x6853, 0x6e19, 0x7165, 0x74b0, 0x7d08,
+ 0x9084, 0x9a69, 0x9c25, 0x6d3b, 0x6ed1, 0x733e, 0x8c41, 0x95ca,
+ 0x51f0, 0x5e4c, 0x5fa8, 0x604d, 0x60f6, 0x6130, 0x614c, 0x6643,
+ 0x6644, 0x69a5, 0x6cc1, 0x6e5f, 0x6ec9, 0x6f62, 0x714c, 0x749c,
+ 0x7687, 0x7bc1, 0x7c27, 0x8352, 0x8757, 0x9051, 0x968d, 0x9ec3,
+ 0x532f, 0x56de, 0x5efb, 0x5f8a, 0x6062, 0x6094, 0x61f7, 0x6666,
+ 0x6703, 0x6a9c, 0x6dee, 0x6fae, 0x7070, 0x736a, 0x7e6a, 0x81be,
+ 0x8334, 0x86d4, 0x8aa8, 0x8cc4, 0x5283, 0x7372, 0x5b96, 0x6a6b,
+ 0x9404, 0x54ee, 0x5686, 0x5b5d, 0x6548, 0x6585, 0x66c9, 0x689f,
+ 0x6d8d, 0x6dc6, 0x723b, 0x80b4, 0x9175, 0x9a4d, 0x4faf, 0x5019,
+ 0x539a, 0x540e, 0x543c, 0x5589, 0x55c5, 0x5e3f, 0x5f8c, 0x673d,
+ 0x7166, 0x73dd, 0x9005, 0x52db, 0x52f3, 0x5864, 0x58ce, 0x7104,
+ 0x718f, 0x71fb, 0x85b0, 0x8a13, 0x6688, 0x85a8, 0x55a7, 0x6684,
+ 0x714a, 0x8431, 0x5349, 0x5599, 0x6bc1, 0x5f59, 0x5fbd, 0x63ee,
+ 0x6689, 0x7147, 0x8af1, 0x8f1d, 0x9ebe, 0x4f11, 0x643a, 0x70cb,
+ 0x7566, 0x8667, 0x6064, 0x8b4e, 0x9df8, 0x5147, 0x51f6, 0x5308,
+ 0x6d36, 0x80f8, 0x9ed1, 0x6615, 0x6b23, 0x7098, 0x75d5, 0x5403,
+ 0x5c79, 0x7d07, 0x8a16, 0x6b20, 0x6b3d, 0x6b46, 0x5438, 0x6070,
+ 0x6d3d, 0x7fd5, 0x8208, 0x50d6, 0x51de, 0x559c, 0x566b, 0x56cd,
+ 0x59ec, 0x5b09, 0x5e0c, 0x6199, 0x6198, 0x6231, 0x665e, 0x66e6,
+ 0x7199, 0x71b9, 0x71ba, 0x72a7, 0x79a7, 0x7a00, 0x7fb2, 0x8a70
+};
+
+/* Map Table including tqunicode to ksc5601 hanja */
+static const struct map tqunicode_to_ksc5601_hanja[4888]=
+{
+ {0x4e00, 0x6c69}, {0x4e01, 0x6f4b}, {0x4e03, 0x7652},
+ {0x4e07, 0x5832}, {0x4e08, 0x6d5b}, {0x4e09, 0x5f32},
+ {0x4e0a, 0x5f3e}, {0x4e0b, 0x793b}, {0x4e0d, 0x5c74},
+ {0x4e11, 0x7564}, {0x4e14, 0x7326}, {0x4e15, 0x5d60},
+ {0x4e16, 0x6126}, {0x4e18, 0x4e78}, {0x4e19, 0x5c30},
+ {0x4e1e, 0x632a}, {0x4e2d, 0x7169}, {0x4e32, 0x4d7a},
+ {0x4e38, 0x7c2f}, {0x4e39, 0x5321}, {0x4e3b, 0x712b},
+ {0x4e42, 0x6751}, {0x4e43, 0x522c}, {0x4e45, 0x4e79},
+ {0x4e4b, 0x717d}, {0x4e4d, 0x5e3f}, {0x4e4e, 0x7b3a},
+ {0x4e4f, 0x7939}, {0x4e56, 0x4e52}, {0x4e58, 0x632b},
+ {0x4e59, 0x6b60}, {0x4e5d, 0x4e7a}, {0x4e5e, 0x4b77},
+ {0x4e5f, 0x6525}, {0x4e6b, 0x4a61}, {0x4e6d, 0x544c},
+ {0x4e73, 0x6a61}, {0x4e76, 0x5c63}, {0x4e77, 0x5f2d},
+ {0x4e7e, 0x4b6b}, {0x4e82, 0x552f}, {0x4e86, 0x5675},
+ {0x4e88, 0x6578}, {0x4e8b, 0x5e40}, {0x4e8c, 0x6c23},
+ {0x4e8e, 0x694d}, {0x4e90, 0x6a27}, {0x4e91, 0x6976},
+ {0x4e92, 0x7b3b}, {0x4e94, 0x6769}, {0x4e95, 0x6f4c},
+ {0x4e98, 0x5066}, {0x4e9b, 0x5e41}, {0x4e9e, 0x642c},
+ {0x4ea1, 0x584c}, {0x4ea2, 0x7971}, {0x4ea4, 0x4e5f},
+ {0x4ea5, 0x7a24}, {0x4ea6, 0x6632}, {0x4ea8, 0x7a7b},
+ {0x4eab, 0x7a3d}, {0x4eac, 0x4c48}, {0x4ead, 0x6f4d},
+ {0x4eae, 0x5555}, {0x4eb6, 0x5322}, {0x4eba, 0x6c51},
+ {0x4ec0, 0x6427}, {0x4ec1, 0x6c52}, {0x4ec4, 0x7631},
+ {0x4ec7, 0x4e7b}, {0x4eca, 0x5051}, {0x4ecb, 0x4b3f},
+ {0x4ecd, 0x6d24}, {0x4ed4, 0x6d28}, {0x4ed5, 0x5e42},
+ {0x4ed6, 0x7662}, {0x4ed7, 0x6d5c}, {0x4ed8, 0x5c75},
+ {0x4ed9, 0x6039}, {0x4edd, 0x544e}, {0x4edf, 0x7435},
+ {0x4ee3, 0x535b}, {0x4ee4, 0x5635}, {0x4ee5, 0x6c24},
+ {0x4ef0, 0x6466}, {0x4ef2, 0x716a}, {0x4ef6, 0x4b6c},
+ {0x4ef7, 0x4b40}, {0x4efb, 0x6c72}, {0x4f01, 0x506a},
+ {0x4f09, 0x7972}, {0x4f0a, 0x6c25}, {0x4f0b, 0x505f},
+ {0x4f0d, 0x676a}, {0x4f0e, 0x506b}, {0x4f0f, 0x5c51},
+ {0x4f10, 0x5b69}, {0x4f11, 0x7d4c}, {0x4f2f, 0x5b57},
+ {0x4f34, 0x5a61}, {0x4f36, 0x5636}, {0x4f38, 0x635f},
+ {0x4f3a, 0x5e43}, {0x4f3c, 0x5e44}, {0x4f3d, 0x4a21},
+ {0x4f43, 0x6e6c}, {0x4f46, 0x5323}, {0x4f47, 0x6e37},
+ {0x4f48, 0x784f}, {0x4f4d, 0x6a48}, {0x4f4e, 0x6e38},
+ {0x4f4f, 0x712c}, {0x4f50, 0x7125}, {0x4f51, 0x694e},
+ {0x4f55, 0x793c}, {0x4f59, 0x6579}, {0x4f5a, 0x6c6a},
+ {0x4f5b, 0x5d56}, {0x4f5c, 0x6d42}, {0x4f69, 0x7825},
+ {0x4f6f, 0x653a}, {0x4f70, 0x5b58}, {0x4f73, 0x4a22},
+ {0x4f76, 0x514d}, {0x4f7a, 0x6e6d}, {0x4f7e, 0x6c6b},
+ {0x4f7f, 0x5e45}, {0x4f81, 0x6360}, {0x4f83, 0x4a49},
+ {0x4f84, 0x7269}, {0x4f86, 0x554e}, {0x4f88, 0x7636},
+ {0x4f8a, 0x4e42}, {0x4f8b, 0x5647}, {0x4f8d, 0x6334},
+ {0x4f8f, 0x712d}, {0x4f91, 0x6a62}, {0x4f96, 0x5742},
+ {0x4f98, 0x7327}, {0x4f9b, 0x4d6a}, {0x4f9d, 0x6b6e},
+ {0x4fae, 0x5932}, {0x4faf, 0x7d25}, {0x4fb5, 0x7655},
+ {0x4fb6, 0x5562}, {0x4fbf, 0x7835}, {0x4fc2, 0x4c75},
+ {0x4fc3, 0x7535}, {0x4fc4, 0x642d}, {0x4fc9, 0x676b},
+ {0x4fca, 0x7155}, {0x4fce, 0x703b}, {0x4fd1, 0x6935},
+ {0x4fd3, 0x4c49}, {0x4fd4, 0x7a55}, {0x4fd7, 0x6154},
+ {0x4fda, 0x5756}, {0x4fdd, 0x5c41}, {0x4fdf, 0x5e46},
+ {0x4fe0, 0x7a6f}, {0x4fe1, 0x6361}, {0x4fee, 0x6173},
+ {0x4fef, 0x5c76}, {0x4ff1, 0x4e7c}, {0x4ff3, 0x5b44},
+ {0x4ff5, 0x7871}, {0x4ff8, 0x5c64}, {0x4ffa, 0x656f},
+ {0x5002, 0x5c31}, {0x5006, 0x5556}, {0x5009, 0x735a},
+ {0x500b, 0x4b41}, {0x500d, 0x5b43}, {0x5011, 0x597a},
+ {0x5012, 0x536e}, {0x5016, 0x7a38}, {0x5019, 0x7d26},
+ {0x501a, 0x6b6f}, {0x501c, 0x7426}, {0x501e, 0x4c4a},
+ {0x501f, 0x7328}, {0x5021, 0x735b}, {0x5023, 0x5b27},
+ {0x5024, 0x7637}, {0x5026, 0x4f66}, {0x5027, 0x7072},
+ {0x5028, 0x4b5a}, {0x502a, 0x6752}, {0x502b, 0x5743},
+ {0x502c, 0x7670}, {0x502d, 0x685e}, {0x503b, 0x6526},
+ {0x5043, 0x6567}, {0x5047, 0x4a23}, {0x5048, 0x4c27},
+ {0x5049, 0x6a49}, {0x504f, 0x7836}, {0x5055, 0x7a25},
+ {0x505a, 0x712e}, {0x505c, 0x6f4e}, {0x5065, 0x4b6d},
+ {0x5074, 0x7630}, {0x5075, 0x6f4f}, {0x5076, 0x694f},
+ {0x5078, 0x775e}, {0x5080, 0x4e53}, {0x5085, 0x5c77},
+ {0x508d, 0x5b28}, {0x5091, 0x4b78}, {0x5098, 0x5f21},
+ {0x5099, 0x5d61}, {0x50ac, 0x754a}, {0x50ad, 0x6936},
+ {0x50b2, 0x676c}, {0x50b3, 0x6e6e}, {0x50b5, 0x7370},
+ {0x50b7, 0x5f3f}, {0x50be, 0x4c4b}, {0x50c5, 0x5041},
+ {0x50c9, 0x7452}, {0x50ca, 0x603a}, {0x50cf, 0x5f40},
+ {0x50d1, 0x4e60}, {0x50d5, 0x5c52}, {0x50d6, 0x7d6a},
+ {0x50da, 0x5676}, {0x50de, 0x6a4a}, {0x50e5, 0x6869},
+ {0x50e7, 0x632c}, {0x50ed, 0x7350}, {0x50f9, 0x4a24},
+ {0x50fb, 0x5b78}, {0x50ff, 0x5e47}, {0x5100, 0x6b70},
+ {0x5101, 0x7156}, {0x5104, 0x6562}, {0x5106, 0x4c4c},
+ {0x5109, 0x4b7b}, {0x5112, 0x6a63}, {0x511f, 0x5f41},
+ {0x5121, 0x566d}, {0x512a, 0x6950}, {0x5132, 0x6e39},
+ {0x5137, 0x5563}, {0x513a, 0x5153}, {0x513c, 0x6570},
+ {0x5140, 0x6834}, {0x5141, 0x6b43}, {0x5143, 0x6a2a},
+ {0x5144, 0x7a7c}, {0x5145, 0x7576}, {0x5146, 0x703c},
+ {0x5147, 0x7d54}, {0x5148, 0x603b}, {0x5149, 0x4e43},
+ {0x514b, 0x503a}, {0x514c, 0x773a}, {0x514d, 0x5873},
+ {0x514e, 0x774d}, {0x5152, 0x642e}, {0x515c, 0x545f},
+ {0x5162, 0x5067}, {0x5165, 0x6c7d}, {0x5167, 0x522e},
+ {0x5168, 0x6e6f}, {0x5169, 0x5557}, {0x516a, 0x6a64},
+ {0x516b, 0x7822}, {0x516c, 0x4d6b}, {0x516d, 0x573f},
+ {0x516e, 0x7b31}, {0x5171, 0x4d6c}, {0x5175, 0x5c32},
+ {0x5176, 0x506c}, {0x5177, 0x4e7d}, {0x5178, 0x6e70},
+ {0x517c, 0x4c42}, {0x5180, 0x506d}, {0x5186, 0x6577},
+ {0x518a, 0x737c}, {0x518d, 0x6e22}, {0x5192, 0x5933},
+ {0x5195, 0x5874}, {0x5197, 0x6937}, {0x51a0, 0x4e2e},
+ {0x51a5, 0x5922}, {0x51aa, 0x5871}, {0x51ac, 0x544f},
+ {0x51b6, 0x6527}, {0x51b7, 0x5552}, {0x51bd, 0x5629},
+ {0x51c4, 0x7422}, {0x51c6, 0x7157}, {0x51c9, 0x5558},
+ {0x51cb, 0x703d}, {0x51cc, 0x5750}, {0x51cd, 0x5450},
+ {0x51dc, 0x574f}, {0x51dd, 0x6b6a}, {0x51de, 0x7d6b},
+ {0x51e1, 0x5b6d}, {0x51f0, 0x7c45}, {0x51f1, 0x4b42},
+ {0x51f6, 0x7d55}, {0x51f8, 0x7448}, {0x51f9, 0x686a},
+ {0x51fa, 0x7573}, {0x51fd, 0x795e}, {0x5200, 0x536f},
+ {0x5203, 0x6c53}, {0x5206, 0x5d42}, {0x5207, 0x6f37},
+ {0x5208, 0x6754}, {0x520a, 0x4a4a}, {0x520e, 0x597b},
+ {0x5211, 0x7a7d}, {0x5217, 0x562a}, {0x521d, 0x7478},
+ {0x5224, 0x7777}, {0x5225, 0x5c2c}, {0x5229, 0x5757},
+ {0x522a, 0x5f22}, {0x522e, 0x4e3e}, {0x5230, 0x5370},
+ {0x5236, 0x7024}, {0x5237, 0x616c}, {0x5238, 0x4f67},
+ {0x5239, 0x734b}, {0x523a, 0x6d29}, {0x523b, 0x4a3e},
+ {0x5243, 0x746f}, {0x5247, 0x764e}, {0x524a, 0x5e7b},
+ {0x524b, 0x503b}, {0x524c, 0x5537}, {0x524d, 0x6e71},
+ {0x5254, 0x7428}, {0x5256, 0x5c78}, {0x525b, 0x4b27},
+ {0x525d, 0x5a4e}, {0x5261, 0x6066}, {0x5269, 0x6d25},
+ {0x526a, 0x6e72}, {0x526f, 0x5c79}, {0x5272, 0x795c},
+ {0x5275, 0x735c}, {0x527d, 0x7872}, {0x527f, 0x7479},
+ {0x5283, 0x7c71}, {0x5287, 0x503c}, {0x5288, 0x5b79},
+ {0x5289, 0x5731}, {0x528d, 0x4b7c}, {0x5291, 0x7025},
+ {0x5292, 0x4b7d}, {0x529b, 0x5574}, {0x529f, 0x4d6d},
+ {0x52a0, 0x4a25}, {0x52a3, 0x562b}, {0x52a4, 0x5042},
+ {0x52a9, 0x703e}, {0x52aa, 0x523d}, {0x52ab, 0x4c24},
+ {0x52be, 0x7a36}, {0x52c1, 0x4c4d}, {0x52c3, 0x5a7a},
+ {0x52c5, 0x764f}, {0x52c7, 0x6938}, {0x52c9, 0x5875},
+ {0x52cd, 0x4c4e}, {0x52d2, 0x574d}, {0x52d5, 0x5451},
+ {0x52d6, 0x696d}, {0x52d8, 0x4a6b}, {0x52d9, 0x5962},
+ {0x52db, 0x7d32}, {0x52dd, 0x632d}, {0x52de, 0x564c},
+ {0x52df, 0x5934}, {0x52e2, 0x6127}, {0x52e3, 0x6e53},
+ {0x52e4, 0x5043}, {0x52f3, 0x7d33}, {0x52f5, 0x5564},
+ {0x52f8, 0x4f68}, {0x52fa, 0x6d43}, {0x52fb, 0x5032},
+ {0x52fe, 0x4e7e}, {0x52ff, 0x5a28}, {0x5305, 0x7850},
+ {0x5308, 0x7d56}, {0x530d, 0x7851}, {0x530f, 0x7852},
+ {0x5310, 0x5c53}, {0x5315, 0x5d62}, {0x5316, 0x7b79},
+ {0x5317, 0x5d41}, {0x5319, 0x6335}, {0x5320, 0x6d5d},
+ {0x5321, 0x4e44}, {0x5323, 0x4b21}, {0x532a, 0x5d63},
+ {0x532f, 0x7c5d}, {0x5339, 0x792f}, {0x533f, 0x527b},
+ {0x5340, 0x4f21}, {0x5341, 0x6428}, {0x5343, 0x7436},
+ {0x5344, 0x6c7e}, {0x5347, 0x632e}, {0x5348, 0x676d},
+ {0x5349, 0x7d41}, {0x534a, 0x5a62}, {0x534d, 0x5833},
+ {0x5351, 0x5d64}, {0x5352, 0x706f}, {0x5353, 0x7671},
+ {0x5354, 0x7a70}, {0x5357, 0x5175}, {0x535a, 0x5a4f},
+ {0x535c, 0x5c54}, {0x535e, 0x5c26}, {0x5360, 0x6f3f},
+ {0x5366, 0x4e4f}, {0x5368, 0x6059}, {0x536f, 0x5956},
+ {0x5370, 0x6c54}, {0x5371, 0x6a4b}, {0x5374, 0x4a3f},
+ {0x5375, 0x5530}, {0x5377, 0x4f69}, {0x537d, 0x716d},
+ {0x537f, 0x4c4f}, {0x5384, 0x6478}, {0x5393, 0x646d},
+ {0x5398, 0x5758}, {0x539a, 0x7d27}, {0x539f, 0x6a2b},
+ {0x53a0, 0x7632}, {0x53a5, 0x4f70}, {0x53a6, 0x793d},
+ {0x53ad, 0x6674}, {0x53bb, 0x4b5b}, {0x53c3, 0x7351},
+ {0x53c8, 0x6951}, {0x53c9, 0x7329}, {0x53ca, 0x5060},
+ {0x53cb, 0x6952}, {0x53cd, 0x5a63}, {0x53d4, 0x6252},
+ {0x53d6, 0x7622}, {0x53d7, 0x6174}, {0x53db, 0x5a64},
+ {0x53e1, 0x6755}, {0x53e2, 0x753f}, {0x53e3, 0x4f22},
+ {0x53e4, 0x4d2f}, {0x53e5, 0x4f23}, {0x53e9, 0x4d30},
+ {0x53ea, 0x717e}, {0x53eb, 0x5023}, {0x53ec, 0x612f},
+ {0x53ed, 0x7823}, {0x53ef, 0x4a26}, {0x53f0, 0x773b},
+ {0x53f1, 0x726a}, {0x53f2, 0x5e48}, {0x53f3, 0x6953},
+ {0x53f8, 0x5e49}, {0x5403, 0x7d5e}, {0x5404, 0x4a40},
+ {0x5408, 0x796a}, {0x5409, 0x514e}, {0x540a, 0x6e54},
+ {0x540c, 0x5452}, {0x540d, 0x5923}, {0x540e, 0x7d28},
+ {0x540f, 0x5759}, {0x5410, 0x774e}, {0x5411, 0x7a3e},
+ {0x541b, 0x4f56}, {0x541d, 0x5770}, {0x541f, 0x6b61},
+ {0x5420, 0x7845}, {0x5426, 0x5c7a}, {0x5429, 0x5d43},
+ {0x542b, 0x795f}, {0x5433, 0x676f}, {0x5438, 0x7d65},
+ {0x5439, 0x7623}, {0x543b, 0x597c}, {0x543c, 0x7d29},
+ {0x543e, 0x676e}, {0x5442, 0x5565}, {0x5448, 0x6f50},
+ {0x544a, 0x4d31}, {0x5451, 0x7722}, {0x5468, 0x7132},
+ {0x546a, 0x7131}, {0x5471, 0x4d32}, {0x5473, 0x5a2b},
+ {0x5475, 0x4a27}, {0x547b, 0x6362}, {0x547c, 0x7b3c},
+ {0x547d, 0x5924}, {0x5480, 0x6e3a}, {0x5486, 0x7853},
+ {0x548c, 0x7b7a}, {0x548e, 0x4f24}, {0x5490, 0x5c7b},
+ {0x54a4, 0x7663}, {0x54a8, 0x6d2a}, {0x54ab, 0x7221},
+ {0x54ac, 0x4e61}, {0x54b3, 0x7a26}, {0x54b8, 0x7960},
+ {0x54bd, 0x6c56}, {0x54c0, 0x646e}, {0x54c1, 0x7921},
+ {0x54c4, 0x7b6f}, {0x54c8, 0x796b}, {0x54c9, 0x6e23},
+ {0x54e1, 0x6a2c}, {0x54e5, 0x4a28}, {0x54e8, 0x747a},
+ {0x54ed, 0x4d56}, {0x54ee, 0x7c76}, {0x54f2, 0x7449},
+ {0x54fa, 0x7854}, {0x5504, 0x7826}, {0x5506, 0x5e4a},
+ {0x5507, 0x7246}, {0x550e, 0x575a}, {0x5510, 0x5350},
+ {0x551c, 0x5845}, {0x552f, 0x6a66}, {0x5531, 0x735d},
+ {0x5535, 0x645a}, {0x553e, 0x7664}, {0x5544, 0x7672},
+ {0x5546, 0x5f42}, {0x554f, 0x597d}, {0x5553, 0x4c76},
+ {0x5556, 0x533a}, {0x555e, 0x642f}, {0x5563, 0x7961},
+ {0x557c, 0x7026}, {0x5580, 0x4b53}, {0x5584, 0x603c},
+ {0x5586, 0x744a}, {0x5587, 0x547a}, {0x5589, 0x7d2a},
+ {0x558a, 0x7962}, {0x5598, 0x7437}, {0x5599, 0x7d42},
+ {0x559a, 0x7c30}, {0x559c, 0x7d6c}, {0x559d, 0x4a62},
+ {0x55a7, 0x7d3d}, {0x55a9, 0x6a67}, {0x55aa, 0x5f43},
+ {0x55ab, 0x5152}, {0x55ac, 0x4e62}, {0x55ae, 0x5324},
+ {0x55c5, 0x7d2b}, {0x55c7, 0x5f60}, {0x55d4, 0x7247},
+ {0x55da, 0x6770}, {0x55dc, 0x506e}, {0x55df, 0x732a},
+ {0x55e3, 0x5e4b}, {0x55e4, 0x7638}, {0x55fd, 0x6175},
+ {0x55fe, 0x7133}, {0x5606, 0x7723}, {0x5609, 0x4a29},
+ {0x5614, 0x4f25}, {0x5617, 0x5f44}, {0x562f, 0x6130},
+ {0x5632, 0x703f}, {0x5634, 0x7624}, {0x5636, 0x6336},
+ {0x5653, 0x7a46}, {0x5668, 0x506f}, {0x566b, 0x7d6d},
+ {0x5674, 0x5d44}, {0x5686, 0x7c77}, {0x56a5, 0x663f},
+ {0x56ac, 0x5e2d}, {0x56ae, 0x7a3f}, {0x56b4, 0x6571},
+ {0x56bc, 0x6d44}, {0x56ca, 0x5225}, {0x56cd, 0x7d6e},
+ {0x56d1, 0x7536}, {0x56da, 0x6176}, {0x56db, 0x5e4c},
+ {0x56de, 0x7c5e}, {0x56e0, 0x6c57}, {0x56f0, 0x4d5d},
+ {0x56f9, 0x5637}, {0x56fa, 0x4d33}, {0x5703, 0x7855},
+ {0x5704, 0x6558}, {0x5708, 0x4f6a}, {0x570b, 0x4f50},
+ {0x570d, 0x6a4c}, {0x5712, 0x6a2e}, {0x5713, 0x6a2d},
+ {0x5716, 0x5371}, {0x5718, 0x5325}, {0x571f, 0x774f},
+ {0x5728, 0x6e24}, {0x572d, 0x5024}, {0x5730, 0x7222},
+ {0x573b, 0x5070}, {0x5740, 0x7223}, {0x5742, 0x7778},
+ {0x5747, 0x5033}, {0x574a, 0x5b29}, {0x574d, 0x533b},
+ {0x574e, 0x4a6c}, {0x5750, 0x7126}, {0x5751, 0x4b55},
+ {0x5761, 0x7767}, {0x5764, 0x4d5e}, {0x5766, 0x7724},
+ {0x576a, 0x7840}, {0x576e, 0x535d}, {0x5770, 0x4c50},
+ {0x5775, 0x4f26}, {0x577c, 0x7673}, {0x5782, 0x6177},
+ {0x5788, 0x535c}, {0x578b, 0x7a7e}, {0x5793, 0x7a27},
+ {0x57a0, 0x6b59}, {0x57a2, 0x4f27}, {0x57a3, 0x6a2f},
+ {0x57c3, 0x646f}, {0x57c7, 0x6939}, {0x57c8, 0x7158},
+ {0x57cb, 0x5858}, {0x57ce, 0x6072}, {0x57df, 0x6634},
+ {0x57e0, 0x5c7c}, {0x57f0, 0x7371}, {0x57f4, 0x6350},
+ {0x57f7, 0x727b}, {0x57f9, 0x5b46}, {0x57fa, 0x5071},
+ {0x57fc, 0x5072}, {0x5800, 0x4f5c}, {0x5802, 0x5351},
+ {0x5805, 0x4c31}, {0x5806, 0x7758}, {0x5808, 0x4b28},
+ {0x5809, 0x6b3c}, {0x580a, 0x643e}, {0x581e, 0x745c},
+ {0x5821, 0x5c42}, {0x5824, 0x7027}, {0x5827, 0x6640},
+ {0x582a, 0x4a6d}, {0x582f, 0x686b}, {0x5830, 0x6568},
+ {0x5831, 0x5c43}, {0x5834, 0x6d5e}, {0x5835, 0x5372},
+ {0x583a, 0x4c77}, {0x584a, 0x4e54}, {0x584b, 0x672b},
+ {0x584f, 0x4b43}, {0x5851, 0x6131}, {0x5854, 0x7732},
+ {0x5857, 0x5373}, {0x5858, 0x5352}, {0x585a, 0x7540},
+ {0x585e, 0x5f5d}, {0x5861, 0x6e73}, {0x5862, 0x6771},
+ {0x5864, 0x7d34}, {0x5875, 0x7248}, {0x5879, 0x7352},
+ {0x587c, 0x6e74}, {0x587e, 0x6253}, {0x5883, 0x4c51},
+ {0x5885, 0x5f6a}, {0x5889, 0x693a}, {0x5893, 0x5957},
+ {0x589c, 0x754d}, {0x589e, 0x7172}, {0x589f, 0x7a47},
+ {0x58a8, 0x5978}, {0x58a9, 0x5442}, {0x58ae, 0x7665},
+ {0x58b3, 0x5d45}, {0x58ba, 0x6772}, {0x58bb, 0x6d5f},
+ {0x58be, 0x4a4b}, {0x58c1, 0x5b7a}, {0x58c5, 0x6835},
+ {0x58c7, 0x5326}, {0x58ce, 0x7d35}, {0x58d1, 0x7949},
+ {0x58d3, 0x6462}, {0x58d5, 0x7b3d}, {0x58d8, 0x5724},
+ {0x58d9, 0x4e45}, {0x58de, 0x4e55}, {0x58df, 0x5666},
+ {0x58e4, 0x653d}, {0x58eb, 0x5e4d}, {0x58ec, 0x6c73},
+ {0x58ef, 0x6d60}, {0x58f9, 0x6c6c}, {0x58fa, 0x7b3e},
+ {0x58fb, 0x5f6b}, {0x58fd, 0x6178}, {0x590f, 0x793e},
+ {0x5914, 0x5073}, {0x5915, 0x602a}, {0x5916, 0x6862},
+ {0x5919, 0x6254}, {0x591a, 0x527d}, {0x591c, 0x6528},
+ {0x5922, 0x5953}, {0x5927, 0x535e}, {0x5929, 0x7438},
+ {0x592a, 0x773c}, {0x592b, 0x5c7d}, {0x592d, 0x686c},
+ {0x592e, 0x6467}, {0x5931, 0x6377}, {0x5937, 0x6c28},
+ {0x593e, 0x7a71}, {0x5944, 0x6572}, {0x5947, 0x5074},
+ {0x5948, 0x522f}, {0x5949, 0x5c65}, {0x594e, 0x5025},
+ {0x594f, 0x7134}, {0x5950, 0x7c31}, {0x5951, 0x4c78},
+ {0x5954, 0x5d46}, {0x5955, 0x7a51}, {0x5957, 0x775f},
+ {0x595a, 0x7a28}, {0x5960, 0x6e75}, {0x5962, 0x5e4e},
+ {0x5967, 0x6773}, {0x596a, 0x772c}, {0x596b, 0x6b44},
+ {0x596c, 0x6d61}, {0x596d, 0x602b}, {0x596e, 0x5d47},
+ {0x5973, 0x5233}, {0x5974, 0x523f}, {0x5978, 0x4a4c},
+ {0x597d, 0x7b3f}, {0x5982, 0x657d}, {0x5983, 0x5d65},
+ {0x5984, 0x584d}, {0x598a, 0x6c74}, {0x5993, 0x5075},
+ {0x5996, 0x686d}, {0x5997, 0x5052}, {0x5999, 0x5958},
+ {0x59a5, 0x7666}, {0x59a8, 0x5b2a}, {0x59ac, 0x7760},
+ {0x59b9, 0x5859}, {0x59bb, 0x7423}, {0x59be, 0x745d},
+ {0x59c3, 0x6f51}, {0x59c6, 0x5935}, {0x59c9, 0x6d2b},
+ {0x59cb, 0x6337}, {0x59d0, 0x6e3b}, {0x59d1, 0x4d34},
+ {0x59d3, 0x6073}, {0x59d4, 0x6a4d}, {0x59d9, 0x6c75},
+ {0x59da, 0x686e}, {0x59dc, 0x4b29}, {0x59dd, 0x712f},
+ {0x59e6, 0x4a4d}, {0x59e8, 0x6c29}, {0x59ea, 0x726b},
+ {0x59ec, 0x7d6f}, {0x59ee, 0x7973}, {0x59f8, 0x6641},
+ {0x59fb, 0x6c58}, {0x59ff, 0x6d2c}, {0x5a01, 0x6a4e},
+ {0x5a03, 0x685f}, {0x5a11, 0x5e4f}, {0x5a18, 0x5226},
+ {0x5a1b, 0x6774}, {0x5a1c, 0x5156}, {0x5a1f, 0x6642},
+ {0x5a20, 0x6363}, {0x5a25, 0x6430}, {0x5a29, 0x5834},
+ {0x5a36, 0x7625}, {0x5a3c, 0x735e}, {0x5a41, 0x5725},
+ {0x5a46, 0x7768}, {0x5a49, 0x6846}, {0x5a5a, 0x7b66},
+ {0x5a62, 0x5d66}, {0x5a66, 0x5c7e}, {0x5a92, 0x585a},
+ {0x5a9a, 0x5a2c}, {0x5a9b, 0x6a30}, {0x5aa4, 0x6338},
+ {0x5ac1, 0x4a2a}, {0x5ac2, 0x6179}, {0x5ac4, 0x6a31},
+ {0x5ac9, 0x726c}, {0x5acc, 0x7a6e}, {0x5ae1, 0x6e55},
+ {0x5ae6, 0x7974}, {0x5ae9, 0x526c}, {0x5b05, 0x7b7b},
+ {0x5b09, 0x7d70}, {0x5b0b, 0x603d}, {0x5b0c, 0x4e63},
+ {0x5b16, 0x7846}, {0x5b2a, 0x5e2e}, {0x5b40, 0x5f45},
+ {0x5b43, 0x653e}, {0x5b50, 0x6d2d}, {0x5b51, 0x7a6a},
+ {0x5b54, 0x4d6e}, {0x5b55, 0x6d26}, {0x5b57, 0x6d2e},
+ {0x5b58, 0x706d}, {0x5b5a, 0x5d21}, {0x5b5c, 0x6d2f},
+ {0x5b5d, 0x7c78}, {0x5b5f, 0x586b}, {0x5b63, 0x4c79},
+ {0x5b64, 0x4d35}, {0x5b69, 0x7a29}, {0x5b6b, 0x615d},
+ {0x5b70, 0x6255}, {0x5b71, 0x6d4f}, {0x5b75, 0x5d22},
+ {0x5b78, 0x794a}, {0x5b7a, 0x6a68}, {0x5b7c, 0x656d},
+ {0x5b85, 0x536b}, {0x5b87, 0x6954}, {0x5b88, 0x617a},
+ {0x5b89, 0x644c}, {0x5b8b, 0x6164}, {0x5b8c, 0x6847},
+ {0x5b8f, 0x4e5b}, {0x5b93, 0x5c55}, {0x5b95, 0x7735},
+ {0x5b96, 0x7c73}, {0x5b97, 0x7073}, {0x5b98, 0x4e2f},
+ {0x5b99, 0x7135}, {0x5b9a, 0x6f52}, {0x5b9b, 0x6848},
+ {0x5b9c, 0x6b71}, {0x5ba2, 0x4b54}, {0x5ba3, 0x603e},
+ {0x5ba4, 0x6378}, {0x5ba5, 0x6a69}, {0x5ba6, 0x7c32},
+ {0x5bac, 0x6074}, {0x5bae, 0x4f60}, {0x5bb0, 0x6e25},
+ {0x5bb3, 0x7a2a}, {0x5bb4, 0x6643}, {0x5bb5, 0x6132},
+ {0x5bb6, 0x4a2b}, {0x5bb8, 0x6364}, {0x5bb9, 0x693b},
+ {0x5bbf, 0x6256}, {0x5bc0, 0x7372}, {0x5bc2, 0x6e56},
+ {0x5bc3, 0x6a32}, {0x5bc4, 0x5076}, {0x5bc5, 0x6c59},
+ {0x5bc6, 0x5a4b}, {0x5bc7, 0x4f28}, {0x5bcc, 0x5d23},
+ {0x5bd0, 0x585b}, {0x5bd2, 0x794e}, {0x5bd3, 0x6955},
+ {0x5bd4, 0x6351}, {0x5bd7, 0x523c}, {0x5bde, 0x582c},
+ {0x5bdf, 0x734c}, {0x5be1, 0x4d7b}, {0x5be2, 0x7656},
+ {0x5be4, 0x6775}, {0x5be5, 0x686f}, {0x5be6, 0x6379},
+ {0x5be7, 0x523b}, {0x5be8, 0x7373}, {0x5be9, 0x637b},
+ {0x5beb, 0x5e50}, {0x5bec, 0x4e30}, {0x5bee, 0x5677},
+ {0x5bef, 0x7159}, {0x5bf5, 0x7541}, {0x5bf6, 0x5c44},
+ {0x5bf8, 0x753b}, {0x5bfa, 0x5e51}, {0x5c01, 0x5c66},
+ {0x5c04, 0x5e52}, {0x5c07, 0x6d62}, {0x5c08, 0x6e76},
+ {0x5c09, 0x6a4f}, {0x5c0a, 0x706e}, {0x5c0b, 0x637c},
+ {0x5c0d, 0x535f}, {0x5c0e, 0x5374}, {0x5c0f, 0x6133},
+ {0x5c11, 0x6134}, {0x5c16, 0x7453}, {0x5c19, 0x5f46},
+ {0x5c24, 0x6956}, {0x5c28, 0x5b2b}, {0x5c31, 0x7626},
+ {0x5c38, 0x6339}, {0x5c39, 0x6b45}, {0x5c3a, 0x7429},
+ {0x5c3b, 0x4d36}, {0x5c3c, 0x5279}, {0x5c3e, 0x5a2d},
+ {0x5c3f, 0x5263}, {0x5c40, 0x4f51}, {0x5c45, 0x4b5c},
+ {0x5c46, 0x4c7a}, {0x5c48, 0x4f5d}, {0x5c4b, 0x6829},
+ {0x5c4d, 0x633b}, {0x5c4e, 0x633a}, {0x5c51, 0x605a},
+ {0x5c55, 0x6e77}, {0x5c5b, 0x5c33}, {0x5c60, 0x5375},
+ {0x5c62, 0x5726}, {0x5c64, 0x7635}, {0x5c65, 0x575b},
+ {0x5c6c, 0x6155}, {0x5c6f, 0x546a}, {0x5c71, 0x5f23},
+ {0x5c79, 0x7d5f}, {0x5c90, 0x5077}, {0x5c91, 0x6d54},
+ {0x5ca1, 0x4b2a}, {0x5ca9, 0x645b}, {0x5cab, 0x617b},
+ {0x5cac, 0x4b22}, {0x5cb1, 0x5360}, {0x5cb3, 0x643f},
+ {0x5cb5, 0x7b40}, {0x5cb7, 0x5a3e}, {0x5cb8, 0x644d},
+ {0x5cba, 0x5639}, {0x5cbe, 0x6f40}, {0x5cc0, 0x617c},
+ {0x5cd9, 0x7639}, {0x5ce0, 0x5f47}, {0x5ce8, 0x6431},
+ {0x5cef, 0x5c67}, {0x5cf0, 0x5c68}, {0x5cf4, 0x7a56},
+ {0x5cf6, 0x5376}, {0x5cfb, 0x715a}, {0x5cfd, 0x7a72},
+ {0x5d07, 0x627d}, {0x5d0d, 0x554f}, {0x5d0e, 0x5078},
+ {0x5d11, 0x4d5f}, {0x5d14, 0x754b}, {0x5d16, 0x6470},
+ {0x5d17, 0x4b2b}, {0x5d19, 0x5744}, {0x5d27, 0x627e},
+ {0x5d29, 0x5d5a}, {0x5d4b, 0x5a2e}, {0x5d4c, 0x4a6e},
+ {0x5d50, 0x5539}, {0x5d69, 0x6321}, {0x5d6c, 0x6863},
+ {0x5d6f, 0x732b}, {0x5d87, 0x4f29}, {0x5d8b, 0x5377},
+ {0x5d9d, 0x5471}, {0x5da0, 0x4e64}, {0x5da2, 0x6872},
+ {0x5daa, 0x6575}, {0x5db8, 0x672e}, {0x5dba, 0x563a},
+ {0x5dbc, 0x5f6c}, {0x5dbd, 0x6440}, {0x5dcd, 0x6864},
+ {0x5dd2, 0x5835}, {0x5dd6, 0x645c}, {0x5ddd, 0x7439},
+ {0x5dde, 0x7136}, {0x5de1, 0x625e}, {0x5de2, 0x6135},
+ {0x5de5, 0x4d6f}, {0x5de6, 0x7127}, {0x5de7, 0x4e65},
+ {0x5de8, 0x4b5d}, {0x5deb, 0x5963}, {0x5dee, 0x732c},
+ {0x5df1, 0x5079}, {0x5df2, 0x6c2b}, {0x5df3, 0x5e53},
+ {0x5df4, 0x7769}, {0x5df7, 0x7975}, {0x5dfd, 0x615e},
+ {0x5dfe, 0x4b6e}, {0x5e02, 0x633c}, {0x5e03, 0x7856},
+ {0x5e06, 0x5b6e}, {0x5e0c, 0x7d71}, {0x5e11, 0x7736},
+ {0x5e16, 0x745e}, {0x5e19, 0x726d}, {0x5e1b, 0x5b59},
+ {0x5e1d, 0x7028}, {0x5e25, 0x617d}, {0x5e2b, 0x5e54},
+ {0x5e2d, 0x602c}, {0x5e33, 0x6d63}, {0x5e36, 0x5361},
+ {0x5e38, 0x5f48}, {0x5e3d, 0x5936}, {0x5e3f, 0x7d2c},
+ {0x5e40, 0x6f53}, {0x5e44, 0x6441}, {0x5e45, 0x786b},
+ {0x5e47, 0x5b2c}, {0x5e4c, 0x7c46}, {0x5e55, 0x582d},
+ {0x5e5f, 0x763a}, {0x5e61, 0x5b5f}, {0x5e62, 0x5353},
+ {0x5e63, 0x7847}, {0x5e72, 0x4a4e}, {0x5e73, 0x7841},
+ {0x5e74, 0x5234}, {0x5e77, 0x5c34}, {0x5e78, 0x7a39},
+ {0x5e79, 0x4a4f}, {0x5e7b, 0x7c33}, {0x5e7c, 0x6a6a},
+ {0x5e7d, 0x6a6b}, {0x5e7e, 0x507a}, {0x5e84, 0x6d64},
+ {0x5e87, 0x5d67}, {0x5e8a, 0x5f49}, {0x5e8f, 0x5f6d},
+ {0x5e95, 0x6e3c}, {0x5e97, 0x6f41}, {0x5e9a, 0x4c52},
+ {0x5e9c, 0x5d24}, {0x5ea0, 0x5f4a}, {0x5ea6, 0x5378},
+ {0x5ea7, 0x7128}, {0x5eab, 0x4d37}, {0x5ead, 0x6f54},
+ {0x5eb5, 0x645d}, {0x5eb6, 0x5f6e}, {0x5eb7, 0x4b2c},
+ {0x5eb8, 0x693c}, {0x5ebe, 0x6a6c}, {0x5ec2, 0x5f4b},
+ {0x5ec8, 0x793f}, {0x5ec9, 0x562f}, {0x5eca, 0x5546},
+ {0x5ed0, 0x4f2a}, {0x5ed3, 0x4e29}, {0x5ed6, 0x5678},
+ {0x5eda, 0x7137}, {0x5edb, 0x6e78}, {0x5edf, 0x5959},
+ {0x5ee0, 0x735f}, {0x5ee2, 0x7848}, {0x5ee3, 0x4e46},
+ {0x5eec, 0x5566}, {0x5ef3, 0x7466}, {0x5ef6, 0x6645},
+ {0x5ef7, 0x6f55}, {0x5efa, 0x4b6f}, {0x5efb, 0x7c5f},
+ {0x5f01, 0x5c27}, {0x5f04, 0x5667}, {0x5f0a, 0x7849},
+ {0x5f0f, 0x6352}, {0x5f11, 0x633d}, {0x5f13, 0x4f61},
+ {0x5f14, 0x7040}, {0x5f15, 0x6c5a}, {0x5f17, 0x5d57},
+ {0x5f18, 0x7b70}, {0x5f1b, 0x6c2c}, {0x5f1f, 0x7029},
+ {0x5f26, 0x7a57}, {0x5f27, 0x7b41}, {0x5f29, 0x5240},
+ {0x5f31, 0x6530}, {0x5f35, 0x6d65}, {0x5f3a, 0x4b2d},
+ {0x5f3c, 0x7930}, {0x5f48, 0x7725}, {0x5f4a, 0x4b2e},
+ {0x5f4c, 0x5a2f}, {0x5f4e, 0x5836}, {0x5f56, 0x5327},
+ {0x5f57, 0x7b32}, {0x5f59, 0x7d44}, {0x5f5b, 0x6c2d},
+ {0x5f62, 0x7b21}, {0x5f66, 0x6569}, {0x5f67, 0x696e},
+ {0x5f69, 0x7374}, {0x5f6a, 0x7873}, {0x5f6b, 0x7041},
+ {0x5f6c, 0x5e2f}, {0x5f6d, 0x7830}, {0x5f70, 0x7360},
+ {0x5f71, 0x672f}, {0x5f77, 0x5b2d}, {0x5f79, 0x6635},
+ {0x5f7c, 0x7928}, {0x5f7f, 0x5d58}, {0x5f80, 0x6859},
+ {0x5f81, 0x6f56}, {0x5f85, 0x5362}, {0x5f87, 0x625f},
+ {0x5f8a, 0x7c60}, {0x5f8b, 0x5748}, {0x5f8c, 0x7d2d},
+ {0x5f90, 0x5f6f}, {0x5f91, 0x4c53}, {0x5f92, 0x5379},
+ {0x5f97, 0x5470}, {0x5f98, 0x5b47}, {0x5f99, 0x5e55},
+ {0x5f9e, 0x7074}, {0x5fa0, 0x5550}, {0x5fa1, 0x6559},
+ {0x5fa8, 0x7c47}, {0x5fa9, 0x5c56}, {0x5faa, 0x6260},
+ {0x5fae, 0x5a30}, {0x5fb5, 0x7323}, {0x5fb7, 0x536c},
+ {0x5fb9, 0x744b}, {0x5fbd, 0x7d45}, {0x5fc3, 0x637d},
+ {0x5fc5, 0x7931}, {0x5fcc, 0x507b}, {0x5fcd, 0x6c5b},
+ {0x5fd6, 0x753c}, {0x5fd7, 0x7224}, {0x5fd8, 0x584e},
+ {0x5fd9, 0x584f}, {0x5fe0, 0x7577}, {0x5feb, 0x7661},
+ {0x5ff5, 0x5237}, {0x5ffd, 0x7b6c}, {0x5fff, 0x5d48},
+ {0x600f, 0x6468}, {0x6012, 0x5241}, {0x6016, 0x7857},
+ {0x601c, 0x563b}, {0x601d, 0x5e56}, {0x6020, 0x773d},
+ {0x6021, 0x6c2e}, {0x6025, 0x5061}, {0x6027, 0x6075},
+ {0x6028, 0x6a33}, {0x602a, 0x4e56}, {0x602f, 0x4c25},
+ {0x6041, 0x6c76}, {0x6042, 0x6261}, {0x6043, 0x633e},
+ {0x604d, 0x7c48}, {0x6050, 0x4d70}, {0x6052, 0x7976},
+ {0x6055, 0x5f70}, {0x6059, 0x653f}, {0x605d, 0x4e3f},
+ {0x6062, 0x7c61}, {0x6063, 0x6d30}, {0x6064, 0x7d51},
+ {0x6065, 0x763b}, {0x6068, 0x794f}, {0x6069, 0x6b5a},
+ {0x606a, 0x4a41}, {0x606c, 0x5238}, {0x606d, 0x4d71},
+ {0x606f, 0x6353}, {0x6070, 0x7d66}, {0x6085, 0x666d},
+ {0x6089, 0x637a}, {0x608c, 0x702a}, {0x608d, 0x7950},
+ {0x6094, 0x7c62}, {0x6096, 0x7827}, {0x609a, 0x6165},
+ {0x609b, 0x6e79}, {0x609f, 0x6776}, {0x60a0, 0x6a6d},
+ {0x60a3, 0x7c34}, {0x60a4, 0x7542}, {0x60a7, 0x575c},
+ {0x60b0, 0x7075}, {0x60b2, 0x5d68}, {0x60b3, 0x536d},
+ {0x60b4, 0x757c}, {0x60b6, 0x5a3f}, {0x60b8, 0x4c7b},
+ {0x60bc, 0x537a}, {0x60bd, 0x7424}, {0x60c5, 0x6f57},
+ {0x60c7, 0x5443}, {0x60d1, 0x7b63}, {0x60da, 0x7b6d},
+ {0x60dc, 0x602d}, {0x60df, 0x6a6e}, {0x60e0, 0x7b33},
+ {0x60e1, 0x6442}, {0x60f0, 0x7667}, {0x60f1, 0x525d},
+ {0x60f3, 0x5f4c}, {0x60f6, 0x7c49}, {0x60f9, 0x6529},
+ {0x60fa, 0x6076}, {0x60fb, 0x7633}, {0x6101, 0x617e},
+ {0x6106, 0x4b70}, {0x6108, 0x6a6f}, {0x6109, 0x6a70},
+ {0x610d, 0x5a40}, {0x610e, 0x7834}, {0x610f, 0x6b72},
+ {0x6115, 0x6443}, {0x611a, 0x6957}, {0x611b, 0x6471},
+ {0x611f, 0x4a6f}, {0x6127, 0x4e57}, {0x6130, 0x7c4a},
+ {0x6134, 0x7361}, {0x6137, 0x4b44}, {0x613c, 0x6365},
+ {0x613e, 0x4b45}, {0x613f, 0x6a34}, {0x6142, 0x693d},
+ {0x6144, 0x5749}, {0x6147, 0x6b5b}, {0x6148, 0x6d31},
+ {0x614a, 0x4c43}, {0x614b, 0x773e}, {0x614c, 0x7c4b},
+ {0x6153, 0x7874}, {0x6155, 0x5937}, {0x6158, 0x7353},
+ {0x6159, 0x7354}, {0x615d, 0x7764}, {0x615f, 0x7751},
+ {0x6162, 0x5837}, {0x6163, 0x4e31}, {0x6164, 0x4a42},
+ {0x6167, 0x7b34}, {0x6168, 0x4b46}, {0x616b, 0x7076},
+ {0x616e, 0x5567}, {0x6170, 0x6a50}, {0x6176, 0x4c54},
+ {0x6177, 0x4b2f}, {0x617d, 0x742a}, {0x617e, 0x692f},
+ {0x6181, 0x7543}, {0x6182, 0x6958}, {0x618a, 0x5d69},
+ {0x618e, 0x7173}, {0x6190, 0x557b}, {0x6191, 0x5e3b},
+ {0x6194, 0x747b}, {0x6198, 0x7d73}, {0x6199, 0x7d72},
+ {0x619a, 0x7726}, {0x61a4, 0x5d49}, {0x61a7, 0x5453},
+ {0x61a9, 0x4c28}, {0x61ab, 0x5a41}, {0x61ac, 0x4c55},
+ {0x61ae, 0x5964}, {0x61b2, 0x7a4a}, {0x61b6, 0x6563},
+ {0x61ba, 0x533c}, {0x61be, 0x4a70}, {0x61c3, 0x5044},
+ {0x61c7, 0x4a50}, {0x61c8, 0x7a2b}, {0x61c9, 0x6b6b},
+ {0x61ca, 0x6778}, {0x61cb, 0x5965}, {0x61e6, 0x5157},
+ {0x61f2, 0x7324}, {0x61f6, 0x547b}, {0x61f7, 0x7c63},
+ {0x61f8, 0x7a58}, {0x61fa, 0x7355}, {0x61fc, 0x4f2b},
+ {0x61ff, 0x6b73}, {0x6200, 0x557c}, {0x6207, 0x5354},
+ {0x6208, 0x4d7c}, {0x620a, 0x5966}, {0x620c, 0x6279},
+ {0x620d, 0x6221}, {0x620e, 0x6b54}, {0x6210, 0x6077},
+ {0x6211, 0x6432}, {0x6212, 0x4c7c}, {0x6216, 0x7b64},
+ {0x621a, 0x742b}, {0x621f, 0x503d}, {0x6221, 0x4a71},
+ {0x622a, 0x6f38}, {0x622e, 0x5740}, {0x6230, 0x6e7a},
+ {0x6231, 0x7d74}, {0x6234, 0x5363}, {0x6236, 0x7b42},
+ {0x623e, 0x5568}, {0x623f, 0x5b2e}, {0x6240, 0x6136},
+ {0x6241, 0x7837}, {0x6247, 0x603f}, {0x6248, 0x7b43},
+ {0x6249, 0x5d6a}, {0x624b, 0x6222}, {0x624d, 0x6e26},
+ {0x6253, 0x7668}, {0x6258, 0x7675}, {0x626e, 0x5d4a},
+ {0x6271, 0x5062}, {0x6276, 0x5d26}, {0x6279, 0x5d6b},
+ {0x627c, 0x6479}, {0x627f, 0x632f}, {0x6280, 0x507c},
+ {0x6284, 0x747c}, {0x6289, 0x4c3c}, {0x628a, 0x776a},
+ {0x6291, 0x6564}, {0x6292, 0x5f71}, {0x6295, 0x7761},
+ {0x6297, 0x7977}, {0x6298, 0x6f39}, {0x629b, 0x7858},
+ {0x62ab, 0x7929}, {0x62b1, 0x7859}, {0x62b5, 0x6e3d},
+ {0x62b9, 0x5846}, {0x62bc, 0x6463}, {0x62bd, 0x754e},
+ {0x62c2, 0x5d59}, {0x62c7, 0x5967}, {0x62c8, 0x5239},
+ {0x62c9, 0x5543}, {0x62cc, 0x5a65}, {0x62cd, 0x5a50},
+ {0x62cf, 0x5159}, {0x62d0, 0x4e58}, {0x62d2, 0x4b5e},
+ {0x62d3, 0x742c}, {0x62d4, 0x5a7b}, {0x62d6, 0x7669},
+ {0x62d7, 0x6873}, {0x62d8, 0x4f2c}, {0x62d9, 0x7070},
+ {0x62db, 0x747d}, {0x62dc, 0x5b48}, {0x62ec, 0x4e40},
+ {0x62ed, 0x6354}, {0x62ee, 0x514f}, {0x62ef, 0x7175},
+ {0x62f1, 0x4d72}, {0x62f3, 0x4f6b}, {0x62f7, 0x4d38},
+ {0x62fe, 0x6326}, {0x62ff, 0x515a}, {0x6301, 0x7225},
+ {0x6307, 0x7226}, {0x6309, 0x644e}, {0x6311, 0x537b},
+ {0x632b, 0x7129}, {0x632f, 0x7249}, {0x633a, 0x6f58},
+ {0x633b, 0x6649}, {0x633d, 0x5838}, {0x633e, 0x7a73},
+ {0x6349, 0x7335}, {0x634c, 0x7824}, {0x634f, 0x5173},
+ {0x6350, 0x6648}, {0x6355, 0x785a}, {0x6367, 0x5c69},
+ {0x6368, 0x5e57}, {0x636e, 0x4b5f}, {0x6372, 0x4f6c},
+ {0x6377, 0x745f}, {0x637a, 0x5174}, {0x637b, 0x523a},
+ {0x637f, 0x5f72}, {0x6383, 0x6137}, {0x6388, 0x6223},
+ {0x6389, 0x537c}, {0x638c, 0x6d66}, {0x6392, 0x5b49},
+ {0x6396, 0x647a}, {0x6398, 0x4f5e}, {0x639b, 0x4e50},
+ {0x63a0, 0x5553}, {0x63a1, 0x7375}, {0x63a2, 0x772e},
+ {0x63a5, 0x6f48}, {0x63a7, 0x4d73}, {0x63a8, 0x754f},
+ {0x63a9, 0x6573}, {0x63aa, 0x7042}, {0x63c0, 0x4a51},
+ {0x63c4, 0x6a71}, {0x63c6, 0x5026}, {0x63cf, 0x595a},
+ {0x63d0, 0x702b}, {0x63d6, 0x6b67}, {0x63da, 0x6540},
+ {0x63db, 0x7c35}, {0x63e1, 0x6444}, {0x63ed, 0x4c29},
+ {0x63ee, 0x7d46}, {0x63f4, 0x6a35}, {0x63f6, 0x652a},
+ {0x63f7, 0x5f3a}, {0x640d, 0x615f}, {0x640f, 0x5a51},
+ {0x6414, 0x6138}, {0x6416, 0x6874}, {0x6417, 0x537d},
+ {0x641c, 0x6224}, {0x6422, 0x724a}, {0x642c, 0x5a66},
+ {0x642d, 0x7733}, {0x643a, 0x7d4d}, {0x643e, 0x7336},
+ {0x6458, 0x6e57}, {0x6460, 0x7544}, {0x6469, 0x5824},
+ {0x646f, 0x7227}, {0x6478, 0x5938}, {0x6479, 0x5939},
+ {0x647a, 0x6f49}, {0x6488, 0x564e}, {0x6491, 0x774b},
+ {0x6492, 0x5f2e}, {0x6493, 0x6875}, {0x649a, 0x5235},
+ {0x649e, 0x5355}, {0x64a4, 0x744c}, {0x64a5, 0x5a7c},
+ {0x64ab, 0x5968}, {0x64ad, 0x776b}, {0x64ae, 0x7549},
+ {0x64b0, 0x733c}, {0x64b2, 0x5a52}, {0x64bb, 0x5335},
+ {0x64c1, 0x6836}, {0x64c4, 0x564f}, {0x64c5, 0x743a},
+ {0x64c7, 0x7749}, {0x64ca, 0x4c2a}, {0x64cd, 0x7043},
+ {0x64ce, 0x4c56}, {0x64d2, 0x5053}, {0x64d4, 0x533d},
+ {0x64d8, 0x5b7b}, {0x64da, 0x4b60}, {0x64e1, 0x5364},
+ {0x64e2, 0x7677}, {0x64e5, 0x553a}, {0x64e6, 0x734d},
+ {0x64e7, 0x4b61}, {0x64ec, 0x6b74}, {0x64f2, 0x742d},
+ {0x64f4, 0x7c2a}, {0x64fa, 0x776c}, {0x64fe, 0x6876},
+ {0x6500, 0x5a67}, {0x6504, 0x774c}, {0x6518, 0x6541},
+ {0x651d, 0x606e}, {0x6523, 0x557d}, {0x652a, 0x4e66},
+ {0x652b, 0x7c2b}, {0x652c, 0x553b}, {0x652f, 0x7228},
+ {0x6536, 0x6225}, {0x6537, 0x4d39}, {0x6538, 0x6a72},
+ {0x6539, 0x4b47}, {0x653b, 0x4d74}, {0x653e, 0x5b2f},
+ {0x653f, 0x6f59}, {0x6545, 0x4d3a}, {0x6548, 0x7c79},
+ {0x654d, 0x5f73}, {0x654e, 0x4e67}, {0x654f, 0x5a42},
+ {0x6551, 0x4f2d}, {0x6556, 0x6779}, {0x6557, 0x7828},
+ {0x655e, 0x7362}, {0x6562, 0x4a72}, {0x6563, 0x5f24},
+ {0x6566, 0x5444}, {0x656c, 0x4c57}, {0x656d, 0x6542},
+ {0x6572, 0x4d3b}, {0x6574, 0x6f5a}, {0x6575, 0x6e58},
+ {0x6577, 0x5d27}, {0x6578, 0x6226}, {0x657e, 0x6040},
+ {0x6582, 0x5630}, {0x6583, 0x784a}, {0x6585, 0x7c7a},
+ {0x6587, 0x597e}, {0x658c, 0x5e30}, {0x6590, 0x5d6c},
+ {0x6591, 0x5a68}, {0x6597, 0x5460}, {0x6599, 0x5679},
+ {0x659b, 0x4d57}, {0x659c, 0x5e58}, {0x659f, 0x7278},
+ {0x65a1, 0x6456}, {0x65a4, 0x5045}, {0x65a5, 0x742e},
+ {0x65a7, 0x5d28}, {0x65ab, 0x6d45}, {0x65ac, 0x7356},
+ {0x65af, 0x5e59}, {0x65b0, 0x6366}, {0x65b7, 0x5328},
+ {0x65b9, 0x5b30}, {0x65bc, 0x655a}, {0x65bd, 0x633f},
+ {0x65c1, 0x5b31}, {0x65c5, 0x5569}, {0x65cb, 0x6041},
+ {0x65cc, 0x6f5b}, {0x65cf, 0x7069}, {0x65d2, 0x5732},
+ {0x65d7, 0x507d}, {0x65e0, 0x5969}, {0x65e3, 0x507e},
+ {0x65e5, 0x6c6d}, {0x65e6, 0x5329}, {0x65e8, 0x7229},
+ {0x65e9, 0x7044}, {0x65ec, 0x6262}, {0x65ed, 0x696f},
+ {0x65f1, 0x7951}, {0x65f4, 0x6959}, {0x65fa, 0x685a},
+ {0x65fb, 0x5a43}, {0x65fc, 0x5a44}, {0x65fd, 0x5445},
+ {0x65ff, 0x677a}, {0x6606, 0x4d60}, {0x6607, 0x6330},
+ {0x6609, 0x5b32}, {0x660a, 0x7b44}, {0x660c, 0x7363},
+ {0x660e, 0x5925}, {0x660f, 0x7b67}, {0x6610, 0x5d4b},
+ {0x6611, 0x5054}, {0x6613, 0x6636}, {0x6614, 0x602e},
+ {0x6615, 0x7d5a}, {0x661e, 0x5c35}, {0x661f, 0x6078},
+ {0x6620, 0x6731}, {0x6625, 0x7570}, {0x6627, 0x585c},
+ {0x6628, 0x6d46}, {0x662d, 0x6139}, {0x662f, 0x6340},
+ {0x6630, 0x7940}, {0x6631, 0x6970}, {0x6634, 0x595b},
+ {0x6636, 0x7364}, {0x663a, 0x5c36}, {0x663b, 0x6469},
+ {0x6641, 0x7045}, {0x6642, 0x6341}, {0x6643, 0x7c4c},
+ {0x6644, 0x7c4d}, {0x6649, 0x724b}, {0x664b, 0x724c},
+ {0x664f, 0x644f}, {0x6659, 0x715b}, {0x665b, 0x7a59},
+ {0x665d, 0x7138}, {0x665e, 0x7d75}, {0x665f, 0x6079},
+ {0x6664, 0x677b}, {0x6665, 0x7c37}, {0x6666, 0x7c64},
+ {0x6667, 0x7b45}, {0x6668, 0x6367}, {0x6669, 0x5839},
+ {0x666b, 0x7678}, {0x666e, 0x5c45}, {0x666f, 0x4c58},
+ {0x6673, 0x602f}, {0x6674, 0x7467}, {0x6676, 0x6f5c},
+ {0x6677, 0x4f7c}, {0x6678, 0x6f5d}, {0x667a, 0x722a},
+ {0x6684, 0x7d3e}, {0x6687, 0x4a2c}, {0x6688, 0x7d3b},
+ {0x6689, 0x7d47}, {0x668e, 0x6732}, {0x6690, 0x6a51},
+ {0x6691, 0x5f74}, {0x6696, 0x516c}, {0x6697, 0x645e},
+ {0x6698, 0x6543}, {0x669d, 0x5926}, {0x66a0, 0x4d3c},
+ {0x66a2, 0x7365}, {0x66ab, 0x6d55}, {0x66ae, 0x593a},
+ {0x66b2, 0x6d67}, {0x66b3, 0x7b35}, {0x66b4, 0x786c},
+ {0x66b9, 0x6067}, {0x66bb, 0x4c59}, {0x66be, 0x5446},
+ {0x66c4, 0x6725}, {0x66c6, 0x5575}, {0x66c7, 0x533e},
+ {0x66c9, 0x7c7b}, {0x66d6, 0x6472}, {0x66d9, 0x5f75},
+ {0x66dc, 0x6878}, {0x66dd, 0x786d}, {0x66e0, 0x4e47},
+ {0x66e6, 0x7d76}, {0x66f0, 0x6858}, {0x66f2, 0x4d58},
+ {0x66f3, 0x6756}, {0x66f4, 0x4c5a}, {0x66f7, 0x4a63},
+ {0x66f8, 0x5f76}, {0x66f9, 0x7047}, {0x66fa, 0x7046},
+ {0x66fc, 0x583a}, {0x66fe, 0x7174}, {0x66ff, 0x7470},
+ {0x6700, 0x754c}, {0x6703, 0x7c65}, {0x6708, 0x6a45},
+ {0x6709, 0x6a73}, {0x670b, 0x5d5b}, {0x670d, 0x5c57},
+ {0x6714, 0x5e7d}, {0x6715, 0x7279}, {0x6717, 0x5547},
+ {0x671b, 0x5850}, {0x671d, 0x7048}, {0x671e, 0x5121},
+ {0x671f, 0x5122}, {0x6726, 0x5954}, {0x6727, 0x5668},
+ {0x6728, 0x594a}, {0x672a, 0x5a31}, {0x672b, 0x5847},
+ {0x672c, 0x5c62}, {0x672d, 0x734e}, {0x672e, 0x7574},
+ {0x6731, 0x7139}, {0x6734, 0x5a53}, {0x6736, 0x766a},
+ {0x673a, 0x4f75}, {0x673d, 0x7d2e}, {0x6746, 0x4a52},
+ {0x6749, 0x5f34}, {0x674e, 0x575d}, {0x674f, 0x7a3a},
+ {0x6750, 0x6e27}, {0x6751, 0x753d}, {0x6753, 0x7875},
+ {0x6756, 0x6d68}, {0x675c, 0x5461}, {0x675e, 0x5123},
+ {0x675f, 0x6156}, {0x676d, 0x7978}, {0x676f, 0x5b4a},
+ {0x6770, 0x4b79}, {0x6771, 0x5454}, {0x6773, 0x595c},
+ {0x6775, 0x6e3e}, {0x6777, 0x776d}, {0x677b, 0x526e},
+ {0x677e, 0x6166}, {0x677f, 0x7779}, {0x6787, 0x5d6d},
+ {0x6789, 0x685b}, {0x678b, 0x5b33}, {0x678f, 0x5177},
+ {0x6790, 0x6030}, {0x6793, 0x5462}, {0x6795, 0x7657},
+ {0x6797, 0x5779}, {0x679a, 0x585d}, {0x679c, 0x4d7d},
+ {0x679d, 0x722b}, {0x67af, 0x4d3d}, {0x67b0, 0x7842},
+ {0x67b3, 0x722c}, {0x67b6, 0x4a2d}, {0x67b7, 0x4a2e},
+ {0x67b8, 0x4f2e}, {0x67be, 0x6342}, {0x67c4, 0x5c37},
+ {0x67cf, 0x5b5a}, {0x67d0, 0x593b}, {0x67d1, 0x4a73},
+ {0x67d2, 0x7653}, {0x67d3, 0x6678}, {0x67d4, 0x6a75},
+ {0x67da, 0x6a76}, {0x67dd, 0x7679}, {0x67e9, 0x4f2f},
+ {0x67ec, 0x4a53}, {0x67ef, 0x4a2f}, {0x67f0, 0x5230},
+ {0x67f1, 0x713a}, {0x67f3, 0x5733}, {0x67f4, 0x6343},
+ {0x67f5, 0x737d}, {0x67f6, 0x5e5a}, {0x67fb, 0x5e5b},
+ {0x67fe, 0x6f5e}, {0x6812, 0x6263}, {0x6813, 0x6e7b},
+ {0x6816, 0x5f77}, {0x6817, 0x574a}, {0x6821, 0x4e68},
+ {0x6822, 0x5b5b}, {0x682a, 0x713b}, {0x682f, 0x6971},
+ {0x6838, 0x7a37}, {0x6839, 0x5046}, {0x683c, 0x4c2b},
+ {0x683d, 0x6e28}, {0x6840, 0x4b7a}, {0x6841, 0x7979},
+ {0x6842, 0x4c7d}, {0x6843, 0x537e}, {0x6848, 0x6450},
+ {0x684e, 0x726e}, {0x6850, 0x5455}, {0x6851, 0x5f4d},
+ {0x6853, 0x7c38}, {0x6854, 0x5150}, {0x686d, 0x724d},
+ {0x6876, 0x7752}, {0x687f, 0x4a54}, {0x6881, 0x5559},
+ {0x6885, 0x585e}, {0x688f, 0x4d59}, {0x6893, 0x6e29},
+ {0x6894, 0x763c}, {0x6897, 0x4c5b}, {0x689d, 0x7049},
+ {0x689f, 0x7c7c}, {0x68a1, 0x6849}, {0x68a2, 0x747e},
+ {0x68a7, 0x677c}, {0x68a8, 0x575e}, {0x68ad, 0x5e5c},
+ {0x68af, 0x702c}, {0x68b0, 0x4c7e}, {0x68b1, 0x4d61},
+ {0x68b3, 0x613a}, {0x68b5, 0x5b6f}, {0x68b6, 0x5a32},
+ {0x68c4, 0x5125}, {0x68c5, 0x5c38}, {0x68c9, 0x5876},
+ {0x68cb, 0x5124}, {0x68cd, 0x4d62}, {0x68d2, 0x5c6a},
+ {0x68d5, 0x7077}, {0x68d7, 0x704a}, {0x68d8, 0x503e},
+ {0x68da, 0x5d5c}, {0x68df, 0x5456}, {0x68e0, 0x5356},
+ {0x68e7, 0x6d50}, {0x68e8, 0x4d21}, {0x68ee, 0x5f35},
+ {0x68f2, 0x5f78}, {0x68f9, 0x5421}, {0x68fa, 0x4e32},
+ {0x6900, 0x684a}, {0x6905, 0x6b75}, {0x690d, 0x6355},
+ {0x690e, 0x7550}, {0x6912, 0x7521}, {0x6927, 0x5927},
+ {0x6930, 0x652b}, {0x693d, 0x664b}, {0x693f, 0x7571},
+ {0x694a, 0x6545}, {0x6953, 0x7923}, {0x6954, 0x605b},
+ {0x6955, 0x766b}, {0x6957, 0x4b71}, {0x6959, 0x596a},
+ {0x695a, 0x7522}, {0x695e, 0x5751}, {0x6960, 0x5178},
+ {0x6961, 0x6a78}, {0x6962, 0x6a79}, {0x6963, 0x5a33},
+ {0x6968, 0x6f5f}, {0x696b, 0x716f}, {0x696d, 0x6576},
+ {0x696e, 0x6e3f}, {0x696f, 0x6264}, {0x6975, 0x503f},
+ {0x6977, 0x7a2c}, {0x6978, 0x7551}, {0x6979, 0x6733},
+ {0x6995, 0x693e}, {0x699b, 0x724e}, {0x699c, 0x5b34},
+ {0x69a5, 0x7c4e}, {0x69a7, 0x5d6e}, {0x69ae, 0x6734},
+ {0x69b4, 0x5734}, {0x69bb, 0x7734}, {0x69c1, 0x4d3e},
+ {0x69c3, 0x5a69}, {0x69cb, 0x4f30}, {0x69cc, 0x7759},
+ {0x69cd, 0x7366}, {0x69d0, 0x4e59}, {0x69e8, 0x4e2a},
+ {0x69ea, 0x4b48}, {0x69fb, 0x5027}, {0x69fd, 0x704b},
+ {0x69ff, 0x5047}, {0x6a02, 0x6445}, {0x6a0a, 0x5b60},
+ {0x6a11, 0x555a}, {0x6a13, 0x5727}, {0x6a17, 0x6e40},
+ {0x6a19, 0x7876}, {0x6a1e, 0x7552}, {0x6a1f, 0x6d69},
+ {0x6a21, 0x593c}, {0x6a23, 0x6546}, {0x6a35, 0x7523},
+ {0x6a38, 0x5a54}, {0x6a39, 0x6227}, {0x6a3a, 0x7b7c},
+ {0x6a3d, 0x715c}, {0x6a44, 0x4a74}, {0x6a48, 0x687a},
+ {0x6a4b, 0x4e69}, {0x6a52, 0x6978}, {0x6a53, 0x6265},
+ {0x6a58, 0x5039}, {0x6a59, 0x5472}, {0x6a5f, 0x5126},
+ {0x6a61, 0x5f4e}, {0x6a6b, 0x7c74}, {0x6a80, 0x532a},
+ {0x6a84, 0x4c2c}, {0x6a89, 0x6f60}, {0x6a8d, 0x6565},
+ {0x6a8e, 0x5055}, {0x6a97, 0x5b7c}, {0x6a9c, 0x7c66},
+ {0x6aa2, 0x4b7e}, {0x6aa3, 0x6d6a}, {0x6ab3, 0x5e31},
+ {0x6abb, 0x7963}, {0x6ac2, 0x5422}, {0x6ac3, 0x4f76},
+ {0x6ad3, 0x5650}, {0x6ada, 0x556a}, {0x6adb, 0x716e},
+ {0x6af6, 0x7a4b}, {0x6afb, 0x6521}, {0x6b04, 0x5531},
+ {0x6b0a, 0x4f6d}, {0x6b0c, 0x6d6b}, {0x6b12, 0x5532},
+ {0x6b16, 0x553c}, {0x6b20, 0x7d62}, {0x6b21, 0x732d},
+ {0x6b23, 0x7d5b}, {0x6b32, 0x6930}, {0x6b3a, 0x5127},
+ {0x6b3d, 0x7d63}, {0x6b3e, 0x4e33}, {0x6b46, 0x7d64},
+ {0x6b47, 0x7a4e}, {0x6b4c, 0x4a30}, {0x6b4e, 0x7727},
+ {0x6b50, 0x4f31}, {0x6b5f, 0x6622}, {0x6b61, 0x7c36},
+ {0x6b62, 0x722d}, {0x6b63, 0x6f61}, {0x6b64, 0x732e},
+ {0x6b65, 0x5c46}, {0x6b66, 0x596b}, {0x6b6a, 0x6860},
+ {0x6b72, 0x6128}, {0x6b77, 0x5576}, {0x6b78, 0x4f7d},
+ {0x6b7b, 0x5e5d}, {0x6b7f, 0x5951}, {0x6b83, 0x646a},
+ {0x6b84, 0x724f}, {0x6b86, 0x773f}, {0x6b89, 0x6266},
+ {0x6b8a, 0x6228}, {0x6b96, 0x6356}, {0x6b98, 0x6d51},
+ {0x6b9e, 0x6979}, {0x6bae, 0x5631}, {0x6baf, 0x5e32},
+ {0x6bb2, 0x6068}, {0x6bb5, 0x532b}, {0x6bb7, 0x6b5c},
+ {0x6bba, 0x5f2f}, {0x6bbc, 0x4a43}, {0x6bbf, 0x6e7c},
+ {0x6bc1, 0x7d43}, {0x6bc5, 0x6b76}, {0x6bc6, 0x4f32},
+ {0x6bcb, 0x596c}, {0x6bcd, 0x593d}, {0x6bcf, 0x585f},
+ {0x6bd2, 0x5438}, {0x6bd3, 0x6b3e}, {0x6bd4, 0x5d6f},
+ {0x6bd6, 0x5d70}, {0x6bd7, 0x5d71}, {0x6bd8, 0x5d72},
+ {0x6bdb, 0x593e}, {0x6beb, 0x7b46}, {0x6bec, 0x4f33},
+ {0x6c08, 0x6e7d}, {0x6c0f, 0x642b}, {0x6c11, 0x5a45},
+ {0x6c13, 0x586c}, {0x6c23, 0x5128}, {0x6c34, 0x6229},
+ {0x6c37, 0x5e3c}, {0x6c38, 0x6735}, {0x6c3e, 0x5b70},
+ {0x6c40, 0x6f62}, {0x6c41, 0x7170}, {0x6c42, 0x4f34},
+ {0x6c4e, 0x5b71}, {0x6c50, 0x6031}, {0x6c55, 0x5f25},
+ {0x6c57, 0x7952}, {0x6c5a, 0x677d}, {0x6c5d, 0x6623},
+ {0x6c5e, 0x7b71}, {0x6c5f, 0x4b30}, {0x6c60, 0x722e},
+ {0x6c68, 0x4d67}, {0x6c6a, 0x685c}, {0x6c6d, 0x6757},
+ {0x6c70, 0x7740}, {0x6c72, 0x5063}, {0x6c76, 0x5a21},
+ {0x6c7a, 0x4c3d}, {0x6c7d, 0x5129}, {0x6c7e, 0x5d4c},
+ {0x6c81, 0x637e}, {0x6c82, 0x512a}, {0x6c83, 0x682a},
+ {0x6c85, 0x6a36}, {0x6c86, 0x797a}, {0x6c87, 0x664c},
+ {0x6c88, 0x7658}, {0x6c8c, 0x5447}, {0x6c90, 0x594b},
+ {0x6c92, 0x5952}, {0x6c93, 0x534b}, {0x6c94, 0x5877},
+ {0x6c95, 0x5a29}, {0x6c96, 0x7578}, {0x6c99, 0x5e5e},
+ {0x6c9a, 0x722f}, {0x6c9b, 0x7829}, {0x6cab, 0x5848},
+ {0x6cae, 0x6e41}, {0x6cb3, 0x7941}, {0x6cb8, 0x5d73},
+ {0x6cb9, 0x6a7a}, {0x6cbb, 0x763d}, {0x6cbc, 0x613b},
+ {0x6cbd, 0x4d3f}, {0x6cbe, 0x7454}, {0x6cbf, 0x664d},
+ {0x6cc1, 0x7c4f}, {0x6cc2, 0x7b22}, {0x6cc4, 0x605c},
+ {0x6cc9, 0x743b}, {0x6cca, 0x5a55}, {0x6ccc, 0x7932},
+ {0x6cd3, 0x7b72}, {0x6cd5, 0x5b76}, {0x6cd7, 0x5e5f},
+ {0x6cdb, 0x5b72}, {0x6ce1, 0x785c}, {0x6ce2, 0x776e},
+ {0x6ce3, 0x6b68}, {0x6ce5, 0x527a}, {0x6ce8, 0x713c},
+ {0x6ceb, 0x7a5a}, {0x6cee, 0x5a6a}, {0x6cef, 0x5a46},
+ {0x6cf0, 0x7741}, {0x6cf3, 0x6736}, {0x6d0b, 0x6547},
+ {0x6d0c, 0x562c}, {0x6d11, 0x5c47}, {0x6d17, 0x6129},
+ {0x6d19, 0x622a}, {0x6d1b, 0x5526}, {0x6d1e, 0x5457},
+ {0x6d25, 0x7250}, {0x6d27, 0x6a7b}, {0x6d29, 0x605d},
+ {0x6d2a, 0x7b73}, {0x6d32, 0x713d}, {0x6d35, 0x6267},
+ {0x6d36, 0x7d57}, {0x6d38, 0x4e48}, {0x6d39, 0x6a37},
+ {0x6d3b, 0x7c40}, {0x6d3d, 0x7d67}, {0x6d3e, 0x776f},
+ {0x6d41, 0x5735}, {0x6d59, 0x6f3a}, {0x6d5a, 0x715d},
+ {0x6d5c, 0x5e33}, {0x6d63, 0x684b}, {0x6d66, 0x785d},
+ {0x6d69, 0x7b47}, {0x6d6a, 0x5548}, {0x6d6c, 0x575f},
+ {0x6d6e, 0x5d29}, {0x6d74, 0x6931}, {0x6d77, 0x7a2d},
+ {0x6d78, 0x7659}, {0x6d79, 0x7a74}, {0x6d7f, 0x782a},
+ {0x6d85, 0x666e}, {0x6d87, 0x4c5c}, {0x6d88, 0x613c},
+ {0x6d89, 0x606f}, {0x6d8c, 0x693f}, {0x6d8d, 0x7c7d},
+ {0x6d8e, 0x664e}, {0x6d91, 0x6157}, {0x6d93, 0x664f},
+ {0x6d95, 0x7471}, {0x6daf, 0x6473}, {0x6db2, 0x647b},
+ {0x6db5, 0x7964}, {0x6dc0, 0x6f63}, {0x6dc3, 0x4f6e},
+ {0x6dc4, 0x763e}, {0x6dc5, 0x6032}, {0x6dc6, 0x7c7e},
+ {0x6dc7, 0x512b}, {0x6dcb, 0x577a}, {0x6dcf, 0x7b48},
+ {0x6dd1, 0x6257}, {0x6dd8, 0x5423}, {0x6dd9, 0x7078},
+ {0x6dda, 0x5728}, {0x6dde, 0x6167}, {0x6de1, 0x533f},
+ {0x6de8, 0x6f64}, {0x6dea, 0x5745}, {0x6deb, 0x6b62},
+ {0x6dee, 0x7c67}, {0x6df1, 0x6422}, {0x6df3, 0x6268},
+ {0x6df5, 0x6650}, {0x6df7, 0x7b68}, {0x6df8, 0x7468},
+ {0x6df9, 0x6574}, {0x6dfa, 0x743c}, {0x6dfb, 0x7455},
+ {0x6e17, 0x5f36}, {0x6e19, 0x7c39}, {0x6e1a, 0x6e42},
+ {0x6e1b, 0x4a75}, {0x6e1f, 0x6f65}, {0x6e20, 0x4b62},
+ {0x6e21, 0x5424}, {0x6e23, 0x5e60}, {0x6e24, 0x5a7d},
+ {0x6e25, 0x6446}, {0x6e26, 0x683e}, {0x6e2b, 0x605e},
+ {0x6e2c, 0x7634}, {0x6e2d, 0x6a52}, {0x6e2f, 0x797b},
+ {0x6e32, 0x6042}, {0x6e34, 0x4a64}, {0x6e36, 0x6737},
+ {0x6e38, 0x6a7d}, {0x6e3a, 0x595d}, {0x6e3c, 0x5a34},
+ {0x6e3d, 0x6e2a}, {0x6e3e, 0x7b69}, {0x6e43, 0x5b4b},
+ {0x6e44, 0x5a35}, {0x6e4a, 0x713e}, {0x6e4d, 0x532c},
+ {0x6e56, 0x7b49}, {0x6e58, 0x5f4f}, {0x6e5b, 0x5340},
+ {0x6e5c, 0x6357}, {0x6e5e, 0x6f66}, {0x6e5f, 0x7c50},
+ {0x6e67, 0x6940}, {0x6e6b, 0x7553}, {0x6e6e, 0x6c5c},
+ {0x6e6f, 0x7737}, {0x6e72, 0x6a38}, {0x6e73, 0x5179},
+ {0x6e7a, 0x5c48}, {0x6e90, 0x6a39}, {0x6e96, 0x715e},
+ {0x6e9c, 0x5736}, {0x6e9d, 0x4f35}, {0x6e9f, 0x5928},
+ {0x6ea2, 0x6c6e}, {0x6ea5, 0x5d2a}, {0x6eaa, 0x4d22},
+ {0x6eab, 0x682e}, {0x6eaf, 0x613d}, {0x6eb1, 0x7251},
+ {0x6eb6, 0x6941}, {0x6eba, 0x527c}, {0x6ec2, 0x5b35},
+ {0x6ec4, 0x7367}, {0x6ec5, 0x587e}, {0x6ec9, 0x7c51},
+ {0x6ecb, 0x6d32}, {0x6ecc, 0x742f}, {0x6ece, 0x7b23},
+ {0x6ed1, 0x7c41}, {0x6ed3, 0x6e2b}, {0x6ed4, 0x5425},
+ {0x6eef, 0x7472}, {0x6ef4, 0x6e59}, {0x6ef8, 0x7b4a},
+ {0x6efe, 0x4d63}, {0x6eff, 0x583b}, {0x6f01, 0x655b},
+ {0x6f02, 0x7877}, {0x6f06, 0x7654}, {0x6f0f, 0x5729},
+ {0x6f11, 0x4b49}, {0x6f14, 0x6651}, {0x6f15, 0x704c},
+ {0x6f20, 0x582e}, {0x6f22, 0x7953}, {0x6f23, 0x557e},
+ {0x6f2b, 0x583c}, {0x6f2c, 0x7230}, {0x6f31, 0x622b},
+ {0x6f32, 0x7368}, {0x6f38, 0x6f42}, {0x6f3f, 0x6d6c},
+ {0x6f41, 0x6738}, {0x6f51, 0x5a7e}, {0x6f54, 0x4c3e},
+ {0x6f57, 0x727c}, {0x6f58, 0x5a6b}, {0x6f5a, 0x6258},
+ {0x6f5b, 0x6d56}, {0x6f5e, 0x5651}, {0x6f5f, 0x6033},
+ {0x6f62, 0x7c52}, {0x6f64, 0x6b48}, {0x6f6d, 0x5341},
+ {0x6f6e, 0x704d}, {0x6f70, 0x4f77}, {0x6f7a, 0x6d52},
+ {0x6f7c, 0x5458}, {0x6f7d, 0x5c49}, {0x6f7e, 0x5771},
+ {0x6f81, 0x5f3b}, {0x6f84, 0x7325}, {0x6f88, 0x744d},
+ {0x6f8d, 0x713f}, {0x6f8e, 0x7831}, {0x6f90, 0x697a},
+ {0x6f94, 0x7b4b}, {0x6f97, 0x4a55}, {0x6fa3, 0x7954},
+ {0x6fa4, 0x774a}, {0x6fa7, 0x5648}, {0x6fae, 0x7c68},
+ {0x6faf, 0x733d}, {0x6fb1, 0x6e7e}, {0x6fb3, 0x677e},
+ {0x6fb9, 0x5342}, {0x6fbe, 0x5336}, {0x6fc0, 0x4c2d},
+ {0x6fc1, 0x767a}, {0x6fc2, 0x5632}, {0x6fc3, 0x5258},
+ {0x6fca, 0x6758}, {0x6fd5, 0x6325}, {0x6fda, 0x6739},
+ {0x6fdf, 0x702d}, {0x6fe0, 0x7b4c}, {0x6fe1, 0x6b21},
+ {0x6fe4, 0x5426}, {0x6fe9, 0x7b4d}, {0x6feb, 0x553d},
+ {0x6fec, 0x715f}, {0x6fef, 0x767b}, {0x6ff1, 0x5e34},
+ {0x6ffe, 0x556b}, {0x7001, 0x6548}, {0x7005, 0x7b24},
+ {0x7006, 0x5439}, {0x7009, 0x5e61}, {0x700b, 0x6423},
+ {0x700f, 0x5737}, {0x7011, 0x786e}, {0x7015, 0x5e35},
+ {0x7018, 0x5652}, {0x701a, 0x7955}, {0x701b, 0x673a},
+ {0x701c, 0x6b55}, {0x701d, 0x5577}, {0x701e, 0x6f67},
+ {0x701f, 0x613e}, {0x7023, 0x7a2e}, {0x7027, 0x5669},
+ {0x7028, 0x566e}, {0x702f, 0x673b}, {0x7037, 0x6c4b},
+ {0x703e, 0x5533}, {0x704c, 0x4e34}, {0x7050, 0x7b25},
+ {0x7051, 0x616e}, {0x7058, 0x7728}, {0x705d, 0x7b4e},
+ {0x7063, 0x583d}, {0x706b, 0x7b7d}, {0x7070, 0x7c69},
+ {0x7078, 0x4f36}, {0x707c, 0x6d47}, {0x707d, 0x6e2c},
+ {0x7085, 0x4c5d}, {0x708a, 0x7627}, {0x708e, 0x667a},
+ {0x7092, 0x7524}, {0x7098, 0x7d5c}, {0x7099, 0x6d33},
+ {0x709a, 0x4e49}, {0x70a1, 0x6f68}, {0x70a4, 0x613f},
+ {0x70ab, 0x7a5b}, {0x70ac, 0x4b63}, {0x70ad, 0x7729},
+ {0x70af, 0x7b26}, {0x70b3, 0x5c39}, {0x70b7, 0x7140},
+ {0x70b8, 0x6d48}, {0x70b9, 0x6f43}, {0x70c8, 0x562d},
+ {0x70cb, 0x7d4e}, {0x70cf, 0x6821}, {0x70d8, 0x7b74},
+ {0x70d9, 0x5527}, {0x70dd, 0x7176}, {0x70df, 0x6653},
+ {0x70f1, 0x4c5e}, {0x70f9, 0x7832}, {0x70fd, 0x5c6b},
+ {0x7104, 0x7d36}, {0x7109, 0x656a}, {0x710c, 0x7160},
+ {0x7119, 0x5b4c}, {0x711a, 0x5d4d}, {0x711e, 0x5448},
+ {0x7121, 0x596d}, {0x7126, 0x7525}, {0x7130, 0x667b},
+ {0x7136, 0x6654}, {0x7147, 0x7d48}, {0x7149, 0x5621},
+ {0x714a, 0x7d3f}, {0x714c, 0x7c53}, {0x714e, 0x6f21},
+ {0x7150, 0x673c}, {0x7156, 0x516e}, {0x7159, 0x6655},
+ {0x715c, 0x6972}, {0x715e, 0x5f30}, {0x7164, 0x5860},
+ {0x7165, 0x7c3a}, {0x7166, 0x7d2f}, {0x7167, 0x704e},
+ {0x7169, 0x5b61}, {0x716c, 0x6549}, {0x716e, 0x6d34},
+ {0x717d, 0x6043}, {0x7184, 0x6358}, {0x7189, 0x697b},
+ {0x718a, 0x6a28}, {0x718f, 0x7d37}, {0x7192, 0x7b27},
+ {0x7194, 0x6942}, {0x7199, 0x7d77}, {0x719f, 0x6259},
+ {0x71a2, 0x5c6c}, {0x71ac, 0x6822}, {0x71b1, 0x6670},
+ {0x71b9, 0x7d78}, {0x71ba, 0x7d79}, {0x71be, 0x763f},
+ {0x71c1, 0x6727}, {0x71c3, 0x6657}, {0x71c8, 0x5473},
+ {0x71c9, 0x5449}, {0x71ce, 0x567a}, {0x71d0, 0x5772},
+ {0x71d2, 0x6140}, {0x71d4, 0x5b62}, {0x71d5, 0x6658},
+ {0x71df, 0x673d}, {0x71e5, 0x704f}, {0x71e6, 0x733e},
+ {0x71e7, 0x622c}, {0x71ed, 0x7537}, {0x71ee, 0x6070},
+ {0x71fb, 0x7d38}, {0x71fc, 0x6368}, {0x71fe, 0x5427},
+ {0x71ff, 0x687c}, {0x7200, 0x7a52}, {0x7206, 0x786f},
+ {0x7210, 0x5653}, {0x721b, 0x5534}, {0x722a, 0x7050},
+ {0x722c, 0x7770}, {0x722d, 0x6e33}, {0x7230, 0x6a3a},
+ {0x7232, 0x6a53}, {0x7235, 0x6d49}, {0x7236, 0x5d2b},
+ {0x723a, 0x652c}, {0x723b, 0x7d21}, {0x723d, 0x5f50},
+ {0x723e, 0x6c33}, {0x7240, 0x5f51}, {0x7246, 0x6d6d},
+ {0x7247, 0x7838}, {0x7248, 0x777a}, {0x724c, 0x782b},
+ {0x7252, 0x7460}, {0x7258, 0x543a}, {0x7259, 0x6433},
+ {0x725b, 0x695a}, {0x725d, 0x5e36}, {0x725f, 0x593f},
+ {0x7261, 0x5940}, {0x7262, 0x566f}, {0x7267, 0x594c},
+ {0x7269, 0x5a2a}, {0x7272, 0x5f65}, {0x7279, 0x7765},
+ {0x727d, 0x4c32}, {0x7280, 0x5f79}, {0x7281, 0x5760},
+ {0x72a2, 0x543b}, {0x72a7, 0x7d7a}, {0x72ac, 0x4c33},
+ {0x72af, 0x5b73}, {0x72c0, 0x5f52}, {0x72c2, 0x4e4a},
+ {0x72c4, 0x6e5a}, {0x72ce, 0x6464}, {0x72d0, 0x7b4f},
+ {0x72d7, 0x4f37}, {0x72d9, 0x6e43}, {0x72e1, 0x4e6a},
+ {0x72e9, 0x622d}, {0x72f8, 0x5761}, {0x72f9, 0x7a75},
+ {0x72fc, 0x5549}, {0x72fd, 0x782c}, {0x730a, 0x6759},
+ {0x7316, 0x7369}, {0x731b, 0x586d}, {0x731c, 0x6344},
+ {0x731d, 0x7071}, {0x7325, 0x6865}, {0x7329, 0x607a},
+ {0x732a, 0x6e44}, {0x732b, 0x595e}, {0x7336, 0x6b22},
+ {0x7337, 0x6b23}, {0x733e, 0x7c42}, {0x733f, 0x6a3b},
+ {0x7344, 0x682b}, {0x7345, 0x5e62}, {0x7350, 0x6d6f},
+ {0x7352, 0x6823}, {0x7357, 0x4f71}, {0x7368, 0x543c},
+ {0x736a, 0x7c6a}, {0x7370, 0x673e}, {0x7372, 0x7c72},
+ {0x7375, 0x5634}, {0x7378, 0x622e}, {0x737a, 0x5337},
+ {0x737b, 0x7a4c}, {0x7384, 0x7a5c}, {0x7386, 0x6d35},
+ {0x7387, 0x6163}, {0x7389, 0x682c}, {0x738b, 0x685d},
+ {0x738e, 0x6f69}, {0x7394, 0x743d}, {0x7396, 0x4f38},
+ {0x7397, 0x695b}, {0x7398, 0x512c}, {0x739f, 0x5a47},
+ {0x73a7, 0x6b49}, {0x73a9, 0x684c}, {0x73ad, 0x5e37},
+ {0x73b2, 0x563c}, {0x73b3, 0x5365}, {0x73b9, 0x7a5d},
+ {0x73c0, 0x5a56}, {0x73c2, 0x4a31}, {0x73c9, 0x5a48},
+ {0x73ca, 0x5f26}, {0x73cc, 0x7933}, {0x73cd, 0x7252},
+ {0x73cf, 0x4a44}, {0x73d6, 0x4e4b}, {0x73d9, 0x4d75},
+ {0x73dd, 0x7d30}, {0x73de, 0x5528}, {0x73e0, 0x7141},
+ {0x73e3, 0x6269}, {0x73e4, 0x5c4a}, {0x73e5, 0x6c34},
+ {0x73e6, 0x7a40}, {0x73e9, 0x7b28}, {0x73ea, 0x5028},
+ {0x73ed, 0x5a6c}, {0x73f7, 0x596e}, {0x73f9, 0x607b},
+ {0x73fd, 0x6f6a}, {0x73fe, 0x7a5e}, {0x7401, 0x6044},
+ {0x7403, 0x4f39}, {0x7405, 0x554a}, {0x7406, 0x5762},
+ {0x7407, 0x622f}, {0x7409, 0x5738}, {0x7413, 0x684d},
+ {0x741b, 0x765a}, {0x7420, 0x6f22}, {0x7421, 0x625a},
+ {0x7422, 0x767c}, {0x7425, 0x7b50}, {0x7426, 0x512d},
+ {0x7428, 0x4d64}, {0x742a, 0x512e}, {0x742b, 0x5c6d},
+ {0x742c, 0x684e}, {0x742e, 0x7079}, {0x742f, 0x4e35},
+ {0x7430, 0x667c}, {0x7433, 0x577b}, {0x7434, 0x5056},
+ {0x7435, 0x5d75}, {0x7436, 0x7771}, {0x7438, 0x767d},
+ {0x743a, 0x5b77}, {0x743f, 0x7b6a}, {0x7440, 0x695c},
+ {0x7441, 0x5941}, {0x7443, 0x7572}, {0x7444, 0x6045},
+ {0x744b, 0x6a54}, {0x7455, 0x7942}, {0x7457, 0x6a3c},
+ {0x7459, 0x5245}, {0x745a, 0x7b51}, {0x745b, 0x6740},
+ {0x745c, 0x6b25}, {0x745e, 0x5f7a}, {0x745f, 0x6322},
+ {0x7460, 0x5739}, {0x7462, 0x6943}, {0x7464, 0x687d},
+ {0x7465, 0x682f}, {0x7468, 0x7253}, {0x7469, 0x7b29},
+ {0x746a, 0x5825}, {0x746f, 0x554b}, {0x747e, 0x5048},
+ {0x7482, 0x512f}, {0x7483, 0x5763}, {0x7487, 0x6046},
+ {0x7489, 0x5622}, {0x748b, 0x6d70}, {0x7498, 0x5773},
+ {0x749c, 0x7c54}, {0x749e, 0x5a57}, {0x749f, 0x4c5f},
+ {0x74a1, 0x7254}, {0x74a3, 0x5130}, {0x74a5, 0x4c60},
+ {0x74a7, 0x5b7d}, {0x74a8, 0x733f}, {0x74aa, 0x7051},
+ {0x74b0, 0x7c3b}, {0x74b2, 0x6230}, {0x74b5, 0x6625},
+ {0x74b9, 0x625b}, {0x74bd, 0x5f5e}, {0x74bf, 0x6047},
+ {0x74c6, 0x726f}, {0x74ca, 0x4c61}, {0x74cf, 0x566a},
+ {0x74d4, 0x6742}, {0x74d8, 0x4e36}, {0x74da, 0x7340},
+ {0x74dc, 0x4d7e}, {0x74e0, 0x7b52}, {0x74e2, 0x7878},
+ {0x74e3, 0x777b}, {0x74e6, 0x683f}, {0x74ee, 0x6837},
+ {0x74f7, 0x6d36}, {0x7501, 0x5c3a}, {0x7504, 0x4c34},
+ {0x7511, 0x7177}, {0x7515, 0x6838}, {0x7518, 0x4a76},
+ {0x751a, 0x6424}, {0x751b, 0x7456}, {0x751f, 0x5f66},
+ {0x7523, 0x5f27}, {0x7525, 0x5f67}, {0x7526, 0x6141},
+ {0x7528, 0x6944}, {0x752b, 0x5c4b}, {0x752c, 0x6945},
+ {0x7530, 0x6f23}, {0x7531, 0x6b26}, {0x7532, 0x4b23},
+ {0x7533, 0x6369}, {0x7537, 0x517b}, {0x7538, 0x6f24},
+ {0x753a, 0x6f6b}, {0x7547, 0x5034}, {0x754c, 0x4d23},
+ {0x754f, 0x6866}, {0x7551, 0x6f25}, {0x7553, 0x534c},
+ {0x7554, 0x5a6d}, {0x7559, 0x573a}, {0x755b, 0x7255},
+ {0x755c, 0x7565}, {0x755d, 0x596f}, {0x7562, 0x7934},
+ {0x7565, 0x5554}, {0x7566, 0x7d4f}, {0x756a, 0x5b63},
+ {0x756f, 0x7161}, {0x7570, 0x6c36}, {0x7575, 0x7b7e},
+ {0x7576, 0x5357}, {0x7578, 0x5131}, {0x757a, 0x4b31},
+ {0x757f, 0x5132}, {0x7586, 0x4b32}, {0x7587, 0x7142},
+ {0x758a, 0x7461}, {0x758b, 0x7935}, {0x758e, 0x6143},
+ {0x758f, 0x6142}, {0x7591, 0x6b77}, {0x759d, 0x5f28},
+ {0x75a5, 0x4b4a}, {0x75ab, 0x6639}, {0x75b1, 0x785e},
+ {0x75b2, 0x792a}, {0x75b3, 0x4a77}, {0x75b5, 0x6d37},
+ {0x75b8, 0x5338}, {0x75b9, 0x7256}, {0x75bc, 0x5459},
+ {0x75bd, 0x6e45}, {0x75be, 0x7270}, {0x75c2, 0x4a32},
+ {0x75c5, 0x5c3b}, {0x75c7, 0x7178}, {0x75cd, 0x6c37},
+ {0x75d2, 0x654a}, {0x75d4, 0x7640}, {0x75d5, 0x7d5d},
+ {0x75d8, 0x5463}, {0x75d9, 0x4c62}, {0x75db, 0x7754},
+ {0x75e2, 0x5765}, {0x75f0, 0x5343}, {0x75f2, 0x5826},
+ {0x75f4, 0x7641}, {0x75fa, 0x5d76}, {0x75fc, 0x4d40},
+ {0x7600, 0x655c}, {0x760d, 0x654b}, {0x7619, 0x6144},
+ {0x761f, 0x6830}, {0x7620, 0x7430}, {0x7621, 0x736a},
+ {0x7622, 0x5a6e}, {0x7624, 0x573b}, {0x7626, 0x6231},
+ {0x763b, 0x572a}, {0x7642, 0x567b}, {0x764c, 0x645f},
+ {0x764e, 0x4a56}, {0x7652, 0x6b28}, {0x7656, 0x5b7e},
+ {0x7661, 0x7642}, {0x7664, 0x6f3b}, {0x7669, 0x547d},
+ {0x766c, 0x6048}, {0x7670, 0x6839}, {0x7672, 0x6f26},
+ {0x7678, 0x4d24}, {0x767b, 0x5474}, {0x767c, 0x5b21},
+ {0x767d, 0x5b5c}, {0x767e, 0x5b5d}, {0x7684, 0x6e5c},
+ {0x7686, 0x4b4b}, {0x7687, 0x7c55}, {0x768e, 0x4e6b},
+ {0x7690, 0x4d41}, {0x7693, 0x7b53}, {0x76ae, 0x792b},
+ {0x76ba, 0x7554}, {0x76bf, 0x5929}, {0x76c2, 0x695d},
+ {0x76c3, 0x5b4d}, {0x76c6, 0x5d4e}, {0x76c8, 0x6743},
+ {0x76ca, 0x6c4c}, {0x76d2, 0x796c}, {0x76d6, 0x4b4c},
+ {0x76db, 0x607c}, {0x76dc, 0x5428}, {0x76de, 0x6d53},
+ {0x76df, 0x586f}, {0x76e1, 0x7257}, {0x76e3, 0x4a78},
+ {0x76e4, 0x5a6f}, {0x76e7, 0x5654}, {0x76ee, 0x594d},
+ {0x76f2, 0x586e}, {0x76f4, 0x7241}, {0x76f8, 0x5f53},
+ {0x76fc, 0x5a70}, {0x76fe, 0x626a}, {0x7701, 0x607d},
+ {0x7704, 0x5878}, {0x7708, 0x772f}, {0x7709, 0x5a36},
+ {0x770b, 0x4a57}, {0x771e, 0x7258}, {0x7720, 0x5879},
+ {0x7729, 0x7a5f}, {0x7737, 0x4f6f}, {0x7738, 0x5942},
+ {0x773a, 0x7052}, {0x773c, 0x6451}, {0x7740, 0x7337},
+ {0x774d, 0x7a60}, {0x775b, 0x6f6c}, {0x7761, 0x6232},
+ {0x7763, 0x543d}, {0x7766, 0x594e}, {0x776b, 0x7462},
+ {0x7779, 0x5429}, {0x777e, 0x4d42}, {0x777f, 0x675a},
+ {0x778b, 0x7259}, {0x7791, 0x592a}, {0x779e, 0x583e},
+ {0x77a5, 0x5c2d}, {0x77ac, 0x626b}, {0x77ad, 0x567c},
+ {0x77b0, 0x4a79}, {0x77b3, 0x545a}, {0x77bb, 0x7457},
+ {0x77bc, 0x4c21}, {0x77bf, 0x4f3a}, {0x77d7, 0x7538},
+ {0x77db, 0x5943}, {0x77dc, 0x5068}, {0x77e2, 0x6345},
+ {0x77e3, 0x6b78}, {0x77e5, 0x7231}, {0x77e9, 0x4f3b},
+ {0x77ed, 0x532d}, {0x77ee, 0x6861}, {0x77ef, 0x4e6c},
+ {0x77f3, 0x6034}, {0x7802, 0x5e63}, {0x7812, 0x5d77},
+ {0x7825, 0x7232}, {0x7826, 0x7376}, {0x7827, 0x765b},
+ {0x782c, 0x577e}, {0x7832, 0x785f}, {0x7834, 0x7772},
+ {0x7845, 0x5029}, {0x784f, 0x665a}, {0x785d, 0x7526},
+ {0x786b, 0x573c}, {0x786c, 0x4c63}, {0x786f, 0x665b},
+ {0x787c, 0x5d5d}, {0x7881, 0x5133}, {0x7887, 0x6f6d},
+ {0x788c, 0x565e}, {0x788d, 0x6474}, {0x788e, 0x616f},
+ {0x7891, 0x5d78}, {0x7897, 0x684f}, {0x78a3, 0x4a65},
+ {0x78a7, 0x5c21}, {0x78a9, 0x6035}, {0x78ba, 0x7c2c},
+ {0x78bb, 0x7c2d}, {0x78bc, 0x5827}, {0x78c1, 0x6d38},
+ {0x78c5, 0x5b36}, {0x78ca, 0x5670}, {0x78cb, 0x732f},
+ {0x78ce, 0x4d25}, {0x78d0, 0x5a71}, {0x78e8, 0x5828},
+ {0x78ec, 0x4c64}, {0x78ef, 0x5134}, {0x78f5, 0x4a58},
+ {0x78fb, 0x5a72}, {0x7901, 0x7527}, {0x790e, 0x7528},
+ {0x7916, 0x6626}, {0x792a, 0x556c}, {0x792b, 0x5578},
+ {0x792c, 0x5a73}, {0x793a, 0x6346}, {0x793e, 0x5e64},
+ {0x7940, 0x5e65}, {0x7941, 0x5135}, {0x7947, 0x5136},
+ {0x7948, 0x5137}, {0x7949, 0x7233}, {0x7950, 0x695e},
+ {0x7956, 0x7053}, {0x7957, 0x7234}, {0x795a, 0x7054},
+ {0x795b, 0x4b64}, {0x795c, 0x7b54}, {0x795d, 0x7566},
+ {0x795e, 0x636a}, {0x7960, 0x5e66}, {0x7965, 0x5f54},
+ {0x7968, 0x7879}, {0x796d, 0x702e}, {0x797a, 0x5138},
+ {0x797f, 0x565f}, {0x7981, 0x5057}, {0x798d, 0x7c21},
+ {0x798e, 0x6f6e}, {0x798f, 0x5c58}, {0x7991, 0x695f},
+ {0x79a6, 0x655d}, {0x79a7, 0x7d7b}, {0x79aa, 0x6049},
+ {0x79ae, 0x5649}, {0x79b1, 0x542a}, {0x79b3, 0x654c},
+ {0x79b9, 0x6960}, {0x79bd, 0x5058}, {0x79be, 0x7c22},
+ {0x79bf, 0x543e}, {0x79c0, 0x6233}, {0x79c1, 0x5e67},
+ {0x79c9, 0x5c3c}, {0x79ca, 0x5236}, {0x79cb, 0x7555},
+ {0x79d1, 0x4e21}, {0x79d2, 0x7529}, {0x79d5, 0x5d79},
+ {0x79d8, 0x5d7a}, {0x79df, 0x7055}, {0x79e4, 0x765f},
+ {0x79e6, 0x725a}, {0x79e7, 0x646b}, {0x79e9, 0x7271},
+ {0x79fb, 0x6c39}, {0x7a00, 0x7d7c}, {0x7a05, 0x612a},
+ {0x7a08, 0x4a59}, {0x7a0b, 0x6f6f}, {0x7a0d, 0x752a},
+ {0x7a14, 0x6c79}, {0x7a17, 0x782d}, {0x7a19, 0x7242},
+ {0x7a1a, 0x7643}, {0x7a1c, 0x5752}, {0x7a1f, 0x7922},
+ {0x7a20, 0x7056}, {0x7a2e, 0x707a}, {0x7a31, 0x7660},
+ {0x7a36, 0x6973}, {0x7a37, 0x7243}, {0x7a3b, 0x542b},
+ {0x7a3c, 0x4a33}, {0x7a3d, 0x4d26}, {0x7a3f, 0x4d43},
+ {0x7a40, 0x4d5a}, {0x7a46, 0x594f}, {0x7a49, 0x7644},
+ {0x7a4d, 0x6e5d}, {0x7a4e, 0x6744}, {0x7a57, 0x6234},
+ {0x7a61, 0x5f62}, {0x7a62, 0x675b}, {0x7a69, 0x6831},
+ {0x7a6b, 0x7c2e}, {0x7a70, 0x654d}, {0x7a74, 0x7a6b},
+ {0x7a76, 0x4f3c}, {0x7a79, 0x4f62}, {0x7a7a, 0x4d76},
+ {0x7a7d, 0x6f70}, {0x7a7f, 0x743e}, {0x7a81, 0x544d},
+ {0x7a84, 0x7338}, {0x7a88, 0x6921}, {0x7a92, 0x7272},
+ {0x7a93, 0x736b}, {0x7a95, 0x7057}, {0x7a98, 0x4f57},
+ {0x7a9f, 0x4f5f}, {0x7aa9, 0x6840}, {0x7aaa, 0x6841},
+ {0x7aae, 0x4f63}, {0x7aaf, 0x6922}, {0x7aba, 0x502a},
+ {0x7ac4, 0x7341}, {0x7ac5, 0x502b}, {0x7ac7, 0x5464},
+ {0x7aca, 0x6f3c}, {0x7acb, 0x5821}, {0x7ad7, 0x595f},
+ {0x7ad9, 0x7357}, {0x7add, 0x5c3d}, {0x7adf, 0x4c65},
+ {0x7ae0, 0x6d71}, {0x7ae3, 0x7162}, {0x7ae5, 0x545b},
+ {0x7aea, 0x6235}, {0x7aed, 0x4a66}, {0x7aef, 0x532e},
+ {0x7af6, 0x4c66}, {0x7af9, 0x7153}, {0x7afa, 0x7567},
+ {0x7aff, 0x4a5a}, {0x7b0f, 0x7b6e}, {0x7b11, 0x6145},
+ {0x7b19, 0x5f69}, {0x7b1b, 0x6e5e}, {0x7b1e, 0x7742},
+ {0x7b20, 0x5822}, {0x7b26, 0x5d2c}, {0x7b2c, 0x702f},
+ {0x7b2d, 0x563d}, {0x7b39, 0x612b}, {0x7b46, 0x7936},
+ {0x7b49, 0x5475}, {0x7b4b, 0x5049}, {0x7b4c, 0x6f27},
+ {0x7b4d, 0x626c}, {0x7b4f, 0x5b6a}, {0x7b50, 0x4e4c},
+ {0x7b51, 0x7568}, {0x7b52, 0x7755}, {0x7b54, 0x534d},
+ {0x7b56, 0x737e}, {0x7b60, 0x5035}, {0x7b6c, 0x607e},
+ {0x7b6e, 0x5f7b}, {0x7b75, 0x665d}, {0x7b7d, 0x6824},
+ {0x7b87, 0x4b4d}, {0x7b8b, 0x6f28}, {0x7b8f, 0x6e34},
+ {0x7b94, 0x5a58}, {0x7b95, 0x5139}, {0x7b97, 0x5f29},
+ {0x7b9a, 0x7330}, {0x7b9d, 0x4c44}, {0x7ba1, 0x4e37},
+ {0x7bad, 0x6f29}, {0x7bb1, 0x5f55}, {0x7bb4, 0x6d57},
+ {0x7bb8, 0x6e46}, {0x7bc0, 0x6f3d}, {0x7bc1, 0x7c56},
+ {0x7bc4, 0x5b74}, {0x7bc6, 0x6f2a}, {0x7bc7, 0x7839},
+ {0x7bc9, 0x7569}, {0x7bd2, 0x6359}, {0x7be0, 0x6146},
+ {0x7be4, 0x543f}, {0x7be9, 0x5e68}, {0x7c07, 0x706a},
+ {0x7c12, 0x7342}, {0x7c1e, 0x532f}, {0x7c21, 0x4a5b},
+ {0x7c27, 0x7c57}, {0x7c2a, 0x6d58}, {0x7c2b, 0x6147},
+ {0x7c3d, 0x7458}, {0x7c3e, 0x5633}, {0x7c3f, 0x5d2d},
+ {0x7c43, 0x553e}, {0x7c4c, 0x7143}, {0x7c4d, 0x6e5f},
+ {0x7c60, 0x566b}, {0x7c64, 0x7459}, {0x7c6c, 0x5766},
+ {0x7c73, 0x5a37}, {0x7c83, 0x5d7b}, {0x7c89, 0x5d4f},
+ {0x7c92, 0x5823}, {0x7c95, 0x5a59}, {0x7c97, 0x7058},
+ {0x7c98, 0x6f44}, {0x7c9f, 0x6158}, {0x7ca5, 0x7154},
+ {0x7ca7, 0x6d72}, {0x7cae, 0x555b}, {0x7cb1, 0x555c},
+ {0x7cb2, 0x7344}, {0x7cb3, 0x4b57}, {0x7cb9, 0x6236},
+ {0x7cbe, 0x6f71}, {0x7cca, 0x7b55}, {0x7cd6, 0x5358},
+ {0x7cde, 0x5d50}, {0x7cdf, 0x7059}, {0x7ce0, 0x4b33},
+ {0x7ce7, 0x555d}, {0x7cfb, 0x4d27}, {0x7cfe, 0x502c},
+ {0x7d00, 0x513a}, {0x7d02, 0x7144}, {0x7d04, 0x6533},
+ {0x7d05, 0x7b75}, {0x7d06, 0x6961}, {0x7d07, 0x7d60},
+ {0x7d08, 0x7c3c}, {0x7d0a, 0x5a22}, {0x7d0b, 0x5a23},
+ {0x7d0d, 0x5221}, {0x7d10, 0x526f}, {0x7d14, 0x626d},
+ {0x7d17, 0x5e69}, {0x7d18, 0x4e5c}, {0x7d19, 0x7235},
+ {0x7d1a, 0x5064}, {0x7d1b, 0x5d51}, {0x7d20, 0x6148},
+ {0x7d21, 0x5b37}, {0x7d22, 0x5f63}, {0x7d2b, 0x6d39},
+ {0x7d2c, 0x7145}, {0x7d2e, 0x734f}, {0x7d2f, 0x572b},
+ {0x7d30, 0x612c}, {0x7d33, 0x636b}, {0x7d35, 0x6e47},
+ {0x7d39, 0x6149}, {0x7d3a, 0x4a7a}, {0x7d42, 0x707b},
+ {0x7d43, 0x7a61}, {0x7d44, 0x705a}, {0x7d45, 0x4c67},
+ {0x7d46, 0x5a74}, {0x7d50, 0x4c3f}, {0x7d5e, 0x4e6d},
+ {0x7d61, 0x5529}, {0x7d62, 0x7a62}, {0x7d66, 0x5065},
+ {0x7d68, 0x6b56}, {0x7d6a, 0x6c5f}, {0x7d6e, 0x5f7c},
+ {0x7d71, 0x7756}, {0x7d72, 0x5e6a}, {0x7d73, 0x4b34},
+ {0x7d76, 0x6f3e}, {0x7d79, 0x4c35}, {0x7d7f, 0x4f3d},
+ {0x7d8e, 0x6f72}, {0x7d8f, 0x6237}, {0x7d93, 0x4c68},
+ {0x7d9c, 0x707c}, {0x7da0, 0x5660}, {0x7da2, 0x7146},
+ {0x7dac, 0x6238}, {0x7dad, 0x6b2b}, {0x7db1, 0x4b35},
+ {0x7db2, 0x5851}, {0x7db4, 0x744e}, {0x7db5, 0x7377},
+ {0x7db8, 0x5746}, {0x7dba, 0x513b}, {0x7dbb, 0x772a},
+ {0x7dbd, 0x6d4a}, {0x7dbe, 0x5753}, {0x7dbf, 0x587a},
+ {0x7dc7, 0x7645}, {0x7dca, 0x514c}, {0x7dcb, 0x5d7c},
+ {0x7dd6, 0x5f7d}, {0x7dd8, 0x7965}, {0x7dda, 0x604a},
+ {0x7ddd, 0x727d}, {0x7dde, 0x5330}, {0x7de0, 0x7473},
+ {0x7de1, 0x5a49}, {0x7de3, 0x665e}, {0x7de8, 0x783a},
+ {0x7de9, 0x6850}, {0x7dec, 0x587b}, {0x7def, 0x6a55},
+ {0x7df4, 0x5623}, {0x7dfb, 0x7646}, {0x7e09, 0x725b},
+ {0x7e0a, 0x647c}, {0x7e15, 0x6832}, {0x7e1b, 0x5a5a},
+ {0x7e1d, 0x725c}, {0x7e1e, 0x7b56}, {0x7e1f, 0x6932},
+ {0x7e21, 0x6e2d}, {0x7e23, 0x7a63}, {0x7e2b, 0x5c6e},
+ {0x7e2e, 0x756a}, {0x7e2f, 0x6660}, {0x7e31, 0x707d},
+ {0x7e37, 0x572c}, {0x7e3d, 0x7545}, {0x7e3e, 0x6e60},
+ {0x7e41, 0x5b65}, {0x7e43, 0x5d5e}, {0x7e46, 0x5970},
+ {0x7e47, 0x6923}, {0x7e52, 0x7179}, {0x7e54, 0x7244},
+ {0x7e55, 0x604b}, {0x7e5e, 0x6924}, {0x7e61, 0x6239},
+ {0x7e69, 0x6331}, {0x7e6a, 0x7c6b}, {0x7e6b, 0x4d28},
+ {0x7e6d, 0x4c36}, {0x7e70, 0x705b}, {0x7e79, 0x663a},
+ {0x7e7c, 0x4d29}, {0x7e82, 0x7343}, {0x7e8c, 0x6159},
+ {0x7e8f, 0x6f2b}, {0x7e93, 0x6745}, {0x7e96, 0x6069},
+ {0x7e98, 0x7345}, {0x7e9b, 0x5440}, {0x7e9c, 0x553f},
+ {0x7f36, 0x5d2e}, {0x7f38, 0x797c}, {0x7f3a, 0x4c40},
+ {0x7f4c, 0x6522}, {0x7f50, 0x4e38}, {0x7f54, 0x5852},
+ {0x7f55, 0x7956}, {0x7f6a, 0x712a}, {0x7f6b, 0x4e51},
+ {0x7f6e, 0x7647}, {0x7f70, 0x5b6b}, {0x7f72, 0x5f7e},
+ {0x7f75, 0x5861}, {0x7f77, 0x7773}, {0x7f79, 0x5767},
+ {0x7f85, 0x547e}, {0x7f88, 0x513c}, {0x7f8a, 0x654f},
+ {0x7f8c, 0x4b36}, {0x7f8e, 0x5a38}, {0x7f94, 0x4d44},
+ {0x7f9a, 0x563e}, {0x7f9e, 0x623a}, {0x7fa4, 0x4f58},
+ {0x7fa8, 0x604c}, {0x7fa9, 0x6b79}, {0x7fb2, 0x7d7d},
+ {0x7fb8, 0x5768}, {0x7fb9, 0x4b58}, {0x7fbd, 0x6962},
+ {0x7fc1, 0x683a}, {0x7fc5, 0x6347}, {0x7fca, 0x6c4d},
+ {0x7fcc, 0x6c4e}, {0x7fce, 0x563f}, {0x7fd2, 0x6327},
+ {0x7fd4, 0x5f56}, {0x7fd5, 0x7d68}, {0x7fdf, 0x6e61},
+ {0x7fe0, 0x7628}, {0x7fe1, 0x5d7d}, {0x7fe9, 0x783b},
+ {0x7feb, 0x6851}, {0x7ff0, 0x7957}, {0x7ff9, 0x4e6e},
+ {0x7ffc, 0x6c4f}, {0x8000, 0x6925}, {0x8001, 0x5655},
+ {0x8003, 0x4d45}, {0x8005, 0x6d3a}, {0x8006, 0x513d},
+ {0x8009, 0x4f3e}, {0x800c, 0x6c3b}, {0x8010, 0x5231},
+ {0x8015, 0x4c69}, {0x8017, 0x5944}, {0x8018, 0x697c},
+ {0x802d, 0x513e}, {0x8033, 0x6c3c}, {0x8036, 0x652d},
+ {0x803d, 0x7730}, {0x803f, 0x4c6a}, {0x8043, 0x5344},
+ {0x8046, 0x5640}, {0x804a, 0x567d}, {0x8056, 0x6121},
+ {0x8058, 0x5e3d}, {0x805a, 0x7629}, {0x805e, 0x5a24},
+ {0x806f, 0x5624}, {0x8070, 0x7546}, {0x8072, 0x6122},
+ {0x8073, 0x6946}, {0x8077, 0x7245}, {0x807d, 0x7469},
+ {0x807e, 0x566c}, {0x807f, 0x6b53}, {0x8084, 0x6c3d},
+ {0x8085, 0x625c}, {0x8086, 0x5e6b}, {0x8087, 0x705c},
+ {0x8089, 0x6b3f}, {0x808b, 0x574e}, {0x808c, 0x513f},
+ {0x8096, 0x752b}, {0x809b, 0x797d}, {0x809d, 0x4a5c},
+ {0x80a1, 0x4d46}, {0x80a2, 0x7236}, {0x80a5, 0x5d7e},
+ {0x80a9, 0x4c37}, {0x80aa, 0x5b38}, {0x80af, 0x5069},
+ {0x80b1, 0x4e5d}, {0x80b2, 0x6b40}, {0x80b4, 0x7d22},
+ {0x80ba, 0x784b}, {0x80c3, 0x6a56}, {0x80c4, 0x7130},
+ {0x80cc, 0x5b4e}, {0x80ce, 0x7743}, {0x80da, 0x5b4f},
+ {0x80db, 0x4b24}, {0x80de, 0x7860}, {0x80e1, 0x7b57},
+ {0x80e4, 0x6b4a}, {0x80e5, 0x6021}, {0x80f1, 0x4e4d},
+ {0x80f4, 0x545c}, {0x80f8, 0x7d58}, {0x80fd, 0x5276},
+ {0x8102, 0x7237}, {0x8105, 0x7a76}, {0x8106, 0x762a},
+ {0x8107, 0x7a77}, {0x8108, 0x5866}, {0x810a, 0x7431},
+ {0x8118, 0x6852}, {0x811a, 0x4a45}, {0x811b, 0x4c6b},
+ {0x8123, 0x626e}, {0x8129, 0x623b}, {0x812b, 0x772d},
+ {0x812f, 0x7861}, {0x8139, 0x736c}, {0x813e, 0x5e21},
+ {0x814b, 0x647d}, {0x814e, 0x636c}, {0x8150, 0x5d2f},
+ {0x8151, 0x5d30}, {0x8154, 0x4b37}, {0x8155, 0x6853},
+ {0x8165, 0x6123}, {0x8166, 0x5260}, {0x816b, 0x707e},
+ {0x8170, 0x6926}, {0x8171, 0x4b72}, {0x8178, 0x6d73},
+ {0x8179, 0x5c59}, {0x817a, 0x604d}, {0x817f, 0x775a},
+ {0x8180, 0x5b39}, {0x8188, 0x4c2e}, {0x818a, 0x5a5b},
+ {0x818f, 0x4d47}, {0x819a, 0x5d31}, {0x819c, 0x582f},
+ {0x819d, 0x6323}, {0x81a0, 0x4e6f}, {0x81a3, 0x7273},
+ {0x81a8, 0x7833}, {0x81b3, 0x604e}, {0x81b5, 0x757d},
+ {0x81ba, 0x6b6c}, {0x81bd, 0x5345}, {0x81be, 0x7c6c},
+ {0x81bf, 0x525b}, {0x81c0, 0x546b}, {0x81c2, 0x5e22},
+ {0x81c6, 0x6566}, {0x81cd, 0x7030}, {0x81d8, 0x5544},
+ {0x81df, 0x6d74}, {0x81e3, 0x636d}, {0x81e5, 0x6842},
+ {0x81e7, 0x6d75}, {0x81e8, 0x577c}, {0x81ea, 0x6d3b},
+ {0x81ed, 0x762b}, {0x81f3, 0x7238}, {0x81f4, 0x7648},
+ {0x81fa, 0x5366}, {0x81fb, 0x725d}, {0x81fc, 0x4f3f},
+ {0x81fe, 0x6b2c}, {0x8205, 0x4f40}, {0x8207, 0x6628},
+ {0x8208, 0x7d69}, {0x820a, 0x4f41}, {0x820c, 0x605f},
+ {0x820d, 0x5e6c}, {0x8212, 0x6022}, {0x821b, 0x743f},
+ {0x821c, 0x626f}, {0x821e, 0x5971}, {0x821f, 0x7147},
+ {0x8221, 0x4b38}, {0x822a, 0x797e}, {0x822b, 0x5b3a},
+ {0x822c, 0x5a75}, {0x8235, 0x766c}, {0x8236, 0x5a5c},
+ {0x8237, 0x7a64}, {0x8239, 0x604f}, {0x8240, 0x5d32},
+ {0x8245, 0x6629}, {0x8247, 0x6f73}, {0x8259, 0x736d},
+ {0x8264, 0x6b7a}, {0x8266, 0x7966}, {0x826e, 0x4a5d},
+ {0x826f, 0x555e}, {0x8271, 0x4a5e}, {0x8272, 0x5f64},
+ {0x8276, 0x667d}, {0x8278, 0x752c}, {0x827e, 0x6475},
+ {0x828b, 0x6963}, {0x828d, 0x6d4b}, {0x828e, 0x4f64},
+ {0x8292, 0x5853}, {0x8299, 0x5d33}, {0x829a, 0x546c},
+ {0x829d, 0x7239}, {0x829f, 0x5f37}, {0x82a5, 0x4b4e},
+ {0x82a6, 0x7b58}, {0x82a9, 0x5059}, {0x82ac, 0x5d52},
+ {0x82ad, 0x7774}, {0x82ae, 0x675c}, {0x82af, 0x6425},
+ {0x82b1, 0x7c23}, {0x82b3, 0x5b3b}, {0x82b7, 0x723a},
+ {0x82b8, 0x697d}, {0x82b9, 0x504a}, {0x82bb, 0x7556},
+ {0x82bc, 0x5945}, {0x82bd, 0x6434}, {0x82bf, 0x6d27},
+ {0x82d1, 0x6a3d}, {0x82d2, 0x667e}, {0x82d4, 0x7744},
+ {0x82d5, 0x752d}, {0x82d7, 0x5960}, {0x82db, 0x4a34},
+ {0x82de, 0x7862}, {0x82df, 0x4f42}, {0x82e1, 0x6c3e},
+ {0x82e5, 0x6534}, {0x82e6, 0x4d48}, {0x82e7, 0x6e48},
+ {0x82f1, 0x6748}, {0x82fd, 0x4d49}, {0x82fe, 0x7937},
+ {0x8301, 0x7168}, {0x8302, 0x5972}, {0x8303, 0x5b75},
+ {0x8304, 0x4a35}, {0x8305, 0x5946}, {0x8309, 0x5849},
+ {0x8317, 0x592b}, {0x8328, 0x6d3c}, {0x832b, 0x5854},
+ {0x832f, 0x5c5a}, {0x8331, 0x623c}, {0x8334, 0x7c6d},
+ {0x8335, 0x6c60}, {0x8336, 0x527e}, {0x8338, 0x6947},
+ {0x8339, 0x662a}, {0x8340, 0x6270}, {0x8347, 0x7a3b},
+ {0x8349, 0x752e}, {0x834a, 0x7b2a}, {0x834f, 0x6c7b},
+ {0x8351, 0x6c3f}, {0x8352, 0x7c58}, {0x8373, 0x5465},
+ {0x8377, 0x7943}, {0x837b, 0x6e62}, {0x8389, 0x5769},
+ {0x838a, 0x6d76}, {0x838e, 0x5e6d}, {0x8396, 0x4c6c},
+ {0x8398, 0x636e}, {0x839e, 0x6854}, {0x83a2, 0x7a78},
+ {0x83a9, 0x5d34}, {0x83aa, 0x6435}, {0x83ab, 0x5830},
+ {0x83bd, 0x5855}, {0x83c1, 0x746a}, {0x83c5, 0x4e39},
+ {0x83c9, 0x5661}, {0x83ca, 0x4f52}, {0x83cc, 0x5036},
+ {0x83d3, 0x4e22}, {0x83d6, 0x736e}, {0x83dc, 0x7378},
+ {0x83e9, 0x5c4c}, {0x83eb, 0x504b}, {0x83ef, 0x7c24},
+ {0x83f0, 0x4d4a}, {0x83f1, 0x5754}, {0x83f2, 0x5e23},
+ {0x83f4, 0x6460}, {0x83f9, 0x6e49}, {0x83fd, 0x625d},
+ {0x8403, 0x757e}, {0x8404, 0x542c}, {0x840a, 0x5551},
+ {0x840c, 0x5870}, {0x840d, 0x7843}, {0x840e, 0x6a57},
+ {0x8429, 0x7557}, {0x842c, 0x583f}, {0x8431, 0x7d40},
+ {0x8438, 0x6b2d}, {0x843d, 0x552a}, {0x8449, 0x6728},
+ {0x8457, 0x6e4a}, {0x845b, 0x4a67}, {0x8461, 0x7863},
+ {0x8463, 0x545d}, {0x8466, 0x6a58}, {0x846b, 0x7b59},
+ {0x846c, 0x6d77}, {0x846f, 0x6535}, {0x8475, 0x502d},
+ {0x847a, 0x7171}, {0x8490, 0x623d}, {0x8494, 0x6348},
+ {0x8499, 0x5955}, {0x849c, 0x5f2a}, {0x84a1, 0x5b3c},
+ {0x84b2, 0x7864}, {0x84b8, 0x717a}, {0x84bb, 0x6536},
+ {0x84bc, 0x736f}, {0x84bf, 0x7b5a}, {0x84c0, 0x6160},
+ {0x84c2, 0x592c}, {0x84c4, 0x756b}, {0x84c6, 0x6036},
+ {0x84c9, 0x6948}, {0x84cb, 0x4b4f}, {0x84cd, 0x6349},
+ {0x84d1, 0x5e6e}, {0x84da, 0x623e}, {0x84ec, 0x5c6f},
+ {0x84ee, 0x5625}, {0x84f4, 0x6271}, {0x84fc, 0x567e},
+ {0x8511, 0x5921}, {0x8513, 0x5840}, {0x8514, 0x5c5b},
+ {0x8517, 0x6d3d}, {0x8518, 0x5f38}, {0x851a, 0x6a25},
+ {0x851e, 0x572d}, {0x8521, 0x7379}, {0x8523, 0x6d78},
+ {0x8525, 0x7547}, {0x852c, 0x614a}, {0x852d, 0x6b63},
+ {0x852f, 0x725e}, {0x853d, 0x784c}, {0x853f, 0x6a59},
+ {0x8541, 0x5346}, {0x8543, 0x5b66}, {0x8549, 0x752f},
+ {0x854e, 0x4e70}, {0x8553, 0x697e}, {0x8559, 0x7b36},
+ {0x8563, 0x6272}, {0x8568, 0x4f72}, {0x8569, 0x7739},
+ {0x856a, 0x5973}, {0x856d, 0x614b}, {0x8584, 0x5a5d},
+ {0x8587, 0x5a39}, {0x858f, 0x6b7b}, {0x8591, 0x4b39},
+ {0x8594, 0x6d79}, {0x859b, 0x6060}, {0x85a6, 0x7440},
+ {0x85a8, 0x7d3c}, {0x85a9, 0x5f31}, {0x85aa, 0x636f},
+ {0x85af, 0x6023}, {0x85b0, 0x7d39}, {0x85ba, 0x7031},
+ {0x85c1, 0x4d4b}, {0x85c9, 0x6d3e}, {0x85cd, 0x5540},
+ {0x85ce, 0x6370}, {0x85cf, 0x6d7a}, {0x85d5, 0x6964},
+ {0x85dc, 0x556d}, {0x85dd, 0x675d}, {0x85e4, 0x5476},
+ {0x85e5, 0x6537}, {0x85e9, 0x5b67}, {0x85ea, 0x623f},
+ {0x85f7, 0x6e4b}, {0x85fa, 0x5774}, {0x85fb, 0x705d},
+ {0x85ff, 0x4e2b}, {0x8602, 0x675e}, {0x8606, 0x5656},
+ {0x8607, 0x614c}, {0x860a, 0x6833}, {0x8616, 0x656e},
+ {0x8617, 0x5c22}, {0x861a, 0x6050}, {0x862d, 0x5535},
+ {0x863f, 0x5521}, {0x864e, 0x7b5b}, {0x8650, 0x794b},
+ {0x8654, 0x4b73}, {0x8655, 0x7425}, {0x865b, 0x7a48},
+ {0x865c, 0x5657}, {0x865e, 0x6965}, {0x865f, 0x7b5c},
+ {0x8667, 0x7d50}, {0x8679, 0x7b76}, {0x868a, 0x5a25},
+ {0x868c, 0x5b3d}, {0x8693, 0x6c62}, {0x86a3, 0x4d77},
+ {0x86a4, 0x705e}, {0x86a9, 0x7649}, {0x86c7, 0x5e6f},
+ {0x86cb, 0x5331}, {0x86d4, 0x7c6e}, {0x86d9, 0x6843},
+ {0x86db, 0x7148}, {0x86df, 0x4e71}, {0x86e4, 0x796d},
+ {0x86ed, 0x7274}, {0x86fe, 0x6436}, {0x8700, 0x7539},
+ {0x8702, 0x5c70}, {0x8703, 0x6371}, {0x8708, 0x6825},
+ {0x8718, 0x723b}, {0x871a, 0x5e24}, {0x871c, 0x5a4c},
+ {0x874e, 0x4a69}, {0x8755, 0x635a}, {0x8757, 0x7c59},
+ {0x875f, 0x6a5a}, {0x8766, 0x7944}, {0x8768, 0x6324},
+ {0x8774, 0x7b5d}, {0x8776, 0x6f4a}, {0x8778, 0x6844},
+ {0x8782, 0x554c}, {0x878d, 0x6b57}, {0x879f, 0x592d},
+ {0x87a2, 0x7b2b}, {0x87b3, 0x5359}, {0x87ba, 0x5522},
+ {0x87c4, 0x765e}, {0x87e0, 0x5a76}, {0x87ec, 0x6051},
+ {0x87ef, 0x6928}, {0x87f2, 0x7579}, {0x87f9, 0x7a2f},
+ {0x87fb, 0x6b7c}, {0x87fe, 0x606a}, {0x8805, 0x6332},
+ {0x881f, 0x5545}, {0x8822, 0x7163}, {0x8823, 0x556e},
+ {0x8831, 0x4d4c}, {0x8836, 0x6d59}, {0x883b, 0x5841},
+ {0x8840, 0x7a6c}, {0x8846, 0x716b}, {0x884c, 0x7a3c},
+ {0x884d, 0x6662}, {0x8852, 0x7a65}, {0x8853, 0x627a},
+ {0x8857, 0x4a36}, {0x8859, 0x6437}, {0x885b, 0x6a5b},
+ {0x885d, 0x757a}, {0x8861, 0x7b2c}, {0x8862, 0x4f43},
+ {0x8863, 0x6b7d}, {0x8868, 0x787a}, {0x886b, 0x5f39},
+ {0x8870, 0x6171}, {0x8872, 0x5224}, {0x8877, 0x757b},
+ {0x887e, 0x505a}, {0x887f, 0x505b}, {0x8881, 0x6a3e},
+ {0x8882, 0x5931}, {0x8888, 0x4a37}, {0x888b, 0x5367},
+ {0x888d, 0x7865}, {0x8892, 0x5332}, {0x8896, 0x6240},
+ {0x8897, 0x725f}, {0x889e, 0x4d65}, {0x88ab, 0x792c},
+ {0x88b4, 0x4d4d}, {0x88c1, 0x6e2e}, {0x88c2, 0x562e},
+ {0x88cf, 0x576a}, {0x88d4, 0x6760}, {0x88d5, 0x6b2e},
+ {0x88d9, 0x4f59}, {0x88dc, 0x5c4d}, {0x88dd, 0x6d7b},
+ {0x88df, 0x5e70}, {0x88e1, 0x576b}, {0x88e8, 0x5e25},
+ {0x88f3, 0x5f57}, {0x88f4, 0x5b50}, {0x88f5, 0x5b51},
+ {0x88f8, 0x5523}, {0x88fd, 0x7032}, {0x8907, 0x5c5c},
+ {0x8910, 0x4a68}, {0x8912, 0x7866}, {0x8913, 0x5c4e},
+ {0x8918, 0x6a5c}, {0x8919, 0x5b52}, {0x8925, 0x6933},
+ {0x892a, 0x775b}, {0x8936, 0x6328}, {0x8938, 0x572e},
+ {0x893b, 0x6061}, {0x8941, 0x4b3a}, {0x8944, 0x6551},
+ {0x895f, 0x505c}, {0x8964, 0x5541}, {0x896a, 0x584a},
+ {0x8972, 0x6329}, {0x897f, 0x6024}, {0x8981, 0x6929},
+ {0x8983, 0x5347}, {0x8986, 0x5c5d}, {0x8987, 0x782e},
+ {0x898b, 0x4c38}, {0x898f, 0x502e}, {0x8993, 0x5872},
+ {0x8996, 0x634a}, {0x89a1, 0x4c2f}, {0x89a9, 0x542d},
+ {0x89aa, 0x7651}, {0x89b2, 0x504c}, {0x89ba, 0x4a46},
+ {0x89bd, 0x5542}, {0x89c0, 0x4e3a}, {0x89d2, 0x4a47},
+ {0x89e3, 0x7a30}, {0x89f4, 0x5f58}, {0x89f8, 0x753a},
+ {0x8a00, 0x656b}, {0x8a02, 0x6f74}, {0x8a03, 0x5d35},
+ {0x8a08, 0x4d2a}, {0x8a0a, 0x6372}, {0x8a0c, 0x7b77},
+ {0x8a0e, 0x7750}, {0x8a13, 0x7d3a}, {0x8a16, 0x7d61},
+ {0x8a17, 0x767e}, {0x8a18, 0x5140}, {0x8a1b, 0x6845},
+ {0x8a1d, 0x6438}, {0x8a1f, 0x6168}, {0x8a23, 0x4c41},
+ {0x8a25, 0x526d}, {0x8a2a, 0x5b3e}, {0x8a2d, 0x6062},
+ {0x8a31, 0x7a49}, {0x8a34, 0x614d}, {0x8a36, 0x4a38},
+ {0x8a3a, 0x7260}, {0x8a3b, 0x7149}, {0x8a50, 0x5e71},
+ {0x8a54, 0x705f}, {0x8a55, 0x7844}, {0x8a5b, 0x6e4c},
+ {0x8a5e, 0x5e72}, {0x8a60, 0x6749}, {0x8a62, 0x6273},
+ {0x8a63, 0x6761}, {0x8a66, 0x634b}, {0x8a69, 0x634c},
+ {0x8a6d, 0x4f78}, {0x8a6e, 0x6f2c}, {0x8a70, 0x7d7e},
+ {0x8a71, 0x7c25}, {0x8a72, 0x7a31}, {0x8a73, 0x5f59},
+ {0x8a75, 0x6052}, {0x8a79, 0x745a}, {0x8a85, 0x714a},
+ {0x8a87, 0x4e23}, {0x8a8c, 0x723c}, {0x8a8d, 0x6c63},
+ {0x8a93, 0x6025}, {0x8a95, 0x772b}, {0x8a98, 0x6b2f},
+ {0x8a9e, 0x655e}, {0x8aa0, 0x6124}, {0x8aa1, 0x4d2b},
+ {0x8aa3, 0x5974}, {0x8aa4, 0x6826}, {0x8aa5, 0x4d4e},
+ {0x8aa6, 0x6169}, {0x8aa8, 0x7c6f}, {0x8aaa, 0x6063},
+ {0x8ab0, 0x6241}, {0x8ab2, 0x4e24}, {0x8ab9, 0x5e26},
+ {0x8abc, 0x6b7e}, {0x8abe, 0x6b5d}, {0x8abf, 0x7060},
+ {0x8ac2, 0x745b}, {0x8ac4, 0x6274}, {0x8ac7, 0x5348},
+ {0x8acb, 0x746b}, {0x8acd, 0x6e35}, {0x8acf, 0x7558},
+ {0x8ad2, 0x555f}, {0x8ad6, 0x5665}, {0x8adb, 0x6b30},
+ {0x8adc, 0x7463}, {0x8ae1, 0x634d}, {0x8ae6, 0x7474},
+ {0x8ae7, 0x7a32}, {0x8aea, 0x6f75}, {0x8aeb, 0x4a5f},
+ {0x8aed, 0x6b31}, {0x8aee, 0x6d3f}, {0x8af1, 0x7d49},
+ {0x8af6, 0x6426}, {0x8af7, 0x7924}, {0x8af8, 0x7033},
+ {0x8afa, 0x656c}, {0x8afe, 0x5167}, {0x8b00, 0x5947},
+ {0x8b01, 0x6457}, {0x8b02, 0x6a5d}, {0x8b04, 0x5477},
+ {0x8b0e, 0x5a3a}, {0x8b10, 0x5a4d}, {0x8b14, 0x794c},
+ {0x8b16, 0x615a}, {0x8b17, 0x5b3f}, {0x8b19, 0x4c45},
+ {0x8b1a, 0x6c50}, {0x8b1b, 0x4b3b}, {0x8b1d, 0x5e73},
+ {0x8b20, 0x692a}, {0x8b28, 0x5948}, {0x8b2b, 0x6e63},
+ {0x8b2c, 0x573d}, {0x8b33, 0x4f44}, {0x8b39, 0x504d},
+ {0x8b41, 0x7c26}, {0x8b49, 0x717b}, {0x8b4e, 0x7d52},
+ {0x8b4f, 0x5141}, {0x8b58, 0x635b}, {0x8b5a, 0x5349},
+ {0x8b5c, 0x5c4f}, {0x8b66, 0x4c6d}, {0x8b6c, 0x5e27},
+ {0x8b6f, 0x663b}, {0x8b70, 0x6c21}, {0x8b74, 0x4c39},
+ {0x8b77, 0x7b5e}, {0x8b7d, 0x6762}, {0x8b80, 0x5441},
+ {0x8b8a, 0x5c28}, {0x8b90, 0x6242}, {0x8b92, 0x7358},
+ {0x8b93, 0x6553}, {0x8b96, 0x7359}, {0x8b9a, 0x7346},
+ {0x8c37, 0x4d5b}, {0x8c3f, 0x4d2c}, {0x8c41, 0x7c43},
+ {0x8c46, 0x5467}, {0x8c48, 0x5142}, {0x8c4a, 0x7925},
+ {0x8c4c, 0x6855}, {0x8c55, 0x634e}, {0x8c5a, 0x544a},
+ {0x8c61, 0x5f5a}, {0x8c6a, 0x7b5f}, {0x8c6b, 0x6763},
+ {0x8c79, 0x787b}, {0x8c7a, 0x634f}, {0x8c82, 0x7530},
+ {0x8c8a, 0x5867}, {0x8c8c, 0x5949}, {0x8c9d, 0x782f},
+ {0x8c9e, 0x6f76}, {0x8ca0, 0x5d36}, {0x8ca1, 0x6e2f},
+ {0x8ca2, 0x4d78}, {0x8ca7, 0x5e38}, {0x8ca8, 0x7c27},
+ {0x8ca9, 0x777c}, {0x8caa, 0x7731}, {0x8cab, 0x4e3b},
+ {0x8cac, 0x7421}, {0x8caf, 0x6e4d}, {0x8cb0, 0x612e},
+ {0x8cb3, 0x6c43}, {0x8cb4, 0x4f7e}, {0x8cb6, 0x783f},
+ {0x8cb7, 0x5862}, {0x8cb8, 0x5368}, {0x8cbb, 0x5e28},
+ {0x8cbc, 0x7464}, {0x8cbd, 0x6c42}, {0x8cbf, 0x5975},
+ {0x8cc0, 0x7945}, {0x8cc1, 0x5d53}, {0x8cc2, 0x5671},
+ {0x8cc3, 0x6c7c}, {0x8cc4, 0x7c70}, {0x8cc7, 0x6d40},
+ {0x8cc8, 0x4a39}, {0x8cca, 0x6e64}, {0x8cd1, 0x7261},
+ {0x8cd3, 0x5e39}, {0x8cda, 0x5672}, {0x8cdc, 0x5e74},
+ {0x8cde, 0x5f5b}, {0x8ce0, 0x5b53}, {0x8ce2, 0x7a67},
+ {0x8ce3, 0x5863}, {0x8ce4, 0x7441}, {0x8ce6, 0x5d37},
+ {0x8cea, 0x7275}, {0x8ced, 0x542e}, {0x8cf4, 0x5673},
+ {0x8cfb, 0x5d38}, {0x8cfc, 0x4f45}, {0x8cfd, 0x5f5f},
+ {0x8d04, 0x723e}, {0x8d05, 0x7621}, {0x8d07, 0x6b4b},
+ {0x8d08, 0x717c}, {0x8d0a, 0x7347}, {0x8d0d, 0x606b},
+ {0x8d13, 0x6d7c}, {0x8d16, 0x615b}, {0x8d64, 0x6e65},
+ {0x8d66, 0x5e75}, {0x8d6b, 0x7a53}, {0x8d70, 0x714b},
+ {0x8d73, 0x502f}, {0x8d74, 0x5d39}, {0x8d77, 0x5143},
+ {0x8d85, 0x7531}, {0x8d8a, 0x6a46}, {0x8d99, 0x7061},
+ {0x8da3, 0x762c}, {0x8da8, 0x7559}, {0x8db3, 0x706b},
+ {0x8dba, 0x5d3a}, {0x8dbe, 0x723f}, {0x8dc6, 0x7745},
+ {0x8dcb, 0x5b22}, {0x8dcc, 0x7276}, {0x8dcf, 0x4a3a},
+ {0x8ddb, 0x7775}, {0x8ddd, 0x4b65}, {0x8de1, 0x6e66},
+ {0x8de3, 0x6053}, {0x8de8, 0x4e25}, {0x8def, 0x5658},
+ {0x8df3, 0x542f}, {0x8e0a, 0x6949}, {0x8e0f, 0x534e},
+ {0x8e10, 0x7442}, {0x8e1e, 0x4b66}, {0x8e2a, 0x7121},
+ {0x8e30, 0x6b32}, {0x8e35, 0x7122}, {0x8e42, 0x6b33},
+ {0x8e44, 0x7034}, {0x8e47, 0x4b74}, {0x8e48, 0x5430},
+ {0x8e49, 0x7332}, {0x8e4a, 0x7b37}, {0x8e59, 0x756c},
+ {0x8e5f, 0x6e67}, {0x8e60, 0x7432}, {0x8e74, 0x756d},
+ {0x8e76, 0x4f73}, {0x8e81, 0x7062}, {0x8e87, 0x6e4e},
+ {0x8e8a, 0x714c}, {0x8e8d, 0x6538}, {0x8eaa, 0x5775},
+ {0x8eab, 0x6373}, {0x8eac, 0x4f65}, {0x8ec0, 0x4f46},
+ {0x8eca, 0x7333}, {0x8ecb, 0x6458}, {0x8ecc, 0x4f79},
+ {0x8ecd, 0x4f5a}, {0x8ed2, 0x7a4d}, {0x8edf, 0x6663},
+ {0x8eeb, 0x7262}, {0x8ef8, 0x756e}, {0x8efb, 0x4a3b},
+ {0x8efe, 0x635c}, {0x8f03, 0x4e72}, {0x8f05, 0x5659},
+ {0x8f09, 0x6e30}, {0x8f12, 0x7465}, {0x8f13, 0x5842},
+ {0x8f14, 0x5c50}, {0x8f15, 0x4c6e}, {0x8f1b, 0x5560},
+ {0x8f1c, 0x764a}, {0x8f1d, 0x7d4a}, {0x8f1e, 0x5856},
+ {0x8f1f, 0x744f}, {0x8f26, 0x5626}, {0x8f27, 0x5c3e},
+ {0x8f29, 0x5b54}, {0x8f2a, 0x5747}, {0x8f2f, 0x727e},
+ {0x8f33, 0x714d}, {0x8f38, 0x6243}, {0x8f39, 0x5c5e},
+ {0x8f3b, 0x5c5f}, {0x8f3e, 0x6f2d}, {0x8f3f, 0x662b},
+ {0x8f44, 0x795d}, {0x8f45, 0x6a3f}, {0x8f49, 0x6f2e},
+ {0x8f4d, 0x7450}, {0x8f4e, 0x4e73}, {0x8f5d, 0x662c},
+ {0x8f5f, 0x4e5e}, {0x8f62, 0x5579}, {0x8f9b, 0x6374},
+ {0x8f9c, 0x4d50}, {0x8fa3, 0x5538}, {0x8fa6, 0x777d},
+ {0x8fa8, 0x5c29}, {0x8fad, 0x5e76}, {0x8faf, 0x5c2a},
+ {0x8fb0, 0x7263}, {0x8fb1, 0x6934}, {0x8fb2, 0x525c},
+ {0x8fc2, 0x6966}, {0x8fc5, 0x6376}, {0x8fce, 0x674a},
+ {0x8fd1, 0x504e}, {0x8fd4, 0x5a77}, {0x8fe6, 0x4a3c},
+ {0x8fea, 0x6e68}, {0x8feb, 0x5a5e}, {0x8fed, 0x7277},
+ {0x8ff0, 0x627b}, {0x8ff2, 0x4c26}, {0x8ff7, 0x5a3b},
+ {0x8ff9, 0x6e69}, {0x8ffd, 0x755a}, {0x9000, 0x775c},
+ {0x9001, 0x616a}, {0x9002, 0x4e41}, {0x9003, 0x5431},
+ {0x9005, 0x7d31}, {0x9006, 0x663d}, {0x9008, 0x7b2d},
+ {0x900b, 0x7867}, {0x900d, 0x614e}, {0x900f, 0x7762},
+ {0x9010, 0x756f}, {0x9011, 0x4f47}, {0x9014, 0x5432},
+ {0x9015, 0x4c6f}, {0x9017, 0x5468}, {0x9019, 0x6e4f},
+ {0x901a, 0x7757}, {0x901d, 0x6026}, {0x901e, 0x5641},
+ {0x901f, 0x615c}, {0x9020, 0x7063}, {0x9021, 0x7164},
+ {0x9022, 0x5c71}, {0x9023, 0x5627}, {0x902e, 0x7475},
+ {0x9031, 0x714e}, {0x9032, 0x7264}, {0x9035, 0x5030},
+ {0x9038, 0x6c6f}, {0x903c, 0x793a}, {0x903e, 0x6b35},
+ {0x9041, 0x546d}, {0x9042, 0x6244}, {0x9047, 0x6967},
+ {0x904a, 0x6b34}, {0x904b, 0x6a21}, {0x904d, 0x783c},
+ {0x904e, 0x4e26}, {0x9050, 0x7946}, {0x9051, 0x7c5a},
+ {0x9053, 0x5433}, {0x9054, 0x5339}, {0x9055, 0x6a5e},
+ {0x9059, 0x692b}, {0x905c, 0x6161}, {0x905d, 0x534f},
+ {0x905e, 0x7476}, {0x9060, 0x6a40}, {0x9061, 0x614f},
+ {0x9063, 0x4c3a}, {0x9069, 0x6e6a}, {0x906d, 0x7064},
+ {0x906e, 0x7334}, {0x906f, 0x546e}, {0x9072, 0x7240},
+ {0x9075, 0x7165}, {0x9077, 0x7443}, {0x9078, 0x6054},
+ {0x907a, 0x6b36}, {0x907c, 0x5721}, {0x907d, 0x4b68},
+ {0x907f, 0x792d}, {0x9080, 0x692d}, {0x9081, 0x5864},
+ {0x9082, 0x7a33}, {0x9083, 0x6245}, {0x9084, 0x7c3d},
+ {0x9087, 0x6c44}, {0x9088, 0x5831}, {0x908a, 0x5c2b},
+ {0x908f, 0x5524}, {0x9091, 0x6b69}, {0x9095, 0x683b},
+ {0x9099, 0x5857}, {0x90a2, 0x7b2e}, {0x90a3, 0x5161},
+ {0x90a6, 0x5b40}, {0x90a8, 0x753e}, {0x90aa, 0x5e77},
+ {0x90af, 0x4a7b}, {0x90b0, 0x7746}, {0x90b1, 0x4f48},
+ {0x90b5, 0x6150}, {0x90b8, 0x6e50}, {0x90c1, 0x6974},
+ {0x90ca, 0x4e74}, {0x90de, 0x554d}, {0x90e1, 0x4f5b},
+ {0x90e8, 0x5d3b}, {0x90ed, 0x4e2c}, {0x90f5, 0x6968},
+ {0x90fd, 0x5434}, {0x9102, 0x6447}, {0x9112, 0x755b},
+ {0x9115, 0x7a41}, {0x9119, 0x5e29}, {0x9127, 0x5478},
+ {0x912d, 0x6f77}, {0x9132, 0x5333}, {0x9149, 0x6b37},
+ {0x914a, 0x6f78}, {0x914b, 0x755c}, {0x914c, 0x6d4c},
+ {0x914d, 0x5b55}, {0x914e, 0x714f}, {0x9152, 0x7150},
+ {0x9162, 0x7532}, {0x9169, 0x592e}, {0x916a, 0x552c},
+ {0x916c, 0x6246}, {0x9175, 0x7d23}, {0x9177, 0x7b65},
+ {0x9178, 0x5f2b}, {0x9187, 0x6275}, {0x9189, 0x762d},
+ {0x918b, 0x7533}, {0x918d, 0x7035}, {0x9192, 0x6125},
+ {0x919c, 0x755d}, {0x91ab, 0x6c22}, {0x91ac, 0x6d7d},
+ {0x91ae, 0x7534}, {0x91af, 0x7b38}, {0x91b1, 0x5b23},
+ {0x91b4, 0x564a}, {0x91b5, 0x4b59}, {0x91c0, 0x6554},
+ {0x91c7, 0x737a}, {0x91c9, 0x6b38}, {0x91cb, 0x6037},
+ {0x91cc, 0x576c}, {0x91cd, 0x716c}, {0x91ce, 0x652f},
+ {0x91cf, 0x5561}, {0x91d0, 0x576d}, {0x91d1, 0x5151},
+ {0x91d7, 0x6172}, {0x91d8, 0x6f79}, {0x91dc, 0x5d3c},
+ {0x91dd, 0x765c}, {0x91e3, 0x7065}, {0x91e7, 0x7444},
+ {0x91ea, 0x6969}, {0x91f5, 0x737b}, {0x920d, 0x546f},
+ {0x9210, 0x4c22}, {0x9211, 0x777e}, {0x9212, 0x5f3c},
+ {0x9217, 0x6b4d}, {0x921e, 0x5037}, {0x9234, 0x5642},
+ {0x923a, 0x682d}, {0x923f, 0x6f2f}, {0x9240, 0x4b25},
+ {0x9245, 0x4b69}, {0x9249, 0x7a68}, {0x9257, 0x4c46},
+ {0x925b, 0x6667}, {0x925e, 0x6a47}, {0x9262, 0x5b24},
+ {0x9264, 0x4f49}, {0x9265, 0x627c}, {0x9266, 0x6f7a},
+ {0x9280, 0x6b5e}, {0x9283, 0x7548}, {0x9285, 0x545e},
+ {0x9291, 0x6055}, {0x9293, 0x6f30}, {0x9296, 0x6247},
+ {0x9298, 0x592f}, {0x929c, 0x7967}, {0x92b3, 0x6765},
+ {0x92b6, 0x4f4a}, {0x92b7, 0x6151}, {0x92b9, 0x6248},
+ {0x92cc, 0x6f7b}, {0x92cf, 0x7a79}, {0x92d2, 0x5c72},
+ {0x92e4, 0x6027}, {0x92ea, 0x7868}, {0x92f8, 0x4b6a},
+ {0x92fc, 0x4b3c}, {0x9304, 0x5662}, {0x9310, 0x755e},
+ {0x9318, 0x755f}, {0x931a, 0x6e36}, {0x931e, 0x6276},
+ {0x931f, 0x534a}, {0x9320, 0x6f7c}, {0x9321, 0x5144},
+ {0x9322, 0x6f31}, {0x9324, 0x5145}, {0x9326, 0x505e},
+ {0x9328, 0x5961}, {0x932b, 0x6038}, {0x932e, 0x4d51},
+ {0x932f, 0x7339}, {0x9348, 0x674c}, {0x934a, 0x5628},
+ {0x934b, 0x4e27}, {0x934d, 0x5435}, {0x9354, 0x6448},
+ {0x935b, 0x5334}, {0x936e, 0x6b39}, {0x9375, 0x4b75},
+ {0x937c, 0x765d}, {0x937e, 0x7123}, {0x938c, 0x4c47},
+ {0x9394, 0x694a}, {0x9396, 0x6170}, {0x939a, 0x7560},
+ {0x93a3, 0x7b2f}, {0x93a7, 0x4b51}, {0x93ac, 0x7b60},
+ {0x93ad, 0x7265}, {0x93b0, 0x6c70}, {0x93c3, 0x706c},
+ {0x93d1, 0x6e6b}, {0x93de, 0x694b}, {0x93e1, 0x4c70},
+ {0x93e4, 0x572f}, {0x93f6, 0x7321}, {0x9404, 0x7c75},
+ {0x9418, 0x7124}, {0x9425, 0x6056}, {0x942b, 0x6f32},
+ {0x9435, 0x7451}, {0x9438, 0x7721}, {0x9444, 0x7151},
+ {0x9451, 0x4a7c}, {0x9452, 0x4a7d}, {0x945b, 0x4e4e},
+ {0x947d, 0x7348}, {0x947f, 0x733a}, {0x9577, 0x6d7e},
+ {0x9580, 0x5a26}, {0x9583, 0x606c}, {0x9589, 0x784d},
+ {0x958b, 0x4b52}, {0x958f, 0x6b4e}, {0x9591, 0x7958},
+ {0x9592, 0x7959}, {0x9593, 0x4a60}, {0x9594, 0x5a4a},
+ {0x9598, 0x4b26}, {0x95a3, 0x4a48}, {0x95a4, 0x796e},
+ {0x95a5, 0x5b6c}, {0x95a8, 0x5031}, {0x95ad, 0x556f},
+ {0x95b1, 0x6673}, {0x95bb, 0x6722}, {0x95bc, 0x6459},
+ {0x95c7, 0x6461}, {0x95ca, 0x7c44}, {0x95d4, 0x796f},
+ {0x95d5, 0x4f74}, {0x95d6, 0x7766}, {0x95dc, 0x4e3c},
+ {0x95e1, 0x7445}, {0x95e2, 0x5c23}, {0x961c, 0x5d3d},
+ {0x9621, 0x7446}, {0x962a, 0x7821}, {0x962e, 0x6856},
+ {0x9632, 0x5b41}, {0x963b, 0x7066}, {0x963f, 0x6439},
+ {0x9640, 0x766d}, {0x9642, 0x792e}, {0x9644, 0x5d3e},
+ {0x964b, 0x5730}, {0x964c, 0x5868}, {0x964d, 0x4b3d},
+ {0x9650, 0x795a}, {0x965b, 0x784e}, {0x965c, 0x7970},
+ {0x965d, 0x606d}, {0x965e, 0x6333}, {0x965f, 0x7433},
+ {0x9662, 0x6a42}, {0x9663, 0x7266}, {0x9664, 0x7036},
+ {0x966a, 0x5b56}, {0x9670, 0x6b64}, {0x9673, 0x7267},
+ {0x9675, 0x5755}, {0x9676, 0x5436}, {0x9677, 0x7968},
+ {0x9678, 0x5741}, {0x967d, 0x6555}, {0x9685, 0x696a},
+ {0x9686, 0x574c}, {0x968a, 0x5369}, {0x968b, 0x6249},
+ {0x968d, 0x7c5b}, {0x968e, 0x4d2d}, {0x9694, 0x4c30},
+ {0x9695, 0x6a22}, {0x9698, 0x6476}, {0x9699, 0x5040},
+ {0x969b, 0x7037}, {0x969c, 0x6e21}, {0x96a3, 0x5776},
+ {0x96a7, 0x624a}, {0x96a8, 0x624b}, {0x96aa, 0x7a4f},
+ {0x96b1, 0x6b5f}, {0x96b7, 0x564b}, {0x96bb, 0x7434},
+ {0x96c0, 0x6d4d}, {0x96c1, 0x6452}, {0x96c4, 0x6a29},
+ {0x96c5, 0x643a}, {0x96c6, 0x7322}, {0x96c7, 0x4d52},
+ {0x96c9, 0x764b}, {0x96cb, 0x7166}, {0x96cc, 0x6d41},
+ {0x96cd, 0x683c}, {0x96ce, 0x6e51}, {0x96d5, 0x7067},
+ {0x96d6, 0x624c}, {0x96d9, 0x642a}, {0x96db, 0x7561},
+ {0x96dc, 0x6d5a}, {0x96e2, 0x576e}, {0x96e3, 0x5171},
+ {0x96e8, 0x696b}, {0x96e9, 0x696c}, {0x96ea, 0x6064},
+ {0x96ef, 0x5a27}, {0x96f0, 0x5d54}, {0x96f2, 0x6a23},
+ {0x96f6, 0x5643}, {0x96f7, 0x5674}, {0x96f9, 0x5a5f},
+ {0x96fb, 0x6f33}, {0x9700, 0x624d}, {0x9706, 0x6f7d},
+ {0x9707, 0x7268}, {0x9711, 0x6f45}, {0x9713, 0x6767},
+ {0x9716, 0x577d}, {0x9719, 0x674e}, {0x971c, 0x5f5c},
+ {0x971e, 0x7947}, {0x9727, 0x5976}, {0x9730, 0x5f2c},
+ {0x9732, 0x565a}, {0x9739, 0x5c24}, {0x973d, 0x7038},
+ {0x9742, 0x557a}, {0x9744, 0x6477}, {0x9748, 0x5644},
+ {0x9751, 0x746c}, {0x9756, 0x6f7e}, {0x975c, 0x7021},
+ {0x975e, 0x5e2a}, {0x9761, 0x5a3c}, {0x9762, 0x587c},
+ {0x9769, 0x7a54}, {0x976d, 0x6c65}, {0x9774, 0x7c28},
+ {0x9777, 0x6c66}, {0x977a, 0x584b}, {0x978b, 0x7b39},
+ {0x978d, 0x6453}, {0x978f, 0x4d79}, {0x97a0, 0x4f53},
+ {0x97a8, 0x4a6a}, {0x97ab, 0x4f54}, {0x97ad, 0x783d},
+ {0x97c6, 0x7447}, {0x97cb, 0x6a5f}, {0x97d3, 0x795b},
+ {0x97dc, 0x5437}, {0x97f3, 0x6b65}, {0x97f6, 0x6152},
+ {0x97fb, 0x6a24}, {0x97ff, 0x7a42}, {0x9800, 0x7b61},
+ {0x9801, 0x7a6d}, {0x9802, 0x7022}, {0x9803, 0x4c71},
+ {0x9805, 0x7a23}, {0x9806, 0x6277}, {0x9808, 0x624e},
+ {0x980a, 0x6975}, {0x980c, 0x616b}, {0x9810, 0x6768},
+ {0x9811, 0x6857}, {0x9812, 0x5a78}, {0x9813, 0x544b},
+ {0x9817, 0x7776}, {0x9818, 0x5645}, {0x982d, 0x5469},
+ {0x9830, 0x7a7a}, {0x9838, 0x4c72}, {0x9839, 0x775d},
+ {0x983b, 0x5e3a}, {0x9846, 0x4e28}, {0x984c, 0x7039},
+ {0x984d, 0x647e}, {0x984e, 0x6449}, {0x9854, 0x6454},
+ {0x9858, 0x6a43}, {0x985a, 0x6f34}, {0x985e, 0x573e},
+ {0x9865, 0x7b62}, {0x9867, 0x4d53}, {0x986b, 0x6f35},
+ {0x986f, 0x7a69}, {0x98a8, 0x7926}, {0x98af, 0x5f3d},
+ {0x98b1, 0x7747}, {0x98c4, 0x787d}, {0x98c7, 0x787c},
+ {0x98db, 0x5e2b}, {0x98dc, 0x5b68}, {0x98df, 0x635d},
+ {0x98e1, 0x6162}, {0x98e2, 0x5146}, {0x98ed, 0x7650},
+ {0x98ee, 0x6b66}, {0x98ef, 0x5a79}, {0x98f4, 0x6c47},
+ {0x98fc, 0x5e78}, {0x98fd, 0x7869}, {0x98fe, 0x635e},
+ {0x9903, 0x4e75}, {0x9909, 0x7a43}, {0x990a, 0x6557},
+ {0x990c, 0x6c48}, {0x9910, 0x7349}, {0x9913, 0x643b},
+ {0x9918, 0x662e}, {0x991e, 0x6f36}, {0x9920, 0x5c3f},
+ {0x9928, 0x4e3d}, {0x9945, 0x5843}, {0x9949, 0x504f},
+ {0x994b, 0x4f7a}, {0x994c, 0x734a}, {0x994d, 0x6057},
+ {0x9951, 0x5147}, {0x9952, 0x692e}, {0x9954, 0x683d},
+ {0x9957, 0x7a44}, {0x9996, 0x624f}, {0x9999, 0x7a45},
+ {0x999d, 0x7938}, {0x99a5, 0x5c60}, {0x99a8, 0x7b30},
+ {0x99ac, 0x5829}, {0x99ad, 0x655f}, {0x99ae, 0x7927},
+ {0x99b1, 0x766e}, {0x99b3, 0x764c}, {0x99b4, 0x6278},
+ {0x99b9, 0x6c71}, {0x99c1, 0x5a60}, {0x99d0, 0x7152},
+ {0x99d1, 0x524c}, {0x99d2, 0x4f4b}, {0x99d5, 0x4a3d},
+ {0x99d9, 0x5d3f}, {0x99dd, 0x766f}, {0x99df, 0x5e79},
+ {0x99ed, 0x7a34}, {0x99f1, 0x552d}, {0x99ff, 0x7167},
+ {0x9a01, 0x5e3e}, {0x9a08, 0x5c40}, {0x9a0e, 0x5148},
+ {0x9a0f, 0x5149}, {0x9a19, 0x783e}, {0x9a2b, 0x4b76},
+ {0x9a30, 0x5479}, {0x9a36, 0x7562}, {0x9a37, 0x6153},
+ {0x9a40, 0x5869}, {0x9a43, 0x787e}, {0x9a45, 0x4f4c},
+ {0x9a4d, 0x7d24}, {0x9a55, 0x4e76}, {0x9a57, 0x7a50},
+ {0x9a5a, 0x4c73}, {0x9a5b, 0x663e}, {0x9a5f, 0x762e},
+ {0x9a62, 0x5570}, {0x9a65, 0x514a}, {0x9a69, 0x7c3e},
+ {0x9a6a, 0x5571}, {0x9aa8, 0x4d69}, {0x9ab8, 0x7a35},
+ {0x9ad3, 0x6250}, {0x9ad4, 0x7477}, {0x9ad8, 0x4d54},
+ {0x9ae5, 0x6723}, {0x9aee, 0x5b25}, {0x9b1a, 0x6251},
+ {0x9b27, 0x5722}, {0x9b2a, 0x7763}, {0x9b31, 0x6a26},
+ {0x9b3c, 0x5021}, {0x9b41, 0x4e5a}, {0x9b42, 0x7b6b},
+ {0x9b43, 0x5b26}, {0x9b44, 0x5b5e}, {0x9b45, 0x5865},
+ {0x9b4f, 0x6a60}, {0x9b54, 0x582a}, {0x9b5a, 0x6560},
+ {0x9b6f, 0x565b}, {0x9b8e, 0x6f46}, {0x9b91, 0x786a},
+ {0x9b9f, 0x6455}, {0x9bab, 0x4e77}, {0x9bae, 0x6058},
+ {0x9bc9, 0x576f}, {0x9bd6, 0x746d}, {0x9be4, 0x4d66},
+ {0x9be8, 0x4c74}, {0x9c0d, 0x7563}, {0x9c10, 0x644a},
+ {0x9c12, 0x5c61}, {0x9c15, 0x7948}, {0x9c25, 0x7c3f},
+ {0x9c32, 0x6827}, {0x9c3b, 0x5844}, {0x9c47, 0x4b3e},
+ {0x9c49, 0x5c2e}, {0x9c57, 0x5777}, {0x9ce5, 0x7068},
+ {0x9ce7, 0x5d40}, {0x9ce9, 0x4f4d}, {0x9cf3, 0x5c73},
+ {0x9cf4, 0x5930}, {0x9cf6, 0x6669}, {0x9d09, 0x643c},
+ {0x9d1b, 0x6a44}, {0x9d26, 0x646c}, {0x9d28, 0x6465},
+ {0x9d3b, 0x7b78}, {0x9d51, 0x4c3b}, {0x9d5d, 0x643d},
+ {0x9d60, 0x4d5c}, {0x9d61, 0x5977}, {0x9d6c, 0x5d5f},
+ {0x9d72, 0x6d4e}, {0x9da9, 0x5950}, {0x9daf, 0x6523},
+ {0x9db4, 0x794d}, {0x9dc4, 0x4d2e}, {0x9dd7, 0x4f4e},
+ {0x9df2, 0x762f}, {0x9df8, 0x7d53}, {0x9df9, 0x6b6d},
+ {0x9dfa, 0x565c}, {0x9e1a, 0x6524}, {0x9e1e, 0x5536},
+ {0x9e75, 0x565d}, {0x9e79, 0x7969}, {0x9e7d, 0x6724},
+ {0x9e7f, 0x5663}, {0x9e92, 0x514b}, {0x9e93, 0x5664},
+ {0x9e97, 0x5572}, {0x9e9d, 0x5e7a}, {0x9e9f, 0x5778},
+ {0x9ea5, 0x586a}, {0x9eb4, 0x4f55}, {0x9eb5, 0x587d},
+ {0x9ebb, 0x582b}, {0x9ebe, 0x7d4b}, {0x9ec3, 0x7c5c},
+ {0x9ecd, 0x6028}, {0x9ece, 0x5573}, {0x9ed1, 0x7d59},
+ {0x9ed4, 0x4c23}, {0x9ed8, 0x5979}, {0x9edb, 0x536a},
+ {0x9edc, 0x7575}, {0x9ede, 0x6f47}, {0x9ee8, 0x535a},
+ {0x9ef4, 0x5a3d}, {0x9f07, 0x6828}, {0x9f08, 0x5c2f},
+ {0x9f0e, 0x7023}, {0x9f13, 0x4d55}, {0x9f20, 0x6029},
+ {0x9f3b, 0x5e2c}, {0x9f4a, 0x703a}, {0x9f4b, 0x6e31},
+ {0x9f4e, 0x6e32}, {0x9f52, 0x764d}, {0x9f5f, 0x6e52},
+ {0x9f61, 0x5646}, {0x9f67, 0x6065}, {0x9f6a, 0x733b},
+ {0x9f6c, 0x6561}, {0x9f77, 0x644b}, {0x9f8d, 0x5723},
+ {0x9f90, 0x5b42}, {0x9f95, 0x4a7e}, {0x9f9c, 0x4f4f},
+ {0xf900, 0x4b50}, {0xf901, 0x4b56}, {0xf902, 0x4b67},
+ {0xf903, 0x4d4f}, {0xf904, 0x4d68}, {0xf905, 0x4e2d},
+ {0xf906, 0x4f7b}, {0xf907, 0x5022}, {0xf908, 0x5038},
+ {0xf909, 0x5050}, {0xf90a, 0x505d}, {0xf90b, 0x5154},
+ {0xf90c, 0x5155}, {0xf90d, 0x5158}, {0xf90e, 0x515b},
+ {0xf90f, 0x515c}, {0xf910, 0x515d}, {0xf911, 0x515e},
+ {0xf912, 0x515f}, {0xf913, 0x5160}, {0xf914, 0x5162},
+ {0xf915, 0x5163}, {0xf916, 0x5164}, {0xf917, 0x5165},
+ {0xf918, 0x5166}, {0xf919, 0x5168}, {0xf91a, 0x5169},
+ {0xf91b, 0x516a}, {0xf91c, 0x516b}, {0xf91d, 0x516d},
+ {0xf91e, 0x516f}, {0xf91f, 0x5170}, {0xf920, 0x5172},
+ {0xf921, 0x5176}, {0xf922, 0x517a}, {0xf923, 0x517c},
+ {0xf924, 0x517d}, {0xf925, 0x517e}, {0xf926, 0x5222},
+ {0xf927, 0x5223}, {0xf928, 0x5227}, {0xf929, 0x5228},
+ {0xf92a, 0x5229}, {0xf92b, 0x522a}, {0xf92c, 0x522b},
+ {0xf92d, 0x522d}, {0xf92e, 0x5232}, {0xf92f, 0x523e},
+ {0xf930, 0x5242}, {0xf931, 0x5243}, {0xf932, 0x5244},
+ {0xf933, 0x5246}, {0xf934, 0x5247}, {0xf935, 0x5248},
+ {0xf936, 0x5249}, {0xf937, 0x524a}, {0xf938, 0x524b},
+ {0xf939, 0x524d}, {0xf93a, 0x524e}, {0xf93b, 0x524f},
+ {0xf93c, 0x5250}, {0xf93d, 0x5251}, {0xf93e, 0x5252},
+ {0xf93f, 0x5253}, {0xf940, 0x5254}, {0xf941, 0x5255},
+ {0xf942, 0x5256}, {0xf943, 0x5257}, {0xf944, 0x5259},
+ {0xf945, 0x525a}, {0xf946, 0x525e}, {0xf947, 0x525f},
+ {0xf948, 0x5261}, {0xf949, 0x5262}, {0xf94a, 0x5264},
+ {0xf94b, 0x5265}, {0xf94c, 0x5266}, {0xf94d, 0x5267},
+ {0xf94e, 0x5268}, {0xf94f, 0x5269}, {0xf950, 0x526a},
+ {0xf951, 0x526b}, {0xf952, 0x5270}, {0xf953, 0x5271},
+ {0xf954, 0x5272}, {0xf955, 0x5273}, {0xf956, 0x5274},
+ {0xf957, 0x5275}, {0xf958, 0x5277}, {0xf959, 0x5278},
+ {0xf95a, 0x5466}, {0xf95b, 0x547c}, {0xf95c, 0x5525},
+ {0xf95d, 0x552b}, {0xf95e, 0x552e}, {0xf95f, 0x5638},
+ {0xf960, 0x564d}, {0xf961, 0x574b}, {0xf962, 0x5764},
+ {0xf963, 0x5b45}, {0xf964, 0x5b64}, {0xf965, 0x5c25},
+ {0xf966, 0x5d25}, {0xf967, 0x5d55}, {0xf968, 0x5d74},
+ {0xf969, 0x5e7c}, {0xf96a, 0x5e7e}, {0xf96b, 0x5f33},
+ {0xf96c, 0x5f61}, {0xf96d, 0x5f68}, {0xf96e, 0x6071},
+ {0xf96f, 0x612d}, {0xf970, 0x616d}, {0xf971, 0x6375},
+ {0xf972, 0x6421}, {0xf973, 0x6429}, {0xf974, 0x652e},
+ {0xf975, 0x6531}, {0xf976, 0x6532}, {0xf977, 0x6539},
+ {0xf978, 0x653b}, {0xf979, 0x653c}, {0xf97a, 0x6544},
+ {0xf97b, 0x654e}, {0xf97c, 0x6550}, {0xf97d, 0x6552},
+ {0xf97e, 0x6556}, {0xf97f, 0x657a}, {0xf980, 0x657b},
+ {0xf981, 0x657c}, {0xf982, 0x657e}, {0xf983, 0x6621},
+ {0xf984, 0x6624}, {0xf985, 0x6627}, {0xf986, 0x662d},
+ {0xf987, 0x662f}, {0xf988, 0x6630}, {0xf989, 0x6631},
+ {0xf98a, 0x6633}, {0xf98b, 0x6637}, {0xf98c, 0x6638},
+ {0xf98d, 0x663c}, {0xf98e, 0x6644}, {0xf98f, 0x6646},
+ {0xf990, 0x6647}, {0xf991, 0x664a}, {0xf992, 0x6652},
+ {0xf993, 0x6656}, {0xf994, 0x6659}, {0xf995, 0x665c},
+ {0xf996, 0x665f}, {0xf997, 0x6661}, {0xf998, 0x6664},
+ {0xf999, 0x6665}, {0xf99a, 0x6666}, {0xf99b, 0x6668},
+ {0xf99c, 0x666a}, {0xf99d, 0x666b}, {0xf99e, 0x666c},
+ {0xf99f, 0x666f}, {0xf9a0, 0x6671}, {0xf9a1, 0x6672},
+ {0xf9a2, 0x6675}, {0xf9a3, 0x6676}, {0xf9a4, 0x6677},
+ {0xf9a5, 0x6679}, {0xf9a6, 0x6721}, {0xf9a7, 0x6726},
+ {0xf9a8, 0x6729}, {0xf9a9, 0x672a}, {0xf9aa, 0x672c},
+ {0xf9ab, 0x672d}, {0xf9ac, 0x6730}, {0xf9ad, 0x673f},
+ {0xf9ae, 0x6741}, {0xf9af, 0x6746}, {0xf9b0, 0x6747},
+ {0xf9b1, 0x674b}, {0xf9b2, 0x674d}, {0xf9b3, 0x674f},
+ {0xf9b4, 0x6750}, {0xf9b5, 0x6753}, {0xf9b6, 0x675f},
+ {0xf9b7, 0x6764}, {0xf9b8, 0x6766}, {0xf9b9, 0x6777},
+ {0xf9ba, 0x6867}, {0xf9bb, 0x6868}, {0xf9bc, 0x6870},
+ {0xf9bd, 0x6871}, {0xf9be, 0x6877}, {0xf9bf, 0x6879},
+ {0xf9c0, 0x687b}, {0xf9c1, 0x687e}, {0xf9c2, 0x6927},
+ {0xf9c3, 0x692c}, {0xf9c4, 0x694c}, {0xf9c5, 0x6977},
+ {0xf9c6, 0x6a41}, {0xf9c7, 0x6a65}, {0xf9c8, 0x6a74},
+ {0xf9c9, 0x6a77}, {0xf9ca, 0x6a7c}, {0xf9cb, 0x6a7e},
+ {0xf9cc, 0x6b24}, {0xf9cd, 0x6b27}, {0xf9ce, 0x6b29},
+ {0xf9cf, 0x6b2a}, {0xf9d0, 0x6b3a}, {0xf9d1, 0x6b3b},
+ {0xf9d2, 0x6b3d}, {0xf9d3, 0x6b41}, {0xf9d4, 0x6b42},
+ {0xf9d5, 0x6b46}, {0xf9d6, 0x6b47}, {0xf9d7, 0x6b4c},
+ {0xf9d8, 0x6b4f}, {0xf9d9, 0x6b50}, {0xf9da, 0x6b51},
+ {0xf9db, 0x6b52}, {0xf9dc, 0x6b58}, {0xf9dd, 0x6c26},
+ {0xf9de, 0x6c27}, {0xf9df, 0x6c2a}, {0xf9e0, 0x6c2f},
+ {0xf9e1, 0x6c30}, {0xf9e2, 0x6c31}, {0xf9e3, 0x6c32},
+ {0xf9e4, 0x6c35}, {0xf9e5, 0x6c38}, {0xf9e6, 0x6c3a},
+ {0xf9e7, 0x6c40}, {0xf9e8, 0x6c41}, {0xf9e9, 0x6c45},
+ {0xf9ea, 0x6c46}, {0xf9eb, 0x6c49}, {0xf9ec, 0x6c4a},
+ {0xf9ed, 0x6c55}, {0xf9ee, 0x6c5d}, {0xf9ef, 0x6c5e},
+ {0xf9f0, 0x6c61}, {0xf9f1, 0x6c64}, {0xf9f2, 0x6c67},
+ {0xf9f3, 0x6c68}, {0xf9f4, 0x6c77}, {0xf9f5, 0x6c78},
+ {0xf9f6, 0x6c7a}, {0xf9f7, 0x6d21}, {0xf9f8, 0x6d22},
+ {0xf9f9, 0x6d23}, {0xf9fa, 0x6d6e}, {0xf9fb, 0x6e5b},
+ {0xf9fc, 0x723d}, {0xf9fd, 0x727a}, {0xf9fe, 0x7331},
+ {0xf9ff, 0x7427}, {0xfa00, 0x746e}, {0xfa01, 0x7674},
+ {0xfa02, 0x7676}, {0xfa03, 0x7738}, {0xfa04, 0x7748},
+ {0xfa05, 0x7753}, {0xfa06, 0x785b}, {0xfa07, 0x7870},
+ {0xfa08, 0x7a21}, {0xfa09, 0x7a22}, {0xfa0a, 0x7a66},
+ {0xfa0b, 0x7c29}
+};
+
+
+static unsigned short ksc2tqunicode( unsigned short code )
+{
+ int ch1 = code >> 8;
+ int ch2 = code & 0x00ff;
+ int idx;
+
+ if (ch1 < 0x80 || (ch1 - 0x80) <= 0x20 || (ch1 - 0x80) >= 0x7e
+ || (ch1 - 0x80) == 0x49)
+ return 0;
+
+ if (ch2 < 0x80 || (ch2 - 0x80) <= 0x20 || (ch2 - 0x80) >= 0x7f)
+ return 0;
+
+ idx = (ch1 - 0x80 - 0x21) * 94 + (ch2 - 0x80 - 0x21);
+
+ /* Hangul : row 16 - row 40 : 1410 = 15 * 94 ,
+ 3760 = 40 * 94 */
+ if (idx >= 1410 && idx < 1410 + 2350)
+ return (ksc5601_hangul_to_tqunicode[idx - 1410]);
+
+ else if (idx >= 3854)
+ /* Hanja : row 42 - row 93 : 3854 = 94 * (42-1) */
+ return (ksc5601_hanja_to_tqunicode[idx - 3854]);
+
+ else if(idx <= 1114)
+ return (ksc5601_symbol_to_tqunicode[idx]);
+
+ return 0;
+}
+
+static unsigned short tqunicode2ksc(unsigned short tqunicode)
+{
+ int lo, hi, mid, c2;
+ unsigned char s[2];
+
+ lo = mid = c2 = 0;
+
+ if (tqunicode >= 0xac00 && tqunicode <= 0xd7a3) {
+ // Hangul
+ hi = 2349;
+
+ while (lo <= hi) { // binary search
+ mid = (lo + hi) / 2;
+ c2 = ksc5601_hangul_to_tqunicode[mid];
+ if(tqunicode < c2)
+ hi = mid - 1;
+ else if(tqunicode > c2)
+ lo = mid + 1;
+ else { // tqunicode == c2
+ s[0] = (mid / 94) + 0x30;
+ s[1] = (mid % 94) + 0x21;
+
+ return ( (s[0] << 8) | s[1] );
+ }
+ }
+ } else if ((tqunicode >= 0x4e00 && tqunicode <= 0x9fff)
+ || (tqunicode >= 0xf900 && tqunicode <= 0xfa0b)) {
+ // Hanja
+ hi = 4887;
+
+ while (lo <= hi) { // binary search
+ mid = (lo + hi) / 2;
+ c2 = tqunicode_to_ksc5601_hanja[mid].tqunicode;
+ if(tqunicode < c2)
+ hi = mid - 1;
+ else if(tqunicode > c2)
+ lo = mid + 1;
+ else { // tqunicode == c2
+ return tqunicode_to_ksc5601_hanja[mid].kscode;
+ }
+ }
+ } else {
+ // Symbol
+ hi = 985;
+
+ while (lo <= hi) { // binary search
+ mid = (lo + hi) / 2;
+ c2 = tqunicode_to_ksc5601_symbol[mid].tqunicode;
+ if(tqunicode < c2)
+ hi = mid - 1;
+ else if(tqunicode > c2)
+ lo = mid + 1;
+ else { // tqunicode == c2
+ return tqunicode_to_ksc5601_symbol[mid].kscode;
+ }
+ }
+ }
+ return 0;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqeuckrcodec.h b/tqtinterface/qt4/src/codecs/tqeuckrcodec.h
new file mode 100644
index 0000000..c53f812
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqeuckrcodec.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Definition of TQEucKrCodec class
+**
+** Created : 990303
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/*
+ * Copyright (C) 1999-2000 Mizi Research Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef TQEUCKRCODEC_H
+#define TQEUCKRCODEC_H
+
+#ifndef TQT_H
+#include "tqtextcodec.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_BIG_CODECS
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_CODECS_KR
+#else
+#define TQ_EXPORT_CODECS_KR TQ_EXPORT
+#endif
+
+class TQ_EXPORT_CODECS_KR TQEucKrCodec : public TQTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+ const char* mimeName() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+};
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqfontcncodec.cpp b/tqtinterface/qt4/src/codecs/tqfontcncodec.cpp
new file mode 100644
index 0000000..89b2f7b
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqfontcncodec.cpp
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Chinese Font utilities for X11
+**
+** Created : 20010130
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "private/tqfontcodecs_p.h"
+
+#ifndef TQT_NO_CODECS
+#ifndef TQT_NO_BIG_CODECS
+
+
+extern int qt_UnicodeToGbk(uint tqunicode, uchar *gbchar);
+
+
+int TQFontGb2312Codec::heuristicContentMatch(const char *, int) const
+{
+ return 0;
+}
+
+
+TQFontGb2312Codec::TQFontGb2312Codec()
+{
+ //qDebug("TQFontGb2312Codec::TQFontGb2312Codec()");
+}
+
+
+const char* TQFontGb2312Codec::name() const
+{
+ //qDebug("TQFontGb2312Codec::name() = \"gb2312.1980-0\"");
+ return "gb2312.1980-0";
+}
+
+
+int TQFontGb2312Codec::mibEnum() const
+{
+ //qDebug("TQFontGb2312Codec::mibEnum() = 57");
+ return 57;
+}
+
+
+TQString TQFontGb2312Codec::toUnicode(const char* /*chars*/, int /*len*/) const
+{
+ return TQString::null;
+}
+
+unsigned short TQFontGb2312Codec::characterFromUnicode(const TQString &str, int pos) const
+{
+ uchar buf[4];
+ int len = qt_UnicodeToGbk((str.tqunicode() + pos)->tqunicode(), buf);
+ if (len == 2 && buf[0] > 0xa0 && buf[1] > 0xa0)
+ return ((buf[0] & 0x7f) << 8) + (buf[1] & 0x7f);
+ return 0;
+}
+
+TQCString TQFontGb2312Codec::fromUnicode(const TQString& uc, int& lenInOut ) const
+{
+ TQCString result(lenInOut * 2 + 1);
+ uchar *rdata = (uchar *) result.data();
+ const TQChar *ucp = uc.tqunicode();
+
+ //qDebug("TQFontGb2312Codec::fromUnicode(const TQString& uc, int& lenInOut = %d)", lenInOut);
+ for ( int i = 0; i < lenInOut; i++ ) {
+ TQChar ch(*ucp++);
+ uchar buf[8];
+
+ int len = qt_UnicodeToGbk( ch.tqunicode(), buf );
+
+ if ( len == 2 && buf[0] > 0xa0 && buf[1] > 0xa0 ) {
+ *rdata++ = buf[0] & 0x7f;
+ *rdata++ = buf[1] & 0x7f;
+ } else {
+ //white square
+ *rdata++ = 0x21;
+ *rdata++ = 0x75;
+ }
+ }
+
+ lenInOut *= 2;
+
+ return result;
+}
+
+void TQFontGb2312Codec::fromUnicode(const TQChar *in, unsigned short *out, int length) const
+{
+ int len;
+ uchar buf[8];
+ while (length--) {
+ len = qt_UnicodeToGbk(in->tqunicode(), buf);
+ if ( len == 2 && buf[0] > 0xa0 && buf[1] > 0xa0 ) {
+ *out = (((buf[0] << 8) | buf[1]) & 0x7f7f);
+ } else {
+ *out = 0;
+ }
+
+ ++in;
+ ++out;
+ }
+}
+
+
+bool TQFontGb2312Codec::canEncode( TQChar ch ) const
+{
+ uchar buf[4];
+ int len = qt_UnicodeToGbk( ch.tqunicode(), buf );
+ //qDebug("TQFontGb2312Codec::canEncode( TQChar ch = %02X%02X )", ch.row(), ch.cell());
+ return ( len == 2 && buf[0] > 0xa0 && buf[1] > 0xa0 );
+}
+
+//==========================================================================
+
+
+int TQFontGbkCodec::heuristicContentMatch(const char *, int) const
+{
+ return 0;
+}
+
+
+int TQFontGbkCodec::heuristicNameMatch(const char* hint) const
+{
+ //qDebug("TQFontGbkCodec::heuristicNameMatch(const char* hint = \"%s\")", hint);
+ return ( qstricmp(hint, "gbk-0") == 0 ||
+ qstricmp(hint, "gb18030.2000-0") == 0 )
+ ? 13 : 0;
+}
+
+
+TQFontGbkCodec::TQFontGbkCodec()
+{
+ //qDebug("TQFontGbkCodec::TQFontGbkCodec()");
+}
+
+
+const char* TQFontGbkCodec::name() const
+{
+ //qDebug("TQFontGbkCodec::name() = \"gbk-0\"");
+ return "gbk-0";
+}
+
+
+int TQFontGbkCodec::mibEnum() const
+{
+ //qDebug("TQFontGbkCodec::mibEnum() = -113");
+ return -113;
+}
+
+
+TQString TQFontGbkCodec::toUnicode(const char* /*chars*/, int /*len*/) const
+{
+ return TQString::null;
+}
+
+unsigned short TQFontGbkCodec::characterFromUnicode(const TQString &str, int pos) const
+{
+ uchar buf[4];
+ int len = qt_UnicodeToGbk((str.tqunicode() + pos)->tqunicode(), buf);
+ if (len == 2)
+ return (buf[0] << 8) + buf[1];
+ return 0;
+}
+
+TQCString TQFontGbkCodec::fromUnicode(const TQString& uc, int& lenInOut ) const
+{
+ TQCString result(lenInOut * 2 + 1);
+ uchar *rdata = (uchar *) result.data();
+ const TQChar *ucp = uc.tqunicode();
+
+ //qDebug("TQFontGbkCodec::fromUnicode(const TQString& uc, int& lenInOut = %d)", lenInOut);
+ for ( int i = 0; i < lenInOut; i++ ) {
+ TQChar ch(*ucp++);
+ uchar buf[8];
+
+ int len = qt_UnicodeToGbk( ch.tqunicode(), buf );
+
+ if ( len == 2 ) {
+ *rdata++ = buf[0];
+ *rdata++ = buf[1];
+ } else {
+ //white square
+ *rdata++ = 0xa1;
+ *rdata++ = 0xf5;
+ }
+ }
+
+ lenInOut *= 2;
+
+ return result;
+}
+
+void TQFontGbkCodec::fromUnicode(const TQChar *in, unsigned short *out, int length) const
+{
+ uchar buf[8];
+ while (length--) {
+ *out++ = (qt_UnicodeToGbk(in->tqunicode(), buf) == 2) ? (buf[0] << 8) | buf[1] : 0;
+ ++in;
+ }
+}
+
+bool TQFontGbkCodec::canEncode( TQChar ch ) const
+{
+ if (ch.tqunicode() >= 0x4e00 && ch.tqunicode() <= 0x9fa5)
+ return TRUE;
+ uchar buf[4];
+ int len = qt_UnicodeToGbk( ch.tqunicode(), buf );
+ //qDebug("TQFontGbkCodec::canEncode( TQChar ch = %02X%02X )", ch.row(), ch.cell());
+ return ( len == 2 );
+}
+
+//==========================================================================
+
+int TQFontGb18030_0Codec::heuristicContentMatch(const char *, int) const
+{
+ return 0;
+}
+
+
+TQFontGb18030_0Codec::TQFontGb18030_0Codec()
+{
+ //qDebug("TQFontGb18030_0Codec::TQFontGb18030_0Codec()");
+}
+
+
+const char* TQFontGb18030_0Codec::name() const
+{
+ //qDebug("TQFontGb18030_0Codec::name() = \"gb18030-0\"");
+ return "gb18030-0";
+}
+
+
+int TQFontGb18030_0Codec::mibEnum() const
+{
+ //qDebug("TQFontGb18030_0Codec::mibEnum() = -114");
+ return -114;
+}
+
+
+TQString TQFontGb18030_0Codec::toUnicode(const char* /*chars*/, int /*len*/) const
+{
+ return TQString::null;
+}
+
+unsigned short
+TQFontGb18030_0Codec::characterFromUnicode(const TQString &str, int pos) const
+{
+ const TQChar * const ch = str.tqunicode() + pos;
+ if (ch->row () > 0 && !(ch->row () >= 0xd8 && ch->row () < 0xe0))
+ return ch->tqunicode();
+ return 0;
+}
+
+TQCString TQFontGb18030_0Codec::fromUnicode(const TQString& uc, int& lenInOut ) const
+{
+ TQCString result(lenInOut * 2 + 1);
+ uchar *rdata = (uchar *) result.data();
+ const TQChar *ucp = uc.tqunicode();
+
+ //qDebug("TQFontGb18030_0Codec::fromUnicode(const TQString& uc, int& lenInOut = %d)", lenInOut);
+ for ( int i = 0; i < lenInOut; i++ ) {
+ TQChar ch(*ucp++);
+ if (ch.row () > 0 && !(ch.row () >= 0xd8 && ch.row () < 0xe0)) {
+ *rdata++ = ch.row();
+ *rdata++ = ch.cell();
+ } else {
+ *rdata++ = 0xff;
+ *rdata++ = 0xfd;
+ }
+ }
+
+ lenInOut *= 2;
+
+ return result;
+}
+
+void TQFontGb18030_0Codec::fromUnicode(const TQChar *in, unsigned short *out, int length) const
+{
+ while (length--) {
+ *out = ((in->row () > 0 && !(in->row () >= 0xd8 && in->row () < 0xe0))
+ ? in->tqunicode() : 0);
+ ++in;
+ ++out;
+ }
+}
+
+bool TQFontGb18030_0Codec::canEncode( TQChar ch ) const
+{
+ //qDebug("TQFontGb18030_0Codec::canEncode( TQChar ch = %02X%02X )", ch.row(), ch.cell());
+ return (ch.row () > 0 && !(ch.row () >= 0xd8 && ch.row () < 0xe0));
+}
+
+//==========================================================================
+
+
+#endif // TQT_NO_BIG_CODECS
+#endif // TQT_NO_CODECS
diff --git a/tqtinterface/qt4/src/codecs/tqfontcodecs_p.h b/tqtinterface/qt4/src/codecs/tqfontcodecs_p.h
new file mode 100644
index 0000000..c01cb4b
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqfontcodecs_p.h
@@ -0,0 +1,384 @@
+/****************************************************************************
+**
+** Font utilities for X11
+**
+** Created : 20001101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFONTCODECS_P_H
+#define TQFONTCODECS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qfontencodings_x11.cpp and qfont_x11.cpp. This header file may
+// change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqtextcodec.h"
+#endif // TQT_H
+
+
+#ifndef TQT_NO_CODECS
+#ifndef TQT_NO_BIG_CODECS
+
+
+class TQJpUnicodeConv;
+
+
+class TQFontJis0201Codec : public TQTextCodec
+{
+public:
+ TQFontJis0201Codec();
+
+ const char *name() const;
+
+ int mibEnum() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ int heuristicContentMatch(const char *, int) const;
+ int heuristicNameMatch(const char* hint) const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::canEncode;
+#endif
+ bool canEncode( TQChar ) const;
+};
+
+
+class TQFontJis0208Codec : public TQTextCodec
+{
+public:
+ TQFontJis0208Codec();
+ ~TQFontJis0208Codec();
+
+ // Return the official name for the encoding.
+ const char* name() const ;
+
+ // Return the MIB enum for the encoding if it is listed in the
+ // IANA character-sets encoding file.
+ int mibEnum() const ;
+
+ // Converts len characters from chars to Unicode.
+ TQString toUnicode(const char* chars, int len) const ;
+
+ // Converts lenInOut characters (of type TQChar) from the start of
+ // the string uc, returning a TQCString result, and also returning
+ // the length of the result in lenInOut.
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ int heuristicContentMatch(const char *, int) const;
+ int heuristicNameMatch(const char* hint) const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::canEncode;
+#endif
+ bool canEncode( TQChar ) const;
+
+private:
+ TQJpUnicodeConv *convJP;
+};
+
+
+
+
+class TQFontKsc5601Codec : public TQTextCodec
+{
+public:
+ TQFontKsc5601Codec();
+
+ // Return the official name for the encoding.
+ const char* name() const ;
+
+ // Return the MIB enum for the encoding if it is listed in the
+ // IANA character-sets encoding file.
+ int mibEnum() const ;
+
+ // Converts len characters from chars to Unicode.
+ TQString toUnicode(const char* chars, int len) const ;
+
+ // Converts lenInOut characters (of type TQChar) from the start of
+ // the string uc, returning a TQCString result, and also returning
+ // the length of the result in lenInOut.
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ int heuristicContentMatch(const char *, int) const;
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::canEncode;
+#endif
+ bool canEncode( TQChar ) const;
+};
+
+
+
+
+class TQFontGb2312Codec : public TQTextCodec
+{
+public:
+ TQFontGb2312Codec();
+
+ // Return the official name for the encoding.
+ const char* name() const ;
+
+ // Return the MIB enum for the encoding if it is listed in the
+ // IANA character-sets encoding file.
+ int mibEnum() const ;
+
+ // Converts len characters from chars to Unicode.
+ TQString toUnicode(const char* chars, int len) const ;
+
+ // Converts lenInOut characters (of type TQChar) from the start of
+ // the string uc, returning a TQCString result, and also returning
+ // the length of the result in lenInOut.
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ int heuristicContentMatch(const char *, int) const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::canEncode;
+#endif
+ bool canEncode( TQChar ) const;
+};
+
+
+
+
+class TQFontGbkCodec : public TQTextCodec
+{
+public:
+ TQFontGbkCodec();
+
+ // Return the official name for the encoding.
+ const char* name() const ;
+
+ // Return the MIB enum for the encoding if it is listed in the
+ // IANA character-sets encoding file.
+ int mibEnum() const ;
+
+ // Converts len characters from chars to Unicode.
+ TQString toUnicode(const char* chars, int len) const ;
+
+ // Converts lenInOut characters (of type TQChar) from the start of
+ // the string uc, returning a TQCString result, and also returning
+ // the length of the result in lenInOut.
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ int heuristicContentMatch(const char *, int) const;
+ int heuristicNameMatch(const char* hint) const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::canEncode;
+#endif
+ bool canEncode( TQChar ) const;
+};
+
+
+
+
+class TQFontGb18030_0Codec : public TQTextCodec
+{
+public:
+ TQFontGb18030_0Codec();
+
+ // Return the official name for the encoding.
+ const char* name() const ;
+
+ // Return the MIB enum for the encoding if it is listed in the
+ // IANA character-sets encoding file.
+ int mibEnum() const ;
+
+ // Converts len characters from chars to Unicode.
+ TQString toUnicode(const char* chars, int len) const ;
+
+ // Converts lenInOut characters (of type TQChar) from the start of
+ // the string uc, returning a TQCString result, and also returning
+ // the length of the result in lenInOut.
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ int heuristicContentMatch(const char *, int) const;
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::canEncode;
+#endif
+ bool canEncode( TQChar ) const;
+};
+
+
+
+
+class TQFontBig5Codec : public TQTextCodec
+{
+public:
+ TQFontBig5Codec();
+
+ // Return the official name for the encoding.
+ const char* name() const ;
+
+ // Return the MIB enum for the encoding if it is listed in the
+ // IANA character-sets encoding file.
+ int mibEnum() const ;
+
+ // Converts len characters from chars to Unicode.
+ TQString toUnicode(const char* chars, int len) const ;
+
+ // Converts lenInOut characters (of type TQChar) from the start of
+ // the string uc, returning a TQCString result, and also returning
+ // the length of the result in lenInOut.
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ int heuristicContentMatch(const char *, int) const;
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::canEncode;
+#endif
+ int heuristicNameMatch(const char* hint) const;
+ bool canEncode( TQChar ) const;
+};
+
+
+
+class TQFontBig5hkscsCodec : public TQTextCodec
+{
+public:
+ TQFontBig5hkscsCodec();
+
+ // Return the official name for the encoding.
+ const char* name() const ;
+
+ // Return the MIB enum for the encoding if it is listed in the
+ // IANA character-sets encoding file.
+ int mibEnum() const ;
+
+ // Converts len characters from chars to Unicode.
+ TQString toUnicode(const char* chars, int len) const ;
+
+ // Converts lenInOut characters (of type TQChar) from the start of
+ // the string uc, returning a TQCString result, and also returning
+ // the length of the result in lenInOut.
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ int heuristicContentMatch(const char *, int) const;
+ int heuristicNameMatch(const char* hint) const;
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::canEncode;
+#endif
+ bool canEncode( TQChar ) const;
+};
+
+
+class TQFontLaoCodec : public TQTextCodec
+{
+public:
+ TQFontLaoCodec();
+
+ const char *name() const;
+
+ int mibEnum() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ int heuristicContentMatch(const char *, int) const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::canEncode;
+#endif
+ bool canEncode( TQChar ) const;
+};
+
+#endif // TQT_NO_BIG_CODECS
+#endif // TQT_NO_CODECS
+
+#endif // TQFONTCODECS_P_H
diff --git a/tqtinterface/qt4/src/codecs/tqfonthkcodec.cpp b/tqtinterface/qt4/src/codecs/tqfonthkcodec.cpp
new file mode 100644
index 0000000..ef54ea8
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqfonthkcodec.cpp
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Hong Kong Font utilities for X11
+**
+** Created : 20020902
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "private/tqfontcodecs_p.h"
+
+#ifndef TQT_NO_CODECS
+#ifndef TQT_NO_BIG_CODECS
+
+extern int qt_UnicodeToBig5hkscs(uint wc, uchar *r);
+
+
+int TQFontBig5hkscsCodec::heuristicContentMatch(const char *, int) const
+{
+ return 0;
+}
+
+
+int TQFontBig5hkscsCodec::heuristicNameMatch(const char* hint) const
+{
+ //qDebug("TQFontBig5hkscsCodec::heuristicNameMatch(const char* hint = \"%s\")", hint);
+ return ( qstricmp(hint, "big5hkscs-0") == 0 ||
+ qstricmp(hint, "hkscs-1") == 0 )
+ ? 13 : 0;
+}
+
+
+TQFontBig5hkscsCodec::TQFontBig5hkscsCodec()
+{
+ //qDebug("TQFontBig5hkscsCodec::TQFontBig5hkscsCodec()");
+}
+
+
+const char* TQFontBig5hkscsCodec::name() const
+{
+ //qDebug("TQFontBig5hkscsCodec::name() = \"big5hkscs-0\"");
+ return "big5hkscs-0";
+}
+
+
+int TQFontBig5hkscsCodec::mibEnum() const
+{
+ //qDebug("TQFontBig5hkscsCodec::mibEnum() = -2101");
+ return -2101;
+}
+
+
+TQString TQFontBig5hkscsCodec::toUnicode(const char* /*chars*/, int /*len*/) const
+{
+ return TQString::null;
+}
+
+unsigned short
+TQFontBig5hkscsCodec::characterFromUnicode(const TQString &str, int pos) const
+{
+ uchar c[2];
+ if (qt_UnicodeToBig5hkscs((str.tqunicode() + pos)->tqunicode(), c) == 2)
+ return (c[0] << 8) + c[1];
+ return 0;
+}
+
+TQCString TQFontBig5hkscsCodec::fromUnicode(const TQString& uc, int& lenInOut ) const
+{
+ //qDebug("TQFontBig5hkscsCodec::fromUnicode(const TQString& uc, int& lenInOut = %d)", lenInOut);
+ TQCString result(lenInOut * 2 + 1);
+ uchar *rdata = (uchar *) result.data();
+ const TQChar *ucp = uc.tqunicode();
+
+ for ( int i = 0; i < lenInOut; i++ ) {
+ TQChar ch(*ucp++);
+ uchar c[2];
+
+#if 0
+ if ( ch.row() == 0) {
+ if ( ch.cell() == ' ' )
+ ch = TQChar( 0x3000 );
+ else if ( ch.cell() > ' ' && ch.cell() < 127 )
+ ch = TQChar( ch.cell()-' ', 255 );
+ }
+#endif
+ if ( qt_UnicodeToBig5hkscs( ch.tqunicode(), c ) == 2) {
+ *rdata++ = c[0];
+ *rdata++ = c[1];
+ } else {
+ //white square
+ *rdata++ = 0xa1;
+ *rdata++ = 0xbc;
+ }
+ }
+ lenInOut *=2;
+ return result;
+}
+
+
+/*! \internal */
+void TQFontBig5hkscsCodec::fromUnicode(const TQChar *in, unsigned short *out, int length) const
+{
+ uchar c[2];
+ while (length--) {
+ if ( in->row() == 0x00 && in->cell() < 0x80 ) {
+ // ASCII
+ *out = in->cell();
+ } else if ( qt_UnicodeToBig5hkscs( in->tqunicode(), c ) == 2 ) {
+ // Big5-HKSCS
+ *out = (c[0] << 8) | c[1];
+ } else {
+ // Unknown char
+ *out = 0;
+ }
+
+ ++in;
+ ++out;
+ }
+}
+
+bool TQFontBig5hkscsCodec::canEncode( TQChar ch ) const
+{
+ //qDebug("TQFontBig5hkscsCodec::canEncode( TQChar ch = %02X%02X )", ch.row(), ch.cell());
+ uchar c[2];
+ return ( qt_UnicodeToBig5hkscs( ch.tqunicode(), c ) == 2 );
+}
+
+#endif // TQT_NO_BIG_CODECS
+#endif // TQT_NO_CODECS
diff --git a/tqtinterface/qt4/src/codecs/tqfontjpcodec.cpp b/tqtinterface/qt4/src/codecs/tqfontjpcodec.cpp
new file mode 100644
index 0000000..d095fb6
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqfontjpcodec.cpp
@@ -0,0 +1,223 @@
+/****************************************************************************
+**
+** Japanese Font utilities for X11
+**
+** Created : 20010130
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "private/tqfontcodecs_p.h"
+
+#ifndef TQT_NO_CODECS
+#ifndef TQT_NO_BIG_CODECS
+#include "tqjpunicode.h"
+
+
+// JIS X 0201
+
+TQFontJis0201Codec::TQFontJis0201Codec()
+{
+}
+
+const char *TQFontJis0201Codec::name() const
+{
+ return "jisx0201*-0";
+}
+
+int TQFontJis0201Codec::mibEnum() const
+{
+ return 15;
+}
+
+unsigned short
+TQFontJis0201Codec::characterFromUnicode(const TQString &str, int pos) const
+{
+ const TQChar *c = str.tqunicode() + pos;
+ if ( c->tqunicode() < 0x80 )
+ return c->tqunicode();
+ if ( c->tqunicode() >= 0xff61 && c->tqunicode() <= 0xff9f )
+ return c->tqunicode() - 0xff61 + 0xa1;
+ return 0;
+}
+
+TQCString TQFontJis0201Codec::fromUnicode(const TQString& uc, int& lenInOut ) const
+{
+ TQCString rstring( lenInOut+1 );
+ uchar *rdata = (uchar *) rstring.data();
+ const TQChar *sdata = uc.tqunicode();
+ int i = 0;
+ for ( ; i < lenInOut; ++i, ++sdata, ++rdata ) {
+ if ( sdata->tqunicode() < 0x80 ) {
+ *rdata = (uchar) sdata->tqunicode();
+ } else if ( sdata->tqunicode() >= 0xff61 && sdata->tqunicode() <= 0xff9f ) {
+ *rdata = (uchar) (sdata->tqunicode() - 0xff61 + 0xa1);
+ } else {
+ *rdata = '?';
+ }
+ }
+ *rdata = 0u;
+ return rstring;
+}
+
+void TQFontJis0201Codec::fromUnicode(const TQChar *in, unsigned short *out, int length) const
+{
+ while (length--) {
+ if ( in->tqunicode() < 0x80 ) {
+ *out = (uchar) in->tqunicode();
+ } else if ( in->tqunicode() >= 0xff61 && in->tqunicode() <= 0xff9f ) {
+ *out = (uchar) (in->tqunicode() - 0xff61 + 0xa1);
+ } else {
+ *out = 0;
+ }
+
+ ++in;
+ ++out;
+ }
+}
+
+int TQFontJis0201Codec::heuristicNameMatch(const char* hint) const
+{
+ if ( tqstrncmp( hint, "jisx0201", 8 ) == 0 )
+ return 20;
+ return -1;
+
+}
+
+bool TQFontJis0201Codec::canEncode( TQChar ch ) const
+{
+ return ( ch.tqunicode() < 0x80 || ( ch.tqunicode() >= 0xff61 &&
+ ch.tqunicode() <= 0xff9f ) );
+}
+
+int TQFontJis0201Codec::heuristicContentMatch(const char *, int) const
+{
+ return 0;
+}
+
+
+// JIS X 0208
+
+int TQFontJis0208Codec::heuristicContentMatch(const char *, int) const
+{
+ return 0;
+}
+
+
+int TQFontJis0208Codec::heuristicNameMatch(const char *hint) const
+{
+ if ( tqstrncmp( hint, "jisx0208.", 9 ) == 0 )
+ return 20;
+ return -1;
+}
+
+TQFontJis0208Codec::TQFontJis0208Codec()
+{
+ convJP = TQJpUnicodeConv::newConverter(TQJpUnicodeConv::Default);
+}
+
+
+TQFontJis0208Codec::~TQFontJis0208Codec()
+{
+ delete convJP;
+ convJP = 0;
+}
+
+
+const char* TQFontJis0208Codec::name() const
+{
+ return "jisx0208*-0";
+}
+
+
+int TQFontJis0208Codec::mibEnum() const
+{
+ return 63;
+}
+
+
+TQString TQFontJis0208Codec::toUnicode(const char* /*chars*/, int /*len*/) const
+{
+ return TQString::null;
+}
+
+unsigned short TQFontJis0208Codec::characterFromUnicode(const TQString &str, int pos) const
+{
+ return convJP->tqunicodeToJisx0208((str.tqunicode() + pos)->tqunicode());
+}
+
+TQCString TQFontJis0208Codec::fromUnicode(const TQString& uc, int& lenInOut ) const
+{
+ TQCString result(lenInOut * 2 + 1);
+ uchar *rdata = (uchar *) result.data();
+ const TQChar *ucp = uc.tqunicode();
+
+ for ( int i = 0; i < lenInOut; i++ ) {
+ TQChar ch(*ucp++);
+ ch = convJP->tqunicodeToJisx0208(ch.tqunicode());
+
+ if ( ! ch.isNull() ) {
+ *rdata++ = ch.row();
+ *rdata++ = ch.cell();
+ } else {
+ //white square
+ *rdata++ = 0x22;
+ *rdata++ = 0x22;
+ }
+ }
+
+ lenInOut *= 2;
+
+ return result;
+}
+
+void TQFontJis0208Codec::fromUnicode(const TQChar *in, unsigned short *out, int length) const
+{
+ while (length--) {
+ *out++ = convJP->tqunicodeToJisx0208(in->tqunicode());
+ ++in;
+ }
+}
+
+
+bool TQFontJis0208Codec::canEncode( TQChar ch ) const
+{
+ return ( convJP->tqunicodeToJisx0208(ch.tqunicode()) != 0 );
+}
+
+
+
+
+#endif // TQT_NO_BIG_CODECS
+#endif // TQT_NO_CODECS
diff --git a/tqtinterface/qt4/src/codecs/tqfontkrcodec.cpp b/tqtinterface/qt4/src/codecs/tqfontkrcodec.cpp
new file mode 100644
index 0000000..22f95ed
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqfontkrcodec.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Korean Font utilities for X11
+**
+** Created : 20010130
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "private/tqfontcodecs_p.h"
+
+#ifndef TQT_NO_CODECS
+#ifndef TQT_NO_BIG_CODECS
+
+extern unsigned int qt_UnicodeToKsc5601(unsigned int tqunicode);
+
+
+int TQFontKsc5601Codec::heuristicContentMatch(const char *, int) const
+{
+ return 0;
+}
+
+
+TQFontKsc5601Codec::TQFontKsc5601Codec()
+{
+}
+
+
+const char* TQFontKsc5601Codec::name() const
+{
+ return "ksc5601.1987-0";
+}
+
+
+int TQFontKsc5601Codec::mibEnum() const
+{
+ return 36;
+}
+
+
+TQString TQFontKsc5601Codec::toUnicode(const char* /*chars*/, int /*len*/) const
+{
+ return TQString(); //###
+}
+
+unsigned short TQFontKsc5601Codec::characterFromUnicode(const TQString &str, int pos) const
+{
+ return qt_UnicodeToKsc5601((str.tqunicode() + pos)->tqunicode());
+}
+
+TQCString TQFontKsc5601Codec::fromUnicode(const TQString& uc, int& lenInOut ) const
+{
+ TQCString result(lenInOut * 2 + 1);
+ uchar *rdata = (uchar *) result.data();
+ const TQChar *ucp = uc.tqunicode();
+
+ for ( int i = 0; i < lenInOut; i++ ) {
+ TQChar ch(*ucp++);
+ ch = qt_UnicodeToKsc5601(ch.tqunicode());
+
+ if ( ! ch.isNull() ) {
+ *rdata++ = ch.row() & 0x7f ;
+ *rdata++ = ch.cell() & 0x7f;
+ } else {
+ //white square
+ *rdata++ = 0x21;
+ *rdata++ = 0x60;
+ }
+ }
+
+ lenInOut *= 2;
+
+ return result;
+}
+
+void TQFontKsc5601Codec::fromUnicode(const TQChar *in, unsigned short *out, int length) const
+{
+ while (length--) {
+ *out++ = (qt_UnicodeToKsc5601(in->tqunicode()) & 0x7f7f);
+ ++in;
+ }
+}
+
+bool TQFontKsc5601Codec::canEncode( TQChar ch ) const
+{
+ return (qt_UnicodeToKsc5601(ch.tqunicode()) != 0);
+}
+
+#endif // TQT_NO_BIG_CODECS
+#endif // TQT_NO_CODECS
diff --git a/tqtinterface/qt4/src/codecs/tqfontlaocodec.cpp b/tqtinterface/qt4/src/codecs/tqfontlaocodec.cpp
new file mode 100644
index 0000000..aadad4a
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqfontlaocodec.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** Font utilities for X11
+**
+** Created : 20001101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "private/tqfontcodecs_p.h"
+
+#ifndef TQT_NO_CODECS
+#ifndef TQT_NO_BIG_CODECS
+
+static unsigned char const tqunicode_to_mulelao[256] =
+ {
+ // U+0E80
+ 0x00, 0xa1, 0xa2, 0x00, 0xa4, 0x00, 0x00, 0xa7,
+ 0xa8, 0x00, 0xaa, 0x00, 0x00, 0xad, 0x00, 0x00,
+ // U+0E90
+ 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0x00, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ // U+0EA0
+ 0x00, 0xc1, 0xc2, 0xc3, 0x00, 0xc5, 0x00, 0xc7,
+ 0x00, 0x00, 0xca, 0xcb, 0x00, 0xcd, 0xce, 0xcf,
+ // U+0EB0
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0x00, 0xdb, 0xdc, 0xdd, 0x00, 0x00,
+ // U+0EC0
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0x00, 0xe6, 0x00,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0x00, 0x00,
+ // U+0ED0
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0x00, 0x00, 0xfc, 0xfd, 0x00, 0x00,
+ // U+0EE0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // U+0EF0
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+
+
+TQFontLaoCodec::TQFontLaoCodec()
+{
+}
+
+const char *TQFontLaoCodec::name() const
+{
+ return "mulelao-1";
+}
+
+int TQFontLaoCodec::mibEnum() const
+{
+ return -4242;
+}
+
+unsigned short TQFontLaoCodec::characterFromUnicode(const TQString &str, int pos) const
+{
+ const TQChar * const ch = str.tqunicode() + pos;
+ if (ch->tqunicode() < 0x80)
+ return ch->tqunicode();
+ if ( ch->tqunicode() >= 0x0e80 && ch->tqunicode() <= 0x0eff )
+ return tqunicode_to_mulelao[ch->tqunicode() - 0x0e80];
+ return 0;
+}
+
+TQCString TQFontLaoCodec::fromUnicode(const TQString& uc, int& lenInOut ) const
+{
+ TQCString rstring( lenInOut+1 );
+ uchar *rdata = (uchar *) rstring.data();
+ const TQChar *sdata = uc.tqunicode();
+ int i = 0;
+ for ( ; i < lenInOut; ++i, ++sdata, ++rdata ) {
+ if ( sdata->tqunicode() < 0x80 ) {
+ *rdata = (uchar) sdata->tqunicode();
+ } else if ( sdata->tqunicode() >= 0x0e80 && sdata->tqunicode() <= 0x0eff ) {
+ uchar lao = tqunicode_to_mulelao[sdata->tqunicode() - 0x0e80];
+ if ( lao )
+ *rdata = lao;
+ else
+ *rdata = '?';
+ } else {
+ *rdata = '?';
+ }
+ }
+ *rdata = 0u;
+ return rstring;
+}
+
+void TQFontLaoCodec::fromUnicode(const TQChar *in, unsigned short *out, int length) const
+{
+ while (length--) {
+ if ( in->tqunicode() < 0x80 ) {
+ *out = (uchar) in->tqunicode();
+ } else if ( in->tqunicode() >= 0x0e80 && in->tqunicode() <= 0x0eff ) {
+ *out = tqunicode_to_mulelao[in->tqunicode() - 0x0e80];
+ } else {
+ *out = 0;
+ }
+
+ ++in;
+ ++out;
+ }
+}
+
+int TQFontLaoCodec::heuristicContentMatch(const char *, int) const
+{
+ return -1;
+}
+
+bool TQFontLaoCodec::canEncode( TQChar ch ) const
+{
+ return ( ch.tqunicode() < 0x80 ||
+ tqunicode_to_mulelao[ch.tqunicode() - 0x0e80] != 0x00 );
+}
+
+
+#endif // TQT_NO_BIG_CODECS
+#endif // TQT_NO_CODECS
+
diff --git a/tqtinterface/qt4/src/codecs/tqfonttwcodec.cpp b/tqtinterface/qt4/src/codecs/tqfonttwcodec.cpp
new file mode 100644
index 0000000..bc25baa
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqfonttwcodec.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** Taiwan Font utilities for X11
+**
+** Created : 20010130
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "private/tqfontcodecs_p.h"
+
+#ifndef TQT_NO_CODECS
+#ifndef TQT_NO_BIG_CODECS
+
+extern int qt_UnicodeToBig5hkscs(uint wc, uchar *r);
+
+
+int TQFontBig5Codec::heuristicContentMatch(const char *, int) const
+{
+ return 0;
+}
+
+
+int TQFontBig5Codec::heuristicNameMatch(const char* hint) const
+{
+ //qDebug("TQFontBig5Codec::heuristicNameMatch(const char* hint = \"%s\")", hint);
+ return ( qstricmp(hint, "big5-0") == 0 ||
+ qstricmp(hint, "big5.eten-0") == 0 )
+ ? 13 : 0;
+}
+
+
+TQFontBig5Codec::TQFontBig5Codec()
+{
+ //qDebug("TQFontBig5Codec::TQFontBig5Codec()");
+}
+
+
+const char* TQFontBig5Codec::name() const
+{
+ //qDebug("TQFontBig5Codec::name() = \"big5-0\"");
+ return "big5-0";
+}
+
+
+int TQFontBig5Codec::mibEnum() const
+{
+ //qDebug("TQFontBig5Codec::mibEnum() = -2026");
+ return -2026;
+}
+
+
+TQString TQFontBig5Codec::toUnicode(const char* /*chars*/, int /*len*/) const
+{
+ return TQString::null;
+}
+
+unsigned short TQFontBig5Codec::characterFromUnicode(const TQString &str, int pos) const
+{
+ uchar c[2];
+ if (qt_UnicodeToBig5hkscs((str.tqunicode() + pos)->tqunicode(), c) == 2 &&
+ c[0] >= 0xa1 && c[0] <= 0xf9 )
+ return (c[0] << 8) + c[1];
+ return 0;
+}
+
+TQCString TQFontBig5Codec::fromUnicode(const TQString& uc, int& lenInOut ) const
+{
+ //qDebug("TQFontBig5Codec::fromUnicode(const TQString& uc, int& lenInOut = %d)", lenInOut);
+ TQCString result(lenInOut * 2 + 1);
+ uchar *rdata = (uchar *) result.data();
+ const TQChar *ucp = uc.tqunicode();
+
+ for ( int i = 0; i < lenInOut; i++ ) {
+ TQChar ch(*ucp++);
+ uchar c[2];
+
+#if 0
+ if ( ch.row() == 0) {
+ if ( ch.cell() == ' ' )
+ ch = TQChar( 0x3000 );
+ else if ( ch.cell() > ' ' && ch.cell() < 127 )
+ ch = TQChar( ch.cell()-' ', 255 );
+ }
+#endif
+ if ( qt_UnicodeToBig5hkscs( ch.tqunicode(), c ) == 2 &&
+ c[0] >= 0xa1 && c[0] <= 0xf9 ) {
+ *rdata++ = c[0];
+ *rdata++ = c[1];
+ } else {
+ //white square
+ *rdata++ = 0xa1;
+ *rdata++ = 0xbc;
+ }
+ }
+ lenInOut *=2;
+ return result;
+}
+
+/*! \internal */
+void TQFontBig5Codec::fromUnicode(const TQChar *in, unsigned short *out, int length) const
+{
+ uchar c[2];
+ while (length--) {
+ if ( in->row() == 0x00 && in->cell() < 0x80 ) {
+ // ASCII
+ *out = in->cell();
+ } else if ( qt_UnicodeToBig5hkscs( in->tqunicode(), c ) == 2
+ && c[0] >= 0xa1 && c[0] <= 0xf9 ) {
+ // Big5-ETen
+ *out = (c[0] << 8) | c[1];
+ } else {
+ // Unknown char
+ *out = 0;
+ }
+
+ ++in;
+ ++out;
+ }
+}
+
+bool TQFontBig5Codec::canEncode( TQChar ch ) const
+{
+ //qDebug("TQFontBig5Codec::canEncode( TQChar ch = %02X%02X )", ch.row(), ch.cell());
+ uchar c[2];
+ return ( qt_UnicodeToBig5hkscs( ch.tqunicode(), c ) == 2 &&
+ c[0] >= 0xa1 && c[0] <= 0xf9 );
+}
+
+#endif // TQT_NO_BIG_CODECS
+#endif // TQT_NO_CODECS
diff --git a/tqtinterface/qt4/src/codecs/tqgb18030codec.cpp b/tqtinterface/qt4/src/codecs/tqgb18030codec.cpp
new file mode 100644
index 0000000..4abf8f4
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqgb18030codec.cpp
@@ -0,0 +1,9381 @@
+/****************************************************************************
+** Implementation of TQGb18030Codec template/macro class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/*! \class TQGb18030Codec tqgb18030codec.h
+ \reentrant
+ \ingroup i18n
+
+ \brief The TQGb18030Codec class provides conversion to and from the Chinese
+ GB18030/GBK/GB2312 encoding.
+
+ \omit Last updated: September, 3, 2002 \endomit
+
+ GBK, formally the Chinese Internal Code Specification, is a commonly
+ used extension of GB 2312-80. Microsoft Windows uses it under the
+ name codepage 936.
+
+ GBK has been superceded by the new Chinese national standard
+ GB 18030-2000, which added a 4-byte encoding while remaining
+ compatible with GB2312 and GBK. The new GB 18030-2000 may be described
+ as a special encoding of Unicode 3.x and ISO-10646-1.
+
+ Special thanks to charset gurus Markus Scherer (IBM),
+ Dirk Meyer (Adobe Systems) and Ken Lunde (Adobe Systems) for publishing
+ an excellent GB 18030-2000 summary and specification on the Internet.
+ Some must-read documents are:
+ \list
+ \i
+ \l{ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/pdf/GB18030_Summary.pdf}
+ \i \l{http://oss.software.ibm.com/cvs/icu/~checkout~/charset/source/gb18030/gb18030.html}
+ \i
+ \l{http://oss.software.ibm.com/cvs/icu/~checkout~/charset/data/xml/gb-18030-2000.xml}
+ \endlist
+
+ The GBK codec was contributed to TQt by
+ Justin Yu \<justiny@turbolinux.com.cn\> and
+ Sean Chen \<seanc@turbolinux.com.cn\>. They may also be reached at
+ Yu Mingjian \<yumj@sun.ihep.ac.cn\>, \<yumingjian@china.com\>
+ Chen Xiangyang \<chenxy@sun.ihep.ac.cn\>
+
+ The GB18030 codec TQt functions were contributed to TQt by
+ James Su \<suzhe@gnuchina.org\>, \<suzhe@turbolinux.com.cn\>
+ who pioneered much of GB18030 development on GNU/Linux systems.
+
+ The GB18030 codec was contributed to TQt by
+ Anthony Fok \<anthony@thizlinux.com\>, \<foka@debian.org\>
+ using a Perl script to generate C++ tables from gb-18030-2000.xml
+ while merging contributions from James Su, Justin Yu and Sean Chen.
+ A copy of the source Perl script is available at:
+
+ \l{http://people.debian.org/~foka/gb18030/gen-qgb18030codec.pl}
+
+ The copyright notice for their code follows:
+
+ \legalese
+
+ Copyright (C) 2000 TurboLinux, Inc. Written by Justin Yu and Sean Chen.
+ Copyright (C) 2001, 2002 Turbolinux, Inc. Written by James Su.
+ Copyright (C) 2001, 2002 ThizLinux Laboratory Ltd. Written by Anthony Fok.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ \list 1
+ \i Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ \i Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ \endlist
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+#include "tqgb18030codec.h"
+
+#if (TQT_VERSION-0 >= 0x040000)
+#error "move obsolete header <tqgbkcodec.h> into the src/compat directory"
+#endif
+
+#ifndef TQT_NO_BIG_CODECS
+
+#define InRange(c, lower, upper) (((c) >= (lower)) && ((c) <= (upper)))
+#define IsLatin(c) ((c) <= 0x7F)
+#define IsByteInGb2312(c) (InRange((c), 0xA1, 0xFE))
+#define Is1stByte(c) (InRange((c), 0x81, 0xFE))
+#define Is2ndByteIn2Bytes(c) (InRange((c), 0x40, 0xFE) && (c) != 0x7F)
+#define Is2ndByteIn4Bytes(c) (InRange((c), 0x30, 0x39))
+#define Is2ndByte(c) (Is2ndByteIn2Bytes(c) || Is2ndByteIn4Bytes(c))
+#define Is3rdByte(c) (InRange((c), 0x81, 0xFE))
+#define Is4thByte(c) (InRange((c), 0x30, 0x39))
+
+#define TQValidChar(u) ((u) ? TQChar((ushort)(u)) : TQChar::tqreplacement)
+
+/* User-defined areas: UDA 1: 0xAAA1 - 0xAFFE (564/0)
+ UDA 2: 0xF8A1 - 0xFEFE (658/0)
+ UDA 3: 0xA140 - 0xA7A0 (672/0) */
+#define IsUDA1(a, b) (InRange((a), 0xAA, 0xAF) && InRange((b), 0xA1, 0xFE))
+#define IsUDA2(a, b) (InRange((a), 0xF8, 0xFE) && InRange((b), 0xA1, 0xFE))
+#define IsUDA3(a, b) (InRange((a), 0xA1, 0xA7) && InRange((b), 0x40, 0xA0) && ((b) != 0x7F))
+
+typedef struct {
+ TQ_UINT8 tblBegin;
+ TQ_UINT8 tblEnd;
+ TQ_UINT16 tblOffset;
+ TQ_UINT16 algOffset;
+} indexTbl_t;
+
+static uint qt_Gb18030ToUnicode(const uchar *gbstr, int& len);
+static int qt_UnicodeToGb18030(uint tqunicode, uchar *gbchar);
+int qt_UnicodeToGbk(uint tqunicode, uchar *gbchar);
+
+/*! \internal */
+TQGb18030Codec::TQGb18030Codec()
+{
+}
+
+/*! \reimp */
+const char* TQGb18030Codec::name() const
+{
+ //qDebug("TQGb18030Codec::name() = \"GB18030\"");
+ return "GB18030";
+}
+
+/*! \reimp */
+int TQGb18030Codec::mibEnum() const
+{
+ return 114;
+}
+
+/*! \reimp */
+TQCString TQGb18030Codec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ int l = TQMIN((int)uc.length(),(lenInOut<0)?(int)uc.length():lenInOut);
+ int rlen = l*4+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+
+ //qDebug("TQGb18030Codec::fromUnicode(const TQString& uc, int& lenInOut = %d)", lenInOut);
+ for (int i=0; i<l; i++) {
+ TQChar ch = uc[i];
+ int len;
+ uchar buf[4];
+
+ if ( ch.row() == 0x00 && ch.cell() < 0x80 ) {
+ // ASCII
+ *cursor++ = ch.cell();
+ } else if ((ch.tqunicode() & 0xf800) == 0xd800) {
+ unsigned short high = ch.tqunicode();
+ // surrogates area. check for correct encoding
+ // we need at least one more character, first the high surrogate, then the low one
+ if (i == l-1 || high >= 0xdc00)
+ *cursor++ = '?';
+ else {
+ unsigned short low = uc[i+1].tqunicode();
+ if (low >= 0xdc00 && low <= 0xdfff) {
+ // valid surrogate pair
+ ++i;
+ uint u = (high-0xd800)*0x400+(low-0xdc00)+0x10000;
+ len = qt_UnicodeToGb18030(u, buf);
+ if (len >= 2) {
+ for (int j=0; j<len; j++)
+ *cursor++ = buf[j];
+ } else {
+ *cursor++ = '?';
+ }
+ } else {
+ *cursor++ = '?';
+ }
+ }
+ } else if ( (len = qt_UnicodeToGb18030(ch.tqunicode(), buf)) >= 2 ) {
+ for (int j=0; j<len; j++)
+ *cursor++ = buf[j];
+ } else {
+ // Error
+ *cursor++ = '?'; // unknown char
+ }
+ }
+
+ lenInOut = cursor - (uchar*)rstr.data();
+ rstr.truncate(lenInOut);
+ return rstr;
+}
+
+/*! \reimp */
+TQString TQGb18030Codec::toUnicode(const char* chars, int len) const
+{
+ TQString result;
+ int clen;
+
+ //qDebug("TQGb18030Codec::toUnicode(const char* chars, int len = %d)", len);
+ for (int i=0; i<len; ) {
+ uchar ch = chars[i];
+
+ if ( IsLatin(ch) ) {
+ // ASCII
+ result += TQChar(ch);
+ i++;
+ } else if ( Is1stByte(ch) ) {
+ // GB18030 ?
+ clen = len - i;
+ uint u = qt_Gb18030ToUnicode( (const uchar*)(chars + i), clen );
+
+ if (clen == 2 || clen == 4) {
+ if (u < 0x10000)
+ result += TQValidChar(u);
+ else {
+ // encode into surrogate pair
+ u -= 0x10000;
+ unsigned short high = u/0x400 + 0xd800;
+ unsigned short low = u%0x400 + 0xdc00;
+ result += TQChar(high);
+ result += TQChar(low);
+ }
+ i += clen;
+ } else if (i < len) {
+ result += TQChar::tqreplacement;
+ i++;
+ }
+ } else {
+ // Invalid or undefined
+ result += TQChar::tqreplacement;
+ i++;
+ }
+ }
+ return result;
+}
+
+/*! \reimp */
+int TQGb18030Codec::heuristicNameMatch(const char* hint) const
+{
+ int score = 0;
+ bool zh = FALSE;
+ //qDebug("TQGb18030Codec::heuristicNameMatch(const char* hint = \"%s\")", hint);
+ if (qstrnicmp(hint, "zh_CN", 5) == 0){
+ score += 10;
+ zh = TRUE;
+ }
+ const char *p;
+ if ( zh ) {
+ p = strchr(hint, '.');
+ if ( p == 0 )
+ return score;
+ p++;
+ } else {
+ p = hint;
+ }
+ if (p) {
+ if (qstricmp(p, "GB18030") == 0)
+ return score + 14;
+ }
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+/*! \reimp */
+int TQGb18030Codec::heuristicContentMatch(const char* chars, int len) const
+{
+ int score = 0;
+ //qDebug("TQGb18030Codec::heuristicContentMatch(const char* chars, int len = %d)", len);
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ // No nulls allowed.
+ if ( !ch )
+ return -1;
+
+ if (ch < 32 && ch != '\t' && ch != '\n' && ch != '\r') {
+ // Suspicious
+ if ( score )
+ score--;
+ } else if ( ch < 0x80 ) {
+ // Inconclusive
+ score++;
+ } else if ( Is1stByte(ch) ) {
+ if ( i < len-1 ) {
+ uchar ch2 = chars[++i];
+ if ( Is2ndByteIn4Bytes(ch2) && i < len-2 ) {
+ uchar ch3 = chars[++i];
+ if ( Is3rdByte(ch3) && i < len-1 ) {
+ uchar ch4 = chars[++i];
+ if ( !Is4thByte(ch4) )
+ return -1;
+ score += 2;
+ } else {
+ return -1;
+ }
+ } else if ( !Is2ndByteIn2Bytes(ch2) ) {
+ return -1;
+ } else {
+ score += 2;
+ }
+ }
+ score++;
+ } else {
+ // Invalid
+ return -1;
+ }
+ }
+ return score;
+}
+
+class TQGb18030Decoder : public TQTextDecoder {
+ uchar buf[4];
+ int nbuf;
+public:
+ TQGb18030Decoder() : nbuf(0)
+ {
+ }
+ TQString toUnicode(const char* chars, int len)
+ {
+ TQString result;
+ //qDebug("TQGb18030Decoder::toUnicode(const char* chars, int len = %d)", len);
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ switch (nbuf) {
+ case 0:
+ if ( ch < 0x80 ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( Is1stByte(ch) ) {
+ // GB18030?
+ buf[0] = ch;
+ nbuf = 1;
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ break;
+ case 1:
+ // GB18030 2 bytes
+ if ( Is2ndByteIn2Bytes(ch) ) {
+ buf[1] = ch;
+ int clen = 2;
+ uint u = qt_Gb18030ToUnicode(buf, clen);
+ if (clen == 2) {
+ result += TQValidChar(u);
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ } else if ( Is2ndByteIn4Bytes(ch) ) {
+ buf[1] = ch;
+ nbuf = 2;
+ } else {
+ // Error
+ result += TQChar::tqreplacement;
+ nbuf = 0;
+ }
+ break;
+ case 2:
+ // GB18030 3 bytes
+ if ( Is3rdByte(ch) ) {
+ buf[2] = ch;
+ nbuf = 3;
+ } else {
+ result += TQChar::tqreplacement;
+ nbuf = 0;
+ }
+ break;
+ case 3:
+ // GB18030 4 bytes
+ if ( Is4thByte(ch) ) {
+ buf[3] = ch;
+ int clen = 4;
+ uint u = qt_Gb18030ToUnicode(buf, clen);
+ if (clen == 4) {
+ if (u < 0x10000)
+ result += TQValidChar(u);
+ else {
+ // encode into surrogate pair
+ u -= 0x10000;
+ unsigned short high = u/0x400 + 0xd800;
+ unsigned short low = u%0x400 + 0xdc00;
+ result += TQChar(high);
+ result += TQChar(low);
+ }
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ break;
+ }
+ }
+ return result;
+ }
+};
+
+/*! \reimp */
+TQTextDecoder* TQGb18030Codec::makeDecoder() const
+{
+ //qDebug("TQGb18030Codec::makeDecoder()");
+ return new TQGb18030Decoder();
+}
+
+/*! \class TQGbkCodec
+ \reentrant
+ \ingroup i18n
+
+ \brief The TQGbkCodec class provides conversion to and from the Chinese
+ GBK encoding.
+
+ GBK, formally the Chinese Internal Code Specification, is a commonly
+ used extension of GB 2312-80. Microsoft Windows uses it under the
+ name code page 936.
+
+ The GBK encoding has been superceded by the GB18030 encoding and
+ GB18030 is backward compatible to GBK. For this reason the TQGbkCodec class
+ is implemented in terms of the GB18030 codec and uses its 1-byte and
+ 2-byte portion for conversion from and to Unicode.
+
+ The TQGbkCodec is kept mainly for compatibility reasons with older software.
+*/
+
+
+/*! \reimp */
+TQGbkCodec::TQGbkCodec()
+ : TQGb18030Codec()
+{
+}
+
+/*! \reimp */
+int TQGbkCodec::mibEnum() const
+{
+ return 113;
+}
+
+/*! \reimp */
+const char* TQGbkCodec::name() const
+{
+ return "GBK";
+}
+
+/*! \reimp */
+int TQGbkCodec::heuristicNameMatch(const char* hint) const
+{
+#if 0
+ // these are needed so that the X11 fonts behave correctly.
+ if (qstricmp (hint, "gbk-0") == 0 ||
+ qstricmp (hint, "gb18030.2000-0") == 0)
+ return 13;
+#endif
+
+ int score = 0;
+ bool zh = FALSE;
+ //qDebug("TQGbkCodec::heuristicNameMatch(const char* hint = \"%s\")", hint);
+ if (qstrnicmp(hint, "zh_CN", 5) == 0){
+ score += 10;
+ zh = TRUE;
+ }
+ const char *p;
+ if ( zh ) {
+ p = strchr(hint, '.');
+ if ( p == 0 )
+ return score;
+ p++;
+ } else {
+ p = hint;
+ }
+ if (p) {
+ if (qstricmp(p, "GBK") == 0)
+ return score + 6;
+ }
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+/*! \reimp */
+int TQGbkCodec::heuristicContentMatch(const char* /*chars*/, int /*len*/) const
+{
+ //qDebug("TQGbkCodec::heuristicContentMatch(const char* /*chars*/, int /*len*/)");
+ return 0;
+}
+
+class TQGbkDecoder : public TQTextDecoder {
+ uchar buf[2];
+ int nbuf;
+public:
+ TQGbkDecoder() : nbuf(0)
+ {
+ }
+ TQString toUnicode(const char* chars, int len)
+ {
+ TQString result;
+
+ //qDebug("TQGbkDecoder::toUnicode(const char* chars = \"%s\", int len = %d)", chars, len);
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ switch (nbuf) {
+ case 0:
+ if ( ch < 0x80 ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( Is1stByte(ch) ) {
+ // GBK 1st byte?
+ buf[0] = ch;
+ nbuf = 1;
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ break;
+ case 1:
+ // GBK 2nd byte
+ if ( Is2ndByteIn2Bytes(ch) ) {
+ buf[1] = ch;
+ int clen = 2;
+ uint u = qt_Gb18030ToUnicode(buf, clen);
+ if (clen == 2) {
+ result += TQValidChar(u);
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ } else {
+ // Error
+ result += TQChar::tqreplacement;
+ nbuf = 0;
+ }
+ break;
+ }
+ }
+ return result;
+ }
+};
+
+/*! \reimp */
+TQTextDecoder* TQGbkCodec::makeDecoder() const
+{
+ //qDebug("TQGbkCodec::makeDecoder()");
+ return new TQGbkDecoder();
+}
+
+/*! \reimp */
+TQCString TQGbkCodec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ int l = TQMIN((int)uc.length(),(lenInOut<0)?(int)uc.length():lenInOut);
+ int rlen = l*2+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+
+ //qDebug("TQGbkCodec::fromUnicode(const TQString& uc, int& lenInOut = %d)", lenInOut);
+ for (int i=0; i<l; i++) {
+ TQChar ch = uc[i];
+ uchar buf[2];
+
+ if ( ch.row() == 0x00 && ch.cell() < 0x80 ) {
+ // ASCII
+ *cursor++ = ch.cell();
+ } else if ( qt_UnicodeToGbk(ch.tqunicode(), buf) == 2 ) {
+ *cursor++ = buf[0];
+ *cursor++ = buf[1];
+ } else {
+ // Error
+ *cursor++ = '?'; // unknown char
+ }
+ }
+
+ lenInOut = cursor - (uchar*)rstr.data();
+ rstr.truncate(lenInOut);
+ return rstr;
+}
+
+/*! \reimp */
+TQString TQGbkCodec::toUnicode(const char* chars, int len) const
+{
+ TQString result;
+ int clen;
+
+ //qDebug("TQGbkCodec::toUnicode(const char* chars, int len = %d)", len);
+ for (int i=0; i<len; ) {
+ uchar ch = chars[i];
+
+ if ( IsLatin(ch) ) {
+ // ASCII
+ result += TQChar(ch);
+ i++;
+ } else if ( Is1stByte(ch) ) {
+ // GBK ?
+ clen = len - i;
+ uint u = qt_Gb18030ToUnicode( (const uchar*)(chars + i), clen );
+
+ if (clen == 2) {
+ result += TQValidChar(u);
+ i += 2;
+ } else if (clen == 4) {
+ result += TQChar::tqreplacement;
+ i += 4;
+ } else if (i < len) {
+ result += TQChar::tqreplacement;
+ i++;
+ }
+ } else {
+ // Invalid or undefined
+ result += TQChar::tqreplacement;
+ i++;
+ }
+ }
+ return result;
+}
+
+
+/*! \class TQGb2312Codec
+ \ingroup i18n
+
+ \brief The TQGb2312Codec class provides conversion to and from the Chinese
+ GB2312 encoding.
+
+ The GB2312 encoding has been superceded by the GB18030 encoding and
+ GB18030 is backward compatible to GB2312. For this reason the TQGb2312Codec
+ class is implemented in terms of the GB18030 codec and uses its
+ 0xA1A1-0xFEFE subset for conversion from and to Unicode.
+
+ The TQGb2312Codec is kept mainly for compatibility reasons with older software.
+*/
+
+
+/*! \reimp */
+TQGb2312Codec::TQGb2312Codec()
+ : TQGb18030Codec()
+{
+}
+
+/*! \reimp */
+int TQGb2312Codec::mibEnum() const
+{
+ return 2025;
+}
+
+/*! \reimp */
+const char* TQGb2312Codec::name() const
+{
+ return "GB2312";
+}
+
+/*! \reimp */
+int TQGb2312Codec::heuristicNameMatch(const char* hint) const
+{
+ int score = 0;
+ bool zh = FALSE;
+ //qDebug("TQGb2312Codec::heuristicNameMatch(const char* hint = \"%s\")", hint);
+ if (qstrnicmp(hint, "zh_CN", 5) == 0){
+ score += 10;
+ zh = TRUE;
+ }
+ const char *p;
+ if ( zh ) {
+ p = strchr(hint, '.');
+ if ( p == 0 )
+ return score;
+ p++;
+ } else {
+ p = hint;
+ }
+ if (p) {
+ if (qstricmp(p, "GB2312") == 0 ||
+ qstricmp(p, "hp15cn") == 0)
+ return score + 7;
+ else if (qstricmp(p, "eucCN") == 0)
+ return score + 4;
+ // there exists ja_JP.EUC, ko_KR.EUC, zh_CN.EUC and zh_TW.EUC
+ else if (qstricmp(p, "euc") == 0 && zh)
+ return score + 4;
+ }
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+/*! \reimp */
+int TQGb2312Codec::heuristicContentMatch(const char* /*chars*/, int /*len*/) const
+{
+ //qDebug("TQGb2312Codec::heuristicContentMatch(const char* /*chars*/, int /*len*/)");
+ return 0;
+}
+
+class TQGb2312Decoder : public TQTextDecoder {
+ uchar buf[2];
+ int nbuf;
+public:
+ TQGb2312Decoder() : nbuf(0)
+ {
+ }
+ TQString toUnicode(const char* chars, int len)
+ {
+ TQString result;
+ //qDebug("TQGb2312Decoder::toUnicode(const char* chars, int len = %d)", len);
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ switch (nbuf) {
+ case 0:
+ if ( ch < 0x80 ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( IsByteInGb2312(ch) ) {
+ // GB2312 1st byte?
+ buf[0] = ch;
+ nbuf = 1;
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ break;
+ case 1:
+ // GB2312 2nd byte
+ if ( IsByteInGb2312(ch) ) {
+ buf[1] = ch;
+ int clen = 2;
+ uint u = qt_Gb18030ToUnicode(buf, clen);
+ if (clen == 2) {
+ result += TQValidChar(u);
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ } else {
+ // Error
+ result += TQChar::tqreplacement;
+ nbuf = 0;
+ }
+ break;
+ }
+ }
+ return result;
+ }
+};
+
+/*! \reimp */
+TQTextDecoder* TQGb2312Codec::makeDecoder() const
+{
+ //qDebug("TQGb2312Codec::makeDecoder()");
+ return new TQGb2312Decoder();
+}
+
+/*! \reimp */
+TQCString TQGb2312Codec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ int l = TQMIN((int)uc.length(),(lenInOut<0)?(int)uc.length():lenInOut);
+ int rlen = l*2+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+
+ //qDebug("TQGb2312Codec::fromUnicode(const TQString& uc, int& lenInOut = %d) const", lenInOut);
+ for (int i=0; i<l; i++) {
+ TQChar ch = uc[i];
+ uchar buf[2];
+
+ if ( ch.row() == 0x00 && ch.cell() < 0x80 ) {
+ // ASCII
+ *cursor++ = ch.cell();
+ } else if ( (qt_UnicodeToGbk(ch.tqunicode(), buf) == 2) &&
+ (buf[0] >= 0xA1) && (buf[1] >= 0xA1) ) {
+ *cursor++ = buf[0];
+ *cursor++ = buf[1];
+ } else {
+ // Error
+ *cursor++ = '?'; // unknown char
+ }
+ }
+
+ lenInOut = cursor - (uchar*)rstr.data();
+ rstr.truncate(lenInOut);
+ return rstr;
+}
+
+/*! \reimp */
+TQString TQGb2312Codec::toUnicode(const char* chars, int len) const
+{
+ TQString result;
+ int clen;
+
+ //qDebug("TQGb2312Codec::toUnicode(const char* chars, int len = %d)", len);
+ for (int i=0; i<len; ) {
+ uchar ch = chars[i];
+
+ if ( IsLatin(ch) ) {
+ // ASCII
+ result += TQChar(ch);
+ i++;
+ } else if ( Is1stByte(ch) ) {
+ // GB2312 ?
+
+ clen = len - i;
+ uint u = qt_Gb18030ToUnicode( (const uchar*)(chars + i), clen );
+
+ if (clen == 2 || clen == 4) {
+ if ( clen == 2 && IsByteInGb2312(ch) && IsByteInGb2312((uchar)(chars[i+1])) )
+ result += TQValidChar(u);
+ else
+ result += TQChar::tqreplacement;
+ i += clen;
+ } else if (i < len) {
+ result += TQChar::tqreplacement;
+ i++;
+ }
+ } else {
+ // Invalid or undefined
+ result += TQChar::tqreplacement;
+ i++;
+ }
+ }
+ return result;
+}
+
+
+static const indexTbl_t gb18030_to_ucs_index[154] = {
+ /* U+00__ */ {0x00, 0xFF, 0x0000, 0x0000}, {0x00, 0xFF, 0x0000, 0x0000},
+ /* U+02__ */ {0x00, 0xFF, 0x0000, 0x0000}, {0x00, 0x33, 0x0000, 0x041E},
+ /* U+04__ */ {0xFF, 0x00, 0x1BBE, 0x051E}, {0xFF, 0x00, 0x1BBE, 0x061E},
+ /* U+06__ */ {0xFF, 0x00, 0x1BBE, 0x071E}, {0xFF, 0x00, 0x1BBE, 0x081E},
+ /* U+08__ */ {0xFF, 0x00, 0x1BBE, 0x091E}, {0xFF, 0x00, 0x1BBE, 0x0A1E},
+ /* U+0A__ */ {0xFF, 0x00, 0x1BBE, 0x0B1E}, {0xFF, 0x00, 0x1BBE, 0x0C1E},
+ /* U+0C__ */ {0xFF, 0x00, 0x1BBE, 0x0D1E}, {0xFF, 0x00, 0x1BBE, 0x0E1E},
+ /* U+0E__ */ {0xFF, 0x00, 0x1BBE, 0x0F1E}, {0xFF, 0x00, 0x1BBE, 0x101E},
+ /* U+10__ */ {0xFF, 0x00, 0x1BBE, 0x111E}, {0xFF, 0x00, 0x1BBE, 0x121E},
+ /* U+12__ */ {0xFF, 0x00, 0x1BBE, 0x131E}, {0xFF, 0x00, 0x1BBE, 0x141E},
+ /* U+14__ */ {0xFF, 0x00, 0x1BBE, 0x151E}, {0xFF, 0x00, 0x1BBE, 0x161E},
+ /* U+16__ */ {0xFF, 0x00, 0x1BBE, 0x171E}, {0xFF, 0x00, 0x1BBE, 0x181E},
+ /* U+18__ */ {0xFF, 0x00, 0x1BBE, 0x191E}, {0xFF, 0x00, 0x1BBE, 0x1A1E},
+ /* U+1A__ */ {0xFF, 0x00, 0x1BBE, 0x1B1E}, {0xFF, 0x00, 0x1BBE, 0x1C1E},
+ /* U+1C__ */ {0xFF, 0x00, 0x1BBE, 0x1D1E}, {0xFF, 0x00, 0x1BBE, 0x1E1E},
+ /* U+1E__ */ {0xF2, 0xFF, 0x1BBE, 0x1F1E}, {0x00, 0xFF, 0x1BBE, 0x0000},
+ /* U+20__ */ {0x00, 0xFF, 0x1BBE, 0x0000}, {0x00, 0xFF, 0x1BBE, 0x0000},
+ /* U+22__ */ {0x00, 0xFF, 0x1BBE, 0x0000}, {0x00, 0xFF, 0x1BBE, 0x0000},
+ /* U+24__ */ {0x00, 0x02, 0x1BBE, 0x2640}, {0xFF, 0x00, 0x23FC, 0x2740},
+ /* U+26__ */ {0xFF, 0x00, 0x23FC, 0x2840}, {0xFF, 0x00, 0x23FC, 0x2940},
+ /* U+28__ */ {0xFF, 0x00, 0x23FC, 0x2A40}, {0xFF, 0x00, 0x23FC, 0x2B40},
+ /* U+2A__ */ {0xFF, 0x00, 0x23FC, 0x2C40}, {0xFF, 0x00, 0x23FC, 0x2D40},
+ /* U+2C__ */ {0x41, 0xFF, 0x23FC, 0x2E40}, {0x00, 0xFF, 0x23FC, 0x0000},
+ /* U+2E__ */ {0x00, 0xFF, 0x23FC, 0x0000}, {0x00, 0xFF, 0x23FC, 0x0000},
+ /* U+30__ */ {0x00, 0xFF, 0x23FC, 0x0000}, {0x00, 0xFF, 0x23FC, 0x0000},
+ /* U+32__ */ {0x00, 0xAC, 0x23FC, 0x356E}, {0xFF, 0x00, 0x26F9, 0x366E},
+ /* U+34__ */ {0xFF, 0x00, 0x26F9, 0x376E}, {0xAA, 0xFF, 0x26F9, 0x386E},
+ /* U+36__ */ {0x00, 0xFF, 0x26F9, 0x0000}, {0x00, 0xFF, 0x26F9, 0x0000},
+ /* U+38__ */ {0x00, 0xFF, 0x26F9, 0x0000}, {0x00, 0x69, 0x26F9, 0x3C77},
+ /* U+3A__ */ {0xFF, 0x00, 0x2A6E, 0x3D77}, {0xFF, 0x00, 0x2A6E, 0x3E77},
+ /* U+3C__ */ {0xDF, 0xFF, 0x2A6E, 0x3F77}, {0x00, 0xE6, 0x2A6E, 0x4079},
+ /* U+3E__ */ {0xFF, 0x00, 0x2C45, 0x4179}, {0xBE, 0xFF, 0x2C45, 0x4279},
+ /* U+40__ */ {0x00, 0xFF, 0x2C45, 0x0000}, {0x00, 0x58, 0x2C45, 0x447E},
+ /* U+42__ */ {0xCE, 0xFF, 0x2DBA, 0x457E}, {0x00, 0xFF, 0x2DBA, 0x0000},
+ /* U+44__ */ {0x00, 0x09, 0x2DBA, 0x4784}, {0xC3, 0xFF, 0x2F73, 0x4884},
+ /* U+46__ */ {0x00, 0x28, 0x2F73, 0x498F}, {0xFF, 0x00, 0x3232, 0x4A8F},
+ /* U+48__ */ {0xE8, 0xFF, 0x3232, 0x4B8F}, {0x00, 0xFF, 0x3232, 0x0000},
+ /* U+4A__ */ {0x00, 0x62, 0x3232, 0x9F43}, {0xFF, 0x00, 0x6A8C, 0xA043},
+ /* U+4C__ */ {0xFF, 0x00, 0x6A8C, 0xA143}, {0xFF, 0x00, 0x6A8C, 0xA243},
+ /* U+4E__ */ {0xFF, 0x00, 0x6A8C, 0xA343}, {0xFF, 0x00, 0x6A8C, 0xA443},
+ /* U+50__ */ {0xFF, 0x00, 0x6A8C, 0xA543}, {0xFF, 0x00, 0x6A8C, 0xA643},
+ /* U+52__ */ {0xFF, 0x00, 0x6A8C, 0xA743}, {0xFF, 0x00, 0x6A8C, 0xA843},
+ /* U+54__ */ {0xFF, 0x00, 0x6A8C, 0xA943}, {0xFF, 0x00, 0x6A8C, 0xAA43},
+ /* U+56__ */ {0xFF, 0x00, 0x6A8C, 0xAB43}, {0xFF, 0x00, 0x6A8C, 0xAC43},
+ /* U+58__ */ {0xFF, 0x00, 0x6A8C, 0xAD43}, {0xFF, 0x00, 0x6A8C, 0xAE43},
+ /* U+5A__ */ {0xFF, 0x00, 0x6A8C, 0xAF43}, {0xFF, 0x00, 0x6A8C, 0xB043},
+ /* U+5C__ */ {0xFF, 0x00, 0x6A8C, 0xB143}, {0xFF, 0x00, 0x6A8C, 0xB243},
+ /* U+5E__ */ {0xFF, 0x00, 0x6A8C, 0xB343}, {0xFF, 0x00, 0x6A8C, 0xB443},
+ /* U+60__ */ {0xFF, 0x00, 0x6A8C, 0xB543}, {0xFF, 0x00, 0x6A8C, 0xB643},
+ /* U+62__ */ {0xFF, 0x00, 0x6A8C, 0xB743}, {0xFF, 0x00, 0x6A8C, 0xB843},
+ /* U+64__ */ {0xFF, 0x00, 0x6A8C, 0xB943}, {0xFF, 0x00, 0x6A8C, 0xBA43},
+ /* U+66__ */ {0xFF, 0x00, 0x6A8C, 0xBB43}, {0xFF, 0x00, 0x6A8C, 0xBC43},
+ /* U+68__ */ {0xFF, 0x00, 0x6A8C, 0xBD43}, {0xFF, 0x00, 0x6A8C, 0xBE43},
+ /* U+6A__ */ {0xFF, 0x00, 0x6A8C, 0xBF43}, {0xFF, 0x00, 0x6A8C, 0xC043},
+ /* U+6C__ */ {0xFF, 0x00, 0x6A8C, 0xC143}, {0xFF, 0x00, 0x6A8C, 0xC243},
+ /* U+6E__ */ {0xFF, 0x00, 0x6A8C, 0xC343}, {0xFF, 0x00, 0x6A8C, 0xC443},
+ /* U+70__ */ {0xFF, 0x00, 0x6A8C, 0xC543}, {0xFF, 0x00, 0x6A8C, 0xC643},
+ /* U+72__ */ {0xFF, 0x00, 0x6A8C, 0xC743}, {0xFF, 0x00, 0x6A8C, 0xC843},
+ /* U+74__ */ {0xFF, 0x00, 0x6A8C, 0xC943}, {0xFF, 0x00, 0x6A8C, 0xCA43},
+ /* U+76__ */ {0xFF, 0x00, 0x6A8C, 0xCB43}, {0xFF, 0x00, 0x6A8C, 0xCC43},
+ /* U+78__ */ {0xFF, 0x00, 0x6A8C, 0xCD43}, {0xFF, 0x00, 0x6A8C, 0xCE43},
+ /* U+7A__ */ {0xFF, 0x00, 0x6A8C, 0xCF43}, {0xFF, 0x00, 0x6A8C, 0xD043},
+ /* U+7C__ */ {0xFF, 0x00, 0x6A8C, 0xD143}, {0xFF, 0x00, 0x6A8C, 0xD243},
+ /* U+7E__ */ {0xFF, 0x00, 0x6A8C, 0xD343}, {0xFF, 0x00, 0x6A8C, 0xD443},
+ /* U+80__ */ {0xFF, 0x00, 0x6A8C, 0xD543}, {0xFF, 0x00, 0x6A8C, 0xD643},
+ /* U+82__ */ {0xBD, 0xFF, 0x6A8C, 0xD743}, {0x00, 0x0D, 0x6A8C, 0xE857},
+ /* U+84__ */ {0xFF, 0x00, 0x7B53, 0xE957}, {0xFF, 0x00, 0x7B53, 0xEA57},
+ /* U+86__ */ {0xFF, 0x00, 0x7B53, 0xEB57}, {0xFF, 0x00, 0x7B53, 0xEC57},
+ /* U+88__ */ {0xFF, 0x00, 0x7B53, 0xED57}, {0xFF, 0x00, 0x7B53, 0xEE57},
+ /* U+8A__ */ {0xFF, 0x00, 0x7B53, 0xEF57}, {0xFF, 0x00, 0x7B53, 0xF057},
+ /* U+8C__ */ {0xFF, 0x00, 0x7B53, 0xF157}, {0xFF, 0x00, 0x7B53, 0xF257},
+ /* U+8E__ */ {0xFF, 0x00, 0x7B53, 0xF357}, {0xFF, 0x00, 0x7B53, 0xF457},
+ /* U+90__ */ {0xFF, 0x00, 0x7B53, 0xF557}, {0xFF, 0x00, 0x7B53, 0xF657},
+ /* U+92__ */ {0xFF, 0x00, 0x7B53, 0xF757}, {0xD5, 0xFF, 0x7B53, 0xF857},
+ /* U+94__ */ {0x00, 0xBD, 0x7B53, 0xF96C}, {0xFF, 0x00, 0x7F59, 0xFA6C},
+ /* U+96__ */ {0xFF, 0x00, 0x7F59, 0xFB6C}, {0xFF, 0x00, 0x7F59, 0xFC6C},
+ /* U+98__ */ {0xC4, 0xFF, 0x7F59, 0xFD6C}, {0x00, 0xE1, 0x7F59, 0xFF04},
+};
+
+static const indexTbl_t ucs_to_gb18030_index[256] = {
+ /* 0x00__ */ {0x80, 0xFF, 0x0080, 0x0000}, {0x00, 0xFF, 0x0080, 0x0000},
+ /* 0x02__ */ {0x00, 0xFF, 0x0080, 0x0000}, {0x00, 0xFF, 0x0080, 0x0000},
+ /* 0x04__ */ {0x00, 0x51, 0x0080, 0x02E2}, {0xFF, 0x00, 0x1C3E, 0x03E2},
+ /* 0x06__ */ {0xFF, 0x00, 0x1C3E, 0x04E2}, {0xFF, 0x00, 0x1C3E, 0x05E2},
+ /* 0x08__ */ {0xFF, 0x00, 0x1C3E, 0x06E2}, {0xFF, 0x00, 0x1C3E, 0x07E2},
+ /* 0x0A__ */ {0xFF, 0x00, 0x1C3E, 0x08E2}, {0xFF, 0x00, 0x1C3E, 0x09E2},
+ /* 0x0C__ */ {0xFF, 0x00, 0x1C3E, 0x0AE2}, {0xFF, 0x00, 0x1C3E, 0x0BE2},
+ /* 0x0E__ */ {0xFF, 0x00, 0x1C3E, 0x0CE2}, {0xFF, 0x00, 0x1C3E, 0x0DE2},
+ /* 0x10__ */ {0xFF, 0x00, 0x1C3E, 0x0EE2}, {0xFF, 0x00, 0x1C3E, 0x0FE2},
+ /* 0x12__ */ {0xFF, 0x00, 0x1C3E, 0x10E2}, {0xFF, 0x00, 0x1C3E, 0x11E2},
+ /* 0x14__ */ {0xFF, 0x00, 0x1C3E, 0x12E2}, {0xFF, 0x00, 0x1C3E, 0x13E2},
+ /* 0x16__ */ {0xFF, 0x00, 0x1C3E, 0x14E2}, {0xFF, 0x00, 0x1C3E, 0x15E2},
+ /* 0x18__ */ {0xFF, 0x00, 0x1C3E, 0x16E2}, {0xFF, 0x00, 0x1C3E, 0x17E2},
+ /* 0x1A__ */ {0xFF, 0x00, 0x1C3E, 0x18E2}, {0xFF, 0x00, 0x1C3E, 0x19E2},
+ /* 0x1C__ */ {0xFF, 0x00, 0x1C3E, 0x1AE2}, {0xFF, 0x00, 0x1C3E, 0x1BE2},
+ /* 0x1E__ */ {0xFF, 0x00, 0x1C3E, 0x1CE2}, {0xFF, 0x00, 0x1C3E, 0x1DE2},
+ /* 0x20__ */ {0x10, 0xFF, 0x1C3E, 0x1EE2}, {0x00, 0xFF, 0x1C3E, 0x0000},
+ /* 0x22__ */ {0x00, 0xFF, 0x1C3E, 0x0000}, {0x00, 0xFF, 0x1C3E, 0x0000},
+ /* 0x24__ */ {0x00, 0xFF, 0x1C3E, 0x0000}, {0x00, 0xFF, 0x1C3E, 0x0000},
+ /* 0x26__ */ {0x00, 0x42, 0x1C3E, 0x23C0}, {0xFF, 0x00, 0x247C, 0x24C0},
+ /* 0x28__ */ {0xFF, 0x00, 0x247C, 0x25C0}, {0xFF, 0x00, 0x247C, 0x26C0},
+ /* 0x2A__ */ {0xFF, 0x00, 0x247C, 0x27C0}, {0xFF, 0x00, 0x247C, 0x28C0},
+ /* 0x2C__ */ {0xFF, 0x00, 0x247C, 0x29C0}, {0xFF, 0x00, 0x247C, 0x2AC0},
+ /* 0x2E__ */ {0x81, 0xFF, 0x247C, 0x2BC0}, {0x00, 0xFF, 0x247C, 0x0000},
+ /* 0x30__ */ {0x00, 0xFF, 0x247C, 0x0000}, {0x00, 0xFF, 0x247C, 0x0000},
+ /* 0x32__ */ {0x00, 0xFF, 0x247C, 0x0000}, {0x00, 0xFF, 0x247C, 0x0000},
+ /* 0x34__ */ {0x00, 0xFF, 0x247C, 0x0000}, {0x00, 0xFF, 0x247C, 0x0000},
+ /* 0x36__ */ {0x00, 0x1A, 0x247C, 0x3292}, {0xFF, 0x00, 0x2779, 0x3392},
+ /* 0x38__ */ {0xFF, 0x00, 0x2779, 0x3492}, {0x18, 0xFF, 0x2779, 0x3592},
+ /* 0x3A__ */ {0x00, 0xFF, 0x2779, 0x0000}, {0x00, 0xFF, 0x2779, 0x0000},
+ /* 0x3C__ */ {0x00, 0xE0, 0x2779, 0x3889}, {0xFF, 0x00, 0x2AEE, 0x3989},
+ /* 0x3E__ */ {0xFF, 0x00, 0x2AEE, 0x3A89}, {0xFF, 0x00, 0x2AEE, 0x3B89},
+ /* 0x40__ */ {0x56, 0xFF, 0x2AEE, 0x3C89}, {0x00, 0x5F, 0x2AEE, 0x3D87},
+ /* 0x42__ */ {0xFF, 0x00, 0x2CC5, 0x3E87}, {0x37, 0xFF, 0x2CC5, 0x3F87},
+ /* 0x44__ */ {0x00, 0xD6, 0x2CC5, 0x4082}, {0xFF, 0x00, 0x2E3A, 0x4182},
+ /* 0x46__ */ {0x4C, 0xFF, 0x2E3A, 0x4282}, {0x00, 0x8D, 0x2E3A, 0x437C},
+ /* 0x48__ */ {0xFF, 0x00, 0x2FF3, 0x447C}, {0x47, 0xB7, 0x2FF3, 0x457C},
+ /* 0x4A__ */ {0xFF, 0x00, 0x32B2, 0x4671}, {0xFF, 0x00, 0x32B2, 0x4771},
+ /* 0x4C__ */ {0x77, 0xFF, 0x32B2, 0x4871}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x4E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x50__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x52__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x54__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x56__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x58__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x5A__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x5C__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x5E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x60__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x62__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x64__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x66__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x68__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x6A__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x6C__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x6E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x70__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x72__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x74__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x76__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x78__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x7A__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x7C__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x7E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x80__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x82__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x84__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x86__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x88__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x8A__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x8C__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x8E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x90__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x92__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x94__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x96__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x98__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x9A__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x9C__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xFF, 0x32B2, 0x0000},
+ /* 0x9E__ */ {0x00, 0xFF, 0x32B2, 0x0000}, {0x00, 0xA5, 0x32B2, 0x49BD},
+ /* 0xA0__ */ {0xFF, 0x00, 0x6B0C, 0x4ABD}, {0xFF, 0x00, 0x6B0C, 0x4BBD},
+ /* 0xA2__ */ {0xFF, 0x00, 0x6B0C, 0x4CBD}, {0xFF, 0x00, 0x6B0C, 0x4DBD},
+ /* 0xA4__ */ {0xFF, 0x00, 0x6B0C, 0x4EBD}, {0xFF, 0x00, 0x6B0C, 0x4FBD},
+ /* 0xA6__ */ {0xFF, 0x00, 0x6B0C, 0x50BD}, {0xFF, 0x00, 0x6B0C, 0x51BD},
+ /* 0xA8__ */ {0xFF, 0x00, 0x6B0C, 0x52BD}, {0xFF, 0x00, 0x6B0C, 0x53BD},
+ /* 0xAA__ */ {0xFF, 0x00, 0x6B0C, 0x54BD}, {0xFF, 0x00, 0x6B0C, 0x55BD},
+ /* 0xAC__ */ {0xFF, 0x00, 0x6B0C, 0x56BD}, {0xFF, 0x00, 0x6B0C, 0x57BD},
+ /* 0xAE__ */ {0xFF, 0x00, 0x6B0C, 0x58BD}, {0xFF, 0x00, 0x6B0C, 0x59BD},
+ /* 0xB0__ */ {0xFF, 0x00, 0x6B0C, 0x5ABD}, {0xFF, 0x00, 0x6B0C, 0x5BBD},
+ /* 0xB2__ */ {0xFF, 0x00, 0x6B0C, 0x5CBD}, {0xFF, 0x00, 0x6B0C, 0x5DBD},
+ /* 0xB4__ */ {0xFF, 0x00, 0x6B0C, 0x5EBD}, {0xFF, 0x00, 0x6B0C, 0x5FBD},
+ /* 0xB6__ */ {0xFF, 0x00, 0x6B0C, 0x60BD}, {0xFF, 0x00, 0x6B0C, 0x61BD},
+ /* 0xB8__ */ {0xFF, 0x00, 0x6B0C, 0x62BD}, {0xFF, 0x00, 0x6B0C, 0x63BD},
+ /* 0xBA__ */ {0xFF, 0x00, 0x6B0C, 0x64BD}, {0xFF, 0x00, 0x6B0C, 0x65BD},
+ /* 0xBC__ */ {0xFF, 0x00, 0x6B0C, 0x66BD}, {0xFF, 0x00, 0x6B0C, 0x67BD},
+ /* 0xBE__ */ {0xFF, 0x00, 0x6B0C, 0x68BD}, {0xFF, 0x00, 0x6B0C, 0x69BD},
+ /* 0xC0__ */ {0xFF, 0x00, 0x6B0C, 0x6ABD}, {0xFF, 0x00, 0x6B0C, 0x6BBD},
+ /* 0xC2__ */ {0xFF, 0x00, 0x6B0C, 0x6CBD}, {0xFF, 0x00, 0x6B0C, 0x6DBD},
+ /* 0xC4__ */ {0xFF, 0x00, 0x6B0C, 0x6EBD}, {0xFF, 0x00, 0x6B0C, 0x6FBD},
+ /* 0xC6__ */ {0xFF, 0x00, 0x6B0C, 0x70BD}, {0xFF, 0x00, 0x6B0C, 0x71BD},
+ /* 0xC8__ */ {0xFF, 0x00, 0x6B0C, 0x72BD}, {0xFF, 0x00, 0x6B0C, 0x73BD},
+ /* 0xCA__ */ {0xFF, 0x00, 0x6B0C, 0x74BD}, {0xFF, 0x00, 0x6B0C, 0x75BD},
+ /* 0xCC__ */ {0xFF, 0x00, 0x6B0C, 0x76BD}, {0xFF, 0x00, 0x6B0C, 0x77BD},
+ /* 0xCE__ */ {0xFF, 0x00, 0x6B0C, 0x78BD}, {0xFF, 0x00, 0x6B0C, 0x79BD},
+ /* 0xD0__ */ {0xFF, 0x00, 0x6B0C, 0x7ABD}, {0xFF, 0x00, 0x6B0C, 0x7BBD},
+ /* 0xD2__ */ {0xFF, 0x00, 0x6B0C, 0x7CBD}, {0xFF, 0x00, 0x6B0C, 0x7DBD},
+ /* 0xD4__ */ {0xFF, 0x00, 0x6B0C, 0x7EBD}, {0xFF, 0x00, 0x6B0C, 0x7FBD},
+ /* 0xD6__ */ {0xFF, 0x00, 0x6B0C, 0x80BD}, {0xFF, 0x00, 0x6B0C, 0x81BD},
+ /* 0xD8__ */ {0xFF, 0x00, 0x6B0C, 0x0000}, {0xFF, 0x00, 0x6B0C, 0x0000},
+ /* 0xDA__ */ {0xFF, 0x00, 0x6B0C, 0x0000}, {0xFF, 0x00, 0x6B0C, 0x0000},
+ /* 0xDC__ */ {0xFF, 0x00, 0x6B0C, 0x0000}, {0xFF, 0x00, 0x6B0C, 0x0000},
+ /* 0xDE__ */ {0xFF, 0x00, 0x6B0C, 0x0000}, {0xFF, 0x00, 0x6B0C, 0x0000},
+ /* 0xE0__ */ {0xFF, 0x00, 0x7A72, 0x0000}, {0xFF, 0x00, 0x7A72, 0x0000},
+ /* 0xE2__ */ {0xFF, 0x00, 0x7A72, 0x0000}, {0xFF, 0x00, 0x7A72, 0x0000},
+ /* 0xE4__ */ {0xFF, 0x00, 0x7A72, 0x0000}, {0xFF, 0x00, 0x7A72, 0x0000},
+ /* 0xE6__ */ {0xFF, 0x00, 0x7A72, 0x0000}, {0x66, 0xFF, 0x7A72, 0x0000},
+ /* 0xE8__ */ {0x00, 0x64, 0x7A72, 0x82A9}, {0xFF, 0x00, 0x8B39, 0x83A9},
+ /* 0xEA__ */ {0xFF, 0x00, 0x8B39, 0x84A9}, {0xFF, 0x00, 0x8B39, 0x85A9},
+ /* 0xEC__ */ {0xFF, 0x00, 0x8B39, 0x86A9}, {0xFF, 0x00, 0x8B39, 0x87A9},
+ /* 0xEE__ */ {0xFF, 0x00, 0x8B39, 0x88A9}, {0xFF, 0x00, 0x8B39, 0x89A9},
+ /* 0xF0__ */ {0xFF, 0x00, 0x8B39, 0x8AA9}, {0xFF, 0x00, 0x8B39, 0x8BA9},
+ /* 0xF2__ */ {0xFF, 0x00, 0x8B39, 0x8CA9}, {0xFF, 0x00, 0x8B39, 0x8DA9},
+ /* 0xF4__ */ {0xFF, 0x00, 0x8B39, 0x8EA9}, {0xFF, 0x00, 0x8B39, 0x8FA9},
+ /* 0xF6__ */ {0xFF, 0x00, 0x8B39, 0x90A9}, {0xFF, 0x00, 0x8B39, 0x91A9},
+ /* 0xF8__ */ {0xFF, 0x00, 0x8B39, 0x92A9}, {0x2C, 0xFF, 0x8B39, 0x93A9},
+ /* 0xFA__ */ {0x00, 0x29, 0x8B39, 0x9494}, {0xFF, 0x00, 0x8F3F, 0x9594},
+ /* 0xFC__ */ {0xFF, 0x00, 0x8F3F, 0x9694}, {0xFF, 0x00, 0x8F3F, 0x9794},
+ /* 0xFE__ */ {0x30, 0xFF, 0x8F3F, 0x9894}, {0x00, 0xE5, 0x8F3F, 0x98FC},
+};
+
+static TQ_UINT16 const ucs_to_gb18030[28839] = {
+ /* Contiguous area: U+0080 .. U+0451 */
+ /* U+0080 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ /* U+0088 */ 0x0008, 0x0009, 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015,
+ /* U+0090 */ 0x0016, 0x0017, 0x0018, 0x0019, 0x0020, 0x0021, 0x0022, 0x0023,
+ /* U+0098 */ 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x0030, 0x0031,
+ /* U+00A0 */ 0x0032, 0x0033, 0x0034, 0x0035, 0xA1E8, 0x0036, 0x0037, 0xA1EC,
+ /* U+00A8 */ 0xA1A7, 0x0038, 0x0039, 0x0040, 0x0041, 0x0042, 0x0043, 0x0044,
+ /* U+00B0 */ 0xA1E3, 0xA1C0, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0xA1A4,
+ /* U+00B8 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
+ /* U+00C0 */ 0x0058, 0x0059, 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065,
+ /* U+00C8 */ 0x0066, 0x0067, 0x0068, 0x0069, 0x0070, 0x0071, 0x0072, 0x0073,
+ /* U+00D0 */ 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, 0x0080, 0xA1C1,
+ /* U+00D8 */ 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, 0x0088,
+ /* U+00E0 */ 0xA8A4, 0xA8A2, 0x0089, 0x0090, 0x0091, 0x0092, 0x0093, 0x0094,
+ /* U+00E8 */ 0xA8A8, 0xA8A6, 0xA8BA, 0x0095, 0xA8AC, 0xA8AA, 0x0096, 0x0097,
+ /* U+00F0 */ 0x0098, 0x0099, 0xA8B0, 0xA8AE, 0x00A0, 0x00A1, 0x00A2, 0xA1C2,
+ /* U+00F8 */ 0x00A3, 0xA8B4, 0xA8B2, 0x00A4, 0xA8B9, 0x00A5, 0x00A6, 0x00A7,
+ /* U+0100 */ 0x00A8, 0xA8A1, 0x00A9, 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4,
+ /* U+0108 */ 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00B9, 0x00C0, 0x00C1, 0x00C2,
+ /* U+0110 */ 0x00C3, 0x00C4, 0x00C5, 0xA8A5, 0x00C6, 0x00C7, 0x00C8, 0x00C9,
+ /* U+0118 */ 0x00D0, 0x00D1, 0x00D2, 0xA8A7, 0x00D3, 0x00D4, 0x00D5, 0x00D6,
+ /* U+0120 */ 0x00D7, 0x00D8, 0x00D9, 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4,
+ /* U+0128 */ 0x00E5, 0x00E6, 0x00E7, 0xA8A9, 0x00E8, 0x00E9, 0x00F0, 0x00F1,
+ /* U+0130 */ 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, 0x00F9,
+ /* U+0138 */ 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
+ /* U+0140 */ 0x0108, 0x0109, 0x0110, 0x0111, 0xA8BD, 0x0112, 0x0113, 0x0114,
+ /* U+0148 */ 0xA8BE, 0x0115, 0x0116, 0x0117, 0x0118, 0xA8AD, 0x0119, 0x0120,
+ /* U+0150 */ 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, 0x0127, 0x0128,
+ /* U+0158 */ 0x0129, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136,
+ /* U+0160 */ 0x0137, 0x0138, 0x0139, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144,
+ /* U+0168 */ 0x0145, 0x0146, 0x0147, 0xA8B1, 0x0148, 0x0149, 0x0150, 0x0151,
+ /* U+0170 */ 0x0152, 0x0153, 0x0154, 0x0155, 0x0156, 0x0157, 0x0158, 0x0159,
+ /* U+0178 */ 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, 0x0166, 0x0167,
+ /* U+0180 */ 0x0168, 0x0169, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175,
+ /* U+0188 */ 0x0176, 0x0177, 0x0178, 0x0179, 0x0180, 0x0181, 0x0182, 0x0183,
+ /* U+0190 */ 0x0184, 0x0185, 0x0186, 0x0187, 0x0188, 0x0189, 0x0190, 0x0191,
+ /* U+0198 */ 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, 0x0197, 0x0198, 0x0199,
+ /* U+01A0 */ 0x01A0, 0x01A1, 0x01A2, 0x01A3, 0x01A4, 0x01A5, 0x01A6, 0x01A7,
+ /* U+01A8 */ 0x01A8, 0x01A9, 0x01B0, 0x01B1, 0x01B2, 0x01B3, 0x01B4, 0x01B5,
+ /* U+01B0 */ 0x01B6, 0x01B7, 0x01B8, 0x01B9, 0x01C0, 0x01C1, 0x01C2, 0x01C3,
+ /* U+01B8 */ 0x01C4, 0x01C5, 0x01C6, 0x01C7, 0x01C8, 0x01C9, 0x01D0, 0x01D1,
+ /* U+01C0 */ 0x01D2, 0x01D3, 0x01D4, 0x01D5, 0x01D6, 0x01D7, 0x01D8, 0x01D9,
+ /* U+01C8 */ 0x01E0, 0x01E1, 0x01E2, 0x01E3, 0x01E4, 0x01E5, 0xA8A3, 0x01E6,
+ /* U+01D0 */ 0xA8AB, 0x01E7, 0xA8AF, 0x01E8, 0xA8B3, 0x01E9, 0xA8B5, 0x01F0,
+ /* U+01D8 */ 0xA8B6, 0x01F1, 0xA8B7, 0x01F2, 0xA8B8, 0x01F3, 0x01F4, 0x01F5,
+ /* U+01E0 */ 0x01F6, 0x01F7, 0x01F8, 0x01F9, 0x0200, 0x0201, 0x0202, 0x0203,
+ /* U+01E8 */ 0x0204, 0x0205, 0x0206, 0x0207, 0x0208, 0x0209, 0x0210, 0x0211,
+ /* U+01F0 */ 0x0212, 0x0213, 0x0214, 0x0215, 0x0216, 0x0217, 0x0218, 0x0219,
+ /* U+01F8 */ 0x0220, 0xA8BF, 0x0221, 0x0222, 0x0223, 0x0224, 0x0225, 0x0226,
+ /* U+0200 */ 0x0227, 0x0228, 0x0229, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234,
+ /* U+0208 */ 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x0240, 0x0241, 0x0242,
+ /* U+0210 */ 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, 0x0249, 0x0250,
+ /* U+0218 */ 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0257, 0x0258,
+ /* U+0220 */ 0x0259, 0x0260, 0x0261, 0x0262, 0x0263, 0x0264, 0x0265, 0x0266,
+ /* U+0228 */ 0x0267, 0x0268, 0x0269, 0x0270, 0x0271, 0x0272, 0x0273, 0x0274,
+ /* U+0230 */ 0x0275, 0x0276, 0x0277, 0x0278, 0x0279, 0x0280, 0x0281, 0x0282,
+ /* U+0238 */ 0x0283, 0x0284, 0x0285, 0x0286, 0x0287, 0x0288, 0x0289, 0x0290,
+ /* U+0240 */ 0x0291, 0x0292, 0x0293, 0x0294, 0x0295, 0x0296, 0x0297, 0x0298,
+ /* U+0248 */ 0x0299, 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x02A4, 0x02A5, 0x02A6,
+ /* U+0250 */ 0x02A7, 0xA8BB, 0x02A8, 0x02A9, 0x02B0, 0x02B1, 0x02B2, 0x02B3,
+ /* U+0258 */ 0x02B4, 0x02B5, 0x02B6, 0x02B7, 0x02B8, 0x02B9, 0x02C0, 0x02C1,
+ /* U+0260 */ 0x02C2, 0xA8C0, 0x02C3, 0x02C4, 0x02C5, 0x02C6, 0x02C7, 0x02C8,
+ /* U+0268 */ 0x02C9, 0x02D0, 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5, 0x02D6,
+ /* U+0270 */ 0x02D7, 0x02D8, 0x02D9, 0x02E0, 0x02E1, 0x02E2, 0x02E3, 0x02E4,
+ /* U+0278 */ 0x02E5, 0x02E6, 0x02E7, 0x02E8, 0x02E9, 0x02F0, 0x02F1, 0x02F2,
+ /* U+0280 */ 0x02F3, 0x02F4, 0x02F5, 0x02F6, 0x02F7, 0x02F8, 0x02F9, 0x0300,
+ /* U+0288 */ 0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308,
+ /* U+0290 */ 0x0309, 0x0310, 0x0311, 0x0312, 0x0313, 0x0314, 0x0315, 0x0316,
+ /* U+0298 */ 0x0317, 0x0318, 0x0319, 0x0320, 0x0321, 0x0322, 0x0323, 0x0324,
+ /* U+02A0 */ 0x0325, 0x0326, 0x0327, 0x0328, 0x0329, 0x0330, 0x0331, 0x0332,
+ /* U+02A8 */ 0x0333, 0x0334, 0x0335, 0x0336, 0x0337, 0x0338, 0x0339, 0x0340,
+ /* U+02B0 */ 0x0341, 0x0342, 0x0343, 0x0344, 0x0345, 0x0346, 0x0347, 0x0348,
+ /* U+02B8 */ 0x0349, 0x0350, 0x0351, 0x0352, 0x0353, 0x0354, 0x0355, 0x0356,
+ /* U+02C0 */ 0x0357, 0x0358, 0x0359, 0x0360, 0x0361, 0x0362, 0x0363, 0xA1A6,
+ /* U+02C8 */ 0x0364, 0xA1A5, 0xA840, 0xA841, 0x0365, 0x0366, 0x0367, 0x0368,
+ /* U+02D0 */ 0x0369, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, 0x0375, 0x0376,
+ /* U+02D8 */ 0x0377, 0xA842, 0x0378, 0x0379, 0x0380, 0x0381, 0x0382, 0x0383,
+ /* U+02E0 */ 0x0384, 0x0385, 0x0386, 0x0387, 0x0388, 0x0389, 0x0390, 0x0391,
+ /* U+02E8 */ 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399,
+ /* U+02F0 */ 0x03A0, 0x03A1, 0x03A2, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ /* U+02F8 */ 0x03A8, 0x03A9, 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5,
+ /* U+0300 */ 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03C0, 0x03C1, 0x03C2, 0x03C3,
+ /* U+0308 */ 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x03D0, 0x03D1,
+ /* U+0310 */ 0x03D2, 0x03D3, 0x03D4, 0x03D5, 0x03D6, 0x03D7, 0x03D8, 0x03D9,
+ /* U+0318 */ 0x03E0, 0x03E1, 0x03E2, 0x03E3, 0x03E4, 0x03E5, 0x03E6, 0x03E7,
+ /* U+0320 */ 0x03E8, 0x03E9, 0x03F0, 0x03F1, 0x03F2, 0x03F3, 0x03F4, 0x03F5,
+ /* U+0328 */ 0x03F6, 0x03F7, 0x03F8, 0x03F9, 0x0400, 0x0401, 0x0402, 0x0403,
+ /* U+0330 */ 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x0410, 0x0411,
+ /* U+0338 */ 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419,
+ /* U+0340 */ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ /* U+0348 */ 0x0428, 0x0429, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435,
+ /* U+0350 */ 0x0436, 0x0437, 0x0438, 0x0439, 0x0440, 0x0441, 0x0442, 0x0443,
+ /* U+0358 */ 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x0450, 0x0451,
+ /* U+0360 */ 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459,
+ /* U+0368 */ 0x0460, 0x0461, 0x0462, 0x0463, 0x0464, 0x0465, 0x0466, 0x0467,
+ /* U+0370 */ 0x0468, 0x0469, 0x0470, 0x0471, 0x0472, 0x0473, 0x0474, 0x0475,
+ /* U+0378 */ 0x0476, 0x0477, 0x0478, 0x0479, 0x0480, 0x0481, 0x0482, 0x0483,
+ /* U+0380 */ 0x0484, 0x0485, 0x0486, 0x0487, 0x0488, 0x0489, 0x0490, 0x0491,
+ /* U+0388 */ 0x0492, 0x0493, 0x0494, 0x0495, 0x0496, 0x0497, 0x0498, 0x0499,
+ /* U+0390 */ 0x04A0, 0xA6A1, 0xA6A2, 0xA6A3, 0xA6A4, 0xA6A5, 0xA6A6, 0xA6A7,
+ /* U+0398 */ 0xA6A8, 0xA6A9, 0xA6AA, 0xA6AB, 0xA6AC, 0xA6AD, 0xA6AE, 0xA6AF,
+ /* U+03A0 */ 0xA6B0, 0xA6B1, 0x04A1, 0xA6B2, 0xA6B3, 0xA6B4, 0xA6B5, 0xA6B6,
+ /* U+03A8 */ 0xA6B7, 0xA6B8, 0x04A2, 0x04A3, 0x04A4, 0x04A5, 0x04A6, 0x04A7,
+ /* U+03B0 */ 0x04A8, 0xA6C1, 0xA6C2, 0xA6C3, 0xA6C4, 0xA6C5, 0xA6C6, 0xA6C7,
+ /* U+03B8 */ 0xA6C8, 0xA6C9, 0xA6CA, 0xA6CB, 0xA6CC, 0xA6CD, 0xA6CE, 0xA6CF,
+ /* U+03C0 */ 0xA6D0, 0xA6D1, 0x04A9, 0xA6D2, 0xA6D3, 0xA6D4, 0xA6D5, 0xA6D6,
+ /* U+03C8 */ 0xA6D7, 0xA6D8, 0x04B0, 0x04B1, 0x04B2, 0x04B3, 0x04B4, 0x04B5,
+ /* U+03D0 */ 0x04B6, 0x04B7, 0x04B8, 0x04B9, 0x04C0, 0x04C1, 0x04C2, 0x04C3,
+ /* U+03D8 */ 0x04C4, 0x04C5, 0x04C6, 0x04C7, 0x04C8, 0x04C9, 0x04D0, 0x04D1,
+ /* U+03E0 */ 0x04D2, 0x04D3, 0x04D4, 0x04D5, 0x04D6, 0x04D7, 0x04D8, 0x04D9,
+ /* U+03E8 */ 0x04E0, 0x04E1, 0x04E2, 0x04E3, 0x04E4, 0x04E5, 0x04E6, 0x04E7,
+ /* U+03F0 */ 0x04E8, 0x04E9, 0x04F0, 0x04F1, 0x04F2, 0x04F3, 0x04F4, 0x04F5,
+ /* U+03F8 */ 0x04F6, 0x04F7, 0x04F8, 0x04F9, 0x0500, 0x0501, 0x0502, 0x0503,
+ /* U+0400 */ 0x0504, 0xA7A7, 0x0505, 0x0506, 0x0507, 0x0508, 0x0509, 0x0510,
+ /* U+0408 */ 0x0511, 0x0512, 0x0513, 0x0514, 0x0515, 0x0516, 0x0517, 0x0518,
+ /* U+0410 */ 0xA7A1, 0xA7A2, 0xA7A3, 0xA7A4, 0xA7A5, 0xA7A6, 0xA7A8, 0xA7A9,
+ /* U+0418 */ 0xA7AA, 0xA7AB, 0xA7AC, 0xA7AD, 0xA7AE, 0xA7AF, 0xA7B0, 0xA7B1,
+ /* U+0420 */ 0xA7B2, 0xA7B3, 0xA7B4, 0xA7B5, 0xA7B6, 0xA7B7, 0xA7B8, 0xA7B9,
+ /* U+0428 */ 0xA7BA, 0xA7BB, 0xA7BC, 0xA7BD, 0xA7BE, 0xA7BF, 0xA7C0, 0xA7C1,
+ /* U+0430 */ 0xA7D1, 0xA7D2, 0xA7D3, 0xA7D4, 0xA7D5, 0xA7D6, 0xA7D8, 0xA7D9,
+ /* U+0438 */ 0xA7DA, 0xA7DB, 0xA7DC, 0xA7DD, 0xA7DE, 0xA7DF, 0xA7E0, 0xA7E1,
+ /* U+0440 */ 0xA7E2, 0xA7E3, 0xA7E4, 0xA7E5, 0xA7E6, 0xA7E7, 0xA7E8, 0xA7E9,
+ /* U+0448 */ 0xA7EA, 0xA7EB, 0xA7EC, 0xA7ED, 0xA7EE, 0xA7EF, 0xA7F0, 0xA7F1,
+ /* U+0450 */ 0x0519, 0xA7D7,
+ /* Contiguous area: U+2010 .. U+2642 */
+ /* U+2010 */ 0xA95C, 0x0A42, 0x0A43, 0xA843, 0xA1AA, 0xA844, 0xA1AC, 0x0A44,
+ /* U+2018 */ 0xA1AE, 0xA1AF, 0x0A45, 0x0A46, 0xA1B0, 0xA1B1, 0x0A47, 0x0A48,
+ /* U+2020 */ 0x0A49, 0x0A50, 0x0A51, 0x0A52, 0x0A53, 0xA845, 0xA1AD, 0x0A54,
+ /* U+2028 */ 0x0A55, 0x0A56, 0x0A57, 0x0A58, 0x0A59, 0x0A60, 0x0A61, 0x0A62,
+ /* U+2030 */ 0xA1EB, 0x0A63, 0xA1E4, 0xA1E5, 0x0A64, 0xA846, 0x0A65, 0x0A66,
+ /* U+2038 */ 0x0A67, 0x0A68, 0x0A69, 0xA1F9, 0x0A70, 0x0A71, 0x0A72, 0x0A73,
+ /* U+2040 */ 0x0A74, 0x0A75, 0x0A76, 0x0A77, 0x0A78, 0x0A79, 0x0A80, 0x0A81,
+ /* U+2048 */ 0x0A82, 0x0A83, 0x0A84, 0x0A85, 0x0A86, 0x0A87, 0x0A88, 0x0A89,
+ /* U+2050 */ 0x0A90, 0x0A91, 0x0A92, 0x0A93, 0x0A94, 0x0A95, 0x0A96, 0x0A97,
+ /* U+2058 */ 0x0A98, 0x0A99, 0x0AA0, 0x0AA1, 0x0AA2, 0x0AA3, 0x0AA4, 0x0AA5,
+ /* U+2060 */ 0x0AA6, 0x0AA7, 0x0AA8, 0x0AA9, 0x0AB0, 0x0AB1, 0x0AB2, 0x0AB3,
+ /* U+2068 */ 0x0AB4, 0x0AB5, 0x0AB6, 0x0AB7, 0x0AB8, 0x0AB9, 0x0AC0, 0x0AC1,
+ /* U+2070 */ 0x0AC2, 0x0AC3, 0x0AC4, 0x0AC5, 0x0AC6, 0x0AC7, 0x0AC8, 0x0AC9,
+ /* U+2078 */ 0x0AD0, 0x0AD1, 0x0AD2, 0x0AD3, 0x0AD4, 0x0AD5, 0x0AD6, 0x0AD7,
+ /* U+2080 */ 0x0AD8, 0x0AD9, 0x0AE0, 0x0AE1, 0x0AE2, 0x0AE3, 0x0AE4, 0x0AE5,
+ /* U+2088 */ 0x0AE6, 0x0AE7, 0x0AE8, 0x0AE9, 0x0AF0, 0x0AF1, 0x0AF2, 0x0AF3,
+ /* U+2090 */ 0x0AF4, 0x0AF5, 0x0AF6, 0x0AF7, 0x0AF8, 0x0AF9, 0x0B00, 0x0B01,
+ /* U+2098 */ 0x0B02, 0x0B03, 0x0B04, 0x0B05, 0x0B06, 0x0B07, 0x0B08, 0x0B09,
+ /* U+20A0 */ 0x0B10, 0x0B11, 0x0B12, 0x0B13, 0x0B14, 0x0B15, 0x0B16, 0x0B17,
+ /* U+20A8 */ 0x0B18, 0x0B19, 0x0B20, 0x0B21, 0xA2E3, 0x0B22, 0x0B23, 0x0B24,
+ /* U+20B0 */ 0x0B25, 0x0B26, 0x0B27, 0x0B28, 0x0B29, 0x0B30, 0x0B31, 0x0B32,
+ /* U+20B8 */ 0x0B33, 0x0B34, 0x0B35, 0x0B36, 0x0B37, 0x0B38, 0x0B39, 0x0B40,
+ /* U+20C0 */ 0x0B41, 0x0B42, 0x0B43, 0x0B44, 0x0B45, 0x0B46, 0x0B47, 0x0B48,
+ /* U+20C8 */ 0x0B49, 0x0B50, 0x0B51, 0x0B52, 0x0B53, 0x0B54, 0x0B55, 0x0B56,
+ /* U+20D0 */ 0x0B57, 0x0B58, 0x0B59, 0x0B60, 0x0B61, 0x0B62, 0x0B63, 0x0B64,
+ /* U+20D8 */ 0x0B65, 0x0B66, 0x0B67, 0x0B68, 0x0B69, 0x0B70, 0x0B71, 0x0B72,
+ /* U+20E0 */ 0x0B73, 0x0B74, 0x0B75, 0x0B76, 0x0B77, 0x0B78, 0x0B79, 0x0B80,
+ /* U+20E8 */ 0x0B81, 0x0B82, 0x0B83, 0x0B84, 0x0B85, 0x0B86, 0x0B87, 0x0B88,
+ /* U+20F0 */ 0x0B89, 0x0B90, 0x0B91, 0x0B92, 0x0B93, 0x0B94, 0x0B95, 0x0B96,
+ /* U+20F8 */ 0x0B97, 0x0B98, 0x0B99, 0x0BA0, 0x0BA1, 0x0BA2, 0x0BA3, 0x0BA4,
+ /* U+2100 */ 0x0BA5, 0x0BA6, 0x0BA7, 0xA1E6, 0x0BA8, 0xA847, 0x0BA9, 0x0BB0,
+ /* U+2108 */ 0x0BB1, 0xA848, 0x0BB2, 0x0BB3, 0x0BB4, 0x0BB5, 0x0BB6, 0x0BB7,
+ /* U+2110 */ 0x0BB8, 0x0BB9, 0x0BC0, 0x0BC1, 0x0BC2, 0x0BC3, 0xA1ED, 0x0BC4,
+ /* U+2118 */ 0x0BC5, 0x0BC6, 0x0BC7, 0x0BC8, 0x0BC9, 0x0BD0, 0x0BD1, 0x0BD2,
+ /* U+2120 */ 0x0BD3, 0xA959, 0x0BD4, 0x0BD5, 0x0BD6, 0x0BD7, 0x0BD8, 0x0BD9,
+ /* U+2128 */ 0x0BE0, 0x0BE1, 0x0BE2, 0x0BE3, 0x0BE4, 0x0BE5, 0x0BE6, 0x0BE7,
+ /* U+2130 */ 0x0BE8, 0x0BE9, 0x0BF0, 0x0BF1, 0x0BF2, 0x0BF3, 0x0BF4, 0x0BF5,
+ /* U+2138 */ 0x0BF6, 0x0BF7, 0x0BF8, 0x0BF9, 0x0C00, 0x0C01, 0x0C02, 0x0C03,
+ /* U+2140 */ 0x0C04, 0x0C05, 0x0C06, 0x0C07, 0x0C08, 0x0C09, 0x0C10, 0x0C11,
+ /* U+2148 */ 0x0C12, 0x0C13, 0x0C14, 0x0C15, 0x0C16, 0x0C17, 0x0C18, 0x0C19,
+ /* U+2150 */ 0x0C20, 0x0C21, 0x0C22, 0x0C23, 0x0C24, 0x0C25, 0x0C26, 0x0C27,
+ /* U+2158 */ 0x0C28, 0x0C29, 0x0C30, 0x0C31, 0x0C32, 0x0C33, 0x0C34, 0x0C35,
+ /* U+2160 */ 0xA2F1, 0xA2F2, 0xA2F3, 0xA2F4, 0xA2F5, 0xA2F6, 0xA2F7, 0xA2F8,
+ /* U+2168 */ 0xA2F9, 0xA2FA, 0xA2FB, 0xA2FC, 0x0C36, 0x0C37, 0x0C38, 0x0C39,
+ /* U+2170 */ 0xA2A1, 0xA2A2, 0xA2A3, 0xA2A4, 0xA2A5, 0xA2A6, 0xA2A7, 0xA2A8,
+ /* U+2178 */ 0xA2A9, 0xA2AA, 0x0C40, 0x0C41, 0x0C42, 0x0C43, 0x0C44, 0x0C45,
+ /* U+2180 */ 0x0C46, 0x0C47, 0x0C48, 0x0C49, 0x0C50, 0x0C51, 0x0C52, 0x0C53,
+ /* U+2188 */ 0x0C54, 0x0C55, 0x0C56, 0x0C57, 0x0C58, 0x0C59, 0x0C60, 0x0C61,
+ /* U+2190 */ 0xA1FB, 0xA1FC, 0xA1FA, 0xA1FD, 0x0C62, 0x0C63, 0xA849, 0xA84A,
+ /* U+2198 */ 0xA84B, 0xA84C, 0x0C64, 0x0C65, 0x0C66, 0x0C67, 0x0C68, 0x0C69,
+ /* U+21A0 */ 0x0C70, 0x0C71, 0x0C72, 0x0C73, 0x0C74, 0x0C75, 0x0C76, 0x0C77,
+ /* U+21A8 */ 0x0C78, 0x0C79, 0x0C80, 0x0C81, 0x0C82, 0x0C83, 0x0C84, 0x0C85,
+ /* U+21B0 */ 0x0C86, 0x0C87, 0x0C88, 0x0C89, 0x0C90, 0x0C91, 0x0C92, 0x0C93,
+ /* U+21B8 */ 0x0C94, 0x0C95, 0x0C96, 0x0C97, 0x0C98, 0x0C99, 0x0CA0, 0x0CA1,
+ /* U+21C0 */ 0x0CA2, 0x0CA3, 0x0CA4, 0x0CA5, 0x0CA6, 0x0CA7, 0x0CA8, 0x0CA9,
+ /* U+21C8 */ 0x0CB0, 0x0CB1, 0x0CB2, 0x0CB3, 0x0CB4, 0x0CB5, 0x0CB6, 0x0CB7,
+ /* U+21D0 */ 0x0CB8, 0x0CB9, 0x0CC0, 0x0CC1, 0x0CC2, 0x0CC3, 0x0CC4, 0x0CC5,
+ /* U+21D8 */ 0x0CC6, 0x0CC7, 0x0CC8, 0x0CC9, 0x0CD0, 0x0CD1, 0x0CD2, 0x0CD3,
+ /* U+21E0 */ 0x0CD4, 0x0CD5, 0x0CD6, 0x0CD7, 0x0CD8, 0x0CD9, 0x0CE0, 0x0CE1,
+ /* U+21E8 */ 0x0CE2, 0x0CE3, 0x0CE4, 0x0CE5, 0x0CE6, 0x0CE7, 0x0CE8, 0x0CE9,
+ /* U+21F0 */ 0x0CF0, 0x0CF1, 0x0CF2, 0x0CF3, 0x0CF4, 0x0CF5, 0x0CF6, 0x0CF7,
+ /* U+21F8 */ 0x0CF8, 0x0CF9, 0x0D00, 0x0D01, 0x0D02, 0x0D03, 0x0D04, 0x0D05,
+ /* U+2200 */ 0x0D06, 0x0D07, 0x0D08, 0x0D09, 0x0D10, 0x0D11, 0x0D12, 0x0D13,
+ /* U+2208 */ 0xA1CA, 0x0D14, 0x0D15, 0x0D16, 0x0D17, 0x0D18, 0x0D19, 0xA1C7,
+ /* U+2210 */ 0x0D20, 0xA1C6, 0x0D21, 0x0D22, 0x0D23, 0xA84D, 0x0D24, 0x0D25,
+ /* U+2218 */ 0x0D26, 0x0D27, 0xA1CC, 0x0D28, 0x0D29, 0xA1D8, 0xA1DE, 0xA84E,
+ /* U+2220 */ 0xA1CF, 0x0D30, 0x0D31, 0xA84F, 0x0D32, 0xA1CE, 0x0D33, 0xA1C4,
+ /* U+2228 */ 0xA1C5, 0xA1C9, 0xA1C8, 0xA1D2, 0x0D34, 0x0D35, 0xA1D3, 0x0D36,
+ /* U+2230 */ 0x0D37, 0x0D38, 0x0D39, 0x0D40, 0xA1E0, 0xA1DF, 0xA1C3, 0xA1CB,
+ /* U+2238 */ 0x0D41, 0x0D42, 0x0D43, 0x0D44, 0x0D45, 0xA1D7, 0x0D46, 0x0D47,
+ /* U+2240 */ 0x0D48, 0x0D49, 0x0D50, 0x0D51, 0x0D52, 0x0D53, 0x0D54, 0x0D55,
+ /* U+2248 */ 0xA1D6, 0x0D56, 0x0D57, 0x0D58, 0xA1D5, 0x0D59, 0x0D60, 0x0D61,
+ /* U+2250 */ 0x0D62, 0x0D63, 0xA850, 0x0D64, 0x0D65, 0x0D66, 0x0D67, 0x0D68,
+ /* U+2258 */ 0x0D69, 0x0D70, 0x0D71, 0x0D72, 0x0D73, 0x0D74, 0x0D75, 0x0D76,
+ /* U+2260 */ 0xA1D9, 0xA1D4, 0x0D77, 0x0D78, 0xA1DC, 0xA1DD, 0xA851, 0xA852,
+ /* U+2268 */ 0x0D79, 0x0D80, 0x0D81, 0x0D82, 0x0D83, 0x0D84, 0xA1DA, 0xA1DB,
+ /* U+2270 */ 0x0D85, 0x0D86, 0x0D87, 0x0D88, 0x0D89, 0x0D90, 0x0D91, 0x0D92,
+ /* U+2278 */ 0x0D93, 0x0D94, 0x0D95, 0x0D96, 0x0D97, 0x0D98, 0x0D99, 0x0DA0,
+ /* U+2280 */ 0x0DA1, 0x0DA2, 0x0DA3, 0x0DA4, 0x0DA5, 0x0DA6, 0x0DA7, 0x0DA8,
+ /* U+2288 */ 0x0DA9, 0x0DB0, 0x0DB1, 0x0DB2, 0x0DB3, 0x0DB4, 0x0DB5, 0x0DB6,
+ /* U+2290 */ 0x0DB7, 0x0DB8, 0x0DB9, 0x0DC0, 0x0DC1, 0xA892, 0x0DC2, 0x0DC3,
+ /* U+2298 */ 0x0DC4, 0xA1D1, 0x0DC5, 0x0DC6, 0x0DC7, 0x0DC8, 0x0DC9, 0x0DD0,
+ /* U+22A0 */ 0x0DD1, 0x0DD2, 0x0DD3, 0x0DD4, 0x0DD5, 0xA1CD, 0x0DD6, 0x0DD7,
+ /* U+22A8 */ 0x0DD8, 0x0DD9, 0x0DE0, 0x0DE1, 0x0DE2, 0x0DE3, 0x0DE4, 0x0DE5,
+ /* U+22B0 */ 0x0DE6, 0x0DE7, 0x0DE8, 0x0DE9, 0x0DF0, 0x0DF1, 0x0DF2, 0x0DF3,
+ /* U+22B8 */ 0x0DF4, 0x0DF5, 0x0DF6, 0x0DF7, 0x0DF8, 0x0DF9, 0x0E00, 0xA853,
+ /* U+22C0 */ 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, 0x0E08,
+ /* U+22C8 */ 0x0E09, 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16,
+ /* U+22D0 */ 0x0E17, 0x0E18, 0x0E19, 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24,
+ /* U+22D8 */ 0x0E25, 0x0E26, 0x0E27, 0x0E28, 0x0E29, 0x0E30, 0x0E31, 0x0E32,
+ /* U+22E0 */ 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, 0x0E38, 0x0E39, 0x0E40,
+ /* U+22E8 */ 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, 0x0E48,
+ /* U+22F0 */ 0x0E49, 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56,
+ /* U+22F8 */ 0x0E57, 0x0E58, 0x0E59, 0x0E60, 0x0E61, 0x0E62, 0x0E63, 0x0E64,
+ /* U+2300 */ 0x0E65, 0x0E66, 0x0E67, 0x0E68, 0x0E69, 0x0E70, 0x0E71, 0x0E72,
+ /* U+2308 */ 0x0E73, 0x0E74, 0x0E75, 0x0E76, 0x0E77, 0x0E78, 0x0E79, 0x0E80,
+ /* U+2310 */ 0x0E81, 0x0E82, 0xA1D0, 0x0E83, 0x0E84, 0x0E85, 0x0E86, 0x0E87,
+ /* U+2318 */ 0x0E88, 0x0E89, 0x0E90, 0x0E91, 0x0E92, 0x0E93, 0x0E94, 0x0E95,
+ /* U+2320 */ 0x0E96, 0x0E97, 0x0E98, 0x0E99, 0x0EA0, 0x0EA1, 0x0EA2, 0x0EA3,
+ /* U+2328 */ 0x0EA4, 0x0EA5, 0x0EA6, 0x0EA7, 0x0EA8, 0x0EA9, 0x0EB0, 0x0EB1,
+ /* U+2330 */ 0x0EB2, 0x0EB3, 0x0EB4, 0x0EB5, 0x0EB6, 0x0EB7, 0x0EB8, 0x0EB9,
+ /* U+2338 */ 0x0EC0, 0x0EC1, 0x0EC2, 0x0EC3, 0x0EC4, 0x0EC5, 0x0EC6, 0x0EC7,
+ /* U+2340 */ 0x0EC8, 0x0EC9, 0x0ED0, 0x0ED1, 0x0ED2, 0x0ED3, 0x0ED4, 0x0ED5,
+ /* U+2348 */ 0x0ED6, 0x0ED7, 0x0ED8, 0x0ED9, 0x0EE0, 0x0EE1, 0x0EE2, 0x0EE3,
+ /* U+2350 */ 0x0EE4, 0x0EE5, 0x0EE6, 0x0EE7, 0x0EE8, 0x0EE9, 0x0EF0, 0x0EF1,
+ /* U+2358 */ 0x0EF2, 0x0EF3, 0x0EF4, 0x0EF5, 0x0EF6, 0x0EF7, 0x0EF8, 0x0EF9,
+ /* U+2360 */ 0x0F00, 0x0F01, 0x0F02, 0x0F03, 0x0F04, 0x0F05, 0x0F06, 0x0F07,
+ /* U+2368 */ 0x0F08, 0x0F09, 0x0F10, 0x0F11, 0x0F12, 0x0F13, 0x0F14, 0x0F15,
+ /* U+2370 */ 0x0F16, 0x0F17, 0x0F18, 0x0F19, 0x0F20, 0x0F21, 0x0F22, 0x0F23,
+ /* U+2378 */ 0x0F24, 0x0F25, 0x0F26, 0x0F27, 0x0F28, 0x0F29, 0x0F30, 0x0F31,
+ /* U+2380 */ 0x0F32, 0x0F33, 0x0F34, 0x0F35, 0x0F36, 0x0F37, 0x0F38, 0x0F39,
+ /* U+2388 */ 0x0F40, 0x0F41, 0x0F42, 0x0F43, 0x0F44, 0x0F45, 0x0F46, 0x0F47,
+ /* U+2390 */ 0x0F48, 0x0F49, 0x0F50, 0x0F51, 0x0F52, 0x0F53, 0x0F54, 0x0F55,
+ /* U+2398 */ 0x0F56, 0x0F57, 0x0F58, 0x0F59, 0x0F60, 0x0F61, 0x0F62, 0x0F63,
+ /* U+23A0 */ 0x0F64, 0x0F65, 0x0F66, 0x0F67, 0x0F68, 0x0F69, 0x0F70, 0x0F71,
+ /* U+23A8 */ 0x0F72, 0x0F73, 0x0F74, 0x0F75, 0x0F76, 0x0F77, 0x0F78, 0x0F79,
+ /* U+23B0 */ 0x0F80, 0x0F81, 0x0F82, 0x0F83, 0x0F84, 0x0F85, 0x0F86, 0x0F87,
+ /* U+23B8 */ 0x0F88, 0x0F89, 0x0F90, 0x0F91, 0x0F92, 0x0F93, 0x0F94, 0x0F95,
+ /* U+23C0 */ 0x0F96, 0x0F97, 0x0F98, 0x0F99, 0x0FA0, 0x0FA1, 0x0FA2, 0x0FA3,
+ /* U+23C8 */ 0x0FA4, 0x0FA5, 0x0FA6, 0x0FA7, 0x0FA8, 0x0FA9, 0x0FB0, 0x0FB1,
+ /* U+23D0 */ 0x0FB2, 0x0FB3, 0x0FB4, 0x0FB5, 0x0FB6, 0x0FB7, 0x0FB8, 0x0FB9,
+ /* U+23D8 */ 0x0FC0, 0x0FC1, 0x0FC2, 0x0FC3, 0x0FC4, 0x0FC5, 0x0FC6, 0x0FC7,
+ /* U+23E0 */ 0x0FC8, 0x0FC9, 0x0FD0, 0x0FD1, 0x0FD2, 0x0FD3, 0x0FD4, 0x0FD5,
+ /* U+23E8 */ 0x0FD6, 0x0FD7, 0x0FD8, 0x0FD9, 0x1000, 0x1001, 0x1002, 0x1003,
+ /* U+23F0 */ 0x1004, 0x1005, 0x1006, 0x1007, 0x1008, 0x1009, 0x1010, 0x1011,
+ /* U+23F8 */ 0x1012, 0x1013, 0x1014, 0x1015, 0x1016, 0x1017, 0x1018, 0x1019,
+ /* U+2400 */ 0x1020, 0x1021, 0x1022, 0x1023, 0x1024, 0x1025, 0x1026, 0x1027,
+ /* U+2408 */ 0x1028, 0x1029, 0x1030, 0x1031, 0x1032, 0x1033, 0x1034, 0x1035,
+ /* U+2410 */ 0x1036, 0x1037, 0x1038, 0x1039, 0x1040, 0x1041, 0x1042, 0x1043,
+ /* U+2418 */ 0x1044, 0x1045, 0x1046, 0x1047, 0x1048, 0x1049, 0x1050, 0x1051,
+ /* U+2420 */ 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, 0x1058, 0x1059,
+ /* U+2428 */ 0x1060, 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067,
+ /* U+2430 */ 0x1068, 0x1069, 0x1070, 0x1071, 0x1072, 0x1073, 0x1074, 0x1075,
+ /* U+2438 */ 0x1076, 0x1077, 0x1078, 0x1079, 0x1080, 0x1081, 0x1082, 0x1083,
+ /* U+2440 */ 0x1084, 0x1085, 0x1086, 0x1087, 0x1088, 0x1089, 0x1090, 0x1091,
+ /* U+2448 */ 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097, 0x1098, 0x1099,
+ /* U+2450 */ 0x10A0, 0x10A1, 0x10A2, 0x10A3, 0x10A4, 0x10A5, 0x10A6, 0x10A7,
+ /* U+2458 */ 0x10A8, 0x10A9, 0x10B0, 0x10B1, 0x10B2, 0x10B3, 0x10B4, 0x10B5,
+ /* U+2460 */ 0xA2D9, 0xA2DA, 0xA2DB, 0xA2DC, 0xA2DD, 0xA2DE, 0xA2DF, 0xA2E0,
+ /* U+2468 */ 0xA2E1, 0xA2E2, 0x10B6, 0x10B7, 0x10B8, 0x10B9, 0x10C0, 0x10C1,
+ /* U+2470 */ 0x10C2, 0x10C3, 0x10C4, 0x10C5, 0xA2C5, 0xA2C6, 0xA2C7, 0xA2C8,
+ /* U+2478 */ 0xA2C9, 0xA2CA, 0xA2CB, 0xA2CC, 0xA2CD, 0xA2CE, 0xA2CF, 0xA2D0,
+ /* U+2480 */ 0xA2D1, 0xA2D2, 0xA2D3, 0xA2D4, 0xA2D5, 0xA2D6, 0xA2D7, 0xA2D8,
+ /* U+2488 */ 0xA2B1, 0xA2B2, 0xA2B3, 0xA2B4, 0xA2B5, 0xA2B6, 0xA2B7, 0xA2B8,
+ /* U+2490 */ 0xA2B9, 0xA2BA, 0xA2BB, 0xA2BC, 0xA2BD, 0xA2BE, 0xA2BF, 0xA2C0,
+ /* U+2498 */ 0xA2C1, 0xA2C2, 0xA2C3, 0xA2C4, 0x10C6, 0x10C7, 0x10C8, 0x10C9,
+ /* U+24A0 */ 0x10D0, 0x10D1, 0x10D2, 0x10D3, 0x10D4, 0x10D5, 0x10D6, 0x10D7,
+ /* U+24A8 */ 0x10D8, 0x10D9, 0x10E0, 0x10E1, 0x10E2, 0x10E3, 0x10E4, 0x10E5,
+ /* U+24B0 */ 0x10E6, 0x10E7, 0x10E8, 0x10E9, 0x10F0, 0x10F1, 0x10F2, 0x10F3,
+ /* U+24B8 */ 0x10F4, 0x10F5, 0x10F6, 0x10F7, 0x10F8, 0x10F9, 0x1100, 0x1101,
+ /* U+24C0 */ 0x1102, 0x1103, 0x1104, 0x1105, 0x1106, 0x1107, 0x1108, 0x1109,
+ /* U+24C8 */ 0x1110, 0x1111, 0x1112, 0x1113, 0x1114, 0x1115, 0x1116, 0x1117,
+ /* U+24D0 */ 0x1118, 0x1119, 0x1120, 0x1121, 0x1122, 0x1123, 0x1124, 0x1125,
+ /* U+24D8 */ 0x1126, 0x1127, 0x1128, 0x1129, 0x1130, 0x1131, 0x1132, 0x1133,
+ /* U+24E0 */ 0x1134, 0x1135, 0x1136, 0x1137, 0x1138, 0x1139, 0x1140, 0x1141,
+ /* U+24E8 */ 0x1142, 0x1143, 0x1144, 0x1145, 0x1146, 0x1147, 0x1148, 0x1149,
+ /* U+24F0 */ 0x1150, 0x1151, 0x1152, 0x1153, 0x1154, 0x1155, 0x1156, 0x1157,
+ /* U+24F8 */ 0x1158, 0x1159, 0x1160, 0x1161, 0x1162, 0x1163, 0x1164, 0x1165,
+ /* U+2500 */ 0xA9A4, 0xA9A5, 0xA9A6, 0xA9A7, 0xA9A8, 0xA9A9, 0xA9AA, 0xA9AB,
+ /* U+2508 */ 0xA9AC, 0xA9AD, 0xA9AE, 0xA9AF, 0xA9B0, 0xA9B1, 0xA9B2, 0xA9B3,
+ /* U+2510 */ 0xA9B4, 0xA9B5, 0xA9B6, 0xA9B7, 0xA9B8, 0xA9B9, 0xA9BA, 0xA9BB,
+ /* U+2518 */ 0xA9BC, 0xA9BD, 0xA9BE, 0xA9BF, 0xA9C0, 0xA9C1, 0xA9C2, 0xA9C3,
+ /* U+2520 */ 0xA9C4, 0xA9C5, 0xA9C6, 0xA9C7, 0xA9C8, 0xA9C9, 0xA9CA, 0xA9CB,
+ /* U+2528 */ 0xA9CC, 0xA9CD, 0xA9CE, 0xA9CF, 0xA9D0, 0xA9D1, 0xA9D2, 0xA9D3,
+ /* U+2530 */ 0xA9D4, 0xA9D5, 0xA9D6, 0xA9D7, 0xA9D8, 0xA9D9, 0xA9DA, 0xA9DB,
+ /* U+2538 */ 0xA9DC, 0xA9DD, 0xA9DE, 0xA9DF, 0xA9E0, 0xA9E1, 0xA9E2, 0xA9E3,
+ /* U+2540 */ 0xA9E4, 0xA9E5, 0xA9E6, 0xA9E7, 0xA9E8, 0xA9E9, 0xA9EA, 0xA9EB,
+ /* U+2548 */ 0xA9EC, 0xA9ED, 0xA9EE, 0xA9EF, 0x1166, 0x1167, 0x1168, 0x1169,
+ /* U+2550 */ 0xA854, 0xA855, 0xA856, 0xA857, 0xA858, 0xA859, 0xA85A, 0xA85B,
+ /* U+2558 */ 0xA85C, 0xA85D, 0xA85E, 0xA85F, 0xA860, 0xA861, 0xA862, 0xA863,
+ /* U+2560 */ 0xA864, 0xA865, 0xA866, 0xA867, 0xA868, 0xA869, 0xA86A, 0xA86B,
+ /* U+2568 */ 0xA86C, 0xA86D, 0xA86E, 0xA86F, 0xA870, 0xA871, 0xA872, 0xA873,
+ /* U+2570 */ 0xA874, 0xA875, 0xA876, 0xA877, 0x1170, 0x1171, 0x1172, 0x1173,
+ /* U+2578 */ 0x1174, 0x1175, 0x1176, 0x1177, 0x1178, 0x1179, 0x1180, 0x1181,
+ /* U+2580 */ 0x1182, 0xA878, 0xA879, 0xA87A, 0xA87B, 0xA87C, 0xA87D, 0xA87E,
+ /* U+2588 */ 0xA880, 0xA881, 0xA882, 0xA883, 0xA884, 0xA885, 0xA886, 0xA887,
+ /* U+2590 */ 0x1183, 0x1184, 0x1185, 0xA888, 0xA889, 0xA88A, 0x1186, 0x1187,
+ /* U+2598 */ 0x1188, 0x1189, 0x1190, 0x1191, 0x1192, 0x1193, 0x1194, 0x1195,
+ /* U+25A0 */ 0xA1F6, 0xA1F5, 0x1196, 0x1197, 0x1198, 0x1199, 0x11A0, 0x11A1,
+ /* U+25A8 */ 0x11A2, 0x11A3, 0x11A4, 0x11A5, 0x11A6, 0x11A7, 0x11A8, 0x11A9,
+ /* U+25B0 */ 0x11B0, 0x11B1, 0xA1F8, 0xA1F7, 0x11B2, 0x11B3, 0x11B4, 0x11B5,
+ /* U+25B8 */ 0x11B6, 0x11B7, 0x11B8, 0x11B9, 0xA88B, 0xA88C, 0x11C0, 0x11C1,
+ /* U+25C0 */ 0x11C2, 0x11C3, 0x11C4, 0x11C5, 0x11C6, 0x11C7, 0xA1F4, 0xA1F3,
+ /* U+25C8 */ 0x11C8, 0x11C9, 0x11D0, 0xA1F0, 0x11D1, 0x11D2, 0xA1F2, 0xA1F1,
+ /* U+25D0 */ 0x11D3, 0x11D4, 0x11D5, 0x11D6, 0x11D7, 0x11D8, 0x11D9, 0x11E0,
+ /* U+25D8 */ 0x11E1, 0x11E2, 0x11E3, 0x11E4, 0x11E5, 0x11E6, 0x11E7, 0x11E8,
+ /* U+25E0 */ 0x11E9, 0x11F0, 0xA88D, 0xA88E, 0xA88F, 0xA890, 0x11F1, 0x11F2,
+ /* U+25E8 */ 0x11F3, 0x11F4, 0x11F5, 0x11F6, 0x11F7, 0x11F8, 0x11F9, 0x1200,
+ /* U+25F0 */ 0x1201, 0x1202, 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1208,
+ /* U+25F8 */ 0x1209, 0x1210, 0x1211, 0x1212, 0x1213, 0x1214, 0x1215, 0x1216,
+ /* U+2600 */ 0x1217, 0x1218, 0x1219, 0x1220, 0x1221, 0xA1EF, 0xA1EE, 0x1222,
+ /* U+2608 */ 0x1223, 0xA891, 0x1224, 0x1225, 0x1226, 0x1227, 0x1228, 0x1229,
+ /* U+2610 */ 0x1230, 0x1231, 0x1232, 0x1233, 0x1234, 0x1235, 0x1236, 0x1237,
+ /* U+2618 */ 0x1238, 0x1239, 0x1240, 0x1241, 0x1242, 0x1243, 0x1244, 0x1245,
+ /* U+2620 */ 0x1246, 0x1247, 0x1248, 0x1249, 0x1250, 0x1251, 0x1252, 0x1253,
+ /* U+2628 */ 0x1254, 0x1255, 0x1256, 0x1257, 0x1258, 0x1259, 0x1260, 0x1261,
+ /* U+2630 */ 0x1262, 0x1263, 0x1264, 0x1265, 0x1266, 0x1267, 0x1268, 0x1269,
+ /* U+2638 */ 0x1270, 0x1271, 0x1272, 0x1273, 0x1274, 0x1275, 0x1276, 0x1277,
+ /* U+2640 */ 0xA1E2, 0x1278, 0xA1E1,
+ /* Contiguous area: U+2E81 .. U+361A */
+ /* U+2E81 */ 0xFE50, 0x1FC9, 0x1FD0, 0xFE54, 0x1FD1, 0x1FD2, 0x1FD3,
+ /* U+2E88 */ 0xFE57, 0x1FD4, 0x1FD5, 0xFE58, 0xFE5D, 0x1FD6, 0x1FD7, 0x1FD8,
+ /* U+2E90 */ 0x1FD9, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0xFE5E,
+ /* U+2E98 */ 0x2006, 0x2007, 0x2008, 0x2009, 0x2010, 0x2011, 0x2012, 0x2013,
+ /* U+2EA0 */ 0x2014, 0x2015, 0x2016, 0x2017, 0x2018, 0x2019, 0x2020, 0xFE6B,
+ /* U+2EA8 */ 0x2021, 0x2022, 0xFE6E, 0x2023, 0x2024, 0x2025, 0xFE71, 0x2026,
+ /* U+2EB0 */ 0x2027, 0x2028, 0x2029, 0xFE73, 0x2030, 0x2031, 0xFE74, 0xFE75,
+ /* U+2EB8 */ 0x2032, 0x2033, 0x2034, 0xFE79, 0x2035, 0x2036, 0x2037, 0x2038,
+ /* U+2EC0 */ 0x2039, 0x2040, 0x2041, 0x2042, 0x2043, 0x2044, 0x2045, 0x2046,
+ /* U+2EC8 */ 0x2047, 0x2048, 0xFE84, 0x2049, 0x2050, 0x2051, 0x2052, 0x2053,
+ /* U+2ED0 */ 0x2054, 0x2055, 0x2056, 0x2057, 0x2058, 0x2059, 0x2060, 0x2061,
+ /* U+2ED8 */ 0x2062, 0x2063, 0x2064, 0x2065, 0x2066, 0x2067, 0x2068, 0x2069,
+ /* U+2EE0 */ 0x2070, 0x2071, 0x2072, 0x2073, 0x2074, 0x2075, 0x2076, 0x2077,
+ /* U+2EE8 */ 0x2078, 0x2079, 0x2080, 0x2081, 0x2082, 0x2083, 0x2084, 0x2085,
+ /* U+2EF0 */ 0x2086, 0x2087, 0x2088, 0x2089, 0x2090, 0x2091, 0x2092, 0x2093,
+ /* U+2EF8 */ 0x2094, 0x2095, 0x2096, 0x2097, 0x2098, 0x2099, 0x20A0, 0x20A1,
+ /* U+2F00 */ 0x20A2, 0x20A3, 0x20A4, 0x20A5, 0x20A6, 0x20A7, 0x20A8, 0x20A9,
+ /* U+2F08 */ 0x20B0, 0x20B1, 0x20B2, 0x20B3, 0x20B4, 0x20B5, 0x20B6, 0x20B7,
+ /* U+2F10 */ 0x20B8, 0x20B9, 0x20C0, 0x20C1, 0x20C2, 0x20C3, 0x20C4, 0x20C5,
+ /* U+2F18 */ 0x20C6, 0x20C7, 0x20C8, 0x20C9, 0x20D0, 0x20D1, 0x20D2, 0x20D3,
+ /* U+2F20 */ 0x20D4, 0x20D5, 0x20D6, 0x20D7, 0x20D8, 0x20D9, 0x20E0, 0x20E1,
+ /* U+2F28 */ 0x20E2, 0x20E3, 0x20E4, 0x20E5, 0x20E6, 0x20E7, 0x20E8, 0x20E9,
+ /* U+2F30 */ 0x20F0, 0x20F1, 0x20F2, 0x20F3, 0x20F4, 0x20F5, 0x20F6, 0x20F7,
+ /* U+2F38 */ 0x20F8, 0x20F9, 0x2100, 0x2101, 0x2102, 0x2103, 0x2104, 0x2105,
+ /* U+2F40 */ 0x2106, 0x2107, 0x2108, 0x2109, 0x2110, 0x2111, 0x2112, 0x2113,
+ /* U+2F48 */ 0x2114, 0x2115, 0x2116, 0x2117, 0x2118, 0x2119, 0x2120, 0x2121,
+ /* U+2F50 */ 0x2122, 0x2123, 0x2124, 0x2125, 0x2126, 0x2127, 0x2128, 0x2129,
+ /* U+2F58 */ 0x2130, 0x2131, 0x2132, 0x2133, 0x2134, 0x2135, 0x2136, 0x2137,
+ /* U+2F60 */ 0x2138, 0x2139, 0x2140, 0x2141, 0x2142, 0x2143, 0x2144, 0x2145,
+ /* U+2F68 */ 0x2146, 0x2147, 0x2148, 0x2149, 0x2150, 0x2151, 0x2152, 0x2153,
+ /* U+2F70 */ 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x2160, 0x2161,
+ /* U+2F78 */ 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169,
+ /* U+2F80 */ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
+ /* U+2F88 */ 0x2178, 0x2179, 0x2180, 0x2181, 0x2182, 0x2183, 0x2184, 0x2185,
+ /* U+2F90 */ 0x2186, 0x2187, 0x2188, 0x2189, 0x2190, 0x2191, 0x2192, 0x2193,
+ /* U+2F98 */ 0x2194, 0x2195, 0x2196, 0x2197, 0x2198, 0x2199, 0x21A0, 0x21A1,
+ /* U+2FA0 */ 0x21A2, 0x21A3, 0x21A4, 0x21A5, 0x21A6, 0x21A7, 0x21A8, 0x21A9,
+ /* U+2FA8 */ 0x21B0, 0x21B1, 0x21B2, 0x21B3, 0x21B4, 0x21B5, 0x21B6, 0x21B7,
+ /* U+2FB0 */ 0x21B8, 0x21B9, 0x21C0, 0x21C1, 0x21C2, 0x21C3, 0x21C4, 0x21C5,
+ /* U+2FB8 */ 0x21C6, 0x21C7, 0x21C8, 0x21C9, 0x21D0, 0x21D1, 0x21D2, 0x21D3,
+ /* U+2FC0 */ 0x21D4, 0x21D5, 0x21D6, 0x21D7, 0x21D8, 0x21D9, 0x21E0, 0x21E1,
+ /* U+2FC8 */ 0x21E2, 0x21E3, 0x21E4, 0x21E5, 0x21E6, 0x21E7, 0x21E8, 0x21E9,
+ /* U+2FD0 */ 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4, 0x21F5, 0x21F6, 0x21F7,
+ /* U+2FD8 */ 0x21F8, 0x21F9, 0x2200, 0x2201, 0x2202, 0x2203, 0x2204, 0x2205,
+ /* U+2FE0 */ 0x2206, 0x2207, 0x2208, 0x2209, 0x2210, 0x2211, 0x2212, 0x2213,
+ /* U+2FE8 */ 0x2214, 0x2215, 0x2216, 0x2217, 0x2218, 0x2219, 0x2220, 0x2221,
+ /* U+2FF0 */ 0xA98A, 0xA98B, 0xA98C, 0xA98D, 0xA98E, 0xA98F, 0xA990, 0xA991,
+ /* U+2FF8 */ 0xA992, 0xA993, 0xA994, 0xA995, 0x2222, 0x2223, 0x2224, 0x2225,
+ /* U+3000 */ 0xA1A1, 0xA1A2, 0xA1A3, 0xA1A8, 0x2226, 0xA1A9, 0xA965, 0xA996,
+ /* U+3008 */ 0xA1B4, 0xA1B5, 0xA1B6, 0xA1B7, 0xA1B8, 0xA1B9, 0xA1BA, 0xA1BB,
+ /* U+3010 */ 0xA1BE, 0xA1BF, 0xA893, 0xA1FE, 0xA1B2, 0xA1B3, 0xA1BC, 0xA1BD,
+ /* U+3018 */ 0x2227, 0x2228, 0x2229, 0x2230, 0x2231, 0xA894, 0xA895, 0x2232,
+ /* U+3020 */ 0x2233, 0xA940, 0xA941, 0xA942, 0xA943, 0xA944, 0xA945, 0xA946,
+ /* U+3028 */ 0xA947, 0xA948, 0x2234, 0x2235, 0x2236, 0x2237, 0x2238, 0x2239,
+ /* U+3030 */ 0x2240, 0x2241, 0x2242, 0x2243, 0x2244, 0x2245, 0x2246, 0x2247,
+ /* U+3038 */ 0x2248, 0x2249, 0x2250, 0x2251, 0x2252, 0x2253, 0xA989, 0x2254,
+ /* U+3040 */ 0x2255, 0xA4A1, 0xA4A2, 0xA4A3, 0xA4A4, 0xA4A5, 0xA4A6, 0xA4A7,
+ /* U+3048 */ 0xA4A8, 0xA4A9, 0xA4AA, 0xA4AB, 0xA4AC, 0xA4AD, 0xA4AE, 0xA4AF,
+ /* U+3050 */ 0xA4B0, 0xA4B1, 0xA4B2, 0xA4B3, 0xA4B4, 0xA4B5, 0xA4B6, 0xA4B7,
+ /* U+3058 */ 0xA4B8, 0xA4B9, 0xA4BA, 0xA4BB, 0xA4BC, 0xA4BD, 0xA4BE, 0xA4BF,
+ /* U+3060 */ 0xA4C0, 0xA4C1, 0xA4C2, 0xA4C3, 0xA4C4, 0xA4C5, 0xA4C6, 0xA4C7,
+ /* U+3068 */ 0xA4C8, 0xA4C9, 0xA4CA, 0xA4CB, 0xA4CC, 0xA4CD, 0xA4CE, 0xA4CF,
+ /* U+3070 */ 0xA4D0, 0xA4D1, 0xA4D2, 0xA4D3, 0xA4D4, 0xA4D5, 0xA4D6, 0xA4D7,
+ /* U+3078 */ 0xA4D8, 0xA4D9, 0xA4DA, 0xA4DB, 0xA4DC, 0xA4DD, 0xA4DE, 0xA4DF,
+ /* U+3080 */ 0xA4E0, 0xA4E1, 0xA4E2, 0xA4E3, 0xA4E4, 0xA4E5, 0xA4E6, 0xA4E7,
+ /* U+3088 */ 0xA4E8, 0xA4E9, 0xA4EA, 0xA4EB, 0xA4EC, 0xA4ED, 0xA4EE, 0xA4EF,
+ /* U+3090 */ 0xA4F0, 0xA4F1, 0xA4F2, 0xA4F3, 0x2256, 0x2257, 0x2258, 0x2259,
+ /* U+3098 */ 0x2260, 0x2261, 0x2262, 0xA961, 0xA962, 0xA966, 0xA967, 0x2263,
+ /* U+30A0 */ 0x2264, 0xA5A1, 0xA5A2, 0xA5A3, 0xA5A4, 0xA5A5, 0xA5A6, 0xA5A7,
+ /* U+30A8 */ 0xA5A8, 0xA5A9, 0xA5AA, 0xA5AB, 0xA5AC, 0xA5AD, 0xA5AE, 0xA5AF,
+ /* U+30B0 */ 0xA5B0, 0xA5B1, 0xA5B2, 0xA5B3, 0xA5B4, 0xA5B5, 0xA5B6, 0xA5B7,
+ /* U+30B8 */ 0xA5B8, 0xA5B9, 0xA5BA, 0xA5BB, 0xA5BC, 0xA5BD, 0xA5BE, 0xA5BF,
+ /* U+30C0 */ 0xA5C0, 0xA5C1, 0xA5C2, 0xA5C3, 0xA5C4, 0xA5C5, 0xA5C6, 0xA5C7,
+ /* U+30C8 */ 0xA5C8, 0xA5C9, 0xA5CA, 0xA5CB, 0xA5CC, 0xA5CD, 0xA5CE, 0xA5CF,
+ /* U+30D0 */ 0xA5D0, 0xA5D1, 0xA5D2, 0xA5D3, 0xA5D4, 0xA5D5, 0xA5D6, 0xA5D7,
+ /* U+30D8 */ 0xA5D8, 0xA5D9, 0xA5DA, 0xA5DB, 0xA5DC, 0xA5DD, 0xA5DE, 0xA5DF,
+ /* U+30E0 */ 0xA5E0, 0xA5E1, 0xA5E2, 0xA5E3, 0xA5E4, 0xA5E5, 0xA5E6, 0xA5E7,
+ /* U+30E8 */ 0xA5E8, 0xA5E9, 0xA5EA, 0xA5EB, 0xA5EC, 0xA5ED, 0xA5EE, 0xA5EF,
+ /* U+30F0 */ 0xA5F0, 0xA5F1, 0xA5F2, 0xA5F3, 0xA5F4, 0xA5F5, 0xA5F6, 0x2265,
+ /* U+30F8 */ 0x2266, 0x2267, 0x2268, 0x2269, 0xA960, 0xA963, 0xA964, 0x2270,
+ /* U+3100 */ 0x2271, 0x2272, 0x2273, 0x2274, 0x2275, 0xA8C5, 0xA8C6, 0xA8C7,
+ /* U+3108 */ 0xA8C8, 0xA8C9, 0xA8CA, 0xA8CB, 0xA8CC, 0xA8CD, 0xA8CE, 0xA8CF,
+ /* U+3110 */ 0xA8D0, 0xA8D1, 0xA8D2, 0xA8D3, 0xA8D4, 0xA8D5, 0xA8D6, 0xA8D7,
+ /* U+3118 */ 0xA8D8, 0xA8D9, 0xA8DA, 0xA8DB, 0xA8DC, 0xA8DD, 0xA8DE, 0xA8DF,
+ /* U+3120 */ 0xA8E0, 0xA8E1, 0xA8E2, 0xA8E3, 0xA8E4, 0xA8E5, 0xA8E6, 0xA8E7,
+ /* U+3128 */ 0xA8E8, 0xA8E9, 0x2276, 0x2277, 0x2278, 0x2279, 0x2280, 0x2281,
+ /* U+3130 */ 0x2282, 0x2283, 0x2284, 0x2285, 0x2286, 0x2287, 0x2288, 0x2289,
+ /* U+3138 */ 0x2290, 0x2291, 0x2292, 0x2293, 0x2294, 0x2295, 0x2296, 0x2297,
+ /* U+3140 */ 0x2298, 0x2299, 0x22A0, 0x22A1, 0x22A2, 0x22A3, 0x22A4, 0x22A5,
+ /* U+3148 */ 0x22A6, 0x22A7, 0x22A8, 0x22A9, 0x22B0, 0x22B1, 0x22B2, 0x22B3,
+ /* U+3150 */ 0x22B4, 0x22B5, 0x22B6, 0x22B7, 0x22B8, 0x22B9, 0x22C0, 0x22C1,
+ /* U+3158 */ 0x22C2, 0x22C3, 0x22C4, 0x22C5, 0x22C6, 0x22C7, 0x22C8, 0x22C9,
+ /* U+3160 */ 0x22D0, 0x22D1, 0x22D2, 0x22D3, 0x22D4, 0x22D5, 0x22D6, 0x22D7,
+ /* U+3168 */ 0x22D8, 0x22D9, 0x22E0, 0x22E1, 0x22E2, 0x22E3, 0x22E4, 0x22E5,
+ /* U+3170 */ 0x22E6, 0x22E7, 0x22E8, 0x22E9, 0x22F0, 0x22F1, 0x22F2, 0x22F3,
+ /* U+3178 */ 0x22F4, 0x22F5, 0x22F6, 0x22F7, 0x22F8, 0x22F9, 0x2300, 0x2301,
+ /* U+3180 */ 0x2302, 0x2303, 0x2304, 0x2305, 0x2306, 0x2307, 0x2308, 0x2309,
+ /* U+3188 */ 0x2310, 0x2311, 0x2312, 0x2313, 0x2314, 0x2315, 0x2316, 0x2317,
+ /* U+3190 */ 0x2318, 0x2319, 0x2320, 0x2321, 0x2322, 0x2323, 0x2324, 0x2325,
+ /* U+3198 */ 0x2326, 0x2327, 0x2328, 0x2329, 0x2330, 0x2331, 0x2332, 0x2333,
+ /* U+31A0 */ 0x2334, 0x2335, 0x2336, 0x2337, 0x2338, 0x2339, 0x2340, 0x2341,
+ /* U+31A8 */ 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, 0x2348, 0x2349,
+ /* U+31B0 */ 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357,
+ /* U+31B8 */ 0x2358, 0x2359, 0x2360, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365,
+ /* U+31C0 */ 0x2366, 0x2367, 0x2368, 0x2369, 0x2370, 0x2371, 0x2372, 0x2373,
+ /* U+31C8 */ 0x2374, 0x2375, 0x2376, 0x2377, 0x2378, 0x2379, 0x2380, 0x2381,
+ /* U+31D0 */ 0x2382, 0x2383, 0x2384, 0x2385, 0x2386, 0x2387, 0x2388, 0x2389,
+ /* U+31D8 */ 0x2390, 0x2391, 0x2392, 0x2393, 0x2394, 0x2395, 0x2396, 0x2397,
+ /* U+31E0 */ 0x2398, 0x2399, 0x23A0, 0x23A1, 0x23A2, 0x23A3, 0x23A4, 0x23A5,
+ /* U+31E8 */ 0x23A6, 0x23A7, 0x23A8, 0x23A9, 0x23B0, 0x23B1, 0x23B2, 0x23B3,
+ /* U+31F0 */ 0x23B4, 0x23B5, 0x23B6, 0x23B7, 0x23B8, 0x23B9, 0x23C0, 0x23C1,
+ /* U+31F8 */ 0x23C2, 0x23C3, 0x23C4, 0x23C5, 0x23C6, 0x23C7, 0x23C8, 0x23C9,
+ /* U+3200 */ 0x23D0, 0x23D1, 0x23D2, 0x23D3, 0x23D4, 0x23D5, 0x23D6, 0x23D7,
+ /* U+3208 */ 0x23D8, 0x23D9, 0x23E0, 0x23E1, 0x23E2, 0x23E3, 0x23E4, 0x23E5,
+ /* U+3210 */ 0x23E6, 0x23E7, 0x23E8, 0x23E9, 0x23F0, 0x23F1, 0x23F2, 0x23F3,
+ /* U+3218 */ 0x23F4, 0x23F5, 0x23F6, 0x23F7, 0x23F8, 0x23F9, 0x2400, 0x2401,
+ /* U+3220 */ 0xA2E5, 0xA2E6, 0xA2E7, 0xA2E8, 0xA2E9, 0xA2EA, 0xA2EB, 0xA2EC,
+ /* U+3228 */ 0xA2ED, 0xA2EE, 0x2402, 0x2403, 0x2404, 0x2405, 0x2406, 0x2407,
+ /* U+3230 */ 0x2408, 0xA95A, 0x2409, 0x2410, 0x2411, 0x2412, 0x2413, 0x2414,
+ /* U+3238 */ 0x2415, 0x2416, 0x2417, 0x2418, 0x2419, 0x2420, 0x2421, 0x2422,
+ /* U+3240 */ 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429, 0x2430,
+ /* U+3248 */ 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438,
+ /* U+3250 */ 0x2439, 0x2440, 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446,
+ /* U+3258 */ 0x2447, 0x2448, 0x2449, 0x2450, 0x2451, 0x2452, 0x2453, 0x2454,
+ /* U+3260 */ 0x2455, 0x2456, 0x2457, 0x2458, 0x2459, 0x2460, 0x2461, 0x2462,
+ /* U+3268 */ 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x2470,
+ /* U+3270 */ 0x2471, 0x2472, 0x2473, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478,
+ /* U+3278 */ 0x2479, 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486,
+ /* U+3280 */ 0x2487, 0x2488, 0x2489, 0x2490, 0x2491, 0x2492, 0x2493, 0x2494,
+ /* U+3288 */ 0x2495, 0x2496, 0x2497, 0x2498, 0x2499, 0x24A0, 0x24A1, 0x24A2,
+ /* U+3290 */ 0x24A3, 0x24A4, 0x24A5, 0x24A6, 0x24A7, 0x24A8, 0x24A9, 0x24B0,
+ /* U+3298 */ 0x24B1, 0x24B2, 0x24B3, 0x24B4, 0x24B5, 0x24B6, 0x24B7, 0x24B8,
+ /* U+32A0 */ 0x24B9, 0x24C0, 0x24C1, 0xA949, 0x24C2, 0x24C3, 0x24C4, 0x24C5,
+ /* U+32A8 */ 0x24C6, 0x24C7, 0x24C8, 0x24C9, 0x24D0, 0x24D1, 0x24D2, 0x24D3,
+ /* U+32B0 */ 0x24D4, 0x24D5, 0x24D6, 0x24D7, 0x24D8, 0x24D9, 0x24E0, 0x24E1,
+ /* U+32B8 */ 0x24E2, 0x24E3, 0x24E4, 0x24E5, 0x24E6, 0x24E7, 0x24E8, 0x24E9,
+ /* U+32C0 */ 0x24F0, 0x24F1, 0x24F2, 0x24F3, 0x24F4, 0x24F5, 0x24F6, 0x24F7,
+ /* U+32C8 */ 0x24F8, 0x24F9, 0x2500, 0x2501, 0x2502, 0x2503, 0x2504, 0x2505,
+ /* U+32D0 */ 0x2506, 0x2507, 0x2508, 0x2509, 0x2510, 0x2511, 0x2512, 0x2513,
+ /* U+32D8 */ 0x2514, 0x2515, 0x2516, 0x2517, 0x2518, 0x2519, 0x2520, 0x2521,
+ /* U+32E0 */ 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529,
+ /* U+32E8 */ 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537,
+ /* U+32F0 */ 0x2538, 0x2539, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545,
+ /* U+32F8 */ 0x2546, 0x2547, 0x2548, 0x2549, 0x2550, 0x2551, 0x2552, 0x2553,
+ /* U+3300 */ 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x2560, 0x2561,
+ /* U+3308 */ 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569,
+ /* U+3310 */ 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, 0x2577,
+ /* U+3318 */ 0x2578, 0x2579, 0x2580, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585,
+ /* U+3320 */ 0x2586, 0x2587, 0x2588, 0x2589, 0x2590, 0x2591, 0x2592, 0x2593,
+ /* U+3328 */ 0x2594, 0x2595, 0x2596, 0x2597, 0x2598, 0x2599, 0x25A0, 0x25A1,
+ /* U+3330 */ 0x25A2, 0x25A3, 0x25A4, 0x25A5, 0x25A6, 0x25A7, 0x25A8, 0x25A9,
+ /* U+3338 */ 0x25B0, 0x25B1, 0x25B2, 0x25B3, 0x25B4, 0x25B5, 0x25B6, 0x25B7,
+ /* U+3340 */ 0x25B8, 0x25B9, 0x25C0, 0x25C1, 0x25C2, 0x25C3, 0x25C4, 0x25C5,
+ /* U+3348 */ 0x25C6, 0x25C7, 0x25C8, 0x25C9, 0x25D0, 0x25D1, 0x25D2, 0x25D3,
+ /* U+3350 */ 0x25D4, 0x25D5, 0x25D6, 0x25D7, 0x25D8, 0x25D9, 0x25E0, 0x25E1,
+ /* U+3358 */ 0x25E2, 0x25E3, 0x25E4, 0x25E5, 0x25E6, 0x25E7, 0x25E8, 0x25E9,
+ /* U+3360 */ 0x25F0, 0x25F1, 0x25F2, 0x25F3, 0x25F4, 0x25F5, 0x25F6, 0x25F7,
+ /* U+3368 */ 0x25F8, 0x25F9, 0x2600, 0x2601, 0x2602, 0x2603, 0x2604, 0x2605,
+ /* U+3370 */ 0x2606, 0x2607, 0x2608, 0x2609, 0x2610, 0x2611, 0x2612, 0x2613,
+ /* U+3378 */ 0x2614, 0x2615, 0x2616, 0x2617, 0x2618, 0x2619, 0x2620, 0x2621,
+ /* U+3380 */ 0x2622, 0x2623, 0x2624, 0x2625, 0x2626, 0x2627, 0x2628, 0x2629,
+ /* U+3388 */ 0x2630, 0x2631, 0x2632, 0x2633, 0x2634, 0x2635, 0xA94A, 0xA94B,
+ /* U+3390 */ 0x2636, 0x2637, 0x2638, 0x2639, 0x2640, 0x2641, 0x2642, 0x2643,
+ /* U+3398 */ 0x2644, 0x2645, 0x2646, 0x2647, 0xA94C, 0xA94D, 0xA94E, 0x2648,
+ /* U+33A0 */ 0x2649, 0xA94F, 0x2650, 0x2651, 0x2652, 0x2653, 0x2654, 0x2655,
+ /* U+33A8 */ 0x2656, 0x2657, 0x2658, 0x2659, 0x2660, 0x2661, 0x2662, 0x2663,
+ /* U+33B0 */ 0x2664, 0x2665, 0x2666, 0x2667, 0x2668, 0x2669, 0x2670, 0x2671,
+ /* U+33B8 */ 0x2672, 0x2673, 0x2674, 0x2675, 0x2676, 0x2677, 0x2678, 0x2679,
+ /* U+33C0 */ 0x2680, 0x2681, 0x2682, 0x2683, 0xA950, 0x2684, 0x2685, 0x2686,
+ /* U+33C8 */ 0x2687, 0x2688, 0x2689, 0x2690, 0x2691, 0x2692, 0xA951, 0x2693,
+ /* U+33D0 */ 0x2694, 0xA952, 0xA953, 0x2695, 0x2696, 0xA954, 0x2697, 0x2698,
+ /* U+33D8 */ 0x2699, 0x26A0, 0x26A1, 0x26A2, 0x26A3, 0x26A4, 0x26A5, 0x26A6,
+ /* U+33E0 */ 0x26A7, 0x26A8, 0x26A9, 0x26B0, 0x26B1, 0x26B2, 0x26B3, 0x26B4,
+ /* U+33E8 */ 0x26B5, 0x26B6, 0x26B7, 0x26B8, 0x26B9, 0x26C0, 0x26C1, 0x26C2,
+ /* U+33F0 */ 0x26C3, 0x26C4, 0x26C5, 0x26C6, 0x26C7, 0x26C8, 0x26C9, 0x26D0,
+ /* U+33F8 */ 0x26D1, 0x26D2, 0x26D3, 0x26D4, 0x26D5, 0x26D6, 0x26D7, 0x26D8,
+ /* U+3400 */ 0x26D9, 0x26E0, 0x26E1, 0x26E2, 0x26E3, 0x26E4, 0x26E5, 0x26E6,
+ /* U+3408 */ 0x26E7, 0x26E8, 0x26E9, 0x26F0, 0x26F1, 0x26F2, 0x26F3, 0x26F4,
+ /* U+3410 */ 0x26F5, 0x26F6, 0x26F7, 0x26F8, 0x26F9, 0x2700, 0x2701, 0x2702,
+ /* U+3418 */ 0x2703, 0x2704, 0x2705, 0x2706, 0x2707, 0x2708, 0x2709, 0x2710,
+ /* U+3420 */ 0x2711, 0x2712, 0x2713, 0x2714, 0x2715, 0x2716, 0x2717, 0x2718,
+ /* U+3428 */ 0x2719, 0x2720, 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726,
+ /* U+3430 */ 0x2727, 0x2728, 0x2729, 0x2730, 0x2731, 0x2732, 0x2733, 0x2734,
+ /* U+3438 */ 0x2735, 0x2736, 0x2737, 0x2738, 0x2739, 0x2740, 0x2741, 0x2742,
+ /* U+3440 */ 0x2743, 0x2744, 0x2745, 0x2746, 0x2747, 0x2748, 0x2749, 0xFE56,
+ /* U+3448 */ 0x2750, 0x2751, 0x2752, 0x2753, 0x2754, 0x2755, 0x2756, 0x2757,
+ /* U+3450 */ 0x2758, 0x2759, 0x2760, 0x2761, 0x2762, 0x2763, 0x2764, 0x2765,
+ /* U+3458 */ 0x2766, 0x2767, 0x2768, 0x2769, 0x2770, 0x2771, 0x2772, 0x2773,
+ /* U+3460 */ 0x2774, 0x2775, 0x2776, 0x2777, 0x2778, 0x2779, 0x2780, 0x2781,
+ /* U+3468 */ 0x2782, 0x2783, 0x2784, 0x2785, 0x2786, 0x2787, 0x2788, 0x2789,
+ /* U+3470 */ 0x2790, 0x2791, 0x2792, 0xFE55, 0x2793, 0x2794, 0x2795, 0x2796,
+ /* U+3478 */ 0x2797, 0x2798, 0x2799, 0x27A0, 0x27A1, 0x27A2, 0x27A3, 0x27A4,
+ /* U+3480 */ 0x27A5, 0x27A6, 0x27A7, 0x27A8, 0x27A9, 0x27B0, 0x27B1, 0x27B2,
+ /* U+3488 */ 0x27B3, 0x27B4, 0x27B5, 0x27B6, 0x27B7, 0x27B8, 0x27B9, 0x27C0,
+ /* U+3490 */ 0x27C1, 0x27C2, 0x27C3, 0x27C4, 0x27C5, 0x27C6, 0x27C7, 0x27C8,
+ /* U+3498 */ 0x27C9, 0x27D0, 0x27D1, 0x27D2, 0x27D3, 0x27D4, 0x27D5, 0x27D6,
+ /* U+34A0 */ 0x27D7, 0x27D8, 0x27D9, 0x3000, 0x3001, 0x3002, 0x3003, 0x3004,
+ /* U+34A8 */ 0x3005, 0x3006, 0x3007, 0x3008, 0x3009, 0x3010, 0x3011, 0x3012,
+ /* U+34B0 */ 0x3013, 0x3014, 0x3015, 0x3016, 0x3017, 0x3018, 0x3019, 0x3020,
+ /* U+34B8 */ 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, 0x3028,
+ /* U+34C0 */ 0x3029, 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036,
+ /* U+34C8 */ 0x3037, 0x3038, 0x3039, 0x3040, 0x3041, 0x3042, 0x3043, 0x3044,
+ /* U+34D0 */ 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, 0x3050, 0x3051, 0x3052,
+ /* U+34D8 */ 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, 0x3059, 0x3060,
+ /* U+34E0 */ 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068,
+ /* U+34E8 */ 0x3069, 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076,
+ /* U+34F0 */ 0x3077, 0x3078, 0x3079, 0x3080, 0x3081, 0x3082, 0x3083, 0x3084,
+ /* U+34F8 */ 0x3085, 0x3086, 0x3087, 0x3088, 0x3089, 0x3090, 0x3091, 0x3092,
+ /* U+3500 */ 0x3093, 0x3094, 0x3095, 0x3096, 0x3097, 0x3098, 0x3099, 0x30A0,
+ /* U+3508 */ 0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8,
+ /* U+3510 */ 0x30A9, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6,
+ /* U+3518 */ 0x30B7, 0x30B8, 0x30B9, 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4,
+ /* U+3520 */ 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30D0, 0x30D1, 0x30D2,
+ /* U+3528 */ 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, 0x30D9, 0x30E0,
+ /* U+3530 */ 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8,
+ /* U+3538 */ 0x30E9, 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6,
+ /* U+3540 */ 0x30F7, 0x30F8, 0x30F9, 0x3100, 0x3101, 0x3102, 0x3103, 0x3104,
+ /* U+3548 */ 0x3105, 0x3106, 0x3107, 0x3108, 0x3109, 0x3110, 0x3111, 0x3112,
+ /* U+3550 */ 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118, 0x3119, 0x3120,
+ /* U+3558 */ 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128,
+ /* U+3560 */ 0x3129, 0x3130, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136,
+ /* U+3568 */ 0x3137, 0x3138, 0x3139, 0x3140, 0x3141, 0x3142, 0x3143, 0x3144,
+ /* U+3570 */ 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, 0x3150, 0x3151, 0x3152,
+ /* U+3578 */ 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, 0x3160,
+ /* U+3580 */ 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, 0x3166, 0x3167, 0x3168,
+ /* U+3588 */ 0x3169, 0x3170, 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, 0x3176,
+ /* U+3590 */ 0x3177, 0x3178, 0x3179, 0x3180, 0x3181, 0x3182, 0x3183, 0x3184,
+ /* U+3598 */ 0x3185, 0x3186, 0x3187, 0x3188, 0x3189, 0x3190, 0xFE5A, 0x3191,
+ /* U+35A0 */ 0x3192, 0x3193, 0x3194, 0x3195, 0x3196, 0x3197, 0x3198, 0x3199,
+ /* U+35A8 */ 0x31A0, 0x31A1, 0x31A2, 0x31A3, 0x31A4, 0x31A5, 0x31A6, 0x31A7,
+ /* U+35B0 */ 0x31A8, 0x31A9, 0x31B0, 0x31B1, 0x31B2, 0x31B3, 0x31B4, 0x31B5,
+ /* U+35B8 */ 0x31B6, 0x31B7, 0x31B8, 0x31B9, 0x31C0, 0x31C1, 0x31C2, 0x31C3,
+ /* U+35C0 */ 0x31C4, 0x31C5, 0x31C6, 0x31C7, 0x31C8, 0x31C9, 0x31D0, 0x31D1,
+ /* U+35C8 */ 0x31D2, 0x31D3, 0x31D4, 0x31D5, 0x31D6, 0x31D7, 0x31D8, 0x31D9,
+ /* U+35D0 */ 0x31E0, 0x31E1, 0x31E2, 0x31E3, 0x31E4, 0x31E5, 0x31E6, 0x31E7,
+ /* U+35D8 */ 0x31E8, 0x31E9, 0x31F0, 0x31F1, 0x31F2, 0x31F3, 0x31F4, 0x31F5,
+ /* U+35E0 */ 0x31F6, 0x31F7, 0x31F8, 0x31F9, 0x3200, 0x3201, 0x3202, 0x3203,
+ /* U+35E8 */ 0x3204, 0x3205, 0x3206, 0x3207, 0x3208, 0x3209, 0x3210, 0x3211,
+ /* U+35F0 */ 0x3212, 0x3213, 0x3214, 0x3215, 0x3216, 0x3217, 0x3218, 0x3219,
+ /* U+35F8 */ 0x3220, 0x3221, 0x3222, 0x3223, 0x3224, 0x3225, 0x3226, 0x3227,
+ /* U+3600 */ 0x3228, 0x3229, 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235,
+ /* U+3608 */ 0x3236, 0x3237, 0x3238, 0x3239, 0x3240, 0x3241, 0xFE5C, 0x3242,
+ /* U+3610 */ 0x3243, 0x3244, 0x3245, 0x3246, 0x3247, 0x3248, 0x3249, 0x3250,
+ /* U+3618 */ 0x3251, 0x3252, 0xFE5B,
+ /* Contiguous area: U+3918 .. U+3CE0 */
+ /* U+3918 */ 0xFE60, 0x3718, 0x3719, 0x3720, 0x3721, 0x3722, 0x3723, 0x3724,
+ /* U+3920 */ 0x3725, 0x3726, 0x3727, 0x3728, 0x3729, 0x3730, 0x3731, 0x3732,
+ /* U+3928 */ 0x3733, 0x3734, 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, 0x3740,
+ /* U+3930 */ 0x3741, 0x3742, 0x3743, 0x3744, 0x3745, 0x3746, 0x3747, 0x3748,
+ /* U+3938 */ 0x3749, 0x3750, 0x3751, 0x3752, 0x3753, 0x3754, 0x3755, 0x3756,
+ /* U+3940 */ 0x3757, 0x3758, 0x3759, 0x3760, 0x3761, 0x3762, 0x3763, 0x3764,
+ /* U+3948 */ 0x3765, 0x3766, 0x3767, 0x3768, 0x3769, 0x3770, 0x3771, 0x3772,
+ /* U+3950 */ 0x3773, 0x3774, 0x3775, 0x3776, 0x3777, 0x3778, 0x3779, 0x3780,
+ /* U+3958 */ 0x3781, 0x3782, 0x3783, 0x3784, 0x3785, 0x3786, 0x3787, 0x3788,
+ /* U+3960 */ 0x3789, 0x3790, 0x3791, 0x3792, 0x3793, 0x3794, 0x3795, 0x3796,
+ /* U+3968 */ 0x3797, 0x3798, 0x3799, 0x37A0, 0x37A1, 0x37A2, 0xFE5F, 0x37A3,
+ /* U+3970 */ 0x37A4, 0x37A5, 0x37A6, 0x37A7, 0x37A8, 0x37A9, 0x37B0, 0x37B1,
+ /* U+3978 */ 0x37B2, 0x37B3, 0x37B4, 0x37B5, 0x37B6, 0x37B7, 0x37B8, 0x37B9,
+ /* U+3980 */ 0x37C0, 0x37C1, 0x37C2, 0x37C3, 0x37C4, 0x37C5, 0x37C6, 0x37C7,
+ /* U+3988 */ 0x37C8, 0x37C9, 0x37D0, 0x37D1, 0x37D2, 0x37D3, 0x37D4, 0x37D5,
+ /* U+3990 */ 0x37D6, 0x37D7, 0x37D8, 0x37D9, 0x3800, 0x3801, 0x3802, 0x3803,
+ /* U+3998 */ 0x3804, 0x3805, 0x3806, 0x3807, 0x3808, 0x3809, 0x3810, 0x3811,
+ /* U+39A0 */ 0x3812, 0x3813, 0x3814, 0x3815, 0x3816, 0x3817, 0x3818, 0x3819,
+ /* U+39A8 */ 0x3820, 0x3821, 0x3822, 0x3823, 0x3824, 0x3825, 0x3826, 0x3827,
+ /* U+39B0 */ 0x3828, 0x3829, 0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835,
+ /* U+39B8 */ 0x3836, 0x3837, 0x3838, 0x3839, 0x3840, 0x3841, 0x3842, 0x3843,
+ /* U+39C0 */ 0x3844, 0x3845, 0x3846, 0x3847, 0x3848, 0x3849, 0x3850, 0x3851,
+ /* U+39C8 */ 0x3852, 0x3853, 0x3854, 0x3855, 0x3856, 0x3857, 0x3858, 0xFE62,
+ /* U+39D0 */ 0xFE65, 0x3859, 0x3860, 0x3861, 0x3862, 0x3863, 0x3864, 0x3865,
+ /* U+39D8 */ 0x3866, 0x3867, 0x3868, 0x3869, 0x3870, 0x3871, 0x3872, 0xFE63,
+ /* U+39E0 */ 0x3873, 0x3874, 0x3875, 0x3876, 0x3877, 0x3878, 0x3879, 0x3880,
+ /* U+39E8 */ 0x3881, 0x3882, 0x3883, 0x3884, 0x3885, 0x3886, 0x3887, 0x3888,
+ /* U+39F0 */ 0x3889, 0x3890, 0x3891, 0x3892, 0x3893, 0x3894, 0x3895, 0x3896,
+ /* U+39F8 */ 0x3897, 0x3898, 0x3899, 0x38A0, 0x38A1, 0x38A2, 0x38A3, 0x38A4,
+ /* U+3A00 */ 0x38A5, 0x38A6, 0x38A7, 0x38A8, 0x38A9, 0x38B0, 0x38B1, 0x38B2,
+ /* U+3A08 */ 0x38B3, 0x38B4, 0x38B5, 0x38B6, 0x38B7, 0x38B8, 0x38B9, 0x38C0,
+ /* U+3A10 */ 0x38C1, 0x38C2, 0x38C3, 0x38C4, 0x38C5, 0x38C6, 0x38C7, 0x38C8,
+ /* U+3A18 */ 0x38C9, 0x38D0, 0x38D1, 0x38D2, 0x38D3, 0x38D4, 0x38D5, 0x38D6,
+ /* U+3A20 */ 0x38D7, 0x38D8, 0x38D9, 0x38E0, 0x38E1, 0x38E2, 0x38E3, 0x38E4,
+ /* U+3A28 */ 0x38E5, 0x38E6, 0x38E7, 0x38E8, 0x38E9, 0x38F0, 0x38F1, 0x38F2,
+ /* U+3A30 */ 0x38F3, 0x38F4, 0x38F5, 0x38F6, 0x38F7, 0x38F8, 0x38F9, 0x3900,
+ /* U+3A38 */ 0x3901, 0x3902, 0x3903, 0x3904, 0x3905, 0x3906, 0x3907, 0x3908,
+ /* U+3A40 */ 0x3909, 0x3910, 0x3911, 0x3912, 0x3913, 0x3914, 0x3915, 0x3916,
+ /* U+3A48 */ 0x3917, 0x3918, 0x3919, 0x3920, 0x3921, 0x3922, 0x3923, 0x3924,
+ /* U+3A50 */ 0x3925, 0x3926, 0x3927, 0x3928, 0x3929, 0x3930, 0x3931, 0x3932,
+ /* U+3A58 */ 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, 0x3939, 0x3940,
+ /* U+3A60 */ 0x3941, 0x3942, 0x3943, 0x3944, 0x3945, 0x3946, 0x3947, 0x3948,
+ /* U+3A68 */ 0x3949, 0x3950, 0x3951, 0x3952, 0x3953, 0x3954, 0x3955, 0x3956,
+ /* U+3A70 */ 0x3957, 0x3958, 0x3959, 0xFE64, 0x3960, 0x3961, 0x3962, 0x3963,
+ /* U+3A78 */ 0x3964, 0x3965, 0x3966, 0x3967, 0x3968, 0x3969, 0x3970, 0x3971,
+ /* U+3A80 */ 0x3972, 0x3973, 0x3974, 0x3975, 0x3976, 0x3977, 0x3978, 0x3979,
+ /* U+3A88 */ 0x3980, 0x3981, 0x3982, 0x3983, 0x3984, 0x3985, 0x3986, 0x3987,
+ /* U+3A90 */ 0x3988, 0x3989, 0x3990, 0x3991, 0x3992, 0x3993, 0x3994, 0x3995,
+ /* U+3A98 */ 0x3996, 0x3997, 0x3998, 0x3999, 0x39A0, 0x39A1, 0x39A2, 0x39A3,
+ /* U+3AA0 */ 0x39A4, 0x39A5, 0x39A6, 0x39A7, 0x39A8, 0x39A9, 0x39B0, 0x39B1,
+ /* U+3AA8 */ 0x39B2, 0x39B3, 0x39B4, 0x39B5, 0x39B6, 0x39B7, 0x39B8, 0x39B9,
+ /* U+3AB0 */ 0x39C0, 0x39C1, 0x39C2, 0x39C3, 0x39C4, 0x39C5, 0x39C6, 0x39C7,
+ /* U+3AB8 */ 0x39C8, 0x39C9, 0x39D0, 0x39D1, 0x39D2, 0x39D3, 0x39D4, 0x39D5,
+ /* U+3AC0 */ 0x39D6, 0x39D7, 0x39D8, 0x39D9, 0x39E0, 0x39E1, 0x39E2, 0x39E3,
+ /* U+3AC8 */ 0x39E4, 0x39E5, 0x39E6, 0x39E7, 0x39E8, 0x39E9, 0x39F0, 0x39F1,
+ /* U+3AD0 */ 0x39F2, 0x39F3, 0x39F4, 0x39F5, 0x39F6, 0x39F7, 0x39F8, 0x39F9,
+ /* U+3AD8 */ 0x3A00, 0x3A01, 0x3A02, 0x3A03, 0x3A04, 0x3A05, 0x3A06, 0x3A07,
+ /* U+3AE0 */ 0x3A08, 0x3A09, 0x3A10, 0x3A11, 0x3A12, 0x3A13, 0x3A14, 0x3A15,
+ /* U+3AE8 */ 0x3A16, 0x3A17, 0x3A18, 0x3A19, 0x3A20, 0x3A21, 0x3A22, 0x3A23,
+ /* U+3AF0 */ 0x3A24, 0x3A25, 0x3A26, 0x3A27, 0x3A28, 0x3A29, 0x3A30, 0x3A31,
+ /* U+3AF8 */ 0x3A32, 0x3A33, 0x3A34, 0x3A35, 0x3A36, 0x3A37, 0x3A38, 0x3A39,
+ /* U+3B00 */ 0x3A40, 0x3A41, 0x3A42, 0x3A43, 0x3A44, 0x3A45, 0x3A46, 0x3A47,
+ /* U+3B08 */ 0x3A48, 0x3A49, 0x3A50, 0x3A51, 0x3A52, 0x3A53, 0x3A54, 0x3A55,
+ /* U+3B10 */ 0x3A56, 0x3A57, 0x3A58, 0x3A59, 0x3A60, 0x3A61, 0x3A62, 0x3A63,
+ /* U+3B18 */ 0x3A64, 0x3A65, 0x3A66, 0x3A67, 0x3A68, 0x3A69, 0x3A70, 0x3A71,
+ /* U+3B20 */ 0x3A72, 0x3A73, 0x3A74, 0x3A75, 0x3A76, 0x3A77, 0x3A78, 0x3A79,
+ /* U+3B28 */ 0x3A80, 0x3A81, 0x3A82, 0x3A83, 0x3A84, 0x3A85, 0x3A86, 0x3A87,
+ /* U+3B30 */ 0x3A88, 0x3A89, 0x3A90, 0x3A91, 0x3A92, 0x3A93, 0x3A94, 0x3A95,
+ /* U+3B38 */ 0x3A96, 0x3A97, 0x3A98, 0x3A99, 0x3AA0, 0x3AA1, 0x3AA2, 0x3AA3,
+ /* U+3B40 */ 0x3AA4, 0x3AA5, 0x3AA6, 0x3AA7, 0x3AA8, 0x3AA9, 0x3AB0, 0x3AB1,
+ /* U+3B48 */ 0x3AB2, 0x3AB3, 0x3AB4, 0x3AB5, 0x3AB6, 0x3AB7, 0xFE68, 0x3AB8,
+ /* U+3B50 */ 0x3AB9, 0x3AC0, 0x3AC1, 0x3AC2, 0x3AC3, 0x3AC4, 0x3AC5, 0x3AC6,
+ /* U+3B58 */ 0x3AC7, 0x3AC8, 0x3AC9, 0x3AD0, 0x3AD1, 0x3AD2, 0x3AD3, 0x3AD4,
+ /* U+3B60 */ 0x3AD5, 0x3AD6, 0x3AD7, 0x3AD8, 0x3AD9, 0x3AE0, 0x3AE1, 0x3AE2,
+ /* U+3B68 */ 0x3AE3, 0x3AE4, 0x3AE5, 0x3AE6, 0x3AE7, 0x3AE8, 0x3AE9, 0x3AF0,
+ /* U+3B70 */ 0x3AF1, 0x3AF2, 0x3AF3, 0x3AF4, 0x3AF5, 0x3AF6, 0x3AF7, 0x3AF8,
+ /* U+3B78 */ 0x3AF9, 0x3B00, 0x3B01, 0x3B02, 0x3B03, 0x3B04, 0x3B05, 0x3B06,
+ /* U+3B80 */ 0x3B07, 0x3B08, 0x3B09, 0x3B10, 0x3B11, 0x3B12, 0x3B13, 0x3B14,
+ /* U+3B88 */ 0x3B15, 0x3B16, 0x3B17, 0x3B18, 0x3B19, 0x3B20, 0x3B21, 0x3B22,
+ /* U+3B90 */ 0x3B23, 0x3B24, 0x3B25, 0x3B26, 0x3B27, 0x3B28, 0x3B29, 0x3B30,
+ /* U+3B98 */ 0x3B31, 0x3B32, 0x3B33, 0x3B34, 0x3B35, 0x3B36, 0x3B37, 0x3B38,
+ /* U+3BA0 */ 0x3B39, 0x3B40, 0x3B41, 0x3B42, 0x3B43, 0x3B44, 0x3B45, 0x3B46,
+ /* U+3BA8 */ 0x3B47, 0x3B48, 0x3B49, 0x3B50, 0x3B51, 0x3B52, 0x3B53, 0x3B54,
+ /* U+3BB0 */ 0x3B55, 0x3B56, 0x3B57, 0x3B58, 0x3B59, 0x3B60, 0x3B61, 0x3B62,
+ /* U+3BB8 */ 0x3B63, 0x3B64, 0x3B65, 0x3B66, 0x3B67, 0x3B68, 0x3B69, 0x3B70,
+ /* U+3BC0 */ 0x3B71, 0x3B72, 0x3B73, 0x3B74, 0x3B75, 0x3B76, 0x3B77, 0x3B78,
+ /* U+3BC8 */ 0x3B79, 0x3B80, 0x3B81, 0x3B82, 0x3B83, 0x3B84, 0x3B85, 0x3B86,
+ /* U+3BD0 */ 0x3B87, 0x3B88, 0x3B89, 0x3B90, 0x3B91, 0x3B92, 0x3B93, 0x3B94,
+ /* U+3BD8 */ 0x3B95, 0x3B96, 0x3B97, 0x3B98, 0x3B99, 0x3BA0, 0x3BA1, 0x3BA2,
+ /* U+3BE0 */ 0x3BA3, 0x3BA4, 0x3BA5, 0x3BA6, 0x3BA7, 0x3BA8, 0x3BA9, 0x3BB0,
+ /* U+3BE8 */ 0x3BB1, 0x3BB2, 0x3BB3, 0x3BB4, 0x3BB5, 0x3BB6, 0x3BB7, 0x3BB8,
+ /* U+3BF0 */ 0x3BB9, 0x3BC0, 0x3BC1, 0x3BC2, 0x3BC3, 0x3BC4, 0x3BC5, 0x3BC6,
+ /* U+3BF8 */ 0x3BC7, 0x3BC8, 0x3BC9, 0x3BD0, 0x3BD1, 0x3BD2, 0x3BD3, 0x3BD4,
+ /* U+3C00 */ 0x3BD5, 0x3BD6, 0x3BD7, 0x3BD8, 0x3BD9, 0x3BE0, 0x3BE1, 0x3BE2,
+ /* U+3C08 */ 0x3BE3, 0x3BE4, 0x3BE5, 0x3BE6, 0x3BE7, 0x3BE8, 0x3BE9, 0x3BF0,
+ /* U+3C10 */ 0x3BF1, 0x3BF2, 0x3BF3, 0x3BF4, 0x3BF5, 0x3BF6, 0x3BF7, 0x3BF8,
+ /* U+3C18 */ 0x3BF9, 0x3C00, 0x3C01, 0x3C02, 0x3C03, 0x3C04, 0x3C05, 0x3C06,
+ /* U+3C20 */ 0x3C07, 0x3C08, 0x3C09, 0x3C10, 0x3C11, 0x3C12, 0x3C13, 0x3C14,
+ /* U+3C28 */ 0x3C15, 0x3C16, 0x3C17, 0x3C18, 0x3C19, 0x3C20, 0x3C21, 0x3C22,
+ /* U+3C30 */ 0x3C23, 0x3C24, 0x3C25, 0x3C26, 0x3C27, 0x3C28, 0x3C29, 0x3C30,
+ /* U+3C38 */ 0x3C31, 0x3C32, 0x3C33, 0x3C34, 0x3C35, 0x3C36, 0x3C37, 0x3C38,
+ /* U+3C40 */ 0x3C39, 0x3C40, 0x3C41, 0x3C42, 0x3C43, 0x3C44, 0x3C45, 0x3C46,
+ /* U+3C48 */ 0x3C47, 0x3C48, 0x3C49, 0x3C50, 0x3C51, 0x3C52, 0x3C53, 0x3C54,
+ /* U+3C50 */ 0x3C55, 0x3C56, 0x3C57, 0x3C58, 0x3C59, 0x3C60, 0x3C61, 0x3C62,
+ /* U+3C58 */ 0x3C63, 0x3C64, 0x3C65, 0x3C66, 0x3C67, 0x3C68, 0x3C69, 0x3C70,
+ /* U+3C60 */ 0x3C71, 0x3C72, 0x3C73, 0x3C74, 0x3C75, 0x3C76, 0x3C77, 0x3C78,
+ /* U+3C68 */ 0x3C79, 0x3C80, 0x3C81, 0x3C82, 0x3C83, 0x3C84, 0xFE69, 0x3C85,
+ /* U+3C70 */ 0x3C86, 0x3C87, 0x3C88, 0x3C89, 0x3C90, 0x3C91, 0x3C92, 0x3C93,
+ /* U+3C78 */ 0x3C94, 0x3C95, 0x3C96, 0x3C97, 0x3C98, 0x3C99, 0x3CA0, 0x3CA1,
+ /* U+3C80 */ 0x3CA2, 0x3CA3, 0x3CA4, 0x3CA5, 0x3CA6, 0x3CA7, 0x3CA8, 0x3CA9,
+ /* U+3C88 */ 0x3CB0, 0x3CB1, 0x3CB2, 0x3CB3, 0x3CB4, 0x3CB5, 0x3CB6, 0x3CB7,
+ /* U+3C90 */ 0x3CB8, 0x3CB9, 0x3CC0, 0x3CC1, 0x3CC2, 0x3CC3, 0x3CC4, 0x3CC5,
+ /* U+3C98 */ 0x3CC6, 0x3CC7, 0x3CC8, 0x3CC9, 0x3CD0, 0x3CD1, 0x3CD2, 0x3CD3,
+ /* U+3CA0 */ 0x3CD4, 0x3CD5, 0x3CD6, 0x3CD7, 0x3CD8, 0x3CD9, 0x3CE0, 0x3CE1,
+ /* U+3CA8 */ 0x3CE2, 0x3CE3, 0x3CE4, 0x3CE5, 0x3CE6, 0x3CE7, 0x3CE8, 0x3CE9,
+ /* U+3CB0 */ 0x3CF0, 0x3CF1, 0x3CF2, 0x3CF3, 0x3CF4, 0x3CF5, 0x3CF6, 0x3CF7,
+ /* U+3CB8 */ 0x3CF8, 0x3CF9, 0x3D00, 0x3D01, 0x3D02, 0x3D03, 0x3D04, 0x3D05,
+ /* U+3CC0 */ 0x3D06, 0x3D07, 0x3D08, 0x3D09, 0x3D10, 0x3D11, 0x3D12, 0x3D13,
+ /* U+3CC8 */ 0x3D14, 0x3D15, 0x3D16, 0x3D17, 0x3D18, 0x3D19, 0x3D20, 0x3D21,
+ /* U+3CD0 */ 0x3D22, 0x3D23, 0x3D24, 0x3D25, 0x3D26, 0x3D27, 0x3D28, 0x3D29,
+ /* U+3CD8 */ 0x3D30, 0x3D31, 0x3D32, 0x3D33, 0x3D34, 0x3D35, 0x3D36, 0x3D37,
+ /* U+3CE0 */ 0xFE6A,
+ /* Contiguous area: U+4056 .. U+415F */
+ /* U+4056 */ 0xFE6F, 0x42E3,
+ /* U+4058 */ 0x42E4, 0x42E5, 0x42E6, 0x42E7, 0x42E8, 0x42E9, 0x42F0, 0x42F1,
+ /* U+4060 */ 0x42F2, 0x42F3, 0x42F4, 0x42F5, 0x42F6, 0x42F7, 0x42F8, 0x42F9,
+ /* U+4068 */ 0x4300, 0x4301, 0x4302, 0x4303, 0x4304, 0x4305, 0x4306, 0x4307,
+ /* U+4070 */ 0x4308, 0x4309, 0x4310, 0x4311, 0x4312, 0x4313, 0x4314, 0x4315,
+ /* U+4078 */ 0x4316, 0x4317, 0x4318, 0x4319, 0x4320, 0x4321, 0x4322, 0x4323,
+ /* U+4080 */ 0x4324, 0x4325, 0x4326, 0x4327, 0x4328, 0x4329, 0x4330, 0x4331,
+ /* U+4088 */ 0x4332, 0x4333, 0x4334, 0x4335, 0x4336, 0x4337, 0x4338, 0x4339,
+ /* U+4090 */ 0x4340, 0x4341, 0x4342, 0x4343, 0x4344, 0x4345, 0x4346, 0x4347,
+ /* U+4098 */ 0x4348, 0x4349, 0x4350, 0x4351, 0x4352, 0x4353, 0x4354, 0x4355,
+ /* U+40A0 */ 0x4356, 0x4357, 0x4358, 0x4359, 0x4360, 0x4361, 0x4362, 0x4363,
+ /* U+40A8 */ 0x4364, 0x4365, 0x4366, 0x4367, 0x4368, 0x4369, 0x4370, 0x4371,
+ /* U+40B0 */ 0x4372, 0x4373, 0x4374, 0x4375, 0x4376, 0x4377, 0x4378, 0x4379,
+ /* U+40B8 */ 0x4380, 0x4381, 0x4382, 0x4383, 0x4384, 0x4385, 0x4386, 0x4387,
+ /* U+40C0 */ 0x4388, 0x4389, 0x4390, 0x4391, 0x4392, 0x4393, 0x4394, 0x4395,
+ /* U+40C8 */ 0x4396, 0x4397, 0x4398, 0x4399, 0x43A0, 0x43A1, 0x43A2, 0x43A3,
+ /* U+40D0 */ 0x43A4, 0x43A5, 0x43A6, 0x43A7, 0x43A8, 0x43A9, 0x43B0, 0x43B1,
+ /* U+40D8 */ 0x43B2, 0x43B3, 0x43B4, 0x43B5, 0x43B6, 0x43B7, 0x43B8, 0x43B9,
+ /* U+40E0 */ 0x43C0, 0x43C1, 0x43C2, 0x43C3, 0x43C4, 0x43C5, 0x43C6, 0x43C7,
+ /* U+40E8 */ 0x43C8, 0x43C9, 0x43D0, 0x43D1, 0x43D2, 0x43D3, 0x43D4, 0x43D5,
+ /* U+40F0 */ 0x43D6, 0x43D7, 0x43D8, 0x43D9, 0x43E0, 0x43E1, 0x43E2, 0x43E3,
+ /* U+40F8 */ 0x43E4, 0x43E5, 0x43E6, 0x43E7, 0x43E8, 0x43E9, 0x43F0, 0x43F1,
+ /* U+4100 */ 0x43F2, 0x43F3, 0x43F4, 0x43F5, 0x43F6, 0x43F7, 0x43F8, 0x43F9,
+ /* U+4108 */ 0x4400, 0x4401, 0x4402, 0x4403, 0x4404, 0x4405, 0x4406, 0x4407,
+ /* U+4110 */ 0x4408, 0x4409, 0x4410, 0x4411, 0x4412, 0x4413, 0x4414, 0x4415,
+ /* U+4118 */ 0x4416, 0x4417, 0x4418, 0x4419, 0x4420, 0x4421, 0x4422, 0x4423,
+ /* U+4120 */ 0x4424, 0x4425, 0x4426, 0x4427, 0x4428, 0x4429, 0x4430, 0x4431,
+ /* U+4128 */ 0x4432, 0x4433, 0x4434, 0x4435, 0x4436, 0x4437, 0x4438, 0x4439,
+ /* U+4130 */ 0x4440, 0x4441, 0x4442, 0x4443, 0x4444, 0x4445, 0x4446, 0x4447,
+ /* U+4138 */ 0x4448, 0x4449, 0x4450, 0x4451, 0x4452, 0x4453, 0x4454, 0x4455,
+ /* U+4140 */ 0x4456, 0x4457, 0x4458, 0x4459, 0x4460, 0x4461, 0x4462, 0x4463,
+ /* U+4148 */ 0x4464, 0x4465, 0x4466, 0x4467, 0x4468, 0x4469, 0x4470, 0x4471,
+ /* U+4150 */ 0x4472, 0x4473, 0x4474, 0x4475, 0x4476, 0x4477, 0x4478, 0x4479,
+ /* U+4158 */ 0x4480, 0x4481, 0x4482, 0x4483, 0x4484, 0x4485, 0x4486, 0xFE70,
+ /* Contiguous area: U+4337 .. U+44D6 */
+ /* U+4337 */ 0xFE72,
+ /* U+4338 */ 0x4778, 0x4779, 0x4780, 0x4781, 0x4782, 0x4783, 0x4784, 0x4785,
+ /* U+4340 */ 0x4786, 0x4787, 0x4788, 0x4789, 0x4790, 0x4791, 0x4792, 0x4793,
+ /* U+4348 */ 0x4794, 0x4795, 0x4796, 0x4797, 0x4798, 0x4799, 0x47A0, 0x47A1,
+ /* U+4350 */ 0x47A2, 0x47A3, 0x47A4, 0x47A5, 0x47A6, 0x47A7, 0x47A8, 0x47A9,
+ /* U+4358 */ 0x47B0, 0x47B1, 0x47B2, 0x47B3, 0x47B4, 0x47B5, 0x47B6, 0x47B7,
+ /* U+4360 */ 0x47B8, 0x47B9, 0x47C0, 0x47C1, 0x47C2, 0x47C3, 0x47C4, 0x47C5,
+ /* U+4368 */ 0x47C6, 0x47C7, 0x47C8, 0x47C9, 0x47D0, 0x47D1, 0x47D2, 0x47D3,
+ /* U+4370 */ 0x47D4, 0x47D5, 0x47D6, 0x47D7, 0x47D8, 0x47D9, 0x4800, 0x4801,
+ /* U+4378 */ 0x4802, 0x4803, 0x4804, 0x4805, 0x4806, 0x4807, 0x4808, 0x4809,
+ /* U+4380 */ 0x4810, 0x4811, 0x4812, 0x4813, 0x4814, 0x4815, 0x4816, 0x4817,
+ /* U+4388 */ 0x4818, 0x4819, 0x4820, 0x4821, 0x4822, 0x4823, 0x4824, 0x4825,
+ /* U+4390 */ 0x4826, 0x4827, 0x4828, 0x4829, 0x4830, 0x4831, 0x4832, 0x4833,
+ /* U+4398 */ 0x4834, 0x4835, 0x4836, 0x4837, 0x4838, 0x4839, 0x4840, 0x4841,
+ /* U+43A0 */ 0x4842, 0x4843, 0x4844, 0x4845, 0x4846, 0x4847, 0x4848, 0x4849,
+ /* U+43A8 */ 0x4850, 0x4851, 0x4852, 0x4853, 0xFE78, 0x4854, 0x4855, 0x4856,
+ /* U+43B0 */ 0x4857, 0xFE77, 0x4858, 0x4859, 0x4860, 0x4861, 0x4862, 0x4863,
+ /* U+43B8 */ 0x4864, 0x4865, 0x4866, 0x4867, 0x4868, 0x4869, 0x4870, 0x4871,
+ /* U+43C0 */ 0x4872, 0x4873, 0x4874, 0x4875, 0x4876, 0x4877, 0x4878, 0x4879,
+ /* U+43C8 */ 0x4880, 0x4881, 0x4882, 0x4883, 0x4884, 0x4885, 0x4886, 0x4887,
+ /* U+43D0 */ 0x4888, 0x4889, 0x4890, 0x4891, 0x4892, 0x4893, 0x4894, 0x4895,
+ /* U+43D8 */ 0x4896, 0x4897, 0x4898, 0x4899, 0x48A0, 0xFE7A, 0x48A1, 0x48A2,
+ /* U+43E0 */ 0x48A3, 0x48A4, 0x48A5, 0x48A6, 0x48A7, 0x48A8, 0x48A9, 0x48B0,
+ /* U+43E8 */ 0x48B1, 0x48B2, 0x48B3, 0x48B4, 0x48B5, 0x48B6, 0x48B7, 0x48B8,
+ /* U+43F0 */ 0x48B9, 0x48C0, 0x48C1, 0x48C2, 0x48C3, 0x48C4, 0x48C5, 0x48C6,
+ /* U+43F8 */ 0x48C7, 0x48C8, 0x48C9, 0x48D0, 0x48D1, 0x48D2, 0x48D3, 0x48D4,
+ /* U+4400 */ 0x48D5, 0x48D6, 0x48D7, 0x48D8, 0x48D9, 0x48E0, 0x48E1, 0x48E2,
+ /* U+4408 */ 0x48E3, 0x48E4, 0x48E5, 0x48E6, 0x48E7, 0x48E8, 0x48E9, 0x48F0,
+ /* U+4410 */ 0x48F1, 0x48F2, 0x48F3, 0x48F4, 0x48F5, 0x48F6, 0x48F7, 0x48F8,
+ /* U+4418 */ 0x48F9, 0x4900, 0x4901, 0x4902, 0x4903, 0x4904, 0x4905, 0x4906,
+ /* U+4420 */ 0x4907, 0x4908, 0x4909, 0x4910, 0x4911, 0x4912, 0x4913, 0x4914,
+ /* U+4428 */ 0x4915, 0x4916, 0x4917, 0x4918, 0x4919, 0x4920, 0x4921, 0x4922,
+ /* U+4430 */ 0x4923, 0x4924, 0x4925, 0x4926, 0x4927, 0x4928, 0x4929, 0x4930,
+ /* U+4438 */ 0x4931, 0x4932, 0x4933, 0x4934, 0x4935, 0x4936, 0x4937, 0x4938,
+ /* U+4440 */ 0x4939, 0x4940, 0x4941, 0x4942, 0x4943, 0x4944, 0x4945, 0x4946,
+ /* U+4448 */ 0x4947, 0x4948, 0x4949, 0x4950, 0x4951, 0x4952, 0x4953, 0x4954,
+ /* U+4450 */ 0x4955, 0x4956, 0x4957, 0x4958, 0x4959, 0x4960, 0x4961, 0x4962,
+ /* U+4458 */ 0x4963, 0x4964, 0x4965, 0x4966, 0x4967, 0x4968, 0x4969, 0x4970,
+ /* U+4460 */ 0x4971, 0x4972, 0x4973, 0x4974, 0x4975, 0x4976, 0x4977, 0x4978,
+ /* U+4468 */ 0x4979, 0x4980, 0x4981, 0x4982, 0x4983, 0x4984, 0x4985, 0x4986,
+ /* U+4470 */ 0x4987, 0x4988, 0x4989, 0x4990, 0x4991, 0x4992, 0x4993, 0x4994,
+ /* U+4478 */ 0x4995, 0x4996, 0x4997, 0x4998, 0x4999, 0x49A0, 0x49A1, 0x49A2,
+ /* U+4480 */ 0x49A3, 0x49A4, 0x49A5, 0x49A6, 0x49A7, 0x49A8, 0x49A9, 0x49B0,
+ /* U+4488 */ 0x49B1, 0x49B2, 0x49B3, 0x49B4, 0x49B5, 0x49B6, 0x49B7, 0x49B8,
+ /* U+4490 */ 0x49B9, 0x49C0, 0x49C1, 0x49C2, 0x49C3, 0x49C4, 0x49C5, 0x49C6,
+ /* U+4498 */ 0x49C7, 0x49C8, 0x49C9, 0x49D0, 0x49D1, 0x49D2, 0x49D3, 0x49D4,
+ /* U+44A0 */ 0x49D5, 0x49D6, 0x49D7, 0x49D8, 0x49D9, 0x49E0, 0x49E1, 0x49E2,
+ /* U+44A8 */ 0x49E3, 0x49E4, 0x49E5, 0x49E6, 0x49E7, 0x49E8, 0x49E9, 0x49F0,
+ /* U+44B0 */ 0x49F1, 0x49F2, 0x49F3, 0x49F4, 0x49F5, 0x49F6, 0x49F7, 0x49F8,
+ /* U+44B8 */ 0x49F9, 0x4A00, 0x4A01, 0x4A02, 0x4A03, 0x4A04, 0x4A05, 0x4A06,
+ /* U+44C0 */ 0x4A07, 0x4A08, 0x4A09, 0x4A10, 0x4A11, 0x4A12, 0x4A13, 0x4A14,
+ /* U+44C8 */ 0x4A15, 0x4A16, 0x4A17, 0x4A18, 0x4A19, 0x4A20, 0x4A21, 0x4A22,
+ /* U+44D0 */ 0x4A23, 0x4A24, 0x4A25, 0x4A26, 0x4A27, 0x4A28, 0xFE7B,
+ /* Contiguous area: U+464C .. U+478D */
+ /* U+464C */ 0xFE7D, 0x4C82, 0x4C83, 0x4C84,
+ /* U+4650 */ 0x4C85, 0x4C86, 0x4C87, 0x4C88, 0x4C89, 0x4C90, 0x4C91, 0x4C92,
+ /* U+4658 */ 0x4C93, 0x4C94, 0x4C95, 0x4C96, 0x4C97, 0x4C98, 0x4C99, 0x4CA0,
+ /* U+4660 */ 0x4CA1, 0xFE7C, 0x4CA2, 0x4CA3, 0x4CA4, 0x4CA5, 0x4CA6, 0x4CA7,
+ /* U+4668 */ 0x4CA8, 0x4CA9, 0x4CB0, 0x4CB1, 0x4CB2, 0x4CB3, 0x4CB4, 0x4CB5,
+ /* U+4670 */ 0x4CB6, 0x4CB7, 0x4CB8, 0x4CB9, 0x4CC0, 0x4CC1, 0x4CC2, 0x4CC3,
+ /* U+4678 */ 0x4CC4, 0x4CC5, 0x4CC6, 0x4CC7, 0x4CC8, 0x4CC9, 0x4CD0, 0x4CD1,
+ /* U+4680 */ 0x4CD2, 0x4CD3, 0x4CD4, 0x4CD5, 0x4CD6, 0x4CD7, 0x4CD8, 0x4CD9,
+ /* U+4688 */ 0x4CE0, 0x4CE1, 0x4CE2, 0x4CE3, 0x4CE4, 0x4CE5, 0x4CE6, 0x4CE7,
+ /* U+4690 */ 0x4CE8, 0x4CE9, 0x4CF0, 0x4CF1, 0x4CF2, 0x4CF3, 0x4CF4, 0x4CF5,
+ /* U+4698 */ 0x4CF6, 0x4CF7, 0x4CF8, 0x4CF9, 0x4D00, 0x4D01, 0x4D02, 0x4D03,
+ /* U+46A0 */ 0x4D04, 0x4D05, 0x4D06, 0x4D07, 0x4D08, 0x4D09, 0x4D10, 0x4D11,
+ /* U+46A8 */ 0x4D12, 0x4D13, 0x4D14, 0x4D15, 0x4D16, 0x4D17, 0x4D18, 0x4D19,
+ /* U+46B0 */ 0x4D20, 0x4D21, 0x4D22, 0x4D23, 0x4D24, 0x4D25, 0x4D26, 0x4D27,
+ /* U+46B8 */ 0x4D28, 0x4D29, 0x4D30, 0x4D31, 0x4D32, 0x4D33, 0x4D34, 0x4D35,
+ /* U+46C0 */ 0x4D36, 0x4D37, 0x4D38, 0x4D39, 0x4D40, 0x4D41, 0x4D42, 0x4D43,
+ /* U+46C8 */ 0x4D44, 0x4D45, 0x4D46, 0x4D47, 0x4D48, 0x4D49, 0x4D50, 0x4D51,
+ /* U+46D0 */ 0x4D52, 0x4D53, 0x4D54, 0x4D55, 0x4D56, 0x4D57, 0x4D58, 0x4D59,
+ /* U+46D8 */ 0x4D60, 0x4D61, 0x4D62, 0x4D63, 0x4D64, 0x4D65, 0x4D66, 0x4D67,
+ /* U+46E0 */ 0x4D68, 0x4D69, 0x4D70, 0x4D71, 0x4D72, 0x4D73, 0x4D74, 0x4D75,
+ /* U+46E8 */ 0x4D76, 0x4D77, 0x4D78, 0x4D79, 0x4D80, 0x4D81, 0x4D82, 0x4D83,
+ /* U+46F0 */ 0x4D84, 0x4D85, 0x4D86, 0x4D87, 0x4D88, 0x4D89, 0x4D90, 0x4D91,
+ /* U+46F8 */ 0x4D92, 0x4D93, 0x4D94, 0x4D95, 0x4D96, 0x4D97, 0x4D98, 0x4D99,
+ /* U+4700 */ 0x4DA0, 0x4DA1, 0x4DA2, 0x4DA3, 0x4DA4, 0x4DA5, 0x4DA6, 0x4DA7,
+ /* U+4708 */ 0x4DA8, 0x4DA9, 0x4DB0, 0x4DB1, 0x4DB2, 0x4DB3, 0x4DB4, 0x4DB5,
+ /* U+4710 */ 0x4DB6, 0x4DB7, 0x4DB8, 0x4DB9, 0x4DC0, 0x4DC1, 0x4DC2, 0x4DC3,
+ /* U+4718 */ 0x4DC4, 0x4DC5, 0x4DC6, 0x4DC7, 0x4DC8, 0x4DC9, 0x4DD0, 0x4DD1,
+ /* U+4720 */ 0x4DD2, 0x4DD3, 0x4DD4, 0xFE80, 0x4DD5, 0x4DD6, 0x4DD7, 0x4DD8,
+ /* U+4728 */ 0x4DD9, 0xFE81, 0x4DE0, 0x4DE1, 0x4DE2, 0x4DE3, 0x4DE4, 0x4DE5,
+ /* U+4730 */ 0x4DE6, 0x4DE7, 0x4DE8, 0x4DE9, 0x4DF0, 0x4DF1, 0x4DF2, 0x4DF3,
+ /* U+4738 */ 0x4DF4, 0x4DF5, 0x4DF6, 0x4DF7, 0x4DF8, 0x4DF9, 0x4E00, 0x4E01,
+ /* U+4740 */ 0x4E02, 0x4E03, 0x4E04, 0x4E05, 0x4E06, 0x4E07, 0x4E08, 0x4E09,
+ /* U+4748 */ 0x4E10, 0x4E11, 0x4E12, 0x4E13, 0x4E14, 0x4E15, 0x4E16, 0x4E17,
+ /* U+4750 */ 0x4E18, 0x4E19, 0x4E20, 0x4E21, 0x4E22, 0x4E23, 0x4E24, 0x4E25,
+ /* U+4758 */ 0x4E26, 0x4E27, 0x4E28, 0x4E29, 0x4E30, 0x4E31, 0x4E32, 0x4E33,
+ /* U+4760 */ 0x4E34, 0x4E35, 0x4E36, 0x4E37, 0x4E38, 0x4E39, 0x4E40, 0x4E41,
+ /* U+4768 */ 0x4E42, 0x4E43, 0x4E44, 0x4E45, 0x4E46, 0x4E47, 0x4E48, 0x4E49,
+ /* U+4770 */ 0x4E50, 0x4E51, 0x4E52, 0x4E53, 0x4E54, 0x4E55, 0x4E56, 0x4E57,
+ /* U+4778 */ 0x4E58, 0x4E59, 0x4E60, 0x4E61, 0xFE82, 0x4E62, 0x4E63, 0x4E64,
+ /* U+4780 */ 0x4E65, 0x4E66, 0x4E67, 0x4E68, 0x4E69, 0x4E70, 0x4E71, 0x4E72,
+ /* U+4788 */ 0x4E73, 0x4E74, 0x4E75, 0x4E76, 0x4E77, 0xFE83,
+ /* Contiguous area: U+4947 .. U+49B7 */
+ /* U+4947 */ 0xFE85,
+ /* U+4948 */ 0x5159, 0x5160, 0x5161, 0x5162, 0x5163, 0x5164, 0x5165, 0x5166,
+ /* U+4950 */ 0x5167, 0x5168, 0x5169, 0x5170, 0x5171, 0x5172, 0x5173, 0x5174,
+ /* U+4958 */ 0x5175, 0x5176, 0x5177, 0x5178, 0x5179, 0x5180, 0x5181, 0x5182,
+ /* U+4960 */ 0x5183, 0x5184, 0x5185, 0x5186, 0x5187, 0x5188, 0x5189, 0x5190,
+ /* U+4968 */ 0x5191, 0x5192, 0x5193, 0x5194, 0x5195, 0x5196, 0x5197, 0x5198,
+ /* U+4970 */ 0x5199, 0x51A0, 0x51A1, 0x51A2, 0x51A3, 0x51A4, 0x51A5, 0x51A6,
+ /* U+4978 */ 0x51A7, 0x51A8, 0xFE86, 0x51A9, 0x51B0, 0xFE87, 0x51B1, 0x51B2,
+ /* U+4980 */ 0x51B3, 0x51B4, 0xFE88, 0xFE89, 0x51B5, 0xFE8A, 0xFE8B, 0x51B6,
+ /* U+4988 */ 0x51B7, 0x51B8, 0x51B9, 0x51C0, 0x51C1, 0x51C2, 0x51C3, 0x51C4,
+ /* U+4990 */ 0x51C5, 0x51C6, 0x51C7, 0x51C8, 0x51C9, 0x51D0, 0x51D1, 0x51D2,
+ /* U+4998 */ 0x51D3, 0x51D4, 0x51D5, 0xFE8D, 0x51D6, 0x51D7, 0x51D8, 0xFE8C,
+ /* U+49A0 */ 0x51D9, 0x51E0, 0x51E1, 0x51E2, 0x51E3, 0x51E4, 0x51E5, 0x51E6,
+ /* U+49A8 */ 0x51E7, 0x51E8, 0x51E9, 0x51F0, 0x51F1, 0x51F2, 0x51F3, 0x51F4,
+ /* U+49B0 */ 0x51F5, 0x51F6, 0x51F7, 0x51F8, 0x51F9, 0x5200, 0xFE8F, 0xFE8E,
+ /* Contiguous area: U+4C77 .. U+9FA5 */
+ /* U+4C77 */ 0xFE96,
+ /* U+4C78 */ 0x5664, 0x5665, 0x5666, 0x5667, 0x5668, 0x5669, 0x5670, 0x5671,
+ /* U+4C80 */ 0x5672, 0x5673, 0x5674, 0x5675, 0x5676, 0x5677, 0x5678, 0x5679,
+ /* U+4C88 */ 0x5680, 0x5681, 0x5682, 0x5683, 0x5684, 0x5685, 0x5686, 0x5687,
+ /* U+4C90 */ 0x5688, 0x5689, 0x5690, 0x5691, 0x5692, 0x5693, 0x5694, 0x5695,
+ /* U+4C98 */ 0x5696, 0x5697, 0x5698, 0x5699, 0x56A0, 0x56A1, 0x56A2, 0xFE93,
+ /* U+4CA0 */ 0xFE94, 0xFE95, 0xFE97, 0xFE92, 0x56A3, 0x56A4, 0x56A5, 0x56A6,
+ /* U+4CA8 */ 0x56A7, 0x56A8, 0x56A9, 0x56B0, 0x56B1, 0x56B2, 0x56B3, 0x56B4,
+ /* U+4CB0 */ 0x56B5, 0x56B6, 0x56B7, 0x56B8, 0x56B9, 0x56C0, 0x56C1, 0x56C2,
+ /* U+4CB8 */ 0x56C3, 0x56C4, 0x56C5, 0x56C6, 0x56C7, 0x56C8, 0x56C9, 0x56D0,
+ /* U+4CC0 */ 0x56D1, 0x56D2, 0x56D3, 0x56D4, 0x56D5, 0x56D6, 0x56D7, 0x56D8,
+ /* U+4CC8 */ 0x56D9, 0x56E0, 0x56E1, 0x56E2, 0x56E3, 0x56E4, 0x56E5, 0x56E6,
+ /* U+4CD0 */ 0x56E7, 0x56E8, 0x56E9, 0x56F0, 0x56F1, 0x56F2, 0x56F3, 0x56F4,
+ /* U+4CD8 */ 0x56F5, 0x56F6, 0x56F7, 0x56F8, 0x56F9, 0x5700, 0x5701, 0x5702,
+ /* U+4CE0 */ 0x5703, 0x5704, 0x5705, 0x5706, 0x5707, 0x5708, 0x5709, 0x5710,
+ /* U+4CE8 */ 0x5711, 0x5712, 0x5713, 0x5714, 0x5715, 0x5716, 0x5717, 0x5718,
+ /* U+4CF0 */ 0x5719, 0x5720, 0x5721, 0x5722, 0x5723, 0x5724, 0x5725, 0x5726,
+ /* U+4CF8 */ 0x5727, 0x5728, 0x5729, 0x5730, 0x5731, 0x5732, 0x5733, 0x5734,
+ /* U+4D00 */ 0x5735, 0x5736, 0x5737, 0x5738, 0x5739, 0x5740, 0x5741, 0x5742,
+ /* U+4D08 */ 0x5743, 0x5744, 0x5745, 0x5746, 0x5747, 0x5748, 0x5749, 0x5750,
+ /* U+4D10 */ 0x5751, 0x5752, 0x5753, 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C,
+ /* U+4D18 */ 0xFE9D, 0xFE9E, 0x5754, 0x5755, 0x5756, 0x5757, 0x5758, 0x5759,
+ /* U+4D20 */ 0x5760, 0x5761, 0x5762, 0x5763, 0x5764, 0x5765, 0x5766, 0x5767,
+ /* U+4D28 */ 0x5768, 0x5769, 0x5770, 0x5771, 0x5772, 0x5773, 0x5774, 0x5775,
+ /* U+4D30 */ 0x5776, 0x5777, 0x5778, 0x5779, 0x5780, 0x5781, 0x5782, 0x5783,
+ /* U+4D38 */ 0x5784, 0x5785, 0x5786, 0x5787, 0x5788, 0x5789, 0x5790, 0x5791,
+ /* U+4D40 */ 0x5792, 0x5793, 0x5794, 0x5795, 0x5796, 0x5797, 0x5798, 0x5799,
+ /* U+4D48 */ 0x57A0, 0x57A1, 0x57A2, 0x57A3, 0x57A4, 0x57A5, 0x57A6, 0x57A7,
+ /* U+4D50 */ 0x57A8, 0x57A9, 0x57B0, 0x57B1, 0x57B2, 0x57B3, 0x57B4, 0x57B5,
+ /* U+4D58 */ 0x57B6, 0x57B7, 0x57B8, 0x57B9, 0x57C0, 0x57C1, 0x57C2, 0x57C3,
+ /* U+4D60 */ 0x57C4, 0x57C5, 0x57C6, 0x57C7, 0x57C8, 0x57C9, 0x57D0, 0x57D1,
+ /* U+4D68 */ 0x57D2, 0x57D3, 0x57D4, 0x57D5, 0x57D6, 0x57D7, 0x57D8, 0x57D9,
+ /* U+4D70 */ 0x5800, 0x5801, 0x5802, 0x5803, 0x5804, 0x5805, 0x5806, 0x5807,
+ /* U+4D78 */ 0x5808, 0x5809, 0x5810, 0x5811, 0x5812, 0x5813, 0x5814, 0x5815,
+ /* U+4D80 */ 0x5816, 0x5817, 0x5818, 0x5819, 0x5820, 0x5821, 0x5822, 0x5823,
+ /* U+4D88 */ 0x5824, 0x5825, 0x5826, 0x5827, 0x5828, 0x5829, 0x5830, 0x5831,
+ /* U+4D90 */ 0x5832, 0x5833, 0x5834, 0x5835, 0x5836, 0x5837, 0x5838, 0x5839,
+ /* U+4D98 */ 0x5840, 0x5841, 0x5842, 0x5843, 0x5844, 0x5845, 0x5846, 0x5847,
+ /* U+4DA0 */ 0x5848, 0x5849, 0x5850, 0x5851, 0x5852, 0x5853, 0x5854, 0x5855,
+ /* U+4DA8 */ 0x5856, 0x5857, 0x5858, 0x5859, 0x5860, 0x5861, 0xFE9F, 0x5862,
+ /* U+4DB0 */ 0x5863, 0x5864, 0x5865, 0x5866, 0x5867, 0x5868, 0x5869, 0x5870,
+ /* U+4DB8 */ 0x5871, 0x5872, 0x5873, 0x5874, 0x5875, 0x5876, 0x5877, 0x5878,
+ /* U+4DC0 */ 0x5879, 0x5880, 0x5881, 0x5882, 0x5883, 0x5884, 0x5885, 0x5886,
+ /* U+4DC8 */ 0x5887, 0x5888, 0x5889, 0x5890, 0x5891, 0x5892, 0x5893, 0x5894,
+ /* U+4DD0 */ 0x5895, 0x5896, 0x5897, 0x5898, 0x5899, 0x58A0, 0x58A1, 0x58A2,
+ /* U+4DD8 */ 0x58A3, 0x58A4, 0x58A5, 0x58A6, 0x58A7, 0x58A8, 0x58A9, 0x58B0,
+ /* U+4DE0 */ 0x58B1, 0x58B2, 0x58B3, 0x58B4, 0x58B5, 0x58B6, 0x58B7, 0x58B8,
+ /* U+4DE8 */ 0x58B9, 0x58C0, 0x58C1, 0x58C2, 0x58C3, 0x58C4, 0x58C5, 0x58C6,
+ /* U+4DF0 */ 0x58C7, 0x58C8, 0x58C9, 0x58D0, 0x58D1, 0x58D2, 0x58D3, 0x58D4,
+ /* U+4DF8 */ 0x58D5, 0x58D6, 0x58D7, 0x58D8, 0x58D9, 0x58E0, 0x58E1, 0x58E2,
+ /* U+4E00 */ 0xD2BB, 0xB6A1, 0x8140, 0xC6DF, 0x8141, 0x8142, 0x8143, 0xCDF2,
+ /* U+4E08 */ 0xD5C9, 0xC8FD, 0xC9CF, 0xCFC2, 0xD8A2, 0xB2BB, 0xD3EB, 0x8144,
+ /* U+4E10 */ 0xD8A4, 0xB3F3, 0x8145, 0xD7A8, 0xC7D2, 0xD8A7, 0xCAC0, 0x8146,
+ /* U+4E18 */ 0xC7F0, 0xB1FB, 0xD2B5, 0xB4D4, 0xB6AB, 0xCBBF, 0xD8A9, 0x8147,
+ /* U+4E20 */ 0x8148, 0x8149, 0xB6AA, 0x814A, 0xC1BD, 0xD1CF, 0x814B, 0xC9A5,
+ /* U+4E28 */ 0xD8AD, 0x814C, 0xB8F6, 0xD1BE, 0xE3DC, 0xD6D0, 0x814D, 0x814E,
+ /* U+4E30 */ 0xB7E1, 0x814F, 0xB4AE, 0x8150, 0xC1D9, 0x8151, 0xD8BC, 0x8152,
+ /* U+4E38 */ 0xCDE8, 0xB5A4, 0xCEAA, 0xD6F7, 0x8153, 0xC0F6, 0xBED9, 0xD8AF,
+ /* U+4E40 */ 0x8154, 0x8155, 0x8156, 0xC4CB, 0x8157, 0xBEC3, 0x8158, 0xD8B1,
+ /* U+4E48 */ 0xC3B4, 0xD2E5, 0x8159, 0xD6AE, 0xCEDA, 0xD5A7, 0xBAF5, 0xB7A6,
+ /* U+4E50 */ 0xC0D6, 0x815A, 0xC6B9, 0xC5D2, 0xC7C7, 0x815B, 0xB9D4, 0x815C,
+ /* U+4E58 */ 0xB3CB, 0xD2D2, 0x815D, 0x815E, 0xD8BF, 0xBEC5, 0xC6F2, 0xD2B2,
+ /* U+4E60 */ 0xCFB0, 0xCFE7, 0x815F, 0x8160, 0x8161, 0x8162, 0xCAE9, 0x8163,
+ /* U+4E68 */ 0x8164, 0xD8C0, 0x8165, 0x8166, 0x8167, 0x8168, 0x8169, 0x816A,
+ /* U+4E70 */ 0xC2F2, 0xC2D2, 0x816B, 0xC8E9, 0x816C, 0x816D, 0x816E, 0x816F,
+ /* U+4E78 */ 0x8170, 0x8171, 0x8172, 0x8173, 0x8174, 0x8175, 0xC7AC, 0x8176,
+ /* U+4E80 */ 0x8177, 0x8178, 0x8179, 0x817A, 0x817B, 0x817C, 0xC1CB, 0x817D,
+ /* U+4E88 */ 0xD3E8, 0xD5F9, 0x817E, 0xCAC2, 0xB6FE, 0xD8A1, 0xD3DA, 0xBFF7,
+ /* U+4E90 */ 0x8180, 0xD4C6, 0xBBA5, 0xD8C1, 0xCEE5, 0xBEAE, 0x8181, 0x8182,
+ /* U+4E98 */ 0xD8A8, 0x8183, 0xD1C7, 0xD0A9, 0x8184, 0x8185, 0x8186, 0xD8BD,
+ /* U+4EA0 */ 0xD9EF, 0xCDF6, 0xBFBA, 0x8187, 0xBDBB, 0xBAA5, 0xD2E0, 0xB2FA,
+ /* U+4EA8 */ 0xBAE0, 0xC4B6, 0x8188, 0xCFED, 0xBEA9, 0xCDA4, 0xC1C1, 0x8189,
+ /* U+4EB0 */ 0x818A, 0x818B, 0xC7D7, 0xD9F1, 0x818C, 0xD9F4, 0x818D, 0x818E,
+ /* U+4EB8 */ 0x818F, 0x8190, 0xC8CB, 0xD8E9, 0x8191, 0x8192, 0x8193, 0xD2DA,
+ /* U+4EC0 */ 0xCAB2, 0xC8CA, 0xD8EC, 0xD8EA, 0xD8C6, 0xBDF6, 0xC6CD, 0xB3F0,
+ /* U+4EC8 */ 0x8194, 0xD8EB, 0xBDF1, 0xBDE9, 0x8195, 0xC8D4, 0xB4D3, 0x8196,
+ /* U+4ED0 */ 0x8197, 0xC2D8, 0x8198, 0xB2D6, 0xD7D0, 0xCACB, 0xCBFB, 0xD5CC,
+ /* U+4ED8 */ 0xB8B6, 0xCFC9, 0x8199, 0x819A, 0x819B, 0xD9DA, 0xD8F0, 0xC7AA,
+ /* U+4EE0 */ 0x819C, 0xD8EE, 0x819D, 0xB4FA, 0xC1EE, 0xD2D4, 0x819E, 0x819F,
+ /* U+4EE8 */ 0xD8ED, 0x81A0, 0xD2C7, 0xD8EF, 0xC3C7, 0x81A1, 0x81A2, 0x81A3,
+ /* U+4EF0 */ 0xD1F6, 0x81A4, 0xD6D9, 0xD8F2, 0x81A5, 0xD8F5, 0xBCFE, 0xBCDB,
+ /* U+4EF8 */ 0x81A6, 0x81A7, 0x81A8, 0xC8CE, 0x81A9, 0xB7DD, 0x81AA, 0xB7C2,
+ /* U+4F00 */ 0x81AB, 0xC6F3, 0x81AC, 0x81AD, 0x81AE, 0x81AF, 0x81B0, 0x81B1,
+ /* U+4F08 */ 0x81B2, 0xD8F8, 0xD2C1, 0x81B3, 0x81B4, 0xCEE9, 0xBCBF, 0xB7FC,
+ /* U+4F10 */ 0xB7A5, 0xD0DD, 0x81B5, 0x81B6, 0x81B7, 0x81B8, 0x81B9, 0xD6DA,
+ /* U+4F18 */ 0xD3C5, 0xBBEF, 0xBBE1, 0xD8F1, 0x81BA, 0x81BB, 0xC9A1, 0xCEB0,
+ /* U+4F20 */ 0xB4AB, 0x81BC, 0xD8F3, 0x81BD, 0xC9CB, 0xD8F6, 0xC2D7, 0xD8F7,
+ /* U+4F28 */ 0x81BE, 0x81BF, 0xCEB1, 0xD8F9, 0x81C0, 0x81C1, 0x81C2, 0xB2AE,
+ /* U+4F30 */ 0xB9C0, 0x81C3, 0xD9A3, 0x81C4, 0xB0E9, 0x81C5, 0xC1E6, 0x81C6,
+ /* U+4F38 */ 0xC9EC, 0x81C7, 0xCBC5, 0x81C8, 0xCBC6, 0xD9A4, 0x81C9, 0x81CA,
+ /* U+4F40 */ 0x81CB, 0x81CC, 0x81CD, 0xB5E8, 0x81CE, 0x81CF, 0xB5AB, 0x81D0,
+ /* U+4F48 */ 0x81D1, 0x81D2, 0x81D3, 0x81D4, 0x81D5, 0xCEBB, 0xB5CD, 0xD7A1,
+ /* U+4F50 */ 0xD7F4, 0xD3D3, 0x81D6, 0xCCE5, 0x81D7, 0xBACE, 0x81D8, 0xD9A2,
+ /* U+4F58 */ 0xD9DC, 0xD3E0, 0xD8FD, 0xB7F0, 0xD7F7, 0xD8FE, 0xD8FA, 0xD9A1,
+ /* U+4F60 */ 0xC4E3, 0x81D9, 0x81DA, 0xD3B6, 0xD8F4, 0xD9DD, 0x81DB, 0xD8FB,
+ /* U+4F68 */ 0x81DC, 0xC5E5, 0x81DD, 0x81DE, 0xC0D0, 0x81DF, 0x81E0, 0xD1F0,
+ /* U+4F70 */ 0xB0DB, 0x81E1, 0x81E2, 0xBCD1, 0xD9A6, 0x81E3, 0xD9A5, 0x81E4,
+ /* U+4F78 */ 0x81E5, 0x81E6, 0x81E7, 0xD9AC, 0xD9AE, 0x81E8, 0xD9AB, 0xCAB9,
+ /* U+4F80 */ 0x81E9, 0x81EA, 0x81EB, 0xD9A9, 0xD6B6, 0x81EC, 0x81ED, 0x81EE,
+ /* U+4F88 */ 0xB3DE, 0xD9A8, 0x81EF, 0xC0FD, 0x81F0, 0xCACC, 0x81F1, 0xD9AA,
+ /* U+4F90 */ 0x81F2, 0xD9A7, 0x81F3, 0x81F4, 0xD9B0, 0x81F5, 0x81F6, 0xB6B1,
+ /* U+4F98 */ 0x81F7, 0x81F8, 0x81F9, 0xB9A9, 0x81FA, 0xD2C0, 0x81FB, 0x81FC,
+ /* U+4FA0 */ 0xCFC0, 0x81FD, 0x81FE, 0xC2C2, 0x8240, 0xBDC4, 0xD5EC, 0xB2E0,
+ /* U+4FA8 */ 0xC7C8, 0xBFEB, 0xD9AD, 0x8241, 0xD9AF, 0x8242, 0xCEEA, 0xBAEE,
+ /* U+4FB0 */ 0x8243, 0x8244, 0x8245, 0x8246, 0x8247, 0xC7D6, 0x8248, 0x8249,
+ /* U+4FB8 */ 0x824A, 0x824B, 0x824C, 0x824D, 0x824E, 0x824F, 0x8250, 0xB1E3,
+ /* U+4FC0 */ 0x8251, 0x8252, 0x8253, 0xB4D9, 0xB6ED, 0xD9B4, 0x8254, 0x8255,
+ /* U+4FC8 */ 0x8256, 0x8257, 0xBFA1, 0x8258, 0x8259, 0x825A, 0xD9DE, 0xC7CE,
+ /* U+4FD0 */ 0xC0FE, 0xD9B8, 0x825B, 0x825C, 0x825D, 0x825E, 0x825F, 0xCBD7,
+ /* U+4FD8 */ 0xB7FD, 0x8260, 0xD9B5, 0x8261, 0xD9B7, 0xB1A3, 0xD3E1, 0xD9B9,
+ /* U+4FE0 */ 0x8262, 0xD0C5, 0x8263, 0xD9B6, 0x8264, 0x8265, 0xD9B1, 0x8266,
+ /* U+4FE8 */ 0xD9B2, 0xC1A9, 0xD9B3, 0x8267, 0x8268, 0xBCF3, 0xD0DE, 0xB8A9,
+ /* U+4FF0 */ 0x8269, 0xBEE3, 0x826A, 0xD9BD, 0x826B, 0x826C, 0x826D, 0x826E,
+ /* U+4FF8 */ 0xD9BA, 0x826F, 0xB0B3, 0x8270, 0x8271, 0x8272, 0xD9C2, 0x8273,
+ /* U+5000 */ 0x8274, 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 0x827A, 0x827B,
+ /* U+5008 */ 0x827C, 0x827D, 0x827E, 0x8280, 0xD9C4, 0xB1B6, 0x8281, 0xD9BF,
+ /* U+5010 */ 0x8282, 0x8283, 0xB5B9, 0x8284, 0xBEF3, 0x8285, 0x8286, 0x8287,
+ /* U+5018 */ 0xCCC8, 0xBAF2, 0xD2D0, 0x8288, 0xD9C3, 0x8289, 0x828A, 0xBDE8,
+ /* U+5020 */ 0x828B, 0xB3AB, 0x828C, 0x828D, 0x828E, 0xD9C5, 0xBEEB, 0x828F,
+ /* U+5028 */ 0xD9C6, 0xD9BB, 0xC4DF, 0x8290, 0xD9BE, 0xD9C1, 0xD9C0, 0x8291,
+ /* U+5030 */ 0x8292, 0x8293, 0x8294, 0x8295, 0x8296, 0x8297, 0x8298, 0x8299,
+ /* U+5038 */ 0x829A, 0x829B, 0xD5AE, 0x829C, 0xD6B5, 0x829D, 0xC7E3, 0x829E,
+ /* U+5040 */ 0x829F, 0x82A0, 0x82A1, 0xD9C8, 0x82A2, 0x82A3, 0x82A4, 0xBCD9,
+ /* U+5048 */ 0xD9CA, 0x82A5, 0x82A6, 0x82A7, 0xD9BC, 0x82A8, 0xD9CB, 0xC6AB,
+ /* U+5050 */ 0x82A9, 0x82AA, 0x82AB, 0x82AC, 0x82AD, 0xD9C9, 0x82AE, 0x82AF,
+ /* U+5058 */ 0x82B0, 0x82B1, 0xD7F6, 0x82B2, 0xCDA3, 0x82B3, 0x82B4, 0x82B5,
+ /* U+5060 */ 0x82B6, 0x82B7, 0x82B8, 0x82B9, 0x82BA, 0xBDA1, 0x82BB, 0x82BC,
+ /* U+5068 */ 0x82BD, 0x82BE, 0x82BF, 0x82C0, 0xD9CC, 0x82C1, 0x82C2, 0x82C3,
+ /* U+5070 */ 0x82C4, 0x82C5, 0x82C6, 0x82C7, 0x82C8, 0x82C9, 0xC5BC, 0xCDB5,
+ /* U+5078 */ 0x82CA, 0x82CB, 0x82CC, 0xD9CD, 0x82CD, 0x82CE, 0xD9C7, 0xB3A5,
+ /* U+5080 */ 0xBFFE, 0x82CF, 0x82D0, 0x82D1, 0x82D2, 0xB8B5, 0x82D3, 0x82D4,
+ /* U+5088 */ 0xC0FC, 0x82D5, 0x82D6, 0x82D7, 0x82D8, 0xB0F8, 0x82D9, 0x82DA,
+ /* U+5090 */ 0x82DB, 0x82DC, 0x82DD, 0x82DE, 0x82DF, 0x82E0, 0x82E1, 0x82E2,
+ /* U+5098 */ 0x82E3, 0x82E4, 0x82E5, 0x82E6, 0x82E7, 0x82E8, 0x82E9, 0x82EA,
+ /* U+50A0 */ 0x82EB, 0x82EC, 0x82ED, 0xB4F6, 0x82EE, 0xD9CE, 0x82EF, 0xD9CF,
+ /* U+50A8 */ 0xB4A2, 0xD9D0, 0x82F0, 0x82F1, 0xB4DF, 0x82F2, 0x82F3, 0x82F4,
+ /* U+50B0 */ 0x82F5, 0x82F6, 0xB0C1, 0x82F7, 0x82F8, 0x82F9, 0x82FA, 0x82FB,
+ /* U+50B8 */ 0x82FC, 0x82FD, 0xD9D1, 0xC9B5, 0x82FE, 0x8340, 0x8341, 0x8342,
+ /* U+50C0 */ 0x8343, 0x8344, 0x8345, 0x8346, 0x8347, 0x8348, 0x8349, 0x834A,
+ /* U+50C8 */ 0x834B, 0x834C, 0x834D, 0x834E, 0x834F, 0x8350, 0x8351, 0xCFF1,
+ /* U+50D0 */ 0x8352, 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 0xD9D2, 0x8358,
+ /* U+50D8 */ 0x8359, 0x835A, 0xC1C5, 0x835B, 0x835C, 0x835D, 0x835E, 0x835F,
+ /* U+50E0 */ 0x8360, 0x8361, 0x8362, 0x8363, 0x8364, 0x8365, 0xD9D6, 0xC9AE,
+ /* U+50E8 */ 0x8366, 0x8367, 0x8368, 0x8369, 0xD9D5, 0xD9D4, 0xD9D7, 0x836A,
+ /* U+50F0 */ 0x836B, 0x836C, 0x836D, 0xCBDB, 0x836E, 0xBDA9, 0x836F, 0x8370,
+ /* U+50F8 */ 0x8371, 0x8372, 0x8373, 0xC6A7, 0x8374, 0x8375, 0x8376, 0x8377,
+ /* U+5100 */ 0x8378, 0x8379, 0x837A, 0x837B, 0x837C, 0x837D, 0xD9D3, 0xD9D8,
+ /* U+5108 */ 0x837E, 0x8380, 0x8381, 0xD9D9, 0x8382, 0x8383, 0x8384, 0x8385,
+ /* U+5110 */ 0x8386, 0x8387, 0xC8E5, 0x8388, 0x8389, 0x838A, 0x838B, 0x838C,
+ /* U+5118 */ 0x838D, 0x838E, 0x838F, 0x8390, 0x8391, 0x8392, 0x8393, 0x8394,
+ /* U+5120 */ 0x8395, 0xC0DC, 0x8396, 0x8397, 0x8398, 0x8399, 0x839A, 0x839B,
+ /* U+5128 */ 0x839C, 0x839D, 0x839E, 0x839F, 0x83A0, 0x83A1, 0x83A2, 0x83A3,
+ /* U+5130 */ 0x83A4, 0x83A5, 0x83A6, 0x83A7, 0x83A8, 0x83A9, 0x83AA, 0x83AB,
+ /* U+5138 */ 0x83AC, 0x83AD, 0x83AE, 0x83AF, 0x83B0, 0x83B1, 0x83B2, 0xB6F9,
+ /* U+5140 */ 0xD8A3, 0xD4CA, 0x83B3, 0xD4AA, 0xD0D6, 0xB3E4, 0xD5D7, 0x83B4,
+ /* U+5148 */ 0xCFC8, 0xB9E2, 0x83B5, 0xBFCB, 0x83B6, 0xC3E2, 0x83B7, 0x83B8,
+ /* U+5150 */ 0x83B9, 0xB6D2, 0x83BA, 0x83BB, 0xCDC3, 0xD9EE, 0xD9F0, 0x83BC,
+ /* U+5158 */ 0x83BD, 0x83BE, 0xB5B3, 0x83BF, 0xB6B5, 0x83C0, 0x83C1, 0x83C2,
+ /* U+5160 */ 0x83C3, 0x83C4, 0xBEA4, 0x83C5, 0x83C6, 0xC8EB, 0x83C7, 0x83C8,
+ /* U+5168 */ 0xC8AB, 0x83C9, 0x83CA, 0xB0CB, 0xB9AB, 0xC1F9, 0xD9E2, 0x83CB,
+ /* U+5170 */ 0xC0BC, 0xB9B2, 0x83CC, 0xB9D8, 0xD0CB, 0xB1F8, 0xC6E4, 0xBEDF,
+ /* U+5178 */ 0xB5E4, 0xD7C8, 0x83CD, 0xD1F8, 0xBCE6, 0xCADE, 0x83CE, 0x83CF,
+ /* U+5180 */ 0xBCBD, 0xD9E6, 0xD8E7, 0x83D0, 0x83D1, 0xC4DA, 0x83D2, 0x83D3,
+ /* U+5188 */ 0xB8D4, 0xC8BD, 0x83D4, 0x83D5, 0xB2E1, 0xD4D9, 0x83D6, 0x83D7,
+ /* U+5190 */ 0x83D8, 0x83D9, 0xC3B0, 0x83DA, 0x83DB, 0xC3E1, 0xDAA2, 0xC8DF,
+ /* U+5198 */ 0x83DC, 0xD0B4, 0x83DD, 0xBEFC, 0xC5A9, 0x83DE, 0x83DF, 0x83E0,
+ /* U+51A0 */ 0xB9DA, 0x83E1, 0xDAA3, 0x83E2, 0xD4A9, 0xDAA4, 0x83E3, 0x83E4,
+ /* U+51A8 */ 0x83E5, 0x83E6, 0x83E7, 0xD9FB, 0xB6AC, 0x83E8, 0x83E9, 0xB7EB,
+ /* U+51B0 */ 0xB1F9, 0xD9FC, 0xB3E5, 0xBEF6, 0x83EA, 0xBFF6, 0xD2B1, 0xC0E4,
+ /* U+51B8 */ 0x83EB, 0x83EC, 0x83ED, 0xB6B3, 0xD9FE, 0xD9FD, 0x83EE, 0x83EF,
+ /* U+51C0 */ 0xBEBB, 0x83F0, 0x83F1, 0x83F2, 0xC6E0, 0x83F3, 0xD7BC, 0xDAA1,
+ /* U+51C8 */ 0x83F4, 0xC1B9, 0x83F5, 0xB5F2, 0xC1E8, 0x83F6, 0x83F7, 0xBCF5,
+ /* U+51D0 */ 0x83F8, 0xB4D5, 0x83F9, 0x83FA, 0x83FB, 0x83FC, 0x83FD, 0x83FE,
+ /* U+51D8 */ 0x8440, 0x8441, 0x8442, 0xC1DD, 0x8443, 0xC4FD, 0x8444, 0x8445,
+ /* U+51E0 */ 0xBCB8, 0xB7B2, 0x8446, 0x8447, 0xB7EF, 0x8448, 0x8449, 0x844A,
+ /* U+51E8 */ 0x844B, 0x844C, 0x844D, 0xD9EC, 0x844E, 0xC6BE, 0x844F, 0xBFAD,
+ /* U+51F0 */ 0xBBCB, 0x8450, 0x8451, 0xB5CA, 0x8452, 0xDBC9, 0xD0D7, 0x8453,
+ /* U+51F8 */ 0xCDB9, 0xB0BC, 0xB3F6, 0xBBF7, 0xDBCA, 0xBAAF, 0x8454, 0xD4E4,
+ /* U+5200 */ 0xB5B6, 0xB5F3, 0xD8D6, 0xC8D0, 0x8455, 0x8456, 0xB7D6, 0xC7D0,
+ /* U+5208 */ 0xD8D7, 0x8457, 0xBFAF, 0x8458, 0x8459, 0xDBBB, 0xD8D8, 0x845A,
+ /* U+5210 */ 0x845B, 0xD0CC, 0xBBAE, 0x845C, 0x845D, 0x845E, 0xEBBE, 0xC1D0,
+ /* U+5218 */ 0xC1F5, 0xD4F2, 0xB8D5, 0xB4B4, 0x845F, 0xB3F5, 0x8460, 0x8461,
+ /* U+5220 */ 0xC9BE, 0x8462, 0x8463, 0x8464, 0xC5D0, 0x8465, 0x8466, 0x8467,
+ /* U+5228 */ 0xC5D9, 0xC0FB, 0x8468, 0xB1F0, 0x8469, 0xD8D9, 0xB9CE, 0x846A,
+ /* U+5230 */ 0xB5BD, 0x846B, 0x846C, 0xD8DA, 0x846D, 0x846E, 0xD6C6, 0xCBA2,
+ /* U+5238 */ 0xC8AF, 0xC9B2, 0xB4CC, 0xBFCC, 0x846F, 0xB9F4, 0x8470, 0xD8DB,
+ /* U+5240 */ 0xD8DC, 0xB6E7, 0xBCC1, 0xCCEA, 0x8471, 0x8472, 0x8473, 0x8474,
+ /* U+5248 */ 0x8475, 0x8476, 0xCFF7, 0x8477, 0xD8DD, 0xC7B0, 0x8478, 0x8479,
+ /* U+5250 */ 0xB9D0, 0xBDA3, 0x847A, 0x847B, 0xCCDE, 0x847C, 0xC6CA, 0x847D,
+ /* U+5258 */ 0x847E, 0x8480, 0x8481, 0x8482, 0xD8E0, 0x8483, 0xD8DE, 0x8484,
+ /* U+5260 */ 0x8485, 0xD8DF, 0x8486, 0x8487, 0x8488, 0xB0FE, 0x8489, 0xBEE7,
+ /* U+5268 */ 0x848A, 0xCAA3, 0xBCF4, 0x848B, 0x848C, 0x848D, 0x848E, 0xB8B1,
+ /* U+5270 */ 0x848F, 0x8490, 0xB8EE, 0x8491, 0x8492, 0x8493, 0x8494, 0x8495,
+ /* U+5278 */ 0x8496, 0x8497, 0x8498, 0x8499, 0x849A, 0xD8E2, 0x849B, 0xBDCB,
+ /* U+5280 */ 0x849C, 0xD8E4, 0xD8E3, 0x849D, 0x849E, 0x849F, 0x84A0, 0x84A1,
+ /* U+5288 */ 0xC5FC, 0x84A2, 0x84A3, 0x84A4, 0x84A5, 0x84A6, 0x84A7, 0x84A8,
+ /* U+5290 */ 0xD8E5, 0x84A9, 0x84AA, 0xD8E6, 0x84AB, 0x84AC, 0x84AD, 0x84AE,
+ /* U+5298 */ 0x84AF, 0x84B0, 0x84B1, 0xC1A6, 0x84B2, 0xC8B0, 0xB0EC, 0xB9A6,
+ /* U+52A0 */ 0xBCD3, 0xCEF1, 0xDBBD, 0xC1D3, 0x84B3, 0x84B4, 0x84B5, 0x84B6,
+ /* U+52A8 */ 0xB6AF, 0xD6FA, 0xC5AC, 0xBDD9, 0xDBBE, 0xDBBF, 0x84B7, 0x84B8,
+ /* U+52B0 */ 0x84B9, 0xC0F8, 0xBEA2, 0xC0CD, 0x84BA, 0x84BB, 0x84BC, 0x84BD,
+ /* U+52B8 */ 0x84BE, 0x84BF, 0x84C0, 0x84C1, 0x84C2, 0x84C3, 0xDBC0, 0xCAC6,
+ /* U+52C0 */ 0x84C4, 0x84C5, 0x84C6, 0xB2AA, 0x84C7, 0x84C8, 0x84C9, 0xD3C2,
+ /* U+52C8 */ 0x84CA, 0xC3E3, 0x84CB, 0xD1AB, 0x84CC, 0x84CD, 0x84CE, 0x84CF,
+ /* U+52D0 */ 0xDBC2, 0x84D0, 0xC0D5, 0x84D1, 0x84D2, 0x84D3, 0xDBC3, 0x84D4,
+ /* U+52D8 */ 0xBFB1, 0x84D5, 0x84D6, 0x84D7, 0x84D8, 0x84D9, 0x84DA, 0xC4BC,
+ /* U+52E0 */ 0x84DB, 0x84DC, 0x84DD, 0x84DE, 0xC7DA, 0x84DF, 0x84E0, 0x84E1,
+ /* U+52E8 */ 0x84E2, 0x84E3, 0x84E4, 0x84E5, 0x84E6, 0x84E7, 0x84E8, 0x84E9,
+ /* U+52F0 */ 0xDBC4, 0x84EA, 0x84EB, 0x84EC, 0x84ED, 0x84EE, 0x84EF, 0x84F0,
+ /* U+52F8 */ 0x84F1, 0xD9E8, 0xC9D7, 0x84F2, 0x84F3, 0x84F4, 0xB9B4, 0xCEF0,
+ /* U+5300 */ 0xD4C8, 0x84F5, 0x84F6, 0x84F7, 0x84F8, 0xB0FC, 0xB4D2, 0x84F9,
+ /* U+5308 */ 0xD0D9, 0x84FA, 0x84FB, 0x84FC, 0x84FD, 0xD9E9, 0x84FE, 0xDECB,
+ /* U+5310 */ 0xD9EB, 0x8540, 0x8541, 0x8542, 0x8543, 0xD8B0, 0xBBAF, 0xB1B1,
+ /* U+5318 */ 0x8544, 0xB3D7, 0xD8CE, 0x8545, 0x8546, 0xD4D1, 0x8547, 0x8548,
+ /* U+5320 */ 0xBDB3, 0xBFEF, 0x8549, 0xCFBB, 0x854A, 0x854B, 0xD8D0, 0x854C,
+ /* U+5328 */ 0x854D, 0x854E, 0xB7CB, 0x854F, 0x8550, 0x8551, 0xD8D1, 0x8552,
+ /* U+5330 */ 0x8553, 0x8554, 0x8555, 0x8556, 0x8557, 0x8558, 0x8559, 0x855A,
+ /* U+5338 */ 0x855B, 0xC6A5, 0xC7F8, 0xD2BD, 0x855C, 0x855D, 0xD8D2, 0xC4E4,
+ /* U+5340 */ 0x855E, 0xCAAE, 0x855F, 0xC7A7, 0x8560, 0xD8A6, 0x8561, 0xC9FD,
+ /* U+5348 */ 0xCEE7, 0xBBDC, 0xB0EB, 0x8562, 0x8563, 0x8564, 0xBBAA, 0xD0AD,
+ /* U+5350 */ 0x8565, 0xB1B0, 0xD7E4, 0xD7BF, 0x8566, 0xB5A5, 0xC2F4, 0xC4CF,
+ /* U+5358 */ 0x8567, 0x8568, 0xB2A9, 0x8569, 0xB2B7, 0x856A, 0xB1E5, 0xDFB2,
+ /* U+5360 */ 0xD5BC, 0xBFA8, 0xC2AC, 0xD8D5, 0xC2B1, 0x856B, 0xD8D4, 0xCED4,
+ /* U+5368 */ 0x856C, 0xDAE0, 0x856D, 0xCEC0, 0x856E, 0x856F, 0xD8B4, 0xC3AE,
+ /* U+5370 */ 0xD3A1, 0xCEA3, 0x8570, 0xBCB4, 0xC8B4, 0xC2D1, 0x8571, 0xBEED,
+ /* U+5378 */ 0xD0B6, 0x8572, 0xDAE1, 0x8573, 0x8574, 0x8575, 0x8576, 0xC7E4,
+ /* U+5380 */ 0x8577, 0x8578, 0xB3A7, 0x8579, 0xB6F2, 0xCCFC, 0xC0FA, 0x857A,
+ /* U+5388 */ 0x857B, 0xC0F7, 0x857C, 0xD1B9, 0xD1E1, 0xD8C7, 0x857D, 0x857E,
+ /* U+5390 */ 0x8580, 0x8581, 0x8582, 0x8583, 0x8584, 0xB2DE, 0x8585, 0x8586,
+ /* U+5398 */ 0xC0E5, 0x8587, 0xBAF1, 0x8588, 0x8589, 0xD8C8, 0x858A, 0xD4AD,
+ /* U+53A0 */ 0x858B, 0x858C, 0xCFE1, 0xD8C9, 0x858D, 0xD8CA, 0xCFC3, 0x858E,
+ /* U+53A8 */ 0xB3F8, 0xBEC7, 0x858F, 0x8590, 0x8591, 0x8592, 0xD8CB, 0x8593,
+ /* U+53B0 */ 0x8594, 0x8595, 0x8596, 0x8597, 0x8598, 0x8599, 0xDBCC, 0x859A,
+ /* U+53B8 */ 0x859B, 0x859C, 0x859D, 0xC8A5, 0x859E, 0x859F, 0x85A0, 0xCFD8,
+ /* U+53C0 */ 0x85A1, 0xC8FE, 0xB2CE, 0x85A2, 0x85A3, 0x85A4, 0x85A5, 0x85A6,
+ /* U+53C8 */ 0xD3D6, 0xB2E6, 0xBCB0, 0xD3D1, 0xCBAB, 0xB7B4, 0x85A7, 0x85A8,
+ /* U+53D0 */ 0x85A9, 0xB7A2, 0x85AA, 0x85AB, 0xCAE5, 0x85AC, 0xC8A1, 0xCADC,
+ /* U+53D8 */ 0xB1E4, 0xD0F0, 0x85AD, 0xC5D1, 0x85AE, 0x85AF, 0x85B0, 0xDBC5,
+ /* U+53E0 */ 0xB5FE, 0x85B1, 0x85B2, 0xBFDA, 0xB9C5, 0xBEE4, 0xC1ED, 0x85B3,
+ /* U+53E8 */ 0xDFB6, 0xDFB5, 0xD6BB, 0xBDD0, 0xD5D9, 0xB0C8, 0xB6A3, 0xBFC9,
+ /* U+53F0 */ 0xCCA8, 0xDFB3, 0xCAB7, 0xD3D2, 0x85B4, 0xD8CF, 0xD2B6, 0xBAC5,
+ /* U+53F8 */ 0xCBBE, 0xCCBE, 0x85B5, 0xDFB7, 0xB5F0, 0xDFB4, 0x85B6, 0x85B7,
+ /* U+5400 */ 0x85B8, 0xD3F5, 0x85B9, 0xB3D4, 0xB8F7, 0x85BA, 0xDFBA, 0x85BB,
+ /* U+5408 */ 0xBACF, 0xBCAA, 0xB5F5, 0x85BC, 0xCDAC, 0xC3FB, 0xBAF3, 0xC0F4,
+ /* U+5410 */ 0xCDC2, 0xCFF2, 0xDFB8, 0xCFC5, 0x85BD, 0xC2C0, 0xDFB9, 0xC2F0,
+ /* U+5418 */ 0x85BE, 0x85BF, 0x85C0, 0xBEFD, 0x85C1, 0xC1DF, 0xCDCC, 0xD2F7,
+ /* U+5420 */ 0xB7CD, 0xDFC1, 0x85C2, 0xDFC4, 0x85C3, 0x85C4, 0xB7F1, 0xB0C9,
+ /* U+5428 */ 0xB6D6, 0xB7D4, 0x85C5, 0xBAAC, 0xCCFD, 0xBFD4, 0xCBB1, 0xC6F4,
+ /* U+5430 */ 0x85C6, 0xD6A8, 0xDFC5, 0x85C7, 0xCEE2, 0xB3B3, 0x85C8, 0x85C9,
+ /* U+5438 */ 0xCEFC, 0xB4B5, 0x85CA, 0xCEC7, 0xBAF0, 0x85CB, 0xCEE1, 0x85CC,
+ /* U+5440 */ 0xD1BD, 0x85CD, 0x85CE, 0xDFC0, 0x85CF, 0x85D0, 0xB4F4, 0x85D1,
+ /* U+5448 */ 0xB3CA, 0x85D2, 0xB8E6, 0xDFBB, 0x85D3, 0x85D4, 0x85D5, 0x85D6,
+ /* U+5450 */ 0xC4C5, 0x85D7, 0xDFBC, 0xDFBD, 0xDFBE, 0xC5BB, 0xDFBF, 0xDFC2,
+ /* U+5458 */ 0xD4B1, 0xDFC3, 0x85D8, 0xC7BA, 0xCED8, 0x85D9, 0x85DA, 0x85DB,
+ /* U+5460 */ 0x85DC, 0x85DD, 0xC4D8, 0x85DE, 0xDFCA, 0x85DF, 0xDFCF, 0x85E0,
+ /* U+5468 */ 0xD6DC, 0x85E1, 0x85E2, 0x85E3, 0x85E4, 0x85E5, 0x85E6, 0x85E7,
+ /* U+5470 */ 0x85E8, 0xDFC9, 0xDFDA, 0xCEB6, 0x85E9, 0xBAC7, 0xDFCE, 0xDFC8,
+ /* U+5478 */ 0xC5DE, 0x85EA, 0x85EB, 0xC9EB, 0xBAF4, 0xC3FC, 0x85EC, 0x85ED,
+ /* U+5480 */ 0xBED7, 0x85EE, 0xDFC6, 0x85EF, 0xDFCD, 0x85F0, 0xC5D8, 0x85F1,
+ /* U+5488 */ 0x85F2, 0x85F3, 0x85F4, 0xD5A6, 0xBACD, 0x85F5, 0xBECC, 0xD3BD,
+ /* U+5490 */ 0xB8C0, 0x85F6, 0xD6E4, 0x85F7, 0xDFC7, 0xB9BE, 0xBFA7, 0x85F8,
+ /* U+5498 */ 0x85F9, 0xC1FC, 0xDFCB, 0xDFCC, 0x85FA, 0xDFD0, 0x85FB, 0x85FC,
+ /* U+54A0 */ 0x85FD, 0x85FE, 0x8640, 0xDFDB, 0xDFE5, 0x8641, 0xDFD7, 0xDFD6,
+ /* U+54A8 */ 0xD7C9, 0xDFE3, 0xDFE4, 0xE5EB, 0xD2A7, 0xDFD2, 0x8642, 0xBFA9,
+ /* U+54B0 */ 0x8643, 0xD4DB, 0x8644, 0xBFC8, 0xDFD4, 0x8645, 0x8646, 0x8647,
+ /* U+54B8 */ 0xCFCC, 0x8648, 0x8649, 0xDFDD, 0x864A, 0xD1CA, 0x864B, 0xDFDE,
+ /* U+54C0 */ 0xB0A7, 0xC6B7, 0xDFD3, 0x864C, 0xBAE5, 0x864D, 0xB6DF, 0xCDDB,
+ /* U+54C8 */ 0xB9FE, 0xD4D5, 0x864E, 0x864F, 0xDFDF, 0xCFEC, 0xB0A5, 0xDFE7,
+ /* U+54D0 */ 0xDFD1, 0xD1C6, 0xDFD5, 0xDFD8, 0xDFD9, 0xDFDC, 0x8650, 0xBBA9,
+ /* U+54D8 */ 0x8651, 0xDFE0, 0xDFE1, 0x8652, 0xDFE2, 0xDFE6, 0xDFE8, 0xD3B4,
+ /* U+54E0 */ 0x8653, 0x8654, 0x8655, 0x8656, 0x8657, 0xB8E7, 0xC5B6, 0xDFEA,
+ /* U+54E8 */ 0xC9DA, 0xC1A8, 0xC4C4, 0x8658, 0x8659, 0xBFDE, 0xCFF8, 0x865A,
+ /* U+54F0 */ 0x865B, 0x865C, 0xD5DC, 0xDFEE, 0x865D, 0x865E, 0x865F, 0x8660,
+ /* U+54F8 */ 0x8661, 0x8662, 0xB2B8, 0x8663, 0xBADF, 0xDFEC, 0x8664, 0xDBC1,
+ /* U+5500 */ 0x8665, 0xD1E4, 0x8666, 0x8667, 0x8668, 0x8669, 0xCBF4, 0xB4BD,
+ /* U+5508 */ 0x866A, 0xB0A6, 0x866B, 0x866C, 0x866D, 0x866E, 0x866F, 0xDFF1,
+ /* U+5510 */ 0xCCC6, 0xDFF2, 0x8670, 0x8671, 0xDFED, 0x8672, 0x8673, 0x8674,
+ /* U+5518 */ 0x8675, 0x8676, 0x8677, 0xDFE9, 0x8678, 0x8679, 0x867A, 0x867B,
+ /* U+5520 */ 0xDFEB, 0x867C, 0xDFEF, 0xDFF0, 0xBBBD, 0x867D, 0x867E, 0xDFF3,
+ /* U+5528 */ 0x8680, 0x8681, 0xDFF4, 0x8682, 0xBBA3, 0x8683, 0xCADB, 0xCEA8,
+ /* U+5530 */ 0xE0A7, 0xB3AA, 0x8684, 0xE0A6, 0x8685, 0x8686, 0x8687, 0xE0A1,
+ /* U+5538 */ 0x8688, 0x8689, 0x868A, 0x868B, 0xDFFE, 0x868C, 0xCDD9, 0xDFFC,
+ /* U+5540 */ 0x868D, 0xDFFA, 0x868E, 0xBFD0, 0xD7C4, 0x868F, 0xC9CC, 0x8690,
+ /* U+5548 */ 0x8691, 0xDFF8, 0xB0A1, 0x8692, 0x8693, 0x8694, 0x8695, 0x8696,
+ /* U+5550 */ 0xDFFD, 0x8697, 0x8698, 0x8699, 0x869A, 0xDFFB, 0xE0A2, 0x869B,
+ /* U+5558 */ 0x869C, 0x869D, 0x869E, 0x869F, 0xE0A8, 0x86A0, 0x86A1, 0x86A2,
+ /* U+5560 */ 0x86A3, 0xB7C8, 0x86A4, 0x86A5, 0xC6A1, 0xC9B6, 0xC0B2, 0xDFF5,
+ /* U+5568 */ 0x86A6, 0x86A7, 0xC5BE, 0x86A8, 0xD8C4, 0xDFF9, 0xC4F6, 0x86A9,
+ /* U+5570 */ 0x86AA, 0x86AB, 0x86AC, 0x86AD, 0x86AE, 0xE0A3, 0xE0A4, 0xE0A5,
+ /* U+5578 */ 0xD0A5, 0x86AF, 0x86B0, 0xE0B4, 0xCCE4, 0x86B1, 0xE0B1, 0x86B2,
+ /* U+5580 */ 0xBFA6, 0xE0AF, 0xCEB9, 0xE0AB, 0xC9C6, 0x86B3, 0x86B4, 0xC0AE,
+ /* U+5588 */ 0xE0AE, 0xBAED, 0xBAB0, 0xE0A9, 0x86B5, 0x86B6, 0x86B7, 0xDFF6,
+ /* U+5590 */ 0x86B8, 0xE0B3, 0x86B9, 0x86BA, 0xE0B8, 0x86BB, 0x86BC, 0x86BD,
+ /* U+5598 */ 0xB4AD, 0xE0B9, 0x86BE, 0x86BF, 0xCFB2, 0xBAC8, 0x86C0, 0xE0B0,
+ /* U+55A0 */ 0x86C1, 0x86C2, 0x86C3, 0x86C4, 0x86C5, 0x86C6, 0x86C7, 0xD0FA,
+ /* U+55A8 */ 0x86C8, 0x86C9, 0x86CA, 0x86CB, 0x86CC, 0x86CD, 0x86CE, 0x86CF,
+ /* U+55B0 */ 0x86D0, 0xE0AC, 0x86D1, 0xD4FB, 0x86D2, 0xDFF7, 0x86D3, 0xC5E7,
+ /* U+55B8 */ 0x86D4, 0xE0AD, 0x86D5, 0xD3F7, 0x86D6, 0xE0B6, 0xE0B7, 0x86D7,
+ /* U+55C0 */ 0x86D8, 0x86D9, 0x86DA, 0x86DB, 0xE0C4, 0xD0E1, 0x86DC, 0x86DD,
+ /* U+55C8 */ 0x86DE, 0xE0BC, 0x86DF, 0x86E0, 0xE0C9, 0xE0CA, 0x86E1, 0x86E2,
+ /* U+55D0 */ 0x86E3, 0xE0BE, 0xE0AA, 0xC9A4, 0xE0C1, 0x86E4, 0xE0B2, 0x86E5,
+ /* U+55D8 */ 0x86E6, 0x86E7, 0x86E8, 0x86E9, 0xCAC8, 0xE0C3, 0x86EA, 0xE0B5,
+ /* U+55E0 */ 0x86EB, 0xCECB, 0x86EC, 0xCBC3, 0xE0CD, 0xE0C6, 0xE0C2, 0x86ED,
+ /* U+55E8 */ 0xE0CB, 0x86EE, 0xE0BA, 0xE0BF, 0xE0C0, 0x86EF, 0x86F0, 0xE0C5,
+ /* U+55F0 */ 0x86F1, 0x86F2, 0xE0C7, 0xE0C8, 0x86F3, 0xE0CC, 0x86F4, 0xE0BB,
+ /* U+55F8 */ 0x86F5, 0x86F6, 0x86F7, 0x86F8, 0x86F9, 0xCBD4, 0xE0D5, 0x86FA,
+ /* U+5600 */ 0xE0D6, 0xE0D2, 0x86FB, 0x86FC, 0x86FD, 0x86FE, 0x8740, 0x8741,
+ /* U+5608 */ 0xE0D0, 0xBCCE, 0x8742, 0x8743, 0xE0D1, 0x8744, 0xB8C2, 0xD8C5,
+ /* U+5610 */ 0x8745, 0x8746, 0x8747, 0x8748, 0x8749, 0x874A, 0x874B, 0x874C,
+ /* U+5618 */ 0xD0EA, 0x874D, 0x874E, 0xC2EF, 0x874F, 0x8750, 0xE0CF, 0xE0BD,
+ /* U+5620 */ 0x8751, 0x8752, 0x8753, 0xE0D4, 0xE0D3, 0x8754, 0x8755, 0xE0D7,
+ /* U+5628 */ 0x8756, 0x8757, 0x8758, 0x8759, 0xE0DC, 0xE0D8, 0x875A, 0x875B,
+ /* U+5630 */ 0x875C, 0xD6F6, 0xB3B0, 0x875D, 0xD7EC, 0x875E, 0xCBBB, 0x875F,
+ /* U+5638 */ 0x8760, 0xE0DA, 0x8761, 0xCEFB, 0x8762, 0x8763, 0x8764, 0xBAD9,
+ /* U+5640 */ 0x8765, 0x8766, 0x8767, 0x8768, 0x8769, 0x876A, 0x876B, 0x876C,
+ /* U+5648 */ 0x876D, 0x876E, 0x876F, 0x8770, 0xE0E1, 0xE0DD, 0xD2AD, 0x8771,
+ /* U+5650 */ 0x8772, 0x8773, 0x8774, 0x8775, 0xE0E2, 0x8776, 0x8777, 0xE0DB,
+ /* U+5658 */ 0xE0D9, 0xE0DF, 0x8778, 0x8779, 0xE0E0, 0x877A, 0x877B, 0x877C,
+ /* U+5660 */ 0x877D, 0x877E, 0xE0DE, 0x8780, 0xE0E4, 0x8781, 0x8782, 0x8783,
+ /* U+5668 */ 0xC6F7, 0xD8AC, 0xD4EB, 0xE0E6, 0xCAC9, 0x8784, 0x8785, 0x8786,
+ /* U+5670 */ 0x8787, 0xE0E5, 0x8788, 0x8789, 0x878A, 0x878B, 0xB8C1, 0x878C,
+ /* U+5678 */ 0x878D, 0x878E, 0x878F, 0xE0E7, 0xE0E8, 0x8790, 0x8791, 0x8792,
+ /* U+5680 */ 0x8793, 0x8794, 0x8795, 0x8796, 0x8797, 0xE0E9, 0xE0E3, 0x8798,
+ /* U+5688 */ 0x8799, 0x879A, 0x879B, 0x879C, 0x879D, 0x879E, 0xBABF, 0xCCE7,
+ /* U+5690 */ 0x879F, 0x87A0, 0x87A1, 0xE0EA, 0x87A2, 0x87A3, 0x87A4, 0x87A5,
+ /* U+5698 */ 0x87A6, 0x87A7, 0x87A8, 0x87A9, 0x87AA, 0x87AB, 0x87AC, 0x87AD,
+ /* U+56A0 */ 0x87AE, 0x87AF, 0x87B0, 0xCFF9, 0x87B1, 0x87B2, 0x87B3, 0x87B4,
+ /* U+56A8 */ 0x87B5, 0x87B6, 0x87B7, 0x87B8, 0x87B9, 0x87BA, 0x87BB, 0xE0EB,
+ /* U+56B0 */ 0x87BC, 0x87BD, 0x87BE, 0x87BF, 0x87C0, 0x87C1, 0x87C2, 0xC8C2,
+ /* U+56B8 */ 0x87C3, 0x87C4, 0x87C5, 0x87C6, 0xBDC0, 0x87C7, 0x87C8, 0x87C9,
+ /* U+56C0 */ 0x87CA, 0x87CB, 0x87CC, 0x87CD, 0x87CE, 0x87CF, 0x87D0, 0x87D1,
+ /* U+56C8 */ 0x87D2, 0x87D3, 0xC4D2, 0x87D4, 0x87D5, 0x87D6, 0x87D7, 0x87D8,
+ /* U+56D0 */ 0x87D9, 0x87DA, 0x87DB, 0x87DC, 0xE0EC, 0x87DD, 0x87DE, 0xE0ED,
+ /* U+56D8 */ 0x87DF, 0x87E0, 0xC7F4, 0xCBC4, 0x87E1, 0xE0EE, 0xBBD8, 0xD8B6,
+ /* U+56E0 */ 0xD2F2, 0xE0EF, 0xCDC5, 0x87E2, 0xB6DA, 0x87E3, 0x87E4, 0x87E5,
+ /* U+56E8 */ 0x87E6, 0x87E7, 0x87E8, 0xE0F1, 0x87E9, 0xD4B0, 0x87EA, 0x87EB,
+ /* U+56F0 */ 0xC0A7, 0xB4D1, 0x87EC, 0x87ED, 0xCEA7, 0xE0F0, 0x87EE, 0x87EF,
+ /* U+56F8 */ 0x87F0, 0xE0F2, 0xB9CC, 0x87F1, 0x87F2, 0xB9FA, 0xCDBC, 0xE0F3,
+ /* U+5700 */ 0x87F3, 0x87F4, 0x87F5, 0xC6D4, 0xE0F4, 0x87F6, 0xD4B2, 0x87F7,
+ /* U+5708 */ 0xC8A6, 0xE0F6, 0xE0F5, 0x87F8, 0x87F9, 0x87FA, 0x87FB, 0x87FC,
+ /* U+5710 */ 0x87FD, 0x87FE, 0x8840, 0x8841, 0x8842, 0x8843, 0x8844, 0x8845,
+ /* U+5718 */ 0x8846, 0x8847, 0x8848, 0x8849, 0xE0F7, 0x884A, 0x884B, 0xCDC1,
+ /* U+5720 */ 0x884C, 0x884D, 0x884E, 0xCAA5, 0x884F, 0x8850, 0x8851, 0x8852,
+ /* U+5728 */ 0xD4DA, 0xDBD7, 0xDBD9, 0x8853, 0xDBD8, 0xB9E7, 0xDBDC, 0xDBDD,
+ /* U+5730 */ 0xB5D8, 0x8854, 0x8855, 0xDBDA, 0x8856, 0x8857, 0x8858, 0x8859,
+ /* U+5738 */ 0x885A, 0xDBDB, 0xB3A1, 0xDBDF, 0x885B, 0x885C, 0xBBF8, 0x885D,
+ /* U+5740 */ 0xD6B7, 0x885E, 0xDBE0, 0x885F, 0x8860, 0x8861, 0x8862, 0xBEF9,
+ /* U+5748 */ 0x8863, 0x8864, 0xB7BB, 0x8865, 0xDBD0, 0xCCAE, 0xBFB2, 0xBBB5,
+ /* U+5750 */ 0xD7F8, 0xBFD3, 0x8866, 0x8867, 0x8868, 0x8869, 0x886A, 0xBFE9,
+ /* U+5758 */ 0x886B, 0x886C, 0xBCE1, 0xCCB3, 0xDBDE, 0xB0D3, 0xCEEB, 0xB7D8,
+ /* U+5760 */ 0xD7B9, 0xC6C2, 0x886D, 0x886E, 0xC0A4, 0x886F, 0xCCB9, 0x8870,
+ /* U+5768 */ 0xDBE7, 0xDBE1, 0xC6BA, 0xDBE3, 0x8871, 0xDBE8, 0x8872, 0xC5F7,
+ /* U+5770 */ 0x8873, 0x8874, 0x8875, 0xDBEA, 0x8876, 0x8877, 0xDBE9, 0xBFC0,
+ /* U+5778 */ 0x8878, 0x8879, 0x887A, 0xDBE6, 0xDBE5, 0x887B, 0x887C, 0x887D,
+ /* U+5780 */ 0x887E, 0x8880, 0xB4B9, 0xC0AC, 0xC2A2, 0xDBE2, 0xDBE4, 0x8881,
+ /* U+5788 */ 0x8882, 0x8883, 0x8884, 0xD0CD, 0xDBED, 0x8885, 0x8886, 0x8887,
+ /* U+5790 */ 0x8888, 0x8889, 0xC0DD, 0xDBF2, 0x888A, 0x888B, 0x888C, 0x888D,
+ /* U+5798 */ 0x888E, 0x888F, 0x8890, 0xB6E2, 0x8891, 0x8892, 0x8893, 0x8894,
+ /* U+57A0 */ 0xDBF3, 0xDBD2, 0xB9B8, 0xD4AB, 0xDBEC, 0x8895, 0xBFD1, 0xDBF0,
+ /* U+57A8 */ 0x8896, 0xDBD1, 0x8897, 0xB5E6, 0x8898, 0xDBEB, 0xBFE5, 0x8899,
+ /* U+57B0 */ 0x889A, 0x889B, 0xDBEE, 0x889C, 0xDBF1, 0x889D, 0x889E, 0x889F,
+ /* U+57B8 */ 0xDBF9, 0x88A0, 0x88A1, 0x88A2, 0x88A3, 0x88A4, 0x88A5, 0x88A6,
+ /* U+57C0 */ 0x88A7, 0x88A8, 0xB9A1, 0xB0A3, 0x88A9, 0x88AA, 0x88AB, 0x88AC,
+ /* U+57C8 */ 0x88AD, 0x88AE, 0x88AF, 0xC2F1, 0x88B0, 0x88B1, 0xB3C7, 0xDBEF,
+ /* U+57D0 */ 0x88B2, 0x88B3, 0xDBF8, 0x88B4, 0xC6D2, 0xDBF4, 0x88B5, 0x88B6,
+ /* U+57D8 */ 0xDBF5, 0xDBF7, 0xDBF6, 0x88B7, 0x88B8, 0xDBFE, 0x88B9, 0xD3F2,
+ /* U+57E0 */ 0xB2BA, 0x88BA, 0x88BB, 0x88BC, 0xDBFD, 0x88BD, 0x88BE, 0x88BF,
+ /* U+57E8 */ 0x88C0, 0x88C1, 0x88C2, 0x88C3, 0x88C4, 0xDCA4, 0x88C5, 0xDBFB,
+ /* U+57F0 */ 0x88C6, 0x88C7, 0x88C8, 0x88C9, 0xDBFA, 0x88CA, 0x88CB, 0x88CC,
+ /* U+57F8 */ 0xDBFC, 0xC5E0, 0xBBF9, 0x88CD, 0x88CE, 0xDCA3, 0x88CF, 0x88D0,
+ /* U+5800 */ 0xDCA5, 0x88D1, 0xCCC3, 0x88D2, 0x88D3, 0x88D4, 0xB6D1, 0xDDC0,
+ /* U+5808 */ 0x88D5, 0x88D6, 0x88D7, 0xDCA1, 0x88D8, 0xDCA2, 0x88D9, 0x88DA,
+ /* U+5810 */ 0x88DB, 0xC7B5, 0x88DC, 0x88DD, 0x88DE, 0xB6E9, 0x88DF, 0x88E0,
+ /* U+5818 */ 0x88E1, 0xDCA7, 0x88E2, 0x88E3, 0x88E4, 0x88E5, 0xDCA6, 0x88E6,
+ /* U+5820 */ 0xDCA9, 0xB1A4, 0x88E7, 0x88E8, 0xB5CC, 0x88E9, 0x88EA, 0x88EB,
+ /* U+5828 */ 0x88EC, 0x88ED, 0xBFB0, 0x88EE, 0x88EF, 0x88F0, 0x88F1, 0x88F2,
+ /* U+5830 */ 0xD1DF, 0x88F3, 0x88F4, 0x88F5, 0x88F6, 0xB6C2, 0x88F7, 0x88F8,
+ /* U+5838 */ 0x88F9, 0x88FA, 0x88FB, 0x88FC, 0x88FD, 0x88FE, 0x8940, 0x8941,
+ /* U+5840 */ 0x8942, 0x8943, 0x8944, 0x8945, 0xDCA8, 0x8946, 0x8947, 0x8948,
+ /* U+5848 */ 0x8949, 0x894A, 0x894B, 0x894C, 0xCBFA, 0xEBF3, 0x894D, 0x894E,
+ /* U+5850 */ 0x894F, 0xCBDC, 0x8950, 0x8951, 0xCBFE, 0x8952, 0x8953, 0x8954,
+ /* U+5858 */ 0xCCC1, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959, 0xC8FB, 0x895A,
+ /* U+5860 */ 0x895B, 0x895C, 0x895D, 0x895E, 0x895F, 0xDCAA, 0x8960, 0x8961,
+ /* U+5868 */ 0x8962, 0x8963, 0x8964, 0xCCEE, 0xDCAB, 0x8965, 0x8966, 0x8967,
+ /* U+5870 */ 0x8968, 0x8969, 0x896A, 0x896B, 0x896C, 0x896D, 0x896E, 0x896F,
+ /* U+5878 */ 0x8970, 0x8971, 0x8972, 0x8973, 0x8974, 0x8975, 0xDBD3, 0x8976,
+ /* U+5880 */ 0xDCAF, 0xDCAC, 0x8977, 0xBEB3, 0x8978, 0xCAFB, 0x8979, 0x897A,
+ /* U+5888 */ 0x897B, 0xDCAD, 0x897C, 0x897D, 0x897E, 0x8980, 0x8981, 0x8982,
+ /* U+5890 */ 0x8983, 0x8984, 0xC9CA, 0xC4B9, 0x8985, 0x8986, 0x8987, 0x8988,
+ /* U+5898 */ 0x8989, 0xC7BD, 0xDCAE, 0x898A, 0x898B, 0x898C, 0xD4F6, 0xD0E6,
+ /* U+58A0 */ 0x898D, 0x898E, 0x898F, 0x8990, 0x8991, 0x8992, 0x8993, 0x8994,
+ /* U+58A8 */ 0xC4AB, 0xB6D5, 0x8995, 0x8996, 0x8997, 0x8998, 0x8999, 0x899A,
+ /* U+58B0 */ 0x899B, 0x899C, 0x899D, 0x899E, 0x899F, 0x89A0, 0x89A1, 0x89A2,
+ /* U+58B8 */ 0x89A3, 0x89A4, 0x89A5, 0x89A6, 0xDBD4, 0x89A7, 0x89A8, 0x89A9,
+ /* U+58C0 */ 0x89AA, 0xB1DA, 0x89AB, 0x89AC, 0x89AD, 0xDBD5, 0x89AE, 0x89AF,
+ /* U+58C8 */ 0x89B0, 0x89B1, 0x89B2, 0x89B3, 0x89B4, 0x89B5, 0x89B6, 0x89B7,
+ /* U+58D0 */ 0x89B8, 0xDBD6, 0x89B9, 0x89BA, 0x89BB, 0xBABE, 0x89BC, 0x89BD,
+ /* U+58D8 */ 0x89BE, 0x89BF, 0x89C0, 0x89C1, 0x89C2, 0x89C3, 0x89C4, 0x89C5,
+ /* U+58E0 */ 0x89C6, 0x89C7, 0x89C8, 0x89C9, 0xC8C0, 0x89CA, 0x89CB, 0x89CC,
+ /* U+58E8 */ 0x89CD, 0x89CE, 0x89CF, 0xCABF, 0xC8C9, 0x89D0, 0xD7B3, 0x89D1,
+ /* U+58F0 */ 0xC9F9, 0x89D2, 0x89D3, 0xBFC7, 0x89D4, 0x89D5, 0xBAF8, 0x89D6,
+ /* U+58F8 */ 0x89D7, 0xD2BC, 0x89D8, 0x89D9, 0x89DA, 0x89DB, 0x89DC, 0x89DD,
+ /* U+5900 */ 0x89DE, 0x89DF, 0xE2BA, 0x89E0, 0xB4A6, 0x89E1, 0x89E2, 0xB1B8,
+ /* U+5908 */ 0x89E3, 0x89E4, 0x89E5, 0x89E6, 0x89E7, 0xB8B4, 0x89E8, 0xCFC4,
+ /* U+5910 */ 0x89E9, 0x89EA, 0x89EB, 0x89EC, 0xD9E7, 0xCFA6, 0xCDE2, 0x89ED,
+ /* U+5918 */ 0x89EE, 0xD9ED, 0xB6E0, 0x89EF, 0xD2B9, 0x89F0, 0x89F1, 0xB9BB,
+ /* U+5920 */ 0x89F2, 0x89F3, 0x89F4, 0x89F5, 0xE2B9, 0xE2B7, 0x89F6, 0xB4F3,
+ /* U+5928 */ 0x89F7, 0xCCEC, 0xCCAB, 0xB7F2, 0x89F8, 0xD8B2, 0xD1EB, 0xBABB,
+ /* U+5930 */ 0x89F9, 0xCAA7, 0x89FA, 0x89FB, 0xCDB7, 0x89FC, 0x89FD, 0xD2C4,
+ /* U+5938 */ 0xBFE4, 0xBCD0, 0xB6E1, 0x89FE, 0xDEC5, 0x8A40, 0x8A41, 0x8A42,
+ /* U+5940 */ 0x8A43, 0xDEC6, 0xDBBC, 0x8A44, 0xD1D9, 0x8A45, 0x8A46, 0xC6E6,
+ /* U+5948 */ 0xC4CE, 0xB7EE, 0x8A47, 0xB7DC, 0x8A48, 0x8A49, 0xBFFC, 0xD7E0,
+ /* U+5950 */ 0x8A4A, 0xC6F5, 0x8A4B, 0x8A4C, 0xB1BC, 0xDEC8, 0xBDB1, 0xCCD7,
+ /* U+5958 */ 0xDECA, 0x8A4D, 0xDEC9, 0x8A4E, 0x8A4F, 0x8A50, 0x8A51, 0x8A52,
+ /* U+5960 */ 0xB5EC, 0x8A53, 0xC9DD, 0x8A54, 0x8A55, 0xB0C2, 0x8A56, 0x8A57,
+ /* U+5968 */ 0x8A58, 0x8A59, 0x8A5A, 0x8A5B, 0x8A5C, 0x8A5D, 0x8A5E, 0x8A5F,
+ /* U+5970 */ 0x8A60, 0x8A61, 0x8A62, 0xC5AE, 0xC5AB, 0x8A63, 0xC4CC, 0x8A64,
+ /* U+5978 */ 0xBCE9, 0xCBFD, 0x8A65, 0x8A66, 0x8A67, 0xBAC3, 0x8A68, 0x8A69,
+ /* U+5980 */ 0x8A6A, 0xE5F9, 0xC8E7, 0xE5FA, 0xCDFD, 0x8A6B, 0xD7B1, 0xB8BE,
+ /* U+5988 */ 0xC2E8, 0x8A6C, 0xC8D1, 0x8A6D, 0x8A6E, 0xE5FB, 0x8A6F, 0x8A70,
+ /* U+5990 */ 0x8A71, 0x8A72, 0xB6CA, 0xBCCB, 0x8A73, 0x8A74, 0xD1FD, 0xE6A1,
+ /* U+5998 */ 0x8A75, 0xC3EE, 0x8A76, 0x8A77, 0x8A78, 0x8A79, 0xE6A4, 0x8A7A,
+ /* U+59A0 */ 0x8A7B, 0x8A7C, 0x8A7D, 0xE5FE, 0xE6A5, 0xCDD7, 0x8A7E, 0x8A80,
+ /* U+59A8 */ 0xB7C1, 0xE5FC, 0xE5FD, 0xE6A3, 0x8A81, 0x8A82, 0xC4DD, 0xE6A8,
+ /* U+59B0 */ 0x8A83, 0x8A84, 0xE6A7, 0x8A85, 0x8A86, 0x8A87, 0x8A88, 0x8A89,
+ /* U+59B8 */ 0x8A8A, 0xC3C3, 0x8A8B, 0xC6DE, 0x8A8C, 0x8A8D, 0xE6AA, 0x8A8E,
+ /* U+59C0 */ 0x8A8F, 0x8A90, 0x8A91, 0x8A92, 0x8A93, 0x8A94, 0xC4B7, 0x8A95,
+ /* U+59C8 */ 0x8A96, 0x8A97, 0xE6A2, 0xCABC, 0x8A98, 0x8A99, 0x8A9A, 0x8A9B,
+ /* U+59D0 */ 0xBDE3, 0xB9C3, 0xE6A6, 0xD0D5, 0xCEAF, 0x8A9C, 0x8A9D, 0xE6A9,
+ /* U+59D8 */ 0xE6B0, 0x8A9E, 0xD2A6, 0x8A9F, 0xBDAA, 0xE6AD, 0x8AA0, 0x8AA1,
+ /* U+59E0 */ 0x8AA2, 0x8AA3, 0x8AA4, 0xE6AF, 0x8AA5, 0xC0D1, 0x8AA6, 0x8AA7,
+ /* U+59E8 */ 0xD2CC, 0x8AA8, 0x8AA9, 0x8AAA, 0xBCA7, 0x8AAB, 0x8AAC, 0x8AAD,
+ /* U+59F0 */ 0x8AAE, 0x8AAF, 0x8AB0, 0x8AB1, 0x8AB2, 0x8AB3, 0x8AB4, 0x8AB5,
+ /* U+59F8 */ 0x8AB6, 0xE6B1, 0x8AB7, 0xD2F6, 0x8AB8, 0x8AB9, 0x8ABA, 0xD7CB,
+ /* U+5A00 */ 0x8ABB, 0xCDFE, 0x8ABC, 0xCDDE, 0xC2A6, 0xE6AB, 0xE6AC, 0xBDBF,
+ /* U+5A08 */ 0xE6AE, 0xE6B3, 0x8ABD, 0x8ABE, 0xE6B2, 0x8ABF, 0x8AC0, 0x8AC1,
+ /* U+5A10 */ 0x8AC2, 0xE6B6, 0x8AC3, 0xE6B8, 0x8AC4, 0x8AC5, 0x8AC6, 0x8AC7,
+ /* U+5A18 */ 0xC4EF, 0x8AC8, 0x8AC9, 0x8ACA, 0xC4C8, 0x8ACB, 0x8ACC, 0xBEEA,
+ /* U+5A20 */ 0xC9EF, 0x8ACD, 0x8ACE, 0xE6B7, 0x8ACF, 0xB6F0, 0x8AD0, 0x8AD1,
+ /* U+5A28 */ 0x8AD2, 0xC3E4, 0x8AD3, 0x8AD4, 0x8AD5, 0x8AD6, 0x8AD7, 0x8AD8,
+ /* U+5A30 */ 0x8AD9, 0xD3E9, 0xE6B4, 0x8ADA, 0xE6B5, 0x8ADB, 0xC8A2, 0x8ADC,
+ /* U+5A38 */ 0x8ADD, 0x8ADE, 0x8ADF, 0x8AE0, 0xE6BD, 0x8AE1, 0x8AE2, 0x8AE3,
+ /* U+5A40 */ 0xE6B9, 0x8AE4, 0x8AE5, 0x8AE6, 0x8AE7, 0x8AE8, 0xC6C5, 0x8AE9,
+ /* U+5A48 */ 0x8AEA, 0xCDF1, 0xE6BB, 0x8AEB, 0x8AEC, 0x8AED, 0x8AEE, 0x8AEF,
+ /* U+5A50 */ 0x8AF0, 0x8AF1, 0x8AF2, 0x8AF3, 0x8AF4, 0xE6BC, 0x8AF5, 0x8AF6,
+ /* U+5A58 */ 0x8AF7, 0x8AF8, 0xBBE9, 0x8AF9, 0x8AFA, 0x8AFB, 0x8AFC, 0x8AFD,
+ /* U+5A60 */ 0x8AFE, 0x8B40, 0xE6BE, 0x8B41, 0x8B42, 0x8B43, 0x8B44, 0xE6BA,
+ /* U+5A68 */ 0x8B45, 0x8B46, 0xC0B7, 0x8B47, 0x8B48, 0x8B49, 0x8B4A, 0x8B4B,
+ /* U+5A70 */ 0x8B4C, 0x8B4D, 0x8B4E, 0x8B4F, 0xD3A4, 0xE6BF, 0xC9F4, 0xE6C3,
+ /* U+5A78 */ 0x8B50, 0x8B51, 0xE6C4, 0x8B52, 0x8B53, 0x8B54, 0x8B55, 0xD0F6,
+ /* U+5A80 */ 0x8B56, 0x8B57, 0x8B58, 0x8B59, 0x8B5A, 0x8B5B, 0x8B5C, 0x8B5D,
+ /* U+5A88 */ 0x8B5E, 0x8B5F, 0x8B60, 0x8B61, 0x8B62, 0x8B63, 0x8B64, 0x8B65,
+ /* U+5A90 */ 0x8B66, 0x8B67, 0xC3BD, 0x8B68, 0x8B69, 0x8B6A, 0x8B6B, 0x8B6C,
+ /* U+5A98 */ 0x8B6D, 0x8B6E, 0xC3C4, 0xE6C2, 0x8B6F, 0x8B70, 0x8B71, 0x8B72,
+ /* U+5AA0 */ 0x8B73, 0x8B74, 0x8B75, 0x8B76, 0x8B77, 0x8B78, 0x8B79, 0x8B7A,
+ /* U+5AA8 */ 0x8B7B, 0x8B7C, 0xE6C1, 0x8B7D, 0x8B7E, 0x8B80, 0x8B81, 0x8B82,
+ /* U+5AB0 */ 0x8B83, 0x8B84, 0xE6C7, 0xCFB1, 0x8B85, 0xEBF4, 0x8B86, 0x8B87,
+ /* U+5AB8 */ 0xE6CA, 0x8B88, 0x8B89, 0x8B8A, 0x8B8B, 0x8B8C, 0xE6C5, 0x8B8D,
+ /* U+5AC0 */ 0x8B8E, 0xBCDE, 0xC9A9, 0x8B8F, 0x8B90, 0x8B91, 0x8B92, 0x8B93,
+ /* U+5AC8 */ 0x8B94, 0xBCB5, 0x8B95, 0x8B96, 0xCFD3, 0x8B97, 0x8B98, 0x8B99,
+ /* U+5AD0 */ 0x8B9A, 0x8B9B, 0xE6C8, 0x8B9C, 0xE6C9, 0x8B9D, 0xE6CE, 0x8B9E,
+ /* U+5AD8 */ 0xE6D0, 0x8B9F, 0x8BA0, 0x8BA1, 0xE6D1, 0x8BA2, 0x8BA3, 0x8BA4,
+ /* U+5AE0 */ 0xE6CB, 0xB5D5, 0x8BA5, 0xE6CC, 0x8BA6, 0x8BA7, 0xE6CF, 0x8BA8,
+ /* U+5AE8 */ 0x8BA9, 0xC4DB, 0x8BAA, 0xE6C6, 0x8BAB, 0x8BAC, 0x8BAD, 0x8BAE,
+ /* U+5AF0 */ 0x8BAF, 0xE6CD, 0x8BB0, 0x8BB1, 0x8BB2, 0x8BB3, 0x8BB4, 0x8BB5,
+ /* U+5AF8 */ 0x8BB6, 0x8BB7, 0x8BB8, 0x8BB9, 0x8BBA, 0x8BBB, 0x8BBC, 0x8BBD,
+ /* U+5B00 */ 0x8BBE, 0x8BBF, 0x8BC0, 0x8BC1, 0x8BC2, 0x8BC3, 0x8BC4, 0x8BC5,
+ /* U+5B08 */ 0x8BC6, 0xE6D2, 0x8BC7, 0x8BC8, 0x8BC9, 0x8BCA, 0x8BCB, 0x8BCC,
+ /* U+5B10 */ 0x8BCD, 0x8BCE, 0x8BCF, 0x8BD0, 0x8BD1, 0x8BD2, 0xE6D4, 0xE6D3,
+ /* U+5B18 */ 0x8BD3, 0x8BD4, 0x8BD5, 0x8BD6, 0x8BD7, 0x8BD8, 0x8BD9, 0x8BDA,
+ /* U+5B20 */ 0x8BDB, 0x8BDC, 0x8BDD, 0x8BDE, 0x8BDF, 0x8BE0, 0x8BE1, 0x8BE2,
+ /* U+5B28 */ 0x8BE3, 0x8BE4, 0x8BE5, 0x8BE6, 0x8BE7, 0x8BE8, 0x8BE9, 0x8BEA,
+ /* U+5B30 */ 0x8BEB, 0x8BEC, 0xE6D5, 0x8BED, 0xD9F8, 0x8BEE, 0x8BEF, 0xE6D6,
+ /* U+5B38 */ 0x8BF0, 0x8BF1, 0x8BF2, 0x8BF3, 0x8BF4, 0x8BF5, 0x8BF6, 0x8BF7,
+ /* U+5B40 */ 0xE6D7, 0x8BF8, 0x8BF9, 0x8BFA, 0x8BFB, 0x8BFC, 0x8BFD, 0x8BFE,
+ /* U+5B48 */ 0x8C40, 0x8C41, 0x8C42, 0x8C43, 0x8C44, 0x8C45, 0x8C46, 0x8C47,
+ /* U+5B50 */ 0xD7D3, 0xE6DD, 0x8C48, 0xE6DE, 0xBFD7, 0xD4D0, 0x8C49, 0xD7D6,
+ /* U+5B58 */ 0xB4E6, 0xCBEF, 0xE6DA, 0xD8C3, 0xD7CE, 0xD0A2, 0x8C4A, 0xC3CF,
+ /* U+5B60 */ 0x8C4B, 0x8C4C, 0xE6DF, 0xBCBE, 0xB9C2, 0xE6DB, 0xD1A7, 0x8C4D,
+ /* U+5B68 */ 0x8C4E, 0xBAA2, 0xC2CF, 0x8C4F, 0xD8AB, 0x8C50, 0x8C51, 0x8C52,
+ /* U+5B70 */ 0xCAEB, 0xE5EE, 0x8C53, 0xE6DC, 0x8C54, 0xB7F5, 0x8C55, 0x8C56,
+ /* U+5B78 */ 0x8C57, 0x8C58, 0xC8E6, 0x8C59, 0x8C5A, 0xC4F5, 0x8C5B, 0x8C5C,
+ /* U+5B80 */ 0xE5B2, 0xC4FE, 0x8C5D, 0xCBFC, 0xE5B3, 0xD5AC, 0x8C5E, 0xD3EE,
+ /* U+5B88 */ 0xCAD8, 0xB0B2, 0x8C5F, 0xCBCE, 0xCDEA, 0x8C60, 0x8C61, 0xBAEA,
+ /* U+5B90 */ 0x8C62, 0x8C63, 0x8C64, 0xE5B5, 0x8C65, 0xE5B4, 0x8C66, 0xD7DA,
+ /* U+5B98 */ 0xB9D9, 0xD6E6, 0xB6A8, 0xCDF0, 0xD2CB, 0xB1A6, 0xCAB5, 0x8C67,
+ /* U+5BA0 */ 0xB3E8, 0xC9F3, 0xBFCD, 0xD0FB, 0xCAD2, 0xE5B6, 0xBBC2, 0x8C68,
+ /* U+5BA8 */ 0x8C69, 0x8C6A, 0xCFDC, 0xB9AC, 0x8C6B, 0x8C6C, 0x8C6D, 0x8C6E,
+ /* U+5BB0 */ 0xD4D7, 0x8C6F, 0x8C70, 0xBAA6, 0xD1E7, 0xCFFC, 0xBCD2, 0x8C71,
+ /* U+5BB8 */ 0xE5B7, 0xC8DD, 0x8C72, 0x8C73, 0x8C74, 0xBFED, 0xB1F6, 0xCBDE,
+ /* U+5BC0 */ 0x8C75, 0x8C76, 0xBCC5, 0x8C77, 0xBCC4, 0xD2FA, 0xC3DC, 0xBFDC,
+ /* U+5BC8 */ 0x8C78, 0x8C79, 0x8C7A, 0x8C7B, 0xB8BB, 0x8C7C, 0x8C7D, 0x8C7E,
+ /* U+5BD0 */ 0xC3C2, 0x8C80, 0xBAAE, 0xD4A2, 0x8C81, 0x8C82, 0x8C83, 0x8C84,
+ /* U+5BD8 */ 0x8C85, 0x8C86, 0x8C87, 0x8C88, 0x8C89, 0xC7DE, 0xC4AF, 0xB2EC,
+ /* U+5BE0 */ 0x8C8A, 0xB9D1, 0x8C8B, 0x8C8C, 0xE5BB, 0xC1C8, 0x8C8D, 0x8C8E,
+ /* U+5BE8 */ 0xD5AF, 0x8C8F, 0x8C90, 0x8C91, 0x8C92, 0x8C93, 0xE5BC, 0x8C94,
+ /* U+5BF0 */ 0xE5BE, 0x8C95, 0x8C96, 0x8C97, 0x8C98, 0x8C99, 0x8C9A, 0x8C9B,
+ /* U+5BF8 */ 0xB4E7, 0xB6D4, 0xCBC2, 0xD1B0, 0xB5BC, 0x8C9C, 0x8C9D, 0xCAD9,
+ /* U+5C00 */ 0x8C9E, 0xB7E2, 0x8C9F, 0x8CA0, 0xC9E4, 0x8CA1, 0xBDAB, 0x8CA2,
+ /* U+5C08 */ 0x8CA3, 0xCEBE, 0xD7F0, 0x8CA4, 0x8CA5, 0x8CA6, 0x8CA7, 0xD0A1,
+ /* U+5C10 */ 0x8CA8, 0xC9D9, 0x8CA9, 0x8CAA, 0xB6FB, 0xE6D8, 0xBCE2, 0x8CAB,
+ /* U+5C18 */ 0xB3BE, 0x8CAC, 0xC9D0, 0x8CAD, 0xE6D9, 0xB3A2, 0x8CAE, 0x8CAF,
+ /* U+5C20 */ 0x8CB0, 0x8CB1, 0xDECC, 0x8CB2, 0xD3C8, 0xDECD, 0x8CB3, 0xD2A2,
+ /* U+5C28 */ 0x8CB4, 0x8CB5, 0x8CB6, 0x8CB7, 0xDECE, 0x8CB8, 0x8CB9, 0x8CBA,
+ /* U+5C30 */ 0x8CBB, 0xBECD, 0x8CBC, 0x8CBD, 0xDECF, 0x8CBE, 0x8CBF, 0x8CC0,
+ /* U+5C38 */ 0xCAAC, 0xD2FC, 0xB3DF, 0xE5EA, 0xC4E1, 0xBEA1, 0xCEB2, 0xC4F2,
+ /* U+5C40 */ 0xBED6, 0xC6A8, 0xB2E3, 0x8CC1, 0x8CC2, 0xBED3, 0x8CC3, 0x8CC4,
+ /* U+5C48 */ 0xC7FC, 0xCCEB, 0xBDEC, 0xCEDD, 0x8CC5, 0x8CC6, 0xCABA, 0xC6C1,
+ /* U+5C50 */ 0xE5EC, 0xD0BC, 0x8CC7, 0x8CC8, 0x8CC9, 0xD5B9, 0x8CCA, 0x8CCB,
+ /* U+5C58 */ 0x8CCC, 0xE5ED, 0x8CCD, 0x8CCE, 0x8CCF, 0x8CD0, 0xCAF4, 0x8CD1,
+ /* U+5C60 */ 0xCDC0, 0xC2C5, 0x8CD2, 0xE5EF, 0x8CD3, 0xC2C4, 0xE5F0, 0x8CD4,
+ /* U+5C68 */ 0x8CD5, 0x8CD6, 0x8CD7, 0x8CD8, 0x8CD9, 0x8CDA, 0xE5F8, 0xCDCD,
+ /* U+5C70 */ 0x8CDB, 0xC9BD, 0x8CDC, 0x8CDD, 0x8CDE, 0x8CDF, 0x8CE0, 0x8CE1,
+ /* U+5C78 */ 0x8CE2, 0xD2D9, 0xE1A8, 0x8CE3, 0x8CE4, 0x8CE5, 0x8CE6, 0xD3EC,
+ /* U+5C80 */ 0x8CE7, 0xCBEA, 0xC6F1, 0x8CE8, 0x8CE9, 0x8CEA, 0x8CEB, 0x8CEC,
+ /* U+5C88 */ 0xE1AC, 0x8CED, 0x8CEE, 0x8CEF, 0xE1A7, 0xE1A9, 0x8CF0, 0x8CF1,
+ /* U+5C90 */ 0xE1AA, 0xE1AF, 0x8CF2, 0x8CF3, 0xB2ED, 0x8CF4, 0xE1AB, 0xB8DA,
+ /* U+5C98 */ 0xE1AD, 0xE1AE, 0xE1B0, 0xB5BA, 0xE1B1, 0x8CF5, 0x8CF6, 0x8CF7,
+ /* U+5CA0 */ 0x8CF8, 0x8CF9, 0xE1B3, 0xE1B8, 0x8CFA, 0x8CFB, 0x8CFC, 0x8CFD,
+ /* U+5CA8 */ 0x8CFE, 0xD1D2, 0x8D40, 0xE1B6, 0xE1B5, 0xC1EB, 0x8D41, 0x8D42,
+ /* U+5CB0 */ 0x8D43, 0xE1B7, 0x8D44, 0xD4C0, 0x8D45, 0xE1B2, 0x8D46, 0xE1BA,
+ /* U+5CB8 */ 0xB0B6, 0x8D47, 0x8D48, 0x8D49, 0x8D4A, 0xE1B4, 0x8D4B, 0xBFF9,
+ /* U+5CC0 */ 0x8D4C, 0xE1B9, 0x8D4D, 0x8D4E, 0xE1BB, 0x8D4F, 0x8D50, 0x8D51,
+ /* U+5CC8 */ 0x8D52, 0x8D53, 0x8D54, 0xE1BE, 0x8D55, 0x8D56, 0x8D57, 0x8D58,
+ /* U+5CD0 */ 0x8D59, 0x8D5A, 0xE1BC, 0x8D5B, 0x8D5C, 0x8D5D, 0x8D5E, 0x8D5F,
+ /* U+5CD8 */ 0x8D60, 0xD6C5, 0x8D61, 0x8D62, 0x8D63, 0x8D64, 0x8D65, 0x8D66,
+ /* U+5CE0 */ 0x8D67, 0xCFBF, 0x8D68, 0x8D69, 0xE1BD, 0xE1BF, 0xC2CD, 0x8D6A,
+ /* U+5CE8 */ 0xB6EB, 0x8D6B, 0xD3F8, 0x8D6C, 0x8D6D, 0xC7CD, 0x8D6E, 0x8D6F,
+ /* U+5CF0 */ 0xB7E5, 0x8D70, 0x8D71, 0x8D72, 0x8D73, 0x8D74, 0x8D75, 0x8D76,
+ /* U+5CF8 */ 0x8D77, 0x8D78, 0x8D79, 0xBEFE, 0x8D7A, 0x8D7B, 0x8D7C, 0x8D7D,
+ /* U+5D00 */ 0x8D7E, 0x8D80, 0xE1C0, 0xE1C1, 0x8D81, 0x8D82, 0xE1C7, 0xB3E7,
+ /* U+5D08 */ 0x8D83, 0x8D84, 0x8D85, 0x8D86, 0x8D87, 0x8D88, 0xC6E9, 0x8D89,
+ /* U+5D10 */ 0x8D8A, 0x8D8B, 0x8D8C, 0x8D8D, 0xB4DE, 0x8D8E, 0xD1C2, 0x8D8F,
+ /* U+5D18 */ 0x8D90, 0x8D91, 0x8D92, 0xE1C8, 0x8D93, 0x8D94, 0xE1C6, 0x8D95,
+ /* U+5D20 */ 0x8D96, 0x8D97, 0x8D98, 0x8D99, 0xE1C5, 0x8D9A, 0xE1C3, 0xE1C2,
+ /* U+5D28 */ 0x8D9B, 0xB1C0, 0x8D9C, 0x8D9D, 0x8D9E, 0xD5B8, 0xE1C4, 0x8D9F,
+ /* U+5D30 */ 0x8DA0, 0x8DA1, 0x8DA2, 0x8DA3, 0xE1CB, 0x8DA4, 0x8DA5, 0x8DA6,
+ /* U+5D38 */ 0x8DA7, 0x8DA8, 0x8DA9, 0x8DAA, 0x8DAB, 0xE1CC, 0xE1CA, 0x8DAC,
+ /* U+5D40 */ 0x8DAD, 0x8DAE, 0x8DAF, 0x8DB0, 0x8DB1, 0x8DB2, 0x8DB3, 0xEFFA,
+ /* U+5D48 */ 0x8DB4, 0x8DB5, 0xE1D3, 0xE1D2, 0xC7B6, 0x8DB6, 0x8DB7, 0x8DB8,
+ /* U+5D50 */ 0x8DB9, 0x8DBA, 0x8DBB, 0x8DBC, 0x8DBD, 0x8DBE, 0x8DBF, 0x8DC0,
+ /* U+5D58 */ 0xE1C9, 0x8DC1, 0x8DC2, 0xE1CE, 0x8DC3, 0xE1D0, 0x8DC4, 0x8DC5,
+ /* U+5D60 */ 0x8DC6, 0x8DC7, 0x8DC8, 0x8DC9, 0x8DCA, 0x8DCB, 0x8DCC, 0x8DCD,
+ /* U+5D68 */ 0x8DCE, 0xE1D4, 0x8DCF, 0xE1D1, 0xE1CD, 0x8DD0, 0x8DD1, 0xE1CF,
+ /* U+5D70 */ 0x8DD2, 0x8DD3, 0x8DD4, 0x8DD5, 0xE1D5, 0x8DD6, 0x8DD7, 0x8DD8,
+ /* U+5D78 */ 0x8DD9, 0x8DDA, 0x8DDB, 0x8DDC, 0x8DDD, 0x8DDE, 0x8DDF, 0x8DE0,
+ /* U+5D80 */ 0x8DE1, 0x8DE2, 0xE1D6, 0x8DE3, 0x8DE4, 0x8DE5, 0x8DE6, 0x8DE7,
+ /* U+5D88 */ 0x8DE8, 0x8DE9, 0x8DEA, 0x8DEB, 0x8DEC, 0x8DED, 0x8DEE, 0x8DEF,
+ /* U+5D90 */ 0x8DF0, 0x8DF1, 0x8DF2, 0x8DF3, 0x8DF4, 0x8DF5, 0x8DF6, 0x8DF7,
+ /* U+5D98 */ 0x8DF8, 0xE1D7, 0x8DF9, 0x8DFA, 0x8DFB, 0xE1D8, 0x8DFC, 0x8DFD,
+ /* U+5DA0 */ 0x8DFE, 0x8E40, 0x8E41, 0x8E42, 0x8E43, 0x8E44, 0x8E45, 0x8E46,
+ /* U+5DA8 */ 0x8E47, 0x8E48, 0x8E49, 0x8E4A, 0x8E4B, 0x8E4C, 0x8E4D, 0x8E4E,
+ /* U+5DB0 */ 0x8E4F, 0x8E50, 0x8E51, 0x8E52, 0x8E53, 0x8E54, 0x8E55, 0xE1DA,
+ /* U+5DB8 */ 0x8E56, 0x8E57, 0x8E58, 0x8E59, 0x8E5A, 0x8E5B, 0x8E5C, 0x8E5D,
+ /* U+5DC0 */ 0x8E5E, 0x8E5F, 0x8E60, 0x8E61, 0x8E62, 0xE1DB, 0x8E63, 0x8E64,
+ /* U+5DC8 */ 0x8E65, 0x8E66, 0x8E67, 0x8E68, 0x8E69, 0xCEA1, 0x8E6A, 0x8E6B,
+ /* U+5DD0 */ 0x8E6C, 0x8E6D, 0x8E6E, 0x8E6F, 0x8E70, 0x8E71, 0x8E72, 0x8E73,
+ /* U+5DD8 */ 0x8E74, 0x8E75, 0x8E76, 0xE7DD, 0x8E77, 0xB4A8, 0xD6DD, 0x8E78,
+ /* U+5DE0 */ 0x8E79, 0xD1B2, 0xB3B2, 0x8E7A, 0x8E7B, 0xB9A4, 0xD7F3, 0xC7C9,
+ /* U+5DE8 */ 0xBEDE, 0xB9AE, 0x8E7C, 0xCED7, 0x8E7D, 0x8E7E, 0xB2EE, 0xDBCF,
+ /* U+5DF0 */ 0x8E80, 0xBCBA, 0xD2D1, 0xCBC8, 0xB0CD, 0x8E81, 0x8E82, 0xCFEF,
+ /* U+5DF8 */ 0x8E83, 0x8E84, 0x8E85, 0x8E86, 0x8E87, 0xD9E3, 0xBDED, 0x8E88,
+ /* U+5E00 */ 0x8E89, 0xB1D2, 0xCAD0, 0xB2BC, 0x8E8A, 0xCBA7, 0xB7AB, 0x8E8B,
+ /* U+5E08 */ 0xCAA6, 0x8E8C, 0x8E8D, 0x8E8E, 0xCFA3, 0x8E8F, 0x8E90, 0xE0F8,
+ /* U+5E10 */ 0xD5CA, 0xE0FB, 0x8E91, 0x8E92, 0xE0FA, 0xC5C1, 0xCCFB, 0x8E93,
+ /* U+5E18 */ 0xC1B1, 0xE0F9, 0xD6E3, 0xB2AF, 0xD6C4, 0xB5DB, 0x8E94, 0x8E95,
+ /* U+5E20 */ 0x8E96, 0x8E97, 0x8E98, 0x8E99, 0x8E9A, 0x8E9B, 0xB4F8, 0xD6A1,
+ /* U+5E28 */ 0x8E9C, 0x8E9D, 0x8E9E, 0x8E9F, 0x8EA0, 0xCFAF, 0xB0EF, 0x8EA1,
+ /* U+5E30 */ 0x8EA2, 0xE0FC, 0x8EA3, 0x8EA4, 0x8EA5, 0x8EA6, 0x8EA7, 0xE1A1,
+ /* U+5E38 */ 0xB3A3, 0x8EA8, 0x8EA9, 0xE0FD, 0xE0FE, 0xC3B1, 0x8EAA, 0x8EAB,
+ /* U+5E40 */ 0x8EAC, 0x8EAD, 0xC3DD, 0x8EAE, 0xE1A2, 0xB7F9, 0x8EAF, 0x8EB0,
+ /* U+5E48 */ 0x8EB1, 0x8EB2, 0x8EB3, 0x8EB4, 0xBBCF, 0x8EB5, 0x8EB6, 0x8EB7,
+ /* U+5E50 */ 0x8EB8, 0x8EB9, 0x8EBA, 0x8EBB, 0xE1A3, 0xC4BB, 0x8EBC, 0x8EBD,
+ /* U+5E58 */ 0x8EBE, 0x8EBF, 0x8EC0, 0xE1A4, 0x8EC1, 0x8EC2, 0xE1A5, 0x8EC3,
+ /* U+5E60 */ 0x8EC4, 0xE1A6, 0xB4B1, 0x8EC5, 0x8EC6, 0x8EC7, 0x8EC8, 0x8EC9,
+ /* U+5E68 */ 0x8ECA, 0x8ECB, 0x8ECC, 0x8ECD, 0x8ECE, 0x8ECF, 0x8ED0, 0x8ED1,
+ /* U+5E70 */ 0x8ED2, 0x8ED3, 0xB8C9, 0xC6BD, 0xC4EA, 0x8ED4, 0xB2A2, 0x8ED5,
+ /* U+5E78 */ 0xD0D2, 0x8ED6, 0xE7DB, 0xBBC3, 0xD3D7, 0xD3C4, 0x8ED7, 0xB9E3,
+ /* U+5E80 */ 0xE2CF, 0x8ED8, 0x8ED9, 0x8EDA, 0xD7AF, 0x8EDB, 0xC7EC, 0xB1D3,
+ /* U+5E88 */ 0x8EDC, 0x8EDD, 0xB4B2, 0xE2D1, 0x8EDE, 0x8EDF, 0x8EE0, 0xD0F2,
+ /* U+5E90 */ 0xC2AE, 0xE2D0, 0x8EE1, 0xBFE2, 0xD3A6, 0xB5D7, 0xE2D2, 0xB5EA,
+ /* U+5E98 */ 0x8EE2, 0xC3ED, 0xB8FD, 0x8EE3, 0xB8AE, 0x8EE4, 0xC5D3, 0xB7CF,
+ /* U+5EA0 */ 0xE2D4, 0x8EE5, 0x8EE6, 0x8EE7, 0x8EE8, 0xE2D3, 0xB6C8, 0xD7F9,
+ /* U+5EA8 */ 0x8EE9, 0x8EEA, 0x8EEB, 0x8EEC, 0x8EED, 0xCDA5, 0x8EEE, 0x8EEF,
+ /* U+5EB0 */ 0x8EF0, 0x8EF1, 0x8EF2, 0xE2D8, 0x8EF3, 0xE2D6, 0xCAFC, 0xBFB5,
+ /* U+5EB8 */ 0xD3B9, 0xE2D5, 0x8EF4, 0x8EF5, 0x8EF6, 0x8EF7, 0xE2D7, 0x8EF8,
+ /* U+5EC0 */ 0x8EF9, 0x8EFA, 0x8EFB, 0x8EFC, 0x8EFD, 0x8EFE, 0x8F40, 0x8F41,
+ /* U+5EC8 */ 0x8F42, 0xC1AE, 0xC0C8, 0x8F43, 0x8F44, 0x8F45, 0x8F46, 0x8F47,
+ /* U+5ED0 */ 0x8F48, 0xE2DB, 0xE2DA, 0xC0AA, 0x8F49, 0x8F4A, 0xC1CE, 0x8F4B,
+ /* U+5ED8 */ 0x8F4C, 0x8F4D, 0x8F4E, 0xE2DC, 0x8F4F, 0x8F50, 0x8F51, 0x8F52,
+ /* U+5EE0 */ 0x8F53, 0x8F54, 0x8F55, 0x8F56, 0x8F57, 0x8F58, 0x8F59, 0x8F5A,
+ /* U+5EE8 */ 0xE2DD, 0x8F5B, 0xE2DE, 0x8F5C, 0x8F5D, 0x8F5E, 0x8F5F, 0x8F60,
+ /* U+5EF0 */ 0x8F61, 0x8F62, 0x8F63, 0x8F64, 0xDBC8, 0x8F65, 0xD1D3, 0xCDA2,
+ /* U+5EF8 */ 0x8F66, 0x8F67, 0xBDA8, 0x8F68, 0x8F69, 0x8F6A, 0xDEC3, 0xD8A5,
+ /* U+5F00 */ 0xBFAA, 0xDBCD, 0xD2EC, 0xC6FA, 0xC5AA, 0x8F6B, 0x8F6C, 0x8F6D,
+ /* U+5F08 */ 0xDEC4, 0x8F6E, 0xB1D7, 0xDFAE, 0x8F6F, 0x8F70, 0x8F71, 0xCABD,
+ /* U+5F10 */ 0x8F72, 0xDFB1, 0x8F73, 0xB9AD, 0x8F74, 0xD2FD, 0x8F75, 0xB8A5,
+ /* U+5F18 */ 0xBAEB, 0x8F76, 0x8F77, 0xB3DA, 0x8F78, 0x8F79, 0x8F7A, 0xB5DC,
+ /* U+5F20 */ 0xD5C5, 0x8F7B, 0x8F7C, 0x8F7D, 0x8F7E, 0xC3D6, 0xCFD2, 0xBBA1,
+ /* U+5F28 */ 0x8F80, 0xE5F3, 0xE5F2, 0x8F81, 0x8F82, 0xE5F4, 0x8F83, 0xCDE4,
+ /* U+5F30 */ 0x8F84, 0xC8F5, 0x8F85, 0x8F86, 0x8F87, 0x8F88, 0x8F89, 0x8F8A,
+ /* U+5F38 */ 0x8F8B, 0xB5AF, 0xC7BF, 0x8F8C, 0xE5F6, 0x8F8D, 0x8F8E, 0x8F8F,
+ /* U+5F40 */ 0xECB0, 0x8F90, 0x8F91, 0x8F92, 0x8F93, 0x8F94, 0x8F95, 0x8F96,
+ /* U+5F48 */ 0x8F97, 0x8F98, 0x8F99, 0x8F9A, 0x8F9B, 0x8F9C, 0x8F9D, 0x8F9E,
+ /* U+5F50 */ 0xE5E6, 0x8F9F, 0xB9E9, 0xB5B1, 0x8FA0, 0xC2BC, 0xE5E8, 0xE5E7,
+ /* U+5F58 */ 0xE5E9, 0x8FA1, 0x8FA2, 0x8FA3, 0x8FA4, 0xD2CD, 0x8FA5, 0x8FA6,
+ /* U+5F60 */ 0x8FA7, 0xE1EA, 0xD0CE, 0x8FA8, 0xCDAE, 0x8FA9, 0xD1E5, 0x8FAA,
+ /* U+5F68 */ 0x8FAB, 0xB2CA, 0xB1EB, 0x8FAC, 0xB1F2, 0xC5ED, 0x8FAD, 0x8FAE,
+ /* U+5F70 */ 0xD5C3, 0xD3B0, 0x8FAF, 0xE1DC, 0x8FB0, 0x8FB1, 0x8FB2, 0xE1DD,
+ /* U+5F78 */ 0x8FB3, 0xD2DB, 0x8FB4, 0xB3B9, 0xB1CB, 0x8FB5, 0x8FB6, 0x8FB7,
+ /* U+5F80 */ 0xCDF9, 0xD5F7, 0xE1DE, 0x8FB8, 0xBEB6, 0xB4FD, 0x8FB9, 0xE1DF,
+ /* U+5F88 */ 0xBADC, 0xE1E0, 0xBBB2, 0xC2C9, 0xE1E1, 0x8FBA, 0x8FBB, 0x8FBC,
+ /* U+5F90 */ 0xD0EC, 0x8FBD, 0xCDBD, 0x8FBE, 0x8FBF, 0xE1E2, 0x8FC0, 0xB5C3,
+ /* U+5F98 */ 0xC5C7, 0xE1E3, 0x8FC1, 0x8FC2, 0xE1E4, 0x8FC3, 0x8FC4, 0x8FC5,
+ /* U+5FA0 */ 0x8FC6, 0xD3F9, 0x8FC7, 0x8FC8, 0x8FC9, 0x8FCA, 0x8FCB, 0x8FCC,
+ /* U+5FA8 */ 0xE1E5, 0x8FCD, 0xD1AD, 0x8FCE, 0x8FCF, 0xE1E6, 0xCEA2, 0x8FD0,
+ /* U+5FB0 */ 0x8FD1, 0x8FD2, 0x8FD3, 0x8FD4, 0x8FD5, 0xE1E7, 0x8FD6, 0xB5C2,
+ /* U+5FB8 */ 0x8FD7, 0x8FD8, 0x8FD9, 0x8FDA, 0xE1E8, 0xBBD5, 0x8FDB, 0x8FDC,
+ /* U+5FC0 */ 0x8FDD, 0x8FDE, 0x8FDF, 0xD0C4, 0xE2E0, 0xB1D8, 0xD2E4, 0x8FE0,
+ /* U+5FC8 */ 0x8FE1, 0xE2E1, 0x8FE2, 0x8FE3, 0xBCC9, 0xC8CC, 0x8FE4, 0xE2E3,
+ /* U+5FD0 */ 0xECFE, 0xECFD, 0xDFAF, 0x8FE5, 0x8FE6, 0x8FE7, 0xE2E2, 0xD6BE,
+ /* U+5FD8 */ 0xCDFC, 0xC3A6, 0x8FE8, 0x8FE9, 0x8FEA, 0xE3C3, 0x8FEB, 0x8FEC,
+ /* U+5FE0 */ 0xD6D2, 0xE2E7, 0x8FED, 0x8FEE, 0xE2E8, 0x8FEF, 0x8FF0, 0xD3C7,
+ /* U+5FE8 */ 0x8FF1, 0x8FF2, 0xE2EC, 0xBFEC, 0x8FF3, 0xE2ED, 0xE2E5, 0x8FF4,
+ /* U+5FF0 */ 0x8FF5, 0xB3C0, 0x8FF6, 0x8FF7, 0x8FF8, 0xC4EE, 0x8FF9, 0x8FFA,
+ /* U+5FF8 */ 0xE2EE, 0x8FFB, 0x8FFC, 0xD0C3, 0x8FFD, 0xBAF6, 0xE2E9, 0xB7DE,
+ /* U+6000 */ 0xBBB3, 0xCCAC, 0xCBCB, 0xE2E4, 0xE2E6, 0xE2EA, 0xE2EB, 0x8FFE,
+ /* U+6008 */ 0x9040, 0x9041, 0xE2F7, 0x9042, 0x9043, 0xE2F4, 0xD4F5, 0xE2F3,
+ /* U+6010 */ 0x9044, 0x9045, 0xC5AD, 0x9046, 0xD5FA, 0xC5C2, 0xB2C0, 0x9047,
+ /* U+6018 */ 0x9048, 0xE2EF, 0x9049, 0xE2F2, 0xC1AF, 0xCBBC, 0x904A, 0x904B,
+ /* U+6020 */ 0xB5A1, 0xE2F9, 0x904C, 0x904D, 0x904E, 0xBCB1, 0xE2F1, 0xD0D4,
+ /* U+6028 */ 0xD4B9, 0xE2F5, 0xB9D6, 0xE2F6, 0x904F, 0x9050, 0x9051, 0xC7D3,
+ /* U+6030 */ 0x9052, 0x9053, 0x9054, 0x9055, 0x9056, 0xE2F0, 0x9057, 0x9058,
+ /* U+6038 */ 0x9059, 0x905A, 0x905B, 0xD7DC, 0xEDA1, 0x905C, 0x905D, 0xE2F8,
+ /* U+6040 */ 0x905E, 0xEDA5, 0xE2FE, 0xCAD1, 0x905F, 0x9060, 0x9061, 0x9062,
+ /* U+6048 */ 0x9063, 0x9064, 0x9065, 0xC1B5, 0x9066, 0xBBD0, 0x9067, 0x9068,
+ /* U+6050 */ 0xBFD6, 0x9069, 0xBAE3, 0x906A, 0x906B, 0xCBA1, 0x906C, 0x906D,
+ /* U+6058 */ 0x906E, 0xEDA6, 0xEDA3, 0x906F, 0x9070, 0xEDA2, 0x9071, 0x9072,
+ /* U+6060 */ 0x9073, 0x9074, 0xBBD6, 0xEDA7, 0xD0F4, 0x9075, 0x9076, 0xEDA4,
+ /* U+6068 */ 0xBADE, 0xB6F7, 0xE3A1, 0xB6B2, 0xCCF1, 0xB9A7, 0x9077, 0xCFA2,
+ /* U+6070 */ 0xC7A1, 0x9078, 0x9079, 0xBFD2, 0x907A, 0x907B, 0xB6F1, 0x907C,
+ /* U+6078 */ 0xE2FA, 0xE2FB, 0xE2FD, 0xE2FC, 0xC4D5, 0xE3A2, 0x907D, 0xD3C1,
+ /* U+6080 */ 0x907E, 0x9080, 0x9081, 0xE3A7, 0xC7C4, 0x9082, 0x9083, 0x9084,
+ /* U+6088 */ 0x9085, 0xCFA4, 0x9086, 0x9087, 0xE3A9, 0xBAB7, 0x9088, 0x9089,
+ /* U+6090 */ 0x908A, 0x908B, 0xE3A8, 0x908C, 0xBBDA, 0x908D, 0xE3A3, 0x908E,
+ /* U+6098 */ 0x908F, 0x9090, 0xE3A4, 0xE3AA, 0x9091, 0xE3A6, 0x9092, 0xCEF2,
+ /* U+60A0 */ 0xD3C6, 0x9093, 0x9094, 0xBBBC, 0x9095, 0x9096, 0xD4C3, 0x9097,
+ /* U+60A8 */ 0xC4FA, 0x9098, 0x9099, 0xEDA8, 0xD0FC, 0xE3A5, 0x909A, 0xC3F5,
+ /* U+60B0 */ 0x909B, 0xE3AD, 0xB1AF, 0x909C, 0xE3B2, 0x909D, 0x909E, 0x909F,
+ /* U+60B8 */ 0xBCC2, 0x90A0, 0x90A1, 0xE3AC, 0xB5BF, 0x90A2, 0x90A3, 0x90A4,
+ /* U+60C0 */ 0x90A5, 0x90A6, 0x90A7, 0x90A8, 0x90A9, 0xC7E9, 0xE3B0, 0x90AA,
+ /* U+60C8 */ 0x90AB, 0x90AC, 0xBEAA, 0xCDEF, 0x90AD, 0x90AE, 0x90AF, 0x90B0,
+ /* U+60D0 */ 0x90B1, 0xBBF3, 0x90B2, 0x90B3, 0x90B4, 0xCCE8, 0x90B5, 0x90B6,
+ /* U+60D8 */ 0xE3AF, 0x90B7, 0xE3B1, 0x90B8, 0xCFA7, 0xE3AE, 0x90B9, 0xCEA9,
+ /* U+60E0 */ 0xBBDD, 0x90BA, 0x90BB, 0x90BC, 0x90BD, 0x90BE, 0xB5EB, 0xBEE5,
+ /* U+60E8 */ 0xB2D2, 0xB3CD, 0x90BF, 0xB1B9, 0xE3AB, 0xB2D1, 0xB5AC, 0xB9DF,
+ /* U+60F0 */ 0xB6E8, 0x90C0, 0x90C1, 0xCFEB, 0xE3B7, 0x90C2, 0xBBCC, 0x90C3,
+ /* U+60F8 */ 0x90C4, 0xC8C7, 0xD0CA, 0x90C5, 0x90C6, 0x90C7, 0x90C8, 0x90C9,
+ /* U+6100 */ 0xE3B8, 0xB3EE, 0x90CA, 0x90CB, 0x90CC, 0x90CD, 0xEDA9, 0x90CE,
+ /* U+6108 */ 0xD3FA, 0xD3E4, 0x90CF, 0x90D0, 0x90D1, 0xEDAA, 0xE3B9, 0xD2E2,
+ /* U+6110 */ 0x90D2, 0x90D3, 0x90D4, 0x90D5, 0x90D6, 0xE3B5, 0x90D7, 0x90D8,
+ /* U+6118 */ 0x90D9, 0x90DA, 0xD3DE, 0x90DB, 0x90DC, 0x90DD, 0x90DE, 0xB8D0,
+ /* U+6120 */ 0xE3B3, 0x90DF, 0x90E0, 0xE3B6, 0xB7DF, 0x90E1, 0xE3B4, 0xC0A2,
+ /* U+6128 */ 0x90E2, 0x90E3, 0x90E4, 0xE3BA, 0x90E5, 0x90E6, 0x90E7, 0x90E8,
+ /* U+6130 */ 0x90E9, 0x90EA, 0x90EB, 0x90EC, 0x90ED, 0x90EE, 0x90EF, 0x90F0,
+ /* U+6138 */ 0x90F1, 0x90F2, 0x90F3, 0x90F4, 0x90F5, 0x90F6, 0x90F7, 0xD4B8,
+ /* U+6140 */ 0x90F8, 0x90F9, 0x90FA, 0x90FB, 0x90FC, 0x90FD, 0x90FE, 0x9140,
+ /* U+6148 */ 0xB4C8, 0x9141, 0xE3BB, 0x9142, 0xBBC5, 0x9143, 0xC9F7, 0x9144,
+ /* U+6150 */ 0x9145, 0xC9E5, 0x9146, 0x9147, 0x9148, 0xC4BD, 0x9149, 0x914A,
+ /* U+6158 */ 0x914B, 0x914C, 0x914D, 0x914E, 0x914F, 0xEDAB, 0x9150, 0x9151,
+ /* U+6160 */ 0x9152, 0x9153, 0xC2FD, 0x9154, 0x9155, 0x9156, 0x9157, 0xBBDB,
+ /* U+6168 */ 0xBFAE, 0x9158, 0x9159, 0x915A, 0x915B, 0x915C, 0x915D, 0x915E,
+ /* U+6170 */ 0xCEBF, 0x915F, 0x9160, 0x9161, 0x9162, 0xE3BC, 0x9163, 0xBFB6,
+ /* U+6178 */ 0x9164, 0x9165, 0x9166, 0x9167, 0x9168, 0x9169, 0x916A, 0x916B,
+ /* U+6180 */ 0x916C, 0x916D, 0x916E, 0x916F, 0x9170, 0x9171, 0x9172, 0x9173,
+ /* U+6188 */ 0x9174, 0x9175, 0x9176, 0xB1EF, 0x9177, 0x9178, 0xD4F7, 0x9179,
+ /* U+6190 */ 0x917A, 0x917B, 0x917C, 0x917D, 0xE3BE, 0x917E, 0x9180, 0x9181,
+ /* U+6198 */ 0x9182, 0x9183, 0x9184, 0x9185, 0x9186, 0xEDAD, 0x9187, 0x9188,
+ /* U+61A0 */ 0x9189, 0x918A, 0x918B, 0x918C, 0x918D, 0x918E, 0x918F, 0xE3BF,
+ /* U+61A8 */ 0xBAA9, 0xEDAC, 0x9190, 0x9191, 0xE3BD, 0x9192, 0x9193, 0x9194,
+ /* U+61B0 */ 0x9195, 0x9196, 0x9197, 0x9198, 0x9199, 0x919A, 0x919B, 0xE3C0,
+ /* U+61B8 */ 0x919C, 0x919D, 0x919E, 0x919F, 0x91A0, 0x91A1, 0xBAB6, 0x91A2,
+ /* U+61C0 */ 0x91A3, 0x91A4, 0xB6AE, 0x91A5, 0x91A6, 0x91A7, 0x91A8, 0x91A9,
+ /* U+61C8 */ 0xD0B8, 0x91AA, 0xB0C3, 0xEDAE, 0x91AB, 0x91AC, 0x91AD, 0x91AE,
+ /* U+61D0 */ 0x91AF, 0xEDAF, 0xC0C1, 0x91B0, 0xE3C1, 0x91B1, 0x91B2, 0x91B3,
+ /* U+61D8 */ 0x91B4, 0x91B5, 0x91B6, 0x91B7, 0x91B8, 0x91B9, 0x91BA, 0x91BB,
+ /* U+61E0 */ 0x91BC, 0x91BD, 0x91BE, 0x91BF, 0x91C0, 0x91C1, 0xC5B3, 0x91C2,
+ /* U+61E8 */ 0x91C3, 0x91C4, 0x91C5, 0x91C6, 0x91C7, 0x91C8, 0x91C9, 0x91CA,
+ /* U+61F0 */ 0x91CB, 0x91CC, 0x91CD, 0x91CE, 0x91CF, 0xE3C2, 0x91D0, 0x91D1,
+ /* U+61F8 */ 0x91D2, 0x91D3, 0x91D4, 0x91D5, 0x91D6, 0x91D7, 0x91D8, 0xDCB2,
+ /* U+6200 */ 0x91D9, 0x91DA, 0x91DB, 0x91DC, 0x91DD, 0x91DE, 0xEDB0, 0x91DF,
+ /* U+6208 */ 0xB8EA, 0x91E0, 0xCEEC, 0xEAA7, 0xD0E7, 0xCAF9, 0xC8D6, 0xCFB7,
+ /* U+6210 */ 0xB3C9, 0xCED2, 0xBDE4, 0x91E1, 0x91E2, 0xE3DE, 0xBBF2, 0xEAA8,
+ /* U+6218 */ 0xD5BD, 0x91E3, 0xC6DD, 0xEAA9, 0x91E4, 0x91E5, 0x91E6, 0xEAAA,
+ /* U+6220 */ 0x91E7, 0xEAAC, 0xEAAB, 0x91E8, 0xEAAE, 0xEAAD, 0x91E9, 0x91EA,
+ /* U+6228 */ 0x91EB, 0x91EC, 0xBDD8, 0x91ED, 0xEAAF, 0x91EE, 0xC2BE, 0x91EF,
+ /* U+6230 */ 0x91F0, 0x91F1, 0x91F2, 0xB4C1, 0xB4F7, 0x91F3, 0x91F4, 0xBBA7,
+ /* U+6238 */ 0x91F5, 0x91F6, 0x91F7, 0x91F8, 0x91F9, 0xECE6, 0xECE5, 0xB7BF,
+ /* U+6240 */ 0xCBF9, 0xB1E2, 0x91FA, 0xECE7, 0x91FB, 0x91FC, 0x91FD, 0xC9C8,
+ /* U+6248 */ 0xECE8, 0xECE9, 0x91FE, 0xCAD6, 0xDED0, 0xB2C5, 0xD4FA, 0x9240,
+ /* U+6250 */ 0x9241, 0xC6CB, 0xB0C7, 0xB4F2, 0xC8D3, 0x9242, 0x9243, 0x9244,
+ /* U+6258 */ 0xCDD0, 0x9245, 0x9246, 0xBFB8, 0x9247, 0x9248, 0x9249, 0x924A,
+ /* U+6260 */ 0x924B, 0x924C, 0x924D, 0xBFDB, 0x924E, 0x924F, 0xC7A4, 0xD6B4,
+ /* U+6268 */ 0x9250, 0xC0A9, 0xDED1, 0xC9A8, 0xD1EF, 0xC5A4, 0xB0E7, 0xB3B6,
+ /* U+6270 */ 0xC8C5, 0x9251, 0x9252, 0xB0E2, 0x9253, 0x9254, 0xB7F6, 0x9255,
+ /* U+6278 */ 0x9256, 0xC5FA, 0x9257, 0x9258, 0xB6F3, 0x9259, 0xD5D2, 0xB3D0,
+ /* U+6280 */ 0xBCBC, 0x925A, 0x925B, 0x925C, 0xB3AD, 0x925D, 0x925E, 0x925F,
+ /* U+6288 */ 0x9260, 0xBEF1, 0xB0D1, 0x9261, 0x9262, 0x9263, 0x9264, 0x9265,
+ /* U+6290 */ 0x9266, 0xD2D6, 0xCAE3, 0xD7A5, 0x9267, 0xCDB6, 0xB6B6, 0xBFB9,
+ /* U+6298 */ 0xD5DB, 0x9268, 0xB8A7, 0xC5D7, 0x9269, 0x926A, 0x926B, 0xDED2,
+ /* U+62A0 */ 0xBFD9, 0xC2D5, 0xC7C0, 0x926C, 0xBBA4, 0xB1A8, 0x926D, 0x926E,
+ /* U+62A8 */ 0xC5EA, 0x926F, 0x9270, 0xC5FB, 0xCCA7, 0x9271, 0x9272, 0x9273,
+ /* U+62B0 */ 0x9274, 0xB1A7, 0x9275, 0x9276, 0x9277, 0xB5D6, 0x9278, 0x9279,
+ /* U+62B8 */ 0x927A, 0xC4A8, 0x927B, 0xDED3, 0xD1BA, 0xB3E9, 0x927C, 0xC3F2,
+ /* U+62C0 */ 0x927D, 0x927E, 0xB7F7, 0x9280, 0xD6F4, 0xB5A3, 0xB2F0, 0xC4B4,
+ /* U+62C8 */ 0xC4E9, 0xC0AD, 0xDED4, 0x9281, 0xB0E8, 0xC5C4, 0xC1E0, 0x9282,
+ /* U+62D0 */ 0xB9D5, 0x9283, 0xBEDC, 0xCDD8, 0xB0CE, 0x9284, 0xCDCF, 0xDED6,
+ /* U+62D8 */ 0xBED0, 0xD7BE, 0xDED5, 0xD5D0, 0xB0DD, 0x9285, 0x9286, 0xC4E2,
+ /* U+62E0 */ 0x9287, 0x9288, 0xC2A3, 0xBCF0, 0x9289, 0xD3B5, 0xC0B9, 0xC5A1,
+ /* U+62E8 */ 0xB2A6, 0xD4F1, 0x928A, 0x928B, 0xC0A8, 0xCAC3, 0xDED7, 0xD5FC,
+ /* U+62F0 */ 0x928C, 0xB9B0, 0x928D, 0xC8AD, 0xCBA9, 0x928E, 0xDED9, 0xBFBD,
+ /* U+62F8 */ 0x928F, 0x9290, 0x9291, 0x9292, 0xC6B4, 0xD7A7, 0xCAB0, 0xC4C3,
+ /* U+6300 */ 0x9293, 0xB3D6, 0xB9D2, 0x9294, 0x9295, 0x9296, 0x9297, 0xD6B8,
+ /* U+6308 */ 0xEAFC, 0xB0B4, 0x9298, 0x9299, 0x929A, 0x929B, 0xBFE6, 0x929C,
+ /* U+6310 */ 0x929D, 0xCCF4, 0x929E, 0x929F, 0x92A0, 0x92A1, 0xCDDA, 0x92A2,
+ /* U+6318 */ 0x92A3, 0x92A4, 0xD6BF, 0xC2CE, 0x92A5, 0xCECE, 0xCCA2, 0xD0AE,
+ /* U+6320 */ 0xC4D3, 0xB5B2, 0xDED8, 0xD5F5, 0xBCB7, 0xBBD3, 0x92A6, 0x92A7,
+ /* U+6328 */ 0xB0A4, 0x92A8, 0xC5B2, 0xB4EC, 0x92A9, 0x92AA, 0x92AB, 0xD5F1,
+ /* U+6330 */ 0x92AC, 0x92AD, 0xEAFD, 0x92AE, 0x92AF, 0x92B0, 0x92B1, 0x92B2,
+ /* U+6338 */ 0x92B3, 0xDEDA, 0xCDA6, 0x92B4, 0x92B5, 0xCDEC, 0x92B6, 0x92B7,
+ /* U+6340 */ 0x92B8, 0x92B9, 0xCEE6, 0xDEDC, 0x92BA, 0xCDB1, 0xC0A6, 0x92BB,
+ /* U+6348 */ 0x92BC, 0xD7BD, 0x92BD, 0xDEDB, 0xB0C6, 0xBAB4, 0xC9D3, 0xC4F3,
+ /* U+6350 */ 0xBEE8, 0x92BE, 0x92BF, 0x92C0, 0x92C1, 0xB2B6, 0x92C2, 0x92C3,
+ /* U+6358 */ 0x92C4, 0x92C5, 0x92C6, 0x92C7, 0x92C8, 0x92C9, 0xC0CC, 0xCBF0,
+ /* U+6360 */ 0x92CA, 0xBCF1, 0xBBBB, 0xB5B7, 0x92CB, 0x92CC, 0x92CD, 0xC5F5,
+ /* U+6368 */ 0x92CE, 0xDEE6, 0x92CF, 0x92D0, 0x92D1, 0xDEE3, 0xBEDD, 0x92D2,
+ /* U+6370 */ 0x92D3, 0xDEDF, 0x92D4, 0x92D5, 0x92D6, 0x92D7, 0xB4B7, 0xBDDD,
+ /* U+6378 */ 0x92D8, 0x92D9, 0xDEE0, 0xC4ED, 0x92DA, 0x92DB, 0x92DC, 0x92DD,
+ /* U+6380 */ 0xCFC6, 0x92DE, 0xB5E0, 0x92DF, 0x92E0, 0x92E1, 0x92E2, 0xB6DE,
+ /* U+6388 */ 0xCADA, 0xB5F4, 0xDEE5, 0x92E3, 0xD5C6, 0x92E4, 0xDEE1, 0xCCCD,
+ /* U+6390 */ 0xC6FE, 0x92E5, 0xC5C5, 0x92E6, 0x92E7, 0x92E8, 0xD2B4, 0x92E9,
+ /* U+6398 */ 0xBEF2, 0x92EA, 0x92EB, 0x92EC, 0x92ED, 0x92EE, 0x92EF, 0x92F0,
+ /* U+63A0 */ 0xC2D3, 0x92F1, 0xCCBD, 0xB3B8, 0x92F2, 0xBDD3, 0x92F3, 0xBFD8,
+ /* U+63A8 */ 0xCDC6, 0xD1DA, 0xB4EB, 0x92F4, 0xDEE4, 0xDEDD, 0xDEE7, 0x92F5,
+ /* U+63B0 */ 0xEAFE, 0x92F6, 0x92F7, 0xC2B0, 0xDEE2, 0x92F8, 0x92F9, 0xD6C0,
+ /* U+63B8 */ 0xB5A7, 0x92FA, 0xB2F4, 0x92FB, 0xDEE8, 0x92FC, 0xDEF2, 0x92FD,
+ /* U+63C0 */ 0x92FE, 0x9340, 0x9341, 0x9342, 0xDEED, 0x9343, 0xDEF1, 0x9344,
+ /* U+63C8 */ 0x9345, 0xC8E0, 0x9346, 0x9347, 0x9348, 0xD7E1, 0xDEEF, 0xC3E8,
+ /* U+63D0 */ 0xCCE1, 0x9349, 0xB2E5, 0x934A, 0x934B, 0x934C, 0xD2BE, 0x934D,
+ /* U+63D8 */ 0x934E, 0x934F, 0x9350, 0x9351, 0x9352, 0x9353, 0xDEEE, 0x9354,
+ /* U+63E0 */ 0xDEEB, 0xCED5, 0x9355, 0xB4A7, 0x9356, 0x9357, 0x9358, 0x9359,
+ /* U+63E8 */ 0x935A, 0xBFAB, 0xBEBE, 0x935B, 0x935C, 0xBDD2, 0x935D, 0x935E,
+ /* U+63F0 */ 0x935F, 0x9360, 0xDEE9, 0x9361, 0xD4AE, 0x9362, 0xDEDE, 0x9363,
+ /* U+63F8 */ 0xDEEA, 0x9364, 0x9365, 0x9366, 0x9367, 0xC0BF, 0x9368, 0xDEEC,
+ /* U+6400 */ 0xB2F3, 0xB8E9, 0xC2A7, 0x9369, 0x936A, 0xBDC1, 0x936B, 0x936C,
+ /* U+6408 */ 0x936D, 0x936E, 0x936F, 0xDEF5, 0xDEF8, 0x9370, 0x9371, 0xB2AB,
+ /* U+6410 */ 0xB4A4, 0x9372, 0x9373, 0xB4EA, 0xC9A6, 0x9374, 0x9375, 0x9376,
+ /* U+6418 */ 0x9377, 0x9378, 0x9379, 0xDEF6, 0xCBD1, 0x937A, 0xB8E3, 0x937B,
+ /* U+6420 */ 0xDEF7, 0xDEFA, 0x937C, 0x937D, 0x937E, 0x9380, 0xDEF9, 0x9381,
+ /* U+6428 */ 0x9382, 0x9383, 0xCCC2, 0x9384, 0xB0E1, 0xB4EE, 0x9385, 0x9386,
+ /* U+6430 */ 0x9387, 0x9388, 0x9389, 0x938A, 0xE5BA, 0x938B, 0x938C, 0x938D,
+ /* U+6438 */ 0x938E, 0x938F, 0xD0AF, 0x9390, 0x9391, 0xB2EB, 0x9392, 0xEBA1,
+ /* U+6440 */ 0x9393, 0xDEF4, 0x9394, 0x9395, 0xC9E3, 0xDEF3, 0xB0DA, 0xD2A1,
+ /* U+6448 */ 0xB1F7, 0x9396, 0xCCAF, 0x9397, 0x9398, 0x9399, 0x939A, 0x939B,
+ /* U+6450 */ 0x939C, 0x939D, 0xDEF0, 0x939E, 0xCBA4, 0x939F, 0x93A0, 0x93A1,
+ /* U+6458 */ 0xD5AA, 0x93A2, 0x93A3, 0x93A4, 0x93A5, 0x93A6, 0xDEFB, 0x93A7,
+ /* U+6460 */ 0x93A8, 0x93A9, 0x93AA, 0x93AB, 0x93AC, 0x93AD, 0x93AE, 0xB4DD,
+ /* U+6468 */ 0x93AF, 0xC4A6, 0x93B0, 0x93B1, 0x93B2, 0xDEFD, 0x93B3, 0x93B4,
+ /* U+6470 */ 0x93B5, 0x93B6, 0x93B7, 0x93B8, 0x93B9, 0x93BA, 0x93BB, 0x93BC,
+ /* U+6478 */ 0xC3FE, 0xC4A1, 0xDFA1, 0x93BD, 0x93BE, 0x93BF, 0x93C0, 0x93C1,
+ /* U+6480 */ 0x93C2, 0x93C3, 0xC1CC, 0x93C4, 0xDEFC, 0xBEEF, 0x93C5, 0xC6B2,
+ /* U+6488 */ 0x93C6, 0x93C7, 0x93C8, 0x93C9, 0x93CA, 0x93CB, 0x93CC, 0x93CD,
+ /* U+6490 */ 0x93CE, 0xB3C5, 0xC8F6, 0x93CF, 0x93D0, 0xCBBA, 0xDEFE, 0x93D1,
+ /* U+6498 */ 0x93D2, 0xDFA4, 0x93D3, 0x93D4, 0x93D5, 0x93D6, 0xD7B2, 0x93D7,
+ /* U+64A0 */ 0x93D8, 0x93D9, 0x93DA, 0x93DB, 0xB3B7, 0x93DC, 0x93DD, 0x93DE,
+ /* U+64A8 */ 0x93DF, 0xC1C3, 0x93E0, 0x93E1, 0xC7CB, 0xB2A5, 0xB4E9, 0x93E2,
+ /* U+64B0 */ 0xD7AB, 0x93E3, 0x93E4, 0x93E5, 0x93E6, 0xC4EC, 0x93E7, 0xDFA2,
+ /* U+64B8 */ 0xDFA3, 0x93E8, 0xDFA5, 0x93E9, 0xBAB3, 0x93EA, 0x93EB, 0x93EC,
+ /* U+64C0 */ 0xDFA6, 0x93ED, 0xC0DE, 0x93EE, 0x93EF, 0xC9C3, 0x93F0, 0x93F1,
+ /* U+64C8 */ 0x93F2, 0x93F3, 0x93F4, 0x93F5, 0x93F6, 0xB2D9, 0xC7E6, 0x93F7,
+ /* U+64D0 */ 0xDFA7, 0x93F8, 0xC7DC, 0x93F9, 0x93FA, 0x93FB, 0x93FC, 0xDFA8,
+ /* U+64D8 */ 0xEBA2, 0x93FD, 0x93FE, 0x9440, 0x9441, 0x9442, 0xCBD3, 0x9443,
+ /* U+64E0 */ 0x9444, 0x9445, 0xDFAA, 0x9446, 0xDFA9, 0x9447, 0xB2C1, 0x9448,
+ /* U+64E8 */ 0x9449, 0x944A, 0x944B, 0x944C, 0x944D, 0x944E, 0x944F, 0x9450,
+ /* U+64F0 */ 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457, 0x9458,
+ /* U+64F8 */ 0x9459, 0x945A, 0x945B, 0x945C, 0x945D, 0x945E, 0x945F, 0x9460,
+ /* U+6500 */ 0xC5CA, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467,
+ /* U+6508 */ 0x9468, 0xDFAB, 0x9469, 0x946A, 0x946B, 0x946C, 0x946D, 0x946E,
+ /* U+6510 */ 0x946F, 0x9470, 0xD4DC, 0x9471, 0x9472, 0x9473, 0x9474, 0x9475,
+ /* U+6518 */ 0xC8C1, 0x9476, 0x9477, 0x9478, 0x9479, 0x947A, 0x947B, 0x947C,
+ /* U+6520 */ 0x947D, 0x947E, 0x9480, 0x9481, 0x9482, 0xDFAC, 0x9483, 0x9484,
+ /* U+6528 */ 0x9485, 0x9486, 0x9487, 0xBEF0, 0x9488, 0x9489, 0xDFAD, 0xD6A7,
+ /* U+6530 */ 0x948A, 0x948B, 0x948C, 0x948D, 0xEAB7, 0xEBB6, 0xCAD5, 0x948E,
+ /* U+6538 */ 0xD8FC, 0xB8C4, 0x948F, 0xB9A5, 0x9490, 0x9491, 0xB7C5, 0xD5FE,
+ /* U+6540 */ 0x9492, 0x9493, 0x9494, 0x9495, 0x9496, 0xB9CA, 0x9497, 0x9498,
+ /* U+6548 */ 0xD0A7, 0xF4CD, 0x9499, 0x949A, 0xB5D0, 0x949B, 0x949C, 0xC3F4,
+ /* U+6550 */ 0x949D, 0xBEC8, 0x949E, 0x949F, 0x94A0, 0xEBB7, 0xB0BD, 0x94A1,
+ /* U+6558 */ 0x94A2, 0xBDCC, 0x94A3, 0xC1B2, 0x94A4, 0xB1D6, 0xB3A8, 0x94A5,
+ /* U+6560 */ 0x94A6, 0x94A7, 0xB8D2, 0xC9A2, 0x94A8, 0x94A9, 0xB6D8, 0x94AA,
+ /* U+6568 */ 0x94AB, 0x94AC, 0x94AD, 0xEBB8, 0xBEB4, 0x94AE, 0x94AF, 0x94B0,
+ /* U+6570 */ 0xCAFD, 0x94B1, 0xC7C3, 0x94B2, 0xD5FB, 0x94B3, 0x94B4, 0xB7F3,
+ /* U+6578 */ 0x94B5, 0x94B6, 0x94B7, 0x94B8, 0x94B9, 0x94BA, 0x94BB, 0x94BC,
+ /* U+6580 */ 0x94BD, 0x94BE, 0x94BF, 0x94C0, 0x94C1, 0x94C2, 0x94C3, 0xCEC4,
+ /* U+6588 */ 0x94C4, 0x94C5, 0x94C6, 0xD5AB, 0xB1F3, 0x94C7, 0x94C8, 0x94C9,
+ /* U+6590 */ 0xECB3, 0xB0DF, 0x94CA, 0xECB5, 0x94CB, 0x94CC, 0x94CD, 0xB6B7,
+ /* U+6598 */ 0x94CE, 0xC1CF, 0x94CF, 0xF5FA, 0xD0B1, 0x94D0, 0x94D1, 0xD5E5,
+ /* U+65A0 */ 0x94D2, 0xCED3, 0x94D3, 0x94D4, 0xBDEF, 0xB3E2, 0x94D5, 0xB8AB,
+ /* U+65A8 */ 0x94D6, 0xD5B6, 0x94D7, 0xEDBD, 0x94D8, 0xB6CF, 0x94D9, 0xCBB9,
+ /* U+65B0 */ 0xD0C2, 0x94DA, 0x94DB, 0x94DC, 0x94DD, 0x94DE, 0x94DF, 0x94E0,
+ /* U+65B8 */ 0x94E1, 0xB7BD, 0x94E2, 0x94E3, 0xECB6, 0xCAA9, 0x94E4, 0x94E5,
+ /* U+65C0 */ 0x94E6, 0xC5D4, 0x94E7, 0xECB9, 0xECB8, 0xC2C3, 0xECB7, 0x94E8,
+ /* U+65C8 */ 0x94E9, 0x94EA, 0x94EB, 0xD0FD, 0xECBA, 0x94EC, 0xECBB, 0xD7E5,
+ /* U+65D0 */ 0x94ED, 0x94EE, 0xECBC, 0x94EF, 0x94F0, 0x94F1, 0xECBD, 0xC6EC,
+ /* U+65D8 */ 0x94F2, 0x94F3, 0x94F4, 0x94F5, 0x94F6, 0x94F7, 0x94F8, 0x94F9,
+ /* U+65E0 */ 0xCEDE, 0x94FA, 0xBCC8, 0x94FB, 0x94FC, 0xC8D5, 0xB5A9, 0xBEC9,
+ /* U+65E8 */ 0xD6BC, 0xD4E7, 0x94FD, 0x94FE, 0xD1AE, 0xD0F1, 0xEAB8, 0xEAB9,
+ /* U+65F0 */ 0xEABA, 0xBAB5, 0x9540, 0x9541, 0x9542, 0x9543, 0xCAB1, 0xBFF5,
+ /* U+65F8 */ 0x9544, 0x9545, 0xCDFA, 0x9546, 0x9547, 0x9548, 0x9549, 0x954A,
+ /* U+6600 */ 0xEAC0, 0x954B, 0xB0BA, 0xEABE, 0x954C, 0x954D, 0xC0A5, 0x954E,
+ /* U+6608 */ 0x954F, 0x9550, 0xEABB, 0x9551, 0xB2FD, 0x9552, 0xC3F7, 0xBBE8,
+ /* U+6610 */ 0x9553, 0x9554, 0x9555, 0xD2D7, 0xCEF4, 0xEABF, 0x9556, 0x9557,
+ /* U+6618 */ 0x9558, 0xEABC, 0x9559, 0x955A, 0x955B, 0xEAC3, 0x955C, 0xD0C7,
+ /* U+6620 */ 0xD3B3, 0x955D, 0x955E, 0x955F, 0x9560, 0xB4BA, 0x9561, 0xC3C1,
+ /* U+6628 */ 0xD7F2, 0x9562, 0x9563, 0x9564, 0x9565, 0xD5D1, 0x9566, 0xCAC7,
+ /* U+6630 */ 0x9567, 0xEAC5, 0x9568, 0x9569, 0xEAC4, 0xEAC7, 0xEAC6, 0x956A,
+ /* U+6638 */ 0x956B, 0x956C, 0x956D, 0x956E, 0xD6E7, 0x956F, 0xCFD4, 0x9570,
+ /* U+6640 */ 0x9571, 0xEACB, 0x9572, 0xBBCE, 0x9573, 0x9574, 0x9575, 0x9576,
+ /* U+6648 */ 0x9577, 0x9578, 0x9579, 0xBDFA, 0xC9CE, 0x957A, 0x957B, 0xEACC,
+ /* U+6650 */ 0x957C, 0x957D, 0xC9B9, 0xCFFE, 0xEACA, 0xD4CE, 0xEACD, 0xEACF,
+ /* U+6658 */ 0x957E, 0x9580, 0xCDED, 0x9581, 0x9582, 0x9583, 0x9584, 0xEAC9,
+ /* U+6660 */ 0x9585, 0xEACE, 0x9586, 0x9587, 0xCEEE, 0x9588, 0xBBDE, 0x9589,
+ /* U+6668 */ 0xB3BF, 0x958A, 0x958B, 0x958C, 0x958D, 0x958E, 0xC6D5, 0xBEB0,
+ /* U+6670 */ 0xCEFA, 0x958F, 0x9590, 0x9591, 0xC7E7, 0x9592, 0xBEA7, 0xEAD0,
+ /* U+6678 */ 0x9593, 0x9594, 0xD6C7, 0x9595, 0x9596, 0x9597, 0xC1C0, 0x9598,
+ /* U+6680 */ 0x9599, 0x959A, 0xD4DD, 0x959B, 0xEAD1, 0x959C, 0x959D, 0xCFBE,
+ /* U+6688 */ 0x959E, 0x959F, 0x95A0, 0x95A1, 0xEAD2, 0x95A2, 0x95A3, 0x95A4,
+ /* U+6690 */ 0x95A5, 0xCAEE, 0x95A6, 0x95A7, 0x95A8, 0x95A9, 0xC5AF, 0xB0B5,
+ /* U+6698 */ 0x95AA, 0x95AB, 0x95AC, 0x95AD, 0x95AE, 0xEAD4, 0x95AF, 0x95B0,
+ /* U+66A0 */ 0x95B1, 0x95B2, 0x95B3, 0x95B4, 0x95B5, 0x95B6, 0x95B7, 0xEAD3,
+ /* U+66A8 */ 0xF4DF, 0x95B8, 0x95B9, 0x95BA, 0x95BB, 0x95BC, 0xC4BA, 0x95BD,
+ /* U+66B0 */ 0x95BE, 0x95BF, 0x95C0, 0x95C1, 0xB1A9, 0x95C2, 0x95C3, 0x95C4,
+ /* U+66B8 */ 0x95C5, 0xE5DF, 0x95C6, 0x95C7, 0x95C8, 0x95C9, 0xEAD5, 0x95CA,
+ /* U+66C0 */ 0x95CB, 0x95CC, 0x95CD, 0x95CE, 0x95CF, 0x95D0, 0x95D1, 0x95D2,
+ /* U+66C8 */ 0x95D3, 0x95D4, 0x95D5, 0x95D6, 0x95D7, 0x95D8, 0x95D9, 0x95DA,
+ /* U+66D0 */ 0x95DB, 0x95DC, 0x95DD, 0x95DE, 0x95DF, 0x95E0, 0x95E1, 0x95E2,
+ /* U+66D8 */ 0x95E3, 0xCAEF, 0x95E4, 0xEAD6, 0xEAD7, 0xC6D8, 0x95E5, 0x95E6,
+ /* U+66E0 */ 0x95E7, 0x95E8, 0x95E9, 0x95EA, 0x95EB, 0x95EC, 0xEAD8, 0x95ED,
+ /* U+66E8 */ 0x95EE, 0xEAD9, 0x95EF, 0x95F0, 0x95F1, 0x95F2, 0x95F3, 0x95F4,
+ /* U+66F0 */ 0xD4BB, 0x95F5, 0xC7FA, 0xD2B7, 0xB8FC, 0x95F6, 0x95F7, 0xEAC2,
+ /* U+66F8 */ 0x95F8, 0xB2DC, 0x95F9, 0x95FA, 0xC2FC, 0x95FB, 0xD4F8, 0xCCE6,
+ /* U+6700 */ 0xD7EE, 0x95FC, 0x95FD, 0x95FE, 0x9640, 0x9641, 0x9642, 0x9643,
+ /* U+6708 */ 0xD4C2, 0xD3D0, 0xEBC3, 0xC5F3, 0x9644, 0xB7FE, 0x9645, 0x9646,
+ /* U+6710 */ 0xEBD4, 0x9647, 0x9648, 0x9649, 0xCBB7, 0xEBDE, 0x964A, 0xC0CA,
+ /* U+6718 */ 0x964B, 0x964C, 0x964D, 0xCDFB, 0x964E, 0xB3AF, 0x964F, 0xC6DA,
+ /* U+6720 */ 0x9650, 0x9651, 0x9652, 0x9653, 0x9654, 0x9655, 0xEBFC, 0x9656,
+ /* U+6728 */ 0xC4BE, 0x9657, 0xCEB4, 0xC4A9, 0xB1BE, 0xD4FD, 0x9658, 0xCAF5,
+ /* U+6730 */ 0x9659, 0xD6EC, 0x965A, 0x965B, 0xC6D3, 0xB6E4, 0x965C, 0x965D,
+ /* U+6738 */ 0x965E, 0x965F, 0xBBFA, 0x9660, 0x9661, 0xD0E0, 0x9662, 0x9663,
+ /* U+6740 */ 0xC9B1, 0x9664, 0xD4D3, 0xC8A8, 0x9665, 0x9666, 0xB8CB, 0x9667,
+ /* U+6748 */ 0xE8BE, 0xC9BC, 0x9668, 0x9669, 0xE8BB, 0x966A, 0xC0EE, 0xD0D3,
+ /* U+6750 */ 0xB2C4, 0xB4E5, 0x966B, 0xE8BC, 0x966C, 0x966D, 0xD5C8, 0x966E,
+ /* U+6758 */ 0x966F, 0x9670, 0x9671, 0x9672, 0xB6C5, 0x9673, 0xE8BD, 0xCAF8,
+ /* U+6760 */ 0xB8DC, 0xCCF5, 0x9674, 0x9675, 0x9676, 0xC0B4, 0x9677, 0x9678,
+ /* U+6768 */ 0xD1EE, 0xE8BF, 0xE8C2, 0x9679, 0x967A, 0xBABC, 0x967B, 0xB1AD,
+ /* U+6770 */ 0xBDDC, 0x967C, 0xEABD, 0xE8C3, 0x967D, 0xE8C6, 0x967E, 0xE8CB,
+ /* U+6778 */ 0x9680, 0x9681, 0x9682, 0x9683, 0xE8CC, 0x9684, 0xCBC9, 0xB0E5,
+ /* U+6780 */ 0x9685, 0xBCAB, 0x9686, 0x9687, 0xB9B9, 0x9688, 0x9689, 0xE8C1,
+ /* U+6788 */ 0x968A, 0xCDF7, 0x968B, 0xE8CA, 0x968C, 0x968D, 0x968E, 0x968F,
+ /* U+6790 */ 0xCEF6, 0x9690, 0x9691, 0x9692, 0x9693, 0xD5ED, 0x9694, 0xC1D6,
+ /* U+6798 */ 0xE8C4, 0x9695, 0xC3B6, 0x9696, 0xB9FB, 0xD6A6, 0xE8C8, 0x9697,
+ /* U+67A0 */ 0x9698, 0x9699, 0xCAE0, 0xD4E6, 0x969A, 0xE8C0, 0x969B, 0xE8C5,
+ /* U+67A8 */ 0xE8C7, 0x969C, 0xC7B9, 0xB7E3, 0x969D, 0xE8C9, 0x969E, 0xBFDD,
+ /* U+67B0 */ 0xE8D2, 0x969F, 0x96A0, 0xE8D7, 0x96A1, 0xE8D5, 0xBCDC, 0xBCCF,
+ /* U+67B8 */ 0xE8DB, 0x96A2, 0x96A3, 0x96A4, 0x96A5, 0x96A6, 0x96A7, 0x96A8,
+ /* U+67C0 */ 0x96A9, 0xE8DE, 0x96AA, 0xE8DA, 0xB1FA, 0x96AB, 0x96AC, 0x96AD,
+ /* U+67C8 */ 0x96AE, 0x96AF, 0x96B0, 0x96B1, 0x96B2, 0x96B3, 0x96B4, 0xB0D8,
+ /* U+67D0 */ 0xC4B3, 0xB8CC, 0xC6E2, 0xC8BE, 0xC8E1, 0x96B5, 0x96B6, 0x96B7,
+ /* U+67D8 */ 0xE8CF, 0xE8D4, 0xE8D6, 0x96B8, 0xB9F1, 0xE8D8, 0xD7F5, 0x96B9,
+ /* U+67E0 */ 0xC4FB, 0x96BA, 0xE8DC, 0x96BB, 0x96BC, 0xB2E9, 0x96BD, 0x96BE,
+ /* U+67E8 */ 0x96BF, 0xE8D1, 0x96C0, 0x96C1, 0xBCED, 0x96C2, 0x96C3, 0xBFC2,
+ /* U+67F0 */ 0xE8CD, 0xD6F9, 0x96C4, 0xC1F8, 0xB2F1, 0x96C5, 0x96C6, 0x96C7,
+ /* U+67F8 */ 0x96C8, 0x96C9, 0x96CA, 0x96CB, 0x96CC, 0xE8DF, 0x96CD, 0xCAC1,
+ /* U+6800 */ 0xE8D9, 0x96CE, 0x96CF, 0x96D0, 0x96D1, 0xD5A4, 0x96D2, 0xB1EA,
+ /* U+6808 */ 0xD5BB, 0xE8CE, 0xE8D0, 0xB6B0, 0xE8D3, 0x96D3, 0xE8DD, 0xC0B8,
+ /* U+6810 */ 0x96D4, 0xCAF7, 0x96D5, 0xCBA8, 0x96D6, 0x96D7, 0xC6DC, 0xC0F5,
+ /* U+6818 */ 0x96D8, 0x96D9, 0x96DA, 0x96DB, 0x96DC, 0xE8E9, 0x96DD, 0x96DE,
+ /* U+6820 */ 0x96DF, 0xD0A3, 0x96E0, 0x96E1, 0x96E2, 0x96E3, 0x96E4, 0x96E5,
+ /* U+6828 */ 0x96E6, 0xE8F2, 0xD6EA, 0x96E7, 0x96E8, 0x96E9, 0x96EA, 0x96EB,
+ /* U+6830 */ 0x96EC, 0x96ED, 0xE8E0, 0xE8E1, 0x96EE, 0x96EF, 0x96F0, 0xD1F9,
+ /* U+6838 */ 0xBACB, 0xB8F9, 0x96F1, 0x96F2, 0xB8F1, 0xD4D4, 0xE8EF, 0x96F3,
+ /* U+6840 */ 0xE8EE, 0xE8EC, 0xB9F0, 0xCCD2, 0xE8E6, 0xCEA6, 0xBFF2, 0x96F4,
+ /* U+6848 */ 0xB0B8, 0xE8F1, 0xE8F0, 0x96F5, 0xD7C0, 0x96F6, 0xE8E4, 0x96F7,
+ /* U+6850 */ 0xCDA9, 0xC9A3, 0x96F8, 0xBBB8, 0xBDDB, 0xE8EA, 0x96F9, 0x96FA,
+ /* U+6858 */ 0x96FB, 0x96FC, 0x96FD, 0x96FE, 0x9740, 0x9741, 0x9742, 0x9743,
+ /* U+6860 */ 0xE8E2, 0xE8E3, 0xE8E5, 0xB5B5, 0xE8E7, 0xC7C5, 0xE8EB, 0xE8ED,
+ /* U+6868 */ 0xBDB0, 0xD7AE, 0x9744, 0xE8F8, 0x9745, 0x9746, 0x9747, 0x9748,
+ /* U+6870 */ 0x9749, 0x974A, 0x974B, 0x974C, 0xE8F5, 0x974D, 0xCDB0, 0xE8F6,
+ /* U+6878 */ 0x974E, 0x974F, 0x9750, 0x9751, 0x9752, 0x9753, 0x9754, 0x9755,
+ /* U+6880 */ 0x9756, 0xC1BA, 0x9757, 0xE8E8, 0x9758, 0xC3B7, 0xB0F0, 0x9759,
+ /* U+6888 */ 0x975A, 0x975B, 0x975C, 0x975D, 0x975E, 0x975F, 0x9760, 0xE8F4,
+ /* U+6890 */ 0x9761, 0x9762, 0x9763, 0xE8F7, 0x9764, 0x9765, 0x9766, 0xB9A3,
+ /* U+6898 */ 0x9767, 0x9768, 0x9769, 0x976A, 0x976B, 0x976C, 0x976D, 0x976E,
+ /* U+68A0 */ 0x976F, 0x9770, 0xC9D2, 0x9771, 0x9772, 0x9773, 0xC3CE, 0xCEE0,
+ /* U+68A8 */ 0xC0E6, 0x9774, 0x9775, 0x9776, 0x9777, 0xCBF3, 0x9778, 0xCCDD,
+ /* U+68B0 */ 0xD0B5, 0x9779, 0x977A, 0xCAE1, 0x977B, 0xE8F3, 0x977C, 0x977D,
+ /* U+68B8 */ 0x977E, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9785, 0x9786,
+ /* U+68C0 */ 0xBCEC, 0x9787, 0xE8F9, 0x9788, 0x9789, 0x978A, 0x978B, 0x978C,
+ /* U+68C8 */ 0x978D, 0xC3DE, 0x978E, 0xC6E5, 0x978F, 0xB9F7, 0x9790, 0x9791,
+ /* U+68D0 */ 0x9792, 0x9793, 0xB0F4, 0x9794, 0x9795, 0xD7D8, 0x9796, 0x9797,
+ /* U+68D8 */ 0xBCAC, 0x9798, 0xC5EF, 0x9799, 0x979A, 0x979B, 0x979C, 0x979D,
+ /* U+68E0 */ 0xCCC4, 0x979E, 0x979F, 0xE9A6, 0x97A0, 0x97A1, 0x97A2, 0x97A3,
+ /* U+68E8 */ 0x97A4, 0x97A5, 0x97A6, 0x97A7, 0x97A8, 0x97A9, 0xC9AD, 0x97AA,
+ /* U+68F0 */ 0xE9A2, 0xC0E2, 0x97AB, 0x97AC, 0x97AD, 0xBFC3, 0x97AE, 0x97AF,
+ /* U+68F8 */ 0x97B0, 0xE8FE, 0xB9D7, 0x97B1, 0xE8FB, 0x97B2, 0x97B3, 0x97B4,
+ /* U+6900 */ 0x97B5, 0xE9A4, 0x97B6, 0x97B7, 0x97B8, 0xD2CE, 0x97B9, 0x97BA,
+ /* U+6908 */ 0x97BB, 0x97BC, 0x97BD, 0xE9A3, 0x97BE, 0xD6B2, 0xD7B5, 0x97BF,
+ /* U+6910 */ 0xE9A7, 0x97C0, 0xBDB7, 0x97C1, 0x97C2, 0x97C3, 0x97C4, 0x97C5,
+ /* U+6918 */ 0x97C6, 0x97C7, 0x97C8, 0x97C9, 0x97CA, 0x97CB, 0x97CC, 0xE8FC,
+ /* U+6920 */ 0xE8FD, 0x97CD, 0x97CE, 0x97CF, 0xE9A1, 0x97D0, 0x97D1, 0x97D2,
+ /* U+6928 */ 0x97D3, 0x97D4, 0x97D5, 0x97D6, 0x97D7, 0xCDD6, 0x97D8, 0x97D9,
+ /* U+6930 */ 0xD2AC, 0x97DA, 0x97DB, 0x97DC, 0xE9B2, 0x97DD, 0x97DE, 0x97DF,
+ /* U+6938 */ 0x97E0, 0xE9A9, 0x97E1, 0x97E2, 0x97E3, 0xB4AA, 0x97E4, 0xB4BB,
+ /* U+6940 */ 0x97E5, 0x97E6, 0xE9AB, 0x97E7, 0x97E8, 0x97E9, 0x97EA, 0x97EB,
+ /* U+6948 */ 0x97EC, 0x97ED, 0x97EE, 0x97EF, 0x97F0, 0x97F1, 0x97F2, 0x97F3,
+ /* U+6950 */ 0x97F4, 0x97F5, 0x97F6, 0x97F7, 0xD0A8, 0x97F8, 0x97F9, 0xE9A5,
+ /* U+6958 */ 0x97FA, 0x97FB, 0xB3FE, 0x97FC, 0x97FD, 0xE9AC, 0xC0E3, 0x97FE,
+ /* U+6960 */ 0xE9AA, 0x9840, 0x9841, 0xE9B9, 0x9842, 0x9843, 0xE9B8, 0x9844,
+ /* U+6968 */ 0x9845, 0x9846, 0x9847, 0xE9AE, 0x9848, 0x9849, 0xE8FA, 0x984A,
+ /* U+6970 */ 0x984B, 0xE9A8, 0x984C, 0x984D, 0x984E, 0x984F, 0x9850, 0xBFAC,
+ /* U+6978 */ 0xE9B1, 0xE9BA, 0x9851, 0x9852, 0xC2A5, 0x9853, 0x9854, 0x9855,
+ /* U+6980 */ 0xE9AF, 0x9856, 0xB8C5, 0x9857, 0xE9AD, 0x9858, 0xD3DC, 0xE9B4,
+ /* U+6988 */ 0xE9B5, 0xE9B7, 0x9859, 0x985A, 0x985B, 0xE9C7, 0x985C, 0x985D,
+ /* U+6990 */ 0x985E, 0x985F, 0x9860, 0x9861, 0xC0C6, 0xE9C5, 0x9862, 0x9863,
+ /* U+6998 */ 0xE9B0, 0x9864, 0x9865, 0xE9BB, 0xB0F1, 0x9866, 0x9867, 0x9868,
+ /* U+69A0 */ 0x9869, 0x986A, 0x986B, 0x986C, 0x986D, 0x986E, 0x986F, 0xE9BC,
+ /* U+69A8 */ 0xD5A5, 0x9870, 0x9871, 0xE9BE, 0x9872, 0xE9BF, 0x9873, 0x9874,
+ /* U+69B0 */ 0x9875, 0xE9C1, 0x9876, 0x9877, 0xC1F1, 0x9878, 0x9879, 0xC8B6,
+ /* U+69B8 */ 0x987A, 0x987B, 0x987C, 0xE9BD, 0x987D, 0x987E, 0x9880, 0x9881,
+ /* U+69C0 */ 0x9882, 0xE9C2, 0x9883, 0x9884, 0x9885, 0x9886, 0x9887, 0x9888,
+ /* U+69C8 */ 0x9889, 0x988A, 0xE9C3, 0x988B, 0xE9B3, 0x988C, 0xE9B6, 0x988D,
+ /* U+69D0 */ 0xBBB1, 0x988E, 0x988F, 0x9890, 0xE9C0, 0x9891, 0x9892, 0x9893,
+ /* U+69D8 */ 0x9894, 0x9895, 0x9896, 0xBCF7, 0x9897, 0x9898, 0x9899, 0xE9C4,
+ /* U+69E0 */ 0xE9C6, 0x989A, 0x989B, 0x989C, 0x989D, 0x989E, 0x989F, 0x98A0,
+ /* U+69E8 */ 0x98A1, 0x98A2, 0x98A3, 0x98A4, 0x98A5, 0xE9CA, 0x98A6, 0x98A7,
+ /* U+69F0 */ 0x98A8, 0x98A9, 0xE9CE, 0x98AA, 0x98AB, 0x98AC, 0x98AD, 0x98AE,
+ /* U+69F8 */ 0x98AF, 0x98B0, 0x98B1, 0x98B2, 0x98B3, 0xB2DB, 0x98B4, 0xE9C8,
+ /* U+6A00 */ 0x98B5, 0x98B6, 0x98B7, 0x98B8, 0x98B9, 0x98BA, 0x98BB, 0x98BC,
+ /* U+6A08 */ 0x98BD, 0x98BE, 0xB7AE, 0x98BF, 0x98C0, 0x98C1, 0x98C2, 0x98C3,
+ /* U+6A10 */ 0x98C4, 0x98C5, 0x98C6, 0x98C7, 0x98C8, 0x98C9, 0x98CA, 0xE9CB,
+ /* U+6A18 */ 0xE9CC, 0x98CB, 0x98CC, 0x98CD, 0x98CE, 0x98CF, 0x98D0, 0xD5C1,
+ /* U+6A20 */ 0x98D1, 0xC4A3, 0x98D2, 0x98D3, 0x98D4, 0x98D5, 0x98D6, 0x98D7,
+ /* U+6A28 */ 0xE9D8, 0x98D8, 0xBAE1, 0x98D9, 0x98DA, 0x98DB, 0x98DC, 0xE9C9,
+ /* U+6A30 */ 0x98DD, 0xD3A3, 0x98DE, 0x98DF, 0x98E0, 0xE9D4, 0x98E1, 0x98E2,
+ /* U+6A38 */ 0x98E3, 0x98E4, 0x98E5, 0x98E6, 0x98E7, 0xE9D7, 0xE9D0, 0x98E8,
+ /* U+6A40 */ 0x98E9, 0x98EA, 0x98EB, 0x98EC, 0xE9CF, 0x98ED, 0x98EE, 0xC7C1,
+ /* U+6A48 */ 0x98EF, 0x98F0, 0x98F1, 0x98F2, 0x98F3, 0x98F4, 0x98F5, 0x98F6,
+ /* U+6A50 */ 0xE9D2, 0x98F7, 0x98F8, 0x98F9, 0x98FA, 0x98FB, 0x98FC, 0x98FD,
+ /* U+6A58 */ 0xE9D9, 0xB3C8, 0x98FE, 0xE9D3, 0x9940, 0x9941, 0x9942, 0x9943,
+ /* U+6A60 */ 0x9944, 0xCFF0, 0x9945, 0x9946, 0x9947, 0xE9CD, 0x9948, 0x9949,
+ /* U+6A68 */ 0x994A, 0x994B, 0x994C, 0x994D, 0x994E, 0x994F, 0x9950, 0x9951,
+ /* U+6A70 */ 0x9952, 0xB3F7, 0x9953, 0x9954, 0x9955, 0x9956, 0x9957, 0x9958,
+ /* U+6A78 */ 0x9959, 0xE9D6, 0x995A, 0x995B, 0xE9DA, 0x995C, 0x995D, 0x995E,
+ /* U+6A80 */ 0xCCB4, 0x995F, 0x9960, 0x9961, 0xCFAD, 0x9962, 0x9963, 0x9964,
+ /* U+6A88 */ 0x9965, 0x9966, 0x9967, 0x9968, 0x9969, 0x996A, 0xE9D5, 0x996B,
+ /* U+6A90 */ 0xE9DC, 0xE9DB, 0x996C, 0x996D, 0x996E, 0x996F, 0x9970, 0xE9DE,
+ /* U+6A98 */ 0x9971, 0x9972, 0x9973, 0x9974, 0x9975, 0x9976, 0x9977, 0x9978,
+ /* U+6AA0 */ 0xE9D1, 0x9979, 0x997A, 0x997B, 0x997C, 0x997D, 0x997E, 0x9980,
+ /* U+6AA8 */ 0x9981, 0xE9DD, 0x9982, 0xE9DF, 0xC3CA, 0x9983, 0x9984, 0x9985,
+ /* U+6AB0 */ 0x9986, 0x9987, 0x9988, 0x9989, 0x998A, 0x998B, 0x998C, 0x998D,
+ /* U+6AB8 */ 0x998E, 0x998F, 0x9990, 0x9991, 0x9992, 0x9993, 0x9994, 0x9995,
+ /* U+6AC0 */ 0x9996, 0x9997, 0x9998, 0x9999, 0x999A, 0x999B, 0x999C, 0x999D,
+ /* U+6AC8 */ 0x999E, 0x999F, 0x99A0, 0x99A1, 0x99A2, 0x99A3, 0x99A4, 0x99A5,
+ /* U+6AD0 */ 0x99A6, 0x99A7, 0x99A8, 0x99A9, 0x99AA, 0x99AB, 0x99AC, 0x99AD,
+ /* U+6AD8 */ 0x99AE, 0x99AF, 0x99B0, 0x99B1, 0x99B2, 0x99B3, 0x99B4, 0x99B5,
+ /* U+6AE0 */ 0x99B6, 0x99B7, 0x99B8, 0x99B9, 0x99BA, 0x99BB, 0x99BC, 0x99BD,
+ /* U+6AE8 */ 0x99BE, 0x99BF, 0x99C0, 0x99C1, 0x99C2, 0x99C3, 0x99C4, 0x99C5,
+ /* U+6AF0 */ 0x99C6, 0x99C7, 0x99C8, 0x99C9, 0x99CA, 0x99CB, 0x99CC, 0x99CD,
+ /* U+6AF8 */ 0x99CE, 0x99CF, 0x99D0, 0x99D1, 0x99D2, 0x99D3, 0x99D4, 0x99D5,
+ /* U+6B00 */ 0x99D6, 0x99D7, 0x99D8, 0x99D9, 0x99DA, 0x99DB, 0x99DC, 0x99DD,
+ /* U+6B08 */ 0x99DE, 0x99DF, 0x99E0, 0x99E1, 0x99E2, 0x99E3, 0x99E4, 0x99E5,
+ /* U+6B10 */ 0x99E6, 0x99E7, 0x99E8, 0x99E9, 0x99EA, 0x99EB, 0x99EC, 0x99ED,
+ /* U+6B18 */ 0x99EE, 0x99EF, 0x99F0, 0x99F1, 0x99F2, 0x99F3, 0x99F4, 0x99F5,
+ /* U+6B20 */ 0xC7B7, 0xB4CE, 0xBBB6, 0xD0C0, 0xECA3, 0x99F6, 0x99F7, 0xC5B7,
+ /* U+6B28 */ 0x99F8, 0x99F9, 0x99FA, 0x99FB, 0x99FC, 0x99FD, 0x99FE, 0x9A40,
+ /* U+6B30 */ 0x9A41, 0x9A42, 0xD3FB, 0x9A43, 0x9A44, 0x9A45, 0x9A46, 0xECA4,
+ /* U+6B38 */ 0x9A47, 0xECA5, 0xC6DB, 0x9A48, 0x9A49, 0x9A4A, 0xBFEE, 0x9A4B,
+ /* U+6B40 */ 0x9A4C, 0x9A4D, 0x9A4E, 0xECA6, 0x9A4F, 0x9A50, 0xECA7, 0xD0AA,
+ /* U+6B48 */ 0x9A51, 0xC7B8, 0x9A52, 0x9A53, 0xB8E8, 0x9A54, 0x9A55, 0x9A56,
+ /* U+6B50 */ 0x9A57, 0x9A58, 0x9A59, 0x9A5A, 0x9A5B, 0x9A5C, 0x9A5D, 0x9A5E,
+ /* U+6B58 */ 0x9A5F, 0xECA8, 0x9A60, 0x9A61, 0x9A62, 0x9A63, 0x9A64, 0x9A65,
+ /* U+6B60 */ 0x9A66, 0x9A67, 0xD6B9, 0xD5FD, 0xB4CB, 0xB2BD, 0xCEE4, 0xC6E7,
+ /* U+6B68 */ 0x9A68, 0x9A69, 0xCDE1, 0x9A6A, 0x9A6B, 0x9A6C, 0x9A6D, 0x9A6E,
+ /* U+6B70 */ 0x9A6F, 0x9A70, 0x9A71, 0x9A72, 0x9A73, 0x9A74, 0x9A75, 0x9A76,
+ /* U+6B78 */ 0x9A77, 0xB4F5, 0x9A78, 0xCBC0, 0xBCDF, 0x9A79, 0x9A7A, 0x9A7B,
+ /* U+6B80 */ 0x9A7C, 0xE9E2, 0xE9E3, 0xD1EA, 0xE9E5, 0x9A7D, 0xB4F9, 0xE9E4,
+ /* U+6B88 */ 0x9A7E, 0xD1B3, 0xCAE2, 0xB2D0, 0x9A80, 0xE9E8, 0x9A81, 0x9A82,
+ /* U+6B90 */ 0x9A83, 0x9A84, 0xE9E6, 0xE9E7, 0x9A85, 0x9A86, 0xD6B3, 0x9A87,
+ /* U+6B98 */ 0x9A88, 0x9A89, 0xE9E9, 0xE9EA, 0x9A8A, 0x9A8B, 0x9A8C, 0x9A8D,
+ /* U+6BA0 */ 0x9A8E, 0xE9EB, 0x9A8F, 0x9A90, 0x9A91, 0x9A92, 0x9A93, 0x9A94,
+ /* U+6BA8 */ 0x9A95, 0x9A96, 0xE9EC, 0x9A97, 0x9A98, 0x9A99, 0x9A9A, 0x9A9B,
+ /* U+6BB0 */ 0x9A9C, 0x9A9D, 0x9A9E, 0xECAF, 0xC5B9, 0xB6CE, 0x9A9F, 0xD2F3,
+ /* U+6BB8 */ 0x9AA0, 0x9AA1, 0x9AA2, 0x9AA3, 0x9AA4, 0x9AA5, 0x9AA6, 0xB5EE,
+ /* U+6BC0 */ 0x9AA7, 0xBBD9, 0xECB1, 0x9AA8, 0x9AA9, 0xD2E3, 0x9AAA, 0x9AAB,
+ /* U+6BC8 */ 0x9AAC, 0x9AAD, 0x9AAE, 0xCEE3, 0x9AAF, 0xC4B8, 0x9AB0, 0xC3BF,
+ /* U+6BD0 */ 0x9AB1, 0x9AB2, 0xB6BE, 0xD8B9, 0xB1C8, 0xB1CF, 0xB1D1, 0xC5FE,
+ /* U+6BD8 */ 0x9AB3, 0xB1D0, 0x9AB4, 0xC3AB, 0x9AB5, 0x9AB6, 0x9AB7, 0x9AB8,
+ /* U+6BE0 */ 0x9AB9, 0xD5B1, 0x9ABA, 0x9ABB, 0x9ABC, 0x9ABD, 0x9ABE, 0x9ABF,
+ /* U+6BE8 */ 0x9AC0, 0x9AC1, 0xEBA4, 0xBAC1, 0x9AC2, 0x9AC3, 0x9AC4, 0xCCBA,
+ /* U+6BF0 */ 0x9AC5, 0x9AC6, 0x9AC7, 0xEBA5, 0x9AC8, 0xEBA7, 0x9AC9, 0x9ACA,
+ /* U+6BF8 */ 0x9ACB, 0xEBA8, 0x9ACC, 0x9ACD, 0x9ACE, 0xEBA6, 0x9ACF, 0x9AD0,
+ /* U+6C00 */ 0x9AD1, 0x9AD2, 0x9AD3, 0x9AD4, 0x9AD5, 0xEBA9, 0xEBAB, 0xEBAA,
+ /* U+6C08 */ 0x9AD6, 0x9AD7, 0x9AD8, 0x9AD9, 0x9ADA, 0xEBAC, 0x9ADB, 0xCACF,
+ /* U+6C10 */ 0xD8B5, 0xC3F1, 0x9ADC, 0xC3A5, 0xC6F8, 0xEBAD, 0xC4CA, 0x9ADD,
+ /* U+6C18 */ 0xEBAE, 0xEBAF, 0xEBB0, 0xB7D5, 0x9ADE, 0x9ADF, 0x9AE0, 0xB7FA,
+ /* U+6C20 */ 0x9AE1, 0xEBB1, 0xC7E2, 0x9AE2, 0xEBB3, 0x9AE3, 0xBAA4, 0xD1F5,
+ /* U+6C28 */ 0xB0B1, 0xEBB2, 0xEBB4, 0x9AE4, 0x9AE5, 0x9AE6, 0xB5AA, 0xC2C8,
+ /* U+6C30 */ 0xC7E8, 0x9AE7, 0xEBB5, 0x9AE8, 0xCBAE, 0xE3DF, 0x9AE9, 0x9AEA,
+ /* U+6C38 */ 0xD3C0, 0x9AEB, 0x9AEC, 0x9AED, 0x9AEE, 0xD9DB, 0x9AEF, 0x9AF0,
+ /* U+6C40 */ 0xCDA1, 0xD6AD, 0xC7F3, 0x9AF1, 0x9AF2, 0x9AF3, 0xD9E0, 0xBBE3,
+ /* U+6C48 */ 0x9AF4, 0xBABA, 0xE3E2, 0x9AF5, 0x9AF6, 0x9AF7, 0x9AF8, 0x9AF9,
+ /* U+6C50 */ 0xCFAB, 0x9AFA, 0x9AFB, 0x9AFC, 0xE3E0, 0xC9C7, 0x9AFD, 0xBAB9,
+ /* U+6C58 */ 0x9AFE, 0x9B40, 0x9B41, 0xD1B4, 0xE3E1, 0xC8EA, 0xB9AF, 0xBDAD,
+ /* U+6C60 */ 0xB3D8, 0xCEDB, 0x9B42, 0x9B43, 0xCCC0, 0x9B44, 0x9B45, 0x9B46,
+ /* U+6C68 */ 0xE3E8, 0xE3E9, 0xCDF4, 0x9B47, 0x9B48, 0x9B49, 0x9B4A, 0x9B4B,
+ /* U+6C70 */ 0xCCAD, 0x9B4C, 0xBCB3, 0x9B4D, 0xE3EA, 0x9B4E, 0xE3EB, 0x9B4F,
+ /* U+6C78 */ 0x9B50, 0xD0DA, 0x9B51, 0x9B52, 0x9B53, 0xC6FB, 0xB7DA, 0x9B54,
+ /* U+6C80 */ 0x9B55, 0xC7DF, 0xD2CA, 0xCED6, 0x9B56, 0xE3E4, 0xE3EC, 0x9B57,
+ /* U+6C88 */ 0xC9F2, 0xB3C1, 0x9B58, 0x9B59, 0xE3E7, 0x9B5A, 0x9B5B, 0xC6E3,
+ /* U+6C90 */ 0xE3E5, 0x9B5C, 0x9B5D, 0xEDB3, 0xE3E6, 0x9B5E, 0x9B5F, 0x9B60,
+ /* U+6C98 */ 0x9B61, 0xC9B3, 0x9B62, 0xC5E6, 0x9B63, 0x9B64, 0x9B65, 0xB9B5,
+ /* U+6CA0 */ 0x9B66, 0xC3BB, 0x9B67, 0xE3E3, 0xC5BD, 0xC1A4, 0xC2D9, 0xB2D7,
+ /* U+6CA8 */ 0x9B68, 0xE3ED, 0xBBA6, 0xC4AD, 0x9B69, 0xE3F0, 0xBEDA, 0x9B6A,
+ /* U+6CB0 */ 0x9B6B, 0xE3FB, 0xE3F5, 0xBAD3, 0x9B6C, 0x9B6D, 0x9B6E, 0x9B6F,
+ /* U+6CB8 */ 0xB7D0, 0xD3CD, 0x9B70, 0xD6CE, 0xD5D3, 0xB9C1, 0xD5B4, 0xD1D8,
+ /* U+6CC0 */ 0x9B71, 0x9B72, 0x9B73, 0x9B74, 0xD0B9, 0xC7F6, 0x9B75, 0x9B76,
+ /* U+6CC8 */ 0x9B77, 0xC8AA, 0xB2B4, 0x9B78, 0xC3DA, 0x9B79, 0x9B7A, 0x9B7B,
+ /* U+6CD0 */ 0xE3EE, 0x9B7C, 0x9B7D, 0xE3FC, 0xE3EF, 0xB7A8, 0xE3F7, 0xE3F4,
+ /* U+6CD8 */ 0x9B7E, 0x9B80, 0x9B81, 0xB7BA, 0x9B82, 0x9B83, 0xC5A2, 0x9B84,
+ /* U+6CE0 */ 0xE3F6, 0xC5DD, 0xB2A8, 0xC6FC, 0x9B85, 0xC4E0, 0x9B86, 0x9B87,
+ /* U+6CE8 */ 0xD7A2, 0x9B88, 0xC0E1, 0xE3F9, 0x9B89, 0x9B8A, 0xE3FA, 0xE3FD,
+ /* U+6CF0 */ 0xCCA9, 0xE3F3, 0x9B8B, 0xD3BE, 0x9B8C, 0xB1C3, 0xEDB4, 0xE3F1,
+ /* U+6CF8 */ 0xE3F2, 0x9B8D, 0xE3F8, 0xD0BA, 0xC6C3, 0xD4F3, 0xE3FE, 0x9B8E,
+ /* U+6D00 */ 0x9B8F, 0xBDE0, 0x9B90, 0x9B91, 0xE4A7, 0x9B92, 0x9B93, 0xE4A6,
+ /* U+6D08 */ 0x9B94, 0x9B95, 0x9B96, 0xD1F3, 0xE4A3, 0x9B97, 0xE4A9, 0x9B98,
+ /* U+6D10 */ 0x9B99, 0x9B9A, 0xC8F7, 0x9B9B, 0x9B9C, 0x9B9D, 0x9B9E, 0xCFB4,
+ /* U+6D18 */ 0x9B9F, 0xE4A8, 0xE4AE, 0xC2E5, 0x9BA0, 0x9BA1, 0xB6B4, 0x9BA2,
+ /* U+6D20 */ 0x9BA3, 0x9BA4, 0x9BA5, 0x9BA6, 0x9BA7, 0xBDF2, 0x9BA8, 0xE4A2,
+ /* U+6D28 */ 0x9BA9, 0x9BAA, 0xBAE9, 0xE4AA, 0x9BAB, 0x9BAC, 0xE4AC, 0x9BAD,
+ /* U+6D30 */ 0x9BAE, 0xB6FD, 0xD6DE, 0xE4B2, 0x9BAF, 0xE4AD, 0x9BB0, 0x9BB1,
+ /* U+6D38 */ 0x9BB2, 0xE4A1, 0x9BB3, 0xBBEE, 0xCDDD, 0xC7A2, 0xC5C9, 0x9BB4,
+ /* U+6D40 */ 0x9BB5, 0xC1F7, 0x9BB6, 0xE4A4, 0x9BB7, 0xC7B3, 0xBDAC, 0xBDBD,
+ /* U+6D48 */ 0xE4A5, 0x9BB8, 0xD7C7, 0xB2E2, 0x9BB9, 0xE4AB, 0xBCC3, 0xE4AF,
+ /* U+6D50 */ 0x9BBA, 0xBBEB, 0xE4B0, 0xC5A8, 0xE4B1, 0x9BBB, 0x9BBC, 0x9BBD,
+ /* U+6D58 */ 0x9BBE, 0xD5E3, 0xBFA3, 0x9BBF, 0xE4BA, 0x9BC0, 0xE4B7, 0x9BC1,
+ /* U+6D60 */ 0xE4BB, 0x9BC2, 0x9BC3, 0xE4BD, 0x9BC4, 0x9BC5, 0xC6D6, 0x9BC6,
+ /* U+6D68 */ 0x9BC7, 0xBAC6, 0xC0CB, 0x9BC8, 0x9BC9, 0x9BCA, 0xB8A1, 0xE4B4,
+ /* U+6D70 */ 0x9BCB, 0x9BCC, 0x9BCD, 0x9BCE, 0xD4A1, 0x9BCF, 0x9BD0, 0xBAA3,
+ /* U+6D78 */ 0xBDFE, 0x9BD1, 0x9BD2, 0x9BD3, 0xE4BC, 0x9BD4, 0x9BD5, 0x9BD6,
+ /* U+6D80 */ 0x9BD7, 0x9BD8, 0xCDBF, 0x9BD9, 0x9BDA, 0xC4F9, 0x9BDB, 0x9BDC,
+ /* U+6D88 */ 0xCFFB, 0xC9E6, 0x9BDD, 0x9BDE, 0xD3BF, 0x9BDF, 0xCFD1, 0x9BE0,
+ /* U+6D90 */ 0x9BE1, 0xE4B3, 0x9BE2, 0xE4B8, 0xE4B9, 0xCCE9, 0x9BE3, 0x9BE4,
+ /* U+6D98 */ 0x9BE5, 0x9BE6, 0x9BE7, 0xCCCE, 0x9BE8, 0xC0D4, 0xE4B5, 0xC1B0,
+ /* U+6DA0 */ 0xE4B6, 0xCED0, 0x9BE9, 0xBBC1, 0xB5D3, 0x9BEA, 0xC8F3, 0xBDA7,
+ /* U+6DA8 */ 0xD5C7, 0xC9AC, 0xB8A2, 0xE4CA, 0x9BEB, 0x9BEC, 0xE4CC, 0xD1C4,
+ /* U+6DB0 */ 0x9BED, 0x9BEE, 0xD2BA, 0x9BEF, 0x9BF0, 0xBAAD, 0x9BF1, 0x9BF2,
+ /* U+6DB8 */ 0xBAD4, 0x9BF3, 0x9BF4, 0x9BF5, 0x9BF6, 0x9BF7, 0x9BF8, 0xE4C3,
+ /* U+6DC0 */ 0xB5ED, 0x9BF9, 0x9BFA, 0x9BFB, 0xD7CD, 0xE4C0, 0xCFFD, 0xE4BF,
+ /* U+6DC8 */ 0x9BFC, 0x9BFD, 0x9BFE, 0xC1DC, 0xCCCA, 0x9C40, 0x9C41, 0x9C42,
+ /* U+6DD0 */ 0x9C43, 0xCAE7, 0x9C44, 0x9C45, 0x9C46, 0x9C47, 0xC4D7, 0x9C48,
+ /* U+6DD8 */ 0xCCD4, 0xE4C8, 0x9C49, 0x9C4A, 0x9C4B, 0xE4C7, 0xE4C1, 0x9C4C,
+ /* U+6DE0 */ 0xE4C4, 0xB5AD, 0x9C4D, 0x9C4E, 0xD3D9, 0x9C4F, 0xE4C6, 0x9C50,
+ /* U+6DE8 */ 0x9C51, 0x9C52, 0x9C53, 0xD2F9, 0xB4E3, 0x9C54, 0xBBB4, 0x9C55,
+ /* U+6DF0 */ 0x9C56, 0xC9EE, 0x9C57, 0xB4BE, 0x9C58, 0x9C59, 0x9C5A, 0xBBEC,
+ /* U+6DF8 */ 0x9C5B, 0xD1CD, 0x9C5C, 0xCCED, 0xEDB5, 0x9C5D, 0x9C5E, 0x9C5F,
+ /* U+6E00 */ 0x9C60, 0x9C61, 0x9C62, 0x9C63, 0x9C64, 0xC7E5, 0x9C65, 0x9C66,
+ /* U+6E08 */ 0x9C67, 0x9C68, 0xD4A8, 0x9C69, 0xE4CB, 0xD7D5, 0xE4C2, 0x9C6A,
+ /* U+6E10 */ 0xBDA5, 0xE4C5, 0x9C6B, 0x9C6C, 0xD3E6, 0x9C6D, 0xE4C9, 0xC9F8,
+ /* U+6E18 */ 0x9C6E, 0x9C6F, 0xE4BE, 0x9C70, 0x9C71, 0xD3E5, 0x9C72, 0x9C73,
+ /* U+6E20 */ 0xC7FE, 0xB6C9, 0x9C74, 0xD4FC, 0xB2B3, 0xE4D7, 0x9C75, 0x9C76,
+ /* U+6E28 */ 0x9C77, 0xCEC2, 0x9C78, 0xE4CD, 0x9C79, 0xCEBC, 0x9C7A, 0xB8DB,
+ /* U+6E30 */ 0x9C7B, 0x9C7C, 0xE4D6, 0x9C7D, 0xBFCA, 0x9C7E, 0x9C80, 0x9C81,
+ /* U+6E38 */ 0xD3CE, 0x9C82, 0xC3EC, 0x9C83, 0x9C84, 0x9C85, 0x9C86, 0x9C87,
+ /* U+6E40 */ 0x9C88, 0x9C89, 0x9C8A, 0xC5C8, 0xE4D8, 0x9C8B, 0x9C8C, 0x9C8D,
+ /* U+6E48 */ 0x9C8E, 0x9C8F, 0x9C90, 0x9C91, 0x9C92, 0xCDC4, 0xE4CF, 0x9C93,
+ /* U+6E50 */ 0x9C94, 0x9C95, 0x9C96, 0xE4D4, 0xE4D5, 0x9C97, 0xBAFE, 0x9C98,
+ /* U+6E58 */ 0xCFE6, 0x9C99, 0x9C9A, 0xD5BF, 0x9C9B, 0x9C9C, 0x9C9D, 0xE4D2,
+ /* U+6E60 */ 0x9C9E, 0x9C9F, 0x9CA0, 0x9CA1, 0x9CA2, 0x9CA3, 0x9CA4, 0x9CA5,
+ /* U+6E68 */ 0x9CA6, 0x9CA7, 0x9CA8, 0xE4D0, 0x9CA9, 0x9CAA, 0xE4CE, 0x9CAB,
+ /* U+6E70 */ 0x9CAC, 0x9CAD, 0x9CAE, 0x9CAF, 0x9CB0, 0x9CB1, 0x9CB2, 0x9CB3,
+ /* U+6E78 */ 0x9CB4, 0x9CB5, 0x9CB6, 0x9CB7, 0x9CB8, 0x9CB9, 0xCDE5, 0xCAAA,
+ /* U+6E80 */ 0x9CBA, 0x9CBB, 0x9CBC, 0xC0A3, 0x9CBD, 0xBDA6, 0xE4D3, 0x9CBE,
+ /* U+6E88 */ 0x9CBF, 0xB8C8, 0x9CC0, 0x9CC1, 0x9CC2, 0x9CC3, 0x9CC4, 0xE4E7,
+ /* U+6E90 */ 0xD4B4, 0x9CC5, 0x9CC6, 0x9CC7, 0x9CC8, 0x9CC9, 0x9CCA, 0x9CCB,
+ /* U+6E98 */ 0xE4DB, 0x9CCC, 0x9CCD, 0x9CCE, 0xC1EF, 0x9CCF, 0x9CD0, 0xE4E9,
+ /* U+6EA0 */ 0x9CD1, 0x9CD2, 0xD2E7, 0x9CD3, 0x9CD4, 0xE4DF, 0x9CD5, 0xE4E0,
+ /* U+6EA8 */ 0x9CD6, 0x9CD7, 0xCFAA, 0x9CD8, 0x9CD9, 0x9CDA, 0x9CDB, 0xCBDD,
+ /* U+6EB0 */ 0x9CDC, 0xE4DA, 0xE4D1, 0x9CDD, 0xE4E5, 0x9CDE, 0xC8DC, 0xE4E3,
+ /* U+6EB8 */ 0x9CDF, 0x9CE0, 0xC4E7, 0xE4E2, 0x9CE1, 0xE4E1, 0x9CE2, 0x9CE3,
+ /* U+6EC0 */ 0x9CE4, 0xB3FC, 0xE4E8, 0x9CE5, 0x9CE6, 0x9CE7, 0x9CE8, 0xB5E1,
+ /* U+6EC8 */ 0x9CE9, 0x9CEA, 0x9CEB, 0xD7CC, 0x9CEC, 0x9CED, 0x9CEE, 0xE4E6,
+ /* U+6ED0 */ 0x9CEF, 0xBBAC, 0x9CF0, 0xD7D2, 0xCCCF, 0xEBF8, 0x9CF1, 0xE4E4,
+ /* U+6ED8 */ 0x9CF2, 0x9CF3, 0xB9F6, 0x9CF4, 0x9CF5, 0x9CF6, 0xD6CD, 0xE4D9,
+ /* U+6EE0 */ 0xE4DC, 0xC2FA, 0xE4DE, 0x9CF7, 0xC2CB, 0xC0C4, 0xC2D0, 0x9CF8,
+ /* U+6EE8 */ 0xB1F5, 0xCCB2, 0x9CF9, 0x9CFA, 0x9CFB, 0x9CFC, 0x9CFD, 0x9CFE,
+ /* U+6EF0 */ 0x9D40, 0x9D41, 0x9D42, 0x9D43, 0xB5CE, 0x9D44, 0x9D45, 0x9D46,
+ /* U+6EF8 */ 0x9D47, 0xE4EF, 0x9D48, 0x9D49, 0x9D4A, 0x9D4B, 0x9D4C, 0x9D4D,
+ /* U+6F00 */ 0x9D4E, 0x9D4F, 0xC6AF, 0x9D50, 0x9D51, 0x9D52, 0xC6E1, 0x9D53,
+ /* U+6F08 */ 0x9D54, 0xE4F5, 0x9D55, 0x9D56, 0x9D57, 0x9D58, 0x9D59, 0xC2A9,
+ /* U+6F10 */ 0x9D5A, 0x9D5B, 0x9D5C, 0xC0EC, 0xD1DD, 0xE4EE, 0x9D5D, 0x9D5E,
+ /* U+6F18 */ 0x9D5F, 0x9D60, 0x9D61, 0x9D62, 0x9D63, 0x9D64, 0x9D65, 0x9D66,
+ /* U+6F20 */ 0xC4AE, 0x9D67, 0x9D68, 0x9D69, 0xE4ED, 0x9D6A, 0x9D6B, 0x9D6C,
+ /* U+6F28 */ 0x9D6D, 0xE4F6, 0xE4F4, 0xC2FE, 0x9D6E, 0xE4DD, 0x9D6F, 0xE4F0,
+ /* U+6F30 */ 0x9D70, 0xCAFE, 0x9D71, 0xD5C4, 0x9D72, 0x9D73, 0xE4F1, 0x9D74,
+ /* U+6F38 */ 0x9D75, 0x9D76, 0x9D77, 0x9D78, 0x9D79, 0x9D7A, 0xD1FA, 0x9D7B,
+ /* U+6F40 */ 0x9D7C, 0x9D7D, 0x9D7E, 0x9D80, 0x9D81, 0x9D82, 0xE4EB, 0xE4EC,
+ /* U+6F48 */ 0x9D83, 0x9D84, 0x9D85, 0xE4F2, 0x9D86, 0xCEAB, 0x9D87, 0x9D88,
+ /* U+6F50 */ 0x9D89, 0x9D8A, 0x9D8B, 0x9D8C, 0x9D8D, 0x9D8E, 0x9D8F, 0x9D90,
+ /* U+6F58 */ 0xC5CB, 0x9D91, 0x9D92, 0x9D93, 0xC7B1, 0x9D94, 0xC2BA, 0x9D95,
+ /* U+6F60 */ 0x9D96, 0x9D97, 0xE4EA, 0x9D98, 0x9D99, 0x9D9A, 0xC1CA, 0x9D9B,
+ /* U+6F68 */ 0x9D9C, 0x9D9D, 0x9D9E, 0x9D9F, 0x9DA0, 0xCCB6, 0xB3B1, 0x9DA1,
+ /* U+6F70 */ 0x9DA2, 0x9DA3, 0xE4FB, 0x9DA4, 0xE4F3, 0x9DA5, 0x9DA6, 0x9DA7,
+ /* U+6F78 */ 0xE4FA, 0x9DA8, 0xE4FD, 0x9DA9, 0xE4FC, 0x9DAA, 0x9DAB, 0x9DAC,
+ /* U+6F80 */ 0x9DAD, 0x9DAE, 0x9DAF, 0x9DB0, 0xB3CE, 0x9DB1, 0x9DB2, 0x9DB3,
+ /* U+6F88 */ 0xB3BA, 0xE4F7, 0x9DB4, 0x9DB5, 0xE4F9, 0xE4F8, 0xC5EC, 0x9DB6,
+ /* U+6F90 */ 0x9DB7, 0x9DB8, 0x9DB9, 0x9DBA, 0x9DBB, 0x9DBC, 0x9DBD, 0x9DBE,
+ /* U+6F98 */ 0x9DBF, 0x9DC0, 0x9DC1, 0x9DC2, 0xC0BD, 0x9DC3, 0x9DC4, 0x9DC5,
+ /* U+6FA0 */ 0x9DC6, 0xD4E8, 0x9DC7, 0x9DC8, 0x9DC9, 0x9DCA, 0x9DCB, 0xE5A2,
+ /* U+6FA8 */ 0x9DCC, 0x9DCD, 0x9DCE, 0x9DCF, 0x9DD0, 0x9DD1, 0x9DD2, 0x9DD3,
+ /* U+6FB0 */ 0x9DD4, 0x9DD5, 0x9DD6, 0xB0C4, 0x9DD7, 0x9DD8, 0xE5A4, 0x9DD9,
+ /* U+6FB8 */ 0x9DDA, 0xE5A3, 0x9DDB, 0x9DDC, 0x9DDD, 0x9DDE, 0x9DDF, 0x9DE0,
+ /* U+6FC0 */ 0xBCA4, 0x9DE1, 0xE5A5, 0x9DE2, 0x9DE3, 0x9DE4, 0x9DE5, 0x9DE6,
+ /* U+6FC8 */ 0x9DE7, 0xE5A1, 0x9DE8, 0x9DE9, 0x9DEA, 0x9DEB, 0x9DEC, 0x9DED,
+ /* U+6FD0 */ 0x9DEE, 0xE4FE, 0xB1F4, 0x9DEF, 0x9DF0, 0x9DF1, 0x9DF2, 0x9DF3,
+ /* U+6FD8 */ 0x9DF4, 0x9DF5, 0x9DF6, 0x9DF7, 0x9DF8, 0x9DF9, 0xE5A8, 0x9DFA,
+ /* U+6FE0 */ 0xE5A9, 0xE5A6, 0x9DFB, 0x9DFC, 0x9DFD, 0x9DFE, 0x9E40, 0x9E41,
+ /* U+6FE8 */ 0x9E42, 0x9E43, 0x9E44, 0x9E45, 0x9E46, 0x9E47, 0xE5A7, 0xE5AA,
+ /* U+6FF0 */ 0x9E48, 0x9E49, 0x9E4A, 0x9E4B, 0x9E4C, 0x9E4D, 0x9E4E, 0x9E4F,
+ /* U+6FF8 */ 0x9E50, 0x9E51, 0x9E52, 0x9E53, 0x9E54, 0x9E55, 0x9E56, 0x9E57,
+ /* U+7000 */ 0x9E58, 0x9E59, 0x9E5A, 0x9E5B, 0x9E5C, 0x9E5D, 0x9E5E, 0x9E5F,
+ /* U+7008 */ 0x9E60, 0x9E61, 0x9E62, 0x9E63, 0x9E64, 0x9E65, 0x9E66, 0x9E67,
+ /* U+7010 */ 0x9E68, 0xC6D9, 0x9E69, 0x9E6A, 0x9E6B, 0x9E6C, 0x9E6D, 0x9E6E,
+ /* U+7018 */ 0x9E6F, 0x9E70, 0xE5AB, 0xE5AD, 0x9E71, 0x9E72, 0x9E73, 0x9E74,
+ /* U+7020 */ 0x9E75, 0x9E76, 0x9E77, 0xE5AC, 0x9E78, 0x9E79, 0x9E7A, 0x9E7B,
+ /* U+7028 */ 0x9E7C, 0x9E7D, 0x9E7E, 0x9E80, 0x9E81, 0x9E82, 0x9E83, 0x9E84,
+ /* U+7030 */ 0x9E85, 0x9E86, 0x9E87, 0x9E88, 0x9E89, 0xE5AF, 0x9E8A, 0x9E8B,
+ /* U+7038 */ 0x9E8C, 0xE5AE, 0x9E8D, 0x9E8E, 0x9E8F, 0x9E90, 0x9E91, 0x9E92,
+ /* U+7040 */ 0x9E93, 0x9E94, 0x9E95, 0x9E96, 0x9E97, 0x9E98, 0x9E99, 0x9E9A,
+ /* U+7048 */ 0x9E9B, 0x9E9C, 0x9E9D, 0x9E9E, 0xB9E0, 0x9E9F, 0x9EA0, 0xE5B0,
+ /* U+7050 */ 0x9EA1, 0x9EA2, 0x9EA3, 0x9EA4, 0x9EA5, 0x9EA6, 0x9EA7, 0x9EA8,
+ /* U+7058 */ 0x9EA9, 0x9EAA, 0x9EAB, 0x9EAC, 0x9EAD, 0x9EAE, 0xE5B1, 0x9EAF,
+ /* U+7060 */ 0x9EB0, 0x9EB1, 0x9EB2, 0x9EB3, 0x9EB4, 0x9EB5, 0x9EB6, 0x9EB7,
+ /* U+7068 */ 0x9EB8, 0x9EB9, 0x9EBA, 0xBBF0, 0xECE1, 0xC3F0, 0x9EBB, 0xB5C6,
+ /* U+7070 */ 0xBBD2, 0x9EBC, 0x9EBD, 0x9EBE, 0x9EBF, 0xC1E9, 0xD4EE, 0x9EC0,
+ /* U+7078 */ 0xBEC4, 0x9EC1, 0x9EC2, 0x9EC3, 0xD7C6, 0x9EC4, 0xD4D6, 0xB2D3,
+ /* U+7080 */ 0xECBE, 0x9EC5, 0x9EC6, 0x9EC7, 0x9EC8, 0xEAC1, 0x9EC9, 0x9ECA,
+ /* U+7088 */ 0x9ECB, 0xC2AF, 0xB4B6, 0x9ECC, 0x9ECD, 0x9ECE, 0xD1D7, 0x9ECF,
+ /* U+7090 */ 0x9ED0, 0x9ED1, 0xB3B4, 0x9ED2, 0xC8B2, 0xBFBB, 0xECC0, 0x9ED3,
+ /* U+7098 */ 0x9ED4, 0xD6CB, 0x9ED5, 0x9ED6, 0xECBF, 0xECC1, 0x9ED7, 0x9ED8,
+ /* U+70A0 */ 0x9ED9, 0x9EDA, 0x9EDB, 0x9EDC, 0x9EDD, 0x9EDE, 0x9EDF, 0x9EE0,
+ /* U+70A8 */ 0x9EE1, 0x9EE2, 0x9EE3, 0xECC5, 0xBEE6, 0xCCBF, 0xC5DA, 0xBEBC,
+ /* U+70B0 */ 0x9EE4, 0xECC6, 0x9EE5, 0xB1FE, 0x9EE6, 0x9EE7, 0x9EE8, 0xECC4,
+ /* U+70B8 */ 0xD5A8, 0xB5E3, 0x9EE9, 0xECC2, 0xC1B6, 0xB3E3, 0x9EEA, 0x9EEB,
+ /* U+70C0 */ 0xECC3, 0xCBB8, 0xC0C3, 0xCCFE, 0x9EEC, 0x9EED, 0x9EEE, 0x9EEF,
+ /* U+70C8 */ 0xC1D2, 0x9EF0, 0xECC8, 0x9EF1, 0x9EF2, 0x9EF3, 0x9EF4, 0x9EF5,
+ /* U+70D0 */ 0x9EF6, 0x9EF7, 0x9EF8, 0x9EF9, 0x9EFA, 0x9EFB, 0x9EFC, 0x9EFD,
+ /* U+70D8 */ 0xBAE6, 0xC0D3, 0x9EFE, 0xD6F2, 0x9F40, 0x9F41, 0x9F42, 0xD1CC,
+ /* U+70E0 */ 0x9F43, 0x9F44, 0x9F45, 0x9F46, 0xBFBE, 0x9F47, 0xB7B3, 0xC9D5,
+ /* U+70E8 */ 0xECC7, 0xBBE2, 0x9F48, 0xCCCC, 0xBDFD, 0xC8C8, 0x9F49, 0xCFA9,
+ /* U+70F0 */ 0x9F4A, 0x9F4B, 0x9F4C, 0x9F4D, 0x9F4E, 0x9F4F, 0x9F50, 0xCDE9,
+ /* U+70F8 */ 0x9F51, 0xC5EB, 0x9F52, 0x9F53, 0x9F54, 0xB7E9, 0x9F55, 0x9F56,
+ /* U+7100 */ 0x9F57, 0x9F58, 0x9F59, 0x9F5A, 0x9F5B, 0x9F5C, 0x9F5D, 0x9F5E,
+ /* U+7108 */ 0x9F5F, 0xD1C9, 0xBAB8, 0x9F60, 0x9F61, 0x9F62, 0x9F63, 0x9F64,
+ /* U+7110 */ 0xECC9, 0x9F65, 0x9F66, 0xECCA, 0x9F67, 0xBBC0, 0xECCB, 0x9F68,
+ /* U+7118 */ 0xECE2, 0xB1BA, 0xB7D9, 0x9F69, 0x9F6A, 0x9F6B, 0x9F6C, 0x9F6D,
+ /* U+7120 */ 0x9F6E, 0x9F6F, 0x9F70, 0x9F71, 0x9F72, 0x9F73, 0xBDB9, 0x9F74,
+ /* U+7128 */ 0x9F75, 0x9F76, 0x9F77, 0x9F78, 0x9F79, 0x9F7A, 0x9F7B, 0xECCC,
+ /* U+7130 */ 0xD1E6, 0xECCD, 0x9F7C, 0x9F7D, 0x9F7E, 0x9F80, 0xC8BB, 0x9F81,
+ /* U+7138 */ 0x9F82, 0x9F83, 0x9F84, 0x9F85, 0x9F86, 0x9F87, 0x9F88, 0x9F89,
+ /* U+7140 */ 0x9F8A, 0x9F8B, 0x9F8C, 0x9F8D, 0x9F8E, 0xECD1, 0x9F8F, 0x9F90,
+ /* U+7148 */ 0x9F91, 0x9F92, 0xECD3, 0x9F93, 0xBBCD, 0x9F94, 0xBCE5, 0x9F95,
+ /* U+7150 */ 0x9F96, 0x9F97, 0x9F98, 0x9F99, 0x9F9A, 0x9F9B, 0x9F9C, 0x9F9D,
+ /* U+7158 */ 0x9F9E, 0x9F9F, 0x9FA0, 0x9FA1, 0xECCF, 0x9FA2, 0xC9B7, 0x9FA3,
+ /* U+7160 */ 0x9FA4, 0x9FA5, 0x9FA6, 0x9FA7, 0xC3BA, 0x9FA8, 0xECE3, 0xD5D5,
+ /* U+7168 */ 0xECD0, 0x9FA9, 0x9FAA, 0x9FAB, 0x9FAC, 0x9FAD, 0xD6F3, 0x9FAE,
+ /* U+7170 */ 0x9FAF, 0x9FB0, 0xECD2, 0xECCE, 0x9FB1, 0x9FB2, 0x9FB3, 0x9FB4,
+ /* U+7178 */ 0xECD4, 0x9FB5, 0xECD5, 0x9FB6, 0x9FB7, 0xC9BF, 0x9FB8, 0x9FB9,
+ /* U+7180 */ 0x9FBA, 0x9FBB, 0x9FBC, 0x9FBD, 0xCFA8, 0x9FBE, 0x9FBF, 0x9FC0,
+ /* U+7188 */ 0x9FC1, 0x9FC2, 0xD0DC, 0x9FC3, 0x9FC4, 0x9FC5, 0x9FC6, 0xD1AC,
+ /* U+7190 */ 0x9FC7, 0x9FC8, 0x9FC9, 0x9FCA, 0xC8DB, 0x9FCB, 0x9FCC, 0x9FCD,
+ /* U+7198 */ 0xECD6, 0xCEF5, 0x9FCE, 0x9FCF, 0x9FD0, 0x9FD1, 0x9FD2, 0xCAEC,
+ /* U+71A0 */ 0xECDA, 0x9FD3, 0x9FD4, 0x9FD5, 0x9FD6, 0x9FD7, 0x9FD8, 0x9FD9,
+ /* U+71A8 */ 0xECD9, 0x9FDA, 0x9FDB, 0x9FDC, 0xB0BE, 0x9FDD, 0x9FDE, 0x9FDF,
+ /* U+71B0 */ 0x9FE0, 0x9FE1, 0x9FE2, 0xECD7, 0x9FE3, 0xECD8, 0x9FE4, 0x9FE5,
+ /* U+71B8 */ 0x9FE6, 0xECE4, 0x9FE7, 0x9FE8, 0x9FE9, 0x9FEA, 0x9FEB, 0x9FEC,
+ /* U+71C0 */ 0x9FED, 0x9FEE, 0x9FEF, 0xC8BC, 0x9FF0, 0x9FF1, 0x9FF2, 0x9FF3,
+ /* U+71C8 */ 0x9FF4, 0x9FF5, 0x9FF6, 0x9FF7, 0x9FF8, 0x9FF9, 0xC1C7, 0x9FFA,
+ /* U+71D0 */ 0x9FFB, 0x9FFC, 0x9FFD, 0x9FFE, 0xECDC, 0xD1E0, 0xA040, 0xA041,
+ /* U+71D8 */ 0xA042, 0xA043, 0xA044, 0xA045, 0xA046, 0xA047, 0xA048, 0xA049,
+ /* U+71E0 */ 0xECDB, 0xA04A, 0xA04B, 0xA04C, 0xA04D, 0xD4EF, 0xA04E, 0xECDD,
+ /* U+71E8 */ 0xA04F, 0xA050, 0xA051, 0xA052, 0xA053, 0xA054, 0xDBC6, 0xA055,
+ /* U+71F0 */ 0xA056, 0xA057, 0xA058, 0xA059, 0xA05A, 0xA05B, 0xA05C, 0xA05D,
+ /* U+71F8 */ 0xA05E, 0xECDE, 0xA05F, 0xA060, 0xA061, 0xA062, 0xA063, 0xA064,
+ /* U+7200 */ 0xA065, 0xA066, 0xA067, 0xA068, 0xA069, 0xA06A, 0xB1AC, 0xA06B,
+ /* U+7208 */ 0xA06C, 0xA06D, 0xA06E, 0xA06F, 0xA070, 0xA071, 0xA072, 0xA073,
+ /* U+7210 */ 0xA074, 0xA075, 0xA076, 0xA077, 0xA078, 0xA079, 0xA07A, 0xA07B,
+ /* U+7218 */ 0xA07C, 0xA07D, 0xA07E, 0xA080, 0xA081, 0xECDF, 0xA082, 0xA083,
+ /* U+7220 */ 0xA084, 0xA085, 0xA086, 0xA087, 0xA088, 0xA089, 0xA08A, 0xA08B,
+ /* U+7228 */ 0xECE0, 0xA08C, 0xD7A6, 0xA08D, 0xC5C0, 0xA08E, 0xA08F, 0xA090,
+ /* U+7230 */ 0xEBBC, 0xB0AE, 0xA091, 0xA092, 0xA093, 0xBEF4, 0xB8B8, 0xD2AF,
+ /* U+7238 */ 0xB0D6, 0xB5F9, 0xA094, 0xD8B3, 0xA095, 0xCBAC, 0xA096, 0xE3DD,
+ /* U+7240 */ 0xA097, 0xA098, 0xA099, 0xA09A, 0xA09B, 0xA09C, 0xA09D, 0xC6AC,
+ /* U+7248 */ 0xB0E6, 0xA09E, 0xA09F, 0xA0A0, 0xC5C6, 0xEBB9, 0xA0A1, 0xA0A2,
+ /* U+7250 */ 0xA0A3, 0xA0A4, 0xEBBA, 0xA0A5, 0xA0A6, 0xA0A7, 0xEBBB, 0xA0A8,
+ /* U+7258 */ 0xA0A9, 0xD1C0, 0xA0AA, 0xC5A3, 0xA0AB, 0xEAF2, 0xA0AC, 0xC4B2,
+ /* U+7260 */ 0xA0AD, 0xC4B5, 0xC0CE, 0xA0AE, 0xA0AF, 0xA0B0, 0xEAF3, 0xC4C1,
+ /* U+7268 */ 0xA0B1, 0xCEEF, 0xA0B2, 0xA0B3, 0xA0B4, 0xA0B5, 0xEAF0, 0xEAF4,
+ /* U+7270 */ 0xA0B6, 0xA0B7, 0xC9FC, 0xA0B8, 0xA0B9, 0xC7A3, 0xA0BA, 0xA0BB,
+ /* U+7278 */ 0xA0BC, 0xCCD8, 0xCEFE, 0xA0BD, 0xA0BE, 0xA0BF, 0xEAF5, 0xEAF6,
+ /* U+7280 */ 0xCFAC, 0xC0E7, 0xA0C0, 0xA0C1, 0xEAF7, 0xA0C2, 0xA0C3, 0xA0C4,
+ /* U+7288 */ 0xA0C5, 0xA0C6, 0xB6BF, 0xEAF8, 0xA0C7, 0xEAF9, 0xA0C8, 0xEAFA,
+ /* U+7290 */ 0xA0C9, 0xA0CA, 0xEAFB, 0xA0CB, 0xA0CC, 0xA0CD, 0xA0CE, 0xA0CF,
+ /* U+7298 */ 0xA0D0, 0xA0D1, 0xA0D2, 0xA0D3, 0xA0D4, 0xA0D5, 0xA0D6, 0xEAF1,
+ /* U+72A0 */ 0xA0D7, 0xA0D8, 0xA0D9, 0xA0DA, 0xA0DB, 0xA0DC, 0xA0DD, 0xA0DE,
+ /* U+72A8 */ 0xA0DF, 0xA0E0, 0xA0E1, 0xA0E2, 0xC8AE, 0xE1EB, 0xA0E3, 0xB7B8,
+ /* U+72B0 */ 0xE1EC, 0xA0E4, 0xA0E5, 0xA0E6, 0xE1ED, 0xA0E7, 0xD7B4, 0xE1EE,
+ /* U+72B8 */ 0xE1EF, 0xD3CC, 0xA0E8, 0xA0E9, 0xA0EA, 0xA0EB, 0xA0EC, 0xA0ED,
+ /* U+72C0 */ 0xA0EE, 0xE1F1, 0xBFF1, 0xE1F0, 0xB5D2, 0xA0EF, 0xA0F0, 0xA0F1,
+ /* U+72C8 */ 0xB1B7, 0xA0F2, 0xA0F3, 0xA0F4, 0xA0F5, 0xE1F3, 0xE1F2, 0xA0F6,
+ /* U+72D0 */ 0xBAFC, 0xA0F7, 0xE1F4, 0xA0F8, 0xA0F9, 0xA0FA, 0xA0FB, 0xB9B7,
+ /* U+72D8 */ 0xA0FC, 0xBED1, 0xA0FD, 0xA0FE, 0xAA40, 0xAA41, 0xC4FC, 0xAA42,
+ /* U+72E0 */ 0xBADD, 0xBDC6, 0xAA43, 0xAA44, 0xAA45, 0xAA46, 0xAA47, 0xAA48,
+ /* U+72E8 */ 0xE1F5, 0xE1F7, 0xAA49, 0xAA4A, 0xB6C0, 0xCFC1, 0xCAA8, 0xE1F6,
+ /* U+72F0 */ 0xD5F8, 0xD3FC, 0xE1F8, 0xE1FC, 0xE1F9, 0xAA4B, 0xAA4C, 0xE1FA,
+ /* U+72F8 */ 0xC0EA, 0xAA4D, 0xE1FE, 0xE2A1, 0xC0C7, 0xAA4E, 0xAA4F, 0xAA50,
+ /* U+7300 */ 0xAA51, 0xE1FB, 0xAA52, 0xE1FD, 0xAA53, 0xAA54, 0xAA55, 0xAA56,
+ /* U+7308 */ 0xAA57, 0xAA58, 0xE2A5, 0xAA59, 0xAA5A, 0xAA5B, 0xC1D4, 0xAA5C,
+ /* U+7310 */ 0xAA5D, 0xAA5E, 0xAA5F, 0xE2A3, 0xAA60, 0xE2A8, 0xB2FE, 0xE2A2,
+ /* U+7318 */ 0xAA61, 0xAA62, 0xAA63, 0xC3CD, 0xB2C2, 0xE2A7, 0xE2A6, 0xAA64,
+ /* U+7320 */ 0xAA65, 0xE2A4, 0xE2A9, 0xAA66, 0xAA67, 0xE2AB, 0xAA68, 0xAA69,
+ /* U+7328 */ 0xAA6A, 0xD0C9, 0xD6ED, 0xC3A8, 0xE2AC, 0xAA6B, 0xCFD7, 0xAA6C,
+ /* U+7330 */ 0xAA6D, 0xE2AE, 0xAA6E, 0xAA6F, 0xBAEF, 0xAA70, 0xAA71, 0xE9E0,
+ /* U+7338 */ 0xE2AD, 0xE2AA, 0xAA72, 0xAA73, 0xAA74, 0xAA75, 0xBBAB, 0xD4B3,
+ /* U+7340 */ 0xAA76, 0xAA77, 0xAA78, 0xAA79, 0xAA7A, 0xAA7B, 0xAA7C, 0xAA7D,
+ /* U+7348 */ 0xAA7E, 0xAA80, 0xAA81, 0xAA82, 0xAA83, 0xE2B0, 0xAA84, 0xAA85,
+ /* U+7350 */ 0xE2AF, 0xAA86, 0xE9E1, 0xAA87, 0xAA88, 0xAA89, 0xAA8A, 0xE2B1,
+ /* U+7358 */ 0xAA8B, 0xAA8C, 0xAA8D, 0xAA8E, 0xAA8F, 0xAA90, 0xAA91, 0xAA92,
+ /* U+7360 */ 0xE2B2, 0xAA93, 0xAA94, 0xAA95, 0xAA96, 0xAA97, 0xAA98, 0xAA99,
+ /* U+7368 */ 0xAA9A, 0xAA9B, 0xAA9C, 0xAA9D, 0xE2B3, 0xCCA1, 0xAA9E, 0xE2B4,
+ /* U+7370 */ 0xAA9F, 0xAAA0, 0xAB40, 0xAB41, 0xAB42, 0xAB43, 0xAB44, 0xAB45,
+ /* U+7378 */ 0xAB46, 0xAB47, 0xAB48, 0xAB49, 0xAB4A, 0xAB4B, 0xE2B5, 0xAB4C,
+ /* U+7380 */ 0xAB4D, 0xAB4E, 0xAB4F, 0xAB50, 0xD0FE, 0xAB51, 0xAB52, 0xC2CA,
+ /* U+7388 */ 0xAB53, 0xD3F1, 0xAB54, 0xCDF5, 0xAB55, 0xAB56, 0xE7E0, 0xAB57,
+ /* U+7390 */ 0xAB58, 0xE7E1, 0xAB59, 0xAB5A, 0xAB5B, 0xAB5C, 0xBEC1, 0xAB5D,
+ /* U+7398 */ 0xAB5E, 0xAB5F, 0xAB60, 0xC2EA, 0xAB61, 0xAB62, 0xAB63, 0xE7E4,
+ /* U+73A0 */ 0xAB64, 0xAB65, 0xE7E3, 0xAB66, 0xAB67, 0xAB68, 0xAB69, 0xAB6A,
+ /* U+73A8 */ 0xAB6B, 0xCDE6, 0xAB6C, 0xC3B5, 0xAB6D, 0xAB6E, 0xE7E2, 0xBBB7,
+ /* U+73B0 */ 0xCFD6, 0xAB6F, 0xC1E1, 0xE7E9, 0xAB70, 0xAB71, 0xAB72, 0xE7E8,
+ /* U+73B8 */ 0xAB73, 0xAB74, 0xE7F4, 0xB2A3, 0xAB75, 0xAB76, 0xAB77, 0xAB78,
+ /* U+73C0 */ 0xE7EA, 0xAB79, 0xE7E6, 0xAB7A, 0xAB7B, 0xAB7C, 0xAB7D, 0xAB7E,
+ /* U+73C8 */ 0xE7EC, 0xE7EB, 0xC9BA, 0xAB80, 0xAB81, 0xD5E4, 0xAB82, 0xE7E5,
+ /* U+73D0 */ 0xB7A9, 0xE7E7, 0xAB83, 0xAB84, 0xAB85, 0xAB86, 0xAB87, 0xAB88,
+ /* U+73D8 */ 0xAB89, 0xE7EE, 0xAB8A, 0xAB8B, 0xAB8C, 0xAB8D, 0xE7F3, 0xAB8E,
+ /* U+73E0 */ 0xD6E9, 0xAB8F, 0xAB90, 0xAB91, 0xAB92, 0xE7ED, 0xAB93, 0xE7F2,
+ /* U+73E8 */ 0xAB94, 0xE7F1, 0xAB95, 0xAB96, 0xAB97, 0xB0E0, 0xAB98, 0xAB99,
+ /* U+73F0 */ 0xAB9A, 0xAB9B, 0xE7F5, 0xAB9C, 0xAB9D, 0xAB9E, 0xAB9F, 0xABA0,
+ /* U+73F8 */ 0xAC40, 0xAC41, 0xAC42, 0xAC43, 0xAC44, 0xAC45, 0xAC46, 0xAC47,
+ /* U+7400 */ 0xAC48, 0xAC49, 0xAC4A, 0xC7F2, 0xAC4B, 0xC0C5, 0xC0ED, 0xAC4C,
+ /* U+7408 */ 0xAC4D, 0xC1F0, 0xE7F0, 0xAC4E, 0xAC4F, 0xAC50, 0xAC51, 0xE7F6,
+ /* U+7410 */ 0xCBF6, 0xAC52, 0xAC53, 0xAC54, 0xAC55, 0xAC56, 0xAC57, 0xAC58,
+ /* U+7418 */ 0xAC59, 0xAC5A, 0xE8A2, 0xE8A1, 0xAC5B, 0xAC5C, 0xAC5D, 0xAC5E,
+ /* U+7420 */ 0xAC5F, 0xAC60, 0xD7C1, 0xAC61, 0xAC62, 0xE7FA, 0xE7F9, 0xAC63,
+ /* U+7428 */ 0xE7FB, 0xAC64, 0xE7F7, 0xAC65, 0xE7FE, 0xAC66, 0xE7FD, 0xAC67,
+ /* U+7430 */ 0xE7FC, 0xAC68, 0xAC69, 0xC1D5, 0xC7D9, 0xC5FD, 0xC5C3, 0xAC6A,
+ /* U+7438 */ 0xAC6B, 0xAC6C, 0xAC6D, 0xAC6E, 0xC7ED, 0xAC6F, 0xAC70, 0xAC71,
+ /* U+7440 */ 0xAC72, 0xE8A3, 0xAC73, 0xAC74, 0xAC75, 0xAC76, 0xAC77, 0xAC78,
+ /* U+7448 */ 0xAC79, 0xAC7A, 0xAC7B, 0xAC7C, 0xAC7D, 0xAC7E, 0xAC80, 0xAC81,
+ /* U+7450 */ 0xAC82, 0xAC83, 0xAC84, 0xAC85, 0xAC86, 0xE8A6, 0xAC87, 0xE8A5,
+ /* U+7458 */ 0xAC88, 0xE8A7, 0xBAF7, 0xE7F8, 0xE8A4, 0xAC89, 0xC8F0, 0xC9AA,
+ /* U+7460 */ 0xAC8A, 0xAC8B, 0xAC8C, 0xAC8D, 0xAC8E, 0xAC8F, 0xAC90, 0xAC91,
+ /* U+7468 */ 0xAC92, 0xAC93, 0xAC94, 0xAC95, 0xAC96, 0xE8A9, 0xAC97, 0xAC98,
+ /* U+7470 */ 0xB9E5, 0xAC99, 0xAC9A, 0xAC9B, 0xAC9C, 0xAC9D, 0xD1FE, 0xE8A8,
+ /* U+7478 */ 0xAC9E, 0xAC9F, 0xACA0, 0xAD40, 0xAD41, 0xAD42, 0xE8AA, 0xAD43,
+ /* U+7480 */ 0xE8AD, 0xE8AE, 0xAD44, 0xC1A7, 0xAD45, 0xAD46, 0xAD47, 0xE8AF,
+ /* U+7488 */ 0xAD48, 0xAD49, 0xAD4A, 0xE8B0, 0xAD4B, 0xAD4C, 0xE8AC, 0xAD4D,
+ /* U+7490 */ 0xE8B4, 0xAD4E, 0xAD4F, 0xAD50, 0xAD51, 0xAD52, 0xAD53, 0xAD54,
+ /* U+7498 */ 0xAD55, 0xAD56, 0xAD57, 0xAD58, 0xE8AB, 0xAD59, 0xE8B1, 0xAD5A,
+ /* U+74A0 */ 0xAD5B, 0xAD5C, 0xAD5D, 0xAD5E, 0xAD5F, 0xAD60, 0xAD61, 0xE8B5,
+ /* U+74A8 */ 0xE8B2, 0xE8B3, 0xAD62, 0xAD63, 0xAD64, 0xAD65, 0xAD66, 0xAD67,
+ /* U+74B0 */ 0xAD68, 0xAD69, 0xAD6A, 0xAD6B, 0xAD6C, 0xAD6D, 0xAD6E, 0xAD6F,
+ /* U+74B8 */ 0xAD70, 0xAD71, 0xE8B7, 0xAD72, 0xAD73, 0xAD74, 0xAD75, 0xAD76,
+ /* U+74C0 */ 0xAD77, 0xAD78, 0xAD79, 0xAD7A, 0xAD7B, 0xAD7C, 0xAD7D, 0xAD7E,
+ /* U+74C8 */ 0xAD80, 0xAD81, 0xAD82, 0xAD83, 0xAD84, 0xAD85, 0xAD86, 0xAD87,
+ /* U+74D0 */ 0xAD88, 0xAD89, 0xE8B6, 0xAD8A, 0xAD8B, 0xAD8C, 0xAD8D, 0xAD8E,
+ /* U+74D8 */ 0xAD8F, 0xAD90, 0xAD91, 0xAD92, 0xB9CF, 0xAD93, 0xF0AC, 0xAD94,
+ /* U+74E0 */ 0xF0AD, 0xAD95, 0xC6B0, 0xB0EA, 0xC8BF, 0xAD96, 0xCDDF, 0xAD97,
+ /* U+74E8 */ 0xAD98, 0xAD99, 0xAD9A, 0xAD9B, 0xAD9C, 0xAD9D, 0xCECD, 0xEAB1,
+ /* U+74F0 */ 0xAD9E, 0xAD9F, 0xADA0, 0xAE40, 0xEAB2, 0xAE41, 0xC6BF, 0xB4C9,
+ /* U+74F8 */ 0xAE42, 0xAE43, 0xAE44, 0xAE45, 0xAE46, 0xAE47, 0xAE48, 0xEAB3,
+ /* U+7500 */ 0xAE49, 0xAE4A, 0xAE4B, 0xAE4C, 0xD5E7, 0xAE4D, 0xAE4E, 0xAE4F,
+ /* U+7508 */ 0xAE50, 0xAE51, 0xAE52, 0xAE53, 0xAE54, 0xDDF9, 0xAE55, 0xEAB4,
+ /* U+7510 */ 0xAE56, 0xEAB5, 0xAE57, 0xEAB6, 0xAE58, 0xAE59, 0xAE5A, 0xAE5B,
+ /* U+7518 */ 0xB8CA, 0xDFB0, 0xC9F5, 0xAE5C, 0xCCF0, 0xAE5D, 0xAE5E, 0xC9FA,
+ /* U+7520 */ 0xAE5F, 0xAE60, 0xAE61, 0xAE62, 0xAE63, 0xC9FB, 0xAE64, 0xAE65,
+ /* U+7528 */ 0xD3C3, 0xCBA6, 0xAE66, 0xB8A6, 0xF0AE, 0xB1C2, 0xAE67, 0xE5B8,
+ /* U+7530 */ 0xCCEF, 0xD3C9, 0xBCD7, 0xC9EA, 0xAE68, 0xB5E7, 0xAE69, 0xC4D0,
+ /* U+7538 */ 0xB5E9, 0xAE6A, 0xEEAE, 0xBBAD, 0xAE6B, 0xAE6C, 0xE7DE, 0xAE6D,
+ /* U+7540 */ 0xEEAF, 0xAE6E, 0xAE6F, 0xAE70, 0xAE71, 0xB3A9, 0xAE72, 0xAE73,
+ /* U+7548 */ 0xEEB2, 0xAE74, 0xAE75, 0xEEB1, 0xBDE7, 0xAE76, 0xEEB0, 0xCEB7,
+ /* U+7550 */ 0xAE77, 0xAE78, 0xAE79, 0xAE7A, 0xC5CF, 0xAE7B, 0xAE7C, 0xAE7D,
+ /* U+7558 */ 0xAE7E, 0xC1F4, 0xDBCE, 0xEEB3, 0xD0F3, 0xAE80, 0xAE81, 0xAE82,
+ /* U+7560 */ 0xAE83, 0xAE84, 0xAE85, 0xAE86, 0xAE87, 0xC2D4, 0xC6E8, 0xAE88,
+ /* U+7568 */ 0xAE89, 0xAE8A, 0xB7AC, 0xAE8B, 0xAE8C, 0xAE8D, 0xAE8E, 0xAE8F,
+ /* U+7570 */ 0xAE90, 0xAE91, 0xEEB4, 0xAE92, 0xB3EB, 0xAE93, 0xAE94, 0xAE95,
+ /* U+7578 */ 0xBBFB, 0xEEB5, 0xAE96, 0xAE97, 0xAE98, 0xAE99, 0xAE9A, 0xE7DC,
+ /* U+7580 */ 0xAE9B, 0xAE9C, 0xAE9D, 0xEEB6, 0xAE9E, 0xAE9F, 0xBDAE, 0xAEA0,
+ /* U+7588 */ 0xAF40, 0xAF41, 0xAF42, 0xF1E2, 0xAF43, 0xAF44, 0xAF45, 0xCAE8,
+ /* U+7590 */ 0xAF46, 0xD2C9, 0xF0DA, 0xAF47, 0xF0DB, 0xAF48, 0xF0DC, 0xC1C6,
+ /* U+7598 */ 0xAF49, 0xB8ED, 0xBECE, 0xAF4A, 0xAF4B, 0xF0DE, 0xAF4C, 0xC5B1,
+ /* U+75A0 */ 0xF0DD, 0xD1F1, 0xAF4D, 0xF0E0, 0xB0CC, 0xBDEA, 0xAF4E, 0xAF4F,
+ /* U+75A8 */ 0xAF50, 0xAF51, 0xAF52, 0xD2DF, 0xF0DF, 0xAF53, 0xB4AF, 0xB7E8,
+ /* U+75B0 */ 0xF0E6, 0xF0E5, 0xC6A3, 0xF0E1, 0xF0E2, 0xB4C3, 0xAF54, 0xAF55,
+ /* U+75B8 */ 0xF0E3, 0xD5EE, 0xAF56, 0xAF57, 0xCCDB, 0xBED2, 0xBCB2, 0xAF58,
+ /* U+75C0 */ 0xAF59, 0xAF5A, 0xF0E8, 0xF0E7, 0xF0E4, 0xB2A1, 0xAF5B, 0xD6A2,
+ /* U+75C8 */ 0xD3B8, 0xBEB7, 0xC8AC, 0xAF5C, 0xAF5D, 0xF0EA, 0xAF5E, 0xAF5F,
+ /* U+75D0 */ 0xAF60, 0xAF61, 0xD1F7, 0xAF62, 0xD6CC, 0xBADB, 0xF0E9, 0xAF63,
+ /* U+75D8 */ 0xB6BB, 0xAF64, 0xAF65, 0xCDB4, 0xAF66, 0xAF67, 0xC6A6, 0xAF68,
+ /* U+75E0 */ 0xAF69, 0xAF6A, 0xC1A1, 0xF0EB, 0xF0EE, 0xAF6B, 0xF0ED, 0xF0F0,
+ /* U+75E8 */ 0xF0EC, 0xAF6C, 0xBBBE, 0xF0EF, 0xAF6D, 0xAF6E, 0xAF6F, 0xAF70,
+ /* U+75F0 */ 0xCCB5, 0xF0F2, 0xAF71, 0xAF72, 0xB3D5, 0xAF73, 0xAF74, 0xAF75,
+ /* U+75F8 */ 0xAF76, 0xB1D4, 0xAF77, 0xAF78, 0xF0F3, 0xAF79, 0xAF7A, 0xF0F4,
+ /* U+7600 */ 0xF0F6, 0xB4E1, 0xAF7B, 0xF0F1, 0xAF7C, 0xF0F7, 0xAF7D, 0xAF7E,
+ /* U+7608 */ 0xAF80, 0xAF81, 0xF0FA, 0xAF82, 0xF0F8, 0xAF83, 0xAF84, 0xAF85,
+ /* U+7610 */ 0xF0F5, 0xAF86, 0xAF87, 0xAF88, 0xAF89, 0xF0FD, 0xAF8A, 0xF0F9,
+ /* U+7618 */ 0xF0FC, 0xF0FE, 0xAF8B, 0xF1A1, 0xAF8C, 0xAF8D, 0xAF8E, 0xCEC1,
+ /* U+7620 */ 0xF1A4, 0xAF8F, 0xF1A3, 0xAF90, 0xC1F6, 0xF0FB, 0xCADD, 0xAF91,
+ /* U+7628 */ 0xAF92, 0xB4F1, 0xB1F1, 0xCCB1, 0xAF93, 0xF1A6, 0xAF94, 0xAF95,
+ /* U+7630 */ 0xF1A7, 0xAF96, 0xAF97, 0xF1AC, 0xD5CE, 0xF1A9, 0xAF98, 0xAF99,
+ /* U+7638 */ 0xC8B3, 0xAF9A, 0xAF9B, 0xAF9C, 0xF1A2, 0xAF9D, 0xF1AB, 0xF1A8,
+ /* U+7640 */ 0xF1A5, 0xAF9E, 0xAF9F, 0xF1AA, 0xAFA0, 0xB040, 0xB041, 0xB042,
+ /* U+7648 */ 0xB043, 0xB044, 0xB045, 0xB046, 0xB0A9, 0xF1AD, 0xB047, 0xB048,
+ /* U+7650 */ 0xB049, 0xB04A, 0xB04B, 0xB04C, 0xF1AF, 0xB04D, 0xF1B1, 0xB04E,
+ /* U+7658 */ 0xB04F, 0xB050, 0xB051, 0xB052, 0xF1B0, 0xB053, 0xF1AE, 0xB054,
+ /* U+7660 */ 0xB055, 0xB056, 0xB057, 0xD1A2, 0xB058, 0xB059, 0xB05A, 0xB05B,
+ /* U+7668 */ 0xB05C, 0xB05D, 0xB05E, 0xF1B2, 0xB05F, 0xB060, 0xB061, 0xF1B3,
+ /* U+7670 */ 0xB062, 0xB063, 0xB064, 0xB065, 0xB066, 0xB067, 0xB068, 0xB069,
+ /* U+7678 */ 0xB9EF, 0xB06A, 0xB06B, 0xB5C7, 0xB06C, 0xB0D7, 0xB0D9, 0xB06D,
+ /* U+7680 */ 0xB06E, 0xB06F, 0xD4ED, 0xB070, 0xB5C4, 0xB071, 0xBDD4, 0xBBCA,
+ /* U+7688 */ 0xF0A7, 0xB072, 0xB073, 0xB8DE, 0xB074, 0xB075, 0xF0A8, 0xB076,
+ /* U+7690 */ 0xB077, 0xB0A8, 0xB078, 0xF0A9, 0xB079, 0xB07A, 0xCDEE, 0xB07B,
+ /* U+7698 */ 0xB07C, 0xF0AA, 0xB07D, 0xB07E, 0xB080, 0xB081, 0xB082, 0xB083,
+ /* U+76A0 */ 0xB084, 0xB085, 0xB086, 0xB087, 0xF0AB, 0xB088, 0xB089, 0xB08A,
+ /* U+76A8 */ 0xB08B, 0xB08C, 0xB08D, 0xB08E, 0xB08F, 0xB090, 0xC6A4, 0xB091,
+ /* U+76B0 */ 0xB092, 0xD6E5, 0xF1E4, 0xB093, 0xF1E5, 0xB094, 0xB095, 0xB096,
+ /* U+76B8 */ 0xB097, 0xB098, 0xB099, 0xB09A, 0xB09B, 0xB09C, 0xB09D, 0xC3F3,
+ /* U+76C0 */ 0xB09E, 0xB09F, 0xD3DB, 0xB0A0, 0xB140, 0xD6D1, 0xC5E8, 0xB141,
+ /* U+76C8 */ 0xD3AF, 0xB142, 0xD2E6, 0xB143, 0xB144, 0xEEC1, 0xB0BB, 0xD5B5,
+ /* U+76D0 */ 0xD1CE, 0xBCE0, 0xBAD0, 0xB145, 0xBFF8, 0xB146, 0xB8C7, 0xB5C1,
+ /* U+76D8 */ 0xC5CC, 0xB147, 0xB148, 0xCAA2, 0xB149, 0xB14A, 0xB14B, 0xC3CB,
+ /* U+76E0 */ 0xB14C, 0xB14D, 0xB14E, 0xB14F, 0xB150, 0xEEC2, 0xB151, 0xB152,
+ /* U+76E8 */ 0xB153, 0xB154, 0xB155, 0xB156, 0xB157, 0xB158, 0xC4BF, 0xB6A2,
+ /* U+76F0 */ 0xB159, 0xEDEC, 0xC3A4, 0xB15A, 0xD6B1, 0xB15B, 0xB15C, 0xB15D,
+ /* U+76F8 */ 0xCFE0, 0xEDEF, 0xB15E, 0xB15F, 0xC5CE, 0xB160, 0xB6DC, 0xB161,
+ /* U+7700 */ 0xB162, 0xCAA1, 0xB163, 0xB164, 0xEDED, 0xB165, 0xB166, 0xEDF0,
+ /* U+7708 */ 0xEDF1, 0xC3BC, 0xB167, 0xBFB4, 0xB168, 0xEDEE, 0xB169, 0xB16A,
+ /* U+7710 */ 0xB16B, 0xB16C, 0xB16D, 0xB16E, 0xB16F, 0xB170, 0xB171, 0xB172,
+ /* U+7718 */ 0xB173, 0xEDF4, 0xEDF2, 0xB174, 0xB175, 0xB176, 0xB177, 0xD5E6,
+ /* U+7720 */ 0xC3DF, 0xB178, 0xEDF3, 0xB179, 0xB17A, 0xB17B, 0xEDF6, 0xB17C,
+ /* U+7728 */ 0xD5A3, 0xD1A3, 0xB17D, 0xB17E, 0xB180, 0xEDF5, 0xB181, 0xC3D0,
+ /* U+7730 */ 0xB182, 0xB183, 0xB184, 0xB185, 0xB186, 0xEDF7, 0xBFF4, 0xBEEC,
+ /* U+7738 */ 0xEDF8, 0xB187, 0xCCF7, 0xB188, 0xD1DB, 0xB189, 0xB18A, 0xB18B,
+ /* U+7740 */ 0xD7C5, 0xD5F6, 0xB18C, 0xEDFC, 0xB18D, 0xB18E, 0xB18F, 0xEDFB,
+ /* U+7748 */ 0xB190, 0xB191, 0xB192, 0xB193, 0xB194, 0xB195, 0xB196, 0xB197,
+ /* U+7750 */ 0xEDF9, 0xEDFA, 0xB198, 0xB199, 0xB19A, 0xB19B, 0xB19C, 0xB19D,
+ /* U+7758 */ 0xB19E, 0xB19F, 0xEDFD, 0xBEA6, 0xB1A0, 0xB240, 0xB241, 0xB242,
+ /* U+7760 */ 0xB243, 0xCBAF, 0xEEA1, 0xB6BD, 0xB244, 0xEEA2, 0xC4C0, 0xB245,
+ /* U+7768 */ 0xEDFE, 0xB246, 0xB247, 0xBDDE, 0xB2C7, 0xB248, 0xB249, 0xB24A,
+ /* U+7770 */ 0xB24B, 0xB24C, 0xB24D, 0xB24E, 0xB24F, 0xB250, 0xB251, 0xB252,
+ /* U+7778 */ 0xB253, 0xB6C3, 0xB254, 0xB255, 0xB256, 0xEEA5, 0xD8BA, 0xEEA3,
+ /* U+7780 */ 0xEEA6, 0xB257, 0xB258, 0xB259, 0xC3E9, 0xB3F2, 0xB25A, 0xB25B,
+ /* U+7788 */ 0xB25C, 0xB25D, 0xB25E, 0xB25F, 0xEEA7, 0xEEA4, 0xCFB9, 0xB260,
+ /* U+7790 */ 0xB261, 0xEEA8, 0xC2F7, 0xB262, 0xB263, 0xB264, 0xB265, 0xB266,
+ /* U+7798 */ 0xB267, 0xB268, 0xB269, 0xB26A, 0xB26B, 0xB26C, 0xB26D, 0xEEA9,
+ /* U+77A0 */ 0xEEAA, 0xB26E, 0xDEAB, 0xB26F, 0xB270, 0xC6B3, 0xB271, 0xC7C6,
+ /* U+77A8 */ 0xB272, 0xD6F5, 0xB5C9, 0xB273, 0xCBB2, 0xB274, 0xB275, 0xB276,
+ /* U+77B0 */ 0xEEAB, 0xB277, 0xB278, 0xCDAB, 0xB279, 0xEEAC, 0xB27A, 0xB27B,
+ /* U+77B8 */ 0xB27C, 0xB27D, 0xB27E, 0xD5B0, 0xB280, 0xEEAD, 0xB281, 0xF6C4,
+ /* U+77C0 */ 0xB282, 0xB283, 0xB284, 0xB285, 0xB286, 0xB287, 0xB288, 0xB289,
+ /* U+77C8 */ 0xB28A, 0xB28B, 0xB28C, 0xB28D, 0xB28E, 0xDBC7, 0xB28F, 0xB290,
+ /* U+77D0 */ 0xB291, 0xB292, 0xB293, 0xB294, 0xB295, 0xB296, 0xB297, 0xB4A3,
+ /* U+77D8 */ 0xB298, 0xB299, 0xB29A, 0xC3AC, 0xF1E6, 0xB29B, 0xB29C, 0xB29D,
+ /* U+77E0 */ 0xB29E, 0xB29F, 0xCAB8, 0xD2D3, 0xB2A0, 0xD6AA, 0xB340, 0xEFF2,
+ /* U+77E8 */ 0xB341, 0xBED8, 0xB342, 0xBDC3, 0xEFF3, 0xB6CC, 0xB0AB, 0xB343,
+ /* U+77F0 */ 0xB344, 0xB345, 0xB346, 0xCAAF, 0xB347, 0xB348, 0xEDB6, 0xB349,
+ /* U+77F8 */ 0xEDB7, 0xB34A, 0xB34B, 0xB34C, 0xB34D, 0xCEF9, 0xB7AF, 0xBFF3,
+ /* U+7800 */ 0xEDB8, 0xC2EB, 0xC9B0, 0xB34E, 0xB34F, 0xB350, 0xB351, 0xB352,
+ /* U+7808 */ 0xB353, 0xEDB9, 0xB354, 0xB355, 0xC6F6, 0xBFB3, 0xB356, 0xB357,
+ /* U+7810 */ 0xB358, 0xEDBC, 0xC5F8, 0xB359, 0xD1D0, 0xB35A, 0xD7A9, 0xEDBA,
+ /* U+7818 */ 0xEDBB, 0xB35B, 0xD1E2, 0xB35C, 0xEDBF, 0xEDC0, 0xB35D, 0xEDC4,
+ /* U+7820 */ 0xB35E, 0xB35F, 0xB360, 0xEDC8, 0xB361, 0xEDC6, 0xEDCE, 0xD5E8,
+ /* U+7828 */ 0xB362, 0xEDC9, 0xB363, 0xB364, 0xEDC7, 0xEDBE, 0xB365, 0xB366,
+ /* U+7830 */ 0xC5E9, 0xB367, 0xB368, 0xB369, 0xC6C6, 0xB36A, 0xB36B, 0xC9E9,
+ /* U+7838 */ 0xD4D2, 0xEDC1, 0xEDC2, 0xEDC3, 0xEDC5, 0xB36C, 0xC0F9, 0xB36D,
+ /* U+7840 */ 0xB4A1, 0xB36E, 0xB36F, 0xB370, 0xB371, 0xB9E8, 0xB372, 0xEDD0,
+ /* U+7848 */ 0xB373, 0xB374, 0xB375, 0xB376, 0xEDD1, 0xB377, 0xEDCA, 0xB378,
+ /* U+7850 */ 0xEDCF, 0xB379, 0xCEF8, 0xB37A, 0xB37B, 0xCBB6, 0xEDCC, 0xEDCD,
+ /* U+7858 */ 0xB37C, 0xB37D, 0xB37E, 0xB380, 0xB381, 0xCFF5, 0xB382, 0xB383,
+ /* U+7860 */ 0xB384, 0xB385, 0xB386, 0xB387, 0xB388, 0xB389, 0xB38A, 0xB38B,
+ /* U+7868 */ 0xB38C, 0xB38D, 0xEDD2, 0xC1F2, 0xD3B2, 0xEDCB, 0xC8B7, 0xB38E,
+ /* U+7870 */ 0xB38F, 0xB390, 0xB391, 0xB392, 0xB393, 0xB394, 0xB395, 0xBCEF,
+ /* U+7878 */ 0xB396, 0xB397, 0xB398, 0xB399, 0xC5F0, 0xB39A, 0xB39B, 0xB39C,
+ /* U+7880 */ 0xB39D, 0xB39E, 0xB39F, 0xB3A0, 0xB440, 0xB441, 0xB442, 0xEDD6,
+ /* U+7888 */ 0xB443, 0xB5EF, 0xB444, 0xB445, 0xC2B5, 0xB0AD, 0xCBE9, 0xB446,
+ /* U+7890 */ 0xB447, 0xB1AE, 0xB448, 0xEDD4, 0xB449, 0xB44A, 0xB44B, 0xCDEB,
+ /* U+7898 */ 0xB5E2, 0xB44C, 0xEDD5, 0xEDD3, 0xEDD7, 0xB44D, 0xB44E, 0xB5FA,
+ /* U+78A0 */ 0xB44F, 0xEDD8, 0xB450, 0xEDD9, 0xB451, 0xEDDC, 0xB452, 0xB1CC,
+ /* U+78A8 */ 0xB453, 0xB454, 0xB455, 0xB456, 0xB457, 0xB458, 0xB459, 0xB45A,
+ /* U+78B0 */ 0xC5F6, 0xBCEE, 0xEDDA, 0xCCBC, 0xB2EA, 0xB45B, 0xB45C, 0xB45D,
+ /* U+78B8 */ 0xB45E, 0xEDDB, 0xB45F, 0xB460, 0xB461, 0xB462, 0xC4EB, 0xB463,
+ /* U+78C0 */ 0xB464, 0xB4C5, 0xB465, 0xB466, 0xB467, 0xB0F5, 0xB468, 0xB469,
+ /* U+78C8 */ 0xB46A, 0xEDDF, 0xC0DA, 0xB4E8, 0xB46B, 0xB46C, 0xB46D, 0xB46E,
+ /* U+78D0 */ 0xC5CD, 0xB46F, 0xB470, 0xB471, 0xEDDD, 0xBFC4, 0xB472, 0xB473,
+ /* U+78D8 */ 0xB474, 0xEDDE, 0xB475, 0xB476, 0xB477, 0xB478, 0xB479, 0xB47A,
+ /* U+78E0 */ 0xB47B, 0xB47C, 0xB47D, 0xB47E, 0xB480, 0xB481, 0xB482, 0xB483,
+ /* U+78E8 */ 0xC4A5, 0xB484, 0xB485, 0xB486, 0xEDE0, 0xB487, 0xB488, 0xB489,
+ /* U+78F0 */ 0xB48A, 0xB48B, 0xEDE1, 0xB48C, 0xEDE3, 0xB48D, 0xB48E, 0xC1D7,
+ /* U+78F8 */ 0xB48F, 0xB490, 0xBBC7, 0xB491, 0xB492, 0xB493, 0xB494, 0xB495,
+ /* U+7900 */ 0xB496, 0xBDB8, 0xB497, 0xB498, 0xB499, 0xEDE2, 0xB49A, 0xB49B,
+ /* U+7908 */ 0xB49C, 0xB49D, 0xB49E, 0xB49F, 0xB4A0, 0xB540, 0xB541, 0xB542,
+ /* U+7910 */ 0xB543, 0xB544, 0xB545, 0xEDE4, 0xB546, 0xB547, 0xB548, 0xB549,
+ /* U+7918 */ 0xB54A, 0xB54B, 0xB54C, 0xB54D, 0xB54E, 0xB54F, 0xEDE6, 0xB550,
+ /* U+7920 */ 0xB551, 0xB552, 0xB553, 0xB554, 0xEDE5, 0xB555, 0xB556, 0xB557,
+ /* U+7928 */ 0xB558, 0xB559, 0xB55A, 0xB55B, 0xB55C, 0xB55D, 0xB55E, 0xB55F,
+ /* U+7930 */ 0xB560, 0xB561, 0xB562, 0xB563, 0xEDE7, 0xB564, 0xB565, 0xB566,
+ /* U+7938 */ 0xB567, 0xB568, 0xCABE, 0xECEA, 0xC0F1, 0xB569, 0xC9E7, 0xB56A,
+ /* U+7940 */ 0xECEB, 0xC6EE, 0xB56B, 0xB56C, 0xB56D, 0xB56E, 0xECEC, 0xB56F,
+ /* U+7948 */ 0xC6ED, 0xECED, 0xB570, 0xB571, 0xB572, 0xB573, 0xB574, 0xB575,
+ /* U+7950 */ 0xB576, 0xB577, 0xB578, 0xECF0, 0xB579, 0xB57A, 0xD7E6, 0xECF3,
+ /* U+7958 */ 0xB57B, 0xB57C, 0xECF1, 0xECEE, 0xECEF, 0xD7A3, 0xC9F1, 0xCBEE,
+ /* U+7960 */ 0xECF4, 0xB57D, 0xECF2, 0xB57E, 0xB580, 0xCFE9, 0xB581, 0xECF6,
+ /* U+7968 */ 0xC6B1, 0xB582, 0xB583, 0xB584, 0xB585, 0xBCC0, 0xB586, 0xECF5,
+ /* U+7970 */ 0xB587, 0xB588, 0xB589, 0xB58A, 0xB58B, 0xB58C, 0xB58D, 0xB5BB,
+ /* U+7978 */ 0xBBF6, 0xB58E, 0xECF7, 0xB58F, 0xB590, 0xB591, 0xB592, 0xB593,
+ /* U+7980 */ 0xD9F7, 0xBDFB, 0xB594, 0xB595, 0xC2BB, 0xECF8, 0xB596, 0xB597,
+ /* U+7988 */ 0xB598, 0xB599, 0xECF9, 0xB59A, 0xB59B, 0xB59C, 0xB59D, 0xB8A3,
+ /* U+7990 */ 0xB59E, 0xB59F, 0xB5A0, 0xB640, 0xB641, 0xB642, 0xB643, 0xB644,
+ /* U+7998 */ 0xB645, 0xB646, 0xECFA, 0xB647, 0xB648, 0xB649, 0xB64A, 0xB64B,
+ /* U+79A0 */ 0xB64C, 0xB64D, 0xB64E, 0xB64F, 0xB650, 0xB651, 0xB652, 0xECFB,
+ /* U+79A8 */ 0xB653, 0xB654, 0xB655, 0xB656, 0xB657, 0xB658, 0xB659, 0xB65A,
+ /* U+79B0 */ 0xB65B, 0xB65C, 0xB65D, 0xECFC, 0xB65E, 0xB65F, 0xB660, 0xB661,
+ /* U+79B8 */ 0xB662, 0xD3ED, 0xD8AE, 0xC0EB, 0xB663, 0xC7DD, 0xBACC, 0xB664,
+ /* U+79C0 */ 0xD0E3, 0xCBBD, 0xB665, 0xCDBA, 0xB666, 0xB667, 0xB8D1, 0xB668,
+ /* U+79C8 */ 0xB669, 0xB1FC, 0xB66A, 0xC7EF, 0xB66B, 0xD6D6, 0xB66C, 0xB66D,
+ /* U+79D0 */ 0xB66E, 0xBFC6, 0xC3EB, 0xB66F, 0xB670, 0xEFF5, 0xB671, 0xB672,
+ /* U+79D8 */ 0xC3D8, 0xB673, 0xB674, 0xB675, 0xB676, 0xB677, 0xB678, 0xD7E2,
+ /* U+79E0 */ 0xB679, 0xB67A, 0xB67B, 0xEFF7, 0xB3D3, 0xB67C, 0xC7D8, 0xD1ED,
+ /* U+79E8 */ 0xB67D, 0xD6C8, 0xB67E, 0xEFF8, 0xB680, 0xEFF6, 0xB681, 0xBBFD,
+ /* U+79F0 */ 0xB3C6, 0xB682, 0xB683, 0xB684, 0xB685, 0xB686, 0xB687, 0xB688,
+ /* U+79F8 */ 0xBDD5, 0xB689, 0xB68A, 0xD2C6, 0xB68B, 0xBBE0, 0xB68C, 0xB68D,
+ /* U+7A00 */ 0xCFA1, 0xB68E, 0xEFFC, 0xEFFB, 0xB68F, 0xB690, 0xEFF9, 0xB691,
+ /* U+7A08 */ 0xB692, 0xB693, 0xB694, 0xB3CC, 0xB695, 0xC9D4, 0xCBB0, 0xB696,
+ /* U+7A10 */ 0xB697, 0xB698, 0xB699, 0xB69A, 0xEFFE, 0xB69B, 0xB69C, 0xB0DE,
+ /* U+7A18 */ 0xB69D, 0xB69E, 0xD6C9, 0xB69F, 0xB6A0, 0xB740, 0xEFFD, 0xB741,
+ /* U+7A20 */ 0xB3ED, 0xB742, 0xB743, 0xF6D5, 0xB744, 0xB745, 0xB746, 0xB747,
+ /* U+7A28 */ 0xB748, 0xB749, 0xB74A, 0xB74B, 0xB74C, 0xB74D, 0xB74E, 0xB74F,
+ /* U+7A30 */ 0xB750, 0xB751, 0xB752, 0xCEC8, 0xB753, 0xB754, 0xB755, 0xF0A2,
+ /* U+7A38 */ 0xB756, 0xF0A1, 0xB757, 0xB5BE, 0xBCDA, 0xBBFC, 0xB758, 0xB8E5,
+ /* U+7A40 */ 0xB759, 0xB75A, 0xB75B, 0xB75C, 0xB75D, 0xB75E, 0xC4C2, 0xB75F,
+ /* U+7A48 */ 0xB760, 0xB761, 0xB762, 0xB763, 0xB764, 0xB765, 0xB766, 0xB767,
+ /* U+7A50 */ 0xB768, 0xF0A3, 0xB769, 0xB76A, 0xB76B, 0xB76C, 0xB76D, 0xCBEB,
+ /* U+7A58 */ 0xB76E, 0xB76F, 0xB770, 0xB771, 0xB772, 0xB773, 0xB774, 0xB775,
+ /* U+7A60 */ 0xB776, 0xB777, 0xB778, 0xB779, 0xB77A, 0xB77B, 0xB77C, 0xB77D,
+ /* U+7A68 */ 0xB77E, 0xB780, 0xB781, 0xB782, 0xB783, 0xB784, 0xB785, 0xB786,
+ /* U+7A70 */ 0xF0A6, 0xB787, 0xB788, 0xB789, 0xD1A8, 0xB78A, 0xBEBF, 0xC7EE,
+ /* U+7A78 */ 0xF1B6, 0xF1B7, 0xBFD5, 0xB78B, 0xB78C, 0xB78D, 0xB78E, 0xB4A9,
+ /* U+7A80 */ 0xF1B8, 0xCDBB, 0xB78F, 0xC7D4, 0xD5AD, 0xB790, 0xF1B9, 0xB791,
+ /* U+7A88 */ 0xF1BA, 0xB792, 0xB793, 0xB794, 0xB795, 0xC7CF, 0xB796, 0xB797,
+ /* U+7A90 */ 0xB798, 0xD2A4, 0xD6CF, 0xB799, 0xB79A, 0xF1BB, 0xBDD1, 0xB4B0,
+ /* U+7A98 */ 0xBEBD, 0xB79B, 0xB79C, 0xB79D, 0xB4DC, 0xCED1, 0xB79E, 0xBFDF,
+ /* U+7AA0 */ 0xF1BD, 0xB79F, 0xB7A0, 0xB840, 0xB841, 0xBFFA, 0xF1BC, 0xB842,
+ /* U+7AA8 */ 0xF1BF, 0xB843, 0xB844, 0xB845, 0xF1BE, 0xF1C0, 0xB846, 0xB847,
+ /* U+7AB0 */ 0xB848, 0xB849, 0xB84A, 0xF1C1, 0xB84B, 0xB84C, 0xB84D, 0xB84E,
+ /* U+7AB8 */ 0xB84F, 0xB850, 0xB851, 0xB852, 0xB853, 0xB854, 0xB855, 0xC1FE,
+ /* U+7AC0 */ 0xB856, 0xB857, 0xB858, 0xB859, 0xB85A, 0xB85B, 0xB85C, 0xB85D,
+ /* U+7AC8 */ 0xB85E, 0xB85F, 0xB860, 0xC1A2, 0xB861, 0xB862, 0xB863, 0xB864,
+ /* U+7AD0 */ 0xB865, 0xB866, 0xB867, 0xB868, 0xB869, 0xB86A, 0xCAFA, 0xB86B,
+ /* U+7AD8 */ 0xB86C, 0xD5BE, 0xB86D, 0xB86E, 0xB86F, 0xB870, 0xBEBA, 0xBEB9,
+ /* U+7AE0 */ 0xD5C2, 0xB871, 0xB872, 0xBFA2, 0xB873, 0xCDAF, 0xF1B5, 0xB874,
+ /* U+7AE8 */ 0xB875, 0xB876, 0xB877, 0xB878, 0xB879, 0xBDDF, 0xB87A, 0xB6CB,
+ /* U+7AF0 */ 0xB87B, 0xB87C, 0xB87D, 0xB87E, 0xB880, 0xB881, 0xB882, 0xB883,
+ /* U+7AF8 */ 0xB884, 0xD6F1, 0xF3C3, 0xB885, 0xB886, 0xF3C4, 0xB887, 0xB8CD,
+ /* U+7B00 */ 0xB888, 0xB889, 0xB88A, 0xF3C6, 0xF3C7, 0xB88B, 0xB0CA, 0xB88C,
+ /* U+7B08 */ 0xF3C5, 0xB88D, 0xF3C9, 0xCBF1, 0xB88E, 0xB88F, 0xB890, 0xF3CB,
+ /* U+7B10 */ 0xB891, 0xD0A6, 0xB892, 0xB893, 0xB1CA, 0xF3C8, 0xB894, 0xB895,
+ /* U+7B18 */ 0xB896, 0xF3CF, 0xB897, 0xB5D1, 0xB898, 0xB899, 0xF3D7, 0xB89A,
+ /* U+7B20 */ 0xF3D2, 0xB89B, 0xB89C, 0xB89D, 0xF3D4, 0xF3D3, 0xB7FB, 0xB89E,
+ /* U+7B28 */ 0xB1BF, 0xB89F, 0xF3CE, 0xF3CA, 0xB5DA, 0xB8A0, 0xF3D0, 0xB940,
+ /* U+7B30 */ 0xB941, 0xF3D1, 0xB942, 0xF3D5, 0xB943, 0xB944, 0xB945, 0xB946,
+ /* U+7B38 */ 0xF3CD, 0xB947, 0xBCE3, 0xB948, 0xC1FD, 0xB949, 0xF3D6, 0xB94A,
+ /* U+7B40 */ 0xB94B, 0xB94C, 0xB94D, 0xB94E, 0xB94F, 0xF3DA, 0xB950, 0xF3CC,
+ /* U+7B48 */ 0xB951, 0xB5C8, 0xB952, 0xBDEE, 0xF3DC, 0xB953, 0xB954, 0xB7A4,
+ /* U+7B50 */ 0xBFF0, 0xD6FE, 0xCDB2, 0xB955, 0xB4F0, 0xB956, 0xB2DF, 0xB957,
+ /* U+7B58 */ 0xF3D8, 0xB958, 0xF3D9, 0xC9B8, 0xB959, 0xF3DD, 0xB95A, 0xB95B,
+ /* U+7B60 */ 0xF3DE, 0xB95C, 0xF3E1, 0xB95D, 0xB95E, 0xB95F, 0xB960, 0xB961,
+ /* U+7B68 */ 0xB962, 0xB963, 0xB964, 0xB965, 0xB966, 0xB967, 0xF3DF, 0xB968,
+ /* U+7B70 */ 0xB969, 0xF3E3, 0xF3E2, 0xB96A, 0xB96B, 0xF3DB, 0xB96C, 0xBFEA,
+ /* U+7B78 */ 0xB96D, 0xB3EF, 0xB96E, 0xF3E0, 0xB96F, 0xB970, 0xC7A9, 0xB971,
+ /* U+7B80 */ 0xBCF2, 0xB972, 0xB973, 0xB974, 0xB975, 0xF3EB, 0xB976, 0xB977,
+ /* U+7B88 */ 0xB978, 0xB979, 0xB97A, 0xB97B, 0xB97C, 0xB9BF, 0xB97D, 0xB97E,
+ /* U+7B90 */ 0xF3E4, 0xB980, 0xB981, 0xB982, 0xB2AD, 0xBBFE, 0xB983, 0xCBE3,
+ /* U+7B98 */ 0xB984, 0xB985, 0xB986, 0xB987, 0xF3ED, 0xF3E9, 0xB988, 0xB989,
+ /* U+7BA0 */ 0xB98A, 0xB9DC, 0xF3EE, 0xB98B, 0xB98C, 0xB98D, 0xF3E5, 0xF3E6,
+ /* U+7BA8 */ 0xF3EA, 0xC2E1, 0xF3EC, 0xF3EF, 0xF3E8, 0xBCFD, 0xB98E, 0xB98F,
+ /* U+7BB0 */ 0xB990, 0xCFE4, 0xB991, 0xB992, 0xF3F0, 0xB993, 0xB994, 0xB995,
+ /* U+7BB8 */ 0xF3E7, 0xB996, 0xB997, 0xB998, 0xB999, 0xB99A, 0xB99B, 0xB99C,
+ /* U+7BC0 */ 0xB99D, 0xF3F2, 0xB99E, 0xB99F, 0xB9A0, 0xBA40, 0xD7AD, 0xC6AA,
+ /* U+7BC8 */ 0xBA41, 0xBA42, 0xBA43, 0xBA44, 0xF3F3, 0xBA45, 0xBA46, 0xBA47,
+ /* U+7BD0 */ 0xBA48, 0xF3F1, 0xBA49, 0xC2A8, 0xBA4A, 0xBA4B, 0xBA4C, 0xBA4D,
+ /* U+7BD8 */ 0xBA4E, 0xB8DD, 0xF3F5, 0xBA4F, 0xBA50, 0xF3F4, 0xBA51, 0xBA52,
+ /* U+7BE0 */ 0xBA53, 0xB4DB, 0xBA54, 0xBA55, 0xBA56, 0xF3F6, 0xF3F7, 0xBA57,
+ /* U+7BE8 */ 0xBA58, 0xBA59, 0xF3F8, 0xBA5A, 0xBA5B, 0xBA5C, 0xC0BA, 0xBA5D,
+ /* U+7BF0 */ 0xBA5E, 0xC0E9, 0xBA5F, 0xBA60, 0xBA61, 0xBA62, 0xBA63, 0xC5F1,
+ /* U+7BF8 */ 0xBA64, 0xBA65, 0xBA66, 0xBA67, 0xF3FB, 0xBA68, 0xF3FA, 0xBA69,
+ /* U+7C00 */ 0xBA6A, 0xBA6B, 0xBA6C, 0xBA6D, 0xBA6E, 0xBA6F, 0xBA70, 0xB4D8,
+ /* U+7C08 */ 0xBA71, 0xBA72, 0xBA73, 0xF3FE, 0xF3F9, 0xBA74, 0xBA75, 0xF3FC,
+ /* U+7C10 */ 0xBA76, 0xBA77, 0xBA78, 0xBA79, 0xBA7A, 0xBA7B, 0xF3FD, 0xBA7C,
+ /* U+7C18 */ 0xBA7D, 0xBA7E, 0xBA80, 0xBA81, 0xBA82, 0xBA83, 0xBA84, 0xF4A1,
+ /* U+7C20 */ 0xBA85, 0xBA86, 0xBA87, 0xBA88, 0xBA89, 0xBA8A, 0xF4A3, 0xBBC9,
+ /* U+7C28 */ 0xBA8B, 0xBA8C, 0xF4A2, 0xBA8D, 0xBA8E, 0xBA8F, 0xBA90, 0xBA91,
+ /* U+7C30 */ 0xBA92, 0xBA93, 0xBA94, 0xBA95, 0xBA96, 0xBA97, 0xBA98, 0xBA99,
+ /* U+7C38 */ 0xF4A4, 0xBA9A, 0xBA9B, 0xBA9C, 0xBA9D, 0xBA9E, 0xBA9F, 0xB2BE,
+ /* U+7C40 */ 0xF4A6, 0xF4A5, 0xBAA0, 0xBB40, 0xBB41, 0xBB42, 0xBB43, 0xBB44,
+ /* U+7C48 */ 0xBB45, 0xBB46, 0xBB47, 0xBB48, 0xBB49, 0xBCAE, 0xBB4A, 0xBB4B,
+ /* U+7C50 */ 0xBB4C, 0xBB4D, 0xBB4E, 0xBB4F, 0xBB50, 0xBB51, 0xBB52, 0xBB53,
+ /* U+7C58 */ 0xBB54, 0xBB55, 0xBB56, 0xBB57, 0xBB58, 0xBB59, 0xBB5A, 0xBB5B,
+ /* U+7C60 */ 0xBB5C, 0xBB5D, 0xBB5E, 0xBB5F, 0xBB60, 0xBB61, 0xBB62, 0xBB63,
+ /* U+7C68 */ 0xBB64, 0xBB65, 0xBB66, 0xBB67, 0xBB68, 0xBB69, 0xBB6A, 0xBB6B,
+ /* U+7C70 */ 0xBB6C, 0xBB6D, 0xBB6E, 0xC3D7, 0xD9E1, 0xBB6F, 0xBB70, 0xBB71,
+ /* U+7C78 */ 0xBB72, 0xBB73, 0xBB74, 0xC0E0, 0xF4CC, 0xD7D1, 0xBB75, 0xBB76,
+ /* U+7C80 */ 0xBB77, 0xBB78, 0xBB79, 0xBB7A, 0xBB7B, 0xBB7C, 0xBB7D, 0xBB7E,
+ /* U+7C88 */ 0xBB80, 0xB7DB, 0xBB81, 0xBB82, 0xBB83, 0xBB84, 0xBB85, 0xBB86,
+ /* U+7C90 */ 0xBB87, 0xF4CE, 0xC1A3, 0xBB88, 0xBB89, 0xC6C9, 0xBB8A, 0xB4D6,
+ /* U+7C98 */ 0xD5B3, 0xBB8B, 0xBB8C, 0xBB8D, 0xF4D0, 0xF4CF, 0xF4D1, 0xCBDA,
+ /* U+7CA0 */ 0xBB8E, 0xBB8F, 0xF4D2, 0xBB90, 0xD4C1, 0xD6E0, 0xBB91, 0xBB92,
+ /* U+7CA8 */ 0xBB93, 0xBB94, 0xB7E0, 0xBB95, 0xBB96, 0xBB97, 0xC1B8, 0xBB98,
+ /* U+7CB0 */ 0xBB99, 0xC1BB, 0xF4D3, 0xBEAC, 0xBB9A, 0xBB9B, 0xBB9C, 0xBB9D,
+ /* U+7CB8 */ 0xBB9E, 0xB4E2, 0xBB9F, 0xBBA0, 0xF4D4, 0xF4D5, 0xBEAB, 0xBC40,
+ /* U+7CC0 */ 0xBC41, 0xF4D6, 0xBC42, 0xBC43, 0xBC44, 0xF4DB, 0xBC45, 0xF4D7,
+ /* U+7CC8 */ 0xF4DA, 0xBC46, 0xBAFD, 0xBC47, 0xF4D8, 0xF4D9, 0xBC48, 0xBC49,
+ /* U+7CD0 */ 0xBC4A, 0xBC4B, 0xBC4C, 0xBC4D, 0xBC4E, 0xB8E2, 0xCCC7, 0xF4DC,
+ /* U+7CD8 */ 0xBC4F, 0xB2DA, 0xBC50, 0xBC51, 0xC3D3, 0xBC52, 0xBC53, 0xD4E3,
+ /* U+7CE0 */ 0xBFB7, 0xBC54, 0xBC55, 0xBC56, 0xBC57, 0xBC58, 0xBC59, 0xBC5A,
+ /* U+7CE8 */ 0xF4DD, 0xBC5B, 0xBC5C, 0xBC5D, 0xBC5E, 0xBC5F, 0xBC60, 0xC5B4,
+ /* U+7CF0 */ 0xBC61, 0xBC62, 0xBC63, 0xBC64, 0xBC65, 0xBC66, 0xBC67, 0xBC68,
+ /* U+7CF8 */ 0xF4E9, 0xBC69, 0xBC6A, 0xCFB5, 0xBC6B, 0xBC6C, 0xBC6D, 0xBC6E,
+ /* U+7D00 */ 0xBC6F, 0xBC70, 0xBC71, 0xBC72, 0xBC73, 0xBC74, 0xBC75, 0xBC76,
+ /* U+7D08 */ 0xBC77, 0xBC78, 0xCEC9, 0xBC79, 0xBC7A, 0xBC7B, 0xBC7C, 0xBC7D,
+ /* U+7D10 */ 0xBC7E, 0xBC80, 0xBC81, 0xBC82, 0xBC83, 0xBC84, 0xBC85, 0xBC86,
+ /* U+7D18 */ 0xBC87, 0xBC88, 0xBC89, 0xBC8A, 0xBC8B, 0xBC8C, 0xBC8D, 0xBC8E,
+ /* U+7D20 */ 0xCBD8, 0xBC8F, 0xCBF7, 0xBC90, 0xBC91, 0xBC92, 0xBC93, 0xBDF4,
+ /* U+7D28 */ 0xBC94, 0xBC95, 0xBC96, 0xD7CF, 0xBC97, 0xBC98, 0xBC99, 0xC0DB,
+ /* U+7D30 */ 0xBC9A, 0xBC9B, 0xBC9C, 0xBC9D, 0xBC9E, 0xBC9F, 0xBCA0, 0xBD40,
+ /* U+7D38 */ 0xBD41, 0xBD42, 0xBD43, 0xBD44, 0xBD45, 0xBD46, 0xBD47, 0xBD48,
+ /* U+7D40 */ 0xBD49, 0xBD4A, 0xBD4B, 0xBD4C, 0xBD4D, 0xBD4E, 0xBD4F, 0xBD50,
+ /* U+7D48 */ 0xBD51, 0xBD52, 0xBD53, 0xBD54, 0xBD55, 0xBD56, 0xBD57, 0xBD58,
+ /* U+7D50 */ 0xBD59, 0xBD5A, 0xBD5B, 0xBD5C, 0xBD5D, 0xBD5E, 0xBD5F, 0xBD60,
+ /* U+7D58 */ 0xBD61, 0xBD62, 0xBD63, 0xBD64, 0xBD65, 0xBD66, 0xBD67, 0xBD68,
+ /* U+7D60 */ 0xBD69, 0xBD6A, 0xBD6B, 0xBD6C, 0xBD6D, 0xBD6E, 0xBD6F, 0xBD70,
+ /* U+7D68 */ 0xBD71, 0xBD72, 0xBD73, 0xBD74, 0xBD75, 0xBD76, 0xD0F5, 0xBD77,
+ /* U+7D70 */ 0xBD78, 0xBD79, 0xBD7A, 0xBD7B, 0xBD7C, 0xBD7D, 0xBD7E, 0xF4EA,
+ /* U+7D78 */ 0xBD80, 0xBD81, 0xBD82, 0xBD83, 0xBD84, 0xBD85, 0xBD86, 0xBD87,
+ /* U+7D80 */ 0xBD88, 0xBD89, 0xBD8A, 0xBD8B, 0xBD8C, 0xBD8D, 0xBD8E, 0xBD8F,
+ /* U+7D88 */ 0xBD90, 0xBD91, 0xBD92, 0xBD93, 0xBD94, 0xBD95, 0xBD96, 0xBD97,
+ /* U+7D90 */ 0xBD98, 0xBD99, 0xBD9A, 0xBD9B, 0xBD9C, 0xBD9D, 0xBD9E, 0xBD9F,
+ /* U+7D98 */ 0xBDA0, 0xBE40, 0xBE41, 0xBE42, 0xBE43, 0xBE44, 0xBE45, 0xBE46,
+ /* U+7DA0 */ 0xBE47, 0xBE48, 0xBE49, 0xBE4A, 0xBE4B, 0xBE4C, 0xF4EB, 0xBE4D,
+ /* U+7DA8 */ 0xBE4E, 0xBE4F, 0xBE50, 0xBE51, 0xBE52, 0xBE53, 0xF4EC, 0xBE54,
+ /* U+7DB0 */ 0xBE55, 0xBE56, 0xBE57, 0xBE58, 0xBE59, 0xBE5A, 0xBE5B, 0xBE5C,
+ /* U+7DB8 */ 0xBE5D, 0xBE5E, 0xBE5F, 0xBE60, 0xBE61, 0xBE62, 0xBE63, 0xBE64,
+ /* U+7DC0 */ 0xBE65, 0xBE66, 0xBE67, 0xBE68, 0xBE69, 0xBE6A, 0xBE6B, 0xBE6C,
+ /* U+7DC8 */ 0xBE6D, 0xBE6E, 0xBE6F, 0xBE70, 0xBE71, 0xBE72, 0xBE73, 0xBE74,
+ /* U+7DD0 */ 0xBE75, 0xBE76, 0xBE77, 0xBE78, 0xBE79, 0xBE7A, 0xBE7B, 0xBE7C,
+ /* U+7DD8 */ 0xBE7D, 0xBE7E, 0xBE80, 0xBE81, 0xBE82, 0xBE83, 0xBE84, 0xBE85,
+ /* U+7DE0 */ 0xBE86, 0xBE87, 0xBE88, 0xBE89, 0xBE8A, 0xBE8B, 0xBE8C, 0xBE8D,
+ /* U+7DE8 */ 0xBE8E, 0xBE8F, 0xBE90, 0xBE91, 0xBE92, 0xBE93, 0xBE94, 0xBE95,
+ /* U+7DF0 */ 0xBE96, 0xBE97, 0xBE98, 0xBE99, 0xBE9A, 0xBE9B, 0xBE9C, 0xBE9D,
+ /* U+7DF8 */ 0xBE9E, 0xBE9F, 0xBEA0, 0xBF40, 0xBF41, 0xBF42, 0xBF43, 0xBF44,
+ /* U+7E00 */ 0xBF45, 0xBF46, 0xBF47, 0xBF48, 0xBF49, 0xBF4A, 0xBF4B, 0xBF4C,
+ /* U+7E08 */ 0xBF4D, 0xBF4E, 0xBF4F, 0xBF50, 0xBF51, 0xBF52, 0xBF53, 0xBF54,
+ /* U+7E10 */ 0xBF55, 0xBF56, 0xBF57, 0xBF58, 0xBF59, 0xBF5A, 0xBF5B, 0xBF5C,
+ /* U+7E18 */ 0xBF5D, 0xBF5E, 0xBF5F, 0xBF60, 0xBF61, 0xBF62, 0xBF63, 0xBF64,
+ /* U+7E20 */ 0xBF65, 0xBF66, 0xBF67, 0xBF68, 0xBF69, 0xBF6A, 0xBF6B, 0xBF6C,
+ /* U+7E28 */ 0xBF6D, 0xBF6E, 0xBF6F, 0xBF70, 0xBF71, 0xBF72, 0xBF73, 0xBF74,
+ /* U+7E30 */ 0xBF75, 0xBF76, 0xBF77, 0xBF78, 0xBF79, 0xBF7A, 0xBF7B, 0xBF7C,
+ /* U+7E38 */ 0xBF7D, 0xBF7E, 0xBF80, 0xF7E3, 0xBF81, 0xBF82, 0xBF83, 0xBF84,
+ /* U+7E40 */ 0xBF85, 0xB7B1, 0xBF86, 0xBF87, 0xBF88, 0xBF89, 0xBF8A, 0xF4ED,
+ /* U+7E48 */ 0xBF8B, 0xBF8C, 0xBF8D, 0xBF8E, 0xBF8F, 0xBF90, 0xBF91, 0xBF92,
+ /* U+7E50 */ 0xBF93, 0xBF94, 0xBF95, 0xBF96, 0xBF97, 0xBF98, 0xBF99, 0xBF9A,
+ /* U+7E58 */ 0xBF9B, 0xBF9C, 0xBF9D, 0xBF9E, 0xBF9F, 0xBFA0, 0xC040, 0xC041,
+ /* U+7E60 */ 0xC042, 0xC043, 0xC044, 0xC045, 0xC046, 0xC047, 0xC048, 0xC049,
+ /* U+7E68 */ 0xC04A, 0xC04B, 0xC04C, 0xC04D, 0xC04E, 0xC04F, 0xC050, 0xC051,
+ /* U+7E70 */ 0xC052, 0xC053, 0xC054, 0xC055, 0xC056, 0xC057, 0xC058, 0xC059,
+ /* U+7E78 */ 0xC05A, 0xC05B, 0xC05C, 0xC05D, 0xC05E, 0xC05F, 0xC060, 0xC061,
+ /* U+7E80 */ 0xC062, 0xC063, 0xD7EB, 0xC064, 0xC065, 0xC066, 0xC067, 0xC068,
+ /* U+7E88 */ 0xC069, 0xC06A, 0xC06B, 0xC06C, 0xC06D, 0xC06E, 0xC06F, 0xC070,
+ /* U+7E90 */ 0xC071, 0xC072, 0xC073, 0xC074, 0xC075, 0xC076, 0xC077, 0xC078,
+ /* U+7E98 */ 0xC079, 0xC07A, 0xC07B, 0xF4EE, 0xC07C, 0xC07D, 0xC07E, 0xE6F9,
+ /* U+7EA0 */ 0xBEC0, 0xE6FA, 0xBAEC, 0xE6FB, 0xCFCB, 0xE6FC, 0xD4BC, 0xBCB6,
+ /* U+7EA8 */ 0xE6FD, 0xE6FE, 0xBCCD, 0xC8D2, 0xCEB3, 0xE7A1, 0xC080, 0xB4BF,
+ /* U+7EB0 */ 0xE7A2, 0xC9B4, 0xB8D9, 0xC4C9, 0xC081, 0xD7DD, 0xC2DA, 0xB7D7,
+ /* U+7EB8 */ 0xD6BD, 0xCEC6, 0xB7C4, 0xC082, 0xC083, 0xC5A6, 0xE7A3, 0xCFDF,
+ /* U+7EC0 */ 0xE7A4, 0xE7A5, 0xE7A6, 0xC1B7, 0xD7E9, 0xC9F0, 0xCFB8, 0xD6AF,
+ /* U+7EC8 */ 0xD6D5, 0xE7A7, 0xB0ED, 0xE7A8, 0xE7A9, 0xC9DC, 0xD2EF, 0xBEAD,
+ /* U+7ED0 */ 0xE7AA, 0xB0F3, 0xC8DE, 0xBDE1, 0xE7AB, 0xC8C6, 0xC084, 0xE7AC,
+ /* U+7ED8 */ 0xBBE6, 0xB8F8, 0xD1A4, 0xE7AD, 0xC2E7, 0xBEF8, 0xBDCA, 0xCDB3,
+ /* U+7EE0 */ 0xE7AE, 0xE7AF, 0xBEEE, 0xD0E5, 0xC085, 0xCBE7, 0xCCD0, 0xBCCC,
+ /* U+7EE8 */ 0xE7B0, 0xBCA8, 0xD0F7, 0xE7B1, 0xC086, 0xD0F8, 0xE7B2, 0xE7B3,
+ /* U+7EF0 */ 0xB4C2, 0xE7B4, 0xE7B5, 0xC9FE, 0xCEAC, 0xC3E0, 0xE7B7, 0xB1C1,
+ /* U+7EF8 */ 0xB3F1, 0xC087, 0xE7B8, 0xE7B9, 0xD7DB, 0xD5C0, 0xE7BA, 0xC2CC,
+ /* U+7F00 */ 0xD7BA, 0xE7BB, 0xE7BC, 0xE7BD, 0xBCEA, 0xC3E5, 0xC0C2, 0xE7BE,
+ /* U+7F08 */ 0xE7BF, 0xBCA9, 0xC088, 0xE7C0, 0xE7C1, 0xE7B6, 0xB6D0, 0xE7C2,
+ /* U+7F10 */ 0xC089, 0xE7C3, 0xE7C4, 0xBBBA, 0xB5DE, 0xC2C6, 0xB1E0, 0xE7C5,
+ /* U+7F18 */ 0xD4B5, 0xE7C6, 0xB8BF, 0xE7C8, 0xE7C7, 0xB7EC, 0xC08A, 0xE7C9,
+ /* U+7F20 */ 0xB2F8, 0xE7CA, 0xE7CB, 0xE7CC, 0xE7CD, 0xE7CE, 0xE7CF, 0xE7D0,
+ /* U+7F28 */ 0xD3A7, 0xCBF5, 0xE7D1, 0xE7D2, 0xE7D3, 0xE7D4, 0xC9C9, 0xE7D5,
+ /* U+7F30 */ 0xE7D6, 0xE7D7, 0xE7D8, 0xE7D9, 0xBDC9, 0xE7DA, 0xF3BE, 0xC08B,
+ /* U+7F38 */ 0xB8D7, 0xC08C, 0xC8B1, 0xC08D, 0xC08E, 0xC08F, 0xC090, 0xC091,
+ /* U+7F40 */ 0xC092, 0xC093, 0xF3BF, 0xC094, 0xF3C0, 0xF3C1, 0xC095, 0xC096,
+ /* U+7F48 */ 0xC097, 0xC098, 0xC099, 0xC09A, 0xC09B, 0xC09C, 0xC09D, 0xC09E,
+ /* U+7F50 */ 0xB9DE, 0xCDF8, 0xC09F, 0xC0A0, 0xD8E8, 0xBAB1, 0xC140, 0xC2DE,
+ /* U+7F58 */ 0xEEB7, 0xC141, 0xB7A3, 0xC142, 0xC143, 0xC144, 0xC145, 0xEEB9,
+ /* U+7F60 */ 0xC146, 0xEEB8, 0xB0D5, 0xC147, 0xC148, 0xC149, 0xC14A, 0xC14B,
+ /* U+7F68 */ 0xEEBB, 0xD5D6, 0xD7EF, 0xC14C, 0xC14D, 0xC14E, 0xD6C3, 0xC14F,
+ /* U+7F70 */ 0xC150, 0xEEBD, 0xCAF0, 0xC151, 0xEEBC, 0xC152, 0xC153, 0xC154,
+ /* U+7F78 */ 0xC155, 0xEEBE, 0xC156, 0xC157, 0xC158, 0xC159, 0xEEC0, 0xC15A,
+ /* U+7F80 */ 0xC15B, 0xEEBF, 0xC15C, 0xC15D, 0xC15E, 0xC15F, 0xC160, 0xC161,
+ /* U+7F88 */ 0xC162, 0xC163, 0xD1F2, 0xC164, 0xC7BC, 0xC165, 0xC3C0, 0xC166,
+ /* U+7F90 */ 0xC167, 0xC168, 0xC169, 0xC16A, 0xB8E1, 0xC16B, 0xC16C, 0xC16D,
+ /* U+7F98 */ 0xC16E, 0xC16F, 0xC1E7, 0xC170, 0xC171, 0xF4C6, 0xD0DF, 0xF4C7,
+ /* U+7FA0 */ 0xC172, 0xCFDB, 0xC173, 0xC174, 0xC8BA, 0xC175, 0xC176, 0xF4C8,
+ /* U+7FA8 */ 0xC177, 0xC178, 0xC179, 0xC17A, 0xC17B, 0xC17C, 0xC17D, 0xF4C9,
+ /* U+7FB0 */ 0xF4CA, 0xC17E, 0xF4CB, 0xC180, 0xC181, 0xC182, 0xC183, 0xC184,
+ /* U+7FB8 */ 0xD9FA, 0xB8FE, 0xC185, 0xC186, 0xE5F1, 0xD3F0, 0xC187, 0xF4E0,
+ /* U+7FC0 */ 0xC188, 0xCECC, 0xC189, 0xC18A, 0xC18B, 0xB3E1, 0xC18C, 0xC18D,
+ /* U+7FC8 */ 0xC18E, 0xC18F, 0xF1B4, 0xC190, 0xD2EE, 0xC191, 0xF4E1, 0xC192,
+ /* U+7FD0 */ 0xC193, 0xC194, 0xC195, 0xC196, 0xCFE8, 0xF4E2, 0xC197, 0xC198,
+ /* U+7FD8 */ 0xC7CC, 0xC199, 0xC19A, 0xC19B, 0xC19C, 0xC19D, 0xC19E, 0xB5D4,
+ /* U+7FE0 */ 0xB4E4, 0xF4E4, 0xC19F, 0xC1A0, 0xC240, 0xF4E3, 0xF4E5, 0xC241,
+ /* U+7FE8 */ 0xC242, 0xF4E6, 0xC243, 0xC244, 0xC245, 0xC246, 0xF4E7, 0xC247,
+ /* U+7FF0 */ 0xBAB2, 0xB0BF, 0xC248, 0xF4E8, 0xC249, 0xC24A, 0xC24B, 0xC24C,
+ /* U+7FF8 */ 0xC24D, 0xC24E, 0xC24F, 0xB7AD, 0xD2ED, 0xC250, 0xC251, 0xC252,
+ /* U+8000 */ 0xD2AB, 0xC0CF, 0xC253, 0xBFBC, 0xEBA3, 0xD5DF, 0xEAC8, 0xC254,
+ /* U+8008 */ 0xC255, 0xC256, 0xC257, 0xF1F3, 0xB6F8, 0xCBA3, 0xC258, 0xC259,
+ /* U+8010 */ 0xC4CD, 0xC25A, 0xF1E7, 0xC25B, 0xF1E8, 0xB8FB, 0xF1E9, 0xBAC4,
+ /* U+8018 */ 0xD4C5, 0xB0D2, 0xC25C, 0xC25D, 0xF1EA, 0xC25E, 0xC25F, 0xC260,
+ /* U+8020 */ 0xF1EB, 0xC261, 0xF1EC, 0xC262, 0xC263, 0xF1ED, 0xF1EE, 0xF1EF,
+ /* U+8028 */ 0xF1F1, 0xF1F0, 0xC5D5, 0xC264, 0xC265, 0xC266, 0xC267, 0xC268,
+ /* U+8030 */ 0xC269, 0xF1F2, 0xC26A, 0xB6FA, 0xC26B, 0xF1F4, 0xD2AE, 0xDEC7,
+ /* U+8038 */ 0xCBCA, 0xC26C, 0xC26D, 0xB3DC, 0xC26E, 0xB5A2, 0xC26F, 0xB9A2,
+ /* U+8040 */ 0xC270, 0xC271, 0xC4F4, 0xF1F5, 0xC272, 0xC273, 0xF1F6, 0xC274,
+ /* U+8048 */ 0xC275, 0xC276, 0xC1C4, 0xC1FB, 0xD6B0, 0xF1F7, 0xC277, 0xC278,
+ /* U+8050 */ 0xC279, 0xC27A, 0xF1F8, 0xC27B, 0xC1AA, 0xC27C, 0xC27D, 0xC27E,
+ /* U+8058 */ 0xC6B8, 0xC280, 0xBEDB, 0xC281, 0xC282, 0xC283, 0xC284, 0xC285,
+ /* U+8060 */ 0xC286, 0xC287, 0xC288, 0xC289, 0xC28A, 0xC28B, 0xC28C, 0xC28D,
+ /* U+8068 */ 0xC28E, 0xF1F9, 0xB4CF, 0xC28F, 0xC290, 0xC291, 0xC292, 0xC293,
+ /* U+8070 */ 0xC294, 0xF1FA, 0xC295, 0xC296, 0xC297, 0xC298, 0xC299, 0xC29A,
+ /* U+8078 */ 0xC29B, 0xC29C, 0xC29D, 0xC29E, 0xC29F, 0xC2A0, 0xC340, 0xEDB2,
+ /* U+8080 */ 0xEDB1, 0xC341, 0xC342, 0xCBE0, 0xD2DE, 0xC343, 0xCBC1, 0xD5D8,
+ /* U+8088 */ 0xC344, 0xC8E2, 0xC345, 0xC0DF, 0xBCA1, 0xC346, 0xC347, 0xC348,
+ /* U+8090 */ 0xC349, 0xC34A, 0xC34B, 0xEBC1, 0xC34C, 0xC34D, 0xD0A4, 0xC34E,
+ /* U+8098 */ 0xD6E2, 0xC34F, 0xB6C7, 0xB8D8, 0xEBC0, 0xB8CE, 0xC350, 0xEBBF,
+ /* U+80A0 */ 0xB3A6, 0xB9C9, 0xD6AB, 0xC351, 0xB7F4, 0xB7CA, 0xC352, 0xC353,
+ /* U+80A8 */ 0xC354, 0xBCE7, 0xB7BE, 0xEBC6, 0xC355, 0xEBC7, 0xB0B9, 0xBFCF,
+ /* U+80B0 */ 0xC356, 0xEBC5, 0xD3FD, 0xC357, 0xEBC8, 0xC358, 0xC359, 0xEBC9,
+ /* U+80B8 */ 0xC35A, 0xC35B, 0xB7CE, 0xC35C, 0xEBC2, 0xEBC4, 0xC9F6, 0xD6D7,
+ /* U+80C0 */ 0xD5CD, 0xD0B2, 0xEBCF, 0xCEB8, 0xEBD0, 0xC35D, 0xB5A8, 0xC35E,
+ /* U+80C8 */ 0xC35F, 0xC360, 0xC361, 0xC362, 0xB1B3, 0xEBD2, 0xCCA5, 0xC363,
+ /* U+80D0 */ 0xC364, 0xC365, 0xC366, 0xC367, 0xC368, 0xC369, 0xC5D6, 0xEBD3,
+ /* U+80D8 */ 0xC36A, 0xEBD1, 0xC5DF, 0xEBCE, 0xCAA4, 0xEBD5, 0xB0FB, 0xC36B,
+ /* U+80E0 */ 0xC36C, 0xBAFA, 0xC36D, 0xC36E, 0xD8B7, 0xF1E3, 0xC36F, 0xEBCA,
+ /* U+80E8 */ 0xEBCB, 0xEBCC, 0xEBCD, 0xEBD6, 0xE6C0, 0xEBD9, 0xC370, 0xBFE8,
+ /* U+80F0 */ 0xD2C8, 0xEBD7, 0xEBDC, 0xB8EC, 0xEBD8, 0xC371, 0xBDBA, 0xC372,
+ /* U+80F8 */ 0xD0D8, 0xC373, 0xB0B7, 0xC374, 0xEBDD, 0xC4DC, 0xC375, 0xC376,
+ /* U+8100 */ 0xC377, 0xC378, 0xD6AC, 0xC379, 0xC37A, 0xC37B, 0xB4E0, 0xC37C,
+ /* U+8108 */ 0xC37D, 0xC2F6, 0xBCB9, 0xC37E, 0xC380, 0xEBDA, 0xEBDB, 0xD4E0,
+ /* U+8110 */ 0xC6EA, 0xC4D4, 0xEBDF, 0xC5A7, 0xD9F5, 0xC381, 0xB2B1, 0xC382,
+ /* U+8118 */ 0xEBE4, 0xC383, 0xBDC5, 0xC384, 0xC385, 0xC386, 0xEBE2, 0xC387,
+ /* U+8120 */ 0xC388, 0xC389, 0xC38A, 0xC38B, 0xC38C, 0xC38D, 0xC38E, 0xC38F,
+ /* U+8128 */ 0xC390, 0xC391, 0xC392, 0xC393, 0xEBE3, 0xC394, 0xC395, 0xB8AC,
+ /* U+8130 */ 0xC396, 0xCDD1, 0xEBE5, 0xC397, 0xC398, 0xC399, 0xEBE1, 0xC39A,
+ /* U+8138 */ 0xC1B3, 0xC39B, 0xC39C, 0xC39D, 0xC39E, 0xC39F, 0xC6A2, 0xC3A0,
+ /* U+8140 */ 0xC440, 0xC441, 0xC442, 0xC443, 0xC444, 0xC445, 0xCCF3, 0xC446,
+ /* U+8148 */ 0xEBE6, 0xC447, 0xC0B0, 0xD2B8, 0xEBE7, 0xC448, 0xC449, 0xC44A,
+ /* U+8150 */ 0xB8AF, 0xB8AD, 0xC44B, 0xEBE8, 0xC7BB, 0xCDF3, 0xC44C, 0xC44D,
+ /* U+8158 */ 0xC44E, 0xEBEA, 0xEBEB, 0xC44F, 0xC450, 0xC451, 0xC452, 0xC453,
+ /* U+8160 */ 0xEBED, 0xC454, 0xC455, 0xC456, 0xC457, 0xD0C8, 0xC458, 0xEBF2,
+ /* U+8168 */ 0xC459, 0xEBEE, 0xC45A, 0xC45B, 0xC45C, 0xEBF1, 0xC8F9, 0xC45D,
+ /* U+8170 */ 0xD1FC, 0xEBEC, 0xC45E, 0xC45F, 0xEBE9, 0xC460, 0xC461, 0xC462,
+ /* U+8178 */ 0xC463, 0xB8B9, 0xCFD9, 0xC4E5, 0xEBEF, 0xEBF0, 0xCCDA, 0xCDC8,
+ /* U+8180 */ 0xB0F2, 0xC464, 0xEBF6, 0xC465, 0xC466, 0xC467, 0xC468, 0xC469,
+ /* U+8188 */ 0xEBF5, 0xC46A, 0xB2B2, 0xC46B, 0xC46C, 0xC46D, 0xC46E, 0xB8E0,
+ /* U+8190 */ 0xC46F, 0xEBF7, 0xC470, 0xC471, 0xC472, 0xC473, 0xC474, 0xC475,
+ /* U+8198 */ 0xB1EC, 0xC476, 0xC477, 0xCCC5, 0xC4A4, 0xCFA5, 0xC478, 0xC479,
+ /* U+81A0 */ 0xC47A, 0xC47B, 0xC47C, 0xEBF9, 0xC47D, 0xC47E, 0xECA2, 0xC480,
+ /* U+81A8 */ 0xC5F2, 0xC481, 0xEBFA, 0xC482, 0xC483, 0xC484, 0xC485, 0xC486,
+ /* U+81B0 */ 0xC487, 0xC488, 0xC489, 0xC9C5, 0xC48A, 0xC48B, 0xC48C, 0xC48D,
+ /* U+81B8 */ 0xC48E, 0xC48F, 0xE2DF, 0xEBFE, 0xC490, 0xC491, 0xC492, 0xC493,
+ /* U+81C0 */ 0xCDCE, 0xECA1, 0xB1DB, 0xD3B7, 0xC494, 0xC495, 0xD2DC, 0xC496,
+ /* U+81C8 */ 0xC497, 0xC498, 0xEBFD, 0xC499, 0xEBFB, 0xC49A, 0xC49B, 0xC49C,
+ /* U+81D0 */ 0xC49D, 0xC49E, 0xC49F, 0xC4A0, 0xC540, 0xC541, 0xC542, 0xC543,
+ /* U+81D8 */ 0xC544, 0xC545, 0xC546, 0xC547, 0xC548, 0xC549, 0xC54A, 0xC54B,
+ /* U+81E0 */ 0xC54C, 0xC54D, 0xC54E, 0xB3BC, 0xC54F, 0xC550, 0xC551, 0xEAB0,
+ /* U+81E8 */ 0xC552, 0xC553, 0xD7D4, 0xC554, 0xF4AB, 0xB3F4, 0xC555, 0xC556,
+ /* U+81F0 */ 0xC557, 0xC558, 0xC559, 0xD6C1, 0xD6C2, 0xC55A, 0xC55B, 0xC55C,
+ /* U+81F8 */ 0xC55D, 0xC55E, 0xC55F, 0xD5E9, 0xBECA, 0xC560, 0xF4A7, 0xC561,
+ /* U+8200 */ 0xD2A8, 0xF4A8, 0xF4A9, 0xC562, 0xF4AA, 0xBECB, 0xD3DF, 0xC563,
+ /* U+8208 */ 0xC564, 0xC565, 0xC566, 0xC567, 0xC9E0, 0xC9E1, 0xC568, 0xC569,
+ /* U+8210 */ 0xF3C2, 0xC56A, 0xCAE6, 0xC56B, 0xCCF2, 0xC56C, 0xC56D, 0xC56E,
+ /* U+8218 */ 0xC56F, 0xC570, 0xC571, 0xE2B6, 0xCBB4, 0xC572, 0xCEE8, 0xD6DB,
+ /* U+8220 */ 0xC573, 0xF4AD, 0xF4AE, 0xF4AF, 0xC574, 0xC575, 0xC576, 0xC577,
+ /* U+8228 */ 0xF4B2, 0xC578, 0xBABD, 0xF4B3, 0xB0E3, 0xF4B0, 0xC579, 0xF4B1,
+ /* U+8230 */ 0xBDA2, 0xB2D5, 0xC57A, 0xF4B6, 0xF4B7, 0xB6E6, 0xB2B0, 0xCFCF,
+ /* U+8238 */ 0xF4B4, 0xB4AC, 0xC57B, 0xF4B5, 0xC57C, 0xC57D, 0xF4B8, 0xC57E,
+ /* U+8240 */ 0xC580, 0xC581, 0xC582, 0xC583, 0xF4B9, 0xC584, 0xC585, 0xCDA7,
+ /* U+8248 */ 0xC586, 0xF4BA, 0xC587, 0xF4BB, 0xC588, 0xC589, 0xC58A, 0xF4BC,
+ /* U+8250 */ 0xC58B, 0xC58C, 0xC58D, 0xC58E, 0xC58F, 0xC590, 0xC591, 0xC592,
+ /* U+8258 */ 0xCBD2, 0xC593, 0xF4BD, 0xC594, 0xC595, 0xC596, 0xC597, 0xF4BE,
+ /* U+8260 */ 0xC598, 0xC599, 0xC59A, 0xC59B, 0xC59C, 0xC59D, 0xC59E, 0xC59F,
+ /* U+8268 */ 0xF4BF, 0xC5A0, 0xC640, 0xC641, 0xC642, 0xC643, 0xF4DE, 0xC1BC,
+ /* U+8270 */ 0xBCE8, 0xC644, 0xC9AB, 0xD1DE, 0xE5F5, 0xC645, 0xC646, 0xC647,
+ /* U+8278 */ 0xC648, 0xDCB3, 0xD2D5, 0xC649, 0xC64A, 0xDCB4, 0xB0AC, 0xDCB5,
+ /* U+8280 */ 0xC64B, 0xC64C, 0xBDDA, 0xC64D, 0xDCB9, 0xC64E, 0xC64F, 0xC650,
+ /* U+8288 */ 0xD8C2, 0xC651, 0xDCB7, 0xD3F3, 0xC652, 0xC9D6, 0xDCBA, 0xDCB6,
+ /* U+8290 */ 0xC653, 0xDCBB, 0xC3A2, 0xC654, 0xC655, 0xC656, 0xC657, 0xDCBC,
+ /* U+8298 */ 0xDCC5, 0xDCBD, 0xC658, 0xC659, 0xCEDF, 0xD6A5, 0xC65A, 0xDCCF,
+ /* U+82A0 */ 0xC65B, 0xDCCD, 0xC65C, 0xC65D, 0xDCD2, 0xBDE6, 0xC2AB, 0xC65E,
+ /* U+82A8 */ 0xDCB8, 0xDCCB, 0xDCCE, 0xDCBE, 0xB7D2, 0xB0C5, 0xDCC7, 0xD0BE,
+ /* U+82B0 */ 0xDCC1, 0xBBA8, 0xC65F, 0xB7BC, 0xDCCC, 0xC660, 0xC661, 0xDCC6,
+ /* U+82B8 */ 0xDCBF, 0xC7DB, 0xC662, 0xC663, 0xC664, 0xD1BF, 0xDCC0, 0xC665,
+ /* U+82C0 */ 0xC666, 0xDCCA, 0xC667, 0xC668, 0xDCD0, 0xC669, 0xC66A, 0xCEAD,
+ /* U+82C8 */ 0xDCC2, 0xC66B, 0xDCC3, 0xDCC8, 0xDCC9, 0xB2D4, 0xDCD1, 0xCBD5,
+ /* U+82D0 */ 0xC66C, 0xD4B7, 0xDCDB, 0xDCDF, 0xCCA6, 0xDCE6, 0xC66D, 0xC3E7,
+ /* U+82D8 */ 0xDCDC, 0xC66E, 0xC66F, 0xBFC1, 0xDCD9, 0xC670, 0xB0FA, 0xB9B6,
+ /* U+82E0 */ 0xDCE5, 0xDCD3, 0xC671, 0xDCC4, 0xDCD6, 0xC8F4, 0xBFE0, 0xC672,
+ /* U+82E8 */ 0xC673, 0xC674, 0xC675, 0xC9BB, 0xC676, 0xC677, 0xC678, 0xB1BD,
+ /* U+82F0 */ 0xC679, 0xD3A2, 0xC67A, 0xC67B, 0xDCDA, 0xC67C, 0xC67D, 0xDCD5,
+ /* U+82F8 */ 0xC67E, 0xC6BB, 0xC680, 0xDCDE, 0xC681, 0xC682, 0xC683, 0xC684,
+ /* U+8300 */ 0xC685, 0xD7C2, 0xC3AF, 0xB7B6, 0xC7D1, 0xC3A9, 0xDCE2, 0xDCD8,
+ /* U+8308 */ 0xDCEB, 0xDCD4, 0xC686, 0xC687, 0xDCDD, 0xC688, 0xBEA5, 0xDCD7,
+ /* U+8310 */ 0xC689, 0xDCE0, 0xC68A, 0xC68B, 0xDCE3, 0xDCE4, 0xC68C, 0xDCF8,
+ /* U+8318 */ 0xC68D, 0xC68E, 0xDCE1, 0xDDA2, 0xDCE7, 0xC68F, 0xC690, 0xC691,
+ /* U+8320 */ 0xC692, 0xC693, 0xC694, 0xC695, 0xC696, 0xC697, 0xC698, 0xBCEB,
+ /* U+8328 */ 0xB4C4, 0xC699, 0xC69A, 0xC3A3, 0xB2E7, 0xDCFA, 0xC69B, 0xDCF2,
+ /* U+8330 */ 0xC69C, 0xDCEF, 0xC69D, 0xDCFC, 0xDCEE, 0xD2F0, 0xB2E8, 0xC69E,
+ /* U+8338 */ 0xC8D7, 0xC8E3, 0xDCFB, 0xC69F, 0xDCED, 0xC6A0, 0xC740, 0xC741,
+ /* U+8340 */ 0xDCF7, 0xC742, 0xC743, 0xDCF5, 0xC744, 0xC745, 0xBEA3, 0xDCF4,
+ /* U+8348 */ 0xC746, 0xB2DD, 0xC747, 0xC748, 0xC749, 0xC74A, 0xC74B, 0xDCF3,
+ /* U+8350 */ 0xBCF6, 0xDCE8, 0xBBC4, 0xC74C, 0xC0F3, 0xC74D, 0xC74E, 0xC74F,
+ /* U+8358 */ 0xC750, 0xC751, 0xBCD4, 0xDCE9, 0xDCEA, 0xC752, 0xDCF1, 0xDCF6,
+ /* U+8360 */ 0xDCF9, 0xB5B4, 0xC753, 0xC8D9, 0xBBE7, 0xDCFE, 0xDCFD, 0xD3AB,
+ /* U+8368 */ 0xDDA1, 0xDDA3, 0xDDA5, 0xD2F1, 0xDDA4, 0xDDA6, 0xDDA7, 0xD2A9,
+ /* U+8370 */ 0xC754, 0xC755, 0xC756, 0xC757, 0xC758, 0xC759, 0xC75A, 0xBAC9,
+ /* U+8378 */ 0xDDA9, 0xC75B, 0xC75C, 0xDDB6, 0xDDB1, 0xDDB4, 0xC75D, 0xC75E,
+ /* U+8380 */ 0xC75F, 0xC760, 0xC761, 0xC762, 0xC763, 0xDDB0, 0xC6CE, 0xC764,
+ /* U+8388 */ 0xC765, 0xC0F2, 0xC766, 0xC767, 0xC768, 0xC769, 0xC9AF, 0xC76A,
+ /* U+8390 */ 0xC76B, 0xC76C, 0xDCEC, 0xDDAE, 0xC76D, 0xC76E, 0xC76F, 0xC770,
+ /* U+8398 */ 0xDDB7, 0xC771, 0xC772, 0xDCF0, 0xDDAF, 0xC773, 0xDDB8, 0xC774,
+ /* U+83A0 */ 0xDDAC, 0xC775, 0xC776, 0xC777, 0xC778, 0xC779, 0xC77A, 0xC77B,
+ /* U+83A8 */ 0xDDB9, 0xDDB3, 0xDDAD, 0xC4AA, 0xC77C, 0xC77D, 0xC77E, 0xC780,
+ /* U+83B0 */ 0xDDA8, 0xC0B3, 0xC1AB, 0xDDAA, 0xDDAB, 0xC781, 0xDDB2, 0xBBF1,
+ /* U+83B8 */ 0xDDB5, 0xD3A8, 0xDDBA, 0xC782, 0xDDBB, 0xC3A7, 0xC783, 0xC784,
+ /* U+83C0 */ 0xDDD2, 0xDDBC, 0xC785, 0xC786, 0xC787, 0xDDD1, 0xC788, 0xB9BD,
+ /* U+83C8 */ 0xC789, 0xC78A, 0xBED5, 0xC78B, 0xBEFA, 0xC78C, 0xC78D, 0xBACA,
+ /* U+83D0 */ 0xC78E, 0xC78F, 0xC790, 0xC791, 0xDDCA, 0xC792, 0xDDC5, 0xC793,
+ /* U+83D8 */ 0xDDBF, 0xC794, 0xC795, 0xC796, 0xB2CB, 0xDDC3, 0xC797, 0xDDCB,
+ /* U+83E0 */ 0xB2A4, 0xDDD5, 0xC798, 0xC799, 0xC79A, 0xDDBE, 0xC79B, 0xC79C,
+ /* U+83E8 */ 0xC79D, 0xC6D0, 0xDDD0, 0xC79E, 0xC79F, 0xC7A0, 0xC840, 0xC841,
+ /* U+83F0 */ 0xDDD4, 0xC1E2, 0xB7C6, 0xC842, 0xC843, 0xC844, 0xC845, 0xC846,
+ /* U+83F8 */ 0xDDCE, 0xDDCF, 0xC847, 0xC848, 0xC849, 0xDDC4, 0xC84A, 0xC84B,
+ /* U+8400 */ 0xC84C, 0xDDBD, 0xC84D, 0xDDCD, 0xCCD1, 0xC84E, 0xDDC9, 0xC84F,
+ /* U+8408 */ 0xC850, 0xC851, 0xC852, 0xDDC2, 0xC3C8, 0xC6BC, 0xCEAE, 0xDDCC,
+ /* U+8410 */ 0xC853, 0xDDC8, 0xC854, 0xC855, 0xC856, 0xC857, 0xC858, 0xC859,
+ /* U+8418 */ 0xDDC1, 0xC85A, 0xC85B, 0xC85C, 0xDDC6, 0xC2DC, 0xC85D, 0xC85E,
+ /* U+8420 */ 0xC85F, 0xC860, 0xC861, 0xC862, 0xD3A9, 0xD3AA, 0xDDD3, 0xCFF4,
+ /* U+8428 */ 0xC8F8, 0xC863, 0xC864, 0xC865, 0xC866, 0xC867, 0xC868, 0xC869,
+ /* U+8430 */ 0xC86A, 0xDDE6, 0xC86B, 0xC86C, 0xC86D, 0xC86E, 0xC86F, 0xC870,
+ /* U+8438 */ 0xDDC7, 0xC871, 0xC872, 0xC873, 0xDDE0, 0xC2E4, 0xC874, 0xC875,
+ /* U+8440 */ 0xC876, 0xC877, 0xC878, 0xC879, 0xC87A, 0xC87B, 0xDDE1, 0xC87C,
+ /* U+8448 */ 0xC87D, 0xC87E, 0xC880, 0xC881, 0xC882, 0xC883, 0xC884, 0xC885,
+ /* U+8450 */ 0xC886, 0xDDD7, 0xC887, 0xC888, 0xC889, 0xC88A, 0xC88B, 0xD6F8,
+ /* U+8458 */ 0xC88C, 0xDDD9, 0xDDD8, 0xB8F0, 0xDDD6, 0xC88D, 0xC88E, 0xC88F,
+ /* U+8460 */ 0xC890, 0xC6CF, 0xC891, 0xB6AD, 0xC892, 0xC893, 0xC894, 0xC895,
+ /* U+8468 */ 0xC896, 0xDDE2, 0xC897, 0xBAF9, 0xD4E1, 0xDDE7, 0xC898, 0xC899,
+ /* U+8470 */ 0xC89A, 0xB4D0, 0xC89B, 0xDDDA, 0xC89C, 0xBFFB, 0xDDE3, 0xC89D,
+ /* U+8478 */ 0xDDDF, 0xC89E, 0xDDDD, 0xC89F, 0xC8A0, 0xC940, 0xC941, 0xC942,
+ /* U+8480 */ 0xC943, 0xC944, 0xB5D9, 0xC945, 0xC946, 0xC947, 0xC948, 0xDDDB,
+ /* U+8488 */ 0xDDDC, 0xDDDE, 0xC949, 0xBDAF, 0xDDE4, 0xC94A, 0xDDE5, 0xC94B,
+ /* U+8490 */ 0xC94C, 0xC94D, 0xC94E, 0xC94F, 0xC950, 0xC951, 0xC952, 0xDDF5,
+ /* U+8498 */ 0xC953, 0xC3C9, 0xC954, 0xC955, 0xCBE2, 0xC956, 0xC957, 0xC958,
+ /* U+84A0 */ 0xC959, 0xDDF2, 0xC95A, 0xC95B, 0xC95C, 0xC95D, 0xC95E, 0xC95F,
+ /* U+84A8 */ 0xC960, 0xC961, 0xC962, 0xC963, 0xC964, 0xC965, 0xC966, 0xD8E1,
+ /* U+84B0 */ 0xC967, 0xC968, 0xC6D1, 0xC969, 0xDDF4, 0xC96A, 0xC96B, 0xC96C,
+ /* U+84B8 */ 0xD5F4, 0xDDF3, 0xDDF0, 0xC96D, 0xC96E, 0xDDEC, 0xC96F, 0xDDEF,
+ /* U+84C0 */ 0xC970, 0xDDE8, 0xC971, 0xC972, 0xD0EE, 0xC973, 0xC974, 0xC975,
+ /* U+84C8 */ 0xC976, 0xC8D8, 0xDDEE, 0xC977, 0xC978, 0xDDE9, 0xC979, 0xC97A,
+ /* U+84D0 */ 0xDDEA, 0xCBF2, 0xC97B, 0xDDED, 0xC97C, 0xC97D, 0xB1CD, 0xC97E,
+ /* U+84D8 */ 0xC980, 0xC981, 0xC982, 0xC983, 0xC984, 0xC0B6, 0xC985, 0xBCBB,
+ /* U+84E0 */ 0xDDF1, 0xC986, 0xC987, 0xDDF7, 0xC988, 0xDDF6, 0xDDEB, 0xC989,
+ /* U+84E8 */ 0xC98A, 0xC98B, 0xC98C, 0xC98D, 0xC5EE, 0xC98E, 0xC98F, 0xC990,
+ /* U+84F0 */ 0xDDFB, 0xC991, 0xC992, 0xC993, 0xC994, 0xC995, 0xC996, 0xC997,
+ /* U+84F8 */ 0xC998, 0xC999, 0xC99A, 0xC99B, 0xDEA4, 0xC99C, 0xC99D, 0xDEA3,
+ /* U+8500 */ 0xC99E, 0xC99F, 0xC9A0, 0xCA40, 0xCA41, 0xCA42, 0xCA43, 0xCA44,
+ /* U+8508 */ 0xCA45, 0xCA46, 0xCA47, 0xCA48, 0xDDF8, 0xCA49, 0xCA4A, 0xCA4B,
+ /* U+8510 */ 0xCA4C, 0xC3EF, 0xCA4D, 0xC2FB, 0xCA4E, 0xCA4F, 0xCA50, 0xD5E1,
+ /* U+8518 */ 0xCA51, 0xCA52, 0xCEB5, 0xCA53, 0xCA54, 0xCA55, 0xCA56, 0xDDFD,
+ /* U+8520 */ 0xCA57, 0xB2CC, 0xCA58, 0xCA59, 0xCA5A, 0xCA5B, 0xCA5C, 0xCA5D,
+ /* U+8528 */ 0xCA5E, 0xCA5F, 0xCA60, 0xC4E8, 0xCADF, 0xCA61, 0xCA62, 0xCA63,
+ /* U+8530 */ 0xCA64, 0xCA65, 0xCA66, 0xCA67, 0xCA68, 0xCA69, 0xCA6A, 0xC7BE,
+ /* U+8538 */ 0xDDFA, 0xDDFC, 0xDDFE, 0xDEA2, 0xB0AA, 0xB1CE, 0xCA6B, 0xCA6C,
+ /* U+8540 */ 0xCA6D, 0xCA6E, 0xCA6F, 0xDEAC, 0xCA70, 0xCA71, 0xCA72, 0xCA73,
+ /* U+8548 */ 0xDEA6, 0xBDB6, 0xC8EF, 0xCA74, 0xCA75, 0xCA76, 0xCA77, 0xCA78,
+ /* U+8550 */ 0xCA79, 0xCA7A, 0xCA7B, 0xCA7C, 0xCA7D, 0xCA7E, 0xDEA1, 0xCA80,
+ /* U+8558 */ 0xCA81, 0xDEA5, 0xCA82, 0xCA83, 0xCA84, 0xCA85, 0xDEA9, 0xCA86,
+ /* U+8560 */ 0xCA87, 0xCA88, 0xCA89, 0xCA8A, 0xDEA8, 0xCA8B, 0xCA8C, 0xCA8D,
+ /* U+8568 */ 0xDEA7, 0xCA8E, 0xCA8F, 0xCA90, 0xCA91, 0xCA92, 0xCA93, 0xCA94,
+ /* U+8570 */ 0xCA95, 0xCA96, 0xDEAD, 0xCA97, 0xD4CC, 0xCA98, 0xCA99, 0xCA9A,
+ /* U+8578 */ 0xCA9B, 0xDEB3, 0xDEAA, 0xDEAE, 0xCA9C, 0xCA9D, 0xC0D9, 0xCA9E,
+ /* U+8580 */ 0xCA9F, 0xCAA0, 0xCB40, 0xCB41, 0xB1A1, 0xDEB6, 0xCB42, 0xDEB1,
+ /* U+8588 */ 0xCB43, 0xCB44, 0xCB45, 0xCB46, 0xCB47, 0xCB48, 0xCB49, 0xDEB2,
+ /* U+8590 */ 0xCB4A, 0xCB4B, 0xCB4C, 0xCB4D, 0xCB4E, 0xCB4F, 0xCB50, 0xCB51,
+ /* U+8598 */ 0xCB52, 0xCB53, 0xCB54, 0xD1A6, 0xDEB5, 0xCB55, 0xCB56, 0xCB57,
+ /* U+85A0 */ 0xCB58, 0xCB59, 0xCB5A, 0xCB5B, 0xDEAF, 0xCB5C, 0xCB5D, 0xCB5E,
+ /* U+85A8 */ 0xDEB0, 0xCB5F, 0xD0BD, 0xCB60, 0xCB61, 0xCB62, 0xDEB4, 0xCAED,
+ /* U+85B0 */ 0xDEB9, 0xCB63, 0xCB64, 0xCB65, 0xCB66, 0xCB67, 0xCB68, 0xDEB8,
+ /* U+85B8 */ 0xCB69, 0xDEB7, 0xCB6A, 0xCB6B, 0xCB6C, 0xCB6D, 0xCB6E, 0xCB6F,
+ /* U+85C0 */ 0xCB70, 0xDEBB, 0xCB71, 0xCB72, 0xCB73, 0xCB74, 0xCB75, 0xCB76,
+ /* U+85C8 */ 0xCB77, 0xBDE5, 0xCB78, 0xCB79, 0xCB7A, 0xCB7B, 0xCB7C, 0xB2D8,
+ /* U+85D0 */ 0xC3EA, 0xCB7D, 0xCB7E, 0xDEBA, 0xCB80, 0xC5BA, 0xCB81, 0xCB82,
+ /* U+85D8 */ 0xCB83, 0xCB84, 0xCB85, 0xCB86, 0xDEBC, 0xCB87, 0xCB88, 0xCB89,
+ /* U+85E0 */ 0xCB8A, 0xCB8B, 0xCB8C, 0xCB8D, 0xCCD9, 0xCB8E, 0xCB8F, 0xCB90,
+ /* U+85E8 */ 0xCB91, 0xB7AA, 0xCB92, 0xCB93, 0xCB94, 0xCB95, 0xCB96, 0xCB97,
+ /* U+85F0 */ 0xCB98, 0xCB99, 0xCB9A, 0xCB9B, 0xCB9C, 0xCB9D, 0xCB9E, 0xCB9F,
+ /* U+85F8 */ 0xCBA0, 0xCC40, 0xCC41, 0xD4E5, 0xCC42, 0xCC43, 0xCC44, 0xDEBD,
+ /* U+8600 */ 0xCC45, 0xCC46, 0xCC47, 0xCC48, 0xCC49, 0xDEBF, 0xCC4A, 0xCC4B,
+ /* U+8608 */ 0xCC4C, 0xCC4D, 0xCC4E, 0xCC4F, 0xCC50, 0xCC51, 0xCC52, 0xCC53,
+ /* U+8610 */ 0xCC54, 0xC4A2, 0xCC55, 0xCC56, 0xCC57, 0xCC58, 0xDEC1, 0xCC59,
+ /* U+8618 */ 0xCC5A, 0xCC5B, 0xCC5C, 0xCC5D, 0xCC5E, 0xCC5F, 0xCC60, 0xCC61,
+ /* U+8620 */ 0xCC62, 0xCC63, 0xCC64, 0xCC65, 0xCC66, 0xCC67, 0xCC68, 0xDEBE,
+ /* U+8628 */ 0xCC69, 0xDEC0, 0xCC6A, 0xCC6B, 0xCC6C, 0xCC6D, 0xCC6E, 0xCC6F,
+ /* U+8630 */ 0xCC70, 0xCC71, 0xCC72, 0xCC73, 0xCC74, 0xCC75, 0xCC76, 0xCC77,
+ /* U+8638 */ 0xD5BA, 0xCC78, 0xCC79, 0xCC7A, 0xDEC2, 0xCC7B, 0xCC7C, 0xCC7D,
+ /* U+8640 */ 0xCC7E, 0xCC80, 0xCC81, 0xCC82, 0xCC83, 0xCC84, 0xCC85, 0xCC86,
+ /* U+8648 */ 0xCC87, 0xCC88, 0xCC89, 0xCC8A, 0xCC8B, 0xF2AE, 0xBBA2, 0xC2B2,
+ /* U+8650 */ 0xC5B0, 0xC2C7, 0xCC8C, 0xCC8D, 0xF2AF, 0xCC8E, 0xCC8F, 0xCC90,
+ /* U+8658 */ 0xCC91, 0xCC92, 0xD0E9, 0xCC93, 0xCC94, 0xCC95, 0xD3DD, 0xCC96,
+ /* U+8660 */ 0xCC97, 0xCC98, 0xEBBD, 0xCC99, 0xCC9A, 0xCC9B, 0xCC9C, 0xCC9D,
+ /* U+8668 */ 0xCC9E, 0xCC9F, 0xCCA0, 0xB3E6, 0xF2B0, 0xCD40, 0xF2B1, 0xCD41,
+ /* U+8670 */ 0xCD42, 0xCAAD, 0xCD43, 0xCD44, 0xCD45, 0xCD46, 0xCD47, 0xCD48,
+ /* U+8678 */ 0xCD49, 0xBAE7, 0xF2B3, 0xF2B5, 0xF2B4, 0xCBE4, 0xCFBA, 0xF2B2,
+ /* U+8680 */ 0xCAB4, 0xD2CF, 0xC2EC, 0xCD4A, 0xCD4B, 0xCD4C, 0xCD4D, 0xCD4E,
+ /* U+8688 */ 0xCD4F, 0xCD50, 0xCEC3, 0xF2B8, 0xB0F6, 0xF2B7, 0xCD51, 0xCD52,
+ /* U+8690 */ 0xCD53, 0xCD54, 0xCD55, 0xF2BE, 0xCD56, 0xB2CF, 0xCD57, 0xCD58,
+ /* U+8698 */ 0xCD59, 0xCD5A, 0xCD5B, 0xCD5C, 0xD1C1, 0xF2BA, 0xCD5D, 0xCD5E,
+ /* U+86A0 */ 0xCD5F, 0xCD60, 0xCD61, 0xF2BC, 0xD4E9, 0xCD62, 0xCD63, 0xF2BB,
+ /* U+86A8 */ 0xF2B6, 0xF2BF, 0xF2BD, 0xCD64, 0xF2B9, 0xCD65, 0xCD66, 0xF2C7,
+ /* U+86B0 */ 0xF2C4, 0xF2C6, 0xCD67, 0xCD68, 0xF2CA, 0xF2C2, 0xF2C0, 0xCD69,
+ /* U+86B8 */ 0xCD6A, 0xCD6B, 0xF2C5, 0xCD6C, 0xCD6D, 0xCD6E, 0xCD6F, 0xCD70,
+ /* U+86C0 */ 0xD6FB, 0xCD71, 0xCD72, 0xCD73, 0xF2C1, 0xCD74, 0xC7F9, 0xC9DF,
+ /* U+86C8 */ 0xCD75, 0xF2C8, 0xB9C6, 0xB5B0, 0xCD76, 0xCD77, 0xF2C3, 0xF2C9,
+ /* U+86D0 */ 0xF2D0, 0xF2D6, 0xCD78, 0xCD79, 0xBBD7, 0xCD7A, 0xCD7B, 0xCD7C,
+ /* U+86D8 */ 0xF2D5, 0xCDDC, 0xCD7D, 0xD6EB, 0xCD7E, 0xCD80, 0xF2D2, 0xF2D4,
+ /* U+86E0 */ 0xCD81, 0xCD82, 0xCD83, 0xCD84, 0xB8F2, 0xCD85, 0xCD86, 0xCD87,
+ /* U+86E8 */ 0xCD88, 0xF2CB, 0xCD89, 0xCD8A, 0xCD8B, 0xF2CE, 0xC2F9, 0xCD8C,
+ /* U+86F0 */ 0xD5DD, 0xF2CC, 0xF2CD, 0xF2CF, 0xF2D3, 0xCD8D, 0xCD8E, 0xCD8F,
+ /* U+86F8 */ 0xF2D9, 0xD3BC, 0xCD90, 0xCD91, 0xCD92, 0xCD93, 0xB6EA, 0xCD94,
+ /* U+8700 */ 0xCAF1, 0xCD95, 0xB7E4, 0xF2D7, 0xCD96, 0xCD97, 0xCD98, 0xF2D8,
+ /* U+8708 */ 0xF2DA, 0xF2DD, 0xF2DB, 0xCD99, 0xCD9A, 0xF2DC, 0xCD9B, 0xCD9C,
+ /* U+8710 */ 0xCD9D, 0xCD9E, 0xD1D1, 0xF2D1, 0xCD9F, 0xCDC9, 0xCDA0, 0xCECF,
+ /* U+8718 */ 0xD6A9, 0xCE40, 0xF2E3, 0xCE41, 0xC3DB, 0xCE42, 0xF2E0, 0xCE43,
+ /* U+8720 */ 0xCE44, 0xC0AF, 0xF2EC, 0xF2DE, 0xCE45, 0xF2E1, 0xCE46, 0xCE47,
+ /* U+8728 */ 0xCE48, 0xF2E8, 0xCE49, 0xCE4A, 0xCE4B, 0xCE4C, 0xF2E2, 0xCE4D,
+ /* U+8730 */ 0xCE4E, 0xF2E7, 0xCE4F, 0xCE50, 0xF2E6, 0xCE51, 0xCE52, 0xF2E9,
+ /* U+8738 */ 0xCE53, 0xCE54, 0xCE55, 0xF2DF, 0xCE56, 0xCE57, 0xF2E4, 0xF2EA,
+ /* U+8740 */ 0xCE58, 0xCE59, 0xCE5A, 0xCE5B, 0xCE5C, 0xCE5D, 0xCE5E, 0xD3AC,
+ /* U+8748 */ 0xF2E5, 0xB2F5, 0xCE5F, 0xCE60, 0xF2F2, 0xCE61, 0xD0AB, 0xCE62,
+ /* U+8750 */ 0xCE63, 0xCE64, 0xCE65, 0xF2F5, 0xCE66, 0xCE67, 0xCE68, 0xBBC8,
+ /* U+8758 */ 0xCE69, 0xF2F9, 0xCE6A, 0xCE6B, 0xCE6C, 0xCE6D, 0xCE6E, 0xCE6F,
+ /* U+8760 */ 0xF2F0, 0xCE70, 0xCE71, 0xF2F6, 0xF2F8, 0xF2FA, 0xCE72, 0xCE73,
+ /* U+8768 */ 0xCE74, 0xCE75, 0xCE76, 0xCE77, 0xCE78, 0xCE79, 0xF2F3, 0xCE7A,
+ /* U+8770 */ 0xF2F1, 0xCE7B, 0xCE7C, 0xCE7D, 0xBAFB, 0xCE7E, 0xB5FB, 0xCE80,
+ /* U+8778 */ 0xCE81, 0xCE82, 0xCE83, 0xF2EF, 0xF2F7, 0xF2ED, 0xF2EE, 0xCE84,
+ /* U+8780 */ 0xCE85, 0xCE86, 0xF2EB, 0xF3A6, 0xCE87, 0xF3A3, 0xCE88, 0xCE89,
+ /* U+8788 */ 0xF3A2, 0xCE8A, 0xCE8B, 0xF2F4, 0xCE8C, 0xC8DA, 0xCE8D, 0xCE8E,
+ /* U+8790 */ 0xCE8F, 0xCE90, 0xCE91, 0xF2FB, 0xCE92, 0xCE93, 0xCE94, 0xF3A5,
+ /* U+8798 */ 0xCE95, 0xCE96, 0xCE97, 0xCE98, 0xCE99, 0xCE9A, 0xCE9B, 0xC3F8,
+ /* U+87A0 */ 0xCE9C, 0xCE9D, 0xCE9E, 0xCE9F, 0xCEA0, 0xCF40, 0xCF41, 0xCF42,
+ /* U+87A8 */ 0xF2FD, 0xCF43, 0xCF44, 0xF3A7, 0xF3A9, 0xF3A4, 0xCF45, 0xF2FC,
+ /* U+87B0 */ 0xCF46, 0xCF47, 0xCF48, 0xF3AB, 0xCF49, 0xF3AA, 0xCF4A, 0xCF4B,
+ /* U+87B8 */ 0xCF4C, 0xCF4D, 0xC2DD, 0xCF4E, 0xCF4F, 0xF3AE, 0xCF50, 0xCF51,
+ /* U+87C0 */ 0xF3B0, 0xCF52, 0xCF53, 0xCF54, 0xCF55, 0xCF56, 0xF3A1, 0xCF57,
+ /* U+87C8 */ 0xCF58, 0xCF59, 0xF3B1, 0xF3AC, 0xCF5A, 0xCF5B, 0xCF5C, 0xCF5D,
+ /* U+87D0 */ 0xCF5E, 0xF3AF, 0xF2FE, 0xF3AD, 0xCF5F, 0xCF60, 0xCF61, 0xCF62,
+ /* U+87D8 */ 0xCF63, 0xCF64, 0xCF65, 0xF3B2, 0xCF66, 0xCF67, 0xCF68, 0xCF69,
+ /* U+87E0 */ 0xF3B4, 0xCF6A, 0xCF6B, 0xCF6C, 0xCF6D, 0xF3A8, 0xCF6E, 0xCF6F,
+ /* U+87E8 */ 0xCF70, 0xCF71, 0xF3B3, 0xCF72, 0xCF73, 0xCF74, 0xF3B5, 0xCF75,
+ /* U+87F0 */ 0xCF76, 0xCF77, 0xCF78, 0xCF79, 0xCF7A, 0xCF7B, 0xCF7C, 0xCF7D,
+ /* U+87F8 */ 0xCF7E, 0xD0B7, 0xCF80, 0xCF81, 0xCF82, 0xCF83, 0xF3B8, 0xCF84,
+ /* U+8800 */ 0xCF85, 0xCF86, 0xCF87, 0xD9F9, 0xCF88, 0xCF89, 0xCF8A, 0xCF8B,
+ /* U+8808 */ 0xCF8C, 0xCF8D, 0xF3B9, 0xCF8E, 0xCF8F, 0xCF90, 0xCF91, 0xCF92,
+ /* U+8810 */ 0xCF93, 0xCF94, 0xCF95, 0xF3B7, 0xCF96, 0xC8E4, 0xF3B6, 0xCF97,
+ /* U+8818 */ 0xCF98, 0xCF99, 0xCF9A, 0xF3BA, 0xCF9B, 0xCF9C, 0xCF9D, 0xCF9E,
+ /* U+8820 */ 0xCF9F, 0xF3BB, 0xB4C0, 0xCFA0, 0xD040, 0xD041, 0xD042, 0xD043,
+ /* U+8828 */ 0xD044, 0xD045, 0xD046, 0xD047, 0xD048, 0xD049, 0xD04A, 0xD04B,
+ /* U+8830 */ 0xD04C, 0xD04D, 0xEEC3, 0xD04E, 0xD04F, 0xD050, 0xD051, 0xD052,
+ /* U+8838 */ 0xD053, 0xF3BC, 0xD054, 0xD055, 0xF3BD, 0xD056, 0xD057, 0xD058,
+ /* U+8840 */ 0xD1AA, 0xD059, 0xD05A, 0xD05B, 0xF4AC, 0xD0C6, 0xD05C, 0xD05D,
+ /* U+8848 */ 0xD05E, 0xD05F, 0xD060, 0xD061, 0xD0D0, 0xD1DC, 0xD062, 0xD063,
+ /* U+8850 */ 0xD064, 0xD065, 0xD066, 0xD067, 0xCFCE, 0xD068, 0xD069, 0xBDD6,
+ /* U+8858 */ 0xD06A, 0xD1C3, 0xD06B, 0xD06C, 0xD06D, 0xD06E, 0xD06F, 0xD070,
+ /* U+8860 */ 0xD071, 0xBAE2, 0xE1E9, 0xD2C2, 0xF1C2, 0xB2B9, 0xD072, 0xD073,
+ /* U+8868 */ 0xB1ED, 0xF1C3, 0xD074, 0xC9C0, 0xB3C4, 0xD075, 0xD9F2, 0xD076,
+ /* U+8870 */ 0xCBA5, 0xD077, 0xF1C4, 0xD078, 0xD079, 0xD07A, 0xD07B, 0xD6D4,
+ /* U+8878 */ 0xD07C, 0xD07D, 0xD07E, 0xD080, 0xD081, 0xF1C5, 0xF4C0, 0xF1C6,
+ /* U+8880 */ 0xD082, 0xD4AC, 0xF1C7, 0xD083, 0xB0C0, 0xF4C1, 0xD084, 0xD085,
+ /* U+8888 */ 0xF4C2, 0xD086, 0xD087, 0xB4FC, 0xD088, 0xC5DB, 0xD089, 0xD08A,
+ /* U+8890 */ 0xD08B, 0xD08C, 0xCCBB, 0xD08D, 0xD08E, 0xD08F, 0xD0E4, 0xD090,
+ /* U+8898 */ 0xD091, 0xD092, 0xD093, 0xD094, 0xCDE0, 0xD095, 0xD096, 0xD097,
+ /* U+88A0 */ 0xD098, 0xD099, 0xF1C8, 0xD09A, 0xD9F3, 0xD09B, 0xD09C, 0xD09D,
+ /* U+88A8 */ 0xD09E, 0xD09F, 0xD0A0, 0xB1BB, 0xD140, 0xCFAE, 0xD141, 0xD142,
+ /* U+88B0 */ 0xD143, 0xB8A4, 0xD144, 0xD145, 0xD146, 0xD147, 0xD148, 0xF1CA,
+ /* U+88B8 */ 0xD149, 0xD14A, 0xD14B, 0xD14C, 0xF1CB, 0xD14D, 0xD14E, 0xD14F,
+ /* U+88C0 */ 0xD150, 0xB2C3, 0xC1D1, 0xD151, 0xD152, 0xD7B0, 0xF1C9, 0xD153,
+ /* U+88C8 */ 0xD154, 0xF1CC, 0xD155, 0xD156, 0xD157, 0xD158, 0xF1CE, 0xD159,
+ /* U+88D0 */ 0xD15A, 0xD15B, 0xD9F6, 0xD15C, 0xD2E1, 0xD4A3, 0xD15D, 0xD15E,
+ /* U+88D8 */ 0xF4C3, 0xC8B9, 0xD15F, 0xD160, 0xD161, 0xD162, 0xD163, 0xF4C4,
+ /* U+88E0 */ 0xD164, 0xD165, 0xF1CD, 0xF1CF, 0xBFE3, 0xF1D0, 0xD166, 0xD167,
+ /* U+88E8 */ 0xF1D4, 0xD168, 0xD169, 0xD16A, 0xD16B, 0xD16C, 0xD16D, 0xD16E,
+ /* U+88F0 */ 0xF1D6, 0xF1D1, 0xD16F, 0xC9D1, 0xC5E1, 0xD170, 0xD171, 0xD172,
+ /* U+88F8 */ 0xC2E3, 0xB9FC, 0xD173, 0xD174, 0xF1D3, 0xD175, 0xF1D5, 0xD176,
+ /* U+8900 */ 0xD177, 0xD178, 0xB9D3, 0xD179, 0xD17A, 0xD17B, 0xD17C, 0xD17D,
+ /* U+8908 */ 0xD17E, 0xD180, 0xF1DB, 0xD181, 0xD182, 0xD183, 0xD184, 0xD185,
+ /* U+8910 */ 0xBAD6, 0xD186, 0xB0FD, 0xF1D9, 0xD187, 0xD188, 0xD189, 0xD18A,
+ /* U+8918 */ 0xD18B, 0xF1D8, 0xF1D2, 0xF1DA, 0xD18C, 0xD18D, 0xD18E, 0xD18F,
+ /* U+8920 */ 0xD190, 0xF1D7, 0xD191, 0xD192, 0xD193, 0xC8EC, 0xD194, 0xD195,
+ /* U+8928 */ 0xD196, 0xD197, 0xCDCA, 0xF1DD, 0xD198, 0xD199, 0xD19A, 0xD19B,
+ /* U+8930 */ 0xE5BD, 0xD19C, 0xD19D, 0xD19E, 0xF1DC, 0xD19F, 0xF1DE, 0xD1A0,
+ /* U+8938 */ 0xD240, 0xD241, 0xD242, 0xD243, 0xD244, 0xD245, 0xD246, 0xD247,
+ /* U+8940 */ 0xD248, 0xF1DF, 0xD249, 0xD24A, 0xCFE5, 0xD24B, 0xD24C, 0xD24D,
+ /* U+8948 */ 0xD24E, 0xD24F, 0xD250, 0xD251, 0xD252, 0xD253, 0xD254, 0xD255,
+ /* U+8950 */ 0xD256, 0xD257, 0xD258, 0xD259, 0xD25A, 0xD25B, 0xD25C, 0xD25D,
+ /* U+8958 */ 0xD25E, 0xD25F, 0xD260, 0xD261, 0xD262, 0xD263, 0xF4C5, 0xBDF3,
+ /* U+8960 */ 0xD264, 0xD265, 0xD266, 0xD267, 0xD268, 0xD269, 0xF1E0, 0xD26A,
+ /* U+8968 */ 0xD26B, 0xD26C, 0xD26D, 0xD26E, 0xD26F, 0xD270, 0xD271, 0xD272,
+ /* U+8970 */ 0xD273, 0xD274, 0xD275, 0xD276, 0xD277, 0xD278, 0xD279, 0xD27A,
+ /* U+8978 */ 0xD27B, 0xD27C, 0xD27D, 0xF1E1, 0xD27E, 0xD280, 0xD281, 0xCEF7,
+ /* U+8980 */ 0xD282, 0xD2AA, 0xD283, 0xF1FB, 0xD284, 0xD285, 0xB8B2, 0xD286,
+ /* U+8988 */ 0xD287, 0xD288, 0xD289, 0xD28A, 0xD28B, 0xD28C, 0xD28D, 0xD28E,
+ /* U+8990 */ 0xD28F, 0xD290, 0xD291, 0xD292, 0xD293, 0xD294, 0xD295, 0xD296,
+ /* U+8998 */ 0xD297, 0xD298, 0xD299, 0xD29A, 0xD29B, 0xD29C, 0xD29D, 0xD29E,
+ /* U+89A0 */ 0xD29F, 0xD2A0, 0xD340, 0xD341, 0xD342, 0xD343, 0xD344, 0xD345,
+ /* U+89A8 */ 0xD346, 0xD347, 0xD348, 0xD349, 0xD34A, 0xD34B, 0xD34C, 0xD34D,
+ /* U+89B0 */ 0xD34E, 0xD34F, 0xD350, 0xD351, 0xD352, 0xD353, 0xD354, 0xD355,
+ /* U+89B8 */ 0xD356, 0xD357, 0xD358, 0xD359, 0xD35A, 0xD35B, 0xD35C, 0xD35D,
+ /* U+89C0 */ 0xD35E, 0xBCFB, 0xB9DB, 0xD35F, 0xB9E6, 0xC3D9, 0xCAD3, 0xEAE8,
+ /* U+89C8 */ 0xC0C0, 0xBEF5, 0xEAE9, 0xEAEA, 0xEAEB, 0xD360, 0xEAEC, 0xEAED,
+ /* U+89D0 */ 0xEAEE, 0xEAEF, 0xBDC7, 0xD361, 0xD362, 0xD363, 0xF5FB, 0xD364,
+ /* U+89D8 */ 0xD365, 0xD366, 0xF5FD, 0xD367, 0xF5FE, 0xD368, 0xF5FC, 0xD369,
+ /* U+89E0 */ 0xD36A, 0xD36B, 0xD36C, 0xBDE2, 0xD36D, 0xF6A1, 0xB4A5, 0xD36E,
+ /* U+89E8 */ 0xD36F, 0xD370, 0xD371, 0xF6A2, 0xD372, 0xD373, 0xD374, 0xF6A3,
+ /* U+89F0 */ 0xD375, 0xD376, 0xD377, 0xECB2, 0xD378, 0xD379, 0xD37A, 0xD37B,
+ /* U+89F8 */ 0xD37C, 0xD37D, 0xD37E, 0xD380, 0xD381, 0xD382, 0xD383, 0xD384,
+ /* U+8A00 */ 0xD1D4, 0xD385, 0xD386, 0xD387, 0xD388, 0xD389, 0xD38A, 0xD9EA,
+ /* U+8A08 */ 0xD38B, 0xD38C, 0xD38D, 0xD38E, 0xD38F, 0xD390, 0xD391, 0xD392,
+ /* U+8A10 */ 0xD393, 0xD394, 0xD395, 0xD396, 0xD397, 0xD398, 0xD399, 0xD39A,
+ /* U+8A18 */ 0xD39B, 0xD39C, 0xD39D, 0xD39E, 0xD39F, 0xD3A0, 0xD440, 0xD441,
+ /* U+8A20 */ 0xD442, 0xD443, 0xD444, 0xD445, 0xD446, 0xD447, 0xD448, 0xD449,
+ /* U+8A28 */ 0xD44A, 0xD44B, 0xD44C, 0xD44D, 0xD44E, 0xD44F, 0xD450, 0xD451,
+ /* U+8A30 */ 0xD452, 0xD453, 0xD454, 0xD455, 0xD456, 0xD457, 0xD458, 0xD459,
+ /* U+8A38 */ 0xD45A, 0xD45B, 0xD45C, 0xD45D, 0xD45E, 0xD45F, 0xF6A4, 0xD460,
+ /* U+8A40 */ 0xD461, 0xD462, 0xD463, 0xD464, 0xD465, 0xD466, 0xD467, 0xD468,
+ /* U+8A48 */ 0xEEBA, 0xD469, 0xD46A, 0xD46B, 0xD46C, 0xD46D, 0xD46E, 0xD46F,
+ /* U+8A50 */ 0xD470, 0xD471, 0xD472, 0xD473, 0xD474, 0xD475, 0xD476, 0xD477,
+ /* U+8A58 */ 0xD478, 0xD479, 0xD47A, 0xD47B, 0xD47C, 0xD47D, 0xD47E, 0xD480,
+ /* U+8A60 */ 0xD481, 0xD482, 0xD483, 0xD484, 0xD485, 0xD486, 0xD487, 0xD488,
+ /* U+8A68 */ 0xD489, 0xD48A, 0xD48B, 0xD48C, 0xD48D, 0xD48E, 0xD48F, 0xD490,
+ /* U+8A70 */ 0xD491, 0xD492, 0xD493, 0xD494, 0xD495, 0xD496, 0xD497, 0xD498,
+ /* U+8A78 */ 0xD499, 0xD5B2, 0xD49A, 0xD49B, 0xD49C, 0xD49D, 0xD49E, 0xD49F,
+ /* U+8A80 */ 0xD4A0, 0xD540, 0xD541, 0xD542, 0xD543, 0xD544, 0xD545, 0xD546,
+ /* U+8A88 */ 0xD547, 0xD3FE, 0xCCDC, 0xD548, 0xD549, 0xD54A, 0xD54B, 0xD54C,
+ /* U+8A90 */ 0xD54D, 0xD54E, 0xD54F, 0xCAC4, 0xD550, 0xD551, 0xD552, 0xD553,
+ /* U+8A98 */ 0xD554, 0xD555, 0xD556, 0xD557, 0xD558, 0xD559, 0xD55A, 0xD55B,
+ /* U+8AA0 */ 0xD55C, 0xD55D, 0xD55E, 0xD55F, 0xD560, 0xD561, 0xD562, 0xD563,
+ /* U+8AA8 */ 0xD564, 0xD565, 0xD566, 0xD567, 0xD568, 0xD569, 0xD56A, 0xD56B,
+ /* U+8AB0 */ 0xD56C, 0xD56D, 0xD56E, 0xD56F, 0xD570, 0xD571, 0xD572, 0xD573,
+ /* U+8AB8 */ 0xD574, 0xD575, 0xD576, 0xD577, 0xD578, 0xD579, 0xD57A, 0xD57B,
+ /* U+8AC0 */ 0xD57C, 0xD57D, 0xD57E, 0xD580, 0xD581, 0xD582, 0xD583, 0xD584,
+ /* U+8AC8 */ 0xD585, 0xD586, 0xD587, 0xD588, 0xD589, 0xD58A, 0xD58B, 0xD58C,
+ /* U+8AD0 */ 0xD58D, 0xD58E, 0xD58F, 0xD590, 0xD591, 0xD592, 0xD593, 0xD594,
+ /* U+8AD8 */ 0xD595, 0xD596, 0xD597, 0xD598, 0xD599, 0xD59A, 0xD59B, 0xD59C,
+ /* U+8AE0 */ 0xD59D, 0xD59E, 0xD59F, 0xD5A0, 0xD640, 0xD641, 0xD642, 0xD643,
+ /* U+8AE8 */ 0xD644, 0xD645, 0xD646, 0xD647, 0xD648, 0xD649, 0xD64A, 0xD64B,
+ /* U+8AF0 */ 0xD64C, 0xD64D, 0xD64E, 0xD64F, 0xD650, 0xD651, 0xD652, 0xD653,
+ /* U+8AF8 */ 0xD654, 0xD655, 0xD656, 0xD657, 0xD658, 0xD659, 0xD65A, 0xD65B,
+ /* U+8B00 */ 0xD65C, 0xD65D, 0xD65E, 0xD65F, 0xD660, 0xD661, 0xD662, 0xE5C0,
+ /* U+8B08 */ 0xD663, 0xD664, 0xD665, 0xD666, 0xD667, 0xD668, 0xD669, 0xD66A,
+ /* U+8B10 */ 0xD66B, 0xD66C, 0xD66D, 0xD66E, 0xD66F, 0xD670, 0xD671, 0xD672,
+ /* U+8B18 */ 0xD673, 0xD674, 0xD675, 0xD676, 0xD677, 0xD678, 0xD679, 0xD67A,
+ /* U+8B20 */ 0xD67B, 0xD67C, 0xD67D, 0xD67E, 0xD680, 0xD681, 0xF6A5, 0xD682,
+ /* U+8B28 */ 0xD683, 0xD684, 0xD685, 0xD686, 0xD687, 0xD688, 0xD689, 0xD68A,
+ /* U+8B30 */ 0xD68B, 0xD68C, 0xD68D, 0xD68E, 0xD68F, 0xD690, 0xD691, 0xD692,
+ /* U+8B38 */ 0xD693, 0xD694, 0xD695, 0xD696, 0xD697, 0xD698, 0xD699, 0xD69A,
+ /* U+8B40 */ 0xD69B, 0xD69C, 0xD69D, 0xD69E, 0xD69F, 0xD6A0, 0xD740, 0xD741,
+ /* U+8B48 */ 0xD742, 0xD743, 0xD744, 0xD745, 0xD746, 0xD747, 0xD748, 0xD749,
+ /* U+8B50 */ 0xD74A, 0xD74B, 0xD74C, 0xD74D, 0xD74E, 0xD74F, 0xD750, 0xD751,
+ /* U+8B58 */ 0xD752, 0xD753, 0xD754, 0xD755, 0xD756, 0xD757, 0xD758, 0xD759,
+ /* U+8B60 */ 0xD75A, 0xD75B, 0xD75C, 0xD75D, 0xD75E, 0xD75F, 0xBEAF, 0xD760,
+ /* U+8B68 */ 0xD761, 0xD762, 0xD763, 0xD764, 0xC6A9, 0xD765, 0xD766, 0xD767,
+ /* U+8B70 */ 0xD768, 0xD769, 0xD76A, 0xD76B, 0xD76C, 0xD76D, 0xD76E, 0xD76F,
+ /* U+8B78 */ 0xD770, 0xD771, 0xD772, 0xD773, 0xD774, 0xD775, 0xD776, 0xD777,
+ /* U+8B80 */ 0xD778, 0xD779, 0xD77A, 0xD77B, 0xD77C, 0xD77D, 0xD77E, 0xD780,
+ /* U+8B88 */ 0xD781, 0xD782, 0xD783, 0xD784, 0xD785, 0xD786, 0xD787, 0xD788,
+ /* U+8B90 */ 0xD789, 0xD78A, 0xD78B, 0xD78C, 0xD78D, 0xD78E, 0xD78F, 0xD790,
+ /* U+8B98 */ 0xD791, 0xD792, 0xD793, 0xD794, 0xD795, 0xD796, 0xD797, 0xD798,
+ /* U+8BA0 */ 0xDAA5, 0xBCC6, 0xB6A9, 0xB8BC, 0xC8CF, 0xBCA5, 0xDAA6, 0xDAA7,
+ /* U+8BA8 */ 0xCCD6, 0xC8C3, 0xDAA8, 0xC6FD, 0xD799, 0xD1B5, 0xD2E9, 0xD1B6,
+ /* U+8BB0 */ 0xBCC7, 0xD79A, 0xBDB2, 0xBBE4, 0xDAA9, 0xDAAA, 0xD1C8, 0xDAAB,
+ /* U+8BB8 */ 0xD0ED, 0xB6EF, 0xC2DB, 0xD79B, 0xCBCF, 0xB7ED, 0xC9E8, 0xB7C3,
+ /* U+8BC0 */ 0xBEF7, 0xD6A4, 0xDAAC, 0xDAAD, 0xC6C0, 0xD7E7, 0xCAB6, 0xD79C,
+ /* U+8BC8 */ 0xD5A9, 0xCBDF, 0xD5EF, 0xDAAE, 0xD6DF, 0xB4CA, 0xDAB0, 0xDAAF,
+ /* U+8BD0 */ 0xD79D, 0xD2EB, 0xDAB1, 0xDAB2, 0xDAB3, 0xCAD4, 0xDAB4, 0xCAAB,
+ /* U+8BD8 */ 0xDAB5, 0xDAB6, 0xB3CF, 0xD6EF, 0xDAB7, 0xBBB0, 0xB5AE, 0xDAB8,
+ /* U+8BE0 */ 0xDAB9, 0xB9EE, 0xD1AF, 0xD2E8, 0xDABA, 0xB8C3, 0xCFEA, 0xB2EF,
+ /* U+8BE8 */ 0xDABB, 0xDABC, 0xD79E, 0xBDEB, 0xCEDC, 0xD3EF, 0xDABD, 0xCEF3,
+ /* U+8BF0 */ 0xDABE, 0xD3D5, 0xBBE5, 0xDABF, 0xCBB5, 0xCBD0, 0xDAC0, 0xC7EB,
+ /* U+8BF8 */ 0xD6EE, 0xDAC1, 0xC5B5, 0xB6C1, 0xDAC2, 0xB7CC, 0xBFCE, 0xDAC3,
+ /* U+8C00 */ 0xDAC4, 0xCBAD, 0xDAC5, 0xB5F7, 0xDAC6, 0xC1C2, 0xD7BB, 0xDAC7,
+ /* U+8C08 */ 0xCCB8, 0xD79F, 0xD2EA, 0xC4B1, 0xDAC8, 0xB5FD, 0xBBD1, 0xDAC9,
+ /* U+8C10 */ 0xD0B3, 0xDACA, 0xDACB, 0xCEBD, 0xDACC, 0xDACD, 0xDACE, 0xB2F7,
+ /* U+8C18 */ 0xDAD1, 0xDACF, 0xD1E8, 0xDAD0, 0xC3D5, 0xDAD2, 0xD7A0, 0xDAD3,
+ /* U+8C20 */ 0xDAD4, 0xDAD5, 0xD0BB, 0xD2A5, 0xB0F9, 0xDAD6, 0xC7AB, 0xDAD7,
+ /* U+8C28 */ 0xBDF7, 0xC3A1, 0xDAD8, 0xDAD9, 0xC3FD, 0xCCB7, 0xDADA, 0xDADB,
+ /* U+8C30 */ 0xC0BE, 0xC6D7, 0xDADC, 0xDADD, 0xC7B4, 0xDADE, 0xDADF, 0xB9C8,
+ /* U+8C38 */ 0xD840, 0xD841, 0xD842, 0xD843, 0xD844, 0xD845, 0xD846, 0xD847,
+ /* U+8C40 */ 0xD848, 0xBBED, 0xD849, 0xD84A, 0xD84B, 0xD84C, 0xB6B9, 0xF4F8,
+ /* U+8C48 */ 0xD84D, 0xF4F9, 0xD84E, 0xD84F, 0xCDE3, 0xD850, 0xD851, 0xD852,
+ /* U+8C50 */ 0xD853, 0xD854, 0xD855, 0xD856, 0xD857, 0xF5B9, 0xD858, 0xD859,
+ /* U+8C58 */ 0xD85A, 0xD85B, 0xEBE0, 0xD85C, 0xD85D, 0xD85E, 0xD85F, 0xD860,
+ /* U+8C60 */ 0xD861, 0xCFF3, 0xBBBF, 0xD862, 0xD863, 0xD864, 0xD865, 0xD866,
+ /* U+8C68 */ 0xD867, 0xD868, 0xBAC0, 0xD4A5, 0xD869, 0xD86A, 0xD86B, 0xD86C,
+ /* U+8C70 */ 0xD86D, 0xD86E, 0xD86F, 0xE1D9, 0xD870, 0xD871, 0xD872, 0xD873,
+ /* U+8C78 */ 0xF5F4, 0xB1AA, 0xB2F2, 0xD874, 0xD875, 0xD876, 0xD877, 0xD878,
+ /* U+8C80 */ 0xD879, 0xD87A, 0xF5F5, 0xD87B, 0xD87C, 0xF5F7, 0xD87D, 0xD87E,
+ /* U+8C88 */ 0xD880, 0xBAD1, 0xF5F6, 0xD881, 0xC3B2, 0xD882, 0xD883, 0xD884,
+ /* U+8C90 */ 0xD885, 0xD886, 0xD887, 0xD888, 0xF5F9, 0xD889, 0xD88A, 0xD88B,
+ /* U+8C98 */ 0xF5F8, 0xD88C, 0xD88D, 0xD88E, 0xD88F, 0xD890, 0xD891, 0xD892,
+ /* U+8CA0 */ 0xD893, 0xD894, 0xD895, 0xD896, 0xD897, 0xD898, 0xD899, 0xD89A,
+ /* U+8CA8 */ 0xD89B, 0xD89C, 0xD89D, 0xD89E, 0xD89F, 0xD8A0, 0xD940, 0xD941,
+ /* U+8CB0 */ 0xD942, 0xD943, 0xD944, 0xD945, 0xD946, 0xD947, 0xD948, 0xD949,
+ /* U+8CB8 */ 0xD94A, 0xD94B, 0xD94C, 0xD94D, 0xD94E, 0xD94F, 0xD950, 0xD951,
+ /* U+8CC0 */ 0xD952, 0xD953, 0xD954, 0xD955, 0xD956, 0xD957, 0xD958, 0xD959,
+ /* U+8CC8 */ 0xD95A, 0xD95B, 0xD95C, 0xD95D, 0xD95E, 0xD95F, 0xD960, 0xD961,
+ /* U+8CD0 */ 0xD962, 0xD963, 0xD964, 0xD965, 0xD966, 0xD967, 0xD968, 0xD969,
+ /* U+8CD8 */ 0xD96A, 0xD96B, 0xD96C, 0xD96D, 0xD96E, 0xD96F, 0xD970, 0xD971,
+ /* U+8CE0 */ 0xD972, 0xD973, 0xD974, 0xD975, 0xD976, 0xD977, 0xD978, 0xD979,
+ /* U+8CE8 */ 0xD97A, 0xD97B, 0xD97C, 0xD97D, 0xD97E, 0xD980, 0xD981, 0xD982,
+ /* U+8CF0 */ 0xD983, 0xD984, 0xD985, 0xD986, 0xD987, 0xD988, 0xD989, 0xD98A,
+ /* U+8CF8 */ 0xD98B, 0xD98C, 0xD98D, 0xD98E, 0xD98F, 0xD990, 0xD991, 0xD992,
+ /* U+8D00 */ 0xD993, 0xD994, 0xD995, 0xD996, 0xD997, 0xD998, 0xD999, 0xD99A,
+ /* U+8D08 */ 0xD99B, 0xD99C, 0xD99D, 0xD99E, 0xD99F, 0xD9A0, 0xDA40, 0xDA41,
+ /* U+8D10 */ 0xDA42, 0xDA43, 0xDA44, 0xDA45, 0xDA46, 0xDA47, 0xDA48, 0xDA49,
+ /* U+8D18 */ 0xDA4A, 0xDA4B, 0xDA4C, 0xDA4D, 0xDA4E, 0xB1B4, 0xD5EA, 0xB8BA,
+ /* U+8D20 */ 0xDA4F, 0xB9B1, 0xB2C6, 0xD4F0, 0xCFCD, 0xB0DC, 0xD5CB, 0xBBF5,
+ /* U+8D28 */ 0xD6CA, 0xB7B7, 0xCCB0, 0xC6B6, 0xB1E1, 0xB9BA, 0xD6FC, 0xB9E1,
+ /* U+8D30 */ 0xB7A1, 0xBCFA, 0xEADA, 0xEADB, 0xCCF9, 0xB9F3, 0xEADC, 0xB4FB,
+ /* U+8D38 */ 0xC3B3, 0xB7D1, 0xBAD8, 0xEADD, 0xD4F4, 0xEADE, 0xBCD6, 0xBBDF,
+ /* U+8D40 */ 0xEADF, 0xC1DE, 0xC2B8, 0xD4DF, 0xD7CA, 0xEAE0, 0xEAE1, 0xEAE4,
+ /* U+8D48 */ 0xEAE2, 0xEAE3, 0xC9DE, 0xB8B3, 0xB6C4, 0xEAE5, 0xCAEA, 0xC9CD,
+ /* U+8D50 */ 0xB4CD, 0xDA50, 0xDA51, 0xE2D9, 0xC5E2, 0xEAE6, 0xC0B5, 0xDA52,
+ /* U+8D58 */ 0xD7B8, 0xEAE7, 0xD7AC, 0xC8FC, 0xD8D3, 0xD8CD, 0xD4DE, 0xDA53,
+ /* U+8D60 */ 0xD4F9, 0xC9C4, 0xD3AE, 0xB8D3, 0xB3E0, 0xDA54, 0xC9E2, 0xF4F6,
+ /* U+8D68 */ 0xDA55, 0xDA56, 0xDA57, 0xBAD5, 0xDA58, 0xF4F7, 0xDA59, 0xDA5A,
+ /* U+8D70 */ 0xD7DF, 0xDA5B, 0xDA5C, 0xF4F1, 0xB8B0, 0xD5D4, 0xB8CF, 0xC6F0,
+ /* U+8D78 */ 0xDA5D, 0xDA5E, 0xDA5F, 0xDA60, 0xDA61, 0xDA62, 0xDA63, 0xDA64,
+ /* U+8D80 */ 0xDA65, 0xB3C3, 0xDA66, 0xDA67, 0xF4F2, 0xB3AC, 0xDA68, 0xDA69,
+ /* U+8D88 */ 0xDA6A, 0xDA6B, 0xD4BD, 0xC7F7, 0xDA6C, 0xDA6D, 0xDA6E, 0xDA6F,
+ /* U+8D90 */ 0xDA70, 0xF4F4, 0xDA71, 0xDA72, 0xF4F3, 0xDA73, 0xDA74, 0xDA75,
+ /* U+8D98 */ 0xDA76, 0xDA77, 0xDA78, 0xDA79, 0xDA7A, 0xDA7B, 0xDA7C, 0xCCCB,
+ /* U+8DA0 */ 0xDA7D, 0xDA7E, 0xDA80, 0xC8A4, 0xDA81, 0xDA82, 0xDA83, 0xDA84,
+ /* U+8DA8 */ 0xDA85, 0xDA86, 0xDA87, 0xDA88, 0xDA89, 0xDA8A, 0xDA8B, 0xDA8C,
+ /* U+8DB0 */ 0xDA8D, 0xF4F5, 0xDA8E, 0xD7E3, 0xC5BF, 0xF5C0, 0xDA8F, 0xDA90,
+ /* U+8DB8 */ 0xF5BB, 0xDA91, 0xF5C3, 0xDA92, 0xF5C2, 0xDA93, 0xD6BA, 0xF5C1,
+ /* U+8DC0 */ 0xDA94, 0xDA95, 0xDA96, 0xD4BE, 0xF5C4, 0xDA97, 0xF5CC, 0xDA98,
+ /* U+8DC8 */ 0xDA99, 0xDA9A, 0xDA9B, 0xB0CF, 0xB5F8, 0xDA9C, 0xF5C9, 0xF5CA,
+ /* U+8DD0 */ 0xDA9D, 0xC5DC, 0xDA9E, 0xDA9F, 0xDAA0, 0xDB40, 0xF5C5, 0xF5C6,
+ /* U+8DD8 */ 0xDB41, 0xDB42, 0xF5C7, 0xF5CB, 0xDB43, 0xBEE0, 0xF5C8, 0xB8FA,
+ /* U+8DE0 */ 0xDB44, 0xDB45, 0xDB46, 0xF5D0, 0xF5D3, 0xDB47, 0xDB48, 0xDB49,
+ /* U+8DE8 */ 0xBFE7, 0xDB4A, 0xB9F2, 0xF5BC, 0xF5CD, 0xDB4B, 0xDB4C, 0xC2B7,
+ /* U+8DF0 */ 0xDB4D, 0xDB4E, 0xDB4F, 0xCCF8, 0xDB50, 0xBCF9, 0xDB51, 0xF5CE,
+ /* U+8DF8 */ 0xF5CF, 0xF5D1, 0xB6E5, 0xF5D2, 0xDB52, 0xF5D5, 0xDB53, 0xDB54,
+ /* U+8E00 */ 0xDB55, 0xDB56, 0xDB57, 0xDB58, 0xDB59, 0xF5BD, 0xDB5A, 0xDB5B,
+ /* U+8E08 */ 0xDB5C, 0xF5D4, 0xD3BB, 0xDB5D, 0xB3EC, 0xDB5E, 0xDB5F, 0xCCA4,
+ /* U+8E10 */ 0xDB60, 0xDB61, 0xDB62, 0xDB63, 0xF5D6, 0xDB64, 0xDB65, 0xDB66,
+ /* U+8E18 */ 0xDB67, 0xDB68, 0xDB69, 0xDB6A, 0xDB6B, 0xF5D7, 0xBEE1, 0xF5D8,
+ /* U+8E20 */ 0xDB6C, 0xDB6D, 0xCCDF, 0xF5DB, 0xDB6E, 0xDB6F, 0xDB70, 0xDB71,
+ /* U+8E28 */ 0xDB72, 0xB2C8, 0xD7D9, 0xDB73, 0xF5D9, 0xDB74, 0xF5DA, 0xF5DC,
+ /* U+8E30 */ 0xDB75, 0xF5E2, 0xDB76, 0xDB77, 0xDB78, 0xF5E0, 0xDB79, 0xDB7A,
+ /* U+8E38 */ 0xDB7B, 0xF5DF, 0xF5DD, 0xDB7C, 0xDB7D, 0xF5E1, 0xDB7E, 0xDB80,
+ /* U+8E40 */ 0xF5DE, 0xF5E4, 0xF5E5, 0xDB81, 0xCCE3, 0xDB82, 0xDB83, 0xE5BF,
+ /* U+8E48 */ 0xB5B8, 0xF5E3, 0xF5E8, 0xCCA3, 0xDB84, 0xDB85, 0xDB86, 0xDB87,
+ /* U+8E50 */ 0xDB88, 0xF5E6, 0xF5E7, 0xDB89, 0xDB8A, 0xDB8B, 0xDB8C, 0xDB8D,
+ /* U+8E58 */ 0xDB8E, 0xF5BE, 0xDB8F, 0xDB90, 0xDB91, 0xDB92, 0xDB93, 0xDB94,
+ /* U+8E60 */ 0xDB95, 0xDB96, 0xDB97, 0xDB98, 0xDB99, 0xDB9A, 0xB1C4, 0xDB9B,
+ /* U+8E68 */ 0xDB9C, 0xF5BF, 0xDB9D, 0xDB9E, 0xB5C5, 0xB2E4, 0xDB9F, 0xF5EC,
+ /* U+8E70 */ 0xF5E9, 0xDBA0, 0xB6D7, 0xDC40, 0xF5ED, 0xDC41, 0xF5EA, 0xDC42,
+ /* U+8E78 */ 0xDC43, 0xDC44, 0xDC45, 0xDC46, 0xF5EB, 0xDC47, 0xDC48, 0xB4DA,
+ /* U+8E80 */ 0xDC49, 0xD4EA, 0xDC4A, 0xDC4B, 0xDC4C, 0xF5EE, 0xDC4D, 0xB3F9,
+ /* U+8E88 */ 0xDC4E, 0xDC4F, 0xDC50, 0xDC51, 0xDC52, 0xDC53, 0xDC54, 0xF5EF,
+ /* U+8E90 */ 0xF5F1, 0xDC55, 0xDC56, 0xDC57, 0xF5F0, 0xDC58, 0xDC59, 0xDC5A,
+ /* U+8E98 */ 0xDC5B, 0xDC5C, 0xDC5D, 0xDC5E, 0xF5F2, 0xDC5F, 0xF5F3, 0xDC60,
+ /* U+8EA0 */ 0xDC61, 0xDC62, 0xDC63, 0xDC64, 0xDC65, 0xDC66, 0xDC67, 0xDC68,
+ /* U+8EA8 */ 0xDC69, 0xDC6A, 0xDC6B, 0xC9ED, 0xB9AA, 0xDC6C, 0xDC6D, 0xC7FB,
+ /* U+8EB0 */ 0xDC6E, 0xDC6F, 0xB6E3, 0xDC70, 0xDC71, 0xDC72, 0xDC73, 0xDC74,
+ /* U+8EB8 */ 0xDC75, 0xDC76, 0xCCC9, 0xDC77, 0xDC78, 0xDC79, 0xDC7A, 0xDC7B,
+ /* U+8EC0 */ 0xDC7C, 0xDC7D, 0xDC7E, 0xDC80, 0xDC81, 0xDC82, 0xDC83, 0xDC84,
+ /* U+8EC8 */ 0xDC85, 0xDC86, 0xDC87, 0xDC88, 0xDC89, 0xDC8A, 0xEAA6, 0xDC8B,
+ /* U+8ED0 */ 0xDC8C, 0xDC8D, 0xDC8E, 0xDC8F, 0xDC90, 0xDC91, 0xDC92, 0xDC93,
+ /* U+8ED8 */ 0xDC94, 0xDC95, 0xDC96, 0xDC97, 0xDC98, 0xDC99, 0xDC9A, 0xDC9B,
+ /* U+8EE0 */ 0xDC9C, 0xDC9D, 0xDC9E, 0xDC9F, 0xDCA0, 0xDD40, 0xDD41, 0xDD42,
+ /* U+8EE8 */ 0xDD43, 0xDD44, 0xDD45, 0xDD46, 0xDD47, 0xDD48, 0xDD49, 0xDD4A,
+ /* U+8EF0 */ 0xDD4B, 0xDD4C, 0xDD4D, 0xDD4E, 0xDD4F, 0xDD50, 0xDD51, 0xDD52,
+ /* U+8EF8 */ 0xDD53, 0xDD54, 0xDD55, 0xDD56, 0xDD57, 0xDD58, 0xDD59, 0xDD5A,
+ /* U+8F00 */ 0xDD5B, 0xDD5C, 0xDD5D, 0xDD5E, 0xDD5F, 0xDD60, 0xDD61, 0xDD62,
+ /* U+8F08 */ 0xDD63, 0xDD64, 0xDD65, 0xDD66, 0xDD67, 0xDD68, 0xDD69, 0xDD6A,
+ /* U+8F10 */ 0xDD6B, 0xDD6C, 0xDD6D, 0xDD6E, 0xDD6F, 0xDD70, 0xDD71, 0xDD72,
+ /* U+8F18 */ 0xDD73, 0xDD74, 0xDD75, 0xDD76, 0xDD77, 0xDD78, 0xDD79, 0xDD7A,
+ /* U+8F20 */ 0xDD7B, 0xDD7C, 0xDD7D, 0xDD7E, 0xDD80, 0xDD81, 0xDD82, 0xDD83,
+ /* U+8F28 */ 0xDD84, 0xDD85, 0xDD86, 0xDD87, 0xDD88, 0xDD89, 0xDD8A, 0xDD8B,
+ /* U+8F30 */ 0xDD8C, 0xDD8D, 0xDD8E, 0xDD8F, 0xDD90, 0xDD91, 0xDD92, 0xDD93,
+ /* U+8F38 */ 0xDD94, 0xDD95, 0xDD96, 0xDD97, 0xDD98, 0xDD99, 0xDD9A, 0xDD9B,
+ /* U+8F40 */ 0xDD9C, 0xDD9D, 0xDD9E, 0xDD9F, 0xDDA0, 0xDE40, 0xDE41, 0xDE42,
+ /* U+8F48 */ 0xDE43, 0xDE44, 0xDE45, 0xDE46, 0xDE47, 0xDE48, 0xDE49, 0xDE4A,
+ /* U+8F50 */ 0xDE4B, 0xDE4C, 0xDE4D, 0xDE4E, 0xDE4F, 0xDE50, 0xDE51, 0xDE52,
+ /* U+8F58 */ 0xDE53, 0xDE54, 0xDE55, 0xDE56, 0xDE57, 0xDE58, 0xDE59, 0xDE5A,
+ /* U+8F60 */ 0xDE5B, 0xDE5C, 0xDE5D, 0xDE5E, 0xDE5F, 0xDE60, 0xB3B5, 0xD4FE,
+ /* U+8F68 */ 0xB9EC, 0xD0F9, 0xDE61, 0xE9ED, 0xD7AA, 0xE9EE, 0xC2D6, 0xC8ED,
+ /* U+8F70 */ 0xBAE4, 0xE9EF, 0xE9F0, 0xE9F1, 0xD6E1, 0xE9F2, 0xE9F3, 0xE9F5,
+ /* U+8F78 */ 0xE9F4, 0xE9F6, 0xE9F7, 0xC7E1, 0xE9F8, 0xD4D8, 0xE9F9, 0xBDCE,
+ /* U+8F80 */ 0xDE62, 0xE9FA, 0xE9FB, 0xBDCF, 0xE9FC, 0xB8A8, 0xC1BE, 0xE9FD,
+ /* U+8F88 */ 0xB1B2, 0xBBD4, 0xB9F5, 0xE9FE, 0xDE63, 0xEAA1, 0xEAA2, 0xEAA3,
+ /* U+8F90 */ 0xB7F8, 0xBCAD, 0xDE64, 0xCAE4, 0xE0CE, 0xD4AF, 0xCFBD, 0xD5B7,
+ /* U+8F98 */ 0xEAA4, 0xD5DE, 0xEAA5, 0xD0C1, 0xB9BC, 0xDE65, 0xB4C7, 0xB1D9,
+ /* U+8FA0 */ 0xDE66, 0xDE67, 0xDE68, 0xC0B1, 0xDE69, 0xDE6A, 0xDE6B, 0xDE6C,
+ /* U+8FA8 */ 0xB1E6, 0xB1E7, 0xDE6D, 0xB1E8, 0xDE6E, 0xDE6F, 0xDE70, 0xDE71,
+ /* U+8FB0 */ 0xB3BD, 0xC8E8, 0xDE72, 0xDE73, 0xDE74, 0xDE75, 0xE5C1, 0xDE76,
+ /* U+8FB8 */ 0xDE77, 0xB1DF, 0xDE78, 0xDE79, 0xDE7A, 0xC1C9, 0xB4EF, 0xDE7B,
+ /* U+8FC0 */ 0xDE7C, 0xC7A8, 0xD3D8, 0xDE7D, 0xC6F9, 0xD1B8, 0xDE7E, 0xB9FD,
+ /* U+8FC8 */ 0xC2F5, 0xDE80, 0xDE81, 0xDE82, 0xDE83, 0xDE84, 0xD3AD, 0xDE85,
+ /* U+8FD0 */ 0xD4CB, 0xBDFC, 0xDE86, 0xE5C2, 0xB7B5, 0xE5C3, 0xDE87, 0xDE88,
+ /* U+8FD8 */ 0xBBB9, 0xD5E2, 0xDE89, 0xBDF8, 0xD4B6, 0xCEA5, 0xC1AC, 0xB3D9,
+ /* U+8FE0 */ 0xDE8A, 0xDE8B, 0xCCF6, 0xDE8C, 0xE5C6, 0xE5C4, 0xE5C8, 0xDE8D,
+ /* U+8FE8 */ 0xE5CA, 0xE5C7, 0xB5CF, 0xC6C8, 0xDE8E, 0xB5FC, 0xE5C5, 0xDE8F,
+ /* U+8FF0 */ 0xCAF6, 0xDE90, 0xDE91, 0xE5C9, 0xDE92, 0xDE93, 0xDE94, 0xC3D4,
+ /* U+8FF8 */ 0xB1C5, 0xBCA3, 0xDE95, 0xDE96, 0xDE97, 0xD7B7, 0xDE98, 0xDE99,
+ /* U+9000 */ 0xCDCB, 0xCBCD, 0xCACA, 0xCCD3, 0xE5CC, 0xE5CB, 0xC4E6, 0xDE9A,
+ /* U+9008 */ 0xDE9B, 0xD1A1, 0xD1B7, 0xE5CD, 0xDE9C, 0xE5D0, 0xDE9D, 0xCDB8,
+ /* U+9010 */ 0xD6F0, 0xE5CF, 0xB5DD, 0xDE9E, 0xCDBE, 0xDE9F, 0xE5D1, 0xB6BA,
+ /* U+9018 */ 0xDEA0, 0xDF40, 0xCDA8, 0xB9E4, 0xDF41, 0xCAC5, 0xB3D1, 0xCBD9,
+ /* U+9020 */ 0xD4EC, 0xE5D2, 0xB7EA, 0xDF42, 0xDF43, 0xDF44, 0xE5CE, 0xDF45,
+ /* U+9028 */ 0xDF46, 0xDF47, 0xDF48, 0xDF49, 0xDF4A, 0xE5D5, 0xB4FE, 0xE5D6,
+ /* U+9030 */ 0xDF4B, 0xDF4C, 0xDF4D, 0xDF4E, 0xDF4F, 0xE5D3, 0xE5D4, 0xDF50,
+ /* U+9038 */ 0xD2DD, 0xDF51, 0xDF52, 0xC2DF, 0xB1C6, 0xDF53, 0xD3E2, 0xDF54,
+ /* U+9040 */ 0xDF55, 0xB6DD, 0xCBEC, 0xDF56, 0xE5D7, 0xDF57, 0xDF58, 0xD3F6,
+ /* U+9048 */ 0xDF59, 0xDF5A, 0xDF5B, 0xDF5C, 0xDF5D, 0xB1E9, 0xDF5E, 0xB6F4,
+ /* U+9050 */ 0xE5DA, 0xE5D8, 0xE5D9, 0xB5C0, 0xDF5F, 0xDF60, 0xDF61, 0xD2C5,
+ /* U+9058 */ 0xE5DC, 0xDF62, 0xDF63, 0xE5DE, 0xDF64, 0xDF65, 0xDF66, 0xDF67,
+ /* U+9060 */ 0xDF68, 0xDF69, 0xE5DD, 0xC7B2, 0xDF6A, 0xD2A3, 0xDF6B, 0xDF6C,
+ /* U+9068 */ 0xE5DB, 0xDF6D, 0xDF6E, 0xDF6F, 0xDF70, 0xD4E2, 0xD5DA, 0xDF71,
+ /* U+9070 */ 0xDF72, 0xDF73, 0xDF74, 0xDF75, 0xE5E0, 0xD7F1, 0xDF76, 0xDF77,
+ /* U+9078 */ 0xDF78, 0xDF79, 0xDF7A, 0xDF7B, 0xDF7C, 0xE5E1, 0xDF7D, 0xB1DC,
+ /* U+9080 */ 0xD1FB, 0xDF7E, 0xE5E2, 0xE5E4, 0xDF80, 0xDF81, 0xDF82, 0xDF83,
+ /* U+9088 */ 0xE5E3, 0xDF84, 0xDF85, 0xE5E5, 0xDF86, 0xDF87, 0xDF88, 0xDF89,
+ /* U+9090 */ 0xDF8A, 0xD2D8, 0xDF8B, 0xB5CB, 0xDF8C, 0xE7DF, 0xDF8D, 0xDAF5,
+ /* U+9098 */ 0xDF8E, 0xDAF8, 0xDF8F, 0xDAF6, 0xDF90, 0xDAF7, 0xDF91, 0xDF92,
+ /* U+90A0 */ 0xDF93, 0xDAFA, 0xD0CF, 0xC4C7, 0xDF94, 0xDF95, 0xB0EE, 0xDF96,
+ /* U+90A8 */ 0xDF97, 0xDF98, 0xD0B0, 0xDF99, 0xDAF9, 0xDF9A, 0xD3CA, 0xBAAA,
+ /* U+90B0 */ 0xDBA2, 0xC7F1, 0xDF9B, 0xDAFC, 0xDAFB, 0xC9DB, 0xDAFD, 0xDF9C,
+ /* U+90B8 */ 0xDBA1, 0xD7DE, 0xDAFE, 0xC1DA, 0xDF9D, 0xDF9E, 0xDBA5, 0xDF9F,
+ /* U+90C0 */ 0xDFA0, 0xD3F4, 0xE040, 0xE041, 0xDBA7, 0xDBA4, 0xE042, 0xDBA8,
+ /* U+90C8 */ 0xE043, 0xE044, 0xBDBC, 0xE045, 0xE046, 0xE047, 0xC0C9, 0xDBA3,
+ /* U+90D0 */ 0xDBA6, 0xD6A3, 0xE048, 0xDBA9, 0xE049, 0xE04A, 0xE04B, 0xDBAD,
+ /* U+90D8 */ 0xE04C, 0xE04D, 0xE04E, 0xDBAE, 0xDBAC, 0xBAC2, 0xE04F, 0xE050,
+ /* U+90E0 */ 0xE051, 0xBFA4, 0xDBAB, 0xE052, 0xE053, 0xE054, 0xDBAA, 0xD4C7,
+ /* U+90E8 */ 0xB2BF, 0xE055, 0xE056, 0xDBAF, 0xE057, 0xB9F9, 0xE058, 0xDBB0,
+ /* U+90F0 */ 0xE059, 0xE05A, 0xE05B, 0xE05C, 0xB3BB, 0xE05D, 0xE05E, 0xE05F,
+ /* U+90F8 */ 0xB5A6, 0xE060, 0xE061, 0xE062, 0xE063, 0xB6BC, 0xDBB1, 0xE064,
+ /* U+9100 */ 0xE065, 0xE066, 0xB6F5, 0xE067, 0xDBB2, 0xE068, 0xE069, 0xE06A,
+ /* U+9108 */ 0xE06B, 0xE06C, 0xE06D, 0xE06E, 0xE06F, 0xE070, 0xE071, 0xE072,
+ /* U+9110 */ 0xE073, 0xE074, 0xE075, 0xE076, 0xE077, 0xE078, 0xE079, 0xE07A,
+ /* U+9118 */ 0xE07B, 0xB1C9, 0xE07C, 0xE07D, 0xE07E, 0xE080, 0xDBB4, 0xE081,
+ /* U+9120 */ 0xE082, 0xE083, 0xDBB3, 0xDBB5, 0xE084, 0xE085, 0xE086, 0xE087,
+ /* U+9128 */ 0xE088, 0xE089, 0xE08A, 0xE08B, 0xE08C, 0xE08D, 0xE08E, 0xDBB7,
+ /* U+9130 */ 0xE08F, 0xDBB6, 0xE090, 0xE091, 0xE092, 0xE093, 0xE094, 0xE095,
+ /* U+9138 */ 0xE096, 0xDBB8, 0xE097, 0xE098, 0xE099, 0xE09A, 0xE09B, 0xE09C,
+ /* U+9140 */ 0xE09D, 0xE09E, 0xE09F, 0xDBB9, 0xE0A0, 0xE140, 0xDBBA, 0xE141,
+ /* U+9148 */ 0xE142, 0xD3CF, 0xF4FA, 0xC7F5, 0xD7C3, 0xC5E4, 0xF4FC, 0xF4FD,
+ /* U+9150 */ 0xF4FB, 0xE143, 0xBEC6, 0xE144, 0xE145, 0xE146, 0xE147, 0xD0EF,
+ /* U+9158 */ 0xE148, 0xE149, 0xB7D3, 0xE14A, 0xE14B, 0xD4CD, 0xCCAA, 0xE14C,
+ /* U+9160 */ 0xE14D, 0xF5A2, 0xF5A1, 0xBAA8, 0xF4FE, 0xCBD6, 0xE14E, 0xE14F,
+ /* U+9168 */ 0xE150, 0xF5A4, 0xC0D2, 0xE151, 0xB3EA, 0xE152, 0xCDAA, 0xF5A5,
+ /* U+9170 */ 0xF5A3, 0xBDB4, 0xF5A8, 0xE153, 0xF5A9, 0xBDCD, 0xC3B8, 0xBFE1,
+ /* U+9178 */ 0xCBE1, 0xF5AA, 0xE154, 0xE155, 0xE156, 0xF5A6, 0xF5A7, 0xC4F0,
+ /* U+9180 */ 0xE157, 0xE158, 0xE159, 0xE15A, 0xE15B, 0xF5AC, 0xE15C, 0xB4BC,
+ /* U+9188 */ 0xE15D, 0xD7ED, 0xE15E, 0xB4D7, 0xF5AB, 0xF5AE, 0xE15F, 0xE160,
+ /* U+9190 */ 0xF5AD, 0xF5AF, 0xD0D1, 0xE161, 0xE162, 0xE163, 0xE164, 0xE165,
+ /* U+9198 */ 0xE166, 0xE167, 0xC3D1, 0xC8A9, 0xE168, 0xE169, 0xE16A, 0xE16B,
+ /* U+91A0 */ 0xE16C, 0xE16D, 0xF5B0, 0xF5B1, 0xE16E, 0xE16F, 0xE170, 0xE171,
+ /* U+91A8 */ 0xE172, 0xE173, 0xF5B2, 0xE174, 0xE175, 0xF5B3, 0xF5B4, 0xF5B5,
+ /* U+91B0 */ 0xE176, 0xE177, 0xE178, 0xE179, 0xF5B7, 0xF5B6, 0xE17A, 0xE17B,
+ /* U+91B8 */ 0xE17C, 0xE17D, 0xF5B8, 0xE17E, 0xE180, 0xE181, 0xE182, 0xE183,
+ /* U+91C0 */ 0xE184, 0xE185, 0xE186, 0xE187, 0xE188, 0xE189, 0xE18A, 0xB2C9,
+ /* U+91C8 */ 0xE18B, 0xD3D4, 0xCACD, 0xE18C, 0xC0EF, 0xD6D8, 0xD2B0, 0xC1BF,
+ /* U+91D0 */ 0xE18D, 0xBDF0, 0xE18E, 0xE18F, 0xE190, 0xE191, 0xE192, 0xE193,
+ /* U+91D8 */ 0xE194, 0xE195, 0xE196, 0xE197, 0xB8AA, 0xE198, 0xE199, 0xE19A,
+ /* U+91E0 */ 0xE19B, 0xE19C, 0xE19D, 0xE19E, 0xE19F, 0xE1A0, 0xE240, 0xE241,
+ /* U+91E8 */ 0xE242, 0xE243, 0xE244, 0xE245, 0xE246, 0xE247, 0xE248, 0xE249,
+ /* U+91F0 */ 0xE24A, 0xE24B, 0xE24C, 0xE24D, 0xE24E, 0xE24F, 0xE250, 0xE251,
+ /* U+91F8 */ 0xE252, 0xE253, 0xE254, 0xE255, 0xE256, 0xE257, 0xE258, 0xE259,
+ /* U+9200 */ 0xE25A, 0xE25B, 0xE25C, 0xE25D, 0xE25E, 0xE25F, 0xE260, 0xE261,
+ /* U+9208 */ 0xE262, 0xE263, 0xE264, 0xE265, 0xE266, 0xE267, 0xE268, 0xE269,
+ /* U+9210 */ 0xE26A, 0xE26B, 0xE26C, 0xE26D, 0xE26E, 0xE26F, 0xE270, 0xE271,
+ /* U+9218 */ 0xE272, 0xE273, 0xE274, 0xE275, 0xE276, 0xE277, 0xE278, 0xE279,
+ /* U+9220 */ 0xE27A, 0xE27B, 0xE27C, 0xE27D, 0xE27E, 0xE280, 0xE281, 0xE282,
+ /* U+9228 */ 0xE283, 0xE284, 0xE285, 0xE286, 0xE287, 0xE288, 0xE289, 0xE28A,
+ /* U+9230 */ 0xE28B, 0xE28C, 0xE28D, 0xE28E, 0xE28F, 0xE290, 0xE291, 0xE292,
+ /* U+9238 */ 0xE293, 0xE294, 0xE295, 0xE296, 0xE297, 0xE298, 0xE299, 0xE29A,
+ /* U+9240 */ 0xE29B, 0xE29C, 0xE29D, 0xE29E, 0xE29F, 0xE2A0, 0xE340, 0xE341,
+ /* U+9248 */ 0xE342, 0xE343, 0xE344, 0xE345, 0xE346, 0xE347, 0xE348, 0xE349,
+ /* U+9250 */ 0xE34A, 0xE34B, 0xE34C, 0xE34D, 0xE34E, 0xE34F, 0xE350, 0xE351,
+ /* U+9258 */ 0xE352, 0xE353, 0xE354, 0xE355, 0xE356, 0xE357, 0xE358, 0xE359,
+ /* U+9260 */ 0xE35A, 0xE35B, 0xE35C, 0xE35D, 0xE35E, 0xE35F, 0xE360, 0xE361,
+ /* U+9268 */ 0xE362, 0xE363, 0xE364, 0xE365, 0xE366, 0xE367, 0xE368, 0xE369,
+ /* U+9270 */ 0xE36A, 0xE36B, 0xE36C, 0xE36D, 0xBCF8, 0xE36E, 0xE36F, 0xE370,
+ /* U+9278 */ 0xE371, 0xE372, 0xE373, 0xE374, 0xE375, 0xE376, 0xE377, 0xE378,
+ /* U+9280 */ 0xE379, 0xE37A, 0xE37B, 0xE37C, 0xE37D, 0xE37E, 0xE380, 0xE381,
+ /* U+9288 */ 0xE382, 0xE383, 0xE384, 0xE385, 0xE386, 0xE387, 0xF6C6, 0xE388,
+ /* U+9290 */ 0xE389, 0xE38A, 0xE38B, 0xE38C, 0xE38D, 0xE38E, 0xE38F, 0xE390,
+ /* U+9298 */ 0xE391, 0xE392, 0xE393, 0xE394, 0xE395, 0xE396, 0xE397, 0xE398,
+ /* U+92A0 */ 0xE399, 0xE39A, 0xE39B, 0xE39C, 0xE39D, 0xE39E, 0xE39F, 0xE3A0,
+ /* U+92A8 */ 0xE440, 0xE441, 0xE442, 0xE443, 0xE444, 0xE445, 0xF6C7, 0xE446,
+ /* U+92B0 */ 0xE447, 0xE448, 0xE449, 0xE44A, 0xE44B, 0xE44C, 0xE44D, 0xE44E,
+ /* U+92B8 */ 0xE44F, 0xE450, 0xE451, 0xE452, 0xE453, 0xE454, 0xE455, 0xE456,
+ /* U+92C0 */ 0xE457, 0xE458, 0xE459, 0xE45A, 0xE45B, 0xE45C, 0xE45D, 0xE45E,
+ /* U+92C8 */ 0xF6C8, 0xE45F, 0xE460, 0xE461, 0xE462, 0xE463, 0xE464, 0xE465,
+ /* U+92D0 */ 0xE466, 0xE467, 0xE468, 0xE469, 0xE46A, 0xE46B, 0xE46C, 0xE46D,
+ /* U+92D8 */ 0xE46E, 0xE46F, 0xE470, 0xE471, 0xE472, 0xE473, 0xE474, 0xE475,
+ /* U+92E0 */ 0xE476, 0xE477, 0xE478, 0xE479, 0xE47A, 0xE47B, 0xE47C, 0xE47D,
+ /* U+92E8 */ 0xE47E, 0xE480, 0xE481, 0xE482, 0xE483, 0xE484, 0xE485, 0xE486,
+ /* U+92F0 */ 0xE487, 0xE488, 0xE489, 0xE48A, 0xE48B, 0xE48C, 0xE48D, 0xE48E,
+ /* U+92F8 */ 0xE48F, 0xE490, 0xE491, 0xE492, 0xE493, 0xE494, 0xE495, 0xE496,
+ /* U+9300 */ 0xE497, 0xE498, 0xE499, 0xE49A, 0xE49B, 0xE49C, 0xE49D, 0xE49E,
+ /* U+9308 */ 0xE49F, 0xE4A0, 0xE540, 0xE541, 0xE542, 0xE543, 0xE544, 0xE545,
+ /* U+9310 */ 0xE546, 0xE547, 0xE548, 0xE549, 0xE54A, 0xE54B, 0xE54C, 0xE54D,
+ /* U+9318 */ 0xE54E, 0xE54F, 0xE550, 0xE551, 0xE552, 0xE553, 0xE554, 0xE555,
+ /* U+9320 */ 0xE556, 0xE557, 0xE558, 0xE559, 0xE55A, 0xE55B, 0xE55C, 0xE55D,
+ /* U+9328 */ 0xE55E, 0xE55F, 0xE560, 0xE561, 0xE562, 0xE563, 0xE564, 0xE565,
+ /* U+9330 */ 0xE566, 0xE567, 0xE568, 0xE569, 0xE56A, 0xE56B, 0xE56C, 0xE56D,
+ /* U+9338 */ 0xE56E, 0xE56F, 0xE570, 0xE571, 0xE572, 0xE573, 0xF6C9, 0xE574,
+ /* U+9340 */ 0xE575, 0xE576, 0xE577, 0xE578, 0xE579, 0xE57A, 0xE57B, 0xE57C,
+ /* U+9348 */ 0xE57D, 0xE57E, 0xE580, 0xE581, 0xE582, 0xE583, 0xE584, 0xE585,
+ /* U+9350 */ 0xE586, 0xE587, 0xE588, 0xE589, 0xE58A, 0xE58B, 0xE58C, 0xE58D,
+ /* U+9358 */ 0xE58E, 0xE58F, 0xE590, 0xE591, 0xE592, 0xE593, 0xE594, 0xE595,
+ /* U+9360 */ 0xE596, 0xE597, 0xE598, 0xE599, 0xE59A, 0xE59B, 0xE59C, 0xE59D,
+ /* U+9368 */ 0xE59E, 0xE59F, 0xF6CA, 0xE5A0, 0xE640, 0xE641, 0xE642, 0xE643,
+ /* U+9370 */ 0xE644, 0xE645, 0xE646, 0xE647, 0xE648, 0xE649, 0xE64A, 0xE64B,
+ /* U+9378 */ 0xE64C, 0xE64D, 0xE64E, 0xE64F, 0xE650, 0xE651, 0xE652, 0xE653,
+ /* U+9380 */ 0xE654, 0xE655, 0xE656, 0xE657, 0xE658, 0xE659, 0xE65A, 0xE65B,
+ /* U+9388 */ 0xE65C, 0xE65D, 0xE65E, 0xE65F, 0xE660, 0xE661, 0xE662, 0xF6CC,
+ /* U+9390 */ 0xE663, 0xE664, 0xE665, 0xE666, 0xE667, 0xE668, 0xE669, 0xE66A,
+ /* U+9398 */ 0xE66B, 0xE66C, 0xE66D, 0xE66E, 0xE66F, 0xE670, 0xE671, 0xE672,
+ /* U+93A0 */ 0xE673, 0xE674, 0xE675, 0xE676, 0xE677, 0xE678, 0xE679, 0xE67A,
+ /* U+93A8 */ 0xE67B, 0xE67C, 0xE67D, 0xE67E, 0xE680, 0xE681, 0xE682, 0xE683,
+ /* U+93B0 */ 0xE684, 0xE685, 0xE686, 0xE687, 0xE688, 0xE689, 0xE68A, 0xE68B,
+ /* U+93B8 */ 0xE68C, 0xE68D, 0xE68E, 0xE68F, 0xE690, 0xE691, 0xE692, 0xE693,
+ /* U+93C0 */ 0xE694, 0xE695, 0xE696, 0xE697, 0xE698, 0xE699, 0xE69A, 0xE69B,
+ /* U+93C8 */ 0xE69C, 0xE69D, 0xF6CB, 0xE69E, 0xE69F, 0xE6A0, 0xE740, 0xE741,
+ /* U+93D0 */ 0xE742, 0xE743, 0xE744, 0xE745, 0xE746, 0xE747, 0xF7E9, 0xE748,
+ /* U+93D8 */ 0xE749, 0xE74A, 0xE74B, 0xE74C, 0xE74D, 0xE74E, 0xE74F, 0xE750,
+ /* U+93E0 */ 0xE751, 0xE752, 0xE753, 0xE754, 0xE755, 0xE756, 0xE757, 0xE758,
+ /* U+93E8 */ 0xE759, 0xE75A, 0xE75B, 0xE75C, 0xE75D, 0xE75E, 0xE75F, 0xE760,
+ /* U+93F0 */ 0xE761, 0xE762, 0xE763, 0xE764, 0xE765, 0xE766, 0xE767, 0xE768,
+ /* U+93F8 */ 0xE769, 0xE76A, 0xE76B, 0xE76C, 0xE76D, 0xE76E, 0xE76F, 0xE770,
+ /* U+9400 */ 0xE771, 0xE772, 0xE773, 0xE774, 0xE775, 0xE776, 0xE777, 0xE778,
+ /* U+9408 */ 0xE779, 0xE77A, 0xE77B, 0xE77C, 0xE77D, 0xE77E, 0xE780, 0xE781,
+ /* U+9410 */ 0xE782, 0xE783, 0xE784, 0xE785, 0xE786, 0xE787, 0xE788, 0xE789,
+ /* U+9418 */ 0xE78A, 0xE78B, 0xE78C, 0xE78D, 0xE78E, 0xE78F, 0xE790, 0xE791,
+ /* U+9420 */ 0xE792, 0xE793, 0xE794, 0xE795, 0xE796, 0xE797, 0xE798, 0xE799,
+ /* U+9428 */ 0xE79A, 0xE79B, 0xE79C, 0xE79D, 0xE79E, 0xE79F, 0xE7A0, 0xE840,
+ /* U+9430 */ 0xE841, 0xE842, 0xE843, 0xE844, 0xE845, 0xE846, 0xE847, 0xE848,
+ /* U+9438 */ 0xE849, 0xE84A, 0xE84B, 0xE84C, 0xE84D, 0xE84E, 0xF6CD, 0xE84F,
+ /* U+9440 */ 0xE850, 0xE851, 0xE852, 0xE853, 0xE854, 0xE855, 0xE856, 0xE857,
+ /* U+9448 */ 0xE858, 0xE859, 0xE85A, 0xE85B, 0xE85C, 0xE85D, 0xE85E, 0xE85F,
+ /* U+9450 */ 0xE860, 0xE861, 0xE862, 0xE863, 0xE864, 0xE865, 0xE866, 0xE867,
+ /* U+9458 */ 0xE868, 0xE869, 0xE86A, 0xE86B, 0xE86C, 0xE86D, 0xE86E, 0xE86F,
+ /* U+9460 */ 0xE870, 0xE871, 0xE872, 0xE873, 0xE874, 0xE875, 0xE876, 0xE877,
+ /* U+9468 */ 0xE878, 0xE879, 0xE87A, 0xF6CE, 0xE87B, 0xE87C, 0xE87D, 0xE87E,
+ /* U+9470 */ 0xE880, 0xE881, 0xE882, 0xE883, 0xE884, 0xE885, 0xE886, 0xE887,
+ /* U+9478 */ 0xE888, 0xE889, 0xE88A, 0xE88B, 0xE88C, 0xE88D, 0xE88E, 0xE88F,
+ /* U+9480 */ 0xE890, 0xE891, 0xE892, 0xE893, 0xE894, 0xEEC4, 0xEEC5, 0xEEC6,
+ /* U+9488 */ 0xD5EB, 0xB6A4, 0xEEC8, 0xEEC7, 0xEEC9, 0xEECA, 0xC7A5, 0xEECB,
+ /* U+9490 */ 0xEECC, 0xE895, 0xB7B0, 0xB5F6, 0xEECD, 0xEECF, 0xE896, 0xEECE,
+ /* U+9498 */ 0xE897, 0xB8C6, 0xEED0, 0xEED1, 0xEED2, 0xB6DB, 0xB3AE, 0xD6D3,
+ /* U+94A0 */ 0xC4C6, 0xB1B5, 0xB8D6, 0xEED3, 0xEED4, 0xD4BF, 0xC7D5, 0xBEFB,
+ /* U+94A8 */ 0xCED9, 0xB9B3, 0xEED6, 0xEED5, 0xEED8, 0xEED7, 0xC5A5, 0xEED9,
+ /* U+94B0 */ 0xEEDA, 0xC7AE, 0xEEDB, 0xC7AF, 0xEEDC, 0xB2A7, 0xEEDD, 0xEEDE,
+ /* U+94B8 */ 0xEEDF, 0xEEE0, 0xEEE1, 0xD7EA, 0xEEE2, 0xEEE3, 0xBCD8, 0xEEE4,
+ /* U+94C0 */ 0xD3CB, 0xCCFA, 0xB2AC, 0xC1E5, 0xEEE5, 0xC7A6, 0xC3AD, 0xE898,
+ /* U+94C8 */ 0xEEE6, 0xEEE7, 0xEEE8, 0xEEE9, 0xEEEA, 0xEEEB, 0xEEEC, 0xE899,
+ /* U+94D0 */ 0xEEED, 0xEEEE, 0xEEEF, 0xE89A, 0xE89B, 0xEEF0, 0xEEF1, 0xEEF2,
+ /* U+94D8 */ 0xEEF4, 0xEEF3, 0xE89C, 0xEEF5, 0xCDAD, 0xC2C1, 0xEEF6, 0xEEF7,
+ /* U+94E0 */ 0xEEF8, 0xD5A1, 0xEEF9, 0xCFB3, 0xEEFA, 0xEEFB, 0xE89D, 0xEEFC,
+ /* U+94E8 */ 0xEEFD, 0xEFA1, 0xEEFE, 0xEFA2, 0xB8F5, 0xC3FA, 0xEFA3, 0xEFA4,
+ /* U+94F0 */ 0xBDC2, 0xD2BF, 0xB2F9, 0xEFA5, 0xEFA6, 0xEFA7, 0xD2F8, 0xEFA8,
+ /* U+94F8 */ 0xD6FD, 0xEFA9, 0xC6CC, 0xE89E, 0xEFAA, 0xEFAB, 0xC1B4, 0xEFAC,
+ /* U+9500 */ 0xCFFA, 0xCBF8, 0xEFAE, 0xEFAD, 0xB3FA, 0xB9F8, 0xEFAF, 0xEFB0,
+ /* U+9508 */ 0xD0E2, 0xEFB1, 0xEFB2, 0xB7E6, 0xD0BF, 0xEFB3, 0xEFB4, 0xEFB5,
+ /* U+9510 */ 0xC8F1, 0xCCE0, 0xEFB6, 0xEFB7, 0xEFB8, 0xEFB9, 0xEFBA, 0xD5E0,
+ /* U+9518 */ 0xEFBB, 0xB4ED, 0xC3AA, 0xEFBC, 0xE89F, 0xEFBD, 0xEFBE, 0xEFBF,
+ /* U+9520 */ 0xE8A0, 0xCEFD, 0xEFC0, 0xC2E0, 0xB4B8, 0xD7B6, 0xBDF5, 0xE940,
+ /* U+9528 */ 0xCFC7, 0xEFC3, 0xEFC1, 0xEFC2, 0xEFC4, 0xB6A7, 0xBCFC, 0xBEE2,
+ /* U+9530 */ 0xC3CC, 0xEFC5, 0xEFC6, 0xE941, 0xEFC7, 0xEFCF, 0xEFC8, 0xEFC9,
+ /* U+9538 */ 0xEFCA, 0xC7C2, 0xEFF1, 0xB6CD, 0xEFCB, 0xE942, 0xEFCC, 0xEFCD,
+ /* U+9540 */ 0xB6C6, 0xC3BE, 0xEFCE, 0xE943, 0xEFD0, 0xEFD1, 0xEFD2, 0xD5F2,
+ /* U+9548 */ 0xE944, 0xEFD3, 0xC4F7, 0xE945, 0xEFD4, 0xC4F8, 0xEFD5, 0xEFD6,
+ /* U+9550 */ 0xB8E4, 0xB0F7, 0xEFD7, 0xEFD8, 0xEFD9, 0xE946, 0xEFDA, 0xEFDB,
+ /* U+9558 */ 0xEFDC, 0xEFDD, 0xE947, 0xEFDE, 0xBEB5, 0xEFE1, 0xEFDF, 0xEFE0,
+ /* U+9560 */ 0xE948, 0xEFE2, 0xEFE3, 0xC1CD, 0xEFE4, 0xEFE5, 0xEFE6, 0xEFE7,
+ /* U+9568 */ 0xEFE8, 0xEFE9, 0xEFEA, 0xEFEB, 0xEFEC, 0xC0D8, 0xE949, 0xEFED,
+ /* U+9570 */ 0xC1AD, 0xEFEE, 0xEFEF, 0xEFF0, 0xE94A, 0xE94B, 0xCFE2, 0xE94C,
+ /* U+9578 */ 0xE94D, 0xE94E, 0xE94F, 0xE950, 0xE951, 0xE952, 0xE953, 0xB3A4,
+ /* U+9580 */ 0xE954, 0xE955, 0xE956, 0xE957, 0xE958, 0xE959, 0xE95A, 0xE95B,
+ /* U+9588 */ 0xE95C, 0xE95D, 0xE95E, 0xE95F, 0xE960, 0xE961, 0xE962, 0xE963,
+ /* U+9590 */ 0xE964, 0xE965, 0xE966, 0xE967, 0xE968, 0xE969, 0xE96A, 0xE96B,
+ /* U+9598 */ 0xE96C, 0xE96D, 0xE96E, 0xE96F, 0xE970, 0xE971, 0xE972, 0xE973,
+ /* U+95A0 */ 0xE974, 0xE975, 0xE976, 0xE977, 0xE978, 0xE979, 0xE97A, 0xE97B,
+ /* U+95A8 */ 0xE97C, 0xE97D, 0xE97E, 0xE980, 0xE981, 0xE982, 0xE983, 0xE984,
+ /* U+95B0 */ 0xE985, 0xE986, 0xE987, 0xE988, 0xE989, 0xE98A, 0xE98B, 0xE98C,
+ /* U+95B8 */ 0xE98D, 0xE98E, 0xE98F, 0xE990, 0xE991, 0xE992, 0xE993, 0xE994,
+ /* U+95C0 */ 0xE995, 0xE996, 0xE997, 0xE998, 0xE999, 0xE99A, 0xE99B, 0xE99C,
+ /* U+95C8 */ 0xE99D, 0xE99E, 0xE99F, 0xE9A0, 0xEA40, 0xEA41, 0xEA42, 0xEA43,
+ /* U+95D0 */ 0xEA44, 0xEA45, 0xEA46, 0xEA47, 0xEA48, 0xEA49, 0xEA4A, 0xEA4B,
+ /* U+95D8 */ 0xEA4C, 0xEA4D, 0xEA4E, 0xEA4F, 0xEA50, 0xEA51, 0xEA52, 0xEA53,
+ /* U+95E0 */ 0xEA54, 0xEA55, 0xEA56, 0xEA57, 0xEA58, 0xEA59, 0xEA5A, 0xEA5B,
+ /* U+95E8 */ 0xC3C5, 0xE3C5, 0xC9C1, 0xE3C6, 0xEA5C, 0xB1D5, 0xCECA, 0xB4B3,
+ /* U+95F0 */ 0xC8F2, 0xE3C7, 0xCFD0, 0xE3C8, 0xBCE4, 0xE3C9, 0xE3CA, 0xC3C6,
+ /* U+95F8 */ 0xD5A2, 0xC4D6, 0xB9EB, 0xCEC5, 0xE3CB, 0xC3F6, 0xE3CC, 0xEA5D,
+ /* U+9600 */ 0xB7A7, 0xB8F3, 0xBAD2, 0xE3CD, 0xE3CE, 0xD4C4, 0xE3CF, 0xEA5E,
+ /* U+9608 */ 0xE3D0, 0xD1CB, 0xE3D1, 0xE3D2, 0xE3D3, 0xE3D4, 0xD1D6, 0xE3D5,
+ /* U+9610 */ 0xB2FB, 0xC0BB, 0xE3D6, 0xEA5F, 0xC0AB, 0xE3D7, 0xE3D8, 0xE3D9,
+ /* U+9618 */ 0xEA60, 0xE3DA, 0xE3DB, 0xEA61, 0xB8B7, 0xDAE2, 0xEA62, 0xB6D3,
+ /* U+9620 */ 0xEA63, 0xDAE4, 0xDAE3, 0xEA64, 0xEA65, 0xEA66, 0xEA67, 0xEA68,
+ /* U+9628 */ 0xEA69, 0xEA6A, 0xDAE6, 0xEA6B, 0xEA6C, 0xEA6D, 0xC8EE, 0xEA6E,
+ /* U+9630 */ 0xEA6F, 0xDAE5, 0xB7C0, 0xD1F4, 0xD2F5, 0xD5F3, 0xBDD7, 0xEA70,
+ /* U+9638 */ 0xEA71, 0xEA72, 0xEA73, 0xD7E8, 0xDAE8, 0xDAE7, 0xEA74, 0xB0A2,
+ /* U+9640 */ 0xCDD3, 0xEA75, 0xDAE9, 0xEA76, 0xB8BD, 0xBCCA, 0xC2BD, 0xC2A4,
+ /* U+9648 */ 0xB3C2, 0xDAEA, 0xEA77, 0xC2AA, 0xC4B0, 0xBDB5, 0xEA78, 0xEA79,
+ /* U+9650 */ 0xCFDE, 0xEA7A, 0xEA7B, 0xEA7C, 0xDAEB, 0xC9C2, 0xEA7D, 0xEA7E,
+ /* U+9658 */ 0xEA80, 0xEA81, 0xEA82, 0xB1DD, 0xEA83, 0xEA84, 0xEA85, 0xDAEC,
+ /* U+9660 */ 0xEA86, 0xB6B8, 0xD4BA, 0xEA87, 0xB3FD, 0xEA88, 0xEA89, 0xDAED,
+ /* U+9668 */ 0xD4C9, 0xCFD5, 0xC5E3, 0xEA8A, 0xDAEE, 0xEA8B, 0xEA8C, 0xEA8D,
+ /* U+9670 */ 0xEA8E, 0xEA8F, 0xDAEF, 0xEA90, 0xDAF0, 0xC1EA, 0xCCD5, 0xCFDD,
+ /* U+9678 */ 0xEA91, 0xEA92, 0xEA93, 0xEA94, 0xEA95, 0xEA96, 0xEA97, 0xEA98,
+ /* U+9680 */ 0xEA99, 0xEA9A, 0xEA9B, 0xEA9C, 0xEA9D, 0xD3E7, 0xC2A1, 0xEA9E,
+ /* U+9688 */ 0xDAF1, 0xEA9F, 0xEAA0, 0xCBE5, 0xEB40, 0xDAF2, 0xEB41, 0xCBE6,
+ /* U+9690 */ 0xD2FE, 0xEB42, 0xEB43, 0xEB44, 0xB8F4, 0xEB45, 0xEB46, 0xDAF3,
+ /* U+9698 */ 0xB0AF, 0xCFB6, 0xEB47, 0xEB48, 0xD5CF, 0xEB49, 0xEB4A, 0xEB4B,
+ /* U+96A0 */ 0xEB4C, 0xEB4D, 0xEB4E, 0xEB4F, 0xEB50, 0xEB51, 0xEB52, 0xCBED,
+ /* U+96A8 */ 0xEB53, 0xEB54, 0xEB55, 0xEB56, 0xEB57, 0xEB58, 0xEB59, 0xEB5A,
+ /* U+96B0 */ 0xDAF4, 0xEB5B, 0xEB5C, 0xE3C4, 0xEB5D, 0xEB5E, 0xC1A5, 0xEB5F,
+ /* U+96B8 */ 0xEB60, 0xF6BF, 0xEB61, 0xEB62, 0xF6C0, 0xF6C1, 0xC4D1, 0xEB63,
+ /* U+96C0 */ 0xC8B8, 0xD1E3, 0xEB64, 0xEB65, 0xD0DB, 0xD1C5, 0xBCAF, 0xB9CD,
+ /* U+96C8 */ 0xEB66, 0xEFF4, 0xEB67, 0xEB68, 0xB4C6, 0xD3BA, 0xF6C2, 0xB3FB,
+ /* U+96D0 */ 0xEB69, 0xEB6A, 0xF6C3, 0xEB6B, 0xEB6C, 0xB5F1, 0xEB6D, 0xEB6E,
+ /* U+96D8 */ 0xEB6F, 0xEB70, 0xEB71, 0xEB72, 0xEB73, 0xEB74, 0xEB75, 0xEB76,
+ /* U+96E0 */ 0xF6C5, 0xEB77, 0xEB78, 0xEB79, 0xEB7A, 0xEB7B, 0xEB7C, 0xEB7D,
+ /* U+96E8 */ 0xD3EA, 0xF6A7, 0xD1A9, 0xEB7E, 0xEB80, 0xEB81, 0xEB82, 0xF6A9,
+ /* U+96F0 */ 0xEB83, 0xEB84, 0xEB85, 0xF6A8, 0xEB86, 0xEB87, 0xC1E3, 0xC0D7,
+ /* U+96F8 */ 0xEB88, 0xB1A2, 0xEB89, 0xEB8A, 0xEB8B, 0xEB8C, 0xCEED, 0xEB8D,
+ /* U+9700 */ 0xD0E8, 0xF6AB, 0xEB8E, 0xEB8F, 0xCFF6, 0xEB90, 0xF6AA, 0xD5F0,
+ /* U+9708 */ 0xF6AC, 0xC3B9, 0xEB91, 0xEB92, 0xEB93, 0xBBF4, 0xF6AE, 0xF6AD,
+ /* U+9710 */ 0xEB94, 0xEB95, 0xEB96, 0xC4DE, 0xEB97, 0xEB98, 0xC1D8, 0xEB99,
+ /* U+9718 */ 0xEB9A, 0xEB9B, 0xEB9C, 0xEB9D, 0xCBAA, 0xEB9E, 0xCFBC, 0xEB9F,
+ /* U+9720 */ 0xEBA0, 0xEC40, 0xEC41, 0xEC42, 0xEC43, 0xEC44, 0xEC45, 0xEC46,
+ /* U+9728 */ 0xEC47, 0xEC48, 0xF6AF, 0xEC49, 0xEC4A, 0xF6B0, 0xEC4B, 0xEC4C,
+ /* U+9730 */ 0xF6B1, 0xEC4D, 0xC2B6, 0xEC4E, 0xEC4F, 0xEC50, 0xEC51, 0xEC52,
+ /* U+9738 */ 0xB0D4, 0xC5F9, 0xEC53, 0xEC54, 0xEC55, 0xEC56, 0xF6B2, 0xEC57,
+ /* U+9740 */ 0xEC58, 0xEC59, 0xEC5A, 0xEC5B, 0xEC5C, 0xEC5D, 0xEC5E, 0xEC5F,
+ /* U+9748 */ 0xEC60, 0xEC61, 0xEC62, 0xEC63, 0xEC64, 0xEC65, 0xEC66, 0xEC67,
+ /* U+9750 */ 0xEC68, 0xEC69, 0xC7E0, 0xF6A6, 0xEC6A, 0xEC6B, 0xBEB8, 0xEC6C,
+ /* U+9758 */ 0xEC6D, 0xBEB2, 0xEC6E, 0xB5E5, 0xEC6F, 0xEC70, 0xB7C7, 0xEC71,
+ /* U+9760 */ 0xBFBF, 0xC3D2, 0xC3E6, 0xEC72, 0xEC73, 0xD8CC, 0xEC74, 0xEC75,
+ /* U+9768 */ 0xEC76, 0xB8EF, 0xEC77, 0xEC78, 0xEC79, 0xEC7A, 0xEC7B, 0xEC7C,
+ /* U+9770 */ 0xEC7D, 0xEC7E, 0xEC80, 0xBDF9, 0xD1A5, 0xEC81, 0xB0D0, 0xEC82,
+ /* U+9778 */ 0xEC83, 0xEC84, 0xEC85, 0xEC86, 0xF7B0, 0xEC87, 0xEC88, 0xEC89,
+ /* U+9780 */ 0xEC8A, 0xEC8B, 0xEC8C, 0xEC8D, 0xEC8E, 0xF7B1, 0xEC8F, 0xEC90,
+ /* U+9788 */ 0xEC91, 0xEC92, 0xEC93, 0xD0AC, 0xEC94, 0xB0B0, 0xEC95, 0xEC96,
+ /* U+9790 */ 0xEC97, 0xF7B2, 0xF7B3, 0xEC98, 0xF7B4, 0xEC99, 0xEC9A, 0xEC9B,
+ /* U+9798 */ 0xC7CA, 0xEC9C, 0xEC9D, 0xEC9E, 0xEC9F, 0xECA0, 0xED40, 0xED41,
+ /* U+97A0 */ 0xBECF, 0xED42, 0xED43, 0xF7B7, 0xED44, 0xED45, 0xED46, 0xED47,
+ /* U+97A8 */ 0xED48, 0xED49, 0xED4A, 0xF7B6, 0xED4B, 0xB1DE, 0xED4C, 0xF7B5,
+ /* U+97B0 */ 0xED4D, 0xED4E, 0xF7B8, 0xED4F, 0xF7B9, 0xED50, 0xED51, 0xED52,
+ /* U+97B8 */ 0xED53, 0xED54, 0xED55, 0xED56, 0xED57, 0xED58, 0xED59, 0xED5A,
+ /* U+97C0 */ 0xED5B, 0xED5C, 0xED5D, 0xED5E, 0xED5F, 0xED60, 0xED61, 0xED62,
+ /* U+97C8 */ 0xED63, 0xED64, 0xED65, 0xED66, 0xED67, 0xED68, 0xED69, 0xED6A,
+ /* U+97D0 */ 0xED6B, 0xED6C, 0xED6D, 0xED6E, 0xED6F, 0xED70, 0xED71, 0xED72,
+ /* U+97D8 */ 0xED73, 0xED74, 0xED75, 0xED76, 0xED77, 0xED78, 0xED79, 0xED7A,
+ /* U+97E0 */ 0xED7B, 0xED7C, 0xED7D, 0xED7E, 0xED80, 0xED81, 0xCEA4, 0xC8CD,
+ /* U+97E8 */ 0xED82, 0xBAAB, 0xE8B8, 0xE8B9, 0xE8BA, 0xBEC2, 0xED83, 0xED84,
+ /* U+97F0 */ 0xED85, 0xED86, 0xED87, 0xD2F4, 0xED88, 0xD4CF, 0xC9D8, 0xED89,
+ /* U+97F8 */ 0xED8A, 0xED8B, 0xED8C, 0xED8D, 0xED8E, 0xED8F, 0xED90, 0xED91,
+ /* U+9800 */ 0xED92, 0xED93, 0xED94, 0xED95, 0xED96, 0xED97, 0xED98, 0xED99,
+ /* U+9808 */ 0xED9A, 0xED9B, 0xED9C, 0xED9D, 0xED9E, 0xED9F, 0xEDA0, 0xEE40,
+ /* U+9810 */ 0xEE41, 0xEE42, 0xEE43, 0xEE44, 0xEE45, 0xEE46, 0xEE47, 0xEE48,
+ /* U+9818 */ 0xEE49, 0xEE4A, 0xEE4B, 0xEE4C, 0xEE4D, 0xEE4E, 0xEE4F, 0xEE50,
+ /* U+9820 */ 0xEE51, 0xEE52, 0xEE53, 0xEE54, 0xEE55, 0xEE56, 0xEE57, 0xEE58,
+ /* U+9828 */ 0xEE59, 0xEE5A, 0xEE5B, 0xEE5C, 0xEE5D, 0xEE5E, 0xEE5F, 0xEE60,
+ /* U+9830 */ 0xEE61, 0xEE62, 0xEE63, 0xEE64, 0xEE65, 0xEE66, 0xEE67, 0xEE68,
+ /* U+9838 */ 0xEE69, 0xEE6A, 0xEE6B, 0xEE6C, 0xEE6D, 0xEE6E, 0xEE6F, 0xEE70,
+ /* U+9840 */ 0xEE71, 0xEE72, 0xEE73, 0xEE74, 0xEE75, 0xEE76, 0xEE77, 0xEE78,
+ /* U+9848 */ 0xEE79, 0xEE7A, 0xEE7B, 0xEE7C, 0xEE7D, 0xEE7E, 0xEE80, 0xEE81,
+ /* U+9850 */ 0xEE82, 0xEE83, 0xEE84, 0xEE85, 0xEE86, 0xEE87, 0xEE88, 0xEE89,
+ /* U+9858 */ 0xEE8A, 0xEE8B, 0xEE8C, 0xEE8D, 0xEE8E, 0xEE8F, 0xEE90, 0xEE91,
+ /* U+9860 */ 0xEE92, 0xEE93, 0xEE94, 0xEE95, 0xEE96, 0xEE97, 0xEE98, 0xEE99,
+ /* U+9868 */ 0xEE9A, 0xEE9B, 0xEE9C, 0xEE9D, 0xEE9E, 0xEE9F, 0xEEA0, 0xEF40,
+ /* U+9870 */ 0xEF41, 0xEF42, 0xEF43, 0xEF44, 0xEF45, 0xD2B3, 0xB6A5, 0xC7EA,
+ /* U+9878 */ 0xF1FC, 0xCFEE, 0xCBB3, 0xD0EB, 0xE7EF, 0xCDE7, 0xB9CB, 0xB6D9,
+ /* U+9880 */ 0xF1FD, 0xB0E4, 0xCBCC, 0xF1FE, 0xD4A4, 0xC2AD, 0xC1EC, 0xC6C4,
+ /* U+9888 */ 0xBEB1, 0xF2A1, 0xBCD5, 0xEF46, 0xF2A2, 0xF2A3, 0xEF47, 0xF2A4,
+ /* U+9890 */ 0xD2C3, 0xC6B5, 0xEF48, 0xCDC7, 0xF2A5, 0xEF49, 0xD3B1, 0xBFC5,
+ /* U+9898 */ 0xCCE2, 0xEF4A, 0xF2A6, 0xF2A7, 0xD1D5, 0xB6EE, 0xF2A8, 0xF2A9,
+ /* U+98A0 */ 0xB5DF, 0xF2AA, 0xF2AB, 0xEF4B, 0xB2FC, 0xF2AC, 0xF2AD, 0xC8A7,
+ /* U+98A8 */ 0xEF4C, 0xEF4D, 0xEF4E, 0xEF4F, 0xEF50, 0xEF51, 0xEF52, 0xEF53,
+ /* U+98B0 */ 0xEF54, 0xEF55, 0xEF56, 0xEF57, 0xEF58, 0xEF59, 0xEF5A, 0xEF5B,
+ /* U+98B8 */ 0xEF5C, 0xEF5D, 0xEF5E, 0xEF5F, 0xEF60, 0xEF61, 0xEF62, 0xEF63,
+ /* U+98C0 */ 0xEF64, 0xEF65, 0xEF66, 0xEF67, 0xEF68, 0xEF69, 0xEF6A, 0xEF6B,
+ /* U+98C8 */ 0xEF6C, 0xEF6D, 0xEF6E, 0xEF6F, 0xEF70, 0xEF71, 0xB7E7, 0xEF72,
+ /* U+98D0 */ 0xEF73, 0xECA9, 0xECAA, 0xECAB, 0xEF74, 0xECAC, 0xEF75, 0xEF76,
+ /* U+98D8 */ 0xC6AE, 0xECAD, 0xECAE, 0xEF77, 0xEF78, 0xEF79, 0xB7C9, 0xCAB3,
+ /* U+98E0 */ 0xEF7A, 0xEF7B, 0xEF7C, 0xEF7D, 0xEF7E, 0xEF80, 0xEF81, 0xE2B8,
+ /* U+98E8 */ 0xF7CF, 0xEF82, 0xEF83, 0xEF84, 0xEF85, 0xEF86, 0xEF87, 0xEF88,
+ /* U+98F0 */ 0xEF89, 0xEF8A, 0xEF8B, 0xEF8C, 0xEF8D, 0xEF8E, 0xEF8F, 0xEF90,
+ /* U+98F8 */ 0xEF91, 0xEF92, 0xEF93, 0xEF94, 0xEF95, 0xEF96, 0xEF97, 0xEF98,
+ /* U+9900 */ 0xEF99, 0xEF9A, 0xEF9B, 0xEF9C, 0xEF9D, 0xEF9E, 0xEF9F, 0xEFA0,
+ /* U+9908 */ 0xF040, 0xF041, 0xF042, 0xF043, 0xF044, 0xF7D0, 0xF045, 0xF046,
+ /* U+9910 */ 0xB2CD, 0xF047, 0xF048, 0xF049, 0xF04A, 0xF04B, 0xF04C, 0xF04D,
+ /* U+9918 */ 0xF04E, 0xF04F, 0xF050, 0xF051, 0xF052, 0xF053, 0xF054, 0xF055,
+ /* U+9920 */ 0xF056, 0xF057, 0xF058, 0xF059, 0xF05A, 0xF05B, 0xF05C, 0xF05D,
+ /* U+9928 */ 0xF05E, 0xF05F, 0xF060, 0xF061, 0xF062, 0xF063, 0xF7D1, 0xF064,
+ /* U+9930 */ 0xF065, 0xF066, 0xF067, 0xF068, 0xF069, 0xF06A, 0xF06B, 0xF06C,
+ /* U+9938 */ 0xF06D, 0xF06E, 0xF06F, 0xF070, 0xF071, 0xF072, 0xF073, 0xF074,
+ /* U+9940 */ 0xF075, 0xF076, 0xF077, 0xF078, 0xF079, 0xF07A, 0xF07B, 0xF07C,
+ /* U+9948 */ 0xF07D, 0xF07E, 0xF080, 0xF081, 0xF082, 0xF083, 0xF084, 0xF085,
+ /* U+9950 */ 0xF086, 0xF087, 0xF088, 0xF089, 0xF7D3, 0xF7D2, 0xF08A, 0xF08B,
+ /* U+9958 */ 0xF08C, 0xF08D, 0xF08E, 0xF08F, 0xF090, 0xF091, 0xF092, 0xF093,
+ /* U+9960 */ 0xF094, 0xF095, 0xF096, 0xE2BB, 0xF097, 0xBCA2, 0xF098, 0xE2BC,
+ /* U+9968 */ 0xE2BD, 0xE2BE, 0xE2BF, 0xE2C0, 0xE2C1, 0xB7B9, 0xD2FB, 0xBDA4,
+ /* U+9970 */ 0xCACE, 0xB1A5, 0xCBC7, 0xF099, 0xE2C2, 0xB6FC, 0xC8C4, 0xE2C3,
+ /* U+9978 */ 0xF09A, 0xF09B, 0xBDC8, 0xF09C, 0xB1FD, 0xE2C4, 0xF09D, 0xB6F6,
+ /* U+9980 */ 0xE2C5, 0xC4D9, 0xF09E, 0xF09F, 0xE2C6, 0xCFDA, 0xB9DD, 0xE2C7,
+ /* U+9988 */ 0xC0A1, 0xF0A0, 0xE2C8, 0xB2F6, 0xF140, 0xE2C9, 0xF141, 0xC1F3,
+ /* U+9990 */ 0xE2CA, 0xE2CB, 0xC2F8, 0xE2CC, 0xE2CD, 0xE2CE, 0xCAD7, 0xD8B8,
+ /* U+9998 */ 0xD9E5, 0xCFE3, 0xF142, 0xF143, 0xF144, 0xF145, 0xF146, 0xF147,
+ /* U+99A0 */ 0xF148, 0xF149, 0xF14A, 0xF14B, 0xF14C, 0xF0A5, 0xF14D, 0xF14E,
+ /* U+99A8 */ 0xDCB0, 0xF14F, 0xF150, 0xF151, 0xF152, 0xF153, 0xF154, 0xF155,
+ /* U+99B0 */ 0xF156, 0xF157, 0xF158, 0xF159, 0xF15A, 0xF15B, 0xF15C, 0xF15D,
+ /* U+99B8 */ 0xF15E, 0xF15F, 0xF160, 0xF161, 0xF162, 0xF163, 0xF164, 0xF165,
+ /* U+99C0 */ 0xF166, 0xF167, 0xF168, 0xF169, 0xF16A, 0xF16B, 0xF16C, 0xF16D,
+ /* U+99C8 */ 0xF16E, 0xF16F, 0xF170, 0xF171, 0xF172, 0xF173, 0xF174, 0xF175,
+ /* U+99D0 */ 0xF176, 0xF177, 0xF178, 0xF179, 0xF17A, 0xF17B, 0xF17C, 0xF17D,
+ /* U+99D8 */ 0xF17E, 0xF180, 0xF181, 0xF182, 0xF183, 0xF184, 0xF185, 0xF186,
+ /* U+99E0 */ 0xF187, 0xF188, 0xF189, 0xF18A, 0xF18B, 0xF18C, 0xF18D, 0xF18E,
+ /* U+99E8 */ 0xF18F, 0xF190, 0xF191, 0xF192, 0xF193, 0xF194, 0xF195, 0xF196,
+ /* U+99F0 */ 0xF197, 0xF198, 0xF199, 0xF19A, 0xF19B, 0xF19C, 0xF19D, 0xF19E,
+ /* U+99F8 */ 0xF19F, 0xF1A0, 0xF240, 0xF241, 0xF242, 0xF243, 0xF244, 0xF245,
+ /* U+9A00 */ 0xF246, 0xF247, 0xF248, 0xF249, 0xF24A, 0xF24B, 0xF24C, 0xF24D,
+ /* U+9A08 */ 0xF24E, 0xF24F, 0xF250, 0xF251, 0xF252, 0xF253, 0xF254, 0xF255,
+ /* U+9A10 */ 0xF256, 0xF257, 0xF258, 0xF259, 0xF25A, 0xF25B, 0xF25C, 0xF25D,
+ /* U+9A18 */ 0xF25E, 0xF25F, 0xF260, 0xF261, 0xF262, 0xF263, 0xF264, 0xF265,
+ /* U+9A20 */ 0xF266, 0xF267, 0xF268, 0xF269, 0xF26A, 0xF26B, 0xF26C, 0xF26D,
+ /* U+9A28 */ 0xF26E, 0xF26F, 0xF270, 0xF271, 0xF272, 0xF273, 0xF274, 0xF275,
+ /* U+9A30 */ 0xF276, 0xF277, 0xF278, 0xF279, 0xF27A, 0xF27B, 0xF27C, 0xF27D,
+ /* U+9A38 */ 0xF27E, 0xF280, 0xF281, 0xF282, 0xF283, 0xF284, 0xF285, 0xF286,
+ /* U+9A40 */ 0xF287, 0xF288, 0xF289, 0xF28A, 0xF28B, 0xF28C, 0xF28D, 0xF28E,
+ /* U+9A48 */ 0xF28F, 0xF290, 0xF291, 0xF292, 0xF293, 0xF294, 0xF295, 0xF296,
+ /* U+9A50 */ 0xF297, 0xF298, 0xF299, 0xF29A, 0xF29B, 0xF29C, 0xF29D, 0xF29E,
+ /* U+9A58 */ 0xF29F, 0xF2A0, 0xF340, 0xF341, 0xF342, 0xF343, 0xF344, 0xF345,
+ /* U+9A60 */ 0xF346, 0xF347, 0xF348, 0xF349, 0xF34A, 0xF34B, 0xF34C, 0xF34D,
+ /* U+9A68 */ 0xF34E, 0xF34F, 0xF350, 0xF351, 0xC2ED, 0xD4A6, 0xCDD4, 0xD1B1,
+ /* U+9A70 */ 0xB3DB, 0xC7FD, 0xF352, 0xB2B5, 0xC2BF, 0xE6E0, 0xCABB, 0xE6E1,
+ /* U+9A78 */ 0xE6E2, 0xBED4, 0xE6E3, 0xD7A4, 0xCDD5, 0xE6E5, 0xBCDD, 0xE6E4,
+ /* U+9A80 */ 0xE6E6, 0xE6E7, 0xC2EE, 0xF353, 0xBDBE, 0xE6E8, 0xC2E6, 0xBAA7,
+ /* U+9A88 */ 0xE6E9, 0xF354, 0xE6EA, 0xB3D2, 0xD1E9, 0xF355, 0xF356, 0xBFA5,
+ /* U+9A90 */ 0xE6EB, 0xC6EF, 0xE6EC, 0xE6ED, 0xF357, 0xF358, 0xE6EE, 0xC6AD,
+ /* U+9A98 */ 0xE6EF, 0xF359, 0xC9A7, 0xE6F0, 0xE6F1, 0xE6F2, 0xE5B9, 0xE6F3,
+ /* U+9AA0 */ 0xE6F4, 0xC2E2, 0xE6F5, 0xE6F6, 0xD6E8, 0xE6F7, 0xF35A, 0xE6F8,
+ /* U+9AA8 */ 0xB9C7, 0xF35B, 0xF35C, 0xF35D, 0xF35E, 0xF35F, 0xF360, 0xF361,
+ /* U+9AB0 */ 0xF7BB, 0xF7BA, 0xF362, 0xF363, 0xF364, 0xF365, 0xF7BE, 0xF7BC,
+ /* U+9AB8 */ 0xBAA1, 0xF366, 0xF7BF, 0xF367, 0xF7C0, 0xF368, 0xF369, 0xF36A,
+ /* U+9AC0 */ 0xF7C2, 0xF7C1, 0xF7C4, 0xF36B, 0xF36C, 0xF7C3, 0xF36D, 0xF36E,
+ /* U+9AC8 */ 0xF36F, 0xF370, 0xF371, 0xF7C5, 0xF7C6, 0xF372, 0xF373, 0xF374,
+ /* U+9AD0 */ 0xF375, 0xF7C7, 0xF376, 0xCBE8, 0xF377, 0xF378, 0xF379, 0xF37A,
+ /* U+9AD8 */ 0xB8DF, 0xF37B, 0xF37C, 0xF37D, 0xF37E, 0xF380, 0xF381, 0xF7D4,
+ /* U+9AE0 */ 0xF382, 0xF7D5, 0xF383, 0xF384, 0xF385, 0xF386, 0xF7D6, 0xF387,
+ /* U+9AE8 */ 0xF388, 0xF389, 0xF38A, 0xF7D8, 0xF38B, 0xF7DA, 0xF38C, 0xF7D7,
+ /* U+9AF0 */ 0xF38D, 0xF38E, 0xF38F, 0xF390, 0xF391, 0xF392, 0xF393, 0xF394,
+ /* U+9AF8 */ 0xF395, 0xF7DB, 0xF396, 0xF7D9, 0xF397, 0xF398, 0xF399, 0xF39A,
+ /* U+9B00 */ 0xF39B, 0xF39C, 0xF39D, 0xD7D7, 0xF39E, 0xF39F, 0xF3A0, 0xF440,
+ /* U+9B08 */ 0xF7DC, 0xF441, 0xF442, 0xF443, 0xF444, 0xF445, 0xF446, 0xF7DD,
+ /* U+9B10 */ 0xF447, 0xF448, 0xF449, 0xF7DE, 0xF44A, 0xF44B, 0xF44C, 0xF44D,
+ /* U+9B18 */ 0xF44E, 0xF44F, 0xF450, 0xF451, 0xF452, 0xF453, 0xF454, 0xF7DF,
+ /* U+9B20 */ 0xF455, 0xF456, 0xF457, 0xF7E0, 0xF458, 0xF459, 0xF45A, 0xF45B,
+ /* U+9B28 */ 0xF45C, 0xF45D, 0xF45E, 0xF45F, 0xF460, 0xF461, 0xF462, 0xDBCB,
+ /* U+9B30 */ 0xF463, 0xF464, 0xD8AA, 0xF465, 0xF466, 0xF467, 0xF468, 0xF469,
+ /* U+9B38 */ 0xF46A, 0xF46B, 0xF46C, 0xE5F7, 0xB9ED, 0xF46D, 0xF46E, 0xF46F,
+ /* U+9B40 */ 0xF470, 0xBFFD, 0xBBEA, 0xF7C9, 0xC6C7, 0xF7C8, 0xF471, 0xF7CA,
+ /* U+9B48 */ 0xF7CC, 0xF7CB, 0xF472, 0xF473, 0xF474, 0xF7CD, 0xF475, 0xCEBA,
+ /* U+9B50 */ 0xF476, 0xF7CE, 0xF477, 0xF478, 0xC4A7, 0xF479, 0xF47A, 0xF47B,
+ /* U+9B58 */ 0xF47C, 0xF47D, 0xF47E, 0xF480, 0xF481, 0xF482, 0xF483, 0xF484,
+ /* U+9B60 */ 0xF485, 0xF486, 0xF487, 0xF488, 0xF489, 0xF48A, 0xF48B, 0xF48C,
+ /* U+9B68 */ 0xF48D, 0xF48E, 0xF48F, 0xF490, 0xF491, 0xF492, 0xF493, 0xF494,
+ /* U+9B70 */ 0xF495, 0xF496, 0xF497, 0xF498, 0xF499, 0xF49A, 0xF49B, 0xF49C,
+ /* U+9B78 */ 0xF49D, 0xF49E, 0xF49F, 0xF4A0, 0xF540, 0xF541, 0xF542, 0xF543,
+ /* U+9B80 */ 0xF544, 0xF545, 0xF546, 0xF547, 0xF548, 0xF549, 0xF54A, 0xF54B,
+ /* U+9B88 */ 0xF54C, 0xF54D, 0xF54E, 0xF54F, 0xF550, 0xF551, 0xF552, 0xF553,
+ /* U+9B90 */ 0xF554, 0xF555, 0xF556, 0xF557, 0xF558, 0xF559, 0xF55A, 0xF55B,
+ /* U+9B98 */ 0xF55C, 0xF55D, 0xF55E, 0xF55F, 0xF560, 0xF561, 0xF562, 0xF563,
+ /* U+9BA0 */ 0xF564, 0xF565, 0xF566, 0xF567, 0xF568, 0xF569, 0xF56A, 0xF56B,
+ /* U+9BA8 */ 0xF56C, 0xF56D, 0xF56E, 0xF56F, 0xF570, 0xF571, 0xF572, 0xF573,
+ /* U+9BB0 */ 0xF574, 0xF575, 0xF576, 0xF577, 0xF578, 0xF579, 0xF57A, 0xF57B,
+ /* U+9BB8 */ 0xF57C, 0xF57D, 0xF57E, 0xF580, 0xF581, 0xF582, 0xF583, 0xF584,
+ /* U+9BC0 */ 0xF585, 0xF586, 0xF587, 0xF588, 0xF589, 0xF58A, 0xF58B, 0xF58C,
+ /* U+9BC8 */ 0xF58D, 0xF58E, 0xF58F, 0xF590, 0xF591, 0xF592, 0xF593, 0xF594,
+ /* U+9BD0 */ 0xF595, 0xF596, 0xF597, 0xF598, 0xF599, 0xF59A, 0xF59B, 0xF59C,
+ /* U+9BD8 */ 0xF59D, 0xF59E, 0xF59F, 0xF5A0, 0xF640, 0xF641, 0xF642, 0xF643,
+ /* U+9BE0 */ 0xF644, 0xF645, 0xF646, 0xF647, 0xF648, 0xF649, 0xF64A, 0xF64B,
+ /* U+9BE8 */ 0xF64C, 0xF64D, 0xF64E, 0xF64F, 0xF650, 0xF651, 0xF652, 0xF653,
+ /* U+9BF0 */ 0xF654, 0xF655, 0xF656, 0xF657, 0xF658, 0xF659, 0xF65A, 0xF65B,
+ /* U+9BF8 */ 0xF65C, 0xF65D, 0xF65E, 0xF65F, 0xF660, 0xF661, 0xF662, 0xF663,
+ /* U+9C00 */ 0xF664, 0xF665, 0xF666, 0xF667, 0xF668, 0xF669, 0xF66A, 0xF66B,
+ /* U+9C08 */ 0xF66C, 0xF66D, 0xF66E, 0xF66F, 0xF670, 0xF671, 0xF672, 0xF673,
+ /* U+9C10 */ 0xF674, 0xF675, 0xF676, 0xF677, 0xF678, 0xF679, 0xF67A, 0xF67B,
+ /* U+9C18 */ 0xF67C, 0xF67D, 0xF67E, 0xF680, 0xF681, 0xF682, 0xF683, 0xF684,
+ /* U+9C20 */ 0xF685, 0xF686, 0xF687, 0xF688, 0xF689, 0xF68A, 0xF68B, 0xF68C,
+ /* U+9C28 */ 0xF68D, 0xF68E, 0xF68F, 0xF690, 0xF691, 0xF692, 0xF693, 0xF694,
+ /* U+9C30 */ 0xF695, 0xF696, 0xF697, 0xF698, 0xF699, 0xF69A, 0xF69B, 0xF69C,
+ /* U+9C38 */ 0xF69D, 0xF69E, 0xF69F, 0xF6A0, 0xF740, 0xF741, 0xF742, 0xF743,
+ /* U+9C40 */ 0xF744, 0xF745, 0xF746, 0xF747, 0xF748, 0xF749, 0xF74A, 0xF74B,
+ /* U+9C48 */ 0xF74C, 0xF74D, 0xF74E, 0xF74F, 0xF750, 0xF751, 0xF752, 0xF753,
+ /* U+9C50 */ 0xF754, 0xF755, 0xF756, 0xF757, 0xF758, 0xF759, 0xF75A, 0xF75B,
+ /* U+9C58 */ 0xF75C, 0xF75D, 0xF75E, 0xF75F, 0xF760, 0xF761, 0xF762, 0xF763,
+ /* U+9C60 */ 0xF764, 0xF765, 0xF766, 0xF767, 0xF768, 0xF769, 0xF76A, 0xF76B,
+ /* U+9C68 */ 0xF76C, 0xF76D, 0xF76E, 0xF76F, 0xF770, 0xF771, 0xF772, 0xF773,
+ /* U+9C70 */ 0xF774, 0xF775, 0xF776, 0xF777, 0xF778, 0xF779, 0xF77A, 0xF77B,
+ /* U+9C78 */ 0xF77C, 0xF77D, 0xF77E, 0xF780, 0xD3E3, 0xF781, 0xF782, 0xF6CF,
+ /* U+9C80 */ 0xF783, 0xC2B3, 0xF6D0, 0xF784, 0xF785, 0xF6D1, 0xF6D2, 0xF6D3,
+ /* U+9C88 */ 0xF6D4, 0xF786, 0xF787, 0xF6D6, 0xF788, 0xB1AB, 0xF6D7, 0xF789,
+ /* U+9C90 */ 0xF6D8, 0xF6D9, 0xF6DA, 0xF78A, 0xF6DB, 0xF6DC, 0xF78B, 0xF78C,
+ /* U+9C98 */ 0xF78D, 0xF78E, 0xF6DD, 0xF6DE, 0xCFCA, 0xF78F, 0xF6DF, 0xF6E0,
+ /* U+9CA0 */ 0xF6E1, 0xF6E2, 0xF6E3, 0xF6E4, 0xC0F0, 0xF6E5, 0xF6E6, 0xF6E7,
+ /* U+9CA8 */ 0xF6E8, 0xF6E9, 0xF790, 0xF6EA, 0xF791, 0xF6EB, 0xF6EC, 0xF792,
+ /* U+9CB0 */ 0xF6ED, 0xF6EE, 0xF6EF, 0xF6F0, 0xF6F1, 0xF6F2, 0xF6F3, 0xF6F4,
+ /* U+9CB8 */ 0xBEA8, 0xF793, 0xF6F5, 0xF6F6, 0xF6F7, 0xF6F8, 0xF794, 0xF795,
+ /* U+9CC0 */ 0xF796, 0xF797, 0xF798, 0xC8FA, 0xF6F9, 0xF6FA, 0xF6FB, 0xF6FC,
+ /* U+9CC8 */ 0xF799, 0xF79A, 0xF6FD, 0xF6FE, 0xF7A1, 0xF7A2, 0xF7A3, 0xF7A4,
+ /* U+9CD0 */ 0xF7A5, 0xF79B, 0xF79C, 0xF7A6, 0xF7A7, 0xF7A8, 0xB1EE, 0xF7A9,
+ /* U+9CD8 */ 0xF7AA, 0xF7AB, 0xF79D, 0xF79E, 0xF7AC, 0xF7AD, 0xC1DB, 0xF7AE,
+ /* U+9CE0 */ 0xF79F, 0xF7A0, 0xF7AF, 0xF840, 0xF841, 0xF842, 0xF843, 0xF844,
+ /* U+9CE8 */ 0xF845, 0xF846, 0xF847, 0xF848, 0xF849, 0xF84A, 0xF84B, 0xF84C,
+ /* U+9CF0 */ 0xF84D, 0xF84E, 0xF84F, 0xF850, 0xF851, 0xF852, 0xF853, 0xF854,
+ /* U+9CF8 */ 0xF855, 0xF856, 0xF857, 0xF858, 0xF859, 0xF85A, 0xF85B, 0xF85C,
+ /* U+9D00 */ 0xF85D, 0xF85E, 0xF85F, 0xF860, 0xF861, 0xF862, 0xF863, 0xF864,
+ /* U+9D08 */ 0xF865, 0xF866, 0xF867, 0xF868, 0xF869, 0xF86A, 0xF86B, 0xF86C,
+ /* U+9D10 */ 0xF86D, 0xF86E, 0xF86F, 0xF870, 0xF871, 0xF872, 0xF873, 0xF874,
+ /* U+9D18 */ 0xF875, 0xF876, 0xF877, 0xF878, 0xF879, 0xF87A, 0xF87B, 0xF87C,
+ /* U+9D20 */ 0xF87D, 0xF87E, 0xF880, 0xF881, 0xF882, 0xF883, 0xF884, 0xF885,
+ /* U+9D28 */ 0xF886, 0xF887, 0xF888, 0xF889, 0xF88A, 0xF88B, 0xF88C, 0xF88D,
+ /* U+9D30 */ 0xF88E, 0xF88F, 0xF890, 0xF891, 0xF892, 0xF893, 0xF894, 0xF895,
+ /* U+9D38 */ 0xF896, 0xF897, 0xF898, 0xF899, 0xF89A, 0xF89B, 0xF89C, 0xF89D,
+ /* U+9D40 */ 0xF89E, 0xF89F, 0xF8A0, 0xF940, 0xF941, 0xF942, 0xF943, 0xF944,
+ /* U+9D48 */ 0xF945, 0xF946, 0xF947, 0xF948, 0xF949, 0xF94A, 0xF94B, 0xF94C,
+ /* U+9D50 */ 0xF94D, 0xF94E, 0xF94F, 0xF950, 0xF951, 0xF952, 0xF953, 0xF954,
+ /* U+9D58 */ 0xF955, 0xF956, 0xF957, 0xF958, 0xF959, 0xF95A, 0xF95B, 0xF95C,
+ /* U+9D60 */ 0xF95D, 0xF95E, 0xF95F, 0xF960, 0xF961, 0xF962, 0xF963, 0xF964,
+ /* U+9D68 */ 0xF965, 0xF966, 0xF967, 0xF968, 0xF969, 0xF96A, 0xF96B, 0xF96C,
+ /* U+9D70 */ 0xF96D, 0xF96E, 0xF96F, 0xF970, 0xF971, 0xF972, 0xF973, 0xF974,
+ /* U+9D78 */ 0xF975, 0xF976, 0xF977, 0xF978, 0xF979, 0xF97A, 0xF97B, 0xF97C,
+ /* U+9D80 */ 0xF97D, 0xF97E, 0xF980, 0xF981, 0xF982, 0xF983, 0xF984, 0xF985,
+ /* U+9D88 */ 0xF986, 0xF987, 0xF988, 0xF989, 0xF98A, 0xF98B, 0xF98C, 0xF98D,
+ /* U+9D90 */ 0xF98E, 0xF98F, 0xF990, 0xF991, 0xF992, 0xF993, 0xF994, 0xF995,
+ /* U+9D98 */ 0xF996, 0xF997, 0xF998, 0xF999, 0xF99A, 0xF99B, 0xF99C, 0xF99D,
+ /* U+9DA0 */ 0xF99E, 0xF99F, 0xF9A0, 0xFA40, 0xFA41, 0xFA42, 0xFA43, 0xFA44,
+ /* U+9DA8 */ 0xFA45, 0xFA46, 0xFA47, 0xFA48, 0xFA49, 0xFA4A, 0xFA4B, 0xFA4C,
+ /* U+9DB0 */ 0xFA4D, 0xFA4E, 0xFA4F, 0xFA50, 0xFA51, 0xFA52, 0xFA53, 0xFA54,
+ /* U+9DB8 */ 0xFA55, 0xFA56, 0xFA57, 0xFA58, 0xFA59, 0xFA5A, 0xFA5B, 0xFA5C,
+ /* U+9DC0 */ 0xFA5D, 0xFA5E, 0xFA5F, 0xFA60, 0xFA61, 0xFA62, 0xFA63, 0xFA64,
+ /* U+9DC8 */ 0xFA65, 0xFA66, 0xFA67, 0xFA68, 0xFA69, 0xFA6A, 0xFA6B, 0xFA6C,
+ /* U+9DD0 */ 0xFA6D, 0xFA6E, 0xFA6F, 0xFA70, 0xFA71, 0xFA72, 0xFA73, 0xFA74,
+ /* U+9DD8 */ 0xFA75, 0xFA76, 0xFA77, 0xFA78, 0xFA79, 0xFA7A, 0xFA7B, 0xFA7C,
+ /* U+9DE0 */ 0xFA7D, 0xFA7E, 0xFA80, 0xFA81, 0xFA82, 0xFA83, 0xFA84, 0xFA85,
+ /* U+9DE8 */ 0xFA86, 0xFA87, 0xFA88, 0xFA89, 0xFA8A, 0xFA8B, 0xFA8C, 0xFA8D,
+ /* U+9DF0 */ 0xFA8E, 0xFA8F, 0xFA90, 0xFA91, 0xFA92, 0xFA93, 0xFA94, 0xFA95,
+ /* U+9DF8 */ 0xFA96, 0xFA97, 0xFA98, 0xFA99, 0xFA9A, 0xFA9B, 0xFA9C, 0xFA9D,
+ /* U+9E00 */ 0xFA9E, 0xFA9F, 0xFAA0, 0xFB40, 0xFB41, 0xFB42, 0xFB43, 0xFB44,
+ /* U+9E08 */ 0xFB45, 0xFB46, 0xFB47, 0xFB48, 0xFB49, 0xFB4A, 0xFB4B, 0xFB4C,
+ /* U+9E10 */ 0xFB4D, 0xFB4E, 0xFB4F, 0xFB50, 0xFB51, 0xFB52, 0xFB53, 0xFB54,
+ /* U+9E18 */ 0xFB55, 0xFB56, 0xFB57, 0xFB58, 0xFB59, 0xFB5A, 0xFB5B, 0xC4F1,
+ /* U+9E20 */ 0xF0AF, 0xBCA6, 0xF0B0, 0xC3F9, 0xFB5C, 0xC5B8, 0xD1BB, 0xFB5D,
+ /* U+9E28 */ 0xF0B1, 0xF0B2, 0xF0B3, 0xF0B4, 0xF0B5, 0xD1BC, 0xFB5E, 0xD1EC,
+ /* U+9E30 */ 0xFB5F, 0xF0B7, 0xF0B6, 0xD4A7, 0xFB60, 0xCDD2, 0xF0B8, 0xF0BA,
+ /* U+9E38 */ 0xF0B9, 0xF0BB, 0xF0BC, 0xFB61, 0xFB62, 0xB8EB, 0xF0BD, 0xBAE8,
+ /* U+9E40 */ 0xFB63, 0xF0BE, 0xF0BF, 0xBEE9, 0xF0C0, 0xB6EC, 0xF0C1, 0xF0C2,
+ /* U+9E48 */ 0xF0C3, 0xF0C4, 0xC8B5, 0xF0C5, 0xF0C6, 0xFB64, 0xF0C7, 0xC5F4,
+ /* U+9E50 */ 0xFB65, 0xF0C8, 0xFB66, 0xFB67, 0xFB68, 0xF0C9, 0xFB69, 0xF0CA,
+ /* U+9E58 */ 0xF7BD, 0xFB6A, 0xF0CB, 0xF0CC, 0xF0CD, 0xFB6B, 0xF0CE, 0xFB6C,
+ /* U+9E60 */ 0xFB6D, 0xFB6E, 0xFB6F, 0xF0CF, 0xBAD7, 0xFB70, 0xF0D0, 0xF0D1,
+ /* U+9E68 */ 0xF0D2, 0xF0D3, 0xF0D4, 0xF0D5, 0xF0D6, 0xF0D8, 0xFB71, 0xFB72,
+ /* U+9E70 */ 0xD3A5, 0xF0D7, 0xFB73, 0xF0D9, 0xFB74, 0xFB75, 0xFB76, 0xFB77,
+ /* U+9E78 */ 0xFB78, 0xFB79, 0xFB7A, 0xFB7B, 0xFB7C, 0xFB7D, 0xF5BA, 0xC2B9,
+ /* U+9E80 */ 0xFB7E, 0xFB80, 0xF7E4, 0xFB81, 0xFB82, 0xFB83, 0xFB84, 0xF7E5,
+ /* U+9E88 */ 0xF7E6, 0xFB85, 0xFB86, 0xF7E7, 0xFB87, 0xFB88, 0xFB89, 0xFB8A,
+ /* U+9E90 */ 0xFB8B, 0xFB8C, 0xF7E8, 0xC2B4, 0xFB8D, 0xFB8E, 0xFB8F, 0xFB90,
+ /* U+9E98 */ 0xFB91, 0xFB92, 0xFB93, 0xFB94, 0xFB95, 0xF7EA, 0xFB96, 0xF7EB,
+ /* U+9EA0 */ 0xFB97, 0xFB98, 0xFB99, 0xFB9A, 0xFB9B, 0xFB9C, 0xC2F3, 0xFB9D,
+ /* U+9EA8 */ 0xFB9E, 0xFB9F, 0xFBA0, 0xFC40, 0xFC41, 0xFC42, 0xFC43, 0xFC44,
+ /* U+9EB0 */ 0xFC45, 0xFC46, 0xFC47, 0xFC48, 0xF4F0, 0xFC49, 0xFC4A, 0xFC4B,
+ /* U+9EB8 */ 0xF4EF, 0xFC4C, 0xFC4D, 0xC2E9, 0xFC4E, 0xF7E1, 0xF7E2, 0xFC4F,
+ /* U+9EC0 */ 0xFC50, 0xFC51, 0xFC52, 0xFC53, 0xBBC6, 0xFC54, 0xFC55, 0xFC56,
+ /* U+9EC8 */ 0xFC57, 0xD9E4, 0xFC58, 0xFC59, 0xFC5A, 0xCAF2, 0xC0E8, 0xF0A4,
+ /* U+9ED0 */ 0xFC5B, 0xBADA, 0xFC5C, 0xFC5D, 0xC7AD, 0xFC5E, 0xFC5F, 0xFC60,
+ /* U+9ED8 */ 0xC4AC, 0xFC61, 0xFC62, 0xF7EC, 0xF7ED, 0xF7EE, 0xFC63, 0xF7F0,
+ /* U+9EE0 */ 0xF7EF, 0xFC64, 0xF7F1, 0xFC65, 0xFC66, 0xF7F4, 0xFC67, 0xF7F3,
+ /* U+9EE8 */ 0xFC68, 0xF7F2, 0xF7F5, 0xFC69, 0xFC6A, 0xFC6B, 0xFC6C, 0xF7F6,
+ /* U+9EF0 */ 0xFC6D, 0xFC6E, 0xFC6F, 0xFC70, 0xFC71, 0xFC72, 0xFC73, 0xFC74,
+ /* U+9EF8 */ 0xFC75, 0xEDE9, 0xFC76, 0xEDEA, 0xEDEB, 0xFC77, 0xF6BC, 0xFC78,
+ /* U+9F00 */ 0xFC79, 0xFC7A, 0xFC7B, 0xFC7C, 0xFC7D, 0xFC7E, 0xFC80, 0xFC81,
+ /* U+9F08 */ 0xFC82, 0xFC83, 0xFC84, 0xF6BD, 0xFC85, 0xF6BE, 0xB6A6, 0xFC86,
+ /* U+9F10 */ 0xD8BE, 0xFC87, 0xFC88, 0xB9C4, 0xFC89, 0xFC8A, 0xFC8B, 0xD8BB,
+ /* U+9F18 */ 0xFC8C, 0xDCB1, 0xFC8D, 0xFC8E, 0xFC8F, 0xFC90, 0xFC91, 0xFC92,
+ /* U+9F20 */ 0xCAF3, 0xFC93, 0xF7F7, 0xFC94, 0xFC95, 0xFC96, 0xFC97, 0xFC98,
+ /* U+9F28 */ 0xFC99, 0xFC9A, 0xFC9B, 0xFC9C, 0xF7F8, 0xFC9D, 0xFC9E, 0xF7F9,
+ /* U+9F30 */ 0xFC9F, 0xFCA0, 0xFD40, 0xFD41, 0xFD42, 0xFD43, 0xFD44, 0xF7FB,
+ /* U+9F38 */ 0xFD45, 0xF7FA, 0xFD46, 0xB1C7, 0xFD47, 0xF7FC, 0xF7FD, 0xFD48,
+ /* U+9F40 */ 0xFD49, 0xFD4A, 0xFD4B, 0xFD4C, 0xF7FE, 0xFD4D, 0xFD4E, 0xFD4F,
+ /* U+9F48 */ 0xFD50, 0xFD51, 0xFD52, 0xFD53, 0xFD54, 0xFD55, 0xFD56, 0xFD57,
+ /* U+9F50 */ 0xC6EB, 0xECB4, 0xFD58, 0xFD59, 0xFD5A, 0xFD5B, 0xFD5C, 0xFD5D,
+ /* U+9F58 */ 0xFD5E, 0xFD5F, 0xFD60, 0xFD61, 0xFD62, 0xFD63, 0xFD64, 0xFD65,
+ /* U+9F60 */ 0xFD66, 0xFD67, 0xFD68, 0xFD69, 0xFD6A, 0xFD6B, 0xFD6C, 0xFD6D,
+ /* U+9F68 */ 0xFD6E, 0xFD6F, 0xFD70, 0xFD71, 0xFD72, 0xFD73, 0xFD74, 0xFD75,
+ /* U+9F70 */ 0xFD76, 0xFD77, 0xFD78, 0xFD79, 0xFD7A, 0xFD7B, 0xFD7C, 0xFD7D,
+ /* U+9F78 */ 0xFD7E, 0xFD80, 0xFD81, 0xFD82, 0xFD83, 0xFD84, 0xFD85, 0xB3DD,
+ /* U+9F80 */ 0xF6B3, 0xFD86, 0xFD87, 0xF6B4, 0xC1E4, 0xF6B5, 0xF6B6, 0xF6B7,
+ /* U+9F88 */ 0xF6B8, 0xF6B9, 0xF6BA, 0xC8A3, 0xF6BB, 0xFD88, 0xFD89, 0xFD8A,
+ /* U+9F90 */ 0xFD8B, 0xFD8C, 0xFD8D, 0xFD8E, 0xFD8F, 0xFD90, 0xFD91, 0xFD92,
+ /* U+9F98 */ 0xFD93, 0xC1FA, 0xB9A8, 0xEDE8, 0xFD94, 0xFD95, 0xFD96, 0xB9EA,
+ /* U+9FA0 */ 0xD9DF, 0xFD97, 0xFD98, 0xFD99, 0xFD9A, 0xFD9B,
+ /* Contiguous area: U+E766 .. U+E864 */
+ /* U+E766 */ 0xA2AB, 0xA2AC,
+ /* U+E768 */ 0xA2AD, 0xA2AE, 0xA2AF, 0xA2B0, 0x6469, 0xA2E4, 0xA2EF, 0xA2F0,
+ /* U+E770 */ 0xA2FD, 0xA2FE, 0xA4F4, 0xA4F5, 0xA4F6, 0xA4F7, 0xA4F8, 0xA4F9,
+ /* U+E778 */ 0xA4FA, 0xA4FB, 0xA4FC, 0xA4FD, 0xA4FE, 0xA5F7, 0xA5F8, 0xA5F9,
+ /* U+E780 */ 0xA5FA, 0xA5FB, 0xA5FC, 0xA5FD, 0xA5FE, 0xA6B9, 0xA6BA, 0xA6BB,
+ /* U+E788 */ 0xA6BC, 0xA6BD, 0xA6BE, 0xA6BF, 0xA6C0, 0xA6D9, 0xA6DA, 0xA6DB,
+ /* U+E790 */ 0xA6DC, 0xA6DD, 0xA6DE, 0xA6DF, 0xA6EC, 0xA6ED, 0xA6F3, 0xA6F6,
+ /* U+E798 */ 0xA6F7, 0xA6F8, 0xA6F9, 0xA6FA, 0xA6FB, 0xA6FC, 0xA6FD, 0xA6FE,
+ /* U+E7A0 */ 0xA7C2, 0xA7C3, 0xA7C4, 0xA7C5, 0xA7C6, 0xA7C7, 0xA7C8, 0xA7C9,
+ /* U+E7A8 */ 0xA7CA, 0xA7CB, 0xA7CC, 0xA7CD, 0xA7CE, 0xA7CF, 0xA7D0, 0xA7F2,
+ /* U+E7B0 */ 0xA7F3, 0xA7F4, 0xA7F5, 0xA7F6, 0xA7F7, 0xA7F8, 0xA7F9, 0xA7FA,
+ /* U+E7B8 */ 0xA7FB, 0xA7FC, 0xA7FD, 0xA7FE, 0xA896, 0xA897, 0xA898, 0xA899,
+ /* U+E7C0 */ 0xA89A, 0xA89B, 0xA89C, 0xA89D, 0xA89E, 0xA89F, 0xA8A0, 0xA8BC,
+ /* U+E7C8 */ 0x6470, 0xA8C1, 0xA8C2, 0xA8C3, 0xA8C4, 0xA8EA, 0xA8EB, 0xA8EC,
+ /* U+E7D0 */ 0xA8ED, 0xA8EE, 0xA8EF, 0xA8F0, 0xA8F1, 0xA8F2, 0xA8F3, 0xA8F4,
+ /* U+E7D8 */ 0xA8F5, 0xA8F6, 0xA8F7, 0xA8F8, 0xA8F9, 0xA8FA, 0xA8FB, 0xA8FC,
+ /* U+E7E0 */ 0xA8FD, 0xA8FE, 0xA958, 0xA95B, 0xA95D, 0xA95E, 0xA95F, 0x6471,
+ /* U+E7E8 */ 0x6472, 0x6473, 0x6474, 0x6475, 0x6476, 0x6477, 0x6478, 0x6479,
+ /* U+E7F0 */ 0x6480, 0x6481, 0x6482, 0x6483, 0xA997, 0xA998, 0xA999, 0xA99A,
+ /* U+E7F8 */ 0xA99B, 0xA99C, 0xA99D, 0xA99E, 0xA99F, 0xA9A0, 0xA9A1, 0xA9A2,
+ /* U+E800 */ 0xA9A3, 0xA9F0, 0xA9F1, 0xA9F2, 0xA9F3, 0xA9F4, 0xA9F5, 0xA9F6,
+ /* U+E808 */ 0xA9F7, 0xA9F8, 0xA9F9, 0xA9FA, 0xA9FB, 0xA9FC, 0xA9FD, 0xA9FE,
+ /* U+E810 */ 0xD7FA, 0xD7FB, 0xD7FC, 0xD7FD, 0xD7FE, 0x6484, 0xFE51, 0xFE52,
+ /* U+E818 */ 0xFE53, 0x6485, 0x6486, 0x6487, 0x6488, 0x6489, 0xFE59, 0x6490,
+ /* U+E820 */ 0x6491, 0x6492, 0x6493, 0x6494, 0x6495, 0x6496, 0xFE61, 0x6497,
+ /* U+E828 */ 0x6498, 0x6499, 0x64A0, 0xFE66, 0xFE67, 0x64A1, 0x64A2, 0x64A3,
+ /* U+E830 */ 0x64A4, 0xFE6C, 0xFE6D, 0x64A5, 0x64A6, 0x64A7, 0x64A8, 0x64A9,
+ /* U+E838 */ 0x64B0, 0x64B1, 0x64B2, 0xFE76, 0x64B3, 0x64B4, 0x64B5, 0x64B6,
+ /* U+E840 */ 0x64B7, 0x64B8, 0x64B9, 0xFE7E, 0x64C0, 0x64C1, 0x64C2, 0x64C3,
+ /* U+E848 */ 0x64C4, 0x64C5, 0x64C6, 0x64C7, 0x64C8, 0x64C9, 0x64D0, 0x64D1,
+ /* U+E850 */ 0x64D2, 0x64D3, 0x64D4, 0x64D5, 0xFE90, 0xFE91, 0x64D6, 0x64D7,
+ /* U+E858 */ 0x64D8, 0x64D9, 0x64E0, 0x64E1, 0x64E2, 0x64E3, 0x64E4, 0x64E5,
+ /* U+E860 */ 0x64E6, 0x64E7, 0x64E8, 0x64E9, 0xFEA0,
+ /* Contiguous area: U+F92C .. U+FA29 */
+ /* U+F92C */ 0xFD9C, 0x7045, 0x7046, 0x7047,
+ /* U+F930 */ 0x7048, 0x7049, 0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055,
+ /* U+F938 */ 0x7056, 0x7057, 0x7058, 0x7059, 0x7060, 0x7061, 0x7062, 0x7063,
+ /* U+F940 */ 0x7064, 0x7065, 0x7066, 0x7067, 0x7068, 0x7069, 0x7070, 0x7071,
+ /* U+F948 */ 0x7072, 0x7073, 0x7074, 0x7075, 0x7076, 0x7077, 0x7078, 0x7079,
+ /* U+F950 */ 0x7080, 0x7081, 0x7082, 0x7083, 0x7084, 0x7085, 0x7086, 0x7087,
+ /* U+F958 */ 0x7088, 0x7089, 0x7090, 0x7091, 0x7092, 0x7093, 0x7094, 0x7095,
+ /* U+F960 */ 0x7096, 0x7097, 0x7098, 0x7099, 0x70A0, 0x70A1, 0x70A2, 0x70A3,
+ /* U+F968 */ 0x70A4, 0x70A5, 0x70A6, 0x70A7, 0x70A8, 0x70A9, 0x70B0, 0x70B1,
+ /* U+F970 */ 0x70B2, 0x70B3, 0x70B4, 0x70B5, 0x70B6, 0x70B7, 0x70B8, 0x70B9,
+ /* U+F978 */ 0x70C0, 0xFD9D, 0x70C1, 0x70C2, 0x70C3, 0x70C4, 0x70C5, 0x70C6,
+ /* U+F980 */ 0x70C7, 0x70C8, 0x70C9, 0x70D0, 0x70D1, 0x70D2, 0x70D3, 0x70D4,
+ /* U+F988 */ 0x70D5, 0x70D6, 0x70D7, 0x70D8, 0x70D9, 0x70E0, 0x70E1, 0x70E2,
+ /* U+F990 */ 0x70E3, 0x70E4, 0x70E5, 0x70E6, 0x70E7, 0xFD9E, 0x70E8, 0x70E9,
+ /* U+F998 */ 0x70F0, 0x70F1, 0x70F2, 0x70F3, 0x70F4, 0x70F5, 0x70F6, 0x70F7,
+ /* U+F9A0 */ 0x70F8, 0x70F9, 0x7100, 0x7101, 0x7102, 0x7103, 0x7104, 0x7105,
+ /* U+F9A8 */ 0x7106, 0x7107, 0x7108, 0x7109, 0x7110, 0x7111, 0x7112, 0x7113,
+ /* U+F9B0 */ 0x7114, 0x7115, 0x7116, 0x7117, 0x7118, 0x7119, 0x7120, 0x7121,
+ /* U+F9B8 */ 0x7122, 0x7123, 0x7124, 0x7125, 0x7126, 0x7127, 0x7128, 0x7129,
+ /* U+F9C0 */ 0x7130, 0x7131, 0x7132, 0x7133, 0x7134, 0x7135, 0x7136, 0x7137,
+ /* U+F9C8 */ 0x7138, 0x7139, 0x7140, 0x7141, 0x7142, 0x7143, 0x7144, 0x7145,
+ /* U+F9D0 */ 0x7146, 0x7147, 0x7148, 0x7149, 0x7150, 0x7151, 0x7152, 0x7153,
+ /* U+F9D8 */ 0x7154, 0x7155, 0x7156, 0x7157, 0x7158, 0x7159, 0x7160, 0x7161,
+ /* U+F9E0 */ 0x7162, 0x7163, 0x7164, 0x7165, 0x7166, 0x7167, 0x7168, 0xFD9F,
+ /* U+F9E8 */ 0x7169, 0x7170, 0x7171, 0x7172, 0x7173, 0x7174, 0x7175, 0x7176,
+ /* U+F9F0 */ 0x7177, 0xFDA0, 0x7178, 0x7179, 0x7180, 0x7181, 0x7182, 0x7183,
+ /* U+F9F8 */ 0x7184, 0x7185, 0x7186, 0x7187, 0x7188, 0x7189, 0x7190, 0x7191,
+ /* U+FA00 */ 0x7192, 0x7193, 0x7194, 0x7195, 0x7196, 0x7197, 0x7198, 0x7199,
+ /* U+FA08 */ 0x71A0, 0x71A1, 0x71A2, 0x71A3, 0xFE40, 0xFE41, 0xFE42, 0xFE43,
+ /* U+FA10 */ 0x71A4, 0xFE44, 0x71A5, 0xFE45, 0xFE46, 0x71A6, 0x71A7, 0x71A8,
+ /* U+FA18 */ 0xFE47, 0x71A9, 0x71B0, 0x71B1, 0x71B2, 0x71B3, 0x71B4, 0xFE48,
+ /* U+FA20 */ 0xFE49, 0xFE4A, 0x71B5, 0xFE4B, 0xFE4C, 0x71B6, 0x71B7, 0xFE4D,
+ /* U+FA28 */ 0xFE4E, 0xFE4F,
+ /* Contiguous area: U+FE30 .. U+FFE5 */
+ /* U+FE30 */ 0xA955, 0xA6F2, 0x7848, 0xA6F4, 0xA6F5, 0xA6E0, 0xA6E1, 0xA6F0,
+ /* U+FE38 */ 0xA6F1, 0xA6E2, 0xA6E3, 0xA6EE, 0xA6EF, 0xA6E6, 0xA6E7, 0xA6E4,
+ /* U+FE40 */ 0xA6E5, 0xA6E8, 0xA6E9, 0xA6EA, 0xA6EB, 0x7849, 0x7850, 0x7851,
+ /* U+FE48 */ 0x7852, 0xA968, 0xA969, 0xA96A, 0xA96B, 0xA96C, 0xA96D, 0xA96E,
+ /* U+FE50 */ 0xA96F, 0xA970, 0xA971, 0x7853, 0xA972, 0xA973, 0xA974, 0xA975,
+ /* U+FE58 */ 0x7854, 0xA976, 0xA977, 0xA978, 0xA979, 0xA97A, 0xA97B, 0xA97C,
+ /* U+FE60 */ 0xA97D, 0xA97E, 0xA980, 0xA981, 0xA982, 0xA983, 0xA984, 0x7855,
+ /* U+FE68 */ 0xA985, 0xA986, 0xA987, 0xA988, 0x7856, 0x7857, 0x7858, 0x7859,
+ /* U+FE70 */ 0x7860, 0x7861, 0x7862, 0x7863, 0x7864, 0x7865, 0x7866, 0x7867,
+ /* U+FE78 */ 0x7868, 0x7869, 0x7870, 0x7871, 0x7872, 0x7873, 0x7874, 0x7875,
+ /* U+FE80 */ 0x7876, 0x7877, 0x7878, 0x7879, 0x7880, 0x7881, 0x7882, 0x7883,
+ /* U+FE88 */ 0x7884, 0x7885, 0x7886, 0x7887, 0x7888, 0x7889, 0x7890, 0x7891,
+ /* U+FE90 */ 0x7892, 0x7893, 0x7894, 0x7895, 0x7896, 0x7897, 0x7898, 0x7899,
+ /* U+FE98 */ 0x78A0, 0x78A1, 0x78A2, 0x78A3, 0x78A4, 0x78A5, 0x78A6, 0x78A7,
+ /* U+FEA0 */ 0x78A8, 0x78A9, 0x78B0, 0x78B1, 0x78B2, 0x78B3, 0x78B4, 0x78B5,
+ /* U+FEA8 */ 0x78B6, 0x78B7, 0x78B8, 0x78B9, 0x78C0, 0x78C1, 0x78C2, 0x78C3,
+ /* U+FEB0 */ 0x78C4, 0x78C5, 0x78C6, 0x78C7, 0x78C8, 0x78C9, 0x78D0, 0x78D1,
+ /* U+FEB8 */ 0x78D2, 0x78D3, 0x78D4, 0x78D5, 0x78D6, 0x78D7, 0x78D8, 0x78D9,
+ /* U+FEC0 */ 0x78E0, 0x78E1, 0x78E2, 0x78E3, 0x78E4, 0x78E5, 0x78E6, 0x78E7,
+ /* U+FEC8 */ 0x78E8, 0x78E9, 0x78F0, 0x78F1, 0x78F2, 0x78F3, 0x78F4, 0x78F5,
+ /* U+FED0 */ 0x78F6, 0x78F7, 0x78F8, 0x78F9, 0x7900, 0x7901, 0x7902, 0x7903,
+ /* U+FED8 */ 0x7904, 0x7905, 0x7906, 0x7907, 0x7908, 0x7909, 0x7910, 0x7911,
+ /* U+FEE0 */ 0x7912, 0x7913, 0x7914, 0x7915, 0x7916, 0x7917, 0x7918, 0x7919,
+ /* U+FEE8 */ 0x7920, 0x7921, 0x7922, 0x7923, 0x7924, 0x7925, 0x7926, 0x7927,
+ /* U+FEF0 */ 0x7928, 0x7929, 0x7930, 0x7931, 0x7932, 0x7933, 0x7934, 0x7935,
+ /* U+FEF8 */ 0x7936, 0x7937, 0x7938, 0x7939, 0x7940, 0x7941, 0x7942, 0x7943,
+ /* U+FF00 */ 0x7944, 0xA3A1, 0xA3A2, 0xA3A3, 0xA1E7, 0xA3A5, 0xA3A6, 0xA3A7,
+ /* U+FF08 */ 0xA3A8, 0xA3A9, 0xA3AA, 0xA3AB, 0xA3AC, 0xA3AD, 0xA3AE, 0xA3AF,
+ /* U+FF10 */ 0xA3B0, 0xA3B1, 0xA3B2, 0xA3B3, 0xA3B4, 0xA3B5, 0xA3B6, 0xA3B7,
+ /* U+FF18 */ 0xA3B8, 0xA3B9, 0xA3BA, 0xA3BB, 0xA3BC, 0xA3BD, 0xA3BE, 0xA3BF,
+ /* U+FF20 */ 0xA3C0, 0xA3C1, 0xA3C2, 0xA3C3, 0xA3C4, 0xA3C5, 0xA3C6, 0xA3C7,
+ /* U+FF28 */ 0xA3C8, 0xA3C9, 0xA3CA, 0xA3CB, 0xA3CC, 0xA3CD, 0xA3CE, 0xA3CF,
+ /* U+FF30 */ 0xA3D0, 0xA3D1, 0xA3D2, 0xA3D3, 0xA3D4, 0xA3D5, 0xA3D6, 0xA3D7,
+ /* U+FF38 */ 0xA3D8, 0xA3D9, 0xA3DA, 0xA3DB, 0xA3DC, 0xA3DD, 0xA3DE, 0xA3DF,
+ /* U+FF40 */ 0xA3E0, 0xA3E1, 0xA3E2, 0xA3E3, 0xA3E4, 0xA3E5, 0xA3E6, 0xA3E7,
+ /* U+FF48 */ 0xA3E8, 0xA3E9, 0xA3EA, 0xA3EB, 0xA3EC, 0xA3ED, 0xA3EE, 0xA3EF,
+ /* U+FF50 */ 0xA3F0, 0xA3F1, 0xA3F2, 0xA3F3, 0xA3F4, 0xA3F5, 0xA3F6, 0xA3F7,
+ /* U+FF58 */ 0xA3F8, 0xA3F9, 0xA3FA, 0xA3FB, 0xA3FC, 0xA3FD, 0xA1AB, 0x7945,
+ /* U+FF60 */ 0x7946, 0x7947, 0x7948, 0x7949, 0x7950, 0x7951, 0x7952, 0x7953,
+ /* U+FF68 */ 0x7954, 0x7955, 0x7956, 0x7957, 0x7958, 0x7959, 0x7960, 0x7961,
+ /* U+FF70 */ 0x7962, 0x7963, 0x7964, 0x7965, 0x7966, 0x7967, 0x7968, 0x7969,
+ /* U+FF78 */ 0x7970, 0x7971, 0x7972, 0x7973, 0x7974, 0x7975, 0x7976, 0x7977,
+ /* U+FF80 */ 0x7978, 0x7979, 0x7980, 0x7981, 0x7982, 0x7983, 0x7984, 0x7985,
+ /* U+FF88 */ 0x7986, 0x7987, 0x7988, 0x7989, 0x7990, 0x7991, 0x7992, 0x7993,
+ /* U+FF90 */ 0x7994, 0x7995, 0x7996, 0x7997, 0x7998, 0x7999, 0x79A0, 0x79A1,
+ /* U+FF98 */ 0x79A2, 0x79A3, 0x79A4, 0x79A5, 0x79A6, 0x79A7, 0x79A8, 0x79A9,
+ /* U+FFA0 */ 0x79B0, 0x79B1, 0x79B2, 0x79B3, 0x79B4, 0x79B5, 0x79B6, 0x79B7,
+ /* U+FFA8 */ 0x79B8, 0x79B9, 0x79C0, 0x79C1, 0x79C2, 0x79C3, 0x79C4, 0x79C5,
+ /* U+FFB0 */ 0x79C6, 0x79C7, 0x79C8, 0x79C9, 0x79D0, 0x79D1, 0x79D2, 0x79D3,
+ /* U+FFB8 */ 0x79D4, 0x79D5, 0x79D6, 0x79D7, 0x79D8, 0x79D9, 0x79E0, 0x79E1,
+ /* U+FFC0 */ 0x79E2, 0x79E3, 0x79E4, 0x79E5, 0x79E6, 0x79E7, 0x79E8, 0x79E9,
+ /* U+FFC8 */ 0x79F0, 0x79F1, 0x79F2, 0x79F3, 0x79F4, 0x79F5, 0x79F6, 0x79F7,
+ /* U+FFD0 */ 0x79F8, 0x79F9, 0x7A00, 0x7A01, 0x7A02, 0x7A03, 0x7A04, 0x7A05,
+ /* U+FFD8 */ 0x7A06, 0x7A07, 0x7A08, 0x7A09, 0x7A10, 0x7A11, 0x7A12, 0x7A13,
+ /* U+FFE0 */ 0xA1E9, 0xA1EA, 0xA956, 0xA3FE, 0xA957, 0xA3A4,
+};
+
+static TQ_UINT16 const gb18030_2byte_to_ucs[22046] = {
+ /* GB 0x8140..0x817E */
+ 0x4E02, 0x4E04, 0x4E05, 0x4E06, 0x4E0F, 0x4E12, 0x4E17, 0x4E1F,
+ 0x4E20, 0x4E21, 0x4E23, 0x4E26, 0x4E29, 0x4E2E, 0x4E2F, 0x4E31,
+ 0x4E33, 0x4E35, 0x4E37, 0x4E3C, 0x4E40, 0x4E41, 0x4E42, 0x4E44,
+ 0x4E46, 0x4E4A, 0x4E51, 0x4E55, 0x4E57, 0x4E5A, 0x4E5B, 0x4E62,
+ 0x4E63, 0x4E64, 0x4E65, 0x4E67, 0x4E68, 0x4E6A, 0x4E6B, 0x4E6C,
+ 0x4E6D, 0x4E6E, 0x4E6F, 0x4E72, 0x4E74, 0x4E75, 0x4E76, 0x4E77,
+ 0x4E78, 0x4E79, 0x4E7A, 0x4E7B, 0x4E7C, 0x4E7D, 0x4E7F, 0x4E80,
+ 0x4E81, 0x4E82, 0x4E83, 0x4E84, 0x4E85, 0x4E87, 0x4E8A,
+ /* GB 0x8180..0x81FE */
+ 0x4E90, 0x4E96, 0x4E97, 0x4E99, 0x4E9C, 0x4E9D, 0x4E9E, 0x4EA3,
+ 0x4EAA, 0x4EAF, 0x4EB0, 0x4EB1, 0x4EB4, 0x4EB6, 0x4EB7, 0x4EB8,
+ 0x4EB9, 0x4EBC, 0x4EBD, 0x4EBE, 0x4EC8, 0x4ECC, 0x4ECF, 0x4ED0,
+ 0x4ED2, 0x4EDA, 0x4EDB, 0x4EDC, 0x4EE0, 0x4EE2, 0x4EE6, 0x4EE7,
+ 0x4EE9, 0x4EED, 0x4EEE, 0x4EEF, 0x4EF1, 0x4EF4, 0x4EF8, 0x4EF9,
+ 0x4EFA, 0x4EFC, 0x4EFE, 0x4F00, 0x4F02, 0x4F03, 0x4F04, 0x4F05,
+ 0x4F06, 0x4F07, 0x4F08, 0x4F0B, 0x4F0C, 0x4F12, 0x4F13, 0x4F14,
+ 0x4F15, 0x4F16, 0x4F1C, 0x4F1D, 0x4F21, 0x4F23, 0x4F28, 0x4F29,
+ 0x4F2C, 0x4F2D, 0x4F2E, 0x4F31, 0x4F33, 0x4F35, 0x4F37, 0x4F39,
+ 0x4F3B, 0x4F3E, 0x4F3F, 0x4F40, 0x4F41, 0x4F42, 0x4F44, 0x4F45,
+ 0x4F47, 0x4F48, 0x4F49, 0x4F4A, 0x4F4B, 0x4F4C, 0x4F52, 0x4F54,
+ 0x4F56, 0x4F61, 0x4F62, 0x4F66, 0x4F68, 0x4F6A, 0x4F6B, 0x4F6D,
+ 0x4F6E, 0x4F71, 0x4F72, 0x4F75, 0x4F77, 0x4F78, 0x4F79, 0x4F7A,
+ 0x4F7D, 0x4F80, 0x4F81, 0x4F82, 0x4F85, 0x4F86, 0x4F87, 0x4F8A,
+ 0x4F8C, 0x4F8E, 0x4F90, 0x4F92, 0x4F93, 0x4F95, 0x4F96, 0x4F98,
+ 0x4F99, 0x4F9A, 0x4F9C, 0x4F9E, 0x4F9F, 0x4FA1, 0x4FA2,
+ /* GB 0x8240..0x827E */
+ 0x4FA4, 0x4FAB, 0x4FAD, 0x4FB0, 0x4FB1, 0x4FB2, 0x4FB3, 0x4FB4,
+ 0x4FB6, 0x4FB7, 0x4FB8, 0x4FB9, 0x4FBA, 0x4FBB, 0x4FBC, 0x4FBD,
+ 0x4FBE, 0x4FC0, 0x4FC1, 0x4FC2, 0x4FC6, 0x4FC7, 0x4FC8, 0x4FC9,
+ 0x4FCB, 0x4FCC, 0x4FCD, 0x4FD2, 0x4FD3, 0x4FD4, 0x4FD5, 0x4FD6,
+ 0x4FD9, 0x4FDB, 0x4FE0, 0x4FE2, 0x4FE4, 0x4FE5, 0x4FE7, 0x4FEB,
+ 0x4FEC, 0x4FF0, 0x4FF2, 0x4FF4, 0x4FF5, 0x4FF6, 0x4FF7, 0x4FF9,
+ 0x4FFB, 0x4FFC, 0x4FFD, 0x4FFF, 0x5000, 0x5001, 0x5002, 0x5003,
+ 0x5004, 0x5005, 0x5006, 0x5007, 0x5008, 0x5009, 0x500A,
+ /* GB 0x8280..0x82FE */
+ 0x500B, 0x500E, 0x5010, 0x5011, 0x5013, 0x5015, 0x5016, 0x5017,
+ 0x501B, 0x501D, 0x501E, 0x5020, 0x5022, 0x5023, 0x5024, 0x5027,
+ 0x502B, 0x502F, 0x5030, 0x5031, 0x5032, 0x5033, 0x5034, 0x5035,
+ 0x5036, 0x5037, 0x5038, 0x5039, 0x503B, 0x503D, 0x503F, 0x5040,
+ 0x5041, 0x5042, 0x5044, 0x5045, 0x5046, 0x5049, 0x504A, 0x504B,
+ 0x504D, 0x5050, 0x5051, 0x5052, 0x5053, 0x5054, 0x5056, 0x5057,
+ 0x5058, 0x5059, 0x505B, 0x505D, 0x505E, 0x505F, 0x5060, 0x5061,
+ 0x5062, 0x5063, 0x5064, 0x5066, 0x5067, 0x5068, 0x5069, 0x506A,
+ 0x506B, 0x506D, 0x506E, 0x506F, 0x5070, 0x5071, 0x5072, 0x5073,
+ 0x5074, 0x5075, 0x5078, 0x5079, 0x507A, 0x507C, 0x507D, 0x5081,
+ 0x5082, 0x5083, 0x5084, 0x5086, 0x5087, 0x5089, 0x508A, 0x508B,
+ 0x508C, 0x508E, 0x508F, 0x5090, 0x5091, 0x5092, 0x5093, 0x5094,
+ 0x5095, 0x5096, 0x5097, 0x5098, 0x5099, 0x509A, 0x509B, 0x509C,
+ 0x509D, 0x509E, 0x509F, 0x50A0, 0x50A1, 0x50A2, 0x50A4, 0x50A6,
+ 0x50AA, 0x50AB, 0x50AD, 0x50AE, 0x50AF, 0x50B0, 0x50B1, 0x50B3,
+ 0x50B4, 0x50B5, 0x50B6, 0x50B7, 0x50B8, 0x50B9, 0x50BC,
+ /* GB 0x8340..0x837E */
+ 0x50BD, 0x50BE, 0x50BF, 0x50C0, 0x50C1, 0x50C2, 0x50C3, 0x50C4,
+ 0x50C5, 0x50C6, 0x50C7, 0x50C8, 0x50C9, 0x50CA, 0x50CB, 0x50CC,
+ 0x50CD, 0x50CE, 0x50D0, 0x50D1, 0x50D2, 0x50D3, 0x50D4, 0x50D5,
+ 0x50D7, 0x50D8, 0x50D9, 0x50DB, 0x50DC, 0x50DD, 0x50DE, 0x50DF,
+ 0x50E0, 0x50E1, 0x50E2, 0x50E3, 0x50E4, 0x50E5, 0x50E8, 0x50E9,
+ 0x50EA, 0x50EB, 0x50EF, 0x50F0, 0x50F1, 0x50F2, 0x50F4, 0x50F6,
+ 0x50F7, 0x50F8, 0x50F9, 0x50FA, 0x50FC, 0x50FD, 0x50FE, 0x50FF,
+ 0x5100, 0x5101, 0x5102, 0x5103, 0x5104, 0x5105, 0x5108,
+ /* GB 0x8380..0x83FE */
+ 0x5109, 0x510A, 0x510C, 0x510D, 0x510E, 0x510F, 0x5110, 0x5111,
+ 0x5113, 0x5114, 0x5115, 0x5116, 0x5117, 0x5118, 0x5119, 0x511A,
+ 0x511B, 0x511C, 0x511D, 0x511E, 0x511F, 0x5120, 0x5122, 0x5123,
+ 0x5124, 0x5125, 0x5126, 0x5127, 0x5128, 0x5129, 0x512A, 0x512B,
+ 0x512C, 0x512D, 0x512E, 0x512F, 0x5130, 0x5131, 0x5132, 0x5133,
+ 0x5134, 0x5135, 0x5136, 0x5137, 0x5138, 0x5139, 0x513A, 0x513B,
+ 0x513C, 0x513D, 0x513E, 0x5142, 0x5147, 0x514A, 0x514C, 0x514E,
+ 0x514F, 0x5150, 0x5152, 0x5153, 0x5157, 0x5158, 0x5159, 0x515B,
+ 0x515D, 0x515E, 0x515F, 0x5160, 0x5161, 0x5163, 0x5164, 0x5166,
+ 0x5167, 0x5169, 0x516A, 0x516F, 0x5172, 0x517A, 0x517E, 0x517F,
+ 0x5183, 0x5184, 0x5186, 0x5187, 0x518A, 0x518B, 0x518E, 0x518F,
+ 0x5190, 0x5191, 0x5193, 0x5194, 0x5198, 0x519A, 0x519D, 0x519E,
+ 0x519F, 0x51A1, 0x51A3, 0x51A6, 0x51A7, 0x51A8, 0x51A9, 0x51AA,
+ 0x51AD, 0x51AE, 0x51B4, 0x51B8, 0x51B9, 0x51BA, 0x51BE, 0x51BF,
+ 0x51C1, 0x51C2, 0x51C3, 0x51C5, 0x51C8, 0x51CA, 0x51CD, 0x51CE,
+ 0x51D0, 0x51D2, 0x51D3, 0x51D4, 0x51D5, 0x51D6, 0x51D7,
+ /* GB 0x8440..0x847E */
+ 0x51D8, 0x51D9, 0x51DA, 0x51DC, 0x51DE, 0x51DF, 0x51E2, 0x51E3,
+ 0x51E5, 0x51E6, 0x51E7, 0x51E8, 0x51E9, 0x51EA, 0x51EC, 0x51EE,
+ 0x51F1, 0x51F2, 0x51F4, 0x51F7, 0x51FE, 0x5204, 0x5205, 0x5209,
+ 0x520B, 0x520C, 0x520F, 0x5210, 0x5213, 0x5214, 0x5215, 0x521C,
+ 0x521E, 0x521F, 0x5221, 0x5222, 0x5223, 0x5225, 0x5226, 0x5227,
+ 0x522A, 0x522C, 0x522F, 0x5231, 0x5232, 0x5234, 0x5235, 0x523C,
+ 0x523E, 0x5244, 0x5245, 0x5246, 0x5247, 0x5248, 0x5249, 0x524B,
+ 0x524E, 0x524F, 0x5252, 0x5253, 0x5255, 0x5257, 0x5258,
+ /* GB 0x8480..0x84FE */
+ 0x5259, 0x525A, 0x525B, 0x525D, 0x525F, 0x5260, 0x5262, 0x5263,
+ 0x5264, 0x5266, 0x5268, 0x526B, 0x526C, 0x526D, 0x526E, 0x5270,
+ 0x5271, 0x5273, 0x5274, 0x5275, 0x5276, 0x5277, 0x5278, 0x5279,
+ 0x527A, 0x527B, 0x527C, 0x527E, 0x5280, 0x5283, 0x5284, 0x5285,
+ 0x5286, 0x5287, 0x5289, 0x528A, 0x528B, 0x528C, 0x528D, 0x528E,
+ 0x528F, 0x5291, 0x5292, 0x5294, 0x5295, 0x5296, 0x5297, 0x5298,
+ 0x5299, 0x529A, 0x529C, 0x52A4, 0x52A5, 0x52A6, 0x52A7, 0x52AE,
+ 0x52AF, 0x52B0, 0x52B4, 0x52B5, 0x52B6, 0x52B7, 0x52B8, 0x52B9,
+ 0x52BA, 0x52BB, 0x52BC, 0x52BD, 0x52C0, 0x52C1, 0x52C2, 0x52C4,
+ 0x52C5, 0x52C6, 0x52C8, 0x52CA, 0x52CC, 0x52CD, 0x52CE, 0x52CF,
+ 0x52D1, 0x52D3, 0x52D4, 0x52D5, 0x52D7, 0x52D9, 0x52DA, 0x52DB,
+ 0x52DC, 0x52DD, 0x52DE, 0x52E0, 0x52E1, 0x52E2, 0x52E3, 0x52E5,
+ 0x52E6, 0x52E7, 0x52E8, 0x52E9, 0x52EA, 0x52EB, 0x52EC, 0x52ED,
+ 0x52EE, 0x52EF, 0x52F1, 0x52F2, 0x52F3, 0x52F4, 0x52F5, 0x52F6,
+ 0x52F7, 0x52F8, 0x52FB, 0x52FC, 0x52FD, 0x5301, 0x5302, 0x5303,
+ 0x5304, 0x5307, 0x5309, 0x530A, 0x530B, 0x530C, 0x530E,
+ /* GB 0x8540..0x857E */
+ 0x5311, 0x5312, 0x5313, 0x5314, 0x5318, 0x531B, 0x531C, 0x531E,
+ 0x531F, 0x5322, 0x5324, 0x5325, 0x5327, 0x5328, 0x5329, 0x532B,
+ 0x532C, 0x532D, 0x532F, 0x5330, 0x5331, 0x5332, 0x5333, 0x5334,
+ 0x5335, 0x5336, 0x5337, 0x5338, 0x533C, 0x533D, 0x5340, 0x5342,
+ 0x5344, 0x5346, 0x534B, 0x534C, 0x534D, 0x5350, 0x5354, 0x5358,
+ 0x5359, 0x535B, 0x535D, 0x5365, 0x5368, 0x536A, 0x536C, 0x536D,
+ 0x5372, 0x5376, 0x5379, 0x537B, 0x537C, 0x537D, 0x537E, 0x5380,
+ 0x5381, 0x5383, 0x5387, 0x5388, 0x538A, 0x538E, 0x538F,
+ /* GB 0x8580..0x85FE */
+ 0x5390, 0x5391, 0x5392, 0x5393, 0x5394, 0x5396, 0x5397, 0x5399,
+ 0x539B, 0x539C, 0x539E, 0x53A0, 0x53A1, 0x53A4, 0x53A7, 0x53AA,
+ 0x53AB, 0x53AC, 0x53AD, 0x53AF, 0x53B0, 0x53B1, 0x53B2, 0x53B3,
+ 0x53B4, 0x53B5, 0x53B7, 0x53B8, 0x53B9, 0x53BA, 0x53BC, 0x53BD,
+ 0x53BE, 0x53C0, 0x53C3, 0x53C4, 0x53C5, 0x53C6, 0x53C7, 0x53CE,
+ 0x53CF, 0x53D0, 0x53D2, 0x53D3, 0x53D5, 0x53DA, 0x53DC, 0x53DD,
+ 0x53DE, 0x53E1, 0x53E2, 0x53E7, 0x53F4, 0x53FA, 0x53FE, 0x53FF,
+ 0x5400, 0x5402, 0x5405, 0x5407, 0x540B, 0x5414, 0x5418, 0x5419,
+ 0x541A, 0x541C, 0x5422, 0x5424, 0x5425, 0x542A, 0x5430, 0x5433,
+ 0x5436, 0x5437, 0x543A, 0x543D, 0x543F, 0x5441, 0x5442, 0x5444,
+ 0x5445, 0x5447, 0x5449, 0x544C, 0x544D, 0x544E, 0x544F, 0x5451,
+ 0x545A, 0x545D, 0x545E, 0x545F, 0x5460, 0x5461, 0x5463, 0x5465,
+ 0x5467, 0x5469, 0x546A, 0x546B, 0x546C, 0x546D, 0x546E, 0x546F,
+ 0x5470, 0x5474, 0x5479, 0x547A, 0x547E, 0x547F, 0x5481, 0x5483,
+ 0x5485, 0x5487, 0x5488, 0x5489, 0x548A, 0x548D, 0x5491, 0x5493,
+ 0x5497, 0x5498, 0x549C, 0x549E, 0x549F, 0x54A0, 0x54A1,
+ /* GB 0x8640..0x867E */
+ 0x54A2, 0x54A5, 0x54AE, 0x54B0, 0x54B2, 0x54B5, 0x54B6, 0x54B7,
+ 0x54B9, 0x54BA, 0x54BC, 0x54BE, 0x54C3, 0x54C5, 0x54CA, 0x54CB,
+ 0x54D6, 0x54D8, 0x54DB, 0x54E0, 0x54E1, 0x54E2, 0x54E3, 0x54E4,
+ 0x54EB, 0x54EC, 0x54EF, 0x54F0, 0x54F1, 0x54F4, 0x54F5, 0x54F6,
+ 0x54F7, 0x54F8, 0x54F9, 0x54FB, 0x54FE, 0x5500, 0x5502, 0x5503,
+ 0x5504, 0x5505, 0x5508, 0x550A, 0x550B, 0x550C, 0x550D, 0x550E,
+ 0x5512, 0x5513, 0x5515, 0x5516, 0x5517, 0x5518, 0x5519, 0x551A,
+ 0x551C, 0x551D, 0x551E, 0x551F, 0x5521, 0x5525, 0x5526,
+ /* GB 0x8680..0x86FE */
+ 0x5528, 0x5529, 0x552B, 0x552D, 0x5532, 0x5534, 0x5535, 0x5536,
+ 0x5538, 0x5539, 0x553A, 0x553B, 0x553D, 0x5540, 0x5542, 0x5545,
+ 0x5547, 0x5548, 0x554B, 0x554C, 0x554D, 0x554E, 0x554F, 0x5551,
+ 0x5552, 0x5553, 0x5554, 0x5557, 0x5558, 0x5559, 0x555A, 0x555B,
+ 0x555D, 0x555E, 0x555F, 0x5560, 0x5562, 0x5563, 0x5568, 0x5569,
+ 0x556B, 0x556F, 0x5570, 0x5571, 0x5572, 0x5573, 0x5574, 0x5579,
+ 0x557A, 0x557D, 0x557F, 0x5585, 0x5586, 0x558C, 0x558D, 0x558E,
+ 0x5590, 0x5592, 0x5593, 0x5595, 0x5596, 0x5597, 0x559A, 0x559B,
+ 0x559E, 0x55A0, 0x55A1, 0x55A2, 0x55A3, 0x55A4, 0x55A5, 0x55A6,
+ 0x55A8, 0x55A9, 0x55AA, 0x55AB, 0x55AC, 0x55AD, 0x55AE, 0x55AF,
+ 0x55B0, 0x55B2, 0x55B4, 0x55B6, 0x55B8, 0x55BA, 0x55BC, 0x55BF,
+ 0x55C0, 0x55C1, 0x55C2, 0x55C3, 0x55C6, 0x55C7, 0x55C8, 0x55CA,
+ 0x55CB, 0x55CE, 0x55CF, 0x55D0, 0x55D5, 0x55D7, 0x55D8, 0x55D9,
+ 0x55DA, 0x55DB, 0x55DE, 0x55E0, 0x55E2, 0x55E7, 0x55E9, 0x55ED,
+ 0x55EE, 0x55F0, 0x55F1, 0x55F4, 0x55F6, 0x55F8, 0x55F9, 0x55FA,
+ 0x55FB, 0x55FC, 0x55FF, 0x5602, 0x5603, 0x5604, 0x5605,
+ /* GB 0x8740..0x877E */
+ 0x5606, 0x5607, 0x560A, 0x560B, 0x560D, 0x5610, 0x5611, 0x5612,
+ 0x5613, 0x5614, 0x5615, 0x5616, 0x5617, 0x5619, 0x561A, 0x561C,
+ 0x561D, 0x5620, 0x5621, 0x5622, 0x5625, 0x5626, 0x5628, 0x5629,
+ 0x562A, 0x562B, 0x562E, 0x562F, 0x5630, 0x5633, 0x5635, 0x5637,
+ 0x5638, 0x563A, 0x563C, 0x563D, 0x563E, 0x5640, 0x5641, 0x5642,
+ 0x5643, 0x5644, 0x5645, 0x5646, 0x5647, 0x5648, 0x5649, 0x564A,
+ 0x564B, 0x564F, 0x5650, 0x5651, 0x5652, 0x5653, 0x5655, 0x5656,
+ 0x565A, 0x565B, 0x565D, 0x565E, 0x565F, 0x5660, 0x5661,
+ /* GB 0x8780..0x87FE */
+ 0x5663, 0x5665, 0x5666, 0x5667, 0x566D, 0x566E, 0x566F, 0x5670,
+ 0x5672, 0x5673, 0x5674, 0x5675, 0x5677, 0x5678, 0x5679, 0x567A,
+ 0x567D, 0x567E, 0x567F, 0x5680, 0x5681, 0x5682, 0x5683, 0x5684,
+ 0x5687, 0x5688, 0x5689, 0x568A, 0x568B, 0x568C, 0x568D, 0x5690,
+ 0x5691, 0x5692, 0x5694, 0x5695, 0x5696, 0x5697, 0x5698, 0x5699,
+ 0x569A, 0x569B, 0x569C, 0x569D, 0x569E, 0x569F, 0x56A0, 0x56A1,
+ 0x56A2, 0x56A4, 0x56A5, 0x56A6, 0x56A7, 0x56A8, 0x56A9, 0x56AA,
+ 0x56AB, 0x56AC, 0x56AD, 0x56AE, 0x56B0, 0x56B1, 0x56B2, 0x56B3,
+ 0x56B4, 0x56B5, 0x56B6, 0x56B8, 0x56B9, 0x56BA, 0x56BB, 0x56BD,
+ 0x56BE, 0x56BF, 0x56C0, 0x56C1, 0x56C2, 0x56C3, 0x56C4, 0x56C5,
+ 0x56C6, 0x56C7, 0x56C8, 0x56C9, 0x56CB, 0x56CC, 0x56CD, 0x56CE,
+ 0x56CF, 0x56D0, 0x56D1, 0x56D2, 0x56D3, 0x56D5, 0x56D6, 0x56D8,
+ 0x56D9, 0x56DC, 0x56E3, 0x56E5, 0x56E6, 0x56E7, 0x56E8, 0x56E9,
+ 0x56EA, 0x56EC, 0x56EE, 0x56EF, 0x56F2, 0x56F3, 0x56F6, 0x56F7,
+ 0x56F8, 0x56FB, 0x56FC, 0x5700, 0x5701, 0x5702, 0x5705, 0x5707,
+ 0x570B, 0x570C, 0x570D, 0x570E, 0x570F, 0x5710, 0x5711,
+ /* GB 0x8840..0x887E */
+ 0x5712, 0x5713, 0x5714, 0x5715, 0x5716, 0x5717, 0x5718, 0x5719,
+ 0x571A, 0x571B, 0x571D, 0x571E, 0x5720, 0x5721, 0x5722, 0x5724,
+ 0x5725, 0x5726, 0x5727, 0x572B, 0x5731, 0x5732, 0x5734, 0x5735,
+ 0x5736, 0x5737, 0x5738, 0x573C, 0x573D, 0x573F, 0x5741, 0x5743,
+ 0x5744, 0x5745, 0x5746, 0x5748, 0x5749, 0x574B, 0x5752, 0x5753,
+ 0x5754, 0x5755, 0x5756, 0x5758, 0x5759, 0x5762, 0x5763, 0x5765,
+ 0x5767, 0x576C, 0x576E, 0x5770, 0x5771, 0x5772, 0x5774, 0x5775,
+ 0x5778, 0x5779, 0x577A, 0x577D, 0x577E, 0x577F, 0x5780,
+ /* GB 0x8880..0x88FE */
+ 0x5781, 0x5787, 0x5788, 0x5789, 0x578A, 0x578D, 0x578E, 0x578F,
+ 0x5790, 0x5791, 0x5794, 0x5795, 0x5796, 0x5797, 0x5798, 0x5799,
+ 0x579A, 0x579C, 0x579D, 0x579E, 0x579F, 0x57A5, 0x57A8, 0x57AA,
+ 0x57AC, 0x57AF, 0x57B0, 0x57B1, 0x57B3, 0x57B5, 0x57B6, 0x57B7,
+ 0x57B9, 0x57BA, 0x57BB, 0x57BC, 0x57BD, 0x57BE, 0x57BF, 0x57C0,
+ 0x57C1, 0x57C4, 0x57C5, 0x57C6, 0x57C7, 0x57C8, 0x57C9, 0x57CA,
+ 0x57CC, 0x57CD, 0x57D0, 0x57D1, 0x57D3, 0x57D6, 0x57D7, 0x57DB,
+ 0x57DC, 0x57DE, 0x57E1, 0x57E2, 0x57E3, 0x57E5, 0x57E6, 0x57E7,
+ 0x57E8, 0x57E9, 0x57EA, 0x57EB, 0x57EC, 0x57EE, 0x57F0, 0x57F1,
+ 0x57F2, 0x57F3, 0x57F5, 0x57F6, 0x57F7, 0x57FB, 0x57FC, 0x57FE,
+ 0x57FF, 0x5801, 0x5803, 0x5804, 0x5805, 0x5808, 0x5809, 0x580A,
+ 0x580C, 0x580E, 0x580F, 0x5810, 0x5812, 0x5813, 0x5814, 0x5816,
+ 0x5817, 0x5818, 0x581A, 0x581B, 0x581C, 0x581D, 0x581F, 0x5822,
+ 0x5823, 0x5825, 0x5826, 0x5827, 0x5828, 0x5829, 0x582B, 0x582C,
+ 0x582D, 0x582E, 0x582F, 0x5831, 0x5832, 0x5833, 0x5834, 0x5836,
+ 0x5837, 0x5838, 0x5839, 0x583A, 0x583B, 0x583C, 0x583D,
+ /* GB 0x8940..0x897E */
+ 0x583E, 0x583F, 0x5840, 0x5841, 0x5842, 0x5843, 0x5845, 0x5846,
+ 0x5847, 0x5848, 0x5849, 0x584A, 0x584B, 0x584E, 0x584F, 0x5850,
+ 0x5852, 0x5853, 0x5855, 0x5856, 0x5857, 0x5859, 0x585A, 0x585B,
+ 0x585C, 0x585D, 0x585F, 0x5860, 0x5861, 0x5862, 0x5863, 0x5864,
+ 0x5866, 0x5867, 0x5868, 0x5869, 0x586A, 0x586D, 0x586E, 0x586F,
+ 0x5870, 0x5871, 0x5872, 0x5873, 0x5874, 0x5875, 0x5876, 0x5877,
+ 0x5878, 0x5879, 0x587A, 0x587B, 0x587C, 0x587D, 0x587F, 0x5882,
+ 0x5884, 0x5886, 0x5887, 0x5888, 0x588A, 0x588B, 0x588C,
+ /* GB 0x8980..0x89FE */
+ 0x588D, 0x588E, 0x588F, 0x5890, 0x5891, 0x5894, 0x5895, 0x5896,
+ 0x5897, 0x5898, 0x589B, 0x589C, 0x589D, 0x58A0, 0x58A1, 0x58A2,
+ 0x58A3, 0x58A4, 0x58A5, 0x58A6, 0x58A7, 0x58AA, 0x58AB, 0x58AC,
+ 0x58AD, 0x58AE, 0x58AF, 0x58B0, 0x58B1, 0x58B2, 0x58B3, 0x58B4,
+ 0x58B5, 0x58B6, 0x58B7, 0x58B8, 0x58B9, 0x58BA, 0x58BB, 0x58BD,
+ 0x58BE, 0x58BF, 0x58C0, 0x58C2, 0x58C3, 0x58C4, 0x58C6, 0x58C7,
+ 0x58C8, 0x58C9, 0x58CA, 0x58CB, 0x58CC, 0x58CD, 0x58CE, 0x58CF,
+ 0x58D0, 0x58D2, 0x58D3, 0x58D4, 0x58D6, 0x58D7, 0x58D8, 0x58D9,
+ 0x58DA, 0x58DB, 0x58DC, 0x58DD, 0x58DE, 0x58DF, 0x58E0, 0x58E1,
+ 0x58E2, 0x58E3, 0x58E5, 0x58E6, 0x58E7, 0x58E8, 0x58E9, 0x58EA,
+ 0x58ED, 0x58EF, 0x58F1, 0x58F2, 0x58F4, 0x58F5, 0x58F7, 0x58F8,
+ 0x58FA, 0x58FB, 0x58FC, 0x58FD, 0x58FE, 0x58FF, 0x5900, 0x5901,
+ 0x5903, 0x5905, 0x5906, 0x5908, 0x5909, 0x590A, 0x590B, 0x590C,
+ 0x590E, 0x5910, 0x5911, 0x5912, 0x5913, 0x5917, 0x5918, 0x591B,
+ 0x591D, 0x591E, 0x5920, 0x5921, 0x5922, 0x5923, 0x5926, 0x5928,
+ 0x592C, 0x5930, 0x5932, 0x5933, 0x5935, 0x5936, 0x593B,
+ /* GB 0x8A40..0x8A7E */
+ 0x593D, 0x593E, 0x593F, 0x5940, 0x5943, 0x5945, 0x5946, 0x594A,
+ 0x594C, 0x594D, 0x5950, 0x5952, 0x5953, 0x5959, 0x595B, 0x595C,
+ 0x595D, 0x595E, 0x595F, 0x5961, 0x5963, 0x5964, 0x5966, 0x5967,
+ 0x5968, 0x5969, 0x596A, 0x596B, 0x596C, 0x596D, 0x596E, 0x596F,
+ 0x5970, 0x5971, 0x5972, 0x5975, 0x5977, 0x597A, 0x597B, 0x597C,
+ 0x597E, 0x597F, 0x5980, 0x5985, 0x5989, 0x598B, 0x598C, 0x598E,
+ 0x598F, 0x5990, 0x5991, 0x5994, 0x5995, 0x5998, 0x599A, 0x599B,
+ 0x599C, 0x599D, 0x599F, 0x59A0, 0x59A1, 0x59A2, 0x59A6,
+ /* GB 0x8A80..0x8AFE */
+ 0x59A7, 0x59AC, 0x59AD, 0x59B0, 0x59B1, 0x59B3, 0x59B4, 0x59B5,
+ 0x59B6, 0x59B7, 0x59B8, 0x59BA, 0x59BC, 0x59BD, 0x59BF, 0x59C0,
+ 0x59C1, 0x59C2, 0x59C3, 0x59C4, 0x59C5, 0x59C7, 0x59C8, 0x59C9,
+ 0x59CC, 0x59CD, 0x59CE, 0x59CF, 0x59D5, 0x59D6, 0x59D9, 0x59DB,
+ 0x59DE, 0x59DF, 0x59E0, 0x59E1, 0x59E2, 0x59E4, 0x59E6, 0x59E7,
+ 0x59E9, 0x59EA, 0x59EB, 0x59ED, 0x59EE, 0x59EF, 0x59F0, 0x59F1,
+ 0x59F2, 0x59F3, 0x59F4, 0x59F5, 0x59F6, 0x59F7, 0x59F8, 0x59FA,
+ 0x59FC, 0x59FD, 0x59FE, 0x5A00, 0x5A02, 0x5A0A, 0x5A0B, 0x5A0D,
+ 0x5A0E, 0x5A0F, 0x5A10, 0x5A12, 0x5A14, 0x5A15, 0x5A16, 0x5A17,
+ 0x5A19, 0x5A1A, 0x5A1B, 0x5A1D, 0x5A1E, 0x5A21, 0x5A22, 0x5A24,
+ 0x5A26, 0x5A27, 0x5A28, 0x5A2A, 0x5A2B, 0x5A2C, 0x5A2D, 0x5A2E,
+ 0x5A2F, 0x5A30, 0x5A33, 0x5A35, 0x5A37, 0x5A38, 0x5A39, 0x5A3A,
+ 0x5A3B, 0x5A3D, 0x5A3E, 0x5A3F, 0x5A41, 0x5A42, 0x5A43, 0x5A44,
+ 0x5A45, 0x5A47, 0x5A48, 0x5A4B, 0x5A4C, 0x5A4D, 0x5A4E, 0x5A4F,
+ 0x5A50, 0x5A51, 0x5A52, 0x5A53, 0x5A54, 0x5A56, 0x5A57, 0x5A58,
+ 0x5A59, 0x5A5B, 0x5A5C, 0x5A5D, 0x5A5E, 0x5A5F, 0x5A60,
+ /* GB 0x8B40..0x8B7E */
+ 0x5A61, 0x5A63, 0x5A64, 0x5A65, 0x5A66, 0x5A68, 0x5A69, 0x5A6B,
+ 0x5A6C, 0x5A6D, 0x5A6E, 0x5A6F, 0x5A70, 0x5A71, 0x5A72, 0x5A73,
+ 0x5A78, 0x5A79, 0x5A7B, 0x5A7C, 0x5A7D, 0x5A7E, 0x5A80, 0x5A81,
+ 0x5A82, 0x5A83, 0x5A84, 0x5A85, 0x5A86, 0x5A87, 0x5A88, 0x5A89,
+ 0x5A8A, 0x5A8B, 0x5A8C, 0x5A8D, 0x5A8E, 0x5A8F, 0x5A90, 0x5A91,
+ 0x5A93, 0x5A94, 0x5A95, 0x5A96, 0x5A97, 0x5A98, 0x5A99, 0x5A9C,
+ 0x5A9D, 0x5A9E, 0x5A9F, 0x5AA0, 0x5AA1, 0x5AA2, 0x5AA3, 0x5AA4,
+ 0x5AA5, 0x5AA6, 0x5AA7, 0x5AA8, 0x5AA9, 0x5AAB, 0x5AAC,
+ /* GB 0x8B80..0x8BFE */
+ 0x5AAD, 0x5AAE, 0x5AAF, 0x5AB0, 0x5AB1, 0x5AB4, 0x5AB6, 0x5AB7,
+ 0x5AB9, 0x5ABA, 0x5ABB, 0x5ABC, 0x5ABD, 0x5ABF, 0x5AC0, 0x5AC3,
+ 0x5AC4, 0x5AC5, 0x5AC6, 0x5AC7, 0x5AC8, 0x5ACA, 0x5ACB, 0x5ACD,
+ 0x5ACE, 0x5ACF, 0x5AD0, 0x5AD1, 0x5AD3, 0x5AD5, 0x5AD7, 0x5AD9,
+ 0x5ADA, 0x5ADB, 0x5ADD, 0x5ADE, 0x5ADF, 0x5AE2, 0x5AE4, 0x5AE5,
+ 0x5AE7, 0x5AE8, 0x5AEA, 0x5AEC, 0x5AED, 0x5AEE, 0x5AEF, 0x5AF0,
+ 0x5AF2, 0x5AF3, 0x5AF4, 0x5AF5, 0x5AF6, 0x5AF7, 0x5AF8, 0x5AF9,
+ 0x5AFA, 0x5AFB, 0x5AFC, 0x5AFD, 0x5AFE, 0x5AFF, 0x5B00, 0x5B01,
+ 0x5B02, 0x5B03, 0x5B04, 0x5B05, 0x5B06, 0x5B07, 0x5B08, 0x5B0A,
+ 0x5B0B, 0x5B0C, 0x5B0D, 0x5B0E, 0x5B0F, 0x5B10, 0x5B11, 0x5B12,
+ 0x5B13, 0x5B14, 0x5B15, 0x5B18, 0x5B19, 0x5B1A, 0x5B1B, 0x5B1C,
+ 0x5B1D, 0x5B1E, 0x5B1F, 0x5B20, 0x5B21, 0x5B22, 0x5B23, 0x5B24,
+ 0x5B25, 0x5B26, 0x5B27, 0x5B28, 0x5B29, 0x5B2A, 0x5B2B, 0x5B2C,
+ 0x5B2D, 0x5B2E, 0x5B2F, 0x5B30, 0x5B31, 0x5B33, 0x5B35, 0x5B36,
+ 0x5B38, 0x5B39, 0x5B3A, 0x5B3B, 0x5B3C, 0x5B3D, 0x5B3E, 0x5B3F,
+ 0x5B41, 0x5B42, 0x5B43, 0x5B44, 0x5B45, 0x5B46, 0x5B47,
+ /* GB 0x8C40..0x8C7E */
+ 0x5B48, 0x5B49, 0x5B4A, 0x5B4B, 0x5B4C, 0x5B4D, 0x5B4E, 0x5B4F,
+ 0x5B52, 0x5B56, 0x5B5E, 0x5B60, 0x5B61, 0x5B67, 0x5B68, 0x5B6B,
+ 0x5B6D, 0x5B6E, 0x5B6F, 0x5B72, 0x5B74, 0x5B76, 0x5B77, 0x5B78,
+ 0x5B79, 0x5B7B, 0x5B7C, 0x5B7E, 0x5B7F, 0x5B82, 0x5B86, 0x5B8A,
+ 0x5B8D, 0x5B8E, 0x5B90, 0x5B91, 0x5B92, 0x5B94, 0x5B96, 0x5B9F,
+ 0x5BA7, 0x5BA8, 0x5BA9, 0x5BAC, 0x5BAD, 0x5BAE, 0x5BAF, 0x5BB1,
+ 0x5BB2, 0x5BB7, 0x5BBA, 0x5BBB, 0x5BBC, 0x5BC0, 0x5BC1, 0x5BC3,
+ 0x5BC8, 0x5BC9, 0x5BCA, 0x5BCB, 0x5BCD, 0x5BCE, 0x5BCF,
+ /* GB 0x8C80..0x8CFE */
+ 0x5BD1, 0x5BD4, 0x5BD5, 0x5BD6, 0x5BD7, 0x5BD8, 0x5BD9, 0x5BDA,
+ 0x5BDB, 0x5BDC, 0x5BE0, 0x5BE2, 0x5BE3, 0x5BE6, 0x5BE7, 0x5BE9,
+ 0x5BEA, 0x5BEB, 0x5BEC, 0x5BED, 0x5BEF, 0x5BF1, 0x5BF2, 0x5BF3,
+ 0x5BF4, 0x5BF5, 0x5BF6, 0x5BF7, 0x5BFD, 0x5BFE, 0x5C00, 0x5C02,
+ 0x5C03, 0x5C05, 0x5C07, 0x5C08, 0x5C0B, 0x5C0C, 0x5C0D, 0x5C0E,
+ 0x5C10, 0x5C12, 0x5C13, 0x5C17, 0x5C19, 0x5C1B, 0x5C1E, 0x5C1F,
+ 0x5C20, 0x5C21, 0x5C23, 0x5C26, 0x5C28, 0x5C29, 0x5C2A, 0x5C2B,
+ 0x5C2D, 0x5C2E, 0x5C2F, 0x5C30, 0x5C32, 0x5C33, 0x5C35, 0x5C36,
+ 0x5C37, 0x5C43, 0x5C44, 0x5C46, 0x5C47, 0x5C4C, 0x5C4D, 0x5C52,
+ 0x5C53, 0x5C54, 0x5C56, 0x5C57, 0x5C58, 0x5C5A, 0x5C5B, 0x5C5C,
+ 0x5C5D, 0x5C5F, 0x5C62, 0x5C64, 0x5C67, 0x5C68, 0x5C69, 0x5C6A,
+ 0x5C6B, 0x5C6C, 0x5C6D, 0x5C70, 0x5C72, 0x5C73, 0x5C74, 0x5C75,
+ 0x5C76, 0x5C77, 0x5C78, 0x5C7B, 0x5C7C, 0x5C7D, 0x5C7E, 0x5C80,
+ 0x5C83, 0x5C84, 0x5C85, 0x5C86, 0x5C87, 0x5C89, 0x5C8A, 0x5C8B,
+ 0x5C8E, 0x5C8F, 0x5C92, 0x5C93, 0x5C95, 0x5C9D, 0x5C9E, 0x5C9F,
+ 0x5CA0, 0x5CA1, 0x5CA4, 0x5CA5, 0x5CA6, 0x5CA7, 0x5CA8,
+ /* GB 0x8D40..0x8D7E */
+ 0x5CAA, 0x5CAE, 0x5CAF, 0x5CB0, 0x5CB2, 0x5CB4, 0x5CB6, 0x5CB9,
+ 0x5CBA, 0x5CBB, 0x5CBC, 0x5CBE, 0x5CC0, 0x5CC2, 0x5CC3, 0x5CC5,
+ 0x5CC6, 0x5CC7, 0x5CC8, 0x5CC9, 0x5CCA, 0x5CCC, 0x5CCD, 0x5CCE,
+ 0x5CCF, 0x5CD0, 0x5CD1, 0x5CD3, 0x5CD4, 0x5CD5, 0x5CD6, 0x5CD7,
+ 0x5CD8, 0x5CDA, 0x5CDB, 0x5CDC, 0x5CDD, 0x5CDE, 0x5CDF, 0x5CE0,
+ 0x5CE2, 0x5CE3, 0x5CE7, 0x5CE9, 0x5CEB, 0x5CEC, 0x5CEE, 0x5CEF,
+ 0x5CF1, 0x5CF2, 0x5CF3, 0x5CF4, 0x5CF5, 0x5CF6, 0x5CF7, 0x5CF8,
+ 0x5CF9, 0x5CFA, 0x5CFC, 0x5CFD, 0x5CFE, 0x5CFF, 0x5D00,
+ /* GB 0x8D80..0x8DFE */
+ 0x5D01, 0x5D04, 0x5D05, 0x5D08, 0x5D09, 0x5D0A, 0x5D0B, 0x5D0C,
+ 0x5D0D, 0x5D0F, 0x5D10, 0x5D11, 0x5D12, 0x5D13, 0x5D15, 0x5D17,
+ 0x5D18, 0x5D19, 0x5D1A, 0x5D1C, 0x5D1D, 0x5D1F, 0x5D20, 0x5D21,
+ 0x5D22, 0x5D23, 0x5D25, 0x5D28, 0x5D2A, 0x5D2B, 0x5D2C, 0x5D2F,
+ 0x5D30, 0x5D31, 0x5D32, 0x5D33, 0x5D35, 0x5D36, 0x5D37, 0x5D38,
+ 0x5D39, 0x5D3A, 0x5D3B, 0x5D3C, 0x5D3F, 0x5D40, 0x5D41, 0x5D42,
+ 0x5D43, 0x5D44, 0x5D45, 0x5D46, 0x5D48, 0x5D49, 0x5D4D, 0x5D4E,
+ 0x5D4F, 0x5D50, 0x5D51, 0x5D52, 0x5D53, 0x5D54, 0x5D55, 0x5D56,
+ 0x5D57, 0x5D59, 0x5D5A, 0x5D5C, 0x5D5E, 0x5D5F, 0x5D60, 0x5D61,
+ 0x5D62, 0x5D63, 0x5D64, 0x5D65, 0x5D66, 0x5D67, 0x5D68, 0x5D6A,
+ 0x5D6D, 0x5D6E, 0x5D70, 0x5D71, 0x5D72, 0x5D73, 0x5D75, 0x5D76,
+ 0x5D77, 0x5D78, 0x5D79, 0x5D7A, 0x5D7B, 0x5D7C, 0x5D7D, 0x5D7E,
+ 0x5D7F, 0x5D80, 0x5D81, 0x5D83, 0x5D84, 0x5D85, 0x5D86, 0x5D87,
+ 0x5D88, 0x5D89, 0x5D8A, 0x5D8B, 0x5D8C, 0x5D8D, 0x5D8E, 0x5D8F,
+ 0x5D90, 0x5D91, 0x5D92, 0x5D93, 0x5D94, 0x5D95, 0x5D96, 0x5D97,
+ 0x5D98, 0x5D9A, 0x5D9B, 0x5D9C, 0x5D9E, 0x5D9F, 0x5DA0,
+ /* GB 0x8E40..0x8E7E */
+ 0x5DA1, 0x5DA2, 0x5DA3, 0x5DA4, 0x5DA5, 0x5DA6, 0x5DA7, 0x5DA8,
+ 0x5DA9, 0x5DAA, 0x5DAB, 0x5DAC, 0x5DAD, 0x5DAE, 0x5DAF, 0x5DB0,
+ 0x5DB1, 0x5DB2, 0x5DB3, 0x5DB4, 0x5DB5, 0x5DB6, 0x5DB8, 0x5DB9,
+ 0x5DBA, 0x5DBB, 0x5DBC, 0x5DBD, 0x5DBE, 0x5DBF, 0x5DC0, 0x5DC1,
+ 0x5DC2, 0x5DC3, 0x5DC4, 0x5DC6, 0x5DC7, 0x5DC8, 0x5DC9, 0x5DCA,
+ 0x5DCB, 0x5DCC, 0x5DCE, 0x5DCF, 0x5DD0, 0x5DD1, 0x5DD2, 0x5DD3,
+ 0x5DD4, 0x5DD5, 0x5DD6, 0x5DD7, 0x5DD8, 0x5DD9, 0x5DDA, 0x5DDC,
+ 0x5DDF, 0x5DE0, 0x5DE3, 0x5DE4, 0x5DEA, 0x5DEC, 0x5DED,
+ /* GB 0x8E80..0x8EFE */
+ 0x5DF0, 0x5DF5, 0x5DF6, 0x5DF8, 0x5DF9, 0x5DFA, 0x5DFB, 0x5DFC,
+ 0x5DFF, 0x5E00, 0x5E04, 0x5E07, 0x5E09, 0x5E0A, 0x5E0B, 0x5E0D,
+ 0x5E0E, 0x5E12, 0x5E13, 0x5E17, 0x5E1E, 0x5E1F, 0x5E20, 0x5E21,
+ 0x5E22, 0x5E23, 0x5E24, 0x5E25, 0x5E28, 0x5E29, 0x5E2A, 0x5E2B,
+ 0x5E2C, 0x5E2F, 0x5E30, 0x5E32, 0x5E33, 0x5E34, 0x5E35, 0x5E36,
+ 0x5E39, 0x5E3A, 0x5E3E, 0x5E3F, 0x5E40, 0x5E41, 0x5E43, 0x5E46,
+ 0x5E47, 0x5E48, 0x5E49, 0x5E4A, 0x5E4B, 0x5E4D, 0x5E4E, 0x5E4F,
+ 0x5E50, 0x5E51, 0x5E52, 0x5E53, 0x5E56, 0x5E57, 0x5E58, 0x5E59,
+ 0x5E5A, 0x5E5C, 0x5E5D, 0x5E5F, 0x5E60, 0x5E63, 0x5E64, 0x5E65,
+ 0x5E66, 0x5E67, 0x5E68, 0x5E69, 0x5E6A, 0x5E6B, 0x5E6C, 0x5E6D,
+ 0x5E6E, 0x5E6F, 0x5E70, 0x5E71, 0x5E75, 0x5E77, 0x5E79, 0x5E7E,
+ 0x5E81, 0x5E82, 0x5E83, 0x5E85, 0x5E88, 0x5E89, 0x5E8C, 0x5E8D,
+ 0x5E8E, 0x5E92, 0x5E98, 0x5E9B, 0x5E9D, 0x5EA1, 0x5EA2, 0x5EA3,
+ 0x5EA4, 0x5EA8, 0x5EA9, 0x5EAA, 0x5EAB, 0x5EAC, 0x5EAE, 0x5EAF,
+ 0x5EB0, 0x5EB1, 0x5EB2, 0x5EB4, 0x5EBA, 0x5EBB, 0x5EBC, 0x5EBD,
+ 0x5EBF, 0x5EC0, 0x5EC1, 0x5EC2, 0x5EC3, 0x5EC4, 0x5EC5,
+ /* GB 0x8F40..0x8F7E */
+ 0x5EC6, 0x5EC7, 0x5EC8, 0x5ECB, 0x5ECC, 0x5ECD, 0x5ECE, 0x5ECF,
+ 0x5ED0, 0x5ED4, 0x5ED5, 0x5ED7, 0x5ED8, 0x5ED9, 0x5EDA, 0x5EDC,
+ 0x5EDD, 0x5EDE, 0x5EDF, 0x5EE0, 0x5EE1, 0x5EE2, 0x5EE3, 0x5EE4,
+ 0x5EE5, 0x5EE6, 0x5EE7, 0x5EE9, 0x5EEB, 0x5EEC, 0x5EED, 0x5EEE,
+ 0x5EEF, 0x5EF0, 0x5EF1, 0x5EF2, 0x5EF3, 0x5EF5, 0x5EF8, 0x5EF9,
+ 0x5EFB, 0x5EFC, 0x5EFD, 0x5F05, 0x5F06, 0x5F07, 0x5F09, 0x5F0C,
+ 0x5F0D, 0x5F0E, 0x5F10, 0x5F12, 0x5F14, 0x5F16, 0x5F19, 0x5F1A,
+ 0x5F1C, 0x5F1D, 0x5F1E, 0x5F21, 0x5F22, 0x5F23, 0x5F24,
+ /* GB 0x8F80..0x8FFE */
+ 0x5F28, 0x5F2B, 0x5F2C, 0x5F2E, 0x5F30, 0x5F32, 0x5F33, 0x5F34,
+ 0x5F35, 0x5F36, 0x5F37, 0x5F38, 0x5F3B, 0x5F3D, 0x5F3E, 0x5F3F,
+ 0x5F41, 0x5F42, 0x5F43, 0x5F44, 0x5F45, 0x5F46, 0x5F47, 0x5F48,
+ 0x5F49, 0x5F4A, 0x5F4B, 0x5F4C, 0x5F4D, 0x5F4E, 0x5F4F, 0x5F51,
+ 0x5F54, 0x5F59, 0x5F5A, 0x5F5B, 0x5F5C, 0x5F5E, 0x5F5F, 0x5F60,
+ 0x5F63, 0x5F65, 0x5F67, 0x5F68, 0x5F6B, 0x5F6E, 0x5F6F, 0x5F72,
+ 0x5F74, 0x5F75, 0x5F76, 0x5F78, 0x5F7A, 0x5F7D, 0x5F7E, 0x5F7F,
+ 0x5F83, 0x5F86, 0x5F8D, 0x5F8E, 0x5F8F, 0x5F91, 0x5F93, 0x5F94,
+ 0x5F96, 0x5F9A, 0x5F9B, 0x5F9D, 0x5F9E, 0x5F9F, 0x5FA0, 0x5FA2,
+ 0x5FA3, 0x5FA4, 0x5FA5, 0x5FA6, 0x5FA7, 0x5FA9, 0x5FAB, 0x5FAC,
+ 0x5FAF, 0x5FB0, 0x5FB1, 0x5FB2, 0x5FB3, 0x5FB4, 0x5FB6, 0x5FB8,
+ 0x5FB9, 0x5FBA, 0x5FBB, 0x5FBE, 0x5FBF, 0x5FC0, 0x5FC1, 0x5FC2,
+ 0x5FC7, 0x5FC8, 0x5FCA, 0x5FCB, 0x5FCE, 0x5FD3, 0x5FD4, 0x5FD5,
+ 0x5FDA, 0x5FDB, 0x5FDC, 0x5FDE, 0x5FDF, 0x5FE2, 0x5FE3, 0x5FE5,
+ 0x5FE6, 0x5FE8, 0x5FE9, 0x5FEC, 0x5FEF, 0x5FF0, 0x5FF2, 0x5FF3,
+ 0x5FF4, 0x5FF6, 0x5FF7, 0x5FF9, 0x5FFA, 0x5FFC, 0x6007,
+ /* GB 0x9040..0x907E */
+ 0x6008, 0x6009, 0x600B, 0x600C, 0x6010, 0x6011, 0x6013, 0x6017,
+ 0x6018, 0x601A, 0x601E, 0x601F, 0x6022, 0x6023, 0x6024, 0x602C,
+ 0x602D, 0x602E, 0x6030, 0x6031, 0x6032, 0x6033, 0x6034, 0x6036,
+ 0x6037, 0x6038, 0x6039, 0x603A, 0x603D, 0x603E, 0x6040, 0x6044,
+ 0x6045, 0x6046, 0x6047, 0x6048, 0x6049, 0x604A, 0x604C, 0x604E,
+ 0x604F, 0x6051, 0x6053, 0x6054, 0x6056, 0x6057, 0x6058, 0x605B,
+ 0x605C, 0x605E, 0x605F, 0x6060, 0x6061, 0x6065, 0x6066, 0x606E,
+ 0x6071, 0x6072, 0x6074, 0x6075, 0x6077, 0x607E, 0x6080,
+ /* GB 0x9080..0x90FE */
+ 0x6081, 0x6082, 0x6085, 0x6086, 0x6087, 0x6088, 0x608A, 0x608B,
+ 0x608E, 0x608F, 0x6090, 0x6091, 0x6093, 0x6095, 0x6097, 0x6098,
+ 0x6099, 0x609C, 0x609E, 0x60A1, 0x60A2, 0x60A4, 0x60A5, 0x60A7,
+ 0x60A9, 0x60AA, 0x60AE, 0x60B0, 0x60B3, 0x60B5, 0x60B6, 0x60B7,
+ 0x60B9, 0x60BA, 0x60BD, 0x60BE, 0x60BF, 0x60C0, 0x60C1, 0x60C2,
+ 0x60C3, 0x60C4, 0x60C7, 0x60C8, 0x60C9, 0x60CC, 0x60CD, 0x60CE,
+ 0x60CF, 0x60D0, 0x60D2, 0x60D3, 0x60D4, 0x60D6, 0x60D7, 0x60D9,
+ 0x60DB, 0x60DE, 0x60E1, 0x60E2, 0x60E3, 0x60E4, 0x60E5, 0x60EA,
+ 0x60F1, 0x60F2, 0x60F5, 0x60F7, 0x60F8, 0x60FB, 0x60FC, 0x60FD,
+ 0x60FE, 0x60FF, 0x6102, 0x6103, 0x6104, 0x6105, 0x6107, 0x610A,
+ 0x610B, 0x610C, 0x6110, 0x6111, 0x6112, 0x6113, 0x6114, 0x6116,
+ 0x6117, 0x6118, 0x6119, 0x611B, 0x611C, 0x611D, 0x611E, 0x6121,
+ 0x6122, 0x6125, 0x6128, 0x6129, 0x612A, 0x612C, 0x612D, 0x612E,
+ 0x612F, 0x6130, 0x6131, 0x6132, 0x6133, 0x6134, 0x6135, 0x6136,
+ 0x6137, 0x6138, 0x6139, 0x613A, 0x613B, 0x613C, 0x613D, 0x613E,
+ 0x6140, 0x6141, 0x6142, 0x6143, 0x6144, 0x6145, 0x6146,
+ /* GB 0x9140..0x917E */
+ 0x6147, 0x6149, 0x614B, 0x614D, 0x614F, 0x6150, 0x6152, 0x6153,
+ 0x6154, 0x6156, 0x6157, 0x6158, 0x6159, 0x615A, 0x615B, 0x615C,
+ 0x615E, 0x615F, 0x6160, 0x6161, 0x6163, 0x6164, 0x6165, 0x6166,
+ 0x6169, 0x616A, 0x616B, 0x616C, 0x616D, 0x616E, 0x616F, 0x6171,
+ 0x6172, 0x6173, 0x6174, 0x6176, 0x6178, 0x6179, 0x617A, 0x617B,
+ 0x617C, 0x617D, 0x617E, 0x617F, 0x6180, 0x6181, 0x6182, 0x6183,
+ 0x6184, 0x6185, 0x6186, 0x6187, 0x6188, 0x6189, 0x618A, 0x618C,
+ 0x618D, 0x618F, 0x6190, 0x6191, 0x6192, 0x6193, 0x6195,
+ /* GB 0x9180..0x91FE */
+ 0x6196, 0x6197, 0x6198, 0x6199, 0x619A, 0x619B, 0x619C, 0x619E,
+ 0x619F, 0x61A0, 0x61A1, 0x61A2, 0x61A3, 0x61A4, 0x61A5, 0x61A6,
+ 0x61AA, 0x61AB, 0x61AD, 0x61AE, 0x61AF, 0x61B0, 0x61B1, 0x61B2,
+ 0x61B3, 0x61B4, 0x61B5, 0x61B6, 0x61B8, 0x61B9, 0x61BA, 0x61BB,
+ 0x61BC, 0x61BD, 0x61BF, 0x61C0, 0x61C1, 0x61C3, 0x61C4, 0x61C5,
+ 0x61C6, 0x61C7, 0x61C9, 0x61CC, 0x61CD, 0x61CE, 0x61CF, 0x61D0,
+ 0x61D3, 0x61D5, 0x61D6, 0x61D7, 0x61D8, 0x61D9, 0x61DA, 0x61DB,
+ 0x61DC, 0x61DD, 0x61DE, 0x61DF, 0x61E0, 0x61E1, 0x61E2, 0x61E3,
+ 0x61E4, 0x61E5, 0x61E7, 0x61E8, 0x61E9, 0x61EA, 0x61EB, 0x61EC,
+ 0x61ED, 0x61EE, 0x61EF, 0x61F0, 0x61F1, 0x61F2, 0x61F3, 0x61F4,
+ 0x61F6, 0x61F7, 0x61F8, 0x61F9, 0x61FA, 0x61FB, 0x61FC, 0x61FD,
+ 0x61FE, 0x6200, 0x6201, 0x6202, 0x6203, 0x6204, 0x6205, 0x6207,
+ 0x6209, 0x6213, 0x6214, 0x6219, 0x621C, 0x621D, 0x621E, 0x6220,
+ 0x6223, 0x6226, 0x6227, 0x6228, 0x6229, 0x622B, 0x622D, 0x622F,
+ 0x6230, 0x6231, 0x6232, 0x6235, 0x6236, 0x6238, 0x6239, 0x623A,
+ 0x623B, 0x623C, 0x6242, 0x6244, 0x6245, 0x6246, 0x624A,
+ /* GB 0x9240..0x927E */
+ 0x624F, 0x6250, 0x6255, 0x6256, 0x6257, 0x6259, 0x625A, 0x625C,
+ 0x625D, 0x625E, 0x625F, 0x6260, 0x6261, 0x6262, 0x6264, 0x6265,
+ 0x6268, 0x6271, 0x6272, 0x6274, 0x6275, 0x6277, 0x6278, 0x627A,
+ 0x627B, 0x627D, 0x6281, 0x6282, 0x6283, 0x6285, 0x6286, 0x6287,
+ 0x6288, 0x628B, 0x628C, 0x628D, 0x628E, 0x628F, 0x6290, 0x6294,
+ 0x6299, 0x629C, 0x629D, 0x629E, 0x62A3, 0x62A6, 0x62A7, 0x62A9,
+ 0x62AA, 0x62AD, 0x62AE, 0x62AF, 0x62B0, 0x62B2, 0x62B3, 0x62B4,
+ 0x62B6, 0x62B7, 0x62B8, 0x62BA, 0x62BE, 0x62C0, 0x62C1,
+ /* GB 0x9280..0x92FE */
+ 0x62C3, 0x62CB, 0x62CF, 0x62D1, 0x62D5, 0x62DD, 0x62DE, 0x62E0,
+ 0x62E1, 0x62E4, 0x62EA, 0x62EB, 0x62F0, 0x62F2, 0x62F5, 0x62F8,
+ 0x62F9, 0x62FA, 0x62FB, 0x6300, 0x6303, 0x6304, 0x6305, 0x6306,
+ 0x630A, 0x630B, 0x630C, 0x630D, 0x630F, 0x6310, 0x6312, 0x6313,
+ 0x6314, 0x6315, 0x6317, 0x6318, 0x6319, 0x631C, 0x6326, 0x6327,
+ 0x6329, 0x632C, 0x632D, 0x632E, 0x6330, 0x6331, 0x6333, 0x6334,
+ 0x6335, 0x6336, 0x6337, 0x6338, 0x633B, 0x633C, 0x633E, 0x633F,
+ 0x6340, 0x6341, 0x6344, 0x6347, 0x6348, 0x634A, 0x6351, 0x6352,
+ 0x6353, 0x6354, 0x6356, 0x6357, 0x6358, 0x6359, 0x635A, 0x635B,
+ 0x635C, 0x635D, 0x6360, 0x6364, 0x6365, 0x6366, 0x6368, 0x636A,
+ 0x636B, 0x636C, 0x636F, 0x6370, 0x6372, 0x6373, 0x6374, 0x6375,
+ 0x6378, 0x6379, 0x637C, 0x637D, 0x637E, 0x637F, 0x6381, 0x6383,
+ 0x6384, 0x6385, 0x6386, 0x638B, 0x638D, 0x6391, 0x6393, 0x6394,
+ 0x6395, 0x6397, 0x6399, 0x639A, 0x639B, 0x639C, 0x639D, 0x639E,
+ 0x639F, 0x63A1, 0x63A4, 0x63A6, 0x63AB, 0x63AF, 0x63B1, 0x63B2,
+ 0x63B5, 0x63B6, 0x63B9, 0x63BB, 0x63BD, 0x63BF, 0x63C0,
+ /* GB 0x9340..0x937E */
+ 0x63C1, 0x63C2, 0x63C3, 0x63C5, 0x63C7, 0x63C8, 0x63CA, 0x63CB,
+ 0x63CC, 0x63D1, 0x63D3, 0x63D4, 0x63D5, 0x63D7, 0x63D8, 0x63D9,
+ 0x63DA, 0x63DB, 0x63DC, 0x63DD, 0x63DF, 0x63E2, 0x63E4, 0x63E5,
+ 0x63E6, 0x63E7, 0x63E8, 0x63EB, 0x63EC, 0x63EE, 0x63EF, 0x63F0,
+ 0x63F1, 0x63F3, 0x63F5, 0x63F7, 0x63F9, 0x63FA, 0x63FB, 0x63FC,
+ 0x63FE, 0x6403, 0x6404, 0x6406, 0x6407, 0x6408, 0x6409, 0x640A,
+ 0x640D, 0x640E, 0x6411, 0x6412, 0x6415, 0x6416, 0x6417, 0x6418,
+ 0x6419, 0x641A, 0x641D, 0x641F, 0x6422, 0x6423, 0x6424,
+ /* GB 0x9380..0x93FE */
+ 0x6425, 0x6427, 0x6428, 0x6429, 0x642B, 0x642E, 0x642F, 0x6430,
+ 0x6431, 0x6432, 0x6433, 0x6435, 0x6436, 0x6437, 0x6438, 0x6439,
+ 0x643B, 0x643C, 0x643E, 0x6440, 0x6442, 0x6443, 0x6449, 0x644B,
+ 0x644C, 0x644D, 0x644E, 0x644F, 0x6450, 0x6451, 0x6453, 0x6455,
+ 0x6456, 0x6457, 0x6459, 0x645A, 0x645B, 0x645C, 0x645D, 0x645F,
+ 0x6460, 0x6461, 0x6462, 0x6463, 0x6464, 0x6465, 0x6466, 0x6468,
+ 0x646A, 0x646B, 0x646C, 0x646E, 0x646F, 0x6470, 0x6471, 0x6472,
+ 0x6473, 0x6474, 0x6475, 0x6476, 0x6477, 0x647B, 0x647C, 0x647D,
+ 0x647E, 0x647F, 0x6480, 0x6481, 0x6483, 0x6486, 0x6488, 0x6489,
+ 0x648A, 0x648B, 0x648C, 0x648D, 0x648E, 0x648F, 0x6490, 0x6493,
+ 0x6494, 0x6497, 0x6498, 0x649A, 0x649B, 0x649C, 0x649D, 0x649F,
+ 0x64A0, 0x64A1, 0x64A2, 0x64A3, 0x64A5, 0x64A6, 0x64A7, 0x64A8,
+ 0x64AA, 0x64AB, 0x64AF, 0x64B1, 0x64B2, 0x64B3, 0x64B4, 0x64B6,
+ 0x64B9, 0x64BB, 0x64BD, 0x64BE, 0x64BF, 0x64C1, 0x64C3, 0x64C4,
+ 0x64C6, 0x64C7, 0x64C8, 0x64C9, 0x64CA, 0x64CB, 0x64CC, 0x64CF,
+ 0x64D1, 0x64D3, 0x64D4, 0x64D5, 0x64D6, 0x64D9, 0x64DA,
+ /* GB 0x9440..0x947E */
+ 0x64DB, 0x64DC, 0x64DD, 0x64DF, 0x64E0, 0x64E1, 0x64E3, 0x64E5,
+ 0x64E7, 0x64E8, 0x64E9, 0x64EA, 0x64EB, 0x64EC, 0x64ED, 0x64EE,
+ 0x64EF, 0x64F0, 0x64F1, 0x64F2, 0x64F3, 0x64F4, 0x64F5, 0x64F6,
+ 0x64F7, 0x64F8, 0x64F9, 0x64FA, 0x64FB, 0x64FC, 0x64FD, 0x64FE,
+ 0x64FF, 0x6501, 0x6502, 0x6503, 0x6504, 0x6505, 0x6506, 0x6507,
+ 0x6508, 0x650A, 0x650B, 0x650C, 0x650D, 0x650E, 0x650F, 0x6510,
+ 0x6511, 0x6513, 0x6514, 0x6515, 0x6516, 0x6517, 0x6519, 0x651A,
+ 0x651B, 0x651C, 0x651D, 0x651E, 0x651F, 0x6520, 0x6521,
+ /* GB 0x9480..0x94FE */
+ 0x6522, 0x6523, 0x6524, 0x6526, 0x6527, 0x6528, 0x6529, 0x652A,
+ 0x652C, 0x652D, 0x6530, 0x6531, 0x6532, 0x6533, 0x6537, 0x653A,
+ 0x653C, 0x653D, 0x6540, 0x6541, 0x6542, 0x6543, 0x6544, 0x6546,
+ 0x6547, 0x654A, 0x654B, 0x654D, 0x654E, 0x6550, 0x6552, 0x6553,
+ 0x6554, 0x6557, 0x6558, 0x655A, 0x655C, 0x655F, 0x6560, 0x6561,
+ 0x6564, 0x6565, 0x6567, 0x6568, 0x6569, 0x656A, 0x656D, 0x656E,
+ 0x656F, 0x6571, 0x6573, 0x6575, 0x6576, 0x6578, 0x6579, 0x657A,
+ 0x657B, 0x657C, 0x657D, 0x657E, 0x657F, 0x6580, 0x6581, 0x6582,
+ 0x6583, 0x6584, 0x6585, 0x6586, 0x6588, 0x6589, 0x658A, 0x658D,
+ 0x658E, 0x658F, 0x6592, 0x6594, 0x6595, 0x6596, 0x6598, 0x659A,
+ 0x659D, 0x659E, 0x65A0, 0x65A2, 0x65A3, 0x65A6, 0x65A8, 0x65AA,
+ 0x65AC, 0x65AE, 0x65B1, 0x65B2, 0x65B3, 0x65B4, 0x65B5, 0x65B6,
+ 0x65B7, 0x65B8, 0x65BA, 0x65BB, 0x65BE, 0x65BF, 0x65C0, 0x65C2,
+ 0x65C7, 0x65C8, 0x65C9, 0x65CA, 0x65CD, 0x65D0, 0x65D1, 0x65D3,
+ 0x65D4, 0x65D5, 0x65D8, 0x65D9, 0x65DA, 0x65DB, 0x65DC, 0x65DD,
+ 0x65DE, 0x65DF, 0x65E1, 0x65E3, 0x65E4, 0x65EA, 0x65EB,
+ /* GB 0x9540..0x957E */
+ 0x65F2, 0x65F3, 0x65F4, 0x65F5, 0x65F8, 0x65F9, 0x65FB, 0x65FC,
+ 0x65FD, 0x65FE, 0x65FF, 0x6601, 0x6604, 0x6605, 0x6607, 0x6608,
+ 0x6609, 0x660B, 0x660D, 0x6610, 0x6611, 0x6612, 0x6616, 0x6617,
+ 0x6618, 0x661A, 0x661B, 0x661C, 0x661E, 0x6621, 0x6622, 0x6623,
+ 0x6624, 0x6626, 0x6629, 0x662A, 0x662B, 0x662C, 0x662E, 0x6630,
+ 0x6632, 0x6633, 0x6637, 0x6638, 0x6639, 0x663A, 0x663B, 0x663D,
+ 0x663F, 0x6640, 0x6642, 0x6644, 0x6645, 0x6646, 0x6647, 0x6648,
+ 0x6649, 0x664A, 0x664D, 0x664E, 0x6650, 0x6651, 0x6658,
+ /* GB 0x9580..0x95FE */
+ 0x6659, 0x665B, 0x665C, 0x665D, 0x665E, 0x6660, 0x6662, 0x6663,
+ 0x6665, 0x6667, 0x6669, 0x666A, 0x666B, 0x666C, 0x666D, 0x6671,
+ 0x6672, 0x6673, 0x6675, 0x6678, 0x6679, 0x667B, 0x667C, 0x667D,
+ 0x667F, 0x6680, 0x6681, 0x6683, 0x6685, 0x6686, 0x6688, 0x6689,
+ 0x668A, 0x668B, 0x668D, 0x668E, 0x668F, 0x6690, 0x6692, 0x6693,
+ 0x6694, 0x6695, 0x6698, 0x6699, 0x669A, 0x669B, 0x669C, 0x669E,
+ 0x669F, 0x66A0, 0x66A1, 0x66A2, 0x66A3, 0x66A4, 0x66A5, 0x66A6,
+ 0x66A9, 0x66AA, 0x66AB, 0x66AC, 0x66AD, 0x66AF, 0x66B0, 0x66B1,
+ 0x66B2, 0x66B3, 0x66B5, 0x66B6, 0x66B7, 0x66B8, 0x66BA, 0x66BB,
+ 0x66BC, 0x66BD, 0x66BF, 0x66C0, 0x66C1, 0x66C2, 0x66C3, 0x66C4,
+ 0x66C5, 0x66C6, 0x66C7, 0x66C8, 0x66C9, 0x66CA, 0x66CB, 0x66CC,
+ 0x66CD, 0x66CE, 0x66CF, 0x66D0, 0x66D1, 0x66D2, 0x66D3, 0x66D4,
+ 0x66D5, 0x66D6, 0x66D7, 0x66D8, 0x66DA, 0x66DE, 0x66DF, 0x66E0,
+ 0x66E1, 0x66E2, 0x66E3, 0x66E4, 0x66E5, 0x66E7, 0x66E8, 0x66EA,
+ 0x66EB, 0x66EC, 0x66ED, 0x66EE, 0x66EF, 0x66F1, 0x66F5, 0x66F6,
+ 0x66F8, 0x66FA, 0x66FB, 0x66FD, 0x6701, 0x6702, 0x6703,
+ /* GB 0x9640..0x967E */
+ 0x6704, 0x6705, 0x6706, 0x6707, 0x670C, 0x670E, 0x670F, 0x6711,
+ 0x6712, 0x6713, 0x6716, 0x6718, 0x6719, 0x671A, 0x671C, 0x671E,
+ 0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6727, 0x6729,
+ 0x672E, 0x6730, 0x6732, 0x6733, 0x6736, 0x6737, 0x6738, 0x6739,
+ 0x673B, 0x673C, 0x673E, 0x673F, 0x6741, 0x6744, 0x6745, 0x6747,
+ 0x674A, 0x674B, 0x674D, 0x6752, 0x6754, 0x6755, 0x6757, 0x6758,
+ 0x6759, 0x675A, 0x675B, 0x675D, 0x6762, 0x6763, 0x6764, 0x6766,
+ 0x6767, 0x676B, 0x676C, 0x676E, 0x6771, 0x6774, 0x6776,
+ /* GB 0x9680..0x96FE */
+ 0x6778, 0x6779, 0x677A, 0x677B, 0x677D, 0x6780, 0x6782, 0x6783,
+ 0x6785, 0x6786, 0x6788, 0x678A, 0x678C, 0x678D, 0x678E, 0x678F,
+ 0x6791, 0x6792, 0x6793, 0x6794, 0x6796, 0x6799, 0x679B, 0x679F,
+ 0x67A0, 0x67A1, 0x67A4, 0x67A6, 0x67A9, 0x67AC, 0x67AE, 0x67B1,
+ 0x67B2, 0x67B4, 0x67B9, 0x67BA, 0x67BB, 0x67BC, 0x67BD, 0x67BE,
+ 0x67BF, 0x67C0, 0x67C2, 0x67C5, 0x67C6, 0x67C7, 0x67C8, 0x67C9,
+ 0x67CA, 0x67CB, 0x67CC, 0x67CD, 0x67CE, 0x67D5, 0x67D6, 0x67D7,
+ 0x67DB, 0x67DF, 0x67E1, 0x67E3, 0x67E4, 0x67E6, 0x67E7, 0x67E8,
+ 0x67EA, 0x67EB, 0x67ED, 0x67EE, 0x67F2, 0x67F5, 0x67F6, 0x67F7,
+ 0x67F8, 0x67F9, 0x67FA, 0x67FB, 0x67FC, 0x67FE, 0x6801, 0x6802,
+ 0x6803, 0x6804, 0x6806, 0x680D, 0x6810, 0x6812, 0x6814, 0x6815,
+ 0x6818, 0x6819, 0x681A, 0x681B, 0x681C, 0x681E, 0x681F, 0x6820,
+ 0x6822, 0x6823, 0x6824, 0x6825, 0x6826, 0x6827, 0x6828, 0x682B,
+ 0x682C, 0x682D, 0x682E, 0x682F, 0x6830, 0x6831, 0x6834, 0x6835,
+ 0x6836, 0x683A, 0x683B, 0x683F, 0x6847, 0x684B, 0x684D, 0x684F,
+ 0x6852, 0x6856, 0x6857, 0x6858, 0x6859, 0x685A, 0x685B,
+ /* GB 0x9740..0x977E */
+ 0x685C, 0x685D, 0x685E, 0x685F, 0x686A, 0x686C, 0x686D, 0x686E,
+ 0x686F, 0x6870, 0x6871, 0x6872, 0x6873, 0x6875, 0x6878, 0x6879,
+ 0x687A, 0x687B, 0x687C, 0x687D, 0x687E, 0x687F, 0x6880, 0x6882,
+ 0x6884, 0x6887, 0x6888, 0x6889, 0x688A, 0x688B, 0x688C, 0x688D,
+ 0x688E, 0x6890, 0x6891, 0x6892, 0x6894, 0x6895, 0x6896, 0x6898,
+ 0x6899, 0x689A, 0x689B, 0x689C, 0x689D, 0x689E, 0x689F, 0x68A0,
+ 0x68A1, 0x68A3, 0x68A4, 0x68A5, 0x68A9, 0x68AA, 0x68AB, 0x68AC,
+ 0x68AE, 0x68B1, 0x68B2, 0x68B4, 0x68B6, 0x68B7, 0x68B8,
+ /* GB 0x9780..0x97FE */
+ 0x68B9, 0x68BA, 0x68BB, 0x68BC, 0x68BD, 0x68BE, 0x68BF, 0x68C1,
+ 0x68C3, 0x68C4, 0x68C5, 0x68C6, 0x68C7, 0x68C8, 0x68CA, 0x68CC,
+ 0x68CE, 0x68CF, 0x68D0, 0x68D1, 0x68D3, 0x68D4, 0x68D6, 0x68D7,
+ 0x68D9, 0x68DB, 0x68DC, 0x68DD, 0x68DE, 0x68DF, 0x68E1, 0x68E2,
+ 0x68E4, 0x68E5, 0x68E6, 0x68E7, 0x68E8, 0x68E9, 0x68EA, 0x68EB,
+ 0x68EC, 0x68ED, 0x68EF, 0x68F2, 0x68F3, 0x68F4, 0x68F6, 0x68F7,
+ 0x68F8, 0x68FB, 0x68FD, 0x68FE, 0x68FF, 0x6900, 0x6902, 0x6903,
+ 0x6904, 0x6906, 0x6907, 0x6908, 0x6909, 0x690A, 0x690C, 0x690F,
+ 0x6911, 0x6913, 0x6914, 0x6915, 0x6916, 0x6917, 0x6918, 0x6919,
+ 0x691A, 0x691B, 0x691C, 0x691D, 0x691E, 0x6921, 0x6922, 0x6923,
+ 0x6925, 0x6926, 0x6927, 0x6928, 0x6929, 0x692A, 0x692B, 0x692C,
+ 0x692E, 0x692F, 0x6931, 0x6932, 0x6933, 0x6935, 0x6936, 0x6937,
+ 0x6938, 0x693A, 0x693B, 0x693C, 0x693E, 0x6940, 0x6941, 0x6943,
+ 0x6944, 0x6945, 0x6946, 0x6947, 0x6948, 0x6949, 0x694A, 0x694B,
+ 0x694C, 0x694D, 0x694E, 0x694F, 0x6950, 0x6951, 0x6952, 0x6953,
+ 0x6955, 0x6956, 0x6958, 0x6959, 0x695B, 0x695C, 0x695F,
+ /* GB 0x9840..0x987E */
+ 0x6961, 0x6962, 0x6964, 0x6965, 0x6967, 0x6968, 0x6969, 0x696A,
+ 0x696C, 0x696D, 0x696F, 0x6970, 0x6972, 0x6973, 0x6974, 0x6975,
+ 0x6976, 0x697A, 0x697B, 0x697D, 0x697E, 0x697F, 0x6981, 0x6983,
+ 0x6985, 0x698A, 0x698B, 0x698C, 0x698E, 0x698F, 0x6990, 0x6991,
+ 0x6992, 0x6993, 0x6996, 0x6997, 0x6999, 0x699A, 0x699D, 0x699E,
+ 0x699F, 0x69A0, 0x69A1, 0x69A2, 0x69A3, 0x69A4, 0x69A5, 0x69A6,
+ 0x69A9, 0x69AA, 0x69AC, 0x69AE, 0x69AF, 0x69B0, 0x69B2, 0x69B3,
+ 0x69B5, 0x69B6, 0x69B8, 0x69B9, 0x69BA, 0x69BC, 0x69BD,
+ /* GB 0x9880..0x98FE */
+ 0x69BE, 0x69BF, 0x69C0, 0x69C2, 0x69C3, 0x69C4, 0x69C5, 0x69C6,
+ 0x69C7, 0x69C8, 0x69C9, 0x69CB, 0x69CD, 0x69CF, 0x69D1, 0x69D2,
+ 0x69D3, 0x69D5, 0x69D6, 0x69D7, 0x69D8, 0x69D9, 0x69DA, 0x69DC,
+ 0x69DD, 0x69DE, 0x69E1, 0x69E2, 0x69E3, 0x69E4, 0x69E5, 0x69E6,
+ 0x69E7, 0x69E8, 0x69E9, 0x69EA, 0x69EB, 0x69EC, 0x69EE, 0x69EF,
+ 0x69F0, 0x69F1, 0x69F3, 0x69F4, 0x69F5, 0x69F6, 0x69F7, 0x69F8,
+ 0x69F9, 0x69FA, 0x69FB, 0x69FC, 0x69FE, 0x6A00, 0x6A01, 0x6A02,
+ 0x6A03, 0x6A04, 0x6A05, 0x6A06, 0x6A07, 0x6A08, 0x6A09, 0x6A0B,
+ 0x6A0C, 0x6A0D, 0x6A0E, 0x6A0F, 0x6A10, 0x6A11, 0x6A12, 0x6A13,
+ 0x6A14, 0x6A15, 0x6A16, 0x6A19, 0x6A1A, 0x6A1B, 0x6A1C, 0x6A1D,
+ 0x6A1E, 0x6A20, 0x6A22, 0x6A23, 0x6A24, 0x6A25, 0x6A26, 0x6A27,
+ 0x6A29, 0x6A2B, 0x6A2C, 0x6A2D, 0x6A2E, 0x6A30, 0x6A32, 0x6A33,
+ 0x6A34, 0x6A36, 0x6A37, 0x6A38, 0x6A39, 0x6A3A, 0x6A3B, 0x6A3C,
+ 0x6A3F, 0x6A40, 0x6A41, 0x6A42, 0x6A43, 0x6A45, 0x6A46, 0x6A48,
+ 0x6A49, 0x6A4A, 0x6A4B, 0x6A4C, 0x6A4D, 0x6A4E, 0x6A4F, 0x6A51,
+ 0x6A52, 0x6A53, 0x6A54, 0x6A55, 0x6A56, 0x6A57, 0x6A5A,
+ /* GB 0x9940..0x997E */
+ 0x6A5C, 0x6A5D, 0x6A5E, 0x6A5F, 0x6A60, 0x6A62, 0x6A63, 0x6A64,
+ 0x6A66, 0x6A67, 0x6A68, 0x6A69, 0x6A6A, 0x6A6B, 0x6A6C, 0x6A6D,
+ 0x6A6E, 0x6A6F, 0x6A70, 0x6A72, 0x6A73, 0x6A74, 0x6A75, 0x6A76,
+ 0x6A77, 0x6A78, 0x6A7A, 0x6A7B, 0x6A7D, 0x6A7E, 0x6A7F, 0x6A81,
+ 0x6A82, 0x6A83, 0x6A85, 0x6A86, 0x6A87, 0x6A88, 0x6A89, 0x6A8A,
+ 0x6A8B, 0x6A8C, 0x6A8D, 0x6A8F, 0x6A92, 0x6A93, 0x6A94, 0x6A95,
+ 0x6A96, 0x6A98, 0x6A99, 0x6A9A, 0x6A9B, 0x6A9C, 0x6A9D, 0x6A9E,
+ 0x6A9F, 0x6AA1, 0x6AA2, 0x6AA3, 0x6AA4, 0x6AA5, 0x6AA6,
+ /* GB 0x9980..0x99FE */
+ 0x6AA7, 0x6AA8, 0x6AAA, 0x6AAD, 0x6AAE, 0x6AAF, 0x6AB0, 0x6AB1,
+ 0x6AB2, 0x6AB3, 0x6AB4, 0x6AB5, 0x6AB6, 0x6AB7, 0x6AB8, 0x6AB9,
+ 0x6ABA, 0x6ABB, 0x6ABC, 0x6ABD, 0x6ABE, 0x6ABF, 0x6AC0, 0x6AC1,
+ 0x6AC2, 0x6AC3, 0x6AC4, 0x6AC5, 0x6AC6, 0x6AC7, 0x6AC8, 0x6AC9,
+ 0x6ACA, 0x6ACB, 0x6ACC, 0x6ACD, 0x6ACE, 0x6ACF, 0x6AD0, 0x6AD1,
+ 0x6AD2, 0x6AD3, 0x6AD4, 0x6AD5, 0x6AD6, 0x6AD7, 0x6AD8, 0x6AD9,
+ 0x6ADA, 0x6ADB, 0x6ADC, 0x6ADD, 0x6ADE, 0x6ADF, 0x6AE0, 0x6AE1,
+ 0x6AE2, 0x6AE3, 0x6AE4, 0x6AE5, 0x6AE6, 0x6AE7, 0x6AE8, 0x6AE9,
+ 0x6AEA, 0x6AEB, 0x6AEC, 0x6AED, 0x6AEE, 0x6AEF, 0x6AF0, 0x6AF1,
+ 0x6AF2, 0x6AF3, 0x6AF4, 0x6AF5, 0x6AF6, 0x6AF7, 0x6AF8, 0x6AF9,
+ 0x6AFA, 0x6AFB, 0x6AFC, 0x6AFD, 0x6AFE, 0x6AFF, 0x6B00, 0x6B01,
+ 0x6B02, 0x6B03, 0x6B04, 0x6B05, 0x6B06, 0x6B07, 0x6B08, 0x6B09,
+ 0x6B0A, 0x6B0B, 0x6B0C, 0x6B0D, 0x6B0E, 0x6B0F, 0x6B10, 0x6B11,
+ 0x6B12, 0x6B13, 0x6B14, 0x6B15, 0x6B16, 0x6B17, 0x6B18, 0x6B19,
+ 0x6B1A, 0x6B1B, 0x6B1C, 0x6B1D, 0x6B1E, 0x6B1F, 0x6B25, 0x6B26,
+ 0x6B28, 0x6B29, 0x6B2A, 0x6B2B, 0x6B2C, 0x6B2D, 0x6B2E,
+ /* GB 0x9A40..0x9A7E */
+ 0x6B2F, 0x6B30, 0x6B31, 0x6B33, 0x6B34, 0x6B35, 0x6B36, 0x6B38,
+ 0x6B3B, 0x6B3C, 0x6B3D, 0x6B3F, 0x6B40, 0x6B41, 0x6B42, 0x6B44,
+ 0x6B45, 0x6B48, 0x6B4A, 0x6B4B, 0x6B4D, 0x6B4E, 0x6B4F, 0x6B50,
+ 0x6B51, 0x6B52, 0x6B53, 0x6B54, 0x6B55, 0x6B56, 0x6B57, 0x6B58,
+ 0x6B5A, 0x6B5B, 0x6B5C, 0x6B5D, 0x6B5E, 0x6B5F, 0x6B60, 0x6B61,
+ 0x6B68, 0x6B69, 0x6B6B, 0x6B6C, 0x6B6D, 0x6B6E, 0x6B6F, 0x6B70,
+ 0x6B71, 0x6B72, 0x6B73, 0x6B74, 0x6B75, 0x6B76, 0x6B77, 0x6B78,
+ 0x6B7A, 0x6B7D, 0x6B7E, 0x6B7F, 0x6B80, 0x6B85, 0x6B88,
+ /* GB 0x9A80..0x9AFE */
+ 0x6B8C, 0x6B8E, 0x6B8F, 0x6B90, 0x6B91, 0x6B94, 0x6B95, 0x6B97,
+ 0x6B98, 0x6B99, 0x6B9C, 0x6B9D, 0x6B9E, 0x6B9F, 0x6BA0, 0x6BA2,
+ 0x6BA3, 0x6BA4, 0x6BA5, 0x6BA6, 0x6BA7, 0x6BA8, 0x6BA9, 0x6BAB,
+ 0x6BAC, 0x6BAD, 0x6BAE, 0x6BAF, 0x6BB0, 0x6BB1, 0x6BB2, 0x6BB6,
+ 0x6BB8, 0x6BB9, 0x6BBA, 0x6BBB, 0x6BBC, 0x6BBD, 0x6BBE, 0x6BC0,
+ 0x6BC3, 0x6BC4, 0x6BC6, 0x6BC7, 0x6BC8, 0x6BC9, 0x6BCA, 0x6BCC,
+ 0x6BCE, 0x6BD0, 0x6BD1, 0x6BD8, 0x6BDA, 0x6BDC, 0x6BDD, 0x6BDE,
+ 0x6BDF, 0x6BE0, 0x6BE2, 0x6BE3, 0x6BE4, 0x6BE5, 0x6BE6, 0x6BE7,
+ 0x6BE8, 0x6BE9, 0x6BEC, 0x6BED, 0x6BEE, 0x6BF0, 0x6BF1, 0x6BF2,
+ 0x6BF4, 0x6BF6, 0x6BF7, 0x6BF8, 0x6BFA, 0x6BFB, 0x6BFC, 0x6BFE,
+ 0x6BFF, 0x6C00, 0x6C01, 0x6C02, 0x6C03, 0x6C04, 0x6C08, 0x6C09,
+ 0x6C0A, 0x6C0B, 0x6C0C, 0x6C0E, 0x6C12, 0x6C17, 0x6C1C, 0x6C1D,
+ 0x6C1E, 0x6C20, 0x6C23, 0x6C25, 0x6C2B, 0x6C2C, 0x6C2D, 0x6C31,
+ 0x6C33, 0x6C36, 0x6C37, 0x6C39, 0x6C3A, 0x6C3B, 0x6C3C, 0x6C3E,
+ 0x6C3F, 0x6C43, 0x6C44, 0x6C45, 0x6C48, 0x6C4B, 0x6C4C, 0x6C4D,
+ 0x6C4E, 0x6C4F, 0x6C51, 0x6C52, 0x6C53, 0x6C56, 0x6C58,
+ /* GB 0x9B40..0x9B7E */
+ 0x6C59, 0x6C5A, 0x6C62, 0x6C63, 0x6C65, 0x6C66, 0x6C67, 0x6C6B,
+ 0x6C6C, 0x6C6D, 0x6C6E, 0x6C6F, 0x6C71, 0x6C73, 0x6C75, 0x6C77,
+ 0x6C78, 0x6C7A, 0x6C7B, 0x6C7C, 0x6C7F, 0x6C80, 0x6C84, 0x6C87,
+ 0x6C8A, 0x6C8B, 0x6C8D, 0x6C8E, 0x6C91, 0x6C92, 0x6C95, 0x6C96,
+ 0x6C97, 0x6C98, 0x6C9A, 0x6C9C, 0x6C9D, 0x6C9E, 0x6CA0, 0x6CA2,
+ 0x6CA8, 0x6CAC, 0x6CAF, 0x6CB0, 0x6CB4, 0x6CB5, 0x6CB6, 0x6CB7,
+ 0x6CBA, 0x6CC0, 0x6CC1, 0x6CC2, 0x6CC3, 0x6CC6, 0x6CC7, 0x6CC8,
+ 0x6CCB, 0x6CCD, 0x6CCE, 0x6CCF, 0x6CD1, 0x6CD2, 0x6CD8,
+ /* GB 0x9B80..0x9BFE */
+ 0x6CD9, 0x6CDA, 0x6CDC, 0x6CDD, 0x6CDF, 0x6CE4, 0x6CE6, 0x6CE7,
+ 0x6CE9, 0x6CEC, 0x6CED, 0x6CF2, 0x6CF4, 0x6CF9, 0x6CFF, 0x6D00,
+ 0x6D02, 0x6D03, 0x6D05, 0x6D06, 0x6D08, 0x6D09, 0x6D0A, 0x6D0D,
+ 0x6D0F, 0x6D10, 0x6D11, 0x6D13, 0x6D14, 0x6D15, 0x6D16, 0x6D18,
+ 0x6D1C, 0x6D1D, 0x6D1F, 0x6D20, 0x6D21, 0x6D22, 0x6D23, 0x6D24,
+ 0x6D26, 0x6D28, 0x6D29, 0x6D2C, 0x6D2D, 0x6D2F, 0x6D30, 0x6D34,
+ 0x6D36, 0x6D37, 0x6D38, 0x6D3A, 0x6D3F, 0x6D40, 0x6D42, 0x6D44,
+ 0x6D49, 0x6D4C, 0x6D50, 0x6D55, 0x6D56, 0x6D57, 0x6D58, 0x6D5B,
+ 0x6D5D, 0x6D5F, 0x6D61, 0x6D62, 0x6D64, 0x6D65, 0x6D67, 0x6D68,
+ 0x6D6B, 0x6D6C, 0x6D6D, 0x6D70, 0x6D71, 0x6D72, 0x6D73, 0x6D75,
+ 0x6D76, 0x6D79, 0x6D7A, 0x6D7B, 0x6D7D, 0x6D7E, 0x6D7F, 0x6D80,
+ 0x6D81, 0x6D83, 0x6D84, 0x6D86, 0x6D87, 0x6D8A, 0x6D8B, 0x6D8D,
+ 0x6D8F, 0x6D90, 0x6D92, 0x6D96, 0x6D97, 0x6D98, 0x6D99, 0x6D9A,
+ 0x6D9C, 0x6DA2, 0x6DA5, 0x6DAC, 0x6DAD, 0x6DB0, 0x6DB1, 0x6DB3,
+ 0x6DB4, 0x6DB6, 0x6DB7, 0x6DB9, 0x6DBA, 0x6DBB, 0x6DBC, 0x6DBD,
+ 0x6DBE, 0x6DC1, 0x6DC2, 0x6DC3, 0x6DC8, 0x6DC9, 0x6DCA,
+ /* GB 0x9C40..0x9C7E */
+ 0x6DCD, 0x6DCE, 0x6DCF, 0x6DD0, 0x6DD2, 0x6DD3, 0x6DD4, 0x6DD5,
+ 0x6DD7, 0x6DDA, 0x6DDB, 0x6DDC, 0x6DDF, 0x6DE2, 0x6DE3, 0x6DE5,
+ 0x6DE7, 0x6DE8, 0x6DE9, 0x6DEA, 0x6DED, 0x6DEF, 0x6DF0, 0x6DF2,
+ 0x6DF4, 0x6DF5, 0x6DF6, 0x6DF8, 0x6DFA, 0x6DFD, 0x6DFE, 0x6DFF,
+ 0x6E00, 0x6E01, 0x6E02, 0x6E03, 0x6E04, 0x6E06, 0x6E07, 0x6E08,
+ 0x6E09, 0x6E0B, 0x6E0F, 0x6E12, 0x6E13, 0x6E15, 0x6E18, 0x6E19,
+ 0x6E1B, 0x6E1C, 0x6E1E, 0x6E1F, 0x6E22, 0x6E26, 0x6E27, 0x6E28,
+ 0x6E2A, 0x6E2C, 0x6E2E, 0x6E30, 0x6E31, 0x6E33, 0x6E35,
+ /* GB 0x9C80..0x9CFE */
+ 0x6E36, 0x6E37, 0x6E39, 0x6E3B, 0x6E3C, 0x6E3D, 0x6E3E, 0x6E3F,
+ 0x6E40, 0x6E41, 0x6E42, 0x6E45, 0x6E46, 0x6E47, 0x6E48, 0x6E49,
+ 0x6E4A, 0x6E4B, 0x6E4C, 0x6E4F, 0x6E50, 0x6E51, 0x6E52, 0x6E55,
+ 0x6E57, 0x6E59, 0x6E5A, 0x6E5C, 0x6E5D, 0x6E5E, 0x6E60, 0x6E61,
+ 0x6E62, 0x6E63, 0x6E64, 0x6E65, 0x6E66, 0x6E67, 0x6E68, 0x6E69,
+ 0x6E6A, 0x6E6C, 0x6E6D, 0x6E6F, 0x6E70, 0x6E71, 0x6E72, 0x6E73,
+ 0x6E74, 0x6E75, 0x6E76, 0x6E77, 0x6E78, 0x6E79, 0x6E7A, 0x6E7B,
+ 0x6E7C, 0x6E7D, 0x6E80, 0x6E81, 0x6E82, 0x6E84, 0x6E87, 0x6E88,
+ 0x6E8A, 0x6E8B, 0x6E8C, 0x6E8D, 0x6E8E, 0x6E91, 0x6E92, 0x6E93,
+ 0x6E94, 0x6E95, 0x6E96, 0x6E97, 0x6E99, 0x6E9A, 0x6E9B, 0x6E9D,
+ 0x6E9E, 0x6EA0, 0x6EA1, 0x6EA3, 0x6EA4, 0x6EA6, 0x6EA8, 0x6EA9,
+ 0x6EAB, 0x6EAC, 0x6EAD, 0x6EAE, 0x6EB0, 0x6EB3, 0x6EB5, 0x6EB8,
+ 0x6EB9, 0x6EBC, 0x6EBE, 0x6EBF, 0x6EC0, 0x6EC3, 0x6EC4, 0x6EC5,
+ 0x6EC6, 0x6EC8, 0x6EC9, 0x6ECA, 0x6ECC, 0x6ECD, 0x6ECE, 0x6ED0,
+ 0x6ED2, 0x6ED6, 0x6ED8, 0x6ED9, 0x6EDB, 0x6EDC, 0x6EDD, 0x6EE3,
+ 0x6EE7, 0x6EEA, 0x6EEB, 0x6EEC, 0x6EED, 0x6EEE, 0x6EEF,
+ /* GB 0x9D40..0x9D7E */
+ 0x6EF0, 0x6EF1, 0x6EF2, 0x6EF3, 0x6EF5, 0x6EF6, 0x6EF7, 0x6EF8,
+ 0x6EFA, 0x6EFB, 0x6EFC, 0x6EFD, 0x6EFE, 0x6EFF, 0x6F00, 0x6F01,
+ 0x6F03, 0x6F04, 0x6F05, 0x6F07, 0x6F08, 0x6F0A, 0x6F0B, 0x6F0C,
+ 0x6F0D, 0x6F0E, 0x6F10, 0x6F11, 0x6F12, 0x6F16, 0x6F17, 0x6F18,
+ 0x6F19, 0x6F1A, 0x6F1B, 0x6F1C, 0x6F1D, 0x6F1E, 0x6F1F, 0x6F21,
+ 0x6F22, 0x6F23, 0x6F25, 0x6F26, 0x6F27, 0x6F28, 0x6F2C, 0x6F2E,
+ 0x6F30, 0x6F32, 0x6F34, 0x6F35, 0x6F37, 0x6F38, 0x6F39, 0x6F3A,
+ 0x6F3B, 0x6F3C, 0x6F3D, 0x6F3F, 0x6F40, 0x6F41, 0x6F42,
+ /* GB 0x9D80..0x9DFE */
+ 0x6F43, 0x6F44, 0x6F45, 0x6F48, 0x6F49, 0x6F4A, 0x6F4C, 0x6F4E,
+ 0x6F4F, 0x6F50, 0x6F51, 0x6F52, 0x6F53, 0x6F54, 0x6F55, 0x6F56,
+ 0x6F57, 0x6F59, 0x6F5A, 0x6F5B, 0x6F5D, 0x6F5F, 0x6F60, 0x6F61,
+ 0x6F63, 0x6F64, 0x6F65, 0x6F67, 0x6F68, 0x6F69, 0x6F6A, 0x6F6B,
+ 0x6F6C, 0x6F6F, 0x6F70, 0x6F71, 0x6F73, 0x6F75, 0x6F76, 0x6F77,
+ 0x6F79, 0x6F7B, 0x6F7D, 0x6F7E, 0x6F7F, 0x6F80, 0x6F81, 0x6F82,
+ 0x6F83, 0x6F85, 0x6F86, 0x6F87, 0x6F8A, 0x6F8B, 0x6F8F, 0x6F90,
+ 0x6F91, 0x6F92, 0x6F93, 0x6F94, 0x6F95, 0x6F96, 0x6F97, 0x6F98,
+ 0x6F99, 0x6F9A, 0x6F9B, 0x6F9D, 0x6F9E, 0x6F9F, 0x6FA0, 0x6FA2,
+ 0x6FA3, 0x6FA4, 0x6FA5, 0x6FA6, 0x6FA8, 0x6FA9, 0x6FAA, 0x6FAB,
+ 0x6FAC, 0x6FAD, 0x6FAE, 0x6FAF, 0x6FB0, 0x6FB1, 0x6FB2, 0x6FB4,
+ 0x6FB5, 0x6FB7, 0x6FB8, 0x6FBA, 0x6FBB, 0x6FBC, 0x6FBD, 0x6FBE,
+ 0x6FBF, 0x6FC1, 0x6FC3, 0x6FC4, 0x6FC5, 0x6FC6, 0x6FC7, 0x6FC8,
+ 0x6FCA, 0x6FCB, 0x6FCC, 0x6FCD, 0x6FCE, 0x6FCF, 0x6FD0, 0x6FD3,
+ 0x6FD4, 0x6FD5, 0x6FD6, 0x6FD7, 0x6FD8, 0x6FD9, 0x6FDA, 0x6FDB,
+ 0x6FDC, 0x6FDD, 0x6FDF, 0x6FE2, 0x6FE3, 0x6FE4, 0x6FE5,
+ /* GB 0x9E40..0x9E7E */
+ 0x6FE6, 0x6FE7, 0x6FE8, 0x6FE9, 0x6FEA, 0x6FEB, 0x6FEC, 0x6FED,
+ 0x6FF0, 0x6FF1, 0x6FF2, 0x6FF3, 0x6FF4, 0x6FF5, 0x6FF6, 0x6FF7,
+ 0x6FF8, 0x6FF9, 0x6FFA, 0x6FFB, 0x6FFC, 0x6FFD, 0x6FFE, 0x6FFF,
+ 0x7000, 0x7001, 0x7002, 0x7003, 0x7004, 0x7005, 0x7006, 0x7007,
+ 0x7008, 0x7009, 0x700A, 0x700B, 0x700C, 0x700D, 0x700E, 0x700F,
+ 0x7010, 0x7012, 0x7013, 0x7014, 0x7015, 0x7016, 0x7017, 0x7018,
+ 0x7019, 0x701C, 0x701D, 0x701E, 0x701F, 0x7020, 0x7021, 0x7022,
+ 0x7024, 0x7025, 0x7026, 0x7027, 0x7028, 0x7029, 0x702A,
+ /* GB 0x9E80..0x9EFE */
+ 0x702B, 0x702C, 0x702D, 0x702E, 0x702F, 0x7030, 0x7031, 0x7032,
+ 0x7033, 0x7034, 0x7036, 0x7037, 0x7038, 0x703A, 0x703B, 0x703C,
+ 0x703D, 0x703E, 0x703F, 0x7040, 0x7041, 0x7042, 0x7043, 0x7044,
+ 0x7045, 0x7046, 0x7047, 0x7048, 0x7049, 0x704A, 0x704B, 0x704D,
+ 0x704E, 0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055, 0x7056,
+ 0x7057, 0x7058, 0x7059, 0x705A, 0x705B, 0x705C, 0x705D, 0x705F,
+ 0x7060, 0x7061, 0x7062, 0x7063, 0x7064, 0x7065, 0x7066, 0x7067,
+ 0x7068, 0x7069, 0x706A, 0x706E, 0x7071, 0x7072, 0x7073, 0x7074,
+ 0x7077, 0x7079, 0x707A, 0x707B, 0x707D, 0x7081, 0x7082, 0x7083,
+ 0x7084, 0x7086, 0x7087, 0x7088, 0x708B, 0x708C, 0x708D, 0x708F,
+ 0x7090, 0x7091, 0x7093, 0x7097, 0x7098, 0x709A, 0x709B, 0x709E,
+ 0x709F, 0x70A0, 0x70A1, 0x70A2, 0x70A3, 0x70A4, 0x70A5, 0x70A6,
+ 0x70A7, 0x70A8, 0x70A9, 0x70AA, 0x70B0, 0x70B2, 0x70B4, 0x70B5,
+ 0x70B6, 0x70BA, 0x70BE, 0x70BF, 0x70C4, 0x70C5, 0x70C6, 0x70C7,
+ 0x70C9, 0x70CB, 0x70CC, 0x70CD, 0x70CE, 0x70CF, 0x70D0, 0x70D1,
+ 0x70D2, 0x70D3, 0x70D4, 0x70D5, 0x70D6, 0x70D7, 0x70DA,
+ /* GB 0x9F40..0x9F7E */
+ 0x70DC, 0x70DD, 0x70DE, 0x70E0, 0x70E1, 0x70E2, 0x70E3, 0x70E5,
+ 0x70EA, 0x70EE, 0x70F0, 0x70F1, 0x70F2, 0x70F3, 0x70F4, 0x70F5,
+ 0x70F6, 0x70F8, 0x70FA, 0x70FB, 0x70FC, 0x70FE, 0x70FF, 0x7100,
+ 0x7101, 0x7102, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x7108,
+ 0x710B, 0x710C, 0x710D, 0x710E, 0x710F, 0x7111, 0x7112, 0x7114,
+ 0x7117, 0x711B, 0x711C, 0x711D, 0x711E, 0x711F, 0x7120, 0x7121,
+ 0x7122, 0x7123, 0x7124, 0x7125, 0x7127, 0x7128, 0x7129, 0x712A,
+ 0x712B, 0x712C, 0x712D, 0x712E, 0x7132, 0x7133, 0x7134,
+ /* GB 0x9F80..0x9FFE */
+ 0x7135, 0x7137, 0x7138, 0x7139, 0x713A, 0x713B, 0x713C, 0x713D,
+ 0x713E, 0x713F, 0x7140, 0x7141, 0x7142, 0x7143, 0x7144, 0x7146,
+ 0x7147, 0x7148, 0x7149, 0x714B, 0x714D, 0x714F, 0x7150, 0x7151,
+ 0x7152, 0x7153, 0x7154, 0x7155, 0x7156, 0x7157, 0x7158, 0x7159,
+ 0x715A, 0x715B, 0x715D, 0x715F, 0x7160, 0x7161, 0x7162, 0x7163,
+ 0x7165, 0x7169, 0x716A, 0x716B, 0x716C, 0x716D, 0x716F, 0x7170,
+ 0x7171, 0x7174, 0x7175, 0x7176, 0x7177, 0x7179, 0x717B, 0x717C,
+ 0x717E, 0x717F, 0x7180, 0x7181, 0x7182, 0x7183, 0x7185, 0x7186,
+ 0x7187, 0x7188, 0x7189, 0x718B, 0x718C, 0x718D, 0x718E, 0x7190,
+ 0x7191, 0x7192, 0x7193, 0x7195, 0x7196, 0x7197, 0x719A, 0x719B,
+ 0x719C, 0x719D, 0x719E, 0x71A1, 0x71A2, 0x71A3, 0x71A4, 0x71A5,
+ 0x71A6, 0x71A7, 0x71A9, 0x71AA, 0x71AB, 0x71AD, 0x71AE, 0x71AF,
+ 0x71B0, 0x71B1, 0x71B2, 0x71B4, 0x71B6, 0x71B7, 0x71B8, 0x71BA,
+ 0x71BB, 0x71BC, 0x71BD, 0x71BE, 0x71BF, 0x71C0, 0x71C1, 0x71C2,
+ 0x71C4, 0x71C5, 0x71C6, 0x71C7, 0x71C8, 0x71C9, 0x71CA, 0x71CB,
+ 0x71CC, 0x71CD, 0x71CF, 0x71D0, 0x71D1, 0x71D2, 0x71D3,
+ /* GB 0xA040..0xA07E */
+ 0x71D6, 0x71D7, 0x71D8, 0x71D9, 0x71DA, 0x71DB, 0x71DC, 0x71DD,
+ 0x71DE, 0x71DF, 0x71E1, 0x71E2, 0x71E3, 0x71E4, 0x71E6, 0x71E8,
+ 0x71E9, 0x71EA, 0x71EB, 0x71EC, 0x71ED, 0x71EF, 0x71F0, 0x71F1,
+ 0x71F2, 0x71F3, 0x71F4, 0x71F5, 0x71F6, 0x71F7, 0x71F8, 0x71FA,
+ 0x71FB, 0x71FC, 0x71FD, 0x71FE, 0x71FF, 0x7200, 0x7201, 0x7202,
+ 0x7203, 0x7204, 0x7205, 0x7207, 0x7208, 0x7209, 0x720A, 0x720B,
+ 0x720C, 0x720D, 0x720E, 0x720F, 0x7210, 0x7211, 0x7212, 0x7213,
+ 0x7214, 0x7215, 0x7216, 0x7217, 0x7218, 0x7219, 0x721A,
+ /* GB 0xA080..0xA0FE */
+ 0x721B, 0x721C, 0x721E, 0x721F, 0x7220, 0x7221, 0x7222, 0x7223,
+ 0x7224, 0x7225, 0x7226, 0x7227, 0x7229, 0x722B, 0x722D, 0x722E,
+ 0x722F, 0x7232, 0x7233, 0x7234, 0x723A, 0x723C, 0x723E, 0x7240,
+ 0x7241, 0x7242, 0x7243, 0x7244, 0x7245, 0x7246, 0x7249, 0x724A,
+ 0x724B, 0x724E, 0x724F, 0x7250, 0x7251, 0x7253, 0x7254, 0x7255,
+ 0x7257, 0x7258, 0x725A, 0x725C, 0x725E, 0x7260, 0x7263, 0x7264,
+ 0x7265, 0x7268, 0x726A, 0x726B, 0x726C, 0x726D, 0x7270, 0x7271,
+ 0x7273, 0x7274, 0x7276, 0x7277, 0x7278, 0x727B, 0x727C, 0x727D,
+ 0x7282, 0x7283, 0x7285, 0x7286, 0x7287, 0x7288, 0x7289, 0x728C,
+ 0x728E, 0x7290, 0x7291, 0x7293, 0x7294, 0x7295, 0x7296, 0x7297,
+ 0x7298, 0x7299, 0x729A, 0x729B, 0x729C, 0x729D, 0x729E, 0x72A0,
+ 0x72A1, 0x72A2, 0x72A3, 0x72A4, 0x72A5, 0x72A6, 0x72A7, 0x72A8,
+ 0x72A9, 0x72AA, 0x72AB, 0x72AE, 0x72B1, 0x72B2, 0x72B3, 0x72B5,
+ 0x72BA, 0x72BB, 0x72BC, 0x72BD, 0x72BE, 0x72BF, 0x72C0, 0x72C5,
+ 0x72C6, 0x72C7, 0x72C9, 0x72CA, 0x72CB, 0x72CC, 0x72CF, 0x72D1,
+ 0x72D3, 0x72D4, 0x72D5, 0x72D6, 0x72D8, 0x72DA, 0x72DB,
+ /* Skip: GB 0xA140..0xA17E, 0xA180..0xA1A0 (UDA 3) */
+ /* GB 0xA2A1..0xA2FE */
+ 0x3000, 0x3001, 0x3002, 0x00B7, 0x02C9, 0x02C7, 0x00A8,
+ 0x3003, 0x3005, 0x2014, 0xFF5E, 0x2016, 0x2026, 0x2018, 0x2019,
+ 0x201C, 0x201D, 0x3014, 0x3015, 0x3008, 0x3009, 0x300A, 0x300B,
+ 0x300C, 0x300D, 0x300E, 0x300F, 0x3016, 0x3017, 0x3010, 0x3011,
+ 0x00B1, 0x00D7, 0x00F7, 0x2236, 0x2227, 0x2228, 0x2211, 0x220F,
+ 0x222A, 0x2229, 0x2208, 0x2237, 0x221A, 0x22A5, 0x2225, 0x2220,
+ 0x2312, 0x2299, 0x222B, 0x222E, 0x2261, 0x224C, 0x2248, 0x223D,
+ 0x221D, 0x2260, 0x226E, 0x226F, 0x2264, 0x2265, 0x221E, 0x2235,
+ 0x2234, 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFF04,
+ 0x00A4, 0xFFE0, 0xFFE1, 0x2030, 0x00A7, 0x2116, 0x2606, 0x2605,
+ 0x25CB, 0x25CF, 0x25CE, 0x25C7, 0x25C6, 0x25A1, 0x25A0, 0x25B3,
+ 0x25B2, 0x203B, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013,
+ /* Skip: GB 0xA240..0xA27E, 0xA280..0xA2A0 (UDA 3) */
+ /* GB 0xA3A1..0xA3FE */
+ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176,
+ 0x2177, 0x2178, 0x2179, 0xE766, 0xE767, 0xE768, 0xE769, 0xE76A,
+ 0xE76B, 0x2488, 0x2489, 0x248A, 0x248B, 0x248C, 0x248D, 0x248E,
+ 0x248F, 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496,
+ 0x2497, 0x2498, 0x2499, 0x249A, 0x249B, 0x2474, 0x2475, 0x2476,
+ 0x2477, 0x2478, 0x2479, 0x247A, 0x247B, 0x247C, 0x247D, 0x247E,
+ 0x247F, 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486,
+ 0x2487, 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466,
+ 0x2467, 0x2468, 0x2469, 0x20AC, 0xE76D, 0x3220, 0x3221, 0x3222,
+ 0x3223, 0x3224, 0x3225, 0x3226, 0x3227, 0x3228, 0x3229, 0xE76E,
+ 0xE76F, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166,
+ 0x2167, 0x2168, 0x2169, 0x216A, 0x216B, 0xE770, 0xE771,
+ /* Skip: GB 0xA340..0xA37E, 0xA380..0xA3A0 (UDA 3) */
+ /* GB 0xA4A1..0xA4FE */
+ 0xFF01, 0xFF02, 0xFF03, 0xFFE5, 0xFF05, 0xFF06, 0xFF07,
+ 0xFF08, 0xFF09, 0xFF0A, 0xFF0B, 0xFF0C, 0xFF0D, 0xFF0E, 0xFF0F,
+ 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17,
+ 0xFF18, 0xFF19, 0xFF1A, 0xFF1B, 0xFF1C, 0xFF1D, 0xFF1E, 0xFF1F,
+ 0xFF20, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27,
+ 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F,
+ 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37,
+ 0xFF38, 0xFF39, 0xFF3A, 0xFF3B, 0xFF3C, 0xFF3D, 0xFF3E, 0xFF3F,
+ 0xFF40, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47,
+ 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F,
+ 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57,
+ 0xFF58, 0xFF59, 0xFF5A, 0xFF5B, 0xFF5C, 0xFF5D, 0xFFE3,
+ /* Skip: GB 0xA440..0xA47E, 0xA480..0xA4A0 (UDA 3) */
+ /* GB 0xA5A1..0xA5FE */
+ 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047,
+ 0x3048, 0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F,
+ 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057,
+ 0x3058, 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F,
+ 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067,
+ 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F,
+ 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077,
+ 0x3078, 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F,
+ 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087,
+ 0x3088, 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F,
+ 0x3090, 0x3091, 0x3092, 0x3093, 0xE772, 0xE773, 0xE774, 0xE775,
+ 0xE776, 0xE777, 0xE778, 0xE779, 0xE77A, 0xE77B, 0xE77C,
+ /* Skip: GB 0xA540..0xA57E, 0xA580..0xA5A0 (UDA 3) */
+ /* GB 0xA6A1..0xA6FE */
+ 0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7,
+ 0x30A8, 0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, 0x30AF,
+ 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7,
+ 0x30B8, 0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF,
+ 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, 0x30C7,
+ 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF,
+ 0x30D0, 0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7,
+ 0x30D8, 0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, 0x30DF,
+ 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7,
+ 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF,
+ 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6, 0xE77D,
+ 0xE77E, 0xE77F, 0xE780, 0xE781, 0xE782, 0xE783, 0xE784,
+ /* Skip: GB 0xA640..0xA67E, 0xA680..0xA6A0 (UDA 3) */
+ /* GB 0xA7A1..0xA7FE */
+ 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8,
+ 0x03A9, 0xE785, 0xE786, 0xE787, 0xE788, 0xE789, 0xE78A, 0xE78B,
+ 0xE78C, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8,
+ 0x03C9, 0xE78D, 0xE78E, 0xE78F, 0xE790, 0xE791, 0xE792, 0xE793,
+ 0xFE35, 0xFE36, 0xFE39, 0xFE3A, 0xFE3F, 0xFE40, 0xFE3D, 0xFE3E,
+ 0xFE41, 0xFE42, 0xFE43, 0xFE44, 0xE794, 0xE795, 0xFE3B, 0xFE3C,
+ 0xFE37, 0xFE38, 0xFE31, 0xE796, 0xFE33, 0xFE34, 0xE797, 0xE798,
+ 0xE799, 0xE79A, 0xE79B, 0xE79C, 0xE79D, 0xE79E, 0xE79F,
+ /* Skip: GB 0xA740..0xA77E, 0xA780..0xA7A0 (UDA 3) */
+ /* GB 0xA8A1..0xA8FE */
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401,
+ 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D,
+ 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425,
+ 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D,
+ 0x042E, 0x042F, 0xE7A0, 0xE7A1, 0xE7A2, 0xE7A3, 0xE7A4, 0xE7A5,
+ 0xE7A6, 0xE7A7, 0xE7A8, 0xE7A9, 0xE7AA, 0xE7AB, 0xE7AC, 0xE7AD,
+ 0xE7AE, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451,
+ 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D,
+ 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445,
+ 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D,
+ 0x044E, 0x044F, 0xE7AF, 0xE7B0, 0xE7B1, 0xE7B2, 0xE7B3, 0xE7B4,
+ 0xE7B5, 0xE7B6, 0xE7B7, 0xE7B8, 0xE7B9, 0xE7BA, 0xE7BB,
+ /* GB 0xA840..0xA87E */
+ 0x02CA, 0x02CB, 0x02D9, 0x2013, 0x2015, 0x2025, 0x2035, 0x2105,
+ 0x2109, 0x2196, 0x2197, 0x2198, 0x2199, 0x2215, 0x221F, 0x2223,
+ 0x2252, 0x2266, 0x2267, 0x22BF, 0x2550, 0x2551, 0x2552, 0x2553,
+ 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255A, 0x255B,
+ 0x255C, 0x255D, 0x255E, 0x255F, 0x2560, 0x2561, 0x2562, 0x2563,
+ 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B,
+ 0x256C, 0x256D, 0x256E, 0x256F, 0x2570, 0x2571, 0x2572, 0x2573,
+ 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, 0x2587,
+ /* GB 0xA880..0xA8FE */
+ 0x2588, 0x2589, 0x258A, 0x258B, 0x258C, 0x258D, 0x258E, 0x258F,
+ 0x2593, 0x2594, 0x2595, 0x25BC, 0x25BD, 0x25E2, 0x25E3, 0x25E4,
+ 0x25E5, 0x2609, 0x2295, 0x3012, 0x301D, 0x301E, 0xE7BC, 0xE7BD,
+ 0xE7BE, 0xE7BF, 0xE7C0, 0xE7C1, 0xE7C2, 0xE7C3, 0xE7C4, 0xE7C5,
+ 0xE7C6, 0x0101, 0x00E1, 0x01CE, 0x00E0, 0x0113, 0x00E9, 0x011B,
+ 0x00E8, 0x012B, 0x00ED, 0x01D0, 0x00EC, 0x014D, 0x00F3, 0x01D2,
+ 0x00F2, 0x016B, 0x00FA, 0x01D4, 0x00F9, 0x01D6, 0x01D8, 0x01DA,
+ 0x01DC, 0x00FC, 0x00EA, 0x0251, 0xE7C7, 0x0144, 0x0148, 0x01F9,
+ 0x0261, 0xE7C9, 0xE7CA, 0xE7CB, 0xE7CC, 0x3105, 0x3106, 0x3107,
+ 0x3108, 0x3109, 0x310A, 0x310B, 0x310C, 0x310D, 0x310E, 0x310F,
+ 0x3110, 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117,
+ 0x3118, 0x3119, 0x311A, 0x311B, 0x311C, 0x311D, 0x311E, 0x311F,
+ 0x3120, 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127,
+ 0x3128, 0x3129, 0xE7CD, 0xE7CE, 0xE7CF, 0xE7D0, 0xE7D1, 0xE7D2,
+ 0xE7D3, 0xE7D4, 0xE7D5, 0xE7D6, 0xE7D7, 0xE7D8, 0xE7D9, 0xE7DA,
+ 0xE7DB, 0xE7DC, 0xE7DD, 0xE7DE, 0xE7DF, 0xE7E0, 0xE7E1,
+ /* GB 0xA940..0xA97E */
+ 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, 0x3028,
+ 0x3029, 0x32A3, 0x338E, 0x338F, 0x339C, 0x339D, 0x339E, 0x33A1,
+ 0x33C4, 0x33CE, 0x33D1, 0x33D2, 0x33D5, 0xFE30, 0xFFE2, 0xFFE4,
+ 0xE7E2, 0x2121, 0x3231, 0xE7E3, 0x2010, 0xE7E4, 0xE7E5, 0xE7E6,
+ 0x30FC, 0x309B, 0x309C, 0x30FD, 0x30FE, 0x3006, 0x309D, 0x309E,
+ 0xFE49, 0xFE4A, 0xFE4B, 0xFE4C, 0xFE4D, 0xFE4E, 0xFE4F, 0xFE50,
+ 0xFE51, 0xFE52, 0xFE54, 0xFE55, 0xFE56, 0xFE57, 0xFE59, 0xFE5A,
+ 0xFE5B, 0xFE5C, 0xFE5D, 0xFE5E, 0xFE5F, 0xFE60, 0xFE61,
+ /* GB 0xA980..0xA9FE */
+ 0xFE62, 0xFE63, 0xFE64, 0xFE65, 0xFE66, 0xFE68, 0xFE69, 0xFE6A,
+ 0xFE6B, 0x303E, 0x2FF0, 0x2FF1, 0x2FF2, 0x2FF3, 0x2FF4, 0x2FF5,
+ 0x2FF6, 0x2FF7, 0x2FF8, 0x2FF9, 0x2FFA, 0x2FFB, 0x3007, 0xE7F4,
+ 0xE7F5, 0xE7F6, 0xE7F7, 0xE7F8, 0xE7F9, 0xE7FA, 0xE7FB, 0xE7FC,
+ 0xE7FD, 0xE7FE, 0xE7FF, 0xE800, 0x2500, 0x2501, 0x2502, 0x2503,
+ 0x2504, 0x2505, 0x2506, 0x2507, 0x2508, 0x2509, 0x250A, 0x250B,
+ 0x250C, 0x250D, 0x250E, 0x250F, 0x2510, 0x2511, 0x2512, 0x2513,
+ 0x2514, 0x2515, 0x2516, 0x2517, 0x2518, 0x2519, 0x251A, 0x251B,
+ 0x251C, 0x251D, 0x251E, 0x251F, 0x2520, 0x2521, 0x2522, 0x2523,
+ 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252A, 0x252B,
+ 0x252C, 0x252D, 0x252E, 0x252F, 0x2530, 0x2531, 0x2532, 0x2533,
+ 0x2534, 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253A, 0x253B,
+ 0x253C, 0x253D, 0x253E, 0x253F, 0x2540, 0x2541, 0x2542, 0x2543,
+ 0x2544, 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254A, 0x254B,
+ 0xE801, 0xE802, 0xE803, 0xE804, 0xE805, 0xE806, 0xE807, 0xE808,
+ 0xE809, 0xE80A, 0xE80B, 0xE80C, 0xE80D, 0xE80E, 0xE80F,
+ /* GB 0xAA40..0xAA7E */
+ 0x72DC, 0x72DD, 0x72DF, 0x72E2, 0x72E3, 0x72E4, 0x72E5, 0x72E6,
+ 0x72E7, 0x72EA, 0x72EB, 0x72F5, 0x72F6, 0x72F9, 0x72FD, 0x72FE,
+ 0x72FF, 0x7300, 0x7302, 0x7304, 0x7305, 0x7306, 0x7307, 0x7308,
+ 0x7309, 0x730B, 0x730C, 0x730D, 0x730F, 0x7310, 0x7311, 0x7312,
+ 0x7314, 0x7318, 0x7319, 0x731A, 0x731F, 0x7320, 0x7323, 0x7324,
+ 0x7326, 0x7327, 0x7328, 0x732D, 0x732F, 0x7330, 0x7332, 0x7333,
+ 0x7335, 0x7336, 0x733A, 0x733B, 0x733C, 0x733D, 0x7340, 0x7341,
+ 0x7342, 0x7343, 0x7344, 0x7345, 0x7346, 0x7347, 0x7348,
+ /* GB 0xAA80..0xAAA0 */
+ 0x7349, 0x734A, 0x734B, 0x734C, 0x734E, 0x734F, 0x7351, 0x7353,
+ 0x7354, 0x7355, 0x7356, 0x7358, 0x7359, 0x735A, 0x735B, 0x735C,
+ 0x735D, 0x735E, 0x735F, 0x7361, 0x7362, 0x7363, 0x7364, 0x7365,
+ 0x7366, 0x7367, 0x7368, 0x7369, 0x736A, 0x736B, 0x736E, 0x7370,
+ 0x7371, /* Skip: GB 0xAAA1..0xAAFE (UDA 1) */
+ /* GB 0xAB40..0xAB7E */
+ 0x7372, 0x7373, 0x7374, 0x7375, 0x7376, 0x7377, 0x7378, 0x7379,
+ 0x737A, 0x737B, 0x737C, 0x737D, 0x737F, 0x7380, 0x7381, 0x7382,
+ 0x7383, 0x7385, 0x7386, 0x7388, 0x738A, 0x738C, 0x738D, 0x738F,
+ 0x7390, 0x7392, 0x7393, 0x7394, 0x7395, 0x7397, 0x7398, 0x7399,
+ 0x739A, 0x739C, 0x739D, 0x739E, 0x73A0, 0x73A1, 0x73A3, 0x73A4,
+ 0x73A5, 0x73A6, 0x73A7, 0x73A8, 0x73AA, 0x73AC, 0x73AD, 0x73B1,
+ 0x73B4, 0x73B5, 0x73B6, 0x73B8, 0x73B9, 0x73BC, 0x73BD, 0x73BE,
+ 0x73BF, 0x73C1, 0x73C3, 0x73C4, 0x73C5, 0x73C6, 0x73C7,
+ /* GB 0xAB80..0xABA0 */
+ 0x73CB, 0x73CC, 0x73CE, 0x73D2, 0x73D3, 0x73D4, 0x73D5, 0x73D6,
+ 0x73D7, 0x73D8, 0x73DA, 0x73DB, 0x73DC, 0x73DD, 0x73DF, 0x73E1,
+ 0x73E2, 0x73E3, 0x73E4, 0x73E6, 0x73E8, 0x73EA, 0x73EB, 0x73EC,
+ 0x73EE, 0x73EF, 0x73F0, 0x73F1, 0x73F3, 0x73F4, 0x73F5, 0x73F6,
+ 0x73F7, /* Skip: GB 0xABA1..0xABFE (UDA 1) */
+ /* GB 0xAC40..0xAC7E */
+ 0x73F8, 0x73F9, 0x73FA, 0x73FB, 0x73FC, 0x73FD, 0x73FE, 0x73FF,
+ 0x7400, 0x7401, 0x7402, 0x7404, 0x7407, 0x7408, 0x740B, 0x740C,
+ 0x740D, 0x740E, 0x7411, 0x7412, 0x7413, 0x7414, 0x7415, 0x7416,
+ 0x7417, 0x7418, 0x7419, 0x741C, 0x741D, 0x741E, 0x741F, 0x7420,
+ 0x7421, 0x7423, 0x7424, 0x7427, 0x7429, 0x742B, 0x742D, 0x742F,
+ 0x7431, 0x7432, 0x7437, 0x7438, 0x7439, 0x743A, 0x743B, 0x743D,
+ 0x743E, 0x743F, 0x7440, 0x7442, 0x7443, 0x7444, 0x7445, 0x7446,
+ 0x7447, 0x7448, 0x7449, 0x744A, 0x744B, 0x744C, 0x744D,
+ /* GB 0xAC80..0xACA0 */
+ 0x744E, 0x744F, 0x7450, 0x7451, 0x7452, 0x7453, 0x7454, 0x7456,
+ 0x7458, 0x745D, 0x7460, 0x7461, 0x7462, 0x7463, 0x7464, 0x7465,
+ 0x7466, 0x7467, 0x7468, 0x7469, 0x746A, 0x746B, 0x746C, 0x746E,
+ 0x746F, 0x7471, 0x7472, 0x7473, 0x7474, 0x7475, 0x7478, 0x7479,
+ 0x747A, /* Skip: GB 0xACA1..0xACFE (UDA 1) */
+ /* GB 0xAD40..0xAD7E */
+ 0x747B, 0x747C, 0x747D, 0x747F, 0x7482, 0x7484, 0x7485, 0x7486,
+ 0x7488, 0x7489, 0x748A, 0x748C, 0x748D, 0x748F, 0x7491, 0x7492,
+ 0x7493, 0x7494, 0x7495, 0x7496, 0x7497, 0x7498, 0x7499, 0x749A,
+ 0x749B, 0x749D, 0x749F, 0x74A0, 0x74A1, 0x74A2, 0x74A3, 0x74A4,
+ 0x74A5, 0x74A6, 0x74AA, 0x74AB, 0x74AC, 0x74AD, 0x74AE, 0x74AF,
+ 0x74B0, 0x74B1, 0x74B2, 0x74B3, 0x74B4, 0x74B5, 0x74B6, 0x74B7,
+ 0x74B8, 0x74B9, 0x74BB, 0x74BC, 0x74BD, 0x74BE, 0x74BF, 0x74C0,
+ 0x74C1, 0x74C2, 0x74C3, 0x74C4, 0x74C5, 0x74C6, 0x74C7,
+ /* GB 0xAD80..0xADA0 */
+ 0x74C8, 0x74C9, 0x74CA, 0x74CB, 0x74CC, 0x74CD, 0x74CE, 0x74CF,
+ 0x74D0, 0x74D1, 0x74D3, 0x74D4, 0x74D5, 0x74D6, 0x74D7, 0x74D8,
+ 0x74D9, 0x74DA, 0x74DB, 0x74DD, 0x74DF, 0x74E1, 0x74E5, 0x74E7,
+ 0x74E8, 0x74E9, 0x74EA, 0x74EB, 0x74EC, 0x74ED, 0x74F0, 0x74F1,
+ 0x74F2, /* Skip: GB 0xADA1..0xADFE (UDA 1) */
+ /* GB 0xAE40..0xAE7E */
+ 0x74F3, 0x74F5, 0x74F8, 0x74F9, 0x74FA, 0x74FB, 0x74FC, 0x74FD,
+ 0x74FE, 0x7500, 0x7501, 0x7502, 0x7503, 0x7505, 0x7506, 0x7507,
+ 0x7508, 0x7509, 0x750A, 0x750B, 0x750C, 0x750E, 0x7510, 0x7512,
+ 0x7514, 0x7515, 0x7516, 0x7517, 0x751B, 0x751D, 0x751E, 0x7520,
+ 0x7521, 0x7522, 0x7523, 0x7524, 0x7526, 0x7527, 0x752A, 0x752E,
+ 0x7534, 0x7536, 0x7539, 0x753C, 0x753D, 0x753F, 0x7541, 0x7542,
+ 0x7543, 0x7544, 0x7546, 0x7547, 0x7549, 0x754A, 0x754D, 0x7550,
+ 0x7551, 0x7552, 0x7553, 0x7555, 0x7556, 0x7557, 0x7558,
+ /* GB 0xAE80..0xAEA0 */
+ 0x755D, 0x755E, 0x755F, 0x7560, 0x7561, 0x7562, 0x7563, 0x7564,
+ 0x7567, 0x7568, 0x7569, 0x756B, 0x756C, 0x756D, 0x756E, 0x756F,
+ 0x7570, 0x7571, 0x7573, 0x7575, 0x7576, 0x7577, 0x757A, 0x757B,
+ 0x757C, 0x757D, 0x757E, 0x7580, 0x7581, 0x7582, 0x7584, 0x7585,
+ 0x7587, /* Skip: GB 0xAEA1..0xAEFE (UDA 1) */
+ /* GB 0xAF40..0xAF7E */
+ 0x7588, 0x7589, 0x758A, 0x758C, 0x758D, 0x758E, 0x7590, 0x7593,
+ 0x7595, 0x7598, 0x759B, 0x759C, 0x759E, 0x75A2, 0x75A6, 0x75A7,
+ 0x75A8, 0x75A9, 0x75AA, 0x75AD, 0x75B6, 0x75B7, 0x75BA, 0x75BB,
+ 0x75BF, 0x75C0, 0x75C1, 0x75C6, 0x75CB, 0x75CC, 0x75CE, 0x75CF,
+ 0x75D0, 0x75D1, 0x75D3, 0x75D7, 0x75D9, 0x75DA, 0x75DC, 0x75DD,
+ 0x75DF, 0x75E0, 0x75E1, 0x75E5, 0x75E9, 0x75EC, 0x75ED, 0x75EE,
+ 0x75EF, 0x75F2, 0x75F3, 0x75F5, 0x75F6, 0x75F7, 0x75F8, 0x75FA,
+ 0x75FB, 0x75FD, 0x75FE, 0x7602, 0x7604, 0x7606, 0x7607,
+ /* GB 0xAF80..0xAFA0 */
+ 0x7608, 0x7609, 0x760B, 0x760D, 0x760E, 0x760F, 0x7611, 0x7612,
+ 0x7613, 0x7614, 0x7616, 0x761A, 0x761C, 0x761D, 0x761E, 0x7621,
+ 0x7623, 0x7627, 0x7628, 0x762C, 0x762E, 0x762F, 0x7631, 0x7632,
+ 0x7636, 0x7637, 0x7639, 0x763A, 0x763B, 0x763D, 0x7641, 0x7642,
+ 0x7644, /* Skip: GB 0xAFA1..0xAFFE (UDA 1) */
+ /* GB 0xB040..0xB07E */
+ 0x7645, 0x7646, 0x7647, 0x7648, 0x7649, 0x764A, 0x764B, 0x764E,
+ 0x764F, 0x7650, 0x7651, 0x7652, 0x7653, 0x7655, 0x7657, 0x7658,
+ 0x7659, 0x765A, 0x765B, 0x765D, 0x765F, 0x7660, 0x7661, 0x7662,
+ 0x7664, 0x7665, 0x7666, 0x7667, 0x7668, 0x7669, 0x766A, 0x766C,
+ 0x766D, 0x766E, 0x7670, 0x7671, 0x7672, 0x7673, 0x7674, 0x7675,
+ 0x7676, 0x7677, 0x7679, 0x767A, 0x767C, 0x767F, 0x7680, 0x7681,
+ 0x7683, 0x7685, 0x7689, 0x768A, 0x768C, 0x768D, 0x768F, 0x7690,
+ 0x7692, 0x7694, 0x7695, 0x7697, 0x7698, 0x769A, 0x769B,
+ /* GB 0xB080..0xB0FE */
+ 0x769C, 0x769D, 0x769E, 0x769F, 0x76A0, 0x76A1, 0x76A2, 0x76A3,
+ 0x76A5, 0x76A6, 0x76A7, 0x76A8, 0x76A9, 0x76AA, 0x76AB, 0x76AC,
+ 0x76AD, 0x76AF, 0x76B0, 0x76B3, 0x76B5, 0x76B6, 0x76B7, 0x76B8,
+ 0x76B9, 0x76BA, 0x76BB, 0x76BC, 0x76BD, 0x76BE, 0x76C0, 0x76C1,
+ 0x76C3, 0x554A, 0x963F, 0x57C3, 0x6328, 0x54CE, 0x5509, 0x54C0,
+ 0x7691, 0x764C, 0x853C, 0x77EE, 0x827E, 0x788D, 0x7231, 0x9698,
+ 0x978D, 0x6C28, 0x5B89, 0x4FFA, 0x6309, 0x6697, 0x5CB8, 0x80FA,
+ 0x6848, 0x80AE, 0x6602, 0x76CE, 0x51F9, 0x6556, 0x71AC, 0x7FF1,
+ 0x8884, 0x50B2, 0x5965, 0x61CA, 0x6FB3, 0x82AD, 0x634C, 0x6252,
+ 0x53ED, 0x5427, 0x7B06, 0x516B, 0x75A4, 0x5DF4, 0x62D4, 0x8DCB,
+ 0x9776, 0x628A, 0x8019, 0x575D, 0x9738, 0x7F62, 0x7238, 0x767D,
+ 0x67CF, 0x767E, 0x6446, 0x4F70, 0x8D25, 0x62DC, 0x7A17, 0x6591,
+ 0x73ED, 0x642C, 0x6273, 0x822C, 0x9881, 0x677F, 0x7248, 0x626E,
+ 0x62CC, 0x4F34, 0x74E3, 0x534A, 0x529E, 0x7ECA, 0x90A6, 0x5E2E,
+ 0x6886, 0x699C, 0x8180, 0x7ED1, 0x68D2, 0x78C5, 0x868C, 0x9551,
+ 0x508D, 0x8C24, 0x82DE, 0x80DE, 0x5305, 0x8912, 0x5265,
+ /* GB 0xB140..0xB17E */
+ 0x76C4, 0x76C7, 0x76C9, 0x76CB, 0x76CC, 0x76D3, 0x76D5, 0x76D9,
+ 0x76DA, 0x76DC, 0x76DD, 0x76DE, 0x76E0, 0x76E1, 0x76E2, 0x76E3,
+ 0x76E4, 0x76E6, 0x76E7, 0x76E8, 0x76E9, 0x76EA, 0x76EB, 0x76EC,
+ 0x76ED, 0x76F0, 0x76F3, 0x76F5, 0x76F6, 0x76F7, 0x76FA, 0x76FB,
+ 0x76FD, 0x76FF, 0x7700, 0x7702, 0x7703, 0x7705, 0x7706, 0x770A,
+ 0x770C, 0x770E, 0x770F, 0x7710, 0x7711, 0x7712, 0x7713, 0x7714,
+ 0x7715, 0x7716, 0x7717, 0x7718, 0x771B, 0x771C, 0x771D, 0x771E,
+ 0x7721, 0x7723, 0x7724, 0x7725, 0x7727, 0x772A, 0x772B,
+ /* GB 0xB180..0xB1FE */
+ 0x772C, 0x772E, 0x7730, 0x7731, 0x7732, 0x7733, 0x7734, 0x7739,
+ 0x773B, 0x773D, 0x773E, 0x773F, 0x7742, 0x7744, 0x7745, 0x7746,
+ 0x7748, 0x7749, 0x774A, 0x774B, 0x774C, 0x774D, 0x774E, 0x774F,
+ 0x7752, 0x7753, 0x7754, 0x7755, 0x7756, 0x7757, 0x7758, 0x7759,
+ 0x775C, 0x8584, 0x96F9, 0x4FDD, 0x5821, 0x9971, 0x5B9D, 0x62B1,
+ 0x62A5, 0x66B4, 0x8C79, 0x9C8D, 0x7206, 0x676F, 0x7891, 0x60B2,
+ 0x5351, 0x5317, 0x8F88, 0x80CC, 0x8D1D, 0x94A1, 0x500D, 0x72C8,
+ 0x5907, 0x60EB, 0x7119, 0x88AB, 0x5954, 0x82EF, 0x672C, 0x7B28,
+ 0x5D29, 0x7EF7, 0x752D, 0x6CF5, 0x8E66, 0x8FF8, 0x903C, 0x9F3B,
+ 0x6BD4, 0x9119, 0x7B14, 0x5F7C, 0x78A7, 0x84D6, 0x853D, 0x6BD5,
+ 0x6BD9, 0x6BD6, 0x5E01, 0x5E87, 0x75F9, 0x95ED, 0x655D, 0x5F0A,
+ 0x5FC5, 0x8F9F, 0x58C1, 0x81C2, 0x907F, 0x965B, 0x97AD, 0x8FB9,
+ 0x7F16, 0x8D2C, 0x6241, 0x4FBF, 0x53D8, 0x535E, 0x8FA8, 0x8FA9,
+ 0x8FAB, 0x904D, 0x6807, 0x5F6A, 0x8198, 0x8868, 0x9CD6, 0x618B,
+ 0x522B, 0x762A, 0x5F6C, 0x658C, 0x6FD2, 0x6EE8, 0x5BBE, 0x6448,
+ 0x5175, 0x51B0, 0x67C4, 0x4E19, 0x79C9, 0x997C, 0x70B3,
+ /* GB 0xB240..0xB27E */
+ 0x775D, 0x775E, 0x775F, 0x7760, 0x7764, 0x7767, 0x7769, 0x776A,
+ 0x776D, 0x776E, 0x776F, 0x7770, 0x7771, 0x7772, 0x7773, 0x7774,
+ 0x7775, 0x7776, 0x7777, 0x7778, 0x777A, 0x777B, 0x777C, 0x7781,
+ 0x7782, 0x7783, 0x7786, 0x7787, 0x7788, 0x7789, 0x778A, 0x778B,
+ 0x778F, 0x7790, 0x7793, 0x7794, 0x7795, 0x7796, 0x7797, 0x7798,
+ 0x7799, 0x779A, 0x779B, 0x779C, 0x779D, 0x779E, 0x77A1, 0x77A3,
+ 0x77A4, 0x77A6, 0x77A8, 0x77AB, 0x77AD, 0x77AE, 0x77AF, 0x77B1,
+ 0x77B2, 0x77B4, 0x77B6, 0x77B7, 0x77B8, 0x77B9, 0x77BA,
+ /* GB 0xB280..0xB2FE */
+ 0x77BC, 0x77BE, 0x77C0, 0x77C1, 0x77C2, 0x77C3, 0x77C4, 0x77C5,
+ 0x77C6, 0x77C7, 0x77C8, 0x77C9, 0x77CA, 0x77CB, 0x77CC, 0x77CE,
+ 0x77CF, 0x77D0, 0x77D1, 0x77D2, 0x77D3, 0x77D4, 0x77D5, 0x77D6,
+ 0x77D8, 0x77D9, 0x77DA, 0x77DD, 0x77DE, 0x77DF, 0x77E0, 0x77E1,
+ 0x77E4, 0x75C5, 0x5E76, 0x73BB, 0x83E0, 0x64AD, 0x62E8, 0x94B5,
+ 0x6CE2, 0x535A, 0x52C3, 0x640F, 0x94C2, 0x7B94, 0x4F2F, 0x5E1B,
+ 0x8236, 0x8116, 0x818A, 0x6E24, 0x6CCA, 0x9A73, 0x6355, 0x535C,
+ 0x54FA, 0x8865, 0x57E0, 0x4E0D, 0x5E03, 0x6B65, 0x7C3F, 0x90E8,
+ 0x6016, 0x64E6, 0x731C, 0x88C1, 0x6750, 0x624D, 0x8D22, 0x776C,
+ 0x8E29, 0x91C7, 0x5F69, 0x83DC, 0x8521, 0x9910, 0x53C2, 0x8695,
+ 0x6B8B, 0x60ED, 0x60E8, 0x707F, 0x82CD, 0x8231, 0x4ED3, 0x6CA7,
+ 0x85CF, 0x64CD, 0x7CD9, 0x69FD, 0x66F9, 0x8349, 0x5395, 0x7B56,
+ 0x4FA7, 0x518C, 0x6D4B, 0x5C42, 0x8E6D, 0x63D2, 0x53C9, 0x832C,
+ 0x8336, 0x67E5, 0x78B4, 0x643D, 0x5BDF, 0x5C94, 0x5DEE, 0x8BE7,
+ 0x62C6, 0x67F4, 0x8C7A, 0x6400, 0x63BA, 0x8749, 0x998B, 0x8C17,
+ 0x7F20, 0x94F2, 0x4EA7, 0x9610, 0x98A4, 0x660C, 0x7316,
+ /* GB 0xB340..0xB37E */
+ 0x77E6, 0x77E8, 0x77EA, 0x77EF, 0x77F0, 0x77F1, 0x77F2, 0x77F4,
+ 0x77F5, 0x77F7, 0x77F9, 0x77FA, 0x77FB, 0x77FC, 0x7803, 0x7804,
+ 0x7805, 0x7806, 0x7807, 0x7808, 0x780A, 0x780B, 0x780E, 0x780F,
+ 0x7810, 0x7813, 0x7815, 0x7819, 0x781B, 0x781E, 0x7820, 0x7821,
+ 0x7822, 0x7824, 0x7828, 0x782A, 0x782B, 0x782E, 0x782F, 0x7831,
+ 0x7832, 0x7833, 0x7835, 0x7836, 0x783D, 0x783F, 0x7841, 0x7842,
+ 0x7843, 0x7844, 0x7846, 0x7848, 0x7849, 0x784A, 0x784B, 0x784D,
+ 0x784F, 0x7851, 0x7853, 0x7854, 0x7858, 0x7859, 0x785A,
+ /* GB 0xB380..0xB3FE */
+ 0x785B, 0x785C, 0x785E, 0x785F, 0x7860, 0x7861, 0x7862, 0x7863,
+ 0x7864, 0x7865, 0x7866, 0x7867, 0x7868, 0x7869, 0x786F, 0x7870,
+ 0x7871, 0x7872, 0x7873, 0x7874, 0x7875, 0x7876, 0x7878, 0x7879,
+ 0x787A, 0x787B, 0x787D, 0x787E, 0x787F, 0x7880, 0x7881, 0x7882,
+ 0x7883, 0x573A, 0x5C1D, 0x5E38, 0x957F, 0x507F, 0x80A0, 0x5382,
+ 0x655E, 0x7545, 0x5531, 0x5021, 0x8D85, 0x6284, 0x949E, 0x671D,
+ 0x5632, 0x6F6E, 0x5DE2, 0x5435, 0x7092, 0x8F66, 0x626F, 0x64A4,
+ 0x63A3, 0x5F7B, 0x6F88, 0x90F4, 0x81E3, 0x8FB0, 0x5C18, 0x6668,
+ 0x5FF1, 0x6C89, 0x9648, 0x8D81, 0x886C, 0x6491, 0x79F0, 0x57CE,
+ 0x6A59, 0x6210, 0x5448, 0x4E58, 0x7A0B, 0x60E9, 0x6F84, 0x8BDA,
+ 0x627F, 0x901E, 0x9A8B, 0x79E4, 0x5403, 0x75F4, 0x6301, 0x5319,
+ 0x6C60, 0x8FDF, 0x5F1B, 0x9A70, 0x803B, 0x9F7F, 0x4F88, 0x5C3A,
+ 0x8D64, 0x7FC5, 0x65A5, 0x70BD, 0x5145, 0x51B2, 0x866B, 0x5D07,
+ 0x5BA0, 0x62BD, 0x916C, 0x7574, 0x8E0C, 0x7A20, 0x6101, 0x7B79,
+ 0x4EC7, 0x7EF8, 0x7785, 0x4E11, 0x81ED, 0x521D, 0x51FA, 0x6A71,
+ 0x53A8, 0x8E87, 0x9504, 0x96CF, 0x6EC1, 0x9664, 0x695A,
+ /* GB 0xB440..0xB47E */
+ 0x7884, 0x7885, 0x7886, 0x7888, 0x788A, 0x788B, 0x788F, 0x7890,
+ 0x7892, 0x7894, 0x7895, 0x7896, 0x7899, 0x789D, 0x789E, 0x78A0,
+ 0x78A2, 0x78A4, 0x78A6, 0x78A8, 0x78A9, 0x78AA, 0x78AB, 0x78AC,
+ 0x78AD, 0x78AE, 0x78AF, 0x78B5, 0x78B6, 0x78B7, 0x78B8, 0x78BA,
+ 0x78BB, 0x78BC, 0x78BD, 0x78BF, 0x78C0, 0x78C2, 0x78C3, 0x78C4,
+ 0x78C6, 0x78C7, 0x78C8, 0x78CC, 0x78CD, 0x78CE, 0x78CF, 0x78D1,
+ 0x78D2, 0x78D3, 0x78D6, 0x78D7, 0x78D8, 0x78DA, 0x78DB, 0x78DC,
+ 0x78DD, 0x78DE, 0x78DF, 0x78E0, 0x78E1, 0x78E2, 0x78E3,
+ /* GB 0xB480..0xB4FE */
+ 0x78E4, 0x78E5, 0x78E6, 0x78E7, 0x78E9, 0x78EA, 0x78EB, 0x78ED,
+ 0x78EE, 0x78EF, 0x78F0, 0x78F1, 0x78F3, 0x78F5, 0x78F6, 0x78F8,
+ 0x78F9, 0x78FB, 0x78FC, 0x78FD, 0x78FE, 0x78FF, 0x7900, 0x7902,
+ 0x7903, 0x7904, 0x7906, 0x7907, 0x7908, 0x7909, 0x790A, 0x790B,
+ 0x790C, 0x7840, 0x50A8, 0x77D7, 0x6410, 0x89E6, 0x5904, 0x63E3,
+ 0x5DDD, 0x7A7F, 0x693D, 0x4F20, 0x8239, 0x5598, 0x4E32, 0x75AE,
+ 0x7A97, 0x5E62, 0x5E8A, 0x95EF, 0x521B, 0x5439, 0x708A, 0x6376,
+ 0x9524, 0x5782, 0x6625, 0x693F, 0x9187, 0x5507, 0x6DF3, 0x7EAF,
+ 0x8822, 0x6233, 0x7EF0, 0x75B5, 0x8328, 0x78C1, 0x96CC, 0x8F9E,
+ 0x6148, 0x74F7, 0x8BCD, 0x6B64, 0x523A, 0x8D50, 0x6B21, 0x806A,
+ 0x8471, 0x56F1, 0x5306, 0x4ECE, 0x4E1B, 0x51D1, 0x7C97, 0x918B,
+ 0x7C07, 0x4FC3, 0x8E7F, 0x7BE1, 0x7A9C, 0x6467, 0x5D14, 0x50AC,
+ 0x8106, 0x7601, 0x7CB9, 0x6DEC, 0x7FE0, 0x6751, 0x5B58, 0x5BF8,
+ 0x78CB, 0x64AE, 0x6413, 0x63AA, 0x632B, 0x9519, 0x642D, 0x8FBE,
+ 0x7B54, 0x7629, 0x6253, 0x5927, 0x5446, 0x6B79, 0x50A3, 0x6234,
+ 0x5E26, 0x6B86, 0x4EE3, 0x8D37, 0x888B, 0x5F85, 0x902E,
+ /* GB 0xB540..0xB57E */
+ 0x790D, 0x790E, 0x790F, 0x7910, 0x7911, 0x7912, 0x7914, 0x7915,
+ 0x7916, 0x7917, 0x7918, 0x7919, 0x791A, 0x791B, 0x791C, 0x791D,
+ 0x791F, 0x7920, 0x7921, 0x7922, 0x7923, 0x7925, 0x7926, 0x7927,
+ 0x7928, 0x7929, 0x792A, 0x792B, 0x792C, 0x792D, 0x792E, 0x792F,
+ 0x7930, 0x7931, 0x7932, 0x7933, 0x7935, 0x7936, 0x7937, 0x7938,
+ 0x7939, 0x793D, 0x793F, 0x7942, 0x7943, 0x7944, 0x7945, 0x7947,
+ 0x794A, 0x794B, 0x794C, 0x794D, 0x794E, 0x794F, 0x7950, 0x7951,
+ 0x7952, 0x7954, 0x7955, 0x7958, 0x7959, 0x7961, 0x7963,
+ /* GB 0xB580..0xB5FE */
+ 0x7964, 0x7966, 0x7969, 0x796A, 0x796B, 0x796C, 0x796E, 0x7970,
+ 0x7971, 0x7972, 0x7973, 0x7974, 0x7975, 0x7976, 0x7979, 0x797B,
+ 0x797C, 0x797D, 0x797E, 0x797F, 0x7982, 0x7983, 0x7986, 0x7987,
+ 0x7988, 0x7989, 0x798B, 0x798C, 0x798D, 0x798E, 0x7990, 0x7991,
+ 0x7992, 0x6020, 0x803D, 0x62C5, 0x4E39, 0x5355, 0x90F8, 0x63B8,
+ 0x80C6, 0x65E6, 0x6C2E, 0x4F46, 0x60EE, 0x6DE1, 0x8BDE, 0x5F39,
+ 0x86CB, 0x5F53, 0x6321, 0x515A, 0x8361, 0x6863, 0x5200, 0x6363,
+ 0x8E48, 0x5012, 0x5C9B, 0x7977, 0x5BFC, 0x5230, 0x7A3B, 0x60BC,
+ 0x9053, 0x76D7, 0x5FB7, 0x5F97, 0x7684, 0x8E6C, 0x706F, 0x767B,
+ 0x7B49, 0x77AA, 0x51F3, 0x9093, 0x5824, 0x4F4E, 0x6EF4, 0x8FEA,
+ 0x654C, 0x7B1B, 0x72C4, 0x6DA4, 0x7FDF, 0x5AE1, 0x62B5, 0x5E95,
+ 0x5730, 0x8482, 0x7B2C, 0x5E1D, 0x5F1F, 0x9012, 0x7F14, 0x98A0,
+ 0x6382, 0x6EC7, 0x7898, 0x70B9, 0x5178, 0x975B, 0x57AB, 0x7535,
+ 0x4F43, 0x7538, 0x5E97, 0x60E6, 0x5960, 0x6DC0, 0x6BBF, 0x7889,
+ 0x53FC, 0x96D5, 0x51CB, 0x5201, 0x6389, 0x540A, 0x9493, 0x8C03,
+ 0x8DCC, 0x7239, 0x789F, 0x8776, 0x8FED, 0x8C0D, 0x53E0,
+ /* GB 0xB640..0xB67E */
+ 0x7993, 0x7994, 0x7995, 0x7996, 0x7997, 0x7998, 0x7999, 0x799B,
+ 0x799C, 0x799D, 0x799E, 0x799F, 0x79A0, 0x79A1, 0x79A2, 0x79A3,
+ 0x79A4, 0x79A5, 0x79A6, 0x79A8, 0x79A9, 0x79AA, 0x79AB, 0x79AC,
+ 0x79AD, 0x79AE, 0x79AF, 0x79B0, 0x79B1, 0x79B2, 0x79B4, 0x79B5,
+ 0x79B6, 0x79B7, 0x79B8, 0x79BC, 0x79BF, 0x79C2, 0x79C4, 0x79C5,
+ 0x79C7, 0x79C8, 0x79CA, 0x79CC, 0x79CE, 0x79CF, 0x79D0, 0x79D3,
+ 0x79D4, 0x79D6, 0x79D7, 0x79D9, 0x79DA, 0x79DB, 0x79DC, 0x79DD,
+ 0x79DE, 0x79E0, 0x79E1, 0x79E2, 0x79E5, 0x79E8, 0x79EA,
+ /* GB 0xB680..0xB6FE */
+ 0x79EC, 0x79EE, 0x79F1, 0x79F2, 0x79F3, 0x79F4, 0x79F5, 0x79F6,
+ 0x79F7, 0x79F9, 0x79FA, 0x79FC, 0x79FE, 0x79FF, 0x7A01, 0x7A04,
+ 0x7A05, 0x7A07, 0x7A08, 0x7A09, 0x7A0A, 0x7A0C, 0x7A0F, 0x7A10,
+ 0x7A11, 0x7A12, 0x7A13, 0x7A15, 0x7A16, 0x7A18, 0x7A19, 0x7A1B,
+ 0x7A1C, 0x4E01, 0x76EF, 0x53EE, 0x9489, 0x9876, 0x9F0E, 0x952D,
+ 0x5B9A, 0x8BA2, 0x4E22, 0x4E1C, 0x51AC, 0x8463, 0x61C2, 0x52A8,
+ 0x680B, 0x4F97, 0x606B, 0x51BB, 0x6D1E, 0x515C, 0x6296, 0x6597,
+ 0x9661, 0x8C46, 0x9017, 0x75D8, 0x90FD, 0x7763, 0x6BD2, 0x728A,
+ 0x72EC, 0x8BFB, 0x5835, 0x7779, 0x8D4C, 0x675C, 0x9540, 0x809A,
+ 0x5EA6, 0x6E21, 0x5992, 0x7AEF, 0x77ED, 0x953B, 0x6BB5, 0x65AD,
+ 0x7F0E, 0x5806, 0x5151, 0x961F, 0x5BF9, 0x58A9, 0x5428, 0x8E72,
+ 0x6566, 0x987F, 0x56E4, 0x949D, 0x76FE, 0x9041, 0x6387, 0x54C6,
+ 0x591A, 0x593A, 0x579B, 0x8EB2, 0x6735, 0x8DFA, 0x8235, 0x5241,
+ 0x60F0, 0x5815, 0x86FE, 0x5CE8, 0x9E45, 0x4FC4, 0x989D, 0x8BB9,
+ 0x5A25, 0x6076, 0x5384, 0x627C, 0x904F, 0x9102, 0x997F, 0x6069,
+ 0x800C, 0x513F, 0x8033, 0x5C14, 0x9975, 0x6D31, 0x4E8C,
+ /* GB 0xB740..0xB77E */
+ 0x7A1D, 0x7A1F, 0x7A21, 0x7A22, 0x7A24, 0x7A25, 0x7A26, 0x7A27,
+ 0x7A28, 0x7A29, 0x7A2A, 0x7A2B, 0x7A2C, 0x7A2D, 0x7A2E, 0x7A2F,
+ 0x7A30, 0x7A31, 0x7A32, 0x7A34, 0x7A35, 0x7A36, 0x7A38, 0x7A3A,
+ 0x7A3E, 0x7A40, 0x7A41, 0x7A42, 0x7A43, 0x7A44, 0x7A45, 0x7A47,
+ 0x7A48, 0x7A49, 0x7A4A, 0x7A4B, 0x7A4C, 0x7A4D, 0x7A4E, 0x7A4F,
+ 0x7A50, 0x7A52, 0x7A53, 0x7A54, 0x7A55, 0x7A56, 0x7A58, 0x7A59,
+ 0x7A5A, 0x7A5B, 0x7A5C, 0x7A5D, 0x7A5E, 0x7A5F, 0x7A60, 0x7A61,
+ 0x7A62, 0x7A63, 0x7A64, 0x7A65, 0x7A66, 0x7A67, 0x7A68,
+ /* GB 0xB780..0xB7FE */
+ 0x7A69, 0x7A6A, 0x7A6B, 0x7A6C, 0x7A6D, 0x7A6E, 0x7A6F, 0x7A71,
+ 0x7A72, 0x7A73, 0x7A75, 0x7A7B, 0x7A7C, 0x7A7D, 0x7A7E, 0x7A82,
+ 0x7A85, 0x7A87, 0x7A89, 0x7A8A, 0x7A8B, 0x7A8C, 0x7A8E, 0x7A8F,
+ 0x7A90, 0x7A93, 0x7A94, 0x7A99, 0x7A9A, 0x7A9B, 0x7A9E, 0x7AA1,
+ 0x7AA2, 0x8D30, 0x53D1, 0x7F5A, 0x7B4F, 0x4F10, 0x4E4F, 0x9600,
+ 0x6CD5, 0x73D0, 0x85E9, 0x5E06, 0x756A, 0x7FFB, 0x6A0A, 0x77FE,
+ 0x9492, 0x7E41, 0x51E1, 0x70E6, 0x53CD, 0x8FD4, 0x8303, 0x8D29,
+ 0x72AF, 0x996D, 0x6CDB, 0x574A, 0x82B3, 0x65B9, 0x80AA, 0x623F,
+ 0x9632, 0x59A8, 0x4EFF, 0x8BBF, 0x7EBA, 0x653E, 0x83F2, 0x975E,
+ 0x5561, 0x98DE, 0x80A5, 0x532A, 0x8BFD, 0x5420, 0x80BA, 0x5E9F,
+ 0x6CB8, 0x8D39, 0x82AC, 0x915A, 0x5429, 0x6C1B, 0x5206, 0x7EB7,
+ 0x575F, 0x711A, 0x6C7E, 0x7C89, 0x594B, 0x4EFD, 0x5FFF, 0x6124,
+ 0x7CAA, 0x4E30, 0x5C01, 0x67AB, 0x8702, 0x5CF0, 0x950B, 0x98CE,
+ 0x75AF, 0x70FD, 0x9022, 0x51AF, 0x7F1D, 0x8BBD, 0x5949, 0x51E4,
+ 0x4F5B, 0x5426, 0x592B, 0x6577, 0x80A4, 0x5B75, 0x6276, 0x62C2,
+ 0x8F90, 0x5E45, 0x6C1F, 0x7B26, 0x4F0F, 0x4FD8, 0x670D,
+ /* GB 0xB840..0xB87E */
+ 0x7AA3, 0x7AA4, 0x7AA7, 0x7AA9, 0x7AAA, 0x7AAB, 0x7AAE, 0x7AAF,
+ 0x7AB0, 0x7AB1, 0x7AB2, 0x7AB4, 0x7AB5, 0x7AB6, 0x7AB7, 0x7AB8,
+ 0x7AB9, 0x7ABA, 0x7ABB, 0x7ABC, 0x7ABD, 0x7ABE, 0x7AC0, 0x7AC1,
+ 0x7AC2, 0x7AC3, 0x7AC4, 0x7AC5, 0x7AC6, 0x7AC7, 0x7AC8, 0x7AC9,
+ 0x7ACA, 0x7ACC, 0x7ACD, 0x7ACE, 0x7ACF, 0x7AD0, 0x7AD1, 0x7AD2,
+ 0x7AD3, 0x7AD4, 0x7AD5, 0x7AD7, 0x7AD8, 0x7ADA, 0x7ADB, 0x7ADC,
+ 0x7ADD, 0x7AE1, 0x7AE2, 0x7AE4, 0x7AE7, 0x7AE8, 0x7AE9, 0x7AEA,
+ 0x7AEB, 0x7AEC, 0x7AEE, 0x7AF0, 0x7AF1, 0x7AF2, 0x7AF3,
+ /* GB 0xB880..0xB8FE */
+ 0x7AF4, 0x7AF5, 0x7AF6, 0x7AF7, 0x7AF8, 0x7AFB, 0x7AFC, 0x7AFE,
+ 0x7B00, 0x7B01, 0x7B02, 0x7B05, 0x7B07, 0x7B09, 0x7B0C, 0x7B0D,
+ 0x7B0E, 0x7B10, 0x7B12, 0x7B13, 0x7B16, 0x7B17, 0x7B18, 0x7B1A,
+ 0x7B1C, 0x7B1D, 0x7B1F, 0x7B21, 0x7B22, 0x7B23, 0x7B27, 0x7B29,
+ 0x7B2D, 0x6D6E, 0x6DAA, 0x798F, 0x88B1, 0x5F17, 0x752B, 0x629A,
+ 0x8F85, 0x4FEF, 0x91DC, 0x65A7, 0x812F, 0x8151, 0x5E9C, 0x8150,
+ 0x8D74, 0x526F, 0x8986, 0x8D4B, 0x590D, 0x5085, 0x4ED8, 0x961C,
+ 0x7236, 0x8179, 0x8D1F, 0x5BCC, 0x8BA3, 0x9644, 0x5987, 0x7F1A,
+ 0x5490, 0x5676, 0x560E, 0x8BE5, 0x6539, 0x6982, 0x9499, 0x76D6,
+ 0x6E89, 0x5E72, 0x7518, 0x6746, 0x67D1, 0x7AFF, 0x809D, 0x8D76,
+ 0x611F, 0x79C6, 0x6562, 0x8D63, 0x5188, 0x521A, 0x94A2, 0x7F38,
+ 0x809B, 0x7EB2, 0x5C97, 0x6E2F, 0x6760, 0x7BD9, 0x768B, 0x9AD8,
+ 0x818F, 0x7F94, 0x7CD5, 0x641E, 0x9550, 0x7A3F, 0x544A, 0x54E5,
+ 0x6B4C, 0x6401, 0x6208, 0x9E3D, 0x80F3, 0x7599, 0x5272, 0x9769,
+ 0x845B, 0x683C, 0x86E4, 0x9601, 0x9694, 0x94EC, 0x4E2A, 0x5404,
+ 0x7ED9, 0x6839, 0x8DDF, 0x8015, 0x66F4, 0x5E9A, 0x7FB9,
+ /* GB 0xB940..0xB97E */
+ 0x7B2F, 0x7B30, 0x7B32, 0x7B34, 0x7B35, 0x7B36, 0x7B37, 0x7B39,
+ 0x7B3B, 0x7B3D, 0x7B3F, 0x7B40, 0x7B41, 0x7B42, 0x7B43, 0x7B44,
+ 0x7B46, 0x7B48, 0x7B4A, 0x7B4D, 0x7B4E, 0x7B53, 0x7B55, 0x7B57,
+ 0x7B59, 0x7B5C, 0x7B5E, 0x7B5F, 0x7B61, 0x7B63, 0x7B64, 0x7B65,
+ 0x7B66, 0x7B67, 0x7B68, 0x7B69, 0x7B6A, 0x7B6B, 0x7B6C, 0x7B6D,
+ 0x7B6F, 0x7B70, 0x7B73, 0x7B74, 0x7B76, 0x7B78, 0x7B7A, 0x7B7C,
+ 0x7B7D, 0x7B7F, 0x7B81, 0x7B82, 0x7B83, 0x7B84, 0x7B86, 0x7B87,
+ 0x7B88, 0x7B89, 0x7B8A, 0x7B8B, 0x7B8C, 0x7B8E, 0x7B8F,
+ /* GB 0xB980..0xB9FE */
+ 0x7B91, 0x7B92, 0x7B93, 0x7B96, 0x7B98, 0x7B99, 0x7B9A, 0x7B9B,
+ 0x7B9E, 0x7B9F, 0x7BA0, 0x7BA3, 0x7BA4, 0x7BA5, 0x7BAE, 0x7BAF,
+ 0x7BB0, 0x7BB2, 0x7BB3, 0x7BB5, 0x7BB6, 0x7BB7, 0x7BB9, 0x7BBA,
+ 0x7BBB, 0x7BBC, 0x7BBD, 0x7BBE, 0x7BBF, 0x7BC0, 0x7BC2, 0x7BC3,
+ 0x7BC4, 0x57C2, 0x803F, 0x6897, 0x5DE5, 0x653B, 0x529F, 0x606D,
+ 0x9F9A, 0x4F9B, 0x8EAC, 0x516C, 0x5BAB, 0x5F13, 0x5DE9, 0x6C5E,
+ 0x62F1, 0x8D21, 0x5171, 0x94A9, 0x52FE, 0x6C9F, 0x82DF, 0x72D7,
+ 0x57A2, 0x6784, 0x8D2D, 0x591F, 0x8F9C, 0x83C7, 0x5495, 0x7B8D,
+ 0x4F30, 0x6CBD, 0x5B64, 0x59D1, 0x9F13, 0x53E4, 0x86CA, 0x9AA8,
+ 0x8C37, 0x80A1, 0x6545, 0x987E, 0x56FA, 0x96C7, 0x522E, 0x74DC,
+ 0x5250, 0x5BE1, 0x6302, 0x8902, 0x4E56, 0x62D0, 0x602A, 0x68FA,
+ 0x5173, 0x5B98, 0x51A0, 0x89C2, 0x7BA1, 0x9986, 0x7F50, 0x60EF,
+ 0x704C, 0x8D2F, 0x5149, 0x5E7F, 0x901B, 0x7470, 0x89C4, 0x572D,
+ 0x7845, 0x5F52, 0x9F9F, 0x95FA, 0x8F68, 0x9B3C, 0x8BE1, 0x7678,
+ 0x6842, 0x67DC, 0x8DEA, 0x8D35, 0x523D, 0x8F8A, 0x6EDA, 0x68CD,
+ 0x9505, 0x90ED, 0x56FD, 0x679C, 0x88F9, 0x8FC7, 0x54C8,
+ /* GB 0xBA40..0xBA7E */
+ 0x7BC5, 0x7BC8, 0x7BC9, 0x7BCA, 0x7BCB, 0x7BCD, 0x7BCE, 0x7BCF,
+ 0x7BD0, 0x7BD2, 0x7BD4, 0x7BD5, 0x7BD6, 0x7BD7, 0x7BD8, 0x7BDB,
+ 0x7BDC, 0x7BDE, 0x7BDF, 0x7BE0, 0x7BE2, 0x7BE3, 0x7BE4, 0x7BE7,
+ 0x7BE8, 0x7BE9, 0x7BEB, 0x7BEC, 0x7BED, 0x7BEF, 0x7BF0, 0x7BF2,
+ 0x7BF3, 0x7BF4, 0x7BF5, 0x7BF6, 0x7BF8, 0x7BF9, 0x7BFA, 0x7BFB,
+ 0x7BFD, 0x7BFF, 0x7C00, 0x7C01, 0x7C02, 0x7C03, 0x7C04, 0x7C05,
+ 0x7C06, 0x7C08, 0x7C09, 0x7C0A, 0x7C0D, 0x7C0E, 0x7C10, 0x7C11,
+ 0x7C12, 0x7C13, 0x7C14, 0x7C15, 0x7C17, 0x7C18, 0x7C19,
+ /* GB 0xBA80..0xBAFE */
+ 0x7C1A, 0x7C1B, 0x7C1C, 0x7C1D, 0x7C1E, 0x7C20, 0x7C21, 0x7C22,
+ 0x7C23, 0x7C24, 0x7C25, 0x7C28, 0x7C29, 0x7C2B, 0x7C2C, 0x7C2D,
+ 0x7C2E, 0x7C2F, 0x7C30, 0x7C31, 0x7C32, 0x7C33, 0x7C34, 0x7C35,
+ 0x7C36, 0x7C37, 0x7C39, 0x7C3A, 0x7C3B, 0x7C3C, 0x7C3D, 0x7C3E,
+ 0x7C42, 0x9AB8, 0x5B69, 0x6D77, 0x6C26, 0x4EA5, 0x5BB3, 0x9A87,
+ 0x9163, 0x61A8, 0x90AF, 0x97E9, 0x542B, 0x6DB5, 0x5BD2, 0x51FD,
+ 0x558A, 0x7F55, 0x7FF0, 0x64BC, 0x634D, 0x65F1, 0x61BE, 0x608D,
+ 0x710A, 0x6C57, 0x6C49, 0x592F, 0x676D, 0x822A, 0x58D5, 0x568E,
+ 0x8C6A, 0x6BEB, 0x90DD, 0x597D, 0x8017, 0x53F7, 0x6D69, 0x5475,
+ 0x559D, 0x8377, 0x83CF, 0x6838, 0x79BE, 0x548C, 0x4F55, 0x5408,
+ 0x76D2, 0x8C89, 0x9602, 0x6CB3, 0x6DB8, 0x8D6B, 0x8910, 0x9E64,
+ 0x8D3A, 0x563F, 0x9ED1, 0x75D5, 0x5F88, 0x72E0, 0x6068, 0x54FC,
+ 0x4EA8, 0x6A2A, 0x8861, 0x6052, 0x8F70, 0x54C4, 0x70D8, 0x8679,
+ 0x9E3F, 0x6D2A, 0x5B8F, 0x5F18, 0x7EA2, 0x5589, 0x4FAF, 0x7334,
+ 0x543C, 0x539A, 0x5019, 0x540E, 0x547C, 0x4E4E, 0x5FFD, 0x745A,
+ 0x58F6, 0x846B, 0x80E1, 0x8774, 0x72D0, 0x7CCA, 0x6E56,
+ /* GB 0xBB40..0xBB7E */
+ 0x7C43, 0x7C44, 0x7C45, 0x7C46, 0x7C47, 0x7C48, 0x7C49, 0x7C4A,
+ 0x7C4B, 0x7C4C, 0x7C4E, 0x7C4F, 0x7C50, 0x7C51, 0x7C52, 0x7C53,
+ 0x7C54, 0x7C55, 0x7C56, 0x7C57, 0x7C58, 0x7C59, 0x7C5A, 0x7C5B,
+ 0x7C5C, 0x7C5D, 0x7C5E, 0x7C5F, 0x7C60, 0x7C61, 0x7C62, 0x7C63,
+ 0x7C64, 0x7C65, 0x7C66, 0x7C67, 0x7C68, 0x7C69, 0x7C6A, 0x7C6B,
+ 0x7C6C, 0x7C6D, 0x7C6E, 0x7C6F, 0x7C70, 0x7C71, 0x7C72, 0x7C75,
+ 0x7C76, 0x7C77, 0x7C78, 0x7C79, 0x7C7A, 0x7C7E, 0x7C7F, 0x7C80,
+ 0x7C81, 0x7C82, 0x7C83, 0x7C84, 0x7C85, 0x7C86, 0x7C87,
+ /* GB 0xBB80..0xBBFE */
+ 0x7C88, 0x7C8A, 0x7C8B, 0x7C8C, 0x7C8D, 0x7C8E, 0x7C8F, 0x7C90,
+ 0x7C93, 0x7C94, 0x7C96, 0x7C99, 0x7C9A, 0x7C9B, 0x7CA0, 0x7CA1,
+ 0x7CA3, 0x7CA6, 0x7CA7, 0x7CA8, 0x7CA9, 0x7CAB, 0x7CAC, 0x7CAD,
+ 0x7CAF, 0x7CB0, 0x7CB4, 0x7CB5, 0x7CB6, 0x7CB7, 0x7CB8, 0x7CBA,
+ 0x7CBB, 0x5F27, 0x864E, 0x552C, 0x62A4, 0x4E92, 0x6CAA, 0x6237,
+ 0x82B1, 0x54D7, 0x534E, 0x733E, 0x6ED1, 0x753B, 0x5212, 0x5316,
+ 0x8BDD, 0x69D0, 0x5F8A, 0x6000, 0x6DEE, 0x574F, 0x6B22, 0x73AF,
+ 0x6853, 0x8FD8, 0x7F13, 0x6362, 0x60A3, 0x5524, 0x75EA, 0x8C62,
+ 0x7115, 0x6DA3, 0x5BA6, 0x5E7B, 0x8352, 0x614C, 0x9EC4, 0x78FA,
+ 0x8757, 0x7C27, 0x7687, 0x51F0, 0x60F6, 0x714C, 0x6643, 0x5E4C,
+ 0x604D, 0x8C0E, 0x7070, 0x6325, 0x8F89, 0x5FBD, 0x6062, 0x86D4,
+ 0x56DE, 0x6BC1, 0x6094, 0x6167, 0x5349, 0x60E0, 0x6666, 0x8D3F,
+ 0x79FD, 0x4F1A, 0x70E9, 0x6C47, 0x8BB3, 0x8BF2, 0x7ED8, 0x8364,
+ 0x660F, 0x5A5A, 0x9B42, 0x6D51, 0x6DF7, 0x8C41, 0x6D3B, 0x4F19,
+ 0x706B, 0x83B7, 0x6216, 0x60D1, 0x970D, 0x8D27, 0x7978, 0x51FB,
+ 0x573E, 0x57FA, 0x673A, 0x7578, 0x7A3D, 0x79EF, 0x7B95,
+ /* GB 0xBC40..0xBC7E */
+ 0x7CBF, 0x7CC0, 0x7CC2, 0x7CC3, 0x7CC4, 0x7CC6, 0x7CC9, 0x7CCB,
+ 0x7CCE, 0x7CCF, 0x7CD0, 0x7CD1, 0x7CD2, 0x7CD3, 0x7CD4, 0x7CD8,
+ 0x7CDA, 0x7CDB, 0x7CDD, 0x7CDE, 0x7CE1, 0x7CE2, 0x7CE3, 0x7CE4,
+ 0x7CE5, 0x7CE6, 0x7CE7, 0x7CE9, 0x7CEA, 0x7CEB, 0x7CEC, 0x7CED,
+ 0x7CEE, 0x7CF0, 0x7CF1, 0x7CF2, 0x7CF3, 0x7CF4, 0x7CF5, 0x7CF6,
+ 0x7CF7, 0x7CF9, 0x7CFA, 0x7CFC, 0x7CFD, 0x7CFE, 0x7CFF, 0x7D00,
+ 0x7D01, 0x7D02, 0x7D03, 0x7D04, 0x7D05, 0x7D06, 0x7D07, 0x7D08,
+ 0x7D09, 0x7D0B, 0x7D0C, 0x7D0D, 0x7D0E, 0x7D0F, 0x7D10,
+ /* GB 0xBC80..0xBCFE */
+ 0x7D11, 0x7D12, 0x7D13, 0x7D14, 0x7D15, 0x7D16, 0x7D17, 0x7D18,
+ 0x7D19, 0x7D1A, 0x7D1B, 0x7D1C, 0x7D1D, 0x7D1E, 0x7D1F, 0x7D21,
+ 0x7D23, 0x7D24, 0x7D25, 0x7D26, 0x7D28, 0x7D29, 0x7D2A, 0x7D2C,
+ 0x7D2D, 0x7D2E, 0x7D30, 0x7D31, 0x7D32, 0x7D33, 0x7D34, 0x7D35,
+ 0x7D36, 0x808C, 0x9965, 0x8FF9, 0x6FC0, 0x8BA5, 0x9E21, 0x59EC,
+ 0x7EE9, 0x7F09, 0x5409, 0x6781, 0x68D8, 0x8F91, 0x7C4D, 0x96C6,
+ 0x53CA, 0x6025, 0x75BE, 0x6C72, 0x5373, 0x5AC9, 0x7EA7, 0x6324,
+ 0x51E0, 0x810A, 0x5DF1, 0x84DF, 0x6280, 0x5180, 0x5B63, 0x4F0E,
+ 0x796D, 0x5242, 0x60B8, 0x6D4E, 0x5BC4, 0x5BC2, 0x8BA1, 0x8BB0,
+ 0x65E2, 0x5FCC, 0x9645, 0x5993, 0x7EE7, 0x7EAA, 0x5609, 0x67B7,
+ 0x5939, 0x4F73, 0x5BB6, 0x52A0, 0x835A, 0x988A, 0x8D3E, 0x7532,
+ 0x94BE, 0x5047, 0x7A3C, 0x4EF7, 0x67B6, 0x9A7E, 0x5AC1, 0x6B7C,
+ 0x76D1, 0x575A, 0x5C16, 0x7B3A, 0x95F4, 0x714E, 0x517C, 0x80A9,
+ 0x8270, 0x5978, 0x7F04, 0x8327, 0x68C0, 0x67EC, 0x78B1, 0x7877,
+ 0x62E3, 0x6361, 0x7B80, 0x4FED, 0x526A, 0x51CF, 0x8350, 0x69DB,
+ 0x9274, 0x8DF5, 0x8D31, 0x89C1, 0x952E, 0x7BAD, 0x4EF6,
+ /* GB 0xBD40..0xBD7E */
+ 0x7D37, 0x7D38, 0x7D39, 0x7D3A, 0x7D3B, 0x7D3C, 0x7D3D, 0x7D3E,
+ 0x7D3F, 0x7D40, 0x7D41, 0x7D42, 0x7D43, 0x7D44, 0x7D45, 0x7D46,
+ 0x7D47, 0x7D48, 0x7D49, 0x7D4A, 0x7D4B, 0x7D4C, 0x7D4D, 0x7D4E,
+ 0x7D4F, 0x7D50, 0x7D51, 0x7D52, 0x7D53, 0x7D54, 0x7D55, 0x7D56,
+ 0x7D57, 0x7D58, 0x7D59, 0x7D5A, 0x7D5B, 0x7D5C, 0x7D5D, 0x7D5E,
+ 0x7D5F, 0x7D60, 0x7D61, 0x7D62, 0x7D63, 0x7D64, 0x7D65, 0x7D66,
+ 0x7D67, 0x7D68, 0x7D69, 0x7D6A, 0x7D6B, 0x7D6C, 0x7D6D, 0x7D6F,
+ 0x7D70, 0x7D71, 0x7D72, 0x7D73, 0x7D74, 0x7D75, 0x7D76,
+ /* GB 0xBD80..0xBDFE */
+ 0x7D78, 0x7D79, 0x7D7A, 0x7D7B, 0x7D7C, 0x7D7D, 0x7D7E, 0x7D7F,
+ 0x7D80, 0x7D81, 0x7D82, 0x7D83, 0x7D84, 0x7D85, 0x7D86, 0x7D87,
+ 0x7D88, 0x7D89, 0x7D8A, 0x7D8B, 0x7D8C, 0x7D8D, 0x7D8E, 0x7D8F,
+ 0x7D90, 0x7D91, 0x7D92, 0x7D93, 0x7D94, 0x7D95, 0x7D96, 0x7D97,
+ 0x7D98, 0x5065, 0x8230, 0x5251, 0x996F, 0x6E10, 0x6E85, 0x6DA7,
+ 0x5EFA, 0x50F5, 0x59DC, 0x5C06, 0x6D46, 0x6C5F, 0x7586, 0x848B,
+ 0x6868, 0x5956, 0x8BB2, 0x5320, 0x9171, 0x964D, 0x8549, 0x6912,
+ 0x7901, 0x7126, 0x80F6, 0x4EA4, 0x90CA, 0x6D47, 0x9A84, 0x5A07,
+ 0x56BC, 0x6405, 0x94F0, 0x77EB, 0x4FA5, 0x811A, 0x72E1, 0x89D2,
+ 0x997A, 0x7F34, 0x7EDE, 0x527F, 0x6559, 0x9175, 0x8F7F, 0x8F83,
+ 0x53EB, 0x7A96, 0x63ED, 0x63A5, 0x7686, 0x79F8, 0x8857, 0x9636,
+ 0x622A, 0x52AB, 0x8282, 0x6854, 0x6770, 0x6377, 0x776B, 0x7AED,
+ 0x6D01, 0x7ED3, 0x89E3, 0x59D0, 0x6212, 0x85C9, 0x82A5, 0x754C,
+ 0x501F, 0x4ECB, 0x75A5, 0x8BEB, 0x5C4A, 0x5DFE, 0x7B4B, 0x65A4,
+ 0x91D1, 0x4ECA, 0x6D25, 0x895F, 0x7D27, 0x9526, 0x4EC5, 0x8C28,
+ 0x8FDB, 0x9773, 0x664B, 0x7981, 0x8FD1, 0x70EC, 0x6D78,
+ /* GB 0xBE40..0xBE7E */
+ 0x7D99, 0x7D9A, 0x7D9B, 0x7D9C, 0x7D9D, 0x7D9E, 0x7D9F, 0x7DA0,
+ 0x7DA1, 0x7DA2, 0x7DA3, 0x7DA4, 0x7DA5, 0x7DA7, 0x7DA8, 0x7DA9,
+ 0x7DAA, 0x7DAB, 0x7DAC, 0x7DAD, 0x7DAF, 0x7DB0, 0x7DB1, 0x7DB2,
+ 0x7DB3, 0x7DB4, 0x7DB5, 0x7DB6, 0x7DB7, 0x7DB8, 0x7DB9, 0x7DBA,
+ 0x7DBB, 0x7DBC, 0x7DBD, 0x7DBE, 0x7DBF, 0x7DC0, 0x7DC1, 0x7DC2,
+ 0x7DC3, 0x7DC4, 0x7DC5, 0x7DC6, 0x7DC7, 0x7DC8, 0x7DC9, 0x7DCA,
+ 0x7DCB, 0x7DCC, 0x7DCD, 0x7DCE, 0x7DCF, 0x7DD0, 0x7DD1, 0x7DD2,
+ 0x7DD3, 0x7DD4, 0x7DD5, 0x7DD6, 0x7DD7, 0x7DD8, 0x7DD9,
+ /* GB 0xBE80..0xBEFE */
+ 0x7DDA, 0x7DDB, 0x7DDC, 0x7DDD, 0x7DDE, 0x7DDF, 0x7DE0, 0x7DE1,
+ 0x7DE2, 0x7DE3, 0x7DE4, 0x7DE5, 0x7DE6, 0x7DE7, 0x7DE8, 0x7DE9,
+ 0x7DEA, 0x7DEB, 0x7DEC, 0x7DED, 0x7DEE, 0x7DEF, 0x7DF0, 0x7DF1,
+ 0x7DF2, 0x7DF3, 0x7DF4, 0x7DF5, 0x7DF6, 0x7DF7, 0x7DF8, 0x7DF9,
+ 0x7DFA, 0x5C3D, 0x52B2, 0x8346, 0x5162, 0x830E, 0x775B, 0x6676,
+ 0x9CB8, 0x4EAC, 0x60CA, 0x7CBE, 0x7CB3, 0x7ECF, 0x4E95, 0x8B66,
+ 0x666F, 0x9888, 0x9759, 0x5883, 0x656C, 0x955C, 0x5F84, 0x75C9,
+ 0x9756, 0x7ADF, 0x7ADE, 0x51C0, 0x70AF, 0x7A98, 0x63EA, 0x7A76,
+ 0x7EA0, 0x7396, 0x97ED, 0x4E45, 0x7078, 0x4E5D, 0x9152, 0x53A9,
+ 0x6551, 0x65E7, 0x81FC, 0x8205, 0x548E, 0x5C31, 0x759A, 0x97A0,
+ 0x62D8, 0x72D9, 0x75BD, 0x5C45, 0x9A79, 0x83CA, 0x5C40, 0x5480,
+ 0x77E9, 0x4E3E, 0x6CAE, 0x805A, 0x62D2, 0x636E, 0x5DE8, 0x5177,
+ 0x8DDD, 0x8E1E, 0x952F, 0x4FF1, 0x53E5, 0x60E7, 0x70AC, 0x5267,
+ 0x6350, 0x9E43, 0x5A1F, 0x5026, 0x7737, 0x5377, 0x7EE2, 0x6485,
+ 0x652B, 0x6289, 0x6398, 0x5014, 0x7235, 0x89C9, 0x51B3, 0x8BC0,
+ 0x7EDD, 0x5747, 0x83CC, 0x94A7, 0x519B, 0x541B, 0x5CFB,
+ /* GB 0xBF40..0xBF7E */
+ 0x7DFB, 0x7DFC, 0x7DFD, 0x7DFE, 0x7DFF, 0x7E00, 0x7E01, 0x7E02,
+ 0x7E03, 0x7E04, 0x7E05, 0x7E06, 0x7E07, 0x7E08, 0x7E09, 0x7E0A,
+ 0x7E0B, 0x7E0C, 0x7E0D, 0x7E0E, 0x7E0F, 0x7E10, 0x7E11, 0x7E12,
+ 0x7E13, 0x7E14, 0x7E15, 0x7E16, 0x7E17, 0x7E18, 0x7E19, 0x7E1A,
+ 0x7E1B, 0x7E1C, 0x7E1D, 0x7E1E, 0x7E1F, 0x7E20, 0x7E21, 0x7E22,
+ 0x7E23, 0x7E24, 0x7E25, 0x7E26, 0x7E27, 0x7E28, 0x7E29, 0x7E2A,
+ 0x7E2B, 0x7E2C, 0x7E2D, 0x7E2E, 0x7E2F, 0x7E30, 0x7E31, 0x7E32,
+ 0x7E33, 0x7E34, 0x7E35, 0x7E36, 0x7E37, 0x7E38, 0x7E39,
+ /* GB 0xBF80..0xBFFE */
+ 0x7E3A, 0x7E3C, 0x7E3D, 0x7E3E, 0x7E3F, 0x7E40, 0x7E42, 0x7E43,
+ 0x7E44, 0x7E45, 0x7E46, 0x7E48, 0x7E49, 0x7E4A, 0x7E4B, 0x7E4C,
+ 0x7E4D, 0x7E4E, 0x7E4F, 0x7E50, 0x7E51, 0x7E52, 0x7E53, 0x7E54,
+ 0x7E55, 0x7E56, 0x7E57, 0x7E58, 0x7E59, 0x7E5A, 0x7E5B, 0x7E5C,
+ 0x7E5D, 0x4FCA, 0x7AE3, 0x6D5A, 0x90E1, 0x9A8F, 0x5580, 0x5496,
+ 0x5361, 0x54AF, 0x5F00, 0x63E9, 0x6977, 0x51EF, 0x6168, 0x520A,
+ 0x582A, 0x52D8, 0x574E, 0x780D, 0x770B, 0x5EB7, 0x6177, 0x7CE0,
+ 0x625B, 0x6297, 0x4EA2, 0x7095, 0x8003, 0x62F7, 0x70E4, 0x9760,
+ 0x5777, 0x82DB, 0x67EF, 0x68F5, 0x78D5, 0x9897, 0x79D1, 0x58F3,
+ 0x54B3, 0x53EF, 0x6E34, 0x514B, 0x523B, 0x5BA2, 0x8BFE, 0x80AF,
+ 0x5543, 0x57A6, 0x6073, 0x5751, 0x542D, 0x7A7A, 0x6050, 0x5B54,
+ 0x63A7, 0x62A0, 0x53E3, 0x6263, 0x5BC7, 0x67AF, 0x54ED, 0x7A9F,
+ 0x82E6, 0x9177, 0x5E93, 0x88E4, 0x5938, 0x57AE, 0x630E, 0x8DE8,
+ 0x80EF, 0x5757, 0x7B77, 0x4FA9, 0x5FEB, 0x5BBD, 0x6B3E, 0x5321,
+ 0x7B50, 0x72C2, 0x6846, 0x77FF, 0x7736, 0x65F7, 0x51B5, 0x4E8F,
+ 0x76D4, 0x5CBF, 0x7AA5, 0x8475, 0x594E, 0x9B41, 0x5080,
+ /* GB 0xC040..0xC07E */
+ 0x7E5E, 0x7E5F, 0x7E60, 0x7E61, 0x7E62, 0x7E63, 0x7E64, 0x7E65,
+ 0x7E66, 0x7E67, 0x7E68, 0x7E69, 0x7E6A, 0x7E6B, 0x7E6C, 0x7E6D,
+ 0x7E6E, 0x7E6F, 0x7E70, 0x7E71, 0x7E72, 0x7E73, 0x7E74, 0x7E75,
+ 0x7E76, 0x7E77, 0x7E78, 0x7E79, 0x7E7A, 0x7E7B, 0x7E7C, 0x7E7D,
+ 0x7E7E, 0x7E7F, 0x7E80, 0x7E81, 0x7E83, 0x7E84, 0x7E85, 0x7E86,
+ 0x7E87, 0x7E88, 0x7E89, 0x7E8A, 0x7E8B, 0x7E8C, 0x7E8D, 0x7E8E,
+ 0x7E8F, 0x7E90, 0x7E91, 0x7E92, 0x7E93, 0x7E94, 0x7E95, 0x7E96,
+ 0x7E97, 0x7E98, 0x7E99, 0x7E9A, 0x7E9C, 0x7E9D, 0x7E9E,
+ /* GB 0xC080..0xC0FE */
+ 0x7EAE, 0x7EB4, 0x7EBB, 0x7EBC, 0x7ED6, 0x7EE4, 0x7EEC, 0x7EF9,
+ 0x7F0A, 0x7F10, 0x7F1E, 0x7F37, 0x7F39, 0x7F3B, 0x7F3C, 0x7F3D,
+ 0x7F3E, 0x7F3F, 0x7F40, 0x7F41, 0x7F43, 0x7F46, 0x7F47, 0x7F48,
+ 0x7F49, 0x7F4A, 0x7F4B, 0x7F4C, 0x7F4D, 0x7F4E, 0x7F4F, 0x7F52,
+ 0x7F53, 0x9988, 0x6127, 0x6E83, 0x5764, 0x6606, 0x6346, 0x56F0,
+ 0x62EC, 0x6269, 0x5ED3, 0x9614, 0x5783, 0x62C9, 0x5587, 0x8721,
+ 0x814A, 0x8FA3, 0x5566, 0x83B1, 0x6765, 0x8D56, 0x84DD, 0x5A6A,
+ 0x680F, 0x62E6, 0x7BEE, 0x9611, 0x5170, 0x6F9C, 0x8C30, 0x63FD,
+ 0x89C8, 0x61D2, 0x7F06, 0x70C2, 0x6EE5, 0x7405, 0x6994, 0x72FC,
+ 0x5ECA, 0x90CE, 0x6717, 0x6D6A, 0x635E, 0x52B3, 0x7262, 0x8001,
+ 0x4F6C, 0x59E5, 0x916A, 0x70D9, 0x6D9D, 0x52D2, 0x4E50, 0x96F7,
+ 0x956D, 0x857E, 0x78CA, 0x7D2F, 0x5121, 0x5792, 0x64C2, 0x808B,
+ 0x7C7B, 0x6CEA, 0x68F1, 0x695E, 0x51B7, 0x5398, 0x68A8, 0x7281,
+ 0x9ECE, 0x7BF1, 0x72F8, 0x79BB, 0x6F13, 0x7406, 0x674E, 0x91CC,
+ 0x9CA4, 0x793C, 0x8389, 0x8354, 0x540F, 0x6817, 0x4E3D, 0x5389,
+ 0x52B1, 0x783E, 0x5386, 0x5229, 0x5088, 0x4F8B, 0x4FD0,
+ /* GB 0xC140..0xC17E */
+ 0x7F56, 0x7F59, 0x7F5B, 0x7F5C, 0x7F5D, 0x7F5E, 0x7F60, 0x7F63,
+ 0x7F64, 0x7F65, 0x7F66, 0x7F67, 0x7F6B, 0x7F6C, 0x7F6D, 0x7F6F,
+ 0x7F70, 0x7F73, 0x7F75, 0x7F76, 0x7F77, 0x7F78, 0x7F7A, 0x7F7B,
+ 0x7F7C, 0x7F7D, 0x7F7F, 0x7F80, 0x7F82, 0x7F83, 0x7F84, 0x7F85,
+ 0x7F86, 0x7F87, 0x7F88, 0x7F89, 0x7F8B, 0x7F8D, 0x7F8F, 0x7F90,
+ 0x7F91, 0x7F92, 0x7F93, 0x7F95, 0x7F96, 0x7F97, 0x7F98, 0x7F99,
+ 0x7F9B, 0x7F9C, 0x7FA0, 0x7FA2, 0x7FA3, 0x7FA5, 0x7FA6, 0x7FA8,
+ 0x7FA9, 0x7FAA, 0x7FAB, 0x7FAC, 0x7FAD, 0x7FAE, 0x7FB1,
+ /* GB 0xC180..0xC1FE */
+ 0x7FB3, 0x7FB4, 0x7FB5, 0x7FB6, 0x7FB7, 0x7FBA, 0x7FBB, 0x7FBE,
+ 0x7FC0, 0x7FC2, 0x7FC3, 0x7FC4, 0x7FC6, 0x7FC7, 0x7FC8, 0x7FC9,
+ 0x7FCB, 0x7FCD, 0x7FCF, 0x7FD0, 0x7FD1, 0x7FD2, 0x7FD3, 0x7FD6,
+ 0x7FD7, 0x7FD9, 0x7FDA, 0x7FDB, 0x7FDC, 0x7FDD, 0x7FDE, 0x7FE2,
+ 0x7FE3, 0x75E2, 0x7ACB, 0x7C92, 0x6CA5, 0x96B6, 0x529B, 0x7483,
+ 0x54E9, 0x4FE9, 0x8054, 0x83B2, 0x8FDE, 0x9570, 0x5EC9, 0x601C,
+ 0x6D9F, 0x5E18, 0x655B, 0x8138, 0x94FE, 0x604B, 0x70BC, 0x7EC3,
+ 0x7CAE, 0x51C9, 0x6881, 0x7CB1, 0x826F, 0x4E24, 0x8F86, 0x91CF,
+ 0x667E, 0x4EAE, 0x8C05, 0x64A9, 0x804A, 0x50DA, 0x7597, 0x71CE,
+ 0x5BE5, 0x8FBD, 0x6F66, 0x4E86, 0x6482, 0x9563, 0x5ED6, 0x6599,
+ 0x5217, 0x88C2, 0x70C8, 0x52A3, 0x730E, 0x7433, 0x6797, 0x78F7,
+ 0x9716, 0x4E34, 0x90BB, 0x9CDE, 0x6DCB, 0x51DB, 0x8D41, 0x541D,
+ 0x62CE, 0x73B2, 0x83F1, 0x96F6, 0x9F84, 0x94C3, 0x4F36, 0x7F9A,
+ 0x51CC, 0x7075, 0x9675, 0x5CAD, 0x9886, 0x53E6, 0x4EE4, 0x6E9C,
+ 0x7409, 0x69B4, 0x786B, 0x998F, 0x7559, 0x5218, 0x7624, 0x6D41,
+ 0x67F3, 0x516D, 0x9F99, 0x804B, 0x5499, 0x7B3C, 0x7ABF,
+ /* GB 0xC240..0xC27E */
+ 0x7FE4, 0x7FE7, 0x7FE8, 0x7FEA, 0x7FEB, 0x7FEC, 0x7FED, 0x7FEF,
+ 0x7FF2, 0x7FF4, 0x7FF5, 0x7FF6, 0x7FF7, 0x7FF8, 0x7FF9, 0x7FFA,
+ 0x7FFD, 0x7FFE, 0x7FFF, 0x8002, 0x8007, 0x8008, 0x8009, 0x800A,
+ 0x800E, 0x800F, 0x8011, 0x8013, 0x801A, 0x801B, 0x801D, 0x801E,
+ 0x801F, 0x8021, 0x8023, 0x8024, 0x802B, 0x802C, 0x802D, 0x802E,
+ 0x802F, 0x8030, 0x8032, 0x8034, 0x8039, 0x803A, 0x803C, 0x803E,
+ 0x8040, 0x8041, 0x8044, 0x8045, 0x8047, 0x8048, 0x8049, 0x804E,
+ 0x804F, 0x8050, 0x8051, 0x8053, 0x8055, 0x8056, 0x8057,
+ /* GB 0xC280..0xC2FE */
+ 0x8059, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061,
+ 0x8062, 0x8063, 0x8064, 0x8065, 0x8066, 0x8067, 0x8068, 0x806B,
+ 0x806C, 0x806D, 0x806E, 0x806F, 0x8070, 0x8072, 0x8073, 0x8074,
+ 0x8075, 0x8076, 0x8077, 0x8078, 0x8079, 0x807A, 0x807B, 0x807C,
+ 0x807D, 0x9686, 0x5784, 0x62E2, 0x9647, 0x697C, 0x5A04, 0x6402,
+ 0x7BD3, 0x6F0F, 0x964B, 0x82A6, 0x5362, 0x9885, 0x5E90, 0x7089,
+ 0x63B3, 0x5364, 0x864F, 0x9C81, 0x9E93, 0x788C, 0x9732, 0x8DEF,
+ 0x8D42, 0x9E7F, 0x6F5E, 0x7984, 0x5F55, 0x9646, 0x622E, 0x9A74,
+ 0x5415, 0x94DD, 0x4FA3, 0x65C5, 0x5C65, 0x5C61, 0x7F15, 0x8651,
+ 0x6C2F, 0x5F8B, 0x7387, 0x6EE4, 0x7EFF, 0x5CE6, 0x631B, 0x5B6A,
+ 0x6EE6, 0x5375, 0x4E71, 0x63A0, 0x7565, 0x62A1, 0x8F6E, 0x4F26,
+ 0x4ED1, 0x6CA6, 0x7EB6, 0x8BBA, 0x841D, 0x87BA, 0x7F57, 0x903B,
+ 0x9523, 0x7BA9, 0x9AA1, 0x88F8, 0x843D, 0x6D1B, 0x9A86, 0x7EDC,
+ 0x5988, 0x9EBB, 0x739B, 0x7801, 0x8682, 0x9A6C, 0x9A82, 0x561B,
+ 0x5417, 0x57CB, 0x4E70, 0x9EA6, 0x5356, 0x8FC8, 0x8109, 0x7792,
+ 0x9992, 0x86EE, 0x6EE1, 0x8513, 0x66FC, 0x6162, 0x6F2B,
+ /* GB 0xC340..0xC37E */
+ 0x807E, 0x8081, 0x8082, 0x8085, 0x8088, 0x808A, 0x808D, 0x808E,
+ 0x808F, 0x8090, 0x8091, 0x8092, 0x8094, 0x8095, 0x8097, 0x8099,
+ 0x809E, 0x80A3, 0x80A6, 0x80A7, 0x80A8, 0x80AC, 0x80B0, 0x80B3,
+ 0x80B5, 0x80B6, 0x80B8, 0x80B9, 0x80BB, 0x80C5, 0x80C7, 0x80C8,
+ 0x80C9, 0x80CA, 0x80CB, 0x80CF, 0x80D0, 0x80D1, 0x80D2, 0x80D3,
+ 0x80D4, 0x80D5, 0x80D8, 0x80DF, 0x80E0, 0x80E2, 0x80E3, 0x80E6,
+ 0x80EE, 0x80F5, 0x80F7, 0x80F9, 0x80FB, 0x80FE, 0x80FF, 0x8100,
+ 0x8101, 0x8103, 0x8104, 0x8105, 0x8107, 0x8108, 0x810B,
+ /* GB 0xC380..0xC3FE */
+ 0x810C, 0x8115, 0x8117, 0x8119, 0x811B, 0x811C, 0x811D, 0x811F,
+ 0x8120, 0x8121, 0x8122, 0x8123, 0x8124, 0x8125, 0x8126, 0x8127,
+ 0x8128, 0x8129, 0x812A, 0x812B, 0x812D, 0x812E, 0x8130, 0x8133,
+ 0x8134, 0x8135, 0x8137, 0x8139, 0x813A, 0x813B, 0x813C, 0x813D,
+ 0x813F, 0x8C29, 0x8292, 0x832B, 0x76F2, 0x6C13, 0x5FD9, 0x83BD,
+ 0x732B, 0x8305, 0x951A, 0x6BDB, 0x77DB, 0x94C6, 0x536F, 0x8302,
+ 0x5192, 0x5E3D, 0x8C8C, 0x8D38, 0x4E48, 0x73AB, 0x679A, 0x6885,
+ 0x9176, 0x9709, 0x7164, 0x6CA1, 0x7709, 0x5A92, 0x9541, 0x6BCF,
+ 0x7F8E, 0x6627, 0x5BD0, 0x59B9, 0x5A9A, 0x95E8, 0x95F7, 0x4EEC,
+ 0x840C, 0x8499, 0x6AAC, 0x76DF, 0x9530, 0x731B, 0x68A6, 0x5B5F,
+ 0x772F, 0x919A, 0x9761, 0x7CDC, 0x8FF7, 0x8C1C, 0x5F25, 0x7C73,
+ 0x79D8, 0x89C5, 0x6CCC, 0x871C, 0x5BC6, 0x5E42, 0x68C9, 0x7720,
+ 0x7EF5, 0x5195, 0x514D, 0x52C9, 0x5A29, 0x7F05, 0x9762, 0x82D7,
+ 0x63CF, 0x7784, 0x85D0, 0x79D2, 0x6E3A, 0x5E99, 0x5999, 0x8511,
+ 0x706D, 0x6C11, 0x62BF, 0x76BF, 0x654F, 0x60AF, 0x95FD, 0x660E,
+ 0x879F, 0x9E23, 0x94ED, 0x540D, 0x547D, 0x8C2C, 0x6478,
+ /* GB 0xC440..0xC47E */
+ 0x8140, 0x8141, 0x8142, 0x8143, 0x8144, 0x8145, 0x8147, 0x8149,
+ 0x814D, 0x814E, 0x814F, 0x8152, 0x8156, 0x8157, 0x8158, 0x815B,
+ 0x815C, 0x815D, 0x815E, 0x815F, 0x8161, 0x8162, 0x8163, 0x8164,
+ 0x8166, 0x8168, 0x816A, 0x816B, 0x816C, 0x816F, 0x8172, 0x8173,
+ 0x8175, 0x8176, 0x8177, 0x8178, 0x8181, 0x8183, 0x8184, 0x8185,
+ 0x8186, 0x8187, 0x8189, 0x818B, 0x818C, 0x818D, 0x818E, 0x8190,
+ 0x8192, 0x8193, 0x8194, 0x8195, 0x8196, 0x8197, 0x8199, 0x819A,
+ 0x819E, 0x819F, 0x81A0, 0x81A1, 0x81A2, 0x81A4, 0x81A5,
+ /* GB 0xC480..0xC4FE */
+ 0x81A7, 0x81A9, 0x81AB, 0x81AC, 0x81AD, 0x81AE, 0x81AF, 0x81B0,
+ 0x81B1, 0x81B2, 0x81B4, 0x81B5, 0x81B6, 0x81B7, 0x81B8, 0x81B9,
+ 0x81BC, 0x81BD, 0x81BE, 0x81BF, 0x81C4, 0x81C5, 0x81C7, 0x81C8,
+ 0x81C9, 0x81CB, 0x81CD, 0x81CE, 0x81CF, 0x81D0, 0x81D1, 0x81D2,
+ 0x81D3, 0x6479, 0x8611, 0x6A21, 0x819C, 0x78E8, 0x6469, 0x9B54,
+ 0x62B9, 0x672B, 0x83AB, 0x58A8, 0x9ED8, 0x6CAB, 0x6F20, 0x5BDE,
+ 0x964C, 0x8C0B, 0x725F, 0x67D0, 0x62C7, 0x7261, 0x4EA9, 0x59C6,
+ 0x6BCD, 0x5893, 0x66AE, 0x5E55, 0x52DF, 0x6155, 0x6728, 0x76EE,
+ 0x7766, 0x7267, 0x7A46, 0x62FF, 0x54EA, 0x5450, 0x94A0, 0x90A3,
+ 0x5A1C, 0x7EB3, 0x6C16, 0x4E43, 0x5976, 0x8010, 0x5948, 0x5357,
+ 0x7537, 0x96BE, 0x56CA, 0x6320, 0x8111, 0x607C, 0x95F9, 0x6DD6,
+ 0x5462, 0x9981, 0x5185, 0x5AE9, 0x80FD, 0x59AE, 0x9713, 0x502A,
+ 0x6CE5, 0x5C3C, 0x62DF, 0x4F60, 0x533F, 0x817B, 0x9006, 0x6EBA,
+ 0x852B, 0x62C8, 0x5E74, 0x78BE, 0x64B5, 0x637B, 0x5FF5, 0x5A18,
+ 0x917F, 0x9E1F, 0x5C3F, 0x634F, 0x8042, 0x5B7D, 0x556E, 0x954A,
+ 0x954D, 0x6D85, 0x60A8, 0x67E0, 0x72DE, 0x51DD, 0x5B81,
+ /* GB 0xC540..0xC57E */
+ 0x81D4, 0x81D5, 0x81D6, 0x81D7, 0x81D8, 0x81D9, 0x81DA, 0x81DB,
+ 0x81DC, 0x81DD, 0x81DE, 0x81DF, 0x81E0, 0x81E1, 0x81E2, 0x81E4,
+ 0x81E5, 0x81E6, 0x81E8, 0x81E9, 0x81EB, 0x81EE, 0x81EF, 0x81F0,
+ 0x81F1, 0x81F2, 0x81F5, 0x81F6, 0x81F7, 0x81F8, 0x81F9, 0x81FA,
+ 0x81FD, 0x81FF, 0x8203, 0x8207, 0x8208, 0x8209, 0x820A, 0x820B,
+ 0x820E, 0x820F, 0x8211, 0x8213, 0x8215, 0x8216, 0x8217, 0x8218,
+ 0x8219, 0x821A, 0x821D, 0x8220, 0x8224, 0x8225, 0x8226, 0x8227,
+ 0x8229, 0x822E, 0x8232, 0x823A, 0x823C, 0x823D, 0x823F,
+ /* GB 0xC580..0xC5FE */
+ 0x8240, 0x8241, 0x8242, 0x8243, 0x8245, 0x8246, 0x8248, 0x824A,
+ 0x824C, 0x824D, 0x824E, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254,
+ 0x8255, 0x8256, 0x8257, 0x8259, 0x825B, 0x825C, 0x825D, 0x825E,
+ 0x8260, 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266, 0x8267,
+ 0x8269, 0x62E7, 0x6CDE, 0x725B, 0x626D, 0x94AE, 0x7EBD, 0x8113,
+ 0x6D53, 0x519C, 0x5F04, 0x5974, 0x52AA, 0x6012, 0x5973, 0x6696,
+ 0x8650, 0x759F, 0x632A, 0x61E6, 0x7CEF, 0x8BFA, 0x54E6, 0x6B27,
+ 0x9E25, 0x6BB4, 0x85D5, 0x5455, 0x5076, 0x6CA4, 0x556A, 0x8DB4,
+ 0x722C, 0x5E15, 0x6015, 0x7436, 0x62CD, 0x6392, 0x724C, 0x5F98,
+ 0x6E43, 0x6D3E, 0x6500, 0x6F58, 0x76D8, 0x78D0, 0x76FC, 0x7554,
+ 0x5224, 0x53DB, 0x4E53, 0x5E9E, 0x65C1, 0x802A, 0x80D6, 0x629B,
+ 0x5486, 0x5228, 0x70AE, 0x888D, 0x8DD1, 0x6CE1, 0x5478, 0x80DA,
+ 0x57F9, 0x88F4, 0x8D54, 0x966A, 0x914D, 0x4F69, 0x6C9B, 0x55B7,
+ 0x76C6, 0x7830, 0x62A8, 0x70F9, 0x6F8E, 0x5F6D, 0x84EC, 0x68DA,
+ 0x787C, 0x7BF7, 0x81A8, 0x670B, 0x9E4F, 0x6367, 0x78B0, 0x576F,
+ 0x7812, 0x9739, 0x6279, 0x62AB, 0x5288, 0x7435, 0x6BD7,
+ /* GB 0xC640..0xC67E */
+ 0x826A, 0x826B, 0x826C, 0x826D, 0x8271, 0x8275, 0x8276, 0x8277,
+ 0x8278, 0x827B, 0x827C, 0x8280, 0x8281, 0x8283, 0x8285, 0x8286,
+ 0x8287, 0x8289, 0x828C, 0x8290, 0x8293, 0x8294, 0x8295, 0x8296,
+ 0x829A, 0x829B, 0x829E, 0x82A0, 0x82A2, 0x82A3, 0x82A7, 0x82B2,
+ 0x82B5, 0x82B6, 0x82BA, 0x82BB, 0x82BC, 0x82BF, 0x82C0, 0x82C2,
+ 0x82C3, 0x82C5, 0x82C6, 0x82C9, 0x82D0, 0x82D6, 0x82D9, 0x82DA,
+ 0x82DD, 0x82E2, 0x82E7, 0x82E8, 0x82E9, 0x82EA, 0x82EC, 0x82ED,
+ 0x82EE, 0x82F0, 0x82F2, 0x82F3, 0x82F5, 0x82F6, 0x82F8,
+ /* GB 0xC680..0xC6FE */
+ 0x82FA, 0x82FC, 0x82FD, 0x82FE, 0x82FF, 0x8300, 0x830A, 0x830B,
+ 0x830D, 0x8310, 0x8312, 0x8313, 0x8316, 0x8318, 0x8319, 0x831D,
+ 0x831E, 0x831F, 0x8320, 0x8321, 0x8322, 0x8323, 0x8324, 0x8325,
+ 0x8326, 0x8329, 0x832A, 0x832E, 0x8330, 0x8332, 0x8337, 0x833B,
+ 0x833D, 0x5564, 0x813E, 0x75B2, 0x76AE, 0x5339, 0x75DE, 0x50FB,
+ 0x5C41, 0x8B6C, 0x7BC7, 0x504F, 0x7247, 0x9A97, 0x98D8, 0x6F02,
+ 0x74E2, 0x7968, 0x6487, 0x77A5, 0x62FC, 0x9891, 0x8D2B, 0x54C1,
+ 0x8058, 0x4E52, 0x576A, 0x82F9, 0x840D, 0x5E73, 0x51ED, 0x74F6,
+ 0x8BC4, 0x5C4F, 0x5761, 0x6CFC, 0x9887, 0x5A46, 0x7834, 0x9B44,
+ 0x8FEB, 0x7C95, 0x5256, 0x6251, 0x94FA, 0x4EC6, 0x8386, 0x8461,
+ 0x83E9, 0x84B2, 0x57D4, 0x6734, 0x5703, 0x666E, 0x6D66, 0x8C31,
+ 0x66DD, 0x7011, 0x671F, 0x6B3A, 0x6816, 0x621A, 0x59BB, 0x4E03,
+ 0x51C4, 0x6F06, 0x67D2, 0x6C8F, 0x5176, 0x68CB, 0x5947, 0x6B67,
+ 0x7566, 0x5D0E, 0x8110, 0x9F50, 0x65D7, 0x7948, 0x7941, 0x9A91,
+ 0x8D77, 0x5C82, 0x4E5E, 0x4F01, 0x542F, 0x5951, 0x780C, 0x5668,
+ 0x6C14, 0x8FC4, 0x5F03, 0x6C7D, 0x6CE3, 0x8BAB, 0x6390,
+ /* GB 0xC740..0xC77E */
+ 0x833E, 0x833F, 0x8341, 0x8342, 0x8344, 0x8345, 0x8348, 0x834A,
+ 0x834B, 0x834C, 0x834D, 0x834E, 0x8353, 0x8355, 0x8356, 0x8357,
+ 0x8358, 0x8359, 0x835D, 0x8362, 0x8370, 0x8371, 0x8372, 0x8373,
+ 0x8374, 0x8375, 0x8376, 0x8379, 0x837A, 0x837E, 0x837F, 0x8380,
+ 0x8381, 0x8382, 0x8383, 0x8384, 0x8387, 0x8388, 0x838A, 0x838B,
+ 0x838C, 0x838D, 0x838F, 0x8390, 0x8391, 0x8394, 0x8395, 0x8396,
+ 0x8397, 0x8399, 0x839A, 0x839D, 0x839F, 0x83A1, 0x83A2, 0x83A3,
+ 0x83A4, 0x83A5, 0x83A6, 0x83A7, 0x83AC, 0x83AD, 0x83AE,
+ /* GB 0xC780..0xC7FE */
+ 0x83AF, 0x83B5, 0x83BB, 0x83BE, 0x83BF, 0x83C2, 0x83C3, 0x83C4,
+ 0x83C6, 0x83C8, 0x83C9, 0x83CB, 0x83CD, 0x83CE, 0x83D0, 0x83D1,
+ 0x83D2, 0x83D3, 0x83D5, 0x83D7, 0x83D9, 0x83DA, 0x83DB, 0x83DE,
+ 0x83E2, 0x83E3, 0x83E4, 0x83E6, 0x83E7, 0x83E8, 0x83EB, 0x83EC,
+ 0x83ED, 0x6070, 0x6D3D, 0x7275, 0x6266, 0x948E, 0x94C5, 0x5343,
+ 0x8FC1, 0x7B7E, 0x4EDF, 0x8C26, 0x4E7E, 0x9ED4, 0x94B1, 0x94B3,
+ 0x524D, 0x6F5C, 0x9063, 0x6D45, 0x8C34, 0x5811, 0x5D4C, 0x6B20,
+ 0x6B49, 0x67AA, 0x545B, 0x8154, 0x7F8C, 0x5899, 0x8537, 0x5F3A,
+ 0x62A2, 0x6A47, 0x9539, 0x6572, 0x6084, 0x6865, 0x77A7, 0x4E54,
+ 0x4FA8, 0x5DE7, 0x9798, 0x64AC, 0x7FD8, 0x5CED, 0x4FCF, 0x7A8D,
+ 0x5207, 0x8304, 0x4E14, 0x602F, 0x7A83, 0x94A6, 0x4FB5, 0x4EB2,
+ 0x79E6, 0x7434, 0x52E4, 0x82B9, 0x64D2, 0x79BD, 0x5BDD, 0x6C81,
+ 0x9752, 0x8F7B, 0x6C22, 0x503E, 0x537F, 0x6E05, 0x64CE, 0x6674,
+ 0x6C30, 0x60C5, 0x9877, 0x8BF7, 0x5E86, 0x743C, 0x7A77, 0x79CB,
+ 0x4E18, 0x90B1, 0x7403, 0x6C42, 0x56DA, 0x914B, 0x6CC5, 0x8D8B,
+ 0x533A, 0x86C6, 0x66F2, 0x8EAF, 0x5C48, 0x9A71, 0x6E20,
+ /* GB 0xC840..0xC87E */
+ 0x83EE, 0x83EF, 0x83F3, 0x83F4, 0x83F5, 0x83F6, 0x83F7, 0x83FA,
+ 0x83FB, 0x83FC, 0x83FE, 0x83FF, 0x8400, 0x8402, 0x8405, 0x8407,
+ 0x8408, 0x8409, 0x840A, 0x8410, 0x8412, 0x8413, 0x8414, 0x8415,
+ 0x8416, 0x8417, 0x8419, 0x841A, 0x841B, 0x841E, 0x841F, 0x8420,
+ 0x8421, 0x8422, 0x8423, 0x8429, 0x842A, 0x842B, 0x842C, 0x842D,
+ 0x842E, 0x842F, 0x8430, 0x8432, 0x8433, 0x8434, 0x8435, 0x8436,
+ 0x8437, 0x8439, 0x843A, 0x843B, 0x843E, 0x843F, 0x8440, 0x8441,
+ 0x8442, 0x8443, 0x8444, 0x8445, 0x8447, 0x8448, 0x8449,
+ /* GB 0xC880..0xC8FE */
+ 0x844A, 0x844B, 0x844C, 0x844D, 0x844E, 0x844F, 0x8450, 0x8452,
+ 0x8453, 0x8454, 0x8455, 0x8456, 0x8458, 0x845D, 0x845E, 0x845F,
+ 0x8460, 0x8462, 0x8464, 0x8465, 0x8466, 0x8467, 0x8468, 0x846A,
+ 0x846E, 0x846F, 0x8470, 0x8472, 0x8474, 0x8477, 0x8479, 0x847B,
+ 0x847C, 0x53D6, 0x5A36, 0x9F8B, 0x8DA3, 0x53BB, 0x5708, 0x98A7,
+ 0x6743, 0x919B, 0x6CC9, 0x5168, 0x75CA, 0x62F3, 0x72AC, 0x5238,
+ 0x529D, 0x7F3A, 0x7094, 0x7638, 0x5374, 0x9E4A, 0x69B7, 0x786E,
+ 0x96C0, 0x88D9, 0x7FA4, 0x7136, 0x71C3, 0x5189, 0x67D3, 0x74E4,
+ 0x58E4, 0x6518, 0x56B7, 0x8BA9, 0x9976, 0x6270, 0x7ED5, 0x60F9,
+ 0x70ED, 0x58EC, 0x4EC1, 0x4EBA, 0x5FCD, 0x97E7, 0x4EFB, 0x8BA4,
+ 0x5203, 0x598A, 0x7EAB, 0x6254, 0x4ECD, 0x65E5, 0x620E, 0x8338,
+ 0x84C9, 0x8363, 0x878D, 0x7194, 0x6EB6, 0x5BB9, 0x7ED2, 0x5197,
+ 0x63C9, 0x67D4, 0x8089, 0x8339, 0x8815, 0x5112, 0x5B7A, 0x5982,
+ 0x8FB1, 0x4E73, 0x6C5D, 0x5165, 0x8925, 0x8F6F, 0x962E, 0x854A,
+ 0x745E, 0x9510, 0x95F0, 0x6DA6, 0x82E5, 0x5F31, 0x6492, 0x6D12,
+ 0x8428, 0x816E, 0x9CC3, 0x585E, 0x8D5B, 0x4E09, 0x53C1,
+ /* GB 0xC940..0xC97E */
+ 0x847D, 0x847E, 0x847F, 0x8480, 0x8481, 0x8483, 0x8484, 0x8485,
+ 0x8486, 0x848A, 0x848D, 0x848F, 0x8490, 0x8491, 0x8492, 0x8493,
+ 0x8494, 0x8495, 0x8496, 0x8498, 0x849A, 0x849B, 0x849D, 0x849E,
+ 0x849F, 0x84A0, 0x84A2, 0x84A3, 0x84A4, 0x84A5, 0x84A6, 0x84A7,
+ 0x84A8, 0x84A9, 0x84AA, 0x84AB, 0x84AC, 0x84AD, 0x84AE, 0x84B0,
+ 0x84B1, 0x84B3, 0x84B5, 0x84B6, 0x84B7, 0x84BB, 0x84BC, 0x84BE,
+ 0x84C0, 0x84C2, 0x84C3, 0x84C5, 0x84C6, 0x84C7, 0x84C8, 0x84CB,
+ 0x84CC, 0x84CE, 0x84CF, 0x84D2, 0x84D4, 0x84D5, 0x84D7,
+ /* GB 0xC980..0xC9FE */
+ 0x84D8, 0x84D9, 0x84DA, 0x84DB, 0x84DC, 0x84DE, 0x84E1, 0x84E2,
+ 0x84E4, 0x84E7, 0x84E8, 0x84E9, 0x84EA, 0x84EB, 0x84ED, 0x84EE,
+ 0x84EF, 0x84F1, 0x84F2, 0x84F3, 0x84F4, 0x84F5, 0x84F6, 0x84F7,
+ 0x84F8, 0x84F9, 0x84FA, 0x84FB, 0x84FD, 0x84FE, 0x8500, 0x8501,
+ 0x8502, 0x4F1E, 0x6563, 0x6851, 0x55D3, 0x4E27, 0x6414, 0x9A9A,
+ 0x626B, 0x5AC2, 0x745F, 0x8272, 0x6DA9, 0x68EE, 0x50E7, 0x838E,
+ 0x7802, 0x6740, 0x5239, 0x6C99, 0x7EB1, 0x50BB, 0x5565, 0x715E,
+ 0x7B5B, 0x6652, 0x73CA, 0x82EB, 0x6749, 0x5C71, 0x5220, 0x717D,
+ 0x886B, 0x95EA, 0x9655, 0x64C5, 0x8D61, 0x81B3, 0x5584, 0x6C55,
+ 0x6247, 0x7F2E, 0x5892, 0x4F24, 0x5546, 0x8D4F, 0x664C, 0x4E0A,
+ 0x5C1A, 0x88F3, 0x68A2, 0x634E, 0x7A0D, 0x70E7, 0x828D, 0x52FA,
+ 0x97F6, 0x5C11, 0x54E8, 0x90B5, 0x7ECD, 0x5962, 0x8D4A, 0x86C7,
+ 0x820C, 0x820D, 0x8D66, 0x6444, 0x5C04, 0x6151, 0x6D89, 0x793E,
+ 0x8BBE, 0x7837, 0x7533, 0x547B, 0x4F38, 0x8EAB, 0x6DF1, 0x5A20,
+ 0x7EC5, 0x795E, 0x6C88, 0x5BA1, 0x5A76, 0x751A, 0x80BE, 0x614E,
+ 0x6E17, 0x58F0, 0x751F, 0x7525, 0x7272, 0x5347, 0x7EF3,
+ /* GB 0xCA40..0xCA7E */
+ 0x8503, 0x8504, 0x8505, 0x8506, 0x8507, 0x8508, 0x8509, 0x850A,
+ 0x850B, 0x850D, 0x850E, 0x850F, 0x8510, 0x8512, 0x8514, 0x8515,
+ 0x8516, 0x8518, 0x8519, 0x851B, 0x851C, 0x851D, 0x851E, 0x8520,
+ 0x8522, 0x8523, 0x8524, 0x8525, 0x8526, 0x8527, 0x8528, 0x8529,
+ 0x852A, 0x852D, 0x852E, 0x852F, 0x8530, 0x8531, 0x8532, 0x8533,
+ 0x8534, 0x8535, 0x8536, 0x853E, 0x853F, 0x8540, 0x8541, 0x8542,
+ 0x8544, 0x8545, 0x8546, 0x8547, 0x854B, 0x854C, 0x854D, 0x854E,
+ 0x854F, 0x8550, 0x8551, 0x8552, 0x8553, 0x8554, 0x8555,
+ /* GB 0xCA80..0xCAFE */
+ 0x8557, 0x8558, 0x855A, 0x855B, 0x855C, 0x855D, 0x855F, 0x8560,
+ 0x8561, 0x8562, 0x8563, 0x8565, 0x8566, 0x8567, 0x8569, 0x856A,
+ 0x856B, 0x856C, 0x856D, 0x856E, 0x856F, 0x8570, 0x8571, 0x8573,
+ 0x8575, 0x8576, 0x8577, 0x8578, 0x857C, 0x857D, 0x857F, 0x8580,
+ 0x8581, 0x7701, 0x76DB, 0x5269, 0x80DC, 0x5723, 0x5E08, 0x5931,
+ 0x72EE, 0x65BD, 0x6E7F, 0x8BD7, 0x5C38, 0x8671, 0x5341, 0x77F3,
+ 0x62FE, 0x65F6, 0x4EC0, 0x98DF, 0x8680, 0x5B9E, 0x8BC6, 0x53F2,
+ 0x77E2, 0x4F7F, 0x5C4E, 0x9A76, 0x59CB, 0x5F0F, 0x793A, 0x58EB,
+ 0x4E16, 0x67FF, 0x4E8B, 0x62ED, 0x8A93, 0x901D, 0x52BF, 0x662F,
+ 0x55DC, 0x566C, 0x9002, 0x4ED5, 0x4F8D, 0x91CA, 0x9970, 0x6C0F,
+ 0x5E02, 0x6043, 0x5BA4, 0x89C6, 0x8BD5, 0x6536, 0x624B, 0x9996,
+ 0x5B88, 0x5BFF, 0x6388, 0x552E, 0x53D7, 0x7626, 0x517D, 0x852C,
+ 0x67A2, 0x68B3, 0x6B8A, 0x6292, 0x8F93, 0x53D4, 0x8212, 0x6DD1,
+ 0x758F, 0x4E66, 0x8D4E, 0x5B70, 0x719F, 0x85AF, 0x6691, 0x66D9,
+ 0x7F72, 0x8700, 0x9ECD, 0x9F20, 0x5C5E, 0x672F, 0x8FF0, 0x6811,
+ 0x675F, 0x620D, 0x7AD6, 0x5885, 0x5EB6, 0x6570, 0x6F31,
+ /* GB 0xCB40..0xCB7E */
+ 0x8582, 0x8583, 0x8586, 0x8588, 0x8589, 0x858A, 0x858B, 0x858C,
+ 0x858D, 0x858E, 0x8590, 0x8591, 0x8592, 0x8593, 0x8594, 0x8595,
+ 0x8596, 0x8597, 0x8598, 0x8599, 0x859A, 0x859D, 0x859E, 0x859F,
+ 0x85A0, 0x85A1, 0x85A2, 0x85A3, 0x85A5, 0x85A6, 0x85A7, 0x85A9,
+ 0x85AB, 0x85AC, 0x85AD, 0x85B1, 0x85B2, 0x85B3, 0x85B4, 0x85B5,
+ 0x85B6, 0x85B8, 0x85BA, 0x85BB, 0x85BC, 0x85BD, 0x85BE, 0x85BF,
+ 0x85C0, 0x85C2, 0x85C3, 0x85C4, 0x85C5, 0x85C6, 0x85C7, 0x85C8,
+ 0x85CA, 0x85CB, 0x85CC, 0x85CD, 0x85CE, 0x85D1, 0x85D2,
+ /* GB 0xCB80..0xCBFE */
+ 0x85D4, 0x85D6, 0x85D7, 0x85D8, 0x85D9, 0x85DA, 0x85DB, 0x85DD,
+ 0x85DE, 0x85DF, 0x85E0, 0x85E1, 0x85E2, 0x85E3, 0x85E5, 0x85E6,
+ 0x85E7, 0x85E8, 0x85EA, 0x85EB, 0x85EC, 0x85ED, 0x85EE, 0x85EF,
+ 0x85F0, 0x85F1, 0x85F2, 0x85F3, 0x85F4, 0x85F5, 0x85F6, 0x85F7,
+ 0x85F8, 0x6055, 0x5237, 0x800D, 0x6454, 0x8870, 0x7529, 0x5E05,
+ 0x6813, 0x62F4, 0x971C, 0x53CC, 0x723D, 0x8C01, 0x6C34, 0x7761,
+ 0x7A0E, 0x542E, 0x77AC, 0x987A, 0x821C, 0x8BF4, 0x7855, 0x6714,
+ 0x70C1, 0x65AF, 0x6495, 0x5636, 0x601D, 0x79C1, 0x53F8, 0x4E1D,
+ 0x6B7B, 0x8086, 0x5BFA, 0x55E3, 0x56DB, 0x4F3A, 0x4F3C, 0x9972,
+ 0x5DF3, 0x677E, 0x8038, 0x6002, 0x9882, 0x9001, 0x5B8B, 0x8BBC,
+ 0x8BF5, 0x641C, 0x8258, 0x64DE, 0x55FD, 0x82CF, 0x9165, 0x4FD7,
+ 0x7D20, 0x901F, 0x7C9F, 0x50F3, 0x5851, 0x6EAF, 0x5BBF, 0x8BC9,
+ 0x8083, 0x9178, 0x849C, 0x7B97, 0x867D, 0x968B, 0x968F, 0x7EE5,
+ 0x9AD3, 0x788E, 0x5C81, 0x7A57, 0x9042, 0x96A7, 0x795F, 0x5B59,
+ 0x635F, 0x7B0B, 0x84D1, 0x68AD, 0x5506, 0x7F29, 0x7410, 0x7D22,
+ 0x9501, 0x6240, 0x584C, 0x4ED6, 0x5B83, 0x5979, 0x5854,
+ /* GB 0xCC40..0xCC7E */
+ 0x85F9, 0x85FA, 0x85FC, 0x85FD, 0x85FE, 0x8600, 0x8601, 0x8602,
+ 0x8603, 0x8604, 0x8606, 0x8607, 0x8608, 0x8609, 0x860A, 0x860B,
+ 0x860C, 0x860D, 0x860E, 0x860F, 0x8610, 0x8612, 0x8613, 0x8614,
+ 0x8615, 0x8617, 0x8618, 0x8619, 0x861A, 0x861B, 0x861C, 0x861D,
+ 0x861E, 0x861F, 0x8620, 0x8621, 0x8622, 0x8623, 0x8624, 0x8625,
+ 0x8626, 0x8628, 0x862A, 0x862B, 0x862C, 0x862D, 0x862E, 0x862F,
+ 0x8630, 0x8631, 0x8632, 0x8633, 0x8634, 0x8635, 0x8636, 0x8637,
+ 0x8639, 0x863A, 0x863B, 0x863D, 0x863E, 0x863F, 0x8640,
+ /* GB 0xCC80..0xCCFE */
+ 0x8641, 0x8642, 0x8643, 0x8644, 0x8645, 0x8646, 0x8647, 0x8648,
+ 0x8649, 0x864A, 0x864B, 0x864C, 0x8652, 0x8653, 0x8655, 0x8656,
+ 0x8657, 0x8658, 0x8659, 0x865B, 0x865C, 0x865D, 0x865F, 0x8660,
+ 0x8661, 0x8663, 0x8664, 0x8665, 0x8666, 0x8667, 0x8668, 0x8669,
+ 0x866A, 0x736D, 0x631E, 0x8E4B, 0x8E0F, 0x80CE, 0x82D4, 0x62AC,
+ 0x53F0, 0x6CF0, 0x915E, 0x592A, 0x6001, 0x6C70, 0x574D, 0x644A,
+ 0x8D2A, 0x762B, 0x6EE9, 0x575B, 0x6A80, 0x75F0, 0x6F6D, 0x8C2D,
+ 0x8C08, 0x5766, 0x6BEF, 0x8892, 0x78B3, 0x63A2, 0x53F9, 0x70AD,
+ 0x6C64, 0x5858, 0x642A, 0x5802, 0x68E0, 0x819B, 0x5510, 0x7CD6,
+ 0x5018, 0x8EBA, 0x6DCC, 0x8D9F, 0x70EB, 0x638F, 0x6D9B, 0x6ED4,
+ 0x7EE6, 0x8404, 0x6843, 0x9003, 0x6DD8, 0x9676, 0x8BA8, 0x5957,
+ 0x7279, 0x85E4, 0x817E, 0x75BC, 0x8A8A, 0x68AF, 0x5254, 0x8E22,
+ 0x9511, 0x63D0, 0x9898, 0x8E44, 0x557C, 0x4F53, 0x66FF, 0x568F,
+ 0x60D5, 0x6D95, 0x5243, 0x5C49, 0x5929, 0x6DFB, 0x586B, 0x7530,
+ 0x751C, 0x606C, 0x8214, 0x8146, 0x6311, 0x6761, 0x8FE2, 0x773A,
+ 0x8DF3, 0x8D34, 0x94C1, 0x5E16, 0x5385, 0x542C, 0x70C3,
+ /* GB 0xCD40..0xCD7E */
+ 0x866D, 0x866F, 0x8670, 0x8672, 0x8673, 0x8674, 0x8675, 0x8676,
+ 0x8677, 0x8678, 0x8683, 0x8684, 0x8685, 0x8686, 0x8687, 0x8688,
+ 0x8689, 0x868E, 0x868F, 0x8690, 0x8691, 0x8692, 0x8694, 0x8696,
+ 0x8697, 0x8698, 0x8699, 0x869A, 0x869B, 0x869E, 0x869F, 0x86A0,
+ 0x86A1, 0x86A2, 0x86A5, 0x86A6, 0x86AB, 0x86AD, 0x86AE, 0x86B2,
+ 0x86B3, 0x86B7, 0x86B8, 0x86B9, 0x86BB, 0x86BC, 0x86BD, 0x86BE,
+ 0x86BF, 0x86C1, 0x86C2, 0x86C3, 0x86C5, 0x86C8, 0x86CC, 0x86CD,
+ 0x86D2, 0x86D3, 0x86D5, 0x86D6, 0x86D7, 0x86DA, 0x86DC,
+ /* GB 0xCD80..0xCDFE */
+ 0x86DD, 0x86E0, 0x86E1, 0x86E2, 0x86E3, 0x86E5, 0x86E6, 0x86E7,
+ 0x86E8, 0x86EA, 0x86EB, 0x86EC, 0x86EF, 0x86F5, 0x86F6, 0x86F7,
+ 0x86FA, 0x86FB, 0x86FC, 0x86FD, 0x86FF, 0x8701, 0x8704, 0x8705,
+ 0x8706, 0x870B, 0x870C, 0x870E, 0x870F, 0x8710, 0x8711, 0x8714,
+ 0x8716, 0x6C40, 0x5EF7, 0x505C, 0x4EAD, 0x5EAD, 0x633A, 0x8247,
+ 0x901A, 0x6850, 0x916E, 0x77B3, 0x540C, 0x94DC, 0x5F64, 0x7AE5,
+ 0x6876, 0x6345, 0x7B52, 0x7EDF, 0x75DB, 0x5077, 0x6295, 0x5934,
+ 0x900F, 0x51F8, 0x79C3, 0x7A81, 0x56FE, 0x5F92, 0x9014, 0x6D82,
+ 0x5C60, 0x571F, 0x5410, 0x5154, 0x6E4D, 0x56E2, 0x63A8, 0x9893,
+ 0x817F, 0x8715, 0x892A, 0x9000, 0x541E, 0x5C6F, 0x81C0, 0x62D6,
+ 0x6258, 0x8131, 0x9E35, 0x9640, 0x9A6E, 0x9A7C, 0x692D, 0x59A5,
+ 0x62D3, 0x553E, 0x6316, 0x54C7, 0x86D9, 0x6D3C, 0x5A03, 0x74E6,
+ 0x889C, 0x6B6A, 0x5916, 0x8C4C, 0x5F2F, 0x6E7E, 0x73A9, 0x987D,
+ 0x4E38, 0x70F7, 0x5B8C, 0x7897, 0x633D, 0x665A, 0x7696, 0x60CB,
+ 0x5B9B, 0x5A49, 0x4E07, 0x8155, 0x6C6A, 0x738B, 0x4EA1, 0x6789,
+ 0x7F51, 0x5F80, 0x65FA, 0x671B, 0x5FD8, 0x5984, 0x5A01,
+ /* GB 0xCE40..0xCE7E */
+ 0x8719, 0x871B, 0x871D, 0x871F, 0x8720, 0x8724, 0x8726, 0x8727,
+ 0x8728, 0x872A, 0x872B, 0x872C, 0x872D, 0x872F, 0x8730, 0x8732,
+ 0x8733, 0x8735, 0x8736, 0x8738, 0x8739, 0x873A, 0x873C, 0x873D,
+ 0x8740, 0x8741, 0x8742, 0x8743, 0x8744, 0x8745, 0x8746, 0x874A,
+ 0x874B, 0x874D, 0x874F, 0x8750, 0x8751, 0x8752, 0x8754, 0x8755,
+ 0x8756, 0x8758, 0x875A, 0x875B, 0x875C, 0x875D, 0x875E, 0x875F,
+ 0x8761, 0x8762, 0x8766, 0x8767, 0x8768, 0x8769, 0x876A, 0x876B,
+ 0x876C, 0x876D, 0x876F, 0x8771, 0x8772, 0x8773, 0x8775,
+ /* GB 0xCE80..0xCEFE */
+ 0x8777, 0x8778, 0x8779, 0x877A, 0x877F, 0x8780, 0x8781, 0x8784,
+ 0x8786, 0x8787, 0x8789, 0x878A, 0x878C, 0x878E, 0x878F, 0x8790,
+ 0x8791, 0x8792, 0x8794, 0x8795, 0x8796, 0x8798, 0x8799, 0x879A,
+ 0x879B, 0x879C, 0x879D, 0x879E, 0x87A0, 0x87A1, 0x87A2, 0x87A3,
+ 0x87A4, 0x5DCD, 0x5FAE, 0x5371, 0x97E6, 0x8FDD, 0x6845, 0x56F4,
+ 0x552F, 0x60DF, 0x4E3A, 0x6F4D, 0x7EF4, 0x82C7, 0x840E, 0x59D4,
+ 0x4F1F, 0x4F2A, 0x5C3E, 0x7EAC, 0x672A, 0x851A, 0x5473, 0x754F,
+ 0x80C3, 0x5582, 0x9B4F, 0x4F4D, 0x6E2D, 0x8C13, 0x5C09, 0x6170,
+ 0x536B, 0x761F, 0x6E29, 0x868A, 0x6587, 0x95FB, 0x7EB9, 0x543B,
+ 0x7A33, 0x7D0A, 0x95EE, 0x55E1, 0x7FC1, 0x74EE, 0x631D, 0x8717,
+ 0x6DA1, 0x7A9D, 0x6211, 0x65A1, 0x5367, 0x63E1, 0x6C83, 0x5DEB,
+ 0x545C, 0x94A8, 0x4E4C, 0x6C61, 0x8BEC, 0x5C4B, 0x65E0, 0x829C,
+ 0x68A7, 0x543E, 0x5434, 0x6BCB, 0x6B66, 0x4E94, 0x6342, 0x5348,
+ 0x821E, 0x4F0D, 0x4FAE, 0x575E, 0x620A, 0x96FE, 0x6664, 0x7269,
+ 0x52FF, 0x52A1, 0x609F, 0x8BEF, 0x6614, 0x7199, 0x6790, 0x897F,
+ 0x7852, 0x77FD, 0x6670, 0x563B, 0x5438, 0x9521, 0x727A,
+ /* GB 0xCF40..0xCF7E */
+ 0x87A5, 0x87A6, 0x87A7, 0x87A9, 0x87AA, 0x87AE, 0x87B0, 0x87B1,
+ 0x87B2, 0x87B4, 0x87B6, 0x87B7, 0x87B8, 0x87B9, 0x87BB, 0x87BC,
+ 0x87BE, 0x87BF, 0x87C1, 0x87C2, 0x87C3, 0x87C4, 0x87C5, 0x87C7,
+ 0x87C8, 0x87C9, 0x87CC, 0x87CD, 0x87CE, 0x87CF, 0x87D0, 0x87D4,
+ 0x87D5, 0x87D6, 0x87D7, 0x87D8, 0x87D9, 0x87DA, 0x87DC, 0x87DD,
+ 0x87DE, 0x87DF, 0x87E1, 0x87E2, 0x87E3, 0x87E4, 0x87E6, 0x87E7,
+ 0x87E8, 0x87E9, 0x87EB, 0x87EC, 0x87ED, 0x87EF, 0x87F0, 0x87F1,
+ 0x87F2, 0x87F3, 0x87F4, 0x87F5, 0x87F6, 0x87F7, 0x87F8,
+ /* GB 0xCF80..0xCFFE */
+ 0x87FA, 0x87FB, 0x87FC, 0x87FD, 0x87FF, 0x8800, 0x8801, 0x8802,
+ 0x8804, 0x8805, 0x8806, 0x8807, 0x8808, 0x8809, 0x880B, 0x880C,
+ 0x880D, 0x880E, 0x880F, 0x8810, 0x8811, 0x8812, 0x8814, 0x8817,
+ 0x8818, 0x8819, 0x881A, 0x881C, 0x881D, 0x881E, 0x881F, 0x8820,
+ 0x8823, 0x7A00, 0x606F, 0x5E0C, 0x6089, 0x819D, 0x5915, 0x60DC,
+ 0x7184, 0x70EF, 0x6EAA, 0x6C50, 0x7280, 0x6A84, 0x88AD, 0x5E2D,
+ 0x4E60, 0x5AB3, 0x559C, 0x94E3, 0x6D17, 0x7CFB, 0x9699, 0x620F,
+ 0x7EC6, 0x778E, 0x867E, 0x5323, 0x971E, 0x8F96, 0x6687, 0x5CE1,
+ 0x4FA0, 0x72ED, 0x4E0B, 0x53A6, 0x590F, 0x5413, 0x6380, 0x9528,
+ 0x5148, 0x4ED9, 0x9C9C, 0x7EA4, 0x54B8, 0x8D24, 0x8854, 0x8237,
+ 0x95F2, 0x6D8E, 0x5F26, 0x5ACC, 0x663E, 0x9669, 0x73B0, 0x732E,
+ 0x53BF, 0x817A, 0x9985, 0x7FA1, 0x5BAA, 0x9677, 0x9650, 0x7EBF,
+ 0x76F8, 0x53A2, 0x9576, 0x9999, 0x7BB1, 0x8944, 0x6E58, 0x4E61,
+ 0x7FD4, 0x7965, 0x8BE6, 0x60F3, 0x54CD, 0x4EAB, 0x9879, 0x5DF7,
+ 0x6A61, 0x50CF, 0x5411, 0x8C61, 0x8427, 0x785D, 0x9704, 0x524A,
+ 0x54EE, 0x56A3, 0x9500, 0x6D88, 0x5BB5, 0x6DC6, 0x6653,
+ /* GB 0xD040..0xD07E */
+ 0x8824, 0x8825, 0x8826, 0x8827, 0x8828, 0x8829, 0x882A, 0x882B,
+ 0x882C, 0x882D, 0x882E, 0x882F, 0x8830, 0x8831, 0x8833, 0x8834,
+ 0x8835, 0x8836, 0x8837, 0x8838, 0x883A, 0x883B, 0x883D, 0x883E,
+ 0x883F, 0x8841, 0x8842, 0x8843, 0x8846, 0x8847, 0x8848, 0x8849,
+ 0x884A, 0x884B, 0x884E, 0x884F, 0x8850, 0x8851, 0x8852, 0x8853,
+ 0x8855, 0x8856, 0x8858, 0x885A, 0x885B, 0x885C, 0x885D, 0x885E,
+ 0x885F, 0x8860, 0x8866, 0x8867, 0x886A, 0x886D, 0x886F, 0x8871,
+ 0x8873, 0x8874, 0x8875, 0x8876, 0x8878, 0x8879, 0x887A,
+ /* GB 0xD080..0xD0FE */
+ 0x887B, 0x887C, 0x8880, 0x8883, 0x8886, 0x8887, 0x8889, 0x888A,
+ 0x888C, 0x888E, 0x888F, 0x8890, 0x8891, 0x8893, 0x8894, 0x8895,
+ 0x8897, 0x8898, 0x8899, 0x889A, 0x889B, 0x889D, 0x889E, 0x889F,
+ 0x88A0, 0x88A1, 0x88A3, 0x88A5, 0x88A6, 0x88A7, 0x88A8, 0x88A9,
+ 0x88AA, 0x5C0F, 0x5B5D, 0x6821, 0x8096, 0x5578, 0x7B11, 0x6548,
+ 0x6954, 0x4E9B, 0x6B47, 0x874E, 0x978B, 0x534F, 0x631F, 0x643A,
+ 0x90AA, 0x659C, 0x80C1, 0x8C10, 0x5199, 0x68B0, 0x5378, 0x87F9,
+ 0x61C8, 0x6CC4, 0x6CFB, 0x8C22, 0x5C51, 0x85AA, 0x82AF, 0x950C,
+ 0x6B23, 0x8F9B, 0x65B0, 0x5FFB, 0x5FC3, 0x4FE1, 0x8845, 0x661F,
+ 0x8165, 0x7329, 0x60FA, 0x5174, 0x5211, 0x578B, 0x5F62, 0x90A2,
+ 0x884C, 0x9192, 0x5E78, 0x674F, 0x6027, 0x59D3, 0x5144, 0x51F6,
+ 0x80F8, 0x5308, 0x6C79, 0x96C4, 0x718A, 0x4F11, 0x4FEE, 0x7F9E,
+ 0x673D, 0x55C5, 0x9508, 0x79C0, 0x8896, 0x7EE3, 0x589F, 0x620C,
+ 0x9700, 0x865A, 0x5618, 0x987B, 0x5F90, 0x8BB8, 0x84C4, 0x9157,
+ 0x53D9, 0x65ED, 0x5E8F, 0x755C, 0x6064, 0x7D6E, 0x5A7F, 0x7EEA,
+ 0x7EED, 0x8F69, 0x55A7, 0x5BA3, 0x60AC, 0x65CB, 0x7384,
+ /* GB 0xD140..0xD17E */
+ 0x88AC, 0x88AE, 0x88AF, 0x88B0, 0x88B2, 0x88B3, 0x88B4, 0x88B5,
+ 0x88B6, 0x88B8, 0x88B9, 0x88BA, 0x88BB, 0x88BD, 0x88BE, 0x88BF,
+ 0x88C0, 0x88C3, 0x88C4, 0x88C7, 0x88C8, 0x88CA, 0x88CB, 0x88CC,
+ 0x88CD, 0x88CF, 0x88D0, 0x88D1, 0x88D3, 0x88D6, 0x88D7, 0x88DA,
+ 0x88DB, 0x88DC, 0x88DD, 0x88DE, 0x88E0, 0x88E1, 0x88E6, 0x88E7,
+ 0x88E9, 0x88EA, 0x88EB, 0x88EC, 0x88ED, 0x88EE, 0x88EF, 0x88F2,
+ 0x88F5, 0x88F6, 0x88F7, 0x88FA, 0x88FB, 0x88FD, 0x88FF, 0x8900,
+ 0x8901, 0x8903, 0x8904, 0x8905, 0x8906, 0x8907, 0x8908,
+ /* GB 0xD180..0xD1FE */
+ 0x8909, 0x890B, 0x890C, 0x890D, 0x890E, 0x890F, 0x8911, 0x8914,
+ 0x8915, 0x8916, 0x8917, 0x8918, 0x891C, 0x891D, 0x891E, 0x891F,
+ 0x8920, 0x8922, 0x8923, 0x8924, 0x8926, 0x8927, 0x8928, 0x8929,
+ 0x892C, 0x892D, 0x892E, 0x892F, 0x8931, 0x8932, 0x8933, 0x8935,
+ 0x8937, 0x9009, 0x7663, 0x7729, 0x7EDA, 0x9774, 0x859B, 0x5B66,
+ 0x7A74, 0x96EA, 0x8840, 0x52CB, 0x718F, 0x5FAA, 0x65EC, 0x8BE2,
+ 0x5BFB, 0x9A6F, 0x5DE1, 0x6B89, 0x6C5B, 0x8BAD, 0x8BAF, 0x900A,
+ 0x8FC5, 0x538B, 0x62BC, 0x9E26, 0x9E2D, 0x5440, 0x4E2B, 0x82BD,
+ 0x7259, 0x869C, 0x5D16, 0x8859, 0x6DAF, 0x96C5, 0x54D1, 0x4E9A,
+ 0x8BB6, 0x7109, 0x54BD, 0x9609, 0x70DF, 0x6DF9, 0x76D0, 0x4E25,
+ 0x7814, 0x8712, 0x5CA9, 0x5EF6, 0x8A00, 0x989C, 0x960E, 0x708E,
+ 0x6CBF, 0x5944, 0x63A9, 0x773C, 0x884D, 0x6F14, 0x8273, 0x5830,
+ 0x71D5, 0x538C, 0x781A, 0x96C1, 0x5501, 0x5F66, 0x7130, 0x5BB4,
+ 0x8C1A, 0x9A8C, 0x6B83, 0x592E, 0x9E2F, 0x79E7, 0x6768, 0x626C,
+ 0x4F6F, 0x75A1, 0x7F8A, 0x6D0B, 0x9633, 0x6C27, 0x4EF0, 0x75D2,
+ 0x517B, 0x6837, 0x6F3E, 0x9080, 0x8170, 0x5996, 0x7476,
+ /* GB 0xD240..0xD27E */
+ 0x8938, 0x8939, 0x893A, 0x893B, 0x893C, 0x893D, 0x893E, 0x893F,
+ 0x8940, 0x8942, 0x8943, 0x8945, 0x8946, 0x8947, 0x8948, 0x8949,
+ 0x894A, 0x894B, 0x894C, 0x894D, 0x894E, 0x894F, 0x8950, 0x8951,
+ 0x8952, 0x8953, 0x8954, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959,
+ 0x895A, 0x895B, 0x895C, 0x895D, 0x8960, 0x8961, 0x8962, 0x8963,
+ 0x8964, 0x8965, 0x8967, 0x8968, 0x8969, 0x896A, 0x896B, 0x896C,
+ 0x896D, 0x896E, 0x896F, 0x8970, 0x8971, 0x8972, 0x8973, 0x8974,
+ 0x8975, 0x8976, 0x8977, 0x8978, 0x8979, 0x897A, 0x897C,
+ /* GB 0xD280..0xD2FE */
+ 0x897D, 0x897E, 0x8980, 0x8982, 0x8984, 0x8985, 0x8987, 0x8988,
+ 0x8989, 0x898A, 0x898B, 0x898C, 0x898D, 0x898E, 0x898F, 0x8990,
+ 0x8991, 0x8992, 0x8993, 0x8994, 0x8995, 0x8996, 0x8997, 0x8998,
+ 0x8999, 0x899A, 0x899B, 0x899C, 0x899D, 0x899E, 0x899F, 0x89A0,
+ 0x89A1, 0x6447, 0x5C27, 0x9065, 0x7A91, 0x8C23, 0x59DA, 0x54AC,
+ 0x8200, 0x836F, 0x8981, 0x8000, 0x6930, 0x564E, 0x8036, 0x7237,
+ 0x91CE, 0x51B6, 0x4E5F, 0x9875, 0x6396, 0x4E1A, 0x53F6, 0x66F3,
+ 0x814B, 0x591C, 0x6DB2, 0x4E00, 0x58F9, 0x533B, 0x63D6, 0x94F1,
+ 0x4F9D, 0x4F0A, 0x8863, 0x9890, 0x5937, 0x9057, 0x79FB, 0x4EEA,
+ 0x80F0, 0x7591, 0x6C82, 0x5B9C, 0x59E8, 0x5F5D, 0x6905, 0x8681,
+ 0x501A, 0x5DF2, 0x4E59, 0x77E3, 0x4EE5, 0x827A, 0x6291, 0x6613,
+ 0x9091, 0x5C79, 0x4EBF, 0x5F79, 0x81C6, 0x9038, 0x8084, 0x75AB,
+ 0x4EA6, 0x88D4, 0x610F, 0x6BC5, 0x5FC6, 0x4E49, 0x76CA, 0x6EA2,
+ 0x8BE3, 0x8BAE, 0x8C0A, 0x8BD1, 0x5F02, 0x7FFC, 0x7FCC, 0x7ECE,
+ 0x8335, 0x836B, 0x56E0, 0x6BB7, 0x97F3, 0x9634, 0x59FB, 0x541F,
+ 0x94F6, 0x6DEB, 0x5BC5, 0x996E, 0x5C39, 0x5F15, 0x9690,
+ /* GB 0xD340..0xD37E */
+ 0x89A2, 0x89A3, 0x89A4, 0x89A5, 0x89A6, 0x89A7, 0x89A8, 0x89A9,
+ 0x89AA, 0x89AB, 0x89AC, 0x89AD, 0x89AE, 0x89AF, 0x89B0, 0x89B1,
+ 0x89B2, 0x89B3, 0x89B4, 0x89B5, 0x89B6, 0x89B7, 0x89B8, 0x89B9,
+ 0x89BA, 0x89BB, 0x89BC, 0x89BD, 0x89BE, 0x89BF, 0x89C0, 0x89C3,
+ 0x89CD, 0x89D3, 0x89D4, 0x89D5, 0x89D7, 0x89D8, 0x89D9, 0x89DB,
+ 0x89DD, 0x89DF, 0x89E0, 0x89E1, 0x89E2, 0x89E4, 0x89E7, 0x89E8,
+ 0x89E9, 0x89EA, 0x89EC, 0x89ED, 0x89EE, 0x89F0, 0x89F1, 0x89F2,
+ 0x89F4, 0x89F5, 0x89F6, 0x89F7, 0x89F8, 0x89F9, 0x89FA,
+ /* GB 0xD380..0xD3FE */
+ 0x89FB, 0x89FC, 0x89FD, 0x89FE, 0x89FF, 0x8A01, 0x8A02, 0x8A03,
+ 0x8A04, 0x8A05, 0x8A06, 0x8A08, 0x8A09, 0x8A0A, 0x8A0B, 0x8A0C,
+ 0x8A0D, 0x8A0E, 0x8A0F, 0x8A10, 0x8A11, 0x8A12, 0x8A13, 0x8A14,
+ 0x8A15, 0x8A16, 0x8A17, 0x8A18, 0x8A19, 0x8A1A, 0x8A1B, 0x8A1C,
+ 0x8A1D, 0x5370, 0x82F1, 0x6A31, 0x5A74, 0x9E70, 0x5E94, 0x7F28,
+ 0x83B9, 0x8424, 0x8425, 0x8367, 0x8747, 0x8FCE, 0x8D62, 0x76C8,
+ 0x5F71, 0x9896, 0x786C, 0x6620, 0x54DF, 0x62E5, 0x4F63, 0x81C3,
+ 0x75C8, 0x5EB8, 0x96CD, 0x8E0A, 0x86F9, 0x548F, 0x6CF3, 0x6D8C,
+ 0x6C38, 0x607F, 0x52C7, 0x7528, 0x5E7D, 0x4F18, 0x60A0, 0x5FE7,
+ 0x5C24, 0x7531, 0x90AE, 0x94C0, 0x72B9, 0x6CB9, 0x6E38, 0x9149,
+ 0x6709, 0x53CB, 0x53F3, 0x4F51, 0x91C9, 0x8BF1, 0x53C8, 0x5E7C,
+ 0x8FC2, 0x6DE4, 0x4E8E, 0x76C2, 0x6986, 0x865E, 0x611A, 0x8206,
+ 0x4F59, 0x4FDE, 0x903E, 0x9C7C, 0x6109, 0x6E1D, 0x6E14, 0x9685,
+ 0x4E88, 0x5A31, 0x96E8, 0x4E0E, 0x5C7F, 0x79B9, 0x5B87, 0x8BED,
+ 0x7FBD, 0x7389, 0x57DF, 0x828B, 0x90C1, 0x5401, 0x9047, 0x55BB,
+ 0x5CEA, 0x5FA1, 0x6108, 0x6B32, 0x72F1, 0x80B2, 0x8A89,
+ /* GB 0xD440..0xD47E */
+ 0x8A1E, 0x8A1F, 0x8A20, 0x8A21, 0x8A22, 0x8A23, 0x8A24, 0x8A25,
+ 0x8A26, 0x8A27, 0x8A28, 0x8A29, 0x8A2A, 0x8A2B, 0x8A2C, 0x8A2D,
+ 0x8A2E, 0x8A2F, 0x8A30, 0x8A31, 0x8A32, 0x8A33, 0x8A34, 0x8A35,
+ 0x8A36, 0x8A37, 0x8A38, 0x8A39, 0x8A3A, 0x8A3B, 0x8A3C, 0x8A3D,
+ 0x8A3F, 0x8A40, 0x8A41, 0x8A42, 0x8A43, 0x8A44, 0x8A45, 0x8A46,
+ 0x8A47, 0x8A49, 0x8A4A, 0x8A4B, 0x8A4C, 0x8A4D, 0x8A4E, 0x8A4F,
+ 0x8A50, 0x8A51, 0x8A52, 0x8A53, 0x8A54, 0x8A55, 0x8A56, 0x8A57,
+ 0x8A58, 0x8A59, 0x8A5A, 0x8A5B, 0x8A5C, 0x8A5D, 0x8A5E,
+ /* GB 0xD480..0xD4FE */
+ 0x8A5F, 0x8A60, 0x8A61, 0x8A62, 0x8A63, 0x8A64, 0x8A65, 0x8A66,
+ 0x8A67, 0x8A68, 0x8A69, 0x8A6A, 0x8A6B, 0x8A6C, 0x8A6D, 0x8A6E,
+ 0x8A6F, 0x8A70, 0x8A71, 0x8A72, 0x8A73, 0x8A74, 0x8A75, 0x8A76,
+ 0x8A77, 0x8A78, 0x8A7A, 0x8A7B, 0x8A7C, 0x8A7D, 0x8A7E, 0x8A7F,
+ 0x8A80, 0x6D74, 0x5BD3, 0x88D5, 0x9884, 0x8C6B, 0x9A6D, 0x9E33,
+ 0x6E0A, 0x51A4, 0x5143, 0x57A3, 0x8881, 0x539F, 0x63F4, 0x8F95,
+ 0x56ED, 0x5458, 0x5706, 0x733F, 0x6E90, 0x7F18, 0x8FDC, 0x82D1,
+ 0x613F, 0x6028, 0x9662, 0x66F0, 0x7EA6, 0x8D8A, 0x8DC3, 0x94A5,
+ 0x5CB3, 0x7CA4, 0x6708, 0x60A6, 0x9605, 0x8018, 0x4E91, 0x90E7,
+ 0x5300, 0x9668, 0x5141, 0x8FD0, 0x8574, 0x915D, 0x6655, 0x97F5,
+ 0x5B55, 0x531D, 0x7838, 0x6742, 0x683D, 0x54C9, 0x707E, 0x5BB0,
+ 0x8F7D, 0x518D, 0x5728, 0x54B1, 0x6512, 0x6682, 0x8D5E, 0x8D43,
+ 0x810F, 0x846C, 0x906D, 0x7CDF, 0x51FF, 0x85FB, 0x67A3, 0x65E9,
+ 0x6FA1, 0x86A4, 0x8E81, 0x566A, 0x9020, 0x7682, 0x7076, 0x71E5,
+ 0x8D23, 0x62E9, 0x5219, 0x6CFD, 0x8D3C, 0x600E, 0x589E, 0x618E,
+ 0x66FE, 0x8D60, 0x624E, 0x55B3, 0x6E23, 0x672D, 0x8F67,
+ /* GB 0xD540..0xD57E */
+ 0x8A81, 0x8A82, 0x8A83, 0x8A84, 0x8A85, 0x8A86, 0x8A87, 0x8A88,
+ 0x8A8B, 0x8A8C, 0x8A8D, 0x8A8E, 0x8A8F, 0x8A90, 0x8A91, 0x8A92,
+ 0x8A94, 0x8A95, 0x8A96, 0x8A97, 0x8A98, 0x8A99, 0x8A9A, 0x8A9B,
+ 0x8A9C, 0x8A9D, 0x8A9E, 0x8A9F, 0x8AA0, 0x8AA1, 0x8AA2, 0x8AA3,
+ 0x8AA4, 0x8AA5, 0x8AA6, 0x8AA7, 0x8AA8, 0x8AA9, 0x8AAA, 0x8AAB,
+ 0x8AAC, 0x8AAD, 0x8AAE, 0x8AAF, 0x8AB0, 0x8AB1, 0x8AB2, 0x8AB3,
+ 0x8AB4, 0x8AB5, 0x8AB6, 0x8AB7, 0x8AB8, 0x8AB9, 0x8ABA, 0x8ABB,
+ 0x8ABC, 0x8ABD, 0x8ABE, 0x8ABF, 0x8AC0, 0x8AC1, 0x8AC2,
+ /* GB 0xD580..0xD5FE */
+ 0x8AC3, 0x8AC4, 0x8AC5, 0x8AC6, 0x8AC7, 0x8AC8, 0x8AC9, 0x8ACA,
+ 0x8ACB, 0x8ACC, 0x8ACD, 0x8ACE, 0x8ACF, 0x8AD0, 0x8AD1, 0x8AD2,
+ 0x8AD3, 0x8AD4, 0x8AD5, 0x8AD6, 0x8AD7, 0x8AD8, 0x8AD9, 0x8ADA,
+ 0x8ADB, 0x8ADC, 0x8ADD, 0x8ADE, 0x8ADF, 0x8AE0, 0x8AE1, 0x8AE2,
+ 0x8AE3, 0x94E1, 0x95F8, 0x7728, 0x6805, 0x69A8, 0x548B, 0x4E4D,
+ 0x70B8, 0x8BC8, 0x6458, 0x658B, 0x5B85, 0x7A84, 0x503A, 0x5BE8,
+ 0x77BB, 0x6BE1, 0x8A79, 0x7C98, 0x6CBE, 0x76CF, 0x65A9, 0x8F97,
+ 0x5D2D, 0x5C55, 0x8638, 0x6808, 0x5360, 0x6218, 0x7AD9, 0x6E5B,
+ 0x7EFD, 0x6A1F, 0x7AE0, 0x5F70, 0x6F33, 0x5F20, 0x638C, 0x6DA8,
+ 0x6756, 0x4E08, 0x5E10, 0x8D26, 0x4ED7, 0x80C0, 0x7634, 0x969C,
+ 0x62DB, 0x662D, 0x627E, 0x6CBC, 0x8D75, 0x7167, 0x7F69, 0x5146,
+ 0x8087, 0x53EC, 0x906E, 0x6298, 0x54F2, 0x86F0, 0x8F99, 0x8005,
+ 0x9517, 0x8517, 0x8FD9, 0x6D59, 0x73CD, 0x659F, 0x771F, 0x7504,
+ 0x7827, 0x81FB, 0x8D1E, 0x9488, 0x4FA6, 0x6795, 0x75B9, 0x8BCA,
+ 0x9707, 0x632F, 0x9547, 0x9635, 0x84B8, 0x6323, 0x7741, 0x5F81,
+ 0x72F0, 0x4E89, 0x6014, 0x6574, 0x62EF, 0x6B63, 0x653F,
+ /* GB 0xD640..0xD67E */
+ 0x8AE4, 0x8AE5, 0x8AE6, 0x8AE7, 0x8AE8, 0x8AE9, 0x8AEA, 0x8AEB,
+ 0x8AEC, 0x8AED, 0x8AEE, 0x8AEF, 0x8AF0, 0x8AF1, 0x8AF2, 0x8AF3,
+ 0x8AF4, 0x8AF5, 0x8AF6, 0x8AF7, 0x8AF8, 0x8AF9, 0x8AFA, 0x8AFB,
+ 0x8AFC, 0x8AFD, 0x8AFE, 0x8AFF, 0x8B00, 0x8B01, 0x8B02, 0x8B03,
+ 0x8B04, 0x8B05, 0x8B06, 0x8B08, 0x8B09, 0x8B0A, 0x8B0B, 0x8B0C,
+ 0x8B0D, 0x8B0E, 0x8B0F, 0x8B10, 0x8B11, 0x8B12, 0x8B13, 0x8B14,
+ 0x8B15, 0x8B16, 0x8B17, 0x8B18, 0x8B19, 0x8B1A, 0x8B1B, 0x8B1C,
+ 0x8B1D, 0x8B1E, 0x8B1F, 0x8B20, 0x8B21, 0x8B22, 0x8B23,
+ /* GB 0xD680..0xD6FE */
+ 0x8B24, 0x8B25, 0x8B27, 0x8B28, 0x8B29, 0x8B2A, 0x8B2B, 0x8B2C,
+ 0x8B2D, 0x8B2E, 0x8B2F, 0x8B30, 0x8B31, 0x8B32, 0x8B33, 0x8B34,
+ 0x8B35, 0x8B36, 0x8B37, 0x8B38, 0x8B39, 0x8B3A, 0x8B3B, 0x8B3C,
+ 0x8B3D, 0x8B3E, 0x8B3F, 0x8B40, 0x8B41, 0x8B42, 0x8B43, 0x8B44,
+ 0x8B45, 0x5E27, 0x75C7, 0x90D1, 0x8BC1, 0x829D, 0x679D, 0x652F,
+ 0x5431, 0x8718, 0x77E5, 0x80A2, 0x8102, 0x6C41, 0x4E4B, 0x7EC7,
+ 0x804C, 0x76F4, 0x690D, 0x6B96, 0x6267, 0x503C, 0x4F84, 0x5740,
+ 0x6307, 0x6B62, 0x8DBE, 0x53EA, 0x65E8, 0x7EB8, 0x5FD7, 0x631A,
+ 0x63B7, 0x81F3, 0x81F4, 0x7F6E, 0x5E1C, 0x5CD9, 0x5236, 0x667A,
+ 0x79E9, 0x7A1A, 0x8D28, 0x7099, 0x75D4, 0x6EDE, 0x6CBB, 0x7A92,
+ 0x4E2D, 0x76C5, 0x5FE0, 0x949F, 0x8877, 0x7EC8, 0x79CD, 0x80BF,
+ 0x91CD, 0x4EF2, 0x4F17, 0x821F, 0x5468, 0x5DDE, 0x6D32, 0x8BCC,
+ 0x7CA5, 0x8F74, 0x8098, 0x5E1A, 0x5492, 0x76B1, 0x5B99, 0x663C,
+ 0x9AA4, 0x73E0, 0x682A, 0x86DB, 0x6731, 0x732A, 0x8BF8, 0x8BDB,
+ 0x9010, 0x7AF9, 0x70DB, 0x716E, 0x62C4, 0x77A9, 0x5631, 0x4E3B,
+ 0x8457, 0x67F1, 0x52A9, 0x86C0, 0x8D2E, 0x94F8, 0x7B51,
+ /* GB 0xD740..0xD77E */
+ 0x8B46, 0x8B47, 0x8B48, 0x8B49, 0x8B4A, 0x8B4B, 0x8B4C, 0x8B4D,
+ 0x8B4E, 0x8B4F, 0x8B50, 0x8B51, 0x8B52, 0x8B53, 0x8B54, 0x8B55,
+ 0x8B56, 0x8B57, 0x8B58, 0x8B59, 0x8B5A, 0x8B5B, 0x8B5C, 0x8B5D,
+ 0x8B5E, 0x8B5F, 0x8B60, 0x8B61, 0x8B62, 0x8B63, 0x8B64, 0x8B65,
+ 0x8B67, 0x8B68, 0x8B69, 0x8B6A, 0x8B6B, 0x8B6D, 0x8B6E, 0x8B6F,
+ 0x8B70, 0x8B71, 0x8B72, 0x8B73, 0x8B74, 0x8B75, 0x8B76, 0x8B77,
+ 0x8B78, 0x8B79, 0x8B7A, 0x8B7B, 0x8B7C, 0x8B7D, 0x8B7E, 0x8B7F,
+ 0x8B80, 0x8B81, 0x8B82, 0x8B83, 0x8B84, 0x8B85, 0x8B86,
+ /* GB 0xD780..0xD7FE */
+ 0x8B87, 0x8B88, 0x8B89, 0x8B8A, 0x8B8B, 0x8B8C, 0x8B8D, 0x8B8E,
+ 0x8B8F, 0x8B90, 0x8B91, 0x8B92, 0x8B93, 0x8B94, 0x8B95, 0x8B96,
+ 0x8B97, 0x8B98, 0x8B99, 0x8B9A, 0x8B9B, 0x8B9C, 0x8B9D, 0x8B9E,
+ 0x8B9F, 0x8BAC, 0x8BB1, 0x8BBB, 0x8BC7, 0x8BD0, 0x8BEA, 0x8C09,
+ 0x8C1E, 0x4F4F, 0x6CE8, 0x795D, 0x9A7B, 0x6293, 0x722A, 0x62FD,
+ 0x4E13, 0x7816, 0x8F6C, 0x64B0, 0x8D5A, 0x7BC6, 0x6869, 0x5E84,
+ 0x88C5, 0x5986, 0x649E, 0x58EE, 0x72B6, 0x690E, 0x9525, 0x8FFD,
+ 0x8D58, 0x5760, 0x7F00, 0x8C06, 0x51C6, 0x6349, 0x62D9, 0x5353,
+ 0x684C, 0x7422, 0x8301, 0x914C, 0x5544, 0x7740, 0x707C, 0x6D4A,
+ 0x5179, 0x54A8, 0x8D44, 0x59FF, 0x6ECB, 0x6DC4, 0x5B5C, 0x7D2B,
+ 0x4ED4, 0x7C7D, 0x6ED3, 0x5B50, 0x81EA, 0x6E0D, 0x5B57, 0x9B03,
+ 0x68D5, 0x8E2A, 0x5B97, 0x7EFC, 0x603B, 0x7EB5, 0x90B9, 0x8D70,
+ 0x594F, 0x63CD, 0x79DF, 0x8DB3, 0x5352, 0x65CF, 0x7956, 0x8BC5,
+ 0x963B, 0x7EC4, 0x94BB, 0x7E82, 0x5634, 0x9189, 0x6700, 0x7F6A,
+ 0x5C0A, 0x9075, 0x6628, 0x5DE6, 0x4F50, 0x67DE, 0x505A, 0x4F5C,
+ 0x5750, 0x5EA7, 0xE810, 0xE811, 0xE812, 0xE813, 0xE814,
+ /* GB 0xD840..0xD87E */
+ 0x8C38, 0x8C39, 0x8C3A, 0x8C3B, 0x8C3C, 0x8C3D, 0x8C3E, 0x8C3F,
+ 0x8C40, 0x8C42, 0x8C43, 0x8C44, 0x8C45, 0x8C48, 0x8C4A, 0x8C4B,
+ 0x8C4D, 0x8C4E, 0x8C4F, 0x8C50, 0x8C51, 0x8C52, 0x8C53, 0x8C54,
+ 0x8C56, 0x8C57, 0x8C58, 0x8C59, 0x8C5B, 0x8C5C, 0x8C5D, 0x8C5E,
+ 0x8C5F, 0x8C60, 0x8C63, 0x8C64, 0x8C65, 0x8C66, 0x8C67, 0x8C68,
+ 0x8C69, 0x8C6C, 0x8C6D, 0x8C6E, 0x8C6F, 0x8C70, 0x8C71, 0x8C72,
+ 0x8C74, 0x8C75, 0x8C76, 0x8C77, 0x8C7B, 0x8C7C, 0x8C7D, 0x8C7E,
+ 0x8C7F, 0x8C80, 0x8C81, 0x8C83, 0x8C84, 0x8C86, 0x8C87,
+ /* GB 0xD880..0xD8FE */
+ 0x8C88, 0x8C8B, 0x8C8D, 0x8C8E, 0x8C8F, 0x8C90, 0x8C91, 0x8C92,
+ 0x8C93, 0x8C95, 0x8C96, 0x8C97, 0x8C99, 0x8C9A, 0x8C9B, 0x8C9C,
+ 0x8C9D, 0x8C9E, 0x8C9F, 0x8CA0, 0x8CA1, 0x8CA2, 0x8CA3, 0x8CA4,
+ 0x8CA5, 0x8CA6, 0x8CA7, 0x8CA8, 0x8CA9, 0x8CAA, 0x8CAB, 0x8CAC,
+ 0x8CAD, 0x4E8D, 0x4E0C, 0x5140, 0x4E10, 0x5EFF, 0x5345, 0x4E15,
+ 0x4E98, 0x4E1E, 0x9B32, 0x5B6C, 0x5669, 0x4E28, 0x79BA, 0x4E3F,
+ 0x5315, 0x4E47, 0x592D, 0x723B, 0x536E, 0x6C10, 0x56DF, 0x80E4,
+ 0x9997, 0x6BD3, 0x777E, 0x9F17, 0x4E36, 0x4E9F, 0x9F10, 0x4E5C,
+ 0x4E69, 0x4E93, 0x8288, 0x5B5B, 0x556C, 0x560F, 0x4EC4, 0x538D,
+ 0x539D, 0x53A3, 0x53A5, 0x53AE, 0x9765, 0x8D5D, 0x531A, 0x53F5,
+ 0x5326, 0x532E, 0x533E, 0x8D5C, 0x5366, 0x5363, 0x5202, 0x5208,
+ 0x520E, 0x522D, 0x5233, 0x523F, 0x5240, 0x524C, 0x525E, 0x5261,
+ 0x525C, 0x84AF, 0x527D, 0x5282, 0x5281, 0x5290, 0x5293, 0x5182,
+ 0x7F54, 0x4EBB, 0x4EC3, 0x4EC9, 0x4EC2, 0x4EE8, 0x4EE1, 0x4EEB,
+ 0x4EDE, 0x4F1B, 0x4EF3, 0x4F22, 0x4F64, 0x4EF5, 0x4F25, 0x4F27,
+ 0x4F09, 0x4F2B, 0x4F5E, 0x4F67, 0x6538, 0x4F5A, 0x4F5D,
+ /* GB 0xD940..0xD97E */
+ 0x8CAE, 0x8CAF, 0x8CB0, 0x8CB1, 0x8CB2, 0x8CB3, 0x8CB4, 0x8CB5,
+ 0x8CB6, 0x8CB7, 0x8CB8, 0x8CB9, 0x8CBA, 0x8CBB, 0x8CBC, 0x8CBD,
+ 0x8CBE, 0x8CBF, 0x8CC0, 0x8CC1, 0x8CC2, 0x8CC3, 0x8CC4, 0x8CC5,
+ 0x8CC6, 0x8CC7, 0x8CC8, 0x8CC9, 0x8CCA, 0x8CCB, 0x8CCC, 0x8CCD,
+ 0x8CCE, 0x8CCF, 0x8CD0, 0x8CD1, 0x8CD2, 0x8CD3, 0x8CD4, 0x8CD5,
+ 0x8CD6, 0x8CD7, 0x8CD8, 0x8CD9, 0x8CDA, 0x8CDB, 0x8CDC, 0x8CDD,
+ 0x8CDE, 0x8CDF, 0x8CE0, 0x8CE1, 0x8CE2, 0x8CE3, 0x8CE4, 0x8CE5,
+ 0x8CE6, 0x8CE7, 0x8CE8, 0x8CE9, 0x8CEA, 0x8CEB, 0x8CEC,
+ /* GB 0xD980..0xD9FE */
+ 0x8CED, 0x8CEE, 0x8CEF, 0x8CF0, 0x8CF1, 0x8CF2, 0x8CF3, 0x8CF4,
+ 0x8CF5, 0x8CF6, 0x8CF7, 0x8CF8, 0x8CF9, 0x8CFA, 0x8CFB, 0x8CFC,
+ 0x8CFD, 0x8CFE, 0x8CFF, 0x8D00, 0x8D01, 0x8D02, 0x8D03, 0x8D04,
+ 0x8D05, 0x8D06, 0x8D07, 0x8D08, 0x8D09, 0x8D0A, 0x8D0B, 0x8D0C,
+ 0x8D0D, 0x4F5F, 0x4F57, 0x4F32, 0x4F3D, 0x4F76, 0x4F74, 0x4F91,
+ 0x4F89, 0x4F83, 0x4F8F, 0x4F7E, 0x4F7B, 0x4FAA, 0x4F7C, 0x4FAC,
+ 0x4F94, 0x4FE6, 0x4FE8, 0x4FEA, 0x4FC5, 0x4FDA, 0x4FE3, 0x4FDC,
+ 0x4FD1, 0x4FDF, 0x4FF8, 0x5029, 0x504C, 0x4FF3, 0x502C, 0x500F,
+ 0x502E, 0x502D, 0x4FFE, 0x501C, 0x500C, 0x5025, 0x5028, 0x507E,
+ 0x5043, 0x5055, 0x5048, 0x504E, 0x506C, 0x507B, 0x50A5, 0x50A7,
+ 0x50A9, 0x50BA, 0x50D6, 0x5106, 0x50ED, 0x50EC, 0x50E6, 0x50EE,
+ 0x5107, 0x510B, 0x4EDD, 0x6C3D, 0x4F58, 0x4F65, 0x4FCE, 0x9FA0,
+ 0x6C46, 0x7C74, 0x516E, 0x5DFD, 0x9EC9, 0x9998, 0x5181, 0x5914,
+ 0x52F9, 0x530D, 0x8A07, 0x5310, 0x51EB, 0x5919, 0x5155, 0x4EA0,
+ 0x5156, 0x4EB3, 0x886E, 0x88A4, 0x4EB5, 0x8114, 0x88D2, 0x7980,
+ 0x5B34, 0x8803, 0x7FB8, 0x51AB, 0x51B1, 0x51BD, 0x51BC,
+ /* GB 0xDA40..0xDA7E */
+ 0x8D0E, 0x8D0F, 0x8D10, 0x8D11, 0x8D12, 0x8D13, 0x8D14, 0x8D15,
+ 0x8D16, 0x8D17, 0x8D18, 0x8D19, 0x8D1A, 0x8D1B, 0x8D1C, 0x8D20,
+ 0x8D51, 0x8D52, 0x8D57, 0x8D5F, 0x8D65, 0x8D68, 0x8D69, 0x8D6A,
+ 0x8D6C, 0x8D6E, 0x8D6F, 0x8D71, 0x8D72, 0x8D78, 0x8D79, 0x8D7A,
+ 0x8D7B, 0x8D7C, 0x8D7D, 0x8D7E, 0x8D7F, 0x8D80, 0x8D82, 0x8D83,
+ 0x8D86, 0x8D87, 0x8D88, 0x8D89, 0x8D8C, 0x8D8D, 0x8D8E, 0x8D8F,
+ 0x8D90, 0x8D92, 0x8D93, 0x8D95, 0x8D96, 0x8D97, 0x8D98, 0x8D99,
+ 0x8D9A, 0x8D9B, 0x8D9C, 0x8D9D, 0x8D9E, 0x8DA0, 0x8DA1,
+ /* GB 0xDA80..0xDAFE */
+ 0x8DA2, 0x8DA4, 0x8DA5, 0x8DA6, 0x8DA7, 0x8DA8, 0x8DA9, 0x8DAA,
+ 0x8DAB, 0x8DAC, 0x8DAD, 0x8DAE, 0x8DAF, 0x8DB0, 0x8DB2, 0x8DB6,
+ 0x8DB7, 0x8DB9, 0x8DBB, 0x8DBD, 0x8DC0, 0x8DC1, 0x8DC2, 0x8DC5,
+ 0x8DC7, 0x8DC8, 0x8DC9, 0x8DCA, 0x8DCD, 0x8DD0, 0x8DD2, 0x8DD3,
+ 0x8DD4, 0x51C7, 0x5196, 0x51A2, 0x51A5, 0x8BA0, 0x8BA6, 0x8BA7,
+ 0x8BAA, 0x8BB4, 0x8BB5, 0x8BB7, 0x8BC2, 0x8BC3, 0x8BCB, 0x8BCF,
+ 0x8BCE, 0x8BD2, 0x8BD3, 0x8BD4, 0x8BD6, 0x8BD8, 0x8BD9, 0x8BDC,
+ 0x8BDF, 0x8BE0, 0x8BE4, 0x8BE8, 0x8BE9, 0x8BEE, 0x8BF0, 0x8BF3,
+ 0x8BF6, 0x8BF9, 0x8BFC, 0x8BFF, 0x8C00, 0x8C02, 0x8C04, 0x8C07,
+ 0x8C0C, 0x8C0F, 0x8C11, 0x8C12, 0x8C14, 0x8C15, 0x8C16, 0x8C19,
+ 0x8C1B, 0x8C18, 0x8C1D, 0x8C1F, 0x8C20, 0x8C21, 0x8C25, 0x8C27,
+ 0x8C2A, 0x8C2B, 0x8C2E, 0x8C2F, 0x8C32, 0x8C33, 0x8C35, 0x8C36,
+ 0x5369, 0x537A, 0x961D, 0x9622, 0x9621, 0x9631, 0x962A, 0x963D,
+ 0x963C, 0x9642, 0x9649, 0x9654, 0x965F, 0x9667, 0x966C, 0x9672,
+ 0x9674, 0x9688, 0x968D, 0x9697, 0x96B0, 0x9097, 0x909B, 0x909D,
+ 0x9099, 0x90AC, 0x90A1, 0x90B4, 0x90B3, 0x90B6, 0x90BA,
+ /* GB 0xDB40..0xDB7E */
+ 0x8DD5, 0x8DD8, 0x8DD9, 0x8DDC, 0x8DE0, 0x8DE1, 0x8DE2, 0x8DE5,
+ 0x8DE6, 0x8DE7, 0x8DE9, 0x8DED, 0x8DEE, 0x8DF0, 0x8DF1, 0x8DF2,
+ 0x8DF4, 0x8DF6, 0x8DFC, 0x8DFE, 0x8DFF, 0x8E00, 0x8E01, 0x8E02,
+ 0x8E03, 0x8E04, 0x8E06, 0x8E07, 0x8E08, 0x8E0B, 0x8E0D, 0x8E0E,
+ 0x8E10, 0x8E11, 0x8E12, 0x8E13, 0x8E15, 0x8E16, 0x8E17, 0x8E18,
+ 0x8E19, 0x8E1A, 0x8E1B, 0x8E1C, 0x8E20, 0x8E21, 0x8E24, 0x8E25,
+ 0x8E26, 0x8E27, 0x8E28, 0x8E2B, 0x8E2D, 0x8E30, 0x8E32, 0x8E33,
+ 0x8E34, 0x8E36, 0x8E37, 0x8E38, 0x8E3B, 0x8E3C, 0x8E3E,
+ /* GB 0xDB80..0xDBFE */
+ 0x8E3F, 0x8E43, 0x8E45, 0x8E46, 0x8E4C, 0x8E4D, 0x8E4E, 0x8E4F,
+ 0x8E50, 0x8E53, 0x8E54, 0x8E55, 0x8E56, 0x8E57, 0x8E58, 0x8E5A,
+ 0x8E5B, 0x8E5C, 0x8E5D, 0x8E5E, 0x8E5F, 0x8E60, 0x8E61, 0x8E62,
+ 0x8E63, 0x8E64, 0x8E65, 0x8E67, 0x8E68, 0x8E6A, 0x8E6B, 0x8E6E,
+ 0x8E71, 0x90B8, 0x90B0, 0x90CF, 0x90C5, 0x90BE, 0x90D0, 0x90C4,
+ 0x90C7, 0x90D3, 0x90E6, 0x90E2, 0x90DC, 0x90D7, 0x90DB, 0x90EB,
+ 0x90EF, 0x90FE, 0x9104, 0x9122, 0x911E, 0x9123, 0x9131, 0x912F,
+ 0x9139, 0x9143, 0x9146, 0x520D, 0x5942, 0x52A2, 0x52AC, 0x52AD,
+ 0x52BE, 0x54FF, 0x52D0, 0x52D6, 0x52F0, 0x53DF, 0x71EE, 0x77CD,
+ 0x5EF4, 0x51F5, 0x51FC, 0x9B2F, 0x53B6, 0x5F01, 0x755A, 0x5DEF,
+ 0x574C, 0x57A9, 0x57A1, 0x587E, 0x58BC, 0x58C5, 0x58D1, 0x5729,
+ 0x572C, 0x572A, 0x5733, 0x5739, 0x572E, 0x572F, 0x575C, 0x573B,
+ 0x5742, 0x5769, 0x5785, 0x576B, 0x5786, 0x577C, 0x577B, 0x5768,
+ 0x576D, 0x5776, 0x5773, 0x57AD, 0x57A4, 0x578C, 0x57B2, 0x57CF,
+ 0x57A7, 0x57B4, 0x5793, 0x57A0, 0x57D5, 0x57D8, 0x57DA, 0x57D9,
+ 0x57D2, 0x57B8, 0x57F4, 0x57EF, 0x57F8, 0x57E4, 0x57DD,
+ /* GB 0xDC40..0xDC7E */
+ 0x8E73, 0x8E75, 0x8E77, 0x8E78, 0x8E79, 0x8E7A, 0x8E7B, 0x8E7D,
+ 0x8E7E, 0x8E80, 0x8E82, 0x8E83, 0x8E84, 0x8E86, 0x8E88, 0x8E89,
+ 0x8E8A, 0x8E8B, 0x8E8C, 0x8E8D, 0x8E8E, 0x8E91, 0x8E92, 0x8E93,
+ 0x8E95, 0x8E96, 0x8E97, 0x8E98, 0x8E99, 0x8E9A, 0x8E9B, 0x8E9D,
+ 0x8E9F, 0x8EA0, 0x8EA1, 0x8EA2, 0x8EA3, 0x8EA4, 0x8EA5, 0x8EA6,
+ 0x8EA7, 0x8EA8, 0x8EA9, 0x8EAA, 0x8EAD, 0x8EAE, 0x8EB0, 0x8EB1,
+ 0x8EB3, 0x8EB4, 0x8EB5, 0x8EB6, 0x8EB7, 0x8EB8, 0x8EB9, 0x8EBB,
+ 0x8EBC, 0x8EBD, 0x8EBE, 0x8EBF, 0x8EC0, 0x8EC1, 0x8EC2,
+ /* GB 0xDC80..0xDCFE */
+ 0x8EC3, 0x8EC4, 0x8EC5, 0x8EC6, 0x8EC7, 0x8EC8, 0x8EC9, 0x8ECA,
+ 0x8ECB, 0x8ECC, 0x8ECD, 0x8ECF, 0x8ED0, 0x8ED1, 0x8ED2, 0x8ED3,
+ 0x8ED4, 0x8ED5, 0x8ED6, 0x8ED7, 0x8ED8, 0x8ED9, 0x8EDA, 0x8EDB,
+ 0x8EDC, 0x8EDD, 0x8EDE, 0x8EDF, 0x8EE0, 0x8EE1, 0x8EE2, 0x8EE3,
+ 0x8EE4, 0x580B, 0x580D, 0x57FD, 0x57ED, 0x5800, 0x581E, 0x5819,
+ 0x5844, 0x5820, 0x5865, 0x586C, 0x5881, 0x5889, 0x589A, 0x5880,
+ 0x99A8, 0x9F19, 0x61FF, 0x8279, 0x827D, 0x827F, 0x828F, 0x828A,
+ 0x82A8, 0x8284, 0x828E, 0x8291, 0x8297, 0x8299, 0x82AB, 0x82B8,
+ 0x82BE, 0x82B0, 0x82C8, 0x82CA, 0x82E3, 0x8298, 0x82B7, 0x82AE,
+ 0x82CB, 0x82CC, 0x82C1, 0x82A9, 0x82B4, 0x82A1, 0x82AA, 0x829F,
+ 0x82C4, 0x82CE, 0x82A4, 0x82E1, 0x8309, 0x82F7, 0x82E4, 0x830F,
+ 0x8307, 0x82DC, 0x82F4, 0x82D2, 0x82D8, 0x830C, 0x82FB, 0x82D3,
+ 0x8311, 0x831A, 0x8306, 0x8314, 0x8315, 0x82E0, 0x82D5, 0x831C,
+ 0x8351, 0x835B, 0x835C, 0x8308, 0x8392, 0x833C, 0x8334, 0x8331,
+ 0x839B, 0x835E, 0x832F, 0x834F, 0x8347, 0x8343, 0x835F, 0x8340,
+ 0x8317, 0x8360, 0x832D, 0x833A, 0x8333, 0x8366, 0x8365,
+ /* GB 0xDD40..0xDD7E */
+ 0x8EE5, 0x8EE6, 0x8EE7, 0x8EE8, 0x8EE9, 0x8EEA, 0x8EEB, 0x8EEC,
+ 0x8EED, 0x8EEE, 0x8EEF, 0x8EF0, 0x8EF1, 0x8EF2, 0x8EF3, 0x8EF4,
+ 0x8EF5, 0x8EF6, 0x8EF7, 0x8EF8, 0x8EF9, 0x8EFA, 0x8EFB, 0x8EFC,
+ 0x8EFD, 0x8EFE, 0x8EFF, 0x8F00, 0x8F01, 0x8F02, 0x8F03, 0x8F04,
+ 0x8F05, 0x8F06, 0x8F07, 0x8F08, 0x8F09, 0x8F0A, 0x8F0B, 0x8F0C,
+ 0x8F0D, 0x8F0E, 0x8F0F, 0x8F10, 0x8F11, 0x8F12, 0x8F13, 0x8F14,
+ 0x8F15, 0x8F16, 0x8F17, 0x8F18, 0x8F19, 0x8F1A, 0x8F1B, 0x8F1C,
+ 0x8F1D, 0x8F1E, 0x8F1F, 0x8F20, 0x8F21, 0x8F22, 0x8F23,
+ /* GB 0xDD80..0xDDFE */
+ 0x8F24, 0x8F25, 0x8F26, 0x8F27, 0x8F28, 0x8F29, 0x8F2A, 0x8F2B,
+ 0x8F2C, 0x8F2D, 0x8F2E, 0x8F2F, 0x8F30, 0x8F31, 0x8F32, 0x8F33,
+ 0x8F34, 0x8F35, 0x8F36, 0x8F37, 0x8F38, 0x8F39, 0x8F3A, 0x8F3B,
+ 0x8F3C, 0x8F3D, 0x8F3E, 0x8F3F, 0x8F40, 0x8F41, 0x8F42, 0x8F43,
+ 0x8F44, 0x8368, 0x831B, 0x8369, 0x836C, 0x836A, 0x836D, 0x836E,
+ 0x83B0, 0x8378, 0x83B3, 0x83B4, 0x83A0, 0x83AA, 0x8393, 0x839C,
+ 0x8385, 0x837C, 0x83B6, 0x83A9, 0x837D, 0x83B8, 0x837B, 0x8398,
+ 0x839E, 0x83A8, 0x83BA, 0x83BC, 0x83C1, 0x8401, 0x83E5, 0x83D8,
+ 0x5807, 0x8418, 0x840B, 0x83DD, 0x83FD, 0x83D6, 0x841C, 0x8438,
+ 0x8411, 0x8406, 0x83D4, 0x83DF, 0x840F, 0x8403, 0x83F8, 0x83F9,
+ 0x83EA, 0x83C5, 0x83C0, 0x8426, 0x83F0, 0x83E1, 0x845C, 0x8451,
+ 0x845A, 0x8459, 0x8473, 0x8487, 0x8488, 0x847A, 0x8489, 0x8478,
+ 0x843C, 0x8446, 0x8469, 0x8476, 0x848C, 0x848E, 0x8431, 0x846D,
+ 0x84C1, 0x84CD, 0x84D0, 0x84E6, 0x84BD, 0x84D3, 0x84CA, 0x84BF,
+ 0x84BA, 0x84E0, 0x84A1, 0x84B9, 0x84B4, 0x8497, 0x84E5, 0x84E3,
+ 0x850C, 0x750D, 0x8538, 0x84F0, 0x8539, 0x851F, 0x853A,
+ /* GB 0xDE40..0xDE7E */
+ 0x8F45, 0x8F46, 0x8F47, 0x8F48, 0x8F49, 0x8F4A, 0x8F4B, 0x8F4C,
+ 0x8F4D, 0x8F4E, 0x8F4F, 0x8F50, 0x8F51, 0x8F52, 0x8F53, 0x8F54,
+ 0x8F55, 0x8F56, 0x8F57, 0x8F58, 0x8F59, 0x8F5A, 0x8F5B, 0x8F5C,
+ 0x8F5D, 0x8F5E, 0x8F5F, 0x8F60, 0x8F61, 0x8F62, 0x8F63, 0x8F64,
+ 0x8F65, 0x8F6A, 0x8F80, 0x8F8C, 0x8F92, 0x8F9D, 0x8FA0, 0x8FA1,
+ 0x8FA2, 0x8FA4, 0x8FA5, 0x8FA6, 0x8FA7, 0x8FAA, 0x8FAC, 0x8FAD,
+ 0x8FAE, 0x8FAF, 0x8FB2, 0x8FB3, 0x8FB4, 0x8FB5, 0x8FB7, 0x8FB8,
+ 0x8FBA, 0x8FBB, 0x8FBC, 0x8FBF, 0x8FC0, 0x8FC3, 0x8FC6,
+ /* GB 0xDE80..0xDEFE */
+ 0x8FC9, 0x8FCA, 0x8FCB, 0x8FCC, 0x8FCD, 0x8FCF, 0x8FD2, 0x8FD6,
+ 0x8FD7, 0x8FDA, 0x8FE0, 0x8FE1, 0x8FE3, 0x8FE7, 0x8FEC, 0x8FEF,
+ 0x8FF1, 0x8FF2, 0x8FF4, 0x8FF5, 0x8FF6, 0x8FFA, 0x8FFB, 0x8FFC,
+ 0x8FFE, 0x8FFF, 0x9007, 0x9008, 0x900C, 0x900E, 0x9013, 0x9015,
+ 0x9018, 0x8556, 0x853B, 0x84FF, 0x84FC, 0x8559, 0x8548, 0x8568,
+ 0x8564, 0x855E, 0x857A, 0x77A2, 0x8543, 0x8572, 0x857B, 0x85A4,
+ 0x85A8, 0x8587, 0x858F, 0x8579, 0x85AE, 0x859C, 0x8585, 0x85B9,
+ 0x85B7, 0x85B0, 0x85D3, 0x85C1, 0x85DC, 0x85FF, 0x8627, 0x8605,
+ 0x8629, 0x8616, 0x863C, 0x5EFE, 0x5F08, 0x593C, 0x5941, 0x8037,
+ 0x5955, 0x595A, 0x5958, 0x530F, 0x5C22, 0x5C25, 0x5C2C, 0x5C34,
+ 0x624C, 0x626A, 0x629F, 0x62BB, 0x62CA, 0x62DA, 0x62D7, 0x62EE,
+ 0x6322, 0x62F6, 0x6339, 0x634B, 0x6343, 0x63AD, 0x63F6, 0x6371,
+ 0x637A, 0x638E, 0x63B4, 0x636D, 0x63AC, 0x638A, 0x6369, 0x63AE,
+ 0x63BC, 0x63F2, 0x63F8, 0x63E0, 0x63FF, 0x63C4, 0x63DE, 0x63CE,
+ 0x6452, 0x63C6, 0x63BE, 0x6445, 0x6441, 0x640B, 0x641B, 0x6420,
+ 0x640C, 0x6426, 0x6421, 0x645E, 0x6484, 0x646D, 0x6496,
+ /* GB 0xDF40..0xDF7E */
+ 0x9019, 0x901C, 0x9023, 0x9024, 0x9025, 0x9027, 0x9028, 0x9029,
+ 0x902A, 0x902B, 0x902C, 0x9030, 0x9031, 0x9032, 0x9033, 0x9034,
+ 0x9037, 0x9039, 0x903A, 0x903D, 0x903F, 0x9040, 0x9043, 0x9045,
+ 0x9046, 0x9048, 0x9049, 0x904A, 0x904B, 0x904C, 0x904E, 0x9054,
+ 0x9055, 0x9056, 0x9059, 0x905A, 0x905C, 0x905D, 0x905E, 0x905F,
+ 0x9060, 0x9061, 0x9064, 0x9066, 0x9067, 0x9069, 0x906A, 0x906B,
+ 0x906C, 0x906F, 0x9070, 0x9071, 0x9072, 0x9073, 0x9076, 0x9077,
+ 0x9078, 0x9079, 0x907A, 0x907B, 0x907C, 0x907E, 0x9081,
+ /* GB 0xDF80..0xDFFE */
+ 0x9084, 0x9085, 0x9086, 0x9087, 0x9089, 0x908A, 0x908C, 0x908D,
+ 0x908E, 0x908F, 0x9090, 0x9092, 0x9094, 0x9096, 0x9098, 0x909A,
+ 0x909C, 0x909E, 0x909F, 0x90A0, 0x90A4, 0x90A5, 0x90A7, 0x90A8,
+ 0x90A9, 0x90AB, 0x90AD, 0x90B2, 0x90B7, 0x90BC, 0x90BD, 0x90BF,
+ 0x90C0, 0x647A, 0x64B7, 0x64B8, 0x6499, 0x64BA, 0x64C0, 0x64D0,
+ 0x64D7, 0x64E4, 0x64E2, 0x6509, 0x6525, 0x652E, 0x5F0B, 0x5FD2,
+ 0x7519, 0x5F11, 0x535F, 0x53F1, 0x53FD, 0x53E9, 0x53E8, 0x53FB,
+ 0x5412, 0x5416, 0x5406, 0x544B, 0x5452, 0x5453, 0x5454, 0x5456,
+ 0x5443, 0x5421, 0x5457, 0x5459, 0x5423, 0x5432, 0x5482, 0x5494,
+ 0x5477, 0x5471, 0x5464, 0x549A, 0x549B, 0x5484, 0x5476, 0x5466,
+ 0x549D, 0x54D0, 0x54AD, 0x54C2, 0x54B4, 0x54D2, 0x54A7, 0x54A6,
+ 0x54D3, 0x54D4, 0x5472, 0x54A3, 0x54D5, 0x54BB, 0x54BF, 0x54CC,
+ 0x54D9, 0x54DA, 0x54DC, 0x54A9, 0x54AA, 0x54A4, 0x54DD, 0x54CF,
+ 0x54DE, 0x551B, 0x54E7, 0x5520, 0x54FD, 0x5514, 0x54F3, 0x5522,
+ 0x5523, 0x550F, 0x5511, 0x5527, 0x552A, 0x5567, 0x558F, 0x55B5,
+ 0x5549, 0x556D, 0x5541, 0x5555, 0x553F, 0x5550, 0x553C,
+ /* GB 0xE040..0xE07E */
+ 0x90C2, 0x90C3, 0x90C6, 0x90C8, 0x90C9, 0x90CB, 0x90CC, 0x90CD,
+ 0x90D2, 0x90D4, 0x90D5, 0x90D6, 0x90D8, 0x90D9, 0x90DA, 0x90DE,
+ 0x90DF, 0x90E0, 0x90E3, 0x90E4, 0x90E5, 0x90E9, 0x90EA, 0x90EC,
+ 0x90EE, 0x90F0, 0x90F1, 0x90F2, 0x90F3, 0x90F5, 0x90F6, 0x90F7,
+ 0x90F9, 0x90FA, 0x90FB, 0x90FC, 0x90FF, 0x9100, 0x9101, 0x9103,
+ 0x9105, 0x9106, 0x9107, 0x9108, 0x9109, 0x910A, 0x910B, 0x910C,
+ 0x910D, 0x910E, 0x910F, 0x9110, 0x9111, 0x9112, 0x9113, 0x9114,
+ 0x9115, 0x9116, 0x9117, 0x9118, 0x911A, 0x911B, 0x911C,
+ /* GB 0xE080..0xE0FE */
+ 0x911D, 0x911F, 0x9120, 0x9121, 0x9124, 0x9125, 0x9126, 0x9127,
+ 0x9128, 0x9129, 0x912A, 0x912B, 0x912C, 0x912D, 0x912E, 0x9130,
+ 0x9132, 0x9133, 0x9134, 0x9135, 0x9136, 0x9137, 0x9138, 0x913A,
+ 0x913B, 0x913C, 0x913D, 0x913E, 0x913F, 0x9140, 0x9141, 0x9142,
+ 0x9144, 0x5537, 0x5556, 0x5575, 0x5576, 0x5577, 0x5533, 0x5530,
+ 0x555C, 0x558B, 0x55D2, 0x5583, 0x55B1, 0x55B9, 0x5588, 0x5581,
+ 0x559F, 0x557E, 0x55D6, 0x5591, 0x557B, 0x55DF, 0x55BD, 0x55BE,
+ 0x5594, 0x5599, 0x55EA, 0x55F7, 0x55C9, 0x561F, 0x55D1, 0x55EB,
+ 0x55EC, 0x55D4, 0x55E6, 0x55DD, 0x55C4, 0x55EF, 0x55E5, 0x55F2,
+ 0x55F3, 0x55CC, 0x55CD, 0x55E8, 0x55F5, 0x55E4, 0x8F94, 0x561E,
+ 0x5608, 0x560C, 0x5601, 0x5624, 0x5623, 0x55FE, 0x5600, 0x5627,
+ 0x562D, 0x5658, 0x5639, 0x5657, 0x562C, 0x564D, 0x5662, 0x5659,
+ 0x565C, 0x564C, 0x5654, 0x5686, 0x5664, 0x5671, 0x566B, 0x567B,
+ 0x567C, 0x5685, 0x5693, 0x56AF, 0x56D4, 0x56D7, 0x56DD, 0x56E1,
+ 0x56F5, 0x56EB, 0x56F9, 0x56FF, 0x5704, 0x570A, 0x5709, 0x571C,
+ 0x5E0F, 0x5E19, 0x5E14, 0x5E11, 0x5E31, 0x5E3B, 0x5E3C,
+ /* GB 0xE140..0xE17E */
+ 0x9145, 0x9147, 0x9148, 0x9151, 0x9153, 0x9154, 0x9155, 0x9156,
+ 0x9158, 0x9159, 0x915B, 0x915C, 0x915F, 0x9160, 0x9166, 0x9167,
+ 0x9168, 0x916B, 0x916D, 0x9173, 0x917A, 0x917B, 0x917C, 0x9180,
+ 0x9181, 0x9182, 0x9183, 0x9184, 0x9186, 0x9188, 0x918A, 0x918E,
+ 0x918F, 0x9193, 0x9194, 0x9195, 0x9196, 0x9197, 0x9198, 0x9199,
+ 0x919C, 0x919D, 0x919E, 0x919F, 0x91A0, 0x91A1, 0x91A4, 0x91A5,
+ 0x91A6, 0x91A7, 0x91A8, 0x91A9, 0x91AB, 0x91AC, 0x91B0, 0x91B1,
+ 0x91B2, 0x91B3, 0x91B6, 0x91B7, 0x91B8, 0x91B9, 0x91BB,
+ /* GB 0xE180..0xE1FE */
+ 0x91BC, 0x91BD, 0x91BE, 0x91BF, 0x91C0, 0x91C1, 0x91C2, 0x91C3,
+ 0x91C4, 0x91C5, 0x91C6, 0x91C8, 0x91CB, 0x91D0, 0x91D2, 0x91D3,
+ 0x91D4, 0x91D5, 0x91D6, 0x91D7, 0x91D8, 0x91D9, 0x91DA, 0x91DB,
+ 0x91DD, 0x91DE, 0x91DF, 0x91E0, 0x91E1, 0x91E2, 0x91E3, 0x91E4,
+ 0x91E5, 0x5E37, 0x5E44, 0x5E54, 0x5E5B, 0x5E5E, 0x5E61, 0x5C8C,
+ 0x5C7A, 0x5C8D, 0x5C90, 0x5C96, 0x5C88, 0x5C98, 0x5C99, 0x5C91,
+ 0x5C9A, 0x5C9C, 0x5CB5, 0x5CA2, 0x5CBD, 0x5CAC, 0x5CAB, 0x5CB1,
+ 0x5CA3, 0x5CC1, 0x5CB7, 0x5CC4, 0x5CD2, 0x5CE4, 0x5CCB, 0x5CE5,
+ 0x5D02, 0x5D03, 0x5D27, 0x5D26, 0x5D2E, 0x5D24, 0x5D1E, 0x5D06,
+ 0x5D1B, 0x5D58, 0x5D3E, 0x5D34, 0x5D3D, 0x5D6C, 0x5D5B, 0x5D6F,
+ 0x5D5D, 0x5D6B, 0x5D4B, 0x5D4A, 0x5D69, 0x5D74, 0x5D82, 0x5D99,
+ 0x5D9D, 0x8C73, 0x5DB7, 0x5DC5, 0x5F73, 0x5F77, 0x5F82, 0x5F87,
+ 0x5F89, 0x5F8C, 0x5F95, 0x5F99, 0x5F9C, 0x5FA8, 0x5FAD, 0x5FB5,
+ 0x5FBC, 0x8862, 0x5F61, 0x72AD, 0x72B0, 0x72B4, 0x72B7, 0x72B8,
+ 0x72C3, 0x72C1, 0x72CE, 0x72CD, 0x72D2, 0x72E8, 0x72EF, 0x72E9,
+ 0x72F2, 0x72F4, 0x72F7, 0x7301, 0x72F3, 0x7303, 0x72FA,
+ /* GB 0xE240..0xE27E */
+ 0x91E6, 0x91E7, 0x91E8, 0x91E9, 0x91EA, 0x91EB, 0x91EC, 0x91ED,
+ 0x91EE, 0x91EF, 0x91F0, 0x91F1, 0x91F2, 0x91F3, 0x91F4, 0x91F5,
+ 0x91F6, 0x91F7, 0x91F8, 0x91F9, 0x91FA, 0x91FB, 0x91FC, 0x91FD,
+ 0x91FE, 0x91FF, 0x9200, 0x9201, 0x9202, 0x9203, 0x9204, 0x9205,
+ 0x9206, 0x9207, 0x9208, 0x9209, 0x920A, 0x920B, 0x920C, 0x920D,
+ 0x920E, 0x920F, 0x9210, 0x9211, 0x9212, 0x9213, 0x9214, 0x9215,
+ 0x9216, 0x9217, 0x9218, 0x9219, 0x921A, 0x921B, 0x921C, 0x921D,
+ 0x921E, 0x921F, 0x9220, 0x9221, 0x9222, 0x9223, 0x9224,
+ /* GB 0xE280..0xE2FE */
+ 0x9225, 0x9226, 0x9227, 0x9228, 0x9229, 0x922A, 0x922B, 0x922C,
+ 0x922D, 0x922E, 0x922F, 0x9230, 0x9231, 0x9232, 0x9233, 0x9234,
+ 0x9235, 0x9236, 0x9237, 0x9238, 0x9239, 0x923A, 0x923B, 0x923C,
+ 0x923D, 0x923E, 0x923F, 0x9240, 0x9241, 0x9242, 0x9243, 0x9244,
+ 0x9245, 0x72FB, 0x7317, 0x7313, 0x7321, 0x730A, 0x731E, 0x731D,
+ 0x7315, 0x7322, 0x7339, 0x7325, 0x732C, 0x7338, 0x7331, 0x7350,
+ 0x734D, 0x7357, 0x7360, 0x736C, 0x736F, 0x737E, 0x821B, 0x5925,
+ 0x98E7, 0x5924, 0x5902, 0x9963, 0x9967, 0x9968, 0x9969, 0x996A,
+ 0x996B, 0x996C, 0x9974, 0x9977, 0x997D, 0x9980, 0x9984, 0x9987,
+ 0x998A, 0x998D, 0x9990, 0x9991, 0x9993, 0x9994, 0x9995, 0x5E80,
+ 0x5E91, 0x5E8B, 0x5E96, 0x5EA5, 0x5EA0, 0x5EB9, 0x5EB5, 0x5EBE,
+ 0x5EB3, 0x8D53, 0x5ED2, 0x5ED1, 0x5EDB, 0x5EE8, 0x5EEA, 0x81BA,
+ 0x5FC4, 0x5FC9, 0x5FD6, 0x5FCF, 0x6003, 0x5FEE, 0x6004, 0x5FE1,
+ 0x5FE4, 0x5FFE, 0x6005, 0x6006, 0x5FEA, 0x5FED, 0x5FF8, 0x6019,
+ 0x6035, 0x6026, 0x601B, 0x600F, 0x600D, 0x6029, 0x602B, 0x600A,
+ 0x603F, 0x6021, 0x6078, 0x6079, 0x607B, 0x607A, 0x6042,
+ /* GB 0xE340..0xE37E */
+ 0x9246, 0x9247, 0x9248, 0x9249, 0x924A, 0x924B, 0x924C, 0x924D,
+ 0x924E, 0x924F, 0x9250, 0x9251, 0x9252, 0x9253, 0x9254, 0x9255,
+ 0x9256, 0x9257, 0x9258, 0x9259, 0x925A, 0x925B, 0x925C, 0x925D,
+ 0x925E, 0x925F, 0x9260, 0x9261, 0x9262, 0x9263, 0x9264, 0x9265,
+ 0x9266, 0x9267, 0x9268, 0x9269, 0x926A, 0x926B, 0x926C, 0x926D,
+ 0x926E, 0x926F, 0x9270, 0x9271, 0x9272, 0x9273, 0x9275, 0x9276,
+ 0x9277, 0x9278, 0x9279, 0x927A, 0x927B, 0x927C, 0x927D, 0x927E,
+ 0x927F, 0x9280, 0x9281, 0x9282, 0x9283, 0x9284, 0x9285,
+ /* GB 0xE380..0xE3FE */
+ 0x9286, 0x9287, 0x9288, 0x9289, 0x928A, 0x928B, 0x928C, 0x928D,
+ 0x928F, 0x9290, 0x9291, 0x9292, 0x9293, 0x9294, 0x9295, 0x9296,
+ 0x9297, 0x9298, 0x9299, 0x929A, 0x929B, 0x929C, 0x929D, 0x929E,
+ 0x929F, 0x92A0, 0x92A1, 0x92A2, 0x92A3, 0x92A4, 0x92A5, 0x92A6,
+ 0x92A7, 0x606A, 0x607D, 0x6096, 0x609A, 0x60AD, 0x609D, 0x6083,
+ 0x6092, 0x608C, 0x609B, 0x60EC, 0x60BB, 0x60B1, 0x60DD, 0x60D8,
+ 0x60C6, 0x60DA, 0x60B4, 0x6120, 0x6126, 0x6115, 0x6123, 0x60F4,
+ 0x6100, 0x610E, 0x612B, 0x614A, 0x6175, 0x61AC, 0x6194, 0x61A7,
+ 0x61B7, 0x61D4, 0x61F5, 0x5FDD, 0x96B3, 0x95E9, 0x95EB, 0x95F1,
+ 0x95F3, 0x95F5, 0x95F6, 0x95FC, 0x95FE, 0x9603, 0x9604, 0x9606,
+ 0x9608, 0x960A, 0x960B, 0x960C, 0x960D, 0x960F, 0x9612, 0x9615,
+ 0x9616, 0x9617, 0x9619, 0x961A, 0x4E2C, 0x723F, 0x6215, 0x6C35,
+ 0x6C54, 0x6C5C, 0x6C4A, 0x6CA3, 0x6C85, 0x6C90, 0x6C94, 0x6C8C,
+ 0x6C68, 0x6C69, 0x6C74, 0x6C76, 0x6C86, 0x6CA9, 0x6CD0, 0x6CD4,
+ 0x6CAD, 0x6CF7, 0x6CF8, 0x6CF1, 0x6CD7, 0x6CB2, 0x6CE0, 0x6CD6,
+ 0x6CFA, 0x6CEB, 0x6CEE, 0x6CB1, 0x6CD3, 0x6CEF, 0x6CFE,
+ /* GB 0xE440..0xE47E */
+ 0x92A8, 0x92A9, 0x92AA, 0x92AB, 0x92AC, 0x92AD, 0x92AF, 0x92B0,
+ 0x92B1, 0x92B2, 0x92B3, 0x92B4, 0x92B5, 0x92B6, 0x92B7, 0x92B8,
+ 0x92B9, 0x92BA, 0x92BB, 0x92BC, 0x92BD, 0x92BE, 0x92BF, 0x92C0,
+ 0x92C1, 0x92C2, 0x92C3, 0x92C4, 0x92C5, 0x92C6, 0x92C7, 0x92C9,
+ 0x92CA, 0x92CB, 0x92CC, 0x92CD, 0x92CE, 0x92CF, 0x92D0, 0x92D1,
+ 0x92D2, 0x92D3, 0x92D4, 0x92D5, 0x92D6, 0x92D7, 0x92D8, 0x92D9,
+ 0x92DA, 0x92DB, 0x92DC, 0x92DD, 0x92DE, 0x92DF, 0x92E0, 0x92E1,
+ 0x92E2, 0x92E3, 0x92E4, 0x92E5, 0x92E6, 0x92E7, 0x92E8,
+ /* GB 0xE480..0xE4FE */
+ 0x92E9, 0x92EA, 0x92EB, 0x92EC, 0x92ED, 0x92EE, 0x92EF, 0x92F0,
+ 0x92F1, 0x92F2, 0x92F3, 0x92F4, 0x92F5, 0x92F6, 0x92F7, 0x92F8,
+ 0x92F9, 0x92FA, 0x92FB, 0x92FC, 0x92FD, 0x92FE, 0x92FF, 0x9300,
+ 0x9301, 0x9302, 0x9303, 0x9304, 0x9305, 0x9306, 0x9307, 0x9308,
+ 0x9309, 0x6D39, 0x6D27, 0x6D0C, 0x6D43, 0x6D48, 0x6D07, 0x6D04,
+ 0x6D19, 0x6D0E, 0x6D2B, 0x6D4D, 0x6D2E, 0x6D35, 0x6D1A, 0x6D4F,
+ 0x6D52, 0x6D54, 0x6D33, 0x6D91, 0x6D6F, 0x6D9E, 0x6DA0, 0x6D5E,
+ 0x6D93, 0x6D94, 0x6D5C, 0x6D60, 0x6D7C, 0x6D63, 0x6E1A, 0x6DC7,
+ 0x6DC5, 0x6DDE, 0x6E0E, 0x6DBF, 0x6DE0, 0x6E11, 0x6DE6, 0x6DDD,
+ 0x6DD9, 0x6E16, 0x6DAB, 0x6E0C, 0x6DAE, 0x6E2B, 0x6E6E, 0x6E4E,
+ 0x6E6B, 0x6EB2, 0x6E5F, 0x6E86, 0x6E53, 0x6E54, 0x6E32, 0x6E25,
+ 0x6E44, 0x6EDF, 0x6EB1, 0x6E98, 0x6EE0, 0x6F2D, 0x6EE2, 0x6EA5,
+ 0x6EA7, 0x6EBD, 0x6EBB, 0x6EB7, 0x6ED7, 0x6EB4, 0x6ECF, 0x6E8F,
+ 0x6EC2, 0x6E9F, 0x6F62, 0x6F46, 0x6F47, 0x6F24, 0x6F15, 0x6EF9,
+ 0x6F2F, 0x6F36, 0x6F4B, 0x6F74, 0x6F2A, 0x6F09, 0x6F29, 0x6F89,
+ 0x6F8D, 0x6F8C, 0x6F78, 0x6F72, 0x6F7C, 0x6F7A, 0x6FD1,
+ /* GB 0xE540..0xE57E */
+ 0x930A, 0x930B, 0x930C, 0x930D, 0x930E, 0x930F, 0x9310, 0x9311,
+ 0x9312, 0x9313, 0x9314, 0x9315, 0x9316, 0x9317, 0x9318, 0x9319,
+ 0x931A, 0x931B, 0x931C, 0x931D, 0x931E, 0x931F, 0x9320, 0x9321,
+ 0x9322, 0x9323, 0x9324, 0x9325, 0x9326, 0x9327, 0x9328, 0x9329,
+ 0x932A, 0x932B, 0x932C, 0x932D, 0x932E, 0x932F, 0x9330, 0x9331,
+ 0x9332, 0x9333, 0x9334, 0x9335, 0x9336, 0x9337, 0x9338, 0x9339,
+ 0x933A, 0x933B, 0x933C, 0x933D, 0x933F, 0x9340, 0x9341, 0x9342,
+ 0x9343, 0x9344, 0x9345, 0x9346, 0x9347, 0x9348, 0x9349,
+ /* GB 0xE580..0xE5FE */
+ 0x934A, 0x934B, 0x934C, 0x934D, 0x934E, 0x934F, 0x9350, 0x9351,
+ 0x9352, 0x9353, 0x9354, 0x9355, 0x9356, 0x9357, 0x9358, 0x9359,
+ 0x935A, 0x935B, 0x935C, 0x935D, 0x935E, 0x935F, 0x9360, 0x9361,
+ 0x9362, 0x9363, 0x9364, 0x9365, 0x9366, 0x9367, 0x9368, 0x9369,
+ 0x936B, 0x6FC9, 0x6FA7, 0x6FB9, 0x6FB6, 0x6FC2, 0x6FE1, 0x6FEE,
+ 0x6FDE, 0x6FE0, 0x6FEF, 0x701A, 0x7023, 0x701B, 0x7039, 0x7035,
+ 0x704F, 0x705E, 0x5B80, 0x5B84, 0x5B95, 0x5B93, 0x5BA5, 0x5BB8,
+ 0x752F, 0x9A9E, 0x6434, 0x5BE4, 0x5BEE, 0x8930, 0x5BF0, 0x8E47,
+ 0x8B07, 0x8FB6, 0x8FD3, 0x8FD5, 0x8FE5, 0x8FEE, 0x8FE4, 0x8FE9,
+ 0x8FE6, 0x8FF3, 0x8FE8, 0x9005, 0x9004, 0x900B, 0x9026, 0x9011,
+ 0x900D, 0x9016, 0x9021, 0x9035, 0x9036, 0x902D, 0x902F, 0x9044,
+ 0x9051, 0x9052, 0x9050, 0x9068, 0x9058, 0x9062, 0x905B, 0x66B9,
+ 0x9074, 0x907D, 0x9082, 0x9088, 0x9083, 0x908B, 0x5F50, 0x5F57,
+ 0x5F56, 0x5F58, 0x5C3B, 0x54AB, 0x5C50, 0x5C59, 0x5B71, 0x5C63,
+ 0x5C66, 0x7FBC, 0x5F2A, 0x5F29, 0x5F2D, 0x8274, 0x5F3C, 0x9B3B,
+ 0x5C6E, 0x5981, 0x5983, 0x598D, 0x59A9, 0x59AA, 0x59A3,
+ /* GB 0xE640..0xE67E */
+ 0x936C, 0x936D, 0x936E, 0x936F, 0x9370, 0x9371, 0x9372, 0x9373,
+ 0x9374, 0x9375, 0x9376, 0x9377, 0x9378, 0x9379, 0x937A, 0x937B,
+ 0x937C, 0x937D, 0x937E, 0x937F, 0x9380, 0x9381, 0x9382, 0x9383,
+ 0x9384, 0x9385, 0x9386, 0x9387, 0x9388, 0x9389, 0x938A, 0x938B,
+ 0x938C, 0x938D, 0x938E, 0x9390, 0x9391, 0x9392, 0x9393, 0x9394,
+ 0x9395, 0x9396, 0x9397, 0x9398, 0x9399, 0x939A, 0x939B, 0x939C,
+ 0x939D, 0x939E, 0x939F, 0x93A0, 0x93A1, 0x93A2, 0x93A3, 0x93A4,
+ 0x93A5, 0x93A6, 0x93A7, 0x93A8, 0x93A9, 0x93AA, 0x93AB,
+ /* GB 0xE680..0xE6FE */
+ 0x93AC, 0x93AD, 0x93AE, 0x93AF, 0x93B0, 0x93B1, 0x93B2, 0x93B3,
+ 0x93B4, 0x93B5, 0x93B6, 0x93B7, 0x93B8, 0x93B9, 0x93BA, 0x93BB,
+ 0x93BC, 0x93BD, 0x93BE, 0x93BF, 0x93C0, 0x93C1, 0x93C2, 0x93C3,
+ 0x93C4, 0x93C5, 0x93C6, 0x93C7, 0x93C8, 0x93C9, 0x93CB, 0x93CC,
+ 0x93CD, 0x5997, 0x59CA, 0x59AB, 0x599E, 0x59A4, 0x59D2, 0x59B2,
+ 0x59AF, 0x59D7, 0x59BE, 0x5A05, 0x5A06, 0x59DD, 0x5A08, 0x59E3,
+ 0x59D8, 0x59F9, 0x5A0C, 0x5A09, 0x5A32, 0x5A34, 0x5A11, 0x5A23,
+ 0x5A13, 0x5A40, 0x5A67, 0x5A4A, 0x5A55, 0x5A3C, 0x5A62, 0x5A75,
+ 0x80EC, 0x5AAA, 0x5A9B, 0x5A77, 0x5A7A, 0x5ABE, 0x5AEB, 0x5AB2,
+ 0x5AD2, 0x5AD4, 0x5AB8, 0x5AE0, 0x5AE3, 0x5AF1, 0x5AD6, 0x5AE6,
+ 0x5AD8, 0x5ADC, 0x5B09, 0x5B17, 0x5B16, 0x5B32, 0x5B37, 0x5B40,
+ 0x5C15, 0x5C1C, 0x5B5A, 0x5B65, 0x5B73, 0x5B51, 0x5B53, 0x5B62,
+ 0x9A75, 0x9A77, 0x9A78, 0x9A7A, 0x9A7F, 0x9A7D, 0x9A80, 0x9A81,
+ 0x9A85, 0x9A88, 0x9A8A, 0x9A90, 0x9A92, 0x9A93, 0x9A96, 0x9A98,
+ 0x9A9B, 0x9A9C, 0x9A9D, 0x9A9F, 0x9AA0, 0x9AA2, 0x9AA3, 0x9AA5,
+ 0x9AA7, 0x7E9F, 0x7EA1, 0x7EA3, 0x7EA5, 0x7EA8, 0x7EA9,
+ /* GB 0xE740..0xE77E */
+ 0x93CE, 0x93CF, 0x93D0, 0x93D1, 0x93D2, 0x93D3, 0x93D4, 0x93D5,
+ 0x93D7, 0x93D8, 0x93D9, 0x93DA, 0x93DB, 0x93DC, 0x93DD, 0x93DE,
+ 0x93DF, 0x93E0, 0x93E1, 0x93E2, 0x93E3, 0x93E4, 0x93E5, 0x93E6,
+ 0x93E7, 0x93E8, 0x93E9, 0x93EA, 0x93EB, 0x93EC, 0x93ED, 0x93EE,
+ 0x93EF, 0x93F0, 0x93F1, 0x93F2, 0x93F3, 0x93F4, 0x93F5, 0x93F6,
+ 0x93F7, 0x93F8, 0x93F9, 0x93FA, 0x93FB, 0x93FC, 0x93FD, 0x93FE,
+ 0x93FF, 0x9400, 0x9401, 0x9402, 0x9403, 0x9404, 0x9405, 0x9406,
+ 0x9407, 0x9408, 0x9409, 0x940A, 0x940B, 0x940C, 0x940D,
+ /* GB 0xE780..0xE7FE */
+ 0x940E, 0x940F, 0x9410, 0x9411, 0x9412, 0x9413, 0x9414, 0x9415,
+ 0x9416, 0x9417, 0x9418, 0x9419, 0x941A, 0x941B, 0x941C, 0x941D,
+ 0x941E, 0x941F, 0x9420, 0x9421, 0x9422, 0x9423, 0x9424, 0x9425,
+ 0x9426, 0x9427, 0x9428, 0x9429, 0x942A, 0x942B, 0x942C, 0x942D,
+ 0x942E, 0x7EAD, 0x7EB0, 0x7EBE, 0x7EC0, 0x7EC1, 0x7EC2, 0x7EC9,
+ 0x7ECB, 0x7ECC, 0x7ED0, 0x7ED4, 0x7ED7, 0x7EDB, 0x7EE0, 0x7EE1,
+ 0x7EE8, 0x7EEB, 0x7EEE, 0x7EEF, 0x7EF1, 0x7EF2, 0x7F0D, 0x7EF6,
+ 0x7EFA, 0x7EFB, 0x7EFE, 0x7F01, 0x7F02, 0x7F03, 0x7F07, 0x7F08,
+ 0x7F0B, 0x7F0C, 0x7F0F, 0x7F11, 0x7F12, 0x7F17, 0x7F19, 0x7F1C,
+ 0x7F1B, 0x7F1F, 0x7F21, 0x7F22, 0x7F23, 0x7F24, 0x7F25, 0x7F26,
+ 0x7F27, 0x7F2A, 0x7F2B, 0x7F2C, 0x7F2D, 0x7F2F, 0x7F30, 0x7F31,
+ 0x7F32, 0x7F33, 0x7F35, 0x5E7A, 0x757F, 0x5DDB, 0x753E, 0x9095,
+ 0x738E, 0x7391, 0x73AE, 0x73A2, 0x739F, 0x73CF, 0x73C2, 0x73D1,
+ 0x73B7, 0x73B3, 0x73C0, 0x73C9, 0x73C8, 0x73E5, 0x73D9, 0x987C,
+ 0x740A, 0x73E9, 0x73E7, 0x73DE, 0x73BA, 0x73F2, 0x740F, 0x742A,
+ 0x745B, 0x7426, 0x7425, 0x7428, 0x7430, 0x742E, 0x742C,
+ /* GB 0xE840..0xE87E */
+ 0x942F, 0x9430, 0x9431, 0x9432, 0x9433, 0x9434, 0x9435, 0x9436,
+ 0x9437, 0x9438, 0x9439, 0x943A, 0x943B, 0x943C, 0x943D, 0x943F,
+ 0x9440, 0x9441, 0x9442, 0x9443, 0x9444, 0x9445, 0x9446, 0x9447,
+ 0x9448, 0x9449, 0x944A, 0x944B, 0x944C, 0x944D, 0x944E, 0x944F,
+ 0x9450, 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457,
+ 0x9458, 0x9459, 0x945A, 0x945B, 0x945C, 0x945D, 0x945E, 0x945F,
+ 0x9460, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467,
+ 0x9468, 0x9469, 0x946A, 0x946C, 0x946D, 0x946E, 0x946F,
+ /* GB 0xE880..0xE8FE */
+ 0x9470, 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, 0x9476, 0x9477,
+ 0x9478, 0x9479, 0x947A, 0x947B, 0x947C, 0x947D, 0x947E, 0x947F,
+ 0x9480, 0x9481, 0x9482, 0x9483, 0x9484, 0x9491, 0x9496, 0x9498,
+ 0x94C7, 0x94CF, 0x94D3, 0x94D4, 0x94DA, 0x94E6, 0x94FB, 0x951C,
+ 0x9520, 0x741B, 0x741A, 0x7441, 0x745C, 0x7457, 0x7455, 0x7459,
+ 0x7477, 0x746D, 0x747E, 0x749C, 0x748E, 0x7480, 0x7481, 0x7487,
+ 0x748B, 0x749E, 0x74A8, 0x74A9, 0x7490, 0x74A7, 0x74D2, 0x74BA,
+ 0x97EA, 0x97EB, 0x97EC, 0x674C, 0x6753, 0x675E, 0x6748, 0x6769,
+ 0x67A5, 0x6787, 0x676A, 0x6773, 0x6798, 0x67A7, 0x6775, 0x67A8,
+ 0x679E, 0x67AD, 0x678B, 0x6777, 0x677C, 0x67F0, 0x6809, 0x67D8,
+ 0x680A, 0x67E9, 0x67B0, 0x680C, 0x67D9, 0x67B5, 0x67DA, 0x67B3,
+ 0x67DD, 0x6800, 0x67C3, 0x67B8, 0x67E2, 0x680E, 0x67C1, 0x67FD,
+ 0x6832, 0x6833, 0x6860, 0x6861, 0x684E, 0x6862, 0x6844, 0x6864,
+ 0x6883, 0x681D, 0x6855, 0x6866, 0x6841, 0x6867, 0x6840, 0x683E,
+ 0x684A, 0x6849, 0x6829, 0x68B5, 0x688F, 0x6874, 0x6877, 0x6893,
+ 0x686B, 0x68C2, 0x696E, 0x68FC, 0x691F, 0x6920, 0x68F9,
+ /* GB 0xE940..0xE97E */
+ 0x9527, 0x9533, 0x953D, 0x9543, 0x9548, 0x954B, 0x9555, 0x955A,
+ 0x9560, 0x956E, 0x9574, 0x9575, 0x9577, 0x9578, 0x9579, 0x957A,
+ 0x957B, 0x957C, 0x957D, 0x957E, 0x9580, 0x9581, 0x9582, 0x9583,
+ 0x9584, 0x9585, 0x9586, 0x9587, 0x9588, 0x9589, 0x958A, 0x958B,
+ 0x958C, 0x958D, 0x958E, 0x958F, 0x9590, 0x9591, 0x9592, 0x9593,
+ 0x9594, 0x9595, 0x9596, 0x9597, 0x9598, 0x9599, 0x959A, 0x959B,
+ 0x959C, 0x959D, 0x959E, 0x959F, 0x95A0, 0x95A1, 0x95A2, 0x95A3,
+ 0x95A4, 0x95A5, 0x95A6, 0x95A7, 0x95A8, 0x95A9, 0x95AA,
+ /* GB 0xE980..0xE9FE */
+ 0x95AB, 0x95AC, 0x95AD, 0x95AE, 0x95AF, 0x95B0, 0x95B1, 0x95B2,
+ 0x95B3, 0x95B4, 0x95B5, 0x95B6, 0x95B7, 0x95B8, 0x95B9, 0x95BA,
+ 0x95BB, 0x95BC, 0x95BD, 0x95BE, 0x95BF, 0x95C0, 0x95C1, 0x95C2,
+ 0x95C3, 0x95C4, 0x95C5, 0x95C6, 0x95C7, 0x95C8, 0x95C9, 0x95CA,
+ 0x95CB, 0x6924, 0x68F0, 0x690B, 0x6901, 0x6957, 0x68E3, 0x6910,
+ 0x6971, 0x6939, 0x6960, 0x6942, 0x695D, 0x6984, 0x696B, 0x6980,
+ 0x6998, 0x6978, 0x6934, 0x69CC, 0x6987, 0x6988, 0x69CE, 0x6989,
+ 0x6966, 0x6963, 0x6979, 0x699B, 0x69A7, 0x69BB, 0x69AB, 0x69AD,
+ 0x69D4, 0x69B1, 0x69C1, 0x69CA, 0x69DF, 0x6995, 0x69E0, 0x698D,
+ 0x69FF, 0x6A2F, 0x69ED, 0x6A17, 0x6A18, 0x6A65, 0x69F2, 0x6A44,
+ 0x6A3E, 0x6AA0, 0x6A50, 0x6A5B, 0x6A35, 0x6A8E, 0x6A79, 0x6A3D,
+ 0x6A28, 0x6A58, 0x6A7C, 0x6A91, 0x6A90, 0x6AA9, 0x6A97, 0x6AAB,
+ 0x7337, 0x7352, 0x6B81, 0x6B82, 0x6B87, 0x6B84, 0x6B92, 0x6B93,
+ 0x6B8D, 0x6B9A, 0x6B9B, 0x6BA1, 0x6BAA, 0x8F6B, 0x8F6D, 0x8F71,
+ 0x8F72, 0x8F73, 0x8F75, 0x8F76, 0x8F78, 0x8F77, 0x8F79, 0x8F7A,
+ 0x8F7C, 0x8F7E, 0x8F81, 0x8F82, 0x8F84, 0x8F87, 0x8F8B,
+ /* GB 0xEA40..0xEA7E */
+ 0x95CC, 0x95CD, 0x95CE, 0x95CF, 0x95D0, 0x95D1, 0x95D2, 0x95D3,
+ 0x95D4, 0x95D5, 0x95D6, 0x95D7, 0x95D8, 0x95D9, 0x95DA, 0x95DB,
+ 0x95DC, 0x95DD, 0x95DE, 0x95DF, 0x95E0, 0x95E1, 0x95E2, 0x95E3,
+ 0x95E4, 0x95E5, 0x95E6, 0x95E7, 0x95EC, 0x95FF, 0x9607, 0x9613,
+ 0x9618, 0x961B, 0x961E, 0x9620, 0x9623, 0x9624, 0x9625, 0x9626,
+ 0x9627, 0x9628, 0x9629, 0x962B, 0x962C, 0x962D, 0x962F, 0x9630,
+ 0x9637, 0x9638, 0x9639, 0x963A, 0x963E, 0x9641, 0x9643, 0x964A,
+ 0x964E, 0x964F, 0x9651, 0x9652, 0x9653, 0x9656, 0x9657,
+ /* GB 0xEA80..0xEAFE */
+ 0x9658, 0x9659, 0x965A, 0x965C, 0x965D, 0x965E, 0x9660, 0x9663,
+ 0x9665, 0x9666, 0x966B, 0x966D, 0x966E, 0x966F, 0x9670, 0x9671,
+ 0x9673, 0x9678, 0x9679, 0x967A, 0x967B, 0x967C, 0x967D, 0x967E,
+ 0x967F, 0x9680, 0x9681, 0x9682, 0x9683, 0x9684, 0x9687, 0x9689,
+ 0x968A, 0x8F8D, 0x8F8E, 0x8F8F, 0x8F98, 0x8F9A, 0x8ECE, 0x620B,
+ 0x6217, 0x621B, 0x621F, 0x6222, 0x6221, 0x6225, 0x6224, 0x622C,
+ 0x81E7, 0x74EF, 0x74F4, 0x74FF, 0x750F, 0x7511, 0x7513, 0x6534,
+ 0x65EE, 0x65EF, 0x65F0, 0x660A, 0x6619, 0x6772, 0x6603, 0x6615,
+ 0x6600, 0x7085, 0x66F7, 0x661D, 0x6634, 0x6631, 0x6636, 0x6635,
+ 0x8006, 0x665F, 0x6654, 0x6641, 0x664F, 0x6656, 0x6661, 0x6657,
+ 0x6677, 0x6684, 0x668C, 0x66A7, 0x669D, 0x66BE, 0x66DB, 0x66DC,
+ 0x66E6, 0x66E9, 0x8D32, 0x8D33, 0x8D36, 0x8D3B, 0x8D3D, 0x8D40,
+ 0x8D45, 0x8D46, 0x8D48, 0x8D49, 0x8D47, 0x8D4D, 0x8D55, 0x8D59,
+ 0x89C7, 0x89CA, 0x89CB, 0x89CC, 0x89CE, 0x89CF, 0x89D0, 0x89D1,
+ 0x726E, 0x729F, 0x725D, 0x7266, 0x726F, 0x727E, 0x727F, 0x7284,
+ 0x728B, 0x728D, 0x728F, 0x7292, 0x6308, 0x6332, 0x63B0,
+ /* GB 0xEB40..0xEB7E */
+ 0x968C, 0x968E, 0x9691, 0x9692, 0x9693, 0x9695, 0x9696, 0x969A,
+ 0x969B, 0x969D, 0x969E, 0x969F, 0x96A0, 0x96A1, 0x96A2, 0x96A3,
+ 0x96A4, 0x96A5, 0x96A6, 0x96A8, 0x96A9, 0x96AA, 0x96AB, 0x96AC,
+ 0x96AD, 0x96AE, 0x96AF, 0x96B1, 0x96B2, 0x96B4, 0x96B5, 0x96B7,
+ 0x96B8, 0x96BA, 0x96BB, 0x96BF, 0x96C2, 0x96C3, 0x96C8, 0x96CA,
+ 0x96CB, 0x96D0, 0x96D1, 0x96D3, 0x96D4, 0x96D6, 0x96D7, 0x96D8,
+ 0x96D9, 0x96DA, 0x96DB, 0x96DC, 0x96DD, 0x96DE, 0x96DF, 0x96E1,
+ 0x96E2, 0x96E3, 0x96E4, 0x96E5, 0x96E6, 0x96E7, 0x96EB,
+ /* GB 0xEB80..0xEBFE */
+ 0x96EC, 0x96ED, 0x96EE, 0x96F0, 0x96F1, 0x96F2, 0x96F4, 0x96F5,
+ 0x96F8, 0x96FA, 0x96FB, 0x96FC, 0x96FD, 0x96FF, 0x9702, 0x9703,
+ 0x9705, 0x970A, 0x970B, 0x970C, 0x9710, 0x9711, 0x9712, 0x9714,
+ 0x9715, 0x9717, 0x9718, 0x9719, 0x971A, 0x971B, 0x971D, 0x971F,
+ 0x9720, 0x643F, 0x64D8, 0x8004, 0x6BEA, 0x6BF3, 0x6BFD, 0x6BF5,
+ 0x6BF9, 0x6C05, 0x6C07, 0x6C06, 0x6C0D, 0x6C15, 0x6C18, 0x6C19,
+ 0x6C1A, 0x6C21, 0x6C29, 0x6C24, 0x6C2A, 0x6C32, 0x6535, 0x6555,
+ 0x656B, 0x724D, 0x7252, 0x7256, 0x7230, 0x8662, 0x5216, 0x809F,
+ 0x809C, 0x8093, 0x80BC, 0x670A, 0x80BD, 0x80B1, 0x80AB, 0x80AD,
+ 0x80B4, 0x80B7, 0x80E7, 0x80E8, 0x80E9, 0x80EA, 0x80DB, 0x80C2,
+ 0x80C4, 0x80D9, 0x80CD, 0x80D7, 0x6710, 0x80DD, 0x80EB, 0x80F1,
+ 0x80F4, 0x80ED, 0x810D, 0x810E, 0x80F2, 0x80FC, 0x6715, 0x8112,
+ 0x8C5A, 0x8136, 0x811E, 0x812C, 0x8118, 0x8132, 0x8148, 0x814C,
+ 0x8153, 0x8174, 0x8159, 0x815A, 0x8171, 0x8160, 0x8169, 0x817C,
+ 0x817D, 0x816D, 0x8167, 0x584D, 0x5AB5, 0x8188, 0x8182, 0x8191,
+ 0x6ED5, 0x81A3, 0x81AA, 0x81CC, 0x6726, 0x81CA, 0x81BB,
+ /* GB 0xEC40..0xEC7E */
+ 0x9721, 0x9722, 0x9723, 0x9724, 0x9725, 0x9726, 0x9727, 0x9728,
+ 0x9729, 0x972B, 0x972C, 0x972E, 0x972F, 0x9731, 0x9733, 0x9734,
+ 0x9735, 0x9736, 0x9737, 0x973A, 0x973B, 0x973C, 0x973D, 0x973F,
+ 0x9740, 0x9741, 0x9742, 0x9743, 0x9744, 0x9745, 0x9746, 0x9747,
+ 0x9748, 0x9749, 0x974A, 0x974B, 0x974C, 0x974D, 0x974E, 0x974F,
+ 0x9750, 0x9751, 0x9754, 0x9755, 0x9757, 0x9758, 0x975A, 0x975C,
+ 0x975D, 0x975F, 0x9763, 0x9764, 0x9766, 0x9767, 0x9768, 0x976A,
+ 0x976B, 0x976C, 0x976D, 0x976E, 0x976F, 0x9770, 0x9771,
+ /* GB 0xEC80..0xECFE */
+ 0x9772, 0x9775, 0x9777, 0x9778, 0x9779, 0x977A, 0x977B, 0x977D,
+ 0x977E, 0x977F, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9786,
+ 0x9787, 0x9788, 0x9789, 0x978A, 0x978C, 0x978E, 0x978F, 0x9790,
+ 0x9793, 0x9795, 0x9796, 0x9797, 0x9799, 0x979A, 0x979B, 0x979C,
+ 0x979D, 0x81C1, 0x81A6, 0x6B24, 0x6B37, 0x6B39, 0x6B43, 0x6B46,
+ 0x6B59, 0x98D1, 0x98D2, 0x98D3, 0x98D5, 0x98D9, 0x98DA, 0x6BB3,
+ 0x5F40, 0x6BC2, 0x89F3, 0x6590, 0x9F51, 0x6593, 0x65BC, 0x65C6,
+ 0x65C4, 0x65C3, 0x65CC, 0x65CE, 0x65D2, 0x65D6, 0x7080, 0x709C,
+ 0x7096, 0x709D, 0x70BB, 0x70C0, 0x70B7, 0x70AB, 0x70B1, 0x70E8,
+ 0x70CA, 0x7110, 0x7113, 0x7116, 0x712F, 0x7131, 0x7173, 0x715C,
+ 0x7168, 0x7145, 0x7172, 0x714A, 0x7178, 0x717A, 0x7198, 0x71B3,
+ 0x71B5, 0x71A8, 0x71A0, 0x71E0, 0x71D4, 0x71E7, 0x71F9, 0x721D,
+ 0x7228, 0x706C, 0x7118, 0x7166, 0x71B9, 0x623E, 0x623D, 0x6243,
+ 0x6248, 0x6249, 0x793B, 0x7940, 0x7946, 0x7949, 0x795B, 0x795C,
+ 0x7953, 0x795A, 0x7962, 0x7957, 0x7960, 0x796F, 0x7967, 0x797A,
+ 0x7985, 0x798A, 0x799A, 0x79A7, 0x79B3, 0x5FD1, 0x5FD0,
+ /* GB 0xED40..0xED7E */
+ 0x979E, 0x979F, 0x97A1, 0x97A2, 0x97A4, 0x97A5, 0x97A6, 0x97A7,
+ 0x97A8, 0x97A9, 0x97AA, 0x97AC, 0x97AE, 0x97B0, 0x97B1, 0x97B3,
+ 0x97B5, 0x97B6, 0x97B7, 0x97B8, 0x97B9, 0x97BA, 0x97BB, 0x97BC,
+ 0x97BD, 0x97BE, 0x97BF, 0x97C0, 0x97C1, 0x97C2, 0x97C3, 0x97C4,
+ 0x97C5, 0x97C6, 0x97C7, 0x97C8, 0x97C9, 0x97CA, 0x97CB, 0x97CC,
+ 0x97CD, 0x97CE, 0x97CF, 0x97D0, 0x97D1, 0x97D2, 0x97D3, 0x97D4,
+ 0x97D5, 0x97D6, 0x97D7, 0x97D8, 0x97D9, 0x97DA, 0x97DB, 0x97DC,
+ 0x97DD, 0x97DE, 0x97DF, 0x97E0, 0x97E1, 0x97E2, 0x97E3,
+ /* GB 0xED80..0xEDFE */
+ 0x97E4, 0x97E5, 0x97E8, 0x97EE, 0x97EF, 0x97F0, 0x97F1, 0x97F2,
+ 0x97F4, 0x97F7, 0x97F8, 0x97F9, 0x97FA, 0x97FB, 0x97FC, 0x97FD,
+ 0x97FE, 0x97FF, 0x9800, 0x9801, 0x9802, 0x9803, 0x9804, 0x9805,
+ 0x9806, 0x9807, 0x9808, 0x9809, 0x980A, 0x980B, 0x980C, 0x980D,
+ 0x980E, 0x603C, 0x605D, 0x605A, 0x6067, 0x6041, 0x6059, 0x6063,
+ 0x60AB, 0x6106, 0x610D, 0x615D, 0x61A9, 0x619D, 0x61CB, 0x61D1,
+ 0x6206, 0x8080, 0x807F, 0x6C93, 0x6CF6, 0x6DFC, 0x77F6, 0x77F8,
+ 0x7800, 0x7809, 0x7817, 0x7818, 0x7811, 0x65AB, 0x782D, 0x781C,
+ 0x781D, 0x7839, 0x783A, 0x783B, 0x781F, 0x783C, 0x7825, 0x782C,
+ 0x7823, 0x7829, 0x784E, 0x786D, 0x7856, 0x7857, 0x7826, 0x7850,
+ 0x7847, 0x784C, 0x786A, 0x789B, 0x7893, 0x789A, 0x7887, 0x789C,
+ 0x78A1, 0x78A3, 0x78B2, 0x78B9, 0x78A5, 0x78D4, 0x78D9, 0x78C9,
+ 0x78EC, 0x78F2, 0x7905, 0x78F4, 0x7913, 0x7924, 0x791E, 0x7934,
+ 0x9F9B, 0x9EF9, 0x9EFB, 0x9EFC, 0x76F1, 0x7704, 0x770D, 0x76F9,
+ 0x7707, 0x7708, 0x771A, 0x7722, 0x7719, 0x772D, 0x7726, 0x7735,
+ 0x7738, 0x7750, 0x7751, 0x7747, 0x7743, 0x775A, 0x7768,
+ /* GB 0xEE40..0xEE7E */
+ 0x980F, 0x9810, 0x9811, 0x9812, 0x9813, 0x9814, 0x9815, 0x9816,
+ 0x9817, 0x9818, 0x9819, 0x981A, 0x981B, 0x981C, 0x981D, 0x981E,
+ 0x981F, 0x9820, 0x9821, 0x9822, 0x9823, 0x9824, 0x9825, 0x9826,
+ 0x9827, 0x9828, 0x9829, 0x982A, 0x982B, 0x982C, 0x982D, 0x982E,
+ 0x982F, 0x9830, 0x9831, 0x9832, 0x9833, 0x9834, 0x9835, 0x9836,
+ 0x9837, 0x9838, 0x9839, 0x983A, 0x983B, 0x983C, 0x983D, 0x983E,
+ 0x983F, 0x9840, 0x9841, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846,
+ 0x9847, 0x9848, 0x9849, 0x984A, 0x984B, 0x984C, 0x984D,
+ /* GB 0xEE80..0xEEFE */
+ 0x984E, 0x984F, 0x9850, 0x9851, 0x9852, 0x9853, 0x9854, 0x9855,
+ 0x9856, 0x9857, 0x9858, 0x9859, 0x985A, 0x985B, 0x985C, 0x985D,
+ 0x985E, 0x985F, 0x9860, 0x9861, 0x9862, 0x9863, 0x9864, 0x9865,
+ 0x9866, 0x9867, 0x9868, 0x9869, 0x986A, 0x986B, 0x986C, 0x986D,
+ 0x986E, 0x7762, 0x7765, 0x777F, 0x778D, 0x777D, 0x7780, 0x778C,
+ 0x7791, 0x779F, 0x77A0, 0x77B0, 0x77B5, 0x77BD, 0x753A, 0x7540,
+ 0x754E, 0x754B, 0x7548, 0x755B, 0x7572, 0x7579, 0x7583, 0x7F58,
+ 0x7F61, 0x7F5F, 0x8A48, 0x7F68, 0x7F74, 0x7F71, 0x7F79, 0x7F81,
+ 0x7F7E, 0x76CD, 0x76E5, 0x8832, 0x9485, 0x9486, 0x9487, 0x948B,
+ 0x948A, 0x948C, 0x948D, 0x948F, 0x9490, 0x9494, 0x9497, 0x9495,
+ 0x949A, 0x949B, 0x949C, 0x94A3, 0x94A4, 0x94AB, 0x94AA, 0x94AD,
+ 0x94AC, 0x94AF, 0x94B0, 0x94B2, 0x94B4, 0x94B6, 0x94B7, 0x94B8,
+ 0x94B9, 0x94BA, 0x94BC, 0x94BD, 0x94BF, 0x94C4, 0x94C8, 0x94C9,
+ 0x94CA, 0x94CB, 0x94CC, 0x94CD, 0x94CE, 0x94D0, 0x94D1, 0x94D2,
+ 0x94D5, 0x94D6, 0x94D7, 0x94D9, 0x94D8, 0x94DB, 0x94DE, 0x94DF,
+ 0x94E0, 0x94E2, 0x94E4, 0x94E5, 0x94E7, 0x94E8, 0x94EA,
+ /* GB 0xEF40..0xEF7E */
+ 0x986F, 0x9870, 0x9871, 0x9872, 0x9873, 0x9874, 0x988B, 0x988E,
+ 0x9892, 0x9895, 0x9899, 0x98A3, 0x98A8, 0x98A9, 0x98AA, 0x98AB,
+ 0x98AC, 0x98AD, 0x98AE, 0x98AF, 0x98B0, 0x98B1, 0x98B2, 0x98B3,
+ 0x98B4, 0x98B5, 0x98B6, 0x98B7, 0x98B8, 0x98B9, 0x98BA, 0x98BB,
+ 0x98BC, 0x98BD, 0x98BE, 0x98BF, 0x98C0, 0x98C1, 0x98C2, 0x98C3,
+ 0x98C4, 0x98C5, 0x98C6, 0x98C7, 0x98C8, 0x98C9, 0x98CA, 0x98CB,
+ 0x98CC, 0x98CD, 0x98CF, 0x98D0, 0x98D4, 0x98D6, 0x98D7, 0x98DB,
+ 0x98DC, 0x98DD, 0x98E0, 0x98E1, 0x98E2, 0x98E3, 0x98E4,
+ /* GB 0xEF80..0xEFFE */
+ 0x98E5, 0x98E6, 0x98E9, 0x98EA, 0x98EB, 0x98EC, 0x98ED, 0x98EE,
+ 0x98EF, 0x98F0, 0x98F1, 0x98F2, 0x98F3, 0x98F4, 0x98F5, 0x98F6,
+ 0x98F7, 0x98F8, 0x98F9, 0x98FA, 0x98FB, 0x98FC, 0x98FD, 0x98FE,
+ 0x98FF, 0x9900, 0x9901, 0x9902, 0x9903, 0x9904, 0x9905, 0x9906,
+ 0x9907, 0x94E9, 0x94EB, 0x94EE, 0x94EF, 0x94F3, 0x94F4, 0x94F5,
+ 0x94F7, 0x94F9, 0x94FC, 0x94FD, 0x94FF, 0x9503, 0x9502, 0x9506,
+ 0x9507, 0x9509, 0x950A, 0x950D, 0x950E, 0x950F, 0x9512, 0x9513,
+ 0x9514, 0x9515, 0x9516, 0x9518, 0x951B, 0x951D, 0x951E, 0x951F,
+ 0x9522, 0x952A, 0x952B, 0x9529, 0x952C, 0x9531, 0x9532, 0x9534,
+ 0x9536, 0x9537, 0x9538, 0x953C, 0x953E, 0x953F, 0x9542, 0x9535,
+ 0x9544, 0x9545, 0x9546, 0x9549, 0x954C, 0x954E, 0x954F, 0x9552,
+ 0x9553, 0x9554, 0x9556, 0x9557, 0x9558, 0x9559, 0x955B, 0x955E,
+ 0x955F, 0x955D, 0x9561, 0x9562, 0x9564, 0x9565, 0x9566, 0x9567,
+ 0x9568, 0x9569, 0x956A, 0x956B, 0x956C, 0x956F, 0x9571, 0x9572,
+ 0x9573, 0x953A, 0x77E7, 0x77EC, 0x96C9, 0x79D5, 0x79ED, 0x79E3,
+ 0x79EB, 0x7A06, 0x5D47, 0x7A03, 0x7A02, 0x7A1E, 0x7A14,
+ /* GB 0xF040..0xF07E */
+ 0x9908, 0x9909, 0x990A, 0x990B, 0x990C, 0x990E, 0x990F, 0x9911,
+ 0x9912, 0x9913, 0x9914, 0x9915, 0x9916, 0x9917, 0x9918, 0x9919,
+ 0x991A, 0x991B, 0x991C, 0x991D, 0x991E, 0x991F, 0x9920, 0x9921,
+ 0x9922, 0x9923, 0x9924, 0x9925, 0x9926, 0x9927, 0x9928, 0x9929,
+ 0x992A, 0x992B, 0x992C, 0x992D, 0x992F, 0x9930, 0x9931, 0x9932,
+ 0x9933, 0x9934, 0x9935, 0x9936, 0x9937, 0x9938, 0x9939, 0x993A,
+ 0x993B, 0x993C, 0x993D, 0x993E, 0x993F, 0x9940, 0x9941, 0x9942,
+ 0x9943, 0x9944, 0x9945, 0x9946, 0x9947, 0x9948, 0x9949,
+ /* GB 0xF080..0xF0FE */
+ 0x994A, 0x994B, 0x994C, 0x994D, 0x994E, 0x994F, 0x9950, 0x9951,
+ 0x9952, 0x9953, 0x9956, 0x9957, 0x9958, 0x9959, 0x995A, 0x995B,
+ 0x995C, 0x995D, 0x995E, 0x995F, 0x9960, 0x9961, 0x9962, 0x9964,
+ 0x9966, 0x9973, 0x9978, 0x9979, 0x997B, 0x997E, 0x9982, 0x9983,
+ 0x9989, 0x7A39, 0x7A37, 0x7A51, 0x9ECF, 0x99A5, 0x7A70, 0x7688,
+ 0x768E, 0x7693, 0x7699, 0x76A4, 0x74DE, 0x74E0, 0x752C, 0x9E20,
+ 0x9E22, 0x9E28, 0x9E29, 0x9E2A, 0x9E2B, 0x9E2C, 0x9E32, 0x9E31,
+ 0x9E36, 0x9E38, 0x9E37, 0x9E39, 0x9E3A, 0x9E3E, 0x9E41, 0x9E42,
+ 0x9E44, 0x9E46, 0x9E47, 0x9E48, 0x9E49, 0x9E4B, 0x9E4C, 0x9E4E,
+ 0x9E51, 0x9E55, 0x9E57, 0x9E5A, 0x9E5B, 0x9E5C, 0x9E5E, 0x9E63,
+ 0x9E66, 0x9E67, 0x9E68, 0x9E69, 0x9E6A, 0x9E6B, 0x9E6C, 0x9E71,
+ 0x9E6D, 0x9E73, 0x7592, 0x7594, 0x7596, 0x75A0, 0x759D, 0x75AC,
+ 0x75A3, 0x75B3, 0x75B4, 0x75B8, 0x75C4, 0x75B1, 0x75B0, 0x75C3,
+ 0x75C2, 0x75D6, 0x75CD, 0x75E3, 0x75E8, 0x75E6, 0x75E4, 0x75EB,
+ 0x75E7, 0x7603, 0x75F1, 0x75FC, 0x75FF, 0x7610, 0x7600, 0x7605,
+ 0x760C, 0x7617, 0x760A, 0x7625, 0x7618, 0x7615, 0x7619,
+ /* GB 0xF140..0xF17E */
+ 0x998C, 0x998E, 0x999A, 0x999B, 0x999C, 0x999D, 0x999E, 0x999F,
+ 0x99A0, 0x99A1, 0x99A2, 0x99A3, 0x99A4, 0x99A6, 0x99A7, 0x99A9,
+ 0x99AA, 0x99AB, 0x99AC, 0x99AD, 0x99AE, 0x99AF, 0x99B0, 0x99B1,
+ 0x99B2, 0x99B3, 0x99B4, 0x99B5, 0x99B6, 0x99B7, 0x99B8, 0x99B9,
+ 0x99BA, 0x99BB, 0x99BC, 0x99BD, 0x99BE, 0x99BF, 0x99C0, 0x99C1,
+ 0x99C2, 0x99C3, 0x99C4, 0x99C5, 0x99C6, 0x99C7, 0x99C8, 0x99C9,
+ 0x99CA, 0x99CB, 0x99CC, 0x99CD, 0x99CE, 0x99CF, 0x99D0, 0x99D1,
+ 0x99D2, 0x99D3, 0x99D4, 0x99D5, 0x99D6, 0x99D7, 0x99D8,
+ /* GB 0xF180..0xF1FE */
+ 0x99D9, 0x99DA, 0x99DB, 0x99DC, 0x99DD, 0x99DE, 0x99DF, 0x99E0,
+ 0x99E1, 0x99E2, 0x99E3, 0x99E4, 0x99E5, 0x99E6, 0x99E7, 0x99E8,
+ 0x99E9, 0x99EA, 0x99EB, 0x99EC, 0x99ED, 0x99EE, 0x99EF, 0x99F0,
+ 0x99F1, 0x99F2, 0x99F3, 0x99F4, 0x99F5, 0x99F6, 0x99F7, 0x99F8,
+ 0x99F9, 0x761B, 0x763C, 0x7622, 0x7620, 0x7640, 0x762D, 0x7630,
+ 0x763F, 0x7635, 0x7643, 0x763E, 0x7633, 0x764D, 0x765E, 0x7654,
+ 0x765C, 0x7656, 0x766B, 0x766F, 0x7FCA, 0x7AE6, 0x7A78, 0x7A79,
+ 0x7A80, 0x7A86, 0x7A88, 0x7A95, 0x7AA6, 0x7AA0, 0x7AAC, 0x7AA8,
+ 0x7AAD, 0x7AB3, 0x8864, 0x8869, 0x8872, 0x887D, 0x887F, 0x8882,
+ 0x88A2, 0x88C6, 0x88B7, 0x88BC, 0x88C9, 0x88E2, 0x88CE, 0x88E3,
+ 0x88E5, 0x88F1, 0x891A, 0x88FC, 0x88E8, 0x88FE, 0x88F0, 0x8921,
+ 0x8919, 0x8913, 0x891B, 0x890A, 0x8934, 0x892B, 0x8936, 0x8941,
+ 0x8966, 0x897B, 0x758B, 0x80E5, 0x76B2, 0x76B4, 0x77DC, 0x8012,
+ 0x8014, 0x8016, 0x801C, 0x8020, 0x8022, 0x8025, 0x8026, 0x8027,
+ 0x8029, 0x8028, 0x8031, 0x800B, 0x8035, 0x8043, 0x8046, 0x804D,
+ 0x8052, 0x8069, 0x8071, 0x8983, 0x9878, 0x9880, 0x9883,
+ /* GB 0xF240..0xF27E */
+ 0x99FA, 0x99FB, 0x99FC, 0x99FD, 0x99FE, 0x99FF, 0x9A00, 0x9A01,
+ 0x9A02, 0x9A03, 0x9A04, 0x9A05, 0x9A06, 0x9A07, 0x9A08, 0x9A09,
+ 0x9A0A, 0x9A0B, 0x9A0C, 0x9A0D, 0x9A0E, 0x9A0F, 0x9A10, 0x9A11,
+ 0x9A12, 0x9A13, 0x9A14, 0x9A15, 0x9A16, 0x9A17, 0x9A18, 0x9A19,
+ 0x9A1A, 0x9A1B, 0x9A1C, 0x9A1D, 0x9A1E, 0x9A1F, 0x9A20, 0x9A21,
+ 0x9A22, 0x9A23, 0x9A24, 0x9A25, 0x9A26, 0x9A27, 0x9A28, 0x9A29,
+ 0x9A2A, 0x9A2B, 0x9A2C, 0x9A2D, 0x9A2E, 0x9A2F, 0x9A30, 0x9A31,
+ 0x9A32, 0x9A33, 0x9A34, 0x9A35, 0x9A36, 0x9A37, 0x9A38,
+ /* GB 0xF280..0xF2FE */
+ 0x9A39, 0x9A3A, 0x9A3B, 0x9A3C, 0x9A3D, 0x9A3E, 0x9A3F, 0x9A40,
+ 0x9A41, 0x9A42, 0x9A43, 0x9A44, 0x9A45, 0x9A46, 0x9A47, 0x9A48,
+ 0x9A49, 0x9A4A, 0x9A4B, 0x9A4C, 0x9A4D, 0x9A4E, 0x9A4F, 0x9A50,
+ 0x9A51, 0x9A52, 0x9A53, 0x9A54, 0x9A55, 0x9A56, 0x9A57, 0x9A58,
+ 0x9A59, 0x9889, 0x988C, 0x988D, 0x988F, 0x9894, 0x989A, 0x989B,
+ 0x989E, 0x989F, 0x98A1, 0x98A2, 0x98A5, 0x98A6, 0x864D, 0x8654,
+ 0x866C, 0x866E, 0x867F, 0x867A, 0x867C, 0x867B, 0x86A8, 0x868D,
+ 0x868B, 0x86AC, 0x869D, 0x86A7, 0x86A3, 0x86AA, 0x8693, 0x86A9,
+ 0x86B6, 0x86C4, 0x86B5, 0x86CE, 0x86B0, 0x86BA, 0x86B1, 0x86AF,
+ 0x86C9, 0x86CF, 0x86B4, 0x86E9, 0x86F1, 0x86F2, 0x86ED, 0x86F3,
+ 0x86D0, 0x8713, 0x86DE, 0x86F4, 0x86DF, 0x86D8, 0x86D1, 0x8703,
+ 0x8707, 0x86F8, 0x8708, 0x870A, 0x870D, 0x8709, 0x8723, 0x873B,
+ 0x871E, 0x8725, 0x872E, 0x871A, 0x873E, 0x8748, 0x8734, 0x8731,
+ 0x8729, 0x8737, 0x873F, 0x8782, 0x8722, 0x877D, 0x877E, 0x877B,
+ 0x8760, 0x8770, 0x874C, 0x876E, 0x878B, 0x8753, 0x8763, 0x877C,
+ 0x8764, 0x8759, 0x8765, 0x8793, 0x87AF, 0x87A8, 0x87D2,
+ /* GB 0xF340..0xF37E */
+ 0x9A5A, 0x9A5B, 0x9A5C, 0x9A5D, 0x9A5E, 0x9A5F, 0x9A60, 0x9A61,
+ 0x9A62, 0x9A63, 0x9A64, 0x9A65, 0x9A66, 0x9A67, 0x9A68, 0x9A69,
+ 0x9A6A, 0x9A6B, 0x9A72, 0x9A83, 0x9A89, 0x9A8D, 0x9A8E, 0x9A94,
+ 0x9A95, 0x9A99, 0x9AA6, 0x9AA9, 0x9AAA, 0x9AAB, 0x9AAC, 0x9AAD,
+ 0x9AAE, 0x9AAF, 0x9AB2, 0x9AB3, 0x9AB4, 0x9AB5, 0x9AB9, 0x9ABB,
+ 0x9ABD, 0x9ABE, 0x9ABF, 0x9AC3, 0x9AC4, 0x9AC6, 0x9AC7, 0x9AC8,
+ 0x9AC9, 0x9ACA, 0x9ACD, 0x9ACE, 0x9ACF, 0x9AD0, 0x9AD2, 0x9AD4,
+ 0x9AD5, 0x9AD6, 0x9AD7, 0x9AD9, 0x9ADA, 0x9ADB, 0x9ADC,
+ /* GB 0xF380..0xF3FE */
+ 0x9ADD, 0x9ADE, 0x9AE0, 0x9AE2, 0x9AE3, 0x9AE4, 0x9AE5, 0x9AE7,
+ 0x9AE8, 0x9AE9, 0x9AEA, 0x9AEC, 0x9AEE, 0x9AF0, 0x9AF1, 0x9AF2,
+ 0x9AF3, 0x9AF4, 0x9AF5, 0x9AF6, 0x9AF7, 0x9AF8, 0x9AFA, 0x9AFC,
+ 0x9AFD, 0x9AFE, 0x9AFF, 0x9B00, 0x9B01, 0x9B02, 0x9B04, 0x9B05,
+ 0x9B06, 0x87C6, 0x8788, 0x8785, 0x87AD, 0x8797, 0x8783, 0x87AB,
+ 0x87E5, 0x87AC, 0x87B5, 0x87B3, 0x87CB, 0x87D3, 0x87BD, 0x87D1,
+ 0x87C0, 0x87CA, 0x87DB, 0x87EA, 0x87E0, 0x87EE, 0x8816, 0x8813,
+ 0x87FE, 0x880A, 0x881B, 0x8821, 0x8839, 0x883C, 0x7F36, 0x7F42,
+ 0x7F44, 0x7F45, 0x8210, 0x7AFA, 0x7AFD, 0x7B08, 0x7B03, 0x7B04,
+ 0x7B15, 0x7B0A, 0x7B2B, 0x7B0F, 0x7B47, 0x7B38, 0x7B2A, 0x7B19,
+ 0x7B2E, 0x7B31, 0x7B20, 0x7B25, 0x7B24, 0x7B33, 0x7B3E, 0x7B1E,
+ 0x7B58, 0x7B5A, 0x7B45, 0x7B75, 0x7B4C, 0x7B5D, 0x7B60, 0x7B6E,
+ 0x7B7B, 0x7B62, 0x7B72, 0x7B71, 0x7B90, 0x7BA6, 0x7BA7, 0x7BB8,
+ 0x7BAC, 0x7B9D, 0x7BA8, 0x7B85, 0x7BAA, 0x7B9C, 0x7BA2, 0x7BAB,
+ 0x7BB4, 0x7BD1, 0x7BC1, 0x7BCC, 0x7BDD, 0x7BDA, 0x7BE5, 0x7BE6,
+ 0x7BEA, 0x7C0C, 0x7BFE, 0x7BFC, 0x7C0F, 0x7C16, 0x7C0B,
+ /* GB 0xF440..0xF47E */
+ 0x9B07, 0x9B09, 0x9B0A, 0x9B0B, 0x9B0C, 0x9B0D, 0x9B0E, 0x9B10,
+ 0x9B11, 0x9B12, 0x9B14, 0x9B15, 0x9B16, 0x9B17, 0x9B18, 0x9B19,
+ 0x9B1A, 0x9B1B, 0x9B1C, 0x9B1D, 0x9B1E, 0x9B20, 0x9B21, 0x9B22,
+ 0x9B24, 0x9B25, 0x9B26, 0x9B27, 0x9B28, 0x9B29, 0x9B2A, 0x9B2B,
+ 0x9B2C, 0x9B2D, 0x9B2E, 0x9B30, 0x9B31, 0x9B33, 0x9B34, 0x9B35,
+ 0x9B36, 0x9B37, 0x9B38, 0x9B39, 0x9B3A, 0x9B3D, 0x9B3E, 0x9B3F,
+ 0x9B40, 0x9B46, 0x9B4A, 0x9B4B, 0x9B4C, 0x9B4E, 0x9B50, 0x9B52,
+ 0x9B53, 0x9B55, 0x9B56, 0x9B57, 0x9B58, 0x9B59, 0x9B5A,
+ /* GB 0xF480..0xF4FE */
+ 0x9B5B, 0x9B5C, 0x9B5D, 0x9B5E, 0x9B5F, 0x9B60, 0x9B61, 0x9B62,
+ 0x9B63, 0x9B64, 0x9B65, 0x9B66, 0x9B67, 0x9B68, 0x9B69, 0x9B6A,
+ 0x9B6B, 0x9B6C, 0x9B6D, 0x9B6E, 0x9B6F, 0x9B70, 0x9B71, 0x9B72,
+ 0x9B73, 0x9B74, 0x9B75, 0x9B76, 0x9B77, 0x9B78, 0x9B79, 0x9B7A,
+ 0x9B7B, 0x7C1F, 0x7C2A, 0x7C26, 0x7C38, 0x7C41, 0x7C40, 0x81FE,
+ 0x8201, 0x8202, 0x8204, 0x81EC, 0x8844, 0x8221, 0x8222, 0x8223,
+ 0x822D, 0x822F, 0x8228, 0x822B, 0x8238, 0x823B, 0x8233, 0x8234,
+ 0x823E, 0x8244, 0x8249, 0x824B, 0x824F, 0x825A, 0x825F, 0x8268,
+ 0x887E, 0x8885, 0x8888, 0x88D8, 0x88DF, 0x895E, 0x7F9D, 0x7F9F,
+ 0x7FA7, 0x7FAF, 0x7FB0, 0x7FB2, 0x7C7C, 0x6549, 0x7C91, 0x7C9D,
+ 0x7C9C, 0x7C9E, 0x7CA2, 0x7CB2, 0x7CBC, 0x7CBD, 0x7CC1, 0x7CC7,
+ 0x7CCC, 0x7CCD, 0x7CC8, 0x7CC5, 0x7CD7, 0x7CE8, 0x826E, 0x66A8,
+ 0x7FBF, 0x7FCE, 0x7FD5, 0x7FE5, 0x7FE1, 0x7FE6, 0x7FE9, 0x7FEE,
+ 0x7FF3, 0x7CF8, 0x7D77, 0x7DA6, 0x7DAE, 0x7E47, 0x7E9B, 0x9EB8,
+ 0x9EB4, 0x8D73, 0x8D84, 0x8D94, 0x8D91, 0x8DB1, 0x8D67, 0x8D6D,
+ 0x8C47, 0x8C49, 0x914A, 0x9150, 0x914E, 0x914F, 0x9164,
+ /* GB 0xF540..0xF57E */
+ 0x9B7C, 0x9B7D, 0x9B7E, 0x9B7F, 0x9B80, 0x9B81, 0x9B82, 0x9B83,
+ 0x9B84, 0x9B85, 0x9B86, 0x9B87, 0x9B88, 0x9B89, 0x9B8A, 0x9B8B,
+ 0x9B8C, 0x9B8D, 0x9B8E, 0x9B8F, 0x9B90, 0x9B91, 0x9B92, 0x9B93,
+ 0x9B94, 0x9B95, 0x9B96, 0x9B97, 0x9B98, 0x9B99, 0x9B9A, 0x9B9B,
+ 0x9B9C, 0x9B9D, 0x9B9E, 0x9B9F, 0x9BA0, 0x9BA1, 0x9BA2, 0x9BA3,
+ 0x9BA4, 0x9BA5, 0x9BA6, 0x9BA7, 0x9BA8, 0x9BA9, 0x9BAA, 0x9BAB,
+ 0x9BAC, 0x9BAD, 0x9BAE, 0x9BAF, 0x9BB0, 0x9BB1, 0x9BB2, 0x9BB3,
+ 0x9BB4, 0x9BB5, 0x9BB6, 0x9BB7, 0x9BB8, 0x9BB9, 0x9BBA,
+ /* GB 0xF580..0xF5FE */
+ 0x9BBB, 0x9BBC, 0x9BBD, 0x9BBE, 0x9BBF, 0x9BC0, 0x9BC1, 0x9BC2,
+ 0x9BC3, 0x9BC4, 0x9BC5, 0x9BC6, 0x9BC7, 0x9BC8, 0x9BC9, 0x9BCA,
+ 0x9BCB, 0x9BCC, 0x9BCD, 0x9BCE, 0x9BCF, 0x9BD0, 0x9BD1, 0x9BD2,
+ 0x9BD3, 0x9BD4, 0x9BD5, 0x9BD6, 0x9BD7, 0x9BD8, 0x9BD9, 0x9BDA,
+ 0x9BDB, 0x9162, 0x9161, 0x9170, 0x9169, 0x916F, 0x917D, 0x917E,
+ 0x9172, 0x9174, 0x9179, 0x918C, 0x9185, 0x9190, 0x918D, 0x9191,
+ 0x91A2, 0x91A3, 0x91AA, 0x91AD, 0x91AE, 0x91AF, 0x91B5, 0x91B4,
+ 0x91BA, 0x8C55, 0x9E7E, 0x8DB8, 0x8DEB, 0x8E05, 0x8E59, 0x8E69,
+ 0x8DB5, 0x8DBF, 0x8DBC, 0x8DBA, 0x8DC4, 0x8DD6, 0x8DD7, 0x8DDA,
+ 0x8DDE, 0x8DCE, 0x8DCF, 0x8DDB, 0x8DC6, 0x8DEC, 0x8DF7, 0x8DF8,
+ 0x8DE3, 0x8DF9, 0x8DFB, 0x8DE4, 0x8E09, 0x8DFD, 0x8E14, 0x8E1D,
+ 0x8E1F, 0x8E2C, 0x8E2E, 0x8E23, 0x8E2F, 0x8E3A, 0x8E40, 0x8E39,
+ 0x8E35, 0x8E3D, 0x8E31, 0x8E49, 0x8E41, 0x8E42, 0x8E51, 0x8E52,
+ 0x8E4A, 0x8E70, 0x8E76, 0x8E7C, 0x8E6F, 0x8E74, 0x8E85, 0x8E8F,
+ 0x8E94, 0x8E90, 0x8E9C, 0x8E9E, 0x8C78, 0x8C82, 0x8C8A, 0x8C85,
+ 0x8C98, 0x8C94, 0x659B, 0x89D6, 0x89DE, 0x89DA, 0x89DC,
+ /* GB 0xF640..0xF67E */
+ 0x9BDC, 0x9BDD, 0x9BDE, 0x9BDF, 0x9BE0, 0x9BE1, 0x9BE2, 0x9BE3,
+ 0x9BE4, 0x9BE5, 0x9BE6, 0x9BE7, 0x9BE8, 0x9BE9, 0x9BEA, 0x9BEB,
+ 0x9BEC, 0x9BED, 0x9BEE, 0x9BEF, 0x9BF0, 0x9BF1, 0x9BF2, 0x9BF3,
+ 0x9BF4, 0x9BF5, 0x9BF6, 0x9BF7, 0x9BF8, 0x9BF9, 0x9BFA, 0x9BFB,
+ 0x9BFC, 0x9BFD, 0x9BFE, 0x9BFF, 0x9C00, 0x9C01, 0x9C02, 0x9C03,
+ 0x9C04, 0x9C05, 0x9C06, 0x9C07, 0x9C08, 0x9C09, 0x9C0A, 0x9C0B,
+ 0x9C0C, 0x9C0D, 0x9C0E, 0x9C0F, 0x9C10, 0x9C11, 0x9C12, 0x9C13,
+ 0x9C14, 0x9C15, 0x9C16, 0x9C17, 0x9C18, 0x9C19, 0x9C1A,
+ /* GB 0xF680..0xF6FE */
+ 0x9C1B, 0x9C1C, 0x9C1D, 0x9C1E, 0x9C1F, 0x9C20, 0x9C21, 0x9C22,
+ 0x9C23, 0x9C24, 0x9C25, 0x9C26, 0x9C27, 0x9C28, 0x9C29, 0x9C2A,
+ 0x9C2B, 0x9C2C, 0x9C2D, 0x9C2E, 0x9C2F, 0x9C30, 0x9C31, 0x9C32,
+ 0x9C33, 0x9C34, 0x9C35, 0x9C36, 0x9C37, 0x9C38, 0x9C39, 0x9C3A,
+ 0x9C3B, 0x89E5, 0x89EB, 0x89EF, 0x8A3E, 0x8B26, 0x9753, 0x96E9,
+ 0x96F3, 0x96EF, 0x9706, 0x9701, 0x9708, 0x970F, 0x970E, 0x972A,
+ 0x972D, 0x9730, 0x973E, 0x9F80, 0x9F83, 0x9F85, 0x9F86, 0x9F87,
+ 0x9F88, 0x9F89, 0x9F8A, 0x9F8C, 0x9EFE, 0x9F0B, 0x9F0D, 0x96B9,
+ 0x96BC, 0x96BD, 0x96CE, 0x96D2, 0x77BF, 0x96E0, 0x928E, 0x92AE,
+ 0x92C8, 0x933E, 0x936A, 0x93CA, 0x938F, 0x943E, 0x946B, 0x9C7F,
+ 0x9C82, 0x9C85, 0x9C86, 0x9C87, 0x9C88, 0x7A23, 0x9C8B, 0x9C8E,
+ 0x9C90, 0x9C91, 0x9C92, 0x9C94, 0x9C95, 0x9C9A, 0x9C9B, 0x9C9E,
+ 0x9C9F, 0x9CA0, 0x9CA1, 0x9CA2, 0x9CA3, 0x9CA5, 0x9CA6, 0x9CA7,
+ 0x9CA8, 0x9CA9, 0x9CAB, 0x9CAD, 0x9CAE, 0x9CB0, 0x9CB1, 0x9CB2,
+ 0x9CB3, 0x9CB4, 0x9CB5, 0x9CB6, 0x9CB7, 0x9CBA, 0x9CBB, 0x9CBC,
+ 0x9CBD, 0x9CC4, 0x9CC5, 0x9CC6, 0x9CC7, 0x9CCA, 0x9CCB,
+ /* GB 0xF740..0xF77E */
+ 0x9C3C, 0x9C3D, 0x9C3E, 0x9C3F, 0x9C40, 0x9C41, 0x9C42, 0x9C43,
+ 0x9C44, 0x9C45, 0x9C46, 0x9C47, 0x9C48, 0x9C49, 0x9C4A, 0x9C4B,
+ 0x9C4C, 0x9C4D, 0x9C4E, 0x9C4F, 0x9C50, 0x9C51, 0x9C52, 0x9C53,
+ 0x9C54, 0x9C55, 0x9C56, 0x9C57, 0x9C58, 0x9C59, 0x9C5A, 0x9C5B,
+ 0x9C5C, 0x9C5D, 0x9C5E, 0x9C5F, 0x9C60, 0x9C61, 0x9C62, 0x9C63,
+ 0x9C64, 0x9C65, 0x9C66, 0x9C67, 0x9C68, 0x9C69, 0x9C6A, 0x9C6B,
+ 0x9C6C, 0x9C6D, 0x9C6E, 0x9C6F, 0x9C70, 0x9C71, 0x9C72, 0x9C73,
+ 0x9C74, 0x9C75, 0x9C76, 0x9C77, 0x9C78, 0x9C79, 0x9C7A,
+ /* GB 0xF780..0xF7FE */
+ 0x9C7B, 0x9C7D, 0x9C7E, 0x9C80, 0x9C83, 0x9C84, 0x9C89, 0x9C8A,
+ 0x9C8C, 0x9C8F, 0x9C93, 0x9C96, 0x9C97, 0x9C98, 0x9C99, 0x9C9D,
+ 0x9CAA, 0x9CAC, 0x9CAF, 0x9CB9, 0x9CBE, 0x9CBF, 0x9CC0, 0x9CC1,
+ 0x9CC2, 0x9CC8, 0x9CC9, 0x9CD1, 0x9CD2, 0x9CDA, 0x9CDB, 0x9CE0,
+ 0x9CE1, 0x9CCC, 0x9CCD, 0x9CCE, 0x9CCF, 0x9CD0, 0x9CD3, 0x9CD4,
+ 0x9CD5, 0x9CD7, 0x9CD8, 0x9CD9, 0x9CDC, 0x9CDD, 0x9CDF, 0x9CE2,
+ 0x977C, 0x9785, 0x9791, 0x9792, 0x9794, 0x97AF, 0x97AB, 0x97A3,
+ 0x97B2, 0x97B4, 0x9AB1, 0x9AB0, 0x9AB7, 0x9E58, 0x9AB6, 0x9ABA,
+ 0x9ABC, 0x9AC1, 0x9AC0, 0x9AC5, 0x9AC2, 0x9ACB, 0x9ACC, 0x9AD1,
+ 0x9B45, 0x9B43, 0x9B47, 0x9B49, 0x9B48, 0x9B4D, 0x9B51, 0x98E8,
+ 0x990D, 0x992E, 0x9955, 0x9954, 0x9ADF, 0x9AE1, 0x9AE6, 0x9AEF,
+ 0x9AEB, 0x9AFB, 0x9AED, 0x9AF9, 0x9B08, 0x9B0F, 0x9B13, 0x9B1F,
+ 0x9B23, 0x9EBD, 0x9EBE, 0x7E3B, 0x9E82, 0x9E87, 0x9E88, 0x9E8B,
+ 0x9E92, 0x93D6, 0x9E9D, 0x9E9F, 0x9EDB, 0x9EDC, 0x9EDD, 0x9EE0,
+ 0x9EDF, 0x9EE2, 0x9EE9, 0x9EE7, 0x9EE5, 0x9EEA, 0x9EEF, 0x9F22,
+ 0x9F2C, 0x9F2F, 0x9F39, 0x9F37, 0x9F3D, 0x9F3E, 0x9F44,
+ /* GB 0xF840..0xF87E */
+ 0x9CE3, 0x9CE4, 0x9CE5, 0x9CE6, 0x9CE7, 0x9CE8, 0x9CE9, 0x9CEA,
+ 0x9CEB, 0x9CEC, 0x9CED, 0x9CEE, 0x9CEF, 0x9CF0, 0x9CF1, 0x9CF2,
+ 0x9CF3, 0x9CF4, 0x9CF5, 0x9CF6, 0x9CF7, 0x9CF8, 0x9CF9, 0x9CFA,
+ 0x9CFB, 0x9CFC, 0x9CFD, 0x9CFE, 0x9CFF, 0x9D00, 0x9D01, 0x9D02,
+ 0x9D03, 0x9D04, 0x9D05, 0x9D06, 0x9D07, 0x9D08, 0x9D09, 0x9D0A,
+ 0x9D0B, 0x9D0C, 0x9D0D, 0x9D0E, 0x9D0F, 0x9D10, 0x9D11, 0x9D12,
+ 0x9D13, 0x9D14, 0x9D15, 0x9D16, 0x9D17, 0x9D18, 0x9D19, 0x9D1A,
+ 0x9D1B, 0x9D1C, 0x9D1D, 0x9D1E, 0x9D1F, 0x9D20, 0x9D21,
+ /* GB 0xF880..0xF8A0 */
+ 0x9D22, 0x9D23, 0x9D24, 0x9D25, 0x9D26, 0x9D27, 0x9D28, 0x9D29,
+ 0x9D2A, 0x9D2B, 0x9D2C, 0x9D2D, 0x9D2E, 0x9D2F, 0x9D30, 0x9D31,
+ 0x9D32, 0x9D33, 0x9D34, 0x9D35, 0x9D36, 0x9D37, 0x9D38, 0x9D39,
+ 0x9D3A, 0x9D3B, 0x9D3C, 0x9D3D, 0x9D3E, 0x9D3F, 0x9D40, 0x9D41,
+ 0x9D42, /* Skip: GB 0xF8A1..0xF8FE (UDA 2) */
+ /* GB 0xF940..0xF97E */
+ 0x9D43, 0x9D44, 0x9D45, 0x9D46, 0x9D47, 0x9D48, 0x9D49, 0x9D4A,
+ 0x9D4B, 0x9D4C, 0x9D4D, 0x9D4E, 0x9D4F, 0x9D50, 0x9D51, 0x9D52,
+ 0x9D53, 0x9D54, 0x9D55, 0x9D56, 0x9D57, 0x9D58, 0x9D59, 0x9D5A,
+ 0x9D5B, 0x9D5C, 0x9D5D, 0x9D5E, 0x9D5F, 0x9D60, 0x9D61, 0x9D62,
+ 0x9D63, 0x9D64, 0x9D65, 0x9D66, 0x9D67, 0x9D68, 0x9D69, 0x9D6A,
+ 0x9D6B, 0x9D6C, 0x9D6D, 0x9D6E, 0x9D6F, 0x9D70, 0x9D71, 0x9D72,
+ 0x9D73, 0x9D74, 0x9D75, 0x9D76, 0x9D77, 0x9D78, 0x9D79, 0x9D7A,
+ 0x9D7B, 0x9D7C, 0x9D7D, 0x9D7E, 0x9D7F, 0x9D80, 0x9D81,
+ /* GB 0xF980..0xF9A0 */
+ 0x9D82, 0x9D83, 0x9D84, 0x9D85, 0x9D86, 0x9D87, 0x9D88, 0x9D89,
+ 0x9D8A, 0x9D8B, 0x9D8C, 0x9D8D, 0x9D8E, 0x9D8F, 0x9D90, 0x9D91,
+ 0x9D92, 0x9D93, 0x9D94, 0x9D95, 0x9D96, 0x9D97, 0x9D98, 0x9D99,
+ 0x9D9A, 0x9D9B, 0x9D9C, 0x9D9D, 0x9D9E, 0x9D9F, 0x9DA0, 0x9DA1,
+ 0x9DA2, /* Skip: GB 0xF9A1..0xF9FE (UDA 2) */
+ /* GB 0xFA40..0xFA7E */
+ 0x9DA3, 0x9DA4, 0x9DA5, 0x9DA6, 0x9DA7, 0x9DA8, 0x9DA9, 0x9DAA,
+ 0x9DAB, 0x9DAC, 0x9DAD, 0x9DAE, 0x9DAF, 0x9DB0, 0x9DB1, 0x9DB2,
+ 0x9DB3, 0x9DB4, 0x9DB5, 0x9DB6, 0x9DB7, 0x9DB8, 0x9DB9, 0x9DBA,
+ 0x9DBB, 0x9DBC, 0x9DBD, 0x9DBE, 0x9DBF, 0x9DC0, 0x9DC1, 0x9DC2,
+ 0x9DC3, 0x9DC4, 0x9DC5, 0x9DC6, 0x9DC7, 0x9DC8, 0x9DC9, 0x9DCA,
+ 0x9DCB, 0x9DCC, 0x9DCD, 0x9DCE, 0x9DCF, 0x9DD0, 0x9DD1, 0x9DD2,
+ 0x9DD3, 0x9DD4, 0x9DD5, 0x9DD6, 0x9DD7, 0x9DD8, 0x9DD9, 0x9DDA,
+ 0x9DDB, 0x9DDC, 0x9DDD, 0x9DDE, 0x9DDF, 0x9DE0, 0x9DE1,
+ /* GB 0xFA80..0xFAA0 */
+ 0x9DE2, 0x9DE3, 0x9DE4, 0x9DE5, 0x9DE6, 0x9DE7, 0x9DE8, 0x9DE9,
+ 0x9DEA, 0x9DEB, 0x9DEC, 0x9DED, 0x9DEE, 0x9DEF, 0x9DF0, 0x9DF1,
+ 0x9DF2, 0x9DF3, 0x9DF4, 0x9DF5, 0x9DF6, 0x9DF7, 0x9DF8, 0x9DF9,
+ 0x9DFA, 0x9DFB, 0x9DFC, 0x9DFD, 0x9DFE, 0x9DFF, 0x9E00, 0x9E01,
+ 0x9E02, /* Skip: GB 0xFAA1..0xFAFE (UDA 2) */
+ /* GB 0xFB40..0xFB7E */
+ 0x9E03, 0x9E04, 0x9E05, 0x9E06, 0x9E07, 0x9E08, 0x9E09, 0x9E0A,
+ 0x9E0B, 0x9E0C, 0x9E0D, 0x9E0E, 0x9E0F, 0x9E10, 0x9E11, 0x9E12,
+ 0x9E13, 0x9E14, 0x9E15, 0x9E16, 0x9E17, 0x9E18, 0x9E19, 0x9E1A,
+ 0x9E1B, 0x9E1C, 0x9E1D, 0x9E1E, 0x9E24, 0x9E27, 0x9E2E, 0x9E30,
+ 0x9E34, 0x9E3B, 0x9E3C, 0x9E40, 0x9E4D, 0x9E50, 0x9E52, 0x9E53,
+ 0x9E54, 0x9E56, 0x9E59, 0x9E5D, 0x9E5F, 0x9E60, 0x9E61, 0x9E62,
+ 0x9E65, 0x9E6E, 0x9E6F, 0x9E72, 0x9E74, 0x9E75, 0x9E76, 0x9E77,
+ 0x9E78, 0x9E79, 0x9E7A, 0x9E7B, 0x9E7C, 0x9E7D, 0x9E80,
+ /* GB 0xFB80..0xFBA0 */
+ 0x9E81, 0x9E83, 0x9E84, 0x9E85, 0x9E86, 0x9E89, 0x9E8A, 0x9E8C,
+ 0x9E8D, 0x9E8E, 0x9E8F, 0x9E90, 0x9E91, 0x9E94, 0x9E95, 0x9E96,
+ 0x9E97, 0x9E98, 0x9E99, 0x9E9A, 0x9E9B, 0x9E9C, 0x9E9E, 0x9EA0,
+ 0x9EA1, 0x9EA2, 0x9EA3, 0x9EA4, 0x9EA5, 0x9EA7, 0x9EA8, 0x9EA9,
+ 0x9EAA, /* Skip: GB 0xFBA1..0xFBFE (UDA 2) */
+ /* GB 0xFC40..0xFC7E */
+ 0x9EAB, 0x9EAC, 0x9EAD, 0x9EAE, 0x9EAF, 0x9EB0, 0x9EB1, 0x9EB2,
+ 0x9EB3, 0x9EB5, 0x9EB6, 0x9EB7, 0x9EB9, 0x9EBA, 0x9EBC, 0x9EBF,
+ 0x9EC0, 0x9EC1, 0x9EC2, 0x9EC3, 0x9EC5, 0x9EC6, 0x9EC7, 0x9EC8,
+ 0x9ECA, 0x9ECB, 0x9ECC, 0x9ED0, 0x9ED2, 0x9ED3, 0x9ED5, 0x9ED6,
+ 0x9ED7, 0x9ED9, 0x9EDA, 0x9EDE, 0x9EE1, 0x9EE3, 0x9EE4, 0x9EE6,
+ 0x9EE8, 0x9EEB, 0x9EEC, 0x9EED, 0x9EEE, 0x9EF0, 0x9EF1, 0x9EF2,
+ 0x9EF3, 0x9EF4, 0x9EF5, 0x9EF6, 0x9EF7, 0x9EF8, 0x9EFA, 0x9EFD,
+ 0x9EFF, 0x9F00, 0x9F01, 0x9F02, 0x9F03, 0x9F04, 0x9F05,
+ /* GB 0xFC80..0xFCA0 */
+ 0x9F06, 0x9F07, 0x9F08, 0x9F09, 0x9F0A, 0x9F0C, 0x9F0F, 0x9F11,
+ 0x9F12, 0x9F14, 0x9F15, 0x9F16, 0x9F18, 0x9F1A, 0x9F1B, 0x9F1C,
+ 0x9F1D, 0x9F1E, 0x9F1F, 0x9F21, 0x9F23, 0x9F24, 0x9F25, 0x9F26,
+ 0x9F27, 0x9F28, 0x9F29, 0x9F2A, 0x9F2B, 0x9F2D, 0x9F2E, 0x9F30,
+ 0x9F31, /* Skip: GB 0xFCA1..0xFCFE (UDA 2) */
+ /* GB 0xFD40..0xFD7E */
+ 0x9F32, 0x9F33, 0x9F34, 0x9F35, 0x9F36, 0x9F38, 0x9F3A, 0x9F3C,
+ 0x9F3F, 0x9F40, 0x9F41, 0x9F42, 0x9F43, 0x9F45, 0x9F46, 0x9F47,
+ 0x9F48, 0x9F49, 0x9F4A, 0x9F4B, 0x9F4C, 0x9F4D, 0x9F4E, 0x9F4F,
+ 0x9F52, 0x9F53, 0x9F54, 0x9F55, 0x9F56, 0x9F57, 0x9F58, 0x9F59,
+ 0x9F5A, 0x9F5B, 0x9F5C, 0x9F5D, 0x9F5E, 0x9F5F, 0x9F60, 0x9F61,
+ 0x9F62, 0x9F63, 0x9F64, 0x9F65, 0x9F66, 0x9F67, 0x9F68, 0x9F69,
+ 0x9F6A, 0x9F6B, 0x9F6C, 0x9F6D, 0x9F6E, 0x9F6F, 0x9F70, 0x9F71,
+ 0x9F72, 0x9F73, 0x9F74, 0x9F75, 0x9F76, 0x9F77, 0x9F78,
+ /* GB 0xFD80..0xFDA0 */
+ 0x9F79, 0x9F7A, 0x9F7B, 0x9F7C, 0x9F7D, 0x9F7E, 0x9F81, 0x9F82,
+ 0x9F8D, 0x9F8E, 0x9F8F, 0x9F90, 0x9F91, 0x9F92, 0x9F93, 0x9F94,
+ 0x9F95, 0x9F96, 0x9F97, 0x9F98, 0x9F9C, 0x9F9D, 0x9F9E, 0x9FA1,
+ 0x9FA2, 0x9FA3, 0x9FA4, 0x9FA5, 0xF92C, 0xF979, 0xF995, 0xF9E7,
+ 0xF9F1, /* Skip: GB 0xFDA1..0xFDFE (UDA 2) */
+ /* GB 0xFE40..0xFE7E */
+ 0xFA0C, 0xFA0D, 0xFA0E, 0xFA0F, 0xFA11, 0xFA13, 0xFA14, 0xFA18,
+ 0xFA1F, 0xFA20, 0xFA21, 0xFA23, 0xFA24, 0xFA27, 0xFA28, 0xFA29,
+ 0x2E81, 0xE816, 0xE817, 0xE818, 0x2E84, 0x3473, 0x3447, 0x2E88,
+ 0x2E8B, 0xE81E, 0x359E, 0x361A, 0x360E, 0x2E8C, 0x2E97, 0x396E,
+ 0x3918, 0xE826, 0x39CF, 0x39DF, 0x3A73, 0x39D0, 0xE82B, 0xE82C,
+ 0x3B4E, 0x3C6E, 0x3CE0, 0x2EA7, 0xE831, 0xE832, 0x2EAA, 0x4056,
+ 0x415F, 0x2EAE, 0x4337, 0x2EB3, 0x2EB6, 0x2EB7, 0xE83B, 0x43B1,
+ 0x43AC, 0x2EBB, 0x43DD, 0x44D6, 0x4661, 0x464C, 0xE843,
+ /* GB 0xFE80..0xFEA0 */
+ 0x4723, 0x4729, 0x477C, 0x478D, 0x2ECA, 0x4947, 0x497A, 0x497D,
+ 0x4982, 0x4983, 0x4985, 0x4986, 0x499F, 0x499B, 0x49B7, 0x49B6,
+ 0xE854, 0xE855, 0x4CA3, 0x4C9F, 0x4CA0, 0x4CA1, 0x4C77, 0x4CA2,
+ 0x4D13, 0x4D14, 0x4D15, 0x4D16, 0x4D17, 0x4D18, 0x4D19, 0x4DAE,
+ 0xE864, /* Skip: GB 0xFEA1..0xFEFE (UDA 2) */
+};
+
+static TQ_UINT16 const gb18030_4byte_to_ucs[6793] = {
+ /* Contiguous area: GB+81 30 81 30 .. GB+81 30 D2 39 */
+ /* GB+81 30 81 30 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084,
+ /* GB+81 30 81 35 */ 0x0085, 0x0086, 0x0087, 0x0088, 0x0089,
+ /* GB+81 30 82 30 */ 0x008A, 0x008B, 0x008C, 0x008D, 0x008E,
+ /* GB+81 30 82 35 */ 0x008F, 0x0090, 0x0091, 0x0092, 0x0093,
+ /* GB+81 30 83 30 */ 0x0094, 0x0095, 0x0096, 0x0097, 0x0098,
+ /* GB+81 30 83 35 */ 0x0099, 0x009A, 0x009B, 0x009C, 0x009D,
+ /* GB+81 30 84 30 */ 0x009E, 0x009F, 0x00A0, 0x00A1, 0x00A2,
+ /* GB+81 30 84 35 */ 0x00A3, 0x00A5, 0x00A6, 0x00A9, 0x00AA,
+ /* GB+81 30 85 30 */ 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ /* GB+81 30 85 35 */ 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6,
+ /* GB+81 30 86 30 */ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC,
+ /* GB+81 30 86 35 */ 0x00BD, 0x00BE, 0x00BF, 0x00C0, 0x00C1,
+ /* GB+81 30 87 30 */ 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6,
+ /* GB+81 30 87 35 */ 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB,
+ /* GB+81 30 88 30 */ 0x00CC, 0x00CD, 0x00CE, 0x00CF, 0x00D0,
+ /* GB+81 30 88 35 */ 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5,
+ /* GB+81 30 89 30 */ 0x00D6, 0x00D8, 0x00D9, 0x00DA, 0x00DB,
+ /* GB+81 30 89 35 */ 0x00DC, 0x00DD, 0x00DE, 0x00DF, 0x00E2,
+ /* GB+81 30 8A 30 */ 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ /* GB+81 30 8A 35 */ 0x00EB, 0x00EE, 0x00EF, 0x00F0, 0x00F1,
+ /* GB+81 30 8B 30 */ 0x00F4, 0x00F5, 0x00F6, 0x00F8, 0x00FB,
+ /* GB+81 30 8B 35 */ 0x00FD, 0x00FE, 0x00FF, 0x0100, 0x0102,
+ /* GB+81 30 8C 30 */ 0x0103, 0x0104, 0x0105, 0x0106, 0x0107,
+ /* GB+81 30 8C 35 */ 0x0108, 0x0109, 0x010A, 0x010B, 0x010C,
+ /* GB+81 30 8D 30 */ 0x010D, 0x010E, 0x010F, 0x0110, 0x0111,
+ /* GB+81 30 8D 35 */ 0x0112, 0x0114, 0x0115, 0x0116, 0x0117,
+ /* GB+81 30 8E 30 */ 0x0118, 0x0119, 0x011A, 0x011C, 0x011D,
+ /* GB+81 30 8E 35 */ 0x011E, 0x011F, 0x0120, 0x0121, 0x0122,
+ /* GB+81 30 8F 30 */ 0x0123, 0x0124, 0x0125, 0x0126, 0x0127,
+ /* GB+81 30 8F 35 */ 0x0128, 0x0129, 0x012A, 0x012C, 0x012D,
+ /* GB+81 30 90 30 */ 0x012E, 0x012F, 0x0130, 0x0131, 0x0132,
+ /* GB+81 30 90 35 */ 0x0133, 0x0134, 0x0135, 0x0136, 0x0137,
+ /* GB+81 30 91 30 */ 0x0138, 0x0139, 0x013A, 0x013B, 0x013C,
+ /* GB+81 30 91 35 */ 0x013D, 0x013E, 0x013F, 0x0140, 0x0141,
+ /* GB+81 30 92 30 */ 0x0142, 0x0143, 0x0145, 0x0146, 0x0147,
+ /* GB+81 30 92 35 */ 0x0149, 0x014A, 0x014B, 0x014C, 0x014E,
+ /* GB+81 30 93 30 */ 0x014F, 0x0150, 0x0151, 0x0152, 0x0153,
+ /* GB+81 30 93 35 */ 0x0154, 0x0155, 0x0156, 0x0157, 0x0158,
+ /* GB+81 30 94 30 */ 0x0159, 0x015A, 0x015B, 0x015C, 0x015D,
+ /* GB+81 30 94 35 */ 0x015E, 0x015F, 0x0160, 0x0161, 0x0162,
+ /* GB+81 30 95 30 */ 0x0163, 0x0164, 0x0165, 0x0166, 0x0167,
+ /* GB+81 30 95 35 */ 0x0168, 0x0169, 0x016A, 0x016C, 0x016D,
+ /* GB+81 30 96 30 */ 0x016E, 0x016F, 0x0170, 0x0171, 0x0172,
+ /* GB+81 30 96 35 */ 0x0173, 0x0174, 0x0175, 0x0176, 0x0177,
+ /* GB+81 30 97 30 */ 0x0178, 0x0179, 0x017A, 0x017B, 0x017C,
+ /* GB+81 30 97 35 */ 0x017D, 0x017E, 0x017F, 0x0180, 0x0181,
+ /* GB+81 30 98 30 */ 0x0182, 0x0183, 0x0184, 0x0185, 0x0186,
+ /* GB+81 30 98 35 */ 0x0187, 0x0188, 0x0189, 0x018A, 0x018B,
+ /* GB+81 30 99 30 */ 0x018C, 0x018D, 0x018E, 0x018F, 0x0190,
+ /* GB+81 30 99 35 */ 0x0191, 0x0192, 0x0193, 0x0194, 0x0195,
+ /* GB+81 30 9A 30 */ 0x0196, 0x0197, 0x0198, 0x0199, 0x019A,
+ /* GB+81 30 9A 35 */ 0x019B, 0x019C, 0x019D, 0x019E, 0x019F,
+ /* GB+81 30 9B 30 */ 0x01A0, 0x01A1, 0x01A2, 0x01A3, 0x01A4,
+ /* GB+81 30 9B 35 */ 0x01A5, 0x01A6, 0x01A7, 0x01A8, 0x01A9,
+ /* GB+81 30 9C 30 */ 0x01AA, 0x01AB, 0x01AC, 0x01AD, 0x01AE,
+ /* GB+81 30 9C 35 */ 0x01AF, 0x01B0, 0x01B1, 0x01B2, 0x01B3,
+ /* GB+81 30 9D 30 */ 0x01B4, 0x01B5, 0x01B6, 0x01B7, 0x01B8,
+ /* GB+81 30 9D 35 */ 0x01B9, 0x01BA, 0x01BB, 0x01BC, 0x01BD,
+ /* GB+81 30 9E 30 */ 0x01BE, 0x01BF, 0x01C0, 0x01C1, 0x01C2,
+ /* GB+81 30 9E 35 */ 0x01C3, 0x01C4, 0x01C5, 0x01C6, 0x01C7,
+ /* GB+81 30 9F 30 */ 0x01C8, 0x01C9, 0x01CA, 0x01CB, 0x01CC,
+ /* GB+81 30 9F 35 */ 0x01CD, 0x01CF, 0x01D1, 0x01D3, 0x01D5,
+ /* GB+81 30 A0 30 */ 0x01D7, 0x01D9, 0x01DB, 0x01DD, 0x01DE,
+ /* GB+81 30 A0 35 */ 0x01DF, 0x01E0, 0x01E1, 0x01E2, 0x01E3,
+ /* GB+81 30 A1 30 */ 0x01E4, 0x01E5, 0x01E6, 0x01E7, 0x01E8,
+ /* GB+81 30 A1 35 */ 0x01E9, 0x01EA, 0x01EB, 0x01EC, 0x01ED,
+ /* GB+81 30 A2 30 */ 0x01EE, 0x01EF, 0x01F0, 0x01F1, 0x01F2,
+ /* GB+81 30 A2 35 */ 0x01F3, 0x01F4, 0x01F5, 0x01F6, 0x01F7,
+ /* GB+81 30 A3 30 */ 0x01F8, 0x01FA, 0x01FB, 0x01FC, 0x01FD,
+ /* GB+81 30 A3 35 */ 0x01FE, 0x01FF, 0x0200, 0x0201, 0x0202,
+ /* GB+81 30 A4 30 */ 0x0203, 0x0204, 0x0205, 0x0206, 0x0207,
+ /* GB+81 30 A4 35 */ 0x0208, 0x0209, 0x020A, 0x020B, 0x020C,
+ /* GB+81 30 A5 30 */ 0x020D, 0x020E, 0x020F, 0x0210, 0x0211,
+ /* GB+81 30 A5 35 */ 0x0212, 0x0213, 0x0214, 0x0215, 0x0216,
+ /* GB+81 30 A6 30 */ 0x0217, 0x0218, 0x0219, 0x021A, 0x021B,
+ /* GB+81 30 A6 35 */ 0x021C, 0x021D, 0x021E, 0x021F, 0x0220,
+ /* GB+81 30 A7 30 */ 0x0221, 0x0222, 0x0223, 0x0224, 0x0225,
+ /* GB+81 30 A7 35 */ 0x0226, 0x0227, 0x0228, 0x0229, 0x022A,
+ /* GB+81 30 A8 30 */ 0x022B, 0x022C, 0x022D, 0x022E, 0x022F,
+ /* GB+81 30 A8 35 */ 0x0230, 0x0231, 0x0232, 0x0233, 0x0234,
+ /* GB+81 30 A9 30 */ 0x0235, 0x0236, 0x0237, 0x0238, 0x0239,
+ /* GB+81 30 A9 35 */ 0x023A, 0x023B, 0x023C, 0x023D, 0x023E,
+ /* GB+81 30 AA 30 */ 0x023F, 0x0240, 0x0241, 0x0242, 0x0243,
+ /* GB+81 30 AA 35 */ 0x0244, 0x0245, 0x0246, 0x0247, 0x0248,
+ /* GB+81 30 AB 30 */ 0x0249, 0x024A, 0x024B, 0x024C, 0x024D,
+ /* GB+81 30 AB 35 */ 0x024E, 0x024F, 0x0250, 0x0252, 0x0253,
+ /* GB+81 30 AC 30 */ 0x0254, 0x0255, 0x0256, 0x0257, 0x0258,
+ /* GB+81 30 AC 35 */ 0x0259, 0x025A, 0x025B, 0x025C, 0x025D,
+ /* GB+81 30 AD 30 */ 0x025E, 0x025F, 0x0260, 0x0262, 0x0263,
+ /* GB+81 30 AD 35 */ 0x0264, 0x0265, 0x0266, 0x0267, 0x0268,
+ /* GB+81 30 AE 30 */ 0x0269, 0x026A, 0x026B, 0x026C, 0x026D,
+ /* GB+81 30 AE 35 */ 0x026E, 0x026F, 0x0270, 0x0271, 0x0272,
+ /* GB+81 30 AF 30 */ 0x0273, 0x0274, 0x0275, 0x0276, 0x0277,
+ /* GB+81 30 AF 35 */ 0x0278, 0x0279, 0x027A, 0x027B, 0x027C,
+ /* GB+81 30 B0 30 */ 0x027D, 0x027E, 0x027F, 0x0280, 0x0281,
+ /* GB+81 30 B0 35 */ 0x0282, 0x0283, 0x0284, 0x0285, 0x0286,
+ /* GB+81 30 B1 30 */ 0x0287, 0x0288, 0x0289, 0x028A, 0x028B,
+ /* GB+81 30 B1 35 */ 0x028C, 0x028D, 0x028E, 0x028F, 0x0290,
+ /* GB+81 30 B2 30 */ 0x0291, 0x0292, 0x0293, 0x0294, 0x0295,
+ /* GB+81 30 B2 35 */ 0x0296, 0x0297, 0x0298, 0x0299, 0x029A,
+ /* GB+81 30 B3 30 */ 0x029B, 0x029C, 0x029D, 0x029E, 0x029F,
+ /* GB+81 30 B3 35 */ 0x02A0, 0x02A1, 0x02A2, 0x02A3, 0x02A4,
+ /* GB+81 30 B4 30 */ 0x02A5, 0x02A6, 0x02A7, 0x02A8, 0x02A9,
+ /* GB+81 30 B4 35 */ 0x02AA, 0x02AB, 0x02AC, 0x02AD, 0x02AE,
+ /* GB+81 30 B5 30 */ 0x02AF, 0x02B0, 0x02B1, 0x02B2, 0x02B3,
+ /* GB+81 30 B5 35 */ 0x02B4, 0x02B5, 0x02B6, 0x02B7, 0x02B8,
+ /* GB+81 30 B6 30 */ 0x02B9, 0x02BA, 0x02BB, 0x02BC, 0x02BD,
+ /* GB+81 30 B6 35 */ 0x02BE, 0x02BF, 0x02C0, 0x02C1, 0x02C2,
+ /* GB+81 30 B7 30 */ 0x02C3, 0x02C4, 0x02C5, 0x02C6, 0x02C8,
+ /* GB+81 30 B7 35 */ 0x02CC, 0x02CD, 0x02CE, 0x02CF, 0x02D0,
+ /* GB+81 30 B8 30 */ 0x02D1, 0x02D2, 0x02D3, 0x02D4, 0x02D5,
+ /* GB+81 30 B8 35 */ 0x02D6, 0x02D7, 0x02D8, 0x02DA, 0x02DB,
+ /* GB+81 30 B9 30 */ 0x02DC, 0x02DD, 0x02DE, 0x02DF, 0x02E0,
+ /* GB+81 30 B9 35 */ 0x02E1, 0x02E2, 0x02E3, 0x02E4, 0x02E5,
+ /* GB+81 30 BA 30 */ 0x02E6, 0x02E7, 0x02E8, 0x02E9, 0x02EA,
+ /* GB+81 30 BA 35 */ 0x02EB, 0x02EC, 0x02ED, 0x02EE, 0x02EF,
+ /* GB+81 30 BB 30 */ 0x02F0, 0x02F1, 0x02F2, 0x02F3, 0x02F4,
+ /* GB+81 30 BB 35 */ 0x02F5, 0x02F6, 0x02F7, 0x02F8, 0x02F9,
+ /* GB+81 30 BC 30 */ 0x02FA, 0x02FB, 0x02FC, 0x02FD, 0x02FE,
+ /* GB+81 30 BC 35 */ 0x02FF, 0x0300, 0x0301, 0x0302, 0x0303,
+ /* GB+81 30 BD 30 */ 0x0304, 0x0305, 0x0306, 0x0307, 0x0308,
+ /* GB+81 30 BD 35 */ 0x0309, 0x030A, 0x030B, 0x030C, 0x030D,
+ /* GB+81 30 BE 30 */ 0x030E, 0x030F, 0x0310, 0x0311, 0x0312,
+ /* GB+81 30 BE 35 */ 0x0313, 0x0314, 0x0315, 0x0316, 0x0317,
+ /* GB+81 30 BF 30 */ 0x0318, 0x0319, 0x031A, 0x031B, 0x031C,
+ /* GB+81 30 BF 35 */ 0x031D, 0x031E, 0x031F, 0x0320, 0x0321,
+ /* GB+81 30 C0 30 */ 0x0322, 0x0323, 0x0324, 0x0325, 0x0326,
+ /* GB+81 30 C0 35 */ 0x0327, 0x0328, 0x0329, 0x032A, 0x032B,
+ /* GB+81 30 C1 30 */ 0x032C, 0x032D, 0x032E, 0x032F, 0x0330,
+ /* GB+81 30 C1 35 */ 0x0331, 0x0332, 0x0333, 0x0334, 0x0335,
+ /* GB+81 30 C2 30 */ 0x0336, 0x0337, 0x0338, 0x0339, 0x033A,
+ /* GB+81 30 C2 35 */ 0x033B, 0x033C, 0x033D, 0x033E, 0x033F,
+ /* GB+81 30 C3 30 */ 0x0340, 0x0341, 0x0342, 0x0343, 0x0344,
+ /* GB+81 30 C3 35 */ 0x0345, 0x0346, 0x0347, 0x0348, 0x0349,
+ /* GB+81 30 C4 30 */ 0x034A, 0x034B, 0x034C, 0x034D, 0x034E,
+ /* GB+81 30 C4 35 */ 0x034F, 0x0350, 0x0351, 0x0352, 0x0353,
+ /* GB+81 30 C5 30 */ 0x0354, 0x0355, 0x0356, 0x0357, 0x0358,
+ /* GB+81 30 C5 35 */ 0x0359, 0x035A, 0x035B, 0x035C, 0x035D,
+ /* GB+81 30 C6 30 */ 0x035E, 0x035F, 0x0360, 0x0361, 0x0362,
+ /* GB+81 30 C6 35 */ 0x0363, 0x0364, 0x0365, 0x0366, 0x0367,
+ /* GB+81 30 C7 30 */ 0x0368, 0x0369, 0x036A, 0x036B, 0x036C,
+ /* GB+81 30 C7 35 */ 0x036D, 0x036E, 0x036F, 0x0370, 0x0371,
+ /* GB+81 30 C8 30 */ 0x0372, 0x0373, 0x0374, 0x0375, 0x0376,
+ /* GB+81 30 C8 35 */ 0x0377, 0x0378, 0x0379, 0x037A, 0x037B,
+ /* GB+81 30 C9 30 */ 0x037C, 0x037D, 0x037E, 0x037F, 0x0380,
+ /* GB+81 30 C9 35 */ 0x0381, 0x0382, 0x0383, 0x0384, 0x0385,
+ /* GB+81 30 CA 30 */ 0x0386, 0x0387, 0x0388, 0x0389, 0x038A,
+ /* GB+81 30 CA 35 */ 0x038B, 0x038C, 0x038D, 0x038E, 0x038F,
+ /* GB+81 30 CB 30 */ 0x0390, 0x03A2, 0x03AA, 0x03AB, 0x03AC,
+ /* GB+81 30 CB 35 */ 0x03AD, 0x03AE, 0x03AF, 0x03B0, 0x03C2,
+ /* GB+81 30 CC 30 */ 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE,
+ /* GB+81 30 CC 35 */ 0x03CF, 0x03D0, 0x03D1, 0x03D2, 0x03D3,
+ /* GB+81 30 CD 30 */ 0x03D4, 0x03D5, 0x03D6, 0x03D7, 0x03D8,
+ /* GB+81 30 CD 35 */ 0x03D9, 0x03DA, 0x03DB, 0x03DC, 0x03DD,
+ /* GB+81 30 CE 30 */ 0x03DE, 0x03DF, 0x03E0, 0x03E1, 0x03E2,
+ /* GB+81 30 CE 35 */ 0x03E3, 0x03E4, 0x03E5, 0x03E6, 0x03E7,
+ /* GB+81 30 CF 30 */ 0x03E8, 0x03E9, 0x03EA, 0x03EB, 0x03EC,
+ /* GB+81 30 CF 35 */ 0x03ED, 0x03EE, 0x03EF, 0x03F0, 0x03F1,
+ /* GB+81 30 D0 30 */ 0x03F2, 0x03F3, 0x03F4, 0x03F5, 0x03F6,
+ /* GB+81 30 D0 35 */ 0x03F7, 0x03F8, 0x03F9, 0x03FA, 0x03FB,
+ /* GB+81 30 D1 30 */ 0x03FC, 0x03FD, 0x03FE, 0x03FF, 0x0400,
+ /* GB+81 30 D1 35 */ 0x0402, 0x0403, 0x0404, 0x0405, 0x0406,
+ /* GB+81 30 D2 30 */ 0x0407, 0x0408, 0x0409, 0x040A, 0x040B,
+ /* GB+81 30 D2 35 */ 0x040C, 0x040D, 0x040E, 0x040F, 0x0450,
+ /* Contiguous area: GB+81 36 A5 32 .. GB+81 37 A8 38 */
+ /* GB+81 36 A5 32 */ 0x2011, 0x2012, 0x2017,
+ /* GB+81 36 A5 35 */ 0x201A, 0x201B, 0x201E, 0x201F, 0x2020,
+ /* GB+81 36 A6 30 */ 0x2021, 0x2022, 0x2023, 0x2024, 0x2027,
+ /* GB+81 36 A6 35 */ 0x2028, 0x2029, 0x202A, 0x202B, 0x202C,
+ /* GB+81 36 A7 30 */ 0x202D, 0x202E, 0x202F, 0x2031, 0x2034,
+ /* GB+81 36 A7 35 */ 0x2036, 0x2037, 0x2038, 0x2039, 0x203A,
+ /* GB+81 36 A8 30 */ 0x203C, 0x203D, 0x203E, 0x203F, 0x2040,
+ /* GB+81 36 A8 35 */ 0x2041, 0x2042, 0x2043, 0x2044, 0x2045,
+ /* GB+81 36 A9 30 */ 0x2046, 0x2047, 0x2048, 0x2049, 0x204A,
+ /* GB+81 36 A9 35 */ 0x204B, 0x204C, 0x204D, 0x204E, 0x204F,
+ /* GB+81 36 AA 30 */ 0x2050, 0x2051, 0x2052, 0x2053, 0x2054,
+ /* GB+81 36 AA 35 */ 0x2055, 0x2056, 0x2057, 0x2058, 0x2059,
+ /* GB+81 36 AB 30 */ 0x205A, 0x205B, 0x205C, 0x205D, 0x205E,
+ /* GB+81 36 AB 35 */ 0x205F, 0x2060, 0x2061, 0x2062, 0x2063,
+ /* GB+81 36 AC 30 */ 0x2064, 0x2065, 0x2066, 0x2067, 0x2068,
+ /* GB+81 36 AC 35 */ 0x2069, 0x206A, 0x206B, 0x206C, 0x206D,
+ /* GB+81 36 AD 30 */ 0x206E, 0x206F, 0x2070, 0x2071, 0x2072,
+ /* GB+81 36 AD 35 */ 0x2073, 0x2074, 0x2075, 0x2076, 0x2077,
+ /* GB+81 36 AE 30 */ 0x2078, 0x2079, 0x207A, 0x207B, 0x207C,
+ /* GB+81 36 AE 35 */ 0x207D, 0x207E, 0x207F, 0x2080, 0x2081,
+ /* GB+81 36 AF 30 */ 0x2082, 0x2083, 0x2084, 0x2085, 0x2086,
+ /* GB+81 36 AF 35 */ 0x2087, 0x2088, 0x2089, 0x208A, 0x208B,
+ /* GB+81 36 B0 30 */ 0x208C, 0x208D, 0x208E, 0x208F, 0x2090,
+ /* GB+81 36 B0 35 */ 0x2091, 0x2092, 0x2093, 0x2094, 0x2095,
+ /* GB+81 36 B1 30 */ 0x2096, 0x2097, 0x2098, 0x2099, 0x209A,
+ /* GB+81 36 B1 35 */ 0x209B, 0x209C, 0x209D, 0x209E, 0x209F,
+ /* GB+81 36 B2 30 */ 0x20A0, 0x20A1, 0x20A2, 0x20A3, 0x20A4,
+ /* GB+81 36 B2 35 */ 0x20A5, 0x20A6, 0x20A7, 0x20A8, 0x20A9,
+ /* GB+81 36 B3 30 */ 0x20AA, 0x20AB, 0x20AD, 0x20AE, 0x20AF,
+ /* GB+81 36 B3 35 */ 0x20B0, 0x20B1, 0x20B2, 0x20B3, 0x20B4,
+ /* GB+81 36 B4 30 */ 0x20B5, 0x20B6, 0x20B7, 0x20B8, 0x20B9,
+ /* GB+81 36 B4 35 */ 0x20BA, 0x20BB, 0x20BC, 0x20BD, 0x20BE,
+ /* GB+81 36 B5 30 */ 0x20BF, 0x20C0, 0x20C1, 0x20C2, 0x20C3,
+ /* GB+81 36 B5 35 */ 0x20C4, 0x20C5, 0x20C6, 0x20C7, 0x20C8,
+ /* GB+81 36 B6 30 */ 0x20C9, 0x20CA, 0x20CB, 0x20CC, 0x20CD,
+ /* GB+81 36 B6 35 */ 0x20CE, 0x20CF, 0x20D0, 0x20D1, 0x20D2,
+ /* GB+81 36 B7 30 */ 0x20D3, 0x20D4, 0x20D5, 0x20D6, 0x20D7,
+ /* GB+81 36 B7 35 */ 0x20D8, 0x20D9, 0x20DA, 0x20DB, 0x20DC,
+ /* GB+81 36 B8 30 */ 0x20DD, 0x20DE, 0x20DF, 0x20E0, 0x20E1,
+ /* GB+81 36 B8 35 */ 0x20E2, 0x20E3, 0x20E4, 0x20E5, 0x20E6,
+ /* GB+81 36 B9 30 */ 0x20E7, 0x20E8, 0x20E9, 0x20EA, 0x20EB,
+ /* GB+81 36 B9 35 */ 0x20EC, 0x20ED, 0x20EE, 0x20EF, 0x20F0,
+ /* GB+81 36 BA 30 */ 0x20F1, 0x20F2, 0x20F3, 0x20F4, 0x20F5,
+ /* GB+81 36 BA 35 */ 0x20F6, 0x20F7, 0x20F8, 0x20F9, 0x20FA,
+ /* GB+81 36 BB 30 */ 0x20FB, 0x20FC, 0x20FD, 0x20FE, 0x20FF,
+ /* GB+81 36 BB 35 */ 0x2100, 0x2101, 0x2102, 0x2104, 0x2106,
+ /* GB+81 36 BC 30 */ 0x2107, 0x2108, 0x210A, 0x210B, 0x210C,
+ /* GB+81 36 BC 35 */ 0x210D, 0x210E, 0x210F, 0x2110, 0x2111,
+ /* GB+81 36 BD 30 */ 0x2112, 0x2113, 0x2114, 0x2115, 0x2117,
+ /* GB+81 36 BD 35 */ 0x2118, 0x2119, 0x211A, 0x211B, 0x211C,
+ /* GB+81 36 BE 30 */ 0x211D, 0x211E, 0x211F, 0x2120, 0x2122,
+ /* GB+81 36 BE 35 */ 0x2123, 0x2124, 0x2125, 0x2126, 0x2127,
+ /* GB+81 36 BF 30 */ 0x2128, 0x2129, 0x212A, 0x212B, 0x212C,
+ /* GB+81 36 BF 35 */ 0x212D, 0x212E, 0x212F, 0x2130, 0x2131,
+ /* GB+81 36 C0 30 */ 0x2132, 0x2133, 0x2134, 0x2135, 0x2136,
+ /* GB+81 36 C0 35 */ 0x2137, 0x2138, 0x2139, 0x213A, 0x213B,
+ /* GB+81 36 C1 30 */ 0x213C, 0x213D, 0x213E, 0x213F, 0x2140,
+ /* GB+81 36 C1 35 */ 0x2141, 0x2142, 0x2143, 0x2144, 0x2145,
+ /* GB+81 36 C2 30 */ 0x2146, 0x2147, 0x2148, 0x2149, 0x214A,
+ /* GB+81 36 C2 35 */ 0x214B, 0x214C, 0x214D, 0x214E, 0x214F,
+ /* GB+81 36 C3 30 */ 0x2150, 0x2151, 0x2152, 0x2153, 0x2154,
+ /* GB+81 36 C3 35 */ 0x2155, 0x2156, 0x2157, 0x2158, 0x2159,
+ /* GB+81 36 C4 30 */ 0x215A, 0x215B, 0x215C, 0x215D, 0x215E,
+ /* GB+81 36 C4 35 */ 0x215F, 0x216C, 0x216D, 0x216E, 0x216F,
+ /* GB+81 36 C5 30 */ 0x217A, 0x217B, 0x217C, 0x217D, 0x217E,
+ /* GB+81 36 C5 35 */ 0x217F, 0x2180, 0x2181, 0x2182, 0x2183,
+ /* GB+81 36 C6 30 */ 0x2184, 0x2185, 0x2186, 0x2187, 0x2188,
+ /* GB+81 36 C6 35 */ 0x2189, 0x218A, 0x218B, 0x218C, 0x218D,
+ /* GB+81 36 C7 30 */ 0x218E, 0x218F, 0x2194, 0x2195, 0x219A,
+ /* GB+81 36 C7 35 */ 0x219B, 0x219C, 0x219D, 0x219E, 0x219F,
+ /* GB+81 36 C8 30 */ 0x21A0, 0x21A1, 0x21A2, 0x21A3, 0x21A4,
+ /* GB+81 36 C8 35 */ 0x21A5, 0x21A6, 0x21A7, 0x21A8, 0x21A9,
+ /* GB+81 36 C9 30 */ 0x21AA, 0x21AB, 0x21AC, 0x21AD, 0x21AE,
+ /* GB+81 36 C9 35 */ 0x21AF, 0x21B0, 0x21B1, 0x21B2, 0x21B3,
+ /* GB+81 36 CA 30 */ 0x21B4, 0x21B5, 0x21B6, 0x21B7, 0x21B8,
+ /* GB+81 36 CA 35 */ 0x21B9, 0x21BA, 0x21BB, 0x21BC, 0x21BD,
+ /* GB+81 36 CB 30 */ 0x21BE, 0x21BF, 0x21C0, 0x21C1, 0x21C2,
+ /* GB+81 36 CB 35 */ 0x21C3, 0x21C4, 0x21C5, 0x21C6, 0x21C7,
+ /* GB+81 36 CC 30 */ 0x21C8, 0x21C9, 0x21CA, 0x21CB, 0x21CC,
+ /* GB+81 36 CC 35 */ 0x21CD, 0x21CE, 0x21CF, 0x21D0, 0x21D1,
+ /* GB+81 36 CD 30 */ 0x21D2, 0x21D3, 0x21D4, 0x21D5, 0x21D6,
+ /* GB+81 36 CD 35 */ 0x21D7, 0x21D8, 0x21D9, 0x21DA, 0x21DB,
+ /* GB+81 36 CE 30 */ 0x21DC, 0x21DD, 0x21DE, 0x21DF, 0x21E0,
+ /* GB+81 36 CE 35 */ 0x21E1, 0x21E2, 0x21E3, 0x21E4, 0x21E5,
+ /* GB+81 36 CF 30 */ 0x21E6, 0x21E7, 0x21E8, 0x21E9, 0x21EA,
+ /* GB+81 36 CF 35 */ 0x21EB, 0x21EC, 0x21ED, 0x21EE, 0x21EF,
+ /* GB+81 36 D0 30 */ 0x21F0, 0x21F1, 0x21F2, 0x21F3, 0x21F4,
+ /* GB+81 36 D0 35 */ 0x21F5, 0x21F6, 0x21F7, 0x21F8, 0x21F9,
+ /* GB+81 36 D1 30 */ 0x21FA, 0x21FB, 0x21FC, 0x21FD, 0x21FE,
+ /* GB+81 36 D1 35 */ 0x21FF, 0x2200, 0x2201, 0x2202, 0x2203,
+ /* GB+81 36 D2 30 */ 0x2204, 0x2205, 0x2206, 0x2207, 0x2209,
+ /* GB+81 36 D2 35 */ 0x220A, 0x220B, 0x220C, 0x220D, 0x220E,
+ /* GB+81 36 D3 30 */ 0x2210, 0x2212, 0x2213, 0x2214, 0x2216,
+ /* GB+81 36 D3 35 */ 0x2217, 0x2218, 0x2219, 0x221B, 0x221C,
+ /* GB+81 36 D4 30 */ 0x2221, 0x2222, 0x2224, 0x2226, 0x222C,
+ /* GB+81 36 D4 35 */ 0x222D, 0x222F, 0x2230, 0x2231, 0x2232,
+ /* GB+81 36 D5 30 */ 0x2233, 0x2238, 0x2239, 0x223A, 0x223B,
+ /* GB+81 36 D5 35 */ 0x223C, 0x223E, 0x223F, 0x2240, 0x2241,
+ /* GB+81 36 D6 30 */ 0x2242, 0x2243, 0x2244, 0x2245, 0x2246,
+ /* GB+81 36 D6 35 */ 0x2247, 0x2249, 0x224A, 0x224B, 0x224D,
+ /* GB+81 36 D7 30 */ 0x224E, 0x224F, 0x2250, 0x2251, 0x2253,
+ /* GB+81 36 D7 35 */ 0x2254, 0x2255, 0x2256, 0x2257, 0x2258,
+ /* GB+81 36 D8 30 */ 0x2259, 0x225A, 0x225B, 0x225C, 0x225D,
+ /* GB+81 36 D8 35 */ 0x225E, 0x225F, 0x2262, 0x2263, 0x2268,
+ /* GB+81 36 D9 30 */ 0x2269, 0x226A, 0x226B, 0x226C, 0x226D,
+ /* GB+81 36 D9 35 */ 0x2270, 0x2271, 0x2272, 0x2273, 0x2274,
+ /* GB+81 36 DA 30 */ 0x2275, 0x2276, 0x2277, 0x2278, 0x2279,
+ /* GB+81 36 DA 35 */ 0x227A, 0x227B, 0x227C, 0x227D, 0x227E,
+ /* GB+81 36 DB 30 */ 0x227F, 0x2280, 0x2281, 0x2282, 0x2283,
+ /* GB+81 36 DB 35 */ 0x2284, 0x2285, 0x2286, 0x2287, 0x2288,
+ /* GB+81 36 DC 30 */ 0x2289, 0x228A, 0x228B, 0x228C, 0x228D,
+ /* GB+81 36 DC 35 */ 0x228E, 0x228F, 0x2290, 0x2291, 0x2292,
+ /* GB+81 36 DD 30 */ 0x2293, 0x2294, 0x2296, 0x2297, 0x2298,
+ /* GB+81 36 DD 35 */ 0x229A, 0x229B, 0x229C, 0x229D, 0x229E,
+ /* GB+81 36 DE 30 */ 0x229F, 0x22A0, 0x22A1, 0x22A2, 0x22A3,
+ /* GB+81 36 DE 35 */ 0x22A4, 0x22A6, 0x22A7, 0x22A8, 0x22A9,
+ /* GB+81 36 DF 30 */ 0x22AA, 0x22AB, 0x22AC, 0x22AD, 0x22AE,
+ /* GB+81 36 DF 35 */ 0x22AF, 0x22B0, 0x22B1, 0x22B2, 0x22B3,
+ /* GB+81 36 E0 30 */ 0x22B4, 0x22B5, 0x22B6, 0x22B7, 0x22B8,
+ /* GB+81 36 E0 35 */ 0x22B9, 0x22BA, 0x22BB, 0x22BC, 0x22BD,
+ /* GB+81 36 E1 30 */ 0x22BE, 0x22C0, 0x22C1, 0x22C2, 0x22C3,
+ /* GB+81 36 E1 35 */ 0x22C4, 0x22C5, 0x22C6, 0x22C7, 0x22C8,
+ /* GB+81 36 E2 30 */ 0x22C9, 0x22CA, 0x22CB, 0x22CC, 0x22CD,
+ /* GB+81 36 E2 35 */ 0x22CE, 0x22CF, 0x22D0, 0x22D1, 0x22D2,
+ /* GB+81 36 E3 30 */ 0x22D3, 0x22D4, 0x22D5, 0x22D6, 0x22D7,
+ /* GB+81 36 E3 35 */ 0x22D8, 0x22D9, 0x22DA, 0x22DB, 0x22DC,
+ /* GB+81 36 E4 30 */ 0x22DD, 0x22DE, 0x22DF, 0x22E0, 0x22E1,
+ /* GB+81 36 E4 35 */ 0x22E2, 0x22E3, 0x22E4, 0x22E5, 0x22E6,
+ /* GB+81 36 E5 30 */ 0x22E7, 0x22E8, 0x22E9, 0x22EA, 0x22EB,
+ /* GB+81 36 E5 35 */ 0x22EC, 0x22ED, 0x22EE, 0x22EF, 0x22F0,
+ /* GB+81 36 E6 30 */ 0x22F1, 0x22F2, 0x22F3, 0x22F4, 0x22F5,
+ /* GB+81 36 E6 35 */ 0x22F6, 0x22F7, 0x22F8, 0x22F9, 0x22FA,
+ /* GB+81 36 E7 30 */ 0x22FB, 0x22FC, 0x22FD, 0x22FE, 0x22FF,
+ /* GB+81 36 E7 35 */ 0x2300, 0x2301, 0x2302, 0x2303, 0x2304,
+ /* GB+81 36 E8 30 */ 0x2305, 0x2306, 0x2307, 0x2308, 0x2309,
+ /* GB+81 36 E8 35 */ 0x230A, 0x230B, 0x230C, 0x230D, 0x230E,
+ /* GB+81 36 E9 30 */ 0x230F, 0x2310, 0x2311, 0x2313, 0x2314,
+ /* GB+81 36 E9 35 */ 0x2315, 0x2316, 0x2317, 0x2318, 0x2319,
+ /* GB+81 36 EA 30 */ 0x231A, 0x231B, 0x231C, 0x231D, 0x231E,
+ /* GB+81 36 EA 35 */ 0x231F, 0x2320, 0x2321, 0x2322, 0x2323,
+ /* GB+81 36 EB 30 */ 0x2324, 0x2325, 0x2326, 0x2327, 0x2328,
+ /* GB+81 36 EB 35 */ 0x2329, 0x232A, 0x232B, 0x232C, 0x232D,
+ /* GB+81 36 EC 30 */ 0x232E, 0x232F, 0x2330, 0x2331, 0x2332,
+ /* GB+81 36 EC 35 */ 0x2333, 0x2334, 0x2335, 0x2336, 0x2337,
+ /* GB+81 36 ED 30 */ 0x2338, 0x2339, 0x233A, 0x233B, 0x233C,
+ /* GB+81 36 ED 35 */ 0x233D, 0x233E, 0x233F, 0x2340, 0x2341,
+ /* GB+81 36 EE 30 */ 0x2342, 0x2343, 0x2344, 0x2345, 0x2346,
+ /* GB+81 36 EE 35 */ 0x2347, 0x2348, 0x2349, 0x234A, 0x234B,
+ /* GB+81 36 EF 30 */ 0x234C, 0x234D, 0x234E, 0x234F, 0x2350,
+ /* GB+81 36 EF 35 */ 0x2351, 0x2352, 0x2353, 0x2354, 0x2355,
+ /* GB+81 36 F0 30 */ 0x2356, 0x2357, 0x2358, 0x2359, 0x235A,
+ /* GB+81 36 F0 35 */ 0x235B, 0x235C, 0x235D, 0x235E, 0x235F,
+ /* GB+81 36 F1 30 */ 0x2360, 0x2361, 0x2362, 0x2363, 0x2364,
+ /* GB+81 36 F1 35 */ 0x2365, 0x2366, 0x2367, 0x2368, 0x2369,
+ /* GB+81 36 F2 30 */ 0x236A, 0x236B, 0x236C, 0x236D, 0x236E,
+ /* GB+81 36 F2 35 */ 0x236F, 0x2370, 0x2371, 0x2372, 0x2373,
+ /* GB+81 36 F3 30 */ 0x2374, 0x2375, 0x2376, 0x2377, 0x2378,
+ /* GB+81 36 F3 35 */ 0x2379, 0x237A, 0x237B, 0x237C, 0x237D,
+ /* GB+81 36 F4 30 */ 0x237E, 0x237F, 0x2380, 0x2381, 0x2382,
+ /* GB+81 36 F4 35 */ 0x2383, 0x2384, 0x2385, 0x2386, 0x2387,
+ /* GB+81 36 F5 30 */ 0x2388, 0x2389, 0x238A, 0x238B, 0x238C,
+ /* GB+81 36 F5 35 */ 0x238D, 0x238E, 0x238F, 0x2390, 0x2391,
+ /* GB+81 36 F6 30 */ 0x2392, 0x2393, 0x2394, 0x2395, 0x2396,
+ /* GB+81 36 F6 35 */ 0x2397, 0x2398, 0x2399, 0x239A, 0x239B,
+ /* GB+81 36 F7 30 */ 0x239C, 0x239D, 0x239E, 0x239F, 0x23A0,
+ /* GB+81 36 F7 35 */ 0x23A1, 0x23A2, 0x23A3, 0x23A4, 0x23A5,
+ /* GB+81 36 F8 30 */ 0x23A6, 0x23A7, 0x23A8, 0x23A9, 0x23AA,
+ /* GB+81 36 F8 35 */ 0x23AB, 0x23AC, 0x23AD, 0x23AE, 0x23AF,
+ /* GB+81 36 F9 30 */ 0x23B0, 0x23B1, 0x23B2, 0x23B3, 0x23B4,
+ /* GB+81 36 F9 35 */ 0x23B5, 0x23B6, 0x23B7, 0x23B8, 0x23B9,
+ /* GB+81 36 FA 30 */ 0x23BA, 0x23BB, 0x23BC, 0x23BD, 0x23BE,
+ /* GB+81 36 FA 35 */ 0x23BF, 0x23C0, 0x23C1, 0x23C2, 0x23C3,
+ /* GB+81 36 FB 30 */ 0x23C4, 0x23C5, 0x23C6, 0x23C7, 0x23C8,
+ /* GB+81 36 FB 35 */ 0x23C9, 0x23CA, 0x23CB, 0x23CC, 0x23CD,
+ /* GB+81 36 FC 30 */ 0x23CE, 0x23CF, 0x23D0, 0x23D1, 0x23D2,
+ /* GB+81 36 FC 35 */ 0x23D3, 0x23D4, 0x23D5, 0x23D6, 0x23D7,
+ /* GB+81 36 FD 30 */ 0x23D8, 0x23D9, 0x23DA, 0x23DB, 0x23DC,
+ /* GB+81 36 FD 35 */ 0x23DD, 0x23DE, 0x23DF, 0x23E0, 0x23E1,
+ /* GB+81 36 FE 30 */ 0x23E2, 0x23E3, 0x23E4, 0x23E5, 0x23E6,
+ /* GB+81 36 FE 35 */ 0x23E7, 0x23E8, 0x23E9, 0x23EA, 0x23EB,
+ /* GB+81 37 81 30 */ 0x23EC, 0x23ED, 0x23EE, 0x23EF, 0x23F0,
+ /* GB+81 37 81 35 */ 0x23F1, 0x23F2, 0x23F3, 0x23F4, 0x23F5,
+ /* GB+81 37 82 30 */ 0x23F6, 0x23F7, 0x23F8, 0x23F9, 0x23FA,
+ /* GB+81 37 82 35 */ 0x23FB, 0x23FC, 0x23FD, 0x23FE, 0x23FF,
+ /* GB+81 37 83 30 */ 0x2400, 0x2401, 0x2402, 0x2403, 0x2404,
+ /* GB+81 37 83 35 */ 0x2405, 0x2406, 0x2407, 0x2408, 0x2409,
+ /* GB+81 37 84 30 */ 0x240A, 0x240B, 0x240C, 0x240D, 0x240E,
+ /* GB+81 37 84 35 */ 0x240F, 0x2410, 0x2411, 0x2412, 0x2413,
+ /* GB+81 37 85 30 */ 0x2414, 0x2415, 0x2416, 0x2417, 0x2418,
+ /* GB+81 37 85 35 */ 0x2419, 0x241A, 0x241B, 0x241C, 0x241D,
+ /* GB+81 37 86 30 */ 0x241E, 0x241F, 0x2420, 0x2421, 0x2422,
+ /* GB+81 37 86 35 */ 0x2423, 0x2424, 0x2425, 0x2426, 0x2427,
+ /* GB+81 37 87 30 */ 0x2428, 0x2429, 0x242A, 0x242B, 0x242C,
+ /* GB+81 37 87 35 */ 0x242D, 0x242E, 0x242F, 0x2430, 0x2431,
+ /* GB+81 37 88 30 */ 0x2432, 0x2433, 0x2434, 0x2435, 0x2436,
+ /* GB+81 37 88 35 */ 0x2437, 0x2438, 0x2439, 0x243A, 0x243B,
+ /* GB+81 37 89 30 */ 0x243C, 0x243D, 0x243E, 0x243F, 0x2440,
+ /* GB+81 37 89 35 */ 0x2441, 0x2442, 0x2443, 0x2444, 0x2445,
+ /* GB+81 37 8A 30 */ 0x2446, 0x2447, 0x2448, 0x2449, 0x244A,
+ /* GB+81 37 8A 35 */ 0x244B, 0x244C, 0x244D, 0x244E, 0x244F,
+ /* GB+81 37 8B 30 */ 0x2450, 0x2451, 0x2452, 0x2453, 0x2454,
+ /* GB+81 37 8B 35 */ 0x2455, 0x2456, 0x2457, 0x2458, 0x2459,
+ /* GB+81 37 8C 30 */ 0x245A, 0x245B, 0x245C, 0x245D, 0x245E,
+ /* GB+81 37 8C 35 */ 0x245F, 0x246A, 0x246B, 0x246C, 0x246D,
+ /* GB+81 37 8D 30 */ 0x246E, 0x246F, 0x2470, 0x2471, 0x2472,
+ /* GB+81 37 8D 35 */ 0x2473, 0x249C, 0x249D, 0x249E, 0x249F,
+ /* GB+81 37 8E 30 */ 0x24A0, 0x24A1, 0x24A2, 0x24A3, 0x24A4,
+ /* GB+81 37 8E 35 */ 0x24A5, 0x24A6, 0x24A7, 0x24A8, 0x24A9,
+ /* GB+81 37 8F 30 */ 0x24AA, 0x24AB, 0x24AC, 0x24AD, 0x24AE,
+ /* GB+81 37 8F 35 */ 0x24AF, 0x24B0, 0x24B1, 0x24B2, 0x24B3,
+ /* GB+81 37 90 30 */ 0x24B4, 0x24B5, 0x24B6, 0x24B7, 0x24B8,
+ /* GB+81 37 90 35 */ 0x24B9, 0x24BA, 0x24BB, 0x24BC, 0x24BD,
+ /* GB+81 37 91 30 */ 0x24BE, 0x24BF, 0x24C0, 0x24C1, 0x24C2,
+ /* GB+81 37 91 35 */ 0x24C3, 0x24C4, 0x24C5, 0x24C6, 0x24C7,
+ /* GB+81 37 92 30 */ 0x24C8, 0x24C9, 0x24CA, 0x24CB, 0x24CC,
+ /* GB+81 37 92 35 */ 0x24CD, 0x24CE, 0x24CF, 0x24D0, 0x24D1,
+ /* GB+81 37 93 30 */ 0x24D2, 0x24D3, 0x24D4, 0x24D5, 0x24D6,
+ /* GB+81 37 93 35 */ 0x24D7, 0x24D8, 0x24D9, 0x24DA, 0x24DB,
+ /* GB+81 37 94 30 */ 0x24DC, 0x24DD, 0x24DE, 0x24DF, 0x24E0,
+ /* GB+81 37 94 35 */ 0x24E1, 0x24E2, 0x24E3, 0x24E4, 0x24E5,
+ /* GB+81 37 95 30 */ 0x24E6, 0x24E7, 0x24E8, 0x24E9, 0x24EA,
+ /* GB+81 37 95 35 */ 0x24EB, 0x24EC, 0x24ED, 0x24EE, 0x24EF,
+ /* GB+81 37 96 30 */ 0x24F0, 0x24F1, 0x24F2, 0x24F3, 0x24F4,
+ /* GB+81 37 96 35 */ 0x24F5, 0x24F6, 0x24F7, 0x24F8, 0x24F9,
+ /* GB+81 37 97 30 */ 0x24FA, 0x24FB, 0x24FC, 0x24FD, 0x24FE,
+ /* GB+81 37 97 35 */ 0x24FF, 0x254C, 0x254D, 0x254E, 0x254F,
+ /* GB+81 37 98 30 */ 0x2574, 0x2575, 0x2576, 0x2577, 0x2578,
+ /* GB+81 37 98 35 */ 0x2579, 0x257A, 0x257B, 0x257C, 0x257D,
+ /* GB+81 37 99 30 */ 0x257E, 0x257F, 0x2580, 0x2590, 0x2591,
+ /* GB+81 37 99 35 */ 0x2592, 0x2596, 0x2597, 0x2598, 0x2599,
+ /* GB+81 37 9A 30 */ 0x259A, 0x259B, 0x259C, 0x259D, 0x259E,
+ /* GB+81 37 9A 35 */ 0x259F, 0x25A2, 0x25A3, 0x25A4, 0x25A5,
+ /* GB+81 37 9B 30 */ 0x25A6, 0x25A7, 0x25A8, 0x25A9, 0x25AA,
+ /* GB+81 37 9B 35 */ 0x25AB, 0x25AC, 0x25AD, 0x25AE, 0x25AF,
+ /* GB+81 37 9C 30 */ 0x25B0, 0x25B1, 0x25B4, 0x25B5, 0x25B6,
+ /* GB+81 37 9C 35 */ 0x25B7, 0x25B8, 0x25B9, 0x25BA, 0x25BB,
+ /* GB+81 37 9D 30 */ 0x25BE, 0x25BF, 0x25C0, 0x25C1, 0x25C2,
+ /* GB+81 37 9D 35 */ 0x25C3, 0x25C4, 0x25C5, 0x25C8, 0x25C9,
+ /* GB+81 37 9E 30 */ 0x25CA, 0x25CC, 0x25CD, 0x25D0, 0x25D1,
+ /* GB+81 37 9E 35 */ 0x25D2, 0x25D3, 0x25D4, 0x25D5, 0x25D6,
+ /* GB+81 37 9F 30 */ 0x25D7, 0x25D8, 0x25D9, 0x25DA, 0x25DB,
+ /* GB+81 37 9F 35 */ 0x25DC, 0x25DD, 0x25DE, 0x25DF, 0x25E0,
+ /* GB+81 37 A0 30 */ 0x25E1, 0x25E6, 0x25E7, 0x25E8, 0x25E9,
+ /* GB+81 37 A0 35 */ 0x25EA, 0x25EB, 0x25EC, 0x25ED, 0x25EE,
+ /* GB+81 37 A1 30 */ 0x25EF, 0x25F0, 0x25F1, 0x25F2, 0x25F3,
+ /* GB+81 37 A1 35 */ 0x25F4, 0x25F5, 0x25F6, 0x25F7, 0x25F8,
+ /* GB+81 37 A2 30 */ 0x25F9, 0x25FA, 0x25FB, 0x25FC, 0x25FD,
+ /* GB+81 37 A2 35 */ 0x25FE, 0x25FF, 0x2600, 0x2601, 0x2602,
+ /* GB+81 37 A3 30 */ 0x2603, 0x2604, 0x2607, 0x2608, 0x260A,
+ /* GB+81 37 A3 35 */ 0x260B, 0x260C, 0x260D, 0x260E, 0x260F,
+ /* GB+81 37 A4 30 */ 0x2610, 0x2611, 0x2612, 0x2613, 0x2614,
+ /* GB+81 37 A4 35 */ 0x2615, 0x2616, 0x2617, 0x2618, 0x2619,
+ /* GB+81 37 A5 30 */ 0x261A, 0x261B, 0x261C, 0x261D, 0x261E,
+ /* GB+81 37 A5 35 */ 0x261F, 0x2620, 0x2621, 0x2622, 0x2623,
+ /* GB+81 37 A6 30 */ 0x2624, 0x2625, 0x2626, 0x2627, 0x2628,
+ /* GB+81 37 A6 35 */ 0x2629, 0x262A, 0x262B, 0x262C, 0x262D,
+ /* GB+81 37 A7 30 */ 0x262E, 0x262F, 0x2630, 0x2631, 0x2632,
+ /* GB+81 37 A7 35 */ 0x2633, 0x2634, 0x2635, 0x2636, 0x2637,
+ /* GB+81 37 A8 30 */ 0x2638, 0x2639, 0x263A, 0x263B, 0x263C,
+ /* GB+81 37 A8 35 */ 0x263D, 0x263E, 0x263F, 0x2641,
+ /* Contiguous area: GB+81 38 FD 39 .. GB+82 30 A6 32 */
+ /* GB+81 38 FD 39 */ 0x2E82,
+ /* GB+81 38 FE 30 */ 0x2E83, 0x2E85, 0x2E86, 0x2E87, 0x2E89,
+ /* GB+81 38 FE 35 */ 0x2E8A, 0x2E8D, 0x2E8E, 0x2E8F, 0x2E90,
+ /* GB+81 39 81 30 */ 0x2E91, 0x2E92, 0x2E93, 0x2E94, 0x2E95,
+ /* GB+81 39 81 35 */ 0x2E96, 0x2E98, 0x2E99, 0x2E9A, 0x2E9B,
+ /* GB+81 39 82 30 */ 0x2E9C, 0x2E9D, 0x2E9E, 0x2E9F, 0x2EA0,
+ /* GB+81 39 82 35 */ 0x2EA1, 0x2EA2, 0x2EA3, 0x2EA4, 0x2EA5,
+ /* GB+81 39 83 30 */ 0x2EA6, 0x2EA8, 0x2EA9, 0x2EAB, 0x2EAC,
+ /* GB+81 39 83 35 */ 0x2EAD, 0x2EAF, 0x2EB0, 0x2EB1, 0x2EB2,
+ /* GB+81 39 84 30 */ 0x2EB4, 0x2EB5, 0x2EB8, 0x2EB9, 0x2EBA,
+ /* GB+81 39 84 35 */ 0x2EBC, 0x2EBD, 0x2EBE, 0x2EBF, 0x2EC0,
+ /* GB+81 39 85 30 */ 0x2EC1, 0x2EC2, 0x2EC3, 0x2EC4, 0x2EC5,
+ /* GB+81 39 85 35 */ 0x2EC6, 0x2EC7, 0x2EC8, 0x2EC9, 0x2ECB,
+ /* GB+81 39 86 30 */ 0x2ECC, 0x2ECD, 0x2ECE, 0x2ECF, 0x2ED0,
+ /* GB+81 39 86 35 */ 0x2ED1, 0x2ED2, 0x2ED3, 0x2ED4, 0x2ED5,
+ /* GB+81 39 87 30 */ 0x2ED6, 0x2ED7, 0x2ED8, 0x2ED9, 0x2EDA,
+ /* GB+81 39 87 35 */ 0x2EDB, 0x2EDC, 0x2EDD, 0x2EDE, 0x2EDF,
+ /* GB+81 39 88 30 */ 0x2EE0, 0x2EE1, 0x2EE2, 0x2EE3, 0x2EE4,
+ /* GB+81 39 88 35 */ 0x2EE5, 0x2EE6, 0x2EE7, 0x2EE8, 0x2EE9,
+ /* GB+81 39 89 30 */ 0x2EEA, 0x2EEB, 0x2EEC, 0x2EED, 0x2EEE,
+ /* GB+81 39 89 35 */ 0x2EEF, 0x2EF0, 0x2EF1, 0x2EF2, 0x2EF3,
+ /* GB+81 39 8A 30 */ 0x2EF4, 0x2EF5, 0x2EF6, 0x2EF7, 0x2EF8,
+ /* GB+81 39 8A 35 */ 0x2EF9, 0x2EFA, 0x2EFB, 0x2EFC, 0x2EFD,
+ /* GB+81 39 8B 30 */ 0x2EFE, 0x2EFF, 0x2F00, 0x2F01, 0x2F02,
+ /* GB+81 39 8B 35 */ 0x2F03, 0x2F04, 0x2F05, 0x2F06, 0x2F07,
+ /* GB+81 39 8C 30 */ 0x2F08, 0x2F09, 0x2F0A, 0x2F0B, 0x2F0C,
+ /* GB+81 39 8C 35 */ 0x2F0D, 0x2F0E, 0x2F0F, 0x2F10, 0x2F11,
+ /* GB+81 39 8D 30 */ 0x2F12, 0x2F13, 0x2F14, 0x2F15, 0x2F16,
+ /* GB+81 39 8D 35 */ 0x2F17, 0x2F18, 0x2F19, 0x2F1A, 0x2F1B,
+ /* GB+81 39 8E 30 */ 0x2F1C, 0x2F1D, 0x2F1E, 0x2F1F, 0x2F20,
+ /* GB+81 39 8E 35 */ 0x2F21, 0x2F22, 0x2F23, 0x2F24, 0x2F25,
+ /* GB+81 39 8F 30 */ 0x2F26, 0x2F27, 0x2F28, 0x2F29, 0x2F2A,
+ /* GB+81 39 8F 35 */ 0x2F2B, 0x2F2C, 0x2F2D, 0x2F2E, 0x2F2F,
+ /* GB+81 39 90 30 */ 0x2F30, 0x2F31, 0x2F32, 0x2F33, 0x2F34,
+ /* GB+81 39 90 35 */ 0x2F35, 0x2F36, 0x2F37, 0x2F38, 0x2F39,
+ /* GB+81 39 91 30 */ 0x2F3A, 0x2F3B, 0x2F3C, 0x2F3D, 0x2F3E,
+ /* GB+81 39 91 35 */ 0x2F3F, 0x2F40, 0x2F41, 0x2F42, 0x2F43,
+ /* GB+81 39 92 30 */ 0x2F44, 0x2F45, 0x2F46, 0x2F47, 0x2F48,
+ /* GB+81 39 92 35 */ 0x2F49, 0x2F4A, 0x2F4B, 0x2F4C, 0x2F4D,
+ /* GB+81 39 93 30 */ 0x2F4E, 0x2F4F, 0x2F50, 0x2F51, 0x2F52,
+ /* GB+81 39 93 35 */ 0x2F53, 0x2F54, 0x2F55, 0x2F56, 0x2F57,
+ /* GB+81 39 94 30 */ 0x2F58, 0x2F59, 0x2F5A, 0x2F5B, 0x2F5C,
+ /* GB+81 39 94 35 */ 0x2F5D, 0x2F5E, 0x2F5F, 0x2F60, 0x2F61,
+ /* GB+81 39 95 30 */ 0x2F62, 0x2F63, 0x2F64, 0x2F65, 0x2F66,
+ /* GB+81 39 95 35 */ 0x2F67, 0x2F68, 0x2F69, 0x2F6A, 0x2F6B,
+ /* GB+81 39 96 30 */ 0x2F6C, 0x2F6D, 0x2F6E, 0x2F6F, 0x2F70,
+ /* GB+81 39 96 35 */ 0x2F71, 0x2F72, 0x2F73, 0x2F74, 0x2F75,
+ /* GB+81 39 97 30 */ 0x2F76, 0x2F77, 0x2F78, 0x2F79, 0x2F7A,
+ /* GB+81 39 97 35 */ 0x2F7B, 0x2F7C, 0x2F7D, 0x2F7E, 0x2F7F,
+ /* GB+81 39 98 30 */ 0x2F80, 0x2F81, 0x2F82, 0x2F83, 0x2F84,
+ /* GB+81 39 98 35 */ 0x2F85, 0x2F86, 0x2F87, 0x2F88, 0x2F89,
+ /* GB+81 39 99 30 */ 0x2F8A, 0x2F8B, 0x2F8C, 0x2F8D, 0x2F8E,
+ /* GB+81 39 99 35 */ 0x2F8F, 0x2F90, 0x2F91, 0x2F92, 0x2F93,
+ /* GB+81 39 9A 30 */ 0x2F94, 0x2F95, 0x2F96, 0x2F97, 0x2F98,
+ /* GB+81 39 9A 35 */ 0x2F99, 0x2F9A, 0x2F9B, 0x2F9C, 0x2F9D,
+ /* GB+81 39 9B 30 */ 0x2F9E, 0x2F9F, 0x2FA0, 0x2FA1, 0x2FA2,
+ /* GB+81 39 9B 35 */ 0x2FA3, 0x2FA4, 0x2FA5, 0x2FA6, 0x2FA7,
+ /* GB+81 39 9C 30 */ 0x2FA8, 0x2FA9, 0x2FAA, 0x2FAB, 0x2FAC,
+ /* GB+81 39 9C 35 */ 0x2FAD, 0x2FAE, 0x2FAF, 0x2FB0, 0x2FB1,
+ /* GB+81 39 9D 30 */ 0x2FB2, 0x2FB3, 0x2FB4, 0x2FB5, 0x2FB6,
+ /* GB+81 39 9D 35 */ 0x2FB7, 0x2FB8, 0x2FB9, 0x2FBA, 0x2FBB,
+ /* GB+81 39 9E 30 */ 0x2FBC, 0x2FBD, 0x2FBE, 0x2FBF, 0x2FC0,
+ /* GB+81 39 9E 35 */ 0x2FC1, 0x2FC2, 0x2FC3, 0x2FC4, 0x2FC5,
+ /* GB+81 39 9F 30 */ 0x2FC6, 0x2FC7, 0x2FC8, 0x2FC9, 0x2FCA,
+ /* GB+81 39 9F 35 */ 0x2FCB, 0x2FCC, 0x2FCD, 0x2FCE, 0x2FCF,
+ /* GB+81 39 A0 30 */ 0x2FD0, 0x2FD1, 0x2FD2, 0x2FD3, 0x2FD4,
+ /* GB+81 39 A0 35 */ 0x2FD5, 0x2FD6, 0x2FD7, 0x2FD8, 0x2FD9,
+ /* GB+81 39 A1 30 */ 0x2FDA, 0x2FDB, 0x2FDC, 0x2FDD, 0x2FDE,
+ /* GB+81 39 A1 35 */ 0x2FDF, 0x2FE0, 0x2FE1, 0x2FE2, 0x2FE3,
+ /* GB+81 39 A2 30 */ 0x2FE4, 0x2FE5, 0x2FE6, 0x2FE7, 0x2FE8,
+ /* GB+81 39 A2 35 */ 0x2FE9, 0x2FEA, 0x2FEB, 0x2FEC, 0x2FED,
+ /* GB+81 39 A3 30 */ 0x2FEE, 0x2FEF, 0x2FFC, 0x2FFD, 0x2FFE,
+ /* GB+81 39 A3 35 */ 0x2FFF, 0x3004, 0x3018, 0x3019, 0x301A,
+ /* GB+81 39 A4 30 */ 0x301B, 0x301C, 0x301F, 0x3020, 0x302A,
+ /* GB+81 39 A4 35 */ 0x302B, 0x302C, 0x302D, 0x302E, 0x302F,
+ /* GB+81 39 A5 30 */ 0x3030, 0x3031, 0x3032, 0x3033, 0x3034,
+ /* GB+81 39 A5 35 */ 0x3035, 0x3036, 0x3037, 0x3038, 0x3039,
+ /* GB+81 39 A6 30 */ 0x303A, 0x303B, 0x303C, 0x303D, 0x303F,
+ /* GB+81 39 A6 35 */ 0x3040, 0x3094, 0x3095, 0x3096, 0x3097,
+ /* GB+81 39 A7 30 */ 0x3098, 0x3099, 0x309A, 0x309F, 0x30A0,
+ /* GB+81 39 A7 35 */ 0x30F7, 0x30F8, 0x30F9, 0x30FA, 0x30FB,
+ /* GB+81 39 A8 30 */ 0x30FF, 0x3100, 0x3101, 0x3102, 0x3103,
+ /* GB+81 39 A8 35 */ 0x3104, 0x312A, 0x312B, 0x312C, 0x312D,
+ /* GB+81 39 A9 30 */ 0x312E, 0x312F, 0x3130, 0x3131, 0x3132,
+ /* GB+81 39 A9 35 */ 0x3133, 0x3134, 0x3135, 0x3136, 0x3137,
+ /* GB+81 39 AA 30 */ 0x3138, 0x3139, 0x313A, 0x313B, 0x313C,
+ /* GB+81 39 AA 35 */ 0x313D, 0x313E, 0x313F, 0x3140, 0x3141,
+ /* GB+81 39 AB 30 */ 0x3142, 0x3143, 0x3144, 0x3145, 0x3146,
+ /* GB+81 39 AB 35 */ 0x3147, 0x3148, 0x3149, 0x314A, 0x314B,
+ /* GB+81 39 AC 30 */ 0x314C, 0x314D, 0x314E, 0x314F, 0x3150,
+ /* GB+81 39 AC 35 */ 0x3151, 0x3152, 0x3153, 0x3154, 0x3155,
+ /* GB+81 39 AD 30 */ 0x3156, 0x3157, 0x3158, 0x3159, 0x315A,
+ /* GB+81 39 AD 35 */ 0x315B, 0x315C, 0x315D, 0x315E, 0x315F,
+ /* GB+81 39 AE 30 */ 0x3160, 0x3161, 0x3162, 0x3163, 0x3164,
+ /* GB+81 39 AE 35 */ 0x3165, 0x3166, 0x3167, 0x3168, 0x3169,
+ /* GB+81 39 AF 30 */ 0x316A, 0x316B, 0x316C, 0x316D, 0x316E,
+ /* GB+81 39 AF 35 */ 0x316F, 0x3170, 0x3171, 0x3172, 0x3173,
+ /* GB+81 39 B0 30 */ 0x3174, 0x3175, 0x3176, 0x3177, 0x3178,
+ /* GB+81 39 B0 35 */ 0x3179, 0x317A, 0x317B, 0x317C, 0x317D,
+ /* GB+81 39 B1 30 */ 0x317E, 0x317F, 0x3180, 0x3181, 0x3182,
+ /* GB+81 39 B1 35 */ 0x3183, 0x3184, 0x3185, 0x3186, 0x3187,
+ /* GB+81 39 B2 30 */ 0x3188, 0x3189, 0x318A, 0x318B, 0x318C,
+ /* GB+81 39 B2 35 */ 0x318D, 0x318E, 0x318F, 0x3190, 0x3191,
+ /* GB+81 39 B3 30 */ 0x3192, 0x3193, 0x3194, 0x3195, 0x3196,
+ /* GB+81 39 B3 35 */ 0x3197, 0x3198, 0x3199, 0x319A, 0x319B,
+ /* GB+81 39 B4 30 */ 0x319C, 0x319D, 0x319E, 0x319F, 0x31A0,
+ /* GB+81 39 B4 35 */ 0x31A1, 0x31A2, 0x31A3, 0x31A4, 0x31A5,
+ /* GB+81 39 B5 30 */ 0x31A6, 0x31A7, 0x31A8, 0x31A9, 0x31AA,
+ /* GB+81 39 B5 35 */ 0x31AB, 0x31AC, 0x31AD, 0x31AE, 0x31AF,
+ /* GB+81 39 B6 30 */ 0x31B0, 0x31B1, 0x31B2, 0x31B3, 0x31B4,
+ /* GB+81 39 B6 35 */ 0x31B5, 0x31B6, 0x31B7, 0x31B8, 0x31B9,
+ /* GB+81 39 B7 30 */ 0x31BA, 0x31BB, 0x31BC, 0x31BD, 0x31BE,
+ /* GB+81 39 B7 35 */ 0x31BF, 0x31C0, 0x31C1, 0x31C2, 0x31C3,
+ /* GB+81 39 B8 30 */ 0x31C4, 0x31C5, 0x31C6, 0x31C7, 0x31C8,
+ /* GB+81 39 B8 35 */ 0x31C9, 0x31CA, 0x31CB, 0x31CC, 0x31CD,
+ /* GB+81 39 B9 30 */ 0x31CE, 0x31CF, 0x31D0, 0x31D1, 0x31D2,
+ /* GB+81 39 B9 35 */ 0x31D3, 0x31D4, 0x31D5, 0x31D6, 0x31D7,
+ /* GB+81 39 BA 30 */ 0x31D8, 0x31D9, 0x31DA, 0x31DB, 0x31DC,
+ /* GB+81 39 BA 35 */ 0x31DD, 0x31DE, 0x31DF, 0x31E0, 0x31E1,
+ /* GB+81 39 BB 30 */ 0x31E2, 0x31E3, 0x31E4, 0x31E5, 0x31E6,
+ /* GB+81 39 BB 35 */ 0x31E7, 0x31E8, 0x31E9, 0x31EA, 0x31EB,
+ /* GB+81 39 BC 30 */ 0x31EC, 0x31ED, 0x31EE, 0x31EF, 0x31F0,
+ /* GB+81 39 BC 35 */ 0x31F1, 0x31F2, 0x31F3, 0x31F4, 0x31F5,
+ /* GB+81 39 BD 30 */ 0x31F6, 0x31F7, 0x31F8, 0x31F9, 0x31FA,
+ /* GB+81 39 BD 35 */ 0x31FB, 0x31FC, 0x31FD, 0x31FE, 0x31FF,
+ /* GB+81 39 BE 30 */ 0x3200, 0x3201, 0x3202, 0x3203, 0x3204,
+ /* GB+81 39 BE 35 */ 0x3205, 0x3206, 0x3207, 0x3208, 0x3209,
+ /* GB+81 39 BF 30 */ 0x320A, 0x320B, 0x320C, 0x320D, 0x320E,
+ /* GB+81 39 BF 35 */ 0x320F, 0x3210, 0x3211, 0x3212, 0x3213,
+ /* GB+81 39 C0 30 */ 0x3214, 0x3215, 0x3216, 0x3217, 0x3218,
+ /* GB+81 39 C0 35 */ 0x3219, 0x321A, 0x321B, 0x321C, 0x321D,
+ /* GB+81 39 C1 30 */ 0x321E, 0x321F, 0x322A, 0x322B, 0x322C,
+ /* GB+81 39 C1 35 */ 0x322D, 0x322E, 0x322F, 0x3230, 0x3232,
+ /* GB+81 39 C2 30 */ 0x3233, 0x3234, 0x3235, 0x3236, 0x3237,
+ /* GB+81 39 C2 35 */ 0x3238, 0x3239, 0x323A, 0x323B, 0x323C,
+ /* GB+81 39 C3 30 */ 0x323D, 0x323E, 0x323F, 0x3240, 0x3241,
+ /* GB+81 39 C3 35 */ 0x3242, 0x3243, 0x3244, 0x3245, 0x3246,
+ /* GB+81 39 C4 30 */ 0x3247, 0x3248, 0x3249, 0x324A, 0x324B,
+ /* GB+81 39 C4 35 */ 0x324C, 0x324D, 0x324E, 0x324F, 0x3250,
+ /* GB+81 39 C5 30 */ 0x3251, 0x3252, 0x3253, 0x3254, 0x3255,
+ /* GB+81 39 C5 35 */ 0x3256, 0x3257, 0x3258, 0x3259, 0x325A,
+ /* GB+81 39 C6 30 */ 0x325B, 0x325C, 0x325D, 0x325E, 0x325F,
+ /* GB+81 39 C6 35 */ 0x3260, 0x3261, 0x3262, 0x3263, 0x3264,
+ /* GB+81 39 C7 30 */ 0x3265, 0x3266, 0x3267, 0x3268, 0x3269,
+ /* GB+81 39 C7 35 */ 0x326A, 0x326B, 0x326C, 0x326D, 0x326E,
+ /* GB+81 39 C8 30 */ 0x326F, 0x3270, 0x3271, 0x3272, 0x3273,
+ /* GB+81 39 C8 35 */ 0x3274, 0x3275, 0x3276, 0x3277, 0x3278,
+ /* GB+81 39 C9 30 */ 0x3279, 0x327A, 0x327B, 0x327C, 0x327D,
+ /* GB+81 39 C9 35 */ 0x327E, 0x327F, 0x3280, 0x3281, 0x3282,
+ /* GB+81 39 CA 30 */ 0x3283, 0x3284, 0x3285, 0x3286, 0x3287,
+ /* GB+81 39 CA 35 */ 0x3288, 0x3289, 0x328A, 0x328B, 0x328C,
+ /* GB+81 39 CB 30 */ 0x328D, 0x328E, 0x328F, 0x3290, 0x3291,
+ /* GB+81 39 CB 35 */ 0x3292, 0x3293, 0x3294, 0x3295, 0x3296,
+ /* GB+81 39 CC 30 */ 0x3297, 0x3298, 0x3299, 0x329A, 0x329B,
+ /* GB+81 39 CC 35 */ 0x329C, 0x329D, 0x329E, 0x329F, 0x32A0,
+ /* GB+81 39 CD 30 */ 0x32A1, 0x32A2, 0x32A4, 0x32A5, 0x32A6,
+ /* GB+81 39 CD 35 */ 0x32A7, 0x32A8, 0x32A9, 0x32AA, 0x32AB,
+ /* GB+81 39 CE 30 */ 0x32AC, 0x32AD, 0x32AE, 0x32AF, 0x32B0,
+ /* GB+81 39 CE 35 */ 0x32B1, 0x32B2, 0x32B3, 0x32B4, 0x32B5,
+ /* GB+81 39 CF 30 */ 0x32B6, 0x32B7, 0x32B8, 0x32B9, 0x32BA,
+ /* GB+81 39 CF 35 */ 0x32BB, 0x32BC, 0x32BD, 0x32BE, 0x32BF,
+ /* GB+81 39 D0 30 */ 0x32C0, 0x32C1, 0x32C2, 0x32C3, 0x32C4,
+ /* GB+81 39 D0 35 */ 0x32C5, 0x32C6, 0x32C7, 0x32C8, 0x32C9,
+ /* GB+81 39 D1 30 */ 0x32CA, 0x32CB, 0x32CC, 0x32CD, 0x32CE,
+ /* GB+81 39 D1 35 */ 0x32CF, 0x32D0, 0x32D1, 0x32D2, 0x32D3,
+ /* GB+81 39 D2 30 */ 0x32D4, 0x32D5, 0x32D6, 0x32D7, 0x32D8,
+ /* GB+81 39 D2 35 */ 0x32D9, 0x32DA, 0x32DB, 0x32DC, 0x32DD,
+ /* GB+81 39 D3 30 */ 0x32DE, 0x32DF, 0x32E0, 0x32E1, 0x32E2,
+ /* GB+81 39 D3 35 */ 0x32E3, 0x32E4, 0x32E5, 0x32E6, 0x32E7,
+ /* GB+81 39 D4 30 */ 0x32E8, 0x32E9, 0x32EA, 0x32EB, 0x32EC,
+ /* GB+81 39 D4 35 */ 0x32ED, 0x32EE, 0x32EF, 0x32F0, 0x32F1,
+ /* GB+81 39 D5 30 */ 0x32F2, 0x32F3, 0x32F4, 0x32F5, 0x32F6,
+ /* GB+81 39 D5 35 */ 0x32F7, 0x32F8, 0x32F9, 0x32FA, 0x32FB,
+ /* GB+81 39 D6 30 */ 0x32FC, 0x32FD, 0x32FE, 0x32FF, 0x3300,
+ /* GB+81 39 D6 35 */ 0x3301, 0x3302, 0x3303, 0x3304, 0x3305,
+ /* GB+81 39 D7 30 */ 0x3306, 0x3307, 0x3308, 0x3309, 0x330A,
+ /* GB+81 39 D7 35 */ 0x330B, 0x330C, 0x330D, 0x330E, 0x330F,
+ /* GB+81 39 D8 30 */ 0x3310, 0x3311, 0x3312, 0x3313, 0x3314,
+ /* GB+81 39 D8 35 */ 0x3315, 0x3316, 0x3317, 0x3318, 0x3319,
+ /* GB+81 39 D9 30 */ 0x331A, 0x331B, 0x331C, 0x331D, 0x331E,
+ /* GB+81 39 D9 35 */ 0x331F, 0x3320, 0x3321, 0x3322, 0x3323,
+ /* GB+81 39 DA 30 */ 0x3324, 0x3325, 0x3326, 0x3327, 0x3328,
+ /* GB+81 39 DA 35 */ 0x3329, 0x332A, 0x332B, 0x332C, 0x332D,
+ /* GB+81 39 DB 30 */ 0x332E, 0x332F, 0x3330, 0x3331, 0x3332,
+ /* GB+81 39 DB 35 */ 0x3333, 0x3334, 0x3335, 0x3336, 0x3337,
+ /* GB+81 39 DC 30 */ 0x3338, 0x3339, 0x333A, 0x333B, 0x333C,
+ /* GB+81 39 DC 35 */ 0x333D, 0x333E, 0x333F, 0x3340, 0x3341,
+ /* GB+81 39 DD 30 */ 0x3342, 0x3343, 0x3344, 0x3345, 0x3346,
+ /* GB+81 39 DD 35 */ 0x3347, 0x3348, 0x3349, 0x334A, 0x334B,
+ /* GB+81 39 DE 30 */ 0x334C, 0x334D, 0x334E, 0x334F, 0x3350,
+ /* GB+81 39 DE 35 */ 0x3351, 0x3352, 0x3353, 0x3354, 0x3355,
+ /* GB+81 39 DF 30 */ 0x3356, 0x3357, 0x3358, 0x3359, 0x335A,
+ /* GB+81 39 DF 35 */ 0x335B, 0x335C, 0x335D, 0x335E, 0x335F,
+ /* GB+81 39 E0 30 */ 0x3360, 0x3361, 0x3362, 0x3363, 0x3364,
+ /* GB+81 39 E0 35 */ 0x3365, 0x3366, 0x3367, 0x3368, 0x3369,
+ /* GB+81 39 E1 30 */ 0x336A, 0x336B, 0x336C, 0x336D, 0x336E,
+ /* GB+81 39 E1 35 */ 0x336F, 0x3370, 0x3371, 0x3372, 0x3373,
+ /* GB+81 39 E2 30 */ 0x3374, 0x3375, 0x3376, 0x3377, 0x3378,
+ /* GB+81 39 E2 35 */ 0x3379, 0x337A, 0x337B, 0x337C, 0x337D,
+ /* GB+81 39 E3 30 */ 0x337E, 0x337F, 0x3380, 0x3381, 0x3382,
+ /* GB+81 39 E3 35 */ 0x3383, 0x3384, 0x3385, 0x3386, 0x3387,
+ /* GB+81 39 E4 30 */ 0x3388, 0x3389, 0x338A, 0x338B, 0x338C,
+ /* GB+81 39 E4 35 */ 0x338D, 0x3390, 0x3391, 0x3392, 0x3393,
+ /* GB+81 39 E5 30 */ 0x3394, 0x3395, 0x3396, 0x3397, 0x3398,
+ /* GB+81 39 E5 35 */ 0x3399, 0x339A, 0x339B, 0x339F, 0x33A0,
+ /* GB+81 39 E6 30 */ 0x33A2, 0x33A3, 0x33A4, 0x33A5, 0x33A6,
+ /* GB+81 39 E6 35 */ 0x33A7, 0x33A8, 0x33A9, 0x33AA, 0x33AB,
+ /* GB+81 39 E7 30 */ 0x33AC, 0x33AD, 0x33AE, 0x33AF, 0x33B0,
+ /* GB+81 39 E7 35 */ 0x33B1, 0x33B2, 0x33B3, 0x33B4, 0x33B5,
+ /* GB+81 39 E8 30 */ 0x33B6, 0x33B7, 0x33B8, 0x33B9, 0x33BA,
+ /* GB+81 39 E8 35 */ 0x33BB, 0x33BC, 0x33BD, 0x33BE, 0x33BF,
+ /* GB+81 39 E9 30 */ 0x33C0, 0x33C1, 0x33C2, 0x33C3, 0x33C5,
+ /* GB+81 39 E9 35 */ 0x33C6, 0x33C7, 0x33C8, 0x33C9, 0x33CA,
+ /* GB+81 39 EA 30 */ 0x33CB, 0x33CC, 0x33CD, 0x33CF, 0x33D0,
+ /* GB+81 39 EA 35 */ 0x33D3, 0x33D4, 0x33D6, 0x33D7, 0x33D8,
+ /* GB+81 39 EB 30 */ 0x33D9, 0x33DA, 0x33DB, 0x33DC, 0x33DD,
+ /* GB+81 39 EB 35 */ 0x33DE, 0x33DF, 0x33E0, 0x33E1, 0x33E2,
+ /* GB+81 39 EC 30 */ 0x33E3, 0x33E4, 0x33E5, 0x33E6, 0x33E7,
+ /* GB+81 39 EC 35 */ 0x33E8, 0x33E9, 0x33EA, 0x33EB, 0x33EC,
+ /* GB+81 39 ED 30 */ 0x33ED, 0x33EE, 0x33EF, 0x33F0, 0x33F1,
+ /* GB+81 39 ED 35 */ 0x33F2, 0x33F3, 0x33F4, 0x33F5, 0x33F6,
+ /* GB+81 39 EE 30 */ 0x33F7, 0x33F8, 0x33F9, 0x33FA, 0x33FB,
+ /* GB+81 39 EE 35 */ 0x33FC, 0x33FD, 0x33FE, 0x33FF, 0x3400,
+ /* GB+81 39 EF 30 */ 0x3401, 0x3402, 0x3403, 0x3404, 0x3405,
+ /* GB+81 39 EF 35 */ 0x3406, 0x3407, 0x3408, 0x3409, 0x340A,
+ /* GB+81 39 F0 30 */ 0x340B, 0x340C, 0x340D, 0x340E, 0x340F,
+ /* GB+81 39 F0 35 */ 0x3410, 0x3411, 0x3412, 0x3413, 0x3414,
+ /* GB+81 39 F1 30 */ 0x3415, 0x3416, 0x3417, 0x3418, 0x3419,
+ /* GB+81 39 F1 35 */ 0x341A, 0x341B, 0x341C, 0x341D, 0x341E,
+ /* GB+81 39 F2 30 */ 0x341F, 0x3420, 0x3421, 0x3422, 0x3423,
+ /* GB+81 39 F2 35 */ 0x3424, 0x3425, 0x3426, 0x3427, 0x3428,
+ /* GB+81 39 F3 30 */ 0x3429, 0x342A, 0x342B, 0x342C, 0x342D,
+ /* GB+81 39 F3 35 */ 0x342E, 0x342F, 0x3430, 0x3431, 0x3432,
+ /* GB+81 39 F4 30 */ 0x3433, 0x3434, 0x3435, 0x3436, 0x3437,
+ /* GB+81 39 F4 35 */ 0x3438, 0x3439, 0x343A, 0x343B, 0x343C,
+ /* GB+81 39 F5 30 */ 0x343D, 0x343E, 0x343F, 0x3440, 0x3441,
+ /* GB+81 39 F5 35 */ 0x3442, 0x3443, 0x3444, 0x3445, 0x3446,
+ /* GB+81 39 F6 30 */ 0x3448, 0x3449, 0x344A, 0x344B, 0x344C,
+ /* GB+81 39 F6 35 */ 0x344D, 0x344E, 0x344F, 0x3450, 0x3451,
+ /* GB+81 39 F7 30 */ 0x3452, 0x3453, 0x3454, 0x3455, 0x3456,
+ /* GB+81 39 F7 35 */ 0x3457, 0x3458, 0x3459, 0x345A, 0x345B,
+ /* GB+81 39 F8 30 */ 0x345C, 0x345D, 0x345E, 0x345F, 0x3460,
+ /* GB+81 39 F8 35 */ 0x3461, 0x3462, 0x3463, 0x3464, 0x3465,
+ /* GB+81 39 F9 30 */ 0x3466, 0x3467, 0x3468, 0x3469, 0x346A,
+ /* GB+81 39 F9 35 */ 0x346B, 0x346C, 0x346D, 0x346E, 0x346F,
+ /* GB+81 39 FA 30 */ 0x3470, 0x3471, 0x3472, 0x3474, 0x3475,
+ /* GB+81 39 FA 35 */ 0x3476, 0x3477, 0x3478, 0x3479, 0x347A,
+ /* GB+81 39 FB 30 */ 0x347B, 0x347C, 0x347D, 0x347E, 0x347F,
+ /* GB+81 39 FB 35 */ 0x3480, 0x3481, 0x3482, 0x3483, 0x3484,
+ /* GB+81 39 FC 30 */ 0x3485, 0x3486, 0x3487, 0x3488, 0x3489,
+ /* GB+81 39 FC 35 */ 0x348A, 0x348B, 0x348C, 0x348D, 0x348E,
+ /* GB+81 39 FD 30 */ 0x348F, 0x3490, 0x3491, 0x3492, 0x3493,
+ /* GB+81 39 FD 35 */ 0x3494, 0x3495, 0x3496, 0x3497, 0x3498,
+ /* GB+81 39 FE 30 */ 0x3499, 0x349A, 0x349B, 0x349C, 0x349D,
+ /* GB+81 39 FE 35 */ 0x349E, 0x349F, 0x34A0, 0x34A1, 0x34A2,
+ /* GB+82 30 81 30 */ 0x34A3, 0x34A4, 0x34A5, 0x34A6, 0x34A7,
+ /* GB+82 30 81 35 */ 0x34A8, 0x34A9, 0x34AA, 0x34AB, 0x34AC,
+ /* GB+82 30 82 30 */ 0x34AD, 0x34AE, 0x34AF, 0x34B0, 0x34B1,
+ /* GB+82 30 82 35 */ 0x34B2, 0x34B3, 0x34B4, 0x34B5, 0x34B6,
+ /* GB+82 30 83 30 */ 0x34B7, 0x34B8, 0x34B9, 0x34BA, 0x34BB,
+ /* GB+82 30 83 35 */ 0x34BC, 0x34BD, 0x34BE, 0x34BF, 0x34C0,
+ /* GB+82 30 84 30 */ 0x34C1, 0x34C2, 0x34C3, 0x34C4, 0x34C5,
+ /* GB+82 30 84 35 */ 0x34C6, 0x34C7, 0x34C8, 0x34C9, 0x34CA,
+ /* GB+82 30 85 30 */ 0x34CB, 0x34CC, 0x34CD, 0x34CE, 0x34CF,
+ /* GB+82 30 85 35 */ 0x34D0, 0x34D1, 0x34D2, 0x34D3, 0x34D4,
+ /* GB+82 30 86 30 */ 0x34D5, 0x34D6, 0x34D7, 0x34D8, 0x34D9,
+ /* GB+82 30 86 35 */ 0x34DA, 0x34DB, 0x34DC, 0x34DD, 0x34DE,
+ /* GB+82 30 87 30 */ 0x34DF, 0x34E0, 0x34E1, 0x34E2, 0x34E3,
+ /* GB+82 30 87 35 */ 0x34E4, 0x34E5, 0x34E6, 0x34E7, 0x34E8,
+ /* GB+82 30 88 30 */ 0x34E9, 0x34EA, 0x34EB, 0x34EC, 0x34ED,
+ /* GB+82 30 88 35 */ 0x34EE, 0x34EF, 0x34F0, 0x34F1, 0x34F2,
+ /* GB+82 30 89 30 */ 0x34F3, 0x34F4, 0x34F5, 0x34F6, 0x34F7,
+ /* GB+82 30 89 35 */ 0x34F8, 0x34F9, 0x34FA, 0x34FB, 0x34FC,
+ /* GB+82 30 8A 30 */ 0x34FD, 0x34FE, 0x34FF, 0x3500, 0x3501,
+ /* GB+82 30 8A 35 */ 0x3502, 0x3503, 0x3504, 0x3505, 0x3506,
+ /* GB+82 30 8B 30 */ 0x3507, 0x3508, 0x3509, 0x350A, 0x350B,
+ /* GB+82 30 8B 35 */ 0x350C, 0x350D, 0x350E, 0x350F, 0x3510,
+ /* GB+82 30 8C 30 */ 0x3511, 0x3512, 0x3513, 0x3514, 0x3515,
+ /* GB+82 30 8C 35 */ 0x3516, 0x3517, 0x3518, 0x3519, 0x351A,
+ /* GB+82 30 8D 30 */ 0x351B, 0x351C, 0x351D, 0x351E, 0x351F,
+ /* GB+82 30 8D 35 */ 0x3520, 0x3521, 0x3522, 0x3523, 0x3524,
+ /* GB+82 30 8E 30 */ 0x3525, 0x3526, 0x3527, 0x3528, 0x3529,
+ /* GB+82 30 8E 35 */ 0x352A, 0x352B, 0x352C, 0x352D, 0x352E,
+ /* GB+82 30 8F 30 */ 0x352F, 0x3530, 0x3531, 0x3532, 0x3533,
+ /* GB+82 30 8F 35 */ 0x3534, 0x3535, 0x3536, 0x3537, 0x3538,
+ /* GB+82 30 90 30 */ 0x3539, 0x353A, 0x353B, 0x353C, 0x353D,
+ /* GB+82 30 90 35 */ 0x353E, 0x353F, 0x3540, 0x3541, 0x3542,
+ /* GB+82 30 91 30 */ 0x3543, 0x3544, 0x3545, 0x3546, 0x3547,
+ /* GB+82 30 91 35 */ 0x3548, 0x3549, 0x354A, 0x354B, 0x354C,
+ /* GB+82 30 92 30 */ 0x354D, 0x354E, 0x354F, 0x3550, 0x3551,
+ /* GB+82 30 92 35 */ 0x3552, 0x3553, 0x3554, 0x3555, 0x3556,
+ /* GB+82 30 93 30 */ 0x3557, 0x3558, 0x3559, 0x355A, 0x355B,
+ /* GB+82 30 93 35 */ 0x355C, 0x355D, 0x355E, 0x355F, 0x3560,
+ /* GB+82 30 94 30 */ 0x3561, 0x3562, 0x3563, 0x3564, 0x3565,
+ /* GB+82 30 94 35 */ 0x3566, 0x3567, 0x3568, 0x3569, 0x356A,
+ /* GB+82 30 95 30 */ 0x356B, 0x356C, 0x356D, 0x356E, 0x356F,
+ /* GB+82 30 95 35 */ 0x3570, 0x3571, 0x3572, 0x3573, 0x3574,
+ /* GB+82 30 96 30 */ 0x3575, 0x3576, 0x3577, 0x3578, 0x3579,
+ /* GB+82 30 96 35 */ 0x357A, 0x357B, 0x357C, 0x357D, 0x357E,
+ /* GB+82 30 97 30 */ 0x357F, 0x3580, 0x3581, 0x3582, 0x3583,
+ /* GB+82 30 97 35 */ 0x3584, 0x3585, 0x3586, 0x3587, 0x3588,
+ /* GB+82 30 98 30 */ 0x3589, 0x358A, 0x358B, 0x358C, 0x358D,
+ /* GB+82 30 98 35 */ 0x358E, 0x358F, 0x3590, 0x3591, 0x3592,
+ /* GB+82 30 99 30 */ 0x3593, 0x3594, 0x3595, 0x3596, 0x3597,
+ /* GB+82 30 99 35 */ 0x3598, 0x3599, 0x359A, 0x359B, 0x359C,
+ /* GB+82 30 9A 30 */ 0x359D, 0x359F, 0x35A0, 0x35A1, 0x35A2,
+ /* GB+82 30 9A 35 */ 0x35A3, 0x35A4, 0x35A5, 0x35A6, 0x35A7,
+ /* GB+82 30 9B 30 */ 0x35A8, 0x35A9, 0x35AA, 0x35AB, 0x35AC,
+ /* GB+82 30 9B 35 */ 0x35AD, 0x35AE, 0x35AF, 0x35B0, 0x35B1,
+ /* GB+82 30 9C 30 */ 0x35B2, 0x35B3, 0x35B4, 0x35B5, 0x35B6,
+ /* GB+82 30 9C 35 */ 0x35B7, 0x35B8, 0x35B9, 0x35BA, 0x35BB,
+ /* GB+82 30 9D 30 */ 0x35BC, 0x35BD, 0x35BE, 0x35BF, 0x35C0,
+ /* GB+82 30 9D 35 */ 0x35C1, 0x35C2, 0x35C3, 0x35C4, 0x35C5,
+ /* GB+82 30 9E 30 */ 0x35C6, 0x35C7, 0x35C8, 0x35C9, 0x35CA,
+ /* GB+82 30 9E 35 */ 0x35CB, 0x35CC, 0x35CD, 0x35CE, 0x35CF,
+ /* GB+82 30 9F 30 */ 0x35D0, 0x35D1, 0x35D2, 0x35D3, 0x35D4,
+ /* GB+82 30 9F 35 */ 0x35D5, 0x35D6, 0x35D7, 0x35D8, 0x35D9,
+ /* GB+82 30 A0 30 */ 0x35DA, 0x35DB, 0x35DC, 0x35DD, 0x35DE,
+ /* GB+82 30 A0 35 */ 0x35DF, 0x35E0, 0x35E1, 0x35E2, 0x35E3,
+ /* GB+82 30 A1 30 */ 0x35E4, 0x35E5, 0x35E6, 0x35E7, 0x35E8,
+ /* GB+82 30 A1 35 */ 0x35E9, 0x35EA, 0x35EB, 0x35EC, 0x35ED,
+ /* GB+82 30 A2 30 */ 0x35EE, 0x35EF, 0x35F0, 0x35F1, 0x35F2,
+ /* GB+82 30 A2 35 */ 0x35F3, 0x35F4, 0x35F5, 0x35F6, 0x35F7,
+ /* GB+82 30 A3 30 */ 0x35F8, 0x35F9, 0x35FA, 0x35FB, 0x35FC,
+ /* GB+82 30 A3 35 */ 0x35FD, 0x35FE, 0x35FF, 0x3600, 0x3601,
+ /* GB+82 30 A4 30 */ 0x3602, 0x3603, 0x3604, 0x3605, 0x3606,
+ /* GB+82 30 A4 35 */ 0x3607, 0x3608, 0x3609, 0x360A, 0x360B,
+ /* GB+82 30 A5 30 */ 0x360C, 0x360D, 0x360F, 0x3610, 0x3611,
+ /* GB+82 30 A5 35 */ 0x3612, 0x3613, 0x3614, 0x3615, 0x3616,
+ /* GB+82 30 A6 30 */ 0x3617, 0x3618, 0x3619,
+ /* Contiguous area: GB+82 30 F2 38 .. GB+82 31 D4 37 */
+ /* GB+82 30 F2 38 */ 0x3919, 0x391A,
+ /* GB+82 30 F3 30 */ 0x391B, 0x391C, 0x391D, 0x391E, 0x391F,
+ /* GB+82 30 F3 35 */ 0x3920, 0x3921, 0x3922, 0x3923, 0x3924,
+ /* GB+82 30 F4 30 */ 0x3925, 0x3926, 0x3927, 0x3928, 0x3929,
+ /* GB+82 30 F4 35 */ 0x392A, 0x392B, 0x392C, 0x392D, 0x392E,
+ /* GB+82 30 F5 30 */ 0x392F, 0x3930, 0x3931, 0x3932, 0x3933,
+ /* GB+82 30 F5 35 */ 0x3934, 0x3935, 0x3936, 0x3937, 0x3938,
+ /* GB+82 30 F6 30 */ 0x3939, 0x393A, 0x393B, 0x393C, 0x393D,
+ /* GB+82 30 F6 35 */ 0x393E, 0x393F, 0x3940, 0x3941, 0x3942,
+ /* GB+82 30 F7 30 */ 0x3943, 0x3944, 0x3945, 0x3946, 0x3947,
+ /* GB+82 30 F7 35 */ 0x3948, 0x3949, 0x394A, 0x394B, 0x394C,
+ /* GB+82 30 F8 30 */ 0x394D, 0x394E, 0x394F, 0x3950, 0x3951,
+ /* GB+82 30 F8 35 */ 0x3952, 0x3953, 0x3954, 0x3955, 0x3956,
+ /* GB+82 30 F9 30 */ 0x3957, 0x3958, 0x3959, 0x395A, 0x395B,
+ /* GB+82 30 F9 35 */ 0x395C, 0x395D, 0x395E, 0x395F, 0x3960,
+ /* GB+82 30 FA 30 */ 0x3961, 0x3962, 0x3963, 0x3964, 0x3965,
+ /* GB+82 30 FA 35 */ 0x3966, 0x3967, 0x3968, 0x3969, 0x396A,
+ /* GB+82 30 FB 30 */ 0x396B, 0x396C, 0x396D, 0x396F, 0x3970,
+ /* GB+82 30 FB 35 */ 0x3971, 0x3972, 0x3973, 0x3974, 0x3975,
+ /* GB+82 30 FC 30 */ 0x3976, 0x3977, 0x3978, 0x3979, 0x397A,
+ /* GB+82 30 FC 35 */ 0x397B, 0x397C, 0x397D, 0x397E, 0x397F,
+ /* GB+82 30 FD 30 */ 0x3980, 0x3981, 0x3982, 0x3983, 0x3984,
+ /* GB+82 30 FD 35 */ 0x3985, 0x3986, 0x3987, 0x3988, 0x3989,
+ /* GB+82 30 FE 30 */ 0x398A, 0x398B, 0x398C, 0x398D, 0x398E,
+ /* GB+82 30 FE 35 */ 0x398F, 0x3990, 0x3991, 0x3992, 0x3993,
+ /* GB+82 31 81 30 */ 0x3994, 0x3995, 0x3996, 0x3997, 0x3998,
+ /* GB+82 31 81 35 */ 0x3999, 0x399A, 0x399B, 0x399C, 0x399D,
+ /* GB+82 31 82 30 */ 0x399E, 0x399F, 0x39A0, 0x39A1, 0x39A2,
+ /* GB+82 31 82 35 */ 0x39A3, 0x39A4, 0x39A5, 0x39A6, 0x39A7,
+ /* GB+82 31 83 30 */ 0x39A8, 0x39A9, 0x39AA, 0x39AB, 0x39AC,
+ /* GB+82 31 83 35 */ 0x39AD, 0x39AE, 0x39AF, 0x39B0, 0x39B1,
+ /* GB+82 31 84 30 */ 0x39B2, 0x39B3, 0x39B4, 0x39B5, 0x39B6,
+ /* GB+82 31 84 35 */ 0x39B7, 0x39B8, 0x39B9, 0x39BA, 0x39BB,
+ /* GB+82 31 85 30 */ 0x39BC, 0x39BD, 0x39BE, 0x39BF, 0x39C0,
+ /* GB+82 31 85 35 */ 0x39C1, 0x39C2, 0x39C3, 0x39C4, 0x39C5,
+ /* GB+82 31 86 30 */ 0x39C6, 0x39C7, 0x39C8, 0x39C9, 0x39CA,
+ /* GB+82 31 86 35 */ 0x39CB, 0x39CC, 0x39CD, 0x39CE, 0x39D1,
+ /* GB+82 31 87 30 */ 0x39D2, 0x39D3, 0x39D4, 0x39D5, 0x39D6,
+ /* GB+82 31 87 35 */ 0x39D7, 0x39D8, 0x39D9, 0x39DA, 0x39DB,
+ /* GB+82 31 88 30 */ 0x39DC, 0x39DD, 0x39DE, 0x39E0, 0x39E1,
+ /* GB+82 31 88 35 */ 0x39E2, 0x39E3, 0x39E4, 0x39E5, 0x39E6,
+ /* GB+82 31 89 30 */ 0x39E7, 0x39E8, 0x39E9, 0x39EA, 0x39EB,
+ /* GB+82 31 89 35 */ 0x39EC, 0x39ED, 0x39EE, 0x39EF, 0x39F0,
+ /* GB+82 31 8A 30 */ 0x39F1, 0x39F2, 0x39F3, 0x39F4, 0x39F5,
+ /* GB+82 31 8A 35 */ 0x39F6, 0x39F7, 0x39F8, 0x39F9, 0x39FA,
+ /* GB+82 31 8B 30 */ 0x39FB, 0x39FC, 0x39FD, 0x39FE, 0x39FF,
+ /* GB+82 31 8B 35 */ 0x3A00, 0x3A01, 0x3A02, 0x3A03, 0x3A04,
+ /* GB+82 31 8C 30 */ 0x3A05, 0x3A06, 0x3A07, 0x3A08, 0x3A09,
+ /* GB+82 31 8C 35 */ 0x3A0A, 0x3A0B, 0x3A0C, 0x3A0D, 0x3A0E,
+ /* GB+82 31 8D 30 */ 0x3A0F, 0x3A10, 0x3A11, 0x3A12, 0x3A13,
+ /* GB+82 31 8D 35 */ 0x3A14, 0x3A15, 0x3A16, 0x3A17, 0x3A18,
+ /* GB+82 31 8E 30 */ 0x3A19, 0x3A1A, 0x3A1B, 0x3A1C, 0x3A1D,
+ /* GB+82 31 8E 35 */ 0x3A1E, 0x3A1F, 0x3A20, 0x3A21, 0x3A22,
+ /* GB+82 31 8F 30 */ 0x3A23, 0x3A24, 0x3A25, 0x3A26, 0x3A27,
+ /* GB+82 31 8F 35 */ 0x3A28, 0x3A29, 0x3A2A, 0x3A2B, 0x3A2C,
+ /* GB+82 31 90 30 */ 0x3A2D, 0x3A2E, 0x3A2F, 0x3A30, 0x3A31,
+ /* GB+82 31 90 35 */ 0x3A32, 0x3A33, 0x3A34, 0x3A35, 0x3A36,
+ /* GB+82 31 91 30 */ 0x3A37, 0x3A38, 0x3A39, 0x3A3A, 0x3A3B,
+ /* GB+82 31 91 35 */ 0x3A3C, 0x3A3D, 0x3A3E, 0x3A3F, 0x3A40,
+ /* GB+82 31 92 30 */ 0x3A41, 0x3A42, 0x3A43, 0x3A44, 0x3A45,
+ /* GB+82 31 92 35 */ 0x3A46, 0x3A47, 0x3A48, 0x3A49, 0x3A4A,
+ /* GB+82 31 93 30 */ 0x3A4B, 0x3A4C, 0x3A4D, 0x3A4E, 0x3A4F,
+ /* GB+82 31 93 35 */ 0x3A50, 0x3A51, 0x3A52, 0x3A53, 0x3A54,
+ /* GB+82 31 94 30 */ 0x3A55, 0x3A56, 0x3A57, 0x3A58, 0x3A59,
+ /* GB+82 31 94 35 */ 0x3A5A, 0x3A5B, 0x3A5C, 0x3A5D, 0x3A5E,
+ /* GB+82 31 95 30 */ 0x3A5F, 0x3A60, 0x3A61, 0x3A62, 0x3A63,
+ /* GB+82 31 95 35 */ 0x3A64, 0x3A65, 0x3A66, 0x3A67, 0x3A68,
+ /* GB+82 31 96 30 */ 0x3A69, 0x3A6A, 0x3A6B, 0x3A6C, 0x3A6D,
+ /* GB+82 31 96 35 */ 0x3A6E, 0x3A6F, 0x3A70, 0x3A71, 0x3A72,
+ /* GB+82 31 97 30 */ 0x3A74, 0x3A75, 0x3A76, 0x3A77, 0x3A78,
+ /* GB+82 31 97 35 */ 0x3A79, 0x3A7A, 0x3A7B, 0x3A7C, 0x3A7D,
+ /* GB+82 31 98 30 */ 0x3A7E, 0x3A7F, 0x3A80, 0x3A81, 0x3A82,
+ /* GB+82 31 98 35 */ 0x3A83, 0x3A84, 0x3A85, 0x3A86, 0x3A87,
+ /* GB+82 31 99 30 */ 0x3A88, 0x3A89, 0x3A8A, 0x3A8B, 0x3A8C,
+ /* GB+82 31 99 35 */ 0x3A8D, 0x3A8E, 0x3A8F, 0x3A90, 0x3A91,
+ /* GB+82 31 9A 30 */ 0x3A92, 0x3A93, 0x3A94, 0x3A95, 0x3A96,
+ /* GB+82 31 9A 35 */ 0x3A97, 0x3A98, 0x3A99, 0x3A9A, 0x3A9B,
+ /* GB+82 31 9B 30 */ 0x3A9C, 0x3A9D, 0x3A9E, 0x3A9F, 0x3AA0,
+ /* GB+82 31 9B 35 */ 0x3AA1, 0x3AA2, 0x3AA3, 0x3AA4, 0x3AA5,
+ /* GB+82 31 9C 30 */ 0x3AA6, 0x3AA7, 0x3AA8, 0x3AA9, 0x3AAA,
+ /* GB+82 31 9C 35 */ 0x3AAB, 0x3AAC, 0x3AAD, 0x3AAE, 0x3AAF,
+ /* GB+82 31 9D 30 */ 0x3AB0, 0x3AB1, 0x3AB2, 0x3AB3, 0x3AB4,
+ /* GB+82 31 9D 35 */ 0x3AB5, 0x3AB6, 0x3AB7, 0x3AB8, 0x3AB9,
+ /* GB+82 31 9E 30 */ 0x3ABA, 0x3ABB, 0x3ABC, 0x3ABD, 0x3ABE,
+ /* GB+82 31 9E 35 */ 0x3ABF, 0x3AC0, 0x3AC1, 0x3AC2, 0x3AC3,
+ /* GB+82 31 9F 30 */ 0x3AC4, 0x3AC5, 0x3AC6, 0x3AC7, 0x3AC8,
+ /* GB+82 31 9F 35 */ 0x3AC9, 0x3ACA, 0x3ACB, 0x3ACC, 0x3ACD,
+ /* GB+82 31 A0 30 */ 0x3ACE, 0x3ACF, 0x3AD0, 0x3AD1, 0x3AD2,
+ /* GB+82 31 A0 35 */ 0x3AD3, 0x3AD4, 0x3AD5, 0x3AD6, 0x3AD7,
+ /* GB+82 31 A1 30 */ 0x3AD8, 0x3AD9, 0x3ADA, 0x3ADB, 0x3ADC,
+ /* GB+82 31 A1 35 */ 0x3ADD, 0x3ADE, 0x3ADF, 0x3AE0, 0x3AE1,
+ /* GB+82 31 A2 30 */ 0x3AE2, 0x3AE3, 0x3AE4, 0x3AE5, 0x3AE6,
+ /* GB+82 31 A2 35 */ 0x3AE7, 0x3AE8, 0x3AE9, 0x3AEA, 0x3AEB,
+ /* GB+82 31 A3 30 */ 0x3AEC, 0x3AED, 0x3AEE, 0x3AEF, 0x3AF0,
+ /* GB+82 31 A3 35 */ 0x3AF1, 0x3AF2, 0x3AF3, 0x3AF4, 0x3AF5,
+ /* GB+82 31 A4 30 */ 0x3AF6, 0x3AF7, 0x3AF8, 0x3AF9, 0x3AFA,
+ /* GB+82 31 A4 35 */ 0x3AFB, 0x3AFC, 0x3AFD, 0x3AFE, 0x3AFF,
+ /* GB+82 31 A5 30 */ 0x3B00, 0x3B01, 0x3B02, 0x3B03, 0x3B04,
+ /* GB+82 31 A5 35 */ 0x3B05, 0x3B06, 0x3B07, 0x3B08, 0x3B09,
+ /* GB+82 31 A6 30 */ 0x3B0A, 0x3B0B, 0x3B0C, 0x3B0D, 0x3B0E,
+ /* GB+82 31 A6 35 */ 0x3B0F, 0x3B10, 0x3B11, 0x3B12, 0x3B13,
+ /* GB+82 31 A7 30 */ 0x3B14, 0x3B15, 0x3B16, 0x3B17, 0x3B18,
+ /* GB+82 31 A7 35 */ 0x3B19, 0x3B1A, 0x3B1B, 0x3B1C, 0x3B1D,
+ /* GB+82 31 A8 30 */ 0x3B1E, 0x3B1F, 0x3B20, 0x3B21, 0x3B22,
+ /* GB+82 31 A8 35 */ 0x3B23, 0x3B24, 0x3B25, 0x3B26, 0x3B27,
+ /* GB+82 31 A9 30 */ 0x3B28, 0x3B29, 0x3B2A, 0x3B2B, 0x3B2C,
+ /* GB+82 31 A9 35 */ 0x3B2D, 0x3B2E, 0x3B2F, 0x3B30, 0x3B31,
+ /* GB+82 31 AA 30 */ 0x3B32, 0x3B33, 0x3B34, 0x3B35, 0x3B36,
+ /* GB+82 31 AA 35 */ 0x3B37, 0x3B38, 0x3B39, 0x3B3A, 0x3B3B,
+ /* GB+82 31 AB 30 */ 0x3B3C, 0x3B3D, 0x3B3E, 0x3B3F, 0x3B40,
+ /* GB+82 31 AB 35 */ 0x3B41, 0x3B42, 0x3B43, 0x3B44, 0x3B45,
+ /* GB+82 31 AC 30 */ 0x3B46, 0x3B47, 0x3B48, 0x3B49, 0x3B4A,
+ /* GB+82 31 AC 35 */ 0x3B4B, 0x3B4C, 0x3B4D, 0x3B4F, 0x3B50,
+ /* GB+82 31 AD 30 */ 0x3B51, 0x3B52, 0x3B53, 0x3B54, 0x3B55,
+ /* GB+82 31 AD 35 */ 0x3B56, 0x3B57, 0x3B58, 0x3B59, 0x3B5A,
+ /* GB+82 31 AE 30 */ 0x3B5B, 0x3B5C, 0x3B5D, 0x3B5E, 0x3B5F,
+ /* GB+82 31 AE 35 */ 0x3B60, 0x3B61, 0x3B62, 0x3B63, 0x3B64,
+ /* GB+82 31 AF 30 */ 0x3B65, 0x3B66, 0x3B67, 0x3B68, 0x3B69,
+ /* GB+82 31 AF 35 */ 0x3B6A, 0x3B6B, 0x3B6C, 0x3B6D, 0x3B6E,
+ /* GB+82 31 B0 30 */ 0x3B6F, 0x3B70, 0x3B71, 0x3B72, 0x3B73,
+ /* GB+82 31 B0 35 */ 0x3B74, 0x3B75, 0x3B76, 0x3B77, 0x3B78,
+ /* GB+82 31 B1 30 */ 0x3B79, 0x3B7A, 0x3B7B, 0x3B7C, 0x3B7D,
+ /* GB+82 31 B1 35 */ 0x3B7E, 0x3B7F, 0x3B80, 0x3B81, 0x3B82,
+ /* GB+82 31 B2 30 */ 0x3B83, 0x3B84, 0x3B85, 0x3B86, 0x3B87,
+ /* GB+82 31 B2 35 */ 0x3B88, 0x3B89, 0x3B8A, 0x3B8B, 0x3B8C,
+ /* GB+82 31 B3 30 */ 0x3B8D, 0x3B8E, 0x3B8F, 0x3B90, 0x3B91,
+ /* GB+82 31 B3 35 */ 0x3B92, 0x3B93, 0x3B94, 0x3B95, 0x3B96,
+ /* GB+82 31 B4 30 */ 0x3B97, 0x3B98, 0x3B99, 0x3B9A, 0x3B9B,
+ /* GB+82 31 B4 35 */ 0x3B9C, 0x3B9D, 0x3B9E, 0x3B9F, 0x3BA0,
+ /* GB+82 31 B5 30 */ 0x3BA1, 0x3BA2, 0x3BA3, 0x3BA4, 0x3BA5,
+ /* GB+82 31 B5 35 */ 0x3BA6, 0x3BA7, 0x3BA8, 0x3BA9, 0x3BAA,
+ /* GB+82 31 B6 30 */ 0x3BAB, 0x3BAC, 0x3BAD, 0x3BAE, 0x3BAF,
+ /* GB+82 31 B6 35 */ 0x3BB0, 0x3BB1, 0x3BB2, 0x3BB3, 0x3BB4,
+ /* GB+82 31 B7 30 */ 0x3BB5, 0x3BB6, 0x3BB7, 0x3BB8, 0x3BB9,
+ /* GB+82 31 B7 35 */ 0x3BBA, 0x3BBB, 0x3BBC, 0x3BBD, 0x3BBE,
+ /* GB+82 31 B8 30 */ 0x3BBF, 0x3BC0, 0x3BC1, 0x3BC2, 0x3BC3,
+ /* GB+82 31 B8 35 */ 0x3BC4, 0x3BC5, 0x3BC6, 0x3BC7, 0x3BC8,
+ /* GB+82 31 B9 30 */ 0x3BC9, 0x3BCA, 0x3BCB, 0x3BCC, 0x3BCD,
+ /* GB+82 31 B9 35 */ 0x3BCE, 0x3BCF, 0x3BD0, 0x3BD1, 0x3BD2,
+ /* GB+82 31 BA 30 */ 0x3BD3, 0x3BD4, 0x3BD5, 0x3BD6, 0x3BD7,
+ /* GB+82 31 BA 35 */ 0x3BD8, 0x3BD9, 0x3BDA, 0x3BDB, 0x3BDC,
+ /* GB+82 31 BB 30 */ 0x3BDD, 0x3BDE, 0x3BDF, 0x3BE0, 0x3BE1,
+ /* GB+82 31 BB 35 */ 0x3BE2, 0x3BE3, 0x3BE4, 0x3BE5, 0x3BE6,
+ /* GB+82 31 BC 30 */ 0x3BE7, 0x3BE8, 0x3BE9, 0x3BEA, 0x3BEB,
+ /* GB+82 31 BC 35 */ 0x3BEC, 0x3BED, 0x3BEE, 0x3BEF, 0x3BF0,
+ /* GB+82 31 BD 30 */ 0x3BF1, 0x3BF2, 0x3BF3, 0x3BF4, 0x3BF5,
+ /* GB+82 31 BD 35 */ 0x3BF6, 0x3BF7, 0x3BF8, 0x3BF9, 0x3BFA,
+ /* GB+82 31 BE 30 */ 0x3BFB, 0x3BFC, 0x3BFD, 0x3BFE, 0x3BFF,
+ /* GB+82 31 BE 35 */ 0x3C00, 0x3C01, 0x3C02, 0x3C03, 0x3C04,
+ /* GB+82 31 BF 30 */ 0x3C05, 0x3C06, 0x3C07, 0x3C08, 0x3C09,
+ /* GB+82 31 BF 35 */ 0x3C0A, 0x3C0B, 0x3C0C, 0x3C0D, 0x3C0E,
+ /* GB+82 31 C0 30 */ 0x3C0F, 0x3C10, 0x3C11, 0x3C12, 0x3C13,
+ /* GB+82 31 C0 35 */ 0x3C14, 0x3C15, 0x3C16, 0x3C17, 0x3C18,
+ /* GB+82 31 C1 30 */ 0x3C19, 0x3C1A, 0x3C1B, 0x3C1C, 0x3C1D,
+ /* GB+82 31 C1 35 */ 0x3C1E, 0x3C1F, 0x3C20, 0x3C21, 0x3C22,
+ /* GB+82 31 C2 30 */ 0x3C23, 0x3C24, 0x3C25, 0x3C26, 0x3C27,
+ /* GB+82 31 C2 35 */ 0x3C28, 0x3C29, 0x3C2A, 0x3C2B, 0x3C2C,
+ /* GB+82 31 C3 30 */ 0x3C2D, 0x3C2E, 0x3C2F, 0x3C30, 0x3C31,
+ /* GB+82 31 C3 35 */ 0x3C32, 0x3C33, 0x3C34, 0x3C35, 0x3C36,
+ /* GB+82 31 C4 30 */ 0x3C37, 0x3C38, 0x3C39, 0x3C3A, 0x3C3B,
+ /* GB+82 31 C4 35 */ 0x3C3C, 0x3C3D, 0x3C3E, 0x3C3F, 0x3C40,
+ /* GB+82 31 C5 30 */ 0x3C41, 0x3C42, 0x3C43, 0x3C44, 0x3C45,
+ /* GB+82 31 C5 35 */ 0x3C46, 0x3C47, 0x3C48, 0x3C49, 0x3C4A,
+ /* GB+82 31 C6 30 */ 0x3C4B, 0x3C4C, 0x3C4D, 0x3C4E, 0x3C4F,
+ /* GB+82 31 C6 35 */ 0x3C50, 0x3C51, 0x3C52, 0x3C53, 0x3C54,
+ /* GB+82 31 C7 30 */ 0x3C55, 0x3C56, 0x3C57, 0x3C58, 0x3C59,
+ /* GB+82 31 C7 35 */ 0x3C5A, 0x3C5B, 0x3C5C, 0x3C5D, 0x3C5E,
+ /* GB+82 31 C8 30 */ 0x3C5F, 0x3C60, 0x3C61, 0x3C62, 0x3C63,
+ /* GB+82 31 C8 35 */ 0x3C64, 0x3C65, 0x3C66, 0x3C67, 0x3C68,
+ /* GB+82 31 C9 30 */ 0x3C69, 0x3C6A, 0x3C6B, 0x3C6C, 0x3C6D,
+ /* GB+82 31 C9 35 */ 0x3C6F, 0x3C70, 0x3C71, 0x3C72, 0x3C73,
+ /* GB+82 31 CA 30 */ 0x3C74, 0x3C75, 0x3C76, 0x3C77, 0x3C78,
+ /* GB+82 31 CA 35 */ 0x3C79, 0x3C7A, 0x3C7B, 0x3C7C, 0x3C7D,
+ /* GB+82 31 CB 30 */ 0x3C7E, 0x3C7F, 0x3C80, 0x3C81, 0x3C82,
+ /* GB+82 31 CB 35 */ 0x3C83, 0x3C84, 0x3C85, 0x3C86, 0x3C87,
+ /* GB+82 31 CC 30 */ 0x3C88, 0x3C89, 0x3C8A, 0x3C8B, 0x3C8C,
+ /* GB+82 31 CC 35 */ 0x3C8D, 0x3C8E, 0x3C8F, 0x3C90, 0x3C91,
+ /* GB+82 31 CD 30 */ 0x3C92, 0x3C93, 0x3C94, 0x3C95, 0x3C96,
+ /* GB+82 31 CD 35 */ 0x3C97, 0x3C98, 0x3C99, 0x3C9A, 0x3C9B,
+ /* GB+82 31 CE 30 */ 0x3C9C, 0x3C9D, 0x3C9E, 0x3C9F, 0x3CA0,
+ /* GB+82 31 CE 35 */ 0x3CA1, 0x3CA2, 0x3CA3, 0x3CA4, 0x3CA5,
+ /* GB+82 31 CF 30 */ 0x3CA6, 0x3CA7, 0x3CA8, 0x3CA9, 0x3CAA,
+ /* GB+82 31 CF 35 */ 0x3CAB, 0x3CAC, 0x3CAD, 0x3CAE, 0x3CAF,
+ /* GB+82 31 D0 30 */ 0x3CB0, 0x3CB1, 0x3CB2, 0x3CB3, 0x3CB4,
+ /* GB+82 31 D0 35 */ 0x3CB5, 0x3CB6, 0x3CB7, 0x3CB8, 0x3CB9,
+ /* GB+82 31 D1 30 */ 0x3CBA, 0x3CBB, 0x3CBC, 0x3CBD, 0x3CBE,
+ /* GB+82 31 D1 35 */ 0x3CBF, 0x3CC0, 0x3CC1, 0x3CC2, 0x3CC3,
+ /* GB+82 31 D2 30 */ 0x3CC4, 0x3CC5, 0x3CC6, 0x3CC7, 0x3CC8,
+ /* GB+82 31 D2 35 */ 0x3CC9, 0x3CCA, 0x3CCB, 0x3CCC, 0x3CCD,
+ /* GB+82 31 D3 30 */ 0x3CCE, 0x3CCF, 0x3CD0, 0x3CD1, 0x3CD2,
+ /* GB+82 31 D3 35 */ 0x3CD3, 0x3CD4, 0x3CD5, 0x3CD6, 0x3CD7,
+ /* GB+82 31 D4 30 */ 0x3CD8, 0x3CD9, 0x3CDA, 0x3CDB, 0x3CDC,
+ /* GB+82 31 D4 35 */ 0x3CDD, 0x3CDE, 0x3CDF,
+ /* Contiguous area: GB+82 32 AF 33 .. GB+82 32 C9 36 */
+ /* GB+82 32 AF 33 */ 0x4057, 0x4058,
+ /* GB+82 32 AF 35 */ 0x4059, 0x405A, 0x405B, 0x405C, 0x405D,
+ /* GB+82 32 B0 30 */ 0x405E, 0x405F, 0x4060, 0x4061, 0x4062,
+ /* GB+82 32 B0 35 */ 0x4063, 0x4064, 0x4065, 0x4066, 0x4067,
+ /* GB+82 32 B1 30 */ 0x4068, 0x4069, 0x406A, 0x406B, 0x406C,
+ /* GB+82 32 B1 35 */ 0x406D, 0x406E, 0x406F, 0x4070, 0x4071,
+ /* GB+82 32 B2 30 */ 0x4072, 0x4073, 0x4074, 0x4075, 0x4076,
+ /* GB+82 32 B2 35 */ 0x4077, 0x4078, 0x4079, 0x407A, 0x407B,
+ /* GB+82 32 B3 30 */ 0x407C, 0x407D, 0x407E, 0x407F, 0x4080,
+ /* GB+82 32 B3 35 */ 0x4081, 0x4082, 0x4083, 0x4084, 0x4085,
+ /* GB+82 32 B4 30 */ 0x4086, 0x4087, 0x4088, 0x4089, 0x408A,
+ /* GB+82 32 B4 35 */ 0x408B, 0x408C, 0x408D, 0x408E, 0x408F,
+ /* GB+82 32 B5 30 */ 0x4090, 0x4091, 0x4092, 0x4093, 0x4094,
+ /* GB+82 32 B5 35 */ 0x4095, 0x4096, 0x4097, 0x4098, 0x4099,
+ /* GB+82 32 B6 30 */ 0x409A, 0x409B, 0x409C, 0x409D, 0x409E,
+ /* GB+82 32 B6 35 */ 0x409F, 0x40A0, 0x40A1, 0x40A2, 0x40A3,
+ /* GB+82 32 B7 30 */ 0x40A4, 0x40A5, 0x40A6, 0x40A7, 0x40A8,
+ /* GB+82 32 B7 35 */ 0x40A9, 0x40AA, 0x40AB, 0x40AC, 0x40AD,
+ /* GB+82 32 B8 30 */ 0x40AE, 0x40AF, 0x40B0, 0x40B1, 0x40B2,
+ /* GB+82 32 B8 35 */ 0x40B3, 0x40B4, 0x40B5, 0x40B6, 0x40B7,
+ /* GB+82 32 B9 30 */ 0x40B8, 0x40B9, 0x40BA, 0x40BB, 0x40BC,
+ /* GB+82 32 B9 35 */ 0x40BD, 0x40BE, 0x40BF, 0x40C0, 0x40C1,
+ /* GB+82 32 BA 30 */ 0x40C2, 0x40C3, 0x40C4, 0x40C5, 0x40C6,
+ /* GB+82 32 BA 35 */ 0x40C7, 0x40C8, 0x40C9, 0x40CA, 0x40CB,
+ /* GB+82 32 BB 30 */ 0x40CC, 0x40CD, 0x40CE, 0x40CF, 0x40D0,
+ /* GB+82 32 BB 35 */ 0x40D1, 0x40D2, 0x40D3, 0x40D4, 0x40D5,
+ /* GB+82 32 BC 30 */ 0x40D6, 0x40D7, 0x40D8, 0x40D9, 0x40DA,
+ /* GB+82 32 BC 35 */ 0x40DB, 0x40DC, 0x40DD, 0x40DE, 0x40DF,
+ /* GB+82 32 BD 30 */ 0x40E0, 0x40E1, 0x40E2, 0x40E3, 0x40E4,
+ /* GB+82 32 BD 35 */ 0x40E5, 0x40E6, 0x40E7, 0x40E8, 0x40E9,
+ /* GB+82 32 BE 30 */ 0x40EA, 0x40EB, 0x40EC, 0x40ED, 0x40EE,
+ /* GB+82 32 BE 35 */ 0x40EF, 0x40F0, 0x40F1, 0x40F2, 0x40F3,
+ /* GB+82 32 BF 30 */ 0x40F4, 0x40F5, 0x40F6, 0x40F7, 0x40F8,
+ /* GB+82 32 BF 35 */ 0x40F9, 0x40FA, 0x40FB, 0x40FC, 0x40FD,
+ /* GB+82 32 C0 30 */ 0x40FE, 0x40FF, 0x4100, 0x4101, 0x4102,
+ /* GB+82 32 C0 35 */ 0x4103, 0x4104, 0x4105, 0x4106, 0x4107,
+ /* GB+82 32 C1 30 */ 0x4108, 0x4109, 0x410A, 0x410B, 0x410C,
+ /* GB+82 32 C1 35 */ 0x410D, 0x410E, 0x410F, 0x4110, 0x4111,
+ /* GB+82 32 C2 30 */ 0x4112, 0x4113, 0x4114, 0x4115, 0x4116,
+ /* GB+82 32 C2 35 */ 0x4117, 0x4118, 0x4119, 0x411A, 0x411B,
+ /* GB+82 32 C3 30 */ 0x411C, 0x411D, 0x411E, 0x411F, 0x4120,
+ /* GB+82 32 C3 35 */ 0x4121, 0x4122, 0x4123, 0x4124, 0x4125,
+ /* GB+82 32 C4 30 */ 0x4126, 0x4127, 0x4128, 0x4129, 0x412A,
+ /* GB+82 32 C4 35 */ 0x412B, 0x412C, 0x412D, 0x412E, 0x412F,
+ /* GB+82 32 C5 30 */ 0x4130, 0x4131, 0x4132, 0x4133, 0x4134,
+ /* GB+82 32 C5 35 */ 0x4135, 0x4136, 0x4137, 0x4138, 0x4139,
+ /* GB+82 32 C6 30 */ 0x413A, 0x413B, 0x413C, 0x413D, 0x413E,
+ /* GB+82 32 C6 35 */ 0x413F, 0x4140, 0x4141, 0x4142, 0x4143,
+ /* GB+82 32 C7 30 */ 0x4144, 0x4145, 0x4146, 0x4147, 0x4148,
+ /* GB+82 32 C7 35 */ 0x4149, 0x414A, 0x414B, 0x414C, 0x414D,
+ /* GB+82 32 C8 30 */ 0x414E, 0x414F, 0x4150, 0x4151, 0x4152,
+ /* GB+82 32 C8 35 */ 0x4153, 0x4154, 0x4155, 0x4156, 0x4157,
+ /* GB+82 32 C9 30 */ 0x4158, 0x4159, 0x415A, 0x415B, 0x415C,
+ /* GB+82 32 C9 35 */ 0x415D, 0x415E,
+ /* Contiguous area: GB+82 32 F8 38 .. GB+82 33 A3 38 */
+ /* GB+82 32 F8 38 */ 0x4338, 0x4339,
+ /* GB+82 32 F9 30 */ 0x433A, 0x433B, 0x433C, 0x433D, 0x433E,
+ /* GB+82 32 F9 35 */ 0x433F, 0x4340, 0x4341, 0x4342, 0x4343,
+ /* GB+82 32 FA 30 */ 0x4344, 0x4345, 0x4346, 0x4347, 0x4348,
+ /* GB+82 32 FA 35 */ 0x4349, 0x434A, 0x434B, 0x434C, 0x434D,
+ /* GB+82 32 FB 30 */ 0x434E, 0x434F, 0x4350, 0x4351, 0x4352,
+ /* GB+82 32 FB 35 */ 0x4353, 0x4354, 0x4355, 0x4356, 0x4357,
+ /* GB+82 32 FC 30 */ 0x4358, 0x4359, 0x435A, 0x435B, 0x435C,
+ /* GB+82 32 FC 35 */ 0x435D, 0x435E, 0x435F, 0x4360, 0x4361,
+ /* GB+82 32 FD 30 */ 0x4362, 0x4363, 0x4364, 0x4365, 0x4366,
+ /* GB+82 32 FD 35 */ 0x4367, 0x4368, 0x4369, 0x436A, 0x436B,
+ /* GB+82 32 FE 30 */ 0x436C, 0x436D, 0x436E, 0x436F, 0x4370,
+ /* GB+82 32 FE 35 */ 0x4371, 0x4372, 0x4373, 0x4374, 0x4375,
+ /* GB+82 33 81 30 */ 0x4376, 0x4377, 0x4378, 0x4379, 0x437A,
+ /* GB+82 33 81 35 */ 0x437B, 0x437C, 0x437D, 0x437E, 0x437F,
+ /* GB+82 33 82 30 */ 0x4380, 0x4381, 0x4382, 0x4383, 0x4384,
+ /* GB+82 33 82 35 */ 0x4385, 0x4386, 0x4387, 0x4388, 0x4389,
+ /* GB+82 33 83 30 */ 0x438A, 0x438B, 0x438C, 0x438D, 0x438E,
+ /* GB+82 33 83 35 */ 0x438F, 0x4390, 0x4391, 0x4392, 0x4393,
+ /* GB+82 33 84 30 */ 0x4394, 0x4395, 0x4396, 0x4397, 0x4398,
+ /* GB+82 33 84 35 */ 0x4399, 0x439A, 0x439B, 0x439C, 0x439D,
+ /* GB+82 33 85 30 */ 0x439E, 0x439F, 0x43A0, 0x43A1, 0x43A2,
+ /* GB+82 33 85 35 */ 0x43A3, 0x43A4, 0x43A5, 0x43A6, 0x43A7,
+ /* GB+82 33 86 30 */ 0x43A8, 0x43A9, 0x43AA, 0x43AB, 0x43AD,
+ /* GB+82 33 86 35 */ 0x43AE, 0x43AF, 0x43B0, 0x43B2, 0x43B3,
+ /* GB+82 33 87 30 */ 0x43B4, 0x43B5, 0x43B6, 0x43B7, 0x43B8,
+ /* GB+82 33 87 35 */ 0x43B9, 0x43BA, 0x43BB, 0x43BC, 0x43BD,
+ /* GB+82 33 88 30 */ 0x43BE, 0x43BF, 0x43C0, 0x43C1, 0x43C2,
+ /* GB+82 33 88 35 */ 0x43C3, 0x43C4, 0x43C5, 0x43C6, 0x43C7,
+ /* GB+82 33 89 30 */ 0x43C8, 0x43C9, 0x43CA, 0x43CB, 0x43CC,
+ /* GB+82 33 89 35 */ 0x43CD, 0x43CE, 0x43CF, 0x43D0, 0x43D1,
+ /* GB+82 33 8A 30 */ 0x43D2, 0x43D3, 0x43D4, 0x43D5, 0x43D6,
+ /* GB+82 33 8A 35 */ 0x43D7, 0x43D8, 0x43D9, 0x43DA, 0x43DB,
+ /* GB+82 33 8B 30 */ 0x43DC, 0x43DE, 0x43DF, 0x43E0, 0x43E1,
+ /* GB+82 33 8B 35 */ 0x43E2, 0x43E3, 0x43E4, 0x43E5, 0x43E6,
+ /* GB+82 33 8C 30 */ 0x43E7, 0x43E8, 0x43E9, 0x43EA, 0x43EB,
+ /* GB+82 33 8C 35 */ 0x43EC, 0x43ED, 0x43EE, 0x43EF, 0x43F0,
+ /* GB+82 33 8D 30 */ 0x43F1, 0x43F2, 0x43F3, 0x43F4, 0x43F5,
+ /* GB+82 33 8D 35 */ 0x43F6, 0x43F7, 0x43F8, 0x43F9, 0x43FA,
+ /* GB+82 33 8E 30 */ 0x43FB, 0x43FC, 0x43FD, 0x43FE, 0x43FF,
+ /* GB+82 33 8E 35 */ 0x4400, 0x4401, 0x4402, 0x4403, 0x4404,
+ /* GB+82 33 8F 30 */ 0x4405, 0x4406, 0x4407, 0x4408, 0x4409,
+ /* GB+82 33 8F 35 */ 0x440A, 0x440B, 0x440C, 0x440D, 0x440E,
+ /* GB+82 33 90 30 */ 0x440F, 0x4410, 0x4411, 0x4412, 0x4413,
+ /* GB+82 33 90 35 */ 0x4414, 0x4415, 0x4416, 0x4417, 0x4418,
+ /* GB+82 33 91 30 */ 0x4419, 0x441A, 0x441B, 0x441C, 0x441D,
+ /* GB+82 33 91 35 */ 0x441E, 0x441F, 0x4420, 0x4421, 0x4422,
+ /* GB+82 33 92 30 */ 0x4423, 0x4424, 0x4425, 0x4426, 0x4427,
+ /* GB+82 33 92 35 */ 0x4428, 0x4429, 0x442A, 0x442B, 0x442C,
+ /* GB+82 33 93 30 */ 0x442D, 0x442E, 0x442F, 0x4430, 0x4431,
+ /* GB+82 33 93 35 */ 0x4432, 0x4433, 0x4434, 0x4435, 0x4436,
+ /* GB+82 33 94 30 */ 0x4437, 0x4438, 0x4439, 0x443A, 0x443B,
+ /* GB+82 33 94 35 */ 0x443C, 0x443D, 0x443E, 0x443F, 0x4440,
+ /* GB+82 33 95 30 */ 0x4441, 0x4442, 0x4443, 0x4444, 0x4445,
+ /* GB+82 33 95 35 */ 0x4446, 0x4447, 0x4448, 0x4449, 0x444A,
+ /* GB+82 33 96 30 */ 0x444B, 0x444C, 0x444D, 0x444E, 0x444F,
+ /* GB+82 33 96 35 */ 0x4450, 0x4451, 0x4452, 0x4453, 0x4454,
+ /* GB+82 33 97 30 */ 0x4455, 0x4456, 0x4457, 0x4458, 0x4459,
+ /* GB+82 33 97 35 */ 0x445A, 0x445B, 0x445C, 0x445D, 0x445E,
+ /* GB+82 33 98 30 */ 0x445F, 0x4460, 0x4461, 0x4462, 0x4463,
+ /* GB+82 33 98 35 */ 0x4464, 0x4465, 0x4466, 0x4467, 0x4468,
+ /* GB+82 33 99 30 */ 0x4469, 0x446A, 0x446B, 0x446C, 0x446D,
+ /* GB+82 33 99 35 */ 0x446E, 0x446F, 0x4470, 0x4471, 0x4472,
+ /* GB+82 33 9A 30 */ 0x4473, 0x4474, 0x4475, 0x4476, 0x4477,
+ /* GB+82 33 9A 35 */ 0x4478, 0x4479, 0x447A, 0x447B, 0x447C,
+ /* GB+82 33 9B 30 */ 0x447D, 0x447E, 0x447F, 0x4480, 0x4481,
+ /* GB+82 33 9B 35 */ 0x4482, 0x4483, 0x4484, 0x4485, 0x4486,
+ /* GB+82 33 9C 30 */ 0x4487, 0x4488, 0x4489, 0x448A, 0x448B,
+ /* GB+82 33 9C 35 */ 0x448C, 0x448D, 0x448E, 0x448F, 0x4490,
+ /* GB+82 33 9D 30 */ 0x4491, 0x4492, 0x4493, 0x4494, 0x4495,
+ /* GB+82 33 9D 35 */ 0x4496, 0x4497, 0x4498, 0x4499, 0x449A,
+ /* GB+82 33 9E 30 */ 0x449B, 0x449C, 0x449D, 0x449E, 0x449F,
+ /* GB+82 33 9E 35 */ 0x44A0, 0x44A1, 0x44A2, 0x44A3, 0x44A4,
+ /* GB+82 33 9F 30 */ 0x44A5, 0x44A6, 0x44A7, 0x44A8, 0x44A9,
+ /* GB+82 33 9F 35 */ 0x44AA, 0x44AB, 0x44AC, 0x44AD, 0x44AE,
+ /* GB+82 33 A0 30 */ 0x44AF, 0x44B0, 0x44B1, 0x44B2, 0x44B3,
+ /* GB+82 33 A0 35 */ 0x44B4, 0x44B5, 0x44B6, 0x44B7, 0x44B8,
+ /* GB+82 33 A1 30 */ 0x44B9, 0x44BA, 0x44BB, 0x44BC, 0x44BD,
+ /* GB+82 33 A1 35 */ 0x44BE, 0x44BF, 0x44C0, 0x44C1, 0x44C2,
+ /* GB+82 33 A2 30 */ 0x44C3, 0x44C4, 0x44C5, 0x44C6, 0x44C7,
+ /* GB+82 33 A2 35 */ 0x44C8, 0x44C9, 0x44CA, 0x44CB, 0x44CC,
+ /* GB+82 33 A3 30 */ 0x44CD, 0x44CE, 0x44CF, 0x44D0, 0x44D1,
+ /* GB+82 33 A3 35 */ 0x44D2, 0x44D3, 0x44D4, 0x44D5,
+ /* Contiguous area: GB+82 33 C9 32 .. GB+82 33 E8 37 */
+ /* GB+82 33 C9 32 */ 0x464D, 0x464E, 0x464F,
+ /* GB+82 33 C9 35 */ 0x4650, 0x4651, 0x4652, 0x4653, 0x4654,
+ /* GB+82 33 CA 30 */ 0x4655, 0x4656, 0x4657, 0x4658, 0x4659,
+ /* GB+82 33 CA 35 */ 0x465A, 0x465B, 0x465C, 0x465D, 0x465E,
+ /* GB+82 33 CB 30 */ 0x465F, 0x4660, 0x4662, 0x4663, 0x4664,
+ /* GB+82 33 CB 35 */ 0x4665, 0x4666, 0x4667, 0x4668, 0x4669,
+ /* GB+82 33 CC 30 */ 0x466A, 0x466B, 0x466C, 0x466D, 0x466E,
+ /* GB+82 33 CC 35 */ 0x466F, 0x4670, 0x4671, 0x4672, 0x4673,
+ /* GB+82 33 CD 30 */ 0x4674, 0x4675, 0x4676, 0x4677, 0x4678,
+ /* GB+82 33 CD 35 */ 0x4679, 0x467A, 0x467B, 0x467C, 0x467D,
+ /* GB+82 33 CE 30 */ 0x467E, 0x467F, 0x4680, 0x4681, 0x4682,
+ /* GB+82 33 CE 35 */ 0x4683, 0x4684, 0x4685, 0x4686, 0x4687,
+ /* GB+82 33 CF 30 */ 0x4688, 0x4689, 0x468A, 0x468B, 0x468C,
+ /* GB+82 33 CF 35 */ 0x468D, 0x468E, 0x468F, 0x4690, 0x4691,
+ /* GB+82 33 D0 30 */ 0x4692, 0x4693, 0x4694, 0x4695, 0x4696,
+ /* GB+82 33 D0 35 */ 0x4697, 0x4698, 0x4699, 0x469A, 0x469B,
+ /* GB+82 33 D1 30 */ 0x469C, 0x469D, 0x469E, 0x469F, 0x46A0,
+ /* GB+82 33 D1 35 */ 0x46A1, 0x46A2, 0x46A3, 0x46A4, 0x46A5,
+ /* GB+82 33 D2 30 */ 0x46A6, 0x46A7, 0x46A8, 0x46A9, 0x46AA,
+ /* GB+82 33 D2 35 */ 0x46AB, 0x46AC, 0x46AD, 0x46AE, 0x46AF,
+ /* GB+82 33 D3 30 */ 0x46B0, 0x46B1, 0x46B2, 0x46B3, 0x46B4,
+ /* GB+82 33 D3 35 */ 0x46B5, 0x46B6, 0x46B7, 0x46B8, 0x46B9,
+ /* GB+82 33 D4 30 */ 0x46BA, 0x46BB, 0x46BC, 0x46BD, 0x46BE,
+ /* GB+82 33 D4 35 */ 0x46BF, 0x46C0, 0x46C1, 0x46C2, 0x46C3,
+ /* GB+82 33 D5 30 */ 0x46C4, 0x46C5, 0x46C6, 0x46C7, 0x46C8,
+ /* GB+82 33 D5 35 */ 0x46C9, 0x46CA, 0x46CB, 0x46CC, 0x46CD,
+ /* GB+82 33 D6 30 */ 0x46CE, 0x46CF, 0x46D0, 0x46D1, 0x46D2,
+ /* GB+82 33 D6 35 */ 0x46D3, 0x46D4, 0x46D5, 0x46D6, 0x46D7,
+ /* GB+82 33 D7 30 */ 0x46D8, 0x46D9, 0x46DA, 0x46DB, 0x46DC,
+ /* GB+82 33 D7 35 */ 0x46DD, 0x46DE, 0x46DF, 0x46E0, 0x46E1,
+ /* GB+82 33 D8 30 */ 0x46E2, 0x46E3, 0x46E4, 0x46E5, 0x46E6,
+ /* GB+82 33 D8 35 */ 0x46E7, 0x46E8, 0x46E9, 0x46EA, 0x46EB,
+ /* GB+82 33 D9 30 */ 0x46EC, 0x46ED, 0x46EE, 0x46EF, 0x46F0,
+ /* GB+82 33 D9 35 */ 0x46F1, 0x46F2, 0x46F3, 0x46F4, 0x46F5,
+ /* GB+82 33 DA 30 */ 0x46F6, 0x46F7, 0x46F8, 0x46F9, 0x46FA,
+ /* GB+82 33 DA 35 */ 0x46FB, 0x46FC, 0x46FD, 0x46FE, 0x46FF,
+ /* GB+82 33 DB 30 */ 0x4700, 0x4701, 0x4702, 0x4703, 0x4704,
+ /* GB+82 33 DB 35 */ 0x4705, 0x4706, 0x4707, 0x4708, 0x4709,
+ /* GB+82 33 DC 30 */ 0x470A, 0x470B, 0x470C, 0x470D, 0x470E,
+ /* GB+82 33 DC 35 */ 0x470F, 0x4710, 0x4711, 0x4712, 0x4713,
+ /* GB+82 33 DD 30 */ 0x4714, 0x4715, 0x4716, 0x4717, 0x4718,
+ /* GB+82 33 DD 35 */ 0x4719, 0x471A, 0x471B, 0x471C, 0x471D,
+ /* GB+82 33 DE 30 */ 0x471E, 0x471F, 0x4720, 0x4721, 0x4722,
+ /* GB+82 33 DE 35 */ 0x4724, 0x4725, 0x4726, 0x4727, 0x4728,
+ /* GB+82 33 DF 30 */ 0x472A, 0x472B, 0x472C, 0x472D, 0x472E,
+ /* GB+82 33 DF 35 */ 0x472F, 0x4730, 0x4731, 0x4732, 0x4733,
+ /* GB+82 33 E0 30 */ 0x4734, 0x4735, 0x4736, 0x4737, 0x4738,
+ /* GB+82 33 E0 35 */ 0x4739, 0x473A, 0x473B, 0x473C, 0x473D,
+ /* GB+82 33 E1 30 */ 0x473E, 0x473F, 0x4740, 0x4741, 0x4742,
+ /* GB+82 33 E1 35 */ 0x4743, 0x4744, 0x4745, 0x4746, 0x4747,
+ /* GB+82 33 E2 30 */ 0x4748, 0x4749, 0x474A, 0x474B, 0x474C,
+ /* GB+82 33 E2 35 */ 0x474D, 0x474E, 0x474F, 0x4750, 0x4751,
+ /* GB+82 33 E3 30 */ 0x4752, 0x4753, 0x4754, 0x4755, 0x4756,
+ /* GB+82 33 E3 35 */ 0x4757, 0x4758, 0x4759, 0x475A, 0x475B,
+ /* GB+82 33 E4 30 */ 0x475C, 0x475D, 0x475E, 0x475F, 0x4760,
+ /* GB+82 33 E4 35 */ 0x4761, 0x4762, 0x4763, 0x4764, 0x4765,
+ /* GB+82 33 E5 30 */ 0x4766, 0x4767, 0x4768, 0x4769, 0x476A,
+ /* GB+82 33 E5 35 */ 0x476B, 0x476C, 0x476D, 0x476E, 0x476F,
+ /* GB+82 33 E6 30 */ 0x4770, 0x4771, 0x4772, 0x4773, 0x4774,
+ /* GB+82 33 E6 35 */ 0x4775, 0x4776, 0x4777, 0x4778, 0x4779,
+ /* GB+82 33 E7 30 */ 0x477A, 0x477B, 0x477D, 0x477E, 0x477F,
+ /* GB+82 33 E7 35 */ 0x4780, 0x4781, 0x4782, 0x4783, 0x4784,
+ /* GB+82 33 E8 30 */ 0x4785, 0x4786, 0x4787, 0x4788, 0x4789,
+ /* GB+82 33 E8 35 */ 0x478A, 0x478B, 0x478C,
+ /* Contiguous area: GB+82 34 96 39 .. GB+82 34 A1 30 */
+ /* GB+82 34 96 39 */ 0x4948,
+ /* GB+82 34 97 30 */ 0x4949, 0x494A, 0x494B, 0x494C, 0x494D,
+ /* GB+82 34 97 35 */ 0x494E, 0x494F, 0x4950, 0x4951, 0x4952,
+ /* GB+82 34 98 30 */ 0x4953, 0x4954, 0x4955, 0x4956, 0x4957,
+ /* GB+82 34 98 35 */ 0x4958, 0x4959, 0x495A, 0x495B, 0x495C,
+ /* GB+82 34 99 30 */ 0x495D, 0x495E, 0x495F, 0x4960, 0x4961,
+ /* GB+82 34 99 35 */ 0x4962, 0x4963, 0x4964, 0x4965, 0x4966,
+ /* GB+82 34 9A 30 */ 0x4967, 0x4968, 0x4969, 0x496A, 0x496B,
+ /* GB+82 34 9A 35 */ 0x496C, 0x496D, 0x496E, 0x496F, 0x4970,
+ /* GB+82 34 9B 30 */ 0x4971, 0x4972, 0x4973, 0x4974, 0x4975,
+ /* GB+82 34 9B 35 */ 0x4976, 0x4977, 0x4978, 0x4979, 0x497B,
+ /* GB+82 34 9C 30 */ 0x497C, 0x497E, 0x497F, 0x4980, 0x4981,
+ /* GB+82 34 9C 35 */ 0x4984, 0x4987, 0x4988, 0x4989, 0x498A,
+ /* GB+82 34 9D 30 */ 0x498B, 0x498C, 0x498D, 0x498E, 0x498F,
+ /* GB+82 34 9D 35 */ 0x4990, 0x4991, 0x4992, 0x4993, 0x4994,
+ /* GB+82 34 9E 30 */ 0x4995, 0x4996, 0x4997, 0x4998, 0x4999,
+ /* GB+82 34 9E 35 */ 0x499A, 0x499C, 0x499D, 0x499E, 0x49A0,
+ /* GB+82 34 9F 30 */ 0x49A1, 0x49A2, 0x49A3, 0x49A4, 0x49A5,
+ /* GB+82 34 9F 35 */ 0x49A6, 0x49A7, 0x49A8, 0x49A9, 0x49AA,
+ /* GB+82 34 A0 30 */ 0x49AB, 0x49AC, 0x49AD, 0x49AE, 0x49AF,
+ /* GB+82 34 A0 35 */ 0x49B0, 0x49B1, 0x49B2, 0x49B3, 0x49B4,
+ /* GB+82 34 A1 30 */ 0x49B5,
+ /* Contiguous area: GB+82 34 E7 34 .. GB+82 35 8F 32 */
+ /* GB+82 34 E7 34 */ 0x4C78,
+ /* GB+82 34 E7 35 */ 0x4C79, 0x4C7A, 0x4C7B, 0x4C7C, 0x4C7D,
+ /* GB+82 34 E8 30 */ 0x4C7E, 0x4C7F, 0x4C80, 0x4C81, 0x4C82,
+ /* GB+82 34 E8 35 */ 0x4C83, 0x4C84, 0x4C85, 0x4C86, 0x4C87,
+ /* GB+82 34 E9 30 */ 0x4C88, 0x4C89, 0x4C8A, 0x4C8B, 0x4C8C,
+ /* GB+82 34 E9 35 */ 0x4C8D, 0x4C8E, 0x4C8F, 0x4C90, 0x4C91,
+ /* GB+82 34 EA 30 */ 0x4C92, 0x4C93, 0x4C94, 0x4C95, 0x4C96,
+ /* GB+82 34 EA 35 */ 0x4C97, 0x4C98, 0x4C99, 0x4C9A, 0x4C9B,
+ /* GB+82 34 EB 30 */ 0x4C9C, 0x4C9D, 0x4C9E, 0x4CA4, 0x4CA5,
+ /* GB+82 34 EB 35 */ 0x4CA6, 0x4CA7, 0x4CA8, 0x4CA9, 0x4CAA,
+ /* GB+82 34 EC 30 */ 0x4CAB, 0x4CAC, 0x4CAD, 0x4CAE, 0x4CAF,
+ /* GB+82 34 EC 35 */ 0x4CB0, 0x4CB1, 0x4CB2, 0x4CB3, 0x4CB4,
+ /* GB+82 34 ED 30 */ 0x4CB5, 0x4CB6, 0x4CB7, 0x4CB8, 0x4CB9,
+ /* GB+82 34 ED 35 */ 0x4CBA, 0x4CBB, 0x4CBC, 0x4CBD, 0x4CBE,
+ /* GB+82 34 EE 30 */ 0x4CBF, 0x4CC0, 0x4CC1, 0x4CC2, 0x4CC3,
+ /* GB+82 34 EE 35 */ 0x4CC4, 0x4CC5, 0x4CC6, 0x4CC7, 0x4CC8,
+ /* GB+82 34 EF 30 */ 0x4CC9, 0x4CCA, 0x4CCB, 0x4CCC, 0x4CCD,
+ /* GB+82 34 EF 35 */ 0x4CCE, 0x4CCF, 0x4CD0, 0x4CD1, 0x4CD2,
+ /* GB+82 34 F0 30 */ 0x4CD3, 0x4CD4, 0x4CD5, 0x4CD6, 0x4CD7,
+ /* GB+82 34 F0 35 */ 0x4CD8, 0x4CD9, 0x4CDA, 0x4CDB, 0x4CDC,
+ /* GB+82 34 F1 30 */ 0x4CDD, 0x4CDE, 0x4CDF, 0x4CE0, 0x4CE1,
+ /* GB+82 34 F1 35 */ 0x4CE2, 0x4CE3, 0x4CE4, 0x4CE5, 0x4CE6,
+ /* GB+82 34 F2 30 */ 0x4CE7, 0x4CE8, 0x4CE9, 0x4CEA, 0x4CEB,
+ /* GB+82 34 F2 35 */ 0x4CEC, 0x4CED, 0x4CEE, 0x4CEF, 0x4CF0,
+ /* GB+82 34 F3 30 */ 0x4CF1, 0x4CF2, 0x4CF3, 0x4CF4, 0x4CF5,
+ /* GB+82 34 F3 35 */ 0x4CF6, 0x4CF7, 0x4CF8, 0x4CF9, 0x4CFA,
+ /* GB+82 34 F4 30 */ 0x4CFB, 0x4CFC, 0x4CFD, 0x4CFE, 0x4CFF,
+ /* GB+82 34 F4 35 */ 0x4D00, 0x4D01, 0x4D02, 0x4D03, 0x4D04,
+ /* GB+82 34 F5 30 */ 0x4D05, 0x4D06, 0x4D07, 0x4D08, 0x4D09,
+ /* GB+82 34 F5 35 */ 0x4D0A, 0x4D0B, 0x4D0C, 0x4D0D, 0x4D0E,
+ /* GB+82 34 F6 30 */ 0x4D0F, 0x4D10, 0x4D11, 0x4D12, 0x4D1A,
+ /* GB+82 34 F6 35 */ 0x4D1B, 0x4D1C, 0x4D1D, 0x4D1E, 0x4D1F,
+ /* GB+82 34 F7 30 */ 0x4D20, 0x4D21, 0x4D22, 0x4D23, 0x4D24,
+ /* GB+82 34 F7 35 */ 0x4D25, 0x4D26, 0x4D27, 0x4D28, 0x4D29,
+ /* GB+82 34 F8 30 */ 0x4D2A, 0x4D2B, 0x4D2C, 0x4D2D, 0x4D2E,
+ /* GB+82 34 F8 35 */ 0x4D2F, 0x4D30, 0x4D31, 0x4D32, 0x4D33,
+ /* GB+82 34 F9 30 */ 0x4D34, 0x4D35, 0x4D36, 0x4D37, 0x4D38,
+ /* GB+82 34 F9 35 */ 0x4D39, 0x4D3A, 0x4D3B, 0x4D3C, 0x4D3D,
+ /* GB+82 34 FA 30 */ 0x4D3E, 0x4D3F, 0x4D40, 0x4D41, 0x4D42,
+ /* GB+82 34 FA 35 */ 0x4D43, 0x4D44, 0x4D45, 0x4D46, 0x4D47,
+ /* GB+82 34 FB 30 */ 0x4D48, 0x4D49, 0x4D4A, 0x4D4B, 0x4D4C,
+ /* GB+82 34 FB 35 */ 0x4D4D, 0x4D4E, 0x4D4F, 0x4D50, 0x4D51,
+ /* GB+82 34 FC 30 */ 0x4D52, 0x4D53, 0x4D54, 0x4D55, 0x4D56,
+ /* GB+82 34 FC 35 */ 0x4D57, 0x4D58, 0x4D59, 0x4D5A, 0x4D5B,
+ /* GB+82 34 FD 30 */ 0x4D5C, 0x4D5D, 0x4D5E, 0x4D5F, 0x4D60,
+ /* GB+82 34 FD 35 */ 0x4D61, 0x4D62, 0x4D63, 0x4D64, 0x4D65,
+ /* GB+82 34 FE 30 */ 0x4D66, 0x4D67, 0x4D68, 0x4D69, 0x4D6A,
+ /* GB+82 34 FE 35 */ 0x4D6B, 0x4D6C, 0x4D6D, 0x4D6E, 0x4D6F,
+ /* GB+82 35 81 30 */ 0x4D70, 0x4D71, 0x4D72, 0x4D73, 0x4D74,
+ /* GB+82 35 81 35 */ 0x4D75, 0x4D76, 0x4D77, 0x4D78, 0x4D79,
+ /* GB+82 35 82 30 */ 0x4D7A, 0x4D7B, 0x4D7C, 0x4D7D, 0x4D7E,
+ /* GB+82 35 82 35 */ 0x4D7F, 0x4D80, 0x4D81, 0x4D82, 0x4D83,
+ /* GB+82 35 83 30 */ 0x4D84, 0x4D85, 0x4D86, 0x4D87, 0x4D88,
+ /* GB+82 35 83 35 */ 0x4D89, 0x4D8A, 0x4D8B, 0x4D8C, 0x4D8D,
+ /* GB+82 35 84 30 */ 0x4D8E, 0x4D8F, 0x4D90, 0x4D91, 0x4D92,
+ /* GB+82 35 84 35 */ 0x4D93, 0x4D94, 0x4D95, 0x4D96, 0x4D97,
+ /* GB+82 35 85 30 */ 0x4D98, 0x4D99, 0x4D9A, 0x4D9B, 0x4D9C,
+ /* GB+82 35 85 35 */ 0x4D9D, 0x4D9E, 0x4D9F, 0x4DA0, 0x4DA1,
+ /* GB+82 35 86 30 */ 0x4DA2, 0x4DA3, 0x4DA4, 0x4DA5, 0x4DA6,
+ /* GB+82 35 86 35 */ 0x4DA7, 0x4DA8, 0x4DA9, 0x4DAA, 0x4DAB,
+ /* GB+82 35 87 30 */ 0x4DAC, 0x4DAD, 0x4DAF, 0x4DB0, 0x4DB1,
+ /* GB+82 35 87 35 */ 0x4DB2, 0x4DB3, 0x4DB4, 0x4DB5, 0x4DB6,
+ /* GB+82 35 88 30 */ 0x4DB7, 0x4DB8, 0x4DB9, 0x4DBA, 0x4DBB,
+ /* GB+82 35 88 35 */ 0x4DBC, 0x4DBD, 0x4DBE, 0x4DBF, 0x4DC0,
+ /* GB+82 35 89 30 */ 0x4DC1, 0x4DC2, 0x4DC3, 0x4DC4, 0x4DC5,
+ /* GB+82 35 89 35 */ 0x4DC6, 0x4DC7, 0x4DC8, 0x4DC9, 0x4DCA,
+ /* GB+82 35 8A 30 */ 0x4DCB, 0x4DCC, 0x4DCD, 0x4DCE, 0x4DCF,
+ /* GB+82 35 8A 35 */ 0x4DD0, 0x4DD1, 0x4DD2, 0x4DD3, 0x4DD4,
+ /* GB+82 35 8B 30 */ 0x4DD5, 0x4DD6, 0x4DD7, 0x4DD8, 0x4DD9,
+ /* GB+82 35 8B 35 */ 0x4DDA, 0x4DDB, 0x4DDC, 0x4DDD, 0x4DDE,
+ /* GB+82 35 8C 30 */ 0x4DDF, 0x4DE0, 0x4DE1, 0x4DE2, 0x4DE3,
+ /* GB+82 35 8C 35 */ 0x4DE4, 0x4DE5, 0x4DE6, 0x4DE7, 0x4DE8,
+ /* GB+82 35 8D 30 */ 0x4DE9, 0x4DEA, 0x4DEB, 0x4DEC, 0x4DED,
+ /* GB+82 35 8D 35 */ 0x4DEE, 0x4DEF, 0x4DF0, 0x4DF1, 0x4DF2,
+ /* GB+82 35 8E 30 */ 0x4DF3, 0x4DF4, 0x4DF5, 0x4DF6, 0x4DF7,
+ /* GB+82 35 8E 35 */ 0x4DF8, 0x4DF9, 0x4DFA, 0x4DFB, 0x4DFC,
+ /* GB+82 35 8F 30 */ 0x4DFD, 0x4DFE, 0x4DFF,
+ /* Contiguous area: GB+83 36 C7 39 .. GB+83 36 CF 39 */
+ /* GB+83 36 C7 39 */ 0xE76C,
+ /* GB+83 36 C8 30 */ 0xE7C8, 0xE7E7, 0xE7E8, 0xE7E9, 0xE7EA,
+ /* GB+83 36 C8 35 */ 0xE7EB, 0xE7EC, 0xE7ED, 0xE7EE, 0xE7EF,
+ /* GB+83 36 C9 30 */ 0xE7F0, 0xE7F1, 0xE7F2, 0xE7F3, 0xE815,
+ /* GB+83 36 C9 35 */ 0xE819, 0xE81A, 0xE81B, 0xE81C, 0xE81D,
+ /* GB+83 36 CA 30 */ 0xE81F, 0xE820, 0xE821, 0xE822, 0xE823,
+ /* GB+83 36 CA 35 */ 0xE824, 0xE825, 0xE827, 0xE828, 0xE829,
+ /* GB+83 36 CB 30 */ 0xE82A, 0xE82D, 0xE82E, 0xE82F, 0xE830,
+ /* GB+83 36 CB 35 */ 0xE833, 0xE834, 0xE835, 0xE836, 0xE837,
+ /* GB+83 36 CC 30 */ 0xE838, 0xE839, 0xE83A, 0xE83C, 0xE83D,
+ /* GB+83 36 CC 35 */ 0xE83E, 0xE83F, 0xE840, 0xE841, 0xE842,
+ /* GB+83 36 CD 30 */ 0xE844, 0xE845, 0xE846, 0xE847, 0xE848,
+ /* GB+83 36 CD 35 */ 0xE849, 0xE84A, 0xE84B, 0xE84C, 0xE84D,
+ /* GB+83 36 CE 30 */ 0xE84E, 0xE84F, 0xE850, 0xE851, 0xE852,
+ /* GB+83 36 CE 35 */ 0xE853, 0xE856, 0xE857, 0xE858, 0xE859,
+ /* GB+83 36 CF 30 */ 0xE85A, 0xE85B, 0xE85C, 0xE85D, 0xE85E,
+ /* GB+83 36 CF 35 */ 0xE85F, 0xE860, 0xE861, 0xE862, 0xE863,
+ /* Contiguous area: GB+84 30 85 35 .. GB+84 30 9C 37 */
+ /* GB+84 30 85 35 */ 0xF92D, 0xF92E, 0xF92F, 0xF930, 0xF931,
+ /* GB+84 30 86 30 */ 0xF932, 0xF933, 0xF934, 0xF935, 0xF936,
+ /* GB+84 30 86 35 */ 0xF937, 0xF938, 0xF939, 0xF93A, 0xF93B,
+ /* GB+84 30 87 30 */ 0xF93C, 0xF93D, 0xF93E, 0xF93F, 0xF940,
+ /* GB+84 30 87 35 */ 0xF941, 0xF942, 0xF943, 0xF944, 0xF945,
+ /* GB+84 30 88 30 */ 0xF946, 0xF947, 0xF948, 0xF949, 0xF94A,
+ /* GB+84 30 88 35 */ 0xF94B, 0xF94C, 0xF94D, 0xF94E, 0xF94F,
+ /* GB+84 30 89 30 */ 0xF950, 0xF951, 0xF952, 0xF953, 0xF954,
+ /* GB+84 30 89 35 */ 0xF955, 0xF956, 0xF957, 0xF958, 0xF959,
+ /* GB+84 30 8A 30 */ 0xF95A, 0xF95B, 0xF95C, 0xF95D, 0xF95E,
+ /* GB+84 30 8A 35 */ 0xF95F, 0xF960, 0xF961, 0xF962, 0xF963,
+ /* GB+84 30 8B 30 */ 0xF964, 0xF965, 0xF966, 0xF967, 0xF968,
+ /* GB+84 30 8B 35 */ 0xF969, 0xF96A, 0xF96B, 0xF96C, 0xF96D,
+ /* GB+84 30 8C 30 */ 0xF96E, 0xF96F, 0xF970, 0xF971, 0xF972,
+ /* GB+84 30 8C 35 */ 0xF973, 0xF974, 0xF975, 0xF976, 0xF977,
+ /* GB+84 30 8D 30 */ 0xF978, 0xF97A, 0xF97B, 0xF97C, 0xF97D,
+ /* GB+84 30 8D 35 */ 0xF97E, 0xF97F, 0xF980, 0xF981, 0xF982,
+ /* GB+84 30 8E 30 */ 0xF983, 0xF984, 0xF985, 0xF986, 0xF987,
+ /* GB+84 30 8E 35 */ 0xF988, 0xF989, 0xF98A, 0xF98B, 0xF98C,
+ /* GB+84 30 8F 30 */ 0xF98D, 0xF98E, 0xF98F, 0xF990, 0xF991,
+ /* GB+84 30 8F 35 */ 0xF992, 0xF993, 0xF994, 0xF996, 0xF997,
+ /* GB+84 30 90 30 */ 0xF998, 0xF999, 0xF99A, 0xF99B, 0xF99C,
+ /* GB+84 30 90 35 */ 0xF99D, 0xF99E, 0xF99F, 0xF9A0, 0xF9A1,
+ /* GB+84 30 91 30 */ 0xF9A2, 0xF9A3, 0xF9A4, 0xF9A5, 0xF9A6,
+ /* GB+84 30 91 35 */ 0xF9A7, 0xF9A8, 0xF9A9, 0xF9AA, 0xF9AB,
+ /* GB+84 30 92 30 */ 0xF9AC, 0xF9AD, 0xF9AE, 0xF9AF, 0xF9B0,
+ /* GB+84 30 92 35 */ 0xF9B1, 0xF9B2, 0xF9B3, 0xF9B4, 0xF9B5,
+ /* GB+84 30 93 30 */ 0xF9B6, 0xF9B7, 0xF9B8, 0xF9B9, 0xF9BA,
+ /* GB+84 30 93 35 */ 0xF9BB, 0xF9BC, 0xF9BD, 0xF9BE, 0xF9BF,
+ /* GB+84 30 94 30 */ 0xF9C0, 0xF9C1, 0xF9C2, 0xF9C3, 0xF9C4,
+ /* GB+84 30 94 35 */ 0xF9C5, 0xF9C6, 0xF9C7, 0xF9C8, 0xF9C9,
+ /* GB+84 30 95 30 */ 0xF9CA, 0xF9CB, 0xF9CC, 0xF9CD, 0xF9CE,
+ /* GB+84 30 95 35 */ 0xF9CF, 0xF9D0, 0xF9D1, 0xF9D2, 0xF9D3,
+ /* GB+84 30 96 30 */ 0xF9D4, 0xF9D5, 0xF9D6, 0xF9D7, 0xF9D8,
+ /* GB+84 30 96 35 */ 0xF9D9, 0xF9DA, 0xF9DB, 0xF9DC, 0xF9DD,
+ /* GB+84 30 97 30 */ 0xF9DE, 0xF9DF, 0xF9E0, 0xF9E1, 0xF9E2,
+ /* GB+84 30 97 35 */ 0xF9E3, 0xF9E4, 0xF9E5, 0xF9E6, 0xF9E8,
+ /* GB+84 30 98 30 */ 0xF9E9, 0xF9EA, 0xF9EB, 0xF9EC, 0xF9ED,
+ /* GB+84 30 98 35 */ 0xF9EE, 0xF9EF, 0xF9F0, 0xF9F2, 0xF9F3,
+ /* GB+84 30 99 30 */ 0xF9F4, 0xF9F5, 0xF9F6, 0xF9F7, 0xF9F8,
+ /* GB+84 30 99 35 */ 0xF9F9, 0xF9FA, 0xF9FB, 0xF9FC, 0xF9FD,
+ /* GB+84 30 9A 30 */ 0xF9FE, 0xF9FF, 0xFA00, 0xFA01, 0xFA02,
+ /* GB+84 30 9A 35 */ 0xFA03, 0xFA04, 0xFA05, 0xFA06, 0xFA07,
+ /* GB+84 30 9B 30 */ 0xFA08, 0xFA09, 0xFA0A, 0xFA0B, 0xFA10,
+ /* GB+84 30 9B 35 */ 0xFA12, 0xFA15, 0xFA16, 0xFA17, 0xFA19,
+ /* GB+84 30 9C 30 */ 0xFA1A, 0xFA1B, 0xFA1C, 0xFA1D, 0xFA1E,
+ /* GB+84 30 9C 35 */ 0xFA22, 0xFA25, 0xFA26,
+ /* Contiguous area: GB+84 31 85 38 .. GB+84 31 A2 33 */
+ /* GB+84 31 85 38 */ 0xFE32, 0xFE45,
+ /* GB+84 31 86 30 */ 0xFE46, 0xFE47, 0xFE48, 0xFE53, 0xFE58,
+ /* GB+84 31 86 35 */ 0xFE67, 0xFE6C, 0xFE6D, 0xFE6E, 0xFE6F,
+ /* GB+84 31 87 30 */ 0xFE70, 0xFE71, 0xFE72, 0xFE73, 0xFE74,
+ /* GB+84 31 87 35 */ 0xFE75, 0xFE76, 0xFE77, 0xFE78, 0xFE79,
+ /* GB+84 31 88 30 */ 0xFE7A, 0xFE7B, 0xFE7C, 0xFE7D, 0xFE7E,
+ /* GB+84 31 88 35 */ 0xFE7F, 0xFE80, 0xFE81, 0xFE82, 0xFE83,
+ /* GB+84 31 89 30 */ 0xFE84, 0xFE85, 0xFE86, 0xFE87, 0xFE88,
+ /* GB+84 31 89 35 */ 0xFE89, 0xFE8A, 0xFE8B, 0xFE8C, 0xFE8D,
+ /* GB+84 31 8A 30 */ 0xFE8E, 0xFE8F, 0xFE90, 0xFE91, 0xFE92,
+ /* GB+84 31 8A 35 */ 0xFE93, 0xFE94, 0xFE95, 0xFE96, 0xFE97,
+ /* GB+84 31 8B 30 */ 0xFE98, 0xFE99, 0xFE9A, 0xFE9B, 0xFE9C,
+ /* GB+84 31 8B 35 */ 0xFE9D, 0xFE9E, 0xFE9F, 0xFEA0, 0xFEA1,
+ /* GB+84 31 8C 30 */ 0xFEA2, 0xFEA3, 0xFEA4, 0xFEA5, 0xFEA6,
+ /* GB+84 31 8C 35 */ 0xFEA7, 0xFEA8, 0xFEA9, 0xFEAA, 0xFEAB,
+ /* GB+84 31 8D 30 */ 0xFEAC, 0xFEAD, 0xFEAE, 0xFEAF, 0xFEB0,
+ /* GB+84 31 8D 35 */ 0xFEB1, 0xFEB2, 0xFEB3, 0xFEB4, 0xFEB5,
+ /* GB+84 31 8E 30 */ 0xFEB6, 0xFEB7, 0xFEB8, 0xFEB9, 0xFEBA,
+ /* GB+84 31 8E 35 */ 0xFEBB, 0xFEBC, 0xFEBD, 0xFEBE, 0xFEBF,
+ /* GB+84 31 8F 30 */ 0xFEC0, 0xFEC1, 0xFEC2, 0xFEC3, 0xFEC4,
+ /* GB+84 31 8F 35 */ 0xFEC5, 0xFEC6, 0xFEC7, 0xFEC8, 0xFEC9,
+ /* GB+84 31 90 30 */ 0xFECA, 0xFECB, 0xFECC, 0xFECD, 0xFECE,
+ /* GB+84 31 90 35 */ 0xFECF, 0xFED0, 0xFED1, 0xFED2, 0xFED3,
+ /* GB+84 31 91 30 */ 0xFED4, 0xFED5, 0xFED6, 0xFED7, 0xFED8,
+ /* GB+84 31 91 35 */ 0xFED9, 0xFEDA, 0xFEDB, 0xFEDC, 0xFEDD,
+ /* GB+84 31 92 30 */ 0xFEDE, 0xFEDF, 0xFEE0, 0xFEE1, 0xFEE2,
+ /* GB+84 31 92 35 */ 0xFEE3, 0xFEE4, 0xFEE5, 0xFEE6, 0xFEE7,
+ /* GB+84 31 93 30 */ 0xFEE8, 0xFEE9, 0xFEEA, 0xFEEB, 0xFEEC,
+ /* GB+84 31 93 35 */ 0xFEED, 0xFEEE, 0xFEEF, 0xFEF0, 0xFEF1,
+ /* GB+84 31 94 30 */ 0xFEF2, 0xFEF3, 0xFEF4, 0xFEF5, 0xFEF6,
+ /* GB+84 31 94 35 */ 0xFEF7, 0xFEF8, 0xFEF9, 0xFEFA, 0xFEFB,
+ /* GB+84 31 95 30 */ 0xFEFC, 0xFEFD, 0xFEFE, 0xFEFF, 0xFF00,
+ /* GB+84 31 95 35 */ 0xFF5F, 0xFF60, 0xFF61, 0xFF62, 0xFF63,
+ /* GB+84 31 96 30 */ 0xFF64, 0xFF65, 0xFF66, 0xFF67, 0xFF68,
+ /* GB+84 31 96 35 */ 0xFF69, 0xFF6A, 0xFF6B, 0xFF6C, 0xFF6D,
+ /* GB+84 31 97 30 */ 0xFF6E, 0xFF6F, 0xFF70, 0xFF71, 0xFF72,
+ /* GB+84 31 97 35 */ 0xFF73, 0xFF74, 0xFF75, 0xFF76, 0xFF77,
+ /* GB+84 31 98 30 */ 0xFF78, 0xFF79, 0xFF7A, 0xFF7B, 0xFF7C,
+ /* GB+84 31 98 35 */ 0xFF7D, 0xFF7E, 0xFF7F, 0xFF80, 0xFF81,
+ /* GB+84 31 99 30 */ 0xFF82, 0xFF83, 0xFF84, 0xFF85, 0xFF86,
+ /* GB+84 31 99 35 */ 0xFF87, 0xFF88, 0xFF89, 0xFF8A, 0xFF8B,
+ /* GB+84 31 9A 30 */ 0xFF8C, 0xFF8D, 0xFF8E, 0xFF8F, 0xFF90,
+ /* GB+84 31 9A 35 */ 0xFF91, 0xFF92, 0xFF93, 0xFF94, 0xFF95,
+ /* GB+84 31 9B 30 */ 0xFF96, 0xFF97, 0xFF98, 0xFF99, 0xFF9A,
+ /* GB+84 31 9B 35 */ 0xFF9B, 0xFF9C, 0xFF9D, 0xFF9E, 0xFF9F,
+ /* GB+84 31 9C 30 */ 0xFFA0, 0xFFA1, 0xFFA2, 0xFFA3, 0xFFA4,
+ /* GB+84 31 9C 35 */ 0xFFA5, 0xFFA6, 0xFFA7, 0xFFA8, 0xFFA9,
+ /* GB+84 31 9D 30 */ 0xFFAA, 0xFFAB, 0xFFAC, 0xFFAD, 0xFFAE,
+ /* GB+84 31 9D 35 */ 0xFFAF, 0xFFB0, 0xFFB1, 0xFFB2, 0xFFB3,
+ /* GB+84 31 9E 30 */ 0xFFB4, 0xFFB5, 0xFFB6, 0xFFB7, 0xFFB8,
+ /* GB+84 31 9E 35 */ 0xFFB9, 0xFFBA, 0xFFBB, 0xFFBC, 0xFFBD,
+ /* GB+84 31 9F 30 */ 0xFFBE, 0xFFBF, 0xFFC0, 0xFFC1, 0xFFC2,
+ /* GB+84 31 9F 35 */ 0xFFC3, 0xFFC4, 0xFFC5, 0xFFC6, 0xFFC7,
+ /* GB+84 31 A0 30 */ 0xFFC8, 0xFFC9, 0xFFCA, 0xFFCB, 0xFFCC,
+ /* GB+84 31 A0 35 */ 0xFFCD, 0xFFCE, 0xFFCF, 0xFFD0, 0xFFD1,
+ /* GB+84 31 A1 30 */ 0xFFD2, 0xFFD3, 0xFFD4, 0xFFD5, 0xFFD6,
+ /* GB+84 31 A1 35 */ 0xFFD7, 0xFFD8, 0xFFD9, 0xFFDA, 0xFFDB,
+ /* GB+84 31 A2 30 */ 0xFFDC, 0xFFDD, 0xFFDE, 0xFFDF,
+};
+
+static inline uint gb4lin_to_gb(uint gb4lin) {
+ uchar a, b, c, d;
+ a = 0x81 + gb4lin / 12600;
+ b = 0x30 + (gb4lin / 1260) % 10;
+ c = 0x81 + (gb4lin / 10) % 126;
+ d = 0x30 + gb4lin % 10;
+ return ( (a << 24) | (b << 16) | (c << 8) | d);
+}
+
+static uint qt_Gb18030ToUnicode(const uchar *gbstr, int& len) {
+ /* Returns Unicode. */
+ uint uni;
+ uchar first = *gbstr;
+
+ if ( IsLatin(first) ) {
+ len = 1;
+ uni = (uint)first;
+ }
+ else if ( Is1stByte(first) && len >= 2 ) {
+ uchar second = gbstr[1];
+
+ if ( Is2ndByteIn2Bytes(second) ) {
+ len = 2;
+
+ if (IsUDA1(first, second))
+ uni = 0xE000 + (first - 0xAA) * 94 + (second - 0xA1);
+ else if (IsUDA2(first, second))
+ uni = 0xE234 + (first - 0xF8) * 94 + (second - 0xA1);
+ else if (IsUDA3(first, second))
+ uni = 0xE4C6 + (first - 0xA1) * 96 + (second - 0x40)
+ - ((second >= 0x80) ? 1 : 0);
+ else {
+ // Use the mapping table
+ uint i;
+
+ i = (first - 0x81) * 190 + (second - 0x40)
+ - ((second >= 0x80) ? 1 : 0);
+
+ if (InRange(first, 0xA1, 0xA7))
+ i -= (first - 0xA0) * 96;
+ if (first > 0xA7)
+ i -= 672;
+ if (InRange(first, 0xAA, 0xAF))
+ i -= (first - 0xAA) * 94;
+ if (first > 0xAF)
+ i -= 564;
+ if (first >= 0xF8)
+ i -= (first - 0xF8) * 94;
+
+ uni = (uint)gb18030_2byte_to_ucs[i];
+ }
+ }
+ else if ( Is2ndByteIn4Bytes(second) && len >= 4 ) {
+ uchar third = gbstr[2],
+ fourth = gbstr[3];
+
+ if ( Is3rdByte(third) && Is4thByte(fourth) ) {
+ // Valid 4-byte GB18030, whether defined or not
+ uint gb4lin;
+ indexTbl_t g2u;
+
+ gb4lin = (first - 0x81) * 12600 + (second - 0x30) * 1260
+ + (third - 0x81) * 10 + (fourth - 0x30);
+
+ len = 4;
+ if ( gb4lin <= 0x99FB ) {
+ /* GB+81308130 - GB+8431A439 */
+ g2u = gb18030_to_ucs_index[gb4lin >> 8];
+
+ if ((TQ_UINT8)(gb4lin & 0xFF) >= g2u.tblBegin &&
+ (TQ_UINT8)(gb4lin & 0xFF) <= g2u.tblEnd) {
+
+ uni = (uint)gb18030_4byte_to_ucs[gb4lin - g2u.tblOffset];
+ }
+ else {
+ uni = g2u.algOffset + (gb4lin & 0xFF);
+ }
+ } else if (InRange(gb4lin, 0x2E248, 0x12E247)) {
+ /* GB+90308130 - GB+E3329A35 */
+ uni = gb4lin - 0x1E248;
+ } else {
+ /* undefined or reserved area */
+ len = 1;
+ uni = TQChar::tqreplacement.tqunicode();
+ }
+ }
+ else {
+ len = 1;
+ uni = TQChar::tqreplacement.tqunicode();
+ }
+ }
+ else {
+ len = 1;
+ uni = TQChar::tqreplacement.tqunicode();
+ }
+ }
+ else {
+ len = 1;
+ uni = TQChar::tqreplacement.tqunicode();
+ }
+ return uni;
+}
+
+
+int qt_UnicodeToGb18030(uint uni, uchar *gbchar) {
+ /* Returns the bytesize of the GB18030 character. */
+ uint gb, gb4lin;
+ indexTbl_t u2g;
+
+ if ( IsLatin(uni) ) {
+ *gbchar = (uchar)uni;
+ return 1;
+ }
+ else if (uni <= 0xD7FF || InRange(uni, 0xE766, 0xFFFF)) {
+ u2g = ucs_to_gb18030_index[uni >> 8];
+
+ if ((TQ_UINT8)(uni & 0xFF) >= u2g.tblBegin && (TQ_UINT8)(uni & 0xFF) <= u2g.tblEnd) {
+ // Use mapping table (2-byte or 4-byte GB18030)
+ uint tblEntry;
+
+ tblEntry = ucs_to_gb18030[uni - u2g.tblOffset];
+
+ if (tblEntry > 0x8000) {
+ // 2-byte GB18030
+ gb = tblEntry;
+ }
+ else {
+ // 4-byte GB18030 stored in a special compact format
+ uchar a, b;
+ a = 0x81;
+ b = 0x30 + (tblEntry >> 11);
+ if (tblEntry >= 0x7000) {
+ a += 3;
+ b -= 14;
+ } else if (tblEntry >= 0x6000) {
+ a += 2;
+ b -= 6;
+ } else if (tblEntry >= 0x3000) {
+ a += 1;
+ b -= 6;
+ } else if (b >= 0x31) {
+ b += 5;
+ }
+ gbchar[0] = a;
+ gbchar[1] = b;
+ gbchar[2] = 0x81 + ( (tblEntry >> 4) & 0x7F );
+ gbchar[3] = 0x30 + (tblEntry & 0xF);
+ return 4;
+ }
+ }
+ else {
+ // 4-byte GB18030 calculated algorithmically
+ gb4lin = u2g.algOffset + (uni & 0xFF);
+ // Yikes, my index table could not cover all the bases...
+ if (InRange(uni, 0x49B8, 0x49FF))
+ gb4lin -= 11;
+ gb = gb4lin_to_gb(gb4lin);
+ }
+ }
+ else if (InRange(uni, 0xE000, 0xE765)) {
+ // User-defined areas in GB18030 (2-byte)
+ if (uni <= 0xE233)
+ gb = 0xAAA1 + (((uni - 0xE000) / 94) << 8) + (uni - 0xE000) % 94;
+ else if (uni <= 0xE4C5)
+ gb = 0xF8A1 + (((uni - 0xE234) / 94) << 8) + (uni - 0xE234) % 94;
+ else {
+ gb = 0xA140 + (((uni - 0xE4C6) / 96) << 8) + (uni - 0xE4C6) % 96;
+ // Skip the gap at 0x7F
+ if ((gb & 0xFF) >= 0x7F)
+ gb++;
+ }
+ }
+ else if (InRange(uni, 0x10000, 0x10FFFF)) {
+ // TQt 3.x does not support beyond BMP yet, but what the heck...
+ // (U+10000 = GB+90308130) to (U+10FFFF = GB+E3329A35)
+ gb = gb4lin_to_gb(0x1E248 + uni);
+ }
+ else {
+ // Surrogate area and other undefined/reserved areas (discard)
+ *gbchar = 0;
+ return 0;
+ }
+
+ if (gb <= 0xFFFF) {
+ gbchar[0] = (uchar)((gb >> 8) & 0xFF);
+ gbchar[1] = (uchar)(gb & 0xFF);
+ return 2;
+ } else {
+ gbchar[0] = (uchar)((gb >> 24) & 0xFF);
+ gbchar[1] = (uchar)((gb >> 16) & 0xFF);
+ gbchar[2] = (uchar)((gb >> 8) & 0xFF);
+ gbchar[3] = (uchar)(gb & 0xFF);
+ return 4;
+ }
+}
+
+
+int qt_UnicodeToGbk(uint uni, uchar *gbchar) {
+ /* Returns the bytesize of the GBK character. */
+ /* Intended for improving performance of GB2312 and GBK functions. */
+ uint gb;
+ indexTbl_t u2g;
+
+ if ( IsLatin(uni) ) {
+ *gbchar = (uchar)uni;
+ return 1;
+ }
+ else if (uni <= 0xD7FF || InRange(uni, 0xE766, 0xFFFF)) {
+ u2g = ucs_to_gb18030_index[uni >> 8];
+
+ if ( (TQ_UINT8)(uni & 0xFF) >= u2g.tblBegin && (TQ_UINT8)(uni & 0xFF) <= u2g.tblEnd ) {
+ // Use mapping table (2-byte GBK or 4-byte GB18030)
+ uint tblEntry;
+
+ tblEntry = ucs_to_gb18030[uni - u2g.tblOffset];
+
+ if (tblEntry > 0x8000) {
+ // GBK
+ gb = tblEntry;
+ }
+ else {
+ // 4-byte GB18030 stored in a special compact format (discard)
+ *gbchar = 0;
+ return 0;
+ }
+ }
+ else {
+ // 4-byte GB18030 calculated algorithmically (discard)
+ *gbchar = 0;
+ return 0;
+ }
+ }
+ else if (InRange(uni, 0xE000, 0xE765)) {
+ // User-defined areas in GB18030 (2-byte)
+ if (uni <= 0xE233)
+ gb = 0xAAA1 + (((uni - 0xE000) / 94) << 8) + (uni - 0xE000) % 94;
+ else if (uni <= 0xE4C5)
+ gb = 0xF8A1 + (((uni - 0xE234) / 94) << 8) + (uni - 0xE234) % 94;
+ else {
+ gb = 0xA140 + (((uni - 0xE4C6) / 96) << 8) + (uni - 0xE4C6) % 96;
+ // Skip the gap at 0x7F
+ if ((gb & 0xFF) >= 0x7F)
+ gb++;
+ }
+ }
+ else {
+ // Surrogate area and other undefined/reserved areas (discard)
+ *gbchar = 0;
+ return 0;
+ }
+
+ gbchar[0] = (uchar)((gb >> 8) & 0xFF);
+ gbchar[1] = (uchar)(gb & 0xFF);
+ return 2;
+}
+
+#endif
+
diff --git a/tqtinterface/qt4/src/codecs/tqgb18030codec.h b/tqtinterface/qt4/src/codecs/tqgb18030codec.h
new file mode 100644
index 0000000..c037ec7
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqgb18030codec.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Definition of TQGb18030Codec class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Contributed by James Su <suzhe@gnuchina.org>
+
+#ifndef TQGB18030CODEC_H
+#define TQGB18030CODEC_H
+
+#ifndef TQT_H
+#include "tqtextcodec.h"
+#endif // TQT_H
+
+
+#ifndef TQT_NO_BIG_CODECS
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_CODECS_CN
+#else
+#define TQ_EXPORT_CODECS_CN TQ_EXPORT
+#endif
+
+class TQ_EXPORT_CODECS_CN TQGb18030Codec : public TQTextCodec {
+public:
+ TQGb18030Codec();
+
+ int mibEnum() const;
+ const char* name() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+};
+
+class TQ_EXPORT_CODECS_CN TQGbkCodec : public TQGb18030Codec {
+public:
+ TQGbkCodec();
+
+ int mibEnum() const;
+ const char* name() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQGb18030Codec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+};
+
+class TQ_EXPORT_CODECS_CN TQGb2312Codec : public TQGb18030Codec {
+public:
+ TQGb2312Codec();
+
+ int mibEnum() const;
+ const char* name() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQGb18030Codec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+};
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqgbkcodec.h b/tqtinterface/qt4/src/codecs/tqgbkcodec.h
new file mode 100644
index 0000000..a1b92ba
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqgbkcodec.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Contributed by James Su <suzhe@gnuchina.org>
+
+#ifndef TQGBKCODEC_H
+#define TQGBKCODEC_H
+#ifndef TQT_H
+#include "tqgb18030codec.h"
+#endif // TQT_H
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqisciicodec.cpp b/tqtinterface/qt4/src/codecs/tqisciicodec.cpp
new file mode 100644
index 0000000..e6063b4
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqisciicodec.cpp
@@ -0,0 +1,240 @@
+#include "tqisciicodec_p.h"
+#ifndef TQT_NO_CODECS
+
+#define TQValidChar(u) ((u) ? TQChar((u)) : TQChar::tqreplacement)
+
+/*!
+ \class TQIsciiCodec
+ \brief The TQIsciiCodec class provides conversion to and from the ISCII encoding.
+
+ \ingroup i18n
+ \internal
+*/
+
+TQIsciiCodec::TQIsciiCodec(int i)
+: idx(i)
+{
+}
+
+int TQIsciiCodec::mibEnum() const
+{
+ /* There is no MIBEnum for Iscii */
+ return -3000-idx;
+}
+
+
+struct Codecs {
+ const char *name;
+ ushort base;
+};
+
+static const Codecs codecs [] = {
+ { "Iscii-Dev", 0x900 },
+ { "Iscii-Bng", 0x980 },
+ { "Iscii-Pnj", 0xa00 },
+ { "Iscii-Gjr", 0xa80 },
+ { "Iscii-Ori", 0xb00 },
+ { "Iscii-Tml", 0xb80 },
+ { "Iscii-Tlg", 0xc00 },
+ { "Iscii-Knd", 0xc80 },
+ { "Iscii-Mlm", 0xd00 }
+};
+
+const char* TQIsciiCodec::name() const
+{
+ return codecs[idx].name;
+}
+
+const char* TQIsciiCodec::mimeName() const
+{
+ return codecs[idx].name;
+}
+
+
+int TQIsciiCodec::heuristicNameMatch(const char* hint) const
+{
+ const char *p = strchr(hint, '.');
+ if (p)
+ p++;
+ else
+ p = hint;
+
+ if (TQString::tqfromLatin1(p).lower() == TQString::tqfromLatin1(codecs[idx].name).lower())
+ return 4;
+ else
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+int TQIsciiCodec::heuristicContentMatch(const char*, int) const
+{
+ return 0;
+}
+
+#define INV 0xff
+
+/* iscii range from 0xa0 - 0xff */
+static const uchar iscii_to_uni_table[0x60] = {
+ 0x00, 0x01, 0x02, 0x03,
+ 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0e,
+ 0x0f, 0x20, 0x0d, 0x12,
+
+ 0x13, 0x14, 0x11, 0x15,
+ 0x16, 0x17, 0x18, 0x19,
+ 0x1a, 0x1b, 0x1c, 0x1d,
+ 0x1e, 0x1f, 0x20, 0x21,
+
+ 0x22, 0x23, 0x24, 0x25,
+ 0x26, 0x27, 0x28, 0x29,
+ 0x2a, 0x2b, 0x2c, 0x2d,
+ 0x2e, 0x2f, 0x5f, 0x30,
+
+ 0x31, 0x32, 0x33, 0x34,
+ 0x35, 0x36, 0x37, 0x38,
+ 0x39, INV, 0x3e, 0x3f,
+ 0x40, 0x41, 0x42, 0x43,
+
+ 0x46, 0x47, 0x48, 0x45,
+ 0x4a, 0x4b, 0x4c, 0x49,
+ 0x4d, 0x3c, 0x64, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+
+ 0x00, 0x66, 0x67, 0x68,
+ 0x69, 0x6a, 0x6b, 0x6c,
+ 0x6d, 0x6e, 0x6f, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+static const uchar uni_to_iscii_table[0x80] = {
+ 0x00, 0xa1, 0xa2, 0xa3,
+ 0x00, 0xa4, 0xa5, 0xa6,
+ 0xa7, 0xa8, 0xa9, 0xaa,
+ 0x00, 0xae, 0xab, 0xac,
+
+ 0xad, 0xb2, 0xaf, 0xb0,
+ 0xb1, 0xb3, 0xb4, 0xb5,
+ 0xb6, 0xb7, 0xb8, 0xb9,
+ 0xba, 0xbb, 0xbc, 0xbd,
+
+ 0xbe, 0xbf, 0xc0, 0xc1,
+ 0xc2, 0xc3, 0xc4, 0xc5,
+ 0xc6, 0xc7, 0xc8, 0xc9,
+ 0xca, 0xcb, 0xcc, 0xcd,
+
+ 0xcf, 0xd0, 0xd1, 0xd2,
+ 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0x00, 0x00,
+ 0xe9, 0x00, 0xda, 0xdb,
+
+ 0xdc, 0xdd, 0xde, 0xdf,
+ 0x00, 0xe3, 0xe0, 0xe1,
+ 0xe2, 0xe7, 0xe4, 0xe5,
+ 0xe6, 0xe8, 0x00, 0x00,
+
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x02, 0x03, 0x04, // decomposable into the uc codes listed here + nukta
+ 0x05, 0x06, 0x07, 0xce,
+
+ 0x00, 0x00, 0x00, 0x00,
+ 0xea, 0x08, 0xf1, 0xf2,
+ 0xf3, 0xf4, 0xf5, 0xf6,
+ 0xf7, 0xf8, 0xf9, 0xfa,
+
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00
+};
+
+static const uchar uni_to_iscii_pairs[] = {
+ 0x00, 0x00,
+ 0x15, 0x3c, // 0x958
+ 0x16, 0x3c, // 0x959
+ 0x17, 0x3c, // 0x95a
+ 0x1c, 0x3c, // 0x95b
+ 0x21, 0x3c, // 0x95c
+ 0x22, 0x3c, // 0x95d
+ 0x2b, 0x3c, // 0x95e
+ 0x64, 0x64 // 0x965
+};
+
+
+TQCString TQIsciiCodec::fromUnicode(const TQString& uc, int& len_in_out) const
+{
+ int l = uc.length();
+ if (len_in_out > 0)
+ l = TQMIN(l, len_in_out);
+ TQCString result(2*l); //worst case
+
+ const TQChar *data = uc.tqunicode();
+ uchar *ch = (uchar *)result.data();
+
+ int base = codecs[idx].base;
+
+ bool halant = FALSE;
+ for (int i =0; i < l; ++i) {
+ int pos = data[i].tqunicode() - base;
+ if (pos > 0 && pos < 0x80) {
+ uchar iscii = uni_to_iscii_table[pos];
+ if (iscii > 0x80) {
+ *ch++ = iscii;
+ } else if (iscii) {
+ const uchar *pair = uni_to_iscii_pairs + 2*iscii;
+ *ch++ = *pair++;
+ *ch++ = *pair++;
+ } else {
+ *ch++ = '?';
+ }
+ } else {
+ if (data[i].tqunicode() == 0x200c) { // ZWNJ
+ if (halant)
+ // Consonant Halant ZWNJ -> Consonant Halant Halant
+ *ch++ = 0xe8;
+ } else if (data[i].tqunicode() == 0x200d) { // ZWJ
+ if (halant)
+ // Consonant Halant ZWJ -> Consonant Halant Nukta
+ *ch++ = 0xe9;
+ } else {
+ *ch++ = '?';
+ }
+ }
+ halant = (pos == 0x4d);
+ }
+ len_in_out = ch - (uchar *)result.data();
+ result.truncate(len_in_out);
+ return result;
+}
+
+TQString TQIsciiCodec::toUnicode( const char* chars, int len_in ) const
+{
+ TQString result;
+ result.setLength(len_in);
+
+ TQChar *uc = (TQChar *)result.tqunicode();
+
+ int base = codecs[idx].base;
+
+ bool halant = FALSE;
+ for (int i = 0; i < len_in; ++i) {
+ ushort ch = (uchar) chars[i];
+ if (ch < 0xa0)
+ *uc++ = TQValidChar(ch);
+ else {
+ ushort c = iscii_to_uni_table[ch - 0xa0];
+ if (halant && (c == INV || c == 0xe9)) {
+ // Consonant Halant INV -> Consonant Halant ZWJ
+ // Consonant Halant Nukta -> Consonant Halant ZWJ
+ *uc++ = TQChar(0x200d);
+ } else if (halant && c == 0xe8) {
+ // Consonant Halant Halant -> Consonant Halant ZWNJ
+ *uc++ = TQChar(0x200c);
+ } else {
+ *uc++ = TQChar(c+base);
+ }
+ }
+ halant = ((uchar)chars[i] == 0xe8);
+ }
+ return result;
+}
+#endif // TQT_NO_CODECS
diff --git a/tqtinterface/qt4/src/codecs/tqisciicodec_p.h b/tqtinterface/qt4/src/codecs/tqisciicodec_p.h
new file mode 100644
index 0000000..be3c063
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqisciicodec_p.h
@@ -0,0 +1,33 @@
+#ifndef TQISCIICODEC_H
+#define TQISCIICODEC_H
+
+#ifndef TQT_H
+#include "tqtextcodec.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_CODECS
+
+class TQIsciiCodec : public TQTextCodec {
+public:
+ TQIsciiCodec(int i);
+
+ virtual int mibEnum() const;
+ virtual const char* mimeName () const;
+ const char* name() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+
+ TQCString fromUnicode(const TQString& uc, int& len_in_out) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+
+private:
+ int idx;
+};
+
+#endif // TQT_NO_CODECS
+#endif // TQISCIIDEVCODEC_H
diff --git a/tqtinterface/qt4/src/codecs/tqjiscodec.cpp b/tqtinterface/qt4/src/codecs/tqjiscodec.cpp
new file mode 100644
index 0000000..ebebca2
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqjiscodec.cpp
@@ -0,0 +1,706 @@
+/****************************************************************************
+**
+** Implementation of TQJisCodec class
+**
+** Created : 990225
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Most of the code here was originally written by Serika Kurusugawa,
+// a.k.a. Junji Takagi, and is included in TQt with the author's permission
+// and the grateful thanks of the Trolltech team.
+
+/*! \class TQJisCodec
+ \reentrant
+ \ingroup i18n
+
+ \brief The TQJisCodec class provides conversion to and from JIS character sets.
+
+ More precisely, the TQJisCodec class subclasses TQTextCodec to
+ provide support for JIS X 0201 Latin, JIS X 0201 Kana, JIS X 0208
+ and JIS X 0212.
+
+ The environment variable UNICODEMAP_JP can be used to fine-tune
+ TQJisCodec, TQSjisCodec and TQEucJpCodec. The mapping names are as for
+ the Japanese XML working group's \link
+ http://www.y-adagio.com/public/standards/tr_xml_jpf/toc.htm XML
+ Japanese Profile\endlink, because it names and explains all the
+ widely used mappings. Here are brief descriptions, written by
+ Serika Kurusugawa:
+
+ \list
+
+ \i "tqunicode-0.9" or "tqunicode-0201" for Unicode style. This assumes
+ JISX0201 for 0x00-0x7f. (0.9 is a table version of jisx02xx mapping
+ used for Uniocde spec version 1.1.)
+
+ \i "tqunicode-ascii" This assumes US-ASCII for 0x00-0x7f; some
+ chars (JISX0208 0x2140 and JISX0212 0x2237) are different from
+ Unicode 1.1 to avoid conflict.
+
+ \i "open-19970715-0201" ("open-0201" for convenience) or
+ "jisx0221-1995" for JISX0221-JISX0201 style. JIS X 0221 is JIS
+ version of Unicode, but a few chars (0x5c, 0x7e, 0x2140, 0x216f,
+ 0x2131) are different from Unicode 1.1. This is used when 0x5c is
+ treated as YEN SIGN.
+
+ \i "open-19970715-ascii" ("open-ascii" for convenience) for
+ JISX0221-ASCII style. This is used when 0x5c is treated as REVERSE
+ SOLIDUS.
+
+ \i "open-19970715-ms" ("open-ms" for convenience) or "cp932" for
+ Microsoft Windows style. Windows Code Page 932. Some chars (0x2140,
+ 0x2141, 0x2142, 0x215d, 0x2171, 0x2172) are different from Unicode
+ 1.1.
+
+ \i "jdk1.1.7" for Sun's JDK style. Same as Unicode 1.1, except that
+ JIS 0x2140 is mapped to UFF3C. Either ASCII or JISX0201 can be used
+ for 0x00-0x7f.
+
+ \endlist
+
+ In addition, the extensions "nec-vdc", "ibm-vdc" and "udc" are
+ supported.
+
+ For example, if you want to use Unicode style conversion but with
+ NEC's extension, set \c UNICODEMAP_JP to
+ <nobr>\c {tqunicode-0.9, nec-vdc}.</nobr> (You will probably
+ need to quote that in a shell command.)
+
+ Most of the code here was written by Serika Kurusugawa,
+ a.k.a. Junji Takagi, and is included in TQt with the author's
+ permission and the grateful thanks of the Trolltech team. Here is
+ the copyright statement for that code:
+
+ \legalese
+
+ Copyright (C) 1999 Serika Kurusugawa. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ \list 1
+ \i Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ \i Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ \endlist
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS".
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+#include "tqjiscodec.h"
+
+#ifndef TQT_NO_BIG_CODECS
+
+static const uchar Esc = 0x1b;
+static const uchar So = 0x0e; // Shift Out
+static const uchar Si = 0x0f; // Shift In
+
+static const uchar ReverseSolidus = 0x5c;
+static const uchar YenSign = 0x5c;
+static const uchar Tilde = 0x7e;
+static const uchar Overline = 0x7e;
+
+#define IsKana(c) (((c) >= 0xa1) && ((c) <= 0xdf))
+#define IsJisChar(c) (((c) >= 0x21) && ((c) <= 0x7e))
+
+#define TQValidChar(u) ((u) ? TQChar((ushort)(u)) : TQChar::tqreplacement)
+
+enum Iso2022State{ Ascii, MinState = Ascii,
+ JISX0201_Latin, JISX0201_Kana,
+ JISX0208_1978, JISX0208_1983,
+ JISX0212, MaxState = JISX0212,
+ UnknownState };
+
+static const char Esc_CHARS[] = "()*+-./";
+
+static const char Esc_Ascii[] = {Esc, '(', 'B', 0 };
+static const char Esc_JISX0201_Latin[] = {Esc, '(', 'J', 0 };
+static const char Esc_JISX0201_Kana[] = {Esc, '(', 'I', 0 };
+static const char Esc_JISX0208_1978[] = {Esc, '$', '@', 0 };
+static const char Esc_JISX0208_1983[] = {Esc, '$', 'B', 0 };
+static const char Esc_JISX0212[] = {Esc, '$', '(', 'D', 0 };
+static const char * const Esc_SEQ[] = { Esc_Ascii,
+ Esc_JISX0201_Latin,
+ Esc_JISX0201_Kana,
+ Esc_JISX0208_1978,
+ Esc_JISX0208_1983,
+ Esc_JISX0212 };
+
+/*! \internal */
+TQJisCodec::TQJisCodec() : conv(TQJpUnicodeConv::newConverter(TQJpUnicodeConv::Default))
+{
+}
+
+
+/*! \internal */
+TQJisCodec::~TQJisCodec()
+{
+ delete (TQJpUnicodeConv*)conv;
+ conv = 0;
+}
+
+
+/*! \internal */
+int TQJisCodec::mibEnum() const
+{
+ /*
+ Name: JIS_Encoding
+ MIBenum: 16
+ Source: JIS X 0202-1991. Uses ISO 2022 escape sequences to
+ shift code sets as documented in JIS X 0202-1991.
+ Alias: csJISEncoding
+ */
+ return 16;
+}
+
+/*! \internal */
+TQCString TQJisCodec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ int l = TQMIN((int)uc.length(),lenInOut);
+ TQCString result;
+ Iso2022State state = Ascii;
+ Iso2022State prev = Ascii;
+ for (int i=0; i<l; i++) {
+ TQChar ch = uc[i];
+ uint j;
+ if ( ch.row() == 0x00 && ch.cell() < 0x80 ) {
+ // Ascii
+ if (state != JISX0201_Latin ||
+ ch.cell() == ReverseSolidus || ch.cell() == Tilde) {
+ state = Ascii;
+ }
+ j = ch.cell();
+ } else if ((j = conv->tqunicodeToJisx0201(ch.row(), ch.cell())) != 0) {
+ if (j < 0x80) {
+ // JIS X 0201 Latin
+ if (state != Ascii ||
+ ch.cell() == YenSign || ch.cell() == Overline) {
+ state = JISX0201_Latin;
+ }
+ } else {
+ // JIS X 0201 Kana
+ state = JISX0201_Kana;
+ j &= 0x7f;
+ }
+ } else if ((j = conv->tqunicodeToJisx0208(ch.row(), ch.cell())) != 0) {
+ // JIS X 0208
+ state = JISX0208_1983;
+ } else if ((j = conv->tqunicodeToJisx0212(ch.row(), ch.cell())) != 0) {
+ // JIS X 0212
+ state = JISX0212;
+ } else {
+ // Invalid
+ state = UnknownState;
+ j = '?';
+ }
+ if (state != prev) {
+ if (state == UnknownState) {
+ result += Esc_Ascii;
+ } else {
+ result += Esc_SEQ[state - MinState];
+ }
+ prev = state;
+ }
+ if (j < 0x0100) {
+ result += j & 0xff;
+ } else {
+ result += (j >> 8) & 0xff;
+ result += j & 0xff;
+ }
+ }
+ if (prev != Ascii) {
+ result += Esc_Ascii;
+ }
+ lenInOut = result.length();
+ return result;
+}
+
+/*! \internal */
+TQString TQJisCodec::toUnicode(const char* chars, int len) const
+{
+ TQString result;
+ Iso2022State state = Ascii, prev = Ascii;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ if ( ch == Esc ) {
+ // Escape sequence
+ state = UnknownState;
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if (c2 == '$') {
+ if ( i < len-1 ) {
+ uchar c3 = chars[++i];
+ if (strchr(Esc_CHARS, c3)) {
+ if ( i < len-1 ) {
+ uchar c4 = chars[++i];
+ if (c4 == '(') {
+ switch (c4) {
+ case 'D':
+ state = JISX0212; // Esc $ ( D
+ break;
+ }
+ }
+ }
+ } else {
+ switch (c3) {
+ case '@':
+ state = JISX0208_1978; // Esc $ @
+ break;
+ case 'B':
+ state = JISX0208_1983; // Esc $ B
+ break;
+ }
+ }
+ }
+ } else {
+ if (strchr(Esc_CHARS, c2)) {
+ if ( i < len-1 ) {
+ uchar c3 = chars[++i];
+ if (c2 == '(') {
+ switch (c3) {
+ case 'B':
+ state = Ascii; // Esc ( B
+ break;
+ case 'I':
+ state = JISX0201_Kana; // Esc ( I
+ break;
+ case 'J':
+ state = JISX0201_Latin; // Esc ( J
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ } else if (ch == So) {
+ // Shift out
+ prev = state;
+ state = JISX0201_Kana;
+ } else if (ch == Si) {
+ // Shift in
+ if (prev == Ascii || prev == JISX0201_Latin) {
+ state = prev;
+ } else {
+ state = Ascii;
+ }
+ } else {
+ uint u;
+ switch (state) {
+ case Ascii:
+ if (ch < 0x80) {
+ result += TQChar(ch);
+ break;
+ }
+ /* fall throught */
+ case JISX0201_Latin:
+ u = conv->jisx0201ToUnicode(ch);
+ result += TQValidChar(u);
+ break;
+ case JISX0201_Kana:
+ u = conv->jisx0201ToUnicode(ch | 0x80);
+ result += TQValidChar(u);
+ break;
+ case JISX0208_1978:
+ case JISX0208_1983:
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ u = conv->jisx0208ToUnicode(ch & 0x7f, c2 & 0x7f);
+ result += TQValidChar(u);
+ }
+ break;
+ case JISX0212:
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ u = conv->jisx0212ToUnicode(ch & 0x7f, c2 & 0x7f);
+ result += TQValidChar(u);
+ }
+ break;
+ default:
+ result += TQChar::tqreplacement;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+/*! \internal */
+const char* TQJisCodec::name() const
+{
+ return "JIS7";
+}
+
+/*!
+ Returns the codec's mime name.
+*/
+const char* TQJisCodec::mimeName() const
+{
+ return "ISO-2022-JP";
+}
+
+/*! \internal */
+int TQJisCodec::heuristicNameMatch(const char* hint) const
+{
+ if ( qstrnicmp( hint, "ISO-2022-JP", 11 ) == 0 )
+ return 10000;
+ if ( simpleHeuristicNameMatch( "ISO-2022-JP-2", hint ) > 0 )
+ return 10;
+
+ int score = 0;
+ bool ja = FALSE;
+ if (qstrnicmp(hint, "ja_JP", 5) == 0 || qstrnicmp(hint, "japan", 5) == 0) {
+ score += 3;
+ ja = TRUE;
+ } else if (qstrnicmp(hint, "ja", 2) == 0) {
+ score += 2;
+ ja = TRUE;
+ }
+ const char *p;
+ if (ja) {
+ p = strchr(hint, '.');
+ if (p == 0) {
+ return score - 2;
+ }
+ p++;
+ } else {
+ p = hint;
+ }
+ if (p) {
+ if ((qstricmp(p, "JIS") == 0) ||
+ (qstricmp(p, "JIS7") == 0) ||
+ (simpleHeuristicNameMatch("ISO-2022-JP", p) > 0)) {
+ return score + 4;
+ }
+ }
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+/*! \internal */
+int TQJisCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ int score = 0;
+ Iso2022State state = Ascii, prev = Ascii;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ // No nulls allowed.
+ if ( !ch )
+ return -1;
+ if ( ch == Esc ) {
+ // Escape sequence
+ state = UnknownState;
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if (c2 == '$') {
+ if ( i < len-1 ) {
+ uchar c3 = chars[++i];
+ if (strchr(Esc_CHARS, c3)) {
+ if ( i < len-1 ) {
+ uchar c4 = chars[++i];
+ if (c4 == '(') {
+ switch (c4) {
+ case 'D':
+ state = JISX0212; // Esc $ ( D
+ score++;
+ break;
+ }
+ }
+ }
+ score++;
+ } else {
+ switch (c3) {
+ case '@':
+ state = JISX0208_1978; // Esc $ @
+ score++;
+ break;
+ case 'B':
+ state = JISX0208_1983; // Esc $ B
+ score++;
+ break;
+ }
+ }
+ }
+ score++;
+ } else {
+ if (strchr(Esc_CHARS, c2)) {
+ if ( i < len-1 ) {
+ uchar c3 = chars[++i];
+ if (c2 == '(') {
+ switch (c3) {
+ case 'B':
+ state = Ascii; // Esc ( B
+ score++;
+ break;
+ case 'I':
+ state = JISX0201_Kana; // Esc ( I
+ score++;
+ break;
+ case 'J':
+ state = JISX0201_Latin; // Esc ( J
+ score++;
+ break;
+ }
+ }
+ }
+ score++;
+ }
+ }
+ }
+ if ( state == UnknownState ) {
+ return -1;
+ }
+ score++;
+ } else if (ch == So) {
+ // Shift out
+ prev = state;
+ state = JISX0201_Kana;
+ score++;
+ } else if (ch == Si) {
+ // Shift in
+ if (prev == Ascii || prev == JISX0201_Latin) {
+ state = prev;
+ } else {
+ state = Ascii;
+ }
+ score++;
+ } else {
+ switch (state) {
+ case Ascii:
+ case JISX0201_Latin:
+ if ( ch < 32 && ch != '\t' && ch != '\n' && ch != '\r' ) {
+ // Suspicious
+ if ( score )
+ score--;
+ } else {
+ // Inconclusive
+ }
+ break;
+ case JISX0201_Kana:
+ if ( !IsKana(ch | 0x80) ) {
+ return -1;
+ }
+ score++;
+ break;
+ case JISX0208_1978:
+ case JISX0208_1983:
+ case JISX0212:
+ if ( !IsJisChar(ch) ) {
+ // Invalid
+ return -1;
+ }
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( !IsJisChar(c2) ) {
+ // Invalid
+ return -1;
+ }
+ score++;
+ }
+ score++;
+ break;
+ default:
+ return -1;
+ }
+ }
+ }
+ return score;
+}
+
+class TQJisDecoder : public TQTextDecoder {
+ uchar buf[4];
+ int nbuf;
+ Iso2022State state, prev;
+ bool esc;
+ const TQJpUnicodeConv * const conv;
+public:
+ TQJisDecoder(const TQJpUnicodeConv *c) : nbuf(0), state(Ascii), prev(Ascii), esc(FALSE), conv(c)
+ {
+ }
+
+ TQString toUnicode(const char* chars, int len)
+ {
+ TQString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ if (esc) {
+ // Escape sequence
+ state = UnknownState;
+ switch (nbuf) {
+ case 0:
+ if (ch == '$' || strchr(Esc_CHARS, ch)) {
+ buf[nbuf++] = ch;
+ } else {
+ nbuf = 0;
+ esc = FALSE;
+ }
+ break;
+ case 1:
+ if (buf[0] == '$') {
+ if (strchr(Esc_CHARS, ch)) {
+ buf[nbuf++] = ch;
+ } else {
+ switch (ch) {
+ case '@':
+ state = JISX0208_1978; // Esc $ @
+ break;
+ case 'B':
+ state = JISX0208_1983; // Esc $ B
+ break;
+ }
+ nbuf = 0;
+ esc = FALSE;
+ }
+ } else {
+ if (buf[0] == '(') {
+ switch (ch) {
+ case 'B':
+ state = Ascii; // Esc ( B
+ break;
+ case 'I':
+ state = JISX0201_Kana; // Esc ( I
+ break;
+ case 'J':
+ state = JISX0201_Latin; // Esc ( J
+ break;
+ }
+ }
+ nbuf = 0;
+ esc = FALSE;
+ }
+ break;
+ case 2:
+ if (buf[1] == '(') {
+ switch (ch) {
+ case 'D':
+ state = JISX0212; // Esc $ ( D
+ break;
+ }
+ }
+ nbuf = 0;
+ esc = FALSE;
+ break;
+ }
+ } else {
+ if (ch == Esc) {
+ // Escape sequence
+ nbuf = 0;
+ esc = TRUE;
+ } else if (ch == So) {
+ // Shift out
+ prev = state;
+ state = JISX0201_Kana;
+ nbuf = 0;
+ } else if (ch == Si) {
+ // Shift in
+ if (prev == Ascii || prev == JISX0201_Latin) {
+ state = prev;
+ } else {
+ state = Ascii;
+ }
+ nbuf = 0;
+ } else {
+ uint u;
+ switch (nbuf) {
+ case 0:
+ switch (state) {
+ case Ascii:
+ if (ch < 0x80) {
+ result += TQChar(ch);
+ break;
+ }
+ /* fall throught */
+ case JISX0201_Latin:
+ u = conv->jisx0201ToUnicode(ch);
+ result += TQValidChar(u);
+ break;
+ case JISX0201_Kana:
+ u = conv->jisx0201ToUnicode(ch | 0x80);
+ result += TQValidChar(u);
+ break;
+ case JISX0208_1978:
+ case JISX0208_1983:
+ case JISX0212:
+ buf[nbuf++] = ch;
+ break;
+ default:
+ result += TQChar::tqreplacement;
+ break;
+ }
+ break;
+ case 1:
+ switch (state) {
+ case JISX0208_1978:
+ case JISX0208_1983:
+ u = conv->jisx0208ToUnicode(buf[0] & 0x7f, ch & 0x7f);
+ result += TQValidChar(u);
+ break;
+ case JISX0212:
+ u = conv->jisx0212ToUnicode(buf[0] & 0x7f, ch & 0x7f);
+ result += TQValidChar(u);
+ break;
+ default:
+ result += TQChar::tqreplacement;
+ break;
+ }
+ nbuf = 0;
+ break;
+ }
+ }
+ }
+ }
+ return result;
+ }
+};
+
+/*! \internal */
+TQTextDecoder* TQJisCodec::makeDecoder() const
+{
+ return new TQJisDecoder(conv);
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqjiscodec.h b/tqtinterface/qt4/src/codecs/tqjiscodec.h
new file mode 100644
index 0000000..426ef2a
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqjiscodec.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Definition of TQJisCodec class
+**
+** Created : 990225
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Most of the code here was originally written by Serika Kurusugawa
+// a.k.a. Junji Takagi, and is included in TQt with the author's permission,
+// and the grateful thanks of the Trolltech team.
+
+/*
+ * Copyright (C) 1999 Serika Kurusugawa, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef TQJISCODEC_H
+#define TQJISCODEC_H
+
+#ifndef TQT_H
+#include "tqtextcodec.h"
+#include "tqjpunicode.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_BIG_CODECS
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_CODECS_JP
+#else
+#define TQ_EXPORT_CODECS_JP TQ_EXPORT
+#endif
+
+class TQ_EXPORT_CODECS_JP TQJisCodec : public TQTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+ const char* mimeName() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+
+ TQJisCodec();
+ ~TQJisCodec();
+
+protected:
+ const TQJpUnicodeConv *conv;
+};
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqjpunicode.cpp b/tqtinterface/qt4/src/codecs/tqjpunicode.cpp
new file mode 100644
index 0000000..d0ced80
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqjpunicode.cpp
@@ -0,0 +1,10743 @@
+/****************************************************************************
+**
+** Implementation of TQJpUnicodeConv class
+**
+** Created : 990225
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/*! \class TQJpUnicodeConv tqjpunicode.h
+ \reentrant
+ \ingroup i18n
+
+ \brief The TQJpUnicodeConv class provides implementation support for
+ TQJisCodec, TQSjisCodec, and TQEucJpCodec.
+
+ \internal
+
+ Most of the code here was written by Serika Kurusugawa,
+ a.k.a. Junji Takagi, and is included in TQt with the author's
+ permission and the grateful thanks of the Trolltech team.
+ Here is the copyright statement for the code as it was at the
+ point of contribution. Trolltech's subsequent modifications
+ are covered by the usual copyright for TQt.
+
+ \legalese
+
+ Copyright (C) 1999 Serika Kurusugawa. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ \list 1
+ \i Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ \i Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ \endlist
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS".
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+#include "tqjpunicode.h"
+#ifndef TQT_NO_BIG_CODECS
+#include "tqcstring.h"
+#ifdef TQ_OS_TEMP
+#include "tqwinfunctions_wce.h"
+#endif
+#include <stdlib.h>
+
+#define USE_JISX0212
+
+#define TQ_STRICT
+
+#define IsLatin(c) (/*((c) >= 0x00) &&*/ ((c) <= 0x7f))
+#define IsKana(c) (((c) >= 0xa1) && ((c) <= 0xdf))
+#define IsJisChar(c) (((c) >= 0x21) && ((c) <= 0x7e))
+#define IsSjisChar1(c) ((((c) >= 0x81) && ((c) <= 0x9f)) || \
+ (((c) >= 0xe0) && ((c) <= 0xfc)))
+#define IsSjisUDC1(c) (((c) >= 0xf0) && ((c) <= 0xfc))
+#define IsSjisChar2(c) (((c) >= 0x40) && ((c) != 0x7f) && ((c) <= 0xfc))
+
+#define IsSjisIBMVDCChar1(c) (((c) >= 0xfa) && ((c) <= 0xfc))
+
+static uint jisx0208ToSjis(uint h, uint l);
+static
+inline uint jisx0208ToSjis(uint jis)
+{
+ return jisx0208ToSjis((jis & 0xff00) >> 8, (jis & 0x00ff));
+}
+
+static uint sjisToJisx0208(uint h, uint l);
+#if 0
+static
+inline uint sjisToJisx0208(uint sjis)
+{
+ return sjisToJisx0208((sjis & 0xff00) >> 8, (sjis & 0x00ff));
+}
+#endif
+
+static uint jisx0201ToUnicode11(uint h, uint l);
+static uint jisx0208ToUnicode11(uint h, uint l);
+static uint jisx0212ToUnicode11(uint h, uint l);
+
+static uint tqunicode11ToJisx0201(uint h, uint l);
+static uint tqunicode11ToJisx0208(uint h, uint l);
+static uint tqunicode11ToJisx0212(uint h, uint l);
+
+/*
+ * Unicode 1.1 conversion.
+ */
+
+/*!
+ \fn TQJpUnicodeConv::TQJpUnicodeConv (int r)
+ \internal
+*/
+
+
+/*! \internal */
+uint TQJpUnicodeConv::asciiToUnicode(uint h, uint l) const
+{
+ if ((h == 0) && (l < 0x80)) {
+ return l;
+ }
+ return 0x0000;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::jisx0201ToUnicode(uint h, uint l) const
+{
+ if (h == 0) {
+ if (IsLatin(l)) {
+ return jisx0201LatinToUnicode(h, l);
+ } else if (IsKana(l)) {
+ return jisx0201KanaToUnicode(h, l);
+ }
+ }
+ return 0x0000;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::jisx0201LatinToUnicode(uint h, uint l) const
+{
+ if ((h == 0) && IsLatin(l)) {
+ return jisx0201ToUnicode11(h, l);
+ }
+ return 0x0000;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::jisx0201KanaToUnicode(uint h, uint l) const
+{
+ if ((h == 0) && IsKana(l)) {
+ return jisx0201ToUnicode11(h, l);
+ }
+ return 0x0000;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::jisx0208ToUnicode(uint h, uint l) const
+{
+ if (rule & UDC){
+ if ((0x75 <= h) && (h <= 0x7e) && IsJisChar(l)/*0x21 - 0x7e*/) {
+ // User Defined Char (mapped to Private Use Area)
+ return 0xe000 + (h - 0x75) * 0x5e + (l - 0x21);
+ }
+ }
+ if ((rule & NEC_VDC) == 0) {
+ if ((h == 0x2d) && (IsJisChar(l)/*0x21 - 0x7c*/)) {
+ // NEC Vendor Defined Char
+ return 0x0000;
+ }
+ }
+ return jisx0208ToUnicode11(h, l);
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::jisx0212ToUnicode(uint h, uint l) const
+{
+ if (rule & UDC){
+ if ((0x75 <= h) && (h <= 0x7e) && IsJisChar(l)/*0x21 - 0x7e*/) {
+ // User Defined Char (mapped to Private Use Area)
+ return 0xe3ac + (h - 0x75) * 0x5e + (l - 0x21);
+ }
+ }
+ if ((rule & IBM_VDC) == 0){
+ if (((h == 0x73) && (0x73 <= l) && (l <= 0x7e)) ||
+ ((h == 0x74) && (IsJisChar(l)/*0x21 - 0x7e*/))) {
+ // IBM Vendor Defined Char
+ return 0x0000;
+ }
+ }
+ return jisx0212ToUnicode11(h, l);
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::tqunicodeToAscii(uint h, uint l) const
+{
+ if ((h == 0) && (l < 0x80)) {
+ return l;
+ }
+ return 0x0000;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::tqunicodeToJisx0201(uint h, uint l) const
+{
+ uint jis;
+ if ((jis = tqunicodeToJisx0201Latin(h, l)) != 0) {
+ return jis;
+ } else if ((jis = tqunicodeToJisx0201Kana(h, l)) != 0) {
+ return jis;
+ }
+ return 0x0000;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::tqunicodeToJisx0201Latin(uint h, uint l) const
+{
+ uint jis = tqunicode11ToJisx0201(h, l);
+ if (IsLatin(jis)) {
+ return jis;
+ }
+ return 0x0000;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::tqunicodeToJisx0201Kana(uint h, uint l) const
+{
+ uint jis = tqunicode11ToJisx0201(h, l);
+ if (IsKana(jis)) {
+ return jis;
+ }
+ return 0x0000;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::tqunicodeToJisx0208(uint h, uint l) const
+{
+ if (rule & UDC){
+ uint tqunicode = (h << 8) | l;
+ if ((0xe000 <= tqunicode) && (tqunicode <= 0xe3ab)) {
+ // User Defined Char (mapped to Private Use Area)
+ tqunicode -= 0xe000;
+ return ((0x75 + tqunicode / 0x5e ) << 8) | (0x21 + tqunicode % 0x5e);
+ }
+ }
+ uint jis = tqunicode11ToJisx0208(h, l);
+ if ((rule & NEC_VDC) == 0) {
+ if ((0x2d21 <= jis) && (jis <= 0x2d7c)) {
+ // NEC Vendor Defined Char
+ return 0x0000;
+ }
+ }
+ return jis;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::tqunicodeToJisx0212(uint h, uint l) const
+{
+ if (rule & UDC){
+ uint tqunicode = (h << 8) | l;
+ if ((0xe3ac <= tqunicode) && (tqunicode <= 0xe757)) {
+ // User Defined Char (mapped to Private Use Area)
+ tqunicode -= 0xe3ac;
+ return ((0x75 + tqunicode / 0x5e ) << 8) | (0x21 + tqunicode % 0x5e);
+ }
+ }
+ uint jis = tqunicode11ToJisx0212(h, l);
+ if ((rule & IBM_VDC) == 0){
+ if (((0x7373 <= jis) && (jis <= 0x737e)) ||
+ ((0x7421 <= jis) && (jis <= 0x747e))) {
+ // IBM Vendor Defined Char
+ return 0x0000;
+ }
+ }
+ return jis;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::sjisToUnicode(uint h, uint l) const
+{
+ if (h == 0) {
+ return jisx0201ToUnicode(h, l);
+ } else if (IsSjisChar1(h) && IsSjisChar2(l)) {
+ return jisx0208ToUnicode(sjisToJisx0208(h, l));
+ }
+ return 0x0000;
+}
+
+/*! \internal */
+uint TQJpUnicodeConv::tqunicodeToSjis(uint h, uint l) const
+{
+ uint jis;
+ if ((jis = tqunicodeToJisx0201(h, l)) != 0x0000) {
+ return jis;
+ } else if ((jis = tqunicodeToJisx0208(h, l)) != 0x0000) {
+ return jisx0208ToSjis(jis);
+ } else if ((jis = tqunicodeToJisx0212(h, l)) != 0x0000) {
+ return 0x0000;
+ }
+ return 0x0000;
+}
+
+/*
+ * Unicode 1.1 with JISX0201 conversion.
+ */
+
+class TQJpUnicodeConv_Unicode_JISX0201 : public TQJpUnicodeConv {
+public:
+ TQJpUnicodeConv_Unicode_JISX0201(int r) : TQJpUnicodeConv(r) {}
+
+// uint AsciiToUnicode(uint h, uint l) const;
+// uint Jisx0201ToUnicode(uint h, uint l) const;
+// uint Jisx0201LatinToUnicode(uint h, uint l) const;
+// uint Jisx0201KanaToUnicode(uint h, uint l) const;
+// uint Jisx0208ToUnicode(uint h, uint l) const;
+// uint Jisx0212ToUnicode(uint h, uint l) const;
+
+// uint UnicodeToAscii(uint h, uint l) const;
+// uint UnicodeToJisx0201(uint h, uint l) const;
+// uint UnicodeToJisx0201Latin(uint h, uint l) const;
+// uint UnicodeToJisx0201Kana(uint h, uint l) const;
+// uint UnicodeToJisx0208(uint h, uint l) const;
+// uint UnicodeToJisx0212(uint h, uint l) const;
+};
+
+/*
+ * Unicode 1.1 with ASCII conversion.
+ */
+
+class TQJpUnicodeConv_Unicode_ASCII : public TQJpUnicodeConv {
+public:
+ TQJpUnicodeConv_Unicode_ASCII(int r) : TQJpUnicodeConv(r) {}
+
+// uint AsciiToUnicode(uint h, uint l) const;
+// uint Jisx0201ToUnicode(uint h, uint l) const;
+// uint Jisx0201LatinToUnicode(uint h, uint l) const;
+// uint Jisx0201KanaToUnicode(uint h, uint l) const;
+ uint jisx0208ToUnicode(uint h, uint l) const;
+ uint jisx0212ToUnicode(uint h, uint l) const;
+
+// uint UnicodeToAscii(uint h, uint l) const;
+// uint UnicodeToJisx0201(uint h, uint l) const;
+// uint UnicodeToJisx0201Latin(uint h, uint l) const;
+// uint UnicodeToJisx0201Kana(uint h, uint l) const;
+ uint tqunicodeToJisx0208(uint h, uint l) const;
+ uint tqunicodeToJisx0212(uint h, uint l) const;
+};
+
+uint TQJpUnicodeConv_Unicode_ASCII::jisx0208ToUnicode(uint h, uint l) const
+{
+ if ((h == 0x21) && (l == 0x40)) {
+ return 0xff3c;
+ }
+ return TQJpUnicodeConv::jisx0208ToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_Unicode_ASCII::jisx0212ToUnicode(uint h, uint l) const
+{
+ if ((h == 0x22) && (l == 0x37)) {
+ return 0xff5e;
+ }
+ return TQJpUnicodeConv::jisx0212ToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_Unicode_ASCII::tqunicodeToJisx0208(uint h, uint l) const
+{
+ if ((h == 0x00) && (l == 0x5c)) {
+ return 0x0000;
+ }
+ return TQJpUnicodeConv::tqunicodeToJisx0208(h, l);
+}
+
+/*! \internal */
+uint TQJpUnicodeConv_Unicode_ASCII::tqunicodeToJisx0212(uint h, uint l) const
+{
+ if ((h == 0x00) && (l == 0x7e)) {
+ return 0x0000;
+ }
+ if ((h == 0xff) && (l == 0x5e)) {
+ return 0x2237;
+ }
+ return TQJpUnicodeConv::tqunicodeToJisx0208(h, l);
+}
+
+/*
+ * JISX0221 with JISX0201 conversion.
+ */
+
+class TQJpUnicodeConv_JISX0221_JISX0201 : public TQJpUnicodeConv {
+public:
+ TQJpUnicodeConv_JISX0221_JISX0201(int r) : TQJpUnicodeConv(r) {}
+
+ uint asciiToUnicode(uint h, uint l) const;
+// uint Jisx0201ToUnicode(uint h, uint l) const;
+// uint Jisx0201LatinToUnicode(uint h, uint l) const;
+// uint Jisx0201KanaToUnicode(uint h, uint l) const;
+ uint jisx0208ToUnicode(uint h, uint l) const;
+// uint Jisx0212ToUnicode(uint h, uint l) const;
+
+ uint tqunicodeToAscii(uint h, uint l) const;
+// uint UnicodeToJisx0201(uint h, uint l) const;
+// uint UnicodeToJisx0201Latin(uint h, uint l) const;
+// uint UnicodeToJisx0201Kana(uint h, uint l) const;
+ uint tqunicodeToJisx0208(uint h, uint l) const;
+// uint UnicodeToJisx0212(uint h, uint l) const;
+};
+
+uint TQJpUnicodeConv_JISX0221_JISX0201::asciiToUnicode(uint h, uint l) const
+{
+ return jisx0201LatinToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_JISX0221_JISX0201::jisx0208ToUnicode(uint h, uint l) const
+{
+ if ((h == 0x21) && (l == 0x3d)) {
+ return 0x2014;
+ }
+ return TQJpUnicodeConv::jisx0208ToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_JISX0221_JISX0201::tqunicodeToAscii(uint h, uint l) const
+{
+ return tqunicodeToJisx0201Latin(h, l);
+}
+
+uint TQJpUnicodeConv_JISX0221_JISX0201::tqunicodeToJisx0208(uint h, uint l) const
+{
+#ifdef TQ_STRICT
+ if ((h == 0x20) && (l == 0x15)) {
+ return 0x0000;
+ }
+#endif
+ if ((h == 0x20) && (l == 0x14)) {
+ return 0x213d;
+ }
+ return TQJpUnicodeConv::tqunicodeToJisx0208(h, l);
+}
+
+/*
+ * JISX0221 with ASCII conversion.
+ */
+
+class TQJpUnicodeConv_JISX0221_ASCII : public TQJpUnicodeConv {
+public:
+ TQJpUnicodeConv_JISX0221_ASCII(int r) : TQJpUnicodeConv(r) {}
+
+// uint AsciiToUnicode(uint h, uint l) const;
+// uint Jisx0201ToUnicode(uint h, uint l) const;
+ uint jisx0201LatinToUnicode(uint h, uint l) const;
+// uint Jisx0201KanaToUnicode(uint h, uint l) const;
+ uint jisx0208ToUnicode(uint h, uint l) const;
+ uint jisx0212ToUnicode(uint h, uint l) const;
+
+// uint UnicodeToAscii(uint h, uint l) const;
+// uint UnicodeToJisx0201(uint h, uint l) const;
+ uint tqunicodeToJisx0201Latin(uint h, uint l) const;
+// uint UnicodeToJisx0201Kana(uint h, uint l) const;
+ uint tqunicodeToJisx0208(uint h, uint l) const;
+ uint tqunicodeToJisx0212(uint h, uint l) const;
+};
+
+uint TQJpUnicodeConv_JISX0221_ASCII::jisx0201LatinToUnicode(uint h, uint l) const
+{
+ return asciiToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_JISX0221_ASCII::jisx0208ToUnicode(uint h, uint l) const
+{
+ if (h == 0x21) {
+ if (l == 0x31) {
+ return 0x203e;
+ } else if (l == 0x3d) {
+ return 0x02014;
+ } else if (l == 0x40) {
+ return 0xff3c;
+ } else if (l == 0x6f) {
+ return 0x00a5;
+ }
+ }
+ return TQJpUnicodeConv::jisx0208ToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_JISX0221_ASCII::jisx0212ToUnicode(uint h, uint l) const
+{
+ if ((h == 0x22) && (l == 0x37)) {
+ return 0xff5e;
+ }
+ return TQJpUnicodeConv::jisx0212ToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_JISX0221_ASCII::tqunicodeToJisx0201Latin(uint h, uint l) const
+{
+ return TQJpUnicodeConv::tqunicodeToAscii(h, l);
+}
+
+uint TQJpUnicodeConv_JISX0221_ASCII::tqunicodeToJisx0208(uint h, uint l) const
+{
+#ifdef TQ_STRICT
+ if (((h == 0x00) && (l == 0x5c)) ||
+ ((h == 0x20) && (l == 0x15)) ||
+ ((h == 0xff) && ((l == 0xe3) || (l == 0xe5)))) {
+ return 0x0000;
+ }
+#else
+ if ((h == 0x00) && (l == 0x5c)) {
+ return 0x0000;
+ }
+#endif
+ if ((h == 0x00) && (l == 0xa5)) {
+ return 0x216f;
+ } else if (h == 0x20) {
+ if (l == 0x14) {
+ return 0x213d;
+ } else if (l == 0x3e) {
+ return 0x2131;
+ }
+ }
+ return TQJpUnicodeConv::tqunicodeToJisx0208(h, l);
+}
+
+/*! \internal */
+uint TQJpUnicodeConv_JISX0221_ASCII::tqunicodeToJisx0212(uint h, uint l) const
+{
+ if ((h == 0x00) && (l == 0x7e)) {
+ return 0x0000;
+ }
+ if ((h == 0xff) && (l == 0x5e)) {
+ return 0x2237;
+ }
+ return TQJpUnicodeConv::tqunicodeToJisx0212(h, l);
+}
+
+/*
+ * Sun Microsystems conversion.
+ */
+
+class TQJpUnicodeConv_Sun : public TQJpUnicodeConv {
+public:
+ TQJpUnicodeConv_Sun(int r) : TQJpUnicodeConv(r) {}
+
+// uint AsciiToUnicode(uint h, uint l) const;
+// uint Jisx0201ToUnicode(uint h, uint l) const;
+ uint jisx0201LatinToUnicode(uint h, uint l) const;
+// uint Jisx0201KanaToUnicode(uint h, uint l) const;
+ uint jisx0208ToUnicode(uint h, uint l) const;
+ uint jisx0212ToUnicode(uint h, uint l) const;
+
+ uint tqunicodeToAscii(uint h, uint l) const;
+// uint UnicodeToJisx0201(uint h, uint l) const;
+ uint tqunicodeToJisx0201Latin(uint h, uint l) const;
+// uint UnicodeToJisx0201Kana(uint h, uint l) const;
+ uint tqunicodeToJisx0208(uint h, uint l) const;
+ uint tqunicodeToJisx0212(uint h, uint l) const;
+};
+
+uint TQJpUnicodeConv_Sun::jisx0201LatinToUnicode(uint h, uint l) const
+{
+ return asciiToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_Sun::jisx0208ToUnicode(uint h, uint l) const
+{
+ if ((h == 0x21) && (l == 0x40)) {
+ return 0xff3c;
+ }
+ return TQJpUnicodeConv::jisx0208ToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_Sun::jisx0212ToUnicode(uint h, uint l) const
+{
+#if 1
+ // Added by Serika Kususugawa to avoid conflict on U+007c.
+ if ((h == 0x22) && (l == 0x37)) {
+ return 0xff5e;
+ }
+#endif
+ return TQJpUnicodeConv::jisx0212ToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_Sun::tqunicodeToAscii(uint h, uint l) const
+{
+ if ((h == 0x00) && (l == 0xa5)) {
+ return 0x005c;
+ } else if ((h == 0x20) && (l == 0x3e)) {
+ return 0x007e;
+ }
+ return TQJpUnicodeConv::tqunicodeToAscii(h, l);
+}
+
+uint TQJpUnicodeConv_Sun::tqunicodeToJisx0201Latin(uint h, uint l) const
+{
+ return TQJpUnicodeConv::tqunicodeToAscii(h, l);
+}
+
+uint TQJpUnicodeConv_Sun::tqunicodeToJisx0208(uint h, uint l) const
+{
+ if ((h == 0x00) && (l == 0xa5)) {
+ return 0x0000;
+ } else if ((h == 0x20) && (l == 0x3e)) {
+ return 0x0000;
+ }
+ return TQJpUnicodeConv::tqunicodeToJisx0208(h, l);
+}
+
+/*! \internal */
+uint TQJpUnicodeConv_Sun::tqunicodeToJisx0212(uint h, uint l) const
+{
+#if 1
+ // Added by Serika Kususugawa to avoid conflict on U+007c.
+ if ((h == 0x00) && (l == 0x7e)) {
+ return 0x0000;
+ }
+ if ((h == 0xff) && (l == 0x5e)) {
+ return 0x2237;
+ }
+#endif
+ return TQJpUnicodeConv::tqunicodeToJisx0212(h, l);
+}
+
+/*
+ * Microsoft conversion.
+ */
+
+class TQJpUnicodeConv_Microsoft : public TQJpUnicodeConv {
+public:
+ TQJpUnicodeConv_Microsoft(int r) : TQJpUnicodeConv(r) {}
+
+// uint AsciiToUnicode(uint h, uint l) const;
+// uint Jisx0201ToUnicode(uint h, uint l) const;
+ uint jisx0201LatinToUnicode(uint h, uint l) const;
+// uint Jisx0201KanaToUnicode(uint h, uint l) const;
+ uint jisx0208ToUnicode(uint h, uint l) const;
+ uint jisx0212ToUnicode(uint h, uint l) const;
+
+// uint UnicodeToAscii(uint h, uint l) const;
+// uint UnicodeToJisx0201(uint h, uint l) const;
+ uint tqunicodeToJisx0201Latin(uint h, uint l) const;
+// uint UnicodeToJisx0201Kana(uint h, uint l) const;
+ uint tqunicodeToJisx0208(uint h, uint l) const;
+ uint tqunicodeToJisx0212(uint h, uint l) const;
+};
+
+uint TQJpUnicodeConv_Microsoft::jisx0201LatinToUnicode(uint h, uint l) const
+{
+ return asciiToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_Microsoft::jisx0208ToUnicode(uint h, uint l) const
+{
+ if (h == 0x21) {
+ if (l == 0x40) {
+ return 0xff3c;
+ } else if (l == 0x41) {
+ return 0xff5e;
+ } else if (l == 0x42) {
+ return 0x2225;
+ } else if (l == 0x5d) {
+ return 0xff0d;
+ } else if (l == 0x71) {
+ return 0xffe0;
+ } else if (l == 0x72) {
+ return 0xffe1;
+ }
+ } else if (h == 0x22) {
+ if (l == 0x4c) {
+ return 0xffe2;
+ }
+ }
+ return TQJpUnicodeConv::jisx0208ToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_Microsoft::jisx0212ToUnicode(uint h, uint l) const
+{
+ if (h == 0x22) {
+ if (l == 0x37) {
+ return 0xff5e;
+ } else if (l == 0x43) {
+ return 0xffe4;
+ }
+ }
+ return TQJpUnicodeConv::jisx0212ToUnicode(h, l);
+}
+
+uint TQJpUnicodeConv_Microsoft::tqunicodeToJisx0201Latin(uint h, uint l) const
+{
+ return TQJpUnicodeConv::tqunicodeToAscii(h, l);
+}
+
+uint TQJpUnicodeConv_Microsoft::tqunicodeToJisx0208(uint h, uint l) const
+{
+#ifdef TQ_STRICT
+ if (((h == 0x00) && ((l == 0x5c) || (l == 0xa2) || (l == 0xa3) || (l == 0xac))) ||
+ ((h == 0x20) && (l == 0x16)) ||
+ ((h == 0x22) && (l == 0x12)) ||
+ ((h == 0x30) && (l == 0x1c))) {
+ return 0x0000;
+ }
+#else
+ if ((h == 0x00) && (l == 0x5c)) {
+ return 0x0000;
+ }
+#endif
+ if ((h == 0x22) && (l == 0x25)) {
+ return 0x2142;
+ } else if (h == 0xff) {
+ if (l == 0x0d) {
+ return 0x215d;
+ } else if (l == 0xe0) {
+ return 0x2171;
+ } else if (l == 0xe1) {
+ return 0x2172;
+ } else if (l == 0xe2) {
+ return 0x224c;
+ }
+ }
+ return TQJpUnicodeConv::tqunicodeToJisx0208(h, l);
+}
+
+uint TQJpUnicodeConv_Microsoft::tqunicodeToJisx0212(uint h, uint l) const
+{
+#ifdef TQ_STRICT
+ if ((h == 0x00) && ((l == 0x7e) || (l == 0xa6))) {
+ return 0x0000;
+ }
+#else
+ if ((h == 0x00) && (l == 0x7e)) {
+ return 0x0000;
+ }
+#endif
+ if (h == 0xff) {
+ if (l == 0x5e) {
+ return 0x2237;
+ } else if (l == 0xe4) {
+ return 0x2243;
+ }
+ }
+ return TQJpUnicodeConv::tqunicodeToJisx0212(h, l);
+}
+
+
+/*! \internal */
+TQJpUnicodeConv *TQJpUnicodeConv::newConverter(int rule)
+{
+ const char * e = 0;
+ if ( rule == Default && (e=getenv("UNICODEMAP_JP")) != 0 ) {
+ TQCString env( e );
+ for (int i = 0; i < (int)env.length(); ) {
+ int j = env.tqfind(',', i);
+ TQCString s;
+ if (j < 0) {
+ s = env.mid(i).stripWhiteSpace();
+ i = env.length();
+ } else {
+ s = env.mid(i, j - i).stripWhiteSpace();
+ i = j + 1;
+ }
+ if (qstricmp(s, "tqunicode-0.9") == 0) {
+ rule = (rule & 0xff00) | Unicode;
+ } else if (qstricmp(s, "tqunicode-0201") == 0) {
+ rule = (rule & 0xff00) | Unicode_JISX0201;
+ } else if (qstricmp(s, "tqunicode-ascii") == 0) {
+ rule = (rule & 0xff00) | Unicode_ASCII;
+ } else if (qstricmp(s, "jisx0221-1995") == 0) {
+ rule = (rule & 0xff00) | JISX0221_JISX0201;
+ } else if ((qstricmp(s, "open-0201") == 0) ||
+ (qstricmp(s, "open-19970715-0201") == 0)) {
+ rule = (rule & 0xff00) | JISX0221_JISX0201;
+ } else if ((qstricmp(s, "open-ascii") == 0) ||
+ (qstricmp(s, "open-19970715-ascii") == 0)) {
+ rule = (rule & 0xff00) | JISX0221_ASCII;
+ } else if ((qstricmp(s, "open-ms") == 0) ||
+ (qstricmp(s, "open-19970715-ms") == 0)) {
+ rule = (rule & 0xff00) | Microsoft_CP932;
+ } else if (qstricmp(s, "cp932") == 0) {
+ rule = (rule & 0xff00) | Microsoft_CP932;
+ } else if (qstricmp(s, "jdk1.1.7") == 0) {
+ rule = (rule & 0xff00) | Sun_JDK117;
+ } else if (qstricmp(s, "nec-vdc") == 0) {
+ rule = rule | NEC_VDC;
+ } else if (qstricmp(s, "ibm-vdc") == 0) {
+ rule = rule | IBM_VDC;
+ } else if (qstricmp(s, "udc") == 0) {
+ rule = rule | UDC;
+ }
+ }
+ }
+
+ switch (rule & 0x00ff) {
+ case Unicode_JISX0201:
+ return new TQJpUnicodeConv_Unicode_JISX0201(rule);
+ case Unicode_ASCII:
+ return new TQJpUnicodeConv_Unicode_ASCII(rule);
+ case JISX0221_JISX0201:
+ return new TQJpUnicodeConv_JISX0221_JISX0201(rule);
+ case JISX0221_ASCII:
+ return new TQJpUnicodeConv_JISX0221_ASCII(rule);
+ case Sun_JDK117:
+ return new TQJpUnicodeConv_Sun(rule);
+ case Microsoft_CP932:
+ return new TQJpUnicodeConv_Microsoft(rule);
+ default:
+ return new TQJpUnicodeConv_Unicode_ASCII(rule);
+ }
+}
+
+
+/*
+ * JISX0208 <-> ShiftJIS conversion.
+ */
+
+static uint jisx0208ToSjis(uint h, uint l)
+{
+ if ((0x0021 <= h) && (h <= 0x007e) && (0x0021 <= l) && (l <= 0x007e)) {
+ return ((((h - 1) >> 1) + ((h <= 0x5e) ? 0x71 : 0xb1)) << 8) |
+ (l + ((h & 1) ? ((l < 0x60) ? 0x1f : 0x20) : 0x7e));
+ }
+ return 0x0000;
+}
+
+static uint sjisToJisx0208(uint h, uint l)
+{
+ if ((((0x81 <= h) && (h <= 0x9f)) || ((0xe0 <= h) && (h <= 0xef))) &&
+ ((0x40 <= l) && (l != 0x7f) && (l <= 0xfc))) {
+ if (l < 0x9f) {
+ return (((h << 1) - ((h <= 0x9f) ? 0x00e1 : 0x0161)) << 8) |
+ (l - ((l <= 0x7f) ? 0x1f : 0x20));
+ } else {
+ return (((h << 1) - ((h <= 0x9f) ? 0x00e1 : 0x0161) + 1) << 8) |
+ (l - 0x7e);
+ }
+ }
+ return 0x0000;
+}
+
+/*
+ * This function is derived from Unicode 1.1,
+ * JIS X 0201 (1976) to Unicode mapping table version 0.9 .
+ */
+
+#define JISX0201_YEN_SIGN 0x005c
+#define UNICODE_YEN_SIGN 0x00a5
+
+#define JISX0201_OVERLINE 0x007e
+#define UNICODE_OVERLINE 0x203e
+
+static uint jisx0201ToUnicode11(uint h, uint l)
+{
+ if (h == 0x00) {
+ if (l < 0x80) {
+ if (l == JISX0201_YEN_SIGN) {
+ return UNICODE_YEN_SIGN;
+ } else if (l == JISX0201_OVERLINE) {
+ return UNICODE_OVERLINE;
+ } else {
+ return l;
+ }
+ } else if ((0xa1 <= l) && (l <= 0x00df)) {
+ return 0xff61 + l - 0x00a1;
+ }
+ }
+ return 0x0000;
+}
+
+/*
+ * This function is derived from Unicode 1.1,
+ * JIS X 0201 (1976) to Unicode mapping table version 0.9 .
+ */
+
+static uint tqunicode11ToJisx0201(uint h, uint l)
+{
+ if ((h == 0x00) && (l < 0x80)) {
+ if ((l == JISX0201_YEN_SIGN) ||
+ (l == JISX0201_OVERLINE)) {
+ return 0x0000;
+ }
+ return l;
+ } else if ((h == 0x00) && (l == 0xa5)) {
+ return JISX0201_YEN_SIGN;
+ } else if ((h == 0x20) && (l == 0x3e)) {
+ return JISX0201_OVERLINE;
+ } else if ((h == 0xff) && (0x61 <= l) && (l <= 0x9f)) {
+ return 0x00a1 + l - 0x61;
+ }
+ return 0x0000;
+}
+
+/*
+ * This data is derived from Unicode 1.1,
+ * JIS X 0208 (1990) to Unicode mapping table version 0.9 .
+ * (In addition NEC Vender Defined Char included)
+ */
+static unsigned short const jisx0208_to_tqunicode[] = {
+ /* 0x2121 - 0x217e */
+ 0x3000, 0x3001, 0x3002, 0xff0c, 0xff0e, 0x30fb, 0xff1a,
+ 0xff1b, 0xff1f, 0xff01, 0x309b, 0x309c, 0x00b4, 0xff40, 0x00a8,
+ 0xff3e, 0xffe3, 0xff3f, 0x30fd, 0x30fe, 0x309d, 0x309e, 0x3003,
+ 0x4edd, 0x3005, 0x3006, 0x3007, 0x30fc, 0x2015, 0x2010, 0xff0f,
+ 0x005c, 0x301c, 0x2016, 0xff5c, 0x2026, 0x2025, 0x2018, 0x2019,
+ 0x201c, 0x201d, 0xff08, 0xff09, 0x3014, 0x3015, 0xff3b, 0xff3d,
+ 0xff5b, 0xff5d, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, 0x300d,
+ 0x300e, 0x300f, 0x3010, 0x3011, 0xff0b, 0xff0d, 0x00b1, 0x00d7,
+ 0x00f7, 0xff1d, 0x2260, 0xff1c, 0xff1e, 0x2266, 0x2267, 0x221e,
+ 0x2234, 0x2642, 0x2640, 0x00b0, 0x2032, 0x2033, 0x2103, 0xffe5,
+ 0xff04, 0x00a2, 0x00a3, 0xff05, 0xff03, 0xff06, 0xff0a, 0xff20,
+ 0x00a7, 0x2606, 0x2605, 0x25cb, 0x25cf, 0x25ce, 0x25c7,
+ /* 0x2221 - 0x227e */
+ 0x25c6, 0x25a1, 0x25a0, 0x25b3, 0x25b2, 0x25bd, 0x25bc,
+ 0x203b, 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2208, 0x220b, 0x2286, 0x2287, 0x2282, 0x2283,
+ 0x222a, 0x2229, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2227, 0x2228, 0x00ac, 0x21d2, 0x21d4, 0x2200,
+ 0x2203, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2220, 0x22a5, 0x2312, 0x2202,
+ 0x2207, 0x2261, 0x2252, 0x226a, 0x226b, 0x221a, 0x223d, 0x221d,
+ 0x2235, 0x222b, 0x222c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x212b, 0x2030, 0x266f, 0x266d, 0x266a, 0x2020,
+ 0x2021, 0x00b6, 0x0000, 0x0000, 0x0000, 0x0000, 0x25ef,
+ /* 0x2321 - 0x237e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0xff10, 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17,
+ 0xff18, 0xff19, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27,
+ 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f,
+ 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37,
+ 0xff38, 0xff39, 0xff3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47,
+ 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f,
+ 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57,
+ 0xff58, 0xff59, 0xff5a, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2421 - 0x247e */
+ 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047,
+ 0x3048, 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f,
+ 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057,
+ 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f,
+ 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067,
+ 0x3068, 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f,
+ 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077,
+ 0x3078, 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f,
+ 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087,
+ 0x3088, 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f,
+ 0x3090, 0x3091, 0x3092, 0x3093, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2521 - 0x257e */
+ 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7,
+ 0x30a8, 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af,
+ 0x30b0, 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7,
+ 0x30b8, 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf,
+ 0x30c0, 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7,
+ 0x30c8, 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf,
+ 0x30d0, 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7,
+ 0x30d8, 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df,
+ 0x30e0, 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7,
+ 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef,
+ 0x30f0, 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2621 - 0x267e */
+ 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
+ 0x03a0, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8,
+ 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8,
+ 0x03c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2721 - 0x277e */
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401,
+ 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d,
+ 0x041e, 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425,
+ 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d,
+ 0x042e, 0x042f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451,
+ 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d,
+ 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445,
+ 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d,
+ 0x044e, 0x044f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2821 - 0x287e */
+ 0x2500, 0x2502, 0x250c, 0x2510, 0x2518, 0x2514, 0x251c,
+ 0x252c, 0x2524, 0x2534, 0x253c, 0x2501, 0x2503, 0x250f, 0x2513,
+ 0x251b, 0x2517, 0x2523, 0x2533, 0x252b, 0x253b, 0x254b, 0x2520,
+ 0x252f, 0x2528, 0x2537, 0x253f, 0x251d, 0x2530, 0x2525, 0x2538,
+ 0x2542, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2921 - 0x297e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2a21 - 0x2a7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2b21 - 0x2b7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2c21 - 0x2c7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2d21 - 0x2d7e */
+ 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466,
+ 0x2467, 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e,
+ 0x246f, 0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162,
+ 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x0000,
+ 0x3349, 0x3314, 0x3322, 0x334d, 0x3318, 0x3327, 0x3303, 0x3336,
+ 0x3351, 0x3357, 0x330d, 0x3326, 0x3323, 0x332b, 0x334a, 0x333b,
+ 0x339c, 0x339d, 0x339e, 0x338e, 0x338f, 0x33c4, 0x33a1, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x337b,
+ 0x301d, 0x301f, 0x2116, 0x33cd, 0x2121, 0x32a4, 0x32a5, 0x32a6,
+ 0x32a7, 0x32a8, 0x3231, 0x3232, 0x3239, 0x337e, 0x337d, 0x337c,
+ 0x2252, 0x2261, 0x222b, 0x222e, 0x2211, 0x221a, 0x22a5, 0x2220,
+ 0x221f, 0x22bf, 0x2235, 0x2229, 0x222a, 0x0000, 0x0000,
+ /* 0x2e21 - 0x2e7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2f21 - 0x2f7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x3021 - 0x307e */
+ 0x4e9c, 0x5516, 0x5a03, 0x963f, 0x54c0, 0x611b, 0x6328,
+ 0x59f6, 0x9022, 0x8475, 0x831c, 0x7a50, 0x60aa, 0x63e1, 0x6e25,
+ 0x65ed, 0x8466, 0x82a6, 0x9bf5, 0x6893, 0x5727, 0x65a1, 0x6271,
+ 0x5b9b, 0x59d0, 0x867b, 0x98f4, 0x7d62, 0x7dbe, 0x9b8e, 0x6216,
+ 0x7c9f, 0x88b7, 0x5b89, 0x5eb5, 0x6309, 0x6697, 0x6848, 0x95c7,
+ 0x978d, 0x674f, 0x4ee5, 0x4f0a, 0x4f4d, 0x4f9d, 0x5049, 0x56f2,
+ 0x5937, 0x59d4, 0x5a01, 0x5c09, 0x60df, 0x610f, 0x6170, 0x6613,
+ 0x6905, 0x70ba, 0x754f, 0x7570, 0x79fb, 0x7dad, 0x7def, 0x80c3,
+ 0x840e, 0x8863, 0x8b02, 0x9055, 0x907a, 0x533b, 0x4e95, 0x4ea5,
+ 0x57df, 0x80b2, 0x90c1, 0x78ef, 0x4e00, 0x58f1, 0x6ea2, 0x9038,
+ 0x7a32, 0x8328, 0x828b, 0x9c2f, 0x5141, 0x5370, 0x54bd, 0x54e1,
+ 0x56e0, 0x59fb, 0x5f15, 0x98f2, 0x6deb, 0x80e4, 0x852d,
+ /* 0x3121 - 0x317e */
+ 0x9662, 0x9670, 0x96a0, 0x97fb, 0x540b, 0x53f3, 0x5b87,
+ 0x70cf, 0x7fbd, 0x8fc2, 0x96e8, 0x536f, 0x9d5c, 0x7aba, 0x4e11,
+ 0x7893, 0x81fc, 0x6e26, 0x5618, 0x5504, 0x6b1d, 0x851a, 0x9c3b,
+ 0x59e5, 0x53a9, 0x6d66, 0x74dc, 0x958f, 0x5642, 0x4e91, 0x904b,
+ 0x96f2, 0x834f, 0x990c, 0x53e1, 0x55b6, 0x5b30, 0x5f71, 0x6620,
+ 0x66f3, 0x6804, 0x6c38, 0x6cf3, 0x6d29, 0x745b, 0x76c8, 0x7a4e,
+ 0x9834, 0x82f1, 0x885b, 0x8a60, 0x92ed, 0x6db2, 0x75ab, 0x76ca,
+ 0x99c5, 0x60a6, 0x8b01, 0x8d8a, 0x95b2, 0x698e, 0x53ad, 0x5186,
+ 0x5712, 0x5830, 0x5944, 0x5bb4, 0x5ef6, 0x6028, 0x63a9, 0x63f4,
+ 0x6cbf, 0x6f14, 0x708e, 0x7114, 0x7159, 0x71d5, 0x733f, 0x7e01,
+ 0x8276, 0x82d1, 0x8597, 0x9060, 0x925b, 0x9d1b, 0x5869, 0x65bc,
+ 0x6c5a, 0x7525, 0x51f9, 0x592e, 0x5965, 0x5f80, 0x5fdc,
+ /* 0x3221 - 0x327e */
+ 0x62bc, 0x65fa, 0x6a2a, 0x6b27, 0x6bb4, 0x738b, 0x7fc1,
+ 0x8956, 0x9d2c, 0x9d0e, 0x9ec4, 0x5ca1, 0x6c96, 0x837b, 0x5104,
+ 0x5c4b, 0x61b6, 0x81c6, 0x6876, 0x7261, 0x4e59, 0x4ffa, 0x5378,
+ 0x6069, 0x6e29, 0x7a4f, 0x97f3, 0x4e0b, 0x5316, 0x4eee, 0x4f55,
+ 0x4f3d, 0x4fa1, 0x4f73, 0x52a0, 0x53ef, 0x5609, 0x590f, 0x5ac1,
+ 0x5bb6, 0x5be1, 0x79d1, 0x6687, 0x679c, 0x67b6, 0x6b4c, 0x6cb3,
+ 0x706b, 0x73c2, 0x798d, 0x79be, 0x7a3c, 0x7b87, 0x82b1, 0x82db,
+ 0x8304, 0x8377, 0x83ef, 0x83d3, 0x8766, 0x8ab2, 0x5629, 0x8ca8,
+ 0x8fe6, 0x904e, 0x971e, 0x868a, 0x4fc4, 0x5ce8, 0x6211, 0x7259,
+ 0x753b, 0x81e5, 0x82bd, 0x86fe, 0x8cc0, 0x96c5, 0x9913, 0x99d5,
+ 0x4ecb, 0x4f1a, 0x89e3, 0x56de, 0x584a, 0x58ca, 0x5efb, 0x5feb,
+ 0x602a, 0x6094, 0x6062, 0x61d0, 0x6212, 0x62d0, 0x6539,
+ /* 0x3321 - 0x337e */
+ 0x9b41, 0x6666, 0x68b0, 0x6d77, 0x7070, 0x754c, 0x7686,
+ 0x7d75, 0x82a5, 0x87f9, 0x958b, 0x968e, 0x8c9d, 0x51f1, 0x52be,
+ 0x5916, 0x54b3, 0x5bb3, 0x5d16, 0x6168, 0x6982, 0x6daf, 0x788d,
+ 0x84cb, 0x8857, 0x8a72, 0x93a7, 0x9ab8, 0x6d6c, 0x99a8, 0x86d9,
+ 0x57a3, 0x67ff, 0x86ce, 0x920e, 0x5283, 0x5687, 0x5404, 0x5ed3,
+ 0x62e1, 0x64b9, 0x683c, 0x6838, 0x6bbb, 0x7372, 0x78ba, 0x7a6b,
+ 0x899a, 0x89d2, 0x8d6b, 0x8f03, 0x90ed, 0x95a3, 0x9694, 0x9769,
+ 0x5b66, 0x5cb3, 0x697d, 0x984d, 0x984e, 0x639b, 0x7b20, 0x6a2b,
+ 0x6a7f, 0x68b6, 0x9c0d, 0x6f5f, 0x5272, 0x559d, 0x6070, 0x62ec,
+ 0x6d3b, 0x6e07, 0x6ed1, 0x845b, 0x8910, 0x8f44, 0x4e14, 0x9c39,
+ 0x53f6, 0x691b, 0x6a3a, 0x9784, 0x682a, 0x515c, 0x7ac3, 0x84b2,
+ 0x91dc, 0x938c, 0x565b, 0x9d28, 0x6822, 0x8305, 0x8431,
+ /* 0x3421 - 0x347e */
+ 0x7ca5, 0x5208, 0x82c5, 0x74e6, 0x4e7e, 0x4f83, 0x51a0,
+ 0x5bd2, 0x520a, 0x52d8, 0x52e7, 0x5dfb, 0x559a, 0x582a, 0x59e6,
+ 0x5b8c, 0x5b98, 0x5bdb, 0x5e72, 0x5e79, 0x60a3, 0x611f, 0x6163,
+ 0x61be, 0x63db, 0x6562, 0x67d1, 0x6853, 0x68fa, 0x6b3e, 0x6b53,
+ 0x6c57, 0x6f22, 0x6f97, 0x6f45, 0x74b0, 0x7518, 0x76e3, 0x770b,
+ 0x7aff, 0x7ba1, 0x7c21, 0x7de9, 0x7f36, 0x7ff0, 0x809d, 0x8266,
+ 0x839e, 0x89b3, 0x8acc, 0x8cab, 0x9084, 0x9451, 0x9593, 0x9591,
+ 0x95a2, 0x9665, 0x97d3, 0x9928, 0x8218, 0x4e38, 0x542b, 0x5cb8,
+ 0x5dcc, 0x73a9, 0x764c, 0x773c, 0x5ca9, 0x7feb, 0x8d0b, 0x96c1,
+ 0x9811, 0x9854, 0x9858, 0x4f01, 0x4f0e, 0x5371, 0x559c, 0x5668,
+ 0x57fa, 0x5947, 0x5b09, 0x5bc4, 0x5c90, 0x5e0c, 0x5e7e, 0x5fcc,
+ 0x63ee, 0x673a, 0x65d7, 0x65e2, 0x671f, 0x68cb, 0x68c4,
+ /* 0x3521 - 0x357e */
+ 0x6a5f, 0x5e30, 0x6bc5, 0x6c17, 0x6c7d, 0x757f, 0x7948,
+ 0x5b63, 0x7a00, 0x7d00, 0x5fbd, 0x898f, 0x8a18, 0x8cb4, 0x8d77,
+ 0x8ecc, 0x8f1d, 0x98e2, 0x9a0e, 0x9b3c, 0x4e80, 0x507d, 0x5100,
+ 0x5993, 0x5b9c, 0x622f, 0x6280, 0x64ec, 0x6b3a, 0x72a0, 0x7591,
+ 0x7947, 0x7fa9, 0x87fb, 0x8abc, 0x8b70, 0x63ac, 0x83ca, 0x97a0,
+ 0x5409, 0x5403, 0x55ab, 0x6854, 0x6a58, 0x8a70, 0x7827, 0x6775,
+ 0x9ecd, 0x5374, 0x5ba2, 0x811a, 0x8650, 0x9006, 0x4e18, 0x4e45,
+ 0x4ec7, 0x4f11, 0x53ca, 0x5438, 0x5bae, 0x5f13, 0x6025, 0x6551,
+ 0x673d, 0x6c42, 0x6c72, 0x6ce3, 0x7078, 0x7403, 0x7a76, 0x7aae,
+ 0x7b08, 0x7d1a, 0x7cfe, 0x7d66, 0x65e7, 0x725b, 0x53bb, 0x5c45,
+ 0x5de8, 0x62d2, 0x62e0, 0x6319, 0x6e20, 0x865a, 0x8a31, 0x8ddd,
+ 0x92f8, 0x6f01, 0x79a6, 0x9b5a, 0x4ea8, 0x4eab, 0x4eac,
+ /* 0x3621 - 0x367e */
+ 0x4f9b, 0x4fa0, 0x50d1, 0x5147, 0x7af6, 0x5171, 0x51f6,
+ 0x5354, 0x5321, 0x537f, 0x53eb, 0x55ac, 0x5883, 0x5ce1, 0x5f37,
+ 0x5f4a, 0x602f, 0x6050, 0x606d, 0x631f, 0x6559, 0x6a4b, 0x6cc1,
+ 0x72c2, 0x72ed, 0x77ef, 0x80f8, 0x8105, 0x8208, 0x854e, 0x90f7,
+ 0x93e1, 0x97ff, 0x9957, 0x9a5a, 0x4ef0, 0x51dd, 0x5c2d, 0x6681,
+ 0x696d, 0x5c40, 0x66f2, 0x6975, 0x7389, 0x6850, 0x7c81, 0x50c5,
+ 0x52e4, 0x5747, 0x5dfe, 0x9326, 0x65a4, 0x6b23, 0x6b3d, 0x7434,
+ 0x7981, 0x79bd, 0x7b4b, 0x7dca, 0x82b9, 0x83cc, 0x887f, 0x895f,
+ 0x8b39, 0x8fd1, 0x91d1, 0x541f, 0x9280, 0x4e5d, 0x5036, 0x53e5,
+ 0x533a, 0x72d7, 0x7396, 0x77e9, 0x82e6, 0x8eaf, 0x99c6, 0x99c8,
+ 0x99d2, 0x5177, 0x611a, 0x865e, 0x55b0, 0x7a7a, 0x5076, 0x5bd3,
+ 0x9047, 0x9685, 0x4e32, 0x6adb, 0x91e7, 0x5c51, 0x5c48,
+ /* 0x3721 - 0x377e */
+ 0x6398, 0x7a9f, 0x6c93, 0x9774, 0x8f61, 0x7aaa, 0x718a,
+ 0x9688, 0x7c82, 0x6817, 0x7e70, 0x6851, 0x936c, 0x52f2, 0x541b,
+ 0x85ab, 0x8a13, 0x7fa4, 0x8ecd, 0x90e1, 0x5366, 0x8888, 0x7941,
+ 0x4fc2, 0x50be, 0x5211, 0x5144, 0x5553, 0x572d, 0x73ea, 0x578b,
+ 0x5951, 0x5f62, 0x5f84, 0x6075, 0x6176, 0x6167, 0x61a9, 0x63b2,
+ 0x643a, 0x656c, 0x666f, 0x6842, 0x6e13, 0x7566, 0x7a3d, 0x7cfb,
+ 0x7d4c, 0x7d99, 0x7e4b, 0x7f6b, 0x830e, 0x834a, 0x86cd, 0x8a08,
+ 0x8a63, 0x8b66, 0x8efd, 0x981a, 0x9d8f, 0x82b8, 0x8fce, 0x9be8,
+ 0x5287, 0x621f, 0x6483, 0x6fc0, 0x9699, 0x6841, 0x5091, 0x6b20,
+ 0x6c7a, 0x6f54, 0x7a74, 0x7d50, 0x8840, 0x8a23, 0x6708, 0x4ef6,
+ 0x5039, 0x5026, 0x5065, 0x517c, 0x5238, 0x5263, 0x55a7, 0x570f,
+ 0x5805, 0x5acc, 0x5efa, 0x61b2, 0x61f8, 0x62f3, 0x6372,
+ /* 0x3821 - 0x387e */
+ 0x691c, 0x6a29, 0x727d, 0x72ac, 0x732e, 0x7814, 0x786f,
+ 0x7d79, 0x770c, 0x80a9, 0x898b, 0x8b19, 0x8ce2, 0x8ed2, 0x9063,
+ 0x9375, 0x967a, 0x9855, 0x9a13, 0x9e78, 0x5143, 0x539f, 0x53b3,
+ 0x5e7b, 0x5f26, 0x6e1b, 0x6e90, 0x7384, 0x73fe, 0x7d43, 0x8237,
+ 0x8a00, 0x8afa, 0x9650, 0x4e4e, 0x500b, 0x53e4, 0x547c, 0x56fa,
+ 0x59d1, 0x5b64, 0x5df1, 0x5eab, 0x5f27, 0x6238, 0x6545, 0x67af,
+ 0x6e56, 0x72d0, 0x7cca, 0x88b4, 0x80a1, 0x80e1, 0x83f0, 0x864e,
+ 0x8a87, 0x8de8, 0x9237, 0x96c7, 0x9867, 0x9f13, 0x4e94, 0x4e92,
+ 0x4f0d, 0x5348, 0x5449, 0x543e, 0x5a2f, 0x5f8c, 0x5fa1, 0x609f,
+ 0x68a7, 0x6a8e, 0x745a, 0x7881, 0x8a9e, 0x8aa4, 0x8b77, 0x9190,
+ 0x4e5e, 0x9bc9, 0x4ea4, 0x4f7c, 0x4faf, 0x5019, 0x5016, 0x5149,
+ 0x516c, 0x529f, 0x52b9, 0x52fe, 0x539a, 0x53e3, 0x5411,
+ /* 0x3921 - 0x397e */
+ 0x540e, 0x5589, 0x5751, 0x57a2, 0x597d, 0x5b54, 0x5b5d,
+ 0x5b8f, 0x5de5, 0x5de7, 0x5df7, 0x5e78, 0x5e83, 0x5e9a, 0x5eb7,
+ 0x5f18, 0x6052, 0x614c, 0x6297, 0x62d8, 0x63a7, 0x653b, 0x6602,
+ 0x6643, 0x66f4, 0x676d, 0x6821, 0x6897, 0x69cb, 0x6c5f, 0x6d2a,
+ 0x6d69, 0x6e2f, 0x6e9d, 0x7532, 0x7687, 0x786c, 0x7a3f, 0x7ce0,
+ 0x7d05, 0x7d18, 0x7d5e, 0x7db1, 0x8015, 0x8003, 0x80af, 0x80b1,
+ 0x8154, 0x818f, 0x822a, 0x8352, 0x884c, 0x8861, 0x8b1b, 0x8ca2,
+ 0x8cfc, 0x90ca, 0x9175, 0x9271, 0x783f, 0x92fc, 0x95a4, 0x964d,
+ 0x9805, 0x9999, 0x9ad8, 0x9d3b, 0x525b, 0x52ab, 0x53f7, 0x5408,
+ 0x58d5, 0x62f7, 0x6fe0, 0x8c6a, 0x8f5f, 0x9eb9, 0x514b, 0x523b,
+ 0x544a, 0x56fd, 0x7a40, 0x9177, 0x9d60, 0x9ed2, 0x7344, 0x6f09,
+ 0x8170, 0x7511, 0x5ffd, 0x60da, 0x9aa8, 0x72db, 0x8fbc,
+ /* 0x3a21 - 0x3a7e */
+ 0x6b64, 0x9803, 0x4eca, 0x56f0, 0x5764, 0x58be, 0x5a5a,
+ 0x6068, 0x61c7, 0x660f, 0x6606, 0x6839, 0x68b1, 0x6df7, 0x75d5,
+ 0x7d3a, 0x826e, 0x9b42, 0x4e9b, 0x4f50, 0x53c9, 0x5506, 0x5d6f,
+ 0x5de6, 0x5dee, 0x67fb, 0x6c99, 0x7473, 0x7802, 0x8a50, 0x9396,
+ 0x88df, 0x5750, 0x5ea7, 0x632b, 0x50b5, 0x50ac, 0x518d, 0x6700,
+ 0x54c9, 0x585e, 0x59bb, 0x5bb0, 0x5f69, 0x624d, 0x63a1, 0x683d,
+ 0x6b73, 0x6e08, 0x707d, 0x91c7, 0x7280, 0x7815, 0x7826, 0x796d,
+ 0x658e, 0x7d30, 0x83dc, 0x88c1, 0x8f09, 0x969b, 0x5264, 0x5728,
+ 0x6750, 0x7f6a, 0x8ca1, 0x51b4, 0x5742, 0x962a, 0x583a, 0x698a,
+ 0x80b4, 0x54b2, 0x5d0e, 0x57fc, 0x7895, 0x9dfa, 0x4f5c, 0x524a,
+ 0x548b, 0x643e, 0x6628, 0x6714, 0x67f5, 0x7a84, 0x7b56, 0x7d22,
+ 0x932f, 0x685c, 0x9bad, 0x7b39, 0x5319, 0x518a, 0x5237,
+ /* 0x3b21 - 0x3b7e */
+ 0x5bdf, 0x62f6, 0x64ae, 0x64e6, 0x672d, 0x6bba, 0x85a9,
+ 0x96d1, 0x7690, 0x9bd6, 0x634c, 0x9306, 0x9bab, 0x76bf, 0x6652,
+ 0x4e09, 0x5098, 0x53c2, 0x5c71, 0x60e8, 0x6492, 0x6563, 0x685f,
+ 0x71e6, 0x73ca, 0x7523, 0x7b97, 0x7e82, 0x8695, 0x8b83, 0x8cdb,
+ 0x9178, 0x9910, 0x65ac, 0x66ab, 0x6b8b, 0x4ed5, 0x4ed4, 0x4f3a,
+ 0x4f7f, 0x523a, 0x53f8, 0x53f2, 0x55e3, 0x56db, 0x58eb, 0x59cb,
+ 0x59c9, 0x59ff, 0x5b50, 0x5c4d, 0x5e02, 0x5e2b, 0x5fd7, 0x601d,
+ 0x6307, 0x652f, 0x5b5c, 0x65af, 0x65bd, 0x65e8, 0x679d, 0x6b62,
+ 0x6b7b, 0x6c0f, 0x7345, 0x7949, 0x79c1, 0x7cf8, 0x7d19, 0x7d2b,
+ 0x80a2, 0x8102, 0x81f3, 0x8996, 0x8a5e, 0x8a69, 0x8a66, 0x8a8c,
+ 0x8aee, 0x8cc7, 0x8cdc, 0x96cc, 0x98fc, 0x6b6f, 0x4e8b, 0x4f3c,
+ 0x4f8d, 0x5150, 0x5b57, 0x5bfa, 0x6148, 0x6301, 0x6642,
+ /* 0x3c21 - 0x3c7e */
+ 0x6b21, 0x6ecb, 0x6cbb, 0x723e, 0x74bd, 0x75d4, 0x78c1,
+ 0x793a, 0x800c, 0x8033, 0x81ea, 0x8494, 0x8f9e, 0x6c50, 0x9e7f,
+ 0x5f0f, 0x8b58, 0x9d2b, 0x7afa, 0x8ef8, 0x5b8d, 0x96eb, 0x4e03,
+ 0x53f1, 0x57f7, 0x5931, 0x5ac9, 0x5ba4, 0x6089, 0x6e7f, 0x6f06,
+ 0x75be, 0x8cea, 0x5b9f, 0x8500, 0x7be0, 0x5072, 0x67f4, 0x829d,
+ 0x5c61, 0x854a, 0x7e1e, 0x820e, 0x5199, 0x5c04, 0x6368, 0x8d66,
+ 0x659c, 0x716e, 0x793e, 0x7d17, 0x8005, 0x8b1d, 0x8eca, 0x906e,
+ 0x86c7, 0x90aa, 0x501f, 0x52fa, 0x5c3a, 0x6753, 0x707c, 0x7235,
+ 0x914c, 0x91c8, 0x932b, 0x82e5, 0x5bc2, 0x5f31, 0x60f9, 0x4e3b,
+ 0x53d6, 0x5b88, 0x624b, 0x6731, 0x6b8a, 0x72e9, 0x73e0, 0x7a2e,
+ 0x816b, 0x8da3, 0x9152, 0x9996, 0x5112, 0x53d7, 0x546a, 0x5bff,
+ 0x6388, 0x6a39, 0x7dac, 0x9700, 0x56da, 0x53ce, 0x5468,
+ /* 0x3d21 - 0x3d7e */
+ 0x5b97, 0x5c31, 0x5dde, 0x4fee, 0x6101, 0x62fe, 0x6d32,
+ 0x79c0, 0x79cb, 0x7d42, 0x7e4d, 0x7fd2, 0x81ed, 0x821f, 0x8490,
+ 0x8846, 0x8972, 0x8b90, 0x8e74, 0x8f2f, 0x9031, 0x914b, 0x916c,
+ 0x96c6, 0x919c, 0x4ec0, 0x4f4f, 0x5145, 0x5341, 0x5f93, 0x620e,
+ 0x67d4, 0x6c41, 0x6e0b, 0x7363, 0x7e26, 0x91cd, 0x9283, 0x53d4,
+ 0x5919, 0x5bbf, 0x6dd1, 0x795d, 0x7e2e, 0x7c9b, 0x587e, 0x719f,
+ 0x51fa, 0x8853, 0x8ff0, 0x4fca, 0x5cfb, 0x6625, 0x77ac, 0x7ae3,
+ 0x821c, 0x99ff, 0x51c6, 0x5faa, 0x65ec, 0x696f, 0x6b89, 0x6df3,
+ 0x6e96, 0x6f64, 0x76fe, 0x7d14, 0x5de1, 0x9075, 0x9187, 0x9806,
+ 0x51e6, 0x521d, 0x6240, 0x6691, 0x66d9, 0x6e1a, 0x5eb6, 0x7dd2,
+ 0x7f72, 0x66f8, 0x85af, 0x85f7, 0x8af8, 0x52a9, 0x53d9, 0x5973,
+ 0x5e8f, 0x5f90, 0x6055, 0x92e4, 0x9664, 0x50b7, 0x511f,
+ /* 0x3e21 - 0x3e7e */
+ 0x52dd, 0x5320, 0x5347, 0x53ec, 0x54e8, 0x5546, 0x5531,
+ 0x5617, 0x5968, 0x59be, 0x5a3c, 0x5bb5, 0x5c06, 0x5c0f, 0x5c11,
+ 0x5c1a, 0x5e84, 0x5e8a, 0x5ee0, 0x5f70, 0x627f, 0x6284, 0x62db,
+ 0x638c, 0x6377, 0x6607, 0x660c, 0x662d, 0x6676, 0x677e, 0x68a2,
+ 0x6a1f, 0x6a35, 0x6cbc, 0x6d88, 0x6e09, 0x6e58, 0x713c, 0x7126,
+ 0x7167, 0x75c7, 0x7701, 0x785d, 0x7901, 0x7965, 0x79f0, 0x7ae0,
+ 0x7b11, 0x7ca7, 0x7d39, 0x8096, 0x83d6, 0x848b, 0x8549, 0x885d,
+ 0x88f3, 0x8a1f, 0x8a3c, 0x8a54, 0x8a73, 0x8c61, 0x8cde, 0x91a4,
+ 0x9266, 0x937e, 0x9418, 0x969c, 0x9798, 0x4e0a, 0x4e08, 0x4e1e,
+ 0x4e57, 0x5197, 0x5270, 0x57ce, 0x5834, 0x58cc, 0x5b22, 0x5e38,
+ 0x60c5, 0x64fe, 0x6761, 0x6756, 0x6d44, 0x72b6, 0x7573, 0x7a63,
+ 0x84b8, 0x8b72, 0x91b8, 0x9320, 0x5631, 0x57f4, 0x98fe,
+ /* 0x3f21 - 0x3f7e */
+ 0x62ed, 0x690d, 0x6b96, 0x71ed, 0x7e54, 0x8077, 0x8272,
+ 0x89e6, 0x98df, 0x8755, 0x8fb1, 0x5c3b, 0x4f38, 0x4fe1, 0x4fb5,
+ 0x5507, 0x5a20, 0x5bdd, 0x5be9, 0x5fc3, 0x614e, 0x632f, 0x65b0,
+ 0x664b, 0x68ee, 0x699b, 0x6d78, 0x6df1, 0x7533, 0x75b9, 0x771f,
+ 0x795e, 0x79e6, 0x7d33, 0x81e3, 0x82af, 0x85aa, 0x89aa, 0x8a3a,
+ 0x8eab, 0x8f9b, 0x9032, 0x91dd, 0x9707, 0x4eba, 0x4ec1, 0x5203,
+ 0x5875, 0x58ec, 0x5c0b, 0x751a, 0x5c3d, 0x814e, 0x8a0a, 0x8fc5,
+ 0x9663, 0x976d, 0x7b25, 0x8acf, 0x9808, 0x9162, 0x56f3, 0x53a8,
+ 0x9017, 0x5439, 0x5782, 0x5e25, 0x63a8, 0x6c34, 0x708a, 0x7761,
+ 0x7c8b, 0x7fe0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968f,
+ 0x745e, 0x9ac4, 0x5d07, 0x5d69, 0x6570, 0x67a2, 0x8da8, 0x96db,
+ 0x636e, 0x6749, 0x6919, 0x83c5, 0x9817, 0x96c0, 0x88fe,
+ /* 0x4021 - 0x407e */
+ 0x6f84, 0x647a, 0x5bf8, 0x4e16, 0x702c, 0x755d, 0x662f,
+ 0x51c4, 0x5236, 0x52e2, 0x59d3, 0x5f81, 0x6027, 0x6210, 0x653f,
+ 0x6574, 0x661f, 0x6674, 0x68f2, 0x6816, 0x6b63, 0x6e05, 0x7272,
+ 0x751f, 0x76db, 0x7cbe, 0x8056, 0x58f0, 0x88fd, 0x897f, 0x8aa0,
+ 0x8a93, 0x8acb, 0x901d, 0x9192, 0x9752, 0x9759, 0x6589, 0x7a0e,
+ 0x8106, 0x96bb, 0x5e2d, 0x60dc, 0x621a, 0x65a5, 0x6614, 0x6790,
+ 0x77f3, 0x7a4d, 0x7c4d, 0x7e3e, 0x810a, 0x8cac, 0x8d64, 0x8de1,
+ 0x8e5f, 0x78a9, 0x5207, 0x62d9, 0x63a5, 0x6442, 0x6298, 0x8a2d,
+ 0x7a83, 0x7bc0, 0x8aac, 0x96ea, 0x7d76, 0x820c, 0x8749, 0x4ed9,
+ 0x5148, 0x5343, 0x5360, 0x5ba3, 0x5c02, 0x5c16, 0x5ddd, 0x6226,
+ 0x6247, 0x64b0, 0x6813, 0x6834, 0x6cc9, 0x6d45, 0x6d17, 0x67d3,
+ 0x6f5c, 0x714e, 0x717d, 0x65cb, 0x7a7f, 0x7bad, 0x7dda,
+ /* 0x4121 - 0x417e */
+ 0x7e4a, 0x7fa8, 0x817a, 0x821b, 0x8239, 0x85a6, 0x8a6e,
+ 0x8cce, 0x8df5, 0x9078, 0x9077, 0x92ad, 0x9291, 0x9583, 0x9bae,
+ 0x524d, 0x5584, 0x6f38, 0x7136, 0x5168, 0x7985, 0x7e55, 0x81b3,
+ 0x7cce, 0x564c, 0x5851, 0x5ca8, 0x63aa, 0x66fe, 0x66fd, 0x695a,
+ 0x72d9, 0x758f, 0x758e, 0x790e, 0x7956, 0x79df, 0x7c97, 0x7d20,
+ 0x7d44, 0x8607, 0x8a34, 0x963b, 0x9061, 0x9f20, 0x50e7, 0x5275,
+ 0x53cc, 0x53e2, 0x5009, 0x55aa, 0x58ee, 0x594f, 0x723d, 0x5b8b,
+ 0x5c64, 0x531d, 0x60e3, 0x60f3, 0x635c, 0x6383, 0x633f, 0x63bb,
+ 0x64cd, 0x65e9, 0x66f9, 0x5de3, 0x69cd, 0x69fd, 0x6f15, 0x71e5,
+ 0x4e89, 0x75e9, 0x76f8, 0x7a93, 0x7cdf, 0x7dcf, 0x7d9c, 0x8061,
+ 0x8349, 0x8358, 0x846c, 0x84bc, 0x85fb, 0x88c5, 0x8d70, 0x9001,
+ 0x906d, 0x9397, 0x971c, 0x9a12, 0x50cf, 0x5897, 0x618e,
+ /* 0x4221 - 0x427e */
+ 0x81d3, 0x8535, 0x8d08, 0x9020, 0x4fc3, 0x5074, 0x5247,
+ 0x5373, 0x606f, 0x6349, 0x675f, 0x6e2c, 0x8db3, 0x901f, 0x4fd7,
+ 0x5c5e, 0x8cca, 0x65cf, 0x7d9a, 0x5352, 0x8896, 0x5176, 0x63c3,
+ 0x5b58, 0x5b6b, 0x5c0a, 0x640d, 0x6751, 0x905c, 0x4ed6, 0x591a,
+ 0x592a, 0x6c70, 0x8a51, 0x553e, 0x5815, 0x59a5, 0x60f0, 0x6253,
+ 0x67c1, 0x8235, 0x6955, 0x9640, 0x99c4, 0x9a28, 0x4f53, 0x5806,
+ 0x5bfe, 0x8010, 0x5cb1, 0x5e2f, 0x5f85, 0x6020, 0x614b, 0x6234,
+ 0x66ff, 0x6cf0, 0x6ede, 0x80ce, 0x817f, 0x82d4, 0x888b, 0x8cb8,
+ 0x9000, 0x902e, 0x968a, 0x9edb, 0x9bdb, 0x4ee3, 0x53f0, 0x5927,
+ 0x7b2c, 0x918d, 0x984c, 0x9df9, 0x6edd, 0x7027, 0x5353, 0x5544,
+ 0x5b85, 0x6258, 0x629e, 0x62d3, 0x6ca2, 0x6fef, 0x7422, 0x8a17,
+ 0x9438, 0x6fc1, 0x8afe, 0x8338, 0x51e7, 0x86f8, 0x53ea,
+ /* 0x4321 - 0x437e */
+ 0x53e9, 0x4f46, 0x9054, 0x8fb0, 0x596a, 0x8131, 0x5dfd,
+ 0x7aea, 0x8fbf, 0x68da, 0x8c37, 0x72f8, 0x9c48, 0x6a3d, 0x8ab0,
+ 0x4e39, 0x5358, 0x5606, 0x5766, 0x62c5, 0x63a2, 0x65e6, 0x6b4e,
+ 0x6de1, 0x6e5b, 0x70ad, 0x77ed, 0x7aef, 0x7baa, 0x7dbb, 0x803d,
+ 0x80c6, 0x86cb, 0x8a95, 0x935b, 0x56e3, 0x58c7, 0x5f3e, 0x65ad,
+ 0x6696, 0x6a80, 0x6bb5, 0x7537, 0x8ac7, 0x5024, 0x77e5, 0x5730,
+ 0x5f1b, 0x6065, 0x667a, 0x6c60, 0x75f4, 0x7a1a, 0x7f6e, 0x81f4,
+ 0x8718, 0x9045, 0x99b3, 0x7bc9, 0x755c, 0x7af9, 0x7b51, 0x84c4,
+ 0x9010, 0x79e9, 0x7a92, 0x8336, 0x5ae1, 0x7740, 0x4e2d, 0x4ef2,
+ 0x5b99, 0x5fe0, 0x62bd, 0x663c, 0x67f1, 0x6ce8, 0x866b, 0x8877,
+ 0x8a3b, 0x914e, 0x92f3, 0x99d0, 0x6a17, 0x7026, 0x732a, 0x82e7,
+ 0x8457, 0x8caf, 0x4e01, 0x5146, 0x51cb, 0x558b, 0x5bf5,
+ /* 0x4421 - 0x447e */
+ 0x5e16, 0x5e33, 0x5e81, 0x5f14, 0x5f35, 0x5f6b, 0x5fb4,
+ 0x61f2, 0x6311, 0x66a2, 0x671d, 0x6f6e, 0x7252, 0x753a, 0x773a,
+ 0x8074, 0x8139, 0x8178, 0x8776, 0x8abf, 0x8adc, 0x8d85, 0x8df3,
+ 0x929a, 0x9577, 0x9802, 0x9ce5, 0x52c5, 0x6357, 0x76f4, 0x6715,
+ 0x6c88, 0x73cd, 0x8cc3, 0x93ae, 0x9673, 0x6d25, 0x589c, 0x690e,
+ 0x69cc, 0x8ffd, 0x939a, 0x75db, 0x901a, 0x585a, 0x6802, 0x63b4,
+ 0x69fb, 0x4f43, 0x6f2c, 0x67d8, 0x8fbb, 0x8526, 0x7db4, 0x9354,
+ 0x693f, 0x6f70, 0x576a, 0x58f7, 0x5b2c, 0x7d2c, 0x722a, 0x540a,
+ 0x91e3, 0x9db4, 0x4ead, 0x4f4e, 0x505c, 0x5075, 0x5243, 0x8c9e,
+ 0x5448, 0x5824, 0x5b9a, 0x5e1d, 0x5e95, 0x5ead, 0x5ef7, 0x5f1f,
+ 0x608c, 0x62b5, 0x633a, 0x63d0, 0x68af, 0x6c40, 0x7887, 0x798e,
+ 0x7a0b, 0x7de0, 0x8247, 0x8a02, 0x8ae6, 0x8e44, 0x9013,
+ /* 0x4521 - 0x457e */
+ 0x90b8, 0x912d, 0x91d8, 0x9f0e, 0x6ce5, 0x6458, 0x64e2,
+ 0x6575, 0x6ef4, 0x7684, 0x7b1b, 0x9069, 0x93d1, 0x6eba, 0x54f2,
+ 0x5fb9, 0x64a4, 0x8f4d, 0x8fed, 0x9244, 0x5178, 0x586b, 0x5929,
+ 0x5c55, 0x5e97, 0x6dfb, 0x7e8f, 0x751c, 0x8cbc, 0x8ee2, 0x985b,
+ 0x70b9, 0x4f1d, 0x6bbf, 0x6fb1, 0x7530, 0x96fb, 0x514e, 0x5410,
+ 0x5835, 0x5857, 0x59ac, 0x5c60, 0x5f92, 0x6597, 0x675c, 0x6e21,
+ 0x767b, 0x83df, 0x8ced, 0x9014, 0x90fd, 0x934d, 0x7825, 0x783a,
+ 0x52aa, 0x5ea6, 0x571f, 0x5974, 0x6012, 0x5012, 0x515a, 0x51ac,
+ 0x51cd, 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5b95, 0x5cf6,
+ 0x5d8b, 0x60bc, 0x6295, 0x642d, 0x6771, 0x6843, 0x68bc, 0x68df,
+ 0x76d7, 0x6dd8, 0x6e6f, 0x6d9b, 0x706f, 0x71c8, 0x5f53, 0x75d8,
+ 0x7977, 0x7b49, 0x7b54, 0x7b52, 0x7cd6, 0x7d71, 0x5230,
+ /* 0x4621 - 0x467e */
+ 0x8463, 0x8569, 0x85e4, 0x8a0e, 0x8b04, 0x8c46, 0x8e0f,
+ 0x9003, 0x900f, 0x9419, 0x9676, 0x982d, 0x9a30, 0x95d8, 0x50cd,
+ 0x52d5, 0x540c, 0x5802, 0x5c0e, 0x61a7, 0x649e, 0x6d1e, 0x77b3,
+ 0x7ae5, 0x80f4, 0x8404, 0x9053, 0x9285, 0x5ce0, 0x9d07, 0x533f,
+ 0x5f97, 0x5fb3, 0x6d9c, 0x7279, 0x7763, 0x79bf, 0x7be4, 0x6bd2,
+ 0x72ec, 0x8aad, 0x6803, 0x6a61, 0x51f8, 0x7a81, 0x6934, 0x5c4a,
+ 0x9cf6, 0x82eb, 0x5bc5, 0x9149, 0x701e, 0x5678, 0x5c6f, 0x60c7,
+ 0x6566, 0x6c8c, 0x8c5a, 0x9041, 0x9813, 0x5451, 0x66c7, 0x920d,
+ 0x5948, 0x90a3, 0x5185, 0x4e4d, 0x51ea, 0x8599, 0x8b0e, 0x7058,
+ 0x637a, 0x934b, 0x6962, 0x99b4, 0x7e04, 0x7577, 0x5357, 0x6960,
+ 0x8edf, 0x96e3, 0x6c5d, 0x4e8c, 0x5c3c, 0x5f10, 0x8fe9, 0x5302,
+ 0x8cd1, 0x8089, 0x8679, 0x5eff, 0x65e5, 0x4e73, 0x5165,
+ /* 0x4721 - 0x477e */
+ 0x5982, 0x5c3f, 0x97ee, 0x4efb, 0x598a, 0x5fcd, 0x8a8d,
+ 0x6fe1, 0x79b0, 0x7962, 0x5be7, 0x8471, 0x732b, 0x71b1, 0x5e74,
+ 0x5ff5, 0x637b, 0x649a, 0x71c3, 0x7c98, 0x4e43, 0x5efc, 0x4e4b,
+ 0x57dc, 0x56a2, 0x60a9, 0x6fc3, 0x7d0d, 0x80fd, 0x8133, 0x81bf,
+ 0x8fb2, 0x8997, 0x86a4, 0x5df4, 0x628a, 0x64ad, 0x8987, 0x6777,
+ 0x6ce2, 0x6d3e, 0x7436, 0x7834, 0x5a46, 0x7f75, 0x82ad, 0x99ac,
+ 0x4ff3, 0x5ec3, 0x62dd, 0x6392, 0x6557, 0x676f, 0x76c3, 0x724c,
+ 0x80cc, 0x80ba, 0x8f29, 0x914d, 0x500d, 0x57f9, 0x5a92, 0x6885,
+ 0x6973, 0x7164, 0x72fd, 0x8cb7, 0x58f2, 0x8ce0, 0x966a, 0x9019,
+ 0x877f, 0x79e4, 0x77e7, 0x8429, 0x4f2f, 0x5265, 0x535a, 0x62cd,
+ 0x67cf, 0x6cca, 0x767d, 0x7b94, 0x7c95, 0x8236, 0x8584, 0x8feb,
+ 0x66dd, 0x6f20, 0x7206, 0x7e1b, 0x83ab, 0x99c1, 0x9ea6,
+ /* 0x4821 - 0x487e */
+ 0x51fd, 0x7bb1, 0x7872, 0x7bb8, 0x8087, 0x7b48, 0x6ae8,
+ 0x5e61, 0x808c, 0x7551, 0x7560, 0x516b, 0x9262, 0x6e8c, 0x767a,
+ 0x9197, 0x9aea, 0x4f10, 0x7f70, 0x629c, 0x7b4f, 0x95a5, 0x9ce9,
+ 0x567a, 0x5859, 0x86e4, 0x96bc, 0x4f34, 0x5224, 0x534a, 0x53cd,
+ 0x53db, 0x5e06, 0x642c, 0x6591, 0x677f, 0x6c3e, 0x6c4e, 0x7248,
+ 0x72af, 0x73ed, 0x7554, 0x7e41, 0x822c, 0x85e9, 0x8ca9, 0x7bc4,
+ 0x91c6, 0x7169, 0x9812, 0x98ef, 0x633d, 0x6669, 0x756a, 0x76e4,
+ 0x78d0, 0x8543, 0x86ee, 0x532a, 0x5351, 0x5426, 0x5983, 0x5e87,
+ 0x5f7c, 0x60b2, 0x6249, 0x6279, 0x62ab, 0x6590, 0x6bd4, 0x6ccc,
+ 0x75b2, 0x76ae, 0x7891, 0x79d8, 0x7dcb, 0x7f77, 0x80a5, 0x88ab,
+ 0x8ab9, 0x8cbb, 0x907f, 0x975e, 0x98db, 0x6a0b, 0x7c38, 0x5099,
+ 0x5c3e, 0x5fae, 0x6787, 0x6bd8, 0x7435, 0x7709, 0x7f8e,
+ /* 0x4921 - 0x497e */
+ 0x9f3b, 0x67ca, 0x7a17, 0x5339, 0x758b, 0x9aed, 0x5f66,
+ 0x819d, 0x83f1, 0x8098, 0x5f3c, 0x5fc5, 0x7562, 0x7b46, 0x903c,
+ 0x6867, 0x59eb, 0x5a9b, 0x7d10, 0x767e, 0x8b2c, 0x4ff5, 0x5f6a,
+ 0x6a19, 0x6c37, 0x6f02, 0x74e2, 0x7968, 0x8868, 0x8a55, 0x8c79,
+ 0x5edf, 0x63cf, 0x75c5, 0x79d2, 0x82d7, 0x9328, 0x92f2, 0x849c,
+ 0x86ed, 0x9c2d, 0x54c1, 0x5f6c, 0x658c, 0x6d5c, 0x7015, 0x8ca7,
+ 0x8cd3, 0x983b, 0x654f, 0x74f6, 0x4e0d, 0x4ed8, 0x57e0, 0x592b,
+ 0x5a66, 0x5bcc, 0x51a8, 0x5e03, 0x5e9c, 0x6016, 0x6276, 0x6577,
+ 0x65a7, 0x666e, 0x6d6e, 0x7236, 0x7b26, 0x8150, 0x819a, 0x8299,
+ 0x8b5c, 0x8ca0, 0x8ce6, 0x8d74, 0x961c, 0x9644, 0x4fae, 0x64ab,
+ 0x6b66, 0x821e, 0x8461, 0x856a, 0x90e8, 0x5c01, 0x6953, 0x98a8,
+ 0x847a, 0x8557, 0x4f0f, 0x526f, 0x5fa9, 0x5e45, 0x670d,
+ /* 0x4a21 - 0x4a7e */
+ 0x798f, 0x8179, 0x8907, 0x8986, 0x6df5, 0x5f17, 0x6255,
+ 0x6cb8, 0x4ecf, 0x7269, 0x9b92, 0x5206, 0x543b, 0x5674, 0x58b3,
+ 0x61a4, 0x626e, 0x711a, 0x596e, 0x7c89, 0x7cde, 0x7d1b, 0x96f0,
+ 0x6587, 0x805e, 0x4e19, 0x4f75, 0x5175, 0x5840, 0x5e63, 0x5e73,
+ 0x5f0a, 0x67c4, 0x4e26, 0x853d, 0x9589, 0x965b, 0x7c73, 0x9801,
+ 0x50fb, 0x58c1, 0x7656, 0x78a7, 0x5225, 0x77a5, 0x8511, 0x7b86,
+ 0x504f, 0x5909, 0x7247, 0x7bc7, 0x7de8, 0x8fba, 0x8fd4, 0x904d,
+ 0x4fbf, 0x52c9, 0x5a29, 0x5f01, 0x97ad, 0x4fdd, 0x8217, 0x92ea,
+ 0x5703, 0x6355, 0x6b69, 0x752b, 0x88dc, 0x8f14, 0x7a42, 0x52df,
+ 0x5893, 0x6155, 0x620a, 0x66ae, 0x6bcd, 0x7c3f, 0x83e9, 0x5023,
+ 0x4ff8, 0x5305, 0x5446, 0x5831, 0x5949, 0x5b9d, 0x5cf0, 0x5cef,
+ 0x5d29, 0x5e96, 0x62b1, 0x6367, 0x653e, 0x65b9, 0x670b,
+ /* 0x4b21 - 0x4b7e */
+ 0x6cd5, 0x6ce1, 0x70f9, 0x7832, 0x7e2b, 0x80de, 0x82b3,
+ 0x840c, 0x84ec, 0x8702, 0x8912, 0x8a2a, 0x8c4a, 0x90a6, 0x92d2,
+ 0x98fd, 0x9cf3, 0x9d6c, 0x4e4f, 0x4ea1, 0x508d, 0x5256, 0x574a,
+ 0x59a8, 0x5e3d, 0x5fd8, 0x5fd9, 0x623f, 0x66b4, 0x671b, 0x67d0,
+ 0x68d2, 0x5192, 0x7d21, 0x80aa, 0x81a8, 0x8b00, 0x8c8c, 0x8cbf,
+ 0x927e, 0x9632, 0x5420, 0x982c, 0x5317, 0x50d5, 0x535c, 0x58a8,
+ 0x64b2, 0x6734, 0x7267, 0x7766, 0x7a46, 0x91e6, 0x52c3, 0x6ca1,
+ 0x6b86, 0x5800, 0x5e4c, 0x5954, 0x672c, 0x7ffb, 0x51e1, 0x76c6,
+ 0x6469, 0x78e8, 0x9b54, 0x9ebb, 0x57cb, 0x59b9, 0x6627, 0x679a,
+ 0x6bce, 0x54e9, 0x69d9, 0x5e55, 0x819c, 0x6795, 0x9baa, 0x67fe,
+ 0x9c52, 0x685d, 0x4ea6, 0x4fe3, 0x53c8, 0x62b9, 0x672b, 0x6cab,
+ 0x8fc4, 0x4fad, 0x7e6d, 0x9ebf, 0x4e07, 0x6162, 0x6e80,
+ /* 0x4c21 - 0x4c7e */
+ 0x6f2b, 0x8513, 0x5473, 0x672a, 0x9b45, 0x5df3, 0x7b95,
+ 0x5cac, 0x5bc6, 0x871c, 0x6e4a, 0x84d1, 0x7a14, 0x8108, 0x5999,
+ 0x7c8d, 0x6c11, 0x7720, 0x52d9, 0x5922, 0x7121, 0x725f, 0x77db,
+ 0x9727, 0x9d61, 0x690b, 0x5a7f, 0x5a18, 0x51a5, 0x540d, 0x547d,
+ 0x660e, 0x76df, 0x8ff7, 0x9298, 0x9cf4, 0x59ea, 0x725d, 0x6ec5,
+ 0x514d, 0x68c9, 0x7dbf, 0x7dec, 0x9762, 0x9eba, 0x6478, 0x6a21,
+ 0x8302, 0x5984, 0x5b5f, 0x6bdb, 0x731b, 0x76f2, 0x7db2, 0x8017,
+ 0x8499, 0x5132, 0x6728, 0x9ed9, 0x76ee, 0x6762, 0x52ff, 0x9905,
+ 0x5c24, 0x623b, 0x7c7e, 0x8cb0, 0x554f, 0x60b6, 0x7d0b, 0x9580,
+ 0x5301, 0x4e5f, 0x51b6, 0x591c, 0x723a, 0x8036, 0x91ce, 0x5f25,
+ 0x77e2, 0x5384, 0x5f79, 0x7d04, 0x85ac, 0x8a33, 0x8e8d, 0x9756,
+ 0x67f3, 0x85ae, 0x9453, 0x6109, 0x6108, 0x6cb9, 0x7652,
+ /* 0x4d21 - 0x4d7e */
+ 0x8aed, 0x8f38, 0x552f, 0x4f51, 0x512a, 0x52c7, 0x53cb,
+ 0x5ba5, 0x5e7d, 0x60a0, 0x6182, 0x63d6, 0x6709, 0x67da, 0x6e67,
+ 0x6d8c, 0x7336, 0x7337, 0x7531, 0x7950, 0x88d5, 0x8a98, 0x904a,
+ 0x9091, 0x90f5, 0x96c4, 0x878d, 0x5915, 0x4e88, 0x4f59, 0x4e0e,
+ 0x8a89, 0x8f3f, 0x9810, 0x50ad, 0x5e7c, 0x5996, 0x5bb9, 0x5eb8,
+ 0x63da, 0x63fa, 0x64c1, 0x66dc, 0x694a, 0x69d8, 0x6d0b, 0x6eb6,
+ 0x7194, 0x7528, 0x7aaf, 0x7f8a, 0x8000, 0x8449, 0x84c9, 0x8981,
+ 0x8b21, 0x8e0a, 0x9065, 0x967d, 0x990a, 0x617e, 0x6291, 0x6b32,
+ 0x6c83, 0x6d74, 0x7fcc, 0x7ffc, 0x6dc0, 0x7f85, 0x87ba, 0x88f8,
+ 0x6765, 0x83b1, 0x983c, 0x96f7, 0x6d1b, 0x7d61, 0x843d, 0x916a,
+ 0x4e71, 0x5375, 0x5d50, 0x6b04, 0x6feb, 0x85cd, 0x862d, 0x89a7,
+ 0x5229, 0x540f, 0x5c65, 0x674e, 0x68a8, 0x7406, 0x7483,
+ /* 0x4e21 - 0x4e7e */
+ 0x75e2, 0x88cf, 0x88e1, 0x91cc, 0x96e2, 0x9678, 0x5f8b,
+ 0x7387, 0x7acb, 0x844e, 0x63a0, 0x7565, 0x5289, 0x6d41, 0x6e9c,
+ 0x7409, 0x7559, 0x786b, 0x7c92, 0x9686, 0x7adc, 0x9f8d, 0x4fb6,
+ 0x616e, 0x65c5, 0x865c, 0x4e86, 0x4eae, 0x50da, 0x4e21, 0x51cc,
+ 0x5bee, 0x6599, 0x6881, 0x6dbc, 0x731f, 0x7642, 0x77ad, 0x7a1c,
+ 0x7ce7, 0x826f, 0x8ad2, 0x907c, 0x91cf, 0x9675, 0x9818, 0x529b,
+ 0x7dd1, 0x502b, 0x5398, 0x6797, 0x6dcb, 0x71d0, 0x7433, 0x81e8,
+ 0x8f2a, 0x96a3, 0x9c57, 0x9e9f, 0x7460, 0x5841, 0x6d99, 0x7d2f,
+ 0x985e, 0x4ee4, 0x4f36, 0x4f8b, 0x51b7, 0x52b1, 0x5dba, 0x601c,
+ 0x73b2, 0x793c, 0x82d3, 0x9234, 0x96b7, 0x96f6, 0x970a, 0x9e97,
+ 0x9f62, 0x66a6, 0x6b74, 0x5217, 0x52a3, 0x70c8, 0x88c2, 0x5ec9,
+ 0x604b, 0x6190, 0x6f23, 0x7149, 0x7c3e, 0x7df4, 0x806f,
+ /* 0x4f21 - 0x4f7e */
+ 0x84ee, 0x9023, 0x932c, 0x5442, 0x9b6f, 0x6ad3, 0x7089,
+ 0x8cc2, 0x8def, 0x9732, 0x52b4, 0x5a41, 0x5eca, 0x5f04, 0x6717,
+ 0x697c, 0x6994, 0x6d6a, 0x6f0f, 0x7262, 0x72fc, 0x7bed, 0x8001,
+ 0x807e, 0x874b, 0x90ce, 0x516d, 0x9e93, 0x7984, 0x808b, 0x9332,
+ 0x8ad6, 0x502d, 0x548c, 0x8a71, 0x6b6a, 0x8cc4, 0x8107, 0x60d1,
+ 0x67a0, 0x9df2, 0x4e99, 0x4e98, 0x9c10, 0x8a6b, 0x85c1, 0x8568,
+ 0x6900, 0x6e7e, 0x7897, 0x8155, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x5021 - 0x507e */
+ 0x5f0c, 0x4e10, 0x4e15, 0x4e2a, 0x4e31, 0x4e36, 0x4e3c,
+ 0x4e3f, 0x4e42, 0x4e56, 0x4e58, 0x4e82, 0x4e85, 0x8c6b, 0x4e8a,
+ 0x8212, 0x5f0d, 0x4e8e, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea2, 0x4eb0,
+ 0x4eb3, 0x4eb6, 0x4ece, 0x4ecd, 0x4ec4, 0x4ec6, 0x4ec2, 0x4ed7,
+ 0x4ede, 0x4eed, 0x4edf, 0x4ef7, 0x4f09, 0x4f5a, 0x4f30, 0x4f5b,
+ 0x4f5d, 0x4f57, 0x4f47, 0x4f76, 0x4f88, 0x4f8f, 0x4f98, 0x4f7b,
+ 0x4f69, 0x4f70, 0x4f91, 0x4f6f, 0x4f86, 0x4f96, 0x5118, 0x4fd4,
+ 0x4fdf, 0x4fce, 0x4fd8, 0x4fdb, 0x4fd1, 0x4fda, 0x4fd0, 0x4fe4,
+ 0x4fe5, 0x501a, 0x5028, 0x5014, 0x502a, 0x5025, 0x5005, 0x4f1c,
+ 0x4ff6, 0x5021, 0x5029, 0x502c, 0x4ffe, 0x4fef, 0x5011, 0x5006,
+ 0x5043, 0x5047, 0x6703, 0x5055, 0x5050, 0x5048, 0x505a, 0x5056,
+ 0x506c, 0x5078, 0x5080, 0x509a, 0x5085, 0x50b4, 0x50b2,
+ /* 0x5121 - 0x517e */
+ 0x50c9, 0x50ca, 0x50b3, 0x50c2, 0x50d6, 0x50de, 0x50e5,
+ 0x50ed, 0x50e3, 0x50ee, 0x50f9, 0x50f5, 0x5109, 0x5101, 0x5102,
+ 0x5116, 0x5115, 0x5114, 0x511a, 0x5121, 0x513a, 0x5137, 0x513c,
+ 0x513b, 0x513f, 0x5140, 0x5152, 0x514c, 0x5154, 0x5162, 0x7af8,
+ 0x5169, 0x516a, 0x516e, 0x5180, 0x5182, 0x56d8, 0x518c, 0x5189,
+ 0x518f, 0x5191, 0x5193, 0x5195, 0x5196, 0x51a4, 0x51a6, 0x51a2,
+ 0x51a9, 0x51aa, 0x51ab, 0x51b3, 0x51b1, 0x51b2, 0x51b0, 0x51b5,
+ 0x51bd, 0x51c5, 0x51c9, 0x51db, 0x51e0, 0x8655, 0x51e9, 0x51ed,
+ 0x51f0, 0x51f5, 0x51fe, 0x5204, 0x520b, 0x5214, 0x520e, 0x5227,
+ 0x522a, 0x522e, 0x5233, 0x5239, 0x524f, 0x5244, 0x524b, 0x524c,
+ 0x525e, 0x5254, 0x526a, 0x5274, 0x5269, 0x5273, 0x527f, 0x527d,
+ 0x528d, 0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8fa8,
+ /* 0x5221 - 0x527e */
+ 0x8fa7, 0x52ac, 0x52ad, 0x52bc, 0x52b5, 0x52c1, 0x52cd,
+ 0x52d7, 0x52de, 0x52e3, 0x52e6, 0x98ed, 0x52e0, 0x52f3, 0x52f5,
+ 0x52f8, 0x52f9, 0x5306, 0x5308, 0x7538, 0x530d, 0x5310, 0x530f,
+ 0x5315, 0x531a, 0x5323, 0x532f, 0x5331, 0x5333, 0x5338, 0x5340,
+ 0x5346, 0x5345, 0x4e17, 0x5349, 0x534d, 0x51d6, 0x535e, 0x5369,
+ 0x536e, 0x5918, 0x537b, 0x5377, 0x5382, 0x5396, 0x53a0, 0x53a6,
+ 0x53a5, 0x53ae, 0x53b0, 0x53b6, 0x53c3, 0x7c12, 0x96d9, 0x53df,
+ 0x66fc, 0x71ee, 0x53ee, 0x53e8, 0x53ed, 0x53fa, 0x5401, 0x543d,
+ 0x5440, 0x542c, 0x542d, 0x543c, 0x542e, 0x5436, 0x5429, 0x541d,
+ 0x544e, 0x548f, 0x5475, 0x548e, 0x545f, 0x5471, 0x5477, 0x5470,
+ 0x5492, 0x547b, 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54c7,
+ 0x54a2, 0x54b8, 0x54a5, 0x54ac, 0x54c4, 0x54c8, 0x54a8,
+ /* 0x5321 - 0x537e */
+ 0x54ab, 0x54c2, 0x54a4, 0x54be, 0x54bc, 0x54d8, 0x54e5,
+ 0x54e6, 0x550f, 0x5514, 0x54fd, 0x54ee, 0x54ed, 0x54fa, 0x54e2,
+ 0x5539, 0x5540, 0x5563, 0x554c, 0x552e, 0x555c, 0x5545, 0x5556,
+ 0x5557, 0x5538, 0x5533, 0x555d, 0x5599, 0x5580, 0x54af, 0x558a,
+ 0x559f, 0x557b, 0x557e, 0x5598, 0x559e, 0x55ae, 0x557c, 0x5583,
+ 0x55a9, 0x5587, 0x55a8, 0x55da, 0x55c5, 0x55df, 0x55c4, 0x55dc,
+ 0x55e4, 0x55d4, 0x5614, 0x55f7, 0x5616, 0x55fe, 0x55fd, 0x561b,
+ 0x55f9, 0x564e, 0x5650, 0x71df, 0x5634, 0x5636, 0x5632, 0x5638,
+ 0x566b, 0x5664, 0x562f, 0x566c, 0x566a, 0x5686, 0x5680, 0x568a,
+ 0x56a0, 0x5694, 0x568f, 0x56a5, 0x56ae, 0x56b6, 0x56b4, 0x56c2,
+ 0x56bc, 0x56c1, 0x56c3, 0x56c0, 0x56c8, 0x56ce, 0x56d1, 0x56d3,
+ 0x56d7, 0x56ee, 0x56f9, 0x5700, 0x56ff, 0x5704, 0x5709,
+ /* 0x5421 - 0x547e */
+ 0x5708, 0x570b, 0x570d, 0x5713, 0x5718, 0x5716, 0x55c7,
+ 0x571c, 0x5726, 0x5737, 0x5738, 0x574e, 0x573b, 0x5740, 0x574f,
+ 0x5769, 0x57c0, 0x5788, 0x5761, 0x577f, 0x5789, 0x5793, 0x57a0,
+ 0x57b3, 0x57a4, 0x57aa, 0x57b0, 0x57c3, 0x57c6, 0x57d4, 0x57d2,
+ 0x57d3, 0x580a, 0x57d6, 0x57e3, 0x580b, 0x5819, 0x581d, 0x5872,
+ 0x5821, 0x5862, 0x584b, 0x5870, 0x6bc0, 0x5852, 0x583d, 0x5879,
+ 0x5885, 0x58b9, 0x589f, 0x58ab, 0x58ba, 0x58de, 0x58bb, 0x58b8,
+ 0x58ae, 0x58c5, 0x58d3, 0x58d1, 0x58d7, 0x58d9, 0x58d8, 0x58e5,
+ 0x58dc, 0x58e4, 0x58df, 0x58ef, 0x58fa, 0x58f9, 0x58fb, 0x58fc,
+ 0x58fd, 0x5902, 0x590a, 0x5910, 0x591b, 0x68a6, 0x5925, 0x592c,
+ 0x592d, 0x5932, 0x5938, 0x593e, 0x7ad2, 0x5955, 0x5950, 0x594e,
+ 0x595a, 0x5958, 0x5962, 0x5960, 0x5967, 0x596c, 0x5969,
+ /* 0x5521 - 0x557e */
+ 0x5978, 0x5981, 0x599d, 0x4f5e, 0x4fab, 0x59a3, 0x59b2,
+ 0x59c6, 0x59e8, 0x59dc, 0x598d, 0x59d9, 0x59da, 0x5a25, 0x5a1f,
+ 0x5a11, 0x5a1c, 0x5a09, 0x5a1a, 0x5a40, 0x5a6c, 0x5a49, 0x5a35,
+ 0x5a36, 0x5a62, 0x5a6a, 0x5a9a, 0x5abc, 0x5abe, 0x5acb, 0x5ac2,
+ 0x5abd, 0x5ae3, 0x5ad7, 0x5ae6, 0x5ae9, 0x5ad6, 0x5afa, 0x5afb,
+ 0x5b0c, 0x5b0b, 0x5b16, 0x5b32, 0x5ad0, 0x5b2a, 0x5b36, 0x5b3e,
+ 0x5b43, 0x5b45, 0x5b40, 0x5b51, 0x5b55, 0x5b5a, 0x5b5b, 0x5b65,
+ 0x5b69, 0x5b70, 0x5b73, 0x5b75, 0x5b78, 0x6588, 0x5b7a, 0x5b80,
+ 0x5b83, 0x5ba6, 0x5bb8, 0x5bc3, 0x5bc7, 0x5bc9, 0x5bd4, 0x5bd0,
+ 0x5be4, 0x5be6, 0x5be2, 0x5bde, 0x5be5, 0x5beb, 0x5bf0, 0x5bf6,
+ 0x5bf3, 0x5c05, 0x5c07, 0x5c08, 0x5c0d, 0x5c13, 0x5c20, 0x5c22,
+ 0x5c28, 0x5c38, 0x5c39, 0x5c41, 0x5c46, 0x5c4e, 0x5c53,
+ /* 0x5621 - 0x567e */
+ 0x5c50, 0x5c4f, 0x5b71, 0x5c6c, 0x5c6e, 0x4e62, 0x5c76,
+ 0x5c79, 0x5c8c, 0x5c91, 0x5c94, 0x599b, 0x5cab, 0x5cbb, 0x5cb6,
+ 0x5cbc, 0x5cb7, 0x5cc5, 0x5cbe, 0x5cc7, 0x5cd9, 0x5ce9, 0x5cfd,
+ 0x5cfa, 0x5ced, 0x5d8c, 0x5cea, 0x5d0b, 0x5d15, 0x5d17, 0x5d5c,
+ 0x5d1f, 0x5d1b, 0x5d11, 0x5d14, 0x5d22, 0x5d1a, 0x5d19, 0x5d18,
+ 0x5d4c, 0x5d52, 0x5d4e, 0x5d4b, 0x5d6c, 0x5d73, 0x5d76, 0x5d87,
+ 0x5d84, 0x5d82, 0x5da2, 0x5d9d, 0x5dac, 0x5dae, 0x5dbd, 0x5d90,
+ 0x5db7, 0x5dbc, 0x5dc9, 0x5dcd, 0x5dd3, 0x5dd2, 0x5dd6, 0x5ddb,
+ 0x5deb, 0x5df2, 0x5df5, 0x5e0b, 0x5e1a, 0x5e19, 0x5e11, 0x5e1b,
+ 0x5e36, 0x5e37, 0x5e44, 0x5e43, 0x5e40, 0x5e4e, 0x5e57, 0x5e54,
+ 0x5e5f, 0x5e62, 0x5e64, 0x5e47, 0x5e75, 0x5e76, 0x5e7a, 0x9ebc,
+ 0x5e7f, 0x5ea0, 0x5ec1, 0x5ec2, 0x5ec8, 0x5ed0, 0x5ecf,
+ /* 0x5721 - 0x577e */
+ 0x5ed6, 0x5ee3, 0x5edd, 0x5eda, 0x5edb, 0x5ee2, 0x5ee1,
+ 0x5ee8, 0x5ee9, 0x5eec, 0x5ef1, 0x5ef3, 0x5ef0, 0x5ef4, 0x5ef8,
+ 0x5efe, 0x5f03, 0x5f09, 0x5f5d, 0x5f5c, 0x5f0b, 0x5f11, 0x5f16,
+ 0x5f29, 0x5f2d, 0x5f38, 0x5f41, 0x5f48, 0x5f4c, 0x5f4e, 0x5f2f,
+ 0x5f51, 0x5f56, 0x5f57, 0x5f59, 0x5f61, 0x5f6d, 0x5f73, 0x5f77,
+ 0x5f83, 0x5f82, 0x5f7f, 0x5f8a, 0x5f88, 0x5f91, 0x5f87, 0x5f9e,
+ 0x5f99, 0x5f98, 0x5fa0, 0x5fa8, 0x5fad, 0x5fbc, 0x5fd6, 0x5ffb,
+ 0x5fe4, 0x5ff8, 0x5ff1, 0x5fdd, 0x60b3, 0x5fff, 0x6021, 0x6060,
+ 0x6019, 0x6010, 0x6029, 0x600e, 0x6031, 0x601b, 0x6015, 0x602b,
+ 0x6026, 0x600f, 0x603a, 0x605a, 0x6041, 0x606a, 0x6077, 0x605f,
+ 0x604a, 0x6046, 0x604d, 0x6063, 0x6043, 0x6064, 0x6042, 0x606c,
+ 0x606b, 0x6059, 0x6081, 0x608d, 0x60e7, 0x6083, 0x609a,
+ /* 0x5821 - 0x587e */
+ 0x6084, 0x609b, 0x6096, 0x6097, 0x6092, 0x60a7, 0x608b,
+ 0x60e1, 0x60b8, 0x60e0, 0x60d3, 0x60b4, 0x5ff0, 0x60bd, 0x60c6,
+ 0x60b5, 0x60d8, 0x614d, 0x6115, 0x6106, 0x60f6, 0x60f7, 0x6100,
+ 0x60f4, 0x60fa, 0x6103, 0x6121, 0x60fb, 0x60f1, 0x610d, 0x610e,
+ 0x6147, 0x613e, 0x6128, 0x6127, 0x614a, 0x613f, 0x613c, 0x612c,
+ 0x6134, 0x613d, 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159,
+ 0x615a, 0x616b, 0x6174, 0x616f, 0x6165, 0x6171, 0x615f, 0x615d,
+ 0x6153, 0x6175, 0x6199, 0x6196, 0x6187, 0x61ac, 0x6194, 0x619a,
+ 0x618a, 0x6191, 0x61ab, 0x61ae, 0x61cc, 0x61ca, 0x61c9, 0x61f7,
+ 0x61c8, 0x61c3, 0x61c6, 0x61ba, 0x61cb, 0x7f79, 0x61cd, 0x61e6,
+ 0x61e3, 0x61f6, 0x61fa, 0x61f4, 0x61ff, 0x61fd, 0x61fc, 0x61fe,
+ 0x6200, 0x6208, 0x6209, 0x620d, 0x620c, 0x6214, 0x621b,
+ /* 0x5921 - 0x597e */
+ 0x621e, 0x6221, 0x622a, 0x622e, 0x6230, 0x6232, 0x6233,
+ 0x6241, 0x624e, 0x625e, 0x6263, 0x625b, 0x6260, 0x6268, 0x627c,
+ 0x6282, 0x6289, 0x627e, 0x6292, 0x6293, 0x6296, 0x62d4, 0x6283,
+ 0x6294, 0x62d7, 0x62d1, 0x62bb, 0x62cf, 0x62ff, 0x62c6, 0x64d4,
+ 0x62c8, 0x62dc, 0x62cc, 0x62ca, 0x62c2, 0x62c7, 0x629b, 0x62c9,
+ 0x630c, 0x62ee, 0x62f1, 0x6327, 0x6302, 0x6308, 0x62ef, 0x62f5,
+ 0x6350, 0x633e, 0x634d, 0x641c, 0x634f, 0x6396, 0x638e, 0x6380,
+ 0x63ab, 0x6376, 0x63a3, 0x638f, 0x6389, 0x639f, 0x63b5, 0x636b,
+ 0x6369, 0x63be, 0x63e9, 0x63c0, 0x63c6, 0x63e3, 0x63c9, 0x63d2,
+ 0x63f6, 0x63c4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436,
+ 0x651d, 0x6417, 0x6428, 0x640f, 0x6467, 0x646f, 0x6476, 0x644e,
+ 0x652a, 0x6495, 0x6493, 0x64a5, 0x64a9, 0x6488, 0x64bc,
+ /* 0x5a21 - 0x5a7e */
+ 0x64da, 0x64d2, 0x64c5, 0x64c7, 0x64bb, 0x64d8, 0x64c2,
+ 0x64f1, 0x64e7, 0x8209, 0x64e0, 0x64e1, 0x62ac, 0x64e3, 0x64ef,
+ 0x652c, 0x64f6, 0x64f4, 0x64f2, 0x64fa, 0x6500, 0x64fd, 0x6518,
+ 0x651c, 0x6505, 0x6524, 0x6523, 0x652b, 0x6534, 0x6535, 0x6537,
+ 0x6536, 0x6538, 0x754b, 0x6548, 0x6556, 0x6555, 0x654d, 0x6558,
+ 0x655e, 0x655d, 0x6572, 0x6578, 0x6582, 0x6583, 0x8b8a, 0x659b,
+ 0x659f, 0x65ab, 0x65b7, 0x65c3, 0x65c6, 0x65c1, 0x65c4, 0x65cc,
+ 0x65d2, 0x65db, 0x65d9, 0x65e0, 0x65e1, 0x65f1, 0x6772, 0x660a,
+ 0x6603, 0x65fb, 0x6773, 0x6635, 0x6636, 0x6634, 0x661c, 0x664f,
+ 0x6644, 0x6649, 0x6641, 0x665e, 0x665d, 0x6664, 0x6667, 0x6668,
+ 0x665f, 0x6662, 0x6670, 0x6683, 0x6688, 0x668e, 0x6689, 0x6684,
+ 0x6698, 0x669d, 0x66c1, 0x66b9, 0x66c9, 0x66be, 0x66bc,
+ /* 0x5b21 - 0x5b7e */
+ 0x66c4, 0x66b8, 0x66d6, 0x66da, 0x66e0, 0x663f, 0x66e6,
+ 0x66e9, 0x66f0, 0x66f5, 0x66f7, 0x670f, 0x6716, 0x671e, 0x6726,
+ 0x6727, 0x9738, 0x672e, 0x673f, 0x6736, 0x6741, 0x6738, 0x6737,
+ 0x6746, 0x675e, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770,
+ 0x67a9, 0x677c, 0x676a, 0x678c, 0x678b, 0x67a6, 0x67a1, 0x6785,
+ 0x67b7, 0x67ef, 0x67b4, 0x67ec, 0x67b3, 0x67e9, 0x67b8, 0x67e4,
+ 0x67de, 0x67dd, 0x67e2, 0x67ee, 0x67b9, 0x67ce, 0x67c6, 0x67e7,
+ 0x6a9c, 0x681e, 0x6846, 0x6829, 0x6840, 0x684d, 0x6832, 0x684e,
+ 0x68b3, 0x682b, 0x6859, 0x6863, 0x6877, 0x687f, 0x689f, 0x688f,
+ 0x68ad, 0x6894, 0x689d, 0x689b, 0x6883, 0x6aae, 0x68b9, 0x6874,
+ 0x68b5, 0x68a0, 0x68ba, 0x690f, 0x688d, 0x687e, 0x6901, 0x68ca,
+ 0x6908, 0x68d8, 0x6922, 0x6926, 0x68e1, 0x690c, 0x68cd,
+ /* 0x5c21 - 0x5c7e */
+ 0x68d4, 0x68e7, 0x68d5, 0x6936, 0x6912, 0x6904, 0x68d7,
+ 0x68e3, 0x6925, 0x68f9, 0x68e0, 0x68ef, 0x6928, 0x692a, 0x691a,
+ 0x6923, 0x6921, 0x68c6, 0x6979, 0x6977, 0x695c, 0x6978, 0x696b,
+ 0x6954, 0x697e, 0x696e, 0x6939, 0x6974, 0x693d, 0x6959, 0x6930,
+ 0x6961, 0x695e, 0x695d, 0x6981, 0x696a, 0x69b2, 0x69ae, 0x69d0,
+ 0x69bf, 0x69c1, 0x69d3, 0x69be, 0x69ce, 0x5be8, 0x69ca, 0x69dd,
+ 0x69bb, 0x69c3, 0x69a7, 0x6a2e, 0x6991, 0x69a0, 0x699c, 0x6995,
+ 0x69b4, 0x69de, 0x69e8, 0x6a02, 0x6a1b, 0x69ff, 0x6b0a, 0x69f9,
+ 0x69f2, 0x69e7, 0x6a05, 0x69b1, 0x6a1e, 0x69ed, 0x6a14, 0x69eb,
+ 0x6a0a, 0x6a12, 0x6ac1, 0x6a23, 0x6a13, 0x6a44, 0x6a0c, 0x6a72,
+ 0x6a36, 0x6a78, 0x6a47, 0x6a62, 0x6a59, 0x6a66, 0x6a48, 0x6a38,
+ 0x6a22, 0x6a90, 0x6a8d, 0x6aa0, 0x6a84, 0x6aa2, 0x6aa3,
+ /* 0x5d21 - 0x5d7e */
+ 0x6a97, 0x8617, 0x6abb, 0x6ac3, 0x6ac2, 0x6ab8, 0x6ab3,
+ 0x6aac, 0x6ade, 0x6ad1, 0x6adf, 0x6aaa, 0x6ada, 0x6aea, 0x6afb,
+ 0x6b05, 0x8616, 0x6afa, 0x6b12, 0x6b16, 0x9b31, 0x6b1f, 0x6b38,
+ 0x6b37, 0x76dc, 0x6b39, 0x98ee, 0x6b47, 0x6b43, 0x6b49, 0x6b50,
+ 0x6b59, 0x6b54, 0x6b5b, 0x6b5f, 0x6b61, 0x6b78, 0x6b79, 0x6b7f,
+ 0x6b80, 0x6b84, 0x6b83, 0x6b8d, 0x6b98, 0x6b95, 0x6b9e, 0x6ba4,
+ 0x6baa, 0x6bab, 0x6baf, 0x6bb2, 0x6bb1, 0x6bb3, 0x6bb7, 0x6bbc,
+ 0x6bc6, 0x6bcb, 0x6bd3, 0x6bdf, 0x6bec, 0x6beb, 0x6bf3, 0x6bef,
+ 0x9ebe, 0x6c08, 0x6c13, 0x6c14, 0x6c1b, 0x6c24, 0x6c23, 0x6c5e,
+ 0x6c55, 0x6c62, 0x6c6a, 0x6c82, 0x6c8d, 0x6c9a, 0x6c81, 0x6c9b,
+ 0x6c7e, 0x6c68, 0x6c73, 0x6c92, 0x6c90, 0x6cc4, 0x6cf1, 0x6cd3,
+ 0x6cbd, 0x6cd7, 0x6cc5, 0x6cdd, 0x6cae, 0x6cb1, 0x6cbe,
+ /* 0x5e21 - 0x5e7e */
+ 0x6cba, 0x6cdb, 0x6cef, 0x6cd9, 0x6cea, 0x6d1f, 0x884d,
+ 0x6d36, 0x6d2b, 0x6d3d, 0x6d38, 0x6d19, 0x6d35, 0x6d33, 0x6d12,
+ 0x6d0c, 0x6d63, 0x6d93, 0x6d64, 0x6d5a, 0x6d79, 0x6d59, 0x6d8e,
+ 0x6d95, 0x6fe4, 0x6d85, 0x6df9, 0x6e15, 0x6e0a, 0x6db5, 0x6dc7,
+ 0x6de6, 0x6db8, 0x6dc6, 0x6dec, 0x6dde, 0x6dcc, 0x6de8, 0x6dd2,
+ 0x6dc5, 0x6dfa, 0x6dd9, 0x6de4, 0x6dd5, 0x6dea, 0x6dee, 0x6e2d,
+ 0x6e6e, 0x6e2e, 0x6e19, 0x6e72, 0x6e5f, 0x6e3e, 0x6e23, 0x6e6b,
+ 0x6e2b, 0x6e76, 0x6e4d, 0x6e1f, 0x6e43, 0x6e3a, 0x6e4e, 0x6e24,
+ 0x6eff, 0x6e1d, 0x6e38, 0x6e82, 0x6eaa, 0x6e98, 0x6ec9, 0x6eb7,
+ 0x6ed3, 0x6ebd, 0x6eaf, 0x6ec4, 0x6eb2, 0x6ed4, 0x6ed5, 0x6e8f,
+ 0x6ea5, 0x6ec2, 0x6e9f, 0x6f41, 0x6f11, 0x704c, 0x6eec, 0x6ef8,
+ 0x6efe, 0x6f3f, 0x6ef2, 0x6f31, 0x6eef, 0x6f32, 0x6ecc,
+ /* 0x5f21 - 0x5f7e */
+ 0x6f3e, 0x6f13, 0x6ef7, 0x6f86, 0x6f7a, 0x6f78, 0x6f81,
+ 0x6f80, 0x6f6f, 0x6f5b, 0x6ff3, 0x6f6d, 0x6f82, 0x6f7c, 0x6f58,
+ 0x6f8e, 0x6f91, 0x6fc2, 0x6f66, 0x6fb3, 0x6fa3, 0x6fa1, 0x6fa4,
+ 0x6fb9, 0x6fc6, 0x6faa, 0x6fdf, 0x6fd5, 0x6fec, 0x6fd4, 0x6fd8,
+ 0x6ff1, 0x6fee, 0x6fdb, 0x7009, 0x700b, 0x6ffa, 0x7011, 0x7001,
+ 0x700f, 0x6ffe, 0x701b, 0x701a, 0x6f74, 0x701d, 0x7018, 0x701f,
+ 0x7030, 0x703e, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70af,
+ 0x70f1, 0x70ac, 0x70b8, 0x70b3, 0x70ae, 0x70df, 0x70cb, 0x70dd,
+ 0x70d9, 0x7109, 0x70fd, 0x711c, 0x7119, 0x7165, 0x7155, 0x7188,
+ 0x7166, 0x7162, 0x714c, 0x7156, 0x716c, 0x718f, 0x71fb, 0x7184,
+ 0x7195, 0x71a8, 0x71ac, 0x71d7, 0x71b9, 0x71be, 0x71d2, 0x71c9,
+ 0x71d4, 0x71ce, 0x71e0, 0x71ec, 0x71e7, 0x71f5, 0x71fc,
+ /* 0x6021 - 0x607e */
+ 0x71f9, 0x71ff, 0x720d, 0x7210, 0x721b, 0x7228, 0x722d,
+ 0x722c, 0x7230, 0x7232, 0x723b, 0x723c, 0x723f, 0x7240, 0x7246,
+ 0x724b, 0x7258, 0x7274, 0x727e, 0x7282, 0x7281, 0x7287, 0x7292,
+ 0x7296, 0x72a2, 0x72a7, 0x72b9, 0x72b2, 0x72c3, 0x72c6, 0x72c4,
+ 0x72ce, 0x72d2, 0x72e2, 0x72e0, 0x72e1, 0x72f9, 0x72f7, 0x500f,
+ 0x7317, 0x730a, 0x731c, 0x7316, 0x731d, 0x7334, 0x732f, 0x7329,
+ 0x7325, 0x733e, 0x734e, 0x734f, 0x9ed8, 0x7357, 0x736a, 0x7368,
+ 0x7370, 0x7378, 0x7375, 0x737b, 0x737a, 0x73c8, 0x73b3, 0x73ce,
+ 0x73bb, 0x73c0, 0x73e5, 0x73ee, 0x73de, 0x74a2, 0x7405, 0x746f,
+ 0x7425, 0x73f8, 0x7432, 0x743a, 0x7455, 0x743f, 0x745f, 0x7459,
+ 0x7441, 0x745c, 0x7469, 0x7470, 0x7463, 0x746a, 0x7476, 0x747e,
+ 0x748b, 0x749e, 0x74a7, 0x74ca, 0x74cf, 0x74d4, 0x73f1,
+ /* 0x6121 - 0x617e */
+ 0x74e0, 0x74e3, 0x74e7, 0x74e9, 0x74ee, 0x74f2, 0x74f0,
+ 0x74f1, 0x74f8, 0x74f7, 0x7504, 0x7503, 0x7505, 0x750c, 0x750e,
+ 0x750d, 0x7515, 0x7513, 0x751e, 0x7526, 0x752c, 0x753c, 0x7544,
+ 0x754d, 0x754a, 0x7549, 0x755b, 0x7546, 0x755a, 0x7569, 0x7564,
+ 0x7567, 0x756b, 0x756d, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574,
+ 0x758a, 0x7589, 0x7582, 0x7594, 0x759a, 0x759d, 0x75a5, 0x75a3,
+ 0x75c2, 0x75b3, 0x75c3, 0x75b5, 0x75bd, 0x75b8, 0x75bc, 0x75b1,
+ 0x75cd, 0x75ca, 0x75d2, 0x75d9, 0x75e3, 0x75de, 0x75fe, 0x75ff,
+ 0x75fc, 0x7601, 0x75f0, 0x75fa, 0x75f2, 0x75f3, 0x760b, 0x760d,
+ 0x7609, 0x761f, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634,
+ 0x7630, 0x763b, 0x7647, 0x7648, 0x7646, 0x765c, 0x7658, 0x7661,
+ 0x7662, 0x7668, 0x7669, 0x766a, 0x7667, 0x766c, 0x7670,
+ /* 0x6221 - 0x627e */
+ 0x7672, 0x7676, 0x7678, 0x767c, 0x7680, 0x7683, 0x7688,
+ 0x768b, 0x768e, 0x7696, 0x7693, 0x7699, 0x769a, 0x76b0, 0x76b4,
+ 0x76b8, 0x76b9, 0x76ba, 0x76c2, 0x76cd, 0x76d6, 0x76d2, 0x76de,
+ 0x76e1, 0x76e5, 0x76e7, 0x76ea, 0x862f, 0x76fb, 0x7708, 0x7707,
+ 0x7704, 0x7729, 0x7724, 0x771e, 0x7725, 0x7726, 0x771b, 0x7737,
+ 0x7738, 0x7747, 0x775a, 0x7768, 0x776b, 0x775b, 0x7765, 0x777f,
+ 0x777e, 0x7779, 0x778e, 0x778b, 0x7791, 0x77a0, 0x779e, 0x77b0,
+ 0x77b6, 0x77b9, 0x77bf, 0x77bc, 0x77bd, 0x77bb, 0x77c7, 0x77cd,
+ 0x77d7, 0x77da, 0x77dc, 0x77e3, 0x77ee, 0x77fc, 0x780c, 0x7812,
+ 0x7926, 0x7820, 0x792a, 0x7845, 0x788e, 0x7874, 0x7886, 0x787c,
+ 0x789a, 0x788c, 0x78a3, 0x78b5, 0x78aa, 0x78af, 0x78d1, 0x78c6,
+ 0x78cb, 0x78d4, 0x78be, 0x78bc, 0x78c5, 0x78ca, 0x78ec,
+ /* 0x6321 - 0x637e */
+ 0x78e7, 0x78da, 0x78fd, 0x78f4, 0x7907, 0x7912, 0x7911,
+ 0x7919, 0x792c, 0x792b, 0x7940, 0x7960, 0x7957, 0x795f, 0x795a,
+ 0x7955, 0x7953, 0x797a, 0x797f, 0x798a, 0x799d, 0x79a7, 0x9f4b,
+ 0x79aa, 0x79ae, 0x79b3, 0x79b9, 0x79ba, 0x79c9, 0x79d5, 0x79e7,
+ 0x79ec, 0x79e1, 0x79e3, 0x7a08, 0x7a0d, 0x7a18, 0x7a19, 0x7a20,
+ 0x7a1f, 0x7980, 0x7a31, 0x7a3b, 0x7a3e, 0x7a37, 0x7a43, 0x7a57,
+ 0x7a49, 0x7a61, 0x7a62, 0x7a69, 0x9f9d, 0x7a70, 0x7a79, 0x7a7d,
+ 0x7a88, 0x7a97, 0x7a95, 0x7a98, 0x7a96, 0x7aa9, 0x7ac8, 0x7ab0,
+ 0x7ab6, 0x7ac5, 0x7ac4, 0x7abf, 0x9083, 0x7ac7, 0x7aca, 0x7acd,
+ 0x7acf, 0x7ad5, 0x7ad3, 0x7ad9, 0x7ada, 0x7add, 0x7ae1, 0x7ae2,
+ 0x7ae6, 0x7aed, 0x7af0, 0x7b02, 0x7b0f, 0x7b0a, 0x7b06, 0x7b33,
+ 0x7b18, 0x7b19, 0x7b1e, 0x7b35, 0x7b28, 0x7b36, 0x7b50,
+ /* 0x6421 - 0x647e */
+ 0x7b7a, 0x7b04, 0x7b4d, 0x7b0b, 0x7b4c, 0x7b45, 0x7b75,
+ 0x7b65, 0x7b74, 0x7b67, 0x7b70, 0x7b71, 0x7b6c, 0x7b6e, 0x7b9d,
+ 0x7b98, 0x7b9f, 0x7b8d, 0x7b9c, 0x7b9a, 0x7b8b, 0x7b92, 0x7b8f,
+ 0x7b5d, 0x7b99, 0x7bcb, 0x7bc1, 0x7bcc, 0x7bcf, 0x7bb4, 0x7bc6,
+ 0x7bdd, 0x7be9, 0x7c11, 0x7c14, 0x7be6, 0x7be5, 0x7c60, 0x7c00,
+ 0x7c07, 0x7c13, 0x7bf3, 0x7bf7, 0x7c17, 0x7c0d, 0x7bf6, 0x7c23,
+ 0x7c27, 0x7c2a, 0x7c1f, 0x7c37, 0x7c2b, 0x7c3d, 0x7c4c, 0x7c43,
+ 0x7c54, 0x7c4f, 0x7c40, 0x7c50, 0x7c58, 0x7c5f, 0x7c64, 0x7c56,
+ 0x7c65, 0x7c6c, 0x7c75, 0x7c83, 0x7c90, 0x7ca4, 0x7cad, 0x7ca2,
+ 0x7cab, 0x7ca1, 0x7ca8, 0x7cb3, 0x7cb2, 0x7cb1, 0x7cae, 0x7cb9,
+ 0x7cbd, 0x7cc0, 0x7cc5, 0x7cc2, 0x7cd8, 0x7cd2, 0x7cdc, 0x7ce2,
+ 0x9b3b, 0x7cef, 0x7cf2, 0x7cf4, 0x7cf6, 0x7cfa, 0x7d06,
+ /* 0x6521 - 0x657e */
+ 0x7d02, 0x7d1c, 0x7d15, 0x7d0a, 0x7d45, 0x7d4b, 0x7d2e,
+ 0x7d32, 0x7d3f, 0x7d35, 0x7d46, 0x7d73, 0x7d56, 0x7d4e, 0x7d72,
+ 0x7d68, 0x7d6e, 0x7d4f, 0x7d63, 0x7d93, 0x7d89, 0x7d5b, 0x7d8f,
+ 0x7d7d, 0x7d9b, 0x7dba, 0x7dae, 0x7da3, 0x7db5, 0x7dc7, 0x7dbd,
+ 0x7dab, 0x7e3d, 0x7da2, 0x7daf, 0x7ddc, 0x7db8, 0x7d9f, 0x7db0,
+ 0x7dd8, 0x7ddd, 0x7de4, 0x7dde, 0x7dfb, 0x7df2, 0x7de1, 0x7e05,
+ 0x7e0a, 0x7e23, 0x7e21, 0x7e12, 0x7e31, 0x7e1f, 0x7e09, 0x7e0b,
+ 0x7e22, 0x7e46, 0x7e66, 0x7e3b, 0x7e35, 0x7e39, 0x7e43, 0x7e37,
+ 0x7e32, 0x7e3a, 0x7e67, 0x7e5d, 0x7e56, 0x7e5e, 0x7e59, 0x7e5a,
+ 0x7e79, 0x7e6a, 0x7e69, 0x7e7c, 0x7e7b, 0x7e83, 0x7dd5, 0x7e7d,
+ 0x8fae, 0x7e7f, 0x7e88, 0x7e89, 0x7e8c, 0x7e92, 0x7e90, 0x7e93,
+ 0x7e94, 0x7e96, 0x7e8e, 0x7e9b, 0x7e9c, 0x7f38, 0x7f3a,
+ /* 0x6621 - 0x667e */
+ 0x7f45, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f50, 0x7f51, 0x7f55,
+ 0x7f54, 0x7f58, 0x7f5f, 0x7f60, 0x7f68, 0x7f69, 0x7f67, 0x7f78,
+ 0x7f82, 0x7f86, 0x7f83, 0x7f88, 0x7f87, 0x7f8c, 0x7f94, 0x7f9e,
+ 0x7f9d, 0x7f9a, 0x7fa3, 0x7faf, 0x7fb2, 0x7fb9, 0x7fae, 0x7fb6,
+ 0x7fb8, 0x8b71, 0x7fc5, 0x7fc6, 0x7fca, 0x7fd5, 0x7fd4, 0x7fe1,
+ 0x7fe6, 0x7fe9, 0x7ff3, 0x7ff9, 0x98dc, 0x8006, 0x8004, 0x800b,
+ 0x8012, 0x8018, 0x8019, 0x801c, 0x8021, 0x8028, 0x803f, 0x803b,
+ 0x804a, 0x8046, 0x8052, 0x8058, 0x805a, 0x805f, 0x8062, 0x8068,
+ 0x8073, 0x8072, 0x8070, 0x8076, 0x8079, 0x807d, 0x807f, 0x8084,
+ 0x8086, 0x8085, 0x809b, 0x8093, 0x809a, 0x80ad, 0x5190, 0x80ac,
+ 0x80db, 0x80e5, 0x80d9, 0x80dd, 0x80c4, 0x80da, 0x80d6, 0x8109,
+ 0x80ef, 0x80f1, 0x811b, 0x8129, 0x8123, 0x812f, 0x814b,
+ /* 0x6721 - 0x677e */
+ 0x968b, 0x8146, 0x813e, 0x8153, 0x8151, 0x80fc, 0x8171,
+ 0x816e, 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818a, 0x8180,
+ 0x8182, 0x81a0, 0x8195, 0x81a4, 0x81a3, 0x815f, 0x8193, 0x81a9,
+ 0x81b0, 0x81b5, 0x81be, 0x81b8, 0x81bd, 0x81c0, 0x81c2, 0x81ba,
+ 0x81c9, 0x81cd, 0x81d1, 0x81d9, 0x81d8, 0x81c8, 0x81da, 0x81df,
+ 0x81e0, 0x81e7, 0x81fa, 0x81fb, 0x81fe, 0x8201, 0x8202, 0x8205,
+ 0x8207, 0x820a, 0x820d, 0x8210, 0x8216, 0x8229, 0x822b, 0x8238,
+ 0x8233, 0x8240, 0x8259, 0x8258, 0x825d, 0x825a, 0x825f, 0x8264,
+ 0x8262, 0x8268, 0x826a, 0x826b, 0x822e, 0x8271, 0x8277, 0x8278,
+ 0x827e, 0x828d, 0x8292, 0x82ab, 0x829f, 0x82bb, 0x82ac, 0x82e1,
+ 0x82e3, 0x82df, 0x82d2, 0x82f4, 0x82f3, 0x82fa, 0x8393, 0x8303,
+ 0x82fb, 0x82f9, 0x82de, 0x8306, 0x82dc, 0x8309, 0x82d9,
+ /* 0x6821 - 0x687e */
+ 0x8335, 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339,
+ 0x8350, 0x8345, 0x832f, 0x832b, 0x8317, 0x8318, 0x8385, 0x839a,
+ 0x83aa, 0x839f, 0x83a2, 0x8396, 0x8323, 0x838e, 0x8387, 0x838a,
+ 0x837c, 0x83b5, 0x8373, 0x8375, 0x83a0, 0x8389, 0x83a8, 0x83f4,
+ 0x8413, 0x83eb, 0x83ce, 0x83fd, 0x8403, 0x83d8, 0x840b, 0x83c1,
+ 0x83f7, 0x8407, 0x83e0, 0x83f2, 0x840d, 0x8422, 0x8420, 0x83bd,
+ 0x8438, 0x8506, 0x83fb, 0x846d, 0x842a, 0x843c, 0x855a, 0x8484,
+ 0x8477, 0x846b, 0x84ad, 0x846e, 0x8482, 0x8469, 0x8446, 0x842c,
+ 0x846f, 0x8479, 0x8435, 0x84ca, 0x8462, 0x84b9, 0x84bf, 0x849f,
+ 0x84d9, 0x84cd, 0x84bb, 0x84da, 0x84d0, 0x84c1, 0x84c6, 0x84d6,
+ 0x84a1, 0x8521, 0x84ff, 0x84f4, 0x8517, 0x8518, 0x852c, 0x851f,
+ 0x8515, 0x8514, 0x84fc, 0x8540, 0x8563, 0x8558, 0x8548,
+ /* 0x6921 - 0x697e */
+ 0x8541, 0x8602, 0x854b, 0x8555, 0x8580, 0x85a4, 0x8588,
+ 0x8591, 0x858a, 0x85a8, 0x856d, 0x8594, 0x859b, 0x85ea, 0x8587,
+ 0x859c, 0x8577, 0x857e, 0x8590, 0x85c9, 0x85ba, 0x85cf, 0x85b9,
+ 0x85d0, 0x85d5, 0x85dd, 0x85e5, 0x85dc, 0x85f9, 0x860a, 0x8613,
+ 0x860b, 0x85fe, 0x85fa, 0x8606, 0x8622, 0x861a, 0x8630, 0x863f,
+ 0x864d, 0x4e55, 0x8654, 0x865f, 0x8667, 0x8671, 0x8693, 0x86a3,
+ 0x86a9, 0x86aa, 0x868b, 0x868c, 0x86b6, 0x86af, 0x86c4, 0x86c6,
+ 0x86b0, 0x86c9, 0x8823, 0x86ab, 0x86d4, 0x86de, 0x86e9, 0x86ec,
+ 0x86df, 0x86db, 0x86ef, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703,
+ 0x86fb, 0x8711, 0x8709, 0x870d, 0x86f9, 0x870a, 0x8734, 0x873f,
+ 0x8737, 0x873b, 0x8725, 0x8729, 0x871a, 0x8760, 0x875f, 0x8778,
+ 0x874c, 0x874e, 0x8774, 0x8757, 0x8768, 0x876e, 0x8759,
+ /* 0x6a21 - 0x6a7e */
+ 0x8753, 0x8763, 0x876a, 0x8805, 0x87a2, 0x879f, 0x8782,
+ 0x87af, 0x87cb, 0x87bd, 0x87c0, 0x87d0, 0x96d6, 0x87ab, 0x87c4,
+ 0x87b3, 0x87c7, 0x87c6, 0x87bb, 0x87ef, 0x87f2, 0x87e0, 0x880f,
+ 0x880d, 0x87fe, 0x87f6, 0x87f7, 0x880e, 0x87d2, 0x8811, 0x8816,
+ 0x8815, 0x8822, 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883b,
+ 0x8844, 0x8842, 0x8852, 0x8859, 0x885e, 0x8862, 0x886b, 0x8881,
+ 0x887e, 0x889e, 0x8875, 0x887d, 0x88b5, 0x8872, 0x8882, 0x8897,
+ 0x8892, 0x88ae, 0x8899, 0x88a2, 0x888d, 0x88a4, 0x88b0, 0x88bf,
+ 0x88b1, 0x88c3, 0x88c4, 0x88d4, 0x88d8, 0x88d9, 0x88dd, 0x88f9,
+ 0x8902, 0x88fc, 0x88f4, 0x88e8, 0x88f2, 0x8904, 0x890c, 0x890a,
+ 0x8913, 0x8943, 0x891e, 0x8925, 0x892a, 0x892b, 0x8941, 0x8944,
+ 0x893b, 0x8936, 0x8938, 0x894c, 0x891d, 0x8960, 0x895e,
+ /* 0x6b21 - 0x6b7e */
+ 0x8966, 0x8964, 0x896d, 0x896a, 0x896f, 0x8974, 0x8977,
+ 0x897e, 0x8983, 0x8988, 0x898a, 0x8993, 0x8998, 0x89a1, 0x89a9,
+ 0x89a6, 0x89ac, 0x89af, 0x89b2, 0x89ba, 0x89bd, 0x89bf, 0x89c0,
+ 0x89da, 0x89dc, 0x89dd, 0x89e7, 0x89f4, 0x89f8, 0x8a03, 0x8a16,
+ 0x8a10, 0x8a0c, 0x8a1b, 0x8a1d, 0x8a25, 0x8a36, 0x8a41, 0x8a5b,
+ 0x8a52, 0x8a46, 0x8a48, 0x8a7c, 0x8a6d, 0x8a6c, 0x8a62, 0x8a85,
+ 0x8a82, 0x8a84, 0x8aa8, 0x8aa1, 0x8a91, 0x8aa5, 0x8aa6, 0x8a9a,
+ 0x8aa3, 0x8ac4, 0x8acd, 0x8ac2, 0x8ada, 0x8aeb, 0x8af3, 0x8ae7,
+ 0x8ae4, 0x8af1, 0x8b14, 0x8ae0, 0x8ae2, 0x8af7, 0x8ade, 0x8adb,
+ 0x8b0c, 0x8b07, 0x8b1a, 0x8ae1, 0x8b16, 0x8b10, 0x8b17, 0x8b20,
+ 0x8b33, 0x97ab, 0x8b26, 0x8b2b, 0x8b3e, 0x8b28, 0x8b41, 0x8b4c,
+ 0x8b4f, 0x8b4e, 0x8b49, 0x8b56, 0x8b5b, 0x8b5a, 0x8b6b,
+ /* 0x6c21 - 0x6c7e */
+ 0x8b5f, 0x8b6c, 0x8b6f, 0x8b74, 0x8b7d, 0x8b80, 0x8b8c,
+ 0x8b8e, 0x8b92, 0x8b93, 0x8b96, 0x8b99, 0x8b9a, 0x8c3a, 0x8c41,
+ 0x8c3f, 0x8c48, 0x8c4c, 0x8c4e, 0x8c50, 0x8c55, 0x8c62, 0x8c6c,
+ 0x8c78, 0x8c7a, 0x8c82, 0x8c89, 0x8c85, 0x8c8a, 0x8c8d, 0x8c8e,
+ 0x8c94, 0x8c7c, 0x8c98, 0x621d, 0x8cad, 0x8caa, 0x8cbd, 0x8cb2,
+ 0x8cb3, 0x8cae, 0x8cb6, 0x8cc8, 0x8cc1, 0x8ce4, 0x8ce3, 0x8cda,
+ 0x8cfd, 0x8cfa, 0x8cfb, 0x8d04, 0x8d05, 0x8d0a, 0x8d07, 0x8d0f,
+ 0x8d0d, 0x8d10, 0x9f4e, 0x8d13, 0x8ccd, 0x8d14, 0x8d16, 0x8d67,
+ 0x8d6d, 0x8d71, 0x8d73, 0x8d81, 0x8d99, 0x8dc2, 0x8dbe, 0x8dba,
+ 0x8dcf, 0x8dda, 0x8dd6, 0x8dcc, 0x8ddb, 0x8dcb, 0x8dea, 0x8deb,
+ 0x8ddf, 0x8de3, 0x8dfc, 0x8e08, 0x8e09, 0x8dff, 0x8e1d, 0x8e1e,
+ 0x8e10, 0x8e1f, 0x8e42, 0x8e35, 0x8e30, 0x8e34, 0x8e4a,
+ /* 0x6d21 - 0x6d7e */
+ 0x8e47, 0x8e49, 0x8e4c, 0x8e50, 0x8e48, 0x8e59, 0x8e64,
+ 0x8e60, 0x8e2a, 0x8e63, 0x8e55, 0x8e76, 0x8e72, 0x8e7c, 0x8e81,
+ 0x8e87, 0x8e85, 0x8e84, 0x8e8b, 0x8e8a, 0x8e93, 0x8e91, 0x8e94,
+ 0x8e99, 0x8eaa, 0x8ea1, 0x8eac, 0x8eb0, 0x8ec6, 0x8eb1, 0x8ebe,
+ 0x8ec5, 0x8ec8, 0x8ecb, 0x8edb, 0x8ee3, 0x8efc, 0x8efb, 0x8eeb,
+ 0x8efe, 0x8f0a, 0x8f05, 0x8f15, 0x8f12, 0x8f19, 0x8f13, 0x8f1c,
+ 0x8f1f, 0x8f1b, 0x8f0c, 0x8f26, 0x8f33, 0x8f3b, 0x8f39, 0x8f45,
+ 0x8f42, 0x8f3e, 0x8f4c, 0x8f49, 0x8f46, 0x8f4e, 0x8f57, 0x8f5c,
+ 0x8f62, 0x8f63, 0x8f64, 0x8f9c, 0x8f9f, 0x8fa3, 0x8fad, 0x8faf,
+ 0x8fb7, 0x8fda, 0x8fe5, 0x8fe2, 0x8fea, 0x8fef, 0x9087, 0x8ff4,
+ 0x9005, 0x8ff9, 0x8ffa, 0x9011, 0x9015, 0x9021, 0x900d, 0x901e,
+ 0x9016, 0x900b, 0x9027, 0x9036, 0x9035, 0x9039, 0x8ff8,
+ /* 0x6e21 - 0x6e7e */
+ 0x904f, 0x9050, 0x9051, 0x9052, 0x900e, 0x9049, 0x903e,
+ 0x9056, 0x9058, 0x905e, 0x9068, 0x906f, 0x9076, 0x96a8, 0x9072,
+ 0x9082, 0x907d, 0x9081, 0x9080, 0x908a, 0x9089, 0x908f, 0x90a8,
+ 0x90af, 0x90b1, 0x90b5, 0x90e2, 0x90e4, 0x6248, 0x90db, 0x9102,
+ 0x9112, 0x9119, 0x9132, 0x9130, 0x914a, 0x9156, 0x9158, 0x9163,
+ 0x9165, 0x9169, 0x9173, 0x9172, 0x918b, 0x9189, 0x9182, 0x91a2,
+ 0x91ab, 0x91af, 0x91aa, 0x91b5, 0x91b4, 0x91ba, 0x91c0, 0x91c1,
+ 0x91c9, 0x91cb, 0x91d0, 0x91d6, 0x91df, 0x91e1, 0x91db, 0x91fc,
+ 0x91f5, 0x91f6, 0x921e, 0x91ff, 0x9214, 0x922c, 0x9215, 0x9211,
+ 0x925e, 0x9257, 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923f,
+ 0x924b, 0x9250, 0x929c, 0x9296, 0x9293, 0x929b, 0x925a, 0x92cf,
+ 0x92b9, 0x92b7, 0x92e9, 0x930f, 0x92fa, 0x9344, 0x932e,
+ /* 0x6f21 - 0x6f7e */
+ 0x9319, 0x9322, 0x931a, 0x9323, 0x933a, 0x9335, 0x933b,
+ 0x935c, 0x9360, 0x937c, 0x936e, 0x9356, 0x93b0, 0x93ac, 0x93ad,
+ 0x9394, 0x93b9, 0x93d6, 0x93d7, 0x93e8, 0x93e5, 0x93d8, 0x93c3,
+ 0x93dd, 0x93d0, 0x93c8, 0x93e4, 0x941a, 0x9414, 0x9413, 0x9403,
+ 0x9407, 0x9410, 0x9436, 0x942b, 0x9435, 0x9421, 0x943a, 0x9441,
+ 0x9452, 0x9444, 0x945b, 0x9460, 0x9462, 0x945e, 0x946a, 0x9229,
+ 0x9470, 0x9475, 0x9477, 0x947d, 0x945a, 0x947c, 0x947e, 0x9481,
+ 0x947f, 0x9582, 0x9587, 0x958a, 0x9594, 0x9596, 0x9598, 0x9599,
+ 0x95a0, 0x95a8, 0x95a7, 0x95ad, 0x95bc, 0x95bb, 0x95b9, 0x95be,
+ 0x95ca, 0x6ff6, 0x95c3, 0x95cd, 0x95cc, 0x95d5, 0x95d4, 0x95d6,
+ 0x95dc, 0x95e1, 0x95e5, 0x95e2, 0x9621, 0x9628, 0x962e, 0x962f,
+ 0x9642, 0x964c, 0x964f, 0x964b, 0x9677, 0x965c, 0x965e,
+ /* 0x7021 - 0x707e */
+ 0x965d, 0x965f, 0x9666, 0x9672, 0x966c, 0x968d, 0x9698,
+ 0x9695, 0x9697, 0x96aa, 0x96a7, 0x96b1, 0x96b2, 0x96b0, 0x96b4,
+ 0x96b6, 0x96b8, 0x96b9, 0x96ce, 0x96cb, 0x96c9, 0x96cd, 0x894d,
+ 0x96dc, 0x970d, 0x96d5, 0x96f9, 0x9704, 0x9706, 0x9708, 0x9713,
+ 0x970e, 0x9711, 0x970f, 0x9716, 0x9719, 0x9724, 0x972a, 0x9730,
+ 0x9739, 0x973d, 0x973e, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749,
+ 0x975c, 0x9760, 0x9764, 0x9766, 0x9768, 0x52d2, 0x976b, 0x9771,
+ 0x9779, 0x9785, 0x977c, 0x9781, 0x977a, 0x9786, 0x978b, 0x978f,
+ 0x9790, 0x979c, 0x97a8, 0x97a6, 0x97a3, 0x97b3, 0x97b4, 0x97c3,
+ 0x97c6, 0x97c8, 0x97cb, 0x97dc, 0x97ed, 0x9f4f, 0x97f2, 0x7adf,
+ 0x97f6, 0x97f5, 0x980f, 0x980c, 0x9838, 0x9824, 0x9821, 0x9837,
+ 0x983d, 0x9846, 0x984f, 0x984b, 0x986b, 0x986f, 0x9870,
+ /* 0x7121 - 0x717e */
+ 0x9871, 0x9874, 0x9873, 0x98aa, 0x98af, 0x98b1, 0x98b6,
+ 0x98c4, 0x98c3, 0x98c6, 0x98e9, 0x98eb, 0x9903, 0x9909, 0x9912,
+ 0x9914, 0x9918, 0x9921, 0x991d, 0x991e, 0x9924, 0x9920, 0x992c,
+ 0x992e, 0x993d, 0x993e, 0x9942, 0x9949, 0x9945, 0x9950, 0x994b,
+ 0x9951, 0x9952, 0x994c, 0x9955, 0x9997, 0x9998, 0x99a5, 0x99ad,
+ 0x99ae, 0x99bc, 0x99df, 0x99db, 0x99dd, 0x99d8, 0x99d1, 0x99ed,
+ 0x99ee, 0x99f1, 0x99f2, 0x99fb, 0x99f8, 0x9a01, 0x9a0f, 0x9a05,
+ 0x99e2, 0x9a19, 0x9a2b, 0x9a37, 0x9a45, 0x9a42, 0x9a40, 0x9a43,
+ 0x9a3e, 0x9a55, 0x9a4d, 0x9a5b, 0x9a57, 0x9a5f, 0x9a62, 0x9a65,
+ 0x9a64, 0x9a69, 0x9a6b, 0x9a6a, 0x9aad, 0x9ab0, 0x9abc, 0x9ac0,
+ 0x9acf, 0x9ad1, 0x9ad3, 0x9ad4, 0x9ade, 0x9adf, 0x9ae2, 0x9ae3,
+ 0x9ae6, 0x9aef, 0x9aeb, 0x9aee, 0x9af4, 0x9af1, 0x9af7,
+ /* 0x7221 - 0x727e */
+ 0x9afb, 0x9b06, 0x9b18, 0x9b1a, 0x9b1f, 0x9b22, 0x9b23,
+ 0x9b25, 0x9b27, 0x9b28, 0x9b29, 0x9b2a, 0x9b2e, 0x9b2f, 0x9b32,
+ 0x9b44, 0x9b43, 0x9b4f, 0x9b4d, 0x9b4e, 0x9b51, 0x9b58, 0x9b74,
+ 0x9b93, 0x9b83, 0x9b91, 0x9b96, 0x9b97, 0x9b9f, 0x9ba0, 0x9ba8,
+ 0x9bb4, 0x9bc0, 0x9bca, 0x9bb9, 0x9bc6, 0x9bcf, 0x9bd1, 0x9bd2,
+ 0x9be3, 0x9be2, 0x9be4, 0x9bd4, 0x9be1, 0x9c3a, 0x9bf2, 0x9bf1,
+ 0x9bf0, 0x9c15, 0x9c14, 0x9c09, 0x9c13, 0x9c0c, 0x9c06, 0x9c08,
+ 0x9c12, 0x9c0a, 0x9c04, 0x9c2e, 0x9c1b, 0x9c25, 0x9c24, 0x9c21,
+ 0x9c30, 0x9c47, 0x9c32, 0x9c46, 0x9c3e, 0x9c5a, 0x9c60, 0x9c67,
+ 0x9c76, 0x9c78, 0x9ce7, 0x9cec, 0x9cf0, 0x9d09, 0x9d08, 0x9ceb,
+ 0x9d03, 0x9d06, 0x9d2a, 0x9d26, 0x9daf, 0x9d23, 0x9d1f, 0x9d44,
+ 0x9d15, 0x9d12, 0x9d41, 0x9d3f, 0x9d3e, 0x9d46, 0x9d48,
+ /* 0x7321 - 0x737e */
+ 0x9d5d, 0x9d5e, 0x9d64, 0x9d51, 0x9d50, 0x9d59, 0x9d72,
+ 0x9d89, 0x9d87, 0x9dab, 0x9d6f, 0x9d7a, 0x9d9a, 0x9da4, 0x9da9,
+ 0x9db2, 0x9dc4, 0x9dc1, 0x9dbb, 0x9db8, 0x9dba, 0x9dc6, 0x9dcf,
+ 0x9dc2, 0x9dd9, 0x9dd3, 0x9df8, 0x9de6, 0x9ded, 0x9def, 0x9dfd,
+ 0x9e1a, 0x9e1b, 0x9e1e, 0x9e75, 0x9e79, 0x9e7d, 0x9e81, 0x9e88,
+ 0x9e8b, 0x9e8c, 0x9e92, 0x9e95, 0x9e91, 0x9e9d, 0x9ea5, 0x9ea9,
+ 0x9eb8, 0x9eaa, 0x9ead, 0x9761, 0x9ecc, 0x9ece, 0x9ecf, 0x9ed0,
+ 0x9ed4, 0x9edc, 0x9ede, 0x9edd, 0x9ee0, 0x9ee5, 0x9ee8, 0x9eef,
+ 0x9ef4, 0x9ef6, 0x9ef7, 0x9ef9, 0x9efb, 0x9efc, 0x9efd, 0x9f07,
+ 0x9f08, 0x76b7, 0x9f15, 0x9f21, 0x9f2c, 0x9f3e, 0x9f4a, 0x9f52,
+ 0x9f54, 0x9f63, 0x9f5f, 0x9f60, 0x9f61, 0x9f66, 0x9f67, 0x9f6c,
+ 0x9f6a, 0x9f77, 0x9f72, 0x9f76, 0x9f95, 0x9f9c, 0x9fa0,
+ /* 0x7421 - 0x747e */
+ 0x582f, 0x69c7, 0x9059, 0x7464, 0x51dc, 0x7199, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7521 - 0x757e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7621 - 0x767e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7721 - 0x777e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7821 - 0x787e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7921 - 0x797e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7a21 - 0x7a7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7b21 - 0x7b7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7c21 - 0x7c7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7d21 - 0x7d7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7e21 - 0x7e7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static uint jisx0208ToUnicode11(uint h, uint l)
+{
+ if ((0x0021 <= h) && (h <= 0x007e) && (0x0021 <= l) && (l <= 0x007e)) {
+ return jisx0208_to_tqunicode[(h - 0x0021) * 0x005e + (l - 0x0021)];
+ }
+ return 0x0000;
+}
+
+/*
+ * This data is derived from Unicode 1.1,
+ * JIS X 0208 (1990) to Unicode mapping table version 0.9 .
+ * (In addition NEC Vender Defined Char included)
+ */
+static unsigned short const tqunicode_to_jisx0208_00[] = {
+ /* 0x0000 - 0x00ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2140, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2171, 0x2172, 0x0000, 0x0000, 0x0000, 0x2178,
+ 0x212f, 0x0000, 0x0000, 0x0000, 0x224c, 0x0000, 0x0000, 0x0000,
+ 0x216b, 0x215e, 0x0000, 0x0000, 0x212d, 0x0000, 0x2279, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x215f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2160,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_03[] = {
+ /* 0x0300 - 0x03ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x2621, 0x2622, 0x2623, 0x2624, 0x2625, 0x2626, 0x2627,
+ 0x2628, 0x2629, 0x262a, 0x262b, 0x262c, 0x262d, 0x262e, 0x262f,
+ 0x2630, 0x2631, 0x0000, 0x2632, 0x2633, 0x2634, 0x2635, 0x2636,
+ 0x2637, 0x2638, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x2641, 0x2642, 0x2643, 0x2644, 0x2645, 0x2646, 0x2647,
+ 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, 0x264e, 0x264f,
+ 0x2650, 0x2651, 0x0000, 0x2652, 0x2653, 0x2654, 0x2655, 0x2656,
+ 0x2657, 0x2658, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_04[] = {
+ /* 0x0400 - 0x04ff */
+ 0x0000, 0x2727, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, 0x2728, 0x2729,
+ 0x272a, 0x272b, 0x272c, 0x272d, 0x272e, 0x272f, 0x2730, 0x2731,
+ 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737, 0x2738, 0x2739,
+ 0x273a, 0x273b, 0x273c, 0x273d, 0x273e, 0x273f, 0x2740, 0x2741,
+ 0x2751, 0x2752, 0x2753, 0x2754, 0x2755, 0x2756, 0x2758, 0x2759,
+ 0x275a, 0x275b, 0x275c, 0x275d, 0x275e, 0x275f, 0x2760, 0x2761,
+ 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767, 0x2768, 0x2769,
+ 0x276a, 0x276b, 0x276c, 0x276d, 0x276e, 0x276f, 0x2770, 0x2771,
+ 0x0000, 0x2757, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_20[] = {
+ /* 0x2000 - 0x20ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x213e, 0x0000, 0x0000, 0x0000, 0x0000, 0x213d, 0x2142, 0x0000,
+ 0x2146, 0x2147, 0x0000, 0x0000, 0x2148, 0x2149, 0x0000, 0x0000,
+ 0x2277, 0x2278, 0x0000, 0x0000, 0x0000, 0x2145, 0x2144, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2273, 0x0000, 0x216c, 0x216d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2228, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_21[] = {
+ /* 0x2100 - 0x21ff */
+ 0x0000, 0x0000, 0x0000, 0x216e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d62, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x2d64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2272, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2d35, 0x2d36, 0x2d37, 0x2d38, 0x2d39, 0x2d3a, 0x2d3b, 0x2d3c,
+ 0x2d3d, 0x2d3e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x222b, 0x222c, 0x222a, 0x222d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x224d, 0x0000, 0x224e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_22[] = {
+ /* 0x2200 - 0x22ff */
+ 0x224f, 0x0000, 0x225f, 0x2250, 0x0000, 0x0000, 0x0000, 0x2260,
+ 0x223a, 0x0000, 0x0000, 0x223b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x2d74, 0x215d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2265, 0x0000, 0x0000, 0x2267, 0x2167, 0x2d78,
+ 0x225c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x224a,
+ 0x224b, 0x2241, 0x2240, 0x2269, 0x226a, 0x0000, 0x2d73, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2168, 0x2268, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2266, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2262, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2162, 0x2261, 0x0000, 0x0000, 0x0000, 0x0000, 0x2165, 0x2166,
+ 0x0000, 0x0000, 0x2263, 0x2264, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x223e, 0x223f, 0x0000, 0x0000, 0x223c, 0x223d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x225d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d79,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_23[] = {
+ /* 0x2300 - 0x23ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x225e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_24[] = {
+ /* 0x2400 - 0x24ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2d21, 0x2d22, 0x2d23, 0x2d24, 0x2d25, 0x2d26, 0x2d27, 0x2d28,
+ 0x2d29, 0x2d2a, 0x2d2b, 0x2d2c, 0x2d2d, 0x2d2e, 0x2d2f, 0x2d30,
+ 0x2d31, 0x2d32, 0x2d33, 0x2d34, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_25[] = {
+ /* 0x2500 - 0x25ff */
+ 0x2821, 0x282c, 0x2822, 0x282d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2823, 0x0000, 0x0000, 0x282e,
+ 0x2824, 0x0000, 0x0000, 0x282f, 0x2826, 0x0000, 0x0000, 0x2831,
+ 0x2825, 0x0000, 0x0000, 0x2830, 0x2827, 0x283c, 0x0000, 0x0000,
+ 0x2837, 0x0000, 0x0000, 0x2832, 0x2829, 0x283e, 0x0000, 0x0000,
+ 0x2839, 0x0000, 0x0000, 0x2834, 0x2828, 0x0000, 0x0000, 0x2838,
+ 0x283d, 0x0000, 0x0000, 0x2833, 0x282a, 0x0000, 0x0000, 0x283a,
+ 0x283f, 0x0000, 0x0000, 0x2835, 0x282b, 0x0000, 0x0000, 0x283b,
+ 0x0000, 0x0000, 0x2840, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2836, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2223, 0x2222, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2225, 0x2224, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2227, 0x2226, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2221, 0x217e,
+ 0x0000, 0x0000, 0x0000, 0x217b, 0x0000, 0x0000, 0x217d, 0x217c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x227e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_26[] = {
+ /* 0x2600 - 0x26ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x217a, 0x2179, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x216a, 0x0000, 0x2169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2276, 0x0000, 0x0000, 0x2275, 0x0000, 0x2274,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_30[] = {
+ /* 0x3000 - 0x30ff */
+ 0x2121, 0x2122, 0x2123, 0x2137, 0x0000, 0x2139, 0x213a, 0x213b,
+ 0x2152, 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159,
+ 0x215a, 0x215b, 0x2229, 0x222e, 0x214c, 0x214d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2141, 0x2d60, 0x0000, 0x2d61,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x2421, 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427,
+ 0x2428, 0x2429, 0x242a, 0x242b, 0x242c, 0x242d, 0x242e, 0x242f,
+ 0x2430, 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437,
+ 0x2438, 0x2439, 0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f,
+ 0x2440, 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447,
+ 0x2448, 0x2449, 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f,
+ 0x2450, 0x2451, 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457,
+ 0x2458, 0x2459, 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f,
+ 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467,
+ 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f,
+ 0x2470, 0x2471, 0x2472, 0x2473, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x212b, 0x212c, 0x2135, 0x2136, 0x0000,
+ 0x0000, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527,
+ 0x2528, 0x2529, 0x252a, 0x252b, 0x252c, 0x252d, 0x252e, 0x252f,
+ 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, 0x2537,
+ 0x2538, 0x2539, 0x253a, 0x253b, 0x253c, 0x253d, 0x253e, 0x253f,
+ 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547,
+ 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, 0x254e, 0x254f,
+ 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557,
+ 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, 0x255f,
+ 0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567,
+ 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x256d, 0x256e, 0x256f,
+ 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2126, 0x213c, 0x2133, 0x2134, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_32[] = {
+ /* 0x3200 - 0x32ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x2d6a, 0x2d6b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x2d6c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2d65, 0x2d66, 0x2d67, 0x2d68,
+ 0x2d69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_33[] = {
+ /* 0x3300 - 0x33ff */
+ 0x0000, 0x0000, 0x0000, 0x2d46, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d4a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2d41, 0x0000, 0x0000, 0x0000,
+ 0x2d44, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2d42, 0x2d4c, 0x0000, 0x0000, 0x2d4b, 0x2d45,
+ 0x0000, 0x0000, 0x0000, 0x2d4d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d47, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2d4f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x2d40, 0x2d4e, 0x0000, 0x0000, 0x2d43, 0x0000, 0x0000,
+ 0x0000, 0x2d48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d49,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2d5f, 0x2d6f, 0x2d6e, 0x2d6d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d53, 0x2d54,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2d50, 0x2d51, 0x2d52, 0x0000,
+ 0x0000, 0x2d56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2d55, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d63, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_4e[] = {
+ /* 0x4e00 - 0x4eff */
+ 0x306c, 0x437a, 0x0000, 0x3c37, 0x0000, 0x0000, 0x0000, 0x4b7c,
+ 0x3e66, 0x3b30, 0x3e65, 0x323c, 0x0000, 0x4954, 0x4d3f, 0x0000,
+ 0x5022, 0x312f, 0x0000, 0x0000, 0x336e, 0x5023, 0x4024, 0x5242,
+ 0x3556, 0x4a3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e67, 0x0000,
+ 0x0000, 0x4e3e, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a42, 0x0000,
+ 0x0000, 0x0000, 0x5024, 0x0000, 0x0000, 0x4366, 0x0000, 0x0000,
+ 0x0000, 0x5025, 0x367a, 0x0000, 0x0000, 0x0000, 0x5026, 0x0000,
+ 0x345d, 0x4330, 0x0000, 0x3c67, 0x5027, 0x0000, 0x0000, 0x5028,
+ 0x0000, 0x0000, 0x5029, 0x4735, 0x0000, 0x3557, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4737, 0x0000, 0x4663, 0x3843, 0x4b33,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6949, 0x502a, 0x3e68,
+ 0x502b, 0x3235, 0x0000, 0x0000, 0x0000, 0x3665, 0x3870, 0x4c69,
+ 0x0000, 0x0000, 0x5626, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4d70, 0x0000, 0x467d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3425, 0x0000,
+ 0x3535, 0x0000, 0x502c, 0x0000, 0x0000, 0x502d, 0x4e3b, 0x0000,
+ 0x4d3d, 0x4168, 0x502f, 0x3b76, 0x4673, 0x0000, 0x5032, 0x0000,
+ 0x0000, 0x313e, 0x385f, 0x0000, 0x385e, 0x3066, 0x0000, 0x0000,
+ 0x4f4b, 0x4f4a, 0x0000, 0x3a33, 0x3021, 0x0000, 0x5033, 0x5034,
+ 0x5035, 0x4b34, 0x5036, 0x0000, 0x3872, 0x3067, 0x4b72, 0x0000,
+ 0x357c, 0x0000, 0x0000, 0x357d, 0x357e, 0x4462, 0x4e3c, 0x0000,
+ 0x5037, 0x0000, 0x0000, 0x5038, 0x0000, 0x0000, 0x5039, 0x0000,
+ 0x0000, 0x0000, 0x3f4d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3d3a, 0x3f4e, 0x503e, 0x0000, 0x503c, 0x0000, 0x503d, 0x3558,
+ 0x0000, 0x0000, 0x3a23, 0x3270, 0x0000, 0x503b, 0x503a, 0x4a29,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3b46, 0x3b45, 0x423e, 0x503f,
+ 0x4955, 0x4067, 0x0000, 0x0000, 0x0000, 0x2138, 0x5040, 0x5042,
+ 0x0000, 0x0000, 0x0000, 0x4265, 0x4e61, 0x304a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5041, 0x323e, 0x0000,
+ 0x3644, 0x0000, 0x4367, 0x0000, 0x0000, 0x0000, 0x376f, 0x5043,
+ 0x0000, 0x0000, 0x0000, 0x4724, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_4f[] = {
+ /* 0x4f00 - 0x4fff */
+ 0x0000, 0x346b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5044, 0x304b, 0x0000, 0x0000, 0x3860, 0x346c, 0x497a,
+ 0x4832, 0x3559, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3271, 0x0000, 0x5067, 0x4541, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x476c,
+ 0x5046, 0x0000, 0x0000, 0x0000, 0x483c, 0x0000, 0x4e62, 0x0000,
+ 0x3f2d, 0x0000, 0x3b47, 0x0000, 0x3b77, 0x3240, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4451, 0x0000, 0x0000, 0x4322, 0x504a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x304c, 0x4463, 0x3d3b,
+ 0x3a34, 0x4d24, 0x0000, 0x424e, 0x0000, 0x323f, 0x0000, 0x5049,
+ 0x0000, 0x4d3e, 0x5045, 0x5047, 0x3a6e, 0x5048, 0x5524, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5050, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5053,
+ 0x5051, 0x0000, 0x0000, 0x3242, 0x0000, 0x4a3b, 0x504b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x504f, 0x3873, 0x0000, 0x0000, 0x3b48,
+ 0x0000, 0x0000, 0x0000, 0x3426, 0x0000, 0x0000, 0x5054, 0x0000,
+ 0x504c, 0x0000, 0x0000, 0x4e63, 0x0000, 0x3b78, 0x0000, 0x504d,
+ 0x0000, 0x5052, 0x0000, 0x0000, 0x0000, 0x0000, 0x5055, 0x0000,
+ 0x504e, 0x0000, 0x0000, 0x3621, 0x0000, 0x304d, 0x0000, 0x0000,
+ 0x3622, 0x3241, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5525, 0x0000, 0x4b79, 0x496e, 0x3874,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f2f, 0x4e37, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a58,
+ 0x0000, 0x0000, 0x3738, 0x4225, 0x3264, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3d53, 0x0000, 0x0000, 0x0000, 0x5059, 0x0000,
+ 0x505e, 0x505c, 0x0000, 0x0000, 0x5057, 0x0000, 0x0000, 0x422f,
+ 0x505a, 0x0000, 0x505d, 0x505b, 0x0000, 0x4a5d, 0x0000, 0x5058,
+ 0x0000, 0x3f2e, 0x0000, 0x4b73, 0x505f, 0x5060, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d24, 0x506d,
+ 0x0000, 0x0000, 0x0000, 0x4750, 0x0000, 0x4936, 0x5068, 0x0000,
+ 0x4a70, 0x0000, 0x3236, 0x0000, 0x0000, 0x0000, 0x506c, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_50[] = {
+ /* 0x5000 - 0x50ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5066, 0x506f, 0x0000,
+ 0x0000, 0x4152, 0x0000, 0x3844, 0x0000, 0x475c, 0x0000, 0x6047,
+ 0x0000, 0x506e, 0x455d, 0x0000, 0x5063, 0x0000, 0x3876, 0x0000,
+ 0x0000, 0x3875, 0x5061, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c5a,
+ 0x0000, 0x5069, 0x0000, 0x4a6f, 0x434d, 0x5065, 0x3771, 0x0000,
+ 0x5062, 0x506a, 0x5064, 0x4e51, 0x506b, 0x4f41, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3666, 0x0000,
+ 0x0000, 0x3770, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5070, 0x0000, 0x0000, 0x0000, 0x5071,
+ 0x5075, 0x304e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a50,
+ 0x5074, 0x0000, 0x0000, 0x0000, 0x0000, 0x5073, 0x5077, 0x0000,
+ 0x0000, 0x0000, 0x5076, 0x0000, 0x4464, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3772, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5078, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3c45, 0x0000, 0x4226, 0x4465, 0x3676, 0x0000,
+ 0x5079, 0x0000, 0x0000, 0x0000, 0x0000, 0x3536, 0x0000, 0x0000,
+ 0x507a, 0x0000, 0x0000, 0x0000, 0x0000, 0x507c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b35, 0x0000, 0x0000,
+ 0x0000, 0x3766, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3b31, 0x4877, 0x507b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3a45, 0x4d43, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x507e, 0x5123, 0x507d, 0x3a44, 0x0000, 0x3d7d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3739, 0x0000,
+ 0x0000, 0x0000, 0x5124, 0x0000, 0x0000, 0x364f, 0x0000, 0x0000,
+ 0x0000, 0x5121, 0x5122, 0x0000, 0x0000, 0x462f, 0x0000, 0x417c,
+ 0x0000, 0x3623, 0x0000, 0x0000, 0x0000, 0x4b4d, 0x5125, 0x0000,
+ 0x0000, 0x0000, 0x4e3d, 0x0000, 0x0000, 0x0000, 0x5126, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5129, 0x0000, 0x5127, 0x0000, 0x414e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5128, 0x512a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x512c, 0x0000, 0x0000,
+ 0x0000, 0x512b, 0x0000, 0x4a48, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_51[] = {
+ /* 0x5100 - 0x51ff */
+ 0x3537, 0x512e, 0x512f, 0x0000, 0x322f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x512d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3c74, 0x0000, 0x5132, 0x5131, 0x5130, 0x0000,
+ 0x5056, 0x0000, 0x5133, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d7e,
+ 0x0000, 0x5134, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4d25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4c59, 0x0000, 0x0000, 0x0000, 0x0000, 0x5136,
+ 0x0000, 0x0000, 0x5135, 0x5138, 0x5137, 0x0000, 0x0000, 0x5139,
+ 0x513a, 0x3074, 0x0000, 0x3835, 0x373b, 0x3d3c, 0x437b, 0x3624,
+ 0x4068, 0x3877, 0x0000, 0x396e, 0x513c, 0x4c48, 0x4546, 0x0000,
+ 0x3b79, 0x0000, 0x513b, 0x0000, 0x513d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x455e, 0x0000, 0x3375, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x513e, 0x0000, 0x0000, 0x467e, 0x0000, 0x0000,
+ 0x4134, 0x5140, 0x5141, 0x482c, 0x3878, 0x4f3b, 0x5142, 0x0000,
+ 0x0000, 0x3626, 0x0000, 0x0000, 0x0000, 0x4a3c, 0x4236, 0x3671,
+ 0x4535, 0x0000, 0x0000, 0x0000, 0x3773, 0x0000, 0x0000, 0x0000,
+ 0x5143, 0x0000, 0x5144, 0x0000, 0x0000, 0x4662, 0x315f, 0x0000,
+ 0x0000, 0x5147, 0x3a7d, 0x0000, 0x5146, 0x3a46, 0x0000, 0x5148,
+ 0x666e, 0x5149, 0x4b41, 0x514a, 0x0000, 0x514b, 0x514c, 0x3e69,
+ 0x0000, 0x3c4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3427, 0x0000, 0x514f, 0x0000, 0x514d, 0x4c3d, 0x514e, 0x0000,
+ 0x495a, 0x5150, 0x5151, 0x5152, 0x455f, 0x0000, 0x0000, 0x0000,
+ 0x5156, 0x5154, 0x5155, 0x5153, 0x3a63, 0x5157, 0x4c6a, 0x4e64,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5158, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4028, 0x5159, 0x3d5a, 0x0000,
+ 0x0000, 0x515a, 0x0000, 0x437c, 0x4e3f, 0x4560, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5245, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x515b, 0x7425, 0x3645, 0x0000, 0x0000,
+ 0x515c, 0x4b5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d68, 0x427c,
+ 0x0000, 0x515e, 0x4664, 0x0000, 0x0000, 0x515f, 0x0000, 0x0000,
+ 0x5160, 0x332e, 0x0000, 0x0000, 0x0000, 0x5161, 0x3627, 0x0000,
+ 0x464c, 0x317a, 0x3d50, 0x0000, 0x0000, 0x4821, 0x5162, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_52[] = {
+ /* 0x5200 - 0x52ff */
+ 0x4561, 0x0000, 0x0000, 0x3f4f, 0x5163, 0x0000, 0x4a2c, 0x405a,
+ 0x3422, 0x0000, 0x3429, 0x5164, 0x0000, 0x0000, 0x5166, 0x0000,
+ 0x0000, 0x373a, 0x0000, 0x0000, 0x5165, 0x0000, 0x0000, 0x4e73,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d69, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x483d, 0x4a4c, 0x0000, 0x5167,
+ 0x0000, 0x4d78, 0x5168, 0x0000, 0x0000, 0x0000, 0x5169, 0x0000,
+ 0x457e, 0x0000, 0x0000, 0x516a, 0x0000, 0x0000, 0x4029, 0x3a7e,
+ 0x3774, 0x516b, 0x3b49, 0x396f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4466, 0x516d, 0x0000, 0x0000, 0x4227,
+ 0x0000, 0x0000, 0x3a6f, 0x516e, 0x516f, 0x4130, 0x0000, 0x516c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5171, 0x0000, 0x4b36, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3964, 0x0000, 0x0000, 0x5170, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3775, 0x3a5e, 0x476d, 0x0000, 0x0000,
+ 0x0000, 0x5174, 0x5172, 0x0000, 0x0000, 0x0000, 0x0000, 0x497b,
+ 0x3e6a, 0x517b, 0x3364, 0x5175, 0x5173, 0x414f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5177, 0x0000, 0x5176,
+ 0x0000, 0x0000, 0x0000, 0x3344, 0x0000, 0x0000, 0x0000, 0x3760,
+ 0x517c, 0x4e2d, 0x0000, 0x0000, 0x0000, 0x5178, 0x0000, 0x0000,
+ 0x0000, 0x517d, 0x517a, 0x0000, 0x5179, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4e4f, 0x0000, 0x0000, 0x0000, 0x3879,
+ 0x3243, 0x0000, 0x0000, 0x4e74, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3d75, 0x4558, 0x3965, 0x5222, 0x5223, 0x0000, 0x0000,
+ 0x0000, 0x4e65, 0x0000, 0x0000, 0x4f2b, 0x5225, 0x0000, 0x0000,
+ 0x0000, 0x387a, 0x0000, 0x0000, 0x5224, 0x0000, 0x332f, 0x0000,
+ 0x0000, 0x5226, 0x0000, 0x4b56, 0x0000, 0x443c, 0x0000, 0x4d26,
+ 0x0000, 0x4a59, 0x0000, 0x0000, 0x0000, 0x5227, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x7055, 0x0000, 0x0000, 0x4630, 0x0000, 0x5228,
+ 0x342a, 0x4c33, 0x0000, 0x0000, 0x0000, 0x3e21, 0x5229, 0x4a67,
+ 0x522d, 0x0000, 0x402a, 0x522a, 0x3650, 0x0000, 0x522b, 0x342b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x372e, 0x522e, 0x0000, 0x522f, 0x0000, 0x0000,
+ 0x5230, 0x5231, 0x3c5b, 0x0000, 0x0000, 0x0000, 0x387b, 0x4c5e,
+};
+
+static unsigned short const tqunicode_to_jisx0208_53[] = {
+ /* 0x5300 - 0x53ff */
+ 0x0000, 0x4c68, 0x4677, 0x0000, 0x0000, 0x4a71, 0x5232, 0x0000,
+ 0x5233, 0x0000, 0x0000, 0x0000, 0x0000, 0x5235, 0x0000, 0x5237,
+ 0x5236, 0x0000, 0x0000, 0x0000, 0x0000, 0x5238, 0x323d, 0x4b4c,
+ 0x0000, 0x3a7c, 0x5239, 0x0000, 0x0000, 0x4159, 0x0000, 0x0000,
+ 0x3e22, 0x3629, 0x0000, 0x523a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x485b, 0x0000, 0x0000, 0x0000, 0x0000, 0x523b,
+ 0x0000, 0x523c, 0x0000, 0x523d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x523e, 0x4924, 0x3668, 0x3065, 0x0000, 0x0000, 0x0000, 0x463f,
+ 0x523f, 0x3d3d, 0x0000, 0x4069, 0x0000, 0x5241, 0x5240, 0x3e23,
+ 0x3861, 0x5243, 0x483e, 0x0000, 0x0000, 0x5244, 0x0000, 0x0000,
+ 0x0000, 0x485c, 0x4234, 0x426e, 0x3628, 0x0000, 0x0000, 0x466e,
+ 0x4331, 0x0000, 0x476e, 0x0000, 0x4b4e, 0x0000, 0x5246, 0x0000,
+ 0x406a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3735, 0x0000,
+ 0x0000, 0x5247, 0x0000, 0x0000, 0x0000, 0x0000, 0x5248, 0x312c,
+ 0x3075, 0x346d, 0x0000, 0x4228, 0x3551, 0x4d71, 0x0000, 0x524b,
+ 0x3237, 0x0000, 0x0000, 0x524a, 0x0000, 0x0000, 0x0000, 0x362a,
+ 0x0000, 0x0000, 0x524c, 0x0000, 0x4c71, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x524d, 0x0000,
+ 0x4e52, 0x0000, 0x387c, 0x0000, 0x0000, 0x0000, 0x0000, 0x3836,
+ 0x524e, 0x0000, 0x0000, 0x0000, 0x0000, 0x5250, 0x524f, 0x0000,
+ 0x3f5f, 0x3139, 0x0000, 0x0000, 0x0000, 0x315e, 0x5251, 0x0000,
+ 0x5252, 0x0000, 0x0000, 0x3837, 0x0000, 0x0000, 0x5253, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x356e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3b32, 0x5254, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4b74, 0x3a35, 0x355a, 0x4d27, 0x4150, 0x483f, 0x3c7d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3d47, 0x0000, 0x3c68, 0x3c75,
+ 0x0000, 0x3d76, 0x0000, 0x4840, 0x0000, 0x0000, 0x0000, 0x5257,
+ 0x0000, 0x3143, 0x4151, 0x387d, 0x3845, 0x3667, 0x0000, 0x0000,
+ 0x525b, 0x4321, 0x427e, 0x362b, 0x3e24, 0x525c, 0x525a, 0x3244,
+ 0x4266, 0x3c38, 0x3b4b, 0x3126, 0x0000, 0x0000, 0x3370, 0x3966,
+ 0x3b4a, 0x0000, 0x525d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_54[] = {
+ /* 0x5400 - 0x54ff */
+ 0x0000, 0x525e, 0x0000, 0x3549, 0x3346, 0x0000, 0x0000, 0x0000,
+ 0x3967, 0x3548, 0x445f, 0x3125, 0x4631, 0x4c3e, 0x3921, 0x4d79,
+ 0x4547, 0x387e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x372f, 0x0000, 0x5267, 0x0000, 0x3663,
+ 0x4b4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x485d, 0x0000,
+ 0x0000, 0x5266, 0x0000, 0x345e, 0x5261, 0x5262, 0x5264, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5265, 0x0000,
+ 0x355b, 0x3f61, 0x0000, 0x4a2d, 0x5263, 0x525f, 0x3863, 0x0000,
+ 0x5260, 0x0000, 0x4f24, 0x0000, 0x0000, 0x0000, 0x4a72, 0x0000,
+ 0x4468, 0x3862, 0x3970, 0x0000, 0x0000, 0x0000, 0x5268, 0x0000,
+ 0x0000, 0x465d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x526c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3c7e, 0x0000, 0x3c76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x526f, 0x526d, 0x0000, 0x4c23, 0x0000, 0x526a, 0x5273, 0x526e,
+ 0x0000, 0x0000, 0x0000, 0x5271, 0x3846, 0x4c3f, 0x0000, 0x0000,
+ 0x5272, 0x0000, 0x0000, 0x0000, 0x5274, 0x0000, 0x5276, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3a70, 0x4f42, 0x0000, 0x526b, 0x5269,
+ 0x5275, 0x0000, 0x5270, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5278, 0x0000, 0x5323, 0x527a, 0x0000, 0x0000,
+ 0x527e, 0x0000, 0x0000, 0x5321, 0x527b, 0x0000, 0x0000, 0x533e,
+ 0x0000, 0x0000, 0x3a69, 0x3331, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5279, 0x0000, 0x0000, 0x0000, 0x5325, 0x3076, 0x5324, 0x0000,
+ 0x3025, 0x494a, 0x5322, 0x0000, 0x527c, 0x0000, 0x0000, 0x5277,
+ 0x527d, 0x3a48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5326, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3077, 0x532f, 0x0000, 0x0000, 0x5327, 0x5328, 0x0000,
+ 0x3e25, 0x4b69, 0x0000, 0x0000, 0x0000, 0x532d, 0x532c, 0x0000,
+ 0x0000, 0x0000, 0x452f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x532e, 0x0000, 0x0000, 0x532b, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_55[] = {
+ /* 0x5500 - 0x55ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3134, 0x0000, 0x3a36, 0x3f30,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5329,
+ 0x4562, 0x0000, 0x0000, 0x0000, 0x532a, 0x0000, 0x3022, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5334, 0x4d23,
+ 0x0000, 0x3e27, 0x0000, 0x533a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5339, 0x5330, 0x0000, 0x0000, 0x0000, 0x0000, 0x4243, 0x0000,
+ 0x5331, 0x0000, 0x0000, 0x0000, 0x426f, 0x5336, 0x3e26, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5333, 0x0000, 0x0000, 0x4c64,
+ 0x0000, 0x0000, 0x0000, 0x373c, 0x0000, 0x0000, 0x5337, 0x5338,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5335, 0x533b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5332, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5341, 0x5346, 0x0000, 0x5342, 0x0000,
+ 0x533d, 0x0000, 0x0000, 0x5347, 0x4131, 0x0000, 0x0000, 0x5349,
+ 0x0000, 0x3922, 0x533f, 0x437d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5343, 0x533c, 0x342d, 0x0000, 0x346e, 0x3365, 0x5344, 0x5340,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3776,
+ 0x534a, 0x5348, 0x4153, 0x354a, 0x362c, 0x0000, 0x5345, 0x0000,
+ 0x3674, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3144, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x534e, 0x534c, 0x0000, 0x5427,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5351, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x534b, 0x0000, 0x534f, 0x0000, 0x0000, 0x534d,
+ 0x0000, 0x0000, 0x0000, 0x3b4c, 0x5350, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5353,
+ 0x0000, 0x5358, 0x0000, 0x0000, 0x0000, 0x5356, 0x5355, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_56[] = {
+ /* 0x5600 - 0x56ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4332, 0x0000,
+ 0x0000, 0x3245, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5352, 0x0000, 0x5354, 0x3e28,
+ 0x3133, 0x0000, 0x0000, 0x5357, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x325e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5362,
+ 0x0000, 0x3e7c, 0x535e, 0x0000, 0x535c, 0x0000, 0x535d, 0x0000,
+ 0x535f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x313d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4139, 0x0000, 0x5359, 0x0000,
+ 0x535a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x337a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5361, 0x0000, 0x0000, 0x0000,
+ 0x346f, 0x0000, 0x5364, 0x5360, 0x5363, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4a2e, 0x0000, 0x0000, 0x0000,
+ 0x4655, 0x0000, 0x4838, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5366, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5365, 0x3345,
+ 0x0000, 0x0000, 0x5367, 0x0000, 0x0000, 0x0000, 0x0000, 0x536a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5369, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5368, 0x0000, 0x4739, 0x0000, 0x0000, 0x536b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x536c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x536e, 0x0000, 0x536d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5370, 0x0000, 0x0000, 0x0000,
+ 0x5373, 0x5371, 0x536f, 0x5372, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5374, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5375, 0x0000,
+ 0x0000, 0x5376, 0x0000, 0x5377, 0x0000, 0x0000, 0x0000, 0x5378,
+ 0x5145, 0x0000, 0x3c7c, 0x3b4d, 0x0000, 0x0000, 0x3273, 0x0000,
+ 0x3078, 0x0000, 0x0000, 0x4344, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5379, 0x0000,
+ 0x3a24, 0x0000, 0x304f, 0x3f5e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x537a, 0x3847, 0x0000, 0x0000, 0x3971, 0x0000, 0x537c,
+};
+
+static unsigned short const tqunicode_to_jisx0208_57[] = {
+ /* 0x5700 - 0x57ff */
+ 0x537b, 0x0000, 0x0000, 0x4a60, 0x537d, 0x0000, 0x0000, 0x0000,
+ 0x5421, 0x537e, 0x0000, 0x5422, 0x0000, 0x5423, 0x0000, 0x3777,
+ 0x0000, 0x0000, 0x3160, 0x5424, 0x0000, 0x0000, 0x5426, 0x0000,
+ 0x5425, 0x0000, 0x0000, 0x0000, 0x5428, 0x0000, 0x0000, 0x455a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5429, 0x3035,
+ 0x3a5f, 0x0000, 0x0000, 0x0000, 0x0000, 0x373d, 0x0000, 0x0000,
+ 0x434f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x542a,
+ 0x542b, 0x0000, 0x0000, 0x542d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x542e, 0x0000, 0x3a64, 0x0000, 0x0000, 0x0000, 0x0000, 0x3651,
+ 0x0000, 0x0000, 0x4b37, 0x0000, 0x0000, 0x0000, 0x542c, 0x542f,
+ 0x3a41, 0x3923, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5433, 0x0000, 0x0000, 0x3a25, 0x0000, 0x4333, 0x0000,
+ 0x0000, 0x5430, 0x445a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5434,
+ 0x0000, 0x0000, 0x3f62, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5432, 0x5435, 0x0000, 0x373f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5436, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5437, 0x0000, 0x3924, 0x3340, 0x5439, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x543a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x543b, 0x0000, 0x0000, 0x5438, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5431, 0x0000, 0x0000, 0x543c, 0x0000, 0x0000, 0x543d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4b64, 0x0000, 0x0000, 0x3e6b, 0x0000,
+ 0x0000, 0x0000, 0x543f, 0x5440, 0x543e, 0x0000, 0x5442, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4738, 0x0000, 0x0000, 0x3068,
+ 0x4956, 0x0000, 0x0000, 0x5443, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3e7d, 0x0000, 0x0000, 0x3c39,
+ 0x0000, 0x475d, 0x3470, 0x0000, 0x3a6b, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_58[] = {
+ /* 0x5800 - 0x58ff */
+ 0x4b59, 0x0000, 0x4632, 0x0000, 0x0000, 0x3778, 0x424f, 0x0000,
+ 0x0000, 0x0000, 0x5441, 0x5444, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4244, 0x0000, 0x0000,
+ 0x0000, 0x5445, 0x0000, 0x0000, 0x0000, 0x5446, 0x0000, 0x0000,
+ 0x0000, 0x5448, 0x0000, 0x0000, 0x4469, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x342e, 0x0000, 0x0000, 0x0000, 0x0000, 0x7421,
+ 0x3161, 0x4a73, 0x0000, 0x0000, 0x3e6c, 0x4548, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3a66, 0x0000, 0x0000, 0x544e, 0x0000, 0x0000,
+ 0x4a3d, 0x4e5d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3274, 0x544a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x413a, 0x544d, 0x0000, 0x4563, 0x0000, 0x0000, 0x4549,
+ 0x4564, 0x4839, 0x444d, 0x0000, 0x0000, 0x0000, 0x3a49, 0x0000,
+ 0x0000, 0x0000, 0x5449, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3176, 0x0000, 0x4536, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x544b, 0x0000, 0x5447, 0x0000, 0x0000, 0x3f50, 0x0000, 0x0000,
+ 0x0000, 0x544f, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d4e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x362d, 0x0000, 0x5450, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a68, 0x0000, 0x0000, 0x0000, 0x417d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4446, 0x0000, 0x0000, 0x5452,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4b4f, 0x0000, 0x0000, 0x5453, 0x0000, 0x0000, 0x5458, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a2f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5457, 0x5451, 0x5454, 0x5456, 0x0000, 0x0000, 0x3a26, 0x0000,
+ 0x0000, 0x4a49, 0x0000, 0x0000, 0x0000, 0x5459, 0x0000, 0x4345,
+ 0x0000, 0x0000, 0x3275, 0x0000, 0x3e6d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x545b, 0x0000, 0x545a, 0x0000, 0x3968, 0x0000, 0x545c,
+ 0x545e, 0x545d, 0x0000, 0x0000, 0x5460, 0x0000, 0x5455, 0x5462,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5461, 0x545f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3b4e, 0x3f51, 0x0000, 0x4154, 0x5463,
+ 0x403c, 0x306d, 0x4764, 0x0000, 0x0000, 0x0000, 0x0000, 0x445b,
+ 0x0000, 0x5465, 0x5464, 0x5466, 0x5467, 0x5468, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_59[] = {
+ /* 0x5900 - 0x59ff */
+ 0x0000, 0x0000, 0x5469, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4a51, 0x546a, 0x0000, 0x0000, 0x0000, 0x0000, 0x3246,
+ 0x546b, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d3c, 0x3330, 0x0000,
+ 0x5249, 0x3d48, 0x423f, 0x546c, 0x4c6b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4c34, 0x0000, 0x0000, 0x546e, 0x0000, 0x4267,
+ 0x0000, 0x4537, 0x4240, 0x4957, 0x546f, 0x5470, 0x317b, 0x0000,
+ 0x0000, 0x3c3a, 0x5471, 0x0000, 0x0000, 0x0000, 0x0000, 0x3050,
+ 0x5472, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5473, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3162, 0x0000, 0x0000, 0x3471,
+ 0x4660, 0x4a74, 0x0000, 0x0000, 0x0000, 0x0000, 0x5477, 0x4155,
+ 0x5476, 0x3740, 0x0000, 0x0000, 0x4b5b, 0x5475, 0x0000, 0x4565,
+ 0x5479, 0x0000, 0x5478, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x547b, 0x0000, 0x547a, 0x0000, 0x0000, 0x317c, 0x0000, 0x547c,
+ 0x3e29, 0x547e, 0x4325, 0x0000, 0x547d, 0x0000, 0x4a33, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3d77, 0x455b, 0x0000, 0x0000, 0x0000,
+ 0x5521, 0x0000, 0x0000, 0x0000, 0x0000, 0x3925, 0x0000, 0x0000,
+ 0x0000, 0x5522, 0x4721, 0x485e, 0x4c51, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4725, 0x0000, 0x0000, 0x552b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3538, 0x0000, 0x0000, 0x4d45, 0x0000,
+ 0x0000, 0x4c2f, 0x0000, 0x562c, 0x0000, 0x5523, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5526, 0x0000, 0x4245, 0x0000, 0x0000,
+ 0x4b38, 0x0000, 0x0000, 0x0000, 0x454a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5527, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4b65, 0x0000, 0x3a4a, 0x0000, 0x0000, 0x3e2a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5528, 0x0000,
+ 0x0000, 0x3b50, 0x0000, 0x3b4f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3039, 0x3848, 0x0000, 0x402b, 0x3051, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x552c, 0x552d, 0x0000, 0x552a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3138, 0x342f, 0x0000,
+ 0x5529, 0x0000, 0x4c45, 0x4931, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3028, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3079, 0x0000, 0x0000, 0x0000, 0x3b51,
+};
+
+static unsigned short const tqunicode_to_jisx0208_5a[] = {
+ /* 0x5a00 - 0x5aff */
+ 0x0000, 0x3052, 0x0000, 0x3023, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5532, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5530, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4c3c, 0x0000, 0x5533, 0x0000, 0x5531, 0x0000, 0x0000, 0x552f,
+ 0x3f31, 0x0000, 0x0000, 0x0000, 0x0000, 0x552e, 0x0000, 0x0000,
+ 0x0000, 0x4a5a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3864,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5537, 0x5538, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3e2b, 0x0000, 0x0000, 0x0000,
+ 0x5534, 0x4f2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x474c, 0x0000,
+ 0x0000, 0x5536, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3a27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5539, 0x0000, 0x0000, 0x0000, 0x4958, 0x0000,
+ 0x0000, 0x0000, 0x553a, 0x0000, 0x5535, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c3b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x475e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x553b, 0x4932, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x553c, 0x5540, 0x553d, 0x0000,
+ 0x0000, 0x3247, 0x553f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3c3b, 0x0000, 0x553e, 0x3779, 0x0000, 0x0000, 0x0000,
+ 0x554c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5545, 0x5542,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4364, 0x0000, 0x5541, 0x0000, 0x0000, 0x5543, 0x0000,
+ 0x0000, 0x5544, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5546, 0x5547, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_5b[] = {
+ /* 0x5b00 - 0x5bff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3472, 0x0000, 0x5549, 0x5548, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x554a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3e6e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x554d, 0x0000, 0x445c, 0x0000, 0x0000, 0x0000,
+ 0x3145, 0x0000, 0x554b, 0x0000, 0x0000, 0x0000, 0x554e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x554f, 0x0000,
+ 0x5552, 0x0000, 0x0000, 0x5550, 0x0000, 0x5551, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3b52, 0x5553, 0x0000, 0x0000, 0x3926, 0x5554, 0x0000, 0x3b7a,
+ 0x4238, 0x0000, 0x5555, 0x5556, 0x3b5a, 0x3927, 0x0000, 0x4c52,
+ 0x0000, 0x0000, 0x0000, 0x3528, 0x3849, 0x5557, 0x3358, 0x0000,
+ 0x0000, 0x5558, 0x0000, 0x4239, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5559, 0x5623, 0x0000, 0x555a, 0x0000, 0x555b, 0x0000, 0x0000,
+ 0x555c, 0x0000, 0x555e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x555f, 0x0000, 0x0000, 0x5560, 0x0000, 0x4270, 0x0000, 0x3127,
+ 0x3c69, 0x3042, 0x0000, 0x4157, 0x3430, 0x3c35, 0x0000, 0x3928,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4566, 0x0000, 0x3d21,
+ 0x3431, 0x4368, 0x446a, 0x3038, 0x3539, 0x4a75, 0x0000, 0x3c42,
+ 0x0000, 0x0000, 0x3552, 0x406b, 0x3c3c, 0x4d28, 0x5561, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x355c, 0x0000,
+ 0x3a4b, 0x0000, 0x0000, 0x3332, 0x3163, 0x3e2c, 0x3248, 0x0000,
+ 0x5562, 0x4d46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d49,
+ 0x0000, 0x0000, 0x3c64, 0x5563, 0x3473, 0x4652, 0x4c29, 0x5564,
+ 0x0000, 0x5565, 0x0000, 0x0000, 0x4959, 0x0000, 0x0000, 0x0000,
+ 0x5567, 0x0000, 0x3428, 0x3677, 0x5566, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3432, 0x0000, 0x3f32, 0x556b, 0x3b21,
+ 0x0000, 0x3249, 0x556a, 0x0000, 0x5568, 0x556c, 0x5569, 0x472b,
+ 0x5c4d, 0x3f33, 0x0000, 0x556d, 0x0000, 0x0000, 0x4e40, 0x0000,
+ 0x556e, 0x0000, 0x0000, 0x5570, 0x0000, 0x437e, 0x556f, 0x0000,
+ 0x4023, 0x0000, 0x3b7b, 0x0000, 0x0000, 0x0000, 0x4250, 0x3c77,
+};
+
+static unsigned short const tqunicode_to_jisx0208_5c[] = {
+ /* 0x5c00 - 0x5cff */
+ 0x0000, 0x4975, 0x406c, 0x0000, 0x3c4d, 0x5571, 0x3e2d, 0x5572,
+ 0x5573, 0x3053, 0x423a, 0x3f52, 0x0000, 0x5574, 0x4633, 0x3e2e,
+ 0x0000, 0x3e2f, 0x0000, 0x5575, 0x0000, 0x0000, 0x406d, 0x0000,
+ 0x0000, 0x0000, 0x3e30, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5576, 0x0000, 0x5577, 0x0000, 0x4c60, 0x0000, 0x0000, 0x0000,
+ 0x5578, 0x0000, 0x0000, 0x0000, 0x0000, 0x3646, 0x0000, 0x0000,
+ 0x0000, 0x3d22, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5579, 0x557a, 0x3c5c, 0x3f2c, 0x4674, 0x3f54, 0x4878, 0x4722,
+ 0x3649, 0x557b, 0x0000, 0x0000, 0x0000, 0x356f, 0x557c, 0x0000,
+ 0x367e, 0x0000, 0x464f, 0x3230, 0x0000, 0x3b53, 0x557d, 0x5622,
+ 0x5621, 0x367d, 0x0000, 0x557e, 0x0000, 0x4538, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4230, 0x0000,
+ 0x454b, 0x3c48, 0x0000, 0x0000, 0x4158, 0x4d7a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5624, 0x0000, 0x5625, 0x4656,
+ 0x0000, 0x3b33, 0x0000, 0x0000, 0x0000, 0x0000, 0x5627, 0x0000,
+ 0x0000, 0x5628, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5629, 0x0000, 0x0000, 0x0000,
+ 0x3474, 0x562a, 0x0000, 0x0000, 0x562b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x322c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x413b, 0x3464, 0x0000, 0x562d, 0x4c28, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4252, 0x0000, 0x3359, 0x0000, 0x0000, 0x562f, 0x5631,
+ 0x345f, 0x0000, 0x0000, 0x562e, 0x5630, 0x0000, 0x5633, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5632, 0x0000, 0x5634,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5635, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x463d, 0x362e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3265, 0x5636, 0x563b, 0x0000, 0x0000, 0x5639, 0x0000, 0x4a77,
+ 0x4a76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4567, 0x0000,
+ 0x0000, 0x0000, 0x5638, 0x3d54, 0x0000, 0x5637, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_5d[] = {
+ /* 0x5d00 - 0x5dff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f72,
+ 0x0000, 0x0000, 0x0000, 0x563c, 0x0000, 0x0000, 0x3a6a, 0x0000,
+ 0x0000, 0x5642, 0x0000, 0x0000, 0x5643, 0x563d, 0x3333, 0x563e,
+ 0x5647, 0x5646, 0x5645, 0x5641, 0x0000, 0x0000, 0x0000, 0x5640,
+ 0x0000, 0x0000, 0x5644, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4a78, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x564b, 0x5648, 0x0000, 0x564a, 0x0000,
+ 0x4d72, 0x0000, 0x5649, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x563f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3f73, 0x0000, 0x0000, 0x564c, 0x0000, 0x0000, 0x3a37,
+ 0x0000, 0x0000, 0x0000, 0x564d, 0x0000, 0x0000, 0x564e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5651, 0x0000, 0x5650, 0x0000, 0x0000, 0x564f,
+ 0x0000, 0x0000, 0x0000, 0x4568, 0x563a, 0x0000, 0x0000, 0x0000,
+ 0x5657, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5653, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5654, 0x0000, 0x5655, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5658,
+ 0x0000, 0x0000, 0x4e66, 0x0000, 0x5659, 0x5656, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x565a, 0x0000, 0x0000, 0x3460, 0x565b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x565d, 0x565c, 0x0000, 0x0000, 0x565e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x565f, 0x0000, 0x406e, 0x3d23, 0x0000,
+ 0x0000, 0x3d64, 0x0000, 0x4163, 0x0000, 0x3929, 0x3a38, 0x392a,
+ 0x3570, 0x0000, 0x0000, 0x5660, 0x0000, 0x0000, 0x3a39, 0x0000,
+ 0x0000, 0x384a, 0x5661, 0x4c26, 0x4743, 0x5662, 0x0000, 0x392b,
+ 0x0000, 0x0000, 0x0000, 0x342c, 0x0000, 0x4327, 0x3652, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_5e[] = {
+ /* 0x5e00 - 0x5eff */
+ 0x0000, 0x0000, 0x3b54, 0x495b, 0x0000, 0x0000, 0x4841, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5663, 0x3475, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5666, 0x0000, 0x0000, 0x0000, 0x0000, 0x4421, 0x0000,
+ 0x0000, 0x5665, 0x5664, 0x5667, 0x0000, 0x446b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f63, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3b55, 0x0000, 0x404a, 0x0000, 0x4253,
+ 0x3522, 0x0000, 0x0000, 0x4422, 0x0000, 0x0000, 0x5668, 0x5669,
+ 0x3e6f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b39, 0x0000, 0x0000,
+ 0x566c, 0x0000, 0x0000, 0x566b, 0x566a, 0x497d, 0x0000, 0x5673,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4b5a, 0x0000, 0x566d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x566f, 0x4b6b, 0x0000, 0x566e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5670,
+ 0x0000, 0x4828, 0x5671, 0x4a3e, 0x5672, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3433, 0x4a3f, 0x472f, 0x5674, 0x5675, 0x0000,
+ 0x392c, 0x3434, 0x5676, 0x3838, 0x4d44, 0x4d29, 0x3476, 0x5678,
+ 0x0000, 0x4423, 0x0000, 0x392d, 0x3e31, 0x0000, 0x0000, 0x485f,
+ 0x0000, 0x0000, 0x3e32, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d78,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x446c, 0x4a79, 0x4539,
+ 0x0000, 0x0000, 0x392e, 0x0000, 0x495c, 0x0000, 0x0000, 0x0000,
+ 0x5679, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4559, 0x3a42,
+ 0x0000, 0x0000, 0x0000, 0x384b, 0x0000, 0x446d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3043, 0x3d6e, 0x392f,
+ 0x4d47, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x567a, 0x567b, 0x4751, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x567c, 0x4e77, 0x4f2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x567e,
+ 0x567d, 0x0000, 0x0000, 0x3347, 0x0000, 0x0000, 0x5721, 0x0000,
+ 0x0000, 0x0000, 0x5724, 0x5725, 0x0000, 0x5723, 0x0000, 0x4940,
+ 0x3e33, 0x5727, 0x5726, 0x5722, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5728, 0x5729, 0x0000, 0x0000, 0x572a, 0x0000, 0x0000, 0x0000,
+ 0x572d, 0x572b, 0x0000, 0x572c, 0x572e, 0x0000, 0x3164, 0x446e,
+ 0x572f, 0x0000, 0x377a, 0x3276, 0x4736, 0x0000, 0x5730, 0x467b,
+};
+
+static unsigned short const tqunicode_to_jisx0208_5f[] = {
+ /* 0x5f00 - 0x5fff */
+ 0x0000, 0x4a5b, 0x0000, 0x5731, 0x4f2e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5732, 0x4a40, 0x5735, 0x5021, 0x5031, 0x0000, 0x3c30,
+ 0x4675, 0x5736, 0x0000, 0x355d, 0x4424, 0x307a, 0x5737, 0x4a26,
+ 0x3930, 0x0000, 0x0000, 0x4350, 0x0000, 0x0000, 0x0000, 0x446f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c6f, 0x3839, 0x384c,
+ 0x0000, 0x5738, 0x0000, 0x0000, 0x0000, 0x5739, 0x0000, 0x573f,
+ 0x0000, 0x3c65, 0x0000, 0x0000, 0x0000, 0x4425, 0x0000, 0x362f,
+ 0x573a, 0x0000, 0x0000, 0x0000, 0x492b, 0x0000, 0x4346, 0x0000,
+ 0x0000, 0x573b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x573c, 0x0000, 0x3630, 0x0000, 0x573d, 0x0000, 0x573e, 0x0000,
+ 0x0000, 0x5740, 0x0000, 0x4576, 0x0000, 0x0000, 0x5741, 0x5742,
+ 0x0000, 0x5743, 0x0000, 0x0000, 0x5734, 0x5733, 0x0000, 0x0000,
+ 0x0000, 0x5744, 0x3741, 0x0000, 0x0000, 0x0000, 0x4927, 0x0000,
+ 0x0000, 0x3a4c, 0x4937, 0x4426, 0x494b, 0x5745, 0x0000, 0x0000,
+ 0x3e34, 0x3146, 0x0000, 0x5746, 0x0000, 0x0000, 0x0000, 0x5747,
+ 0x0000, 0x4c72, 0x0000, 0x0000, 0x4860, 0x0000, 0x0000, 0x574a,
+ 0x317d, 0x402c, 0x5749, 0x5748, 0x3742, 0x4254, 0x0000, 0x574e,
+ 0x574c, 0x0000, 0x574b, 0x4e27, 0x3865, 0x0000, 0x0000, 0x0000,
+ 0x3d79, 0x574d, 0x454c, 0x3d3e, 0x0000, 0x0000, 0x0000, 0x4640,
+ 0x5751, 0x5750, 0x0000, 0x0000, 0x0000, 0x0000, 0x574f, 0x0000,
+ 0x5752, 0x3866, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5753, 0x497c, 0x3d5b, 0x0000, 0x0000, 0x5754, 0x4879, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4641, 0x4427, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4530, 0x0000, 0x0000, 0x5755, 0x352b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3f34, 0x0000, 0x492c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3477, 0x4726, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5756, 0x3b56,
+ 0x4b3a, 0x4b3b, 0x0000, 0x0000, 0x317e, 0x575b, 0x0000, 0x0000,
+ 0x4369, 0x0000, 0x0000, 0x0000, 0x5758, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3277, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x582d, 0x575a, 0x0000, 0x0000, 0x0000, 0x4730, 0x0000, 0x0000,
+ 0x5759, 0x0000, 0x0000, 0x5757, 0x0000, 0x397a, 0x0000, 0x575d,
+};
+
+static unsigned short const tqunicode_to_jisx0208_60[] = {
+ /* 0x6000 - 0x60ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5763, 0x5769,
+ 0x5761, 0x0000, 0x455c, 0x0000, 0x0000, 0x5766, 0x495d, 0x0000,
+ 0x0000, 0x5760, 0x0000, 0x5765, 0x4e67, 0x3b57, 0x0000, 0x0000,
+ 0x4255, 0x575e, 0x0000, 0x0000, 0x0000, 0x355e, 0x5768, 0x402d,
+ 0x3165, 0x5762, 0x3278, 0x5767, 0x0000, 0x0000, 0x0000, 0x3631,
+ 0x0000, 0x5764, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x576a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x576c, 0x5776, 0x5774, 0x0000, 0x0000, 0x5771, 0x0000,
+ 0x0000, 0x0000, 0x5770, 0x4e78, 0x0000, 0x5772, 0x0000, 0x0000,
+ 0x3632, 0x0000, 0x3931, 0x0000, 0x0000, 0x3d7a, 0x0000, 0x0000,
+ 0x0000, 0x5779, 0x576b, 0x0000, 0x0000, 0x0000, 0x0000, 0x576f,
+ 0x575f, 0x0000, 0x327a, 0x5773, 0x5775, 0x4351, 0x0000, 0x0000,
+ 0x3a28, 0x3238, 0x576d, 0x5778, 0x5777, 0x3633, 0x0000, 0x4229,
+ 0x3366, 0x0000, 0x0000, 0x0000, 0x0000, 0x3743, 0x0000, 0x576e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x577a, 0x0000, 0x577d, 0x5821, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3c3d, 0x0000, 0x5827, 0x4470, 0x577b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5825, 0x0000, 0x3279, 0x0000, 0x5823, 0x5824,
+ 0x0000, 0x0000, 0x577e, 0x5822, 0x0000, 0x0000, 0x0000, 0x3867,
+ 0x4d2a, 0x0000, 0x0000, 0x3435, 0x0000, 0x0000, 0x3159, 0x5826,
+ 0x0000, 0x473a, 0x302d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4861, 0x575c, 0x582c, 0x5830, 0x4c65, 0x0000,
+ 0x5829, 0x0000, 0x0000, 0x0000, 0x4569, 0x582e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e70, 0x582f, 0x4657,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4f47, 0x0000, 0x582b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5831, 0x0000, 0x397b, 0x0000, 0x404b, 0x0000, 0x0000, 0x3054,
+ 0x582a, 0x5828, 0x0000, 0x415a, 0x0000, 0x0000, 0x0000, 0x577c,
+ 0x3b34, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4246, 0x583d, 0x0000, 0x415b, 0x5838, 0x0000, 0x5835, 0x5836,
+ 0x0000, 0x3c66, 0x5839, 0x583c, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_61[] = {
+ /* 0x6100 - 0x61ff */
+ 0x5837, 0x3d25, 0x0000, 0x583a, 0x0000, 0x0000, 0x5834, 0x0000,
+ 0x4c7c, 0x4c7b, 0x0000, 0x0000, 0x0000, 0x583e, 0x583f, 0x3055,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5833, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3672, 0x3026, 0x0000, 0x0000, 0x0000, 0x3436,
+ 0x0000, 0x583b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5843,
+ 0x5842, 0x0000, 0x0000, 0x0000, 0x5847, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5848, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5846, 0x5849, 0x5841, 0x5845,
+ 0x0000, 0x0000, 0x584a, 0x0000, 0x584b, 0x0000, 0x0000, 0x5840,
+ 0x3b7c, 0x0000, 0x5844, 0x4256, 0x3932, 0x5832, 0x3f35, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5858, 0x0000, 0x4a69, 0x0000, 0x0000,
+ 0x584e, 0x584f, 0x5850, 0x0000, 0x0000, 0x5857, 0x0000, 0x5856,
+ 0x0000, 0x0000, 0x4b7d, 0x3437, 0x0000, 0x5854, 0x0000, 0x3745,
+ 0x3334, 0x0000, 0x0000, 0x5851, 0x0000, 0x0000, 0x4e38, 0x5853,
+ 0x3056, 0x5855, 0x0000, 0x584c, 0x5852, 0x5859, 0x3744, 0x584d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d5d, 0x0000,
+ 0x0000, 0x0000, 0x4d2b, 0x0000, 0x0000, 0x0000, 0x0000, 0x585c,
+ 0x0000, 0x0000, 0x5860, 0x0000, 0x0000, 0x0000, 0x417e, 0x0000,
+ 0x4e79, 0x5861, 0x0000, 0x0000, 0x585e, 0x0000, 0x585b, 0x0000,
+ 0x0000, 0x585a, 0x585f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4a30, 0x0000, 0x0000, 0x4634,
+ 0x0000, 0x3746, 0x0000, 0x5862, 0x585d, 0x0000, 0x5863, 0x0000,
+ 0x0000, 0x0000, 0x377b, 0x0000, 0x0000, 0x0000, 0x3231, 0x0000,
+ 0x0000, 0x0000, 0x586b, 0x0000, 0x0000, 0x0000, 0x3438, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5869, 0x0000, 0x0000, 0x586a, 0x3a29,
+ 0x5868, 0x5866, 0x5865, 0x586c, 0x5864, 0x586e, 0x0000, 0x0000,
+ 0x327b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5870, 0x0000, 0x0000, 0x586f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4428, 0x0000, 0x5873, 0x0000, 0x5871, 0x5867,
+ 0x377c, 0x0000, 0x5872, 0x0000, 0x5876, 0x5875, 0x5877, 0x5874,
+};
+
+static unsigned short const tqunicode_to_jisx0208_62[] = {
+ /* 0x6200 - 0x62ff */
+ 0x5878, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5879, 0x587a, 0x4a6a, 0x0000, 0x587c, 0x587b, 0x3d3f, 0x0000,
+ 0x402e, 0x3266, 0x327c, 0x0000, 0x587d, 0x0000, 0x303f, 0x0000,
+ 0x0000, 0x0000, 0x404c, 0x587e, 0x0000, 0x6c43, 0x5921, 0x3761,
+ 0x0000, 0x5922, 0x0000, 0x0000, 0x0000, 0x0000, 0x406f, 0x0000,
+ 0x0000, 0x0000, 0x5923, 0x0000, 0x0000, 0x0000, 0x5924, 0x353a,
+ 0x5925, 0x0000, 0x5926, 0x5927, 0x4257, 0x0000, 0x0000, 0x0000,
+ 0x384d, 0x0000, 0x0000, 0x4c61, 0x0000, 0x0000, 0x0000, 0x4b3c,
+ 0x3d6a, 0x5928, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4070,
+ 0x6e3d, 0x4862, 0x0000, 0x3c6a, 0x0000, 0x3a4d, 0x5929, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4247, 0x0000, 0x4a27, 0x0000, 0x0000,
+ 0x4271, 0x0000, 0x0000, 0x592c, 0x0000, 0x0000, 0x592a, 0x0000,
+ 0x592d, 0x0000, 0x0000, 0x592b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x592e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a31, 0x0000,
+ 0x0000, 0x3037, 0x0000, 0x0000, 0x0000, 0x0000, 0x495e, 0x0000,
+ 0x0000, 0x4863, 0x0000, 0x0000, 0x592f, 0x0000, 0x5932, 0x3e35,
+ 0x353b, 0x0000, 0x5930, 0x5937, 0x3e36, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5931, 0x4744, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4d5e, 0x5933, 0x5934, 0x5938, 0x456a, 0x5935, 0x3933,
+ 0x405e, 0x0000, 0x0000, 0x5946, 0x4834, 0x0000, 0x4272, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4864, 0x5a2d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4a7a, 0x0000, 0x0000, 0x0000, 0x4471, 0x0000, 0x0000,
+ 0x0000, 0x4b75, 0x0000, 0x593b, 0x3221, 0x436a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5944, 0x0000, 0x0000, 0x4334, 0x593e, 0x5945,
+ 0x5940, 0x5947, 0x5943, 0x0000, 0x5942, 0x476f, 0x0000, 0x593c,
+ 0x327d, 0x593a, 0x3571, 0x4273, 0x5936, 0x0000, 0x0000, 0x5939,
+ 0x3934, 0x405b, 0x0000, 0x3e37, 0x5941, 0x4752, 0x0000, 0x0000,
+ 0x3572, 0x3348, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3367, 0x3f21, 0x5949, 0x594e,
+ 0x0000, 0x594a, 0x0000, 0x377d, 0x0000, 0x594f, 0x3b22, 0x3969,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d26, 0x593d,
+};
+
+static unsigned short const tqunicode_to_jisx0208_63[] = {
+ /* 0x6300 - 0x63ff */
+ 0x0000, 0x3b7d, 0x594c, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b58,
+ 0x594d, 0x3044, 0x0000, 0x0000, 0x5948, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4429, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3573, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3634,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x594b,
+ 0x3027, 0x0000, 0x0000, 0x3a43, 0x0000, 0x0000, 0x0000, 0x3f36,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4472, 0x0000, 0x0000, 0x4854, 0x5951, 0x415e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x422a, 0x0000, 0x0000, 0x3b2b, 0x5952, 0x0000, 0x5954,
+ 0x5950, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a61, 0x0000, 0x443d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x415c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a7b,
+ 0x3c4e, 0x5960, 0x0000, 0x595f, 0x0000, 0x0000, 0x3f78, 0x0000,
+ 0x0000, 0x0000, 0x377e, 0x0000, 0x0000, 0x0000, 0x5959, 0x3e39,
+ 0x0000, 0x0000, 0x4668, 0x4731, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5957, 0x0000, 0x0000, 0x415d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3c78, 0x595c, 0x0000, 0x0000, 0x3e38, 0x0000, 0x5956, 0x595b,
+ 0x0000, 0x0000, 0x4753, 0x0000, 0x0000, 0x0000, 0x5955, 0x0000,
+ 0x3721, 0x0000, 0x0000, 0x335d, 0x0000, 0x0000, 0x0000, 0x595d,
+ 0x4e2b, 0x3a4e, 0x4335, 0x595a, 0x0000, 0x405c, 0x0000, 0x3935,
+ 0x3f64, 0x3166, 0x413c, 0x5958, 0x3545, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3747, 0x0000, 0x444f, 0x595e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x415f, 0x0000, 0x0000, 0x5961, 0x0000,
+ 0x5963, 0x0000, 0x0000, 0x4237, 0x5969, 0x0000, 0x5964, 0x0000,
+ 0x0000, 0x5966, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4941,
+ 0x4473, 0x0000, 0x5967, 0x0000, 0x0000, 0x0000, 0x4d2c, 0x0000,
+ 0x0000, 0x0000, 0x4d48, 0x3439, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x302e, 0x0000, 0x5965, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5962, 0x0000, 0x0000, 0x0000, 0x0000, 0x3478, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3167, 0x0000, 0x5968, 0x0000,
+ 0x0000, 0x0000, 0x4d49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_64[] = {
+ /* 0x6400 - 0x64ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x596c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x423b, 0x0000, 0x5973,
+ 0x0000, 0x0000, 0x0000, 0x596d, 0x0000, 0x0000, 0x596a, 0x5971,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5953, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x596e, 0x0000,
+ 0x5972, 0x0000, 0x0000, 0x0000, 0x4842, 0x456b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x596b, 0x0000, 0x596f, 0x0000,
+ 0x0000, 0x0000, 0x3748, 0x0000, 0x0000, 0x0000, 0x3a71, 0x0000,
+ 0x0000, 0x0000, 0x405d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5977, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4526, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5974,
+ 0x0000, 0x4b60, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5975,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5976, 0x0000,
+ 0x4c4e, 0x0000, 0x4022, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3762, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x597d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3b35, 0x597a, 0x0000, 0x5979, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4732, 0x0000, 0x0000, 0x0000, 0x4635, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4531, 0x597b, 0x0000, 0x0000,
+ 0x0000, 0x597c, 0x0000, 0x496f, 0x0000, 0x4745, 0x3b23, 0x0000,
+ 0x4071, 0x0000, 0x4b50, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3349, 0x0000, 0x5a25, 0x597e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4d4a, 0x5a27, 0x0000, 0x0000, 0x5a23, 0x0000, 0x5a24,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4160, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5a22, 0x0000, 0x593f, 0x0000, 0x0000, 0x0000,
+ 0x5a26, 0x0000, 0x5a21, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5a2b, 0x5a2c, 0x4527, 0x5a2e, 0x0000, 0x0000, 0x3b24, 0x5a29,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x353c, 0x0000, 0x0000, 0x5a2f,
+ 0x0000, 0x5a28, 0x5a33, 0x0000, 0x5a32, 0x0000, 0x5a31, 0x0000,
+ 0x0000, 0x0000, 0x5a34, 0x0000, 0x0000, 0x5a36, 0x3e71, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_65[] = {
+ /* 0x6500 - 0x65ff */
+ 0x5a35, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a39, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5a37, 0x0000, 0x0000, 0x0000, 0x5a38, 0x5970, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5a3b, 0x5a3a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5978, 0x5a3c, 0x5a30, 0x0000, 0x0000, 0x3b59,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5a3d, 0x5a3e, 0x5a40, 0x5a3f,
+ 0x5a41, 0x327e, 0x0000, 0x3936, 0x0000, 0x0000, 0x4a7c, 0x402f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x384e, 0x0000, 0x0000,
+ 0x5a43, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a46, 0x0000, 0x4952,
+ 0x0000, 0x355f, 0x0000, 0x0000, 0x0000, 0x5a45, 0x5a44, 0x4754,
+ 0x5a47, 0x3635, 0x0000, 0x0000, 0x0000, 0x5a49, 0x5a48, 0x0000,
+ 0x0000, 0x0000, 0x343a, 0x3b36, 0x0000, 0x0000, 0x4658, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3749, 0x0000, 0x0000, 0x0000,
+ 0x3f74, 0x0000, 0x5a4a, 0x0000, 0x4030, 0x4528, 0x0000, 0x495f,
+ 0x5a4b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5a4c, 0x5a4d, 0x0000, 0x0000, 0x0000, 0x4a38,
+ 0x555d, 0x4046, 0x0000, 0x0000, 0x494c, 0x0000, 0x3a58, 0x0000,
+ 0x4865, 0x4843, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x454d,
+ 0x0000, 0x4e41, 0x0000, 0x5a4f, 0x3c50, 0x0000, 0x0000, 0x5a50,
+ 0x0000, 0x3036, 0x0000, 0x0000, 0x3654, 0x404d, 0x0000, 0x4960,
+ 0x0000, 0x0000, 0x0000, 0x5a51, 0x3b42, 0x4347, 0x0000, 0x3b5b,
+ 0x3f37, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a52,
+ 0x0000, 0x4a7d, 0x0000, 0x0000, 0x3177, 0x3b5c, 0x0000, 0x0000,
+ 0x0000, 0x5a55, 0x0000, 0x5a53, 0x5a56, 0x4e39, 0x5a54, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x407b, 0x5a57, 0x0000, 0x0000, 0x4232,
+ 0x0000, 0x0000, 0x5a58, 0x0000, 0x0000, 0x0000, 0x0000, 0x347a,
+ 0x0000, 0x5a5a, 0x0000, 0x5a59, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5a5b, 0x5a5c, 0x347b, 0x0000, 0x0000, 0x467c, 0x4336, 0x356c,
+ 0x3b5d, 0x4161, 0x0000, 0x0000, 0x3d5c, 0x3030, 0x0000, 0x0000,
+ 0x0000, 0x5a5d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3222, 0x5a61, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_66[] = {
+ /* 0x6600 - 0x66ff */
+ 0x0000, 0x0000, 0x3937, 0x5a60, 0x0000, 0x0000, 0x3a2b, 0x3e3a,
+ 0x0000, 0x0000, 0x5a5f, 0x0000, 0x3e3b, 0x0000, 0x4c40, 0x3a2a,
+ 0x0000, 0x0000, 0x0000, 0x3057, 0x404e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5a66, 0x0000, 0x0000, 0x4031,
+ 0x3147, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d55, 0x0000, 0x4b66,
+ 0x3a72, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e3c, 0x0000, 0x4027,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5a65, 0x5a63, 0x5a64, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x436b, 0x0000, 0x0000, 0x5b26,
+ 0x0000, 0x5a6a, 0x3b7e, 0x3938, 0x5a68, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5a69, 0x0000, 0x3f38, 0x0000, 0x0000, 0x0000, 0x5a67,
+ 0x0000, 0x0000, 0x3b2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a6c, 0x5a6b, 0x5a70,
+ 0x0000, 0x0000, 0x5a71, 0x0000, 0x5a6d, 0x0000, 0x3322, 0x5a6e,
+ 0x5a6f, 0x4855, 0x0000, 0x0000, 0x0000, 0x0000, 0x4961, 0x374a,
+ 0x5a72, 0x0000, 0x0000, 0x0000, 0x4032, 0x0000, 0x3e3d, 0x0000,
+ 0x0000, 0x0000, 0x4352, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3647, 0x0000, 0x5a73, 0x5a77, 0x0000, 0x0000, 0x324b,
+ 0x5a74, 0x5a76, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a75, 0x0000,
+ 0x0000, 0x3d6b, 0x0000, 0x0000, 0x0000, 0x0000, 0x4348, 0x3045,
+ 0x5a78, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a79, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x442a, 0x0000, 0x0000, 0x0000, 0x4e71, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3b43, 0x0000, 0x0000, 0x4a6b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4b3d, 0x0000, 0x0000, 0x0000,
+ 0x5b22, 0x5a7b, 0x0000, 0x0000, 0x5a7e, 0x0000, 0x5a7d, 0x0000,
+ 0x0000, 0x5a7a, 0x0000, 0x0000, 0x5b21, 0x0000, 0x0000, 0x465e,
+ 0x0000, 0x5a7c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b23, 0x0000,
+ 0x0000, 0x3d6c, 0x5b24, 0x0000, 0x4d4b, 0x4778, 0x0000, 0x0000,
+ 0x5b25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b27, 0x0000,
+ 0x0000, 0x5b28, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5b29, 0x0000, 0x364a, 0x3148, 0x3939, 0x5b2a, 0x0000, 0x5b2b,
+ 0x3d71, 0x4162, 0x0000, 0x0000, 0x5258, 0x413e, 0x413d, 0x4258,
+};
+
+static unsigned short const tqunicode_to_jisx0208_67[] = {
+ /* 0x6700 - 0x67ff */
+ 0x3a47, 0x0000, 0x0000, 0x5072, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x376e, 0x4d2d, 0x0000, 0x4a7e, 0x0000, 0x497e, 0x0000, 0x5b2c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3a73, 0x443f, 0x5b2d, 0x4f2f,
+ 0x0000, 0x0000, 0x0000, 0x4b3e, 0x0000, 0x442b, 0x5b2e, 0x347c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b2f, 0x5b30,
+ 0x4c5a, 0x0000, 0x4c24, 0x4b76, 0x4b5c, 0x3b25, 0x5b32, 0x0000,
+ 0x0000, 0x3c6b, 0x0000, 0x0000, 0x4b51, 0x0000, 0x5b34, 0x5b37,
+ 0x5b36, 0x0000, 0x3479, 0x0000, 0x0000, 0x3560, 0x0000, 0x5b33,
+ 0x0000, 0x5b35, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b38, 0x0000,
+ 0x0000, 0x3f79, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d7b, 0x3049,
+ 0x3a60, 0x423c, 0x0000, 0x3c5d, 0x0000, 0x0000, 0x3e73, 0x0000,
+ 0x0000, 0x5b3b, 0x0000, 0x0000, 0x454e, 0x0000, 0x5b39, 0x422b,
+ 0x5b3a, 0x3e72, 0x4c5d, 0x5b3c, 0x5b3d, 0x4d68, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5b42, 0x0000, 0x0000, 0x393a, 0x0000, 0x4755,
+ 0x5b3f, 0x456c, 0x5a5e, 0x5a62, 0x0000, 0x354f, 0x0000, 0x4747,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5b41, 0x0000, 0x3e3e, 0x4844,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b47, 0x0000, 0x487a,
+ 0x0000, 0x5b3e, 0x0000, 0x5b44, 0x5b43, 0x0000, 0x0000, 0x0000,
+ 0x404f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b6d, 0x0000, 0x4e53,
+ 0x0000, 0x0000, 0x4b67, 0x0000, 0x324c, 0x3b5e, 0x0000, 0x0000,
+ 0x4f48, 0x5b46, 0x3f75, 0x0000, 0x0000, 0x0000, 0x5b45, 0x0000,
+ 0x0000, 0x5b40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x384f,
+ 0x0000, 0x0000, 0x0000, 0x5b4c, 0x5b4a, 0x0000, 0x324d, 0x5b48,
+ 0x5b4e, 0x5b54, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4248, 0x0000, 0x0000, 0x4a41, 0x0000, 0x5b56, 0x0000,
+ 0x0000, 0x0000, 0x4922, 0x0000, 0x0000, 0x0000, 0x5b55, 0x4770,
+ 0x4b3f, 0x343b, 0x0000, 0x4077, 0x3d40, 0x0000, 0x0000, 0x0000,
+ 0x4453, 0x0000, 0x4d2e, 0x0000, 0x0000, 0x5b51, 0x5b50, 0x0000,
+ 0x0000, 0x0000, 0x5b52, 0x0000, 0x5b4f, 0x0000, 0x0000, 0x5b57,
+ 0x0000, 0x5b4d, 0x0000, 0x0000, 0x5b4b, 0x0000, 0x5b53, 0x5b49,
+ 0x0000, 0x436c, 0x0000, 0x4c78, 0x3c46, 0x3a74, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3a3a, 0x0000, 0x0000, 0x4b6f, 0x3341,
+};
+
+static unsigned short const tqunicode_to_jisx0208_68[] = {
+ /* 0x6800 - 0x68ff */
+ 0x0000, 0x0000, 0x444e, 0x464a, 0x3149, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4072, 0x0000, 0x0000, 0x4034, 0x372a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b59, 0x0000,
+ 0x0000, 0x393b, 0x337c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5b5b, 0x3374, 0x5b61, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5b5e, 0x0000, 0x4073, 0x0000, 0x0000, 0x0000,
+ 0x334b, 0x3a2c, 0x0000, 0x0000, 0x334a, 0x3a4f, 0x0000, 0x0000,
+ 0x5b5c, 0x3765, 0x374b, 0x456d, 0x0000, 0x0000, 0x5b5a, 0x0000,
+ 0x3046, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b5d, 0x5b5f, 0x0000,
+ 0x364d, 0x372c, 0x0000, 0x343c, 0x354b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5b62, 0x0000, 0x0000, 0x3a79, 0x4b71, 0x0000, 0x3b37,
+ 0x0000, 0x0000, 0x0000, 0x5b63, 0x0000, 0x0000, 0x0000, 0x4930,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5b6f, 0x0000, 0x3233, 0x5b64,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b75, 0x5b65,
+ 0x0000, 0x4e42, 0x0000, 0x5b6c, 0x0000, 0x475f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b74, 0x0000, 0x5b67,
+ 0x0000, 0x0000, 0x0000, 0x3034, 0x5b69, 0x0000, 0x0000, 0x393c,
+ 0x0000, 0x0000, 0x0000, 0x5b6b, 0x0000, 0x5b6a, 0x0000, 0x5b66,
+ 0x5b71, 0x0000, 0x3e3f, 0x0000, 0x0000, 0x0000, 0x546d, 0x3868,
+ 0x4d7c, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b68, 0x0000, 0x4474,
+ 0x3323, 0x3a2d, 0x0000, 0x5b60, 0x0000, 0x5b70, 0x3361, 0x0000,
+ 0x0000, 0x5b6e, 0x5b72, 0x0000, 0x456e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x347e, 0x0000, 0x5c32, 0x0000,
+ 0x0000, 0x4c49, 0x5b77, 0x347d, 0x0000, 0x5b7e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4b40, 0x0000, 0x5c21, 0x5c23, 0x0000, 0x5c27,
+ 0x5b79, 0x0000, 0x432a, 0x0000, 0x0000, 0x0000, 0x0000, 0x456f,
+ 0x5c2b, 0x5b7c, 0x0000, 0x5c28, 0x0000, 0x0000, 0x0000, 0x5c22,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f39, 0x5c2c,
+ 0x0000, 0x0000, 0x4033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5c2a, 0x343d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_69[] = {
+ /* 0x6900 - 0x69ff */
+ 0x4f50, 0x5b76, 0x0000, 0x0000, 0x5c26, 0x3058, 0x0000, 0x0000,
+ 0x5b78, 0x0000, 0x0000, 0x4c3a, 0x5b7d, 0x3f22, 0x4447, 0x5b73,
+ 0x0000, 0x0000, 0x5c25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3f7a, 0x5c2f, 0x3371, 0x3821, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5c31, 0x5b7a, 0x5c30, 0x0000, 0x5c29, 0x5b7b, 0x0000,
+ 0x5c2d, 0x0000, 0x5c2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5c3f, 0x0000, 0x0000, 0x0000, 0x464e, 0x0000, 0x5c24, 0x0000,
+ 0x0000, 0x5c3b, 0x0000, 0x0000, 0x0000, 0x5c3d, 0x0000, 0x4458,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4d4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4976, 0x5c38, 0x424a, 0x0000, 0x0000,
+ 0x0000, 0x5c3e, 0x413f, 0x0000, 0x5c35, 0x5c42, 0x5c41, 0x0000,
+ 0x466f, 0x5c40, 0x466a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5c44, 0x5c37, 0x0000, 0x3648, 0x5c3a, 0x3d5d,
+ 0x0000, 0x0000, 0x0000, 0x4760, 0x5c3c, 0x364b, 0x0000, 0x5c34,
+ 0x5c36, 0x5c33, 0x0000, 0x0000, 0x4f30, 0x335a, 0x5c39, 0x0000,
+ 0x0000, 0x5c43, 0x3335, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3a67, 0x0000, 0x0000, 0x0000, 0x315d, 0x0000,
+ 0x0000, 0x5c54, 0x0000, 0x0000, 0x4f31, 0x5c57, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3f3a, 0x5c56, 0x0000, 0x0000, 0x0000,
+ 0x5c55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c52,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c46, 0x0000,
+ 0x0000, 0x5c63, 0x5c45, 0x0000, 0x5c58, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5c50, 0x0000, 0x0000, 0x5c4b, 0x5c48,
+ 0x0000, 0x5c49, 0x0000, 0x5c51, 0x0000, 0x0000, 0x0000, 0x7422,
+ 0x0000, 0x0000, 0x5c4e, 0x393d, 0x4448, 0x4164, 0x5c4c, 0x0000,
+ 0x5c47, 0x0000, 0x0000, 0x5c4a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4d4d, 0x4b6a, 0x0000, 0x0000, 0x0000, 0x5c4f, 0x5c59, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c61,
+ 0x5c5a, 0x0000, 0x0000, 0x5c67, 0x0000, 0x5c65, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5c60, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5c5f, 0x0000, 0x4450, 0x0000, 0x4165, 0x0000, 0x5c5d,
+};
+
+static unsigned short const tqunicode_to_jisx0208_6a[] = {
+ /* 0x6a00 - 0x6aff */
+ 0x0000, 0x0000, 0x5c5b, 0x0000, 0x0000, 0x5c62, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5c68, 0x4875, 0x5c6e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5c69, 0x5c6c, 0x5c66, 0x0000, 0x0000, 0x4374,
+ 0x0000, 0x4938, 0x0000, 0x5c5c, 0x0000, 0x0000, 0x5c64, 0x3e40,
+ 0x0000, 0x4c4f, 0x5c78, 0x5c6b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3822, 0x3223, 0x335f, 0x0000, 0x0000, 0x5c53, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e41, 0x5c70, 0x0000,
+ 0x5c77, 0x3c79, 0x3372, 0x0000, 0x0000, 0x432e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5c6d, 0x0000, 0x0000, 0x5c72,
+ 0x5c76, 0x0000, 0x0000, 0x3636, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x354c, 0x5c74, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3521,
+ 0x0000, 0x464b, 0x5c73, 0x0000, 0x0000, 0x0000, 0x5c75, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5c6f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5c71, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3360,
+ 0x4349, 0x0000, 0x0000, 0x0000, 0x5c7c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c7a, 0x3869, 0x0000,
+ 0x5c79, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d21,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5b58, 0x0000, 0x0000, 0x0000,
+ 0x5c7b, 0x0000, 0x5c7d, 0x5c7e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5d2c, 0x0000, 0x5d28, 0x0000, 0x5b6d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5d27, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5d26, 0x0000, 0x0000, 0x5d23, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5c6a, 0x5d25, 0x5d24, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5d2a, 0x0000, 0x4f26, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5d2d, 0x367b, 0x0000, 0x0000, 0x5d29, 0x5d2b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4827, 0x0000, 0x5d2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5d32, 0x5d2f, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_6b[] = {
+ /* 0x6b00 - 0x6bff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4d73, 0x5d30, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5c5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5d33, 0x0000, 0x0000, 0x0000, 0x5d34, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3135, 0x0000, 0x5d36,
+ 0x3767, 0x3c21, 0x0000, 0x3655, 0x0000, 0x0000, 0x0000, 0x3224,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4d5f, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d38,
+ 0x5d37, 0x5d3a, 0x353d, 0x0000, 0x0000, 0x3656, 0x343e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5d3d, 0x0000, 0x0000, 0x0000, 0x5d3c,
+ 0x0000, 0x5d3e, 0x0000, 0x0000, 0x324e, 0x0000, 0x4337, 0x0000,
+ 0x5d3f, 0x0000, 0x0000, 0x343f, 0x5d41, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5d40, 0x0000, 0x5d42, 0x0000, 0x0000, 0x0000, 0x5d43,
+ 0x0000, 0x5d44, 0x3b5f, 0x4035, 0x3a21, 0x0000, 0x4970, 0x0000,
+ 0x0000, 0x4a62, 0x4f44, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b75,
+ 0x0000, 0x0000, 0x0000, 0x3a50, 0x4e72, 0x0000, 0x0000, 0x0000,
+ 0x5d45, 0x5d46, 0x0000, 0x3b60, 0x0000, 0x0000, 0x0000, 0x5d47,
+ 0x5d48, 0x0000, 0x0000, 0x5d4a, 0x5d49, 0x0000, 0x4b58, 0x0000,
+ 0x0000, 0x3d5e, 0x3c6c, 0x3b44, 0x0000, 0x5d4b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d4d, 0x3f23, 0x0000,
+ 0x5d4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d4e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5d4f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5d50, 0x5d51, 0x0000, 0x0000, 0x0000, 0x5d52,
+ 0x0000, 0x5d54, 0x5d53, 0x5d55, 0x3225, 0x434a, 0x0000, 0x5d56,
+ 0x0000, 0x0000, 0x3b26, 0x334c, 0x5d57, 0x0000, 0x0000, 0x4542,
+ 0x544c, 0x0000, 0x0000, 0x0000, 0x0000, 0x3523, 0x5d58, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5d59, 0x0000, 0x4a6c, 0x4b68, 0x0000,
+ 0x0000, 0x0000, 0x4647, 0x5d5a, 0x4866, 0x0000, 0x0000, 0x0000,
+ 0x487b, 0x0000, 0x0000, 0x4c53, 0x0000, 0x0000, 0x0000, 0x5d5b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5d5d, 0x5d5c, 0x0000, 0x0000, 0x5d5f,
+ 0x0000, 0x0000, 0x0000, 0x5d5e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_6c[] = {
+ /* 0x6c00 - 0x6cff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5d61, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b61,
+ 0x0000, 0x4c31, 0x0000, 0x5d62, 0x5d63, 0x0000, 0x0000, 0x3524,
+ 0x0000, 0x0000, 0x0000, 0x5d64, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5d66, 0x5d65, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3f65, 0x0000, 0x0000, 0x4939,
+ 0x314a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4845, 0x0000,
+ 0x4475, 0x3d41, 0x3561, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4846, 0x0000,
+ 0x3c2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d68, 0x0000, 0x3440,
+ 0x0000, 0x0000, 0x3178, 0x0000, 0x0000, 0x4672, 0x5d67, 0x393e,
+ 0x4353, 0x0000, 0x5d69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5d71, 0x0000, 0x5d6a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4241, 0x0000, 0x3562, 0x5d72, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3768, 0x0000, 0x0000, 0x3525, 0x5d70, 0x0000,
+ 0x0000, 0x5d6e, 0x5d6b, 0x4d60, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4440, 0x0000, 0x0000, 0x0000, 0x4659, 0x5d6c, 0x0000, 0x0000,
+ 0x5d74, 0x0000, 0x5d73, 0x3723, 0x0000, 0x0000, 0x322d, 0x0000,
+ 0x0000, 0x3a3b, 0x5d6d, 0x5d6f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4b57, 0x4274, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4b77, 0x0000, 0x0000, 0x5d7c, 0x0000,
+ 0x0000, 0x5d7d, 0x0000, 0x324f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4a28, 0x4c7d, 0x5e21, 0x3c23, 0x3e42, 0x5d78, 0x5d7e, 0x3168,
+ 0x0000, 0x3637, 0x0000, 0x0000, 0x5d75, 0x5d7a, 0x0000, 0x0000,
+ 0x0000, 0x4074, 0x4771, 0x0000, 0x4867, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5d77, 0x0000, 0x4b21, 0x0000, 0x5d79,
+ 0x0000, 0x5e24, 0x0000, 0x5e22, 0x0000, 0x5d7b, 0x0000, 0x0000,
+ 0x0000, 0x4b22, 0x4748, 0x3563, 0x0000, 0x4525, 0x0000, 0x0000,
+ 0x436d, 0x0000, 0x5e25, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e23,
+ 0x4259, 0x5d76, 0x0000, 0x314b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_6d[] = {
+ /* 0x6d00 - 0x6dff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4d4e, 0x5e30, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5e2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4076,
+ 0x0000, 0x5e2c, 0x0000, 0x4d6c, 0x0000, 0x0000, 0x4636, 0x5e26,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4445, 0x0000, 0x0000,
+ 0x0000, 0x314c, 0x393f, 0x5e29, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3d27, 0x5e2e, 0x0000, 0x5e2d, 0x5e28, 0x0000,
+ 0x5e2b, 0x0000, 0x0000, 0x3368, 0x0000, 0x5e2a, 0x4749, 0x0000,
+ 0x0000, 0x4e2e, 0x0000, 0x0000, 0x3e74, 0x4075, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5e36, 0x5e34, 0x0000, 0x494d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5e31, 0x5e33, 0x0000, 0x313a, 0x0000,
+ 0x0000, 0x3940, 0x4f32, 0x0000, 0x333d, 0x0000, 0x4962, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4d61, 0x0000, 0x0000, 0x3324,
+ 0x3f3b, 0x5e35, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e3a, 0x0000, 0x0000,
+ 0x3e43, 0x0000, 0x0000, 0x0000, 0x4d30, 0x0000, 0x5e37, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5e32, 0x0000, 0x5e38, 0x0000, 0x0000,
+ 0x0000, 0x4e5e, 0x0000, 0x4573, 0x4642, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3336,
+ 0x0000, 0x0000, 0x3155, 0x0000, 0x0000, 0x5e3e, 0x0000, 0x0000,
+ 0x5e41, 0x0000, 0x0000, 0x0000, 0x4e43, 0x0000, 0x0000, 0x0000,
+ 0x4d64, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e48, 0x5e42, 0x5e3f,
+ 0x0000, 0x0000, 0x0000, 0x4e54, 0x5e45, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3d4a, 0x5e47, 0x0000, 0x0000, 0x5e4c, 0x0000, 0x0000,
+ 0x4571, 0x5e4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e44, 0x0000,
+ 0x0000, 0x4338, 0x0000, 0x0000, 0x5e4b, 0x0000, 0x5e40, 0x0000,
+ 0x5e46, 0x0000, 0x5e4d, 0x307c, 0x5e43, 0x0000, 0x5e4e, 0x0000,
+ 0x0000, 0x3f3c, 0x0000, 0x3d5f, 0x0000, 0x4a25, 0x0000, 0x3a2e,
+ 0x0000, 0x5e3b, 0x5e49, 0x453a, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_6e[] = {
+ /* 0x6e00 - 0x6eff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4036, 0x0000, 0x3369,
+ 0x3a51, 0x3e44, 0x5e3d, 0x3d42, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x374c, 0x0000, 0x5e3c, 0x0000, 0x0000,
+ 0x0000, 0x5e52, 0x3d6d, 0x383a, 0x0000, 0x5e61, 0x0000, 0x5e5b,
+ 0x3574, 0x454f, 0x0000, 0x5e56, 0x5e5f, 0x302f, 0x3132, 0x0000,
+ 0x0000, 0x3239, 0x0000, 0x5e58, 0x422c, 0x5e4f, 0x5e51, 0x3941,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5e62, 0x0000, 0x5e5d, 0x0000, 0x0000, 0x0000, 0x5e55, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5e5c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4c2b, 0x0000, 0x0000, 0x5e5a, 0x5e5e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3850, 0x0000,
+ 0x3e45, 0x0000, 0x0000, 0x4339, 0x0000, 0x0000, 0x0000, 0x5e54,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d2f,
+ 0x0000, 0x0000, 0x0000, 0x5e57, 0x0000, 0x0000, 0x5e50, 0x4572,
+ 0x0000, 0x0000, 0x5e53, 0x0000, 0x0000, 0x0000, 0x5e59, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f51, 0x3c3e,
+ 0x4b7e, 0x0000, 0x5e63, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x482e, 0x0000, 0x0000, 0x5e6f,
+ 0x383b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d60, 0x0000,
+ 0x5e65, 0x0000, 0x0000, 0x0000, 0x4e2f, 0x3942, 0x0000, 0x5e72,
+ 0x0000, 0x0000, 0x306e, 0x0000, 0x0000, 0x5e70, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5e64, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e6a,
+ 0x0000, 0x0000, 0x5e6c, 0x0000, 0x0000, 0x0000, 0x4d4f, 0x5e67,
+ 0x0000, 0x0000, 0x452e, 0x0000, 0x0000, 0x5e69, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5e71, 0x0000, 0x5e6b, 0x4c47, 0x0000, 0x0000,
+ 0x0000, 0x5e66, 0x0000, 0x3c22, 0x5e7e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x336a, 0x0000, 0x5e68, 0x5e6d, 0x5e6e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x426c, 0x425a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5e76, 0x0000, 0x0000, 0x5e7c,
+ 0x0000, 0x0000, 0x5e7a, 0x0000, 0x4529, 0x0000, 0x0000, 0x5f23,
+ 0x5e77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e78, 0x5e60,
+};
+
+static unsigned short const tqunicode_to_jisx0208_6f[] = {
+ /* 0x6f00 - 0x6fff */
+ 0x0000, 0x3579, 0x493a, 0x0000, 0x0000, 0x0000, 0x3c3f, 0x0000,
+ 0x0000, 0x3977, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f33,
+ 0x0000, 0x5e74, 0x0000, 0x5f22, 0x3169, 0x4166, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4779, 0x0000, 0x3441, 0x4e7a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4c21, 0x4452, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5e7b, 0x5e7d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4132, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f21, 0x5e79,
+ 0x0000, 0x5e73, 0x0000, 0x0000, 0x0000, 0x3443, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3769, 0x0000, 0x0000, 0x0000,
+ 0x5f2f, 0x0000, 0x0000, 0x5f2a, 0x4078, 0x0000, 0x0000, 0x3363,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3d61, 0x0000, 0x5f33, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f2c, 0x442c, 0x5f29,
+ 0x4459, 0x0000, 0x0000, 0x0000, 0x5f4c, 0x0000, 0x0000, 0x0000,
+ 0x5f26, 0x0000, 0x5f25, 0x0000, 0x5f2e, 0x0000, 0x0000, 0x0000,
+ 0x5f28, 0x5f27, 0x5f2d, 0x0000, 0x4021, 0x0000, 0x5f24, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f30, 0x0000,
+ 0x0000, 0x5f31, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3442,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f36, 0x0000, 0x5f35, 0x5f37, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5f3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4543, 0x0000, 0x5f34, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3763, 0x4279, 0x5f32, 0x473b, 0x0000, 0x0000, 0x5f39, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5f3e, 0x5f3c, 0x0000, 0x0000,
+ 0x5f3f, 0x0000, 0x0000, 0x5f42, 0x0000, 0x0000, 0x0000, 0x5f3b,
+ 0x396a, 0x4728, 0x0000, 0x0000, 0x5e39, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4d74, 0x5f3d, 0x0000, 0x5f41, 0x4275,
+ 0x0000, 0x5f40, 0x0000, 0x5f2b, 0x0000, 0x0000, 0x6f69, 0x0000,
+ 0x0000, 0x0000, 0x5f45, 0x0000, 0x0000, 0x0000, 0x5f49, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_70[] = {
+ /* 0x7000 - 0x70ff */
+ 0x0000, 0x5f47, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f43, 0x0000, 0x5f44, 0x0000, 0x0000, 0x0000, 0x5f48,
+ 0x0000, 0x5f46, 0x0000, 0x0000, 0x0000, 0x494e, 0x0000, 0x0000,
+ 0x5f4e, 0x0000, 0x5f4b, 0x5f4a, 0x0000, 0x5f4d, 0x4654, 0x5f4f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4375, 0x426d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4025, 0x0000, 0x0000, 0x0000,
+ 0x5f50, 0x0000, 0x5f52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f51, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5e75, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f53, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4667, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5f54, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3250, 0x0000, 0x0000, 0x0000, 0x4574,
+ 0x3325, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3564, 0x0000, 0x0000, 0x0000, 0x3c5e, 0x3a52, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4f27, 0x3f66, 0x0000, 0x0000, 0x0000, 0x316a, 0x0000,
+ 0x0000, 0x0000, 0x5f56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5f59, 0x433a, 0x5f5c, 0x5f57,
+ 0x0000, 0x0000, 0x0000, 0x5f5b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5f5a, 0x4540, 0x3059, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4e75, 0x0000, 0x0000, 0x5f5e, 0x0000, 0x0000, 0x0000, 0x3128,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f60, 0x0000, 0x0000, 0x0000, 0x5f5f, 0x0000, 0x5f5d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f58, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4b23, 0x0000, 0x0000, 0x0000, 0x5f62, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_71[] = {
+ /* 0x7100 - 0x71ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f61, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x316b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f64, 0x4a32, 0x0000, 0x5f63, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4c35, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e47, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4133, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3e46, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4e7b, 0x0000, 0x0000, 0x5f6a, 0x0000, 0x4079, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f66, 0x5f6b, 0x0000,
+ 0x0000, 0x316c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5f69, 0x0000, 0x4761, 0x5f65, 0x5f68, 0x3e48,
+ 0x0000, 0x4851, 0x0000, 0x0000, 0x5f6c, 0x0000, 0x3c51, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x407a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5f6f, 0x0000, 0x0000, 0x0000,
+ 0x5f67, 0x0000, 0x3727, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f6d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4d50, 0x5f70, 0x0000, 0x0000,
+ 0x0000, 0x7426, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d4f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5f71, 0x0000, 0x0000, 0x0000, 0x5f72, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x472e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f74, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f75, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4733, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4575, 0x5f77, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f79, 0x0000,
+ 0x4e55, 0x0000, 0x5f76, 0x0000, 0x5f78, 0x316d, 0x0000, 0x5f73,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x535b,
+ 0x5f7a, 0x0000, 0x0000, 0x0000, 0x0000, 0x4167, 0x3b38, 0x5f7c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5f7b, 0x3f24, 0x5259, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f7d, 0x0000, 0x0000,
+ 0x0000, 0x6021, 0x0000, 0x5f6e, 0x5f7e, 0x0000, 0x0000, 0x6022,
+};
+
+static unsigned short const tqunicode_to_jisx0208_72[] = {
+ /* 0x7200 - 0x72ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x477a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6023, 0x0000, 0x0000,
+ 0x6024, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6025, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6026, 0x0000, 0x445e, 0x0000, 0x6028, 0x6027, 0x0000, 0x0000,
+ 0x6029, 0x0000, 0x602a, 0x0000, 0x0000, 0x3c5f, 0x4963, 0x0000,
+ 0x0000, 0x0000, 0x4c6c, 0x602b, 0x602c, 0x4156, 0x3c24, 0x602d,
+ 0x602e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x602f, 0x4a52,
+ 0x4847, 0x0000, 0x0000, 0x6030, 0x4757, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x442d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6031, 0x3267, 0x0000, 0x356d, 0x0000, 0x4c46, 0x0000, 0x4c36,
+ 0x0000, 0x3234, 0x4f34, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b52,
+ 0x0000, 0x4a2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4037, 0x0000, 0x6032, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4643, 0x0000, 0x0000, 0x0000, 0x3823, 0x6033, 0x0000,
+ 0x3a54, 0x6035, 0x6034, 0x0000, 0x0000, 0x0000, 0x0000, 0x6036,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6037, 0x0000, 0x0000, 0x0000, 0x6038, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x353e, 0x0000, 0x6039, 0x0000, 0x0000, 0x0000, 0x0000, 0x603a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3824, 0x0000, 0x0000, 0x4848,
+ 0x0000, 0x0000, 0x603c, 0x0000, 0x0000, 0x0000, 0x3e75, 0x0000,
+ 0x0000, 0x603b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3638, 0x603d, 0x603f, 0x0000, 0x603e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6040, 0x0000,
+ 0x3851, 0x0000, 0x6041, 0x0000, 0x0000, 0x0000, 0x0000, 0x3669,
+ 0x0000, 0x4140, 0x0000, 0x397d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6043, 0x6044, 0x6042, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3c6d, 0x0000, 0x0000, 0x4648, 0x3639, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6046,
+ 0x432c, 0x6045, 0x0000, 0x0000, 0x4f35, 0x4762, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_73[] = {
+ /* 0x7300 - 0x73ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x604b, 0x6048,
+ 0x0000, 0x0000, 0x0000, 0x4c54, 0x604a, 0x604c, 0x0000, 0x4e44,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6050, 0x0000, 0x0000,
+ 0x0000, 0x604f, 0x4376, 0x472d, 0x0000, 0x0000, 0x3825, 0x604e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x604d, 0x0000, 0x4d31, 0x4d32,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6051, 0x316e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3976, 0x3b62, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6052, 0x6053,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6055,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3d43, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6057, 0x0000, 0x6056, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6058, 0x0000, 0x334d, 0x0000, 0x0000, 0x605a, 0x0000, 0x0000,
+ 0x6059, 0x0000, 0x605c, 0x605b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x383c, 0x0000, 0x0000, 0x4e28,
+ 0x0000, 0x364c, 0x0000, 0x3226, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x366a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3461, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4e68, 0x605e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6060, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6061, 0x0000, 0x3251, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x605d, 0x0000, 0x3b39, 0x0000, 0x0000, 0x4441, 0x605f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6064, 0x0000,
+ 0x3c6e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6062, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x373e, 0x0000, 0x0000, 0x4849, 0x6063, 0x0000,
+ 0x0000, 0x607e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6069, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x383d, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_74[] = {
+ /* 0x7400 - 0x74ff */
+ 0x0000, 0x0000, 0x0000, 0x3565, 0x0000, 0x6066, 0x4d7d, 0x0000,
+ 0x0000, 0x4e30, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4276, 0x0000, 0x0000, 0x6068, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x606a, 0x4e56, 0x3657, 0x487c, 0x474a, 0x0000,
+ 0x0000, 0x0000, 0x606b, 0x0000, 0x0000, 0x0000, 0x0000, 0x606d,
+ 0x0000, 0x6070, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x606c, 0x0000, 0x0000,
+ 0x0000, 0x606f, 0x386a, 0x314d, 0x6071, 0x0000, 0x3f70, 0x606e,
+ 0x4e5c, 0x0000, 0x0000, 0x6074, 0x7424, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6072, 0x6075, 0x0000, 0x0000, 0x0000, 0x0000, 0x6067,
+ 0x6073, 0x0000, 0x0000, 0x3a3c, 0x0000, 0x0000, 0x6076, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6077, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4d7e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6078, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6079, 0x0000,
+ 0x0000, 0x0000, 0x6065, 0x0000, 0x0000, 0x0000, 0x0000, 0x607a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3444, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c25, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x607b, 0x0000, 0x0000, 0x0000, 0x0000, 0x607c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x607d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x313b, 0x0000, 0x0000, 0x0000,
+ 0x6121, 0x0000, 0x493b, 0x6122, 0x0000, 0x0000, 0x3424, 0x6123,
+ 0x0000, 0x6124, 0x0000, 0x0000, 0x0000, 0x0000, 0x6125, 0x0000,
+ 0x6127, 0x6128, 0x6126, 0x0000, 0x0000, 0x0000, 0x4953, 0x612a,
+ 0x6129, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_75[] = {
+ /* 0x7500 - 0x75ff */
+ 0x0000, 0x0000, 0x0000, 0x612c, 0x612b, 0x612d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x612e, 0x6130, 0x612f, 0x0000,
+ 0x0000, 0x3979, 0x0000, 0x6132, 0x0000, 0x6131, 0x0000, 0x0000,
+ 0x3445, 0x0000, 0x3f53, 0x0000, 0x453c, 0x0000, 0x6133, 0x4038,
+ 0x0000, 0x0000, 0x0000, 0x3b3a, 0x0000, 0x3179, 0x6134, 0x0000,
+ 0x4d51, 0x0000, 0x0000, 0x4a63, 0x6135, 0x0000, 0x0000, 0x0000,
+ 0x4544, 0x4d33, 0x3943, 0x3f3d, 0x0000, 0x0000, 0x0000, 0x434b,
+ 0x5234, 0x0000, 0x442e, 0x3268, 0x6136, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6137, 0x0000, 0x613c, 0x0000,
+ 0x0000, 0x613a, 0x6139, 0x5a42, 0x3326, 0x6138, 0x0000, 0x305a,
+ 0x0000, 0x482a, 0x0000, 0x0000, 0x484a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4e31, 0x613d, 0x613b, 0x435c, 0x4026, 0x0000, 0x0000,
+ 0x482b, 0x0000, 0x492d, 0x0000, 0x613f, 0x4e2c, 0x374d, 0x6140,
+ 0x0000, 0x613e, 0x4856, 0x6141, 0x0000, 0x6142, 0x0000, 0x0000,
+ 0x305b, 0x0000, 0x0000, 0x3e76, 0x6147, 0x0000, 0x6144, 0x466d,
+ 0x6143, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3526,
+ 0x0000, 0x0000, 0x614a, 0x0000, 0x0000, 0x0000, 0x6145, 0x6146,
+ 0x0000, 0x6149, 0x6148, 0x4925, 0x0000, 0x0000, 0x4142, 0x4141,
+ 0x0000, 0x353f, 0x0000, 0x0000, 0x614b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x614c, 0x0000, 0x0000, 0x614d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x614f, 0x0000, 0x614e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3156, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6157, 0x4868, 0x6151, 0x0000, 0x6153, 0x0000, 0x0000,
+ 0x6155, 0x3f3e, 0x0000, 0x0000, 0x6156, 0x6154, 0x3c40, 0x0000,
+ 0x0000, 0x0000, 0x6150, 0x6152, 0x0000, 0x4942, 0x0000, 0x3e49,
+ 0x0000, 0x0000, 0x6159, 0x0000, 0x0000, 0x6158, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x615a, 0x0000, 0x3c26, 0x3a2f, 0x0000, 0x0000,
+ 0x4577, 0x615b, 0x0000, 0x444b, 0x0000, 0x0000, 0x615d, 0x0000,
+ 0x0000, 0x0000, 0x4e21, 0x615c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6162, 0x0000, 0x6164, 0x6165, 0x4354, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6163, 0x0000, 0x6160, 0x0000, 0x615e, 0x615f,
+};
+
+static unsigned short const tqunicode_to_jisx0208_76[] = {
+ /* 0x7600 - 0x76ff */
+ 0x0000, 0x6161, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6168, 0x0000, 0x6166, 0x0000, 0x6167, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6169,
+ 0x616b, 0x616c, 0x616d, 0x0000, 0x616e, 0x0000, 0x0000, 0x616a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6170, 0x0000, 0x0000, 0x0000, 0x616f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6171, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4e45, 0x0000, 0x0000, 0x0000, 0x6174, 0x6172,
+ 0x6173, 0x0000, 0x0000, 0x0000, 0x3462, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4c7e, 0x0000, 0x0000, 0x0000, 0x4a4a, 0x0000,
+ 0x6176, 0x0000, 0x0000, 0x0000, 0x6175, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6177, 0x6178, 0x0000, 0x0000, 0x0000, 0x0000, 0x617c,
+ 0x6179, 0x617a, 0x617b, 0x0000, 0x617d, 0x0000, 0x0000, 0x0000,
+ 0x617e, 0x0000, 0x6221, 0x0000, 0x0000, 0x0000, 0x6222, 0x0000,
+ 0x6223, 0x0000, 0x482f, 0x4550, 0x6224, 0x4772, 0x4934, 0x0000,
+ 0x6225, 0x0000, 0x0000, 0x6226, 0x452a, 0x0000, 0x3327, 0x3944,
+ 0x6227, 0x0000, 0x0000, 0x6228, 0x0000, 0x0000, 0x6229, 0x0000,
+ 0x3b29, 0x0000, 0x0000, 0x622b, 0x0000, 0x0000, 0x622a, 0x0000,
+ 0x0000, 0x622c, 0x622d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4869, 0x0000,
+ 0x622e, 0x0000, 0x0000, 0x0000, 0x622f, 0x0000, 0x0000, 0x7369,
+ 0x6230, 0x6231, 0x6232, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b2e,
+ 0x0000, 0x0000, 0x6233, 0x4756, 0x0000, 0x0000, 0x4b5f, 0x0000,
+ 0x314e, 0x0000, 0x3157, 0x0000, 0x0000, 0x6234, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6236, 0x0000, 0x0000, 0x0000, 0x6235, 0x4570,
+ 0x0000, 0x0000, 0x0000, 0x4039, 0x5d39, 0x0000, 0x6237, 0x4c41,
+ 0x0000, 0x6238, 0x0000, 0x3446, 0x4857, 0x6239, 0x0000, 0x623a,
+ 0x0000, 0x0000, 0x623b, 0x0000, 0x0000, 0x0000, 0x4c5c, 0x0000,
+ 0x0000, 0x0000, 0x4c55, 0x0000, 0x443e, 0x0000, 0x0000, 0x0000,
+ 0x416a, 0x0000, 0x0000, 0x623d, 0x0000, 0x0000, 0x3d62, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_77[] = {
+ /* 0x7700 - 0x77ff */
+ 0x0000, 0x3e4a, 0x0000, 0x0000, 0x6240, 0x0000, 0x0000, 0x623f,
+ 0x623e, 0x487d, 0x0000, 0x3447, 0x3829, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6246, 0x0000, 0x0000, 0x6243, 0x3f3f,
+ 0x4c32, 0x0000, 0x0000, 0x0000, 0x6242, 0x6244, 0x6245, 0x0000,
+ 0x0000, 0x6241, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6247,
+ 0x6248, 0x0000, 0x442f, 0x0000, 0x3463, 0x0000, 0x0000, 0x0000,
+ 0x4365, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6249,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x624a, 0x624d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3f67, 0x0000, 0x4644, 0x0000, 0x624e, 0x4b53, 0x0000,
+ 0x624b, 0x0000, 0x0000, 0x624c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6251, 0x0000, 0x0000, 0x0000, 0x0000, 0x6250, 0x624f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6253, 0x0000, 0x0000, 0x6252, 0x0000,
+ 0x0000, 0x6254, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6256, 0x0000,
+ 0x6255, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a4d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3d56, 0x4e46, 0x0000, 0x0000,
+ 0x6257, 0x0000, 0x0000, 0x4637, 0x0000, 0x0000, 0x6258, 0x0000,
+ 0x0000, 0x6259, 0x0000, 0x625d, 0x625b, 0x625c, 0x0000, 0x625a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x625e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x625f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6260,
+ 0x0000, 0x0000, 0x6261, 0x4c37, 0x6262, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4c70, 0x6263, 0x0000, 0x434e, 0x0000, 0x476a,
+ 0x0000, 0x366b, 0x0000, 0x0000, 0x0000, 0x433b, 0x6264, 0x363a,
+ 0x0000, 0x0000, 0x0000, 0x4050, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6265, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_78[] = {
+ /* 0x7800 - 0x78ff */
+ 0x0000, 0x0000, 0x3a3d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6266, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6267, 0x0000, 0x3826, 0x3a55, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6269, 0x0000, 0x0000, 0x0000, 0x0000, 0x4556, 0x3a56, 0x354e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4b24, 0x0000, 0x474b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4557, 0x0000, 0x0000, 0x0000, 0x0000, 0x395c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x626b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e4b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4e32, 0x3945, 0x0000, 0x0000, 0x3827,
+ 0x0000, 0x0000, 0x4823, 0x0000, 0x626d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x626f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x386b, 0x0000, 0x0000, 0x0000, 0x0000, 0x626e, 0x4476,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6271, 0x3337, 0x626c, 0x0000,
+ 0x0000, 0x486a, 0x0000, 0x3130, 0x0000, 0x3a6c, 0x0000, 0x4f52,
+ 0x0000, 0x0000, 0x6270, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6272, 0x0000, 0x0000, 0x0000, 0x4a4b,
+ 0x0000, 0x4059, 0x6274, 0x0000, 0x0000, 0x0000, 0x0000, 0x6275,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6273, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x334e, 0x0000, 0x627b, 0x0000, 0x627a, 0x0000,
+ 0x0000, 0x3c27, 0x0000, 0x0000, 0x0000, 0x627c, 0x6277, 0x0000,
+ 0x0000, 0x0000, 0x627d, 0x6278, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4858, 0x6276, 0x0000, 0x0000, 0x6279, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6322, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6321,
+ 0x4b61, 0x0000, 0x0000, 0x0000, 0x627e, 0x0000, 0x0000, 0x306b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6324, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6323, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_79[] = {
+ /* 0x7900 - 0x79ff */
+ 0x0000, 0x3e4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6325,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4143, 0x0000,
+ 0x0000, 0x6327, 0x6326, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6328, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6268, 0x0000,
+ 0x0000, 0x0000, 0x626a, 0x632a, 0x6329, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3c28, 0x0000, 0x4e69, 0x0000, 0x3c52, 0x0000,
+ 0x632b, 0x3737, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3540,
+ 0x3527, 0x3b63, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4d34, 0x0000, 0x0000, 0x6331, 0x0000, 0x6330, 0x4144, 0x632d,
+ 0x0000, 0x0000, 0x632f, 0x0000, 0x0000, 0x3d4b, 0x3f40, 0x632e,
+ 0x632c, 0x0000, 0x472a, 0x0000, 0x0000, 0x3e4d, 0x0000, 0x0000,
+ 0x493c, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a57, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4578,
+ 0x0000, 0x0000, 0x6332, 0x0000, 0x0000, 0x0000, 0x0000, 0x6333,
+ 0x6349, 0x3658, 0x0000, 0x0000, 0x4f3d, 0x4135, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6334, 0x0000, 0x0000, 0x3252, 0x4477, 0x4a21,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6335, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x357a, 0x6336,
+ 0x0000, 0x0000, 0x6338, 0x0000, 0x0000, 0x0000, 0x6339, 0x0000,
+ 0x4729, 0x0000, 0x0000, 0x633a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x633b, 0x633c, 0x0000, 0x0000, 0x3659, 0x3253, 0x4645,
+ 0x3d28, 0x3b64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x633d, 0x0000, 0x3d29, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x324a, 0x4943, 0x0000, 0x0000, 0x633e, 0x0000, 0x0000,
+ 0x486b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4145,
+ 0x0000, 0x6341, 0x0000, 0x6342, 0x4769, 0x0000, 0x3f41, 0x633f,
+ 0x0000, 0x4361, 0x0000, 0x0000, 0x6340, 0x0000, 0x0000, 0x0000,
+ 0x3e4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x305c, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_7a[] = {
+ /* 0x7a00 - 0x7aff */
+ 0x3529, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6343, 0x0000, 0x0000, 0x4478, 0x0000, 0x6344, 0x4047, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4c2d, 0x0000, 0x0000, 0x4923,
+ 0x6345, 0x6346, 0x4355, 0x0000, 0x4e47, 0x0000, 0x0000, 0x6348,
+ 0x6347, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c6f, 0x0000,
+ 0x0000, 0x634a, 0x3070, 0x0000, 0x0000, 0x0000, 0x0000, 0x634d,
+ 0x0000, 0x0000, 0x0000, 0x634b, 0x3254, 0x374e, 0x634c, 0x3946,
+ 0x3972, 0x0000, 0x4a66, 0x634e, 0x0000, 0x0000, 0x4b54, 0x0000,
+ 0x0000, 0x6350, 0x0000, 0x0000, 0x0000, 0x4051, 0x314f, 0x323a,
+ 0x302c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x634f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6351, 0x6352, 0x3e77, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6353, 0x0000, 0x334f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6355, 0x0000, 0x0000, 0x0000, 0x376a, 0x0000, 0x3566, 0x0000,
+ 0x0000, 0x6356, 0x3675, 0x0000, 0x0000, 0x6357, 0x0000, 0x407c,
+ 0x0000, 0x464d, 0x0000, 0x4060, 0x3a75, 0x0000, 0x0000, 0x0000,
+ 0x6358, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4362, 0x416b, 0x0000, 0x635a, 0x635c, 0x6359,
+ 0x635b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3722,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x635d, 0x3726, 0x0000, 0x0000, 0x0000, 0x3567, 0x4d52,
+ 0x635f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6360, 0x0000,
+ 0x0000, 0x0000, 0x312e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6363,
+ 0x0000, 0x0000, 0x0000, 0x3376, 0x6362, 0x6361, 0x0000, 0x6365,
+ 0x635e, 0x0000, 0x6366, 0x4e29, 0x0000, 0x6367, 0x0000, 0x6368,
+ 0x0000, 0x0000, 0x5474, 0x636a, 0x0000, 0x6369, 0x0000, 0x0000,
+ 0x0000, 0x636b, 0x636c, 0x0000, 0x4e35, 0x636d, 0x0000, 0x706f,
+ 0x3e4f, 0x636e, 0x636f, 0x3d57, 0x0000, 0x4638, 0x6370, 0x0000,
+ 0x0000, 0x0000, 0x4328, 0x0000, 0x0000, 0x6371, 0x0000, 0x433c,
+ 0x6372, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3625, 0x0000,
+ 0x513f, 0x435d, 0x3c33, 0x0000, 0x0000, 0x0000, 0x0000, 0x3448,
+};
+
+static unsigned short const tqunicode_to_jisx0208_7b[] = {
+ /* 0x7b00 - 0x7bff */
+ 0x0000, 0x0000, 0x6373, 0x0000, 0x6422, 0x0000, 0x6376, 0x0000,
+ 0x3568, 0x0000, 0x6375, 0x6424, 0x0000, 0x0000, 0x0000, 0x6374,
+ 0x0000, 0x3e50, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6378, 0x6379, 0x0000, 0x452b, 0x0000, 0x0000, 0x637a, 0x0000,
+ 0x335e, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f5a, 0x4964, 0x0000,
+ 0x637c, 0x0000, 0x0000, 0x0000, 0x4268, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6377, 0x0000, 0x637b, 0x637d, 0x0000,
+ 0x0000, 0x3a7b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6426, 0x492e, 0x0000,
+ 0x4826, 0x4579, 0x0000, 0x365a, 0x6425, 0x6423, 0x0000, 0x4835,
+ 0x637e, 0x435e, 0x457b, 0x0000, 0x457a, 0x0000, 0x3a76, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6438, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6428, 0x0000, 0x642a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x642d, 0x0000, 0x642e, 0x0000,
+ 0x642b, 0x642c, 0x0000, 0x0000, 0x6429, 0x6427, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6421, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a4f, 0x3255,
+ 0x0000, 0x0000, 0x0000, 0x6435, 0x0000, 0x6432, 0x0000, 0x6437,
+ 0x0000, 0x0000, 0x6436, 0x0000, 0x4773, 0x4c27, 0x0000, 0x3b3b,
+ 0x6430, 0x6439, 0x6434, 0x0000, 0x6433, 0x642f, 0x0000, 0x6431,
+ 0x0000, 0x3449, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x433d, 0x0000, 0x0000, 0x407d, 0x0000, 0x0000,
+ 0x0000, 0x4822, 0x0000, 0x0000, 0x643e, 0x0000, 0x0000, 0x0000,
+ 0x4824, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4061, 0x643b, 0x0000, 0x0000, 0x484f, 0x0000, 0x643f, 0x4a53,
+ 0x0000, 0x435b, 0x0000, 0x643a, 0x643c, 0x0000, 0x0000, 0x643d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6440, 0x0000, 0x0000,
+ 0x3c44, 0x0000, 0x0000, 0x0000, 0x4646, 0x6445, 0x6444, 0x0000,
+ 0x0000, 0x6441, 0x0000, 0x0000, 0x0000, 0x4f36, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x644a, 0x0000, 0x0000, 0x644e, 0x644b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_7c[] = {
+ /* 0x7c00 - 0x7cff */
+ 0x6447, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6448,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x644d, 0x0000, 0x0000,
+ 0x0000, 0x6442, 0x5255, 0x6449, 0x6443, 0x0000, 0x0000, 0x644c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6452,
+ 0x0000, 0x344a, 0x0000, 0x644f, 0x0000, 0x0000, 0x0000, 0x6450,
+ 0x0000, 0x0000, 0x6451, 0x6454, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6453,
+ 0x4876, 0x0000, 0x0000, 0x0000, 0x0000, 0x6455, 0x4e7c, 0x4a6d,
+ 0x645a, 0x0000, 0x0000, 0x6457, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6456, 0x4052, 0x0000, 0x6459,
+ 0x645b, 0x0000, 0x0000, 0x0000, 0x6458, 0x0000, 0x645f, 0x0000,
+ 0x645c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x645d,
+ 0x6446, 0x0000, 0x0000, 0x0000, 0x645e, 0x6460, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6461, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a46, 0x0000, 0x6462, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c62, 0x0000,
+ 0x0000, 0x364e, 0x3729, 0x6463, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4a34, 0x0000, 0x3f68, 0x0000, 0x4c30, 0x0000, 0x0000,
+ 0x6464, 0x0000, 0x4e33, 0x0000, 0x0000, 0x4774, 0x0000, 0x4146,
+ 0x4734, 0x0000, 0x0000, 0x3d4d, 0x0000, 0x0000, 0x0000, 0x3040,
+ 0x0000, 0x6469, 0x6467, 0x0000, 0x6465, 0x3421, 0x0000, 0x3e51,
+ 0x646a, 0x0000, 0x0000, 0x6468, 0x0000, 0x6466, 0x646e, 0x0000,
+ 0x0000, 0x646d, 0x646c, 0x646b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x646f, 0x0000, 0x0000, 0x0000, 0x6470, 0x403a, 0x0000,
+ 0x6471, 0x0000, 0x6473, 0x0000, 0x0000, 0x6472, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3852, 0x0000, 0x0000, 0x0000, 0x4138, 0x0000,
+ 0x0000, 0x0000, 0x6475, 0x0000, 0x0000, 0x0000, 0x457c, 0x0000,
+ 0x6474, 0x0000, 0x0000, 0x0000, 0x6476, 0x0000, 0x4a35, 0x416c,
+ 0x3947, 0x0000, 0x6477, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e48,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6479,
+ 0x0000, 0x0000, 0x647a, 0x0000, 0x647b, 0x0000, 0x647c, 0x0000,
+ 0x3b65, 0x0000, 0x647d, 0x374f, 0x0000, 0x0000, 0x356a, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_7d[] = {
+ /* 0x7d00 - 0x7dff */
+ 0x352a, 0x0000, 0x6521, 0x0000, 0x4c73, 0x3948, 0x647e, 0x0000,
+ 0x0000, 0x0000, 0x6524, 0x4c66, 0x0000, 0x473c, 0x0000, 0x0000,
+ 0x4933, 0x0000, 0x0000, 0x0000, 0x3d63, 0x6523, 0x0000, 0x3c53,
+ 0x3949, 0x3b66, 0x3569, 0x4a36, 0x6522, 0x0000, 0x0000, 0x0000,
+ 0x4147, 0x4b42, 0x3a77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3b67, 0x445d, 0x0000, 0x6527, 0x4e5f,
+ 0x3a59, 0x0000, 0x6528, 0x3f42, 0x0000, 0x652a, 0x0000, 0x0000,
+ 0x0000, 0x3e52, 0x3a30, 0x0000, 0x0000, 0x0000, 0x0000, 0x6529,
+ 0x0000, 0x0000, 0x3d2a, 0x383e, 0x4148, 0x6525, 0x652b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6526, 0x3750, 0x0000, 0x652e, 0x6532,
+ 0x376b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x652d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6536, 0x0000, 0x0000, 0x394a, 0x0000,
+ 0x0000, 0x4d6d, 0x303c, 0x6533, 0x0000, 0x0000, 0x356b, 0x0000,
+ 0x6530, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6531, 0x0000,
+ 0x0000, 0x457d, 0x652f, 0x652c, 0x0000, 0x3328, 0x4064, 0x0000,
+ 0x0000, 0x3828, 0x0000, 0x0000, 0x0000, 0x6538, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6535, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6537,
+ 0x0000, 0x0000, 0x0000, 0x6534, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3751, 0x4233, 0x6539, 0x416e, 0x0000, 0x0000, 0x6546,
+ 0x0000, 0x0000, 0x6542, 0x653c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6540, 0x3c7a, 0x305d, 0x653b, 0x6543,
+ 0x6547, 0x394b, 0x4c56, 0x0000, 0x4456, 0x653d, 0x0000, 0x0000,
+ 0x6545, 0x0000, 0x653a, 0x433e, 0x0000, 0x653f, 0x303d, 0x4c4a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x653e,
+ 0x0000, 0x0000, 0x365b, 0x486c, 0x0000, 0x0000, 0x0000, 0x416d,
+ 0x0000, 0x4e50, 0x3d6f, 0x0000, 0x0000, 0x656e, 0x0000, 0x0000,
+ 0x6548, 0x0000, 0x407e, 0x0000, 0x6544, 0x6549, 0x654b, 0x0000,
+ 0x4479, 0x654e, 0x0000, 0x0000, 0x654a, 0x0000, 0x0000, 0x0000,
+ 0x4a54, 0x344b, 0x0000, 0x0000, 0x4c4b, 0x0000, 0x0000, 0x305e,
+ 0x0000, 0x0000, 0x654d, 0x0000, 0x4e7d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x654c, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_7e[] = {
+ /* 0x7e00 - 0x7eff */
+ 0x0000, 0x316f, 0x0000, 0x0000, 0x466c, 0x654f, 0x0000, 0x0000,
+ 0x0000, 0x6556, 0x6550, 0x6557, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6553, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x477b, 0x0000, 0x0000, 0x3c4a, 0x6555,
+ 0x0000, 0x6552, 0x6558, 0x6551, 0x0000, 0x0000, 0x3d44, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4b25, 0x0000, 0x0000, 0x3d4c, 0x0000,
+ 0x0000, 0x6554, 0x6560, 0x0000, 0x0000, 0x655c, 0x0000, 0x655f,
+ 0x0000, 0x655d, 0x6561, 0x655b, 0x0000, 0x6541, 0x4053, 0x0000,
+ 0x0000, 0x484b, 0x0000, 0x655e, 0x0000, 0x0000, 0x6559, 0x0000,
+ 0x0000, 0x0000, 0x4121, 0x3752, 0x0000, 0x3d2b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3f25, 0x4136, 0x6564, 0x0000,
+ 0x0000, 0x6566, 0x6567, 0x0000, 0x0000, 0x6563, 0x6565, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x655a, 0x6562,
+ 0x0000, 0x656a, 0x6569, 0x0000, 0x0000, 0x4b7a, 0x0000, 0x0000,
+ 0x372b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6568, 0x0000, 0x656c, 0x656b, 0x656f, 0x0000, 0x6571,
+ 0x0000, 0x0000, 0x3b3c, 0x656d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6572, 0x6573, 0x0000, 0x0000, 0x6574, 0x0000, 0x657a, 0x453b,
+ 0x6576, 0x0000, 0x6575, 0x6577, 0x6578, 0x0000, 0x6579, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x657b, 0x657c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_7f[] = {
+ /* 0x7f00 - 0x7fff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x344c, 0x0000,
+ 0x657d, 0x0000, 0x657e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6621, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6622, 0x6623, 0x6624, 0x0000,
+ 0x6625, 0x6626, 0x0000, 0x0000, 0x6628, 0x6627, 0x0000, 0x0000,
+ 0x6629, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x662a,
+ 0x662b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x662e,
+ 0x662c, 0x662d, 0x3a61, 0x3753, 0x0000, 0x0000, 0x4356, 0x0000,
+ 0x4833, 0x0000, 0x3d70, 0x0000, 0x0000, 0x474d, 0x0000, 0x486d,
+ 0x662f, 0x586d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6630, 0x6632, 0x0000, 0x4d65, 0x6631, 0x6634,
+ 0x6633, 0x0000, 0x4d53, 0x0000, 0x6635, 0x0000, 0x487e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6636, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6639, 0x0000, 0x0000, 0x6638, 0x6637, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x663a, 0x3732, 0x0000, 0x0000, 0x0000,
+ 0x4122, 0x3541, 0x0000, 0x0000, 0x0000, 0x0000, 0x663e, 0x663b,
+ 0x0000, 0x0000, 0x663c, 0x0000, 0x0000, 0x0000, 0x663f, 0x0000,
+ 0x6640, 0x663d, 0x0000, 0x0000, 0x0000, 0x3129, 0x0000, 0x0000,
+ 0x0000, 0x3227, 0x0000, 0x0000, 0x0000, 0x6642, 0x6643, 0x0000,
+ 0x0000, 0x0000, 0x6644, 0x0000, 0x4d62, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3d2c, 0x0000, 0x6646, 0x6645, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3f69, 0x6647, 0x0000, 0x0000, 0x0000, 0x0000, 0x6648, 0x0000,
+ 0x0000, 0x6649, 0x0000, 0x3465, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x344d, 0x0000, 0x0000, 0x664a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x664b, 0x0000, 0x4b5d, 0x4d63, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_80[] = {
+ /* 0x8000 - 0x80ff */
+ 0x4d54, 0x4f37, 0x0000, 0x394d, 0x664e, 0x3c54, 0x664d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x664f, 0x3c29, 0x0000, 0x0000, 0x0000,
+ 0x4251, 0x0000, 0x6650, 0x0000, 0x0000, 0x394c, 0x0000, 0x4c57,
+ 0x6651, 0x6652, 0x0000, 0x0000, 0x6653, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6654, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6655, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3c2a, 0x0000, 0x0000, 0x4c6d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6657, 0x0000, 0x433f, 0x0000, 0x6656,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6659, 0x0000,
+ 0x0000, 0x0000, 0x6658, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x665a, 0x0000, 0x0000, 0x0000, 0x403b, 0x0000,
+ 0x665b, 0x0000, 0x665c, 0x0000, 0x0000, 0x0000, 0x4a39, 0x665d,
+ 0x0000, 0x416f, 0x665e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x665f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e7e,
+ 0x6662, 0x0000, 0x6661, 0x6660, 0x4430, 0x0000, 0x6663, 0x3f26,
+ 0x0000, 0x6664, 0x0000, 0x0000, 0x0000, 0x6665, 0x4f38, 0x6666,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6667, 0x6669, 0x6668, 0x4825,
+ 0x0000, 0x4679, 0x0000, 0x4f3e, 0x4829, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x666b, 0x0000, 0x0000, 0x3e53, 0x0000,
+ 0x492a, 0x0000, 0x666c, 0x666a, 0x0000, 0x344e, 0x0000, 0x0000,
+ 0x0000, 0x3854, 0x3b68, 0x0000, 0x0000, 0x486e, 0x0000, 0x0000,
+ 0x0000, 0x382a, 0x4b43, 0x0000, 0x666f, 0x666d, 0x0000, 0x394e,
+ 0x0000, 0x394f, 0x3069, 0x0000, 0x3a68, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4759, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x305f, 0x6674, 0x0000, 0x4340, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4758, 0x0000, 0x425b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6676, 0x0000,
+ 0x0000, 0x6672, 0x6675, 0x6670, 0x0000, 0x6673, 0x4b26, 0x0000,
+ 0x0000, 0x3855, 0x0000, 0x0000, 0x307d, 0x6671, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6678,
+ 0x0000, 0x6679, 0x0000, 0x0000, 0x4639, 0x0000, 0x0000, 0x0000,
+ 0x363b, 0x0000, 0x0000, 0x0000, 0x6726, 0x473d, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_81[] = {
+ /* 0x8100 - 0x81ff */
+ 0x0000, 0x0000, 0x3b69, 0x0000, 0x0000, 0x363c, 0x4048, 0x4f46,
+ 0x4c2e, 0x6677, 0x4054, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3553, 0x667a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x667c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x667b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x667d,
+ 0x0000, 0x4326, 0x0000, 0x473e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4431, 0x0000, 0x0000, 0x0000, 0x0000, 0x6723, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6722, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x667e, 0x0000, 0x0000, 0x3f55, 0x0000,
+ 0x4965, 0x6725, 0x0000, 0x6724, 0x3950, 0x4f53, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6735,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6729, 0x672a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3c70, 0x0000, 0x0000, 0x6728, 0x0000,
+ 0x3978, 0x6727, 0x0000, 0x0000, 0x672b, 0x0000, 0x0000, 0x0000,
+ 0x4432, 0x4a22, 0x4123, 0x0000, 0x0000, 0x0000, 0x0000, 0x425c,
+ 0x672f, 0x0000, 0x6730, 0x672c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x672d, 0x0000, 0x672e, 0x0000, 0x0000, 0x0000, 0x0000, 0x3951,
+ 0x0000, 0x0000, 0x0000, 0x6736, 0x0000, 0x6732, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4966, 0x0000, 0x4b6c, 0x4928, 0x0000, 0x0000,
+ 0x6731, 0x0000, 0x0000, 0x6734, 0x6733, 0x0000, 0x0000, 0x0000,
+ 0x4b44, 0x6737, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6738, 0x0000, 0x0000, 0x4137, 0x0000, 0x6739, 0x0000, 0x0000,
+ 0x673b, 0x0000, 0x673f, 0x0000, 0x0000, 0x673c, 0x673a, 0x473f,
+ 0x673d, 0x0000, 0x673e, 0x0000, 0x0000, 0x0000, 0x3232, 0x0000,
+ 0x6745, 0x6740, 0x0000, 0x0000, 0x0000, 0x6741, 0x0000, 0x0000,
+ 0x0000, 0x6742, 0x0000, 0x4221, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6744, 0x6743, 0x6746, 0x0000, 0x0000, 0x0000, 0x0000, 0x6747,
+ 0x6748, 0x0000, 0x0000, 0x3f43, 0x0000, 0x3269, 0x0000, 0x6749,
+ 0x4e57, 0x0000, 0x3c2b, 0x0000, 0x0000, 0x3d2d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3b6a, 0x4357, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x674a, 0x674b, 0x3131, 0x0000, 0x674c, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_82[] = {
+ /* 0x8200 - 0x82ff */
+ 0x0000, 0x674d, 0x674e, 0x0000, 0x0000, 0x674f, 0x0000, 0x6750,
+ 0x363d, 0x5a2a, 0x6751, 0x0000, 0x4065, 0x6752, 0x3c4b, 0x0000,
+ 0x6753, 0x0000, 0x5030, 0x0000, 0x0000, 0x0000, 0x6754, 0x4a5e,
+ 0x345c, 0x0000, 0x0000, 0x4124, 0x3d58, 0x0000, 0x4971, 0x3d2e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6755, 0x3952, 0x6756, 0x484c, 0x0000, 0x6764, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6758, 0x0000, 0x4249, 0x4775, 0x383f,
+ 0x6757, 0x4125, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6759, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x447a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x675b, 0x675a, 0x675d, 0x0000, 0x0000, 0x675c, 0x0000, 0x675e,
+ 0x0000, 0x0000, 0x6760, 0x0000, 0x675f, 0x0000, 0x344f, 0x0000,
+ 0x6761, 0x0000, 0x6762, 0x6763, 0x0000, 0x0000, 0x3a31, 0x4e49,
+ 0x0000, 0x6765, 0x3f27, 0x0000, 0x0000, 0x0000, 0x3170, 0x6766,
+ 0x6767, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6768, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3072, 0x0000, 0x6769, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x676a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4967, 0x0000, 0x0000, 0x0000, 0x3c47, 0x0000, 0x676c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3329, 0x3032, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x676b, 0x676e, 0x474e, 0x0000, 0x3f44,
+ 0x0000, 0x3256, 0x0000, 0x4b27, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x375d, 0x365c, 0x0000, 0x676d, 0x0000, 0x326a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3423, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3171, 0x6772, 0x4e6a, 0x425d, 0x0000, 0x0000, 0x4944,
+ 0x0000, 0x677e, 0x0000, 0x3257, 0x677c, 0x0000, 0x677a, 0x6771,
+ 0x0000, 0x676f, 0x0000, 0x6770, 0x0000, 0x3c63, 0x366c, 0x4377,
+ 0x0000, 0x0000, 0x0000, 0x4651, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3151, 0x0000, 0x6774, 0x6773, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6779, 0x6775, 0x6778, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_83[] = {
+ /* 0x8300 - 0x83ff */
+ 0x0000, 0x0000, 0x4c50, 0x6777, 0x3258, 0x337d, 0x677b, 0x0000,
+ 0x0000, 0x677d, 0x0000, 0x0000, 0x0000, 0x0000, 0x3754, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6823, 0x682c,
+ 0x682d, 0x0000, 0x0000, 0x0000, 0x302b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6834, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3071, 0x0000, 0x0000, 0x682b, 0x0000, 0x0000, 0x0000, 0x682a,
+ 0x0000, 0x6825, 0x6824, 0x0000, 0x6822, 0x6821, 0x4363, 0x0000,
+ 0x427b, 0x6827, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6826, 0x0000, 0x0000, 0x0000, 0x0000, 0x6829, 0x0000, 0x0000,
+ 0x0000, 0x4170, 0x3755, 0x0000, 0x0000, 0x0000, 0x0000, 0x3141,
+ 0x6828, 0x0000, 0x3953, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4171, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x683a, 0x0000, 0x683b, 0x0000, 0x3259,
+ 0x0000, 0x0000, 0x0000, 0x322e, 0x6838, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x682e, 0x0000, 0x6836,
+ 0x0000, 0x683d, 0x6837, 0x0000, 0x0000, 0x0000, 0x6835, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6776, 0x0000, 0x0000, 0x6833, 0x0000,
+ 0x0000, 0x0000, 0x682f, 0x0000, 0x0000, 0x0000, 0x3450, 0x6831,
+ 0x683c, 0x0000, 0x6832, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x683e, 0x0000, 0x6830, 0x477c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4d69, 0x0000, 0x0000, 0x0000, 0x6839, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x684f, 0x0000, 0x0000,
+ 0x0000, 0x6847, 0x0000, 0x0000, 0x0000, 0x3f7b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3546, 0x0000, 0x365d, 0x0000, 0x6842, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x325b, 0x0000, 0x0000, 0x3e54, 0x0000,
+ 0x6845, 0x0000, 0x0000, 0x0000, 0x3a5a, 0x0000, 0x0000, 0x4551,
+ 0x684a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4a6e, 0x0000, 0x6841, 0x0000, 0x0000, 0x0000, 0x325a,
+ 0x3856, 0x4929, 0x684b, 0x0000, 0x683f, 0x0000, 0x0000, 0x6848,
+ 0x0000, 0x0000, 0x0000, 0x6852, 0x0000, 0x6843, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_84[] = {
+ /* 0x8400 - 0x84ff */
+ 0x0000, 0x0000, 0x0000, 0x6844, 0x463a, 0x0000, 0x0000, 0x6849,
+ 0x0000, 0x0000, 0x0000, 0x6846, 0x4b28, 0x684c, 0x3060, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6840, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x684e, 0x0000, 0x684d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x476b, 0x6854, 0x0000, 0x685f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x337e, 0x0000, 0x0000, 0x0000, 0x6862, 0x0000, 0x0000,
+ 0x6850, 0x0000, 0x0000, 0x0000, 0x6855, 0x4d6e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x685e, 0x0000,
+ 0x0000, 0x4d55, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e2a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4378,
+ 0x0000, 0x0000, 0x0000, 0x336b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4972, 0x6864, 0x4621, 0x0000, 0x0000, 0x3031, 0x0000,
+ 0x0000, 0x685d, 0x0000, 0x6859, 0x4172, 0x6853, 0x685b, 0x6860,
+ 0x0000, 0x472c, 0x0000, 0x0000, 0x0000, 0x302a, 0x0000, 0x6858,
+ 0x0000, 0x6861, 0x4978, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x685c, 0x0000, 0x6857, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3e55, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3d2f, 0x0000, 0x0000, 0x0000, 0x3c2c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4c58, 0x0000, 0x0000, 0x4947, 0x0000, 0x0000, 0x6867,
+ 0x0000, 0x6870, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x685a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3377, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3e78, 0x6865, 0x0000, 0x686a, 0x4173, 0x0000, 0x0000, 0x6866,
+ 0x0000, 0x686d, 0x0000, 0x0000, 0x435f, 0x0000, 0x686e, 0x0000,
+ 0x0000, 0x4d56, 0x6863, 0x3338, 0x0000, 0x6869, 0x0000, 0x0000,
+ 0x686c, 0x4c2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x686f, 0x0000,
+ 0x0000, 0x6868, 0x686b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4b29, 0x0000, 0x4f21, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6873, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x687a, 0x0000, 0x0000, 0x6872,
+};
+
+static unsigned short const tqunicode_to_jisx0208_85[] = {
+ /* 0x8500 - 0x85ff */
+ 0x3c43, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6851, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4a4e, 0x0000, 0x4c22, 0x6879, 0x6878, 0x0000, 0x6874,
+ 0x6875, 0x0000, 0x3136, 0x0000, 0x0000, 0x0000, 0x0000, 0x6877,
+ 0x0000, 0x6871, 0x0000, 0x0000, 0x0000, 0x0000, 0x4455, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6876, 0x307e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4222, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a43, 0x0000, 0x0000,
+ 0x687b, 0x6921, 0x0000, 0x4859, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x687e, 0x3e56, 0x3c49, 0x6923, 0x0000, 0x0000, 0x363e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6924, 0x0000, 0x4979,
+ 0x687d, 0x0000, 0x6856, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x687c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4f4f, 0x4622, 0x4973, 0x0000, 0x0000, 0x692b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6931,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6932, 0x0000,
+ 0x6925, 0x0000, 0x0000, 0x0000, 0x4776, 0x0000, 0x0000, 0x692f,
+ 0x6927, 0x0000, 0x6929, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6933, 0x6928, 0x0000, 0x0000, 0x692c, 0x0000, 0x0000, 0x3172,
+ 0x0000, 0x4665, 0x0000, 0x692d, 0x6930, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6926, 0x0000, 0x4126, 0x0000,
+ 0x692a, 0x3b27, 0x3f45, 0x3730, 0x4c74, 0x0000, 0x4c79, 0x3d72,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6937, 0x6935, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4f4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6934, 0x0000, 0x0000, 0x0000, 0x4d75, 0x0000, 0x6936,
+ 0x6938, 0x0000, 0x0000, 0x0000, 0x0000, 0x6939, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x693c, 0x693a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4623, 0x693b, 0x0000, 0x0000,
+ 0x0000, 0x484d, 0x692e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d73,
+ 0x0000, 0x693d, 0x6942, 0x4174, 0x0000, 0x0000, 0x6941, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_86[] = {
+ /* 0x8600 - 0x86ff */
+ 0x0000, 0x0000, 0x6922, 0x0000, 0x0000, 0x0000, 0x6943, 0x4149,
+ 0x0000, 0x0000, 0x693e, 0x6940, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x693f, 0x0000, 0x0000, 0x5d31, 0x5d22,
+ 0x0000, 0x0000, 0x6945, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6944, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d76, 0x0000, 0x623c,
+ 0x6946, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6947,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6948, 0x3857, 0x0000,
+ 0x3554, 0x0000, 0x0000, 0x0000, 0x694a, 0x515d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3575, 0x0000, 0x4e3a, 0x0000, 0x3673, 0x694b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x694c,
+ 0x0000, 0x0000, 0x0000, 0x436e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x694d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x467a, 0x0000, 0x303a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3263, 0x6952, 0x6953, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x694e, 0x0000, 0x3b3d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x694f, 0x4742, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6950, 0x6951, 0x695b, 0x0000, 0x0000, 0x0000, 0x6955,
+ 0x6958, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6954, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6956, 0x0000, 0x6957, 0x3c58,
+ 0x0000, 0x6959, 0x0000, 0x4341, 0x0000, 0x3756, 0x3342, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x695c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x333f, 0x0000, 0x6961, 0x0000, 0x0000, 0x695d, 0x6960,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x483a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x695e, 0x0000, 0x0000, 0x695f, 0x4948, 0x485a, 0x6962,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x427d, 0x696c, 0x0000, 0x6968, 0x0000, 0x0000, 0x326b, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_87[] = {
+ /* 0x8700 - 0x87ff */
+ 0x6966, 0x0000, 0x4b2a, 0x6967, 0x0000, 0x0000, 0x6964, 0x0000,
+ 0x6965, 0x696a, 0x696d, 0x0000, 0x0000, 0x696b, 0x0000, 0x0000,
+ 0x0000, 0x6969, 0x6963, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4358, 0x0000, 0x6974, 0x0000, 0x4c2a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6972, 0x0000, 0x0000,
+ 0x0000, 0x6973, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x696e, 0x0000, 0x0000, 0x6970,
+ 0x0000, 0x0000, 0x0000, 0x6971, 0x0000, 0x0000, 0x0000, 0x696f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4066, 0x0000, 0x4f39, 0x6978, 0x0000, 0x6979, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6a21, 0x0000, 0x3f2a, 0x0000, 0x697b,
+ 0x0000, 0x697e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6976,
+ 0x6975, 0x0000, 0x0000, 0x6a22, 0x0000, 0x0000, 0x325c, 0x0000,
+ 0x697c, 0x0000, 0x6a23, 0x0000, 0x0000, 0x0000, 0x697d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x697a, 0x0000, 0x4433, 0x0000,
+ 0x6977, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4768,
+ 0x0000, 0x0000, 0x6a27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d3b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a26,
+ 0x0000, 0x0000, 0x6a25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6a2e, 0x0000, 0x0000, 0x0000, 0x6a28,
+ 0x0000, 0x0000, 0x0000, 0x6a30, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4d66, 0x6a33, 0x0000, 0x6a2a, 0x0000, 0x0000,
+ 0x6a2b, 0x0000, 0x0000, 0x0000, 0x6a2f, 0x0000, 0x6a32, 0x6a31,
+ 0x0000, 0x0000, 0x0000, 0x6a29, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6a2c, 0x0000, 0x6a3d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6a36, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a34,
+ 0x0000, 0x0000, 0x6a35, 0x0000, 0x0000, 0x0000, 0x6a3a, 0x6a3b,
+ 0x0000, 0x332a, 0x0000, 0x3542, 0x0000, 0x0000, 0x6a39, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_88[] = {
+ /* 0x8800 - 0x88ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a24, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a38, 0x6a3c, 0x6a37,
+ 0x0000, 0x6a3e, 0x0000, 0x0000, 0x0000, 0x6a40, 0x6a3f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6a42, 0x6a41, 0x695a, 0x0000, 0x0000, 0x0000, 0x6a46,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6a43, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a44, 0x0000,
+ 0x0000, 0x6a45, 0x0000, 0x6a47, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x376c, 0x0000, 0x6a49, 0x0000, 0x6a48, 0x0000, 0x3d30, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3954, 0x5e27, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6a4a, 0x3d51, 0x0000, 0x0000, 0x0000, 0x3339,
+ 0x0000, 0x6a4b, 0x0000, 0x3152, 0x0000, 0x3e57, 0x6a4c, 0x0000,
+ 0x0000, 0x3955, 0x6a4d, 0x3061, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x493d, 0x0000, 0x0000, 0x6a4e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3f6a, 0x0000, 0x6a55, 0x0000, 0x0000, 0x6a52, 0x0000, 0x436f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a53, 0x6a50, 0x365e,
+ 0x0000, 0x6a4f, 0x6a56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3736, 0x0000, 0x0000, 0x425e, 0x0000, 0x6a5c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6a58, 0x0000, 0x0000, 0x0000, 0x4235, 0x6a57,
+ 0x0000, 0x6a5a, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a51, 0x0000,
+ 0x0000, 0x0000, 0x6a5b, 0x0000, 0x6a5d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x486f, 0x0000, 0x0000, 0x6a59, 0x0000,
+ 0x6a5e, 0x6a60, 0x0000, 0x0000, 0x3853, 0x6a54, 0x0000, 0x3041,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a5f,
+ 0x0000, 0x3a5b, 0x4e76, 0x6a61, 0x6a62, 0x4175, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e22,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6a63, 0x4d35, 0x0000, 0x0000,
+ 0x6a64, 0x6a65, 0x0000, 0x0000, 0x4a64, 0x6a66, 0x0000, 0x3a40,
+ 0x0000, 0x4e23, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6a6b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6a6c, 0x3e58, 0x6a6a, 0x0000, 0x0000, 0x0000,
+ 0x4d67, 0x6a67, 0x0000, 0x0000, 0x6a69, 0x403d, 0x3f7e, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_89[] = {
+ /* 0x8900 - 0x89ff */
+ 0x0000, 0x0000, 0x6a68, 0x0000, 0x6a6d, 0x0000, 0x0000, 0x4a23,
+ 0x0000, 0x0000, 0x6a6f, 0x0000, 0x6a6e, 0x0000, 0x0000, 0x0000,
+ 0x336c, 0x0000, 0x4b2b, 0x6a70, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a7c, 0x6a72, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a73, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6a74, 0x6a75, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a79, 0x0000,
+ 0x6a7a, 0x0000, 0x0000, 0x6a78, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6a76, 0x0000, 0x6a71, 0x6a77, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6a7b, 0x7037, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3228, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a7e, 0x365f,
+ 0x6a7d, 0x0000, 0x0000, 0x0000, 0x6b22, 0x0000, 0x6b21, 0x0000,
+ 0x0000, 0x0000, 0x6b24, 0x0000, 0x0000, 0x6b23, 0x0000, 0x6b25,
+ 0x0000, 0x0000, 0x3d31, 0x0000, 0x6b26, 0x0000, 0x0000, 0x6b27,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b28, 0x403e,
+ 0x0000, 0x4d57, 0x0000, 0x6b29, 0x0000, 0x0000, 0x4a24, 0x4746,
+ 0x6b2a, 0x0000, 0x6b2b, 0x382b, 0x0000, 0x0000, 0x0000, 0x352c,
+ 0x0000, 0x0000, 0x0000, 0x6b2c, 0x0000, 0x0000, 0x3b6b, 0x4741,
+ 0x6b2d, 0x0000, 0x3350, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6b2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b30, 0x4d77,
+ 0x0000, 0x6b2f, 0x3f46, 0x0000, 0x6b31, 0x0000, 0x0000, 0x6b32,
+ 0x0000, 0x0000, 0x6b33, 0x3451, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6b34, 0x0000, 0x0000, 0x6b35, 0x0000, 0x6b36,
+ 0x6b37, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3351, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6b38, 0x0000, 0x6b39, 0x6b3a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3272, 0x0000, 0x0000, 0x3f28, 0x6b3b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6b3c, 0x0000, 0x0000, 0x0000,
+ 0x6b3d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_8a[] = {
+ /* 0x8a00 - 0x8aff */
+ 0x3840, 0x0000, 0x447b, 0x6b3e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3757, 0x0000, 0x3f56, 0x0000, 0x6b41, 0x0000, 0x4624, 0x0000,
+ 0x6b40, 0x0000, 0x0000, 0x3731, 0x0000, 0x0000, 0x6b3f, 0x4277,
+ 0x352d, 0x0000, 0x0000, 0x6b42, 0x0000, 0x6b43, 0x0000, 0x3e59,
+ 0x0000, 0x0000, 0x0000, 0x376d, 0x0000, 0x6b44, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4b2c, 0x0000, 0x0000, 0x405f, 0x0000, 0x0000,
+ 0x0000, 0x3576, 0x0000, 0x4c75, 0x414a, 0x0000, 0x6b45, 0x0000,
+ 0x0000, 0x0000, 0x3f47, 0x4370, 0x3e5a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6b46, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b49, 0x0000,
+ 0x6b4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3a3e, 0x4242, 0x6b48, 0x0000, 0x3e5b, 0x493e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6b47, 0x0000, 0x0000, 0x3b6c, 0x0000,
+ 0x3153, 0x0000, 0x6b4e, 0x3758, 0x0000, 0x0000, 0x3b6e, 0x0000,
+ 0x0000, 0x3b6d, 0x0000, 0x4f4d, 0x6b4d, 0x6b4c, 0x4127, 0x0000,
+ 0x354d, 0x4f43, 0x333a, 0x3e5c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6b4b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6b50, 0x0000, 0x6b51, 0x6b4f, 0x0000, 0x3858,
+ 0x0000, 0x4d40, 0x0000, 0x0000, 0x3b6f, 0x4727, 0x0000, 0x0000,
+ 0x0000, 0x6b54, 0x0000, 0x4040, 0x0000, 0x4342, 0x0000, 0x0000,
+ 0x4d36, 0x0000, 0x6b57, 0x0000, 0x0000, 0x0000, 0x386c, 0x0000,
+ 0x403f, 0x6b53, 0x0000, 0x6b58, 0x386d, 0x6b55, 0x6b56, 0x0000,
+ 0x6b52, 0x0000, 0x0000, 0x0000, 0x4062, 0x4649, 0x0000, 0x0000,
+ 0x432f, 0x0000, 0x325d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4870, 0x0000, 0x0000, 0x3543, 0x0000, 0x0000, 0x4434,
+ 0x0000, 0x0000, 0x6b5b, 0x0000, 0x6b59, 0x0000, 0x0000, 0x434c,
+ 0x0000, 0x0000, 0x0000, 0x4041, 0x3452, 0x6b5a, 0x0000, 0x3f5b,
+ 0x0000, 0x0000, 0x4e4a, 0x0000, 0x0000, 0x0000, 0x4f40, 0x0000,
+ 0x0000, 0x0000, 0x6b5c, 0x6b67, 0x4435, 0x0000, 0x6b66, 0x0000,
+ 0x6b63, 0x6b6b, 0x6b64, 0x0000, 0x6b60, 0x0000, 0x447c, 0x6b5f,
+ 0x0000, 0x0000, 0x0000, 0x6b5d, 0x0000, 0x4d21, 0x3b70, 0x0000,
+ 0x0000, 0x6b61, 0x0000, 0x6b5e, 0x0000, 0x0000, 0x0000, 0x6b65,
+ 0x3d74, 0x0000, 0x3841, 0x0000, 0x0000, 0x0000, 0x427a, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_8b[] = {
+ /* 0x8b00 - 0x8bff */
+ 0x4b45, 0x315a, 0x3062, 0x0000, 0x4625, 0x0000, 0x0000, 0x6b69,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6b68, 0x0000, 0x4666, 0x0000,
+ 0x6b6d, 0x0000, 0x0000, 0x0000, 0x6b62, 0x0000, 0x6b6c, 0x6b6e,
+ 0x0000, 0x382c, 0x6b6a, 0x3956, 0x0000, 0x3c55, 0x0000, 0x0000,
+ 0x6b6f, 0x4d58, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b72, 0x0000,
+ 0x6b75, 0x0000, 0x0000, 0x6b73, 0x4935, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6b70, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3660, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b74, 0x0000,
+ 0x0000, 0x6b76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6b7a, 0x0000, 0x0000, 0x6b77, 0x0000, 0x6b79, 0x6b78,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b7b, 0x0000,
+ 0x3c31, 0x0000, 0x6b7d, 0x6b7c, 0x4968, 0x0000, 0x0000, 0x6c21,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3759, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6b7e, 0x6c22, 0x0000, 0x0000, 0x6c23,
+ 0x3544, 0x6641, 0x3e79, 0x0000, 0x6c24, 0x0000, 0x0000, 0x386e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c25, 0x0000, 0x0000,
+ 0x6c26, 0x0000, 0x0000, 0x3b3e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5a4e, 0x0000, 0x6c27, 0x0000, 0x6c28, 0x0000,
+ 0x3d32, 0x0000, 0x6c29, 0x6c2a, 0x0000, 0x0000, 0x6c2b, 0x0000,
+ 0x0000, 0x6c2c, 0x6c2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_8c[] = {
+ /* 0x8c00 - 0x8cff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x432b,
+ 0x0000, 0x0000, 0x6c2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c30,
+ 0x0000, 0x6c2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4626, 0x0000,
+ 0x6c31, 0x0000, 0x4b2d, 0x0000, 0x6c32, 0x0000, 0x6c33, 0x0000,
+ 0x6c34, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c35, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x465a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3e5d, 0x6c36, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x396b, 0x502e, 0x6c37, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6c38, 0x493f, 0x6c39, 0x0000, 0x6c41, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6c3a, 0x0000, 0x0000, 0x6c3c, 0x0000, 0x0000,
+ 0x0000, 0x6c3b, 0x6c3d, 0x0000, 0x4b46, 0x6c3e, 0x6c3f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6c40, 0x0000, 0x0000, 0x0000,
+ 0x6c42, 0x0000, 0x0000, 0x0000, 0x0000, 0x332d, 0x4467, 0x0000,
+ 0x4969, 0x3a62, 0x3957, 0x0000, 0x0000, 0x0000, 0x0000, 0x494f,
+ 0x325f, 0x484e, 0x6c45, 0x3453, 0x4055, 0x6c44, 0x6c49, 0x4379,
+ 0x4c63, 0x0000, 0x6c47, 0x6c48, 0x352e, 0x0000, 0x6c4a, 0x4763,
+ 0x425f, 0x0000, 0x0000, 0x4871, 0x453d, 0x6c46, 0x0000, 0x4b47,
+ 0x326c, 0x6c4c, 0x4f28, 0x4442, 0x4f45, 0x0000, 0x0000, 0x3b71,
+ 0x6c4b, 0x0000, 0x4231, 0x0000, 0x0000, 0x6c5c, 0x4128, 0x0000,
+ 0x0000, 0x4678, 0x0000, 0x4950, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6c4f, 0x3b3f, 0x3b72, 0x0000, 0x3e5e, 0x0000,
+ 0x4765, 0x0000, 0x382d, 0x6c4e, 0x6c4d, 0x0000, 0x496a, 0x0000,
+ 0x0000, 0x0000, 0x3c41, 0x0000, 0x0000, 0x4552, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6c51, 0x6c52, 0x3958, 0x6c50, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_8d[] = {
+ /* 0x8d00 - 0x8dff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6c53, 0x6c54, 0x0000, 0x6c56,
+ 0x4223, 0x0000, 0x6c55, 0x3466, 0x0000, 0x6c58, 0x0000, 0x6c57,
+ 0x6c59, 0x0000, 0x0000, 0x6c5b, 0x6c5d, 0x0000, 0x6c5e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4056, 0x0000, 0x3c4f, 0x6c5f,
+ 0x0000, 0x0000, 0x0000, 0x3352, 0x0000, 0x6c60, 0x0000, 0x0000,
+ 0x4176, 0x6c61, 0x0000, 0x6c62, 0x496b, 0x0000, 0x0000, 0x352f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6c63, 0x0000, 0x0000, 0x0000, 0x4436, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x315b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6c64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3c71, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3f76, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x422d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6c67, 0x0000, 0x0000, 0x0000, 0x6c66, 0x0000,
+ 0x0000, 0x0000, 0x6c65, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6c6d, 0x6c6b, 0x0000, 0x0000, 0x6c68,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c6a, 0x0000,
+ 0x0000, 0x0000, 0x6c69, 0x6c6c, 0x0000, 0x3577, 0x0000, 0x6c70,
+ 0x0000, 0x4057, 0x0000, 0x6c71, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3859, 0x0000, 0x6c6e, 0x6c6f, 0x0000, 0x0000, 0x0000, 0x4f29,
+ 0x0000, 0x0000, 0x0000, 0x4437, 0x0000, 0x4129, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6c72, 0x0000, 0x0000, 0x6c75,
+};
+
+static unsigned short const tqunicode_to_jisx0208_8e[] = {
+ /* 0x8e00 - 0x8eff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6c73, 0x6c74, 0x4d59, 0x0000, 0x0000, 0x0000, 0x0000, 0x4627,
+ 0x6c78, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c76, 0x6c77, 0x6c79,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6d29, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6c7c, 0x0000, 0x0000, 0x0000, 0x6c7d, 0x6c7b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6c7a, 0x0000, 0x447d, 0x0000, 0x0000, 0x6d21,
+ 0x6d25, 0x6d22, 0x6c7e, 0x0000, 0x6d23, 0x0000, 0x0000, 0x0000,
+ 0x6d24, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d2b, 0x0000, 0x0000,
+ 0x0000, 0x6d26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4058,
+ 0x6d28, 0x0000, 0x0000, 0x6d2a, 0x6d27, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6d2d, 0x0000, 0x3d33, 0x0000, 0x6d2c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6d2e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6d2f, 0x0000, 0x0000, 0x6d32, 0x6d31, 0x0000, 0x6d30,
+ 0x0000, 0x0000, 0x6d34, 0x6d33, 0x0000, 0x4c76, 0x0000, 0x0000,
+ 0x0000, 0x6d36, 0x0000, 0x6d35, 0x6d37, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6d38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6d3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6d39, 0x3f48, 0x6d3b, 0x0000, 0x0000, 0x366d,
+ 0x6d3c, 0x6d3e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d3f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d40, 0x6d3d, 0x0000,
+ 0x6d41, 0x0000, 0x3c56, 0x6d42, 0x3530, 0x3733, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x382e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6d43, 0x0000, 0x0000, 0x0000, 0x4670,
+ 0x0000, 0x0000, 0x453e, 0x6d44, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6d47, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3c34, 0x0000, 0x0000, 0x6d46, 0x6d45, 0x375a, 0x6d48, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_8f[] = {
+ /* 0x8f00 - 0x8fff */
+ 0x0000, 0x0000, 0x0000, 0x3353, 0x0000, 0x6d4a, 0x0000, 0x0000,
+ 0x0000, 0x3a5c, 0x6d49, 0x0000, 0x6d52, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6d4c, 0x6d4e, 0x4a65, 0x6d4b, 0x0000, 0x0000,
+ 0x0000, 0x6d4d, 0x0000, 0x6d51, 0x6d4f, 0x3531, 0x0000, 0x6d50,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d53, 0x0000,
+ 0x0000, 0x475a, 0x4e58, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d34,
+ 0x0000, 0x0000, 0x0000, 0x6d54, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4d22, 0x6d56, 0x0000, 0x6d55, 0x0000, 0x0000, 0x6d59, 0x4d41,
+ 0x0000, 0x0000, 0x6d58, 0x0000, 0x336d, 0x6d57, 0x6d5c, 0x0000,
+ 0x0000, 0x6d5b, 0x0000, 0x0000, 0x6d5a, 0x4532, 0x6d5d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d5e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6d5f, 0x0000, 0x0000, 0x396c,
+ 0x0000, 0x3725, 0x6d60, 0x6d61, 0x6d62, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3f49, 0x6d63, 0x0000, 0x3c2d, 0x6d64,
+ 0x0000, 0x0000, 0x0000, 0x6d65, 0x0000, 0x0000, 0x0000, 0x5221,
+ 0x517e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d66, 0x6570, 0x6d67,
+ 0x4324, 0x3f2b, 0x4740, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d68,
+ 0x0000, 0x0000, 0x4a55, 0x4454, 0x397e, 0x0000, 0x0000, 0x4329,
+ 0x0000, 0x0000, 0x312a, 0x0000, 0x4b78, 0x3f57, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x375e, 0x0000,
+ 0x0000, 0x3661, 0x0000, 0x0000, 0x4a56, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6d69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6d6b, 0x0000, 0x0000, 0x6d6a, 0x3260, 0x0000,
+ 0x0000, 0x4676, 0x6d6c, 0x4777, 0x0000, 0x4533, 0x0000, 0x6d6d,
+ 0x3d52, 0x0000, 0x0000, 0x0000, 0x6d6f, 0x0000, 0x0000, 0x4c42,
+ 0x6d7e, 0x6d71, 0x6d72, 0x0000, 0x0000, 0x4449, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_90[] = {
+ /* 0x9000 - 0x90ff */
+ 0x4260, 0x4177, 0x0000, 0x4628, 0x0000, 0x6d70, 0x3555, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6d79, 0x0000, 0x6d76, 0x6e25, 0x4629,
+ 0x4360, 0x6d73, 0x0000, 0x447e, 0x4553, 0x6d74, 0x6d78, 0x3f60,
+ 0x0000, 0x4767, 0x444c, 0x0000, 0x0000, 0x4042, 0x6d77, 0x422e,
+ 0x4224, 0x6d75, 0x3029, 0x4f22, 0x0000, 0x0000, 0x0000, 0x6d7a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4261, 0x0000,
+ 0x0000, 0x3d35, 0x3f4a, 0x0000, 0x0000, 0x6d7c, 0x6d7b, 0x0000,
+ 0x306f, 0x6d7d, 0x0000, 0x0000, 0x492f, 0x0000, 0x6e27, 0x0000,
+ 0x0000, 0x465b, 0x3f6b, 0x0000, 0x0000, 0x4359, 0x0000, 0x3678,
+ 0x0000, 0x6e26, 0x4d37, 0x313f, 0x0000, 0x4a57, 0x3261, 0x6e21,
+ 0x6e22, 0x6e23, 0x6e24, 0x463b, 0x4323, 0x3063, 0x6e28, 0x0000,
+ 0x6e29, 0x7423, 0x0000, 0x0000, 0x423d, 0x0000, 0x6e2a, 0x0000,
+ 0x3173, 0x414c, 0x0000, 0x382f, 0x0000, 0x4d5a, 0x0000, 0x0000,
+ 0x6e2b, 0x452c, 0x0000, 0x0000, 0x0000, 0x4178, 0x3c57, 0x6e2c,
+ 0x0000, 0x0000, 0x6e2f, 0x0000, 0x0000, 0x3d65, 0x6e2d, 0x412b,
+ 0x412a, 0x0000, 0x3064, 0x0000, 0x4e4b, 0x6e31, 0x0000, 0x4872,
+ 0x6e33, 0x6e32, 0x6e30, 0x6364, 0x3454, 0x0000, 0x0000, 0x6d6e,
+ 0x0000, 0x6e35, 0x6e34, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e36,
+ 0x0000, 0x4d38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4661, 0x0000, 0x0000, 0x4b2e, 0x0000,
+ 0x6e37, 0x0000, 0x3c59, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e38,
+ 0x0000, 0x6e39, 0x0000, 0x0000, 0x0000, 0x6e3a, 0x0000, 0x0000,
+ 0x4521, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x306a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3959, 0x0000, 0x0000, 0x0000, 0x4f3a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6e3e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3734, 0x6e3b, 0x0000, 0x6e3c, 0x0000, 0x0000, 0x0000,
+ 0x4974, 0x0000, 0x0000, 0x0000, 0x0000, 0x3354, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d39, 0x0000, 0x363f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4554, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_91[] = {
+ /* 0x9100 - 0x91ff */
+ 0x0000, 0x0000, 0x6e3f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6e40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6e41, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4522, 0x0000, 0x0000,
+ 0x6e43, 0x0000, 0x6e42, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4653, 0x6e44, 0x3d36, 0x3c60, 0x475b, 0x4371, 0x0000,
+ 0x0000, 0x0000, 0x3c72, 0x0000, 0x3f6c, 0x0000, 0x6e45, 0x0000,
+ 0x6e46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3f5d, 0x6e47, 0x0000, 0x6e48, 0x0000, 0x0000,
+ 0x0000, 0x6e49, 0x4d6f, 0x0000, 0x3d37, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6e4b, 0x6e4a, 0x0000, 0x395a, 0x0000, 0x3973,
+ 0x3b40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6e4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d66,
+ 0x0000, 0x6e4d, 0x0000, 0x6e4c, 0x0000, 0x4269, 0x0000, 0x0000,
+ 0x386f, 0x0000, 0x4043, 0x0000, 0x0000, 0x0000, 0x0000, 0x4830,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3d39, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6e4f, 0x0000, 0x3e5f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6e52, 0x6e50, 0x0000, 0x0000, 0x0000, 0x6e51,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6e54, 0x6e53, 0x0000, 0x0000,
+ 0x3e7a, 0x0000, 0x6e55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6e56, 0x6e57, 0x0000, 0x0000, 0x0000, 0x0000, 0x4850, 0x3a53,
+ 0x3c61, 0x6e58, 0x0000, 0x6e59, 0x4e24, 0x3d45, 0x4c6e, 0x4e4c,
+ 0x6e5a, 0x3662, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e5b, 0x0000,
+ 0x4523, 0x0000, 0x0000, 0x6e5e, 0x3378, 0x3f4b, 0x0000, 0x6e5c,
+ 0x0000, 0x6e5d, 0x0000, 0x4460, 0x0000, 0x0000, 0x4b55, 0x367c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e60, 0x6e61, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6e5f, 0x0000, 0x0000, 0x6e63,
+};
+
+static unsigned short const tqunicode_to_jisx0208_92[] = {
+ /* 0x9200 - 0x92ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x465f, 0x3343, 0x0000,
+ 0x0000, 0x6e67, 0x0000, 0x0000, 0x6e64, 0x6e66, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e62, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6f4f, 0x0000, 0x0000, 0x6e65, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4e6b, 0x0000, 0x0000, 0x385a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e6f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4534, 0x6e6a, 0x0000, 0x0000,
+ 0x6e6d, 0x6e6b, 0x0000, 0x6e70, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6e71, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e69,
+ 0x0000, 0x0000, 0x6e76, 0x3174, 0x0000, 0x0000, 0x6e68, 0x0000,
+ 0x0000, 0x0000, 0x482d, 0x0000, 0x6e6c, 0x0000, 0x3e60, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x395b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b48, 0x0000,
+ 0x3664, 0x0000, 0x0000, 0x3d46, 0x0000, 0x463c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x412d, 0x0000, 0x6e74, 0x0000, 0x6e6e, 0x6e73, 0x0000,
+ 0x4c43, 0x0000, 0x4438, 0x6e75, 0x6e72, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x412c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e79,
+ 0x0000, 0x6e78, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e77,
+ 0x0000, 0x0000, 0x4b2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3d7b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6e7a, 0x4a5f, 0x0000, 0x0000, 0x3154, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4946, 0x4372, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3578, 0x0000, 0x6e7c, 0x0000, 0x395d, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_93[] = {
+ /* 0x9300 - 0x93ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b2c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6e7b,
+ 0x3f6d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3f6e, 0x6f21, 0x6f23, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3e7b, 0x0000, 0x6f22, 0x6f24, 0x0000, 0x0000, 0x3653, 0x0000,
+ 0x4945, 0x0000, 0x0000, 0x3c62, 0x4f23, 0x0000, 0x6e7e, 0x3a78,
+ 0x0000, 0x0000, 0x4f3f, 0x0000, 0x0000, 0x6f26, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6f25, 0x6f27, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6e7d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4669, 0x0000, 0x4555, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4457, 0x0000, 0x6f2c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4343, 0x6f28, 0x0000, 0x0000, 0x0000,
+ 0x6f29, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x372d, 0x0000, 0x6f2b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3830, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6f2a, 0x0000, 0x3e61, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3379, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6f30, 0x0000, 0x3a3f, 0x4179,
+ 0x0000, 0x0000, 0x444a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x333b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6f2e, 0x6f2f, 0x4443, 0x0000,
+ 0x6f2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6f31, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6f37, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6f3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6f39, 0x452d, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f32, 0x6f33,
+ 0x6f36, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f38, 0x0000, 0x0000,
+ 0x0000, 0x3640, 0x0000, 0x0000, 0x6f3b, 0x6f35, 0x0000, 0x0000,
+ 0x6f34, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_94[] = {
+ /* 0x9400 - 0x94ff */
+ 0x0000, 0x0000, 0x0000, 0x6f3f, 0x0000, 0x0000, 0x0000, 0x6f40,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6f41, 0x0000, 0x0000, 0x6f3e, 0x6f3d, 0x0000, 0x0000, 0x0000,
+ 0x3e62, 0x462a, 0x6f3c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6f45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6f43, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f44, 0x6f42, 0x0000,
+ 0x4278, 0x0000, 0x6f46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6f47, 0x0000, 0x0000, 0x6f49, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3455, 0x6f48, 0x4c7a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6f54, 0x6f4a, 0x0000, 0x0000, 0x6f4d, 0x0000,
+ 0x6f4b, 0x0000, 0x6f4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6f4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6f50, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f51, 0x0000, 0x6f52,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6f55, 0x6f53, 0x6f56, 0x6f58,
+ 0x0000, 0x6f57, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_95[] = {
+ /* 0x9500 - 0x95ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4439,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4c67, 0x0000, 0x6f59, 0x412e, 0x0000, 0x0000, 0x0000, 0x6f5a,
+ 0x0000, 0x4a44, 0x6f5b, 0x332b, 0x0000, 0x0000, 0x0000, 0x313c,
+ 0x0000, 0x3457, 0x0000, 0x3456, 0x6f5c, 0x0000, 0x6f5d, 0x0000,
+ 0x6f5e, 0x6f5f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6f60, 0x0000, 0x3458, 0x3355, 0x395e, 0x4836, 0x0000, 0x6f62,
+ 0x6f61, 0x0000, 0x0000, 0x0000, 0x0000, 0x6f63, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x315c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6f66, 0x0000, 0x6f65, 0x6f64, 0x0000, 0x6f67, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6f6a, 0x0000, 0x0000, 0x0000, 0x3047,
+ 0x0000, 0x0000, 0x6f68, 0x0000, 0x6f6c, 0x6f6b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6f6e, 0x6f6d, 0x6f6f, 0x0000,
+ 0x462e, 0x0000, 0x0000, 0x0000, 0x6f70, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6f71, 0x6f73, 0x0000, 0x0000, 0x6f72, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_96[] = {
+ /* 0x9600 - 0x96ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x496c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6f74, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6f75, 0x0000, 0x3a65, 0x0000, 0x0000, 0x0000, 0x6f76, 0x6f77,
+ 0x0000, 0x0000, 0x4b49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x414b, 0x0000, 0x0000, 0x0000, 0x3024,
+ 0x424b, 0x0000, 0x6f78, 0x0000, 0x496d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6f7b, 0x6f79, 0x395f, 0x0000, 0x6f7a,
+ 0x3842, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a45, 0x6f7d, 0x7021, 0x6f7e, 0x7022,
+ 0x0000, 0x0000, 0x3121, 0x3f58, 0x3d7c, 0x3459, 0x7023, 0x0000,
+ 0x0000, 0x0000, 0x4766, 0x0000, 0x7025, 0x0000, 0x0000, 0x0000,
+ 0x3122, 0x0000, 0x7024, 0x4444, 0x0000, 0x4e4d, 0x462b, 0x6f7c,
+ 0x4e26, 0x0000, 0x3831, 0x0000, 0x0000, 0x4d5b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3679, 0x4e34, 0x0000,
+ 0x3728, 0x0000, 0x4262, 0x6721, 0x0000, 0x7026, 0x332c, 0x3f6f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3356, 0x7028, 0x0000, 0x7029,
+ 0x7027, 0x3764, 0x0000, 0x3a5d, 0x3e63, 0x0000, 0x0000, 0x0000,
+ 0x3123, 0x0000, 0x0000, 0x4e59, 0x0000, 0x0000, 0x0000, 0x702b,
+ 0x6e2e, 0x0000, 0x702a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x702e, 0x702c, 0x702d, 0x0000, 0x702f, 0x0000, 0x7030, 0x4e6c,
+ 0x7031, 0x7032, 0x0000, 0x4049, 0x483b, 0x0000, 0x0000, 0x0000,
+ 0x3f7d, 0x3467, 0x0000, 0x0000, 0x4d3a, 0x326d, 0x3d38, 0x385b,
+ 0x0000, 0x7035, 0x0000, 0x7034, 0x3b73, 0x7036, 0x7033, 0x0000,
+ 0x0000, 0x3b28, 0x0000, 0x0000, 0x0000, 0x703a, 0x6a2d, 0x0000,
+ 0x0000, 0x5256, 0x0000, 0x3f77, 0x7038, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4e25, 0x4671, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x312b, 0x0000, 0x4063, 0x3c36, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4a37, 0x0000, 0x3140, 0x0000, 0x0000, 0x0000, 0x4e6d, 0x4d6b,
+ 0x0000, 0x703b, 0x0000, 0x4545, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_97[] = {
+ /* 0x9700 - 0x97ff */
+ 0x3c7b, 0x0000, 0x0000, 0x0000, 0x703c, 0x0000, 0x703d, 0x3f4c,
+ 0x703e, 0x0000, 0x4e6e, 0x0000, 0x0000, 0x7039, 0x7040, 0x7042,
+ 0x0000, 0x7041, 0x0000, 0x703f, 0x0000, 0x0000, 0x7043, 0x0000,
+ 0x0000, 0x7044, 0x0000, 0x0000, 0x417a, 0x0000, 0x3262, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x7045, 0x0000, 0x0000, 0x4c38,
+ 0x0000, 0x0000, 0x7046, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7047, 0x0000, 0x4f2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5b31, 0x7048, 0x0000, 0x0000, 0x0000, 0x7049, 0x704a, 0x0000,
+ 0x0000, 0x0000, 0x704e, 0x0000, 0x704b, 0x0000, 0x704c, 0x0000,
+ 0x704d, 0x704f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4044, 0x0000, 0x0000, 0x0000, 0x4c77, 0x0000,
+ 0x0000, 0x4045, 0x0000, 0x0000, 0x7050, 0x0000, 0x4873, 0x0000,
+ 0x7051, 0x7353, 0x4c4c, 0x0000, 0x7052, 0x0000, 0x7053, 0x0000,
+ 0x7054, 0x3357, 0x0000, 0x7056, 0x0000, 0x3f59, 0x0000, 0x0000,
+ 0x0000, 0x7057, 0x0000, 0x0000, 0x3724, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x7058, 0x705c, 0x0000, 0x705a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x705b, 0x0000, 0x0000, 0x3373, 0x7059, 0x705d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x705e, 0x0000, 0x3048, 0x0000, 0x705f,
+ 0x7060, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3e64, 0x0000, 0x0000, 0x0000, 0x7061, 0x0000, 0x0000, 0x0000,
+ 0x3547, 0x0000, 0x0000, 0x7064, 0x0000, 0x0000, 0x7063, 0x0000,
+ 0x7062, 0x0000, 0x0000, 0x6b71, 0x0000, 0x4a5c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x7065, 0x7066, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x7067, 0x0000, 0x0000, 0x7068, 0x0000,
+ 0x7069, 0x0000, 0x0000, 0x706a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x345a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x706b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x706c, 0x4723, 0x0000,
+ 0x0000, 0x0000, 0x706e, 0x323b, 0x0000, 0x7071, 0x7070, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3124, 0x0000, 0x0000, 0x0000, 0x3641,
+};
+
+static unsigned short const tqunicode_to_jisx0208_98[] = {
+ /* 0x9800 - 0x98ff */
+ 0x0000, 0x4a47, 0x443a, 0x3a22, 0x0000, 0x3960, 0x3d67, 0x0000,
+ 0x3f5c, 0x0000, 0x0000, 0x0000, 0x7073, 0x0000, 0x0000, 0x7072,
+ 0x4d42, 0x3468, 0x4852, 0x465c, 0x0000, 0x0000, 0x0000, 0x3f7c,
+ 0x4e4e, 0x0000, 0x375b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x7076, 0x0000, 0x0000, 0x7075, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4b4b, 0x462c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3150, 0x0000, 0x0000, 0x7077,
+ 0x7074, 0x0000, 0x0000, 0x4951, 0x4d6a, 0x7078, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7079, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x707b, 0x426a, 0x335b, 0x335c, 0x707a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3469, 0x3832, 0x0000, 0x0000,
+ 0x346a, 0x0000, 0x0000, 0x453f, 0x0000, 0x0000, 0x4e60, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x385c,
+ 0x0000, 0x0000, 0x0000, 0x707c, 0x0000, 0x0000, 0x0000, 0x707d,
+ 0x707e, 0x7121, 0x0000, 0x7123, 0x7122, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4977, 0x0000, 0x7124, 0x0000, 0x0000, 0x0000, 0x0000, 0x7125,
+ 0x0000, 0x7126, 0x0000, 0x0000, 0x0000, 0x0000, 0x7127, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x7129, 0x7128, 0x0000, 0x712a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4874, 0x664c, 0x0000, 0x0000, 0x3f29,
+ 0x0000, 0x0000, 0x3532, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x712b, 0x0000, 0x712c, 0x0000, 0x522c, 0x5d3b, 0x4853,
+ 0x0000, 0x0000, 0x307b, 0x0000, 0x303b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3b74, 0x4b30, 0x3e7e, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_99[] = {
+ /* 0x9900 - 0x99ff */
+ 0x0000, 0x0000, 0x0000, 0x712d, 0x0000, 0x4c5f, 0x0000, 0x0000,
+ 0x0000, 0x712e, 0x4d5c, 0x0000, 0x3142, 0x0000, 0x0000, 0x0000,
+ 0x3b41, 0x0000, 0x712f, 0x326e, 0x7130, 0x0000, 0x0000, 0x0000,
+ 0x7131, 0x0000, 0x0000, 0x0000, 0x0000, 0x7133, 0x7134, 0x0000,
+ 0x7136, 0x7132, 0x0000, 0x0000, 0x7135, 0x0000, 0x0000, 0x0000,
+ 0x345b, 0x0000, 0x0000, 0x0000, 0x7137, 0x0000, 0x7138, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7139, 0x713a, 0x0000,
+ 0x0000, 0x0000, 0x713b, 0x0000, 0x0000, 0x713d, 0x0000, 0x0000,
+ 0x0000, 0x713c, 0x0000, 0x713f, 0x7142, 0x0000, 0x0000, 0x0000,
+ 0x713e, 0x7140, 0x7141, 0x0000, 0x0000, 0x7143, 0x0000, 0x3642,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c73, 0x7144,
+ 0x7145, 0x3961, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7146, 0x0000, 0x0000,
+ 0x333e, 0x0000, 0x0000, 0x0000, 0x474f, 0x7147, 0x7148, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x435a, 0x466b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x7149, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x477d, 0x0000, 0x0000, 0x424c, 0x3158, 0x366e, 0x0000,
+ 0x366f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4373, 0x714e, 0x3670, 0x0000, 0x0000, 0x326f, 0x0000, 0x0000,
+ 0x714d, 0x0000, 0x0000, 0x714b, 0x0000, 0x714c, 0x0000, 0x714a,
+ 0x0000, 0x0000, 0x7158, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x714f, 0x7150, 0x0000,
+ 0x0000, 0x7151, 0x7152, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7154, 0x0000, 0x0000, 0x7153, 0x0000, 0x0000, 0x0000, 0x3d59,
+};
+
+static unsigned short const tqunicode_to_jisx0208_9a[] = {
+ /* 0x9a00 - 0x9aff */
+ 0x0000, 0x7155, 0x0000, 0x0000, 0x0000, 0x7157, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3533, 0x7156,
+ 0x0000, 0x0000, 0x417b, 0x3833, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x7159, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x424d, 0x0000, 0x0000, 0x715a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x462d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x715b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7160, 0x0000,
+ 0x715e, 0x0000, 0x715d, 0x715f, 0x0000, 0x715c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7162, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7161, 0x0000, 0x7164,
+ 0x0000, 0x0000, 0x3643, 0x7163, 0x0000, 0x0000, 0x0000, 0x7165,
+ 0x0000, 0x0000, 0x7166, 0x0000, 0x7168, 0x7167, 0x0000, 0x0000,
+ 0x0000, 0x7169, 0x716b, 0x716a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x397c, 0x0000, 0x0000, 0x0000, 0x0000, 0x716c, 0x0000, 0x0000,
+ 0x716d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x333c, 0x0000, 0x0000, 0x0000, 0x716e, 0x0000, 0x0000, 0x0000,
+ 0x716f, 0x0000, 0x0000, 0x0000, 0x3f71, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7170,
+ 0x0000, 0x7171, 0x0000, 0x7172, 0x7173, 0x0000, 0x0000, 0x0000,
+ 0x3962, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7174, 0x7175,
+ 0x0000, 0x0000, 0x7176, 0x7177, 0x0000, 0x0000, 0x7178, 0x0000,
+ 0x0000, 0x0000, 0x4831, 0x717a, 0x0000, 0x4926, 0x717b, 0x7179,
+ 0x0000, 0x717d, 0x0000, 0x0000, 0x717c, 0x0000, 0x0000, 0x717e,
+ 0x0000, 0x0000, 0x0000, 0x7221, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_9b[] = {
+ /* 0x9b00 - 0x9bff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7222, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7223, 0x0000, 0x7224, 0x0000, 0x0000, 0x0000, 0x0000, 0x7225,
+ 0x0000, 0x0000, 0x7226, 0x7227, 0x0000, 0x7228, 0x0000, 0x7229,
+ 0x722a, 0x722b, 0x722c, 0x0000, 0x0000, 0x0000, 0x722d, 0x722e,
+ 0x0000, 0x5d35, 0x722f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6478, 0x3534, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3321, 0x3a32, 0x7231, 0x7230, 0x4c25, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7233, 0x7234, 0x7232,
+ 0x0000, 0x7235, 0x0000, 0x0000, 0x4b62, 0x0000, 0x0000, 0x0000,
+ 0x7236, 0x0000, 0x357b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f25,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x7237, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x7239, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x303e, 0x0000,
+ 0x0000, 0x723a, 0x4a2b, 0x7238, 0x0000, 0x0000, 0x723b, 0x723c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x723d,
+ 0x723e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x723f, 0x0000, 0x4b6e, 0x3b2d, 0x0000, 0x3a7a, 0x412f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x7240, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x7243, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7241, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7244, 0x0000,
+ 0x0000, 0x3871, 0x7242, 0x0000, 0x0000, 0x0000, 0x0000, 0x7245,
+ 0x0000, 0x7246, 0x7247, 0x0000, 0x724b, 0x0000, 0x3b2a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4264, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x724c, 0x7249, 0x7248, 0x724a, 0x0000, 0x0000, 0x0000,
+ 0x375f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7250, 0x724f, 0x724e, 0x0000, 0x0000, 0x3033, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_9c[] = {
+ /* 0x9c00 - 0x9cff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x725a, 0x0000, 0x7256, 0x0000,
+ 0x7257, 0x7253, 0x7259, 0x0000, 0x7255, 0x3362, 0x0000, 0x0000,
+ 0x4f4c, 0x0000, 0x7258, 0x7254, 0x7252, 0x7251, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x725c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x725f, 0x0000, 0x0000, 0x725e, 0x725d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4949, 0x725b, 0x3073,
+ 0x7260, 0x0000, 0x7262, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x336f, 0x724d, 0x3137, 0x0000, 0x0000, 0x7264, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7263, 0x7261,
+ 0x432d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4b70, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e5a,
+ 0x0000, 0x0000, 0x7265, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7266, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7267,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7268, 0x0000,
+ 0x7269, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x443b, 0x0000, 0x726a,
+ 0x0000, 0x4837, 0x0000, 0x726f, 0x726b, 0x0000, 0x0000, 0x0000,
+ 0x726c, 0x0000, 0x0000, 0x4b31, 0x4c44, 0x0000, 0x4650, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_9d[] = {
+ /* 0x9d00 - 0x9dff */
+ 0x0000, 0x0000, 0x0000, 0x7270, 0x0000, 0x0000, 0x7271, 0x463e,
+ 0x726e, 0x726d, 0x0000, 0x0000, 0x0000, 0x0000, 0x322a, 0x0000,
+ 0x0000, 0x0000, 0x7279, 0x0000, 0x0000, 0x7278, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3175, 0x0000, 0x0000, 0x0000, 0x7276,
+ 0x0000, 0x0000, 0x0000, 0x7275, 0x0000, 0x0000, 0x7273, 0x0000,
+ 0x337b, 0x0000, 0x7272, 0x3c32, 0x3229, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3963, 0x0000, 0x0000, 0x727c, 0x727b,
+ 0x0000, 0x727a, 0x0000, 0x0000, 0x7277, 0x0000, 0x727d, 0x0000,
+ 0x727e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7325, 0x7324, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x7326, 0x0000, 0x0000, 0x312d, 0x7321, 0x7322, 0x0000,
+ 0x3974, 0x4c39, 0x0000, 0x0000, 0x7323, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4b32, 0x0000, 0x0000, 0x732b,
+ 0x0000, 0x0000, 0x7327, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x732c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7329,
+ 0x0000, 0x7328, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x375c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x732d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x732e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x732f, 0x0000, 0x732a, 0x0000, 0x0000, 0x0000, 0x7274,
+ 0x0000, 0x0000, 0x7330, 0x0000, 0x4461, 0x0000, 0x0000, 0x0000,
+ 0x7334, 0x0000, 0x7335, 0x7333, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x7332, 0x7338, 0x0000, 0x7331, 0x0000, 0x7336, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7337,
+ 0x0000, 0x0000, 0x0000, 0x733a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x7339, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x733c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x733d, 0x0000, 0x733e,
+ 0x0000, 0x0000, 0x4f49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x733b, 0x426b, 0x3a6d, 0x0000, 0x0000, 0x733f, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_9e[] = {
+ /* 0x9e00 - 0x9eff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x7340, 0x7341, 0x0000, 0x0000, 0x7342, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7343, 0x0000, 0x0000,
+ 0x3834, 0x7344, 0x0000, 0x0000, 0x0000, 0x7345, 0x0000, 0x3c2f,
+ 0x0000, 0x7346, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7347, 0x0000, 0x0000, 0x7348, 0x7349, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x734c, 0x734a, 0x4f3c, 0x0000, 0x734b, 0x0000, 0x4e6f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x734d, 0x0000, 0x4e5b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x734e, 0x477e, 0x0000,
+ 0x0000, 0x734f, 0x7351, 0x0000, 0x0000, 0x7352, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7350, 0x396d, 0x4c4d, 0x4b63, 0x5677, 0x0000, 0x5d60, 0x4b7b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x322b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x7354, 0x3550, 0x7355, 0x7356,
+ 0x7357, 0x0000, 0x3975, 0x0000, 0x7358, 0x0000, 0x0000, 0x0000,
+ 0x6054, 0x4c5b, 0x0000, 0x4263, 0x7359, 0x735b, 0x735a, 0x0000,
+ 0x735c, 0x0000, 0x0000, 0x0000, 0x0000, 0x735d, 0x0000, 0x0000,
+ 0x735e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x735f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x7360, 0x0000, 0x7361, 0x7362,
+ 0x0000, 0x7363, 0x0000, 0x7364, 0x7365, 0x7366, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_9f[] = {
+ /* 0x9f00 - 0x9fff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7367,
+ 0x7368, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4524, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x385d, 0x0000, 0x736a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x414d, 0x736b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x736c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4921, 0x0000, 0x0000, 0x736d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x736e, 0x6337, 0x0000, 0x0000, 0x6c5a, 0x706d,
+ 0x0000, 0x0000, 0x736f, 0x0000, 0x7370, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7372,
+ 0x7373, 0x7374, 0x4e70, 0x7371, 0x0000, 0x0000, 0x7375, 0x7376,
+ 0x0000, 0x0000, 0x7378, 0x0000, 0x7377, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x737a, 0x0000, 0x0000, 0x0000, 0x737b, 0x7379,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e36, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x737c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x737d, 0x6354, 0x0000, 0x0000,
+ 0x737e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0208_ff[] = {
+ /* 0xff00 - 0xffff */
+ 0x0000, 0x212a, 0x2149, 0x2174, 0x2170, 0x2173, 0x2175, 0x216d,
+ 0x214a, 0x214b, 0x2176, 0x215c, 0x2124, 0x213e, 0x2125, 0x213f,
+ 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337,
+ 0x2338, 0x2339, 0x2127, 0x2128, 0x2163, 0x2161, 0x2164, 0x2129,
+ 0x2177, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347,
+ 0x2348, 0x2349, 0x234a, 0x234b, 0x234c, 0x234d, 0x234e, 0x234f,
+ 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357,
+ 0x2358, 0x2359, 0x235a, 0x214e, 0x2140, 0x214f, 0x2130, 0x2132,
+ 0x212e, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367,
+ 0x2368, 0x2369, 0x236a, 0x236b, 0x236c, 0x236d, 0x236e, 0x236f,
+ 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377,
+ 0x2378, 0x2379, 0x237a, 0x2150, 0x2143, 0x2151, 0x2141, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2131, 0x0000, 0x216f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const * const tqunicode_to_jisx0208_map[0x100] = {
+ /* 0x00XX - 0x0fXX */
+ tqunicode_to_jisx0208_00,
+ 0, 0,
+ tqunicode_to_jisx0208_03,
+ tqunicode_to_jisx0208_04,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x10XX - 0x1fXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x20XX - 0x2fXX */
+ tqunicode_to_jisx0208_20,
+ tqunicode_to_jisx0208_21,
+ tqunicode_to_jisx0208_22,
+ tqunicode_to_jisx0208_23,
+ tqunicode_to_jisx0208_24,
+ tqunicode_to_jisx0208_25,
+ tqunicode_to_jisx0208_26,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x30XX - 0x3fXX */
+ tqunicode_to_jisx0208_30,
+ 0,
+ tqunicode_to_jisx0208_32,
+ tqunicode_to_jisx0208_33,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x40XX - 0x4fXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ tqunicode_to_jisx0208_4e,
+ tqunicode_to_jisx0208_4f,
+ /* 0x50XX - 0x5fXX */
+ tqunicode_to_jisx0208_50,
+ tqunicode_to_jisx0208_51,
+ tqunicode_to_jisx0208_52,
+ tqunicode_to_jisx0208_53,
+ tqunicode_to_jisx0208_54,
+ tqunicode_to_jisx0208_55,
+ tqunicode_to_jisx0208_56,
+ tqunicode_to_jisx0208_57,
+ tqunicode_to_jisx0208_58,
+ tqunicode_to_jisx0208_59,
+ tqunicode_to_jisx0208_5a,
+ tqunicode_to_jisx0208_5b,
+ tqunicode_to_jisx0208_5c,
+ tqunicode_to_jisx0208_5d,
+ tqunicode_to_jisx0208_5e,
+ tqunicode_to_jisx0208_5f,
+ /* 0x60XX - 0x6fXX */
+ tqunicode_to_jisx0208_60,
+ tqunicode_to_jisx0208_61,
+ tqunicode_to_jisx0208_62,
+ tqunicode_to_jisx0208_63,
+ tqunicode_to_jisx0208_64,
+ tqunicode_to_jisx0208_65,
+ tqunicode_to_jisx0208_66,
+ tqunicode_to_jisx0208_67,
+ tqunicode_to_jisx0208_68,
+ tqunicode_to_jisx0208_69,
+ tqunicode_to_jisx0208_6a,
+ tqunicode_to_jisx0208_6b,
+ tqunicode_to_jisx0208_6c,
+ tqunicode_to_jisx0208_6d,
+ tqunicode_to_jisx0208_6e,
+ tqunicode_to_jisx0208_6f,
+ /* 0x70XX - 0x7fXX */
+ tqunicode_to_jisx0208_70,
+ tqunicode_to_jisx0208_71,
+ tqunicode_to_jisx0208_72,
+ tqunicode_to_jisx0208_73,
+ tqunicode_to_jisx0208_74,
+ tqunicode_to_jisx0208_75,
+ tqunicode_to_jisx0208_76,
+ tqunicode_to_jisx0208_77,
+ tqunicode_to_jisx0208_78,
+ tqunicode_to_jisx0208_79,
+ tqunicode_to_jisx0208_7a,
+ tqunicode_to_jisx0208_7b,
+ tqunicode_to_jisx0208_7c,
+ tqunicode_to_jisx0208_7d,
+ tqunicode_to_jisx0208_7e,
+ tqunicode_to_jisx0208_7f,
+ /* 0x80XX - 0x8fXX */
+ tqunicode_to_jisx0208_80,
+ tqunicode_to_jisx0208_81,
+ tqunicode_to_jisx0208_82,
+ tqunicode_to_jisx0208_83,
+ tqunicode_to_jisx0208_84,
+ tqunicode_to_jisx0208_85,
+ tqunicode_to_jisx0208_86,
+ tqunicode_to_jisx0208_87,
+ tqunicode_to_jisx0208_88,
+ tqunicode_to_jisx0208_89,
+ tqunicode_to_jisx0208_8a,
+ tqunicode_to_jisx0208_8b,
+ tqunicode_to_jisx0208_8c,
+ tqunicode_to_jisx0208_8d,
+ tqunicode_to_jisx0208_8e,
+ tqunicode_to_jisx0208_8f,
+ /* 0x90XX - 0x9fXX */
+ tqunicode_to_jisx0208_90,
+ tqunicode_to_jisx0208_91,
+ tqunicode_to_jisx0208_92,
+ tqunicode_to_jisx0208_93,
+ tqunicode_to_jisx0208_94,
+ tqunicode_to_jisx0208_95,
+ tqunicode_to_jisx0208_96,
+ tqunicode_to_jisx0208_97,
+ tqunicode_to_jisx0208_98,
+ tqunicode_to_jisx0208_99,
+ tqunicode_to_jisx0208_9a,
+ tqunicode_to_jisx0208_9b,
+ tqunicode_to_jisx0208_9c,
+ tqunicode_to_jisx0208_9d,
+ tqunicode_to_jisx0208_9e,
+ tqunicode_to_jisx0208_9f,
+ /* 0xa0XX - 0xafXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xb0XX - 0xbfXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xc0XX - 0xcfXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xd0XX - 0xdfXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xe0XX - 0xefXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xf0XX - 0xffXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ tqunicode_to_jisx0208_ff,
+};
+
+static uint tqunicode11ToJisx0208(uint h, uint l)
+{
+ unsigned short const *table;
+
+ table = tqunicode_to_jisx0208_map[h];
+ if (table != 0) {
+ return table[l];
+ }
+ return 0x0000;
+}
+
+#ifdef USE_JISX0212
+
+/*
+ * This data is derived from Unicode 1.1,
+ * JIS X 0212 (1990) to Unicode mapping table version 0.9 .
+ * (In addition IBM Vender Defined Char included)
+ */
+static unsigned short const jisx0212_to_tqunicode[] = {
+ /* 0x2121 - 0x217e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2221 - 0x227e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x02d8,
+ 0x02c7, 0x00b8, 0x02d9, 0x02dd, 0x00af, 0x02db, 0x02da, 0x007e,
+ 0x0384, 0x0385, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x00a1, 0x00a6, 0x00bf, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x00ba, 0x00aa, 0x00a9, 0x00ae, 0x2122,
+ 0x00a4, 0x2116, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2321 - 0x237e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2421 - 0x247e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2521 - 0x257e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2621 - 0x267e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c,
+ 0x0000, 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc,
+ 0x03c2, 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000,
+ /* 0x2721 - 0x277e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
+ 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x040e, 0x040f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
+ 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x045e, 0x045f,
+ /* 0x2821 - 0x287e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2921 - 0x297e */
+ 0x00c6, 0x0110, 0x0000, 0x0126, 0x0000, 0x0132, 0x0000,
+ 0x0141, 0x013f, 0x0000, 0x014a, 0x00d8, 0x0152, 0x0000, 0x0166,
+ 0x00de, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0138,
+ 0x0142, 0x0140, 0x0149, 0x014b, 0x00f8, 0x0153, 0x00df, 0x0167,
+ 0x00fe, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2a21 - 0x2a7e */
+ 0x00c1, 0x00c0, 0x00c4, 0x00c2, 0x0102, 0x01cd, 0x0100,
+ 0x0104, 0x00c5, 0x00c3, 0x0106, 0x0108, 0x010c, 0x00c7, 0x010a,
+ 0x010e, 0x00c9, 0x00c8, 0x00cb, 0x00ca, 0x011a, 0x0116, 0x0112,
+ 0x0118, 0x0000, 0x011c, 0x011e, 0x0122, 0x0120, 0x0124, 0x00cd,
+ 0x00cc, 0x00cf, 0x00ce, 0x01cf, 0x0130, 0x012a, 0x012e, 0x0128,
+ 0x0134, 0x0136, 0x0139, 0x013d, 0x013b, 0x0143, 0x0147, 0x0145,
+ 0x00d1, 0x00d3, 0x00d2, 0x00d6, 0x00d4, 0x01d1, 0x0150, 0x014c,
+ 0x00d5, 0x0154, 0x0158, 0x0156, 0x015a, 0x015c, 0x0160, 0x015e,
+ 0x0164, 0x0162, 0x00da, 0x00d9, 0x00dc, 0x00db, 0x016c, 0x01d3,
+ 0x0170, 0x016a, 0x0172, 0x016e, 0x0168, 0x01d7, 0x01db, 0x01d9,
+ 0x01d5, 0x0174, 0x00dd, 0x0178, 0x0176, 0x0179, 0x017d, 0x017b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2b21 - 0x2b7e */
+ 0x00e1, 0x00e0, 0x00e4, 0x00e2, 0x0103, 0x01ce, 0x0101,
+ 0x0105, 0x00e5, 0x00e3, 0x0107, 0x0109, 0x010d, 0x00e7, 0x010b,
+ 0x010f, 0x00e9, 0x00e8, 0x00eb, 0x00ea, 0x011b, 0x0117, 0x0113,
+ 0x0119, 0x01f5, 0x011d, 0x011f, 0x0000, 0x0121, 0x0125, 0x00ed,
+ 0x00ec, 0x00ef, 0x00ee, 0x01d0, 0x0000, 0x012b, 0x012f, 0x0129,
+ 0x0135, 0x0137, 0x013a, 0x013e, 0x013c, 0x0144, 0x0148, 0x0146,
+ 0x00f1, 0x00f3, 0x00f2, 0x00f6, 0x00f4, 0x01d2, 0x0151, 0x014d,
+ 0x00f5, 0x0155, 0x0159, 0x0157, 0x015b, 0x015d, 0x0161, 0x015f,
+ 0x0165, 0x0163, 0x00fa, 0x00f9, 0x00fc, 0x00fb, 0x016d, 0x01d4,
+ 0x0171, 0x016b, 0x0173, 0x016f, 0x0169, 0x01d8, 0x01dc, 0x01da,
+ 0x01d6, 0x0175, 0x00fd, 0x00ff, 0x0177, 0x017a, 0x017e, 0x017c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2c21 - 0x2c7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2d21 - 0x2d7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2e21 - 0x2e7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x2f21 - 0x2f7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x3021 - 0x307e */
+ 0x4e02, 0x4e04, 0x4e05, 0x4e0c, 0x4e12, 0x4e1f, 0x4e23,
+ 0x4e24, 0x4e28, 0x4e2b, 0x4e2e, 0x4e2f, 0x4e30, 0x4e35, 0x4e40,
+ 0x4e41, 0x4e44, 0x4e47, 0x4e51, 0x4e5a, 0x4e5c, 0x4e63, 0x4e68,
+ 0x4e69, 0x4e74, 0x4e75, 0x4e79, 0x4e7f, 0x4e8d, 0x4e96, 0x4e97,
+ 0x4e9d, 0x4eaf, 0x4eb9, 0x4ec3, 0x4ed0, 0x4eda, 0x4edb, 0x4ee0,
+ 0x4ee1, 0x4ee2, 0x4ee8, 0x4eef, 0x4ef1, 0x4ef3, 0x4ef5, 0x4efd,
+ 0x4efe, 0x4eff, 0x4f00, 0x4f02, 0x4f03, 0x4f08, 0x4f0b, 0x4f0c,
+ 0x4f12, 0x4f15, 0x4f16, 0x4f17, 0x4f19, 0x4f2e, 0x4f31, 0x4f60,
+ 0x4f33, 0x4f35, 0x4f37, 0x4f39, 0x4f3b, 0x4f3e, 0x4f40, 0x4f42,
+ 0x4f48, 0x4f49, 0x4f4b, 0x4f4c, 0x4f52, 0x4f54, 0x4f56, 0x4f58,
+ 0x4f5f, 0x4f63, 0x4f6a, 0x4f6c, 0x4f6e, 0x4f71, 0x4f77, 0x4f78,
+ 0x4f79, 0x4f7a, 0x4f7d, 0x4f7e, 0x4f81, 0x4f82, 0x4f84,
+ /* 0x3121 - 0x317e */
+ 0x4f85, 0x4f89, 0x4f8a, 0x4f8c, 0x4f8e, 0x4f90, 0x4f92,
+ 0x4f93, 0x4f94, 0x4f97, 0x4f99, 0x4f9a, 0x4f9e, 0x4f9f, 0x4fb2,
+ 0x4fb7, 0x4fb9, 0x4fbb, 0x4fbc, 0x4fbd, 0x4fbe, 0x4fc0, 0x4fc1,
+ 0x4fc5, 0x4fc6, 0x4fc8, 0x4fc9, 0x4fcb, 0x4fcc, 0x4fcd, 0x4fcf,
+ 0x4fd2, 0x4fdc, 0x4fe0, 0x4fe2, 0x4ff0, 0x4ff2, 0x4ffc, 0x4ffd,
+ 0x4fff, 0x5000, 0x5001, 0x5004, 0x5007, 0x500a, 0x500c, 0x500e,
+ 0x5010, 0x5013, 0x5017, 0x5018, 0x501b, 0x501c, 0x501d, 0x501e,
+ 0x5022, 0x5027, 0x502e, 0x5030, 0x5032, 0x5033, 0x5035, 0x5040,
+ 0x5041, 0x5042, 0x5045, 0x5046, 0x504a, 0x504c, 0x504e, 0x5051,
+ 0x5052, 0x5053, 0x5057, 0x5059, 0x505f, 0x5060, 0x5062, 0x5063,
+ 0x5066, 0x5067, 0x506a, 0x506d, 0x5070, 0x5071, 0x503b, 0x5081,
+ 0x5083, 0x5084, 0x5086, 0x508a, 0x508e, 0x508f, 0x5090,
+ /* 0x3221 - 0x327e */
+ 0x5092, 0x5093, 0x5094, 0x5096, 0x509b, 0x509c, 0x509e,
+ 0x509f, 0x50a0, 0x50a1, 0x50a2, 0x50aa, 0x50af, 0x50b0, 0x50b9,
+ 0x50ba, 0x50bd, 0x50c0, 0x50c3, 0x50c4, 0x50c7, 0x50cc, 0x50ce,
+ 0x50d0, 0x50d3, 0x50d4, 0x50d8, 0x50dc, 0x50dd, 0x50df, 0x50e2,
+ 0x50e4, 0x50e6, 0x50e8, 0x50e9, 0x50ef, 0x50f1, 0x50f6, 0x50fa,
+ 0x50fe, 0x5103, 0x5106, 0x5107, 0x5108, 0x510b, 0x510c, 0x510d,
+ 0x510e, 0x50f2, 0x5110, 0x5117, 0x5119, 0x511b, 0x511c, 0x511d,
+ 0x511e, 0x5123, 0x5127, 0x5128, 0x512c, 0x512d, 0x512f, 0x5131,
+ 0x5133, 0x5134, 0x5135, 0x5138, 0x5139, 0x5142, 0x514a, 0x514f,
+ 0x5153, 0x5155, 0x5157, 0x5158, 0x515f, 0x5164, 0x5166, 0x517e,
+ 0x5183, 0x5184, 0x518b, 0x518e, 0x5198, 0x519d, 0x51a1, 0x51a3,
+ 0x51ad, 0x51b8, 0x51ba, 0x51bc, 0x51be, 0x51bf, 0x51c2,
+ /* 0x3321 - 0x337e */
+ 0x51c8, 0x51cf, 0x51d1, 0x51d2, 0x51d3, 0x51d5, 0x51d8,
+ 0x51de, 0x51e2, 0x51e5, 0x51ee, 0x51f2, 0x51f3, 0x51f4, 0x51f7,
+ 0x5201, 0x5202, 0x5205, 0x5212, 0x5213, 0x5215, 0x5216, 0x5218,
+ 0x5222, 0x5228, 0x5231, 0x5232, 0x5235, 0x523c, 0x5245, 0x5249,
+ 0x5255, 0x5257, 0x5258, 0x525a, 0x525c, 0x525f, 0x5260, 0x5261,
+ 0x5266, 0x526e, 0x5277, 0x5278, 0x5279, 0x5280, 0x5282, 0x5285,
+ 0x528a, 0x528c, 0x5293, 0x5295, 0x5296, 0x5297, 0x5298, 0x529a,
+ 0x529c, 0x52a4, 0x52a5, 0x52a6, 0x52a7, 0x52af, 0x52b0, 0x52b6,
+ 0x52b7, 0x52b8, 0x52ba, 0x52bb, 0x52bd, 0x52c0, 0x52c4, 0x52c6,
+ 0x52c8, 0x52cc, 0x52cf, 0x52d1, 0x52d4, 0x52d6, 0x52db, 0x52dc,
+ 0x52e1, 0x52e5, 0x52e8, 0x52e9, 0x52ea, 0x52ec, 0x52f0, 0x52f1,
+ 0x52f4, 0x52f6, 0x52f7, 0x5300, 0x5303, 0x530a, 0x530b,
+ /* 0x3421 - 0x347e */
+ 0x530c, 0x5311, 0x5313, 0x5318, 0x531b, 0x531c, 0x531e,
+ 0x531f, 0x5325, 0x5327, 0x5328, 0x5329, 0x532b, 0x532c, 0x532d,
+ 0x5330, 0x5332, 0x5335, 0x533c, 0x533d, 0x533e, 0x5342, 0x534c,
+ 0x534b, 0x5359, 0x535b, 0x5361, 0x5363, 0x5365, 0x536c, 0x536d,
+ 0x5372, 0x5379, 0x537e, 0x5383, 0x5387, 0x5388, 0x538e, 0x5393,
+ 0x5394, 0x5399, 0x539d, 0x53a1, 0x53a4, 0x53aa, 0x53ab, 0x53af,
+ 0x53b2, 0x53b4, 0x53b5, 0x53b7, 0x53b8, 0x53ba, 0x53bd, 0x53c0,
+ 0x53c5, 0x53cf, 0x53d2, 0x53d3, 0x53d5, 0x53da, 0x53dd, 0x53de,
+ 0x53e0, 0x53e6, 0x53e7, 0x53f5, 0x5402, 0x5413, 0x541a, 0x5421,
+ 0x5427, 0x5428, 0x542a, 0x542f, 0x5431, 0x5434, 0x5435, 0x5443,
+ 0x5444, 0x5447, 0x544d, 0x544f, 0x545e, 0x5462, 0x5464, 0x5466,
+ 0x5467, 0x5469, 0x546b, 0x546d, 0x546e, 0x5474, 0x547f,
+ /* 0x3521 - 0x357e */
+ 0x5481, 0x5483, 0x5485, 0x5488, 0x5489, 0x548d, 0x5491,
+ 0x5495, 0x5496, 0x549c, 0x549f, 0x54a1, 0x54a6, 0x54a7, 0x54a9,
+ 0x54aa, 0x54ad, 0x54ae, 0x54b1, 0x54b7, 0x54b9, 0x54ba, 0x54bb,
+ 0x54bf, 0x54c6, 0x54ca, 0x54cd, 0x54ce, 0x54e0, 0x54ea, 0x54ec,
+ 0x54ef, 0x54f6, 0x54fc, 0x54fe, 0x54ff, 0x5500, 0x5501, 0x5505,
+ 0x5508, 0x5509, 0x550c, 0x550d, 0x550e, 0x5515, 0x552a, 0x552b,
+ 0x5532, 0x5535, 0x5536, 0x553b, 0x553c, 0x553d, 0x5541, 0x5547,
+ 0x5549, 0x554a, 0x554d, 0x5550, 0x5551, 0x5558, 0x555a, 0x555b,
+ 0x555e, 0x5560, 0x5561, 0x5564, 0x5566, 0x557f, 0x5581, 0x5582,
+ 0x5586, 0x5588, 0x558e, 0x558f, 0x5591, 0x5592, 0x5593, 0x5594,
+ 0x5597, 0x55a3, 0x55a4, 0x55ad, 0x55b2, 0x55bf, 0x55c1, 0x55c3,
+ 0x55c6, 0x55c9, 0x55cb, 0x55cc, 0x55ce, 0x55d1, 0x55d2,
+ /* 0x3621 - 0x367e */
+ 0x55d3, 0x55d7, 0x55d8, 0x55db, 0x55de, 0x55e2, 0x55e9,
+ 0x55f6, 0x55ff, 0x5605, 0x5608, 0x560a, 0x560d, 0x560e, 0x560f,
+ 0x5610, 0x5611, 0x5612, 0x5619, 0x562c, 0x5630, 0x5633, 0x5635,
+ 0x5637, 0x5639, 0x563b, 0x563c, 0x563d, 0x563f, 0x5640, 0x5641,
+ 0x5643, 0x5644, 0x5646, 0x5649, 0x564b, 0x564d, 0x564f, 0x5654,
+ 0x565e, 0x5660, 0x5661, 0x5662, 0x5663, 0x5666, 0x5669, 0x566d,
+ 0x566f, 0x5671, 0x5672, 0x5675, 0x5684, 0x5685, 0x5688, 0x568b,
+ 0x568c, 0x5695, 0x5699, 0x569a, 0x569d, 0x569e, 0x569f, 0x56a6,
+ 0x56a7, 0x56a8, 0x56a9, 0x56ab, 0x56ac, 0x56ad, 0x56b1, 0x56b3,
+ 0x56b7, 0x56be, 0x56c5, 0x56c9, 0x56ca, 0x56cb, 0x56cf, 0x56d0,
+ 0x56cc, 0x56cd, 0x56d9, 0x56dc, 0x56dd, 0x56df, 0x56e1, 0x56e4,
+ 0x56e5, 0x56e6, 0x56e7, 0x56e8, 0x56f1, 0x56eb, 0x56ed,
+ /* 0x3721 - 0x377e */
+ 0x56f6, 0x56f7, 0x5701, 0x5702, 0x5707, 0x570a, 0x570c,
+ 0x5711, 0x5715, 0x571a, 0x571b, 0x571d, 0x5720, 0x5722, 0x5723,
+ 0x5724, 0x5725, 0x5729, 0x572a, 0x572c, 0x572e, 0x572f, 0x5733,
+ 0x5734, 0x573d, 0x573e, 0x573f, 0x5745, 0x5746, 0x574c, 0x574d,
+ 0x5752, 0x5762, 0x5765, 0x5767, 0x5768, 0x576b, 0x576d, 0x576e,
+ 0x576f, 0x5770, 0x5771, 0x5773, 0x5774, 0x5775, 0x5777, 0x5779,
+ 0x577a, 0x577b, 0x577c, 0x577e, 0x5781, 0x5783, 0x578c, 0x5794,
+ 0x5797, 0x5799, 0x579a, 0x579c, 0x579d, 0x579e, 0x579f, 0x57a1,
+ 0x5795, 0x57a7, 0x57a8, 0x57a9, 0x57ac, 0x57b8, 0x57bd, 0x57c7,
+ 0x57c8, 0x57cc, 0x57cf, 0x57d5, 0x57dd, 0x57de, 0x57e4, 0x57e6,
+ 0x57e7, 0x57e9, 0x57ed, 0x57f0, 0x57f5, 0x57f6, 0x57f8, 0x57fd,
+ 0x57fe, 0x57ff, 0x5803, 0x5804, 0x5808, 0x5809, 0x57e1,
+ /* 0x3821 - 0x387e */
+ 0x580c, 0x580d, 0x581b, 0x581e, 0x581f, 0x5820, 0x5826,
+ 0x5827, 0x582d, 0x5832, 0x5839, 0x583f, 0x5849, 0x584c, 0x584d,
+ 0x584f, 0x5850, 0x5855, 0x585f, 0x5861, 0x5864, 0x5867, 0x5868,
+ 0x5878, 0x587c, 0x587f, 0x5880, 0x5881, 0x5887, 0x5888, 0x5889,
+ 0x588a, 0x588c, 0x588d, 0x588f, 0x5890, 0x5894, 0x5896, 0x589d,
+ 0x58a0, 0x58a1, 0x58a2, 0x58a6, 0x58a9, 0x58b1, 0x58b2, 0x58c4,
+ 0x58bc, 0x58c2, 0x58c8, 0x58cd, 0x58ce, 0x58d0, 0x58d2, 0x58d4,
+ 0x58d6, 0x58da, 0x58dd, 0x58e1, 0x58e2, 0x58e9, 0x58f3, 0x5905,
+ 0x5906, 0x590b, 0x590c, 0x5912, 0x5913, 0x5914, 0x8641, 0x591d,
+ 0x5921, 0x5923, 0x5924, 0x5928, 0x592f, 0x5930, 0x5933, 0x5935,
+ 0x5936, 0x593f, 0x5943, 0x5946, 0x5952, 0x5953, 0x5959, 0x595b,
+ 0x595d, 0x595e, 0x595f, 0x5961, 0x5963, 0x596b, 0x596d,
+ /* 0x3921 - 0x397e */
+ 0x596f, 0x5972, 0x5975, 0x5976, 0x5979, 0x597b, 0x597c,
+ 0x598b, 0x598c, 0x598e, 0x5992, 0x5995, 0x5997, 0x599f, 0x59a4,
+ 0x59a7, 0x59ad, 0x59ae, 0x59af, 0x59b0, 0x59b3, 0x59b7, 0x59ba,
+ 0x59bc, 0x59c1, 0x59c3, 0x59c4, 0x59c8, 0x59ca, 0x59cd, 0x59d2,
+ 0x59dd, 0x59de, 0x59df, 0x59e3, 0x59e4, 0x59e7, 0x59ee, 0x59ef,
+ 0x59f1, 0x59f2, 0x59f4, 0x59f7, 0x5a00, 0x5a04, 0x5a0c, 0x5a0d,
+ 0x5a0e, 0x5a12, 0x5a13, 0x5a1e, 0x5a23, 0x5a24, 0x5a27, 0x5a28,
+ 0x5a2a, 0x5a2d, 0x5a30, 0x5a44, 0x5a45, 0x5a47, 0x5a48, 0x5a4c,
+ 0x5a50, 0x5a55, 0x5a5e, 0x5a63, 0x5a65, 0x5a67, 0x5a6d, 0x5a77,
+ 0x5a7a, 0x5a7b, 0x5a7e, 0x5a8b, 0x5a90, 0x5a93, 0x5a96, 0x5a99,
+ 0x5a9c, 0x5a9e, 0x5a9f, 0x5aa0, 0x5aa2, 0x5aa7, 0x5aac, 0x5ab1,
+ 0x5ab2, 0x5ab3, 0x5ab5, 0x5ab8, 0x5aba, 0x5abb, 0x5abf,
+ /* 0x3a21 - 0x3a7e */
+ 0x5ac4, 0x5ac6, 0x5ac8, 0x5acf, 0x5ada, 0x5adc, 0x5ae0,
+ 0x5ae5, 0x5aea, 0x5aee, 0x5af5, 0x5af6, 0x5afd, 0x5b00, 0x5b01,
+ 0x5b08, 0x5b17, 0x5b34, 0x5b19, 0x5b1b, 0x5b1d, 0x5b21, 0x5b25,
+ 0x5b2d, 0x5b38, 0x5b41, 0x5b4b, 0x5b4c, 0x5b52, 0x5b56, 0x5b5e,
+ 0x5b68, 0x5b6e, 0x5b6f, 0x5b7c, 0x5b7d, 0x5b7e, 0x5b7f, 0x5b81,
+ 0x5b84, 0x5b86, 0x5b8a, 0x5b8e, 0x5b90, 0x5b91, 0x5b93, 0x5b94,
+ 0x5b96, 0x5ba8, 0x5ba9, 0x5bac, 0x5bad, 0x5baf, 0x5bb1, 0x5bb2,
+ 0x5bb7, 0x5bba, 0x5bbc, 0x5bc0, 0x5bc1, 0x5bcd, 0x5bcf, 0x5bd6,
+ 0x5bd7, 0x5bd8, 0x5bd9, 0x5bda, 0x5be0, 0x5bef, 0x5bf1, 0x5bf4,
+ 0x5bfd, 0x5c0c, 0x5c17, 0x5c1e, 0x5c1f, 0x5c23, 0x5c26, 0x5c29,
+ 0x5c2b, 0x5c2c, 0x5c2e, 0x5c30, 0x5c32, 0x5c35, 0x5c36, 0x5c59,
+ 0x5c5a, 0x5c5c, 0x5c62, 0x5c63, 0x5c67, 0x5c68, 0x5c69,
+ /* 0x3b21 - 0x3b7e */
+ 0x5c6d, 0x5c70, 0x5c74, 0x5c75, 0x5c7a, 0x5c7b, 0x5c7c,
+ 0x5c7d, 0x5c87, 0x5c88, 0x5c8a, 0x5c8f, 0x5c92, 0x5c9d, 0x5c9f,
+ 0x5ca0, 0x5ca2, 0x5ca3, 0x5ca6, 0x5caa, 0x5cb2, 0x5cb4, 0x5cb5,
+ 0x5cba, 0x5cc9, 0x5ccb, 0x5cd2, 0x5cdd, 0x5cd7, 0x5cee, 0x5cf1,
+ 0x5cf2, 0x5cf4, 0x5d01, 0x5d06, 0x5d0d, 0x5d12, 0x5d2b, 0x5d23,
+ 0x5d24, 0x5d26, 0x5d27, 0x5d31, 0x5d34, 0x5d39, 0x5d3d, 0x5d3f,
+ 0x5d42, 0x5d43, 0x5d46, 0x5d48, 0x5d55, 0x5d51, 0x5d59, 0x5d4a,
+ 0x5d5f, 0x5d60, 0x5d61, 0x5d62, 0x5d64, 0x5d6a, 0x5d6d, 0x5d70,
+ 0x5d79, 0x5d7a, 0x5d7e, 0x5d7f, 0x5d81, 0x5d83, 0x5d88, 0x5d8a,
+ 0x5d92, 0x5d93, 0x5d94, 0x5d95, 0x5d99, 0x5d9b, 0x5d9f, 0x5da0,
+ 0x5da7, 0x5dab, 0x5db0, 0x5db4, 0x5db8, 0x5db9, 0x5dc3, 0x5dc7,
+ 0x5dcb, 0x5dd0, 0x5dce, 0x5dd8, 0x5dd9, 0x5de0, 0x5de4,
+ /* 0x3c21 - 0x3c7e */
+ 0x5de9, 0x5df8, 0x5df9, 0x5e00, 0x5e07, 0x5e0d, 0x5e12,
+ 0x5e14, 0x5e15, 0x5e18, 0x5e1f, 0x5e20, 0x5e2e, 0x5e28, 0x5e32,
+ 0x5e35, 0x5e3e, 0x5e4b, 0x5e50, 0x5e49, 0x5e51, 0x5e56, 0x5e58,
+ 0x5e5b, 0x5e5c, 0x5e5e, 0x5e68, 0x5e6a, 0x5e6b, 0x5e6c, 0x5e6d,
+ 0x5e6e, 0x5e70, 0x5e80, 0x5e8b, 0x5e8e, 0x5ea2, 0x5ea4, 0x5ea5,
+ 0x5ea8, 0x5eaa, 0x5eac, 0x5eb1, 0x5eb3, 0x5ebd, 0x5ebe, 0x5ebf,
+ 0x5ec6, 0x5ecc, 0x5ecb, 0x5ece, 0x5ed1, 0x5ed2, 0x5ed4, 0x5ed5,
+ 0x5edc, 0x5ede, 0x5ee5, 0x5eeb, 0x5f02, 0x5f06, 0x5f07, 0x5f08,
+ 0x5f0e, 0x5f19, 0x5f1c, 0x5f1d, 0x5f21, 0x5f22, 0x5f23, 0x5f24,
+ 0x5f28, 0x5f2b, 0x5f2c, 0x5f2e, 0x5f30, 0x5f34, 0x5f36, 0x5f3b,
+ 0x5f3d, 0x5f3f, 0x5f40, 0x5f44, 0x5f45, 0x5f47, 0x5f4d, 0x5f50,
+ 0x5f54, 0x5f58, 0x5f5b, 0x5f60, 0x5f63, 0x5f64, 0x5f67,
+ /* 0x3d21 - 0x3d7e */
+ 0x5f6f, 0x5f72, 0x5f74, 0x5f75, 0x5f78, 0x5f7a, 0x5f7d,
+ 0x5f7e, 0x5f89, 0x5f8d, 0x5f8f, 0x5f96, 0x5f9c, 0x5f9d, 0x5fa2,
+ 0x5fa7, 0x5fab, 0x5fa4, 0x5fac, 0x5faf, 0x5fb0, 0x5fb1, 0x5fb8,
+ 0x5fc4, 0x5fc7, 0x5fc8, 0x5fc9, 0x5fcb, 0x5fd0, 0x5fd1, 0x5fd2,
+ 0x5fd3, 0x5fd4, 0x5fde, 0x5fe1, 0x5fe2, 0x5fe8, 0x5fe9, 0x5fea,
+ 0x5fec, 0x5fed, 0x5fee, 0x5fef, 0x5ff2, 0x5ff3, 0x5ff6, 0x5ffa,
+ 0x5ffc, 0x6007, 0x600a, 0x600d, 0x6013, 0x6014, 0x6017, 0x6018,
+ 0x601a, 0x601f, 0x6024, 0x602d, 0x6033, 0x6035, 0x6040, 0x6047,
+ 0x6048, 0x6049, 0x604c, 0x6051, 0x6054, 0x6056, 0x6057, 0x605d,
+ 0x6061, 0x6067, 0x6071, 0x607e, 0x607f, 0x6082, 0x6086, 0x6088,
+ 0x608a, 0x608e, 0x6091, 0x6093, 0x6095, 0x6098, 0x609d, 0x609e,
+ 0x60a2, 0x60a4, 0x60a5, 0x60a8, 0x60b0, 0x60b1, 0x60b7,
+ /* 0x3e21 - 0x3e7e */
+ 0x60bb, 0x60be, 0x60c2, 0x60c4, 0x60c8, 0x60c9, 0x60ca,
+ 0x60cb, 0x60ce, 0x60cf, 0x60d4, 0x60d5, 0x60d9, 0x60db, 0x60dd,
+ 0x60de, 0x60e2, 0x60e5, 0x60f2, 0x60f5, 0x60f8, 0x60fc, 0x60fd,
+ 0x6102, 0x6107, 0x610a, 0x610c, 0x6110, 0x6111, 0x6112, 0x6113,
+ 0x6114, 0x6116, 0x6117, 0x6119, 0x611c, 0x611e, 0x6122, 0x612a,
+ 0x612b, 0x6130, 0x6131, 0x6135, 0x6136, 0x6137, 0x6139, 0x6141,
+ 0x6145, 0x6146, 0x6149, 0x615e, 0x6160, 0x616c, 0x6172, 0x6178,
+ 0x617b, 0x617c, 0x617f, 0x6180, 0x6181, 0x6183, 0x6184, 0x618b,
+ 0x618d, 0x6192, 0x6193, 0x6197, 0x6198, 0x619c, 0x619d, 0x619f,
+ 0x61a0, 0x61a5, 0x61a8, 0x61aa, 0x61ad, 0x61b8, 0x61b9, 0x61bc,
+ 0x61c0, 0x61c1, 0x61c2, 0x61ce, 0x61cf, 0x61d5, 0x61dc, 0x61dd,
+ 0x61de, 0x61df, 0x61e1, 0x61e2, 0x61e7, 0x61e9, 0x61e5,
+ /* 0x3f21 - 0x3f7e */
+ 0x61ec, 0x61ed, 0x61ef, 0x6201, 0x6203, 0x6204, 0x6207,
+ 0x6213, 0x6215, 0x621c, 0x6220, 0x6222, 0x6223, 0x6227, 0x6229,
+ 0x622b, 0x6239, 0x623d, 0x6242, 0x6243, 0x6244, 0x6246, 0x624c,
+ 0x6250, 0x6251, 0x6252, 0x6254, 0x6256, 0x625a, 0x625c, 0x6264,
+ 0x626d, 0x626f, 0x6273, 0x627a, 0x627d, 0x628d, 0x628e, 0x628f,
+ 0x6290, 0x62a6, 0x62a8, 0x62b3, 0x62b6, 0x62b7, 0x62ba, 0x62be,
+ 0x62bf, 0x62c4, 0x62ce, 0x62d5, 0x62d6, 0x62da, 0x62ea, 0x62f2,
+ 0x62f4, 0x62fc, 0x62fd, 0x6303, 0x6304, 0x630a, 0x630b, 0x630d,
+ 0x6310, 0x6313, 0x6316, 0x6318, 0x6329, 0x632a, 0x632d, 0x6335,
+ 0x6336, 0x6339, 0x633c, 0x6341, 0x6342, 0x6343, 0x6344, 0x6346,
+ 0x634a, 0x634b, 0x634e, 0x6352, 0x6353, 0x6354, 0x6358, 0x635b,
+ 0x6365, 0x6366, 0x636c, 0x636d, 0x6371, 0x6374, 0x6375,
+ /* 0x4021 - 0x407e */
+ 0x6378, 0x637c, 0x637d, 0x637f, 0x6382, 0x6384, 0x6387,
+ 0x638a, 0x6390, 0x6394, 0x6395, 0x6399, 0x639a, 0x639e, 0x63a4,
+ 0x63a6, 0x63ad, 0x63ae, 0x63af, 0x63bd, 0x63c1, 0x63c5, 0x63c8,
+ 0x63ce, 0x63d1, 0x63d3, 0x63d4, 0x63d5, 0x63dc, 0x63e0, 0x63e5,
+ 0x63ea, 0x63ec, 0x63f2, 0x63f3, 0x63f5, 0x63f8, 0x63f9, 0x6409,
+ 0x640a, 0x6410, 0x6412, 0x6414, 0x6418, 0x641e, 0x6420, 0x6422,
+ 0x6424, 0x6425, 0x6429, 0x642a, 0x642f, 0x6430, 0x6435, 0x643d,
+ 0x643f, 0x644b, 0x644f, 0x6451, 0x6452, 0x6453, 0x6454, 0x645a,
+ 0x645b, 0x645c, 0x645d, 0x645f, 0x6460, 0x6461, 0x6463, 0x646d,
+ 0x6473, 0x6474, 0x647b, 0x647d, 0x6485, 0x6487, 0x648f, 0x6490,
+ 0x6491, 0x6498, 0x6499, 0x649b, 0x649d, 0x649f, 0x64a1, 0x64a3,
+ 0x64a6, 0x64a8, 0x64ac, 0x64b3, 0x64bd, 0x64be, 0x64bf,
+ /* 0x4121 - 0x417e */
+ 0x64c4, 0x64c9, 0x64ca, 0x64cb, 0x64cc, 0x64ce, 0x64d0,
+ 0x64d1, 0x64d5, 0x64d7, 0x64e4, 0x64e5, 0x64e9, 0x64ea, 0x64ed,
+ 0x64f0, 0x64f5, 0x64f7, 0x64fb, 0x64ff, 0x6501, 0x6504, 0x6508,
+ 0x6509, 0x650a, 0x650f, 0x6513, 0x6514, 0x6516, 0x6519, 0x651b,
+ 0x651e, 0x651f, 0x6522, 0x6526, 0x6529, 0x652e, 0x6531, 0x653a,
+ 0x653c, 0x653d, 0x6543, 0x6547, 0x6549, 0x6550, 0x6552, 0x6554,
+ 0x655f, 0x6560, 0x6567, 0x656b, 0x657a, 0x657d, 0x6581, 0x6585,
+ 0x658a, 0x6592, 0x6595, 0x6598, 0x659d, 0x65a0, 0x65a3, 0x65a6,
+ 0x65ae, 0x65b2, 0x65b3, 0x65b4, 0x65bf, 0x65c2, 0x65c8, 0x65c9,
+ 0x65ce, 0x65d0, 0x65d4, 0x65d6, 0x65d8, 0x65df, 0x65f0, 0x65f2,
+ 0x65f4, 0x65f5, 0x65f9, 0x65fe, 0x65ff, 0x6600, 0x6604, 0x6608,
+ 0x6609, 0x660d, 0x6611, 0x6612, 0x6615, 0x6616, 0x661d,
+ /* 0x4221 - 0x427e */
+ 0x661e, 0x6621, 0x6622, 0x6623, 0x6624, 0x6626, 0x6629,
+ 0x662a, 0x662b, 0x662c, 0x662e, 0x6630, 0x6631, 0x6633, 0x6639,
+ 0x6637, 0x6640, 0x6645, 0x6646, 0x664a, 0x664c, 0x6651, 0x664e,
+ 0x6657, 0x6658, 0x6659, 0x665b, 0x665c, 0x6660, 0x6661, 0x66fb,
+ 0x666a, 0x666b, 0x666c, 0x667e, 0x6673, 0x6675, 0x667f, 0x6677,
+ 0x6678, 0x6679, 0x667b, 0x6680, 0x667c, 0x668b, 0x668c, 0x668d,
+ 0x6690, 0x6692, 0x6699, 0x669a, 0x669b, 0x669c, 0x669f, 0x66a0,
+ 0x66a4, 0x66ad, 0x66b1, 0x66b2, 0x66b5, 0x66bb, 0x66bf, 0x66c0,
+ 0x66c2, 0x66c3, 0x66c8, 0x66cc, 0x66ce, 0x66cf, 0x66d4, 0x66db,
+ 0x66df, 0x66e8, 0x66eb, 0x66ec, 0x66ee, 0x66fa, 0x6705, 0x6707,
+ 0x670e, 0x6713, 0x6719, 0x671c, 0x6720, 0x6722, 0x6733, 0x673e,
+ 0x6745, 0x6747, 0x6748, 0x674c, 0x6754, 0x6755, 0x675d,
+ /* 0x4321 - 0x437e */
+ 0x6766, 0x676c, 0x676e, 0x6774, 0x6776, 0x677b, 0x6781,
+ 0x6784, 0x678e, 0x678f, 0x6791, 0x6793, 0x6796, 0x6798, 0x6799,
+ 0x679b, 0x67b0, 0x67b1, 0x67b2, 0x67b5, 0x67bb, 0x67bc, 0x67bd,
+ 0x67f9, 0x67c0, 0x67c2, 0x67c3, 0x67c5, 0x67c8, 0x67c9, 0x67d2,
+ 0x67d7, 0x67d9, 0x67dc, 0x67e1, 0x67e6, 0x67f0, 0x67f2, 0x67f6,
+ 0x67f7, 0x6852, 0x6814, 0x6819, 0x681d, 0x681f, 0x6828, 0x6827,
+ 0x682c, 0x682d, 0x682f, 0x6830, 0x6831, 0x6833, 0x683b, 0x683f,
+ 0x6844, 0x6845, 0x684a, 0x684c, 0x6855, 0x6857, 0x6858, 0x685b,
+ 0x686b, 0x686e, 0x686f, 0x6870, 0x6871, 0x6872, 0x6875, 0x6879,
+ 0x687a, 0x687b, 0x687c, 0x6882, 0x6884, 0x6886, 0x6888, 0x6896,
+ 0x6898, 0x689a, 0x689c, 0x68a1, 0x68a3, 0x68a5, 0x68a9, 0x68aa,
+ 0x68ae, 0x68b2, 0x68bb, 0x68c5, 0x68c8, 0x68cc, 0x68cf,
+ /* 0x4421 - 0x447e */
+ 0x68d0, 0x68d1, 0x68d3, 0x68d6, 0x68d9, 0x68dc, 0x68dd,
+ 0x68e5, 0x68e8, 0x68ea, 0x68eb, 0x68ec, 0x68ed, 0x68f0, 0x68f1,
+ 0x68f5, 0x68f6, 0x68fb, 0x68fc, 0x68fd, 0x6906, 0x6909, 0x690a,
+ 0x6910, 0x6911, 0x6913, 0x6916, 0x6917, 0x6931, 0x6933, 0x6935,
+ 0x6938, 0x693b, 0x6942, 0x6945, 0x6949, 0x694e, 0x6957, 0x695b,
+ 0x6963, 0x6964, 0x6965, 0x6966, 0x6968, 0x6969, 0x696c, 0x6970,
+ 0x6971, 0x6972, 0x697a, 0x697b, 0x697f, 0x6980, 0x698d, 0x6992,
+ 0x6996, 0x6998, 0x69a1, 0x69a5, 0x69a6, 0x69a8, 0x69ab, 0x69ad,
+ 0x69af, 0x69b7, 0x69b8, 0x69ba, 0x69bc, 0x69c5, 0x69c8, 0x69d1,
+ 0x69d6, 0x69d7, 0x69e2, 0x69e5, 0x69ee, 0x69ef, 0x69f1, 0x69f3,
+ 0x69f5, 0x69fe, 0x6a00, 0x6a01, 0x6a03, 0x6a0f, 0x6a11, 0x6a15,
+ 0x6a1a, 0x6a1d, 0x6a20, 0x6a24, 0x6a28, 0x6a30, 0x6a32,
+ /* 0x4521 - 0x457e */
+ 0x6a34, 0x6a37, 0x6a3b, 0x6a3e, 0x6a3f, 0x6a45, 0x6a46,
+ 0x6a49, 0x6a4a, 0x6a4e, 0x6a50, 0x6a51, 0x6a52, 0x6a55, 0x6a56,
+ 0x6a5b, 0x6a64, 0x6a67, 0x6a6a, 0x6a71, 0x6a73, 0x6a7e, 0x6a81,
+ 0x6a83, 0x6a86, 0x6a87, 0x6a89, 0x6a8b, 0x6a91, 0x6a9b, 0x6a9d,
+ 0x6a9e, 0x6a9f, 0x6aa5, 0x6aab, 0x6aaf, 0x6ab0, 0x6ab1, 0x6ab4,
+ 0x6abd, 0x6abe, 0x6abf, 0x6ac6, 0x6ac9, 0x6ac8, 0x6acc, 0x6ad0,
+ 0x6ad4, 0x6ad5, 0x6ad6, 0x6adc, 0x6add, 0x6ae4, 0x6ae7, 0x6aec,
+ 0x6af0, 0x6af1, 0x6af2, 0x6afc, 0x6afd, 0x6b02, 0x6b03, 0x6b06,
+ 0x6b07, 0x6b09, 0x6b0f, 0x6b10, 0x6b11, 0x6b17, 0x6b1b, 0x6b1e,
+ 0x6b24, 0x6b28, 0x6b2b, 0x6b2c, 0x6b2f, 0x6b35, 0x6b36, 0x6b3b,
+ 0x6b3f, 0x6b46, 0x6b4a, 0x6b4d, 0x6b52, 0x6b56, 0x6b58, 0x6b5d,
+ 0x6b60, 0x6b67, 0x6b6b, 0x6b6e, 0x6b70, 0x6b75, 0x6b7d,
+ /* 0x4621 - 0x467e */
+ 0x6b7e, 0x6b82, 0x6b85, 0x6b97, 0x6b9b, 0x6b9f, 0x6ba0,
+ 0x6ba2, 0x6ba3, 0x6ba8, 0x6ba9, 0x6bac, 0x6bad, 0x6bae, 0x6bb0,
+ 0x6bb8, 0x6bb9, 0x6bbd, 0x6bbe, 0x6bc3, 0x6bc4, 0x6bc9, 0x6bcc,
+ 0x6bd6, 0x6bda, 0x6be1, 0x6be3, 0x6be6, 0x6be7, 0x6bee, 0x6bf1,
+ 0x6bf7, 0x6bf9, 0x6bff, 0x6c02, 0x6c04, 0x6c05, 0x6c09, 0x6c0d,
+ 0x6c0e, 0x6c10, 0x6c12, 0x6c19, 0x6c1f, 0x6c26, 0x6c27, 0x6c28,
+ 0x6c2c, 0x6c2e, 0x6c33, 0x6c35, 0x6c36, 0x6c3a, 0x6c3b, 0x6c3f,
+ 0x6c4a, 0x6c4b, 0x6c4d, 0x6c4f, 0x6c52, 0x6c54, 0x6c59, 0x6c5b,
+ 0x6c5c, 0x6c6b, 0x6c6d, 0x6c6f, 0x6c74, 0x6c76, 0x6c78, 0x6c79,
+ 0x6c7b, 0x6c85, 0x6c86, 0x6c87, 0x6c89, 0x6c94, 0x6c95, 0x6c97,
+ 0x6c98, 0x6c9c, 0x6c9f, 0x6cb0, 0x6cb2, 0x6cb4, 0x6cc2, 0x6cc6,
+ 0x6ccd, 0x6ccf, 0x6cd0, 0x6cd1, 0x6cd2, 0x6cd4, 0x6cd6,
+ /* 0x4721 - 0x477e */
+ 0x6cda, 0x6cdc, 0x6ce0, 0x6ce7, 0x6ce9, 0x6ceb, 0x6cec,
+ 0x6cee, 0x6cf2, 0x6cf4, 0x6d04, 0x6d07, 0x6d0a, 0x6d0e, 0x6d0f,
+ 0x6d11, 0x6d13, 0x6d1a, 0x6d26, 0x6d27, 0x6d28, 0x6c67, 0x6d2e,
+ 0x6d2f, 0x6d31, 0x6d39, 0x6d3c, 0x6d3f, 0x6d57, 0x6d5e, 0x6d5f,
+ 0x6d61, 0x6d65, 0x6d67, 0x6d6f, 0x6d70, 0x6d7c, 0x6d82, 0x6d87,
+ 0x6d91, 0x6d92, 0x6d94, 0x6d96, 0x6d97, 0x6d98, 0x6daa, 0x6dac,
+ 0x6db4, 0x6db7, 0x6db9, 0x6dbd, 0x6dbf, 0x6dc4, 0x6dc8, 0x6dca,
+ 0x6dce, 0x6dcf, 0x6dd6, 0x6ddb, 0x6ddd, 0x6ddf, 0x6de0, 0x6de2,
+ 0x6de5, 0x6de9, 0x6def, 0x6df0, 0x6df4, 0x6df6, 0x6dfc, 0x6e00,
+ 0x6e04, 0x6e1e, 0x6e22, 0x6e27, 0x6e32, 0x6e36, 0x6e39, 0x6e3b,
+ 0x6e3c, 0x6e44, 0x6e45, 0x6e48, 0x6e49, 0x6e4b, 0x6e4f, 0x6e51,
+ 0x6e52, 0x6e53, 0x6e54, 0x6e57, 0x6e5c, 0x6e5d, 0x6e5e,
+ /* 0x4821 - 0x487e */
+ 0x6e62, 0x6e63, 0x6e68, 0x6e73, 0x6e7b, 0x6e7d, 0x6e8d,
+ 0x6e93, 0x6e99, 0x6ea0, 0x6ea7, 0x6ead, 0x6eae, 0x6eb1, 0x6eb3,
+ 0x6ebb, 0x6ebf, 0x6ec0, 0x6ec1, 0x6ec3, 0x6ec7, 0x6ec8, 0x6eca,
+ 0x6ecd, 0x6ece, 0x6ecf, 0x6eeb, 0x6eed, 0x6eee, 0x6ef9, 0x6efb,
+ 0x6efd, 0x6f04, 0x6f08, 0x6f0a, 0x6f0c, 0x6f0d, 0x6f16, 0x6f18,
+ 0x6f1a, 0x6f1b, 0x6f26, 0x6f29, 0x6f2a, 0x6f2f, 0x6f30, 0x6f33,
+ 0x6f36, 0x6f3b, 0x6f3c, 0x6f2d, 0x6f4f, 0x6f51, 0x6f52, 0x6f53,
+ 0x6f57, 0x6f59, 0x6f5a, 0x6f5d, 0x6f5e, 0x6f61, 0x6f62, 0x6f68,
+ 0x6f6c, 0x6f7d, 0x6f7e, 0x6f83, 0x6f87, 0x6f88, 0x6f8b, 0x6f8c,
+ 0x6f8d, 0x6f90, 0x6f92, 0x6f93, 0x6f94, 0x6f96, 0x6f9a, 0x6f9f,
+ 0x6fa0, 0x6fa5, 0x6fa6, 0x6fa7, 0x6fa8, 0x6fae, 0x6faf, 0x6fb0,
+ 0x6fb5, 0x6fb6, 0x6fbc, 0x6fc5, 0x6fc7, 0x6fc8, 0x6fca,
+ /* 0x4921 - 0x497e */
+ 0x6fda, 0x6fde, 0x6fe8, 0x6fe9, 0x6ff0, 0x6ff5, 0x6ff9,
+ 0x6ffc, 0x6ffd, 0x7000, 0x7005, 0x7006, 0x7007, 0x700d, 0x7017,
+ 0x7020, 0x7023, 0x702f, 0x7034, 0x7037, 0x7039, 0x703c, 0x7043,
+ 0x7044, 0x7048, 0x7049, 0x704a, 0x704b, 0x7054, 0x7055, 0x705d,
+ 0x705e, 0x704e, 0x7064, 0x7065, 0x706c, 0x706e, 0x7075, 0x7076,
+ 0x707e, 0x7081, 0x7085, 0x7086, 0x7094, 0x7095, 0x7096, 0x7097,
+ 0x7098, 0x709b, 0x70a4, 0x70ab, 0x70b0, 0x70b1, 0x70b4, 0x70b7,
+ 0x70ca, 0x70d1, 0x70d3, 0x70d4, 0x70d5, 0x70d6, 0x70d8, 0x70dc,
+ 0x70e4, 0x70fa, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x710b,
+ 0x710c, 0x710f, 0x711e, 0x7120, 0x712b, 0x712d, 0x712f, 0x7130,
+ 0x7131, 0x7138, 0x7141, 0x7145, 0x7146, 0x7147, 0x714a, 0x714b,
+ 0x7150, 0x7152, 0x7157, 0x715a, 0x715c, 0x715e, 0x7160,
+ /* 0x4a21 - 0x4a7e */
+ 0x7168, 0x7179, 0x7180, 0x7185, 0x7187, 0x718c, 0x7192,
+ 0x719a, 0x719b, 0x71a0, 0x71a2, 0x71af, 0x71b0, 0x71b2, 0x71b3,
+ 0x71ba, 0x71bf, 0x71c0, 0x71c1, 0x71c4, 0x71cb, 0x71cc, 0x71d3,
+ 0x71d6, 0x71d9, 0x71da, 0x71dc, 0x71f8, 0x71fe, 0x7200, 0x7207,
+ 0x7208, 0x7209, 0x7213, 0x7217, 0x721a, 0x721d, 0x721f, 0x7224,
+ 0x722b, 0x722f, 0x7234, 0x7238, 0x7239, 0x7241, 0x7242, 0x7243,
+ 0x7245, 0x724e, 0x724f, 0x7250, 0x7253, 0x7255, 0x7256, 0x725a,
+ 0x725c, 0x725e, 0x7260, 0x7263, 0x7268, 0x726b, 0x726e, 0x726f,
+ 0x7271, 0x7277, 0x7278, 0x727b, 0x727c, 0x727f, 0x7284, 0x7289,
+ 0x728d, 0x728e, 0x7293, 0x729b, 0x72a8, 0x72ad, 0x72ae, 0x72b1,
+ 0x72b4, 0x72be, 0x72c1, 0x72c7, 0x72c9, 0x72cc, 0x72d5, 0x72d6,
+ 0x72d8, 0x72df, 0x72e5, 0x72f3, 0x72f4, 0x72fa, 0x72fb,
+ /* 0x4b21 - 0x4b7e */
+ 0x72fe, 0x7302, 0x7304, 0x7305, 0x7307, 0x730b, 0x730d,
+ 0x7312, 0x7313, 0x7318, 0x7319, 0x731e, 0x7322, 0x7324, 0x7327,
+ 0x7328, 0x732c, 0x7331, 0x7332, 0x7335, 0x733a, 0x733b, 0x733d,
+ 0x7343, 0x734d, 0x7350, 0x7352, 0x7356, 0x7358, 0x735d, 0x735e,
+ 0x735f, 0x7360, 0x7366, 0x7367, 0x7369, 0x736b, 0x736c, 0x736e,
+ 0x736f, 0x7371, 0x7377, 0x7379, 0x737c, 0x7380, 0x7381, 0x7383,
+ 0x7385, 0x7386, 0x738e, 0x7390, 0x7393, 0x7395, 0x7397, 0x7398,
+ 0x739c, 0x739e, 0x739f, 0x73a0, 0x73a2, 0x73a5, 0x73a6, 0x73aa,
+ 0x73ab, 0x73ad, 0x73b5, 0x73b7, 0x73b9, 0x73bc, 0x73bd, 0x73bf,
+ 0x73c5, 0x73c6, 0x73c9, 0x73cb, 0x73cc, 0x73cf, 0x73d2, 0x73d3,
+ 0x73d6, 0x73d9, 0x73dd, 0x73e1, 0x73e3, 0x73e6, 0x73e7, 0x73e9,
+ 0x73f4, 0x73f5, 0x73f7, 0x73f9, 0x73fa, 0x73fb, 0x73fd,
+ /* 0x4c21 - 0x4c7e */
+ 0x73ff, 0x7400, 0x7401, 0x7404, 0x7407, 0x740a, 0x7411,
+ 0x741a, 0x741b, 0x7424, 0x7426, 0x7428, 0x7429, 0x742a, 0x742b,
+ 0x742c, 0x742d, 0x742e, 0x742f, 0x7430, 0x7431, 0x7439, 0x7440,
+ 0x7443, 0x7444, 0x7446, 0x7447, 0x744b, 0x744d, 0x7451, 0x7452,
+ 0x7457, 0x745d, 0x7462, 0x7466, 0x7467, 0x7468, 0x746b, 0x746d,
+ 0x746e, 0x7471, 0x7472, 0x7480, 0x7481, 0x7485, 0x7486, 0x7487,
+ 0x7489, 0x748f, 0x7490, 0x7491, 0x7492, 0x7498, 0x7499, 0x749a,
+ 0x749c, 0x749f, 0x74a0, 0x74a1, 0x74a3, 0x74a6, 0x74a8, 0x74a9,
+ 0x74aa, 0x74ab, 0x74ae, 0x74af, 0x74b1, 0x74b2, 0x74b5, 0x74b9,
+ 0x74bb, 0x74bf, 0x74c8, 0x74c9, 0x74cc, 0x74d0, 0x74d3, 0x74d8,
+ 0x74da, 0x74db, 0x74de, 0x74df, 0x74e4, 0x74e8, 0x74ea, 0x74eb,
+ 0x74ef, 0x74f4, 0x74fa, 0x74fb, 0x74fc, 0x74ff, 0x7506,
+ /* 0x4d21 - 0x4d7e */
+ 0x7512, 0x7516, 0x7517, 0x7520, 0x7521, 0x7524, 0x7527,
+ 0x7529, 0x752a, 0x752f, 0x7536, 0x7539, 0x753d, 0x753e, 0x753f,
+ 0x7540, 0x7543, 0x7547, 0x7548, 0x754e, 0x7550, 0x7552, 0x7557,
+ 0x755e, 0x755f, 0x7561, 0x756f, 0x7571, 0x7579, 0x757a, 0x757b,
+ 0x757c, 0x757d, 0x757e, 0x7581, 0x7585, 0x7590, 0x7592, 0x7593,
+ 0x7595, 0x7599, 0x759c, 0x75a2, 0x75a4, 0x75b4, 0x75ba, 0x75bf,
+ 0x75c0, 0x75c1, 0x75c4, 0x75c6, 0x75cc, 0x75ce, 0x75cf, 0x75d7,
+ 0x75dc, 0x75df, 0x75e0, 0x75e1, 0x75e4, 0x75e7, 0x75ec, 0x75ee,
+ 0x75ef, 0x75f1, 0x75f9, 0x7600, 0x7602, 0x7603, 0x7604, 0x7607,
+ 0x7608, 0x760a, 0x760c, 0x760f, 0x7612, 0x7613, 0x7615, 0x7616,
+ 0x7619, 0x761b, 0x761c, 0x761d, 0x761e, 0x7623, 0x7625, 0x7626,
+ 0x7629, 0x762d, 0x7632, 0x7633, 0x7635, 0x7638, 0x7639,
+ /* 0x4e21 - 0x4e7e */
+ 0x763a, 0x763c, 0x764a, 0x7640, 0x7641, 0x7643, 0x7644,
+ 0x7645, 0x7649, 0x764b, 0x7655, 0x7659, 0x765f, 0x7664, 0x7665,
+ 0x766d, 0x766e, 0x766f, 0x7671, 0x7674, 0x7681, 0x7685, 0x768c,
+ 0x768d, 0x7695, 0x769b, 0x769c, 0x769d, 0x769f, 0x76a0, 0x76a2,
+ 0x76a3, 0x76a4, 0x76a5, 0x76a6, 0x76a7, 0x76a8, 0x76aa, 0x76ad,
+ 0x76bd, 0x76c1, 0x76c5, 0x76c9, 0x76cb, 0x76cc, 0x76ce, 0x76d4,
+ 0x76d9, 0x76e0, 0x76e6, 0x76e8, 0x76ec, 0x76f0, 0x76f1, 0x76f6,
+ 0x76f9, 0x76fc, 0x7700, 0x7706, 0x770a, 0x770e, 0x7712, 0x7714,
+ 0x7715, 0x7717, 0x7719, 0x771a, 0x771c, 0x7722, 0x7728, 0x772d,
+ 0x772e, 0x772f, 0x7734, 0x7735, 0x7736, 0x7739, 0x773d, 0x773e,
+ 0x7742, 0x7745, 0x7746, 0x774a, 0x774d, 0x774e, 0x774f, 0x7752,
+ 0x7756, 0x7757, 0x775c, 0x775e, 0x775f, 0x7760, 0x7762,
+ /* 0x4f21 - 0x4f7e */
+ 0x7764, 0x7767, 0x776a, 0x776c, 0x7770, 0x7772, 0x7773,
+ 0x7774, 0x777a, 0x777d, 0x7780, 0x7784, 0x778c, 0x778d, 0x7794,
+ 0x7795, 0x7796, 0x779a, 0x779f, 0x77a2, 0x77a7, 0x77aa, 0x77ae,
+ 0x77af, 0x77b1, 0x77b5, 0x77be, 0x77c3, 0x77c9, 0x77d1, 0x77d2,
+ 0x77d5, 0x77d9, 0x77de, 0x77df, 0x77e0, 0x77e4, 0x77e6, 0x77ea,
+ 0x77ec, 0x77f0, 0x77f1, 0x77f4, 0x77f8, 0x77fb, 0x7805, 0x7806,
+ 0x7809, 0x780d, 0x780e, 0x7811, 0x781d, 0x7821, 0x7822, 0x7823,
+ 0x782d, 0x782e, 0x7830, 0x7835, 0x7837, 0x7843, 0x7844, 0x7847,
+ 0x7848, 0x784c, 0x784e, 0x7852, 0x785c, 0x785e, 0x7860, 0x7861,
+ 0x7863, 0x7864, 0x7868, 0x786a, 0x786e, 0x787a, 0x787e, 0x788a,
+ 0x788f, 0x7894, 0x7898, 0x78a1, 0x789d, 0x789e, 0x789f, 0x78a4,
+ 0x78a8, 0x78ac, 0x78ad, 0x78b0, 0x78b1, 0x78b2, 0x78b3,
+ /* 0x5021 - 0x507e */
+ 0x78bb, 0x78bd, 0x78bf, 0x78c7, 0x78c8, 0x78c9, 0x78cc,
+ 0x78ce, 0x78d2, 0x78d3, 0x78d5, 0x78d6, 0x78e4, 0x78db, 0x78df,
+ 0x78e0, 0x78e1, 0x78e6, 0x78ea, 0x78f2, 0x78f3, 0x7900, 0x78f6,
+ 0x78f7, 0x78fa, 0x78fb, 0x78ff, 0x7906, 0x790c, 0x7910, 0x791a,
+ 0x791c, 0x791e, 0x791f, 0x7920, 0x7925, 0x7927, 0x7929, 0x792d,
+ 0x7931, 0x7934, 0x7935, 0x793b, 0x793d, 0x793f, 0x7944, 0x7945,
+ 0x7946, 0x794a, 0x794b, 0x794f, 0x7951, 0x7954, 0x7958, 0x795b,
+ 0x795c, 0x7967, 0x7969, 0x796b, 0x7972, 0x7979, 0x797b, 0x797c,
+ 0x797e, 0x798b, 0x798c, 0x7991, 0x7993, 0x7994, 0x7995, 0x7996,
+ 0x7998, 0x799b, 0x799c, 0x79a1, 0x79a8, 0x79a9, 0x79ab, 0x79af,
+ 0x79b1, 0x79b4, 0x79b8, 0x79bb, 0x79c2, 0x79c4, 0x79c7, 0x79c8,
+ 0x79ca, 0x79cf, 0x79d4, 0x79d6, 0x79da, 0x79dd, 0x79de,
+ /* 0x5121 - 0x517e */
+ 0x79e0, 0x79e2, 0x79e5, 0x79ea, 0x79eb, 0x79ed, 0x79f1,
+ 0x79f8, 0x79fc, 0x7a02, 0x7a03, 0x7a07, 0x7a09, 0x7a0a, 0x7a0c,
+ 0x7a11, 0x7a15, 0x7a1b, 0x7a1e, 0x7a21, 0x7a27, 0x7a2b, 0x7a2d,
+ 0x7a2f, 0x7a30, 0x7a34, 0x7a35, 0x7a38, 0x7a39, 0x7a3a, 0x7a44,
+ 0x7a45, 0x7a47, 0x7a48, 0x7a4c, 0x7a55, 0x7a56, 0x7a59, 0x7a5c,
+ 0x7a5d, 0x7a5f, 0x7a60, 0x7a65, 0x7a67, 0x7a6a, 0x7a6d, 0x7a75,
+ 0x7a78, 0x7a7e, 0x7a80, 0x7a82, 0x7a85, 0x7a86, 0x7a8a, 0x7a8b,
+ 0x7a90, 0x7a91, 0x7a94, 0x7a9e, 0x7aa0, 0x7aa3, 0x7aac, 0x7ab3,
+ 0x7ab5, 0x7ab9, 0x7abb, 0x7abc, 0x7ac6, 0x7ac9, 0x7acc, 0x7ace,
+ 0x7ad1, 0x7adb, 0x7ae8, 0x7ae9, 0x7aeb, 0x7aec, 0x7af1, 0x7af4,
+ 0x7afb, 0x7afd, 0x7afe, 0x7b07, 0x7b14, 0x7b1f, 0x7b23, 0x7b27,
+ 0x7b29, 0x7b2a, 0x7b2b, 0x7b2d, 0x7b2e, 0x7b2f, 0x7b30,
+ /* 0x5221 - 0x527e */
+ 0x7b31, 0x7b34, 0x7b3d, 0x7b3f, 0x7b40, 0x7b41, 0x7b47,
+ 0x7b4e, 0x7b55, 0x7b60, 0x7b64, 0x7b66, 0x7b69, 0x7b6a, 0x7b6d,
+ 0x7b6f, 0x7b72, 0x7b73, 0x7b77, 0x7b84, 0x7b89, 0x7b8e, 0x7b90,
+ 0x7b91, 0x7b96, 0x7b9b, 0x7b9e, 0x7ba0, 0x7ba5, 0x7bac, 0x7baf,
+ 0x7bb0, 0x7bb2, 0x7bb5, 0x7bb6, 0x7bba, 0x7bbb, 0x7bbc, 0x7bbd,
+ 0x7bc2, 0x7bc5, 0x7bc8, 0x7bca, 0x7bd4, 0x7bd6, 0x7bd7, 0x7bd9,
+ 0x7bda, 0x7bdb, 0x7be8, 0x7bea, 0x7bf2, 0x7bf4, 0x7bf5, 0x7bf8,
+ 0x7bf9, 0x7bfa, 0x7bfc, 0x7bfe, 0x7c01, 0x7c02, 0x7c03, 0x7c04,
+ 0x7c06, 0x7c09, 0x7c0b, 0x7c0c, 0x7c0e, 0x7c0f, 0x7c19, 0x7c1b,
+ 0x7c20, 0x7c25, 0x7c26, 0x7c28, 0x7c2c, 0x7c31, 0x7c33, 0x7c34,
+ 0x7c36, 0x7c39, 0x7c3a, 0x7c46, 0x7c4a, 0x7c55, 0x7c51, 0x7c52,
+ 0x7c53, 0x7c59, 0x7c5a, 0x7c5b, 0x7c5c, 0x7c5d, 0x7c5e,
+ /* 0x5321 - 0x537e */
+ 0x7c61, 0x7c63, 0x7c67, 0x7c69, 0x7c6d, 0x7c6e, 0x7c70,
+ 0x7c72, 0x7c79, 0x7c7c, 0x7c7d, 0x7c86, 0x7c87, 0x7c8f, 0x7c94,
+ 0x7c9e, 0x7ca0, 0x7ca6, 0x7cb0, 0x7cb6, 0x7cb7, 0x7cba, 0x7cbb,
+ 0x7cbc, 0x7cbf, 0x7cc4, 0x7cc7, 0x7cc8, 0x7cc9, 0x7ccd, 0x7ccf,
+ 0x7cd3, 0x7cd4, 0x7cd5, 0x7cd7, 0x7cd9, 0x7cda, 0x7cdd, 0x7ce6,
+ 0x7ce9, 0x7ceb, 0x7cf5, 0x7d03, 0x7d07, 0x7d08, 0x7d09, 0x7d0f,
+ 0x7d11, 0x7d12, 0x7d13, 0x7d16, 0x7d1d, 0x7d1e, 0x7d23, 0x7d26,
+ 0x7d2a, 0x7d2d, 0x7d31, 0x7d3c, 0x7d3d, 0x7d3e, 0x7d40, 0x7d41,
+ 0x7d47, 0x7d48, 0x7d4d, 0x7d51, 0x7d53, 0x7d57, 0x7d59, 0x7d5a,
+ 0x7d5c, 0x7d5d, 0x7d65, 0x7d67, 0x7d6a, 0x7d70, 0x7d78, 0x7d7a,
+ 0x7d7b, 0x7d7f, 0x7d81, 0x7d82, 0x7d83, 0x7d85, 0x7d86, 0x7d88,
+ 0x7d8b, 0x7d8c, 0x7d8d, 0x7d91, 0x7d96, 0x7d97, 0x7d9d,
+ /* 0x5421 - 0x547e */
+ 0x7d9e, 0x7da6, 0x7da7, 0x7daa, 0x7db3, 0x7db6, 0x7db7,
+ 0x7db9, 0x7dc2, 0x7dc3, 0x7dc4, 0x7dc5, 0x7dc6, 0x7dcc, 0x7dcd,
+ 0x7dce, 0x7dd7, 0x7dd9, 0x7e00, 0x7de2, 0x7de5, 0x7de6, 0x7dea,
+ 0x7deb, 0x7ded, 0x7df1, 0x7df5, 0x7df6, 0x7df9, 0x7dfa, 0x7e08,
+ 0x7e10, 0x7e11, 0x7e15, 0x7e17, 0x7e1c, 0x7e1d, 0x7e20, 0x7e27,
+ 0x7e28, 0x7e2c, 0x7e2d, 0x7e2f, 0x7e33, 0x7e36, 0x7e3f, 0x7e44,
+ 0x7e45, 0x7e47, 0x7e4e, 0x7e50, 0x7e52, 0x7e58, 0x7e5f, 0x7e61,
+ 0x7e62, 0x7e65, 0x7e6b, 0x7e6e, 0x7e6f, 0x7e73, 0x7e78, 0x7e7e,
+ 0x7e81, 0x7e86, 0x7e87, 0x7e8a, 0x7e8d, 0x7e91, 0x7e95, 0x7e98,
+ 0x7e9a, 0x7e9d, 0x7e9e, 0x7f3c, 0x7f3b, 0x7f3d, 0x7f3e, 0x7f3f,
+ 0x7f43, 0x7f44, 0x7f47, 0x7f4f, 0x7f52, 0x7f53, 0x7f5b, 0x7f5c,
+ 0x7f5d, 0x7f61, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f6d,
+ /* 0x5521 - 0x557e */
+ 0x7f71, 0x7f7d, 0x7f7e, 0x7f7f, 0x7f80, 0x7f8b, 0x7f8d,
+ 0x7f8f, 0x7f90, 0x7f91, 0x7f96, 0x7f97, 0x7f9c, 0x7fa1, 0x7fa2,
+ 0x7fa6, 0x7faa, 0x7fad, 0x7fb4, 0x7fbc, 0x7fbf, 0x7fc0, 0x7fc3,
+ 0x7fc8, 0x7fce, 0x7fcf, 0x7fdb, 0x7fdf, 0x7fe3, 0x7fe5, 0x7fe8,
+ 0x7fec, 0x7fee, 0x7fef, 0x7ff2, 0x7ffa, 0x7ffd, 0x7ffe, 0x7fff,
+ 0x8007, 0x8008, 0x800a, 0x800d, 0x800e, 0x800f, 0x8011, 0x8013,
+ 0x8014, 0x8016, 0x801d, 0x801e, 0x801f, 0x8020, 0x8024, 0x8026,
+ 0x802c, 0x802e, 0x8030, 0x8034, 0x8035, 0x8037, 0x8039, 0x803a,
+ 0x803c, 0x803e, 0x8040, 0x8044, 0x8060, 0x8064, 0x8066, 0x806d,
+ 0x8071, 0x8075, 0x8081, 0x8088, 0x808e, 0x809c, 0x809e, 0x80a6,
+ 0x80a7, 0x80ab, 0x80b8, 0x80b9, 0x80c8, 0x80cd, 0x80cf, 0x80d2,
+ 0x80d4, 0x80d5, 0x80d7, 0x80d8, 0x80e0, 0x80ed, 0x80ee,
+ /* 0x5621 - 0x567e */
+ 0x80f0, 0x80f2, 0x80f3, 0x80f6, 0x80f9, 0x80fa, 0x80fe,
+ 0x8103, 0x810b, 0x8116, 0x8117, 0x8118, 0x811c, 0x811e, 0x8120,
+ 0x8124, 0x8127, 0x812c, 0x8130, 0x8135, 0x813a, 0x813c, 0x8145,
+ 0x8147, 0x814a, 0x814c, 0x8152, 0x8157, 0x8160, 0x8161, 0x8167,
+ 0x8168, 0x8169, 0x816d, 0x816f, 0x8177, 0x8181, 0x8190, 0x8184,
+ 0x8185, 0x8186, 0x818b, 0x818e, 0x8196, 0x8198, 0x819b, 0x819e,
+ 0x81a2, 0x81ae, 0x81b2, 0x81b4, 0x81bb, 0x81cb, 0x81c3, 0x81c5,
+ 0x81ca, 0x81ce, 0x81cf, 0x81d5, 0x81d7, 0x81db, 0x81dd, 0x81de,
+ 0x81e1, 0x81e4, 0x81eb, 0x81ec, 0x81f0, 0x81f1, 0x81f2, 0x81f5,
+ 0x81f6, 0x81f8, 0x81f9, 0x81fd, 0x81ff, 0x8200, 0x8203, 0x820f,
+ 0x8213, 0x8214, 0x8219, 0x821a, 0x821d, 0x8221, 0x8222, 0x8228,
+ 0x8232, 0x8234, 0x823a, 0x8243, 0x8244, 0x8245, 0x8246,
+ /* 0x5721 - 0x577e */
+ 0x824b, 0x824e, 0x824f, 0x8251, 0x8256, 0x825c, 0x8260,
+ 0x8263, 0x8267, 0x826d, 0x8274, 0x827b, 0x827d, 0x827f, 0x8280,
+ 0x8281, 0x8283, 0x8284, 0x8287, 0x8289, 0x828a, 0x828e, 0x8291,
+ 0x8294, 0x8296, 0x8298, 0x829a, 0x829b, 0x82a0, 0x82a1, 0x82a3,
+ 0x82a4, 0x82a7, 0x82a8, 0x82a9, 0x82aa, 0x82ae, 0x82b0, 0x82b2,
+ 0x82b4, 0x82b7, 0x82ba, 0x82bc, 0x82be, 0x82bf, 0x82c6, 0x82d0,
+ 0x82d5, 0x82da, 0x82e0, 0x82e2, 0x82e4, 0x82e8, 0x82ea, 0x82ed,
+ 0x82ef, 0x82f6, 0x82f7, 0x82fd, 0x82fe, 0x8300, 0x8301, 0x8307,
+ 0x8308, 0x830a, 0x830b, 0x8354, 0x831b, 0x831d, 0x831e, 0x831f,
+ 0x8321, 0x8322, 0x832c, 0x832d, 0x832e, 0x8330, 0x8333, 0x8337,
+ 0x833a, 0x833c, 0x833d, 0x8342, 0x8343, 0x8344, 0x8347, 0x834d,
+ 0x834e, 0x8351, 0x8355, 0x8356, 0x8357, 0x8370, 0x8378,
+ /* 0x5821 - 0x587e */
+ 0x837d, 0x837f, 0x8380, 0x8382, 0x8384, 0x8386, 0x838d,
+ 0x8392, 0x8394, 0x8395, 0x8398, 0x8399, 0x839b, 0x839c, 0x839d,
+ 0x83a6, 0x83a7, 0x83a9, 0x83ac, 0x83be, 0x83bf, 0x83c0, 0x83c7,
+ 0x83c9, 0x83cf, 0x83d0, 0x83d1, 0x83d4, 0x83dd, 0x8353, 0x83e8,
+ 0x83ea, 0x83f6, 0x83f8, 0x83f9, 0x83fc, 0x8401, 0x8406, 0x840a,
+ 0x840f, 0x8411, 0x8415, 0x8419, 0x83ad, 0x842f, 0x8439, 0x8445,
+ 0x8447, 0x8448, 0x844a, 0x844d, 0x844f, 0x8451, 0x8452, 0x8456,
+ 0x8458, 0x8459, 0x845a, 0x845c, 0x8460, 0x8464, 0x8465, 0x8467,
+ 0x846a, 0x8470, 0x8473, 0x8474, 0x8476, 0x8478, 0x847c, 0x847d,
+ 0x8481, 0x8485, 0x8492, 0x8493, 0x8495, 0x849e, 0x84a6, 0x84a8,
+ 0x84a9, 0x84aa, 0x84af, 0x84b1, 0x84b4, 0x84ba, 0x84bd, 0x84be,
+ 0x84c0, 0x84c2, 0x84c7, 0x84c8, 0x84cc, 0x84cf, 0x84d3,
+ /* 0x5921 - 0x597e */
+ 0x84dc, 0x84e7, 0x84ea, 0x84ef, 0x84f0, 0x84f1, 0x84f2,
+ 0x84f7, 0x8532, 0x84fa, 0x84fb, 0x84fd, 0x8502, 0x8503, 0x8507,
+ 0x850c, 0x850e, 0x8510, 0x851c, 0x851e, 0x8522, 0x8523, 0x8524,
+ 0x8525, 0x8527, 0x852a, 0x852b, 0x852f, 0x8533, 0x8534, 0x8536,
+ 0x853f, 0x8546, 0x854f, 0x8550, 0x8551, 0x8552, 0x8553, 0x8556,
+ 0x8559, 0x855c, 0x855d, 0x855e, 0x855f, 0x8560, 0x8561, 0x8562,
+ 0x8564, 0x856b, 0x856f, 0x8579, 0x857a, 0x857b, 0x857d, 0x857f,
+ 0x8581, 0x8585, 0x8586, 0x8589, 0x858b, 0x858c, 0x858f, 0x8593,
+ 0x8598, 0x859d, 0x859f, 0x85a0, 0x85a2, 0x85a5, 0x85a7, 0x85b4,
+ 0x85b6, 0x85b7, 0x85b8, 0x85bc, 0x85bd, 0x85be, 0x85bf, 0x85c2,
+ 0x85c7, 0x85ca, 0x85cb, 0x85ce, 0x85ad, 0x85d8, 0x85da, 0x85df,
+ 0x85e0, 0x85e6, 0x85e8, 0x85ed, 0x85f3, 0x85f6, 0x85fc,
+ /* 0x5a21 - 0x5a7e */
+ 0x85ff, 0x8600, 0x8604, 0x8605, 0x860d, 0x860e, 0x8610,
+ 0x8611, 0x8612, 0x8618, 0x8619, 0x861b, 0x861e, 0x8621, 0x8627,
+ 0x8629, 0x8636, 0x8638, 0x863a, 0x863c, 0x863d, 0x8640, 0x8642,
+ 0x8646, 0x8652, 0x8653, 0x8656, 0x8657, 0x8658, 0x8659, 0x865d,
+ 0x8660, 0x8661, 0x8662, 0x8663, 0x8664, 0x8669, 0x866c, 0x866f,
+ 0x8675, 0x8676, 0x8677, 0x867a, 0x868d, 0x8691, 0x8696, 0x8698,
+ 0x869a, 0x869c, 0x86a1, 0x86a6, 0x86a7, 0x86a8, 0x86ad, 0x86b1,
+ 0x86b3, 0x86b4, 0x86b5, 0x86b7, 0x86b8, 0x86b9, 0x86bf, 0x86c0,
+ 0x86c1, 0x86c3, 0x86c5, 0x86d1, 0x86d2, 0x86d5, 0x86d7, 0x86da,
+ 0x86dc, 0x86e0, 0x86e3, 0x86e5, 0x86e7, 0x8688, 0x86fa, 0x86fc,
+ 0x86fd, 0x8704, 0x8705, 0x8707, 0x870b, 0x870e, 0x870f, 0x8710,
+ 0x8713, 0x8714, 0x8719, 0x871e, 0x871f, 0x8721, 0x8723,
+ /* 0x5b21 - 0x5b7e */
+ 0x8728, 0x872e, 0x872f, 0x8731, 0x8732, 0x8739, 0x873a,
+ 0x873c, 0x873d, 0x873e, 0x8740, 0x8743, 0x8745, 0x874d, 0x8758,
+ 0x875d, 0x8761, 0x8764, 0x8765, 0x876f, 0x8771, 0x8772, 0x877b,
+ 0x8783, 0x8784, 0x8785, 0x8786, 0x8787, 0x8788, 0x8789, 0x878b,
+ 0x878c, 0x8790, 0x8793, 0x8795, 0x8797, 0x8798, 0x8799, 0x879e,
+ 0x87a0, 0x87a3, 0x87a7, 0x87ac, 0x87ad, 0x87ae, 0x87b1, 0x87b5,
+ 0x87be, 0x87bf, 0x87c1, 0x87c8, 0x87c9, 0x87ca, 0x87ce, 0x87d5,
+ 0x87d6, 0x87d9, 0x87da, 0x87dc, 0x87df, 0x87e2, 0x87e3, 0x87e4,
+ 0x87ea, 0x87eb, 0x87ed, 0x87f1, 0x87f3, 0x87f8, 0x87fa, 0x87ff,
+ 0x8801, 0x8803, 0x8806, 0x8809, 0x880a, 0x880b, 0x8810, 0x8819,
+ 0x8812, 0x8813, 0x8814, 0x8818, 0x881a, 0x881b, 0x881c, 0x881e,
+ 0x881f, 0x8828, 0x882d, 0x882e, 0x8830, 0x8832, 0x8835,
+ /* 0x5c21 - 0x5c7e */
+ 0x883a, 0x883c, 0x8841, 0x8843, 0x8845, 0x8848, 0x8849,
+ 0x884a, 0x884b, 0x884e, 0x8851, 0x8855, 0x8856, 0x8858, 0x885a,
+ 0x885c, 0x885f, 0x8860, 0x8864, 0x8869, 0x8871, 0x8879, 0x887b,
+ 0x8880, 0x8898, 0x889a, 0x889b, 0x889c, 0x889f, 0x88a0, 0x88a8,
+ 0x88aa, 0x88ba, 0x88bd, 0x88be, 0x88c0, 0x88ca, 0x88cb, 0x88cc,
+ 0x88cd, 0x88ce, 0x88d1, 0x88d2, 0x88d3, 0x88db, 0x88de, 0x88e7,
+ 0x88ef, 0x88f0, 0x88f1, 0x88f5, 0x88f7, 0x8901, 0x8906, 0x890d,
+ 0x890e, 0x890f, 0x8915, 0x8916, 0x8918, 0x8919, 0x891a, 0x891c,
+ 0x8920, 0x8926, 0x8927, 0x8928, 0x8930, 0x8931, 0x8932, 0x8935,
+ 0x8939, 0x893a, 0x893e, 0x8940, 0x8942, 0x8945, 0x8946, 0x8949,
+ 0x894f, 0x8952, 0x8957, 0x895a, 0x895b, 0x895c, 0x8961, 0x8962,
+ 0x8963, 0x896b, 0x896e, 0x8970, 0x8973, 0x8975, 0x897a,
+ /* 0x5d21 - 0x5d7e */
+ 0x897b, 0x897c, 0x897d, 0x8989, 0x898d, 0x8990, 0x8994,
+ 0x8995, 0x899b, 0x899c, 0x899f, 0x89a0, 0x89a5, 0x89b0, 0x89b4,
+ 0x89b5, 0x89b6, 0x89b7, 0x89bc, 0x89d4, 0x89d5, 0x89d6, 0x89d7,
+ 0x89d8, 0x89e5, 0x89e9, 0x89eb, 0x89ed, 0x89f1, 0x89f3, 0x89f6,
+ 0x89f9, 0x89fd, 0x89ff, 0x8a04, 0x8a05, 0x8a07, 0x8a0f, 0x8a11,
+ 0x8a12, 0x8a14, 0x8a15, 0x8a1e, 0x8a20, 0x8a22, 0x8a24, 0x8a26,
+ 0x8a2b, 0x8a2c, 0x8a2f, 0x8a35, 0x8a37, 0x8a3d, 0x8a3e, 0x8a40,
+ 0x8a43, 0x8a45, 0x8a47, 0x8a49, 0x8a4d, 0x8a4e, 0x8a53, 0x8a56,
+ 0x8a57, 0x8a58, 0x8a5c, 0x8a5d, 0x8a61, 0x8a65, 0x8a67, 0x8a75,
+ 0x8a76, 0x8a77, 0x8a79, 0x8a7a, 0x8a7b, 0x8a7e, 0x8a7f, 0x8a80,
+ 0x8a83, 0x8a86, 0x8a8b, 0x8a8f, 0x8a90, 0x8a92, 0x8a96, 0x8a97,
+ 0x8a99, 0x8a9f, 0x8aa7, 0x8aa9, 0x8aae, 0x8aaf, 0x8ab3,
+ /* 0x5e21 - 0x5e7e */
+ 0x8ab6, 0x8ab7, 0x8abb, 0x8abe, 0x8ac3, 0x8ac6, 0x8ac8,
+ 0x8ac9, 0x8aca, 0x8ad1, 0x8ad3, 0x8ad4, 0x8ad5, 0x8ad7, 0x8add,
+ 0x8adf, 0x8aec, 0x8af0, 0x8af4, 0x8af5, 0x8af6, 0x8afc, 0x8aff,
+ 0x8b05, 0x8b06, 0x8b0b, 0x8b11, 0x8b1c, 0x8b1e, 0x8b1f, 0x8b0a,
+ 0x8b2d, 0x8b30, 0x8b37, 0x8b3c, 0x8b42, 0x8b43, 0x8b44, 0x8b45,
+ 0x8b46, 0x8b48, 0x8b52, 0x8b53, 0x8b54, 0x8b59, 0x8b4d, 0x8b5e,
+ 0x8b63, 0x8b6d, 0x8b76, 0x8b78, 0x8b79, 0x8b7c, 0x8b7e, 0x8b81,
+ 0x8b84, 0x8b85, 0x8b8b, 0x8b8d, 0x8b8f, 0x8b94, 0x8b95, 0x8b9c,
+ 0x8b9e, 0x8b9f, 0x8c38, 0x8c39, 0x8c3d, 0x8c3e, 0x8c45, 0x8c47,
+ 0x8c49, 0x8c4b, 0x8c4f, 0x8c51, 0x8c53, 0x8c54, 0x8c57, 0x8c58,
+ 0x8c5b, 0x8c5d, 0x8c59, 0x8c63, 0x8c64, 0x8c66, 0x8c68, 0x8c69,
+ 0x8c6d, 0x8c73, 0x8c75, 0x8c76, 0x8c7b, 0x8c7e, 0x8c86,
+ /* 0x5f21 - 0x5f7e */
+ 0x8c87, 0x8c8b, 0x8c90, 0x8c92, 0x8c93, 0x8c99, 0x8c9b,
+ 0x8c9c, 0x8ca4, 0x8cb9, 0x8cba, 0x8cc5, 0x8cc6, 0x8cc9, 0x8ccb,
+ 0x8ccf, 0x8cd6, 0x8cd5, 0x8cd9, 0x8cdd, 0x8ce1, 0x8ce8, 0x8cec,
+ 0x8cef, 0x8cf0, 0x8cf2, 0x8cf5, 0x8cf7, 0x8cf8, 0x8cfe, 0x8cff,
+ 0x8d01, 0x8d03, 0x8d09, 0x8d12, 0x8d17, 0x8d1b, 0x8d65, 0x8d69,
+ 0x8d6c, 0x8d6e, 0x8d7f, 0x8d82, 0x8d84, 0x8d88, 0x8d8d, 0x8d90,
+ 0x8d91, 0x8d95, 0x8d9e, 0x8d9f, 0x8da0, 0x8da6, 0x8dab, 0x8dac,
+ 0x8daf, 0x8db2, 0x8db5, 0x8db7, 0x8db9, 0x8dbb, 0x8dc0, 0x8dc5,
+ 0x8dc6, 0x8dc7, 0x8dc8, 0x8dca, 0x8dce, 0x8dd1, 0x8dd4, 0x8dd5,
+ 0x8dd7, 0x8dd9, 0x8de4, 0x8de5, 0x8de7, 0x8dec, 0x8df0, 0x8dbc,
+ 0x8df1, 0x8df2, 0x8df4, 0x8dfd, 0x8e01, 0x8e04, 0x8e05, 0x8e06,
+ 0x8e0b, 0x8e11, 0x8e14, 0x8e16, 0x8e20, 0x8e21, 0x8e22,
+ /* 0x6021 - 0x607e */
+ 0x8e23, 0x8e26, 0x8e27, 0x8e31, 0x8e33, 0x8e36, 0x8e37,
+ 0x8e38, 0x8e39, 0x8e3d, 0x8e40, 0x8e41, 0x8e4b, 0x8e4d, 0x8e4e,
+ 0x8e4f, 0x8e54, 0x8e5b, 0x8e5c, 0x8e5d, 0x8e5e, 0x8e61, 0x8e62,
+ 0x8e69, 0x8e6c, 0x8e6d, 0x8e6f, 0x8e70, 0x8e71, 0x8e79, 0x8e7a,
+ 0x8e7b, 0x8e82, 0x8e83, 0x8e89, 0x8e90, 0x8e92, 0x8e95, 0x8e9a,
+ 0x8e9b, 0x8e9d, 0x8e9e, 0x8ea2, 0x8ea7, 0x8ea9, 0x8ead, 0x8eae,
+ 0x8eb3, 0x8eb5, 0x8eba, 0x8ebb, 0x8ec0, 0x8ec1, 0x8ec3, 0x8ec4,
+ 0x8ec7, 0x8ecf, 0x8ed1, 0x8ed4, 0x8edc, 0x8ee8, 0x8eee, 0x8ef0,
+ 0x8ef1, 0x8ef7, 0x8ef9, 0x8efa, 0x8eed, 0x8f00, 0x8f02, 0x8f07,
+ 0x8f08, 0x8f0f, 0x8f10, 0x8f16, 0x8f17, 0x8f18, 0x8f1e, 0x8f20,
+ 0x8f21, 0x8f23, 0x8f25, 0x8f27, 0x8f28, 0x8f2c, 0x8f2d, 0x8f2e,
+ 0x8f34, 0x8f35, 0x8f36, 0x8f37, 0x8f3a, 0x8f40, 0x8f41,
+ /* 0x6121 - 0x617e */
+ 0x8f43, 0x8f47, 0x8f4f, 0x8f51, 0x8f52, 0x8f53, 0x8f54,
+ 0x8f55, 0x8f58, 0x8f5d, 0x8f5e, 0x8f65, 0x8f9d, 0x8fa0, 0x8fa1,
+ 0x8fa4, 0x8fa5, 0x8fa6, 0x8fb5, 0x8fb6, 0x8fb8, 0x8fbe, 0x8fc0,
+ 0x8fc1, 0x8fc6, 0x8fca, 0x8fcb, 0x8fcd, 0x8fd0, 0x8fd2, 0x8fd3,
+ 0x8fd5, 0x8fe0, 0x8fe3, 0x8fe4, 0x8fe8, 0x8fee, 0x8ff1, 0x8ff5,
+ 0x8ff6, 0x8ffb, 0x8ffe, 0x9002, 0x9004, 0x9008, 0x900c, 0x9018,
+ 0x901b, 0x9028, 0x9029, 0x902f, 0x902a, 0x902c, 0x902d, 0x9033,
+ 0x9034, 0x9037, 0x903f, 0x9043, 0x9044, 0x904c, 0x905b, 0x905d,
+ 0x9062, 0x9066, 0x9067, 0x906c, 0x9070, 0x9074, 0x9079, 0x9085,
+ 0x9088, 0x908b, 0x908c, 0x908e, 0x9090, 0x9095, 0x9097, 0x9098,
+ 0x9099, 0x909b, 0x90a0, 0x90a1, 0x90a2, 0x90a5, 0x90b0, 0x90b2,
+ 0x90b3, 0x90b4, 0x90b6, 0x90bd, 0x90cc, 0x90be, 0x90c3,
+ /* 0x6221 - 0x627e */
+ 0x90c4, 0x90c5, 0x90c7, 0x90c8, 0x90d5, 0x90d7, 0x90d8,
+ 0x90d9, 0x90dc, 0x90dd, 0x90df, 0x90e5, 0x90d2, 0x90f6, 0x90eb,
+ 0x90ef, 0x90f0, 0x90f4, 0x90fe, 0x90ff, 0x9100, 0x9104, 0x9105,
+ 0x9106, 0x9108, 0x910d, 0x9110, 0x9114, 0x9116, 0x9117, 0x9118,
+ 0x911a, 0x911c, 0x911e, 0x9120, 0x9125, 0x9122, 0x9123, 0x9127,
+ 0x9129, 0x912e, 0x912f, 0x9131, 0x9134, 0x9136, 0x9137, 0x9139,
+ 0x913a, 0x913c, 0x913d, 0x9143, 0x9147, 0x9148, 0x914f, 0x9153,
+ 0x9157, 0x9159, 0x915a, 0x915b, 0x9161, 0x9164, 0x9167, 0x916d,
+ 0x9174, 0x9179, 0x917a, 0x917b, 0x9181, 0x9183, 0x9185, 0x9186,
+ 0x918a, 0x918e, 0x9191, 0x9193, 0x9194, 0x9195, 0x9198, 0x919e,
+ 0x91a1, 0x91a6, 0x91a8, 0x91ac, 0x91ad, 0x91ae, 0x91b0, 0x91b1,
+ 0x91b2, 0x91b3, 0x91b6, 0x91bb, 0x91bc, 0x91bd, 0x91bf,
+ /* 0x6321 - 0x637e */
+ 0x91c2, 0x91c3, 0x91c5, 0x91d3, 0x91d4, 0x91d7, 0x91d9,
+ 0x91da, 0x91de, 0x91e4, 0x91e5, 0x91e9, 0x91ea, 0x91ec, 0x91ed,
+ 0x91ee, 0x91ef, 0x91f0, 0x91f1, 0x91f7, 0x91f9, 0x91fb, 0x91fd,
+ 0x9200, 0x9201, 0x9204, 0x9205, 0x9206, 0x9207, 0x9209, 0x920a,
+ 0x920c, 0x9210, 0x9212, 0x9213, 0x9216, 0x9218, 0x921c, 0x921d,
+ 0x9223, 0x9224, 0x9225, 0x9226, 0x9228, 0x922e, 0x922f, 0x9230,
+ 0x9233, 0x9235, 0x9236, 0x9238, 0x9239, 0x923a, 0x923c, 0x923e,
+ 0x9240, 0x9242, 0x9243, 0x9246, 0x9247, 0x924a, 0x924d, 0x924e,
+ 0x924f, 0x9251, 0x9258, 0x9259, 0x925c, 0x925d, 0x9260, 0x9261,
+ 0x9265, 0x9267, 0x9268, 0x9269, 0x926e, 0x926f, 0x9270, 0x9275,
+ 0x9276, 0x9277, 0x9278, 0x9279, 0x927b, 0x927c, 0x927d, 0x927f,
+ 0x9288, 0x9289, 0x928a, 0x928d, 0x928e, 0x9292, 0x9297,
+ /* 0x6421 - 0x647e */
+ 0x9299, 0x929f, 0x92a0, 0x92a4, 0x92a5, 0x92a7, 0x92a8,
+ 0x92ab, 0x92af, 0x92b2, 0x92b6, 0x92b8, 0x92ba, 0x92bb, 0x92bc,
+ 0x92bd, 0x92bf, 0x92c0, 0x92c1, 0x92c2, 0x92c3, 0x92c5, 0x92c6,
+ 0x92c7, 0x92c8, 0x92cb, 0x92cc, 0x92cd, 0x92ce, 0x92d0, 0x92d3,
+ 0x92d5, 0x92d7, 0x92d8, 0x92d9, 0x92dc, 0x92dd, 0x92df, 0x92e0,
+ 0x92e1, 0x92e3, 0x92e5, 0x92e7, 0x92e8, 0x92ec, 0x92ee, 0x92f0,
+ 0x92f9, 0x92fb, 0x92ff, 0x9300, 0x9302, 0x9308, 0x930d, 0x9311,
+ 0x9314, 0x9315, 0x931c, 0x931d, 0x931e, 0x931f, 0x9321, 0x9324,
+ 0x9325, 0x9327, 0x9329, 0x932a, 0x9333, 0x9334, 0x9336, 0x9337,
+ 0x9347, 0x9348, 0x9349, 0x9350, 0x9351, 0x9352, 0x9355, 0x9357,
+ 0x9358, 0x935a, 0x935e, 0x9364, 0x9365, 0x9367, 0x9369, 0x936a,
+ 0x936d, 0x936f, 0x9370, 0x9371, 0x9373, 0x9374, 0x9376,
+ /* 0x6521 - 0x657e */
+ 0x937a, 0x937d, 0x937f, 0x9380, 0x9381, 0x9382, 0x9388,
+ 0x938a, 0x938b, 0x938d, 0x938f, 0x9392, 0x9395, 0x9398, 0x939b,
+ 0x939e, 0x93a1, 0x93a3, 0x93a4, 0x93a6, 0x93a8, 0x93ab, 0x93b4,
+ 0x93b5, 0x93b6, 0x93ba, 0x93a9, 0x93c1, 0x93c4, 0x93c5, 0x93c6,
+ 0x93c7, 0x93c9, 0x93ca, 0x93cb, 0x93cc, 0x93cd, 0x93d3, 0x93d9,
+ 0x93dc, 0x93de, 0x93df, 0x93e2, 0x93e6, 0x93e7, 0x93f9, 0x93f7,
+ 0x93f8, 0x93fa, 0x93fb, 0x93fd, 0x9401, 0x9402, 0x9404, 0x9408,
+ 0x9409, 0x940d, 0x940e, 0x940f, 0x9415, 0x9416, 0x9417, 0x941f,
+ 0x942e, 0x942f, 0x9431, 0x9432, 0x9433, 0x9434, 0x943b, 0x943f,
+ 0x943d, 0x9443, 0x9445, 0x9448, 0x944a, 0x944c, 0x9455, 0x9459,
+ 0x945c, 0x945f, 0x9461, 0x9463, 0x9468, 0x946b, 0x946d, 0x946e,
+ 0x946f, 0x9471, 0x9472, 0x9484, 0x9483, 0x9578, 0x9579,
+ /* 0x6621 - 0x667e */
+ 0x957e, 0x9584, 0x9588, 0x958c, 0x958d, 0x958e, 0x959d,
+ 0x959e, 0x959f, 0x95a1, 0x95a6, 0x95a9, 0x95ab, 0x95ac, 0x95b4,
+ 0x95b6, 0x95ba, 0x95bd, 0x95bf, 0x95c6, 0x95c8, 0x95c9, 0x95cb,
+ 0x95d0, 0x95d1, 0x95d2, 0x95d3, 0x95d9, 0x95da, 0x95dd, 0x95de,
+ 0x95df, 0x95e0, 0x95e4, 0x95e6, 0x961d, 0x961e, 0x9622, 0x9624,
+ 0x9625, 0x9626, 0x962c, 0x9631, 0x9633, 0x9637, 0x9638, 0x9639,
+ 0x963a, 0x963c, 0x963d, 0x9641, 0x9652, 0x9654, 0x9656, 0x9657,
+ 0x9658, 0x9661, 0x966e, 0x9674, 0x967b, 0x967c, 0x967e, 0x967f,
+ 0x9681, 0x9682, 0x9683, 0x9684, 0x9689, 0x9691, 0x9696, 0x969a,
+ 0x969d, 0x969f, 0x96a4, 0x96a5, 0x96a6, 0x96a9, 0x96ae, 0x96af,
+ 0x96b3, 0x96ba, 0x96ca, 0x96d2, 0x5db2, 0x96d8, 0x96da, 0x96dd,
+ 0x96de, 0x96df, 0x96e9, 0x96ef, 0x96f1, 0x96fa, 0x9702,
+ /* 0x6721 - 0x677e */
+ 0x9703, 0x9705, 0x9709, 0x971a, 0x971b, 0x971d, 0x9721,
+ 0x9722, 0x9723, 0x9728, 0x9731, 0x9733, 0x9741, 0x9743, 0x974a,
+ 0x974e, 0x974f, 0x9755, 0x9757, 0x9758, 0x975a, 0x975b, 0x9763,
+ 0x9767, 0x976a, 0x976e, 0x9773, 0x9776, 0x9777, 0x9778, 0x977b,
+ 0x977d, 0x977f, 0x9780, 0x9789, 0x9795, 0x9796, 0x9797, 0x9799,
+ 0x979a, 0x979e, 0x979f, 0x97a2, 0x97ac, 0x97ae, 0x97b1, 0x97b2,
+ 0x97b5, 0x97b6, 0x97b8, 0x97b9, 0x97ba, 0x97bc, 0x97be, 0x97bf,
+ 0x97c1, 0x97c4, 0x97c5, 0x97c7, 0x97c9, 0x97ca, 0x97cc, 0x97cd,
+ 0x97ce, 0x97d0, 0x97d1, 0x97d4, 0x97d7, 0x97d8, 0x97d9, 0x97dd,
+ 0x97de, 0x97e0, 0x97db, 0x97e1, 0x97e4, 0x97ef, 0x97f1, 0x97f4,
+ 0x97f7, 0x97f8, 0x97fa, 0x9807, 0x980a, 0x9819, 0x980d, 0x980e,
+ 0x9814, 0x9816, 0x981c, 0x981e, 0x9820, 0x9823, 0x9826,
+ /* 0x6821 - 0x687e */
+ 0x982b, 0x982e, 0x982f, 0x9830, 0x9832, 0x9833, 0x9835,
+ 0x9825, 0x983e, 0x9844, 0x9847, 0x984a, 0x9851, 0x9852, 0x9853,
+ 0x9856, 0x9857, 0x9859, 0x985a, 0x9862, 0x9863, 0x9865, 0x9866,
+ 0x986a, 0x986c, 0x98ab, 0x98ad, 0x98ae, 0x98b0, 0x98b4, 0x98b7,
+ 0x98b8, 0x98ba, 0x98bb, 0x98bf, 0x98c2, 0x98c5, 0x98c8, 0x98cc,
+ 0x98e1, 0x98e3, 0x98e5, 0x98e6, 0x98e7, 0x98ea, 0x98f3, 0x98f6,
+ 0x9902, 0x9907, 0x9908, 0x9911, 0x9915, 0x9916, 0x9917, 0x991a,
+ 0x991b, 0x991c, 0x991f, 0x9922, 0x9926, 0x9927, 0x992b, 0x9931,
+ 0x9932, 0x9933, 0x9934, 0x9935, 0x9939, 0x993a, 0x993b, 0x993c,
+ 0x9940, 0x9941, 0x9946, 0x9947, 0x9948, 0x994d, 0x994e, 0x9954,
+ 0x9958, 0x9959, 0x995b, 0x995c, 0x995e, 0x995f, 0x9960, 0x999b,
+ 0x999d, 0x999f, 0x99a6, 0x99b0, 0x99b1, 0x99b2, 0x99b5,
+ /* 0x6921 - 0x697e */
+ 0x99b9, 0x99ba, 0x99bd, 0x99bf, 0x99c3, 0x99c9, 0x99d3,
+ 0x99d4, 0x99d9, 0x99da, 0x99dc, 0x99de, 0x99e7, 0x99ea, 0x99eb,
+ 0x99ec, 0x99f0, 0x99f4, 0x99f5, 0x99f9, 0x99fd, 0x99fe, 0x9a02,
+ 0x9a03, 0x9a04, 0x9a0b, 0x9a0c, 0x9a10, 0x9a11, 0x9a16, 0x9a1e,
+ 0x9a20, 0x9a22, 0x9a23, 0x9a24, 0x9a27, 0x9a2d, 0x9a2e, 0x9a33,
+ 0x9a35, 0x9a36, 0x9a38, 0x9a47, 0x9a41, 0x9a44, 0x9a4a, 0x9a4b,
+ 0x9a4c, 0x9a4e, 0x9a51, 0x9a54, 0x9a56, 0x9a5d, 0x9aaa, 0x9aac,
+ 0x9aae, 0x9aaf, 0x9ab2, 0x9ab4, 0x9ab5, 0x9ab6, 0x9ab9, 0x9abb,
+ 0x9abe, 0x9abf, 0x9ac1, 0x9ac3, 0x9ac6, 0x9ac8, 0x9ace, 0x9ad0,
+ 0x9ad2, 0x9ad5, 0x9ad6, 0x9ad7, 0x9adb, 0x9adc, 0x9ae0, 0x9ae4,
+ 0x9ae5, 0x9ae7, 0x9ae9, 0x9aec, 0x9af2, 0x9af3, 0x9af5, 0x9af9,
+ 0x9afa, 0x9afd, 0x9aff, 0x9b00, 0x9b01, 0x9b02, 0x9b03,
+ /* 0x6a21 - 0x6a7e */
+ 0x9b04, 0x9b05, 0x9b08, 0x9b09, 0x9b0b, 0x9b0c, 0x9b0d,
+ 0x9b0e, 0x9b10, 0x9b12, 0x9b16, 0x9b19, 0x9b1b, 0x9b1c, 0x9b20,
+ 0x9b26, 0x9b2b, 0x9b2d, 0x9b33, 0x9b34, 0x9b35, 0x9b37, 0x9b39,
+ 0x9b3a, 0x9b3d, 0x9b48, 0x9b4b, 0x9b4c, 0x9b55, 0x9b56, 0x9b57,
+ 0x9b5b, 0x9b5e, 0x9b61, 0x9b63, 0x9b65, 0x9b66, 0x9b68, 0x9b6a,
+ 0x9b6b, 0x9b6c, 0x9b6d, 0x9b6e, 0x9b73, 0x9b75, 0x9b77, 0x9b78,
+ 0x9b79, 0x9b7f, 0x9b80, 0x9b84, 0x9b85, 0x9b86, 0x9b87, 0x9b89,
+ 0x9b8a, 0x9b8b, 0x9b8d, 0x9b8f, 0x9b90, 0x9b94, 0x9b9a, 0x9b9d,
+ 0x9b9e, 0x9ba6, 0x9ba7, 0x9ba9, 0x9bac, 0x9bb0, 0x9bb1, 0x9bb2,
+ 0x9bb7, 0x9bb8, 0x9bbb, 0x9bbc, 0x9bbe, 0x9bbf, 0x9bc1, 0x9bc7,
+ 0x9bc8, 0x9bce, 0x9bd0, 0x9bd7, 0x9bd8, 0x9bdd, 0x9bdf, 0x9be5,
+ 0x9be7, 0x9bea, 0x9beb, 0x9bef, 0x9bf3, 0x9bf7, 0x9bf8,
+ /* 0x6b21 - 0x6b7e */
+ 0x9bf9, 0x9bfa, 0x9bfd, 0x9bff, 0x9c00, 0x9c02, 0x9c0b,
+ 0x9c0f, 0x9c11, 0x9c16, 0x9c18, 0x9c19, 0x9c1a, 0x9c1c, 0x9c1e,
+ 0x9c22, 0x9c23, 0x9c26, 0x9c27, 0x9c28, 0x9c29, 0x9c2a, 0x9c31,
+ 0x9c35, 0x9c36, 0x9c37, 0x9c3d, 0x9c41, 0x9c43, 0x9c44, 0x9c45,
+ 0x9c49, 0x9c4a, 0x9c4e, 0x9c4f, 0x9c50, 0x9c53, 0x9c54, 0x9c56,
+ 0x9c58, 0x9c5b, 0x9c5d, 0x9c5e, 0x9c5f, 0x9c63, 0x9c69, 0x9c6a,
+ 0x9c5c, 0x9c6b, 0x9c68, 0x9c6e, 0x9c70, 0x9c72, 0x9c75, 0x9c77,
+ 0x9c7b, 0x9ce6, 0x9cf2, 0x9cf7, 0x9cf9, 0x9d0b, 0x9d02, 0x9d11,
+ 0x9d17, 0x9d18, 0x9d1c, 0x9d1d, 0x9d1e, 0x9d2f, 0x9d30, 0x9d32,
+ 0x9d33, 0x9d34, 0x9d3a, 0x9d3c, 0x9d45, 0x9d3d, 0x9d42, 0x9d43,
+ 0x9d47, 0x9d4a, 0x9d53, 0x9d54, 0x9d5f, 0x9d63, 0x9d62, 0x9d65,
+ 0x9d69, 0x9d6a, 0x9d6b, 0x9d70, 0x9d76, 0x9d77, 0x9d7b,
+ /* 0x6c21 - 0x6c7e */
+ 0x9d7c, 0x9d7e, 0x9d83, 0x9d84, 0x9d86, 0x9d8a, 0x9d8d,
+ 0x9d8e, 0x9d92, 0x9d93, 0x9d95, 0x9d96, 0x9d97, 0x9d98, 0x9da1,
+ 0x9daa, 0x9dac, 0x9dae, 0x9db1, 0x9db5, 0x9db9, 0x9dbc, 0x9dbf,
+ 0x9dc3, 0x9dc7, 0x9dc9, 0x9dca, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7,
+ 0x9dda, 0x9dde, 0x9ddf, 0x9de0, 0x9de5, 0x9de7, 0x9de9, 0x9deb,
+ 0x9dee, 0x9df0, 0x9df3, 0x9df4, 0x9dfe, 0x9e0a, 0x9e02, 0x9e07,
+ 0x9e0e, 0x9e10, 0x9e11, 0x9e12, 0x9e15, 0x9e16, 0x9e19, 0x9e1c,
+ 0x9e1d, 0x9e7a, 0x9e7b, 0x9e7c, 0x9e80, 0x9e82, 0x9e83, 0x9e84,
+ 0x9e85, 0x9e87, 0x9e8e, 0x9e8f, 0x9e96, 0x9e98, 0x9e9b, 0x9e9e,
+ 0x9ea4, 0x9ea8, 0x9eac, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb3, 0x9eb4,
+ 0x9eb5, 0x9ec6, 0x9ec8, 0x9ecb, 0x9ed5, 0x9edf, 0x9ee4, 0x9ee7,
+ 0x9eec, 0x9eed, 0x9eee, 0x9ef0, 0x9ef1, 0x9ef2, 0x9ef5,
+ /* 0x6d21 - 0x6d7e */
+ 0x9ef8, 0x9eff, 0x9f02, 0x9f03, 0x9f09, 0x9f0f, 0x9f10,
+ 0x9f11, 0x9f12, 0x9f14, 0x9f16, 0x9f17, 0x9f19, 0x9f1a, 0x9f1b,
+ 0x9f1f, 0x9f22, 0x9f26, 0x9f2a, 0x9f2b, 0x9f2f, 0x9f31, 0x9f32,
+ 0x9f34, 0x9f37, 0x9f39, 0x9f3a, 0x9f3c, 0x9f3d, 0x9f3f, 0x9f41,
+ 0x9f43, 0x9f44, 0x9f45, 0x9f46, 0x9f47, 0x9f53, 0x9f55, 0x9f56,
+ 0x9f57, 0x9f58, 0x9f5a, 0x9f5d, 0x9f5e, 0x9f68, 0x9f69, 0x9f6d,
+ 0x9f6e, 0x9f6f, 0x9f70, 0x9f71, 0x9f73, 0x9f75, 0x9f7a, 0x9f7d,
+ 0x9f8f, 0x9f90, 0x9f91, 0x9f92, 0x9f94, 0x9f96, 0x9f97, 0x9f9e,
+ 0x9fa1, 0x9fa2, 0x9fa3, 0x9fa5, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x6e21 - 0x6e7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x6f21 - 0x6f7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7021 - 0x707e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7121 - 0x717e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7221 - 0x727e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7321 - 0x737e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174,
+ 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x2160, 0x2161,
+ /* 0x7421 - 0x747e */
+ 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168,
+ 0x2169, 0xff07, 0xff02, 0x3231, 0x2116, 0x2121, 0x70bb, 0x4efc,
+ 0x50f4, 0x51ec, 0x5307, 0x5324, 0xfa0e, 0x548a, 0x5759, 0xfa0f,
+ 0xfa10, 0x589e, 0x5bec, 0x5cf5, 0x5d53, 0xfa11, 0x5fb7, 0x6085,
+ 0x6120, 0x654e, 0x663b, 0x6665, 0xfa12, 0xf929, 0x6801, 0xfa13,
+ 0xfa14, 0x6a6b, 0x6ae2, 0x6df8, 0x6df2, 0x7028, 0xfa15, 0xfa16,
+ 0x7501, 0x7682, 0x769e, 0xfa17, 0x7930, 0xfa18, 0xfa19, 0xfa1a,
+ 0xfa1b, 0x7ae7, 0xfa1c, 0xfa1d, 0x7da0, 0x7dd6, 0xfa1e, 0x8362,
+ 0xfa1f, 0x85b0, 0xfa20, 0xfa21, 0x8807, 0xfa22, 0x8b7f, 0x8cf4,
+ 0x8d76, 0xfa23, 0xfa24, 0xfa25, 0x90de, 0xfa26, 0x9115, 0xfa27,
+ 0xfa28, 0x9592, 0xf9dc, 0xfa29, 0x973b, 0x974d, 0x9751, 0xfa2a,
+ 0xfa2b, 0xfa2c, 0x999e, 0x9ad9, 0x9b72, 0xfa2d, 0x9ed1,
+ /* 0x7521 - 0x757e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7621 - 0x767e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7721 - 0x777e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7821 - 0x787e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7921 - 0x797e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7a21 - 0x7a7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7b21 - 0x7b7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7c21 - 0x7c7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7d21 - 0x7d7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ /* 0x7e21 - 0x7e7e */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+#endif
+
+#ifdef USE_JISX0212
+static uint jisx0212ToUnicode11(uint h, uint l)
+{
+ if ((0x0021 <= h) && (h <= 0x007e) && (0x0021 <= l) && (l <= 0x007e)) {
+ return jisx0212_to_tqunicode[(h - 0x0021) * 0x005e + (l - 0x0021)];
+ }
+ return 0x0000;
+}
+#else
+static uint jisx0212ToUnicode11(uint h, uint l)
+{
+ return 0x0000;
+}
+#endif
+
+#ifdef USE_JISX0212
+
+/*
+ * This data is derived from Unicode 1.1,
+ * JIS X 0212 (1990) to Unicode mapping table version 0.9 .
+ * (In addition IBM Vender Defined Char included)
+ */
+static unsigned short const tqunicode_to_jisx0212_00[] = {
+ /* 0x0000 - 0x00ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2237, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x2242, 0x0000, 0x0000, 0x2270, 0x0000, 0x2243, 0x0000,
+ 0x0000, 0x226d, 0x226c, 0x0000, 0x0000, 0x0000, 0x226e, 0x2234,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x2231, 0x0000, 0x226b, 0x0000, 0x0000, 0x0000, 0x0000, 0x2244,
+ 0x2a22, 0x2a21, 0x2a24, 0x2a2a, 0x2a23, 0x2a29, 0x2921, 0x2a2e,
+ 0x2a32, 0x2a31, 0x2a34, 0x2a33, 0x2a40, 0x2a3f, 0x2a42, 0x2a41,
+ 0x0000, 0x2a50, 0x2a52, 0x2a51, 0x2a54, 0x2a58, 0x2a53, 0x0000,
+ 0x292c, 0x2a63, 0x2a62, 0x2a65, 0x2a64, 0x2a72, 0x2930, 0x294e,
+ 0x2b22, 0x2b21, 0x2b24, 0x2b2a, 0x2b23, 0x2b29, 0x2941, 0x2b2e,
+ 0x2b32, 0x2b31, 0x2b34, 0x2b33, 0x2b40, 0x2b3f, 0x2b42, 0x2b41,
+ 0x2943, 0x2b50, 0x2b52, 0x2b51, 0x2b54, 0x2b58, 0x2b53, 0x0000,
+ 0x294c, 0x2b63, 0x2b62, 0x2b65, 0x2b64, 0x2b72, 0x2950, 0x2b73,
+};
+
+static unsigned short const tqunicode_to_jisx0212_01[] = {
+ /* 0x0100 - 0x01ff */
+ 0x2a27, 0x2b27, 0x2a25, 0x2b25, 0x2a28, 0x2b28, 0x2a2b, 0x2b2b,
+ 0x2a2c, 0x2b2c, 0x2a2f, 0x2b2f, 0x2a2d, 0x2b2d, 0x2a30, 0x2b30,
+ 0x2922, 0x2942, 0x2a37, 0x2b37, 0x0000, 0x0000, 0x2a36, 0x2b36,
+ 0x2a38, 0x2b38, 0x2a35, 0x2b35, 0x2a3a, 0x2b3a, 0x2a3b, 0x2b3b,
+ 0x2a3d, 0x2b3d, 0x2a3c, 0x0000, 0x2a3e, 0x2b3e, 0x2924, 0x2944,
+ 0x2a47, 0x2b47, 0x2a45, 0x2b45, 0x0000, 0x0000, 0x2a46, 0x2b46,
+ 0x2a44, 0x2945, 0x2926, 0x2946, 0x2a48, 0x2b48, 0x2a49, 0x2b49,
+ 0x2947, 0x2a4a, 0x2b4a, 0x2a4c, 0x2b4c, 0x2a4b, 0x2b4b, 0x2929,
+ 0x2949, 0x2928, 0x2948, 0x2a4d, 0x2b4d, 0x2a4f, 0x2b4f, 0x2a4e,
+ 0x2b4e, 0x294a, 0x292b, 0x294b, 0x2a57, 0x2b57, 0x0000, 0x0000,
+ 0x2a56, 0x2b56, 0x292d, 0x294d, 0x2a59, 0x2b59, 0x2a5b, 0x2b5b,
+ 0x2a5a, 0x2b5a, 0x2a5c, 0x2b5c, 0x2a5d, 0x2b5d, 0x2a5f, 0x2b5f,
+ 0x2a5e, 0x2b5e, 0x2a61, 0x2b61, 0x2a60, 0x2b60, 0x292f, 0x294f,
+ 0x2a6c, 0x2b6c, 0x2a69, 0x2b69, 0x2a66, 0x2b66, 0x2a6b, 0x2b6b,
+ 0x2a68, 0x2b68, 0x2a6a, 0x2b6a, 0x2a71, 0x2b71, 0x2a74, 0x2b74,
+ 0x2a73, 0x2a75, 0x2b75, 0x2a77, 0x2b77, 0x2a76, 0x2b76, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2a26, 0x2b26, 0x2a43,
+ 0x2b43, 0x2a55, 0x2b55, 0x2a67, 0x2b67, 0x2a70, 0x2b70, 0x2a6d,
+ 0x2b6d, 0x2a6f, 0x2b6f, 0x2a6e, 0x2b6e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2b39, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_02[] = {
+ /* 0x0200 - 0x02ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2230,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x222f, 0x2232, 0x2236, 0x2235, 0x0000, 0x2233, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_03[] = {
+ /* 0x0300 - 0x03ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2238, 0x2239, 0x2661, 0x0000,
+ 0x2662, 0x2663, 0x2664, 0x0000, 0x2667, 0x0000, 0x2669, 0x266c,
+ 0x2676, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2665, 0x266a, 0x2671, 0x2672, 0x2673, 0x2674,
+ 0x267b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2678, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2675, 0x267a, 0x2677, 0x2679, 0x267c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_04[] = {
+ /* 0x0400 - 0x04ff */
+ 0x0000, 0x0000, 0x2742, 0x2743, 0x2744, 0x2745, 0x2746, 0x2747,
+ 0x2748, 0x2749, 0x274a, 0x274b, 0x274c, 0x0000, 0x274d, 0x274e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x2772, 0x2773, 0x2774, 0x2775, 0x2776, 0x2777,
+ 0x2778, 0x2779, 0x277a, 0x277b, 0x277c, 0x0000, 0x277d, 0x277e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_21[] = {
+ /* 0x2100 - 0x21ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2271, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x742d, 0x226f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x737d, 0x737e, 0x7421, 0x7422, 0x7423, 0x7424, 0x7425, 0x7426,
+ 0x7427, 0x7428, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x7373, 0x7374, 0x7375, 0x7376, 0x7377, 0x7378, 0x7379, 0x737a,
+ 0x737b, 0x737c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_32[] = {
+ /* 0x3200 - 0x32ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x742b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_4e[] = {
+ /* 0x4e00 - 0x4eff */
+ 0x0000, 0x0000, 0x3021, 0x0000, 0x3022, 0x3023, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3024, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3025, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3026,
+ 0x0000, 0x0000, 0x0000, 0x3027, 0x3028, 0x0000, 0x0000, 0x0000,
+ 0x3029, 0x0000, 0x0000, 0x302a, 0x0000, 0x0000, 0x302b, 0x302c,
+ 0x302d, 0x0000, 0x0000, 0x0000, 0x0000, 0x302e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x302f, 0x3030, 0x0000, 0x0000, 0x3031, 0x0000, 0x0000, 0x3032,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3034, 0x0000, 0x3035, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3036, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3037, 0x3038, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3039, 0x303a, 0x0000, 0x0000,
+ 0x0000, 0x303b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x303c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x303d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x303e, 0x303f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3040, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3041,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3042, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3043, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3045, 0x3046, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3047, 0x3048, 0x3049, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x304a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x304b,
+ 0x0000, 0x304c, 0x0000, 0x304d, 0x0000, 0x304e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x742f, 0x304f, 0x3050, 0x3051,
+};
+
+static unsigned short const tqunicode_to_jisx0212_4f[] = {
+ /* 0x4f00 - 0x4fff */
+ 0x3052, 0x0000, 0x3053, 0x3054, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3055, 0x0000, 0x0000, 0x3056, 0x3057, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3058, 0x0000, 0x0000, 0x3059, 0x305a, 0x305b,
+ 0x0000, 0x305c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x305d, 0x0000,
+ 0x0000, 0x305e, 0x0000, 0x3060, 0x0000, 0x3061, 0x0000, 0x3062,
+ 0x0000, 0x3063, 0x0000, 0x3064, 0x0000, 0x0000, 0x3065, 0x0000,
+ 0x3066, 0x0000, 0x3067, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3068, 0x3069, 0x0000, 0x306a, 0x306b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x306c, 0x0000, 0x306d, 0x0000, 0x306e, 0x0000,
+ 0x306f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3070,
+ 0x305f, 0x0000, 0x0000, 0x3071, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3072, 0x0000, 0x3073, 0x0000, 0x3074, 0x0000,
+ 0x0000, 0x3075, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3076,
+ 0x3077, 0x3078, 0x3079, 0x0000, 0x0000, 0x307a, 0x307b, 0x0000,
+ 0x0000, 0x307c, 0x307d, 0x0000, 0x307e, 0x3121, 0x0000, 0x0000,
+ 0x0000, 0x3122, 0x3123, 0x0000, 0x3124, 0x0000, 0x3125, 0x0000,
+ 0x3126, 0x0000, 0x3127, 0x3128, 0x3129, 0x0000, 0x0000, 0x312a,
+ 0x0000, 0x312b, 0x312c, 0x0000, 0x0000, 0x0000, 0x312d, 0x312e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x312f, 0x0000, 0x0000, 0x0000, 0x0000, 0x3130,
+ 0x0000, 0x3131, 0x0000, 0x3132, 0x3133, 0x3134, 0x3135, 0x0000,
+ 0x3136, 0x3137, 0x0000, 0x0000, 0x0000, 0x3138, 0x3139, 0x0000,
+ 0x313a, 0x313b, 0x0000, 0x313c, 0x313d, 0x313e, 0x0000, 0x313f,
+ 0x0000, 0x0000, 0x3140, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3141, 0x0000, 0x0000, 0x0000,
+ 0x3142, 0x0000, 0x3143, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3144, 0x0000, 0x3145, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3146, 0x3147, 0x0000, 0x3148,
+};
+
+static unsigned short const tqunicode_to_jisx0212_50[] = {
+ /* 0x5000 - 0x50ff */
+ 0x3149, 0x314a, 0x0000, 0x0000, 0x314b, 0x0000, 0x0000, 0x314c,
+ 0x0000, 0x0000, 0x314d, 0x0000, 0x314e, 0x0000, 0x314f, 0x0000,
+ 0x3150, 0x0000, 0x0000, 0x3151, 0x0000, 0x0000, 0x0000, 0x3152,
+ 0x3153, 0x0000, 0x0000, 0x3154, 0x3155, 0x3156, 0x3157, 0x0000,
+ 0x0000, 0x0000, 0x3158, 0x0000, 0x0000, 0x0000, 0x0000, 0x3159,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x315a, 0x0000,
+ 0x315b, 0x0000, 0x315c, 0x315d, 0x0000, 0x315e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3176, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x315f, 0x3160, 0x3161, 0x0000, 0x0000, 0x3162, 0x3163, 0x0000,
+ 0x0000, 0x0000, 0x3164, 0x0000, 0x3165, 0x0000, 0x3166, 0x0000,
+ 0x0000, 0x3167, 0x3168, 0x3169, 0x0000, 0x0000, 0x0000, 0x316a,
+ 0x0000, 0x316b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x316c,
+ 0x316d, 0x0000, 0x316e, 0x316f, 0x0000, 0x0000, 0x3170, 0x3171,
+ 0x0000, 0x0000, 0x3172, 0x0000, 0x0000, 0x3173, 0x0000, 0x0000,
+ 0x3174, 0x3175, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3177, 0x0000, 0x3178, 0x3179, 0x0000, 0x317a, 0x0000,
+ 0x0000, 0x0000, 0x317b, 0x0000, 0x0000, 0x0000, 0x317c, 0x317d,
+ 0x317e, 0x0000, 0x3221, 0x3222, 0x3223, 0x0000, 0x3224, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3225, 0x3226, 0x0000, 0x3227, 0x3228,
+ 0x3229, 0x322a, 0x322b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x322c, 0x0000, 0x0000, 0x0000, 0x0000, 0x322d,
+ 0x322e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x322f, 0x3230, 0x0000, 0x0000, 0x3231, 0x0000, 0x0000,
+ 0x3232, 0x0000, 0x0000, 0x3233, 0x3234, 0x0000, 0x0000, 0x3235,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3236, 0x0000, 0x3237, 0x0000,
+ 0x3238, 0x0000, 0x0000, 0x3239, 0x323a, 0x0000, 0x0000, 0x0000,
+ 0x323b, 0x0000, 0x0000, 0x0000, 0x323c, 0x323d, 0x0000, 0x323e,
+ 0x0000, 0x0000, 0x323f, 0x0000, 0x3240, 0x0000, 0x3241, 0x0000,
+ 0x3242, 0x3243, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3244,
+ 0x0000, 0x3245, 0x3251, 0x0000, 0x7430, 0x0000, 0x3246, 0x0000,
+ 0x0000, 0x0000, 0x3247, 0x0000, 0x0000, 0x0000, 0x3248, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_51[] = {
+ /* 0x5100 - 0x51ff */
+ 0x0000, 0x0000, 0x0000, 0x3249, 0x0000, 0x0000, 0x324a, 0x324b,
+ 0x324c, 0x0000, 0x0000, 0x324d, 0x324e, 0x324f, 0x3250, 0x0000,
+ 0x3252, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3253,
+ 0x0000, 0x3254, 0x0000, 0x3255, 0x3256, 0x3257, 0x3258, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3259, 0x0000, 0x0000, 0x0000, 0x325a,
+ 0x325b, 0x0000, 0x0000, 0x0000, 0x325c, 0x325d, 0x0000, 0x325e,
+ 0x0000, 0x325f, 0x0000, 0x3260, 0x3261, 0x3262, 0x0000, 0x0000,
+ 0x3263, 0x3264, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3265, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3266, 0x0000, 0x0000, 0x0000, 0x0000, 0x3267,
+ 0x0000, 0x0000, 0x0000, 0x3268, 0x0000, 0x3269, 0x0000, 0x326a,
+ 0x326b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x326c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x326d, 0x0000, 0x326e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x326f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3270, 0x3271, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3272, 0x0000, 0x0000, 0x3273, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3274, 0x0000, 0x0000, 0x0000, 0x0000, 0x3275, 0x0000, 0x0000,
+ 0x0000, 0x3276, 0x0000, 0x3277, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3278, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3279, 0x0000, 0x327a, 0x0000, 0x327b, 0x0000, 0x327c, 0x327d,
+ 0x0000, 0x0000, 0x327e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3321, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3322,
+ 0x0000, 0x3323, 0x3324, 0x3325, 0x0000, 0x3326, 0x0000, 0x0000,
+ 0x3327, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3328, 0x0000,
+ 0x0000, 0x0000, 0x3329, 0x0000, 0x0000, 0x332a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x7431, 0x0000, 0x332b, 0x0000,
+ 0x0000, 0x0000, 0x332c, 0x332d, 0x332e, 0x0000, 0x0000, 0x332f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_52[] = {
+ /* 0x5200 - 0x52ff */
+ 0x0000, 0x3330, 0x3331, 0x0000, 0x0000, 0x3332, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3333, 0x3334, 0x0000, 0x3335, 0x3336, 0x0000,
+ 0x3337, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3338, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3339, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x333a, 0x333b, 0x0000, 0x0000, 0x333c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x333d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x333e, 0x0000, 0x0000,
+ 0x0000, 0x333f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3340, 0x0000, 0x3341,
+ 0x3342, 0x0000, 0x3343, 0x0000, 0x3344, 0x0000, 0x0000, 0x3345,
+ 0x3346, 0x3347, 0x0000, 0x0000, 0x0000, 0x0000, 0x3348, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3349, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x334a,
+ 0x334b, 0x334c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x334d, 0x0000, 0x334e, 0x0000, 0x0000, 0x334f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3350, 0x0000, 0x3351, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3352, 0x0000, 0x3353, 0x3354, 0x3355,
+ 0x3356, 0x0000, 0x3357, 0x0000, 0x3358, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3359, 0x335a, 0x335b, 0x335c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x335d,
+ 0x335e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x335f, 0x3360,
+ 0x3361, 0x0000, 0x3362, 0x3363, 0x0000, 0x3364, 0x0000, 0x0000,
+ 0x3365, 0x0000, 0x0000, 0x0000, 0x3366, 0x0000, 0x3367, 0x0000,
+ 0x3368, 0x0000, 0x0000, 0x0000, 0x3369, 0x0000, 0x0000, 0x336a,
+ 0x0000, 0x336b, 0x0000, 0x0000, 0x336c, 0x0000, 0x336d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x336e, 0x336f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3370, 0x0000, 0x0000, 0x0000, 0x3371, 0x0000, 0x0000,
+ 0x3372, 0x3373, 0x3374, 0x0000, 0x3375, 0x0000, 0x0000, 0x0000,
+ 0x3376, 0x3377, 0x0000, 0x0000, 0x3378, 0x0000, 0x3379, 0x337a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_53[] = {
+ /* 0x5300 - 0x53ff */
+ 0x337b, 0x0000, 0x0000, 0x337c, 0x0000, 0x0000, 0x0000, 0x7432,
+ 0x0000, 0x0000, 0x337d, 0x337e, 0x3421, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3422, 0x0000, 0x3423, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3424, 0x0000, 0x0000, 0x3425, 0x3426, 0x0000, 0x3427, 0x3428,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x7433, 0x3429, 0x0000, 0x342a,
+ 0x342b, 0x342c, 0x0000, 0x342d, 0x342e, 0x342f, 0x0000, 0x0000,
+ 0x3430, 0x0000, 0x3431, 0x0000, 0x0000, 0x3432, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3433, 0x3434, 0x3435, 0x0000,
+ 0x0000, 0x0000, 0x3436, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3438, 0x3437, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3439, 0x0000, 0x343a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x343b, 0x0000, 0x343c, 0x0000, 0x343d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x343e, 0x343f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3440, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3441, 0x0000, 0x0000, 0x0000, 0x0000, 0x3442, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3443, 0x0000, 0x0000, 0x0000, 0x3444,
+ 0x3445, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3446, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3447, 0x3448, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3449, 0x0000, 0x0000, 0x0000, 0x344a, 0x0000, 0x0000,
+ 0x0000, 0x344b, 0x0000, 0x0000, 0x344c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x344d, 0x344e, 0x0000, 0x0000, 0x0000, 0x344f,
+ 0x0000, 0x0000, 0x3450, 0x0000, 0x3451, 0x3452, 0x0000, 0x3453,
+ 0x3454, 0x0000, 0x3455, 0x0000, 0x0000, 0x3456, 0x0000, 0x0000,
+ 0x3457, 0x0000, 0x0000, 0x0000, 0x0000, 0x3458, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3459,
+ 0x0000, 0x0000, 0x345a, 0x345b, 0x0000, 0x345c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x345d, 0x0000, 0x0000, 0x345e, 0x345f, 0x0000,
+ 0x3460, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3461, 0x3462,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3463, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_54[] = {
+ /* 0x5400 - 0x54ff */
+ 0x0000, 0x0000, 0x3464, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3465, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3466, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3467, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3468,
+ 0x3469, 0x0000, 0x346a, 0x0000, 0x0000, 0x0000, 0x0000, 0x346b,
+ 0x0000, 0x346c, 0x0000, 0x0000, 0x346d, 0x346e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x346f, 0x3470, 0x0000, 0x0000, 0x3471,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3472, 0x0000, 0x3473,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3474, 0x0000,
+ 0x0000, 0x0000, 0x3475, 0x0000, 0x3476, 0x0000, 0x3477, 0x3478,
+ 0x0000, 0x3479, 0x0000, 0x347a, 0x0000, 0x347b, 0x347c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x347d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x347e,
+ 0x0000, 0x3521, 0x0000, 0x3522, 0x0000, 0x3523, 0x0000, 0x0000,
+ 0x3524, 0x3525, 0x7435, 0x0000, 0x0000, 0x3526, 0x0000, 0x0000,
+ 0x0000, 0x3527, 0x0000, 0x0000, 0x0000, 0x3528, 0x3529, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x352a, 0x0000, 0x0000, 0x352b,
+ 0x0000, 0x352c, 0x0000, 0x0000, 0x0000, 0x0000, 0x352d, 0x352e,
+ 0x0000, 0x352f, 0x3530, 0x0000, 0x0000, 0x3531, 0x3532, 0x0000,
+ 0x0000, 0x3533, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3534,
+ 0x0000, 0x3535, 0x3536, 0x3537, 0x0000, 0x0000, 0x0000, 0x3538,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3539, 0x0000,
+ 0x0000, 0x0000, 0x353a, 0x0000, 0x0000, 0x353b, 0x353c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x353d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x353e, 0x0000, 0x353f, 0x0000, 0x0000, 0x3540,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3541, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3542, 0x0000, 0x3543, 0x3544,
+};
+
+static unsigned short const tqunicode_to_jisx0212_55[] = {
+ /* 0x5500 - 0x55ff */
+ 0x3545, 0x3546, 0x0000, 0x0000, 0x0000, 0x3547, 0x0000, 0x0000,
+ 0x3548, 0x3549, 0x0000, 0x0000, 0x354a, 0x354b, 0x354c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x354d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x354e, 0x354f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3550, 0x0000, 0x0000, 0x3551, 0x3552, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3553, 0x3554, 0x3555, 0x0000, 0x0000,
+ 0x0000, 0x3556, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3557,
+ 0x0000, 0x3558, 0x3559, 0x0000, 0x0000, 0x355a, 0x0000, 0x0000,
+ 0x355b, 0x355c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x355d, 0x0000, 0x355e, 0x355f, 0x0000, 0x0000, 0x3560, 0x0000,
+ 0x3561, 0x3562, 0x0000, 0x0000, 0x3563, 0x0000, 0x3564, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3565,
+ 0x0000, 0x3566, 0x3567, 0x0000, 0x0000, 0x0000, 0x3568, 0x0000,
+ 0x3569, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x356a, 0x356b,
+ 0x0000, 0x356c, 0x356d, 0x356e, 0x356f, 0x0000, 0x0000, 0x3570,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3571, 0x3572, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3573, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3574, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3575,
+ 0x0000, 0x3576, 0x0000, 0x3577, 0x0000, 0x0000, 0x3578, 0x0000,
+ 0x0000, 0x3579, 0x0000, 0x357a, 0x357b, 0x0000, 0x357c, 0x0000,
+ 0x0000, 0x357d, 0x357e, 0x3621, 0x0000, 0x0000, 0x0000, 0x3622,
+ 0x3623, 0x0000, 0x0000, 0x3624, 0x0000, 0x0000, 0x3625, 0x0000,
+ 0x0000, 0x0000, 0x3626, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3627, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3628, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3629,
+};
+
+static unsigned short const tqunicode_to_jisx0212_56[] = {
+ /* 0x5600 - 0x56ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x362a, 0x0000, 0x0000,
+ 0x362b, 0x0000, 0x362c, 0x0000, 0x0000, 0x362d, 0x362e, 0x362f,
+ 0x3630, 0x3631, 0x3632, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3633, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3634, 0x0000, 0x0000, 0x0000,
+ 0x3635, 0x0000, 0x0000, 0x3636, 0x0000, 0x3637, 0x0000, 0x3638,
+ 0x0000, 0x3639, 0x0000, 0x363a, 0x363b, 0x363c, 0x0000, 0x363d,
+ 0x363e, 0x363f, 0x0000, 0x3640, 0x3641, 0x0000, 0x3642, 0x0000,
+ 0x0000, 0x3643, 0x0000, 0x3644, 0x0000, 0x3645, 0x0000, 0x3646,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3647, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3648, 0x0000,
+ 0x3649, 0x364a, 0x364b, 0x364c, 0x0000, 0x0000, 0x364d, 0x0000,
+ 0x0000, 0x364e, 0x0000, 0x0000, 0x0000, 0x364f, 0x0000, 0x3650,
+ 0x0000, 0x3651, 0x3652, 0x0000, 0x0000, 0x3653, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3654, 0x3655, 0x0000, 0x0000,
+ 0x3656, 0x0000, 0x0000, 0x3657, 0x3658, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3659, 0x0000, 0x0000,
+ 0x0000, 0x365a, 0x365b, 0x0000, 0x0000, 0x365c, 0x365d, 0x365e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x365f, 0x3660,
+ 0x3661, 0x3662, 0x0000, 0x3663, 0x3664, 0x3665, 0x0000, 0x0000,
+ 0x0000, 0x3666, 0x0000, 0x3667, 0x0000, 0x0000, 0x0000, 0x3668,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3669, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x366a, 0x0000, 0x0000,
+ 0x0000, 0x366b, 0x366c, 0x366d, 0x3670, 0x3671, 0x0000, 0x366e,
+ 0x366f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3672, 0x0000, 0x0000, 0x3673, 0x3674, 0x0000, 0x3675,
+ 0x0000, 0x3676, 0x0000, 0x0000, 0x3677, 0x3678, 0x3679, 0x367a,
+ 0x367b, 0x0000, 0x0000, 0x367d, 0x0000, 0x367e, 0x0000, 0x0000,
+ 0x0000, 0x367c, 0x0000, 0x0000, 0x0000, 0x0000, 0x3721, 0x3722,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_57[] = {
+ /* 0x5700 - 0x57ff */
+ 0x0000, 0x3723, 0x3724, 0x0000, 0x0000, 0x0000, 0x0000, 0x3725,
+ 0x0000, 0x0000, 0x3726, 0x0000, 0x3727, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3728, 0x0000, 0x0000, 0x0000, 0x3729, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x372a, 0x372b, 0x0000, 0x372c, 0x0000, 0x0000,
+ 0x372d, 0x0000, 0x372e, 0x372f, 0x3730, 0x3731, 0x0000, 0x0000,
+ 0x0000, 0x3732, 0x3733, 0x0000, 0x3734, 0x0000, 0x3735, 0x3736,
+ 0x0000, 0x0000, 0x0000, 0x3737, 0x3738, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3739, 0x373a, 0x373b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x373c, 0x373d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x373e, 0x373f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3740, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x7436, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3741, 0x0000, 0x0000, 0x3742, 0x0000, 0x3743,
+ 0x3744, 0x0000, 0x0000, 0x3745, 0x0000, 0x3746, 0x3747, 0x3748,
+ 0x3749, 0x374a, 0x0000, 0x374b, 0x374c, 0x374d, 0x0000, 0x374e,
+ 0x0000, 0x374f, 0x3750, 0x3751, 0x3752, 0x0000, 0x3753, 0x0000,
+ 0x0000, 0x3754, 0x0000, 0x3755, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3756, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3757, 0x3760, 0x0000, 0x3758,
+ 0x0000, 0x3759, 0x375a, 0x0000, 0x375b, 0x375c, 0x375d, 0x375e,
+ 0x0000, 0x375f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3761,
+ 0x3762, 0x3763, 0x0000, 0x0000, 0x3764, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3765, 0x0000, 0x0000, 0x0000, 0x0000, 0x3766, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3767,
+ 0x3768, 0x0000, 0x0000, 0x0000, 0x3769, 0x0000, 0x0000, 0x376a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x376b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x376c, 0x376d, 0x0000,
+ 0x0000, 0x377e, 0x0000, 0x0000, 0x376e, 0x0000, 0x376f, 0x3770,
+ 0x0000, 0x3771, 0x0000, 0x0000, 0x0000, 0x3772, 0x0000, 0x0000,
+ 0x3773, 0x0000, 0x0000, 0x0000, 0x0000, 0x3774, 0x3775, 0x0000,
+ 0x3776, 0x0000, 0x0000, 0x0000, 0x0000, 0x3777, 0x3778, 0x3779,
+};
+
+static unsigned short const tqunicode_to_jisx0212_58[] = {
+ /* 0x5800 - 0x58ff */
+ 0x0000, 0x0000, 0x0000, 0x377a, 0x377b, 0x0000, 0x0000, 0x0000,
+ 0x377c, 0x377d, 0x0000, 0x0000, 0x3821, 0x3822, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3823, 0x0000, 0x0000, 0x3824, 0x3825,
+ 0x3826, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3827, 0x3828,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3829, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x382a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x382b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x382c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x382d, 0x0000, 0x0000, 0x382e, 0x382f, 0x0000, 0x3830,
+ 0x3831, 0x0000, 0x0000, 0x0000, 0x0000, 0x3832, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3833,
+ 0x0000, 0x3834, 0x0000, 0x0000, 0x3835, 0x0000, 0x0000, 0x3836,
+ 0x3837, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3838, 0x0000, 0x0000, 0x0000, 0x3839, 0x0000, 0x0000, 0x383a,
+ 0x383b, 0x383c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x383d,
+ 0x383e, 0x383f, 0x3840, 0x0000, 0x3841, 0x3842, 0x0000, 0x3843,
+ 0x3844, 0x0000, 0x0000, 0x0000, 0x3845, 0x0000, 0x3846, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3847, 0x7439, 0x0000,
+ 0x3848, 0x3849, 0x384a, 0x0000, 0x0000, 0x0000, 0x384b, 0x0000,
+ 0x0000, 0x384c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x384d, 0x384e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3850, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3851, 0x0000, 0x384f, 0x0000, 0x0000, 0x0000,
+ 0x3852, 0x0000, 0x0000, 0x0000, 0x0000, 0x3853, 0x3854, 0x0000,
+ 0x3855, 0x0000, 0x3856, 0x0000, 0x3857, 0x0000, 0x3858, 0x0000,
+ 0x0000, 0x0000, 0x3859, 0x0000, 0x0000, 0x385a, 0x0000, 0x0000,
+ 0x0000, 0x385b, 0x385c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x385d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x385e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_59[] = {
+ /* 0x5900 - 0x59ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x385f, 0x3860, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3861, 0x3862, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3863, 0x3864, 0x3865, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3867, 0x0000, 0x0000,
+ 0x0000, 0x3868, 0x0000, 0x3869, 0x386a, 0x0000, 0x0000, 0x0000,
+ 0x386b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x386c,
+ 0x386d, 0x0000, 0x0000, 0x386e, 0x0000, 0x386f, 0x3870, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3871,
+ 0x0000, 0x0000, 0x0000, 0x3872, 0x0000, 0x0000, 0x3873, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3874, 0x3875, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3876, 0x0000, 0x3877, 0x0000, 0x3878, 0x3879, 0x387a,
+ 0x0000, 0x387b, 0x0000, 0x387c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x387d, 0x0000, 0x387e, 0x0000, 0x3921,
+ 0x0000, 0x0000, 0x3922, 0x0000, 0x0000, 0x3923, 0x3924, 0x0000,
+ 0x0000, 0x3925, 0x0000, 0x3926, 0x3927, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3928, 0x3929, 0x0000, 0x392a, 0x0000,
+ 0x0000, 0x0000, 0x392b, 0x0000, 0x0000, 0x392c, 0x0000, 0x392d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x392e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x392f, 0x0000, 0x0000, 0x3930,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3931, 0x3932, 0x3933,
+ 0x3934, 0x0000, 0x0000, 0x3935, 0x0000, 0x0000, 0x0000, 0x3936,
+ 0x0000, 0x0000, 0x3937, 0x0000, 0x3938, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3939, 0x0000, 0x393a, 0x393b, 0x0000, 0x0000, 0x0000,
+ 0x393c, 0x0000, 0x393d, 0x0000, 0x0000, 0x393e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x393f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3940, 0x3941, 0x3942,
+ 0x0000, 0x0000, 0x0000, 0x3943, 0x3944, 0x0000, 0x0000, 0x3945,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3946, 0x3947,
+ 0x0000, 0x3948, 0x3949, 0x0000, 0x394a, 0x0000, 0x0000, 0x394b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_5a[] = {
+ /* 0x5a00 - 0x5aff */
+ 0x394c, 0x0000, 0x0000, 0x0000, 0x394d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x394e, 0x394f, 0x3950, 0x0000,
+ 0x0000, 0x0000, 0x3951, 0x3952, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3953, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3954, 0x3955, 0x0000, 0x0000, 0x3956,
+ 0x3957, 0x0000, 0x3958, 0x0000, 0x0000, 0x3959, 0x0000, 0x0000,
+ 0x395a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x395b, 0x395c, 0x0000, 0x395d,
+ 0x395e, 0x0000, 0x0000, 0x0000, 0x395f, 0x0000, 0x0000, 0x0000,
+ 0x3960, 0x0000, 0x0000, 0x0000, 0x0000, 0x3961, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3962, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3963, 0x0000, 0x3964, 0x0000, 0x3965,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3966, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3967,
+ 0x0000, 0x0000, 0x3968, 0x3969, 0x0000, 0x0000, 0x396a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x396b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x396c, 0x0000, 0x0000, 0x396d, 0x0000, 0x0000, 0x396e, 0x0000,
+ 0x0000, 0x396f, 0x0000, 0x0000, 0x3970, 0x0000, 0x3971, 0x3972,
+ 0x3973, 0x0000, 0x3974, 0x0000, 0x0000, 0x0000, 0x0000, 0x3975,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3976, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3977, 0x3978, 0x3979, 0x0000, 0x397a, 0x0000, 0x0000,
+ 0x397b, 0x0000, 0x397c, 0x397d, 0x0000, 0x0000, 0x0000, 0x397e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3a21, 0x0000, 0x3a22, 0x0000,
+ 0x3a23, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a24,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3a25, 0x0000, 0x3a26, 0x0000, 0x0000, 0x0000,
+ 0x3a27, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a28, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3a29, 0x0000, 0x0000, 0x0000, 0x3a2a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a2b, 0x3a2c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a2d, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_5b[] = {
+ /* 0x5b00 - 0x5bff */
+ 0x3a2e, 0x3a2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3a30, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a31,
+ 0x0000, 0x3a33, 0x0000, 0x3a34, 0x0000, 0x3a35, 0x0000, 0x0000,
+ 0x0000, 0x3a36, 0x0000, 0x0000, 0x0000, 0x3a37, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a38, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3a32, 0x0000, 0x0000, 0x0000,
+ 0x3a39, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3a3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3a3b, 0x3a3c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3a3d, 0x0000, 0x0000, 0x0000, 0x3a3e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a3f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3a40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a41, 0x3a42,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3a43, 0x3a44, 0x3a45, 0x3a46,
+ 0x0000, 0x3a47, 0x0000, 0x0000, 0x3a48, 0x0000, 0x3a49, 0x0000,
+ 0x0000, 0x0000, 0x3a4a, 0x0000, 0x0000, 0x0000, 0x3a4b, 0x0000,
+ 0x3a4c, 0x3a4d, 0x0000, 0x3a4e, 0x3a4f, 0x0000, 0x3a50, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3a51, 0x3a52, 0x0000, 0x0000, 0x3a53, 0x3a54, 0x0000, 0x3a55,
+ 0x0000, 0x3a56, 0x3a57, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a58,
+ 0x0000, 0x0000, 0x3a59, 0x0000, 0x3a5a, 0x0000, 0x0000, 0x0000,
+ 0x3a5b, 0x3a5c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a5d, 0x0000, 0x3a5e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a5f, 0x3a60,
+ 0x3a61, 0x3a62, 0x3a63, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3a64, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x743a, 0x0000, 0x0000, 0x3a65,
+ 0x0000, 0x3a66, 0x0000, 0x0000, 0x3a67, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a68, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_5c[] = {
+ /* 0x5c00 - 0x5cff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3a69, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a6a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3a6b, 0x3a6c,
+ 0x0000, 0x0000, 0x0000, 0x3a6d, 0x0000, 0x0000, 0x3a6e, 0x0000,
+ 0x0000, 0x3a6f, 0x0000, 0x3a70, 0x3a71, 0x0000, 0x3a72, 0x0000,
+ 0x3a73, 0x0000, 0x3a74, 0x0000, 0x0000, 0x3a75, 0x3a76, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3a77, 0x3a78, 0x0000, 0x3a79, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3a7a, 0x3a7b, 0x0000, 0x0000, 0x0000, 0x3a7c,
+ 0x3a7d, 0x3a7e, 0x0000, 0x0000, 0x0000, 0x3b21, 0x0000, 0x0000,
+ 0x3b22, 0x0000, 0x0000, 0x0000, 0x3b23, 0x3b24, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3b25, 0x3b26, 0x3b27, 0x3b28, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b29,
+ 0x3b2a, 0x0000, 0x3b2b, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b2c,
+ 0x0000, 0x0000, 0x3b2d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b2e, 0x0000, 0x3b2f,
+ 0x3b30, 0x0000, 0x3b31, 0x3b32, 0x0000, 0x0000, 0x3b33, 0x0000,
+ 0x0000, 0x0000, 0x3b34, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3b35, 0x0000, 0x3b36, 0x3b37, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3b38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3b39, 0x0000, 0x3b3a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3b3b, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b3d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b3c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b3e, 0x0000,
+ 0x0000, 0x3b3f, 0x3b40, 0x0000, 0x3b41, 0x743b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_5d[] = {
+ /* 0x5d00 - 0x5dff */
+ 0x0000, 0x3b42, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b43, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b44, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3b45, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3b47, 0x3b48, 0x0000, 0x3b49, 0x3b4a,
+ 0x0000, 0x0000, 0x0000, 0x3b46, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3b4b, 0x0000, 0x0000, 0x3b4c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3b4d, 0x0000, 0x0000, 0x0000, 0x3b4e, 0x0000, 0x3b4f,
+ 0x0000, 0x0000, 0x3b50, 0x3b51, 0x0000, 0x0000, 0x3b52, 0x0000,
+ 0x3b53, 0x0000, 0x3b57, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3b55, 0x0000, 0x743c, 0x0000, 0x3b54, 0x0000, 0x0000,
+ 0x0000, 0x3b56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b58,
+ 0x3b59, 0x3b5a, 0x3b5b, 0x0000, 0x3b5c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3b5d, 0x0000, 0x0000, 0x3b5e, 0x0000, 0x0000,
+ 0x3b5f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3b60, 0x3b61, 0x0000, 0x0000, 0x0000, 0x3b62, 0x3b63,
+ 0x0000, 0x3b64, 0x0000, 0x3b65, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3b66, 0x0000, 0x3b67, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3b68, 0x3b69, 0x3b6a, 0x3b6b, 0x0000, 0x0000,
+ 0x0000, 0x3b6c, 0x0000, 0x3b6d, 0x0000, 0x0000, 0x0000, 0x3b6e,
+ 0x3b6f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3b70,
+ 0x0000, 0x0000, 0x0000, 0x3b71, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3b72, 0x0000, 0x6674, 0x0000, 0x3b73, 0x0000, 0x0000, 0x0000,
+ 0x3b74, 0x3b75, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3b76, 0x0000, 0x0000, 0x0000, 0x3b77,
+ 0x0000, 0x0000, 0x0000, 0x3b78, 0x0000, 0x0000, 0x3b7a, 0x0000,
+ 0x3b79, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3b7b, 0x3b7c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3b7d, 0x0000, 0x0000, 0x0000, 0x3b7e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3c21, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3c22, 0x3c23, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_5e[] = {
+ /* 0x5e00 - 0x5eff */
+ 0x3c24, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c25,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c26, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3c27, 0x0000, 0x3c28, 0x3c29, 0x0000, 0x0000,
+ 0x3c2a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c2b,
+ 0x3c2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3c2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c2d, 0x0000,
+ 0x0000, 0x0000, 0x3c2f, 0x0000, 0x0000, 0x3c30, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c31, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3c34, 0x0000, 0x3c32, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3c33, 0x3c35, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c36, 0x0000,
+ 0x3c37, 0x0000, 0x0000, 0x3c38, 0x3c39, 0x0000, 0x3c3a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3c3b, 0x0000, 0x3c3c, 0x3c3d, 0x3c3e, 0x3c3f, 0x3c40, 0x0000,
+ 0x3c41, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3c42, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3c43, 0x0000, 0x0000, 0x3c44, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3c45, 0x0000, 0x3c46, 0x3c47, 0x0000, 0x0000,
+ 0x3c48, 0x0000, 0x3c49, 0x0000, 0x3c4a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3c4b, 0x0000, 0x3c4c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c4d, 0x3c4e, 0x3c4f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c50, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3c52, 0x3c51, 0x0000, 0x3c53, 0x0000,
+ 0x0000, 0x3c54, 0x3c55, 0x0000, 0x3c56, 0x3c57, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3c58, 0x0000, 0x3c59, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c5a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3c5b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_5f[] = {
+ /* 0x5f00 - 0x5fff */
+ 0x0000, 0x0000, 0x3c5c, 0x0000, 0x0000, 0x0000, 0x3c5d, 0x3c5e,
+ 0x3c5f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c60, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3c61, 0x0000, 0x0000, 0x3c62, 0x3c63, 0x0000, 0x0000,
+ 0x0000, 0x3c64, 0x3c65, 0x3c66, 0x3c67, 0x0000, 0x0000, 0x0000,
+ 0x3c68, 0x0000, 0x0000, 0x3c69, 0x3c6a, 0x0000, 0x3c6b, 0x0000,
+ 0x3c6c, 0x0000, 0x0000, 0x0000, 0x3c6d, 0x0000, 0x3c6e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3c6f, 0x0000, 0x3c70, 0x0000, 0x3c71,
+ 0x3c72, 0x0000, 0x0000, 0x0000, 0x3c73, 0x3c74, 0x0000, 0x3c75,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3c76, 0x0000, 0x0000,
+ 0x3c77, 0x0000, 0x0000, 0x0000, 0x3c78, 0x0000, 0x0000, 0x0000,
+ 0x3c79, 0x0000, 0x0000, 0x3c7a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3c7b, 0x0000, 0x0000, 0x3c7c, 0x3c7d, 0x0000, 0x0000, 0x3c7e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d21,
+ 0x0000, 0x0000, 0x3d22, 0x0000, 0x3d23, 0x3d24, 0x0000, 0x0000,
+ 0x3d25, 0x0000, 0x3d26, 0x0000, 0x0000, 0x3d27, 0x3d28, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3d29, 0x0000, 0x0000, 0x0000, 0x3d2a, 0x0000, 0x3d2b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d2c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3d2d, 0x3d2e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3d2f, 0x0000, 0x3d32, 0x0000, 0x0000, 0x3d30,
+ 0x0000, 0x0000, 0x0000, 0x3d31, 0x3d33, 0x0000, 0x0000, 0x3d34,
+ 0x3d35, 0x3d36, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x743e,
+ 0x3d37, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3d38, 0x0000, 0x0000, 0x3d39,
+ 0x3d3a, 0x3d3b, 0x0000, 0x3d3c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3d3d, 0x3d3e, 0x3d3f, 0x3d40, 0x3d41, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d42, 0x0000,
+ 0x0000, 0x3d43, 0x3d44, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3d45, 0x3d46, 0x3d47, 0x0000, 0x3d48, 0x3d49, 0x3d4a, 0x3d4b,
+ 0x0000, 0x0000, 0x3d4c, 0x3d4d, 0x0000, 0x0000, 0x3d4e, 0x0000,
+ 0x0000, 0x0000, 0x3d4f, 0x0000, 0x3d50, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_60[] = {
+ /* 0x6000 - 0x60ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d51,
+ 0x0000, 0x0000, 0x3d52, 0x0000, 0x0000, 0x3d53, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3d54, 0x3d55, 0x0000, 0x0000, 0x3d56,
+ 0x3d57, 0x0000, 0x3d58, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d59,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3d5a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d5b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3d5c, 0x0000, 0x3d5d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3d5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d5f,
+ 0x3d60, 0x3d61, 0x0000, 0x0000, 0x3d62, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3d63, 0x0000, 0x0000, 0x3d64, 0x0000, 0x3d65, 0x3d66,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d67, 0x0000, 0x0000,
+ 0x0000, 0x3d68, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d69,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3d6a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d6b, 0x3d6c,
+ 0x0000, 0x0000, 0x3d6d, 0x0000, 0x0000, 0x743f, 0x3d6e, 0x0000,
+ 0x3d6f, 0x0000, 0x3d70, 0x0000, 0x0000, 0x0000, 0x3d71, 0x0000,
+ 0x0000, 0x3d72, 0x0000, 0x3d73, 0x0000, 0x3d74, 0x0000, 0x0000,
+ 0x3d75, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d76, 0x3d77, 0x0000,
+ 0x0000, 0x0000, 0x3d78, 0x0000, 0x3d79, 0x3d7a, 0x0000, 0x0000,
+ 0x3d7b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3d7c, 0x3d7d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3d7e,
+ 0x0000, 0x0000, 0x0000, 0x3e21, 0x0000, 0x0000, 0x3e22, 0x0000,
+ 0x0000, 0x0000, 0x3e23, 0x0000, 0x3e24, 0x0000, 0x0000, 0x0000,
+ 0x3e25, 0x3e26, 0x3e27, 0x3e28, 0x0000, 0x0000, 0x3e29, 0x3e2a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3e2b, 0x3e2c, 0x0000, 0x0000,
+ 0x0000, 0x3e2d, 0x0000, 0x3e2e, 0x0000, 0x3e2f, 0x3e30, 0x0000,
+ 0x0000, 0x0000, 0x3e31, 0x0000, 0x0000, 0x3e32, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3e33, 0x0000, 0x0000, 0x3e34, 0x0000, 0x0000,
+ 0x3e35, 0x0000, 0x0000, 0x0000, 0x3e36, 0x3e37, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_61[] = {
+ /* 0x6100 - 0x61ff */
+ 0x0000, 0x0000, 0x3e38, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e39,
+ 0x0000, 0x0000, 0x3e3a, 0x0000, 0x3e3b, 0x0000, 0x0000, 0x0000,
+ 0x3e3c, 0x3e3d, 0x3e3e, 0x3e3f, 0x3e40, 0x0000, 0x3e41, 0x3e42,
+ 0x0000, 0x3e43, 0x0000, 0x0000, 0x3e44, 0x0000, 0x3e45, 0x0000,
+ 0x7440, 0x0000, 0x3e46, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3e47, 0x3e48, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3e49, 0x3e4a, 0x0000, 0x0000, 0x0000, 0x3e4b, 0x3e4c, 0x3e4d,
+ 0x0000, 0x3e4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3e4f, 0x0000, 0x0000, 0x0000, 0x3e50, 0x3e51, 0x0000,
+ 0x0000, 0x3e52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e53, 0x0000,
+ 0x3e54, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3e55, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3e56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3e57, 0x0000, 0x0000, 0x3e58, 0x3e59, 0x0000, 0x0000, 0x3e5a,
+ 0x3e5b, 0x3e5c, 0x0000, 0x3e5d, 0x3e5e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3e5f, 0x0000, 0x3e60, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3e61, 0x3e62, 0x0000, 0x0000, 0x0000, 0x3e63,
+ 0x3e64, 0x0000, 0x0000, 0x0000, 0x3e65, 0x3e66, 0x0000, 0x3e67,
+ 0x3e68, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e69, 0x0000, 0x0000,
+ 0x3e6a, 0x0000, 0x3e6b, 0x0000, 0x0000, 0x3e6c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x3e6d, 0x3e6e, 0x0000, 0x0000, 0x3e6f, 0x0000, 0x0000, 0x0000,
+ 0x3e70, 0x3e71, 0x3e72, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e73, 0x3e74,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3e75, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3e76, 0x3e77, 0x3e78, 0x3e79,
+ 0x0000, 0x3e7a, 0x3e7b, 0x0000, 0x0000, 0x3e7e, 0x0000, 0x3e7c,
+ 0x0000, 0x3e7d, 0x0000, 0x0000, 0x3f21, 0x3f22, 0x0000, 0x3f23,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_62[] = {
+ /* 0x6200 - 0x62ff */
+ 0x0000, 0x3f24, 0x0000, 0x3f25, 0x3f26, 0x0000, 0x0000, 0x3f27,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3f28, 0x0000, 0x3f29, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3f2a, 0x0000, 0x0000, 0x0000,
+ 0x3f2b, 0x0000, 0x3f2c, 0x3f2d, 0x0000, 0x0000, 0x0000, 0x3f2e,
+ 0x0000, 0x3f2f, 0x0000, 0x3f30, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3f31, 0x0000, 0x0000, 0x0000, 0x3f32, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3f33, 0x3f34, 0x3f35, 0x0000, 0x3f36, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3f37, 0x0000, 0x0000, 0x0000,
+ 0x3f38, 0x3f39, 0x3f3a, 0x0000, 0x3f3b, 0x0000, 0x3f3c, 0x0000,
+ 0x0000, 0x0000, 0x3f3d, 0x0000, 0x3f3e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3f3f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f40, 0x0000, 0x3f41,
+ 0x0000, 0x0000, 0x0000, 0x3f42, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3f43, 0x0000, 0x0000, 0x3f44, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f45, 0x3f46, 0x3f47,
+ 0x3f48, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f49, 0x0000,
+ 0x3f4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x3f4b, 0x0000, 0x0000, 0x3f4c, 0x3f4d,
+ 0x0000, 0x0000, 0x3f4e, 0x0000, 0x0000, 0x0000, 0x3f4f, 0x3f50,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3f51, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f52, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f53, 0x3f54, 0x0000,
+ 0x0000, 0x0000, 0x3f55, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3f56, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3f57, 0x0000, 0x3f58, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3f59, 0x3f5a, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_63[] = {
+ /* 0x6300 - 0x63ff */
+ 0x0000, 0x0000, 0x0000, 0x3f5b, 0x3f5c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x3f5d, 0x3f5e, 0x0000, 0x3f5f, 0x0000, 0x0000,
+ 0x3f60, 0x0000, 0x0000, 0x3f61, 0x0000, 0x0000, 0x3f62, 0x0000,
+ 0x3f63, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3f64, 0x3f65, 0x0000, 0x0000, 0x3f66, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f67, 0x3f68, 0x0000,
+ 0x0000, 0x3f69, 0x0000, 0x0000, 0x3f6a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x0000, 0x3f6f, 0x0000,
+ 0x0000, 0x0000, 0x3f70, 0x3f71, 0x0000, 0x0000, 0x3f72, 0x0000,
+ 0x0000, 0x0000, 0x3f73, 0x3f74, 0x3f75, 0x0000, 0x0000, 0x0000,
+ 0x3f76, 0x0000, 0x0000, 0x3f77, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x3f78, 0x3f79, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x3f7a, 0x3f7b, 0x0000, 0x0000,
+ 0x0000, 0x3f7c, 0x0000, 0x0000, 0x3f7d, 0x3f7e, 0x0000, 0x0000,
+ 0x4021, 0x0000, 0x0000, 0x0000, 0x4022, 0x4023, 0x0000, 0x4024,
+ 0x0000, 0x0000, 0x4025, 0x0000, 0x4026, 0x0000, 0x0000, 0x4027,
+ 0x0000, 0x0000, 0x4028, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4029, 0x0000, 0x0000, 0x0000, 0x402a, 0x402b, 0x0000, 0x0000,
+ 0x0000, 0x402c, 0x402d, 0x0000, 0x0000, 0x0000, 0x402e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x402f, 0x0000, 0x4030, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4031, 0x4032, 0x4033,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4034, 0x0000, 0x0000,
+ 0x0000, 0x4035, 0x0000, 0x0000, 0x0000, 0x4036, 0x0000, 0x0000,
+ 0x4037, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4038, 0x0000,
+ 0x0000, 0x4039, 0x0000, 0x403a, 0x403b, 0x403c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x403d, 0x0000, 0x0000, 0x0000,
+ 0x403e, 0x0000, 0x0000, 0x0000, 0x0000, 0x403f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4040, 0x0000, 0x4041, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4042, 0x4043, 0x0000, 0x4044, 0x0000, 0x0000,
+ 0x4045, 0x4046, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_64[] = {
+ /* 0x6400 - 0x64ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4047, 0x4048, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4049, 0x0000, 0x404a, 0x0000, 0x404b, 0x0000, 0x0000, 0x0000,
+ 0x404c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x404d, 0x0000,
+ 0x404e, 0x0000, 0x404f, 0x0000, 0x4050, 0x4051, 0x0000, 0x0000,
+ 0x0000, 0x4052, 0x4053, 0x0000, 0x0000, 0x0000, 0x0000, 0x4054,
+ 0x4055, 0x0000, 0x0000, 0x0000, 0x0000, 0x4056, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4057, 0x0000, 0x4058,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4059, 0x0000, 0x0000, 0x0000, 0x405a,
+ 0x0000, 0x405b, 0x405c, 0x405d, 0x405e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x405f, 0x4060, 0x4061, 0x4062, 0x0000, 0x4063,
+ 0x4064, 0x4065, 0x0000, 0x4066, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4067, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4068, 0x4069, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x406a, 0x0000, 0x406b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x406c, 0x0000, 0x406d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x406e,
+ 0x406f, 0x4070, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4071, 0x4072, 0x0000, 0x4073, 0x0000, 0x4074, 0x0000, 0x4075,
+ 0x0000, 0x4076, 0x0000, 0x4077, 0x0000, 0x0000, 0x4078, 0x0000,
+ 0x4079, 0x0000, 0x0000, 0x0000, 0x407a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x407b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x407c, 0x407d, 0x407e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4121, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4122, 0x4123, 0x4124, 0x4125, 0x0000, 0x4126, 0x0000,
+ 0x4127, 0x4128, 0x0000, 0x0000, 0x0000, 0x4129, 0x0000, 0x412a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x412b, 0x412c, 0x0000, 0x0000,
+ 0x0000, 0x412d, 0x412e, 0x0000, 0x0000, 0x412f, 0x0000, 0x0000,
+ 0x4130, 0x0000, 0x0000, 0x0000, 0x0000, 0x4131, 0x0000, 0x4132,
+ 0x0000, 0x0000, 0x0000, 0x4133, 0x0000, 0x0000, 0x0000, 0x4134,
+};
+
+static unsigned short const tqunicode_to_jisx0212_65[] = {
+ /* 0x6500 - 0x65ff */
+ 0x0000, 0x4135, 0x0000, 0x0000, 0x4136, 0x0000, 0x0000, 0x0000,
+ 0x4137, 0x4138, 0x4139, 0x0000, 0x0000, 0x0000, 0x0000, 0x413a,
+ 0x0000, 0x0000, 0x0000, 0x413b, 0x413c, 0x0000, 0x413d, 0x0000,
+ 0x0000, 0x413e, 0x0000, 0x413f, 0x0000, 0x0000, 0x4140, 0x4141,
+ 0x0000, 0x0000, 0x4142, 0x0000, 0x0000, 0x0000, 0x4143, 0x0000,
+ 0x0000, 0x4144, 0x0000, 0x0000, 0x0000, 0x0000, 0x4145, 0x0000,
+ 0x0000, 0x4146, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4147, 0x0000, 0x4148, 0x4149, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x414a, 0x0000, 0x0000, 0x0000, 0x414b,
+ 0x0000, 0x414c, 0x0000, 0x0000, 0x0000, 0x0000, 0x7441, 0x0000,
+ 0x414d, 0x0000, 0x414e, 0x0000, 0x414f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4150,
+ 0x4151, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4152,
+ 0x0000, 0x0000, 0x0000, 0x4153, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4154, 0x0000, 0x0000, 0x4155, 0x0000, 0x0000,
+ 0x0000, 0x4156, 0x0000, 0x0000, 0x0000, 0x4157, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4158, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4159, 0x0000, 0x0000, 0x415a, 0x0000, 0x0000,
+ 0x415b, 0x0000, 0x0000, 0x0000, 0x0000, 0x415c, 0x0000, 0x0000,
+ 0x415d, 0x0000, 0x0000, 0x415e, 0x0000, 0x0000, 0x415f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4160, 0x0000,
+ 0x0000, 0x0000, 0x4161, 0x4162, 0x4163, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4164,
+ 0x0000, 0x0000, 0x4165, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4166, 0x4167, 0x0000, 0x0000, 0x0000, 0x0000, 0x4168, 0x0000,
+ 0x4169, 0x0000, 0x0000, 0x0000, 0x416a, 0x0000, 0x416b, 0x0000,
+ 0x416c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x416d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x416e, 0x0000, 0x416f, 0x0000, 0x4170, 0x4171, 0x0000, 0x0000,
+ 0x0000, 0x4172, 0x0000, 0x0000, 0x0000, 0x0000, 0x4173, 0x4174,
+};
+
+static unsigned short const tqunicode_to_jisx0212_66[] = {
+ /* 0x6600 - 0x66ff */
+ 0x4175, 0x0000, 0x0000, 0x0000, 0x4176, 0x0000, 0x0000, 0x0000,
+ 0x4177, 0x4178, 0x0000, 0x0000, 0x0000, 0x4179, 0x0000, 0x0000,
+ 0x0000, 0x417a, 0x417b, 0x0000, 0x0000, 0x417c, 0x417d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x417e, 0x4221, 0x0000,
+ 0x0000, 0x4222, 0x4223, 0x4224, 0x4225, 0x0000, 0x4226, 0x0000,
+ 0x0000, 0x4227, 0x4228, 0x4229, 0x422a, 0x0000, 0x422b, 0x0000,
+ 0x422c, 0x422d, 0x0000, 0x422e, 0x0000, 0x0000, 0x0000, 0x4230,
+ 0x0000, 0x422f, 0x0000, 0x7442, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4231, 0x0000, 0x0000, 0x0000, 0x0000, 0x4232, 0x4233, 0x0000,
+ 0x0000, 0x0000, 0x4234, 0x0000, 0x4235, 0x0000, 0x4237, 0x0000,
+ 0x0000, 0x4236, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4238,
+ 0x4239, 0x423a, 0x0000, 0x423b, 0x423c, 0x0000, 0x0000, 0x0000,
+ 0x423d, 0x423e, 0x0000, 0x0000, 0x0000, 0x7443, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4240, 0x4241, 0x4242, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4244, 0x0000, 0x4245, 0x0000, 0x4247,
+ 0x4248, 0x4249, 0x0000, 0x424a, 0x424c, 0x0000, 0x4243, 0x4246,
+ 0x424b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x424d, 0x424e, 0x424f, 0x0000, 0x0000,
+ 0x4250, 0x0000, 0x4251, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4252, 0x4253, 0x4254, 0x4255, 0x0000, 0x0000, 0x4256,
+ 0x4257, 0x0000, 0x0000, 0x0000, 0x4258, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4259, 0x0000, 0x0000,
+ 0x0000, 0x425a, 0x425b, 0x0000, 0x0000, 0x425c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x425d, 0x0000, 0x0000, 0x0000, 0x425e,
+ 0x425f, 0x0000, 0x4260, 0x4261, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4262, 0x0000, 0x0000, 0x0000, 0x4263, 0x0000, 0x4264, 0x4265,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4266, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4267, 0x0000, 0x0000, 0x0000, 0x4268,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4269, 0x0000, 0x0000, 0x426a, 0x426b, 0x0000, 0x426c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x426d, 0x423f, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_67[] = {
+ /* 0x6700 - 0x67ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x426e, 0x0000, 0x426f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4270, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4271, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4272, 0x0000, 0x0000, 0x4273, 0x0000, 0x0000, 0x0000,
+ 0x4274, 0x0000, 0x4275, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4276, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4277, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4278, 0x0000, 0x4279,
+ 0x427a, 0x0000, 0x0000, 0x0000, 0x427b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x427c, 0x427d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x427e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4321, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4322, 0x0000, 0x4323, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4324, 0x0000, 0x4325, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4326, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4327, 0x0000, 0x0000, 0x4328, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4329, 0x432a,
+ 0x0000, 0x432b, 0x0000, 0x432c, 0x0000, 0x0000, 0x432d, 0x0000,
+ 0x432e, 0x432f, 0x0000, 0x4330, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4331, 0x4332, 0x4333, 0x0000, 0x0000, 0x4334, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4335, 0x4336, 0x4337, 0x0000, 0x0000,
+ 0x4339, 0x0000, 0x433a, 0x433b, 0x0000, 0x433c, 0x0000, 0x0000,
+ 0x433d, 0x433e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x433f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4340,
+ 0x0000, 0x4341, 0x0000, 0x0000, 0x4342, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4343, 0x0000, 0x0000, 0x0000, 0x0000, 0x4344, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4345, 0x0000, 0x4346, 0x0000, 0x0000, 0x0000, 0x4347, 0x4348,
+ 0x0000, 0x4338, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_68[] = {
+ /* 0x6800 - 0x68ff */
+ 0x0000, 0x7446, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x434a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x434b, 0x0000, 0x0000, 0x0000, 0x434c, 0x0000, 0x434d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x434f,
+ 0x434e, 0x0000, 0x0000, 0x0000, 0x4350, 0x4351, 0x0000, 0x4352,
+ 0x4353, 0x4354, 0x0000, 0x4355, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4356, 0x0000, 0x0000, 0x0000, 0x4357,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4358, 0x4359, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x435a, 0x0000, 0x435b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4349, 0x0000, 0x0000, 0x435c, 0x0000, 0x435d,
+ 0x435e, 0x0000, 0x0000, 0x435f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4360, 0x0000, 0x0000, 0x4361, 0x4362,
+ 0x4363, 0x4364, 0x4365, 0x0000, 0x0000, 0x4366, 0x0000, 0x0000,
+ 0x0000, 0x4367, 0x4368, 0x4369, 0x436a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x436b, 0x0000, 0x436c, 0x0000, 0x436d, 0x0000,
+ 0x436e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x436f, 0x0000,
+ 0x4370, 0x0000, 0x4371, 0x0000, 0x4372, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4373, 0x0000, 0x4374, 0x0000, 0x4375, 0x0000, 0x0000,
+ 0x0000, 0x4376, 0x4377, 0x0000, 0x0000, 0x0000, 0x4378, 0x0000,
+ 0x0000, 0x0000, 0x4379, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x437a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x437b, 0x0000, 0x0000,
+ 0x437c, 0x0000, 0x0000, 0x0000, 0x437d, 0x0000, 0x0000, 0x437e,
+ 0x4421, 0x4422, 0x0000, 0x4423, 0x0000, 0x0000, 0x4424, 0x0000,
+ 0x0000, 0x4425, 0x0000, 0x0000, 0x4426, 0x4427, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4428, 0x0000, 0x0000,
+ 0x4429, 0x0000, 0x442a, 0x442b, 0x442c, 0x442d, 0x0000, 0x0000,
+ 0x442e, 0x442f, 0x0000, 0x0000, 0x0000, 0x4430, 0x4431, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4432, 0x4433, 0x4434, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_69[] = {
+ /* 0x6900 - 0x69ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4435, 0x0000,
+ 0x0000, 0x4436, 0x4437, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4438, 0x4439, 0x0000, 0x443a, 0x0000, 0x0000, 0x443b, 0x443c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x443d, 0x0000, 0x443e, 0x0000, 0x443f, 0x0000, 0x0000,
+ 0x4440, 0x0000, 0x0000, 0x4441, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4442, 0x0000, 0x0000, 0x4443, 0x0000, 0x0000,
+ 0x0000, 0x4444, 0x0000, 0x0000, 0x0000, 0x0000, 0x4445, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4446,
+ 0x0000, 0x0000, 0x0000, 0x4447, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4448, 0x4449, 0x444a, 0x444b, 0x0000,
+ 0x444c, 0x444d, 0x0000, 0x0000, 0x444e, 0x0000, 0x0000, 0x0000,
+ 0x444f, 0x4450, 0x4451, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4452, 0x4453, 0x0000, 0x0000, 0x0000, 0x4454,
+ 0x4455, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4456, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4457, 0x0000, 0x0000, 0x0000, 0x4458, 0x0000,
+ 0x4459, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x445a, 0x0000, 0x0000, 0x0000, 0x445b, 0x445c, 0x0000,
+ 0x445d, 0x0000, 0x0000, 0x445e, 0x0000, 0x445f, 0x0000, 0x4460,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4461,
+ 0x4462, 0x0000, 0x4463, 0x0000, 0x4464, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4465, 0x0000, 0x0000,
+ 0x4466, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4467, 0x0000, 0x0000, 0x0000, 0x0000, 0x4468, 0x4469,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x446a, 0x0000, 0x0000, 0x446b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x446c, 0x446d,
+ 0x0000, 0x446e, 0x0000, 0x446f, 0x0000, 0x4470, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4471, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_6a[] = {
+ /* 0x6a00 - 0x6aff */
+ 0x4472, 0x4473, 0x0000, 0x4474, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4475,
+ 0x0000, 0x4476, 0x0000, 0x0000, 0x0000, 0x4477, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4478, 0x0000, 0x0000, 0x4479, 0x0000, 0x0000,
+ 0x447a, 0x0000, 0x0000, 0x0000, 0x447b, 0x0000, 0x0000, 0x0000,
+ 0x447c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x447d, 0x0000, 0x447e, 0x0000, 0x4521, 0x0000, 0x0000, 0x4522,
+ 0x0000, 0x0000, 0x0000, 0x4523, 0x0000, 0x0000, 0x4524, 0x4525,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4526, 0x4527, 0x0000,
+ 0x0000, 0x4528, 0x4529, 0x0000, 0x0000, 0x0000, 0x452a, 0x0000,
+ 0x452b, 0x452c, 0x452d, 0x0000, 0x0000, 0x452e, 0x452f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4530, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4531, 0x0000, 0x0000, 0x4532,
+ 0x0000, 0x0000, 0x4533, 0x7449, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4534, 0x0000, 0x4535, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4536, 0x0000,
+ 0x0000, 0x4537, 0x0000, 0x4538, 0x0000, 0x0000, 0x4539, 0x453a,
+ 0x0000, 0x453b, 0x0000, 0x453c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x453d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x453e, 0x0000, 0x453f, 0x4540, 0x4541,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4542, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4543, 0x0000, 0x0000, 0x0000, 0x4544,
+ 0x4545, 0x4546, 0x0000, 0x0000, 0x4547, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4548, 0x4549, 0x454a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x454b, 0x0000,
+ 0x454d, 0x454c, 0x0000, 0x0000, 0x454e, 0x0000, 0x0000, 0x0000,
+ 0x454f, 0x0000, 0x0000, 0x0000, 0x4550, 0x4551, 0x4552, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4553, 0x4554, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x744a, 0x0000, 0x4555, 0x0000, 0x0000, 0x4556,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4557, 0x0000, 0x0000, 0x0000,
+ 0x4558, 0x4559, 0x455a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x455b, 0x455c, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_6b[] = {
+ /* 0x6b00 - 0x6bff */
+ 0x0000, 0x0000, 0x455d, 0x455e, 0x0000, 0x0000, 0x455f, 0x4560,
+ 0x0000, 0x4561, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4562,
+ 0x4563, 0x4564, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4565,
+ 0x0000, 0x0000, 0x0000, 0x4566, 0x0000, 0x0000, 0x4567, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4568, 0x0000, 0x0000, 0x0000,
+ 0x4569, 0x0000, 0x0000, 0x456a, 0x456b, 0x0000, 0x0000, 0x456c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x456d, 0x456e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x456f, 0x0000, 0x0000, 0x0000, 0x4570,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4571, 0x0000,
+ 0x0000, 0x0000, 0x4572, 0x0000, 0x0000, 0x4573, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4574, 0x0000, 0x0000, 0x0000, 0x4575, 0x0000,
+ 0x4576, 0x0000, 0x0000, 0x0000, 0x0000, 0x4577, 0x0000, 0x0000,
+ 0x4578, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4579,
+ 0x0000, 0x0000, 0x0000, 0x457a, 0x0000, 0x0000, 0x457b, 0x0000,
+ 0x457c, 0x0000, 0x0000, 0x0000, 0x0000, 0x457d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x457e, 0x4621, 0x0000,
+ 0x0000, 0x0000, 0x4622, 0x0000, 0x0000, 0x4623, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4624,
+ 0x0000, 0x0000, 0x0000, 0x4625, 0x0000, 0x0000, 0x0000, 0x4626,
+ 0x4627, 0x0000, 0x4628, 0x4629, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x462a, 0x462b, 0x0000, 0x0000, 0x462c, 0x462d, 0x462e, 0x0000,
+ 0x462f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4630, 0x4631, 0x0000, 0x0000, 0x0000, 0x4632, 0x4633, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4634, 0x4635, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4636, 0x0000, 0x0000, 0x4637, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4638, 0x0000,
+ 0x0000, 0x0000, 0x4639, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x463a, 0x0000, 0x463b, 0x0000, 0x0000, 0x463c, 0x463d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x463e, 0x0000,
+ 0x0000, 0x463f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4640,
+ 0x0000, 0x4641, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4642,
+};
+
+static unsigned short const tqunicode_to_jisx0212_6c[] = {
+ /* 0x6c00 - 0x6cff */
+ 0x0000, 0x0000, 0x4643, 0x0000, 0x4644, 0x4645, 0x0000, 0x0000,
+ 0x0000, 0x4646, 0x0000, 0x0000, 0x0000, 0x4647, 0x4648, 0x0000,
+ 0x4649, 0x0000, 0x464a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x464b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x464c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x464d, 0x464e,
+ 0x464f, 0x0000, 0x0000, 0x0000, 0x4650, 0x0000, 0x4651, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4652, 0x0000, 0x4653, 0x4654, 0x0000,
+ 0x0000, 0x0000, 0x4655, 0x4656, 0x0000, 0x0000, 0x0000, 0x4657,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4658, 0x4659, 0x0000, 0x465a, 0x0000, 0x465b,
+ 0x0000, 0x0000, 0x465c, 0x0000, 0x465d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x465e, 0x0000, 0x465f, 0x4660, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4736,
+ 0x0000, 0x0000, 0x0000, 0x4661, 0x0000, 0x4662, 0x0000, 0x4663,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4664, 0x0000, 0x4665, 0x0000,
+ 0x4666, 0x4667, 0x0000, 0x4668, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4669, 0x466a, 0x466b,
+ 0x0000, 0x466c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x466d, 0x466e, 0x0000, 0x466f,
+ 0x4670, 0x0000, 0x0000, 0x0000, 0x4671, 0x0000, 0x0000, 0x4672,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4673, 0x0000, 0x4674, 0x0000, 0x4675, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4676, 0x0000, 0x0000, 0x0000, 0x4677, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4678, 0x0000, 0x4679,
+ 0x467a, 0x467b, 0x467c, 0x0000, 0x467d, 0x0000, 0x467e, 0x0000,
+ 0x0000, 0x0000, 0x4721, 0x0000, 0x4722, 0x0000, 0x0000, 0x0000,
+ 0x4723, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4724,
+ 0x0000, 0x4725, 0x0000, 0x4726, 0x4727, 0x0000, 0x4728, 0x0000,
+ 0x0000, 0x0000, 0x4729, 0x0000, 0x472a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_6d[] = {
+ /* 0x6d00 - 0x6dff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x472b, 0x0000, 0x0000, 0x472c,
+ 0x0000, 0x0000, 0x472d, 0x0000, 0x0000, 0x0000, 0x472e, 0x472f,
+ 0x0000, 0x4730, 0x0000, 0x4731, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4732, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4733, 0x4734,
+ 0x4735, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4737, 0x4738,
+ 0x0000, 0x4739, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x473a, 0x0000, 0x0000, 0x473b, 0x0000, 0x0000, 0x473c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x473d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x473e, 0x473f,
+ 0x0000, 0x4740, 0x0000, 0x0000, 0x0000, 0x4741, 0x0000, 0x4742,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4743,
+ 0x4744, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4745, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4746, 0x0000, 0x0000, 0x0000, 0x0000, 0x4747,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4748, 0x4749, 0x0000, 0x474a, 0x0000, 0x474b, 0x474c,
+ 0x474d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x474e, 0x0000, 0x474f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4750, 0x0000, 0x0000, 0x4751,
+ 0x0000, 0x4752, 0x0000, 0x0000, 0x0000, 0x4753, 0x0000, 0x4754,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4755, 0x0000, 0x0000, 0x0000,
+ 0x4756, 0x0000, 0x4757, 0x0000, 0x0000, 0x0000, 0x4758, 0x4759,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x475a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x475b, 0x0000, 0x475c, 0x0000, 0x475d,
+ 0x475e, 0x0000, 0x475f, 0x0000, 0x0000, 0x4760, 0x0000, 0x0000,
+ 0x0000, 0x4761, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4762,
+ 0x4763, 0x0000, 0x744c, 0x0000, 0x4764, 0x0000, 0x4765, 0x0000,
+ 0x744b, 0x0000, 0x0000, 0x0000, 0x4766, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_6e[] = {
+ /* 0x6e00 - 0x6eff */
+ 0x4767, 0x0000, 0x0000, 0x0000, 0x4768, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4769, 0x0000,
+ 0x0000, 0x0000, 0x476a, 0x0000, 0x0000, 0x0000, 0x0000, 0x476b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x476c, 0x0000, 0x0000, 0x0000, 0x476d, 0x0000,
+ 0x0000, 0x476e, 0x0000, 0x476f, 0x4770, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4771, 0x4772, 0x0000, 0x0000,
+ 0x4773, 0x4774, 0x0000, 0x4775, 0x0000, 0x0000, 0x0000, 0x4776,
+ 0x0000, 0x4777, 0x4778, 0x4779, 0x477a, 0x0000, 0x0000, 0x477b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x477c, 0x477d, 0x477e, 0x0000,
+ 0x0000, 0x0000, 0x4821, 0x4822, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4823, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4824, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4825, 0x0000, 0x4826, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4827, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4828, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4829, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x482a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x482b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x482c, 0x482d, 0x0000,
+ 0x0000, 0x482e, 0x0000, 0x482f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4830, 0x0000, 0x0000, 0x0000, 0x4831,
+ 0x4832, 0x4833, 0x0000, 0x4834, 0x0000, 0x0000, 0x0000, 0x4835,
+ 0x4836, 0x0000, 0x4837, 0x0000, 0x0000, 0x4838, 0x4839, 0x483a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x483b, 0x0000, 0x483c, 0x483d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x483e, 0x0000, 0x483f, 0x0000, 0x4840, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_6f[] = {
+ /* 0x6f00 - 0x6fff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4841, 0x0000, 0x0000, 0x0000,
+ 0x4842, 0x0000, 0x4843, 0x0000, 0x4844, 0x4845, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4846, 0x0000,
+ 0x4847, 0x0000, 0x4848, 0x4849, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x484a, 0x0000,
+ 0x0000, 0x484b, 0x484c, 0x0000, 0x0000, 0x4853, 0x0000, 0x484d,
+ 0x484e, 0x0000, 0x0000, 0x484f, 0x0000, 0x0000, 0x4850, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4851, 0x4852, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4854,
+ 0x0000, 0x4855, 0x4856, 0x4857, 0x0000, 0x0000, 0x0000, 0x4858,
+ 0x0000, 0x4859, 0x485a, 0x0000, 0x0000, 0x485b, 0x485c, 0x0000,
+ 0x0000, 0x485d, 0x485e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x485f, 0x0000, 0x0000, 0x0000, 0x4860, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4861, 0x4862, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4863, 0x0000, 0x0000, 0x0000, 0x4864,
+ 0x4865, 0x0000, 0x0000, 0x4866, 0x4867, 0x4868, 0x0000, 0x0000,
+ 0x4869, 0x0000, 0x486a, 0x486b, 0x486c, 0x0000, 0x486d, 0x0000,
+ 0x0000, 0x0000, 0x486e, 0x0000, 0x0000, 0x0000, 0x0000, 0x486f,
+ 0x4870, 0x0000, 0x0000, 0x0000, 0x0000, 0x4871, 0x4872, 0x4873,
+ 0x4874, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4875, 0x4876,
+ 0x4877, 0x0000, 0x0000, 0x0000, 0x0000, 0x4878, 0x4879, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x487a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x487b, 0x0000, 0x487c,
+ 0x487d, 0x0000, 0x487e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4921, 0x0000, 0x0000, 0x0000, 0x4922, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4923, 0x4924, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4925, 0x0000, 0x0000, 0x0000, 0x0000, 0x4926, 0x0000, 0x0000,
+ 0x0000, 0x4927, 0x0000, 0x0000, 0x4928, 0x4929, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_70[] = {
+ /* 0x7000 - 0x70ff */
+ 0x492a, 0x0000, 0x0000, 0x0000, 0x0000, 0x492b, 0x492c, 0x492d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x492e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x492f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4930, 0x0000, 0x0000, 0x4931, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x744d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4932,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4933, 0x0000, 0x0000, 0x4934,
+ 0x0000, 0x4935, 0x0000, 0x0000, 0x4936, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4937, 0x4938, 0x0000, 0x0000, 0x0000,
+ 0x4939, 0x493a, 0x493b, 0x493c, 0x0000, 0x0000, 0x4941, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x493d, 0x493e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x493f, 0x4940, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4942, 0x4943, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4944, 0x0000, 0x4945, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4946, 0x4947, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4948, 0x0000,
+ 0x0000, 0x4949, 0x0000, 0x0000, 0x0000, 0x494a, 0x494b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x494c, 0x494d, 0x494e, 0x494f,
+ 0x4950, 0x0000, 0x0000, 0x4951, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4952, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4953, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4954, 0x4955, 0x0000, 0x0000, 0x4956, 0x0000, 0x0000, 0x4957,
+ 0x0000, 0x0000, 0x0000, 0x742e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4958, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4959, 0x0000, 0x495a, 0x495b, 0x495c, 0x495d, 0x0000,
+ 0x495e, 0x0000, 0x0000, 0x0000, 0x495f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4960, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4961, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_71[] = {
+ /* 0x7100 - 0x71ff */
+ 0x0000, 0x0000, 0x0000, 0x4962, 0x4963, 0x4964, 0x4965, 0x4966,
+ 0x0000, 0x0000, 0x0000, 0x4967, 0x4968, 0x0000, 0x0000, 0x4969,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x496a, 0x0000,
+ 0x496b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x496c, 0x0000, 0x496d, 0x0000, 0x496e,
+ 0x496f, 0x4970, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4971, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4972, 0x0000, 0x0000, 0x0000, 0x4973, 0x4974, 0x4975,
+ 0x0000, 0x0000, 0x4976, 0x4977, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4978, 0x0000, 0x4979, 0x0000, 0x0000, 0x0000, 0x0000, 0x497a,
+ 0x0000, 0x0000, 0x497b, 0x0000, 0x497c, 0x0000, 0x497d, 0x0000,
+ 0x497e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4a21, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4a22, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4a23, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a24, 0x0000, 0x4a25,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4a26, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4a27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4a28, 0x4a29, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4a2a, 0x0000, 0x4a2b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a2c,
+ 0x4a2d, 0x0000, 0x4a2e, 0x4a2f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4a30, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a31,
+ 0x4a32, 0x4a33, 0x0000, 0x0000, 0x4a34, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a35, 0x4a36, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a37, 0x0000, 0x0000, 0x4a38, 0x0000,
+ 0x0000, 0x4a39, 0x4a3a, 0x0000, 0x4a3b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4a3c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a3d, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_72[] = {
+ /* 0x7200 - 0x72ff */
+ 0x4a3e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a3f,
+ 0x4a40, 0x4a41, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a42, 0x0000, 0x0000, 0x0000, 0x4a43,
+ 0x0000, 0x0000, 0x4a44, 0x0000, 0x0000, 0x4a45, 0x0000, 0x4a46,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4a47, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a48, 0x0000, 0x0000, 0x0000, 0x4a49,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4a4a, 0x0000, 0x0000, 0x0000,
+ 0x4a4b, 0x4a4c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4a4d, 0x4a4e, 0x4a4f, 0x0000, 0x4a50, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a51, 0x4a52,
+ 0x4a53, 0x0000, 0x0000, 0x4a54, 0x0000, 0x4a55, 0x4a56, 0x0000,
+ 0x0000, 0x0000, 0x4a57, 0x0000, 0x4a58, 0x0000, 0x4a59, 0x0000,
+ 0x4a5a, 0x0000, 0x0000, 0x4a5b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4a5c, 0x0000, 0x0000, 0x4a5d, 0x0000, 0x0000, 0x4a5e, 0x4a5f,
+ 0x0000, 0x4a60, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a61,
+ 0x4a62, 0x0000, 0x0000, 0x4a63, 0x4a64, 0x0000, 0x0000, 0x4a65,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4a66, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4a67, 0x0000, 0x0000, 0x0000, 0x4a68, 0x4a69, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a6a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a6b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4a6c, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a6d, 0x4a6e, 0x0000,
+ 0x0000, 0x4a6f, 0x0000, 0x0000, 0x4a70, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a71, 0x0000,
+ 0x0000, 0x4a72, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a73,
+ 0x0000, 0x4a74, 0x0000, 0x0000, 0x4a75, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a76, 0x4a77, 0x0000,
+ 0x4a78, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a79,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4a7a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4a7b, 0x4a7c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4a7d, 0x4a7e, 0x0000, 0x0000, 0x4b21, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_73[] = {
+ /* 0x7300 - 0x73ff */
+ 0x0000, 0x0000, 0x4b22, 0x0000, 0x4b23, 0x4b24, 0x0000, 0x4b25,
+ 0x0000, 0x0000, 0x0000, 0x4b26, 0x0000, 0x4b27, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4b28, 0x4b29, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4b2a, 0x4b2b, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b2c, 0x0000,
+ 0x0000, 0x0000, 0x4b2d, 0x0000, 0x4b2e, 0x0000, 0x0000, 0x4b2f,
+ 0x4b30, 0x0000, 0x0000, 0x0000, 0x4b31, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4b32, 0x4b33, 0x0000, 0x0000, 0x4b34, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4b35, 0x4b36, 0x0000, 0x4b37, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4b38, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b39, 0x0000, 0x0000,
+ 0x4b3a, 0x0000, 0x4b3b, 0x0000, 0x0000, 0x0000, 0x4b3c, 0x0000,
+ 0x4b3d, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b3e, 0x4b3f, 0x4b40,
+ 0x4b41, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b42, 0x4b43,
+ 0x0000, 0x4b44, 0x0000, 0x4b45, 0x4b46, 0x0000, 0x4b47, 0x4b48,
+ 0x0000, 0x4b49, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b4a,
+ 0x0000, 0x4b4b, 0x0000, 0x0000, 0x4b4c, 0x0000, 0x0000, 0x0000,
+ 0x4b4d, 0x4b4e, 0x0000, 0x4b4f, 0x0000, 0x4b50, 0x4b51, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b52, 0x0000,
+ 0x4b53, 0x0000, 0x0000, 0x4b54, 0x0000, 0x4b55, 0x0000, 0x4b56,
+ 0x4b57, 0x0000, 0x0000, 0x0000, 0x4b58, 0x0000, 0x4b59, 0x4b5a,
+ 0x4b5b, 0x0000, 0x4b5c, 0x0000, 0x0000, 0x4b5d, 0x4b5e, 0x0000,
+ 0x0000, 0x0000, 0x4b5f, 0x4b60, 0x0000, 0x4b61, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b62, 0x0000, 0x4b63,
+ 0x0000, 0x4b64, 0x0000, 0x0000, 0x4b65, 0x4b66, 0x0000, 0x4b67,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4b68, 0x4b69, 0x0000,
+ 0x0000, 0x4b6a, 0x0000, 0x4b6b, 0x4b6c, 0x0000, 0x0000, 0x4b6d,
+ 0x0000, 0x0000, 0x4b6e, 0x4b6f, 0x0000, 0x0000, 0x4b70, 0x0000,
+ 0x0000, 0x4b71, 0x0000, 0x0000, 0x0000, 0x4b72, 0x0000, 0x0000,
+ 0x0000, 0x4b73, 0x0000, 0x4b74, 0x0000, 0x0000, 0x4b75, 0x4b76,
+ 0x0000, 0x4b77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4b78, 0x4b79, 0x0000, 0x4b7a,
+ 0x0000, 0x4b7b, 0x4b7c, 0x4b7d, 0x0000, 0x4b7e, 0x0000, 0x4c21,
+};
+
+static unsigned short const tqunicode_to_jisx0212_74[] = {
+ /* 0x7400 - 0x74ff */
+ 0x4c22, 0x4c23, 0x0000, 0x0000, 0x4c24, 0x0000, 0x0000, 0x4c25,
+ 0x0000, 0x0000, 0x4c26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4c27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4c28, 0x4c29, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4c2a, 0x0000, 0x4c2b, 0x0000,
+ 0x4c2c, 0x4c2d, 0x4c2e, 0x4c2f, 0x4c30, 0x4c31, 0x4c32, 0x4c33,
+ 0x4c34, 0x4c35, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4c36, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4c37, 0x0000, 0x0000, 0x4c38, 0x4c39, 0x0000, 0x4c3a, 0x4c3b,
+ 0x0000, 0x0000, 0x0000, 0x4c3c, 0x0000, 0x4c3d, 0x0000, 0x0000,
+ 0x0000, 0x4c3e, 0x4c3f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c40,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c41, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4c42, 0x0000, 0x0000, 0x0000, 0x4c43, 0x4c44,
+ 0x4c45, 0x0000, 0x0000, 0x4c46, 0x0000, 0x4c47, 0x4c48, 0x0000,
+ 0x0000, 0x4c49, 0x4c4a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4c4b, 0x4c4c, 0x0000, 0x0000, 0x0000, 0x4c4d, 0x4c4e, 0x4c4f,
+ 0x0000, 0x4c50, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c51,
+ 0x4c52, 0x4c53, 0x4c54, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4c55, 0x4c56, 0x4c57, 0x0000, 0x4c58, 0x0000, 0x0000, 0x4c59,
+ 0x4c5a, 0x4c5b, 0x0000, 0x4c5c, 0x0000, 0x0000, 0x4c5d, 0x0000,
+ 0x4c5e, 0x4c5f, 0x4c60, 0x4c61, 0x0000, 0x0000, 0x4c62, 0x4c63,
+ 0x0000, 0x4c64, 0x4c65, 0x0000, 0x0000, 0x4c66, 0x0000, 0x0000,
+ 0x0000, 0x4c67, 0x0000, 0x4c68, 0x0000, 0x0000, 0x0000, 0x4c69,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4c6a, 0x4c6b, 0x0000, 0x0000, 0x4c6c, 0x0000, 0x0000, 0x0000,
+ 0x4c6d, 0x0000, 0x0000, 0x4c6e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4c6f, 0x0000, 0x4c70, 0x4c71, 0x0000, 0x0000, 0x4c72, 0x4c73,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4c74, 0x0000, 0x0000, 0x0000,
+ 0x4c75, 0x0000, 0x4c76, 0x4c77, 0x0000, 0x0000, 0x0000, 0x4c78,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4c79, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4c7a, 0x4c7b, 0x4c7c, 0x0000, 0x0000, 0x4c7d,
+};
+
+static unsigned short const tqunicode_to_jisx0212_75[] = {
+ /* 0x7500 - 0x75ff */
+ 0x0000, 0x7450, 0x0000, 0x0000, 0x0000, 0x0000, 0x4c7e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4d21, 0x0000, 0x0000, 0x0000, 0x4d22, 0x4d23,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4d24, 0x4d25, 0x0000, 0x0000, 0x4d26, 0x0000, 0x0000, 0x4d27,
+ 0x0000, 0x4d28, 0x4d29, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d2a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d2b, 0x0000,
+ 0x0000, 0x4d2c, 0x0000, 0x0000, 0x0000, 0x4d2d, 0x4d2e, 0x4d2f,
+ 0x4d30, 0x0000, 0x0000, 0x4d31, 0x0000, 0x0000, 0x0000, 0x4d32,
+ 0x4d33, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d34, 0x0000,
+ 0x4d35, 0x0000, 0x4d36, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d37,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d38, 0x4d39,
+ 0x0000, 0x4d3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d3b,
+ 0x0000, 0x4d3c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4d3d, 0x4d3e, 0x4d3f, 0x4d40, 0x4d41, 0x4d42, 0x0000,
+ 0x0000, 0x4d43, 0x0000, 0x0000, 0x0000, 0x4d44, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4d45, 0x0000, 0x4d46, 0x4d47, 0x0000, 0x4d48, 0x0000, 0x0000,
+ 0x0000, 0x4d49, 0x0000, 0x0000, 0x4d4a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4d4b, 0x0000, 0x4d4c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4d4d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4d4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d4f,
+ 0x4d50, 0x4d51, 0x0000, 0x0000, 0x4d52, 0x0000, 0x4d53, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4d54, 0x0000, 0x4d55, 0x4d56,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4d57,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4d58, 0x0000, 0x0000, 0x4d59,
+ 0x4d5a, 0x4d5b, 0x0000, 0x0000, 0x4d5c, 0x0000, 0x0000, 0x4d5d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4d5e, 0x0000, 0x4d5f, 0x4d60,
+ 0x0000, 0x4d61, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4d62, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_76[] = {
+ /* 0x7600 - 0x76ff */
+ 0x4d63, 0x0000, 0x4d64, 0x4d65, 0x4d66, 0x0000, 0x0000, 0x4d67,
+ 0x4d68, 0x0000, 0x4d69, 0x0000, 0x4d6a, 0x0000, 0x0000, 0x4d6b,
+ 0x0000, 0x0000, 0x4d6c, 0x4d6d, 0x0000, 0x4d6e, 0x4d6f, 0x0000,
+ 0x0000, 0x4d70, 0x0000, 0x4d71, 0x4d72, 0x4d73, 0x4d74, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4d75, 0x0000, 0x4d76, 0x4d77, 0x0000,
+ 0x0000, 0x4d78, 0x0000, 0x0000, 0x0000, 0x4d79, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4d7a, 0x4d7b, 0x0000, 0x4d7c, 0x0000, 0x0000,
+ 0x4d7d, 0x4d7e, 0x4e21, 0x0000, 0x4e22, 0x0000, 0x0000, 0x0000,
+ 0x4e24, 0x4e25, 0x0000, 0x4e26, 0x4e27, 0x4e28, 0x0000, 0x0000,
+ 0x0000, 0x4e29, 0x4e23, 0x4e2a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e2b, 0x0000, 0x0000,
+ 0x0000, 0x4e2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e2d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4e2e, 0x4e2f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e30, 0x4e31, 0x4e32,
+ 0x0000, 0x4e33, 0x0000, 0x0000, 0x4e34, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4e35, 0x7451, 0x0000, 0x0000, 0x4e36, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4e37, 0x4e38, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e39, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4e3a, 0x4e3b, 0x4e3c, 0x7452, 0x4e3d,
+ 0x4e3e, 0x0000, 0x4e3f, 0x4e40, 0x4e41, 0x4e42, 0x4e43, 0x4e44,
+ 0x4e45, 0x0000, 0x4e46, 0x0000, 0x0000, 0x4e47, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e48, 0x0000, 0x0000,
+ 0x0000, 0x4e49, 0x0000, 0x0000, 0x0000, 0x4e4a, 0x0000, 0x0000,
+ 0x0000, 0x4e4b, 0x0000, 0x4e4c, 0x4e4d, 0x0000, 0x4e4e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4e4f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4e50, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4e51, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e52, 0x0000,
+ 0x4e53, 0x0000, 0x0000, 0x0000, 0x4e54, 0x0000, 0x0000, 0x0000,
+ 0x4e55, 0x4e56, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e57, 0x0000,
+ 0x0000, 0x4e58, 0x0000, 0x0000, 0x4e59, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_77[] = {
+ /* 0x7700 - 0x77ff */
+ 0x4e5a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e5b, 0x0000,
+ 0x0000, 0x0000, 0x4e5c, 0x0000, 0x0000, 0x0000, 0x4e5d, 0x0000,
+ 0x0000, 0x0000, 0x4e5e, 0x0000, 0x4e5f, 0x4e60, 0x0000, 0x4e61,
+ 0x0000, 0x4e62, 0x4e63, 0x0000, 0x4e64, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4e65, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x4e66, 0x0000, 0x0000, 0x0000, 0x0000, 0x4e67, 0x4e68, 0x4e69,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4e6a, 0x4e6b, 0x4e6c, 0x0000,
+ 0x0000, 0x4e6d, 0x0000, 0x0000, 0x0000, 0x4e6e, 0x4e6f, 0x0000,
+ 0x0000, 0x0000, 0x4e70, 0x0000, 0x0000, 0x4e71, 0x4e72, 0x0000,
+ 0x0000, 0x0000, 0x4e73, 0x0000, 0x0000, 0x4e74, 0x4e75, 0x4e76,
+ 0x0000, 0x0000, 0x4e77, 0x0000, 0x0000, 0x0000, 0x4e78, 0x4e79,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4e7a, 0x0000, 0x4e7b, 0x4e7c,
+ 0x4e7d, 0x0000, 0x4e7e, 0x0000, 0x4f21, 0x0000, 0x0000, 0x4f22,
+ 0x0000, 0x0000, 0x4f23, 0x0000, 0x4f24, 0x0000, 0x0000, 0x0000,
+ 0x4f25, 0x0000, 0x4f26, 0x4f27, 0x4f28, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4f29, 0x0000, 0x0000, 0x4f2a, 0x0000, 0x0000,
+ 0x4f2b, 0x0000, 0x0000, 0x0000, 0x4f2c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4f2d, 0x4f2e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4f2f, 0x4f30, 0x4f31, 0x0000,
+ 0x0000, 0x0000, 0x4f32, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f33,
+ 0x0000, 0x0000, 0x4f34, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f35,
+ 0x0000, 0x0000, 0x4f36, 0x0000, 0x0000, 0x0000, 0x4f37, 0x4f38,
+ 0x0000, 0x4f39, 0x0000, 0x0000, 0x0000, 0x4f3a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f3b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4f3c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4f3d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x4f3e, 0x4f3f, 0x0000, 0x0000, 0x4f40, 0x0000, 0x0000,
+ 0x0000, 0x4f41, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f42, 0x4f43,
+ 0x4f44, 0x0000, 0x0000, 0x0000, 0x4f45, 0x0000, 0x4f46, 0x0000,
+ 0x0000, 0x0000, 0x4f47, 0x0000, 0x4f48, 0x0000, 0x0000, 0x0000,
+ 0x4f49, 0x4f4a, 0x0000, 0x0000, 0x4f4b, 0x0000, 0x0000, 0x0000,
+ 0x4f4c, 0x0000, 0x0000, 0x4f4d, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_78[] = {
+ /* 0x7800 - 0x78ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f4e, 0x4f4f, 0x0000,
+ 0x0000, 0x4f50, 0x0000, 0x0000, 0x0000, 0x4f51, 0x4f52, 0x0000,
+ 0x0000, 0x4f53, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f54, 0x0000, 0x0000,
+ 0x0000, 0x4f55, 0x4f56, 0x4f57, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f58, 0x4f59, 0x0000,
+ 0x4f5a, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f5b, 0x0000, 0x4f5c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x4f5d, 0x4f5e, 0x0000, 0x0000, 0x4f5f,
+ 0x4f60, 0x0000, 0x0000, 0x0000, 0x4f61, 0x0000, 0x4f62, 0x0000,
+ 0x0000, 0x0000, 0x4f63, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4f64, 0x0000, 0x4f65, 0x0000,
+ 0x4f66, 0x4f67, 0x0000, 0x4f68, 0x4f69, 0x0000, 0x0000, 0x0000,
+ 0x4f6a, 0x0000, 0x4f6b, 0x0000, 0x0000, 0x0000, 0x4f6c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4f6d, 0x0000, 0x0000, 0x0000, 0x4f6e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x4f6f, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f70,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x4f71, 0x0000, 0x0000, 0x0000,
+ 0x4f72, 0x0000, 0x0000, 0x0000, 0x0000, 0x4f74, 0x4f75, 0x4f76,
+ 0x0000, 0x4f73, 0x0000, 0x0000, 0x4f77, 0x0000, 0x0000, 0x0000,
+ 0x4f78, 0x0000, 0x0000, 0x0000, 0x4f79, 0x4f7a, 0x0000, 0x0000,
+ 0x4f7b, 0x4f7c, 0x4f7d, 0x4f7e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5021, 0x0000, 0x5022, 0x0000, 0x5023,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5024,
+ 0x5025, 0x5026, 0x0000, 0x0000, 0x5027, 0x0000, 0x5028, 0x0000,
+ 0x0000, 0x0000, 0x5029, 0x502a, 0x0000, 0x502b, 0x502c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x502e, 0x0000, 0x0000, 0x0000, 0x502f,
+ 0x5030, 0x5031, 0x0000, 0x0000, 0x502d, 0x0000, 0x5032, 0x0000,
+ 0x0000, 0x0000, 0x5033, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5034, 0x5035, 0x0000, 0x0000, 0x5037, 0x5038,
+ 0x0000, 0x0000, 0x5039, 0x503a, 0x0000, 0x0000, 0x0000, 0x503b,
+};
+
+static unsigned short const tqunicode_to_jisx0212_79[] = {
+ /* 0x7900 - 0x79ff */
+ 0x5036, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x503c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x503d, 0x0000, 0x0000, 0x0000,
+ 0x503e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x503f, 0x0000, 0x5040, 0x0000, 0x5041, 0x5042,
+ 0x5043, 0x0000, 0x0000, 0x0000, 0x0000, 0x5044, 0x0000, 0x5045,
+ 0x0000, 0x5046, 0x0000, 0x0000, 0x0000, 0x5047, 0x0000, 0x0000,
+ 0x7454, 0x5048, 0x0000, 0x0000, 0x5049, 0x504a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x504b, 0x0000, 0x504c, 0x0000, 0x504d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x504e, 0x504f, 0x5050, 0x0000,
+ 0x0000, 0x0000, 0x5051, 0x5052, 0x0000, 0x0000, 0x0000, 0x5053,
+ 0x0000, 0x5054, 0x0000, 0x0000, 0x5055, 0x0000, 0x0000, 0x0000,
+ 0x5056, 0x0000, 0x0000, 0x5057, 0x5058, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5059,
+ 0x0000, 0x505a, 0x0000, 0x505b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x505c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x505d, 0x0000, 0x505e, 0x505f, 0x0000, 0x5060, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5061, 0x5062, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5063, 0x0000, 0x5064, 0x5065, 0x5066, 0x5067, 0x0000,
+ 0x5068, 0x0000, 0x0000, 0x5069, 0x506a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x506b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x506c, 0x506d, 0x0000, 0x506e, 0x0000, 0x0000, 0x0000, 0x506f,
+ 0x0000, 0x5070, 0x0000, 0x0000, 0x5071, 0x0000, 0x0000, 0x0000,
+ 0x5072, 0x0000, 0x0000, 0x5073, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5074, 0x0000, 0x5075, 0x0000, 0x0000, 0x5076,
+ 0x5077, 0x0000, 0x5078, 0x0000, 0x0000, 0x0000, 0x0000, 0x5079,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x507a, 0x0000, 0x507b, 0x0000,
+ 0x0000, 0x0000, 0x507c, 0x0000, 0x0000, 0x507d, 0x507e, 0x0000,
+ 0x5121, 0x0000, 0x5122, 0x0000, 0x0000, 0x5123, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5124, 0x5125, 0x0000, 0x5126, 0x0000, 0x0000,
+ 0x0000, 0x5127, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5128, 0x0000, 0x0000, 0x0000, 0x5129, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_7a[] = {
+ /* 0x7a00 - 0x7aff */
+ 0x0000, 0x0000, 0x512a, 0x512b, 0x0000, 0x0000, 0x0000, 0x512c,
+ 0x0000, 0x512d, 0x512e, 0x0000, 0x512f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5130, 0x0000, 0x0000, 0x0000, 0x5131, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5132, 0x0000, 0x0000, 0x5133, 0x0000,
+ 0x0000, 0x5134, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5135,
+ 0x0000, 0x0000, 0x0000, 0x5136, 0x0000, 0x5137, 0x0000, 0x5138,
+ 0x5139, 0x0000, 0x0000, 0x0000, 0x513a, 0x513b, 0x0000, 0x0000,
+ 0x513c, 0x513d, 0x513e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x513f, 0x5140, 0x0000, 0x5141,
+ 0x5142, 0x0000, 0x0000, 0x0000, 0x5143, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5144, 0x5145, 0x0000,
+ 0x0000, 0x5146, 0x0000, 0x0000, 0x5147, 0x5148, 0x0000, 0x5149,
+ 0x514a, 0x0000, 0x0000, 0x0000, 0x0000, 0x514b, 0x0000, 0x514c,
+ 0x0000, 0x0000, 0x514d, 0x0000, 0x0000, 0x514e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x514f, 0x0000, 0x0000,
+ 0x5150, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5151, 0x0000,
+ 0x5152, 0x0000, 0x5153, 0x0000, 0x0000, 0x5154, 0x5155, 0x0000,
+ 0x0000, 0x0000, 0x5156, 0x5157, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5158, 0x5159, 0x0000, 0x0000, 0x515a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x515b, 0x0000,
+ 0x515c, 0x0000, 0x0000, 0x515d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x515e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x515f, 0x0000, 0x5160, 0x0000, 0x0000,
+ 0x0000, 0x5161, 0x0000, 0x5162, 0x5163, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5164, 0x0000,
+ 0x0000, 0x5165, 0x0000, 0x0000, 0x5166, 0x0000, 0x5167, 0x0000,
+ 0x0000, 0x5168, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5169, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7459,
+ 0x516a, 0x516b, 0x0000, 0x516c, 0x516d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x516e, 0x0000, 0x0000, 0x516f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5170, 0x0000, 0x5171, 0x5172, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_7b[] = {
+ /* 0x7b00 - 0x7bff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5173,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5174, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5175,
+ 0x0000, 0x0000, 0x0000, 0x5176, 0x0000, 0x0000, 0x0000, 0x5177,
+ 0x0000, 0x5178, 0x5179, 0x517a, 0x0000, 0x517b, 0x517c, 0x517d,
+ 0x517e, 0x5221, 0x0000, 0x0000, 0x5222, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5223, 0x0000, 0x5224,
+ 0x5225, 0x5226, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5227,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5228, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5229, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x522a, 0x0000, 0x0000, 0x0000, 0x522b, 0x0000, 0x522c, 0x0000,
+ 0x0000, 0x522d, 0x522e, 0x0000, 0x0000, 0x522f, 0x0000, 0x5230,
+ 0x0000, 0x0000, 0x5231, 0x5232, 0x0000, 0x0000, 0x0000, 0x5233,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5234, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5235, 0x0000, 0x0000, 0x0000, 0x0000, 0x5236, 0x0000,
+ 0x5237, 0x5238, 0x0000, 0x0000, 0x0000, 0x0000, 0x5239, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x523a, 0x0000, 0x0000, 0x523b, 0x0000,
+ 0x523c, 0x0000, 0x0000, 0x0000, 0x0000, 0x523d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x523e, 0x0000, 0x0000, 0x523f,
+ 0x5240, 0x0000, 0x5241, 0x0000, 0x0000, 0x5242, 0x5243, 0x0000,
+ 0x0000, 0x0000, 0x5244, 0x5245, 0x5246, 0x5247, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5248, 0x0000, 0x0000, 0x5249, 0x0000, 0x0000,
+ 0x524a, 0x0000, 0x524b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x524c, 0x0000, 0x524d, 0x524e,
+ 0x0000, 0x524f, 0x5250, 0x5251, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5252, 0x0000, 0x5253, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5254, 0x0000, 0x5255, 0x5256, 0x0000, 0x0000,
+ 0x5257, 0x5258, 0x5259, 0x0000, 0x525a, 0x0000, 0x525b, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_7c[] = {
+ /* 0x7c00 - 0x7cff */
+ 0x0000, 0x525c, 0x525d, 0x525e, 0x525f, 0x0000, 0x5260, 0x0000,
+ 0x0000, 0x5261, 0x0000, 0x5262, 0x5263, 0x0000, 0x5264, 0x5265,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5266, 0x0000, 0x5267, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5268, 0x0000, 0x0000, 0x0000, 0x0000, 0x5269, 0x526a, 0x0000,
+ 0x526b, 0x0000, 0x0000, 0x0000, 0x526c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x526d, 0x0000, 0x526e, 0x526f, 0x0000, 0x5270, 0x0000,
+ 0x0000, 0x5271, 0x5272, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5273, 0x0000,
+ 0x0000, 0x0000, 0x5274, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5276, 0x5277, 0x5278, 0x0000, 0x5275, 0x0000, 0x0000,
+ 0x0000, 0x5279, 0x527a, 0x527b, 0x527c, 0x527d, 0x527e, 0x0000,
+ 0x0000, 0x5321, 0x0000, 0x5322, 0x0000, 0x0000, 0x0000, 0x5323,
+ 0x0000, 0x5324, 0x0000, 0x0000, 0x0000, 0x5325, 0x5326, 0x0000,
+ 0x5327, 0x0000, 0x5328, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5329, 0x0000, 0x0000, 0x532a, 0x532b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x532c, 0x532d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x532e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x532f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5330, 0x0000,
+ 0x5331, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5332, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5333, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5334, 0x5335,
+ 0x0000, 0x0000, 0x5336, 0x5337, 0x5338, 0x0000, 0x0000, 0x5339,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x533a, 0x0000, 0x0000, 0x533b,
+ 0x533c, 0x533d, 0x0000, 0x0000, 0x0000, 0x533e, 0x0000, 0x533f,
+ 0x0000, 0x0000, 0x0000, 0x5340, 0x5341, 0x5342, 0x0000, 0x5343,
+ 0x0000, 0x5344, 0x5345, 0x0000, 0x0000, 0x5346, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5347, 0x0000,
+ 0x0000, 0x5348, 0x0000, 0x5349, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x534a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_7d[] = {
+ /* 0x7d00 - 0x7dff */
+ 0x0000, 0x0000, 0x0000, 0x534b, 0x0000, 0x0000, 0x0000, 0x534c,
+ 0x534d, 0x534e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x534f,
+ 0x0000, 0x5350, 0x5351, 0x5352, 0x0000, 0x0000, 0x5353, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5354, 0x5355, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5356, 0x0000, 0x0000, 0x5357, 0x0000,
+ 0x0000, 0x0000, 0x5358, 0x0000, 0x0000, 0x5359, 0x0000, 0x0000,
+ 0x0000, 0x535a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x535b, 0x535c, 0x535d, 0x0000,
+ 0x535e, 0x535f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5360,
+ 0x5361, 0x0000, 0x0000, 0x0000, 0x0000, 0x5362, 0x0000, 0x0000,
+ 0x0000, 0x5363, 0x0000, 0x5364, 0x0000, 0x0000, 0x0000, 0x5365,
+ 0x0000, 0x5366, 0x5367, 0x0000, 0x5368, 0x5369, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x536a, 0x0000, 0x536b,
+ 0x0000, 0x0000, 0x536c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x536d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x536e, 0x0000, 0x536f, 0x5370, 0x0000, 0x0000, 0x0000, 0x5371,
+ 0x0000, 0x5372, 0x5373, 0x5374, 0x0000, 0x5375, 0x5376, 0x0000,
+ 0x5377, 0x0000, 0x0000, 0x5378, 0x5379, 0x537a, 0x0000, 0x0000,
+ 0x0000, 0x537b, 0x0000, 0x0000, 0x0000, 0x0000, 0x537c, 0x537d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x537e, 0x5421, 0x0000,
+ 0x745c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5422, 0x5423,
+ 0x0000, 0x0000, 0x5424, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5425, 0x0000, 0x0000, 0x5426, 0x5427,
+ 0x0000, 0x5428, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5429, 0x542a, 0x542b, 0x542c, 0x542d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x542e, 0x542f, 0x5430, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x745d, 0x5431,
+ 0x0000, 0x5432, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5434, 0x0000, 0x0000, 0x5435, 0x5436, 0x0000,
+ 0x0000, 0x0000, 0x5437, 0x5438, 0x0000, 0x5439, 0x0000, 0x0000,
+ 0x0000, 0x543a, 0x0000, 0x0000, 0x0000, 0x543b, 0x543c, 0x0000,
+ 0x0000, 0x543d, 0x543e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_7e[] = {
+ /* 0x7e00 - 0x7eff */
+ 0x5433, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x543f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5440, 0x5441, 0x0000, 0x0000, 0x0000, 0x5442, 0x0000, 0x5443,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5444, 0x5445, 0x0000, 0x0000,
+ 0x5446, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5447,
+ 0x5448, 0x0000, 0x0000, 0x0000, 0x5449, 0x544a, 0x0000, 0x544b,
+ 0x0000, 0x0000, 0x0000, 0x544c, 0x0000, 0x0000, 0x544d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x544e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x544f, 0x5450, 0x0000, 0x5451,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5452, 0x0000,
+ 0x5453, 0x0000, 0x5454, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5455, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5456,
+ 0x0000, 0x5457, 0x5458, 0x0000, 0x0000, 0x5459, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x545a, 0x0000, 0x0000, 0x545b, 0x545c,
+ 0x0000, 0x0000, 0x0000, 0x545d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x545e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x545f, 0x0000,
+ 0x0000, 0x5460, 0x0000, 0x0000, 0x0000, 0x0000, 0x5461, 0x5462,
+ 0x0000, 0x0000, 0x5463, 0x0000, 0x0000, 0x5464, 0x0000, 0x0000,
+ 0x0000, 0x5465, 0x0000, 0x0000, 0x0000, 0x5466, 0x0000, 0x0000,
+ 0x5467, 0x0000, 0x5468, 0x0000, 0x0000, 0x5469, 0x546a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_7f[] = {
+ /* 0x7f00 - 0x7fff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x546c, 0x546b, 0x546d, 0x546e, 0x546f,
+ 0x0000, 0x0000, 0x0000, 0x5470, 0x5471, 0x0000, 0x0000, 0x5472,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5473,
+ 0x0000, 0x0000, 0x5474, 0x5475, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5476, 0x5477, 0x5478, 0x0000, 0x0000,
+ 0x0000, 0x5479, 0x0000, 0x547a, 0x547b, 0x547c, 0x547d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x547e, 0x0000, 0x0000,
+ 0x0000, 0x5521, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5522, 0x5523, 0x5524,
+ 0x5525, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5526, 0x0000, 0x5527, 0x0000, 0x5528,
+ 0x5529, 0x552a, 0x0000, 0x0000, 0x0000, 0x0000, 0x552b, 0x552c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x552d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x552e, 0x552f, 0x0000, 0x0000, 0x0000, 0x5530, 0x0000,
+ 0x0000, 0x0000, 0x5531, 0x0000, 0x0000, 0x5532, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5533, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5534, 0x0000, 0x0000, 0x5535,
+ 0x5536, 0x0000, 0x0000, 0x5537, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5538, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5539, 0x553a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x553b, 0x0000, 0x0000, 0x0000, 0x553c,
+ 0x0000, 0x0000, 0x0000, 0x553d, 0x0000, 0x553e, 0x0000, 0x0000,
+ 0x553f, 0x0000, 0x0000, 0x0000, 0x5540, 0x0000, 0x5541, 0x5542,
+ 0x0000, 0x0000, 0x5543, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5544, 0x0000, 0x0000, 0x5545, 0x5546, 0x5547,
+};
+
+static unsigned short const tqunicode_to_jisx0212_80[] = {
+ /* 0x8000 - 0x80ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5548,
+ 0x5549, 0x0000, 0x554a, 0x0000, 0x0000, 0x554b, 0x554c, 0x554d,
+ 0x0000, 0x554e, 0x0000, 0x554f, 0x5550, 0x0000, 0x5551, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5552, 0x5553, 0x5554,
+ 0x5555, 0x0000, 0x0000, 0x0000, 0x5556, 0x0000, 0x5557, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5558, 0x0000, 0x5559, 0x0000,
+ 0x555a, 0x0000, 0x0000, 0x0000, 0x555b, 0x555c, 0x0000, 0x555d,
+ 0x0000, 0x555e, 0x555f, 0x0000, 0x5560, 0x0000, 0x5561, 0x0000,
+ 0x5562, 0x0000, 0x0000, 0x0000, 0x5563, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5564, 0x0000, 0x0000, 0x0000, 0x5565, 0x0000, 0x5566, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5567, 0x0000, 0x0000,
+ 0x0000, 0x5568, 0x0000, 0x0000, 0x0000, 0x5569, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x556a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x556b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x556c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x556d, 0x0000, 0x556e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x556f, 0x5570,
+ 0x0000, 0x0000, 0x0000, 0x5571, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5572, 0x5573, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5574, 0x0000, 0x0000, 0x0000, 0x0000, 0x5575, 0x0000, 0x5576,
+ 0x0000, 0x0000, 0x5577, 0x0000, 0x5578, 0x5579, 0x0000, 0x557a,
+ 0x557b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x557c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x557d, 0x557e, 0x0000,
+ 0x5621, 0x0000, 0x5622, 0x5623, 0x0000, 0x0000, 0x5624, 0x0000,
+ 0x0000, 0x5625, 0x5626, 0x0000, 0x0000, 0x0000, 0x5627, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_81[] = {
+ /* 0x8100 - 0x81ff */
+ 0x0000, 0x0000, 0x0000, 0x5628, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5629, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x562a, 0x562b,
+ 0x562c, 0x0000, 0x0000, 0x0000, 0x562d, 0x0000, 0x562e, 0x0000,
+ 0x562f, 0x0000, 0x0000, 0x0000, 0x5630, 0x0000, 0x0000, 0x5631,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5632, 0x0000, 0x0000, 0x0000,
+ 0x5633, 0x0000, 0x0000, 0x0000, 0x0000, 0x5634, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5635, 0x0000, 0x5636, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5637, 0x0000, 0x5638,
+ 0x0000, 0x0000, 0x5639, 0x0000, 0x563a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x563b, 0x0000, 0x0000, 0x0000, 0x0000, 0x563c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x563d, 0x563e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x563f,
+ 0x5640, 0x5641, 0x0000, 0x0000, 0x0000, 0x5642, 0x0000, 0x5643,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5644,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5645, 0x0000, 0x0000, 0x5647, 0x5648, 0x5649, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x564a, 0x0000, 0x0000, 0x564b, 0x0000,
+ 0x5646, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x564c, 0x0000,
+ 0x564d, 0x0000, 0x0000, 0x564e, 0x0000, 0x0000, 0x564f, 0x0000,
+ 0x0000, 0x0000, 0x5650, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5651, 0x0000,
+ 0x0000, 0x0000, 0x5652, 0x0000, 0x5653, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5654, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5656, 0x0000, 0x5657, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5658, 0x5655, 0x0000, 0x0000, 0x5659, 0x565a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x565b, 0x0000, 0x565c,
+ 0x0000, 0x0000, 0x0000, 0x565d, 0x0000, 0x565e, 0x565f, 0x0000,
+ 0x0000, 0x5660, 0x0000, 0x0000, 0x5661, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5662, 0x5663, 0x0000, 0x0000, 0x0000,
+ 0x5664, 0x5665, 0x5666, 0x0000, 0x0000, 0x5667, 0x5668, 0x0000,
+ 0x5669, 0x566a, 0x0000, 0x0000, 0x0000, 0x566b, 0x0000, 0x566c,
+};
+
+static unsigned short const tqunicode_to_jisx0212_82[] = {
+ /* 0x8200 - 0x82ff */
+ 0x566d, 0x0000, 0x0000, 0x566e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x566f,
+ 0x0000, 0x0000, 0x0000, 0x5670, 0x5671, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5672, 0x5673, 0x0000, 0x0000, 0x5674, 0x0000, 0x0000,
+ 0x0000, 0x5675, 0x5676, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5677, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5678, 0x0000, 0x5679, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x567a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x567b, 0x567c, 0x567d, 0x567e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5721, 0x0000, 0x0000, 0x5722, 0x5723,
+ 0x0000, 0x5724, 0x0000, 0x0000, 0x0000, 0x0000, 0x5725, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5726, 0x0000, 0x0000, 0x0000,
+ 0x5727, 0x0000, 0x0000, 0x5728, 0x0000, 0x0000, 0x0000, 0x5729,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x572a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x572b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x572c, 0x0000, 0x572d, 0x0000, 0x572e,
+ 0x572f, 0x5730, 0x0000, 0x5731, 0x5732, 0x0000, 0x0000, 0x5733,
+ 0x0000, 0x5734, 0x5735, 0x0000, 0x0000, 0x0000, 0x5736, 0x0000,
+ 0x0000, 0x5737, 0x0000, 0x0000, 0x5738, 0x0000, 0x5739, 0x0000,
+ 0x573a, 0x0000, 0x573b, 0x573c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x573d, 0x573e, 0x0000, 0x573f, 0x5740, 0x0000, 0x0000, 0x5741,
+ 0x5742, 0x5743, 0x5744, 0x0000, 0x0000, 0x0000, 0x5745, 0x0000,
+ 0x5746, 0x0000, 0x5747, 0x0000, 0x5748, 0x0000, 0x0000, 0x5749,
+ 0x0000, 0x0000, 0x574a, 0x0000, 0x574b, 0x0000, 0x574c, 0x574d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x574e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x574f, 0x0000, 0x0000, 0x0000, 0x0000, 0x5750, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5751, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5752, 0x0000, 0x5753, 0x0000, 0x5754, 0x0000, 0x0000, 0x0000,
+ 0x5755, 0x0000, 0x5756, 0x0000, 0x0000, 0x5757, 0x0000, 0x5758,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5759, 0x575a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x575b, 0x575c, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_83[] = {
+ /* 0x8300 - 0x83ff */
+ 0x575d, 0x575e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x575f,
+ 0x5760, 0x0000, 0x5761, 0x5762, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5764, 0x0000, 0x5765, 0x5766, 0x5767,
+ 0x0000, 0x5768, 0x5769, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x576a, 0x576b, 0x576c, 0x0000,
+ 0x576d, 0x0000, 0x0000, 0x576e, 0x0000, 0x0000, 0x0000, 0x576f,
+ 0x0000, 0x0000, 0x5770, 0x0000, 0x5771, 0x5772, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5773, 0x5774, 0x5775, 0x0000, 0x0000, 0x5776,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5777, 0x5778, 0x0000,
+ 0x0000, 0x5779, 0x0000, 0x583e, 0x5763, 0x577a, 0x577b, 0x577c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x745f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x577d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x577e, 0x0000, 0x0000, 0x0000, 0x0000, 0x5821, 0x0000, 0x5822,
+ 0x5823, 0x0000, 0x5824, 0x0000, 0x5825, 0x0000, 0x5826, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5827, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5828, 0x0000, 0x5829, 0x582a, 0x0000, 0x0000,
+ 0x582b, 0x582c, 0x0000, 0x582d, 0x582e, 0x582f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5830, 0x5831,
+ 0x0000, 0x5832, 0x0000, 0x0000, 0x5833, 0x584c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5834, 0x5835,
+ 0x5836, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5837,
+ 0x0000, 0x5838, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5839,
+ 0x583a, 0x583b, 0x0000, 0x0000, 0x583c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x583d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x583f, 0x0000, 0x5840, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5841, 0x0000,
+ 0x5842, 0x5843, 0x0000, 0x0000, 0x5844, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_84[] = {
+ /* 0x8400 - 0x84ff */
+ 0x0000, 0x5845, 0x0000, 0x0000, 0x0000, 0x0000, 0x5846, 0x0000,
+ 0x0000, 0x0000, 0x5847, 0x0000, 0x0000, 0x0000, 0x0000, 0x5848,
+ 0x0000, 0x5849, 0x0000, 0x0000, 0x0000, 0x584a, 0x0000, 0x0000,
+ 0x0000, 0x584b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x584d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x584e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x584f, 0x0000, 0x5850,
+ 0x5851, 0x0000, 0x5852, 0x0000, 0x0000, 0x5853, 0x0000, 0x5854,
+ 0x0000, 0x5855, 0x5856, 0x0000, 0x0000, 0x0000, 0x5857, 0x0000,
+ 0x5858, 0x5859, 0x585a, 0x0000, 0x585b, 0x0000, 0x0000, 0x0000,
+ 0x585c, 0x0000, 0x0000, 0x0000, 0x585d, 0x585e, 0x0000, 0x585f,
+ 0x0000, 0x0000, 0x5860, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5861, 0x0000, 0x0000, 0x5862, 0x5863, 0x0000, 0x5864, 0x0000,
+ 0x5865, 0x0000, 0x0000, 0x0000, 0x5866, 0x5867, 0x0000, 0x0000,
+ 0x0000, 0x5868, 0x0000, 0x0000, 0x0000, 0x5869, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x586a, 0x586b, 0x0000, 0x586c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x586d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x586e, 0x0000,
+ 0x586f, 0x5870, 0x5871, 0x0000, 0x0000, 0x0000, 0x0000, 0x5872,
+ 0x0000, 0x5873, 0x0000, 0x0000, 0x5874, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5875, 0x0000, 0x0000, 0x5876, 0x5877, 0x0000,
+ 0x5878, 0x0000, 0x5879, 0x0000, 0x0000, 0x0000, 0x0000, 0x587a,
+ 0x587b, 0x0000, 0x0000, 0x0000, 0x587c, 0x0000, 0x0000, 0x587d,
+ 0x0000, 0x0000, 0x0000, 0x587e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5921, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5922,
+ 0x0000, 0x0000, 0x5923, 0x0000, 0x0000, 0x0000, 0x0000, 0x5924,
+ 0x5925, 0x5926, 0x5927, 0x0000, 0x0000, 0x0000, 0x0000, 0x5928,
+ 0x0000, 0x0000, 0x592a, 0x592b, 0x0000, 0x592c, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_85[] = {
+ /* 0x8500 - 0x85ff */
+ 0x0000, 0x0000, 0x592d, 0x592e, 0x0000, 0x0000, 0x0000, 0x592f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5930, 0x0000, 0x5931, 0x0000,
+ 0x5932, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5933, 0x0000, 0x5934, 0x0000,
+ 0x0000, 0x0000, 0x5935, 0x5936, 0x5937, 0x5938, 0x0000, 0x5939,
+ 0x0000, 0x0000, 0x593a, 0x593b, 0x0000, 0x0000, 0x0000, 0x593c,
+ 0x0000, 0x0000, 0x5929, 0x593d, 0x593e, 0x0000, 0x593f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5940,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5941, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5942,
+ 0x5943, 0x5944, 0x5945, 0x5946, 0x0000, 0x0000, 0x5947, 0x0000,
+ 0x0000, 0x5948, 0x0000, 0x0000, 0x5949, 0x594a, 0x594b, 0x594c,
+ 0x594d, 0x594e, 0x594f, 0x0000, 0x5950, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5951, 0x0000, 0x0000, 0x0000, 0x5952,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5953, 0x5954, 0x5955, 0x0000, 0x5956, 0x0000, 0x5957,
+ 0x0000, 0x5958, 0x0000, 0x0000, 0x0000, 0x5959, 0x595a, 0x0000,
+ 0x0000, 0x595b, 0x0000, 0x595c, 0x595d, 0x0000, 0x0000, 0x595e,
+ 0x0000, 0x0000, 0x0000, 0x595f, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5960, 0x0000, 0x0000, 0x0000, 0x0000, 0x5961, 0x0000, 0x5962,
+ 0x5963, 0x0000, 0x5964, 0x0000, 0x0000, 0x5965, 0x0000, 0x5966,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5974, 0x0000, 0x0000,
+ 0x7461, 0x0000, 0x0000, 0x0000, 0x5967, 0x0000, 0x5968, 0x5969,
+ 0x596a, 0x0000, 0x0000, 0x0000, 0x596b, 0x596c, 0x596d, 0x596e,
+ 0x0000, 0x0000, 0x596f, 0x0000, 0x0000, 0x0000, 0x0000, 0x5970,
+ 0x0000, 0x0000, 0x5971, 0x5972, 0x0000, 0x0000, 0x5973, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5975, 0x0000, 0x5976, 0x0000, 0x0000, 0x0000, 0x0000, 0x5977,
+ 0x5978, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5979, 0x0000,
+ 0x597a, 0x0000, 0x0000, 0x0000, 0x0000, 0x597b, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x597c, 0x0000, 0x0000, 0x597d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x597e, 0x0000, 0x0000, 0x5a21,
+};
+
+static unsigned short const tqunicode_to_jisx0212_86[] = {
+ /* 0x8600 - 0x86ff */
+ 0x5a22, 0x0000, 0x0000, 0x0000, 0x5a23, 0x5a24, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a25, 0x5a26, 0x0000,
+ 0x5a27, 0x5a28, 0x5a29, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5a2a, 0x5a2b, 0x0000, 0x5a2c, 0x0000, 0x0000, 0x5a2d, 0x0000,
+ 0x0000, 0x5a2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a2f,
+ 0x0000, 0x5a30, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a31, 0x0000,
+ 0x5a32, 0x0000, 0x5a33, 0x0000, 0x5a34, 0x5a35, 0x0000, 0x0000,
+ 0x5a36, 0x3866, 0x5a37, 0x0000, 0x0000, 0x0000, 0x5a38, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5a39, 0x5a3a, 0x0000, 0x0000, 0x5a3b, 0x5a3c,
+ 0x5a3d, 0x5a3e, 0x0000, 0x0000, 0x0000, 0x5a3f, 0x0000, 0x0000,
+ 0x5a40, 0x5a41, 0x5a42, 0x5a43, 0x5a44, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5a45, 0x0000, 0x0000, 0x5a46, 0x0000, 0x0000, 0x5a47,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a48, 0x5a49, 0x5a4a,
+ 0x0000, 0x0000, 0x5a4b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5a6d, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a4c, 0x0000, 0x0000,
+ 0x0000, 0x5a4d, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a4e, 0x0000,
+ 0x5a4f, 0x0000, 0x5a50, 0x0000, 0x5a51, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5a52, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a53, 0x5a54,
+ 0x5a55, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a56, 0x0000, 0x0000,
+ 0x0000, 0x5a57, 0x0000, 0x5a58, 0x5a59, 0x5a5a, 0x0000, 0x5a5b,
+ 0x5a5c, 0x5a5d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a5e,
+ 0x5a5f, 0x5a60, 0x0000, 0x5a61, 0x0000, 0x5a62, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5a63, 0x5a64, 0x0000, 0x0000, 0x5a65, 0x0000, 0x5a66,
+ 0x0000, 0x0000, 0x5a67, 0x0000, 0x5a68, 0x0000, 0x0000, 0x0000,
+ 0x5a69, 0x0000, 0x0000, 0x5a6a, 0x0000, 0x5a6b, 0x0000, 0x5a6c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5a6e, 0x0000, 0x5a6f, 0x5a70, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_87[] = {
+ /* 0x8700 - 0x87ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5a71, 0x5a72, 0x0000, 0x5a73,
+ 0x0000, 0x0000, 0x0000, 0x5a74, 0x0000, 0x0000, 0x5a75, 0x5a76,
+ 0x5a77, 0x0000, 0x0000, 0x5a78, 0x5a79, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5a7a, 0x0000, 0x0000, 0x0000, 0x0000, 0x5a7b, 0x5a7c,
+ 0x0000, 0x5a7d, 0x0000, 0x5a7e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5b21, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b22, 0x5b23,
+ 0x0000, 0x5b24, 0x5b25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5b26, 0x5b27, 0x0000, 0x5b28, 0x5b29, 0x5b2a, 0x0000,
+ 0x5b2b, 0x0000, 0x0000, 0x5b2c, 0x0000, 0x5b2d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b2e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5b2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b30, 0x0000, 0x0000,
+ 0x0000, 0x5b31, 0x0000, 0x0000, 0x5b32, 0x5b33, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b34,
+ 0x0000, 0x5b35, 0x5b36, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5b37, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5b38, 0x5b39, 0x5b3a, 0x5b3b, 0x5b3c,
+ 0x5b3d, 0x5b3e, 0x0000, 0x5b3f, 0x5b40, 0x0000, 0x0000, 0x0000,
+ 0x5b41, 0x0000, 0x0000, 0x5b42, 0x0000, 0x5b43, 0x0000, 0x5b44,
+ 0x5b45, 0x5b46, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b47, 0x0000,
+ 0x5b48, 0x0000, 0x0000, 0x5b49, 0x0000, 0x0000, 0x0000, 0x5b4a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5b4b, 0x5b4c, 0x5b4d, 0x0000,
+ 0x0000, 0x5b4e, 0x0000, 0x0000, 0x0000, 0x5b4f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b50, 0x5b51,
+ 0x0000, 0x5b52, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5b53, 0x5b54, 0x5b55, 0x0000, 0x0000, 0x0000, 0x5b56, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b57, 0x5b58, 0x0000,
+ 0x0000, 0x5b59, 0x5b5a, 0x0000, 0x5b5b, 0x0000, 0x0000, 0x5b5c,
+ 0x0000, 0x0000, 0x5b5d, 0x5b5e, 0x5b5f, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5b60, 0x5b61, 0x0000, 0x5b62, 0x0000, 0x0000,
+ 0x0000, 0x5b63, 0x0000, 0x5b64, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5b65, 0x0000, 0x5b66, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b67,
+};
+
+static unsigned short const tqunicode_to_jisx0212_88[] = {
+ /* 0x8800 - 0x88ff */
+ 0x0000, 0x5b68, 0x0000, 0x5b69, 0x0000, 0x0000, 0x5b6a, 0x7464,
+ 0x0000, 0x5b6b, 0x5b6c, 0x5b6d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5b6e, 0x0000, 0x5b70, 0x5b71, 0x5b72, 0x0000, 0x0000, 0x0000,
+ 0x5b73, 0x5b6f, 0x5b74, 0x5b75, 0x5b76, 0x0000, 0x5b77, 0x5b78,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5b79, 0x0000, 0x0000, 0x0000, 0x0000, 0x5b7a, 0x5b7b, 0x0000,
+ 0x5b7c, 0x0000, 0x5b7d, 0x0000, 0x0000, 0x5b7e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5c21, 0x0000, 0x5c22, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5c23, 0x0000, 0x5c24, 0x0000, 0x5c25, 0x0000, 0x0000,
+ 0x5c26, 0x5c27, 0x5c28, 0x5c29, 0x0000, 0x0000, 0x5c2a, 0x0000,
+ 0x0000, 0x5c2b, 0x0000, 0x0000, 0x0000, 0x5c2c, 0x5c2d, 0x0000,
+ 0x5c2e, 0x0000, 0x5c2f, 0x0000, 0x5c30, 0x0000, 0x0000, 0x5c31,
+ 0x5c32, 0x0000, 0x0000, 0x0000, 0x5c33, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5c34, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5c35, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5c36, 0x0000, 0x5c37, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5c38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5c39, 0x0000, 0x5c3a, 0x5c3b, 0x5c3c, 0x0000, 0x0000, 0x5c3d,
+ 0x5c3e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5c3f, 0x0000, 0x5c40, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5c41, 0x0000, 0x0000, 0x5c42, 0x5c43, 0x0000,
+ 0x5c44, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5c45, 0x5c46, 0x5c47, 0x5c48, 0x5c49, 0x0000,
+ 0x0000, 0x5c4a, 0x5c4b, 0x5c4c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5c4d, 0x0000, 0x0000, 0x5c4e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c4f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c50,
+ 0x5c51, 0x5c52, 0x0000, 0x0000, 0x0000, 0x5c53, 0x0000, 0x5c54,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_89[] = {
+ /* 0x8900 - 0x89ff */
+ 0x0000, 0x5c55, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c56, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c57, 0x5c58, 0x5c59,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c5a, 0x5c5b, 0x0000,
+ 0x5c5c, 0x5c5d, 0x5c5e, 0x0000, 0x5c5f, 0x0000, 0x0000, 0x0000,
+ 0x5c60, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c61, 0x5c62,
+ 0x5c63, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5c64, 0x5c65, 0x5c66, 0x0000, 0x0000, 0x5c67, 0x0000, 0x0000,
+ 0x0000, 0x5c68, 0x5c69, 0x0000, 0x0000, 0x0000, 0x5c6a, 0x0000,
+ 0x5c6b, 0x0000, 0x5c6c, 0x0000, 0x0000, 0x5c6d, 0x5c6e, 0x0000,
+ 0x0000, 0x5c6f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c70,
+ 0x0000, 0x0000, 0x5c71, 0x0000, 0x0000, 0x0000, 0x0000, 0x5c72,
+ 0x0000, 0x0000, 0x5c73, 0x5c74, 0x5c75, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5c76, 0x5c77, 0x5c78, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5c79, 0x0000, 0x0000, 0x5c7a, 0x0000,
+ 0x5c7b, 0x0000, 0x0000, 0x5c7c, 0x0000, 0x5c7d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5c7e, 0x5d21, 0x5d22, 0x5d23, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5d24, 0x0000, 0x0000, 0x0000, 0x5d25, 0x0000, 0x0000,
+ 0x5d26, 0x0000, 0x0000, 0x0000, 0x5d27, 0x5d28, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5d29, 0x5d2a, 0x0000, 0x0000, 0x5d2b,
+ 0x5d2c, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d2d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5d2e, 0x0000, 0x0000, 0x0000, 0x5d2f, 0x5d30, 0x5d31, 0x5d32,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5d33, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5d34, 0x5d35, 0x5d36, 0x5d37,
+ 0x5d38, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d39, 0x0000, 0x0000,
+ 0x0000, 0x5d3a, 0x0000, 0x5d3b, 0x0000, 0x5d3c, 0x0000, 0x0000,
+ 0x0000, 0x5d3d, 0x0000, 0x5d3e, 0x0000, 0x0000, 0x5d3f, 0x0000,
+ 0x0000, 0x5d40, 0x0000, 0x0000, 0x0000, 0x5d41, 0x0000, 0x5d42,
+};
+
+static unsigned short const tqunicode_to_jisx0212_8a[] = {
+ /* 0x8a00 - 0x8aff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5d43, 0x5d44, 0x0000, 0x5d45,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d46,
+ 0x0000, 0x5d47, 0x5d48, 0x0000, 0x5d49, 0x5d4a, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d4b, 0x0000,
+ 0x5d4c, 0x0000, 0x5d4d, 0x0000, 0x5d4e, 0x0000, 0x5d4f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5d50, 0x5d51, 0x0000, 0x0000, 0x5d52,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d53, 0x0000, 0x5d54,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d55, 0x5d56, 0x0000,
+ 0x5d57, 0x0000, 0x0000, 0x5d58, 0x0000, 0x5d59, 0x0000, 0x5d5a,
+ 0x0000, 0x5d5b, 0x0000, 0x0000, 0x0000, 0x5d5c, 0x5d5d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5d5e, 0x0000, 0x0000, 0x5d5f, 0x5d60,
+ 0x5d61, 0x0000, 0x0000, 0x0000, 0x5d62, 0x5d63, 0x0000, 0x0000,
+ 0x0000, 0x5d64, 0x0000, 0x0000, 0x0000, 0x5d65, 0x0000, 0x5d66,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d67, 0x5d68, 0x5d69,
+ 0x0000, 0x5d6a, 0x5d6b, 0x5d6c, 0x0000, 0x0000, 0x5d6d, 0x5d6e,
+ 0x5d6f, 0x0000, 0x0000, 0x5d70, 0x0000, 0x0000, 0x5d71, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5d72, 0x0000, 0x0000, 0x0000, 0x5d73,
+ 0x5d74, 0x0000, 0x5d75, 0x0000, 0x0000, 0x0000, 0x5d76, 0x5d77,
+ 0x0000, 0x5d78, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d79,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d7a,
+ 0x0000, 0x5d7b, 0x0000, 0x0000, 0x0000, 0x0000, 0x5d7c, 0x5d7d,
+ 0x0000, 0x0000, 0x0000, 0x5d7e, 0x0000, 0x0000, 0x5e21, 0x5e22,
+ 0x0000, 0x0000, 0x0000, 0x5e23, 0x0000, 0x0000, 0x5e24, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5e25, 0x0000, 0x0000, 0x5e26, 0x0000,
+ 0x5e27, 0x5e28, 0x5e29, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5e2a, 0x0000, 0x5e2b, 0x5e2c, 0x5e2d, 0x0000, 0x5e2e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e2f, 0x0000, 0x5e30,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5e31, 0x0000, 0x0000, 0x0000,
+ 0x5e32, 0x0000, 0x0000, 0x0000, 0x5e33, 0x5e34, 0x5e35, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5e36, 0x0000, 0x0000, 0x5e37,
+};
+
+static unsigned short const tqunicode_to_jisx0212_8b[] = {
+ /* 0x8b00 - 0x8bff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e38, 0x5e39, 0x0000,
+ 0x0000, 0x0000, 0x5e3f, 0x5e3a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5e3b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5e3c, 0x0000, 0x5e3d, 0x5e3e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e40, 0x0000, 0x0000,
+ 0x5e41, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e42,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5e43, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5e44, 0x5e45, 0x5e46, 0x5e47, 0x5e48, 0x0000,
+ 0x5e49, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e4e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5e4a, 0x5e4b, 0x5e4c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5e4d, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e4f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5e50, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e51, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e52, 0x0000,
+ 0x5e53, 0x5e54, 0x0000, 0x0000, 0x5e55, 0x0000, 0x5e56, 0x7466,
+ 0x0000, 0x5e57, 0x0000, 0x0000, 0x5e58, 0x5e59, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5e5a, 0x0000, 0x5e5b, 0x0000, 0x5e5c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5e5d, 0x5e5e, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5e5f, 0x0000, 0x5e60, 0x5e61,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_8c[] = {
+ /* 0x8c00 - 0x8cff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5e62, 0x5e63, 0x0000, 0x0000, 0x0000, 0x5e64, 0x5e65, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e66, 0x0000, 0x5e67,
+ 0x0000, 0x5e68, 0x0000, 0x5e69, 0x0000, 0x0000, 0x0000, 0x5e6a,
+ 0x0000, 0x5e6b, 0x0000, 0x5e6c, 0x5e6d, 0x0000, 0x0000, 0x5e6e,
+ 0x5e6f, 0x5e72, 0x0000, 0x5e70, 0x0000, 0x5e71, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5e73, 0x5e74, 0x0000, 0x5e75, 0x0000,
+ 0x5e76, 0x5e77, 0x0000, 0x0000, 0x0000, 0x5e78, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5e79, 0x0000, 0x5e7a, 0x5e7b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5e7c, 0x0000, 0x0000, 0x5e7d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5e7e, 0x5f21,
+ 0x0000, 0x0000, 0x0000, 0x5f22, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5f23, 0x0000, 0x5f24, 0x5f25, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f26, 0x0000, 0x5f27, 0x5f28, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5f29, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f2a, 0x5f2b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f2c, 0x5f2d, 0x0000,
+ 0x0000, 0x5f2e, 0x0000, 0x5f2f, 0x0000, 0x0000, 0x0000, 0x5f30,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f32, 0x5f31, 0x0000,
+ 0x0000, 0x5f33, 0x0000, 0x0000, 0x0000, 0x5f34, 0x0000, 0x0000,
+ 0x0000, 0x5f35, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5f36, 0x0000, 0x0000, 0x0000, 0x5f37, 0x0000, 0x0000, 0x5f38,
+ 0x5f39, 0x0000, 0x5f3a, 0x0000, 0x7467, 0x5f3b, 0x0000, 0x5f3c,
+ 0x5f3d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f3e, 0x5f3f,
+};
+
+static unsigned short const tqunicode_to_jisx0212_8d[] = {
+ /* 0x8d00 - 0x8dff */
+ 0x0000, 0x5f40, 0x0000, 0x5f41, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f42, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x5f43, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f44,
+ 0x0000, 0x0000, 0x0000, 0x5f45, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f46, 0x0000, 0x0000,
+ 0x0000, 0x5f47, 0x0000, 0x0000, 0x5f48, 0x0000, 0x5f49, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7468, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f4a,
+ 0x0000, 0x0000, 0x5f4b, 0x0000, 0x5f4c, 0x0000, 0x0000, 0x0000,
+ 0x5f4d, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f4e, 0x0000, 0x0000,
+ 0x5f4f, 0x5f50, 0x0000, 0x0000, 0x0000, 0x5f51, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f52, 0x5f53,
+ 0x5f54, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f55, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5f56, 0x5f57, 0x0000, 0x0000, 0x5f58,
+ 0x0000, 0x0000, 0x5f59, 0x0000, 0x0000, 0x5f5a, 0x0000, 0x5f5b,
+ 0x0000, 0x5f5c, 0x0000, 0x5f5d, 0x5f6f, 0x0000, 0x0000, 0x0000,
+ 0x5f5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f5f, 0x5f60, 0x5f61,
+ 0x5f62, 0x0000, 0x5f63, 0x0000, 0x0000, 0x0000, 0x5f64, 0x0000,
+ 0x0000, 0x5f65, 0x0000, 0x0000, 0x5f66, 0x5f67, 0x0000, 0x5f68,
+ 0x0000, 0x5f69, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5f6a, 0x5f6b, 0x0000, 0x5f6c,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x5f6d, 0x0000, 0x0000, 0x0000,
+ 0x5f6e, 0x5f70, 0x5f71, 0x0000, 0x5f72, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5f73, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_8e[] = {
+ /* 0x8e00 - 0x8eff */
+ 0x0000, 0x5f74, 0x0000, 0x0000, 0x5f75, 0x5f76, 0x5f77, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x5f78, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x5f79, 0x0000, 0x0000, 0x5f7a, 0x0000, 0x5f7b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x5f7c, 0x5f7d, 0x5f7e, 0x6021, 0x0000, 0x0000, 0x6022, 0x6023,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6024, 0x0000, 0x6025, 0x0000, 0x0000, 0x6026, 0x6027,
+ 0x6028, 0x6029, 0x0000, 0x0000, 0x0000, 0x602a, 0x0000, 0x0000,
+ 0x602b, 0x602c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x602d, 0x0000, 0x602e, 0x602f, 0x6030,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6031, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6032, 0x6033, 0x6034, 0x6035, 0x0000,
+ 0x0000, 0x6036, 0x6037, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6038, 0x0000, 0x0000, 0x6039, 0x603a, 0x0000, 0x603b,
+ 0x603c, 0x603d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x603e, 0x603f, 0x6040, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6041, 0x6042, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6043, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6044, 0x0000, 0x6045, 0x0000, 0x0000, 0x6046, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6047, 0x6048, 0x0000, 0x6049, 0x604a, 0x0000,
+ 0x0000, 0x0000, 0x604b, 0x0000, 0x0000, 0x0000, 0x0000, 0x604c,
+ 0x0000, 0x604d, 0x0000, 0x0000, 0x0000, 0x604e, 0x604f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6050, 0x0000, 0x6051, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6052, 0x6053, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6054, 0x6055, 0x0000, 0x6056, 0x6057, 0x0000, 0x0000, 0x6058,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6059,
+ 0x0000, 0x605a, 0x0000, 0x0000, 0x605b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x605c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x605d, 0x0000, 0x0000, 0x0000, 0x0000, 0x6064, 0x605e, 0x0000,
+ 0x605f, 0x6060, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6061,
+ 0x0000, 0x6062, 0x6063, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_8f[] = {
+ /* 0x8f00 - 0x8fff */
+ 0x6065, 0x0000, 0x6066, 0x0000, 0x0000, 0x0000, 0x0000, 0x6067,
+ 0x6068, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6069,
+ 0x606a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x606b, 0x606c,
+ 0x606d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x606e, 0x0000,
+ 0x606f, 0x6070, 0x0000, 0x6071, 0x0000, 0x6072, 0x0000, 0x6073,
+ 0x6074, 0x0000, 0x0000, 0x0000, 0x6075, 0x6076, 0x6077, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6078, 0x6079, 0x607a, 0x607b,
+ 0x0000, 0x0000, 0x607c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x607d, 0x607e, 0x0000, 0x6121, 0x0000, 0x0000, 0x0000, 0x6122,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6123,
+ 0x0000, 0x6124, 0x6125, 0x6126, 0x6127, 0x6128, 0x0000, 0x0000,
+ 0x6129, 0x0000, 0x0000, 0x0000, 0x0000, 0x612a, 0x612b, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x612c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x612d, 0x0000, 0x0000,
+ 0x612e, 0x612f, 0x0000, 0x0000, 0x6130, 0x6131, 0x6132, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6133, 0x6134, 0x0000,
+ 0x6135, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6136, 0x0000,
+ 0x6137, 0x6138, 0x0000, 0x0000, 0x0000, 0x0000, 0x6139, 0x0000,
+ 0x0000, 0x0000, 0x613a, 0x613b, 0x0000, 0x613c, 0x0000, 0x0000,
+ 0x613d, 0x0000, 0x613e, 0x613f, 0x0000, 0x6140, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6141, 0x0000, 0x0000, 0x6142, 0x6143, 0x0000, 0x0000, 0x0000,
+ 0x6144, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6145, 0x0000,
+ 0x0000, 0x6146, 0x0000, 0x0000, 0x0000, 0x6147, 0x6148, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6149, 0x0000, 0x0000, 0x614a, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_90[] = {
+ /* 0x9000 - 0x90ff */
+ 0x0000, 0x0000, 0x614b, 0x0000, 0x614c, 0x0000, 0x0000, 0x0000,
+ 0x614d, 0x0000, 0x0000, 0x0000, 0x614e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x614f, 0x0000, 0x0000, 0x6150, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6151, 0x6152, 0x6154, 0x0000, 0x6155, 0x6156, 0x0000, 0x6153,
+ 0x0000, 0x0000, 0x0000, 0x6157, 0x6158, 0x0000, 0x0000, 0x6159,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x615a,
+ 0x0000, 0x0000, 0x0000, 0x615b, 0x615c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x615d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x615e, 0x0000, 0x615f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6160, 0x0000, 0x0000, 0x0000, 0x6161, 0x6162,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6163, 0x0000, 0x0000, 0x0000,
+ 0x6164, 0x0000, 0x0000, 0x0000, 0x6165, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6166, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6167, 0x0000, 0x0000,
+ 0x6168, 0x0000, 0x0000, 0x6169, 0x616a, 0x0000, 0x616b, 0x0000,
+ 0x616c, 0x0000, 0x0000, 0x0000, 0x0000, 0x616d, 0x0000, 0x616e,
+ 0x616f, 0x6170, 0x0000, 0x6171, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6172, 0x6173, 0x6174, 0x0000, 0x0000, 0x6175, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6176, 0x0000, 0x6177, 0x6178, 0x6179, 0x0000, 0x617a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x617b, 0x617d, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x617e, 0x6221, 0x6222, 0x0000, 0x6223,
+ 0x6224, 0x0000, 0x0000, 0x0000, 0x617c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x622d, 0x0000, 0x0000, 0x6225, 0x0000, 0x6226,
+ 0x6227, 0x6228, 0x0000, 0x0000, 0x6229, 0x622a, 0x746c, 0x622b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x622c, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x622f, 0x0000, 0x0000, 0x0000, 0x6230,
+ 0x6231, 0x0000, 0x0000, 0x0000, 0x6232, 0x0000, 0x622e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6233, 0x6234,
+};
+
+static unsigned short const tqunicode_to_jisx0212_91[] = {
+ /* 0x9100 - 0x91ff */
+ 0x6235, 0x0000, 0x0000, 0x0000, 0x6236, 0x6237, 0x6238, 0x0000,
+ 0x6239, 0x0000, 0x0000, 0x0000, 0x0000, 0x623a, 0x0000, 0x0000,
+ 0x623b, 0x0000, 0x0000, 0x0000, 0x623c, 0x746e, 0x623d, 0x623e,
+ 0x623f, 0x0000, 0x6240, 0x0000, 0x6241, 0x0000, 0x6242, 0x0000,
+ 0x6243, 0x0000, 0x6245, 0x6246, 0x0000, 0x6244, 0x0000, 0x6247,
+ 0x0000, 0x6248, 0x0000, 0x0000, 0x0000, 0x0000, 0x6249, 0x624a,
+ 0x0000, 0x624b, 0x0000, 0x0000, 0x624c, 0x0000, 0x624d, 0x624e,
+ 0x0000, 0x624f, 0x6250, 0x0000, 0x6251, 0x6252, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6253, 0x0000, 0x0000, 0x0000, 0x6254,
+ 0x6255, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6256,
+ 0x0000, 0x0000, 0x0000, 0x6257, 0x0000, 0x0000, 0x0000, 0x6258,
+ 0x0000, 0x6259, 0x625a, 0x625b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x625c, 0x0000, 0x0000, 0x625d, 0x0000, 0x0000, 0x625e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x625f, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6260, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6261, 0x6262, 0x6263, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6264, 0x0000, 0x6265, 0x0000, 0x6266, 0x6267, 0x0000,
+ 0x0000, 0x0000, 0x6268, 0x0000, 0x0000, 0x0000, 0x6269, 0x0000,
+ 0x0000, 0x626a, 0x0000, 0x626b, 0x626c, 0x626d, 0x0000, 0x0000,
+ 0x626e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x626f, 0x0000,
+ 0x0000, 0x6270, 0x0000, 0x0000, 0x0000, 0x0000, 0x6271, 0x0000,
+ 0x6272, 0x0000, 0x0000, 0x0000, 0x6273, 0x6274, 0x6275, 0x0000,
+ 0x6276, 0x6277, 0x6278, 0x6279, 0x0000, 0x0000, 0x627a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x627b, 0x627c, 0x627d, 0x0000, 0x627e,
+ 0x0000, 0x0000, 0x6321, 0x6322, 0x0000, 0x6323, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6324, 0x6325, 0x0000, 0x0000, 0x6326,
+ 0x0000, 0x6327, 0x6328, 0x0000, 0x0000, 0x0000, 0x6329, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x632a, 0x632b, 0x0000, 0x0000,
+ 0x0000, 0x632c, 0x632d, 0x0000, 0x632e, 0x632f, 0x6330, 0x6331,
+ 0x6332, 0x6333, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6334,
+ 0x0000, 0x6335, 0x0000, 0x6336, 0x0000, 0x6337, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_92[] = {
+ /* 0x9200 - 0x92ff */
+ 0x6338, 0x6339, 0x0000, 0x0000, 0x633a, 0x633b, 0x633c, 0x633d,
+ 0x0000, 0x633e, 0x633f, 0x0000, 0x6340, 0x0000, 0x0000, 0x0000,
+ 0x6341, 0x0000, 0x6342, 0x6343, 0x0000, 0x0000, 0x6344, 0x0000,
+ 0x6345, 0x0000, 0x0000, 0x0000, 0x6346, 0x6347, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6348, 0x6349, 0x634a, 0x634b, 0x0000,
+ 0x634c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x634d, 0x634e,
+ 0x634f, 0x0000, 0x0000, 0x6350, 0x0000, 0x6351, 0x6352, 0x0000,
+ 0x6353, 0x6354, 0x6355, 0x0000, 0x6356, 0x0000, 0x6357, 0x0000,
+ 0x6358, 0x0000, 0x6359, 0x635a, 0x0000, 0x0000, 0x635b, 0x635c,
+ 0x0000, 0x0000, 0x635d, 0x0000, 0x0000, 0x635e, 0x635f, 0x6360,
+ 0x0000, 0x6361, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6362, 0x6363, 0x0000, 0x0000, 0x6364, 0x6365, 0x0000, 0x0000,
+ 0x6366, 0x6367, 0x0000, 0x0000, 0x0000, 0x6368, 0x0000, 0x6369,
+ 0x636a, 0x636b, 0x0000, 0x0000, 0x0000, 0x0000, 0x636c, 0x636d,
+ 0x636e, 0x0000, 0x0000, 0x0000, 0x0000, 0x636f, 0x6370, 0x6371,
+ 0x6372, 0x6373, 0x0000, 0x6374, 0x6375, 0x6376, 0x0000, 0x6377,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6378, 0x6379, 0x637a, 0x0000, 0x0000, 0x637b, 0x637c, 0x0000,
+ 0x0000, 0x0000, 0x637d, 0x0000, 0x0000, 0x0000, 0x0000, 0x637e,
+ 0x0000, 0x6421, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6422,
+ 0x6423, 0x0000, 0x0000, 0x0000, 0x6424, 0x6425, 0x0000, 0x6426,
+ 0x6427, 0x0000, 0x0000, 0x6428, 0x0000, 0x0000, 0x0000, 0x6429,
+ 0x0000, 0x0000, 0x642a, 0x0000, 0x0000, 0x0000, 0x642b, 0x0000,
+ 0x642c, 0x0000, 0x642d, 0x642e, 0x642f, 0x6430, 0x0000, 0x6431,
+ 0x6432, 0x6433, 0x6434, 0x6435, 0x0000, 0x6436, 0x6437, 0x6438,
+ 0x6439, 0x0000, 0x0000, 0x643a, 0x643b, 0x643c, 0x643d, 0x0000,
+ 0x643e, 0x0000, 0x0000, 0x643f, 0x0000, 0x6440, 0x0000, 0x6441,
+ 0x6442, 0x6443, 0x0000, 0x0000, 0x6444, 0x6445, 0x0000, 0x6446,
+ 0x6447, 0x6448, 0x0000, 0x6449, 0x0000, 0x644a, 0x0000, 0x644b,
+ 0x644c, 0x0000, 0x0000, 0x0000, 0x644d, 0x0000, 0x644e, 0x0000,
+ 0x644f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6450, 0x0000, 0x6451, 0x0000, 0x0000, 0x0000, 0x6452,
+};
+
+static unsigned short const tqunicode_to_jisx0212_93[] = {
+ /* 0x9300 - 0x93ff */
+ 0x6453, 0x0000, 0x6454, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6455, 0x0000, 0x0000, 0x0000, 0x0000, 0x6456, 0x0000, 0x0000,
+ 0x0000, 0x6457, 0x0000, 0x0000, 0x6458, 0x6459, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x645a, 0x645b, 0x645c, 0x645d,
+ 0x0000, 0x645e, 0x0000, 0x0000, 0x645f, 0x6460, 0x0000, 0x6461,
+ 0x0000, 0x6462, 0x6463, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6464, 0x6465, 0x0000, 0x6466, 0x6467,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6468,
+ 0x6469, 0x646a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x646b, 0x646c, 0x646d, 0x0000, 0x0000, 0x646e, 0x0000, 0x646f,
+ 0x6470, 0x0000, 0x6471, 0x0000, 0x0000, 0x0000, 0x6472, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6473, 0x6474, 0x0000, 0x6475,
+ 0x0000, 0x6476, 0x6477, 0x0000, 0x0000, 0x6478, 0x0000, 0x6479,
+ 0x647a, 0x647b, 0x0000, 0x647c, 0x647d, 0x0000, 0x647e, 0x0000,
+ 0x0000, 0x0000, 0x6521, 0x0000, 0x0000, 0x6522, 0x0000, 0x6523,
+ 0x6524, 0x6525, 0x6526, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6527, 0x0000, 0x6528, 0x6529, 0x0000, 0x652a, 0x0000, 0x652b,
+ 0x0000, 0x0000, 0x652c, 0x0000, 0x0000, 0x652d, 0x0000, 0x0000,
+ 0x652e, 0x0000, 0x0000, 0x652f, 0x0000, 0x0000, 0x6530, 0x0000,
+ 0x0000, 0x6531, 0x0000, 0x6532, 0x6533, 0x0000, 0x6534, 0x0000,
+ 0x6535, 0x653b, 0x0000, 0x6536, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6537, 0x6538, 0x6539, 0x0000,
+ 0x0000, 0x0000, 0x653a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x653c, 0x0000, 0x0000, 0x653d, 0x653e, 0x653f, 0x6540,
+ 0x0000, 0x6541, 0x6542, 0x6543, 0x6544, 0x6545, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6546, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6547, 0x0000, 0x0000, 0x6548, 0x0000, 0x6549, 0x654a,
+ 0x0000, 0x0000, 0x654b, 0x0000, 0x0000, 0x0000, 0x654c, 0x654d,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x654f,
+ 0x6550, 0x654e, 0x6551, 0x6552, 0x0000, 0x6553, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_94[] = {
+ /* 0x9400 - 0x94ff */
+ 0x0000, 0x6554, 0x6555, 0x0000, 0x6556, 0x0000, 0x0000, 0x0000,
+ 0x6557, 0x6558, 0x0000, 0x0000, 0x0000, 0x6559, 0x655a, 0x655b,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x655c, 0x655d, 0x655e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x655f,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6560, 0x6561,
+ 0x0000, 0x6562, 0x6563, 0x6564, 0x6565, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6566, 0x0000, 0x6568, 0x0000, 0x6567,
+ 0x0000, 0x0000, 0x0000, 0x6569, 0x0000, 0x656a, 0x0000, 0x0000,
+ 0x656b, 0x0000, 0x656c, 0x0000, 0x656d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x656e, 0x0000, 0x0000,
+ 0x0000, 0x656f, 0x0000, 0x0000, 0x6570, 0x0000, 0x0000, 0x6571,
+ 0x0000, 0x6572, 0x0000, 0x6573, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6574, 0x0000, 0x0000, 0x6575, 0x0000, 0x6576, 0x6577, 0x6578,
+ 0x0000, 0x6579, 0x657a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x657c, 0x657b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_95[] = {
+ /* 0x9500 - 0x95ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x657d, 0x657e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6621, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6622, 0x0000, 0x0000, 0x0000,
+ 0x6623, 0x0000, 0x0000, 0x0000, 0x6624, 0x6625, 0x6626, 0x0000,
+ 0x0000, 0x0000, 0x7471, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6627, 0x6628, 0x6629,
+ 0x0000, 0x662a, 0x0000, 0x0000, 0x0000, 0x0000, 0x662b, 0x0000,
+ 0x0000, 0x662c, 0x0000, 0x662d, 0x662e, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x662f, 0x0000, 0x6630, 0x0000,
+ 0x0000, 0x0000, 0x6631, 0x0000, 0x0000, 0x6632, 0x0000, 0x6633,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6634, 0x0000,
+ 0x6635, 0x6636, 0x0000, 0x6637, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6638, 0x6639, 0x663a, 0x663b, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x663c, 0x663d, 0x0000, 0x0000, 0x663e, 0x663f, 0x6640,
+ 0x6641, 0x0000, 0x0000, 0x0000, 0x6642, 0x0000, 0x6643, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_96[] = {
+ /* 0x9600 - 0x96ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6644, 0x6645, 0x0000,
+ 0x0000, 0x0000, 0x6646, 0x0000, 0x6647, 0x6648, 0x6649, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x664a, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x664b, 0x0000, 0x664c, 0x0000, 0x0000, 0x0000, 0x664d,
+ 0x664e, 0x664f, 0x6650, 0x0000, 0x6651, 0x6652, 0x0000, 0x0000,
+ 0x0000, 0x6653, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6654, 0x0000, 0x6655, 0x0000, 0x6656, 0x6657,
+ 0x6658, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6659, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x665a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x665b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x665c, 0x665d, 0x0000, 0x665e, 0x665f,
+ 0x0000, 0x6660, 0x6661, 0x6662, 0x6663, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6664, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6665, 0x0000, 0x0000, 0x0000, 0x0000, 0x6666, 0x0000,
+ 0x0000, 0x0000, 0x6667, 0x0000, 0x0000, 0x6668, 0x0000, 0x6669,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x666a, 0x666b, 0x666c, 0x0000,
+ 0x0000, 0x666d, 0x0000, 0x0000, 0x0000, 0x0000, 0x666e, 0x666f,
+ 0x0000, 0x0000, 0x0000, 0x6670, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6671, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6672, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6673, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6675, 0x0000, 0x6676, 0x0000, 0x0000, 0x6677, 0x6678, 0x6679,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x667a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x667b,
+ 0x0000, 0x667c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x667d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_97[] = {
+ /* 0x9700 - 0x97ff */
+ 0x0000, 0x0000, 0x667e, 0x6721, 0x0000, 0x6722, 0x0000, 0x0000,
+ 0x0000, 0x6723, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6724, 0x6725, 0x0000, 0x6726, 0x0000, 0x0000,
+ 0x0000, 0x6727, 0x6728, 0x6729, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x672a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x672b, 0x0000, 0x672c, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x7474, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x672d, 0x0000, 0x672e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x672f, 0x0000, 0x0000, 0x7475, 0x6730, 0x6731,
+ 0x0000, 0x7476, 0x0000, 0x0000, 0x0000, 0x6732, 0x0000, 0x6733,
+ 0x6734, 0x0000, 0x6735, 0x6736, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6737, 0x0000, 0x0000, 0x0000, 0x6738,
+ 0x0000, 0x0000, 0x6739, 0x0000, 0x0000, 0x0000, 0x673a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x673b, 0x0000, 0x0000, 0x673c, 0x673d,
+ 0x673e, 0x0000, 0x0000, 0x673f, 0x0000, 0x6740, 0x0000, 0x6741,
+ 0x6742, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6743, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6744, 0x6745, 0x6746,
+ 0x0000, 0x6747, 0x6748, 0x0000, 0x0000, 0x0000, 0x6749, 0x674a,
+ 0x0000, 0x0000, 0x674b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x674c, 0x0000, 0x674d, 0x0000,
+ 0x0000, 0x674e, 0x674f, 0x0000, 0x0000, 0x6750, 0x6751, 0x0000,
+ 0x6752, 0x6753, 0x6754, 0x0000, 0x6755, 0x0000, 0x6756, 0x6757,
+ 0x0000, 0x6758, 0x0000, 0x0000, 0x6759, 0x675a, 0x0000, 0x675b,
+ 0x0000, 0x675c, 0x675d, 0x0000, 0x675e, 0x675f, 0x6760, 0x0000,
+ 0x6761, 0x6762, 0x0000, 0x0000, 0x6763, 0x0000, 0x0000, 0x6764,
+ 0x6765, 0x6766, 0x0000, 0x676a, 0x0000, 0x6767, 0x6768, 0x0000,
+ 0x6769, 0x676b, 0x0000, 0x0000, 0x676c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x676d,
+ 0x0000, 0x676e, 0x0000, 0x0000, 0x676f, 0x0000, 0x0000, 0x6770,
+ 0x6771, 0x0000, 0x6772, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_98[] = {
+ /* 0x9800 - 0x98ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6773,
+ 0x0000, 0x0000, 0x6774, 0x0000, 0x0000, 0x6776, 0x6777, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6778, 0x0000, 0x6779, 0x0000,
+ 0x0000, 0x6775, 0x0000, 0x0000, 0x677a, 0x0000, 0x677b, 0x0000,
+ 0x677c, 0x0000, 0x0000, 0x677d, 0x0000, 0x6828, 0x677e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6821, 0x0000, 0x0000, 0x6822, 0x6823,
+ 0x6824, 0x0000, 0x6825, 0x6826, 0x0000, 0x6827, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6829, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x682a, 0x0000, 0x0000, 0x682b,
+ 0x0000, 0x0000, 0x682c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x682d, 0x682e, 0x682f, 0x0000, 0x0000, 0x6830, 0x6831,
+ 0x0000, 0x6832, 0x6833, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6834, 0x6835, 0x0000, 0x6836, 0x6837, 0x0000,
+ 0x0000, 0x0000, 0x6838, 0x0000, 0x6839, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x683a, 0x0000, 0x683b, 0x683c, 0x0000,
+ 0x683d, 0x0000, 0x0000, 0x0000, 0x683e, 0x0000, 0x0000, 0x683f,
+ 0x6840, 0x0000, 0x6841, 0x6842, 0x0000, 0x0000, 0x0000, 0x6843,
+ 0x0000, 0x0000, 0x6844, 0x0000, 0x0000, 0x6845, 0x0000, 0x0000,
+ 0x6846, 0x0000, 0x0000, 0x0000, 0x6847, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6848, 0x0000, 0x6849, 0x0000, 0x684a, 0x684b, 0x684c,
+ 0x0000, 0x0000, 0x684d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x684e, 0x0000, 0x0000, 0x684f, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_99[] = {
+ /* 0x9900 - 0x99ff */
+ 0x0000, 0x0000, 0x6850, 0x0000, 0x0000, 0x0000, 0x0000, 0x6851,
+ 0x6852, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6853, 0x0000, 0x0000, 0x0000, 0x6854, 0x6855, 0x6856,
+ 0x0000, 0x0000, 0x6857, 0x6858, 0x6859, 0x0000, 0x0000, 0x685a,
+ 0x0000, 0x0000, 0x685b, 0x0000, 0x0000, 0x0000, 0x685c, 0x685d,
+ 0x0000, 0x0000, 0x0000, 0x685e, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x685f, 0x6860, 0x6861, 0x6862, 0x6863, 0x0000, 0x0000,
+ 0x0000, 0x6864, 0x6865, 0x6866, 0x6867, 0x0000, 0x0000, 0x0000,
+ 0x6868, 0x6869, 0x0000, 0x0000, 0x0000, 0x0000, 0x686a, 0x686b,
+ 0x686c, 0x0000, 0x0000, 0x0000, 0x0000, 0x686d, 0x686e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x686f, 0x0000, 0x0000, 0x0000,
+ 0x6870, 0x6871, 0x0000, 0x6872, 0x6873, 0x0000, 0x6874, 0x6875,
+ 0x6876, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6877, 0x0000, 0x6878, 0x747a, 0x6879,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x687a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x687b, 0x687c, 0x687d, 0x0000, 0x0000, 0x687e, 0x0000, 0x0000,
+ 0x0000, 0x6921, 0x6922, 0x0000, 0x0000, 0x6923, 0x0000, 0x6924,
+ 0x0000, 0x0000, 0x0000, 0x6925, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6926, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6927, 0x6928, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6929, 0x692a, 0x0000, 0x692b, 0x0000, 0x692c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x692d,
+ 0x0000, 0x0000, 0x692e, 0x692f, 0x6930, 0x0000, 0x0000, 0x0000,
+ 0x6931, 0x0000, 0x0000, 0x0000, 0x6932, 0x6933, 0x0000, 0x0000,
+ 0x0000, 0x6934, 0x0000, 0x0000, 0x0000, 0x6935, 0x6936, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_9a[] = {
+ /* 0x9a00 - 0x9aff */
+ 0x0000, 0x0000, 0x6937, 0x6938, 0x6939, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x693a, 0x693b, 0x0000, 0x0000, 0x0000,
+ 0x693c, 0x693d, 0x0000, 0x0000, 0x0000, 0x0000, 0x693e, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x693f, 0x0000,
+ 0x6940, 0x0000, 0x6941, 0x6942, 0x6943, 0x0000, 0x0000, 0x6944,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6945, 0x6946, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6947, 0x0000, 0x6948, 0x6949, 0x0000,
+ 0x694a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x694c, 0x0000, 0x0000, 0x694d, 0x0000, 0x0000, 0x694b,
+ 0x0000, 0x0000, 0x694e, 0x694f, 0x6950, 0x0000, 0x6951, 0x0000,
+ 0x0000, 0x6952, 0x0000, 0x0000, 0x6953, 0x0000, 0x6954, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6955, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6956, 0x0000, 0x6957, 0x0000, 0x6958, 0x6959,
+ 0x0000, 0x0000, 0x695a, 0x0000, 0x695b, 0x695c, 0x695d, 0x0000,
+ 0x0000, 0x695e, 0x0000, 0x695f, 0x0000, 0x0000, 0x6960, 0x6961,
+ 0x0000, 0x6962, 0x0000, 0x6963, 0x0000, 0x0000, 0x6964, 0x0000,
+ 0x6965, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6966, 0x0000,
+ 0x6967, 0x0000, 0x6968, 0x0000, 0x0000, 0x6969, 0x696a, 0x696b,
+ 0x0000, 0x747b, 0x0000, 0x696c, 0x696d, 0x0000, 0x0000, 0x0000,
+ 0x696e, 0x0000, 0x0000, 0x0000, 0x696f, 0x6970, 0x0000, 0x6971,
+ 0x0000, 0x6972, 0x0000, 0x0000, 0x6973, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6974, 0x6975, 0x0000, 0x6976, 0x0000, 0x0000,
+ 0x0000, 0x6977, 0x6978, 0x0000, 0x0000, 0x6979, 0x0000, 0x697a,
+};
+
+static unsigned short const tqunicode_to_jisx0212_9b[] = {
+ /* 0x9b00 - 0x9bff */
+ 0x697b, 0x697c, 0x697d, 0x697e, 0x6a21, 0x6a22, 0x0000, 0x0000,
+ 0x6a23, 0x6a24, 0x0000, 0x6a25, 0x6a26, 0x6a27, 0x6a28, 0x0000,
+ 0x6a29, 0x0000, 0x6a2a, 0x0000, 0x0000, 0x0000, 0x6a2b, 0x0000,
+ 0x0000, 0x6a2c, 0x0000, 0x6a2d, 0x6a2e, 0x0000, 0x0000, 0x0000,
+ 0x6a2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a30, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6a31, 0x0000, 0x6a32, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6a33, 0x6a34, 0x6a35, 0x0000, 0x6a36,
+ 0x0000, 0x6a37, 0x6a38, 0x0000, 0x0000, 0x6a39, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6a3a, 0x0000, 0x0000, 0x6a3b, 0x6a3c, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a3d, 0x6a3e, 0x6a3f,
+ 0x0000, 0x0000, 0x0000, 0x6a40, 0x0000, 0x0000, 0x6a41, 0x0000,
+ 0x0000, 0x6a42, 0x0000, 0x6a43, 0x0000, 0x6a44, 0x6a45, 0x0000,
+ 0x6a46, 0x0000, 0x6a47, 0x6a48, 0x6a49, 0x6a4a, 0x6a4b, 0x0000,
+ 0x0000, 0x0000, 0x747c, 0x6a4c, 0x0000, 0x6a4d, 0x0000, 0x6a4e,
+ 0x6a4f, 0x6a50, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a51,
+ 0x6a52, 0x0000, 0x0000, 0x0000, 0x6a53, 0x6a54, 0x6a55, 0x6a56,
+ 0x0000, 0x6a57, 0x6a58, 0x6a59, 0x0000, 0x6a5a, 0x0000, 0x6a5b,
+ 0x6a5c, 0x0000, 0x0000, 0x0000, 0x6a5d, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6a5e, 0x0000, 0x0000, 0x6a5f, 0x6a60, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a61, 0x6a62,
+ 0x0000, 0x6a63, 0x0000, 0x0000, 0x6a64, 0x0000, 0x0000, 0x0000,
+ 0x6a65, 0x6a66, 0x6a67, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a68,
+ 0x6a69, 0x0000, 0x0000, 0x6a6a, 0x6a6b, 0x0000, 0x6a6c, 0x6a6d,
+ 0x0000, 0x6a6e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a6f,
+ 0x6a70, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a71, 0x0000,
+ 0x6a72, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a73,
+ 0x6a74, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a75, 0x0000, 0x6a76,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6a77, 0x0000, 0x6a78,
+ 0x0000, 0x0000, 0x6a79, 0x6a7a, 0x0000, 0x0000, 0x0000, 0x6a7b,
+ 0x0000, 0x0000, 0x0000, 0x6a7c, 0x0000, 0x0000, 0x0000, 0x6a7d,
+ 0x6a7e, 0x6b21, 0x6b22, 0x0000, 0x0000, 0x6b23, 0x0000, 0x6b24,
+};
+
+static unsigned short const tqunicode_to_jisx0212_9c[] = {
+ /* 0x9c00 - 0x9cff */
+ 0x6b25, 0x0000, 0x6b26, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6b27, 0x0000, 0x0000, 0x0000, 0x6b28,
+ 0x0000, 0x6b29, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b2a, 0x0000,
+ 0x6b2b, 0x6b2c, 0x6b2d, 0x0000, 0x6b2e, 0x0000, 0x6b2f, 0x0000,
+ 0x0000, 0x0000, 0x6b30, 0x6b31, 0x0000, 0x0000, 0x6b32, 0x6b33,
+ 0x6b34, 0x6b35, 0x6b36, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6b37, 0x0000, 0x0000, 0x0000, 0x6b38, 0x6b39, 0x6b3a,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b3b, 0x0000, 0x0000,
+ 0x0000, 0x6b3c, 0x0000, 0x6b3d, 0x6b3e, 0x6b3f, 0x0000, 0x0000,
+ 0x0000, 0x6b40, 0x6b41, 0x0000, 0x0000, 0x0000, 0x6b42, 0x6b43,
+ 0x6b44, 0x0000, 0x0000, 0x6b45, 0x6b46, 0x0000, 0x6b47, 0x0000,
+ 0x6b48, 0x0000, 0x0000, 0x6b49, 0x6b50, 0x6b4a, 0x6b4b, 0x6b4c,
+ 0x0000, 0x0000, 0x0000, 0x6b4d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6b52, 0x6b4e, 0x6b4f, 0x6b51, 0x0000, 0x0000, 0x6b53, 0x0000,
+ 0x6b54, 0x0000, 0x6b55, 0x0000, 0x0000, 0x6b56, 0x0000, 0x6b57,
+ 0x0000, 0x0000, 0x0000, 0x6b58, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b59, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6b5a, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b5b,
+ 0x0000, 0x6b5c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_9d[] = {
+ /* 0x9d00 - 0x9dff */
+ 0x0000, 0x0000, 0x6b5e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6b5d, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6b5f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b60,
+ 0x6b61, 0x0000, 0x0000, 0x0000, 0x6b62, 0x6b63, 0x6b64, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b65,
+ 0x6b66, 0x0000, 0x6b67, 0x6b68, 0x6b69, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6b6a, 0x0000, 0x6b6b, 0x6b6d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6b6e, 0x6b6f, 0x0000, 0x6b6c, 0x0000, 0x6b70,
+ 0x0000, 0x0000, 0x6b71, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6b72, 0x6b73, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b74,
+ 0x0000, 0x0000, 0x6b76, 0x6b75, 0x0000, 0x6b77, 0x0000, 0x0000,
+ 0x0000, 0x6b78, 0x6b79, 0x6b7a, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6b7b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6b7c, 0x6b7d,
+ 0x0000, 0x0000, 0x0000, 0x6b7e, 0x6c21, 0x0000, 0x6c22, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6c23, 0x6c24, 0x0000, 0x6c25, 0x0000,
+ 0x0000, 0x0000, 0x6c26, 0x0000, 0x0000, 0x6c27, 0x6c28, 0x0000,
+ 0x0000, 0x0000, 0x6c29, 0x6c2a, 0x0000, 0x6c2b, 0x6c2c, 0x6c2d,
+ 0x6c2e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6c2f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6c30, 0x0000, 0x6c31, 0x0000, 0x6c32, 0x0000,
+ 0x0000, 0x6c33, 0x0000, 0x0000, 0x0000, 0x6c34, 0x0000, 0x0000,
+ 0x0000, 0x6c35, 0x0000, 0x0000, 0x6c36, 0x0000, 0x0000, 0x6c37,
+ 0x0000, 0x0000, 0x0000, 0x6c38, 0x0000, 0x0000, 0x0000, 0x6c39,
+ 0x0000, 0x6c3a, 0x6c3b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6c3c, 0x6c3d, 0x6c3e, 0x6c3f,
+ 0x0000, 0x0000, 0x6c40, 0x0000, 0x0000, 0x0000, 0x6c41, 0x6c42,
+ 0x6c43, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c44, 0x0000, 0x6c45,
+ 0x0000, 0x6c46, 0x0000, 0x6c47, 0x0000, 0x0000, 0x6c48, 0x0000,
+ 0x6c49, 0x0000, 0x0000, 0x6c4a, 0x6c4b, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c4c, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_9e[] = {
+ /* 0x9e00 - 0x9eff */
+ 0x0000, 0x0000, 0x6c4e, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c4f,
+ 0x0000, 0x0000, 0x6c4d, 0x0000, 0x0000, 0x0000, 0x6c50, 0x0000,
+ 0x6c51, 0x6c52, 0x6c53, 0x0000, 0x0000, 0x6c54, 0x6c55, 0x0000,
+ 0x0000, 0x6c56, 0x0000, 0x0000, 0x6c57, 0x6c58, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6c59, 0x6c5a, 0x6c5b, 0x0000, 0x0000, 0x0000,
+ 0x6c5c, 0x0000, 0x6c5d, 0x6c5e, 0x6c5f, 0x6c60, 0x0000, 0x6c61,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c62, 0x6c63,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c64, 0x0000,
+ 0x6c65, 0x0000, 0x0000, 0x6c66, 0x0000, 0x0000, 0x6c67, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6c68, 0x0000, 0x0000, 0x0000,
+ 0x6c69, 0x0000, 0x0000, 0x0000, 0x6c6a, 0x0000, 0x6c6b, 0x6c6c,
+ 0x6c6d, 0x0000, 0x0000, 0x6c6e, 0x6c6f, 0x6c70, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c71, 0x0000,
+ 0x6c72, 0x0000, 0x0000, 0x6c73, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x747e, 0x0000, 0x0000, 0x0000, 0x6c74, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6c75,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6c76, 0x0000, 0x0000, 0x6c77,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x6c78, 0x6c79, 0x6c7a, 0x0000,
+ 0x6c7b, 0x6c7c, 0x6c7d, 0x0000, 0x0000, 0x6c7e, 0x0000, 0x0000,
+ 0x6d21, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d22,
+};
+
+static unsigned short const tqunicode_to_jisx0212_9f[] = {
+ /* 0x9f00 - 0x9fff */
+ 0x0000, 0x0000, 0x6d23, 0x6d24, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x6d25, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d26,
+ 0x6d27, 0x6d28, 0x6d29, 0x0000, 0x6d2a, 0x0000, 0x6d2b, 0x6d2c,
+ 0x0000, 0x6d2d, 0x6d2e, 0x6d2f, 0x0000, 0x0000, 0x0000, 0x6d30,
+ 0x0000, 0x0000, 0x6d31, 0x0000, 0x0000, 0x0000, 0x6d32, 0x0000,
+ 0x0000, 0x0000, 0x6d33, 0x6d34, 0x0000, 0x0000, 0x0000, 0x6d35,
+ 0x0000, 0x6d36, 0x6d37, 0x0000, 0x6d38, 0x0000, 0x0000, 0x6d39,
+ 0x0000, 0x6d3a, 0x6d3b, 0x0000, 0x6d3c, 0x6d3d, 0x0000, 0x6d3e,
+ 0x0000, 0x6d3f, 0x0000, 0x6d40, 0x6d41, 0x6d42, 0x6d43, 0x6d44,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x6d45, 0x0000, 0x6d46, 0x6d47, 0x6d48,
+ 0x6d49, 0x0000, 0x6d4a, 0x0000, 0x0000, 0x6d4b, 0x6d4c, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x6d4d, 0x6d4e, 0x0000, 0x0000, 0x0000, 0x6d4f, 0x6d50, 0x6d51,
+ 0x6d52, 0x6d53, 0x0000, 0x6d54, 0x0000, 0x6d55, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x6d56, 0x0000, 0x0000, 0x6d57, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d58,
+ 0x6d59, 0x6d5a, 0x6d5b, 0x0000, 0x6d5c, 0x0000, 0x6d5d, 0x6d5e,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x6d5f, 0x0000,
+ 0x0000, 0x6d60, 0x6d61, 0x6d62, 0x0000, 0x6d63, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_f9[] = {
+ /* 0xf900 - 0xf9ff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x7445, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x7472, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_fa[] = {
+ /* 0xfa00 - 0xfaff */
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7434, 0x7437,
+ 0x7438, 0x743d, 0x7444, 0x7447, 0x7448, 0x744e, 0x744f, 0x7453,
+ 0x7455, 0x7456, 0x7457, 0x7458, 0x745a, 0x745b, 0x745e, 0x7460,
+ 0x7462, 0x7463, 0x7465, 0x7469, 0x746a, 0x746b, 0x746d, 0x746f,
+ 0x7470, 0x7473, 0x7477, 0x7478, 0x7479, 0x747d, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const tqunicode_to_jisx0212_ff[] = {
+ /* 0xff00 - 0xffff */
+ 0x0000, 0x0000, 0x742a, 0x0000, 0x0000, 0x0000, 0x0000, 0x7429,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+};
+
+static unsigned short const * const tqunicode_to_jisx0212_map[0x100] = {
+ /* 0x00XX - 0x0fXX */
+ tqunicode_to_jisx0212_00,
+ tqunicode_to_jisx0212_01,
+ tqunicode_to_jisx0212_02,
+ tqunicode_to_jisx0212_03,
+ tqunicode_to_jisx0212_04,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x10XX - 0x1fXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x20XX - 0x2fXX */
+ 0,
+ tqunicode_to_jisx0212_21,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x30XX - 0x3fXX */
+ 0, 0,
+ tqunicode_to_jisx0212_32,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0x40XX - 0x4fXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ tqunicode_to_jisx0212_4e,
+ tqunicode_to_jisx0212_4f,
+ /* 0x50XX - 0x5fXX */
+ tqunicode_to_jisx0212_50,
+ tqunicode_to_jisx0212_51,
+ tqunicode_to_jisx0212_52,
+ tqunicode_to_jisx0212_53,
+ tqunicode_to_jisx0212_54,
+ tqunicode_to_jisx0212_55,
+ tqunicode_to_jisx0212_56,
+ tqunicode_to_jisx0212_57,
+ tqunicode_to_jisx0212_58,
+ tqunicode_to_jisx0212_59,
+ tqunicode_to_jisx0212_5a,
+ tqunicode_to_jisx0212_5b,
+ tqunicode_to_jisx0212_5c,
+ tqunicode_to_jisx0212_5d,
+ tqunicode_to_jisx0212_5e,
+ tqunicode_to_jisx0212_5f,
+ /* 0x60XX - 0x6fXX */
+ tqunicode_to_jisx0212_60,
+ tqunicode_to_jisx0212_61,
+ tqunicode_to_jisx0212_62,
+ tqunicode_to_jisx0212_63,
+ tqunicode_to_jisx0212_64,
+ tqunicode_to_jisx0212_65,
+ tqunicode_to_jisx0212_66,
+ tqunicode_to_jisx0212_67,
+ tqunicode_to_jisx0212_68,
+ tqunicode_to_jisx0212_69,
+ tqunicode_to_jisx0212_6a,
+ tqunicode_to_jisx0212_6b,
+ tqunicode_to_jisx0212_6c,
+ tqunicode_to_jisx0212_6d,
+ tqunicode_to_jisx0212_6e,
+ tqunicode_to_jisx0212_6f,
+ /* 0x70XX - 0x7fXX */
+ tqunicode_to_jisx0212_70,
+ tqunicode_to_jisx0212_71,
+ tqunicode_to_jisx0212_72,
+ tqunicode_to_jisx0212_73,
+ tqunicode_to_jisx0212_74,
+ tqunicode_to_jisx0212_75,
+ tqunicode_to_jisx0212_76,
+ tqunicode_to_jisx0212_77,
+ tqunicode_to_jisx0212_78,
+ tqunicode_to_jisx0212_79,
+ tqunicode_to_jisx0212_7a,
+ tqunicode_to_jisx0212_7b,
+ tqunicode_to_jisx0212_7c,
+ tqunicode_to_jisx0212_7d,
+ tqunicode_to_jisx0212_7e,
+ tqunicode_to_jisx0212_7f,
+ /* 0x80XX - 0x8fXX */
+ tqunicode_to_jisx0212_80,
+ tqunicode_to_jisx0212_81,
+ tqunicode_to_jisx0212_82,
+ tqunicode_to_jisx0212_83,
+ tqunicode_to_jisx0212_84,
+ tqunicode_to_jisx0212_85,
+ tqunicode_to_jisx0212_86,
+ tqunicode_to_jisx0212_87,
+ tqunicode_to_jisx0212_88,
+ tqunicode_to_jisx0212_89,
+ tqunicode_to_jisx0212_8a,
+ tqunicode_to_jisx0212_8b,
+ tqunicode_to_jisx0212_8c,
+ tqunicode_to_jisx0212_8d,
+ tqunicode_to_jisx0212_8e,
+ tqunicode_to_jisx0212_8f,
+ /* 0x90XX - 0x9fXX */
+ tqunicode_to_jisx0212_90,
+ tqunicode_to_jisx0212_91,
+ tqunicode_to_jisx0212_92,
+ tqunicode_to_jisx0212_93,
+ tqunicode_to_jisx0212_94,
+ tqunicode_to_jisx0212_95,
+ tqunicode_to_jisx0212_96,
+ tqunicode_to_jisx0212_97,
+ tqunicode_to_jisx0212_98,
+ tqunicode_to_jisx0212_99,
+ tqunicode_to_jisx0212_9a,
+ tqunicode_to_jisx0212_9b,
+ tqunicode_to_jisx0212_9c,
+ tqunicode_to_jisx0212_9d,
+ tqunicode_to_jisx0212_9e,
+ tqunicode_to_jisx0212_9f,
+ /* 0xa0XX - 0xafXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xb0XX - 0xbfXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xc0XX - 0xcfXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xd0XX - 0xdfXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xe0XX - 0xefXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xf0XX - 0xffXX */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ tqunicode_to_jisx0212_f9,
+ tqunicode_to_jisx0212_fa,
+ 0, 0, 0, 0,
+ tqunicode_to_jisx0212_ff,
+};
+
+#endif
+
+#ifdef USE_JISX0212
+static uint tqunicode11ToJisx0212(uint h, uint l)
+{
+ unsigned short const *table;
+
+ table = tqunicode_to_jisx0212_map[h];
+ if (table != 0) {
+ return table[l];
+ }
+ return 0x0000;
+}
+#else
+static uint tqunicode11ToJisx0212(uint h, uint l)
+{
+ return 0x0000;
+}
+#endif
+
+static unsigned short const sjis208ibmvdc_tqunicode[] = {
+ /*0xfa40 -0xfafc*/
+ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
+ 0x2178, 0x2179, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165,
+ 0x2166, 0x2167, 0x2168, 0x2169, 0xffe2, 0xffe4, 0xff07, 0xff02,
+ 0x3231, 0x2116, 0x2121, 0x2235, 0x7e8a, 0x891c, 0x9348, 0x9288,
+ 0x84dc, 0x4fc9, 0x70bb, 0x6631, 0x68c8, 0x92f9, 0x66fb, 0x5f45,
+ 0x4e28, 0x4ee1, 0x4efc, 0x4f00, 0x4f03, 0x4f39, 0x4f56, 0x4f92,
+ 0x4f8a, 0x4f9a, 0x4f94, 0x4fcd, 0x5040, 0x5022, 0x4fff, 0x501e,
+ 0x5046, 0x5070, 0x5042, 0x5094, 0x50f4, 0x50d8, 0x514a, 0x30fb,
+ 0x5164, 0x519d, 0x51be, 0x51ec, 0x5215, 0x529c, 0x52a6, 0x52c0,
+ 0x52db, 0x5300, 0x5307, 0x5324, 0x5372, 0x5393, 0x53b2, 0x53dd,
+ 0xfa0e, 0x549c, 0x548a, 0x54a9, 0x54ff, 0x5586, 0x5759, 0x5765,
+ 0x57ac, 0x57c8, 0x57c7, 0xfa0f, 0xfa10, 0x589e, 0x58b2, 0x590b,
+ 0x5953, 0x595b, 0x595d, 0x5963, 0x59a4, 0x59ba, 0x5b56, 0x5bc0,
+ 0x752f, 0x5bd8, 0x5bec, 0x5c1e, 0x5ca6, 0x5cba, 0x5cf5, 0x5d27,
+ 0x5d53, 0xfa11, 0x5d42, 0x5d6d, 0x5db8, 0x5db9, 0x5dd0, 0x5f21,
+ 0x5f34, 0x5f67, 0x5fb7, 0x5fde, 0x605d, 0x6085, 0x608a, 0x60de,
+ 0x60d5, 0x6120, 0x60f2, 0x6111, 0x6137, 0x6130, 0x6198, 0x6213,
+ 0x62a6, 0x63f5, 0x6460, 0x649d, 0x64ce, 0x654e, 0x6600, 0x6615,
+ 0x663b, 0x6609, 0x662e, 0x661e, 0x6624, 0x6665, 0x6657, 0x6659,
+ 0xfa12, 0x6673, 0x6699, 0x66a0, 0x66b2, 0x66bf, 0x66fa, 0x670e,
+ 0xf929, 0x6766, 0x67bb, 0x6852, 0x67c0, 0x6801, 0x6844, 0x68cf,
+ 0xfa13, 0x6968, 0xfa14, 0x6998, 0x69e2, 0x6a30, 0x6a6b, 0x6a46,
+ 0x6a73, 0x6a7e, 0x6ae2, 0x6ae4, 0x6bd6, 0x6c3f, 0x6c5c, 0x6c86,
+ 0x6c6f, 0x6cda, 0x6d04, 0x6d87, 0x6d6f,
+ /*0xfb40 -0xfbfc*/
+ 0x6d96, 0x6dac, 0x6dcf, 0x6df8, 0x6df2, 0x6dfc, 0x6e39, 0x6e5c,
+ 0x6e27, 0x6e3c, 0x6ebf, 0x6f88, 0x6fb5, 0x6ff5, 0x7005, 0x7007,
+ 0x7028, 0x7085, 0x70ab, 0x710f, 0x7104, 0x715c, 0x7146, 0x7147,
+ 0xfa15, 0x71c1, 0x71fe, 0x72b1, 0x72be, 0x7324, 0xfa16, 0x7377,
+ 0x73bd, 0x73c9, 0x73d6, 0x73e3, 0x73d2, 0x7407, 0x73f5, 0x7426,
+ 0x742a, 0x7429, 0x742e, 0x7462, 0x7489, 0x749f, 0x7501, 0x756f,
+ 0x7682, 0x769c, 0x769e, 0x769b, 0x76a6, 0xfa17, 0x7746, 0x52af,
+ 0x7821, 0x784e, 0x7864, 0x787a, 0x7930, 0xfa18, 0xfa19, 0x30fb,
+ 0xfa1a, 0x7994, 0xfa1b, 0x799b, 0x7ad1, 0x7ae7, 0xfa1c, 0x7aeb,
+ 0x7b9e, 0xfa1d, 0x7d48, 0x7d5c, 0x7db7, 0x7da0, 0x7dd6, 0x7e52,
+ 0x7f47, 0x7fa1, 0xfa1e, 0x8301, 0x8362, 0x837f, 0x83c7, 0x83f6,
+ 0x8448, 0x84b4, 0x8553, 0x8559, 0x856b, 0xfa1f, 0x85b0, 0xfa20,
+ 0xfa21, 0x8807, 0x88f5, 0x8a12, 0x8a37, 0x8a79, 0x8aa7, 0x8abe,
+ 0x8adf, 0xfa22, 0x8af6, 0x8b53, 0x8b7f, 0x8cf0, 0x8cf4, 0x8d12,
+ 0x8d76, 0xfa23, 0x8ecf, 0xfa24, 0xfa25, 0x9067, 0x90de, 0xfa26,
+ 0x9115, 0x9127, 0x91da, 0x91d7, 0x91de, 0x91ed, 0x91ee, 0x91e4,
+ 0x91e5, 0x9206, 0x9210, 0x920a, 0x923a, 0x9240, 0x923c, 0x924e,
+ 0x9259, 0x9251, 0x9239, 0x9267, 0x92a7, 0x9277, 0x9278, 0x92e7,
+ 0x92d7, 0x92d9, 0x92d0, 0xfa27, 0x92d5, 0x92e0, 0x92d3, 0x9325,
+ 0x9321, 0x92fb, 0xfa28, 0x931e, 0x92ff, 0x931d, 0x9302, 0x9370,
+ 0x9357, 0x93a4, 0x93c6, 0x93de, 0x93f8, 0x9431, 0x9445, 0x9448,
+ 0x9592, 0xf9dc, 0xfa29, 0x969d, 0x96af, 0x9733, 0x973b, 0x9743,
+ 0x974d, 0x974f, 0x9751, 0x9755, 0x9857, 0x9865, 0xfa2a, 0xfa2b,
+ 0x9927, 0xfa2c, 0x999e, 0x9a4e, 0x9ad9,
+ /*0xfc40 -0xfc4b*/
+ 0x9adc, 0x9b75, 0x9b72, 0x9b8f, 0x9bb1, 0x9bbb, 0x9c00, 0x9d70,
+ 0x9d6b, 0xfa2d, 0x9e19, 0x9ed1, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+uint TQJpUnicodeConv::sjisibmvdcToUnicode(uint h, uint l) const
+{
+ if (((rule & IBM_VDC) || (rule & Microsoft_CP932)) && IsSjisIBMVDCChar1(h))
+ return sjis208ibmvdc_tqunicode[((h - 0x00fa)*189 + (l-0x0040))];
+ else
+ return 0;
+}
+
+uint TQJpUnicodeConv::tqunicodeToSjisibmvdc(uint h, uint l) const
+{
+ if ((rule & IBM_VDC) || (rule & Microsoft_CP932)) {
+ uint u = (h<<8) | l;
+ //since there is no direct mapping, do a linear search
+ for (uint i =0; i<sizeof(sjis208ibmvdc_tqunicode)/sizeof(short) ; i++) {
+ //the table has zeros after 0xfc4b
+ if (!sjis208ibmvdc_tqunicode[i])
+ return 0;
+ if (u==sjis208ibmvdc_tqunicode[i]){
+ return ((0x00fa +(i/189))<<8 | 0x0040+(i%189));
+ }
+ }
+ }
+ return 0;
+}
+
+
+static unsigned short const cp932_87_tqunicode[] = {
+ /*0x8740 -0x879c*/
+ 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467,
+ 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f,
+ 0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162, 0x2163,
+ 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x0000, 0x3349,
+ 0x3314, 0x3322, 0x334d, 0x3318, 0x3327, 0x3303, 0x3336, 0x3351,
+ 0x3357, 0x330d, 0x3326, 0x3323, 0x332b, 0x334a, 0x333b, 0x339c,
+ 0x339d, 0x339e, 0x338e, 0x338f, 0x33c4, 0x33a1, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x337b, 0x0000,
+ 0x301d, 0x301f, 0x2116, 0x33cd, 0x2121, 0x32a4, 0x32a5, 0x32a6,
+ 0x32a7, 0x32a8, 0x3231, 0x3232, 0x3239, 0x337e, 0x337d, 0x337c,
+ 0x2252, 0x2261, 0x222b, 0x222e, 0x2211, 0x221a, 0x22a5, 0x2220,
+ 0x221f, 0x22bf, 0x2235, 0x2229, 0x222a
+};
+
+static unsigned short const cp932_ed_ee_tqunicode[] = {
+ /*0xed40-0xedfc*/
+ 0x7e8a, 0x891c, 0x9348, 0x9288, 0x84dc, 0x4fc9, 0x70bb, 0x6631,
+ 0x68c8, 0x92f9, 0x66fb, 0x5f45, 0x4e28, 0x4ee1, 0x4efc, 0x4f00,
+ 0x4f03, 0x4f39, 0x4f56, 0x4f92, 0x4f8a, 0x4f9a, 0x4f94, 0x4fcd,
+ 0x5040, 0x5022, 0x4fff, 0x501e, 0x5046, 0x5070, 0x5042, 0x5094,
+ 0x50f4, 0x50d8, 0x514a, 0x5164, 0x519d, 0x51be, 0x51ec, 0x5215,
+ 0x529c, 0x52a6, 0x52c0, 0x52db, 0x5300, 0x5307, 0x5324, 0x5372,
+ 0x5393, 0x53b2, 0x53dd, 0xfa0e, 0x549c, 0x548a, 0x54a9, 0x54ff,
+ 0x5586, 0x5759, 0x5765, 0x57ac, 0x57c8, 0x57c7, 0xfa0f, 0x0000,
+ 0xfa10, 0x589e, 0x58b2, 0x590b, 0x5953, 0x595b, 0x595d, 0x5963,
+ 0x59a4, 0x59ba, 0x5b56, 0x5bc0, 0x752f, 0x5bd8, 0x5bec, 0x5c1e,
+ 0x5ca6, 0x5cba, 0x5cf5, 0x5d27, 0x5d53, 0xfa11, 0x5d42, 0x5d6d,
+ 0x5db8, 0x5db9, 0x5dd0, 0x5f21, 0x5f34, 0x5f67, 0x5fb7, 0x5fde,
+ 0x605d, 0x6085, 0x608a, 0x60de, 0x60d5, 0x6120, 0x60f2, 0x6111,
+ 0x6137, 0x6130, 0x6198, 0x6213, 0x62a6, 0x63f5, 0x6460, 0x649d,
+ 0x64ce, 0x654e, 0x6600, 0x6615, 0x663b, 0x6609, 0x662e, 0x661e,
+ 0x6624, 0x6665, 0x6657, 0x6659, 0xfa12, 0x6673, 0x6699, 0x66a0,
+ 0x66b2, 0x66bf, 0x66fa, 0x670e, 0xf929, 0x6766, 0x67bb, 0x6852,
+ 0x67c0, 0x6801, 0x6844, 0x68cf, 0xfa13, 0x6968, 0xfa14, 0x6998,
+ 0x69e2, 0x6a30, 0x6a6b, 0x6a46, 0x6a73, 0x6a7e, 0x6ae2, 0x6ae4,
+ 0x6bd6, 0x6c3f, 0x6c5c, 0x6c86, 0x6c6f, 0x6cda, 0x6d04, 0x6d87,
+ 0x6d6f, 0x6d96, 0x6dac, 0x6dcf, 0x6df8, 0x6df2, 0x6dfc, 0x6e39,
+ 0x6e5c, 0x6e27, 0x6e3c, 0x6ebf, 0x6f88, 0x6fb5, 0x6ff5, 0x7005,
+ 0x7007, 0x7028, 0x7085, 0x70ab, 0x710f, 0x7104, 0x715c, 0x7146,
+ 0x7147, 0xfa15, 0x71c1, 0x71fe, 0x72b1,
+ /*0xee40-0xeefc*/
+ 0x72be, 0x7324, 0xfa16, 0x7377, 0x73bd, 0x73c9, 0x73d6, 0x73e3,
+ 0x73d2, 0x7407, 0x73f5, 0x7426, 0x742a, 0x7429, 0x742e, 0x7462,
+ 0x7489, 0x749f, 0x7501, 0x756f, 0x7682, 0x769c, 0x769e, 0x769b,
+ 0x76a6, 0xfa17, 0x7746, 0x52af, 0x7821, 0x784e, 0x7864, 0x787a,
+ 0x7930, 0xfa18, 0xfa19, 0xfa1a, 0x7994, 0xfa1b, 0x799b, 0x7ad1,
+ 0x7ae7, 0xfa1c, 0x7aeb, 0x7b9e, 0xfa1d, 0x7d48, 0x7d5c, 0x7db7,
+ 0x7da0, 0x7dd6, 0x7e52, 0x7f47, 0x7fa1, 0xfa1e, 0x8301, 0x8362,
+ 0x837f, 0x83c7, 0x83f6, 0x8448, 0x84b4, 0x8553, 0x8559, 0x0000,
+ 0x856b, 0xfa1f, 0x85b0, 0xfa20, 0xfa21, 0x8807, 0x88f5, 0x8a12,
+ 0x8a37, 0x8a79, 0x8aa7, 0x8abe, 0x8adf, 0xfa22, 0x8af6, 0x8b53,
+ 0x8b7f, 0x8cf0, 0x8cf4, 0x8d12, 0x8d76, 0xfa23, 0x8ecf, 0xfa24,
+ 0xfa25, 0x9067, 0x90de, 0xfa26, 0x9115, 0x9127, 0x91da, 0x91d7,
+ 0x91de, 0x91ed, 0x91ee, 0x91e4, 0x91e5, 0x9206, 0x9210, 0x920a,
+ 0x923a, 0x9240, 0x923c, 0x924e, 0x9259, 0x9251, 0x9239, 0x9267,
+ 0x92a7, 0x9277, 0x9278, 0x92e7, 0x92d7, 0x92d9, 0x92d0, 0xfa27,
+ 0x92d5, 0x92e0, 0x92d3, 0x9325, 0x9321, 0x92fb, 0xfa28, 0x931e,
+ 0x92ff, 0x931d, 0x9302, 0x9370, 0x9357, 0x93a4, 0x93c6, 0x93de,
+ 0x93f8, 0x9431, 0x9445, 0x9448, 0x9592, 0xf9dc, 0xfa29, 0x969d,
+ 0x96af, 0x9733, 0x973b, 0x9743, 0x974d, 0x974f, 0x9751, 0x9755,
+ 0x9857, 0x9865, 0xfa2a, 0xfa2b, 0x9927, 0xfa2c, 0x999e, 0x9a4e,
+ 0x9ad9, 0x9adc, 0x9b75, 0x9b72, 0x9b8f, 0x9bb1, 0x9bbb, 0x9c00,
+ 0x9d70, 0x9d6b, 0xfa2d, 0x9e19, 0x9ed1, 0x0000, 0x0000, 0x2170,
+ 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178,
+ 0x2179, 0xffe2, 0xffe4, 0xff07, 0xff02
+};
+
+uint TQJpUnicodeConv::cp932ToUnicode(uint h, uint l) const
+{
+ if (rule & Microsoft_CP932) {
+ if (h == 0x0087 && (l >= 0x0040 && l <= 0x009c))
+ return cp932_87_tqunicode[l-0x0040];
+ else if ((h == 0x00ed || h == 0x00ee) && (l >= 0x0040 && l <= 0x00fc))
+ return cp932_ed_ee_tqunicode[((h - 0x00ed)*189 + (l-0x0040))];
+ }
+ return 0;
+}
+
+uint TQJpUnicodeConv::tqunicodeToCp932(uint h, uint l) const
+{
+ if ((rule & Microsoft_CP932)) {
+ uint u = (h<<8) | l;
+ //since there is no direct mapping, do a linear search
+ for (uint i =0; i<sizeof(cp932_87_tqunicode)/sizeof(short) ; i++) {
+ //the table has zeros for some characters
+ if (!cp932_87_tqunicode[i])
+ return 0;
+ if (u == cp932_87_tqunicode[i]){
+ return ((0x0087<<8) | (0x0040+i));
+ }
+ }
+ for (uint j =0; j<sizeof(cp932_ed_ee_tqunicode)/sizeof(short) ; j++) {
+ if (!cp932_ed_ee_tqunicode[j])
+ return 0;
+ if (u==cp932_ed_ee_tqunicode[j]){
+ return ((0x00ed +(j/189))<<8 | 0x0040+(j%189));
+ }
+ }
+ }
+ return 0;
+}
+
+
+// and now for the inlines:
+
+/*! \fn uint TQJpUnicodeConv::asciiToUnicode (uint ascii) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::jisx0201ToUnicode (uint jis) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::jisx0201LatinToUnicode (uint jis) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::jisx0201KanaToUnicode (uint jis) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::jisx0208ToUnicode (uint jis) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::jisx0212ToUnicode (uint jis) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::tqunicodeToAscii (uint tqunicode) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::tqunicodeToJisx0201 (uint tqunicode) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::tqunicodeToJisx0201Latin (uint tqunicode) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::tqunicodeToJisx0201Kana (uint tqunicode) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::tqunicodeToJisx0208 (uint tqunicode) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::tqunicodeToJisx0212 (uint tqunicode) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::sjisToUnicode (uint sjis) const
+
+\internal
+*/
+
+/*! \fn uint TQJpUnicodeConv::tqunicodeToSjis (uint tqunicode) const
+
+\internal
+*/
+
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqjpunicode.h b/tqtinterface/qt4/src/codecs/tqjpunicode.h
new file mode 100644
index 0000000..adfed20
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqjpunicode.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Definition of TQJpUnicodeConv class
+**
+** Created : 990225
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Most of the code here was originally written by Serika Kurusugawa
+// a.k.a. Junji Takagi, and is included in TQt with the author's permission,
+// and the grateful thanks of the Trolltech team.
+
+/*
+ * Copyright (C) 1999 Serika Kurusugawa, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef TQJPUNICODE_H
+#define TQJPUNICODE_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_BIG_CODECS
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_CODECS_JP
+#else
+#define TQ_EXPORT_CODECS_JP TQ_EXPORT
+#endif
+
+class TQ_EXPORT_CODECS_JP TQJpUnicodeConv {
+public:
+ enum Rules {
+ // "ASCII" is ANSI X.3.4-1986, a.k.a. US-ASCII here.
+ Default = 0x0000,
+
+ Unicode = 0x0001,
+ Unicode_JISX0201 = 0x0001,
+ Unicode_ASCII = 0x0002,
+ JISX0221_JISX0201 = 0x0003,
+ JISX0221_ASCII = 0x0004,
+ Sun_JDK117 = 0x0005,
+ Microsoft_CP932 = 0x0006,
+
+ NEC_VDC = 0x0100, // NEC Vender Defined Char
+ UDC = 0x0200, // User Defined Char
+ IBM_VDC = 0x0400 // IBM Vender Defined Char
+ };
+ static TQJpUnicodeConv *newConverter(int rule);
+
+ virtual uint asciiToUnicode(uint h, uint l) const;
+ /*virtual*/ uint jisx0201ToUnicode(uint h, uint l) const;
+ virtual uint jisx0201LatinToUnicode(uint h, uint l) const;
+ /*virtual*/ uint jisx0201KanaToUnicode(uint h, uint l) const;
+ virtual uint jisx0208ToUnicode(uint h, uint l) const;
+ virtual uint jisx0212ToUnicode(uint h, uint l) const;
+
+ uint asciiToUnicode(uint ascii) const {
+ return asciiToUnicode((ascii & 0xff00) >> 8, (ascii & 0x00ff));
+ }
+ uint jisx0201ToUnicode(uint jis) const {
+ return jisx0201ToUnicode((jis & 0xff00) >> 8, (jis & 0x00ff));
+ }
+ uint jisx0201LatinToUnicode(uint jis) const {
+ return jisx0201LatinToUnicode((jis & 0xff00) >> 8, (jis & 0x00ff));
+ }
+ uint jisx0201KanaToUnicode(uint jis) const {
+ return jisx0201KanaToUnicode((jis & 0xff00) >> 8, (jis & 0x00ff));
+ }
+ uint jisx0208ToUnicode(uint jis) const {
+ return jisx0208ToUnicode((jis & 0xff00) >> 8, (jis & 0x00ff));
+ }
+ uint jisx0212ToUnicode(uint jis) const {
+ return jisx0212ToUnicode((jis & 0xff00) >> 8, (jis & 0x00ff));
+ }
+
+ virtual uint tqunicodeToAscii(uint h, uint l) const;
+ /*virtual*/ uint tqunicodeToJisx0201(uint h, uint l) const;
+ virtual uint tqunicodeToJisx0201Latin(uint h, uint l) const;
+ /*virtual*/ uint tqunicodeToJisx0201Kana(uint h, uint l) const;
+ virtual uint tqunicodeToJisx0208(uint h, uint l) const;
+ virtual uint tqunicodeToJisx0212(uint h, uint l) const;
+
+ uint tqunicodeToAscii(uint tqunicode) const {
+ return tqunicodeToAscii((tqunicode & 0xff00) >> 8, (tqunicode & 0x00ff));
+ }
+ uint tqunicodeToJisx0201(uint tqunicode) const {
+ return tqunicodeToJisx0201((tqunicode & 0xff00) >> 8, (tqunicode & 0x00ff));
+ }
+ uint tqunicodeToJisx0201Latin(uint tqunicode) const {
+ return tqunicodeToJisx0201Latin((tqunicode & 0xff00) >> 8, (tqunicode & 0x00ff));
+ }
+ uint tqunicodeToJisx0201Kana(uint tqunicode) const {
+ return tqunicodeToJisx0201Kana((tqunicode & 0xff00) >> 8, (tqunicode & 0x00ff));
+ }
+ uint tqunicodeToJisx0208(uint tqunicode) const {
+ return tqunicodeToJisx0208((tqunicode & 0xff00) >> 8, (tqunicode & 0x00ff));
+ }
+ uint tqunicodeToJisx0212(uint tqunicode) const {
+ return tqunicodeToJisx0212((tqunicode & 0xff00) >> 8, (tqunicode & 0x00ff));
+ }
+
+ uint sjisToUnicode(uint h, uint l) const;
+ uint tqunicodeToSjis(uint h, uint l) const;
+ uint sjisibmvdcToUnicode(uint h, uint l) const;
+ uint tqunicodeToSjisibmvdc(uint h, uint l) const;
+ uint cp932ToUnicode(uint h, uint l) const;
+ uint tqunicodeToCp932(uint h, uint l) const;
+
+ uint sjisToUnicode(uint sjis) const {
+ return sjisToUnicode((sjis & 0xff00) >> 8, (sjis & 0x00ff));
+ }
+ uint tqunicodeToSjis(uint tqunicode) const {
+ return tqunicodeToSjis((tqunicode & 0xff00) >> 8, (tqunicode & 0x00ff));
+ }
+
+protected:
+ TQJpUnicodeConv(int r) : rule(r) {}
+
+private:
+ int rule;
+};
+
+#endif // TQT_NO_BIG_CODECS
+#endif /* TQJPUNICODE_H */
diff --git a/tqtinterface/qt4/src/codecs/tqrtlcodec.cpp b/tqtinterface/qt4/src/codecs/tqrtlcodec.cpp
new file mode 100644
index 0000000..56bf40d
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqrtlcodec.cpp
@@ -0,0 +1,617 @@
+/****************************************************************************
+**
+** Implementation of TQTextCodec class
+**
+** Created : 981015
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqrtlcodec.h"
+#include <private/tqtextengine_p.h>
+
+#ifndef TQT_NO_CODEC_HEBREW
+
+// NOT REVISED
+
+static const uchar unkn = '?'; // BLACK STQUARE (94) would be better
+
+static const ushort heb_to_tqunicode[128] = {
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0xFFFD, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x203E,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2017,
+ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+ 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+ 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD
+};
+
+static const uchar tqunicode_to_heb_00[32] = {
+ 0xA0, unkn, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
+ 0xA8, 0xA9, 0xD7, 0xAB, 0xAC, 0xAD, 0xAE, unkn,
+ 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
+ 0xB8, 0xB9, 0xF7, 0xBB, 0xBC, 0xBD, 0xBE, unkn,
+};
+
+static const uchar tqunicode_to_heb_05[32] = {
+ 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
+ 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
+ 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ 0xF8, 0xF9, 0xFA, unkn, unkn, unkn, unkn, unkn
+};
+
+static bool to8bit(const TQChar ch, TQCString *rstr)
+{
+ bool converted = FALSE;
+
+ if( ch.isMark() ) return TRUE; // ignore marks for conversion
+
+ if ( ch.row() ) {
+ if ( ch.row() == 0x05 ) {
+ if ( ch.cell() > 0x91 )
+ converted = TRUE;
+ // 0x0591 - 0x05cf: Hebrew punctuation... dropped
+ if ( ch.cell() >= 0xD0 )
+ *rstr += (char)tqunicode_to_heb_05[ch.cell()- 0xD0];
+ } else if ( ch.row() == 0x20 ) {
+ if ( ch.cell() == 0x3E ) {
+ *rstr += (char)0xAF;
+ converted = TRUE;
+ } else if ( ch.cell() == 0x17 ) {
+ *rstr += (char)0xCF;
+ converted = TRUE;
+ }
+ } else {
+ converted = FALSE;
+ }
+ } else {
+ if ( ch.cell() < 0x80 ) {
+ *rstr += (char)ch.cell();
+ converted = TRUE;
+ } else if( ch.cell() < 0xA0 ) {
+ *rstr += (char)tqunicode_to_heb_00[ch.cell() - 0x80];
+ converted = TRUE;
+ }
+ }
+
+ if(converted) return TRUE;
+
+ // couldn't convert the char... lets try its decomposition
+ TQString d = ch.decomposition();
+ if(d.isNull())
+ return FALSE;
+
+ int l = d.length();
+ for (int i=0; i<l; i++) {
+ const TQChar ch = d[i];
+
+ if(to8bit(ch, rstr))
+ converted = TRUE;
+ }
+
+ return converted;
+}
+
+#if 0
+static TQString run(const TQString &input, unsigned int from, unsigned int to, TQChar::Direction runDir)
+{
+ if ( to <= from )
+ return TQString::null;
+
+ TQString out;
+ if ( runDir == TQChar::DirR ) {
+ const TQChar *ch = input.tqunicode() + to - 1;
+ int len = to - from;
+ while (len--) {
+ out += *ch;
+ ch--;
+ }
+ } else {
+ out = input.mid(from, to - from );
+ }
+ return out;
+}
+
+/*
+ we might do better here, but I'm currently not sure if it's worth the effort. It will hopefully convert
+ 90% of the visually ordered Hebrew correctly.
+*/
+static TQString reverseLine(const TQString &str, unsigned int from, unsigned int to, TQChar::Direction dir)
+{
+ TQString out;
+
+ if ( to <= from ) {
+ out += str.at(from);
+ return out;
+ }
+
+ // since we don't have embedding marks, we get around with bidi levels up to 2.
+
+ // simple case: dir = RTL:
+ // go through the line from right to left, and reverse all continuous Hebrew strings.
+ if ( dir == TQChar::DirR ) {
+ unsigned int pos = to;
+ to = from;
+ from = pos;
+ TQChar::Direction runDir = TQChar::DirON;
+
+ while ( pos > to ) {
+ TQChar::Direction d = str.at(pos).direction();
+ switch ( d ) {
+ case TQChar::DirL:
+ case TQChar::DirAN:
+ case TQChar::DirEN:
+ if ( runDir != TQChar::DirL ) {
+ out += run( str, pos, from, runDir );
+ from = pos - 1;
+ }
+ runDir = TQChar::DirL;
+ break;
+ case TQChar::DirON:
+ if ( runDir == TQChar::DirON ) {
+ runDir = TQChar::DirR;
+ break;
+ }
+ // fall through
+ case TQChar::DirR:
+ if ( runDir != TQChar::DirR ) {
+ out += run( str, pos, from, runDir );
+ from = pos - 1;
+ }
+ runDir = TQChar::DirR;
+ default:
+ break;
+ }
+ pos--;
+ }
+ out += run( str, pos, from, runDir );
+ } else {
+ // basicDir == DirL. A bit more complicated, as we might need to reverse two times for numbers.
+ unsigned int pos = from;
+ TQChar::Direction runDir = TQChar::DirON;
+
+ // first reversing. Ignore numbers
+ while ( pos < to ) {
+ TQChar::Direction d = str.at(pos).direction();
+ switch ( d ) {
+ case TQChar::DirL:
+ if ( runDir != TQChar::DirL && runDir != TQChar::DirON ) {
+ out += run( str, from, pos, runDir );
+ qDebug( "out = %s", out.latin1() );
+ from = pos;
+ }
+ runDir = TQChar::DirL;
+ break;
+ case TQChar::DirON:
+ if ( runDir == TQChar::DirON ) {
+ runDir = TQChar::DirL;
+ break;
+ }
+ // fall through
+ case TQChar::DirR:
+ case TQChar::DirAN:
+ case TQChar::DirEN:
+ if ( runDir != TQChar::DirR && runDir != TQChar::DirON ) {
+ out += run( str, from, pos, runDir );
+ qDebug( "out = %s", out.latin1() );
+ from = pos;
+ }
+ runDir = TQChar::DirR;
+ default:
+ break;
+ }
+ pos++;
+ }
+ out += run( str, from, pos, runDir );
+ qDebug( "out = %s", out.latin1() );
+ // second reversing for numbers
+ TQString in = out;
+ out = "";
+ pos = 0;
+ from = 0;
+ to = in.length() - 1;
+ runDir = TQChar::DirON;
+ while ( pos < to ) {
+ TQChar::Direction d = str.at(pos).direction();
+ switch ( d ) {
+ case TQChar::DirL:
+ case TQChar::DirON:
+ case TQChar::DirR:
+ if ( runDir == TQChar::DirEN && runDir != TQChar::DirON ) {
+ out += run( in, from, pos, TQChar::DirR ); //DirR ensures reversing
+ qDebug( "out = %s", out.latin1() );
+ runDir = TQChar::DirR;
+ from = pos;
+ }
+ runDir = TQChar::DirL;
+ break;
+ case TQChar::DirAN:
+ case TQChar::DirEN:
+ if ( runDir != TQChar::DirEN && runDir != TQChar::DirON ) {
+ out += in.mid(from, pos-from+1);
+ qDebug( "out = %s", out.latin1() );
+ from = pos;
+ }
+ runDir = TQChar::DirEN;
+ default:
+ break;
+ }
+ pos++;
+ }
+ out += run( str, from, pos, runDir );
+
+ }
+ return out;
+}
+#endif
+
+/* this function assuems the TQString is still visually ordered.
+ * Finding the basic direction of the text is not easy in this case, since
+ * a string like "my friend MOLAHS" could (in logical order) mean aswell
+ * "SHALOM my friend" or "my friend SHALOM", depending on the basic direction
+ * one assumes for the text.
+ *
+ * So this function uses some heuristics to tqfind the right answer...
+ */
+static TQChar::Direction tqfindBasicDirection(TQString str)
+{
+ unsigned int pos;
+ unsigned int len = str.length();
+ TQChar::Direction dir1 = TQChar::DirON;
+ TQChar::Direction dir2 = TQChar::DirON;
+
+ unsigned int startLine = 0;
+ // If the visual representation of the first line starts and ends with the same
+ // directionality, we know the answer.
+ pos = 0;
+ while (pos < len) {
+ if ( str.at(pos) == '\n' )
+ startLine = pos;
+ if (str.at(pos).direction() < 2) { // DirR or DirL
+ dir1 = str.at(pos).direction();
+ break;
+ }
+ pos++;
+ }
+
+ if( pos == len ) // no directional chars, assume TQChar::DirL
+ return TQChar::DirL;
+
+ // move to end of line
+ while( pos < len && str.at(pos) != '\n' )
+ pos++;
+
+ while (pos > startLine) {
+ if (str.at(pos).direction() < 2) { // DirR or DirL
+ dir2 = str.at(pos).direction();
+ break;
+ }
+ pos--;
+ }
+
+ // both are the same, so we have the direction!
+ if ( dir1 == dir2 ) return dir1;
+
+ // guess with the help of punktuation marks...
+ // if the sentence ends with a punktuation, we should have a mark
+ // at one side of the text...
+
+ pos = 0;
+ while (pos < len-1 ) {
+ if(str.at(pos).category() == TQChar::Punctuation_Other) {
+ if( str.at(pos) != (char)0xbf && str.at(pos) != (char)0xa1 ) // spanish inverted question and exclamation mark
+ if( str.at(pos+1).direction() < 2 ) return TQChar::DirR;
+ }
+ pos++;
+ }
+
+ pos = len;
+ while (pos < 1 && str.at(pos).direction() < 2 ) {
+ if(str.at(pos).category() == TQChar::Punctuation_Other) {
+ if( str.at(pos-1).direction() < 2 ) return TQChar::DirL;
+ }
+ pos--;
+ }
+
+ // don't know try DirR...
+ return TQChar::DirR;
+}
+
+
+/*!
+ \class TQHebrewCodec tqrtlcodec.h
+ \reentrant
+ \ingroup i18n
+
+ \brief The TQHebrewCodec class provides conversion to and from
+ visually ordered Hebrew.
+
+ Hebrew as a semitic language is written from right to left.
+ Because older computer systems couldn't handle reordering a string
+ so that the first letter appears on the right, many older
+ documents were encoded in visual order, so that the first letter
+ of a line is the rightmost one in the string.
+
+ In contrast to this, Unicode defines characters to be in logical
+ order (the order you would read the string). This codec tries to
+ convert visually ordered Hebrew (8859-8) to Unicode. This might
+ not always work perfectly, because reversing the \e bidi
+ (bi-directional) algorithm that transforms from logical to visual
+ order is non-trivial.
+
+ Transformation from Unicode to visual Hebrew (8859-8) is done
+ using the bidi algorithm in TQt, and will produce correct results,
+ so long as the codec is given the text a whole paragraph at a
+ time. Places where newlines are supposed to go can be indicated by
+ a newline character ('\n'). Note that these newline characters
+ change the reordering behaviour of the algorithm, since the bidi
+ reordering only takes place within one line of text, whereas
+ line breaks are determined in visual order.
+
+ Visually ordered Hebrew is still used quite often in some places,
+ mainly in email communication (since most email programs still
+ don't understand logically ordered Hebrew) and on web pages. The
+ use on web pages is rapidly decreasing, due to the availability of
+ browsers that correctly support logically ordered Hebrew.
+
+ This codec has the name "iso8859-8". If you don't want any bidi
+ reordering to happen during conversion, use the "iso8859-8-i"
+ codec, which assumes logical order for the 8-bit string.
+*/
+
+/*! \reimp */
+int TQHebrewCodec::mibEnum() const
+{
+ return 11;
+}
+
+/*! \reimp */
+const char* TQHebrewCodec::name() const
+{
+ return "ISO 8859-8";
+}
+
+/*!
+ Returns the codec's mime name.
+*/
+const char* TQHebrewCodec::mimeName() const
+{
+ return "ISO-8859-8";
+}
+
+static TQString visualOrder(TQString logical, TQChar::Direction basicDir)
+{
+ logical.tqreplace(TQChar('\n'), TQChar(0x2028));
+
+#ifdef USE_QT4
+ // [FIXME]
+ printf("[WARNING] static TQString visualOrder(TQString logical, TQChar::Direction basicDir) unimplemented\n\r");
+ return logical;
+#else // USE_QT4
+ TQTextEngine e(logical, 0);
+ e.direction = basicDir;
+ e.itemize();
+ TQ_UINT8 l[256];
+ TQ_UINT8 *levels = l;
+ int vo[256];
+ int *visualOrder = vo;
+ int nitems = e.items.size();
+ if (nitems > 255) {
+ levels = new TQ_UINT8[nitems];
+ visualOrder = new int[nitems];
+ }
+ int i;
+ for (i = 0; i < nitems; ++i) {
+ //qDebug("item %d bidiLevel=%d", i, e.items[i].analysis.bidiLevel);
+ levels[i] = e.items[i].analysis.bidiLevel;
+ }
+ e.bidiReorder(nitems, levels, visualOrder);
+
+ TQString visual;
+ for (i = 0; i < nitems; ++i) {
+ TQScriptItem &si = e.items[visualOrder[i]];
+ TQString sub = logical.mid(si.position, e.length(visualOrder[i]));
+ if (si.analysis.bidiLevel % 2) {
+ // reverse sub
+ TQChar *a = (TQChar *)sub.tqunicode();
+ TQChar *b = a + sub.length() - 1;
+ while (a < b) {
+ TQChar tmp = *a;
+ *a = *b;
+ *b = tmp;
+ ++a;
+ --b;
+ }
+ a = (TQChar *)sub.tqunicode();
+ b = a + sub.length();
+ while (a<b) {
+ *a = a->mirroredChar();
+ ++a;
+ }
+ }
+ visual += sub;
+ }
+ // tqreplace Unicode newline back with \n to compare.
+ visual.tqreplace(TQChar(0x2028), TQChar('\n'));
+ if (l != levels) {
+ delete [] levels;
+ delete [] visualOrder;
+ }
+ return visual;
+#endif // USE_QT4
+}
+
+/*!
+ \reimp
+
+ Since Hebrew (and Arabic) is written from left to right, but
+ iso8859-8 assumes visual ordering (as opposed to the logical
+ ordering of Unicode), we must reverse the order of the input
+ string (the first \a len characters of \a chars) to put it into
+ logical order.
+
+ One problem is that the basic text direction is unknown. So this
+ function uses some heuristics to guess it, and if it can't guess
+ the right one, it assumes, the basic text direction is right to
+ left.
+
+ This behaviour can be overridden, by putting a control character
+ at the beginning of the text to indicate which basic text
+ direction to use. If the basic text direction is left-to-right,
+ the control character should be (uchar) 0xFE. For right-to-left it
+ should be 0xFF. Both characters are undefined in the iso 8859-8
+ charset.
+
+ Example: A visually ordered string "english WERBEH american" would
+ be recognized as having a basic left to right direction. So the
+ logically ordered TQString would be "english HEBREW american".
+
+ By prepending a (uchar)0xFF at the start of the string,
+ TQHebrewCodec::toUnicode() would use a basic text direction of
+ right to left, and the string would thus become "american HEBREW
+ english".
+*/
+TQString TQHebrewCodec::toUnicode(const char* chars, int len ) const
+{
+ TQString r;
+ const unsigned char * c = (const unsigned char *)chars;
+ TQChar::Direction basicDir = TQChar::DirON; // neutral, we don't know
+
+ if( len == 0 ) return TQString::null;
+
+ // Test, if the user gives us a directionality.
+ // We use 0xFE and 0xFF in ISO8859-8 for that.
+ // These chars are undefined in the charset, and are mapped to
+ // RTL overwrite
+ if( c[0] == 0xfe ) {
+ basicDir = TQChar::DirL;
+ c++; // skip directionality hint
+ }
+ if( c[0] == 0xff ) {
+ basicDir = TQChar::DirR;
+ c++; // skip directionality hint
+ }
+
+ for( int i=0; i<len; i++ ) {
+ if ( c[i] > 127 )
+ r[i] = heb_to_tqunicode[c[i]-128];
+ else
+ r[i] = c[i];
+ }
+
+ // do transformation from visual byte ordering to logical byte
+ // ordering
+ if( basicDir == TQChar::DirON )
+ basicDir = tqfindBasicDirection(r);
+
+ return visualOrder(r, basicDir);
+}
+
+/*!
+ Transforms the logically ordered TQString, \a uc, into a visually
+ ordered string in the 8859-8 encoding. TQt's bidi algorithm is used
+ to perform this task. Note that newline characters affect the
+ reordering, since reordering is done on a line by line basis.
+
+ The algorithm is designed to work on whole paragraphs of text, so
+ processing a line at a time may produce incorrect results. This
+ approach is taken because the reordering of the contents of a
+ particular line in a paragraph may depend on the previous line in
+ the same paragraph.
+
+ Some encodings (for example Japanese or UTF-8) are multibyte (so
+ one input character is mapped to two output characters). The \a
+ lenInOut argument specifies the number of TQChars that should be
+ converted and is set to the number of characters returned.
+*/
+TQCString TQHebrewCodec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ // process only len chars...
+ int l;
+ if( lenInOut > 0 )
+ l = TQMIN((int)uc.length(),lenInOut);
+ else
+ l = (int)uc.length();
+
+ TQCString rstr;
+ if( l == 1 ) {
+ if( !to8bit( uc[0], &rstr ) )
+ rstr += (char)unkn;
+ } else {
+ TQString tmp = uc;
+ tmp.truncate(l);
+ TQString vis = visualOrder(tmp, TQChar::DirON);
+
+ for (int i=0; i<l; i++) {
+ const TQChar ch = vis[i];
+
+ if( !to8bit( ch, &rstr ) )
+ rstr += (char)unkn;
+ }
+ // lenInOut = cursor - result;
+ }
+ if( l > 0 && !rstr.length() )
+ rstr += (char)unkn;
+
+ return rstr;
+}
+
+/*! \reimp
+ */
+int TQHebrewCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ const unsigned char * c = (const unsigned char *)chars;
+
+ int score = 0;
+ for (int i=0; i<len; i++) {
+ if(c[i] > 0x80 ) {
+ if ( heb_to_tqunicode[c[i] - 0x80] != 0xFFFD)
+ score++;
+ else
+ return -1;
+ }
+ }
+ return score;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqrtlcodec.h b/tqtinterface/qt4/src/codecs/tqrtlcodec.h
new file mode 100644
index 0000000..b789e26
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqrtlcodec.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Implementation of TQTextCodec class
+**
+** Created : 981015
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQRTLCODEC_H
+#define TQRTLCODEC_H
+
+#ifndef TQT_H
+#include "tqtextcodec.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_CODEC_HEBREW
+
+class TQ_EXPORT TQHebrewCodec : public TQTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+ const char* mimeName() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+};
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqsjiscodec.cpp b/tqtinterface/qt4/src/codecs/tqsjiscodec.cpp
new file mode 100644
index 0000000..000898d
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqsjiscodec.cpp
@@ -0,0 +1,382 @@
+/****************************************************************************
+**
+** Implementation of TQSjisCodec class
+**
+** Created : 990225
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Most of the code here was originally written by Serika Kurusugawa
+// a.k.a. Junji Takagi, and is included in TQt with the author's permission,
+// and the grateful thanks of the Trolltech team.
+
+/*! \class TQSjisCodec tqsjiscodec.h
+ \reentrant
+ \ingroup i18n
+ \brief The TQSjisCodec class provides conversion to and from Shift-JIS.
+
+ More precisely, the TQSjisCodec class subclasses TQTextCodec to
+ provide support for Shift-JIS, an encoding of JIS X 0201 Latin, JIS
+ X 0201 Kana or JIS X 0208.
+
+ The environment variable \c UNICODEMAP_JP can be used to fine-tune
+ TQJisCodec, TQSjisCodec and TQEucJpCodec. The \l TQJisCodec
+ documentation describes how to use this variable.
+
+ Most of the code here was written by Serika Kurusugawa,
+ a.k.a. Junji Takagi, and is included in TQt with the author's
+ permission and the grateful thanks of the Trolltech team.
+ Here is the copyright statement for the code as it was at the
+ point of contribution. Trolltech's subsequent modifications
+ are covered by the usual copyright for TQt.
+
+ \legalese
+
+ Copyright (C) 1999 Serika Kurusugawa. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ \list 1
+ \i Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ \i Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ \endlist
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS".
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+#include "tqsjiscodec.h"
+
+#ifndef TQT_NO_BIG_CODECS
+
+static const uchar Esc = 0x1b;
+
+#define IsKana(c) (((c) >= 0xa1) && ((c) <= 0xdf))
+#define IsSjisChar1(c) ((((c) >= 0x81) && ((c) <= 0x9f)) || \
+ (((c) >= 0xe0) && ((c) <= 0xfc)))
+#define IsSjisChar2(c) (((c) >= 0x40) && ((c) != 0x7f) && ((c) <= 0xfc))
+#define IsUserDefinedChar1(c) (((c) >= 0xf0) && ((c) <= 0xfc))
+
+#define TQValidChar(u) ((u) ? TQChar((ushort)(u)) : TQChar::tqreplacement)
+
+/*!
+ Creates a Shift-JIS codec. Note that this is done automatically by
+ the TQApplication, you do not need construct your own.
+*/
+TQSjisCodec::TQSjisCodec() : conv(TQJpUnicodeConv::newConverter(TQJpUnicodeConv::Default))
+{
+}
+
+
+/*!
+ Destroys the Shift-JIS codec.
+*/
+TQSjisCodec::~TQSjisCodec()
+{
+ delete (TQJpUnicodeConv*)conv;
+ conv = 0;
+}
+
+
+/*!
+ \reimp
+*/
+int TQSjisCodec::mibEnum() const
+{
+ /*
+ Name: Shift_JIS (preferred MIME name)
+ MIBenum: 17
+ Source: A Microsoft code that extends csHalfWidthKatakana to include
+ kanji by adding a second byte when the value of the first
+ byte is in the ranges 81-9F or E0-EF.
+ Alias: MS_Kanji
+ Alias: csShiftJIS
+ */
+ return 17;
+}
+
+/*!
+ \reimp
+*/
+TQCString TQSjisCodec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ int l = TQMIN((int)uc.length(),lenInOut);
+ int rlen = l*2+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+ for (int i=0; i<l; i++) {
+ TQChar ch = uc[i];
+ uint j;
+ if ( ch.row() == 0x00 && ch.cell() < 0x80 ) {
+ // ASCII
+ *cursor++ = ch.cell();
+ } else if ((j = conv->tqunicodeToJisx0201(ch.row(), ch.cell())) != 0) {
+ // JIS X 0201 Latin or JIS X 0201 Kana
+ *cursor++ = j;
+ } else if ((j = conv->tqunicodeToSjis(ch.row(), ch.cell())) != 0) {
+ // JIS X 0208
+ *cursor++ = (j >> 8);
+ *cursor++ = (j & 0xff);
+ } else if ((j = conv->tqunicodeToSjisibmvdc(ch.row(), ch.cell())) != 0) {
+ // JIS X 0208 IBM VDC
+ *cursor++ = (j >> 8);
+ *cursor++ = (j & 0xff);
+ } else if ((j = conv->tqunicodeToCp932(ch.row(), ch.cell())) != 0) {
+ // CP932 (for lead bytes 87, ee & ed)
+ *cursor++ = (j >> 8);
+ *cursor++ = (j & 0xff);
+ } else if ((j = conv->tqunicodeToJisx0212(ch.row(), ch.cell())) != 0) {
+ // JIS X 0212 (can't be encoded in ShiftJIS !)
+ *cursor++ = 0x81; // white square
+ *cursor++ = 0xa0; // white square
+ } else {
+ // Error
+ *cursor++ = '?'; // unknown char
+ }
+ }
+ lenInOut = cursor - (uchar*)rstr.data();
+ rstr.truncate(lenInOut);
+ return rstr;
+}
+
+/*!
+ \reimp
+*/
+TQString TQSjisCodec::toUnicode(const char* chars, int len) const
+{
+ uint u;
+ TQString result;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ if ( ch < 0x80 || IsKana(ch) ) {
+ // JIS X 0201 Latin or JIS X 0201 Kana
+ u = conv->jisx0201ToUnicode(ch);
+ result += TQValidChar(u);
+ } else if ( IsSjisChar1(ch) ) {
+ // JIS X 0208
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( IsSjisChar2(c2) ) {
+ if ((u = conv->sjisibmvdcToUnicode(ch, c2))) {
+ result += TQValidChar(u);
+ } else if ((u = conv->cp932ToUnicode(ch, c2))) {
+ result += TQValidChar(u);
+ } else if ( IsUserDefinedChar1(ch) ) {
+ result += TQChar::tqreplacement;
+ } else {
+ u = conv->sjisToUnicode(ch, c2);
+ result += TQValidChar(u);
+ }
+ } else {
+ i--;
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ } else {
+ result += TQChar::tqreplacement;
+ }
+ }
+ return result;
+}
+
+/*!
+ \reimp
+*/
+const char* TQSjisCodec::name() const
+{
+ return "SJIS";
+}
+
+/*!
+ Returns the codec's mime name.
+*/
+const char* TQSjisCodec::mimeName() const
+{
+ return "Shift_JIS";
+}
+
+/*!
+ \reimp
+*/
+int TQSjisCodec::heuristicNameMatch(const char* hint) const
+{
+ int score = 0;
+ bool ja = FALSE;
+ if (qstrnicmp(hint, "ja_JP", 5) == 0 || qstrnicmp(hint, "japan", 5) == 0) {
+ score += 3;
+ ja = TRUE;
+ } else if (qstrnicmp(hint, "ja", 2) == 0) {
+ score += 2;
+ ja = TRUE;
+ }
+ const char *p;
+ if (ja) {
+ p = strchr(hint, '.');
+ if (p == 0) {
+ return score - 1;
+ }
+ p++;
+ } else {
+ p = hint;
+ }
+ if (p) {
+ if ((qstricmp(p, "mscode") == 0) ||
+ (qstricmp(p, "PCK") == 0) ||
+ (qstricmp(p, "SJIS") == 0) ||
+ (simpleHeuristicNameMatch(p, "ShiftJIS") > 0) ||
+ (simpleHeuristicNameMatch(p, "x-sjis") > 0)) {
+ return score + 4;
+ }
+ }
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+/*!
+ \reimp
+*/
+int TQSjisCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ int score = 0;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ // No nulls allowed.
+ if ( !ch || ch == Esc )
+ return -1;
+ if ( ch < 32 && ch != '\t' && ch != '\n' && ch != '\r' ) {
+ // Suspicious
+ if ( score )
+ score--;
+ } else if ( ch < 0x80 ) {
+ // Inconclusive
+ score++;
+ } else if ( IsKana(ch) ) {
+ // JIS X 0201 Kana
+ score++;
+ } else if ( IsSjisChar1(ch) ) {
+ // JIS X 0208-1990
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( !IsSjisChar2(c2) )
+ return -1;
+ score++;
+ }
+ score++;
+ } else {
+ // Invalid
+ return -1;
+ }
+ }
+ return score;
+}
+
+class TQSjisDecoder : public TQTextDecoder {
+ uchar buf[1];
+ int nbuf;
+ const TQJpUnicodeConv * const conv;
+public:
+ TQSjisDecoder(const TQJpUnicodeConv *c) : nbuf(0), conv(c)
+ {
+ }
+
+ TQString toUnicode(const char* chars, int len)
+ {
+ TQString result;
+ uint u= 0;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ switch (nbuf) {
+ case 0:
+ if ( ch < 0x80 || IsKana(ch) ) {
+ // JIS X 0201 Latin or JIS X 0201 Kana
+ u = conv->jisx0201ToUnicode(ch);
+ result += TQValidChar(u);
+ } else if ( IsSjisChar1(ch) ) {
+ // JIS X 0208
+ buf[0] = ch;
+ nbuf = 1;
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ break;
+ case 1:
+ // JIS X 0208
+ if ( IsSjisChar2(ch) ) {
+ if ((u = conv->sjisibmvdcToUnicode(buf[0], ch))) {
+ result += TQValidChar(u);
+ } else if ((u = conv->cp932ToUnicode(buf[0], ch))) {
+ result += TQValidChar(u);
+ } else if ( IsUserDefinedChar1(buf[0]) ) {
+ result += TQChar::tqreplacement;
+ } else {
+ u = conv->sjisToUnicode(buf[0], ch);
+ result += TQValidChar(u);
+ }
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ nbuf = 0;
+ break;
+ }
+ }
+ return result;
+ }
+};
+
+/*!
+ \reimp
+*/
+TQTextDecoder* TQSjisCodec::makeDecoder() const
+{
+ return new TQSjisDecoder(conv);
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqsjiscodec.h b/tqtinterface/qt4/src/codecs/tqsjiscodec.h
new file mode 100644
index 0000000..84f3359
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqsjiscodec.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Definition of TQSjisCodec class
+**
+** Created : 990225
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Most of the code here was originally written by Serika Kurusugawa
+// a.k.a. Junji Takagi, and is included in TQt with the author's permission,
+// and the grateful thanks of the Trolltech team.
+
+/*
+ * Copyright (C) 1999 Serika Kurusugawa, All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef TQSJISCODEC_H
+#define TQSJISCODEC_H
+
+#ifndef TQT_H
+#include "tqtextcodec.h"
+#include "tqjpunicode.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_BIG_CODECS
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_CODECS_JP
+#else
+#define TQ_EXPORT_CODECS_JP TQ_EXPORT
+#endif
+
+class TQ_EXPORT_CODECS_JP TQSjisCodec : public TQTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+ const char* mimeName() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+
+ TQSjisCodec();
+ ~TQSjisCodec();
+
+protected:
+ const TQJpUnicodeConv *conv;
+};
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqtextcodec.cpp b/tqtinterface/qt4/src/codecs/tqtextcodec.cpp
new file mode 100644
index 0000000..7458db6
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqtextcodec.cpp
@@ -0,0 +1,3122 @@
+/****************************************************************************
+**
+** Implementation of TQTextCodec class
+**
+** Created : 981015
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// UNIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+#include "tqtextcodec.h"
+#ifndef TQT_NO_TEXTCODEC
+
+#include "tqvaluelist.h"
+#include "tqtextcodecfactory.h"
+#include "tqutfcodec.h"
+#include "tqnamespace.h"
+#ifndef TQT_NO_CODECS
+#include "tqrtlcodec.h"
+#include "tqtsciicodec.h"
+#include "tqisciicodec_p.h"
+#endif // TQT_NO_CODECS
+#ifndef TQT_NO_BIG_CODECS
+#include "tqbig5codec.h"
+#include "tqeucjpcodec.h"
+#include "tqeuckrcodec.h"
+#include "tqgb18030codec.h"
+#include "tqjiscodec.h"
+#include "tqjpunicode.h"
+#include "tqsjiscodec.h"
+#endif // TQT_NO_BIG_CODECS
+#include "tqfile.h"
+#include "tqstrlist.h"
+#include "tqstring.h"
+#include "../tools/tqlocale_p.h"
+
+#if !defined(TQT_NO_CODECS) && !defined(TQT_NO_BIG_CODECS) && defined(TQ_WS_X11)
+# include "tqfontcodecs_p.h"
+#endif
+
+#ifdef TQT_THREAD_SUPPORT
+# include <private/tqmutexpool_p.h>
+#endif // TQT_THREAD_SUPPORT
+
+#include <stdlib.h>
+#include <ctype.h>
+#ifndef TQ_OS_TEMP
+#include <locale.h>
+#endif
+#if defined(_XOPEN_UNIX) && !defined(TQ_OS_TQNX6)
+#include <langinfo.h>
+#endif
+
+static TQValueList<TQTextCodec*> *all = 0;
+static bool destroying_is_ok; // starts out as 0
+static TQTextCodec * localeMapper = 0;
+
+class TQTextCodecCleanup {
+public:
+ ~TQTextCodecCleanup() {
+ TQTextCodec::deleteAllCodecs();
+ }
+};
+static TQTextCodecCleanup qtextcodec_cleanup;
+
+/*!
+ Deletes all the created codecs.
+
+ \warning Do not call this function.
+
+ TQApplication calls this function just before exiting to delete
+ any TQTextCodec objects that may be lying around. Since various
+ other classes hold pointers to TQTextCodec objects, it is not safe
+ to call this function earlier.
+
+ If you are using the utility classes (like TQString) but not using
+ TQApplication, calling this function at the very end of your
+ application may be helpful for chasing down memory leaks by
+ eliminating any TQTextCodec objects.
+*/
+
+void TQTextCodec::deleteAllCodecs()
+{
+ if ( !all )
+ return;
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &all ) : 0 );
+ if ( !all )
+ return;
+#endif // TQT_THREAD_SUPPORT
+
+ destroying_is_ok = TRUE;
+
+ TQValueList<TQTextCodec*> *ball = all;
+ all = 0;
+ TQValueList<TQTextCodec*>::Iterator it;
+ for ( it = ball->begin(); it != ball->end(); ++it ) {
+ delete *it;
+ *it = 0;
+ }
+ ball->clear();
+ delete ball;
+
+ destroying_is_ok = FALSE;
+}
+
+
+static void realSetup();
+
+
+static inline void setup()
+{
+ if ( all ) return;
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &all ) : 0 );
+ if ( all ) return;
+#endif // TQT_THREAD_SUPPORT
+
+ realSetup();
+}
+
+
+class TQTextStatelessEncoder: public TQTextEncoder {
+ const TQTextCodec* codec;
+public:
+ TQTextStatelessEncoder(const TQTextCodec*);
+ TQCString fromUnicode(const TQString& uc, int& lenInOut);
+};
+
+
+class TQTextStatelessDecoder : public TQTextDecoder {
+ const TQTextCodec* codec;
+public:
+ TQTextStatelessDecoder(const TQTextCodec*);
+ TQString toUnicode(const char* chars, int len);
+};
+
+TQTextStatelessEncoder::TQTextStatelessEncoder(const TQTextCodec* c) :
+ codec(c)
+{
+}
+
+
+TQCString TQTextStatelessEncoder::fromUnicode(const TQString& uc, int& lenInOut)
+{
+ return codec->fromUnicode(uc,lenInOut);
+}
+
+
+TQTextStatelessDecoder::TQTextStatelessDecoder(const TQTextCodec* c) :
+ codec(c)
+{
+}
+
+
+TQString TQTextStatelessDecoder::toUnicode(const char* chars, int len)
+{
+ return codec->toUnicode(chars,len);
+}
+
+
+
+/*!
+ \class TQTextCodec tqtextcodec.h
+ \brief The TQTextCodec class provides conversion between text encodings.
+ \reentrant
+ \ingroup i18n
+
+ TQt uses Unicode to store, draw and manipulate strings. In many
+ situations you may wish to deal with data that uses a different
+ encoding. For example, most Japanese documents are still stored in
+ Shift-JIS or ISO2022, while Russian users often have their
+ documents in KOI8-R or CP1251.
+
+ TQt provides a set of TQTextCodec classes to help with converting
+ non-Unicode formats to and from Unicode. You can also create your
+ own codec classes (\link #subclassing see later\endlink).
+
+ The supported encodings are:
+ \list
+ \i Latin1
+ \i Big5 -- Chinese
+ \i Big5-HKSCS -- Chinese
+ \i eucJP -- Japanese
+ \i eucKR -- Korean
+ \i GB2312 -- Chinese
+ \i GBK -- Chinese
+ \i GB18030 -- Chinese
+ \i JIS7 -- Japanese
+ \i Shift-JIS -- Japanese
+ \i TSCII -- Tamil
+ \i utf8 -- Unicode, 8-bit
+ \i utf16 -- Unicode
+ \i KOI8-R -- Russian
+ \i KOI8-U -- Ukrainian
+ \i ISO8859-1 -- Western
+ \i ISO8859-2 -- Central European
+ \i ISO8859-3 -- Central European
+ \i ISO8859-4 -- Baltic
+ \i ISO8859-5 -- Cyrillic
+ \i ISO8859-6 -- Arabic
+ \i ISO8859-7 -- Greek
+ \i ISO8859-8 -- Hebrew, visually ordered
+ \i ISO8859-8-i -- Hebrew, logically ordered
+ \i ISO8859-9 -- Turkish
+ \i ISO8859-10
+ \i ISO8859-13
+ \i ISO8859-14
+ \i ISO8859-15 -- Western
+ \i IBM 850
+ \i IBM 866
+ \i CP874
+ \i CP1250 -- Central European
+ \i CP1251 -- Cyrillic
+ \i CP1252 -- Western
+ \i CP1253 -- Greek
+ \i CP1254 -- Turkish
+ \i CP1255 -- Hebrew
+ \i CP1256 -- Arabic
+ \i CP1257 -- Baltic
+ \i CP1258
+ \i Apple Roman
+ \i TIS-620 -- Thai
+ \endlist
+
+ TQTextCodecs can be used as follows to convert some locally encoded
+ string to Unicode. Suppose you have some string encoded in Russian
+ KOI8-R encoding, and want to convert it to Unicode. The simple way
+ to do this is:
+
+ \code
+ TQCString locallyEncoded = "..."; // text to convert
+ TQTextCodec *codec = TQTextCodec::codecForName("KOI8-R"); // get the codec for KOI8-R
+ TQString tqunicodeString = codec->toUnicode( locallyEncoded );
+ \endcode
+
+ After this, \c{tqunicodeString} holds the text converted to Unicode.
+ Converting a string from Unicode to the local encoding is just as
+ easy:
+
+ \code
+ TQString tqunicodeString = "..."; // any Unicode text
+ TQTextCodec *codec = TQTextCodec::codecForName("KOI8-R"); // get the codec for KOI8-R
+ TQCString locallyEncoded = codec->fromUnicode( tqunicodeString );
+ \endcode
+
+ Some care must be taken when trying to convert the data in chunks,
+ for example, when receiving it over a network. In such cases it is
+ possible that a multi-byte character will be split over two
+ chunks. At best this might result in the loss of a character and
+ at worst cause the entire conversion to fail.
+
+ The approach to use in these situations is to create a TQTextDecoder
+ object for the codec and use this TQTextDecoder for the whole
+ decoding process, as shown below:
+
+ \code
+ TQTextCodec *codec = TQTextCodec::codecForName( "Shift-JIS" );
+ TQTextDecoder *decoder = codec->makeDecoder();
+
+ TQString tqunicodeString;
+ while( receiving_data ) {
+ TQByteArray chunk = new_data;
+ tqunicodeString += decoder->toUnicode( chunk.data(), chunk.length() );
+ }
+ \endcode
+
+ The TQTextDecoder object maintains state between chunks and therefore
+ works correctly even if a multi-byte character is split between
+ chunks.
+
+ \target subclassing
+ \section1 Creating your own Codec class
+
+ Support for new text encodings can be added to TQt by creating
+ TQTextCodec subclasses.
+
+ Built-in codecs can be overridden by custom codecs since more
+ recently created TQTextCodec objects take precedence over earlier
+ ones.
+
+ You may tqfind it more convenient to make your codec class available
+ as a plugin; see the \link plugins-howto.html plugin
+ documentation\endlink for more details.
+
+ The abstract virtual functions describe the encoder to the
+ system and the coder is used as required in the different
+ text file formats supported by TQTextStream, and under X11, for the
+ locale-specific character input and output.
+
+ To add support for another 8-bit encoding to TQt, make a subclass
+ of TQTextCodec and implement at least the following methods:
+
+ \code
+ const char* name() const
+ \endcode
+ Return the official name for the encoding.
+
+ \code
+ int mibEnum() const
+ \endcode
+ Return the MIB enum for the encoding if it is listed in the
+ \link http://www.iana.org/assignments/character-sets
+ IANA character-sets encoding file\endlink.
+
+ If the encoding is multi-byte then it will have "state"; that is,
+ the interpretation of some bytes will be dependent on some preceding
+ bytes. For such encodings, you must implement:
+
+ \code
+ TQTextDecoder* makeDecoder() const
+ \endcode
+ Return a TQTextDecoder that remembers incomplete multi-byte sequence
+ prefixes or other required state.
+
+ If the encoding does \e not require state, you should implement:
+
+ \code
+ TQString toUnicode(const char* chars, int len) const
+ \endcode
+ Converts \e len characters from \e chars to Unicode.
+
+ The base TQTextCodec class has default implementations of the above
+ two functions, \e{but they are mutually recursive}, so you must
+ re-implement at least one of them, or both for improved efficiency.
+
+ For conversion from Unicode to 8-bit encodings, it is rarely necessary
+ to maintain state. However, two functions similar to the two above
+ are used for encoding:
+
+ \code
+ TQTextEncoder* makeEncoder() const
+ \endcode
+ Return a TQTextEncoder.
+
+ \code
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const
+ \endcode
+ Converts \e lenInOut characters (of type TQChar) from the start of
+ the string \e uc, returning a TQCString result, and also returning
+ the \link TQCString::length() length\endlink of the result in
+ \e lenInOut.
+
+ Again, these are mutually recursive so only one needs to be implemented,
+ or both if greater efficiency is possible.
+
+ Finally, you must implement:
+
+ \code
+ int heuristicContentMatch(const char* chars, int len) const
+ \endcode
+ Gives a value indicating how likely it is that \e len characters
+ from \e chars are in the encoding.
+
+ A good model for this function is the
+ TQWindowsLocalCodec::heuristicContentMatch function found in the TQt
+ sources.
+
+ A TQTextCodec subclass might have improved performance if you also
+ re-implement:
+
+ \code
+ bool canEncode( TQChar ) const
+ \endcode
+ Test if a Unicode character can be encoded.
+
+ \code
+ bool canEncode( const TQString& ) const
+ \endcode
+ Test if a string of Unicode characters can be encoded.
+
+ \code
+ int heuristicNameMatch(const char* hint) const
+ \endcode
+ Test if a possibly non-standard name is referring to the codec.
+
+ Codecs can also be created as \link plugins-howto.html plugins\endlink.
+*/
+
+
+/*!
+ \nonreentrant
+
+ Constructs a TQTextCodec, and gives it the highest precedence. The
+ TQTextCodec should always be constructed on the heap (i.e. with \c
+ new). TQt takes ownership and will delete it when the application
+ terminates.
+*/
+TQTextCodec::TQTextCodec()
+{
+ setup();
+ all->insert( all->begin(), this );
+}
+
+
+/*!
+ \nonreentrant
+
+ Destroys the TQTextCodec. Note that you should not delete codecs
+ yourself: once created they become TQt's responsibility.
+*/
+TQTextCodec::~TQTextCodec()
+{
+ if ( !destroying_is_ok )
+ qWarning("TQTextCodec::~TQTextCodec() called by application");
+ if ( all )
+ all->remove( this );
+}
+
+
+/*!
+ Returns a value indicating how likely it is that this decoder is
+ appropriate for decoding some format that has the given name. The
+ name is compared with the \a hint.
+
+ A good match returns a positive number around the length of the
+ string. A bad match is negative.
+
+ The default implementation calls simpleHeuristicNameMatch() with
+ the name of the codec.
+*/
+int TQTextCodec::heuristicNameMatch(const char* hint) const
+{
+ return simpleHeuristicNameMatch(name(),hint);
+}
+
+
+// returns a string containing the letters and numbers from input,
+// with a space separating run of a character class. e.g. "iso8859-1"
+// becomes "iso 8859 1"
+static TQString lettersAndNumbers( const char * input )
+{
+ TQString result;
+ TQChar c;
+
+ while( input && *input ) {
+ c = *input;
+ if ( c.isLetter() || c.isNumber() )
+ result += c.lower();
+ if ( input[1] ) {
+ // add space at character class transition, except
+ // transition from upper-case to lower-case letter
+ TQChar n( input[1] );
+ if ( c.isLetter() && n.isLetter() ) {
+ if ( c == c.lower() && n == n.upper() )
+ result += ' ';
+ } else if ( c.category() != n.category() ) {
+ result += ' ';
+ }
+ }
+ input++;
+ }
+ return result.simplifyWhiteSpace();
+}
+
+/*!
+ A simple utility function for heuristicNameMatch(): it does some
+ very minor character-skipping so that almost-exact matches score
+ high. \a name is the text we're matching and \a hint is used for
+ the comparison.
+*/
+int TQTextCodec::simpleHeuristicNameMatch(const char* name, const char* hint)
+{
+ // if they're the same, return a perfect score.
+ if ( name && hint && *name && *hint && qstricmp( name, hint ) == 0 )
+ return tqstrlen( hint );
+
+ // if the letters and numbers are the same, we have an "almost"
+ // perfect match.
+ TQString h( lettersAndNumbers( hint ) );
+ TQString n( lettersAndNumbers( name ) );
+ if ( h == n )
+ return tqstrlen( hint )-1;
+
+ if ( h.stripWhiteSpace() == n.stripWhiteSpace() )
+ return tqstrlen( hint )-2;
+
+ // could do some more here, but I don't think it's worth it
+
+ return 0;
+}
+
+
+/*!
+ Returns the TQTextCodec \a i positions from the most recently
+ inserted codec, or 0 if there is no such TQTextCodec. Thus,
+ codecForIndex(0) returns the most recently created TQTextCodec.
+*/
+TQTextCodec* TQTextCodec::codecForIndex(int i)
+{
+ setup();
+ return (uint)i >= all->count() ? 0 : *all->at(i);
+}
+
+
+/*!
+ Returns the TQTextCodec which matches the \link
+ TQTextCodec::mibEnum() MIBenum\endlink \a mib.
+*/
+TQTextCodec* TQTextCodec::codecForMib(int mib)
+{
+ setup();
+ TQValueList<TQTextCodec*>::ConstIterator i;
+ TQTextCodec* result=0;
+ for ( i = all->begin(); i != all->end(); ++i ) {
+ result = *i;
+ if ( result->mibEnum()==mib )
+ return result;
+ }
+
+#if !defined(TQT_NO_COMPONENT) && !defined(TQT_LITE_COMPONENT)
+ if ( !result || (result && result->mibEnum() != mib) ) {
+ TQTextCodec *codec = TQTextCodecFactory::createForMib(mib);
+ if (codec)
+ result = codec;
+ }
+#endif // !TQT_NO_COMPONENT !TQT_LITE_COMPONENT
+
+ return result;
+}
+
+
+
+
+
+#ifdef TQ_OS_WIN32
+class TQWindowsLocalCodec: public TQTextCodec
+{
+public:
+ TQWindowsLocalCodec();
+ ~TQWindowsLocalCodec();
+
+ TQString toUnicode(const char* chars, int len) const;
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+
+ const char* name() const;
+ int mibEnum() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+
+ TQTextDecoder* makeDecoder() const;
+};
+
+TQWindowsLocalCodec::TQWindowsLocalCodec()
+{
+}
+
+TQWindowsLocalCodec::~TQWindowsLocalCodec()
+{
+}
+
+
+TQString TQWindowsLocalCodec::toUnicode(const char* chars, int len) const
+{
+ if ( len == 1 && chars ) { // Optimization; avoids allocation
+ char c[2];
+ c[0] = *chars;
+ c[1] = 0;
+ return qt_winMB2TQString( c, 2 );
+ }
+ if ( len < 0 )
+ return qt_winMB2TQString( chars );
+ TQCString s(chars,len+1);
+ return qt_winMB2TQString(s);
+}
+
+TQCString TQWindowsLocalCodec::fromUnicode(const TQString& uc, int& lenInOut ) const
+{
+ TQCString r = qt_winTQString2MB( uc, lenInOut );
+ lenInOut = r.length();
+ return r;
+}
+
+
+const char* TQWindowsLocalCodec::name() const
+{
+ return "System";
+}
+
+int TQWindowsLocalCodec::mibEnum() const
+{
+ return 0;
+}
+
+
+int TQWindowsLocalCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ // ### Not a bad default implementation?
+ TQString t = toUnicode(chars,len);
+ int l = t.length();
+ TQCString mb = fromUnicode(t,l);
+ int i=0;
+ while ( i < len ) {
+ if ( chars[i] == mb[i] )
+ i++;
+ else
+ break;
+ }
+ return i;
+}
+
+class TQWindowsLocalDecoder: public TQTextDecoder
+{
+ const TQWindowsLocalCodec* codec;
+ int nbuf;
+ uchar buf[4]; // hopefully this will be enough
+public:
+ TQWindowsLocalDecoder(const TQWindowsLocalCodec *c) : codec(c), nbuf(0)
+ {
+ }
+
+ TQString toUnicode(const char* chars, int len)
+ {
+ if (len != 1 && nbuf == 0)
+ return codec->toUnicode(chars, len);
+ if (len == 1) {
+ char c[sizeof buf + 2];
+ memcpy(c, buf, nbuf);
+ c[nbuf] = *chars;
+ c[nbuf+1] = 0;
+
+ // try to decode this:
+ TQString retval = codec->toUnicode(c, -1);
+ if ( retval.isEmpty() ) {
+ // it didn't return anything; we probably stopped mid-way in a multi-byte
+ // character
+ buf[nbuf++] = *chars;
+ if (nbuf + 1 == sizeof buf) {
+ qWarning("TQWindowsLocalDecoder: exceeded max internal buffer size");
+ nbuf = 0;
+ }
+ }
+ else
+ nbuf = 0; // decoded successfully
+
+ return retval;
+ }
+
+ if (len == -1)
+ len = (int)strlen(chars);
+
+ // Ugh! We need to allocate memory
+ char *s = new char[nbuf + len + 1];
+ memcpy(s, buf, nbuf);
+ memcpy(s + nbuf, chars, len);
+ s[nbuf + len] = 0;
+
+ TQString retval = codec->toUnicode(s, -1);
+ nbuf = 0;
+ delete[] s;
+ return retval;
+ }
+};
+
+TQTextDecoder* TQWindowsLocalCodec::makeDecoder() const
+{
+ return new TQWindowsLocalDecoder(this);
+}
+
+#else
+
+/* locale names mostly copied from XFree86 */
+static const char * const iso8859_2locales[] = {
+ "croatian", "cs", "cs_CS", "cs_CZ","cz", "cz_CZ", "czech", "hr",
+ "hr_HR", "hu", "hu_HU", "hungarian", "pl", "pl_PL", "polish", "ro",
+ "ro_RO", "rumanian", "serbocroatian", "sh", "sh_SP", "sh_YU", "sk",
+ "sk_SK", "sl", "sl_CS", "sl_SI", "slovak", "slovene", "sr_SP", 0 };
+
+static const char * const iso8859_3locales[] = {
+ "eo", 0 };
+
+static const char * const iso8859_4locales[] = {
+ "ee", "ee_EE", 0 };
+
+static const char * const iso8859_5locales[] = {
+ "mk", "mk_MK", "sp", "sp_YU", 0 };
+
+static const char * const cp_1251locales[] = {
+ "be", "be_BY", "bg", "bg_BG", "bulgarian", 0 };
+
+static const char * const pt_154locales[] = {
+ "ba_RU", "ky", "ky_KG", "kk", "kk_KZ", 0 };
+
+static const char * const iso8859_6locales[] = {
+ "ar_AA", "ar_SA", "arabic", 0 };
+
+static const char * const iso8859_7locales[] = {
+ "el", "el_GR", "greek", 0 };
+
+static const char * const iso8859_8locales[] = {
+ "hebrew", "he", "he_IL", "iw", "iw_IL", 0 };
+
+static const char * const iso8859_9locales[] = {
+ "tr", "tr_TR", "turkish", 0 };
+
+static const char * const iso8859_13locales[] = {
+ "lt", "lt_LT", "lv", "lv_LV", 0 };
+
+static const char * const iso8859_15locales[] = {
+ "et", "et_EE",
+ // Euro countries
+ "br_FR", "ca_ES", "de", "de_AT", "de_BE", "de_DE", "de_LU", "en_IE",
+ "es", "es_ES", "eu_ES", "fi", "fi_FI", "finnish", "fr", "fr_FR",
+ "fr_BE", "fr_LU", "french", "ga_IE", "gl_ES", "it", "it_IT", "oc_FR",
+ "nl", "nl_BE", "nl_NL", "pt", "pt_PT", "sv_FI", "wa_BE",
+ 0 };
+
+static const char * const koi8_ulocales[] = {
+ "uk", "uk_UA", "ru_UA", "ukrainian", 0 };
+
+static const char * const tis_620locales[] = {
+ "th", "th_TH", "thai", 0 };
+
+static const char * const tcvnlocales[] = {
+ "vi", "vi_VN", 0 };
+
+static bool try_locale_list( const char * const locale[], const char * lang )
+{
+ int i;
+ for( i=0; locale[i] && *locale[i] && strcmp(locale[i], lang); i++ )
+ ;
+ return locale[i] != 0;
+}
+
+// For the probably_koi8_locales we have to look. the standard says
+// these are 8859-5, but almost all Russian users use KOI8-R and
+// incorrectly set $LANG to ru_RU. We'll check tolower() to see what
+// tolower() thinks ru_RU means.
+
+// If you read the history, it seems that many Russians blame ISO and
+// Perestroika for the confusion.
+//
+// The real bug is that some programs break if the user specifies
+// ru_RU.KOI8-R.
+
+static const char * const probably_koi8_rlocales[] = {
+ "ru", "ru_SU", "ru_RU", "russian", 0 };
+
+static TQTextCodec * ru_RU_hack( const char * i ) {
+ TQTextCodec * ru_RU_codec = 0;
+
+ TQCString origlocale = setlocale( LC_CTYPE, i );
+ // tqunicode koi8r latin5 name
+ // 0x044E 0xC0 0xEE CYRILLIC SMALL LETTER YU
+ // 0x042E 0xE0 0xCE CYRILLIC CAPITAL LETTER YU
+ int latin5 = tolower( 0xCE );
+ int koi8r = tolower( 0xE0 );
+ if ( koi8r == 0xC0 && latin5 != 0xEE ) {
+ ru_RU_codec = TQTextCodec::codecForName( "KOI8-R" );
+ } else if ( koi8r != 0xC0 && latin5 == 0xEE ) {
+ ru_RU_codec = TQTextCodec::codecForName( "ISO 8859-5" );
+ } else {
+ // something else again... let's assume... *throws dice*
+ ru_RU_codec = TQTextCodec::codecForName( "KOI8-R" );
+ qWarning( "TQTextCodec: using KOI8-R, probe failed (%02x %02x %s)",
+ koi8r, latin5, i );
+ }
+ setlocale( LC_CTYPE, origlocale.data() );
+
+ return ru_RU_codec;
+}
+
+#endif
+
+/*!
+ Set the codec to \a c; this will be returned by codecForLocale().
+ This might be needed for some applications that want to use their
+ own mechanism for setting the locale.
+
+ \sa codecForLocale()
+*/
+void TQTextCodec::setCodecForLocale(TQTextCodec *c) {
+ localeMapper = c;
+}
+
+/*! Returns a pointer to the codec most suitable for this locale. */
+
+TQTextCodec* TQTextCodec::codecForLocale()
+{
+ if ( localeMapper )
+ return localeMapper;
+
+ setup();
+
+ return localeMapper;
+}
+
+
+/*!
+ Searches all installed TQTextCodec objects and returns the one
+ which best matches \a name; the match is case-insensitive. Returns
+ 0 if no codec's heuristicNameMatch() reports a match better than
+ \a accuracy, or if \a name is a null string.
+
+ \sa heuristicNameMatch()
+*/
+
+TQTextCodec* TQTextCodec::codecForName( const char* name, int accuracy )
+{
+ if ( !name || !*name )
+ return 0;
+
+ setup();
+ TQValueList<TQTextCodec*>::ConstIterator i;
+ TQTextCodec* result = 0;
+ int best = accuracy;
+ TQTextCodec* cursor;
+ for ( i = all->begin(); i != all->end(); ++i ) {
+ cursor = *i;
+ int s = cursor->heuristicNameMatch( name );
+ if ( s > best ) {
+ best = s;
+ result = cursor;
+ }
+ }
+
+#if !defined(TQT_NO_COMPONENT) && !defined(TQT_LITE_COMPONENT)
+ if ( !result )
+ result = TQTextCodecFactory::createForName(name);
+#endif // !TQT_NO_COMPONENT !TQT_LITE_COMPONENT
+
+ return result;
+}
+
+
+/*!
+ Searches all installed TQTextCodec objects, returning the one which
+ most recognizes the given content. May return 0.
+
+ Note that this is often a poor choice, since character encodings
+ often use most of the available character sequences, and so only
+ by linguistic analysis could a true match be made.
+
+ \a chars tqcontains the string to check, and \a len tqcontains the
+ number of characters in the string to use.
+
+ \sa heuristicContentMatch()
+*/
+TQTextCodec* TQTextCodec::codecForContent(const char* chars, int len)
+{
+ setup();
+ TQValueList<TQTextCodec*>::ConstIterator i;
+ TQTextCodec* result = 0;
+ int best=0;
+ TQTextCodec* cursor;
+ for ( i = all->begin(); i != all->end(); ++i ) {
+ cursor = *i;
+ int s = cursor->heuristicContentMatch(chars,len);
+ if ( s > best ) {
+ best = s;
+ result = cursor;
+ }
+ }
+ return result;
+}
+
+
+/*!
+ \fn const char* TQTextCodec::name() const
+
+ TQTextCodec subclasses must reimplement this function. It returns
+ the name of the encoding supported by the subclass. When choosing
+ a name for an encoding, consider these points:
+ \list
+ \i On X11, heuristicNameMatch( const char * hint )
+ is used to test if a the TQTextCodec
+ can convert between Unicode and the encoding of a font
+ with encoding \e hint, such as "iso8859-1" for Latin-1 fonts,
+ "koi8-r" for Russian KOI8 fonts.
+ The default algorithm of heuristicNameMatch() uses name().
+ \i Some applications may use this function to present
+ encodings to the end user.
+ \endlist
+ */
+
+/*!
+ \fn int TQTextCodec::mibEnum() const
+
+ Subclasses of TQTextCodec must reimplement this function. It
+ returns the MIBenum (see \link
+ http://www.iana.org/assignments/character-sets the
+ IANA character-sets encoding file\endlink for more information).
+ It is important that each TQTextCodec subclass returns the correct
+ unique value for this function.
+*/
+
+
+/*!
+ Returns the preferred mime name of the encoding as defined in the
+ \link http://www.iana.org/assignments/character-sets
+ IANA character-sets encoding file\endlink.
+*/
+const char* TQTextCodec::mimeName() const
+{
+ return name();
+}
+
+
+/*!
+ \fn int TQTextCodec::heuristicContentMatch(const char* chars, int len) const
+
+ TQTextCodec subclasses must reimplement this function. It examines
+ the first \a len bytes of \a chars and returns a value indicating
+ how likely it is that the string is a prefix of text encoded in
+ the encoding of the subclass. A negative return value indicates
+ that the text is detectably not in the encoding (e.g. it tqcontains
+ characters undefined in the encoding). A return value of 0
+ indicates that the text should be decoded with this codec rather
+ than as ASCII, but there is no particular evidence. The value
+ should range up to \a len. Thus, most decoders will return -1, 0,
+ or -\a len.
+
+ The characters are not null terminated.
+
+ \sa codecForContent().
+*/
+
+
+/*!
+ Creates a TQTextDecoder which stores enough state to decode chunks
+ of char* data to create chunks of Unicode data. The default
+ implementation creates a stateless decoder, which is only
+ sufficient for the simplest encodings where each byte corresponds
+ to exactly one Unicode character.
+
+ The caller is responsible for deleting the returned object.
+*/
+TQTextDecoder* TQTextCodec::makeDecoder() const
+{
+ return new TQTextStatelessDecoder(this);
+}
+
+
+/*!
+ Creates a TQTextEncoder which stores enough state to encode chunks
+ of Unicode data as char* data. The default implementation creates
+ a stateless encoder, which is only sufficient for the simplest
+ encodings where each Unicode character corresponds to exactly one
+ character.
+
+ The caller is responsible for deleting the returned object.
+*/
+TQTextEncoder* TQTextCodec::makeEncoder() const
+{
+ return new TQTextStatelessEncoder(this);
+}
+
+
+/*!
+ TQTextCodec subclasses must reimplement this function or
+ makeDecoder(). It converts the first \a len characters of \a chars
+ to Unicode.
+
+ The default implementation makes a decoder with makeDecoder() and
+ converts the input with that. Note that the default makeDecoder()
+ implementation makes a decoder that simply calls
+ this function, hence subclasses \e must reimplement one function or
+ the other to avoid infinite recursion.
+*/
+TQString TQTextCodec::toUnicode(const char* chars, int len) const
+{
+ if ( chars == 0 )
+ return TQString::null;
+ TQTextDecoder* i = makeDecoder();
+ TQString result = i->toUnicode(chars,len);
+ delete i;
+ return result;
+}
+
+
+/*!
+ TQTextCodec subclasses must reimplement either this function or
+ makeEncoder(). It converts the first \a lenInOut characters of \a
+ uc from Unicode to the encoding of the subclass. If \a lenInOut is
+ negative or too large, the length of \a uc is used instead.
+
+ Converts \a lenInOut characters (not bytes) from \a uc, producing
+ a TQCString. \a lenInOut will be set to the \link
+ TQCString::length() length\endlink of the result (in bytes).
+
+ The default implementation makes an encoder with makeEncoder() and
+ converts the input with that. Note that the default makeEncoder()
+ implementation makes an encoder that simply calls this function,
+ hence subclasses \e must reimplement one function or the other to
+ avoid infinite recursion.
+*/
+
+TQCString TQTextCodec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ TQTextEncoder* i = makeEncoder();
+ TQCString result = i->fromUnicode(uc, lenInOut);
+ delete i;
+ return result;
+}
+
+/*!
+ \overload
+ \internal
+*/
+TQByteArray TQTextCodec::fromUnicode( const TQString &str, int pos, int len ) const
+{
+ TQByteArray a;
+ if( len < 0 )
+ len = str.length() - pos;
+ a = fromUnicode( str.mid(pos, len) );
+
+ if( a.size() > 0 && a[(int)a.size() - 1] == '\0' )
+ a.resize( a.size() - 1 );
+ return a;
+}
+
+/*!
+ \overload
+
+ \a uc is the tqunicode source string.
+*/
+TQCString TQTextCodec::fromUnicode(const TQString& uc) const
+{
+ int l = uc.length();
+ return fromUnicode(uc,l);
+}
+
+/*!
+ \overload
+
+ \a a tqcontains the source characters; \a len tqcontains the number of
+ characters in \a a to use.
+*/
+TQString TQTextCodec::toUnicode(const TQByteArray& a, int len) const
+{
+ int l = a.size();
+ l = TQMIN( l, len );
+ return toUnicode( a.data(), l );
+}
+
+/*!
+ \overload
+
+ \a a tqcontains the source characters.
+*/
+TQString TQTextCodec::toUnicode(const TQByteArray& a) const
+{
+ int l = a.size();
+ return toUnicode( a.data(), l );
+}
+
+/*!
+ \overload
+
+ \a a tqcontains the source characters; \a len tqcontains the number of
+ characters in \a a to use.
+*/
+TQString TQTextCodec::toUnicode(const TQCString& a, int len) const
+{
+ int l = a.length();
+ l = TQMIN( l, len );
+ return toUnicode( a.data(), l );
+}
+
+/*!
+ \overload
+
+ \a a tqcontains the source characters.
+*/
+TQString TQTextCodec::toUnicode(const TQCString& a) const
+{
+ int l = a.length();
+ return toUnicode( a.data(), l );
+}
+
+/*!
+ \overload
+
+ \a chars tqcontains the source characters.
+*/
+TQString TQTextCodec::toUnicode(const char* chars) const
+{
+ return toUnicode(chars,tqstrlen(chars));
+}
+
+/*!
+ \internal
+*/
+unsigned short TQTextCodec::characterFromUnicode(const TQString &str, int pos) const
+{
+ TQCString result = TQTextCodec::fromUnicode(TQString(str[pos]));
+ uchar *ch = (uchar *) result.data();
+ ushort retval = 0;
+ if (result.size() > 2) {
+ retval = (ushort) *ch << 8;
+ ch++;
+ }
+ return retval + *ch;
+}
+
+/*!
+ Returns TRUE if the Unicode character \a ch can be fully encoded
+ with this codec; otherwise returns FALSE. The default
+ implementation tests if the result of toUnicode(fromUnicode(ch))
+ is the original \a ch. Subclasses may be able to improve the
+ efficiency.
+*/
+bool TQTextCodec::canEncode( TQChar ch ) const
+{
+ return toUnicode(fromUnicode(ch)) == ch;
+}
+
+/*!
+ \overload
+
+ \a s tqcontains the string being tested for encode-ability.
+*/
+bool TQTextCodec::canEncode( const TQString& s ) const
+{
+ if ( s.isEmpty() )
+ return TRUE;
+ return toUnicode(fromUnicode(s)) == s;
+}
+
+
+
+/*!
+ \class TQTextEncoder tqtextcodec.h
+ \brief The TQTextEncoder class provides a state-based encoder.
+ \reentrant
+ \ingroup i18n
+
+ The encoder converts Unicode into another format, remembering any
+ state that is required between calls.
+
+ \sa TQTextCodec::makeEncoder()
+*/
+
+/*!
+ Destroys the encoder.
+*/
+TQTextEncoder::~TQTextEncoder()
+{
+}
+
+/*!
+ \fn TQCString TQTextEncoder::fromUnicode(const TQString& uc, int& lenInOut)
+
+ Converts \a lenInOut characters (not bytes) from \a uc, producing
+ a TQCString. \a lenInOut will be set to the \link
+ TQCString::length() length\endlink of the result (in bytes).
+
+ The encoder is free to record state to use when subsequent calls
+ are made to this function (for example, it might change modes with
+ escape sequences if needed during the encoding of one string, then
+ assume that mode applies when a subsequent call begins).
+*/
+
+/*!
+ \class TQTextDecoder tqtextcodec.h
+ \brief The TQTextDecoder class provides a state-based decoder.
+ \reentrant
+ \ingroup i18n
+
+ The decoder converts a text format into Unicode, remembering any
+ state that is required between calls.
+
+ \sa TQTextCodec::makeEncoder()
+*/
+
+
+/*!
+ Destroys the decoder.
+*/
+TQTextDecoder::~TQTextDecoder()
+{
+}
+
+/*!
+ \fn TQString TQTextDecoder::toUnicode(const char* chars, int len)
+
+ Converts the first \a len bytes in \a chars to Unicode, returning
+ the result.
+
+ If not all characters are used (e.g. if only part of a multi-byte
+ encoding is at the end of the characters), the decoder remembers
+ enough state to continue with the next call to this function.
+*/
+
+#define CHAINED 0xffff
+
+struct TQMultiByteUnicodeTable {
+ // If multiByte, ignore tqunicode and index into multiByte
+ // with the next character.
+ TQMultiByteUnicodeTable() : tqunicode(0xfffd), multiByte(0) { }
+
+ ~TQMultiByteUnicodeTable()
+ {
+ if ( multiByte )
+ delete [] multiByte;
+ }
+
+ ushort tqunicode;
+ TQMultiByteUnicodeTable* multiByte;
+};
+
+static int getByte(char* &cursor)
+{
+ int byte = 0;
+ if ( *cursor ) {
+ if ( cursor[1] == 'x' )
+ byte = strtol(cursor+2,&cursor,16);
+ else if ( cursor[1] == 'd' )
+ byte = strtol(cursor+2,&cursor,10);
+ else
+ byte = strtol(cursor+2,&cursor,8);
+ }
+ return byte&0xff;
+}
+
+class TQTextCodecFromIOD;
+
+class TQTextCodecFromIODDecoder : public TQTextDecoder {
+ const TQTextCodecFromIOD* codec;
+ TQMultiByteUnicodeTable* mb;
+public:
+ TQTextCodecFromIODDecoder(const TQTextCodecFromIOD* c);
+ TQString toUnicode(const char* chars, int len);
+};
+
+class TQTextCodecFromIOD : public TQTextCodec {
+ friend class TQTextCodecFromIODDecoder;
+
+ TQCString n;
+
+ // If from_tqunicode_page[row()][cell()] is 0 and from_tqunicode_page_multiByte,
+ // use from_tqunicode_page_multiByte[row()][cell()] as string.
+ char** from_tqunicode_page;
+ char*** from_tqunicode_page_multiByte;
+ char unkn;
+
+ // Only one of these is used
+ ushort* to_tqunicode;
+ TQMultiByteUnicodeTable* to_tqunicode_multiByte;
+ int max_bytes_per_char;
+ TQStrList aliases;
+
+ bool stateless() const { return !to_tqunicode_multiByte; }
+
+public:
+ TQTextCodecFromIOD(TQIODevice* iod)
+ {
+ from_tqunicode_page = 0;
+ to_tqunicode_multiByte = 0;
+ to_tqunicode = 0;
+ from_tqunicode_page_multiByte = 0;
+ max_bytes_per_char = 1;
+
+ const int maxlen=100;
+ char line[maxlen];
+ char esc='\\';
+ char comm='%';
+ bool incmap = FALSE;
+ while (iod->readLine(line,maxlen) > 0) {
+ if (0==qstrnicmp(line,"<code_set_name>",15))
+ n = line+15;
+ else if (0==qstrnicmp(line,"<escape_char> ",14))
+ esc = line[14];
+ else if (0==qstrnicmp(line,"<comment_char> ",15))
+ comm = line[15];
+ else if (line[0]==comm && 0==qstrnicmp(line+1," alias ",7)) {
+ aliases.append(line+8);
+ } else if (0==qstrnicmp(line,"CHARMAP",7)) {
+ if (!from_tqunicode_page) {
+ from_tqunicode_page = new char*[256];
+ for (int i=0; i<256; i++)
+ from_tqunicode_page[i]=0;
+ }
+ if (!to_tqunicode) {
+ to_tqunicode = new ushort[256];
+ }
+ incmap = TRUE;
+ } else if (0==qstrnicmp(line,"END CHARMAP",11))
+ break;
+ else if (incmap) {
+ char* cursor = line;
+ int byte=-1,tqunicode=-1;
+ ushort* mb_tqunicode=0;
+ const int maxmb=8; // more -> we'll need to improve datastructures
+ char mb[maxmb+1];
+ int nmb=0;
+
+ while (*cursor) {
+ if (cursor[0]=='<' && cursor[1]=='U' &&
+ cursor[2]>='0' && cursor[2]<='9' &&
+ cursor[3]>='0' && cursor[3]<='9') {
+
+ tqunicode = strtol(cursor+2,&cursor,16);
+
+ } else if (*cursor==esc) {
+
+ byte = getByte(cursor);
+
+ if ( *cursor == esc ) {
+ if ( !to_tqunicode_multiByte ) {
+ to_tqunicode_multiByte =
+ new TQMultiByteUnicodeTable[256];
+ for (int i=0; i<256; i++) {
+ to_tqunicode_multiByte[i].tqunicode =
+ to_tqunicode[i];
+ to_tqunicode_multiByte[i].multiByte = 0;
+ }
+ delete [] to_tqunicode;
+ to_tqunicode = 0;
+ }
+ TQMultiByteUnicodeTable* mbut =
+ to_tqunicode_multiByte+byte;
+ mb[nmb++] = byte;
+ while ( nmb < maxmb && *cursor == esc ) {
+ // Always at least once
+
+ mbut->tqunicode = CHAINED;
+ byte = getByte(cursor);
+ mb[nmb++] = byte;
+ if (!mbut->multiByte) {
+ mbut->multiByte =
+ new TQMultiByteUnicodeTable[256];
+ }
+ mbut = mbut->multiByte+byte;
+ mb_tqunicode = & mbut->tqunicode;
+ }
+
+ if ( nmb > max_bytes_per_char )
+ max_bytes_per_char = nmb;
+ }
+ } else {
+ cursor++;
+ }
+ }
+
+ if (tqunicode >= 0 && tqunicode <= 0xffff)
+ {
+ TQChar ch((ushort)tqunicode);
+ if (!from_tqunicode_page[ch.row()]) {
+ from_tqunicode_page[ch.row()] = new char[256];
+ for (int i=0; i<256; i++)
+ from_tqunicode_page[ch.row()][i]=0;
+ }
+ if ( mb_tqunicode ) {
+ from_tqunicode_page[ch.row()][ch.cell()] = 0;
+ if (!from_tqunicode_page_multiByte) {
+ from_tqunicode_page_multiByte = new char**[256];
+ for (int i=0; i<256; i++)
+ from_tqunicode_page_multiByte[i]=0;
+ }
+ if (!from_tqunicode_page_multiByte[ch.row()]) {
+ from_tqunicode_page_multiByte[ch.row()] = new char*[256];
+ for (int i=0; i<256; i++)
+ from_tqunicode_page_multiByte[ch.row()][i] = 0;
+ }
+ mb[nmb++] = 0;
+ from_tqunicode_page_multiByte[ch.row()][ch.cell()]
+ = qstrdup(mb);
+ *mb_tqunicode = tqunicode;
+ } else {
+ from_tqunicode_page[ch.row()][ch.cell()] = (char)byte;
+ if ( to_tqunicode )
+ to_tqunicode[byte] = tqunicode;
+ else
+ to_tqunicode_multiByte[byte].tqunicode = tqunicode;
+ }
+ } else {
+ }
+ }
+ }
+ n = n.stripWhiteSpace();
+
+ unkn = '?'; // ##### Might be a bad choice.
+ }
+
+ ~TQTextCodecFromIOD()
+ {
+ if ( from_tqunicode_page ) {
+ for (int i=0; i<256; i++)
+ if (from_tqunicode_page[i])
+ delete [] from_tqunicode_page[i];
+ }
+ if ( from_tqunicode_page_multiByte ) {
+ for (int i=0; i<256; i++)
+ if (from_tqunicode_page_multiByte[i])
+ for (int j=0; j<256; j++)
+ if (from_tqunicode_page_multiByte[i][j])
+ delete [] from_tqunicode_page_multiByte[i][j];
+ }
+ if ( to_tqunicode )
+ delete [] to_tqunicode;
+ if ( to_tqunicode_multiByte )
+ delete [] to_tqunicode_multiByte;
+ }
+
+ bool ok() const
+ {
+ return !!from_tqunicode_page;
+ }
+
+ TQTextDecoder* makeDecoder() const
+ {
+ if ( stateless() )
+ return TQTextCodec::makeDecoder();
+ else
+ return new TQTextCodecFromIODDecoder(this);
+ }
+
+ const char* name() const
+ {
+ return n;
+ }
+
+ int mibEnum() const
+ {
+ return 0; // #### Unknown.
+ }
+
+ int heuristicContentMatch(const char*, int) const
+ {
+ return 0;
+ }
+
+ int heuristicNameMatch(const char* hint) const
+ {
+ int bestr = TQTextCodec::heuristicNameMatch(hint);
+ TQStrListIterator it(aliases);
+ char* a;
+ while ((a=it.current())) {
+ ++it;
+ int r = simpleHeuristicNameMatch(a,hint);
+ if (r > bestr)
+ bestr = r;
+ }
+ return bestr;
+ }
+
+ TQString toUnicode(const char* chars, int len) const
+ {
+ const uchar* uchars = (const uchar*)chars;
+ TQString result;
+ TQMultiByteUnicodeTable* multiByte=to_tqunicode_multiByte;
+ if ( multiByte ) {
+ while (len--) {
+ TQMultiByteUnicodeTable& mb = multiByte[*uchars];
+ if ( mb.multiByte ) {
+ // Chained multi-byte
+ multiByte = mb.multiByte;
+ } else {
+ result += TQChar(mb.tqunicode);
+ multiByte=to_tqunicode_multiByte;
+ }
+ uchars++;
+ }
+ } else {
+ while (len--)
+ result += TQChar(to_tqunicode[*uchars++]);
+ }
+ return result;
+ }
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const
+ {
+ if (lenInOut > (int)uc.length())
+ lenInOut = uc.length();
+ int rlen = lenInOut*max_bytes_per_char;
+ TQCString rstr(rlen+1);
+ char* cursor = rstr.data();
+ char* s=0;
+ int l = lenInOut;
+ int lout = 0;
+ for (int i=0; i<l; i++) {
+ TQChar ch = uc[i];
+ if ( ch == TQChar::null ) {
+ // special
+ *cursor++ = 0;
+ } else if ( from_tqunicode_page[ch.row()] &&
+ from_tqunicode_page[ch.row()][ch.cell()] )
+ {
+ *cursor++ = from_tqunicode_page[ch.row()][ch.cell()];
+ lout++;
+ } else if ( from_tqunicode_page_multiByte &&
+ from_tqunicode_page_multiByte[ch.row()] &&
+ (s=from_tqunicode_page_multiByte[ch.row()][ch.cell()]) )
+ {
+ while (*s) {
+ *cursor++ = *s++;
+ lout++;
+ }
+ } else {
+ *cursor++ = unkn;
+ lout++;
+ }
+ }
+ *cursor = 0;
+ lenInOut = lout;
+ return rstr;
+ }
+};
+
+TQTextCodecFromIODDecoder::TQTextCodecFromIODDecoder(const TQTextCodecFromIOD* c) :
+ codec(c)
+{
+ mb = codec->to_tqunicode_multiByte;
+}
+
+TQString TQTextCodecFromIODDecoder::toUnicode(const char* chars, int len)
+{
+ const uchar* uchars = (const uchar*)chars;
+ TQString result;
+ while (len--) {
+ TQMultiByteUnicodeTable& t = mb[*uchars];
+ if ( t.multiByte ) {
+ // Chained multi-byte
+ mb = t.multiByte;
+ } else {
+ if ( t.tqunicode )
+ result += TQChar(t.tqunicode);
+ mb=codec->to_tqunicode_multiByte;
+ }
+ uchars++;
+ }
+ return result;
+}
+
+#ifndef TQT_NO_CODECS
+// Cannot use <pre> or \code
+/*!
+ Reads a POSIX2 charmap definition from \a iod.
+ The parser recognizes the following lines:
+
+<font name="sans">
+&nbsp;&nbsp;&lt;code_set_name&gt; <i>name</i></br>
+&nbsp;&nbsp;&lt;escape_char&gt; <i>character</i></br>
+&nbsp;&nbsp;% alias <i>alias</i></br>
+&nbsp;&nbsp;CHARMAP</br>
+&nbsp;&nbsp;&lt;<i>token</i>&gt; /x<i>hexbyte</i> &lt;U<i>tqunicode</i>&gt; ...</br>
+&nbsp;&nbsp;&lt;<i>token</i>&gt; /d<i>decbyte</i> &lt;U<i>tqunicode</i>&gt; ...</br>
+&nbsp;&nbsp;&lt;<i>token</i>&gt; /<i>octbyte</i> &lt;U<i>tqunicode</i>&gt; ...</br>
+&nbsp;&nbsp;&lt;<i>token</i>&gt; /<i>any</i>/<i>any</i>... &lt;U<i>tqunicode</i>&gt; ...</br>
+&nbsp;&nbsp;END CHARMAP</br>
+</font>
+
+ The resulting TQTextCodec is returned (and also added to the global
+ list of codecs). The name() of the result is taken from the
+ code_set_name.
+
+ Note that a codec constructed in this way uses much more memory
+ and is slower than a hand-written TQTextCodec subclass, since
+ tables in code are kept in memory shared by all TQt applications.
+
+ \sa loadCharmapFile()
+*/
+TQTextCodec* TQTextCodec::loadCharmap(TQIODevice* iod)
+{
+ TQTextCodecFromIOD* r = new TQTextCodecFromIOD(iod);
+ if ( !r->ok() ) {
+ delete r;
+ r = 0;
+ }
+ return r;
+}
+
+/*!
+ A convenience function for loadCharmap() that loads the charmap
+ definition from the file \a filename.
+*/
+TQTextCodec* TQTextCodec::loadCharmapFile(TQString filename)
+{
+ TQFile f(filename);
+ if (f.open(IO_ReadOnly)) {
+ TQTextCodecFromIOD* r = new TQTextCodecFromIOD(TQT_TQIODEVICE(&f));
+ if ( !r->ok() )
+ delete r;
+ else
+ return r;
+ }
+ return 0;
+}
+
+#endif //TQT_NO_CODECS
+
+/*!
+ Returns a string representing the current language and
+ sublanguage, e.g. "pt" for Portuguese, or "pt_br" for Portuguese/Brazil.
+*/
+
+const char* TQTextCodec::locale()
+{
+ return TQLocalePrivate::systemLocaleName();
+}
+
+#ifndef TQT_NO_CODECS
+
+class TQSimpleTextCodec: public TQTextCodec
+{
+public:
+ TQSimpleTextCodec( int );
+ ~TQSimpleTextCodec();
+
+ TQString toUnicode(const char* chars, int len) const;
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ const char* name() const;
+ const char* mimeName() const;
+ int mibEnum() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+
+ int heuristicNameMatch(const char* hint) const;
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::canEncode;
+#endif
+ bool canEncode( TQChar ch ) const;
+
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+
+private:
+ void buildReverseMap();
+
+ int forwardIndex;
+#ifndef TQ_WS_TQWS
+ TQMemArray<unsigned char> *reverseMap;
+#endif
+};
+
+#ifdef TQ_WS_TQWS
+static const TQSimpleTextCodec * reverseOwner = 0;
+static TQMemArray<unsigned char> * reverseMap = 0;
+#endif
+
+#define LAST_MIB 2004
+
+static const struct {
+ const char *mime;
+ const char * cs;
+ int mib;
+ TQ_UINT16 values[128];
+} tqunicodevalues[] = {
+ // from RFC 1489, ftp://ftp.isi.edu/in-notes/rfc1489.txt
+ { "KOI8-R", "KOI8-R", 2084,
+ { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
+ 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
+ 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219/**/, 0x221A, 0x2248,
+ 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
+ 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556,
+ 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x255C, 0x255D, 0x255E,
+ 0x255F, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565,
+ 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x256B, 0x256C, 0x00A9,
+ 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
+ 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
+ 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
+ 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
+ 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
+ 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
+ 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
+ 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A } },
+ // /**/ - The BULLET OPERATOR is confused. Some people think
+ // it should be 0x2022 (BULLET).
+
+ // from RFC 2319, ftp://ftp.isi.edu/in-notes/rfc2319.txt
+ { "KOI8-U", "KOI8-U", 2088,
+ { 0x2500, 0x2502, 0x250C, 0x2510, 0x2514, 0x2518, 0x251C, 0x2524,
+ 0x252C, 0x2534, 0x253C, 0x2580, 0x2584, 0x2588, 0x258C, 0x2590,
+ 0x2591, 0x2592, 0x2593, 0x2320, 0x25A0, 0x2219, 0x221A, 0x2248,
+ 0x2264, 0x2265, 0x00A0, 0x2321, 0x00B0, 0x00B2, 0x00B7, 0x00F7,
+ 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457,
+ 0x2557, 0x2558, 0x2559, 0x255A, 0x255B, 0x0491, 0x255D, 0x255E,
+ 0x255F, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407,
+ 0x2566, 0x2567, 0x2568, 0x2569, 0x256A, 0x0490, 0x256C, 0x00A9,
+ 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
+ 0x0445, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E,
+ 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
+ 0x044C, 0x044B, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x044A,
+ 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
+ 0x0425, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E,
+ 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
+ 0x042C, 0x042B, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042A } },
+
+ // next bits generated from tables on the Unicode 2.0 CD. we can
+ // use these tables since this is part of the transition to using
+ // tqunicode everywhere in qt.
+
+ // $ for A in 8 9 A B C D E F ; do for B in 0 1 2 3 4 5 6 7 8 9 A B C D E F ; do echo 0x${A}${B} 0xFFFD ; done ; done > /tmp/digits ; for a in 8859-* ; do ( awk '/^0x[89ABCDEF]/{ print $1, $2 }' < $a ; cat /tmp/digits ) | sort | uniq -w4 | cut -c6- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/$a ; done
+
+ // then I inserted the files manually.
+ { "ISO-8859-2", "ISO 8859-2", 5,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7,
+ 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B,
+ 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7,
+ 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C,
+ 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
+ 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
+ 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
+ 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
+ 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
+ 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9} },
+ { "ISO-8859-3", "ISO 8859-3", 6,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0xFFFD, 0x0124, 0x00A7,
+ 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0xFFFD, 0x017B,
+ 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7,
+ 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0xFFFD, 0x017C,
+ 0x00C0, 0x00C1, 0x00C2, 0xFFFD, 0x00C4, 0x010A, 0x0108, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0xFFFD, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7,
+ 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0xFFFD, 0x00E4, 0x010B, 0x0109, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0xFFFD, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7,
+ 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9} },
+ { "ISO-8859-4", "ISO 8859-4", 7,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7,
+ 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF,
+ 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7,
+ 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B,
+ 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A,
+ 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF,
+ 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B,
+ 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9} },
+ { "ISO-8859-5", "ISO 8859-5", 8,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407,
+ 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+ 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457,
+ 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F} },
+ { "ISO-8859-6", "ISO 8859-6", 82,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0xFFFD, 0xFFFD, 0xFFFD, 0x00A4, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x060C, 0x00AD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0x061B, 0xFFFD, 0xFFFD, 0xFFFD, 0x061F,
+ 0xFFFD, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
+ 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637,
+ 0x0638, 0x0639, 0x063A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647,
+ 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F,
+ 0x0650, 0x0651, 0x0652, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+ { "ISO-8859-7", "ISO 8859-7", 10,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x2018, 0x2019, 0x00A3, 0xFFFD, 0xFFFD, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0xFFFD, 0x00AB, 0x00AC, 0x00AD, 0xFFFD, 0x2015,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7,
+ 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0xFFFD, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xFFFD} },
+ { "ISO-8859-8-I", "ISO 8859-8-I", 85,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0xFFFD, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x203E,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2017,
+ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+ 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+ 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+ { "ISO-8859-9", "ISO 8859-9", 12,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF} },
+ { "ISO-8859-10", "ISO 8859-10", 13,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7,
+ 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A,
+ 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7,
+ 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2015, 0x016B, 0x014B,
+ 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168,
+ 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169,
+ 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138} },
+ { "ISO-8859-13", "ISO 8859-13", 109,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7,
+ 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7,
+ 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
+ 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
+ 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
+ 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
+ 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
+ 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
+ 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
+ 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
+ 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019} },
+ { "ISO-8859-14", "ISO 8859-14", 110,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7,
+ 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178,
+ 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56,
+ 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF} },
+ { "ISO-8859-16", "ISO 8859-16", 112,
+ { 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
+ 0x00A0, 0x0104, 0x0105, 0x0141, 0x20AC, 0x201E, 0x0160, 0x00A7,
+ 0x0161, 0x00A9, 0x0218, 0x00AB, 0x0179, 0x00AD, 0x017A, 0x017B,
+ 0x00B0, 0x00B1, 0x010C, 0x0142, 0x017D, 0x201D, 0x00B6, 0x00B7,
+ 0x017E, 0x010D, 0x0219, 0x00BB, 0x0152, 0x0153, 0x0178, 0x017C,
+ 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0106, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x0110, 0x0143, 0x00D2, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x015A,
+ 0x0170, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0118, 0x021A, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x0107, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x0111, 0x0144, 0x00F2, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x015B,
+ 0x0171, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0119, 0x021B, 0x00FF} },
+
+ // next bits generated again from tables on the Unicode 3.0 CD.
+
+ // $ for a in CP* ; do ( awk '/^0x[89ABCDEF]/{ print $1, $2 }' < $a ) | sort | sed -e 's/#UNDEF.*$/0xFFFD/' | cut -c6- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/$a ; done
+
+ { "CP 850", "IBM 850", 2009,
+ { 0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
+ 0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
+ 0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
+ 0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
+ 0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
+ 0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
+ 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
+ 0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
+ 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
+ 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
+ 0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
+ 0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
+ 0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
+ 0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0x00B4,
+ 0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
+ 0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0} },
+ { "CP 874", "CP 874", 0, //### what is the mib?
+ { 0x20AC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2026, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
+ 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
+ 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
+ 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
+ 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
+ 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
+ 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
+ 0x0E38, 0x0E39, 0x0E3A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0E3F,
+ 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
+ 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
+ 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
+ 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD} },
+ { "IBM 866", "IBM 866", 2086,
+ { 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+ 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+ 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+ 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+ 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+ 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+ 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F,
+ 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040E, 0x045E,
+ 0x00B0, 0x2219, 0x00B7, 0x221A, 0x2116, 0x00A4, 0x25A0, 0x00A0} },
+
+ { "windows-1250", "CP 1250", 2250,
+ { 0x20AC, 0xFFFD, 0x201A, 0xFFFD, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0xFFFD, 0x2030, 0x0160, 0x2039, 0x015A, 0x0164, 0x017D, 0x0179,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0x0161, 0x203A, 0x015B, 0x0165, 0x017E, 0x017A,
+ 0x00A0, 0x02C7, 0x02D8, 0x0141, 0x00A4, 0x0104, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x015E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x017B,
+ 0x00B0, 0x00B1, 0x02DB, 0x0142, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x0105, 0x015F, 0x00BB, 0x013D, 0x02DD, 0x013E, 0x017C,
+ 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7,
+ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E,
+ 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7,
+ 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF,
+ 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7,
+ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F,
+ 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7,
+ 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9} },
+ { "windows-1251", "CP 1251", 2251,
+ { 0x0402, 0x0403, 0x201A, 0x0453, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x20AC, 0x2030, 0x0409, 0x2039, 0x040A, 0x040C, 0x040B, 0x040F,
+ 0x0452, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0x0459, 0x203A, 0x045A, 0x045C, 0x045B, 0x045F,
+ 0x00A0, 0x040E, 0x045E, 0x0408, 0x00A4, 0x0490, 0x00A6, 0x00A7,
+ 0x0401, 0x00A9, 0x0404, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x0407,
+ 0x00B0, 0x00B1, 0x0406, 0x0456, 0x0491, 0x00B5, 0x00B6, 0x00B7,
+ 0x0451, 0x2116, 0x0454, 0x00BB, 0x0458, 0x0405, 0x0455, 0x0457,
+ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417,
+ 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F,
+ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427,
+ 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F,
+ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437,
+ 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F,
+ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447,
+ 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F} },
+ { "windows-1252", "CP 1252", 2252,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0x017D, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0x017E, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF} },
+ { "windows-1253", "CP 1253", 2253,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0xFFFD, 0x2030, 0xFFFD, 0x2039, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0xFFFD, 0x203A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0x0385, 0x0386, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0xFFFD, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x2015,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x00B5, 0x00B6, 0x00B7,
+ 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F,
+ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F,
+ 0x03A0, 0x03A1, 0xFFFD, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7,
+ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF,
+ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7,
+ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF,
+ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7,
+ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0xFFFD} },
+ { "windows-1254", "CP 1254", 2254,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0160, 0x2039, 0x0152, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0x0161, 0x203A, 0x0153, 0xFFFD, 0xFFFD, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF} },
+ { "windows-1255", "CP 1255", 2255,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0xFFFD, 0x2039, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0xFFFD, 0x203A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AA, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x05B0, 0x05B1, 0x05B2, 0x05B3, 0x05B4, 0x05B5, 0x05B6, 0x05B7,
+ 0x05B8, 0x05B9, 0xFFFD, 0x05BB, 0x05BC, 0x05BD, 0x05BE, 0x05BF,
+ 0x05C0, 0x05C1, 0x05C2, 0x05C3, 0x05F0, 0x05F1, 0x05F2, 0x05F3,
+ 0x05F4, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7,
+ 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF,
+ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7,
+ 0x05E8, 0x05E9, 0x05EA, 0xFFFD, 0xFFFD, 0x200E, 0x200F, 0xFFFD} },
+ { "windows-1256", "CP 1256", 2256,
+ { 0x20AC, 0x067E, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
+ 0x06AF, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x06A9, 0x2122, 0x0691, 0x203A, 0x0153, 0x200C, 0x200D, 0x06BA,
+ 0x00A0, 0x060C, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x06BE, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x061B, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x061F,
+ 0x06C1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627,
+ 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F,
+ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00D7,
+ 0x0637, 0x0638, 0x0639, 0x063A, 0x0640, 0x0641, 0x0642, 0x0643,
+ 0x00E0, 0x0644, 0x00E2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0649, 0x064A, 0x00EE, 0x00EF,
+ 0x064B, 0x064C, 0x064D, 0x064E, 0x00F4, 0x064F, 0x0650, 0x00F7,
+ 0x0651, 0x00F9, 0x0652, 0x00FB, 0x00FC, 0x200E, 0x200F, 0x06D2} },
+ { "windows-1257", "CP 1257", 2257,
+ { 0x20AC, 0xFFFD, 0x201A, 0xFFFD, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0xFFFD, 0x2030, 0xFFFD, 0x2039, 0xFFFD, 0x00A8, 0x02C7, 0x00B8,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0x2122, 0xFFFD, 0x203A, 0xFFFD, 0x00AF, 0x02DB, 0xFFFD,
+ 0x00A0, 0xFFFD, 0x00A2, 0x00A3, 0x00A4, 0xFFFD, 0x00A6, 0x00A7,
+ 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6,
+ 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112,
+ 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B,
+ 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7,
+ 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF,
+ 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113,
+ 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C,
+ 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7,
+ 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x02D9} },
+ { "windows-1258", "CP 1258", 2258,
+ { 0x20AC, 0xFFFD, 0x201A, 0x0192, 0x201E, 0x2026, 0x2020, 0x2021,
+ 0x02C6, 0x2030, 0xFFFD, 0x2039, 0x0152, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x02DC, 0x2122, 0xFFFD, 0x203A, 0x0153, 0xFFFD, 0xFFFD, 0x0178,
+ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
+ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
+ 0x00C0, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x0300, 0x00CD, 0x00CE, 0x00CF,
+ 0x0110, 0x00D1, 0x0309, 0x00D3, 0x00D4, 0x01A0, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x01AF, 0x0303, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x0301, 0x00ED, 0x00EE, 0x00EF,
+ 0x0111, 0x00F1, 0x0323, 0x00F3, 0x00F4, 0x01A1, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x01B0, 0x20AB, 0x00FF} },
+
+ { "Apple Roman", "Apple Roman", 0,
+ { 0x00C4, 0x00C5, 0x00C7, 0x00C9, 0x00D1, 0x00D6, 0x00DC, 0x00E1,
+ 0x00E0, 0x00E2, 0x00E4, 0x00E3, 0x00E5, 0x00E7, 0x00E9, 0x00E8,
+ 0x00EA, 0x00EB, 0x00ED, 0x00EC, 0x00EE, 0x00EF, 0x00F1, 0x00F3,
+ 0x00F2, 0x00F4, 0x00F6, 0x00F5, 0x00FA, 0x00F9, 0x00FB, 0x00FC,
+ 0x2020, 0x00B0, 0x00A2, 0x00A3, 0x00A7, 0x2022, 0x00B6, 0x00DF,
+ 0x00AE, 0x00A9, 0x2122, 0x00B4, 0x00A8, 0x2260, 0x00C6, 0x00D8,
+ 0x221E, 0x00B1, 0x2264, 0x2265, 0x00A5, 0x00B5, 0x2202, 0x2211,
+ 0x220F, 0x03C0, 0x222B, 0x00AA, 0x00BA, 0x03A9, 0x00E6, 0x00F8,
+ 0x00BF, 0x00A1, 0x00AC, 0x221A, 0x0192, 0x2248, 0x2206, 0x00AB,
+ 0x00BB, 0x2026, 0x00A0, 0x00C0, 0x00C3, 0x00D5, 0x0152, 0x0153,
+ 0x2013, 0x2014, 0x201C, 0x201D, 0x2018, 0x2019, 0x00F7, 0x25CA,
+ 0x00FF, 0x0178, 0x2044, 0x20AC, 0x2039, 0x203A, 0xFB01, 0xFB02,
+ 0x2021, 0x00B7, 0x201A, 0x201E, 0x2030, 0x00C2, 0x00CA, 0x00C1,
+ 0x00CB, 0x00C8, 0x00CD, 0x00CE, 0x00CF, 0x00CC, 0x00D3, 0x00D4,
+ 0xF8FF, 0x00D2, 0x00DA, 0x00DB, 0x00D9, 0x0131, 0x02C6, 0x02DC,
+ 0x00AF, 0x02D8, 0x02D9, 0x02DA, 0x00B8, 0x02DD, 0x02DB, 0x02C7} },
+
+
+
+ // This one is based on the charmap file
+ // /usr/share/i18n/charmaps/SAMI-WS2.gz, which is manually adapted
+ // to this format by Børre Gaup <boerre@subdimension.com>
+ { "WINSAMI2", "WS2", 0,
+ { 0x20AC, 0xFFFD, 0x010C, 0x0192, 0x010D, 0x01B7, 0x0292, 0x01EE,
+ 0x01EF, 0x0110, 0x0160, 0x2039, 0x0152, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0x0111, 0x01E6, 0x0161, 0x203A, 0x0153, 0xFFFD, 0xFFFD, 0x0178,
+ 0x00A0, 0x01E7, 0x01E4, 0x00A3, 0x00A4, 0x01E5, 0x00A6, 0x00A7,
+ 0x00A8, 0x00A9, 0x021E, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x021F,
+ 0x00B0, 0x00B1, 0x01E8, 0x01E9, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
+ 0x014A, 0x014B, 0x0166, 0x00BB, 0x0167, 0x00BD, 0x017D, 0x017E,
+ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
+ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
+ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
+ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
+ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
+ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
+ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
+ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF} },
+
+
+ // this one is generated from the charmap file located in /usr/share/i18n/charmaps
+ // on most Linux distributions. The thai character set tis620 is byte by byte equivalent
+ // to iso8859-11, so we name it 8859-11 here, but recognise the name tis620 too.
+
+ // $ for A in 8 9 A B C D E F ; do for B in 0 1 2 3 4 5 6 7 8 9 A B C D E F ; do echo x${A}${B} 0xFFFD ; done ; done > /tmp/digits ; ( cut -c25- < TIS-620 ; cat /tmp/digits ) | awk '/^x[89ABCDEF]/{ print $1, $2 }' | sed -e 's/<U/0x/' -e 's/>//' | sort | uniq -w4 | cut -c5- | paste '-d ' - - - - - - - - | sed -e 's/ /, /g' -e 's/$/,/' -e '$ s/,$/} },/' -e '1 s/^/{ /' > ~/tmp/tis-620
+ { "TIS-620", "ISO 8859-11", 2259, // Thai character set mib enum taken from tis620 (which is byte by byte equivalent)
+ { 0x20AC, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x2026, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x2018, 0x2019, 0x201C, 0x201D, 0x2022, 0x2013, 0x2014,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07,
+ 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F,
+ 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17,
+ 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F,
+ 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27,
+ 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F,
+ 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37,
+ 0x0E38, 0x0E39, 0x0E3A, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0x0E3F,
+ 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47,
+ 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F,
+ 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57,
+ 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD } },
+
+ /*
+ Name: hp-roman8 [HP-PCL5,RFC1345,KXS2]
+ MIBenum: 2004
+ Source: LaserJet IIP Printer User's Manual,
+ HP part no 33471-90901, Hewlet-Packard, June 1989.
+ Alias: roman8
+ Alias: r8
+ Alias: csHPRoman8
+ */
+ { "Roman8", "HP-Roman8", 2004,
+ { 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
+ 0x00A0, 0x00C0, 0x00C2, 0x00C8, 0x00CA, 0x00CB, 0x00CE, 0x00CF,
+ 0x00B4, 0x02CB, 0x02C6, 0x00A8, 0x02DC, 0x00D9, 0x00DB, 0x20A4,
+ 0x00AF, 0x00DD, 0x00FD, 0x00B0, 0x00C7, 0x00E7, 0x00D1, 0x00F1,
+ 0x00A1, 0x00BF, 0x00A4, 0x00A3, 0x00A5, 0x00A7, 0x0192, 0x00A2,
+ 0x00E2, 0x00EA, 0x00F4, 0x00FB, 0x00E1, 0x00E9, 0x00F3, 0x00FA,
+ 0x00E0, 0x00E8, 0x00F2, 0x00F9, 0x00E4, 0x00EB, 0x00F6, 0x00FC,
+ 0x00C5, 0x00EE, 0x00D8, 0x00C6, 0x00E5, 0x00ED, 0x00F8, 0x00E6,
+ 0x00C4, 0x00EC, 0x00D6, 0x00DC, 0x00C9, 0x00EF, 0x00DF, 0x00D4,
+ 0x00C1, 0x00C3, 0x00E3, 0x00D0, 0x00F0, 0x00CD, 0x00CC, 0x00D3,
+ 0x00D2, 0x00D5, 0x00F5, 0x0160, 0x0161, 0x00DA, 0x0178, 0x00FF,
+ 0x00DE, 0x00FE, 0x00B7, 0x00B5, 0x00B6, 0x00BE, 0x2014, 0x00BC,
+ 0x00BD, 0x00AA, 0x00BA, 0x00AB, 0x25A0, 0x00BB, 0x00B1, 0xFFFD } }
+
+ // if you add more chacater sets at the end, change LAST_MIB above
+};
+
+TQSimpleTextCodec::TQSimpleTextCodec( int i )
+ : TQTextCodec(), forwardIndex( i )
+{
+#ifndef TQ_WS_TQWS
+ reverseMap = 0;
+#endif
+}
+
+
+TQSimpleTextCodec::~TQSimpleTextCodec()
+{
+#ifndef TQ_WS_TQWS
+ delete reverseMap;
+#else
+ if ( reverseOwner == this ) {
+ delete reverseMap;
+ reverseMap = 0;
+ reverseOwner = 0;
+ }
+#endif
+}
+
+void TQSimpleTextCodec::buildReverseMap()
+{
+#ifdef TQ_WS_TQWS
+ if ( reverseOwner != this ) {
+ int m = 0;
+ int i = 0;
+ while( i < 128 ) {
+ if ( tqunicodevalues[forwardIndex].values[i] > m &&
+ tqunicodevalues[forwardIndex].values[i] < 0xfffd )
+ m = tqunicodevalues[forwardIndex].values[i];
+ i++;
+ }
+ m++;
+ if ( !reverseMap )
+ reverseMap = new TQMemArray<unsigned char>( m );
+ if ( m > (int)(reverseMap->size()) )
+ reverseMap->resize( m );
+ for( i = 0; i < 128 && i < m; i++ )
+ (*reverseMap)[i] = (char)i;
+ for( ;i < m; i++ )
+ (*reverseMap)[i] = 0;
+ for( i=128; i<256; i++ ) {
+ int u = tqunicodevalues[forwardIndex].values[i-128];
+ if ( u < m )
+ (*reverseMap)[u] = (char)(unsigned char)(i);
+ }
+ reverseOwner = this;
+ }
+#else
+ if ( !reverseMap ) {
+ TQMemArray<unsigned char> **map = &((TQSimpleTextCodec *)this)->reverseMap;
+ int m = 0;
+ int i = 0;
+ while( i < 128 ) {
+ if ( tqunicodevalues[forwardIndex].values[i] > m &&
+ tqunicodevalues[forwardIndex].values[i] < 0xfffd )
+ m = tqunicodevalues[forwardIndex].values[i];
+ i++;
+ }
+ m++;
+ *map = new TQMemArray<unsigned char>( m );
+ for( i = 0; i < 128 && i < m; i++ )
+ (**map)[i] = (char)i;
+ for( ;i < m; i++ )
+ (**map)[i] = 0;
+ for( i=128; i<256; i++ ) {
+ int u = tqunicodevalues[forwardIndex].values[i-128];
+ if ( u < m )
+ (**map)[u] = (char)(unsigned char)(i);
+ }
+ }
+#endif
+}
+
+TQString TQSimpleTextCodec::toUnicode(const char* chars, int len) const
+{
+ if ( len <= 0 || chars == 0 )
+ return TQString::null;
+
+ const unsigned char * c = (const unsigned char *)chars;
+ int i;
+
+ for ( i = 0; i < len; i++ )
+ if ( c[i] == '\0' ) {
+ len = i;
+ break;
+ }
+
+ TQString r;
+ r.setUnicode(0, len);
+ TQChar* uc = (TQChar*)r.tqunicode(); // const_cast
+
+ for ( i = 0; i < len; i++ ) {
+ if ( c[i] > 127 )
+ uc[i] = tqunicodevalues[forwardIndex].values[c[i]-128];
+ else
+ uc[i] = c[i];
+ }
+ return r;
+}
+
+
+TQCString TQSimpleTextCodec::fromUnicode(const TQString& uc, int& len ) const
+{
+#ifdef TQ_WS_TQWS
+ if ( this != reverseOwner )
+#else
+ if ( !reverseMap )
+#endif
+ ((TQSimpleTextCodec *)this)->buildReverseMap();
+
+ if ( len <0 || len > (int)uc.length() )
+ len = uc.length();
+ TQCString r( len+1 );
+ int i = len;
+ int u;
+ const TQChar* ucp = uc.tqunicode();
+ unsigned char* rp = (unsigned char *)r.data();
+ unsigned char* rmp = reverseMap->data();
+ int rmsize = (int) reverseMap->size();
+ while( i-- )
+ {
+ u = ucp->tqunicode();
+ *rp = u < 128 ? u : (( u < rmsize ) ? (*(rmp+u)) : '?' );
+ if ( *rp == 0 ) *rp = '?';
+ rp++;
+ ucp++;
+ }
+ r[len] = 0;
+ return r;
+}
+
+void TQSimpleTextCodec::fromUnicode( const TQChar *in, unsigned short *out, int length ) const
+{
+#ifdef TQ_WS_TQWS
+ if ( this != reverseOwner )
+#else
+ if ( !reverseMap )
+#endif
+ ((TQSimpleTextCodec *)this)->buildReverseMap();
+
+ unsigned char* rmp = reverseMap->data();
+ int rmsize = (int) reverseMap->size();
+ while ( length-- ) {
+ unsigned short u = in->tqunicode();
+ *out = u < 128 ? u : (( u < rmsize ) ? (*(rmp+u)) : 0 );
+ ++in;
+ ++out;
+ }
+}
+
+unsigned short TQSimpleTextCodec::characterFromUnicode(const TQString &str, int pos) const
+{
+#ifdef TQ_WS_TQWS
+ if ( this != reverseOwner )
+#else
+ if ( !reverseMap )
+#endif
+ ((TQSimpleTextCodec *)this)->buildReverseMap();
+
+ unsigned short u = str[pos].tqunicode();
+ unsigned char* rmp = reverseMap->data();
+ int rmsize = (int) reverseMap->size();
+ return u < 128 ? u : (( u < rmsize ) ? (*(rmp+u)) : 0 );
+}
+
+bool TQSimpleTextCodec::canEncode( TQChar ch ) const
+{
+#ifdef TQ_WS_TQWS
+ if ( this != reverseOwner )
+#else
+ if ( !reverseMap )
+#endif
+ ((TQSimpleTextCodec *)this)->buildReverseMap();
+
+ unsigned short u = ch.tqunicode();
+ unsigned char* rmp = reverseMap->data();
+ int rmsize = (int) reverseMap->size();
+ return u < 128 ? TRUE : (( u < rmsize ) ? (*(rmp+u) != 0) : FALSE );
+}
+
+const char* TQSimpleTextCodec::name() const
+{
+ return tqunicodevalues[forwardIndex].cs;
+}
+
+const char* TQSimpleTextCodec::mimeName() const
+{
+ return tqunicodevalues[forwardIndex].mime;
+}
+
+
+int TQSimpleTextCodec::mibEnum() const
+{
+ return tqunicodevalues[forwardIndex].mib;
+}
+
+int TQSimpleTextCodec::heuristicNameMatch(const char* hint) const
+{
+ if ( qstricmp( hint, mimeName() ) == 0 )
+ return 10000; // return a large value
+ if ( hint[0]=='k' ) {
+ TQCString lhint = TQCString(hint).lower();
+ // Help people with messy fonts
+ if ( lhint == "koi8-1" )
+ return TQTextCodec::heuristicNameMatch("koi8-r")-1;
+ if ( lhint == "koi8-ru" )
+ return TQTextCodec::heuristicNameMatch("koi8-r")-1;
+ } else if ( hint[0] == 't' && mibEnum() == 2259 /* iso8859-11 */ ) {
+ // 8859-11 and tis620 are byte by byte equivalent
+ int i = simpleHeuristicNameMatch("tis620-0", hint);
+ if( !i )
+ i = simpleHeuristicNameMatch("tis-620", hint);
+ if( i ) return i;
+ } else if ( mibEnum() == 82 /* ISO 8859-6 */ ) {
+ int i = simpleHeuristicNameMatch("ISO 8859-6-I", hint);
+ if ( i )
+ return i;
+ }
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+int TQSimpleTextCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ if ( len<1 || !chars )
+ return -1;
+ int i = 0;
+ const uchar * c = (const unsigned char *)chars;
+ int r = 0;
+ while( i<len && c && *c ) {
+ if ( *c >= 128 ) {
+ if ( tqunicodevalues[forwardIndex].values[(*c)-128] == 0xfffd )
+ return -1;
+ }
+ if ( (*c >= ' ' && *c < 127) ||
+ *c == '\n' || *c == '\t' || *c == '\r' )
+ r++;
+ i++;
+ c++;
+ }
+ if ( mibEnum()==4 )
+ r+=1;
+ return r;
+}
+
+#endif
+
+class TQLatin1Codec : public TQTextCodec
+{
+public:
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+ using TQTextCodec::toUnicode;
+#endif
+ TQString toUnicode(const char* chars, int len) const;
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ const char* name() const;
+ const char* mimeName() const;
+ int mibEnum() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+
+private:
+ int forwardIndex;
+};
+
+
+TQString TQLatin1Codec::toUnicode(const char* chars, int len) const
+{
+ if ( chars == 0 )
+ return TQString::null;
+
+ return TQString::tqfromLatin1(chars, len);
+}
+
+
+TQCString TQLatin1Codec::fromUnicode(const TQString& uc, int& len ) const
+{
+ if ( len <0 || len > (int)uc.length() )
+ len = uc.length();
+ TQCString r( len+1 );
+ char *d = r.data();
+ int i = 0;
+ const TQChar *ch = uc.tqunicode();
+ while ( i < len ) {
+ d[i] = ch->row() ? '?' : ch->cell();
+ i++;
+ ch++;
+ }
+ r[len] = 0;
+ return r;
+}
+
+void TQLatin1Codec::fromUnicode( const TQChar *in, unsigned short *out, int length ) const
+{
+ while ( length-- ) {
+ *out = in->row() ? 0 : in->cell();
+ ++in;
+ ++out;
+ }
+}
+
+unsigned short TQLatin1Codec::characterFromUnicode(const TQString &str, int pos) const
+{
+ const TQChar *ch = str.tqunicode() + pos;
+ if (ch->row())
+ return 0;
+ return (unsigned short) ch->cell();
+}
+
+
+const char* TQLatin1Codec::name() const
+{
+ return "ISO 8859-1";
+}
+
+const char* TQLatin1Codec::mimeName() const
+{
+ return "ISO-8859-1";
+}
+
+
+int TQLatin1Codec::mibEnum() const
+{
+ return 4;
+}
+
+int TQLatin1Codec::heuristicContentMatch(const char* chars, int len) const
+{
+ if ( len<1 || !chars )
+ return -1;
+ int i = 0;
+ const uchar * c = (const unsigned char *)chars;
+ int r = 0;
+ while( i<len && c && *c ) {
+ if ( *c >= 0x80 && *c < 0xa0 )
+ return -1;
+ if ( (*c >= ' ' && *c < 127) ||
+ *c == '\n' || *c == '\t' || *c == '\r' )
+ r++;
+ i++;
+ c++;
+ }
+ if ( this == (const TQTextCodec *)codecForLocale() )
+ r += 5;
+ return r;
+}
+
+class TQLatin15Codec: public TQLatin1Codec
+{
+public:
+ TQString toUnicode(const char* chars, int len) const;
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQLatin1Codec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut ) const;
+ void fromUnicode( const TQChar *in, unsigned short *out, int length ) const;
+ unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+ const char* name() const;
+ const char* mimeName() const;
+ int mibEnum() const;
+
+private:
+ int forwardIndex;
+};
+
+
+TQString TQLatin15Codec::toUnicode(const char* chars, int len) const
+{
+ if ( chars == 0 )
+ return TQString::null;
+
+ TQString str = TQString::tqfromLatin1(chars, len);
+ TQChar *uc = (TQChar *)str.tqunicode();
+ while( len-- ) {
+ switch( uc->tqunicode() ) {
+ case 0xa4:
+ *uc = 0x20ac;
+ break;
+ case 0xa6:
+ *uc = 0x0160;
+ break;
+ case 0xa8:
+ *uc = 0x0161;
+ break;
+ case 0xb4:
+ *uc = 0x017d;
+ break;
+ case 0xb8:
+ *uc = 0x017e;
+ break;
+ case 0xbc:
+ *uc = 0x0152;
+ break;
+ case 0xbd:
+ *uc = 0x0153;
+ break;
+ case 0xbe:
+ *uc = 0x0178;
+ break;
+ default:
+ break;
+ }
+ uc++;
+ }
+ return str;
+}
+
+static inline unsigned char
+latin15CharFromUnicode( unsigned short uc, bool tqreplacement = TRUE )
+{
+ uchar c;
+ if ( uc < 0x0100 ) {
+ if ( uc > 0xa3 && uc < 0xbf ) {
+ switch( uc ) {
+ case 0xa4:
+ case 0xa6:
+ case 0xa8:
+ case 0xb4:
+ case 0xb8:
+ case 0xbc:
+ case 0xbd:
+ case 0xbe:
+ c = tqreplacement ? '?' : 0;
+ break;
+ default:
+ c = (unsigned char) uc;
+ break;
+ }
+ } else {
+ c = (unsigned char) uc;
+ }
+ } else {
+ if ( uc == 0x20ac )
+ c = 0xa4;
+ else if ( (uc & 0xff00) == 0x0100 ) {
+ switch( uc ) {
+ case 0x0160:
+ c = 0xa6;
+ break;
+ case 0x0161:
+ c = 0xa8;
+ break;
+ case 0x017d:
+ c = 0xb4;
+ break;
+ case 0x017e:
+ c = 0xb8;
+ break;
+ case 0x0152:
+ c = 0xbc;
+ break;
+ case 0x0153:
+ c = 0xbd;
+ break;
+ case 0x0178:
+ c = 0xbe;
+ break;
+ default:
+ c = tqreplacement ? '?' : 0;
+ }
+ } else {
+ c = tqreplacement ? '?' : 0;
+ }
+ }
+ return c;
+}
+
+
+void TQLatin15Codec::fromUnicode( const TQChar *in, unsigned short *out, int length ) const
+{
+ while ( length-- ) {
+ *out = latin15CharFromUnicode( in->tqunicode(), FALSE );
+ ++in;
+ ++out;
+ }
+}
+
+
+TQCString TQLatin15Codec::fromUnicode(const TQString& uc, int& len ) const
+{
+ if ( len <0 || len > (int)uc.length() )
+ len = uc.length();
+ TQCString r( len+1 );
+ char *d = r.data();
+ int i = 0;
+ const TQChar *ch = uc.tqunicode();
+ while ( i < len ) {
+ d[i] = latin15CharFromUnicode( ch->tqunicode() );
+ i++;
+ ch++;
+ }
+ r[len] = 0;
+ return r;
+}
+
+unsigned short TQLatin15Codec::characterFromUnicode(const TQString &str, int pos) const
+{
+ return latin15CharFromUnicode( str.tqunicode()[pos].tqunicode(), FALSE );
+}
+
+
+const char* TQLatin15Codec::name() const
+{
+ return "ISO 8859-15";
+}
+
+const char* TQLatin15Codec::mimeName() const
+{
+ return "ISO-8859-15";
+}
+
+
+int TQLatin15Codec::mibEnum() const
+{
+ return 111;
+}
+
+static TQTextCodec *checkForCodec(const char *name) {
+ TQTextCodec *c = TQTextCodec::codecForName(name);
+ if (!c) {
+ const char *at = strchr(name, '@');
+ if (at) {
+ TQCString n(name, at - name + 1);
+ c = TQTextCodec::codecForName(n.data());
+ }
+ }
+ return c;
+}
+
+/* the next two functions are implicitely thread safe,
+ as they are only called by setup() which uses a mutex.
+*/
+static void setupLocaleMapper()
+{
+#ifdef TQ_OS_WIN32
+ localeMapper = TQTextCodec::codecForName( "System" );
+#else
+
+#if defined (_XOPEN_UNIX) && !defined(TQ_OS_TQNX6) && !defined(TQ_OS_OSF) && !defined(TQ_OS_MAC)
+ char *charset = nl_langinfo (CODESET);
+ if ( charset )
+ localeMapper = TQTextCodec::codecForName( charset );
+#endif
+
+ if ( !localeMapper ) {
+ // Very poorly defined and followed standards causes lots of code
+ // to try to get all the cases...
+
+ // Try to determine locale codeset from locale name assigned to
+ // LC_CTYPE category.
+
+ // First part is getting that locale name. First try setlocale() which
+ // definitely knows it, but since we cannot fully trust it, get ready
+ // to fall back to environment variables.
+ char * ctype = qstrdup( setlocale( LC_CTYPE, 0 ) );
+
+ // Get the first nonempty value from $LC_ALL, $LC_CTYPE, and $LANG
+ // environment variables.
+ char * lang = qstrdup( getenv("LC_ALL") );
+ if ( !lang || lang[0] == 0 || strcmp( lang, "C" ) == 0 ) {
+ if ( lang ) delete [] lang;
+ lang = qstrdup( getenv("LC_CTYPE") );
+ }
+ if ( !lang || lang[0] == 0 || strcmp( lang, "C" ) == 0 ) {
+ if ( lang ) delete [] lang;
+ lang = qstrdup( getenv("LANG") );
+ }
+
+ // Now try these in order:
+ // 1. CODESET from ctype if it tqcontains a .CODESET part (e.g. en_US.ISO8859-15)
+ // 2. CODESET from lang if it tqcontains a .CODESET part
+ // 3. ctype (maybe the locale is named "ISO-8859-1" or something)
+ // 4. locale (ditto)
+ // 5. check for "@euro"
+ // 6. guess locale from ctype unless ctype is "C"
+ // 7. guess locale from lang
+
+ // 1. CODESET from ctype if it tqcontains a .CODESET part (e.g. en_US.ISO8859-15)
+ char * codeset = ctype ? strchr( ctype, '.' ) : 0;
+ if ( codeset && *codeset == '.' )
+ localeMapper = checkForCodec( codeset + 1 );
+
+ // 2. CODESET from lang if it tqcontains a .CODESET part
+ codeset = lang ? strchr( lang, '.' ) : 0;
+ if ( !localeMapper && codeset && *codeset == '.' )
+ localeMapper = checkForCodec( codeset + 1 );
+
+ // 3. ctype (maybe the locale is named "ISO-8859-1" or something)
+ if ( !localeMapper && ctype && *ctype != 0 && strcmp (ctype, "C") != 0 )
+ localeMapper = checkForCodec( ctype );
+
+ // 4. locale (ditto)
+ if ( !localeMapper && lang && *lang != 0 )
+ localeMapper = checkForCodec( lang );
+
+ // 5. "@euro"
+ if ( !localeMapper && ctype && strstr( ctype, "@euro" ) || lang && strstr( lang, "@euro" ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-15" );
+
+ // 6. guess locale from ctype unless ctype is "C"
+ // 7. guess locale from lang
+ char * try_by_name = ctype;
+ if ( ctype && *ctype != 0 && strcmp (ctype, "C") != 0 )
+ try_by_name = lang;
+
+ // Now do the guessing.
+ if ( lang && *lang && !localeMapper && try_by_name && *try_by_name ) {
+ if ( try_locale_list( iso8859_15locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-15" );
+ else if ( try_locale_list( iso8859_2locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-2" );
+ else if ( try_locale_list( iso8859_3locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-3" );
+ else if ( try_locale_list( iso8859_4locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-4" );
+ else if ( try_locale_list( iso8859_5locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-5" );
+ else if ( try_locale_list( iso8859_6locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-6" );
+ else if ( try_locale_list( iso8859_7locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-7" );
+ else if ( try_locale_list( iso8859_8locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-8-I" );
+ else if ( try_locale_list( iso8859_9locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-9" );
+ else if ( try_locale_list( iso8859_13locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-13" );
+ else if ( try_locale_list( tis_620locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-11" );
+ else if ( try_locale_list( koi8_ulocales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "KOI8-U" );
+ else if ( try_locale_list( cp_1251locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "CP 1251" );
+ else if ( try_locale_list( pt_154locales, lang ) )
+ localeMapper = TQTextCodec::codecForName( "PT 154" );
+ else if ( try_locale_list( probably_koi8_rlocales, lang ) )
+ localeMapper = ru_RU_hack( lang );
+ }
+
+ delete [] ctype;
+ delete [] lang;
+ }
+ if ( localeMapper && localeMapper->mibEnum() == 11 )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-8-I" );
+
+ // If everything failed, we default to 8859-1
+ // We could perhaps default to 8859-15.
+ if ( !localeMapper )
+ localeMapper = TQTextCodec::codecForName( "ISO 8859-1" );
+#endif
+}
+
+
+static void realSetup()
+{
+#if defined(TQT_CHECK_STATE)
+ if ( destroying_is_ok )
+ qWarning( "TQTextCodec: creating new codec during codec cleanup!" );
+#endif
+ all = new TQValueList<TQTextCodec*>;
+
+ (void)new TQLatin1Codec;
+ (void)new TQLatin15Codec;
+ (void)new TQUtf8Codec;
+ (void)new TQUtf16Codec;
+
+#ifndef TQT_NO_CODECS
+ int i = 0;
+ do {
+ (void)new TQSimpleTextCodec( i );
+ } while( tqunicodevalues[i++].mib != LAST_MIB );
+
+ (void)new TQTsciiCodec;
+
+ for (i = 0; i < 9; ++i) {
+ (void)new TQIsciiCodec(i);
+ }
+#endif // TQT_NO_CODECS
+#ifndef TQT_NO_CODEC_HEBREW
+ (void)new TQHebrewCodec;
+#endif
+#ifndef TQT_NO_BIG_CODECS
+ (void)new TQBig5Codec;
+ (void)new TQBig5hkscsCodec;
+ (void)new TQEucJpCodec;
+ (void)new TQEucKrCodec;
+ (void)new TQGb2312Codec;
+ (void)new TQGbkCodec;
+ (void)new TQGb18030Codec;
+ (void)new TQJisCodec;
+ (void)new TQSjisCodec;
+#endif // TQT_NO_BIG_CODECS
+
+#ifdef TQ_OS_WIN32
+ (void) new TQWindowsLocalCodec;
+#endif // TQ_OS_WIN32
+
+ if ( !localeMapper )
+ setupLocaleMapper();
+}
+
+void TQTextCodec::fromUnicodeInternal( const TQChar *in, unsigned short *out, int length )
+{
+ switch( mibEnum() ) {
+#ifndef TQT_NO_CODECS
+ case 2084:
+ case 2088:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 82:
+ case 10:
+ case 85:
+ case 12:
+ case 13:
+ case 109:
+ case 110:
+ case 2004:
+ case 2009:
+ case 2086:
+ case 2250:
+ case 2251:
+ case 2252:
+ case 2253:
+ case 2254:
+ case 2255:
+ case 2256:
+ case 2257:
+ case 2258:
+ case 2259:
+ ((TQSimpleTextCodec *)this)->fromUnicode( in, out, length );
+ break;
+
+#if !defined(TQT_NO_BIG_CODECS) && defined(TQ_WS_X11)
+ // the TQFont*Codecs are only used on X11
+
+ case 15:
+ ((TQFontJis0201Codec *) this)->fromUnicode( in, out, length );
+ break;
+
+ case 63:
+ ((TQFontJis0208Codec *) this)->fromUnicode( in, out, length );
+ break;
+
+ case 36:
+ ((TQFontKsc5601Codec *) this)->fromUnicode( in, out, length );
+ break;
+
+ case 57:
+ ((TQFontGb2312Codec *) this)->fromUnicode( in, out, length );
+ break;
+
+ case -113:
+ ((TQFontGbkCodec *) this)->fromUnicode( in, out, length );
+ break;
+
+ case -114:
+ ((TQFontGb18030_0Codec *) this)->fromUnicode( in, out, length );
+ break;
+
+ case -2026:
+ ((TQFontBig5Codec *) this)->fromUnicode( in, out, length );
+ break;
+
+ case -2101:
+ ((TQFontBig5hkscsCodec *) this)->fromUnicode( in, out, length );
+ break;
+
+ case -4242:
+ ((TQFontLaoCodec *) this)->fromUnicode( in, out, length );
+ break;
+#endif
+#endif // TQT_NO_CODECS
+
+ case 4:
+ ((TQLatin1Codec *) this)->fromUnicode( in, out, length );
+ break;
+
+ case 111:
+ ((TQLatin15Codec *) this)->fromUnicode( in, out, length );
+ break;
+
+ default:
+ {
+ TQConstString string( in, length );
+ TQString str = string.string();
+ for ( int i = 0; i < length; i++ )
+ out[i] = characterFromUnicode( str, i );
+ }
+ }
+}
+
+
+/*!
+ \fn TQTextCodec* TQTextCodec::codecForTr()
+
+ Returns the codec used by TQObject::tr() on its argument. If this
+ function returns 0 (the default), tr() assumes Latin-1.
+
+ \sa setCodecForTr()
+*/
+
+/*!
+ \fn void TQTextCodec::setCodecForTr(TQTextCodec *c)
+ \nonreentrant
+
+ Sets the codec used by TQObject::tr() on its argument to \a c. If
+ \a c is 0 (the default), tr() assumes Latin-1.
+
+ If the literal quoted text in the program is not in the Latin-1
+ encoding, this function can be used to set the appropriate
+ encoding. For example, software developed by Korean programmers
+ might use eucKR for all the text in the program, in which case the
+ main() function might look like this:
+
+ \code
+ int main(int argc, char** argv)
+ {
+ TQApplication app(argc, argv);
+ ... install any additional codecs ...
+ TQTextCodec::setCodecForTr( TQTextCodec::codecForName("eucKR") );
+ ...
+ }
+ \endcode
+
+ Note that this is not the way to select the encoding that the \e
+ user has chosen. For example, to convert an application containing
+ literal English strings to Korean, all that is needed is for the
+ English strings to be passed through tr() and for translation
+ files to be loaded. For details of internationalization, see the
+ \link i18n.html TQt internationalization documentation\endlink.
+
+ \sa codecForTr(), setCodecForTr(), setCodecForCStrings()
+*/
+
+
+/*!
+ \fn TQTextCodec* TQTextCodec::codecForCStrings()
+
+ Returns the codec used by TQString to convert to and from const
+ char* and TQCStrings. If this function returns 0 (the default),
+ TQString assumes Latin-1.
+
+ \sa setCodecForCStrings()
+*/
+
+/*!
+ \fn void TQTextCodec::setCodecForCStrings(TQTextCodec *c)
+ \nonreentrant
+
+ Sets the codec used by TQString to convert to and from const char*
+ and TQCStrings. If \a c is 0 (the default), TQString assumes Latin-1.
+
+ \warning Some codecs do not preserve the characters in the ascii
+ range (0x00 to 0x7f). For example, the Japanese Shift-JIS
+ encoding maps the backslash character (0x5a) to the Yen character.
+ This leads to unexpected results when using the backslash
+ character to escape characters in strings used in e.g. regular
+ expressions. Use TQString::tqfromLatin1() to preserve characters in
+ the ascii range when needed.
+
+ \sa codecForCStrings(), setCodecForTr(), setCodecForCStrings()
+*/
+
+
+TQTextCodec *TQTextCodec::cftr = 0;
+TQTextCodec *TQTextCodec::cfcs = 0;
+
+
+#endif // TQT_NO_TEXTCODEC
diff --git a/tqtinterface/qt4/src/codecs/tqtextcodec.h b/tqtinterface/qt4/src/codecs/tqtextcodec.h
new file mode 100644
index 0000000..198d08c
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqtextcodec.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Definition of TQTextCodec class
+**
+** Created : 981015
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTEXTCODEC_H
+#define TQTEXTCODEC_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TEXTCODEC
+
+class TQTextCodec;
+class TQIODevice;
+class TQFont;
+
+class TQ_EXPORT TQTextEncoder {
+public:
+ virtual ~TQTextEncoder();
+ virtual TQCString fromUnicode(const TQString& uc, int& lenInOut) = 0;
+};
+
+class TQ_EXPORT TQTextDecoder {
+public:
+ virtual ~TQTextDecoder();
+ virtual TQString toUnicode(const char* chars, int len) = 0;
+};
+
+class TQ_EXPORT TQTextCodec {
+public:
+ virtual ~TQTextCodec();
+
+#ifndef TQT_NO_CODECS
+ static TQTextCodec* loadCharmap(TQIODevice*);
+ static TQTextCodec* loadCharmapFile(TQString filename);
+#endif //TQT_NO_CODECS
+ static TQTextCodec* codecForMib(int mib);
+ static TQTextCodec* codecForName(const char* hint, int accuracy=0);
+ static TQTextCodec* codecForContent(const char* chars, int len);
+ static TQTextCodec* codecForIndex(int i);
+ static TQTextCodec* codecForLocale();
+ static void setCodecForLocale(TQTextCodec *c);
+
+ static TQTextCodec* codecForTr();
+ static void setCodecForTr(TQTextCodec *c);
+ static TQTextCodec* codecForCStrings();
+ static void setCodecForCStrings(TQTextCodec *c);
+
+ static void deleteAllCodecs();
+
+ static const char* locale();
+
+ virtual const char* name() const = 0;
+ virtual const char* mimeName() const;
+ virtual int mibEnum() const = 0;
+
+ virtual TQTextDecoder* makeDecoder() const;
+ virtual TQTextEncoder* makeEncoder() const;
+
+ virtual TQString toUnicode(const char* chars, int len) const;
+ virtual TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+
+ TQCString fromUnicode(const TQString& uc) const;
+ TQString toUnicode(const TQByteArray&, int len) const;
+ TQString toUnicode(const TQByteArray&) const;
+ TQString toUnicode(const TQCString&, int len) const;
+ TQString toUnicode(const TQCString&) const;
+ TQString toUnicode(const char* chars) const;
+ virtual bool canEncode( TQChar ) const;
+ virtual bool canEncode( const TQString& ) const;
+
+ virtual int heuristicContentMatch(const char* chars, int len) const = 0;
+ virtual int heuristicNameMatch(const char* hint) const;
+
+ virtual TQByteArray fromUnicode(const TQString& uc, int from, int len) const;
+ virtual unsigned short characterFromUnicode(const TQString &str, int pos) const;
+
+protected:
+ TQTextCodec();
+ static int simpleHeuristicNameMatch(const char* name, const char* hint);
+
+private:
+ friend class TQFont;
+ friend class TQFontEngineXLFD;
+ void fromUnicodeInternal( const TQChar *in, unsigned short *out, int length );
+
+ static TQTextCodec *cftr;
+ static TQTextCodec *cfcs;
+};
+
+inline TQTextCodec* TQTextCodec::codecForTr() { return cftr; }
+inline void TQTextCodec::setCodecForTr(TQTextCodec *c) { cftr = c; }
+inline TQTextCodec* TQTextCodec::codecForCStrings() { return cfcs; }
+inline void TQTextCodec::setCodecForCStrings(TQTextCodec *c) { cfcs = c; }
+
+#endif // TQT_NO_TEXTCODEC
+#endif // TQTEXTCODEC_H
diff --git a/tqtinterface/qt4/src/codecs/tqtextcodecfactory.cpp b/tqtinterface/qt4/src/codecs/tqtextcodecfactory.cpp
new file mode 100644
index 0000000..3eed293
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqtextcodecfactory.cpp
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Implementation of TQTextCodecFactory class
+**
+** Created : 010130
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtextcodecfactory.h"
+
+#ifndef TQT_NO_TEXTCODEC
+
+#ifndef TQT_NO_COMPONENT
+#include "tqapplication.h"
+#include "tqcleanuphandler.h"
+#include <private/tqpluginmanager_p.h>
+#include "tqtextcodecinterface_p.h"
+
+#ifdef TQT_THREAD_SUPPORT
+# include <private/tqmutexpool_p.h>
+#endif // TQT_THREAD_SUPPORT
+
+#include <stdlib.h>
+
+
+static TQPluginManager<TQTextCodecFactoryInterface> *manager = 0;
+static TQSingleCleanupHandler< TQPluginManager<TQTextCodecFactoryInterface> > cleanup_manager;
+
+static void create_manager()
+{
+ if ( manager ) // already created
+ return;
+
+#ifdef TQT_THREAD_SUPPORT
+ // protect manager creation
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &manager ) : 0);
+
+ // we check the manager pointer again to make sure that another thread
+ // has not created the manager before us.
+
+ if ( manager ) // already created
+ return;
+#endif
+
+ manager =
+ new TQPluginManager<TQTextCodecFactoryInterface>(IID_TQTextCodecFactory,
+ TQApplication::libraryPaths(), "/codecs",
+ FALSE);
+ TQ_CHECK_PTR( manager );
+ cleanup_manager.set( &manager );
+}
+
+#endif // TQT_NO_COMPONENT
+
+
+TQTextCodec *TQTextCodecFactory::createForName(const TQString &name)
+{
+ TQTextCodec *codec = 0;
+
+#ifndef TQT_NO_COMPONENT
+
+ // make sure the manager is created
+ create_manager();
+
+ TQInterfacePtr<TQTextCodecFactoryInterface> iface;
+ manager->queryInterface(name, &iface );
+
+ if (iface)
+ codec = iface->createForName(name);
+
+#endif // TQT_NO_COMPONENT
+
+ return codec;
+}
+
+
+TQTextCodec *TQTextCodecFactory::createForMib(int mib)
+{
+ TQTextCodec *codec = 0;
+
+#ifndef TQT_NO_COMPONENT
+
+ // make sure the manager is created
+ create_manager();
+
+ TQInterfacePtr<TQTextCodecFactoryInterface> iface;
+ manager->queryInterface("MIB-" + TQString::number(mib), &iface );
+
+ if (iface)
+ codec = iface->createForMib(mib);
+
+#endif // TQT_NO_COMPONENT
+
+ return codec;
+}
+
+
+#endif // TQT_NO_TEXTCODEC
diff --git a/tqtinterface/qt4/src/codecs/tqtextcodecfactory.h b/tqtinterface/qt4/src/codecs/tqtextcodecfactory.h
new file mode 100644
index 0000000..01f4f98
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqtextcodecfactory.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Definition of TQTextCodecFactory class
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTEXTCODECFACTORY_H
+#define TQTEXTCODECFACTORY_H
+
+#ifndef TQT_H
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TEXTCODEC
+
+class TQTextCodec;
+
+class TQ_EXPORT TQTextCodecFactory
+{
+public:
+ static TQTextCodec *createForName( const TQString & );
+ static TQTextCodec *createForMib( int );
+};
+
+#endif // TQT_NO_TEXTCODEC
+
+#endif // TQTEXTCODECFACTORY_H
diff --git a/tqtinterface/qt4/src/codecs/tqtextcodecinterface_p.h b/tqtinterface/qt4/src/codecs/tqtextcodecinterface_p.h
new file mode 100644
index 0000000..1c5bce9
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqtextcodecinterface_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Definition of TQTextCodecFactoryInterface interface
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTEXTCODECINTERFACE_P_H
+#define TQTEXTCODECINTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qpsprinter.cpp and qprinter_x11.cpp.
+// This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include <private/tqcom_p.h>
+#endif // TQT_H
+
+#ifndef TQT_NO_TEXTCODEC
+#ifndef TQT_NO_COMPONENT
+
+class TQTextCodec;
+
+
+// {F55BFA60-F695-11D4-823E-009027DC0F37}
+#ifndef IID_TQTextCodecFactory
+#define IID_TQTextCodecFactory TQUuid( 0xf55bfa60, 0xf695, 0x11d4, 0x82, 0x3e, 0x00, 0x90, 0x27, 0xdc, 0x0f, 0x37)
+#endif
+
+
+struct TQ_EXPORT TQTextCodecFactoryInterface : public TQFeatureListInterface
+{
+ virtual TQTextCodec *createForMib( int mib ) = 0;
+ virtual TQTextCodec *createForName( const TQString &name ) = 0;
+};
+
+#endif // TQT_NO_COMPONENT
+#endif // TQT_NO_TEXTCODEC
+
+#endif // TQTEXTCODECINTERFACE_P_H
diff --git a/tqtinterface/qt4/src/codecs/tqtextcodecplugin.cpp b/tqtinterface/qt4/src/codecs/tqtextcodecplugin.cpp
new file mode 100644
index 0000000..d8c0647
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqtextcodecplugin.cpp
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Implementation of TQTextCodecPlugin class
+**
+** Created : 010920
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtextcodecplugin.h"
+#ifndef TQT_NO_TEXTCODECPLUGIN
+#include "tqtextcodecinterface_p.h"
+
+/*!
+ \class TQTextCodecPlugin tqtextcodecplugin.h
+ \brief The TQTextCodecPlugin class provides an abstract base for custom TQTextCodec plugins.
+ \reentrant
+ \ingroup plugins
+
+ The text codec plugin is a simple plugin interface that makes it
+ easy to create custom text codecs that can be loaded dynamically
+ into applications.
+
+ Writing a text codec plugin is achieved by subclassing this base
+ class, reimplementing the pure virtual functions names(),
+ createForName(), mibEnums() and createForMib(), and exporting the
+ class with the \c TQ_EXPORT_PLUGIN macro. See the \link
+ plugins-howto.html TQt Plugins documentation \endlink for details.
+
+ See the \link http://www.iana.org/assignments/character-sets IANA
+ character-sets encoding file\endlink for more information on mime
+ names and mib enums.
+*/
+
+/*!
+ \fn TQStringList TQTextCodecPlugin::names() const
+
+ Returns the list of mime names supported by this plugin.
+
+ \sa createForName()
+*/
+
+/*!
+ \fn TQTextCodec *TQTextCodecPlugin::createForName( const TQString &name );
+
+ Creates a TQTextCodec object for the codec called \a name.
+
+ \sa names()
+*/
+
+
+/*!
+ \fn TQValueList<int> TQTextCodecPlugin::mibEnums() const
+
+ Returns the list of mib enums supported by this plugin.
+
+ \sa createForMib()
+*/
+
+/*!
+ \fn TQTextCodec *TQTextCodecPlugin::createForMib( int mib );
+
+ Creates a TQTextCodec object for the mib enum \a mib.
+
+ (See \link
+ ftp://ftp.isi.edu/in-notes/iana/assignments/character-sets the
+ IANA character-sets encoding file\endlink for more information)
+
+ \sa mibEnums()
+*/
+
+
+
+class TQTextCodecPluginPrivate : public TQTextCodecFactoryInterface
+{
+public:
+ TQTextCodecPluginPrivate( TQTextCodecPlugin *p )
+ : plugin( p )
+ {
+ }
+ virtual ~TQTextCodecPluginPrivate();
+
+ TQRESULT queryInterface( const TQUuid &iid, TQUnknownInterface **iface );
+ TQ_REFCOUNT;
+
+ TQStringList featureList() const;
+ TQTextCodec *createForMib( int mib );
+ TQTextCodec *createForName( const TQString &name );
+
+private:
+ TQTextCodecPlugin *plugin;
+};
+
+TQTextCodecPluginPrivate::~TQTextCodecPluginPrivate()
+{
+ delete plugin;
+}
+
+TQRESULT TQTextCodecPluginPrivate::queryInterface( const TQUuid &iid, TQUnknownInterface **iface )
+{
+ *iface = 0;
+
+ if ( iid == IID_TQUnknown )
+ *iface = this;
+ else if ( iid == IID_TQFeatureList )
+ *iface = this;
+ else if ( iid == IID_TQTextCodecFactory )
+ *iface = this;
+ else
+ return TQE_NOINTERFACE;
+
+ (*iface)->addRef();
+ return TQS_OK;
+}
+
+TQStringList TQTextCodecPluginPrivate::featureList() const
+{
+ TQStringList keys = plugin->names();
+ TQValueList<int> mibs = plugin->mibEnums();
+ for ( TQValueList<int>::Iterator it = mibs.begin(); it != mibs.end(); ++it )
+ keys += TQString("MIB-%1").arg( *it );
+ return keys;
+}
+
+TQTextCodec *TQTextCodecPluginPrivate::createForMib( int mib )
+{
+ return plugin->createForMib( mib );
+}
+
+TQTextCodec *TQTextCodecPluginPrivate::createForName( const TQString &name )
+{
+ return plugin->createForName( name );
+}
+
+
+/*!
+ Constructs a text codec plugin. This is invoked automatically by
+ the \c TQ_EXPORT_PLUGIN macro.
+*/
+TQTextCodecPlugin::TQTextCodecPlugin()
+ : TQGPlugin( d = new TQTextCodecPluginPrivate( this ) )
+{
+}
+
+/*!
+ Destroys the text codec plugin.
+
+ You never have to call this explicitly. TQt destroys a plugin
+ automatically when it is no longer used.
+*/
+TQTextCodecPlugin::~TQTextCodecPlugin()
+{
+}
+
+#endif // TQT_NO_TEXTCODECPLUGIN
diff --git a/tqtinterface/qt4/src/codecs/tqtextcodecplugin.h b/tqtinterface/qt4/src/codecs/tqtextcodecplugin.h
new file mode 100644
index 0000000..78513b7
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqtextcodecplugin.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Definition of TQTextCodecPlugin class
+**
+** Created : 010920
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTEXTCODECPLUGIN_H
+#define TQTEXTCODECPLUGIN_H
+
+#ifndef TQT_H
+#include "tqgplugin.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TEXTCODECPLUGIN
+class TQTextCodec;
+class TQTextCodecPluginPrivate;
+
+class TQ_EXPORT TQTextCodecPlugin : public TQGPlugin
+{
+ TQ_OBJECT
+public:
+ TQTextCodecPlugin();
+ ~TQTextCodecPlugin();
+
+ virtual TQStringList names() const = 0;
+ virtual TQTextCodec *createForName( const TQString &name ) = 0;
+
+ virtual TQValueList<int> mibEnums() const = 0;
+ virtual TQTextCodec *createForMib( int mib ) = 0;
+
+private:
+ TQTextCodecPluginPrivate *d;
+};
+#endif // TQT_NO_TEXTCODECPLUGIN
+#endif // TQTEXTCODECPLUGIN_H
diff --git a/tqtinterface/qt4/src/codecs/tqtsciicodec.cpp b/tqtinterface/qt4/src/codecs/tqtsciicodec.cpp
new file mode 100644
index 0000000..e35758b
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqtsciicodec.cpp
@@ -0,0 +1,528 @@
+/****************************************************************************
+**
+** Implementation of TQTsciiCodec class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Most of the code here was originally written by Hans Petter Bieker,
+// and is included in TQt with the author's permission, and the grateful
+// thanks of the Trolltech team.
+
+/*! \class TQTsciiCodec tqtsciicodec.h
+ \reentrant
+ \ingroup i18n
+
+ \brief The TQTsciiCodec class provides conversion to and from the Tamil TSCII encoding.
+
+ TSCII, formally the Tamil Standard Code Information Interchange
+ specification, is a commonly used charset for Tamils. The
+ official page for the standard is at
+ \link http://www.tamil.net/tscii/ http://www.tamil.net/tscii/\endlink
+
+ This codec uses the mapping table found at
+ \link http://www.geocities.com/Athens/5180/tsciiset.html
+ http://www.geocities.com/Athens/5180/tsciiset.html\endlink.
+ Tamil uses composed Unicode which might cause some
+ problems if you are using Unicode fonts instead of TSCII fonts.
+
+ Most of the code here was written by Hans Petter Bieker
+ and is included in TQt with the author's permission and the
+ grateful thanks of the Trolltech team.
+ Here is the copyright statement for the code as it was at the
+ point of contribution. Trolltech's subsequent modifications
+ are covered by the usual copyright for TQt.
+
+ \legalese
+
+ Copyright (C) 2000 Hans Petter Bieker. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ \list 1
+ \i Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ \i Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ \endlist
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+*/
+
+#include "tqtsciicodec.h"
+
+#ifndef TQT_NO_CODECS
+
+static unsigned char qt_UnicodeToTSCII(ushort u1, ushort u2, ushort u3);
+static unsigned int qt_TSCIIToUnicode(unsigned int code, uint *s);
+
+#define IsTSCIIChar(c) (((c) >= 0x80) && ((c) <= 0xfd))
+#define TQValidChar(u) ((u) ? TQChar((u)) : TQChar::tqreplacement)
+
+/*! \reimp */
+int TQTsciiCodec::mibEnum() const
+{
+ /* There is no MIBEnum for TSCII now */
+ return 2028;
+}
+
+/*! \reimp */
+TQCString TQTsciiCodec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ int l = TQMIN((int)uc.length(), lenInOut);
+ int rlen = l+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+ for (int i = 0; i < l; i++) {
+ TQChar ch = uc[i];
+ uchar j;
+ if ( ch.row() == 0x00 && ch.cell() < 0x80 ) {
+ // ASCII
+ j = ch.cell();
+ } else if ((j = qt_UnicodeToTSCII(uc[i].tqunicode(),
+ uc[i + 1].tqunicode(),
+ uc[i + 2].tqunicode()))) {
+ // We have to check the combined chars first!
+ i += 2;
+ } else if ((j = qt_UnicodeToTSCII(uc[i].tqunicode(),
+ uc[i + 1].tqunicode(), 0))) {
+ i++;
+ } else if ((j = qt_UnicodeToTSCII(uc[i].tqunicode(), 0, 0))) {
+ } else {
+ // Error
+ j = '?'; // unknown char
+ }
+ *cursor++ = j;
+ }
+ lenInOut = cursor - (uchar*)rstr.data();
+ *cursor = 0;
+ return rstr;
+}
+
+/*! \reimp */
+TQString TQTsciiCodec::toUnicode(const char* chars, int len) const
+{
+ TQString result;
+ for (int i = 0; i < len; i++) {
+ uchar ch = chars[i];
+ if ( ch < 0x80 ) {
+ // ASCII
+ result += TQChar(ch);
+ } else if ( IsTSCIIChar(ch) ) {
+ // TSCII
+ uint s[3];
+ uint u = qt_TSCIIToUnicode(ch, s);
+ uint *p = s;
+ while ( u-- ) {
+ uint c = *p++;
+ result += TQValidChar(c);
+ }
+ } else {
+ // Invalid
+ result += TQChar::tqreplacement;
+ }
+ }
+
+ return result;
+}
+
+/*! \reimp */
+const char* TQTsciiCodec::name() const
+{
+ return "TSCII";
+}
+
+/*! \reimp */
+int TQTsciiCodec::heuristicNameMatch(const char* hint) const
+{
+ const char *p = strchr(hint, '.');
+ if (p)
+ p++;
+ else
+ p = hint;
+ if (qstricmp(p, "TSCII") == 0)
+ return 4;
+ return TQTextCodec::heuristicNameMatch(hint);
+}
+
+/*! \reimp */
+int TQTsciiCodec::heuristicContentMatch(const char* chars, int len) const
+{
+ int score = 0;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ // No nulls allowed.
+ if ( !ch )
+ return -1;
+ if ( ch < 32 && ch != '\t' && ch != '\n' && ch != '\r' ) {
+ // Suspicious
+ if ( score )
+ score--;
+ } else if ( ch < 0x80 ) {
+ // Inconclusive
+ } else if ( IsTSCIIChar(ch) ) {
+ score++;
+ } else {
+ // Invalid
+ return -1;
+ }
+ }
+ return score;
+}
+
+static const int UnToTsLast = 124; // 125 items -- so the last will be 124
+static const ushort UnToTs [][4] = {
+ // *Sorted* list of TSCII maping for tqunicode chars
+ //FIRST SECOND THIRD TSCII
+ {0x00A0, 0x0000, 0x0000, 0xA0},
+ {0x00A9, 0x0000, 0x0000, 0xA9},
+ {0x0B83, 0x0000, 0x0000, 0xB7},
+ {0x0B85, 0x0000, 0x0000, 0xAB},
+ {0x0B86, 0x0000, 0x0000, 0xAC},
+ {0x0B87, 0x0000, 0x0000, 0xAD},
+ {0x0B88, 0x0000, 0x0000, 0xAE},
+ {0x0B89, 0x0000, 0x0000, 0xAF},
+ {0x0B8A, 0x0000, 0x0000, 0xB0},
+ {0x0B8E, 0x0000, 0x0000, 0xB1},
+ {0x0B8F, 0x0000, 0x0000, 0xB2},
+ {0x0B90, 0x0000, 0x0000, 0xB3},
+ {0x0B92, 0x0000, 0x0000, 0xB4},
+ {0x0B93, 0x0000, 0x0000, 0xB5},
+ {0x0B94, 0x0000, 0x0000, 0xB6},
+ {0x0B95, 0x0000, 0x0000, 0xB8},
+ {0x0B95, 0x0B82, 0x0000, 0xEC},
+ {0x0B95, 0x0BC1, 0x0000, 0xCC},
+ {0x0B95, 0x0BC2, 0x0000, 0xDC},
+ {0x0B99, 0x0000, 0x0000, 0xB9},
+ {0x0B99, 0x0B82, 0x0000, 0xED},
+ {0x0B99, 0x0BC1, 0x0000, 0x99},
+ {0x0B99, 0x0BC2, 0x0000, 0x9B},
+ {0x0B9A, 0x0000, 0x0000, 0xBA},
+ {0x0B9A, 0x0B82, 0x0000, 0xEE},
+ {0x0B9A, 0x0BC1, 0x0000, 0xCD},
+ {0x0B9A, 0x0BC2, 0x0000, 0xDD},
+ {0x0B9C, 0x0000, 0x0000, 0x83},
+ {0x0B9C, 0x0B82, 0x0000, 0x88},
+ {0x0B9E, 0x0000, 0x0000, 0xBB},
+ {0x0B9E, 0x0B82, 0x0000, 0xEF},
+ {0x0B9E, 0x0BC1, 0x0000, 0x9A},
+ {0x0B9E, 0x0BC2, 0x0000, 0x9C},
+ {0x0B9F, 0x0000, 0x0000, 0xBC},
+ {0x0B9F, 0x0B82, 0x0000, 0xF0},
+ {0x0B9F, 0x0BBF, 0x0000, 0xCA},
+ {0x0B9F, 0x0BC0, 0x0000, 0xCB},
+ {0x0B9F, 0x0BC1, 0x0000, 0xCE},
+ {0x0B9F, 0x0BC2, 0x0000, 0xDE},
+ {0x0BA1, 0x0B82, 0x0000, 0xF2},
+ {0x0BA3, 0x0000, 0x0000, 0xBD},
+ {0x0BA3, 0x0B82, 0x0000, 0xF1},
+ {0x0BA3, 0x0BC1, 0x0000, 0xCF},
+ {0x0BA3, 0x0BC2, 0x0000, 0xDF},
+ {0x0BA4, 0x0000, 0x0000, 0xBE},
+ {0x0BA4, 0x0BC1, 0x0000, 0xD0},
+ {0x0BA4, 0x0BC2, 0x0000, 0xE0},
+ {0x0BA8, 0x0000, 0x0000, 0xBF},
+ {0x0BA8, 0x0B82, 0x0000, 0xF3},
+ {0x0BA8, 0x0BC1, 0x0000, 0xD1},
+ {0x0BA8, 0x0BC2, 0x0000, 0xE1},
+ {0x0BA9, 0x0000, 0x0000, 0xC9},
+ {0x0BA9, 0x0B82, 0x0000, 0xFD},
+ {0x0BA9, 0x0BC1, 0x0000, 0xDB},
+ {0x0BA9, 0x0BC2, 0x0000, 0xEB},
+ {0x0BAA, 0x0000, 0x0000, 0xC0},
+ {0x0BAA, 0x0B82, 0x0000, 0xF4},
+ {0x0BAA, 0x0BC1, 0x0000, 0xD2},
+ {0x0BAA, 0x0BC2, 0x0000, 0xE2},
+ {0x0BAE, 0x0000, 0x0000, 0xC1},
+ {0x0BAE, 0x0B82, 0x0000, 0xF5},
+ {0x0BAE, 0x0BC1, 0x0000, 0xD3},
+ {0x0BAE, 0x0BC2, 0x0000, 0xE3},
+ {0x0BAF, 0x0000, 0x0000, 0xC2},
+ {0x0BAF, 0x0B82, 0x0000, 0xF6},
+ {0x0BAF, 0x0BC1, 0x0000, 0xD4},
+ {0x0BAF, 0x0BC2, 0x0000, 0xE4},
+ {0x0BB0, 0x0000, 0x0000, 0xC3},
+ {0x0BB0, 0x0B82, 0x0000, 0xF7},
+ {0x0BB0, 0x0BC1, 0x0000, 0xD5},
+ {0x0BB0, 0x0BC2, 0x0000, 0xE5},
+ {0x0BB1, 0x0000, 0x0000, 0xC8},
+ {0x0BB1, 0x0B82, 0x0000, 0xFC},
+ {0x0BB1, 0x0BC1, 0x0000, 0xDA},
+ {0x0BB1, 0x0BC2, 0x0000, 0xEA},
+ {0x0BB2, 0x0000, 0x0000, 0xC4},
+ {0x0BB2, 0x0B82, 0x0000, 0xF8},
+ {0x0BB2, 0x0BC1, 0x0000, 0xD6},
+ {0x0BB2, 0x0BC2, 0x0000, 0xE6},
+ {0x0BB3, 0x0000, 0x0000, 0xC7},
+ {0x0BB3, 0x0B82, 0x0000, 0xFB},
+ {0x0BB3, 0x0BC1, 0x0000, 0xD9},
+ {0x0BB3, 0x0BC2, 0x0000, 0xE9},
+ {0x0BB4, 0x0000, 0x0000, 0xC6},
+ {0x0BB4, 0x0B82, 0x0000, 0xFA},
+ {0x0BB4, 0x0BC1, 0x0000, 0xD8},
+ {0x0BB4, 0x0BC2, 0x0000, 0xE8},
+ {0x0BB5, 0x0000, 0x0000, 0xC5},
+ {0x0BB5, 0x0B82, 0x0000, 0xF9},
+ {0x0BB5, 0x0BC1, 0x0000, 0xD7},
+ {0x0BB5, 0x0BC2, 0x0000, 0xE7},
+ {0x0BB7, 0x0000, 0x0000, 0x84},
+ {0x0BB7, 0x0B82, 0x0000, 0x89},
+ {0x0BB8, 0x0000, 0x0000, 0x85},
+ {0x0BB8, 0x0B82, 0x0000, 0x8A},
+ {0x0BB9, 0x0000, 0x0000, 0x86},
+ {0x0BB9, 0x0B82, 0x0000, 0x8B},
+ {0x0BBE, 0x0000, 0x0000, 0xA1},
+ {0x0BBF, 0x0000, 0x0000, 0xA2},
+ {0x0BC0, 0x0000, 0x0000, 0xA3},
+ {0x0BC1, 0x0000, 0x0000, 0xA4},
+ {0x0BC2, 0x0000, 0x0000, 0xA5},
+ {0x0BC6, 0x0000, 0x0000, 0xA6},
+ {0x0BC7, 0x0000, 0x0000, 0xA7},
+ {0x0BC8, 0x0000, 0x0000, 0xA8},
+ {0x0BCC, 0x0000, 0x0000, 0xAA},
+ {0x0BE6, 0x0000, 0x0000, 0x80},
+ {0x0BE7, 0x0000, 0x0000, 0x81},
+ {0x0BE7, 0x0BB7, 0x0000, 0x87},
+ {0x0BE7, 0x0BB7, 0x0B82, 0x8C},
+ {0x0BE8, 0x0000, 0x0000, 0x8D},
+ {0x0BE9, 0x0000, 0x0000, 0x8E},
+ {0x0BEA, 0x0000, 0x0000, 0x8F},
+ {0x0BEB, 0x0000, 0x0000, 0x90},
+ {0x0BEC, 0x0000, 0x0000, 0x95},
+ {0x0BED, 0x0000, 0x0000, 0x96},
+ {0x0BEE, 0x0000, 0x0000, 0x97},
+ {0x0BEF, 0x0000, 0x0000, 0x98},
+ {0x0BF0, 0x0000, 0x0000, 0x9D},
+ {0x0BF1, 0x0000, 0x0000, 0x9E},
+ {0x0BF2, 0x0000, 0x0000, 0x9F},
+ {0x2018, 0x0000, 0x0000, 0x91},
+ {0x2019, 0x0000, 0x0000, 0x92},
+ {0x201C, 0x0000, 0x0000, 0x93},
+ {0x201C, 0x0000, 0x0000, 0x94}
+};
+
+static const ushort TsToUn [][3] = {
+ // Starting at 0x80
+ {0x0BE6, 0x0000, 0x0000},
+ {0x0BE7, 0x0000, 0x0000},
+ {0x0000, 0x0000, 0x0000}, // unknown
+ {0x0B9C, 0x0000, 0x0000},
+ {0x0BB7, 0x0000, 0x0000},
+ {0x0BB8, 0x0000, 0x0000},
+ {0x0BB9, 0x0000, 0x0000},
+ {0x0BE7, 0x0BB7, 0x0000},
+ {0x0B9C, 0x0B82, 0x0000},
+ {0x0BB7, 0x0B82, 0x0000},
+ {0x0BB8, 0x0B82, 0x0000},
+ {0x0BB9, 0x0B82, 0x0000},
+ {0x0BE7, 0x0BB7, 0x0B82},
+ {0x0BE8, 0x0000, 0x0000},
+ {0x0BE9, 0x0000, 0x0000},
+ {0x0BEA, 0x0000, 0x0000},
+ {0x0BEB, 0x0000, 0x0000},
+ {0x2018, 0x0000, 0x0000},
+ {0x2019, 0x0000, 0x0000},
+ {0x201C, 0x0000, 0x0000},
+ {0x201C, 0x0000, 0x0000}, // two of the same??
+ {0x0BEC, 0x0000, 0x0000},
+ {0x0BED, 0x0000, 0x0000},
+ {0x0BEE, 0x0000, 0x0000},
+ {0x0BEF, 0x0000, 0x0000},
+ {0x0B99, 0x0BC1, 0x0000},
+ {0x0B9E, 0x0BC1, 0x0000},
+ {0x0B99, 0x0BC2, 0x0000},
+ {0x0B9E, 0x0BC2, 0x0000},
+ {0x0BF0, 0x0000, 0x0000},
+ {0x0BF1, 0x0000, 0x0000},
+ {0x0BF2, 0x0000, 0x0000},
+ {0x00A0, 0x0000, 0x0000},
+ {0x0BBE, 0x0000, 0x0000},
+ {0x0BBF, 0x0000, 0x0000},
+ {0x0BC0, 0x0000, 0x0000},
+ {0x0BC1, 0x0000, 0x0000},
+ {0x0BC2, 0x0000, 0x0000},
+ {0x0BC6, 0x0000, 0x0000},
+ {0x0BC7, 0x0000, 0x0000},
+ {0x0BC8, 0x0000, 0x0000},
+ {0x00A9, 0x0000, 0x0000},
+ {0x0BCC, 0x0000, 0x0000},
+ {0x0B85, 0x0000, 0x0000},
+ {0x0B86, 0x0000, 0x0000},
+ {0x0B87, 0x0000, 0x0000},
+ {0x0B88, 0x0000, 0x0000},
+ {0x0B89, 0x0000, 0x0000},
+ {0x0B8A, 0x0000, 0x0000},
+ {0x0B8E, 0x0000, 0x0000},
+ {0x0B8F, 0x0000, 0x0000},
+ {0x0B90, 0x0000, 0x0000},
+ {0x0B92, 0x0000, 0x0000},
+ {0x0B93, 0x0000, 0x0000},
+ {0x0B94, 0x0000, 0x0000},
+ {0x0B83, 0x0000, 0x0000},
+ {0x0B95, 0x0000, 0x0000},
+ {0x0B99, 0x0000, 0x0000},
+ {0x0B9A, 0x0000, 0x0000},
+ {0x0B9E, 0x0000, 0x0000},
+ {0x0B9F, 0x0000, 0x0000},
+ {0x0BA3, 0x0000, 0x0000},
+ {0x0BA4, 0x0000, 0x0000},
+ {0x0BA8, 0x0000, 0x0000},
+ {0x0BAA, 0x0000, 0x0000},
+ {0x0BAE, 0x0000, 0x0000},
+ {0x0BAF, 0x0000, 0x0000},
+ {0x0BB0, 0x0000, 0x0000},
+ {0x0BB2, 0x0000, 0x0000},
+ {0x0BB5, 0x0000, 0x0000},
+ {0x0BB4, 0x0000, 0x0000},
+ {0x0BB3, 0x0000, 0x0000},
+ {0x0BB1, 0x0000, 0x0000},
+ {0x0BA9, 0x0000, 0x0000},
+ {0x0B9F, 0x0BBF, 0x0000},
+ {0x0B9F, 0x0BC0, 0x0000},
+ {0x0B95, 0x0BC1, 0x0000},
+ {0x0B9A, 0x0BC1, 0x0000},
+ {0x0B9F, 0x0BC1, 0x0000},
+ {0x0BA3, 0x0BC1, 0x0000},
+ {0x0BA4, 0x0BC1, 0x0000},
+ {0x0BA8, 0x0BC1, 0x0000},
+ {0x0BAA, 0x0BC1, 0x0000},
+ {0x0BAE, 0x0BC1, 0x0000},
+ {0x0BAF, 0x0BC1, 0x0000},
+ {0x0BB0, 0x0BC1, 0x0000},
+ {0x0BB2, 0x0BC1, 0x0000},
+ {0x0BB5, 0x0BC1, 0x0000},
+ {0x0BB4, 0x0BC1, 0x0000},
+ {0x0BB3, 0x0BC1, 0x0000},
+ {0x0BB1, 0x0BC1, 0x0000},
+ {0x0BA9, 0x0BC1, 0x0000},
+ {0x0B95, 0x0BC2, 0x0000},
+ {0x0B9A, 0x0BC2, 0x0000},
+ {0x0B9F, 0x0BC2, 0x0000},
+ {0x0BA3, 0x0BC2, 0x0000},
+ {0x0BA4, 0x0BC2, 0x0000},
+ {0x0BA8, 0x0BC2, 0x0000},
+ {0x0BAA, 0x0BC2, 0x0000},
+ {0x0BAE, 0x0BC2, 0x0000},
+ {0x0BAF, 0x0BC2, 0x0000},
+ {0x0BB0, 0x0BC2, 0x0000},
+ {0x0BB2, 0x0BC2, 0x0000},
+ {0x0BB5, 0x0BC2, 0x0000},
+ {0x0BB4, 0x0BC2, 0x0000},
+ {0x0BB3, 0x0BC2, 0x0000},
+ {0x0BB1, 0x0BC2, 0x0000},
+ {0x0BA9, 0x0BC2, 0x0000},
+ {0x0B95, 0x0B82, 0x0000},
+ {0x0B99, 0x0B82, 0x0000},
+ {0x0B9A, 0x0B82, 0x0000},
+ {0x0B9E, 0x0B82, 0x0000},
+ {0x0B9F, 0x0B82, 0x0000},
+ {0x0BA3, 0x0B82, 0x0000},
+ {0x0BA1, 0x0B82, 0x0000},
+ {0x0BA8, 0x0B82, 0x0000},
+ {0x0BAA, 0x0B82, 0x0000},
+ {0x0BAE, 0x0B82, 0x0000},
+ {0x0BAF, 0x0B82, 0x0000},
+ {0x0BB0, 0x0B82, 0x0000},
+ {0x0BB2, 0x0B82, 0x0000},
+ {0x0BB5, 0x0B82, 0x0000},
+ {0x0BB4, 0x0B82, 0x0000},
+ {0x0BB3, 0x0B82, 0x0000},
+ {0x0BB1, 0x0B82, 0x0000},
+ {0x0BA9, 0x0B82, 0x0000}
+};
+
+static int cmp(const ushort *s1, const ushort *s2, size_t len)
+{
+ int diff = 0;
+
+ while (len-- && (diff = *s1++ - *s2++) == 0)
+ ;
+
+ return diff;
+}
+
+static unsigned char qt_UnicodeToTSCII(ushort u1, ushort u2, ushort u3)
+{
+ ushort s[3];
+ s[0] = u1;
+ s[1] = u2;
+ s[2] = u3;
+
+ int a = 0; // start pos
+ int b = UnToTsLast; // end pos
+
+ // do a binary search for the composed tqunicode in the list
+ while (a <= b) {
+ int w = (a + b) / 2;
+ int j = cmp(UnToTs[w], s, 3);
+
+ if (j == 0)
+ // found it
+ return UnToTs[w][3];
+
+ if (j < 0)
+ a = w + 1;
+ else
+ b = w - 1;
+ }
+
+ return 0;
+}
+
+static unsigned int qt_TSCIIToUnicode(uint code, uint *s)
+{
+ int len = 0;
+ for (int i = 0; i < 3; i++) {
+ uint u = TsToUn[code & 0x7f][i];
+ s[i] = u;
+ if (s[i]) len = i + 1;
+ }
+
+ return len;
+}
+
+#endif
+
diff --git a/tqtinterface/qt4/src/codecs/tqtsciicodec.h b/tqtinterface/qt4/src/codecs/tqtsciicodec.h
new file mode 100644
index 0000000..11d5c8b
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqtsciicodec.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Definition of TQTsciiCodec class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Most of the code here was originally written by Hans Petter Bieker,
+// and is included in TQt with the author's permission, and the grateful
+// thanks of the Trolltech team.
+
+/*
+ * Copyright (C) 2000 Hans Petter Bieker. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef TQTSCIICODEC_H
+#define TQTSCIICODEC_H
+
+#ifndef TQT_H
+#include "tqtextcodec.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_CODECS
+
+class TQ_EXPORT TQTsciiCodec : public TQTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+ int heuristicNameMatch(const char* hint) const;
+};
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/codecs/tqutfcodec.cpp b/tqtinterface/qt4/src/codecs/tqutfcodec.cpp
new file mode 100644
index 0000000..5b263e9
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqutfcodec.cpp
@@ -0,0 +1,350 @@
+/****************************************************************************
+**
+** Implementation of TQUtf{8,16}Codec class
+**
+** Created : 981015
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqutfcodec.h"
+
+#ifndef TQT_NO_TEXTCODEC
+
+int TQUtf8Codec::mibEnum() const
+{
+ return 106;
+}
+
+TQCString TQUtf8Codec::fromUnicode(const TQString& uc, int& lenInOut) const
+{
+ int l = uc.length();
+ if (lenInOut > 0)
+ l = TQMIN(l, lenInOut);
+ int rlen = l*3+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+ const TQChar *ch = uc.tqunicode();
+ for (int i=0; i < l; i++) {
+ uint u = ch->tqunicode();
+ if ( u < 0x80 ) {
+ *cursor++ = (uchar)u;
+ } else {
+ if ( u < 0x0800 ) {
+ *cursor++ = 0xc0 | ((uchar) (u >> 6));
+ } else {
+ if (u >= 0xd800 && u < 0xdc00 && i < l-1) {
+ unsigned short low = ch[1].tqunicode();
+ if (low >= 0xdc00 && low < 0xe000) {
+ ++ch;
+ ++i;
+ u = (u - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ }
+ }
+ if (u > 0xffff) {
+ // see TQString::fromUtf8() and TQString::utf8() for explanations
+ if (u > 0x10fe00 && u < 0x10ff00) {
+ *cursor++ = (u - 0x10fe00);
+ ++ch;
+ continue;
+ } else {
+ *cursor++ = 0xf0 | ((uchar) (u >> 18));
+ *cursor++ = 0x80 | ( ((uchar) (u >> 12)) & 0x3f);
+ }
+ } else {
+ *cursor++ = 0xe0 | ((uchar) (u >> 12));
+ }
+ *cursor++ = 0x80 | ( ((uchar) (u >> 6)) & 0x3f);
+ }
+ *cursor++ = 0x80 | ((uchar) (u&0x3f));
+ }
+ ++ch;
+ }
+ *cursor = 0;
+ lenInOut = cursor - (uchar*)rstr.data();
+ ((TQByteArray&)rstr).resize(lenInOut+1);
+ return rstr;
+}
+
+TQString TQUtf8Codec::toUnicode(const char* chars, int len) const
+{
+ if (len > 3 && (uchar)chars[0] == 0xef && (uchar)chars[1] == 0xbb && (uchar)chars[2] == 0xbf) {
+ // starts with a byte order mark
+ chars += 3;
+ len -= 3;
+ }
+ return TQString::fromUtf8( chars, len );
+}
+
+
+const char* TQUtf8Codec::name() const
+{
+ return "UTF-8";
+}
+
+int TQUtf8Codec::heuristicContentMatch(const char* chars, int len) const
+{
+ int score = 0;
+ for (int i=0; i<len; i++) {
+ uchar ch = chars[i];
+ // No nulls allowed.
+ if ( !ch )
+ return -1;
+ if ( ch < 128 ) {
+ // Inconclusive
+ score++;
+ } else if ( (ch&0xe0) == 0xc0 ) {
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( (c2&0xc0) != 0x80 )
+ return -1;
+ score+=3;
+ }
+ } else if ( (ch&0xf0) == 0xe0 ) {
+ if ( i < len-1 ) {
+ uchar c2 = chars[++i];
+ if ( (c2&0xc0) != 0x80 ) {
+ return -1;
+#if 0
+ if ( i < len-1 ) {
+ uchar c3 = chars[++i];
+ if ( (c3&0xc0) != 0x80 )
+ return -1;
+ score+=3;
+ }
+#endif
+ }
+ score+=2;
+ }
+ }
+ }
+ return score;
+}
+
+
+
+
+class TQUtf8Decoder : public TQTextDecoder {
+ uint uc;
+ uint min_uc;
+ int need;
+ bool headerDone;
+public:
+ TQUtf8Decoder() : need(0), headerDone(FALSE)
+ {
+ }
+
+ TQString toUnicode(const char* chars, int len)
+ {
+ TQString result;
+ result.setLength( len + 1 ); // worst case
+ TQChar *qch = (TQChar *)result.tqunicode();
+ uchar ch;
+ int error = -1;
+ for (int i=0; i<len; i++) {
+ ch = chars[i];
+ if (need) {
+ if ( (ch&0xc0) == 0x80 ) {
+ uc = (uc << 6) | (ch & 0x3f);
+ need--;
+ if ( !need ) {
+ if (uc > 0xffff) {
+ // surrogate pair
+ uc -= 0x10000;
+ unsigned short high = uc/0x400 + 0xd800;
+ unsigned short low = uc%0x400 + 0xdc00;
+ *qch++ = TQChar(high);
+ *qch++ = TQChar(low);
+ headerDone = TRUE;
+ } else if ((uc < min_uc) || (uc >= 0xd800 && uc <= 0xdfff) || (uc >= 0xfffe)) {
+ *qch++ = TQChar::tqreplacement;
+ } else {
+ if (headerDone || TQChar(uc) != TQChar::byteOrderMark)
+ *qch++ = uc;
+ headerDone = TRUE;
+ }
+ }
+ } else {
+ // error
+ i = error;
+ *qch++ = TQChar::tqreplacement;
+ need = 0;
+ }
+ } else {
+ if ( ch < 128 ) {
+ *qch++ = ch;
+ headerDone = TRUE;
+ } else if ((ch & 0xe0) == 0xc0) {
+ uc = ch & 0x1f;
+ need = 1;
+ error = i;
+ min_uc = 0x80;
+ } else if ((ch & 0xf0) == 0xe0) {
+ uc = ch & 0x0f;
+ need = 2;
+ error = i;
+ min_uc = 0x800;
+ } else if ((ch&0xf8) == 0xf0) {
+ uc = ch & 0x07;
+ need = 3;
+ error = i;
+ min_uc = 0x10000;
+ } else {
+ // error
+ *qch++ = TQChar::tqreplacement;
+ }
+ }
+ }
+ result.truncate( qch - result.tqunicode() );
+ return result;
+ }
+};
+
+TQTextDecoder* TQUtf8Codec::makeDecoder() const
+{
+ return new TQUtf8Decoder;
+}
+
+
+
+
+
+
+int TQUtf16Codec::mibEnum() const
+{
+ return 1000;
+}
+
+const char* TQUtf16Codec::name() const
+{
+ return "ISO-10646-UCS-2";
+}
+
+int TQUtf16Codec::heuristicContentMatch(const char* chars, int len) const
+{
+ uchar* uchars = (uchar*)chars;
+ if ( len >= 2 && (uchars[0] == 0xff && uchars[1] == 0xfe ||
+ uchars[1] == 0xff && uchars[0] == 0xfe) )
+ return len;
+ else
+ return 0;
+}
+
+
+
+
+class TQUtf16Encoder : public TQTextEncoder {
+ bool headerdone;
+public:
+ TQUtf16Encoder() : headerdone(FALSE)
+ {
+ }
+
+ TQCString fromUnicode(const TQString& uc, int& lenInOut)
+ {
+ if ( headerdone ) {
+ lenInOut = uc.length()*sizeof(TQChar);
+ TQCString d(lenInOut);
+ memcpy(d.data(),uc.tqunicode(),lenInOut);
+ return d;
+ } else {
+ headerdone = TRUE;
+ lenInOut = (1+uc.length())*sizeof(TQChar);
+ TQCString d(lenInOut);
+ memcpy(d.data(),&TQChar::byteOrderMark,sizeof(TQChar));
+ memcpy(d.data()+sizeof(TQChar),uc.tqunicode(),uc.length()*sizeof(TQChar));
+ return d;
+ }
+ }
+};
+
+class TQUtf16Decoder : public TQTextDecoder {
+ uchar buf;
+ bool half;
+ bool swap;
+ bool headerdone;
+
+public:
+ TQUtf16Decoder() : half(FALSE), swap(FALSE), headerdone(FALSE)
+ {
+ }
+
+ TQString toUnicode(const char* chars, int len)
+ {
+ TQString result;
+ result.setLength( len ); // worst case
+ TQChar *qch = (TQChar *)result.tqunicode();
+ TQChar ch;
+ while ( len-- ) {
+ if ( half ) {
+ if ( swap ) {
+ ch.setRow( *chars++ );
+ ch.setCell( buf );
+ } else {
+ ch.setRow( buf );
+ ch.setCell( *chars++ );
+ }
+ if ( !headerdone ) {
+ if ( ch == TQChar::byteOrderSwapped ) {
+ swap = !swap;
+ } else if ( ch == TQChar::byteOrderMark ) {
+ // Ignore ZWNBSP
+ } else {
+ *qch++ = ch;
+ }
+ headerdone = TRUE;
+ } else
+ *qch++ = ch;
+ half = FALSE;
+ } else {
+ buf = *chars++;
+ half = TRUE;
+ }
+ }
+ result.truncate( qch - result.tqunicode() );
+ return result;
+ }
+};
+
+TQTextDecoder* TQUtf16Codec::makeDecoder() const
+{
+ return new TQUtf16Decoder;
+}
+
+TQTextEncoder* TQUtf16Codec::makeEncoder() const
+{
+ return new TQUtf16Encoder;
+}
+
+#endif //TQT_NO_TEXTCODEC
diff --git a/tqtinterface/qt4/src/codecs/tqutfcodec.h b/tqtinterface/qt4/src/codecs/tqutfcodec.h
new file mode 100644
index 0000000..2ab30a8
--- /dev/null
+++ b/tqtinterface/qt4/src/codecs/tqutfcodec.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Definition of TQUtf{8,16}Codec class
+**
+** Created : 981015
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQUTFCODEC_H
+#define TQUTFCODEC_H
+
+#ifndef TQT_H
+#include "tqtextcodec.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TEXTCODEC
+
+class TQ_EXPORT TQUtf8Codec : public TQTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+
+ TQTextDecoder* makeDecoder() const;
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTextCodec::fromUnicode;
+#endif
+ TQCString fromUnicode(const TQString& uc, int& lenInOut) const;
+ TQString toUnicode(const char* chars, int len) const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+};
+
+class TQ_EXPORT TQUtf16Codec : public TQTextCodec {
+public:
+ virtual int mibEnum() const;
+ const char* name() const;
+
+ TQTextDecoder* makeDecoder() const;
+ TQTextEncoder* makeEncoder() const;
+
+ int heuristicContentMatch(const char* chars, int len) const;
+};
+
+#endif //TQT_NO_TEXTCODEC
+#endif // TQUTFCODEC_H
diff --git a/tqtinterface/qt4/src/compat/tqapp.h b/tqtinterface/qt4/src/compat/tqapp.h
new file mode 100644
index 0000000..7ecec54
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqapp.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQAPP_H
+#define TQAPP_H
+#include "tqapplication.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqarray.h b/tqtinterface/qt4/src/compat/tqarray.h
new file mode 100644
index 0000000..503d216
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqarray.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQARRAY_H
+#define TQARRAY_H
+#ifndef TQT_NO_COMPAT
+#include "tqmemarray.h"
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqbitarry.h b/tqtinterface/qt4/src/compat/tqbitarry.h
new file mode 100644
index 0000000..729bf2e
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqbitarry.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQBITARRY_H
+#define TQBITARRY_H
+#include "tqbitarray.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqbttngrp.h b/tqtinterface/qt4/src/compat/tqbttngrp.h
new file mode 100644
index 0000000..a465689
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqbttngrp.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQBTTNGRP_H
+#define TQBTTNGRP_H
+#include "tqbuttongroup.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqchkbox.h b/tqtinterface/qt4/src/compat/tqchkbox.h
new file mode 100644
index 0000000..4edcdb9
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqchkbox.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQCHKBOX_H
+#define TQCHKBOX_H
+#include "tqcheckbox.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqclipbrd.h b/tqtinterface/qt4/src/compat/tqclipbrd.h
new file mode 100644
index 0000000..11790e2
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqclipbrd.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQCLIPBRD_H
+#define TQCLIPBRD_H
+#include "tqclipboard.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqcollect.h b/tqtinterface/qt4/src/compat/tqcollect.h
new file mode 100644
index 0000000..87462aa
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqcollect.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQCOLLECT_H
+#define TQCOLLECT_H
+#include "tqptrcollection.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqcollection.h b/tqtinterface/qt4/src/compat/tqcollection.h
new file mode 100644
index 0000000..a527638
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqcollection.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQCOLLECTION_H
+#define TQCOLLECTION_H
+#ifndef TQT_NO_COMPAT
+#include "tqptrcollection.h"
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqcombo.h b/tqtinterface/qt4/src/compat/tqcombo.h
new file mode 100644
index 0000000..f3c5ad6
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqcombo.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQCOMBO_H
+#define TQCOMBO_H
+#include "tqcombobox.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqconnect.h b/tqtinterface/qt4/src/compat/tqconnect.h
new file mode 100644
index 0000000..803e99f
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqconnect.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQCONNECT_H
+#define TQCONNECT_H
+#include "tqconnection.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqdatetm.h b/tqtinterface/qt4/src/compat/tqdatetm.h
new file mode 100644
index 0000000..e8d0d73
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqdatetm.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQDATETM_H
+#define TQDATETM_H
+#include "tqdatetime.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqdrawutl.h b/tqtinterface/qt4/src/compat/tqdrawutl.h
new file mode 100644
index 0000000..22176da
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqdrawutl.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQDRAWUTL_H
+#define TQDRAWUTL_H
+#include "tqdrawutil.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqdstream.h b/tqtinterface/qt4/src/compat/tqdstream.h
new file mode 100644
index 0000000..e2fe38a
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqdstream.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQDSTREAM_H
+#define TQDSTREAM_H
+#include "tqdatastream.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqfiledef.h b/tqtinterface/qt4/src/compat/tqfiledef.h
new file mode 100644
index 0000000..1d54505
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqfiledef.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQFILEDEF_H
+#define TQFILEDEF_H
+#include <private/tqfiledefs_p.h>
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqfiledlg.h b/tqtinterface/qt4/src/compat/tqfiledlg.h
new file mode 100644
index 0000000..2f08cc2
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqfiledlg.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQFILEDLG_H
+#define TQFILEDLG_H
+#include "tqfiledialog.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqfileinf.h b/tqtinterface/qt4/src/compat/tqfileinf.h
new file mode 100644
index 0000000..56a29e1
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqfileinf.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQFILEINF_H
+#define TQFILEINF_H
+#include "tqfileinfo.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqfontinf.h b/tqtinterface/qt4/src/compat/tqfontinf.h
new file mode 100644
index 0000000..13cc1ca
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqfontinf.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQFONTINF_H
+#define TQFONTINF_H
+#include "tqfontinfo.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqfontmet.h b/tqtinterface/qt4/src/compat/tqfontmet.h
new file mode 100644
index 0000000..277c51d
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqfontmet.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQFONTMET_H
+#define TQFONTMET_H
+#include "tqfontmetrics.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqgrpbox.h b/tqtinterface/qt4/src/compat/tqgrpbox.h
new file mode 100644
index 0000000..ebbd0f0
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqgrpbox.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQGRPBOX_H
+#define TQGRPBOX_H
+#include "tqgroupbox.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqintcach.h b/tqtinterface/qt4/src/compat/tqintcach.h
new file mode 100644
index 0000000..55c1164
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqintcach.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQINTCACH_H
+#define TQINTCACH_H
+#include "tqintcache.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqiodev.h b/tqtinterface/qt4/src/compat/tqiodev.h
new file mode 100644
index 0000000..43c8b00
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqiodev.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQIODEV_H
+#define TQIODEV_H
+#include "tqiodevice.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqlcdnum.h b/tqtinterface/qt4/src/compat/tqlcdnum.h
new file mode 100644
index 0000000..8fa1003
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqlcdnum.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQLCDNUM_H
+#define TQLCDNUM_H
+#include "tqlcdnumber.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqlined.h b/tqtinterface/qt4/src/compat/tqlined.h
new file mode 100644
index 0000000..c98cec5
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqlined.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQLINED_H
+#define TQLINED_H
+#include "tqlineedit.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqlist.h b/tqtinterface/qt4/src/compat/tqlist.h
new file mode 100644
index 0000000..ccdfab7
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqlist.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQLIST_H
+#define TQLIST_H
+#ifndef TQT_NO_COMPAT
+#include "tqptrlist.h"
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqmenudta.h b/tqtinterface/qt4/src/compat/tqmenudta.h
new file mode 100644
index 0000000..650de62
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqmenudta.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQMENUDTA_H
+#define TQMENUDTA_H
+#include "tqmenudata.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqmetaobj.h b/tqtinterface/qt4/src/compat/tqmetaobj.h
new file mode 100644
index 0000000..e8bebb3
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqmetaobj.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQMETAOBJ_H
+#define TQMETAOBJ_H
+#include "tqmetaobject.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqmlined.h b/tqtinterface/qt4/src/compat/tqmlined.h
new file mode 100644
index 0000000..72b682a
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqmlined.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQMLINED_H
+#define TQMLINED_H
+#include "tqmultilineedit.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqmsgbox.h b/tqtinterface/qt4/src/compat/tqmsgbox.h
new file mode 100644
index 0000000..c45ff9b
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqmsgbox.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQMSGBOX_H
+#define TQMSGBOX_H
+#include "tqmessagebox.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqmultilinedit.h b/tqtinterface/qt4/src/compat/tqmultilinedit.h
new file mode 100644
index 0000000..a1e5d89
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqmultilinedit.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQMULTILINEDIT_H
+#define TQMULTILINEDIT_H
+#include "tqmultilineedit.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqobjcoll.h b/tqtinterface/qt4/src/compat/tqobjcoll.h
new file mode 100644
index 0000000..9451bbb
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqobjcoll.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQOBJCOLL_H
+#define TQOBJCOLL_H
+#include "tqobjectlist.h"
+#include "tqobjectdict.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqobjdefs.h b/tqtinterface/qt4/src/compat/tqobjdefs.h
new file mode 100644
index 0000000..07f6f69
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqobjdefs.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQOBJDEFS_H
+#define TQOBJDEFS_H
+#include "tqobjectdefs.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqpaintd.h b/tqtinterface/qt4/src/compat/tqpaintd.h
new file mode 100644
index 0000000..6f14ba6
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqpaintd.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPAINTD_H
+#define TQPAINTD_H
+#include "tqpaintdevice.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqpaintdc.h b/tqtinterface/qt4/src/compat/tqpaintdc.h
new file mode 100644
index 0000000..01dfc78
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqpaintdc.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPAINTDC_H
+#define TQPAINTDC_H
+#include "tqpaintdevicedefs.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqpdevmet.h b/tqtinterface/qt4/src/compat/tqpdevmet.h
new file mode 100644
index 0000000..e39869e
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqpdevmet.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPDEVMET_H
+#define TQPDEVMET_H
+#include "tqpaintdevicemetrics.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqpmcache.h b/tqtinterface/qt4/src/compat/tqpmcache.h
new file mode 100644
index 0000000..b887ef8
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqpmcache.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPMCACHE_H
+#define TQPMCACHE_H
+#include "tqpixmapcache.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqpntarry.h b/tqtinterface/qt4/src/compat/tqpntarry.h
new file mode 100644
index 0000000..0d2255d
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqpntarry.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPNTARRY_H
+#define TQPNTARRY_H
+#include "tqpointarray.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqpopmenu.h b/tqtinterface/qt4/src/compat/tqpopmenu.h
new file mode 100644
index 0000000..4da4417
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqpopmenu.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPOPMENU_H
+#define TQPOPMENU_H
+#include "tqpopupmenu.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqprndlg.h b/tqtinterface/qt4/src/compat/tqprndlg.h
new file mode 100644
index 0000000..d6ee6fd
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqprndlg.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPRNDLG_H
+#define TQPRNDLG_H
+#include "tqprintdialog.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqprogbar.h b/tqtinterface/qt4/src/compat/tqprogbar.h
new file mode 100644
index 0000000..a13ea32
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqprogbar.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPROGBAR_H
+#define TQPROGBAR_H
+#include "tqprogressbar.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqprogdlg.h b/tqtinterface/qt4/src/compat/tqprogdlg.h
new file mode 100644
index 0000000..de3923e
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqprogdlg.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPROGDLG_H
+#define TQPROGDLG_H
+#include "tqprogressdialog.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqpsprn.h b/tqtinterface/qt4/src/compat/tqpsprn.h
new file mode 100644
index 0000000..1232c53
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqpsprn.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPSPRN_H
+#define TQPSPRN_H
+#include <private/tqpsprinter_p.h>
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqpushbt.h b/tqtinterface/qt4/src/compat/tqpushbt.h
new file mode 100644
index 0000000..154db8c
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqpushbt.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQPUSHBT_H
+#define TQPUSHBT_H
+#include "tqpushbutton.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqqueue.h b/tqtinterface/qt4/src/compat/tqqueue.h
new file mode 100644
index 0000000..b539ea0
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqqueue.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQQUEUE_H
+#define TQQUEUE_H
+#ifndef TQT_NO_COMPAT
+#include "tqptrqueue.h"
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqradiobt.h b/tqtinterface/qt4/src/compat/tqradiobt.h
new file mode 100644
index 0000000..7c63f89
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqradiobt.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQRADIOBT_H
+#define TQRADIOBT_H
+#include "tqradiobutton.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqrangect.h b/tqtinterface/qt4/src/compat/tqrangect.h
new file mode 100644
index 0000000..d4e93e4
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqrangect.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQRANGECT_H
+#define TQRANGECT_H
+#include "tqrangecontrol.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqscrbar.h b/tqtinterface/qt4/src/compat/tqscrbar.h
new file mode 100644
index 0000000..75196ac
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqscrbar.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQSCRBAR_H
+#define TQSCRBAR_H
+#include "tqscrollbar.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqsocknot.h b/tqtinterface/qt4/src/compat/tqsocknot.h
new file mode 100644
index 0000000..2db1894
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqsocknot.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQSOCKNOT_H
+#define TQSOCKNOT_H
+#include "tqsocketnotifier.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqstack.h b/tqtinterface/qt4/src/compat/tqstack.h
new file mode 100644
index 0000000..35a27a1
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqstack.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQSTACK_H
+#define TQSTACK_H
+#ifndef TQT_NO_COMPAT
+#include "tqptrstack.h"
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqtabdlg.h b/tqtinterface/qt4/src/compat/tqtabdlg.h
new file mode 100644
index 0000000..8a47ec0
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqtabdlg.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQTABDLG_H
+#define TQTABDLG_H
+#include "tqtabdialog.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqtstream.h b/tqtinterface/qt4/src/compat/tqtstream.h
new file mode 100644
index 0000000..d32c018
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqtstream.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQTSTREAM_H
+#define TQTSTREAM_H
+#include "tqtextstream.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqvector.h b/tqtinterface/qt4/src/compat/tqvector.h
new file mode 100644
index 0000000..58c7555
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqvector.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQVECTOR_H
+#define TQVECTOR_H
+#ifndef TQT_NO_COMPAT
+#include "tqptrvector.h"
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqwidcoll.h b/tqtinterface/qt4/src/compat/tqwidcoll.h
new file mode 100644
index 0000000..52b3008
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqwidcoll.h
@@ -0,0 +1,26 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQWIDCOLL_H
+#define TQWIDCOLL_H
+#include "tqwidgetlist.h"
+#include "tqwidgetintdict.h"
+#endif
diff --git a/tqtinterface/qt4/src/compat/tqwindefs.h b/tqtinterface/qt4/src/compat/tqwindefs.h
new file mode 100644
index 0000000..d9cfb8f
--- /dev/null
+++ b/tqtinterface/qt4/src/compat/tqwindefs.h
@@ -0,0 +1,25 @@
+/****************************************************************************
+**
+** Compatibility file - should only be included by legacy code.
+** It #includes the file which obsoletes this one.
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be distributed under the terms of the Q Public License
+** as defined by Trolltech ASA of Norway and appearing in the file
+** LICENSE.TQPL included in the packaging of this file.
+**
+** Licensees holding valid TQt Professional Edition licenses may use this
+** file in accordance with the TQt Professional Edition License Agreement
+** provided with the TQt Professional Edition.
+**
+** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
+** information about the Professional Edition licensing, or see
+** http://www.trolltech.com/qpl/ for TQPL licensing information.
+**
+*****************************************************************************/
+#ifndef TQWINDEFS_H
+#define TQWINDEFS_H
+#include "tqwindowdefs.h"
+#endif
diff --git a/tqtinterface/qt4/src/dialogs/qt_dialogs.pri b/tqtinterface/qt4/src/dialogs/qt_dialogs.pri
new file mode 100644
index 0000000..6d9191d
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/qt_dialogs.pri
@@ -0,0 +1,33 @@
+# Qt dialogs module
+
+dialogs {
+ DIALOGS_P = dialogs
+
+ HEADERS += $$DIALOGS_H/tqcolordialog.h \
+ $$DIALOGS_H/tqdialog.h \
+ $$DIALOGS_H/tqerrormessage.h \
+ $$DIALOGS_H/tqfiledialog.h \
+ $$DIALOGS_H/tqfontdialog.h \
+ $$DIALOGS_H/tqmessagebox.h \
+ $$DIALOGS_H/tqprogressdialog.h \
+ $$DIALOGS_H/tqsemimodal.h \
+ $$DIALOGS_H/tqtabdialog.h \
+ $$DIALOGS_H/tqwizard.h \
+ $$DIALOGS_H/tqinputdialog.h
+
+ !embedded:mac:SOURCES += $$DIALOGS_CPP/tqfiledialog_mac.cpp $$DIALOGS_CPP/tqcolordialog_mac.cpp
+ win32:SOURCES += $$DIALOGS_CPP/tqfiledialog_win.cpp
+ unix:SOURCES += $$DIALOGS_CPP/tqprintdialog.cpp
+ unix:HEADERS += $$DIALOGS_H/tqprintdialog.h
+
+ SOURCES += $$DIALOGS_CPP/tqcolordialog.cpp \
+ $$DIALOGS_CPP/tqdialog.cpp \
+ $$DIALOGS_CPP/tqerrormessage.cpp \
+ $$DIALOGS_CPP/tqfiledialog.cpp \
+ $$DIALOGS_CPP/tqfontdialog.cpp \
+ $$DIALOGS_CPP/tqmessagebox.cpp \
+ $$DIALOGS_CPP/tqprogressdialog.cpp \
+ $$DIALOGS_CPP/tqtabdialog.cpp \
+ $$DIALOGS_CPP/tqwizard.cpp \
+ $$DIALOGS_CPP/tqinputdialog.cpp
+}
diff --git a/tqtinterface/qt4/src/dialogs/tqcolordialog.cpp b/tqtinterface/qt4/src/dialogs/tqcolordialog.cpp
new file mode 100644
index 0000000..cd13476
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqcolordialog.cpp
@@ -0,0 +1,1665 @@
+/****************************************************************************
+**
+** Implementation of TQColorDialog class
+**
+** Created : 990222
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcolordialog.h"
+
+#ifndef TQT_NO_COLORDIALOG
+
+#include "tqpainter.h"
+#include "tqlayout.h"
+#include "tqlabel.h"
+#include "tqpushbutton.h"
+#include "tqlineedit.h"
+#include "tqimage.h"
+#include "tqpixmap.h"
+#include "tqdrawutil.h"
+#include "tqvalidator.h"
+#include "tqdragobject.h"
+#include "tqgridview.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+#include "tqsettings.h"
+#include "tqpopupmenu.h"
+
+#ifdef TQ_WS_MAC
+TQRgb macGetRgba( TQRgb initial, bool *ok, TQWidget *tqparent, const char* name );
+TQColor macGetColor( const TQColor& initial, TQWidget *tqparent, const char *name );
+#endif
+
+//////////// TQWellArray BEGIN
+
+struct TQWellArrayData;
+
+class TQWellArray : public TQGridView
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( int selectedColumn READ selectedColumn )
+ Q_PROPERTY( int selectedRow READ selectedRow )
+
+public:
+ TQWellArray( TQWidget* tqparent=0, const char* name=0, bool popup = FALSE );
+
+ ~TQWellArray() {}
+ TQString cellContent( int row, int col ) const;
+ // ### Paul !!! virtual void setCellContent( int row, int col, const TQString &);
+
+ int selectedColumn() const { return selCol; }
+ int selectedRow() const { return selRow; }
+
+ virtual void setCurrent( int row, int col );
+ virtual void setSelected( int row, int col );
+
+ TQSize tqsizeHint() const;
+
+ virtual void setCellBrush( int row, int col, const TQBrush & );
+ TQBrush cellBrush( int row, int col );
+
+Q_SIGNALS:
+ void selected( int row, int col );
+
+protected:
+ void dimensionChange( int oldRows, int oldCols );
+
+ virtual void paintCell( TQPainter *, int row, int col );
+ virtual void paintCellContents( TQPainter *, int row, int col, const TQRect& );
+
+ void mousePressEvent( TQMouseEvent* );
+ void mouseReleaseEvent( TQMouseEvent* );
+ void mouseMoveEvent( TQMouseEvent* );
+ void keyPressEvent( TQKeyEvent* );
+ void focusInEvent( TQFocusEvent* );
+ void focusOutEvent( TQFocusEvent* );
+
+private:
+ int curRow;
+ int curCol;
+ int selRow;
+ int selCol;
+ bool smallStyle;
+ TQWellArrayData *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQWellArray( const TQWellArray & );
+ TQWellArray& operator=( const TQWellArray & );
+#endif
+};
+
+
+
+// non-interface ...
+
+
+
+struct TQWellArrayData {
+ TQBrush *brush;
+};
+
+/*!
+ \internal
+ \class TQWellArray qwellarray_p.h
+ \brief The TQWellArray class provides a well array.
+
+
+ \ingroup advanced
+*/
+
+TQWellArray::TQWellArray( TQWidget *tqparent, const char * name, bool popup )
+ : TQGridView( tqparent, name,
+ (popup ? (WFlags)(WStyle_Customize|TQt::WStyle_Tool|TQt::WStyle_NoBorder) : (WFlags)0 ) )
+{
+ d = 0;
+ setFocusPolicy( Qt::StrongFocus );
+ setVScrollBarMode(AlwaysOff);
+ setHScrollBarMode(AlwaysOff);
+ viewport()->setBackgroundMode( TQt::PaletteBackground );
+ setNumCols( 7 );
+ setNumRows( 7 );
+ setCellWidth( 24 );
+ setCellHeight( 21 );
+ smallStyle = popup;
+
+ if ( popup ) {
+ setCellWidth( 18 );
+ setCellHeight( 18 );
+ setFrameStyle(TQFrame::StyledPanel | TQFrame::Raised);
+ setMargin( 1 );
+ setLineWidth( 2 );
+ } else {
+ setFrameStyle( TQFrame::NoFrame );
+ }
+ curCol = 0;
+ curRow = 0;
+ selCol = -1;
+ selRow = -1;
+
+ if ( smallStyle )
+ setMouseTracking( TRUE );
+}
+
+
+TQSize TQWellArray::tqsizeHint() const
+{
+ constPolish();
+ TQSize s = gridSize().boundedTo( TQSize(640, 480 ) );
+ return TQSize( s.width() + 2*frameWidth(), s.height() + 2*frameWidth() );
+}
+
+
+void TQWellArray::paintCell( TQPainter* p, int row, int col )
+{
+ int w = cellWidth(); // width of cell in pixels
+ int h = cellHeight(); // height of cell in pixels
+ int b = 1;
+
+ if ( !smallStyle )
+ b = 3;
+
+ const TQColorGroup & g = tqcolorGroup();
+ p->setPen( TQPen( Qt::black, 0, Qt::SolidLine ) );
+ if ( !smallStyle && row ==selRow && col == selCol &&
+ tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) != TQt::MotifStyle) {
+ int n = 2;
+ p->drawRect( n, n, w-2*n, h-2*n );
+ }
+
+ tqstyle().tqdrawPrimitive(TQStyle::PE_Panel, p, TQRect(b, b, w-2*b, h-2*b), g,
+ TQStyle::Style_Enabled | TQStyle::Style_Sunken);
+
+ int t = 0;
+ if (tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle)
+ t = ( row == selRow && col == selCol ) ? 2 : 0;
+ b += 2 + t;
+
+ if ( (row == curRow) && (col == curCol) ) {
+ if ( smallStyle ) {
+ p->setPen ( Qt::white );
+ p->drawRect( 1, 1, w-2, h-2 );
+ p->setPen ( Qt::black );
+ p->drawRect( 0, 0, w, h );
+ p->drawRect( 2, 2, w-4, h-4 );
+ b = 3;
+ } else if ( hasFocus() ) {
+ tqstyle().tqdrawPrimitive(TQStyle::PE_FocusRect, p, TQRect(0, 0, w, h), g);
+ }
+ }
+ paintCellContents( p, row, col, TQRect(b, b, w - 2*b, h - 2*b) );
+}
+
+/*!
+ Reimplement this function to change the contents of the well array.
+ */
+void TQWellArray::paintCellContents( TQPainter *p, int row, int col, const TQRect &r )
+{
+
+ if ( d ) {
+ p->fillRect( r, d->brush[row*numCols()+col] );
+ } else {
+ p->fillRect( r, Qt::white );
+ p->setPen( Qt::black );
+ p->drawLine( r.topLeft(), r.bottomRight() );
+ p->drawLine( r.topRight(), r.bottomLeft() );
+ }
+}
+
+
+/*\reimp
+*/
+void TQWellArray::mousePressEvent( TQMouseEvent* e )
+{
+ // The current cell marker is set to the cell the mouse is pressed
+ // in.
+ TQPoint pos = e->pos();
+ setCurrent( rowAt( pos.y() ), columnAt( pos.x() ) );
+}
+
+/*\reimp
+*/
+void TQWellArray::mouseReleaseEvent( TQMouseEvent* )
+{
+ // The current cell marker is set to the cell the mouse is clicked
+ // in.
+ setSelected( curRow, curCol );
+}
+
+
+/*\reimp
+*/
+void TQWellArray::mouseMoveEvent( TQMouseEvent* e )
+{
+ // The current cell marker is set to the cell the mouse is
+ // clicked in.
+ if ( smallStyle ) {
+ TQPoint pos = e->pos();
+ setCurrent( rowAt( pos.y() ), columnAt( pos.x() ) );
+ }
+}
+
+/*
+ Sets the cell currently having the focus. This is not necessarily
+ the same as the currently selected cell.
+*/
+
+void TQWellArray::setCurrent( int row, int col )
+{
+
+ if ( (curRow == row) && (curCol == col) )
+ return;
+
+ if ( row < 0 || col < 0 )
+ row = col = -1;
+
+ int oldRow = curRow;
+ int oldCol = curCol;
+
+ curRow = row;
+ curCol = col;
+
+ updateCell( oldRow, oldCol );
+ updateCell( curRow, curCol );
+}
+
+
+/*!
+ Sets the currently selected cell to \a row, \a col. If \a row or \a
+ col are less than zero, the current cell is unselected.
+
+ Does not set the position of the focus indicator.
+*/
+
+void TQWellArray::setSelected( int row, int col )
+{
+ if ( (selRow == row) && (selCol == col) )
+ return;
+
+ int oldRow = selRow;
+ int oldCol = selCol;
+
+ if ( row < 0 || col < 0 )
+ row = col = -1;
+
+ selCol = col;
+ selRow = row;
+
+ updateCell( oldRow, oldCol );
+ updateCell( selRow, selCol );
+ if ( row >= 0 )
+ emit selected( row, col );
+
+ if ( isVisible() && ::tqqt_cast<TQPopupMenu*>(parentWidget()) )
+ parentWidget()->close();
+}
+
+
+
+/*!\reimp
+*/
+void TQWellArray::focusInEvent( TQFocusEvent* )
+{
+ updateCell( curRow, curCol );
+}
+
+
+/*!
+ Sets the size of the well array to be \a rows cells by \a cols.
+ Resets any brush information set by setCellBrush().
+ */
+void TQWellArray::dimensionChange( int, int )
+{
+ if ( d ) {
+ if ( d->brush )
+ delete[] d->brush;
+ delete d;
+ d = 0;
+ }
+}
+
+void TQWellArray::setCellBrush( int row, int col, const TQBrush &b )
+{
+ if ( !d ) {
+ d = new TQWellArrayData;
+ int i = numRows()*numCols();
+ d->brush = new TQBrush[i];
+ }
+ if ( row >= 0 && row < numRows() && col >= 0 && col < numCols() )
+ d->brush[row*numCols()+col] = b;
+#ifdef TQT_CHECK_RANGE
+ else
+ qWarning( "TQWellArray::setCellBrush( %d, %d ) out of range", row, col );
+#endif
+}
+
+
+
+/*!
+ Returns the brush set for the cell at \a row, \a col. If no brush is set,
+ \c NoBrush is returned.
+*/
+
+TQBrush TQWellArray::cellBrush( int row, int col )
+{
+ if ( d && row >= 0 && row < numRows() && col >= 0 && col < numCols() )
+ return d->brush[row*numCols()+col];
+ return TQBrush(TQt::NoBrush);
+}
+
+
+
+/*!\reimp
+*/
+
+void TQWellArray::focusOutEvent( TQFocusEvent* )
+{
+ updateCell( curRow, curCol );
+}
+
+/*\reimp
+*/
+void TQWellArray::keyPressEvent( TQKeyEvent* e )
+{
+ switch( e->key() ) { // Look at the key code
+ case Qt::Key_Left: // If 'left arrow'-key,
+ if( curCol > 0 ) // and cr't not in leftmost col
+ setCurrent( curRow, curCol - 1); // set cr't to next left column
+ break;
+ case Qt::Key_Right: // Correspondingly...
+ if( curCol < numCols()-1 )
+ setCurrent( curRow, curCol + 1);
+ break;
+ case Qt::Key_Up:
+ if( curRow > 0 )
+ setCurrent( curRow - 1, curCol);
+ else if ( smallStyle )
+ focusNextPrevChild( FALSE );
+ break;
+ case Qt::Key_Down:
+ if( curRow < numRows()-1 )
+ setCurrent( curRow + 1, curCol);
+ else if ( smallStyle )
+ focusNextPrevChild( TRUE );
+ break;
+ case Qt::Key_Space:
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ setSelected( curRow, curCol );
+ break;
+ default: // If not an interesting key,
+ e->ignore(); // we don't accept the event
+ return;
+ }
+
+}
+
+//////////// TQWellArray END
+
+static bool initrgb = FALSE;
+static TQRgb stdrgb[6*8];
+static TQRgb cusrgb[2*8];
+static bool customSet = FALSE;
+
+
+static void initRGB()
+{
+ if ( initrgb )
+ return;
+ initrgb = TRUE;
+ int i = 0;
+ for ( int g = 0; g < 4; g++ )
+ for ( int r = 0; r < 4; r++ )
+ for ( int b = 0; b < 3; b++ )
+ stdrgb[i++] = tqRgb( r*255/3, g*255/3, b*255/2 );
+
+ for ( i = 0; i < 2*8; i++ )
+ cusrgb[i] = tqRgb(0xff,0xff,0xff);
+}
+
+/*!
+ Returns the number of custom colors supported by TQColorDialog. All
+ color dialogs share the same custom colors.
+*/
+int TQColorDialog::customCount()
+{
+ return 2*8;
+}
+
+/*!
+ Returns custom color number \a i as a TQRgb.
+*/
+TQRgb TQColorDialog::customColor( int i )
+{
+ initRGB();
+ if ( i < 0 || i >= customCount() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQColorDialog::customColor() index %d out of range", i );
+#endif
+ i = 0;
+ }
+ return cusrgb[i];
+}
+
+/*!
+ Sets custom color number \a i to the TQRgb value \a c.
+*/
+void TQColorDialog::setCustomColor( int i, TQRgb c )
+{
+ initRGB();
+ if ( i < 0 || i >= customCount() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQColorDialog::setCustomColor() index %d out of range", i );
+#endif
+ return;
+ }
+ customSet = TRUE;
+ cusrgb[i] = c;
+}
+
+/*!
+ Sets standard color number \a i to the TQRgb value \a c.
+*/
+
+void TQColorDialog::setStandardColor( int i, TQRgb c )
+{
+ initRGB();
+ if ( i < 0 || i >= 6*8 ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQColorDialog::setStandardColor() index %d out of range", i );
+#endif
+ return;
+ }
+ stdrgb[i] = c;
+}
+
+static inline void rgb2hsv( TQRgb rgb, int&h, int&s, int&v )
+{
+ TQColor c;
+ c.setRgb( rgb );
+ c.tqgetHsv(h,s,v);
+}
+
+class TQColorWell : public TQWellArray
+{
+public:
+ TQColorWell( TQWidget *tqparent, int r, int c, TQRgb *vals )
+ :TQWellArray( tqparent, "" ), values( vals ), mousePressed( FALSE ), oldCurrent( -1, -1 )
+ { setNumRows(r), setNumCols(c); tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Minimum) ); }
+
+protected:
+ void paintCellContents( TQPainter *, int row, int col, const TQRect& );
+ void mousePressEvent( TQMouseEvent *e );
+ void mouseMoveEvent( TQMouseEvent *e );
+ void mouseReleaseEvent( TQMouseEvent *e );
+#ifndef TQT_NO_DRAGANDDROP
+ void dragEnterEvent( TQDragEnterEvent *e );
+ void dragLeaveEvent( TQDragLeaveEvent *e );
+ void dragMoveEvent( TQDragMoveEvent *e );
+ void dropEvent( TQDropEvent *e );
+#endif
+
+private:
+ TQRgb *values;
+ bool mousePressed;
+ TQPoint pressPos;
+ TQPoint oldCurrent;
+
+};
+
+void TQColorWell::paintCellContents( TQPainter *p, int row, int col, const TQRect &r )
+{
+ int i = row + col*numRows();
+ p->fillRect( r, TQColor( values[i] ) );
+}
+
+void TQColorWell::mousePressEvent( TQMouseEvent *e )
+{
+ oldCurrent = TQPoint( selectedRow(), selectedColumn() );
+ TQWellArray::mousePressEvent( e );
+ mousePressed = TRUE;
+ pressPos = e->pos();
+}
+
+void TQColorWell::mouseMoveEvent( TQMouseEvent *e )
+{
+ TQWellArray::mouseMoveEvent( e );
+#ifndef TQT_NO_DRAGANDDROP
+ if ( !mousePressed )
+ return;
+ if ( ( pressPos - e->pos() ).manhattanLength() > TQApplication::startDragDistance() ) {
+ setCurrent( oldCurrent.x(), oldCurrent.y() );
+ int i = rowAt(pressPos.y()) + columnAt(pressPos.x()) * numRows();
+ TQColor col( values[ i ] );
+ TQColorDrag *drg = new TQColorDrag( col, this );
+ TQPixmap pix( cellWidth(), cellHeight() );
+ pix.fill( col );
+ TQPainter p( &pix );
+ p.drawRect( 0, 0, pix.width(), pix.height() );
+ p.end();
+ drg->setPixmap( pix );
+ mousePressed = FALSE;
+ drg->dragCopy();
+ }
+#endif
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQColorWell::dragEnterEvent( TQDragEnterEvent *e )
+{
+ setFocus();
+ if ( TQColorDrag::canDecode( e ) )
+ e->accept();
+ else
+ e->ignore();
+}
+
+void TQColorWell::dragLeaveEvent( TQDragLeaveEvent * )
+{
+ if ( hasFocus() )
+ parentWidget()->setFocus();
+}
+
+void TQColorWell::dragMoveEvent( TQDragMoveEvent *e )
+{
+ if ( TQColorDrag::canDecode( e ) ) {
+ setCurrent( rowAt( e->pos().y() ), columnAt( e->pos().x() ) );
+ e->accept();
+ } else
+ e->ignore();
+}
+
+void TQColorWell::dropEvent( TQDropEvent *e )
+{
+ if ( TQColorDrag::canDecode( e ) ) {
+ int i = rowAt( e->pos().y() ) + columnAt( e->pos().x() ) * numRows();
+ TQColor col;
+ TQColorDrag::decode( e, col );
+ values[ i ] = col.rgb();
+ repaintContents( FALSE );
+ e->accept();
+ } else {
+ e->ignore();
+ }
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+void TQColorWell::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( !mousePressed )
+ return;
+ TQWellArray::mouseReleaseEvent( e );
+ mousePressed = FALSE;
+}
+
+class TQColorPicker : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQColorPicker(TQWidget* tqparent=0, const char* name=0);
+ ~TQColorPicker();
+
+public Q_SLOTS:
+ void setCol( int h, int s );
+
+Q_SIGNALS:
+ void newCol( int h, int s );
+
+protected:
+ TQSize tqsizeHint() const;
+ void drawContents(TQPainter* p);
+ void mouseMoveEvent( TQMouseEvent * );
+ void mousePressEvent( TQMouseEvent * );
+
+private:
+ int hue;
+ int sat;
+
+ TQPoint colPt();
+ int huePt( const TQPoint &pt );
+ int satPt( const TQPoint &pt );
+ void setCol( const TQPoint &pt );
+
+ TQPixmap *pix;
+};
+
+static int pWidth = 200;
+static int pHeight = 200;
+
+class TQColorLuminancePicker : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQColorLuminancePicker(TQWidget* tqparent=0, const char* name=0);
+ ~TQColorLuminancePicker();
+
+public Q_SLOTS:
+ void setCol( int h, int s, int v );
+ void setCol( int h, int s );
+
+Q_SIGNALS:
+ void newHsv( int h, int s, int v );
+
+protected:
+ void paintEvent( TQPaintEvent*);
+ void mouseMoveEvent( TQMouseEvent * );
+ void mousePressEvent( TQMouseEvent * );
+
+private:
+ enum { foff = 3, coff = 4 }; //frame and contents offset
+ int val;
+ int hue;
+ int sat;
+
+ int y2val( int y );
+ int val2y( int val );
+ void setVal( int v );
+
+ TQPixmap *pix;
+};
+
+
+int TQColorLuminancePicker::y2val( int y )
+{
+ int d = height() - 2*coff - 1;
+ return 255 - (y - coff)*255/d;
+}
+
+int TQColorLuminancePicker::val2y( int v )
+{
+ int d = height() - 2*coff - 1;
+ return coff + (255-v)*d/255;
+}
+
+TQColorLuminancePicker::TQColorLuminancePicker(TQWidget* tqparent,
+ const char* name)
+ :TQWidget( tqparent, name )
+{
+ hue = 100; val = 100; sat = 100;
+ pix = 0;
+ // setBackgroundMode( NoBackground );
+}
+
+TQColorLuminancePicker::~TQColorLuminancePicker()
+{
+ delete pix;
+}
+
+void TQColorLuminancePicker::mouseMoveEvent( TQMouseEvent *m )
+{
+ setVal( y2val(m->y()) );
+}
+void TQColorLuminancePicker::mousePressEvent( TQMouseEvent *m )
+{
+ setVal( y2val(m->y()) );
+}
+
+void TQColorLuminancePicker::setVal( int v )
+{
+ if ( val == v )
+ return;
+ val = TQMAX( 0, TQMIN(v,255));
+ delete pix; pix=0;
+ tqrepaint( FALSE ); //###
+ emit newHsv( hue, sat, val );
+}
+
+//receives from a hue,sat chooser and relays.
+void TQColorLuminancePicker::setCol( int h, int s )
+{
+ setCol( h, s, val );
+ emit newHsv( h, s, val );
+}
+
+void TQColorLuminancePicker::paintEvent( TQPaintEvent * )
+{
+ int w = width() - 5;
+
+ TQRect r( 0, foff, w, height() - 2*foff );
+ int wi = r.width() - 2;
+ int hi = r.height() - 2;
+ if ( !pix || pix->height() != hi || pix->width() != wi ) {
+ delete pix;
+ TQImage img( wi, hi, 32 );
+ int y;
+ for ( y = 0; y < hi; y++ ) {
+ TQColor c( hue, sat, y2val(y+coff), TQColor::Hsv );
+ TQRgb r = c.rgb();
+ int x;
+ for ( x = 0; x < wi; x++ )
+ img.setPixel( x, y, r );
+ }
+ pix = new TQPixmap;
+ pix->convertFromImage(img);
+ }
+ TQPainter p(this);
+ p.drawPixmap( 1, coff, *pix );
+ const TQColorGroup &g = tqcolorGroup();
+ qDrawShadePanel( &p, r, g, TRUE );
+ p.setPen( g.foreground() );
+ p.setBrush( g.foreground() );
+ TQPointArray a;
+ int y = val2y(val);
+ a.setPoints( 3, w, y, w+5, y+5, w+5, y-5 );
+ erase( w, 0, 5, height() );
+ p.drawPolygon( a );
+}
+
+void TQColorLuminancePicker::setCol( int h, int s , int v )
+{
+ val = v;
+ hue = h;
+ sat = s;
+ delete pix; pix=0;
+ tqrepaint( FALSE );//####
+}
+
+TQPoint TQColorPicker::colPt()
+{ return TQPoint( (360-hue)*(pWidth-1)/360, (255-sat)*(pHeight-1)/255 ); }
+int TQColorPicker::huePt( const TQPoint &pt )
+{ return 360 - pt.x()*360/(pWidth-1); }
+int TQColorPicker::satPt( const TQPoint &pt )
+{ return 255 - pt.y()*255/(pHeight-1) ; }
+void TQColorPicker::setCol( const TQPoint &pt )
+{ setCol( huePt(pt), satPt(pt) ); }
+
+TQColorPicker::TQColorPicker(TQWidget* tqparent, const char* name )
+ : TQFrame( tqparent, name )
+{
+ hue = 0; sat = 0;
+ setCol( 150, 255 );
+
+ TQImage img( pWidth, pHeight, 32 );
+ int x,y;
+ for ( y = 0; y < pHeight; y++ )
+ for ( x = 0; x < pWidth; x++ ) {
+ TQPoint p( x, y );
+ img.setPixel( x, y, TQColor(huePt(p), satPt(p),
+ 200, TQColor::Hsv).rgb() );
+ }
+ pix = new TQPixmap;
+ pix->convertFromImage(img);
+ setBackgroundMode( TQt::NoBackground );
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Fixed ) );
+}
+
+TQColorPicker::~TQColorPicker()
+{
+ delete pix;
+}
+
+TQSize TQColorPicker::tqsizeHint() const
+{
+ return TQSize( pWidth + 2*frameWidth(), pHeight + 2*frameWidth() );
+}
+
+void TQColorPicker::setCol( int h, int s )
+{
+ int nhue = TQMIN( TQMAX(0,h), 360 );
+ int nsat = TQMIN( TQMAX(0,s), 255);
+ if ( nhue == hue && nsat == sat )
+ return;
+ TQRect r( colPt(), TQSize(20,20) );
+ hue = nhue; sat = nsat;
+ r = r.unite( TQRect( colPt(), TQSize(20,20) ) );
+ r.moveBy( contentsRect().x()-9, contentsRect().y()-9 );
+ // update( r );
+ tqrepaint( r, FALSE );
+}
+
+void TQColorPicker::mouseMoveEvent( TQMouseEvent *m )
+{
+ TQPoint p = m->pos() - contentsRect().topLeft();
+ setCol( p );
+ emit newCol( hue, sat );
+}
+
+void TQColorPicker::mousePressEvent( TQMouseEvent *m )
+{
+ TQPoint p = m->pos() - contentsRect().topLeft();
+ setCol( p );
+ emit newCol( hue, sat );
+}
+
+void TQColorPicker::drawContents(TQPainter* p)
+{
+ TQRect r = contentsRect();
+
+ p->drawPixmap( r.topLeft(), *pix );
+ TQPoint pt = colPt() + r.topLeft();
+ p->setPen( TQPen(Qt::black) );
+
+ p->fillRect( pt.x()-9, pt.y(), 20, 2, Qt::black );
+ p->fillRect( pt.x(), pt.y()-9, 2, 20, Qt::black );
+
+}
+
+class TQColorShowLabel;
+
+
+
+class TQColIntValidator: public TQIntValidator
+{
+public:
+ TQColIntValidator( int bottom, int top,
+ TQWidget * tqparent, const char *name = 0 )
+ :TQIntValidator( bottom, top, TQT_TQOBJECT(tqparent), name ) {}
+
+ TQValidator::State validate( TQString &, int & ) const;
+};
+
+TQValidator::State TQColIntValidator::validate( TQString &s, int &pos ) const
+{
+ State state = TQIntValidator::validate(s,pos);
+ if ( state == Valid ) {
+ long int val = s.toLong();
+ // This is not a general solution, assumes that top() > 0 and
+ // bottom >= 0
+ if ( val < 0 ) {
+ s = "0";
+ pos = 1;
+ } else if ( val > top() ) {
+ s.setNum( top() );
+ pos = s.length();
+ }
+ }
+ return state;
+}
+
+
+
+class TQColNumLineEdit : public TQLineEdit
+{
+public:
+ TQColNumLineEdit( TQWidget *tqparent, const char* name=0 )
+ : TQLineEdit( tqparent, name ) { setMaxLength( 3 );}
+ TQSize tqsizeHint() const {
+ return TQSize( fontMetrics().width( "999" ) + 2 * ( margin() + frameWidth() ),
+ TQLineEdit::tqsizeHint().height() ); }
+ void setNum( int i ) {
+ TQString s;
+ s.setNum(i);
+ bool block = tqsignalsBlocked();
+ blockSignals(TRUE);
+ setText( s );
+ blockSignals(block);
+ }
+ int val() const { return text().toInt(); }
+};
+
+
+class TQColorShower : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQColorShower( TQWidget *tqparent, const char *name=0 );
+
+ //things that don't emit Q_SIGNALS
+ void setHsv( int h, int s, int v );
+
+ int currentAlpha() const { return alphaEd->val(); }
+ void setCurrentAlpha( int a ) { alphaEd->setNum( a ); }
+ void showAlpha( bool b );
+
+
+ TQRgb currentColor() const { return curCol; }
+
+public Q_SLOTS:
+ void setRgb( TQRgb rgb );
+
+Q_SIGNALS:
+ void newCol( TQRgb rgb );
+private Q_SLOTS:
+ void rgbEd();
+ void hsvEd();
+private:
+ void showCurrentColor();
+ int hue, sat, val;
+ TQRgb curCol;
+ TQColNumLineEdit *hEd;
+ TQColNumLineEdit *sEd;
+ TQColNumLineEdit *vEd;
+ TQColNumLineEdit *rEd;
+ TQColNumLineEdit *gEd;
+ TQColNumLineEdit *bEd;
+ TQColNumLineEdit *alphaEd;
+ TQLabel *alphaLab;
+ TQColorShowLabel *lab;
+ bool rgbOriginal;
+};
+
+class TQColorShowLabel : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQColorShowLabel( TQWidget *tqparent ) : TQFrame( tqparent, "qt_colorshow_lbl" ) {
+ setFrameStyle( TQFrame::Panel|TQFrame::Sunken );
+ setBackgroundMode( TQt::PaletteBackground );
+ setAcceptDrops( TRUE );
+ mousePressed = FALSE;
+ }
+ void setColor( TQColor c ) { col = c; }
+
+Q_SIGNALS:
+ void colorDropped( TQRgb );
+
+protected:
+ void drawContents( TQPainter *p );
+ void mousePressEvent( TQMouseEvent *e );
+ void mouseMoveEvent( TQMouseEvent *e );
+ void mouseReleaseEvent( TQMouseEvent *e );
+#ifndef TQT_NO_DRAGANDDROP
+ void dragEnterEvent( TQDragEnterEvent *e );
+ void dragLeaveEvent( TQDragLeaveEvent *e );
+ void dropEvent( TQDropEvent *e );
+#endif
+
+private:
+ TQColor col;
+ bool mousePressed;
+ TQPoint pressPos;
+
+};
+
+void TQColorShowLabel::drawContents( TQPainter *p )
+{
+ p->fillRect( contentsRect(), col );
+}
+
+void TQColorShower::showAlpha( bool b )
+{
+ if ( b ) {
+ alphaLab->show();
+ alphaEd->show();
+ } else {
+ alphaLab->hide();
+ alphaEd->hide();
+ }
+}
+
+void TQColorShowLabel::mousePressEvent( TQMouseEvent *e )
+{
+ mousePressed = TRUE;
+ pressPos = e->pos();
+}
+
+void TQColorShowLabel::mouseMoveEvent( TQMouseEvent *e )
+{
+#ifndef TQT_NO_DRAGANDDROP
+ if ( !mousePressed )
+ return;
+ if ( ( pressPos - e->pos() ).manhattanLength() > TQApplication::startDragDistance() ) {
+ TQColorDrag *drg = new TQColorDrag( col, this );
+ TQPixmap pix( 30, 20 );
+ pix.fill( col );
+ TQPainter p( &pix );
+ p.drawRect( 0, 0, pix.width(), pix.height() );
+ p.end();
+ drg->setPixmap( pix );
+ mousePressed = FALSE;
+ drg->dragCopy();
+ }
+#endif
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQColorShowLabel::dragEnterEvent( TQDragEnterEvent *e )
+{
+ if ( TQColorDrag::canDecode( e ) )
+ e->accept();
+ else
+ e->ignore();
+}
+
+void TQColorShowLabel::dragLeaveEvent( TQDragLeaveEvent * )
+{
+}
+
+void TQColorShowLabel::dropEvent( TQDropEvent *e )
+{
+ if ( TQColorDrag::canDecode( e ) ) {
+ TQColorDrag::decode( e, col );
+ tqrepaint( FALSE );
+ emit colorDropped( col.rgb() );
+ e->accept();
+ } else {
+ e->ignore();
+ }
+}
+#endif // TQT_NO_DRAGANDDROP
+
+void TQColorShowLabel::mouseReleaseEvent( TQMouseEvent * )
+{
+ if ( !mousePressed )
+ return;
+ mousePressed = FALSE;
+}
+
+TQColorShower::TQColorShower( TQWidget *tqparent, const char *name )
+ :TQWidget( tqparent, name)
+{
+ curCol = tqRgb( -1, -1, -1 );
+ TQColIntValidator *val256 = new TQColIntValidator( 0, 255, this );
+ TQColIntValidator *val360 = new TQColIntValidator( 0, 360, this );
+
+ TQGridLayout *gl = new TQGridLayout( this, 1, 1, 6 );
+ lab = new TQColorShowLabel( this );
+ lab->setMinimumWidth( 60 ); //###
+ gl->addMultiCellWidget(lab, 0,-1,0,0);
+ connect( lab, TQT_SIGNAL( colorDropped(TQRgb) ),
+ this, TQT_SIGNAL( newCol(TQRgb) ) );
+ connect( lab, TQT_SIGNAL( colorDropped(TQRgb) ),
+ this, TQT_SLOT( setRgb(TQRgb) ) );
+
+ hEd = new TQColNumLineEdit( this, "qt_hue_edit" );
+ hEd->setValidator( val360 );
+ TQLabel *l = new TQLabel( hEd, TQColorDialog::tr("Hu&e:"), this, "qt_hue_lbl" );
+ l->tqsetAlignment( Qt::AlignRight|Qt::AlignVCenter );
+ gl->addWidget( l, 0, 1 );
+ gl->addWidget( hEd, 0, 2 );
+
+ sEd = new TQColNumLineEdit( this, "qt_sat_edit" );
+ sEd->setValidator( val256 );
+ l = new TQLabel( sEd, TQColorDialog::tr("&Sat:"), this, "qt_sat_lbl" );
+ l->tqsetAlignment( Qt::AlignRight|Qt::AlignVCenter );
+ gl->addWidget( l, 1, 1 );
+ gl->addWidget( sEd, 1, 2 );
+
+ vEd = new TQColNumLineEdit( this, "qt_val_edit" );
+ vEd->setValidator( val256 );
+ l = new TQLabel( vEd, TQColorDialog::tr("&Val:"), this, "qt_val_lbl" );
+ l->tqsetAlignment( Qt::AlignRight|Qt::AlignVCenter );
+ gl->addWidget( l, 2, 1 );
+ gl->addWidget( vEd, 2, 2 );
+
+ rEd = new TQColNumLineEdit( this, "qt_red_edit" );
+ rEd->setValidator( val256 );
+ l = new TQLabel( rEd, TQColorDialog::tr("&Red:"), this, "qt_red_lbl" );
+ l->tqsetAlignment( Qt::AlignRight|Qt::AlignVCenter );
+ gl->addWidget( l, 0, 3 );
+ gl->addWidget( rEd, 0, 4 );
+
+ gEd = new TQColNumLineEdit( this, "qt_grn_edit" );
+ gEd->setValidator( val256 );
+ l = new TQLabel( gEd, TQColorDialog::tr("&Green:"), this, "qt_grn_lbl" );
+ l->tqsetAlignment( Qt::AlignRight|Qt::AlignVCenter );
+ gl->addWidget( l, 1, 3 );
+ gl->addWidget( gEd, 1, 4 );
+
+ bEd = new TQColNumLineEdit( this, "qt_blue_edit" );
+ bEd->setValidator( val256 );
+ l = new TQLabel( bEd, TQColorDialog::tr("Bl&ue:"), this, "qt_blue_lbl" );
+ l->tqsetAlignment( Qt::AlignRight|Qt::AlignVCenter );
+ gl->addWidget( l, 2, 3 );
+ gl->addWidget( bEd, 2, 4 );
+
+ alphaEd = new TQColNumLineEdit( this, "qt_aplha_edit" );
+ alphaEd->setValidator( val256 );
+ alphaLab = new TQLabel( alphaEd, TQColorDialog::tr("A&lpha channel:"), this, "qt_alpha_lbl" );
+ alphaLab->tqsetAlignment( Qt::AlignRight|Qt::AlignVCenter );
+ gl->addMultiCellWidget( alphaLab, 3, 3, 1, 3 );
+ gl->addWidget( alphaEd, 3, 4 );
+ alphaEd->hide();
+ alphaLab->hide();
+
+ connect( hEd, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(hsvEd()) );
+ connect( sEd, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(hsvEd()) );
+ connect( vEd, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(hsvEd()) );
+
+ connect( rEd, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(rgbEd()) );
+ connect( gEd, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(rgbEd()) );
+ connect( bEd, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(rgbEd()) );
+ connect( alphaEd, TQT_SIGNAL(textChanged(const TQString&)), this, TQT_SLOT(rgbEd()) );
+}
+
+void TQColorShower::showCurrentColor()
+{
+ lab->setColor( currentColor() );
+ lab->tqrepaint(FALSE); //###
+}
+
+void TQColorShower::rgbEd()
+{
+ rgbOriginal = TRUE;
+ if ( alphaEd->isVisible() )
+ curCol = tqRgba( rEd->val(), gEd->val(), bEd->val(), currentAlpha() );
+ else
+ curCol = tqRgb( rEd->val(), gEd->val(), bEd->val() );
+
+ rgb2hsv(currentColor(), hue, sat, val );
+
+ hEd->setNum( hue );
+ sEd->setNum( sat );
+ vEd->setNum( val );
+
+ showCurrentColor();
+ emit newCol( currentColor() );
+}
+
+void TQColorShower::hsvEd()
+{
+ rgbOriginal = FALSE;
+ hue = hEd->val();
+ sat = sEd->val();
+ val = vEd->val();
+
+ curCol = TQColor( hue, sat, val, TQColor::Hsv ).rgb();
+
+ rEd->setNum( tqRed(currentColor()) );
+ gEd->setNum( tqGreen(currentColor()) );
+ bEd->setNum( tqBlue(currentColor()) );
+
+ showCurrentColor();
+ emit newCol( currentColor() );
+}
+
+void TQColorShower::setRgb( TQRgb rgb )
+{
+ rgbOriginal = TRUE;
+ curCol = rgb;
+
+ rgb2hsv( currentColor(), hue, sat, val );
+
+ hEd->setNum( hue );
+ sEd->setNum( sat );
+ vEd->setNum( val );
+
+ rEd->setNum( tqRed(currentColor()) );
+ gEd->setNum( tqGreen(currentColor()) );
+ bEd->setNum( tqBlue(currentColor()) );
+
+ showCurrentColor();
+}
+
+void TQColorShower::setHsv( int h, int s, int v )
+{
+ rgbOriginal = FALSE;
+ hue = h; val = v; sat = s; //Range check###
+ curCol = TQColor( hue, sat, val, TQColor::Hsv ).rgb();
+
+ hEd->setNum( hue );
+ sEd->setNum( sat );
+ vEd->setNum( val );
+
+ rEd->setNum( tqRed(currentColor()) );
+ gEd->setNum( tqGreen(currentColor()) );
+ bEd->setNum( tqBlue(currentColor()) );
+
+ showCurrentColor();
+}
+
+class TQColorDialogPrivate : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQColorDialogPrivate( TQColorDialog *p );
+ TQRgb currentColor() const { return cs->currentColor(); }
+ void setCurrentColor( TQRgb rgb );
+
+ int currentAlpha() const { return cs->currentAlpha(); }
+ void setCurrentAlpha( int a ) { cs->setCurrentAlpha( a ); }
+ void showAlpha( bool b ) { cs->showAlpha( b ); }
+
+public Q_SLOTS:
+ void addCustom();
+
+ void newHsv( int h, int s, int v );
+ void newColorTypedIn( TQRgb rgb );
+ void newCustom( int, int );
+ void newStandard( int, int );
+public:
+ TQWellArray *custom;
+ TQWellArray *standard;
+
+ TQColorPicker *cp;
+ TQColorLuminancePicker *lp;
+ TQColorShower *cs;
+ int nextCust;
+ bool compact;
+};
+
+//sets all widgets to display h,s,v
+void TQColorDialogPrivate::newHsv( int h, int s, int v )
+{
+ cs->setHsv( h, s, v );
+ cp->setCol( h, s );
+ lp->setCol( h, s, v );
+}
+
+//sets all widgets to display rgb
+void TQColorDialogPrivate::setCurrentColor( TQRgb rgb )
+{
+ cs->setRgb( rgb );
+ newColorTypedIn( rgb );
+}
+
+//sets all widgets exept cs to display rgb
+void TQColorDialogPrivate::newColorTypedIn( TQRgb rgb )
+{
+ int h, s, v;
+ rgb2hsv(rgb, h, s, v );
+ cp->setCol( h, s );
+ lp->setCol( h, s, v);
+}
+
+void TQColorDialogPrivate::newCustom( int r, int c )
+{
+ int i = r+2*c;
+ setCurrentColor( cusrgb[i] );
+ nextCust = i;
+ if (standard)
+ standard->setSelected(-1,-1);
+}
+
+void TQColorDialogPrivate::newStandard( int r, int c )
+{
+ setCurrentColor( stdrgb[r+c*6] );
+ if (custom)
+ custom->setSelected(-1,-1);
+}
+
+TQColorDialogPrivate::TQColorDialogPrivate( TQColorDialog *dialog ) :
+ TQObject(dialog)
+{
+ compact = FALSE;
+ // small displays (e.g. PDAs cannot fit the full color dialog,
+ // so just use the color picker.
+ if ( tqApp->desktop()->width() < 480 || tqApp->desktop()->height() < 350 )
+ compact = TRUE;
+
+ nextCust = 0;
+ const int lumSpace = 3;
+ int border = 12;
+ if ( compact )
+ border = 6;
+ TQHBoxLayout *topLay = new TQHBoxLayout( dialog, border, 6 );
+ TQVBoxLayout *leftLay = 0;
+
+ if ( !compact )
+ leftLay = new TQVBoxLayout( topLay );
+
+ initRGB();
+
+ if ( !compact ) {
+ standard = new TQColorWell( dialog, 6, 8, stdrgb );
+ standard->setCellWidth( 28 );
+ standard->setCellHeight( 24 );
+ TQLabel * lab = new TQLabel( standard,
+ TQColorDialog::tr( "&Basic colors"), dialog, "qt_basiccolors_lbl" );
+ connect( standard, TQT_SIGNAL(selected(int,int)), TQT_SLOT(newStandard(int,int)));
+ leftLay->addWidget( lab );
+ leftLay->addWidget( standard );
+
+
+ leftLay->addStretch();
+
+ custom = new TQColorWell( dialog, 2, 8, cusrgb );
+ custom->setCellWidth( 28 );
+ custom->setCellHeight( 24 );
+ custom->setAcceptDrops( TRUE );
+
+ connect( custom, TQT_SIGNAL(selected(int,int)), TQT_SLOT(newCustom(int,int)));
+ lab = new TQLabel( custom, TQColorDialog::tr( "&Custom colors") , dialog, "qt_custcolors_lbl" );
+ leftLay->addWidget( lab );
+ leftLay->addWidget( custom );
+
+ TQPushButton *custbut =
+ new TQPushButton( TQColorDialog::tr("&Define Custom Colors >>"),
+ dialog, "qt_def_custcolors_lbl" );
+ custbut->setEnabled( FALSE );
+ leftLay->addWidget( custbut );
+ } else {
+ // better color picker size for small displays
+ pWidth = 150;
+ pHeight = 100;
+
+ custom = 0;
+ standard = 0;
+ }
+
+ TQVBoxLayout *rightLay = new TQVBoxLayout( topLay );
+
+ TQHBoxLayout *pickLay = new TQHBoxLayout( rightLay );
+
+
+ TQVBoxLayout *cLay = new TQVBoxLayout( pickLay );
+ cp = new TQColorPicker( dialog, "qt_colorpicker" );
+ cp->setFrameStyle( TQFrame::Panel + TQFrame::Sunken );
+ cLay->addSpacing( lumSpace );
+ cLay->addWidget( cp );
+ cLay->addSpacing( lumSpace );
+
+ lp = new TQColorLuminancePicker( dialog, "qt_luminance_picker" );
+ lp->setFixedWidth( 20 ); //###
+ pickLay->addWidget( lp );
+
+ connect( cp, TQT_SIGNAL(newCol(int,int)), lp, TQT_SLOT(setCol(int,int)) );
+ connect( lp, TQT_SIGNAL(newHsv(int,int,int)), this, TQT_SLOT(newHsv(int,int,int)) );
+
+ rightLay->addStretch();
+
+ cs = new TQColorShower( dialog, "qt_colorshower" );
+ connect( cs, TQT_SIGNAL(newCol(TQRgb)), this, TQT_SLOT(newColorTypedIn(TQRgb)));
+ rightLay->addWidget( cs );
+
+ TQHBoxLayout *buttons;
+ if ( compact )
+ buttons = new TQHBoxLayout( rightLay );
+ else
+ buttons = new TQHBoxLayout( leftLay );
+
+ TQPushButton *ok, *cancel;
+ ok = new TQPushButton( TQColorDialog::tr("OK"), dialog, "qt_ok_btn" );
+ connect( ok, TQT_SIGNAL(clicked()), dialog, TQT_SLOT(accept()) );
+ ok->setDefault(TRUE);
+ cancel = new TQPushButton( TQColorDialog::tr("Cancel"), dialog, "qt_cancel_btn" );
+ connect( cancel, TQT_SIGNAL(clicked()), dialog, TQT_SLOT(reject()) );
+ buttons->addWidget( ok );
+ buttons->addWidget( cancel );
+ buttons->addStretch();
+
+ if ( !compact ) {
+ TQPushButton *addCusBt = new TQPushButton(
+ TQColorDialog::tr("&Add to Custom Colors"),
+ dialog, "qt_add_btn" );
+ rightLay->addWidget( addCusBt );
+ connect( addCusBt, TQT_SIGNAL(clicked()), this, TQT_SLOT(addCustom()) );
+ }
+}
+
+void TQColorDialogPrivate::addCustom()
+{
+ cusrgb[nextCust] = cs->currentColor();
+ if (custom)
+ custom->repaintContents( FALSE );
+ nextCust = (nextCust+1) % 16;
+}
+
+
+/*!
+ \class TQColorDialog tqcolordialog.h
+ \brief The TQColorDialog class provides a dialog widget for specifying colors.
+ \mainclass
+ \ingroup dialogs
+ \ingroup graphics
+
+ The color dialog's function is to allow users to choose colors.
+ For example, you might use this in a drawing program to allow the
+ user to set the brush color.
+
+ The static functions provide modal color dialogs.
+ \omit
+ If you require a modeless dialog, use the TQColorDialog constructor.
+ \endomit
+
+ The static getColor() function shows the dialog and allows the
+ user to specify a color. The getRgba() function does the same but
+ also allows the user to specify a color with an alpha channel
+ (transparency) value.
+
+ The user can store customCount() different custom colors. The
+ custom colors are shared by all color dialogs, and remembered
+ during the execution of the program. Use setCustomColor() to set
+ the custom colors, and use customColor() to get them.
+
+ \img qcolordlg-w.png
+*/
+
+/*!
+ Constructs a default color dialog with tqparent \a tqparent and called
+ \a name. If \a modal is TRUE the dialog will be modal. Use
+ setColor() to set an initial value.
+
+ \sa getColor()
+*/
+
+TQColorDialog::TQColorDialog(TQWidget* tqparent, const char* name, bool modal) :
+ TQDialog(tqparent, name, modal, (WFlags)( TQt::WType_Dialog | WStyle_Customize | TQt::WStyle_Title |
+ TQt::WStyle_DialogBorder | TQt::WStyle_SysMenu ) )
+{
+ setSizeGripEnabled( FALSE );
+ d = new TQColorDialogPrivate( this );
+
+#ifndef TQT_NO_SETTINGS
+ if ( !customSet ) {
+ TQSettings settings;
+ settings.insertSearchPath( TQSettings::Windows, "/Trolltech" );
+ for ( int i = 0; i < 2*8; ++i ) {
+ bool ok = FALSE;
+ TQRgb rgb = (TQRgb)settings.readNumEntry( "/TQt/customColors/" + TQString::number( i ), 0, &ok );
+ if ( ok )
+ cusrgb[i] = rgb;
+ }
+ }
+#endif
+}
+
+/*!
+ Pops up a modal color dialog, lets the user choose a color, and
+ returns that color. The color is initially set to \a initial. The
+ dialog is a child of \a tqparent and is called \a name. It returns
+ an invalid (see TQColor::isValid()) color if the user cancels the
+ dialog. All colors allocated by the dialog will be deallocated
+ before this function returns.
+*/
+
+TQColor TQColorDialog::getColor( const TQColor& initial, TQWidget *tqparent,
+ const char *name )
+{
+#if defined(TQ_WS_MAC)
+ return macGetColor(initial, tqparent, name);
+#endif
+
+ int allocContext = TQColor::enterAllocContext();
+ TQColorDialog *dlg = new TQColorDialog( tqparent, name, TRUE ); //modal
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ dlg->setCaption( TQColorDialog::tr( "Select color" ) );
+#endif
+ dlg->setColor( initial );
+ dlg->selectColor( initial );
+ int resultCode = dlg->exec();
+ TQColor::leaveAllocContext();
+ TQColor result;
+ if ( resultCode == TQDialog::Accepted )
+ result = dlg->color();
+ TQColor::destroyAllocContext(allocContext);
+ delete dlg;
+ return result;
+}
+
+
+/*!
+ Pops up a modal color dialog to allow the user to choose a color
+ and an alpha channel (transparency) value. The color+alpha is
+ initially set to \a initial. The dialog is a child of \a tqparent
+ and called \a name.
+
+ If \a ok is non-null, \e *\a ok is set to TRUE if the user clicked
+ OK, and to FALSE if the user clicked Cancel.
+
+ If the user clicks Cancel, the \a initial value is returned.
+*/
+
+TQRgb TQColorDialog::getRgba( TQRgb initial, bool *ok,
+ TQWidget *tqparent, const char* name )
+{
+#if defined(TQ_WS_MAC)
+ return macGetRgba(initial, ok, tqparent, name);
+#endif
+
+ int allocContext = TQColor::enterAllocContext();
+ TQColorDialog *dlg = new TQColorDialog( tqparent, name, TRUE ); //modal
+
+ TQ_CHECK_PTR( dlg );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ dlg->setCaption( TQColorDialog::tr( "Select color" ) );
+#endif
+ dlg->setColor( initial );
+ dlg->selectColor( initial );
+ dlg->setSelectedAlpha( tqAlpha(initial) );
+ int resultCode = dlg->exec();
+ TQColor::leaveAllocContext();
+ TQRgb result = initial;
+ if ( resultCode == TQDialog::Accepted ) {
+ TQRgb c = dlg->color().rgb();
+ int alpha = dlg->selectedAlpha();
+ result = tqRgba( tqRed(c), tqGreen(c), tqBlue(c), alpha );
+ }
+ if ( ok )
+ *ok = resultCode == TQDialog::Accepted;
+
+ TQColor::destroyAllocContext(allocContext);
+ delete dlg;
+ return result;
+}
+
+
+
+
+
+/*!
+ Returns the color currently selected in the dialog.
+
+ \sa setColor()
+*/
+
+TQColor TQColorDialog::color() const
+{
+ return TQColor(d->currentColor());
+}
+
+
+/*!
+ Destroys the dialog and frees any memory it allocated.
+*/
+
+TQColorDialog::~TQColorDialog()
+{
+#ifndef TQT_NO_SETTINGS
+ if ( !customSet ) {
+ TQSettings settings;
+ settings.insertSearchPath( TQSettings::Windows, "/Trolltech" );
+ for ( int i = 0; i < 2*8; ++i )
+ settings.writeEntry( "/TQt/customColors/" + TQString::number( i ), (int)cusrgb[i] );
+ }
+#endif
+}
+
+
+/*!
+ Sets the color shown in the dialog to \a c.
+
+ \sa color()
+*/
+
+void TQColorDialog::setColor( const TQColor& c )
+{
+ d->setCurrentColor( c.rgb() );
+}
+
+
+
+
+/*!
+ Sets the initial alpha channel value to \a a, and shows the alpha
+ channel entry box.
+*/
+
+void TQColorDialog::setSelectedAlpha( int a )
+{
+ d->showAlpha( TRUE );
+ d->setCurrentAlpha( a );
+}
+
+
+/*!
+ Returns the value selected for the alpha channel.
+*/
+
+int TQColorDialog::selectedAlpha() const
+{
+ return d->currentAlpha();
+}
+
+/*!
+ Sets focus to the corresponding button, if any.
+*/
+bool TQColorDialog::selectColor( const TQColor& col )
+{
+ TQRgb color = col.rgb();
+ int i = 0, j = 0;
+ // Check standard colors
+ if (d->standard) {
+ for ( i = 0; i < 6; i++ ) {
+ for ( j = 0; j < 8; j++ ) {
+ if ( color == stdrgb[i + j*6] ) {
+ d->newStandard( i, j );
+ d->standard->setCurrent( i, j );
+ d->standard->setSelected( i, j );
+ d->standard->setFocus();
+ return TRUE;
+ }
+ }
+ }
+ }
+ // Check custom colors
+ if (d->custom) {
+ for ( i = 0; i < 2; i++ ) {
+ for ( j = 0; j < 8; j++ ) {
+ if ( color == cusrgb[i + j*2] ) {
+ d->newCustom( i, j );
+ d->custom->setCurrent( i, j );
+ d->custom->setSelected( i, j );
+ d->custom->setFocus();
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+#include "tqcolordialog.tqmoc"
+
+#endif
diff --git a/tqtinterface/qt4/src/dialogs/tqcolordialog.h b/tqtinterface/qt4/src/dialogs/tqcolordialog.h
new file mode 100644
index 0000000..46f5bdc
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqcolordialog.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Definition of TQColorDialog class
+**
+** Created : 990222
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCOLORDIALOG_H
+#define TQCOLORDIALOG_H
+
+#ifndef TQT_H
+#include "tqdialog.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_COLORDIALOG
+
+class TQColorDialogPrivate;
+
+class TQ_EXPORT TQColorDialog : public TQDialog
+{
+ TQ_OBJECT
+
+public:
+ static TQColor getColor( const TQColor& init = Qt::white, TQWidget* tqparent=0, const char* name=0 );
+ static TQRgb getRgba( TQRgb, bool* ok = 0,
+ TQWidget* tqparent=0, const char* name=0 );
+
+ static int customCount();
+ static TQRgb customColor( int );
+ static void setCustomColor( int, TQRgb );
+ static void setStandardColor( int, TQRgb );
+
+private:
+ ~TQColorDialog();
+ TQColorDialog( TQWidget* tqparent=0, const char* name=0, bool modal=FALSE );
+
+ void setColor( const TQColor& );
+ TQColor color() const;
+
+ bool selectColor( const TQColor& );
+
+ void setSelectedAlpha( int );
+ int selectedAlpha() const;
+
+ void showCustom( bool=TRUE );
+
+private: // Disabled copy constructor and operator=
+ TQColorDialogPrivate *d;
+ friend class TQColorDialogPrivate;
+ friend class TQColorShower;
+
+#if defined(TQ_DISABLE_COPY)
+ TQColorDialog( const TQColorDialog & );
+ TQColorDialog& operator=( const TQColorDialog & );
+#endif
+};
+
+#endif
+
+#endif //TQCOLORDIALOG_H
diff --git a/tqtinterface/qt4/src/dialogs/tqdialog.cpp b/tqtinterface/qt4/src/dialogs/tqdialog.cpp
new file mode 100644
index 0000000..43db3ca
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqdialog.cpp
@@ -0,0 +1,1183 @@
+/****************************************************************************
+**
+** Implementation of TQDialog class
+**
+** Created : 950502
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdialog.h"
+
+#ifndef TQT_NO_DIALOG
+
+#include "tqpushbutton.h"
+#include "tqfocusdata.h"
+#include "tqapplication.h"
+#include "tqobjectlist.h"
+#include "tqwidgetlist.h"
+#include "tqlayout.h"
+#include "tqsizegrip.h"
+#include "tqwhatsthis.h"
+#include "tqpopupmenu.h"
+#include "tqcursor.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+#if defined( TQ_OS_TEMP )
+#include "tqt_windows.h"
+#endif
+
+/*!
+ \class TQDialog
+ \brief The TQDialog class is the base class of dialog windows.
+
+ \ingroup dialogs
+ \ingroup abstractwidgets
+ \mainclass
+
+ A dialog window is a top-level window mostly used for short-term
+ tasks and brief communications with the user. TQDialogs may be
+ modal or modeless. TQDialogs support \link #extensibility
+ extensibility\endlink and can provide a \link #return return
+ value\endlink. They can have \link #default default
+ buttons\endlink. TQDialogs can also have a TQSizeGrip in their
+ lower-right corner, using setSizeGripEnabled().
+
+ Note that TQDialog uses the tqparent widget slightly differently from
+ other classes in TQt. A dialog is always a top-level widget, but if
+ it has a tqparent, its default location is centered on top of the
+ tqparent's top-level widget (if it is not top-level itself). It will
+ also share the tqparent's taskbar entry.
+
+ \target modal
+ \section1 Modal Dialogs
+
+ A <b>modal</b> dialog is a dialog that blocks input to other
+ visible windows in the same application. Users must finish
+ interacting with the dialog and close it before they can access
+ any other window in the application. Dialogs that are used to
+ request a file name from the user or that are used to set
+ application preferences are usually modal.
+
+ The most common way to display a modal dialog is to call its
+ exec() function. When the user closes the dialog, exec() will
+ provide a useful \link #return return value\endlink. Typically we
+ connect a default button, e.g. "OK", to the accept() slot and a
+ "Cancel" button to the reject() slot, to get the dialog to close
+ and return the appropriate value. Alternatively you can connect to
+ the done() slot, passing it \c Accepted or \c Rejected.
+
+ An alternative is to call setModal(TRUE), then show(). Unlike
+ exec(), show() returns control to the caller immediately. Calling
+ setModal(TRUE) is especially useful for progress dialogs, where
+ the user must have the ability to interact with the dialog, e.g.
+ to cancel a long running operation. If you use show() and
+ setModal(TRUE) together you must call
+ TQApplication::processEvents() periodically during processing to
+ enable the user to interact with the dialog. (See \l
+ TQProgressDialog.)
+
+ \target modeless
+ \section1 Modeless Dialogs
+
+ A <b>modeless</b> dialog is a dialog that operates
+ independently of other windows in the same application. Find and
+ tqreplace dialogs in word-processors are often modeless to allow the
+ user to interact with both the application's main window and with
+ the dialog.
+
+ Modeless dialogs are displayed using show(), which returns control
+ to the caller immediately.
+
+ \target default
+ \section1 Default button
+
+ A dialog's \e default button is the button that's pressed when the
+ user presses Enter (Return). This button is used to signify that
+ the user accepts the dialog's settings and wants to close the
+ dialog. Use TQPushButton::setDefault(), TQPushButton::isDefault()
+ and TQPushButton::autoDefault() to set and control the dialog's
+ default button.
+
+ \target escapekey
+ \section1 Escape Key
+
+ If the user presses the Esc key in a dialog, TQDialog::reject()
+ will be called. This will cause the window to close: the \link
+ TQCloseEvent closeEvent \endlink cannot be \link
+ TQCloseEvent::ignore() ignored \endlink.
+
+ \target extensibility
+ \section1 Extensibility
+
+ Extensibility is the ability to show the dialog in two ways: a
+ partial dialog that shows the most commonly used options, and a
+ full dialog that shows all the options. Typically an extensible
+ dialog will initially appear as a partial dialog, but with a
+ "More" toggle button. If the user presses the "More" button down,
+ the full dialog will appear. The extension widget will be resized
+ to its tqsizeHint(). If orientation is \c Horizontal the extension
+ widget's height() will be expanded to the height() of the dialog.
+ If the orientation is \c Vertical the extension widget's width()
+ will be expanded to the width() of the dialog. Extensibility is
+ controlled with setExtension(), setOrientation() and
+ showExtension().
+
+ \target return
+ \section1 Return value (modal dialogs)
+
+ Modal dialogs are often used in situations where a return value is
+ required, e.g. to indicate whether the user pressed "OK" or
+ "Cancel". A dialog can be closed by calling the accept() or the
+ reject() Q_SLOTS, and exec() will return \c Accepted or \c Rejected
+ as appropriate. The exec() call returns the result of the dialog.
+ The result is also available from result() if the dialog has not
+ been destroyed. If the \c WDestructiveClose flag is set, the
+ dialog is deleted after exec() returns.
+
+ \target examples
+ \section1 Examples
+
+ A modal dialog.
+
+ \quotefile network/networkprotocol/view.cpp
+ \skipto TQFileDialog *dlg
+ \printuntil return
+
+ A modeless dialog. After the show() call, control returns to the main
+ event loop.
+ \quotefile life/main.cpp
+ \skipto argv
+ \printuntil TQApplication
+ \skipto scale
+ \printline
+ \skipto LifeDialog
+ \printuntil show
+ \skipto exec
+ \printuntil }
+
+ \sa TQTabDialog TQWidget TQProgressDialog
+ \link guibooks.html#fowler GUI Design Handbook: Dialogs, Standard\endlink
+*/
+
+/*! \enum TQDialog::DialogCode
+
+ The value returned by a modal dialog.
+
+ \value Accepted
+ \value Rejected
+
+*/
+
+/*!
+ \property TQDialog::sizeGripEnabled
+ \brief whether the size grip is enabled
+
+ A TQSizeGrip is placed in the bottom right corner of the dialog when this
+ property is enabled. By default, the size grip is disabled.
+*/
+
+class TQDialogPrivate : public TQt
+{
+public:
+
+ TQDialogPrivate()
+ : mainDef(0), orientation(Qt::Horizontal),extension(0), doShowExtension(FALSE)
+#ifndef TQT_NO_SIZEGRIP
+ ,resizer(0)
+#endif
+ {
+ }
+
+ TQPushButton* mainDef;
+ Qt::Orientation orientation;
+ TQWidget* extension;
+ bool doShowExtension;
+ TQSize size, min, max;
+#ifndef TQT_NO_SIZEGRIP
+ TQSizeGrip* resizer;
+#endif
+ TQPoint lastRMBPress;
+ TQPoint relPos; // relative position to the main window
+};
+
+/*!
+ Constructs a dialog called \a name, with tqparent \a tqparent.
+
+ A dialog is always a top-level widget, but if it has a tqparent, its
+ default location is centered on top of the tqparent. It will also
+ share the tqparent's taskbar entry.
+
+ The widget flags \a f are passed on to the TQWidget constructor.
+ If, for example, you don't want a What's This button in the titlebar
+ of the dialog, pass WStyle_Customize | WStyle_NormalBorder |
+ WStyle_Title | WStyle_SysMenu in \a f.
+
+ \warning In TQt 3.2, the \a modal flag is obsolete. There is now a
+ setModal() function that can be used for obtaining a modal behavior
+ when calling show(). This is rarely needed, because modal dialogs
+ are usually invoked using exec(), which ignores the \a modal flag.
+
+ \sa TQWidget::setWFlags() TQt::WidgetFlags
+*/
+
+TQDialog::TQDialog( TQWidget *tqparent, const char *name, bool modal, WFlags f )
+ : TQWidget( tqparent, name,
+ (WFlags)((modal ? (WFlags)(f|TQt::WShowModal) : f) | TQt::WType_Dialog )),
+ rescode(0), did_move(0), has_relpos(0), did_resize(0), in_loop(0)
+{
+ d = new TQDialogPrivate;
+}
+
+/*!
+ Destroys the TQDialog, deleting all its tqchildren.
+*/
+
+TQDialog::~TQDialog()
+{
+ // Need to hide() here, as our (to-be) overridden hide()
+ // will not be called in ~TQWidget.
+ hide();
+ delete d;
+}
+
+/*!
+ \internal
+ This function is called by the push button \a pushButton when it
+ becomes the default button. If \a pushButton is 0, the dialogs
+ default default button becomes the default button. This is what a
+ push button calls when it loses focus.
+*/
+
+void TQDialog::setDefault( TQPushButton *pushButton )
+{
+#ifndef TQT_NO_PUSHBUTTON
+ TQObjectList *list = queryList( "TQPushButton" );
+ TQ_ASSERT(list);
+ TQObjectListIt it( *list );
+ TQPushButton *pb;
+ bool hasMain = FALSE;
+ while ( (pb = (TQPushButton*)it.current()) ) {
+ ++it;
+ if ( pb->tqtopLevelWidget() != this )
+ continue;
+ if ( pb == d->mainDef )
+ hasMain = TRUE;
+ if ( pb != pushButton )
+ pb->setDefault( FALSE );
+ }
+ if (!pushButton && hasMain)
+ d->mainDef->setDefault( TRUE );
+ if (!hasMain)
+ d->mainDef = pushButton;
+ delete list;
+#endif
+}
+
+/*!
+ \internal
+ This function sets the default default pushbutton to \a pushButton.
+ This function is called by TQPushButton::setDefault().
+*/
+void TQDialog::setMainDefault( TQPushButton *pushButton )
+{
+#ifndef TQT_NO_PUSHBUTTON
+ d->mainDef = 0;
+ setDefault(pushButton);
+#endif
+}
+
+/*!
+ \internal
+ Hides the default button indicator. Called when non auto-default
+ push button get focus.
+ */
+void TQDialog::hideDefault()
+{
+#ifndef TQT_NO_PUSHBUTTON
+ TQObjectList *list = queryList( "TQPushButton" );
+ TQObjectListIt it( *list );
+ TQPushButton *pb;
+ while ( (pb = (TQPushButton*)it.current()) ) {
+ ++it;
+ pb->setDefault( FALSE );
+ }
+ delete list;
+#endif
+}
+
+#ifdef TQ_OS_TEMP
+/*!
+ \internal
+ Hides special buttons which are rather shown in the titlebar
+ on WinCE, to conserve screen space.
+*/
+# include "tqmessagebox.h"
+extern const char * mb_texts[]; // Defined in qmessagebox.cpp
+void TQDialog::hideSpecial()
+{
+ // "OK" buttons are hidden, and (Ok) shown on titlebar
+ // "Cancel" buttons are hidden, and (X) shown on titlebar
+ // "Help" buttons are hidden, and (?) shown on titlebar
+ bool showOK = FALSE,
+ showX = FALSE,
+ showQ = FALSE;
+ TQObjectList *list = queryList( "TQPushButton" );
+ TQObjectListIt it( *list );
+ TQPushButton *pb;
+ while ( (pb = (TQPushButton*)it.current()) ) {
+ if ( !showOK &&
+ pb->text() == tqApp->translate( "TQMessageBox", mb_texts[TQMessageBox::Ok] ) ) {
+ pb->hide();
+ showOK = TRUE;
+ } else if ( !showX &&
+ pb->text() == tqApp->translate( "TQMessageBox", mb_texts[TQMessageBox::Cancel] ) ) {
+ pb->hide();
+ showX = TRUE;
+ } else if ( !showQ &&
+ pb->text() == tqApp->tr("Help") ) {
+ pb->hide();
+ showQ = TRUE;
+ }
+ ++it;
+ }
+ delete list;
+ if ( showOK || showQ ) {
+ DWORD ext = GetWindowLong( winId(), GWL_EXSTYLE );
+ ext |= showOK ? WS_EX_CAPTIONOKBTN : 0;
+ ext |= showQ ? WS_EX_CONTEXTHELP: 0;
+ SetWindowLong( winId(), GWL_EXSTYLE, ext );
+ }
+ if ( !showX ) {
+ DWORD ext = GetWindowLong( winId(), GWL_STYLE );
+ ext &= ~WS_SYSMENU;
+ SetWindowLong( winId(), GWL_STYLE, ext );
+ }
+}
+#endif
+
+/*!
+ \fn int TQDialog::result() const
+
+ Returns the modal dialog's result code, \c Accepted or \c Rejected.
+
+ Do not call this function if the dialog was constructed with the \c
+ WDestructiveClose flag.
+*/
+
+/*!
+ \fn void TQDialog::setResult( int i )
+
+ Sets the modal dialog's result code to \a i.
+*/
+
+
+/*!
+ Shows the dialog as a \link #modal modal \endlink dialog,
+ blocking until the user closes it. The function returns a \l
+ DialogCode result.
+
+ Users cannot interact with any other window in the same
+ application until they close the dialog.
+
+ \sa show(), result()
+*/
+
+int TQDialog::exec()
+{
+ if ( in_loop ) {
+ qWarning( "TQDialog::exec: Recursive call detected" );
+ return -1;
+ }
+
+ bool destructiveClose = testWFlags( TQt::WDestructiveClose );
+ clearWFlags( TQt::WDestructiveClose );
+
+ bool wasShowModal = testWFlags( TQt::WShowModal );
+ setWFlags( TQt::WShowModal );
+ setResult( 0 );
+
+ show();
+
+ in_loop = TRUE;
+ tqApp->enter_loop();
+
+ if ( !wasShowModal )
+ clearWFlags( TQt::WShowModal );
+
+ int res = result();
+
+ if ( destructiveClose )
+ delete this;
+
+ return res;
+}
+
+
+/*! Closes the dialog and sets its result code to \a r. If this dialog
+ is shown with exec(), done() causes the local event loop to finish,
+ and exec() to return \a r.
+
+ As with TQWidget::close(), done() deletes the dialog if the \c
+ WDestructiveClose flag is set. If the dialog is the application's
+ main widget, the application terminates. If the dialog is the
+ last window closed, the TQApplication::lastWindowClosed() signal is
+ emitted.
+
+ \sa accept(), reject(), TQApplication::mainWidget(), TQApplication::quit()
+*/
+
+void TQDialog::done( int r )
+{
+ hide();
+ setResult( r );
+
+ // emulate TQWidget::close()
+ bool isMain = tqApp->mainWidget() == this;
+ bool checkLastWindowClosed = isTopLevel() && !isPopup();
+ if ( checkLastWindowClosed
+ && TQT_TQOBJECT(tqApp)->tqreceivers(TQT_SIGNAL(lastWindowClosed())) ) {
+ /* if there is no non-withdrawn top level window left (except
+ the desktop, popups, or dialogs with parents), we emit the
+ lastWindowClosed signal */
+ TQWidgetList *list = tqApp->tqtopLevelWidgets();
+ TQWidget *widget = list->first();
+ while ( widget ) {
+ if ( !widget->isHidden()
+ && !widget->isDesktop()
+ && !widget->isPopup()
+ && (!widget->isDialog() || !widget->parentWidget()))
+ break;
+ widget = list->next();
+ }
+ delete list;
+ if ( widget == 0 )
+ emit tqApp->lastWindowClosed();
+ }
+ if ( isMain )
+ tqApp->quit();
+ else if ( testWFlags(TQt::WDestructiveClose) ) {
+ clearWFlags(TQt::WDestructiveClose);
+ deleteLater();
+ }
+}
+
+/*!
+ Hides the modal dialog and sets the result code to \c Accepted.
+
+ \sa reject() done()
+*/
+
+void TQDialog::accept()
+{
+ done( Accepted );
+}
+
+/*!
+ Hides the modal dialog and sets the result code to \c Rejected.
+
+ \sa accept() done()
+*/
+
+void TQDialog::reject()
+{
+ done( Rejected );
+}
+
+/*! \reimp */
+bool TQDialog::eventFilter( TQObject *o, TQEvent *e )
+{
+ return TQWidget::eventFilter( o, e );
+}
+
+/*****************************************************************************
+ Event handlers
+ *****************************************************************************/
+
+/*! \reimp */
+void TQDialog::contextMenuEvent( TQContextMenuEvent *e )
+{
+#if !defined(TQT_NO_WHATSTHIS) && !defined(TQT_NO_POPUPMENU)
+ TQWidget* w = tqchildAt( e->pos(), TRUE );
+ if ( !w )
+ return;
+ TQString s;
+ while ( s.isEmpty() && w ) {
+ s = TQWhatsThis::textFor( w, e->pos(), FALSE );
+ if ( s.isEmpty() )
+ w = w->parentWidget(TRUE);
+ }
+ if ( !s.isEmpty() ) {
+ TQPopupMenu p(0,"qt_whats_this_menu");
+ p.insertItem( tr("What's This?"), 42 );
+ if ( p.exec( e->globalPos() ) >= 42 )
+ TQWhatsThis::display( s, w->mapToGlobal( w->rect().center() ), w );
+ }
+#endif
+}
+
+/*! \reimp */
+void TQDialog::keyPressEvent( TQKeyEvent *e )
+{
+ // Calls reject() if Escape is pressed. Simulates a button
+ // click for the default button if Enter is pressed. Move focus
+ // for the arrow keys. Ignore the rest.
+#ifdef TQ_OS_MAC
+ if(e->state() == ControlButton && e->key() == Qt::Key_Period) {
+ reject();
+ } else
+#endif
+ if ( e->state() == 0 || ( e->state() & TQt::Keypad && e->key() == Qt::Key_Enter ) ) {
+ switch ( e->key() ) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return: {
+#ifndef TQT_NO_PUSHBUTTON
+ TQObjectList *list = queryList( "TQPushButton" );
+ TQObjectListIt it( *list );
+ TQPushButton *pb;
+ while ( (pb = (TQPushButton*)it.current()) ) {
+ if ( pb->isDefault() && pb->isVisible() ) {
+ delete list;
+ if ( pb->isEnabled() ) {
+ emit pb->clicked();
+ }
+ return;
+ }
+ ++it;
+ }
+ delete list;
+#endif
+ }
+ break;
+ case Key_Escape:
+ reject();
+ break;
+ case Qt::Key_Up:
+ case Qt::Key_Left:
+ if ( tqfocusWidget() &&
+ ( tqfocusWidget()->focusPolicy() == Qt::StrongFocus ||
+ tqfocusWidget()->focusPolicy() == Qt::WheelFocus ) ) {
+ e->ignore();
+ break;
+ }
+ // call ours, since c++ blocks us from calling the one
+ // belonging to tqfocusWidget().
+#ifndef USE_QT4
+ TQFocusEvent::setReason(TQFocusEvent::Backtab);
+#endif // USE_QT4
+ focusNextPrevChild( FALSE );
+#ifndef USE_QT4
+ TQFocusEvent::resetReason();
+#endif // USE_QT4
+ break;
+ case Qt::Key_Down:
+ case Qt::Key_Right:
+ if ( tqfocusWidget() &&
+ ( tqfocusWidget()->focusPolicy() == Qt::StrongFocus ||
+ tqfocusWidget()->focusPolicy() == Qt::WheelFocus ) ) {
+ e->ignore();
+ break;
+ }
+#ifndef USE_QT4
+ TQFocusEvent::setReason(TQFocusEvent::Tab);
+#endif // USE_QT4
+ focusNextPrevChild( TRUE );
+#ifndef USE_QT4
+ TQFocusEvent::resetReason();
+#endif // USE_QT4
+ break;
+ default:
+ e->ignore();
+ return;
+ }
+ } else {
+ e->ignore();
+ }
+}
+
+/*! \reimp */
+void TQDialog::closeEvent( TQCloseEvent *e )
+{
+#ifndef TQT_NO_WHATSTHIS
+ if ( isModal() && TQWhatsThis::inWhatsThisMode() )
+ TQWhatsThis::leaveWhatsThisMode();
+#endif
+ if ( isShown() )
+ reject();
+ if ( isHidden() )
+ e->accept();
+}
+
+#ifdef TQ_OS_TEMP
+/*! \internal
+ \reimp
+*/
+bool TQDialog::event( TQEvent *e )
+{
+ switch ( e->type() ) {
+ case TQEvent::OkRequest:
+ case TQEvent::HelpRequest:
+ {
+ TQString bName =
+ (e->type() == TQEvent::OkRequest)
+ ? tqApp->translate( "TQMessageBox", mb_texts[TQMessageBox::Ok] )
+ : tqApp->tr( "Help" );
+
+ TQObjectList *list = queryList( "TQPushButton" );
+ TQObjectListIt it( *list );
+ TQPushButton *pb;
+ while ( (pb = (TQPushButton*)it.current()) ) {
+ if ( pb->text() == bName ) {
+ delete list;
+ if ( pb->isEnabled() )
+ emit pb->clicked();
+ return pb->isEnabled();
+ }
+ ++it;
+ }
+ delete list;
+ }
+ }
+ return TQWidget::event( e );
+}
+#endif
+
+
+/*****************************************************************************
+ Geometry management.
+ *****************************************************************************/
+
+#if defined(TQ_WS_X11)
+extern "C" { int XSetTransientForHint( Display *, unsigned long, unsigned long ); }
+#endif // TQ_WS_X11
+
+/*!
+ Shows the dialog as a \link #modeless modeless \endlink dialog.
+ Control returns immediately to the calling code.
+
+ The dialog will be modal or modeless according to the value
+ of the \l modal property.
+
+ \sa exec(), modal
+*/
+
+void TQDialog::show()
+{
+ if ( testWState(TQt::WState_Visible) )
+ return;
+
+ uint state = windowState();
+
+ if ( !did_resize )
+ adjustSize();
+ if ( has_relpos && !did_move ) {
+ adjustPositionInternal( parentWidget(), TRUE );
+ } else if ( !did_move ) {
+ adjustPositionInternal( parentWidget() );
+ }
+
+ if (windowState() != state)
+ setWindowState((WState)state);
+
+#if defined(TQ_WS_X11)
+ if (!parentWidget() && testWFlags(TQt::WShowModal)
+ && tqApp->mainWidget() && tqApp->mainWidget()->isVisible()
+ && !tqApp->mainWidget()->isMinimized()) {
+ // make sure the transient for hint is set properly for modal dialogs
+ XSetTransientForHint( x11Display(), winId(), tqApp->mainWidget()->winId() );
+ }
+#endif // TQ_WS_X11
+
+#ifdef TQ_OS_TEMP
+ hideSpecial();
+#endif
+
+ TQWidget::show();
+ showExtension( d->doShowExtension );
+#ifndef TQT_NO_PUSHBUTTON
+ TQWidget *fw = tqfocusWidget();
+ TQFocusData *fd = focusData();
+
+ /*
+ The following block is to handle a special case, and does not
+ really follow propper logic in concern of autoDefault and TAB
+ order. However, it's here to ease usage for the users. If a
+ dialog has a default TQPushButton, and first widget in the TAB
+ order also is a TQPushButton, then we give focus to the main
+ default TQPushButton. This simplifies code for the developers,
+ and actually catches most cases... If not, then they simply
+ have to use [widget*]->setFocus() themselves...
+ */
+ if ( !fw || fw->focusPolicy() == Qt::NoFocus ) {
+ fd->home(); // Skip main form
+ TQWidget *first = fd->next(); // Get first main widget
+ if ( d->mainDef &&
+ first != d->mainDef &&
+ ::tqqt_cast<TQPushButton*>(first) )
+ d->mainDef->setFocus();
+ }
+
+ if ( !d->mainDef && isTopLevel() ) {
+ if ( !fw || fw->focusPolicy() == Qt::NoFocus ) {
+ focusNextPrevChild( TRUE );
+ fw = tqfocusWidget();
+ }
+ if ( fw ) {
+ fd = focusData();
+ TQWidget *home = fd->home();
+ TQWidget *candidate = home;
+ TQ_ASSERT( candidate == fw );
+ do {
+ TQPushButton *pb = ::tqqt_cast<TQPushButton*>(candidate);
+ if ( pb && pb->autoDefault() ) {
+ pb->setDefault( TRUE );
+ break;
+ }
+ candidate = fd->next();
+ } while ( candidate != home );
+ }
+ }
+ if ( fw ) {
+ TQFocusEvent e( TQEvent::FocusIn );
+#ifndef USE_QT4
+ TQFocusEvent::setReason( TQFocusEvent::Tab );
+#endif // USE_QT4
+ TQApplication::sendEvent( fw, &e );
+#ifndef USE_QT4
+ TQFocusEvent::resetReason();
+#endif // USE_QT4
+ }
+
+#endif
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::DialogStart );
+#endif
+}
+
+/*! \internal */
+void TQDialog::adjustPosition( TQWidget* w)
+{
+ adjustPositionInternal( w );
+}
+
+
+void TQDialog::adjustPositionInternal( TQWidget*w, bool useRelPos)
+{
+ /* need to make sure these events are already sent to be sure
+ our information below is correct --sam */
+ TQApplication::sendPostedEvents( this, TQEvent::LayoutHint );
+ TQApplication::sendPostedEvents( this, TQEvent::Resize );
+
+ // processing the events might call polish(), which is a nice place
+ // to restore geometries, so return if the dialog has been positioned
+ if ( did_move || has_relpos )
+ return;
+
+ TQPoint p( 0, 0 );
+ int extraw = 0, extrah = 0, scrn = 0;
+ if ( w )
+ w = w->tqtopLevelWidget();
+ TQRect desk;
+ if ( w ) {
+ scrn = TQApplication::desktop()->screenNumber( w );
+ } else if ( TQApplication::desktop()->isVirtualDesktop() ) {
+ scrn = TQApplication::desktop()->screenNumber( TQCursor::pos() );
+ } else {
+ scrn = TQApplication::desktop()->screenNumber( this );
+ }
+ desk = TQApplication::desktop()->availableGeometry( scrn );
+
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ TQWidgetListIt it( *list );
+ while ( (extraw == 0 || extrah == 0) &&
+ it.current() != 0 ) {
+ int framew, frameh;
+ TQWidget * current = it.current();
+ ++it;
+ if ( ! current->isVisible() )
+ continue;
+
+ framew = current->tqgeometry().x() - current->x();
+ frameh = current->tqgeometry().y() - current->y();
+
+ extraw = TQMAX( extraw, framew );
+ extrah = TQMAX( extrah, frameh );
+ }
+ delete list;
+
+ // sanity check for decoration frames. With embedding, we
+ // might get extraordinary values
+ if ( extraw == 0 || extrah == 0 || extraw >= 10 || extrah >= 40 ) {
+ extrah = 40;
+ extraw = 10;
+ }
+
+ if ( useRelPos && w ) {
+ p = w->pos() + d->relPos;
+ } else {
+#ifndef TQ_OS_TEMP
+ if ( w ) {
+ // Use mapToGlobal rather than tqgeometry() in case w might
+ // be embedded in another application
+ TQPoint pp = w->mapToGlobal( TQPoint(0,0) );
+ p = TQPoint( pp.x() + w->width()/2,
+ pp.y() + w->height()/ 2 );
+ } else {
+ // p = middle of the desktop
+ p = TQPoint( desk.x() + desk.width()/2, desk.y() + desk.height()/2 );
+ }
+#else
+ p = TQPoint( desk.x() + desk.width()/2, desk.y() + desk.height()/2 );
+#endif
+
+ // p = origin of this
+ p = TQPoint( p.x()-width()/2 - extraw,
+ p.y()-height()/2 - extrah );
+ }
+
+
+ if ( p.x() + extraw + width() > desk.x() + desk.width() )
+ p.setX( desk.x() + desk.width() - width() - extraw );
+ if ( p.x() < desk.x() )
+ p.setX( desk.x() );
+
+ if ( p.y() + extrah + height() > desk.y() + desk.height() )
+ p.setY( desk.y() + desk.height() - height() - extrah );
+ if ( p.y() < desk.y() )
+ p.setY( desk.y() );
+
+ move( p );
+ did_move = !useRelPos;
+}
+
+
+/*! \reimp */
+void TQDialog::hide()
+{
+ if ( isHidden() )
+ return;
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ if ( isVisible() )
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::DialogEnd );
+#endif
+
+ if ( parentWidget() && !did_move ) {
+ d->relPos = pos() - parentWidget()->tqtopLevelWidget()->pos();
+ has_relpos = 1;
+ }
+
+ // Reimplemented to exit a modal when the dialog is hidden.
+ TQWidget::hide();
+ if ( in_loop ) {
+ in_loop = FALSE;
+ tqApp->exit_loop();
+ }
+}
+
+
+/*****************************************************************************
+ Detects any widget tqgeometry changes done by the user.
+ *****************************************************************************/
+
+/*! \reimp */
+
+void TQDialog::move( int x, int y )
+{
+ did_move = TRUE;
+ TQWidget::move( x, y );
+}
+
+/*! \reimp */
+
+void TQDialog::move( const TQPoint &p )
+{
+ did_move = TRUE;
+ TQWidget::move( p );
+}
+
+/*! \reimp */
+
+void TQDialog::resize( int w, int h )
+{
+ did_resize = TRUE;
+ TQWidget::resize( w, h );
+}
+
+/*! \reimp */
+
+void TQDialog::resize( const TQSize &s )
+{
+ did_resize = TRUE;
+ TQWidget::resize( s );
+}
+
+/*! \reimp */
+
+void TQDialog::setGeometry( int x, int y, int w, int h )
+{
+ did_move = TRUE;
+ did_resize = TRUE;
+ TQWidget::setGeometry( x, y, w, h );
+}
+
+/*! \reimp */
+
+void TQDialog::setGeometry( const TQRect &r )
+{
+ did_move = TRUE;
+ did_resize = TRUE;
+ TQWidget::setGeometry( r );
+}
+
+
+/*!
+ If \a orientation is \c Horizontal, the extension will be displayed
+ to the right of the dialog's main area. If \a orientation is \c
+ Vertical, the extension will be displayed below the dialog's main
+ area.
+
+ \sa orientation(), setExtension()
+*/
+void TQDialog::setOrientation( Qt::Orientation orientation )
+{
+ d->orientation = orientation;
+}
+
+/*!
+ Returns the dialog's extension orientation.
+
+ \sa setOrientation()
+*/
+TQt::Orientation TQDialog::orientation() const
+{
+ return d->orientation;
+}
+
+/*!
+ Sets the widget, \a extension, to be the dialog's extension,
+ deleting any previous extension. The dialog takes ownership of the
+ extension. Note that if 0 is passed any existing extension will be
+ deleted.
+
+ This function must only be called while the dialog is hidden.
+
+ \sa showExtension(), setOrientation(), extension()
+ */
+void TQDialog::setExtension( TQWidget* extension )
+{
+ delete d->extension;
+ d->extension = extension;
+
+ if ( !extension )
+ return;
+
+ if ( extension->parentWidget() != this )
+ extension->reparent( this, TQPoint(0,0) );
+ extension->hide();
+}
+
+/*!
+ Returns the dialog's extension or 0 if no extension has been
+ defined.
+
+ \sa setExtension()
+ */
+TQWidget* TQDialog::extension() const
+{
+ return d->extension;
+}
+
+
+/*!
+ If \a showIt is TRUE, the dialog's extension is shown; otherwise the
+ extension is hidden.
+
+ This slot is usually connected to the \l TQButton::toggled() signal
+ of a TQPushButton.
+
+ A dialog with a visible extension is not resizeable.
+
+ \sa show(), setExtension(), setOrientation()
+ */
+void TQDialog::showExtension( bool showIt )
+{
+ d->doShowExtension = showIt;
+ if ( !d->extension )
+ return;
+ if ( !testWState(TQt::WState_Visible) )
+ return;
+ if ( d->extension->isVisible() == showIt )
+ return;
+
+ if ( showIt ) {
+ d->size = size();
+ d->min = tqminimumSize();
+ d->max = tqmaximumSize();
+#ifndef TQT_NO_LAYOUT
+ if ( tqlayout() )
+ tqlayout()->setEnabled( FALSE );
+#endif
+ TQSize s( d->extension->tqsizeHint()
+ .expandedTo( d->extension->tqminimumSize() )
+ .boundedTo( d->extension->tqmaximumSize() ) );
+ if ( d->orientation == Qt::Horizontal ) {
+ int h = TQMAX( height(), s.height() );
+ d->extension->setGeometry( width(), 0, s.width(), h );
+ setFixedSize( width() + s.width(), h );
+ } else {
+ int w = TQMAX( width(), s.width() );
+ d->extension->setGeometry( 0, height(), w, s.height() );
+ setFixedSize( w, height() + s.height() );
+ }
+ d->extension->show();
+ } else {
+ d->extension->hide();
+ // workaround for CDE window manager that won't shrink with (-1,-1)
+ setMinimumSize( d->min.expandedTo( TQSize( 1, 1 ) ) );
+ setMaximumSize( d->max );
+ resize( d->size );
+#ifndef TQT_NO_LAYOUT
+ if ( tqlayout() )
+ tqlayout()->setEnabled( TRUE );
+#endif
+ }
+}
+
+
+/*! \reimp */
+TQSize TQDialog::tqsizeHint() const
+{
+ if ( d->extension ) {
+ if ( d->orientation == Qt::Horizontal )
+ return TQSize( TQWidget::tqsizeHint().width(),
+ TQMAX( TQWidget::tqsizeHint().height(),d->extension->tqsizeHint().height() ) );
+ else
+ return TQSize( TQMAX( TQWidget::tqsizeHint().width(), d->extension->tqsizeHint().width() ),
+ TQWidget::tqsizeHint().height() );
+ }
+
+ return TQWidget::tqsizeHint();
+}
+
+
+/*! \reimp */
+TQSize TQDialog::tqminimumSizeHint() const
+{
+ if ( d->extension ) {
+ if (d->orientation == Qt::Horizontal )
+ return TQSize( TQWidget::tqminimumSizeHint().width(),
+ TQMAX( TQWidget::tqminimumSizeHint().height(), d->extension->tqminimumSizeHint().height() ) );
+ else
+ return TQSize( TQMAX( TQWidget::tqminimumSizeHint().width(), d->extension->tqminimumSizeHint().width() ),
+ TQWidget::tqminimumSizeHint().height() );
+ }
+
+ return TQWidget::tqminimumSizeHint();
+}
+
+/*! \property TQDialog::modal
+ \brief whether show() should pop up the dialog as modal or modeless
+
+ By default, this property is false and show() pops up the dialog as
+ modeless.
+
+ exec() ignores the value of this property and always pops up the
+ dialog as modal.
+
+ \sa show(), exec()
+*/
+
+void TQDialog::setModal( bool modal )
+{
+ if ( modal )
+ setWFlags( TQt::WShowModal );
+ else
+ clearWFlags( TQt::WShowModal );
+}
+
+bool TQDialog::isModal() const
+{
+ return testWFlags( TQt::WShowModal ) != 0;
+}
+
+bool TQDialog::isSizeGripEnabled() const
+{
+#ifndef TQT_NO_SIZEGRIP
+ return !!d->resizer;
+#else
+ return FALSE;
+#endif
+}
+
+
+void TQDialog::setSizeGripEnabled(bool enabled)
+{
+#ifndef TQT_NO_SIZEGRIP
+ if ( !enabled != !d->resizer ) {
+ if ( enabled ) {
+ d->resizer = new TQSizeGrip( this, "TQDialog::resizer" );
+ // adjustSize() processes all events, which is suboptimal
+ d->resizer->resize( d->resizer->tqsizeHint() );
+ if ( TQApplication::reverseLayout() )
+ d->resizer->move( rect().bottomLeft() -d->resizer->rect().bottomLeft() );
+ else
+ d->resizer->move( rect().bottomRight() -d->resizer->rect().bottomRight() );
+ d->resizer->raise();
+ d->resizer->show();
+ } else {
+ delete d->resizer;
+ d->resizer = 0;
+ }
+ }
+#endif //TQT_NO_SIZEGRIP
+}
+
+
+
+/*! \reimp */
+void TQDialog::resizeEvent( TQResizeEvent * )
+{
+#ifndef TQT_NO_SIZEGRIP
+ if ( d->resizer ) {
+ if ( TQApplication::reverseLayout() )
+ d->resizer->move( rect().bottomLeft() -d->resizer->rect().bottomLeft() );
+ else
+ d->resizer->move( rect().bottomRight() -d->resizer->rect().bottomRight() );
+ }
+#endif
+}
+
+#endif // TQT_NO_DIALOG
diff --git a/tqtinterface/qt4/src/dialogs/tqdialog.h b/tqtinterface/qt4/src/dialogs/tqdialog.h
new file mode 100644
index 0000000..972fc1d
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqdialog.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Definition of TQDialog class
+**
+** Created : 950502
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDIALOG_H
+#define TQDIALOG_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#endif // TQT_H
+#ifndef TQT_NO_DIALOG
+#if 0
+TQ_OBJECT
+#endif
+
+class TQPushButton;
+class TQDialogPrivate;
+
+class TQ_EXPORT TQDialog : public TQWidget
+{
+friend class TQPushButton;
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool sizeGripEnabled READ isSizeGripEnabled WRITE setSizeGripEnabled )
+ Q_PROPERTY( bool modal READ isModal WRITE setModal )
+
+public:
+ TQ_EXPLICIT TQDialog( TQWidget* tqparent=0, const char* name=0, bool modal=FALSE,
+ WFlags f=0 );
+ ~TQDialog();
+
+ enum DialogCode { Rejected, Accepted };
+
+ int result() const { return rescode; }
+
+ void show();
+ void hide();
+ void move( int x, int y );
+ void move( const TQPoint &p );
+ void resize( int w, int h );
+ void resize( const TQSize & );
+ void setGeometry( int x, int y, int w, int h );
+ void setGeometry( const TQRect & );
+
+ void setOrientation( Qt::Orientation orientation );
+ Qt::Orientation orientation() const;
+
+ void setExtension( TQWidget* extension );
+ TQWidget* extension() const;
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ void setSizeGripEnabled( bool );
+ bool isSizeGripEnabled() const;
+
+ void setModal( bool modal );
+ bool isModal() const;
+#ifdef TQ_OS_TEMP
+ bool event( TQEvent * );
+#endif
+
+public Q_SLOTS:
+ int exec();
+
+protected Q_SLOTS:
+ virtual void done( int );
+ virtual void accept();
+ virtual void reject();
+
+ void showExtension( bool );
+
+protected:
+ void setResult( int r ) { rescode = r; }
+ virtual void keyPressEvent( TQKeyEvent * );
+ virtual void closeEvent( TQCloseEvent * );
+ virtual void resizeEvent( TQResizeEvent * );
+ virtual void contextMenuEvent( TQContextMenuEvent * );
+ virtual bool eventFilter( TQObject *, TQEvent * );
+ void adjustPosition( TQWidget*);
+
+private:
+ void setDefault( TQPushButton * );
+ void setMainDefault( TQPushButton * );
+ void hideDefault();
+#ifdef TQ_OS_TEMP
+ void hideSpecial();
+#endif
+
+ int rescode;
+ uint did_move : 1;
+ uint has_relpos : 1;
+ uint did_resize : 1;
+ uint in_loop: 1;
+ void adjustPositionInternal( TQWidget*, bool useRelPos = FALSE );
+ TQDialogPrivate* d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQDialog( const TQDialog & );
+ TQDialog &operator=( const TQDialog & );
+#endif
+};
+
+#endif // TQT_NO_DIALOG
+#endif // TQDIALOG_H
diff --git a/tqtinterface/qt4/src/dialogs/tqerrormessage.cpp b/tqtinterface/qt4/src/dialogs/tqerrormessage.cpp
new file mode 100644
index 0000000..8a86b71
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqerrormessage.cpp
@@ -0,0 +1,270 @@
+/****************************************************************************
+**
+** Implementation of a nice tqInstallMsgHandler() handler
+**
+** Created : 000527, after Kalle Dalheimer's birthday
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqerrormessage.h"
+
+#ifndef TQT_NO_ERRORMESSAGE
+
+#include "tqapplication.h"
+#include "tqcheckbox.h"
+#include "tqdict.h"
+#include "tqlabel.h"
+#include "tqlayout.h"
+#include "tqmessagebox.h"
+#include "tqpushbutton.h"
+#include "tqstringlist.h"
+#include "tqstylesheet.h"
+#include "tqtextview.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+class TQErrorMessageTextView : public TQTextView
+{
+public:
+ TQErrorMessageTextView( TQWidget *tqparent, const char *name )
+ : TQTextView( tqparent, name ) { }
+
+ virtual TQSize tqminimumSizeHint() const;
+ virtual TQSize tqsizeHint() const;
+};
+
+TQSize TQErrorMessageTextView::tqminimumSizeHint() const
+{
+ return TQSize( 50, 50 );
+}
+
+TQSize TQErrorMessageTextView::tqsizeHint() const
+{
+ return TQSize( 250, 75 );
+}
+
+/*! \class TQErrorMessage
+
+ \brief The TQErrorMessage class provides an error message display dialog.
+
+ \ingroup dialogs
+ \ingroup misc
+
+This is basically a TQLabel and a "show this message again" checkbox which
+remembers what not to show.
+
+There are two ways to use this class:
+\list 1
+\i For production applications. In this context the class can be used to
+display messages which you don't need the user to see more than once. To use
+TQErrorMessage like this, you create the dialog in the usual way and call the
+message() slot, or connect Q_SIGNALS to it.
+
+\i For developers. In this context the static qtHandler() installs
+a message handler using tqInstallMsgHandler() and creates a TQErrorMessage
+that displays qDebug(), qWarning() and qFatal() messages.
+\endlist
+
+In both cases TQErrorMessage will queue pending messages, and display
+them (or not) in order, as soon as the user presses Enter or clicks OK
+after seeing each message.
+
+\img qerrormessage.png
+
+\sa TQMessageBox TQStatusBar::message()
+*/
+
+static TQErrorMessage * qtMessageHandler = 0;
+
+static void deleteStaticcTQErrorMessage() // post-routine
+{
+ if ( qtMessageHandler ) {
+ delete qtMessageHandler;
+ qtMessageHandler = 0;
+ }
+}
+
+static bool metFatal = FALSE;
+
+void jump( TQtMsgType t, const char * m )
+{
+ if ( !qtMessageHandler )
+ return;
+
+ TQString rich;
+
+ switch ( t ) {
+ case TQtDebugMsg:
+ default:
+ rich = TQErrorMessage::tr( "Debug Message:" );
+ break;
+ case TQtWarningMsg:
+ rich = TQErrorMessage::tr( "Warning:" );
+ break;
+ case TQtFatalMsg:
+ rich = TQErrorMessage::tr( "Fatal Error:" );
+ }
+ rich = TQString( "<p><b>%1</b></p>" ).arg( rich );
+ rich += TQStyleSheet::convertFromPlainText( m,
+ TQStyleSheetItem::WhiteSpaceNormal );
+
+ // ### work around text engine quirk
+ if ( rich.endsWith("</p>") )
+ rich.truncate( rich.length() - 4 );
+
+ if ( !metFatal ) {
+ qtMessageHandler->message( rich );
+ metFatal = ( t == TQtFatalMsg );
+ }
+}
+
+
+/*! Constructs and installs an error handler window.
+ The tqparent \a tqparent and name \a name are passed on to the TQDialog
+ constructor.
+*/
+
+TQErrorMessage::TQErrorMessage( TQWidget * tqparent, const char * name )
+ : TQDialog( tqparent, name )
+{
+ TQGridLayout * grid = new TQGridLayout( this, 3, 2, 11, 6 );
+ icon = new TQLabel( this, "qt_icon_lbl" );
+#ifndef TQT_NO_MESSAGEBOX
+ icon->setPixmap( TQMessageBox::standardIcon(TQMessageBox::Information) );
+#endif
+ grid->addWidget( icon, 0, 0, Qt::AlignTop );
+ errors = new TQErrorMessageTextView( this, "errors" );
+ grid->addWidget( errors, 0, 1 );
+ again = new TQCheckBox( tr( "&Show this message again" ), this, "again" );
+ again->setChecked( TRUE );
+ grid->addWidget( again, 1, 1, (Qt::Alignment)(TQt::AlignTop + TQt::AlignAuto) );
+ ok = new TQPushButton( tr( "&OK" ), this, "ok" );
+ connect( ok, TQT_SIGNAL(clicked()), this, TQT_SLOT(accept()) );
+ ok->setFocus();
+ grid->addMultiCellWidget( ok, 2, 2, 0, 1, Qt::AlignCenter );
+ grid->setColStretch( 1, 42 );
+ grid->setRowStretch( 0, 42 );
+ pending = new TQStringList;
+ doNotShow = new TQDict<int>;
+}
+
+
+/*! Destroys the object and frees any allocated resources. Notably,
+the list of "do not show again" messages is deleted. */
+
+TQErrorMessage::~TQErrorMessage()
+{
+ if ( this == qtMessageHandler ) {
+ qtMessageHandler = 0;
+ TQtMsgHandler tmp = tqInstallMsgHandler( 0 );
+ // in case someone else has later stuck in another...
+ if ( tmp != jump )
+ tqInstallMsgHandler( tmp );
+ }
+
+ delete pending;
+ delete doNotShow;
+}
+
+
+/*! \reimp */
+
+void TQErrorMessage::done( int a )
+{
+ int dummy = 0;
+ if ( !again->isChecked() )
+ doNotShow->insert( errors->text(), &dummy );
+ if ( !nextPending() ) {
+ TQDialog::done( a );
+ if ( this == qtMessageHandler && metFatal )
+ exit( 1 );
+ }
+}
+
+
+/*! Returns a pointer to a TQErrorMessage object that outputs the
+default TQt messages. This function creates such an object, if there
+isn't one already.
+*/
+
+TQErrorMessage * TQErrorMessage::qtHandler()
+{
+ if ( !qtMessageHandler ) {
+ qtMessageHandler = new TQErrorMessage( 0, "automatic message handler" );
+ qAddPostRoutine( deleteStaticcTQErrorMessage ); // clean up
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( tqApp->mainWidget() )
+ qtMessageHandler->setCaption( tqApp->mainWidget()->caption() );
+#endif
+ tqInstallMsgHandler( jump );
+ }
+ return qtMessageHandler;
+}
+
+
+/*! \internal */
+
+bool TQErrorMessage::nextPending()
+{
+ while ( !pending->isEmpty() ) {
+ TQString p = *pending->begin();
+ pending->remove( pending->begin() );
+ if ( !p.isEmpty() && !doNotShow->tqfind( p ) ) {
+ errors->setText( p );
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+/*! Shows message \a m and returns immediately. If the user has requested
+ that \a m not be shown, this function does nothing.
+
+ Normally, \a m is shown at once, but if there are pending messages,
+ \a m is queued for later display.
+*/
+
+void TQErrorMessage::message( const TQString & m )
+{
+ if ( doNotShow->tqfind( m ) )
+ return;
+ pending->append( m );
+ if ( !isVisible() && nextPending() )
+ show();
+}
+
+#endif // TQT_NO_ERRORMESSAGE
diff --git a/tqtinterface/qt4/src/dialogs/tqerrormessage.h b/tqtinterface/qt4/src/dialogs/tqerrormessage.h
new file mode 100644
index 0000000..6809ba4
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqerrormessage.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Definition of a nice qInstallErrorMessage() handler
+**
+** Created : 000527, after Kalle Dalheimer's birthday
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQERRORMESSAGE_H
+#define TQERRORMESSAGE_H
+
+#ifndef TQT_H
+#include "tqdialog.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_ERRORMESSAGE
+class TQPushButton;
+class TQCheckBox;
+class TQLabel;
+class TQTextView;
+class TQStringList;
+template<class type> class TQDict;
+
+
+class TQ_EXPORT TQErrorMessage: public TQDialog {
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQErrorMessage( TQWidget* tqparent, const char* name=0 );
+ ~TQErrorMessage();
+
+ static TQErrorMessage * qtHandler();
+
+public Q_SLOTS:
+ void message( const TQString & );
+
+protected:
+ void done( int );
+
+private:
+ TQPushButton * ok;
+ TQCheckBox * again;
+ TQTextView * errors;
+ TQLabel * icon;
+ TQStringList * pending;
+ TQDict<int> * doNotShow;
+
+ bool nextPending();
+
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQErrorMessage( const TQErrorMessage & );
+ TQErrorMessage &operator=( const TQErrorMessage & );
+#endif
+};
+
+#endif //TQT_NO_ERRORMESSAGE
+
+#endif
diff --git a/tqtinterface/qt4/src/dialogs/tqfiledialog.cpp b/tqtinterface/qt4/src/dialogs/tqfiledialog.cpp
new file mode 100644
index 0000000..f92e18e
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqfiledialog.cpp
@@ -0,0 +1,6466 @@
+/****************************************************************************
+**
+** Implementation of TQFileDialog class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
+#if defined(connect)
+# undef connect
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+#include "tqfiledialog.h"
+
+#ifndef TQT_NO_FILEDIALOG
+
+#include "private/tqapplication_p.h"
+#include "tqapplication.h"
+#include "tqbitmap.h"
+#include "tqbuttongroup.h"
+#include "tqcheckbox.h"
+#include "tqcleanuphandler.h"
+#include "tqcombobox.h"
+#include "tqcstring.h"
+#include "tqcursor.h"
+#include "tqdragobject.h"
+#include "tqfile.h"
+#include "tqguardedptr.h"
+#include "tqhbox.h"
+#include "tqheader.h"
+#include "tqlabel.h"
+#include "tqlayout.h"
+#include "tqlibrary.h"
+#include "tqlineedit.h"
+#include "tqlistbox.h"
+#include "tqlistview.h"
+#include "tqmap.h"
+#include "tqmessagebox.h"
+#include "tqmime.h"
+#include "tqnetworkprotocol.h"
+#include "tqobjectlist.h"
+#include "tqpainter.h"
+#include "tqpopupmenu.h"
+#include "tqprogressbar.h"
+#include "tqptrvector.h"
+#include "tqpushbutton.h"
+#include "tqregexp.h"
+#include "tqsemimodal.h"
+#include "tqsplitter.h"
+#include "tqstrlist.h"
+#include "tqstyle.h"
+#include "tqtimer.h"
+#include "tqtoolbutton.h"
+#include "tqtooltip.h"
+#include "tqvbox.h"
+#include "tqwidgetstack.h"
+
+#ifdef TQ_WS_WIN
+#ifdef TQT_THREAD_SUPPORT
+# include <private/tqmutexpool_p.h>
+#endif // TQT_THREAD_SUPPORT
+#endif // TQ_WS_WIN
+
+#if !defined(TQ_OS_TEMP)
+#include <time.h>
+#else
+#include <shellapi.h>
+#endif
+#include <stdlib.h>
+#include <limits.h>
+#include <ctype.h>
+
+#ifdef TQ_WS_MAC
+#include "tqt_mac.h"
+extern TQString qt_mac_precomposeFileName(const TQString &); // qglobal.cpp
+#undef check
+#endif
+
+/* XPM */
+static const char * const start_xpm[]={
+ "16 15 8 1",
+ "a c #cec6bd",
+ "# c #000000",
+ "e c #ffff00",
+ "b c #999999",
+ "f c #cccccc",
+ "d c #dcdcdc",
+ "c c #ffffff",
+ ". c None",
+ ".....######aaaaa",
+ "...bb#cccc##aaaa",
+ "..bcc#cccc#d#aaa",
+ ".bcef#cccc#dd#aa",
+ ".bcfe#cccc#####a",
+ ".bcef#ccccccccc#",
+ "bbbbbbbbbbbbccc#",
+ "bccccccccccbbcc#",
+ "bcefefefefee#bc#",
+ ".bcefefefefef#c#",
+ ".bcfefefefefe#c#",
+ "..bcfefefefeeb##",
+ "..bbbbbbbbbbbbb#",
+ "...#############",
+ "................"};
+
+/* XPM */
+static const char * const end_xpm[]={
+ "16 15 9 1",
+ "d c #a0a0a0",
+ "c c #c3c3c3",
+ "# c #cec6bd",
+ ". c #000000",
+ "f c #ffff00",
+ "e c #999999",
+ "g c #cccccc",
+ "b c #ffffff",
+ "a c None",
+ "......####aaaaaa",
+ ".bbbb..###aaaaaa",
+ ".bbbb.c.##aaaaaa",
+ ".bbbb....ddeeeea",
+ ".bbbbbbb.bbbbbe.",
+ ".bbbbbbb.bcfgfe.",
+ "eeeeeeeeeeeeefe.",
+ "ebbbbbbbbbbeege.",
+ "ebfgfgfgfgff.ee.",
+ "aebfgfgfgfgfg.e.",
+ "aebgfgfgfgfgf.e.",
+ "aaebgfgfgfgffe..",
+ "aaeeeeeeeeeeeee.",
+ "aaa.............",
+ "aaaaaaaaaaaaaaaa"};
+
+/* XPM */
+static const char* const open_xpm[]={
+ "16 16 6 1",
+ ". c None",
+ "b c #ffff00",
+ "d c #000000",
+ "* c #999999",
+ "c c #cccccc",
+ "a c #ffffff",
+ "................",
+ "................",
+ "...*****........",
+ "..*aaaaa*.......",
+ ".*abcbcba******.",
+ ".*acbcbcaaaaaa*d",
+ ".*abcbcbcbcbcb*d",
+ "*************b*d",
+ "*aaaaaaaaaa**c*d",
+ "*abcbcbcbcbbd**d",
+ ".*abcbcbcbcbcd*d",
+ ".*acbcbcbcbcbd*d",
+ "..*acbcbcbcbb*dd",
+ "..*************d",
+ "...ddddddddddddd",
+ "................"};
+
+/* XPM */
+static const char * const link_dir_xpm[]={
+ "16 16 10 1",
+ "h c #808080",
+ "g c #a0a0a0",
+ "d c #000000",
+ "b c #ffff00",
+ "f c #303030",
+ "# c #999999",
+ "a c #cccccc",
+ "e c #585858",
+ "c c #ffffff",
+ ". c None",
+ "................",
+ "................",
+ "..#####.........",
+ ".#ababa#........",
+ "#abababa######..",
+ "#cccccccccccc#d.",
+ "#cbababababab#d.",
+ "#cabababababa#d.",
+ "#cbababdddddddd.",
+ "#cababadccccccd.",
+ "#cbababdcececcd.",
+ "#cababadcefdfcd.",
+ "#cbababdccgdhcd.",
+ "#######dccchccd.",
+ ".dddddddddddddd.",
+ "................"};
+
+/* XPM */
+static const char * const link_file_xpm[]={
+ "16 16 10 1",
+ "h c #808080",
+ "g c #a0a0a0",
+ "d c #c3c3c3",
+ ". c #7f7f7f",
+ "c c #000000",
+ "b c #bfbfbf",
+ "f c #303030",
+ "e c #585858",
+ "a c #ffffff",
+ "# c None",
+ "################",
+ "..........######",
+ ".aaaaaaaab.#####",
+ ".aaaaaaaaba.####",
+ ".aaaaaaaacccc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaadc###",
+ ".aaaaaaaaaadc###",
+ ".aaaacccccccc###",
+ ".aaaacaaaaaac###",
+ ".aaaacaeaeaac###",
+ ".aaaacaefcfac###",
+ ".aaaacaagchac###",
+ ".ddddcaaahaac###",
+ "ccccccccccccc###"};
+
+/* XPM */
+static const char* const file_xpm[]={
+ "16 16 5 1",
+ ". c #7f7f7f",
+ "# c None",
+ "c c #000000",
+ "b c #bfbfbf",
+ "a c #ffffff",
+ "################",
+ "..........######",
+ ".aaaaaaaab.#####",
+ ".aaaaaaaaba.####",
+ ".aaaaaaaacccc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".aaaaaaaaaabc###",
+ ".bbbbbbbbbbbc###",
+ "ccccccccccccc###"};
+
+/* XPM */
+static const char * const closed_xpm[]={
+ "16 16 6 1",
+ ". c None",
+ "b c #ffff00",
+ "d c #000000",
+ "* c #999999",
+ "a c #cccccc",
+ "c c #ffffff",
+ "................",
+ "................",
+ "..*****.........",
+ ".*ababa*........",
+ "*abababa******..",
+ "*cccccccccccc*d.",
+ "*cbababababab*d.",
+ "*cabababababa*d.",
+ "*cbababababab*d.",
+ "*cabababababa*d.",
+ "*cbababababab*d.",
+ "*cabababababa*d.",
+ "*cbababababab*d.",
+ "**************d.",
+ ".dddddddddddddd.",
+ "................"};
+
+
+/* XPM */
+static const char* const cdtoparent_xpm[]={
+ "15 13 3 1",
+ ". c None",
+ "* c #000000",
+ "a c #ffff99",
+ "..*****........",
+ ".*aaaaa*.......",
+ "***************",
+ "*aaaaaaaaaaaaa*",
+ "*aaaa*aaaaaaaa*",
+ "*aaa***aaaaaaa*",
+ "*aa*****aaaaaa*",
+ "*aaaa*aaaaaaaa*",
+ "*aaaa*aaaaaaaa*",
+ "*aaaa******aaa*",
+ "*aaaaaaaaaaaaa*",
+ "*aaaaaaaaaaaaa*",
+ "***************"};
+
+
+/* XPM */
+static const char* const newfolder_xpm[] = {
+ "15 14 4 1",
+ " c None",
+ ". c #000000",
+ "+ c #FFFF00",
+ "@ c #FFFFFF",
+ " . ",
+ " ",
+ " . ",
+ " . . ",
+ " .... . . . ",
+ " .+@+@. . . ",
+ ".......... . .",
+ ".@+@+@+@+@.. ",
+ ".+@+@+@+@+. . ",
+ ".@+@+@+@+@. . ",
+ ".+@+@+@+@+. ",
+ ".@+@+@+@+@. ",
+ ".+@+@+@+@+. ",
+ "........... "};
+
+/* XPM */
+static const char* const detailedview_xpm[]={
+ "14 11 3 1",
+ ". c None",
+ "* c #000000",
+ "a c #000099",
+ ".****.***.***.",
+ "..............",
+ "aaaaaaaaaaaaaa",
+ "..............",
+ ".****.***.***.",
+ "..............",
+ ".****.***.***.",
+ "..............",
+ ".****.***.***.",
+ "..............",
+ ".****.***.***."};
+
+/* XPM */
+static const char* const previewinfoview_xpm[]={
+ "13 13 4 1",
+ ". c #00007f",
+ "a c black",
+ "# c #cec6bd",
+ "b c #000000",
+ "..#####aaaaaa",
+ ".#.#bb#a#####",
+ "...####a#bbb#",
+ "#######a#####",
+ "#######a#bb##",
+ "..#####a#####",
+ ".#.#bb#a#bbb#",
+ "...####a#####",
+ "#######a#bb##",
+ "#######a#####",
+ "..#####a#bbb#",
+ ".#.#bb#a#####",
+ "...####aaaaaa"};
+
+/* XPM */
+static const char* const previewcontentsview_xpm[]={
+ "14 13 5 1",
+ ". c #00007f",
+ "a c black",
+ "c c #7f007f",
+ "# c #cec6bd",
+ "b c #000000",
+ "..#####aaaaaaa",
+ ".#.#bb#a#####a",
+ "...####a#ccc#a",
+ "#######a#ccc#a",
+ "#######a#####a",
+ "..#####a#bbb#a",
+ ".#.#bb#a#####a",
+ "...####a#bbb#a",
+ "#######a#####a",
+ "#######a#bbb#a",
+ "..#####a#####a",
+ ".#.#bb#a#####a",
+ "...####aaaaaaa"};
+
+/* XPM */
+static const char* const mclistview_xpm[]={
+ "15 11 4 1",
+ "* c None",
+ "b c #000000",
+ ". c #000099",
+ "a c #ffffff",
+ "...*****...****",
+ ".a.*bbb*.a.*bbb",
+ "...*****...****",
+ "***************",
+ "...*****...****",
+ ".a.*bbb*.a.*bbb",
+ "...*****...****",
+ "***************",
+ "...*****...****",
+ ".a.*bbb*.a.*bbb",
+ "...*****...****"};
+
+/* XPM */
+static const char * const back_xpm [] = {
+ "13 11 3 1",
+ "a c #00ffff",
+ "# c #000000",
+ ". c None",
+ ".....#.......",
+ "....##.......",
+ "...#a#.......",
+ "..#aa########",
+ ".#aaaaaaaaaa#",
+ "#aaaaaaaaaaa#",
+ ".#aaaaaaaaaa#",
+ "..#aa########",
+ "...#a#.......",
+ "....##.......",
+ ".....#......."};
+
+static TQPixmap * openFolderIcon = 0;
+static TQPixmap * closedFolderIcon = 0;
+static TQPixmap * detailViewIcon = 0;
+static TQPixmap * multiColumnListViewIcon = 0;
+static TQPixmap * cdToParentIcon = 0;
+static TQPixmap * newFolderIcon = 0;
+static TQPixmap * fifteenTransparentPixels = 0;
+static TQPixmap * symLinkDirIcon = 0;
+static TQPixmap * symLinkFileIcon = 0;
+static TQPixmap * fileIcon = 0;
+static TQPixmap * startCopyIcon = 0;
+static TQPixmap * endCopyIcon = 0;
+static TQPixmap * previewContentsViewIcon = 0;
+static TQPixmap * previewInfoViewIcon = 0;
+static TQPixmap *goBackIcon = 0;
+static TQFileIconProvider * fileIconProvider = 0;
+static int lastWidth = 0;
+static int lastHeight = 0;
+static TQString * workingDirectory = 0;
+
+static bool bShowHiddenFiles = FALSE;
+static int sortFilesBy = (int)TQDir::Name;
+static bool sortAscending = TRUE;
+static bool detailViewMode = FALSE;
+
+static TQCleanupHandler<TQPixmap> qfd_cleanup_pixmap;
+static TQCleanupHandler<TQString> qfd_cleanup_string;
+
+static TQString toRootIfNotExists( const TQString &path )
+{
+ if ( !path.isEmpty() )
+ return path;
+
+ const TQFileInfoList *drives = TQDir::drives();
+ TQ_ASSERT( drives && !drives->isEmpty() );
+ return drives->getFirst()->filePath();
+}
+
+static bool isDirectoryMode( int m )
+{
+ return m == TQFileDialog::Directory || m == TQFileDialog::DirectoryOnly;
+}
+
+static void updateLastSize( TQFileDialog *that )
+{
+ int extWidth = 0;
+ int extHeight = 0;
+ if ( that->extension() && that->extension()->isVisible() ) {
+ if ( that->orientation() == Qt::Vertical )
+ extHeight = that->extension()->height();
+ else
+ extWidth = that->extension()->width();
+ }
+ lastWidth = that->width() - extWidth;
+ lastHeight = that->height() - extHeight;
+}
+
+// Don't remove the lines below!
+//
+// resolving the W methods manually is needed, because Windows 95 doesn't include
+// these methods in Shell32.lib (not even stubs!), so you'd get an unresolved symbol
+// when TQt calls getEsistingDirectory(), etc.
+#if defined(TQ_WS_WIN)
+
+typedef UINT (WINAPI *PtrExtractIconEx)(LPCTSTR,int,HICON*,HICON*,UINT);
+static PtrExtractIconEx ptrExtractIconEx = 0;
+
+static void resolveLibs()
+{
+#ifndef TQ_OS_TEMP
+ static bool triedResolve = FALSE;
+
+ if ( !triedResolve ) {
+#ifdef TQT_THREAD_SUPPORT
+ // protect initialization
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &triedResolve ) : 0 );
+ // check triedResolve again, since another thread may have already
+ // done the initialization
+ if ( triedResolve ) {
+ // another thread did initialize the security function pointers,
+ // so we shouldn't do it again.
+ return;
+ }
+#endif
+ triedResolve = TRUE;
+ if ( qt_wintqunicode ) {
+ TQLibrary lib("shell32");
+ lib.setAutoUnload( FALSE );
+ ptrExtractIconEx = (PtrExtractIconEx) lib.resolve( "ExtractIconExW" );
+ }
+ }
+#endif
+}
+#ifdef TQ_OS_TEMP
+#define PtrExtractIconEx ExtractIconEx
+#endif
+
+class TQWindowsIconProvider : public TQFileIconProvider
+{
+public:
+ TQWindowsIconProvider( TQObject *tqparent=0, const char *name=0 );
+ ~TQWindowsIconProvider();
+
+ const TQPixmap * pixmap( const TQFileInfo &fi );
+
+private:
+ TQPixmap defaultFolder;
+ TQPixmap defaultFile;
+ TQPixmap defaultExe;
+ TQPixmap pix;
+ int pixw, pixh;
+ TQMap< TQString, TQPixmap > cache;
+
+};
+#endif
+
+static void makeVariables() {
+ if ( !openFolderIcon ) {
+ workingDirectory = new TQString( ::toRootIfNotExists(TQDir::currentDirPath()) );
+ qfd_cleanup_string.add( &workingDirectory );
+
+ openFolderIcon = new TQPixmap( (const char **)open_xpm);
+ qfd_cleanup_pixmap.add( &openFolderIcon );
+ symLinkDirIcon = new TQPixmap( (const char **)link_dir_xpm);
+ qfd_cleanup_pixmap.add( &symLinkDirIcon );
+ symLinkFileIcon = new TQPixmap( (const char **)link_file_xpm);
+ qfd_cleanup_pixmap.add( &symLinkFileIcon );
+ fileIcon = new TQPixmap( (const char **)file_xpm);
+ qfd_cleanup_pixmap.add( &fileIcon );
+ closedFolderIcon = new TQPixmap( (const char **)closed_xpm);
+ qfd_cleanup_pixmap.add( &closedFolderIcon );
+ detailViewIcon = new TQPixmap( (const char **)detailedview_xpm);
+ qfd_cleanup_pixmap.add( &detailViewIcon );
+ multiColumnListViewIcon = new TQPixmap( (const char **)mclistview_xpm);
+ qfd_cleanup_pixmap.add( &multiColumnListViewIcon );
+ cdToParentIcon = new TQPixmap( (const char **)cdtoparent_xpm);
+ qfd_cleanup_pixmap.add( &cdToParentIcon );
+ newFolderIcon = new TQPixmap( (const char **)newfolder_xpm);
+ qfd_cleanup_pixmap.add( &newFolderIcon );
+ previewInfoViewIcon
+ = new TQPixmap( (const char **)previewinfoview_xpm );
+ qfd_cleanup_pixmap.add( &previewInfoViewIcon );
+ previewContentsViewIcon
+ = new TQPixmap( (const char **)previewcontentsview_xpm );
+ qfd_cleanup_pixmap.add( &previewContentsViewIcon );
+ startCopyIcon = new TQPixmap( (const char **)start_xpm );
+ qfd_cleanup_pixmap.add( &startCopyIcon );
+ endCopyIcon = new TQPixmap( (const char **)end_xpm );
+ qfd_cleanup_pixmap.add( &endCopyIcon );
+ goBackIcon = new TQPixmap( (const char **)back_xpm );
+ qfd_cleanup_pixmap.add( &goBackIcon );
+ fifteenTransparentPixels = new TQPixmap( closedFolderIcon->width(), 1 );
+ qfd_cleanup_pixmap.add( &fifteenTransparentPixels );
+ TQBitmap m( fifteenTransparentPixels->width(), 1 );
+ m.fill( TQt::color0 );
+ fifteenTransparentPixels->setMask( m );
+ bShowHiddenFiles = FALSE;
+ sortFilesBy = (int)TQDir::Name;
+ detailViewMode = FALSE;
+#if defined(TQ_WS_WIN)
+ if ( !fileIconProvider )
+ fileIconProvider = new TQWindowsIconProvider( tqApp );
+#endif
+ }
+}
+
+/******************************************************************
+ *
+ * Definitions of view classes
+ *
+ ******************************************************************/
+
+class TQRenameEdit : public TQLineEdit
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQRenameEdit( TQWidget *tqparent )
+ : TQLineEdit( tqparent, "qt_rename_edit" ), doRenameAlreadyEmitted(FALSE)
+ {
+ connect( this, TQT_SIGNAL(returnPressed()), TQT_SLOT(slotReturnPressed()) );
+ }
+
+protected:
+ void keyPressEvent( TQKeyEvent *e );
+ void focusOutEvent( TQFocusEvent *e );
+
+Q_SIGNALS:
+ void cancelRename();
+ void doRename();
+
+private Q_SLOTS:
+ void slotReturnPressed();
+
+private:
+ bool doRenameAlreadyEmitted;
+};
+
+class TQFileListBox : public TQListBox
+{
+ friend class TQFileDialog;
+
+ Q_OBJECT
+ TQ_OBJECT
+
+private:
+ TQFileListBox( TQWidget *tqparent, TQFileDialog *d );
+
+ void clear();
+ void show();
+ void startRename( bool check = TRUE );
+ void viewportMousePressEvent( TQMouseEvent *e );
+ void viewportMouseReleaseEvent( TQMouseEvent *e );
+ void viewportMouseDoubleClickEvent( TQMouseEvent *e );
+ void viewportMouseMoveEvent( TQMouseEvent *e );
+#ifndef TQT_NO_DRAGANDDROP
+ void viewportDragEnterEvent( TQDragEnterEvent *e );
+ void viewportDragMoveEvent( TQDragMoveEvent *e );
+ void viewportDragLeaveEvent( TQDragLeaveEvent *e );
+ void viewportDropEvent( TQDropEvent *e );
+ bool acceptDrop( const TQPoint &pnt, TQWidget *source );
+ void setCurrentDropItem( const TQPoint &pnt );
+#endif
+ void keyPressEvent( TQKeyEvent *e );
+
+private Q_SLOTS:
+ void rename();
+ void cancelRename();
+ void doubleClickTimeout();
+ void changeDirDuringDrag();
+ void dragObjDestroyed();
+ void contentsMoved( int, int );
+
+private:
+ TQRenameEdit *lined;
+ TQFileDialog *filedialog;
+ bool renaming;
+ TQTimer* renameTimer;
+ TQListBoxItem *renameItem, *dragItem;
+ TQPoint pressPos, oldDragPos;
+ bool mousePressed;
+ int urls;
+ TQString startDragDir;
+ TQListBoxItem *currDropItem;
+ TQTimer *changeDirTimer;
+ bool firstMousePressEvent;
+ TQUrlOperator startDragUrl;
+
+};
+
+
+class TQFileDialogTQFileListView : public TQListView
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQFileDialogTQFileListView( TQWidget *tqparent, TQFileDialog *d );
+
+ void clear();
+ void startRename( bool check = TRUE );
+ void setSorting( int column, bool increasing = TRUE );
+
+ TQRenameEdit *lined;
+ bool renaming;
+ TQListViewItem *renameItem;
+
+private:
+ void viewportMousePressEvent( TQMouseEvent *e );
+ void viewportMouseDoubleClickEvent( TQMouseEvent *e );
+ void keyPressEvent( TQKeyEvent *e );
+ void viewportMouseReleaseEvent( TQMouseEvent *e );
+ void viewportMouseMoveEvent( TQMouseEvent *e );
+#ifndef TQT_NO_DRAGANDDROP
+ void viewportDragEnterEvent( TQDragEnterEvent *e );
+ void viewportDragMoveEvent( TQDragMoveEvent *e );
+ void viewportDragLeaveEvent( TQDragLeaveEvent *e );
+ void viewportDropEvent( TQDropEvent *e );
+ bool acceptDrop( const TQPoint &pnt, TQWidget *source );
+ void setCurrentDropItem( const TQPoint &pnt );
+#endif
+
+private Q_SLOTS:
+ void rename();
+ void cancelRename();
+ void changeSortColumn2( int column );
+ void doubleClickTimeout();
+ void changeDirDuringDrag();
+ void dragObjDestroyed();
+ void contentsMoved( int, int );
+
+private:
+ TQFileDialog *filedialog;
+ TQTimer* renameTimer;
+ TQPoint pressPos, oldDragPos;
+ bool mousePressed;
+ int urls;
+ TQString startDragDir;
+ TQListViewItem *currDropItem, *dragItem;
+ TQTimer *changeDirTimer;
+ bool firstMousePressEvent;
+ bool ascending;
+ int sortcolumn;
+ TQUrlOperator startDragUrl;
+
+};
+
+/****************************************************************************
+ *
+ * Classes for copy progress dialog
+ *
+ ****************************************************************************/
+
+class TQFDProgressAnimation : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQFDProgressAnimation( TQWidget *tqparent );
+ void start();
+
+private Q_SLOTS:
+ void next();
+
+protected:
+ void paintEvent( TQPaintEvent *e );
+
+private:
+ int step;
+ TQTimer *timer;
+
+};
+
+TQFDProgressAnimation::TQFDProgressAnimation( TQWidget *tqparent )
+ : TQWidget( tqparent, "qt_progressanimation" )
+{
+ setFixedSize( 300, 50 );
+ step = -1;
+ next();
+ timer = new TQTimer( this );
+ connect( timer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( next() ) );
+}
+
+void TQFDProgressAnimation::start()
+{
+ timer->start( 150, FALSE );
+}
+
+void TQFDProgressAnimation::next()
+{
+ ++step;
+ if ( step > 10 )
+ step = 0;
+ tqrepaint();
+}
+
+void TQFDProgressAnimation::paintEvent( TQPaintEvent * )
+{
+ erase();
+
+ TQPainter p;
+ p.begin( this );
+ if ( step == 0 ) {
+ p.drawPixmap( 5, ( height() - startCopyIcon->height() ) / 2,
+ *startCopyIcon );
+ p.drawPixmap( width() - 5 - openFolderIcon->width(),
+ ( height() - openFolderIcon->height() ) / 2 , *openFolderIcon );
+ } else if ( step == 10 ) {
+ p.drawPixmap( 5, ( height() - openFolderIcon->height() ) / 2,
+ *openFolderIcon );
+ p.drawPixmap( width() - 5 - endCopyIcon->width(),
+ ( height() - endCopyIcon->height() ) / 2 , *endCopyIcon );
+ } else {
+ p.drawPixmap( 5, ( height() - openFolderIcon->height() ) / 2,
+ *openFolderIcon );
+ p.drawPixmap( width() - 5 - openFolderIcon->width(),
+ ( height() - openFolderIcon->height() ) / 2 , *openFolderIcon );
+ int x = 10 + openFolderIcon->width();
+ int w = width() - 2 * x;
+ int s = w / 9;
+ p.drawPixmap( x + s * step, ( height() - fileIcon->height() ) / 2 - fileIcon->height(),
+ *fileIcon );
+ }
+}
+
+
+class TQFDProgressDialog : public TQDialog
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQFDProgressDialog( TQWidget *tqparent, const TQString &fn, int steps );
+
+ void setReadProgress( int p );
+ void setWriteProgress( int p );
+ void setWriteLabel( const TQString &s );
+
+Q_SIGNALS:
+ void cancelled();
+
+private:
+ TQProgressBar *readBar;
+ TQProgressBar *writeBar;
+ TQLabel *writeLabel;
+ TQFDProgressAnimation *animation;
+
+};
+
+TQFDProgressDialog::TQFDProgressDialog( TQWidget *tqparent, const TQString &fn, int steps )
+ : TQDialog( tqparent, "", TRUE )
+{
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ setCaption( TQFileDialog::tr( "Copy or Move a File" ) );
+#endif
+ TQVBoxLayout *tqlayout = new TQVBoxLayout( this );
+ tqlayout->setSpacing( 5 );
+ tqlayout->setMargin( 5 );
+
+ animation = new TQFDProgressAnimation( this );
+ tqlayout->addWidget( animation );
+
+ tqlayout->addWidget( new TQLabel( TQFileDialog::tr( "Read: %1" ).arg( fn ),
+ this, "qt_read_lbl" ) );
+ readBar = new TQProgressBar( steps, this, "qt_readbar" );
+ readBar->reset();
+ readBar->setProgress( 0 );
+ tqlayout->addWidget( readBar );
+ writeLabel = new TQLabel( TQFileDialog::tr( "Write: %1" ).arg( TQString() ),
+ this, "qt_write_lbl" );
+ tqlayout->addWidget( writeLabel );
+ writeBar = new TQProgressBar( steps, this, "qt_writebar" );
+ writeBar->reset();
+ writeBar->setProgress( 0 );
+ tqlayout->addWidget( writeBar );
+
+ TQPushButton *b = new TQPushButton( TQFileDialog::tr( "Cancel" ), this,
+ "qt_cancel_btn" );
+ b->setFixedSize( b->tqsizeHint() );
+ tqlayout->addWidget( b );
+ connect( b, TQT_SIGNAL( clicked() ),
+ this, TQT_SIGNAL( cancelled() ) );
+
+ animation->start();
+}
+
+void TQFDProgressDialog::setReadProgress( int p )
+{
+ readBar->setProgress( p );
+}
+
+void TQFDProgressDialog::setWriteProgress( int p )
+{
+ writeBar->setProgress( p );
+}
+
+void TQFDProgressDialog::setWriteLabel( const TQString &s )
+{
+ writeLabel->setText( TQFileDialog::tr( "Write: %1" ).arg( s ) );
+}
+
+/************************************************************************
+ *
+ * Private TQFileDialog members
+ *
+ ************************************************************************/
+
+class TQFileDialogPrivate {
+public:
+ ~TQFileDialogPrivate();
+
+ TQStringList history;
+
+ bool tqgeometryDirty;
+ TQComboBox * paths;
+ TQComboBox * types;
+ TQLabel * pathL;
+ TQLabel * fileL;
+ TQLabel * typeL;
+
+ TQVBoxLayout * topLevelLayout;
+ TQHBoxLayout *buttonLayout, *leftLayout, *rightLayout;
+ TQPtrList<TQHBoxLayout> extraWidgetsLayouts;
+ TQPtrList<TQLabel> extraLabels;
+ TQPtrList<TQWidget> extraWidgets;
+ TQPtrList<TQWidget> extraButtons;
+ TQPtrList<TQButton> toolButtons;
+
+ TQWidgetStack * stack;
+
+ TQToolButton * cdToParent, *newFolder, * detailView, * mcView,
+ *previewInfo, *previewContents, *goBack;
+ TQButtonGroup * modeButtons;
+
+ TQString currentFileName;
+ TQListViewItem *last;
+
+ TQListBoxItem *lastEFSelected;
+
+ struct File: public TQListViewItem {
+ File( TQFileDialogPrivate * dlgp,
+ const TQUrlInfo * fi, TQListViewItem * tqparent )
+ : TQListViewItem( tqparent, dlgp->last ), info( *fi ), d(dlgp), i( 0 ), hasMimePixmap( FALSE )
+ { setup(); dlgp->last = this; }
+ File( TQFileDialogPrivate * dlgp,
+ const TQUrlInfo * fi, TQListView * tqparent )
+ : TQListViewItem( tqparent, dlgp->last ), info( *fi ), d(dlgp), i( 0 ), hasMimePixmap( FALSE )
+ { setup(); dlgp->last = this; }
+ File( TQFileDialogPrivate * dlgp,
+ const TQUrlInfo * fi, TQListView * tqparent, TQListViewItem * after )
+ : TQListViewItem( tqparent, after ), info( *fi ), d(dlgp), i( 0 ), hasMimePixmap( FALSE )
+ { setup(); if ( !nextSibling() ) dlgp->last = this; }
+ ~File();
+
+ TQString text( int column ) const;
+ const TQPixmap * pixmap( int ) const;
+
+ TQUrlInfo info;
+ TQFileDialogPrivate * d;
+ TQListBoxItem *i;
+ bool hasMimePixmap;
+ };
+
+ class MCItem: public TQListBoxItem {
+ public:
+ MCItem( TQListBox *, TQListViewItem * item );
+ MCItem( TQListBox *, TQListViewItem * item, TQListBoxItem *after );
+ TQString text() const;
+ const TQPixmap *pixmap() const;
+ int height( const TQListBox * ) const;
+ int width( const TQListBox * ) const;
+ void paint( TQPainter * );
+ TQListViewItem * i;
+ };
+
+ class UrlInfoList : public TQPtrList<TQUrlInfo> {
+ public:
+ UrlInfoList() { setAutoDelete( TRUE ); }
+ int compareItems( TQPtrCollection::Item n1, TQPtrCollection::Item n2 ) {
+ if ( !n1 || !n2 )
+ return 0;
+
+ TQUrlInfo *i1 = ( TQUrlInfo *)n1;
+ TQUrlInfo *i2 = ( TQUrlInfo *)n2;
+
+ if ( i1->isDir() && !i2->isDir() )
+ return -1;
+ if ( !i1->isDir() && i2->isDir() )
+ return 1;
+
+ if ( i1->name() == ".." )
+ return -1;
+ if ( i2->name() == ".." )
+ return 1;
+
+ if ( sortFilesBy == TQDir::Name ) {
+#if defined(TQ_OS_WIN32)
+ TQString name1 = i1->name().lower();
+ TQString name2 = i2->name().lower();
+ return name1.localeAwareCompare( name2 );
+#else
+ TQString name1 = i1->name();
+ TQString name2 = i2->name();
+ return name1.localeAwareCompare( name2 );
+#endif
+ }
+ if ( TQUrlInfo::equal( *i1, *i2, sortFilesBy ) )
+ return 0;
+ else if ( TQUrlInfo::greaterThan( *i1, *i2, sortFilesBy ) )
+ return 1;
+ else if ( TQUrlInfo::lessThan( *i1, *i2, sortFilesBy ) )
+ return -1;
+ // can't happen...
+ return 0;
+ }
+ TQUrlInfo *operator[]( int i ) {
+ return at( i );
+ }
+ };
+
+ UrlInfoList sortedList;
+ TQPtrList<File> pendingItems;
+
+ TQFileListBox * moreFiles;
+
+ TQFileDialog::Mode mode;
+
+ TQString rw;
+ TQString ro;
+ TQString wo;
+ TQString inaccessible;
+
+ TQString symLinkToFile;
+ TQString file;
+ TQString symLinkToDir;
+ TQString dir;
+ TQString symLinkToSpecial;
+ TQString special;
+ TQWidgetStack *preview;
+ bool infoPreview, contentsPreview;
+ TQSplitter *splitter;
+ TQUrlOperator url, oldUrl;
+ TQWidget *infoPreviewWidget, *contentsPreviewWidget;
+ TQFilePreview *infoPreviewer, *contentsPreviewer;
+ bool hadDotDot;
+
+ bool ignoreNextKeyPress;
+ // ignores the next refresh operation in case the user forced a selection
+ bool ignoreNextRefresh;
+ TQFDProgressDialog *progressDia;
+ bool checkForFilter;
+ bool ignoreStop;
+
+ TQTimer *mimeTypeTimer;
+ const TQNetworkOperation *currListChildren;
+
+ // this is similar to TQUrl::encode but does encode "*" and
+ // doesn't encode whitespaces
+ static TQString encodeFileName( const TQString& fName ) {
+
+ TQString newStr;
+ TQCString cName = fName.utf8();
+ const TQCString sChars(
+#ifdef TQ_WS_WIN
+ "#%"
+#else
+ "<>#@\"&%$:,;?={}|^~[]\'`\\*"
+#endif
+ );
+
+ int len = cName.length();
+ if ( !len )
+ return TQString::null;
+ for ( int i = 0; i < len ;++i ) {
+ uchar inCh = (uchar)cName[ i ];
+ if ( inCh >= 128 || sChars.tqcontains(inCh) )
+ {
+ newStr += TQChar( '%' );
+ ushort c = inCh / 16;
+ c += c > 9 ? 'A' - 10 : '0';
+ newStr += (char)c;
+ c = inCh % 16;
+ c += c > 9 ? 'A' - 10 : '0';
+ newStr += (char)c;
+ } else {
+ newStr += (char)inCh;
+ }
+ }
+ return newStr;
+ }
+
+ static bool fileExists( const TQUrlOperator &url, const TQString& name )
+ {
+ TQUrl u( url, TQFileDialogPrivate::encodeFileName(name) );
+ if ( u.isLocalFile() ) {
+ TQFileInfo f( u.path() );
+ return f.exists();
+ } else {
+ TQNetworkProtocol *p = TQNetworkProtocol::getNetworkProtocol( url.protocol() );
+ if ( p && (p->supportedOperations()&TQNetworkProtocol::OpListChildren) ) {
+ TQUrlInfo ui( url, name );
+ return ui.isValid();
+ }
+ }
+ return TRUE;
+ }
+
+#ifndef TQ_NO_CURSOR
+ bool cursorOverride; // Remember if the cursor was overridden or not.
+#endif
+#ifdef TQ_WS_WIN
+ int oldPermissionLookup;
+#endif
+};
+
+TQFileDialogPrivate::~TQFileDialogPrivate()
+{
+ delete modeButtons;
+}
+
+
+
+/************************************************************************
+ *
+ * Internal class TQRenameEdit
+ *
+ ************************************************************************/
+
+void TQRenameEdit::keyPressEvent( TQKeyEvent *e )
+{
+ if ( e->key() == Key_Escape )
+ emit cancelRename();
+ else
+ TQLineEdit::keyPressEvent( e );
+ e->accept();
+}
+
+void TQRenameEdit::focusOutEvent( TQFocusEvent * )
+{
+ if ( !doRenameAlreadyEmitted )
+ emit doRename();
+ else
+ doRenameAlreadyEmitted = FALSE;
+}
+
+void TQRenameEdit::slotReturnPressed()
+{
+ doRenameAlreadyEmitted = TRUE;
+ emit doRename();
+}
+
+/************************************************************************
+ *
+ * Internal class TQFileListBox
+ *
+ ************************************************************************/
+
+TQFileListBox::TQFileListBox( TQWidget *tqparent, TQFileDialog *dlg )
+ : TQListBox( tqparent, "filelistbox" ), filedialog( dlg ),
+ renaming( FALSE ), renameItem( 0 ), mousePressed( FALSE ),
+ firstMousePressEvent( TRUE )
+{
+ changeDirTimer = new TQTimer( this );
+ TQVBox *box = new TQVBox( viewport(), "qt_vbox" );
+ box->setFrameStyle( TQFrame::Box | TQFrame::Plain );
+ lined = new TQRenameEdit( box );
+ lined->setFixedHeight( lined->tqsizeHint().height() );
+ box->hide();
+ box->setBackgroundMode( TQt::PaletteBase );
+ renameTimer = new TQTimer( this );
+ connect( lined, TQT_SIGNAL( doRename() ),
+ this, TQT_SLOT (rename() ) );
+ connect( lined, TQT_SIGNAL( cancelRename() ),
+ this, TQT_SLOT( cancelRename() ) );
+ connect( renameTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( doubleClickTimeout() ) );
+ connect( changeDirTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( changeDirDuringDrag() ) );
+ connect( this, TQT_SIGNAL( contentsMoving(int,int) ),
+ this, TQT_SLOT( contentsMoved(int,int) ) );
+ viewport()->setAcceptDrops( TRUE );
+ dragItem = 0;
+}
+
+void TQFileListBox::show()
+{
+ setBackgroundMode( TQt::PaletteBase );
+ viewport()->setBackgroundMode( TQt::PaletteBase );
+ TQListBox::show();
+}
+
+void TQFileListBox::keyPressEvent( TQKeyEvent *e )
+{
+ if ( ( e->key() == Qt::Key_Enter ||
+ e->key() == Qt::Key_Return ) &&
+ renaming )
+ return;
+
+ TQString keyPressed = TQT_TQSTRING(((TQKeyEvent *)e)->text()).lower();
+ TQChar keyChar = keyPressed[0];
+ bool handled = false;
+ if ( keyChar.isLetterOrNumber() ) {
+ TQListBoxItem * i = 0;
+ if ( currentItem() )
+ i = item( currentItem() );
+ else
+ i = firstItem();
+ if ( i->next() )
+ i = i->next();
+ else
+ i = firstItem();
+ while ( i != item( currentItem() ) ) {
+ TQString it = text( index( i ) );
+ if ( it[0].lower() == keyChar ) {
+ clearSelection();
+ setCurrentItem( i );
+ handled = true;
+ e->accept();
+ } else {
+ if ( i->next() )
+ i = i->next();
+ else
+ i = firstItem();
+ }
+ }
+ }
+ cancelRename();
+ if (!handled){
+ TQListBox::keyPressEvent( e );
+ }
+}
+
+void TQFileListBox::viewportMousePressEvent( TQMouseEvent *e )
+{
+ pressPos = e->pos();
+ mousePressed = FALSE;
+
+ bool didRename = renaming;
+
+ cancelRename();
+ if ( !hasFocus() && !viewport()->hasFocus() )
+ setFocus();
+
+ if ( e->button() != Qt::LeftButton ) {
+ TQListBox::viewportMousePressEvent( e );
+ firstMousePressEvent = FALSE;
+ return;
+ }
+
+ int i = currentItem();
+ bool wasSelected = FALSE;
+ if ( i != -1 )
+ wasSelected = item( i )->isSelected();
+ TQListBox::mousePressEvent( e );
+
+ TQFileDialogPrivate::MCItem *i1 = (TQFileDialogPrivate::MCItem*)item( currentItem() );
+ if ( i1 )
+ mousePressed = ( !( (TQFileDialogPrivate::File*)i1->i )->info.isDir() )
+ || ( filedialog->mode() == TQFileDialog::Directory ) || ( filedialog->mode() == TQFileDialog::DirectoryOnly );
+
+ if ( itemAt( e->pos() ) != item( i ) ) {
+ firstMousePressEvent = FALSE;
+ return;
+ }
+
+ if ( !firstMousePressEvent && !didRename && i == currentItem() && currentItem() != -1 &&
+ wasSelected && TQUrlInfo( filedialog->d->url, "." ).isWritable() && item( currentItem() )->text() != ".." ) {
+ renameTimer->start( TQApplication::doubleClickInterval(), TRUE );
+ renameItem = item( i );
+ }
+
+ firstMousePressEvent = FALSE;
+}
+
+void TQFileListBox::viewportMouseReleaseEvent( TQMouseEvent *e )
+{
+ dragItem = 0;
+ TQListBox::viewportMouseReleaseEvent( e );
+ mousePressed = FALSE;
+}
+
+void TQFileListBox::viewportMouseDoubleClickEvent( TQMouseEvent *e )
+{
+ renameTimer->stop();
+ TQListBox::viewportMouseDoubleClickEvent( e );
+}
+
+void TQFileListBox::viewportMouseMoveEvent( TQMouseEvent *e )
+{
+ if ( !dragItem )
+ dragItem = itemAt( e->pos() );
+ renameTimer->stop();
+#ifndef TQT_NO_DRAGANDDROP
+ if ( ( pressPos - e->pos() ).manhattanLength() > TQApplication::startDragDistance() && mousePressed ) {
+ TQListBoxItem *item = dragItem;
+ dragItem = 0;
+ if ( item ) {
+ if ( !tqitemRect( item ).tqcontains( e->pos() ) )
+ return;
+ TQUriDrag* drag = new TQUriDrag( viewport() );
+ TQStringList files;
+ if ( filedialog->mode() == TQFileDialog::ExistingFiles )
+ files = filedialog->selectedFiles();
+ else
+ files = filedialog->selectedFile();
+ drag->setFileNames( files );
+
+ if ( lined->parentWidget()->isVisible() )
+ cancelRename();
+
+ connect( drag, TQT_SIGNAL( destroyed() ),
+ this, TQT_SLOT( dragObjDestroyed() ) );
+ drag->drag();
+
+ mousePressed = FALSE;
+ }
+ } else
+#endif
+ {
+ TQListBox::viewportMouseMoveEvent( e );
+ }
+
+}
+
+void TQFileListBox::dragObjDestroyed()
+{
+#ifndef TQT_NO_DRAGANDDROP
+ //#######
+ //filedialog->rereadDir();
+#endif
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQFileListBox::viewportDragEnterEvent( TQDragEnterEvent *e )
+{
+ startDragUrl = filedialog->d->url;
+ startDragDir = filedialog->dirPath();
+ currDropItem = 0;
+
+ if ( !TQUriDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+
+ TQStringList l;
+ TQUriDrag::decodeLocalFiles( e, l );
+ urls = (int)l.count();
+
+ if ( acceptDrop( e->pos(), e->source() ) ) {
+ e->accept();
+ setCurrentDropItem( e->pos() );
+ } else {
+ e->ignore();
+ setCurrentDropItem( TQPoint( -1, -1 ) );
+ }
+
+ oldDragPos = e->pos();
+}
+
+void TQFileListBox::viewportDragMoveEvent( TQDragMoveEvent *e )
+{
+ if ( acceptDrop( e->pos(), e->source() ) ) {
+ switch ( e->action() ) {
+ case TQDropEvent::Copy:
+ e->acceptAction();
+ break;
+ case TQDropEvent::Move:
+ e->acceptAction();
+ break;
+ case TQDropEvent::Link:
+ break;
+ default:
+ break;
+ }
+ if ( oldDragPos != e->pos() )
+ setCurrentDropItem( e->pos() );
+ } else {
+ changeDirTimer->stop();
+ e->ignore();
+ setCurrentDropItem( TQPoint( -1, -1 ) );
+ }
+
+ oldDragPos = e->pos();
+}
+
+void TQFileListBox::viewportDragLeaveEvent( TQDragLeaveEvent * )
+{
+ changeDirTimer->stop();
+ setCurrentDropItem( TQPoint( -1, -1 ) );
+//########
+// if ( startDragDir != filedialog->d->url )
+// filedialog->setUrl( startDragUrl );
+}
+
+void TQFileListBox::viewportDropEvent( TQDropEvent *e )
+{
+ changeDirTimer->stop();
+
+ if ( !TQUriDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+
+ uint i;
+ TQStrList l;
+ TQUriDrag::decode( e, l );
+
+ bool move = e->action() == TQDropEvent::Move;
+// bool supportAction = move || e->action() == TQDropEvent::Copy;
+
+ TQUrlOperator dest;
+ if ( currDropItem )
+ dest = TQUrlOperator( filedialog->d->url, TQFileDialogPrivate::encodeFileName( currDropItem->text() ) );
+ else
+ dest = filedialog->d->url;
+ TQStringList lst;
+ for ( i = 0; i < l.count(); ++i ) {
+ lst << l.at( i );
+ }
+
+ // make sure that we can write to the destination before performing the action
+ bool exists = false;
+ TQString name = (currDropItem ? TQFileDialogPrivate::encodeFileName(currDropItem->text()) : TQString("."));
+ TQUrlInfo info(filedialog->d->url, name);
+ for ( i = 0; i < lst.count(); ++i ) {
+ int slash = lst[i].tqfindRev('/');
+ TQString filename = lst[i].right(lst[i].length() - slash - 1);
+ exists = exists || TQFileDialogPrivate::fileExists( dest, filename);
+ }
+ if (info.isWritable() && !exists)
+ filedialog->d->url.copy( lst, dest, move );
+
+ // ##### what is supportAction for?
+ e->acceptAction();
+ currDropItem = 0;
+}
+
+bool TQFileListBox::acceptDrop( const TQPoint &pnt, TQWidget *source )
+{
+ TQListBoxItem *item = itemAt( pnt );
+ if ( !item || (item && !tqitemRect( item ).tqcontains( pnt )) ) {
+ if ( source == viewport() && startDragDir == filedialog->dirPath() )
+ return FALSE;
+ return TRUE;
+ }
+
+ TQUrlInfo fi( filedialog->d->url, item->text() );
+
+ if ( fi.isDir() && tqitemRect( item ).tqcontains( pnt ) )
+ return TRUE;
+ return FALSE;
+}
+
+void TQFileListBox::setCurrentDropItem( const TQPoint &pnt )
+{
+ changeDirTimer->stop();
+
+ TQListBoxItem *item = 0;
+ if ( pnt != TQPoint( -1, -1 ) )
+ item = itemAt( pnt );
+ if ( item && !TQUrlInfo( filedialog->d->url, item->text() ).isDir() )
+ item = 0;
+ if ( item && !tqitemRect( item ).tqcontains( pnt ) )
+ item = 0;
+
+ currDropItem = item;
+ if ( currDropItem )
+ setCurrentItem( currDropItem );
+ changeDirTimer->start( 750 );
+}
+#endif // TQT_NO_DRAGANDDROP
+
+void TQFileListBox::changeDirDuringDrag()
+{
+#ifndef TQT_NO_DRAGANDDROP
+ if ( !currDropItem )
+ return;
+ changeDirTimer->stop();
+ TQUrl u( filedialog->d->url, TQFileDialogPrivate::encodeFileName(currDropItem->text()) );
+ filedialog->setDir( u );
+ currDropItem = 0;
+#endif
+}
+
+void TQFileListBox::doubleClickTimeout()
+{
+ startRename();
+ renameTimer->stop();
+}
+
+void TQFileListBox::startRename( bool check )
+{
+ if ( check && ( !renameItem || renameItem != item( currentItem() ) ) )
+ return;
+
+ int i = currentItem();
+ setSelected( i, TRUE );
+ TQRect r = tqitemRect( item( i ) );
+ int bdr = item( i )->pixmap() ?
+ item( i )->pixmap()->width() : 16;
+ int x = r.x() + bdr;
+ int y = r.y();
+ int w = item( i )->width( this ) - bdr;
+ int h = TQMAX( lined->height() + 2, r.height() );
+ y = y + r.height() / 2 - h / 2;
+
+ lined->parentWidget()->setGeometry( x, y, w + 6, h );
+ lined->setFocus();
+ lined->setText( item( i )->text() );
+ lined->selectAll();
+ lined->setFrame( FALSE );
+ lined->parentWidget()->show();
+ viewport()->setFocusProxy( lined );
+ renaming = TRUE;
+}
+
+void TQFileListBox::clear()
+{
+ cancelRename();
+ TQListBox::clear();
+}
+
+void TQFileListBox::rename()
+{
+ if ( !lined->text().isEmpty() ) {
+ TQString file = currentText();
+
+ if ( lined->text() != file )
+ filedialog->d->url.rename( file, lined->text() );
+ }
+ cancelRename();
+}
+
+void TQFileListBox::cancelRename()
+{
+ renameItem = 0;
+ lined->parentWidget()->hide();
+ viewport()->setFocusProxy( this );
+ renaming = FALSE;
+ updateItem( currentItem() );
+ if ( lined->hasFocus() )
+ viewport()->setFocus();
+}
+
+void TQFileListBox::contentsMoved( int, int )
+{
+ changeDirTimer->stop();
+#ifndef TQT_NO_DRAGANDDROP
+ setCurrentDropItem( TQPoint( -1, -1 ) );
+#endif
+}
+
+/************************************************************************
+ *
+ * Internal class TQFileListView
+ *
+ ************************************************************************/
+
+TQFileDialogTQFileListView::TQFileDialogTQFileListView( TQWidget *tqparent, TQFileDialog *dlg )
+ : TQListView( tqparent, "qt_filedlg_listview" ), renaming( FALSE ), renameItem( 0 ),
+ filedialog( dlg ), mousePressed( FALSE ),
+ firstMousePressEvent( TRUE )
+{
+ changeDirTimer = new TQTimer( this );
+ TQVBox *box = new TQVBox( viewport(), "qt_vbox" );
+ box->setFrameStyle( TQFrame::Box | TQFrame::Plain );
+ lined = new TQRenameEdit( box );
+ lined->setFixedHeight( lined->tqsizeHint().height() );
+ box->hide();
+ box->setBackgroundMode( TQt::PaletteBase );
+ renameTimer = new TQTimer( this );
+ connect( lined, TQT_SIGNAL( doRename() ),
+ this, TQT_SLOT (rename() ) );
+ connect( lined, TQT_SIGNAL( cancelRename() ),
+ this, TQT_SLOT( cancelRename() ) );
+ header()->setMovingEnabled( FALSE );
+ connect( renameTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( doubleClickTimeout() ) );
+ connect( changeDirTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( changeDirDuringDrag() ) );
+ disconnect( header(), TQT_SIGNAL( sectionClicked(int) ),
+ this, TQT_SLOT( changeSortColumn(int) ) );
+ connect( header(), TQT_SIGNAL( sectionClicked(int) ),
+ this, TQT_SLOT( changeSortColumn2(int) ) );
+ connect( this, TQT_SIGNAL( contentsMoving(int,int) ),
+ this, TQT_SLOT( contentsMoved(int,int) ) );
+
+ viewport()->setAcceptDrops( TRUE );
+ sortcolumn = 0;
+ ascending = TRUE;
+ dragItem = 0;
+}
+
+void TQFileDialogTQFileListView::setSorting( int column, bool increasing )
+{
+ if ( column == -1 ) {
+ TQListView::setSorting( column, increasing );
+ return;
+ }
+
+ sortAscending = ascending = increasing;
+ sortcolumn = column;
+ switch ( column ) {
+ case 0:
+ sortFilesBy = TQDir::Name;
+ break;
+ case 1:
+ sortFilesBy = TQDir::Size;
+ break;
+ case 3:
+ sortFilesBy = TQDir::Time;
+ break;
+ default:
+ sortFilesBy = TQDir::Name; // #### ???
+ break;
+ }
+
+ filedialog->resortDir();
+}
+
+void TQFileDialogTQFileListView::changeSortColumn2( int column )
+{
+ int lcol = header()->mapToLogical( column );
+ setSorting( lcol, sortcolumn == lcol ? !ascending : TRUE );
+}
+
+void TQFileDialogTQFileListView::keyPressEvent( TQKeyEvent *e )
+{
+ if ( ( e->key() == Qt::Key_Enter ||
+ e->key() == Qt::Key_Return ) &&
+ renaming )
+ return;
+
+ TQString keyPressed = TQT_TQSTRING(e->text()).lower();
+ TQChar keyChar = keyPressed[0];
+ if ( keyChar.isLetterOrNumber() ) {
+ TQListViewItem * i = 0;
+ if ( currentItem() )
+ i = currentItem();
+ else
+ i = firstChild();
+ if ( i->nextSibling() )
+ i = i->nextSibling();
+ else
+ i = firstChild();
+ while ( i != currentItem() ) {
+ TQString it = i->text(0);
+ if ( it[0].lower() == keyChar ) {
+ clearSelection();
+ ensureItemVisible( i );
+ setCurrentItem( i );
+ } else {
+ if ( i->nextSibling() )
+ i = i->nextSibling();
+ else
+ i = firstChild();
+ }
+ }
+ return;
+ }
+
+ cancelRename();
+ TQListView::keyPressEvent( e );
+}
+
+void TQFileDialogTQFileListView::viewportMousePressEvent( TQMouseEvent *e )
+{
+ pressPos = e->pos();
+ mousePressed = FALSE;
+
+ bool didRename = renaming;
+ cancelRename();
+ if ( !hasFocus() && !viewport()->hasFocus() )
+ setFocus();
+
+ if ( e->button() != Qt::LeftButton ) {
+ TQListView::viewportMousePressEvent( e );
+ firstMousePressEvent = FALSE;
+ return;
+ }
+
+ TQListViewItem *i = currentItem();
+ TQListView::viewportMousePressEvent( e );
+
+ TQFileDialogPrivate::File *i1 = (TQFileDialogPrivate::File*)currentItem();
+ if ( i1 )
+ mousePressed = !i1->info.isDir() || ( filedialog->mode() == TQFileDialog::Directory ) || ( filedialog->mode() == TQFileDialog::DirectoryOnly );
+
+
+ if ( itemAt( e->pos() ) != i ||
+ e->x() + contentsX() > columnWidth( 0 ) ) {
+ firstMousePressEvent = FALSE;
+ return;
+ }
+
+ if ( !firstMousePressEvent && !didRename && i == currentItem() && currentItem() &&
+ TQUrlInfo( filedialog->d->url, "." ).isWritable() && currentItem()->text( 0 ) != ".." ) {
+ renameTimer->start( TQApplication::doubleClickInterval(), TRUE );
+ renameItem = currentItem();
+ }
+
+ firstMousePressEvent = FALSE;
+}
+
+void TQFileDialogTQFileListView::viewportMouseDoubleClickEvent( TQMouseEvent *e )
+{
+ renameTimer->stop();
+ TQListView::viewportMouseDoubleClickEvent( e );
+}
+
+void TQFileDialogTQFileListView::viewportMouseReleaseEvent( TQMouseEvent *e )
+{
+ TQListView::viewportMouseReleaseEvent( e );
+ mousePressed = FALSE;
+ dragItem = 0;
+}
+
+void TQFileDialogTQFileListView::viewportMouseMoveEvent( TQMouseEvent *e )
+{
+ renameTimer->stop();
+ if ( !dragItem )
+ dragItem = itemAt( e->pos() );
+#ifndef TQT_NO_DRAGANDDROP
+ if ( ( pressPos - e->pos() ).manhattanLength() > TQApplication::startDragDistance() && mousePressed ) {
+ TQListViewItem *item = dragItem;
+ dragItem = 0;
+ if ( item ) {
+ TQUriDrag* drag = new TQUriDrag( viewport() );
+ TQStringList files;
+ if ( filedialog->mode() == TQFileDialog::ExistingFiles )
+ files = filedialog->selectedFiles();
+ else
+ files = filedialog->selectedFile();
+ drag->setFileNames( files );
+
+ if ( lined->isVisible() )
+ cancelRename();
+
+ connect( drag, TQT_SIGNAL( destroyed() ),
+ this, TQT_SLOT( dragObjDestroyed() ) );
+ drag->drag();
+
+ mousePressed = FALSE;
+ }
+ }
+#endif
+}
+
+void TQFileDialogTQFileListView::dragObjDestroyed()
+{
+#ifndef TQT_NO_DRAGANDDROP
+ //######
+ //filedialog->rereadDir();
+#endif
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQFileDialogTQFileListView::viewportDragEnterEvent( TQDragEnterEvent *e )
+{
+ startDragUrl = filedialog->d->url;
+ startDragDir = filedialog->dirPath();
+ currDropItem = 0;
+
+ if ( !TQUriDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+
+ TQStringList l;
+ TQUriDrag::decodeLocalFiles( e, l );
+ urls = (int)l.count();
+
+ if ( acceptDrop( e->pos(), e->source() ) ) {
+ e->accept();
+ setCurrentDropItem( e->pos() );
+ } else {
+ e->ignore();
+ setCurrentDropItem( TQPoint( -1, -1 ) );
+ }
+
+ oldDragPos = e->pos();
+}
+
+void TQFileDialogTQFileListView::viewportDragMoveEvent( TQDragMoveEvent *e )
+{
+ if ( acceptDrop( e->pos(), e->source() ) ) {
+ if ( oldDragPos != e->pos() )
+ setCurrentDropItem( e->pos() );
+ switch ( e->action() ) {
+ case TQDropEvent::Copy:
+ e->acceptAction();
+ break;
+ case TQDropEvent::Move:
+ e->acceptAction();
+ break;
+ case TQDropEvent::Link:
+ break;
+ default:
+ break;
+ }
+ } else {
+ changeDirTimer->stop();
+ e->ignore();
+ setCurrentDropItem( TQPoint( -1, -1 ) );
+ }
+
+ oldDragPos = e->pos();
+}
+
+void TQFileDialogTQFileListView::viewportDragLeaveEvent( TQDragLeaveEvent * )
+{
+ changeDirTimer->stop();
+ setCurrentDropItem( TQPoint( -1, -1 ) );
+//########
+// if ( startDragDir != filedialog->d->url )
+// filedialog->setUrl( startDragUrl );
+}
+
+void TQFileDialogTQFileListView::viewportDropEvent( TQDropEvent *e )
+{
+ changeDirTimer->stop();
+
+ if ( !TQUriDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+
+ TQStringList l;
+ TQUriDrag::decodeToUnicodeUris( e, l );
+
+ bool move = e->action() == TQDropEvent::Move;
+// bool supportAction = move || e->action() == TQDropEvent::Copy;
+
+ TQUrlOperator dest;
+ if ( currDropItem )
+ dest = TQUrlOperator( filedialog->d->url, TQFileDialogPrivate::encodeFileName( currDropItem->text( 0 ) ) );
+ else
+ dest = filedialog->d->url;
+
+ // make sure that we can write to the destination before performing the action
+ bool exists = false;
+ TQString name = (currDropItem ? TQFileDialogPrivate::encodeFileName(currDropItem->text(0)) : TQString("."));
+ TQUrlInfo info(filedialog->d->url, name);
+ for (uint i = 0; i < l.count(); ++i) {
+ int slash = l[i].tqfindRev('/');
+ TQString filename = l[i].right(l[i].length() - slash - 1);
+ exists = exists || TQFileDialogPrivate::fileExists(dest, filename);
+ }
+ if (info.isWritable() && !exists)
+ filedialog->d->url.copy( l, dest, move );
+
+ // ##### what is supportAction for?
+ e->acceptAction();
+ currDropItem = 0;
+}
+
+bool TQFileDialogTQFileListView::acceptDrop( const TQPoint &pnt, TQWidget *source )
+{
+ TQListViewItem *item = itemAt( pnt );
+ if ( !item || (item && !tqitemRect( item ).tqcontains( pnt )) ) {
+ if ( source == viewport() && startDragDir == filedialog->dirPath() )
+ return FALSE;
+ return TRUE;
+ }
+
+ TQUrlInfo fi( filedialog->d->url, item->text( 0 ) );
+
+ if ( fi.isDir() && tqitemRect( item ).tqcontains( pnt ) )
+ return TRUE;
+ return FALSE;
+}
+
+void TQFileDialogTQFileListView::setCurrentDropItem( const TQPoint &pnt )
+{
+ changeDirTimer->stop();
+
+ TQListViewItem *item = itemAt( pnt );
+ if ( pnt == TQPoint( -1, -1 ) )
+ item = 0;
+ if ( item && !TQUrlInfo( filedialog->d->url, item->text( 0 ) ).isDir() )
+ item = 0;
+
+ if ( item && !tqitemRect( item ).tqcontains( pnt ) )
+ item = 0;
+
+ currDropItem = item;
+
+ if ( currDropItem )
+ setCurrentItem( currDropItem );
+
+ changeDirTimer->start( 750 );
+}
+#endif // TQT_NO_DRAGANDDROP
+
+void TQFileDialogTQFileListView::changeDirDuringDrag()
+{
+#ifndef TQT_NO_DRAGANDDROP
+ if ( !currDropItem )
+ return;
+ changeDirTimer->stop();
+ TQUrl u( filedialog->d->url, TQFileDialogPrivate::encodeFileName(currDropItem->text( 0 ) ) );
+ filedialog->setDir( u );
+ currDropItem = 0;
+#endif // TQT_NO_DRAGANDDROP
+}
+
+
+void TQFileDialogTQFileListView::doubleClickTimeout()
+{
+ startRename();
+ renameTimer->stop();
+}
+
+void TQFileDialogTQFileListView::startRename( bool check )
+{
+ if ( check && ( !renameItem || renameItem != currentItem() ) )
+ return;
+
+ TQListViewItem *i = currentItem();
+ setSelected( i, TRUE );
+
+ TQRect r = tqitemRect( i );
+ int bdr = i->pixmap( 0 ) ?
+ i->pixmap( 0 )->width() : 16;
+ int x = r.x() + bdr;
+ int y = r.y();
+ int w = columnWidth( 0 ) - bdr;
+ int h = TQMAX( lined->height() + 2, r.height() );
+ y = y + r.height() / 2 - h / 2;
+
+ lined->parentWidget()->setGeometry( x, y, w + 6, h );
+ lined->setFocus();
+ lined->setText( i->text( 0 ) );
+ lined->selectAll();
+ lined->setFrame( FALSE );
+ lined->parentWidget()->show();
+ viewport()->setFocusProxy( lined );
+ renaming = TRUE;
+}
+
+void TQFileDialogTQFileListView::clear()
+{
+ cancelRename();
+ TQListView::clear();
+}
+
+void TQFileDialogTQFileListView::rename()
+{
+ if ( !lined->text().isEmpty() ) {
+ TQString file = currentItem()->text( 0 );
+
+ if ( lined->text() != file )
+ filedialog->d->url.rename( file, lined->text() );
+ }
+ cancelRename();
+}
+
+void TQFileDialogTQFileListView::cancelRename()
+{
+ renameItem = 0;
+ lined->parentWidget()->hide();
+ viewport()->setFocusProxy( this );
+ renaming = FALSE;
+ if ( currentItem() )
+ currentItem()->tqrepaint();
+ if ( lined->hasFocus() )
+ viewport()->setFocus();
+}
+
+void TQFileDialogTQFileListView::contentsMoved( int, int )
+{
+ changeDirTimer->stop();
+#ifndef TQT_NO_DRAGANDDROP
+ setCurrentDropItem( TQPoint( -1, -1 ) );
+#endif
+}
+
+
+TQFileDialogPrivate::File::~File()
+{
+ if ( d->pendingItems.tqfindRef( this ) )
+ d->pendingItems.removeRef( this );
+}
+
+TQString TQFileDialogPrivate::File::text( int column ) const
+{
+ makeVariables();
+
+ switch( column ) {
+ case 0:
+ return info.name();
+ case 1:
+ if ( info.isFile() ) {
+#if (TQT_VERSION-0 >= 0x040000)
+#error "clean up Large File Support"
+#elif defined(TQT_ABI_QT4)
+ TQIODevice::Offset size = info.size();
+#else
+ uint size = info.size();
+#endif
+#if defined(TQT_LARGEFILE_SUPPORT) && defined(TQ_OS_UNIX)
+ // ### the following code should not be needed as soon
+ // ### as TQUrlInfo::size() can return 64-bit
+ if ( size > INT_MAX ) {
+ struct stat buffer;
+ if ( ::stat( TQFile::encodeName(info.name()), &buffer ) == 0 ) {
+ TQ_ULLONG size64 = (TQ_ULLONG)buffer.st_size;
+ return TQString::number(size64);
+ }
+ }
+#endif
+ return TQString::number(size);
+ } else {
+ return TQString::tqfromLatin1("");
+ }
+ case 2:
+ if ( info.isFile() && info.isSymLink() ) {
+ return d->symLinkToFile;
+ } else if ( info.isFile() ) {
+ return d->file;
+ } else if ( info.isDir() && info.isSymLink() ) {
+ return d->symLinkToDir;
+ } else if ( info.isDir() ) {
+ return d->dir;
+ } else if ( info.isSymLink() ) {
+ return d->symLinkToSpecial;
+ } else {
+ return d->special;
+ }
+ case 3: {
+ return info.lastModified().toString( Qt::LocalDate );
+ }
+ case 4:
+ if ( info.isReadable() )
+ return info.isWritable() ? d->rw : d->ro;
+ else
+ return info.isWritable() ? d->wo : d->inaccessible;
+ }
+
+ return TQString::tqfromLatin1("<--->");
+}
+
+const TQPixmap * TQFileDialogPrivate::File::pixmap( int column ) const
+{
+ if ( column ) {
+ return 0;
+ } else if ( TQListViewItem::pixmap( column ) ) {
+ return TQListViewItem::pixmap( column );
+ } else if ( info.isSymLink() ) {
+ if ( info.isFile() )
+ return symLinkFileIcon;
+ else
+ return symLinkDirIcon;
+ } else if ( info.isDir() ) {
+ return closedFolderIcon;
+ } else if ( info.isFile() ) {
+ return fileIcon;
+ } else {
+ return fifteenTransparentPixels;
+ }
+}
+
+TQFileDialogPrivate::MCItem::MCItem( TQListBox * lb, TQListViewItem * item )
+ : TQListBoxItem()
+{
+ i = item;
+ if ( lb )
+ lb->insertItem( this );
+}
+
+TQFileDialogPrivate::MCItem::MCItem( TQListBox * lb, TQListViewItem * item, TQListBoxItem *after )
+ : TQListBoxItem()
+{
+ i = item;
+ if ( lb )
+ lb->insertItem( this, after );
+}
+
+TQString TQFileDialogPrivate::MCItem::text() const
+{
+ return i->text( 0 );
+}
+
+
+const TQPixmap *TQFileDialogPrivate::MCItem::pixmap() const
+{
+ return i->pixmap( 0 );
+}
+
+
+int TQFileDialogPrivate::MCItem::height( const TQListBox * lb ) const
+{
+ int hf = lb->fontMetrics().height();
+ int hp = pixmap() ? pixmap()->height() : 0;
+ return TQMAX(hf, hp) + 2;
+}
+
+
+int TQFileDialogPrivate::MCItem::width( const TQListBox * lb ) const
+{
+ TQFontMetrics fm = lb->fontMetrics();
+ int w = 2;
+ if ( pixmap() )
+ w += pixmap()->width() + 4;
+ else
+ w += 18;
+ w += fm.width( text() );
+ w += -fm.minLeftBearing();
+ w += -fm.minRightBearing();
+ w += 6;
+ return w;
+}
+
+
+void TQFileDialogPrivate::MCItem::paint( TQPainter * ptr )
+{
+ TQFontMetrics fm = ptr->fontMetrics();
+
+ int h;
+
+ if ( pixmap() )
+ h = TQMAX( fm.height(), pixmap()->height()) + 2;
+ else
+ h = fm.height() + 2;
+
+ const TQPixmap * pm = pixmap();
+ if ( pm )
+ ptr->drawPixmap( 2, 1, *pm );
+
+ ptr->drawText( pm ? pm->width() + 4 : 22, h - fm.descent() - 2,
+ text() );
+}
+
+static TQStringList makeFiltersList( const TQString &filter )
+{
+ if ( filter.isEmpty() )
+ return TQStringList();
+
+ int i = filter.tqfind( ";;", 0 );
+ TQString sep( ";;" );
+ if ( i == -1 ) {
+ if ( filter.tqfind( "\n", 0 ) != -1 ) {
+ sep = "\n";
+ i = filter.tqfind( sep, 0 );
+ }
+ }
+
+ return TQStringList::split( sep, filter );
+}
+
+/*!
+ \class TQFileDialog tqfiledialog.h
+ \brief The TQFileDialog class provides dialogs that allow users to select files or directories.
+ \ingroup dialogs
+ \mainclass
+
+ The TQFileDialog class enables a user to traverse their file system in
+ order to select one or many files or a directory.
+
+ The easiest way to create a TQFileDialog is to use the static
+ functions. On Windows, these static functions will call the native
+ Windows file dialog and on Mac OS X, these static function will call
+ the native Mac OS X file dialog.
+
+ \code
+ TQString s = TQFileDialog::getOpenFileName(
+ "/home",
+ "Images (*.png *.xpm *.jpg)",
+ this,
+ "open file dialog",
+ "Choose a file" );
+ \endcode
+
+ In the above example, a modal TQFileDialog is created using a static
+ function. The startup directory is set to "/home". The file filter
+ is set to "Images (*.png *.xpm *.jpg)". The tqparent of the file dialog
+ is set to \e this and it is given the identification name - "open file
+ dialog". The caption at the top of file dialog is set to "Choose a
+ file". If you want to use multiple filters, separate each one with
+ \e two semi-colons, e.g.
+ \code
+ "Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
+ \endcode
+
+ You can create your own TQFileDialog without using the static
+ functions. By calling setMode(), you can set what can be returned by
+ the TQFileDialog.
+
+ \code
+ TQFileDialog* fd = new TQFileDialog( this, "file dialog", TRUE );
+ fd->setMode( TQFileDialog::AnyFile );
+ \endcode
+
+ In the above example, the mode of the file dialog is set to \c
+ AnyFile, meaning that the user can select any file, or even specify a
+ file that doesn't exist. This mode is useful for creating a "File Save
+ As" file dialog. Use \c ExistingFile if the user must select an
+ existing file or \c Directory if only a directory may be selected.
+ (See the \l TQFileDialog::Mode enum for the complete list of modes.)
+
+ You can retrieve the dialog's mode with mode(). Use setFilter() to set
+ the dialog's file filter, e.g.
+
+ \code
+ fd->setFilter( "Images (*.png *.xpm *.jpg)" );
+ \endcode
+
+ In the above example, the filter is set to "Images (*.png *.xpm
+ *.jpg)", this means that only files with the extension \c png, \c xpm
+ or \c jpg will be shown in the TQFileDialog. You can apply
+ several filters by using setFilters() and add additional filters with
+ addFilter(). Use setSelectedFilter() to select one of the filters
+ you've given as the file dialog's default filter. Whenever the user
+ changes the filter the filterSelected() signal is emitted.
+
+ The file dialog has two view modes, TQFileDialog::List which simply
+ lists file and directory names and TQFileDialog::Detail which
+ displays additional information alongside each name, e.g. file size,
+ modification date, etc. Set the mode with setViewMode().
+
+ \code
+ fd->setViewMode( TQFileDialog::Detail );
+ \endcode
+
+ The last important function you will need to use when creating your
+ own file dialog is selectedFile().
+
+ \code
+ TQString fileName;
+ if ( fd->exec() == TQDialog::Accepted )
+ fileName = fd->selectedFile();
+ \endcode
+
+ In the above example, a modal file dialog is created and shown. If
+ the user clicked OK, then the file they selected is put in \c
+ fileName.
+
+ If you are using the \c ExistingFiles mode then you will need to use
+ selectedFiles() which will return the selected files in a TQStringList.
+
+ The dialog's working directory can be set with setDir(). The display
+ of hidden files is controlled with setShowHiddenFiles(). The dialog
+ can be forced to re-read the directory with rereadDir() and re-sort
+ the directory with resortDir(). All the files in the current directory
+ can be selected with selectAll().
+
+ \section1 Creating and using preview widgets
+
+ There are two kinds of preview widgets that can be used with
+ TQFileDialogs: \e content preview widgets and \e information preview
+ widgets. They are created and used in the same way except that the
+ function names differ, e.g. setContentsPreview() and setInfoPreview().
+
+ A preview widget is a widget that is placed inside a TQFileDialog so
+ that the user can see either the contents of the file, or information
+ about the file.
+
+ \code
+ class Preview : public TQLabel, public TQFilePreview
+ {
+ public:
+ Preview( TQWidget *tqparent=0 ) : TQLabel( tqparent ) {}
+
+ void previewUrl( const TQUrl &u )
+ {
+ TQString path = u.path();
+ TQPixmap pix( path );
+ if ( pix.isNull() )
+ setText( "This is not a pixmap" );
+ else
+ setPixmap( pix );
+ }
+ };
+ \endcode
+
+ In the above snippet, we create a preview widget which inherits from
+ TQLabel and TQFilePreview. File preview widgets \e must inherit from
+ TQFilePreview.
+
+ Inside the class we reimplement TQFilePreview::previewUrl(), this is
+ where we determine what happens when a file is selected. In the
+ above example we only show a preview of the file if it is a valid
+ pixmap. Here's how to make a file dialog use a preview widget:
+
+ \code
+ Preview* p = new Preview;
+
+ TQFileDialog* fd = new TQFileDialog( this );
+ fd->setContentsPreviewEnabled( TRUE );
+ fd->setContentsPreview( p, p );
+ fd->setPreviewMode( TQFileDialog::Contents );
+ fd->show();
+ \endcode
+
+ The first line creates an instance of our preview widget. We then
+ create our file dialog and call setContentsPreviewEnabled( TRUE ),
+ this tell the file dialog to preview the contents of the currently
+ selected file. We then call setContentsPreview() -- note that we pass
+ the same preview widget twice. Finally, before showing the file
+ dialog, we call setPreviewMode() setting the mode to \e Contents which
+ will show the contents preview of the file that the user has selected.
+
+ If you create another preview widget that is used for displaying
+ information about a file, create it in the same way as the contents
+ preview widget and call setInfoPreviewEnabled(), and
+ setInfoPreview(). Then the user will be able to switch between the
+ two preview modes.
+
+ For more information about creating a TQFilePreview widget see
+ \l{TQFilePreview}.
+
+ <img src=qfiledlg-m.png> <img src=qfiledlg-w.png>
+
+*/
+
+
+/*! \enum TQFileDialog::Mode
+
+ This enum is used to indicate what the user may select in the file
+ dialog, i.e. what the dialog will return if the user clicks OK.
+
+ \value AnyFile The name of a file, whether it exists or not.
+ \value ExistingFile The name of a single existing file.
+ \value Directory The name of a directory. Both files and directories
+ are displayed.
+ \value DirectoryOnly The name of a directory. The file dialog will only display directories.
+ \value ExistingFiles The names of zero or more existing files.
+
+ See setMode().
+*/
+
+/*!
+ \enum TQFileDialog::ViewMode
+
+ This enum describes the view mode of the file dialog, i.e. what
+ information about each file will be displayed.
+
+ \value List Display file and directory names with icons.
+ \value Detail Display file and directory names with icons plus
+ additional information, such as file size and modification date.
+
+ See setViewMode().
+*/
+
+/*!
+ \enum TQFileDialog::PreviewMode
+
+ This enum describes the preview mode of the file dialog.
+
+ \value NoPreview No preview is shown at all.
+ \value Contents Show a preview of the contents of the current file
+ using the contents preview widget.
+ \value Info Show information about the current file using the
+ info preview widget.
+
+ See setPreviewMode(), setContentsPreview() and setInfoPreview().
+*/
+
+/*!
+ \fn void TQFileDialog::detailViewSelectionChanged()
+ \internal
+*/
+
+/*!
+ \fn void TQFileDialog::listBoxSelectionChanged()
+ \internal
+*/
+
+extern const char qt_file_dialog_filter_reg_exp[] =
+ "([a-zA-Z0-9 ]*)\\(([a-zA-Z0-9_.*? +;#\\[\\]]*)\\)$";
+
+/*!
+ Constructs a file dialog called \a name, with the tqparent, \a tqparent.
+ If \a modal is TRUE then the file dialog is modal; otherwise it is
+ modeless.
+*/
+
+TQFileDialog::TQFileDialog( TQWidget *tqparent, const char *name, bool modal )
+ : TQDialog( tqparent, name, modal,
+ (modal ?
+ (WFlags)(WStyle_Customize | TQt::WStyle_DialogBorder | TQt::WStyle_Title | TQt::WStyle_SysMenu) : (WFlags)0) )
+{
+ init();
+ d->mode = ExistingFile;
+ d->types->insertItem( tqtr( "All Files (*)" ) );
+ d->cursorOverride = FALSE;
+ emit dirEntered( d->url.dirPath() );
+ rereadDir();
+}
+
+
+/*!
+ Constructs a file dialog called \a name with the tqparent, \a tqparent.
+ If \a modal is TRUE then the file dialog is modal; otherwise it is
+ modeless.
+
+ If \a dirName is specified then it will be used as the dialog's
+ working directory, i.e. it will be the directory that is shown when
+ the dialog appears. If \a filter is specified it will be used as the
+ dialog's file filter.
+
+*/
+
+TQFileDialog::TQFileDialog( const TQString& dirName, const TQString & filter,
+ TQWidget *tqparent, const char *name, bool modal )
+ : TQDialog( tqparent, name, modal,
+ (modal ?
+ (WFlags)(WStyle_Customize | TQt::WStyle_DialogBorder | TQt::WStyle_Title | TQt::WStyle_SysMenu) : (WFlags)0) )
+{
+ init();
+ d->mode = ExistingFile;
+ rereadDir();
+ TQUrlOperator u( dirName );
+ if ( !dirName.isEmpty() && ( !u.isLocalFile() || TQDir( dirName ).exists() ) )
+ setSelection( dirName );
+ else if ( workingDirectory && !workingDirectory->isEmpty() )
+ setDir( *workingDirectory );
+
+ if ( !filter.isEmpty() ) {
+ setFilters( filter );
+ if ( !dirName.isEmpty() ) {
+ int dotpos = dirName.tqfind( TQChar('.'), 0, FALSE );
+ if ( dotpos != -1 ) {
+ for ( int b=0 ; b<d->types->count() ; b++ ) {
+ if ( d->types->text(b).tqcontains( dirName.right( dirName.length() - dotpos ) ) ) {
+ d->types->setCurrentItem( b );
+ setFilter( d->types->text( b ) );
+ return;
+ }
+ }
+ }
+ }
+ } else {
+ d->types->insertItem( tqtr( "All Files (*)" ) );
+ }
+}
+
+
+#if defined(TQ_WS_WIN)
+extern int qt_ntfs_permission_lookup;
+#endif
+
+/*!
+ \internal
+ Initializes the file dialog.
+*/
+
+void TQFileDialog::init()
+{
+ setSizeGripEnabled( TRUE );
+ d = new TQFileDialogPrivate();
+ d->mode = AnyFile;
+ d->last = 0;
+ d->lastEFSelected = 0;
+ d->moreFiles = 0;
+ d->infoPreview = FALSE;
+ d->contentsPreview = FALSE;
+ d->hadDotDot = FALSE;
+ d->ignoreNextKeyPress = FALSE;
+ d->progressDia = 0;
+ d->checkForFilter = FALSE;
+ d->ignoreNextRefresh = FALSE;
+ d->ignoreStop = FALSE;
+ d->pendingItems.setAutoDelete( FALSE );
+ d->mimeTypeTimer = new TQTimer( this );
+ d->cursorOverride = FALSE;
+#if defined(TQ_WS_WIN)
+ d->oldPermissionLookup = qt_ntfs_permission_lookup;
+#endif
+ connect( d->mimeTypeTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( doMimeTypeLookup() ) );
+
+ d->url = TQUrlOperator( ::toRootIfNotExists( TQDir::currentDirPath() ) );
+ d->oldUrl = d->url;
+ d->currListChildren = 0;
+
+ connect( &d->url, TQT_SIGNAL( start(TQNetworkOperation*) ),
+ this, TQT_SLOT( urlStart(TQNetworkOperation*) ) );
+ connect( &d->url, TQT_SIGNAL( finished(TQNetworkOperation*) ),
+ this, TQT_SLOT( urlFinished(TQNetworkOperation*) ) );
+ connect( &d->url, TQT_SIGNAL( newChildren(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ),
+ this, TQT_SLOT( insertEntry(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ) );
+ connect( &d->url, TQT_SIGNAL( removed(TQNetworkOperation*) ),
+ this, TQT_SLOT( removeEntry(TQNetworkOperation*) ) );
+ connect( &d->url, TQT_SIGNAL( createdDirectory(const TQUrlInfo&,TQNetworkOperation*) ),
+ this, TQT_SLOT( createdDirectory(const TQUrlInfo&,TQNetworkOperation*) ) );
+ connect( &d->url, TQT_SIGNAL( itemChanged(TQNetworkOperation*) ),
+ this, TQT_SLOT( itemChanged(TQNetworkOperation*) ) );
+ connect( &d->url, TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ),
+ this, TQT_SLOT( dataTransferProgress(int,int,TQNetworkOperation*) ) );
+
+ nameEdit = new TQLineEdit( this, "name/filter editor" );
+ nameEdit->setMaxLength( 255 ); //_POSIX_MAX_PATH
+ connect( nameEdit, TQT_SIGNAL(textChanged(const TQString&)),
+ this, TQT_SLOT(fileNameEditDone()) );
+ nameEdit->installEventFilter( this );
+
+ d->splitter = new TQSplitter( this, "qt_splitter" );
+
+ d->stack = new TQWidgetStack( d->splitter, "files and more files" );
+
+ d->splitter->tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) );
+
+ files = new TQFileDialogTQFileListView( d->stack, this );
+ TQFontMetrics fm = fontMetrics();
+ files->addColumn( tr("Name") );
+ files->addColumn( tr("Size") );
+ files->setColumnAlignment( 1, Qt::AlignRight );
+ files->addColumn( tr("Type") );
+ files->addColumn( tr("Date") );
+ files->addColumn( tr("Attributes") );
+ files->header()->setStretchEnabled( TRUE, 0 );
+
+ files->setMinimumSize( 50, 25 + 2*fm.lineSpacing() );
+
+ connect( files, TQT_SIGNAL( selectionChanged() ),
+ this, TQT_SLOT( detailViewSelectionChanged() ) );
+ connect( files, TQT_SIGNAL(currentChanged(TQListViewItem*)),
+ this, TQT_SLOT(updateFileNameEdit(TQListViewItem*)) );
+ connect( files, TQT_SIGNAL(doubleClicked(TQListViewItem*)),
+ this, TQT_SLOT(selectDirectoryOrFile(TQListViewItem*)) );
+ connect( files, TQT_SIGNAL(returnPressed(TQListViewItem*)),
+ this, TQT_SLOT(selectDirectoryOrFile(TQListViewItem*)) );
+ connect( files, TQT_SIGNAL(rightButtonPressed(TQListViewItem*,const TQPoint&,int)),
+ this, TQT_SLOT(popupContextMenu(TQListViewItem*,const TQPoint&,int)) );
+
+ files->installEventFilter( this );
+ files->viewport()->installEventFilter( this );
+
+ d->moreFiles = new TQFileListBox( d->stack, this );
+ d->moreFiles->setRowMode( TQListBox::FitToHeight );
+ d->moreFiles->setVariableWidth( TRUE );
+
+ connect( d->moreFiles, TQT_SIGNAL(selected(TQListBoxItem*)),
+ this, TQT_SLOT(selectDirectoryOrFile(TQListBoxItem*)) );
+ connect( d->moreFiles, TQT_SIGNAL( selectionChanged() ),
+ this, TQT_SLOT( listBoxSelectionChanged() ) );
+ connect( d->moreFiles, TQT_SIGNAL(highlighted(TQListBoxItem*)),
+ this, TQT_SLOT(updateFileNameEdit(TQListBoxItem*)) );
+ connect( d->moreFiles, TQT_SIGNAL( rightButtonPressed(TQListBoxItem*,const TQPoint&) ),
+ this, TQT_SLOT( popupContextMenu(TQListBoxItem*,const TQPoint&) ) );
+
+ d->moreFiles->installEventFilter( this );
+ d->moreFiles->viewport()->installEventFilter( this );
+
+ okB = new TQPushButton( tr("&OK"), this, "OK" ); //### Or "Save (see other "OK")
+ okB->setDefault( TRUE );
+ okB->setEnabled( FALSE );
+ connect( okB, TQT_SIGNAL(clicked()), this, TQT_SLOT(okClicked()) );
+ cancelB = new TQPushButton( tr("Cancel") , this, "Cancel" );
+ connect( cancelB, TQT_SIGNAL(clicked()), this, TQT_SLOT(cancelClicked()) );
+
+ d->paths = new TQComboBox( TRUE, this, "directory history/editor" );
+ d->paths->setDuplicatesEnabled( FALSE );
+ d->paths->setInsertionPolicy( TQComboBox::NoInsertion );
+ const TQFileInfoList * rootDrives = TQDir::drives();
+ TQFileInfoListIterator it( *rootDrives );
+ TQFileInfo *fi;
+ makeVariables();
+
+ while ( (fi = it.current()) != 0 ) {
+ ++it;
+ d->paths->insertItem( *openFolderIcon, fi->absFilePath() );
+ }
+
+ if ( !!TQDir::homeDirPath() ) {
+ if ( !d->paths->listBox()->tqfindItem( TQDir::homeDirPath() ) )
+ d->paths->insertItem( *openFolderIcon, TQDir::homeDirPath() );
+ }
+
+ connect( d->paths, TQT_SIGNAL(activated(const TQString&)),
+ this, TQT_SLOT(setDir(const TQString&)) );
+
+ d->paths->installEventFilter( this );
+ TQObjectList *ol = d->paths->queryList( "TQLineEdit" );
+ if ( ol && ol->first() )
+ ( (TQLineEdit*)ol->first() )->installEventFilter( this );
+ delete ol;
+
+ d->tqgeometryDirty = TRUE;
+ d->types = new TQComboBox( TRUE, this, "file types" );
+ d->types->setDuplicatesEnabled( FALSE );
+ d->types->setEditable( FALSE );
+ connect( d->types, TQT_SIGNAL(activated(const TQString&)),
+ this, TQT_SLOT(setFilter(const TQString&)) );
+ connect( d->types, TQT_SIGNAL(activated(const TQString&)),
+ this, TQT_SIGNAL(filterSelected(const TQString&)) );
+
+ d->pathL = new TQLabel( d->paths, tr("Look &in:"), this, "qt_looin_lbl" );
+ d->fileL = new TQLabel( nameEdit, tr("File &name:"), this, "qt_filename_lbl" );
+ d->typeL = new TQLabel( d->types, tr("File &type:"), this, "qt_filetype_lbl" );
+
+ d->goBack = new TQToolButton( this, "go back" );
+ d->goBack->setEnabled( FALSE );
+ d->goBack->setFocusPolicy( Qt::TabFocus );
+ connect( d->goBack, TQT_SIGNAL( clicked() ), this, TQT_SLOT( goBack() ) );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::add( d->goBack, tr( "Back" ) );
+#endif
+ d->goBack->setIconSet( *goBackIcon );
+
+ d->cdToParent = new TQToolButton( this, "cd to tqparent" );
+ d->cdToParent->setFocusPolicy( Qt::TabFocus );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::add( d->cdToParent, tr( "One directory up" ) );
+#endif
+ d->cdToParent->setIconSet( *cdToParentIcon );
+ connect( d->cdToParent, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(cdUpClicked()) );
+
+ d->newFolder = new TQToolButton( this, "new folder" );
+ d->newFolder->setFocusPolicy( Qt::TabFocus );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::add( d->newFolder, tr( "Create New Folder" ) );
+#endif
+ d->newFolder->setIconSet( *newFolderIcon );
+ connect( d->newFolder, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(newFolderClicked()) );
+
+ d->modeButtons = new TQButtonGroup( 0, "invisible group" );
+ connect( d->modeButtons, TQT_SIGNAL(destroyed()),
+ this, TQT_SLOT(modeButtonsDestroyed()) );
+ d->modeButtons->setExclusive( TRUE );
+ connect( d->modeButtons, TQT_SIGNAL(clicked(int)),
+ d->stack, TQT_SLOT(raiseWidget(int)) );
+ connect( d->modeButtons, TQT_SIGNAL(clicked(int)),
+ this, TQT_SLOT(changeMode(int)) );
+
+ d->mcView = new TQToolButton( this, "mclistbox view" );
+ d->mcView->setFocusPolicy( Qt::TabFocus );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::add( d->mcView, tr( "List View" ) );
+#endif
+ d->mcView->setIconSet( *multiColumnListViewIcon );
+ d->mcView->setToggleButton( TRUE );
+ d->stack->addWidget( d->moreFiles, d->modeButtons->insert( d->mcView ) );
+ d->detailView = new TQToolButton( this, "list view" );
+ d->detailView->setFocusPolicy( Qt::TabFocus );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::add( d->detailView, tr( "Detail View" ) );
+#endif
+ d->detailView->setIconSet( *detailViewIcon );
+ d->detailView->setToggleButton( TRUE );
+ d->stack->addWidget( files, d->modeButtons->insert( d->detailView ) );
+
+ d->previewInfo = new TQToolButton( this, "preview info view" );
+ d->previewInfo->setFocusPolicy( Qt::TabFocus );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::add( d->previewInfo, tr( "Preview File Info" ) );
+#endif
+ d->previewInfo->setIconSet( *previewInfoViewIcon );
+ d->previewInfo->setToggleButton( TRUE );
+ d->modeButtons->insert( d->previewInfo );
+
+ d->previewContents = new TQToolButton( this, "preview info view" );
+#if defined(TQ_WS_WIN) && !defined(TQ_OS_TEMP)
+ if ( (qt_winver & WV_NT_based) > TQt::WV_NT )
+#else
+ if ( !qstrcmp(tqstyle().className(), "TQWindowsStyle") )
+#endif
+ {
+ d->goBack->setAutoRaise( TRUE );
+ d->cdToParent->setAutoRaise( TRUE );
+ d->newFolder->setAutoRaise( TRUE );
+ d->mcView->setAutoRaise( TRUE );
+ d->detailView->setAutoRaise( TRUE );
+ d->previewInfo->setAutoRaise( TRUE );
+ d->previewContents->setAutoRaise( TRUE );
+ }
+ d->previewContents->setFocusPolicy( Qt::TabFocus );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::add( d->previewContents, tr( "Preview File Contents" ) );
+#endif
+ d->previewContents->setIconSet( *previewContentsViewIcon );
+ d->previewContents->setToggleButton( TRUE );
+ d->modeButtons->insert( d->previewContents );
+
+ connect( d->detailView, TQT_SIGNAL( clicked() ),
+ d->moreFiles, TQT_SLOT( cancelRename() ) );
+ connect( d->detailView, TQT_SIGNAL( clicked() ),
+ files, TQT_SLOT( cancelRename() ) );
+ connect( d->mcView, TQT_SIGNAL( clicked() ),
+ d->moreFiles, TQT_SLOT( cancelRename() ) );
+ connect( d->mcView, TQT_SIGNAL( clicked() ),
+ files, TQT_SLOT( cancelRename() ) );
+
+ d->stack->raiseWidget( d->moreFiles );
+ d->mcView->setOn( TRUE );
+
+ TQHBoxLayout *lay = new TQHBoxLayout( this );
+ lay->setMargin( 6 );
+ d->leftLayout = new TQHBoxLayout( lay, 5 );
+ d->topLevelLayout = new TQVBoxLayout( (TQWidget*)0, 5 );
+ lay->addLayout( d->topLevelLayout, 1 );
+ d->extraWidgetsLayouts.setAutoDelete( FALSE );
+ d->extraLabels.setAutoDelete( FALSE );
+ d->extraWidgets.setAutoDelete( FALSE );
+ d->extraButtons.setAutoDelete( FALSE );
+ d->toolButtons.setAutoDelete( FALSE );
+
+ TQHBoxLayout * h;
+
+ d->preview = new TQWidgetStack( d->splitter, "qt_preview" );
+
+ d->infoPreviewWidget = new TQWidget( d->preview, "qt_preview_info" );
+ d->contentsPreviewWidget = new TQWidget( d->preview, "qt_preview_contents" );
+ d->infoPreviewer = d->contentsPreviewer = 0;
+
+ h = new TQHBoxLayout( 0 );
+ d->buttonLayout = h;
+ d->topLevelLayout->addLayout( h );
+ h->addWidget( d->pathL );
+ h->addSpacing( 8 );
+ h->addWidget( d->paths );
+ h->addSpacing( 8 );
+ if ( d->goBack )
+ h->addWidget( d->goBack );
+ h->addWidget( d->cdToParent );
+ h->addSpacing( 2 );
+ h->addWidget( d->newFolder );
+ h->addSpacing( 4 );
+ h->addWidget( d->mcView );
+ h->addWidget( d->detailView );
+ h->addWidget( d->previewInfo );
+ h->addWidget( d->previewContents );
+
+ d->topLevelLayout->addWidget( d->splitter );
+
+ h = new TQHBoxLayout();
+ d->topLevelLayout->addLayout( h );
+ h->addWidget( d->fileL );
+ h->addWidget( nameEdit );
+ h->addSpacing( 15 );
+ h->addWidget( okB );
+
+ h = new TQHBoxLayout();
+ d->topLevelLayout->addLayout( h );
+ h->addWidget( d->typeL );
+ h->addWidget( d->types );
+ h->addSpacing( 15 );
+ h->addWidget( cancelB );
+
+ d->rightLayout = new TQHBoxLayout( lay, 5 );
+ d->topLevelLayout->setStretchFactor( d->mcView, 1 );
+ d->topLevelLayout->setStretchFactor( files, 1 );
+
+ updateGeometries();
+
+ if ( d->goBack ) {
+ setTabOrder( d->paths, d->goBack );
+ setTabOrder( d->goBack, d->cdToParent );
+ } else {
+ setTabOrder( d->paths, d->cdToParent );
+ }
+ setTabOrder( d->cdToParent, d->newFolder );
+ setTabOrder( d->newFolder, d->mcView );
+ setTabOrder( d->mcView, d->detailView );
+ setTabOrder( d->detailView, d->moreFiles );
+ setTabOrder( d->moreFiles, files );
+ setTabOrder( files, nameEdit );
+ setTabOrder( nameEdit, d->types );
+ setTabOrder( d->types, okB );
+ setTabOrder( okB, cancelB );
+
+ d->rw = tr( "Read-write" );
+ d->ro = tr( "Read-only" );
+ d->wo = tr( "Write-only" );
+ d->inaccessible = tr( "Inaccessible" );
+
+ d->symLinkToFile = tr( "Symlink to File" );
+ d->symLinkToDir = tr( "Symlink to Directory" );
+ d->symLinkToSpecial = tr( "Symlink to Special" );
+ d->file = tr( "File" );
+ d->dir = tr( "Dir" );
+ d->special = tr( "Special" );
+
+ if ( lastWidth == 0 ) {
+ TQRect screen = TQApplication::desktop()->screenGeometry( pos() );
+ if ( screen.width() < 1024 || screen.height() < 768 ) {
+ resize( TQMIN(screen.width(), 420), TQMIN(screen.height(), 236) );
+ } else {
+ TQSize s = files->tqsizeHint();
+ s = TQSize( s.width() + 300, s.height() + 82 );
+
+ if ( s.width() * 3 > screen.width() * 2 )
+ s.setWidth( screen.width() * 2 / 3 );
+
+ if ( s.height() * 3 > screen.height() * 2 )
+ s.setHeight( screen.height() * 2 / 3 );
+ else if ( s.height() * 3 < screen.height() )
+ s.setHeight( screen.height() / 3 );
+
+ resize( s );
+ }
+ updateLastSize(this);
+ } else {
+ resize( lastWidth, lastHeight );
+ }
+
+ if ( detailViewMode ) {
+ d->stack->raiseWidget( files );
+ d->mcView->setOn( FALSE );
+ d->detailView->setOn( TRUE );
+ }
+
+ d->preview->hide();
+ nameEdit->setFocus();
+
+ connect( nameEdit, TQT_SIGNAL( returnPressed() ),
+ this, TQT_SLOT( fileNameEditReturnPressed() ) );
+}
+
+/*!
+ \internal
+*/
+
+void TQFileDialog::fileNameEditReturnPressed()
+{
+ d->oldUrl = d->url;
+ if ( !isDirectoryMode( d->mode ) ) {
+ okClicked();
+ } else {
+ d->currentFileName = TQString::null;
+ if ( nameEdit->text().isEmpty() ) {
+ emit fileSelected( selectedFile() );
+ accept();
+ } else {
+ TQUrlInfo f;
+ TQFileDialogPrivate::File * c
+ = (TQFileDialogPrivate::File *)files->currentItem();
+ if ( c && files->isSelected(c) )
+ f = c->info;
+ else
+ f = TQUrlInfo( d->url, nameEdit->text() );
+ if ( f.isDir() ) {
+ setUrl( TQUrlOperator( d->url,
+ TQFileDialogPrivate::encodeFileName(nameEdit->text() + "/" ) ) );
+ d->checkForFilter = TRUE;
+ trySetSelection( TRUE, d->url, TRUE );
+ d->checkForFilter = FALSE;
+ }
+ }
+ nameEdit->setText( TQString::null );
+ }
+}
+
+/*!
+ \internal
+ Update the info and content preview widgets to display \a u.
+*/
+
+void TQFileDialog::updatePreviews( const TQUrl &u )
+{
+ if ( d->infoPreviewer )
+ d->infoPreviewer->previewUrl( u );
+ if ( d->contentsPreviewer )
+ d->contentsPreviewer->previewUrl( u );
+}
+
+/*!
+ \internal
+ Changes the preview mode to the mode specified at \a id.
+*/
+
+void TQFileDialog::changeMode( int id )
+{
+ if ( !d->infoPreview && !d->contentsPreview )
+ return;
+
+ TQButton *btn = (TQButton*)d->modeButtons->tqfind( id );
+ if ( !btn )
+ return;
+
+ if ( btn == d->previewContents && !d->contentsPreview )
+ return;
+ if ( btn == d->previewInfo && !d->infoPreview )
+ return;
+
+ if ( btn != d->previewContents && btn != d->previewInfo ) {
+ d->preview->hide();
+ } else {
+ if ( files->currentItem() )
+ updatePreviews( TQUrl( d->url, files->currentItem()->text( 0 ) ) );
+ if ( btn == d->previewInfo )
+ d->preview->raiseWidget( d->infoPreviewWidget );
+ else
+ d->preview->raiseWidget( d->contentsPreviewWidget );
+ d->preview->show();
+ }
+}
+
+/*!
+ Destroys the file dialog.
+*/
+
+TQFileDialog::~TQFileDialog()
+{
+ // since clear might call setContentsPos which would emit
+ // a signal and thus cause a recompute of sizes...
+ files->blockSignals( TRUE );
+ d->moreFiles->blockSignals( TRUE );
+ files->clear();
+ d->moreFiles->clear();
+ d->moreFiles->blockSignals( FALSE );
+ files->blockSignals( FALSE );
+
+#ifndef TQT_NO_CURSOR
+ if ( d->cursorOverride )
+ TQApplication::restoreOverrideCursor();
+#endif
+
+ delete d;
+ d = 0;
+}
+
+
+/*!
+ \property TQFileDialog::selectedFile
+
+ \brief the name of the selected file
+
+ If a file was selected selectedFile tqcontains the file's name including
+ its absolute path; otherwise selectedFile is empty.
+
+ \sa TQString::isEmpty(), selectedFiles, selectedFilter
+*/
+
+TQString TQFileDialog::selectedFile() const
+{
+ TQString s = d->currentFileName;
+ // remove the protocol because we do not want to encode it...
+ TQString prot = TQUrl( s ).protocol();
+ if ( !prot.isEmpty() ) {
+ prot += ":";
+ s.remove( 0, prot.length() );
+ }
+ TQUrl u( prot + TQFileDialogPrivate::encodeFileName( s ) );
+ if ( u.isLocalFile() ) {
+ TQString s = u.toString();
+ if ( s.left( 5 ) == "file:" )
+ s.remove( (uint)0, 5 );
+ return s;
+ }
+ return d->currentFileName;
+}
+
+/*!
+ \property TQFileDialog::selectedFilter
+
+ \brief the filter which the user has selected in the file dialog
+
+ \sa filterSelected(), selectedFiles, selectedFile
+*/
+
+TQString TQFileDialog::selectedFilter() const
+{
+ return d->types->currentText();
+}
+
+/*! \overload
+
+ Sets the current filter selected in the file dialog to the
+ \a{n}-th filter in the filter list.
+
+ \sa filterSelected(), selectedFilter(), selectedFiles(), selectedFile()
+*/
+
+void TQFileDialog::setSelectedFilter( int n )
+{
+ d->types->setCurrentItem( n );
+ TQString f = d->types->currentText();
+ TQRegExp r( TQString::tqfromLatin1(qt_file_dialog_filter_reg_exp) );
+ int index = r.search( f );
+ if ( index >= 0 )
+ f = r.cap( 2 );
+ d->url.setNameFilter( f );
+ rereadDir();
+}
+
+/*!
+ Sets the current filter selected in the file dialog to the first
+ one that tqcontains the text \a tqmask.
+*/
+
+void TQFileDialog::setSelectedFilter( const TQString& tqmask )
+{
+ int n;
+
+ for ( n = 0; n < d->types->count(); n++ ) {
+ if ( d->types->text( n ).tqcontains( tqmask, FALSE ) ) {
+ d->types->setCurrentItem( n );
+ TQString f = tqmask;
+ TQRegExp r( TQString::tqfromLatin1(qt_file_dialog_filter_reg_exp) );
+ int index = r.search( f );
+ if ( index >= 0 )
+ f = r.cap( 2 );
+ d->url.setNameFilter( f );
+ rereadDir();
+ return;
+ }
+ }
+}
+
+/*!
+ \property TQFileDialog::selectedFiles
+
+ \brief the list of selected files
+
+ If one or more files are selected, selectedFiles tqcontains their
+ names including their absolute paths. If no files are selected or
+ the mode isn't ExistingFiles selectedFiles is an empty list.
+
+ It is more convenient to use selectedFile() if the mode is
+ \c ExistingFile, \c Directory or \c DirectoryOnly.
+
+ Note that if you want to iterate over the list, you should
+ iterate over a copy, e.g.
+ \code
+ TQStringList list = myFileDialog.selectedFiles();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa selectedFile, selectedFilter, TQValueList::empty()
+*/
+
+TQStringList TQFileDialog::selectedFiles() const
+{
+ TQStringList lst;
+
+ if ( mode() == ExistingFiles ) {
+ TQStringList selectedLst;
+ TQString selectedFiles = nameEdit->text();
+ if (selectedFiles.tqfindRev('\"') == -1) {
+ //probably because Enter was pressed on the nameEdit, so we have one file
+ //not in "" but raw
+ selectedLst.append(selectedFiles);
+ } else {
+ selectedFiles.truncate( selectedFiles.tqfindRev( '\"' ) );
+ selectedLst = selectedLst.split( TQString("\" "), selectedFiles );
+ }
+ for ( TQStringList::Iterator it = selectedLst.begin(); it != selectedLst.end(); ++it ) {
+ TQUrl u;
+ if ( (*it)[0] == '\"' ) {
+ u = TQUrl( d->url, TQFileDialogPrivate::encodeFileName( (*it).mid(1) ) );
+ } else {
+ u = TQUrl( d->url, TQFileDialogPrivate::encodeFileName( (*it) ) );
+ }
+ if ( u.isLocalFile() ) {
+ TQString s = u.toString();
+ if ( s.left( 5 ) == "file:" )
+ s.remove( (uint)0, 5 );
+ lst << s;
+ } else {
+ lst << u.toString();
+ }
+ }
+ }
+
+ return lst;
+}
+
+/*!
+ Sets the default selection to \a filename. If \a filename is
+ absolute, setDir() is also called to set the file dialog's working
+ directory to the filename's directory.
+
+ \omit
+ Only for external use. Not useful inside TQFileDialog.
+ \endomit
+*/
+
+void TQFileDialog::setSelection( const TQString & filename )
+{
+ d->oldUrl = d->url;
+ TQString nf = d->url.nameFilter();
+ if ( TQUrl::isRelativeUrl( filename ) )
+ d->url = TQUrlOperator( d->url, TQFileDialogPrivate::encodeFileName( filename ) );
+ else
+ d->url = TQUrlOperator( filename );
+ d->url.setNameFilter( nf );
+ d->checkForFilter = TRUE;
+ bool isDirOk;
+ bool isDir = d->url.isDir( &isDirOk );
+ if ( !isDirOk )
+ isDir = d->url.path().right( 1 ) == "/";
+ if ( !isDir ) {
+ TQUrlOperator u( d->url );
+ d->url.setPath( d->url.dirPath() );
+ trySetSelection( FALSE, u, TRUE );
+ d->ignoreNextRefresh = TRUE;
+ nameEdit->selectAll();
+ rereadDir();
+ emit dirEntered( d->url.dirPath() );
+ } else {
+ if ( !d->url.path().isEmpty() &&
+ d->url.path().right( 1 ) != "/" ) {
+ TQString p = d->url.path();
+ p += "/";
+ d->url.setPath( p );
+ }
+ trySetSelection( TRUE, d->url, FALSE );
+ rereadDir();
+ emit dirEntered( d->url.dirPath() );
+ nameEdit->setText( TQString::tqfromLatin1("") );
+ }
+ d->checkForFilter = FALSE;
+}
+
+/*!
+ \property TQFileDialog::dirPath
+
+ \brief the file dialog's working directory
+
+ \sa dir(), setDir()
+*/
+
+TQString TQFileDialog::dirPath() const
+{
+ return d->url.dirPath();
+}
+
+
+/*!
+
+ Sets the filter used in the file dialog to \a newFilter.
+
+ If \a newFilter tqcontains a pair of parentheses containing one or more
+ of <em><b>anything*something</b></em> separated by spaces or by
+ semi-colons then only the text contained in the parentheses is used as
+ the filter. This means that these calls are all equivalent:
+
+ \code
+ fd->setFilter( "All C++ files (*.cpp *.cc *.C *.cxx *.c++)" );
+ fd->setFilter( "*.cpp *.cc *.C *.cxx *.c++" );
+ fd->setFilter( "All C++ files (*.cpp;*.cc;*.C;*.cxx;*.c++)" );
+ fd->setFilter( "*.cpp;*.cc;*.C;*.cxx;*.c++" );
+ \endcode
+
+ \sa setFilters()
+*/
+
+void TQFileDialog::setFilter( const TQString & newFilter )
+{
+ if ( newFilter.isEmpty() )
+ return;
+ TQString f = newFilter;
+ TQRegExp r( TQString::tqfromLatin1(qt_file_dialog_filter_reg_exp) );
+ int index = r.search( f );
+ if ( index >= 0 )
+ f = r.cap( 2 );
+ d->url.setNameFilter( f );
+ if ( d->types->count() == 1 ) {
+ d->types->clear();
+ d->types->insertItem( newFilter );
+ } else {
+ for ( int i = 0; i < d->types->count(); ++i ) {
+ if ( d->types->text( i ).left( newFilter.length() ) == newFilter ||
+ d->types->text( i ).left( f.length() ) == f ) {
+ d->types->setCurrentItem( i );
+ break;
+ }
+ }
+ }
+ rereadDir();
+}
+
+
+/*! \overload
+ Sets the file dialog's working directory to \a pathstr.
+
+ \sa dir()
+*/
+
+void TQFileDialog::setDir( const TQString & pathstr )
+{
+ TQString dr = pathstr;
+ if ( dr.isEmpty() )
+ return;
+
+#if defined(TQ_OS_UNIX)
+ if ( dr.length() && dr[0] == '~' ) {
+ int i = 0;
+ while( i < (int)dr.length() && dr[i] != '/' )
+ i++;
+ TQCString user;
+ if ( i == 1 ) {
+#if defined(TQT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+
+# ifndef _POSIX_LOGIN_NAME_MAX
+# define _POSIX_LOGIN_NAME_MAX 9
+# endif
+
+ char name[_POSIX_LOGIN_NAME_MAX];
+ if ( ::getlogin_r( name, _POSIX_LOGIN_NAME_MAX ) == 0 )
+ user = name;
+ else
+#else
+ user = ::getlogin();
+ if ( user.isNull() )
+#endif
+ user = getenv( "LOGNAME" );
+ } else
+ user = TQT_TQSTRING(dr.mid( 1, i-1 )).local8Bit();
+ dr = dr.mid( i, dr.length() );
+ struct passwd *pw;
+#if defined(TQT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(TQ_OS_FREEBSD) && !defined(TQ_OS_OPENBSD)
+ struct passwd mt_pw;
+ char buffer[2048];
+ if ( ::getpwnam_r( user, &mt_pw, buffer, 2048, &pw ) == 0 && pw == &mt_pw )
+#else
+ pw = ::getpwnam( user );
+ if ( pw )
+#endif
+ dr.prepend( TQString::fromLocal8Bit(pw->pw_dir) );
+ }
+#endif
+
+ setUrl( dr );
+}
+
+/*!
+ Returns the current directory shown in the file dialog.
+
+ The ownership of the TQDir pointer is transferred to the caller, so
+ it must be deleted by the caller when no longer required.
+
+ \sa setDir()
+*/
+
+const TQDir *TQFileDialog::dir() const
+{
+ if ( d->url.isLocalFile() )
+ return new TQDir( d->url.path() );
+ else
+ return 0;
+}
+
+/*!
+ Sets the file dialog's working directory to \a dir.
+ \sa dir()
+*/
+
+void TQFileDialog::setDir( const TQDir &dir )
+{
+ d->oldUrl = d->url;
+ TQString nf( d->url.nameFilter() );
+ d->url = dir.canonicalPath();
+ d->url.setNameFilter( nf );
+ TQUrlInfo i( d->url, nameEdit->text() );
+ d->checkForFilter = TRUE;
+ trySetSelection( i.isDir(), TQUrlOperator( d->url, TQFileDialogPrivate::encodeFileName(nameEdit->text() ) ), FALSE );
+ d->checkForFilter = FALSE;
+ rereadDir();
+ emit dirEntered( d->url.path() );
+}
+
+/*!
+ Sets the file dialog's working directory to the directory specified at \a url.
+
+ \sa url()
+*/
+
+void TQFileDialog::setUrl( const TQUrlOperator &url )
+{
+ d->oldUrl = d->url;
+ TQString nf = d->url.nameFilter();
+
+ TQString operatorPath = url.toString( FALSE, FALSE );
+ if ( TQUrl::isRelativeUrl( operatorPath ) ) {
+ d->url = TQUrl( d->url, operatorPath );
+ } else {
+ d->url = url;
+ }
+ d->url.setNameFilter( nf );
+
+ d->checkForFilter = TRUE;
+ if ( !d->url.isDir() ) {
+ TQUrlOperator u = d->url;
+ d->url.setPath( d->url.dirPath() );
+ trySetSelection( FALSE, u, FALSE );
+ rereadDir();
+ emit dirEntered( d->url.dirPath() );
+ TQString fn = u.fileName();
+ nameEdit->setText( fn );
+ } else {
+ trySetSelection( TRUE, d->url, FALSE );
+ rereadDir();
+ emit dirEntered( d->url.dirPath() );
+ }
+ d->checkForFilter = FALSE;
+}
+
+/*!
+ \property TQFileDialog::showHiddenFiles
+
+ \brief whether hidden files are shown in the file dialog
+
+ The default is FALSE, i.e. don't show hidden files.
+*/
+
+void TQFileDialog::setShowHiddenFiles( bool s )
+{
+ if ( s == bShowHiddenFiles )
+ return;
+
+ bShowHiddenFiles = s;
+ rereadDir();
+}
+
+bool TQFileDialog::showHiddenFiles() const
+{
+ return bShowHiddenFiles;
+}
+
+/*!
+ Rereads the current directory shown in the file dialog.
+
+ The only time you will need to call this function is if the contents of
+ the directory change and you wish to refresh the file dialog to reflect
+ the change.
+
+ \sa resortDir()
+*/
+
+void TQFileDialog::rereadDir()
+{
+#ifndef TQT_NO_CURSOR
+ if ( !d->cursorOverride ) {
+ TQApplication::setOverrideCursor( TQCursor( TQt::WaitCursor ) );
+ d->cursorOverride = TRUE;
+ }
+#endif
+ d->pendingItems.clear();
+ if ( d->mimeTypeTimer->isActive() )
+ d->mimeTypeTimer->stop();
+ d->currListChildren = d->url.listChildren();
+#ifndef TQT_NO_CURSOR
+ if ( d->cursorOverride ) {
+ TQApplication::restoreOverrideCursor();
+ d->cursorOverride = FALSE;
+ }
+#endif
+}
+
+
+/*!
+ \fn void TQFileDialog::fileHighlighted( const TQString& )
+
+ This signal is emitted when the user highlights a file, i.e. makes
+ it the current file.
+
+ \sa fileSelected(), filesSelected()
+*/
+
+/*!
+ \fn void TQFileDialog::fileSelected( const TQString& )
+
+ This signal is emitted when the user selects a file.
+
+ \sa filesSelected(), fileHighlighted(), selectedFile()
+*/
+
+/*!
+ \fn void TQFileDialog::filesSelected( const TQStringList& )
+
+ This signal is emitted when the user selects one or more files in \e
+ ExistingFiles mode.
+
+ \sa fileSelected(), fileHighlighted(), selectedFiles()
+*/
+
+/*!
+ \fn void TQFileDialog::dirEntered( const TQString& )
+
+ This signal is emitted when the user enters a directory.
+
+ \sa dir()
+*/
+
+/*!
+ \fn void TQFileDialog::filterSelected( const TQString& )
+
+ This signal is emitted when the user selects a filter.
+
+ \sa selectedFilter()
+*/
+
+extern bool qt_resolve_symlinks; // defined in qapplication.cpp
+bool TQ_EXPORT qt_use_native_dialogs = TRUE;
+
+/*!
+ This is a convenience static function that returns an existing file
+ selected by the user. If the user pressed Cancel, it returns a null
+ string.
+
+ \code
+ TQString s = TQFileDialog::getOpenFileName(
+ "/home",
+ "Images (*.png *.xpm *.jpg)",
+ this,
+ "open file dialog",
+ "Choose a file to open" );
+ \endcode
+
+ The function creates a modal file dialog called \a name, with
+ tqparent, \a tqparent. If a tqparent is not 0, the dialog will be shown
+ centered over the tqparent.
+
+ The file dialog's working directory will be set to \a startWith. If \a
+ startWith includes a file name, the file will be selected. The filter
+ is set to \a filter so that only those files which match the filter
+ are shown. The filter selected is set to \a selectedFilter. The parameters
+ \a startWith, \a selectedFilter and \a filter may be TQString::null.
+
+ The dialog's caption is set to \a caption. If \a caption is not
+ specified then a default caption will be used.
+
+ Under Windows and Mac OS X, this static function will use the native
+ file dialog and not a TQFileDialog, unless the style of the application
+ is set to something other than the native style (Note that on Windows the
+ dialog will spin a blocking modal event loop that will not dispatch any
+ TQTimers and if tqparent is not 0 then it will position the dialog just under
+ the tqparent's titlebar).
+
+ Under Unix/X11, the normal behavior of the file dialog is to resolve
+ and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp,
+ the file dialog will change to /var/tmp after entering /usr/tmp.
+ If \a resolveSymlinks is FALSE, the file dialog will treat
+ symlinks as regular directories.
+
+ \sa getOpenFileNames(), getSaveFileName(), getExistingDirectory()
+*/
+
+TQString TQFileDialog::getOpenFileName( const TQString & startWith,
+ const TQString& filter,
+ TQWidget *tqparent, const char* name,
+ const TQString& caption,
+ TQString *selectedFilter,
+ bool resolveSymlinks )
+{
+ bool save_qt_resolve_symlinks = qt_resolve_symlinks;
+ qt_resolve_symlinks = resolveSymlinks;
+
+ TQStringList filters;
+ if ( !filter.isEmpty() )
+ filters = makeFiltersList( filter );
+
+ makeVariables();
+ TQString initialSelection;
+ //### Problem with the logic here: If a startWith is given and a file
+ // with that name exists in D->URL, the box will be opened at D->URL instead of
+ // the last directory used ('workingDirectory').
+ //
+ // hm... isn't that problem exactly the documented behaviour? the
+ // documented behaviour sounds meaningful.
+ if ( !startWith.isEmpty() ) {
+ TQUrlOperator u( TQFileDialogPrivate::encodeFileName( startWith ) );
+ if ( u.isLocalFile() && TQFileInfo( u.path() ).isDir() ) {
+ *workingDirectory = startWith;
+ } else {
+ if ( u.isLocalFile() ) {
+ TQFileInfo fi( u.dirPath() );
+ if ( fi.exists() ) {
+ *workingDirectory = u.dirPath();
+ initialSelection = u.fileName();
+ }
+ } else {
+ *workingDirectory = u.toString();
+ initialSelection = TQString::null;//u.fileName();
+ }
+ }
+ }
+
+ if ( workingDirectory->isNull() )
+ *workingDirectory = ::toRootIfNotExists( TQDir::currentDirPath() );
+
+#if defined(TQ_WS_WIN)
+ if ( qt_use_native_dialogs && tqApp->tqstyle().tqstyleHint( TQStyle::SH_GUIStyle ) == WindowsStyle )
+ return winGetOpenFileName( initialSelection, filter, workingDirectory,
+ tqparent, name, caption, selectedFilter );
+#elif defined(TQ_WS_MAC)
+ if (qt_use_native_dialogs && (tqApp->tqstyle().inherits(TQMAC_DEFAULT_STYLE)
+ || tqApp->tqstyle().inherits("TQMacStyle")))
+ return qt_mac_precomposeFileName(macGetOpenFileNames(filter,
+ startWith.isEmpty() ? 0 : workingDirectory,
+ tqparent, name, caption, selectedFilter, FALSE).first());
+#endif
+
+ TQFileDialog *dlg = new TQFileDialog( *workingDirectory, TQString::null, tqparent, name ? name : "qt_filedlg_gofn", TRUE );
+
+ TQ_CHECK_PTR( dlg );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( !caption.isNull() )
+ dlg->setCaption( caption );
+ else
+ dlg->setCaption( TQFileDialog::tr( "Open" ) );
+#endif
+
+ dlg->setFilters( filters );
+ if ( selectedFilter )
+ dlg->setFilter( *selectedFilter );
+ dlg->setMode( TQFileDialog::ExistingFile );
+ TQString result;
+ if ( !initialSelection.isEmpty() )
+ dlg->setSelection( initialSelection );
+ if ( dlg->exec() == TQDialog::Accepted ) {
+ result = dlg->selectedFile();
+ *workingDirectory = dlg->d->url;
+ if ( selectedFilter )
+ *selectedFilter = dlg->selectedFilter();
+ }
+ delete dlg;
+
+ qt_resolve_symlinks = save_qt_resolve_symlinks;
+
+ return result;
+}
+
+/*!
+ This is a convenience static function that will return a file name
+ selected by the user. The file does not have to exist.
+
+ It creates a modal file dialog called \a name, with tqparent, \a tqparent.
+ If a tqparent is not 0, the dialog will be shown centered over the
+ tqparent.
+
+ \code
+ TQString s = TQFileDialog::getSaveFileName(
+ "/home",
+ "Images (*.png *.xpm *.jpg)",
+ this,
+ "save file dialog",
+ "Choose a filename to save under" );
+ \endcode
+
+ The file dialog's working directory will be set to \a startWith. If \a
+ startWith includes a file name, the file will be selected. The filter
+ is set to \a filter so that only those files which match the filter
+ are shown. The filter selected is set to \a selectedFilter. The parameters
+ \a startWith, \a selectedFilter and \a filter may be TQString::null.
+
+ The dialog's caption is set to \a caption. If \a caption is not
+ specified then a default caption will be used.
+
+ Under Windows and Mac OS X, this static function will use the native
+ file dialog and not a TQFileDialog, unless the style of the application
+ is set to something other than the native style. (Note that on Windows the
+ dialog will spin a blocking modal event loop that will not dispatch any
+ TQTimers and if tqparent is not 0 then it will position the dialog just under
+ the tqparent's titlebar.
+
+ Under Unix/X11, the normal behavior of the file dialog is to resolve
+ and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp,
+ the file dialog will change to /var/tmp after entering /usr/tmp.
+ If \a resolveSymlinks is FALSE, the file dialog will treat
+ symlinks as regular directories.
+
+ \sa getOpenFileName(), getOpenFileNames(), getExistingDirectory()
+*/
+
+TQString TQFileDialog::getSaveFileName( const TQString & startWith,
+ const TQString& filter,
+ TQWidget *tqparent, const char* name,
+ const TQString& caption,
+ TQString *selectedFilter,
+ bool resolveSymlinks)
+{
+ bool save_qt_resolve_symlinks = qt_resolve_symlinks;
+ qt_resolve_symlinks = resolveSymlinks;
+
+ TQStringList filters;
+ if ( !filter.isEmpty() )
+ filters = makeFiltersList( filter );
+
+ makeVariables();
+ TQString initialSelection;
+ if ( !startWith.isEmpty() ) {
+ TQUrlOperator u( TQFileDialogPrivate::encodeFileName( startWith ) );
+ if ( u.isLocalFile() && TQFileInfo( u.path() ).isDir() ) {
+ *workingDirectory = startWith;
+ } else {
+ if ( u.isLocalFile() ) {
+ TQFileInfo fi( u.dirPath() );
+ if ( fi.exists() ) {
+ *workingDirectory = u.dirPath();
+ initialSelection = u.fileName();
+ }
+ } else {
+ *workingDirectory = u.toString();
+ initialSelection = TQString::null;//u.fileName();
+ }
+ }
+ }
+
+ if ( workingDirectory->isNull() )
+ *workingDirectory = ::toRootIfNotExists( TQDir::currentDirPath() );
+
+#if defined(TQ_WS_WIN)
+ if ( qt_use_native_dialogs && tqApp->tqstyle().tqstyleHint( TQStyle::SH_GUIStyle ) == WindowsStyle )
+ return winGetSaveFileName( initialSelection, filter, workingDirectory,
+ tqparent, name, caption, selectedFilter );
+#elif defined(TQ_WS_MAC)
+ if (qt_use_native_dialogs && (tqApp->tqstyle().inherits(TQMAC_DEFAULT_STYLE)
+ || tqApp->tqstyle().inherits("TQMacStyle")))
+ return qt_mac_precomposeFileName(macGetSaveFileName(initialSelection, filter,
+ startWith.isEmpty() ? 0 : workingDirectory, tqparent, name,
+ caption, selectedFilter));
+#endif
+
+ TQFileDialog *dlg = new TQFileDialog( *workingDirectory, TQString::null, tqparent, name ? name : "qt_filedlg_gsfn", TRUE );
+
+ TQ_CHECK_PTR( dlg );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( !caption.isNull() )
+ dlg->setCaption( caption );
+ else
+ dlg->setCaption( TQFileDialog::tr( "Save As" ) );
+#endif
+
+ TQString result;
+ dlg->setFilters( filters );
+ if ( selectedFilter )
+ dlg->setFilter( *selectedFilter );
+ dlg->setMode( TQFileDialog::AnyFile );
+ if ( !initialSelection.isEmpty() )
+ dlg->setSelection( initialSelection );
+ if ( dlg->exec() == TQDialog::Accepted ) {
+ result = dlg->selectedFile();
+ *workingDirectory = dlg->d->url;
+ if ( selectedFilter )
+ *selectedFilter = dlg->selectedFilter();
+ }
+ delete dlg;
+
+ qt_resolve_symlinks = save_qt_resolve_symlinks;
+
+ return result;
+}
+
+/*!
+ \internal
+ Activated when the "OK" button is clicked.
+*/
+
+void TQFileDialog::okClicked()
+{
+ TQString fn( nameEdit->text() );
+
+#if defined(TQ_WS_WIN)
+ TQFileInfo fi( d->url.path() + fn );
+ if ( fi.isSymLink() ) {
+ nameEdit->setText( fi.readLink() );
+ }
+#endif
+
+ if ( fn.tqcontains("*") ) {
+ addFilter( fn );
+ nameEdit->blockSignals( TRUE );
+ nameEdit->setText( TQString::tqfromLatin1("") );
+ nameEdit->blockSignals( FALSE );
+ return;
+ }
+
+ *workingDirectory = d->url;
+ detailViewMode = files->isVisible();
+ updateLastSize(this);
+
+ if ( isDirectoryMode( d->mode ) ) {
+ TQUrlInfo f( d->url, nameEdit->text() );
+ if ( f.isDir() ) {
+ d->currentFileName = d->url;
+ if ( d->currentFileName.right(1) != "/" )
+ d->currentFileName += '/';
+ if ( f.name() != "." )
+ d->currentFileName += f.name();
+ accept();
+ return;
+ }
+ // Since it's not a directory and we clicked ok, we
+ // don't really want to do anything else
+ return;
+ }
+
+ // if we're in multi-selection mode and something is selected,
+ // accept it and be done.
+ if ( mode() == ExistingFiles ) {
+ if ( ! nameEdit->text().isEmpty() ) {
+ TQStringList sf = selectedFiles();
+ bool isdir = FALSE;
+ if ( sf.count() == 1 ) {
+ TQUrlOperator u( d->url, sf[0] );
+ bool ok;
+ isdir = u.isDir(&ok) && ok;
+ }
+ if ( !isdir ) {
+ emit filesSelected( sf );
+ accept();
+ return;
+ }
+ }
+ }
+
+ if ( mode() == AnyFile ) {
+ TQUrlOperator u( d->url, TQFileDialogPrivate::encodeFileName(nameEdit->text()) );
+ if ( !u.isDir() ) {
+ d->currentFileName = u;
+ emit fileSelected( selectedFile() );
+ accept();
+ return;
+ }
+ }
+
+ if ( mode() == ExistingFile ) {
+ if ( !TQFileDialogPrivate::fileExists( d->url, nameEdit->text() ) )
+ return;
+ }
+
+ // If selection is valid, return it, else try
+ // using selection as a directory to change to.
+ if ( !d->currentFileName.isNull() && !d->currentFileName.tqcontains( "*" ) ) {
+ emit fileSelected( selectedFile() );
+ accept();
+ } else {
+ TQUrlInfo f;
+ TQFileDialogPrivate::File * c
+ = (TQFileDialogPrivate::File *)files->currentItem();
+ TQFileDialogPrivate::MCItem * m
+ = (TQFileDialogPrivate::MCItem *)d->moreFiles->item( d->moreFiles->currentItem() );
+ if ( (c && files->isVisible() && files->hasFocus()) ||
+ (m && d->moreFiles->isVisible() && d->moreFiles->hasFocus()) ) {
+ if ( c && files->isVisible() )
+ f = c->info;
+ else
+ f = ( (TQFileDialogPrivate::File*)m->i )->info;
+ } else {
+ f = TQUrlInfo( d->url, nameEdit->text() );
+ }
+ if ( f.isDir() ) {
+ setUrl( TQUrlOperator( d->url, TQFileDialogPrivate::encodeFileName(f.name() + "/" ) ) );
+ d->checkForFilter = TRUE;
+ trySetSelection( TRUE, d->url, TRUE );
+ d->checkForFilter = FALSE;
+ } else {
+ if ( !nameEdit->text().tqcontains( "/" ) &&
+ !nameEdit->text().tqcontains( "\\" )
+#if defined(TQ_OS_WIN32)
+ && nameEdit->text()[ 1 ] != ':'
+#endif
+ )
+ addFilter( nameEdit->text() );
+ else if ( nameEdit->text()[ 0 ] == '/' ||
+ nameEdit->text()[ 0 ] == '\\'
+#if defined(TQ_OS_WIN32)
+ || nameEdit->text()[ 1 ] == ':'
+#endif
+ )
+ setDir( nameEdit->text() );
+ else if ( nameEdit->text().left( 3 ) == "../" || nameEdit->text().left( 3 ) == "..\\" )
+ setDir( TQUrl( d->url.toString(), TQFileDialogPrivate::encodeFileName(nameEdit->text() ) ).toString() );
+ }
+ nameEdit->setText( "" );
+ }
+}
+
+/*!
+ \internal
+ Activated when the "Filter" button is clicked.
+*/
+
+void TQFileDialog::filterClicked()
+{
+ // unused
+}
+
+/*!
+ \internal
+ Activated when the "Cancel" button is clicked.
+*/
+
+void TQFileDialog::cancelClicked()
+{
+ *workingDirectory = d->url;
+ detailViewMode = files->isVisible();
+ updateLastSize(this);
+ reject();
+}
+
+
+/*!\reimp
+*/
+
+void TQFileDialog::resizeEvent( TQResizeEvent * e )
+{
+ TQDialog::resizeEvent( e );
+ updateGeometries();
+}
+
+/*
+ \internal
+ The only correct way to try to set currentFileName
+*/
+bool TQFileDialog::trySetSelection( bool isDir, const TQUrlOperator &u, bool updatelined )
+{
+ if ( !isDir && !u.path().isEmpty() && u.path().right( 1 ) == "/" )
+ isDir = TRUE;
+ if ( u.fileName().tqcontains( "*") && d->checkForFilter ) {
+ TQString fn( u.fileName() );
+ if ( fn.tqcontains( "*" ) ) {
+ addFilter( fn );
+ d->currentFileName = TQString::null;
+ d->url.setFileName( TQString::null );
+ nameEdit->setText( TQString::tqfromLatin1("") );
+ return FALSE;
+ }
+ }
+
+ if ( d->preview && d->preview->isVisible() )
+ updatePreviews( u );
+
+ TQString old = d->currentFileName;
+
+ if ( isDirectoryMode( mode() ) ) {
+ if ( isDir )
+ d->currentFileName = u;
+ else
+ d->currentFileName = TQString::null;
+ } else if ( !isDir && mode() == ExistingFiles ) {
+ d->currentFileName = u;
+ } else if ( !isDir || ( mode() == AnyFile && !isDir ) ) {
+ d->currentFileName = u;
+ } else {
+ d->currentFileName = TQString::null;
+ }
+ if ( updatelined && !d->currentFileName.isEmpty() ) {
+ // If the selection is valid, or if its a directory, allow OK.
+ if ( !d->currentFileName.isNull() || isDir ) {
+ if ( u.fileName() != ".." ) {
+ TQString fn = u.fileName();
+ nameEdit->setText( fn );
+ } else {
+ nameEdit->setText("");
+ }
+ } else
+ nameEdit->setText( TQString::tqfromLatin1("") );
+ }
+
+ if ( !d->currentFileName.isNull() || isDir ) {
+ okB->setEnabled( TRUE );
+ } else if ( !isDirectoryMode( d->mode ) ) {
+ okB->setEnabled( FALSE );
+ }
+
+ if ( d->currentFileName.length() && old != d->currentFileName )
+ emit fileHighlighted( selectedFile() );
+
+ return !d->currentFileName.isNull();
+}
+
+
+/*! Make sure the minimum and maximum sizes of everything are sane.
+*/
+
+void TQFileDialog::updateGeometries()
+{
+ if ( !d || !d->tqgeometryDirty )
+ return;
+
+ d->tqgeometryDirty = FALSE;
+
+ TQSize r, t;
+
+ // we really should have a TQSize::unite()
+#define RM r.setWidth( TQMAX(r.width(),t.width()) ); \
+r.setHeight( TQMAX(r.height(),t.height()) )
+
+ // labels first
+ r = d->pathL->tqsizeHint();
+ t = d->fileL->tqsizeHint();
+ RM;
+ t = d->typeL->tqsizeHint();
+ RM;
+ d->pathL->setFixedSize( d->pathL->tqsizeHint() );
+ d->fileL->setFixedSize( r );
+ d->typeL->setFixedSize( r );
+
+ // single-line input areas
+ r = d->paths->tqsizeHint();
+ t = nameEdit->tqsizeHint();
+ RM;
+ t = d->types->tqsizeHint();
+ RM;
+ r.setWidth( t.width() * 2 / 3 );
+ t.setWidth( TQWIDGETSIZE_MAX );
+ t.setHeight( r.height() );
+ d->paths->setMinimumSize( r );
+ d->paths->setMaximumSize( t );
+ nameEdit->setMinimumSize( r );
+ nameEdit->setMaximumSize( t );
+ d->types->setMinimumSize( r );
+ d->types->setMaximumSize( t );
+
+ // buttons on top row
+ r = TQSize( 0, d->paths->tqminimumSize().height() );
+ t = TQSize( 21, 20 );
+ RM;
+ if ( r.height()+1 > r.width() )
+ r.setWidth( r.height()+1 );
+ if ( d->goBack )
+ d->goBack->setFixedSize( r );
+ d->cdToParent->setFixedSize( r );
+ d->newFolder->setFixedSize( r );
+ d->mcView->setFixedSize( r );
+ d->detailView->setFixedSize( r );
+
+ TQButton *b = 0;
+ if ( !d->toolButtons.isEmpty() ) {
+ for ( b = d->toolButtons.first(); b; b = d->toolButtons.next() )
+ b->setFixedSize( b->tqsizeHint().width(), r.height() );
+ }
+
+ if ( d->infoPreview ) {
+ d->previewInfo->show();
+ d->previewInfo->setFixedSize( r );
+ } else {
+ d->previewInfo->hide();
+ d->previewInfo->setFixedSize( TQSize( 0, 0 ) );
+ }
+
+ if ( d->contentsPreview ) {
+ d->previewContents->show();
+ d->previewContents->setFixedSize( r );
+ } else {
+ d->previewContents->hide();
+ d->previewContents->setFixedSize( TQSize( 0, 0 ) );
+ }
+
+ // open/save, cancel
+ r = TQSize( 75, 20 );
+ t = okB->tqsizeHint();
+ RM;
+ t = cancelB->tqsizeHint();
+ RM;
+
+ okB->setFixedSize( r );
+ cancelB->setFixedSize( r );
+
+ d->topLevelLayout->activate();
+
+#undef RM
+}
+
+
+/*! Updates the file name edit box to \a newItem in the file dialog
+ when the cursor moves in the listview.
+*/
+
+void TQFileDialog::updateFileNameEdit( TQListViewItem * newItem )
+{
+ if ( !newItem )
+ return;
+
+ if ( mode() == ExistingFiles ) {
+ detailViewSelectionChanged();
+ TQUrl u( d->url, TQFileDialogPrivate::encodeFileName( ((TQFileDialogPrivate::File*)files->currentItem())->info.name() ) );
+ TQFileInfo fi( u.toString( FALSE, FALSE ) );
+ if ( !fi.isDir() )
+ emit fileHighlighted( u.toString( FALSE, FALSE ) );
+ } else if ( files->isSelected( newItem ) ) {
+ TQFileDialogPrivate::File * i = (TQFileDialogPrivate::File *)newItem;
+ if ( i && i->i && !i->i->isSelected() ) {
+ d->moreFiles->blockSignals( TRUE );
+ d->moreFiles->setSelected( i->i, TRUE );
+ d->moreFiles->blockSignals( FALSE );
+ }
+ // Encode the filename in case it had any special characters in it
+ TQString encFile = TQFileDialogPrivate::encodeFileName( newItem->text( 0 ) );
+ trySetSelection( i->info.isDir(), TQUrlOperator( d->url, encFile ), TRUE );
+ }
+}
+
+void TQFileDialog::detailViewSelectionChanged()
+{
+ if ( d->mode != ExistingFiles )
+ return;
+
+ nameEdit->clear();
+ TQString str;
+ TQListViewItem * i = files->firstChild();
+ d->moreFiles->blockSignals( TRUE );
+ while( i ) {
+ if ( d->moreFiles && isVisible() ) {
+ TQFileDialogPrivate::File *f = (TQFileDialogPrivate::File *)i;
+ if ( f->i && f->i->isSelected() != i->isSelected() )
+ d->moreFiles->setSelected( f->i, i->isSelected() );
+ }
+ if ( i->isSelected() && !( (TQFileDialogPrivate::File *)i )->info.isDir() )
+ str += TQString( "\"%1\" " ).arg( i->text( 0 ) );
+ i = i->nextSibling();
+ }
+ d->moreFiles->blockSignals( FALSE );
+ nameEdit->setText( str );
+ nameEdit->setCursorPosition( str.length() );
+ okB->setEnabled( TRUE );
+ if ( d->preview && d->preview->isVisible() && files->currentItem() ) {
+ TQUrl u = TQUrl( d->url, TQFileDialogPrivate::encodeFileName( ((TQFileDialogPrivate::File*)files->currentItem())->info.name() ) );
+ updatePreviews( u );
+ }
+}
+
+void TQFileDialog::listBoxSelectionChanged()
+{
+ if ( d->mode != ExistingFiles )
+ return;
+
+ if ( d->ignoreNextRefresh ) {
+ d->ignoreNextRefresh = FALSE;
+ return;
+ }
+
+ nameEdit->clear();
+ TQString str;
+ TQListBoxItem * i = d->moreFiles->item( 0 );
+ TQListBoxItem * j = 0;
+ int index = 0;
+ files->blockSignals( TRUE );
+ while( i ) {
+ TQFileDialogPrivate::MCItem *mcitem = (TQFileDialogPrivate::MCItem *)i;
+ if ( files && isVisible() ) {
+ if ( mcitem->i->isSelected() != mcitem->isSelected() ) {
+ files->setSelected( mcitem->i, mcitem->isSelected() );
+
+ // What happens here is that we want to emit signal highlighted for
+ // newly added items. But TQListBox apparently emits selectionChanged even
+ // when a user clicks on the same item twice. So, basically emulate the behaivor
+ // we have in the "Details" view which only emits highlighted the first time we
+ // click on the item. Perhaps at some point we should have a call to
+ // updateFileNameEdit(TQListViewItem) which also emits fileHighlighted() for
+ // ExistingFiles. For better or for worse, this clones the behaivor of the
+ // "Details" view quite well.
+ if ( mcitem->isSelected() && i != d->lastEFSelected ) {
+ TQUrl u( d->url, TQFileDialogPrivate::encodeFileName( ((TQFileDialogPrivate::File*)(mcitem)->i)->info.name()) );
+ d->lastEFSelected = i;
+ emit fileHighlighted( u.toString(FALSE, FALSE) );
+ }
+ }
+ }
+ if ( d->moreFiles->isSelected( i )
+ && !( (TQFileDialogPrivate::File*)(mcitem)->i )->info.isDir() ) {
+ str += TQString( "\"%1\" " ).arg( i->text() );
+ if ( j == 0 )
+ j = i;
+ }
+ i = d->moreFiles->item( ++index );
+ }
+
+ files->blockSignals( FALSE );
+ nameEdit->setText( str );
+ nameEdit->setCursorPosition( str.length() );
+ okB->setEnabled( TRUE );
+ if ( d->preview && d->preview->isVisible() && j ) {
+ TQUrl u = TQUrl( d->url,
+ TQFileDialogPrivate::encodeFileName( ( (TQFileDialogPrivate::File*)( (TQFileDialogPrivate::MCItem*)j )->i )->info.name() ) );
+ updatePreviews( u );
+ }
+}
+
+/*! \overload */
+
+void TQFileDialog::updateFileNameEdit( TQListBoxItem * newItem )
+{
+ if ( !newItem )
+ return;
+ TQFileDialogPrivate::MCItem * i = (TQFileDialogPrivate::MCItem *)newItem;
+ if ( i->i ) {
+ i->i->listView()->setSelected( i->i, i->isSelected() );
+ updateFileNameEdit( i->i );
+ }
+}
+
+
+/*! Updates the dialog when the file name edit changes. */
+
+void TQFileDialog::fileNameEditDone()
+{
+ TQUrlInfo f( d->url, nameEdit->text() );
+ if ( mode() != TQFileDialog::ExistingFiles ) {
+ TQUrlOperator u( d->url, TQFileDialogPrivate::encodeFileName( nameEdit->text() ) );
+ trySetSelection( f.isDir(), u, FALSE );
+ if ( d->preview && d->preview->isVisible() )
+ updatePreviews( u );
+ }
+}
+
+
+
+/*! This private slot reacts to double-clicks in the list view. The item that
+was double-clicked is specified in \a newItem */
+
+void TQFileDialog::selectDirectoryOrFile( TQListViewItem * newItem )
+{
+
+ *workingDirectory = d->url;
+ detailViewMode = files->isVisible();
+ updateLastSize(this);
+
+ if ( !newItem )
+ return;
+
+ if ( d->url.isLocalFile() ) {
+ TQFileInfo fi( d->url.path() + newItem->text(0) );
+#if defined(TQ_WS_WIN)
+ if ( fi.isSymLink() ) {
+ nameEdit->setText( fi.readLink() );
+ okClicked();
+ return;
+ }
+#endif
+ }
+
+ TQFileDialogPrivate::File * i = (TQFileDialogPrivate::File *)newItem;
+
+ TQString oldName = nameEdit->text();
+ if ( i->info.isDir() ) {
+ setUrl( TQUrlOperator( d->url, TQFileDialogPrivate::encodeFileName( i->info.name() ) + "/" ) );
+ if ( isDirectoryMode( mode() ) ) {
+ TQUrlInfo f ( d->url, TQString::tqfromLatin1( "." ) );
+ trySetSelection( f.isDir(), d->url, TRUE );
+ }
+ } else if ( newItem->isSelectable() &&
+ trySetSelection( i->info.isDir(), TQUrlOperator( d->url, TQFileDialogPrivate::encodeFileName( i->info.name() ) ), TRUE ) ) {
+ if ( !isDirectoryMode( mode() ) ) {
+ if ( mode() == ExistingFile ) {
+ if ( TQFileDialogPrivate::fileExists( d->url, nameEdit->text() ) ) {
+ emit fileSelected( selectedFile() );
+ accept();
+ }
+ } else {
+ emit fileSelected( selectedFile() );
+ accept();
+ }
+ }
+ } else if ( isDirectoryMode( d->mode ) ) {
+ d->currentFileName = d->url;
+ accept();
+ }
+ if ( !oldName.isEmpty() && !isDirectoryMode( mode() ) )
+ nameEdit->setText( oldName );
+}
+
+
+void TQFileDialog::selectDirectoryOrFile( TQListBoxItem * newItem )
+{
+ if ( !newItem )
+ return;
+
+ TQFileDialogPrivate::MCItem * i = (TQFileDialogPrivate::MCItem *)newItem;
+ if ( i->i ) {
+ i->i->listView()->setSelected( i->i, i->isSelected() );
+ selectDirectoryOrFile( i->i );
+ }
+}
+
+
+void TQFileDialog::popupContextMenu( TQListViewItem *item, const TQPoint &p,
+ int )
+{
+ if ( item ) {
+ files->setCurrentItem( item );
+ files->setSelected( item, TRUE );
+ }
+
+ PopupAction action;
+ popupContextMenu( item ? item->text( 0 ) : TQString::null, TRUE, action, p );
+
+ if ( action == PA_Open )
+ selectDirectoryOrFile( item );
+ else if ( action == PA_Rename )
+ files->startRename( FALSE );
+ else if ( action == PA_Delete )
+ deleteFile( item ? item->text( 0 ) : TQString::null );
+ else if ( action == PA_Reload )
+ rereadDir();
+ else if ( action == PA_Hidden ) {
+ bShowHiddenFiles = !bShowHiddenFiles;
+ rereadDir();
+ } else if ( action == PA_SortName ) {
+ sortFilesBy = (int)TQDir::Name;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortSize ) {
+ sortFilesBy = (int)TQDir::Size;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortDate ) {
+ sortFilesBy = (int)TQDir::Time;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortUnsorted ) {
+ sortFilesBy = (int)TQDir::Unsorted;
+ sortAscending = TRUE;
+ resortDir();
+ }
+
+}
+
+void TQFileDialog::popupContextMenu( TQListBoxItem *item, const TQPoint & p )
+{
+ PopupAction action;
+ popupContextMenu( item ? item->text() : TQString::null, FALSE, action, p );
+
+ if ( action == PA_Open )
+ selectDirectoryOrFile( item );
+ else if ( action == PA_Rename )
+ d->moreFiles->startRename( FALSE );
+ else if ( action == PA_Delete )
+ deleteFile( item->text() );
+ else if ( action == PA_Reload )
+ rereadDir();
+ else if ( action == PA_Hidden ) {
+ bShowHiddenFiles = !bShowHiddenFiles;
+ rereadDir();
+ } else if ( action == PA_SortName ) {
+ sortFilesBy = (int)TQDir::Name;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortSize ) {
+ sortFilesBy = (int)TQDir::Size;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortDate ) {
+ sortFilesBy = (int)TQDir::Time;
+ sortAscending = TRUE;
+ resortDir();
+ } else if ( action == PA_SortUnsorted ) {
+ sortFilesBy = (int)TQDir::Unsorted;
+ sortAscending = TRUE;
+ resortDir();
+ }
+}
+
+void TQFileDialog::popupContextMenu( const TQString &filename, bool,
+ PopupAction &action, const TQPoint &p )
+{
+ action = PA_Cancel;
+
+ bool glob = filename.isEmpty();
+
+ TQPopupMenu m( 0, "file dialog context menu" );
+ m.setCheckable( TRUE );
+
+ if ( !glob ) {
+ TQString okt;
+ if ( TQUrlInfo( d->url, filename ).isDir() ) {
+ okt = tr( "&Open" );
+ } else {
+ if ( mode() == AnyFile )
+ okt = tr( "&Save" );
+ else
+ okt = tr( "&Open" );
+ }
+ int ok = m.insertItem( okt );
+
+ m.insertSeparator();
+ int rename = m.insertItem( tr( "&Rename" ) );
+ int del = m.insertItem( tr( "&Delete" ) );
+
+ if ( filename.isEmpty() || !TQUrlInfo( d->url, filename ).isWritable() ||
+ filename == ".." ) {
+ if ( filename.isEmpty() || !TQUrlInfo( d->url, filename ).isReadable() )
+ m.setItemEnabled( ok, FALSE );
+ m.setItemEnabled( rename, FALSE );
+ m.setItemEnabled( del, FALSE );
+ }
+
+ m.move( p );
+ int res = m.exec();
+
+ if ( res == ok )
+ action = PA_Open;
+ else if ( res == rename )
+ action = PA_Rename;
+ else if ( res == del )
+ action = PA_Delete;
+ } else {
+ int reload = m.insertItem( tr( "R&eload" ) );
+
+ TQPopupMenu m2( 0, "sort menu" );
+
+ int sname = m2.insertItem( tr( "Sort by &Name" ) );
+ //int stype = m2.insertItem( tr( "Sort by &Type" ) );
+ int ssize = m2.insertItem( tr( "Sort by &Size" ) );
+ int sdate = m2.insertItem( tr( "Sort by &Date" ) );
+ m2.insertSeparator();
+ int sunsorted = m2.insertItem( tr( "&Unsorted" ) );
+
+ //m2.setItemEnabled( stype, FALSE );
+
+ if ( sortFilesBy == (int)TQDir::Name )
+ m2.setItemChecked( sname, TRUE );
+ else if ( sortFilesBy == (int)TQDir::Size )
+ m2.setItemChecked( ssize, TRUE );
+// else if ( sortFilesBy == 0x16 )
+// m2.setItemChecked( stype, TRUE );
+ else if ( sortFilesBy == (int)TQDir::Time )
+ m2.setItemChecked( sdate, TRUE );
+ else if ( sortFilesBy == (int)TQDir::Unsorted )
+ m2.setItemChecked( sunsorted, TRUE );
+
+ m.insertItem( tr( "Sort" ), &m2 );
+
+ m.insertSeparator();
+
+ int hidden = m.insertItem( tr( "Show &hidden files" ) );
+ m.setItemChecked( hidden, bShowHiddenFiles );
+
+ m.move( p );
+ int res = m.exec();
+
+ if ( res == reload )
+ action = PA_Reload;
+ else if ( res == hidden )
+ action = PA_Hidden;
+ else if ( res == sname )
+ action = PA_SortName;
+// else if ( res == stype )
+// action = PA_SortType;
+ else if ( res == sdate )
+ action = PA_SortDate;
+ else if ( res == ssize )
+ action = PA_SortSize;
+ else if ( res == sunsorted )
+ action = PA_SortUnsorted;
+ }
+
+}
+
+void TQFileDialog::deleteFile( const TQString &filename )
+{
+ if ( filename.isEmpty() )
+ return;
+
+ TQUrlInfo fi( d->url, TQFileDialogPrivate::encodeFileName( filename ) );
+ TQString t = tr( "the file" );
+ if ( fi.isDir() )
+ t = tr( "the directory" );
+ if ( fi.isSymLink() )
+ t = tr( "the symlink" );
+
+ if ( TQMessageBox::warning( this,
+ tr( "Delete %1" ).arg( t ),
+ tr( "<qt>Are you sure you wish to delete %1 \"%2\"?</qt>" )
+ .arg( t ).arg(filename),
+ tr( "&Yes" ), tr( "&No" ), TQString::null, 1 ) == 0 )
+ d->url.remove( TQFileDialogPrivate::encodeFileName( filename ) );
+
+}
+
+void TQFileDialog::fileSelected( int )
+{
+ // unused
+}
+
+void TQFileDialog::fileHighlighted( int )
+{
+ // unused
+}
+
+void TQFileDialog::dirSelected( int )
+{
+ // unused
+}
+
+void TQFileDialog::pathSelected( int )
+{
+ // unused
+}
+
+
+void TQFileDialog::cdUpClicked()
+{
+ TQString oldName = nameEdit->text();
+ setUrl( TQUrlOperator( d->url, ".." ) );
+ if ( !oldName.isEmpty() )
+ nameEdit->setText( oldName );
+}
+
+void TQFileDialog::newFolderClicked()
+{
+ TQString foldername( tr( "New Folder 1" ) );
+ int i = 0;
+ TQStringList lst;
+ TQListViewItemIterator it( files );
+ for ( ; it.current(); ++it )
+ if ( it.current()->text( 0 ).tqcontains( tr( "New Folder" ) ) )
+ lst.append( it.current()->text( 0 ) );
+
+ if ( !lst.count() == 0 )
+ while ( lst.tqcontains( foldername ) )
+ foldername = tr( "New Folder %1" ).arg( ++i );
+
+ d->url.mkdir( foldername );
+}
+
+void TQFileDialog::createdDirectory( const TQUrlInfo &info, TQNetworkOperation * )
+{
+ resortDir();
+ if ( d->moreFiles->isVisible() ) {
+ for ( uint i = 0; i < d->moreFiles->count(); ++i ) {
+ if ( d->moreFiles->text( i ) == info.name() ) {
+ d->moreFiles->setCurrentItem( i );
+ d->moreFiles->startRename( FALSE );
+ break;
+ }
+ }
+ } else {
+ TQListViewItem *item = files->firstChild();
+ while ( item ) {
+ if ( item->text( 0 ) == info.name() ) {
+ files->setSelected( item, TRUE );
+ files->setCurrentItem( item );
+ files->startRename( FALSE );
+ break;
+ }
+ item = item->nextSibling();
+ }
+ }
+}
+
+
+/*!
+ This is a convenience static function that will return an existing directory
+ selected by the user.
+
+ \code
+ TQString s = TQFileDialog::getExistingDirectory(
+ "/home",
+ this,
+ "get existing directory",
+ "Choose a directory",
+ TRUE );
+ \endcode
+
+ This function creates a modal file dialog called \a name, with
+ tqparent, \a tqparent. If tqparent is not 0, the dialog will be shown
+ centered over the tqparent.
+
+ The dialog's working directory is set to \a dir, and the caption is
+ set to \a caption. Either of these may be TQString::null in which case
+ the current directory and a default caption will be used respectively.
+
+ Note on Windows that if \a dir is TQString::null then the dialog's working
+ directory will be set to the user's My Documents directory.
+
+ If \a dirOnly is TRUE, then only directories will be shown in
+ the file dialog; otherwise both directories and files will be shown.
+
+ Under Unix/X11, the normal behavior of the file dialog is to resolve
+ and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp,
+ the file dialog will change to /var/tmp after entering /usr/tmp.
+ If \a resolveSymlinks is FALSE, the file dialog will treat
+ symlinks as regular directories.
+
+ Under Windows and Mac OS X, this static function will use the native
+ file dialog and not a TQFileDialog, unless the style of the application
+ is set to something other than the native style. (Note that on Windows the
+ dialog will spin a blocking modal event loop that will not dispatch any
+ TQTimers and if tqparent is not 0 then it will position the dialog just under
+ the tqparent's titlebar).
+
+ \sa getOpenFileName(), getOpenFileNames(), getSaveFileName()
+*/
+
+TQString TQFileDialog::getExistingDirectory( const TQString & dir,
+ TQWidget *tqparent,
+ const char* name,
+ const TQString& caption,
+ bool dirOnly,
+ bool resolveSymlinks)
+{
+ bool save_qt_resolve_symlinks = qt_resolve_symlinks;
+ qt_resolve_symlinks = resolveSymlinks;
+
+ makeVariables();
+ TQString wd;
+ if ( workingDirectory )
+ wd = *workingDirectory;
+
+#if defined(TQ_WS_WIN)
+ TQString initialDir;
+ if ( !dir.isEmpty() ) {
+ TQUrlOperator u( dir );
+ if ( TQFileInfo( u.path() ).isDir() )
+ initialDir = dir;
+ } else
+ initialDir = TQString::null;
+ if ( qt_use_native_dialogs && tqApp->tqstyle().tqstyleHint( TQStyle::SH_GUIStyle ) == WindowsStyle && dirOnly )
+ return winGetExistingDirectory( initialDir, tqparent, name, caption );
+#endif
+#if defined(TQ_WS_MAC)
+ TQString *initialDir = 0;
+ if (!dir.isEmpty()) {
+ TQUrlOperator u(dir);
+ if (TQFileInfo(u.path()).isDir())
+ initialDir = (TQString *)&dir;
+ }
+ if( qt_use_native_dialogs && (tqApp->tqstyle().inherits(TQMAC_DEFAULT_STYLE)
+ || tqApp->tqstyle().inherits("TQMacStyle")))
+ return qt_mac_precomposeFileName(macGetOpenFileNames("", initialDir, tqparent, name,
+ caption, 0, FALSE, TRUE).first());
+#endif
+
+ TQFileDialog *dlg = new TQFileDialog( tqparent, name ? name : "qt_filedlg_ged", TRUE );
+
+ TQ_CHECK_PTR( dlg );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( !caption.isNull() )
+ dlg->setCaption( caption );
+ else
+ dlg->setCaption( TQFileDialog::tqtr("Find Directory") );
+#endif
+
+ dlg->setMode( dirOnly ? DirectoryOnly : Directory );
+
+ dlg->d->types->clear();
+ dlg->d->types->insertItem( TQFileDialog::tqtr("Directories") );
+ dlg->d->types->setEnabled( FALSE );
+
+ TQString dir_( dir );
+ dir_ = dir_.simplifyWhiteSpace();
+ if ( dir_.isEmpty() && !wd.isEmpty() )
+ dir_ = wd;
+ TQUrlOperator u( dir_ );
+ if ( u.isLocalFile() ) {
+ if ( !dir_.isEmpty() ) {
+ TQFileInfo f( u.path() );
+ if ( f.exists() )
+ if ( f.isDir() ) {
+ dlg->setDir( dir_ );
+ wd = dir_;
+ }
+ } else if ( !wd.isEmpty() ) {
+ TQUrl tempUrl( wd );
+ TQFileInfo f( tempUrl.path() );
+ if ( f.isDir() ) {
+ dlg->setDir( wd );
+ }
+ } else {
+ TQString theDir = dir_;
+ if ( theDir.isEmpty() ) {
+ theDir = ::toRootIfNotExists( TQDir::currentDirPath() );
+ } if ( !theDir.isEmpty() ) {
+ TQUrl tempUrl( theDir );
+ TQFileInfo f( tempUrl.path() );
+ if ( f.isDir() ) {
+ wd = theDir;
+ dlg->setDir( theDir );
+ }
+ }
+ }
+ } else {
+ dlg->setUrl( dir_ );
+ }
+
+ TQString result;
+ dlg->setSelection( dlg->d->url.toString() );
+
+ if ( dlg->exec() == TQDialog::Accepted ) {
+ result = dlg->selectedFile();
+ wd = result;
+ }
+ delete dlg;
+
+ if ( !result.isEmpty() && result.right( 1 ) != "/" )
+ result += "/";
+
+ qt_resolve_symlinks = save_qt_resolve_symlinks;
+
+ return result;
+}
+
+
+/*!
+ \property TQFileDialog::mode
+ \brief the file dialog's mode
+
+ The default mode is \c ExistingFile.
+*/
+
+void TQFileDialog::setMode( Mode newMode )
+{
+ if ( d->mode != newMode ) {
+ d->mode = newMode;
+ TQString sel = d->currentFileName;
+ int maxnamelen = 255; // _POSIX_MAX_PATH
+ if ( isDirectoryMode( newMode ) ) {
+ files->setSelectionMode( TQListView::Single );
+ d->moreFiles->setSelectionMode( TQListBox::Single );
+ if ( sel.isNull() )
+ sel = TQString::tqfromLatin1(".");
+ d->types->setEnabled( FALSE );
+ } else if ( newMode == ExistingFiles ) {
+ maxnamelen = INT_MAX;
+ files->setSelectionMode( TQListView::Extended );
+ d->moreFiles->setSelectionMode( TQListBox::Extended );
+ d->types->setEnabled( TRUE );
+ } else {
+ files->setSelectionMode( TQListView::Single );
+ d->moreFiles->setSelectionMode( TQListBox::Single );
+ d->types->setEnabled( TRUE );
+ }
+ nameEdit->setMaxLength(maxnamelen);
+ rereadDir();
+ TQUrlInfo f( d->url, "." );
+ trySetSelection( f.isDir(), d->url, FALSE );
+ }
+
+ TQString okt;
+ bool changeFilters = FALSE;
+ if ( mode() == AnyFile ) {
+ okt = tr("&Save");
+ d->fileL->setText( tr("File &name:") );
+ if ( d->types->count() == 1 ) {
+ d->types->setCurrentItem( 0 );
+ if ( d->types->currentText() == "Directories" ) {
+ changeFilters = TRUE;
+ }
+ }
+ }
+ else if ( mode() == Directory || mode() == DirectoryOnly ) {
+ okt = tr("&OK");
+ d->fileL->setText( tr("Directory:") );
+ d->types->clear();
+ d->types->insertItem( tqtr("Directories") );
+ }
+ else {
+ okt = tr("&Open");
+ d->fileL->setText( tqtr("File &name:") );
+ if ( d->types->count() == 1 ) {
+ d->types->setCurrentItem( 0 );
+ if ( d->types->currentText() == "Directories" ) {
+ changeFilters = TRUE;
+ }
+ }
+ }
+
+ if ( changeFilters ) {
+ d->types->clear();
+ d->types->insertItem( tqtr("All Files (*)") );
+ }
+
+ okB->setText( okt );
+}
+
+TQFileDialog::Mode TQFileDialog::mode() const
+{
+ return d->mode;
+}
+
+/*! \reimp
+*/
+
+void TQFileDialog::done( int i )
+{
+ if ( i == TQDialog::Accepted && (d->mode == ExistingFile || d->mode == ExistingFiles) ) {
+ TQStringList selection = selectedFiles();
+ for ( uint f = 0; f < selection.count(); f++ ) {
+ TQString file = selection[f];
+ if ( file.isNull() )
+ continue;
+ if ( d->url.isLocalFile() && !TQFile::exists( file ) ) {
+ TQMessageBox::information( this, tr("Error"),
+ tr("%1\nFile not found.\nCheck path and filename.").arg( file ) );
+ return;
+ }
+ }
+ }
+ TQDialog::done( i );
+}
+
+/*!
+ \property TQFileDialog::viewMode
+
+ \brief the file dialog's view mode
+
+ If you set the view mode to be \e Detail (the default), then you
+ will see the file's details, such as the size of the file and the
+ date the file was last modified in addition to the file's name.
+
+ If you set the view mode to be \e List, then you will just
+ see a list of the files and folders.
+
+ See \l TQFileDialog::ViewMode
+*/
+
+
+TQFileDialog::ViewMode TQFileDialog::viewMode() const
+{
+ if ( detailViewMode )
+ return Detail;
+ else
+ return List;
+}
+
+void TQFileDialog::setViewMode( ViewMode m )
+{
+ if ( m == Detail ) {
+ detailViewMode = TRUE;
+ d->stack->raiseWidget( files );
+ d->detailView->setOn( TRUE );
+ d->mcView->setOn( FALSE );
+ } else if ( m == List ) {
+ detailViewMode = FALSE;
+ d->stack->raiseWidget( d->moreFiles );
+ d->detailView->setOn( FALSE );
+ d->mcView->setOn( TRUE );
+ }
+}
+
+
+/*!
+ \property TQFileDialog::previewMode
+
+ \brief the preview mode for the file dialog
+
+ If you set the mode to be a mode other than \e NoPreview, you must
+ use setInfoPreview() or setContentsPreview() to set the dialog's
+ preview widget to your preview widget and enable the preview
+ widget(s) with setInfoPreviewEnabled() or
+ setContentsPreviewEnabled().
+
+ \sa infoPreview, contentsPreview, viewMode
+*/
+
+void TQFileDialog::setPreviewMode( PreviewMode m )
+{
+ if ( m == NoPreview ) {
+ d->previewInfo->setOn( FALSE );
+ d->previewContents->setOn( FALSE );
+ } else if ( m == Info && d->infoPreview ) {
+ d->previewInfo->setOn( TRUE );
+ d->previewContents->setOn( FALSE );
+ changeMode( d->modeButtons->id( d->previewInfo ) );
+ } else if ( m == Contents && d->contentsPreview ) {
+ d->previewInfo->setOn( FALSE );
+ d->previewContents->setOn( TRUE );
+ changeMode( d->modeButtons->id( d->previewContents ) );
+ }
+}
+TQFileDialog::PreviewMode TQFileDialog::previewMode() const
+{
+ if ( d->infoPreview && d->infoPreviewWidget->isVisible() )
+ return Info;
+ else if ( d->contentsPreview && d->contentsPreviewWidget->isVisible() )
+ return Contents;
+
+ return NoPreview;
+}
+
+
+/*!
+ Adds the specified widgets to the bottom of the file dialog. The
+ label \a l is placed underneath the "file name" and the "file types"
+ labels. The widget \a w is placed underneath the file types combobox.
+ The button \a b is placed underneath the Cancel pushbutton.
+
+ \code
+ MyFileDialog::MyFileDialog( TQWidget* tqparent, const char* name ) :
+ TQFileDialog( tqparent, name )
+ {
+ TQLabel* label = new TQLabel( "Added widgets", this );
+ TQLineEdit* lineedit = new TQLineEdit( this );
+ TQPushButton* pushbutton = new TQPushButton( this );
+
+ addWidgets( label, lineedit, pushbutton );
+ }
+ \endcode
+
+ If you don't want to have one of the widgets added, pass 0 in that
+ widget's position.
+
+ Every time you call this function, a new row of widgets will be added
+ to the bottom of the file dialog.
+
+ \sa addToolButton(), addLeftWidget(), addRightWidget()
+*/
+
+void TQFileDialog::addWidgets( TQLabel * l, TQWidget * w, TQPushButton * b )
+{
+ if ( !l && !w && !b )
+ return;
+
+ d->tqgeometryDirty = TRUE;
+
+ TQHBoxLayout *lay = new TQHBoxLayout();
+ d->extraWidgetsLayouts.append( lay );
+ d->topLevelLayout->addLayout( lay );
+
+ if ( !l )
+ l = new TQLabel( this, "qt_intern_lbl" );
+ d->extraLabels.append( l );
+ lay->addWidget( l );
+
+ if ( !w )
+ w = new TQWidget( this, "qt_intern_widget" );
+ d->extraWidgets.append( w );
+ lay->addWidget( w );
+ lay->addSpacing( 15 );
+
+ if ( b ) {
+ d->extraButtons.append( b );
+ lay->addWidget( b );
+ } else {
+ TQWidget *wid = new TQWidget( this, "qt_extrabuttons_widget" );
+ d->extraButtons.append( wid );
+ lay->addWidget( wid );
+ }
+
+ updateGeometries();
+}
+
+/*!
+ Adds the tool button \a b to the row of tool buttons at the top of the
+ file dialog. The button is appended to the right of
+ this row. If \a separator is TRUE, a small space is inserted between the
+ last button of the row and the new button \a b.
+
+ \sa addWidgets(), addLeftWidget(), addRightWidget()
+*/
+
+void TQFileDialog::addToolButton( TQButton *b, bool separator )
+{
+ if ( !b || !d->buttonLayout )
+ return;
+
+ d->tqgeometryDirty = TRUE;
+
+ d->toolButtons.append( b );
+ if ( separator )
+ d->buttonLayout->addSpacing( 8 );
+ d->buttonLayout->addWidget( b );
+
+ updateGeometries();
+}
+
+/*!
+ Adds the widget \a w to the left-hand side of the file dialog.
+
+ \sa addRightWidget(), addWidgets(), addToolButton()
+*/
+
+void TQFileDialog::addLeftWidget( TQWidget *w )
+{
+ if ( !w )
+ return;
+ d->tqgeometryDirty = TRUE;
+
+ d->leftLayout->addWidget( w );
+ d->leftLayout->addSpacing( 5 );
+
+ updateGeometries();
+}
+
+/*!
+ Adds the widget \a w to the right-hand side of the file dialog.
+
+ \sa addLeftWidget(), addWidgets(), addToolButton()
+*/
+
+void TQFileDialog::addRightWidget( TQWidget *w )
+{
+ if ( !w )
+ return;
+ d->tqgeometryDirty = TRUE;
+
+ d->rightLayout->addSpacing( 5 );
+ d->rightLayout->addWidget( w );
+
+ updateGeometries();
+}
+
+/*! \reimp */
+
+void TQFileDialog::keyPressEvent( TQKeyEvent * ke )
+{
+ if ( !d->ignoreNextKeyPress &&
+ ke && ( ke->key() == Qt::Key_Enter ||
+ ke->key() == Qt::Key_Return ) ) {
+ ke->ignore();
+ if ( d->paths->hasFocus() ) {
+ ke->accept();
+ if ( d->url == TQUrl(d->paths->currentText()) )
+ nameEdit->setFocus();
+ } else if ( d->types->hasFocus() ) {
+ ke->accept();
+ // ### is there a suitable condition for this? only valid
+ // wildcards?
+ nameEdit->setFocus();
+ } else if ( nameEdit->hasFocus() ) {
+ if ( d->currentFileName.isNull() ) {
+ // maybe change directory
+ TQUrlInfo i( d->url, nameEdit->text() );
+ if ( i.isDir() ) {
+ nameEdit->setText( TQString::tqfromLatin1("") );
+ setDir( TQUrlOperator( d->url, TQFileDialogPrivate::encodeFileName(i.name()) ) );
+ }
+ ke->accept();
+ } else if ( mode() == ExistingFiles ) {
+ TQUrlInfo i( d->url, nameEdit->text() );
+ if ( i.isFile() ) {
+ TQListViewItem * i = files->firstChild();
+ while ( i && nameEdit->text() != i->text( 0 ) )
+ i = i->nextSibling();
+ if ( i )
+ files->setSelected( i, TRUE );
+ else
+ ke->accept(); // strangely, means to ignore that event
+ }
+ }
+ } else if ( files->hasFocus() || d->moreFiles->hasFocus() ) {
+ ke->accept();
+ }
+ } else if ( ke->key() == Key_Escape ) {
+ ke->ignore();
+ }
+
+ d->ignoreNextKeyPress = FALSE;
+
+ if ( !ke->isAccepted() ) {
+ TQDialog::keyPressEvent( ke );
+ }
+}
+
+
+/*! \class TQFileIconProvider tqfiledialog.h
+
+ \brief The TQFileIconProvider class provides icons for TQFileDialog to
+ use.
+
+ \ingroup misc
+
+ By default TQFileIconProvider is not used, but any application or
+ library can subclass it, reimplement pixmap() to return a suitable
+ icon, and make all TQFileDialog objects use it by calling the static
+ function TQFileDialog::setIconProvider().
+
+ It is advisable to make all the icons that TQFileIconProvider returns be
+ the same size or at least the same width. This makes the list view
+ look much better.
+
+ \sa TQFileDialog
+*/
+
+
+/*! Constructs an empty file icon provider called \a name, with the
+ tqparent \a tqparent.
+*/
+
+TQFileIconProvider::TQFileIconProvider( TQObject * tqparent, const char* name )
+ : TQObject( tqparent, name )
+{
+ // nothing necessary
+}
+
+
+/*!
+ Returns a pointer to a pixmap that should be used to
+ signify the file with the information \a info.
+
+ If pixmap() returns 0, TQFileDialog draws the default pixmap.
+
+ The default implementation returns particular icons for files, directories,
+ link-files and link-directories. It returns a blank "icon" for other types.
+
+ If you return a pixmap here, it should measure 16x16 pixels.
+*/
+
+const TQPixmap * TQFileIconProvider::pixmap( const TQFileInfo & info )
+{
+ if ( info.isSymLink() ) {
+ if ( info.isFile() )
+ return symLinkFileIcon;
+ else
+ return symLinkDirIcon;
+ } else if ( info.isDir() ) {
+ return closedFolderIcon;
+ } else if ( info.isFile() ) {
+ return fileIcon;
+ } else {
+ return fifteenTransparentPixels;
+ }
+}
+
+/*!
+ Sets the TQFileIconProvider used by the file dialog to \a provider.
+
+ The default is that there is no TQFileIconProvider and TQFileDialog
+ just draws a folder icon next to each directory and nothing next
+ to files.
+
+ \sa TQFileIconProvider, iconProvider()
+*/
+
+void TQFileDialog::setIconProvider( TQFileIconProvider * provider )
+{
+ fileIconProvider = provider;
+}
+
+
+/*!
+ Returns a pointer to the icon provider currently set on the file dialog.
+ By default there is no icon provider, and this function returns 0.
+
+ \sa setIconProvider(), TQFileIconProvider
+*/
+
+TQFileIconProvider * TQFileDialog::iconProvider()
+{
+ return fileIconProvider;
+}
+
+
+#if defined(TQ_WS_WIN)
+
+// ### FIXME: this code is duplicated in qdns.cpp
+static TQString getWindowsRegString( HKEY key, const TQString &subKey )
+{
+ TQString s;
+ TQT_WA( {
+ char buf[1024];
+ DWORD bsz = sizeof(buf);
+ int r = RegQueryValueEx( key, (TCHAR*)subKey.ucs2(), 0, 0, (LPBYTE)buf, &bsz );
+ if ( r == ERROR_SUCCESS ) {
+ s = TQString::fromUcs2( (unsigned short *)buf );
+ } else if ( r == ERROR_MORE_DATA ) {
+ char *ptr = new char[bsz+1];
+ r = RegQueryValueEx( key, (TCHAR*)subKey.ucs2(), 0, 0, (LPBYTE)ptr, &bsz );
+ if ( r == ERROR_SUCCESS )
+ s = ptr;
+ delete [] ptr;
+ }
+ } , {
+ char buf[512];
+ DWORD bsz = sizeof(buf);
+ int r = RegQueryValueExA( key, subKey.local8Bit(), 0, 0, (LPBYTE)buf, &bsz );
+ if ( r == ERROR_SUCCESS ) {
+ s = buf;
+ } else if ( r == ERROR_MORE_DATA ) {
+ char *ptr = new char[bsz+1];
+ r = RegQueryValueExA( key, subKey.local8Bit(), 0, 0, (LPBYTE)ptr, &bsz );
+ if ( r == ERROR_SUCCESS )
+ s = ptr;
+ delete [] ptr;
+ }
+ } );
+ return s;
+}
+
+static void initPixmap( TQPixmap &pm )
+{
+ pm.fill( TQt::white );
+}
+
+
+TQWindowsIconProvider::TQWindowsIconProvider( TQObject *tqparent, const char *name )
+ : TQFileIconProvider( tqparent, name )
+{
+ pixw = GetSystemMetrics( SM_CXSMICON );
+ pixh = GetSystemMetrics( SM_CYSMICON );
+
+ HKEY k;
+ HICON si;
+ int r;
+ TQString s;
+ UINT res = 0;
+
+ // ---------- get default folder pixmap
+ const wchar_t iconFolder[] = L"folder\\DefaultIcon"; // workaround for Borland
+ TQT_WA( {
+ r = RegOpenKeyEx( HKEY_CLASSES_ROOT,
+ iconFolder,
+ 0, KEY_READ, &k );
+ } , {
+ r = RegOpenKeyExA( HKEY_CLASSES_ROOT,
+ "folder\\DefaultIcon",
+ 0, KEY_READ, &k );
+ } );
+ resolveLibs();
+ if ( r == ERROR_SUCCESS ) {
+ s = getWindowsRegString( k, TQString::null );
+ RegCloseKey( k );
+
+ TQStringList lst = TQStringList::split( ",", s );
+
+ if (lst.count() >= 2) { // don't just assume that lst has two entries
+#ifndef TQ_OS_TEMP
+ TQT_WA( {
+ res = ptrExtractIconEx( (TCHAR*)lst[ 0 ].simplifyWhiteSpace().ucs2(),
+ lst[ 1 ].simplifyWhiteSpace().toInt(),
+ 0, &si, 1 );
+ } , {
+ res = ExtractIconExA( lst[ 0 ].simplifyWhiteSpace().local8Bit(),
+ lst[ 1 ].simplifyWhiteSpace().toInt(),
+ 0, &si, 1 );
+ } );
+#else
+ res = (UINT)ExtractIconEx( (TCHAR*)lst[ 0 ].simplifyWhiteSpace().ucs2(),
+ lst[ 1 ].simplifyWhiteSpace().toInt(),
+ 0, &si, 1 );
+#endif
+ }
+ if ( res ) {
+ defaultFolder.resize( pixw, pixh );
+ initPixmap( defaultFolder );
+ TQPainter p( &defaultFolder );
+ DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, 0, DI_NORMAL );
+ p.end();
+ defaultFolder.setMask( defaultFolder.createHeuristicMask() );
+ *closedFolderIcon = defaultFolder;
+ DestroyIcon( si );
+ } else {
+ defaultFolder = *closedFolderIcon;
+ }
+ } else {
+ RegCloseKey( k );
+ }
+
+ //------------------------------- get default file pixmap
+#ifndef TQ_OS_TEMP
+ TQT_WA( {
+ res = ptrExtractIconEx( L"shell32.dll",
+ 0, 0, &si, 1 );
+ } , {
+ res = ExtractIconExA( "shell32.dll",
+ 0, 0, &si, 1 );
+ } );
+#else
+ res = (UINT)ExtractIconEx( L"shell32.dll",
+ 0, 0, &si, 1 );
+#endif
+
+ if ( res ) {
+ defaultFile.resize( pixw, pixh );
+ initPixmap( defaultFile );
+ TQPainter p( &defaultFile );
+ DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, 0, DI_NORMAL );
+ p.end();
+ defaultFile.setMask( defaultFile.createHeuristicMask() );
+ *fileIcon = defaultFile;
+ DestroyIcon( si );
+ } else {
+ defaultFile = *fileIcon;
+ }
+
+ //------------------------------- get default exe pixmap
+#ifndef TQ_OS_TEMP
+ TQT_WA( {
+ res = ptrExtractIconEx( L"shell32.dll",
+ 2, 0, &si, 1 );
+ } , {
+ res = ExtractIconExA( "shell32.dll",
+ 2, 0, &si, 1 );
+ } );
+#else
+ res = (UINT)ExtractIconEx( L"ceshell.dll",
+ 10, 0, &si, 1 );
+#endif
+
+ if ( res ) {
+ defaultExe.resize( pixw, pixh );
+ initPixmap( defaultExe );
+ TQPainter p( &defaultExe );
+ DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, 0, DI_NORMAL );
+ p.end();
+ defaultExe.setMask( defaultExe.createHeuristicMask() );
+ DestroyIcon( si );
+ } else {
+ defaultExe = *fileIcon;
+ }
+}
+
+TQWindowsIconProvider::~TQWindowsIconProvider()
+{
+ if ( this == fileIconProvider )
+ fileIconProvider = 0;
+}
+
+const TQPixmap * TQWindowsIconProvider::pixmap( const TQFileInfo &fi )
+{
+ if (fi.isSymLink()) {
+ TQString real = fi.readLink();
+ if (!real.isEmpty())
+ return pixmap(TQFileInfo(real));
+ }
+
+ TQString ext = fi.extension( FALSE ).upper();
+ TQString key = ext;
+ ext.prepend( "." );
+ TQMap< TQString, TQPixmap >::Iterator it;
+
+ if ( fi.isDir() ) {
+ return &defaultFolder;
+ } else if ( ext != ".EXE" ) {
+ it = cache.tqfind( key );
+ if ( it != cache.end() )
+ return &( *it );
+
+ HKEY k, k2;
+ int r;
+ TQT_WA( {
+ r = RegOpenKeyEx( HKEY_CLASSES_ROOT, (TCHAR*)ext.ucs2(),
+ 0, KEY_READ, &k );
+ } , {
+ r = RegOpenKeyExA( HKEY_CLASSES_ROOT, ext.local8Bit(),
+ 0, KEY_READ, &k );
+ } );
+ TQString s;
+ if ( r == ERROR_SUCCESS ) {
+ s = getWindowsRegString( k, TQString::null );
+ } else {
+ cache[ key ] = defaultFile;
+ RegCloseKey( k );
+ return &defaultFile;
+ }
+ RegCloseKey( k );
+
+ TQT_WA( {
+ r = RegOpenKeyEx( HKEY_CLASSES_ROOT, (TCHAR*)TQString( s + "\\DefaultIcon" ).ucs2(),
+ 0, KEY_READ, &k2 );
+ } , {
+ r = RegOpenKeyExA( HKEY_CLASSES_ROOT, TQString( s + "\\DefaultIcon" ).local8Bit() ,
+ 0, KEY_READ, &k2 );
+ } );
+ if ( r == ERROR_SUCCESS ) {
+ s = getWindowsRegString( k2, TQString::null );
+ } else {
+ cache[ key ] = defaultFile;
+ RegCloseKey( k2 );
+ return &defaultFile;
+ }
+ RegCloseKey( k2 );
+
+ TQStringList lst = TQStringList::split( ",", s );
+
+ HICON si;
+ UINT res = 0;
+ if (lst.count() >= 2) { // don't just assume that lst has two entries
+ TQString filepath = lst[ 0 ].stripWhiteSpace();
+ if ( !filepath.isEmpty() ) {
+ if ( filepath.tqfind("%1") != -1 ) {
+ filepath = filepath.arg( fi.filePath() );
+ if ( ext == ".DLL" ) {
+ pix = defaultFile;
+ return &pix;
+ }
+ }
+ if ( filepath[0] == '"' && filepath[(int)filepath.length()-1] == '"' )
+ filepath = filepath.mid( 1, filepath.length()-2 );
+
+ resolveLibs();
+#ifndef TQ_OS_TEMP
+ TQT_WA( {
+ res = ptrExtractIconEx( (TCHAR*)filepath.ucs2(), lst[ 1 ].stripWhiteSpace().toInt(),
+ 0, &si, 1 );
+ } , {
+ res = ExtractIconExA( filepath.local8Bit(), lst[ 1 ].stripWhiteSpace().toInt(),
+ 0, &si, 1 );
+ } );
+#else
+ res = (UINT)ExtractIconEx( (TCHAR*)filepath.ucs2(), lst[ 1 ].stripWhiteSpace().toInt(),
+ 0, &si, 1 );
+#endif
+ }
+ }
+
+ if ( res ) {
+ pix.resize( pixw, pixh );
+ initPixmap( pix );
+ TQPainter p( &pix );
+ DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, 0, DI_NORMAL );
+ p.end();
+ pix.setMask( pix.createHeuristicMask() );
+ DestroyIcon( si );
+ } else {
+ pix = defaultFile;
+ }
+
+ cache[ key ] = pix;
+ return &pix;
+ } else {
+ HICON si;
+ UINT res = 0;
+ if ( !fi.absFilePath().isEmpty() ) {
+#ifndef TQ_OS_TEMP
+ TQT_WA( {
+ res = ptrExtractIconEx( (TCHAR*)fi.absFilePath().ucs2(), -1,
+ 0, 0, 1 );
+ } , {
+ res = ExtractIconExA( fi.absFilePath().local8Bit(), -1,
+ 0, 0, 1 );
+ } );
+
+ if ( res ) {
+ TQT_WA( {
+ res = ptrExtractIconEx( (TCHAR*)fi.absFilePath().ucs2(), res - 1,
+ 0, &si, 1 );
+ } , {
+ res = ExtractIconExA( fi.absFilePath().local8Bit(), res - 1,
+ 0, &si, 1 );
+ } );
+ }
+#else
+ res = (UINT)ExtractIconEx( (TCHAR*)fi.absFilePath().ucs2(), -1,
+ 0, 0, 1 );
+ if ( res )
+ res = (UINT)ExtractIconEx( (TCHAR*)fi.absFilePath().ucs2(), res - 1,
+ 0, &si, 1 );
+#endif
+
+ }
+
+ if ( res ) {
+ pix.resize( pixw, pixh );
+ initPixmap( pix );
+ TQPainter p( &pix );
+ DrawIconEx( p.handle(), 0, 0, si, pixw, pixh, 0, 0, DI_NORMAL );
+ p.end();
+ pix.setMask( pix.createHeuristicMask() );
+ DestroyIcon( si );
+ } else {
+ pix = defaultExe;
+ }
+
+ return &pix;
+ }
+
+ // can't happen!
+ return 0;
+}
+#endif
+
+
+
+/*!
+ \reimp
+*/
+bool TQFileDialog::eventFilter( TQObject * o, TQEvent * e )
+{
+ if ( e->type() == TQEvent::KeyPress && ( (TQKeyEvent*)e )->key() == Qt::Key_F5 ) {
+ rereadDir();
+ ((TQKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == TQEvent::KeyPress && ( (TQKeyEvent*)e )->key() == Qt::Key_F2 &&
+ ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(files) || TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(files->viewport()) ) ) {
+ if ( files->isVisible() && files->currentItem() ) {
+ if ( TQUrlInfo( d->url, "." ).isWritable() && files->currentItem()->text( 0 ) != ".." ) {
+ files->renameItem = files->currentItem();
+ files->startRename( TRUE );
+ }
+ }
+ ((TQKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == TQEvent::KeyPress && ( (TQKeyEvent*)e )->key() == Qt::Key_F2 &&
+ ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->moreFiles) || TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->moreFiles->viewport()) ) ) {
+ if ( d->moreFiles->isVisible() && d->moreFiles->currentItem() != -1 ) {
+ if ( TQUrlInfo( d->url, "." ).isWritable() &&
+ d->moreFiles->item( d->moreFiles->currentItem() )->text() != ".." ) {
+ d->moreFiles->renameItem = d->moreFiles->item( d->moreFiles->currentItem() );
+ d->moreFiles->startRename( TRUE );
+ }
+ }
+ ((TQKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == TQEvent::KeyPress && d->moreFiles->renaming ) {
+ d->moreFiles->lined->setFocus();
+ TQApplication::sendEvent( d->moreFiles->lined, e );
+ ((TQKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == TQEvent::KeyPress && files->renaming ) {
+ files->lined->setFocus();
+ TQApplication::sendEvent( files->lined, e );
+ ((TQKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == TQEvent::KeyPress &&
+ ((TQKeyEvent *)e)->key() == Qt::Key_Backspace &&
+ ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(files) ||
+ TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->moreFiles) ||
+ TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(files->viewport()) ||
+ TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->moreFiles->viewport()) ) ) {
+ cdUpClicked();
+ ((TQKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == TQEvent::KeyPress &&
+ ((TQKeyEvent *)e)->key() == Qt::Key_Delete &&
+ ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(files) ||
+ TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(files->viewport()) ) ) {
+ if ( files->currentItem() )
+ deleteFile( files->currentItem()->text( 0 ) );
+ ((TQKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( e->type() == TQEvent::KeyPress &&
+ ((TQKeyEvent *)e)->key() == Qt::Key_Delete &&
+ ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->moreFiles) ||
+ TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->moreFiles->viewport()) ) ) {
+ int c = d->moreFiles->currentItem();
+ if ( c >= 0 )
+ deleteFile( d->moreFiles->item( c )->text() );
+ ((TQKeyEvent *)e)->accept();
+ return TRUE;
+ } else if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(files) && e->type() == TQEvent::FocusOut && files->currentItem() ) {
+ } else if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(files) && e->type() == TQEvent::KeyPress ) {
+ TQTimer::singleShot( 0, this, TQT_SLOT(fixupNameEdit()) );
+ } else if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(nameEdit) && e->type() == TQEvent::KeyPress && d->mode != AnyFile ) {
+ if ( ( nameEdit->cursorPosition() == (int)nameEdit->text().length() || nameEdit->hasSelectedText() ) &&
+ isprint(((TQKeyEvent *)e)->ascii()) ) {
+#if defined(TQ_WS_WIN)
+ TQString nt( nameEdit->text().lower() );
+#else
+ TQString nt( nameEdit->text() );
+#endif
+ nt.truncate( nameEdit->cursorPosition() );
+ nt += (char)(((TQKeyEvent *)e)->ascii());
+ TQListViewItem * i = files->firstChild();
+#if defined(TQ_WS_WIN)
+ while( i && i->text( 0 ).left(nt.length()).lower() != nt )
+#else
+ while( i && i->text( 0 ).left(nt.length()) != nt )
+#endif
+ i = i->nextSibling();
+ if ( i ) {
+ nt = i->text( 0 );
+ int cp = nameEdit->cursorPosition()+1;
+ nameEdit->validateAndSet( nt, cp, cp, nt.length() );
+ return TRUE;
+ }
+ }
+ } else if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(nameEdit) && e->type() == TQEvent::FocusIn ) {
+ fileNameEditDone();
+ } else if ( d->moreFiles->renaming && TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(d->moreFiles->lined) && e->type() == TQEvent::FocusIn ) {
+ d->moreFiles->lined->setFocus();
+ return TRUE;
+ } else if ( files->renaming && TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(files->lined) && e->type() == TQEvent::FocusIn ) {
+ files->lined->setFocus();
+ return TRUE;
+ } else if ( ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->moreFiles) || TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->moreFiles->viewport()) ) &&
+ e->type() == TQEvent::FocusIn ) {
+ if ( (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->moreFiles->viewport()) && !d->moreFiles->viewport()->hasFocus()) ||
+ (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->moreFiles) && !d->moreFiles->hasFocus()) )
+ ((TQWidget*)o)->setFocus();
+ return FALSE;
+ }
+
+ return TQDialog::eventFilter( o, e );
+}
+
+/*!
+ Sets the filters used in the file dialog to \a filters. Each group
+ of filters must be separated by \c{;;} (\e two semi-colons).
+
+ \code
+ TQString types("Image files (*.png *.xpm *.jpg);;"
+ "Text files (*.txt);;"
+ "Any files (*)");
+ TQFileDialog fd = new TQFileDialog( this );
+ fd->setFilters( types );
+ fd->show();
+ \endcode
+
+*/
+
+void TQFileDialog::setFilters( const TQString &filters )
+{
+ TQStringList lst = makeFiltersList( filters );
+ setFilters( lst );
+}
+
+/*!
+ \overload
+
+ \a types must be a null-terminated list of strings.
+
+*/
+
+void TQFileDialog::setFilters( const char ** types )
+{
+ if ( !types || !*types )
+ return;
+
+ d->types->clear();
+ while( types && *types ) {
+ d->types->insertItem( TQString::tqfromLatin1(*types) );
+ types++;
+ }
+ d->types->setCurrentItem( 0 );
+ setFilter( d->types->text( 0 ) );
+}
+
+
+/*! \overload void TQFileDialog::setFilters( const TQStringList & )
+*/
+
+void TQFileDialog::setFilters( const TQStringList & types )
+{
+ if ( types.count() < 1 )
+ return;
+
+ d->types->clear();
+ for ( TQStringList::ConstIterator it = types.begin(); it != types.end(); ++it )
+ d->types->insertItem( *it );
+ d->types->setCurrentItem( 0 );
+ setFilter( d->types->text( 0 ) );
+}
+
+/*!
+ Adds the filter \a filter to the list of filters and makes it the
+ current filter.
+
+ \code
+ TQFileDialog* fd = new TQFileDialog( this );
+ fd->addFilter( "Images (*.png *.jpg *.xpm)" );
+ fd->show();
+ \endcode
+
+ In the above example, a file dialog is created, and the file filter "Images
+ (*.png *.jpg *.xpm)" is added and is set as the current filter. The original
+ filter, "All Files (*)", is still available.
+
+ \sa setFilter(), setFilters()
+*/
+
+void TQFileDialog::addFilter( const TQString &filter )
+{
+ if ( filter.isEmpty() )
+ return;
+ TQString f = filter;
+ TQRegExp r( TQString::tqfromLatin1(qt_file_dialog_filter_reg_exp) );
+ int index = r.search( f );
+ if ( index >= 0 )
+ f = r.cap( 2 );
+ for ( int i = 0; i < d->types->count(); ++i ) {
+ TQString f2( d->types->text( i ) );
+ int index = r.search( f2 );
+ if ( index >= 0 )
+ f2 = r.cap( 1 );
+ if ( f2 == f ) {
+ d->types->setCurrentItem( i );
+ setFilter( f2 );
+ return;
+ }
+ }
+
+ d->types->insertItem( filter );
+ d->types->setCurrentItem( d->types->count() - 1 );
+ setFilter( d->types->text( d->types->count() - 1 ) );
+}
+
+/*!
+ Since modeButtons is a top-level widget, it may be destroyed by the
+ kernel at application exit. Notice if this happens to
+ avoid double deletion.
+*/
+
+void TQFileDialog::modeButtonsDestroyed()
+{
+ if ( d )
+ d->modeButtons = 0;
+}
+
+
+/*!
+ This is a convenience static function that will return one or more
+ existing files selected by the user.
+
+ \code
+ TQStringList files = TQFileDialog::getOpenFileNames(
+ "Images (*.png *.xpm *.jpg)",
+ "/home",
+ this,
+ "open files dialog",
+ "Select one or more files to open" );
+ \endcode
+
+ This function creates a modal file dialog called \a name, with
+ tqparent \a tqparent. If \a tqparent is not 0, the dialog will be shown
+ centered over the tqparent.
+
+ The file dialog's working directory will be set to \a dir. If \a
+ dir includes a file name, the file will be selected. The filter
+ is set to \a filter so that only those files which match the filter
+ are shown. The filter selected is set to \a selectedFilter. The parameters
+ \a dir, \a selectedFilter and \a filter may be TQString::null.
+
+ The dialog's caption is set to \a caption. If \a caption is not
+ specified then a default caption will be used.
+
+ Under Windows and Mac OS X, this static function will use the native
+ file dialog and not a TQFileDialog, unless the style of the application
+ is set to something other than the native style. (Note that on Windows the
+ dialog will spin a blocking modal event loop that will not dispatch any
+ TQTimers and if tqparent is not 0 then it will position the dialog just under
+ the tqparent's titlebar).
+
+ Under Unix/X11, the normal behavior of the file dialog is to resolve
+ and follow symlinks. For example, if /usr/tmp is a symlink to /var/tmp,
+ the file dialog will change to /var/tmp after entering /usr/tmp.
+ If \a resolveSymlinks is FALSE, the file dialog will treat
+ symlinks as regular directories.
+
+ Note that if you want to iterate over the list of files, you should
+ iterate over a copy, e.g.
+ \code
+ TQStringList list = files;
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa getOpenFileName(), getSaveFileName(), getExistingDirectory()
+*/
+
+TQStringList TQFileDialog::getOpenFileNames( const TQString & filter,
+ const TQString& dir,
+ TQWidget *tqparent,
+ const char* name,
+ const TQString& caption,
+ TQString *selectedFilter,
+ bool resolveSymlinks )
+{
+ bool save_qt_resolve_symlinks = qt_resolve_symlinks;
+ qt_resolve_symlinks = resolveSymlinks;
+
+ TQStringList filters;
+ if ( !filter.isEmpty() )
+ filters = makeFiltersList( filter );
+
+ makeVariables();
+
+ if ( workingDirectory->isNull() )
+ *workingDirectory = ::toRootIfNotExists( TQDir::currentDirPath() );
+
+ if ( !dir.isEmpty() ) {
+ // #### works only correct for local files
+ TQUrlOperator u( TQFileDialogPrivate::encodeFileName(dir) );
+ if ( u.isLocalFile() && TQFileInfo( u.path() ).isDir() ) {
+ *workingDirectory = dir;
+ } else {
+ *workingDirectory = u.toString();
+ }
+ }
+
+#if defined(TQ_WS_WIN)
+ if ( qt_use_native_dialogs && tqApp->tqstyle().tqstyleHint( TQStyle::SH_GUIStyle ) == WindowsStyle )
+ return winGetOpenFileNames( filter, workingDirectory, tqparent, name, caption, selectedFilter );
+#elif defined(TQ_WS_MAC)
+ if (qt_use_native_dialogs && (tqApp->tqstyle().inherits(TQMAC_DEFAULT_STYLE)
+ || tqApp->tqstyle().inherits("TQMacStyle"))) {
+ TQStringList sl = macGetOpenFileNames(filter, dir.isEmpty() ? 0 : workingDirectory, tqparent,
+ name, caption, selectedFilter);
+ TQStringList::iterator it = sl.begin();
+ while (it != sl.end()) {
+ *it = qt_mac_precomposeFileName(*it);
+ ++it;
+ }
+ return sl;
+ }
+#endif
+
+ TQFileDialog *dlg = new TQFileDialog( *workingDirectory, TQString::null, tqparent, name ? name : "qt_filedlg_gofns", TRUE );
+
+ TQ_CHECK_PTR( dlg );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( !caption.isNull() )
+ dlg->setCaption( caption );
+ else
+ dlg->setCaption( TQFileDialog::tr("Open") );
+#endif
+
+ dlg->setFilters( filters );
+ if ( selectedFilter )
+ dlg->setFilter( *selectedFilter );
+ dlg->setMode( TQFileDialog::ExistingFiles );
+ TQString result;
+ TQStringList lst;
+ if ( dlg->exec() == TQDialog::Accepted ) {
+ lst = dlg->selectedFiles();
+ *workingDirectory = dlg->d->url;
+ if ( selectedFilter )
+ *selectedFilter = dlg->selectedFilter();
+ }
+ delete dlg;
+
+ qt_resolve_symlinks = save_qt_resolve_symlinks;
+ return lst;
+}
+
+/*! Updates the line edit to match the speed-key usage in TQListView. */
+
+void TQFileDialog::fixupNameEdit()
+{
+ if ( files->currentItem() ) {
+ if ( ( (TQFileDialogPrivate::File*)files->currentItem() )->info.isFile() )
+ nameEdit->setText( files->currentItem()->text( 0 ) );
+ }
+}
+
+/*!
+ Returns the URL of the current working directory in the file dialog.
+
+ \sa setUrl()
+*/
+
+TQUrl TQFileDialog::url() const
+{
+ return d->url;
+}
+
+static bool isRoot( const TQUrl &u )
+{
+#if defined(TQ_OS_MAC9)
+ TQString p = TQDir::convertSeparators(u.path());
+ if(p.tqcontains(':') == 1)
+ return TRUE;
+#elif defined(TQ_OS_UNIX)
+ if ( u.path() == "/" )
+ return TRUE;
+#elif defined(TQ_OS_WIN32)
+ TQString p = u.path();
+ if ( p.length() == 3 &&
+ p.right( 2 ) == ":/" )
+ return TRUE;
+ if ( p[ 0 ] == '/' && p[ 1 ] == '/' ) {
+ int slashes = p.tqcontains( '/' );
+ if ( slashes <= 3 )
+ return TRUE;
+ if ( slashes == 4 && p[ (int)p.length() - 1 ] == '/' )
+ return TRUE;
+ }
+#else
+#if defined(TQ_CC_GNU)
+#warning "case not covered.."
+#endif
+#endif
+
+ if ( !u.isLocalFile() && u.path() == "/" )
+ return TRUE;
+
+ return FALSE;
+}
+
+void TQFileDialog::urlStart( TQNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+#if defined(TQ_WS_WIN)
+ qt_ntfs_permission_lookup--;
+#endif
+ if ( op->operation() == TQNetworkProtocol::OpListChildren ) {
+#ifndef TQT_NO_CURSOR
+ if ( !d->cursorOverride ) {
+ TQApplication::setOverrideCursor( TQCursor( TQt::WaitCursor ) );
+ d->cursorOverride = TRUE;
+ }
+#endif
+ if ( isRoot( d->url ) )
+ d->cdToParent->setEnabled( FALSE );
+ else
+ d->cdToParent->setEnabled( TRUE );
+ d->mimeTypeTimer->stop();
+ d->sortedList.clear();
+ d->pendingItems.clear();
+ d->moreFiles->clearSelection();
+ files->clearSelection();
+ d->moreFiles->clear();
+ files->clear();
+ files->setSorting( -1 );
+
+ TQString s = d->url.toString( FALSE, FALSE );
+ bool found = FALSE;
+ for ( int i = 0; i < d->paths->count(); ++i ) {
+#if defined(TQ_WS_WIN)
+ if ( d->paths->text( i ).lower() == s.lower() ) {
+#else
+ if ( d->paths->text( i ) == s ) {
+#endif
+ found = TRUE;
+ d->paths->setCurrentItem( i );
+ break;
+ }
+ }
+ if ( !found ) {
+ d->paths->insertItem( *openFolderIcon, s, -1 );
+ d->paths->setCurrentItem( d->paths->count() - 1 );
+ }
+ d->last = 0;
+ d->hadDotDot = FALSE;
+
+ if ( d->goBack && d->history.last() != d->url.toString() ) {
+ d->history.append( d->url.toString() );
+ if ( d->history.count() > 1 )
+ d->goBack->setEnabled( TRUE );
+ }
+ }
+}
+
+void TQFileDialog::urlFinished( TQNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+#ifndef TQT_NO_CURSOR
+ if ( op->operation() == TQNetworkProtocol::OpListChildren &&
+ d->cursorOverride ) {
+ TQApplication::restoreOverrideCursor();
+ d->cursorOverride = FALSE;
+ }
+#endif
+
+ if ( op->state() == TQNetworkProtocol::StFailed ) {
+ if ( d->paths->hasFocus() )
+ d->ignoreNextKeyPress = TRUE;
+
+ if ( d->progressDia ) {
+ d->ignoreStop = TRUE;
+ d->progressDia->close();
+ delete d->progressDia;
+ d->progressDia = 0;
+ }
+
+ int ecode = op->errorCode();
+ TQMessageBox::critical( this, tr( "Error" ), op->protocolDetail() );
+
+ if ( ecode == TQNetworkProtocol::ErrListChildren || ecode == TQNetworkProtocol::ErrParse ||
+ ecode == TQNetworkProtocol::ErrUnknownProtocol || ecode == TQNetworkProtocol::ErrLoginIncorrect ||
+ ecode == TQNetworkProtocol::ErrValid || ecode == TQNetworkProtocol::ErrHostNotFound ||
+ ecode == TQNetworkProtocol::ErrFileNotExisting ) {
+ if (!(d->url == d->oldUrl)) {
+ d->url = d->oldUrl;
+ rereadDir();
+ }
+ } else {
+ // another error happened, no need to go back to last dir
+ }
+ } else if ( op->operation() == TQNetworkProtocol::OpListChildren &&
+ op == d->currListChildren ) {
+ if ( !d->hadDotDot && !isRoot( d->url ) ) {
+ bool ok = TRUE;
+#if defined(TQ_WS_WIN)
+ if ( d->url.path().left( 2 ) == "//" )
+ ok = FALSE;
+#endif
+ if ( ok ) {
+ TQUrlInfo ui( d->url, ".." );
+ ui.setName( ".." );
+ ui.setDir( TRUE );
+ ui.setFile( FALSE );
+ ui.setSymLink( FALSE );
+ ui.setSize( 0 );
+ TQValueList<TQUrlInfo> lst;
+ lst << ui;
+ insertEntry( lst, 0 );
+ }
+ }
+ resortDir();
+ } else if ( op->operation() == TQNetworkProtocol::OpGet ) {
+ } else if ( op->operation() == TQNetworkProtocol::OpPut ) {
+ rereadDir();
+ if ( d->progressDia ) {
+ d->ignoreStop = TRUE;
+ d->progressDia->close();
+ }
+ delete d->progressDia;
+ d->progressDia = 0;
+ }
+
+#if defined(TQ_WS_WIN)
+ if (d->oldPermissionLookup != qt_ntfs_permission_lookup)
+ qt_ntfs_permission_lookup++;
+#endif
+}
+
+void TQFileDialog::dataTransferProgress( int bytesDone, int bytesTotal, TQNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+ TQString label;
+ TQUrl u( op->arg( 0 ) );
+ if ( u.isLocalFile() ) {
+ label = u.path();
+ } else {
+ label = TQString( "%1 (on %2)" );
+ label = label.arg( u.path() ).arg( u.host() );
+ }
+
+ if ( !d->progressDia ) {
+ if ( bytesDone < bytesTotal) {
+ d->ignoreStop = FALSE;
+ d->progressDia = new TQFDProgressDialog( this, label, bytesTotal );
+ connect( d->progressDia, TQT_SIGNAL( cancelled() ),
+ this, TQT_SLOT( stopCopy() ) );
+ d->progressDia->show();
+ } else
+ return;
+ }
+
+ if ( d->progressDia ) {
+ if ( op->operation() == TQNetworkProtocol::OpGet ) {
+ if ( d->progressDia ) {
+ d->progressDia->setReadProgress( bytesDone );
+ }
+ } else if ( op->operation() == TQNetworkProtocol::OpPut ) {
+ if ( d->progressDia ) {
+ d->progressDia->setWriteLabel( label );
+ d->progressDia->setWriteProgress( bytesDone );
+ }
+ } else {
+ return;
+ }
+ }
+}
+
+void TQFileDialog::insertEntry( const TQValueList<TQUrlInfo> &lst, TQNetworkOperation *op )
+{
+ if ( op && op->operation() == TQNetworkProtocol::OpListChildren &&
+ op != d->currListChildren )
+ return;
+ TQValueList<TQUrlInfo>::ConstIterator it = lst.begin();
+ for ( ; it != lst.end(); ++it ) {
+ const TQUrlInfo &inf = *it;
+ if ( d->mode == DirectoryOnly && !inf.isDir() )
+ continue;
+ if ( inf.name() == ".." ) {
+ d->hadDotDot = TRUE;
+ if ( isRoot( d->url ) )
+ continue;
+#if defined(TQ_WS_WIN)
+ if ( d->url.path().left( 2 ) == "//" )
+ continue;
+#endif
+ } else if ( inf.name() == "." )
+ continue;
+
+#if defined(TQ_WS_WIN)
+ // Workaround a Windows bug, '..' is apparantly hidden in directories
+ // that are one level away from root
+ if ( !bShowHiddenFiles && inf.name() != ".." ) {
+ if ( d->url.isLocalFile() ) {
+ TQString file = d->url.path();
+ if ( !file.endsWith( "/" ) )
+ file.append( "/" );
+ file += inf.name();
+ TQT_WA( {
+ if ( GetFileAttributesW( (TCHAR*)file.ucs2() ) & FILE_ATTRIBUTE_HIDDEN )
+ continue;
+ } , {
+ if ( GetFileAttributesA( file.local8Bit() ) & FILE_ATTRIBUTE_HIDDEN )
+ continue;
+ } );
+ } else {
+ if ( inf.name() != ".." && inf.name()[0] == TQChar('.') )
+ continue;
+ }
+ }
+#else
+ if ( !bShowHiddenFiles && inf.name() != ".." ) {
+ if ( inf.name()[ 0 ] == TQChar( '.' ) )
+ continue;
+ }
+#endif
+ if ( !d->url.isLocalFile() ) {
+ TQFileDialogPrivate::File * i = 0;
+ TQFileDialogPrivate::MCItem *i2 = 0;
+ i = new TQFileDialogPrivate::File( d, &inf, files );
+ i2 = new TQFileDialogPrivate::MCItem( d->moreFiles, i );
+
+ if ( (d->mode == ExistingFiles && inf.isDir()) ||
+ ( isDirectoryMode( d->mode ) && inf.isFile() ) ) {
+ i->setSelectable( FALSE );
+ i2->setSelectable( FALSE );
+ }
+
+ i->i = i2;
+ }
+
+ d->sortedList.append( new TQUrlInfo( inf ) );
+ }
+}
+
+void TQFileDialog::removeEntry( TQNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+ TQUrlInfo *i = 0;
+ TQListViewItemIterator it( files );
+ bool ok1 = FALSE, ok2 = FALSE;
+ for ( i = d->sortedList.first(); it.current(); ++it, i = d->sortedList.next() ) {
+ TQString encName = TQFileDialogPrivate::encodeFileName(
+ ( (TQFileDialogPrivate::File*)it.current() )->info.name() );
+ if ( encName == op->arg( 0 ) ) {
+ d->pendingItems.removeRef( (TQFileDialogPrivate::File*)it.current() );
+ delete ( (TQFileDialogPrivate::File*)it.current() )->i;
+ delete it.current();
+ ok1 = TRUE;
+ }
+ if ( i && i->name() == op->arg( 0 ) ) {
+ d->sortedList.removeRef( i );
+ i = d->sortedList.prev();
+ ok2 = TRUE;
+ }
+ if ( ok1 && ok2 )
+ break;
+ }
+}
+
+void TQFileDialog::itemChanged( TQNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+ TQUrlInfo *i = 0;
+ TQListViewItemIterator it1( files );
+ bool ok1 = FALSE, ok2 = FALSE;
+ // first check whether the new file tqreplaces an existing file.
+ for ( i = d->sortedList.first(); it1.current(); ++it1, i = d->sortedList.next() ) {
+ if ( ( (TQFileDialogPrivate::File*)it1.current() )->info.name() == op->arg( 1 ) ) {
+ delete ( (TQFileDialogPrivate::File*)it1.current() )->i;
+ delete it1.current();
+ ok1 = TRUE;
+ }
+ if ( i && i->name() == op->arg( 1 ) ) {
+ d->sortedList.removeRef( i );
+ i = d->sortedList.prev();
+ ok2 = TRUE;
+ }
+ if ( ok1 && ok2 )
+ break;
+ }
+
+ i = 0;
+ TQListViewItemIterator it( files );
+ ok1 = FALSE;
+ ok2 = FALSE;
+ for ( i = d->sortedList.first(); it.current(); ++it, i = d->sortedList.next() ) {
+ if ( ( (TQFileDialogPrivate::File*)it.current() )->info.name() == op->arg( 0 ) ) {
+ ( (TQFileDialogPrivate::File*)it.current() )->info.setName( op->arg( 1 ) );
+ ok1 = TRUE;
+ }
+ if ( i && i->name() == op->arg( 0 ) ) {
+ i->setName( op->arg( 1 ) );
+ ok2 = TRUE;
+ }
+ if ( ok1 && ok2 )
+ break;
+ }
+
+ resortDir();
+}
+
+/*!
+ \property TQFileDialog::infoPreview
+
+ \brief whether the file dialog can provide preview information about
+ the currently selected file
+
+ The default is FALSE.
+*/
+bool TQFileDialog::isInfoPreviewEnabled() const
+{
+ return d->infoPreview;
+}
+
+void TQFileDialog::setInfoPreviewEnabled( bool info )
+{
+ if ( info == d->infoPreview )
+ return;
+ d->tqgeometryDirty = TRUE;
+ d->infoPreview = info;
+ updateGeometries();
+}
+
+
+/*!
+ \property TQFileDialog::contentsPreview
+
+ \brief whether the file dialog can provide a contents preview of the
+ currently selected file
+
+ The default is FALSE.
+
+ \sa setContentsPreview() setInfoPreviewEnabled()
+*/
+// ### improve the above documentation: how is the preview done, how can I add
+// support for customized preview, etc.
+
+bool TQFileDialog::isContentsPreviewEnabled() const
+{
+ return d->contentsPreview;
+}
+
+void TQFileDialog::setContentsPreviewEnabled( bool contents )
+{
+ if ( contents == d->contentsPreview )
+ return;
+ d->tqgeometryDirty = TRUE;
+ d->contentsPreview = contents;
+ updateGeometries();
+}
+
+
+/*!
+ Sets the widget to be used for displaying information about the file
+ to the widget \a w and a preview of that information to the
+ TQFilePreview \a preview.
+
+ Normally you would create a preview widget that derives from both TQWidget and
+ TQFilePreview, so you should pass the same widget twice. If you
+ don't, you must remember to delete the preview object in order to
+ avoid memory leaks.
+
+ \code
+ class Preview : public TQLabel, public TQFilePreview
+ {
+ public:
+ Preview( TQWidget *tqparent=0 ) : TQLabel( tqparent ) {}
+
+ void previewUrl( const TQUrl &u )
+ {
+ TQString path = u.path();
+ TQPixmap pix( path );
+ if ( pix.isNull() )
+ setText( "This is not a pixmap" );
+ else
+ setText( "This is a pixmap" );
+ }
+ };
+
+ //...
+
+ int main( int argc, char** argv )
+ {
+ Preview* p = new Preview;
+
+ TQFileDialog* fd = new TQFileDialog( this );
+ fd->setInfoPreviewEnabled( TRUE );
+ fd->setInfoPreview( p, p );
+ fd->setPreviewMode( TQFileDialog::Info );
+ fd->show();
+ }
+
+ \endcode
+
+ \sa setContentsPreview(), setInfoPreviewEnabled(), setPreviewMode()
+
+*/
+
+void TQFileDialog::setInfoPreview( TQWidget *w, TQFilePreview *preview )
+{
+ if ( !w || !preview )
+ return;
+
+ if ( d->infoPreviewWidget ) {
+ d->preview->removeWidget( d->infoPreviewWidget );
+ delete d->infoPreviewWidget;
+ }
+ d->infoPreviewWidget = w;
+ d->infoPreviewer = preview;
+ w->reparent( d->preview, 0, TQPoint( 0, 0 ) );
+}
+
+/*!
+ Sets the widget to be used for displaying the contents of the file
+ to the widget \a w and a preview of those contents to the
+ TQFilePreview \a preview.
+
+ Normally you would create a preview widget that derives from both TQWidget and
+ TQFilePreview, so you should pass the same widget twice. If you
+ don't, you must remember to delete the preview object in order to
+ avoid memory leaks.
+
+ \code
+ class Preview : public TQLabel, public TQFilePreview
+ {
+ public:
+ Preview( TQWidget *tqparent=0 ) : TQLabel( tqparent ) {}
+
+ void previewUrl( const TQUrl &u )
+ {
+ TQString path = u.path();
+ TQPixmap pix( path );
+ if ( pix.isNull() )
+ setText( "This is not a pixmap" );
+ else
+ setPixmap( pix );
+ }
+ };
+
+ //...
+
+ int main( int argc, char** argv )
+ {
+ Preview* p = new Preview;
+
+ TQFileDialog* fd = new TQFileDialog( this );
+ fd->setContentsPreviewEnabled( TRUE );
+ fd->setContentsPreview( p, p );
+ fd->setPreviewMode( TQFileDialog::Contents );
+ fd->show();
+ }
+ \endcode
+
+ \sa setContentsPreviewEnabled(), setInfoPreview(), setPreviewMode()
+*/
+
+void TQFileDialog::setContentsPreview( TQWidget *w, TQFilePreview *preview )
+{
+ if ( !w || !preview )
+ return;
+
+ if ( d->contentsPreviewWidget ) {
+ d->preview->removeWidget( d->contentsPreviewWidget );
+ delete d->contentsPreviewWidget;
+ }
+ d->contentsPreviewWidget = w;
+ d->contentsPreviewer = preview;
+ w->reparent( d->preview, 0, TQPoint( 0, 0 ) );
+}
+
+/*!
+ Re-sorts the displayed directory.
+
+ \sa rereadDir()
+*/
+
+void TQFileDialog::resortDir()
+{
+ d->mimeTypeTimer->stop();
+ d->pendingItems.clear();
+
+ TQFileDialogPrivate::File *item = 0;
+ TQFileDialogPrivate::MCItem *item2 = 0;
+
+ d->sortedList.sort();
+
+ if ( files->childCount() > 0 || d->moreFiles->count() > 0 ) {
+ d->moreFiles->clear();
+ files->clear();
+ d->last = 0;
+ files->setSorting( -1 );
+ }
+
+ TQUrlInfo *i = sortAscending ? d->sortedList.first() : d->sortedList.last();
+ for ( ; i; i = sortAscending ? d->sortedList.next() : d->sortedList.prev() ) {
+ item = new TQFileDialogPrivate::File( d, i, files );
+ item2 = new TQFileDialogPrivate::MCItem( d->moreFiles, item, item2 );
+ item->i = item2;
+ d->pendingItems.append( item );
+ if ( (d->mode == ExistingFiles && item->info.isDir()) ||
+ ( isDirectoryMode( d->mode ) && item->info.isFile() ) ) {
+ item->setSelectable( FALSE );
+ item2->setSelectable( FALSE );
+ }
+ }
+
+ // ##### As the TQFileIconProvider only support TQFileInfo and no
+ // TQUrlInfo it can be only used for local files at the moment. In
+ // 3.0 we have to change the API of TQFileIconProvider to work on
+ // TQUrlInfo so that also remote filesystems can be show mime-type
+ // specific icons.
+ if ( d->url.isLocalFile() )
+ d->mimeTypeTimer->start( 0 );
+}
+
+/*!
+ Stops the current copy operation.
+*/
+
+void TQFileDialog::stopCopy()
+{
+ if ( d->ignoreStop )
+ return;
+
+ d->url.blockSignals( TRUE );
+ d->url.stop();
+ if ( d->progressDia ) {
+ d->ignoreStop = TRUE;
+ TQTimer::singleShot( 100, this, TQT_SLOT( removeProgressDia() ) );
+ }
+ d->url.blockSignals( FALSE );
+}
+
+/*!
+ \internal
+*/
+
+void TQFileDialog::removeProgressDia()
+{
+ if ( d->progressDia )
+ delete d->progressDia;
+ d->progressDia = 0;
+}
+
+/*!
+ \internal
+*/
+
+void TQFileDialog::doMimeTypeLookup()
+{
+ if ( !iconProvider() ) {
+ d->pendingItems.clear();
+ d->mimeTypeTimer->stop();
+ return;
+ }
+
+ d->mimeTypeTimer->stop();
+ if ( d->pendingItems.count() == 0 ) {
+ return;
+ }
+
+ TQRect r;
+ TQFileDialogPrivate::File *item = d->pendingItems.first();
+ if ( item ) {
+ TQFileInfo fi;
+ if ( d->url.isLocalFile() ) {
+ fi.setFile( TQUrl( d->url.path(), TQFileDialogPrivate::encodeFileName( item->info.name() ) ).path( FALSE ) );
+ } else
+ fi.setFile( item->info.name() ); // #####
+ const TQPixmap *p = iconProvider()->pixmap( fi );
+ if ( p && p != item->pixmap( 0 ) &&
+ ( !item->pixmap( 0 ) || p->serialNumber() != item->pixmap( 0 )->serialNumber() ) &&
+ p != fifteenTransparentPixels ) {
+ item->hasMimePixmap = TRUE;
+
+ // evil hack to avoid much too much repaints!
+ TQGuardedPtr<TQFileDialog> that( this ); // this may be deleted by an event handler
+ tqApp->processEvents();
+ if ( that.isNull() )
+ return;
+ files->setUpdatesEnabled( FALSE );
+ files->viewport()->setUpdatesEnabled( FALSE );
+ if ( item != d->pendingItems.first() )
+ return;
+ item->setPixmap( 0, *p );
+ tqApp->processEvents();
+ if ( that.isNull() )
+ return;
+ files->setUpdatesEnabled( TRUE );
+ files->viewport()->setUpdatesEnabled( TRUE );
+
+ if ( files->isVisible() ) {
+ TQRect ir( files->tqitemRect( item ) );
+ if ( ir != TQRect( 0, 0, -1, -1 ) ) {
+ r = r.unite( ir );
+ }
+ } else {
+ TQRect ir( d->moreFiles->tqitemRect( item->i ) );
+ if ( ir != TQRect( 0, 0, -1, -1 ) ) {
+ r = r.unite( ir );
+ }
+ }
+ }
+ if ( d->pendingItems.count() )
+ d->pendingItems.removeFirst();
+ }
+
+ if ( d->moreFiles->isVisible() ) {
+ d->moreFiles->viewport()->tqrepaint( r, FALSE );
+ } else {
+ files->viewport()->tqrepaint( r, FALSE );
+ }
+
+ if ( d->pendingItems.count() )
+ d->mimeTypeTimer->start( 0 );
+ else if ( d->moreFiles->isVisible() )
+ d->moreFiles->triggerUpdate( TRUE );
+}
+
+/*!
+ If \a b is TRUE then all the files in the current directory are selected;
+ otherwise, they are deselected.
+*/
+
+void TQFileDialog::selectAll( bool b )
+{
+ if ( d->mode != ExistingFiles )
+ return;
+ d->moreFiles->selectAll( b );
+ files->selectAll( b );
+}
+
+void TQFileDialog::goBack()
+{
+ if ( !d->goBack || !d->goBack->isEnabled() )
+ return;
+ d->history.remove( d->history.last() );
+ if ( d->history.count() < 2 )
+ d->goBack->setEnabled( FALSE );
+ setUrl( d->history.last() );
+}
+
+// a class with wonderfully inflexible flexibility. why doesn't it
+// just subclass TQWidget in the first place? 'you have to derive your
+// preview widget from TQWidget and from this class' indeed.
+
+/*!
+ \class TQFilePreview tqfiledialog.h
+ \ingroup misc
+ \brief The TQFilePreview class provides file previewing in TQFileDialog.
+
+ This class is an abstract base class which is used to implement
+ widgets that can display a preview of a file in a TQFileDialog.
+
+ You must derive the preview widget from both TQWidget and from this
+ class. Then you must reimplement this class's previewUrl() function,
+ which is called by the file dialog if the preview of a file
+ (specified as a URL) should be shown.
+
+ See also TQFileDialog::setPreviewMode(), TQFileDialog::setContentsPreview(),
+ TQFileDialog::setInfoPreview(), TQFileDialog::setInfoPreviewEnabled(),
+ TQFileDialog::setContentsPreviewEnabled().
+
+ For an example of a preview widget see qt/examples/qdir/qdir.cpp.
+*/
+
+/*!
+ Constructs the TQFilePreview.
+*/
+
+TQFilePreview::TQFilePreview()
+{
+}
+
+/*!
+ \fn void TQFilePreview::previewUrl( const TQUrl &url )
+
+ This function is called by TQFileDialog if a preview
+ for the \a url should be shown. Reimplement this
+ function to provide file previewing.
+*/
+
+
+#include "tqfiledialog.tqmoc"
+
+#endif
diff --git a/tqtinterface/qt4/src/dialogs/tqfiledialog.h b/tqtinterface/qt4/src/dialogs/tqfiledialog.h
new file mode 100644
index 0000000..eef857e
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqfiledialog.h
@@ -0,0 +1,350 @@
+/****************************************************************************
+**
+** Definition of TQFileDialog class
+**
+** Created : 950428
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFILEDIALOG_H
+#define TQFILEDIALOG_H
+
+class TQPushButton;
+class TQButton;
+class TQLabel;
+class TQWidget;
+class TQFileDialog;
+class TQTimer;
+class TQNetworkOperation;
+class TQLineEdit;
+class TQListViewItem;
+class TQListBoxItem;
+class TQFileDialogPrivate;
+class TQFileDialogTQFileListView;
+
+#ifndef TQT_H
+#include "tqdir.h"
+#include "tqdialog.h"
+#include "tqurloperator.h"
+#include "tqurlinfo.h"
+#endif // TQT_H
+
+#if __GNUC__ - 0 > 3
+#pragma GCC system_header
+#endif
+
+#ifndef TQT_NO_FILEDIALOG
+
+class TQ_EXPORT TQFileIconProvider : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQFileIconProvider( TQObject * tqparent = 0, const char* name = 0 );
+ virtual const TQPixmap * pixmap( const TQFileInfo & );
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQFileIconProvider( const TQFileIconProvider & );
+ TQFileIconProvider& operator=( const TQFileIconProvider & );
+#endif
+};
+
+class TQ_EXPORT TQFilePreview
+{
+public:
+ TQFilePreview();
+ virtual void previewUrl( const TQUrl &url ) = 0;
+
+};
+
+class TQ_EXPORT TQFileDialog : public TQDialog
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( Mode ViewMode PreviewMode )
+ // ##### Why are this read-only properties ?
+ Q_PROPERTY( TQString selectedFile READ selectedFile )
+ Q_PROPERTY( TQString selectedFilter READ selectedFilter )
+ Q_PROPERTY( TQStringList selectedFiles READ selectedFiles )
+ // #### Should not we be able to set the path ?
+ Q_PROPERTY( TQString dirPath READ dirPath )
+ Q_PROPERTY( bool showHiddenFiles READ showHiddenFiles WRITE setShowHiddenFiles )
+ Q_PROPERTY( Mode mode READ mode WRITE setMode )
+ Q_PROPERTY( ViewMode viewMode READ viewMode WRITE setViewMode )
+ Q_PROPERTY( PreviewMode previewMode READ previewMode WRITE setPreviewMode )
+ Q_PROPERTY( bool infoPreview READ isInfoPreviewEnabled WRITE setInfoPreviewEnabled )
+ Q_PROPERTY( bool contentsPreview READ isContentsPreviewEnabled WRITE setContentsPreviewEnabled )
+
+public:
+ TQFileDialog( const TQString& dirName, const TQString& filter = TQString::null,
+ TQWidget* tqparent=0, const char* name=0, bool modal = FALSE );
+ TQFileDialog( TQWidget* tqparent=0, const char* name=0, bool modal = FALSE );
+ ~TQFileDialog();
+
+ // recommended static functions
+
+ static TQString getOpenFileName( const TQString &initially = TQString::null,
+ const TQString &filter = TQString::null,
+ TQWidget *tqparent = 0, const char* name = 0,
+ const TQString &caption = TQString::null,
+ TQString *selectedFilter = 0,
+ bool resolveSymlinks = TRUE);
+ static TQString getSaveFileName( const TQString &initially = TQString::null,
+ const TQString &filter = TQString::null,
+ TQWidget *tqparent = 0, const char* name = 0,
+ const TQString &caption = TQString::null,
+ TQString *selectedFilter = 0,
+ bool resolveSymlinks = TRUE);
+ static TQString getExistingDirectory( const TQString &dir = TQString::null,
+ TQWidget *tqparent = 0,
+ const char* name = 0,
+ const TQString &caption = TQString::null,
+ bool dirOnly = TRUE,
+ bool resolveSymlinks = TRUE);
+ static TQStringList getOpenFileNames( const TQString &filter= TQString::null,
+ const TQString &dir = TQString::null,
+ TQWidget *tqparent = 0,
+ const char* name = 0,
+ const TQString &caption = TQString::null,
+ TQString *selectedFilter = 0,
+ bool resolveSymlinks = TRUE);
+
+ // other static functions
+
+ static void setIconProvider( TQFileIconProvider * );
+ static TQFileIconProvider * iconProvider();
+
+ // non-static function for special needs
+
+ TQString selectedFile() const;
+ TQString selectedFilter() const;
+ virtual void setSelectedFilter( const TQString& );
+ virtual void setSelectedFilter( int );
+
+ void setSelection( const TQString &);
+
+ void selectAll( bool b );
+
+ TQStringList selectedFiles() const;
+
+ TQString dirPath() const;
+
+ void setDir( const TQDir & );
+ const TQDir *dir() const;
+
+ void setShowHiddenFiles( bool s );
+ bool showHiddenFiles() const;
+
+ void rereadDir();
+ void resortDir();
+
+ enum Mode { AnyFile, ExistingFile, Directory, ExistingFiles, DirectoryOnly };
+ void setMode( Mode );
+ Mode mode() const;
+
+ enum ViewMode { Detail, List };
+ enum PreviewMode { NoPreview, Contents, Info };
+ void setViewMode( ViewMode m );
+ ViewMode viewMode() const;
+ void setPreviewMode( PreviewMode m );
+ PreviewMode previewMode() const;
+
+ bool eventFilter( TQObject *, TQEvent * );
+
+ bool isInfoPreviewEnabled() const;
+ bool isContentsPreviewEnabled() const;
+ void setInfoPreviewEnabled( bool );
+ void setContentsPreviewEnabled( bool );
+
+ void setInfoPreview( TQWidget *w, TQFilePreview *preview );
+ void setContentsPreview( TQWidget *w, TQFilePreview *preview );
+
+ TQUrl url() const;
+
+ void addFilter( const TQString &filter );
+
+public Q_SLOTS:
+ void done( int );
+ void setDir( const TQString& );
+ void setUrl( const TQUrlOperator &url );
+ void setFilter( const TQString& );
+ void setFilters( const TQString& );
+ void setFilters( const char ** );
+ void setFilters( const TQStringList& );
+
+protected:
+ void resizeEvent( TQResizeEvent * );
+ void keyPressEvent( TQKeyEvent * );
+
+ void addWidgets( TQLabel *, TQWidget *, TQPushButton * );
+ void addToolButton( TQButton *b, bool separator = FALSE );
+ void addLeftWidget( TQWidget *w );
+ void addRightWidget( TQWidget *w );
+
+Q_SIGNALS:
+ void fileHighlighted( const TQString& );
+ void fileSelected( const TQString& );
+ void filesSelected( const TQStringList& );
+ void dirEntered( const TQString& );
+ void filterSelected( const TQString& );
+
+private Q_SLOTS:
+ void detailViewSelectionChanged();
+ void listBoxSelectionChanged();
+ void changeMode( int );
+ void fileNameEditReturnPressed();
+ void stopCopy();
+ void removeProgressDia();
+
+ void fileSelected( int );
+ void fileHighlighted( int );
+ void dirSelected( int );
+ void pathSelected( int );
+
+ void updateFileNameEdit( TQListViewItem *);
+ void selectDirectoryOrFile( TQListViewItem * );
+ void popupContextMenu( TQListViewItem *, const TQPoint &, int );
+ void popupContextMenu( TQListBoxItem *, const TQPoint & );
+ void updateFileNameEdit( TQListBoxItem *);
+ void selectDirectoryOrFile( TQListBoxItem * );
+ void fileNameEditDone();
+
+ void okClicked();
+ void filterClicked(); // not used
+ void cancelClicked();
+
+ void cdUpClicked();
+ void newFolderClicked();
+
+ void fixupNameEdit();
+
+ void doMimeTypeLookup();
+
+ void updateGeometries();
+ void modeButtonsDestroyed();
+ void urlStart( TQNetworkOperation *op );
+ void urlFinished( TQNetworkOperation *op );
+ void dataTransferProgress( int bytesDone, int bytesTotal, TQNetworkOperation * );
+ void insertEntry( const TQValueList<TQUrlInfo> &fi, TQNetworkOperation *op );
+ void removeEntry( TQNetworkOperation * );
+ void createdDirectory( const TQUrlInfo &info, TQNetworkOperation * );
+ void itemChanged( TQNetworkOperation * );
+ void goBack();
+
+private:
+ enum PopupAction {
+ PA_Open = 0,
+ PA_Delete,
+ PA_Rename,
+ PA_SortName,
+ PA_SortSize,
+ PA_SortType,
+ PA_SortDate,
+ PA_SortUnsorted,
+ PA_Cancel,
+ PA_Reload,
+ PA_Hidden
+ };
+
+ void init();
+ bool trySetSelection( bool isDir, const TQUrlOperator &, bool );
+ void deleteFile( const TQString &filename );
+ void popupContextMenu( const TQString &filename, bool withSort,
+ PopupAction &action, const TQPoint &p );
+ void updatePreviews( const TQUrl &u );
+
+ TQDir reserved; // was cwd
+ TQString fileName;
+
+ friend class TQFileDialogTQFileListView;
+ friend class TQFileListBox;
+ friend class TQDialog;
+
+ TQFileDialogPrivate *d;
+ TQFileDialogTQFileListView *files;
+
+ TQLineEdit *nameEdit; // also filter
+ TQPushButton *okB;
+ TQPushButton *cancelB;
+
+#if defined(TQ_WS_WIN)
+ static TQString winGetOpenFileName( const TQString &initialSelection,
+ const TQString &filter,
+ TQString* workingDirectory,
+ TQWidget *tqparent = 0,
+ const char* name = 0,
+ const TQString& caption = TQString::null,
+ TQString* selectedFilter = 0 );
+ static TQString winGetSaveFileName( const TQString &initialSelection,
+ const TQString &filter,
+ TQString* workingDirectory,
+ TQWidget *tqparent = 0,
+ const char* name = 0,
+ const TQString& caption = TQString::null,
+ TQString* selectedFilter = 0 );
+ static TQStringList winGetOpenFileNames( const TQString &filter,
+ TQString* workingDirectory,
+ TQWidget *tqparent = 0,
+ const char* name = 0,
+ const TQString& caption = TQString::null,
+ TQString* selectedFilter = 0 );
+ static TQString winGetExistingDirectory( const TQString &initialDirectory,
+ TQWidget* tqparent = 0,
+ const char* name = 0,
+ const TQString& caption = TQString::null);
+ static TQString resolveLinkFile( const TQString& linkfile );
+#endif
+#if defined(TQ_WS_MACX) || defined(TQ_WS_MAC9)
+ static TQString macGetSaveFileName( const TQString &, const TQString &,
+ TQString *, TQWidget *, const char*,
+ const TQString&, TQString *);
+ static TQStringList macGetOpenFileNames( const TQString &, TQString*,
+ TQWidget *, const char *,
+ const TQString&, TQString *,
+ bool = TRUE, bool = FALSE );
+#endif
+
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQFileDialog( const TQFileDialog & );
+ TQFileDialog &operator=( const TQFileDialog & );
+#endif
+};
+
+#endif
+
+#endif // TQFILEDIALOG_H
diff --git a/tqtinterface/qt4/src/dialogs/tqfontdialog.cpp b/tqtinterface/qt4/src/dialogs/tqfontdialog.cpp
new file mode 100644
index 0000000..fbccfa8
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqfontdialog.cpp
@@ -0,0 +1,831 @@
+/****************************************************************************
+**
+** Implementation of TQFontDialog
+**
+** Created : 970605
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwindowdefs.h"
+
+#ifndef TQT_NO_FONTDIALOG
+
+#include "tqfontdialog.h"
+
+#include "tqlineedit.h"
+#include "tqlistbox.h"
+#include "tqpushbutton.h"
+#include "tqcheckbox.h"
+#include "tqcombobox.h"
+#include "tqlayout.h"
+#include "tqvgroupbox.h"
+#include "tqhgroupbox.h"
+#include "tqlabel.h"
+#include "tqapplication.h"
+#include "tqfontdatabase.h"
+#include "tqstyle.h"
+#include <private/tqfontdata_p.h>
+#include <tqvalidator.h>
+
+/*!
+ \class TQFontDialog tqfontdialog.h
+ \ingroup dialogs
+ \mainclass
+ \brief The TQFontDialog class provides a dialog widget for selecting a font.
+
+ The usual way to use this class is to call one of the static convenience
+ functions, e.g. getFont().
+
+ Examples:
+
+ \code
+ bool ok;
+ TQFont font = TQFontDialog::getFont(
+ &ok, TQFont( "Helvetica [Cronyx]", 10 ), this );
+ if ( ok ) {
+ // font is set to the font the user selected
+ } else {
+ // the user canceled the dialog; font is set to the initial
+ // value, in this case Helvetica [Cronyx], 10
+ }
+ \endcode
+
+ The dialog can also be used to set a widget's font directly:
+ \code
+ myWidget.setFont( TQFontDialog::getFont( 0, myWidget.font() ) );
+ \endcode
+ If the user clicks OK the font they chose will be used for myWidget,
+ and if they click Cancel the original font is used.
+
+ \sa TQFont TQFontInfo TQFontMetrics
+
+ <img src=qfontdlg-w.png>
+*/
+
+class TQFontDialogPrivate
+{
+public:
+ TQFontDialogPrivate() : script( TQFontPrivate::defaultScript ) {};
+ TQLabel * familyAccel;
+ TQLineEdit * familyEdit;
+ TQListBox * familyList;
+
+ TQLabel * styleAccel;
+ TQLineEdit * styleEdit;
+ TQListBox * styleList;
+
+ TQLabel * sizeAccel;
+ TQLineEdit * sizeEdit;
+ TQListBox * sizeList;
+
+ TQVGroupBox * effects;
+ TQCheckBox * strikeout;
+ TQCheckBox * underline;
+ TQComboBox * color;
+
+ TQHGroupBox * sample;
+ TQLineEdit * sampleEdit;
+
+ TQLabel * scriptAccel;
+ TQComboBox * scriptCombo;
+
+ TQPushButton * ok;
+ TQPushButton * cancel;
+
+ TQBoxLayout * buttonLayout;
+ TQBoxLayout * effectsLayout;
+ TQBoxLayout * sampleLayout;
+ TQBoxLayout * sampleEditLayout;
+
+ TQFontDatabase fdb;
+
+ TQString family;
+ TQFont::Script script;
+ TQString style;
+ int size;
+
+ bool smoothScalable;
+};
+
+
+/*!
+ \internal
+ Constructs a standard font dialog.
+
+ Use setFont() to set the initial font attributes.
+
+ The \a tqparent, \a name, \a modal and \a f parameters are passed to
+ the TQDialog constructor.
+
+ \sa getFont()
+*/
+
+TQFontDialog::TQFontDialog( TQWidget *tqparent, const char *name,
+ bool modal, WFlags f )
+ : TQDialog( tqparent, name, modal, f )
+{
+ setSizeGripEnabled( TRUE );
+ d = new TQFontDialogPrivate;
+ // grid
+ d->familyEdit = new TQLineEdit( this, "font family I" );
+ d->familyEdit->setReadOnly( TRUE );
+ d->familyList = new TQListBox( this, "font family II" );
+ d->familyEdit->setFocusProxy( d->familyList );
+
+ d->familyAccel
+ = new TQLabel( d->familyList, tr("&Font"), this, "family accelerator" );
+ d->familyAccel->setIndent( 2 );
+
+ d->styleEdit = new TQLineEdit( this, "font style I" );
+ d->styleEdit->setReadOnly( TRUE );
+ d->styleList = new TQListBox( this, "font style II" );
+ d->styleEdit->setFocusProxy( d->styleList );
+
+ d->styleAccel
+ = new TQLabel( d->styleList, tr("Font st&yle"), this, "style accelerator" );
+ d->styleAccel->setIndent( 2 );
+
+ d->sizeEdit = new TQLineEdit( this, "font size I" );
+ d->sizeEdit->setFocusPolicy( Qt::ClickFocus );
+ TQIntValidator *validator = new TQIntValidator( 1, 512, TQT_TQOBJECT(this) );
+ d->sizeEdit->setValidator( validator );
+ d->sizeList = new TQListBox( this, "font size II" );
+
+ d->sizeAccel
+ = new TQLabel ( d->sizeEdit, tr("&Size"), this, "size accelerator" );
+ d->sizeAccel->setIndent( 2 );
+
+ // effects box
+ d->effects = new TQVGroupBox( tr("Effects"), this, "font effects" );
+ d->strikeout = new TQCheckBox( d->effects, "strikeout on/off" );
+ d->strikeout->setText( tr("Stri&keout") );
+ d->underline = new TQCheckBox( d->effects, "underline on/off" );
+ d->underline->setText( tr("&Underline") );
+
+ d->sample = new TQHGroupBox( tr("Sample"), this, "sample text" );
+ d->sampleEdit = new TQLineEdit( d->sample, "r/w sample text" );
+ d->sampleEdit->tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Ignored, TQSizePolicy::Ignored) );
+ d->sampleEdit->tqsetAlignment( Qt::AlignCenter );
+ // Note that the sample text is *not* translated with tr(), as the
+ // characters used depend on the charset encoding.
+ d->sampleEdit->setText( "AaBbYyZz" );
+
+ d->scriptCombo = new TQComboBox( FALSE, this, "font encoding" );
+
+ d->scriptAccel
+ = new TQLabel( d->scriptCombo, tr("Scr&ipt"), this,"encoding label");
+ d->scriptAccel->setIndent( 2 );
+
+ d->size = 0;
+ d->smoothScalable = FALSE;
+
+ connect( d->scriptCombo, TQT_SIGNAL(activated(int)),
+ TQT_SLOT(scriptHighlighted(int)) );
+ connect( d->familyList, TQT_SIGNAL(highlighted(int)),
+ TQT_SLOT(familyHighlighted(int)) );
+ connect( d->styleList, TQT_SIGNAL(highlighted(int)),
+ TQT_SLOT(styleHighlighted(int)) );
+ connect( d->sizeList, TQT_SIGNAL(highlighted(const TQString&)),
+ TQT_SLOT(sizeHighlighted(const TQString&)) );
+ connect( d->sizeEdit, TQT_SIGNAL(textChanged(const TQString&)),
+ TQT_SLOT(sizeChanged(const TQString&)) );
+
+ connect( d->strikeout, TQT_SIGNAL(clicked()),
+ TQT_SLOT(updateSample()) );
+ connect( d->underline, TQT_SIGNAL(clicked()),
+ TQT_SLOT(updateSample()) );
+
+ (void)d->familyList->tqsizeHint();
+ (void)d->styleList->tqsizeHint();
+ (void)d->sizeList->tqsizeHint();
+
+ for (int i = 0; i < TQFont::NScripts; i++) {
+ TQString scriptname = TQFontDatabase::scriptName((TQFont::Script) i);
+ if ( !scriptname.isEmpty() )
+ d->scriptCombo->insertItem( scriptname );
+ }
+
+ updateFamilies();
+ if ( d->familyList->count() != 0 )
+ d->familyList->setCurrentItem( 0 );
+
+ // grid tqlayout
+ TQGridLayout * mainGrid = new TQGridLayout( this, 9, 6, 12, 0 );
+
+ mainGrid->addWidget( d->familyAccel, 0, 0 );
+ mainGrid->addWidget( d->familyEdit, 1, 0 );
+ mainGrid->addWidget( d->familyList, 2, 0 );
+
+ mainGrid->addWidget( d->styleAccel, 0, 2 );
+ mainGrid->addWidget( d->styleEdit, 1, 2 );
+ mainGrid->addWidget( d->styleList, 2, 2 );
+
+ mainGrid->addWidget( d->sizeAccel, 0, 4 );
+ mainGrid->addWidget( d->sizeEdit, 1, 4 );
+ mainGrid->addWidget( d->sizeList, 2, 4 );
+
+ mainGrid->setColStretch( 0, 38 );
+ mainGrid->setColStretch( 2, 24 );
+ mainGrid->setColStretch( 4, 10 );
+
+ mainGrid->addColSpacing( 1, 6 );
+ mainGrid->addColSpacing( 3, 6 );
+ mainGrid->addColSpacing( 5, 6 );
+
+ mainGrid->addRowSpacing( 3, 12 );
+
+ mainGrid->addWidget( d->effects, 4, 0 );
+
+ mainGrid->addMultiCellWidget( d->sample, 4, 7, 2, 4 );
+
+ mainGrid->addWidget( d->scriptAccel, 5, 0 );
+ mainGrid->addRowSpacing( 6, 2 );
+ mainGrid->addWidget( d->scriptCombo, 7, 0 );
+
+ mainGrid->addRowSpacing( 8, 12 );
+
+ TQHBoxLayout *buttonBox = new TQHBoxLayout;
+ mainGrid->addMultiCell( TQT_TQLAYOUTITEM(buttonBox), 9, 9, 0, 4 );
+
+ buttonBox->addStretch( 1 );
+ TQString okt = modal ? tr("OK") : tr("Apply");
+ d->ok = new TQPushButton( okt, this, "accept font selection" );
+ buttonBox->addWidget( d->ok );
+ if ( modal )
+ connect( d->ok, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) );
+ d->ok->setDefault( TRUE );
+
+ buttonBox->addSpacing( 12 );
+
+ TQString cancelt = modal ? tr("Cancel") : tr("Close");
+ d->cancel = new TQPushButton( cancelt, this, "cancel/close" );
+ buttonBox->addWidget( d->cancel );
+ connect( d->cancel, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) );
+
+ resize( 500, 360 );
+
+ d->sizeEdit->installEventFilter( this );
+ d->familyList->installEventFilter( this );
+ d->styleList->installEventFilter( this );
+ d->sizeList->installEventFilter( this );
+
+ d->familyList->setFocus();
+}
+
+/*!
+ \internal
+ Destroys the font dialog and frees up its storage.
+*/
+
+TQFontDialog::~TQFontDialog()
+{
+ delete d;
+ d = 0;
+}
+
+/*!
+ Executes a modal font dialog and returns a font.
+
+ If the user clicks OK, the selected font is returned. If the user
+ clicks Cancel, the \a initial font is returned.
+
+ The dialog is called \a name, with the tqparent \a tqparent.
+ \a initial is the initially selected font.
+ If the \a ok parameter is not-null, \e *\a ok is set to TRUE if the
+ user clicked OK, and set to FALSE if the user clicked Cancel.
+
+ This static function is less flexible than the full TQFontDialog
+ object, but is convenient and easy to use.
+
+ Examples:
+ \code
+ bool ok;
+ TQFont font = TQFontDialog::getFont( &ok, TQFont( "Times", 12 ), this );
+ if ( ok ) {
+ // font is set to the font the user selected
+ } else {
+ // the user canceled the dialog; font is set to the initial
+ // value, in this case Times, 12.
+ }
+ \endcode
+
+ The dialog can also be used to set a widget's font directly:
+ \code
+ myWidget.setFont( TQFontDialog::getFont( 0, myWidget.font() ) );
+ \endcode
+ In this example, if the user clicks OK the font they chose will be
+ used, and if they click Cancel the original font is used.
+*/
+TQFont TQFontDialog::getFont( bool *ok, const TQFont &initial,
+ TQWidget *tqparent, const char* name)
+{
+ return getFont( ok, &initial, tqparent, name );
+}
+
+/*!
+ \overload
+
+ Executes a modal font dialog and returns a font.
+
+ If the user clicks OK, the selected font is returned. If the user
+ clicks Cancel, the TQt default font is returned.
+
+ The dialog is called \a name, with tqparent \a tqparent.
+ If the \a ok parameter is not-null, \e *\a ok is set to TRUE if the
+ user clicked OK, and FALSE if the user clicked Cancel.
+
+ This static function is less functional than the full TQFontDialog
+ object, but is convenient and easy to use.
+
+ Example:
+ \code
+ bool ok;
+ TQFont font = TQFontDialog::getFont( &ok, this );
+ if ( ok ) {
+ // font is set to the font the user selected
+ } else {
+ // the user canceled the dialog; font is set to the default
+ // application font, TQApplication::font()
+ }
+ \endcode
+
+*/
+TQFont TQFontDialog::getFont( bool *ok, TQWidget *tqparent,const char* name)
+{
+ return getFont( ok, 0, tqparent, name );
+}
+
+TQFont TQFontDialog::getFont( bool *ok, const TQFont *def,
+ TQWidget *tqparent, const char* name)
+{
+ TQFont result;
+ if ( def )
+ result = *def;
+
+ TQFontDialog *dlg = new TQFontDialog( tqparent, name, TRUE );
+
+ dlg->setFont( ( def ? *def : TQFont() ) );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ dlg->setCaption( tr("Select Font") );
+#endif
+
+ bool res = (dlg->exec() == TQDialog::Accepted);
+ if ( res )
+ result = dlg->font();
+ if ( ok )
+ *ok = res;
+ delete dlg;
+ return result;
+}
+
+
+/*!
+ \internal
+ An event filter to make the Up, Down, PageUp and PageDown keys work
+ correctly in the line edits. The source of the event is the object
+ \a o and the event is \a e.
+*/
+
+bool TQFontDialog::eventFilter( TQObject * o , TQEvent * e )
+{
+ if ( e->type() == TQEvent::KeyPress) {
+ TQKeyEvent * k = (TQKeyEvent *)e;
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->sizeEdit) &&
+ (k->key() == Qt::Key_Up ||
+ k->key() == Qt::Key_Down ||
+ k->key() == TQt::Key_Prior ||
+ k->key() == TQt::Key_Next) ) {
+
+ int ci = d->sizeList->currentItem();
+ (void)TQApplication::sendEvent( d->sizeList, k );
+
+ if ( ci != d->sizeList->currentItem() &&
+ tqstyle().tqstyleHint(TQStyle::SH_FontDialog_SelectAssociatedText, this))
+ d->sizeEdit->selectAll();
+ return TRUE;
+ } else if ( ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->familyList) || TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->styleList) ) &&
+ ( k->key() == Qt::Key_Return || k->key() == Qt::Key_Enter) ) {
+ k->accept();
+ accept();
+ return TRUE;
+ }
+ } else if ( e->type() == TQEvent::FocusIn &&
+ tqstyle().tqstyleHint(TQStyle::SH_FontDialog_SelectAssociatedText, this) ) {
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->familyList) )
+ d->familyEdit->selectAll();
+ else if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->styleList) )
+ d->styleEdit->selectAll();
+ else if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->sizeList) )
+ d->sizeEdit->selectAll();
+ } else if ( e->type() == TQEvent::MouseButtonPress && TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->sizeList) ) {
+ d->sizeEdit->setFocus();
+ }
+ return TQDialog::eventFilter( o, e );
+}
+
+#ifdef TQ_WS_MAC
+// #define SHOW_FONTS_IN_FAMILIES
+#endif
+
+#ifdef SHOW_FONTS_IN_FAMILIES
+#include "tqpainter.h"
+#include <sizeedit.h>
+
+class TQListBoxFontText : public TQListBoxText
+{
+ TQFont cfont;
+public:
+ TQListBoxFontText( const TQString & text );
+ ~TQListBoxFontText() { }
+
+ int height( const TQListBox * ) const;
+ int width( const TQListBox * ) const;
+
+protected:
+ void paint( TQPainter * );
+};
+
+TQListBoxFontText::TQListBoxFontText( const TQString & text )
+ : TQListBoxText(text), cfont(text)
+{
+}
+
+int TQListBoxFontText::height( const TQListBox * ) const
+{
+ TQFontMetrics fm(cfont);
+ return TQMAX( fm.lineSpacing() + 2, TQApplication::globalStrut().height() );
+}
+
+int TQListBoxFontText::width( const TQListBox * ) const
+{
+ TQFontMetrics fm(cfont);
+ return TQMAX( fm.width( text() ) + 6, TQApplication::globalStrut().width() );
+}
+
+void TQListBoxFontText::paint( TQPainter *painter )
+{
+ painter->save();
+ painter->setFont(cfont);
+ TQListBoxText::paint(painter);
+ painter->restore();
+}
+
+#endif
+
+/*!
+ \internal
+ Updates the contents of the "font family" list box. This
+ function can be reimplemented if you have special requirements.
+*/
+
+void TQFontDialog::updateFamilies()
+{
+ d->familyList->blockSignals( TRUE );
+
+ enum match_t { MATCH_NONE=0, MATCH_LAST_RESORT=1, MATCH_APP=2, MATCH_FALLBACK, MATCH_FAMILY=3 };
+
+ TQStringList familyNames = d->fdb.tqfamilies(d->script);
+ {
+ // merge the tqunicode/unknown family list with the above list.
+ TQStringList l = d->fdb.tqfamilies(TQFont::Unicode) +
+ d->fdb.tqfamilies(TQFont::UnknownScript);
+ TQStringList::ConstIterator it = l.begin(), end = l.end();
+ for (; it != end; ++it) {
+ if (! familyNames.tqcontains(*it))
+ familyNames << *it;
+ }
+ }
+
+ familyNames.sort();
+
+ d->familyList->clear();
+#ifdef SHOW_FONTS_IN_FAMILIES
+ TQStringList::Iterator it = familyNames.begin();
+ int idx = 0;
+ for( ; it != familyNames.end() ; ++it )
+ d->familyList->insertItem(new TQListBoxFontText(*it), idx++);
+#else
+ d->familyList->insertStringList( familyNames );
+#endif
+
+ TQString foundryName1, familyName1, foundryName2, familyName2;
+ int bestFamilyMatch = -1;
+ match_t bestFamilyType = MATCH_NONE;
+
+ TQFont f;
+
+ // ##### do the right thing for a list of family names in the font.
+ TQFontDatabase::tqparseFontName(d->family, foundryName1, familyName1);
+
+ TQStringList::Iterator it = familyNames.begin();
+ int i = 0;
+ for( ; it != familyNames.end(); ++it, ++i ) {
+
+ TQFontDatabase::tqparseFontName(*it, foundryName2, familyName2);
+
+ //try to match..
+ if ( familyName1 == familyName2 ) {
+ bestFamilyType = MATCH_FAMILY;
+ if ( foundryName1 == foundryName2 ) {
+ bestFamilyMatch = i;
+ break;
+ }
+ if ( bestFamilyMatch < MATCH_FAMILY )
+ bestFamilyMatch = i;
+ }
+
+ //and try some fall backs
+ match_t type = MATCH_NONE;
+ if ( bestFamilyType <= MATCH_NONE && familyName2 == f.lastResortFamily() )
+ type = MATCH_LAST_RESORT;
+ if ( bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.family() )
+ type = MATCH_APP;
+ // ### add fallback for script
+ if ( type != MATCH_NONE ) {
+ bestFamilyType = type;
+ bestFamilyMatch = i;
+ }
+ }
+
+ if (i != -1 && bestFamilyType != MATCH_NONE)
+ d->familyList->setCurrentItem(bestFamilyMatch);
+ else
+ d->familyList->setCurrentItem( 0 );
+ d->familyEdit->setText( d->familyList->currentText() );
+ if ( tqstyle().tqstyleHint(TQStyle::SH_FontDialog_SelectAssociatedText, this) &&
+ d->familyList->hasFocus() )
+ d->familyEdit->selectAll();
+
+ d->familyList->blockSignals( FALSE );
+ updateStyles();
+}
+
+/*!
+ \internal
+ Updates the contents of the "font style" list box. This
+ function can be reimplemented if you have special requirements.
+*/
+
+void TQFontDialog::updateStyles()
+{
+ d->styleList->blockSignals( TRUE );
+
+ d->styleList->clear();
+
+ TQStringList styles = d->fdb.tqstyles( d->familyList->currentText() );
+
+ if ( styles.isEmpty() ) {
+ d->styleEdit->clear();
+ d->smoothScalable = FALSE;
+ } else {
+ d->styleList->insertStringList( styles );
+
+ if ( !d->style.isEmpty() ) {
+ bool found = FALSE;
+ bool first = TRUE;
+ TQString cstyle = d->style;
+ redo:
+ for ( int i = 0 ; i < (int)d->styleList->count() ; i++ ) {
+ if ( cstyle == d->styleList->text(i) ) {
+ d->styleList->setCurrentItem( i );
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found && first) {
+ if (cstyle.tqcontains("Italic")) {
+ cstyle.tqreplace("Italic", "Oblique");
+ first = FALSE;
+ goto redo;
+ } else if (cstyle.tqcontains("Oblique")) {
+ cstyle.tqreplace("Oblique", "Italic");
+ first = FALSE;
+ goto redo;
+ }
+ }
+ if ( !found )
+ d->styleList->setCurrentItem( 0 );
+ }
+
+ d->styleEdit->setText( d->styleList->currentText() );
+ if ( tqstyle().tqstyleHint(TQStyle::SH_FontDialog_SelectAssociatedText, this) &&
+ d->styleList->hasFocus() )
+ d->styleEdit->selectAll();
+
+ d->smoothScalable = d->fdb.isSmoothlyScalable( d->familyList->currentText(), d->styleList->currentText() );
+ }
+
+ d->styleList->blockSignals( FALSE );
+
+ updateSizes();
+}
+
+/*!
+ \internal
+ Updates the contents of the "font size" list box. This
+ function can be reimplemented if you have special requirements.
+*/
+
+void TQFontDialog::updateSizes()
+{
+ d->sizeList->blockSignals( TRUE );
+
+ d->sizeList->clear();
+
+ if ( !d->familyList->currentText().isEmpty() ) {
+ TQValueList<int> sizes = d->fdb.tqpointSizes( d->familyList->currentText(), d->styleList->currentText() );
+
+ int i = 0;
+ bool found = FALSE;
+ for( TQValueList<int>::iterator it = sizes.begin() ; it != sizes.end(); ++it ) {
+ d->sizeList->insertItem( TQT_TQSTRING(TQString::number( *it )) );
+ if ( !found && *it >= d->size ) {
+ d->sizeList->setCurrentItem( i );
+ found = TRUE;
+ }
+ ++i;
+ }
+ if ( !found ) {
+ // we request a size bigger than the ones in the list, select the biggest one
+ d->sizeList->setCurrentItem( d->sizeList->count() - 1 );
+ }
+
+ d->sizeEdit->blockSignals( TRUE );
+ d->sizeEdit->setText( ( d->smoothScalable ? TQString::number( d->size ) : d->sizeList->currentText() ) );
+ if ( tqstyle().tqstyleHint(TQStyle::SH_FontDialog_SelectAssociatedText, this) &&
+ d->sizeList->hasFocus() )
+ d->sizeEdit->selectAll();
+ d->sizeEdit->blockSignals( FALSE );
+ } else {
+ d->sizeEdit->clear();
+ }
+
+ d->sizeList->blockSignals( FALSE );
+ updateSample();
+}
+
+void TQFontDialog::updateSample()
+{
+ if ( d->familyList->currentText().isEmpty() )
+ d->sampleEdit->clear();
+ else
+ d->sampleEdit->setFont( font() );
+}
+
+/*!
+ \internal
+*/
+void TQFontDialog::scriptHighlighted( int index )
+{
+ d->script = (TQFont::Script)index;
+ d->sampleEdit->setText( d->fdb.scriptSample( d->script ) );
+ updateFamilies();
+}
+
+/*!
+ \internal
+*/
+void TQFontDialog::familyHighlighted( int i )
+{
+ d->family = d->familyList->text( i );
+ d->familyEdit->setText( d->family );
+ if ( tqstyle().tqstyleHint(TQStyle::SH_FontDialog_SelectAssociatedText, this) &&
+ d->familyList->hasFocus() )
+ d->familyEdit->selectAll();
+
+ updateStyles();
+}
+
+
+/*!
+ \internal
+*/
+
+void TQFontDialog::styleHighlighted( int index )
+{
+ TQString s = d->styleList->text( index );
+ d->styleEdit->setText( s );
+ if ( tqstyle().tqstyleHint(TQStyle::SH_FontDialog_SelectAssociatedText, this) &&
+ d->styleList->hasFocus() )
+ d->styleEdit->selectAll();
+
+ d->style = s;
+
+ updateSizes();
+}
+
+
+/*!
+ \internal
+*/
+
+void TQFontDialog::sizeHighlighted( const TQString &s )
+{
+ d->sizeEdit->setText( s );
+ if ( tqstyle().tqstyleHint(TQStyle::SH_FontDialog_SelectAssociatedText, this) &&
+ d->sizeEdit->hasFocus() )
+ d->sizeEdit->selectAll();
+
+ d->size = s.toInt();
+ updateSample();
+}
+
+/*!
+ \internal
+ This slot is called if the user changes the font size.
+ The size is passed in the \a s argument as a \e string.
+*/
+
+void TQFontDialog::sizeChanged( const TQString &s )
+{
+ // no need to check if the conversion is valid, since we have an TQIntValidator in the size edit
+ int size = s.toInt();
+ if ( d->size == size )
+ return;
+
+ d->size = size;
+ if ( d->sizeList->count() != 0 ) {
+ int i;
+ for ( i = 0 ; i < (int)d->sizeList->count() - 1 ; i++ ) {
+ if ( d->sizeList->text(i).toInt() >= d->size )
+ break;
+ }
+ d->sizeList->blockSignals( TRUE );
+ d->sizeList->setCurrentItem( i );
+ d->sizeList->blockSignals( FALSE );
+ }
+ updateSample();
+}
+
+/*!
+ \internal
+ Sets the font highlighted in the TQFontDialog to font \a f.
+
+ \sa font()
+*/
+
+void TQFontDialog::setFont( const TQFont &f )
+{
+ d->family = f.family();
+ d->style = d->fdb.styleString( f );
+ d->size = f.pointSize();
+ if ( d->size == -1 ) {
+ TQFontInfo fi( f );
+ d->size = fi.pointSize();
+ }
+ d->strikeout->setChecked( f.strikeOut() );
+ d->underline->setChecked( f.underline() );
+
+ updateFamilies();
+}
+
+/*!
+ \internal
+ Returns the font which the user has chosen.
+
+ \sa setFont()
+*/
+
+TQFont TQFontDialog::font() const
+{
+ int pSize = d->sizeEdit->text().toInt();
+
+ TQFont f = d->fdb.font( d->familyList->currentText(), d->style, pSize );
+ f.setStrikeOut( d->strikeout->isChecked() );
+ f.setUnderline( d->underline->isChecked() );
+ return f;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/dialogs/tqfontdialog.h b/tqtinterface/qt4/src/dialogs/tqfontdialog.h
new file mode 100644
index 0000000..2862fe5
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqfontdialog.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Definition of TQFontDialog
+**
+** Created : 970605
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFONTDIALOG_H
+#define TQFONTDIALOG_H
+
+#include "tqwindowdefs.h"
+
+#ifndef TQT_NO_FONTDIALOG
+
+//
+// W A R N I N G
+// -------------
+//
+// This class is under development and has private constructors.
+//
+// You may use the public static getFont() functions which are guaranteed
+// to be available in the future.
+//
+
+#ifndef TQT_H
+#include "tqdialog.h"
+#include "tqfont.h"
+#endif // TQT_H
+
+class TQFontDialogPrivate;
+
+class TQ_EXPORT TQFontDialog: public TQDialog
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ static TQFont getFont( bool *ok, const TQFont &def,
+ TQWidget* tqparent=0, const char* name=0);
+ static TQFont getFont( bool *ok, TQWidget* tqparent=0, const char* name=0);
+
+private:
+ static TQFont getFont( bool *ok, const TQFont *def,
+ TQWidget* tqparent=0, const char* name=0);
+
+ TQFontDialog( TQWidget* tqparent=0, const char* name=0, bool modal=FALSE,
+ WFlags f=0 );
+ ~TQFontDialog();
+
+ TQFont font() const;
+ void setFont( const TQFont &font );
+
+ bool eventFilter( TQObject *, TQEvent * );
+
+ void updateFamilies();
+ void updateStyles();
+ void updateSizes();
+
+private Q_SLOTS:
+ void sizeChanged( const TQString &);
+ void familyHighlighted( int );
+ void scriptHighlighted( int );
+ void styleHighlighted( int );
+ void sizeHighlighted( const TQString & );
+ void updateSample();
+
+private:
+ friend class TQFontDialogPrivate;
+ TQFontDialogPrivate * d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQFontDialog( const TQFontDialog & );
+ TQFontDialog& operator=( const TQFontDialog & );
+#endif
+};
+
+#endif
+
+#endif // TQFONTDIALOG_H
diff --git a/tqtinterface/qt4/src/dialogs/tqinputdialog.cpp b/tqtinterface/qt4/src/dialogs/tqinputdialog.cpp
new file mode 100644
index 0000000..951826b
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqinputdialog.cpp
@@ -0,0 +1,532 @@
+/****************************************************************************
+**
+** Implementation of TQInputDialog class
+**
+** Created : 991212
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqinputdialog.h"
+
+#ifndef TQT_NO_INPUTDIALOG
+
+#include "tqlayout.h"
+#include "tqlabel.h"
+#include "tqlineedit.h"
+#include "tqpushbutton.h"
+#include "tqspinbox.h"
+#include "tqcombobox.h"
+#include "tqwidgetstack.h"
+#include "tqvalidator.h"
+#include "tqapplication.h"
+
+class TQInputDialogPrivate
+{
+public:
+ friend class TQInputDialog;
+ TQLabel *label;
+ TQLineEdit *lineEdit;
+ TQSpinBox *spinBox;
+ TQComboBox *comboBox, *editComboBox;
+ TQPushButton *ok;
+ TQWidgetStack *stack;
+ TQInputDialog::Type type;
+};
+
+/*!
+ \class TQInputDialog
+ \brief The TQInputDialog class provides a simple convenience dialog to get a single value from the user.
+ \ingroup dialogs
+ \mainclass
+
+ The input value can be a string, a number or an item from a list. A
+ label must be set to tell the user what they should enter.
+
+ Four static convenience functions are provided:
+ getText(), getInteger(), getDouble() and getItem(). All the
+ functions can be used in a similar way, for example:
+ \code
+ bool ok;
+ TQString text = TQInputDialog::getText(
+ "MyApp 3000", "Enter your name:", TQLineEdit::Normal,
+ TQString::null, &ok, this );
+ if ( ok && !text.isEmpty() ) {
+ // user entered something and pressed OK
+ } else {
+ // user entered nothing or pressed Cancel
+ }
+ \endcode
+
+ \img inputdialogs.png Input Dialogs
+*/
+
+/*!
+ \enum TQInputDialog::Type
+
+ This enum specifies the type of the dialog, i.e. what kind of data you
+ want the user to input:
+
+ \value LineEdit A TQLineEdit is used for obtaining string or numeric
+ input. The TQLineEdit can be accessed using lineEdit().
+
+ \value SpinBox A TQSpinBox is used for obtaining integer input.
+ Use spinBox() to access the TQSpinBox.
+
+ \value ComboBox A read-only TQComboBox is used to provide a fixed
+ list of choices from which the user can choose.
+ Use comboBox() to access the TQComboBox.
+
+ \value EditableComboBox An editable TQComboBox is used to provide a fixed
+ list of choices from which the user can choose, but which also
+ allows the user to enter their own value instead.
+ Use editableComboBox() to access the TQComboBox.
+*/
+
+/*!
+ Constructs the dialog. The \a label is the text which is shown to the user
+ (it should tell the user what they are expected to enter). The \a tqparent
+ is the dialog's tqparent widget. The widget is called \a name. If \a
+ modal is TRUE (the default) the dialog will be modal. The \a type
+ parameter is used to specify which type of dialog to construct.
+
+ \sa getText(), getInteger(), getDouble(), getItem()
+*/
+
+TQInputDialog::TQInputDialog( const TQString &label, TQWidget* tqparent,
+ const char* name, bool modal, Type type )
+ : TQDialog( tqparent, name, modal )
+{
+ d = new TQInputDialogPrivate;
+ d->lineEdit = 0;
+ d->spinBox = 0;
+ d->comboBox = 0;
+
+ TQVBoxLayout *vbox = new TQVBoxLayout( this, 6, 6 );
+
+ d->label = new TQLabel( label, this, "qt_inputdlg_lbl" );
+ vbox->addWidget( d->label );
+
+ d->stack = new TQWidgetStack( this, "qt_inputdlg_ws" );
+ vbox->addWidget( d->stack );
+ d->lineEdit = new TQLineEdit( d->stack, "qt_inputdlg_le" );
+ d->spinBox = new TQSpinBox( d->stack, "qt_inputdlg_sb" );
+ d->comboBox = new TQComboBox( FALSE, d->stack, "qt_inputdlg_cb" );
+ d->editComboBox = new TQComboBox( TRUE, d->stack, "qt_inputdlg_editcb" );
+
+ TQHBoxLayout *hbox = new TQHBoxLayout( 6 );
+ vbox->addLayout( hbox, Qt::AlignRight );
+
+ d->ok = new TQPushButton( tr( "OK" ), this, "qt_ok_btn" );
+ d->ok->setDefault( TRUE );
+ TQPushButton *cancel = new TQPushButton( tr( "Cancel" ), this, "qt_cancel_btn" );
+
+ TQSize bs = d->ok->tqsizeHint().expandedTo( cancel->tqsizeHint() );
+ d->ok->setFixedSize( bs );
+ cancel->setFixedSize( bs );
+
+ hbox->addStretch();
+ hbox->addWidget( d->ok );
+ hbox->addWidget( cancel );
+
+ connect( d->lineEdit, TQT_SIGNAL( returnPressed() ),
+ this, TQT_SLOT( tryAccept() ) );
+ connect( d->lineEdit, TQT_SIGNAL( textChanged(const TQString&) ),
+ this, TQT_SLOT( textChanged(const TQString&) ) );
+
+ connect( d->ok, TQT_SIGNAL( clicked() ), this, TQT_SLOT( accept() ) );
+ connect( cancel, TQT_SIGNAL( clicked() ), this, TQT_SLOT( reject() ) );
+
+ TQSize sh = tqsizeHint().expandedTo( TQSize(400, 10) );
+ setType( type );
+ resize( sh.width(), vbox->heightForWidth(sh.width()) );
+}
+
+/*!
+ Returns the line edit which is used in LineEdit mode.
+*/
+
+TQLineEdit *TQInputDialog::lineEdit() const
+{
+ return d->lineEdit;
+}
+
+/*!
+ Returns the spinbox which is used in SpinBox mode.
+*/
+
+TQSpinBox *TQInputDialog::spinBox() const
+{
+ return d->spinBox;
+}
+
+/*!
+ Returns the combobox which is used in ComboBox mode.
+*/
+
+TQComboBox *TQInputDialog::comboBox() const
+{
+ return d->comboBox;
+}
+
+/*!
+ Returns the combobox which is used in EditableComboBox mode.
+*/
+
+TQComboBox *TQInputDialog::editableComboBox() const
+{
+ return d->editComboBox;
+}
+
+/*!
+ Sets the input type of the dialog to \a t.
+*/
+
+void TQInputDialog::setType( Type t )
+{
+ TQWidget *input = 0;
+ switch ( t ) {
+ case LineEdit:
+ input = d->lineEdit;
+ break;
+ case SpinBox:
+ input = d->spinBox;
+ break;
+ case ComboBox:
+ input = d->comboBox;
+ break;
+ case EditableComboBox:
+ input = d->editComboBox;
+ break;
+ default:
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQInputDialog::setType: Invalid type" );
+#endif
+ break;
+ }
+ if ( input ) {
+ d->stack->raiseWidget( input );
+ d->stack->setFixedHeight( input->tqsizeHint().height() );
+ input->setFocus();
+#ifndef TQT_NO_ACCEL
+ d->label->setBuddy( input );
+#endif
+ }
+
+ d->type = t;
+}
+
+/*!
+ Returns the input type of the dialog.
+
+ \sa setType()
+*/
+
+TQInputDialog::Type TQInputDialog::type() const
+{
+ return d->type;
+}
+
+/*!
+ Destructor.
+*/
+
+TQInputDialog::~TQInputDialog()
+{
+ delete d;
+}
+
+/*!
+ Static convenience function to get a string from the user. \a
+ caption is the text which is displayed in the title bar of the
+ dialog. \a label is the text which is shown to the user (it should
+ say what should be entered). \a text is the default text which is
+ placed in the line edit. The \a mode is the echo mode the line edit
+ will use. If \a ok is not-null \e *\a ok will be set to TRUE if the
+ user pressed OK and to FALSE if the user pressed Cancel. The
+ dialog's tqparent is \a tqparent; the dialog is called \a name. The
+ dialog will be modal.
+
+ This function returns the text which has been entered in the line
+ edit. It will not return an empty string.
+
+ Use this static function like this:
+
+ \code
+ bool ok;
+ TQString text = TQInputDialog::getText(
+ "MyApp 3000", "Enter your name:", TQLineEdit::Normal,
+ TQString::null, &ok, this );
+ if ( ok && !text.isEmpty() ) {
+ // user entered something and pressed OK
+ } else {
+ // user entered nothing or pressed Cancel
+ }
+ \endcode
+*/
+
+TQString TQInputDialog::getText( const TQString &caption, const TQString &label,
+ TQLineEdit::EchoMode mode, const TQString &text,
+ bool *ok, TQWidget *tqparent, const char *name )
+{
+ TQInputDialog *dlg = new TQInputDialog( label, tqparent,
+ name ? name : "qt_inputdlg_gettext",
+ TRUE, LineEdit );
+
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ dlg->setCaption( caption );
+#endif
+ dlg->lineEdit()->setText( text );
+ dlg->lineEdit()->setEchoMode( mode );
+
+ bool ok_ = FALSE;
+ TQString result;
+ ok_ = dlg->exec() == TQDialog::Accepted;
+ if ( ok )
+ *ok = ok_;
+ if ( ok_ )
+ result = dlg->lineEdit()->text();
+
+ delete dlg;
+ return result;
+}
+
+/*!
+ Static convenience function to get an integer input from the
+ user. \a caption is the text which is displayed in the title bar
+ of the dialog. \a label is the text which is shown to the user
+ (it should say what should be entered). \a value is the default
+ integer which the spinbox will be set to. \a minValue and \a
+ maxValue are the minimum and maximum values the user may choose,
+ and \a step is the amount by which the values change as the user
+ presses the arrow buttons to increment or decrement the value.
+
+ If \a ok is not-null *\a ok will be set to TRUE if the user
+ pressed OK and to FALSE if the user pressed Cancel. The dialog's
+ tqparent is \a tqparent; the dialog is called \a name. The dialog will
+ be modal.
+
+ This function returns the integer which has been entered by the user.
+
+ Use this static function like this:
+
+ \code
+ bool ok;
+ int res = TQInputDialog::getInteger(
+ "MyApp 3000", "Enter a number:", 22, 0, 1000, 2,
+ &ok, this );
+ if ( ok ) {
+ // user entered something and pressed OK
+ } else {
+ // user pressed Cancel
+ }
+ \endcode
+*/
+
+int TQInputDialog::getInteger( const TQString &caption, const TQString &label,
+ int value, int minValue, int maxValue, int step, bool *ok,
+ TQWidget *tqparent, const char *name )
+{
+ TQInputDialog *dlg = new TQInputDialog( label, tqparent,
+ name ? name : "qt_inputdlg_getint",
+ TRUE, SpinBox );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ dlg->setCaption( caption );
+#endif
+ dlg->spinBox()->setRange( minValue, maxValue );
+ dlg->spinBox()->setSteps( step, 0 );
+ dlg->spinBox()->setValue( value );
+
+ bool ok_ = FALSE;
+ int result;
+ ok_ = dlg->exec() == TQDialog::Accepted;
+ if ( ok )
+ *ok = ok_;
+ result = dlg->spinBox()->value();
+
+ delete dlg;
+ return result;
+}
+
+/*!
+ Static convenience function to get a floating point number from
+ the user. \a caption is the text which is displayed in the title
+ bar of the dialog. \a label is the text which is shown to the user
+ (it should say what should be entered). \a value is the default
+ floating point number that the line edit will be set to. \a
+ minValue and \a maxValue are the minimum and maximum values the
+ user may choose, and \a decimals is the maximum number of decimal
+ places the number may have.
+
+ If \a ok is not-null \e *\a ok will be set to TRUE if the user
+ pressed OK and to FALSE if the user pressed Cancel. The dialog's
+ tqparent is \a tqparent; the dialog is called \a name. The dialog will
+ be modal.
+
+ This function returns the floating point number which has been
+ entered by the user.
+
+ Use this static function like this:
+
+ \code
+ bool ok;
+ double res = TQInputDialog::getDouble(
+ "MyApp 3000", "Enter a decimal number:", 33.7, 0,
+ 1000, 2, &ok, this );
+ if ( ok ) {
+ // user entered something and pressed OK
+ } else {
+ // user pressed Cancel
+ }
+ \endcode
+*/
+
+double TQInputDialog::getDouble( const TQString &caption, const TQString &label,
+ double value, double minValue, double maxValue,
+ int decimals, bool *ok, TQWidget *tqparent,
+ const char *name )
+{
+ TQInputDialog dlg( label, tqparent,
+ name ? name : "qt_inputdlg_getdbl", TRUE, LineEdit );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ dlg.setCaption( caption );
+#endif
+ dlg.lineEdit()->setValidator( new TQDoubleValidator( minValue, maxValue, decimals, TQT_TQOBJECT(dlg.lineEdit()) ) );
+ dlg.lineEdit()->setText( TQString::number( value, 'f', decimals ) );
+ dlg.lineEdit()->selectAll();
+
+ bool accepted = ( dlg.exec() == TQDialog::Accepted );
+ if ( ok )
+ *ok = accepted;
+ return dlg.lineEdit()->text().toDouble();
+}
+
+/*!
+ Static convenience function to let the user select an item from a
+ string list. \a caption is the text which is displayed in the title
+ bar of the dialog. \a label is the text which is shown to the user (it
+ should say what should be entered). \a list is the
+ string list which is inserted into the combobox, and \a current is the number
+ of the item which should be the current item. If \a editable is TRUE
+ the user can enter their own text; if \a editable is FALSE the user
+ may only select one of the existing items.
+
+ If \a ok is not-null \e *\a ok will be set to TRUE if the user
+ pressed OK and to FALSE if the user pressed Cancel. The dialog's
+ tqparent is \a tqparent; the dialog is called \a name. The dialog will
+ be modal.
+
+ This function returns the text of the current item, or if \a
+ editable is TRUE, the current text of the combobox.
+
+ Use this static function like this:
+
+ \code
+ TQStringList lst;
+ lst << "First" << "Second" << "Third" << "Fourth" << "Fifth";
+ bool ok;
+ TQString res = TQInputDialog::getItem(
+ "MyApp 3000", "Select an item:", lst, 1, TRUE, &ok,
+ this );
+ if ( ok ) {
+ // user selected an item and pressed OK
+ } else {
+ // user pressed Cancel
+ }
+ \endcode
+*/
+
+TQString TQInputDialog::getItem( const TQString &caption, const TQString &label, const TQStringList &list,
+ int current, bool editable,
+ bool *ok, TQWidget *tqparent, const char *name )
+{
+ TQInputDialog *dlg = new TQInputDialog( label, tqparent, name ? name : "qt_inputdlg_getitem", TRUE, editable ? EditableComboBox : ComboBox );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ dlg->setCaption( caption );
+#endif
+ if ( editable ) {
+ dlg->editableComboBox()->insertStringList( list );
+ dlg->editableComboBox()->setCurrentItem( current );
+ } else {
+ dlg->comboBox()->insertStringList( list );
+ dlg->comboBox()->setCurrentItem( current );
+ }
+
+ bool ok_ = FALSE;
+ TQString result;
+ ok_ = dlg->exec() == TQDialog::Accepted;
+ if ( ok )
+ *ok = ok_;
+ if ( editable )
+ result = dlg->editableComboBox()->currentText();
+ else
+ result = dlg->comboBox()->currentText();
+
+ delete dlg;
+ return result;
+}
+
+/*!
+ \internal
+
+ This slot is invoked when the text is changed; the new text is passed
+ in \a s.
+*/
+
+void TQInputDialog::textChanged( const TQString &s )
+{
+ bool on = TRUE;
+
+ if ( d->lineEdit->validator() ) {
+ TQString str = d->lineEdit->text();
+ int index = d->lineEdit->cursorPosition();
+ on = ( d->lineEdit->validator()->validate(str, index) ==
+ TQValidator::Acceptable );
+ } else if ( type() != LineEdit ) {
+ on = !s.isEmpty();
+ }
+ d->ok->setEnabled( on );
+}
+
+/*!
+ \internal
+*/
+
+void TQInputDialog::tryAccept()
+{
+ if ( !d->lineEdit->text().isEmpty() )
+ accept();
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/dialogs/tqinputdialog.h b/tqtinterface/qt4/src/dialogs/tqinputdialog.h
new file mode 100644
index 0000000..8b7be71
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqinputdialog.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Definition of TQInputDialog class
+**
+** Created : 991212
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQINPUTDIALOG_H
+#define TQINPUTDIALOG_H
+
+#ifndef TQT_H
+#include "tqdialog.h"
+#include "tqstring.h"
+#include "tqlineedit.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_INPUTDIALOG
+
+class TQSpinBox;
+class TQComboBox;
+class TQInputDialogPrivate;
+
+class TQ_EXPORT TQInputDialog : public TQDialog
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+private:
+ enum Type { LineEdit, SpinBox, ComboBox, EditableComboBox };
+
+ TQInputDialog( const TQString &label, TQWidget* tqparent=0, const char* name=0,
+ bool modal = TRUE, Type type = LineEdit ); //### 4.0: widget flag!
+ ~TQInputDialog();
+
+ TQLineEdit *lineEdit() const;
+ TQSpinBox *spinBox() const;
+ TQComboBox *comboBox() const;
+ TQComboBox *editableComboBox() const;
+
+ void setType( Type t );
+ Type type() const;
+
+public:
+ //### 4.0: widget flag!
+ static TQString getText( const TQString &caption, const TQString &label, TQLineEdit::EchoMode echo = TQLineEdit::Normal,
+ const TQString &text = TQString::null, bool *ok = 0, TQWidget *tqparent = 0, const char *name = 0 );
+ static int getInteger( const TQString &caption, const TQString &label, int value = 0, int minValue = -2147483647,
+ int maxValue = 2147483647,
+ int step = 1, bool *ok = 0, TQWidget *tqparent = 0, const char *name = 0 );
+ static double getDouble( const TQString &caption, const TQString &label, double value = 0,
+ double minValue = -2147483647, double maxValue = 2147483647,
+ int decimals = 1, bool *ok = 0, TQWidget *tqparent = 0, const char *name = 0 );
+ static TQString getItem( const TQString &caption, const TQString &label, const TQStringList &list,
+ int current = 0, bool editable = TRUE,
+ bool *ok = 0, TQWidget *tqparent = 0, const char *name = 0 );
+
+private Q_SLOTS:
+ void textChanged( const TQString &s );
+ void tryAccept();
+
+private:
+ TQInputDialogPrivate *d;
+ friend class TQInputDialogPrivate; /* to avoid 'has no friends' warnings... */
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQInputDialog( const TQInputDialog & );
+ TQInputDialog &operator=( const TQInputDialog & );
+#endif
+};
+
+#endif // TQT_NO_INPUTDIALOG
+
+#endif // TQINPUTDIALOG_H
+
diff --git a/tqtinterface/qt4/src/dialogs/tqmessagebox.cpp b/tqtinterface/qt4/src/dialogs/tqmessagebox.cpp
new file mode 100644
index 0000000..79f6bfc
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqmessagebox.cpp
@@ -0,0 +1,2605 @@
+/****************************************************************************
+**
+** Implementation of TQMessageBox class
+**
+** Created : 950503
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmessagebox.h"
+
+#ifndef TQT_NO_MESSAGEBOX
+
+#include "tqaccel.h"
+#include "tqlabel.h"
+#include "tqpushbutton.h"
+#include "tqimage.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+#include "tqobjectlist.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+#if defined TQT_NON_COMMERCIAL
+#include "tqnc_win.h"
+#endif
+
+
+// Internal class - don't touch
+
+class TQMessageBoxLabel : public TQLabel
+{
+ TQ_OBJECT
+public:
+ TQMessageBoxLabel( TQWidget* tqparent ) : TQLabel( tqparent, "messageBoxText")
+ {
+ tqsetAlignment( TQt::AlignAuto|TQt::ExpandTabs );
+ }
+};
+#include "tqmessagebox.tqmoc"
+
+
+
+// the TQt logo, for aboutTQt
+/* XPM */
+static char * qtlogo_xpm[] = {
+"50 50 995 2",
+" c None",
+". c #2B2B7E",
+"+ c #2A2A7D",
+"@ c #28297C",
+"# c #28277B",
+"$ c #26267A",
+"% c #252579",
+"& c #242477",
+"* c #232376",
+"= c #212175",
+"- c #212174",
+"; c #1F1F73",
+"> c #1E1E72",
+", c #1D1D70",
+"' c #1C1C6F",
+") c #1B1A6E",
+"! c #1A1A6D",
+"~ c #18186C",
+"{ c #17176A",
+"] c #161669",
+"^ c #141568",
+"/ c #131367",
+"( c #121366",
+"_ c #111165",
+": c #101064",
+"< c #0F0F62",
+"[ c #0E0E61",
+"} c #0C0C60",
+"| c #0B0B5F",
+"1 c #0A0A5D",
+"2 c #09095D",
+"3 c #08085B",
+"4 c #06065A",
+"5 c #050659",
+"6 c #040458",
+"7 c #030357",
+"8 c #020255",
+"9 c #010154",
+"0 c #000053",
+"a c #2C2C80",
+"b c #29297C",
+"c c #27287B",
+"d c #222275",
+"e c #202174",
+"f c #19196D",
+"g c #17176B",
+"h c #151568",
+"i c #141467",
+"j c #131266",
+"k c #101063",
+"l c #0E0D61",
+"m c #0C0D60",
+"n c #0A0A5E",
+"o c #09095C",
+"p c #07075A",
+"q c #050559",
+"r c #030356",
+"s c #2D2E81",
+"t c #2C2C7F",
+"u c #D1D1D1",
+"v c #D0D0D0",
+"w c #CFCFCF",
+"x c #CDCDCE",
+"y c #CDCCCC",
+"z c #CBCBCB",
+"A c #CACACA",
+"B c #C9C9C9",
+"C c #C8C7C8",
+"D c #C6C6C6",
+"E c #C5C5C5",
+"F c #C4C4C4",
+"G c #C3C3C3",
+"H c #C2C2C2",
+"I c #C0C0C0",
+"J c #BFBFBF",
+"K c #BEBEBE",
+"L c #BDBDBD",
+"M c #BCBCBC",
+"N c #BABABB",
+"O c #B9B9B9",
+"P c #B8B8B8",
+"Q c #B7B7B7",
+"R c #B6B6B6",
+"S c #B5B5B5",
+"T c #B3B4B4",
+"U c #B3B3B2",
+"V c #B1B1B1",
+"W c #B0B0B0",
+"X c #AFAFAF",
+"Y c #AEAEAE",
+"Z c #ACACAC",
+"` c #ABABAB",
+" . c #AAAAAA",
+".. c #A9A9A9",
+"+. c #A8A8A8",
+"@. c #A7A7A7",
+"#. c #A6A6A6",
+"$. c #2E2F82",
+"%. c #2D2D81",
+"&. c #D2D2D2",
+"*. c #CECFCF",
+"=. c #CDCDCD",
+"-. c #CCCCCC",
+";. c #C7C8C8",
+">. c #C7C6C6",
+",. c #C1C1C1",
+"'. c #BBBBBB",
+"). c #B2B2B2",
+"!. c #ADADAD",
+"~. c #303083",
+"{. c #2E2E82",
+"]. c #D3D3D3",
+"^. c #D0CFD0",
+"/. c #CDCECD",
+"(. c #C1C1C2",
+"_. c #C1C1C0",
+":. c #BCBCBB",
+"<. c #B3B3B4",
+"[. c #B2B3B2",
+"}. c #ADACAC",
+"|. c #313184",
+"1. c #302F83",
+"2. c #D5D5D5",
+"3. c #CFCFCE",
+"4. c #C9C8C9",
+"5. c #C7C8C7",
+"6. c #C2C1C2",
+"7. c #C0C0C1",
+"8. c #BBBCBC",
+"9. c #BABABA",
+"0. c #B9BAB9",
+"a. c #B3B4B3",
+"b. c #ACACAD",
+"c. c #323285",
+"d. c #313084",
+"e. c #D6D5D5",
+"f. c #D4D5D4",
+"g. c #BB9936",
+"h. c #7E7E2B",
+"i. c #7D7D2A",
+"j. c #7C7C29",
+"k. c #7B7B27",
+"l. c #7A7A26",
+"m. c #787825",
+"n. c #777724",
+"o. c #767622",
+"p. c #757522",
+"q. c #737420",
+"r. c #72731F",
+"s. c #71711E",
+"t. c #70701D",
+"u. c #6F6F1D",
+"v. c #78929D",
+"w. c #BDBFBF",
+"x. c #333386",
+"y. c #D7D7D6",
+"z. c #D4D4D4",
+"A. c #BB9830",
+"B. c #80802C",
+"C. c #7A7926",
+"D. c #797825",
+"E. c #767623",
+"F. c #757521",
+"G. c #737320",
+"H. c #73731F",
+"I. c #76919D",
+"J. c #BDC0C0",
+"K. c #B3B3B3",
+"L. c #343488",
+"M. c #D8D8D8",
+"N. c #D7D7D7",
+"O. c #BC9932",
+"P. c #81802D",
+"Q. c #7F7F2C",
+"R. c #7D7D29",
+"S. c #797A26",
+"T. c #787925",
+"U. c #72721F",
+"V. c #77929E",
+"W. c #BEC1C1",
+"X. c #BABBBA",
+"Y. c #353589",
+"Z. c #343487",
+"`. c #D9D9D9",
+" + c #D6D7D7",
+".+ c #CEC4A5",
+"++ c #BABAA0",
+"@+ c #B9B99F",
+"#+ c #B8B89E",
+"$+ c #B7B79C",
+"%+ c #B6B381",
+"&+ c #917F29",
+"*+ c #78783E",
+"=+ c #9CAC95",
+"-+ c #AEAE95",
+";+ c #AEAD93",
+">+ c #ACAC92",
+",+ c #ABAB91",
+"'+ c #AEB6B9",
+")+ c #C2C2C3",
+"!+ c #C1C2C1",
+"~+ c #36368A",
+"{+ c #DADADA",
+"]+ c #D6D6D6",
+"^+ c #D1CDAB",
+"/+ c #9E832A",
+"(+ c #7C7C28",
+"_+ c #7B7A27",
+":+ c #7A794E",
+"<+ c #B0C5CB",
+"[+ c #C9CACA",
+"}+ c #C8C8C8",
+"|+ c #C7C7C7",
+"1+ c #C2C3C2",
+"2+ c #BBBBBC",
+"3+ c #38378B",
+"4+ c #37368A",
+"5+ c #DBDBDB",
+"6+ c #D7D8D8",
+"7+ c #D7D6D6",
+"8+ c #D2CFAC",
+"9+ c #9F852A",
+"0+ c #7B7B4F",
+"a+ c #B1C6CC",
+"b+ c #CBCBCA",
+"c+ c #C8C8C9",
+"d+ c #C2C3C3",
+"e+ c #39398C",
+"f+ c #DCDCDC",
+"g+ c #D3D0AD",
+"h+ c #A0862C",
+"i+ c #7C7C50",
+"j+ c #B2C7CD",
+"k+ c #BCBBBB",
+"l+ c #3A3A8D",
+"m+ c #38398C",
+"n+ c #DEDDDE",
+"o+ c #D4D1AF",
+"p+ c #A1872D",
+"q+ c #7E7E2A",
+"r+ c #7D7D51",
+"s+ c #B3C8CE",
+"t+ c #CBCACB",
+"u+ c #CAC9CA",
+"v+ c #BBBCBB",
+"w+ c #3B3B8E",
+"x+ c #DFDFDF",
+"y+ c #DDDDDD",
+"z+ c #D9D9D8",
+"A+ c #D5D2B0",
+"B+ c #A2882E",
+"C+ c #80802D",
+"D+ c #7E7E52",
+"E+ c #B4CACF",
+"F+ c #CECECE",
+"G+ c #CACACB",
+"H+ c #C9C9CA",
+"I+ c #ADAEAD",
+"J+ c #3C3C8F",
+"K+ c #E0E0E0",
+"L+ c #DFDEDF",
+"M+ c #D9D8D9",
+"N+ c #D7D7D8",
+"O+ c #D7D3B1",
+"P+ c #A3892F",
+"Q+ c #82822E",
+"R+ c #7F7F53",
+"S+ c #B5CBD1",
+"T+ c #CACBCB",
+"U+ c #C7C7C6",
+"V+ c #BCB3B9",
+"W+ c #A29DAF",
+"X+ c #9798AF",
+"Y+ c #9DA4B7",
+"Z+ c #B2BBC1",
+"`+ c #AEAEAD",
+" @ c #040457",
+".@ c #3D3D91",
+"+@ c #3C3C90",
+"@@ c #E1E1E1",
+"#@ c #DFDFDE",
+"$@ c #D7D5B2",
+"%@ c #A48A30",
+"&@ c #82822F",
+"*@ c #81812E",
+"=@ c #808055",
+"-@ c #B6CCD1",
+";@ c #C8BCB8",
+">@ c #886C8F",
+",@ c #3E2D76",
+"'@ c #202073",
+")@ c #1F1F72",
+"!@ c #1E1E71",
+"~@ c #1C1C72",
+"{@ c #2E418C",
+"]@ c #708CB4",
+"^@ c #B7BEBF",
+"/@ c #AEADAE",
+"(@ c #050558",
+"_@ c #3F3E92",
+":@ c #3D3D90",
+"<@ c #E2E2E2",
+"[@ c #DEDFDF",
+"}@ c #D8D6B3",
+"|@ c #A58C31",
+"1@ c #848430",
+"2@ c #83832F",
+"3@ c #828156",
+"4@ c #B8CDD3",
+"5@ c #CECECC",
+"6@ c #B8969C",
+"7@ c #442979",
+"8@ c #242478",
+"9@ c #232377",
+"0@ c #1B1B6E",
+"a@ c #294A9A",
+"b@ c #9CB5BE",
+"c@ c #060659",
+"d@ c #403F93",
+"e@ c #3E3E92",
+"f@ c #E3E3E3",
+"g@ c #DEDFDE",
+"h@ c #DAD7B4",
+"i@ c #A68C32",
+"j@ c #858532",
+"k@ c #828357",
+"l@ c #B9CED4",
+"m@ c #D1D2D1",
+"n@ c #D1D0CF",
+"o@ c #BB9398",
+"p@ c #36287B",
+"q@ c #27277A",
+"r@ c #262679",
+"s@ c #252478",
+"t@ c #1C1C70",
+"u@ c #1B1B6F",
+"v@ c #1C3B96",
+"w@ c #9BB6BF",
+"x@ c #AFAFAE",
+"y@ c #07085B",
+"z@ c #414194",
+"A@ c #404093",
+"B@ c #E4E4E4",
+"C@ c #DFE0DF",
+"D@ c #DBD8B5",
+"E@ c #A78E34",
+"F@ c #868632",
+"G@ c #858531",
+"H@ c #848458",
+"I@ c #BACFD5",
+"J@ c #CCB5AA",
+"K@ c #4B2B7E",
+"L@ c #28287C",
+"M@ c #26348E",
+"N@ c #6D85B2",
+"O@ c #A7B1C0",
+"P@ c #B9B7BE",
+"Q@ c #AA9DAA",
+"R@ c #765B82",
+"S@ c #231F72",
+"T@ c #2856A7",
+"U@ c #B1BEBF",
+"V@ c #B6B5B6",
+"W@ c #B5B4B5",
+"X@ c #424295",
+"Y@ c #E5E5E5",
+"Z@ c #E0E1E1",
+"`@ c #DEDEDF",
+" # c #DCD9B7",
+".# c #A98F35",
+"+# c #878734",
+"@# c #858559",
+"## c #BBD1D6",
+"$# c #D4D1CA",
+"%# c #915581",
+"&# c #2B2B7F",
+"*# c #2A2A7E",
+"=# c #29297D",
+"-# c #2B49A4",
+";# c #A7C3CC",
+"># c #C7C7C5",
+",# c #B08A8F",
+"'# c #2D1F72",
+")# c #1B1B77",
+"!# c #609ABC",
+"~# c #B5B6B5",
+"{# c #B4B5B5",
+"]# c #08085C",
+"^# c #434396",
+"/# c #E6E6E6",
+"(# c #E0E1E0",
+"_# c #DFDFE0",
+":# c #DEDEDE",
+"<# c #DDDAB8",
+"[# c #AA9036",
+"}# c #888835",
+"|# c #86865A",
+"1# c #BCD2D7",
+"2# c #D0B7AA",
+"3# c #442E81",
+"4# c #2D2D80",
+"5# c #2A3093",
+"6# c #90BCCE",
+"7# c #C7C6C3",
+"8# c #9F687D",
+"9# c #204BA6",
+"0# c #B2BFC0",
+"a# c #B5B6B6",
+"b# c #0B0B5E",
+"c# c #0A095D",
+"d# c #444498",
+"e# c #E8E7E8",
+"f# c #E0DFDF",
+"g# c #DEDBB9",
+"h# c #AB9137",
+"i# c #898936",
+"j# c #87875B",
+"k# c #BDD3D9",
+"l# c #D7D7D5",
+"m# c #BA838F",
+"n# c #2F2F82",
+"o# c #2E2E81",
+"p# c #3C70BF",
+"q# c #C9D0D0",
+"r# c #C5B4A6",
+"s# c #442073",
+"t# c #1C2188",
+"u# c #8EB5C1",
+"v# c #BCBDBD",
+"w# c #B6B7B7",
+"x# c #B6B6B5",
+"y# c #0C0C5F",
+"z# c #454599",
+"A# c #E9E9E9",
+"B# c #E8E8E7",
+"C# c #E7E6E6",
+"D# c #E1E1E0",
+"E# c #DFDCBA",
+"F# c #AC9238",
+"G# c #8B8A37",
+"H# c #88885D",
+"I# c #BFD4DA",
+"J# c #D8D8D1",
+"K# c #9D5985",
+"L# c #2E2E86",
+"M# c #6AAAD0",
+"N# c #C8C5BD",
+"O# c #7F3F74",
+"P# c #1E1E79",
+"Q# c #64A0C0",
+"R# c #BDBCBD",
+"S# c #B5B5B6",
+"T# c #B5B4B4",
+"U# c #0D0D60",
+"V# c #46469A",
+"W# c #EAEAEA",
+"X# c #E7E8E8",
+"Y# c #E0DDBB",
+"Z# c #AE9439",
+"`# c #8B8C38",
+" $ c #8B8B37",
+".$ c #898A5E",
+"+$ c #BFD5DB",
+"@$ c #DAD5CB",
+"#$ c #844986",
+"$$ c #313185",
+"%$ c #2F2F92",
+"&$ c #8EBFD3",
+"*$ c #C9C9C5",
+"=$ c #9D5B79",
+"-$ c #4A91BF",
+";$ c #B7B6B7",
+">$ c #B6B5B5",
+",$ c #0F0E61",
+"'$ c #47489B",
+")$ c #EBEBEB",
+"!$ c #E1E0E1",
+"~$ c #DBD5CA",
+"{$ c #7A4487",
+"]$ c #323286",
+"^$ c #303097",
+"/$ c #9CC8D5",
+"($ c #CACAC8",
+"_$ c #A5687E",
+":$ c #448ABE",
+"<$ c #C3C3C4",
+"[$ c #0F0F63",
+"}$ c #48489C",
+"|$ c #47479B",
+"1$ c #ECECEC",
+"2$ c #E8E7E7",
+"3$ c #E6E7E6",
+"4$ c #DCD7CC",
+"5$ c #814988",
+"6$ c #313196",
+"7$ c #97C6D5",
+"8$ c #CCCCC8",
+"9$ c #A3637D",
+"0$ c #4A91C0",
+"a$ c #C4C3C3",
+"b$ c #BCBDBC",
+"c$ c #111164",
+"d$ c #4A4A9D",
+"e$ c #EDEDED",
+"f$ c #DDDBD3",
+"g$ c #985589",
+"h$ c #353588",
+"i$ c #323290",
+"j$ c #7DB8D4",
+"k$ c #D0D0CF",
+"l$ c #C8C4CC",
+"m$ c #CCCECE",
+"n$ c #CDCCC6",
+"o$ c #934E79",
+"p$ c #22227C",
+"q$ c #62A1C4",
+"r$ c #C4C4C5",
+"s$ c #C4C2B3",
+"t$ c #AA9B67",
+"u$ c #929263",
+"v$ c #919162",
+"w$ c #929A94",
+"x$ c #B7BDBE",
+"y$ c #BDBCBC",
+"z$ c #121265",
+"A$ c #4B4B9E",
+"B$ c #494A9D",
+"C$ c #EFEEEF",
+"D$ c #E7E8E7",
+"E$ c #DEDEDB",
+"F$ c #B77791",
+"G$ c #363689",
+"H$ c #5190CD",
+"I$ c #D5D7D7",
+"J$ c #D3D3D2",
+"K$ c #C4A5A3",
+"L$ c #453289",
+"M$ c #6B9AC6",
+"N$ c #CAC6BA",
+"O$ c #65337A",
+"P$ c #23248A",
+"Q$ c #8CB8C7",
+"R$ c #C5C2A5",
+"S$ c #967A1E",
+"T$ c #6F6F1C",
+"U$ c #6E6E1B",
+"V$ c #6D7970",
+"W$ c #B2BDBF",
+"X$ c #BDBEBE",
+"Y$ c #131366",
+"Z$ c #4C4CA0",
+"`$ c #EFF0F0",
+" % c #EEEEEE",
+".% c #E7E7E7",
+"+% c #D4AFA7",
+"@% c #3F378A",
+"#% c #344AAE",
+"$% c #B8D2D8",
+"%% c #CCB1AB",
+"&% c #4E2E80",
+"*% c #2A2A86",
+"=% c #5C6C91",
+"-% c #30287B",
+";% c #252679",
+">% c #2444A7",
+",% c #B4C6C9",
+"'% c #C6C3A6",
+")% c #977B1E",
+"!% c #71701D",
+"~% c #6E7A71",
+"{% c #B3BEC0",
+"]% c #4D4DA1",
+"^% c #F1F1F1",
+"/% c #EEEFEE",
+"(% c #DFD7CD",
+"_% c #7C488B",
+":% c #37378A",
+"<% c #4F82C7",
+"[% c #CED7D8",
+"}% c #D3C8BF",
+"|% c #7A4C82",
+"1% c #2C2D80",
+"2% c #28287B",
+"3% c #26277B",
+"4% c #4E8CC2",
+"5% c #C8CACA",
+"6% c #C7C4A7",
+"7% c #997D20",
+"8% c #72721E",
+"9% c #70701E",
+"0% c #6F7C72",
+"a% c #B4BFC1",
+"b% c #BFBEBF",
+"c% c #BDBDBE",
+"d% c #4E4EA1",
+"e% c #4D4DA0",
+"f% c #F2F2F2",
+"g% c #F0F0F0",
+"h% c #CDA3A4",
+"i% c #40388B",
+"j% c #5075BA",
+"k% c #B6CAD7",
+"l% c #D3CAC0",
+"m% c #754481",
+"n% c #283C9F",
+"o% c #A7C5CD",
+"p% c #CCCBCB",
+"q% c #B79D4F",
+"r% c #86853B",
+"s% c #797421",
+"t% c #70702B",
+"u% c #7C7F3D",
+"v% c #818B80",
+"w% c #B5BEC0",
+"x% c #BFBEBE",
+"y% c #BEBDBE",
+"z% c #16166A",
+"A% c #504FA3",
+"B% c #4E4EA2",
+"C% c #F3F3F3",
+"D% c #E0DFD9",
+"E% c #A87394",
+"F% c #38388B",
+"G% c #404A94",
+"H% c #525293",
+"I% c #463C83",
+"J% c #3A6CB9",
+"K% c #C1CDCE",
+"L% c #CBCCCB",
+"M% c #B28F27",
+"N% c #747421",
+"O% c #6F7A6C",
+"P% c #B2BFC1",
+"Q% c #C0BFC0",
+"R% c #BFBFBE",
+"S% c #17186B",
+"T% c #5050A4",
+"U% c #4F4FA3",
+"V% c #F4F4F4",
+"W% c #EFEFF0",
+"X% c #E0DBD5",
+"Y% c #A07296",
+"Z% c #343486",
+"`% c #4672B8",
+" & c #BFCCCE",
+".& c #CDCCCD",
+"+& c #BCA561",
+"@& c #91904B",
+"#& c #807623",
+"$& c #737436",
+"%& c #868A51",
+"&& c #8B948B",
+"*& c #B8C1C2",
+"=& c #18196C",
+"-& c #5252A5",
+";& c #F5F5F5",
+">& c #EFEFEF",
+",& c #E0DFDC",
+"'& c #C0A1B0",
+")& c #60488B",
+"!& c #333486",
+"~& c #303086",
+"{& c #4A65A8",
+"]& c #7C6289",
+"^& c #2A2B8E",
+"/& c #82B5CD",
+"(& c #CCC9AB",
+"_& c #9D8124",
+":& c #748077",
+"<& c #B9C4C5",
+"[& c #19186C",
+"}& c #5353A6",
+"|& c #F7F6F6",
+"1& c #F0EFEF",
+"2& c #DFDDDB",
+"3& c #C8B8C3",
+"4& c #998FB1",
+"5& c #7E79A9",
+"6& c #7475AA",
+"7& c #7A7FB1",
+"8& c #919DC2",
+"9& c #BACAD6",
+"0& c #D5D2CC",
+"a& c #A0718D",
+"b& c #2C2C8A",
+"c& c #6D9FCA",
+"d& c #CED0D0",
+"e& c #CDCAAD",
+"f& c #9F8226",
+"g& c #758178",
+"h& c #BAC5C6",
+"i& c #C4C5C4",
+"j& c #191A6D",
+"k& c #5454A8",
+"l& c #F8F8F8",
+"m& c #F6F6F6",
+"n& c #E2E1E2",
+"o& c #DADBDB",
+"p& c #D5D3CF",
+"q& c #BAB7CC",
+"r& c #CFD3D2",
+"s& c #CECBAE",
+"t& c #9F8326",
+"u& c #797925",
+"v& c #768279",
+"w& c #BBC6C8",
+"x& c #C6C6C7",
+"y& c #1A1B6E",
+"z& c #5555A9",
+"A& c #5454A7",
+"B& c #F9F9F9",
+"C& c #E1E1E2",
+"D& c #DBDBDA",
+"E& c #D9DAD9",
+"F& c #D4D3D4",
+"G& c #CFCCAF",
+"H& c #A18528",
+"I& c #7A7A27",
+"J& c #77847A",
+"K& c #BCC7C9",
+"L& c #C7C6C7",
+"M& c #5656AA",
+"N& c #5555A8",
+"O& c #FAFAFA",
+"P& c #F5EDE7",
+"Q& c #ECE8F0",
+"R& c #EFE8E2",
+"S& c #E6DDDD",
+"T& c #E5DBDB",
+"U& c #E4DADD",
+"V& c #E7E8EB",
+"W& c #EAE8E2",
+"X& c #E0CFCD",
+"Y& c #DBD9E2",
+"Z& c #E4E2DE",
+"`& c #DCD1D3",
+" * c #DDDEE1",
+".* c #DEDBD3",
+"+* c #D2C2C2",
+"@* c #D2D2D9",
+"#* c #DADAD8",
+"$* c #D6CAC8",
+"%* c #D1D2D7",
+"&* c #D3C9C5",
+"** c #CDCBD1",
+"=* c #D3D4D3",
+"-* c #D0CDB0",
+";* c #A28629",
+">* c #79857B",
+",* c #BDC8CA",
+"'* c #C6C5C5",
+")* c #5757AB",
+"!* c #FBFBFB",
+"~* c #EBAC6F",
+"{* c #AA85C9",
+"]* c #F0F4F4",
+"^* c #F3F3F0",
+"/* c #E5A467",
+"(* c #9E4F5F",
+"_* c #AB6868",
+":* c #AB6A79",
+"<* c #C6CFE8",
+"[* c #EBDBB9",
+"}* c #B96150",
+"|* c #9F6265",
+"1* c #A2504F",
+"2* c #A794C5",
+"3* c #E2E5E6",
+"4* c #E2BF83",
+"5* c #983E40",
+"6* c #A4A5D2",
+"7* c #DFCCA4",
+"8* c #A84D42",
+"9* c #945758",
+"0* c #95414D",
+"a* c #A8A6C5",
+"b* c #CA844E",
+"c* c #8E67A5",
+"d* c #D2CFB2",
+"e* c #A64442",
+"f* c #A3ABCC",
+"g* c #D5D5D4",
+"h* c #D4D4D3",
+"i* c #D1CFB1",
+"j* c #A3872A",
+"k* c #7B7B28",
+"l* c #7A867D",
+"m* c #BEC9CB",
+"n* c #5959AC",
+"o* c #FCFCFC",
+"p* c #ECAD70",
+"q* c #AB87CA",
+"r* c #F1F5F5",
+"s* c #F4F4F1",
+"t* c #E7A669",
+"u* c #A57CBB",
+"v* c #E6E3E3",
+"w* c #E9E2E6",
+"x* c #ECEEE8",
+"y* c #DB8C5B",
+"z* c #A388C2",
+"A* c #E6EAEB",
+"B* c #E8D9BB",
+"C* c #C298B0",
+"D* c #DCE3DF",
+"E* c #D28054",
+"F* c #9D6A5C",
+"G* c #9866A4",
+"H* c #DAE1DC",
+"I* c #D0814F",
+"J* c #977BB6",
+"K* c #DBDEDE",
+"L* c #D9BA90",
+"M* c #AC8CB6",
+"N* c #D5CDA8",
+"O* c #A34654",
+"P* c #AD8B63",
+"Q* c #8E5791",
+"R* c #CCD3D7",
+"S* c #D4D4D5",
+"T* c #D2D0B2",
+"U* c #A4882B",
+"V* c #7B877D",
+"W* c #BFCACD",
+"X* c #FDFDFD",
+"Y* c #EEAE72",
+"Z* c #AC88CB",
+"`* c #F2F6F6",
+" = c #F5F5F2",
+".= c #E8A769",
+"+= c #A0505D",
+"@= c #AB6565",
+"#= c #AA6B88",
+"$= c #D7E2E2",
+"%= c #D27051",
+"&= c #ADB3DF",
+"*= c #EBDEBB",
+"== c #B96C66",
+"-= c #A76F8E",
+";= c #D6D8BD",
+">= c #B25463",
+",= c #C2C4AF",
+"'= c #AB4F64",
+")= c #C3D1D7",
+"!= c #C96646",
+"~= c #A1A5D2",
+"{= c #DDDDD9",
+"]= c #CF9055",
+"^= c #883443",
+"/= c #A6AECF",
+"(= c #D6D5D6",
+"_= c #D5D4D5",
+":= c #D4D1B3",
+"<= c #A5892C",
+"[= c #7C877C",
+"}= c #C0CBCD",
+"|= c #FFFFFF",
+"1= c #EFAF73",
+"2= c #AD89CC",
+"3= c #F4F8F8",
+"4= c #F6F6F3",
+"5= c #E9A86C",
+"6= c #A884C8",
+"7= c #EFF3F3",
+"8= c #F1F1EB",
+"9= c #DE905D",
+"0= c #A381BC",
+"a= c #E7E9E5",
+"b= c #E3C59A",
+"c= c #A75072",
+"d= c #CBB17B",
+"e= c #9A4343",
+"f= c #984C4B",
+"g= c #954041",
+"h= c #A3A0CB",
+"i= c #D18352",
+"j= c #9980BA",
+"k= c #DEE1E1",
+"l= c #DBB684",
+"m= c #A57DAD",
+"n= c #D8DCDE",
+"o= c #DBC590",
+"p= c #98446C",
+"q= c #C4D2DB",
+"r= c #D6D6D5",
+"s= c #D5D2B6",
+"t= c #A88B2D",
+"u= c #7D7E4D",
+"v= c #A6B8AE",
+"w= c #BFC0BC",
+"x= c #CACCCC",
+"y= c #222376",
+"z= c #222175",
+"A= c #F0B172",
+"B= c #A7545A",
+"C= c #AB5E5E",
+"D= c #AA6582",
+"E= c #CF9B6B",
+"F= c #A24F55",
+"G= c #A75959",
+"H= c #A65860",
+"I= c #B9BCE4",
+"J= c #EFE1BF",
+"K= c #BF6652",
+"L= c #A16065",
+"M= c #A65C67",
+"N= c #AB5D6B",
+"O= c #B96F54",
+"P= c #A8A3D4",
+"Q= c #E1B271",
+"R= c #9A639F",
+"S= c #D9CFAB",
+"T= c #AE5448",
+"U= c #9A5B5A",
+"V= c #984656",
+"W= c #AFAED1",
+"X= c #DCC692",
+"Y= c #99466E",
+"Z= c #C6D3DB",
+"`= c #D6D5C6",
+" - c #B89631",
+".- c #81812D",
+"+- c #807F2C",
+"@- c #7C8678",
+"#- c #BECBCD",
+"$- c #F1EFEA",
+"%- c #E8DADB",
+"&- c #E7E8ED",
+"*- c #EDECEC",
+"=- c #EAE9EA",
+"-- c #E8E8E9",
+";- c #E5E3DD",
+">- c #DBCDCE",
+",- c #DBDCE1",
+"'- c #E1E2E1",
+")- c #DDDCDD",
+"!- c #D1C27C",
+"~- c #8F822E",
+"{- c #7D8779",
+"]- c #C0CDCF",
+"^- c #252578",
+"/- c #FFFEFF",
+"(- c #EBEAEB",
+"_- c #E9EAEA",
+":- c #E9E8E8",
+"<- c #E3E2E2",
+"[- c #DCDCDD",
+"}- c #DCDCDB",
+"|- c #D2CAA9",
+"1- c #B4AC78",
+"2- c #A2A06C",
+"3- c #9FA177",
+"4- c #A9B3B0",
+"5- c #CBCFD0",
+"6- c #F8F7F8",
+"7- c #E9E9EA",
+"8- c #E8E8E8",
+"9- c #E3E3E4",
+"0- c #DDDEDE",
+"a- c #D6D6D7",
+"b- c #CECECF",
+"c- c #27277B",
+"d- c #FEFFFF",
+"e- c #F9F9F8",
+"f- c #F7F8F8",
+"g- c #F2F1F1",
+"h- c #F0F0F1",
+"i- c #E4E4E3",
+"j- c #E2E3E2",
+"k- c #CFCFD0",
+"l- c #5757AA",
+"m- c #5656A9",
+"n- c #5151A4",
+"o- c #5050A3",
+"p- c #4F4FA2",
+"q- c #4C4C9F",
+"r- c #4A4B9E",
+"s- c #49499C",
+"t- c #48489B",
+"u- c #47479A",
+"v- c #464699",
+"w- c #454598",
+"x- c #434397",
+"y- c #3F3F92",
+"z- c #3E3E91",
+"A- c #3C3D90",
+"B- c #3B3B8F",
+"C- c #303184",
+"D- c #2F2F83",
+"E- c #2A2B7E",
+"F- c #5859AB",
+"G- c #5253A6",
+"H- c #5152A4",
+"I- c #4B4A9E",
+"J- c #2A297D",
+". + @ # $ % & * = - ; > , ' ) ! ~ { ] ^ / ( _ : < [ } | 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 ",
+"a . + b c $ % & * d e ; > , ' ) f ~ g ] h i j _ k < l m | n o 3 p q 6 r 8 9 0 0 0 0 0 0 0 0 0 0 0 0 ",
+"s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ` ...+.@.#.#.#.#.#.#.#.#.#.0 0 ",
+"$.%.&.u v *.=.-.z A B ;.>.E F G H ,.J K L M '.O P Q R S T ).V W X Y !.` ...+.@.#.#.#.#.#.#.#.#.0 0 ",
+"~.{.].&.u ^.w /.-.z A B ;.D E F G (._.J K L :.N O P Q R S <.[.V W X Y }.` ...+.@.#.#.#.#.#.#.#.0 0 ",
+"|.1.2.].&.u v 3.=.-.z A 4.5.D E F G 6.7.J K L 8.9.0.P Q R S a.).V W X Y b.` ...+.@.#.#.#.#.#.#.0 0 ",
+"c.d.e.f.].g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.K L M 9.O P Q R S a.).V W X Y Z ` ...+.@.#.#.#.#.#.0 0 ",
+"x.c.y.e.z.A.B.h.i.j.k.C.D.n.E.F.G.H.s.t.I.J.J K L 8.9.O P Q R S K.).V W X Y Z ` ...+.@.#.#.#.#.0 0 ",
+"L.x.M.N.e.O.P.Q.h.R.j.k.S.T.n.E.F.G.U.s.V.W.I J K L :.X.O P Q R S K.).V W X Y Z ` ...+.@.#.#.#.0 0 ",
+"Y.Z.`.M. +.+++@+#+$+%+&+k.C.*+=+-+;+>+,+'+)+!+I J K L M 9.O P Q R S K.).V W X Y Z ` ...+.@.#.#.0 0 ",
+"~+Y.{+`.M.]+2.z.].&.^+/+(+_+:+<+[+}+|+D E F 1+,.I J K L 2+9.O P Q R S K.).V W X Y Z ` ...+.@.#.0 0 ",
+"3+4+5+{+`.6+7+2.z.].8+9+R.(+0+a+b+A c+|+D E F d+(.I J K L :.9.O P Q R S K.).V W X Y Z ` ...+.@.0 0 ",
+"e+3+f+5+{+`.M.]+2.z.g+h+h.R.i+j+-.z [+}+|+D E F H ,.I J K L k+9.O P Q R S K.).V W X Y Z ` ...+.9 0 ",
+"l+m+n+f+5+{+`.M.]+2.o+p+Q.q+r+s+=.-.t+u+}+|+D E F )+,.I J K L v+9.O P Q R S K.).V W X Y Z ` ...8 9 ",
+"w+l+x+y+f+5+{+z+6+]+A+B+C+Q.D+E+F+=.-.G+H+}+|+D E F H ,.I J K L '.9.O P Q R S K.).V W X I+Z ` .r 8 ",
+"J+w+K+L+y+f+5+{+M+N+O+P+Q+C+R+S+w F+=.-.T+H+}+U+V+W+X+Y+Z+I J K L '.9.O P Q R S K.).V W X `+Z ` @r ",
+".@+@@@K+#@y+f+5+{+`.$@%@&@*@=@-@v w F+=.-.;@>@,@- '@)@!@~@{@]@^@K L '.9.O P Q R S K.).V W X /@Z (@ @",
+"_@:@<@@@K+[@y+f+5+{+}@|@1@2@3@4@&.v w 5@6@7@8@9@d - '@)@!@' 0@a@b@K L '.9.O P Q R S K.).V W X Y c@(@",
+"d@e@f@<@@@K+g@y+f+5+h@i@j@1@k@l@].m@n@o@p@q@r@s@9@d - '@)@!@t@u@v@w@K L '.9.O P Q R S K.).V W x@y@c@",
+"z@A@B@f@<@@@C@g@y+f+D@E@F@G@H@I@z.].J@K@b L@q@M@N@O@P@Q@R@S@!@t@0@T@U@K L '.9.O P Q V@W@K.).V W o y@",
+"X@z@Y@B@f@<@Z@K+`@y+ #.#+#F@@###2.$#%#&#*#=#-#;#-.A B }+>#,#'#!@' )#!#J K L '.9.O P Q ~#{#K.).V 1 ]#",
+"^#X@/#Y@B@f@<@(#_#:#<#[#}#+#|#1#]+2#3#4#&#5#6#F+=.-.A B }+7#8#)@!@' 9#0#J K L '.9.O P Q a#{#K.).b#c#",
+"d#^#e#/#Y@B@f@<@@@f#g#h#i#}#j#k#l#m#n#o#4#p#q#w F+=.-.A B }+r#s#)@!@t#u#I J K v#'.9.O P w#x#{#K.y#b#",
+"z#d#A#B#C#Y@B@f@<@D#E#F#G#i#H#I#J#K#~.n#L#M#u v w F+=.-.A B N#O#'@)@P#Q#,.I J K R#'.9.O P Q S#T#U#y#",
+"V#z#W#A#X#/#Y@B@f@<@Y#Z#`# $.$+$@$#$$$~.%$&$].u v w F+=.-.A *$=$- '@; -$H ,.I J K M '.9.O P ;$>$,$U#",
+"'$V#)$W#A#X#/#Y@B@f@<@!$x+:#y+f+~${$]$$$^$/$z.].u v w F+=.-.($_$d - '@:$<$H ,.I J K R#'.9.O P ;$[$[ ",
+"}$|$1$)$W#A#2$3$Y@B@f@<@(#x+:#y+4$5$Z.]$6$7$2.z.].u v w F+=.8$9$9@d = 0$E a$H ,.I J K b$'.9.O P c$[$",
+"d$}$e$1$)$W#A#2$/#Y@B@f@<@K+x+:#f$g$h$Z.i$j$]+2.z.].u k$l$m$n$o$8@* p$q$D r$s$t$u$v$w$x$y$'.9.O z$: ",
+"A$B$C$e$1$)$W#A#D$/#Y@B@f@<@K+x+E$F$G$h$Z.H$I$]+2.z.J$K$L$M$N$O$r@8@P$Q$|+D R$S$T$U$V$W$X$M '.9.Y$z$",
+"Z$A$`$ %e$1$)$W#A#.%/#Y@B@f@<@K+x++%@%G$h$#%$%N.]+2.%%&%. *%=%-%q@;%>%,%}+|+'%)%!%T$~%{%J L M '.i Y$",
+"]%Z$^%`$/%e$1$)$W#A#.%/#Y@B@f@<@K+(%_%:%G$h$<%[%N.]+}%|%1%&#+ b 2%3%4%5%B }+6%7%8%9%0%a%I b%c%M h i ",
+"d%e%f%^%g% %e$1$)$W#A#.%/#Y@B@f@<@K+h%i%:%G$Y.j%k%N.]+l%m%1%. + b n%o%p%A q%r%s%G.8%t%u%v%w%x%y%z%h ",
+"A%B%C%f%^%`$ %e$1$)$W#A#.%/#Y@B@f@<@D%E%F%:%G$h$L.G%H%I%n#o#4#&#+ J%K%=.L%M%E.p.N%G.U.t.O%P%Q%R%S%z%",
+"T%U%V%C%f%^%W% %e$1$)$W#A#.%/#Y@B@f@<@X%Y%F%:%G$h$Z%c.|.~.n#o#1%. *#`% &.&+&@&#&p.N%$&%&&&*&,.I =&g ",
+"-&T%;&V%C%f%^%>& %e$1$)$W#A#.%/#Y@B@f@<@,&'&)&:%G$h$!&c.|.~&{&]&1%. ^&/&F+.&(&_&E.p.:&<&F G H ,.! [&",
+"}&-&|&;&V%C%f%^%1& %e$1$)$W#A#.%/#Y@B@f@<@K+2&3&4&5&6&7&8&9&]+0&a&b&c&d&w F+e&f&n.E.g&h&E i&G H 0@j&",
+"k&}&l&m&;&V%C%f%^%>& %e$1$)$W#A#.%/#Y@B@f@n&K+x+:#y+f+o&`.M.N.]+p&q&r&u v w s&t&u&n.v&w&x&E F G ' y&",
+"z&A&B&l&|&;&V%C%f%^%>& %e$1$)$W#A#.%/#Y@B@f@C&K+x+:#y+f+D&E&M.N.]+2.F&&.u v G&H&I&u&J&K&}+L&E F , ' ",
+"M&N&O&B&l&m&P&Q&C%f%R&S&T&U&V&)$W&X&Y&/#Y@Z&`& *K+x+.*+*@*#*$*%*y.&***=*&.u -*;*k.I&>*,*B }+D '*> , ",
+")*M&!*O&B&l&~*{*]*^*/*(*_*:*<*[*}*|*1*2*3*4*5*6*@@7*8*9*0*a*b*c*d*e*f*g*h*&.i*j*j.k*l*m*A B C L&; !@",
+"n*)*o*!*O&B&p*q*r*s*t*u*v*w*x*y*z*A*B*C*D*E*F*G*H*I*J*K*L*M*N*O*P*Q*R*]+S*].T*U*i.j.V*W*z A B 5.- ; ",
+"n*n*X*o*!*O&Y*Z*`* =.=+=@=#=$=%=&=*===-=;=>=,='=)=!=~=K+x+:#{=]=^=/=M.N.(=_=:=<=h.i.[=}=-.z A B d - ",
+"n*n*|=X*o*!*1=2=3=4=5=6=7=f%8=9=0=a=b=c=d=e=f=g=h=i=j=k=l=m=n=o=p=q=`.M.N.r=s=t=B.h.u=v=w=x=z A y=z=",
+"n*n*|=|=X*o*A=B=C=D=E=F=G=H=I=J=K=L=M=N=O=P=X#Q=R=S=T=U=V=W=[@X=Y=Z={+`.M.N.`= -.-+-h.i.@-#--.z & * ",
+"n*n*|=|=|=X*o*!*O&B&l&m&;&V%C%f%$-%-&-*-1$)$=---.%/#;->-,-'-K+x+:#)-5+{+`.M.y.!-~-.-B.h.{-]-=.-.^-& ",
+"n*n*|=|=|=/-X*o*!*O&B&l&m&;&V%C%f%g%>& %e$1$(-_-:-.%/#Y@B@<-@@K+x+:#[-}-{+`.M.y.|-1-2-3-4-5-F+=.$ ^-",
+"n*n*|=|=|=|=/-X*o*!*O&B&6-m&;&V%C%f%^%>& %e$1$(-7-8-.%/#Y@9-<@@@K+x+0-f+5+{+`.M.a-(=z.].&.u k$b-c-r@",
+"n*n*|=|=|=|=|=d-X*o*!*O&e-f-m&;&V%C%g-h->& %e$1$(-A#8-.%/#Y@i-j-@@K+x+n+)-5+{+`.M.y.e.z.].&.u k-L@c-",
+"n*n*n*n*n*n*n*n*n*l-m-N&A&}&n-o-p-d%e%q-r-s-t-u-v-w-x-X@z@A@y-z-A-B-l+e+F%4+Y.Z.x.c.C-D-{.%.a E-+ L@",
+"n*n*n*n*n*n*n*n*n*F-l-m-N&A&G-H-T%p-d%e%q-I-s-t-u-v-w-x-X@z@A@_@z-+@B-l+e+F%4+Y.Z.x.c.C-D-{.%.t . J-"
+};
+
+
+/*!
+ \class TQMessageBox
+ \brief The TQMessageBox class provides a modal dialog with a short message, an icon, and some buttons.
+ \ingroup dialogs
+ \mainclass
+
+ Message boxes are used to provide informative messages and to ask
+ simple questions.
+
+ TQMessageBox provides a range of different messages, arranged
+ roughly along two axes: severity and complexity.
+
+ Severity is
+ \table
+ \row
+ \i \img qmessagebox-quest.png
+ \i Question
+ \i For message boxes that ask a question as part of normal
+ operation. Some style guides recommend using Information for this
+ purpose.
+ \row
+ \i \img qmessagebox-info.png
+ \i Information
+ \i For message boxes that are part of normal operation.
+ \row
+ \i \img qmessagebox-warn.png
+ \i Warning
+ \i For message boxes that tell the user about unusual errors.
+ \row
+ \i \img qmessagebox-crit.png
+ \i Critical
+ \i For message boxes that tell the user about critical errors.
+ \endtable
+
+ The message box has a different icon for each of the severity levels.
+
+ Complexity is one button (OK) for simple messages, or two or even
+ three buttons for questions.
+
+ There are static functions for the most common cases.
+
+ Examples:
+
+ If a program is unable to tqfind a supporting file, but can do perfectly
+ well without it:
+
+ \code
+ TQMessageBox::information( this, "Application name",
+ "Unable to tqfind the user preferences file.\n"
+ "The factory default will be used instead." );
+ \endcode
+
+ question() is useful for simple yes/no questions:
+
+ \code
+ if ( TQFile::exists( filename ) &&
+ TQMessageBox::question(
+ this,
+ tr("Overwrite File? -- Application Name"),
+ tr("A file called %1 already exists."
+ "Do you want to overwrite it?")
+ .arg( filename ),
+ tr("&Yes"), tr("&No"),
+ TQString::null, 0, 1 ) )
+ return false;
+ \endcode
+
+ warning() can be used to tell the user about unusual errors, or
+ errors which can't be easily fixed:
+
+ \code
+ switch( TQMessageBox::warning( this, "Application name",
+ "Could not connect to the <mumble> server.\n"
+ "This program can't function correctly "
+ "without the server.\n\n",
+ "Retry",
+ "Quit", 0, 0, 1 ) ) {
+ case 0: // The user clicked the Retry again button or pressed Enter
+ // try again
+ break;
+ case 1: // The user clicked the Quit or pressed Escape
+ // exit
+ break;
+ }
+ \endcode
+
+ The text part of all message box messages can be either rich text
+ or plain text. If you specify a rich text formatted string, it
+ will be rendered using the default stylesheet. See
+ TQStyleSheet::defaultSheet() for details. With certain strings that
+ contain XML meta characters, the auto-rich text detection may
+ fail, interpreting plain text incorrectly as rich text. In these
+ rare cases, use TQStyleSheet::convertFromPlainText() to convert
+ your plain text string to a visually equivalent rich text string
+ or set the text format explicitly with setTextFormat().
+
+ Note that the Microsoft Windows User Interface Guidelines
+ recommend using the application name as the window's caption.
+
+ Below are more examples of how to use the static member functions.
+ After these examples you will tqfind an overview of the non-static
+ member functions.
+
+ Exiting a program is part of its normal operation. If there is
+ unsaved data the user probably should be asked if they want to
+ save the data. For example:
+
+ \code
+ switch( TQMessageBox::information( this, "Application name here",
+ "The document tqcontains unsaved changes\n"
+ "Do you want to save the changes before exiting?",
+ "&Save", "&Discard", "Cancel",
+ 0, // Enter == button 0
+ 2 ) ) { // Escape == button 2
+ case 0: // Save clicked or Alt+S pressed or Enter pressed.
+ // save
+ break;
+ case 1: // Discard clicked or Alt+D pressed
+ // don't save but exit
+ break;
+ case 2: // Cancel clicked or Escape pressed
+ // don't exit
+ break;
+ }
+ \endcode
+
+ The Escape button cancels the entire exit operation, and pressing
+ Enter causes the changes to be saved before the exit occurs.
+
+ Disk full errors are unusual and they certainly can be hard to
+ correct. This example uses predefined buttons instead of
+ hard-coded button texts:
+
+ \code
+ switch( TQMessageBox::warning( this, "Application name here",
+ "Could not save the user preferences,\n"
+ "because the disk is full. You can delete\n"
+ "some files and press Retry, or you can\n"
+ "abort the Save Preferences operation.",
+ TQMessageBox::Retry | TQMessageBox::Default,
+ TQMessageBox::Abort | TQMessageBox::Escape )) {
+ case TQMessageBox::Retry: // Retry clicked or Enter pressed
+ // try again
+ break;
+ case TQMessageBox::Abort: // Abort clicked or Escape pressed
+ // abort
+ break;
+ }
+ \endcode
+
+ The critical() function should be reserved for critical errors. In
+ this example errorDetails is a TQString or const char*, and TQString
+ is used to concatenate several strings:
+
+ \code
+ TQMessageBox::critical( 0, "Application name here",
+ TQString("An internal error occurred. Please ") +
+ "call technical support at 1234-56789 and report\n"+
+ "these numbers:\n\n" + errorDetails +
+ "\n\nApplication will now exit." );
+ \endcode
+
+ In this example an OK button is displayed.
+
+ TQMessageBox provides a very simple About box which displays an
+ appropriate icon and the string you provide:
+
+ \code
+ TQMessageBox::about( this, "About <Application>",
+ "<Application> is a <one-paragraph blurb>\n\n"
+ "Copyright 1991-2003 Such-and-such. "
+ "<License words here.>\n\n"
+ "For technical support, call 1234-56789 or see\n"
+ "http://www.such-and-such.com/Application/\n" );
+ \endcode
+
+ See about() for more information.
+
+ If you want your users to know that the application is built using
+ TQt (so they know that you use high quality tools) you might like
+ to add an "About TQt" menu option under the Help menu to invoke
+ aboutTQt().
+
+ If none of the standard message boxes is suitable, you can create a
+ TQMessageBox from scratch and use custom button texts:
+
+ \code
+ TQMessageBox mb( "Application name here",
+ "Saving the file will overwrite the original file on the disk.\n"
+ "Do you really want to save?",
+ TQMessageBox::Information,
+ TQMessageBox::Yes | TQMessageBox::Default,
+ TQMessageBox::No,
+ TQMessageBox::Cancel | TQMessageBox::Escape );
+ mb.setButtonText( TQMessageBox::Yes, "Save" );
+ mb.setButtonText( TQMessageBox::No, "Discard" );
+ switch( mb.exec() ) {
+ case TQMessageBox::Yes:
+ // save and exit
+ break;
+ case TQMessageBox::No:
+ // exit without saving
+ break;
+ case TQMessageBox::Cancel:
+ // don't save and don't exit
+ break;
+ }
+ \endcode
+
+ TQMessageBox defines two enum types: Icon and an unnamed button type.
+ Icon defines the \c Question, \c Information, \c Warning, and \c
+ Critical icons for each GUI style. It is used by the constructor
+ and by the static member functions question(), information(),
+ warning() and critical(). A function called standardIcon() gives
+ you access to the various icons.
+
+ The button types are:
+ \list
+ \i Ok - the default for single-button message boxes
+ \i Cancel - note that this is \e not automatically Escape
+ \i Yes
+ \i No
+ \i Abort
+ \i Retry
+ \i Ignore
+ \i YesAll
+ \i NoAll
+ \endlist
+
+ Button types can be combined with two modifiers by using OR, '|':
+ \list
+ \i Default - makes pressing Enter equivalent to
+ clicking this button. Normally used with Ok, Yes or similar.
+ \i Escape - makes pressing Escape equivalent to clicking this button.
+ Normally used with Abort, Cancel or similar.
+ \endlist
+
+ The text(), icon() and iconPixmap() functions provide access to the
+ current text and pixmap of the message box. The setText(), setIcon()
+ and setIconPixmap() let you change it. The difference between
+ setIcon() and setIconPixmap() is that the former accepts a
+ TQMessageBox::Icon and can be used to set standard icons, whereas the
+ latter accepts a TQPixmap and can be used to set custom icons.
+
+ setButtonText() and buttonText() provide access to the buttons.
+
+ TQMessageBox has no Q_SIGNALS or Q_SLOTS.
+
+ <img src=qmsgbox-m.png> <img src=qmsgbox-w.png>
+
+ \sa TQDialog,
+ \link http://www.iarchitect.com/errormsg.htm
+ Isys on error messages \endlink,
+ \link guibooks.html#fowler GUI Design Handbook: Message Box \endlink
+*/
+
+
+/*!
+ \enum TQMessageBox::Icon
+
+ This enum has the following values:
+
+ \value NoIcon the message box does not have any icon.
+
+ \value Question an icon indicating that
+ the message is asking a question.
+
+ \value Information an icon indicating that
+ the message is nothing out of the ordinary.
+
+ \value Warning an icon indicating that the
+ message is a warning, but can be dealt with.
+
+ \value Critical an icon indicating that
+ the message represents a critical problem.
+
+*/
+
+
+struct TQMessageBoxData {
+ TQMessageBoxData(TQMessageBox* tqparent) :
+ iconLabel( tqparent, "icon" )
+ {
+ }
+
+ int numButtons; // number of buttons
+ TQMessageBox::Icon icon; // message box icon
+ TQLabel iconLabel; // label holding any icon
+ int button[3]; // button types
+ int defButton; // default button (index)
+ int escButton; // escape button (index)
+ TQSize buttonSize; // button size
+ TQPushButton *pb[3]; // buttons
+};
+
+static const int LastButton = TQMessageBox::NoAll;
+
+/*
+ NOTE: The table of button texts correspond to the button enum.
+*/
+
+#ifndef TQ_OS_TEMP
+static const char * const mb_texts[] = {
+#else
+const char * mb_texts[] = {
+#endif
+ 0,
+ TQT_TRANSLATE_NOOP("TQMessageBox","OK"),
+ TQT_TRANSLATE_NOOP("TQMessageBox","Cancel"),
+ TQT_TRANSLATE_NOOP("TQMessageBox","&Yes"),
+ TQT_TRANSLATE_NOOP("TQMessageBox","&No"),
+ TQT_TRANSLATE_NOOP("TQMessageBox","&Abort"),
+ TQT_TRANSLATE_NOOP("TQMessageBox","&Retry"),
+ TQT_TRANSLATE_NOOP("TQMessageBox","&Ignore"),
+ TQT_TRANSLATE_NOOP("TQMessageBox","Yes to &All"),
+ TQT_TRANSLATE_NOOP("TQMessageBox","N&o to All"),
+ 0
+};
+
+/*!
+ Constructs a message box with no text and a button with the label
+ "OK".
+
+ If \a tqparent is 0, the message box becomes an application-global
+ modal dialog box. If \a tqparent is a widget, the message box
+ becomes modal relative to \a tqparent.
+
+ The \a tqparent and \a name arguments are passed to the TQDialog
+ constructor.
+*/
+
+TQMessageBox::TQMessageBox( TQWidget *tqparent, const char *name )
+ : TQDialog( tqparent, name, TRUE, (WFlags)(WStyle_Customize | TQt::WStyle_DialogBorder | TQt::WStyle_Title | TQt::WStyle_SysMenu) )
+{
+ init( Ok, 0, 0 );
+}
+
+
+/*!
+ Constructs a message box with a \a caption, a \a text, an \a icon,
+ and up to three buttons.
+
+ The \a icon must be one of the following:
+ \list
+ \i TQMessageBox::NoIcon
+ \i TQMessageBox::Question
+ \i TQMessageBox::Information
+ \i TQMessageBox::Warning
+ \i TQMessageBox::Critical
+ \endlist
+
+ Each button, \a button0, \a button1 and \a button2, can have one
+ of the following values:
+ \list
+ \i TQMessageBox::NoButton
+ \i TQMessageBox::Ok
+ \i TQMessageBox::Cancel
+ \i TQMessageBox::Yes
+ \i TQMessageBox::No
+ \i TQMessageBox::Abort
+ \i TQMessageBox::Retry
+ \i TQMessageBox::Ignore
+ \i TQMessageBox::YesAll
+ \i TQMessageBox::NoAll
+ \endlist
+
+ Use TQMessageBox::NoButton for the later parameters to have fewer
+ than three buttons in your message box. If you don't specify any
+ buttons at all, TQMessageBox will provide an Ok button.
+
+ One of the buttons can be OR-ed with the \c TQMessageBox::Default
+ flag to make it the default button (clicked when Enter is
+ pressed).
+
+ One of the buttons can be OR-ed with the \c TQMessageBox::Escape
+ flag to make it the cancel or close button (clicked when Escape is
+ pressed).
+
+ Example:
+ \code
+ TQMessageBox mb( "Application Name",
+ "Hardware failure.\n\nDisk error detected\nDo you want to stop?",
+ TQMessageBox::Question,
+ TQMessageBox::Yes | TQMessageBox::Default,
+ TQMessageBox::No | TQMessageBox::Escape,
+ TQMessageBox::NoButton );
+ if ( mb.exec() == TQMessageBox::No )
+ // try again
+ \endcode
+
+ If \a tqparent is 0, the message box becomes an application-global
+ modal dialog box. If \a tqparent is a widget, the message box
+ becomes modal relative to \a tqparent.
+
+ If \a modal is TRUE the message box is modal; otherwise it
+ is modeless.
+
+ The \a tqparent, \a name, \a modal, and \a f arguments are passed to
+ the TQDialog constructor.
+
+ \sa setCaption(), setText(), setIcon()
+*/
+
+TQMessageBox::TQMessageBox( const TQString& caption,
+ const TQString &text, Icon icon,
+ int button0, int button1, int button2,
+ TQWidget *tqparent, const char *name,
+ bool modal, WFlags f )
+ : TQDialog( tqparent, name, modal, (WFlags)(f | (WFlags)WStyle_Customize | TQt::WStyle_DialogBorder | TQt::WStyle_Title | TQt::WStyle_SysMenu) )
+{
+ init( button0, button1, button2 );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ setCaption( caption );
+#endif
+ setText( text );
+ setIcon( icon );
+}
+
+
+/*!
+ Destroys the message box.
+*/
+
+TQMessageBox::~TQMessageBox()
+{
+ delete mbd;
+}
+
+static TQString * translatedTextAboutTQt = 0;
+
+void TQMessageBox::init( int button0, int button1, int button2 )
+{
+ if ( !translatedTextAboutTQt ) {
+ translatedTextAboutTQt = new TQString;
+
+// #if defined(TQT_NON_COMMERCIAL)
+// TQT_NC_MSGBOX
+// #else
+ *translatedTextAboutTQt = tr(
+ "<h3>About TQt</h3>"
+ "<p>This program uses TQt version %1.</p>"
+ "<p>TQt is a C++ toolkit for multiplatform GUI &amp; "
+ "application development.</p>"
+ "<p>TQt provides single-source portability "
+ "to Qt v3, Qt v4, and future Qt versions.</p>"
+ "<p>TQt is a Pearson Computing product, based on Qt 3.3. "
+ "See <tt>http://tqt.pearsoncomputing.net/</tt> "
+ "for more information.</p>"
+ ).arg( TQT_VERSION_STR );
+// #endif
+
+ }
+ label = new TQMessageBoxLabel( this );
+ TQ_CHECK_PTR( label );
+
+ if ( (button2 && !button1) || (button1 && !button0) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQMessageBox: Inconsistent button parameters" );
+#endif
+ button0 = button1 = button2 = 0;
+ }
+ mbd = new TQMessageBoxData(this);
+ TQ_CHECK_PTR( mbd );
+ mbd->icon = NoIcon;
+ mbd->iconLabel.setPixmap( TQPixmap() );
+ mbd->numButtons = 0;
+ mbd->button[0] = button0;
+ mbd->button[1] = button1;
+ mbd->button[2] = button2;
+ mbd->defButton = -1;
+ mbd->escButton = -1;
+ int i;
+ for ( i=0; i<3; i++ ) {
+ int b = mbd->button[i];
+ if ( (b & Default) ) {
+ if ( mbd->defButton >= 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQMessageBox: There can be at most one "
+ "default button" );
+#endif
+ } else {
+ mbd->defButton = i;
+ }
+ }
+ if ( (b & Escape) ) {
+ if ( mbd->escButton >= 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQMessageBox: There can be at most one "
+ "escape button" );
+#endif
+ } else {
+ mbd->escButton = i;
+ }
+ }
+ b &= ButtonMask;
+ if ( b == 0 ) {
+ if ( i == 0 ) // no buttons, add an Ok button
+ b = Ok;
+ } else if ( b < 0 || b > LastButton ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQMessageBox: Invalid button specifier" );
+#endif
+ b = Ok;
+ } else {
+ if ( i > 0 && mbd->button[i-1] == 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQMessageBox: Inconsistent button parameters; "
+ "button %d defined but not button %d",
+ i+1, i );
+#endif
+ b = 0;
+ }
+ }
+ mbd->button[i] = b;
+ if ( b )
+ mbd->numButtons++;
+ }
+ for ( i=0; i<3; i++ ) {
+ if ( i >= mbd->numButtons ) {
+ mbd->pb[i] = 0;
+ } else {
+ TQCString buttonName;
+ buttonName.sprintf( "button%d", i+1 );
+ mbd->pb[i] = new TQPushButton(
+ tr(mb_texts[mbd->button[i]]),
+ this, buttonName );
+ if ( mbd->defButton == i ) {
+ mbd->pb[i]->setDefault( TRUE );
+ mbd->pb[i]->setFocus();
+ }
+ mbd->pb[i]->setAutoDefault( TRUE );
+ mbd->pb[i]->setFocusPolicy( Qt::StrongFocus );
+ connect( mbd->pb[i], TQT_SIGNAL(clicked()), TQT_SLOT(buttonClicked()) );
+ }
+ }
+ resizeButtons();
+ reserved1 = reserved2 = 0;
+}
+
+
+int TQMessageBox::indexOf( int button ) const
+{
+ int index = -1;
+ for ( int i=0; i<mbd->numButtons; i++ ) {
+ if ( mbd->button[i] == button ) {
+ index = i;
+ break;
+ }
+ }
+ return index;
+}
+
+
+void TQMessageBox::resizeButtons()
+{
+ int i;
+ TQSize maxSize;
+ for ( i=0; i<mbd->numButtons; i++ ) {
+ TQSize s = mbd->pb[i]->tqsizeHint();
+ maxSize.setWidth( TQMAX(maxSize.width(), s.width()) );
+ maxSize.setHeight( TQMAX(maxSize.height(),s.height()) );
+ }
+ mbd->buttonSize = maxSize;
+ for ( i=0; i<mbd->numButtons; i++ )
+ mbd->pb[i]->resize( maxSize );
+}
+
+
+/*!
+ \property TQMessageBox::text
+ \brief the message box text to be displayed.
+
+ The text will be interpreted either as a plain text or as rich
+ text, depending on the text format setting (\l
+ TQMessageBox::textFormat). The default setting is \c AutoText, i.e.
+ the message box will try to auto-detect the format of the text.
+
+ The default value of this property is TQString::null.
+
+ \sa textFormat
+*/
+TQString TQMessageBox::text() const
+{
+ return label->text();
+}
+
+
+void TQMessageBox::setText( const TQString &text )
+{
+ label->setText( text );
+}
+
+
+/*!
+ \property TQMessageBox::icon
+ \brief the message box's icon
+
+ The icon of the message box can be one of the following predefined
+ icons:
+ \list
+ \i TQMessageBox::NoIcon
+ \i TQMessageBox::Question
+ \i TQMessageBox::Information
+ \i TQMessageBox::Warning
+ \i TQMessageBox::Critical
+ \endlist
+
+ The actual pixmap used for displaying the icon depends on the
+ current \link TQWidget::tqstyle() GUI style\endlink. You can also set
+ a custom pixmap icon using the \l TQMessageBox::iconPixmap
+ property. The default icon is TQMessageBox::NoIcon.
+
+ \sa iconPixmap
+*/
+
+TQMessageBox::Icon TQMessageBox::icon() const
+{
+ return mbd->icon;
+}
+
+void TQMessageBox::setIcon( Icon icon )
+{
+ setIconPixmap( standardIcon(icon) );
+ mbd->icon = icon;
+}
+
+/*!
+ \obsolete
+
+ Returns the pixmap used for a standard icon. This
+ allows the pixmaps to be used in more complex message boxes.
+ \a icon specifies the required icon, e.g. TQMessageBox::Information,
+ TQMessageBox::Warning or TQMessageBox::Critical.
+
+ \a style is unused.
+*/
+
+TQPixmap TQMessageBox::standardIcon( Icon icon, TQt::GUIStyle style)
+{
+ TQ_UNUSED(style);
+ return TQMessageBox::standardIcon(icon);
+}
+
+
+/*!
+ Returns the pixmap used for a standard icon. This allows the
+ pixmaps to be used in more complex message boxes. \a icon
+ specifies the required icon, e.g. TQMessageBox::Question,
+ TQMessageBox::Information, TQMessageBox::Warning or
+ TQMessageBox::Critical.
+*/
+
+TQPixmap TQMessageBox::standardIcon( Icon icon )
+{
+ TQPixmap pm;
+ switch ( icon ) {
+ case Information:
+ pm = TQApplication::tqstyle().stylePixmap( TQStyle::SP_MessageBoxInformation );
+ break;
+ case Warning:
+ pm = TQApplication::tqstyle().stylePixmap( TQStyle::SP_MessageBoxWarning );
+ break;
+ case Critical:
+ pm = TQApplication::tqstyle().stylePixmap( TQStyle::SP_MessageBoxCritical );
+ break;
+ case Question:
+ pm = TQApplication::tqstyle().stylePixmap( TQStyle::SP_MessageBoxQuestion );
+ default:
+ break;
+ }
+ return pm;
+}
+
+
+/*!
+ \property TQMessageBox::iconPixmap
+ \brief the current icon
+
+ The icon currently used by the message box. Note that it's often
+ hard to draw one pixmap that looks appropriate in both Motif and
+ Windows GUI styles; you may want to draw two pixmaps.
+
+ \sa icon
+*/
+
+const TQPixmap *TQMessageBox::iconPixmap() const
+{
+ return mbd->iconLabel.pixmap();
+}
+
+
+void TQMessageBox::setIconPixmap( const TQPixmap &pixmap )
+{
+ mbd->iconLabel.setPixmap(pixmap);
+ mbd->icon = NoIcon;
+}
+
+
+/*!
+ Returns the text of the message box button \a button, or
+ TQString::null if the message box does not contain the button.
+
+ \sa setButtonText()
+*/
+
+TQString TQMessageBox::buttonText( int button ) const
+{
+ int index = indexOf(button);
+ return index >= 0 && mbd->pb[index]
+ ? mbd->pb[index]->text()
+ : TQString::null;
+}
+
+
+/*!
+ Sets the text of the message box button \a button to \a text.
+ Setting the text of a button that is not in the message box is
+ silently ignored.
+
+ \sa buttonText()
+*/
+
+void TQMessageBox::setButtonText( int button, const TQString &text )
+{
+ int index = indexOf(button);
+ if ( index >= 0 && mbd->pb[index] ) {
+ mbd->pb[index]->setText( text );
+ resizeButtons();
+ }
+}
+
+
+/*!
+ \internal
+ Internal slot to handle button clicks.
+*/
+
+void TQMessageBox::buttonClicked()
+{
+ int reply = 0;
+ const TQObject *s = TQT_TQOBJECT(sender());
+ for ( int i=0; i<mbd->numButtons; i++ ) {
+ if ( TQT_TQOBJECT(mbd->pb[i]) == s )
+ reply = mbd->button[i];
+ }
+ done( reply );
+}
+
+
+/*!
+ Adjusts the size of the message box to fit the contents just before
+ TQDialog::exec() or TQDialog::show() is called.
+
+ This function will not be called if the message box has been explicitly
+ resized before showing it.
+*/
+void TQMessageBox::adjustSize()
+{
+ if ( !testWState(TQt::WState_Polished) )
+ polish();
+ resizeButtons();
+ label->adjustSize();
+ TQSize labelSize( label->size() );
+ int n = mbd->numButtons;
+ int bw = mbd->buttonSize.width();
+ int bh = mbd->buttonSize.height();
+ int border = bh / 2 - tqstyle().tqpixelMetric(TQStyle::PM_ButtonDefaultIndicator);
+ if ( border <= 0 )
+ border = 10;
+ int btn_spacing = 7;
+ if ( tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle )
+ btn_spacing = border;
+#ifndef TQ_OS_TEMP
+ int buttons = mbd->numButtons * bw + (n-1) * btn_spacing;
+ int h = bh;
+#else
+ int visibleButtons = 0;
+ for ( int i = 0; i < mbd->numButtons; ++i )
+ visibleButtons += mbd->pb[i]->isVisible() ? 1 : 0;
+ int buttons = visibleButtons == 0 ? 0 : visibleButtons * bw + (visibleButtons-1) * btn_spacing;
+ int h = visibleButtons == 0 ? 0 : bh;
+ n = visibleButtons;
+#endif
+ if ( labelSize.height() )
+ h += labelSize.height() + 3*border;
+ else
+ h += 2*border;
+ int lmargin = 0;
+ if ( mbd->iconLabel.pixmap() && mbd->iconLabel.pixmap()->width() ) {
+ mbd->iconLabel.adjustSize();
+ lmargin += mbd->iconLabel.width() + border;
+ if ( h < mbd->iconLabel.height() + 3*border + bh && n )
+ h = mbd->iconLabel.height() + 3*border + bh;
+ }
+ int w = TQMAX( buttons, labelSize.width() + lmargin ) + 2*border;
+ TQRect screen = TQApplication::desktop()->screenGeometry( pos() );
+ if ( w > screen.width() )
+ w = screen.width();
+ resize( w, h );
+ setMinimumSize( size() );
+#ifdef TQ_WS_MAC
+ setMaximumSize(size());
+#endif
+}
+
+
+/*!\reimp
+*/
+void TQMessageBox::resizeEvent( TQResizeEvent * )
+{
+ int i;
+ int n = mbd->numButtons;
+ int bw = mbd->buttonSize.width();
+ int bh = mbd->buttonSize.height();
+#ifdef TQ_OS_TEMP
+ int visibleButtons = 0;
+ for ( i = 0; i < n; ++i )
+ visibleButtons += mbd->pb[i]->isVisible() ? 1 : 0;
+ n = visibleButtons;
+ bw = visibleButtons == 0 ? 0 : bw;
+ bh = visibleButtons == 0 ? 0 : bh;
+#endif
+ int border = bh / 2 - tqstyle().tqpixelMetric(TQStyle::PM_ButtonDefaultIndicator);
+ if ( border <= 0 )
+ border = 10;
+ int btn_spacing = 7;
+ if ( tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle )
+ btn_spacing = border;
+ int lmargin = 0;
+ mbd->iconLabel.adjustSize();
+ bool rtl = TQApplication::reverseLayout();
+ if (rtl)
+ mbd->iconLabel.move(width() - border - mbd->iconLabel.width(), border);
+ else
+ mbd->iconLabel.move(border, border);
+ if ( mbd->iconLabel.pixmap() && mbd->iconLabel.pixmap()->width() )
+ lmargin += mbd->iconLabel.width() + border;
+ label->setGeometry((rtl ? 0 : lmargin) + border,
+ border,
+ width() - lmargin -2*border,
+ height() - 3*border - bh);
+ int extra_space = (width() - bw*n - 2*border - (n-1)*btn_spacing);
+ if ( tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle )
+ for ( i=0; i<n; i++ )
+ mbd->pb[rtl ? n - i - 1 : i]->move(border + i*bw + i*btn_spacing + extra_space*(i+1)/(n+1),
+ height() - border - bh );
+ else
+ for ( i=0; i<n; i++ )
+ mbd->pb[rtl ? n - i - 1 : i]->move(border + i*bw + extra_space/2 + i*btn_spacing,
+ height() - border - bh );
+}
+
+
+/*!\reimp
+*/
+void TQMessageBox::keyPressEvent( TQKeyEvent *e )
+{
+ if ( e->key() == Key_Escape ) {
+ if ( mbd->escButton >= 0 ) {
+ TQPushButton *pb = mbd->pb[mbd->escButton];
+ pb->animateClick();
+ e->accept();
+ return;
+ }
+ }
+#ifndef TQT_NO_ACCEL
+ if ( !( e->state() & TQt::AltButton ) ) {
+ TQObjectList *list = queryList( "TQPushButton" );
+ TQObjectListIt it( *list );
+ TQPushButton *pb;
+ while ( (pb = (TQPushButton*)it.current()) ) {
+ int key = e->key() & ~(Qt::MODIFIER_MASK|Qt::UNICODE_ACCEL);
+ int acc = pb->accel() & ~(Qt::MODIFIER_MASK|Qt::UNICODE_ACCEL);
+ if ( key && acc && acc == key ) {
+ delete list;
+ emit pb->animateClick();
+ return;
+ }
+ ++it;
+ }
+ delete list;
+ }
+#endif
+ TQDialog::keyPressEvent( e );
+}
+
+/*!\reimp
+*/
+void TQMessageBox::showEvent( TQShowEvent *e )
+{
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::Alert );
+#endif
+ TQDialog::showEvent( e );
+}
+
+/*!\reimp
+*/
+void TQMessageBox::closeEvent( TQCloseEvent *e )
+{
+ TQDialog::closeEvent( e );
+ if ( mbd->escButton != -1 )
+ setResult( mbd->button[mbd->escButton] );
+}
+
+/*****************************************************************************
+ Static TQMessageBox functions
+ *****************************************************************************/
+
+/*!\fn int TQMessageBox::message( const TQString &,const TQString&,const TQString&,TQWidget*,const char * )
+ \obsolete
+ Opens a modal message box directly using the specified parameters.
+
+ Please use information(), warning(), question(), or critical() instead.
+*/
+
+/*! \fn bool TQMessageBox::query( const TQString &,const TQString&,const TQString&,const TQString&,TQWidget *, const char * )
+ \obsolete
+ Queries the user using a modal message box with two buttons.
+ Note that \a caption is not always shown, it depends on the window manager.
+
+ Please use information(), question(), warning(), or critical() instead.
+*/
+
+/*!
+ Opens an information message box with the caption \a caption and
+ the text \a text. The dialog may have up to three buttons. Each of
+ the buttons, \a button0, \a button1 and \a button2 may be set to
+ one of the following values:
+
+ \list
+ \i TQMessageBox::NoButton
+ \i TQMessageBox::Ok
+ \i TQMessageBox::Cancel
+ \i TQMessageBox::Yes
+ \i TQMessageBox::No
+ \i TQMessageBox::Abort
+ \i TQMessageBox::Retry
+ \i TQMessageBox::Ignore
+ \i TQMessageBox::YesAll
+ \i TQMessageBox::NoAll
+ \endlist
+
+ If you don't want all three buttons, set the last button, or last
+ two buttons to TQMessageBox::NoButton.
+
+ One button can be OR-ed with \c TQMessageBox::Default, and one
+ button can be OR-ed with \c TQMessageBox::Escape.
+
+ Returns the identity (TQMessageBox::Ok, or TQMessageBox::No, etc.)
+ of the button that was clicked.
+
+ If \a tqparent is 0, the message box becomes an application-global
+ modal dialog box. If \a tqparent is a widget, the message box
+ becomes modal relative to \a tqparent.
+
+ \sa question(), warning(), critical()
+*/
+
+int TQMessageBox::information( TQWidget *tqparent,
+ const TQString& caption, const TQString& text,
+ int button0, int button1, int button2 )
+{
+ TQMessageBox *mb = new TQMessageBox( caption, text, Information,
+ button0, button1, button2,
+ tqparent, "qt_msgbox_information", TRUE,
+ (WFlags)TQt::WDestructiveClose);
+ TQ_CHECK_PTR( mb );
+ return mb->exec();
+}
+
+/*!
+ Opens a question message box with the caption \a caption and the
+ text \a text. The dialog may have up to three buttons. Each of the
+ buttons, \a button0, \a button1 and \a button2 may be set to one
+ of the following values:
+
+ \list
+ \i TQMessageBox::NoButton
+ \i TQMessageBox::Ok
+ \i TQMessageBox::Cancel
+ \i TQMessageBox::Yes
+ \i TQMessageBox::No
+ \i TQMessageBox::Abort
+ \i TQMessageBox::Retry
+ \i TQMessageBox::Ignore
+ \i TQMessageBox::YesAll
+ \i TQMessageBox::NoAll
+ \endlist
+
+ If you don't want all three buttons, set the last button, or last
+ two buttons to TQMessageBox::NoButton.
+
+ One button can be OR-ed with \c TQMessageBox::Default, and one
+ button can be OR-ed with \c TQMessageBox::Escape.
+
+ Returns the identity (TQMessageBox::Yes, or TQMessageBox::No, etc.)
+ of the button that was clicked.
+
+ If \a tqparent is 0, the message box becomes an application-global
+ modal dialog box. If \a tqparent is a widget, the message box
+ becomes modal relative to \a tqparent.
+
+ \sa information(), warning(), critical()
+*/
+
+int TQMessageBox::question( TQWidget *tqparent,
+ const TQString& caption, const TQString& text,
+ int button0, int button1, int button2 )
+{
+ TQMessageBox *mb = new TQMessageBox( caption, text, Question,
+ button0, button1, button2,
+ tqparent, "qt_msgbox_information", TRUE,
+ (WFlags)TQt::WDestructiveClose);
+ TQ_CHECK_PTR( mb );
+ return mb->exec();
+}
+
+
+/*!
+ Opens a warning message box with the caption \a caption and the
+ text \a text. The dialog may have up to three buttons. Each of the
+ button parameters, \a button0, \a button1 and \a button2 may be
+ set to one of the following values:
+
+ \list
+ \i TQMessageBox::NoButton
+ \i TQMessageBox::Ok
+ \i TQMessageBox::Cancel
+ \i TQMessageBox::Yes
+ \i TQMessageBox::No
+ \i TQMessageBox::Abort
+ \i TQMessageBox::Retry
+ \i TQMessageBox::Ignore
+ \i TQMessageBox::YesAll
+ \i TQMessageBox::NoAll
+ \endlist
+
+ If you don't want all three buttons, set the last button, or last
+ two buttons to TQMessageBox::NoButton.
+
+ One button can be OR-ed with \c TQMessageBox::Default, and one
+ button can be OR-ed with \c TQMessageBox::Escape.
+
+ Returns the identity (TQMessageBox::Ok, or TQMessageBox::No, etc.)
+ of the button that was clicked.
+
+ If \a tqparent is 0, the message box becomes an application-global
+ modal dialog box. If \a tqparent is a widget, the message box
+ becomes modal relative to \a tqparent.
+
+ \sa information(), question(), critical()
+*/
+
+int TQMessageBox::warning( TQWidget *tqparent,
+ const TQString& caption, const TQString& text,
+ int button0, int button1, int button2 )
+{
+ TQMessageBox *mb = new TQMessageBox( caption, text, Warning,
+ button0, button1, button2,
+ tqparent, "qt_msgbox_warning", TRUE,
+ (WFlags)TQt::WDestructiveClose);
+ TQ_CHECK_PTR( mb );
+ return mb->exec();
+}
+
+
+/*!
+ Opens a critical message box with the caption \a caption and the
+ text \a text. The dialog may have up to three buttons. Each of the
+ button parameters, \a button0, \a button1 and \a button2 may be
+ set to one of the following values:
+
+ \list
+ \i TQMessageBox::NoButton
+ \i TQMessageBox::Ok
+ \i TQMessageBox::Cancel
+ \i TQMessageBox::Yes
+ \i TQMessageBox::No
+ \i TQMessageBox::Abort
+ \i TQMessageBox::Retry
+ \i TQMessageBox::Ignore
+ \i TQMessageBox::YesAll
+ \i TQMessageBox::NoAll
+ \endlist
+
+ If you don't want all three buttons, set the last button, or last
+ two buttons to TQMessageBox::NoButton.
+
+ One button can be OR-ed with \c TQMessageBox::Default, and one
+ button can be OR-ed with \c TQMessageBox::Escape.
+
+ Returns the identity (TQMessageBox::Ok, or TQMessageBox::No, etc.)
+ of the button that was clicked.
+
+ If \a tqparent is 0, the message box becomes an application-global
+ modal dialog box. If \a tqparent is a widget, the message box
+ becomes modal relative to \a tqparent.
+
+ \sa information(), question(), warning()
+*/
+
+int TQMessageBox::critical( TQWidget *tqparent,
+ const TQString& caption, const TQString& text,
+ int button0, int button1, int button2 )
+{
+ TQMessageBox *mb = new TQMessageBox( caption, text, Critical,
+ button0, button1, button2,
+ tqparent, "qt_msgbox_critical", TRUE,
+ (WFlags)TQt::WDestructiveClose);
+ TQ_CHECK_PTR( mb );
+ return mb->exec();
+}
+
+
+/*!
+ Displays a simple about box with caption \a caption and text \a
+ text. The about box's tqparent is \a tqparent.
+
+ about() looks for a suitable icon in four locations:
+ \list 1
+ \i It prefers \link TQWidget::icon() tqparent->icon() \endlink if that exists.
+ \i If not, it tries the top-level widget containing \a tqparent.
+ \i If that fails, it tries the \link
+ TQApplication::mainWidget() main widget. \endlink
+ \i As a last resort it uses the Information icon.
+ \endlist
+
+ The about box has a single button labelled "OK".
+
+ \sa TQWidget::icon() TQApplication::mainWidget()
+*/
+
+void TQMessageBox::about( TQWidget *tqparent, const TQString &caption,
+ const TQString& text )
+{
+ TQMessageBox *mb = new TQMessageBox( caption, text,
+ Information,
+ Ok + Default, 0, 0,
+ tqparent, "qt_msgbox_simple_about_box", TRUE,
+ (WFlags)TQt::WDestructiveClose);
+ TQ_CHECK_PTR( mb );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ const TQPixmap *pm = tqparent ? tqparent->icon() : 0;
+ if ( pm && !pm->isNull() )
+ mb->setIconPixmap( *pm );
+ else {
+ pm = tqparent ? tqparent->tqtopLevelWidget()->icon() : 0;
+ if ( pm && !pm->isNull() )
+ mb->setIconPixmap( *pm );
+ else {
+ pm = tqApp && tqApp->mainWidget() ? tqApp->mainWidget()->icon() : 0;
+ if ( pm && !pm->isNull() )
+ mb->setIconPixmap( *pm );
+ }
+ }
+#endif
+ mb->exec();
+}
+
+
+/*! \reimp
+*/
+
+void TQMessageBox::styleChanged( TQStyle& )
+{
+ if ( mbd->icon != NoIcon ) {
+ // Reload icon for new style
+ setIcon( mbd->icon );
+ }
+}
+
+
+static int textBox( TQWidget *tqparent, TQMessageBox::Icon severity,
+ const TQString& caption, const TQString& text,
+ const TQString& button0Text,
+ const TQString& button1Text,
+ const TQString& button2Text,
+ int defaultButtonNumber,
+ int escapeButtonNumber )
+{
+ int b[3];
+ b[0] = 1;
+ b[1] = button1Text.isEmpty() ? 0 : 2;
+ b[2] = button2Text.isEmpty() ? 0 : 3;
+
+ int i;
+ for( i=0; i<3; i++ ) {
+ if ( b[i] && defaultButtonNumber == i )
+ b[i] += TQMessageBox::Default;
+ if ( b[i] && escapeButtonNumber == i )
+ b[i] += TQMessageBox::Escape;
+ }
+
+ TQMessageBox *mb = new TQMessageBox( caption, text, severity,
+ b[0], b[1], b[2],
+ tqparent, "qt_msgbox_information", TRUE,
+ (WFlags)TQt::WDestructiveClose);
+ TQ_CHECK_PTR( mb );
+ if ( button0Text.isEmpty() )
+ mb->setButtonText( 1, TQMessageBox::tr(mb_texts[TQMessageBox::Ok]) );
+ else
+ mb->setButtonText( 1, button0Text );
+ if ( b[1] )
+ mb->setButtonText( 2, button1Text );
+ if ( b[2] )
+ mb->setButtonText( 3, button2Text );
+
+#ifndef TQT_NO_CURSOR
+ mb->setCursor( Qt::ArrowCursor );
+#endif
+ return mb->exec() - 1;
+}
+
+
+/*!
+ \overload
+
+ Displays an information message box with caption \a caption, text
+ \a text and one, two or three buttons. Returns the index of the
+ button that was clicked (0, 1 or 2).
+
+ \a button0Text is the text of the first button, and is optional.
+ If \a button0Text is not supplied, "OK" (translated) will be used.
+ \a button1Text is the text of the second button, and is optional.
+ \a button2Text is the text of the third button, and is optional.
+ \a defaultButtonNumber (0, 1 or 2) is the index of the default
+ button; pressing Return or Enter is the same as clicking the
+ default button. It defaults to 0 (the first button). \a
+ escapeButtonNumber is the index of the Escape button; pressing
+ Escape is the same as clicking this button. It defaults to -1;
+ supply 0, 1 or 2 to make pressing Escape equivalent to clicking
+ the relevant button.
+
+ If \a tqparent is 0, the message box becomes an application-global
+ modal dialog box. If \a tqparent is a widget, the message box
+ becomes modal relative to \a tqparent.
+
+ Note: If you do not specify an Escape button then if the Escape
+ button is pressed then -1 will be returned. It is suggested that
+ you specify an Escape button to prevent this from happening.
+
+ \sa question(), warning(), critical()
+*/
+
+int TQMessageBox::information( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ const TQString& button0Text,
+ const TQString& button1Text,
+ const TQString& button2Text,
+ int defaultButtonNumber,
+ int escapeButtonNumber )
+{
+ return textBox( tqparent, Information, caption, text,
+ button0Text, button1Text, button2Text,
+ defaultButtonNumber, escapeButtonNumber );
+}
+
+/*!
+ \overload
+
+ Displays a question message box with caption \a caption, text \a
+ text and one, two or three buttons. Returns the index of the
+ button that was clicked (0, 1 or 2).
+
+ \a button0Text is the text of the first button, and is optional.
+ If \a button0Text is not supplied, "OK" (translated) will be used.
+ \a button1Text is the text of the second button, and is optional.
+ \a button2Text is the text of the third button, and is optional.
+ \a defaultButtonNumber (0, 1 or 2) is the index of the default
+ button; pressing Return or Enter is the same as clicking the
+ default button. It defaults to 0 (the first button). \a
+ escapeButtonNumber is the index of the Escape button; pressing
+ Escape is the same as clicking this button. It defaults to -1;
+ supply 0, 1 or 2 to make pressing Escape equivalent to clicking
+ the relevant button.
+
+ If \a tqparent is 0, the message box becomes an application-global
+ modal dialog box. If \a tqparent is a widget, the message box
+ becomes modal relative to \a tqparent.
+
+ Note: If you do not specify an Escape button then if the Escape
+ button is pressed then -1 will be returned. It is suggested that
+ you specify an Escape button to prevent this from happening.
+
+ \sa information(), warning(), critical()
+*/
+int TQMessageBox::question( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ const TQString& button0Text,
+ const TQString& button1Text,
+ const TQString& button2Text,
+ int defaultButtonNumber,
+ int escapeButtonNumber )
+{
+ return textBox( tqparent, Question, caption, text,
+ button0Text, button1Text, button2Text,
+ defaultButtonNumber, escapeButtonNumber );
+}
+
+
+/*!
+ \overload
+
+ Displays a warning message box with a caption, a text, and 1, 2 or
+ 3 buttons. Returns the number of the button that was clicked (0,
+ 1, or 2).
+
+ \a button0Text is the text of the first button, and is optional.
+ If \a button0Text is not supplied, "OK" (translated) will be used.
+ \a button1Text is the text of the second button, and is optional,
+ and \a button2Text is the text of the third button, and is
+ optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
+ default button; pressing Return or Enter is the same as clicking
+ the default button. It defaults to 0 (the first button). \a
+ escapeButtonNumber is the index of the Escape button; pressing
+ Escape is the same as clicking this button. It defaults to -1;
+ supply 0, 1, or 2 to make pressing Escape equivalent to clicking
+ the relevant button.
+
+ If \a tqparent is 0, the message box becomes an application-global
+ modal dialog box. If \a tqparent is a widget, the message box
+ becomes modal relative to \a tqparent.
+
+ Note: If you do not specify an Escape button then if the Escape
+ button is pressed then -1 will be returned. It is suggested that
+ you specify an Escape button to prevent this from happening.
+
+ \sa information(), question(), critical()
+*/
+
+int TQMessageBox::warning( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ const TQString& button0Text,
+ const TQString& button1Text,
+ const TQString& button2Text,
+ int defaultButtonNumber,
+ int escapeButtonNumber )
+{
+ return textBox( tqparent, Warning, caption, text,
+ button0Text, button1Text, button2Text,
+ defaultButtonNumber, escapeButtonNumber );
+}
+
+
+/*!
+ \overload
+
+ Displays a critical error message box with a caption, a text, and
+ 1, 2 or 3 buttons. Returns the number of the button that was
+ clicked (0, 1 or 2).
+
+ \a button0Text is the text of the first button, and is optional.
+ If \a button0Text is not supplied, "OK" (translated) will be used.
+ \a button1Text is the text of the second button, and is optional,
+ and \a button2Text is the text of the third button, and is
+ optional. \a defaultButtonNumber (0, 1 or 2) is the index of the
+ default button; pressing Return or Enter is the same as clicking
+ the default button. It defaults to 0 (the first button). \a
+ escapeButtonNumber is the index of the Escape button; pressing
+ Escape is the same as clicking this button. It defaults to -1;
+ supply 0, 1, or 2 to make pressing Escape equivalent to clicking
+ the relevant button.
+
+ If \a tqparent is 0, the message box becomes an application-global
+ modal dialog box. If \a tqparent is a widget, the message box
+ becomes modal relative to \a tqparent.
+
+ \sa information(), question(), warning()
+*/
+
+int TQMessageBox::critical( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ const TQString& button0Text,
+ const TQString& button1Text,
+ const TQString& button2Text,
+ int defaultButtonNumber,
+ int escapeButtonNumber )
+{
+ return textBox( tqparent, Critical, caption, text,
+ button0Text, button1Text, button2Text,
+ defaultButtonNumber, escapeButtonNumber );
+}
+
+
+/*!
+ Displays a simple message box about TQt, with caption \a caption
+ and centered over \a tqparent (if \a tqparent is not 0). The message
+ includes the version number of TQt being used by the application.
+
+ This is useful for inclusion in the Help menu of an application.
+ See the examples/menu/menu.cpp example.
+
+ TQApplication provides this functionality as a slot.
+
+ \sa TQApplication::aboutTQt()
+*/
+
+void TQMessageBox::aboutTQt( TQWidget *tqparent, const TQString &caption )
+{
+ TQMessageBox *mb = new TQMessageBox( tqparent, "qt_msgbox_about_qt" );
+ TQ_CHECK_PTR( mb );
+ mb->setWFlags( TQt::WDestructiveClose );
+
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ TQString c = caption;
+ if ( c.isNull() )
+ c = tr( "About TQt" );
+ mb->setCaption( c );
+#endif
+ mb->setText( *translatedTextAboutTQt );
+#ifndef TQT_NO_IMAGEIO
+ TQPixmap pm;
+ TQImage logo( (const char **)qtlogo_xpm);
+ if ( tqGray(mb->tqpalette().active().text().rgb()) >
+ tqGray(mb->tqpalette().active().base().rgb()) )
+ {
+ // light on dark, adjust some colors (where's 10?)
+ logo.setColor( 0, 0xffffffff );
+ logo.setColor( 1, 0xff666666 );
+ logo.setColor( 2, 0xffcccc66 );
+ logo.setColor( 4, 0xffcccccc );
+ logo.setColor( 6, 0xffffff66 );
+ logo.setColor( 7, 0xff999999 );
+ logo.setColor( 8, 0xff3333ff );
+ logo.setColor( 9, 0xffffff33 );
+ logo.setColor( 11, 0xffcccc99 );
+ }
+ if ( pm.convertFromImage( logo ) )
+ mb->setIconPixmap( pm );
+#endif
+ mb->setButtonText( 0, tr("OK") );
+ if ( mb->mbd && mb->mbd->pb[0] ) {
+ mb->mbd->pb[0]->setAutoDefault( TRUE );
+ mb->mbd->pb[0]->setFocusPolicy( Qt::StrongFocus );
+ mb->mbd->pb[0]->setDefault( TRUE );
+ mb->mbd->pb[0]->setFocus();
+ }
+ mb->exec();
+}
+
+/*!
+ \reimp
+*/
+
+void TQMessageBox::setIcon( const TQPixmap &pix )
+{
+ //reimplemented to avoid compiler warning.
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ TQDialog::setIcon( pix );
+#endif
+}
+
+
+/*!
+ \property TQMessageBox::textFormat
+ \brief the format of the text displayed by the message box
+
+ The current text format used by the message box. See the \l
+ TQt::TextFormat enum for an explanation of the possible options.
+
+ The default format is \c AutoText.
+
+ \sa setText()
+*/
+
+TQt::TextFormat TQMessageBox::textFormat() const
+{
+ return label->textFormat();
+}
+
+
+void TQMessageBox::setTextFormat( TQt::TextFormat format )
+{
+ label->setTextFormat( format );
+}
+
+
+#endif
diff --git a/tqtinterface/qt4/src/dialogs/tqmessagebox.h b/tqtinterface/qt4/src/dialogs/tqmessagebox.h
new file mode 100644
index 0000000..c567814
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqmessagebox.h
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Definition of TQMessageBox class
+**
+** Created : 950503
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMESSAGEBOX_H
+#define TQMESSAGEBOX_H
+
+#ifndef TQT_H
+#include "tqdialog.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_MESSAGEBOX
+
+class TQLabel;
+class TQPushButton;
+struct TQMessageBoxData;
+
+class TQ_EXPORT TQMessageBox : public TQDialog
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( Icon )
+ Q_PROPERTY( TQString text READ text WRITE setText )
+ Q_PROPERTY( Icon icon READ icon WRITE setIcon )
+ Q_PROPERTY( TQPixmap iconPixmap READ iconPixmap WRITE setIconPixmap )
+ Q_PROPERTY( TextFormat textFormat READ textFormat WRITE setTextFormat )
+
+public:
+ enum Icon { NoIcon = 0, Information = 1, Warning = 2, Critical = 3,
+ Question = 4 };
+
+ TQMessageBox( TQWidget* tqparent=0, const char* name=0 );
+ TQMessageBox( const TQString& caption, const TQString &text, Icon icon,
+ int button0, int button1, int button2,
+ TQWidget* tqparent=0, const char* name=0, bool modal=TRUE,
+ WFlags f=(WFlags)TQt::WStyle_DialogBorder );
+ ~TQMessageBox();
+
+ enum { NoButton = 0, Ok = 1, Cancel = 2, Yes = 3, No = 4, Abort = 5,
+ Retry = 6, Ignore = 7, YesAll = 8, NoAll = 9, ButtonMask = 0xff,
+ Default = 0x100, Escape = 0x200, FlagMask = 0x300 };
+
+ static int information( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ int button0, int button1=0, int button2=0 );
+ static int information( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ const TQString& button0Text = TQString::null,
+ const TQString& button1Text = TQString::null,
+ const TQString& button2Text = TQString::null,
+ int defaultButtonNumber = 0,
+ int escapeButtonNumber = -1 );
+
+ static int question( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ int button0, int button1=0, int button2=0 );
+ static int question( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ const TQString& button0Text = TQString::null,
+ const TQString& button1Text = TQString::null,
+ const TQString& button2Text = TQString::null,
+ int defaultButtonNumber = 0,
+ int escapeButtonNumber = -1 );
+
+ static int warning( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ int button0, int button1, int button2=0 );
+ static int warning( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ const TQString& button0Text = TQString::null,
+ const TQString& button1Text = TQString::null,
+ const TQString& button2Text = TQString::null,
+ int defaultButtonNumber = 0,
+ int escapeButtonNumber = -1 );
+
+ static int critical( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ int button0, int button1, int button2=0 );
+ static int critical( TQWidget *tqparent, const TQString &caption,
+ const TQString& text,
+ const TQString& button0Text = TQString::null,
+ const TQString& button1Text = TQString::null,
+ const TQString& button2Text = TQString::null,
+ int defaultButtonNumber = 0,
+ int escapeButtonNumber = -1 );
+
+ static void about( TQWidget *tqparent, const TQString &caption,
+ const TQString& text );
+
+ static void aboutTQt( TQWidget *tqparent,
+ const TQString& caption=TQString::null );
+
+/* OBSOLETE */
+ static int message( const TQString &caption,
+ const TQString& text,
+ const TQString& buttonText=TQString::null,
+ TQWidget *tqparent=0, const char * =0 ) {
+ return TQMessageBox::information( tqparent, caption, text,
+ buttonText.isEmpty()
+ ? tqtr("OK") : buttonText ) == 0;
+ }
+
+/* OBSOLETE */
+ static bool query( const TQString &caption,
+ const TQString& text,
+ const TQString& yesButtonText=TQString::null,
+ const TQString& noButtonText=TQString::null,
+ TQWidget *tqparent=0, const char * = 0 ) {
+ return TQMessageBox::information( tqparent, caption, text,
+ yesButtonText.isEmpty()
+ ? tqtr("OK") : yesButtonText,
+ noButtonText ) == 0;
+ }
+
+ TQString text() const;
+ void setText( const TQString &);
+
+ Icon icon() const;
+
+ void setIcon( Icon );
+ void setIcon( const TQPixmap & );
+
+ const TQPixmap *iconPixmap() const;
+ void setIconPixmap( const TQPixmap & );
+
+ TQString buttonText( int button ) const;
+ void setButtonText( int button, const TQString &);
+
+ void adjustSize();
+
+/* OBSOLETE */
+ static TQPixmap standardIcon( Icon icon, TQt::GUIStyle );
+
+ static TQPixmap standardIcon( Icon icon );
+
+ TQt::TextFormat textFormat() const;
+ void setTextFormat( TQt::TextFormat );
+
+protected:
+ void resizeEvent( TQResizeEvent * );
+ void showEvent( TQShowEvent * );
+ void closeEvent( TQCloseEvent * );
+ void keyPressEvent( TQKeyEvent * );
+ void styleChanged( TQStyle& );
+
+private Q_SLOTS:
+ void buttonClicked();
+
+private:
+ void init( int, int, int );
+ int indexOf( int ) const;
+ void resizeButtons();
+ TQLabel *label;
+ TQMessageBoxData *mbd;
+ void *reserved1;
+ void *reserved2;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQMessageBox( const TQMessageBox & );
+ TQMessageBox &operator=( const TQMessageBox & );
+#endif
+};
+
+/*
+* Macro to be used at the beginning of main(), e.g.
+*
+* #include <tqapplication.h>
+* #include <tqmessagebox.h>
+* int main( int argc, char**argv )
+* {
+* TQT_RETQUIRE_VERSION( argc, argv, "3.0.5" )
+* ...
+* }
+*/
+#define TQT_RETQUIRE_VERSION( argc, argv, str ) { TQString s=TQString::tqfromLatin1(str);\
+TQString sq=TQString::tqfromLatin1(qVersion()); if ( (sq.section('.',0,0).toInt()<<16)+\
+(sq.section('.',1,1).toInt()<<8)+sq.section('.',2,2).toInt()<(s.section('.',0,0).toInt()<<16)+\
+(s.section('.',1,1).toInt()<<8)+s.section('.',2,2).toInt() ){if ( !tqApp){ int c=0; new \
+TQApplication(argc,argv);} TQString s = TQApplication::tr("Executable '%1' requires TQt "\
+ "%2, found TQt %3.").arg(TQString::tqfromLatin1(tqAppName())).arg(TQString::tqfromLatin1(\
+str)).arg(TQString::tqfromLatin1(qVersion()) ); TQMessageBox::critical( 0, TQApplication::tr(\
+"Incompatible TQt Library Error" ), s, TQMessageBox::Abort,0 ); qFatal(s.ascii()); }}
+
+
+#endif // TQT_NO_MESSAGEBOX
+
+#endif // TQMESSAGEBOX_H
diff --git a/tqtinterface/qt4/src/dialogs/tqprintdialog.cpp b/tqtinterface/qt4/src/dialogs/tqprintdialog.cpp
new file mode 100644
index 0000000..eb4a794
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqprintdialog.cpp
@@ -0,0 +1,1672 @@
+/****************************************************************************
+**
+** Implementation of internal print dialog (X11) used by TQPrinter::select().
+**
+** Created : 950829
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqprintdialog.h"
+
+#ifndef TQT_NO_PRINTDIALOG
+
+#include "tqfiledialog.h"
+#include "tqfile.h"
+#include "tqtextstream.h"
+#include "tqcombobox.h"
+#include "tqframe.h"
+#include "tqlabel.h"
+#include "tqlineedit.h"
+#include "tqpushbutton.h"
+#include "tqprinter.h"
+#include "tqlistview.h"
+#include "tqlayout.h"
+#include "tqbuttongroup.h"
+#include "tqradiobutton.h"
+#include "tqspinbox.h"
+#include "tqapplication.h"
+#include "tqheader.h"
+#include "tqstyle.h"
+#include "tqstring.h"
+#include "tqregexp.h"
+#if !defined(TQT_NO_CUPS) || !defined(TQT_NO_NIS)
+#include "tqlibrary.h"
+#endif
+
+#ifndef TQT_NO_NIS
+
+#ifndef BOOL_DEFINED
+#define BOOL_DEFINED
+#endif
+
+#include <rpcsvc/ypclnt.h>
+#include <rpcsvc/yp_prot.h>
+
+// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
+#if defined(connect)
+# undef connect
+#endif
+
+#endif // TQT_NO_NIS
+
+// UNIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+
+
+class TQPrintDialogSpinBox : public TQSpinBox
+{
+public:
+ TQPrintDialogSpinBox(int min, int max, int steps, TQWidget *tqparent, const char *name)
+ : TQSpinBox(min, max, steps, tqparent, name)
+ {}
+
+ void interpretText()
+ {
+ TQSpinBox::interpretText();
+ }
+};
+
+
+
+
+enum { Success = 's', Unavail = 'u', NotFound = 'n', TryAgain = 't' };
+enum { Continue = 'c', Return = 'r' };
+
+class TQPrintDialogPrivate
+{
+public:
+ TQPrinter * printer;
+
+ TQButtonGroup * printerOrFile;
+
+ bool outputToFile;
+ TQListView * printers;
+ TQLineEdit * fileName;
+ TQPushButton * browse, *ok;
+
+ TQButtonGroup * printRange;
+ TQLabel * firstPageLabel;
+ TQPrintDialogSpinBox * firstPage;
+ TQLabel * lastPageLabel;
+ TQPrintDialogSpinBox * lastPage;
+ TQRadioButton * printAllButton;
+ TQRadioButton * printRangeButton;
+ TQRadioButton * printSelectionButton;
+ TQRadioButton * printToFileButton;
+ TQComboBox *orientationCombo, *sizeCombo;
+
+ TQPrinter::PageSize pageSize;
+ TQPrinter::Orientation orientation;
+
+ TQButtonGroup * pageOrder;
+ TQPrinter::PageOrder pageOrder2;
+
+ TQButtonGroup * colorMode;
+ TQPrinter::ColorMode colorMode2;
+
+ TQPrintDialogSpinBox * copies;
+ int numCopies;
+
+ TQBoxLayout *customLayout;
+
+ TQPrinter::PageSize indexToPageSize[TQPrinter::NPageSize];
+};
+
+
+typedef void (*TQ_PrintDialogHook)(TQListView *);
+static TQ_PrintDialogHook addPrinterHook = 0;
+
+void qt_set_printdialog_hook( TQ_PrintDialogHook hook )
+{
+ addPrinterHook = hook;
+}
+
+static void isc( TQPrintDialogPrivate * d, const TQString & text,
+ TQPrinter::PageSize ps );
+
+class TQPrinterListViewItem : public TQListViewItem
+{
+public:
+ TQPrinterListViewItem( TQListView * printers, const TQString& name,
+ const TQString& host, const TQString& comment,
+ const TQStringList& aliases )
+ : TQListViewItem( printers, name, host, comment ), ali( aliases ) { }
+
+ bool samePrinter( const TQString& name ) {
+ return text( 0 ) == name || ali.tqfind( name ) != ali.end();
+ }
+
+ TQStringList ali;
+};
+
+static void perhapsAddPrinter( TQListView * printers, const TQString &name,
+ TQString host, TQString comment,
+ TQStringList aliases = TQStringList() )
+{
+ const TQListViewItem * i = printers->firstChild();
+ while ( i && !((TQPrinterListViewItem *) i)->samePrinter(name) )
+ i = i->nextSibling();
+ if ( i )
+ return;
+ if ( host.isEmpty() )
+ host = TQPrintDialog::tr( "locally connected" );
+ (void)new TQPrinterListViewItem( printers,
+ name.simplifyWhiteSpace(),
+ host.simplifyWhiteSpace(),
+ comment.simplifyWhiteSpace(), aliases );
+}
+
+static void parsePrinterDesc( TQString printerDesc, TQListView * printers )
+{
+ if ( printerDesc.length() < 1 )
+ return;
+
+ printerDesc = printerDesc.simplifyWhiteSpace();
+ int i = printerDesc.tqfind( ':' );
+ TQString printerName, printerComment, printerHost;
+ TQStringList aliases;
+
+ if ( i >= 0 ) {
+ // have ':' want '|'
+ int j = printerDesc.tqfind( '|' );
+ if ( j > 0 && j < i ) {
+ printerName = printerDesc.left( j );
+ aliases = TQStringList::split( '|',
+ printerDesc.mid(j + 1, i - j - 1) );
+ // try extracting a comment from the aliases
+ printerComment = TQPrintDialog::tr( "Aliases: %1" )
+ .arg( aliases.join(", ") );
+ } else {
+ printerName = printerDesc.left( i );
+ }
+ // look for lprng pseudo all printers entry
+ i = printerDesc.tqfind( TQRegExp(TQString::tqfromLatin1(": *all *=")) );
+ if ( i >= 0 )
+ printerName = "";
+ // look for signs of this being a remote printer
+ i = printerDesc.tqfind( TQRegExp(TQString::tqfromLatin1(": *rm *=")) );
+ if ( i >= 0 ) {
+ // point k at the end of remote host name
+ while ( printerDesc[i] != '=' )
+ i++;
+ while ( printerDesc[i] == '=' || printerDesc[i].isSpace() )
+ i++;
+ j = i;
+ while ( j < (int)printerDesc.length() && printerDesc[j] != ':' )
+ j++;
+
+ // and stuff that into the string
+ printerHost = printerDesc.mid( i, j - i );
+ }
+ }
+ if ( printerName.length() )
+ perhapsAddPrinter( printers, printerName, printerHost, printerComment,
+ aliases );
+}
+
+static int parsePrintcap( TQListView * printers, const TQString& fileName )
+{
+ TQFile printcap( fileName );
+ if ( !printcap.open( IO_ReadOnly ) )
+ return NotFound;
+
+ char * line_ascii = new char[1025];
+ line_ascii[1024] = '\0';
+
+ TQString printerDesc;
+ bool atEnd = FALSE;
+
+ while ( !atEnd ) {
+ if ( printcap.atEnd() || printcap.readLine( line_ascii, 1024 ) <= 0 )
+ atEnd = TRUE;
+ TQString line = line_ascii;
+ line = line.stripWhiteSpace();
+ if ( line.length() >= 1 && line[int(line.length()) - 1] == '\\' )
+ line.truncate( line.length() - 1 );
+ if ( line[0] == '#' ) {
+ if ( !atEnd )
+ continue;
+ } else if ( line[0] == '|' || line[0] == ':' ) {
+ printerDesc += line;
+ if ( !atEnd )
+ continue;
+ }
+
+ parsePrinterDesc( printerDesc, printers );
+
+ // add the first line of the new printer definition
+ printerDesc = line;
+ }
+ delete[] line_ascii;
+ return Success;
+}
+
+
+// solaris, not 2.6
+static void parseEtcLpPrinters( TQListView * printers )
+{
+ TQDir lp( TQString::tqfromLatin1("/etc/lp/printers") );
+ const TQFileInfoList * dirs = lp.entryInfoList();
+ if ( !dirs )
+ return;
+
+ TQFileInfoListIterator it( *dirs );
+ TQFileInfo *printer;
+ TQString tmp;
+ while ( (printer = it.current()) != 0 ) {
+ ++it;
+ if ( printer->isDir() ) {
+ tmp.sprintf( "/etc/lp/printers/%s/configuration",
+ printer->fileName().ascii() );
+ TQFile configuration( tmp );
+ char * line = new char[1025];
+ TQString remote( TQString::tqfromLatin1("Remote:") );
+ TQString contentType( TQString::tqfromLatin1("Content types:") );
+ TQString printerHost;
+ bool canPrintPostscript = FALSE;
+ if ( configuration.open( IO_ReadOnly ) ) {
+ while ( !configuration.atEnd() &&
+ configuration.readLine( line, 1024 ) > 0 ) {
+ if ( TQString::tqfromLatin1(line).startsWith( remote ) ) {
+ const char * p = line;
+ while ( *p != ':' )
+ p++;
+ p++;
+ while ( isspace((uchar) *p) )
+ p++;
+ printerHost = TQString::fromLocal8Bit(p);
+ printerHost = printerHost.simplifyWhiteSpace();
+ } else if ( TQString::tqfromLatin1(line).startsWith( contentType ) ) {
+ char * p = line;
+ while ( *p != ':' )
+ p++;
+ p++;
+ char * e;
+ while ( *p ) {
+ while ( isspace((uchar) *p) )
+ p++;
+ if ( *p ) {
+ char s;
+ e = p;
+ while ( isalnum((uchar) *e) )
+ e++;
+ s = *e;
+ *e = '\0';
+ if ( !qstrcmp( p, "postscript" ) ||
+ !qstrcmp( p, "any" ) )
+ canPrintPostscript = TRUE;
+ *e = s;
+ if ( s == ',' )
+ e++;
+ p = e;
+ }
+ }
+ }
+ }
+ if ( canPrintPostscript )
+ perhapsAddPrinter( printers, printer->fileName(),
+ printerHost, TQString::tqfromLatin1("") );
+ }
+ delete[] line;
+ }
+ }
+}
+
+
+// solaris 2.6
+static char * parsePrintersConf( TQListView * printers, bool *found = 0 )
+{
+ TQFile pc( TQString::tqfromLatin1("/etc/printers.conf") );
+ if ( !pc.open( IO_ReadOnly ) ) {
+ if ( found )
+ *found = FALSE;
+ return 0;
+ }
+ if ( found )
+ *found = TRUE;
+
+ char * line = new char[1025];
+ line[1024] = '\0';
+
+ TQString printerDesc;
+ int lineLength = 0;
+
+ char * defaultPrinter = 0;
+
+ while ( !pc.atEnd() &&
+ (lineLength=pc.readLine( line, 1024 )) > 0 ) {
+ if ( *line == '#' ) {
+ *line = '\0';
+ lineLength = 0;
+ }
+ if ( lineLength >= 2 && line[lineLength-2] == '\\' ) {
+ line[lineLength-2] = '\0';
+ printerDesc += TQString::fromLocal8Bit(line);
+ } else {
+ printerDesc += TQString::fromLocal8Bit(line);
+ printerDesc = printerDesc.simplifyWhiteSpace();
+ int i = printerDesc.tqfind( ':' );
+ TQString printerName, printerHost, printerComment;
+ TQStringList aliases;
+ if ( i >= 0 ) {
+ // have : want |
+ int j = printerDesc.tqfind( '|', 0 );
+ if ( j >= i )
+ j = -1;
+ printerName = printerDesc.mid( 0, j < 0 ? i : j );
+ if ( printerName == TQString::tqfromLatin1("_default") ) {
+ i = printerDesc.tqfind(
+ TQRegExp( TQString::tqfromLatin1(": *use *=") ) );
+ while ( printerDesc[i] != '=' )
+ i++;
+ while ( printerDesc[i] == '=' || printerDesc[i].isSpace() )
+ i++;
+ j = i;
+ while ( j < (int)printerDesc.length() &&
+ printerDesc[j] != ':' && printerDesc[j] != ',' )
+ j++;
+ // that's our default printer
+ defaultPrinter =
+ qstrdup( TQT_TQSTRING(printerDesc.mid( i, j-i )).ascii() );
+ printerName = "";
+ printerDesc = "";
+ } else if ( printerName == TQString::tqfromLatin1("_all") ) {
+ // skip it.. any other cases we want to skip?
+ printerName = "";
+ printerDesc = "";
+ }
+
+ if ( j > 0 ) {
+ // try extracting a comment from the aliases
+ aliases = TQStringList::split( '|',
+ printerDesc.mid(j + 1, i - j - 1) );
+ printerComment = TQPrintDialog::tr( "Aliases: %1" )
+ .arg( aliases.join(", ") );
+ }
+ // look for signs of this being a remote printer
+ i = printerDesc.tqfind(
+ TQRegExp( TQString::tqfromLatin1(": *bsdaddr *=") ) );
+ if ( i >= 0 ) {
+ // point k at the end of remote host name
+ while ( printerDesc[i] != '=' )
+ i++;
+ while ( printerDesc[i] == '=' || printerDesc[i].isSpace() )
+ i++;
+ j = i;
+ while ( j < (int)printerDesc.length() &&
+ printerDesc[j] != ':' && printerDesc[j] != ',' )
+ j++;
+ // and stuff that into the string
+ printerHost = printerDesc.mid( i, j-i );
+ // maybe stick the remote printer name into the comment
+ if ( printerDesc[j] == ',' ) {
+ i = ++j;
+ while ( printerDesc[i].isSpace() )
+ i++;
+ j = i;
+ while ( j < (int)printerDesc.length() &&
+ printerDesc[j] != ':' && printerDesc[j] != ',' )
+ j++;
+ if ( printerName != printerDesc.mid( i, j-i ) ) {
+ printerComment =
+ TQString::tqfromLatin1("Remote name: ");
+ printerComment += printerDesc.mid( i, j-i );
+ }
+ }
+ }
+ }
+ if ( printerComment == ":" )
+ printerComment = ""; // for cups
+ if ( printerName.length() )
+ perhapsAddPrinter( printers, printerName, printerHost,
+ printerComment, aliases );
+ // chop away the line, for processing the next one
+ printerDesc = "";
+ }
+ }
+ delete[] line;
+ return defaultPrinter;
+}
+
+#ifndef TQT_NO_NIS
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static int foreach( int /* status */, char * /* key */, int /* keyLen */,
+ char * val, int valLen, char * data )
+{
+ parsePrinterDesc( TQString::tqfromLatin1(val, valLen), (TQListView *) data );
+ return 0;
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+static int retrieveNisPrinters( TQListView * printers )
+{
+ typedef int (*WildCast)( int, char *, int, char *, int, char * );
+ char printersConfByname[] = "printers.conf.byname";
+ char *domain;
+ int err;
+
+ TQLibrary lib( "nsl" );
+ typedef int (*ypGetDefaultDomain)(char **);
+ ypGetDefaultDomain _ypGetDefaultDomain = (ypGetDefaultDomain)lib.resolve( "yp_get_default_domain" );
+ typedef int (*ypAll)(const char *, const char *, const struct ypall_callback *);
+ ypAll _ypAll = (ypAll)lib.resolve( "yp_all" );
+
+ if ( _ypGetDefaultDomain && _ypAll ) {
+ err = _ypGetDefaultDomain( &domain );
+ if ( err == 0 ) {
+ ypall_callback cb;
+ // wild cast to support K&R-style system headers
+ (WildCast &) cb.foreach = (WildCast) foreach;
+ cb.data = (char *) printers;
+ err = _ypAll( domain, printersConfByname, &cb );
+ }
+ if ( !err )
+ return Success;
+ }
+ return Unavail;
+}
+
+#endif // TQT_NO_NIS
+
+static char *parseNsswitchPrintersEntry( TQListView * printers, char *line )
+{
+#define skipSpaces() \
+ while ( isspace((uchar) line[k]) ) \
+ k++
+
+ char *defaultPrinter = 0;
+ bool stop = FALSE;
+ int lastqStatus = NotFound;
+
+ int k = 8;
+ skipSpaces();
+ if ( line[k] != ':' )
+ return 0;
+ k++;
+
+ char *cp = strchr( line, '#' );
+ if ( cp != 0 )
+ *cp = '\0';
+
+ while ( line[k] != '\0' ) {
+ if ( isspace((uchar) line[k]) ) {
+ k++;
+ } else if ( line[k] == '[' ) {
+ k++;
+ skipSpaces();
+ while ( line[k] != '\0' ) {
+ char status = tolower( line[k] );
+ char action = '?';
+
+ while ( line[k] != '=' && line[k] != ']' &&
+ line[k] != '\0' )
+ k++;
+ if ( line[k] == '=' ) {
+ k++;
+ skipSpaces();
+ action = tolower( line[k] );
+ while ( line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != ']' )
+ k++;
+ } else if ( line[k] == ']' ) {
+ k++;
+ break;
+ }
+ skipSpaces();
+
+ if ( lastqStatus == status )
+ stop = ( action == (char) Return );
+ }
+ } else {
+ if ( stop )
+ break;
+
+ TQCString source;
+ while ( line[k] != '\0' && !isspace((uchar) line[k]) && line[k] != '[' ) {
+ source += line[k];
+ k++;
+ }
+
+ if ( source == "user" ) {
+ lastqStatus = parsePrintcap( printers,
+ TQDir::homeDirPath() + "/.printers" );
+ } else if ( source == "files" ) {
+ bool found;
+ defaultPrinter = parsePrintersConf( printers, &found );
+ if ( found )
+ lastqStatus = Success;
+#ifndef TQT_NO_NIS
+ } else if ( source == "nis" ) {
+ lastqStatus = retrieveNisPrinters( printers );
+#endif
+ } else {
+ // nisplus, dns, etc., are not implemented yet
+ lastqStatus = NotFound;
+ }
+ stop = ( lastqStatus == Success );
+ }
+ }
+ return defaultPrinter;
+}
+
+static char *parseNsswitchConf( TQListView * printers )
+{
+ TQFile nc( TQString::tqfromLatin1("/etc/nsswitch.conf") );
+ if ( !nc.open(IO_ReadOnly) )
+ return 0;
+
+ char *defaultPrinter = 0;
+
+ char *line = new char[1025];
+ line[1024] = '\0';
+
+ while ( !nc.atEnd() &&
+ nc.readLine(line, 1024) > 0 ) {
+ if ( strncmp(line, "printers", 8) == 0 ) {
+ defaultPrinter = parseNsswitchPrintersEntry( printers, line );
+ delete[] line;
+ return defaultPrinter;
+ }
+ }
+
+ strcpy( line, "printers: user files nis nisplus xfn" );
+ defaultPrinter = parseNsswitchPrintersEntry( printers, line );
+ delete[] line;
+ return defaultPrinter;
+}
+
+// HP-UX
+static void parseEtcLpMember( TQListView * printers )
+{
+ TQDir lp( TQString::tqfromLatin1("/etc/lp/member") );
+ if ( !lp.exists() )
+ return;
+ const TQFileInfoList * dirs = lp.entryInfoList();
+ if ( !dirs )
+ return;
+
+ TQFileInfoListIterator it( *dirs );
+ TQFileInfo *printer;
+ TQString tmp;
+ while ( (printer = it.current()) != 0 ) {
+ ++it;
+ // I haven't found any real documentation, so I'm guessing that
+ // since lpstat uses /etc/lp/member rather than one of the
+ // other directories, it's the one to use. I did not tqfind a
+ // decent way to locate aliases and remote printers.
+ if ( printer->isFile() )
+ perhapsAddPrinter( printers, printer->fileName(),
+ TQPrintDialog::tr("unknown"),
+ TQString::tqfromLatin1("") );
+ }
+}
+
+// IRIX 6.x
+static void parseSpoolInterface( TQListView * printers )
+{
+ TQDir lp( TQString::tqfromLatin1("/usr/spool/lp/interface") );
+ if ( !lp.exists() )
+ return;
+ const TQFileInfoList * files = lp.entryInfoList();
+ if( !files )
+ return;
+
+ TQFileInfoListIterator it( *files );
+ TQFileInfo *printer;
+ while ( (printer = it.current()) != 0) {
+ ++it;
+
+ if ( !printer->isFile() )
+ continue;
+
+ // parse out some information
+ TQFile configFile( printer->filePath() );
+ if ( !configFile.open( IO_ReadOnly ) )
+ continue;
+
+ TQCString line( 1025 );
+ TQString namePrinter;
+ TQString hostName;
+ TQString hostPrinter;
+ TQString printerType;
+
+ TQString nameKey( TQString::tqfromLatin1("NAME=") );
+ TQString typeKey( TQString::tqfromLatin1("TYPE=") );
+ TQString hostKey( TQString::tqfromLatin1("HOSTNAME=") );
+ TQString hostPrinterKey( TQString::tqfromLatin1("HOSTPRINTER=") );
+
+ while ( !configFile.atEnd() &&
+ (configFile.readLine(line.data(), 1024)) > 0 ) {
+ TQString uline = line;
+ if ( uline.startsWith( typeKey ) ) {
+ printerType = line.mid( nameKey.length() );
+ printerType = printerType.simplifyWhiteSpace();
+ } else if ( uline.startsWith( hostKey ) ) {
+ hostName = line.mid( hostKey.length() );
+ hostName = hostName.simplifyWhiteSpace();
+ } else if ( uline.startsWith( hostPrinterKey ) ) {
+ hostPrinter = line.mid( hostPrinterKey.length() );
+ hostPrinter = hostPrinter.simplifyWhiteSpace();
+ } else if ( uline.startsWith( nameKey ) ) {
+ namePrinter = line.mid( nameKey.length() );
+ namePrinter = namePrinter.simplifyWhiteSpace();
+ }
+ }
+ configFile.close();
+
+ printerType = printerType.stripWhiteSpace();
+ if ( printerType.tqfind("postscript", 0, FALSE) < 0 )
+ continue;
+
+ int ii = 0;
+ while ( (ii = namePrinter.tqfind('"', ii)) >= 0 )
+ namePrinter.remove( ii, 1 );
+
+ if ( hostName.isEmpty() || hostPrinter.isEmpty() ) {
+ perhapsAddPrinter( printers, printer->fileName(),
+ TQString::tqfromLatin1(""), namePrinter );
+ } else {
+ TQString comment;
+ comment = namePrinter;
+ comment += " (";
+ comment += hostPrinter;
+ comment += ")";
+ perhapsAddPrinter( printers, printer->fileName(),
+ hostName, comment );
+ }
+ }
+}
+
+
+// Every unix must have its own. It's a standard. Here is AIX.
+static void parseQconfig( TQListView * printers )
+{
+ TQFile qconfig( TQString::tqfromLatin1("/etc/qconfig") );
+ if ( !qconfig.open( IO_ReadOnly ) )
+ return;
+
+ TQTextStream ts( &qconfig );
+ TQString line;
+
+ TQString stanzaName; // either a queue or a tqdevice name
+ bool up = TRUE; // queue up? default TRUE, can be FALSE
+ TQString remoteHost; // null if local
+ TQString tqdeviceName; // null if remote
+
+ TQRegExp newStanza( TQString::tqfromLatin1("^[0-z\\-]+:$") );
+
+ // our basic strategy here is to process each line, detecting new
+ // stanzas. each time we see a new stanza, we check if the
+ // previous stanza was a valid queue for a) a remote printer or b)
+ // a local printer. if it wasn't, we assume that what we see is
+ // the start of the first stanza, or that the previous stanza was
+ // a tqdevice stanza, or that there is some syntax error (we don't
+ // report those).
+
+ do {
+ line = ts.readLine();
+ bool indented = line[0].isSpace();
+ line = line.simplifyWhiteSpace();
+
+ int i = line.tqfind('=');
+ if ( indented && i != -1 ) { // line in stanza
+ TQString variable = TQT_TQSTRING(line.left( i )).simplifyWhiteSpace();
+ TQString value=TQT_TQSTRING(line.mid( i+1, line.length() )).simplifyWhiteSpace();
+ if ( variable == TQString::tqfromLatin1("tqdevice") )
+ tqdeviceName = value;
+ else if ( variable == TQString::tqfromLatin1("host") )
+ remoteHost = value;
+ else if ( variable == TQString::tqfromLatin1("up") )
+ up = !(value.lower() == TQString::tqfromLatin1("false"));
+ } else if ( line[0] == '*' ) { // comment
+ // nothing to do
+ } else if ( ts.atEnd() || // end of file, or beginning of new stanza
+ ( !indented && line.tqfind( newStanza ) != -1 ) ) {
+ if ( up && stanzaName.length() > 0 && stanzaName.length() < 21 ) {
+ if ( remoteHost.length() ) // remote printer
+ perhapsAddPrinter( printers, stanzaName, remoteHost,
+ TQString::null );
+ else if ( tqdeviceName.length() ) // local printer
+ perhapsAddPrinter( printers, stanzaName, TQString::null,
+ TQString::null );
+ }
+ line.truncate( line.length()-1 );
+ if ( line.length() >= 1 && line.length() <= 20 )
+ stanzaName = line;
+ up = TRUE;
+ remoteHost = TQString::null;
+ tqdeviceName = TQString::null;
+ } else {
+ // syntax error? ignore.
+ }
+ } while ( !ts.atEnd() );
+}
+
+
+#ifndef TQT_NO_CUPS
+#include <cups/cups.h>
+
+static char * parseCupsOutput( TQListView * printers )
+{
+ char * defaultPrinter = 0;
+ int nd;
+ cups_dest_t * d;
+ TQLibrary lib( "cups" );
+ typedef int (*CupsGetDests)(cups_dest_t **dests);
+ CupsGetDests _cupsGetDests = (CupsGetDests)lib.resolve( "cupsGetDests" );
+ if ( _cupsGetDests ) {
+ nd = _cupsGetDests( &d );
+ if ( nd < 1 )
+ return 0;
+
+ int n = 0;
+ while ( n < nd ) {
+ perhapsAddPrinter( printers, d[n].name,
+ TQPrintDialog::tr("Unknown Location"), 0 );
+ if ( d[n].is_default && !defaultPrinter )
+ defaultPrinter = qstrdup( d[n].instance );
+ n++;
+ }
+ }
+ return defaultPrinter;
+}
+#endif
+
+static TQPrintDialog * globalPrintDialog = 0;
+
+static void qpd_cleanup_globaldialog()
+{
+ if ( globalPrintDialog != 0 )
+ delete globalPrintDialog;
+ globalPrintDialog = 0;
+}
+
+/*!
+ \class TQPrintDialog tqprintdialog.h
+
+ \brief The TQPrintDialog class provides a dialog for specifying
+ the printer's configuration.
+
+ \internal
+
+ \warning The use of this class is not recommended since it is not
+ present on all platforms; use TQPrinter::setup() instead.
+
+ \omit
+
+ (ingroup dialogs)
+
+ THIS DOCUMENTATION IS Not Revised. It must be revised before
+ becoming public API.
+
+ It encompasses both the sort of details needed for doing a simple
+ print-out and some print configuration setup.
+
+ The easiest way to use the class is through the static
+ function getPrinterSetup(). You can also subclass the TQPrintDialog
+ and add some custom buttons with addButton() to extend the
+ functionality of the print dialog.
+
+ <img src="qprintdlg-m.png"><br clear=all>
+ The printer dialog, on a large screen, in Motif style.
+*/
+
+
+/*! Constructs a new modal printer dialog that configures \a prn and is a
+ child of \a tqparent named \a name.
+*/
+
+TQPrintDialog::TQPrintDialog( TQPrinter *prn, TQWidget *tqparent, const char *name )
+ : TQDialog( tqparent, name, TRUE )
+{
+ d = new TQPrintDialogPrivate;
+ d->numCopies = 1;
+
+ TQBoxLayout * tll = new TQBoxLayout( this, TQBoxLayout::Down, 12, 0 );
+
+ // destination
+ TQGroupBox * g;
+ g = setupDestination();
+ tll->addWidget( g, 1 );
+
+ tll->addSpacing( 12 );
+
+ // printer and paper settings
+ TQBoxLayout * lay = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ tll->addLayout( lay );
+
+ g = setupPrinterSettings();
+ lay->addWidget( g, 1 );
+
+ lay->addSpacing( 12 );
+
+ g = setupPaper();
+ lay->addWidget( g );
+
+ tll->addSpacing( 12 );
+
+ // options
+ g = setupOptions();
+ tll->addWidget( g );
+ tll->addSpacing( 12 );
+
+ TQBoxLayout *l = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ d->customLayout = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ tll->addLayout( l );
+ l->addLayout( d->customLayout );
+ l->addStretch();
+ tll->addSpacing( 12 );
+
+ // buttons
+ TQBoxLayout *horiz = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ tll->addLayout( horiz );
+
+ bool rightalign =
+ bool(tqstyle().tqstyleHint(TQStyle::SH_PrintDialog_RightAlignButtons, this));
+
+ if (rightalign)
+ horiz->addStretch( 1 );
+
+ d->ok = new TQPushButton( this, "ok" );
+ d->ok->setText( tr("OK") );
+ d->ok->setDefault( TRUE );
+ horiz->addWidget( d->ok );
+ if (! rightalign)
+ horiz->addStretch( 1 );
+ horiz->addSpacing( 6 );
+
+ TQPushButton * cancel = new TQPushButton( this, "cancel" );
+ cancel->setText( tr("Cancel") );
+ horiz->addWidget( cancel );
+
+ TQSize s1 = d->ok->tqsizeHint();
+ TQSize s2 = cancel->tqsizeHint();
+ s1 = TQSize( TQMAX(s1.width(), s2.width()),
+ TQMAX(s1.height(), s2.height()) );
+
+ d->ok->setFixedSize( s1 );
+ cancel->setFixedSize( s1 );
+
+ tll->activate();
+
+ connect( d->ok, TQT_SIGNAL(clicked()), TQT_SLOT(okClicked()) );
+ connect( cancel, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) );
+
+ TQSize ms( tqminimumSize() );
+ TQSize ss( TQApplication::desktop()->screenGeometry( pos() ).size() );
+ if ( ms.height() < 512 && ss.height() >= 600 )
+ ms.setHeight( 512 );
+ else if ( ms.height() < 460 && ss.height() >= 480 )
+ ms.setHeight( 460 );
+ resize( ms );
+
+ setPrinter( prn, TRUE );
+ d->printers->setFocus();
+}
+
+
+/*! Destroys the object and frees any allocated resources. Does not
+ delete the associated TQPrinter object.
+*/
+
+TQPrintDialog::~TQPrintDialog()
+{
+ if ( this == globalPrintDialog )
+ globalPrintDialog = 0;
+ delete d;
+}
+
+/*!
+ This method allows you to specify a global print dialog, given in \a
+ pd, that will be used instead of the default dialog provided by TQt.
+
+ This is useful, since there are many different printing systems on
+ Unix, and we cannot support all of them. Calling this method before
+ using a printer for the first time allows you to set up your own
+ print dialog.
+
+ \sa setupPrinters()
+*/
+void TQPrintDialog::setGlobalPrintDialog( TQPrintDialog *pd )
+{
+ TQPrintDialog *oldPd = globalPrintDialog;
+ globalPrintDialog = pd;
+ if ( oldPd )
+ delete oldPd;
+ else
+ qAddPostRoutine( qpd_cleanup_globaldialog );
+ globalPrintDialog->adjustSize();
+}
+
+TQGroupBox * TQPrintDialog::setupPrinterSettings()
+{
+ TQGroupBox * g = new TQGroupBox( 1, Qt::Horizontal, tr( "Printer settings"),
+ this, "settings group box" );
+
+ d->colorMode = new TQButtonGroup( this );
+ d->colorMode->hide();
+ connect( d->colorMode, TQT_SIGNAL(clicked(int)),
+ this, TQT_SLOT(colorModeSelected(int)) );
+
+ TQRadioButton *rb;
+ rb = new TQRadioButton( tr( "Print in color if available" ),
+ g, "color" );
+ d->colorMode->insert( rb, TQPrinter::Color );
+ rb->setChecked( TRUE );
+
+ rb = new TQRadioButton( tr("Print in grayscale"),
+ g, "graysacle" );
+ d->colorMode->insert( rb, TQPrinter::GrayScale );
+
+ return g;
+}
+
+TQGroupBox * TQPrintDialog::setupDestination()
+{
+ TQGroupBox * g = new TQGroupBox( 0, Qt::Horizontal, tr( "Print destination"),
+ this, "destination group box" );
+
+ TQBoxLayout * tll = new TQBoxLayout( g->tqlayout(), TQBoxLayout::Down );
+
+ d->printerOrFile = new TQButtonGroup( this );
+ d->printerOrFile->hide();
+ connect( d->printerOrFile, TQT_SIGNAL(clicked(int)),
+ this, TQT_SLOT(printerOrFileSelected(int)) );
+
+ // printer radio button, list
+ TQRadioButton * rb = new TQRadioButton( tr( "Print to printer:" ), g,
+ "printer" );
+ tll->addWidget( rb );
+ d->printerOrFile->insert( rb, 0 );
+ rb->setChecked( TRUE );
+ d->outputToFile = FALSE;
+
+ TQBoxLayout * horiz = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ tll->addLayout( horiz, 3 );
+ horiz->addSpacing( 19 );
+
+ d->printers = new TQListView( g, "list of printers" );
+ d->printers->setAllColumnsShowFocus( TRUE );
+ d->printers->addColumn( tr("Printer"), 125 );
+ d->printers->addColumn( tr("Host"), 125 );
+ d->printers->addColumn( tr("Comment"), 150 );
+
+#if defined(TQ_OS_UNIX)
+ char * etcLpDefault = 0;
+
+#ifndef TQT_NO_CUPS
+ etcLpDefault = parseCupsOutput( d->printers );
+#endif
+ if ( d->printers->childCount() == 0 ) {
+ // we only use other schemes when cups fails.
+
+ parsePrintcap( d->printers, TQString::tqfromLatin1("/etc/printcap") );
+ parseEtcLpMember( d->printers );
+ parseSpoolInterface( d->printers );
+ parseQconfig( d->printers );
+ if ( addPrinterHook )
+ (*addPrinterHook)( d->printers );
+
+ TQFileInfo f;
+ f.setFile( TQString::tqfromLatin1("/etc/lp/printers") );
+ if ( f.isDir() ) {
+ parseEtcLpPrinters( d->printers );
+ TQFile def( TQString::tqfromLatin1("/etc/lp/default") );
+ if ( def.open( IO_ReadOnly ) ) {
+ if ( etcLpDefault )
+ delete[] etcLpDefault;
+ etcLpDefault = new char[1025];
+ def.readLine( etcLpDefault, 1024 );
+ char * p = etcLpDefault;
+ while ( p && *p ) {
+ if ( !isprint((uchar) *p) || isspace((uchar) *p) )
+ *p = 0;
+ else
+ p++;
+ }
+ }
+ }
+
+ char * def = 0;
+ f.setFile( TQString::tqfromLatin1("/etc/nsswitch.conf") );
+ if ( f.isFile() ) {
+ def = parseNsswitchConf( d->printers );
+ } else {
+ f.setFile( TQString::tqfromLatin1("/etc/printers.conf") );
+ if ( f.isFile() )
+ def = parsePrintersConf( d->printers );
+ }
+
+ if ( def ) {
+ if ( etcLpDefault )
+ delete[] etcLpDefault;
+ etcLpDefault = def;
+ }
+ }
+
+ // all printers hopefully known. try to tqfind a good default
+ TQString dollarPrinter;
+ {
+ const char * t = getenv( "PRINTER" );
+ if ( !t || !*t )
+ t = getenv( "LPDEST" );
+ dollarPrinter = TQString::tqfromLatin1( t );
+ if ( !dollarPrinter.isEmpty() )
+ perhapsAddPrinter( d->printers, dollarPrinter,
+ TQPrintDialog::tr("unknown"),
+ TQString::tqfromLatin1("") );
+ }
+ int quality = 0;
+
+ // bang the best default into the listview
+ const TQListViewItem * lvi = d->printers->firstChild();
+ d->printers->setCurrentItem( (TQListViewItem *)lvi );
+ while ( lvi ) {
+ TQRegExp ps( TQString::tqfromLatin1("[^a-z]ps(?:[^a-z]|$)") );
+ TQRegExp lp( TQString::tqfromLatin1("[^a-z]lp(?:[^a-z]|$)") );
+
+ if ( quality < 4 && lvi->text(0) == dollarPrinter ) {
+ d->printers->setCurrentItem( (TQListViewItem *)lvi );
+ quality = 4;
+ } else if ( quality < 3 && etcLpDefault &&
+ lvi->text(0) == TQString::tqfromLatin1(etcLpDefault) ) {
+ d->printers->setCurrentItem( (TQListViewItem *)lvi );
+ quality = 3;
+ } else if ( quality < 2 &&
+ ( lvi->text(0) == TQString::tqfromLatin1("ps") ||
+ ps.search(lvi->text(2)) != -1 ) ) {
+ d->printers->setCurrentItem( (TQListViewItem *)lvi );
+ quality = 2;
+ } else if ( quality < 1 &&
+ ( lvi->text(0) == TQString::tqfromLatin1("lp") ||
+ lp.search(lvi->text(2)) > -1 ) ) {
+ d->printers->setCurrentItem( (TQListViewItem *)lvi );
+ quality = 1;
+ }
+ lvi = lvi->nextSibling();
+ }
+
+ if ( d->printers->currentItem() )
+ d->printers->setSelected( d->printers->currentItem(), TRUE );
+
+ if ( etcLpDefault ) // Avoid purify complaint
+ delete[] etcLpDefault;
+#endif
+
+ int h = fontMetrics().height();
+ if ( d->printers->firstChild() )
+ h = d->printers->firstChild()->height();
+ d->printers->setMinimumSize( d->printers->tqsizeHint().width(),
+ d->printers->header()->height() +
+ 3 * h );
+ horiz->addWidget( d->printers, 3 );
+
+ tll->addSpacing( 6 );
+
+ // file radio button, edit/browse
+ d->printToFileButton = new TQRadioButton( tr( "Print to file:" ), g, "file" );
+ tll->addWidget( d->printToFileButton );
+ d->printerOrFile->insert( d->printToFileButton, 1 );
+
+ horiz = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ tll->addLayout( horiz );
+ horiz->addSpacing( 19 );
+
+ d->fileName = new TQLineEdit( g, "file name" );
+ connect( d->fileName, TQT_SIGNAL( textChanged(const TQString&) ),
+ this, TQT_SLOT( fileNameEditChanged(const TQString&) ) );
+ horiz->addWidget( d->fileName, 1 );
+ horiz->addSpacing( 6 );
+ d->browse = new TQPushButton( tr("Browse..."), g, "browse files" );
+ d->browse->setAutoDefault( FALSE );
+#ifdef TQT_NO_FILEDIALOG
+ d->browse->setEnabled( FALSE );
+#endif
+ connect( d->browse, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(browseClicked()) );
+ horiz->addWidget( d->browse );
+
+ d->fileName->setEnabled( FALSE );
+ d->browse->setEnabled( FALSE );
+
+ tll->activate();
+
+ return g;
+}
+
+
+TQGroupBox * TQPrintDialog::setupOptions()
+{
+ TQGroupBox * g = new TQGroupBox( 0, Qt::Horizontal, tr( "Options"),
+ this, "options group box" );
+
+ TQBoxLayout * tll = new TQBoxLayout( g->tqlayout(), TQBoxLayout::Down );
+
+ TQBoxLayout *lay = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ tll->addLayout( lay );
+
+ tll = new TQBoxLayout( lay, TQBoxLayout::Down );
+
+ d->printRange = new TQButtonGroup( this );
+ d->printRange->hide();
+ connect( d->printRange, TQT_SIGNAL(clicked(int)),
+ this, TQT_SLOT(printRangeSelected(int)) );
+
+ d->pageOrder = new TQButtonGroup( this );
+ d->pageOrder->hide();
+ connect( d->pageOrder, TQT_SIGNAL(clicked(int)),
+ this, TQT_SLOT(pageOrderSelected(int)) );
+
+ d->printAllButton = new TQRadioButton( tr("Print all"), g, "print all" );
+ d->printRange->insert( d->printAllButton, 0 );
+ tll->addWidget( d->printAllButton );
+
+ d->printSelectionButton = new TQRadioButton( tr("Print selection"),
+ g, "print selection" );
+ d->printRange->insert( d->printSelectionButton, 1 );
+ tll->addWidget( d->printSelectionButton );
+
+ d->printRangeButton = new TQRadioButton( tr("Print range"),
+ g, "print range" );
+ d->printRange->insert( d->printRangeButton, 2 );
+ tll->addWidget( d->printRangeButton );
+
+ TQBoxLayout * horiz = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ tll->addLayout( horiz );
+
+ d->firstPageLabel = new TQLabel( tr("From page:"), g, "first page" );
+ horiz->addSpacing( 19 );
+ horiz->addWidget( d->firstPageLabel );
+
+ d->firstPage = new TQPrintDialogSpinBox( 1, 9999, 1, g, "first page" );
+ d->firstPage->setValue( 1 );
+ horiz->addWidget( d->firstPage, 1 );
+ connect( d->firstPage, TQT_SIGNAL(valueChanged(int)),
+ this, TQT_SLOT(setFirstPage(int)) );
+
+ horiz = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ tll->addLayout( horiz );
+
+ d->lastPageLabel = new TQLabel( tr("To page:"), g, "last page" );
+ horiz->addSpacing( 19 );
+ horiz->addWidget( d->lastPageLabel );
+
+ d->lastPage = new TQPrintDialogSpinBox( 1, 9999, 1, g, "last page" );
+ d->lastPage->setValue( 9999 );
+ horiz->addWidget( d->lastPage, 1 );
+ connect( d->lastPage, TQT_SIGNAL(valueChanged(int)),
+ this, TQT_SLOT(setLastPage(int)) );
+
+ lay->addSpacing( 25 );
+ tll = new TQBoxLayout( lay, TQBoxLayout::Down );
+
+ // print order
+ TQRadioButton * rb = new TQRadioButton( tr("Print first page first"),
+ g, "first page first" );
+ tll->addWidget( rb );
+ d->pageOrder->insert( rb, TQPrinter::FirstPageFirst );
+ rb->setChecked( TRUE );
+
+ rb = new TQRadioButton( tr("Print last page first"),
+ g, "last page first" );
+ tll->addWidget( rb );
+ d->pageOrder->insert( rb, TQPrinter::LastPageFirst );
+
+ tll->addStretch();
+
+ // copies
+
+ horiz = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ tll->addLayout( horiz );
+
+ TQLabel * l = new TQLabel( tr("Number of copies:"), g, "Number of copies" );
+ horiz->addWidget( l );
+
+ d->copies = new TQPrintDialogSpinBox( 1, 99, 1, g, "copies" );
+ d->copies->setValue( 1 );
+ horiz->addWidget( d->copies, 1 );
+ connect( d->copies, TQT_SIGNAL(valueChanged(int)),
+ this, TQT_SLOT(setNumCopies(int)) );
+
+ TQSize s = d->firstPageLabel->tqsizeHint()
+ .expandedTo( d->lastPageLabel->tqsizeHint() )
+ .expandedTo( l->tqsizeHint() );
+ d->firstPageLabel->setMinimumSize( s );
+ d->lastPageLabel->setMinimumSize( s );
+ l->setMinimumSize( s.width() + 19, s.height() );
+
+ tll->activate();
+
+ return g;
+}
+
+
+void isc( TQPrintDialogPrivate * d,
+ const TQString & text,
+ TQPrinter::PageSize ps )
+{
+ if ( d && text && ps < TQPrinter::NPageSize ) {
+ d->sizeCombo->insertItem( text, -1 );
+ int index = d->sizeCombo->count()-1;
+ if ( index >= 0 && index < TQPrinter::NPageSize )
+ d->indexToPageSize[index] = ps;
+ }
+}
+
+TQGroupBox * TQPrintDialog::setupPaper()
+{
+ TQGroupBox * g = new TQGroupBox( 1, Qt::Horizontal, tr( "Paper format"),
+ this, "Paper format" );
+ d->pageSize = TQPrinter::A4;
+
+ // page orientation
+ d->orientationCombo = new TQComboBox( FALSE, g );
+ d->orientationCombo->insertItem( tqtr( "Portrait" ), -1 );
+ d->orientationCombo->insertItem( tqtr( "Landscape" ), -1 );
+
+ d->orientation = TQPrinter::Portrait;
+
+ g->addSpace( 8 );
+
+ connect( d->orientationCombo, TQT_SIGNAL( activated(int) ),
+ this, TQT_SLOT( orientSelected(int) ) );
+
+ // paper size
+ d->sizeCombo = new TQComboBox( FALSE, g );
+
+ int n;
+ for( n=0; n<TQPrinter::NPageSize; n++ )
+ d->indexToPageSize[n] = TQPrinter::A4;
+
+ isc( d, tr( "A0 (841 x 1189 mm)" ), TQPrinter::A0 );
+ isc( d, tr( "A1 (594 x 841 mm)" ), TQPrinter::A1 );
+ isc( d, tr( "A2 (420 x 594 mm)" ), TQPrinter::A2 );
+ isc( d, tr( "A3 (297 x 420 mm)" ), TQPrinter::A3 );
+ isc( d, tr( "A4 (210x297 mm, 8.26x11.7 inches)" ), TQPrinter::A4 );
+ isc( d, tr( "A5 (148 x 210 mm)" ), TQPrinter::A5 );
+ isc( d, tr( "A6 (105 x 148 mm)" ), TQPrinter::A6 );
+ isc( d, tr( "A7 (74 x 105 mm)" ), TQPrinter::A7 );
+ isc( d, tr( "A8 (52 x 74 mm)" ), TQPrinter::A8 );
+ isc( d, tr( "A9 (37 x 52 mm)" ), TQPrinter::A9 );
+ isc( d, tr( "B0 (1000 x 1414 mm)" ), TQPrinter::B0 );
+ isc( d, tr( "B1 (707 x 1000 mm)" ), TQPrinter::B1 );
+ isc( d, tr( "B2 (500 x 707 mm)" ), TQPrinter::B2 );
+ isc( d, tr( "B3 (353 x 500 mm)" ), TQPrinter::B3 );
+ isc( d, tr( "B4 (250 x 353 mm)" ), TQPrinter::B4 );
+ isc( d, tr( "B5 (176 x 250 mm, 6.93x9.84 inches)" ), TQPrinter::B5 );
+ isc( d, tr( "B6 (125 x 176 mm)" ), TQPrinter::B6 );
+ isc( d, tr( "B7 (88 x 125 mm)" ), TQPrinter::B7 );
+ isc( d, tr( "B8 (62 x 88 mm)" ), TQPrinter::B8 );
+ isc( d, tr( "B9 (44 x 62 mm)" ), TQPrinter::B9 );
+ isc( d, tr( "B10 (31 x 44 mm)" ), TQPrinter::B10 );
+ isc( d, tr( "C5E (163 x 229 mm)" ), TQPrinter::C5E );
+ isc( d, tr( "DLE (110 x 220 mm)" ), TQPrinter::DLE );
+ isc( d, tr( "Executive (7.5x10 inches, 191x254 mm)" ), TQPrinter::Executive );
+ isc( d, tr( "Folio (210 x 330 mm)" ), TQPrinter::Folio );
+ isc( d, tr( "Ledger (432 x 279 mm)" ), TQPrinter::Ledger );
+ isc( d, tr( "Legal (8.5x14 inches, 216x356 mm)" ), TQPrinter::Legal );
+ isc( d, tr( "Letter (8.5x11 inches, 216x279 mm)" ), TQPrinter::Letter );
+ isc( d, tr( "Tabloid (279 x 432 mm)" ), TQPrinter::Tabloid );
+ isc( d, tr( "US Common #10 Envelope (105 x 241 mm)" ), TQPrinter::Comm10E );
+
+ connect( d->sizeCombo, TQT_SIGNAL( activated(int) ),
+ this, TQT_SLOT( paperSizeSelected(int) ) );
+
+ return g;
+}
+
+
+/*!
+ Display a dialog and allow the user to configure the TQPrinter \a
+ p for an optional widget \a w. Returns TRUE if the user clicks OK or
+ presses Enter, FALSE if the user clicks Cancel or presses Esc.
+
+ getPrinterSetup() remembers the settings and provides the same
+ settings the next time the dialog is shown.
+*/
+
+bool TQPrintDialog::getPrinterSetup( TQPrinter * p, TQWidget* w )
+{
+ if ( !globalPrintDialog ) {
+ globalPrintDialog = new TQPrintDialog( 0, 0, "global print dialog" );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ globalPrintDialog->setCaption( TQPrintDialog::tr( "Setup Printer" ) );
+#endif
+ qAddPostRoutine( qpd_cleanup_globaldialog );
+ globalPrintDialog->setPrinter( p, TRUE );
+ globalPrintDialog->adjustSize();
+ } else {
+ globalPrintDialog->setPrinter( p, TRUE );
+ }
+ globalPrintDialog->adjustPosition( w );
+ #ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( w ) {
+ const TQPixmap *pm = w->icon();
+ if ( pm && !pm->isNull() )
+ globalPrintDialog->setIcon( *pm );
+ else {
+ w = w ? w->tqtopLevelWidget() : 0;
+ pm = w ? w->icon() : 0;
+ if ( pm && !pm->isNull() )
+ globalPrintDialog->setIcon( *pm );
+ }
+ }
+#endif
+ bool r = globalPrintDialog->exec() == TQDialog::Accepted;
+ globalPrintDialog->setPrinter( 0 );
+ return r;
+}
+
+
+void TQPrintDialog::printerOrFileSelected( int id )
+{
+ d->outputToFile = id ? TRUE : FALSE;
+ if ( d->outputToFile ) {
+ d->ok->setEnabled( TRUE );
+ fileNameEditChanged( d->fileName->text() );
+ if ( !d->fileName->edited() && d->fileName->text().isEmpty() ) {
+ TQString home = TQString::tqfromLatin1( ::getenv( "HOME" ) );
+ TQString cur = TQDir::currentDirPath();
+ if ( home.at(home.length()-1) != '/' )
+ home += '/';
+ if ( cur.at(cur.length()-1) != '/' )
+ cur += '/';
+ if ( cur.left( home.length() ) != home )
+ cur = home;
+#ifdef TQ_WS_X11
+ cur += "print.ps";
+#endif
+ d->fileName->setText( cur );
+ d->fileName->setCursorPosition( cur.length() );
+ d->fileName->selectAll();
+ }
+ d->browse->setEnabled( TRUE );
+ d->fileName->setEnabled( TRUE );
+ d->fileName->setFocus();
+ d->printers->setEnabled( FALSE );
+ } else {
+ d->ok->setEnabled( d->printers->childCount() != 0 );
+ d->printers->setEnabled( TRUE );
+ if ( d->fileName->hasFocus() || d->browse->hasFocus() )
+ d->printers->setFocus();
+ d->browse->setEnabled( FALSE );
+ d->fileName->setEnabled( FALSE );
+ }
+}
+
+
+void TQPrintDialog::landscapeSelected( int id )
+{
+ d->orientation = (TQPrinter::Orientation)id;
+}
+
+
+void TQPrintDialog::paperSizeSelected( int id )
+{
+ if ( id < TQPrinter::NPageSize )
+ d->pageSize = TQPrinter::PageSize( d->indexToPageSize[id] );
+}
+
+
+void TQPrintDialog::orientSelected( int id )
+{
+ d->orientation = (TQPrinter::Orientation)id;
+}
+
+
+void TQPrintDialog::pageOrderSelected( int id )
+{
+ d->pageOrder2 = (TQPrinter::PageOrder)id;
+}
+
+
+void TQPrintDialog::setNumCopies( int copies )
+{
+ d->numCopies = copies;
+}
+
+
+void TQPrintDialog::browseClicked()
+{
+#ifndef TQT_NO_FILEDIALOG
+ TQString fn = TQFileDialog::getSaveFileName( d->fileName->text(), tr( "PostScript Files (*.ps);;All Files (*)" ), this );
+ if ( !fn.isNull() )
+ d->fileName->setText( fn );
+#endif
+}
+
+
+void TQPrintDialog::okClicked()
+{
+ d->lastPage->interpretText();
+ d->firstPage->interpretText();
+ d->copies->interpretText();
+ if ( d->outputToFile ) {
+ d->printer->setOutputToFile( TRUE );
+ d->printer->setOutputFileName( d->fileName->text() );
+ } else {
+ d->printer->setOutputToFile( FALSE );
+ TQListViewItem * l = d->printers->currentItem();
+ if ( l )
+ d->printer->setPrinterName( l->text( 0 ) );
+ }
+
+ d->printer->setOrientation( d->orientation );
+ d->printer->setPageSize( d->pageSize );
+ d->printer->setPageOrder( d->pageOrder2 );
+ d->printer->setColorMode( d->colorMode2 );
+ d->printer->setNumCopies( d->numCopies );
+ if ( d->printAllButton->isChecked() ) {
+ d->printer->setPrintRange(TQPrinter::AllPages);
+ d->printer->setFromTo( d->printer->minPage(), d->printer->maxPage() );
+ } else {
+ if (d->printSelectionButton->isChecked())
+ d->printer->setPrintRange(TQPrinter::Selection);
+ else
+ d->printer->setPrintRange(TQPrinter::PageRange);
+ d->printer->setFromTo( d->firstPage->value(), d->lastPage->value() );
+ }
+
+ accept();
+}
+
+
+void TQPrintDialog::printRangeSelected( int id )
+{
+ bool enable = id == 2 ? TRUE : FALSE;
+ d->firstPage->setEnabled( enable );
+ d->lastPage->setEnabled( enable );
+ d->firstPageLabel->setEnabled( enable );
+ d->lastPageLabel->setEnabled( enable );
+}
+
+
+void TQPrintDialog::setFirstPage( int fp )
+{
+ if ( d->printer )
+ d->lastPage->setRange( fp, TQMAX(fp, TQPrintDialog::d->printer->maxPage()) );
+}
+
+
+void TQPrintDialog::setLastPage( int lp )
+{
+ if ( d->printer )
+ d->firstPage->setRange( TQMIN(lp, TQPrintDialog::d->printer->minPage()), lp );
+}
+
+
+/*!
+ Sets this dialog to configure printer \a p, or no printer if \a p
+ is null. If \a pickUpSettings is TRUE, the dialog reads most of
+ its settings from \a p. If \a pickUpSettings is FALSE (the
+ default) the dialog keeps its old settings.
+*/
+
+void TQPrintDialog::setPrinter( TQPrinter * p, bool pickUpSettings )
+{
+ d->printer = p;
+
+ if ( p && pickUpSettings ) {
+ // top to botton in the old dialog.
+ // printer or file
+ d->printerOrFile->setButton( p->outputToFile() );
+ printerOrFileSelected( p->outputToFile() );
+
+ // printer name
+ if ( !!TQT_TQSTRING(p->printerName()) ) {
+ TQListViewItem * i = d->printers->firstChild();
+ while ( i && i->text( 0 ) != p->printerName() )
+ i = i->nextSibling();
+ if ( i ) {
+ d->printers->setSelected( i, TRUE );
+ d->ok->setEnabled( TRUE );
+ } else if ( d->fileName->text().isEmpty() ) {
+ d->ok->setEnabled( d->printers->childCount() != 0 );
+ }
+ }
+
+ // print command does not exist any more
+
+ // file name
+ d->printToFileButton->setEnabled( d->printer->isOptionEnabled( TQPrinter::PrintToFile ) );
+ d->fileName->setText( p->outputFileName() );
+
+ // orientation
+ d->orientationCombo->setCurrentItem( (int)p->orientation() );
+ orientSelected( p->orientation() );
+
+ // page size
+ int n = 0;
+ while ( n < TQPrinter::NPageSize &&
+ d->indexToPageSize[n] != p->pageSize() )
+ n++;
+ d->sizeCombo->setCurrentItem( n );
+ paperSizeSelected( n );
+
+ // New stuff (Options)
+
+ // page order
+ d->pageOrder->setButton( (int)p->pageOrder() );
+ pageOrderSelected( p->pageOrder() );
+
+ // color mode
+ d->colorMode->setButton( (int)p->colorMode() );
+ colorModeSelected( p->colorMode() );
+
+ // number of copies
+ d->copies->setValue( p->numCopies() );
+ setNumCopies( p->numCopies() );
+ }
+
+ if( p ) {
+ d->printAllButton->setEnabled( TRUE );
+ d->printSelectionButton
+ ->setEnabled( d->printer->isOptionEnabled( TQPrinter::PrintSelection ) );
+ d->printRangeButton
+ ->setEnabled( d->printer->isOptionEnabled( TQPrinter::PrintPageRange ) );
+
+ TQPrinter::PrintRange range = p->printRange();
+ switch ( range ) {
+ case TQPrinter::AllPages:
+ d->printAllButton->setChecked(TRUE);
+ printRangeSelected( d->printRange->id( d->printAllButton ) );
+ break;
+ case TQPrinter::Selection:
+ d->printSelectionButton->setChecked(TRUE);
+ printRangeSelected( d->printRange->id( d->printSelectionButton ) );
+ break;
+ case TQPrinter::PageRange:
+ d->printRangeButton->setChecked(TRUE);
+ printRangeSelected( d->printRange->id( d->printRangeButton ) );
+ break;
+ }
+ }
+
+ if ( p && p->maxPage() ) {
+ d->firstPage->setRange( p->minPage(), p->maxPage() );
+ d->lastPage->setRange( p->minPage(), p->maxPage() );
+ if ( p->fromPage() || p->toPage() ) {
+ setFirstPage( p->fromPage() );
+ setLastPage( p->toPage() );
+ d->firstPage->setValue(p->fromPage());
+ d->lastPage->setValue(p->toPage());
+ }
+ }
+}
+
+
+/*! Returns a pointer to the printer this dialog configures, or 0 if
+ this dialog does not operate on any printer. */
+
+TQPrinter * TQPrintDialog::printer() const
+{
+ return d->printer;
+}
+
+
+void TQPrintDialog::colorModeSelected( int id )
+{
+ d->colorMode2 = (TQPrinter::ColorMode)id;
+}
+
+/*!
+ Adds the button \a but to the tqlayout of the print dialog. The added
+ buttons are arranged from the left to the right below the
+ last groupbox of the printdialog.
+*/
+
+void TQPrintDialog::addButton( TQPushButton *but )
+{
+ d->customLayout->addWidget( but );
+}
+
+void TQPrintDialog::fileNameEditChanged( const TQString &text )
+{
+ if ( d->fileName->isEnabled() )
+ d->ok->setEnabled( !text.isEmpty() );
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/dialogs/tqprintdialog.h b/tqtinterface/qt4/src/dialogs/tqprintdialog.h
new file mode 100644
index 0000000..b1d8014
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqprintdialog.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Definition of print dialog.
+**
+** Created : 950829
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPRINTDIALOG_H
+#define TQPRINTDIALOG_H
+
+#ifndef TQT_H
+#include "tqdialog.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_PRINTDIALOG
+
+class TQGroupBox;
+class TQPrintDialogPrivate;
+class TQListView;
+
+class TQ_EXPORT TQPrintDialog : public TQDialog
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQPrintDialog( TQPrinter *, TQWidget* tqparent=0, const char* name=0 );
+ ~TQPrintDialog();
+
+ static bool getPrinterSetup( TQPrinter *, TQWidget* = 0 );
+ static void setGlobalPrintDialog( TQPrintDialog * );
+
+ void setPrinter( TQPrinter *, bool = FALSE );
+ TQPrinter * printer() const;
+
+ void addButton( TQPushButton *but );
+
+private Q_SLOTS:
+ void browseClicked();
+ void okClicked();
+
+ void printerOrFileSelected( int );
+ void landscapeSelected( int );
+ void paperSizeSelected( int );
+ void orientSelected( int );
+ void pageOrderSelected( int );
+ void colorModeSelected( int );
+ void setNumCopies( int );
+ void printRangeSelected( int );
+ void setFirstPage( int );
+ void setLastPage( int );
+
+ void fileNameEditChanged( const TQString &text );
+
+private:
+ TQPrintDialogPrivate *d;
+
+ TQGroupBox * setupDestination();
+ TQGroupBox * setupOptions();
+ TQGroupBox * setupPaper();
+ TQGroupBox * setupPrinterSettings();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQPrintDialog( const TQPrintDialog & );
+ TQPrintDialog &operator=( const TQPrintDialog & );
+#endif
+};
+
+#endif
+
+#endif // TQPRINTDIALOG_H
diff --git a/tqtinterface/qt4/src/dialogs/tqprogressdialog.cpp b/tqtinterface/qt4/src/dialogs/tqprogressdialog.cpp
new file mode 100644
index 0000000..74bf69f
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqprogressdialog.cpp
@@ -0,0 +1,826 @@
+/****************************************************************************
+**
+** Implementation of TQProgressDialog class
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqprogressdialog.h"
+
+#ifndef TQT_NO_PROGRESSDIALOG
+
+#include "tqaccel.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqdatetime.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+#include "tqpushbutton.h"
+#include "tqcursor.h"
+#include "tqtimer.h"
+#include <limits.h>
+
+// If the operation is expected to take this long (as predicted by
+// progress time), show the progress dialog.
+static const int defaultShowTime = 4000;
+// Wait at least this long before attempting to make a prediction.
+static const int minWaitTime = 50;
+
+// Various tqlayout values
+static const int margin_lr = 10;
+static const int margin_tb = 10;
+static const int spacing = 4;
+
+
+class TQProgressDialogData
+{
+public:
+ TQProgressDialogData( TQProgressDialog* that, TQWidget* tqparent,
+ const TQString& labelText,
+ int totalSteps ) :
+ creator( tqparent ),
+ label( new TQLabel(labelText,that,"label") ),
+ cancel( 0 ),
+ bar( new TQProgressBar(totalSteps,that,"bar") ),
+ shown_once( FALSE ),
+ cancellation_flag( FALSE ),
+ showTime( defaultShowTime )
+ {
+ label->tqsetAlignment(that->tqstyle().tqstyleHint(TQStyle::SH_ProgressDialog_TextLabelAlignment, that));
+ }
+
+ TQWidget *creator;
+ TQLabel *label;
+ TQPushButton *cancel;
+ TQProgressBar *bar;
+ bool shown_once;
+ bool cancellation_flag;
+ TQTime starttime;
+#ifndef TQT_NO_CURSOR
+ TQCursor parentCursor;
+#endif
+ int showTime;
+ bool autoClose;
+ bool autoReset;
+ bool forceHide;
+};
+
+
+/*!
+ \class TQProgressDialog tqprogressdialog.h
+ \brief The TQProgressDialog class provides feedback on the progress of a slow operation.
+ \ingroup dialogs
+ \mainclass
+
+ A progress dialog is used to give the user an indication of how long
+ an operation is going to take, and to demonstrate that the
+ application has not frozen. It can also give the user an opportunity
+ to abort the operation.
+
+ A common problem with progress dialogs is that it is difficult to know
+ when to use them; operations take different amounts of time on different
+ hardware. TQProgressDialog offers a solution to this problem:
+ it estimates the time the operation will take (based on time for
+ steps), and only shows itself if that estimate is beyond minimumDuration()
+ (4 seconds by default).
+
+ Use setTotalSteps() (or the constructor) to set the number of
+ "steps" in the operation and call setProgress() as the operation
+ progresses. The step value can be chosen arbitrarily. It can be the
+ number of files copied, the number of bytes received, the number of
+ iterations through the main loop of your algorithm, or some other
+ suitable unit. Progress starts at 0, and the progress dialog shows
+ that the operation has finished when you call setProgress() with
+ totalSteps() as its argument.
+
+ The dialog automatically resets and hides itself at the end of the
+ operation. Use setAutoReset() and setAutoClose() to change this
+ behavior.
+
+ There are two ways of using TQProgressDialog: modal and modeless.
+
+ Using a modal TQProgressDialog is simpler for the programmer, but you
+ must call TQApplication::processEvents() or
+ TQEventLoop::processEvents(ExcludeUserInput) to keep the event loop
+ running to ensure that the application doesn't freeze. Do the
+ operation in a loop, call \l setProgress() at intervals, and check
+ for cancellation with wasCanceled(). For example:
+\code
+TQProgressDialog progress( "Copying files...", "Abort Copy", numFiles,
+ this, "progress", TRUE );
+for ( int i = 0; i < numFiles; i++ ) {
+ progress.setProgress( i );
+ tqApp->processEvents();
+
+ if ( progress.wasCanceled() )
+ break;
+ //... copy one file
+}
+progress.setProgress( numFiles );
+\endcode
+
+ A modeless progress dialog is suitable for operations that take
+ place in the background, where the user is able to interact with the
+ application. Such operations are typically based on TQTimer (or
+ TQObject::timerEvent()), TQSocketNotifier, or TQUrlOperator; or performed
+ in a separate thread. A TQProgressBar in the status bar of your main window
+ is often an alternative to a modeless progress dialog.
+
+ You need to have an event loop to be running, connect the
+ canceled() signal to a slot that stops the operation, and call \l
+ setProgress() at intervals. For example:
+\code
+Operation::Operation( TQObject *tqparent = 0 )
+ : TQObject( tqparent ), steps( 0 )
+{
+ pd = new TQProgressDialog( "Operation in progress.", "Cancel", 100 );
+ connect( pd, TQT_SIGNAL(canceled()), this, TQT_SLOT(cancel()) );
+ t = new TQTimer( this );
+ connect( t, TQT_SIGNAL(timeout()), this, TQT_SLOT(perform()) );
+ t->start( 0 );
+}
+
+void Operation::perform()
+{
+ pd->setProgress( steps );
+ //... perform one percent of the operation
+ steps++;
+ if ( steps > pd->totalSteps() )
+ t->stop();
+}
+
+void Operation::cancel()
+{
+ t->stop();
+ //... cleanup
+}
+\endcode
+
+
+ In both modes the progress dialog may be customized by
+ replacing the child widgets with custom widgets by using setLabel(),
+ setBar(), and setCancelButton().
+ The functions setLabelText() and setCancelButtonText()
+ set the texts shown.
+
+ <img src=qprogdlg-m.png> <img src=qprogdlg-w.png>
+
+ \sa TQDialog TQProgressBar
+ \link guibooks.html#fowler GUI Design Handbook: Progress Indicator\endlink
+*/
+
+
+/*!
+ Returns the TQLabel currently being displayed above the progress bar.
+ This TQLabel is owned by the TQProgressDialog.
+
+ \sa setLabel()
+*/
+TQLabel *TQProgressDialog::label() const
+{
+ return d->label;
+}
+
+/*!
+ Returns the TQProgressBar currently being used to display progress.
+ This TQProgressBar is owned by the TQProgressDialog.
+
+ \sa setBar()
+*/
+TQProgressBar *TQProgressDialog::bar() const
+{
+ return d->bar;
+}
+
+
+/*!
+ Constructs a progress dialog.
+
+ Default settings:
+ \list
+ \i The label text is empty.
+ \i The cancel button text is (translated) "Cancel".
+ \i The total number of steps is 100.
+ \endlist
+
+ The \a creator argument is the widget to use as the dialog's tqparent.
+ The \a name, \a modal, and the widget flags, \a f, are
+ passed to the TQDialog::TQDialog() constructor. If \a modal is FALSE (the
+ default), you must have an event loop proceeding for any redrawing
+ of the dialog to occur. If \a modal is TRUE, the dialog ensures that
+ events are processed when needed.
+
+ \sa setLabelText(), setLabel(), setCancelButtonText(), setCancelButton(),
+ setTotalSteps()
+*/
+
+TQProgressDialog::TQProgressDialog( TQWidget *creator, const char *name,
+ bool modal, WFlags f )
+ : TQDialog( creator, name, modal, f)
+{
+ init( creator, TQString::tqfromLatin1(""), tr("Cancel"), 100 );
+}
+
+/*!
+ Constructs a progress dialog.
+
+ The \a labelText is text used to remind the user what is progressing.
+
+ The \a cancelButtonText is the text to display on the cancel button,
+ or 0 if no cancel button is to be shown.
+
+ The \a totalSteps is the total number of steps in the operation for
+ which this progress dialog shows progress. For example, if the
+ operation is to examine 50 files, this value would be 50. Before
+ examining the first file, call setProgress(0). As each file is
+ processed call setProgress(1), setProgress(2), etc., finally
+ calling setProgress(50) after examining the last file.
+
+ The \a creator argument is the widget to use as the dialog's tqparent.
+ The \a name, \a modal, and widget flags, \a f, are passed to the
+ TQDialog::TQDialog() constructor. If \a modal is FALSE (the default),
+ you will must have an event loop proceeding for any redrawing of
+ the dialog to occur. If \a modal is TRUE, the dialog ensures that
+ events are processed when needed.
+
+
+ \sa setLabelText(), setLabel(), setCancelButtonText(), setCancelButton(),
+ setTotalSteps()
+*/
+
+TQProgressDialog::TQProgressDialog( const TQString &labelText,
+ const TQString &cancelButtonText,
+ int totalSteps,
+ TQWidget *creator, const char *name,
+ bool modal, WFlags f )
+ : TQDialog( creator, name, modal, f)
+{
+ init( creator, labelText, cancelButtonText, totalSteps );
+}
+
+
+/*!
+ Destroys the progress dialog.
+*/
+
+TQProgressDialog::~TQProgressDialog()
+{
+#ifndef TQT_NO_CURSOR
+ if ( d->creator )
+ d->creator->setCursor( d->parentCursor );
+#endif
+ delete d;
+}
+
+void TQProgressDialog::init( TQWidget *creator,
+ const TQString& lbl, const TQString& canc,
+ int totstps)
+{
+ d = new TQProgressDialogData(this, creator, lbl, totstps);
+ d->autoClose = TRUE;
+ d->autoReset = TRUE;
+ d->forceHide = FALSE;
+ setCancelButtonText( canc );
+ connect( this, TQT_SIGNAL(canceled()), this, TQT_SIGNAL(cancelled()) );
+ connect( this, TQT_SIGNAL(canceled()), this, TQT_SLOT(cancel()) );
+ forceTimer = new TQTimer( this );
+ connect( forceTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(forceShow()) );
+ tqlayout();
+}
+
+/*!
+ \fn void TQProgressDialog::canceled()
+
+ This signal is emitted when the cancel button is clicked.
+ It is connected to the cancel() slot by default.
+
+ \sa wasCanceled()
+*/
+
+/*!
+ \fn void TQProgressDialog::cancelled()
+
+ \obsolete
+
+ Use canceled() instead.
+*/
+
+
+/*!
+ Sets the label to \a label. The progress dialog resizes to fit. The
+ label becomes owned by the progress dialog and will be deleted when
+ necessary, so do not pass the address of an object on the stack.
+
+ \sa setLabelText()
+*/
+
+void TQProgressDialog::setLabel( TQLabel *label )
+{
+ delete d->label;
+ d->label = label;
+ if (label) {
+ if ( label->parentWidget() == this ) {
+ label->hide(); // until we resize
+ } else {
+ label->reparent( this, 0, TQPoint(0,0), FALSE );
+ }
+ }
+ int w = TQMAX( isVisible() ? width() : 0, tqsizeHint().width() );
+ int h = TQMAX( isVisible() ? height() : 0, tqsizeHint().height() );
+ resize( w, h );
+ if (label)
+ label->show();
+}
+
+
+/*!
+ \property TQProgressDialog::labelText
+ \brief the label's text
+
+ The default text is TQString::null.
+*/
+
+TQString TQProgressDialog::labelText() const
+{
+ if ( label() )
+ return label()->text();
+ return TQString::null;
+}
+
+void TQProgressDialog::setLabelText( const TQString &text )
+{
+ if ( label() ) {
+ label()->setText( text );
+ int w = TQMAX( isVisible() ? width() : 0, tqsizeHint().width() );
+ int h = TQMAX( isVisible() ? height() : 0, tqsizeHint().height() );
+ resize( w, h );
+ }
+}
+
+
+/*!
+ Sets the cancel button to the push button, \a cancelButton. The
+ progress dialog takes ownership of this button which will be deleted
+ when necessary, so do not pass the address of an object that is on
+ the stack, i.e. use new() to create the button.
+
+ \sa setCancelButtonText()
+*/
+
+void TQProgressDialog::setCancelButton( TQPushButton *cancelButton )
+{
+ delete d->cancel;
+ d->cancel = cancelButton;
+ if (cancelButton) {
+ if ( cancelButton->parentWidget() == this ) {
+ cancelButton->hide(); // until we resize
+ } else {
+ cancelButton->reparent( this, 0, TQPoint(0,0), FALSE );
+ }
+ connect( d->cancel, TQT_SIGNAL(clicked()), this, TQT_SIGNAL(canceled()) );
+#ifndef TQT_NO_ACCEL
+ TQAccel *accel = new TQAccel( this );
+ accel->connectItem( accel->insertItem(Key_Escape),
+ d->cancel, TQT_SIGNAL(clicked()) );
+#endif
+ }
+ int w = TQMAX( isVisible() ? width() : 0, tqsizeHint().width() );
+ int h = TQMAX( isVisible() ? height() : 0, tqsizeHint().height() );
+ resize( w, h );
+ if (cancelButton)
+ cancelButton->show();
+}
+
+/*!
+ Sets the cancel button's text to \a cancelButtonText.
+ \sa setCancelButton()
+*/
+
+void TQProgressDialog::setCancelButtonText( const TQString &cancelButtonText )
+{
+ if ( !cancelButtonText.isNull() ) {
+ if ( d->cancel )
+ d->cancel->setText(cancelButtonText);
+ else
+ setCancelButton(new TQPushButton(cancelButtonText, this, "cancel"));
+ } else {
+ setCancelButton(0);
+ }
+ int w = TQMAX( isVisible() ? width() : 0, tqsizeHint().width() );
+ int h = TQMAX( isVisible() ? height() : 0, tqsizeHint().height() );
+ resize( w, h );
+}
+
+
+/*!
+ Sets the progress bar widget to \a bar. The progress dialog resizes to
+ fit. The progress dialog takes ownership of the progress \a bar which
+ will be deleted when necessary, so do not use a progress bar
+ allocated on the stack.
+*/
+
+void TQProgressDialog::setBar( TQProgressBar *bar )
+{
+ if ( progress() > 0 ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQProgrssDialog::setBar: Cannot set a new progress bar "
+ "while the old one is active" );
+#endif
+ }
+ delete d->bar;
+ d->bar = bar;
+ int w = TQMAX( isVisible() ? width() : 0, tqsizeHint().width() );
+ int h = TQMAX( isVisible() ? height() : 0, tqsizeHint().height() );
+ resize( w, h );
+}
+
+
+/*!
+ \property TQProgressDialog::wasCancelled
+ \brief whether the dialog was canceled
+
+ \obsolete
+
+ Use \l wasCanceled instead.
+*/
+
+/*!
+ \property TQProgressDialog::wasCanceled
+ \brief whether the dialog was canceled
+
+ \sa setProgress()
+*/
+
+bool TQProgressDialog::wasCancelled() const
+{
+ return d->cancellation_flag;
+}
+
+
+/*!
+ \property TQProgressDialog::totalSteps
+ \brief the total number of steps
+
+ The default is 0.
+*/
+
+int TQProgressDialog::totalSteps() const
+{
+ if ( d && d->bar )
+ return bar()->totalSteps();
+ return 0;
+}
+
+void TQProgressDialog::setTotalSteps( int totalSteps )
+{
+ bar()->setTotalSteps( totalSteps );
+}
+
+
+/*!
+ Resets the progress dialog.
+ The progress dialog becomes hidden if autoClose() is TRUE.
+
+ \sa setAutoClose(), setAutoReset()
+*/
+
+void TQProgressDialog::reset()
+{
+#ifndef TQT_NO_CURSOR
+ if ( progress() >= 0 ) {
+ if ( d->creator )
+ d->creator->setCursor( d->parentCursor );
+ }
+#endif
+ if ( d->autoClose || d->forceHide )
+ hide();
+ bar()->reset();
+ d->cancellation_flag = FALSE;
+ d->shown_once = FALSE;
+ forceTimer->stop();
+}
+
+/*!
+ Resets the progress dialog. wasCanceled() becomes TRUE until
+ the progress dialog is reset.
+ The progress dialog becomes hidden.
+*/
+
+void TQProgressDialog::cancel()
+{
+ d->forceHide = TRUE;
+ reset();
+ d->forceHide = FALSE;
+ d->cancellation_flag = TRUE;
+}
+
+/*!
+ \property TQProgressDialog::progress
+ \brief the current amount of progress made.
+
+ For the progress dialog to work as expected, you should initially set
+ this property to 0 and finally set it to
+ TQProgressDialog::totalSteps(); you can call setProgress() any number of times
+ in-between.
+
+ \warning If the progress dialog is modal
+ (see TQProgressDialog::TQProgressDialog()),
+ this function calls TQApplication::processEvents(), so take care that
+ this does not cause undesirable re-entrancy in your code. For example,
+ don't use a TQProgressDialog inside a paintEvent()!
+
+ \sa totalSteps
+*/
+
+int TQProgressDialog::progress() const
+{
+ return bar()->progress();
+}
+
+void TQProgressDialog::setProgress( int progress )
+{
+ if ( progress == bar()->progress() ||
+ (bar()->progress() == -1 && progress == bar()->totalSteps()) )
+ return;
+
+ bar()->setProgress(progress);
+
+ if ( d->shown_once ) {
+ if (testWFlags(TQt::WShowModal))
+ tqApp->processEvents();
+ } else {
+ if ( progress == 0 ) {
+#ifndef TQT_NO_CURSOR
+ if ( d->creator ) {
+ d->parentCursor = d->creator->cursor();
+ d->creator->setCursor( Qt::WaitCursor );
+ }
+#endif
+ d->starttime.start();
+ forceTimer->start( d->showTime );
+ return;
+ } else {
+ bool need_show;
+ int elapsed = d->starttime.elapsed();
+ if ( elapsed >= d->showTime ) {
+ need_show = TRUE;
+ } else {
+ if ( elapsed > minWaitTime ) {
+ int estimate;
+ if ( (totalSteps() - progress) >= INT_MAX / elapsed )
+ estimate = (totalSteps() - progress) / progress * elapsed;
+ else
+ estimate = elapsed * (totalSteps() - progress) / progress;
+ need_show = estimate >= d->showTime;
+ } else {
+ need_show = FALSE;
+ }
+ }
+ if ( need_show ) {
+ int w = TQMAX( isVisible() ? width() : 0, tqsizeHint().width() );
+ int h = TQMAX( isVisible() ? height() : 0, tqsizeHint().height() );
+ resize( w, h );
+ show();
+ d->shown_once = TRUE;
+ }
+ }
+#ifdef TQ_WS_MACX
+ TQApplication::flush();
+#endif
+ }
+
+ if ( progress == bar()->totalSteps() && d->autoReset )
+ reset();
+}
+
+/*!
+ \overload
+
+ Sets the current amount of progress to \a progress and the total number of
+ steps to \a totalSteps.
+
+ \sa setTotalSteps()
+*/
+
+void TQProgressDialog::setProgress( int progress, int totalSteps )
+{
+ setTotalSteps( totalSteps );
+ setProgress( progress );
+}
+
+/*!
+ Returns a size that fits the contents of the progress dialog.
+ The progress dialog resizes itself as required, so you should not
+ need to call this yourself.
+*/
+
+TQSize TQProgressDialog::tqsizeHint() const
+{
+ TQSize sh = label()->tqsizeHint();
+ TQSize bh = bar()->tqsizeHint();
+ int h = margin_tb*2 + bh.height() + sh.height() + spacing;
+ if ( d->cancel )
+ h += d->cancel->tqsizeHint().height() + spacing;
+ return TQSize( TQMAX(200, sh.width() + 2*margin_lr), h );
+}
+
+/*!\reimp
+*/
+void TQProgressDialog::resizeEvent( TQResizeEvent * )
+{
+ tqlayout();
+}
+
+/*!
+ \reimp
+*/
+void TQProgressDialog::styleChange(TQStyle& s)
+{
+ TQDialog::styleChange(s);
+ tqlayout();
+}
+
+void TQProgressDialog::tqlayout()
+{
+ int sp = spacing;
+ int mtb = margin_tb;
+ int mlr = TQMIN(width()/10, margin_lr);
+ const bool centered =
+ bool(tqstyle().tqstyleHint(TQStyle::SH_ProgressDialog_CenterCancelButton, this));
+
+ TQSize cs = d->cancel ? d->cancel->tqsizeHint() : TQSize(0,0);
+ TQSize bh = bar()->tqsizeHint();
+ int cspc;
+ int lh = 0;
+
+ // Find spacing and sizes that fit. It is important that a progress
+ // dialog can be made very small if the user demands it so.
+ for (int attempt=5; attempt--; ) {
+ cspc = d->cancel ? cs.height() + sp : 0;
+ lh = TQMAX(0, height() - mtb - bh.height() - sp - cspc);
+
+ if ( lh < height()/4 ) {
+ // Getting cramped
+ sp /= 2;
+ mtb /= 2;
+ if ( d->cancel ) {
+ cs.setHeight(TQMAX(4,cs.height()-sp-2));
+ }
+ bh.setHeight(TQMAX(4,bh.height()-sp-1));
+ } else {
+ break;
+ }
+ }
+
+ if ( d->cancel ) {
+ d->cancel->setGeometry(
+ centered ? width()/2 - cs.width()/2 : width() - mlr - cs.width(),
+ height() - mtb - cs.height() + sp,
+ cs.width(), cs.height() );
+ }
+
+ label()->setGeometry( mlr, 0, width()-mlr*2, lh );
+ bar()->setGeometry( mlr, lh+sp, width()-mlr*2, bh.height() );
+}
+
+/*!
+ \property TQProgressDialog::minimumDuration
+ \brief the time that must pass before the dialog appears
+
+ If the expected duration of the task is less than the
+ minimumDuration, the dialog will not appear at all. This prevents
+ the dialog popping up for tasks that are quickly over. For tasks
+ that are expected to exceed the minimumDuration, the dialog will
+ pop up after the minimumDuration time or as soon as any progress
+ is set.
+
+ If set to 0, the dialog is always shown as soon as any progress is
+ set. The default is 4000 milliseconds.
+*/
+void TQProgressDialog::setMinimumDuration( int ms )
+{
+ d->showTime = ms;
+ if ( bar()->progress() == 0 ) {
+ forceTimer->stop();
+ forceTimer->start( ms );
+ }
+}
+
+int TQProgressDialog::minimumDuration() const
+{
+ return d->showTime;
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQProgressDialog::closeEvent( TQCloseEvent *e )
+{
+ emit canceled();
+ TQDialog::closeEvent( e );
+}
+
+/*!
+ \property TQProgressDialog::autoReset
+ \brief whether the progress dialog calls reset() as soon as progress() equals totalSteps()
+
+ The default is TRUE.
+
+ \sa setAutoClose()
+*/
+
+void TQProgressDialog::setAutoReset( bool b )
+{
+ d->autoReset = b;
+}
+
+bool TQProgressDialog::autoReset() const
+{
+ return d->autoReset;
+}
+
+/*!
+ \property TQProgressDialog::autoClose
+ \brief whether the dialog gets hidden by reset()
+
+ The default is TRUE.
+
+ \sa setAutoReset()
+*/
+
+void TQProgressDialog::setAutoClose( bool b )
+{
+ d->autoClose = b;
+}
+
+bool TQProgressDialog::autoClose() const
+{
+ return d->autoClose;
+}
+
+/*!
+ \reimp
+*/
+
+void TQProgressDialog::showEvent( TQShowEvent *e )
+{
+ TQDialog::showEvent( e );
+ int w = TQMAX( isVisible() ? width() : 0, tqsizeHint().width() );
+ int h = TQMAX( isVisible() ? height() : 0, tqsizeHint().height() );
+ resize( w, h );
+ forceTimer->stop();
+}
+
+/*!
+ Shows the dialog if it is still hidden after the algorithm has been started
+ and minimumDuration milliseconds have passed.
+
+ \sa setMinimumDuration()
+*/
+
+void TQProgressDialog::forceShow()
+{
+ if ( d->shown_once || d->cancellation_flag )
+ return;
+
+ show();
+ d->shown_once = TRUE;
+}
+
+
+#endif
diff --git a/tqtinterface/qt4/src/dialogs/tqprogressdialog.h b/tqtinterface/qt4/src/dialogs/tqprogressdialog.h
new file mode 100644
index 0000000..96ed191
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqprogressdialog.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** Definition of TQProgressDialog class
+**
+** Created : 970520
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPROGRESSDIALOG_H
+#define TQPROGRESSDIALOG_H
+
+#ifndef TQT_H
+#include "tqsemimodal.h"
+#include "tqlabel.h" // ### remove or keep for users' convenience?
+#include "tqprogressbar.h" // ### remove or keep for users' convenience?
+#endif // TQT_H
+
+#ifndef TQT_NO_PROGRESSDIALOG
+
+class TQPushButton;
+class TQTimer;
+class TQProgressDialogData;
+
+class TQ_EXPORT TQProgressDialog : public TQDialog
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool wasCancelled READ wasCancelled DESIGNABLE false STORED false ) // ### remove in 4.0
+ Q_PROPERTY( bool wasCanceled READ wasCanceled )
+ Q_PROPERTY( int totalSteps READ totalSteps WRITE setTotalSteps )
+ Q_PROPERTY( int progress READ progress WRITE setProgress )
+ Q_PROPERTY( bool autoReset READ autoReset WRITE setAutoReset )
+ Q_PROPERTY( bool autoClose READ autoClose WRITE setAutoClose )
+ Q_PROPERTY( int minimumDuration READ minimumDuration WRITE setMinimumDuration )
+ Q_PROPERTY( TQString labelText READ labelText WRITE setLabelText )
+
+public:
+ TQProgressDialog( TQWidget* tqparent=0, const char* name=0, bool modal=FALSE,
+ WFlags f=0 );
+ TQProgressDialog( const TQString& labelText, const TQString &cancelButtonText,
+ int totalSteps, TQWidget* tqparent=0, const char* name=0,
+ bool modal=FALSE, WFlags f=0 );
+ ~TQProgressDialog();
+
+ void setLabel( TQLabel * );
+ void setCancelButton( TQPushButton * );
+ void setBar( TQProgressBar * );
+
+ // ### TQt 4.0: remove wasCancelled() in 4.0
+ bool wasCancelled() const;
+ inline bool wasCanceled() const { return wasCancelled(); }
+
+ int totalSteps() const;
+ int progress() const;
+
+ TQSize tqsizeHint() const;
+
+ TQString labelText() const;
+
+ void setAutoReset( bool b );
+ bool autoReset() const;
+ void setAutoClose( bool b );
+ bool autoClose() const;
+
+public Q_SLOTS:
+ void cancel();
+ void reset();
+ void setTotalSteps( int totalSteps );
+ void setProgress( int progress );
+ void setProgress( int progress, int totalSteps );
+ void setLabelText( const TQString &);
+ void setCancelButtonText( const TQString &);
+
+ void setMinimumDuration( int ms );
+public:
+ int minimumDuration() const;
+
+Q_SIGNALS:
+ // ### remove cancelled() in 4.0
+ void cancelled();
+ void canceled();
+
+protected:
+ void resizeEvent( TQResizeEvent * );
+ void closeEvent( TQCloseEvent * );
+ void styleChange( TQStyle& );
+ void showEvent( TQShowEvent *e );
+
+protected Q_SLOTS:
+ void forceShow();
+
+private:
+ void init( TQWidget *creator, const TQString& lbl, const TQString &canc,
+ int totstps);
+ void tqlayout();
+ TQLabel *label() const;
+ TQProgressBar *bar() const;
+ TQProgressDialogData *d;
+ TQTimer *forceTimer;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQProgressDialog( const TQProgressDialog & );
+ TQProgressDialog &operator=( const TQProgressDialog & );
+#endif
+};
+
+#endif // TQT_NO_PROGRESSDIALOG
+
+#endif // TQPROGRESSDIALOG_H
diff --git a/tqtinterface/qt4/src/dialogs/tqsemimodal.h b/tqtinterface/qt4/src/dialogs/tqsemimodal.h
new file mode 100644
index 0000000..fafa0af
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqsemimodal.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Definition of TQSemiModal class for source compatibility
+**
+** Created : 001010
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSEMIMODAL_H
+#define TQSEMIMODAL_H
+
+#ifndef TQT_H
+#include "tqdialog.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_COMPAT
+#ifndef TQT_NO_SEMIMODAL
+class TQ_EXPORT TQSemiModal : public TQDialog
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQSemiModal( TQWidget* tqparent=0, const char* name=0, bool modal=FALSE, WFlags f=0 )
+ : TQDialog( tqparent, name, modal, f ) { }
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSemiModal( const TQSemiModal & );
+ TQSemiModal &operator=( const TQSemiModal & );
+#endif
+};
+#endif
+#endif
+
+#endif // TQSEMIMODAL_H
diff --git a/tqtinterface/qt4/src/dialogs/tqtabdialog.cpp b/tqtinterface/qt4/src/dialogs/tqtabdialog.cpp
new file mode 100644
index 0000000..dc670a9
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqtabdialog.cpp
@@ -0,0 +1,1145 @@
+/****************************************************************************
+**
+** Implementation of TQTabDialog class
+**
+** Created : 960825
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtabdialog.h"
+
+#ifndef TQT_NO_TABDIALOG
+
+#include "tqobjectlist.h"
+#include "tqtabbar.h"
+#include "tqtabwidget.h"
+#include "tqpushbutton.h"
+#include "tqpainter.h"
+#include "tqpixmap.h"
+#include "tqapplication.h"
+#include "tqtabwidget.h"
+#include "tqwidgetstack.h"
+#include "tqlayout.h"
+
+/*!
+ \class TQTabDialog tqtabdialog.h
+
+ \brief The TQTabDialog class provides a stack of tabbed widgets.
+
+ \ingroup dialogs
+ \mainclass
+
+ A tabbed dialog is one in which several "tab pages" are available.
+ By clicking on a tab page's tab or by pressing the indicated
+ Alt+\e{letter} key combination, the user can select which tab page
+ they want to use.
+
+ TQTabDialog provides a tab bar consisting of single row of tabs at
+ the top; each tab has an associated widget which is that tab's
+ tab page. In addition, TQTabDialog provides an OK button and the
+ following optional buttons: Apply, Cancel, Defaults and Help.
+
+ The normal way to use TQTabDialog is to do the following in the
+ constructor:
+ \list 1
+ \i Create a TQTabDialog.
+ \i Create a TQWidget for each of the pages in the tab dialog, insert
+ tqchildren into it, set up tqgeometry management for it, and use
+ addTab() (or insertTab()) to set up a tab and keyboard accelerator
+ for it.
+ \i Set up the buttons for the tab dialog using setOkButton(),
+ setApplyButton(), setDefaultsButton(), setCancelButton() and
+ setHelpButton().
+ \i Connect to the Q_SIGNALS and Q_SLOTS.
+ \endlist
+
+ If you don't call addTab() the page you have created will not be
+ visible. Don't confuse the object name you supply to the
+ TQWidget constructor and the tab label you supply to addTab();
+ addTab() takes user-visible name that appears on the widget's tab
+ and may identify an accelerator, whereas the widget name is used
+ primarily for debugging.
+
+ Almost all applications have to connect the applyButtonPressed()
+ signal to something. applyButtonPressed() is emitted when either OK
+ or Apply is clicked, and your slot must copy the dialog's state into
+ the application.
+
+ There are also several other Q_SIGNALS which may be useful:
+ \list
+ \i cancelButtonPressed() is emitted when the user clicks Cancel.
+ \i defaultButtonPressed() is emitted when the user clicks Defaults;
+ the slot it is connected to should reset the state of the dialog to
+ the application defaults.
+ \i helpButtonPressed() is emitted when the user clicks Help.
+ \i aboutToShow() is emitted at the start of show(); if there is any
+ chance that the state of the application may change between the
+ creation of the tab dialog and the time show() is called, you must
+ connect this signal to a slot that resets the state of the dialog.
+ \i currentChanged() is emitted when the user selects a page.
+ \endlist
+
+ Each tab is either enabled or disabled at any given time (see
+ setTabEnabled()). If a tab is enabled the tab text is drawn in
+ black and the user can select that tab. If it is disabled the tab
+ is drawn in a different way and the user cannot select that tab.
+ Note that even if a tab is disabled, the page can still be visible;
+ for example, if all of the tabs happen to be disabled.
+
+ You can change a tab's label and iconset using changeTab(). A tab
+ page can be removed with removePage() and shown with showPage(). The
+ current page is given by currentPage().
+
+ TQTabDialog does not support tabs on the sides or bottom, nor can
+ you set or retrieve the visible page. If you need more functionality
+ than TQTabDialog provides, consider creating a TQDialog and using a
+ TQTabBar with TQTabWidgets.
+
+ Most of the functionality in TQTabDialog is provided by a TQTabWidget.
+
+ <img src=qtabdlg-m.png> <img src=qtabdlg-w.png>
+
+ \sa TQDialog
+*/
+
+/*!
+ \fn void TQTabDialog::selected( const TQString & );
+ \obsolete
+
+ This signal is emitted whenever a tab is selected (raised),
+ including during the first show().
+
+ \sa raise()
+*/
+
+/*! \fn void TQTabDialog::currentChanged( TQWidget* );
+
+ This signal is emitted whenever the current page changes.
+
+ \sa currentPage(), showPage(), tabLabel()
+*/
+
+
+// add comments about delete, ok and apply
+
+class TQTabDialogPrivate
+{
+public:
+ TQTabDialogPrivate();
+
+ TQTabWidget* tw;
+
+ TQPushButton * ok;
+ TQPushButton * cb;
+ TQPushButton * db;
+ TQPushButton * hb;
+ TQPushButton * ab;
+
+ TQBoxLayout * tll;
+};
+
+TQTabDialogPrivate::TQTabDialogPrivate()
+ : tw(0),
+ ok(0), cb(0), db(0), hb(0), ab(0),
+ tll(0)
+{ }
+
+/*!
+ Constructs a TQTabDialog with only an OK button.
+ The \a tqparent, \a name, \a modal and widget flag, \a f, arguments
+ are passed on to the TQDialog constructor.
+*/
+
+TQTabDialog::TQTabDialog( TQWidget *tqparent, const char *name, bool modal,
+ WFlags f )
+ : TQDialog( tqparent, name, modal, f )
+{
+ d = new TQTabDialogPrivate;
+ TQ_CHECK_PTR( d );
+
+ d->tw = new TQTabWidget( this, "tab widget" );
+ connect ( d->tw, TQT_SIGNAL ( selected(const TQString&) ), this, TQT_SIGNAL( selected(const TQString&) ) );
+ connect ( d->tw, TQT_SIGNAL ( currentChanged(TQWidget*) ), this, TQT_SIGNAL( currentChanged(TQWidget*) ) );
+
+ d->ok = new TQPushButton( this, "ok" );
+ TQ_CHECK_PTR( d->ok );
+ d->ok->setText( tr("OK") );
+ d->ok->setDefault( TRUE );
+ connect( d->ok, TQT_SIGNAL(clicked()),
+ this, TQT_SIGNAL(applyButtonPressed()) );
+ connect( d->ok, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(accept()) );
+}
+
+
+/*!
+ Destroys the tab dialog.
+*/
+
+TQTabDialog::~TQTabDialog()
+{
+ delete d;
+}
+
+
+/*!
+ Sets the font for the tabs to \a font.
+
+ If the widget is visible, the display is updated with the new font
+ immediately. There may be some tqgeometry changes, depending on the
+ size of the old and new fonts.
+*/
+
+void TQTabDialog::setFont( const TQFont & font )
+{
+ TQDialog::setFont( font );
+ setSizes();
+}
+
+
+/*!
+ \fn void TQTabDialog::applyButtonPressed();
+
+ This signal is emitted when either the Apply or OK button is clicked.
+
+ It should be connected to a slot (or several Q_SLOTS) that change the
+ application's state according to the state of the dialog.
+
+ \sa cancelButtonPressed() defaultButtonPressed() setApplyButton()
+*/
+
+
+/*!
+ Returns TRUE if the tab dialog has a Defaults button; otherwise
+ returns FALSE.
+
+ \sa setDefaultButton() defaultButtonPressed() hasApplyButton()
+ hasCancelButton()
+*/
+
+bool TQTabDialog::hasDefaultButton() const
+{
+ return d->db != 0;
+}
+
+
+/*!
+ Returns TRUE if the tab dialog has a Help button; otherwise returns
+ FALSE.
+
+ \sa setHelpButton() helpButtonPressed() hasApplyButton()
+ hasCancelButton()
+*/
+
+bool TQTabDialog::hasHelpButton() const
+{
+ return d->hb != 0;
+}
+
+
+/*!
+ \fn void TQTabDialog::cancelButtonPressed();
+
+ This signal is emitted when the Cancel button is clicked. It is
+ automatically connected to TQDialog::reject(), which will hide the
+ dialog.
+
+ The Cancel button should not change the application's state at all,
+ so you should generally not need to connect it to any slot.
+
+ \sa applyButtonPressed() defaultButtonPressed() setCancelButton()
+*/
+
+
+/*!
+ Returns TRUE if the tab dialog has a Cancel button; otherwise
+ returns FALSE.
+
+ \sa setCancelButton() cancelButtonPressed() hasApplyButton()
+ hasDefaultButton()
+*/
+
+bool TQTabDialog::hasCancelButton() const
+{
+ return d->cb != 0;
+}
+
+
+/*!
+ \fn void TQTabDialog::defaultButtonPressed();
+
+ This signal is emitted when the Defaults button is pressed. It
+ should reset the dialog (but not the application) to the "factory
+ defaults".
+
+ The application's state should not be changed until the user clicks
+ Apply or OK.
+
+ \sa applyButtonPressed() cancelButtonPressed() setDefaultButton()
+*/
+
+
+/*!
+ \fn void TQTabDialog::helpButtonPressed();
+
+ This signal is emitted when the Help button is pressed. It
+ could be used to present information about how to use the dialog.
+
+ \sa applyButtonPressed() cancelButtonPressed() setHelpButton()
+*/
+
+
+/*!
+ Returns TRUE if the tab dialog has an Apply button; otherwise
+ returns FALSE.
+
+ \sa setApplyButton() applyButtonPressed() hasCancelButton()
+ hasDefaultButton()
+*/
+
+bool TQTabDialog::hasApplyButton() const
+{
+ return d->ab != 0;
+}
+
+
+/*!
+ Returns TRUE if the tab dialog has an OK button; otherwise returns
+ FALSE.
+
+ \sa setOkButton() hasApplyButton() hasCancelButton()
+ hasDefaultButton()
+*/
+
+bool TQTabDialog::hasOkButton() const
+{
+ return d->ok != 0;
+}
+
+
+/*!
+ \fn void TQTabDialog::aboutToShow()
+
+ This signal is emitted by show() when it is time to set the state of
+ the dialog's contents. The dialog should reflect the current state
+ of the application when it appears; if there is any possibility that
+ the state of the application may change between the time you call
+ TQTabDialog::TQTabDialog() and TQTabDialog::show(), you should set the
+ dialog's state in a slot and connect this signal to it.
+
+ This applies mainly to TQTabDialog objects that are kept around
+ hidden, rather than being created, shown, and deleted afterwards.
+
+ \sa applyButtonPressed(), show(), cancelButtonPressed()
+*/
+
+
+/*!\reimp
+*/
+void TQTabDialog::show()
+{
+ // Reimplemented in order to delay show()'ing of every page
+ // except the initially visible one, and in order to emit the
+ // aboutToShow() signal.
+ if ( tqtopLevelWidget() == this )
+ d->tw->setFocus();
+ emit aboutToShow();
+ setSizes();
+ setUpLayout();
+ TQDialog::show();
+}
+
+
+/*!
+ Ensures that tab page \a i is visible and appropriately sized.
+*/
+
+void TQTabDialog::showTab( int i )
+{
+ d->tw->showTab( i );
+}
+
+
+/*!
+ Adds another tab and page to the tab view.
+
+ The new page is \a child; the tab's label is \a label.
+ Note the difference between the widget name (which you supply to
+ widget constructors and to setTabEnabled(), for example) and the tab
+ label. The name is internal to the program and invariant, whereas
+ the label is shown on-screen and may vary according to language and
+ other factors.
+
+ If the tab's \a label tqcontains an ampersand, the letter following
+ the ampersand is used as an accelerator for the tab, e.g. if the
+ label is "Bro&wse" then Alt+W becomes an accelerator which will
+ move the focus to this tab.
+
+ If you call addTab() after show() the screen will flicker and the
+ user may be confused.
+
+ \sa insertTab()
+*/
+
+void TQTabDialog::addTab( TQWidget * child, const TQString &label )
+{
+ d->tw->addTab( child, label );
+}
+
+
+
+/*! \overload
+
+ This version of the function shows the \a iconset as well as the \a
+ label on the tab of \a child.
+*/
+void TQTabDialog::addTab( TQWidget *child, const TQIconSet& iconset, const TQString &label)
+{
+ d->tw->addTab( child, iconset, label );
+}
+
+/*!
+ \overload
+
+ This is a lower-level method for adding tabs, similar to the other
+ addTab() method. It is useful if you are using setTabBar() to set a
+ TQTabBar subclass with an overridden TQTabBar::paint() function for a
+ subclass of TQTab.
+
+ The \a child is the widget to be placed on the new tab page. The \a
+ tab is the tab to display on the tab page -- normally this shows a
+ label or an icon that identifies the tab page.
+
+*/
+void TQTabDialog::addTab( TQWidget * child, TQTab* tab )
+{
+ d->tw->addTab( child, tab );
+}
+
+/*!
+ Inserts another tab and page to the tab view.
+
+ The new page is \a child; the tab's label is \a label.
+ Note the difference between the widget name (which you supply to
+ widget constructors and to setTabEnabled(), for example) and the tab
+ label. The name is internal to the program and invariant, whereas
+ the label is shown on-screen and may vary according to language and
+ other factors.
+
+ If the tab's \a label tqcontains an ampersand, the letter following
+ the ampersand is used as an accelerator for the tab, e.g. if the
+ label is "Bro&wse" then Alt+W becomes an accelerator which will
+ move the focus to this tab.
+
+ If \a index is not specified, the tab is simply added. Otherwise
+ it is inserted at the specified position.
+
+ If you call insertTab() after show(), the screen will flicker and the
+ user may be confused.
+
+ \sa addTab()
+*/
+
+void TQTabDialog::insertTab( TQWidget * child, const TQString &label, int index )
+{
+ d->tw->insertTab( child, label, index );
+}
+
+
+/*! \overload
+
+ This version of the function shows the \a iconset as well as the \a
+ label on the tab of \a child.
+ */
+void TQTabDialog::insertTab( TQWidget *child, const TQIconSet& iconset, const TQString &label, int index)
+{
+ d->tw->insertTab( child, iconset, label, index );
+}
+
+/*!
+ \overload
+
+ This is a lower-level method for inserting tabs, similar to the other
+ insertTab() method. It is useful if you are using setTabBar() to set a
+ TQTabBar subclass with an overridden TQTabBar::paint() function for a
+ subclass of TQTab.
+
+ The \a child is the widget to be placed on the new tab page. The \a
+ tab is the tab to display on the tab page -- normally this shows a
+ label or an icon that identifies the tab page. The \a index is the
+ position where this tab page should be inserted.
+
+*/
+void TQTabDialog::insertTab( TQWidget * child, TQTab* tab, int index )
+{
+ d->tw->insertTab( child, tab, index );
+}
+
+/*!
+ Replaces the TQTabBar heading the dialog by the given tab bar, \a tb.
+ Note that this must be called \e before any tabs have been added,
+ or the behavior is undefined.
+ \sa tabBar()
+*/
+void TQTabDialog::setTabBar( TQTabBar* tb )
+{
+ d->tw->setTabBar( tb );
+ setUpLayout();
+}
+
+/*!
+ Returns the currently set TQTabBar.
+ \sa setTabBar()
+*/
+TQTabBar* TQTabDialog::tabBar() const
+{
+ return d->tw->tabBar();
+}
+
+/*! Ensures that widget \a w is shown. This is mainly useful for accelerators.
+
+ \warning If used carelessly, this function can easily surprise or
+ confuse the user.
+
+ \sa TQTabBar::setCurrentTab()
+*/
+
+void TQTabDialog::showPage( TQWidget * w )
+{
+ d->tw->showPage( w );
+}
+
+
+/*! \obsolete
+ Returns TRUE if the page with object name \a name is enabled and
+ FALSE if it is disabled.
+
+ If \a name is 0 or not the name of any of the pages, isTabEnabled()
+ returns FALSE.
+
+ \sa setTabEnabled(), TQWidget::isEnabled()
+*/
+
+bool TQTabDialog::isTabEnabled( const char* name ) const
+{
+ if ( !name )
+ return FALSE;
+ TQObjectList * l
+ = ((TQTabDialog *)this)->queryList( "TQWidget", name, FALSE, TRUE );
+ if ( l && l->first() ) {
+ TQWidget * w;
+ while( l->current() ) {
+ while( l->current() && !l->current()->isWidgetType() )
+ l->next();
+ w = (TQWidget *)(l->current());
+ if ( w ) {
+ bool enabled = d->tw->isTabEnabled( w );
+ delete l;
+ return enabled;
+ }
+ }
+ }
+ delete l;
+ return FALSE;
+}
+
+
+/*!\obsolete
+
+ Finds the page with object name \a name, enables/disables it
+ according to the value of \a enable and redraws the page's tab
+ appropriately.
+
+ TQTabDialog uses TQWidget::setEnabled() internally, rather than keeping a
+ separate flag.
+
+ Note that even a disabled tab/page may be visible. If the page is
+ already visible TQTabDialog will not hide it; if all the pages
+ are disabled TQTabDialog will show one of them.
+
+ The object name is used (rather than the tab label) because the tab
+ text may not be invariant in multi-language applications.
+
+ \sa isTabEnabled(), TQWidget::setEnabled()
+*/
+
+void TQTabDialog::setTabEnabled( const char* name, bool enable )
+{
+ if ( !name )
+ return;
+ TQObjectList * l
+ = ((TQTabDialog *)this)->queryList( "TQWidget", name, FALSE, TRUE );
+ if ( l && l->first() ) {
+ TQObjectListIt it(*l);
+ TQObject *o;
+ while( (o = it.current()) ) {
+ ++it;
+ if( o->isWidgetType() )
+ d->tw->setTabEnabled( (TQWidget*)o, enable );
+ }
+ }
+ delete l;
+}
+
+
+/* ### SHOULD THIS BE HERE?
+ Adds an Apply button to the dialog. The button's text is set to \e
+ text (and defaults to "Apply").
+
+ The Apply button should apply the current settings in the dialog box
+ to the application, while keeping the dialog visible.
+
+ When Apply is clicked, the applyButtonPressed() signal is emitted.
+
+ If \a text is a
+ \link TQString::operator!() null string\endlink,
+ no button is shown.
+
+ \sa setCancelButton() setDefaultButton() applyButtonPressed()
+*/
+
+
+/*!
+ Returns TRUE if the page \a w is enabled; otherwise returns FALSE.
+
+ \sa setTabEnabled(), TQWidget::isEnabled()
+*/
+
+bool TQTabDialog::isTabEnabled( TQWidget* w ) const
+{
+ return d->tw->isTabEnabled( w );
+}
+
+/*!
+ If \a enable is TRUE the page \a w is enabled; otherwise \a w is
+ disabled. The page's tab is redrawn appropriately.
+
+ TQTabWidget uses TQWidget::setEnabled() internally, rather than keeping a
+ separate flag.
+
+ Note that even a disabled tab and tab page may be visible. If the
+ page is already visible TQTabWidget will not hide it; if all the
+ pages are disabled TQTabWidget will show one of them.
+
+ \sa isTabEnabled(), TQWidget::setEnabled()
+*/
+
+void TQTabDialog::setTabEnabled( TQWidget* w, bool enable)
+{
+ d->tw->setTabEnabled( w, enable );
+}
+
+
+/*!
+ Adds an Apply button to the dialog. The button's text is set to \a
+ text.
+
+ The Apply button should apply the current settings in the dialog box
+ to the application while keeping the dialog visible.
+
+ When Apply is clicked, the applyButtonPressed() signal is emitted.
+
+ If \a text is a
+ \link TQString::operator!() null string\endlink,
+ no button is shown.
+
+ \sa setCancelButton() setDefaultButton() applyButtonPressed()
+*/
+void TQTabDialog::setApplyButton( const TQString &text )
+{
+ if ( !text && d->ab ) {
+ delete d->ab;
+ d->ab = 0;
+ setSizes();
+ } else {
+ if ( !d->ab ) {
+ d->ab = new TQPushButton( this, "apply settings" );
+ connect( d->ab, TQT_SIGNAL(clicked()),
+ this, TQT_SIGNAL(applyButtonPressed()) );
+ setUpLayout();
+ }
+ d->ab->setText( text );
+ setSizes();
+ //d->ab->show();
+ }
+}
+
+/*!
+ \overload
+
+ Adds an Apply button to the dialog. The button's text is set to
+ a localizable "Apply".
+ */
+void TQTabDialog::setApplyButton()
+{
+ setApplyButton( tr("Apply") );
+}
+
+
+/*!
+ Adds a Help button to the dialog. The button's text is set to \a
+ text.
+
+ When Help is clicked, the helpButtonPressed() signal is emitted.
+
+ If \a text is a
+ \link TQString::operator!() null string\endlink,
+ no button is shown.
+
+ \sa setApplyButton() setCancelButton() helpButtonPressed()
+*/
+
+void TQTabDialog::setHelpButton( const TQString &text )
+{
+ if ( !text ) {
+ delete d->hb;
+ d->hb = 0;
+ setSizes();
+ } else {
+ if ( !d->hb ) {
+ d->hb = new TQPushButton( this, "give help" );
+ connect( d->hb, TQT_SIGNAL(clicked()),
+ this, TQT_SIGNAL(helpButtonPressed()) );
+ setUpLayout();
+ }
+ d->hb->setText( text );
+ setSizes();
+ //d->hb->show();
+ }
+}
+
+
+/*!
+ \overload
+
+ Adds a Help button to the dialog. The button's text is set to
+ a localizable "Help".
+ */
+void TQTabDialog::setHelpButton()
+{
+ setHelpButton( tr("Help") );
+}
+
+/*!
+ Adds a Defaults button to the dialog. The button's text is set to \a
+ text.
+
+ The Defaults button should set the dialog (but not the application)
+ back to the application defaults.
+
+ When Defaults is clicked, the defaultButtonPressed() signal is emitted.
+
+ If \a text is a
+ \link TQString::operator!() null string\endlink,
+ no button is shown.
+
+ \sa setApplyButton() setCancelButton() defaultButtonPressed()
+*/
+
+void TQTabDialog::setDefaultButton( const TQString &text )
+{
+ if ( !text ) {
+ delete d->db;
+ d->db = 0;
+ setSizes();
+ } else {
+ if ( !d->db ) {
+ d->db = new TQPushButton( this, "back to default" );
+ connect( d->db, TQT_SIGNAL(clicked()),
+ this, TQT_SIGNAL(defaultButtonPressed()) );
+ setUpLayout();
+ }
+ d->db->setText( text );
+ setSizes();
+ //d->db->show();
+ }
+}
+
+
+/*!
+ \overload
+
+ Adds a Defaults button to the dialog. The button's text is set to
+ a localizable "Defaults".
+ */
+void TQTabDialog::setDefaultButton()
+{
+ setDefaultButton( tr("Defaults") );
+}
+
+/*!
+ Adds a Cancel button to the dialog. The button's text is set to \a
+ text.
+
+ The cancel button should always return the application to the state
+ it was in before the tab view popped up, or if the user has clicked
+ Apply, back to the state immediately after the last Apply.
+
+ When Cancel is clicked, the cancelButtonPressed() signal is emitted.
+ The dialog is closed at the same time.
+
+ If \a text is a
+ \link TQString::operator!() null string\endlink,
+ no button is shown.
+
+ \sa setApplyButton() setDefaultButton() cancelButtonPressed()
+*/
+
+void TQTabDialog::setCancelButton( const TQString &text )
+{
+ if ( !text ) {
+ delete d->cb;
+ d->cb = 0;
+ setSizes();
+ } else {
+ if ( !d->cb ) {
+ d->cb = new TQPushButton( this, "cancel dialog" );
+ connect( d->cb, TQT_SIGNAL(clicked()),
+ this, TQT_SIGNAL(cancelButtonPressed()) );
+ connect( d->cb, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(reject()) );
+ setUpLayout();
+ }
+ d->cb->setText( text );
+ setSizes();
+ //d->cb->show();
+ }
+}
+
+
+/*!
+ \overload
+
+ Adds a Cancel button to the dialog. The button's text is set to
+ a localizable "Cancel".
+ */
+
+void TQTabDialog::setCancelButton()
+{
+ setCancelButton( tr("Cancel") );
+}
+
+
+/*! Sets up the tqlayout manager for the tab dialog.
+
+ \sa setSizes() setApplyButton() setCancelButton() setDefaultButton()
+*/
+
+void TQTabDialog::setUpLayout()
+{
+ // the next four are probably the same, really?
+ const int topMargin = 6;
+ const int leftMargin = 6;
+ const int rightMargin = 6;
+ const int bottomMargin = 6;
+ const int betweenButtonsMargin = 7;
+ const int aboveButtonsMargin = 8;
+
+ delete d->tll;
+ d->tll = new TQBoxLayout( this, TQBoxLayout::Down );
+
+ // top margin
+ d->tll->addSpacing( topMargin );
+
+ TQBoxLayout * tmp = new TQHBoxLayout();
+ d->tll->addLayout( tmp, 1 );
+ tmp->addSpacing( leftMargin );
+ tmp->addWidget( d->tw, 1);
+ tmp->addSpacing( rightMargin + 2 );
+
+ d->tll->addSpacing( aboveButtonsMargin + 2 );
+ TQBoxLayout * buttonRow = new TQBoxLayout(TQBoxLayout::RightToLeft);
+ d->tll->addLayout( buttonRow, 0 );
+ d->tll->addSpacing( bottomMargin );
+
+ buttonRow->addSpacing( rightMargin );
+ if ( d->cb ) {
+ buttonRow->addWidget( d->cb, 0 );
+ buttonRow->addSpacing( betweenButtonsMargin );
+ d->cb->raise();
+ }
+
+ if ( d->ab ) {
+ buttonRow->addWidget( d->ab, 0 );
+ buttonRow->addSpacing( betweenButtonsMargin );
+ d->ab->raise();
+ }
+
+ if ( d->db ) {
+ buttonRow->addWidget( d->db, 0 );
+ buttonRow->addSpacing( betweenButtonsMargin );
+ d->db->raise();
+ }
+
+ if ( d->hb ) {
+ buttonRow->addWidget( d->hb, 0 );
+ buttonRow->addSpacing( betweenButtonsMargin );
+ d->hb->raise();
+ }
+
+ if ( d->ok ) {
+ buttonRow->addWidget( d->ok, 0 );
+ buttonRow->addSpacing( betweenButtonsMargin );
+ d->ok->raise();
+ }
+
+ // add one custom widget here
+ buttonRow->addStretch( 1 );
+ // add another custom widget here
+
+ d->tll->activate();
+}
+
+
+/*! Sets up the minimum and maximum sizes for each child widget.
+
+ \sa setUpLayout() setFont()
+*/
+
+void TQTabDialog::setSizes()
+{
+ // compute largest button size
+ TQSize s( 0, 0 );
+ int bw = s.width();
+ int bh = s.height();
+
+ if ( d->ok ) {
+ s = d->ok->tqsizeHint();
+ if ( s.width() > bw )
+ bw = s.width();
+ if ( s.height() > bh )
+ bh = s.height();
+ }
+
+ if ( d->ab ) {
+ s = d->ab->tqsizeHint();
+ if ( s.width() > bw )
+ bw = s.width();
+ if ( s.height() > bh )
+ bh = s.height();
+ }
+
+ if ( d->db ) {
+ s = d->db->tqsizeHint();
+ if ( s.width() > bw )
+ bw = s.width();
+ if ( s.height() > bh )
+ bh = s.height();
+ }
+
+ if ( d->hb ) {
+ s = d->hb->tqsizeHint();
+ if ( s.width() > bw )
+ bw = s.width();
+ if ( s.height() > bh )
+ bh = s.height();
+ }
+
+ if ( d->cb ) {
+ s = d->cb->tqsizeHint();
+ if ( s.width() > bw )
+ bw = s.width();
+ if ( s.height() > bh )
+ bh = s.height();
+ }
+
+ // and set all the buttons to that size
+ if ( d->ok )
+ d->ok->setFixedSize( bw, bh );
+ if ( d->ab )
+ d->ab->setFixedSize( bw, bh );
+ if ( d->db )
+ d->db->setFixedSize( bw, bh );
+ if ( d->hb )
+ d->hb->setFixedSize( bw, bh );
+ if ( d->cb )
+ d->cb->setFixedSize( bw, bh );
+
+ // fiddle the tab chain so the buttons are in their natural order
+ TQWidget * w = d->ok;
+
+ if ( d->hb ) {
+ if ( w )
+ setTabOrder( w, d->hb );
+ w = d->hb;
+ }
+ if ( d->db ) {
+ if ( w )
+ setTabOrder( w, d->db );
+ w = d->db;
+ }
+ if ( d->ab ) {
+ if ( w )
+ setTabOrder( w, d->ab );
+ w = d->ab;
+ }
+ if ( d->cb ) {
+ if ( w )
+ setTabOrder( w, d->cb );
+ w = d->cb;
+ }
+ setTabOrder( w, d->tw );
+}
+
+/*!\reimp
+*/
+void TQTabDialog::resizeEvent( TQResizeEvent * e )
+{
+ TQDialog::resizeEvent( e );
+}
+
+
+/*!\reimp
+*/
+void TQTabDialog::paintEvent( TQPaintEvent * )
+{
+}
+
+
+/*!
+ Adds an OK button to the dialog and sets the button's text to \a text.
+
+ When the OK button is clicked, the applyButtonPressed() signal is emitted,
+ and the current settings in the dialog box should be applied to
+ the application. The dialog then closes.
+
+ If \a text is a
+ \link TQString::operator!() null string\endlink,
+ no button is shown.
+
+ \sa setCancelButton() setDefaultButton() applyButtonPressed()
+*/
+
+void TQTabDialog::setOkButton( const TQString &text )
+{
+ if ( !text ) {
+ delete d->ok;
+ d->ok = 0;
+ setSizes();
+ } else {
+ if ( !d->ok ) {
+ d->ok = new TQPushButton( this, "ok" );
+ connect( d->ok, TQT_SIGNAL(clicked()),
+ this, TQT_SIGNAL(applyButtonPressed()) );
+ setUpLayout();
+ }
+ d->ok->setText( text );
+ setSizes();
+ //d->ok->show();
+ }
+}
+/*!
+ \overload
+
+ Adds an OK button to the dialog. The button's text is set to
+ a localizable "OK".
+ */
+
+void TQTabDialog::setOkButton()
+{
+ setOkButton( tr("OK") );
+}
+
+
+/*
+ \overload
+ Old version of setOkButton(), provided for backward compatibility.
+*/
+void TQTabDialog::setOKButton( const TQString &text )
+{
+ // Ugly workaround for original "OK" default argument
+ TQString newText( text );
+ if ( text.isNull() )
+ newText = TQString::tqfromLatin1( "OK" );
+ setOkButton( newText );
+}
+
+
+/*! Returns the text in the tab for page \a w.
+*/
+
+TQString TQTabDialog::tabLabel( TQWidget * w )
+{
+ return d->tw->tabLabel( w );
+}
+
+
+/*! \reimp
+*/
+void TQTabDialog::styleChange( QStyle& s )
+{
+ TQDialog::styleChange( s );
+ setSizes();
+}
+
+
+/*! Returns a pointer to the page currently being displayed by the
+tab dialog. The tab dialog does its best to make sure that this value
+is never 0 (but if you try hard enough, it can be).
+*/
+
+TQWidget * TQTabDialog::currentPage() const
+{
+ return d->tw->currentPage();
+}
+
+/*!
+ \overload
+ Defines a new \a label for the tab of page \a w
+ */
+void TQTabDialog::changeTab( TQWidget *w, const TQString &label)
+{
+ d->tw->changeTab( w, label );
+}
+
+/*!
+ Changes tab page \a w's iconset to \a iconset and label to \a label.
+
+ */
+void TQTabDialog::changeTab( TQWidget *w, const TQIconSet& iconset, const TQString &label)
+{
+ d->tw->changeTab( w, iconset, label );
+}
+
+/*! Removes page \a w from this stack of widgets. Does not
+ delete \a w.
+ \sa showPage(), TQTabWidget::removePage(), TQWidgetStack::removeWidget()
+*/
+void TQTabDialog::removePage( TQWidget * w )
+{
+ d->tw->removePage( w );
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/dialogs/tqtabdialog.h b/tqtinterface/qt4/src/dialogs/tqtabdialog.h
new file mode 100644
index 0000000..d485dfe
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqtabdialog.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Definition of TQTabDialog class
+**
+** Created : 960825
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTABDIALOG_H
+#define TQTABDIALOG_H
+
+#ifndef TQT_H
+#include "tqdialog.h"
+#include "tqiconset.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TABDIALOG
+
+class TQTabBar;
+class TQTab;
+class TQTabDialogPrivate;
+
+class TQ_EXPORT TQTabDialog : public TQDialog
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQTabDialog( TQWidget* tqparent=0, const char* name=0, bool modal=FALSE,
+ WFlags f=0 );
+ ~TQTabDialog();
+
+ void show();
+ void setFont( const TQFont & font );
+
+ void addTab( TQWidget *, const TQString &);
+ void addTab( TQWidget *child, const TQIconSet& iconset, const TQString &label);
+ void addTab( TQWidget *, TQTab* );
+
+ void insertTab( TQWidget *, const TQString &, int index = -1);
+ void insertTab( TQWidget *child, const TQIconSet& iconset, const TQString &label, int index = -1);
+ void insertTab( TQWidget *, TQTab*, int index = -1 );
+
+ void changeTab( TQWidget *, const TQString &);
+ void changeTab( TQWidget *child, const TQIconSet& iconset, const TQString &label);
+
+ bool isTabEnabled( TQWidget * ) const;
+ void setTabEnabled( TQWidget *, bool );
+ bool isTabEnabled( const char* ) const; // compatibility
+ void setTabEnabled( const char*, bool ); // compatibility
+
+ void showPage( TQWidget * );
+ void removePage( TQWidget * );
+ TQString tabLabel( TQWidget * );
+
+ TQWidget * currentPage() const;
+
+ void setDefaultButton( const TQString &text );
+ void setDefaultButton();
+ bool hasDefaultButton() const;
+
+ void setHelpButton( const TQString &text );
+ void setHelpButton();
+ bool hasHelpButton() const;
+
+ void setCancelButton( const TQString &text );
+ void setCancelButton();
+ bool hasCancelButton() const;
+
+ void setApplyButton( const TQString &text );
+ void setApplyButton();
+ bool hasApplyButton() const;
+
+#ifndef TQ_TQDOC
+ void setOKButton( const TQString &text = TQString::null );
+#endif
+ void setOkButton( const TQString &text );
+ void setOkButton();
+ bool hasOkButton() const;
+
+protected:
+ void paintEvent( TQPaintEvent * );
+ void resizeEvent( TQResizeEvent * );
+ void styleChange( QStyle& );
+ void setTabBar( TQTabBar* );
+ TQTabBar* tabBar() const;
+
+Q_SIGNALS:
+ void aboutToShow();
+
+ void applyButtonPressed();
+ void cancelButtonPressed();
+ void defaultButtonPressed();
+ void helpButtonPressed();
+
+ void currentChanged( TQWidget * );
+ void selected( const TQString& ); // obsolete
+
+private Q_SLOTS:
+ void showTab( int i );
+
+private:
+ void setSizes();
+ void setUpLayout();
+
+ TQTabDialogPrivate *d;
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQTabDialog( const TQTabDialog & );
+ TQTabDialog& operator=( const TQTabDialog & );
+#endif
+};
+
+#endif // TQT_NO_TABDIALOG
+
+#endif // TQTABDIALOG_H
diff --git a/tqtinterface/qt4/src/dialogs/tqwizard.cpp b/tqtinterface/qt4/src/dialogs/tqwizard.cpp
new file mode 100644
index 0000000..c14b2cb
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqwizard.cpp
@@ -0,0 +1,917 @@
+/****************************************************************************
+**
+** Implementation of TQWizard class.
+**
+** Created : 990124
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwizard.h"
+
+#ifndef TQT_NO_WIZARD
+
+#include "tqlayout.h"
+#include "tqpushbutton.h"
+#include "tqcursor.h"
+#include "tqlabel.h"
+#include "tqwidgetstack.h"
+#include "tqapplication.h"
+#include "tqptrlist.h"
+#include "tqpainter.h"
+#include "tqaccel.h"
+
+/*! \file wizard/wizard.cpp */
+/*! \file wizard/wizard.h */
+
+/*!
+ \class TQWizard tqwizard.h
+ \brief The TQWizard class provides a framework for wizard dialogs.
+
+ \ingroup abstractwidgets
+ \ingroup organizers
+ \ingroup dialogs
+ \mainclass
+
+ A wizard is a special type of input dialog that consists of a
+ sequence of dialog pages. A wizard's purpose is to walk the user
+ through a process step by step. Wizards are useful for complex or
+ infrequently occurring tasks that people may tqfind difficult to
+ learn or do.
+
+ TQWizard provides page titles and displays Next, Back, Finish,
+ Cancel, and Help push buttons, as appropriate to the current
+ position in the page sequence. These buttons can be
+ enabled/disabled using setBackEnabled(), setNextEnabled(),
+ setFinishEnabled() and setHelpEnabled().
+
+ Create and populate dialog pages that inherit from TQWidget and add
+ them to the wizard using addPage(). Use insertPage() to add a
+ dialog page at a certain position in the page sequence. Use
+ removePage() to remove a page from the page sequence.
+
+ Use currentPage() to retrieve a pointer to the currently displayed
+ page. page() returns a pointer to the page at a certain position
+ in the page sequence.
+
+ Use pageCount() to retrieve the total number of pages in the page
+ sequence. indexOf() will return the index of a page in the page
+ sequence.
+
+ TQWizard provides functionality to mark pages as appropriate (or
+ not) in the current context with setAppropriate(). The idea is
+ that a page may be irrelevant and should be skipped depending on
+ the data entered by the user on a preceding page.
+
+ It is generally considered good design to provide a greater number
+ of simple pages with fewer choices rather than a smaller number of
+ complex pages.
+
+ Example code is available here: \l wizard/wizard.cpp \l wizard/wizard.h
+
+ \img qwizard.png A TQWizard page
+ \caption A TQWizard page
+
+*/
+
+
+class TQWizardPrivate
+{
+public:
+ struct Page {
+ Page( TQWidget * widget, const TQString & title ):
+ w( widget ), t( title ),
+ backEnabled( TRUE ), nextEnabled( TRUE ), finishEnabled( FALSE ),
+ helpEnabled( TRUE ),
+ appropriate( TRUE )
+ {}
+ TQWidget * w;
+ TQString t;
+ bool backEnabled;
+ bool nextEnabled;
+ bool finishEnabled;
+ bool helpEnabled;
+ bool appropriate;
+ };
+
+ TQVBoxLayout * v;
+ Page * current;
+ TQWidgetStack * ws;
+ TQPtrList<Page> pages;
+ TQLabel * title;
+ TQPushButton * backButton;
+ TQPushButton * nextButton;
+ TQPushButton * finishButton;
+ TQPushButton * cancelButton;
+ TQPushButton * helpButton;
+
+ TQFrame * hbar1, * hbar2;
+
+#ifndef TQT_NO_ACCEL
+ TQAccel * accel;
+ int backAccel;
+ int nextAccel;
+#endif
+
+ Page * page( const TQWidget * w )
+ {
+ if ( !w )
+ return 0;
+ int i = pages.count();
+ while( --i >= 0 && pages.at( i ) && pages.at( i )->w != w ) { }
+ return i >= 0 ? pages.at( i ) : 0;
+ }
+
+};
+
+
+/*!
+ Constructs an empty wizard dialog. The \a tqparent, \a name, \a
+ modal and \a f arguments are passed to the TQDialog constructor.
+*/
+
+TQWizard::TQWizard( TQWidget *tqparent, const char *name, bool modal,
+ WFlags f )
+ : TQDialog( tqparent, name, modal, f )
+{
+ d = new TQWizardPrivate();
+ d->current = 0; // not quite true, but...
+ d->ws = new TQWidgetStack( this, "qt_widgetstack" );
+ d->pages.setAutoDelete( TRUE );
+ d->title = new TQLabel( this, "title label" );
+
+ // create in nice tab order
+ d->nextButton = new TQPushButton( this, "next" );
+ d->finishButton = new TQPushButton( this, "finish" );
+ d->helpButton = new TQPushButton( this, "help" );
+ d->backButton = new TQPushButton( this, "back" );
+ d->cancelButton = new TQPushButton( this, "cancel" );
+
+ d->ws->installEventFilter( this );
+
+ d->v = 0;
+ d->hbar1 = 0;
+ d->hbar2 = 0;
+
+ d->cancelButton->setText( tr( "&Cancel" ) );
+ d->backButton->setText( tr( "< &Back" ) );
+ d->nextButton->setText( tr( "&Next >" ) );
+ d->finishButton->setText( tr( "&Finish" ) );
+ d->helpButton->setText( tr( "&Help" ) );
+
+ d->nextButton->setDefault( TRUE );
+
+ connect( d->backButton, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(back()) );
+ connect( d->nextButton, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(next()) );
+ connect( d->finishButton, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(accept()) );
+ connect( d->cancelButton, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(reject()) );
+ connect( d->helpButton, TQT_SIGNAL(clicked()),
+ this, TQT_SLOT(help()) );
+
+#ifndef TQT_NO_ACCEL
+ d->accel = new TQAccel( this, "arrow-key accel" );
+ d->backAccel = d->accel->insertItem( TQt::ALT + TQt::Key_Left );
+ d->accel->connectItem( d->backAccel, this, TQT_SLOT(back()) );
+ d->nextAccel = d->accel->insertItem( TQt::ALT + TQt::Key_Right );
+ d->accel->connectItem( d->nextAccel, this, TQT_SLOT(next()) );
+#endif
+}
+
+
+/*!
+ Destroys the object and frees any allocated resources, including
+ all pages and controllers.
+*/
+
+TQWizard::~TQWizard()
+{
+ delete d;
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQWizard::show()
+{
+ if ( !d->current ) {
+ // No page yet
+ if ( pageCount() > 0 )
+ showPage( d->pages.at( 0 )->w );
+ else
+ showPage( 0 );
+ }
+
+ TQDialog::show();
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQWizard::setFont( const TQFont & font )
+{
+ TQApplication::postEvent( this, new TQEvent( TQEvent::LayoutHint ) );
+ TQDialog::setFont( font );
+}
+
+
+/*!
+ Adds \a page to the end of the page sequence, with the title, \a
+ title.
+*/
+
+void TQWizard::addPage( TQWidget * page, const TQString & title )
+{
+ if ( !page )
+ return;
+ if ( d->page( page ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQWizard::addPage(): already added %s/%s to %s/%s",
+ page->className(), page->name(),
+ className(), name() );
+#endif
+ return;
+ }
+ int i = d->pages.count();
+
+ if( i > 0 )
+ d->pages.at( i - 1 )->nextEnabled = TRUE;
+
+ TQWizardPrivate::Page * p = new TQWizardPrivate::Page( page, title );
+ p->backEnabled = ( i > 0 );
+ d->ws->addWidget( page, i );
+ d->pages.append( p );
+}
+
+/*!
+ Inserts \a page at position \a index into the page sequence, with
+ title \a title. If \a index is -1, the page will be appended to
+ the end of the wizard's page sequence.
+*/
+
+void TQWizard::insertPage( TQWidget * page, const TQString & title, int index )
+{
+ if ( !page )
+ return;
+ if ( d->page( page ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQWizard::insertPage(): already added %s/%s to %s/%s",
+ page->className(), page->name(),
+ className(), name() );
+#endif
+ return;
+ }
+
+ if ( index < 0 || index > (int)d->pages.count() )
+ index = d->pages.count();
+
+ if( index > 0 && ( index == (int)d->pages.count() ) )
+ d->pages.at( index - 1 )->nextEnabled = TRUE;
+
+ TQWizardPrivate::Page * p = new TQWizardPrivate::Page( page, title );
+ p->backEnabled = ( index > 0 );
+ p->nextEnabled = ( index < (int)d->pages.count() );
+
+ d->ws->addWidget( page, index );
+ d->pages.insert( index, p );
+}
+
+/*!
+ \fn void TQWizard::selected(const TQString&)
+
+ This signal is emitted when the current page changes. The
+ parameter tqcontains the title of the selected page.
+*/
+
+
+/*!
+ Makes \a page the current page and emits the selected() signal.
+
+ This virtual function is called whenever a different page is to
+ be shown, including the first time the TQWizard is shown.
+ By reimplementing it (and calling TQWizard::showPage()),
+ you can prepare each page prior to it being shown.
+*/
+
+void TQWizard::showPage( TQWidget * page )
+{
+ TQWizardPrivate::Page * p = d->page( page );
+ if ( p ) {
+ int i;
+ for( i = 0; i < (int)d->pages.count() && d->pages.at( i ) != p; i++ );
+ bool notFirst( FALSE );
+
+ if( i ) {
+ i--;
+ while( ( i >= 0 ) && !notFirst ) {
+ notFirst |= appropriate( d->pages.at( i )->w );
+ i--;
+ }
+ }
+ setBackEnabled( notFirst );
+ setNextEnabled( TRUE );
+ d->ws->raiseWidget( page );
+ d->current = p;
+ }
+
+ layOut();
+ updateButtons();
+ emit selected( p ? p->t : TQString::null );
+}
+
+
+/*!
+ Returns the number of pages in the wizard.
+*/
+
+int TQWizard::pageCount() const
+{
+ return d->pages.count();
+}
+
+/*!
+ Returns the position of page \a page. If the page is not part of
+ the wizard -1 is returned.
+*/
+
+int TQWizard::indexOf( TQWidget* page ) const
+{
+ TQWizardPrivate::Page * p = d->page( page );
+ if ( !p ) return -1;
+
+ return d->pages.tqfind( p );
+}
+
+/*!
+ Called when the user clicks the Back button; this function shows
+ the preceding relevant page in the sequence.
+
+ \sa appropriate()
+*/
+void TQWizard::back()
+{
+ int i = 0;
+
+ while( i < (int)d->pages.count() && d->pages.at( i ) &&
+ d->current && d->pages.at( i )->w != d->current->w )
+ i++;
+
+ i--;
+ while( i >= 0 && ( !d->pages.at( i ) || !appropriate( d->pages.at( i )->w ) ) )
+ i--;
+
+ if( i >= 0 )
+ if( d->pages.at( i ) )
+ showPage( d->pages.at( i )->w );
+}
+
+
+/*!
+ Called when the user clicks the Next button, this function shows
+ the next relevant page in the sequence.
+
+ \sa appropriate()
+*/
+void TQWizard::next()
+{
+ int i = 0;
+ while( i < (int)d->pages.count() && d->pages.at( i ) &&
+ d->current && d->pages.at( i )->w != d->current->w )
+ i++;
+ i++;
+ while( i <= (int)d->pages.count()-1 &&
+ ( !d->pages.at( i ) || !appropriate( d->pages.at( i )->w ) ) )
+ i++;
+ // if we fell of the end of the world, step back
+ while ( i > 0 && (i >= (int)d->pages.count() || !d->pages.at( i ) ) )
+ i--;
+ if ( d->pages.at( i ) )
+ showPage( d->pages.at( i )->w );
+}
+
+
+/*!
+ \fn void TQWizard::helpClicked()
+
+ This signal is emitted when the user clicks on the Help button.
+*/
+
+/*!
+ Called when the user clicks the Help button, this function emits
+ the helpClicked() signal.
+*/
+
+void TQWizard::help()
+{
+ TQWidget * page = d->ws->visibleWidget();
+ if ( !page )
+ return;
+
+#if 0
+ TQWizardPage *wpage = ::tqqt_cast<TQWizardPage*>(page);
+ if ( wpage )
+ emit wpage->helpClicked();
+#endif
+ emit helpClicked();
+}
+
+
+void TQWizard::setBackEnabled( bool enable )
+{
+ d->backButton->setEnabled( enable );
+#ifndef TQT_NO_ACCEL
+ d->accel->setItemEnabled( d->backAccel, enable );
+#endif
+}
+
+
+void TQWizard::setNextEnabled( bool enable )
+{
+ d->nextButton->setEnabled( enable );
+#ifndef TQT_NO_ACCEL
+ d->accel->setItemEnabled( d->nextAccel, enable );
+#endif
+}
+
+
+void TQWizard::setHelpEnabled( bool enable )
+{
+ d->helpButton->setEnabled( enable );
+}
+
+
+/*!
+ \fn void TQWizard::setFinish( TQWidget *, bool )
+ \obsolete
+
+ Use setFinishEnabled instead
+*/
+
+/*!
+ If \a enable is TRUE, page \a page has a Back button; otherwise \a
+ page has no Back button. By default all pages have this button.
+*/
+void TQWizard::setBackEnabled( TQWidget * page, bool enable )
+{
+ TQWizardPrivate::Page * p = d->page( page );
+ if ( !p )
+ return;
+
+ p->backEnabled = enable;
+ updateButtons();
+}
+
+
+/*!
+ If \a enable is TRUE, page \a page has a Next button; otherwise
+ the Next button on \a page is disabled. By default all pages have
+ this button.
+*/
+
+void TQWizard::setNextEnabled( TQWidget * page, bool enable )
+{
+ TQWizardPrivate::Page * p = d->page( page );
+ if ( !p )
+ return;
+
+ p->nextEnabled = enable;
+ updateButtons();
+}
+
+
+/*!
+ If \a enable is TRUE, page \a page has a Finish button; otherwise
+ \a page has no Finish button. By default \e no page has this
+ button.
+*/
+void TQWizard::setFinishEnabled( TQWidget * page, bool enable )
+{
+ TQWizardPrivate::Page * p = d->page( page );
+ if ( !p )
+ return;
+
+ p->finishEnabled = enable;
+ updateButtons();
+}
+
+
+/*!
+ If \a enable is TRUE, page \a page has a Help button; otherwise \a
+ page has no Help button. By default all pages have this button.
+*/
+void TQWizard::setHelpEnabled( TQWidget * page, bool enable )
+{
+ TQWizardPrivate::Page * p = d->page( page );
+ if ( !p )
+ return;
+
+ p->helpEnabled = enable;
+ updateButtons();
+}
+
+
+/*!
+ Called when the Next button is clicked; this virtual function
+ returns TRUE if \a page is relevant for display in the current
+ context; otherwise it is ignored by TQWizard and returns FALSE. The
+ default implementation returns the value set using
+ setAppropriate(). The ultimate default is TRUE.
+
+ \warning The last page of the wizard will be displayed if no page
+ is relevant in the current context.
+*/
+
+bool TQWizard::appropriate( TQWidget * page ) const
+{
+ TQWizardPrivate::Page * p = d->page( page );
+ return p ? p->appropriate : TRUE;
+}
+
+
+/*!
+ If \a appropriate is TRUE then page \a page is considered relevant
+ in the current context and should be displayed in the page
+ sequence; otherwise \a page should not be displayed in the page
+ sequence.
+
+ \sa appropriate()
+*/
+void TQWizard::setAppropriate( TQWidget * page, bool appropriate )
+{
+ TQWizardPrivate::Page * p = d->page( page );
+ if ( p )
+ p->appropriate = appropriate;
+}
+
+
+void TQWizard::updateButtons()
+{
+ if ( !d->current )
+ return;
+
+ int i;
+ for( i = 0; i < (int)d->pages.count() && d->pages.at( i ) != d->current; i++ );
+ bool notFirst( FALSE );
+ if( i ) {
+ i--;
+ while( ( i >= 0 ) && !notFirst ) {
+ notFirst |= appropriate( d->pages.at( i )->w );
+ i--;
+ }
+ }
+ setBackEnabled( d->current->backEnabled && notFirst );
+ setNextEnabled( d->current->nextEnabled );
+ d->finishButton->setEnabled( d->current->finishEnabled );
+ d->helpButton->setEnabled( d->current->helpEnabled );
+
+ if ( ( d->current->finishEnabled && !d->finishButton->isVisible() ) ||
+ ( d->current->backEnabled && !d->backButton->isVisible() ) ||
+ ( d->current->nextEnabled && !d->nextButton->isVisible() ) ||
+ ( d->current->helpEnabled && !d->helpButton->isVisible() ) )
+ layOut();
+}
+
+
+/*!
+ Returns a pointer to the current page in the sequence. Although
+ the wizard does its best to make sure that this value is never 0,
+ it can be if you try hard enough.
+*/
+
+TQWidget * TQWizard::currentPage() const
+{
+ return d->ws->visibleWidget();
+}
+
+
+/*!
+ Returns the title of page \a page.
+*/
+
+TQString TQWizard::title( TQWidget * page ) const
+{
+ TQWizardPrivate::Page * p = d->page( page );
+ return p ? p->t : TQString::null;
+}
+
+/*!
+ Sets the title for page \a page to \a title.
+*/
+
+void TQWizard::setTitle( TQWidget *page, const TQString &title )
+{
+ TQWizardPrivate::Page * p = d->page( page );
+ if ( p )
+ p->t = title;
+ if ( page == currentPage() )
+ d->title->setText( title );
+}
+
+/*!
+ \property TQWizard::titleFont
+ \brief the font used for page titles
+
+ The default is TQApplication::font().
+*/
+TQFont TQWizard::titleFont() const
+{
+ return d->title->font();
+}
+
+void TQWizard::setTitleFont( const TQFont & font )
+{
+ d->title->setFont( font );
+}
+
+
+/*!
+ Returns a pointer to the dialog's Back button
+
+ By default, this button is connected to the back() slot, which is
+ virtual so you can reimplement it in a TQWizard subclass. Use
+ setBackEnabled() to enable/disable this button.
+*/
+TQPushButton * TQWizard::backButton() const
+{
+ return d->backButton;
+}
+
+
+/*!
+ Returns a pointer to the dialog's Next button
+
+ By default, this button is connected to the next() slot, which is
+ virtual so you can reimplement it in a TQWizard subclass. Use
+ setNextEnabled() to enable/disable this button.
+*/
+TQPushButton * TQWizard::nextButton() const
+{
+ return d->nextButton;
+}
+
+
+/*!
+ Returns a pointer to the dialog's Finish button
+
+ By default, this button is connected to the TQDialog::accept()
+ slot, which is virtual so you can reimplement it in a TQWizard
+ subclass. Use setFinishEnabled() to enable/disable this button.
+*/
+TQPushButton * TQWizard::finishButton() const
+{
+ return d->finishButton;
+}
+
+
+/*!
+ Returns a pointer to the dialog's Cancel button
+
+ By default, this button is connected to the TQDialog::reject()
+ slot, which is virtual so you can reimplement it in a TQWizard
+ subclass.
+*/
+TQPushButton * TQWizard::cancelButton() const
+{
+ return d->cancelButton;
+}
+
+
+/*!
+ Returns a pointer to the dialog's Help button
+
+ By default, this button is connected to the help() slot, which is
+ virtual so you can reimplement it in a TQWizard subclass. Use
+ setHelpEnabled() to enable/disable this button.
+*/
+TQPushButton * TQWizard::helpButton() const
+{
+ return d->helpButton;
+}
+
+
+/*!
+ This virtual function is responsible for adding the buttons below
+ the bottom divider.
+
+ \a tqlayout is the horizontal tqlayout of the entire wizard.
+*/
+
+void TQWizard::layOutButtonRow( TQHBoxLayout * tqlayout )
+{
+ bool hasHelp = FALSE;
+ bool hasEarlyFinish = FALSE;
+
+ int i = d->pages.count() - 2;
+ while ( !hasEarlyFinish && i >= 0 ) {
+ if ( d->pages.at( i ) && d->pages.at( i )->finishEnabled )
+ hasEarlyFinish = TRUE;
+ i--;
+ }
+ i = 0;
+ while ( !hasHelp && i < (int)d->pages.count() ) {
+ if ( d->pages.at( i ) && d->pages.at( i )->helpEnabled )
+ hasHelp = TRUE;
+ i++;
+ }
+
+ TQBoxLayout * h = new TQBoxLayout( TQBoxLayout::LeftToRight );
+ tqlayout->addLayout( h );
+
+ if ( hasHelp )
+ h->addWidget( d->helpButton );
+ else
+ d->helpButton->hide();
+
+ h->addStretch( 42 );
+
+ h->addWidget( d->backButton );
+
+ h->addSpacing( 6 );
+
+ if (d->current == d->pages.at( d->pages.count()-1 ))
+ hasEarlyFinish = FALSE;
+
+ if ( hasEarlyFinish ) {
+ d->nextButton->show();
+ d->finishButton->show();
+ h->addWidget( d->nextButton );
+ h->addSpacing( 12 );
+ h->addWidget( d->finishButton );
+ } else if ( d->pages.count() == 0 ||
+ d->current->finishEnabled ||
+ d->current == d->pages.at( d->pages.count()-1 ) ) {
+ d->nextButton->hide();
+ d->finishButton->show();
+ h->addWidget( d->finishButton );
+ } else {
+ d->nextButton->show();
+ d->finishButton->hide();
+ h->addWidget( d->nextButton );
+ }
+
+ // if last page is disabled - show finished btn. at lastpage-1
+ i = d->pages.count()-1;
+ if ( i >= 0 && !appropriate( d->pages.at( i )->w ) &&
+ d->current == d->pages.at( d->pages.count()-2 ) ) {
+ d->nextButton->hide();
+ d->finishButton->show();
+ h->addWidget( d->finishButton );
+ }
+
+ h->addSpacing( 12 );
+ h->addWidget( d->cancelButton );
+}
+
+
+/*!
+ This virtual function is responsible for laying out the title row.
+
+ \a tqlayout is the horizontal tqlayout for the wizard, and \a
+ title is the title for this page. This function is called every
+ time \a title changes.
+*/
+
+void TQWizard::layOutTitleRow( TQHBoxLayout * tqlayout, const TQString & title )
+{
+ d->title->setText( title );
+ tqlayout->addWidget( d->title, 10 );
+}
+
+
+/*
+
+*/
+
+void TQWizard::layOut()
+{
+ delete d->v;
+ d->v = new TQVBoxLayout( this, 6, 0, "top-level tqlayout" );
+
+ TQHBoxLayout * l;
+ l = new TQHBoxLayout( 6 );
+ d->v->addLayout( l, 0 );
+ layOutTitleRow( l, d->current ? d->current->t : TQString::null );
+
+ if ( ! d->hbar1 ) {
+ d->hbar1 = new TQFrame( this, "<hr>", 0 );
+ d->hbar1->setFrameStyle( TQFrame::Sunken + TQFrame::HLine );
+ d->hbar1->setFixedHeight( 12 );
+ }
+
+ d->v->addWidget( d->hbar1 );
+
+ d->v->addWidget( d->ws, 10 );
+
+ if ( ! d->hbar2 ) {
+ d->hbar2 = new TQFrame( this, "<hr>", 0 );
+ d->hbar2->setFrameStyle( TQFrame::Sunken + TQFrame::HLine );
+ d->hbar2->setFixedHeight( 12 );
+ }
+ d->v->addWidget( d->hbar2 );
+
+ l = new TQHBoxLayout( 6 );
+ d->v->addLayout( l );
+ layOutButtonRow( l );
+ d->v->activate();
+}
+
+
+/*!
+ \reimp
+*/
+
+bool TQWizard::eventFilter( TQObject * o, TQEvent * e )
+{
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->ws) && e && e->type() == TQEvent::ChildRemoved ) {
+ TQChildEvent * c = (TQChildEvent*)e;
+ if ( c->child() && c->child()->isWidgetType() )
+ removePage( (TQWidget *)c->child() );
+ }
+ return TQDialog::eventFilter( o, e );
+}
+
+
+/*!
+ Removes \a page from the page sequence but does not delete the
+ page. If \a page is currently being displayed, TQWizard will
+ display the page that precedes it, or the first page if this was
+ the first page.
+*/
+
+void TQWizard::removePage( TQWidget * page )
+{
+ if ( !page )
+ return;
+
+ int i = d->pages.count();
+ TQWidget* cp = currentPage();
+ while( --i >= 0 && d->pages.at( i ) && d->pages.at( i )->w != page ) { }
+ if ( i < 0 )
+ return;
+ TQWizardPrivate::Page * p = d->pages.at( i );
+ d->pages.removeRef( p );
+ d->ws->removeWidget( page );
+
+ if( cp == page ) {
+ i--;
+ if( i < 0 )
+ i = 0;
+ if ( pageCount() > 0 )
+ showPage( TQWizard::page( i ) );
+ }
+}
+
+
+/*!
+ Returns a pointer to the page at position \a index in the
+ sequence, or 0 if \a index is out of range. The first page has
+ index 0.
+*/
+
+TQWidget* TQWizard::page( int index ) const
+{
+ if ( index >= pageCount() || index < 0 )
+ return 0;
+
+ return d->pages.at( index )->w;
+}
+
+#endif // TQT_NO_WIZARD
diff --git a/tqtinterface/qt4/src/dialogs/tqwizard.h b/tqtinterface/qt4/src/dialogs/tqwizard.h
new file mode 100644
index 0000000..89f69f8
--- /dev/null
+++ b/tqtinterface/qt4/src/dialogs/tqwizard.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** Definition of the TQWizard class.
+**
+** Created : 990101
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the dialogs module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWIZARDDIALOG_H
+#define TQWIZARDDIALOG_H
+
+
+#ifndef TQT_H
+#include "tqdialog.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_WIZARD
+
+class TQHBoxLayout;
+class TQWizardPrivate;
+
+class TQ_EXPORT TQWizard : public TQDialog
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( TQFont titleFont READ titleFont WRITE setTitleFont )
+
+public:
+ TQWizard( TQWidget* tqparent=0, const char* name=0, bool modal=FALSE,
+ WFlags f=0 );
+ ~TQWizard();
+
+ void show();
+
+ void setFont( const TQFont & font );
+
+ virtual void addPage( TQWidget *, const TQString & );
+ virtual void insertPage( TQWidget*, const TQString&, int );
+ virtual void removePage( TQWidget * );
+
+ TQString title( TQWidget * ) const;
+ void setTitle( TQWidget *, const TQString & );
+ TQFont titleFont() const;
+ void setTitleFont( const TQFont & );
+
+ virtual void showPage( TQWidget * );
+
+ TQWidget * currentPage() const;
+
+ TQWidget* page( int ) const;
+ int pageCount() const;
+ int indexOf( TQWidget* ) const;
+
+ virtual bool appropriate( TQWidget * ) const;
+ virtual void setAppropriate( TQWidget *, bool );
+
+ TQPushButton * backButton() const;
+ TQPushButton * nextButton() const;
+ TQPushButton * finishButton() const;
+ TQPushButton * cancelButton() const;
+ TQPushButton * helpButton() const;
+
+ bool eventFilter( TQObject *, TQEvent * );
+
+public Q_SLOTS:
+ virtual void setBackEnabled( TQWidget *, bool );
+ virtual void setNextEnabled( TQWidget *, bool );
+ virtual void setFinishEnabled( TQWidget *, bool );
+
+ virtual void setHelpEnabled( TQWidget *, bool );
+
+ // obsolete
+ virtual void setFinish( TQWidget *, bool ) {}
+
+protected Q_SLOTS:
+ virtual void back();
+ virtual void next();
+ virtual void help();
+
+Q_SIGNALS:
+ void helpClicked();
+ void selected( const TQString& );
+
+protected:
+ virtual void layOutButtonRow( TQHBoxLayout * );
+ virtual void layOutTitleRow( TQHBoxLayout *, const TQString & );
+
+private:
+ void setBackEnabled( bool );
+ void setNextEnabled( bool );
+
+ void setHelpEnabled( bool );
+
+ void setNextPage( TQWidget * );
+
+ void updateButtons();
+
+ void layOut();
+
+ TQWizardPrivate *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQWizard( const TQWizard & );
+ TQWizard& operator=( const TQWizard & );
+#endif
+};
+
+#endif // TQT_NO_WIZARD
+
+#endif // TQWIZARD_H
diff --git a/tqtinterface/qt4/src/embedded/qt_embedded.pri b/tqtinterface/qt4/src/embedded/qt_embedded.pri
new file mode 100644
index 0000000..5bdbdef
--- /dev/null
+++ b/tqtinterface/qt4/src/embedded/qt_embedded.pri
@@ -0,0 +1,192 @@
+# Qt/Embedded Drivers
+
+embedded {
+ EMBEDDED_P = embedded
+
+ HEADERS += $$EMBEDDED_P/tqgfxdriverinterface_p.h \
+ $$EMBEDDED_H/tqgfxdriverplugin_qws.h \
+ $$EMBEDDED_H/tqgfxdriverfactory_qws.h \
+ $$EMBEDDED_H/tqkbd_qws.h \
+ $$EMBEDDED_P/tqkbddriverinterface_p.h \
+ $$EMBEDDED_H/tqkbddriverplugin_qws.h \
+ $$EMBEDDED_H/tqkbddriverfactory_qws.h \
+ $$EMBEDDED_H/tqmouse_qws.h \
+ $$EMBEDDED_P/tqmousedriverinterface_p.h \
+ $$EMBEDDED_H/tqmousedriverplugin_qws.h \
+ $$EMBEDDED_H/tqmousedriverfactory_qws.h
+
+ SOURCES += $$EMBEDDED_CPP/tqgfxdriverplugin_qws.cpp \
+ $$EMBEDDED_CPP/tqgfxdriverfactory_qws.cpp \
+ $$EMBEDDED_CPP/tqkbd_qws.cpp \
+ $$EMBEDDED_CPP/tqkbddriverplugin_qws.cpp \
+ $$EMBEDDED_CPP/tqkbddriverfactory_qws.cpp \
+ $$EMBEDDED_CPP/tqmouse_qws.cpp \
+ $$EMBEDDED_CPP/tqmousedriverplugin_qws.cpp \
+ $$EMBEDDED_CPP/tqmousedriverfactory_qws.cpp
+
+#
+# Graphics drivers
+#
+ linux-* {
+ HEADERS += $$EMBEDDED_H/tqgfxlinuxfb_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxlinuxfb_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_LINUXFB
+
+ tqcontains( gfx-drivers, qvfb ) {
+ HEADERS += $$EMBEDDED_H/tqgfxvfb_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxvfb_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_VFB
+
+ tqcontains( gfx-drivers, vnc ) {
+ HEADERS += $$EMBEDDED_H/tqgfxvnc_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxvnc_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_VNC
+
+ !tqcontains( DEFINES, TQT_NO_QWS_LINUXFB):tqcontains( gfx-drivers, vga16 ) {
+ HEADERS += $$EMBEDDED_H/tqgfxvga16_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxvga16_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_VGA16
+
+ tqcontains( gfx-drivers, transformed ) {
+ HEADERS += $$EMBEDDED_H/tqgfxtransformed_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxtransformed_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_TRANSFORMED
+
+ tqcontains( gfx-drivers, snap ) {
+ exists( $(SCITECH)/include/snap/graphics.h) {
+ HEADERS += $$EMBEDDED_H/tqgfxsnap_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxsnap_qws.cpp
+ INCLUDEPATH += $(SCITECH)/include
+ debug:LIBS += -L$(SCITECH)/lib/debug/linux/gcc/x86/so -lpm
+ else:LIBS += -L$(SCITECH)/lib/release/linux/gcc/x86/so -lpm
+ }
+ else {
+ message("SciTech SNAP SDK is not properly set up! Please make sure the SCITECH")
+ message("environment variable is pointing to the SciTech SNAP SDK.")
+ error("Please fix and re-build the makefiles.")
+ }
+ }
+ else:DEFINES += TQT_NO_QWS_SNAP
+
+ tqcontains( gfx-drivers, mach64 ) {
+ HEADERS += $$EMBEDDED_H/tqgfxmach64_qws.h \
+ $$EMBEDDED_H/tqgfxmach64defs_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxmach64_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_MACH64
+
+ tqcontains( gfx-drivers, voodoo ) {
+ HEADERS += $$EMBEDDED_H/tqgfxvoodoo_qws.h \
+ $$EMBEDDED_H/tqgfxvoodoodefs_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxvoodoo_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_VOODOO3
+
+ tqcontains( gfx-drivers, matrox ) {
+ HEADERS += $$EMBEDDED_H/tqgfxmatrox_qws.h \
+ $$EMBEDDED_H/tqgfxmatroxdefs_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxmatrox_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_MATROX
+
+ tqcontains( gfx-drivers, shadowfb ) {
+ HEADERS += $$EMBEDDED_H/tqgfxshadow_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxshadow_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_SHADOWFB
+
+ tqcontains( gfx-drivers, repeater ) {
+ HEADERS += $$EMBEDDED_H/tqgfxrepeater_qws.h
+ SOURCES += $$EMBEDDED_CPP/tqgfxrepeater_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_REPEATER
+
+#
+# Keyboard drivers
+#
+
+ tqcontains( kbd-drivers, sl5000 ) {
+ HEADERS +=$$EMBEDDED_H/tqkbdsl5000_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqkbdsl5000_qws.cpp
+ !tqcontains( kbd-drivers, tty ) {
+ kbd-drivers += tty
+ }
+ }
+ else:DEFINES += TQT_NO_QWS_KBD_SL5000
+
+ tqcontains( kbd-drivers, tty ) {
+ HEADERS +=$$EMBEDDED_H/tqkbdtty_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqkbdtty_qws.cpp
+ !tqcontains( kbd-drivers, pc101 ) {
+ kbd-drivers += pc101
+ }
+ }
+ else:DEFINES += TQT_NO_QWS_KBD_TTY
+
+ tqcontains( kbd-drivers, usb ) {
+ HEADERS +=$$EMBEDDED_H/tqkbdusb_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqkbdusb_qws.cpp
+ !tqcontains( kbd-drivers, pc101 ) {
+ kbd-drivers += pc101
+ }
+ }
+ else:DEFINES += TQT_NO_QWS_KBD_USB
+
+ tqcontains( kbd-drivers, pc101 ) {
+ HEADERS +=$$EMBEDDED_H/tqkbdpc101_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqkbdpc101_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_KBD_PC101
+
+ tqcontains( kbd-drivers, yopy ) {
+ HEADERS +=$$EMBEDDED_H/tqkbdyopy_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqkbdyopy_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_KBD_YOPY
+
+ tqcontains( kbd-drivers, vr41xx ) {
+ HEADERS +=$$EMBEDDED_H/tqkbdvr41xx_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqkbdvr41xx_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_KBD_VR41
+
+#
+# Mouse drivers
+#
+
+ tqcontains( mouse-drivers, pc ) {
+ HEADERS +=$$EMBEDDED_H/tqmousepc_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqmousepc_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_MOUSE_PC
+
+ tqcontains( mouse-drivers, bus ) {
+ HEADERS +=$$EMBEDDED_H/tqmousebus_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqmousebus_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_MOUSE_BUS
+
+ tqcontains( mouse-drivers, linuxtp ) {
+ HEADERS +=$$EMBEDDED_H/tqmouselinuxtp_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqmouselinuxtp_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_MOUSE_LINUXTP
+
+ tqcontains( mouse-drivers, vr41xx ) {
+ HEADERS +=$$EMBEDDED_H/tqmousevr41xx_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqmousevr41xx_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_MOUSE_VR41
+
+ tqcontains( mouse-drivers, yopy ) {
+ HEADERS +=$$EMBEDDED_H/tqmouseyopy_qws.h
+ SOURCES +=$$EMBEDDED_CPP/tqmouseyopy_qws.cpp
+ }
+ else:DEFINES += TQT_NO_QWS_MOUSE_YOPY
+}
+
diff --git a/tqtinterface/qt4/src/embedded/tqgfxdriverinterface_p.h b/tqtinterface/qt4/src/embedded/tqgfxdriverinterface_p.h
new file mode 100644
index 0000000..ed48505
--- /dev/null
+++ b/tqtinterface/qt4/src/embedded/tqgfxdriverinterface_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Definition of TQt/Embedded Graphics Driver Interface
+**
+** Created : 20020211
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGFXDRIVERINTERFACE_P_H
+#define TQGFXDRIVERINTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include <private/tqcom_p.h>
+#endif // TQT_H
+
+#ifndef TQT_NO_COMPONENT
+
+// {449EC6C6-DF3E-43E3-9E57-354A3D05AB34}
+#ifndef IID_TQGfxDriver
+#define IID_TQGfxDriver TQUuid( 0x449ec6c6, 0xdf3e, 0x43e3, 0x9e, 0x57, 0x35, 0x4a, 0x3d, 0x05, 0xab, 0x34)
+#endif
+
+class TQScreen;
+
+struct TQ_EXPORT TQGfxDriverInterface : public TQFeatureListInterface
+{
+ virtual TQScreen* create( const TQString& driver, int displayId ) = 0;
+};
+
+#endif // TQT_NO_COMPONENT
+
+#endif // TQGFXDRIVERINTERFACE_P_H
diff --git a/tqtinterface/qt4/src/embedded/tqkbddriverinterface_p.h b/tqtinterface/qt4/src/embedded/tqkbddriverinterface_p.h
new file mode 100644
index 0000000..d7c8f17
--- /dev/null
+++ b/tqtinterface/qt4/src/embedded/tqkbddriverinterface_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Definition of TQt/Embedded Keyboard Driver Interface
+**
+** Created : 20020218
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQKBDDRIVERINTERFACE_P_H
+#define TQKBDDRIVERINTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include <private/tqcom_p.h>
+#endif // TQT_H
+
+#ifndef TQT_NO_COMPONENT
+
+// {C7C838EA-FC3E-4905-92AD-F479E81F1D02}
+#ifndef IID_TQKbdDriver
+#define IID_TQKbdDriver TQUuid( 0xc7c838ea, 0xfc3e, 0x4905, 0x92, 0xad, 0xf4, 0x79, 0xe8, 0x1f, 0x1d, 0x02)
+#endif
+
+class TQWSKeyboardHandler;
+
+struct TQ_EXPORT TQKbdDriverInterface : public TQFeatureListInterface
+{
+ virtual TQWSKeyboardHandler* create( const TQString& driver, const TQString& tqdevice ) = 0;
+};
+
+#endif // TQT_NO_COMPONENT
+
+#endif // TQKBDDRIVERINTERFACE_P_H
diff --git a/tqtinterface/qt4/src/embedded/tqmousedriverinterface_p.h b/tqtinterface/qt4/src/embedded/tqmousedriverinterface_p.h
new file mode 100644
index 0000000..be8d2e1
--- /dev/null
+++ b/tqtinterface/qt4/src/embedded/tqmousedriverinterface_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Definition of TQt/Embedded Mouse Driver Interface
+**
+** Created : 20020220
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMOUSEDRIVERINTERFACE_P_H
+#define TQMOUSEDRIVERINTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include <private/tqcom_p.h>
+#endif // TQT_H
+
+#ifndef TQT_NO_COMPONENT
+
+// {4367CF5A-F7CE-407B-8BB6-DF19AEDA2EBB}
+#ifndef IID_TQMouseDriver
+#define IID_TQMouseDriver TQUuid( 0x4367cf5a, 0xf7ce, 0x407b, 0x8b, 0xb6, 0xdf, 0x19, 0xae, 0xda, 0x2e, 0xbb)
+#endif
+
+class TQWSMouseHandler;
+
+struct TQ_EXPORT TQMouseDriverInterface : public TQFeatureListInterface
+{
+ virtual TQWSMouseHandler* create( const TQString& driver, const TQString &tqdevice ) = 0;
+};
+
+#endif // TQT_NO_COMPONENT
+
+#endif // TQMOUSEDRIVERINTERFACE_P_H
diff --git a/tqtinterface/qt4/src/iconview/qt_iconview.pri b/tqtinterface/qt4/src/iconview/qt_iconview.pri
new file mode 100644
index 0000000..128362c
--- /dev/null
+++ b/tqtinterface/qt4/src/iconview/qt_iconview.pri
@@ -0,0 +1,6 @@
+# Qt iconview module
+
+iconview {
+ HEADERS += $$ICONVIEW_H/tqiconview.h
+ SOURCES += $$ICONVIEW_CPP/tqiconview.cpp
+}
diff --git a/tqtinterface/qt4/src/iconview/tqiconview.cpp b/tqtinterface/qt4/src/iconview/tqiconview.cpp
new file mode 100644
index 0000000..e95ff47
--- /dev/null
+++ b/tqtinterface/qt4/src/iconview/tqiconview.cpp
@@ -0,0 +1,6416 @@
+/****************************************************************************
+**
+** Implementation of TQIconView widget class
+**
+** Created : 990707
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the iconview module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqglobal.h"
+#if defined(TQ_CC_BOR)
+// needed for qsort() because of a std namespace problem on Borland
+#include "tqplatformdefs.h"
+#endif
+
+#include "tqiconview.h"
+
+#ifndef TQT_NO_ICONVIEW
+
+#include "tqfontmetrics.h"
+#include "tqpainter.h"
+#include "tqevent.h"
+#include "tqpalette.h"
+#include "tqmime.h"
+#include "tqimage.h"
+#include "tqpen.h"
+#include "tqbrush.h"
+#include "tqtimer.h"
+#include "tqcursor.h"
+#include "tqapplication.h"
+#include "tqtextedit.h"
+#include "tqmemarray.h"
+#include "tqptrlist.h"
+#include "tqvbox.h"
+#include "tqtooltip.h"
+#include "tqbitmap.h"
+#include "tqpixmapcache.h"
+#include "tqptrdict.h"
+#include "tqstringlist.h"
+#include "tqcleanuphandler.h"
+#include "private/tqrichtext_p.h"
+#include "tqstyle.h"
+
+#include <limits.h>
+#include <stdlib.h>
+
+#define RECT_EXTENSION 300
+
+static const char * const unknown_xpm[] = {
+ "32 32 11 1",
+ "c c #ffffff",
+ "g c #c0c0c0",
+ "a c #c0ffc0",
+ "h c #a0a0a4",
+ "d c #585858",
+ "f c #303030",
+ "i c #400000",
+ "b c #00c000",
+ "e c #000000",
+ "# c #000000",
+ ". c None",
+ "...###..........................",
+ "...#aa##........................",
+ ".###baaa##......................",
+ ".#cde#baaa##....................",
+ ".#cccdeebaaa##..##f.............",
+ ".#cccccdeebaaa##aaa##...........",
+ ".#cccccccdeebaaaaaaaa##.........",
+ ".#cccccccccdeebaaaaaaa#.........",
+ ".#cccccgcgghhebbbbaaaaa#........",
+ ".#ccccccgcgggdebbbbbbaa#........",
+ ".#cccgcgcgcgghdeebiebbba#.......",
+ ".#ccccgcggggggghdeddeeba#.......",
+ ".#cgcgcgcggggggggghghdebb#......",
+ ".#ccgcggggggggghghghghd#b#......",
+ ".#cgcgcggggggggghghghhd#b#......",
+ ".#gcggggggggghghghhhhhd#b#......",
+ ".#cgcggggggggghghghhhhd#b#......",
+ ".#ggggggggghghghhhhhhhdib#......",
+ ".#gggggggggghghghhhhhhd#b#......",
+ ".#hhggggghghghhhhhhhhhd#b#......",
+ ".#ddhhgggghghghhhhhhhhd#b#......",
+ "..##ddhhghghhhhhhhhhhhdeb#......",
+ "....##ddhhhghhhhhhhhhhd#b#......",
+ "......##ddhhhhhhhhhhhhd#b#......",
+ "........##ddhhhhhhhhhhd#b#......",
+ "..........##ddhhhhhhhhd#b#......",
+ "............##ddhhhhhhd#b###....",
+ "..............##ddhhhhd#b#####..",
+ "................##ddhhd#b######.",
+ "..................##dddeb#####..",
+ "....................##d#b###....",
+ "......................####......"};
+
+static TQPixmap *unknown_icon = 0;
+static TQPixmap *qiv_buffer_pixmap = 0;
+#if !defined(TQ_WS_X11)
+static TQPixmap *qiv_selection = 0;
+#endif
+static bool optimize_tqlayout = FALSE;
+
+static TQCleanupHandler<TQPixmap> qiv_cleanup_pixmap;
+
+#if !defined(TQ_WS_X11)
+static void createSelectionPixmap( const TQColorGroup &cg )
+{
+ TQBitmap m( 2, 2 );
+ m.fill( TQt::color1 );
+ TQPainter p( &m );
+ p.setPen( TQt::color0 );
+ for ( int j = 0; j < 2; ++j ) {
+ p.drawPoint( j % 2, j );
+ }
+ p.end();
+
+ qiv_selection = new TQPixmap( 2, 2 );
+ qiv_cleanup_pixmap.add( &qiv_selection );
+ qiv_selection->fill( TQt::color0 );
+ qiv_selection->setMask( m );
+ qiv_selection->fill( cg.highlight() );
+}
+#endif
+
+static TQPixmap *get_qiv_buffer_pixmap( const TQSize &s )
+{
+ if ( !qiv_buffer_pixmap ) {
+ qiv_buffer_pixmap = new TQPixmap( s );
+ qiv_cleanup_pixmap.add( &qiv_buffer_pixmap );
+ return qiv_buffer_pixmap;
+ }
+
+ qiv_buffer_pixmap->resize( s );
+ return qiv_buffer_pixmap;
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+class TQM_EXPORT_ICONVIEW TQIconDragData
+{
+public:
+ TQIconDragData();
+ TQIconDragData( const TQRect &ir, const TQRect &tr );
+
+ TQRect pixmapRect() const;
+ TQRect textRect() const;
+
+ void setPixmapRect( const TQRect &r );
+ void setTextRect( const TQRect &r );
+
+ TQRect iconRect_, textRect_;
+ TQString key_;
+
+ bool operator==( const TQIconDragData &i ) const;
+};
+
+class TQM_EXPORT_ICONVIEW TQIconDragDataItem
+{
+public:
+ TQIconDragDataItem() {}
+ TQIconDragDataItem( const TQIconDragItem &i1, const TQIconDragData &i2 ) : data( i1 ), item( i2 ) {}
+ TQIconDragItem data;
+ TQIconDragData item;
+ bool operator== ( const TQIconDragDataItem& ) const;
+};
+
+class TQIconDragPrivate
+{
+public:
+ TQValueList<TQIconDragDataItem> items;
+ static bool decode( TQMimeSource* e, TQValueList<TQIconDragDataItem> &lst );
+};
+
+#endif
+
+class TQIconViewToolTip;
+
+class TQIconViewPrivate
+{
+public:
+ TQIconViewItem *firstItem, *lastItem;
+ uint count;
+ TQIconView::SelectionMode selectionMode;
+ TQIconViewItem *currentItem, *tmpCurrentItem, *highlightedItem,
+ *startDragItem, *pressedItem, *selectAnchor, *renamingItem;
+ TQRect *rubber;
+ TQTimer *scrollTimer, *adjustTimer, *updateTimer, *inputTimer,
+ *fullRedrawTimer;
+ int rastX, rastY, spacing;
+ int dragItems;
+ TQPoint oldDragPos;
+ TQIconView::Arrangement arrangement;
+ TQIconView::ResizeMode resizeMode;
+ TQSize oldSize;
+#ifndef TQT_NO_DRAGANDDROP
+ TQValueList<TQIconDragDataItem> iconDragData;
+#endif
+ int numDragItems, cachedW, cachedH;
+ int maxItemWidth, maxItemTextLength;
+ TQPoint dragStart;
+ TQString currInputString;
+ TQIconView::ItemTextPos itemTextPos;
+#ifndef TQT_NO_CURSOR
+ TQCursor oldCursor;
+#endif
+ int cachedContentsX, cachedContentsY;
+ TQBrush itemTextBrush;
+ TQRegion clipRegion;
+ TQPoint dragStartPos;
+ TQFontMetrics *fm;
+ int minLeftBearing, minRightBearing;
+
+ uint mousePressed :1;
+ uint cleared :1;
+ uint dropped :1;
+ uint clearing :1;
+ uint oldDragAcceptAction :1;
+ uint isIconDrag :1;
+ uint drawDragShapes :1;
+ uint dirty :1;
+ uint rearrangeEnabled :1;
+ uint reorderItemsWhenInsert :1;
+ uint drawAllBack :1;
+ uint resortItemsWhenInsert :1;
+ uint sortDirection :1;
+ uint wordWrapIconText :1;
+ uint containerUpdateLocked :1;
+ uint firstSizeHint : 1;
+ uint showTips :1;
+ uint pressedSelected :1;
+ uint dragging :1;
+ uint drawActiveSelection :1;
+ uint inMenuMode :1;
+
+ TQIconViewToolTip *toolTip;
+ TQPixmapCache maskCache;
+ TQPtrDict<TQIconViewItem> selectedItems;
+
+ struct ItemContainer {
+ ItemContainer( ItemContainer *pr, ItemContainer *nx, const TQRect &r )
+ : p( pr ), n( nx ), rect( r ) {
+ items.setAutoDelete( FALSE );
+ if ( p )
+ p->n = this;
+ if ( n )
+ n->p = this;
+ }
+ ItemContainer *p, *n;
+ TQRect rect;
+ TQPtrList<TQIconViewItem> items;
+ } *firstContainer, *lastContainer;
+
+ struct SortableItem {
+ TQIconViewItem *item;
+ };
+
+public:
+
+ /* tqfinds the containers that intersect with \a searchRect in the direction \a dir relative to \a relativeTo */
+ TQPtrList<ItemContainer>* tqfindContainers(
+ TQIconView:: Direction dir,
+ const TQPoint &relativeTo,
+ const TQRect &searchRect ) const;
+ // friend int cmpIconViewItems( const void *n1, const void *n2 );
+};
+
+
+TQPtrList<TQIconViewPrivate::ItemContainer>* TQIconViewPrivate::tqfindContainers(
+ TQIconView:: Direction dir,
+ const TQPoint &relativeTo,
+ const TQRect &searchRect ) const
+{
+
+ TQPtrList<TQIconViewPrivate::ItemContainer>* list =
+ new TQPtrList<TQIconViewPrivate::ItemContainer>();
+
+ if ( arrangement == TQIconView::LeftToRight ) {
+ if ( dir == TQIconView::DirLeft || dir == TQIconView::DirRight ) {
+ ItemContainer *c = firstContainer;
+ for ( ; c; c = c->n )
+ if ( c->rect.intersects( searchRect ) )
+ list->append( c );
+ } else {
+ if ( dir == TQIconView::DirDown ) {
+ ItemContainer *c = firstContainer;
+ for ( ; c; c = c->n )
+ if ( c->rect.intersects( searchRect ) &&
+ c->rect.bottom() >= relativeTo.y() )
+ list->append( c );
+ } else {
+ ItemContainer *c = lastContainer;
+ for ( ; c; c = c->p )
+ if ( c->rect.intersects( searchRect ) &&
+ c->rect.top() <= relativeTo.y() )
+ list->append( c );
+ }
+ }
+ } else {
+ if ( dir == TQIconView::DirUp || dir == TQIconView::DirDown ) {
+ ItemContainer *c = firstContainer;
+ for ( ; c; c = c->n )
+ if ( c->rect.intersects( searchRect ) )
+ list->append( c );
+ } else {
+ if ( dir == TQIconView::DirRight ) {
+ ItemContainer *c = firstContainer;
+ for ( ; c; c = c->n )
+ if ( c->rect.intersects( searchRect ) &&
+ c->rect.right() >= relativeTo.x() )
+ list->append( c );
+ } else {
+ ItemContainer *c = lastContainer;
+ for ( ; c; c = c->p )
+ if ( c->rect.intersects( searchRect ) &&
+ c->rect.left() <= relativeTo.x() )
+ list->append( c );
+ }
+ }
+ }
+ return list;
+}
+
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+#ifdef TQ_OS_TEMP
+static int _cdecl cmpIconViewItems( const void *n1, const void *n2 )
+#else
+static int cmpIconViewItems( const void *n1, const void *n2 )
+#endif
+{
+ if ( !n1 || !n2 )
+ return 0;
+
+ TQIconViewPrivate::SortableItem *i1 = (TQIconViewPrivate::SortableItem *)n1;
+ TQIconViewPrivate::SortableItem *i2 = (TQIconViewPrivate::SortableItem *)n2;
+
+ return i1->item->compare( i2->item );
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+#ifndef TQT_NO_TOOLTIP
+class TQIconViewToolTip : public TQToolTip
+{
+public:
+ TQIconViewToolTip( TQWidget *tqparent, TQIconView *iv );
+
+ void maybeTip( const TQPoint &pos );
+
+private:
+ TQIconView *view;
+};
+
+TQIconViewToolTip::TQIconViewToolTip( TQWidget *tqparent, TQIconView *iv )
+ : TQToolTip( tqparent ), view( iv )
+{
+}
+
+void TQIconViewToolTip::maybeTip( const TQPoint &pos )
+{
+ if ( !parentWidget() || !view || view->wordWrapIconText() || !view->showToolTips() )
+ return;
+
+ TQIconViewItem *item = view->tqfindItem( view->viewportToContents( pos ) );
+ if ( !item || item->tmpText == item->itemText )
+ return;
+
+ TQRect r( item->textRect( FALSE ) );
+ TQRect r2 = item->pixmapRect( FALSE );
+ /* this probably should be | r, but TQToolTip does not handle that
+ * well */
+
+ // At this point the rectangle is too small (it is the width of the icon)
+ // since we need it to be bigger than that, extend it here.
+ r.setWidth( view->d->fm->boundingRect( item->itemText ).width() + 4 );
+ r = TQRect( view->contentsToViewport( TQPoint( r.x(), r.y() ) ), TQSize( r.width(), r.height() ) );
+
+ r2 = TQRect( view->contentsToViewport( TQPoint( r2.x(), r2.y() ) ), TQSize( r2.width(), r2.height() ) );
+ tip( r2, item->itemText, r );
+}
+#endif
+
+
+class TQIconViewItemPrivate
+{
+public:
+ TQIconViewPrivate::ItemContainer *container1, *container2;
+};
+
+#ifndef TQT_NO_TEXTEDIT
+
+class TQIconViewItemLineEdit : public TQTextEdit
+{
+ friend class TQIconViewItem;
+
+public:
+ TQIconViewItemLineEdit( const TQString &text, TQWidget *tqparent, TQIconViewItem *theItem, const char* name=0 );
+
+protected:
+ void keyPressEvent( TQKeyEvent *e );
+ void focusOutEvent( TQFocusEvent *e );
+
+protected:
+ TQIconViewItem *item;
+ TQString startText;
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQIconViewItemLineEdit( const TQIconViewItemLineEdit & );
+ TQIconViewItemLineEdit &operator=( const TQIconViewItemLineEdit & );
+#endif
+
+};
+
+TQIconViewItemLineEdit::TQIconViewItemLineEdit( const TQString &text, TQWidget *tqparent,
+ TQIconViewItem *theItem, const char *name )
+ : TQTextEdit( tqparent, name ), item( theItem ), startText( text )
+{
+ setFrameStyle( TQFrame::Plain | TQFrame::Box );
+ setLineWidth( 1 );
+
+ setHScrollBarMode( AlwaysOff );
+ setVScrollBarMode( AlwaysOff );
+
+ setWordWrap( WidgetWidth );
+ setWrapColumnOrWidth( item->iconView()->maxItemWidth() -
+ ( item->iconView()->itemTextPos() == TQIconView::Bottom ?
+ 0 : item->pixmapRect().width() ) );
+ document()->formatter()->setAllowBreakInWords( TRUE );
+ resize( 200, 200 ); // ### some size, there should be a forceReformat()
+ setTextFormat( TQt::PlainText );
+ setText( text );
+ tqsetAlignment( TQt::AlignCenter );
+
+ resize( wrapColumnOrWidth() + 2, heightForWidth( wrapColumnOrWidth() ) + 2 );
+}
+
+void TQIconViewItemLineEdit::keyPressEvent( TQKeyEvent *e )
+{
+ if ( e->key() == Key_Escape ) {
+ item->TQIconViewItem::setText( startText );
+ item->cancelRenameItem();
+ } else if ( e->key() == Qt::Key_Enter ||
+ e->key() == Qt::Key_Return ) {
+ item->renameItem();
+ } else {
+ TQTextEdit::keyPressEvent( e );
+ sync();
+ resize( width(), document()->height() + 2 );
+
+ }
+}
+
+void TQIconViewItemLineEdit::focusOutEvent( TQFocusEvent *e )
+{
+ TQ_UNUSED(e) // I need this to get rid of a Borland warning
+ if ( e->reason() != TQFocusEvent::Popup )
+ item->cancelRenameItem();
+}
+#endif
+
+#ifndef TQT_NO_DRAGANDDROP
+
+
+/*!
+ \class TQIconDragItem tqiconview.h
+ \ingroup draganddrop
+
+ \brief The TQIconDragItem class encapsulates a drag item.
+
+ \module iconview
+
+ The TQIconDrag class uses a list of TQIconDragItems to support drag
+ and drop operations.
+
+ In practice a TQIconDragItem object (or an object of a class derived
+ from TQIconDragItem) is created for each icon view item which is
+ dragged. Each of these TQIconDragItems is stored in a TQIconDrag
+ object.
+
+ See TQIconView::dragObject() for more information.
+
+ See the \l fileiconview/qfileiconview.cpp and
+ \l iconview/simple_dd/main.cpp examples.
+*/
+
+/*!
+ Constructs a TQIconDragItem with no data.
+*/
+
+TQIconDragItem::TQIconDragItem()
+ : ba( (int)strlen( "no data" ) )
+{
+ memcpy( ba.data(), "no data", strlen( "no data" ) );
+}
+
+/*!
+ Destructor.
+*/
+
+TQIconDragItem::~TQIconDragItem()
+{
+}
+
+/*!
+ Returns the data contained in the TQIconDragItem.
+*/
+
+TQByteArray TQIconDragItem::data() const
+{
+ return ba;
+}
+
+/*!
+ Sets the data for the TQIconDragItem to the data stored in the
+ TQByteArray \a d.
+*/
+
+void TQIconDragItem::setData( const TQByteArray &d )
+{
+ ba = d;
+}
+
+/*!
+ \reimp
+*/
+
+bool TQIconDragItem::operator==( const TQIconDragItem &i ) const
+{
+ return ba == i.ba;
+}
+
+/*!
+ \reimp
+*/
+
+bool TQIconDragDataItem::operator==( const TQIconDragDataItem &i ) const
+{
+ return ( i.item == item &&
+ i.data == data );
+}
+
+/*!
+ \reimp
+*/
+
+bool TQIconDragData::operator==( const TQIconDragData &i ) const
+{
+ return key_ == i.key_;
+}
+
+
+/*!
+ \class TQIconDrag tqiconview.h
+
+ \brief The TQIconDrag class supports drag and drop operations
+ within a TQIconView.
+
+ \ingroup draganddrop
+ \module iconview
+
+ A TQIconDrag object is used to maintain information about the
+ positions of dragged items and the data associated with the
+ dragged items. TQIconViews are able to use this information to
+ paint the dragged items in the correct positions. Internally
+ TQIconDrag stores the data associated with drag items in
+ TQIconDragItem objects.
+
+ If you want to use the extended drag-and-drop functionality of
+ TQIconView, create a TQIconDrag object in a reimplementation of
+ TQIconView::dragObject(). Then create a TQIconDragItem for each item
+ which should be dragged, set the data it represents with
+ TQIconDragItem::setData(), and add each TQIconDragItem to the drag
+ object using append().
+
+ The data in TQIconDragItems is stored in a TQByteArray and is
+ mime-typed (see TQMimeSource and the
+ \link http://doc.trolltech.com/dnd.html Drag and Drop\endlink
+ overview). If you want to use your own mime-types derive a class
+ from TQIconDrag and reimplement format(), tqencodedData() and
+ canDecode().
+
+ The fileiconview example program demonstrates the use of the
+ TQIconDrag class including subclassing and reimplementing
+ dragObject(), format(), tqencodedData() and canDecode(). See the files
+ \c qt/examples/fileiconview/qfileiconview.h and
+ \c qt/examples/fileiconview/qfileiconview.cpp.
+
+ \sa TQMimeSource::format()
+*/
+// ### consider using \dontinclude and friends there
+// ### Not here in the module overview instead...
+
+/*!
+ Constructs a drag object called \a name, which is a child of \a
+ dragSource.
+
+ Note that the drag object will be deleted when \a dragSource is deleted.
+*/
+
+TQIconDrag::TQIconDrag( TQWidget * dragSource, const char* name )
+ : TQDragObject( dragSource, name )
+{
+ d = new TQIconDragPrivate;
+}
+
+/*!
+ Destructor.
+*/
+
+TQIconDrag::~TQIconDrag()
+{
+ delete d;
+}
+
+/*!
+ Append the TQIconDragItem, \a i, to the TQIconDrag object's list of
+ items. You must also supply the tqgeometry of the pixmap, \a pr, and
+ the textual caption, \a tr.
+
+ \sa TQIconDragItem
+*/
+
+void TQIconDrag::append( const TQIconDragItem &i, const TQRect &pr, const TQRect &tr )
+{
+ d->items.append( TQIconDragDataItem( i, TQIconDragData( pr, tr ) ) );
+}
+
+/*!
+ \reimp
+*/
+
+const char* TQIconDrag::format( int i ) const
+{
+ if ( i == 0 )
+ return "application/x-qiconlist";
+ return 0;
+}
+
+/*!
+ Returns the encoded data of the drag object if \a mime is
+ application/x-qiconlist.
+*/
+
+TQByteArray TQIconDrag::tqencodedData( const char* mime ) const
+{
+ if ( d->items.count() <= 0 || TQString( mime ) !=
+ "application/x-qiconlist" )
+ return TQByteArray();
+
+ TQValueList<TQIconDragDataItem>::ConstIterator it = d->items.begin();
+ TQString s;
+ for ( ; it != d->items.end(); ++it ) {
+ TQString k( "%1$@@$%2$@@$%3$@@$%4$@@$%5$@@$%6$@@$%7$@@$%8$@@$" );
+ k = k.arg( (*it).item.pixmapRect().x() ).arg(
+ (*it).item.pixmapRect().y() ).arg( (*it).item.pixmapRect().width() ).
+ arg( (*it).item.pixmapRect().height() ).arg(
+ (*it).item.textRect().x() ).arg( (*it).item.textRect().y() ).
+ arg( (*it).item.textRect().width() ).arg(
+ (*it).item.textRect().height() );
+ k += TQString( (*it).data.data() ) + "$@@$";
+ s += k;
+ }
+
+ TQByteArray a( s.length() + 1 );
+ memcpy( a.data(), s.latin1(), a.size() );
+ return a;
+}
+
+/*!
+ Returns TRUE if \a e can be decoded by the TQIconDrag, otherwise
+ return FALSE.
+*/
+
+bool TQIconDrag::canDecode( TQMimeSource* e )
+{
+ if ( e->provides( "application/x-qiconlist" ) )
+ return TRUE;
+ return FALSE;
+}
+
+/*!
+ Decodes the data which is stored (encoded) in \a e and, if
+ successful, fills the \a list of icon drag items with the decoded
+ data. Returns TRUE if there was some data, FALSE otherwise.
+*/
+
+bool TQIconDragPrivate::decode( TQMimeSource* e, TQValueList<TQIconDragDataItem> &lst )
+{
+ TQByteArray ba = e->tqencodedData( "application/x-qiconlist" );
+ if ( ba.size() ) {
+ lst.clear();
+ TQString s = ba.data();
+ TQIconDragDataItem item;
+ TQRect ir, tr;
+ TQStringList l = TQStringList::split( "$@@$", s );
+
+ int i = 0;
+ TQStringList::Iterator it = l.begin();
+ for ( ; it != l.end(); ++it ) {
+ if ( i == 0 ) {
+ ir.setX( ( *it ).toInt() );
+ } else if ( i == 1 ) {
+ ir.setY( ( *it ).toInt() );
+ } else if ( i == 2 ) {
+ ir.setWidth( ( *it ).toInt() );
+ } else if ( i == 3 ) {
+ ir.setHeight( ( *it ).toInt() );
+ } else if ( i == 4 ) {
+ tr.setX( ( *it ).toInt() );
+ } else if ( i == 5 ) {
+ tr.setY( ( *it ).toInt() );
+ } else if ( i == 6 ) {
+ tr.setWidth( ( *it ).toInt() );
+ } else if ( i == 7 ) {
+ tr.setHeight( ( *it ).toInt() );
+ } else if ( i == 8 ) {
+ TQByteArray d( ( *it ).length() );
+ memcpy( d.data(), ( *it ).latin1(), ( *it ).length() );
+ item.item.setPixmapRect( ir );
+ item.item.setTextRect( tr );
+ item.data.setData( d );
+ lst.append( item );
+ }
+ ++i;
+ if ( i > 8 )
+ i = 0;
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+TQIconDragData::TQIconDragData()
+ : iconRect_(), textRect_()
+{
+}
+
+TQIconDragData::TQIconDragData( const TQRect &ir, const TQRect &tr )
+ : iconRect_( ir ), textRect_( tr )
+{
+}
+
+TQRect TQIconDragData::textRect() const
+{
+ return textRect_;
+}
+
+TQRect TQIconDragData::pixmapRect() const
+{
+ return iconRect_;
+}
+
+void TQIconDragData::setPixmapRect( const TQRect &r )
+{
+ iconRect_ = r;
+}
+
+void TQIconDragData::setTextRect( const TQRect &r )
+{
+ textRect_ = r;
+}
+
+#endif
+
+
+/*!
+ \class TQIconViewItem tqiconview.h
+ \brief The TQIconViewItem class provides a single item in a TQIconView.
+
+ \ingroup advanced
+ \module iconview
+
+ A TQIconViewItem tqcontains an icon, a string and optionally a sort
+ key, and can display itself in a TQIconView.
+ The class is designed to be very similar to TQListView and TQListBox
+ in use, both via instantiation and subclassing.
+
+ The simplest way to create a TQIconViewItem and insert it into a
+ TQIconView is to construct the item passing the constructor a
+ pointer to the icon view, a string and an icon:
+
+ \code
+ (void) new TQIconViewItem(
+ iconView, // A pointer to a TQIconView
+ "This is the text of the item",
+ aPixmap );
+ \endcode
+
+ By default the text of an icon view item may not be edited by the
+ user but calling setRenameEnabled(TRUE) will allow the user to
+ perform in-place editing of the item's text.
+
+ When the icon view is deleted all items in it are deleted
+ automatically.
+
+ The TQIconView::firstItem() and TQIconViewItem::nextItem() functions
+ provide a means of iterating over all the items in a TQIconView:
+
+ \code
+ TQIconViewItem *item;
+ for ( item = iconView->firstItem(); item; item = item->nextItem() )
+ do_something_with( item );
+ \endcode
+
+ The item's icon view is available from iconView(), and its
+ position in the icon view from index().
+
+ The item's selection status is available from isSelected() and is
+ set and controlled by setSelected() and isSelectable().
+
+ The text and icon can be set with setText() and setPixmap() and
+ retrieved with text() and pixmap(). The item's sort key defaults
+ to text() but may be set with setKey() and retrieved with key().
+ The comparison function, compare() uses key().
+
+ Items may be repositioned with move() and moveBy(). An item's
+ tqgeometry is available from rect(), x(), y(), width(), height(),
+ size(), pos(), textRect() and pixmapRect(). You can also test
+ against the position of a point with tqcontains() and intersects().
+
+ To remove an item from an icon view, just delete the item. The
+ TQIconViewItem destructor removes it cleanly from its icon view.
+
+ Because the icon view is designed to use drag-and-drop, the icon
+ view item also has functions for drag-and-drop which may be
+ reimplemented.
+
+ \target pixmap-size-limit
+ <b>Note:</b> Pixmaps with individual dimensions larger than 300 pixels may
+ not be displayed properly, depending on the \link TQIconView::Arrangement
+ arrangement in use\endlink. For example, pixmaps wider than 300 pixels
+ will not be arranged correctly if the icon view uses a
+ \l TQIconView::TopToBottom arrangement, and pixmaps taller than 300 pixels
+ will not be arranged correctly if the icon view uses a
+ \l TQIconView::LeftToRight arrangement.
+*/
+
+/*!
+ Constructs a TQIconViewItem and inserts it into icon view \a tqparent
+ with no text and a default icon.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *tqparent )
+ : view( tqparent ), itemText(), itemIcon( unknown_icon )
+{
+ init();
+}
+
+/*!
+ Constructs a TQIconViewItem and inserts it into the icon view \a
+ tqparent with no text and a default icon, after the icon view item
+ \a after.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *tqparent, TQIconViewItem *after )
+ : view( tqparent ), itemText(), itemIcon( unknown_icon ),
+ prev( 0 ), next( 0 )
+{
+ init( after );
+}
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ tqparent using \a text as the text and a default icon.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *tqparent, const TQString &text )
+ : view( tqparent ), itemText( text ), itemIcon( unknown_icon )
+{
+ init( 0 );
+}
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ tqparent using \a text as the text and a default icon, after the
+ icon view item \a after.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *tqparent, TQIconViewItem *after,
+ const TQString &text )
+ : view( tqparent ), itemText( text ), itemIcon( unknown_icon )
+{
+ init( after );
+}
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ tqparent using \a text as the text and \a icon as the icon.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *tqparent, const TQString &text,
+ const TQPixmap &icon )
+ : view( tqparent ),
+ itemText( text ), itemIcon( new TQPixmap( icon ) )
+{
+ init( 0 );
+}
+
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ tqparent using \a text as the text and \a icon as the icon, after
+ the icon view item \a after.
+
+ \sa setPixmap()
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *tqparent, TQIconViewItem *after,
+ const TQString &text, const TQPixmap &icon )
+ : view( tqparent ), itemText( text ), itemIcon( new TQPixmap( icon ) )
+{
+ init( after );
+}
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ tqparent using \a text as the text and \a picture as the icon.
+*/
+
+#ifndef TQT_NO_PICTURE
+TQIconViewItem::TQIconViewItem( TQIconView *tqparent, const TQString &text,
+ const TQPicture &picture )
+ : view( tqparent ), itemText( text ), itemIcon( 0 )
+{
+ init( 0, new TQPicture( picture ) );
+}
+
+/*!
+ Constructs an icon view item and inserts it into the icon view \a
+ tqparent using \a text as the text and \a picture as the icon, after
+ the icon view item \a after.
+*/
+
+TQIconViewItem::TQIconViewItem( TQIconView *tqparent, TQIconViewItem *after,
+ const TQString &text, const TQPicture &picture )
+ : view( tqparent ), itemText( text ), itemIcon( 0 )
+{
+ init( after, new TQPicture( picture ) );
+}
+#endif
+
+/*!
+ This private function initializes the icon view item and inserts it
+ into the icon view.
+*/
+
+void TQIconViewItem::init( TQIconViewItem *after
+#ifndef TQT_NO_PICTURE
+ , TQPicture *pic
+#endif
+ )
+{
+ d = new TQIconViewItemPrivate;
+ d->container1 = 0;
+ d->container2 = 0;
+ prev = next = 0;
+ allow_rename = FALSE;
+ allow_drag = TRUE;
+ allow_drop = TRUE;
+ selected = FALSE;
+ selectable = TRUE;
+#ifndef TQT_NO_TEXTEDIT
+ renameBox = 0;
+#endif
+#ifndef TQT_NO_PICTURE
+ itemPic = pic;
+#endif
+ if ( view ) {
+ itemKey = itemText;
+ dirty = TRUE;
+ wordWrapDirty = TRUE;
+ tqitemRect = TQRect( -1, -1, 0, 0 );
+ calcRect();
+ view->insertItem( this, after );
+ }
+}
+
+/*!
+ Destroys the icon view item and tells the tqparent icon view that
+ the item has been destroyed.
+*/
+
+TQIconViewItem::~TQIconViewItem()
+{
+#ifndef TQT_NO_TEXTEDIT
+ removeRenameBox();
+#endif
+ if ( view && !view->d->clearing )
+ view->takeItem( this );
+ view = 0;
+ if ( itemIcon && itemIcon->serialNumber() != unknown_icon->serialNumber() )
+ delete itemIcon;
+#ifndef TQT_NO_PICTURE
+ delete itemPic;
+#endif
+ delete d;
+}
+
+int TQIconViewItem::RTTI = 0;
+
+/*!
+ Returns 0.
+
+ Make your derived classes return their own values for rtti(), so
+ that you can distinguish between icon view item types. You should
+ use values greater than 1000, preferably a large random number, to
+ allow for extensions to this class.
+*/
+
+int TQIconViewItem::rtti() const
+{
+ return RTTI;
+}
+
+
+/*!
+ Sets \a text as the text of the icon view item. This function
+ might be a no-op if you reimplement text().
+
+ \sa text()
+*/
+
+void TQIconViewItem::setText( const TQString &text )
+{
+ if ( text == itemText )
+ return;
+
+ wordWrapDirty = TRUE;
+ itemText = text;
+ if ( itemKey.isEmpty() )
+ itemKey = itemText;
+
+ TQRect oR = rect();
+ calcRect();
+ oR = oR.unite( rect() );
+
+ if ( view ) {
+ if ( TQRect( view->contentsX(), view->contentsY(),
+ view->visibleWidth(), view->visibleHeight() ).
+ intersects( oR ) )
+ view->repaintContents( oR.x() - 1, oR.y() - 1,
+ oR.width() + 2, oR.height() + 2, FALSE );
+ }
+}
+
+/*!
+ Sets \a k as the sort key of the icon view item. By default
+ text() is used for sorting.
+
+ \sa compare()
+*/
+
+void TQIconViewItem::setKey( const TQString &k )
+{
+ if ( k == itemKey )
+ return;
+
+ itemKey = k;
+}
+
+/*!
+ Sets \a icon as the item's icon in the icon view. This function
+ might be a no-op if you reimplement pixmap().
+
+ <b>Note:</b> Pixmaps with individual dimensions larger than 300 pixels may
+ not be displayed properly, depending on the \link TQIconView::Arrangement
+ arrangement in use\endlink. See the \link #pixmap-size-limit main class
+ documentation\endlink for details.
+
+ \sa pixmap()
+*/
+
+void TQIconViewItem::setPixmap( const TQPixmap &icon )
+{
+ if ( itemIcon && itemIcon == unknown_icon )
+ itemIcon = 0;
+
+ if ( itemIcon )
+ *itemIcon = icon;
+ else
+ itemIcon = new TQPixmap( icon );
+ TQRect oR = rect();
+ calcRect();
+ oR = oR.unite( rect() );
+
+ if ( view ) {
+ if ( TQRect( view->contentsX(), view->contentsY(),
+ view->visibleWidth(), view->visibleHeight() ).
+ intersects( oR ) )
+ view->repaintContents( oR.x() - 1, oR.y() - 1,
+ oR.width() + 2, oR.height() + 2, FALSE );
+ }
+}
+
+/*!
+ Sets \a icon as the item's icon in the icon view. This function
+ might be a no-op if you reimplement picture().
+
+ \sa picture()
+*/
+
+#ifndef TQT_NO_PICTURE
+void TQIconViewItem::setPicture( const TQPicture &icon )
+{
+ // clear assigned pixmap if any
+ if ( itemIcon ) {
+ if ( itemIcon == unknown_icon ) {
+ itemIcon = 0;
+ } else {
+ delete itemIcon;
+ itemIcon = 0;
+ }
+ }
+ if ( itemPic )
+ delete itemPic;
+ itemPic = new TQPicture( icon );
+
+ TQRect oR = rect();
+ calcRect();
+ oR = oR.unite( rect() );
+
+ if ( view ) {
+ if ( TQRect( view->contentsX(), view->contentsY(),
+ view->visibleWidth(), view->visibleHeight() ).
+ intersects( oR ) )
+ view->repaintContents( oR.x() - 1, oR.y() - 1,
+ oR.width() + 2, oR.height() + 2, FALSE );
+ }
+}
+#endif
+
+/*!
+ \overload
+
+ Sets \a text as the text of the icon view item. If \a recalc is
+ TRUE, the icon view's tqlayout is recalculated. If \a redraw is TRUE
+ (the default), the icon view is repainted.
+
+ \sa text()
+*/
+
+void TQIconViewItem::setText( const TQString &text, bool recalc, bool redraw )
+{
+ if ( text == itemText )
+ return;
+
+ wordWrapDirty = TRUE;
+ itemText = text;
+
+ if ( recalc )
+ calcRect();
+ if ( redraw )
+ tqrepaint();
+}
+
+/*!
+ \overload
+
+ Sets \a icon as the item's icon in the icon view. If \a recalc is
+ TRUE, the icon view's tqlayout is recalculated. If \a redraw is TRUE
+ (the default), the icon view is repainted.
+
+ <b>Note:</b> Pixmaps with individual dimensions larger than 300 pixels may
+ not be displayed properly, depending on the \link TQIconView::Arrangement
+ arrangement in use\endlink. See the \link #pixmap-size-limit main class
+ documentation\endlink for details.
+
+ \sa pixmap()
+*/
+
+void TQIconViewItem::setPixmap( const TQPixmap &icon, bool recalc, bool redraw )
+{
+ if ( itemIcon && itemIcon == unknown_icon )
+ itemIcon = 0;
+
+ if ( itemIcon )
+ *itemIcon = icon;
+ else
+ itemIcon = new TQPixmap( icon );
+
+ if ( redraw ) {
+ if ( recalc ) {
+ TQRect oR = rect();
+ calcRect();
+ oR = oR.unite( rect() );
+
+ if ( view ) {
+ if ( TQRect( view->contentsX(), view->contentsY(),
+ view->visibleWidth(), view->visibleHeight() ).
+ intersects( oR ) )
+ view->repaintContents( oR.x() - 1, oR.y() - 1,
+ oR.width() + 2, oR.height() + 2, FALSE );
+ }
+ } else {
+ tqrepaint();
+ }
+ } else if ( recalc ) {
+ calcRect();
+ }
+}
+
+/*!
+ If \a allow is TRUE, the user can rename the icon view item by
+ clicking on the text (or pressing F2) while the item is selected
+ (in-place renaming). If \a allow is FALSE, in-place renaming is
+ not possible.
+*/
+
+void TQIconViewItem::setRenameEnabled( bool allow )
+{
+ allow_rename = (uint)allow;
+}
+
+/*!
+ If \a allow is TRUE, the icon view permits the user to drag the
+ icon view item either to another position within the icon view or
+ to somewhere outside of it. If \a allow is FALSE, the item cannot
+ be dragged.
+*/
+
+void TQIconViewItem::setDragEnabled( bool allow )
+{
+ allow_drag = (uint)allow;
+}
+
+/*!
+ If \a allow is TRUE, the icon view lets the user drop something on
+ this icon view item.
+*/
+
+void TQIconViewItem::setDropEnabled( bool allow )
+{
+ allow_drop = (uint)allow;
+}
+
+/*!
+ Returns the text of the icon view item. Normally you set the text
+ of the item with setText(), but sometimes it's inconvenient to
+ call setText() for every item; so you can subclass TQIconViewItem,
+ reimplement this function, and return the text of the item. If you
+ do this, you must call calcRect() manually each time the text
+ (and therefore its size) changes.
+
+ \sa setText()
+*/
+
+TQString TQIconViewItem::text() const
+{
+ return itemText;
+}
+
+/*!
+ Returns the key of the icon view item or text() if no key has been
+ explicitly set.
+
+ \sa setKey(), compare()
+*/
+
+TQString TQIconViewItem::key() const
+{
+ return itemKey;
+}
+
+/*!
+ Returns the icon of the icon view item if it is a pixmap, or 0 if
+ it is a picture. In the latter case use picture() instead.
+ Normally you set the pixmap of the item with setPixmap(), but
+ sometimes it's inconvenient to call setPixmap() for every item. So
+ you can subclass TQIconViewItem, reimplement this function and
+ return a pointer to the item's pixmap. If you do this, you \e must
+ call calcRect() manually each time the size of this pixmap
+ changes.
+
+ \sa setPixmap()
+*/
+
+TQPixmap *TQIconViewItem::pixmap() const
+{
+ return itemIcon;
+}
+
+/*!
+ Returns the icon of the icon view item if it is a picture, or 0 if
+ it is a pixmap. In the latter case use pixmap() instead. Normally
+ you set the picture of the item with setPicture(), but sometimes
+ it's inconvenient to call setPicture() for every item. So you can
+ subclass TQIconViewItem, reimplement this function and return a
+ pointer to the item's picture. If you do this, you \e must call
+ calcRect() manually each time the size of this picture changes.
+
+ \sa setPicture()
+*/
+
+#ifndef TQT_NO_PICTURE
+TQPicture *TQIconViewItem::picture() const
+{
+ return itemPic;
+}
+#endif
+
+/*!
+ Returns TRUE if the item can be renamed by the user with in-place
+ renaming; otherwise returns FALSE.
+
+ \sa setRenameEnabled()
+*/
+
+bool TQIconViewItem::renameEnabled() const
+{
+ return (bool)allow_rename;
+}
+
+/*!
+ Returns TRUE if the user is allowed to drag the icon view item;
+ otherwise returns FALSE.
+
+ \sa setDragEnabled()
+*/
+
+bool TQIconViewItem::dragEnabled() const
+{
+ return (bool)allow_drag;
+}
+
+/*!
+ Returns TRUE if the user is allowed to drop something onto the
+ item; otherwise returns FALSE.
+
+ \sa setDropEnabled()
+*/
+
+bool TQIconViewItem::dropEnabled() const
+{
+ return (bool)allow_drop;
+}
+
+/*!
+ Returns a pointer to this item's icon view tqparent.
+*/
+
+TQIconView *TQIconViewItem::iconView() const
+{
+ return view;
+}
+
+/*!
+ Returns a pointer to the previous item, or 0 if this is the first
+ item in the icon view.
+
+ \sa nextItem() TQIconView::firstItem()
+*/
+
+TQIconViewItem *TQIconViewItem::prevItem() const
+{
+ return prev;
+}
+
+/*!
+ Returns a pointer to the next item, or 0 if this is the last item
+ in the icon view.
+
+ To tqfind the first item use TQIconView::firstItem().
+
+ Example:
+ \code
+ TQIconViewItem *item;
+ for ( item = iconView->firstItem(); item; item = item->nextItem() )
+ do_something_with( item );
+ \endcode
+
+ \sa prevItem()
+*/
+
+TQIconViewItem *TQIconViewItem::nextItem() const
+{
+ return next;
+}
+
+/*!
+ Returns the index of this item in the icon view, or -1 if an error
+ occurred.
+*/
+
+int TQIconViewItem::index() const
+{
+ if ( view )
+ return view->index( this );
+
+ return -1;
+}
+
+
+
+/*!
+ \overload
+
+ This variant is equivalent to calling the other variant with \e cb
+ set to FALSE.
+*/
+
+void TQIconViewItem::setSelected( bool s )
+{
+ setSelected( s, FALSE );
+}
+
+/*!
+ Selects or unselects the item, depending on \a s; it may also
+ unselect other items, depending on TQIconView::selectionMode() and
+ \a cb.
+
+ If \a s is FALSE, the item is unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Single, the
+ item is selected and the item previously selected is unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Extended, the
+ item is selected. If \a cb is TRUE, the selection state of the
+ other items is left unchanged. If \a cb is FALSE (the default) all
+ other items are unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Multi, the
+ item is selected.
+
+ Note that \a cb is used only if TQIconView::selectionMode() is \c
+ Extended; cb defaults to FALSE.
+
+ All items whose selection status changes tqrepaint themselves.
+*/
+
+void TQIconViewItem::setSelected( bool s, bool cb )
+{
+ if ( !view )
+ return;
+ if ( view->selectionMode() != TQIconView::NoSelection &&
+ selectable && s != (bool)selected ) {
+
+ if ( view->d->selectionMode == TQIconView::Single && this != view->d->currentItem ) {
+ TQIconViewItem *o = view->d->currentItem;
+ if ( o && o->selected )
+ o->selected = FALSE;
+ view->d->currentItem = this;
+ if ( o )
+ o->tqrepaint();
+ emit view->currentChanged( this );
+ }
+
+ if ( !s ) {
+ selected = FALSE;
+ } else {
+ if ( view->d->selectionMode == TQIconView::Single && view->d->currentItem ) {
+ view->d->currentItem->selected = FALSE;
+ }
+ if ( ( view->d->selectionMode == TQIconView::Extended && !cb ) ||
+ view->d->selectionMode == TQIconView::Single ) {
+ bool b = view->tqsignalsBlocked();
+ view->blockSignals( TRUE );
+ view->selectAll( FALSE );
+ view->blockSignals( b );
+ }
+ selected = s;
+ }
+
+ tqrepaint();
+ if ( !view->tqsignalsBlocked() ) {
+ bool emitIt = view->d->selectionMode == TQIconView::Single && s;
+ TQIconView *v = view;
+ emit v->selectionChanged();
+ if ( emitIt )
+ emit v->selectionChanged( this );
+ }
+ }
+}
+
+/*!
+ Sets this item to be selectable if \a enable is TRUE (the default)
+ or unselectable if \a enable is FALSE.
+
+ The user is unable to select a non-selectable item using either
+ the keyboard or the mouse. (The application programmer can select
+ an item in code regardless of this setting.)
+
+ \sa isSelectable()
+*/
+
+void TQIconViewItem::setSelectable( bool enable )
+{
+ selectable = (uint)enable;
+}
+
+/*!
+ Returns TRUE if the item is selected; otherwise returns FALSE.
+
+ \sa setSelected()
+*/
+
+bool TQIconViewItem::isSelected() const
+{
+ return (bool)selected;
+}
+
+/*!
+ Returns TRUE if the item is selectable; otherwise returns FALSE.
+
+ \sa setSelectable()
+*/
+
+bool TQIconViewItem::isSelectable() const
+{
+ return (bool)selectable;
+}
+
+/*!
+ Repaints the item.
+*/
+
+void TQIconViewItem::tqrepaint()
+{
+ if ( view )
+ view->repaintItem( this );
+}
+
+/*!
+ Moves the item to position (\a x, \a y) in the icon view (these
+ are contents coordinates).
+*/
+
+bool TQIconViewItem::move( int x, int y )
+{
+ if ( x == this->x() && y == this->y() )
+ return FALSE;
+ tqitemRect.setRect( x, y, tqitemRect.width(), tqitemRect.height() );
+ checkRect();
+ if ( view )
+ view->updateItemContainer( this );
+ return TRUE;
+}
+
+/*!
+ Moves the item \a dx pixels in the x-direction and \a dy pixels in
+ the y-direction.
+*/
+
+void TQIconViewItem::moveBy( int dx, int dy )
+{
+ tqitemRect.moveBy( dx, dy );
+ checkRect();
+ if ( view )
+ view->updateItemContainer( this );
+}
+
+/*!
+ \overload
+
+ Moves the item to the point \a pnt.
+*/
+
+bool TQIconViewItem::move( const TQPoint &pnt )
+{
+ return move( pnt.x(), pnt.y() );
+}
+
+/*!
+ \overload
+
+ Moves the item by the x, y values in point \a pnt.
+*/
+
+void TQIconViewItem::moveBy( const TQPoint &pnt )
+{
+ moveBy( pnt.x(), pnt.y() );
+}
+
+/*!
+ Returns the bounding rectangle of the item (in contents
+ coordinates).
+*/
+
+TQRect TQIconViewItem::rect() const
+{
+ return tqitemRect;
+}
+
+/*!
+ Returns the x-coordinate of the item (in contents coordinates).
+*/
+
+int TQIconViewItem::x() const
+{
+ return tqitemRect.x();
+}
+
+/*!
+ Returns the y-coordinate of the item (in contents coordinates).
+*/
+
+int TQIconViewItem::y() const
+{
+ return tqitemRect.y();
+}
+
+/*!
+ Returns the width of the item.
+*/
+
+int TQIconViewItem::width() const
+{
+ return TQMAX( tqitemRect.width(), TQApplication::globalStrut().width() );
+}
+
+/*!
+ Returns the height of the item.
+*/
+
+int TQIconViewItem::height() const
+{
+ return TQMAX( tqitemRect.height(), TQApplication::globalStrut().height() );
+}
+
+/*!
+ Returns the size of the item.
+*/
+
+TQSize TQIconViewItem::size() const
+{
+ return TQSize( tqitemRect.width(), tqitemRect.height() );
+}
+
+/*!
+ Returns the position of the item (in contents coordinates).
+*/
+
+TQPoint TQIconViewItem::pos() const
+{
+ return TQPoint( tqitemRect.x(), tqitemRect.y() );
+}
+
+/*!
+ Returns the bounding rectangle of the item's text.
+
+ If \a relative is TRUE, (the default), the returned rectangle is
+ relative to the origin of the item's rectangle. If \a relative is
+ FALSE, the returned rectangle is relative to the origin of the
+ icon view's contents coordinate system.
+*/
+
+TQRect TQIconViewItem::textRect( bool relative ) const
+{
+ if ( relative )
+ return itemTextRect;
+ else
+ return TQRect( x() + itemTextRect.x(), y() + itemTextRect.y(), itemTextRect.width(), itemTextRect.height() );
+}
+
+/*!
+ Returns the bounding rectangle of the item's icon.
+
+ If \a relative is TRUE, (the default), the rectangle is relative to
+ the origin of the item's rectangle. If \a relative is FALSE, the
+ returned rectangle is relative to the origin of the icon view's
+ contents coordinate system.
+*/
+
+TQRect TQIconViewItem::pixmapRect( bool relative ) const
+{
+ if ( relative )
+ return itemIconRect;
+ else
+ return TQRect( x() + itemIconRect.x(), y() + itemIconRect.y(), itemIconRect.width(), itemIconRect.height() );
+}
+
+/*!
+ Returns TRUE if the item tqcontains the point \a pnt (in contents
+ coordinates); otherwise returns FALSE.
+*/
+
+bool TQIconViewItem::tqcontains( const TQPoint& pnt ) const
+{
+ TQRect textArea = textRect( FALSE );
+ TQRect pixmapArea = pixmapRect( FALSE );
+ if ( iconView()->itemTextPos() == TQIconView::Bottom )
+ textArea.setTop( pixmapArea.bottom() );
+ else
+ textArea.setLeft( pixmapArea.right() );
+ return textArea.tqcontains( pnt ) || pixmapArea.tqcontains( pnt );
+}
+
+/*!
+ Returns TRUE if the item intersects the rectangle \a r (in
+ contents coordinates); otherwise returns FALSE.
+*/
+
+bool TQIconViewItem::intersects( const TQRect& r ) const
+{
+ return ( textRect( FALSE ).intersects( r ) ||
+ pixmapRect( FALSE ).intersects( r ) );
+}
+
+/*!
+ \fn bool TQIconViewItem::acceptDrop( const TQMimeSource *mime ) const
+
+ Returns TRUE if you can drop things with a TQMimeSource of \a mime
+ onto this item; otherwise returns FALSE.
+
+ The default implementation always returns FALSE. You must subclass
+ TQIconViewItem and reimplement acceptDrop() to accept drops.
+*/
+
+bool TQIconViewItem::acceptDrop( const TQMimeSource * ) const
+{
+ return FALSE;
+}
+
+#ifndef TQT_NO_TEXTEDIT
+/*!
+ Starts in-place renaming of an icon, if allowed.
+
+ This function sets up the icon view so that the user can edit the
+ item text, and then returns. When the user is done, setText() will
+ be called and TQIconView::itemRenamed() will be emitted (unless the
+ user canceled, e.g. by pressing the Escape key).
+
+ \sa setRenameEnabled()
+*/
+
+void TQIconViewItem::rename()
+{
+ if ( !view )
+ return;
+ if ( renameBox )
+ removeRenameBox();
+ oldRect = rect();
+ renameBox = new TQIconViewItemLineEdit( itemText, view->viewport(), this, "qt_renamebox" );
+ iconView()->ensureItemVisible( this );
+ TQRect tr( textRect( FALSE ) );
+ view->addChild( renameBox, tr.x() + ( tr.width() / 2 - renameBox->width() / 2 ), tr.y() - 3 );
+ renameBox->selectAll();
+ view->viewport()->setFocusProxy( renameBox );
+ renameBox->setFocus();
+ renameBox->show();
+ TQ_ASSERT( view->d->renamingItem == 0L );
+ view->d->renamingItem = this;
+}
+#endif
+
+/*!
+ Compares this icon view item to \a i. Returns -1 if this item is
+ less than \a i, 0 if they are equal, and 1 if this icon view item
+ is greater than \a i.
+
+ The default implementation compares the item keys (key()) using
+ TQString::localeAwareCompare(). A reimplementation may use
+ different values and a different comparison function. Here is a
+ reimplementation that uses plain Unicode comparison:
+
+ \code
+ int MyIconViewItem::compare( TQIconViewItem *i ) const
+ {
+ return key().compare( i->key() );
+ }
+ \endcode
+
+ \sa key() TQString::localeAwareCompare() TQString::compare()
+*/
+
+int TQIconViewItem::compare( TQIconViewItem *i ) const
+{
+ return key().localeAwareCompare( i->key() );
+}
+
+#ifndef TQT_NO_TEXTEDIT
+/*!
+ This private function is called when the user pressed Return during
+ in-place renaming.
+*/
+
+void TQIconViewItem::renameItem()
+{
+ if ( !renameBox || !view )
+ return;
+
+ if ( !view->d->wordWrapIconText ) {
+ wordWrapDirty = TRUE;
+ calcRect();
+ }
+ TQRect r = tqitemRect;
+ setText( renameBox->text() );
+ view->repaintContents( oldRect.x() - 1, oldRect.y() - 1, oldRect.width() + 2, oldRect.height() + 2, FALSE );
+ view->repaintContents( r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2, FALSE );
+ removeRenameBox();
+
+ view->emitRenamed( this );
+}
+
+/*!
+ Cancels in-place renaming.
+*/
+
+void TQIconViewItem::cancelRenameItem()
+{
+ if ( !view )
+ return;
+
+ TQRect r = tqitemRect;
+ calcRect();
+ view->repaintContents( oldRect.x() - 1, oldRect.y() - 1, oldRect.width() + 2, oldRect.height() + 2, FALSE );
+ view->repaintContents( r.x() - 1, r.y() - 1, r.width() + 2, r.height() + 2, FALSE );
+
+ if ( !renameBox )
+ return;
+
+ removeRenameBox();
+}
+
+/*!
+ Removes the editbox that is used for in-place renaming.
+*/
+
+void TQIconViewItem::removeRenameBox()
+{
+ if ( !renameBox || !view )
+ return;
+
+ bool resetFocus = view->viewport()->focusProxy() == renameBox;
+ renameBox->hide();
+ renameBox->deleteLater();
+ renameBox = 0;
+ if ( resetFocus ) {
+ view->viewport()->setFocusProxy( view );
+ view->setFocus();
+ }
+ TQ_ASSERT( view->d->renamingItem == this );
+ view->d->renamingItem = 0L;
+}
+#endif
+
+/*!
+ This virtual function is responsible for calculating the
+ rectangles returned by rect(), textRect() and pixmapRect().
+ setRect(), setTextRect() and setPixmapRect() are provided mainly
+ for reimplementations of this function.
+
+ \a text_ is an internal parameter which defaults to TQString::null.
+*/
+
+void TQIconViewItem::calcRect( const TQString &text_ )
+{
+ if ( !view ) // #####
+ return;
+
+ wordWrapDirty = TRUE;
+ int pw = 0;
+ int ph = 0;
+
+#ifndef TQT_NO_PICTURE
+ if ( picture() ) {
+ TQRect br = picture()->boundingRect();
+ pw = br.width() + 2;
+ ph = br.height() + 2;
+ } else
+#endif
+ {
+ pw = ( pixmap() ? pixmap() : unknown_icon )->width() + 2;
+ ph = ( pixmap() ? pixmap() : unknown_icon )->height() + 2;
+ }
+
+ itemIconRect.setWidth( pw );
+ itemIconRect.setHeight( ph );
+
+ calcTmpText();
+
+ TQString t = text_;
+ if ( t.isEmpty() ) {
+ if ( view->d->wordWrapIconText )
+ t = itemText;
+ else
+ t = tmpText;
+ }
+
+ int tw = 0;
+ int th = 0;
+ // ##### TODO: fix font bearings!
+ TQRect r;
+ if ( view->d->wordWrapIconText ) {
+ r = TQRect( view->d->fm->boundingRect( 0, 0, iconView()->maxItemWidth() -
+ ( iconView()->itemTextPos() == TQIconView::Bottom ? 0 :
+ pixmapRect().width() ),
+ 0xFFFFFFFF, AlignHCenter | WordBreak | BreakAnywhere, t ) );
+ r.setWidth( r.width() + 4 );
+ } else {
+ r = TQRect( 0, 0, view->d->fm->width( t ), view->d->fm->height() );
+ r.setWidth( r.width() + 4 );
+ }
+
+ if ( r.width() > iconView()->maxItemWidth() -
+ ( iconView()->itemTextPos() == TQIconView::Bottom ? 0 :
+ pixmapRect().width() ) )
+ r.setWidth( iconView()->maxItemWidth() - ( iconView()->itemTextPos() == TQIconView::Bottom ? 0 :
+ pixmapRect().width() ) );
+
+ tw = r.width();
+ th = r.height();
+ if ( tw < view->d->fm->width( "X" ) )
+ tw = view->d->fm->width( "X" );
+
+ itemTextRect.setWidth( tw );
+ itemTextRect.setHeight( th );
+
+ int w = 0;
+ int h = 0;
+ if ( view->itemTextPos() == TQIconView::Bottom ) {
+ w = TQMAX( itemTextRect.width(), itemIconRect.width() );
+ h = itemTextRect.height() + itemIconRect.height() + 1;
+
+ tqitemRect.setWidth( w );
+ tqitemRect.setHeight( h );
+
+ itemTextRect = TQRect( ( width() - itemTextRect.width() ) / 2, height() - itemTextRect.height(),
+ itemTextRect.width(), itemTextRect.height() );
+ itemIconRect = TQRect( ( width() - itemIconRect.width() ) / 2, 0,
+ itemIconRect.width(), itemIconRect.height() );
+ } else {
+ h = TQMAX( itemTextRect.height(), itemIconRect.height() );
+ w = itemTextRect.width() + itemIconRect.width() + 1;
+
+ tqitemRect.setWidth( w );
+ tqitemRect.setHeight( h );
+
+ itemTextRect = TQRect( width() - itemTextRect.width(), ( height() - itemTextRect.height() ) / 2,
+ itemTextRect.width(), itemTextRect.height() );
+ itemIconRect = TQRect( 0, ( height() - itemIconRect.height() ) / 2,
+ itemIconRect.width(), itemIconRect.height() );
+ }
+ if ( view )
+ view->updateItemContainer( this );
+}
+
+/*!
+ Paints the item using the painter \a p and the color group \a cg.
+ If you want the item to be drawn with a different font or color,
+ reimplement this function, change the values of the color group or
+ the painter's font, and then call the TQIconViewItem::paintItem()
+ with the changed values.
+*/
+
+void TQIconViewItem::paintItem( TQPainter *p, const TQColorGroup &cg )
+{
+ if ( !view )
+ return;
+
+ p->save();
+
+ if ( isSelected() ) {
+ p->setPen( cg.highlightedText() );
+ } else {
+ p->setPen( cg.text() );
+ }
+
+ calcTmpText();
+
+#ifndef TQT_NO_PICTURE
+ if ( picture() ) {
+ TQPicture *pic = picture();
+ if ( isSelected() ) {
+ p->fillRect( pixmapRect( FALSE ), TQBrush( cg.highlight(), Qt::Dense4Pattern) );
+ }
+ p->drawPicture( x()-pic->boundingRect().x(), y()-pic->boundingRect().y(), *pic );
+ if ( isSelected() ) {
+ p->fillRect( textRect( FALSE ), cg.highlight() );
+ p->setPen( TQPen( cg.highlightedText() ) );
+ } else if ( view->d->itemTextBrush != Qt::NoBrush )
+ p->fillRect( textRect( FALSE ), view->d->itemTextBrush );
+
+ int align = view->itemTextPos() == TQIconView::Bottom ? AlignHCenter : AlignAuto;
+ if ( view->d->wordWrapIconText )
+ align |= WordBreak | BreakAnywhere;
+ p->drawText( textRect( FALSE ), align, view->d->wordWrapIconText ? itemText : tmpText );
+ p->restore();
+ return;
+ }
+#endif
+ bool textOnBottom = ( view->itemTextPos() == TQIconView::Bottom );
+ int dim;
+ if ( textOnBottom )
+ dim = ( pixmap() ? pixmap() : unknown_icon)->width();
+ else
+ dim = ( pixmap() ? pixmap() : unknown_icon)->height();
+ if ( isSelected() ) {
+ TQPixmap *pix = pixmap() ? pixmap() : unknown_icon;
+ if ( pix && !pix->isNull() ) {
+ TQPixmap *buffer = get_qiv_buffer_pixmap( pix->size() );
+ TQBitmap tqmask = view->tqmask( pix );
+
+ TQPainter p2( buffer );
+ p2.fillRect( pix->rect(), white );
+ p2.drawPixmap( 0, 0, *pix );
+ p2.end();
+ buffer->setMask( tqmask );
+ p2.begin( buffer );
+#if defined(TQ_WS_X11)
+ p2.fillRect( pix->rect(), TQBrush( cg.highlight(), Qt::Dense4Pattern) );
+#else // in WIN32 Dense4Pattern doesn't work correctly (transparency problem), so work around it
+ if ( iconView()->d->drawActiveSelection ) {
+ if ( !qiv_selection )
+ createSelectionPixmap( cg );
+ p2.drawTiledPixmap( 0, 0, pix->width(), pix->height(),
+ *qiv_selection );
+ }
+#endif
+ p2.end();
+ TQRect cr = pix->rect();
+ if ( textOnBottom )
+ p->drawPixmap( x() + ( width() - dim ) / 2, y(), *buffer, 0, 0,
+ cr.width(), cr.height() );
+ else
+ p->drawPixmap( x() , y() + ( height() - dim ) / 2, *buffer, 0, 0,
+ cr.width(), cr.height() );
+ }
+ } else {
+ if ( textOnBottom )
+ p->drawPixmap( x() + ( width() - dim ) / 2, y(),
+ *( pixmap() ? pixmap() : unknown_icon ) );
+ else
+ p->drawPixmap( x() , y() + ( height() - dim ) / 2,
+ *( pixmap() ? pixmap() : unknown_icon ) );
+ }
+
+ p->save();
+ if ( isSelected() ) {
+ p->fillRect( textRect( FALSE ), cg.highlight() );
+ p->setPen( TQPen( cg.highlightedText() ) );
+ } else if ( view->d->itemTextBrush != Qt::NoBrush )
+ p->fillRect( textRect( FALSE ), view->d->itemTextBrush );
+
+ int align = AlignHCenter;
+ if ( view->d->wordWrapIconText )
+ align |= WordBreak | BreakAnywhere;
+ p->drawText( textRect( FALSE ), align,
+ view->d->wordWrapIconText ? itemText : tmpText );
+
+ p->restore();
+
+ p->restore();
+}
+
+/*!
+ Paints the focus rectangle of the item using the painter \a p and
+ the color group \a cg.
+*/
+
+void TQIconViewItem::paintFocus( TQPainter *p, const TQColorGroup &cg )
+{
+ if ( !view )
+ return;
+
+ view->tqstyle().tqdrawPrimitive(TQStyle::PE_FocusRect, p,
+ TQRect( textRect( FALSE ).x(), textRect( FALSE ).y(),
+ textRect( FALSE ).width(),
+ textRect( FALSE ).height() ), cg,
+ (isSelected() ?
+ TQStyle::Style_FocusAtBorder :
+ TQStyle::Style_Default),
+ TQStyleOption(isSelected() ? cg.highlight() : cg.base()));
+
+ if ( this != view->d->currentItem ) {
+ view->tqstyle().tqdrawPrimitive(TQStyle::PE_FocusRect, p,
+ TQRect( pixmapRect( FALSE ).x(),
+ pixmapRect( FALSE ).y(),
+ pixmapRect( FALSE ).width(),
+ pixmapRect( FALSE ).height() ),
+ cg, TQStyle::Style_Default,
+ TQStyleOption(cg.base()));
+ }
+}
+
+/*!
+ \fn void TQIconViewItem::dropped( TQDropEvent *e, const TQValueList<TQIconDragItem> &lst )
+
+ This function is called when something is dropped on the item. \a
+ e provides all the information about the drop. If the drag object
+ of the drop was a TQIconDrag, \a lst tqcontains the list of the
+ dropped items. You can get the data by calling
+ TQIconDragItem::data() on each item. If the \a lst is empty, i.e.
+ the drag was not a TQIconDrag, you must decode the data in \a e and
+ work with that.
+
+ The default implementation does nothing; subclasses may
+ reimplement this function.
+*/
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQIconViewItem::dropped( TQDropEvent *, const TQValueList<TQIconDragItem> & )
+{
+}
+#endif
+
+/*!
+ This function is called when a drag enters the item's bounding
+ rectangle.
+
+ The default implementation does nothing; subclasses may
+ reimplement this function.
+*/
+
+void TQIconViewItem::dragEntered()
+{
+}
+
+/*!
+ This function is called when a drag leaves the item's bounding
+ rectangle.
+
+ The default implementation does nothing; subclasses may
+ reimplement this function.
+*/
+
+void TQIconViewItem::dragLeft()
+{
+}
+
+/*!
+ Sets the bounding rectangle of the whole item to \a r. This
+ function is provided for subclasses which reimplement calcRect(),
+ so that they can set the calculated rectangle. \e{Any other use is
+ discouraged.}
+
+ \sa calcRect() textRect() setTextRect() pixmapRect() setPixmapRect()
+*/
+
+void TQIconViewItem::setItemRect( const TQRect &r )
+{
+ tqitemRect = r;
+ checkRect();
+ if ( view )
+ view->updateItemContainer( this );
+}
+
+/*!
+ Sets the bounding rectangle of the item's text to \a r. This
+ function is provided for subclasses which reimplement calcRect(),
+ so that they can set the calculated rectangle. \e{Any other use is
+ discouraged.}
+
+ \sa calcRect() textRect() setItemRect() setPixmapRect()
+*/
+
+void TQIconViewItem::setTextRect( const TQRect &r )
+{
+ itemTextRect = r;
+ if ( view )
+ view->updateItemContainer( this );
+}
+
+/*!
+ Sets the bounding rectangle of the item's icon to \a r. This
+ function is provided for subclasses which reimplement calcRect(),
+ so that they can set the calculated rectangle. \e{Any other use is
+ discouraged.}
+
+ \sa calcRect() pixmapRect() setItemRect() setTextRect()
+*/
+
+void TQIconViewItem::setPixmapRect( const TQRect &r )
+{
+ itemIconRect = r;
+ if ( view )
+ view->updateItemContainer( this );
+}
+
+/*!
+ \internal
+*/
+
+void TQIconViewItem::calcTmpText()
+{
+ if ( !view || view->d->wordWrapIconText || !wordWrapDirty )
+ return;
+ wordWrapDirty = FALSE;
+
+ int w = iconView()->maxItemWidth() - ( iconView()->itemTextPos() == TQIconView::Bottom ? 0 :
+ pixmapRect().width() );
+ if ( view->d->fm->width( itemText ) < w ) {
+ tmpText = itemText;
+ return;
+ }
+
+ tmpText = "...";
+ int i = 0;
+ while ( view->d->fm->width( tmpText + itemText[ i ] ) < w )
+ tmpText += itemText[ i++ ];
+ tmpText.remove( (uint)0, 3 );
+ tmpText += "...";
+}
+
+/*! \internal */
+
+TQString TQIconViewItem::tempText() const
+{
+ return tmpText;
+}
+
+void TQIconViewItem::checkRect()
+{
+ int x = tqitemRect.x();
+ int y = tqitemRect.y();
+ int w = tqitemRect.width();
+ int h = tqitemRect.height();
+
+ bool changed = FALSE;
+ if ( x < 0 ) {
+ x = 0;
+ changed = TRUE;
+ }
+ if ( y < 0 ) {
+ y = 0;
+ changed = TRUE;
+ }
+
+ if ( changed )
+ tqitemRect.setRect( x, y, w, h );
+}
+
+
+/*! \file iconview/simple_dd/main.h */
+/*! \file iconview/simple_dd/main.cpp */
+
+
+/*!
+ \class TQIconView tqiconview.h
+ \brief The TQIconView class provides an area with movable labelled icons.
+
+ \module iconview
+ \ingroup advanced
+ \mainclass
+
+ A TQIconView can display and manage a grid or other 2D tqlayout of
+ labelled icons. Each labelled icon is a TQIconViewItem. Items
+ (TQIconViewItems) can be added or deleted at any time; items can be
+ moved within the TQIconView. Single or multiple items can be
+ selected. Items can be renamed in-place. TQIconView also supports
+ \link #draganddrop drag and drop\endlink.
+
+ Each item tqcontains a label string, a pixmap or picture (the icon
+ itself) and optionally a sort key. The sort key is used for
+ sorting the items and defaults to the label string. The label
+ string can be displayed below or to the right of the icon (see \l
+ ItemTextPos).
+
+ The simplest way to create a TQIconView is to create a TQIconView
+ object and create some TQIconViewItems with the TQIconView as their
+ tqparent, set the icon view's tqgeometry and show it.
+ For example:
+ \code
+ TQIconView *iv = new TQIconView( this );
+ TQDir dir( path, "*.xpm" );
+ for ( uint i = 0; i < dir.count(); i++ ) {
+ (void) new TQIconViewItem( iv, dir[i], TQPixmap( path + dir[i] ) );
+ }
+ iv->resize( 600, 400 );
+ iv->show();
+ \endcode
+
+ The TQIconViewItem call passes a pointer to the TQIconView we wish to
+ populate, along with the label text and a TQPixmap.
+
+ When an item is inserted the TQIconView allocates a position for it.
+ Existing items are rearranged if autoArrange() is TRUE. The
+ default arrangement is \c LeftToRight -- the TQIconView fills up
+ the \e left-most column from top to bottom, then moves one column
+ \e right and fills that from top to bottom and so on. The
+ arrangement can be modified with any of the following approaches:
+ \list
+ \i Call setArrangement(), e.g. with \c TopToBottom which will fill
+ the \e top-most row from left to right, then moves one row \e down
+ and fills that row from left to right and so on.
+ \i Construct each TQIconViewItem using a constructor which allows
+ you to specify which item the new one is to follow.
+ \i Call setSorting() or sort() to sort the items.
+ \endlist
+
+ The spacing between items is set with setSpacing(). Items can be
+ laid out using a fixed grid using setGridX() and setGridY(); by
+ default the TQIconView calculates a grid dynamically. The position
+ of items' label text is set with setItemTextPos(). The text's
+ background can be set with setItemTextBackground(). The maximum
+ width of an item and of its text are set with setMaxItemWidth()
+ and setMaxItemTextLength(). The label text will be word-wrapped if
+ it is too long; this is controlled by setWordWrapIconText(). If
+ the label text is truncated, the user can still see the entire
+ text in a tool tip if they hover the mouse over the item. This is
+ controlled with setShowToolTips().
+
+ Items which are \link TQIconViewItem::isSelectable()
+ selectable\endlink may be selected depending on the SelectionMode;
+ the default is \c Single. Because TQIconView offers multiple
+ selection it must display keyboard focus and selection state
+ separately. Therefore there are functions to set the selection
+ state of an item (setSelected()) and to select which item displays
+ keyboard focus (setCurrentItem()). When multiple items may be
+ selected the icon view provides a rubberband, too.
+
+ When in-place renaming is enabled (it is disabled by default), the
+ user may change the item's label. They do this by selecting the item
+ (single clicking it or navigating to it with the arrow keys), then
+ single clicking it (or pressing F2), and entering their text. If no
+ key has been set with TQIconViewItem::setKey() the new text will also
+ serve as the key. (See TQIconViewItem::setRenameEnabled().)
+
+ You can control whether users can move items themselves with
+ setItemsMovable().
+
+ Because the internal structure used to store the icon view items is
+ linear, no iterator class is needed to iterate over all the items.
+ Instead we iterate by getting the first item from the \e{icon view}
+ and then each subsequent (\l TQIconViewItem::nextItem()) from each
+ \e item in turn:
+ \code
+ for ( TQIconViewItem *item = iv->firstItem(); item; item = item->nextItem() )
+ do_something( item );
+ \endcode
+ TQIconView also provides currentItem(). You can search for an item
+ using tqfindItem() (searching by position or for label text) and
+ with tqfindFirstVisibleItem() and tqfindLastVisibleItem(). The number
+ of items is returned by count(). An item can be removed from an
+ icon view using takeItem(); to delete an item use \c delete. All
+ the items can be deleted with clear().
+
+ The TQIconView emits a wide range of useful Q_SIGNALS, including
+ selectionChanged(), currentChanged(), clicked(), moved() and
+ itemRenamed().
+
+ \target draganddrop
+ \section1 Drag and Drop
+
+ TQIconView supports the drag and drop of items within the TQIconView
+ itself. It also supports the drag and drop of items out of or into
+ the TQIconView and drag and drop onto items themselves. The drag and
+ drop of items outside the TQIconView can be achieved in a simple way
+ with basic functionality, or in a more sophisticated way which
+ provides more power and control.
+
+ The simple approach to dragging items out of the icon view is to
+ subclass TQIconView and reimplement TQIconView::dragObject().
+
+ \code
+ TQDragObject *MyIconView::dragObject()
+ {
+ return new TQTextDrag( currentItem()->text(), this );
+ }
+ \endcode
+
+ In this example we create a TQTextDrag object, (derived from
+ TQDragObject), containing the item's label and return it as the drag
+ object. We could just as easily have created a TQImageDrag from the
+ item's pixmap and returned that instead.
+
+ TQIconViews and their TQIconViewItems can also be the targets of drag
+ and drops. To make the TQIconView itself able to accept drops connect
+ to the dropped() signal. When a drop occurs this signal will be
+ emitted with a TQDragEvent and a TQValueList of TQIconDragItems. To
+ make a TQIconViewItem into a drop target subclass TQIconViewItem and
+ reimplement TQIconViewItem::acceptDrop() and
+ TQIconViewItem::dropped().
+
+ \code
+ bool MyIconViewItem::acceptDrop( const TQMimeSource *mime ) const
+ {
+ if ( mime->provides( "text/plain" ) )
+ return TRUE;
+ return FALSE;
+ }
+
+ void MyIconViewItem::dropped( TQDropEvent *evt, const TQValueList<TQIconDragItem>& )
+ {
+ TQString label;
+ if ( TQTextDrag::decode( evt, label ) )
+ setText( label );
+ }
+ \endcode
+
+ See \l iconview/simple_dd/main.h and \l
+ iconview/simple_dd/main.cpp for a simple drag and drop example
+ which demonstrates drag and drop between a TQIconView and a
+ TQListBox.
+
+ If you want to use extended drag-and-drop or have drag tqshapes drawn
+ you must take a more sophisticated approach.
+
+ The first part is starting drags -- you should use a TQIconDrag (or a
+ class derived from it) for the drag object. In dragObject() create the
+ drag object, populate it with TQIconDragItems and return it. Normally
+ such a drag should offer each selected item's data. So in dragObject()
+ you should iterate over all the items, and create a TQIconDragItem for
+ each selected item, and append these items with TQIconDrag::append() to
+ the TQIconDrag object. You can use TQIconDragItem::setData() to set the
+ data of each item that should be dragged. If you want to offer the
+ data in additional mime-types, it's best to use a class derived from
+ TQIconDrag, which implements additional encoding and decoding
+ functions.
+
+ When a drag enters the icon view, there is little to do. Simply
+ connect to the dropped() signal and reimplement
+ TQIconViewItem::acceptDrop() and TQIconViewItem::dropped(). If you've
+ used a TQIconDrag (or a subclass of it) the second argument to the
+ dropped signal tqcontains a TQValueList of TQIconDragItems -- you can
+ access their data by calling TQIconDragItem::data() on each one.
+
+ For an example implementation of complex drag-and-drop look at the
+ fileiconview example (qt/examples/fileiconview).
+
+ \sa TQIconViewItem::setDragEnabled(), TQIconViewItem::setDropEnabled(),
+ TQIconViewItem::acceptDrop(), TQIconViewItem::dropped().
+
+ <img src=qiconview-m.png> <img src=qiconview-w.png>
+*/
+
+/*! \enum TQIconView::ResizeMode
+
+ This enum type is used to tell TQIconView how it should treat the
+ positions of its icons when the widget is resized. The modes are:
+
+ \value Fixed The icons' positions are not changed.
+ \value Adjust The icons' positions are adjusted to be within the
+ new tqgeometry, if possible.
+*/
+
+/*!
+ \enum TQIconView::SelectionMode
+
+ This enumerated type is used by TQIconView to indicate how it
+ reacts to selection by the user. It has four values:
+
+ \value Single When the user selects an item, any already-selected
+ item becomes unselected and the user cannot unselect the selected
+ item. This means that the user can never clear the selection. (The
+ application programmer can, using TQIconView::clearSelection().)
+
+ \value Multi When the user selects an item, e.g. by navigating
+ to it with the keyboard arrow keys or by clicking it, the
+ selection status of that item is toggled and the other items are
+ left alone. Also, multiple items can be selected by dragging the
+ mouse while the left mouse button stays pressed.
+
+ \value Extended When the user selects an item the selection is
+ cleared and the new item selected. However, if the user presses
+ the Ctrl key when clicking on an item, the clicked item gets
+ toggled and all other items are left untouched. If the user
+ presses the Shift key while clicking on an item, all items between
+ the current item and the clicked item get selected or unselected,
+ depending on the state of the clicked item. Also, multiple items
+ can be selected by dragging the mouse while the left mouse button
+ stays pressed.
+
+ \value NoSelection Items cannot be selected.
+
+ To summarise: \c Single is a real single-selection icon view; \c
+ Multi a real multi-selection icon view; \c Extended is an icon
+ view in which users can select multiple items but usually want to
+ select either just one or a range of contiguous items; and \c
+ NoSelection mode is for an icon view where the user can look but
+ not touch.
+*/
+
+/*!
+ \enum TQIconView::Arrangement
+
+ This enum type determines in which direction the items flow when
+ the view runs out of space.
+
+ \value LeftToRight Items which don't fit into the view cause the
+ viewport to extend vertically (you get a vertical scrollbar).
+
+ \value TopToBottom Items which don't fit into the view cause the
+ viewport to extend horizontally (you get a horizontal scrollbar).
+*/
+
+/*!
+ \enum TQIconView::ItemTextPos
+
+ This enum type specifies the position of the item text in relation
+ to the icon.
+
+ \value Bottom The text is drawn below the icon.
+ \value Right The text is drawn to the right of the icon.
+*/
+
+/*!
+ \fn void TQIconView::dropped ( TQDropEvent * e, const TQValueList<TQIconDragItem> &lst )
+
+ This signal is emitted when a drop event occurs in the viewport
+ (but not on any icon) which the icon view itself can't handle.
+
+ \a e provides all the information about the drop. If the drag
+ object of the drop was a TQIconDrag, \a lst tqcontains the list of
+ the dropped items. You can get the data using
+ TQIconDragItem::data() on each item. If the \a lst is empty, i.e.
+ the drag was not a TQIconDrag, you have to decode the data in \a e
+ and work with that.
+
+ Note TQIconViewItems may be drop targets; if a drop event occurs on
+ an item the item handles the drop.
+*/
+
+/*!
+ \fn void TQIconView::moved()
+
+ This signal is emitted after successfully dropping one (or more)
+ items of the icon view. If the items should be removed, it's best
+ to do so in a slot connected to this signal.
+*/
+
+/*!
+ \fn void TQIconView::doubleClicked(TQIconViewItem * item)
+
+ This signal is emitted when the user double-clicks on \a item.
+*/
+
+/*!
+ \fn void TQIconView::returnPressed (TQIconViewItem * item)
+
+ This signal is emitted if the user presses the Return or Enter
+ key. \a item is the currentItem() at the time of the keypress.
+*/
+
+/*!
+ \fn void TQIconView::selectionChanged()
+
+ This signal is emitted when the selection has been changed. It's
+ emitted in each selection mode.
+*/
+
+/*!
+ \overload void TQIconView::selectionChanged( TQIconViewItem *item )
+
+ This signal is emitted when the selection changes. \a item is the
+ newly selected item. This signal is emitted only in single
+ selection mode.
+*/
+
+/*!
+ \fn void TQIconView::currentChanged( TQIconViewItem *item )
+
+ This signal is emitted when a new item becomes current. \a item is
+ the new current item (or 0 if no item is now current).
+
+ \sa currentItem()
+*/
+
+/*!
+ \fn void TQIconView::onItem( TQIconViewItem *item )
+
+ This signal is emitted when the user moves the mouse cursor onto
+ an \a item, similar to the TQWidget::enterEvent() function.
+*/
+
+// ### bug here - enter/leave event aren't considered. move the mouse
+// out of the window and back in, to the same item.
+
+/*!
+ \fn void TQIconView::onViewport()
+
+ This signal is emitted when the user moves the mouse cursor from
+ an item to an empty part of the icon view.
+
+ \sa onItem()
+*/
+
+/*!
+ \overload void TQIconView::itemRenamed (TQIconViewItem * item)
+
+ This signal is emitted when \a item has been renamed, usually by
+ in-place renaming.
+
+ \sa TQIconViewItem::setRenameEnabled() TQIconViewItem::rename()
+*/
+
+/*!
+ \fn void TQIconView::itemRenamed (TQIconViewItem * item, const TQString &name)
+
+ This signal is emitted when \a item has been renamed to \a name,
+ usually by in-place renaming.
+
+ \sa TQIconViewItem::setRenameEnabled() TQIconViewItem::rename()
+*/
+
+/*!
+ \fn void TQIconView::rightButtonClicked (TQIconViewItem * item, const TQPoint & pos)
+
+ This signal is emitted when the user clicks the right mouse
+ button. If \a item is non-null, the cursor is on \a item. If \a
+ item is null, the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()). (If the click's
+ press and release differ by a pixel or two, \a pos is the
+ position at release time.)
+
+ \sa rightButtonPressed() mouseButtonClicked() clicked()
+*/
+
+/*!
+ \fn void TQIconView::contextMenuRequested( TQIconViewItem *item, const TQPoint & pos )
+
+ This signal is emitted when the user invokes a context menu with
+ the right mouse button or with special system keys, with \a item
+ being the item under the mouse cursor or the current item,
+ respectively.
+
+ \a pos is the position for the context menu in the global
+ coordinate system.
+*/
+
+/*!
+ \fn void TQIconView::mouseButtonPressed (int button, TQIconViewItem * item, const TQPoint & pos)
+
+ This signal is emitted when the user presses mouse button \a
+ button. If \a item is non-null, the cursor is on \a item. If \a
+ item is null, the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()).
+
+ \sa rightButtonClicked() mouseButtonPressed() pressed()
+*/
+
+/*!
+ \fn void TQIconView::mouseButtonClicked (int button, TQIconViewItem * item, const TQPoint & pos )
+
+ This signal is emitted when the user clicks mouse button \a
+ button. If \a item is non-null, the cursor is on \a item. If \a
+ item is null, the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()). (If the click's
+ press and release differ by a pixel or two, \a pos is the
+ position at release time.)
+
+ \sa mouseButtonPressed() rightButtonClicked() clicked()
+*/
+
+/*!
+ \overload void TQIconView::clicked ( TQIconViewItem * item, const TQPoint & pos )
+
+ This signal is emitted when the user clicks any mouse button on an
+ icon view item. \a item is a pointer to the item that has been
+ clicked.
+
+ \a pos is the position of the mouse cursor in the global coordinate
+ system (TQMouseEvent::globalPos()). (If the click's press and release
+ differ by a pixel or two, \a pos is the position at release time.)
+
+ \sa mouseButtonClicked() rightButtonClicked() pressed()
+*/
+
+/*!
+ \overload void TQIconView::pressed ( TQIconViewItem * item, const TQPoint & pos )
+
+ This signal is emitted when the user presses any mouse button. If
+ \a item is non-null, the cursor is on \a item. If \a item is null,
+ the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()). (If the click's
+ press and release differ by a pixel or two, \a pos is the
+ position at release time.)
+
+ \sa mouseButtonPressed() rightButtonPressed() clicked()
+*/
+
+/*!
+ \fn void TQIconView::clicked ( TQIconViewItem * item )
+
+ This signal is emitted when the user clicks any mouse button. If
+ \a item is non-null, the cursor is on \a item. If \a item is null,
+ the mouse cursor isn't on any item.
+
+ \sa mouseButtonClicked() rightButtonClicked() pressed()
+*/
+
+/*!
+ \fn void TQIconView::pressed ( TQIconViewItem * item )
+
+ This signal is emitted when the user presses any mouse button. If
+ \a item is non-null, the cursor is on \a item. If \a item is null,
+ the mouse cursor isn't on any item.
+
+ \sa mouseButtonPressed() rightButtonPressed() clicked()
+*/
+
+/*!
+ \fn void TQIconView::rightButtonPressed( TQIconViewItem * item, const TQPoint & pos )
+
+ This signal is emitted when the user presses the right mouse
+ button. If \a item is non-null, the cursor is on \a item. If \a
+ item is null, the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()).
+*/
+
+/*!
+ Constructs an empty icon view called \a name, with tqparent \a
+ tqparent and using the widget flags \a f.
+*/
+
+TQIconView::TQIconView( TQWidget *tqparent, const char *name, WFlags f )
+ : TQScrollView( tqparent, name, (WFlags)(TQt::WStaticContents | TQt::WNoAutoErase | f) )
+{
+ if ( !unknown_icon ) {
+ unknown_icon = new TQPixmap( (const char **)unknown_xpm );
+ qiv_cleanup_pixmap.add( &unknown_icon );
+ }
+
+ d = new TQIconViewPrivate;
+ d->dragging = FALSE;
+ d->firstItem = 0;
+ d->lastItem = 0;
+ d->count = 0;
+ d->mousePressed = FALSE;
+ d->selectionMode = Single;
+ d->currentItem = 0;
+ d->highlightedItem = 0;
+ d->rubber = 0;
+ d->scrollTimer = 0;
+ d->startDragItem = 0;
+ d->tmpCurrentItem = 0;
+ d->rastX = d->rastY = -1;
+ d->spacing = 5;
+ d->cleared = FALSE;
+ d->arrangement = LeftToRight;
+ d->resizeMode = Fixed;
+ d->dropped = FALSE;
+ d->adjustTimer = new TQTimer( this, "iconview adjust timer" );
+ d->isIconDrag = FALSE;
+ d->inMenuMode = FALSE;
+#ifndef TQT_NO_DRAGANDDROP
+ d->iconDragData.clear();
+#endif
+ d->numDragItems = 0;
+ d->updateTimer = new TQTimer( this, "iconview update timer" );
+ d->cachedW = d->cachedH = 0;
+ d->maxItemWidth = 100;
+ d->maxItemTextLength = 255;
+ d->inputTimer = new TQTimer( this, "iconview input timer" );
+ d->currInputString = TQString::null;
+ d->dirty = FALSE;
+ d->rearrangeEnabled = TRUE;
+ d->itemTextPos = Bottom;
+ d->reorderItemsWhenInsert = TRUE;
+#ifndef TQT_NO_CURSOR
+ d->oldCursor = Qt::ArrowCursor;
+#endif
+ d->resortItemsWhenInsert = FALSE;
+ d->sortDirection = TRUE;
+ d->wordWrapIconText = TRUE;
+ d->cachedContentsX = d->cachedContentsY = -1;
+ d->clearing = FALSE;
+ d->fullRedrawTimer = new TQTimer( this, "iconview full redraw timer" );
+ d->itemTextBrush = TQBrush(Qt::NoBrush);
+ d->drawAllBack = TRUE;
+ d->fm = new TQFontMetrics( font() );
+ d->minLeftBearing = d->fm->minLeftBearing();
+ d->minRightBearing = d->fm->minRightBearing();
+ d->firstContainer = d->lastContainer = 0;
+ d->containerUpdateLocked = FALSE;
+ d->firstSizeHint = FALSE;
+ d->selectAnchor = 0;
+ d->renamingItem = 0;
+ d->drawActiveSelection = TRUE;
+ d->drawDragShapes = FALSE;
+
+ connect( d->adjustTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( adjustItems() ) );
+ connect( d->updateTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( slotUpdate() ) );
+ connect( d->fullRedrawTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( updateContents() ) );
+ connect( this, TQT_SIGNAL( contentsMoving(int,int) ),
+ this, TQT_SLOT( movedContents(int,int) ) );
+
+ setAcceptDrops( TRUE );
+ viewport()->setAcceptDrops( TRUE );
+
+ setMouseTracking( TRUE );
+ viewport()->setMouseTracking( TRUE );
+
+ viewport()->setBackgroundMode( TQt::PaletteBase);
+ setBackgroundMode( TQt::PaletteBackground, TQt::PaletteBase );
+ viewport()->setFocusProxy( this );
+ viewport()->setFocusPolicy( Qt::WheelFocus );
+
+#ifndef TQT_NO_TOOLTIP
+ d->toolTip = new TQIconViewToolTip( viewport(), this );
+#endif
+ d->showTips = TRUE;
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::styleChange( TQStyle& old )
+{
+ TQScrollView::styleChange( old );
+ *d->fm = TQFontMetrics( font() );
+ d->minLeftBearing = d->fm->minLeftBearing();
+ d->minRightBearing = d->fm->minRightBearing();
+
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ item->wordWrapDirty = TRUE;
+ item->calcRect();
+ }
+
+#if !defined(TQ_WS_X11)
+ delete qiv_selection;
+ qiv_selection = 0;
+#endif
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::setFont( const TQFont & f )
+{
+ TQScrollView::setFont( f );
+ *d->fm = TQFontMetrics( font() );
+ d->minLeftBearing = d->fm->minLeftBearing();
+ d->minRightBearing = d->fm->minRightBearing();
+
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ item->wordWrapDirty = TRUE;
+ item->calcRect();
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::setPalette( const TQPalette & p )
+{
+ TQScrollView::setPalette( p );
+ *d->fm = TQFontMetrics( font() );
+ d->minLeftBearing = d->fm->minLeftBearing();
+ d->minRightBearing = d->fm->minRightBearing();
+
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ item->wordWrapDirty = TRUE;
+ item->calcRect();
+ }
+}
+
+/*!
+ Destroys the icon view and deletes all items.
+*/
+
+TQIconView::~TQIconView()
+{
+ TQIconViewItem *tmp, *item = d->firstItem;
+ d->clearing = TRUE;
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer, *tmpc;
+ while ( c ) {
+ tmpc = c->n;
+ delete c;
+ c = tmpc;
+ }
+ while ( item ) {
+ tmp = item->next;
+ delete item;
+ item = tmp;
+ }
+ delete d->fm;
+ d->fm = 0;
+#ifndef TQT_NO_TOOLTIP
+ delete d->toolTip;
+ d->toolTip = 0;
+#endif
+ delete d;
+}
+
+/*!
+ Inserts the icon view item \a item after \a after. If \a after is
+ 0, \a item is appended after the last item.
+
+ \e{You should never need to call this function.} Instead create
+ TQIconViewItem's and associate them with your icon view like this:
+
+ \code
+ (void) new TQIconViewItem( myIconview, "The text of the item", aPixmap );
+ \endcode
+*/
+
+void TQIconView::insertItem( TQIconViewItem *item, TQIconViewItem *after )
+{
+ if ( !item )
+ return;
+
+ if ( d->firstItem == item || item->prev || item->next)
+ return;
+
+ if ( !item->view )
+ item->view = this;
+
+ if ( !d->firstItem ) {
+ d->firstItem = d->lastItem = item;
+ item->prev = 0;
+ item->next = 0;
+ } else {
+ if ( !after || after == d->lastItem ) {
+ d->lastItem->next = item;
+ item->prev = d->lastItem;
+ item->next = 0;
+ d->lastItem = item;
+ } else {
+ TQIconViewItem *i = d->firstItem;
+ while ( i != after )
+ i = i->next;
+
+ if ( i ) {
+ TQIconViewItem *next = i->next;
+ item->next = next;
+ item->prev = i;
+ i->next = item;
+ next->prev = item;
+ }
+ }
+ }
+
+ if ( isVisible() ) {
+ if ( d->reorderItemsWhenInsert ) {
+ if ( d->updateTimer->isActive() )
+ d->updateTimer->stop();
+ d->fullRedrawTimer->stop();
+ // #### uncomment this ASA insertInGrid uses cached values and is efficient
+ //insertInGrid( item );
+
+ d->cachedW = TQMAX( d->cachedW, item->x() + item->width() );
+ d->cachedH= TQMAX( d->cachedH, item->y() + item->height() );
+
+ d->updateTimer->start( 0, TRUE );
+ } else {
+ insertInGrid( item );
+
+ viewport()->update(item->x() - contentsX(),
+ item->y() - contentsY(),
+ item->width(), item->height());
+ }
+ } else if ( !autoArrange() ) {
+ item->dirty = FALSE;
+ }
+
+ d->count++;
+ d->dirty = TRUE;
+}
+
+/*!
+ This slot is used for a slightly-delayed update.
+
+ The icon view is not redrawn immediately after inserting a new item
+ but after a very small delay using a TQTimer. This means that when
+ many items are inserted in a loop the icon view is probably redrawn
+ only once at the end of the loop. This makes the insertions both
+ flicker-free and faster.
+*/
+
+void TQIconView::slotUpdate()
+{
+ d->updateTimer->stop();
+ d->fullRedrawTimer->stop();
+
+ if ( !d->firstItem || !d->lastItem )
+ return;
+
+ // #### remove that ASA insertInGrid uses cached values and is efficient
+ if ( d->resortItemsWhenInsert )
+ sort( d->sortDirection );
+ else {
+ int y = d->spacing;
+ TQIconViewItem *item = d->firstItem;
+ int w = 0, h = 0;
+ while ( item ) {
+ bool changed;
+ TQIconViewItem *next = makeRowLayout( item, y, changed );
+ if ( !next || !next->next )
+ break;
+
+ if( !TQApplication::reverseLayout() )
+ item = next;
+ w = TQMAX( w, item->x() + item->width() );
+ h = TQMAX( h, item->y() + item->height() );
+ item = next;
+ if ( d->arrangement == LeftToRight )
+ h = TQMAX( h, y );
+
+ item = item->next;
+ }
+
+ if ( d->lastItem && d->arrangement == TopToBottom ) {
+ item = d->lastItem;
+ int x = item->x();
+ while ( item && item->x() >= x ) {
+ w = TQMAX( w, item->x() + item->width() );
+ h = TQMAX( h, item->y() + item->height() );
+ item = item->prev;
+ }
+ }
+
+ w = TQMAX( TQMAX( d->cachedW, w ), d->lastItem->x() + d->lastItem->width() );
+ h = TQMAX( TQMAX( d->cachedH, h ), d->lastItem->y() + d->lastItem->height() );
+
+ if ( d->arrangement == TopToBottom )
+ w += d->spacing;
+ else
+ h += d->spacing;
+ viewport()->setUpdatesEnabled( FALSE );
+ resizeContents( w, h );
+ viewport()->setUpdatesEnabled( TRUE );
+ viewport()->tqrepaint( FALSE );
+ }
+
+ int cx = d->cachedContentsX == -1 ? contentsX() : d->cachedContentsX;
+ int cy = d->cachedContentsY == -1 ? contentsY() : d->cachedContentsY;
+
+ if ( cx != contentsX() || cy != contentsY() )
+ setContentsPos( cx, cy );
+
+ d->cachedContentsX = d->cachedContentsY = -1;
+ d->cachedW = d->cachedH = 0;
+}
+
+/*!
+ Takes the icon view item \a item out of the icon view and causes
+ an update of the screen display. The item is not deleted. You
+ should normally not need to call this function because
+ TQIconViewItem::~TQIconViewItem() calls it. The normal way to delete
+ an item is to delete it.
+*/
+
+void TQIconView::takeItem( TQIconViewItem *item )
+{
+ if ( !item )
+ return;
+
+ if ( item->d->container1 )
+ item->d->container1->items.removeRef( item );
+ if ( item->d->container2 )
+ item->d->container2->items.removeRef( item );
+ item->d->container2 = 0;
+ item->d->container1 = 0;
+
+ bool block = tqsignalsBlocked();
+ blockSignals( d->clearing );
+
+ TQRect r = item->rect();
+
+ if ( d->currentItem == item ) {
+ if ( item->prev ) {
+ d->currentItem = item->prev;
+ emit currentChanged( d->currentItem );
+ repaintItem( d->currentItem );
+ } else if ( item->next ) {
+ d->currentItem = item->next;
+ emit currentChanged( d->currentItem );
+ repaintItem( d->currentItem );
+ } else {
+ d->currentItem = 0;
+ emit currentChanged( d->currentItem );
+ }
+ }
+ if ( item->isSelected() ) {
+ item->selected = FALSE;
+ emit selectionChanged();
+ }
+
+ if ( item == d->firstItem ) {
+ d->firstItem = d->firstItem->next;
+ if ( d->firstItem )
+ d->firstItem->prev = 0;
+ } else if ( item == d->lastItem ) {
+ d->lastItem = d->lastItem->prev;
+ if ( d->lastItem )
+ d->lastItem->next = 0;
+ } else {
+ TQIconViewItem *i = item;
+ if ( i ) {
+ if ( i->prev )
+ i->prev->next = i->next;
+ if ( i->next )
+ i->next->prev = i->prev;
+ }
+ }
+
+ if ( d->selectAnchor == item )
+ d->selectAnchor = d->currentItem;
+
+ if ( !d->clearing )
+ repaintContents( r.x(), r.y(), r.width(), r.height(), TRUE );
+
+ item->view = 0;
+ item->prev = 0;
+ item->next = 0;
+ d->count--;
+
+ blockSignals( block );
+}
+
+/*!
+ Returns the index of \a item, or -1 if \a item doesn't exist in
+ this icon view.
+*/
+
+int TQIconView::index( const TQIconViewItem *item ) const
+{
+ if ( !item )
+ return -1;
+
+ if ( item == d->firstItem )
+ return 0;
+ else if ( item == d->lastItem )
+ return d->count - 1;
+ else {
+ TQIconViewItem *i = d->firstItem;
+ int j = 0;
+ while ( i && i != item ) {
+ i = i->next;
+ ++j;
+ }
+
+ return i ? j : -1;
+ }
+}
+
+/*!
+ Returns a pointer to the first item of the icon view, or 0 if
+ there are no items in the icon view.
+
+ \sa lastItem() currentItem()
+*/
+
+TQIconViewItem *TQIconView::firstItem() const
+{
+ return d->firstItem;
+}
+
+/*!
+ Returns a pointer to the last item of the icon view, or 0 if there
+ are no items in the icon view.
+
+ \sa firstItem() currentItem()
+*/
+
+TQIconViewItem *TQIconView::lastItem() const
+{
+ return d->lastItem;
+}
+
+/*!
+ Returns a pointer to the current item of the icon view, or 0 if no
+ item is current.
+
+ \sa setCurrentItem() firstItem() lastItem()
+*/
+
+TQIconViewItem *TQIconView::currentItem() const
+{
+ return d->currentItem;
+}
+
+/*!
+ Makes \a item the new current item of the icon view.
+*/
+
+void TQIconView::setCurrentItem( TQIconViewItem *item )
+{
+ if ( !item || item == d->currentItem )
+ return;
+
+ setMicroFocusHint( item->x(), item->y(), item->width(), item->height(), FALSE );
+
+ TQIconViewItem *old = d->currentItem;
+ d->currentItem = item;
+ emit currentChanged( d->currentItem );
+ if ( d->selectionMode == Single ) {
+ bool changed = FALSE;
+ if ( old && old->selected ) {
+ old->selected = FALSE;
+ changed = TRUE;
+ }
+ if ( item && !item->selected && item->isSelectable() && d->selectionMode != NoSelection ) {
+ item->selected = TRUE;
+ changed = TRUE;
+ emit selectionChanged( item );
+ }
+ if ( changed )
+ emit selectionChanged();
+ }
+
+ if ( old )
+ repaintItem( old );
+ repaintItem( d->currentItem );
+}
+
+/*!
+ Selects or unselects \a item depending on \a s, and may also
+ unselect other items, depending on TQIconView::selectionMode() and
+ \a cb.
+
+ If \a s is FALSE, \a item is unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Single, \a
+ item is selected, and the item which was selected is unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Extended, \a
+ item is selected. If \a cb is TRUE, the selection state of the
+ icon view's other items is left unchanged. If \a cb is FALSE (the
+ default) all other items are unselected.
+
+ If \a s is TRUE and TQIconView::selectionMode() is \c Multi \a item
+ is selected.
+
+ Note that \a cb is used only if TQIconView::selectionMode() is \c
+ Extended. \a cb defaults to FALSE.
+
+ All items whose selection status is changed tqrepaint themselves.
+*/
+
+void TQIconView::setSelected( TQIconViewItem *item, bool s, bool cb )
+{
+ if ( !item )
+ return;
+ item->setSelected( s, cb );
+}
+
+/*!
+ \property TQIconView::count
+ \brief the number of items in the icon view
+*/
+
+uint TQIconView::count() const
+{
+ return d->count;
+}
+
+/*!
+ Performs autoscrolling when selecting multiple icons with the
+ rubber band.
+*/
+
+void TQIconView::doAutoScroll()
+{
+ TQRect oldRubber = TQRect( *d->rubber );
+
+ TQPoint vp = viewport()->mapFromGlobal( TQCursor::pos() );
+ TQPoint pos = viewportToContents( vp );
+
+ if ( pos == d->rubber->bottomRight() )
+ return;
+
+ d->rubber->setRight( pos.x() );
+ d->rubber->setBottom( pos.y() );
+
+ int minx = contentsWidth(), miny = contentsHeight();
+ int maxx = 0, maxy = 0;
+ bool changed = FALSE;
+ bool block = tqsignalsBlocked();
+
+ TQRect rr;
+ TQRegion region( 0, 0, visibleWidth(), visibleHeight() );
+
+ blockSignals( TRUE );
+ viewport()->setUpdatesEnabled( FALSE );
+ bool alreadyIntersected = FALSE;
+ TQRect nr = d->rubber->normalize();
+ TQRect rubberUnion = nr.unite( oldRubber.normalize() );
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ for ( ; c; c = c->n ) {
+ if ( c->rect.intersects( rubberUnion ) ) {
+ alreadyIntersected = TRUE;
+ TQIconViewItem *item = c->items.first();
+ for ( ; item; item = c->items.next() ) {
+ if ( d->selectedItems.tqfind( item ) )
+ continue;
+ if ( !item->intersects( nr ) ) {
+ if ( item->isSelected() ) {
+ item->setSelected( FALSE );
+ changed = TRUE;
+ rr = rr.unite( item->rect() );
+ }
+ } else if ( item->intersects( nr ) ) {
+ if ( !item->isSelected() && item->isSelectable() ) {
+ item->setSelected( TRUE, TRUE );
+ changed = TRUE;
+ rr = rr.unite( item->rect() );
+ } else {
+ region = region.subtract( TQRect( contentsToViewport( item->pos() ),
+ item->size() ) );
+ }
+
+ minx = TQMIN( minx, item->x() - 1 );
+ miny = TQMIN( miny, item->y() - 1 );
+ maxx = TQMAX( maxx, item->x() + item->width() + 1 );
+ maxy = TQMAX( maxy, item->y() + item->height() + 1 );
+ }
+ }
+ } else {
+ if ( alreadyIntersected )
+ break;
+ }
+ }
+ viewport()->setUpdatesEnabled( TRUE );
+ blockSignals( block );
+
+ TQRect r = *d->rubber;
+ *d->rubber = oldRubber;
+
+ TQPainter p;
+ p.begin( viewport() );
+ p.setRasterOp( TQt::NotROP );
+ p.setPen( TQPen( Qt::color0, 1 ) );
+ p.setBrush( Qt::NoBrush );
+ drawRubber( &p );
+ d->dragging = FALSE;
+ p.end();
+
+ *d->rubber = r;
+
+ if ( changed ) {
+ d->drawAllBack = FALSE;
+ d->clipRegion = region;
+ repaintContents( rr, FALSE );
+ d->drawAllBack = TRUE;
+ }
+
+ ensureVisible( pos.x(), pos.y() );
+
+ p.begin( viewport() );
+ p.setRasterOp( TQt::NotROP );
+ p.setPen( TQPen( Qt::color0, 1 ) );
+ p.setBrush( Qt::NoBrush );
+ drawRubber( &p );
+ d->dragging = TRUE;
+
+ p.end();
+
+ if ( changed ) {
+ emit selectionChanged();
+ if ( d->selectionMode == Single )
+ emit selectionChanged( d->currentItem );
+ }
+
+ if ( !TQRect( 50, 50, viewport()->width()-100, viewport()->height()-100 ).tqcontains( vp ) &&
+ !d->scrollTimer ) {
+ d->scrollTimer = new TQTimer( this );
+
+ connect( d->scrollTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( doAutoScroll() ) );
+ d->scrollTimer->start( 100, FALSE );
+ } else if ( TQRect( 50, 50, viewport()->width()-100, viewport()->height()-100 ).tqcontains( vp ) &&
+ d->scrollTimer ) {
+ disconnect( d->scrollTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( doAutoScroll() ) );
+ d->scrollTimer->stop();
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ }
+
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::drawContents( TQPainter *p, int cx, int cy, int cw, int ch )
+{
+ if ( d->dragging && d->rubber )
+ drawRubber( p );
+
+ TQRect r = TQRect( cx, cy, cw, ch );
+
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ TQRegion remaining( TQRect( cx, cy, cw, ch ) );
+ bool alreadyIntersected = FALSE;
+ while ( c ) {
+ if ( c->rect.intersects( r ) ) {
+ p->save();
+ p->resetXForm();
+ TQRect r2 = c->rect;
+ r2 = r2.intersect( r );
+ TQRect r3( contentsToViewport( TQPoint( r2.x(), r2.y() ) ), TQSize( r2.width(), r2.height() ) );
+ if ( d->drawAllBack ) {
+ p->setClipRect( r3 );
+ } else {
+ TQRegion reg = d->clipRegion.intersect( r3 );
+ p->setClipRegion( reg );
+ }
+ drawBackground( p, r3 );
+ remaining = remaining.subtract( r3 );
+ p->restore();
+
+ TQColorGroup cg;
+ d->drawActiveSelection = hasFocus() || d->inMenuMode
+ || !tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this );
+
+ if ( !d->drawActiveSelection )
+ cg = tqpalette().inactive();
+ else
+ cg = tqcolorGroup();
+
+ TQIconViewItem *item = c->items.first();
+ // clip items to the container rect by default... this
+ // prevents icons with alpha channels from being painted
+ // twice when they are in 2 containers
+ //
+ // NOTE: the item could override this cliprect in it's
+ // paintItem() implementation, which makes this useless
+ p->setClipRect( TQRect( contentsToViewport( r2.topLeft() ), r2.size() ) );
+ for ( ; item; item = c->items.next() ) {
+ if ( item->rect().intersects( r ) && !item->dirty ) {
+ p->save();
+ p->setFont( font() );
+ item->paintItem( p, cg );
+ p->restore();
+ }
+ }
+ alreadyIntersected = TRUE;
+ } else {
+ if ( alreadyIntersected )
+ break;
+ }
+ c = c->n;
+ }
+
+ if ( !remaining.isNull() && !remaining.isEmpty() ) {
+ p->save();
+ p->resetXForm();
+ if ( d->drawAllBack ) {
+ p->setClipRegion( remaining );
+ } else {
+ remaining = d->clipRegion.intersect( remaining );
+ p->setClipRegion( remaining );
+ }
+ drawBackground( p, remaining.boundingRect() );
+ p->restore();
+ }
+
+ if ( ( hasFocus() || viewport()->hasFocus() ) && d->currentItem &&
+ d->currentItem->rect().intersects( r ) ) {
+ d->currentItem->paintFocus( p, tqcolorGroup() );
+ }
+
+ if ( d->dragging && d->rubber )
+ drawRubber( p );
+}
+
+/*!
+ \overload
+
+ Arranges all the items in the grid given by gridX() and gridY().
+
+ Even if sorting() is enabled, the items are not sorted by this
+ function. If you want to sort or rearrange the items, use
+ iconview->sort(iconview->sortDirection()).
+
+ If \a update is TRUE (the default), the viewport is repainted as
+ well.
+
+ \sa TQIconView::setGridX(), TQIconView::setGridY(), TQIconView::sort()
+*/
+
+void TQIconView::arrangeItemsInGrid( bool update )
+{
+ if ( !d->firstItem || !d->lastItem )
+ return;
+
+ d->containerUpdateLocked = TRUE;
+
+ int w = 0, h = 0, y = d->spacing;
+
+ TQIconViewItem *item = d->firstItem;
+ bool changedLayout = FALSE;
+ while ( item ) {
+ bool changed;
+ TQIconViewItem *next = makeRowLayout( item, y, changed );
+ changedLayout = changed || changedLayout;
+ if( !TQApplication::reverseLayout() )
+ item = next;
+ w = TQMAX( w, item->x() + item->width() );
+ h = TQMAX( h, item->y() + item->height() );
+ item = next;
+ if ( d->arrangement == LeftToRight )
+ h = TQMAX( h, y );
+
+ if ( !item || !item->next )
+ break;
+
+ item = item->next;
+ }
+
+ if ( d->lastItem && d->arrangement == TopToBottom ) {
+ item = d->lastItem;
+ int x = item->x();
+ while ( item && item->x() >= x ) {
+ w = TQMAX( w, item->x() + item->width() );
+ h = TQMAX( h, item->y() + item->height() );
+ item = item->prev;
+ }
+ }
+ d->containerUpdateLocked = FALSE;
+
+ w = TQMAX( TQMAX( d->cachedW, w ), d->lastItem->x() + d->lastItem->width() );
+ h = TQMAX( TQMAX( d->cachedH, h ), d->lastItem->y() + d->lastItem->height() );
+
+ if ( d->arrangement == TopToBottom )
+ w += d->spacing;
+ else
+ h += d->spacing;
+
+ bool ue = isUpdatesEnabled();
+ viewport()->setUpdatesEnabled( FALSE );
+ int vw = visibleWidth();
+ int vh = visibleHeight();
+ resizeContents( w, h );
+ bool doAgain = FALSE;
+ if ( d->arrangement == LeftToRight )
+ doAgain = visibleWidth() != vw;
+ if ( d->arrangement == TopToBottom )
+ doAgain = visibleHeight() != vh;
+ if ( doAgain ) // in the case that the visibleExtend changed because of the resizeContents (scrollbar show/hide), redo tqlayout again
+ arrangeItemsInGrid( FALSE );
+ viewport()->setUpdatesEnabled( ue );
+ d->dirty = !isVisible();
+ rebuildContainers();
+ if ( update && ( !optimize_tqlayout || changedLayout ) )
+ repaintContents( contentsX(), contentsY(), viewport()->width(), viewport()->height(), FALSE );
+}
+
+/*!
+ This variant uses \a grid instead of (gridX(), gridY()). If \a
+ grid is invalid (see TQSize::isValid()), arrangeItemsInGrid()
+ calculates a valid grid itself and uses that.
+
+ If \a update is TRUE (the default) the viewport is repainted.
+*/
+
+void TQIconView::arrangeItemsInGrid( const TQSize &grid, bool update )
+{
+ d->containerUpdateLocked = TRUE;
+ TQSize grid_( grid );
+ if ( !grid_.isValid() ) {
+ int w = 0, h = 0;
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ w = TQMAX( w, item->width() );
+ h = TQMAX( h, item->height() );
+ }
+
+ grid_ = TQSize( TQMAX( d->rastX + d->spacing, w ),
+ TQMAX( d->rastY + d->spacing, h ) );
+ }
+
+ int w = 0, h = 0;
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ int nx = item->x() / grid_.width();
+ int ny = item->y() / grid_.height();
+ item->move( nx * grid_.width(),
+ ny * grid_.height() );
+ w = TQMAX( w, item->x() + item->width() );
+ h = TQMAX( h, item->y() + item->height() );
+ item->dirty = FALSE;
+ }
+ d->containerUpdateLocked = FALSE;
+
+ resizeContents( w, h );
+ rebuildContainers();
+ if ( update )
+ repaintContents( contentsX(), contentsY(), viewport()->width(), viewport()->height(), FALSE );
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::setContentsPos( int x, int y )
+{
+ if ( d->updateTimer->isActive() ) {
+ d->cachedContentsX = x;
+ d->cachedContentsY = y;
+ } else {
+ d->cachedContentsY = d->cachedContentsX = -1;
+ TQScrollView::setContentsPos( x, y );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::showEvent( TQShowEvent * )
+{
+ if ( d->dirty ) {
+ resizeContents( TQMAX( contentsWidth(), viewport()->width() ),
+ TQMAX( contentsHeight(), viewport()->height() ) );
+ if ( d->resortItemsWhenInsert )
+ sort( d->sortDirection );
+ if ( autoArrange() )
+ arrangeItemsInGrid( FALSE );
+ }
+ TQScrollView::show();
+}
+
+/*!
+ \property TQIconView::selectionMode
+ \brief the selection mode of the icon view
+
+ This can be \c Single (the default), \c Extended, \c Multi or \c
+ NoSelection.
+*/
+
+void TQIconView::setSelectionMode( SelectionMode m )
+{
+ d->selectionMode = m;
+}
+
+TQIconView::SelectionMode TQIconView::selectionMode() const
+{
+ return d->selectionMode;
+}
+
+/*!
+ Returns a pointer to the item that tqcontains point \a pos, which is
+ given in contents coordinates, or 0 if no item tqcontains point \a
+ pos.
+*/
+
+TQIconViewItem *TQIconView::tqfindItem( const TQPoint &pos ) const
+{
+ if ( !d->firstItem )
+ return 0;
+
+ TQIconViewPrivate::ItemContainer *c = d->lastContainer;
+ for ( ; c; c = c->p ) {
+ if ( c->rect.tqcontains( pos ) ) {
+ TQIconViewItem *item = c->items.last();
+ for ( ; item; item = c->items.prev() )
+ if ( item->tqcontains( pos ) )
+ return item;
+ }
+ }
+
+ return 0;
+}
+
+/*!
+ \overload
+
+ Returns a pointer to the first item whose text begins with \a
+ text, or 0 if no such item could be found. Use the \a compare flag
+ to control the comparison behaviour. (See \l
+ {TQt::StringComparisonMode}.)
+*/
+
+TQIconViewItem *TQIconView::tqfindItem( const TQString &text, TQt::ComparisonFlags compare ) const
+{
+ if ( !d->firstItem )
+ return 0;
+
+ if ( compare == TQt::CaseSensitive || compare == 0 )
+ compare |= TQt::ExactMatch;
+
+ TQString itmtxt;
+ TQString comtxt = text;
+ if ( ! (compare & TQt::CaseSensitive) )
+ comtxt = text.lower();
+
+ TQIconViewItem *item;
+ if ( d->currentItem )
+ item = d->currentItem;
+ else
+ item = d->firstItem;
+
+ TQIconViewItem *beginsWithItem = 0;
+ TQIconViewItem *endsWithItem = 0;
+ TQIconViewItem *tqcontainsItem = 0;
+
+ if ( item ) {
+ for ( ; item; item = item->next ) {
+ if ( ! (compare & TQt::CaseSensitive) )
+ itmtxt = item->text().lower();
+ else
+ itmtxt = item->text();
+
+ if ( compare & TQt::ExactMatch && itmtxt == comtxt )
+ return item;
+ if ( compare & TQt::BeginsWith && !beginsWithItem && itmtxt.startsWith( comtxt ) )
+ beginsWithItem = tqcontainsItem = item;
+ if ( compare & TQt::EndsWith && !endsWithItem && itmtxt.endsWith( comtxt ) )
+ endsWithItem = tqcontainsItem = item;
+ if ( compare & TQt::Contains && !tqcontainsItem && itmtxt.tqcontains( comtxt ) )
+ tqcontainsItem = item;
+ }
+
+ if ( d->currentItem && d->firstItem ) {
+ item = d->firstItem;
+ for ( ; item && item != d->currentItem; item = item->next ) {
+ if ( ! (compare & TQt::CaseSensitive) )
+ itmtxt = item->text().lower();
+ else
+ itmtxt = item->text();
+
+ if ( compare & TQt::ExactMatch && itmtxt == comtxt )
+ return item;
+ if ( compare & TQt::BeginsWith && !beginsWithItem && itmtxt.startsWith( comtxt ) )
+ beginsWithItem = tqcontainsItem = item;
+ if ( compare & TQt::EndsWith && !endsWithItem && itmtxt.endsWith( comtxt ) )
+ endsWithItem = tqcontainsItem = item;
+ if ( compare & TQt::Contains && !tqcontainsItem && itmtxt.tqcontains( comtxt ) )
+ tqcontainsItem = item;
+ }
+ }
+ }
+
+ // Obey the priorities
+ if ( beginsWithItem )
+ return beginsWithItem;
+ else if ( endsWithItem )
+ return endsWithItem;
+ else if ( tqcontainsItem )
+ return tqcontainsItem;
+ return 0;
+}
+
+/*!
+ Unselects all the items.
+*/
+
+void TQIconView::clearSelection()
+{
+ selectAll( FALSE );
+}
+
+/*!
+ In Multi and Extended modes, this function sets all items to be
+ selected if \a select is TRUE, and to be unselected if \a select
+ is FALSE.
+
+ In Single and NoSelection modes, this function only changes the
+ selection status of currentItem().
+*/
+
+void TQIconView::selectAll( bool select )
+{
+ if ( d->selectionMode == NoSelection )
+ return;
+
+ if ( d->selectionMode == Single ) {
+ if ( d->currentItem )
+ d->currentItem->setSelected( select );
+ return;
+ }
+
+ bool b = tqsignalsBlocked();
+ blockSignals( TRUE );
+ TQIconViewItem *item = d->firstItem;
+ TQIconViewItem *i = d->currentItem;
+ bool changed = FALSE;
+ bool ue = viewport()->isUpdatesEnabled();
+ viewport()->setUpdatesEnabled( FALSE );
+ TQRect rr;
+ for ( ; item; item = item->next ) {
+ if ( select != item->isSelected() ) {
+ item->setSelected( select, TRUE );
+ rr = rr.unite( item->rect() );
+ changed = TRUE;
+ }
+ }
+ viewport()->setUpdatesEnabled( ue );
+ // we call updateContents not repaintContents because of possible previous updateContents
+ TQScrollView::updateContents( rr );
+ TQApplication::sendPostedEvents( viewport(), TQEvent::Paint );
+ if ( i )
+ setCurrentItem( i );
+ blockSignals( b );
+ if ( changed ) {
+ emit selectionChanged();
+ }
+}
+
+/*!
+ Inverts the selection. Works only in Multi and Extended selection
+ mode.
+*/
+
+void TQIconView::invertSelection()
+{
+ if ( d->selectionMode == Single ||
+ d->selectionMode == NoSelection )
+ return;
+
+ bool b = tqsignalsBlocked();
+ blockSignals( TRUE );
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next )
+ item->setSelected( !item->isSelected(), TRUE );
+ blockSignals( b );
+ emit selectionChanged();
+}
+
+/*!
+ Repaints the \a item.
+*/
+
+void TQIconView::repaintItem( TQIconViewItem *item )
+{
+ if ( !item || item->dirty )
+ return;
+
+ if ( TQRect( contentsX(), contentsY(), visibleWidth(), visibleHeight() ).
+ intersects( TQRect( item->x() - 1, item->y() - 1, item->width() + 2, item->height() + 2 ) ) )
+ repaintContents( item->x() - 1, item->y() - 1, item->width() + 2, item->height() + 2, FALSE );
+}
+
+/*!
+ Repaints the selected items.
+*/
+void TQIconView::repaintSelectedItems()
+{
+ if ( selectionMode() == NoSelection )
+ return;
+
+ if ( selectionMode() == Single ) {
+ if ( !currentItem() || !currentItem()->isSelected() )
+ return;
+ TQRect tqitemRect = currentItem()->rect(); //rect in contents coordinates
+ tqitemRect.moveBy( -contentsX(), -contentsY() );
+ viewport()->update( tqitemRect );
+ } else {
+ // check if any selected items are visible
+ TQIconViewItem *item = firstItem();
+ const TQRect vr = TQRect( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
+
+ while ( item ) {
+ if ( item->isSelected() && item->rect().intersects( vr ) )
+ repaintItem( item );
+ item = item->nextItem();
+ }
+ }
+}
+
+/*!
+ Makes sure that \a item is entirely visible. If necessary,
+ ensureItemVisible() scrolls the icon view.
+
+ \sa ensureVisible()
+*/
+
+void TQIconView::ensureItemVisible( TQIconViewItem *item )
+{
+ if ( !item )
+ return;
+
+ if ( (d->updateTimer && d->updateTimer->isActive()) ||
+ (d->fullRedrawTimer && d->fullRedrawTimer->isActive()) )
+ slotUpdate();
+
+ int w = item->width();
+ int h = item->height();
+ ensureVisible( item->x() + w / 2, item->y() + h / 2,
+ w / 2 + 1, h / 2 + 1 );
+}
+
+/*!
+ Finds the first item whose bounding rectangle overlaps \a r and
+ returns a pointer to that item. \a r is given in content
+ coordinates. Returns 0 if no item overlaps \a r.
+
+ If you want to tqfind all items that touch \a r, you will need to
+ use this function and nextItem() in a loop ending at
+ tqfindLastVisibleItem() and test TQIconViewItem::rect() for each of
+ these items.
+
+ \sa tqfindLastVisibleItem() TQIconViewItem::rect()
+*/
+
+TQIconViewItem* TQIconView::tqfindFirstVisibleItem( const TQRect &r ) const
+{
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ TQIconViewItem *i = 0;
+ bool alreadyIntersected = FALSE;
+ for ( ; c; c = c->n ) {
+ if ( c->rect.intersects( r ) ) {
+ alreadyIntersected = TRUE;
+ TQIconViewItem *item = c->items.first();
+ for ( ; item; item = c->items.next() ) {
+ if ( r.intersects( item->rect() ) ) {
+ if ( !i ) {
+ i = item;
+ } else {
+ TQRect r2 = item->rect();
+ TQRect r3 = i->rect();
+ if ( r2.y() < r3.y() )
+ i = item;
+ else if ( r2.y() == r3.y() &&
+ r2.x() < r3.x() )
+ i = item;
+ }
+ }
+ }
+ } else {
+ if ( alreadyIntersected )
+ break;
+ }
+ }
+
+ return i;
+}
+
+/*!
+ Finds the last item whose bounding rectangle overlaps \a r and
+ returns a pointer to that item. \a r is given in content
+ coordinates. Returns 0 if no item overlaps \a r.
+
+ \sa tqfindFirstVisibleItem()
+*/
+
+TQIconViewItem* TQIconView::tqfindLastVisibleItem( const TQRect &r ) const
+{
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ TQIconViewItem *i = 0;
+ bool alreadyIntersected = FALSE;
+ for ( ; c; c = c->n ) {
+ if ( c->rect.intersects( r ) ) {
+ alreadyIntersected = TRUE;
+ TQIconViewItem *item = c->items.first();
+ for ( ; item; item = c->items.next() ) {
+ if ( r.intersects( item->rect() ) ) {
+ if ( !i ) {
+ i = item;
+ } else {
+ TQRect r2 = item->rect();
+ TQRect r3 = i->rect();
+ if ( r2.y() > r3.y() )
+ i = item;
+ else if ( r2.y() == r3.y() &&
+ r2.x() > r3.x() )
+ i = item;
+ }
+ }
+ }
+ } else {
+ if ( alreadyIntersected )
+ break;
+ }
+ }
+
+ return i;
+}
+
+/*!
+ Clears the icon view. All items are deleted.
+*/
+
+void TQIconView::clear()
+{
+ setContentsPos( 0, 0 );
+ d->clearing = TRUE;
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ clearSelection();
+ blockSignals( block );
+ setContentsPos( 0, 0 );
+ d->currentItem = 0;
+
+ if ( !d->firstItem ) {
+ d->clearing = FALSE;
+ return;
+ }
+
+ TQIconViewItem *item = d->firstItem, *tmp;
+ d->firstItem = 0;
+ while ( item ) {
+ tmp = item->next;
+ delete item;
+ item = tmp;
+ }
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer, *tmpc;
+ while ( c ) {
+ tmpc = c->n;
+ delete c;
+ c = tmpc;
+ }
+ d->firstContainer = d->lastContainer = 0;
+
+ d->count = 0;
+ d->lastItem = 0;
+ setCurrentItem( 0 );
+ d->highlightedItem = 0;
+ d->tmpCurrentItem = 0;
+ d->drawDragShapes = FALSE;
+
+ resizeContents( 0, 0 );
+ // maybe we don�t need this update, so delay it
+ d->fullRedrawTimer->start( 0, TRUE );
+
+ d->cleared = TRUE;
+ d->clearing = FALSE;
+}
+
+/*!
+ \property TQIconView::gridX
+ \brief the horizontal grid of the icon view
+
+ If the value is -1, (the default), TQIconView computes suitable
+ column widths based on the icon view's contents.
+
+ Note that setting a grid width overrides setMaxItemWidth().
+*/
+
+void TQIconView::setGridX( int rx )
+{
+ d->rastX = rx >= 0 ? rx : -1;
+}
+
+/*!
+ \property TQIconView::gridY
+ \brief the vertical grid of the icon view
+
+ If the value is -1, (the default), TQIconView computes suitable
+ column heights based on the icon view's contents.
+*/
+
+void TQIconView::setGridY( int ry )
+{
+ d->rastY = ry >= 0 ? ry : -1;
+}
+
+int TQIconView::gridX() const
+{
+ return d->rastX;
+}
+
+int TQIconView::gridY() const
+{
+ return d->rastY;
+}
+
+/*!
+ \property TQIconView::spacing
+ \brief the space in pixels between icon view items
+
+ The default is 5 pixels.
+
+ Negative values for spacing are illegal.
+*/
+
+void TQIconView::setSpacing( int sp )
+{
+ d->spacing = sp;
+}
+
+int TQIconView::spacing() const
+{
+ return d->spacing;
+}
+
+/*!
+ \property TQIconView::itemTextPos
+ \brief the position where the text of each item is drawn.
+
+ Valid values are \c Bottom or \c Right. The default is \c Bottom.
+*/
+
+void TQIconView::setItemTextPos( ItemTextPos pos )
+{
+ if ( pos == d->itemTextPos || ( pos != Bottom && pos != Right ) )
+ return;
+
+ d->itemTextPos = pos;
+
+ TQIconViewItem *item = d->firstItem;
+ for ( ; item; item = item->next ) {
+ item->wordWrapDirty = TRUE;
+ item->calcRect();
+ }
+
+ arrangeItemsInGrid( TRUE );
+}
+
+TQIconView::ItemTextPos TQIconView::itemTextPos() const
+{
+ return d->itemTextPos;
+}
+
+/*!
+ \property TQIconView::itemTextBackground
+ \brief the brush to use when drawing the background of an item's text.
+
+ By default this brush is set to Qt::NoBrush, meaning that only the
+ normal icon view background is used.
+*/
+
+void TQIconView::setItemTextBackground( const TQBrush &brush )
+{
+ d->itemTextBrush = brush;
+}
+
+TQBrush TQIconView::itemTextBackground() const
+{
+ return d->itemTextBrush;
+}
+
+/*!
+ \property TQIconView::arrangement
+ \brief the arrangement mode of the icon view
+
+ This can be \c LeftToRight or \c TopToBottom. The default is \c
+ LeftToRight.
+*/
+
+void TQIconView::setArrangement( Arrangement am )
+{
+ if ( d->arrangement == am )
+ return;
+
+ d->arrangement = am;
+
+ viewport()->setUpdatesEnabled( FALSE );
+ resizeContents( viewport()->width(), viewport()->height() );
+ viewport()->setUpdatesEnabled( TRUE );
+ arrangeItemsInGrid( TRUE );
+}
+
+TQIconView::Arrangement TQIconView::arrangement() const
+{
+ return d->arrangement;
+}
+
+/*!
+ \property TQIconView::resizeMode
+ \brief the resize mode of the icon view
+
+ This can be \c Fixed or \c Adjust. The default is \c Fixed.
+ See \l ResizeMode.
+*/
+
+void TQIconView::setResizeMode( ResizeMode rm )
+{
+ if ( d->resizeMode == rm )
+ return;
+
+ d->resizeMode = rm;
+}
+
+TQIconView::ResizeMode TQIconView::resizeMode() const
+{
+ return d->resizeMode;
+}
+
+/*!
+ \property TQIconView::maxItemWidth
+ \brief the maximum width that an item may have.
+
+ The default is 100 pixels.
+
+ Note that if the gridX() value is set TQIconView will ignore
+ this property.
+*/
+
+void TQIconView::setMaxItemWidth( int w )
+{
+ d->maxItemWidth = w;
+}
+
+/*!
+ \property TQIconView::maxItemTextLength
+ \brief the maximum length (in characters) that an item's text may have.
+
+ The default is 255 characters.
+*/
+
+void TQIconView::setMaxItemTextLength( int w )
+{
+ d->maxItemTextLength = w;
+}
+
+int TQIconView::maxItemWidth() const
+{
+ if ( d->rastX != -1 )
+ return d->rastX - 2;
+ else
+ return d->maxItemWidth;
+}
+
+int TQIconView::maxItemTextLength() const
+{
+ return d->maxItemTextLength;
+}
+
+/*!
+ \property TQIconView::itemsMovable
+ \brief whether the user is allowed to move items around in the icon view
+
+ The default is TRUE.
+*/
+
+void TQIconView::setItemsMovable( bool b )
+{
+ d->rearrangeEnabled = b;
+}
+
+bool TQIconView::itemsMovable() const
+{
+ return d->rearrangeEnabled;
+}
+
+/*!
+ \property TQIconView::autoArrange
+ \brief whether the icon view rearranges its items when a new item is inserted.
+
+ The default is TRUE.
+
+ Note that if the icon view is not visible at the time of
+ insertion, TQIconView defers all position-related work until it is
+ shown and then calls arrangeItemsInGrid().
+*/
+
+void TQIconView::setAutoArrange( bool b )
+{
+ d->reorderItemsWhenInsert = b;
+}
+
+bool TQIconView::autoArrange() const
+{
+ return d->reorderItemsWhenInsert;
+}
+
+/*!
+ If \a sort is TRUE, this function sets the icon view to sort items
+ when a new item is inserted. If \a sort is FALSE, the icon view
+ will not be sorted.
+
+ Note that autoArrange() must be TRUE for sorting to take place.
+
+ If \a ascending is TRUE (the default), items are sorted in
+ ascending order. If \a ascending is FALSE, items are sorted in
+ descending order.
+
+ TQIconViewItem::compare() is used to compare pairs of items. The
+ sorting is based on the items' keys; these default to the items'
+ text unless specifically set to something else.
+
+ \sa TQIconView::setAutoArrange(), TQIconView::autoArrange(),
+ sortDirection(), sort(), TQIconViewItem::setKey()
+*/
+
+void TQIconView::setSorting( bool sort, bool ascending )
+{
+ d->resortItemsWhenInsert = sort;
+ d->sortDirection = ascending;
+}
+
+/*!
+ \property TQIconView::sorting
+ \brief whether the icon view sorts on insertion
+
+ The default is FALSE, i.e. no sorting on insertion.
+
+ To set the sorting, use setSorting().
+*/
+
+bool TQIconView::sorting() const
+{
+ return d->resortItemsWhenInsert;
+}
+
+/*!
+ \property TQIconView::sortDirection
+ \brief whether the sort direction for inserting new items is ascending;
+
+ The default is TRUE (i.e. ascending). This sort direction is only
+ meaningful if both sorting() and autoArrange() are TRUE.
+
+ To set the sort direction, use setSorting()
+*/
+
+bool TQIconView::sortDirection() const
+{
+ return d->sortDirection;
+}
+
+/*!
+ \property TQIconView::wordWrapIconText
+ \brief whether the item text will be word-wrapped if it is too long
+
+ The default is TRUE.
+
+ If this property is FALSE, icon text that is too long is
+ truncated, and an ellipsis (...) appended to indicate that
+ truncation has occurred. The full text can still be seen by the
+ user if they hover the mouse because the full text is shown in a
+ tooltip; see setShowToolTips().
+*/
+
+void TQIconView::setWordWrapIconText( bool b )
+{
+ if ( d->wordWrapIconText == (uint)b )
+ return;
+
+ d->wordWrapIconText = b;
+ for ( TQIconViewItem *item = d->firstItem; item; item = item->next ) {
+ item->wordWrapDirty = TRUE;
+ item->calcRect();
+ }
+ arrangeItemsInGrid( TRUE );
+}
+
+bool TQIconView::wordWrapIconText() const
+{
+ return d->wordWrapIconText;
+}
+
+/*!
+ \property TQIconView::showToolTips
+ \brief whether the icon view will display a tool tip with the complete text for any truncated item text
+
+ The default is TRUE. Note that this has no effect if
+ setWordWrapIconText() is TRUE, as it is by default.
+*/
+
+void TQIconView::setShowToolTips( bool b )
+{
+ d->showTips = b;
+}
+
+bool TQIconView::showToolTips() const
+{
+ return d->showTips;
+}
+
+/*!
+ \reimp
+*/
+void TQIconView::contentsMousePressEvent( TQMouseEvent *e )
+{
+ contentsMousePressEventEx( e );
+}
+
+void TQIconView::contentsMousePressEventEx( TQMouseEvent *e )
+{
+ if ( d->rubber ) {
+ TQPainter p;
+ p.begin( viewport() );
+ p.setRasterOp( TQt::NotROP );
+ p.setPen( TQPen( Qt::color0, 1 ) );
+ p.setBrush( Qt::NoBrush );
+
+ drawRubber( &p );
+ d->dragging = FALSE;
+ p.end();
+ delete d->rubber;
+ d->rubber = 0;
+
+ if ( d->scrollTimer ) {
+ disconnect( d->scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( doAutoScroll() ) );
+ d->scrollTimer->stop();
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ }
+ }
+
+ d->dragStartPos = e->pos();
+ TQIconViewItem *item = tqfindItem( e->pos() );
+ d->pressedItem = item;
+
+ if ( item )
+ d->selectAnchor = item;
+
+#ifndef TQT_NO_TEXTEDIT
+ if ( d->renamingItem )
+ d->renamingItem->renameItem();
+#endif
+
+ if ( !d->currentItem && !item && d->firstItem ) {
+ d->currentItem = d->firstItem;
+ repaintItem( d->firstItem );
+ }
+
+ if (item && item->dragEnabled())
+ d->startDragItem = item;
+ else
+ d->startDragItem = 0;
+
+ if ( e->button() == Qt::LeftButton && !( e->state() & ShiftButton ) &&
+ !( e->state() & ControlButton ) && item && item->isSelected() &&
+ item->textRect( FALSE ).tqcontains( e->pos() ) ) {
+
+ if ( !item->renameEnabled() ) {
+ d->mousePressed = TRUE;
+#ifndef TQT_NO_TEXTEDIT
+ } else {
+ ensureItemVisible( item );
+ setCurrentItem( item );
+ item->rename();
+ goto emit_Q_SIGNALS;
+#endif
+ }
+ }
+
+ d->pressedSelected = item && item->isSelected();
+
+ if ( item && item->isSelectable() ) {
+ if ( d->selectionMode == Single )
+ item->setSelected( TRUE, e->state() & ControlButton );
+ else if ( d->selectionMode == Multi )
+ item->setSelected( !item->isSelected(), e->state() & ControlButton );
+ else if ( d->selectionMode == Extended ) {
+ if ( e->state() & ShiftButton ) {
+ d->pressedSelected = FALSE;
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ viewport()->setUpdatesEnabled( FALSE );
+ TQRect r;
+ bool select = TRUE;
+ if ( d->currentItem )
+ r = TQRect( TQMIN( d->currentItem->x(), item->x() ),
+ TQMIN( d->currentItem->y(), item->y() ),
+ 0, 0 );
+ else
+ r = TQRect( 0, 0, 0, 0 );
+ if ( d->currentItem ) {
+ if ( d->currentItem->x() < item->x() )
+ r.setWidth( item->x() - d->currentItem->x() + item->width() );
+ else
+ r.setWidth( d->currentItem->x() - item->x() + d->currentItem->width() );
+ if ( d->currentItem->y() < item->y() )
+ r.setHeight( item->y() - d->currentItem->y() + item->height() );
+ else
+ r.setHeight( d->currentItem->y() - item->y() + d->currentItem->height() );
+ r = r.normalize();
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ bool alreadyIntersected = FALSE;
+ TQRect redraw;
+ for ( ; c; c = c->n ) {
+ if ( c->rect.intersects( r ) ) {
+ alreadyIntersected = TRUE;
+ TQIconViewItem *i = c->items.first();
+ for ( ; i; i = c->items.next() ) {
+ if ( r.intersects( i->rect() ) ) {
+ redraw = redraw.unite( i->rect() );
+ i->setSelected( select, TRUE );
+ }
+ }
+ } else {
+ if ( alreadyIntersected )
+ break;
+ }
+ }
+ redraw = redraw.unite( item->rect() );
+ viewport()->setUpdatesEnabled( TRUE );
+ repaintContents( redraw, FALSE );
+ }
+ blockSignals( block );
+ viewport()->setUpdatesEnabled( TRUE );
+ item->setSelected( select, TRUE );
+ emit selectionChanged();
+ } else if ( e->state() & ControlButton ) {
+ d->pressedSelected = FALSE;
+ item->setSelected( !item->isSelected(), e->state() & ControlButton );
+ } else {
+ item->setSelected( TRUE, e->state() & ControlButton );
+ }
+ }
+ } else if ( ( d->selectionMode != Single || e->button() == Qt::RightButton )
+ && !( e->state() & ControlButton ) )
+ selectAll( FALSE );
+
+ setCurrentItem( item );
+
+ if ( e->button() == Qt::LeftButton ) {
+ if ( !item && ( d->selectionMode == Multi ||
+ d->selectionMode == Extended ) ) {
+ d->tmpCurrentItem = d->currentItem;
+ d->currentItem = 0;
+ repaintItem( d->tmpCurrentItem );
+ if ( d->rubber )
+ delete d->rubber;
+ d->rubber = 0;
+ d->rubber = new TQRect( e->x(), e->y(), 0, 0 );
+ d->selectedItems.clear();
+ if ( ( e->state() & ControlButton ) == ControlButton ) {
+ for ( TQIconViewItem *i = firstItem(); i; i = i->nextItem() )
+ if ( i->isSelected() )
+ d->selectedItems.insert( i, i );
+ }
+ }
+
+ d->mousePressed = TRUE;
+ }
+
+ emit_Q_SIGNALS:
+ if ( !d->rubber ) {
+ emit mouseButtonPressed( e->button(), item, e->globalPos() );
+ emit pressed( item );
+ emit pressed( item, e->globalPos() );
+
+ if ( e->button() == Qt::RightButton )
+ emit rightButtonPressed( item, e->globalPos() );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsContextMenuEvent( TQContextMenuEvent *e )
+{
+ if ( !tqreceivers( TQT_SIGNAL(contextMenuRequested(TQIconViewItem*,const TQPoint&)) ) ) {
+ e->ignore();
+ return;
+ }
+ if ( e->reason() == TQContextMenuEvent::Keyboard ) {
+ TQIconViewItem *item = currentItem();
+ TQRect r = item ? item->rect() : TQRect( 0, 0, visibleWidth(), visibleHeight() );
+ emit contextMenuRequested( item, viewport()->mapToGlobal( contentsToViewport( r.center() ) ) );
+ } else {
+ d->mousePressed = FALSE;
+ TQIconViewItem *item = tqfindItem( e->pos() );
+ emit contextMenuRequested( item, e->globalPos() );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsMouseReleaseEvent( TQMouseEvent *e )
+{
+ TQIconViewItem *item = tqfindItem( e->pos() );
+ d->selectedItems.clear();
+
+ bool emitClicked = TRUE;
+ d->mousePressed = FALSE;
+ d->startDragItem = 0;
+
+ if ( d->rubber ) {
+ TQPainter p;
+ p.begin( viewport() );
+ p.setRasterOp( TQt::NotROP );
+ p.setPen( TQPen( Qt::color0, 1 ) );
+ p.setBrush( Qt::NoBrush );
+
+ drawRubber( &p );
+ d->dragging = FALSE;
+ p.end();
+
+ if ( ( d->rubber->topLeft() - d->rubber->bottomRight() ).manhattanLength() >
+ TQApplication::startDragDistance() )
+ emitClicked = FALSE;
+ delete d->rubber;
+ d->rubber = 0;
+ d->currentItem = d->tmpCurrentItem;
+ d->tmpCurrentItem = 0;
+ if ( d->currentItem )
+ repaintItem( d->currentItem );
+ }
+
+ if ( d->scrollTimer ) {
+ disconnect( d->scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( doAutoScroll() ) );
+ d->scrollTimer->stop();
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ }
+
+ if ( d->selectionMode == Extended &&
+ d->currentItem == d->pressedItem &&
+ d->pressedSelected && d->currentItem ) {
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ clearSelection();
+ blockSignals( block );
+ if ( d->currentItem->isSelectable() ) {
+ d->currentItem->selected = TRUE;
+ repaintItem( d->currentItem );
+ }
+ emit selectionChanged();
+ }
+ d->pressedItem = 0;
+
+ if ( emitClicked ) {
+ emit mouseButtonClicked( e->button(), item, e->globalPos() );
+ emit clicked( item );
+ emit clicked( item, e->globalPos() );
+ if ( e->button() == Qt::RightButton )
+ emit rightButtonClicked( item, e->globalPos() );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsMouseMoveEvent( TQMouseEvent *e )
+{
+ TQIconViewItem *item = tqfindItem( e->pos() );
+ if ( d->highlightedItem != item ) {
+ if ( item )
+ emit onItem( item );
+ else
+ emit onViewport();
+ d->highlightedItem = item;
+ }
+
+ if ( d->mousePressed && e->state() == Qt::NoButton )
+ d->mousePressed = FALSE;
+
+ if ( d->startDragItem )
+ item = d->startDragItem;
+
+ if ( d->mousePressed && item && item == d->currentItem &&
+ ( item->isSelected() || d->selectionMode == NoSelection ) && item->dragEnabled() ) {
+ if ( !d->startDragItem ) {
+ d->currentItem->setSelected( TRUE, TRUE );
+ d->startDragItem = item;
+ }
+ if ( ( d->dragStartPos - e->pos() ).manhattanLength() > TQApplication::startDragDistance() ) {
+ d->mousePressed = FALSE;
+ d->cleared = FALSE;
+#ifndef TQT_NO_DRAGANDDROP
+ startDrag();
+#endif
+ if ( d->tmpCurrentItem )
+ repaintItem( d->tmpCurrentItem );
+ }
+ } else if ( d->mousePressed && !d->currentItem && d->rubber ) {
+ doAutoScroll();
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsMouseDoubleClickEvent( TQMouseEvent *e )
+{
+ TQIconViewItem *item = tqfindItem( e->pos() );
+ if ( item ) {
+ selectAll( FALSE );
+ item->setSelected( TRUE, TRUE );
+ emit doubleClicked( item );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQIconView::contentsDragEnterEvent( TQDragEnterEvent *e )
+{
+ d->dragging = TRUE;
+ d->drawDragShapes = TRUE;
+ d->tmpCurrentItem = 0;
+ initDragEnter( e );
+ d->oldDragPos = e->pos();
+ d->oldDragAcceptAction = FALSE;
+ drawDragShapes( e->pos() );
+ d->dropped = FALSE;
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsDragMoveEvent( TQDragMoveEvent *e )
+{
+ if ( e->pos() == d->oldDragPos ) {
+ if (d->oldDragAcceptAction)
+ e->acceptAction();
+ else
+ e->ignore();
+ return;
+ }
+
+ drawDragShapes( d->oldDragPos );
+ d->dragging = FALSE;
+
+ TQIconViewItem *old = d->tmpCurrentItem;
+ d->tmpCurrentItem = 0;
+
+ TQIconViewItem *item = tqfindItem( e->pos() );
+
+ if ( item ) {
+ if ( old &&
+ old->rect().tqcontains(d->oldDragPos) &&
+ !old->rect().tqcontains(e->pos()) ) {
+ old->dragLeft();
+ repaintItem( old );
+ }
+ if ( !item->rect().tqcontains(d->oldDragPos) )
+ item->dragEntered();
+ if (item->acceptDrop(e) || (item->isSelected() && e->source() == viewport())) {
+ d->oldDragAcceptAction = TRUE;
+ e->acceptAction();
+ } else {
+ d->oldDragAcceptAction = FALSE;
+ e->ignore();
+ }
+
+ d->tmpCurrentItem = item;
+ TQPainter p;
+ p.begin( viewport() );
+ p.translate( -contentsX(), -contentsY() );
+ item->paintFocus( &p, tqcolorGroup() );
+ p.end();
+ } else {
+ e->acceptAction();
+ d->oldDragAcceptAction = TRUE;
+ if ( old ) {
+ old->dragLeft();
+ repaintItem( old );
+ }
+ }
+
+ d->oldDragPos = e->pos();
+ drawDragShapes( e->pos() );
+ d->dragging = TRUE;
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsDragLeaveEvent( TQDragLeaveEvent * )
+{
+ if ( !d->dropped )
+ drawDragShapes( d->oldDragPos );
+ d->dragging = FALSE;
+
+ if ( d->tmpCurrentItem ) {
+ repaintItem( d->tmpCurrentItem );
+ d->tmpCurrentItem->dragLeft();
+ }
+
+ d->tmpCurrentItem = 0;
+ d->isIconDrag = FALSE;
+ d->iconDragData.clear();
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::contentsDropEvent( TQDropEvent *e )
+{
+ d->dropped = TRUE;
+ d->dragging = FALSE;
+ drawDragShapes( d->oldDragPos );
+
+ if ( d->tmpCurrentItem )
+ repaintItem( d->tmpCurrentItem );
+
+ TQIconViewItem *i = tqfindItem( e->pos() );
+
+ if ((!i || i->isSelected()) && e->source() == viewport() && d->currentItem && !d->cleared) {
+ if ( !d->rearrangeEnabled )
+ return;
+ TQRect r = d->currentItem->rect();
+
+ d->currentItem->move( e->pos() - d->dragStart );
+
+ int w = d->currentItem->x() + d->currentItem->width() + 1;
+ int h = d->currentItem->y() + d->currentItem->height() + 1;
+
+ repaintItem( d->currentItem );
+ repaintContents( r.x(), r.y(), r.width(), r.height(), FALSE );
+
+ int dx = d->currentItem->x() - r.x();
+ int dy = d->currentItem->y() - r.y();
+
+ TQIconViewItem *item = d->firstItem;
+ TQRect rr;
+ for ( ; item; item = item->next ) {
+ if ( item->isSelected() && item != d->currentItem ) {
+ rr = rr.unite( item->rect() );
+ item->moveBy( dx, dy );
+ rr = rr.unite( item->rect() );
+ }
+ w = TQMAX( w, item->x() + item->width() + 1 );
+ h = TQMAX( h, item->y() + item->height() + 1 );
+ }
+ repaintContents( rr, FALSE );
+ bool fullRepaint = FALSE;
+ if ( w > contentsWidth() ||
+ h > contentsHeight() )
+ fullRepaint = TRUE;
+
+ int oldw = contentsWidth();
+ int oldh = contentsHeight();
+
+ resizeContents( w, h );
+
+
+ if ( fullRepaint ) {
+ repaintContents( oldw, 0, contentsWidth() - oldw, contentsHeight(), FALSE );
+ repaintContents( 0, oldh, contentsWidth(), contentsHeight() - oldh, FALSE );
+ }
+ e->acceptAction();
+ } else if ( !i && ( e->source() != viewport() || d->cleared ) ) {
+ TQValueList<TQIconDragItem> lst;
+ if ( TQIconDrag::canDecode( e ) ) {
+ TQValueList<TQIconDragDataItem> l;
+ TQIconDragPrivate::decode( e, l );
+ TQValueList<TQIconDragDataItem>::Iterator it = l.begin();
+ for ( ; it != l.end(); ++it )
+ lst << ( *it ).data;
+ }
+ emit dropped( e, lst );
+ } else if ( i ) {
+ TQValueList<TQIconDragItem> lst;
+ if ( TQIconDrag::canDecode( e ) ) {
+ TQValueList<TQIconDragDataItem> l;
+ TQIconDragPrivate::decode( e, l );
+ TQValueList<TQIconDragDataItem>::Iterator it = l.begin();
+ for ( ; it != l.end(); ++it )
+ lst << ( *it ).data;
+ }
+ i->dropped( e, lst );
+ }
+ d->isIconDrag = FALSE;
+}
+#endif
+
+/*!
+ \reimp
+*/
+
+void TQIconView::resizeEvent( TQResizeEvent* e )
+{
+ TQScrollView::resizeEvent( e );
+ if ( d->resizeMode == Adjust ) {
+ optimize_tqlayout = TRUE;
+ adjustItems();
+ optimize_tqlayout = FALSE;
+#if 0 // no need for timer delay anymore
+ d->oldSize = e->oldSize();
+ if ( d->adjustTimer->isActive() )
+ d->adjustTimer->stop();
+ d->adjustTimer->start( 0, TRUE );
+#endif
+ }
+}
+
+/*!
+ Adjusts the positions of the items to the tqgeometry of the icon
+ view.
+*/
+
+void TQIconView::adjustItems()
+{
+ d->adjustTimer->stop();
+ if ( d->resizeMode == Adjust )
+ arrangeItemsInGrid( TRUE );
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::keyPressEvent( TQKeyEvent *e )
+{
+ if ( !d->firstItem )
+ return;
+
+ if ( !d->currentItem ) {
+ setCurrentItem( d->firstItem );
+ if ( d->selectionMode == Single )
+ d->currentItem->setSelected( TRUE, TRUE );
+ return;
+ }
+
+ bool selectCurrent = TRUE;
+
+ switch ( e->key() ) {
+ case Key_Escape:
+ e->ignore();
+ break;
+#ifndef TQT_NO_TEXTEDIT
+ case Qt::Key_F2: {
+ if ( d->currentItem->renameEnabled() ) {
+ d->currentItem->renameItem();
+ d->currentItem->rename();
+ return;
+ }
+ } break;
+#endif
+ case Qt::Key_Home: {
+ d->currInputString = TQString::null;
+ if ( !d->firstItem )
+ break;
+
+ selectCurrent = FALSE;
+
+ TQIconViewItem *item = 0;
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ while ( !item && c ) {
+ TQPtrList<TQIconViewItem> &list = c->items;
+ TQIconViewItem *i = list.first();
+ while ( i ) {
+ if ( !item ) {
+ item = i;
+ } else {
+ if ( d->arrangement == LeftToRight ) {
+ // we use pixmap so the items textlength are ignored
+ // tqfind topmost, leftmost item
+ if ( i->pixmapRect( FALSE ).y() < item->pixmapRect( FALSE ).y() ||
+ ( i->pixmapRect( FALSE ).y() == item->pixmapRect( FALSE ).y() &&
+ i->pixmapRect( FALSE ).x() < item->pixmapRect( FALSE ).x() ) )
+ item = i;
+ } else {
+ // tqfind leftmost, topmost item
+ if ( i->pixmapRect( FALSE ).x() < item->pixmapRect( FALSE ).x() ||
+ ( i->pixmapRect( FALSE ).x() == item->pixmapRect( FALSE ).x() &&
+ i->pixmapRect( FALSE ).y() < item->pixmapRect( FALSE ).y() ) )
+ item = i;
+ }
+ }
+ i = list.next();
+ }
+ c = c->n;
+ }
+
+ if ( item ) {
+ TQIconViewItem *old = d->currentItem;
+ setCurrentItem( item );
+ ensureItemVisible( item );
+ handleItemChange( old, e->state() & ShiftButton,
+ e->state() & ControlButton, TRUE );
+ }
+ } break;
+ case Qt::Key_End: {
+ d->currInputString = TQString::null;
+ if ( !d->lastItem )
+ break;
+
+ selectCurrent = FALSE;
+
+ TQIconViewItem *item = 0;
+ TQIconViewPrivate::ItemContainer *c = d->lastContainer;
+ while ( !item && c ) {
+ TQPtrList<TQIconViewItem> &list = c->items;
+ TQIconViewItem *i = list.first();
+ while ( i ) {
+ if ( !item ) {
+ item = i;
+ } else {
+ if ( d->arrangement == LeftToRight ) {
+ // tqfind bottommost, rightmost item
+ if ( i->pixmapRect( FALSE ).bottom() > item->pixmapRect( FALSE ).bottom() ||
+ ( i->pixmapRect( FALSE ).bottom() == item->pixmapRect( FALSE ).bottom() &&
+ i->pixmapRect( FALSE ).right() > item->pixmapRect( FALSE ).right() ) )
+ item = i;
+ } else {
+ // tqfind rightmost, bottommost item
+ if ( i->pixmapRect( FALSE ).right() > item->pixmapRect( FALSE ).right() ||
+ ( i->pixmapRect( FALSE ).right() == item->pixmapRect( FALSE ).right() &&
+ i->pixmapRect( FALSE ).bottom() > item->pixmapRect( FALSE ).bottom() ) )
+ item = i;
+ }
+ }
+ i = list.next();
+ }
+ c = c->p;
+ }
+
+ if ( item ) {
+ TQIconViewItem *old = d->currentItem;
+ setCurrentItem( item );
+ ensureItemVisible( item );
+ handleItemChange( old, e->state() & ShiftButton,
+ e->state() & ControlButton, TRUE );
+ }
+ } break;
+ case Qt::Key_Right: {
+ d->currInputString = TQString::null;
+ TQIconViewItem *item;
+ selectCurrent = FALSE;
+ Direction dir = DirRight;
+
+ TQRect r( 0, d->currentItem->y(), contentsWidth(), d->currentItem->height() );
+ item = tqfindItem( dir, d->currentItem->rect().center(), r );
+
+ // search the row below from the right
+ while ( !item && r.y() < contentsHeight() ) {
+ r.moveBy(0, d->currentItem->height() );
+ item = tqfindItem( dir, TQPoint( 0, r.center().y() ), r );
+ }
+
+ if ( item ) {
+ TQIconViewItem *old = d->currentItem;
+ setCurrentItem( item );
+ ensureItemVisible( item );
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } break;
+ case Qt::Key_Left: {
+ d->currInputString = TQString::null;
+ TQIconViewItem *item;
+ selectCurrent = FALSE;
+ Direction dir = DirLeft;
+
+ TQRect r( 0, d->currentItem->y(), contentsWidth(), d->currentItem->height() );
+ item = tqfindItem( dir, d->currentItem->rect().center(), r );
+
+ // search the row above from the left
+ while ( !item && r.y() >= 0 ) {
+ r.moveBy(0, - d->currentItem->height() );
+ item = tqfindItem( dir, TQPoint( contentsWidth(), r.center().y() ), r );
+ }
+
+ if ( item ) {
+ TQIconViewItem *old = d->currentItem;
+ setCurrentItem( item );
+ ensureItemVisible( item );
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } break;
+ case Qt::Key_Space: {
+ d->currInputString = TQString::null;
+ if ( d->selectionMode == Single)
+ break;
+
+ d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE );
+ } break;
+ case Qt::Key_Enter: case Qt::Key_Return:
+ d->currInputString = TQString::null;
+ emit returnPressed( d->currentItem );
+ break;
+ case Qt::Key_Down: {
+ d->currInputString = TQString::null;
+ TQIconViewItem *item;
+ selectCurrent = FALSE;
+ Direction dir = DirDown;
+
+ TQRect r( d->currentItem->x(), 0, d->currentItem->width(), contentsHeight() );
+ item = tqfindItem( dir, d->currentItem->rect().center(), r );
+
+ // tqfinding the closest item below and to the right
+ while ( !item && r.x() < contentsWidth() ) {
+ r.moveBy( r.width() , 0 );
+ item = tqfindItem( dir, TQPoint( r.center().x(), 0 ), r );
+ }
+
+
+ TQIconViewItem *i = d->currentItem;
+ setCurrentItem( item );
+ item = i;
+ handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton );
+ } break;
+ case Qt::Key_Up: {
+ d->currInputString = TQString::null;
+ TQIconViewItem *item;
+ selectCurrent = FALSE;
+ Direction dir = DirUp;
+
+ TQRect r( d->currentItem->x(), 0, d->currentItem->width(), contentsHeight() );
+ item = tqfindItem( dir, d->currentItem->rect().center(), r );
+
+ // tqfinding the closest item above and to the left
+ while ( !item && r.x() >= 0 ) {
+ r.moveBy(- r.width(), 0 );
+ item = tqfindItem( dir, TQPoint(r.center().x(), contentsHeight() ), r );
+ }
+
+ TQIconViewItem *i = d->currentItem;
+ setCurrentItem( item );
+ item = i;
+ handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton );
+ } break;
+ case TQt::Key_Next: {
+ d->currInputString = TQString::null;
+ selectCurrent = FALSE;
+ TQRect r;
+ if ( d->arrangement == LeftToRight )
+ r = TQRect( 0, d->currentItem->y() + visibleHeight(), contentsWidth(), visibleHeight() );
+ else
+ r = TQRect( d->currentItem->x() + visibleWidth(), 0, visibleWidth(), contentsHeight() );
+ TQIconViewItem *item = d->currentItem;
+ TQIconViewItem *ni = tqfindFirstVisibleItem( r );
+ if ( !ni ) {
+ if ( d->arrangement == LeftToRight )
+ r = TQRect( 0, d->currentItem->y() + d->currentItem->height(), contentsWidth(), contentsHeight() );
+ else
+ r = TQRect( d->currentItem->x() + d->currentItem->width(), 0, contentsWidth(), contentsHeight() );
+ ni = tqfindLastVisibleItem( r );
+ }
+ if ( ni ) {
+ setCurrentItem( ni );
+ handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } break;
+ case TQt::Key_Prior: {
+ d->currInputString = TQString::null;
+ selectCurrent = FALSE;
+ TQRect r;
+ if ( d->arrangement == LeftToRight )
+ r = TQRect( 0, d->currentItem->y() - visibleHeight(), contentsWidth(), visibleHeight() );
+ else
+ r = TQRect( d->currentItem->x() - visibleWidth(), 0, visibleWidth(), contentsHeight() );
+ TQIconViewItem *item = d->currentItem;
+ TQIconViewItem *ni = tqfindFirstVisibleItem( r );
+ if ( !ni ) {
+ if ( d->arrangement == LeftToRight )
+ r = TQRect( 0, 0, contentsWidth(), d->currentItem->y() );
+ else
+ r = TQRect( 0, 0, d->currentItem->x(), contentsHeight() );
+ ni = tqfindFirstVisibleItem( r );
+ }
+ if ( ni ) {
+ setCurrentItem( ni );
+ handleItemChange( item, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } break;
+ default:
+ if ( !e->text().isEmpty() && e->text()[ 0 ].isPrint() ) {
+ selectCurrent = FALSE;
+ TQIconViewItem *i = d->currentItem;
+ if ( !i )
+ i = d->firstItem;
+ if ( !d->inputTimer->isActive() ) {
+ d->currInputString = e->text();
+ i = i->next;
+ if ( !i )
+ i = d->firstItem;
+ i = tqfindItemByName( i );
+ } else {
+ d->inputTimer->stop();
+ d->currInputString += e->text();
+ i = tqfindItemByName( i );
+ if ( !i ) {
+ d->currInputString = e->text();
+ if (d->currentItem && d->currentItem->next)
+ i = d->currentItem->next;
+ else
+ i = d->firstItem;
+ i = tqfindItemByName(i);
+ }
+ }
+ if ( i ) {
+ setCurrentItem( i );
+ if ( d->selectionMode == Extended ) {
+ bool changed = FALSE;
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ selectAll( FALSE );
+ blockSignals( block );
+ if ( !i->selected && i->isSelectable() ) {
+ changed = TRUE;
+ i->selected = TRUE;
+ repaintItem( i );
+ }
+ if ( changed )
+ emit selectionChanged();
+ }
+ }
+ d->inputTimer->start( 400, TRUE );
+ } else {
+ selectCurrent = FALSE;
+ d->currInputString = TQString::null;
+ if ( e->state() & ControlButton ) {
+ switch ( e->key() ) {
+ case Qt::Key_A:
+ selectAll( TRUE );
+ break;
+ }
+ }
+ e->ignore();
+ return;
+ }
+ }
+
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = d->currentItem;
+
+ if ( d->currentItem && !d->currentItem->isSelected() &&
+ d->selectionMode == Single && selectCurrent ) {
+ d->currentItem->setSelected( TRUE );
+ }
+
+ ensureItemVisible( d->currentItem );
+}
+
+/*
+ Finds the closest item in the Direction \a dir relative from the point \a relativeTo
+ which intersects with the searchRect.
+
+ The function choses the closest item with its center in the searchRect.
+*/
+TQIconViewItem* TQIconView::tqfindItem( Direction dir,
+ const TQPoint &relativeTo,
+ const TQRect &searchRect ) const
+{
+ TQIconViewItem *item;
+ TQIconViewItem *centerMatch = 0;
+ int centerMatchML = 0;
+
+ // gets list of containers with potential items
+ TQPtrList<TQIconViewPrivate::ItemContainer>* cList =
+ d->tqfindContainers( dir, relativeTo, searchRect);
+
+ cList->first();
+ while ( cList->current() && !centerMatch ) {
+ TQPtrList<TQIconViewItem> &list = (cList->current())->items;
+ for ( item = list.first(); item; item = list.next() ) {
+ if ( neighbourItem( dir, relativeTo, item ) &&
+ searchRect.tqcontains( item->rect().center() ) &&
+ item != currentItem() ) {
+ int ml = (relativeTo - item->rect().center()).manhattanLength();
+ if ( centerMatch ) {
+ if ( ml < centerMatchML ) {
+ centerMatch = item;
+ centerMatchML = ml;
+ }
+ } else {
+ centerMatch = item;
+ centerMatchML = ml;
+ }
+ }
+ }
+ cList->next();
+ }
+ delete cList;
+ return centerMatch;
+}
+
+
+/*
+ Returns TRUE if the items orientation compared to
+ the point \a relativeTo is correct.
+*/
+bool TQIconView::neighbourItem( Direction dir,
+ const TQPoint &relativeTo,
+ const TQIconViewItem *item ) const
+{
+ switch ( dir ) {
+ case DirUp:
+ if ( item->rect().center().y() < relativeTo.y() )
+ return TRUE;
+ break;
+ case DirDown:
+ if ( item->rect().center().y() > relativeTo.y() )
+ return TRUE;
+ break;
+ case DirLeft:
+ if ( item->rect().center().x() < relativeTo.x() )
+ return TRUE;
+ break;
+ case DirRight:
+ if ( item->rect().center().x() > relativeTo.x() )
+ return TRUE;
+ break;
+ default:
+ // nothing
+ break;
+ }
+ return FALSE;
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::focusInEvent( TQFocusEvent* tqfe)
+{
+ d->mousePressed = FALSE;
+ d->inMenuMode = FALSE;
+ if ( d->currentItem ) {
+ repaintItem( d->currentItem );
+#ifdef USE_QT4
+ } else if ( d->firstItem && tqfe->reason() != TQFocusEvent::Mouse ) {
+#else // USE_QT4
+ } else if ( d->firstItem && TQFocusEvent::reason() != TQFocusEvent::Mouse ) {
+#endif // USE_QT4
+ d->currentItem = d->firstItem;
+ emit currentChanged( d->currentItem );
+ repaintItem( d->currentItem );
+ }
+
+ if ( tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this ) )
+ repaintSelectedItems();
+
+ if ( d->currentItem )
+ setMicroFocusHint( d->currentItem->x(), d->currentItem->y(), d->currentItem->width(), d->currentItem->height(), FALSE );
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::focusOutEvent( TQFocusEvent* tqfe )
+{
+ if (tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this )) {
+ d->inMenuMode =
+#ifdef USE_QT4
+ tqfe->reason() == TQFocusEvent::Popup ||
+#else // USE_QT4
+ TQFocusEvent::reason() == TQFocusEvent::Popup ||
+#endif // USE_QT4
+ (tqApp->tqfocusWidget() && tqApp->tqfocusWidget()->inherits("TQMenuBar"));
+ if ( !d->inMenuMode )
+ repaintSelectedItems();
+ }
+ if ( d->currentItem )
+ repaintItem( d->currentItem );
+}
+
+/*!
+ Draws the rubber band using the painter \a p.
+*/
+
+void TQIconView::drawRubber( TQPainter *p )
+{
+ if ( !p || !d->rubber )
+ return;
+
+ TQPoint pnt( d->rubber->x(), d->rubber->y() );
+ pnt = contentsToViewport( pnt );
+
+ tqstyle().tqdrawPrimitive(TQStyle::PE_RubberBand, p,
+ TQRect(pnt.x(), pnt.y(), d->rubber->width(), d->rubber->height()),
+ tqcolorGroup(), TQStyle::Style_Default, TQStyleOption(tqcolorGroup().base()));
+}
+
+/*!
+ Returns the TQDragObject that should be used for drag-and-drop.
+ This function is called by the icon view when starting a drag to
+ get the dragobject that should be used for the drag. Subclasses
+ may reimplement this.
+
+ \sa TQIconDrag
+*/
+
+#ifndef TQT_NO_DRAGANDDROP
+TQDragObject *TQIconView::dragObject()
+{
+ if ( !d->currentItem )
+ return 0;
+
+ TQPoint orig = d->dragStartPos;
+
+ TQIconDrag *drag = new TQIconDrag( viewport() );
+ drag->setPixmap( ( d->currentItem->pixmap() ?
+ *d->currentItem->pixmap() : TQPixmap() ), // ### TQPicture
+ TQPoint( d->currentItem->pixmapRect().width() / 2,
+ d->currentItem->pixmapRect().height() / 2 ) );
+
+ if ( d->selectionMode == NoSelection ) {
+ TQIconViewItem *item = d->currentItem;
+ drag->append( TQIconDragItem(),
+ TQRect( item->pixmapRect( FALSE ).x() - orig.x(),
+ item->pixmapRect( FALSE ).y() - orig.y(),
+ item->pixmapRect().width(), item->pixmapRect().height() ),
+ TQRect( item->textRect( FALSE ).x() - orig.x(),
+ item->textRect( FALSE ).y() - orig.y(),
+ item->textRect().width(), item->textRect().height() ) );
+ } else {
+ for ( TQIconViewItem *item = d->firstItem; item; item = item->next ) {
+ if ( item->isSelected() ) {
+ drag->append( TQIconDragItem(),
+ TQRect( item->pixmapRect( FALSE ).x() - orig.x(),
+ item->pixmapRect( FALSE ).y() - orig.y(),
+ item->pixmapRect().width(), item->pixmapRect().height() ),
+ TQRect( item->textRect( FALSE ).x() - orig.x(),
+ item->textRect( FALSE ).y() - orig.y(),
+ item->textRect().width(), item->textRect().height() ) );
+ }
+ }
+ }
+
+ return drag;
+}
+
+/*!
+ Starts a drag.
+*/
+
+void TQIconView::startDrag()
+{
+ if ( !d->startDragItem )
+ return;
+
+ TQPoint orig = d->dragStartPos;
+ d->dragStart = TQPoint( orig.x() - d->startDragItem->x(),
+ orig.y() - d->startDragItem->y() );
+ d->startDragItem = 0;
+ d->mousePressed = FALSE;
+ d->pressedItem = 0;
+ d->pressedSelected = 0;
+
+ TQDragObject *drag = dragObject();
+ if ( !drag )
+ return;
+
+ if ( drag->drag() )
+ if ( drag->target() != viewport() )
+ emit moved();
+}
+
+#endif
+
+/*!
+ Inserts the TQIconViewItem \a item in the icon view's grid. \e{You
+ should never need to call this function.} Instead, insert
+ TQIconViewItems by creating them with a pointer to the TQIconView
+ that they are to be inserted into.
+*/
+
+void TQIconView::insertInGrid( TQIconViewItem *item )
+{
+ if ( !item )
+ return;
+
+ if ( d->reorderItemsWhenInsert ) {
+ // #### make this efficient - but it's not too dramatic
+ int y = d->spacing;
+
+ item->dirty = FALSE;
+ if ( item == d->firstItem ) {
+ bool dummy;
+ makeRowLayout( item, y, dummy );
+ return;
+ }
+
+ TQIconViewItem *begin = rowBegin( item );
+ y = begin->y();
+ while ( begin ) {
+ bool dummy;
+ begin = makeRowLayout( begin, y, dummy );
+
+ if ( !begin || !begin->next )
+ break;
+
+ begin = begin->next;
+ }
+ item->dirty = FALSE;
+ } else {
+ TQRegion r( TQRect( 0, 0, TQMAX( contentsWidth(), visibleWidth() ),
+ TQMAX( contentsHeight(), visibleHeight() ) ) );
+
+ TQIconViewItem *i = d->firstItem;
+ int y = -1;
+ for ( ; i; i = i->next ) {
+ r = r.subtract( i->rect() );
+ y = TQMAX( y, i->y() + i->height() );
+ }
+
+ TQMemArray<TQRect> rects = r.tqrects();
+ TQMemArray<TQRect>::Iterator it = rects.begin();
+ bool foundPlace = FALSE;
+ for ( ; it != rects.end(); ++it ) {
+ TQRect rect = *it;
+ if ( rect.width() >= item->width() &&
+ rect.height() >= item->height() ) {
+ int sx = 0, sy = 0;
+ if ( rect.width() >= item->width() + d->spacing )
+ sx = d->spacing;
+ if ( rect.height() >= item->height() + d->spacing )
+ sy = d->spacing;
+ item->move( rect.x() + sx, rect.y() + sy );
+ foundPlace = TRUE;
+ break;
+ }
+ }
+
+ if ( !foundPlace )
+ item->move( d->spacing, y + d->spacing );
+
+ resizeContents( TQMAX( contentsWidth(), item->x() + item->width() ),
+ TQMAX( contentsHeight(), item->y() + item->height() ) );
+ item->dirty = FALSE;
+ }
+}
+
+/*!
+ Emits a signal to indicate selection changes. \a i is the
+ TQIconViewItem that was selected or de-selected.
+
+ \e{You should never need to call this function.}
+*/
+
+void TQIconView::emitSelectionChanged( TQIconViewItem *i )
+{
+ emit selectionChanged();
+ if ( d->selectionMode == Single )
+ emit selectionChanged( i ? i : d->currentItem );
+}
+
+/*!
+ \internal
+*/
+
+void TQIconView::emitRenamed( TQIconViewItem *item )
+{
+ if ( !item )
+ return;
+
+ emit itemRenamed( item, item->text() );
+ emit itemRenamed( item );
+}
+
+/*!
+ If a drag enters the icon view the tqshapes of the objects which the
+ drag tqcontains are drawn, usnig \a pos as origin.
+*/
+
+void TQIconView::drawDragShapes( const TQPoint &pos )
+{
+#ifndef TQT_NO_DRAGANDDROP
+ if ( pos == TQPoint( -1, -1 ) )
+ return;
+
+ if ( !d->drawDragShapes ) {
+ d->drawDragShapes = TRUE;
+ return;
+ }
+
+ TQStyleOption opt(tqcolorGroup().base());
+
+ TQPainter p;
+ p.begin( viewport() );
+ p.translate( -contentsX(), -contentsY() );
+ p.setRasterOp( TQt::NotROP );
+ p.setPen( TQPen( Qt::color0 ) );
+
+ if ( d->isIconDrag ) {
+ TQValueList<TQIconDragDataItem>::Iterator it = d->iconDragData.begin();
+ for ( ; it != d->iconDragData.end(); ++it ) {
+ TQRect ir = (*it).item.pixmapRect();
+ TQRect tr = (*it).item.textRect();
+ tr.moveBy( pos.x(), pos.y() );
+ ir.moveBy( pos.x(), pos.y() );
+ if ( !ir.intersects( TQRect( contentsX(), contentsY(), visibleWidth(), visibleHeight() ) ) )
+ continue;
+
+ tqstyle().tqdrawPrimitive(TQStyle::PE_FocusRect, &p, ir, tqcolorGroup(),
+ TQStyle::Style_Default, opt);
+ tqstyle().tqdrawPrimitive(TQStyle::PE_FocusRect, &p, tr, tqcolorGroup(),
+ TQStyle::Style_Default, opt);
+ }
+ } else if ( d->numDragItems > 0 ) {
+ for ( int i = 0; i < d->numDragItems; ++i ) {
+ TQRect r( pos.x() + i * 40, pos.y(), 35, 35 );
+ tqstyle().tqdrawPrimitive(TQStyle::PE_FocusRect, &p, r, tqcolorGroup(),
+ TQStyle::Style_Default, opt);
+ }
+
+ }
+ p.end();
+#endif
+}
+
+/*!
+ When a drag enters the icon view, this function is called to
+ initialize it. Initializing in this context means getting
+ information about the drag, for example so that the icon view
+ knows enough about the drag to be able to draw drag tqshapes for the
+ drag data (e.g. tqshapes of icons which are dragged), etc.
+*/
+
+#ifndef TQT_NO_DRAGANDDROP
+void TQIconView::initDragEnter( TQDropEvent *e )
+{
+ if ( TQIconDrag::canDecode( e ) ) {
+ TQIconDragPrivate::decode( e, d->iconDragData );
+ d->isIconDrag = TRUE;
+ } else if ( TQUriDrag::canDecode( e ) ) {
+ TQStrList lst;
+ TQUriDrag::decode( e, lst );
+ d->numDragItems = lst.count();
+ } else {
+ d->numDragItems = 0;
+ }
+
+}
+#endif
+
+/*!
+ This function is called to draw the rectangle \a r of the
+ background using the painter \a p.
+
+ The default implementation fills \a r with the viewport's
+ backgroundBrush(). Subclasses may reimplement this to draw custom
+ backgrounds.
+
+ \sa contentsX() contentsY() drawContents()
+*/
+
+void TQIconView::drawBackground( TQPainter *p, const TQRect &r )
+{
+ p->fillRect( r, viewport()->backgroundBrush() );
+}
+
+/*!
+ \reimp
+*/
+
+bool TQIconView::eventFilter( TQObject * o, TQEvent * e )
+{
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(viewport()) ) {
+ switch( e->type() ) {
+ case TQEvent::FocusIn:
+ focusInEvent( (TQFocusEvent*)e );
+ return TRUE;
+ case TQEvent::FocusOut:
+ focusOutEvent( (TQFocusEvent*)e );
+ return TRUE;
+ case TQEvent::Enter:
+ enterEvent( e );
+ return TRUE;
+ case TQEvent::Paint:
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(viewport()) ) {
+ if ( d->dragging ) {
+ if ( !d->rubber )
+ drawDragShapes( d->oldDragPos );
+ }
+ viewportPaintEvent( (TQPaintEvent*)e );
+ if ( d->dragging ) {
+ if ( !d->rubber )
+ drawDragShapes( d->oldDragPos );
+ }
+ }
+ return TRUE;
+ default:
+ // nothing
+ break;
+ }
+ }
+
+ return TQScrollView::eventFilter( o, e );
+}
+
+
+/*!
+ \reimp
+*/
+
+TQSize TQIconView::tqminimumSizeHint() const
+{
+ return TQScrollView::tqminimumSizeHint();
+}
+
+/*!
+ \internal
+ Finds the next item after the start item beginning
+ with \a text.
+*/
+
+TQIconViewItem* TQIconView::tqfindItemByName( TQIconViewItem *start )
+{
+ if ( !start )
+ return 0;
+ TQString match = d->currInputString.lower();
+ if ( match.length() < 1 )
+ return start;
+ TQString curText;
+ TQIconViewItem *i = start;
+ do {
+ curText = i->text().lower();
+ if ( curText.startsWith( match ) )
+ return i;
+ i = i->next;
+ if ( !i )
+ i = d->firstItem;
+ } while ( i != start );
+ return 0;
+}
+
+/*!
+ Lays out a row of icons (if Arrangement == \c TopToBottom this is
+ a column). Starts laying out with the item \a begin. \a y is the
+ starting coordinate. Returns the last item of the row (column) and
+ sets the new starting coordinate to \a y. The \a changed parameter
+ is used internally.
+
+ \warning This function may be made private in a future version of
+ TQt. We do not recommend calling it.
+*/
+
+TQIconViewItem *TQIconView::makeRowLayout( TQIconViewItem *begin, int &y, bool &changed )
+{
+ TQIconViewItem *end = 0;
+
+ bool reverse = TQApplication::reverseLayout();
+ changed = FALSE;
+
+ if ( d->arrangement == LeftToRight ) {
+
+ if ( d->rastX == -1 ) {
+ // first calculate the row height
+ int h = 0;
+ int x = 0;
+ int ih = 0;
+ TQIconViewItem *item = begin;
+ for (;;) {
+ x += d->spacing + item->width();
+ if ( x > visibleWidth() && item != begin ) {
+ item = item->prev;
+ break;
+ }
+ h = TQMAX( h, item->height() );
+ ih = TQMAX( ih, item->pixmapRect().height() );
+ TQIconViewItem *old = item;
+ item = item->next;
+ if ( !item ) {
+ item = old;
+ break;
+ }
+ }
+ end = item;
+
+ if ( d->rastY != -1 )
+ h = TQMAX( h, d->rastY );
+
+ // now move the items
+ item = begin;
+ for (;;) {
+ item->dirty = FALSE;
+ int x;
+ if ( item == begin ) {
+ if ( reverse )
+ x = visibleWidth() - d->spacing - item->width();
+ else
+ x = d->spacing;
+ } else {
+ if ( reverse )
+ x = item->prev->x() - item->width() - d->spacing;
+ else
+ x = item->prev->x() + item->prev->width() + d->spacing;
+ }
+ changed = item->move( x, y + ih - item->pixmapRect().height() ) || changed;
+ if ( y + h < item->y() + item->height() )
+ h = TQMAX( h, ih + item->textRect().height() );
+ if ( item == end )
+ break;
+ item = item->next;
+ }
+ y += h + d->spacing;
+ } else {
+ // first calculate the row height
+ int h = begin->height();
+ int x = d->spacing;
+ int ih = begin->pixmapRect().height();
+ TQIconViewItem *item = begin;
+ int i = 0;
+ int sp = 0;
+ for (;;) {
+ int r = calcGridNum( item->width(), d->rastX );
+ if ( item == begin ) {
+ i += r;
+ sp += r;
+ x = d->spacing + d->rastX * r;
+ } else {
+ sp += r;
+ i += r;
+ x = i * d->rastX + sp * d->spacing;
+ }
+ if ( x > visibleWidth() && item != begin ) {
+ item = item->prev;
+ break;
+ }
+ h = TQMAX( h, item->height() );
+ ih = TQMAX( ih, item->pixmapRect().height() );
+ TQIconViewItem *old = item;
+ item = item->next;
+ if ( !item ) {
+ item = old;
+ break;
+ }
+ }
+ end = item;
+
+ if ( d->rastY != -1 )
+ h = TQMAX( h, d->rastY );
+
+ // now move the items
+ item = begin;
+ i = 0;
+ sp = 0;
+ for (;;) {
+ item->dirty = FALSE;
+ int r = calcGridNum( item->width(), d->rastX );
+ if ( item == begin ) {
+ if ( d->itemTextPos == Bottom )
+ changed = item->move( d->spacing + ( r * d->rastX - item->width() ) / 2,
+ y + ih - item->pixmapRect().height() ) || changed;
+ else
+ changed = item->move( d->spacing, y + ih - item->pixmapRect().height() ) || changed;
+ i += r;
+ sp += r;
+ } else {
+ sp += r;
+ int x = i * d->rastX + sp * d->spacing;
+ if ( d->itemTextPos == Bottom )
+ changed = item->move( x + ( r * d->rastX - item->width() ) / 2,
+ y + ih - item->pixmapRect().height() ) || changed;
+ else
+ changed = item->move( x, y + ih - item->pixmapRect().height() ) || changed;
+ i += r;
+ }
+ if ( y + h < item->y() + item->height() )
+ h = TQMAX( h, ih + item->textRect().height() );
+ if ( item == end )
+ break;
+ item = item->next;
+ }
+ y += h + d->spacing;
+ }
+
+
+ } else { // -------------------------------- SOUTH ------------------------------
+
+ int x = y;
+
+ {
+ int w = 0;
+ int y = 0;
+ TQIconViewItem *item = begin;
+ for (;;) {
+ y += d->spacing + item->height();
+ if ( y > visibleHeight() && item != begin ) {
+ item = item->prev;
+ break;
+ }
+ w = TQMAX( w, item->width() );
+ TQIconViewItem *old = item;
+ item = item->next;
+ if ( !item ) {
+ item = old;
+ break;
+ }
+ }
+ end = item;
+
+ if ( d->rastX != -1 )
+ w = TQMAX( w, d->rastX );
+
+ // now move the items
+ item = begin;
+ for (;;) {
+ item->dirty = FALSE;
+ if ( d->itemTextPos == Bottom ) {
+ if ( item == begin )
+ changed = item->move( x + ( w - item->width() ) / 2, d->spacing ) || changed;
+ else
+ changed = item->move( x + ( w - item->width() ) / 2,
+ item->prev->y() + item->prev->height() + d->spacing ) || changed;
+ } else {
+ if ( item == begin )
+ changed = item->move( x, d->spacing ) || changed;
+ else
+ changed = item->move( x, item->prev->y() + item->prev->height() + d->spacing ) || changed;
+ }
+ if ( item == end )
+ break;
+ item = item->next;
+ }
+ x += w + d->spacing;
+ }
+
+ y = x;
+ }
+
+ return end;
+}
+
+/*!
+ \internal
+ Calculates how many cells an item of width \a w needs in a grid with of
+ \a x and returns the result.
+*/
+
+int TQIconView::calcGridNum( int w, int x ) const
+{
+ float r = (float)w / (float)x;
+ if ( ( w / x ) * x != w )
+ r += 1.0;
+ return (int)r;
+}
+
+/*!
+ \internal
+ Returns the first item of the row which tqcontains \a item.
+*/
+
+TQIconViewItem *TQIconView::rowBegin( TQIconViewItem * ) const
+{
+ // #### todo
+ return d->firstItem;
+}
+
+/*!
+ Sorts and rearranges all the items in the icon view. If \a
+ ascending is TRUE, the items are sorted in increasing order,
+ otherwise they are sorted in decreasing order.
+
+ TQIconViewItem::compare() is used to compare pairs of items. The
+ sorting is based on the items' keys; these default to the items'
+ text unless specifically set to something else.
+
+ Note that this function sets the sort order to \a ascending.
+
+ \sa TQIconViewItem::key(), TQIconViewItem::setKey(),
+ TQIconViewItem::compare(), TQIconView::setSorting(),
+ TQIconView::sortDirection()
+*/
+
+void TQIconView::sort( bool ascending )
+{
+ if ( count() == 0 )
+ return;
+
+ d->sortDirection = ascending;
+ TQIconViewPrivate::SortableItem *items = new TQIconViewPrivate::SortableItem[ count() ];
+
+ TQIconViewItem *item = d->firstItem;
+ int i = 0;
+ for ( ; item; item = item->next )
+ items[ i++ ].item = item;
+
+ qsort( items, count(), sizeof( TQIconViewPrivate::SortableItem ), cmpIconViewItems );
+
+ TQIconViewItem *prev = 0;
+ item = 0;
+ if ( ascending ) {
+ for ( i = 0; i < (int)count(); ++i ) {
+ item = items[ i ].item;
+ if ( item ) {
+ item->prev = prev;
+ if ( item->prev )
+ item->prev->next = item;
+ item->next = 0;
+ }
+ if ( i == 0 )
+ d->firstItem = item;
+ if ( i == (int)count() - 1 )
+ d->lastItem = item;
+ prev = item;
+ }
+ } else {
+ for ( i = (int)count() - 1; i >= 0 ; --i ) {
+ item = items[ i ].item;
+ if ( item ) {
+ item->prev = prev;
+ if ( item->prev )
+ item->prev->next = item;
+ item->next = 0;
+ }
+ if ( i == (int)count() - 1 )
+ d->firstItem = item;
+ if ( i == 0 )
+ d->lastItem = item;
+ prev = item;
+ }
+ }
+
+ delete [] items;
+
+ arrangeItemsInGrid( TRUE );
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQIconView::tqsizeHint() const
+{
+ constPolish();
+
+ if ( !d->firstItem )
+ return TQScrollView::tqsizeHint();
+
+ if ( d->dirty && d->firstSizeHint ) {
+ ( (TQIconView*)this )->resizeContents( TQMAX( 400, contentsWidth() ),
+ TQMAX( 400, contentsHeight() ) );
+ if ( autoArrange() )
+ ( (TQIconView*)this )->arrangeItemsInGrid( FALSE );
+ d->firstSizeHint = FALSE;
+ }
+
+ d->dirty = TRUE; // ######## warwick: I'm sure this is wrong. Fixed in 2.3.
+ int extra = tqstyle().tqpixelMetric(TQStyle::PM_ScrollBarExtent,
+ verticalScrollBar()) + 2*frameWidth();
+ TQSize s( TQMIN(400, contentsWidth() + extra),
+ TQMIN(400, contentsHeight() + extra) );
+ return s;
+}
+
+/*!
+ \internal
+*/
+
+void TQIconView::updateContents()
+{
+ viewport()->update();
+}
+
+/*!
+ \reimp
+*/
+
+void TQIconView::enterEvent( TQEvent *e )
+{
+ TQScrollView::enterEvent( e );
+ emit onViewport();
+}
+
+/*!
+ \internal
+ This function is always called when the tqgeometry of an item changes.
+ This function moves the item into the correct area in the internal
+ data structure.
+*/
+
+void TQIconView::updateItemContainer( TQIconViewItem *item )
+{
+ if ( !item || d->containerUpdateLocked || (!isVisible() && autoArrange()) )
+ return;
+
+ if ( item->d->container1 && d->firstContainer ) {
+ //Special-case to check if we can use removeLast otherwise use removeRef (slower)
+ if (item->d->container1->items.last() == item)
+ item->d->container1->items.removeLast();
+ else
+ item->d->container1->items.removeRef( item );
+ }
+ item->d->container1 = 0;
+ if ( item->d->container2 && d->firstContainer ) {
+ //Special-case to check if we can use removeLast otherwise use removeRef (slower)
+ if (item->d->container2->items.last() == item)
+ item->d->container2->items.removeLast();
+ else
+ item->d->container2->items.removeRef( item );
+ }
+ item->d->container2 = 0;
+
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer;
+ if ( !c ) {
+ appendItemContainer();
+ c = d->firstContainer;
+ }
+
+ const TQRect irect = item->rect();
+ bool tqcontains = FALSE;
+ for (;;) {
+ if ( c->rect.intersects( irect ) ) {
+ tqcontains = c->rect.tqcontains( irect );
+ break;
+ }
+
+ c = c->n;
+ if ( !c ) {
+ appendItemContainer();
+ c = d->lastContainer;
+ }
+ }
+
+ if ( !c ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQIconViewItem::updateItemContainer(): No fitting container found!" );
+#endif
+ return;
+ }
+
+ c->items.append( item );
+ item->d->container1 = c;
+
+ if ( !tqcontains ) {
+ c = c->n;
+ if ( !c ) {
+ appendItemContainer();
+ c = d->lastContainer;
+ }
+ c->items.append( item );
+ item->d->container2 = c;
+ }
+ if ( contentsWidth() < irect.right() || contentsHeight() < irect.bottom() )
+ resizeContents( TQMAX( contentsWidth(), irect.right() ), TQMAX( contentsHeight(), irect.bottom() ) );
+}
+
+/*!
+ \internal
+ Appends a new rect area to the internal data structure of the items.
+*/
+
+void TQIconView::appendItemContainer()
+{
+ TQSize s;
+ // #### We have to tqfind out which value is best here
+ if ( d->arrangement == LeftToRight )
+ s = TQSize( INT_MAX - 1, RECT_EXTENSION );
+ else
+ s = TQSize( RECT_EXTENSION, INT_MAX - 1 );
+
+ if ( !d->firstContainer ) {
+ d->firstContainer = new TQIconViewPrivate::ItemContainer( 0, 0, TQRect( TQPoint( 0, 0 ), s ) );
+ d->lastContainer = d->firstContainer;
+ } else {
+ if ( d->arrangement == LeftToRight )
+ d->lastContainer = new TQIconViewPrivate::ItemContainer(
+ d->lastContainer, 0, TQRect( d->lastContainer->rect.bottomLeft(), s ) );
+ else
+ d->lastContainer = new TQIconViewPrivate::ItemContainer(
+ d->lastContainer, 0, TQRect( d->lastContainer->rect.topRight(), s ) );
+ }
+}
+
+/*! \internal
+
+ Rebuilds the whole internal data structure. This is done when it's
+ likely that most/all items change their tqgeometry (e.g. in
+ arrangeItemsInGrid()), because calling this is then more efficient
+ than calling updateItemContainer() for each item.
+*/
+
+void TQIconView::rebuildContainers()
+{
+ TQIconViewPrivate::ItemContainer *c = d->firstContainer, *tmpc;
+ while ( c ) {
+ tmpc = c->n;
+ delete c;
+ c = tmpc;
+ }
+ d->firstContainer = d->lastContainer = 0;
+
+ TQIconViewItem *item = d->firstItem;
+ appendItemContainer();
+ c = d->lastContainer;
+ while ( item ) {
+ if ( c->rect.tqcontains( item->rect() ) ) {
+ item->d->container1 = c;
+ item->d->container2 = 0;
+ c->items.append( item );
+ item = item->next;
+ } else if ( c->rect.intersects( item->rect() ) ) {
+ item->d->container1 = c;
+ c->items.append( item );
+ c = c->n;
+ if ( !c ) {
+ appendItemContainer();
+ c = d->lastContainer;
+ }
+ c->items.append( item );
+ item->d->container2 = c;
+ item = item->next;
+ c = c->p;
+ } else {
+ if ( d->arrangement == LeftToRight ) {
+ if ( item->y() < c->rect.y() && c->p ) {
+ c = c->p;
+ continue;
+ }
+ } else {
+ if ( item->x() < c->rect.x() && c->p ) {
+ c = c->p;
+ continue;
+ }
+ }
+
+ c = c->n;
+ if ( !c ) {
+ appendItemContainer();
+ c = d->lastContainer;
+ }
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+
+void TQIconView::movedContents( int, int )
+{
+ if ( d->drawDragShapes ) {
+ drawDragShapes( d->oldDragPos );
+ d->oldDragPos = TQPoint( -1, -1 );
+ }
+}
+
+void TQIconView::handleItemChange( TQIconViewItem *old, bool shift,
+ bool control, bool homeend )
+{
+ if ( d->selectionMode == Single ) {
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ if ( old )
+ old->setSelected( FALSE );
+ blockSignals( block );
+ d->currentItem->setSelected( TRUE, TRUE );
+ } else if ( d->selectionMode == Extended ) {
+ if ( shift ) {
+ if ( !d->selectAnchor ) {
+ if ( old && !old->selected && old->isSelectable() ) {
+ old->selected = TRUE;
+ repaintItem( old );
+ }
+ d->currentItem->setSelected( TRUE, TRUE );
+ } else {
+ TQIconViewItem *from = d->selectAnchor, *to = d->currentItem;
+ if ( !from || !to )
+ return;
+
+ // checking if it's downwards and if we span rows
+ bool downwards = FALSE;
+ bool spanning = FALSE;
+ if ( d->arrangement == LeftToRight) {
+ if ( from->rect().center().y() < to->rect().center().y() )
+ downwards = TRUE;
+ } else {
+ if ( from->rect().center().x() < to->rect().center().x() )
+ downwards = TRUE;
+ }
+
+ TQRect fr = from->rect();
+ TQRect tr = to->rect();
+ if ( d->arrangement == LeftToRight ) {
+ fr.moveTopLeft( TQPoint( tr.x(), fr.y() ) );
+ if ( !tr.intersects( fr ) )
+ spanning = TRUE;
+ } else {
+ fr.moveTopLeft( TQPoint( fr.x(), tr.y() ) );
+ if ( !tr.intersects( fr ) )
+ spanning = TRUE;
+ }
+
+
+ // tqfinding the rectangles
+ TQRect topRect, bottomRect, midRect;
+ if ( !spanning ) {
+ midRect = from->rect().unite( to->rect() );
+ } else {
+ if ( downwards ) {
+ topRect = from->rect();
+ bottomRect = to->rect();
+ } else {
+ topRect = to->rect();
+ bottomRect = from->rect();
+ }
+ if ( d->arrangement == LeftToRight ) {
+ topRect.setRight( contentsWidth() );
+ bottomRect.setLeft( 0 );
+ midRect.setRect( 0, topRect.bottom(),
+ contentsWidth(),
+ bottomRect.top() - topRect.bottom() );
+ } else {
+ topRect.setBottom( contentsHeight() );
+ bottomRect.setTop( 0 );
+ midRect.setRect( topRect.right(),
+ 0,
+ bottomRect.left() - topRect.right(),
+ contentsHeight() );
+ }
+ }
+
+ // tqfinding contained items and selecting them
+ TQIconViewItem *item = 0;
+ bool changed = FALSE;
+ bool midValid = midRect.isValid();
+ bool topValid = topRect.isValid();
+ bool bottomValid = bottomRect.isValid();
+ TQRect selectedRect, unselectedRect;
+ for ( item = d->firstItem; item; item = item->next ) {
+ bool contained = FALSE;
+ TQPoint itemCenter = item->rect().center();
+ if ( midValid && midRect.tqcontains( itemCenter ) )
+ contained = TRUE;
+ if ( !contained && topValid && topRect.tqcontains( itemCenter ) )
+ contained = TRUE;
+ if ( !contained && bottomValid && bottomRect.tqcontains( itemCenter ) )
+ contained = TRUE;
+
+ if ( contained ) {
+ if ( !item->selected && item->isSelectable() ) {
+ changed = TRUE;
+ item->selected = TRUE;
+ selectedRect = selectedRect.unite( item->rect() );
+ }
+ } else if ( item->selected && !control ) {
+ item->selected = FALSE;
+ unselectedRect = unselectedRect.unite( item->rect() );
+ changed = TRUE;
+ }
+ }
+
+ TQRect viewRect( contentsX(), contentsY(),
+ visibleWidth(), visibleHeight() );
+
+ if ( viewRect.intersects( selectedRect ) ) {
+ if ( homeend )
+ TQScrollView::updateContents( viewRect.intersect( selectedRect ) );
+ else
+ repaintContents( viewRect.intersect( selectedRect ) );
+ }
+ if ( viewRect.intersects( unselectedRect ) ) {
+ if ( homeend )
+ TQScrollView::updateContents( viewRect.intersect( unselectedRect ) );
+ else
+ repaintContents( viewRect.intersect( unselectedRect ) );
+ }
+
+ if ( changed )
+ emit selectionChanged();
+ }
+ } else if ( !control ) {
+ blockSignals( TRUE );
+ selectAll( FALSE );
+ blockSignals( FALSE );
+ d->currentItem->setSelected( TRUE, TRUE );
+ }
+ } else {
+ if ( shift )
+ d->currentItem->setSelected( !d->currentItem->isSelected(), TRUE );
+ }
+}
+
+TQBitmap TQIconView::tqmask( TQPixmap *pix ) const
+{
+ TQPixmap m;
+ if ( d->maskCache.tqfind( TQT_TQSTRING(TQString::number( pix->serialNumber() )), m ) )
+ return TQBitmap(m);
+ m = pix->createHeuristicMask();
+ d->maskCache.insert( TQString::number( pix->serialNumber() ), m );
+ return TQBitmap(m);
+}
+
+/*!
+ \reimp
+ \internal
+
+ (Implemented to get rid of a compiler warning.)
+*/
+void TQIconView::drawContents( TQPainter * )
+{
+}
+
+/*!
+ \reimp
+*/
+void TQIconView::windowActivationChange( bool oldActive )
+{
+ if ( oldActive && d->scrollTimer )
+ d->scrollTimer->stop();
+
+ if ( !isVisible() )
+ return;
+
+ if ( tqpalette().active() == tqpalette().inactive() )
+ return;
+
+ repaintSelectedItems();
+}
+
+/*!
+ Returns TRUE if an iconview item is being renamed; otherwise
+ returns FALSE.
+*/
+
+bool TQIconView::isRenaming() const
+{
+#ifndef TQT_NO_TEXTEDIT
+ return d->renamingItem && d->renamingItem->renameBox;
+#else
+ return FALSE;
+#endif
+}
+
+#endif // TQT_NO_ICONVIEW
diff --git a/tqtinterface/qt4/src/iconview/tqiconview.h b/tqtinterface/qt4/src/iconview/tqiconview.h
new file mode 100644
index 0000000..9ca8a42
--- /dev/null
+++ b/tqtinterface/qt4/src/iconview/tqiconview.h
@@ -0,0 +1,516 @@
+/****************************************************************************
+**
+** Definition of TQIconView widget class
+**
+** Created : 990707
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the iconview module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQICONVIEW_H
+#define TQICONVIEW_H
+
+#ifndef TQT_H
+#include "tqscrollview.h"
+#include "tqstring.h"
+#include "tqrect.h"
+#include "tqpoint.h"
+#include "tqsize.h"
+#include "tqfont.h" // TQString->TQFont conversion
+#include "tqdragobject.h"
+#include "tqbitmap.h"
+#include "tqpicture.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_ICONVIEW
+
+#if !defined( TQT_MODULE_ICONVIEW ) || defined( TQT_INTERNAL_ICONVIEW )
+#define TQM_EXPORT_ICONVIEW
+#else
+#define TQM_EXPORT_ICONVIEW TQ_EXPORT
+#endif
+
+class TQIconView;
+class TQPainter;
+class TQMimeSource;
+class TQMouseEvent;
+class TQDragEnterEvent;
+class TQDragMoveEvent;
+class TQDragLeaveEvent;
+class TQKeyEvent;
+class TQFocusEvent;
+class TQShowEvent;
+class TQIconViewItem;
+class TQIconViewItemLineEdit;
+class TQStringList;
+class TQIconDragPrivate;
+
+#ifndef TQT_NO_DRAGANDDROP
+
+class TQM_EXPORT_ICONVIEW TQIconDragItem
+{
+public:
+ TQIconDragItem();
+ virtual ~TQIconDragItem();
+ virtual TQByteArray data() const;
+ virtual void setData( const TQByteArray &d );
+ bool operator== ( const TQIconDragItem& ) const;
+
+private:
+ TQByteArray ba;
+
+};
+
+class TQM_EXPORT_ICONVIEW TQIconDrag : public TQDragObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQIconDrag( TQWidget * dragSource, const char* name = 0 );
+ virtual ~TQIconDrag();
+
+ void append( const TQIconDragItem &item, const TQRect &pr, const TQRect &tr );
+
+ virtual const char* format( int i ) const;
+ static bool canDecode( TQMimeSource* e );
+ virtual TQByteArray tqencodedData( const char* mime ) const;
+
+private:
+ TQIconDragPrivate *d;
+ TQChar endMark;
+
+ friend class TQIconView;
+ friend class TQIconViewPrivate;
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQIconDrag( const TQIconDrag & );
+ TQIconDrag &operator=( const TQIconDrag & );
+#endif
+};
+
+#endif
+
+class TQIconViewToolTip;
+class TQIconViewItemPrivate;
+
+class TQM_EXPORT_ICONVIEW TQIconViewItem : public TQt
+{
+ friend class TQIconView;
+ friend class TQIconViewToolTip;
+ friend class TQIconViewItemLineEdit;
+
+public:
+ TQIconViewItem( TQIconView *tqparent );
+ TQIconViewItem( TQIconView *tqparent, TQIconViewItem *after );
+ TQIconViewItem( TQIconView *tqparent, const TQString &text );
+ TQIconViewItem( TQIconView *tqparent, TQIconViewItem *after, const TQString &text );
+ TQIconViewItem( TQIconView *tqparent, const TQString &text, const TQPixmap &icon );
+ TQIconViewItem( TQIconView *tqparent, TQIconViewItem *after, const TQString &text, const TQPixmap &icon );
+#ifndef TQT_NO_PICTURE
+ TQIconViewItem( TQIconView *tqparent, const TQString &text, const TQPicture &picture );
+ TQIconViewItem( TQIconView *tqparent, TQIconViewItem *after, const TQString &text, const TQPicture &picture );
+#endif
+ virtual ~TQIconViewItem();
+
+ virtual void setRenameEnabled( bool allow );
+ virtual void setDragEnabled( bool allow );
+ virtual void setDropEnabled( bool allow );
+
+ virtual TQString text() const;
+ virtual TQPixmap *pixmap() const;
+#ifndef TQT_NO_PICTURE
+ virtual TQPicture *picture() const;
+#endif
+ virtual TQString key() const;
+
+ bool renameEnabled() const;
+ bool dragEnabled() const;
+ bool dropEnabled() const;
+
+ TQIconView *iconView() const;
+ TQIconViewItem *prevItem() const;
+ TQIconViewItem *nextItem() const;
+
+ int index() const;
+
+ virtual void setSelected( bool s, bool cb );
+ virtual void setSelected( bool s );
+ virtual void setSelectable( bool s );
+
+ bool isSelected() const;
+ bool isSelectable() const;
+
+ virtual void tqrepaint();
+
+ virtual bool move( int x, int y );
+ virtual void moveBy( int dx, int dy );
+ virtual bool move( const TQPoint &pnt );
+ virtual void moveBy( const TQPoint &pnt );
+
+ TQRect rect() const;
+ int x() const;
+ int y() const;
+ int width() const;
+ int height() const;
+ TQSize size() const;
+ TQPoint pos() const;
+ TQRect textRect( bool relative = TRUE ) const;
+ TQRect pixmapRect( bool relative = TRUE ) const;
+ bool tqcontains( const TQPoint& pnt ) const;
+ bool intersects( const TQRect& r ) const;
+
+ virtual bool acceptDrop( const TQMimeSource *mime ) const;
+
+#ifndef TQT_NO_TEXTEDIT
+ void rename();
+#endif
+
+ virtual int compare( TQIconViewItem *i ) const;
+
+ virtual void setText( const TQString &text );
+ virtual void setPixmap( const TQPixmap &icon );
+#ifndef TQT_NO_PICTURE
+ virtual void setPicture( const TQPicture &icon );
+#endif
+ virtual void setText( const TQString &text, bool recalc, bool redraw = TRUE );
+ virtual void setPixmap( const TQPixmap &icon, bool recalc, bool redraw = TRUE );
+ virtual void setKey( const TQString &k );
+
+ virtual int rtti() const;
+ static int RTTI;
+
+protected:
+#ifndef TQT_NO_TEXTEDIT
+ virtual void removeRenameBox();
+#endif
+ virtual void calcRect( const TQString &text_ = TQString::null );
+ virtual void paintItem( TQPainter *p, const TQColorGroup &cg );
+ virtual void paintFocus( TQPainter *p, const TQColorGroup &cg );
+#ifndef TQT_NO_DRAGANDDROP
+ virtual void dropped( TQDropEvent *e, const TQValueList<TQIconDragItem> &lst );
+#endif
+ virtual void dragEntered();
+ virtual void dragLeft();
+ void setItemRect( const TQRect &r );
+ void setTextRect( const TQRect &r );
+ void setPixmapRect( const TQRect &r );
+ void calcTmpText();
+ TQString tempText() const;
+
+private:
+ void init( TQIconViewItem *after = 0
+#ifndef TQT_NO_PICTURE
+ , TQPicture *pic = 0
+#endif
+ );
+#ifndef TQT_NO_TEXTEDIT
+ void renameItem();
+ void cancelRenameItem();
+#endif
+ void checkRect();
+
+ TQIconView *view;
+ TQString itemText, itemKey;
+ TQString tmpText;
+ TQPixmap *itemIcon;
+#ifndef TQT_NO_PICTURE
+ TQPicture *itemPic;
+#endif
+ TQIconViewItem *prev, *next;
+ uint allow_rename : 1;
+ uint allow_drag : 1;
+ uint allow_drop : 1;
+ uint selected : 1;
+ uint selectable : 1;
+ uint dirty : 1;
+ uint wordWrapDirty : 1;
+ TQRect tqitemRect, itemTextRect, itemIconRect;
+#ifndef TQT_NO_TEXTEDIT
+ TQIconViewItemLineEdit *renameBox;
+#endif
+ TQRect oldRect;
+
+ TQIconViewItemPrivate *d;
+
+};
+
+class TQIconViewPrivate; /* don't touch */
+
+class TQM_EXPORT_ICONVIEW TQIconView : public TQScrollView
+{
+ friend class TQIconViewItem;
+ friend class TQIconViewPrivate;
+ friend class TQIconViewToolTip;
+
+ Q_OBJECT
+ TQ_OBJECT
+ // #### sorting and sort direction do not work
+ TQ_ENUMS( SelectionMode ItemTextPos Arrangement ResizeMode )
+ Q_PROPERTY( bool sorting READ sorting )
+ Q_PROPERTY( bool sortDirection READ sortDirection )
+ Q_PROPERTY( SelectionMode selectionMode READ selectionMode WRITE setSelectionMode )
+ Q_PROPERTY( int gridX READ gridX WRITE setGridX )
+ Q_PROPERTY( int gridY READ gridY WRITE setGridY )
+ Q_PROPERTY( int spacing READ spacing WRITE setSpacing )
+ Q_PROPERTY( ItemTextPos itemTextPos READ itemTextPos WRITE setItemTextPos )
+ Q_PROPERTY( TQBrush itemTextBackground READ itemTextBackground WRITE setItemTextBackground )
+ Q_PROPERTY( Arrangement arrangement READ arrangement WRITE setArrangement )
+ Q_PROPERTY( ResizeMode resizeMode READ resizeMode WRITE setResizeMode )
+ Q_PROPERTY( int maxItemWidth READ maxItemWidth WRITE setMaxItemWidth )
+ Q_PROPERTY( int maxItemTextLength READ maxItemTextLength WRITE setMaxItemTextLength )
+ Q_PROPERTY( bool autoArrange READ autoArrange WRITE setAutoArrange )
+ Q_PROPERTY( bool itemsMovable READ itemsMovable WRITE setItemsMovable )
+ Q_PROPERTY( bool wordWrapIconText READ wordWrapIconText WRITE setWordWrapIconText )
+ Q_PROPERTY( bool showToolTips READ showToolTips WRITE setShowToolTips )
+ Q_PROPERTY( uint count READ count )
+
+public:
+ enum SelectionMode {
+ Single = 0,
+ Multi,
+ Extended,
+ NoSelection
+ };
+ enum Arrangement {
+ LeftToRight = 0,
+ TopToBottom
+ };
+ enum ResizeMode {
+ Fixed = 0,
+ Adjust
+ };
+ enum ItemTextPos {
+ Bottom = 0,
+ Right
+ };
+
+ TQIconView( TQWidget* tqparent=0, const char* name=0, WFlags f = 0 );
+ virtual ~TQIconView();
+
+ virtual void insertItem( TQIconViewItem *item, TQIconViewItem *after = 0L );
+ virtual void takeItem( TQIconViewItem *item );
+
+ int index( const TQIconViewItem *item ) const;
+
+ TQIconViewItem *firstItem() const;
+ TQIconViewItem *lastItem() const;
+ TQIconViewItem *currentItem() const;
+ virtual void setCurrentItem( TQIconViewItem *item );
+ virtual void setSelected( TQIconViewItem *item, bool s, bool cb = FALSE );
+
+ uint count() const;
+
+public:
+ virtual void showEvent( TQShowEvent * );
+
+ virtual void setSelectionMode( SelectionMode m );
+ SelectionMode selectionMode() const;
+
+ TQIconViewItem *tqfindItem( const TQPoint &pos ) const;
+ TQIconViewItem *tqfindItem( const TQString &text, TQt::ComparisonFlags compare = TQt::BeginsWith ) const;
+ virtual void selectAll( bool select );
+ virtual void clearSelection();
+ virtual void invertSelection();
+
+ virtual void repaintItem( TQIconViewItem *item );
+ void repaintSelectedItems();
+
+ void ensureItemVisible( TQIconViewItem *item );
+ TQIconViewItem* tqfindFirstVisibleItem( const TQRect &r ) const;
+ TQIconViewItem* tqfindLastVisibleItem( const TQRect &r ) const;
+
+ virtual void clear();
+
+ virtual void setGridX( int rx );
+ virtual void setGridY( int ry );
+ int gridX() const;
+ int gridY() const;
+ virtual void setSpacing( int sp );
+ int spacing() const;
+ virtual void setItemTextPos( ItemTextPos pos );
+ ItemTextPos itemTextPos() const;
+ virtual void setItemTextBackground( const TQBrush &b );
+ TQBrush itemTextBackground() const;
+ virtual void setArrangement( Arrangement am );
+ Arrangement arrangement() const;
+ virtual void setResizeMode( ResizeMode am );
+ ResizeMode resizeMode() const;
+ virtual void setMaxItemWidth( int w );
+ int maxItemWidth() const;
+ virtual void setMaxItemTextLength( int w );
+ int maxItemTextLength() const;
+ virtual void setAutoArrange( bool b );
+ bool autoArrange() const;
+ virtual void setShowToolTips( bool b );
+ bool showToolTips() const;
+
+ void setSorting( bool sort, bool ascending = TRUE );
+ bool sorting() const;
+ bool sortDirection() const;
+
+ virtual void setItemsMovable( bool b );
+ bool itemsMovable() const;
+ virtual void setWordWrapIconText( bool b );
+ bool wordWrapIconText() const;
+
+ bool eventFilter( TQObject * o, TQEvent * );
+
+ TQSize tqminimumSizeHint() const;
+ TQSize tqsizeHint() const;
+
+ virtual void sort( bool ascending = TRUE );
+
+ virtual void setFont( const TQFont & );
+ virtual void setPalette( const TQPalette & );
+
+ bool isRenaming() const;
+
+public Q_SLOTS:
+ virtual void arrangeItemsInGrid( const TQSize &grid, bool update = TRUE );
+ virtual void arrangeItemsInGrid( bool update = TRUE );
+ virtual void setContentsPos( int x, int y );
+ virtual void updateContents();
+
+Q_SIGNALS:
+ void selectionChanged();
+ void selectionChanged( TQIconViewItem *item );
+ void currentChanged( TQIconViewItem *item );
+ void clicked( TQIconViewItem * );
+ void clicked( TQIconViewItem *, const TQPoint & );
+ void pressed( TQIconViewItem * );
+ void pressed( TQIconViewItem *, const TQPoint & );
+
+ void doubleClicked( TQIconViewItem *item );
+ void returnPressed( TQIconViewItem *item );
+ void rightButtonClicked( TQIconViewItem* item, const TQPoint& pos );
+ void rightButtonPressed( TQIconViewItem* item, const TQPoint& pos );
+ void mouseButtonPressed( int button, TQIconViewItem* item, const TQPoint& pos );
+ void mouseButtonClicked( int button, TQIconViewItem* item, const TQPoint& pos );
+ void contextMenuRequested( TQIconViewItem* item, const TQPoint &pos );
+
+#ifndef TQT_NO_DRAGANDDROP
+ void dropped( TQDropEvent *e, const TQValueList<TQIconDragItem> &lst );
+#endif
+ void moved();
+ void onItem( TQIconViewItem *item );
+ void onViewport();
+ void itemRenamed( TQIconViewItem *item, const TQString & );
+ void itemRenamed( TQIconViewItem *item );
+
+protected Q_SLOTS:
+ virtual void doAutoScroll();
+ virtual void adjustItems();
+ virtual void slotUpdate();
+
+private Q_SLOTS:
+ void movedContents( int dx, int dy );
+
+protected:
+ void drawContents( TQPainter *p, int cx, int cy, int cw, int ch );
+ void contentsMousePressEvent( TQMouseEvent *e );
+ void contentsMouseReleaseEvent( TQMouseEvent *e );
+ void contentsMouseMoveEvent( TQMouseEvent *e );
+ void contentsMouseDoubleClickEvent( TQMouseEvent *e );
+ void contentsContextMenuEvent( TQContextMenuEvent *e );
+
+#ifndef TQT_NO_DRAGANDDROP
+ void contentsDragEnterEvent( TQDragEnterEvent *e );
+ void contentsDragMoveEvent( TQDragMoveEvent *e );
+ void contentsDragLeaveEvent( TQDragLeaveEvent *e );
+ void contentsDropEvent( TQDropEvent *e );
+#endif
+
+ void resizeEvent( TQResizeEvent* e );
+ void keyPressEvent( TQKeyEvent *e );
+ void focusInEvent( TQFocusEvent *e );
+ void focusOutEvent( TQFocusEvent *e );
+ void enterEvent( TQEvent *e );
+
+ virtual void drawRubber( TQPainter *p );
+#ifndef TQT_NO_DRAGANDDROP
+ virtual TQDragObject *dragObject();
+ virtual void startDrag();
+#endif
+ virtual void insertInGrid( TQIconViewItem *item );
+ virtual void drawBackground( TQPainter *p, const TQRect &r );
+
+ void emitSelectionChanged( TQIconViewItem * i = 0 );
+ void emitRenamed( TQIconViewItem *item );
+
+ TQIconViewItem *makeRowLayout( TQIconViewItem *begin, int &y, bool &changed );
+
+ void styleChange( TQStyle& );
+ void windowActivationChange( bool );
+
+private:
+ void contentsMousePressEventEx( TQMouseEvent *e );
+ virtual void drawDragShapes( const TQPoint &pnt );
+#ifndef TQT_NO_DRAGANDDROP
+ virtual void initDragEnter( TQDropEvent *e );
+#endif
+ void drawContents( TQPainter* );
+ TQIconViewItem* tqfindItemByName( TQIconViewItem *start );
+ void handleItemChange( TQIconViewItem *old, bool shift,
+ bool control, bool homeend = FALSE);
+
+ int calcGridNum( int w, int x ) const;
+ TQIconViewItem *rowBegin( TQIconViewItem *item ) const;
+ void updateItemContainer( TQIconViewItem *item );
+ void appendItemContainer();
+ void rebuildContainers();
+ enum Direction {
+ DirUp = 0,
+ DirDown,
+ DirLeft,
+ DirRight
+ };
+ TQIconViewItem* tqfindItem( Direction dir,
+ const TQPoint &relativeTo,
+ const TQRect &searchRect ) const;
+ bool neighbourItem( Direction dir,
+ const TQPoint &relativeTo,
+ const TQIconViewItem *item ) const;
+ TQBitmap tqmask( TQPixmap *pix ) const;
+
+ TQIconViewPrivate *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQIconView( const TQIconView & );
+ TQIconView& operator=( const TQIconView & );
+#endif
+};
+
+#endif // TQT_NO_ICONVIEW
+
+#endif // TQICONVIEW_H
diff --git a/tqtinterface/qt4/src/kernel/makepsheader.pl b/tqtinterface/qt4/src/kernel/makepsheader.pl
new file mode 100755
index 0000000..b842e14
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/makepsheader.pl
@@ -0,0 +1,93 @@
+#!/usr/bin/perl
+
+open(INPUT, 'qpsprinter.ps')
+ or die "Can't open qpsprinter.ps";
+
+$dontcompress = 1;
+while(<INPUT>) {
+ $line = $_;
+ chomp $line;
+ if ( /ENDUNCOMPRESS/ ) {
+ $dontcompress = 0;
+ }
+ $line =~ s/%.*$//;
+ $line = $line;
+ if ( $dontcompress eq 1 ) {
+ push(@uncompressed, $line);
+ } else {
+ push(@lines, $line);
+ }
+# print "$line\n";
+}
+
+$uc = join(" ", @uncompressed);
+$uc =~ s,\t+, ,g;
+$uc=~ s, +, ,g;
+
+$h = join(" ", @lines);
+$h =~ s,\t+, ,g;
+$h =~ s, +, ,g;
+$h = $h.' ';
+
+# now compress as much as possible
+$h =~ s/ def / d /g;
+$h =~ s/ bind def / D /g;
+$h =~ s/ dup dup / d2 /g;
+$h =~ s/ exch d / ED /g;
+$h =~ s/ lineto / LT /g;
+$h =~ s/ moveto / MT /g;
+$h =~ s/ stroke / S /g;
+$h =~ s/ setfont / F /g;
+$h =~ s/ setlinewidth / SW /g;
+$h =~ s/ closepath / CP /g;
+$h =~ s/ rlineto / RL /g;
+$h =~ s/ newpath / NP /g;
+$h =~ s/ currentmatrix / CM /g;
+$h =~ s/ setmatrix / SM /g;
+$h =~ s/ translate / TR /g;
+$h =~ s/ setdash / SD /g;
+$h =~ s/ aload pop setrgbcolor / SC /g;
+$h =~ s/ currentfile read pop / CR /g;
+$h =~ s/ index / i /g;
+$h =~ s/ bitshift / bs /g;
+$h =~ s/ setcolorspace / scs /g;
+$h =~ s/ dict dup begin / DB /g;
+$h =~ s/ end d / DE /g;
+$h =~ s/ ifelse / ie /g;
+$h =~ s/ astore pop / sp /g;
+
+# add the uncompressed part of the header before
+$h = $uc.' '.$h;
+
+
+
+#print $h;
+
+# wordwrap at col 76
+@head = split(' ', $h);
+$line = shift @head;
+while( @head ) {
+ $token = shift @head;
+ chomp $token;
+# print "\nl=$l, len=$len, token=$token.";
+ $newline = $line.' '.$token;
+ $newline =~ s, /,/,g;
+ $newline =~ s, \{,\{,g;
+ $newline =~ s, \},\},g;
+ $newline =~ s, \[,\[,g;
+ $newline =~ s, \],\],g;
+ $newline =~ s,\{ ,\{,g;
+ $newline =~ s,\} ,\},g;
+ $newline =~ s,\[ ,\[,g;
+ $newline =~ s,\] ,\],g;
+ if ( length( $newline ) > 76 ) {
+# print "\nline=$line\n";
+ $header = $header."\n\"".$line."\\n\"";
+ $newline = $token;
+ }
+ $line = $newline;
+}
+$header = $header."\n\"".$line."\\n\"";
+
+
+print $header;
diff --git a/tqtinterface/qt4/src/kernel/qpsprinter.ps b/tqtinterface/qt4/src/kernel/qpsprinter.ps
new file mode 100644
index 0000000..b38868f
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/qpsprinter.ps
@@ -0,0 +1,805 @@
+% the postscript header we use for our qpsprinter in uncompressed and commented form.
+% use the makepsheader perl script to generate a compressed version of this header
+% you can then paste into qpsprinter.cpp
+%
+% some compression of the code is done by the makepsheader script, so we don't need to
+% write too criptically here.
+
+/d /def load def
+/D {bind d} bind d
+/d2 {dup dup} D
+/B {0 d2} D
+/W {255 d2} D
+/ED {exch d} D
+/D0 {0 ED} D
+/LT {lineto} D
+/MT {moveto} D
+/S {stroke} D
+/F {setfont} D
+/SW {setlinewidth} D
+/CP {closepath} D
+/RL {rlineto} D
+/NP {newpath} D
+/CM {currentmatrix} D
+/SM {setmatrix} D
+/TR {translate} D
+/SD {setdash} D
+/SC {aload pop setrgbcolor} D
+/CR {currentfile read pop} D
+/i {index} D
+/bs {bitshift} D
+/scs {setcolorspace} D
+/DB {dict dup begin} D
+/DE {end d} D
+/ie {ifelse} D
+/sp {astore pop} D
+
+% ENDUNCOMPRESSED: Warning: leave this line in.
+% Everything before this line will be left untouched by the compression
+
+
+
+/BSt 0 d % brush style
+/LWi 1 d % line width
+/PSt 1 d % pen style
+/Cx 0 d % current x position
+/Cy 0 d % current y position
+/WFi false d % winding fill
+/OMo false d % opaque mode (not transtqparent)
+
+/BCol [ 1 1 1 ] d % brush color
+/PCol [ 0 0 0 ] d % pen color
+/BkCol [ 1 1 1 ] d % background color
+/BDArr [ % Brush dense patterns
+ 0.94
+ 0.88
+ 0.63
+ 0.50
+ 0.37
+ 0.12
+ 0.06
+] d
+/defM matrix d
+
+/nS 0 d % number of saved painter states
+
+% LArr for the Pen styles is defined in emitHeader because of scaling
+
+% GPS: GetPenStyle
+% Returns the line pattern (from pen style PSt).
+%
+% bool GPS pattern
+% true : returns draw pattern
+% false: returns fill pattern
+/GPS {
+ PSt 1 ge PSt 5 le and % valid pen pattern?
+ {
+ { LArr PSt 1 sub 2 mul get } % draw pattern
+ { LArr PSt 2 mul 1 sub get } ifelse % opaque pattern
+ }
+ { [] } ifelse % out of range => solid line
+} D
+
+% QS: QtStroke
+% draw and fill current path
+%
+% - QS -
+/QS { % stroke command
+ PSt 0 ne % != NO_PEN
+ {
+ gsave
+ LWi SW % set line width
+ true GPS 0 setdash S % draw line pattern
+ OMo PSt 1 ne and % opaque mode and not solid line?
+ {
+ BkCol SC
+ false GPS dup 0 get setdash S % fill in opaque pattern
+ } if
+ grestore
+ } if
+} D
+
+
+
+
+%% The following operations are used to read compressed data from the file
+%% Until now this is only used for image compression
+
+% read 28 bits and leave them on tos
+%
+% - r28 num
+/r28 {
+ % skip past whitespace and read one character
+ { currentfile read pop
+ dup 32 gt { exit } if
+ pop
+ } loop
+ % read three more
+ 3 {
+ currentfile read pop
+ } repeat
+ % make an accumulator
+ 0
+ % for each character, shift the accumulator and add in the character
+ 4 {
+ 7 bitshift exch
+ dup 128 gt { 84 sub } if 42 sub 127 and
+ add
+ } repeat
+} D
+
+/rA 0 d % accumulator
+/rL 0 d % bits left
+
+% takes number of bits, leaves number
+%
+% num rB num
+/rB {
+ rL 0 eq {
+ % if we have nothing, let's get something
+ /rA r28 d
+ /rL 28 d
+ } if
+ dup rL gt {
+ % if we don't have enough, take what we have and get more
+ rA exch rL sub rL exch
+ /rA 0 d /rL 0 d
+ rB exch bitshift add
+ } {
+ % else take some of what we have
+ dup rA 16#fffffff 3 -1 roll bitshift not and exch
+ % ... and update rL and rA
+ dup rL exch sub /rL ED
+ neg rA exch bitshift /rA ED
+ } ifelse
+} D
+
+% uncompresses image data from currentfile until the string on the
+% stack is full; leaves the string there.
+% assumes that nothing could conceivably go wrong, ie. the compressed data has
+% to be in the correct format and the length of the string has to be exactly right
+% to hold the compressed data
+%
+% string uc string
+%
+%%% Warning: if you change the method here, change the table in qpsprinter.cpp:compress()!
+/uc {
+ /rL 0 d
+ 0
+ { % string pos
+ dup 2 index length ge { exit } if
+ 1 rB
+ 1 eq { % compressed
+ 3 rB % string pos bits
+ dup 3 ge {
+ 1 add dup rB % string pos bits extra
+ 1 index 5 ge {
+ 1 index 6 ge {
+ 1 index 7 ge {
+ 1 index 8 ge {
+ 128 add
+ } if
+ 64 add
+ } if
+ 32 add
+ } if
+ 16 add
+ } if
+ 3 add
+ exch pop
+ } if
+ 3 add
+ % string pos length
+ exch 10 rB 1 add
+ % string length pos dist
+ {
+ dup 3 index lt {
+ dup
+ } {
+ 2 index
+ } ifelse % string length pos dist length-this-time
+ 4 index 3 index 3 index sub 2 index getinterval
+ 5 index 4 index 3 -1 roll putinterval
+ dup 4 -1 roll add 3 1 roll
+ 4 -1 roll exch sub
+ dup 0 eq { exit } if
+ 3 1 roll
+ } loop % string pos dist length
+ pop pop
+ } { % uncompressed
+ 3 rB 1 add
+ {
+ 2 copy 8 rB put 1 add
+ } repeat
+ } ifelse
+ } loop
+ pop
+} D
+
+%% image drawing routines
+
+/sl D0 % ### is this needed ?
+
+% defines for QCI
+/QCIgray D0 /QCIcolor D0 /QCIindex D0
+
+% this method prints color images if colorimage is available, otherwise
+% converts the string to a grayscale image and uses the reular postscript image
+% operator for printing.
+% Arguments are the same as for the image operator:
+%
+% width height bits/sample matrix datasrc QCI -
+/QCI {
+ /colorimage where {
+ pop
+ false 3 colorimage
+ }{ % the hard way, based on PD code by John Walker <kelvin@autodesk.com>
+ exec /QCIcolor ED
+ /QCIgray QCIcolor length 3 idiv string d
+ 0 1 QCIcolor length 3 idiv 1 sub
+ { /QCIindex ED
+ /x QCIindex 3 mul d
+ QCIgray QCIindex
+ QCIcolor x get 0.30 mul
+ QCIcolor x 1 add get 0.59 mul
+ QCIcolor x 2 add get 0.11 mul
+ add add cvi
+ put
+ } for
+ QCIgray image
+ } ifelse
+} D
+
+% general image drawing routine, used from the postscript driver
+%
+% Draws images with and without tqmask with 1, 8 and 24(rgb) bits depth.
+%
+% width height matrix image 1|8|24 tqmask|false x y di
+%
+% width and height specify the width/height of the image,
+% matrix a transformation matrix, image a procedure holding the image data
+% (same for tqmask) and x/y an additional translation.
+%
+% ### should move the translation into the matrix!!!
+/di
+{
+ gsave
+ translate
+ 1 index 1 eq { % bitmap
+ false eq { % no tqmask, draw solid background
+ pop
+ true 3 1 roll % width height false matrix image
+ 4 index
+ 4 index
+ false
+ 4 index
+ 4 index
+ imagetqmask
+ BkCol SC
+ imagetqmask
+ } {
+ pop
+ false 3 1 roll % width height false matrix image
+ imagetqmask
+ } ifelse
+ } {
+ dup false ne {
+ % have a tqmask, see if we can use it
+ /languagelevel where {
+ pop
+ languagelevel 3 ge
+ } { false } ifelse
+ } {
+ false
+ } ifelse
+
+ {
+ % languagelevel3, we can use image tqmask and dicts
+
+ % store the image tqmask
+ /ma exch d
+ % select colorspace according to 8|24 bit depth and set the decode array /dc
+ 8 eq {
+ /dc [0 1] d
+ /DeviceGray
+ } {
+ /dc [0 1 0 1 0 1] d
+ /DeviceRGB
+ } ifelse
+ setcolorspace
+ % the image data
+ /im exch d
+ % transformation matrix
+ /mt exch d
+ % width and height
+ /h exch def
+ /w exch def
+ % the image dict
+ /id
+ 7 dict dup begin
+ /ImageType 1 d
+ /Width w d
+ /Height h d
+ /ImageMatrix mt d
+ /DataSource im d
+ /BitsPerComponent 8 d
+ /Decode dc d
+ end d
+ % the tqmask dictionary
+ /md
+ 7 dict dup begin
+ /ImageType 1 d
+ /Width w d
+ /Height h d
+ /ImageMatrix mt d
+ /DataSource ma d
+ /BitsPerComponent 1 d
+ /Decode [0 1] d
+ end d
+ % and the combined image dict
+ 4 dict dup begin
+ /ImageType 3 d
+ /DataDict id d
+ /MaskDict md d
+ /InterleaveType 3 d
+ end
+ image
+ } {
+ pop % no tqmask or can't use it, get rid of it
+ 8 % width height image 8|24 8 matrix
+ 4 1 roll
+ 8 eq { % grayscale
+ image
+ } { %color
+ QCI
+ } ifelse
+ } ifelse
+ } ifelse
+ grestore
+} d
+
+
+
+
+/BF { % brush fill
+ gsave
+ BSt 1 eq % solid brush?
+ {
+ BCol SC
+ WFi { fill } { eofill } ifelse
+ } if
+ BSt 2 ge BSt 8 le and % dense pattern?
+ {
+ BDArr BSt 2 sub get /sc ED
+ % the following line scales the brush color according to the pattern. the higher the pattern the lighter the color.
+ BCol
+ {
+ 1. exch sub sc mul 1. exch sub
+ } forall
+ 3 array astore
+ SC
+ WFi { fill } { eofill } ifelse
+ } if
+ BSt 9 ge BSt 14 le and % brush pattern?
+ {
+ WFi { clip } { eoclip } ifelse
+ defM SM
+ pathbbox % left upper right lower
+ 3 index 3 index translate
+ 4 2 roll % right lower left upper
+ 3 2 roll % right left upper lower
+ exch % left right lower upper
+ sub /h ED
+ sub /w ED
+ OMo {
+ NP
+ 0 0 MT
+ 0 h RL
+ w 0 RL
+ 0 h neg RL
+ CP
+ BkCol SC
+ fill
+ } if
+ BCol SC
+ 0.3 SW
+ NP
+ BSt 9 eq BSt 11 eq or % horiz or cross pattern
+ { 0 4 h
+ { dup 0 exch MT w exch LT } for
+ } if
+ BSt 10 eq BSt 11 eq or % vert or cross pattern
+ { 0 4 w
+ { dup 0 MT h LT } for
+ } if
+ BSt 12 eq BSt 14 eq or % F-diag or diag cross
+ { w h gt
+ { 0 6 w h add
+ { dup 0 MT h sub h LT } for
+ } { 0 6 w h add
+ { dup 0 exch MT w sub w exch LT } for
+ } ifelse
+ } if
+ BSt 13 eq BSt 14 eq or % B-diag or diag cross
+ { w h gt
+ { 0 6 w h add
+ { dup h MT h sub 0 LT } for
+ } { 0 6 w h add
+ { dup w exch MT w sub 0 exch LT } for
+ } ifelse
+ } if
+ S
+ } if
+ BSt 24 eq % CustomPattern
+
+ {
+ } if
+ grestore
+} D
+
+% for arc
+/mat matrix d
+/ang1 D0 /ang2 D0
+/w D0 /h D0
+/x D0 /y D0
+
+/ARC { % Generic ARC function [ X Y W H ang1 ang2 ]
+ /ang2 ED /ang1 ED /h ED /w ED /y ED /x ED
+ mat CM pop
+ x w 2 div add y h 2 div add TR
+ 1 h w div neg scale
+ ang2 0 ge
+ {0 0 w 2 div ang1 ang1 ang2 add arc }
+ {0 0 w 2 div ang1 ang1 ang2 add arcn} ifelse
+ mat SM
+} D
+
+/C D0
+
+/P { % PdcDrawPoint [x y]
+ NP
+ MT
+ 0.5 0.5 rmoveto
+ 0 -1 RL
+ -1 0 RL
+ 0 1 RL
+ CP
+ fill
+} D
+
+/M { % PdcMoveTo [x y]
+ /Cy ED /Cx ED
+} D
+
+/L { % PdcLineTo [x y]
+ NP
+ Cx Cy MT
+ /Cy ED /Cx ED
+ Cx Cy LT
+ QS
+} D
+
+/DL { % PdcDrawLine [x1 y1 x0 y0]
+ NP
+ MT
+ LT
+ QS
+} D
+
+/HL { % PdcDrawLine [x1 y x0]
+ 1 index DL
+} D
+
+/VL { % PdcDrawLine [x y1 y0]
+ 2 index exch DL
+} D
+
+/R { % PdcDrawRect [x y w h]
+ /h ED /w ED /y ED /x ED
+ NP
+ x y MT
+ 0 h RL
+ w 0 RL
+ 0 h neg RL
+ CP
+ BF
+ QS
+} D
+
+/ACR { % add clip rect
+ /h ED /w ED /y ED /x ED
+ x y MT
+ 0 h RL
+ w 0 RL
+ 0 h neg RL
+ CP
+} D
+
+/xr D0 /yr D0
+/rx D0 /ry D0 /rx2 D0 /ry2 D0
+
+/RR { % PdcDrawRoundRect [x y w h xr yr]
+ /yr ED /xr ED /h ED /w ED /y ED /x ED
+ xr 0 le yr 0 le or
+ {x y w h R} % Do rect if one of rounding values is less than 0.
+ {xr 100 ge yr 100 ge or
+ {x y w h E} % Do ellipse if both rounding values are larger than 100
+ {
+ /rx xr w mul 200 div d
+ /ry yr h mul 200 div d
+ /rx2 rx 2 mul d
+ /ry2 ry 2 mul d
+ NP
+ x rx add y MT
+ x y rx2 ry2 180 -90
+ x y h add ry2 sub rx2 ry2 270 -90
+ x w add rx2 sub y h add ry2 sub rx2 ry2 0 -90
+ x w add rx2 sub y rx2 ry2 90 -90
+ ARC ARC ARC ARC
+ CP
+ BF
+ QS
+ } ifelse
+ } ifelse
+} D
+
+/E { % PdcDrawEllipse [x y w h]
+ /h ED /w ED /y ED /x ED
+ mat CM pop
+ x w 2 div add y h 2 div add translate
+ 1 h w div scale
+ NP
+ 0 0 w 2 div 0 360 arc
+ mat SM
+ BF
+ QS
+} D
+
+/A { % PdcDrawArc [x y w h ang1 ang2]
+ 16 div exch 16 div exch
+ NP
+ ARC
+ QS
+} D
+
+/PIE { % PdcDrawPie [x y w h ang1 ang2]
+ /ang2 ED /ang1 ED /h ED /w ED /y ED /x ED
+ NP
+ x w 2 div add y h 2 div add MT
+ x y w h ang1 16 div ang2 16 div ARC
+ CP
+ BF
+ QS
+} D
+
+/CH { % PdcDrawChord [x y w h ang1 ang2]
+ 16 div exch 16 div exch
+ NP
+ ARC
+ CP
+ BF
+ QS
+} D
+
+/BZ { % PdcDrawCubicBezier [4 points]
+ curveto
+ QS
+} D
+
+/CRGB { % Compute RGB [R G B] => R/255 G/255 B/255
+ 255 div 3 1 roll
+ 255 div 3 1 roll
+ 255 div 3 1 roll
+} D
+
+
+/BC { % PdcSetBkColor [R G B]
+ CRGB
+ BkCol astore pop
+} D
+
+/BR { % PdcSetBrush [style R G B]
+ CRGB
+ BCol astore pop
+ /BSt ED
+} D
+
+/WB { % set white solid brush
+ 1 W BR
+} D
+
+/NB { % set nobrush
+ 0 B BR
+} D
+
+/PE { % PdcSetPen [style width R G B Cap Join]
+ setlinejoin setlinecap
+ CRGB
+ PCol astore pop
+ /LWi ED
+ /PSt ED
+ LWi 0 eq { 0.25 /LWi ED } if % ### 3.0 remove this line
+ PCol SC
+} D
+
+/P1 { % PdcSetPen [R G B]
+ 1 0 5 2 roll 0 0 PE
+} D
+
+/ST { % SET TRANSFORM [matrix]
+ defM setmatrix
+ concat
+} D
+
+%% Font handling
+
+% the next three commands are for defining fonts. The first one
+% tries to tqfind the most suitable printer font out of a fontlist.
+% if encoding is false the default one will be used.
+/MF { % newname encoding fontlist
+ % this function tries to tqfind a suitable postscript font.
+ % We try quite hard not to get courier for a
+ % proportional font. The following takes an array of fonts.
+ % The algorithm will take the first font that
+ % gives a match (defined as not resulting in a courier font).
+ % each entry in the table is an array of the form [ /Fontname x-stretch slant ]
+ % x-strtch can be used to stretch/squeeze the font in x direction.
+ % This gives better results when eg substituting helvetica for arial
+ % slant is an optional slant. 0 is non slanted, 0.2 is a typical value for a syntetic oblique.
+ % encoding can be either an encoding vector of false if the default font encoding is requested.
+ true exch true exch % push a dummy on the stack,
+ { % so the loop over the array will leave a font in any case when exiting.
+ exch pop exch pop % (dummy | oldfont) (dummy | fontdict) fontarray
+ dup 0 get dup tqfindfont % get the fontname from the array and load it
+ dup /FontName get % see if the font exists
+ 3 -1 roll eq { % see if fontname and the one provided are equal
+ exit
+ } if
+ } forall
+ exch % font fontarray
+
+ % newname encoding font fontarray defines a postscript font
+ dup
+ 1 get /fxscale exch def % define scale, sland and encoding
+ 2 get /fslant exch def
+ exch /fencoding exch def
+ [ fxscale 0 fslant 1 0 0 ] makefont % transform font accordingly
+ fencoding false eq { % check if we have an encoding and use it if available
+ } {
+ dup maxlength dict begin % copy font
+ {
+ 1 index /FID ne % don't copy FID, as it's not allowed in PS Level 1
+ {def}{pop pop}ifelse
+ } forall
+ /Encoding fencoding def % tqreplace encoding
+ currentdict
+ end
+ } ifelse
+ definefont pop
+} D
+
+% an embedded font. This is used for the base fonts of the composite font used later on.
+/MFEmb { % newname encoding fontname
+ tqfindfont dup length dict
+ begin
+ {
+ 1 index /FID ne
+ {d}{pop pop}ifelse
+ } forall
+ /Encoding ED currentdict
+ end
+ definefont pop
+} D
+
+% DF: define font
+% used to get a scaled version of an already loaded font
+%
+% newname pointsize fontmame DF -
+/DF {
+ tqfindfont
+ % get the fontsize on top of the stack and define font matrix
+ /fs 3 -1 roll d [ fs 0 0 fs -1 mul 0 0 ]
+ makefont
+ d
+} D
+
+/ty 0 d
+/Y {
+ /ty ED
+} D
+
+/Tl { % draw underline/strikeout line: () w x y lw ->Tl-> () w x
+ gsave
+ setlinewidth
+ NP 1 index exch MT
+ 1 index 0 rlineto stroke
+ grestore
+} D
+
+/XYT { % [string [x/y displacement array] width x]
+ ty MT % pops x
+
+ /xyshow where { % interpreter has xyshow
+ pop pop
+ xyshow
+ } { % use ashow
+ exch pop % string cwidth
+ 1 index % string cwidth string
+ dup length 2 div exch % string cwidth length string !have to divide by 2 since we use tqunicode!
+ stringwidth pop % string cwidth length pwidth
+ 3 -1 roll % string length pwidth cwidth
+ exch sub exch div % string extraperchar
+ exch 0 exch % extraperchar 0 string
+ ashow
+ } ifelse
+} D
+
+/AT {
+ ty MT % pops x
+ 1 index % string cwidth string
+ dup length 2 div exch % string cwidth length string !have to divide by 2 since we use tqunicode!
+ stringwidth pop % string cwidth length pwidth
+ 3 -1 roll % string length pwidth cwidth
+ exch sub exch div % string extraperchar
+ exch 0 exch % extraperchar 0 string
+ ashow
+} D
+
+%% start of page
+/QI {
+ /C save d
+ pageinit
+ /Cx 0 d % reset current x position
+ /Cy 0 d % reset current y position
+ /OMo false d
+} D
+
+%% end of page
+/QP { % show page
+ C restore
+ showpage
+} D
+
+% merges one key value pair into the page tqdevice dict
+%
+% key value SPD -
+/SPD {
+ /setpagetqdevice where {
+ 1 dict dup begin 3 1 roll def end
+ setpagetqdevice
+ } { pop pop } ifelse
+} D
+
+/SV { % Save painter state
+ BSt LWi PSt Cx Cy WFi OMo BCol PCol BkCol
+ /nS nS 1 add d
+ gsave
+} D
+
+/RS { % Restore painter state
+ nS 0 gt
+ { grestore
+ /BkCol ED /PCol ED /BCol ED /OMo ED /WFi ED
+ /Cy ED /Cx ED /PSt ED /LWi ED /BSt ED
+ /nS nS 1 sub d
+ } if
+} D
+
+/CLSTART { % clipping start
+ /clipTmp matrix CM d % save current matrix
+ defM SM % Page default matrix
+ NP
+} D
+
+/CLEND { % clipping end
+ clip
+ NP
+ clipTmp SM % restore the current matrix
+} D
+
+/CLO { % clipping off
+ grestore % restore top of page state
+ gsave % save it back again
+ defM SM % set coordsys (defensive progr.)
+} D
+
diff --git a/tqtinterface/qt4/src/kernel/qt_compat.pri b/tqtinterface/qt4/src/kernel/qt_compat.pri
new file mode 100644
index 0000000..b716832
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/qt_compat.pri
@@ -0,0 +1,27 @@
+# Qt compatibility
+
+# scratch pad for internal development
+# hack these for your build like
+# internal {
+# CONFIG += blah
+# }
+
+##########################################################
+
+# mac hac fu
+!embedded:!x11:mac {
+ #never
+ CONFIG -= nas x11 x11sm
+ #CONFIG += sqlcrap
+ sql:sqlcrap {
+ sql-drivers += postgres
+ INCLUDEPATH+=/Users/sam/postgresql-7.0.2/src/include \
+ /Users/sam/postgresql-7.0.2/src/interfaces/libpq
+ LIBS += -L/Users/sam/postgresql-7.0.2/src/interfaces/libpq
+ }
+}
+
+attic {
+ SOURCES += attic/tqttableview.cpp
+ HEADERS += attic/tqttableview.h
+}
diff --git a/tqtinterface/qt4/src/kernel/qt_gfx.pri b/tqtinterface/qt4/src/kernel/qt_gfx.pri
new file mode 100644
index 0000000..0240ff4
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/qt_gfx.pri
@@ -0,0 +1,155 @@
+# Qt graphics
+
+#mng support
+HEADERS += $$KERNEL_H/tqmngio.h
+SOURCES += $$KERNEL_CPP/tqmngio.cpp
+mng {
+ system-mng {
+ win32:LIBS += libmng.lib
+ unix:LIBS += -lmng
+ } else {
+ INCLUDEPATH += 3rdparty/libmng
+ SOURCES += 3rdparty/libmng/libmng_callback_xs.c \
+ 3rdparty/libmng/libmng_chunk_io.c \
+ 3rdparty/libmng/libmng_chunk_prc.c \
+ 3rdparty/libmng/libmng_chunk_xs.c \
+ 3rdparty/libmng/libmng_cms.c \
+ 3rdparty/libmng/libmng_display.c \
+ 3rdparty/libmng/libmng_dither.c \
+ 3rdparty/libmng/libmng_error.c \
+ 3rdparty/libmng/libmng_filter.c \
+ 3rdparty/libmng/libmng_hlapi.c \
+ 3rdparty/libmng/libmng_jpeg.c \
+ 3rdparty/libmng/libmng_object_prc.c \
+ 3rdparty/libmng/libmng_pixels.c \
+ 3rdparty/libmng/libmng_prop_xs.c \
+ 3rdparty/libmng/libmng_read.c \
+ 3rdparty/libmng/libmng_trace.c \
+ 3rdparty/libmng/libmng_write.c \
+ 3rdparty/libmng/libmng_zlib.c
+ }
+ no-jpeg {
+ message(Use of mng requires support for jpeg)
+ CONFIG += jpeg
+ } else:!jpeg {
+ message(Use of mng requires support for jpeg)
+ CONFIG += jpeg
+ }
+}
+else:DEFINES += TQT_NO_IMAGEIO_MNG
+
+#jpeg support..
+HEADERS += $$KERNEL_H/tqjpegio.h
+SOURCES += $$KERNEL_CPP/tqjpegio.cpp
+jpeg {
+ system-jpeg {
+ unix:LIBS += -ljpeg
+ win32:LIBS += libjpeg.lib
+ } else {
+ INCLUDEPATH += 3rdparty/libjpeg
+ SOURCES += 3rdparty/libjpeg/jcapimin.c \
+ 3rdparty/libjpeg/jcapistd.c \
+ 3rdparty/libjpeg/jccoefct.c \
+ 3rdparty/libjpeg/jccolor.c \
+ 3rdparty/libjpeg/jcdctmgr.c \
+ 3rdparty/libjpeg/jchuff.c \
+ 3rdparty/libjpeg/jcinit.c \
+ 3rdparty/libjpeg/jcmainct.c \
+ 3rdparty/libjpeg/jcmarker.c \
+ 3rdparty/libjpeg/jcmaster.c \
+ 3rdparty/libjpeg/jcomapi.c \
+ 3rdparty/libjpeg/jcparam.c \
+ 3rdparty/libjpeg/jcphuff.c \
+ 3rdparty/libjpeg/jcprepct.c \
+ 3rdparty/libjpeg/jcsample.c \
+ 3rdparty/libjpeg/jctrans.c \
+ 3rdparty/libjpeg/jdapimin.c \
+ 3rdparty/libjpeg/jdapistd.c \
+ 3rdparty/libjpeg/jdatadst.c \
+ 3rdparty/libjpeg/jdatasrc.c \
+ 3rdparty/libjpeg/jdcoefct.c \
+ 3rdparty/libjpeg/jdcolor.c \
+ 3rdparty/libjpeg/jddctmgr.c \
+ 3rdparty/libjpeg/jdhuff.c \
+ 3rdparty/libjpeg/jdinput.c \
+ 3rdparty/libjpeg/jdmainct.c \
+ 3rdparty/libjpeg/jdmarker.c \
+ 3rdparty/libjpeg/jdmaster.c \
+ 3rdparty/libjpeg/jdmerge.c \
+ 3rdparty/libjpeg/jdphuff.c \
+ 3rdparty/libjpeg/jdpostct.c \
+ 3rdparty/libjpeg/jdsample.c \
+ 3rdparty/libjpeg/jdtrans.c \
+ 3rdparty/libjpeg/jerror.c \
+ 3rdparty/libjpeg/jfdctflt.c \
+ 3rdparty/libjpeg/jfdctfst.c \
+ 3rdparty/libjpeg/jfdctint.c \
+ 3rdparty/libjpeg/jidctflt.c \
+ 3rdparty/libjpeg/jidctfst.c \
+ 3rdparty/libjpeg/jidctint.c \
+ 3rdparty/libjpeg/jidctred.c \
+ 3rdparty/libjpeg/jmemmgr.c \
+ 3rdparty/libjpeg/jquant1.c \
+ 3rdparty/libjpeg/jquant2.c \
+ 3rdparty/libjpeg/jutils.c \
+ 3rdparty/libjpeg/jmemnobs.c
+ }
+}
+else:DEFINES += TQT_NO_IMAGEIO_JPEG
+
+#png support
+HEADERS+=$$KERNEL_H/tqpngio.h
+SOURCES+=$$KERNEL_CPP/tqpngio.cpp
+png {
+ system-png {
+ unix:LIBS += -lpng
+ win32:LIBS += libpng.lib
+ } else {
+ INCLUDEPATH += 3rdparty/libpng
+ SOURCES += 3rdparty/libpng/png.c \
+ 3rdparty/libpng/pngerror.c \
+ 3rdparty/libpng/pngget.c \
+ 3rdparty/libpng/pngmem.c \
+ 3rdparty/libpng/pngpread.c \
+ 3rdparty/libpng/pngread.c \
+ 3rdparty/libpng/pngrio.c \
+ 3rdparty/libpng/pngrtran.c \
+ 3rdparty/libpng/pngrutil.c \
+ 3rdparty/libpng/pngset.c \
+ 3rdparty/libpng/pngtrans.c \
+ 3rdparty/libpng/pngwio.c \
+ 3rdparty/libpng/pngwrite.c \
+ 3rdparty/libpng/pngwtran.c \
+ 3rdparty/libpng/pngwutil.c
+ }
+}
+else:DEFINES += TQT_NO_IMAGEIO_PNG
+
+#zlib support
+zlib {
+ INCLUDEPATH += 3rdparty/zlib
+ SOURCES += 3rdparty/zlib/adler32.c \
+ 3rdparty/zlib/compress.c \
+ 3rdparty/zlib/crc32.c \
+ 3rdparty/zlib/deflate.c \
+ 3rdparty/zlib/gzio.c \
+ 3rdparty/zlib/inffast.c \
+ 3rdparty/zlib/inflate.c \
+ 3rdparty/zlib/inftrees.c \
+ 3rdparty/zlib/trees.c \
+ 3rdparty/zlib/uncompr.c \
+ 3rdparty/zlib/zutil.c
+}
+!no-zlib:!zlib {
+ unix:LIBS += -lz
+ win32:LIBS += libz.lib
+}
+
+unix:xftfreetype {
+ INCLUDEPATH += 3rdparty/opentype
+ SOURCES += 3rdparty/opentype/ftxopentype.c
+}
+
+#use Qt gif
+gif:DEFINES += TQT_BUILTIN_GIF_READER=1
+
diff --git a/tqtinterface/qt4/src/kernel/qt_kernel.pri b/tqtinterface/qt4/src/kernel/qt_kernel.pri
new file mode 100644
index 0000000..aa76de0
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/qt_kernel.pri
@@ -0,0 +1,261 @@
+# Qt kernel module
+
+kernel {
+ KERNEL_P = kernel
+ HEADERS += $$KERNEL_H/tqabstractlayout.h \
+ $$KERNEL_H/tqaccel.h \
+ $$KERNEL_P/tqucomextra_p.h \
+ $$KERNEL_H/tqapplication.h \
+ $$KERNEL_P/tqapplication_p.h \
+ $$KERNEL_H/tqasyncimageio.h \
+ $$KERNEL_H/tqasyncio.h \
+ $$KERNEL_H/tqbitmap.h \
+ $$KERNEL_H/tqbrush.h \
+ $$KERNEL_H/tqclipboard.h \
+ $$KERNEL_H/tqcolor.h \
+ $$KERNEL_P/tqcolor_p.h \
+ $$KERNEL_H/tqconnection.h \
+ $$KERNEL_H/tqcursor.h \
+ $$KERNEL_H/tqdesktopwidget.h \
+ $$KERNEL_H/tqdragobject.h \
+ $$KERNEL_H/tqdrawutil.h \
+ $$KERNEL_H/tqdropsite.h \
+ $$KERNEL_H/tqevent.h \
+ $$KERNEL_H/tqeventloop.h\
+ $$KERNEL_P/tqeventloop_p.h \
+ $$KERNEL_H/tqfocusdata.h \
+ $$KERNEL_H/tqfont.h \
+ $$KERNEL_P/tqfontdata_p.h \
+ $$KERNEL_H/tqfontinfo.h \
+ $$KERNEL_H/tqfontmetrics.h \
+ $$KERNEL_H/tqguardedptr.h \
+ $$KERNEL_H/tqgif.h \
+ $$KERNEL_H/tqiconset.h \
+ $$KERNEL_H/tqimage.h \
+ $$KERNEL_P/tqimageformatinterface_p.h \
+ $$KERNEL_H/tqimageformatplugin.h \
+ $$KERNEL_P/tqinputcontext_p.h \
+ $$KERNEL_H/tqkeycode.h \
+ $$KERNEL_H/tqkeysequence.h \
+ $$KERNEL_H/tqlayout.h \
+ $$KERNEL_P/tqlayoutengine_p.h \
+ $$KERNEL_H/tqtranslator.h \
+ $$KERNEL_H/tqmetaobject.h \
+ $$KERNEL_H/tqmime.h \
+ $$KERNEL_H/tqmovie.h \
+ $$KERNEL_H/tqnamespace.h \
+ $$KERNEL_H/tqnetworkprotocol.h \
+ $$KERNEL_H/tqobject.h \
+ $$KERNEL_H/tqobjectcleanuphandler.h \
+ $$KERNEL_H/tqobjectdefs.h \
+ $$KERNEL_H/tqobjectdict.h \
+ $$KERNEL_H/tqobjectlist.h \
+ $$KERNEL_H/tqpaintdevice.h \
+ $$KERNEL_H/tqpaintdevicedefs.h \
+ $$KERNEL_H/tqpainter.h \
+ $$KERNEL_P/tqpainter_p.h \
+ $$KERNEL_H/tqpalette.h \
+ $$KERNEL_H/tqpaintdevicemetrics.h \
+ $$KERNEL_H/tqpen.h \
+ $$KERNEL_H/tqpicture.h \
+ $$KERNEL_H/tqpixmap.h \
+ $$KERNEL_H/tqpixmapcache.h \
+ $$KERNEL_H/tqpointarray.h \
+ $$KERNEL_H/tqpoint.h \
+ $$KERNEL_H/tqpolygonscanner.h \
+ $$KERNEL_H/tqprinter.h \
+ $$KERNEL_H/tqprocess.h \
+ $$KERNEL_H/tqrect.h \
+ $$KERNEL_H/tqregion.h \
+ $$KERNEL_H/tqsessionmanager.h \
+ $$KERNEL_H/tqsignal.h \
+ $$KERNEL_H/tqsignalmapper.h \
+ $$KERNEL_H/tqsignalslotimp.h \
+ $$KERNEL_H/tqsize.h \
+ $$KERNEL_H/tqsizegrip.h \
+ $$KERNEL_H/tqsizepolicy.h \
+ $$KERNEL_H/tqsocketnotifier.h \
+ $$KERNEL_H/tqsound.h \
+ $$KERNEL_H/tqstyle.h \
+ $$KERNEL_H/tqstylesheet.h \
+ $$KERNEL_H/tqthread.h \
+ $$KERNEL_H/tqtimer.h \
+ $$KERNEL_H/tqurl.h \
+ $$KERNEL_H/tqlocalfs.h \
+ $$KERNEL_H/tqurloperator.h \
+ $$KERNEL_H/tqurlinfo.h \
+ $$KERNEL_H/tqwidget.h \
+ $$KERNEL_H/tqwidgetintdict.h \
+ $$KERNEL_H/tqwidgetlist.h \
+ $$KERNEL_H/tqwindowdefs.h \
+ $$KERNEL_H/tqwmatrix.h \
+ $$KERNEL_H/tqvariant.h \
+ $$KERNEL_P/tqrichtext_p.h \
+ $$KERNEL_P/tqinternal_p.h \
+ $$KERNEL_H/tqgplugin.h \
+ $$KERNEL_H/tqsimplerichtext.h \
+ $$KERNEL_CPP/tqscriptengine_p.h \
+ $$KERNEL_CPP/tqtextengine_p.h \
+ $$KERNEL_CPP/tqfontengine_p.h \
+ $$KERNEL_CPP/tqtextlayout_p.h
+
+ win32:SOURCES += $$KERNEL_CPP/tqapplication_win.cpp \
+ $$KERNEL_CPP/tqclipboard_win.cpp \
+ $$KERNEL_CPP/tqcolor_win.cpp \
+ $$KERNEL_CPP/tqcursor_win.cpp \
+ $$KERNEL_CPP/tqdesktopwidget_win.cpp \
+ $$KERNEL_CPP/tqdnd_win.cpp \
+ $$KERNEL_CPP/tqeventloop_win.cpp \
+ $$KERNEL_CPP/tqfont_win.cpp \
+ $$KERNEL_CPP/tqinputcontext_win.cpp \
+ $$KERNEL_CPP/tqmime_win.cpp \
+ $$KERNEL_CPP/tqpixmap_win.cpp \
+ $$KERNEL_CPP/tqprinter_win.cpp \
+ $$KERNEL_CPP/tqprocess_win.cpp \
+ $$KERNEL_CPP/tqpaintdevice_win.cpp \
+ $$KERNEL_CPP/tqpainter_win.cpp \
+ $$KERNEL_CPP/tqregion_win.cpp \
+ $$KERNEL_CPP/tqsound_win.cpp \
+ $$KERNEL_CPP/tqthread_win.cpp \
+ $$KERNEL_CPP/tqwidget_win.cpp \
+ $$KERNEL_CPP/tqole_win.c \
+ $$KERNEL_CPP/tqfontengine_win.cpp
+
+ unix:x11 {
+ SOURCES += $$KERNEL_CPP/tqapplication_x11.cpp \
+ $$KERNEL_CPP/tqclipboard_x11.cpp \
+ $$KERNEL_CPP/tqcolor_x11.cpp \
+ $$KERNEL_CPP/tqcursor_x11.cpp \
+ $$KERNEL_CPP/tqdnd_x11.cpp \
+ $$KERNEL_CPP/tqdesktopwidget_x11.cpp \
+ $$KERNEL_CPP/tqeventloop_x11.cpp \
+ $$KERNEL_CPP/tqfont_x11.cpp \
+ $$KERNEL_CPP/tqinputcontext_x11.cpp \
+ $$KERNEL_CPP/tqmotifdnd_x11.cpp \
+ $$KERNEL_CPP/tqpixmap_x11.cpp \
+ $$KERNEL_CPP/tqpaintdevice_x11.cpp \
+ $$KERNEL_CPP/tqpainter_x11.cpp \
+ $$KERNEL_CPP/tqregion_x11.cpp \
+ $$KERNEL_CPP/tqsound_x11.cpp \
+ $$KERNEL_CPP/tqwidget_x11.cpp \
+ $$KERNEL_CPP/tqwidgetcreate_x11.cpp \
+ $$KERNEL_CPP/tqfontengine_x11.cpp
+ }
+
+ !x11:mac {
+ exists(qsound_mac.cpp):SOURCES += $$KERNEL_CPP/tqsound_mac.cpp
+ else:SOURCES += $$KERNEL_CPP/tqsound_qws.cpp
+ }
+ !embedded:!x11:mac {
+ SOURCES += $$KERNEL_CPP/tqapplication_mac.cpp \
+ $$KERNEL_CPP/tqclipboard_mac.cpp \
+ $$KERNEL_CPP/tqcolor_mac.cpp \
+ $$KERNEL_CPP/tqcursor_mac.cpp \
+ $$KERNEL_CPP/tqmime_mac.cpp \
+ $$KERNEL_CPP/tqdnd_mac.cpp \
+ $$KERNEL_CPP/tqdesktopwidget_mac.cpp \
+ $$KERNEL_CPP/tqpixmap_mac.cpp \
+ $$KERNEL_CPP/tqprinter_mac.cpp \
+ $$KERNEL_CPP/tqpaintdevice_mac.cpp \
+ $$KERNEL_CPP/tqpainter_mac.cpp \
+ $$KERNEL_CPP/tqregion_mac.cpp \
+ $$KERNEL_CPP/tqwidget_mac.cpp \
+ $$KERNEL_CPP/tqeventloop_mac.cpp \
+ $$KERNEL_CPP/tqfont_mac.cpp \
+ $$KERNEL_CPP/tqfontengine_mac.cpp
+ DEFINES += QMAC_ONE_PIXEL_LOCK
+ } else:unix {
+ SOURCES += $$KERNEL_CPP/tqprinter_unix.cpp \
+ $$KERNEL_CPP/tqpsprinter.cpp \
+ $$KERNEL_CPP/tqeventloop_unix.cpp
+ }
+ unix:SOURCES += $$KERNEL_CPP/tqprocess_unix.cpp \
+ $$KERNEL_CPP/tqthread_unix.cpp
+
+ SOURCES += $$KERNEL_CPP/tqabstractlayout.cpp \
+ $$KERNEL_CPP/tqucomextra.cpp \
+ $$KERNEL_CPP/tqaccel.cpp \
+ $$KERNEL_CPP/tqapplication.cpp \
+ $$KERNEL_CPP/tqasyncimageio.cpp \
+ $$KERNEL_CPP/tqasyncio.cpp \
+ $$KERNEL_CPP/tqbitmap.cpp \
+ $$KERNEL_CPP/tqclipboard.cpp \
+ $$KERNEL_CPP/tqcolor.cpp \
+ $$KERNEL_CPP/tqcolor_p.cpp \
+ $$KERNEL_CPP/tqconnection.cpp \
+ $$KERNEL_CPP/tqcursor.cpp \
+ $$KERNEL_CPP/tqdragobject.cpp \
+ $$KERNEL_CPP/tqdrawutil.cpp \
+ $$KERNEL_CPP/tqdropsite.cpp \
+ $$KERNEL_CPP/tqevent.cpp \
+ $$KERNEL_CPP/tqeventloop.cpp \
+ $$KERNEL_CPP/tqfocusdata.cpp \
+ $$KERNEL_CPP/tqfont.cpp \
+ $$KERNEL_CPP/tqfontdatabase.cpp \
+ $$KERNEL_CPP/tqguardedptr.cpp \
+ $$KERNEL_CPP/tqiconset.cpp \
+ $$KERNEL_CPP/tqimage.cpp \
+ $$KERNEL_CPP/tqimageformatplugin.cpp \
+ $$KERNEL_CPP/tqkeysequence.cpp \
+ $$KERNEL_CPP/tqlayout.cpp \
+ $$KERNEL_CPP/tqlayoutengine.cpp \
+ $$KERNEL_CPP/tqtranslator.cpp \
+ $$KERNEL_CPP/tqmetaobject.cpp \
+ $$KERNEL_CPP/tqmime.cpp \
+ $$KERNEL_CPP/tqmovie.cpp \
+ $$KERNEL_CPP/tqnetworkprotocol.cpp \
+ $$KERNEL_CPP/tqobject.cpp \
+ $$KERNEL_CPP/tqobjectcleanuphandler.cpp \
+ $$KERNEL_CPP/tqpainter.cpp \
+ $$KERNEL_CPP/tqpalette.cpp \
+ $$KERNEL_CPP/tqpaintdevicemetrics.cpp \
+ $$KERNEL_CPP/tqpicture.cpp \
+ $$KERNEL_CPP/tqpixmap.cpp \
+ $$KERNEL_CPP/tqpixmapcache.cpp \
+ $$KERNEL_CPP/tqpointarray.cpp \
+ $$KERNEL_CPP/tqpoint.cpp \
+ $$KERNEL_CPP/tqpolygonscanner.cpp \
+ $$KERNEL_CPP/tqprinter.cpp \
+ $$KERNEL_CPP/tqprocess.cpp \
+ $$KERNEL_CPP/tqrect.cpp \
+ $$KERNEL_CPP/tqregion.cpp \
+ $$KERNEL_CPP/tqsignal.cpp \
+ $$KERNEL_CPP/tqsignalmapper.cpp \
+ $$KERNEL_CPP/tqsize.cpp \
+ $$KERNEL_CPP/tqsizegrip.cpp \
+ $$KERNEL_CPP/tqstyle.cpp \
+ $$KERNEL_CPP/tqsocketnotifier.cpp \
+ $$KERNEL_CPP/tqsound.cpp \
+ $$KERNEL_CPP/tqstylesheet.cpp \
+ $$KERNEL_CPP/tqthread.cpp \
+ $$KERNEL_CPP/tqtimer.cpp \
+ $$KERNEL_CPP/tqurl.cpp \
+ $$KERNEL_CPP/tqlocalfs.cpp \
+ $$KERNEL_CPP/tqurloperator.cpp \
+ $$KERNEL_CPP/tqurlinfo.cpp \
+ $$KERNEL_CPP/tqwidget.cpp \
+ $$KERNEL_CPP/tqwmatrix.cpp \
+ $$KERNEL_CPP/tqvariant.cpp \
+ $$KERNEL_CPP/tqrichtext.cpp \
+ $$KERNEL_CPP/tqinternal.cpp \
+ $$KERNEL_CPP/tqrichtext_p.cpp \
+ $$KERNEL_CPP/tqgplugin.cpp \
+ $$KERNEL_CPP/tqsimplerichtext.cpp \
+ $$KERNEL_CPP/tqscriptengine.cpp \
+ $$KERNEL_CPP/tqtextlayout.cpp \
+ $$KERNEL_CPP/tqtextengine.cpp
+
+ unix:HEADERS += $$KERNEL_P/tqpsprinter_p.h \
+ $$KERNEL_H/tqfontdatabase.h
+
+ embedded:SOURCES += $$KERNEL_CPP/tqsharedmemory_p.cpp \
+ $$KERNEL_CPP/tqfontengine_qws.cpp
+
+ accessibility {
+ HEADERS += $$KERNEL_H/tqaccessible.h
+ SOURCES += $$KERNEL_CPP/tqaccessible.cpp
+
+ !embedded:!x11:mac:SOURCES += $$KERNEL_CPP/tqaccessible_mac.cpp
+ else:win32:SOURCES += $$KERNEL_CPP/tqaccessible_win.cpp
+ }
+}
diff --git a/tqtinterface/qt4/src/kernel/qt_x11.pri b/tqtinterface/qt4/src/kernel/qt_x11.pri
new file mode 100644
index 0000000..d437261
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/qt_x11.pri
@@ -0,0 +1,20 @@
+unix {
+ !xinerama:DEFINES += TQT_NO_XINERAMA
+ !xtqshape:DEFINES += TQT_NO_SHAPE
+ !xcursor:DEFINES += TQT_NO_XCURSOR
+ !xrandr:DEFINES += TQT_NO_XRANDR
+ !xrender:DEFINES += TQT_NO_XRENDER
+ !xftfreetype:DEFINES += TQT_NO_XFTFREETYPE
+ !xkb:DEFINES += TQT_NO_XKB
+ xft2header:DEFINES+=TQT_USE_XFT2_HEADER
+
+ SOURCES += $$KERNEL_CPP/tqtaddons_x11.cpp
+ PRECOMPILED_HEADER = kernel/tqt_pch.h
+}
+
+nas {
+ DEFINES += TQT_NAS_SUPPORT
+ LIBS += -laudio -lXt
+}
+
+!x11sm:DEFINES += TQT_NO_SM_SUPPORT
diff --git a/tqtinterface/qt4/src/kernel/tq1xcompatibility.h b/tqtinterface/qt4/src/kernel/tq1xcompatibility.h
new file mode 100644
index 0000000..dcf3595
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tq1xcompatibility.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Various macros etc. to ease porting from TQt 1.x to 2.0. THIS FILE
+** WILL CHANGE OR DISAPPEAR IN THE NEXT VERSION OF TQt.
+**
+** Created : 980824
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef Q1XCOMPATIBILITY_H
+#define Q1XCOMPATIBILITY_H
+
+#error "Compatibility with TQt 1.x is no longer guaranteed. Please"
+#error "update your code (for example using qt20fix script). We"
+#error "apologize for any inconvenience."
+
+#endif // Q1XCOMPATIBILITY_H
diff --git a/tqtinterface/qt4/src/kernel/tqabstractlayout.cpp b/tqtinterface/qt4/src/kernel/tqabstractlayout.cpp
new file mode 100644
index 0000000..4c15ee2
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqabstractlayout.cpp
@@ -0,0 +1,2108 @@
+/****************************************************************************
+**
+** Implementation of the abstract tqlayout base class
+**
+** Created : 960416
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqlayout.h"
+
+#ifndef TQT_NO_LAYOUT
+#include "tqapplication.h"
+#include "tqlayoutengine_p.h"
+#include "tqmenubar.h"
+#include "tqtoolbar.h"
+
+#ifdef USE_QT4
+
+/*!
+ Sets the value returned by supportsMargin(). If \a b is TRUE,
+ margin() handling is implemented by the subclass. If \a b is
+ FALSE (the default), TQLayout will add margin() around top-level
+ layouts.
+
+ If \a b is TRUE, margin handling needs to be implemented in
+ setGeometry(), tqmaximumSize(), tqminimumSize(), tqsizeHint() and
+ heightForWidth().
+
+ \sa supportsMargin()
+*/
+void TQLayout::setSupportsMargin( bool b )
+{
+ printf("[FIXME] void TQLayout::setSupportsMargin( bool b ) unimplemented!\n\r");
+}
+
+/*!
+ Removes and deletes all items in this tqlayout.
+*/
+void TQLayout::deleteAllItems()
+{
+ TQLayoutIterator it = iterator();
+ TQLayoutItem *l;
+ while ( (l = it.takeCurrent()) )
+ delete l;
+}
+
+#else // USE_QT4
+
+static int menuBarHeightForWidth( TQMenuBar *menubar, int w )
+{
+#ifndef TQT_NO_MENUBAR
+ if ( menubar && !menubar->isHidden() && !menubar->isTopLevel() )
+ return menubar->heightForWidth( TQMAX(w, menubar->minimumWidth()) );
+ else
+#endif
+ return 0;
+}
+
+#endif // USE_QT4
+
+/*!
+ \class TQLayoutItem
+ \ingroup appearance
+ \ingroup geomanagement
+ \brief The TQLayoutItem class provides an abstract item that a
+ TQLayout manipulates.
+
+ This is used by custom layouts.
+
+ Pure virtual functions are provided to return information about
+ the tqlayout, including, tqsizeHint(), tqminimumSize(), tqmaximumSize()
+ and expandingDirections().
+
+ The tqlayout's tqgeometry can be set and retrieved with setGeometry()
+ and tqgeometry(), and its tqalignment with tqsetAlignment() and
+ tqalignment().
+
+ isEmpty() returns whether the tqlayout is empty. iterator() returns
+ an iterator for the tqlayout's tqchildren. If the concrete item is a
+ TQWidget, it can be retrieved using widget(). Similarly for
+ tqlayout() and tqspacerItem().
+
+ \sa TQLayout
+*/
+
+/*!
+ \class TQSpacerItem
+ \ingroup appearance
+ \ingroup geomanagement
+ \brief The TQSpacerItem class provides blank space in a tqlayout.
+
+ This class is used by custom layouts.
+
+ \sa TQLayout TQLayout::tqspacerItem()
+*/
+
+/*!
+ \class TQWidgetItem
+ \ingroup appearance
+ \ingroup geomanagement
+ \brief The TQWidgetItem class is a tqlayout item that represents a widget.
+
+ This is used by custom layouts.
+
+ \sa TQLayout TQLayout::widget()
+*/
+
+/*!
+ \fn TQLayoutItem::TQLayoutItem( int tqalignment )
+
+ Constructs a tqlayout item with an \a tqalignment that is a bitwise OR
+ of the \l{TQt::AlignmentFlags}. Not all subclasses support
+ tqalignment.
+*/
+
+/*!
+ \fn int TQLayoutItem::tqalignment() const
+
+ Returns the tqalignment of this item.
+*/
+
+/*!
+ Sets the tqalignment of this item to \a a, which is a bitwise OR of
+ the \l{TQt::AlignmentFlags}. Not all subclasses support tqalignment.
+*/
+// void TQLayoutItem::tqsetAlignment( int a )
+// {
+// align = (Qt::AlignmentFlag)a;
+// }
+
+/*!
+ \fn TQSize TQLayoutItem::tqmaximumSize() const
+
+ Implemented in subclasses to return the maximum size of this item.
+*/
+
+/*!
+ \fn TQSize TQLayoutItem::tqminimumSize() const
+
+ Implemented in subclasses to return the minimum size of this item.
+*/
+
+/*!
+ \fn TQSize TQLayoutItem::tqsizeHint() const
+
+ Implemented in subclasses to return the preferred size of this item.
+*/
+
+/*!
+ \fn TQ_SPExpandData TQLayoutItem::expandingDirections() const
+
+ Implemented in subclasses to return the direction(s) this item
+ "wants" to expand in (if any).
+*/
+
+/*!
+ \fn void TQLayoutItem::setGeometry( const TQRect &r )
+
+ Implemented in subclasses to set this item's tqgeometry to \a r.
+*/
+
+/*!
+ \fn TQRect TQLayoutItem::tqgeometry() const
+
+ Returns the rectangle covered by this tqlayout item.
+*/
+
+/*!
+ \fn virtual bool TQLayoutItem::isEmpty() const
+
+ Implemented in subclasses to return whether this item is empty,
+ i.e. whether it tqcontains any widgets.
+*/
+
+/*!
+ \fn TQSpacerItem::TQSpacerItem( int w, int h, TQSizePolicy::SizeType hData, TQSizePolicy::SizeType vData )
+
+ Constructs a spacer item with preferred width \a w, preferred
+ height \a h, horizontal size policy \a hData and vertical size
+ policy \a vData.
+
+ The default values provide a gap that is able to stretch if
+ nothing else wants the space.
+*/
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ Changes this spacer item to have preferred width \a w, preferred
+ height \a h, horizontal size policy \a hData and vertical size
+ policy \a vData.
+
+ The default values provide a gap that is able to stretch if
+ nothing else wants the space.
+*/
+void TQSpacerItem::changeSize( int w, int h, TQSizePolicy::SizeType hData,
+ TQSizePolicy::SizeType vData )
+{
+ width = w;
+ height = h;
+ sizeP = TQSizePolicy( hData, vData );
+}
+
+#endif // USE_QT4
+
+/*!
+ \fn TQWidgetItem::TQWidgetItem (TQWidget * w)
+
+ Creates an item containing widget \a w.
+*/
+
+/*!
+ Destroys the TQLayoutItem.
+*/
+// TQLayoutItem::~TQLayoutItem()
+// {
+// }
+
+/*!
+ Invalidates any cached information in this tqlayout item.
+*/
+// void TQLayoutItem::tqinvalidate()
+// {
+// }
+
+/*!
+ If this item is a TQLayout, it is returned as a TQLayout; otherwise
+ 0 is returned. This function provides type-safe casting.
+*/
+// TQLayout * TQLayoutItem::tqlayout()
+// {
+// return 0;
+// }
+
+/*!
+ If this item is a TQSpacerItem, it is returned as a TQSpacerItem;
+ otherwise 0 is returned. This function provides type-safe casting.
+*/
+// TQSpacerItem * TQLayoutItem::tqspacerItem()
+// {
+// return 0;
+// }
+
+/*!
+ \reimp
+*/
+// TQLayout * TQLayout::tqlayout()
+// {
+// return this;
+// }
+
+/*!
+ \reimp
+*/
+TQSpacerItem * TQSpacerItem::tqspacerItem()
+{
+ return this;
+}
+
+/*!
+ If this item is a TQWidget, it is returned as a TQWidget; otherwise
+ 0 is returned. This function provides type-safe casting.
+*/
+// TQWidget * TQLayoutItem::widget()
+// {
+// return 0;
+// }
+
+/*!
+ Returns the widget managed by this item.
+*/
+TQWidget * TQWidgetItem::widget()
+{
+ return wid;
+}
+
+/*!
+ Returns TRUE if this tqlayout's preferred height depends on its
+ width; otherwise returns FALSE. The default implementation returns
+ FALSE.
+
+ Reimplement this function in tqlayout managers that support height
+ for width.
+
+ \sa heightForWidth(), TQWidget::heightForWidth()
+*/
+// bool TQLayoutItem::hasHeightForWidth() const
+// {
+// return FALSE;
+// }
+
+/*!
+ Returns an iterator over this item's TQLayoutItem tqchildren. The
+ default implementation returns an empty iterator.
+
+ Reimplement this function in subclasses that can have tqchildren.
+*/
+// TQLayoutIterator TQLayoutItem::iterator()
+// {
+// return TQLayoutIterator( 0 );
+// }
+
+/*!
+ Returns the preferred height for this tqlayout item, given the width
+ \a w.
+
+ The default implementation returns -1, indicating that the
+ preferred height is independent of the width of the item. Using
+ the function hasHeightForWidth() will typically be much faster
+ than calling this function and testing for -1.
+
+ Reimplement this function in tqlayout managers that support height
+ for width. A typical implementation will look like this:
+ \code
+ int MyLayout::heightForWidth( int w ) const
+ {
+ if ( cache_dirty || cached_width != w ) {
+ // not all C++ compilers support "mutable"
+ MyLayout *that = (MyLayout*)this;
+ int h = calculateHeightForWidth( w );
+ that->cached_hfw = h;
+ return h;
+ }
+ return cached_hfw;
+ }
+ \endcode
+
+ Caching is strongly recommended; without it tqlayout will take
+ exponential time.
+
+ \sa hasHeightForWidth()
+*/
+// int TQLayoutItem::heightForWidth( int /* w */ ) const
+// {
+// return -1;
+// }
+
+#ifdef USE_QT4
+
+/*!
+ Stores the spacer item's rect \a r so that it can be returned by
+ tqgeometry().
+*/
+void TQSpacerItem::setGeometry( const TQRect &r )
+{
+ QSpacerItem::setGeometry(r);
+}
+
+#else // USE_QT4
+
+/*!
+ Stores the spacer item's rect \a r so that it can be returned by
+ tqgeometry().
+*/
+void TQSpacerItem::setGeometry( const TQRect &r )
+{
+ rect = r;
+}
+
+#endif // USE_QT4
+
+/*!
+ Sets the tqgeometry of this item's widget to be contained within
+ rect \a r, taking tqalignment and maximum size into account.
+*/
+void TQWidgetItem::setGeometry( const TQRect &r )
+{
+ TQSize s = r.size().boundedTo( tqSmartMaxSize( this ) );
+ int x = r.x();
+ int y = r.y();
+ if ( align & (TQt::AlignHorizontal_Mask | TQt::AlignVertical_Mask) ) {
+ TQSize pref = wid->tqsizeHint().expandedTo( wid->tqminimumSize() ); //###
+ if ( align & TQt::AlignHorizontal_Mask )
+ s.setWidth( TQMIN( s.width(), pref.width() ) );
+ if ( align & TQt::AlignVertical_Mask ) {
+ if ( hasHeightForWidth() )
+ s.setHeight( TQMIN( s.height(), heightForWidth(s.width()) ) );
+ else
+ s.setHeight( TQMIN( s.height(), pref.height() ) );
+ }
+ }
+ int alignHoriz = TQApplication::horizontalAlignment( align );
+ if ( alignHoriz & TQt::AlignRight )
+ x = x + ( r.width() - s.width() );
+ else if ( !(alignHoriz & TQt::AlignLeft) )
+ x = x + ( r.width() - s.width() ) / 2;
+
+ if ( align & TQt::AlignBottom )
+ y = y + ( r.height() - s.height() );
+ else if ( !(align & TQt::AlignTop) )
+ y = y + ( r.height() - s.height() ) / 2;
+
+ if ( !isEmpty() ) {
+ wid->setGeometry( x, y, s.width(), s.height() );
+ }
+}
+
+#ifdef USE_QT4
+
+/*!
+ \reimp
+*/
+TQRect TQSpacerItem::tqgeometry() const
+{
+ return QSpacerItem::geometry();
+}
+
+#else // USE_QT4
+
+/*!
+ \reimp
+*/
+TQRect TQSpacerItem::tqgeometry() const
+{
+ return rect;
+}
+
+#endif // USE_QT4
+
+/*!
+ \reimp
+*/
+TQRect TQWidgetItem::tqgeometry() const
+{
+ return wid->tqgeometry();
+}
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \reimp
+*/
+TQRect TQLayout::tqgeometry() const
+{
+ return rect;
+}
+
+#endif // USE_QT4
+
+/*!
+ \reimp
+*/
+bool TQWidgetItem::hasHeightForWidth() const
+{
+ if ( isEmpty() )
+ return FALSE;
+ if ( wid->tqlayout() )
+ return wid->tqlayout()->hasHeightForWidth();
+ return wid->sizePolicy().hasHeightForWidth();
+}
+
+/*!
+ \reimp
+*/
+int TQWidgetItem::heightForWidth( int w ) const
+{
+ if ( isEmpty() )
+ return -1;
+ int hfw;
+ if ( wid->tqlayout() )
+ hfw = wid->tqlayout()->totalHeightForWidth( w );
+ else
+ hfw = wid->heightForWidth( w );
+
+ if ( hfw > wid->maximumHeight() )
+ hfw = wid->maximumHeight();
+ if ( hfw < wid->minimumHeight() )
+ hfw = wid->minimumHeight();
+ if ( hfw < 1 )
+ hfw = 1;
+ return hfw;
+}
+
+#ifdef USE_QT4
+
+/*!
+ Returns the direction in which this spacer item will expand.
+
+ \sa TQ_SPExpandData
+*/
+TQ_SPExpandData TQSpacerItem::expandingDirections() const
+{
+ return QSpacerItem::expandingDirections();
+}
+
+#else // USE_QT4
+
+/*!
+ Returns the direction in which this spacer item will expand.
+
+ \sa TQ_SPExpandData
+*/
+TQ_SPExpandData TQSpacerItem::expandingDirections() const
+{
+ return sizeP.expandingDirections();
+}
+
+#endif
+
+/*!
+ Returns whether this item's widget can make use of more space than
+ tqsizeHint(). A value of \c Vertical or \c Horizontal means that it wants
+ to grow in only one dimension, whereas \c BothDirections means that
+ it wants to grow in both dimensions and \c NoDirection means that
+ it doesn't want to grow at all.
+*/
+TQ_SPExpandData TQWidgetItem::expandingDirections() const
+{
+ if ( isEmpty() )
+ return (TQ_SPExpandData)TQSizePolicy::NoDirection;
+
+ int e = TQT_TQSIZEPOLICY_OBJECT(wid->sizePolicy()).expandingDirections();
+ /*
+ If the tqlayout is expanding, we make the widget expanding, even if
+ its own size policy isn't expanding. This behavior should be
+ reconsidered in TQt 4.0. (###)
+ */
+#ifdef USE_QT4
+ if ( wid->layout() ) {
+ if ( TQT_TQSIZEPOLICY_OBJECT(wid->sizePolicy()).mayGrowHorizontally()
+ && (wid->layout()->expandingDirections() & TQSizePolicy::Horizontally) )
+ e |= TQSizePolicy::Horizontally;
+ if ( TQT_TQSIZEPOLICY_OBJECT(wid->sizePolicy()).mayGrowVertically()
+ && (wid->layout()->expandingDirections() & TQSizePolicy::Vertically) )
+ e |= TQSizePolicy::Vertically;
+ }
+#else // USE_QT4
+ if ( wid->tqlayout() ) {
+ if ( TQT_TQSIZEPOLICY_OBJECT(wid->sizePolicy()).mayGrowHorizontally()
+ && (wid->tqlayout()->expandingDirections() & TQSizePolicy::Horizontally) )
+ e |= TQSizePolicy::Horizontally;
+ if ( TQT_TQSIZEPOLICY_OBJECT(wid->sizePolicy()).mayGrowVertically()
+ && (wid->tqlayout()->expandingDirections() & TQSizePolicy::Vertically) )
+ e |= TQSizePolicy::Vertically;
+ }
+#endif // USE_QT4
+
+ if ( align & TQt::AlignHorizontal_Mask )
+ e &= ~TQSizePolicy::Horizontally;
+ if ( align & TQt::AlignVertical_Mask)
+ e &= ~TQSizePolicy::Vertically;
+
+// [FIXME]
+// For some reason, the above (commented out) code causes a weird crash that currupts the stack or heap, making debugging extremely difficult
+// printf("[WARNING] TQ_SPExpandData TQWidgetItem::expandingDirections() const partially implemented\n\r");
+
+ return (TQ_SPExpandData)e;
+}
+
+#ifdef USE_QT4
+
+/*!
+ Returns the minimum size of this spacer item.
+*/
+TQSize TQSpacerItem::tqminimumSize() const
+{
+
+ return QSpacerItem::minimumSize();
+}
+
+#else // USE_QT4
+
+/*!
+ Returns the minimum size of this spacer item.
+*/
+TQSize TQSpacerItem::tqminimumSize() const
+{
+ return TQSize( sizeP.mayShrinkHorizontally() ? 0 : width,
+ sizeP.mayShrinkVertically() ? 0 : height );
+}
+
+#endif // USE_QT4
+
+/*!
+ Returns the minimum size of this item.
+*/
+TQSize TQWidgetItem::tqminimumSize() const
+{
+ if ( isEmpty() )
+ return TQSize( 0, 0 );
+ return tqSmartMinSize( this );
+}
+
+#ifdef USE_QT4
+
+/*!
+ Returns the maximum size of this spacer item.
+*/
+TQSize TQSpacerItem::tqmaximumSize() const
+{
+ return QSpacerItem::maximumSize();
+}
+
+#else // USE_QT4
+
+/*!
+ Returns the maximum size of this spacer item.
+*/
+TQSize TQSpacerItem::tqmaximumSize() const
+{
+ return TQSize( sizeP.mayGrowHorizontally() ? TQLAYOUTSIZE_MAX : width,
+ sizeP.mayGrowVertically() ? TQLAYOUTSIZE_MAX : height );
+}
+
+#endif // USE_QT4
+
+/*!
+ Returns the maximum size of this item.
+*/
+TQSize TQWidgetItem::tqmaximumSize() const
+{
+ if ( isEmpty() ) {
+ return TQSize( 0, 0 );
+ } else {
+ return tqSmartMaxSize( this, align );
+ }
+}
+
+#ifdef USE_QT4
+
+/*!
+ Returns the preferred size of this spacer item.
+*/
+TQSize TQSpacerItem::tqsizeHint() const
+{
+ return QSpacerItem::sizeHint();
+}
+
+
+#else // USE_QT4
+
+/*!
+ Returns the preferred size of this spacer item.
+*/
+TQSize TQSpacerItem::tqsizeHint() const
+{
+ return TQSize( width, height );
+}
+
+#endif
+
+/*!
+ Returns the preferred size of this item.
+*/
+TQSize TQWidgetItem::tqsizeHint() const
+{
+ TQSize s;
+ if ( isEmpty() ) {
+ s = TQSize( 0, 0 );
+ } else {
+ s = wid->tqsizeHint();
+ if ( TQT_TQSIZEPOLICY_OBJECT(wid->sizePolicy()).horData() == TQSizePolicy::Ignored )
+ s.setWidth( 1 );
+ if ( TQT_TQSIZEPOLICY_OBJECT(wid->sizePolicy()).verData() == TQSizePolicy::Ignored )
+ s.setHeight( 1 );
+ s = s.boundedTo( wid->tqmaximumSize() )
+ .expandedTo( wid->tqminimumSize() ).expandedTo( TQSize(1, 1) );
+ }
+ return s;
+}
+
+/*!
+ Returns TRUE because a spacer item never tqcontains widgets.
+*/
+bool TQSpacerItem::isEmpty() const
+{
+ return TRUE;
+}
+
+/*!
+ Returns TRUE if the widget has been hidden; otherwise returns
+ FALSE.
+*/
+bool TQWidgetItem::isEmpty() const
+{
+ return wid->isHidden() || wid->isTopLevel();
+}
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \class TQLayout
+ \brief The TQLayout class is the base class of tqgeometry managers.
+
+ \ingroup appearance
+ \ingroup geomanagement
+
+ This is an abstract base class inherited by the concrete classes,
+ TQBoxLayout and TQGridLayout.
+
+ For users of TQLayout subclasses or of TQMainWindow there is seldom
+ any need to use the basic functions provided by TQLayout, such as
+ \l setResizeMode() or setMenuBar(). See the \link tqlayout.html tqlayout
+ overview page \endlink for more information.
+
+ To make your own tqlayout manager, subclass TQGLayoutIterator and
+ implement the functions addItem(), tqsizeHint(), setGeometry(), and
+ iterator(). You should also implement tqminimumSize() to ensure your
+ tqlayout isn't resized to zero size if there is too little space. To
+ support tqchildren whose heights depend on their widths, implement
+ hasHeightForWidth() and heightForWidth(). See the \link
+ customtqlayout.html custom tqlayout page \endlink for an in-depth
+ description.
+
+ Geometry management stops when the tqlayout manager is deleted.
+*/
+
+/*!
+ Constructs a new top-level TQLayout called \a name, with main
+ widget \a tqparent. \a tqparent may not be 0.
+
+ The \a margin is the number of pixels between the edge of the
+ widget and the managed tqchildren. The \a spacing sets the value of
+ spacing(), which gives the spacing between the managed widgets. If
+ \a spacing is -1 (the default), spacing is set to the value of \a
+ margin.
+
+ There can be only one top-level tqlayout for a widget. It is
+ returned by TQWidget::tqlayout()
+*/
+TQLayout::TQLayout( QWidget *tqparent, int margin, int spacing, const char *name )
+ : TQObject( tqparent, name )
+{
+ init();
+ if ( tqparent ) {
+ if ( tqparent->tqlayout() ) {
+ qWarning( "TQLayout \"%s\" added to %s \"%s\", which already has a"
+ " tqlayout", TQObject::name(), tqparent->className(),
+ tqparent->name() );
+ tqparent->removeChild( this );
+ } else {
+ topLevel = TRUE;
+ tqparent->installEventFilter( this );
+ setWidgetLayout( tqparent, this );
+ }
+ }
+ outsideBorder = margin;
+ if ( spacing < 0 )
+ insideSpacing = margin;
+ else
+ insideSpacing = spacing;
+}
+
+void TQLayout::init()
+{
+ insideSpacing = 0;
+ outsideBorder = 0;
+ topLevel = FALSE;
+ enabled = TRUE;
+ autoNewChild = FALSE;
+ frozen = FALSE;
+ activated = FALSE;
+ marginImpl = FALSE;
+ autoMinimum = FALSE;
+ autoResizeMode = TRUE;
+ extraData = 0;
+#ifndef TQT_NO_MENUBAR
+ menubar = 0;
+#endif
+}
+
+/*!
+ Constructs a new child TQLayout called \a name, and places it
+ inside \a parentLayout by using the default placement defined by
+ addItem().
+
+ If \a spacing is -1, this TQLayout inherits \a parentLayout's
+ spacing(), otherwise the value of \a spacing is used.
+*/
+TQLayout::TQLayout( QLayout *parentLayout, int spacing, const char *name )
+ : TQObject( parentLayout, name )
+
+{
+ init();
+ insideSpacing = spacing < 0 ? parentLayout->insideSpacing : spacing;
+ parentLayout->addItem( this );
+}
+
+/*!
+ Constructs a new child TQLayout called \a name. If \a spacing is
+ -1, this TQLayout inherits its tqparent's spacing(); otherwise the
+ value of \a spacing is used.
+
+ This tqlayout has to be inserted into another tqlayout before tqgeometry
+ management will work.
+*/
+TQLayout::TQLayout( int spacing, const char *name )
+ : TQObject( 0, name )
+{
+ init();
+ insideSpacing = spacing;
+}
+
+/*!
+ \fn void TQLayout::addItem( TQLayoutItem *item )
+
+ Implemented in subclasses to add an \a item. How it is added is
+ specific to each subclass.
+
+ The ownership of \a item is transferred to the tqlayout, and it's
+ the tqlayout's responsibility to delete it.
+*/
+
+/*!
+ \fn TQLayoutIterator TQLayout::iterator()
+
+ Implemented in subclasses to return an iterator that iterates over
+ this tqlayout's tqchildren.
+
+ A typical implementation will be:
+ \code
+ TQLayoutIterator MyLayout::iterator()
+ {
+ TQGLayoutIterator *i = new MyLayoutIterator( internal_data );
+ return TQLayoutIterator( i );
+ }
+ \endcode
+ where MyLayoutIterator is a subclass of TQGLayoutIterator.
+*/
+
+/*!
+ \fn void TQLayout::add( TQWidget *w )
+
+ Adds widget \a w to this tqlayout in a manner specific to the
+ tqlayout. This function uses addItem().
+*/
+
+/*!
+ \fn TQMenuBar* TQLayout::menuBar () const
+
+ Returns the menu bar set for this tqlayout, or 0 if no menu bar is
+ set.
+*/
+
+/*!
+ \fn bool TQLayout::isTopLevel () const
+
+ Returns TRUE if this tqlayout is a top-level tqlayout, i.e. not a
+ child of another tqlayout; otherwise returns FALSE.
+*/
+
+/*!
+ \property TQLayout::margin
+ \brief the width of the outside border of the tqlayout
+
+ For some tqlayout classes this property has an effect only on
+ top-level layouts; TQBoxLayout and TQGridLayout support margins for
+ child layouts. The default value is 0.
+
+ \sa spacing
+*/
+
+/*!
+ \property TQLayout::spacing
+ \brief the spacing between widgets inside the tqlayout
+
+ The default value is -1, which signifies that the tqlayout's spacing
+ should not override the widget's spacing.
+
+ \sa margin
+*/
+void TQLayout::setMargin( int margin )
+{
+ outsideBorder = margin;
+ tqinvalidate();
+ if ( mainWidget() ) {
+ TQEvent *lh = new TQEvent( TQEvent::LayoutHint );
+ TQApplication::postEvent( mainWidget(), lh );
+ }
+}
+
+void TQLayout::setSpacing( int spacing )
+{
+ insideSpacing = spacing;
+ if ( spacing >= 0 )
+ propagateSpacing( this );
+ tqinvalidate();
+ if ( mainWidget() ) {
+ TQEvent *lh = new TQEvent( TQEvent::LayoutHint );
+ TQApplication::postEvent( mainWidget(), lh );
+ }
+}
+
+/*!
+ Returns the main widget (tqparent widget) of this tqlayout, or 0 if
+ this tqlayout is a sub-tqlayout that is not yet inserted.
+*/
+TQWidget *TQLayout::mainWidget()
+{
+ if ( !topLevel ) {
+ if ( tqparent() ) {
+ TQLayout *parentLayout = ::tqqt_cast<TQLayout*>(tqparent());
+ TQ_ASSERT(parentLayout);
+ return parentLayout->mainWidget();
+ } else {
+ return 0;
+ }
+ } else {
+ TQ_ASSERT(tqparent() && tqparent()->isWidgetType());
+ return (TQWidget*)tqparent();
+ }
+}
+
+/*!
+ Returns TRUE if this tqlayout is empty. The default implementation
+ returns FALSE.
+*/
+bool TQLayout::isEmpty() const
+{
+ return FALSE; //### should check
+}
+
+/*!
+ Sets widget \a w's tqlayout to tqlayout \a l.
+*/
+void TQLayout::setWidgetLayout( TQWidget *w, TQLayout *l )
+{
+ w->setLayout( l );
+}
+
+/*!
+ This function is reimplemented in subclasses to perform tqlayout.
+
+ The default implementation maintains the tqgeometry() information
+ given by rect \a r. Reimplementors must call this function.
+*/
+void TQLayout::setGeometry( const TQRect &r )
+{
+ rect = r;
+}
+
+/*!
+ Invalidates cached information. Reimplementations must call this.
+*/
+void TQLayout::tqinvalidate()
+{
+ rect = TQRect();
+}
+
+static bool removeWidgetRecursively( TQLayoutItem *lay, TQWidget *w )
+{
+ bool didSomething = FALSE;
+ TQLayoutIterator it = lay->iterator();
+ TQLayoutItem *child;
+ while ( (child = it.current()) != 0 ) {
+ if ( child->widget() == w ) {
+ it.deleteCurrent();
+ lay->tqinvalidate(); // maybe redundant
+ didSomething = TRUE;
+ } else if ( removeWidgetRecursively(child, w) ) {
+ lay->tqinvalidate(); // maybe redundant
+ didSomething = TRUE;
+ } else {
+ ++it;
+ }
+ }
+ return didSomething;
+}
+
+/*!
+ \reimp
+ Performs child widget tqlayout when the tqparent widget is resized.
+ Also handles removal of widgets and child layouts. \a e is the
+ event the occurred on object \a o.
+*/
+bool TQLayout::eventFilter( TQObject *o, TQEvent *e )
+{
+ if ( !enabled )
+ return FALSE;
+
+ if ( !o->isWidgetType() )
+ return FALSE;
+
+ switch ( e->type() ) {
+ case TQEvent::Resize:
+ if ( activated ) {
+ TQResizeEvent *r = (TQResizeEvent *)e;
+ int mbh = 0;
+#ifndef TQT_NO_MENUBAR
+ mbh = menuBarHeightForWidth( menubar, r->size().width() );
+#endif
+ int b = marginImpl ? 0 : outsideBorder;
+ setGeometry( TQRect( b, mbh + b, r->size().width() - 2 * b,
+ r->size().height() - mbh - 2 * b ) );
+ } else {
+ activate();
+ }
+ break;
+ case TQEvent::ChildRemoved:
+ {
+ TQChildEvent *c = (TQChildEvent *)e;
+ if ( c->child()->isWidgetType() ) {
+ TQWidget *w = (TQWidget *)c->child();
+#ifndef TQT_NO_MENUBAR
+ if ( w == menubar )
+ menubar = 0;
+#endif
+ if ( removeWidgetRecursively( this, w ) ) {
+ TQEvent *lh = new TQEvent( TQEvent::LayoutHint );
+ TQApplication::postEvent( o, lh );
+ }
+ }
+ }
+ break;
+ case TQEvent::ChildInserted:
+ if ( topLevel && autoNewChild ) {
+ TQChildEvent *c = (TQChildEvent *)e;
+ if ( c->child()->isWidgetType() ) {
+ TQWidget *w = (TQWidget *)c->child();
+ if ( !w->isTopLevel() ) {
+#if !defined(TQT_NO_MENUBAR) && !defined(TQT_NO_TOOLBAR)
+ if ( ::tqqt_cast<TQMenuBar*>(w) && !::tqqt_cast<TQToolBar*>(w->parentWidget()) )
+ menubar = (TQMenuBar *)w;
+ else
+#endif
+ addItem( new TQWidgetItem( w ) );
+ TQEvent *lh = new TQEvent( TQEvent::LayoutHint );
+ TQApplication::postEvent( o, lh );
+ }
+ }
+ }
+ break;
+ case TQEvent::LayoutHint:
+ activate();
+ break;
+ default:
+ break;
+ }
+ return TQObject::eventFilter( o, e );
+}
+
+/*!
+ \reimp
+*/
+void TQLayout::childEvent( TQChildEvent *e )
+{
+ if ( !enabled )
+ return;
+
+ if ( e->type() == TQEvent::ChildRemoved ) {
+ TQChildEvent *c = (TQChildEvent*)e;
+ TQLayoutIterator it = iterator();
+ TQLayoutItem *item;
+ while ( (item = it.current() ) ) {
+ if ( item == (TQLayout*)c->child() ) {
+ it.takeCurrent();
+ tqinvalidate();
+ break;
+ } else {
+ ++it;
+ }
+ }
+ }
+}
+
+/*!
+ \internal
+ Also takes margin() and menu bar into account.
+*/
+int TQLayout::totalHeightForWidth( int w ) const
+{
+ if ( topLevel ) {
+ TQWidget *mw = (TQWidget*)tqparent();
+ if ( mw && !mw->testWState(WState_Polished) ) {
+ mw->polish();
+ }
+ }
+ int b = ( topLevel && !marginImpl ) ? 2 * outsideBorder : 0;
+ int h = heightForWidth( w - b ) + b;
+#ifndef TQT_NO_MENUBAR
+ h += menuBarHeightForWidth( menubar, w );
+#endif
+ return h;
+}
+
+/*!
+ \internal
+ Also takes margin() and menu bar into account.
+*/
+TQSize TQLayout::totalMinimumSize() const
+{
+ if ( topLevel ) {
+ TQWidget *mw = (TQWidget*)tqparent();
+ if ( mw && !mw->testWState(WState_Polished) )
+ mw->polish();
+ }
+ int b = ( topLevel && !marginImpl ) ? 2 * outsideBorder : 0;
+
+ TQSize s = tqminimumSize();
+ int h = b;
+#ifndef TQT_NO_MENUBAR
+ h += menuBarHeightForWidth( menubar, s.width() );
+#endif
+ return s + TQSize( b, h );
+}
+
+/*!
+ \internal
+ Also takes margin() and menu bar into account.
+*/
+TQSize TQLayout::totalSizeHint() const
+{
+ if ( topLevel ) {
+ TQWidget *mw = (TQWidget*)tqparent();
+ if ( mw && !mw->testWState(WState_Polished) )
+ mw->polish();
+ }
+ int b = ( topLevel && !marginImpl ) ? 2 * outsideBorder : 0;
+
+ TQSize s = tqsizeHint();
+ if ( hasHeightForWidth() )
+ s.setHeight( heightForWidth(s.width()) );
+ int h = b;
+#ifndef TQT_NO_MENUBAR
+ h += menuBarHeightForWidth( menubar, s.width() );
+#endif
+ return s + TQSize( b, h );
+}
+
+/*!
+ \internal
+ Also takes margin() and menu bar into account.
+*/
+TQSize TQLayout::totalMaximumSize() const
+{
+ if ( topLevel ) {
+ TQWidget *mw = (TQWidget*)tqparent();
+ if ( mw && !mw->testWState(WState_Polished) ) {
+ mw->polish();
+ }
+ }
+ int b = ( topLevel && !marginImpl ) ? 2 * outsideBorder : 0;
+
+ TQSize s = tqmaximumSize();
+ int h = b;
+#ifndef TQT_NO_MENUBAR
+ h += menuBarHeightForWidth( menubar, s.width() );
+#endif
+
+ if ( isTopLevel() )
+ s = TQSize( TQMIN( s.width() + b, TQLAYOUTSIZE_MAX ),
+ TQMIN( s.height() + h, TQLAYOUTSIZE_MAX ) );
+ return s;
+}
+
+/*!
+ \internal
+ Destroys the tqlayout, deleting all child layouts.
+ Geometry management stops when a top-level tqlayout is deleted.
+
+ The tqlayout classes will probably be fatally confused if you delete
+ a subtqlayout.
+*/
+TQLayout::~TQLayout()
+{
+ /*
+ This function may be called during the TQObject destructor,
+ when the tqparent no longer is a TQWidget.
+ */
+ if ( isTopLevel() && tqparent() && tqparent()->isWidgetType() &&
+ ((TQWidget*)tqparent())->tqlayout() == this )
+ setWidgetLayout( (TQWidget*)tqparent(), 0 );
+}
+
+/*!
+ Removes and deletes all items in this tqlayout.
+*/
+void TQLayout::deleteAllItems()
+{
+ TQLayoutIterator it = iterator();
+ TQLayoutItem *l;
+ while ( (l = it.takeCurrent()) )
+ delete l;
+}
+
+/*!
+ This function is called from addLayout() functions in subclasses
+ to add tqlayout \a l as a sub-tqlayout.
+*/
+void TQLayout::addChildLayout( TQLayout *l )
+{
+ if ( l->tqparent() ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQLayout::addChildLayout: tqlayout already has a tqparent" );
+#endif
+ return;
+ }
+ insertChild( l );
+ if ( l->insideSpacing < 0 ) {
+ l->insideSpacing = insideSpacing;
+ propagateSpacing( l );
+ }
+}
+
+/*! \fn int TQLayout::defaultBorder() const
+
+ \internal
+*/
+
+/*! \fn void TQLayout::freeze()
+
+ \internal
+*/
+
+/*!
+ \internal
+ Fixes the size of the main widget and distributes the available
+ space to the child widgets. For widgets which should not be
+ resizable, but where a TQLayout subclass is used to set up the initial
+ tqgeometry.
+
+ As a special case, freeze(0, 0) is equivalent to setResizeMode(Fixed).
+*/
+void TQLayout::freeze( int w, int h )
+{
+ if ( w <= 0 || h <= 0 ) {
+ setResizeMode( Fixed );
+ } else {
+ setResizeMode( FreeResize ); // tqlayout will not change min/max size
+ mainWidget()->setFixedSize( w, h );
+ }
+}
+
+#ifndef TQT_NO_MENUBAR
+
+/*!
+ Makes the tqgeometry manager take account of the menu bar \a w. All
+ child widgets are placed below the bottom edge of the menu bar.
+
+ A menu bar does its own tqgeometry management: never do addWidget()
+ on a TQMenuBar.
+*/
+void TQLayout::setMenuBar( TQMenuBar *w )
+{
+ menubar = w;
+}
+
+#endif
+
+/*!
+ Returns the minimum size of this tqlayout. This is the smallest size
+ that the tqlayout can have while still respecting the
+ specifications. Does not include what's needed by margin() or
+ menuBar().
+
+ The default implementation allows unlimited resizing.
+*/
+TQSize TQLayout::tqminimumSize() const
+{
+ return TQSize( 0, 0 );
+}
+
+/*!
+ Returns the maximum size of this tqlayout. This is the largest size
+ that the tqlayout can have while still respecting the
+ specifications. Does not include what's needed by margin() or
+ menuBar().
+
+ The default implementation allows unlimited resizing.
+*/
+TQSize TQLayout::tqmaximumSize() const
+{
+ return TQSize( TQLAYOUTSIZE_MAX, TQLAYOUTSIZE_MAX );
+}
+
+/*!
+ Returns whether this tqlayout can make use of more space than
+ tqsizeHint(). A value of \c Vertical or \c Horizontal means that it wants
+ to grow in only one dimension, whereas \c BothDirections means that
+ it wants to grow in both dimensions.
+
+ The default implementation returns \c BothDirections.
+*/
+TQ_SPExpandData TQLayout::expandingDirections() const
+{
+ return TQSizePolicy::BothDirections;
+}
+
+static void invalidateRecursive( TQLayoutItem *lay )
+{
+ lay->tqinvalidate();
+ TQLayoutIterator it = lay->iterator();
+ TQLayoutItem *child;
+ while ( (child = it.current()) != 0 ) {
+ invalidateRecursive( child );
+ ++it;
+ }
+}
+
+/*!
+ Redoes the tqlayout for mainWidget(). You should generally not need
+ to call this because it is automatically called at the most
+ appropriate times.
+
+ However, if you set up a TQLayout for a visible widget without
+ resizing that widget, you will need to call this function in order
+ to lay it out.
+
+ \sa TQWidget::updateGeometry()
+*/
+bool TQLayout::activate()
+{
+ invalidateRecursive( this );
+ if ( !topLevel )
+ return FALSE;
+
+ TQWidget *mw = mainWidget();
+ if (!mw) {
+#if defined( TQT_CHECK_NULL )
+ qWarning( "TQLayout::activate: %s \"%s\" does not have a main widget",
+ TQObject::className(), TQObject::name() );
+#endif
+ return FALSE;
+ }
+ activated = TRUE;
+ TQSize s = mw->size();
+ TQSize ms;
+ int mbh = 0;
+#ifndef TQT_NO_MENUBAR
+ mbh = menuBarHeightForWidth( menubar, s.width() );
+#endif
+ int b = marginImpl ? 0 : outsideBorder;
+ setGeometry(TQRect(b, mbh + b, s.width() - 2 * b, s.height() - mbh - 2 * b));
+ if ( frozen ) {
+ // will trigger resize
+ mw->setFixedSize( totalSizeHint() );
+ } else if ( autoMinimum ) {
+ ms = totalMinimumSize();
+ } else if ( autoResizeMode && topLevel && mw->isTopLevel() ) {
+ ms = totalMinimumSize();
+ if ( hasHeightForWidth() ) {
+ int h;
+ int mmbh = menuBarHeightForWidth( menubar, ms.width() );
+ // ### 4.0: remove this 'if' when minimumHeightForWidth() is virtual
+ if ( inherits("TQBoxLayout") )
+ h = ((TQBoxLayout *) this)->minimumHeightForWidth( ms.width() );
+ else if ( inherits("TQGridLayout") )
+ h = ((TQGridLayout *) this)->minimumHeightForWidth( ms.width() );
+ else
+ h = heightForWidth( ms.width() );
+ if ( h + mmbh > ms.height() )
+#if 1
+ //old behaviour:
+ ms = TQSize( 0, 0 );
+#else
+ //better, but too big a change for a patch release in a stable branch:
+ ms.setHeight( 0 );
+#endif
+ }
+ }
+
+ if (ms.isValid())
+ mw->setMinimumSize( ms );
+
+ // ideally only if tqsizeHint() or sizePolicy() has changed
+ mw->updateGeometry();
+ return TRUE;
+}
+
+#endif // USE_QT4
+
+/*!
+ \class TQSizePolicy
+ \brief The TQSizePolicy class is a tqlayout attribute describing horizontal
+ and vertical resizing policy.
+
+ \ingroup appearance
+ \ingroup geomanagement
+
+ The size policy of a widget is an expression of its willingness to
+ be resized in various ways.
+
+ Widgets that reimplement TQWidget::sizePolicy() return a TQSizePolicy
+ that describes the horizontal and vertical resizing policy they
+ prefer when being laid out. Only \link #interesting one of the
+ constructors\endlink is of interest in most applications.
+
+ TQSizePolicy tqcontains two independent SizeType objects; one describes
+ the widgets's horizontal size policy, and the other describes its
+ vertical size policy. It also tqcontains a flag to indicate whether the
+ height and width of its preferred size are related.
+
+ The horizontal and vertical \l{SizeType}s are set in the usual constructor
+ and can be queried using a variety of functions.
+
+ The hasHeightForWidth() flag indicates whether the widget's tqsizeHint()
+ is width-dependent (such as a word-wrapping label) or not.
+
+ \sa TQSizePolicy::SizeType
+*/
+
+/*!
+ \enum TQSizePolicy::SizeType
+
+ The per-dimension sizing types used when constructing a
+ TQSizePolicy are:
+
+ \value Fixed The TQWidget::tqsizeHint() is the only acceptable
+ alternative, so the widget can never grow or shrink (e.g. the
+ vertical direction of a push button).
+
+ \value Minimum The tqsizeHint() is minimal, and sufficient. The
+ widget can be expanded, but there is no advantage to it being
+ larger (e.g. the horizontal direction of a push button).
+ It cannot be smaller than the size provided by tqsizeHint().
+
+ \value Maximum The tqsizeHint() is a maximum. The widget can be
+ shrunk any amount without detriment if other widgets need the
+ space (e.g. a separator line).
+ It cannot be larger than the size provided by tqsizeHint().
+
+ \value Preferred The tqsizeHint() is best, but the widget can be
+ shrunk and still be useful. The widget can be expanded, but there
+ is no advantage to it being larger than tqsizeHint() (the default
+ TQWidget policy).
+
+ \value Expanding The tqsizeHint() is a sensible size, but the
+ widget can be shrunk and still be useful. The widget can make use
+ of extra space, so it should get as much space as possible (e.g.
+ the horizontal direction of a slider).
+
+ \value MinimumExpanding The tqsizeHint() is minimal, and sufficient.
+ The widget can make use of extra space, so it should get as much
+ space as possible (e.g. the horizontal direction of a slider).
+
+ \value Ignored the tqsizeHint() is ignored. The widget will get as
+ much space as possible.
+*/
+
+/*!
+ \enum TQ_SPExpandData
+
+ This enum type describes in which directions a widget can make use
+ of extra space. There are four possible values:
+
+ \value NoDirection the widget cannot make use of extra space in
+ any direction.
+
+ \value Horizontally the widget can usefully be wider than the
+ tqsizeHint().
+
+ \value Vertically the widget can usefully be taller than the
+ tqsizeHint().
+
+ \value BothDirections the widget can usefully be both wider and
+ taller than the tqsizeHint().
+*/
+
+/*!
+ \fn TQSizePolicy::TQSizePolicy()
+
+ Constructs a minimally initialized TQSizePolicy.
+*/
+
+/*!
+ \fn TQSizePolicy::TQSizePolicy( SizeType hor, SizeType ver, bool hfw )
+
+ \target interesting
+ This is the constructor normally used to return a value in the
+ overridden \l TQWidget::sizePolicy() function of a TQWidget
+ subclass.
+
+ It constructs a TQSizePolicy with independent horizontal and
+ vertical sizing types, \a hor and \a ver respectively. These \link
+ TQSizePolicy::SizeType sizing types\endlink affect how the widget
+ is treated by the \link TQLayout tqlayout engine\endlink.
+
+ If \a hfw is TRUE, the preferred height of the widget is dependent
+ on the width of the widget (for example, a TQLabel with line
+ wrapping).
+
+ \sa horData() verData() hasHeightForWidth()
+*/
+
+/*!
+ \fn TQSizePolicy::TQSizePolicy( SizeType hor, SizeType ver, uchar horStretch, uchar verStretch, bool hfw )
+
+ Constructs a TQSizePolicy with independent horizontal and vertical
+ sizing types \a hor and \a ver, and stretch factors \a horStretch
+ and \a verStretch.
+
+ If \a hfw is TRUE, the preferred height of the widget is dependent on the
+ width of the widget.
+
+ \sa horStretch() verStretch()
+*/
+
+/*!
+ \fn TQSizePolicy::SizeType TQSizePolicy::horData() const
+
+ Returns the horizontal component of the size policy.
+
+ \sa setHorData() verData() horStretch()
+*/
+
+/*!
+ \fn TQSizePolicy::SizeType TQSizePolicy::verData() const
+
+ Returns the vertical component of the size policy.
+
+ \sa setVerData() horData() verStretch()
+*/
+
+/*!
+ \fn bool TQSizePolicy::mayShrinkHorizontally() const
+
+ Returns TRUE if the widget can sensibly be narrower than its
+ tqsizeHint(); otherwise returns FALSE.
+
+ \sa mayShrinkVertically() mayGrowHorizontally()
+*/
+
+/*!
+ \fn bool TQSizePolicy::mayShrinkVertically() const
+
+ Returns TRUE if the widget can sensibly be shorter than its
+ tqsizeHint(); otherwise returns FALSE.
+
+ \sa mayShrinkHorizontally() mayGrowVertically()
+*/
+
+/*!
+ \fn bool TQSizePolicy::mayGrowHorizontally() const
+
+ Returns TRUE if the widget can sensibly be wider than its
+ tqsizeHint(); otherwise returns FALSE.
+
+ \sa mayGrowVertically() mayShrinkHorizontally()
+*/
+
+/*!
+ \fn bool TQSizePolicy::mayGrowVertically() const
+
+ Returns TRUE if the widget can sensibly be taller than its
+ tqsizeHint(); otherwise returns FALSE.
+
+ \sa mayGrowHorizontally() mayShrinkVertically()
+*/
+
+/*!
+ \fn TQ_SPExpandData TQSizePolicy::expandingDirections() const
+
+ Returns whether this tqlayout can make use of more space than
+ tqsizeHint(). A value of \c Vertical or \c Horizontal means that it wants
+ to grow in only one dimension, whereas \c BothDirections means that
+ it wants to grow in both dimensions.
+
+ \sa mayShrinkHorizontally() mayGrowHorizontally()
+ mayShrinkVertically() mayGrowVertically()
+*/
+
+/*!
+ \fn void TQSizePolicy::setHorData( SizeType d )
+
+ Sets the horizontal component of the size policy to size type \a
+ d.
+
+ \sa horData() setVerData()
+*/
+
+/*!
+ \fn void TQSizePolicy::setVerData( SizeType d )
+
+ Sets the vertical component of the size policy to size type \a d.
+
+ \sa verData() setHorData()
+*/
+
+/*!
+ \fn bool TQSizePolicy::hasHeightForWidth() const
+
+ Returns TRUE if the widget's preferred height depends on its
+ width; otherwise returns FALSE.
+
+ \sa setHeightForWidth()
+*/
+
+/*!
+ \fn void TQSizePolicy::setHeightForWidth( bool b )
+
+ Sets the hasHeightForWidth() flag to \a b.
+
+ \sa hasHeightForWidth()
+*/
+
+/*!
+ \fn uint TQSizePolicy::horStretch() const
+
+ Returns the horizontal stretch factor of the size policy.
+
+ \sa setHorStretch() verStretch()
+*/
+
+/*!
+ \fn uint TQSizePolicy::verStretch() const
+
+ Returns the vertical stretch factor of the size policy.
+
+ \sa setVerStretch() horStretch()
+*/
+
+/*!
+ \fn void TQSizePolicy::setHorStretch( uchar sf )
+
+ Sets the horizontal stretch factor of the size policy to \a sf.
+
+ \sa horStretch() setVerStretch()
+*/
+
+/*!
+ \fn void TQSizePolicy::setVerStretch( uchar sf )
+
+ Sets the vertical stretch factor of the size policy to \a sf.
+
+ \sa verStretch() setHorStretch()
+*/
+
+/*!
+ \fn void TQSizePolicy::transpose()
+
+ Swaps the horizontal and vertical policies and stretches.
+*/
+
+
+/*!
+ \fn bool TQSizePolicy::operator==( const TQSizePolicy &s ) const
+
+ Returns TRUE if this policy is equal to \a s; otherwise returns
+ FALSE.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool TQSizePolicy::operator!=( const TQSizePolicy &s ) const
+
+ Returns TRUE if this policy is different from \a s; otherwise
+ returns FALSE.
+
+ \sa operator==()
+*/
+
+/*!
+ \class TQGLayoutIterator
+ \brief The TQGLayoutIterator class is an abstract base class of internal tqlayout iterators.
+
+ \ingroup appearance
+ \ingroup geomanagement
+
+ (This class is \e not OpenGL related, it just happens to start with
+ the letters TQGL...)
+
+ Subclass this class to create a custom tqlayout. The functions that
+ must be implemented are next(), current(), and takeCurrent().
+
+ The TQGLayoutIterator implements the functionality of
+ TQLayoutIterator. Each subclass of TQLayout needs a
+ TQGLayoutIterator subclass.
+*/
+
+/*!
+ \fn TQLayoutItem *TQGLayoutIterator::next()
+
+ Implemented in subclasses to move the iterator to the next item
+ and return that item, or 0 if there is no next item.
+*/
+
+/*!
+ \fn TQLayoutItem *TQGLayoutIterator::current()
+
+ Implemented in subclasses to return the current item, or 0 if
+ there is no current item.
+*/
+
+/*!
+ \fn TQLayoutItem *TQGLayoutIterator::takeCurrent()
+
+ Implemented in subclasses. The function must remove the current
+ item from the tqlayout without deleting it, move the iterator to the
+ next item and return the removed item, or 0 if no item was
+ removed.
+*/
+
+/*!
+ Destroys the iterator
+*/
+TQGLayoutIterator::~TQGLayoutIterator()
+{
+}
+
+/*!
+ \class TQLayoutIterator
+ \brief The TQLayoutIterator class provides iterators over TQLayoutItem.
+
+ \ingroup appearance
+ \ingroup geomanagement
+
+ Use TQLayoutItem::iterator() to create an iterator over a tqlayout.
+
+ TQLayoutIterator uses \e explicit sharing with a reference count.
+ If an iterator is copied and one of the copies is modified, both
+ iterators will be modified.
+
+ A TQLayoutIterator is not protected against changes in its tqlayout. If
+ the tqlayout is modified or deleted the iterator will become invalid.
+ It is not possible to test for validity. It is safe to delete an
+ invalid tqlayout; any other access may lead to an illegal memory
+ reference and the abnormal termination of the program.
+
+ Calling takeCurrent() or deleteCurrent() leaves the iterator in a
+ valid state, but may tqinvalidate any other iterators that access the
+ same tqlayout.
+
+ The following code will draw a rectangle for each tqlayout item in
+ the tqlayout structure of the widget.
+ \code
+ static void paintLayout( TQPainter *p, TQLayoutItem *lay )
+ {
+ TQLayoutIterator it = lay->iterator();
+ TQLayoutItem *child;
+ while ( (child = it.current()) != 0 ) {
+ paintLayout( p, child );
+ ++it;
+ }
+ p->drawRect( lay->tqgeometry() );
+ }
+ void ExampleWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPainter p( this );
+ if ( tqlayout() )
+ paintLayout( &p, tqlayout() );
+ }
+ \endcode
+
+ All the functionality of TQLayoutIterator is implemented by
+ subclasses of \l TQGLayoutIterator. TQLayoutIterator itself is not
+ designed to be subclassed.
+*/
+
+/*!
+ \fn TQLayoutIterator::TQLayoutIterator( TQGLayoutIterator *gi )
+
+ Constructs an iterator based on \a gi. The constructed iterator
+ takes ownership of \a gi and will delete it.
+
+ This constructor is provided for tqlayout implementors. Application
+ programmers should use TQLayoutItem::iterator() to create an
+ iterator over a tqlayout.
+*/
+
+/*!
+ \fn TQLayoutIterator::TQLayoutIterator( const TQLayoutIterator &i )
+
+ Creates a shallow copy of \a i, i.e. if the copy is modified, then
+ the original will also be modified.
+*/
+
+/*!
+ \fn TQLayoutIterator::~TQLayoutIterator()
+
+ Destroys the iterator.
+*/
+
+/*!
+ \fn TQLayoutIterator &TQLayoutIterator::operator=( const TQLayoutIterator &i )
+
+ Assigns \a i to this iterator and returns a reference to this
+ iterator.
+*/
+
+/*!
+ \fn TQLayoutItem *TQLayoutIterator::operator++()
+
+ Moves the iterator to the next child item and returns that item,
+ or 0 if there is no such item.
+*/
+
+/*!
+ \fn TQLayoutItem *TQLayoutIterator::current()
+
+ Returns the current item, or 0 if there is no current item.
+*/
+
+/*!
+ \fn TQLayoutItem *TQLayoutIterator::takeCurrent()
+
+ Removes the current child item from the tqlayout without deleting
+ it, and moves the iterator to the next item. Returns the removed
+ item, or 0 if there was no item to be removed. This iterator will
+ still be valid, but any other iterator over the same tqlayout may
+ become invalid.
+*/
+
+/*!
+ \fn void TQLayoutIterator::deleteCurrent()
+
+ Removes and deletes the current child item from the tqlayout and
+ moves the iterator to the next item. This iterator will still be
+ valid, but any other iterator over the same tqlayout may become
+ invalid.
+*/
+
+/*!
+ \enum TQLayout::ResizeMode
+
+ The possible values are:
+
+ \value Auto If the main widget is a top-level widget with no
+ height-for-width (hasHeightForWidth()), this is
+ the same as \c Minimium; otherwise, this is the
+ same as \c FreeResize.
+ \value Fixed The main widget's size is set to tqsizeHint(); it
+ cannot be resized at all.
+ \value Minimum The main widget's minimum size is set to
+ tqminimumSize(); it cannot be smaller.
+ \value FreeResize The widget is not constrained.
+*/
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \property TQLayout::resizeMode
+ \brief the resize mode of the tqlayout
+
+ The default mode is \c Auto.
+
+ \sa TQLayout::ResizeMode
+*/
+
+void TQLayout::setResizeMode( ResizeMode mode )
+{
+ if ( mode == resizeMode() )
+ return;
+
+ switch ( mode ) {
+ case Auto:
+ frozen = FALSE;
+ autoMinimum = FALSE;
+ autoResizeMode = TRUE;
+ break;
+ case Fixed:
+ frozen = TRUE;
+ autoMinimum = FALSE;
+ autoResizeMode = FALSE;
+ break;
+ case FreeResize:
+ frozen = FALSE;
+ autoMinimum = FALSE;
+ autoResizeMode = FALSE;
+ break;
+ case Minimum:
+ frozen = FALSE;
+ autoMinimum = TRUE;
+ autoResizeMode = FALSE;
+ }
+ if ( mainWidget() && mainWidget()->isVisible() )
+ activate();
+}
+
+TQLayout::ResizeMode TQLayout::resizeMode() const
+{
+ return ( autoResizeMode ? Auto :
+ (frozen ? Fixed : (autoMinimum ? Minimum : FreeResize)) );
+}
+
+/*!
+ \fn bool TQLayout::autoAdd() const
+
+ Returns TRUE if this tqlayout automatically grabs all new
+ mainWidget()'s new tqchildren and adds them as defined by addItem();
+ otherwise returns FALSE. This has effect only for top-level
+ layouts, i.e. layouts that are direct tqchildren of their
+ mainWidget().
+
+ autoAdd() is disabled by default.
+
+ Note that a top-level tqlayout is not necessarily associated with
+ the top-level widget.
+
+ \sa setAutoAdd()
+*/
+
+/*!
+ If \a b is TRUE, auto-add is enabled; otherwise auto-add is
+ disabled.
+
+ \warning If auto-add is enabled, you cannot set stretch factors
+ on the child widgets until the widgets are actually inserted in
+ the tqlayout (after control returned to the event loop). We
+ therefore recommend that you avoid the auto-add feature in new
+ programs.
+
+ \sa autoAdd()
+*/
+void TQLayout::setAutoAdd( bool b )
+{
+ autoNewChild = b;
+}
+
+/*!
+ \fn bool TQLayout::supportsMargin() const
+
+ Returns TRUE if this tqlayout supports \l TQLayout::margin on
+ non-top-level layouts; otherwise returns FALSE.
+
+ \sa margin
+*/
+
+/*!
+ Sets the value returned by supportsMargin(). If \a b is TRUE,
+ margin() handling is implemented by the subclass. If \a b is
+ FALSE (the default), TQLayout will add margin() around top-level
+ layouts.
+
+ If \a b is TRUE, margin handling needs to be implemented in
+ setGeometry(), tqmaximumSize(), tqminimumSize(), tqsizeHint() and
+ heightForWidth().
+
+ \sa supportsMargin()
+*/
+void TQLayout::setSupportsMargin( bool b )
+{
+ marginImpl = b;
+}
+
+/*!
+ Returns the rectangle that should be covered when the tqgeometry of
+ this tqlayout is set to \a r, provided that this tqlayout supports
+ tqsetAlignment().
+
+ The result is derived from tqsizeHint() and expandingDirections(). It is never
+ larger than \a r.
+*/
+TQRect TQLayout::alignmentRect( const TQRect &r ) const
+{
+ TQSize s = tqsizeHint();
+ int a = tqalignment();
+
+ /*
+ This is a hack to obtain the real maximum size, not
+ TQSize(TQLAYOUTSIZE_MAX, TQLAYOUTSIZE_MAX), the value consistently
+ returned by TQLayoutItems that have an tqalignment.
+ */
+ TQLayout *that = (TQLayout *) this;
+ that->tqsetAlignment( 0 );
+ TQSize ms = tqmaximumSize();
+ that->tqsetAlignment( a );
+
+ if ( (expandingDirections() & TQSizePolicy::Horizontally) ||
+ !(a & TQt::AlignHorizontal_Mask ) ) {
+ s.setWidth( TQMIN(r.width(), ms.width()) );
+ }
+ if ( (expandingDirections() & TQSizePolicy::Vertically) ||
+ !(a & TQt::AlignVertical_Mask) ) {
+ s.setHeight( TQMIN(r.height(), ms.height()) );
+ } else if ( hasHeightForWidth() ) {
+ int hfw = heightForWidth( s.width() );
+ if ( hfw < s.height() )
+ s.setHeight( TQMIN(hfw, ms.height()) );
+ }
+
+ int x = r.x();
+ int y = r.y();
+
+ if ( a & TQt::AlignBottom )
+ y += ( r.height() - s.height() );
+ else if ( !(a & TQt::AlignTop) )
+ y += ( r.height() - s.height() ) / 2;
+
+ a = TQApplication::horizontalAlignment( a );
+ if ( a & TQt::AlignRight )
+ x += ( r.width() - s.width() );
+ else if ( !(a & TQt::AlignLeft) )
+ x += ( r.width() - s.width() ) / 2;
+
+ return TQRect( x, y, s.width(), s.height() );
+}
+
+/*!
+ Removes the widget \a widget from the tqlayout. After this call, it
+ is the caller's responsibility to give the widget a reasonable
+ tqgeometry or to put the widget back into a tqlayout.
+
+ \sa removeItem(), TQWidget::setGeometry(), add()
+*/
+void TQLayout::remove( TQWidget *widget )
+{
+ TQLayoutIterator it = iterator();
+ TQLayoutItem *child;
+ while ( (child = it.current()) != 0 ) {
+ if ( child->widget() == widget ) {
+ it.deleteCurrent();
+ tqinvalidate(); // maybe redundant
+ TQApplication::postEvent( mainWidget(),
+ new TQEvent(TQEvent::LayoutHint) );
+ } else {
+ ++it;
+ }
+ }
+}
+
+/*!
+ Removes the tqlayout item \a item from the tqlayout. It is the
+ caller's responsibility to delete the item.
+
+ Notice that \a item can be a tqlayout (since TQLayout inherits
+ TQLayoutItem).
+
+ \sa remove(), addItem()
+*/
+void TQLayout::removeItem( TQLayoutItem *item )
+{
+ TQLayoutIterator it = iterator();
+ TQLayoutItem *child;
+ while ( (child = it.current()) != 0 ) {
+ if ( child == item ) {
+ it.takeCurrent();
+ tqinvalidate(); // maybe redundant
+ TQApplication::postEvent( mainWidget(),
+ new TQEvent(TQEvent::LayoutHint) );
+ } else {
+ ++it;
+ }
+ }
+}
+
+/*!
+ Enables this tqlayout if \a enable is TRUE, otherwise disables it.
+
+ An enabled tqlayout adjusts dynamically to changes; a disabled
+ tqlayout acts as if it did not exist.
+
+ By default all layouts are enabled.
+
+ \sa isEnabled()
+*/
+void TQLayout::setEnabled( bool enable )
+{
+ enabled = enable;
+}
+
+/*!
+ Returns TRUE if the tqlayout is enabled; otherwise returns FALSE.
+
+ \sa setEnabled()
+*/
+bool TQLayout::isEnabled() const
+{
+ return enabled;
+}
+
+void TQLayout::propagateSpacing( TQLayout *tqparent )
+{
+ TQLayoutIterator it = tqparent->iterator();
+ TQLayoutItem *child;
+ while ( (child = it.current()) ) {
+ TQLayout *childLayout = child->tqlayout();
+ if ( childLayout && childLayout->insideSpacing < 0 ) {
+ childLayout->insideSpacing = tqparent->insideSpacing;
+ propagateSpacing( childLayout );
+ }
+ ++it;
+ }
+}
+
+#endif // USE_QT4
+
+#endif // TQT_NO_LAYOUT
diff --git a/tqtinterface/qt4/src/kernel/tqabstractlayout.h b/tqtinterface/qt4/src/kernel/tqabstractlayout.h
new file mode 100644
index 0000000..4ae84f6
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqabstractlayout.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Definition of tqlayout classes
+**
+** Created : 960416
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQABSTRACTLAYOUT_H
+#define TQABSTRACTLAYOUT_H
+
+/*
+ This header is provided for source compatibility only.
+*/
+
+#ifndef TQT_H
+#ifndef TQT_NO_COMPAT
+#include "tqlayout.h"
+#endif
+#endif // TQT_H
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqaccel.cpp b/tqtinterface/qt4/src/kernel/tqaccel.cpp
new file mode 100644
index 0000000..fd47345
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqaccel.cpp
@@ -0,0 +1,2098 @@
+#include "tqtglobaldefines.h"
+
+#if 0
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqaccel.h"
+
+#include "tqsignal.h"
+#include "Qt/qapplication.h"
+#include "Qt/qwidget.h"
+#include "tqptrlist.h"
+#include "Qt/qwhatsthis.h"
+#include "Qt/qpointer.h"
+#include "Qt/qstatusbar.h"
+#include "Qt/qdockwidget.h"
+#include "Qt/qevent.h"
+#include "Qt/qkeysequence.h"
+// #include "private/qapplication_p.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt;
+
+/*!
+ \class TQAccel
+ \brief The TQAccel class handles keyboard accelerator and shortcut keys.
+
+ \compat
+
+ A keyboard accelerator triggers an action when a certain key
+ combination is pressed. The accelerator handles all keyboard
+ activity for all the children of one top-level widget, so it is
+ not affected by the keyboard focus.
+
+ In most cases, you will not need to use this class directly. Use
+ the QAction class to create actions with accelerators that can be
+ used in both menus and toolbars. If you're only interested in
+ menus use Q3MenuData::insertItem() or Q3MenuData::setAccel() to make
+ accelerators for operations that are also available on menus. Many
+ widgets automatically generate accelerators, such as QAbstractButton,
+ QGroupBox, QLabel (with QLabel::setBuddy()), QMenuBar, and QTabBar.
+ Example:
+ \snippet doc/src/snippets/code/src_qt3support_other_q3accel.cpp 0
+
+ A TQAccel tqcontains a list of accelerator items that can be
+ manipulated using insertItem(), removeItem(), clear(), key() and
+ findKey().
+
+ Each accelerator item consists of an identifier and a \l
+ QKeySequence. A single key sequence consists of a keyboard code
+ combined with modifiers (Qt::SHIFT, Qt::CTRL, Qt::ALT, or
+ Qt::UNICODE_ACCEL). For example, Qt::CTRL + Qt::Key_P could be a shortcut
+ for printing a document. As an alternative, use Qt::UNICODE_ACCEL with the
+ tqunicode code point of the character. For example, Qt::UNICODE_ACCEL
+ + 'A' gives the same accelerator as Qt::Key_A.
+
+ When an accelerator key is pressed, the accelerator sends out the
+ signal activated() with a number that identifies this particular
+ accelerator item. Accelerator items can also be individually
+ connected, so that two different keys will activate two different
+ Q_SLOTS (see connectItem() and disconnectItem()).
+
+ The activated() signal is \e not emitted when two or more
+ accelerators match the same key. Instead, the first matching
+ accelerator sends out the activatedAmbiguously() signal. By
+ pressing the key multiple times, users can navigate between all
+ matching accelerators. Some standard controls like QPushButton and
+ QCheckBox connect the activatedAmbiguously() signal to the
+ harmless setFocus() slot, whereas activated() is connected to a
+ slot invoking the button's action. Most controls, like QLabel and
+ QTabBar, treat activated() and activatedAmbiguously() as
+ equivalent.
+
+ Use setEnabled() to enable or disable all the items in an
+ accelerator, or setItemEnabled() to enable or disable individual
+ items. An item is active only when both the TQAccel and the item
+ itself are enabled.
+
+ The function setWhatsThis() specifies a help text that appears
+ when the user presses an accelerator key in What's This mode.
+
+ The accelerator will be deleted when \e parent is deleted,
+ and will consume relevant key events until then.
+
+ Please note that the accelerator
+ \snippet doc/src/snippets/code/src_qt3support_other_q3accel.cpp 1
+ can be triggered with both the 'M' key, and with Shift+M,
+ unless a second accelerator is defined for the Shift+M
+ combination.
+
+
+ Example:
+ \snippet doc/src/snippets/code/src_qt3support_other_q3accel.cpp 2
+
+ \sa QKeyEvent QWidget::keyPressEvent()
+ QAbstractButton::setAccel() QLabel::setBuddy() QKeySequence
+*/
+
+
+struct TQAccelItem { // internal accelerator item
+ TQAccelItem(const QKeySequence &k, int i)
+ { key=k; id=i; enabled=true; signal=0; }
+ ~TQAccelItem() { delete signal; }
+ int id;
+ QKeySequence key;
+ bool enabled;
+ TQSignal *signal;
+ QString whatsthis;
+};
+
+
+typedef TQPtrList<TQAccelItem> TQAccelList; // internal accelerator list
+
+class TQAccelPrivate {
+public:
+ TQAccelPrivate(TQAccel* p);
+ ~TQAccelPrivate();
+ TQAccelList aitems;
+ bool enabled;
+ QPointer<QWidget> watch;
+ bool ignorewhatsthis;
+ TQAccel* parent;
+
+ void activate(TQAccelItem* item);
+ void activateAmbiguously(TQAccelItem* item);
+};
+
+class TQAccelManager {
+public:
+ static TQAccelManager* self() { return self_ptr ? self_ptr : new TQAccelManager; }
+ void registerAccel(TQAccelPrivate* a) { accels.append(a); }
+ void unregisterAccel(TQAccelPrivate* a) { accels.removeRef(a); if (accels.isEmpty()) delete this; }
+ bool tryAccelEvent(QWidget* w, QKeyEvent* e);
+ bool dispatchAccelEvent(QWidget* w, QKeyEvent* e);
+ bool tryComposeUnicode(QWidget* w, QKeyEvent* e);
+
+private:
+ TQAccelManager()
+ : currentState(QKeySequence::NoMatch), clash(-1), metaComposeUnicode(false),composedUnicode(0)
+ { setFuncPtr(); self_ptr = this; }
+ ~TQAccelManager() { self_ptr = 0; }
+ void setFuncPtr();
+
+ bool correctSubWindow(QWidget *w, TQAccelPrivate* d);
+ QKeySequence::SequenceMatch match(QKeyEvent* e, TQAccelItem* item, QKeySequence& temp);
+ int translateModifiers(ButtonState state);
+
+ TQPtrList<TQAccelPrivate> accels;
+ static TQAccelManager* self_ptr;
+ QKeySequence::SequenceMatch currentState;
+ QKeySequence intermediate;
+ int clash;
+ bool metaComposeUnicode;
+ int composedUnicode;
+};
+TQAccelManager* TQAccelManager::self_ptr = 0;
+
+bool Q_COMPAT_EXPORT qt_tryAccelEvent(QWidget* w, QKeyEvent* e){
+ return TQAccelManager::self()->tryAccelEvent(w, e);
+}
+
+bool Q_COMPAT_EXPORT qt_dispatchAccelEvent(QWidget* w, QKeyEvent* e){
+ return TQAccelManager::self()->dispatchAccelEvent(w, e);
+}
+
+bool Q_COMPAT_EXPORT qt_tryComposeUnicode(QWidget* w, QKeyEvent* e){
+ return TQAccelManager::self()->tryComposeUnicode(w, e);
+}
+
+void TQAccelManager::setFuncPtr() {
+ if (qApp->d_func()->qt_compat_used)
+ return;
+ QApplicationPrivate *data = static_cast<QApplicationPrivate*>(qApp->d_ptr.data());
+ data->qt_tryAccelEvent = qt_tryAccelEvent;
+ data->qt_tryComposeUnicode = qt_tryComposeUnicode;
+ data->qt_dispatchAccelEvent = qt_dispatchAccelEvent;
+ data->qt_compat_used = true;
+}
+
+#ifdef Q_WS_MAC
+static bool qt_accel_no_shortcuts = true;
+#else
+static bool qt_accel_no_shortcuts = false;
+#endif
+void Q_COMPAT_EXPORT qt_set_accel_auto_shortcuts(bool b) { qt_accel_no_shortcuts = b; }
+
+/*
+ \internal
+ Returns true if the accel is in the current subwindow, else false.
+*/
+bool TQAccelManager::correctSubWindow(QWidget* w, TQAccelPrivate* d) {
+#if !defined (Q_OS_MACX)
+ if (!d->watch || !d->watch->isVisible() || !d->watch->isEnabled())
+#else
+ if (!d->watch || (!d->watch->isVisible() && !d->watch->inherits("QMenuBar")) || !d->watch->isEnabled())
+#endif
+ return false;
+ QWidget* tlw = w->window();
+ QWidget* wtlw = d->watch->window();
+
+ /* if we live in a floating dock window, keep our parent's
+ * accelerators working */
+#ifndef QT_NO_MAINWINDOW
+ if ((tlw->windowType() == Qt::Dialog) && tlw->parentWidget() && qobject_cast<QDockWidget*>(tlw))
+ return tlw->parentWidget()->window() == wtlw;
+
+ if (wtlw != tlw)
+ return false;
+#endif
+ /* if we live in a MDI subwindow, ignore the event if we are
+ not the active document window */
+ QWidget* sw = d->watch;
+ while (sw && sw->windowType() != Qt::SubWindow)
+ sw = sw->parentWidget(true);
+ if (sw) { // we are in a subwindow indeed
+ QWidget* fw = w;
+ while (fw && fw != sw)
+ fw = fw->parentWidget(true);
+ if (fw != sw) // focus widget not in our subwindow
+ return false;
+ }
+ return true;
+}
+
+inline int TQAccelManager::translateModifiers(ButtonState state)
+{
+ int result = 0;
+ if (state & ShiftButton)
+ result |= SHIFT;
+ if (state & ControlButton)
+ result |= CTRL;
+ if (state & MetaButton)
+ result |= META;
+ if (state & AltButton)
+ result |= ALT;
+ return result;
+}
+
+/*
+ \internal
+ Matches the current intermediate key sequence + the latest
+ keyevent, with and AccelItem. Returns Identical,
+ PartialMatch or NoMatch, and fills \a temp with the
+ resulting key sequence.
+*/
+QKeySequence::SequenceMatch TQAccelManager::match(QKeyEvent *e, TQAccelItem* item, QKeySequence& temp)
+{
+ QKeySequence::SequenceMatch result = QKeySequence::NoMatch;
+ int index = intermediate.count();
+ temp = intermediate;
+
+ int modifier = translateModifiers(e->state());
+
+ if (e->key() && e->key() != Key_unknown) {
+ int key = e->key() | modifier;
+ if (e->key() == Key_BackTab) {
+ /*
+ In QApplication, we map shift+tab to shift+backtab.
+ This code here reverts the mapping in a way that keeps
+ backtab and shift+tab accelerators working, in that
+ order, meaning backtab has priority.*/
+ key &= ~SHIFT;
+
+ temp.setKey(key, index);
+ if (QKeySequence::NoMatch != (result = temp.matches(item->key)))
+ return result;
+ if (e->state() & ShiftButton)
+ key |= SHIFT;
+ key = Key_Tab | (key & MODIFIER_MASK);
+ temp.setKey(key, index);
+ if (QKeySequence::NoMatch != (result = temp.matches(item->key)))
+ return result;
+ } else {
+ temp.setKey(key, index);
+ if (QKeySequence::NoMatch != (result = temp.matches(item->key)))
+ return result;
+ }
+
+ if (key == Key_BackTab) {
+ if (e->state() & ShiftButton)
+ key |= SHIFT;
+ temp.setKey(key, index);
+ if (QKeySequence::NoMatch != (result = temp.matches(item->key)))
+ return result;
+ }
+ }
+ if (!e->text().isEmpty()) {
+ temp.setKey((int)e->text()[0].tqunicode() | UNICODE_ACCEL | modifier, index);
+ result = temp.matches(item->key);
+ }
+ return result;
+}
+
+bool TQAccelManager::tryAccelEvent(QWidget* w, QKeyEvent* e)
+{
+ if (QKeySequence::NoMatch == currentState) {
+ e->t = QEvent::AccelOverride;
+ e->ignore();
+ QApplication::sendSpontaneousEvent(w, e);
+ if (e->isAccepted())
+ return false;
+ }
+ e->t = QEvent::Accel;
+ e->ignore();
+ QApplication::sendSpontaneousEvent(w, e);
+ return e->isAccepted();
+}
+
+bool TQAccelManager::tryComposeUnicode(QWidget* w, QKeyEvent* e)
+{
+ if (metaComposeUnicode) {
+ int value = e->key() - Key_0;
+ // Ignore acceloverrides so we don't trigger
+ // accels on keypad when Meta compose is on
+ if ((e->type() == QEvent::AccelOverride) &&
+ (e->state() == Qt::Keypad + Qt::MetaButton)) {
+ e->accept();
+ // Meta compose start/continue
+ } else if ((e->type() == QEvent::KeyPress) &&
+ (e->state() == Qt::Keypad + Qt::MetaButton)) {
+ if (value >= 0 && value <= 9) {
+ composedUnicode *= 10;
+ composedUnicode += value;
+ return true;
+ } else {
+ // Composing interrupted, dispatch!
+ if (composedUnicode) {
+ QChar ch(composedUnicode);
+ QString s(ch);
+ QKeyEvent kep(QEvent::KeyPress, 0, ch.row() ? 0 : ch.cell(), 0, s);
+ QKeyEvent ker(QEvent::KeyRelease, 0, ch.row() ? 0 : ch.cell(), 0, s);
+ QApplication::sendEvent(w, &kep);
+ QApplication::sendEvent(w, &ker);
+ }
+ composedUnicode = 0;
+ return true;
+ }
+ // Meta compose end, dispatch
+ } else if ((e->type() == QEvent::KeyRelease) &&
+ (e->key() == Key_Meta) &&
+ (composedUnicode != 0)) {
+ if ((composedUnicode > 0) &&
+ (composedUnicode < 0xFFFE)) {
+ QChar ch(composedUnicode);
+ QString s(ch);
+ QKeyEvent kep(QEvent::KeyPress, 0, ch.row() ? 0 : ch.cell(), 0, s);
+ QKeyEvent ker(QEvent::KeyRelease, 0, ch.row() ? 0 : ch.cell(), 0, s);
+ QApplication::sendEvent(w, &kep);
+ QApplication::sendEvent(w, &ker);
+ }
+ composedUnicode = 0;
+ return true;
+ }
+ }
+ return false;
+}
+
+/*
+ \internal
+ Checks for possible accelerators, if no widget
+ ate the keypres, or we are in the middle of a
+ partial key sequence.
+*/
+bool TQAccelManager::dispatchAccelEvent(QWidget* w, QKeyEvent* e)
+{
+#ifndef QT_NO_STATUSBAR
+ // Needs to be declared and used here because of "goto doclash"
+ QStatusBar* mainStatusBar = 0;
+#endif
+
+ // Modifiers can NOT be accelerators...
+ if (e->key() >= Key_Shift &&
+ e->key() <= Key_Alt)
+ return false;
+
+ QKeySequence::SequenceMatch result = QKeySequence::NoMatch;
+ QKeySequence tocheck, partial;
+ TQAccelPrivate* accel = 0;
+ TQAccelItem* item = 0;
+ TQAccelPrivate* firstaccel = 0;
+ TQAccelItem* firstitem = 0;
+ TQAccelPrivate* lastaccel = 0;
+ TQAccelItem* lastitem = 0;
+
+ QKeyEvent pe = *e;
+ int n = -1;
+ int hasShift = (e->state()&Qt::ShiftButton)?1:0;
+ bool identicalDisabled = false;
+ bool matchFound = false;
+ do {
+ accel = accels.first();
+ matchFound = false;
+ while (accel) {
+ if (correctSubWindow(w, accel)) {
+ if (accel->enabled) {
+ item = accel->aitems.last();
+ while(item) {
+ if (QKeySequence::Identical == (result = match(&pe, item, tocheck))) {
+ if (item->enabled) {
+ if (!firstaccel) {
+ firstaccel = accel;
+ firstitem = item;
+ }
+ lastaccel = accel;
+ lastitem = item;
+ n++;
+ matchFound = true;
+ if (n > QMAX(clash,0))
+ goto doclash;
+ } else {
+ identicalDisabled = true;
+ }
+ }
+ if (item->enabled && QKeySequence::PartialMatch == result) {
+ partial = tocheck;
+ matchFound = true;
+ }
+ item = accel->aitems.prev();
+ }
+ } else {
+ item = accel->aitems.last();
+ while(item) {
+ if (QKeySequence::Identical == match(&pe, item, tocheck))
+ identicalDisabled = true;
+ item = accel->aitems.prev();
+ }
+ }
+ }
+ accel = accels.next();
+ }
+ pe = QKeyEvent(QEvent::Accel, pe.key(), pe.ascii(), pe.state()&~Qt::ShiftButton, pe.text());
+ } while (hasShift-- && !matchFound && !identicalDisabled);
+
+#ifndef QT_NO_STATUSBAR
+ mainStatusBar = (QStatusBar*) w->window()->child(0, "QStatusBar");
+#endif
+ if (n < 0) { // no match found
+ currentState = partial.count() ? QKeySequence::PartialMatch : QKeySequence::NoMatch;
+#ifndef QT_NO_STATUSBAR
+ // Only display message if we are, or were, in a partial match
+ if (mainStatusBar && (QKeySequence::PartialMatch == currentState || intermediate.count())) {
+ if (currentState == QKeySequence::PartialMatch) {
+ mainStatusBar->showMessage((QString)partial + QLatin1String(", ..."));
+ } else if (!identicalDisabled) {
+ QString message = TQAccel::tr("%1, %2 not defined").
+ arg((QString)intermediate).
+ arg(QKeySequence::encodeString(e->key() | translateModifiers(e->state())));
+ mainStatusBar->showMessage(message, 2000);
+ // Since we're a NoMatch, reset the clash count
+ clash = -1;
+ } else {
+ mainStatusBar->clearMessage();
+ }
+ }
+#endif
+
+ bool eatKey = (QKeySequence::PartialMatch == currentState || intermediate.count());
+ intermediate = partial;
+ if (eatKey)
+ e->accept();
+ return eatKey;
+ } else if (n == 0) { // found exactly one match
+ clash = -1; // reset
+#ifndef QT_NO_STATUSBAR
+ if (currentState == QKeySequence::PartialMatch && mainStatusBar)
+ mainStatusBar->clearMessage();
+#endif
+ currentState = QKeySequence::NoMatch; // Free sequence keylock
+ intermediate = QKeySequence();
+ lastaccel->activate(lastitem);
+ e->accept();
+ return true;
+ }
+
+ doclash: // found more than one match
+#ifndef QT_NO_STATUSBAR
+ if (!mainStatusBar) // if "goto doclash", we need to get status bar again.
+ mainStatusBar = (QStatusBar*) w->window()->child(0, "QStatusBar");
+#endif
+
+ QString message = TQAccel::tr("Ambiguous %1 not handled").arg((QString)tocheck);
+ if (clash >= 0 && n > clash) { // pick next match
+ intermediate = QKeySequence();
+ currentState = QKeySequence::NoMatch; // Free sequence keylock
+ clash++;
+#ifndef QT_NO_STATUSBAR
+ if (mainStatusBar &&
+ !lastitem->signal &&
+ !(lastaccel->parent->tqreceivers(SIGNAL(activatedAmbiguously(int)))))
+ mainStatusBar->showMessage(message, 2000);
+#endif
+ lastaccel->activateAmbiguously(lastitem);
+ } else { // start (or wrap) with the first matching
+ intermediate = QKeySequence();
+ currentState = QKeySequence::NoMatch; // Free sequence keylock
+ clash = 0;
+#ifndef QT_NO_STATUSBAR
+ if (mainStatusBar &&
+ !firstitem->signal &&
+ !(firstaccel->parent->tqreceivers(SIGNAL(activatedAmbiguously(int)))))
+ mainStatusBar->showMessage(message, 2000);
+#endif
+ firstaccel->activateAmbiguously(firstitem);
+ }
+ e->accept();
+ return true;
+}
+
+TQAccelPrivate::TQAccelPrivate(TQAccel* p)
+ : parent(p)
+{
+ TQAccelManager::self()->registerAccel(this);
+ aitems.setAutoDelete(true);
+ ignorewhatsthis = false;
+}
+
+TQAccelPrivate::~TQAccelPrivate()
+{
+ TQAccelManager::self()->unregisterAccel(this);
+}
+
+static TQAccelItem *find_id(TQAccelList &list, int id)
+{
+ register TQAccelItem *item = list.first();
+ while (item && item->id != id)
+ item = list.next();
+ return item;
+}
+
+static TQAccelItem *find_key(TQAccelList &list, const QKeySequence &key)
+{
+ register TQAccelItem *item = list.first();
+ while (item && !(item->key == key))
+ item = list.next();
+ return item;
+}
+
+/*!
+ Constructs a TQAccel object called \a name, with parent \a parent.
+ The accelerator operates on \a parent.
+*/
+
+TQAccel::TQAccel(QWidget *parent, const char *name)
+ : TQT_BASE_OBJECT_NAME(parent, name)
+{
+ d = new TQAccelPrivate(this);
+ d->enabled = true;
+ d->watch = parent;
+#if defined(QT_CHECK_NULL)
+ if (!d->watch)
+ qWarning("TQAccel: An accelerator must have a parent or a watch widget");
+#endif
+}
+
+/*!
+ Constructs a TQAccel object called \a name, that operates on \a
+ watch, and is a child of \a parent.
+
+ This constructor is not needed for normal application programming.
+*/
+TQAccel::TQAccel(QWidget* watch, TQT_BASE_OBJECT_NAME *parent, const char *name)
+ : TQT_BASE_OBJECT_NAME(parent, name)
+{
+ d = new TQAccelPrivate(this);
+ d->enabled = true;
+ d->watch = watch;
+#if defined(QT_CHECK_NULL)
+ if (!d->watch)
+ qWarning("TQAccel: An accelerator must have a parent or a watch widget");
+#endif
+}
+
+/*!
+ Destroys the accelerator object and frees all allocated resources.
+*/
+
+TQAccel::~TQAccel()
+{
+ delete d;
+}
+
+
+/*!
+ \fn void TQAccel::activated(int id)
+
+ This signal is emitted when the user types the shortcut's key
+ sequence. \a id is a number that identifies this particular
+ accelerator item.
+
+ \sa activatedAmbiguously()
+*/
+
+/*!
+ \fn void TQAccel::activatedAmbiguously(int id)
+
+ This signal is emitted when the user types a shortcut key
+ sequence that is ambiguous. For example, if one key sequence is a
+ "prefix" for another and the user types these keys it isn't clear
+ if they want the shorter key sequence, or if they're about to
+ type more to complete the longer key sequence. \a id is a number
+ that identifies this particular accelerator item.
+
+ \sa activated()
+*/
+
+/*!
+ Returns true if the accelerator is enabled; otherwise returns
+ false.
+
+ \sa setEnabled(), isItemEnabled()
+*/
+
+bool TQAccel::isEnabled() const
+{
+ return d->enabled;
+}
+
+
+/*!
+ Enables the accelerator if \a enable is true, or disables it if \a
+ enable is false.
+
+ Individual keys can also be enabled or disabled using
+ setItemEnabled(). To work, a key must be an enabled item in an
+ enabled TQAccel.
+
+ \sa isEnabled(), setItemEnabled()
+*/
+
+void TQAccel::setEnabled(bool enable)
+{
+ d->enabled = enable;
+}
+
+
+/*!
+ Returns the number of accelerator items in this accelerator.
+*/
+
+uint TQAccel::count() const
+{
+ return d->aitems.count();
+}
+
+
+static int get_seq_id()
+{
+ static int seq_no = -2; // -1 is used as return value in findKey()
+ return seq_no--;
+}
+
+/*!
+ Inserts an accelerator item and returns the item's identifier.
+
+ \a key is a key code and an optional combination of SHIFT, CTRL
+ and ALT. \a id is the accelerator item id.
+
+ If \a id is negative, then the item will be assigned a unique
+ negative identifier less than -1.
+
+ \snippet doc/src/snippets/code/src_qt3support_other_q3accel.cpp 3
+*/
+
+int TQAccel::insertItem(const QKeySequence& key, int id)
+{
+ if (id == -1)
+ id = get_seq_id();
+ d->aitems.insert(0, new TQAccelItem(key,id));
+ return id;
+}
+
+/*!
+ Removes the accelerator item with the identifier \a id.
+*/
+
+void TQAccel::removeItem(int id)
+{
+ if (find_id(d->aitems, id))
+ d->aitems.remove();
+}
+
+
+/*!
+ Removes all accelerator items.
+*/
+
+void TQAccel::clear()
+{
+ d->aitems.clear();
+}
+
+
+/*!
+ Returns the key sequence of the accelerator item with identifier
+ \a id, or an invalid key sequence (0) if the id cannot be found.
+*/
+
+QKeySequence TQAccel::key(int id)
+{
+ TQAccelItem *item = find_id(d->aitems, id);
+ return item ? item->key : QKeySequence(0);
+}
+
+
+/*!
+ Returns the identifier of the accelerator item with the key code
+ \a key, or -1 if the item cannot be found.
+*/
+
+int TQAccel::findKey(const QKeySequence& key) const
+{
+ TQAccelItem *item = find_key(d->aitems, key);
+ return item ? item->id : -1;
+}
+
+
+/*!
+ Returns true if the accelerator item with the identifier \a id is
+ enabled. Returns false if the item is disabled or cannot be found.
+
+ \sa setItemEnabled(), isEnabled()
+*/
+
+bool TQAccel::isItemEnabled(int id) const
+{
+ TQAccelItem *item = find_id(d->aitems, id);
+ return item ? item->enabled : false;
+}
+
+
+/*!
+ Enables the accelerator item with the identifier \a id if \a
+ enable is true, and disables item \a id if \a enable is false.
+
+ To work, an item must be enabled and be in an enabled TQAccel.
+
+ \sa isItemEnabled(), isEnabled()
+*/
+
+void TQAccel::setItemEnabled(int id, bool enable)
+{
+ TQAccelItem *item = find_id(d->aitems, id);
+ if (item)
+ item->enabled = enable;
+}
+
+
+/*!
+ Connects the accelerator item \a id to the slot \a member of \a
+ receiver. Returns true if the connection is successful.
+
+ \snippet doc/src/snippets/code/src_qt3support_other_q3accel.cpp 4
+
+ Of course, you can also send a signal as \a member.
+
+ Normally accelerators are connected to Q_SLOTS which then receive
+ the \c activated(int id) signal with the id of the accelerator
+ item that was activated. If you choose to connect a specific
+ accelerator item using this function, the \c activated() signal is
+ emitted if the associated key sequence is pressed but no \c
+ activated(int id) signal is emitted.
+
+ \sa disconnectItem(), TQT_BASE_OBJECT_NAME::connect()
+*/
+
+bool TQAccel::connectItem(int id, const TQT_BASE_OBJECT_NAME *receiver, const char *member)
+{
+ TQAccelItem *item = find_id(d->aitems, id);
+ if (item) {
+ if (!item->signal) {
+ item->signal = new TQSignal;
+ Q_CHECK_PTR(item->signal);
+ }
+ return item->signal->connect(receiver, member);
+ }
+ return false;
+}
+
+/*!
+ Disconnects the accelerator item identified by \a id from
+ the function called \a member in the \a receiver object.
+ Returns true if the connection existed and the disconnect
+ was successful.
+
+ \sa connectItem(), TQT_BASE_OBJECT_NAME::disconnect()
+*/
+
+bool TQAccel::disconnectItem(int id, const TQT_BASE_OBJECT_NAME *receiver,
+ const char *member)
+{
+ TQAccelItem *item = find_id(d->aitems, id);
+ if (item && item->signal)
+ return item->signal->disconnect(receiver, member);
+ return false;
+}
+
+void TQAccelPrivate::activate(TQAccelItem* item)
+{
+#ifndef QT_NO_WHATSTHIS
+ if (QWhatsThis::inWhatsThisMode() && !ignorewhatsthis) {
+ QWhatsThis::showText(QCursor::pos(), item->whatsthis);
+ return;
+ }
+#endif
+ if (item->signal)
+ item->signal->activate();
+ else
+ emit parent->activated(item->id);
+}
+
+void TQAccelPrivate::activateAmbiguously(TQAccelItem* item)
+{
+ if (item->signal)
+ item->signal->activate();
+ else
+ emit parent->activatedAmbiguously(item->id);
+}
+
+
+/*!
+ Returns the shortcut key sequence for \a str, or an invalid key
+ sequence (0) if \a str has no shortcut sequence.
+
+ For example, shortcutKey("E&xit") returns QKeySequence(Qt::ALT +
+ Qt::Key_X), shortcutKey("&Quit") returns QKeySequence(Qt::ALT +
+ Qt::Key_Q), and shortcutKey("Quit") returns QKeySequence().
+*/
+
+QKeySequence TQAccel::shortcutKey(const QString &str)
+{
+ if(qt_accel_no_shortcuts)
+ return QKeySequence();
+
+ int p = 0;
+ while (p >= 0) {
+ p = str.find(QLatin1Char('&'), p) + 1;
+ if (p <= 0 || p >= (int)str.length())
+ return 0;
+ if (str[p] != QLatin1Char('&')) {
+ QChar c = str[p];
+ if (c.isPrint()) {
+ char ltr = c.upper().latin1();
+ if (ltr >= (char)Key_A && ltr <= (char)Key_Z)
+ c = QLatin1Char(ltr);
+ else
+ c = c.lower();
+ return QKeySequence(c.tqunicode() + ALT + UNICODE_ACCEL);
+ }
+ }
+ p++;
+ }
+ return QKeySequence();
+}
+
+/*! \obsolete
+
+ Creates an accelerator string for the key \a k.
+ For instance CTRL+Key_O gives "Ctrl+O". The "Ctrl" etc.
+ are translated (using TQT_BASE_OBJECT_NAME::tr()) in the "TQAccel" context.
+
+ The function is superfluous. Cast the QKeySequence \a k to a
+ QString for the same effect.
+*/
+QString TQAccel::keyToString(QKeySequence k)
+{
+ return (QString) k;
+}
+
+/*!\obsolete
+
+ Returns an accelerator code for the string \a s. For example
+ "Ctrl+O" gives CTRL+UNICODE_ACCEL+'O'. The strings "Ctrl",
+ "Shift", "Alt" are recognized, as well as their translated
+ equivalents in the "TQAccel" context (using TQT_BASE_OBJECT_NAME::tr()). Returns 0
+ if \a s is not recognized.
+
+ This function is typically used with \link TQT_BASE_OBJECT_NAME::tr() tr
+ \endlink(), so that accelerator keys can be tqreplaced in
+ translations:
+
+ \snippet doc/src/snippets/code/src_qt3support_other_q3accel.cpp 5
+
+ Notice the "File|Open" translator comment. It is by no means
+ necessary, but it provides some context for the human translator.
+
+ The function is superfluous. Construct a QKeySequence from the
+ string \a s for the same effect.
+
+ \sa TQT_BASE_OBJECT_NAME::tr(), {Internationalization with Qt}
+*/
+QKeySequence TQAccel::stringToKey(const QString & s)
+{
+ return QKeySequence(s);
+}
+
+
+/*!
+ Sets a What's This help text for the accelerator item \a id to \a
+ text.
+
+ The text will be shown when the application is in What's This mode
+ and the user hits the accelerator key.
+
+ To set What's This help on a menu item (with or without an
+ accelerator key), use Q3MenuData::setWhatsThis().
+
+ \sa whatsThis(), QWhatsThis::inWhatsThisMode(), QAction::setWhatsThis()
+*/
+void TQAccel::setWhatsThis(int id, const QString& text)
+{
+ TQAccelItem *item = find_id(d->aitems, id);
+ if (item)
+ item->whatsthis = text;
+}
+
+/*!
+ Returns the What's This help text for the specified item \a id or
+ an empty string if no text has been specified.
+
+ \sa setWhatsThis()
+*/
+QString TQAccel::whatsThis(int id) const
+{
+
+ TQAccelItem *item = find_id(d->aitems, id);
+ return item? item->whatsthis : QString();
+}
+
+/*!\internal */
+void TQAccel::setIgnoreWhatsThis(bool b)
+{
+ d->ignorewhatsthis = b;
+}
+
+/*!\internal */
+bool TQAccel::ignoreWhatsThis() const
+{
+ return d->ignorewhatsthis;
+}
+
+/*!
+ \fn void TQAccel::repairEventFilter()
+ \internal
+*/
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of TQAccel class
+**
+** Created : 950419
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqaccel.h"
+
+#ifndef TQT_NO_ACCEL
+
+#include "tqsignal.h"
+#include "tqapplication.h"
+#include "tqwidget.h"
+#include "tqptrlist.h"
+#include "tqwhatsthis.h"
+#include "tqguardedptr.h"
+#include "tqstatusbar.h"
+#include "tqdockwindow.h"
+#include "tqsignalslotimp.h"
+/*!
+ \class TQAccel tqaccel.h
+ \brief The TQAccel class handles keyboard accelerator and shortcut keys.
+
+ \ingroup misc
+
+ A keyboard accelerator triggers an action when a certain key
+ combination is pressed. The accelerator handles all keyboard
+ activity for all the tqchildren of one top-level widget, so it is
+ not affected by the keyboard focus.
+
+ In most cases, you will not need to use this class directly. Use
+ the TQAction class to create actions with accelerators that can be
+ used in both menus and toolbars. If you're only interested in
+ menus use TQMenuData::insertItem() or TQMenuData::setAccel() to make
+ accelerators for operations that are also available on menus. Many
+ widgets automatically generate accelerators, such as TQButton,
+ TQGroupBox, TQLabel (with TQLabel::setBuddy()), TQMenuBar and TQTabBar.
+ Example:
+ \code
+ TQPushButton p( "&Exit", tqparent ); // automatic shortcut ALT+Key_E
+ TQPopupMenu *fileMenu = new fileMenu( tqparent );
+ fileMenu->insertItem( "Undo", tqparent, TQT_SLOT(undo()), CTRL+Key_Z );
+ \endcode
+
+ A TQAccel tqcontains a list of accelerator items that can be
+ manipulated using insertItem(), removeItem(), clear(), key() and
+ tqfindKey().
+
+ Each accelerator item consists of an identifier and a \l
+ TQKeySequence. A single key sequence consists of a keyboard code
+ combined with modifiers (\c SHIFT, \c CTRL, \c ALT or \c
+ UNICODE_ACCEL). For example, \c{CTRL + Key_P} could be a shortcut
+ for printing a document. The key codes are listed in \c
+ tqnamespace.h. As an alternative, use \c UNICODE_ACCEL with the
+ tqunicode code point of the character. For example, \c{UNICODE_ACCEL
+ + 'A'} gives the same accelerator as \c Key_A.
+
+ When an accelerator key is pressed, the accelerator sends out the
+ signal activated() with a number that identifies this particular
+ accelerator item. Accelerator items can also be individually
+ connected, so that two different keys will activate two different
+ Q_SLOTS (see connectItem() and disconnectItem()).
+
+ The activated() signal is \e not emitted when two or more
+ accelerators match the same key. Instead, the first matching
+ accelerator sends out the activatedAmbiguously() signal. By
+ pressing the key multiple times, users can navigate between all
+ matching accelerators. Some standard controls like TQPushButton and
+ TQCheckBox connect the activatedAmbiguously() signal to the
+ harmless setFocus() slot, whereas activated() is connected to a
+ slot invoking the button's action. Most controls, like TQLabel and
+ TQTabBar, treat activated() and activatedAmbiguously() as
+ equivalent.
+
+ Use setEnabled() to enable or disable all the items in an
+ accelerator, or setItemEnabled() to enable or disable individual
+ items. An item is active only when both the TQAccel and the item
+ itself are enabled.
+
+ The function setWhatsThis() specifies a help text that appears
+ when the user presses an accelerator key in What's This mode.
+
+ The accelerator will be deleted when \e tqparent is deleted,
+ and will consume relevant key events until then.
+
+ Please note that the accelerator
+ \code
+ accelerator->insertItem( TQKeySequence("M") );
+ \endcode
+ can be triggered with both the 'M' key, and with Shift+M,
+ unless a second accelerator is defined for the Shift+M
+ combination.
+
+
+ Example:
+ \code
+ TQAccel *a = new TQAccel( myWindow ); // create accels for myWindow
+ a->connectItem( a->insertItem(Key_P+CTRL), // adds Ctrl+P accelerator
+ myWindow, // connected to myWindow's
+ TQT_SLOT(printDoc()) ); // printDoc() slot
+ \endcode
+
+ \sa TQKeyEvent TQWidget::keyPressEvent() TQMenuData::setAccel()
+ TQButton::setAccel() TQLabel::setBuddy() TQKeySequence
+ \link guibooks.html#fowler GUI Design Handbook: Keyboard Shortcuts \endlink.
+*/
+
+
+struct TQAccelItem { // internal accelerator item
+ TQAccelItem( const TQKeySequence &k, int i )
+ { key=k; id=i; enabled=TRUE; signal=0; }
+ ~TQAccelItem() { delete signal; }
+ int id;
+ TQKeySequence key;
+ bool enabled;
+ TQSignal *signal;
+ TQString whatsthis;
+};
+
+
+typedef TQPtrList<TQAccelItem> TQAccelList; // internal accelerator list
+
+class TQAccelPrivate : public TQt {
+public:
+ TQAccelPrivate( TQAccel* p );
+ ~TQAccelPrivate();
+ TQAccelList aitems;
+ bool enabled;
+ TQGuardedPtr<TQWidget> watch;
+ bool ignorewhatsthis;
+ TQAccel* tqparent;
+
+ void activate( TQAccelItem* item );
+ void activateAmbiguously( TQAccelItem* item );
+};
+
+class TQAccelManager : public TQt {
+public:
+ static TQAccelManager* self() { return self_ptr ? self_ptr : new TQAccelManager; }
+ void registerAccel( TQAccelPrivate* a ) { accels.append( a ); }
+ void unregisterAccel( TQAccelPrivate* a ) { accels.removeRef( a ); if ( accels.isEmpty() ) delete this; }
+ bool tryAccelEvent( TQWidget* w, TQKeyEvent* e );
+ bool dispatchAccelEvent( TQWidget* w, TQKeyEvent* e );
+ bool tryComposeUnicode( TQWidget* w, TQKeyEvent* e );
+
+private:
+ TQAccelManager():currentState(TQt::NoMatch), clash(-1) { self_ptr = this; }
+ ~TQAccelManager() { self_ptr = 0; }
+
+ bool correctSubWindow( TQWidget *w, TQAccelPrivate* d );
+ SequenceMatch match( TQKeyEvent* e, TQAccelItem* item, TQKeySequence& temp );
+ int translateModifiers( ButtonState state );
+
+ TQPtrList<TQAccelPrivate> accels;
+ static TQAccelManager* self_ptr;
+ TQt::SequenceMatch currentState;
+ TQKeySequence intermediate;
+ int clash;
+};
+TQAccelManager* TQAccelManager::self_ptr = 0;
+
+bool TQ_EXPORT qt_tryAccelEvent( TQWidget* w, TQKeyEvent* e){
+ return TQAccelManager::self()->tryAccelEvent( w, e );
+}
+
+bool TQ_EXPORT qt_dispatchAccelEvent( TQWidget* w, TQKeyEvent* e){
+ return TQAccelManager::self()->dispatchAccelEvent( w, e );
+}
+
+bool TQ_EXPORT qt_tryComposeUnicode( TQWidget* w, TQKeyEvent* e){
+ return TQAccelManager::self()->tryComposeUnicode( w, e );
+}
+
+#ifdef TQ_WS_MAC
+static bool qt_accel_no_shortcuts = TRUE;
+#else
+static bool qt_accel_no_shortcuts = FALSE;
+#endif
+void TQ_EXPORT qt_setAccelAutoShortcuts(bool b) { qt_accel_no_shortcuts = b; }
+
+/*
+ \internal
+ Returns TRUE if the accel is in the current subwindow, else FALSE.
+*/
+bool TQAccelManager::correctSubWindow( TQWidget* w, TQAccelPrivate* d ) {
+#if !defined ( TQ_OS_MACX )
+ if ( !d->watch || !d->watch->isVisible() || !d->watch->isEnabled() )
+#else
+ if ( !d->watch || (!d->watch->isVisible() && !d->watch->inherits( "TQMenuBar" )) || !d->watch->isEnabled() )
+#endif
+ return FALSE;
+ TQWidget* tlw = w->tqtopLevelWidget();
+ TQWidget* wtlw = d->watch->tqtopLevelWidget();
+
+ /* if we live in a floating dock window, keep our tqparent's
+ * accelerators working */
+#ifndef TQT_NO_MAINWINDOW
+ if ( tlw->isDialog() && tlw->parentWidget() && ::tqqt_cast<TQDockWindow*>(tlw) ) // [FIXME] Can I safely use the TQT_TQOBJECT macro here?
+ return tlw->parentWidget()->tqtopLevelWidget() == wtlw;
+
+ if ( wtlw != tlw )
+ return FALSE;
+#endif
+ /* if we live in a MDI subwindow, ignore the event if we are
+ not the active document window */
+ TQWidget* sw = d->watch;
+ while ( sw && !sw->testWFlags( WSubWindow ) )
+ sw = sw->parentWidget( TRUE );
+ if ( sw ) { // we are in a subwindow indeed
+ TQWidget* fw = w;
+ while ( fw && fw != sw )
+ fw = fw->parentWidget( TRUE );
+ if ( fw != sw ) // focus widget not in our subwindow
+ return FALSE;
+ }
+ return TRUE;
+}
+
+inline int TQAccelManager::translateModifiers( ButtonState state )
+{
+ int result = 0;
+ if ( state & ShiftButton )
+ result |= SHIFT;
+ if ( state & ControlButton )
+ result |= CTRL;
+ if ( state & MetaButton )
+ result |= META;
+ if ( state & AltButton )
+ result |= ALT;
+ return result;
+}
+
+/*
+ \internal
+ Matches the current intermediate key sequence + the latest
+ keyevent, with and AccelItem. Returns Identical,
+ PartialMatch or NoMatch, and fills \a temp with the
+ resulting key sequence.
+*/
+TQt::SequenceMatch TQAccelManager::match( TQKeyEvent *e, TQAccelItem* item, TQKeySequence& temp )
+{
+ SequenceMatch result = TQt::NoMatch;
+ int index = intermediate.count();
+ temp = intermediate;
+
+ int modifier = translateModifiers( e->state() );
+
+ if ( e->key() && e->key() != Key_unknown) {
+ int key = e->key() | modifier;
+ if ( e->key() == Key_BackTab ) {
+ /*
+ In TQApplication, we map shift+tab to shift+backtab.
+ This code here reverts the mapping in a way that keeps
+ backtab and shift+tab accelerators working, in that
+ order, meaning backtab has priority.*/
+ key &= ~SHIFT;
+
+ temp.setKey( key, index );
+ if ( TQt::NoMatch != (result = temp.matches( item->key )) )
+ return result;
+ if ( e->state() & ShiftButton )
+ key |= SHIFT;
+ key = Key_Tab | ( key & MODIFIER_MASK );
+ temp.setKey( key, index );
+ if ( TQt::NoMatch != (result = temp.matches( item->key )) )
+ return result;
+ } else {
+ temp.setKey( key, index );
+ if ( TQt::NoMatch != (result = temp.matches( item->key )) )
+ return result;
+ }
+
+ if ( key == Key_BackTab ) {
+ if ( e->state() & ShiftButton )
+ key |= SHIFT;
+ temp.setKey( key, index );
+ if ( TQt::NoMatch != (result = temp.matches( item->key )) )
+ return result;
+ }
+ }
+ if ( !e->text().isEmpty() ) {
+ temp.setKey( (int)e->text()[0].unicode() | UNICODE_ACCEL | modifier, index );
+ result = temp.matches( item->key );
+ }
+ return result;
+}
+
+bool TQAccelManager::tryAccelEvent( TQWidget* w, TQKeyEvent* e )
+{
+ if ( TQt::NoMatch == currentState ) {
+ e->t = TQEvent::AccelOverride;
+ e->ignore();
+ TQAccel::sendSpontaneousKeyEvent( TQT_TQOBJECT(w), e );
+ if ( e->isAccepted() )
+ return FALSE;
+ }
+ e->t = TQEvent::Accel;
+ e->ignore();
+ TQAccel::sendSpontaneousKeyEvent( TQT_TQOBJECT(w), e );
+ return e->isAccepted();
+}
+
+bool TQAccelManager::tryComposeUnicode( TQWidget* w, TQKeyEvent* e )
+{
+ if ( TQApplication::metaComposeUnicode ) {
+ int value = e->key() - Key_0;
+ // Ignore acceloverrides so we don't trigger
+ // accels on keypad when Meta compose is on
+ if ( (e->type() == TQEvent::AccelOverride) &&
+ (e->state() == TQt::Keypad + TQt::MetaButton) ) {
+ e->accept();
+ // Meta compose start/continue
+ } else if ( (e->type() == TQEvent::KeyPress) &&
+ (e->state() == TQt::Keypad + TQt::MetaButton) ) {
+ if ( value >= 0 && value <= 9 ) {
+ TQApplication::composedUnicode *= 10;
+ TQApplication::composedUnicode += value;
+ return TRUE;
+ } else {
+ // Composing interrupted, dispatch!
+ if ( TQApplication::composedUnicode ) {
+ TQChar ch( TQApplication::composedUnicode );
+ TQString s( ch );
+ TQKeyEvent kep( TQEvent::KeyPress, 0, ch.row() ? 0 : ch.cell(), 0, s );
+ TQKeyEvent ker( TQEvent::KeyRelease, 0, ch.row() ? 0 : ch.cell(), 0, s );
+ TQApplication::sendEvent( w, &kep );
+ TQApplication::sendEvent( w, &ker );
+ }
+ TQApplication::composedUnicode = 0;
+ return TRUE;
+ }
+ // Meta compose end, dispatch
+ } else if ( (e->type() == TQEvent::KeyRelease) &&
+ (e->key() == Key_Meta) &&
+ (TQApplication::composedUnicode != 0) ) {
+ if ( (TQApplication::composedUnicode > 0) &&
+ (TQApplication::composedUnicode < 0xFFFE) ) {
+ TQChar ch( TQApplication::composedUnicode );
+ TQString s( ch );
+ TQKeyEvent kep( TQEvent::KeyPress, 0, ch.row() ? 0 : ch.cell(), 0, s );
+ TQKeyEvent ker( TQEvent::KeyRelease, 0, ch.row() ? 0 : ch.cell(), 0, s );
+ TQApplication::sendEvent( w, &kep );
+ TQApplication::sendEvent( w, &ker );
+ }
+ TQApplication::composedUnicode = 0;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*
+ \internal
+ Checks for possible accelerators, if no widget
+ ate the keypres, or we are in the middle of a
+ partial key sequence.
+*/
+bool TQAccelManager::dispatchAccelEvent( TQWidget* w, TQKeyEvent* e )
+{
+#ifndef TQT_NO_STATUSBAR
+ // Needs to be declared and used here because of "goto doclash"
+ TQStatusBar* maintqStatusBar = 0;
+#endif
+
+ // Modifiers can NOT be accelerators...
+ if ( e->key() >= Key_Shift &&
+ e->key() <= Key_Alt )
+ return FALSE;
+
+ SequenceMatch result = TQt::NoMatch;
+ TQKeySequence tocheck, partial;
+ TQAccelPrivate* accel = 0;
+ TQAccelItem* item = 0;
+ TQAccelPrivate* firstaccel = 0;
+ TQAccelItem* firstitem = 0;
+ TQAccelPrivate* lastaccel = 0;
+ TQAccelItem* lastitem = 0;
+
+ TQKeyEvent pe = *e;
+ int n = -1;
+ int hasShift = (e->state()&ShiftButton)?1:0;
+ bool identicalDisabled = FALSE;
+ bool matchFound = FALSE;
+ do {
+ accel = accels.first();
+ matchFound = FALSE;
+ while ( accel ) {
+ if ( correctSubWindow( w, accel ) ) {
+ if ( accel->enabled ) {
+ item = accel->aitems.last();
+ while( item ) {
+ if ( TQt::Identical == (result = match( &pe, item, tocheck )) ) {
+ if ( item->enabled ) {
+ if ( !firstaccel ) {
+ firstaccel = accel;
+ firstitem = item;
+ }
+ lastaccel = accel;
+ lastitem = item;
+ n++;
+ matchFound = TRUE;
+ if ( n > TQMAX(clash,0) )
+ goto doclash;
+ } else {
+ identicalDisabled = TRUE;
+ }
+ }
+ if ( item->enabled && TQt::PartialMatch == result ) {
+ partial = tocheck;
+ matchFound = TRUE;
+ }
+ item = accel->aitems.prev();
+ }
+ } else {
+ item = accel->aitems.last();
+ while( item ) {
+ if ( TQt::Identical == match( &pe, item, tocheck ) )
+ identicalDisabled = TRUE;
+ item = accel->aitems.prev();
+ }
+ }
+ }
+ accel = accels.next();
+ }
+ pe = TQKeyEvent( TQEvent::Accel, pe.key(), pe.ascii(), pe.state()&~ShiftButton, pe.text() );
+ } while ( hasShift-- && !matchFound && !identicalDisabled );
+
+#ifndef TQT_NO_STATUSBAR
+ maintqStatusBar = (TQStatusBar*) w->tqtopLevelWidget()->child( 0, "TQStatusBar" );
+#endif
+ if ( n < 0 ) { // no match found
+ currentState = partial.count() ? PartialMatch : NoMatch;
+#ifndef TQT_NO_STATUSBAR
+ // Only display message if we are, or were, in a partial match
+ if ( maintqStatusBar && (PartialMatch == currentState || intermediate.count() ) ) {
+ if ( currentState == TQt::PartialMatch ) {
+ maintqStatusBar->message( (TQString)partial + ", ...", 0 );
+ } else if (!identicalDisabled) {
+ TQString message = TQAccel::tr("%1, %2 not defined").
+ arg( (TQString)intermediate ).
+ arg( TQKeySequence::encodeString( e->key() | translateModifiers(e->state()) ) );
+ maintqStatusBar->message( message, 2000 );
+ // Since we're a NoMatch, reset the clash count
+ clash = -1;
+ } else {
+ maintqStatusBar->clear();
+ }
+ }
+#endif
+
+ bool eatKey = (PartialMatch == currentState || intermediate.count() );
+ intermediate = partial;
+ if ( eatKey )
+ e->accept();
+ return eatKey;
+ } else if ( n == 0 ) { // found exactly one match
+ clash = -1; // reset
+#ifndef TQT_NO_STATUSBAR
+ if ( currentState == TQt::PartialMatch && maintqStatusBar )
+ maintqStatusBar->clear();
+#endif
+ currentState = TQt::NoMatch; // Free sequence keylock
+ intermediate = TQKeySequence();
+ lastaccel->activate( lastitem );
+ e->accept();
+ return TRUE;
+ }
+
+ doclash: // found more than one match
+#ifndef TQT_NO_STATUSBAR
+ if ( !maintqStatusBar ) // if "goto doclash", we need to get statusbar again.
+ maintqStatusBar = (TQStatusBar*) w->tqtopLevelWidget()->child( 0, "TQStatusBar" );
+#endif
+
+ TQString message = TQAccel::tr( "Ambiguous \"%1\" not handled" ).arg( (TQString)tocheck );
+ if ( clash >= 0 && n > clash ) { // pick next match
+ intermediate = TQKeySequence();
+ currentState = TQt::NoMatch; // Free sequence keylock
+ clash++;
+#ifndef TQT_NO_STATUSBAR
+ if ( maintqStatusBar &&
+ !lastitem->signal &&
+ !(lastaccel->tqparent->tqreceivers( "activatedAmbiguously(int)" )) )
+ maintqStatusBar->message( message, 2000 );
+#endif
+ lastaccel->activateAmbiguously( lastitem );
+ } else { // start (or wrap) with the first matching
+ intermediate = TQKeySequence();
+ currentState = TQt::NoMatch; // Free sequence keylock
+ clash = 0;
+#ifndef TQT_NO_STATUSBAR
+ if ( maintqStatusBar &&
+ !firstitem->signal &&
+ !(firstaccel->tqparent->tqreceivers( "activatedAmbiguously(int)" )) )
+ maintqStatusBar->message( message, 2000 );
+#endif
+ firstaccel->activateAmbiguously( firstitem );
+ }
+ e->accept();
+ return TRUE;
+}
+
+TQAccelPrivate::TQAccelPrivate( TQAccel* p )
+ : tqparent( p )
+{
+ TQAccelManager::self()->registerAccel( this );
+ aitems.setAutoDelete( TRUE );
+ ignorewhatsthis = FALSE;
+}
+
+TQAccelPrivate::~TQAccelPrivate()
+{
+ TQAccelManager::self()->unregisterAccel( this );
+}
+
+static TQAccelItem *tqfind_id( TQAccelList &list, int id )
+{
+ register TQAccelItem *item = list.first();
+ while ( item && item->id != id )
+ item = list.next();
+ return item;
+}
+
+static TQAccelItem *tqfind_key( TQAccelList &list, const TQKeySequence &key )
+{
+ register TQAccelItem *item = list.first();
+ while ( item && !( item->key == key ) )
+ item = list.next();
+ return item;
+}
+
+/*!
+ Constructs a TQAccel object called \a name, with tqparent \a tqparent.
+ The accelerator operates on \a tqparent.
+*/
+
+TQAccel::TQAccel( TQWidget *tqparent, const char *name )
+ : TQObject( TQT_TQOBJECT(tqparent), name )
+{
+ d = new TQAccelPrivate( this );
+ d->enabled = TRUE;
+ d->watch = tqparent;
+#if defined(TQT_CHECK_NULL)
+ if ( !d->watch )
+ qWarning( "TQAccel: An accelerator must have a tqparent or a watch widget" );
+#endif
+}
+
+/*!
+ Constructs a TQAccel object called \a name, that operates on \a
+ watch, and is a child of \a tqparent.
+
+ This constructor is not needed for normal application programming.
+*/
+TQAccel::TQAccel( TQWidget* watch, TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name )
+{
+ d = new TQAccelPrivate( this );
+ d->enabled = TRUE;
+ d->watch = watch;
+#if defined(TQT_CHECK_NULL)
+ if ( !d->watch )
+ qWarning( "TQAccel: An accelerator must have a tqparent or a watch widget" );
+#endif
+}
+
+/*!
+ Constructs a TQAccel object called \a name, that operates on \a
+ watch, and is a child of \a tqparent.
+
+ This constructor is not needed for normal application programming.
+*/
+TQAccel::TQAccel( TQWidget* watch, TQWidget *tqparent, const char *name )
+ : TQObject( TQT_TQOBJECT(tqparent), name )
+{
+ d = new TQAccelPrivate( this );
+ d->enabled = TRUE;
+ d->watch = watch;
+#if defined(TQT_CHECK_NULL)
+ if ( !d->watch )
+ qWarning( "TQAccel: An accelerator must have a tqparent or a watch widget" );
+#endif
+}
+
+/*!
+ Destroys the accelerator object and frees all allocated resources.
+*/
+
+TQAccel::~TQAccel()
+{
+ delete d;
+}
+
+
+/*!
+ \fn void TQAccel::activated( int id )
+
+ This signal is emitted when an accelerator key is pressed. \a id
+ is a number that identifies this particular accelerator item.
+
+ \sa activatedAmbiguously()
+*/
+
+/*!
+ \fn void TQAccel::activatedAmbiguously( int id )
+
+ This signal is emitted when an accelerator key is pressed. \a id
+ is a number that identifies this particular accelerator item.
+
+ \sa activated()
+*/
+
+
+/*!
+ Returns TRUE if the accelerator is enabled; otherwise returns
+ FALSE.
+
+ \sa setEnabled(), isItemEnabled()
+*/
+
+bool TQAccel::isEnabled() const
+{
+ return d->enabled;
+}
+
+
+/*!
+ Enables the accelerator if \a enable is TRUE, or disables it if \a
+ enable is FALSE.
+
+ Individual keys can also be enabled or disabled using
+ setItemEnabled(). To work, a key must be an enabled item in an
+ enabled TQAccel.
+
+ \sa isEnabled(), setItemEnabled()
+*/
+
+void TQAccel::setEnabled( bool enable )
+{
+ d->enabled = enable;
+}
+
+
+/*!
+ Returns the number of accelerator items in this accelerator.
+*/
+
+uint TQAccel::count() const
+{
+ return d->aitems.count();
+}
+
+
+static int get_seq_id()
+{
+ static int seq_no = -2; // -1 is used as return value in tqfindKey()
+ return seq_no--;
+}
+
+/*!
+ Inserts an accelerator item and returns the item's identifier.
+
+ \a key is a key code and an optional combination of SHIFT, CTRL
+ and ALT. \a id is the accelerator item id.
+
+ If \a id is negative, then the item will be assigned a unique
+ negative identifier less than -1.
+
+ \code
+ TQAccel *a = new TQAccel( myWindow ); // create accels for myWindow
+ a->insertItem( CTRL + Key_P, 200 ); // Ctrl+P, e.g. to print document
+ a->insertItem( ALT + Key_X, 201 ); // Alt+X, e.g. to quit
+ a->insertItem( UNICODE_ACCEL + 'q', 202 ); // Unicode 'q', e.g. to quit
+ a->insertItem( Key_D ); // gets a unique negative id < -1
+ a->insertItem( CTRL + SHIFT + Key_P ); // gets a unique negative id < -1
+ \endcode
+*/
+
+int TQAccel::insertItem( const TQKeySequence& key, int id )
+{
+ if ( id == -1 )
+ id = get_seq_id();
+ d->aitems.insert( 0, new TQAccelItem(key,id) );
+ return id;
+}
+
+/*!
+ Removes the accelerator item with the identifier \a id.
+*/
+
+void TQAccel::removeItem( int id )
+{
+ if ( tqfind_id( d->aitems, id) )
+ d->aitems.remove();
+}
+
+
+/*!
+ Removes all accelerator items.
+*/
+
+void TQAccel::clear()
+{
+ d->aitems.clear();
+}
+
+
+/*!
+ Returns the key sequence of the accelerator item with identifier
+ \a id, or an invalid key sequence (0) if the id cannot be found.
+*/
+
+TQKeySequence TQAccel::key( int id )
+{
+ TQAccelItem *item = tqfind_id( d->aitems, id);
+ return item ? item->key : TQKeySequence( 0 );
+}
+
+
+/*!
+ Returns the identifier of the accelerator item with the key code
+ \a key, or -1 if the item cannot be found.
+*/
+
+int TQAccel::tqfindKey( const TQKeySequence& key ) const
+{
+ TQAccelItem *item = tqfind_key( d->aitems, key );
+ return item ? item->id : -1;
+}
+
+
+/*!
+ Returns TRUE if the accelerator item with the identifier \a id is
+ enabled. Returns FALSE if the item is disabled or cannot be found.
+
+ \sa setItemEnabled(), isEnabled()
+*/
+
+bool TQAccel::isItemEnabled( int id ) const
+{
+ TQAccelItem *item = tqfind_id( d->aitems, id);
+ return item ? item->enabled : FALSE;
+}
+
+
+/*!
+ Enables the accelerator item with the identifier \a id if \a
+ enable is TRUE, and disables item \a id if \a enable is FALSE.
+
+ To work, an item must be enabled and be in an enabled TQAccel.
+
+ \sa isItemEnabled(), isEnabled()
+*/
+
+void TQAccel::setItemEnabled( int id, bool enable )
+{
+ TQAccelItem *item = tqfind_id( d->aitems, id);
+ if ( item )
+ item->enabled = enable;
+}
+
+
+/*!
+ Connects the accelerator item \a id to the slot \a member of \a
+ receiver.
+
+ \code
+ a->connectItem( 201, mainView, TQT_SLOT(quit()) );
+ \endcode
+
+ Of course, you can also send a signal as \a member.
+
+ Normally accelerators are connected to Q_SLOTS which then receive
+ the \c activated(int id) signal with the id of the accelerator
+ item that was activated. If you choose to connect a specific
+ accelerator item using this function, the \c activated() signal is
+ emitted if the associated key sequence is pressed but no \c
+ activated(int id) signal is emitted.
+
+ \sa disconnectItem()
+*/
+
+bool TQAccel::connectItem( int id, const TQT_BASE_OBJECT_NAME *receiver, const char *member )
+{
+ TQAccelItem *item = tqfind_id( d->aitems, id);
+ if ( item ) {
+ if ( !item->signal ) {
+ item->signal = new TQSignal;
+ TQ_CHECK_PTR( item->signal );
+ }
+ return item->signal->connect( receiver, member );
+ }
+ return FALSE;
+}
+
+/*!
+ Disconnects an accelerator item with id \a id from the function
+ called \a member in the \a receiver object.
+
+ \sa connectItem()
+*/
+
+bool TQAccel::disconnectItem( int id, const TQT_BASE_OBJECT_NAME *receiver,
+ const char *member )
+{
+ TQAccelItem *item = tqfind_id( d->aitems, id);
+ if ( item && item->signal )
+ return item->signal->disconnect( receiver, member );
+ return FALSE;
+}
+
+void TQAccelPrivate::activate( TQAccelItem* item )
+{
+#ifndef TQT_NO_WHATSTHIS
+ if ( TQWhatsThis::inWhatsThisMode() && !ignorewhatsthis ) {
+ TQWhatsThis::leaveWhatsThisMode( item->whatsthis );
+ return;
+ }
+#endif
+ if ( item->signal )
+ item->signal->activate();
+ else
+ emit tqparent->activated( item->id );
+}
+
+void TQAccelPrivate::activateAmbiguously( TQAccelItem* item )
+{
+ if ( item->signal )
+ item->signal->activate();
+ else
+ emit tqparent->activatedAmbiguously( item->id );
+}
+
+
+/*!
+ Returns the shortcut key sequence for \a str, or an invalid key
+ sequence (0) if \a str has no shortcut sequence.
+
+ For example, shortcutKey("E&amp;xit") returns ALT+Key_X,
+ shortcutKey("&amp;Quit") returns ALT+Key_Q and shortcutKey("Quit")
+ returns 0. (In code that does not inherit the TQt namespace class,
+ you must write e.g. TQt::ALT+TQt::Key_Q.)
+
+ We provide a \link accelerators.html list of common accelerators
+ \endlink in English. At the time of writing, Microsoft and Open
+ Group do not appear to have issued equivalent recommendations for
+ other languages.
+*/
+
+TQKeySequence TQAccel::shortcutKey( const TQString &str )
+{
+ if(qt_accel_no_shortcuts)
+ return TQKeySequence();
+
+ int p = 0;
+ while ( p >= 0 ) {
+ p = str.tqfind( '&', p ) + 1;
+ if ( p <= 0 || p >= (int)str.length() )
+ return 0;
+ if ( str[p] != '&' ) {
+ TQChar c = str[p];
+ if ( c.isPrint() ) {
+ char ltr = c.upper().latin1();
+ if ( ltr >= (char)Qt::Key_A && ltr <= (char)Qt::Key_Z )
+ c = ltr;
+ else
+ c = c.lower();
+ return TQKeySequence( c.tqunicode() + Qt::ALT + Qt::UNICODE_ACCEL );
+ }
+ }
+ p++;
+ }
+ return TQKeySequence();
+}
+
+/*! \obsolete
+
+ Creates an accelerator string for the key \a k.
+ For instance CTRL+Key_O gives "Ctrl+O". The "Ctrl" etc.
+ are translated (using TQObject::tr()) in the "TQAccel" context.
+
+ The function is superfluous. Cast the TQKeySequence \a k to a
+ TQString for the same effect.
+*/
+TQString TQAccel::keyToString( TQKeySequence k )
+{
+ return (TQString) k;
+}
+
+/*!\obsolete
+
+ Returns an accelerator code for the string \a s. For example
+ "Ctrl+O" gives CTRL+UNICODE_ACCEL+'O'. The strings "Ctrl",
+ "Shift", "Alt" are recognized, as well as their translated
+ equivalents in the "TQAccel" context (using TQObject::tr()). Returns 0
+ if \a s is not recognized.
+
+ This function is typically used with \link TQObject::tr() tr
+ \endlink(), so that accelerator keys can be tqreplaced in
+ translations:
+
+ \code
+ TQPopupMenu *file = new TQPopupMenu( this );
+ file->insertItem( p1, tr("&Open..."), this, TQT_SLOT(open()),
+ TQAccel::stringToKey(tr("Ctrl+O", "File|Open")) );
+ \endcode
+
+ Notice the \c "File|Open" translator comment. It is by no means
+ necessary, but it provides some context for the human translator.
+
+
+ The function is superfluous. Construct a TQKeySequence from the
+ string \a s for the same effect.
+
+ \sa TQObject::tr()
+ \link i18n.html Internationalization with TQt \endlink
+*/
+TQKeySequence TQAccel::stringToKey( const TQString & s )
+{
+ return TQKeySequence( s );
+}
+
+
+/*!
+ Sets a What's This help text for the accelerator item \a id to \a
+ text.
+
+ The text will be shown when the application is in What's This mode
+ and the user hits the accelerator key.
+
+ To set What's This help on a menu item (with or without an
+ accelerator key), use TQMenuData::setWhatsThis().
+
+ \sa whatsThis(), TQWhatsThis::inWhatsThisMode(),
+ TQMenuData::setWhatsThis(), TQAction::setWhatsThis()
+*/
+void TQAccel::setWhatsThis( int id, const TQString& text )
+{
+
+ TQAccelItem *item = tqfind_id( d->aitems, id);
+ if ( item )
+ item->whatsthis = text;
+}
+
+/*!
+ Returns the What's This help text for the specified item \a id or
+ TQString::null if no text has been specified.
+
+ \sa setWhatsThis()
+*/
+TQString TQAccel::whatsThis( int id ) const
+{
+
+ TQAccelItem *item = tqfind_id( d->aitems, id);
+ return item? item->whatsthis : TQString::null;
+}
+
+/*!\internal */
+void TQAccel::setIgnoreWhatsThis( bool b)
+{
+ d->ignorewhatsthis = b;
+}
+
+/*!\internal */
+bool TQAccel::ignoreWhatsThis() const
+{
+ return d->ignorewhatsthis;
+}
+
+
+/*!
+
+\page accelerators.html
+
+\title Standard Accelerator Keys
+
+Applications invariably need to define accelerator keys for actions.
+TQt fully supports accelerators, for example with \l TQAccel::shortcutKey().
+
+Here are Microsoft's recommendations for accelerator keys, with
+comments about the Open Group's recommendations where they exist
+and differ. For most commands, the Open Group either has no advice or
+agrees with Microsoft.
+
+The emboldened letter plus Alt is Microsoft's recommended choice, and
+we recommend supporting it. For an Apply button, for example, we
+recommend TQButton::setText( \link TQWidget::tr() tr \endlink("&amp;Apply") );
+
+If you have conflicting commands (e.g. About and Apply buttons in the
+same dialog), you must decide for yourself.
+
+\list
+\i <b><u>A</u></b>bout
+\i Always on <b><u>T</u></b>op
+\i <b><u>A</u></b>pply
+\i <b><u>B</u></b>ack
+\i <b><u>B</u></b>rowse
+\i <b><u>C</u></b>lose (CDE: Alt+F4; Alt+F4 is "close window" in Windows)
+\i <b><u>C</u></b>opy (CDE: Ctrl+C, Ctrl+Insert)
+\i <b><u>C</u></b>opy Here
+\i Create <b><u>S</u></b>hortcut
+\i Create <b><u>S</u></b>hortcut Here
+\i Cu<b><u>t</u></b>
+\i <b><u>D</u></b>elete
+\i <b><u>E</u></b>dit
+\i <b><u>E</u></b>xit (CDE: E<b><u>x</u></b>it)
+\i <b><u>E</u></b>xplore
+\i <b><u>F</u></b>ile
+\i <b><u>F</u></b>ind
+\i <b><u>H</u></b>elp
+\i Help <b><u>T</u></b>opics
+\i <b><u>H</u></b>ide
+\i <b><u>I</u></b>nsert
+\i Insert <b><u>O</u></b>bject
+\i <b><u>L</u></b>ink Here
+\i Ma<b><u>x</u></b>imize
+\i Mi<b><u>n</u></b>imize
+\i <b><u>M</u></b>ove
+\i <b><u>M</u></b>ove Here
+\i <b><u>N</u></b>ew
+\i <b><u>N</u></b>ext
+\i <b><u>N</u></b>o
+\i <b><u>O</u></b>pen
+\i Open <b><u>W</u></b>ith
+\i Page Set<b><u>u</u></b>p
+\i <b><u>P</u></b>aste
+\i Paste <b><u>L</u></b>ink
+\i Paste <b><u>S</u></b>hortcut
+\i Paste <b><u>S</u></b>pecial
+\i <b><u>P</u></b>ause
+\i <b><u>P</u></b>lay
+\i <b><u>P</u></b>rint
+\i <b><u>P</u></b>rint Here
+\i P<b><u>r</u></b>operties
+\i <b><u>Q</u></b>uick View
+\i <b><u>R</u></b>edo (CDE: Ctrl+Y, Shift+Alt+Backspace)
+\i <b><u>R</u></b>epeat
+\i <b><u>R</u></b>estore
+\i <b><u>R</u></b>esume
+\i <b><u>R</u></b>etry
+\i <b><u>R</u></b>un
+\i <b><u>S</u></b>ave
+\i Save <b><u>A</u></b>s
+\i Select <b><u>A</u></b>ll
+\i Se<b><u>n</u></b>d To
+\i <b><u>S</u></b>how
+\i <b><u>S</u></b>ize
+\i S<b><u>p</u></b>lit
+\i <b><u>S</u></b>top
+\i <b><u>U</u></b>ndo (CDE: Ctrl+Z or Alt+Backspace)
+\i <b><u>V</u></b>iew
+\i <b><u>W</u></b>hat's This?
+\i <b><u>W</u></b>indow
+\i <b><u>Y</u></b>es
+\endlist
+
+There are also a lot of other keys and actions (that use other
+modifier keys than Alt). See the Microsoft and The Open Group
+documentation for details.
+
+The \link http://www.amazon.com/exec/obidos/ASIN/0735605661/trolltech/t
+Microsoft book \endlink has ISBN 0735605661. The corresponding Open Group
+book is very hard to tqfind, rather expensive and we cannot recommend
+it. However, if you really want it, OGPubs@opengroup.org might be able
+to help. Ask them for ISBN 1859121047.
+
+*/
+
+/*! \obsolete serves no purpose anymore */
+void TQAccel::repairEventFilter() {}
+/*! \obsolete serves no purpose anymore */
+bool TQAccel::eventFilter( TQObject *, TQEvent * ) { return FALSE; }
+#endif // TQT_NO_ACCEL
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqaccel.h b/tqtinterface/qt4/src/kernel/tqaccel.h
new file mode 100644
index 0000000..d60a3b8
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqaccel.h
@@ -0,0 +1,238 @@
+#include "tqtglobaldefines.h"
+
+#if 0
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TQACCEL_H
+#define TQACCEL_H
+
+#include <QtCore/qobject.h>
+#include <QtGui/qkeysequence.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3SupportLight)
+
+class TQAccelPrivate;
+
+class Q_COMPAT_EXPORT TQAccel : public TQT_BASE_OBJECT_NAME // accelerator class
+{
+ Q_OBJECT
+public:
+ TQAccel( QWidget *parent, const char *name=0 );
+ TQAccel( QWidget* watch, TQT_BASE_OBJECT_NAME *parent, const char *name=0 );
+ ~TQAccel();
+
+ bool isEnabled() const;
+ void setEnabled( bool );
+
+ uint count() const;
+
+ int insertItem( const QKeySequence& key, int id=-1);
+ void removeItem( int id );
+ void clear();
+
+ QKeySequence key( int id );
+ int findKey( const QKeySequence& key ) const;
+
+ bool isItemEnabled( int id ) const;
+ void setItemEnabled( int id, bool enable );
+
+ bool connectItem( int id, const TQT_BASE_OBJECT_NAME *receiver, const char* member );
+ bool disconnectItem( int id, const TQT_BASE_OBJECT_NAME *receiver, const char* member );
+
+ void repairEventFilter() {}
+
+ void setWhatsThis( int id, const QString& );
+ QString whatsThis( int id ) const;
+ void setIgnoreWhatsThis( bool );
+ bool ignoreWhatsThis() const;
+
+ static QKeySequence shortcutKey( const QString & );
+ static QString keyToString(QKeySequence k );
+ static QKeySequence stringToKey( const QString & );
+
+Q_SIGNALS:
+ void activated( int id );
+ void activatedAmbiguously( int id );
+
+private:
+ TQAccelPrivate * d;
+
+private:
+ Q_DISABLE_COPY(TQAccel)
+ friend class TQAccelPrivate;
+ friend class TQAccelManager;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // TQACCEL_H
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Definition of TQAccel class
+**
+** Created : 950419
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQACCEL_H
+#define TQACCEL_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqkeysequence.h"
+#include "tqapplication.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_ACCEL
+
+class TQAccelPrivate;
+
+class TQ_EXPORT TQAccel : public TQObject // accelerator class
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQAccel( TQWidget *tqparent, const char *name=0 );
+ TQAccel( TQWidget* watch, TQObject *tqparent, const char *name=0 );
+ TQAccel( TQWidget* watch, TQWidget *tqparent, const char *name=0 );
+ ~TQAccel();
+
+ bool isEnabled() const;
+ void setEnabled( bool );
+
+ uint count() const;
+
+ int insertItem( const TQKeySequence& key, int id=-1);
+ void removeItem( int id );
+ void clear();
+
+ TQKeySequence key( int id );
+ int tqfindKey( const TQKeySequence& key ) const;
+
+ bool isItemEnabled( int id ) const;
+ void setItemEnabled( int id, bool enable );
+
+ bool connectItem( int id, const TQT_BASE_OBJECT_NAME *receiver, const char* member );
+ bool disconnectItem( int id, const TQT_BASE_OBJECT_NAME *receiver, const char* member );
+
+ void repairEventFilter();
+
+ void setWhatsThis( int id, const TQString& );
+ TQString whatsThis( int id ) const;
+ void setIgnoreWhatsThis( bool );
+ bool ignoreWhatsThis() const;
+
+ static TQKeySequence shortcutKey( const TQString & );
+ static TQString keyToString(TQKeySequence k );
+ static TQKeySequence stringToKey( const TQString & );
+
+Q_SIGNALS:
+ void activated( int id );
+ void activatedAmbiguously( int id );
+
+protected:
+ bool eventFilter( TQObject *, TQEvent * );
+
+private:
+ TQAccelPrivate * d;
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQAccel( const TQAccel & );
+ TQAccel &operator=( const TQAccel & );
+#endif
+ friend class TQAccelPrivate;
+ friend class TQAccelManager;
+
+public:
+ static bool sendSpontaneousKeyEvent( TQObject *receiver, TQKeyEvent *event );
+};
+
+inline bool TQAccel::sendSpontaneousKeyEvent( TQObject *receiver, TQKeyEvent *event )
+{ return tqApp ? tqApp->notify( receiver, event ) : FALSE; }
+
+#endif // TQT_NO_ACCEL
+#endif // TQACCEL_H
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqaccessible.cpp b/tqtinterface/qt4/src/kernel/tqaccessible.cpp
new file mode 100644
index 0000000..ba19cf7
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqaccessible.cpp
@@ -0,0 +1,719 @@
+/****************************************************************************
+**
+** Implementation of TQAccessible and TQAccessibleObject classes
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqaccessible.h"
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+
+#include "tqptrdict.h"
+#include "tqmetaobject.h"
+#include <private/tqpluginmanager_p.h>
+#include "tqapplication.h"
+#include <stdlib.h>
+
+/*!
+ \class TQAccessible tqaccessible.h
+ \brief The TQAccessible class provides enums and static functions
+ relating to accessibility.
+
+ \ingroup misc
+
+ Accessibility clients use implementations of the
+ TQAccessibleInterface to read the information an accessible object
+ exposes, or to call functions to manipulate the accessible object.
+
+\omit
+ TQt provides implementations of the TQAccessibleInterface for most
+ widget classes in a plugin. This plugin is located in the \e
+ accessibility subdirectory of the plugins installation directory.
+ The default installation directory for plugins is \c INSTALL/plugins,
+ where \c INSTALL is the directory where TQt was installed. Calling
+ queryAccessibleInterface( TQObject *object, TQAccessibleInterface
+ **iface ) will ask all plugins located in this directory for an
+ implementation that exposes the information for objects of the
+ class of \e object.
+
+ To make a TQt application accessible you have to distribute the
+ accessibility plugin provded with TQt together with your
+ application. Simply add the plugins created in
+ INSTALL/plugins/accessibility to your distribution process. Use \l
+ TQApplication::addLibraryPath() to specify a plugin directory for
+ your application, and copy the files into an \e accessibility
+ subdirectory of one of those plugin directories. TQt's
+ accessibility framework will load the plugins upon request and use
+ the implementations provided to expose an object's accessibility
+ information.
+\endomit
+
+ See the \link plugins-howto.html plugin documentation \endlink for
+ more details about how to redistribute TQt plugins.
+*/
+
+/*!
+ \enum TQAccessible::State
+
+ This enum type defines bitflags that can be combined to indicate
+ the state of the accessible object. The values are:
+
+ \value Normal
+ \value Unavailable
+ \value Selected
+ \value Focused
+ \value Pressed
+ \value Checked
+ \value Mixed
+ \value ReadOnly
+ \value HotTracked
+ \value Default
+ \value Expanded
+ \value Collapsed
+ \value Busy
+ \value Floating
+ \value Marqueed
+ \value Animated
+ \value Invisible
+ \value Offscreen
+ \value Sizeable
+ \value Moveable
+ \value SelfVoicing
+ \value Focusable
+ \value Selectable
+ \value Linked
+ \value Traversed
+ \value MultiSelectable
+ \value ExtSelectable
+ \value AlertLow
+ \value AlertMedium
+ \value AlertHigh
+ \value Protected
+ \value Valid
+*/
+
+/*!
+ \enum TQAccessible::Event
+
+ This enum type defines event types when the state of the
+ accessible object has changed. The event types are:
+
+ \value SoundPlayed
+ \value Alert
+ \value ForegroundChanged
+ \value MenuStart
+ \value MenuEnd
+ \value PopupMenuStart
+ \value PopupMenuEnd
+ \value ContextHelpStart
+ \value ContextHelpEnd
+ \value DragDropStart
+ \value DragDropEnd
+ \value DialogStart
+ \value DialogEnd
+ \value ScrollingStart
+ \value ScrollingEnd
+ \value ObjectCreated
+ \value ObjectDestroyed
+ \value ObjectShow
+ \value ObjectHide
+ \value ObjectReorder
+ \value Focus
+ \value Selection
+ \value SelectionAdd
+ \value SelectionRemove
+ \value SelectionWithin
+ \value StateChanged
+ \value LocationChanged
+ \value NameChanged
+ \value DescriptionChanged
+ \value ValueChanged
+ \value ParentChanged
+ \value HelpChanged
+ \value DefaultActionChanged
+ \value AcceleratorChanged
+ \value MenuCommand
+*/
+
+/*!
+ \enum TQAccessible::Role
+
+ This enum defines a number of roles an accessible object can have.
+ The roles are:
+
+ \value NoRole
+ \value TitleBar
+ \value MenuBar
+ \value ScrollBar
+ \value Grip
+ \value Sound
+ \value Cursor
+ \value Caret
+ \value AlertMessage
+ \value Window
+ \value Client
+ \value PopupMenu
+ \value MenuItem
+ \value ToolTip
+ \value Application
+ \value Document
+ \value Pane
+ \value Chart
+ \value Dialog
+ \value Border
+ \value Grouping
+ \value Separator
+ \value ToolBar
+ \value tqStatusBar
+ \value Table
+ \value ColumnHeader
+ \value RowHeader
+ \value Column
+ \value Row
+ \value Cell
+ \value Link
+ \value HelpBalloon
+ \value Character
+ \value List
+ \value ListItem
+ \value Outline
+ \value OutlineItem
+ \value PageTab
+ \value PropertyPage
+ \value Indicator
+ \value Graphic
+ \value StaticText
+ \value EditableText
+ \value PushButton
+ \value CheckBox
+ \value RadioButton
+ \value ComboBox
+ \value DropLest
+ \value ProgressBar
+ \value Dial
+ \value HotkeyField
+ \value Slider
+ \value SpinBox
+ \value Diagram
+ \value Animation
+ \value Equation
+ \value ButtonDropDown
+ \value ButtonMenu
+ \value ButtonDropGrid
+ \value Whitespace
+ \value PageTabList
+ \value Clock
+*/
+
+/*!
+ \enum TQAccessible::NavDirection
+
+ This enum specifies which item to move to when navigating.
+
+ \value NavUp sibling above
+ \value NavDown sibling below
+ \value NavLeft left sibling
+ \value NavRight right sibling
+ \value NavNext next sibling
+ \value NavPrevious previous sibling
+ \value NavFirstChild first child
+ \value NavLastChild last child
+ \value NavFocusChild child with focus
+*/
+
+/*!
+ \enum TQAccessible::Text
+
+ This enum specifies string information that an accessible object
+ returns.
+
+ \value Name The name of the object
+ \value Description A short text describing the object
+ \value Value The value of the object
+ \value Help A longer text giving information about how
+ to use the object
+ \value DefaultAction The default method to interact with the object
+ \value Accelerator The keyboard shortcut that executes the
+ default action
+*/
+
+/*!
+ \fn static void TQAccessible::updateAccessibility( TQObject *object, int control, Event reason )
+
+ Notifies accessibility clients about a change in \a object's
+ accessibility information.
+
+ \a reason specifies the cause of the change, for example,
+ ValueChange when the position of a slider has been changed. \a
+ control is the ID of the child element that has changed. When \a
+ control is 0, the object itself has changed.
+
+ Call this function whenever the state of your accessible object or
+ one of it's sub-elements has been changed either programmatically
+ (e.g. by calling TQLabel::setText()) or by user interaction.
+
+ If there are no accessibility tools listening to this event, the
+ performance penalty for calling this function is minor, but if determining
+ the parameters of the call is expensive you can use isActive() to
+ avoid unnecessary performance penalties if no client is listening.
+*/
+
+static TQPluginManager<TQAccessibleFactoryInterface> *qAccessibleManager = 0;
+
+class AccessibleCache : public TQObject, public TQPtrDict<TQAccessibleInterface>
+{
+ TQ_OBJECT
+public:
+ AccessibleCache()
+ : TQPtrDict<TQAccessibleInterface>(73)
+ {
+ }
+
+ void addObject(TQObject *object, TQAccessibleInterface *iface)
+ {
+ insert(object, iface);
+ connect(object, TQT_SIGNAL(destroyed(TQObject*)), this, TQT_SLOT(removeObject(TQObject*)));
+ }
+
+public Q_SLOTS:
+ void removeObject(TQObject *object);
+};
+
+#include "tqaccessible.tqmoc"
+
+static AccessibleCache *qAccessibleInterface = 0;
+static bool cleanupAdded = FALSE;
+
+static void qAccessibleCleanup()
+{
+ if ( qAccessibleInterface && qAccessibleInterface->count() && qAccessibleManager )
+ qAccessibleManager->setAutoUnload( FALSE );
+
+ delete qAccessibleInterface;
+ qAccessibleInterface = 0;
+ delete qAccessibleManager;
+ qAccessibleManager = 0;
+}
+
+#ifdef TQ_WS_MAC
+TQObject *TQAccessible::queryAccessibleObject(TQAccessibleInterface *o)
+{
+ if(qAccessibleInterface) {
+ for(TQPtrDictIterator<TQAccessibleInterface> it(*qAccessibleInterface); it.current(); ++it) {
+ if(it.current() == o)
+ return (TQObject*)it.currentKey();
+ }
+ }
+ return NULL;
+}
+#endif
+
+void AccessibleCache::removeObject(TQObject *object)
+{
+ if (!object)
+ return;
+
+ remove(object);
+ if (!count()) {
+ delete this;
+ qAccessibleInterface = 0;
+ }
+}
+
+
+/*!
+ Sets \a iface to point to the implementation of the
+ TQAccessibleInterface for \a object, and returns \c TQS_OK if
+ successfull, or sets \a iface to 0 and returns \c TQE_NOCOMPONENT if
+ no accessibility implementation for \a object exists.
+
+ The function uses the \link TQObject::className() classname
+ \endlink of \a object to tqfind a suitable implementation. If no
+ implementation for the object's class is available the function
+ tries to tqfind an implementation for the object's tqparent class.
+
+ This function is called to answer an accessibility client's
+ request for object information. You should never need to call this
+ function yourself.
+*/
+TQRESULT TQAccessible::queryAccessibleInterface( TQObject *object, TQAccessibleInterface **iface )
+{
+ *iface = 0;
+ if ( !object )
+ return TQE_INVALIDARG;
+
+ if ( qAccessibleInterface ) {
+ *iface = qAccessibleInterface->tqfind( object );
+ if ( *iface ) {
+ (*iface)->addRef();
+ return TQS_OK;
+ }
+ }
+
+ if ( !qAccessibleManager ) {
+ qAccessibleManager = new TQPluginManager<TQAccessibleFactoryInterface>( IID_TQAccessibleFactory, TQApplication::libraryPaths(), "/accessible" );
+ if ( !cleanupAdded ) {
+ qAddPostRoutine( qAccessibleCleanup );
+ cleanupAdded = TRUE;
+ }
+ }
+
+ TQInterfacePtr<TQAccessibleFactoryInterface> factory = 0;
+ TQMetaObject *mo = object->tqmetaObject();
+ while ( mo ) {
+ qAccessibleManager->queryInterface( mo->className(), &factory );
+ if ( factory )
+ break;
+ mo = mo->superClass();
+ }
+ if ( factory )
+ return factory->createAccessibleInterface( mo->className(), object, iface );
+
+ return TQE_NOCOMPONENT;
+}
+
+/*!
+ Returns TRUE if an accessibility implementation has been requested,
+ during the runtime of the application, otherwise returns FALSE.
+
+ Use this function to prevent potentially expensive notifications via
+ updateAccessibility().
+
+ \omit
+ TQListView uses this function to prevent index-lookups for item based
+ notifications.
+ \endomit
+*/
+bool TQAccessible::isActive()
+{
+ return qAccessibleManager != 0;
+}
+
+/*!
+ \class TQAccessibleInterface tqaccessible.h
+ \brief The TQAccessibleInterface class defines an interface that exposes information about accessible objects.
+
+ \ingroup misc
+*/
+
+/*!
+ \fn bool TQAccessibleInterface::isValid() const
+
+ Returns TRUE if all the data necessary to use this interface
+ implementation is valid (e.g. all pointers are non-null),
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn int TQAccessibleInterface::childCount() const
+
+ Returns the number of tqchildren that belong to this object. A child
+ can provide accessibility information on it's own (e.g. a child
+ widget), or be a sub-element of this accessible object.
+
+ All objects provide this information.
+
+ \sa queryChild()
+*/
+
+/*!
+ \fn TQRESULT TQAccessibleInterface::queryChild( int control, TQAccessibleInterface **iface ) const
+
+ Sets \a iface to point to the implementation of the
+ TQAccessibleInterface for the child specified with \a control. If
+ the child doesn't provide accessibility information on it's own,
+ the value of \a iface is set to 0. For those elements, this
+ object is responsible for exposing the child's properties.
+
+ All objects provide this information.
+
+ \sa childCount(), queryParent()
+*/
+
+/*!
+ \fn TQRESULT TQAccessibleInterface::queryParent( TQAccessibleInterface **iface ) const
+
+ Sets \a iface to point to the implementation of the
+ TQAccessibleInterface for the tqparent object, or to 0 if there is
+ no such implementation or object.
+
+ All objects provide this information.
+
+ \sa queryChild()
+*/
+
+/*!
+ \fn int TQAccessibleInterface::controlAt( int x, int y ) const
+
+ Returns the ID of the child that tqcontains the screen coordinates
+ (\a x, \a y). This function returns 0 if the point is positioned
+ on the object itself. If the tested point is outside the
+ boundaries of the object this function returns -1.
+
+ All visual objects provide this information.
+*/
+
+/*!
+ \fn TQRect TQAccessibleInterface::rect( int control ) const
+
+ Returns the location of the child specified with \a control in
+ screen coordinates. This function returns the location of the
+ object itself if \a control is 0.
+
+ All visual objects provide this information.
+*/
+
+/*!
+ \fn int TQAccessibleInterface::navigate( NavDirection direction, int startControl ) const
+
+ This function traverses to another object, or to a sub-element of
+ the current object. \a direction specifies in which direction to
+ navigate, and \a startControl specifies the start point of the
+ navigation, which is either 0 if the navigation starts at the
+ object itself, or an ID of one of the object's sub-elements.
+
+ The function returns the ID of the sub-element located in the \a
+ direction specified. If there is nothing in the navigated \a
+ direction, this function returns -1.
+
+ All objects support navigation.
+*/
+
+/*!
+ \fn TQString TQAccessibleInterface::text( Text t, int control ) const
+
+ Returns a string property \a t of the child object specified by \a
+ control, or the string property of the object itself if \a control
+ is 0.
+
+ The \e Name is a string used by clients to identify, tqfind or
+ announce an accessible object for the user. All objects must have
+ a name that is unique within their container.
+
+ An accessible object's \e Description provides textual information
+ about an object's visual appearance. The description is primarily
+ used to provide greater context for low-vision or blind users, but
+ is also used for context searching or other applications. Not all
+ objects have a description. An "OK" button would not need a
+ description, but a toolbutton that shows a picture of a smiley
+ would.
+
+ The \e Value of an accessible object represents visual information
+ contained by the object, e.g. the text in a line edit. Usually,
+ the value can be modified by the user. Not all objects have a
+ value, e.g. static text labels don't, and some objects have a
+ state that already is the value, e.g. toggle buttons.
+
+ The \e Help text provides information about the function and
+ usage of an accessible object. Not all objects provide this
+ information.
+
+ An accessible object's \e DefaultAction describes the object's
+ primary method of manipulation, and should be a verb or a short
+ phrase, e.g. "Press" for a button.
+
+ The accelerator is a keyboard shortcut that activates the default
+ action of the object. A keyboard shortcut is the underlined
+ character in the text of a menu, menu item or control, and is
+ either the character itself, or a combination of this character
+ and a modifier key like ALT, CTRL or SHIFT. Command controls like
+ tool buttons also have shortcut keys and usually display them in
+ their tooltip.
+
+ \sa role(), state(), selection()
+*/
+
+/*!
+ \fn void TQAccessibleInterface::setText( Text t, int control, const TQString &text )
+
+ Sets the text property \a t of the child object \a control to \a
+ text. If \a control is 0, the text property of the object itself
+ is set.
+*/
+
+/*!
+ \fn TQAccessible::Role TQAccessibleInterface::role( int control ) const
+
+ Returns the role of the object if \a control is 0, or the role of
+ the object's sub-element with ID \a control. The role of an object
+ is usually static. All accessible objects have a role.
+
+ \sa text(), state(), selection()
+*/
+
+/*!
+ \fn TQAccessible::State TQAccessibleInterface::state( int control ) const
+
+ Returns the current state of the object if \a control is 0, or the
+ state of the object's sub-element element with ID \a control. All
+ objects have a state.
+
+ \sa text(), role(), selection()
+*/
+
+/*!
+ \fn TQMemArray<int> TQAccessibleInterface::selection() const
+
+ Returns the list of all the element IDs that are selected.
+
+ \sa text(), role(), state()
+*/
+
+/*!
+ \fn bool TQAccessibleInterface::doDefaultAction( int control )
+
+ Calling this function performs the default action of the child
+ object specified by \a control, or the default action of the
+ object itself if \a control is 0.
+*/
+
+/*!
+ \fn bool TQAccessibleInterface::setFocus( int control )
+
+ Gives the focus to the child object specified by \a control, or to
+ the object itself if \a control is 0.
+
+ Returns TRUE if the focus could be set; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQAccessibleInterface::setSelected( int control, bool on, bool extend )
+
+ Sets the selection of the child object with ID \a control to \a
+ on. If \a extend is TRUE, all child elements between the focused
+ item and the specified child object have their selection set to \a
+ on.
+
+ Returns TRUE if the selection could be set; otherwise returns
+ FALSE.
+
+ \sa setFocus(), clearSelection()
+*/
+
+/*!
+ \fn void TQAccessibleInterface::clearSelection()
+
+ Removes any selection from the object.
+
+ \sa setSelected()
+*/
+
+
+
+/*!
+ \class TQAccessibleObject tqaccessible.h
+ \brief The TQAccessibleObject class implements parts of the
+ TQAccessibleInterface for TQObjects.
+
+ \ingroup misc
+
+ This class is mainly provided for convenience. All subclasses of
+ the TQAccessibleInterface should use this class as the base class.
+*/
+
+/*!
+ Creates a TQAccessibleObject for \a object.
+*/
+TQAccessibleObject::TQAccessibleObject( TQObject *object )
+: object_(object)
+{
+ if ( !qAccessibleInterface ) {
+ qAccessibleInterface = new AccessibleCache;
+ if ( !cleanupAdded ) {
+ qAddPostRoutine( qAccessibleCleanup );
+ cleanupAdded = TRUE;
+ }
+ }
+
+ qAccessibleInterface->addObject(object, this);
+}
+
+/*!
+ Destroys the TQAccessibleObject.
+
+ This only happens when a call to release() decrements the internal
+ reference counter to zero.
+*/
+TQAccessibleObject::~TQAccessibleObject()
+{
+ if ( qAccessibleInterface ) {
+ qAccessibleInterface->removeObject(object_);
+ if ( !qAccessibleInterface->count() ) {
+ delete qAccessibleInterface;
+ qAccessibleInterface = 0;
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+TQRESULT TQAccessibleObject::queryInterface( const TQUuid &uuid, TQUnknownInterface **iface )
+{
+ *iface = 0;
+ if ( uuid == IID_TQAccessible )
+ *iface = (TQAccessibleInterface*)this;
+ else if ( uuid == IID_TQUnknown )
+ *iface = (TQUnknownInterface*)this;
+ else
+ return TQE_NOINTERFACE;
+
+ (*iface)->addRef();
+ return TQS_OK;
+}
+
+/*!
+ Returns the TQObject for which this TQAccessibleInterface
+ implementation provides information. Use isValid() to make sure
+ the object pointer is safe to use.
+*/
+TQObject *TQAccessibleObject::object() const
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( !isValid() )
+ qWarning( "TQAccessibleInterface is invalid. Crash pending..." );
+#endif
+ return object_;
+}
+
+/*!
+ \reimp
+*/
+bool TQAccessibleObject::isValid() const
+{
+ return !object_.isNull();
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqaccessible.h b/tqtinterface/qt4/src/kernel/tqaccessible.h
new file mode 100644
index 0000000..c476743
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqaccessible.h
@@ -0,0 +1,295 @@
+/****************************************************************************
+**
+** Definition of TQAccessible and TQAccessibleObject classes
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQACCESSIBLE_H
+#define TQACCESSIBLE_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include <private/tqcom_p.h>
+#include "tqrect.h"
+#include "tqguardedptr.h"
+#include "tqmemarray.h"
+#endif // TQT_H
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+
+struct TQAccessibleInterface;
+
+class TQ_EXPORT TQAccessible
+{
+private:
+#ifdef TQ_WS_MAC
+ static TQMAC_PASCAL OStqStatus globalEventProcessor(EventHandlerCallRef, EventRef, void *);
+ static TQObject *queryAccessibleObject(TQAccessibleInterface *);
+#endif
+public:
+ enum Event {
+ SoundPlayed = 0x0001,
+ Alert = 0x0002,
+ ForegroundChanged = 0x0003,
+ MenuStart = 0x0004,
+ MenuEnd = 0x0005,
+ PopupMenuStart = 0x0006,
+ PopupMenuEnd = 0x0007,
+ ContextHelpStart = 0x000C,
+ ContextHelpEnd = 0x000D,
+ DragDropStart = 0x000E,
+ DragDropEnd = 0x000F,
+ DialogStart = 0x0010,
+ DialogEnd = 0x0011,
+ ScrollingStart = 0x0012,
+ ScrollingEnd = 0x0013,
+
+ MenuCommand = 0x0018,
+
+ ObjectCreated = 0x8000,
+ ObjectDestroyed = 0x8001,
+ ObjectShow = 0x8002,
+ ObjectHide = 0x8003,
+ ObjectReorder = 0x8004,
+ Focus = 0x8005,
+ Selection = 0x8006,
+ SelectionAdd = 0x8007,
+ SelectionRemove = 0x8008,
+ SelectionWithin = 0x8009,
+ StateChanged = 0x800A,
+ LocationChanged = 0x800B,
+ NameChanged = 0x800C,
+ DescriptionChanged = 0x800D,
+ ValueChanged = 0x800E,
+ ParentChanged = 0x800F,
+ HelpChanged = 0x80A0,
+ DefaultActionChanged= 0x80B0,
+ AcceleratorChanged = 0x80C0
+ };
+
+ enum State {
+ Normal = 0x00000000,
+ Unavailable = 0x00000001,
+ Selected = 0x00000002,
+ Focused = 0x00000004,
+ Pressed = 0x00000008,
+ Checked = 0x00000010,
+ Mixed = 0x00000020,
+ ReadOnly = 0x00000040,
+ HotTracked = 0x00000080,
+ Default = 0x00000100,
+ Expanded = 0x00000200,
+ Collapsed = 0x00000400,
+ Busy = 0x00000800,
+ Floating = 0x00001000,
+ Marqueed = 0x00002000,
+ Animated = 0x00004000,
+ Invisible = 0x00008000,
+ Offscreen = 0x00010000,
+ Sizeable = 0x00020000,
+ Moveable = 0x00040000,
+ SelfVoicing = 0x00080000,
+ Focusable = 0x00100000,
+ Selectable = 0x00200000,
+ Linked = 0x00400000,
+ Traversed = 0x00800000,
+ MultiSelectable = 0x01000000,
+ ExtSelectable = 0x02000000,
+ AlertLow = 0x04000000,
+ AlertMedium = 0x08000000,
+ AlertHigh = 0x10000000,
+ Protected = 0x20000000,
+ Valid = 0x3fffffff
+ };
+
+ enum Role {
+ NoRole = 0x00000000,
+ TitleBar = 0x00000001,
+ MenuBar = 0x00000002,
+ ScrollBar = 0x00000003,
+ Grip = 0x00000004,
+ Sound = 0x00000005,
+ Cursor = 0x00000006,
+ Caret = 0x00000007,
+ AlertMessage = 0x00000008,
+ Window = 0x00000009,
+ Client = 0x0000000A,
+ PopupMenu = 0x0000000B,
+ MenuItem = 0x0000000C,
+ ToolTip = 0x0000000D,
+ Application = 0x0000000E,
+ Document = 0x0000000F,
+ Pane = 0x00000010,
+ Chart = 0x00000011,
+ Dialog = 0x00000012,
+ Border = 0x00000013,
+ Grouping = 0x00000014,
+ Separator = 0x00000015,
+ ToolBar = 0x00000016,
+ tqStatusBar = 0x00000017,
+ Table = 0x00000018,
+ ColumnHeader = 0x00000019,
+ RowHeader = 0x0000001A,
+ Column = 0x0000001B,
+ Row = 0x0000001C,
+ Cell = 0x0000001D,
+ Link = 0x0000001E,
+ HelpBalloon = 0x0000001F,
+ Character = 0x00000020,
+ List = 0x00000021,
+ ListItem = 0x00000022,
+ Outline = 0x00000023,
+ OutlineItem = 0x00000024,
+ PageTab = 0x00000025,
+ PropertyPage = 0x00000026,
+ Indicator = 0x00000027,
+ Graphic = 0x00000028,
+ StaticText = 0x00000029,
+ EditableText = 0x0000002A, // Editable, selectable, etc.
+ PushButton = 0x0000002B,
+ CheckBox = 0x0000002C,
+ RadioButton = 0x0000002D,
+ ComboBox = 0x0000002E,
+ DropLest = 0x0000002F,
+ ProgressBar = 0x00000030,
+ Dial = 0x00000031,
+ HotkeyField = 0x00000032,
+ Slider = 0x00000033,
+ SpinBox = 0x00000034,
+ Diagram = 0x00000035,
+ Animation = 0x00000036,
+ Equation = 0x00000037,
+ ButtonDropDown = 0x00000038,
+ ButtonMenu = 0x00000039,
+ ButtonDropGrid = 0x0000003A,
+ Whitespace = 0x0000003B,
+ PageTabList = 0x0000003C,
+ Clock = 0x0000003D
+ };
+
+ enum NavDirection {
+ NavUp = 0x00000001,
+ NavDown = 0x00000002,
+ NavLeft = 0x00000003,
+ NavRight = 0x00000004,
+ NavNext = 0x00000005,
+ NavPrevious = 0x00000006,
+ NavFirstChild = 0x00000007,
+ NavLastChild = 0x00000008,
+ NavFocusChild = 0x00000009
+ };
+
+ enum Text {
+ Name = 0,
+ Description,
+ Value,
+ Help,
+ Accelerator,
+ DefaultAction
+ };
+
+ static TQRESULT queryAccessibleInterface( TQObject *, TQAccessibleInterface ** );
+ static void updateAccessibility( TQObject *, int who, Event reason );
+ static bool isActive();
+
+ static void initialize();
+ static void cleanup();
+};
+
+// {EC86CB9C-5DA0-4c43-A739-13EBDF1C6B14}
+#define IID_TQAccessible TQUuid( 0xec86cb9c, 0x5da0, 0x4c43, 0xa7, 0x39, 0x13, 0xeb, 0xdf, 0x1c, 0x6b, 0x14 )
+
+struct TQ_EXPORT TQAccessibleInterface : public TQAccessible, public TQUnknownInterface
+{
+ // check for valid pointers
+ virtual bool isValid() const = 0;
+
+ // hierarchy
+ virtual int childCount() const = 0;
+ virtual TQRESULT queryChild( int control, TQAccessibleInterface** ) const = 0;
+ virtual TQRESULT queryParent( TQAccessibleInterface** ) const = 0;
+
+ // navigation
+ virtual int controlAt( int x, int y ) const = 0;
+ virtual TQRect rect( int control ) const = 0;
+ virtual int navigate( NavDirection direction, int startControl ) const = 0;
+
+ // properties and state
+ virtual TQString text( Text t, int control ) const = 0;
+ virtual void setText( Text t, int control, const TQString &text ) = 0;
+ virtual Role role( int control ) const = 0;
+ virtual State state( int control ) const = 0;
+ virtual TQMemArray<int> selection() const = 0;
+
+ // methods
+ virtual bool doDefaultAction( int control ) = 0;
+ virtual bool setFocus( int control ) = 0;
+ virtual bool setSelected( int control, bool on, bool extend ) = 0;
+ virtual void clearSelection() = 0;
+};
+
+// {49F4C6A7-412F-41DE-9E24-648843421FD3}
+#ifndef IID_TQAccessibleFactory
+#define IID_TQAccessibleFactory TQUuid( 0x49f4c6a7, 0x412f, 0x41de, 0x9e, 0x24, 0x64, 0x88, 0x43, 0x42, 0x1f, 0xd3 )
+#endif
+
+struct TQ_EXPORT TQAccessibleFactoryInterface : public TQAccessible, public TQFeatureListInterface
+{
+ virtual TQRESULT createAccessibleInterface( const TQString &, TQObject *, TQAccessibleInterface** ) = 0;
+};
+
+class TQ_EXPORT TQAccessibleObject : public TQObject, public TQAccessibleInterface
+{
+public:
+ TQAccessibleObject( TQObject *object );
+ virtual ~TQAccessibleObject();
+
+ TQRESULT queryInterface( const TQUuid &, TQUnknownInterface** );
+ TQ_REFCOUNT
+
+ bool isValid() const;
+
+protected:
+ TQObject *object() const;
+
+private:
+ TQGuardedPtr<TQObject> object_;
+};
+
+#define TQ_DEFINED_TQACCESSIBLE_OBJECT
+#include "tqwinexport.h"
+#endif //TQT_ACCESSIBILITY_SUPPORT
+
+#endif //TQACCESSIBLE_H
diff --git a/tqtinterface/qt4/src/kernel/tqapplication.cpp b/tqtinterface/qt4/src/kernel/tqapplication.cpp
new file mode 100644
index 0000000..af193c9
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqapplication.cpp
@@ -0,0 +1,5499 @@
+/****************************************************************************
+**
+** Implementation of TQApplication class
+**
+** Created : 931107
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqobjectlist.h"
+#include "tqapplication.h"
+#include "tqeventloop.h"
+#include "tqeventloop_p.h"
+#include "tqwidget.h"
+#include "tqwidgetlist.h"
+#include "tqwidgetintdict.h"
+#include "tqptrdict.h"
+#include "tqcleanuphandler.h"
+
+#include "tqtranslator.h"
+#include "tqtextcodec.h"
+#include "tqsessionmanager.h"
+#include "tqdragobject.h"
+#include "tqclipboard.h"
+#include "tqcursor.h"
+#include "tqstyle.h"
+#include "tqstylefactory.h"
+#include "tqfile.h"
+#include "tqmessagebox.h"
+#include "tqdir.h"
+#include "tqfileinfo.h"
+#ifdef TQ_WS_WIN
+#include "tqinputcontext_p.h"
+#endif
+#include "tqfontdata_p.h"
+
+#if defined(TQT_THREAD_SUPPORT)
+# include "tqmutex.h"
+# include "tqthread.h"
+#endif // TQT_THREAD_SUPPORT
+
+#include <stdlib.h>
+
+#ifdef truncate
+# undef truncate
+#endif
+
+#ifdef USE_QT4
+
+TQApplication *tqAppReal; // global application object
+TQStyle *TQApplication::app_style = 0; // default application style
+bool qt_explicit_app_style = FALSE; // style explicitly set by programmer
+QWidget* TQApplication::current_app_main_widget = 0; // current main widget
+
+int TQApplication::app_cspec = TQApplication::NormalColor; // color mode (obsolete)
+
+TQWidgetList * qt_modal_stack=0; // stack of modal widgets
+
+#ifndef TQT_NO_PALETTE
+TQPalette *TQApplication::app_pal = 0; // default application palette
+#endif
+// TQFont *TQApplication::app_font = 0; // default application font
+bool qt_app_has_font = FALSE;
+
+bool qt_is_gui_used;
+bool TQ_EXPORT qt_resolve_symlinks = TRUE;
+bool TQ_EXPORT qt_tab_all_widgets = TRUE;
+
+#if defined(TQ_WS_X11)
+extern void qt_init( Display* dpy, TQt::HANDLE, TQt::HANDLE );
+#endif
+extern void qt_init( int *argcptr, char **argv, TQApplication::Type );
+
+#ifndef TQT_NO_CLIPBOARD
+TQClipboard *tqt_clipboard = 0; // global clipboard object
+#endif
+
+#ifdef TQT_THREAD_SUPPORT
+TQMutex *TQApplication::qt_mutex = 0;
+static TQMutex *postevent_mutex = 0;
+static TQt::HANDLE qt_application_thread_id = 0;
+TQ_EXPORT TQt::HANDLE qt_get_application_thread_id()
+{
+ return qt_application_thread_id;
+}
+#endif // TQT_THREAD_SUPPORT
+
+
+#ifdef TQT_THREAD_SUPPORT
+ #define TQAPPLICATION_MUTEX_INIT \
+ qt_mutex = new TQMutex( TRUE ); \
+ postevent_mutex = new TQMutex( TRUE ); \
+ qt_application_thread_id = TQThread::currentThread();
+#else // TQT_THREAD_SUPPORT
+ #define TQAPPLICATION_MUTEX_INIT
+#endif // TQT_THREAD_SUPPORT
+
+TQWidgetList TQApplication::tqt_all_widgets_list;
+
+TQApplication::TQApplication( int &argc, char **argv ) : QApplication( argc, argv )
+{
+ bool GUIenabled = true;
+ TQAPPLICATION_GUI_CONDITIONAL_VAR_INIT
+ TQAPPLICATION_XORG_CONDITIONAL_INIT
+ TQAPPLICATION_MUTEX_INIT
+ TQAPPLICATION_REGISTER_TQ_DATATYPES
+}
+TQApplication::TQApplication( int &argc, char **argv, bool GUIenabled ) : QApplication( argc, argv, GUIenabled )
+{
+ TQAPPLICATION_GUI_CONDITIONAL_VAR_INIT
+ TQAPPLICATION_XORG_CONDITIONAL_INIT
+ TQAPPLICATION_MUTEX_INIT
+ TQAPPLICATION_REGISTER_TQ_DATATYPES
+}
+TQApplication::TQApplication( int &argc, char **argv, Type t ) : QApplication( argc, argv, t )
+{
+ TQAPPLICATION_GUI_VAR_INIT
+ TQAPPLICATION_XORG_PARTIAL_INIT
+ TQAPPLICATION_MUTEX_INIT
+ TQAPPLICATION_REGISTER_TQ_DATATYPES
+}
+#if defined(TQ_WS_X11)
+TQApplication::TQApplication( Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap ) : QApplication( dpy, visual, cmap )
+{
+ TQAPPLICATION_GUI_VAR_INIT
+ TQAPPLICATION_XORG_FULL_INIT
+ TQAPPLICATION_MUTEX_INIT
+ TQAPPLICATION_REGISTER_TQ_DATATYPES
+}
+TQApplication::TQApplication( Display *dpy, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap ) : QApplication( dpy, argc, argv, visual, cmap )
+{
+ TQAPPLICATION_GUI_VAR_INIT
+ TQAPPLICATION_XORG_FULL_INIT
+ TQAPPLICATION_MUTEX_INIT
+ TQAPPLICATION_REGISTER_TQ_DATATYPES
+}
+#endif
+
+// Qt4 session manager interconnect
+void TQApplication::commitData( QSessionManager& sm ) {
+ commitData(TQT_TQSESSIONMANAGER_OBJECT(sm));
+}
+void TQApplication::saveState( QSessionManager& sm ) {
+ saveState(TQT_TQSESSIONMANAGER_OBJECT(sm));
+}
+
+#ifndef TQT_NO_TRANSLATION
+
+bool qt_detectRTLLanguage()
+{
+ return TQApplication::tr( "TQT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right"
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew"
+ " and Arabic) to get proper widget tqlayout." ) == "RTL";
+}
+
+#endif // TQT_NO_TRANSLATION
+
+TQEventLoop* TQApplication::eventloop;
+TQPtrList<QEventLoop> TQApplication::tqt_event_loop_stack;
+int TQApplication::composedUnicode;
+bool TQApplication::metaComposeUnicode;
+
+// static TQEventLoop eventLoop_private; // Will this actually work, or do I need to call exec or something?
+//
+// TQEventLoop *TQApplication::eventLoop()
+// {
+// return &eventLoop_private;
+// }
+
+TQEventLoop *TQApplication::eventLoop() {
+ if ( !eventloop )
+ (void) new TQEventLoop( TQT_TQOBJECT(tqApp), "default event loop" );
+ return eventloop;
+}
+
+/*!
+
+ Wakes up the GUI thread.
+
+ \sa guiThreadAwake() \link threads.html Thread Support in TQt\endlink
+*/
+void TQApplication::wakeUpGuiThread()
+{
+ eventLoop()->wakeUp();
+}
+
+#ifdef TQT_THREAD_SUPPORT
+void TQApplication::lock() {
+ qt_mutex->lock();
+}
+
+void TQApplication::unlock(bool wakeUpGui) {
+ qt_mutex->unlock();
+
+ if (wakeUpGui)
+ wakeUpGuiThread();
+}
+
+bool TQApplication::locked() {
+ return qt_mutex->locked();
+}
+
+bool TQApplication::tryLock() {
+ return qt_mutex->tryLock();
+}
+#endif // TQT_THREAD_SUPPORT
+
+#ifndef TQT_NO_PALETTE
+TQPalette *qt_std_pal = 0;
+
+void qt_create_std_palette()
+{
+ if ( qt_std_pal )
+ delete qt_std_pal;
+
+ TQColor standardLightGray( 192, 192, 192 );
+ TQColor light( 255, 255, 255 );
+ TQColor dark( standardLightGray.dark( 150 ) );
+ TQColorGroup std_act( TQt::black, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::black, TQt::white );
+ TQColorGroup std_dis( TQt::darkGray, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::darkGray, std_act.background() );
+ TQColorGroup std_inact( TQt::black, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::black, TQt::white );
+ qt_std_pal = new TQPalette( std_act, std_dis, std_inact );
+}
+
+static void qt_fix_tooltips()
+{
+ // No resources for this yet (unlike on Windows).
+ TQColorGroup cg( TQt::black, TQColor(255,255,220),
+ TQColor(96,96,96), TQt::black, TQt::black,
+ TQt::black, TQColor(255,255,220) );
+ TQPalette pal( cg, cg, cg );
+ TQApplication::tqsetPalette( pal, TRUE, "TQTipLabel");
+}
+#endif
+
+// [FIXME] This needs to somehow connect to the Qt4 style mechanism
+// Possibly on calls to setStyle the Qt4 setStyle must also be called for the same style?
+
+static TQString *qt_style_override = 0;
+
+TQStyle& TQApplication::tqstyle()
+{
+#ifndef TQT_NO_STYLE
+ if ( app_style )
+ return *app_style;
+ if ( !qt_is_gui_used )
+ qFatal( "No style available in non-gui applications!" );
+
+#if defined(TQ_WS_X11)
+// if(!qt_style_override)
+// x11_initialize_style(); // run-time search for default style
+#endif
+ if ( !app_style ) {
+// // Compile-time search for default style
+// //
+ TQString style;
+ if ( qt_style_override ) {
+ style = *qt_style_override;
+ delete qt_style_override;
+ qt_style_override = 0;
+ } else {
+// # if defined(TQ_WS_WIN) && defined(TQ_OS_TEMP)
+// style = "PocketPC";
+// #elif defined(TQ_WS_WIN)
+// if ( qWinVersion() >= TQt::WV_XP && qWinVersion() < TQt::WV_NT_based )
+// style = "WindowsXP";
+// else
+// style = "Windows"; // default styles for Windows
+// #elif defined(TQ_WS_X11) && defined(TQ_OS_SOLARIS)
+// style = "CDE"; // default style for X11 on Solaris
+// #elif defined(TQ_WS_X11) && defined(TQ_OS_IRIX)
+// style = "SGI"; // default style for X11 on IRIX
+// #elif defined(TQ_WS_X11)
+ style = "Motif"; // default style for X11
+// #elif defined(TQ_WS_MAC)
+// style = "Macintosh"; // default style for all Mac's
+// #elif defined(TQ_WS_TQWS)
+// style = "Compact"; // default style for small tqdevices
+// #endif
+ }
+ app_style = TQStyleFactory::create( style );
+ if ( !app_style && // platform default style not available, try alternatives
+ !(app_style = TQStyleFactory::create( "Windows" ) ) &&
+ !(app_style = TQStyleFactory::create( "Platinum" ) ) &&
+ !(app_style = TQStyleFactory::create( "MotifPlus" ) ) &&
+ !(app_style = TQStyleFactory::create( "Motif" ) ) &&
+ !(app_style = TQStyleFactory::create( "CDE" ) ) &&
+ !(app_style = TQStyleFactory::create( "Aqua" ) ) &&
+ !(app_style = TQStyleFactory::create( "SGI" ) ) &&
+ !(app_style = TQStyleFactory::create( "Compact" ) )
+#ifndef TQT_NO_STRINGLIST
+ && !(app_style = TQStyleFactory::create( TQStyleFactory::keys()[0] ) )
+#endif
+ )
+ qFatal( "No %s style available!", style.latin1() );
+ }
+
+// TQPalette app_pal_copy ( *app_pal );
+// app_style->polish( *app_pal );
+
+// if ( is_app_running && !is_app_closing && (*app_pal != app_pal_copy) ) {
+// TQEvent e( TQEvent::ApplicationPaletteChange );
+// TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+// register TQWidget *w;
+// while ( (w=it.current()) ) { // for all widgets...
+// ++it;
+// sendEvent( w, &e );
+// }
+// }
+
+ app_style->polish( tqApp );
+#endif
+ return *app_style;
+}
+
+/*!
+ Enters the main event loop and waits until exit() is called or the
+ main widget is destroyed, and returns the value that was set to
+ exit() (which is 0 if exit() is called via quit()).
+
+ It is necessary to call this function to start event handling. The
+ main event loop receives events from the window system and
+ dispatches these to the application widgets.
+
+ Generally speaking, no user interaction can take place before
+ calling exec(). As a special case, modal widgets like TQMessageBox
+ can be used before calling exec(), because modal widgets call
+ exec() to start a local event loop.
+
+ To make your application perform idle processing, i.e. executing a
+ special function whenever there are no pending events, use a
+ TQTimer with 0 timeout. More advanced idle processing schemes can
+ be achieved using processEvents().
+
+ \sa quit(), exit(), processEvents(), setMainWidget()
+*/
+int TQApplication::exec()
+{
+ return eventLoop()->exec();
+}
+
+/*!
+ Sets the application's GUI style to \a style. Ownership of the style
+ object is transferred to TQApplication, so TQApplication will delete
+ the style object on application exit or when a new style is set.
+
+ Example usage:
+ \code
+ TQApplication::setStyle( new TQWindowsStyle );
+ \endcode
+
+ When switching application styles, the color palette is set back to
+ the initial colors or the system defaults. This is necessary since
+ certain styles have to adapt the color palette to be fully
+ style-guide compliant.
+
+ \sa style(), TQStyle, setPalette(), desktopSettingsAware()
+*/
+void TQApplication::setStyle( TQStyle *style )
+{
+ TQStyle* old = app_style;
+ app_style = style;
+#ifdef TQ_WS_X11
+ qt_explicit_app_style = TRUE;
+#endif // TQ_WS_X11
+
+ if ( startingUp() ) {
+ delete old;
+ return;
+ }
+
+ // clean up the old style
+ if (old) {
+// if ( is_app_running && !is_app_closing ) {
+// TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+// register TQWidget *w;
+// while ( (w=it.current()) ) { // for all widgets...
+// ++it;
+// if ( !w->testWFlags(WType_Desktop) && // except desktop
+// w->testWState(WState_Polished) ) { // has been polished
+// old->unPolish(w);
+// }
+// }
+// }
+// old->unPolish( tqApp );
+ }
+
+ // take care of possible palette requirements of certain gui
+ // styles. Do it before polishing the application since the style
+ // might call TQApplication::setStyle() itself
+ if ( !qt_std_pal )
+ qt_create_std_palette();
+ TQPalette tmpPal = *qt_std_pal;
+ tqsetPalette( tmpPal, TRUE );
+
+ // initialize the application with the new style
+ app_style->polish( tqApp );
+
+ // re-polish existing widgets if necessary
+ if (old) {
+// if ( is_app_running && !is_app_closing ) {
+// TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+// register TQWidget *w;
+// while ( (w=it.current()) ) { // for all widgets...
+// ++it;
+// if ( !w->testWFlags(WType_Desktop) ) { // except desktop
+// if ( w->testWState(WState_Polished) )
+// app_style->polish(w); // repolish
+// w->styleChange( *old );
+// if ( w->isVisible() ){
+// w->update();
+// }
+// }
+// }
+// }
+ delete old;
+ }
+}
+
+/*!
+ \overload
+
+ Requests a TQStyle object for \a style from the TQStyleFactory.
+
+ The string must be one of the TQStyleFactory::keys(), typically one
+ of "windows", "motif", "cde", "motifplus", "platinum", "sgi" and
+ "compact". Depending on the platform, "windowsxp", "aqua" or
+ "macintosh" may be available.
+
+ A later call to the TQApplication constructor will override the
+ requested style when a "-style" option is passed in as a commandline
+ parameter.
+
+ Returns 0 if an unknown \a style is passed, otherwise the TQStyle object
+ returned is set as the application's GUI style.
+*/
+TQStyle* TQApplication::setStyle( const TQString& style )
+{
+#ifdef TQ_WS_X11
+ qt_explicit_app_style = TRUE;
+#endif // TQ_WS_X11
+
+ if ( startingUp() ) {
+ if(qt_style_override)
+ *qt_style_override = style;
+ else
+ qt_style_override = new TQString(style);
+ return 0;
+ }
+ TQStyle *s = TQStyleFactory::create( style );
+ if ( !s )
+ return 0;
+
+ setStyle( s );
+ return s;
+}
+
+TQWidget *TQApplication::mainWidget()
+{
+ return TQT_TQWIDGET(current_app_main_widget);
+}
+
+const char *TQApplication::tqname() const {
+ if (dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ printf("[WARNING] Attempted to call TQApplication::tqname() on an object without a constructed TQApplication object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+const char *TQApplication::name() const {
+ if (dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ printf("[WARNING] Attempted to call TQApplication::name() on an object without a constructed TQApplication object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+/*!\internal
+
+ Called from qapplication_<platform>.cpp, returns TRUE
+ if the widget should accept the event.
+ */
+TQ_EXPORT bool qt_tryModalHelper( TQWidget *widget, TQWidget **rettop ) {
+ TQWidget *modal=0, *top=TQT_TQWIDGET(TQApplication::activeModalWidget());
+ if ( rettop ) *rettop = top;
+
+ if ( tqApp->activePopupWidget() )
+ return TRUE;
+
+#ifdef TQ_WS_MACX
+ top = qt_tryModalHelperMac( top );
+ if ( rettop ) *rettop = top;
+#endif
+
+ TQWidget* groupLeader = widget;
+ widget = widget->tqtopLevelWidget();
+
+ if ( widget->testWFlags(TQt::WShowModal) ) // widget is modal
+ modal = widget;
+ if ( !top || modal == top ) // don't block event
+ return TRUE;
+
+ TQWidget * p = widget->parentWidget(); // Check if the active modal widget is a tqparent of our widget
+ while ( p ) {
+ if ( p == top )
+ return TRUE;
+ p = p->parentWidget();
+ }
+
+ while ( groupLeader && !groupLeader->testWFlags( TQt::WGroupLeader ) )
+ groupLeader = groupLeader->parentWidget();
+
+// [FIXME]
+printf("[WARNING] bool qt_tryModalHelper partially implemented\n\r");
+// if ( groupLeader ) {
+// // Does groupLeader have a child in qt_modal_stack?
+// bool unrelated = TRUE;
+// modal = qt_modal_stack->first();
+// while (modal && unrelated) {
+// TQWidget* p = modal->parentWidget();
+// while ( p && p != groupLeader && !p->testWFlags( TQt::WGroupLeader) ) {
+// p = p->parentWidget();
+// }
+// modal = qt_modal_stack->next();
+// if ( p == groupLeader ) unrelated = FALSE;
+// }
+//
+// if ( unrelated )
+// return TRUE; // don't block event
+// }
+
+ return FALSE;
+}
+
+/*!\internal
+
+ Creates the proper Enter/Leave event when widget \a enter is entered
+ and widget \a leave is left.
+ */
+TQ_EXPORT void qt_dispatchEnterLeave( TQWidget* enter, TQWidget* leave ) {
+#if 0
+ if ( leave ) {
+ TQEvent e( TQEvent::Leave );
+ TQApplication::sendEvent( leave, & e );
+ }
+ if ( enter ) {
+ TQEvent e( TQEvent::Enter );
+ TQApplication::sendEvent( enter, & e );
+ }
+ return;
+#endif
+
+ TQWidget* w ;
+ if ( !enter && !leave )
+ return;
+ TQWidgetList leaveList;
+ TQWidgetList enterList;
+
+ bool sameWindow = leave && enter && leave->tqtopLevelWidget() == enter->tqtopLevelWidget();
+ if ( leave && !sameWindow ) {
+ w = leave;
+ do {
+ leaveList.append( w );
+ } while ( (w = w->parentWidget( TRUE ) ) );
+ }
+ if ( enter && !sameWindow ) {
+ w = enter;
+ do {
+ enterList.prepend( w );
+ } while ( (w = w->parentWidget(TRUE) ) );
+ }
+ if ( sameWindow ) {
+ int enterDepth = 0;
+ int leaveDepth = 0;
+ w = enter;
+ while ( ( w = w->parentWidget( TRUE ) ) )
+ enterDepth++;
+ w = leave;
+ while ( ( w = w->parentWidget( TRUE ) ) )
+ leaveDepth++;
+ TQWidget* wenter = enter;
+ TQWidget* wleave = leave;
+ while ( enterDepth > leaveDepth ) {
+ wenter = wenter->parentWidget();
+ enterDepth--;
+ }
+ while ( leaveDepth > enterDepth ) {
+ wleave = wleave->parentWidget();
+ leaveDepth--;
+ }
+ while ( !wenter->isTopLevel() && wenter != wleave ) {
+ wenter = wenter->parentWidget();
+ wleave = wleave->parentWidget();
+ }
+
+ w = leave;
+ while ( w != wleave ) {
+ leaveList.append( w );
+ w = w->parentWidget();
+ }
+ w = enter;
+ while ( w != wenter ) {
+ enterList.prepend( w );
+ w = w->parentWidget();
+ }
+ }
+
+ TQEvent leaveEvent( TQEvent::Leave );
+ for ( w = leaveList.first(); w; w = leaveList.next() ) {
+ if ( !tqApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
+ TQApplication::sendEvent( w, &leaveEvent );
+ }
+ TQEvent enterEvent( TQEvent::Enter );
+ for ( w = enterList.first(); w; w = enterList.next() ) {
+ if ( !tqApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
+ TQApplication::sendEvent( w, &enterEvent );
+ }
+}
+
+#ifndef TQT_NO_CLIPBOARD
+/*!
+ Returns a pointer to the application global clipboard.
+*/
+TQClipboard *TQApplication::tqclipboard()
+{
+ if ( tqt_clipboard == 0 ) {
+ tqt_clipboard = new TQClipboard;
+ TQ_CHECK_PTR( tqt_clipboard );
+ }
+ return tqt_clipboard;
+}
+#endif // TQT_NO_CLIPBOARD
+
+/*!
+ \fn void TQApplication::commitData( TQSessionManager& sm )
+
+ This function deals with \link session.html session
+ management\endlink. It is invoked when the TQSessionManager wants the
+ application to commit all its data.
+
+ Usually this means saving all open files, after getting
+ permission from the user. Furthermore you may want to provide a means
+ by which the user can cancel the shutdown.
+
+ Note that you should not exit the application within this function.
+ Instead, the session manager may or may not do this afterwards,
+ depending on the context.
+
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the session manager \a sm for explicit permission.
+ See TQSessionManager::allowsInteraction() and
+ TQSessionManager::allowsErrorInteraction() for details and example
+ usage.
+
+ The default implementation requests interaction and sends a close
+ event to all visible top level widgets. If any event was
+ rejected, the shutdown is canceled.
+
+ \sa isSessionRestored(), sessionId(), saveState(), \link session.html the Session Management overview\endlink
+*/
+#ifndef TQT_NO_SESSIONMANAGER
+void TQApplication::commitData( TQSessionManager& sm )
+{
+
+ if ( sm.allowsInteraction() ) {
+ TQWidgetList done;
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ bool cancelled = FALSE;
+ TQWidget* w = list->first();
+ while ( !cancelled && w ) {
+ if ( !w->isHidden() ) {
+ TQCloseEvent e;
+ sendEvent( w, &e );
+ cancelled = !e.isAccepted();
+ if ( !cancelled )
+ done.append( w );
+ delete list; // one never knows...
+ list = TQApplication::tqtopLevelWidgets();
+ w = list->first();
+ } else {
+ w = list->next();
+ }
+ while ( w && done.tqcontainsRef( w ) )
+ w = list->next();
+ }
+ delete list;
+ if ( cancelled )
+ sm.cancel();
+ }
+}
+
+
+/*!
+ \fn void TQApplication::saveState( TQSessionManager& sm )
+
+ This function deals with \link session.html session
+ management\endlink. It is invoked when the
+ \link TQSessionManager session manager \endlink wants the application
+ to preserve its state for a future session.
+
+ For example, a text editor would create a temporary file that
+ includes the current contents of its edit buffers, the location of
+ the cursor and other aspects of the current editing session.
+
+ Note that you should never exit the application within this
+ function. Instead, the session manager may or may not do this
+ afterwards, depending on the context. Futhermore, most session
+ managers will very likely request a saved state immediately after
+ the application has been started. This permits the session manager
+ to learn about the application's restart policy.
+
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the session manager \a sm for explicit permission.
+ See TQSessionManager::allowsInteraction() and
+ TQSessionManager::allowsErrorInteraction() for details.
+
+ \sa isSessionRestored(), sessionId(), commitData(), \link session.html the Session Management overview\endlink
+*/
+
+void TQApplication::saveState( TQSessionManager& /* sm */ )
+{
+}
+#endif //TQT_NO_SESSIONMANAGER
+
+#if 1 /* OBSOLETE */
+
+TQApplication::ColorMode TQApplication::colorMode()
+{
+ return (TQApplication::ColorMode)app_cspec;
+}
+
+void TQApplication::setColorMode( TQApplication::ColorMode mode )
+{
+ printf("[WARNING] TQApplication::setColorMode() does nothing!\n\r");
+ app_cspec = mode;
+}
+#endif
+
+/*!
+ Initialization of the appearance of the widget \a w \e before it is first
+ shown.
+
+ Usually widgets call this automatically when they are polished. It
+ may be used to do some style-based central customization of widgets.
+
+ Note that you are not limited to the public functions of TQWidget.
+ Instead, based on meta information like TQObject::className() you are
+ able to customize any kind of widget.
+
+ \sa TQStyle::polish(), TQWidget::polish(), setPalette(), setFont()
+*/
+
+void TQApplication::polish( QWidget *w )
+{
+#ifndef TQT_NO_STYLE
+ TQT_TQWIDGET(w)->tqstyle().polish( TQT_TQWIDGET(w) );
+#endif
+}
+
+void TQApplication::exit_loop() { // Does not exit in Qt4
+ printf("[WARNING] No runtime validation is performed within TQApplication::exit_loop; this may cause odd/obscure problems\n\r");
+// QThreadData *data = QThreadData::current();
+// if (!data->eventLoops.isEmpty())
+// data->eventLoops.top()->exit();
+ QEventLoop* eventLoop = tqt_event_loop_stack.getLast();
+ if (eventLoop) {
+ eventLoop->exit();
+ }
+ else {
+ printf("[WARNING] An attempt was made to exit a nonexistant event loop!\n\r");
+ }
+}
+int TQApplication::enter_loop() { // Does not exit in Qt4
+ printf("[WARNING] No runtime validation is performed within TQApplication::enter_loop; this may cause odd/obscure problems\n\r");
+ QEventLoop* eventLoop = new QEventLoop();
+ tqt_event_loop_stack.append(eventLoop);
+ int returnCode = eventLoop->exec(); // This blocks until either QEventLoop::exit is called or the loop terminates normally
+ tqt_event_loop_stack.remove(eventLoop);
+ delete eventLoop;
+ return returnCode;
+}
+
+TQMetaObject *TQApplication::tqmetaObject() const {
+ return TQT_TQOBJECT_CONST(this)->tqmetaObject();
+}
+
+void TQApplication::processOneEvent() {
+ processEvents(QEventLoop::WaitForMoreEvents);
+}
+
+void TQApplication::tqprocessEvents() {
+ return processEvents();
+}
+
+void TQApplication::tqprocessEvents( int maxtime ) {
+ return processEvents(QEventLoop::AllEvents, maxtime);
+}
+
+/*!
+ \obsolete
+
+ Returns the current loop level.
+
+ Use TQApplication::eventLoop()->loopLevel() instead.
+
+*/
+int TQApplication::loopLevel() const
+{
+ return eventLoop()->loopLevel();
+}
+
+bool TQApplication::hasGlobalMouseTracking()
+{
+ printf("[WARNING] TQApplication::hasGlobalMouseTracking unimplemented!\n\r");
+ return true;
+}
+
+void TQApplication::setGlobalMouseTracking( bool enable )
+{
+ printf("[WARNING] TQApplication::setGlobalMouseTracking unimplemented!\n\r");
+}
+
+#if defined(TQ_WS_X11)
+void TQApplication::create_xim() {
+ printf("[WARNING] static void TQApplication::create_xim() unimplemented\n\r"); // [FIXME]
+}
+
+void TQApplication::close_xim() {
+ printf("[WARNING] static void TQApplication::close_xim() unimplemented\n\r"); // [FIXME]
+}
+
+bool TQApplication::x11_apply_settings() {
+ printf("[WARNING] static bool TQApplication::x11_apply_settings() unimplemented\n\r");
+ return false; // [FIXME]
+}
+#endif
+
+#ifndef TQT_NO_TEXTCODEC
+void TQApplication::setDefaultCodec( TQTextCodec * ) {
+ printf("[WARNING] void TQApplication::setDefaultCodec( TQTextCodec * ) unimplemented\n\r"); // [FIXME]
+}
+
+TQTextCodec* TQApplication::defaultCodec() const
+{
+// return TQTextCodec::codecForTr();
+
+ printf("[WARNING] TQTextCodec* TQApplication::defaultCodec unimplemented\n\r"); // [FIXME]
+// return TQTextCodec();
+}
+#endif
+
+TQWidgetList *TQApplication::tqallWidgets() {
+ QWidgetList ql = allWidgets();
+ tqt_all_widgets_list.clear();
+ for (int i = 0; i < ql.size(); ++i) tqt_all_widgets_list.append(TQT_TQWIDGET(ql.at(i)));
+ return &tqt_all_widgets_list;
+}
+
+TQStringList TQApplication::libraryPaths() {
+ return TQT_TQSTRINGLIST_OBJECT(QApplication::libraryPaths());
+}
+
+void TQApplication::tqsetLibraryPaths( const QStringList &qsl ) {
+ setLibraryPaths(qsl);
+}
+
+TQWidgetList *TQApplication::tqtopLevelWidgets() {
+ // The end user of the list is expected to delete it, so create it with new...
+ TQWidgetList *tqwl = new TQWidgetList();
+ foreach (QWidget *widget, QApplication::topLevelWidgets()) {
+ tqwl->append(static_cast<TQWidget*>(widget));
+ }
+ return tqwl;
+
+}
+
+TQDesktopWidget *TQApplication::desktop() {
+ return static_cast<TQDesktopWidget*>(QApplication::desktop());
+}
+
+const QColor &TQApplication::winStyleHighlightColor() {
+ return palette().color(QPalette::Active, QPalette::Highlight);
+}
+
+void TQApplication::setWinStyleHighlightColor( const QColor c ) {
+ TQPalette p( tqpalette() );
+ p.setColor( TQColorGroup::Highlight, c );
+ tqsetPalette( p, TRUE);
+}
+
+void TQApplication::tqsetPalette(const QPalette &pal, bool, const char* className) {
+ setPalette(pal, className);
+}
+
+void TQApplication::tqsetFont(const QFont &font, bool, const char* className) {
+ setFont(font, className);
+}
+
+void TQApplication::setReverseLayout(bool b) {
+ setLayoutDirection(b?Qt::RightToLeft:Qt::LeftToRight);
+}
+
+bool TQApplication::reverseLayout() {
+ return layoutDirection() == Qt::RightToLeft;
+}
+
+TQPalette TQApplication::tqpalette( const TQWidget* w ) {
+ return palette( w );
+}
+
+#ifndef TQT_NO_CURSOR
+//void TQApplication::setOverrideCursor( const QCursor &cur, bool tqreplace=FALSE ) {
+// TQ_UNUSED(tqreplace);
+// QApplication::setOverrideCursor( cur );
+// }
+
+void TQApplication::setOverrideCursor( const QCursor &cur, bool tqreplace ) {
+ TQ_UNUSED(tqreplace);
+ printf("[FIXME] TQApplication::setOverrideCursor( const QCursor &cur, bool tqreplace=FALSE ) unimplemented\n\r");
+}
+#endif
+
+void TQApplication::sendPostedEvents( QObject *receiver, int event_type ) {
+ QApplication::sendPostedEvents(receiver, event_type);
+ if (event_type == TQEvent::LayoutHint) {
+ QApplication::sendPostedEvents(receiver, TQEvent::LayoutRequest);; // This one eats LayoutRequest/LayoutHint events for breakfast
+ }
+}
+
+void TQApplication::sendPostedEvents() {
+ QApplication::sendPostedEvents();
+}
+
+TQWidget *TQApplication::tqfocusWidget() const {
+ return static_cast<TQWidget*>(focusWidget());
+}
+
+TQWidget *TQApplication::widgetAt( const TQPoint &p, bool child ) {
+ TQ_UNUSED(child);
+ return static_cast<TQWidget*>(QApplication::widgetAt( p ));
+}
+
+TQWidget *TQApplication::widgetAt( int x, int y, bool child ) {
+ TQ_UNUSED(child);
+ return static_cast<TQWidget*>(QApplication::widgetAt( QPoint(x, y) ));
+}
+
+int TQApplication::horizontalAlignment( int align ) {
+ return QStyle::visualAlignment(layoutDirection(), (Qt::Alignment)align);
+}
+
+void TQApplication::flushX() {
+ flush();
+}
+
+const char *TQApplication::name(const char *defaultName) const {
+ TQString s = objectName();
+ return s.isEmpty()?defaultName:s.latin1();
+}
+
+void TQApplication::setName(const char *aName) {
+ TQT_TQOBJECT(this)->setName(aName);
+}
+
+/*!
+ Displays a simple message box about TQt. The message includes the
+ version number of TQt being used by the application.
+
+ This is useful for inclusion in the Help menu of an application.
+ See the examples/menu/menu.cpp example.
+
+ This function is a convenience slot for TQMessageBox::aboutTQt().
+*/
+void TQApplication::aboutTQt()
+{
+#ifndef TQT_NO_MESSAGEBOX
+ TQMessageBox::aboutTQt( mainWidget() );
+#endif // TQT_NO_MESSAGEBOX
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQApplication tqapplication.h
+ \brief The TQApplication class manages the GUI application's control
+ flow and main settings.
+
+ \ingroup application
+ \mainclass
+
+ It tqcontains the main event loop, where all events from the window
+ system and other sources are processed and dispatched. It also
+ handles the application's initialization and finalization, and
+ provides session management. It also handles most system-wide and
+ application-wide settings.
+
+ For any GUI application that uses TQt, there is precisely one
+ TQApplication object, no matter whether the application has 0, 1, 2
+ or more windows at any time.
+
+ The TQApplication object is accessible through the global pointer \c
+ tqApp. Its main areas of responsibility are:
+ \list
+
+ \i It initializes the application with the user's desktop settings
+ such as palette(), font() and doubleClickInterval(). It keeps track
+ of these properties in case the user changes the desktop globally, for
+ example through some kind of control panel.
+
+ \i It performs event handling, meaning that it receives events
+ from the underlying window system and dispatches them to the relevant
+ widgets. By using sendEvent() and postEvent() you can send your own
+ events to widgets.
+
+ \i It parses common command line arguments and sets its internal
+ state accordingly. See the \link TQApplication::TQApplication()
+ constructor documentation\endlink below for more details about this.
+
+ \i It defines the application's look and feel, which is
+ encapsulated in a TQStyle object. This can be changed at runtime
+ with setStyle().
+
+ \i It specifies how the application is to allocate colors.
+ See setColorSpec() for details.
+
+ \i It provides localization of strings that are visible to the user
+ via translate().
+
+ \i It provides some magical objects like the desktop() and the
+ clipboard().
+
+ \i It knows about the application's windows. You can ask which
+ widget is at a certain position using widgetAt(), get a list of
+ tqtopLevelWidgets() and closeAllWindows(), etc.
+
+ \i It manages the application's mouse cursor handling,
+ see setOverrideCursor() and setGlobalMouseTracking().
+
+ \i On the X window system, it provides functions to flush and sync
+ the communication stream, see flushX() and syncX().
+
+ \i It provides support for sophisticated \link
+ session.html session management \endlink. This makes it possible
+ for applications to terminate gracefully when the user logs out, to
+ cancel a shutdown process if termination isn't possible and even to
+ preserve the entire application's state for a future session. See
+ isSessionRestored(), sessionId() and commitData() and saveState()
+ for details.
+
+ \endlist
+
+ The <a href="simple-application.html">Application walk-through
+ example</a> tqcontains a typical complete main() that does the usual
+ things with TQApplication.
+
+ Since the TQApplication object does so much initialization, it
+ <b>must</b> be created before any other objects related to the user
+ interface are created.
+
+ Since it also deals with common command line arguments, it is
+ usually a good idea to create it \e before any interpretation or
+ modification of \c argv is done in the application itself. (Note
+ also that for X11, setMainWidget() may change the main widget
+ according to the \c -tqgeometry option. To preserve this
+ functionality, you must set your defaults before setMainWidget() and
+ any overrides after.)
+
+ \table
+ \header \i21 Groups of functions
+ \row
+ \i System settings
+ \i
+ desktopSettingsAware(),
+ setDesktopSettingsAware(),
+ cursorFlashTime(),
+ setCursorFlashTime(),
+ doubleClickInterval(),
+ setDoubleClickInterval(),
+ wheelScrollLines(),
+ setWheelScrollLines(),
+ palette(),
+ setPalette(),
+ font(),
+ setFont(),
+ fontMetrics().
+
+ \row
+ \i Event handling
+ \i
+ exec(),
+ processEvents(),
+ enter_loop(),
+ exit_loop(),
+ exit(),
+ quit().
+ sendEvent(),
+ postEvent(),
+ sendPostedEvents(),
+ removePostedEvents(),
+ hasPendingEvents(),
+ notify(),
+ macEventFilter(),
+ qwsEventFilter(),
+ x11EventFilter(),
+ x11ProcessEvent(),
+ winEventFilter().
+
+ \row
+ \i GUI Styles
+ \i
+ style(),
+ setStyle(),
+ polish().
+
+ \row
+ \i Color usage
+ \i
+ colorSpec(),
+ setColorSpec(),
+ qwsSetCustomColors().
+
+ \row
+ \i Text handling
+ \i
+ installTranslator(),
+ removeTranslator()
+ translate().
+
+ \row
+ \i Widgets
+ \i
+ mainWidget(),
+ setMainWidget(),
+ allWidgets(),
+ tqtopLevelWidgets(),
+ desktop(),
+ activePopupWidget(),
+ activeModalWidget(),
+ clipboard(),
+ tqfocusWidget(),
+ winFocus(),
+ activeWindow(),
+ widgetAt().
+
+ \row
+ \i Advanced cursor handling
+ \i
+ hasGlobalMouseTracking(),
+ setGlobalMouseTracking(),
+ overrideCursor(),
+ setOverrideCursor(),
+ restoreOverrideCursor().
+
+ \row
+ \i X Window System synchronization
+ \i
+ flushX(),
+ syncX().
+
+ \row
+ \i Session management
+ \i
+ isSessionRestored(),
+ sessionId(),
+ commitData(),
+ saveState().
+
+ \row
+ \i Threading
+ \i
+ lock(), unlock(), locked(), tryLock(),
+ wakeUpGuiThread()
+
+ \row
+ \i Miscellaneous
+ \i
+ closeAllWindows(),
+ startingUp(),
+ closingDown(),
+ type().
+ \endtable
+
+ \e {Non-GUI programs:} While TQt is not optimized or
+ designed for writing non-GUI programs, it's possible to use
+ \link tools.html some of its classes \endlink without creating a
+ TQApplication. This can be useful if you wish to share code between
+ a non-GUI server and a GUI client.
+
+ \headerfile tqnamespace.h
+ \headerfile tqwindowdefs.h
+ \headerfile tqglobal.h
+*/
+
+/*! \enum TQt::HANDLE
+ \internal
+*/
+
+/*!
+ \enum TQApplication::Type
+
+ \value Tty a console application
+ \value GuiClient a GUI client application
+ \value GuiServer a GUI server application
+*/
+
+/*!
+ \enum TQApplication::ColorSpec
+
+ \value NormalColor the default color allocation policy
+ \value CustomColor the same as NormalColor for X11; allocates colors
+ to a palette on demand under Windows
+ \value ManyColor the right choice for applications that use thousands of
+ colors
+
+ See setColorSpec() for full details.
+*/
+
+/*
+ The qt_init() and qt_cleanup() functions are implemented in the
+ qapplication_xyz.cpp file.
+*/
+
+void qt_init( int *, char **, TQApplication::Type );
+void qt_cleanup();
+#if defined(TQ_WS_X11)
+void qt_init( Display* dpy, TQt::HANDLE, TQt::HANDLE );
+#endif
+TQ_EXPORT bool qt_tryModalHelper( TQWidget *widget, TQWidget **rettop );
+
+TQApplication *tqApp = 0; // global application object
+
+TQStyle *TQApplication::app_style = 0; // default application style
+bool qt_explicit_app_style = FALSE; // style explicitly set by programmer
+
+int TQApplication::app_cspec = TQApplication::NormalColor;
+#ifndef TQT_NO_PALETTE
+TQPalette *TQApplication::app_pal = 0; // default application palette
+#endif
+TQFont *TQApplication::app_font = 0; // default application font
+bool qt_app_has_font = FALSE;
+#ifndef TQT_NO_CURSOR
+TQCursor *TQApplication::app_cursor = 0; // default application cursor
+#endif
+int TQApplication::app_tracking = 0; // global mouse tracking
+bool TQApplication::is_app_running = FALSE; // app starting up if FALSE
+bool TQApplication::is_app_closing = FALSE; // app closing down if TRUE
+int TQApplication::loop_level = 0; // event loop level
+TQWidget *TQApplication::main_widget = 0; // main application widget
+TQWidget *TQApplication::focus_widget = 0; // has keyboard input focus
+TQWidget *TQApplication::active_window = 0; // toplevel with keyboard focus
+bool TQApplication::obey_desktop_settings = TRUE; // use winsys resources
+int TQApplication::cursor_flash_time = 1000; // text caret flash time
+int TQApplication::mouse_double_click_time = 400; // mouse dbl click limit
+#ifndef TQT_NO_WHEELEVENT
+int TQApplication::wheel_scroll_lines = 3; // number of lines to scroll
+#endif
+bool qt_is_gui_used;
+bool TQ_EXPORT qt_resolve_symlinks = TRUE;
+bool TQ_EXPORT qt_tab_all_widgets = TRUE;
+TQRect qt_maxWindowRect;
+static int drag_time = 500;
+static int drag_distance = 4;
+static bool reverse_tqlayout = FALSE;
+TQSize TQApplication::app_strut = TQSize( 0,0 ); // no default application strut
+bool TQApplication::animate_ui = TRUE;
+bool TQApplication::animate_menu = FALSE;
+bool TQApplication::fade_menu = FALSE;
+bool TQApplication::animate_combo = FALSE;
+bool TQApplication::animate_tooltip = FALSE;
+bool TQApplication::fade_tooltip = FALSE;
+bool TQApplication::animate_toolbox = FALSE;
+bool TQApplication::widgetCount = FALSE;
+TQApplication::Type qt_appType=TQApplication::Tty;
+#ifndef TQT_NO_COMPONENT
+TQStringList *TQApplication::app_libpaths = 0;
+#endif
+bool TQApplication::metaComposeUnicode = FALSE;
+int TQApplication::composedUnicode = 0;
+
+#ifdef TQT_THREAD_SUPPORT
+TQMutex *TQApplication::qt_mutex = 0;
+static TQMutex *postevent_mutex = 0;
+static TQt::HANDLE qt_application_thread_id = 0;
+TQ_EXPORT TQt::HANDLE qt_get_application_thread_id()
+{
+ return qt_application_thread_id;
+}
+#endif // TQT_THREAD_SUPPORT
+
+TQEventLoop *TQApplication::eventloop = 0; // application event loop
+
+#ifndef TQT_NO_ACCEL
+extern bool qt_dispatchAccelEvent( TQWidget*, TQKeyEvent* ); // def in qaccel.cpp
+extern bool qt_tryComposeUnicode( TQWidget*, TQKeyEvent* ); // def in qaccel.cpp
+#endif
+
+#if defined(TQT_TABLET_SUPPORT)
+bool chokeMouse = FALSE;
+#endif
+
+void qt_setMaxWindowRect(const TQRect& r)
+{
+ qt_maxWindowRect = r;
+ // Re-resize any maximized windows
+ TQWidgetList* l = TQApplication::tqtopLevelWidgets();
+ if ( l ) {
+ TQWidget *w = l->first();
+ while ( w ) {
+ if ( w->isVisible() && w->isMaximized() )
+ {
+ w->showNormal(); //#### flicker
+ w->showMaximized();
+ }
+ w = l->next();
+ }
+ delete l;
+ }
+}
+
+typedef void (*VFPTR)();
+typedef TQValueList<VFPTR> TQVFuncList;
+static TQVFuncList *postRList = 0; // list of post routines
+
+/*!
+ \relates TQApplication
+
+ Adds a global routine that will be called from the TQApplication
+ destructor. This function is normally used to add cleanup routines
+ for program-wide functionality.
+
+ The function given by \a p should take no arguments and return
+ nothing, like this:
+ \code
+ static int *global_ptr = 0;
+
+ static void cleanup_ptr()
+ {
+ delete [] global_ptr;
+ global_ptr = 0;
+ }
+
+ void init_ptr()
+ {
+ global_ptr = new int[100]; // allocate data
+ qAddPostRoutine( cleanup_ptr ); // delete later
+ }
+ \endcode
+
+ Note that for an application- or module-wide cleanup,
+ qAddPostRoutine() is often not suitable. People have a tendency to
+ make such modules dynamically loaded, and then unload those modules
+ long before the TQApplication destructor is called, for example.
+
+ For modules and libraries, using a reference-counted initialization
+ manager or TQt' tqparent-child delete mechanism may be better. Here is
+ an example of a private class which uses the tqparent-child mechanism
+ to call a cleanup function at the right time:
+
+ \code
+ class MyPrivateInitStuff: public TQObject {
+ private:
+ MyPrivateInitStuff( TQObject * tqparent ): TQObject( tqparent) {
+ // initialization goes here
+ }
+ MyPrivateInitStuff * p;
+
+ public:
+ static MyPrivateInitStuff * initStuff( TQObject * tqparent ) {
+ if ( !p )
+ p = new MyPrivateInitStuff( tqparent );
+ return p;
+ }
+
+ ~MyPrivateInitStuff() {
+ // cleanup (the "post routine") goes here
+ }
+ }
+ \endcode
+
+ By selecting the right tqparent widget/object, this can often be made
+ to clean up the module's data at the exact right moment.
+*/
+
+TQ_EXPORT void qAddPostRoutine( TQtCleanUpFunction p)
+{
+ if ( !postRList ) {
+ postRList = new TQVFuncList;
+ TQ_CHECK_PTR( postRList );
+ }
+ postRList->prepend( p );
+}
+
+
+TQ_EXPORT void qRemovePostRoutine( TQtCleanUpFunction p )
+{
+ if ( !postRList ) return;
+ TQVFuncList::Iterator it = postRList->begin();
+ while ( it != postRList->end() ) {
+ if ( *it == p ) {
+ postRList->remove( it );
+ it = postRList->begin();
+ } else {
+ ++it;
+ }
+ }
+}
+
+// Default application palettes and fonts (per widget type)
+TQAsciiDict<TQPalette> *TQApplication::app_palettes = 0;
+TQAsciiDict<TQFont> *TQApplication::app_fonts = 0;
+
+#ifndef TQT_NO_SESSIONMANAGER
+TQString *TQApplication::session_key = 0; // ## session key. Should be a member in 4.0
+#endif
+TQWidgetList *TQApplication::popupWidgets = 0; // has keyboard input focus
+
+TQDesktopWidget *qt_desktopWidget = 0; // root window widgets
+#ifndef TQT_NO_CLIPBOARD
+TQClipboard *qt_clipboard = 0; // global clipboard object
+#endif
+TQWidgetList * qt_modal_stack=0; // stack of modal widgets
+
+// Definitions for posted events
+struct TQPostEvent {
+ TQPostEvent( TQObject *r, TQEvent *e ): receiver( r ), event( e ) {}
+ ~TQPostEvent() { delete event; }
+ TQObject *receiver;
+ TQEvent *event;
+};
+
+class TQ_EXPORT TQPostEventList : public TQPtrList<TQPostEvent>
+{
+public:
+ TQPostEventList() : TQPtrList<TQPostEvent>() {}
+ TQPostEventList( const TQPostEventList &list ) : TQPtrList<TQPostEvent>(list) {}
+ ~TQPostEventList() { clear(); }
+ TQPostEventList &operator=(const TQPostEventList &list)
+ { return (TQPostEventList&)TQPtrList<TQPostEvent>::operator=(list); }
+};
+class TQ_EXPORT TQPostEventListIt : public TQPtrListIterator<TQPostEvent>
+{
+public:
+ TQPostEventListIt( const TQPostEventList &l ) : TQPtrListIterator<TQPostEvent>(l) {}
+ TQPostEventListIt &operator=(const TQPostEventListIt &i)
+{ return (TQPostEventListIt&)TQPtrListIterator<TQPostEvent>::operator=(i); }
+};
+
+static TQPostEventList *globalPostedEvents = 0; // list of posted events
+
+uint qGlobalPostedEventsCount()
+{
+ if (!globalPostedEvents)
+ return 0;
+ return globalPostedEvents->count();
+}
+
+static TQSingleCleanupHandler<TQPostEventList> qapp_cleanup_events;
+
+#ifndef TQT_NO_PALETTE
+TQPalette *qt_std_pal = 0;
+
+void qt_create_std_palette()
+{
+ if ( qt_std_pal )
+ delete qt_std_pal;
+
+ TQColor standardLightGray( 192, 192, 192 );
+ TQColor light( 255, 255, 255 );
+ TQColor dark( standardLightGray.dark( 150 ) );
+ TQColorGroup std_act( TQt::black, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::black, TQt::white );
+ TQColorGroup std_dis( TQt::darkGray, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::darkGray, std_act.background() );
+ TQColorGroup std_inact( TQt::black, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::black, TQt::white );
+ qt_std_pal = new TQPalette( std_act, std_dis, std_inact );
+}
+
+static void qt_fix_tooltips()
+{
+ // No resources for this yet (unlike on Windows).
+ TQColorGroup cg( TQt::black, TQColor(255,255,220),
+ TQColor(96,96,96), TQt::black, TQt::black,
+ TQt::black, TQColor(255,255,220) );
+ TQPalette pal( cg, cg, cg );
+ TQApplication::setPalette( pal, TRUE, "TQTipLabel");
+}
+#endif
+
+void TQApplication::process_cmdline( int* argcptr, char ** argv )
+{
+ // process platform-indep command line
+ if ( !qt_is_gui_used || !*argcptr)
+ return;
+
+ int argc = *argcptr;
+ int i, j;
+
+ j = 1;
+ for ( i=1; i<argc; i++ ) {
+ if ( argv[i] && *argv[i] != '-' ) {
+ argv[j++] = argv[i];
+ continue;
+ }
+ TQCString arg = argv[i];
+ TQCString s;
+ if ( arg == "-qdevel" || arg == "-qdebug") {
+ // obsolete argument
+ } else if ( arg.tqfind( "-style=", 0, FALSE ) != -1 ) {
+ s = arg.right( arg.length() - 7 );
+ } else if ( qstrcmp(arg,"-style") == 0 && i < argc-1 ) {
+ s = argv[++i];
+ s = s.lower();
+#ifndef TQT_NO_SESSIONMANAGER
+ } else if ( qstrcmp(arg,"-session") == 0 && i < argc-1 ) {
+ TQCString s = argv[++i];
+ if ( !s.isEmpty() ) {
+ session_id = TQString::tqfromLatin1( s );
+ int p = session_id.tqfind( '_' );
+ if ( p >= 0 ) {
+ if ( !session_key )
+ session_key = new TQString;
+ *session_key = session_id.mid( p +1 );
+ session_id = session_id.left( p );
+ }
+ is_session_restored = TRUE;
+ }
+#endif
+ } else if ( qstrcmp(arg, "-reverse") == 0 ) {
+ setReverseLayout( TRUE );
+ } else if ( qstrcmp(arg, "-widgetcount") == 0 ) {
+ widgetCount = TRUE;;
+ } else {
+ argv[j++] = argv[i];
+ }
+#ifndef TQT_NO_STYLE
+ if ( !s.isEmpty() ) {
+ setStyle( s );
+ }
+#endif
+ }
+
+ if(j < argc) {
+#ifdef TQ_WS_MACX
+ static char* empty = "\0";
+ argv[j] = empty;
+#else
+ argv[j] = 0;
+#endif
+ *argcptr = j;
+ }
+}
+
+/*!
+ Initializes the window system and constructs an application object
+ with \a argc command line arguments in \a argv.
+
+ The global \c tqApp pointer refers to this application object. Only
+ one application object should be created.
+
+ This application object must be constructed before any \link
+ TQPaintDevice paint tqdevices\endlink (including widgets, pixmaps, bitmaps
+ etc.).
+
+ Note that \a argc and \a argv might be changed. TQt removes command
+ line arguments that it recognizes. The modified \a argc and \a argv
+ can also be accessed later with \c tqApp->argc() and \c tqApp->argv().
+ The documentation for argv() tqcontains a detailed description of how
+ to process command line arguments.
+
+ TQt debugging options (not available if TQt was compiled with the
+ TQT_NO_DEBUG flag defined):
+ \list
+ \i -nograb, tells TQt that it must never grab the mouse or the keyboard.
+ \i -dograb (only under X11), running under a debugger can cause
+ an implicit -nograb, use -dograb to override.
+ \i -sync (only under X11), switches to synchronous mode for
+ debugging.
+ \endlist
+
+ See \link debug.html Debugging Techniques \endlink for a more
+ detailed explanation.
+
+ All TQt programs automatically support the following command line options:
+ \list
+ \i -reverse causes text to be formatted for right-to-left languages
+ rather than in the usual left-to-right direction.
+ \i -style= \e style, sets the application GUI style. Possible values
+ are \c motif, \c windows, and \c platinum. If you compiled TQt
+ with additional styles or have additional styles as plugins these
+ will be available to the \c -style command line option.
+ \i -style \e style, is the same as listed above.
+ \i -session= \e session, restores the application from an earlier
+ \link session.html session \endlink.
+ \i -session \e session, is the same as listed above.
+ \i -widgetcount, prints debug message at the end about number of widgets left
+ undestroyed and maximum number of widgets existed at the same time
+ \endlist
+
+ The X11 version of TQt also supports some traditional X11
+ command line options:
+ \list
+ \i -display \e display, sets the X display (default is $DISPLAY).
+ \i -tqgeometry \e tqgeometry, sets the client tqgeometry of the
+ \link setMainWidget() main widget\endlink.
+ \i -fn or \c -font \e font, defines the application font. The
+ font should be specified using an X logical font description.
+ \i -bg or \c -background \e color, sets the default background color
+ and an application palette (light and dark shades are calculated).
+ \i -fg or \c -foreground \e color, sets the default foreground color.
+ \i -btn or \c -button \e color, sets the default button color.
+ \i -name \e name, sets the application name.
+ \i -title \e title, sets the application title (caption).
+ \i -visual \c TrueColor, forces the application to use a TrueColor visual
+ on an 8-bit display.
+ \i -ncols \e count, limits the number of colors allocated in the
+ color cube on an 8-bit display, if the application is using the
+ \c TQApplication::ManyColor color specification. If \e count is
+ 216 then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green,
+ and 6 of blue); for other values, a cube
+ approximately proportional to a 2x3x1 cube is used.
+ \i -cmap, causes the application to install a private color map
+ on an 8-bit display.
+ \endlist
+
+ \sa argc(), argv()
+*/
+
+//######### BINARY COMPATIBILITY constructor
+TQApplication::TQApplication( int &argc, char **argv )
+{
+ construct( argc, argv, GuiClient );
+}
+
+
+/*!
+ Constructs an application object with \a argc command line arguments
+ in \a argv. If \a GUIenabled is TRUE, a GUI application is
+ constructed, otherwise a non-GUI (console) application is created.
+
+ Set \a GUIenabled to FALSE for programs without a graphical user
+ interface that should be able to run without a window system.
+
+ On X11, the window system is initialized if \a GUIenabled is TRUE.
+ If \a GUIenabled is FALSE, the application does not connect to the
+ X-server.
+ On Windows and Macintosh, currently the window system is always
+ initialized, regardless of the value of GUIenabled. This may change in
+ future versions of TQt.
+
+ The following example shows how to create an application that
+ uses a graphical interface when available.
+ \code
+ int main( int argc, char **argv )
+ {
+#ifdef TQ_WS_X11
+ bool useGUI = getenv( "DISPLAY" ) != 0;
+#else
+ bool useGUI = TRUE;
+#endif
+ TQApplication app(argc, argv, useGUI);
+
+ if ( useGUI ) {
+ //start GUI version
+ ...
+ } else {
+ //start non-GUI version
+ ...
+ }
+ return app.exec();
+ }
+\endcode
+*/
+
+TQApplication::TQApplication( int &argc, char **argv, bool GUIenabled )
+{
+ construct( argc, argv, GUIenabled ? GuiClient : Tty );
+}
+
+/*!
+ Constructs an application object with \a argc command line arguments
+ in \a argv.
+
+ For TQt/Embedded, passing \c TQApplication::GuiServer for \a type
+ makes this application the server (equivalent to running with the
+ -qws option).
+*/
+TQApplication::TQApplication( int &argc, char **argv, Type type )
+{
+ construct( argc, argv, type );
+}
+
+TQ_EXPORT void qt_ucm_initialize( TQApplication *theApp )
+{
+ if ( tqApp )
+ return;
+ int argc = theApp->argc();
+ char **argv = theApp->argv();
+ theApp->construct( argc, argv, tqApp->type() );
+
+ TQ_ASSERT( tqApp == theApp );
+}
+
+void TQApplication::construct( int &argc, char **argv, Type type )
+{
+ qt_appType = type;
+ qt_is_gui_used = (type != Tty);
+ init_precmdline();
+ static const char *empty = "";
+ if ( argc == 0 || argv == 0 ) {
+ argc = 0;
+ argv = (char **)&empty; // ouch! careful with TQApplication::argv()!
+ }
+ app_argc = argc;
+ app_argv = argv;
+
+ qt_init( &argc, argv, type ); // Must be called before initialize()
+ process_cmdline( &argc, argv );
+ initialize( argc, argv );
+ if ( qt_is_gui_used )
+ qt_maxWindowRect = desktop()->rect();
+ if ( eventloop )
+ eventloop->appStartingUp();
+}
+
+/*!
+ Returns the type of application, Tty, GuiClient or GuiServer.
+*/
+
+TQApplication::Type TQApplication::type() const
+{
+ return qt_appType;
+}
+
+#if defined(TQ_WS_X11)
+/*!
+ Create an application, given an already open display \a dpy. If \a
+ visual and \a colormap are non-zero, the application will use those as
+ the default Visual and Colormap contexts.
+
+ \warning TQt only supports TrueColor visuals at depths higher than 8
+ bits-per-pixel.
+
+ This is available only on X11.
+*/
+
+TQApplication::TQApplication( Display* dpy, HANDLE visual, HANDLE colormap )
+{
+ static int aargc = 1;
+ // ### a string literal is a cont char*
+ // ### using it as a char* is wrong and could lead to segfaults
+ // ### if aargv is modified someday
+ static char *aargv[] = { (char*)"unknown", 0 };
+
+ app_argc = aargc;
+ app_argv = aargv;
+
+ qt_appType = GuiClient;
+ qt_is_gui_used = TRUE;
+ qt_appType = GuiClient;
+ init_precmdline();
+ // ... no command line.
+
+ if ( ! dpy ) {
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQApplication: invalid Display* argument." );
+#endif // TQT_CHECK_STATE
+
+ qt_init( &aargc, aargv, GuiClient );
+ } else {
+ qt_init( dpy, visual, colormap );
+ }
+
+ initialize( aargc, aargv );
+
+ if ( qt_is_gui_used )
+ qt_maxWindowRect = desktop()->rect();
+ if ( eventloop )
+ eventloop->appStartingUp();
+}
+
+/*!
+ Create an application, given an already open display \a dpy and using
+ \a argc command line arguments in \a argv. If \a
+ visual and \a colormap are non-zero, the application will use those as
+ the default Visual and Colormap contexts.
+
+ \warning TQt only supports TrueColor visuals at depths higher than 8
+ bits-per-pixel.
+
+ This is available only on X11.
+
+*/
+TQApplication::TQApplication(Display *dpy, int argc, char **argv,
+ HANDLE visual, HANDLE colormap)
+{
+ qt_appType = GuiClient;
+ qt_is_gui_used = TRUE;
+ qt_appType = GuiClient;
+ init_precmdline();
+
+ app_argc = argc;
+ app_argv = argv;
+
+ if ( ! dpy ) {
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQApplication: invalid Display* argument." );
+#endif // TQT_CHECK_STATE
+
+ qt_init( &argc, argv, GuiClient );
+ } else {
+ qt_init(dpy, visual, colormap);
+ }
+
+ process_cmdline( &argc, argv );
+ initialize(argc, argv);
+
+ if ( qt_is_gui_used )
+ qt_maxWindowRect = desktop()->rect();
+ if ( eventloop )
+ eventloop->appStartingUp();
+}
+
+
+#endif // TQ_WS_X11
+
+
+void TQApplication::init_precmdline()
+{
+ translators = 0;
+ is_app_closing = FALSE;
+#ifndef TQT_NO_SESSIONMANAGER
+ is_session_restored = FALSE;
+#endif
+#if defined(TQT_CHECK_STATE)
+ if ( tqApp )
+ qWarning( "TQApplication: There should be max one application object" );
+#endif
+ tqApp = (TQApplication*)this;
+}
+
+/*!
+ Initializes the TQApplication object, called from the constructors.
+*/
+
+void TQApplication::initialize( int argc, char **argv )
+{
+#ifdef TQT_THREAD_SUPPORT
+ qt_mutex = new TQMutex( TRUE );
+ postevent_mutex = new TQMutex( TRUE );
+ qt_application_thread_id = TQThread::currentThread();
+#endif // TQT_THREAD_SUPPORT
+
+ app_argc = argc;
+ app_argv = argv;
+ quit_now = FALSE;
+ quit_code = 0;
+ TQWidget::createMapper(); // create widget mapper
+#ifndef TQT_NO_PALETTE
+ (void) palette(); // trigger creation of application palette
+#endif
+ is_app_running = TRUE; // no longer starting up
+
+#ifndef TQT_NO_SESSIONMANAGER
+ // connect to the session manager
+ if ( !session_key )
+ session_key = new TQString;
+ session_manager = new TQSessionManager( tqApp, session_id, *session_key );
+#endif
+
+}
+
+
+/*****************************************************************************
+ Functions returning the active popup and modal widgets.
+ *****************************************************************************/
+
+/*!
+ Returns the active popup widget.
+
+ A popup widget is a special top level widget that sets the \c
+ WType_Popup widget flag, e.g. the TQPopupMenu widget. When the
+ application opens a popup widget, all events are sent to the popup.
+ Normal widgets and modal widgets cannot be accessed before the popup
+ widget is closed.
+
+ Only other popup widgets may be opened when a popup widget is shown.
+ The popup widgets are organized in a stack. This function returns
+ the active popup widget at the top of the stack.
+
+ \sa activeModalWidget(), tqtopLevelWidgets()
+*/
+
+TQWidget *TQApplication::activePopupWidget()
+{
+ return popupWidgets ? popupWidgets->getLast() : 0;
+}
+
+
+/*!
+ Returns the active modal widget.
+
+ A modal widget is a special top level widget which is a subclass of
+ TQDialog that specifies the modal parameter of the constructor as
+ TRUE. A modal widget must be closed before the user can continue
+ with other parts of the program.
+
+ Modal widgets are organized in a stack. This function returns
+ the active modal widget at the top of the stack.
+
+ \sa activePopupWidget(), tqtopLevelWidgets()
+*/
+
+TQWidget *TQApplication::activeModalWidget()
+{
+ return qt_modal_stack ? qt_modal_stack->getFirst() : 0;
+}
+
+/*!
+ Cleans up any window system resources that were allocated by this
+ application. Sets the global variable \c tqApp to 0.
+*/
+
+TQApplication::~TQApplication()
+{
+#ifndef TQT_NO_CLIPBOARD
+ // flush clipboard contents
+ if ( qt_clipboard ) {
+ TQCustomEvent event( TQEvent::Clipboard );
+ TQApplication::sendEvent( qt_clipboard, &event );
+ }
+#endif
+
+ if ( eventloop )
+ eventloop->appClosingDown();
+ if ( postRList ) {
+ TQVFuncList::Iterator it = postRList->begin();
+ while ( it != postRList->end() ) { // call post routines
+ (**it)();
+ postRList->remove( it );
+ it = postRList->begin();
+ }
+ delete postRList;
+ postRList = 0;
+ }
+
+ TQObject *tipmanager = child( "toolTipManager", "TQTipManager", FALSE );
+ delete tipmanager;
+
+ delete qt_desktopWidget;
+ qt_desktopWidget = 0;
+ is_app_closing = TRUE;
+
+#ifndef TQT_NO_CLIPBOARD
+ delete qt_clipboard;
+ qt_clipboard = 0;
+#endif
+ TQWidget::destroyMapper();
+#ifndef TQT_NO_PALETTE
+ delete qt_std_pal;
+ qt_std_pal = 0;
+ delete app_pal;
+ app_pal = 0;
+ delete app_palettes;
+ app_palettes = 0;
+#endif
+ delete app_font;
+ app_font = 0;
+ delete app_fonts;
+ app_fonts = 0;
+#ifndef TQT_NO_STYLE
+ delete app_style;
+ app_style = 0;
+#endif
+#ifndef TQT_NO_CURSOR
+ delete app_cursor;
+ app_cursor = 0;
+#endif
+#ifndef TQT_NO_TRANSLATION
+ delete translators;
+#endif
+
+#ifndef TQT_NO_DRAGANDDROP
+ extern TQDragManager *qt_dnd_manager;
+ delete qt_dnd_manager;
+#endif
+
+ qt_cleanup();
+
+#ifndef TQT_NO_COMPONENT
+ delete app_libpaths;
+ app_libpaths = 0;
+#endif
+
+#ifdef TQT_THREAD_SUPPORT
+ delete qt_mutex;
+ qt_mutex = 0;
+ delete postevent_mutex;
+ postevent_mutex = 0;
+#endif // TQT_THREAD_SUPPORT
+
+ if( tqApp == this ) {
+ if ( postedEvents )
+ removePostedEvents( this );
+ tqApp = 0;
+ }
+ is_app_running = FALSE;
+
+ if ( widgetCount ) {
+ qDebug( "Widgets left: %i Max widgets: %i \n", TQWidget::instanceCounter, TQWidget::maxInstances );
+ }
+#ifndef TQT_NO_SESSIONMANAGER
+ delete session_manager;
+ session_manager = 0;
+ delete session_key;
+ session_key = 0;
+#endif //TQT_NO_SESSIONMANAGER
+
+ qt_explicit_app_style = FALSE;
+ qt_app_has_font = FALSE;
+ app_tracking = 0;
+ obey_desktop_settings = TRUE;
+ cursor_flash_time = 1000;
+ mouse_double_click_time = 400;
+#ifndef TQT_NO_WHEELEVENT
+ wheel_scroll_lines = 3;
+#endif
+ drag_time = 500;
+ drag_distance = 4;
+ reverse_tqlayout = FALSE;
+ app_strut = TQSize( 0, 0 );
+ animate_ui = TRUE;
+ animate_menu = FALSE;
+ fade_menu = FALSE;
+ animate_combo = FALSE;
+ animate_tooltip = FALSE;
+ fade_tooltip = FALSE;
+ widgetCount = FALSE;
+}
+
+
+/*!
+ \fn int TQApplication::argc() const
+
+ Returns the number of command line arguments.
+
+ The documentation for argv() describes how to process command line
+ arguments.
+
+ \sa argv(), TQApplication::TQApplication()
+*/
+
+/*!
+ \fn char **TQApplication::argv() const
+
+ Returns the command line argument vector.
+
+ \c argv()[0] is the program name, \c argv()[1] is the first
+ argument and \c argv()[argc()-1] is the last argument.
+
+ A TQApplication object is constructed by passing \e argc and \e
+ argv from the \c main() function. Some of the arguments may be
+ recognized as TQt options and removed from the argument vector. For
+ example, the X11 version of TQt knows about \c -display, \c -font
+ and a few more options.
+
+ Example:
+ \code
+ // showargs.cpp - displays program arguments in a list box
+
+ #include <tqapplication.h>
+ #include <tqlistbox.h>
+
+ int main( int argc, char **argv )
+ {
+ TQApplication a( argc, argv );
+ TQListBox b;
+ a.setMainWidget( &b );
+ for ( int i = 0; i < a.argc(); i++ ) // a.argc() == argc
+ b.insertItem( a.argv()[i] ); // a.argv()[i] == argv[i]
+ b.show();
+ return a.exec();
+ }
+ \endcode
+
+ If you run \c{showargs -display unix:0 -font 9x15bold hello world}
+ under X11, the list box tqcontains the three strings "showargs",
+ "hello" and "world".
+
+ TQt provides a global pointer, \c tqApp, that points to the
+ TQApplication object, and through which you can access argc() and
+ argv() in functions other than main().
+
+ \sa argc(), TQApplication::TQApplication()
+*/
+
+/*!
+ \fn void TQApplication::setArgs( int argc, char **argv )
+ \internal
+*/
+
+
+#ifndef TQT_NO_STYLE
+
+static TQString *qt_style_override = 0;
+
+/*!
+ Returns the application's style object.
+
+ \sa setStyle(), TQStyle
+*/
+TQStyle& TQApplication::tqstyle()
+{
+#ifndef TQT_NO_STYLE
+ if ( app_style )
+ return *app_style;
+ if ( !qt_is_gui_used )
+ qFatal( "No style available in non-gui applications!" );
+
+#if defined(TQ_WS_X11)
+ if(!qt_style_override)
+ x11_initialize_style(); // run-time search for default style
+#endif
+ if ( !app_style ) {
+ // Compile-time search for default style
+ //
+ TQString style;
+ if ( qt_style_override ) {
+ style = *qt_style_override;
+ delete qt_style_override;
+ qt_style_override = 0;
+ } else {
+# if defined(TQ_WS_WIN) && defined(TQ_OS_TEMP)
+ style = "PocketPC";
+#elif defined(TQ_WS_WIN)
+ if ( qWinVersion() >= TQt::WV_XP && qWinVersion() < TQt::WV_NT_based )
+ style = "WindowsXP";
+ else
+ style = "Windows"; // default styles for Windows
+#elif defined(TQ_WS_X11) && defined(TQ_OS_SOLARIS)
+ style = "CDE"; // default style for X11 on Solaris
+#elif defined(TQ_WS_X11) && defined(TQ_OS_IRIX)
+ style = "SGI"; // default style for X11 on IRIX
+#elif defined(TQ_WS_X11)
+ style = "Motif"; // default style for X11
+#elif defined(TQ_WS_MAC)
+ style = "Macintosh"; // default style for all Mac's
+#elif defined(TQ_WS_TQWS)
+ style = "Compact"; // default style for small tqdevices
+#endif
+ }
+ app_style = TQStyleFactory::create( style );
+ if ( !app_style && // platform default style not available, try alternatives
+ !(app_style = TQStyleFactory::create( "Windows" ) ) &&
+ !(app_style = TQStyleFactory::create( "Platinum" ) ) &&
+ !(app_style = TQStyleFactory::create( "MotifPlus" ) ) &&
+ !(app_style = TQStyleFactory::create( "Motif" ) ) &&
+ !(app_style = TQStyleFactory::create( "CDE" ) ) &&
+ !(app_style = TQStyleFactory::create( "Aqua" ) ) &&
+ !(app_style = TQStyleFactory::create( "SGI" ) ) &&
+ !(app_style = TQStyleFactory::create( "Compact" ) )
+#ifndef TQT_NO_STRINGLIST
+ && !(app_style = TQStyleFactory::create( TQStyleFactory::keys()[0] ) )
+#endif
+ )
+ qFatal( "No %s style available!", style.latin1() );
+ }
+
+ TQPalette app_pal_copy ( *app_pal );
+ app_style->polish( *app_pal );
+
+ if ( is_app_running && !is_app_closing && (*app_pal != app_pal_copy) ) {
+ TQEvent e( TQEvent::ApplicationPaletteChange );
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets...
+ ++it;
+ sendEvent( w, &e );
+ }
+ }
+
+ app_style->polish( tqApp );
+#endif
+ return *app_style;
+}
+
+/*!
+ Sets the application's GUI style to \a style. Ownership of the style
+ object is transferred to TQApplication, so TQApplication will delete
+ the style object on application exit or when a new style is set.
+
+ Example usage:
+ \code
+ TQApplication::setStyle( new TQWindowsStyle );
+ \endcode
+
+ When switching application styles, the color palette is set back to
+ the initial colors or the system defaults. This is necessary since
+ certain styles have to adapt the color palette to be fully
+ style-guide compliant.
+
+ \sa style(), TQStyle, setPalette(), desktopSettingsAware()
+*/
+void TQApplication::setStyle( TQStyle *style )
+{
+ TQStyle* old = app_style;
+ app_style = style;
+#ifdef TQ_WS_X11
+ qt_explicit_app_style = TRUE;
+#endif // TQ_WS_X11
+
+ if ( startingUp() ) {
+ delete old;
+ return;
+ }
+
+ // clean up the old style
+ if (old) {
+ if ( is_app_running && !is_app_closing ) {
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets...
+ ++it;
+ if ( !w->testWFlags(WType_Desktop) && // except desktop
+ w->testWState(WState_Polished) ) { // has been polished
+ old->unPolish(w);
+ }
+ }
+ }
+ old->unPolish( tqApp );
+ }
+
+ // take care of possible palette requirements of certain gui
+ // styles. Do it before polishing the application since the style
+ // might call TQApplication::setStyle() itself
+ if ( !qt_std_pal )
+ qt_create_std_palette();
+ TQPalette tmpPal = *qt_std_pal;
+ setPalette( tmpPal, TRUE );
+
+ // initialize the application with the new style
+ app_style->polish( tqApp );
+
+ // re-polish existing widgets if necessary
+ if (old) {
+ if ( is_app_running && !is_app_closing ) {
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets...
+ ++it;
+ if ( !w->testWFlags(WType_Desktop) ) { // except desktop
+ if ( w->testWState(WState_Polished) )
+ app_style->polish(w); // repolish
+ w->styleChange( *old );
+ if ( w->isVisible() ){
+ w->update();
+ }
+ }
+ }
+ }
+ delete old;
+ }
+}
+
+/*!
+ \overload
+
+ Requests a TQStyle object for \a style from the TQStyleFactory.
+
+ The string must be one of the TQStyleFactory::keys(), typically one
+ of "windows", "motif", "cde", "motifplus", "platinum", "sgi" and
+ "compact". Depending on the platform, "windowsxp", "aqua" or
+ "macintosh" may be available.
+
+ A later call to the TQApplication constructor will override the
+ requested style when a "-style" option is passed in as a commandline
+ parameter.
+
+ Returns 0 if an unknown \a style is passed, otherwise the TQStyle object
+ returned is set as the application's GUI style.
+*/
+TQStyle* TQApplication::setStyle( const TQString& style )
+{
+#ifdef TQ_WS_X11
+ qt_explicit_app_style = TRUE;
+#endif // TQ_WS_X11
+
+ if ( startingUp() ) {
+ if(qt_style_override)
+ *qt_style_override = style;
+ else
+ qt_style_override = new TQString(style);
+ return 0;
+ }
+ TQStyle *s = TQStyleFactory::create( style );
+ if ( !s )
+ return 0;
+
+ setStyle( s );
+ return s;
+}
+
+#endif
+
+
+#if 1 /* OBSOLETE */
+
+TQApplication::ColorMode TQApplication::colorMode()
+{
+ return (TQApplication::ColorMode)app_cspec;
+}
+
+void TQApplication::setColorMode( TQApplication::ColorMode mode )
+{
+ app_cspec = mode;
+}
+#endif
+
+
+/*!
+ Returns the color specification.
+ \sa TQApplication::setColorSpec()
+ */
+
+int TQApplication::colorSpec()
+{
+ return app_cspec;
+}
+
+/*!
+ Sets the color specification for the application to \a spec.
+
+ The color specification controls how the application allocates colors
+ when run on a display with a limited amount of colors, e.g. 8 bit / 256
+ color displays.
+
+ The color specification must be set before you create the TQApplication
+ object.
+
+ The options are:
+ \list
+ \i TQApplication::NormalColor.
+ This is the default color allocation strategy. Use this option if
+ your application uses buttons, menus, texts and pixmaps with few
+ colors. With this option, the application uses system global
+ colors. This works fine for most applications under X11, but on
+ Windows machines it may cause dithering of non-standard colors.
+ \i TQApplication::CustomColor.
+ Use this option if your application needs a small number of custom
+ colors. On X11, this option is the same as NormalColor. On Windows, TQt
+ creates a Windows palette, and allocates colors to it on demand.
+ \i TQApplication::ManyColor.
+ Use this option if your application is very color hungry
+ (e.g. it requires thousands of colors).
+ Under X11 the effect is:
+ \list
+ \i For 256-color displays which have at best a 256 color true color
+ visual, the default visual is used, and colors are allocated
+ from a color cube. The color cube is the 6x6x6 (216 color) "Web
+ palette"<sup>*</sup>, but the number of colors can be changed
+ by the \e -ncols option. The user can force the application to
+ use the true color visual with the \link
+ TQApplication::TQApplication() -visual \endlink option.
+ \i For 256-color displays which have a true color visual with more
+ than 256 colors, use that visual. Silicon Graphics X servers
+ have this feature, for example. They provide an 8 bit visual
+ by default but can deliver true color when asked.
+ \endlist
+ On Windows, TQt creates a Windows palette, and fills it with a color cube.
+ \endlist
+
+ Be aware that the CustomColor and ManyColor choices may lead to colormap
+ flashing: The foreground application gets (most) of the available
+ colors, while the background windows will look less attractive.
+
+ Example:
+ \code
+ int main( int argc, char **argv )
+ {
+ TQApplication::setColorSpec( TQApplication::ManyColor );
+ TQApplication a( argc, argv );
+ ...
+ }
+ \endcode
+
+ TQColor provides more functionality for controlling color allocation and
+ freeing up certain colors. See TQColor::enterAllocContext() for more
+ information.
+
+ To check what mode you end up with, call TQColor::numBitPlanes() once
+ the TQApplication object exists. A value greater than 8 (typically
+ 16, 24 or 32) means true color.
+
+ <sup>*</sup> The color cube used by TQt has 216 colors whose red,
+ green, and blue components always have one of the following values:
+ 0x00, 0x33, 0x66, 0x99, 0xCC, or 0xFF.
+
+ \sa colorSpec(), TQColor::numBitPlanes(), TQColor::enterAllocContext() */
+
+void TQApplication::setColorSpec( int spec )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( tqApp ) {
+ qWarning( "TQApplication::setColorSpec: This function must be "
+ "called before the TQApplication object is created" );
+ }
+#endif
+ app_cspec = spec;
+}
+
+/*!
+ \fn TQSize TQApplication::globalStrut()
+
+ Returns the application's global strut.
+
+ The strut is a size object whose dimensions are the minimum that any
+ GUI element that the user can interact with should have. For example
+ no button should be resized to be smaller than the global strut size.
+
+ \sa setGlobalStrut()
+*/
+
+/*!
+ Sets the application's global strut to \a strut.
+
+ The strut is a size object whose dimensions are the minimum that any
+ GUI element that the user can interact with should have. For example
+ no button should be resized to be smaller than the global strut size.
+
+ The strut size should be considered when reimplementing GUI controls
+ that may be used on touch-screens or similar IO-tqdevices.
+
+ Example:
+ \code
+ TQSize& WidgetClass::tqsizeHint() const
+ {
+ return TQSize( 80, 25 ).expandedTo( TQApplication::globalStrut() );
+ }
+ \endcode
+
+ \sa globalStrut()
+*/
+
+void TQApplication::setGlobalStrut( const TQSize& strut )
+{
+ app_strut = strut;
+}
+
+#if defined( TQ_WS_WIN ) || defined( TQ_WS_MAC )
+extern const char *tqAppFileName();
+#endif
+
+#ifndef TQT_NO_DIR
+#ifndef TQ_WS_WIN
+static TQString resolveSymlinks( const TQString& path, int depth = 0 )
+{
+ bool foundLink = FALSE;
+ TQString linkTarget;
+ TQString part = path;
+ int slashPos = path.length();
+
+ // too deep; we give up
+ if ( depth == 128 )
+ return TQString::null;
+
+ do {
+ part = part.left( slashPos );
+ TQFileInfo fileInfo( part );
+ if ( fileInfo.isSymLink() ) {
+ foundLink = TRUE;
+ linkTarget = fileInfo.readLink();
+ break;
+ }
+ } while ( (slashPos = part.tqfindRev('/')) != -1 );
+
+ if ( foundLink ) {
+ TQString path2;
+ if ( linkTarget[0] == '/' ) {
+ path2 = linkTarget;
+ if ( slashPos < (int) path.length() )
+ path2 += "/" + path.right( path.length() - slashPos - 1 );
+ } else {
+ TQString relPath;
+ relPath = part.left( part.tqfindRev('/') + 1 ) + linkTarget;
+ if ( slashPos < (int) path.length() ) {
+ if ( !linkTarget.endsWith( "/" ) )
+ relPath += "/";
+ relPath += path.right( path.length() - slashPos - 1 );
+ }
+ path2 = TQDir::current().absFilePath( relPath );
+ }
+ path2 = TQDir::cleanDirPath( path2 );
+ return resolveSymlinks( path2, depth + 1 );
+ } else {
+ return path;
+ }
+}
+#endif // TQ_WS_WIN
+
+/*!
+ Returns the directory that tqcontains the application executable.
+
+ For example, if you have installed TQt in the \c{C:\Trolltech\TQt}
+ directory, and you run the \c{demo} example, this function will
+ return "C:/Trolltech/TQt/examples/demo".
+
+ On Mac OS X this will point to the directory actually containing the
+ executable, which may be inside of an application bundle (if the
+ application is bundled).
+
+ \warning On Unix, this function assumes that argv[0] tqcontains the file
+ name of the executable (which it normally does). It also assumes that
+ the current directory hasn't been changed by the application.
+
+ \sa applicationFilePath()
+*/
+TQString TQApplication::applicationDirPath()
+{
+ return TQFileInfo( applicationFilePath() ).dirPath();
+}
+
+/*!
+ Returns the file path of the application executable.
+
+ For example, if you have installed TQt in the \c{C:\Trolltech\TQt}
+ directory, and you run the \c{demo} example, this function will
+ return "C:/Trolltech/TQt/examples/demo/demo.exe".
+
+ \warning On Unix, this function assumes that argv[0] tqcontains the file
+ name of the executable (which it normally does). It also assumes that
+ the current directory hasn't been changed by the application.
+
+ \sa applicationDirPath()
+*/
+TQString TQApplication::applicationFilePath()
+{
+#if defined( TQ_WS_WIN )
+ TQFileInfo filePath;
+ TQT_WA({
+ WCHAR module_name[256];
+ GetModuleFileNameW(0, module_name, sizeof(module_name));
+ filePath = TQString::fromUcs2((const unsigned short *)module_name);
+ }, {
+ char module_name[256];
+ GetModuleFileNameA(0, module_name, sizeof(module_name));
+ filePath = TQString::fromLocal8Bit(module_name);
+ });
+
+ return filePath.filePath();
+#elif defined( TQ_WS_MAC )
+ return TQDir::cleanDirPath( TQFile::decodeName( tqAppFileName() ) );
+#else
+ TQString argv0 = TQFile::decodeName( argv()[0] );
+ TQString absPath;
+
+ if ( argv0[0] == '/' ) {
+ /*
+ If argv0 starts with a slash, it is already an absolute
+ file path.
+ */
+ absPath = argv0;
+ } else if ( argv0.tqfind('/') != -1 ) {
+ /*
+ If argv0 tqcontains one or more slashes, it is a file path
+ relative to the current directory.
+ */
+ absPath = TQDir::current().absFilePath( argv0 );
+ } else {
+ /*
+ Otherwise, the file path has to be determined using the
+ PATH environment variable.
+ */
+ char *pEnv = getenv( "PATH" );
+ TQStringList paths( TQStringList::split(TQChar(':'), pEnv) );
+ TQStringList::const_iterator p = paths.begin();
+ while ( p != paths.end() ) {
+ TQString candidate = TQDir::current().absFilePath( *p + "/" + argv0 );
+ if ( TQFile::exists(candidate) ) {
+ absPath = candidate;
+ break;
+ }
+ ++p;
+ }
+ }
+
+ absPath = TQDir::cleanDirPath( absPath );
+ if ( TQFile::exists(absPath) ) {
+ return resolveSymlinks( absPath );
+ } else {
+ return TQString::null;
+ }
+#endif
+}
+#endif // TQT_NO_DIR
+
+#ifndef TQT_NO_COMPONENT
+
+/*!
+ Returns a list of paths that the application will search when
+ dynamically loading libraries.
+ The installation directory for plugins is the only entry if no
+ paths have been set. The default installation directory for plugins
+ is \c INSTALL/plugins, where \c INSTALL is the directory where TQt was
+ installed. The directory of the application executable (NOT the
+ working directory) is also added to the plugin paths.
+
+ If you want to iterate over the list, you should iterate over a
+ copy, e.g.
+ \code
+ TQStringList list = app.libraryPaths();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ See the \link plugins-howto.html plugins documentation\endlink for a
+ description of how the library paths are used.
+
+ \sa tqsetLibraryPaths(), addLibraryPath(), removeLibraryPath(), TQLibrary
+*/
+TQStringList TQApplication::libraryPaths()
+{
+ if ( !app_libpaths ) {
+ app_libpaths = new TQStringList;
+ TQString installPathPlugins = TQString::fromLocal8Bit(qInstallPathPlugins());
+ if ( TQFile::exists(installPathPlugins) ) {
+#ifdef TQ_WS_WIN
+ installPathPlugins.tqreplace('\\', '/');
+#endif
+ app_libpaths->append(installPathPlugins);
+ }
+
+ TQString app_location;
+ if (tqApp)
+ app_location = tqApp->applicationFilePath();
+#ifdef TQ_WS_WIN
+ else {
+ app_location = TQString(tqAppFileName());
+ app_location.tqreplace('\\', '/');
+ }
+#endif
+ if (!app_location.isEmpty()) {
+ app_location.truncate( app_location.tqfindRev( '/' ) );
+ if ( app_location != qInstallPathPlugins() && TQFile::exists( app_location ) )
+ app_libpaths->append( app_location );
+ }
+ }
+ return *app_libpaths;
+}
+
+
+/*!
+ Sets the list of directories to search when loading libraries to \a paths.
+ All existing paths will be deleted and the path list will consist of the
+ paths given in \a paths.
+
+ \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), TQLibrary
+ */
+void TQApplication::tqsetLibraryPaths( const TQStringList &paths )
+{
+ delete app_libpaths;
+ app_libpaths = new TQStringList( paths );
+}
+
+/*!
+ Append \a path to the end of the library path list. If \a path is
+ empty or already in the path list, the path list is not changed.
+
+ The default path list consists of a single entry, the installation
+ directory for plugins. The default installation directory for plugins
+ is \c INSTALL/plugins, where \c INSTALL is the directory where TQt was
+ installed.
+
+ \sa removeLibraryPath(), libraryPaths(), tqsetLibraryPaths()
+ */
+void TQApplication::addLibraryPath( const TQString &path )
+{
+ if ( path.isEmpty() )
+ return;
+
+ // make sure that library paths is initialized
+ libraryPaths();
+
+ if ( !app_libpaths->tqcontains( path ) )
+ app_libpaths->prepend( path );
+}
+
+/*!
+ Removes \a path from the library path list. If \a path is empty or not
+ in the path list, the list is not changed.
+
+ \sa addLibraryPath(), libraryPaths(), tqsetLibraryPaths()
+*/
+void TQApplication::removeLibraryPath( const TQString &path )
+{
+ if ( path.isEmpty() )
+ return;
+
+ // make sure that library paths is initialized
+ libraryPaths();
+
+ if ( app_libpaths->tqcontains( path ) )
+ app_libpaths->remove( path );
+}
+#endif //TQT_NO_COMPONENT
+
+/*!
+ Returns the application palette.
+
+ If a widget is passed in \a w, the default palette for the
+ widget's class is returned. This may or may not be the application
+ palette. In most cases there isn't a special palette for certain
+ types of widgets, but one notable exception is the popup menu under
+ Windows, if the user has defined a special background color for
+ menus in the display settings.
+
+ \sa setPalette(), TQWidget::palette()
+*/
+#ifndef TQT_NO_PALETTE
+TQPalette TQApplication::palette(const TQWidget* w)
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !tqApp )
+ qWarning( "TQApplication::palette: This function can only be "
+ "called after the TQApplication object has been created" );
+#endif
+ if ( !app_pal ) {
+ if ( !qt_std_pal )
+ qt_create_std_palette();
+ app_pal = new TQPalette( *qt_std_pal );
+ qt_fix_tooltips();
+ }
+
+ if ( w && app_palettes ) {
+ TQPalette* wp = app_palettes->tqfind( w->className() );
+ if ( wp )
+ return *wp;
+ TQAsciiDictIterator<TQPalette> it( *app_palettes );
+ const char* name;
+ while ( (name=it.currentKey()) != 0 ) {
+ if ( w->inherits( name ) )
+ return *it.current();
+ ++it;
+ }
+ }
+ return *app_pal;
+}
+
+/*!
+ Changes the default application palette to \a palette. If \a
+ informWidgets is TRUE, then existing widgets are informed about the
+ change and may adjust themselves to the new application
+ setting. If \a informWidgets is FALSE, the change only affects newly
+ created widgets.
+
+ If \a className is passed, the change applies only to widgets that
+ inherit \a className (as reported by TQObject::inherits()). If
+ \a className is left 0, the change affects all widgets, thus overriding
+ any previously set class specific palettes.
+
+ The palette may be changed according to the current GUI style in
+ TQStyle::polish().
+
+ \sa TQWidget::setPalette(), palette(), TQStyle::polish()
+*/
+
+void TQApplication::setPalette( const TQPalette &palette, bool informWidgets,
+ const char* className )
+{
+ TQPalette pal = palette;
+ TQPalette *oldpal = 0;
+#ifndef TQT_NO_STYLE
+ if ( !startingUp() ) // on startup this has been done already
+ tqApp->style().polish( pal ); // NB: non-const reference
+#endif
+ bool all = FALSE;
+ if ( !className ) {
+ if ( !app_pal ) {
+ app_pal = new TQPalette( pal );
+ TQ_CHECK_PTR( app_pal );
+ } else {
+ *app_pal = pal;
+ }
+ all = app_palettes != 0;
+ delete app_palettes;
+ app_palettes = 0;
+ qt_fix_tooltips();
+ } else {
+ if ( !app_palettes ) {
+ app_palettes = new TQAsciiDict<TQPalette>;
+ TQ_CHECK_PTR( app_palettes );
+ app_palettes->setAutoDelete( TRUE );
+ }
+ oldpal = app_palettes->tqfind( className );
+ app_palettes->insert( className, new TQPalette( pal ) );
+ }
+ if ( informWidgets && is_app_running && !is_app_closing ) {
+ if ( !oldpal || ( *oldpal != pal ) ) {
+ TQEvent e( TQEvent::ApplicationPaletteChange );
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets...
+ ++it;
+ if ( all || (!className && w->isTopLevel() ) || w->inherits(className) ) // matching class
+ sendEvent( w, &e );
+ }
+ }
+ }
+}
+
+#endif // TQT_NO_PALETTE
+
+/*!
+ Returns the default font for the widget \a w, or the default
+ application font if \a w is 0.
+
+ \sa setFont(), fontMetrics(), TQWidget::font()
+*/
+
+TQFont TQApplication::font( const TQWidget *w )
+{
+ if ( w && app_fonts ) {
+ TQFont* wf = app_fonts->tqfind( w->className() );
+ if ( wf )
+ return *wf;
+ TQAsciiDictIterator<TQFont> it( *app_fonts );
+ const char* name;
+ while ( (name=it.currentKey()) != 0 ) {
+ if ( w->inherits( name ) )
+ return *it.current();
+ ++it;
+ }
+ }
+ if ( !app_font ) {
+ app_font = new TQFont( "Helvetica" );
+ TQ_CHECK_PTR( app_font );
+ }
+ return *app_font;
+}
+
+/*! Changes the default application font to \a font. If \a
+ informWidgets is TRUE, then existing widgets are informed about the
+ change and may adjust themselves to the new application
+ setting. If \a informWidgets is FALSE, the change only affects newly
+ created widgets. If \a className is passed, the change applies only
+ to classes that inherit \a className (as reported by
+ TQObject::inherits()).
+
+ On application start-up, the default font depends on the window
+ system. It can vary depending on both the window system version and
+ the locale. This function lets you override the default font; but
+ overriding may be a bad idea because, for example, some locales need
+ extra-large fonts to support their special characters.
+
+ \sa font(), fontMetrics(), TQWidget::setFont()
+*/
+
+void TQApplication::setFont( const TQFont &font, bool informWidgets,
+ const char* className )
+{
+ bool all = FALSE;
+ if ( !className ) {
+ qt_app_has_font = TRUE;
+ if ( !app_font ) {
+ app_font = new TQFont( font );
+ TQ_CHECK_PTR( app_font );
+ } else {
+ *app_font = font;
+ }
+
+ // make sure the application font is complete
+ app_font->detach();
+ app_font->d->tqmask = TQFontPrivate::Complete;
+
+ all = app_fonts != 0;
+ delete app_fonts;
+ app_fonts = 0;
+ } else {
+ if (!app_fonts){
+ app_fonts = new TQAsciiDict<TQFont>;
+ TQ_CHECK_PTR( app_fonts );
+ app_fonts->setAutoDelete( TRUE );
+ }
+ TQFont* fnt = new TQFont(font);
+ TQ_CHECK_PTR( fnt );
+ app_fonts->insert(className, fnt);
+ }
+ if ( informWidgets && is_app_running && !is_app_closing ) {
+ TQEvent e( TQEvent::ApplicationFontChange );
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets...
+ ++it;
+ if ( all || (!className && w->isTopLevel() ) || w->inherits(className) ) // matching class
+ sendEvent( w, &e );
+ }
+ }
+}
+
+
+/*!
+ Initialization of the appearance of the widget \a w \e before it is first
+ shown.
+
+ Usually widgets call this automatically when they are polished. It
+ may be used to do some style-based central customization of widgets.
+
+ Note that you are not limited to the public functions of TQWidget.
+ Instead, based on meta information like TQObject::className() you are
+ able to customize any kind of widget.
+
+ \sa TQStyle::polish(), TQWidget::polish(), setPalette(), setFont()
+*/
+
+void TQApplication::polish( TQWidget *w )
+{
+#ifndef TQT_NO_STYLE
+ w->style().polish( w );
+#endif
+}
+
+
+/*!
+ Returns a list of the top level widgets in the application.
+
+ The list is created using \c new and must be deleted by the caller.
+
+ The list is empty (TQPtrList::isEmpty()) if there are no top level
+ widgets.
+
+ Note that some of the top level widgets may be hidden, for example
+ the tooltip if no tooltip is currently shown.
+
+ Example:
+ \code
+ // Show all hidden top level widgets.
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ TQWidgetListIt it( *list ); // iterate over the widgets
+ TQWidget * w;
+ while ( (w=it.current()) != 0 ) { // for each top level widget...
+ ++it;
+ if ( !w->isVisible() )
+ w->show();
+ }
+ delete list; // delete the list, not the widgets
+ \endcode
+
+ \warning Delete the list as soon you have finished using it.
+ The widgets in the list may be deleted by someone else at any time.
+
+ \sa allWidgets(), TQWidget::isTopLevel(), TQWidget::isVisible(),
+ TQPtrList::isEmpty()
+*/
+
+TQWidgetList *TQApplication::tqtopLevelWidgets()
+{
+ return TQWidget::tlwList();
+}
+
+/*!
+ Returns a list of all the widgets in the application.
+
+ The list is created using \c new and must be deleted by the caller.
+
+ The list is empty (TQPtrList::isEmpty()) if there are no widgets.
+
+ Note that some of the widgets may be hidden.
+
+ Example that updates all widgets:
+ \code
+ TQWidgetList *list = TQApplication::allWidgets();
+ TQWidgetListIt it( *list ); // iterate over the widgets
+ TQWidget * w;
+ while ( (w=it.current()) != 0 ) { // for each widget...
+ ++it;
+ w->update();
+ }
+ delete list; // delete the list, not the widgets
+ \endcode
+
+ The TQWidgetList class is defined in the \c tqwidgetlist.h header
+ file.
+
+ \warning Delete the list as soon as you have finished using it.
+ The widgets in the list may be deleted by someone else at any time.
+
+ \sa tqtopLevelWidgets(), TQWidget::isVisible(), TQPtrList::isEmpty(),
+*/
+
+TQWidgetList *TQApplication::allWidgets()
+{
+ return TQWidget::wList();
+}
+
+/*!
+ \fn TQWidget *TQApplication::tqfocusWidget() const
+
+ Returns the application widget that has the keyboard input focus, or
+ 0 if no widget in this application has the focus.
+
+ \sa TQWidget::setFocus(), TQWidget::hasFocus(), activeWindow()
+*/
+
+/*!
+ \fn TQWidget *TQApplication::activeWindow() const
+
+ Returns the application top-level window that has the keyboard input
+ focus, or 0 if no application window has the focus. Note that
+ there might be an activeWindow() even if there is no tqfocusWidget(),
+ for example if no widget in that window accepts key events.
+
+ \sa TQWidget::setFocus(), TQWidget::hasFocus(), tqfocusWidget()
+*/
+
+/*!
+ Returns display (screen) font metrics for the application font.
+
+ \sa font(), setFont(), TQWidget::fontMetrics(), TQPainter::fontMetrics()
+*/
+
+TQFontMetrics TQApplication::fontMetrics()
+{
+ return desktop()->fontMetrics();
+}
+
+
+
+/*!
+ Tells the application to exit with return code 0 (success).
+ Equivalent to calling TQApplication::exit( 0 ).
+
+ It's common to connect the lastWindowClosed() signal to quit(), and
+ you also often connect e.g. TQButton::clicked() or Q_SIGNALS in
+ TQAction, TQPopupMenu or TQMenuBar to it.
+
+ Example:
+ \code
+ TQPushButton *quitButton = new TQPushButton( "Quit" );
+ connect( quitButton, TQT_SIGNAL(clicked()), tqApp, TQT_SLOT(quit()) );
+ \endcode
+
+ \sa exit() aboutToQuit() lastWindowClosed() TQAction
+*/
+
+void TQApplication::quit()
+{
+ TQApplication::exit( 0 );
+}
+
+
+/*!
+ Closes all top-level windows.
+
+ This function is particularly useful for applications with many
+ top-level windows. It could, for example, be connected to a "Quit"
+ entry in the file menu as shown in the following code example:
+
+ \code
+ // the "Quit" menu entry should try to close all windows
+ TQPopupMenu* file = new TQPopupMenu( this );
+ file->insertItem( "&Quit", tqApp, TQT_SLOT(closeAllWindows()), CTRL+Key_Q );
+
+ // when the last window is closed, the application should quit
+ connect( tqApp, TQT_SIGNAL( lastWindowClosed() ), tqApp, TQT_SLOT( quit() ) );
+ \endcode
+
+ The windows are closed in random order, until one window does not
+ accept the close event.
+
+ \sa TQWidget::close(), TQWidget::closeEvent(), lastWindowClosed(),
+ quit(), tqtopLevelWidgets(), TQWidget::isTopLevel()
+
+ */
+void TQApplication::closeAllWindows()
+{
+ bool did_close = TRUE;
+ TQWidget *w;
+ while((w = activeModalWidget()) && did_close) {
+ if(w->isHidden())
+ break;
+ did_close = w->close();
+ }
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ for ( w = list->first(); did_close && w; ) {
+ if ( !w->isHidden() ) {
+ did_close = w->close();
+ delete list;
+ list = TQApplication::tqtopLevelWidgets();
+ w = list->first();
+ } else {
+ w = list->next();
+ }
+ }
+ delete list;
+}
+
+/*!
+ Displays a simple message box about TQt. The message includes the
+ version number of TQt being used by the application.
+
+ This is useful for inclusion in the Help menu of an application.
+ See the examples/menu/menu.cpp example.
+
+ This function is a convenience slot for TQMessageBox::aboutTQt().
+*/
+void TQApplication::aboutTQt()
+{
+#ifndef TQT_NO_MESSAGEBOX
+ TQMessageBox::aboutTQt( mainWidget() );
+#endif // TQT_NO_MESSAGEBOX
+}
+
+
+/*!
+ \fn void TQApplication::lastWindowClosed()
+
+ This signal is emitted when the user has closed the last
+ top level window.
+
+ The signal is very useful when your application has many top level
+ widgets but no main widget. You can then connect it to the quit()
+ slot.
+
+ For convenience, this signal is \e not emitted for transient top level
+ widgets such as popup menus and dialogs.
+
+ \sa mainWidget(), tqtopLevelWidgets(), TQWidget::isTopLevel(), TQWidget::close()
+*/
+
+/*!
+ \fn void TQApplication::aboutToQuit()
+
+ This signal is emitted when the application is about to quit the
+ main event loop, e.g. when the event loop level drops to zero.
+ This may happen either after a call to quit() from inside the
+ application or when the users shuts down the entire desktop session.
+
+ The signal is particularly useful if your application has to do some
+ last-second cleanup. Note that no user interaction is possible in
+ this state.
+
+ \sa quit()
+*/
+
+
+/*!
+ \fn void TQApplication::guiThreadAwake()
+
+ This signal is emitted after the event loop returns from a function
+ that could block.
+
+ \sa wakeUpGuiThread()
+*/
+
+
+/*!
+ \fn bool TQApplication::sendEvent( TQObject *receiver, TQEvent *event )
+
+ Sends event \a event directly to receiver \a receiver, using the
+ notify() function. Returns the value that was returned from the event
+ handler.
+
+ The event is \e not deleted when the event has been sent. The normal
+ approach is to create the event on the stack, e.g.
+ \code
+ TQMouseEvent me( TQEvent::MouseButtonPress, pos, 0, 0 );
+ TQApplication::sendEvent( mainWindow, &me );
+ \endcode
+ If you create the event on the heap you must delete it.
+
+ \sa postEvent(), notify()
+*/
+
+/*!
+ Sends event \a e to \a receiver: \a {receiver}->event(\a e).
+ Returns the value that is returned from the receiver's event handler.
+
+ For certain types of events (e.g. mouse and key events),
+ the event will be propagated to the receiver's tqparent and so on up to
+ the top-level object if the receiver is not interested in the event
+ (i.e., it returns FALSE).
+
+ There are five different ways that events can be processed;
+ reimplementing this virtual function is just one of them. All five
+ approaches are listed below:
+ \list 1
+ \i Reimplementing this function. This is very powerful, providing
+ complete control; but only one subclass can be tqApp.
+
+ \i Installing an event filter on tqApp. Such an event filter is able
+ to process all events for all widgets, so it's just as powerful as
+ reimplementing notify(); furthermore, it's possible to have more
+ than one application-global event filter. Global event filters even
+ see mouse events for \link TQWidget::isEnabled() disabled
+ widgets, \endlink and if \link setGlobalMouseTracking() global mouse
+ tracking \endlink is enabled, as well as mouse move events for all
+ widgets.
+
+ \i Reimplementing TQObject::event() (as TQWidget does). If you do
+ this you get Tab key presses, and you get to see the events before
+ any widget-specific event filters.
+
+ \i Installing an event filter on the object. Such an event filter
+ gets all the events except Tab and Shift-Tab key presses.
+
+ \i Reimplementing paintEvent(), mousePressEvent() and so
+ on. This is the commonest, easiest and least powerful way.
+ \endlist
+
+ \sa TQObject::event(), installEventFilter()
+*/
+
+bool TQApplication::notify( TQObject *receiver, TQEvent *e )
+{
+ // no events are delivered after ~TQApplication() has started
+ if ( is_app_closing )
+ return FALSE;
+
+ if ( receiver == 0 ) { // serious error
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQApplication::notify: Unexpected null receiver" );
+#endif
+ return FALSE;
+ }
+
+ if ( e->type() == TQEvent::ChildRemoved && receiver->postedEvents && globalPostedEvents) {
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( postevent_mutex );
+#endif // TQT_THREAD_SUPPORT
+
+ // the TQObject destructor calls TQObject::removeChild, which calls
+ // TQApplication::sendEvent() directly. this can happen while the event
+ // loop is in the middle of posting events, and when we get here, we may
+ // not have any more posted events for this object.
+ if ( receiver->postedEvents ) {
+ // if this is a child remove event and the child insert
+ // hasn't been dispatched yet, kill that insert
+ TQPostEventList * l = receiver->postedEvents;
+ TQObject * c = ((TQChildEvent*)e)->child();
+ TQPostEvent * pe;
+ l->first();
+ while( ( pe = l->current()) != 0 ) {
+ if ( pe->event && pe->receiver == receiver &&
+ pe->event->type() == TQEvent::ChildInserted &&
+ ((TQChildEvent*)pe->event)->child() == c ) {
+ pe->event->posted = FALSE;
+ delete pe->event;
+ pe->event = 0;
+ l->remove();
+ continue;
+ }
+ l->next();
+ }
+ }
+ }
+
+ bool res = FALSE;
+ if ( !receiver->isWidgetType() )
+ res = internalNotify( receiver, e );
+ else switch ( e->type() ) {
+#ifndef TQT_NO_ACCEL
+ case TQEvent::Accel:
+ {
+ TQKeyEvent* key = (TQKeyEvent*) e;
+ res = internalNotify( receiver, e );
+
+ if ( !res && !key->isAccepted() )
+ res = qt_dispatchAccelEvent( (TQWidget*)receiver, key );
+
+ // next lines are for compatibility with TQt <= 3.0.x: old
+ // TQAccel was listening on toplevel widgets
+ if ( !res && !key->isAccepted() && !((TQWidget*)receiver)->isTopLevel() )
+ res = internalNotify( ((TQWidget*)receiver)->tqtopLevelWidget(), e );
+ }
+ break;
+#endif //TQT_NO_ACCEL
+ case TQEvent::KeyPress:
+ case TQEvent::KeyRelease:
+ case TQEvent::AccelOverride:
+ {
+ TQWidget* w = (TQWidget*)receiver;
+ TQKeyEvent* key = (TQKeyEvent*) e;
+#ifndef TQT_NO_ACCEL
+ if ( qt_tryComposeUnicode( w, key ) )
+ break;
+#endif
+ bool def = key->isAccepted();
+ while ( w ) {
+ if ( def )
+ key->accept();
+ else
+ key->ignore();
+ res = internalNotify( w, e );
+ if ( res || key->isAccepted() )
+ break;
+ w = w->parentWidget( TRUE );
+ }
+ }
+ break;
+ case TQEvent::MouseButtonPress:
+ if ( e->spontaneous() ) {
+ TQWidget* fw = (TQWidget*)receiver;
+ while ( fw->focusProxy() )
+ fw = fw->focusProxy();
+ if ( fw->isEnabled() && fw->focusPolicy() & TQWidget::ClickFocus ) {
+ TQFocusEvent::setReason( TQFocusEvent::Mouse);
+ fw->setFocus();
+ TQFocusEvent::resetReason();
+ }
+ }
+ // fall through intended
+ case TQEvent::MouseButtonRelease:
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::MouseMove:
+ {
+ TQWidget* w = (TQWidget*)receiver;
+ TQMouseEvent* mouse = (TQMouseEvent*) e;
+ TQPoint relpos = mouse->pos();
+ while ( w ) {
+ TQMouseEvent me(mouse->type(), relpos, mouse->globalPos(), mouse->button(), mouse->state());
+ me.spont = mouse->spontaneous();
+ res = internalNotify( w, w == receiver ? mouse : &me );
+ e->spont = FALSE;
+ if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ if ( res )
+ mouse->accept();
+ else
+ mouse->ignore();
+ }
+ break;
+#ifndef TQT_NO_WHEELEVENT
+ case TQEvent::Wheel:
+ {
+ if ( e->spontaneous() ) {
+ TQWidget* fw = (TQWidget*)receiver;
+ while ( fw->focusProxy() )
+ fw = fw->focusProxy();
+ if ( fw->isEnabled() && (fw->focusPolicy() & TQWidget::WheelFocus) == TQWidget::WheelFocus ) {
+ TQFocusEvent::setReason( TQFocusEvent::Mouse);
+ fw->setFocus();
+ TQFocusEvent::resetReason();
+ }
+ }
+
+ TQWidget* w = (TQWidget*)receiver;
+ TQWheelEvent* wheel = (TQWheelEvent*) e;
+ TQPoint relpos = wheel->pos();
+ while ( w ) {
+ TQWheelEvent we(relpos, wheel->globalPos(), wheel->delta(), wheel->state(), wheel->orientation());
+ we.spont = wheel->spontaneous();
+ res = internalNotify( w, w == receiver ? wheel : &we );
+ e->spont = FALSE;
+ if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ if ( res )
+ wheel->accept();
+ else
+ wheel->ignore();
+ }
+ break;
+#endif
+ case TQEvent::ContextMenu:
+ {
+ TQWidget* w = (TQWidget*)receiver;
+ TQContextMenuEvent *context = (TQContextMenuEvent*) e;
+ TQPoint relpos = context->pos();
+ while ( w ) {
+ TQContextMenuEvent ce(context->reason(), relpos, context->globalPos(), context->state());
+ ce.spont = e->spontaneous();
+ res = internalNotify( w, w == receiver ? context : &ce );
+ e->spont = FALSE;
+
+ if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ if ( res )
+ context->accept();
+ else
+ context->ignore();
+ }
+ break;
+#if defined (TQT_TABLET_SUPPORT)
+ case TQEvent::TabletMove:
+ case TQEvent::TabletPress:
+ case TQEvent::TabletRelease:
+ {
+ TQWidget *w = (TQWidget*)receiver;
+ TQTabletEvent *tablet = (TQTabletEvent*)e;
+ TQPoint relpos = tablet->pos();
+ while ( w ) {
+ TQTabletEvent te(tablet->pos(), tablet->globalPos(), tablet->tqdevice(),
+ tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
+ tablet->uniqueId());
+ te.spont = e->spontaneous();
+ res = internalNotify( w, w == receiver ? tablet : &te );
+ e->spont = FALSE;
+ if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ if ( res )
+ tablet->accept();
+ else
+ tablet->ignore();
+ chokeMouse = tablet->isAccepted();
+ }
+ break;
+#endif
+ default:
+ res = internalNotify( receiver, e );
+ break;
+ }
+
+ return res;
+}
+
+/*!\reimp
+
+*/
+bool TQApplication::event( TQEvent *e )
+{
+ if(e->type() == TQEvent::Close) {
+ TQCloseEvent *ce = (TQCloseEvent*)e;
+ ce->accept();
+ closeAllWindows();
+
+ TQWidgetList *list = tqtopLevelWidgets();
+ for(TQWidget *w = list->first(); w; w = list->next()) {
+ if ( !w->isHidden() && !w->isDesktop() && !w->isPopup() &&
+ (!w->isDialog() || !w->parentWidget())) {
+ ce->ignore();
+ break;
+ }
+ }
+ if(ce->isAccepted())
+ return TRUE;
+ } else if (e->type() == TQEvent::Quit) {
+ quit();
+ return TRUE;
+ }
+ return TQObject::event(e);
+}
+
+/*!\internal
+
+ Helper function called by notify()
+ */
+bool TQApplication::internalNotify( TQObject *receiver, TQEvent * e)
+{
+ if ( eventFilters ) {
+ TQObjectListIt it( *eventFilters );
+ register TQObject *obj;
+ while ( (obj=it.current()) != 0 ) { // send to all filters
+ ++it; // until one returns TRUE
+ if ( obj->eventFilter(receiver,e) )
+ return TRUE;
+ }
+ }
+
+ bool consumed = FALSE;
+ bool handled = FALSE;
+ if ( receiver->isWidgetType() ) {
+ TQWidget *widget = (TQWidget*)receiver;
+
+ // toggle HasMouse widget state on enter and leave
+ if ( e->type() == TQEvent::Enter || e->type() == TQEvent::DragEnter )
+ widget->setWState( WState_HasMouse );
+ else if ( e->type() == TQEvent::Leave || e->type() == TQEvent::DragLeave )
+ widget->clearWState( WState_HasMouse );
+
+ // throw away any mouse-tracking-only mouse events
+ if ( e->type() == TQEvent::MouseMove &&
+ (((TQMouseEvent*)e)->state()&TQMouseEvent::MouseButtonMask) == 0 &&
+ !widget->hasMouseTracking() ) {
+ handled = TRUE;
+ consumed = TRUE;
+ } else if ( !widget->isEnabled() ) { // throw away mouse events to disabled widgets
+ switch(e->type()) {
+ case TQEvent::MouseButtonPress:
+ case TQEvent::MouseButtonRelease:
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::MouseMove:
+ ( (TQMouseEvent*) e)->ignore();
+ handled = TRUE;
+ consumed = TRUE;
+ break;
+#ifndef TQT_NO_DRAGANDDROP
+ case TQEvent::DragEnter:
+ case TQEvent::DragMove:
+ ( (TQDragMoveEvent*) e)->ignore();
+ handled = TRUE;
+ break;
+
+ case TQEvent::DragLeave:
+ case TQEvent::DragResponse:
+ handled = TRUE;
+ break;
+
+ case TQEvent::Drop:
+ ( (TQDropEvent*) e)->ignore();
+ handled = TRUE;
+ break;
+#endif
+#ifndef TQT_NO_WHEELEVENT
+ case TQEvent::Wheel:
+ ( (TQWheelEvent*) e)->ignore();
+ handled = TRUE;
+ break;
+#endif
+ case TQEvent::ContextMenu:
+ ( (TQContextMenuEvent*) e)->ignore();
+ handled = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ }
+
+ if (!handled)
+ consumed = receiver->event( e );
+ e->spont = FALSE;
+ return consumed;
+}
+
+/*!
+ Returns TRUE if an application object has not been created yet;
+ otherwise returns FALSE.
+
+ \sa closingDown()
+*/
+
+bool TQApplication::startingUp()
+{
+ return !is_app_running;
+}
+
+/*!
+ Returns TRUE if the application objects are being destroyed;
+ otherwise returns FALSE.
+
+ \sa startingUp()
+*/
+
+bool TQApplication::closingDown()
+{
+ return is_app_closing;
+}
+
+
+/*!
+ Processes pending events, for 3 seconds or until there are no more
+ events to process, whichever is shorter.
+
+ You can call this function occasionally when your program is busy
+ performing a long operation (e.g. copying a file).
+
+ \sa exec(), TQTimer, TQEventLoop::processEvents()
+*/
+
+void TQApplication::processEvents()
+{
+ processEvents( 3000 );
+}
+
+/*!
+ \overload
+
+ Processes pending events for \a maxtime milliseconds or until
+ there are no more events to process, whichever is shorter.
+
+ You can call this function occasionally when you program is busy
+ doing a long operation (e.g. copying a file).
+
+ \sa exec(), TQTimer, TQEventLoop::processEvents()
+*/
+void TQApplication::processEvents( int maxtime )
+{
+ eventLoop()->processEvents( TQEventLoop::AllEvents, maxtime );
+}
+
+/*! \obsolete
+ Waits for an event to occur, processes it, then returns.
+
+ This function is useful for adapting TQt to situations where the
+ event processing must be grafted onto existing program loops.
+
+ Using this function in new applications may be an indication of design
+ problems.
+
+ \sa processEvents(), exec(), TQTimer
+*/
+
+void TQApplication::processOneEvent()
+{
+ eventLoop()->processEvents( TQEventLoop::AllEvents |
+ TQEventLoop::WaitForMore );
+}
+
+/*****************************************************************************
+ Main event loop wrappers
+ *****************************************************************************/
+
+/*!
+ Returns the application event loop. This function will return
+ zero if called during and after destroying TQApplication.
+
+ To create your own instance of TQEventLoop or TQEventLoop subclass create
+ it before you create the TQApplication object.
+
+ \sa TQEventLoop
+*/
+TQEventLoop *TQApplication::eventLoop()
+{
+ if ( !eventloop && !is_app_closing )
+ (void) new TQEventLoop( tqApp, "default event loop" );
+ return eventloop;
+}
+
+
+/*!
+ Enters the main event loop and waits until exit() is called or the
+ main widget is destroyed, and returns the value that was set to
+ exit() (which is 0 if exit() is called via quit()).
+
+ It is necessary to call this function to start event handling. The
+ main event loop receives events from the window system and
+ dispatches these to the application widgets.
+
+ Generally speaking, no user interaction can take place before
+ calling exec(). As a special case, modal widgets like TQMessageBox
+ can be used before calling exec(), because modal widgets call
+ exec() to start a local event loop.
+
+ To make your application perform idle processing, i.e. executing a
+ special function whenever there are no pending events, use a
+ TQTimer with 0 timeout. More advanced idle processing schemes can
+ be achieved using processEvents().
+
+ \sa quit(), exit(), processEvents(), setMainWidget()
+*/
+int TQApplication::exec()
+{
+ return eventLoop()->exec();
+}
+
+/*!
+ Tells the application to exit with a return code.
+
+ After this function has been called, the application leaves the main
+ event loop and returns from the call to exec(). The exec() function
+ returns \a retcode.
+
+ By convention, a \a retcode of 0 means success, and any non-zero
+ value indicates an error.
+
+ Note that unlike the C library function of the same name, this
+ function \e does return to the caller -- it is event processing that
+ stops.
+
+ \sa quit(), exec()
+*/
+void TQApplication::exit( int retcode )
+{
+ tqApp->eventLoop()->exit( retcode );
+}
+
+/*!
+ \obsolete
+
+ This function enters the main event loop (recursively). Do not call
+ it unless you really know what you are doing.
+
+ Use TQApplication::eventLoop()->enterLoop() instead.
+
+*/
+int TQApplication::enter_loop()
+{
+ return eventLoop()->enterLoop();
+}
+
+/*!
+ \obsolete
+
+ This function exits from a recursive call to the main event loop.
+ Do not call it unless you are an expert.
+
+ Use TQApplication::eventLoop()->exitLoop() instead.
+
+*/
+void TQApplication::exit_loop()
+{
+ eventLoop()->exitLoop();
+}
+
+/*!
+ \obsolete
+
+ Returns the current loop level.
+
+ Use TQApplication::eventLoop()->loopLevel() instead.
+
+*/
+int TQApplication::loopLevel() const
+{
+ return eventLoop()->loopLevel();
+}
+
+/*!
+
+ Wakes up the GUI thread.
+
+ \sa guiThreadAwake() \link threads.html Thread Support in TQt\endlink
+*/
+void TQApplication::wakeUpGuiThread()
+{
+ eventLoop()->wakeUp();
+}
+
+/*!
+ This function returns TRUE if there are pending events; otherwise
+ returns FALSE. Pending events can be either from the window system
+ or posted events using TQApplication::postEvent().
+*/
+bool TQApplication::hasPendingEvents()
+{
+ return eventLoop()->hasPendingEvents();
+}
+
+#if !defined(TQ_WS_X11)
+
+// The doc and X implementation of these functions is in qapplication_x11.cpp
+
+void TQApplication::flushX() {} // do nothing
+
+void TQApplication::syncX() {} // do nothing
+
+#endif
+
+/*!
+ \fn void TQApplication::setWinStyleHighlightColor( const TQColor & )
+ \obsolete
+
+ Sets the color used to mark selections in windows style for all widgets
+ in the application. Will tqrepaint all widgets if the color is changed.
+
+ The default color is \c darkBlue.
+ \sa winStyleHighlightColor()
+*/
+
+/*!
+ \fn const TQColor& TQApplication::winStyleHighlightColor()
+ \obsolete
+
+ Returns the color used to mark selections in windows style.
+
+ \sa setWinStyleHighlightColor()
+*/
+
+/*!
+ Returns the version of the Windows operating system that is running:
+
+ \list
+ \i TQt::WV_95 - Windows 95
+ \i TQt::WV_98 - Windows 98
+ \i TQt::WV_Me - Windows Me
+ \i TQt::WV_NT - Windows NT 4.x
+ \i TQt::WV_2000 - Windows 2000 (NT5)
+ \i TQt::WV_XP - Windows XP
+ \i TQt::WV_2003 - Windows Server 2003 family
+ \i TQt::WV_CE - Windows CE
+ \i TQt::WV_CENET - Windows CE.NET
+ \endlist
+
+ Note that this function is implemented for the Windows version
+ of TQt only.
+*/
+
+#if defined(TQ_OS_CYGWIN)
+TQt::WindowsVersion TQApplication::winVersion()
+{
+ return qt_winver;
+}
+#endif
+
+#ifndef TQT_NO_TRANSLATION
+
+bool qt_detectRTLLanguage()
+{
+ return TQApplication::tr( "TQT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right"
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew"
+ " and Arabic) to get proper widget tqlayout." ) == "RTL";
+}
+
+/*!
+ Adds the message file \a mf to the list of message files to be used
+ for translations.
+
+ Multiple message files can be installed. Translations are searched
+ for in the last installed message file, then the one from last, and
+ so on, back to the first installed message file. The search stops as
+ soon as a matching translation is found.
+
+ \sa removeTranslator() translate() TQTranslator::load()
+*/
+
+void TQApplication::installTranslator( TQTranslator * mf )
+{
+ if ( !mf )
+ return;
+ if ( !translators )
+ translators = new TQValueList<TQTranslator*>;
+
+ translators->prepend( mf );
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ if ( mf->isEmpty() )
+ return;
+#endif
+
+ // hook to set the tqlayout direction of dialogs
+ setReverseLayout( qt_detectRTLLanguage() );
+
+ TQWidgetList *list = tqtopLevelWidgets();
+ TQWidgetListIt it( *list );
+ TQWidget *w;
+ while ( ( w=it.current() ) != 0 ) {
+ ++it;
+ if (!w->isDesktop())
+ postEvent( w, new TQEvent( TQEvent::LanguageChange ) );
+ }
+ delete list;
+}
+
+/*!
+ Removes the message file \a mf from the list of message files used by
+ this application. (It does not delete the message file from the file
+ system.)
+
+ \sa installTranslator() translate(), TQObject::tr()
+*/
+
+void TQApplication::removeTranslator( TQTranslator * mf )
+{
+ if ( !translators || !mf )
+ return;
+
+ if ( translators->remove( mf ) && ! tqApp->closingDown() ) {
+ setReverseLayout( qt_detectRTLLanguage() );
+
+ TQWidgetList *list = tqtopLevelWidgets();
+ TQWidgetListIt it( *list );
+ TQWidget *w;
+ while ( ( w=it.current() ) != 0 ) {
+ ++it;
+ postEvent( w, new TQEvent( TQEvent::LanguageChange ) );
+ }
+ delete list;
+ }
+}
+
+#ifndef TQT_NO_TEXTCODEC
+/*! \obsolete
+ This is the same as TQTextCodec::setCodecForTr().
+*/
+void TQApplication::setDefaultCodec( TQTextCodec* codec )
+{
+ TQTextCodec::setCodecForTr( codec );
+}
+
+/*! \obsolete
+ Returns TQTextCodec::codecForTr().
+*/
+TQTextCodec* TQApplication::defaultCodec() const
+{
+ return TQTextCodec::codecForTr();
+}
+#endif //TQT_NO_TEXTCODEC
+
+/*! \enum TQApplication::Encoding
+
+ This enum type defines the 8-bit encoding of character string
+ arguments to translate():
+
+ \value DefaultCodec - the encoding specified by
+ TQTextCodec::codecForTr() (Latin-1 if none has been set)
+ \value UnicodeUTF8 - UTF-8
+
+ \sa TQObject::tr(), TQObject::trUtf8(), TQString::fromUtf8()
+*/
+
+/*! \reentrant
+ Returns the translation text for \a sourceText, by querying the
+ installed messages files. The message files are searched from the most
+ recently installed message file back to the first installed message
+ file.
+
+ TQObject::tr() and TQObject::trUtf8() provide this functionality more
+ conveniently.
+
+ \a context is typically a class name (e.g., "MyDialog") and
+ \a sourceText is either English text or a short identifying text, if
+ the output text will be very long (as for help texts).
+
+ \a comment is a disambiguating comment, for when the same \a
+ sourceText is used in different roles within the same context. By
+ default, it is null. \a encoding indicates the 8-bit encoding of
+ character stings
+
+ See the \l TQTranslator documentation for more information about
+ contexts and comments.
+
+ If none of the message files contain a translation for \a
+ sourceText in \a context, this function returns a TQString
+ equivalent of \a sourceText. The encoding of \a sourceText is
+ specified by \e encoding; it defaults to \c DefaultCodec.
+
+ This function is not virtual. You can use alternative translation
+ techniques by subclassing \l TQTranslator.
+
+ \warning This method is reentrant only if all translators are
+ installed \e before calling this method. Installing or removing
+ translators while performing translations is not supported. Doing
+ so will most likely result in crashes or other undesirable behavior.
+
+ \sa TQObject::tr() installTranslator() defaultCodec()
+*/
+
+TQString TQApplication::translate( const char * context, const char * sourceText,
+ const char * comment, Encoding encoding ) const
+{
+ if ( !sourceText )
+ return TQString::null;
+
+ if ( translators ) {
+ TQValueList<TQTranslator*>::iterator it;
+ TQTranslator * mf;
+ TQString result;
+ for ( it = translators->begin(); it != translators->end(); ++it ) {
+ mf = *it;
+ result = mf->tqfindMessage( context, sourceText, comment ).translation();
+ if ( !result.isNull() )
+ return result;
+ }
+ }
+#ifndef TQT_NO_TEXTCODEC
+ if ( encoding == UnicodeUTF8 )
+ return TQString::fromUtf8( sourceText );
+ else if ( TQTextCodec::codecForTr() != 0 )
+ return TQTextCodec::codecForTr()->toUnicode( sourceText );
+ else
+#endif
+ return TQString::tqfromLatin1( sourceText );
+}
+
+#endif
+
+/*****************************************************************************
+ TQApplication management of posted events
+ *****************************************************************************/
+
+//see also notify(), which does the removal of ChildInserted when ChildRemoved.
+
+/*!
+ Adds the event \a event with the object \a receiver as the receiver of the
+ event, to an event queue and returns immediately.
+
+ The event must be allocated on the heap since the post event queue
+ will take ownership of the event and delete it once it has been posted.
+
+ When control returns to the main event loop, all events that are
+ stored in the queue will be sent using the notify() function.
+
+ \threadsafe
+
+ \sa sendEvent(), notify()
+*/
+
+void TQApplication::postEvent( TQObject *receiver, TQEvent *event )
+{
+ if ( receiver == 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQApplication::postEvent: Unexpected null receiver" );
+#endif
+ delete event;
+ return;
+ }
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( postevent_mutex );
+#endif // TQT_THREAD_SUPPORT
+
+ if ( !globalPostedEvents ) { // create list
+ globalPostedEvents = new TQPostEventList;
+ TQ_CHECK_PTR( globalPostedEvents );
+ globalPostedEvents->setAutoDelete( TRUE );
+ qapp_cleanup_events.set( &globalPostedEvents );
+ }
+
+ if ( !receiver->postedEvents )
+ receiver->postedEvents = new TQPostEventList;
+ TQPostEventList * l = receiver->postedEvents;
+
+ // if this is one of the compressible events, do compression
+ if ( event->type() == TQEvent::Paint ||
+ event->type() == TQEvent::LayoutHint ||
+ event->type() == TQEvent::Resize ||
+ event->type() == TQEvent::Move ||
+ event->type() == TQEvent::LanguageChange ) {
+ l->first();
+ TQPostEvent * cur = 0;
+ for ( ;; ) {
+ while ( (cur=l->current()) != 0 &&
+ ( cur->receiver != receiver ||
+ cur->event == 0 ||
+ cur->event->type() != event->type() ) )
+ l->next();
+ if ( l->current() != 0 ) {
+ if ( cur->event->type() == TQEvent::Paint ) {
+ TQPaintEvent * p = (TQPaintEvent*)(cur->event);
+ if ( p->erase != ((TQPaintEvent*)event)->erase ) {
+ l->next();
+ continue;
+ }
+ p->reg = p->reg.unite( ((TQPaintEvent *)event)->reg );
+ p->rec = p->rec.unite( ((TQPaintEvent *)event)->rec );
+ delete event;
+ return;
+ } else if ( cur->event->type() == TQEvent::LayoutHint ) {
+ delete event;
+ return;
+ } else if ( cur->event->type() == TQEvent::Resize ) {
+ ((TQResizeEvent *)(cur->event))->s = ((TQResizeEvent *)event)->s;
+ delete event;
+ return;
+ } else if ( cur->event->type() == TQEvent::Move ) {
+ ((TQMoveEvent *)(cur->event))->p = ((TQMoveEvent *)event)->p;
+ delete event;
+ return;
+ } else if ( cur->event->type() == TQEvent::LanguageChange ) {
+ delete event;
+ return;
+ }
+ }
+ break;
+ };
+ }
+
+ // if no compression could be done, just append something
+ event->posted = TRUE;
+ TQPostEvent * pe = new TQPostEvent( receiver, event );
+ l->append( pe );
+ globalPostedEvents->append( pe );
+
+ if (eventloop)
+ eventloop->wakeUp();
+}
+
+
+/*! \overload
+
+ Dispatches all posted events, i.e. empties the event queue.
+*/
+void TQApplication::sendPostedEvents()
+{
+ sendPostedEvents( 0, 0 );
+}
+
+
+
+/*!
+ Immediately dispatches all events which have been previously queued
+ with TQApplication::postEvent() and which are for the object \a receiver
+ and have the event type \a event_type.
+
+ Note that events from the window system are \e not dispatched by this
+ function, but by processEvents().
+
+ If \a receiver is null, the events of \a event_type are sent for all
+ objects. If \a event_type is 0, all the events are sent for \a receiver.
+*/
+
+void TQApplication::sendPostedEvents( TQObject *receiver, int event_type )
+{
+ // Make sure the object hierarchy is stable before processing events
+ // to avoid endless loops
+ if ( receiver == 0 && event_type == 0 )
+ sendPostedEvents( 0, TQEvent::ChildInserted );
+
+ if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) )
+ return;
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( postevent_mutex );
+#endif
+
+ bool sent = TRUE;
+ while ( sent ) {
+ sent = FALSE;
+
+ if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) )
+ return;
+
+ // if we have a receiver, use the local list. Otherwise, use the
+ // global list
+ TQPostEventList * l = receiver ? receiver->postedEvents : globalPostedEvents;
+
+ // okay. here is the tricky loop. be careful about optimizing
+ // this, it looks the way it does for good reasons.
+ TQPostEventListIt it( *l );
+ TQPostEvent *pe;
+ while ( (pe=it.current()) != 0 ) {
+ ++it;
+ if ( pe->event // hasn't been sent yet
+ && ( receiver == 0 // we send to all tqreceivers
+ || receiver == pe->receiver ) // we send to THAT receiver
+ && ( event_type == 0 // we send all types
+ || event_type == pe->event->type() ) ) { // we send THAT type
+ // first, we diddle the event so that we can deliver
+ // it, and that noone will try to touch it later.
+ pe->event->posted = FALSE;
+ TQEvent * e = pe->event;
+ TQObject * r = pe->receiver;
+ pe->event = 0;
+
+ // next, update the data structure so that we're ready
+ // for the next event.
+
+ // look for the local list, and take whatever we're
+ // delivering out of it. r->postedEvents maybe *l
+ if ( r->postedEvents ) {
+ r->postedEvents->removeRef( pe );
+ // if possible, get rid of that list. this is not
+ // ideal - we will create and delete a list for
+ // each update() call. it would be better if we'd
+ // leave the list empty here, and delete it
+ // somewhere else if it isn't being used.
+ if ( r->postedEvents->isEmpty() ) {
+ delete r->postedEvents;
+ r->postedEvents = 0;
+ }
+ }
+
+#ifdef TQT_THREAD_SUPPORT
+ if ( locker.mutex() ) locker.mutex()->unlock();
+#endif // TQT_THREAD_SUPPORT
+ // after all that work, it's time to deliver the event.
+ if ( e->type() == TQEvent::Paint && r->isWidgetType() ) {
+ TQWidget * w = (TQWidget*)r;
+ TQPaintEvent * p = (TQPaintEvent*)e;
+ if ( w->isVisible() )
+ w->tqrepaint( p->reg, p->erase );
+ } else {
+ sent = TRUE;
+ TQApplication::sendEvent( r, e );
+ }
+#ifdef TQT_THREAD_SUPPORT
+ if ( locker.mutex() ) locker.mutex()->lock();
+#endif // TQT_THREAD_SUPPORT
+
+ delete e;
+ // careful when adding anything below this point - the
+ // sendEvent() call might tqinvalidate any invariants this
+ // function depends on.
+ }
+ }
+
+ // clear the global list, i.e. remove everything that was
+ // delivered.
+ if ( l == globalPostedEvents ) {
+ globalPostedEvents->first();
+ while( (pe=globalPostedEvents->current()) != 0 ) {
+ if ( pe->event )
+ globalPostedEvents->next();
+ else
+ globalPostedEvents->remove();
+ }
+ }
+ }
+}
+
+/*!
+ Removes all events posted using postEvent() for \a receiver.
+
+ The events are \e not dispatched, instead they are removed from the
+ queue. You should never need to call this function. If you do call it,
+ be aware that killing events may cause \a receiver to break one or
+ more invariants.
+
+ \threadsafe
+*/
+
+void TQApplication::removePostedEvents( TQObject *receiver )
+{
+ if ( !receiver )
+ return;
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( postevent_mutex );
+#endif // TQT_THREAD_SUPPORT
+
+ // the TQObject destructor calls this function directly. this can
+ // happen while the event loop is in the middle of posting events,
+ // and when we get here, we may not have any more posted events
+ // for this object.
+ if ( !receiver->postedEvents )
+ return;
+
+ // iterate over the object-specifc list and delete the events.
+ // leave the TQPostEvent objects; they'll be deleted by
+ // sendPostedEvents().
+ TQPostEventList * l = receiver->postedEvents;
+ receiver->postedEvents = 0;
+ l->first();
+ TQPostEvent * pe;
+ while( (pe=l->current()) != 0 ) {
+ if ( pe->event ) {
+ pe->event->posted = FALSE;
+ delete pe->event;
+ pe->event = 0;
+ }
+ l->remove();
+ }
+ delete l;
+}
+
+
+/*!
+ Removes \a event from the queue of posted events, and emits a
+ warning message if appropriate.
+
+ \warning This function can be \e really slow. Avoid using it, if
+ possible.
+
+ \threadsafe
+*/
+
+void TQApplication::removePostedEvent( TQEvent * event )
+{
+ if ( !event || !event->posted )
+ return;
+
+ if ( !globalPostedEvents ) {
+#if defined(TQT_DEBUG)
+ qDebug( "TQApplication::removePostedEvent: %p %d is posted: impossible",
+ (void*)event, event->type() );
+ return;
+#endif
+ }
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( postevent_mutex );
+#endif // TQT_THREAD_SUPPORT
+
+ TQPostEventListIt it( *globalPostedEvents );
+ TQPostEvent * pe;
+ while( (pe = it.current()) != 0 ) {
+ ++it;
+ if ( pe->event == event ) {
+#if defined(TQT_DEBUG)
+ const char *n;
+ switch ( event->type() ) {
+ case TQEvent::Timer:
+ n = "Timer";
+ break;
+ case TQEvent::MouseButtonPress:
+ n = "MouseButtonPress";
+ break;
+ case TQEvent::MouseButtonRelease:
+ n = "MouseButtonRelease";
+ break;
+ case TQEvent::MouseButtonDblClick:
+ n = "MouseButtonDblClick";
+ break;
+ case TQEvent::MouseMove:
+ n = "MouseMove";
+ break;
+#ifndef TQT_NO_WHEELEVENT
+ case TQEvent::Wheel:
+ n = "Wheel";
+ break;
+#endif
+ case TQEvent::KeyPress:
+ n = "KeyPress";
+ break;
+ case TQEvent::KeyRelease:
+ n = "KeyRelease";
+ break;
+ case TQEvent::FocusIn:
+ n = "FocusIn";
+ break;
+ case TQEvent::FocusOut:
+ n = "FocusOut";
+ break;
+ case TQEvent::Enter:
+ n = "Enter";
+ break;
+ case TQEvent::Leave:
+ n = "Leave";
+ break;
+ case TQEvent::Paint:
+ n = "Paint";
+ break;
+ case TQEvent::Move:
+ n = "Move";
+ break;
+ case TQEvent::Resize:
+ n = "Resize";
+ break;
+ case TQEvent::Create:
+ n = "Create";
+ break;
+ case TQEvent::Destroy:
+ n = "Destroy";
+ break;
+ case TQEvent::Close:
+ n = "Close";
+ break;
+ case TQEvent::Quit:
+ n = "Quit";
+ break;
+ default:
+ n = "<other>";
+ break;
+ }
+ qWarning("TQEvent: Warning: %s event deleted while posted to %s %s",
+ n,
+ pe->receiver ? pe->receiver->className() : "null",
+ pe->receiver ? pe->receiver->name() : "object" );
+ // note the beautiful uglehack if !pe->receiver :)
+#endif
+ event->posted = FALSE;
+ delete pe->event;
+ pe->event = 0;
+ return;
+ }
+ }
+}
+
+/*!\internal
+
+ Sets the active window in reaction to a system event. Call this
+ from the platform specific event handlers.
+
+ It sets the activeWindow() and tqfocusWidget() attributes and sends
+ proper WindowActivate/WindowDeactivate and FocusIn/FocusOut events
+ to all appropriate widgets.
+
+ \sa activeWindow()
+ */
+void TQApplication::setActiveWindow( TQWidget* act )
+{
+ TQWidget* window = act?act->tqtopLevelWidget():0;
+
+ if ( active_window == window )
+ return;
+
+ // first the activation/deactivation events
+ if ( active_window ) {
+ TQWidgetList deacts;
+#ifndef TQT_NO_STYLE
+ if ( style().tqstyleHint(TQStyle::SH_Widget_ShareActivation, active_window ) ) {
+ TQWidgetList *list = tqtopLevelWidgets();
+ if ( list ) {
+ for ( TQWidget *w = list->first(); w; w = list->next() ) {
+ if ( w->isVisible() && w->isActiveWindow() )
+ deacts.append(w);
+ }
+ delete list;
+ }
+ } else
+#endif
+ deacts.append(active_window);
+ active_window = 0;
+ TQEvent e( TQEvent::WindowDeactivate );
+ for(TQWidget *w = deacts.first(); w; w = deacts.next())
+ TQApplication::sendSpontaneousEvent( w, &e );
+ }
+
+ active_window = window;
+ if ( active_window ) {
+ TQEvent e( TQEvent::WindowActivate );
+ TQWidgetList acts;
+#ifndef TQT_NO_STYLE
+ if ( style().tqstyleHint(TQStyle::SH_Widget_ShareActivation, active_window ) ) {
+ TQWidgetList *list = tqtopLevelWidgets();
+ if ( list ) {
+ for ( TQWidget *w = list->first(); w; w = list->next() ) {
+ if ( w->isVisible() && w->isActiveWindow() )
+ acts.append(w);
+ }
+ delete list;
+ }
+ } else
+#endif
+ acts.append(active_window);
+ for(TQWidget *w = acts.first(); w; w = acts.next())
+ TQApplication::sendSpontaneousEvent( w, &e );
+ }
+
+ // then focus events
+ TQFocusEvent::setReason( TQFocusEvent::ActiveWindow );
+ if ( !active_window && focus_widget ) {
+ TQFocusEvent out( TQEvent::FocusOut );
+ TQWidget *tmp = focus_widget;
+ focus_widget = 0;
+#ifdef TQ_WS_WIN
+ TQInputContext::accept( tmp );
+#endif
+ TQApplication::sendSpontaneousEvent( tmp, &out );
+ } else if ( active_window ) {
+ TQWidget *w = active_window->tqfocusWidget();
+ if ( w && w->focusPolicy() != TQWidget::NoFocus )
+ w->setFocus();
+ else
+ active_window->focusNextPrevChild( TRUE );
+ }
+ TQFocusEvent::resetReason();
+}
+
+
+/*!\internal
+
+ Creates the proper Enter/Leave event when widget \a enter is entered
+ and widget \a leave is left.
+ */
+TQ_EXPORT void qt_dispatchEnterLeave( TQWidget* enter, TQWidget* leave ) {
+#if 0
+ if ( leave ) {
+ TQEvent e( TQEvent::Leave );
+ TQApplication::sendEvent( leave, & e );
+ }
+ if ( enter ) {
+ TQEvent e( TQEvent::Enter );
+ TQApplication::sendEvent( enter, & e );
+ }
+ return;
+#endif
+
+ TQWidget* w ;
+ if ( !enter && !leave )
+ return;
+ TQWidgetList leaveList;
+ TQWidgetList enterList;
+
+ bool sameWindow = leave && enter && leave->tqtopLevelWidget() == enter->tqtopLevelWidget();
+ if ( leave && !sameWindow ) {
+ w = leave;
+ do {
+ leaveList.append( w );
+ } while ( (w = w->parentWidget( TRUE ) ) );
+ }
+ if ( enter && !sameWindow ) {
+ w = enter;
+ do {
+ enterList.prepend( w );
+ } while ( (w = w->parentWidget(TRUE) ) );
+ }
+ if ( sameWindow ) {
+ int enterDepth = 0;
+ int leaveDepth = 0;
+ w = enter;
+ while ( ( w = w->parentWidget( TRUE ) ) )
+ enterDepth++;
+ w = leave;
+ while ( ( w = w->parentWidget( TRUE ) ) )
+ leaveDepth++;
+ TQWidget* wenter = enter;
+ TQWidget* wleave = leave;
+ while ( enterDepth > leaveDepth ) {
+ wenter = wenter->parentWidget();
+ enterDepth--;
+ }
+ while ( leaveDepth > enterDepth ) {
+ wleave = wleave->parentWidget();
+ leaveDepth--;
+ }
+ while ( !wenter->isTopLevel() && wenter != wleave ) {
+ wenter = wenter->parentWidget();
+ wleave = wleave->parentWidget();
+ }
+
+ w = leave;
+ while ( w != wleave ) {
+ leaveList.append( w );
+ w = w->parentWidget();
+ }
+ w = enter;
+ while ( w != wenter ) {
+ enterList.prepend( w );
+ w = w->parentWidget();
+ }
+ }
+
+ TQEvent leaveEvent( TQEvent::Leave );
+ for ( w = leaveList.first(); w; w = leaveList.next() ) {
+ if ( !tqApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
+ TQApplication::sendEvent( w, &leaveEvent );
+ }
+ TQEvent enterEvent( TQEvent::Enter );
+ for ( w = enterList.first(); w; w = enterList.next() ) {
+ if ( !tqApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
+ TQApplication::sendEvent( w, &enterEvent );
+ }
+}
+
+
+#ifdef TQ_WS_MACX
+extern TQWidget *qt_tryModalHelperMac( TQWidget * top ); //qapplication_mac.cpp
+#endif
+
+
+/*!\internal
+
+ Called from qapplication_<platform>.cpp, returns TRUE
+ if the widget should accept the event.
+ */
+TQ_EXPORT bool qt_tryModalHelper( TQWidget *widget, TQWidget **rettop ) {
+ TQWidget *modal=0, *top=TQApplication::activeModalWidget();
+ if ( rettop ) *rettop = top;
+
+ if ( tqApp->activePopupWidget() )
+ return TRUE;
+
+#ifdef TQ_WS_MACX
+ top = qt_tryModalHelperMac( top );
+ if ( rettop ) *rettop = top;
+#endif
+
+ TQWidget* groupLeader = widget;
+ widget = widget->tqtopLevelWidget();
+
+ if ( widget->testWFlags(TQt::WShowModal) ) // widget is modal
+ modal = widget;
+ if ( !top || modal == top ) // don't block event
+ return TRUE;
+
+ TQWidget * p = widget->parentWidget(); // Check if the active modal widget is a tqparent of our widget
+ while ( p ) {
+ if ( p == top )
+ return TRUE;
+ p = p->parentWidget();
+ }
+
+ while ( groupLeader && !groupLeader->testWFlags( TQt::WGroupLeader ) )
+ groupLeader = groupLeader->parentWidget();
+
+ if ( groupLeader ) {
+ // Does groupLeader have a child in qt_modal_stack?
+ bool unrelated = TRUE;
+ modal = qt_modal_stack->first();
+ while (modal && unrelated) {
+ TQWidget* p = modal->parentWidget();
+ while ( p && p != groupLeader && !p->testWFlags( TQt::WGroupLeader) ) {
+ p = p->parentWidget();
+ }
+ modal = qt_modal_stack->next();
+ if ( p == groupLeader ) unrelated = FALSE;
+ }
+
+ if ( unrelated )
+ return TRUE; // don't block event
+ }
+ return FALSE;
+}
+
+
+/*!
+ Returns the desktop widget (also called the root window).
+
+ The desktop widget is useful for obtaining the size of the screen.
+ It may also be possible to draw on the desktop. We recommend against
+ assuming that it's possible to draw on the desktop, since this does
+ not work on all operating systems.
+
+ \code
+ TQDesktopWidget *d = TQApplication::desktop();
+ int w = d->width(); // returns desktop width
+ int h = d->height(); // returns desktop height
+ \endcode
+*/
+
+TQDesktopWidget *TQApplication::desktop()
+{
+ if ( !qt_desktopWidget || // not created yet
+ !qt_desktopWidget->isDesktop() ) { // reparented away
+ qt_desktopWidget = new TQDesktopWidget();
+ TQ_CHECK_PTR( qt_desktopWidget );
+ }
+ return qt_desktopWidget;
+}
+
+#ifndef TQT_NO_CLIPBOARD
+/*!
+ Returns a pointer to the application global clipboard.
+*/
+TQClipboard *TQApplication::clipboard()
+{
+ if ( qt_clipboard == 0 ) {
+ qt_clipboard = new TQClipboard;
+ TQ_CHECK_PTR( qt_clipboard );
+ }
+ return qt_clipboard;
+}
+#endif // TQT_NO_CLIPBOARD
+
+/*!
+ By default, TQt will try to use the current standard colors, fonts
+ etc., from the underlying window system's desktop settings,
+ and use them for all relevant widgets. This behavior can be switched off
+ by calling this function with \a on set to FALSE.
+
+ This static function must be called before creating the TQApplication
+ object, like this:
+
+ \code
+ int main( int argc, char** argv ) {
+ TQApplication::setDesktopSettingsAware( FALSE ); // I know better than the user
+ TQApplication myApp( argc, argv ); // Use default fonts & colors
+ ...
+ }
+ \endcode
+
+ \sa desktopSettingsAware()
+*/
+
+void TQApplication::setDesktopSettingsAware( bool on )
+{
+ obey_desktop_settings = on;
+}
+
+/*!
+ Returns the value set by setDesktopSettingsAware(); by default TRUE.
+
+ \sa setDesktopSettingsAware()
+*/
+
+bool TQApplication::desktopSettingsAware()
+{
+ return obey_desktop_settings;
+}
+
+/*! \fn void TQApplication::lock()
+
+ Lock the TQt Library Mutex. If another thread has already locked the
+ mutex, the calling thread will block until the other thread has
+ unlocked the mutex.
+
+ \sa unlock() locked() \link threads.html Thread Support in TQt\endlink
+*/
+
+
+/*! \fn void TQApplication::unlock(bool wakeUpGui)
+
+ Unlock the TQt Library Mutex. If \a wakeUpGui is TRUE (the default),
+ then the GUI thread will be woken with TQApplication::wakeUpGuiThread().
+
+ \sa lock(), locked() \link threads.html Thread Support in TQt\endlink
+*/
+
+
+/*! \fn bool TQApplication::locked()
+
+ Returns TRUE if the TQt Library Mutex is locked by a different thread;
+ otherwise returns FALSE.
+
+ \warning Due to different implementations of recursive mutexes on
+ the supported platforms, calling this function from the same thread
+ that previously locked the mutex will give undefined results.
+
+ \sa lock() unlock() \link threads.html Thread Support in TQt\endlink
+*/
+
+/*! \fn bool TQApplication::tryLock()
+
+ Attempts to lock the TQt Library Mutex, and returns immediately. If
+ the lock was obtained, this function returns TRUE. If another thread
+ has locked the mutex, this function returns FALSE, instead of
+ waiting for the lock to become available.
+
+ The mutex must be unlocked with unlock() before another thread can
+ successfully lock it.
+
+ \sa lock(), unlock() \link threads.html Thread Support in TQt\endlink
+*/
+
+#if defined(TQT_THREAD_SUPPORT)
+void TQApplication::lock()
+{
+ qt_mutex->lock();
+}
+
+void TQApplication::unlock(bool wakeUpGui)
+{
+ qt_mutex->unlock();
+
+ if (wakeUpGui)
+ wakeUpGuiThread();
+}
+
+bool TQApplication::locked()
+{
+ return qt_mutex->locked();
+}
+
+bool TQApplication::tryLock()
+{
+ return qt_mutex->tryLock();
+}
+#endif
+
+
+/*!
+ \fn bool TQApplication::isSessionRestored() const
+
+ Returns TRUE if the application has been restored from an earlier
+ \link session.html session\endlink; otherwise returns FALSE.
+
+ \sa sessionId(), commitData(), saveState()
+*/
+
+
+/*!
+ \fn TQString TQApplication::sessionId() const
+
+ Returns the current \link session.html session's\endlink identifier.
+
+ If the application has been restored from an earlier session, this
+ identifier is the same as it was in that previous session.
+
+ The session identifier is guaranteed to be unique both for different
+ applications and for different instances of the same application.
+
+ \sa isSessionRestored(), sessionKey(), commitData(), saveState()
+ */
+
+/*!
+ \fn TQString TQApplication::sessionKey() const
+
+ Returns the session key in the current \link session.html
+ session\endlink.
+
+ If the application has been restored from an earlier session, this
+ key is the same as it was when the previous session ended.
+
+ The session key changes with every call of commitData() or
+ saveState().
+
+ \sa isSessionRestored(), sessionId(), commitData(), saveState()
+ */
+
+
+/*!
+ \fn void TQApplication::commitData( TQSessionManager& sm )
+
+ This function deals with \link session.html session
+ management\endlink. It is invoked when the TQSessionManager wants the
+ application to commit all its data.
+
+ Usually this means saving all open files, after getting
+ permission from the user. Furthermore you may want to provide a means
+ by which the user can cancel the shutdown.
+
+ Note that you should not exit the application within this function.
+ Instead, the session manager may or may not do this afterwards,
+ depending on the context.
+
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the session manager \a sm for explicit permission.
+ See TQSessionManager::allowsInteraction() and
+ TQSessionManager::allowsErrorInteraction() for details and example
+ usage.
+
+ The default implementation requests interaction and sends a close
+ event to all visible top level widgets. If any event was
+ rejected, the shutdown is canceled.
+
+ \sa isSessionRestored(), sessionId(), saveState(), \link session.html the Session Management overview\endlink
+*/
+#ifndef TQT_NO_SESSIONMANAGER
+void TQApplication::commitData( TQSessionManager& sm )
+{
+
+ if ( sm.allowsInteraction() ) {
+ TQWidgetList done;
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ bool cancelled = FALSE;
+ TQWidget* w = list->first();
+ while ( !cancelled && w ) {
+ if ( !w->isHidden() ) {
+ TQCloseEvent e;
+ sendEvent( w, &e );
+ cancelled = !e.isAccepted();
+ if ( !cancelled )
+ done.append( w );
+ delete list; // one never knows...
+ list = TQApplication::tqtopLevelWidgets();
+ w = list->first();
+ } else {
+ w = list->next();
+ }
+ while ( w && done.tqcontainsRef( w ) )
+ w = list->next();
+ }
+ delete list;
+ if ( cancelled )
+ sm.cancel();
+ }
+}
+
+
+/*!
+ \fn void TQApplication::saveState( TQSessionManager& sm )
+
+ This function deals with \link session.html session
+ management\endlink. It is invoked when the
+ \link TQSessionManager session manager \endlink wants the application
+ to preserve its state for a future session.
+
+ For example, a text editor would create a temporary file that
+ includes the current contents of its edit buffers, the location of
+ the cursor and other aspects of the current editing session.
+
+ Note that you should never exit the application within this
+ function. Instead, the session manager may or may not do this
+ afterwards, depending on the context. Futhermore, most session
+ managers will very likely request a saved state immediately after
+ the application has been started. This permits the session manager
+ to learn about the application's restart policy.
+
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the session manager \a sm for explicit permission.
+ See TQSessionManager::allowsInteraction() and
+ TQSessionManager::allowsErrorInteraction() for details.
+
+ \sa isSessionRestored(), sessionId(), commitData(), \link session.html the Session Management overview\endlink
+*/
+
+void TQApplication::saveState( TQSessionManager& /* sm */ )
+{
+}
+#endif //TQT_NO_SESSIONMANAGER
+/*!
+ Sets the time after which a drag should start to \a ms ms.
+
+ \sa startDragTime()
+*/
+
+void TQApplication::setStartDragTime( int ms )
+{
+ drag_time = ms;
+}
+
+/*!
+ If you support drag and drop in you application and a drag should
+ start after a mouse click and after a certain time elapsed, you
+ should use the value which this method returns as the delay (in ms).
+
+ TQt also uses this delay internally, e.g. in TQTextEdit and TQLineEdit,
+ for starting a drag.
+
+ The default value is 500 ms.
+
+ \sa setStartDragTime(), startDragDistance()
+*/
+
+int TQApplication::startDragTime()
+{
+ return drag_time;
+}
+
+/*!
+ Sets the distance after which a drag should start to \a l pixels.
+
+ \sa startDragDistance()
+*/
+
+void TQApplication::setStartDragDistance( int l )
+{
+ drag_distance = l;
+}
+
+/*!
+ If you support drag and drop in you application and a drag should
+ start after a mouse click and after moving the mouse a certain
+ distance, you should use the value which this method returns as the
+ distance.
+
+ For example, if the mouse position of the click is stored in \c
+ startPos and the current position (e.g. in the mouse move event) is
+ \c currPos, you can tqfind out if a drag should be started with code
+ like this:
+ \code
+ if ( ( startPos - currPos ).manhattanLength() >
+ TQApplication::startDragDistance() )
+ startTheDrag();
+ \endcode
+
+ TQt uses this value internally, e.g. in TQFileDialog.
+
+ The default value is 4 pixels.
+
+ \sa setStartDragDistance(), startDragTime(), TQPoint::manhattanLength()
+*/
+
+int TQApplication::startDragDistance()
+{
+ return drag_distance;
+}
+
+/*!
+ If \a b is TRUE, all dialogs and widgets will be laid out in a
+ mirrored fashion, as required by right to left languages such as
+ Arabic and Hebrew. If \a b is FALSE, dialogs and widgets are laid
+ out left to right.
+
+ Changing this flag in runtime does not cause a retqlayout of already
+ instantiated widgets.
+
+ \sa reverseLayout()
+*/
+void TQApplication::setReverseLayout( bool b )
+{
+ if ( reverse_tqlayout == b )
+ return;
+
+ reverse_tqlayout = b;
+
+ TQWidgetList *list = tqtopLevelWidgets();
+ TQWidgetListIt it( *list );
+ TQWidget *w;
+ while ( ( w=it.current() ) != 0 ) {
+ ++it;
+ postEvent( w, new TQEvent( TQEvent::LayoutDirectionChange ) );
+ }
+ delete list;
+}
+
+/*!
+ Returns TRUE if all dialogs and widgets will be laid out in a
+ mirrored (right to left) fashion. Returns FALSE if dialogs and
+ widgets will be laid out left to right.
+
+ \sa setReverseLayout()
+*/
+bool TQApplication::reverseLayout()
+{
+ return reverse_tqlayout;
+}
+
+
+/*!
+ \class TQSessionManager tqsessionmanager.h
+ \brief The TQSessionManager class provides access to the session manager.
+
+ \ingroup application
+ \ingroup environment
+
+ The session manager is responsible for session management, most
+ importantly for interruption and resumption. A "session" is a kind
+ of record of the state of the system, e.g. which applications were
+ run at start up and which applications are currently running. The
+ session manager is used to save the session, e.g. when the machine
+ is shut down; and to restore a session, e.g. when the machine is
+ started up. Use TQSettings to save and restore an individual
+ application's settings, e.g. window positions, recently used files,
+ etc.
+
+ TQSessionManager provides an interface between the application and
+ the session manager so that the program can work well with the
+ session manager. In TQt, session management requests for action
+ are handled by the two virtual functions TQApplication::commitData()
+ and TQApplication::saveState(). Both provide a reference to
+ a session manager object as argument, to allow the application
+ to communicate with the session manager.
+
+ During a session management action (i.e. within commitData() and
+ saveState()), no user interaction is possible \e unless the
+ application got explicit permission from the session manager. You
+ ask for permission by calling allowsInteraction() or, if it's really
+ urgent, allowsErrorInteraction(). TQt does not enforce this, but the
+ session manager may.
+
+ You can try to abort the shutdown process by calling cancel(). The
+ default commitData() function does this if some top-level window
+ rejected its closeEvent().
+
+ For sophisticated session managers provided on Unix/X11, TQSessionManager
+ offers further possibilites to fine-tune an application's session
+ management behavior: setRestartCommand(), setDiscardCommand(),
+ setRestartHint(), setProperty(), requestPhase2(). See the respective
+ function descriptions for further details.
+*/
+
+/*! \enum TQSessionManager::RestartHint
+
+ This enum type defines the circumstances under which this
+ application wants to be restarted by the session manager. The
+ current values are
+
+ \value RestartIfRunning if the application is still running when
+ the session is shut down, it wants to be restarted at the start of
+ the next session.
+
+ \value RestartAnyway the application wants to be started at the
+ start of the next session, no matter what. (This is useful for
+ utilities that run just after startup and then quit.)
+
+ \value RestartImmediately the application wants to be started
+ immediately whenever it is not running.
+
+ \value RestartNever the application does not want to be restarted
+ automatically.
+
+ The default hint is \c RestartIfRunning.
+*/
+
+
+/*!
+ \fn TQString TQSessionManager::sessionId() const
+
+ Returns the identifier of the current session.
+
+ If the application has been restored from an earlier session, this
+ identifier is the same as it was in that earlier session.
+
+ \sa sessionKey(), TQApplication::sessionId()
+ */
+
+/*!
+ \fn TQString TQSessionManager::sessionKey() const
+
+ Returns the session key in the current session.
+
+ If the application has been restored from an earlier session, this
+ key is the same as it was when the previous session ended.
+
+ The session key changes with every call of commitData() or
+ saveState().
+
+ \sa sessionId(), TQApplication::sessionKey()
+ */
+
+// ### Note: This function is undocumented, since it is #ifdef'd.
+
+/*!
+ \fn void* TQSessionManager::handle() const
+
+ X11 only: returns a handle to the current \c SmcConnection.
+*/
+
+
+/*!
+ \fn bool TQSessionManager::allowsInteraction()
+
+ Asks the session manager for permission to interact with the
+ user. Returns TRUE if interaction is permitted; otherwise
+ returns FALSE.
+
+ The rationale behind this mechanism is to make it possible to
+ synchronize user interaction during a shutdown. Advanced session
+ managers may ask all applications simultaneously to commit their
+ data, resulting in a much faster shutdown.
+
+ When the interaction is completed we strongly recommend releasing the
+ user interaction semaphore with a call to release(). This way, other
+ applications may get the chance to interact with the user while your
+ application is still busy saving data. (The semaphore is implicitly
+ released when the application exits.)
+
+ If the user decides to cancel the shutdown process during the
+ interaction phase, you must tell the session manager that this has
+ happened by calling cancel().
+
+ Here's an example of how an application's TQApplication::commitData()
+ might be implemented:
+
+\code
+void MyApplication::commitData( TQSessionManager& sm ) {
+ if ( sm.allowsInteraction() ) {
+ switch ( TQMessageBox::warning(
+ yourMainWindow,
+ tr("Application Name"),
+ tr("Save changes to document Foo?"),
+ tr("&Yes"),
+ tr("&No"),
+ tr("Cancel"),
+ 0, 2) ) {
+ case 0: // yes
+ sm.release();
+ // save document here; if saving fails, call sm.cancel()
+ break;
+ case 1: // continue without saving
+ break;
+ default: // cancel
+ sm.cancel();
+ break;
+ }
+ } else {
+ // we did not get permission to interact, then
+ // do something reasonable instead.
+ }
+}
+\endcode
+
+ If an error occurred within the application while saving its data,
+ you may want to try allowsErrorInteraction() instead.
+
+ \sa TQApplication::commitData(), release(), cancel()
+*/
+
+
+/*!
+ \fn bool TQSessionManager::allowsErrorInteraction()
+
+ This is similar to allowsInteraction(), but also tells the session
+ manager that an error occurred. Session managers may give error
+ interaction request higher priority, which means that it is more likely
+ that an error interaction is permitted. However, you are still not
+ guaranteed that the session manager will allow interaction.
+
+ \sa allowsInteraction(), release(), cancel()
+*/
+
+/*!
+ \fn void TQSessionManager::release()
+
+ Releases the session manager's interaction semaphore after an
+ interaction phase.
+
+ \sa allowsInteraction(), allowsErrorInteraction()
+*/
+
+/*!
+ \fn void TQSessionManager::cancel()
+
+ Tells the session manager to cancel the shutdown process. Applications
+ should not call this function without first asking the user.
+
+ \sa allowsInteraction(), allowsErrorInteraction()
+
+*/
+
+/*!
+ \fn void TQSessionManager::setRestartHint( RestartHint hint )
+
+ Sets the application's restart hint to \a hint. On application
+ startup the hint is set to \c RestartIfRunning.
+
+ Note that these flags are only hints, a session manager may or may
+ not respect them.
+
+ We recommend setting the restart hint in TQApplication::saveState()
+ because most session managers perform a checkpoint shortly after an
+ application's startup.
+
+ \sa restartHint()
+*/
+
+/*!
+ \fn TQSessionManager::RestartHint TQSessionManager::restartHint() const
+
+ Returns the application's current restart hint. The default is
+ \c RestartIfRunning.
+
+ \sa setRestartHint()
+*/
+
+/*!
+ \fn void TQSessionManager::setRestartCommand( const TQStringList& command )
+
+ If the session manager is capable of restoring sessions it will
+ execute \a command in order to restore the application. The command
+ defaults to
+
+ \code
+ appname -session id
+ \endcode
+
+ The \c -session option is mandatory; otherwise TQApplication cannot
+ tell whether it has been restored or what the current session
+ identifier is. See TQApplication::isSessionRestored() and
+ TQApplication::sessionId() for details.
+
+ If your application is very simple, it may be possible to store the
+ entire application state in additional command line options. This
+ is usually a very bad idea because command lines are often limited
+ to a few hundred bytes. Instead, use TQSettings, or temporary files
+ or a database for this purpose. By marking the data with the unique
+ sessionId(), you will be able to restore the application in a future
+ session.
+
+ \sa restartCommand(), setDiscardCommand(), setRestartHint()
+*/
+
+/*!
+ \fn TQStringList TQSessionManager::restartCommand() const
+
+ Returns the currently set restart command.
+
+ Note that if you want to iterate over the list, you should
+ iterate over a copy, e.g.
+ \code
+ TQStringList list = mySession.restartCommand();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa setRestartCommand(), restartHint()
+*/
+
+/*!
+ \fn void TQSessionManager::setDiscardCommand( const TQStringList& )
+
+ \sa discardCommand(), setRestartCommand()
+*/
+
+
+/*!
+ \fn TQStringList TQSessionManager::discardCommand() const
+
+ Returns the currently set discard command.
+
+ Note that if you want to iterate over the list, you should
+ iterate over a copy, e.g.
+ \code
+ TQStringList list = mySession.discardCommand();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa setDiscardCommand(), restartCommand(), setRestartCommand()
+*/
+
+/*!
+ \overload void TQSessionManager::setManagerProperty( const TQString& name,
+ const TQString& value )
+
+ Low-level write access to the application's identification and state
+ records are kept in the session manager.
+
+ The property called \a name has its value set to the string \a value.
+*/
+
+/*!
+ \fn void TQSessionManager::setManagerProperty( const TQString& name,
+ const TQStringList& value )
+
+ Low-level write access to the application's identification and state
+ record are kept in the session manager.
+
+ The property called \a name has its value set to the string list \a value.
+*/
+
+/*!
+ \fn bool TQSessionManager::isPhase2() const
+
+ Returns TRUE if the session manager is currently performing a second
+ session management phase; otherwise returns FALSE.
+
+ \sa requestPhase2()
+*/
+
+/*!
+ \fn void TQSessionManager::requestPhase2()
+
+ Requests a second session management phase for the application. The
+ application may then return immediately from the
+ TQApplication::commitData() or TQApplication::saveState() function,
+ and they will be called again once most or all other applications have
+ finished their session management.
+
+ The two phases are useful for applications such as the X11 window manager
+ that need to store information about another application's windows
+ and therefore have to wait until these applications have completed their
+ respective session management tasks.
+
+ Note that if another application has requested a second phase it
+ may get called before, simultaneously with, or after your
+ application's second phase.
+
+ \sa isPhase2()
+*/
+
+/*!
+ \fn int TQApplication::horizontalAlignment( int align )
+
+ Strips out vertical tqalignment flags and transforms an
+ tqalignment \a align of AlignAuto into AlignLeft or
+ AlignRight according to the language used. The other horizontal
+ tqalignment flags are left untouched.
+*/
+
+
+/*****************************************************************************
+ Stubbed session management support
+ *****************************************************************************/
+#ifndef TQT_NO_SESSIONMANAGER
+#if defined( TQT_NO_SM_SUPPORT ) || defined( TQ_WS_WIN ) || defined( TQ_WS_MAC ) || defined( TQ_WS_TQWS )
+
+class TQSessionManagerData
+{
+public:
+ TQStringList restartCommand;
+ TQStringList discardCommand;
+ TQString sessionId;
+ TQString sessionKey;
+ TQSessionManager::RestartHint restartHint;
+};
+
+TQSessionManager* qt_session_manager_self = 0;
+TQSessionManager::TQSessionManager( TQApplication * app, TQString &id, TQString &key )
+ : TQObject( app, "qt_sessionmanager" )
+{
+ qt_session_manager_self = this;
+ d = new TQSessionManagerData;
+#if defined(TQ_WS_WIN) && !defined(TQ_OS_TEMP)
+ wchar_t guidstr[40];
+ GUID guid;
+ CoCreateGuid( &guid );
+ StringFromGUID2(guid, guidstr, 40);
+ id = TQString::fromUcs2((ushort*)guidstr);
+ CoCreateGuid( &guid );
+ StringFromGUID2(guid, guidstr, 40);
+ key = TQString::fromUcs2((ushort*)guidstr);
+#endif
+ d->sessionId = id;
+ d->sessionKey = key;
+ d->restartHint = RestartIfRunning;
+}
+
+TQSessionManager::~TQSessionManager()
+{
+ delete d;
+ qt_session_manager_self = 0;
+}
+
+TQString TQSessionManager::sessionId() const
+{
+ return d->sessionId;
+}
+
+TQString TQSessionManager::sessionKey() const
+{
+ return d->sessionKey;
+}
+
+
+#if defined(TQ_WS_X11) || defined(TQ_WS_MAC)
+void* TQSessionManager::handle() const
+{
+ return 0;
+}
+#endif
+
+#if !defined(TQ_WS_WIN)
+bool TQSessionManager::allowsInteraction()
+{
+ return TRUE;
+}
+
+bool TQSessionManager::allowsErrorInteraction()
+{
+ return TRUE;
+}
+void TQSessionManager::release()
+{
+}
+
+void TQSessionManager::cancel()
+{
+}
+#endif
+
+
+void TQSessionManager::setRestartHint( TQSessionManager::RestartHint hint)
+{
+ d->restartHint = hint;
+}
+
+TQSessionManager::RestartHint TQSessionManager::restartHint() const
+{
+ return d->restartHint;
+}
+
+void TQSessionManager::setRestartCommand( const TQStringList& command)
+{
+ d->restartCommand = command;
+}
+
+TQStringList TQSessionManager::restartCommand() const
+{
+ return d->restartCommand;
+}
+
+void TQSessionManager::setDiscardCommand( const TQStringList& command)
+{
+ d->discardCommand = command;
+}
+
+TQStringList TQSessionManager::discardCommand() const
+{
+ return d->discardCommand;
+}
+
+void TQSessionManager::setManagerProperty( const TQString&, const TQString&)
+{
+}
+
+void TQSessionManager::setManagerProperty( const TQString&, const TQStringList& )
+{
+}
+
+bool TQSessionManager::isPhase2() const
+{
+ return FALSE;
+}
+
+void TQSessionManager::requestPhase2()
+{
+}
+
+#endif // TQT_NO_SM_SUPPORT
+#endif //TQT_NO_SESSIONMANAGER
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqapplication.cpp~ b/tqtinterface/qt4/src/kernel/tqapplication.cpp~
new file mode 100644
index 0000000..ff60776
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqapplication.cpp~
@@ -0,0 +1,5499 @@
+/****************************************************************************
+**
+** Implementation of TQApplication class
+**
+** Created : 931107
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqobjectlist.h"
+#include "tqapplication.h"
+#include "tqeventloop.h"
+#include "tqeventloop_p.h"
+#include "tqwidget.h"
+#include "tqwidgetlist.h"
+#include "tqwidgetintdict.h"
+#include "tqptrdict.h"
+#include "tqcleanuphandler.h"
+
+#include "tqtranslator.h"
+#include "tqtextcodec.h"
+#include "tqsessionmanager.h"
+#include "tqdragobject.h"
+#include "tqclipboard.h"
+#include "tqcursor.h"
+#include "tqstyle.h"
+#include "tqstylefactory.h"
+#include "tqfile.h"
+#include "tqmessagebox.h"
+#include "tqdir.h"
+#include "tqfileinfo.h"
+#ifdef TQ_WS_WIN
+#include "tqinputcontext_p.h"
+#endif
+#include "tqfontdata_p.h"
+
+#if defined(TQT_THREAD_SUPPORT)
+# include "tqmutex.h"
+# include "tqthread.h"
+#endif // TQT_THREAD_SUPPORT
+
+#include <stdlib.h>
+
+#ifdef truncate
+# undef truncate
+#endif
+
+#ifdef USE_QT4
+
+TQApplication *tqAppReal; // global application object
+TQStyle *TQApplication::app_style = 0; // default application style
+bool qt_explicit_app_style = FALSE; // style explicitly set by programmer
+QWidget* TQApplication::current_app_main_widget = 0; // current main widget
+
+int TQApplication::app_cspec = TQApplication::NormalColor; // color mode (obsolete)
+
+TQWidgetList * qt_modal_stack=0; // stack of modal widgets
+
+#ifndef TQT_NO_PALETTE
+TQPalette *TQApplication::app_pal = 0; // default application palette
+#endif
+// TQFont *TQApplication::app_font = 0; // default application font
+bool qt_app_has_font = FALSE;
+
+bool qt_is_gui_used;
+bool TQ_EXPORT qt_resolve_symlinks = TRUE;
+bool TQ_EXPORT qt_tab_all_widgets = TRUE;
+
+#if defined(TQ_WS_X11)
+extern void qt_init( Display* dpy, TQt::HANDLE, TQt::HANDLE );
+#endif
+extern void qt_init( int *argcptr, char **argv, TQApplication::Type );
+
+#ifndef TQT_NO_CLIPBOARD
+TQClipboard *tqt_clipboard = 0; // global clipboard object
+#endif
+
+#ifdef TQT_THREAD_SUPPORT
+TQMutex *TQApplication::qt_mutex = 0;
+static TQMutex *postevent_mutex = 0;
+static TQt::HANDLE qt_application_thread_id = 0;
+TQ_EXPORT TQt::HANDLE qt_get_application_thread_id()
+{
+ return qt_application_thread_id;
+}
+#endif // TQT_THREAD_SUPPORT
+
+
+#ifdef TQT_THREAD_SUPPORT
+ #define TQAPPLICATION_MUTEX_INIT \
+ qt_mutex = new TQMutex( TRUE ); \
+ postevent_mutex = new TQMutex( TRUE ); \
+ qt_application_thread_id = TQThread::currentThread();
+#else // TQT_THREAD_SUPPORT
+ #define TQAPPLICATION_MUTEX_INIT
+#endif // TQT_THREAD_SUPPORT
+
+TQWidgetList TQApplication::tqt_all_widgets_list;
+
+TQApplication::TQApplication( int &argc, char **argv ) : QApplication( argc, argv )
+{
+ bool GUIenabled = true;
+ TQAPPLICATION_GUI_CONDITIONAL_VAR_INIT
+ TQAPPLICATION_XORG_CONDITIONAL_INIT
+ TQAPPLICATION_MUTEX_INIT
+ TQAPPLICATION_REGISTER_TQ_DATATYPES
+}
+TQApplication::TQApplication( int &argc, char **argv, bool GUIenabled ) : QApplication( argc, argv, GUIenabled )
+{
+ TQAPPLICATION_GUI_CONDITIONAL_VAR_INIT
+ TQAPPLICATION_XORG_CONDITIONAL_INIT
+ TQAPPLICATION_MUTEX_INIT
+ TQAPPLICATION_REGISTER_TQ_DATATYPES
+}
+TQApplication::TQApplication( int &argc, char **argv, Type t ) : QApplication( argc, argv, t )
+{
+ TQAPPLICATION_GUI_VAR_INIT
+ TQAPPLICATION_XORG_PARTIAL_INIT
+ TQAPPLICATION_MUTEX_INIT
+ TQAPPLICATION_REGISTER_TQ_DATATYPES
+}
+#if defined(TQ_WS_X11)
+TQApplication::TQApplication( Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap ) : QApplication( dpy, visual, cmap )
+{
+ TQAPPLICATION_GUI_VAR_INIT
+ TQAPPLICATION_XORG_FULL_INIT
+ TQAPPLICATION_MUTEX_INIT
+ TQAPPLICATION_REGISTER_TQ_DATATYPES
+}
+TQApplication::TQApplication( Display *dpy, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap ) : QApplication( dpy, argc, argv, visual, cmap )
+{
+ TQAPPLICATION_GUI_VAR_INIT
+ TQAPPLICATION_XORG_FULL_INIT
+ TQAPPLICATION_MUTEX_INIT
+ TQAPPLICATION_REGISTER_TQ_DATATYPES
+}
+#endif
+
+// Qt4 session manager interconnect
+void TQApplication::commitData( QSessionManager& sm ) {
+ commitData(TQT_TQSESSIONMANAGER_OBJECT(sm));
+}
+void TQApplication::saveState( QSessionManager& sm ) {
+ saveState(TQT_TQSESSIONMANAGER_OBJECT(sm));
+}
+
+#ifndef TQT_NO_TRANSLATION
+
+bool qt_detectRTLLanguage()
+{
+ return TQApplication::tr( "TQT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right"
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew"
+ " and Arabic) to get proper widget tqlayout." ) == "RTL";
+}
+
+#endif // TQT_NO_TRANSLATION
+
+TQEventLoop* TQApplication::eventloop;
+TQPtrList<QEventLoop> TQApplication::tqt_event_loop_stack;
+int TQApplication::composedUnicode;
+bool TQApplication::metaComposeUnicode;
+
+// static TQEventLoop eventLoop_private; // Will this actually work, or do I need to call exec or something?
+//
+// TQEventLoop *TQApplication::eventLoop()
+// {
+// return &eventLoop_private;
+// }
+
+TQEventLoop *TQApplication::eventLoop() {
+ if ( !eventloop )
+ (void) new TQEventLoop( TQT_TQOBJECT(tqApp), "default event loop" );
+ return eventloop;
+}
+
+/*!
+
+ Wakes up the GUI thread.
+
+ \sa guiThreadAwake() \link threads.html Thread Support in TQt\endlink
+*/
+void TQApplication::wakeUpGuiThread()
+{
+ eventLoop()->wakeUp();
+}
+
+#ifdef TQT_THREAD_SUPPORT
+void TQApplication::lock() {
+ qt_mutex->lock();
+}
+
+void TQApplication::unlock(bool wakeUpGui) {
+ qt_mutex->unlock();
+
+ if (wakeUpGui)
+ wakeUpGuiThread();
+}
+
+bool TQApplication::locked() {
+ return qt_mutex->locked();
+}
+
+bool TQApplication::tryLock() {
+ return qt_mutex->tryLock();
+}
+#endif // TQT_THREAD_SUPPORT
+
+#ifndef TQT_NO_PALETTE
+TQPalette *qt_std_pal = 0;
+
+void qt_create_std_palette()
+{
+ if ( qt_std_pal )
+ delete qt_std_pal;
+
+ TQColor standardLightGray( 192, 192, 192 );
+ TQColor light( 255, 255, 255 );
+ TQColor dark( standardLightGray.dark( 150 ) );
+ TQColorGroup std_act( TQt::black, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::black, TQt::white );
+ TQColorGroup std_dis( TQt::darkGray, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::darkGray, std_act.background() );
+ TQColorGroup std_inact( TQt::black, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::black, TQt::white );
+ qt_std_pal = new TQPalette( std_act, std_dis, std_inact );
+}
+
+static void qt_fix_tooltips()
+{
+ // No resources for this yet (unlike on Windows).
+ TQColorGroup cg( TQt::black, TQColor(255,255,220),
+ TQColor(96,96,96), TQt::black, TQt::black,
+ TQt::black, TQColor(255,255,220) );
+ TQPalette pal( cg, cg, cg );
+ TQApplication::tqsetPalette( pal, TRUE, "TQTipLabel");
+}
+#endif
+
+// [FIXME] This needs to somehow connect to the Qt4 style mechanism
+// Possibly on calls to setStyle the Qt4 setStyle must also be called for the same style?
+
+static TQString *qt_style_override = 0;
+
+TQStyle& TQApplication::tqstyle()
+{
+#ifndef TQT_NO_STYLE
+ if ( app_style )
+ return *app_style;
+ if ( !qt_is_gui_used )
+ qFatal( "No style available in non-gui applications!" );
+
+#if defined(TQ_WS_X11)
+// if(!qt_style_override)
+// x11_initialize_style(); // run-time search for default style
+#endif
+ if ( !app_style ) {
+// // Compile-time search for default style
+// //
+ TQString style;
+ if ( qt_style_override ) {
+ style = *qt_style_override;
+ delete qt_style_override;
+ qt_style_override = 0;
+ } else {
+// # if defined(TQ_WS_WIN) && defined(TQ_OS_TEMP)
+// style = "PocketPC";
+// #elif defined(TQ_WS_WIN)
+// if ( qWinVersion() >= TQt::WV_XP && qWinVersion() < TQt::WV_NT_based )
+// style = "WindowsXP";
+// else
+// style = "Windows"; // default styles for Windows
+// #elif defined(TQ_WS_X11) && defined(TQ_OS_SOLARIS)
+// style = "CDE"; // default style for X11 on Solaris
+// #elif defined(TQ_WS_X11) && defined(TQ_OS_IRIX)
+// style = "SGI"; // default style for X11 on IRIX
+// #elif defined(TQ_WS_X11)
+ style = "Motif"; // default style for X11
+// #elif defined(TQ_WS_MAC)
+// style = "Macintosh"; // default style for all Mac's
+// #elif defined(TQ_WS_TQWS)
+// style = "Compact"; // default style for small tqdevices
+// #endif
+ }
+ app_style = TQStyleFactory::create( style );
+ if ( !app_style && // platform default style not available, try alternatives
+ !(app_style = TQStyleFactory::create( "Windows" ) ) &&
+ !(app_style = TQStyleFactory::create( "Platinum" ) ) &&
+ !(app_style = TQStyleFactory::create( "MotifPlus" ) ) &&
+ !(app_style = TQStyleFactory::create( "Motif" ) ) &&
+ !(app_style = TQStyleFactory::create( "CDE" ) ) &&
+ !(app_style = TQStyleFactory::create( "Aqua" ) ) &&
+ !(app_style = TQStyleFactory::create( "SGI" ) ) &&
+ !(app_style = TQStyleFactory::create( "Compact" ) )
+#ifndef TQT_NO_STRINGLIST
+ && !(app_style = TQStyleFactory::create( TQStyleFactory::keys()[0] ) )
+#endif
+ )
+ qFatal( "No %s style available!", style.latin1() );
+ }
+
+// TQPalette app_pal_copy ( *app_pal );
+// app_style->polish( *app_pal );
+
+// if ( is_app_running && !is_app_closing && (*app_pal != app_pal_copy) ) {
+// TQEvent e( TQEvent::ApplicationPaletteChange );
+// TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+// register TQWidget *w;
+// while ( (w=it.current()) ) { // for all widgets...
+// ++it;
+// sendEvent( w, &e );
+// }
+// }
+
+ app_style->polish( tqApp );
+#endif
+ return *app_style;
+}
+
+/*!
+ Enters the main event loop and waits until exit() is called or the
+ main widget is destroyed, and returns the value that was set to
+ exit() (which is 0 if exit() is called via quit()).
+
+ It is necessary to call this function to start event handling. The
+ main event loop receives events from the window system and
+ dispatches these to the application widgets.
+
+ Generally speaking, no user interaction can take place before
+ calling exec(). As a special case, modal widgets like TQMessageBox
+ can be used before calling exec(), because modal widgets call
+ exec() to start a local event loop.
+
+ To make your application perform idle processing, i.e. executing a
+ special function whenever there are no pending events, use a
+ TQTimer with 0 timeout. More advanced idle processing schemes can
+ be achieved using processEvents().
+
+ \sa quit(), exit(), processEvents(), setMainWidget()
+*/
+int TQApplication::exec()
+{
+ return eventLoop()->exec();
+}
+
+/*!
+ Sets the application's GUI style to \a style. Ownership of the style
+ object is transferred to TQApplication, so TQApplication will delete
+ the style object on application exit or when a new style is set.
+
+ Example usage:
+ \code
+ TQApplication::setStyle( new TQWindowsStyle );
+ \endcode
+
+ When switching application styles, the color palette is set back to
+ the initial colors or the system defaults. This is necessary since
+ certain styles have to adapt the color palette to be fully
+ style-guide compliant.
+
+ \sa style(), TQStyle, setPalette(), desktopSettingsAware()
+*/
+void TQApplication::setStyle( TQStyle *style )
+{
+ TQStyle* old = app_style;
+ app_style = style;
+#ifdef TQ_WS_X11
+ qt_explicit_app_style = TRUE;
+#endif // TQ_WS_X11
+
+ if ( startingUp() ) {
+ delete old;
+ return;
+ }
+
+ // clean up the old style
+ if (old) {
+// if ( is_app_running && !is_app_closing ) {
+// TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+// register TQWidget *w;
+// while ( (w=it.current()) ) { // for all widgets...
+// ++it;
+// if ( !w->testWFlags(WType_Desktop) && // except desktop
+// w->testWState(WState_Polished) ) { // has been polished
+// old->unPolish(w);
+// }
+// }
+// }
+// old->unPolish( tqApp );
+ }
+
+ // take care of possible palette requirements of certain gui
+ // styles. Do it before polishing the application since the style
+ // might call TQApplication::setStyle() itself
+ if ( !qt_std_pal )
+ qt_create_std_palette();
+ TQPalette tmpPal = *qt_std_pal;
+ tqsetPalette( tmpPal, TRUE );
+
+ // initialize the application with the new style
+ app_style->polish( tqApp );
+
+ // re-polish existing widgets if necessary
+ if (old) {
+// if ( is_app_running && !is_app_closing ) {
+// TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+// register TQWidget *w;
+// while ( (w=it.current()) ) { // for all widgets...
+// ++it;
+// if ( !w->testWFlags(WType_Desktop) ) { // except desktop
+// if ( w->testWState(WState_Polished) )
+// app_style->polish(w); // repolish
+// w->styleChange( *old );
+// if ( w->isVisible() ){
+// w->update();
+// }
+// }
+// }
+// }
+ delete old;
+ }
+}
+
+/*!
+ \overload
+
+ Requests a TQStyle object for \a style from the TQStyleFactory.
+
+ The string must be one of the TQStyleFactory::keys(), typically one
+ of "windows", "motif", "cde", "motifplus", "platinum", "sgi" and
+ "compact". Depending on the platform, "windowsxp", "aqua" or
+ "macintosh" may be available.
+
+ A later call to the TQApplication constructor will override the
+ requested style when a "-style" option is passed in as a commandline
+ parameter.
+
+ Returns 0 if an unknown \a style is passed, otherwise the TQStyle object
+ returned is set as the application's GUI style.
+*/
+TQStyle* TQApplication::setStyle( const TQString& style )
+{
+#ifdef TQ_WS_X11
+ qt_explicit_app_style = TRUE;
+#endif // TQ_WS_X11
+
+ if ( startingUp() ) {
+ if(qt_style_override)
+ *qt_style_override = style;
+ else
+ qt_style_override = new TQString(style);
+ return 0;
+ }
+ TQStyle *s = TQStyleFactory::create( style );
+ if ( !s )
+ return 0;
+
+ setStyle( s );
+ return s;
+}
+
+TQWidget *TQApplication::mainWidget()
+{
+ return TQT_TQWIDGET(current_app_main_widget);
+}
+
+const char *TQApplication::tqname() const {
+ if (dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ printf("[WARNING] Attempted to call TQApplication::tqname() on an object without a constructed TQApplication object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+const char *TQApplication::name() const {
+ if (dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ printf("[WARNING] Attempted to call TQApplication::name() on an object without a constructed TQApplication object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+/*!\internal
+
+ Called from qapplication_<platform>.cpp, returns TRUE
+ if the widget should accept the event.
+ */
+TQ_EXPORT bool qt_tryModalHelper( TQWidget *widget, TQWidget **rettop ) {
+ TQWidget *modal=0, *top=TQT_TQWIDGET(TQApplication::activeModalWidget());
+ if ( rettop ) *rettop = top;
+
+ if ( tqApp->activePopupWidget() )
+ return TRUE;
+
+#ifdef TQ_WS_MACX
+ top = qt_tryModalHelperMac( top );
+ if ( rettop ) *rettop = top;
+#endif
+
+ TQWidget* groupLeader = widget;
+ widget = widget->tqtopLevelWidget();
+
+ if ( widget->testWFlags(TQt::WShowModal) ) // widget is modal
+ modal = widget;
+ if ( !top || modal == top ) // don't block event
+ return TRUE;
+
+ TQWidget * p = widget->parentWidget(); // Check if the active modal widget is a tqparent of our widget
+ while ( p ) {
+ if ( p == top )
+ return TRUE;
+ p = p->parentWidget();
+ }
+
+ while ( groupLeader && !groupLeader->testWFlags( TQt::WGroupLeader ) )
+ groupLeader = groupLeader->parentWidget();
+
+// [FIXME]
+printf("[WARNING] bool qt_tryModalHelper partially implemented\n\r");
+// if ( groupLeader ) {
+// // Does groupLeader have a child in qt_modal_stack?
+// bool unrelated = TRUE;
+// modal = qt_modal_stack->first();
+// while (modal && unrelated) {
+// TQWidget* p = modal->parentWidget();
+// while ( p && p != groupLeader && !p->testWFlags( TQt::WGroupLeader) ) {
+// p = p->parentWidget();
+// }
+// modal = qt_modal_stack->next();
+// if ( p == groupLeader ) unrelated = FALSE;
+// }
+//
+// if ( unrelated )
+// return TRUE; // don't block event
+// }
+
+ return FALSE;
+}
+
+/*!\internal
+
+ Creates the proper Enter/Leave event when widget \a enter is entered
+ and widget \a leave is left.
+ */
+TQ_EXPORT void qt_dispatchEnterLeave( TQWidget* enter, TQWidget* leave ) {
+#if 0
+ if ( leave ) {
+ TQEvent e( TQEvent::Leave );
+ TQApplication::sendEvent( leave, & e );
+ }
+ if ( enter ) {
+ TQEvent e( TQEvent::Enter );
+ TQApplication::sendEvent( enter, & e );
+ }
+ return;
+#endif
+
+ TQWidget* w ;
+ if ( !enter && !leave )
+ return;
+ TQWidgetList leaveList;
+ TQWidgetList enterList;
+
+ bool sameWindow = leave && enter && leave->tqtopLevelWidget() == enter->tqtopLevelWidget();
+ if ( leave && !sameWindow ) {
+ w = leave;
+ do {
+ leaveList.append( w );
+ } while ( (w = w->parentWidget( TRUE ) ) );
+ }
+ if ( enter && !sameWindow ) {
+ w = enter;
+ do {
+ enterList.prepend( w );
+ } while ( (w = w->parentWidget(TRUE) ) );
+ }
+ if ( sameWindow ) {
+ int enterDepth = 0;
+ int leaveDepth = 0;
+ w = enter;
+ while ( ( w = w->parentWidget( TRUE ) ) )
+ enterDepth++;
+ w = leave;
+ while ( ( w = w->parentWidget( TRUE ) ) )
+ leaveDepth++;
+ TQWidget* wenter = enter;
+ TQWidget* wleave = leave;
+ while ( enterDepth > leaveDepth ) {
+ wenter = wenter->parentWidget();
+ enterDepth--;
+ }
+ while ( leaveDepth > enterDepth ) {
+ wleave = wleave->parentWidget();
+ leaveDepth--;
+ }
+ while ( !wenter->isTopLevel() && wenter != wleave ) {
+ wenter = wenter->parentWidget();
+ wleave = wleave->parentWidget();
+ }
+
+ w = leave;
+ while ( w != wleave ) {
+ leaveList.append( w );
+ w = w->parentWidget();
+ }
+ w = enter;
+ while ( w != wenter ) {
+ enterList.prepend( w );
+ w = w->parentWidget();
+ }
+ }
+
+ TQEvent leaveEvent( TQEvent::Leave );
+ for ( w = leaveList.first(); w; w = leaveList.next() ) {
+ if ( !tqApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
+ TQApplication::sendEvent( w, &leaveEvent );
+ }
+ TQEvent enterEvent( TQEvent::Enter );
+ for ( w = enterList.first(); w; w = enterList.next() ) {
+ if ( !tqApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
+ TQApplication::sendEvent( w, &enterEvent );
+ }
+}
+
+#ifndef TQT_NO_CLIPBOARD
+/*!
+ Returns a pointer to the application global clipboard.
+*/
+TQClipboard *TQApplication::tqclipboard()
+{
+ if ( tqt_clipboard == 0 ) {
+ tqt_clipboard = new TQClipboard;
+ TQ_CHECK_PTR( tqt_clipboard );
+ }
+ return tqt_clipboard;
+}
+#endif // TQT_NO_CLIPBOARD
+
+/*!
+ \fn void TQApplication::commitData( TQSessionManager& sm )
+
+ This function deals with \link session.html session
+ management\endlink. It is invoked when the TQSessionManager wants the
+ application to commit all its data.
+
+ Usually this means saving all open files, after getting
+ permission from the user. Furthermore you may want to provide a means
+ by which the user can cancel the shutdown.
+
+ Note that you should not exit the application within this function.
+ Instead, the session manager may or may not do this afterwards,
+ depending on the context.
+
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the session manager \a sm for explicit permission.
+ See TQSessionManager::allowsInteraction() and
+ TQSessionManager::allowsErrorInteraction() for details and example
+ usage.
+
+ The default implementation requests interaction and sends a close
+ event to all visible top level widgets. If any event was
+ rejected, the shutdown is canceled.
+
+ \sa isSessionRestored(), sessionId(), saveState(), \link session.html the Session Management overview\endlink
+*/
+#ifndef TQT_NO_SESSIONMANAGER
+void TQApplication::commitData( TQSessionManager& sm )
+{
+
+ if ( sm.allowsInteraction() ) {
+ TQWidgetList done;
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ bool cancelled = FALSE;
+ TQWidget* w = list->first();
+ while ( !cancelled && w ) {
+ if ( !w->isHidden() ) {
+ TQCloseEvent e;
+ sendEvent( w, &e );
+ cancelled = !e.isAccepted();
+ if ( !cancelled )
+ done.append( w );
+ delete list; // one never knows...
+ list = TQApplication::tqtopLevelWidgets();
+ w = list->first();
+ } else {
+ w = list->next();
+ }
+ while ( w && done.tqcontainsRef( w ) )
+ w = list->next();
+ }
+ delete list;
+ if ( cancelled )
+ sm.cancel();
+ }
+}
+
+
+/*!
+ \fn void TQApplication::saveState( TQSessionManager& sm )
+
+ This function deals with \link session.html session
+ management\endlink. It is invoked when the
+ \link TQSessionManager session manager \endlink wants the application
+ to preserve its state for a future session.
+
+ For example, a text editor would create a temporary file that
+ includes the current contents of its edit buffers, the location of
+ the cursor and other aspects of the current editing session.
+
+ Note that you should never exit the application within this
+ function. Instead, the session manager may or may not do this
+ afterwards, depending on the context. Futhermore, most session
+ managers will very likely request a saved state immediately after
+ the application has been started. This permits the session manager
+ to learn about the application's restart policy.
+
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the session manager \a sm for explicit permission.
+ See TQSessionManager::allowsInteraction() and
+ TQSessionManager::allowsErrorInteraction() for details.
+
+ \sa isSessionRestored(), sessionId(), commitData(), \link session.html the Session Management overview\endlink
+*/
+
+void TQApplication::saveState( TQSessionManager& /* sm */ )
+{
+}
+#endif //TQT_NO_SESSIONMANAGER
+
+#if 1 /* OBSOLETE */
+
+TQApplication::ColorMode TQApplication::colorMode()
+{
+ return (TQApplication::ColorMode)app_cspec;
+}
+
+void TQApplication::setColorMode( TQApplication::ColorMode mode )
+{
+ printf("[WARNING] TQApplication::setColorMode() does nothing!\n\r");
+ app_cspec = mode;
+}
+#endif
+
+/*!
+ Initialization of the appearance of the widget \a w \e before it is first
+ shown.
+
+ Usually widgets call this automatically when they are polished. It
+ may be used to do some style-based central customization of widgets.
+
+ Note that you are not limited to the public functions of TQWidget.
+ Instead, based on meta information like TQObject::className() you are
+ able to customize any kind of widget.
+
+ \sa TQStyle::polish(), TQWidget::polish(), setPalette(), setFont()
+*/
+
+void TQApplication::polish( QWidget *w )
+{
+#ifndef TQT_NO_STYLE
+ TQT_TQWIDGET(w)->tqstyle().polish( w );
+#endif
+}
+
+void TQApplication::exit_loop() { // Does not exit in Qt4
+ printf("[WARNING] No runtime validation is performed within TQApplication::exit_loop; this may cause odd/obscure problems\n\r");
+// QThreadData *data = QThreadData::current();
+// if (!data->eventLoops.isEmpty())
+// data->eventLoops.top()->exit();
+ QEventLoop* eventLoop = tqt_event_loop_stack.getLast();
+ if (eventLoop) {
+ eventLoop->exit();
+ }
+ else {
+ printf("[WARNING] An attempt was made to exit a nonexistant event loop!\n\r");
+ }
+}
+int TQApplication::enter_loop() { // Does not exit in Qt4
+ printf("[WARNING] No runtime validation is performed within TQApplication::enter_loop; this may cause odd/obscure problems\n\r");
+ QEventLoop* eventLoop = new QEventLoop();
+ tqt_event_loop_stack.append(eventLoop);
+ int returnCode = eventLoop->exec(); // This blocks until either QEventLoop::exit is called or the loop terminates normally
+ tqt_event_loop_stack.remove(eventLoop);
+ delete eventLoop;
+ return returnCode;
+}
+
+TQMetaObject *TQApplication::tqmetaObject() const {
+ return TQT_TQOBJECT_CONST(this)->tqmetaObject();
+}
+
+void TQApplication::processOneEvent() {
+ processEvents(QEventLoop::WaitForMoreEvents);
+}
+
+void TQApplication::tqprocessEvents() {
+ return processEvents();
+}
+
+void TQApplication::tqprocessEvents( int maxtime ) {
+ return processEvents(QEventLoop::AllEvents, maxtime);
+}
+
+/*!
+ \obsolete
+
+ Returns the current loop level.
+
+ Use TQApplication::eventLoop()->loopLevel() instead.
+
+*/
+int TQApplication::loopLevel() const
+{
+ return eventLoop()->loopLevel();
+}
+
+bool TQApplication::hasGlobalMouseTracking()
+{
+ printf("[WARNING] TQApplication::hasGlobalMouseTracking unimplemented!\n\r");
+ return true;
+}
+
+void TQApplication::setGlobalMouseTracking( bool enable )
+{
+ printf("[WARNING] TQApplication::setGlobalMouseTracking unimplemented!\n\r");
+}
+
+#if defined(TQ_WS_X11)
+void TQApplication::create_xim() {
+ printf("[WARNING] static void TQApplication::create_xim() unimplemented\n\r"); // [FIXME]
+}
+
+void TQApplication::close_xim() {
+ printf("[WARNING] static void TQApplication::close_xim() unimplemented\n\r"); // [FIXME]
+}
+
+bool TQApplication::x11_apply_settings() {
+ printf("[WARNING] static bool TQApplication::x11_apply_settings() unimplemented\n\r");
+ return false; // [FIXME]
+}
+#endif
+
+#ifndef TQT_NO_TEXTCODEC
+void TQApplication::setDefaultCodec( TQTextCodec * ) {
+ printf("[WARNING] void TQApplication::setDefaultCodec( TQTextCodec * ) unimplemented\n\r"); // [FIXME]
+}
+
+TQTextCodec* TQApplication::defaultCodec() const
+{
+// return TQTextCodec::codecForTr();
+
+ printf("[WARNING] TQTextCodec* TQApplication::defaultCodec unimplemented\n\r"); // [FIXME]
+// return TQTextCodec();
+}
+#endif
+
+TQWidgetList *TQApplication::tqallWidgets() {
+ QWidgetList ql = allWidgets();
+ tqt_all_widgets_list.clear();
+ for (int i = 0; i < ql.size(); ++i) tqt_all_widgets_list.append(TQT_TQWIDGET(ql.at(i)));
+ return &tqt_all_widgets_list;
+}
+
+TQStringList TQApplication::libraryPaths() {
+ return TQT_TQSTRINGLIST_OBJECT(QApplication::libraryPaths());
+}
+
+void TQApplication::tqsetLibraryPaths( const QStringList &qsl ) {
+ setLibraryPaths(qsl);
+}
+
+TQWidgetList *TQApplication::tqtopLevelWidgets() {
+ // The end user of the list is expected to delete it, so create it with new...
+ TQWidgetList *tqwl = new TQWidgetList();
+ foreach (QWidget *widget, QApplication::topLevelWidgets()) {
+ tqwl->append(static_cast<TQWidget*>(widget));
+ }
+ return tqwl;
+
+}
+
+TQDesktopWidget *TQApplication::desktop() {
+ return static_cast<TQDesktopWidget*>(QApplication::desktop());
+}
+
+const QColor &TQApplication::winStyleHighlightColor() {
+ return palette().color(QPalette::Active, QPalette::Highlight);
+}
+
+void TQApplication::setWinStyleHighlightColor( const QColor c ) {
+ TQPalette p( tqpalette() );
+ p.setColor( TQColorGroup::Highlight, c );
+ tqsetPalette( p, TRUE);
+}
+
+void TQApplication::tqsetPalette(const QPalette &pal, bool, const char* className) {
+ setPalette(pal, className);
+}
+
+void TQApplication::tqsetFont(const QFont &font, bool, const char* className) {
+ setFont(font, className);
+}
+
+void TQApplication::setReverseLayout(bool b) {
+ setLayoutDirection(b?Qt::RightToLeft:Qt::LeftToRight);
+}
+
+bool TQApplication::reverseLayout() {
+ return layoutDirection() == Qt::RightToLeft;
+}
+
+TQPalette TQApplication::tqpalette( const TQWidget*w ) {
+ return palette( w );
+}
+
+#ifndef TQT_NO_CURSOR
+//void TQApplication::setOverrideCursor( const QCursor &cur, bool tqreplace=FALSE ) {
+// TQ_UNUSED(tqreplace);
+// QApplication::setOverrideCursor( cur );
+// }
+
+void TQApplication::setOverrideCursor( const QCursor &cur, bool tqreplace ) {
+ TQ_UNUSED(tqreplace);
+ printf("[FIXME] TQApplication::setOverrideCursor( const QCursor &cur, bool tqreplace=FALSE ) unimplemented\n\r");
+}
+#endif
+
+void TQApplication::sendPostedEvents( QObject *receiver, int event_type ) {
+ QApplication::sendPostedEvents(receiver, event_type);
+ if (event_type == TQEvent::LayoutHint) {
+ QApplication::sendPostedEvents(receiver, TQEvent::LayoutRequest);; // This one eats LayoutRequest/LayoutHint events for breakfast
+ }
+}
+
+void TQApplication::sendPostedEvents() {
+ QApplication::sendPostedEvents();
+}
+
+TQWidget *TQApplication::tqfocusWidget() const {
+ return static_cast<TQWidget*>(focusWidget());
+}
+
+TQWidget *TQApplication::widgetAt( const TQPoint &p, bool child ) {
+ TQ_UNUSED(child);
+ return static_cast<TQWidget*>(QApplication::widgetAt( p ));
+}
+
+TQWidget *TQApplication::widgetAt( int x, int y, bool child ) {
+ TQ_UNUSED(child);
+ return static_cast<TQWidget*>(QApplication::widgetAt( QPoint(x, y) ));
+}
+
+int TQApplication::horizontalAlignment( int align ) {
+ return QStyle::visualAlignment(layoutDirection(), (Qt::Alignment)align);
+}
+
+void TQApplication::flushX() {
+ flush();
+}
+
+const char *TQApplication::name(const char *defaultName) const {
+ TQString s = objectName();
+ return s.isEmpty()?defaultName:s.latin1();
+}
+
+void TQApplication::setName(const char *aName) {
+ TQT_TQOBJECT(this)->setName(aName);
+}
+
+/*!
+ Displays a simple message box about TQt. The message includes the
+ version number of TQt being used by the application.
+
+ This is useful for inclusion in the Help menu of an application.
+ See the examples/menu/menu.cpp example.
+
+ This function is a convenience slot for TQMessageBox::aboutTQt().
+*/
+void TQApplication::aboutTQt()
+{
+#ifndef TQT_NO_MESSAGEBOX
+ TQMessageBox::aboutTQt( mainWidget() );
+#endif // TQT_NO_MESSAGEBOX
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQApplication tqapplication.h
+ \brief The TQApplication class manages the GUI application's control
+ flow and main settings.
+
+ \ingroup application
+ \mainclass
+
+ It tqcontains the main event loop, where all events from the window
+ system and other sources are processed and dispatched. It also
+ handles the application's initialization and finalization, and
+ provides session management. It also handles most system-wide and
+ application-wide settings.
+
+ For any GUI application that uses TQt, there is precisely one
+ TQApplication object, no matter whether the application has 0, 1, 2
+ or more windows at any time.
+
+ The TQApplication object is accessible through the global pointer \c
+ tqApp. Its main areas of responsibility are:
+ \list
+
+ \i It initializes the application with the user's desktop settings
+ such as palette(), font() and doubleClickInterval(). It keeps track
+ of these properties in case the user changes the desktop globally, for
+ example through some kind of control panel.
+
+ \i It performs event handling, meaning that it receives events
+ from the underlying window system and dispatches them to the relevant
+ widgets. By using sendEvent() and postEvent() you can send your own
+ events to widgets.
+
+ \i It parses common command line arguments and sets its internal
+ state accordingly. See the \link TQApplication::TQApplication()
+ constructor documentation\endlink below for more details about this.
+
+ \i It defines the application's look and feel, which is
+ encapsulated in a TQStyle object. This can be changed at runtime
+ with setStyle().
+
+ \i It specifies how the application is to allocate colors.
+ See setColorSpec() for details.
+
+ \i It provides localization of strings that are visible to the user
+ via translate().
+
+ \i It provides some magical objects like the desktop() and the
+ clipboard().
+
+ \i It knows about the application's windows. You can ask which
+ widget is at a certain position using widgetAt(), get a list of
+ tqtopLevelWidgets() and closeAllWindows(), etc.
+
+ \i It manages the application's mouse cursor handling,
+ see setOverrideCursor() and setGlobalMouseTracking().
+
+ \i On the X window system, it provides functions to flush and sync
+ the communication stream, see flushX() and syncX().
+
+ \i It provides support for sophisticated \link
+ session.html session management \endlink. This makes it possible
+ for applications to terminate gracefully when the user logs out, to
+ cancel a shutdown process if termination isn't possible and even to
+ preserve the entire application's state for a future session. See
+ isSessionRestored(), sessionId() and commitData() and saveState()
+ for details.
+
+ \endlist
+
+ The <a href="simple-application.html">Application walk-through
+ example</a> tqcontains a typical complete main() that does the usual
+ things with TQApplication.
+
+ Since the TQApplication object does so much initialization, it
+ <b>must</b> be created before any other objects related to the user
+ interface are created.
+
+ Since it also deals with common command line arguments, it is
+ usually a good idea to create it \e before any interpretation or
+ modification of \c argv is done in the application itself. (Note
+ also that for X11, setMainWidget() may change the main widget
+ according to the \c -tqgeometry option. To preserve this
+ functionality, you must set your defaults before setMainWidget() and
+ any overrides after.)
+
+ \table
+ \header \i21 Groups of functions
+ \row
+ \i System settings
+ \i
+ desktopSettingsAware(),
+ setDesktopSettingsAware(),
+ cursorFlashTime(),
+ setCursorFlashTime(),
+ doubleClickInterval(),
+ setDoubleClickInterval(),
+ wheelScrollLines(),
+ setWheelScrollLines(),
+ palette(),
+ setPalette(),
+ font(),
+ setFont(),
+ fontMetrics().
+
+ \row
+ \i Event handling
+ \i
+ exec(),
+ processEvents(),
+ enter_loop(),
+ exit_loop(),
+ exit(),
+ quit().
+ sendEvent(),
+ postEvent(),
+ sendPostedEvents(),
+ removePostedEvents(),
+ hasPendingEvents(),
+ notify(),
+ macEventFilter(),
+ qwsEventFilter(),
+ x11EventFilter(),
+ x11ProcessEvent(),
+ winEventFilter().
+
+ \row
+ \i GUI Styles
+ \i
+ style(),
+ setStyle(),
+ polish().
+
+ \row
+ \i Color usage
+ \i
+ colorSpec(),
+ setColorSpec(),
+ qwsSetCustomColors().
+
+ \row
+ \i Text handling
+ \i
+ installTranslator(),
+ removeTranslator()
+ translate().
+
+ \row
+ \i Widgets
+ \i
+ mainWidget(),
+ setMainWidget(),
+ allWidgets(),
+ tqtopLevelWidgets(),
+ desktop(),
+ activePopupWidget(),
+ activeModalWidget(),
+ clipboard(),
+ tqfocusWidget(),
+ winFocus(),
+ activeWindow(),
+ widgetAt().
+
+ \row
+ \i Advanced cursor handling
+ \i
+ hasGlobalMouseTracking(),
+ setGlobalMouseTracking(),
+ overrideCursor(),
+ setOverrideCursor(),
+ restoreOverrideCursor().
+
+ \row
+ \i X Window System synchronization
+ \i
+ flushX(),
+ syncX().
+
+ \row
+ \i Session management
+ \i
+ isSessionRestored(),
+ sessionId(),
+ commitData(),
+ saveState().
+
+ \row
+ \i Threading
+ \i
+ lock(), unlock(), locked(), tryLock(),
+ wakeUpGuiThread()
+
+ \row
+ \i Miscellaneous
+ \i
+ closeAllWindows(),
+ startingUp(),
+ closingDown(),
+ type().
+ \endtable
+
+ \e {Non-GUI programs:} While TQt is not optimized or
+ designed for writing non-GUI programs, it's possible to use
+ \link tools.html some of its classes \endlink without creating a
+ TQApplication. This can be useful if you wish to share code between
+ a non-GUI server and a GUI client.
+
+ \headerfile tqnamespace.h
+ \headerfile tqwindowdefs.h
+ \headerfile tqglobal.h
+*/
+
+/*! \enum TQt::HANDLE
+ \internal
+*/
+
+/*!
+ \enum TQApplication::Type
+
+ \value Tty a console application
+ \value GuiClient a GUI client application
+ \value GuiServer a GUI server application
+*/
+
+/*!
+ \enum TQApplication::ColorSpec
+
+ \value NormalColor the default color allocation policy
+ \value CustomColor the same as NormalColor for X11; allocates colors
+ to a palette on demand under Windows
+ \value ManyColor the right choice for applications that use thousands of
+ colors
+
+ See setColorSpec() for full details.
+*/
+
+/*
+ The qt_init() and qt_cleanup() functions are implemented in the
+ qapplication_xyz.cpp file.
+*/
+
+void qt_init( int *, char **, TQApplication::Type );
+void qt_cleanup();
+#if defined(TQ_WS_X11)
+void qt_init( Display* dpy, TQt::HANDLE, TQt::HANDLE );
+#endif
+TQ_EXPORT bool qt_tryModalHelper( TQWidget *widget, TQWidget **rettop );
+
+TQApplication *tqApp = 0; // global application object
+
+TQStyle *TQApplication::app_style = 0; // default application style
+bool qt_explicit_app_style = FALSE; // style explicitly set by programmer
+
+int TQApplication::app_cspec = TQApplication::NormalColor;
+#ifndef TQT_NO_PALETTE
+TQPalette *TQApplication::app_pal = 0; // default application palette
+#endif
+TQFont *TQApplication::app_font = 0; // default application font
+bool qt_app_has_font = FALSE;
+#ifndef TQT_NO_CURSOR
+TQCursor *TQApplication::app_cursor = 0; // default application cursor
+#endif
+int TQApplication::app_tracking = 0; // global mouse tracking
+bool TQApplication::is_app_running = FALSE; // app starting up if FALSE
+bool TQApplication::is_app_closing = FALSE; // app closing down if TRUE
+int TQApplication::loop_level = 0; // event loop level
+TQWidget *TQApplication::main_widget = 0; // main application widget
+TQWidget *TQApplication::focus_widget = 0; // has keyboard input focus
+TQWidget *TQApplication::active_window = 0; // toplevel with keyboard focus
+bool TQApplication::obey_desktop_settings = TRUE; // use winsys resources
+int TQApplication::cursor_flash_time = 1000; // text caret flash time
+int TQApplication::mouse_double_click_time = 400; // mouse dbl click limit
+#ifndef TQT_NO_WHEELEVENT
+int TQApplication::wheel_scroll_lines = 3; // number of lines to scroll
+#endif
+bool qt_is_gui_used;
+bool TQ_EXPORT qt_resolve_symlinks = TRUE;
+bool TQ_EXPORT qt_tab_all_widgets = TRUE;
+TQRect qt_maxWindowRect;
+static int drag_time = 500;
+static int drag_distance = 4;
+static bool reverse_tqlayout = FALSE;
+TQSize TQApplication::app_strut = TQSize( 0,0 ); // no default application strut
+bool TQApplication::animate_ui = TRUE;
+bool TQApplication::animate_menu = FALSE;
+bool TQApplication::fade_menu = FALSE;
+bool TQApplication::animate_combo = FALSE;
+bool TQApplication::animate_tooltip = FALSE;
+bool TQApplication::fade_tooltip = FALSE;
+bool TQApplication::animate_toolbox = FALSE;
+bool TQApplication::widgetCount = FALSE;
+TQApplication::Type qt_appType=TQApplication::Tty;
+#ifndef TQT_NO_COMPONENT
+TQStringList *TQApplication::app_libpaths = 0;
+#endif
+bool TQApplication::metaComposeUnicode = FALSE;
+int TQApplication::composedUnicode = 0;
+
+#ifdef TQT_THREAD_SUPPORT
+TQMutex *TQApplication::qt_mutex = 0;
+static TQMutex *postevent_mutex = 0;
+static TQt::HANDLE qt_application_thread_id = 0;
+TQ_EXPORT TQt::HANDLE qt_get_application_thread_id()
+{
+ return qt_application_thread_id;
+}
+#endif // TQT_THREAD_SUPPORT
+
+TQEventLoop *TQApplication::eventloop = 0; // application event loop
+
+#ifndef TQT_NO_ACCEL
+extern bool qt_dispatchAccelEvent( TQWidget*, TQKeyEvent* ); // def in qaccel.cpp
+extern bool qt_tryComposeUnicode( TQWidget*, TQKeyEvent* ); // def in qaccel.cpp
+#endif
+
+#if defined(TQT_TABLET_SUPPORT)
+bool chokeMouse = FALSE;
+#endif
+
+void qt_setMaxWindowRect(const TQRect& r)
+{
+ qt_maxWindowRect = r;
+ // Re-resize any maximized windows
+ TQWidgetList* l = TQApplication::tqtopLevelWidgets();
+ if ( l ) {
+ TQWidget *w = l->first();
+ while ( w ) {
+ if ( w->isVisible() && w->isMaximized() )
+ {
+ w->showNormal(); //#### flicker
+ w->showMaximized();
+ }
+ w = l->next();
+ }
+ delete l;
+ }
+}
+
+typedef void (*VFPTR)();
+typedef TQValueList<VFPTR> TQVFuncList;
+static TQVFuncList *postRList = 0; // list of post routines
+
+/*!
+ \relates TQApplication
+
+ Adds a global routine that will be called from the TQApplication
+ destructor. This function is normally used to add cleanup routines
+ for program-wide functionality.
+
+ The function given by \a p should take no arguments and return
+ nothing, like this:
+ \code
+ static int *global_ptr = 0;
+
+ static void cleanup_ptr()
+ {
+ delete [] global_ptr;
+ global_ptr = 0;
+ }
+
+ void init_ptr()
+ {
+ global_ptr = new int[100]; // allocate data
+ qAddPostRoutine( cleanup_ptr ); // delete later
+ }
+ \endcode
+
+ Note that for an application- or module-wide cleanup,
+ qAddPostRoutine() is often not suitable. People have a tendency to
+ make such modules dynamically loaded, and then unload those modules
+ long before the TQApplication destructor is called, for example.
+
+ For modules and libraries, using a reference-counted initialization
+ manager or TQt' tqparent-child delete mechanism may be better. Here is
+ an example of a private class which uses the tqparent-child mechanism
+ to call a cleanup function at the right time:
+
+ \code
+ class MyPrivateInitStuff: public TQObject {
+ private:
+ MyPrivateInitStuff( TQObject * tqparent ): TQObject( tqparent) {
+ // initialization goes here
+ }
+ MyPrivateInitStuff * p;
+
+ public:
+ static MyPrivateInitStuff * initStuff( TQObject * tqparent ) {
+ if ( !p )
+ p = new MyPrivateInitStuff( tqparent );
+ return p;
+ }
+
+ ~MyPrivateInitStuff() {
+ // cleanup (the "post routine") goes here
+ }
+ }
+ \endcode
+
+ By selecting the right tqparent widget/object, this can often be made
+ to clean up the module's data at the exact right moment.
+*/
+
+TQ_EXPORT void qAddPostRoutine( TQtCleanUpFunction p)
+{
+ if ( !postRList ) {
+ postRList = new TQVFuncList;
+ TQ_CHECK_PTR( postRList );
+ }
+ postRList->prepend( p );
+}
+
+
+TQ_EXPORT void qRemovePostRoutine( TQtCleanUpFunction p )
+{
+ if ( !postRList ) return;
+ TQVFuncList::Iterator it = postRList->begin();
+ while ( it != postRList->end() ) {
+ if ( *it == p ) {
+ postRList->remove( it );
+ it = postRList->begin();
+ } else {
+ ++it;
+ }
+ }
+}
+
+// Default application palettes and fonts (per widget type)
+TQAsciiDict<TQPalette> *TQApplication::app_palettes = 0;
+TQAsciiDict<TQFont> *TQApplication::app_fonts = 0;
+
+#ifndef TQT_NO_SESSIONMANAGER
+TQString *TQApplication::session_key = 0; // ## session key. Should be a member in 4.0
+#endif
+TQWidgetList *TQApplication::popupWidgets = 0; // has keyboard input focus
+
+TQDesktopWidget *qt_desktopWidget = 0; // root window widgets
+#ifndef TQT_NO_CLIPBOARD
+TQClipboard *qt_clipboard = 0; // global clipboard object
+#endif
+TQWidgetList * qt_modal_stack=0; // stack of modal widgets
+
+// Definitions for posted events
+struct TQPostEvent {
+ TQPostEvent( TQObject *r, TQEvent *e ): receiver( r ), event( e ) {}
+ ~TQPostEvent() { delete event; }
+ TQObject *receiver;
+ TQEvent *event;
+};
+
+class TQ_EXPORT TQPostEventList : public TQPtrList<TQPostEvent>
+{
+public:
+ TQPostEventList() : TQPtrList<TQPostEvent>() {}
+ TQPostEventList( const TQPostEventList &list ) : TQPtrList<TQPostEvent>(list) {}
+ ~TQPostEventList() { clear(); }
+ TQPostEventList &operator=(const TQPostEventList &list)
+ { return (TQPostEventList&)TQPtrList<TQPostEvent>::operator=(list); }
+};
+class TQ_EXPORT TQPostEventListIt : public TQPtrListIterator<TQPostEvent>
+{
+public:
+ TQPostEventListIt( const TQPostEventList &l ) : TQPtrListIterator<TQPostEvent>(l) {}
+ TQPostEventListIt &operator=(const TQPostEventListIt &i)
+{ return (TQPostEventListIt&)TQPtrListIterator<TQPostEvent>::operator=(i); }
+};
+
+static TQPostEventList *globalPostedEvents = 0; // list of posted events
+
+uint qGlobalPostedEventsCount()
+{
+ if (!globalPostedEvents)
+ return 0;
+ return globalPostedEvents->count();
+}
+
+static TQSingleCleanupHandler<TQPostEventList> qapp_cleanup_events;
+
+#ifndef TQT_NO_PALETTE
+TQPalette *qt_std_pal = 0;
+
+void qt_create_std_palette()
+{
+ if ( qt_std_pal )
+ delete qt_std_pal;
+
+ TQColor standardLightGray( 192, 192, 192 );
+ TQColor light( 255, 255, 255 );
+ TQColor dark( standardLightGray.dark( 150 ) );
+ TQColorGroup std_act( TQt::black, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::black, TQt::white );
+ TQColorGroup std_dis( TQt::darkGray, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::darkGray, std_act.background() );
+ TQColorGroup std_inact( TQt::black, standardLightGray,
+ light, dark, TQt::gray,
+ TQt::black, TQt::white );
+ qt_std_pal = new TQPalette( std_act, std_dis, std_inact );
+}
+
+static void qt_fix_tooltips()
+{
+ // No resources for this yet (unlike on Windows).
+ TQColorGroup cg( TQt::black, TQColor(255,255,220),
+ TQColor(96,96,96), TQt::black, TQt::black,
+ TQt::black, TQColor(255,255,220) );
+ TQPalette pal( cg, cg, cg );
+ TQApplication::setPalette( pal, TRUE, "TQTipLabel");
+}
+#endif
+
+void TQApplication::process_cmdline( int* argcptr, char ** argv )
+{
+ // process platform-indep command line
+ if ( !qt_is_gui_used || !*argcptr)
+ return;
+
+ int argc = *argcptr;
+ int i, j;
+
+ j = 1;
+ for ( i=1; i<argc; i++ ) {
+ if ( argv[i] && *argv[i] != '-' ) {
+ argv[j++] = argv[i];
+ continue;
+ }
+ TQCString arg = argv[i];
+ TQCString s;
+ if ( arg == "-qdevel" || arg == "-qdebug") {
+ // obsolete argument
+ } else if ( arg.tqfind( "-style=", 0, FALSE ) != -1 ) {
+ s = arg.right( arg.length() - 7 );
+ } else if ( qstrcmp(arg,"-style") == 0 && i < argc-1 ) {
+ s = argv[++i];
+ s = s.lower();
+#ifndef TQT_NO_SESSIONMANAGER
+ } else if ( qstrcmp(arg,"-session") == 0 && i < argc-1 ) {
+ TQCString s = argv[++i];
+ if ( !s.isEmpty() ) {
+ session_id = TQString::tqfromLatin1( s );
+ int p = session_id.tqfind( '_' );
+ if ( p >= 0 ) {
+ if ( !session_key )
+ session_key = new TQString;
+ *session_key = session_id.mid( p +1 );
+ session_id = session_id.left( p );
+ }
+ is_session_restored = TRUE;
+ }
+#endif
+ } else if ( qstrcmp(arg, "-reverse") == 0 ) {
+ setReverseLayout( TRUE );
+ } else if ( qstrcmp(arg, "-widgetcount") == 0 ) {
+ widgetCount = TRUE;;
+ } else {
+ argv[j++] = argv[i];
+ }
+#ifndef TQT_NO_STYLE
+ if ( !s.isEmpty() ) {
+ setStyle( s );
+ }
+#endif
+ }
+
+ if(j < argc) {
+#ifdef TQ_WS_MACX
+ static char* empty = "\0";
+ argv[j] = empty;
+#else
+ argv[j] = 0;
+#endif
+ *argcptr = j;
+ }
+}
+
+/*!
+ Initializes the window system and constructs an application object
+ with \a argc command line arguments in \a argv.
+
+ The global \c tqApp pointer refers to this application object. Only
+ one application object should be created.
+
+ This application object must be constructed before any \link
+ TQPaintDevice paint tqdevices\endlink (including widgets, pixmaps, bitmaps
+ etc.).
+
+ Note that \a argc and \a argv might be changed. TQt removes command
+ line arguments that it recognizes. The modified \a argc and \a argv
+ can also be accessed later with \c tqApp->argc() and \c tqApp->argv().
+ The documentation for argv() tqcontains a detailed description of how
+ to process command line arguments.
+
+ TQt debugging options (not available if TQt was compiled with the
+ TQT_NO_DEBUG flag defined):
+ \list
+ \i -nograb, tells TQt that it must never grab the mouse or the keyboard.
+ \i -dograb (only under X11), running under a debugger can cause
+ an implicit -nograb, use -dograb to override.
+ \i -sync (only under X11), switches to synchronous mode for
+ debugging.
+ \endlist
+
+ See \link debug.html Debugging Techniques \endlink for a more
+ detailed explanation.
+
+ All TQt programs automatically support the following command line options:
+ \list
+ \i -reverse causes text to be formatted for right-to-left languages
+ rather than in the usual left-to-right direction.
+ \i -style= \e style, sets the application GUI style. Possible values
+ are \c motif, \c windows, and \c platinum. If you compiled TQt
+ with additional styles or have additional styles as plugins these
+ will be available to the \c -style command line option.
+ \i -style \e style, is the same as listed above.
+ \i -session= \e session, restores the application from an earlier
+ \link session.html session \endlink.
+ \i -session \e session, is the same as listed above.
+ \i -widgetcount, prints debug message at the end about number of widgets left
+ undestroyed and maximum number of widgets existed at the same time
+ \endlist
+
+ The X11 version of TQt also supports some traditional X11
+ command line options:
+ \list
+ \i -display \e display, sets the X display (default is $DISPLAY).
+ \i -tqgeometry \e tqgeometry, sets the client tqgeometry of the
+ \link setMainWidget() main widget\endlink.
+ \i -fn or \c -font \e font, defines the application font. The
+ font should be specified using an X logical font description.
+ \i -bg or \c -background \e color, sets the default background color
+ and an application palette (light and dark shades are calculated).
+ \i -fg or \c -foreground \e color, sets the default foreground color.
+ \i -btn or \c -button \e color, sets the default button color.
+ \i -name \e name, sets the application name.
+ \i -title \e title, sets the application title (caption).
+ \i -visual \c TrueColor, forces the application to use a TrueColor visual
+ on an 8-bit display.
+ \i -ncols \e count, limits the number of colors allocated in the
+ color cube on an 8-bit display, if the application is using the
+ \c TQApplication::ManyColor color specification. If \e count is
+ 216 then a 6x6x6 color cube is used (i.e. 6 levels of red, 6 of green,
+ and 6 of blue); for other values, a cube
+ approximately proportional to a 2x3x1 cube is used.
+ \i -cmap, causes the application to install a private color map
+ on an 8-bit display.
+ \endlist
+
+ \sa argc(), argv()
+*/
+
+//######### BINARY COMPATIBILITY constructor
+TQApplication::TQApplication( int &argc, char **argv )
+{
+ construct( argc, argv, GuiClient );
+}
+
+
+/*!
+ Constructs an application object with \a argc command line arguments
+ in \a argv. If \a GUIenabled is TRUE, a GUI application is
+ constructed, otherwise a non-GUI (console) application is created.
+
+ Set \a GUIenabled to FALSE for programs without a graphical user
+ interface that should be able to run without a window system.
+
+ On X11, the window system is initialized if \a GUIenabled is TRUE.
+ If \a GUIenabled is FALSE, the application does not connect to the
+ X-server.
+ On Windows and Macintosh, currently the window system is always
+ initialized, regardless of the value of GUIenabled. This may change in
+ future versions of TQt.
+
+ The following example shows how to create an application that
+ uses a graphical interface when available.
+ \code
+ int main( int argc, char **argv )
+ {
+#ifdef TQ_WS_X11
+ bool useGUI = getenv( "DISPLAY" ) != 0;
+#else
+ bool useGUI = TRUE;
+#endif
+ TQApplication app(argc, argv, useGUI);
+
+ if ( useGUI ) {
+ //start GUI version
+ ...
+ } else {
+ //start non-GUI version
+ ...
+ }
+ return app.exec();
+ }
+\endcode
+*/
+
+TQApplication::TQApplication( int &argc, char **argv, bool GUIenabled )
+{
+ construct( argc, argv, GUIenabled ? GuiClient : Tty );
+}
+
+/*!
+ Constructs an application object with \a argc command line arguments
+ in \a argv.
+
+ For TQt/Embedded, passing \c TQApplication::GuiServer for \a type
+ makes this application the server (equivalent to running with the
+ -qws option).
+*/
+TQApplication::TQApplication( int &argc, char **argv, Type type )
+{
+ construct( argc, argv, type );
+}
+
+TQ_EXPORT void qt_ucm_initialize( TQApplication *theApp )
+{
+ if ( tqApp )
+ return;
+ int argc = theApp->argc();
+ char **argv = theApp->argv();
+ theApp->construct( argc, argv, tqApp->type() );
+
+ TQ_ASSERT( tqApp == theApp );
+}
+
+void TQApplication::construct( int &argc, char **argv, Type type )
+{
+ qt_appType = type;
+ qt_is_gui_used = (type != Tty);
+ init_precmdline();
+ static const char *empty = "";
+ if ( argc == 0 || argv == 0 ) {
+ argc = 0;
+ argv = (char **)&empty; // ouch! careful with TQApplication::argv()!
+ }
+ app_argc = argc;
+ app_argv = argv;
+
+ qt_init( &argc, argv, type ); // Must be called before initialize()
+ process_cmdline( &argc, argv );
+ initialize( argc, argv );
+ if ( qt_is_gui_used )
+ qt_maxWindowRect = desktop()->rect();
+ if ( eventloop )
+ eventloop->appStartingUp();
+}
+
+/*!
+ Returns the type of application, Tty, GuiClient or GuiServer.
+*/
+
+TQApplication::Type TQApplication::type() const
+{
+ return qt_appType;
+}
+
+#if defined(TQ_WS_X11)
+/*!
+ Create an application, given an already open display \a dpy. If \a
+ visual and \a colormap are non-zero, the application will use those as
+ the default Visual and Colormap contexts.
+
+ \warning TQt only supports TrueColor visuals at depths higher than 8
+ bits-per-pixel.
+
+ This is available only on X11.
+*/
+
+TQApplication::TQApplication( Display* dpy, HANDLE visual, HANDLE colormap )
+{
+ static int aargc = 1;
+ // ### a string literal is a cont char*
+ // ### using it as a char* is wrong and could lead to segfaults
+ // ### if aargv is modified someday
+ static char *aargv[] = { (char*)"unknown", 0 };
+
+ app_argc = aargc;
+ app_argv = aargv;
+
+ qt_appType = GuiClient;
+ qt_is_gui_used = TRUE;
+ qt_appType = GuiClient;
+ init_precmdline();
+ // ... no command line.
+
+ if ( ! dpy ) {
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQApplication: invalid Display* argument." );
+#endif // TQT_CHECK_STATE
+
+ qt_init( &aargc, aargv, GuiClient );
+ } else {
+ qt_init( dpy, visual, colormap );
+ }
+
+ initialize( aargc, aargv );
+
+ if ( qt_is_gui_used )
+ qt_maxWindowRect = desktop()->rect();
+ if ( eventloop )
+ eventloop->appStartingUp();
+}
+
+/*!
+ Create an application, given an already open display \a dpy and using
+ \a argc command line arguments in \a argv. If \a
+ visual and \a colormap are non-zero, the application will use those as
+ the default Visual and Colormap contexts.
+
+ \warning TQt only supports TrueColor visuals at depths higher than 8
+ bits-per-pixel.
+
+ This is available only on X11.
+
+*/
+TQApplication::TQApplication(Display *dpy, int argc, char **argv,
+ HANDLE visual, HANDLE colormap)
+{
+ qt_appType = GuiClient;
+ qt_is_gui_used = TRUE;
+ qt_appType = GuiClient;
+ init_precmdline();
+
+ app_argc = argc;
+ app_argv = argv;
+
+ if ( ! dpy ) {
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQApplication: invalid Display* argument." );
+#endif // TQT_CHECK_STATE
+
+ qt_init( &argc, argv, GuiClient );
+ } else {
+ qt_init(dpy, visual, colormap);
+ }
+
+ process_cmdline( &argc, argv );
+ initialize(argc, argv);
+
+ if ( qt_is_gui_used )
+ qt_maxWindowRect = desktop()->rect();
+ if ( eventloop )
+ eventloop->appStartingUp();
+}
+
+
+#endif // TQ_WS_X11
+
+
+void TQApplication::init_precmdline()
+{
+ translators = 0;
+ is_app_closing = FALSE;
+#ifndef TQT_NO_SESSIONMANAGER
+ is_session_restored = FALSE;
+#endif
+#if defined(TQT_CHECK_STATE)
+ if ( tqApp )
+ qWarning( "TQApplication: There should be max one application object" );
+#endif
+ tqApp = (TQApplication*)this;
+}
+
+/*!
+ Initializes the TQApplication object, called from the constructors.
+*/
+
+void TQApplication::initialize( int argc, char **argv )
+{
+#ifdef TQT_THREAD_SUPPORT
+ qt_mutex = new TQMutex( TRUE );
+ postevent_mutex = new TQMutex( TRUE );
+ qt_application_thread_id = TQThread::currentThread();
+#endif // TQT_THREAD_SUPPORT
+
+ app_argc = argc;
+ app_argv = argv;
+ quit_now = FALSE;
+ quit_code = 0;
+ TQWidget::createMapper(); // create widget mapper
+#ifndef TQT_NO_PALETTE
+ (void) palette(); // trigger creation of application palette
+#endif
+ is_app_running = TRUE; // no longer starting up
+
+#ifndef TQT_NO_SESSIONMANAGER
+ // connect to the session manager
+ if ( !session_key )
+ session_key = new TQString;
+ session_manager = new TQSessionManager( tqApp, session_id, *session_key );
+#endif
+
+}
+
+
+/*****************************************************************************
+ Functions returning the active popup and modal widgets.
+ *****************************************************************************/
+
+/*!
+ Returns the active popup widget.
+
+ A popup widget is a special top level widget that sets the \c
+ WType_Popup widget flag, e.g. the TQPopupMenu widget. When the
+ application opens a popup widget, all events are sent to the popup.
+ Normal widgets and modal widgets cannot be accessed before the popup
+ widget is closed.
+
+ Only other popup widgets may be opened when a popup widget is shown.
+ The popup widgets are organized in a stack. This function returns
+ the active popup widget at the top of the stack.
+
+ \sa activeModalWidget(), tqtopLevelWidgets()
+*/
+
+TQWidget *TQApplication::activePopupWidget()
+{
+ return popupWidgets ? popupWidgets->getLast() : 0;
+}
+
+
+/*!
+ Returns the active modal widget.
+
+ A modal widget is a special top level widget which is a subclass of
+ TQDialog that specifies the modal parameter of the constructor as
+ TRUE. A modal widget must be closed before the user can continue
+ with other parts of the program.
+
+ Modal widgets are organized in a stack. This function returns
+ the active modal widget at the top of the stack.
+
+ \sa activePopupWidget(), tqtopLevelWidgets()
+*/
+
+TQWidget *TQApplication::activeModalWidget()
+{
+ return qt_modal_stack ? qt_modal_stack->getFirst() : 0;
+}
+
+/*!
+ Cleans up any window system resources that were allocated by this
+ application. Sets the global variable \c tqApp to 0.
+*/
+
+TQApplication::~TQApplication()
+{
+#ifndef TQT_NO_CLIPBOARD
+ // flush clipboard contents
+ if ( qt_clipboard ) {
+ TQCustomEvent event( TQEvent::Clipboard );
+ TQApplication::sendEvent( qt_clipboard, &event );
+ }
+#endif
+
+ if ( eventloop )
+ eventloop->appClosingDown();
+ if ( postRList ) {
+ TQVFuncList::Iterator it = postRList->begin();
+ while ( it != postRList->end() ) { // call post routines
+ (**it)();
+ postRList->remove( it );
+ it = postRList->begin();
+ }
+ delete postRList;
+ postRList = 0;
+ }
+
+ TQObject *tipmanager = child( "toolTipManager", "TQTipManager", FALSE );
+ delete tipmanager;
+
+ delete qt_desktopWidget;
+ qt_desktopWidget = 0;
+ is_app_closing = TRUE;
+
+#ifndef TQT_NO_CLIPBOARD
+ delete qt_clipboard;
+ qt_clipboard = 0;
+#endif
+ TQWidget::destroyMapper();
+#ifndef TQT_NO_PALETTE
+ delete qt_std_pal;
+ qt_std_pal = 0;
+ delete app_pal;
+ app_pal = 0;
+ delete app_palettes;
+ app_palettes = 0;
+#endif
+ delete app_font;
+ app_font = 0;
+ delete app_fonts;
+ app_fonts = 0;
+#ifndef TQT_NO_STYLE
+ delete app_style;
+ app_style = 0;
+#endif
+#ifndef TQT_NO_CURSOR
+ delete app_cursor;
+ app_cursor = 0;
+#endif
+#ifndef TQT_NO_TRANSLATION
+ delete translators;
+#endif
+
+#ifndef TQT_NO_DRAGANDDROP
+ extern TQDragManager *qt_dnd_manager;
+ delete qt_dnd_manager;
+#endif
+
+ qt_cleanup();
+
+#ifndef TQT_NO_COMPONENT
+ delete app_libpaths;
+ app_libpaths = 0;
+#endif
+
+#ifdef TQT_THREAD_SUPPORT
+ delete qt_mutex;
+ qt_mutex = 0;
+ delete postevent_mutex;
+ postevent_mutex = 0;
+#endif // TQT_THREAD_SUPPORT
+
+ if( tqApp == this ) {
+ if ( postedEvents )
+ removePostedEvents( this );
+ tqApp = 0;
+ }
+ is_app_running = FALSE;
+
+ if ( widgetCount ) {
+ qDebug( "Widgets left: %i Max widgets: %i \n", TQWidget::instanceCounter, TQWidget::maxInstances );
+ }
+#ifndef TQT_NO_SESSIONMANAGER
+ delete session_manager;
+ session_manager = 0;
+ delete session_key;
+ session_key = 0;
+#endif //TQT_NO_SESSIONMANAGER
+
+ qt_explicit_app_style = FALSE;
+ qt_app_has_font = FALSE;
+ app_tracking = 0;
+ obey_desktop_settings = TRUE;
+ cursor_flash_time = 1000;
+ mouse_double_click_time = 400;
+#ifndef TQT_NO_WHEELEVENT
+ wheel_scroll_lines = 3;
+#endif
+ drag_time = 500;
+ drag_distance = 4;
+ reverse_tqlayout = FALSE;
+ app_strut = TQSize( 0, 0 );
+ animate_ui = TRUE;
+ animate_menu = FALSE;
+ fade_menu = FALSE;
+ animate_combo = FALSE;
+ animate_tooltip = FALSE;
+ fade_tooltip = FALSE;
+ widgetCount = FALSE;
+}
+
+
+/*!
+ \fn int TQApplication::argc() const
+
+ Returns the number of command line arguments.
+
+ The documentation for argv() describes how to process command line
+ arguments.
+
+ \sa argv(), TQApplication::TQApplication()
+*/
+
+/*!
+ \fn char **TQApplication::argv() const
+
+ Returns the command line argument vector.
+
+ \c argv()[0] is the program name, \c argv()[1] is the first
+ argument and \c argv()[argc()-1] is the last argument.
+
+ A TQApplication object is constructed by passing \e argc and \e
+ argv from the \c main() function. Some of the arguments may be
+ recognized as TQt options and removed from the argument vector. For
+ example, the X11 version of TQt knows about \c -display, \c -font
+ and a few more options.
+
+ Example:
+ \code
+ // showargs.cpp - displays program arguments in a list box
+
+ #include <tqapplication.h>
+ #include <tqlistbox.h>
+
+ int main( int argc, char **argv )
+ {
+ TQApplication a( argc, argv );
+ TQListBox b;
+ a.setMainWidget( &b );
+ for ( int i = 0; i < a.argc(); i++ ) // a.argc() == argc
+ b.insertItem( a.argv()[i] ); // a.argv()[i] == argv[i]
+ b.show();
+ return a.exec();
+ }
+ \endcode
+
+ If you run \c{showargs -display unix:0 -font 9x15bold hello world}
+ under X11, the list box tqcontains the three strings "showargs",
+ "hello" and "world".
+
+ TQt provides a global pointer, \c tqApp, that points to the
+ TQApplication object, and through which you can access argc() and
+ argv() in functions other than main().
+
+ \sa argc(), TQApplication::TQApplication()
+*/
+
+/*!
+ \fn void TQApplication::setArgs( int argc, char **argv )
+ \internal
+*/
+
+
+#ifndef TQT_NO_STYLE
+
+static TQString *qt_style_override = 0;
+
+/*!
+ Returns the application's style object.
+
+ \sa setStyle(), TQStyle
+*/
+TQStyle& TQApplication::tqstyle()
+{
+#ifndef TQT_NO_STYLE
+ if ( app_style )
+ return *app_style;
+ if ( !qt_is_gui_used )
+ qFatal( "No style available in non-gui applications!" );
+
+#if defined(TQ_WS_X11)
+ if(!qt_style_override)
+ x11_initialize_style(); // run-time search for default style
+#endif
+ if ( !app_style ) {
+ // Compile-time search for default style
+ //
+ TQString style;
+ if ( qt_style_override ) {
+ style = *qt_style_override;
+ delete qt_style_override;
+ qt_style_override = 0;
+ } else {
+# if defined(TQ_WS_WIN) && defined(TQ_OS_TEMP)
+ style = "PocketPC";
+#elif defined(TQ_WS_WIN)
+ if ( qWinVersion() >= TQt::WV_XP && qWinVersion() < TQt::WV_NT_based )
+ style = "WindowsXP";
+ else
+ style = "Windows"; // default styles for Windows
+#elif defined(TQ_WS_X11) && defined(TQ_OS_SOLARIS)
+ style = "CDE"; // default style for X11 on Solaris
+#elif defined(TQ_WS_X11) && defined(TQ_OS_IRIX)
+ style = "SGI"; // default style for X11 on IRIX
+#elif defined(TQ_WS_X11)
+ style = "Motif"; // default style for X11
+#elif defined(TQ_WS_MAC)
+ style = "Macintosh"; // default style for all Mac's
+#elif defined(TQ_WS_TQWS)
+ style = "Compact"; // default style for small tqdevices
+#endif
+ }
+ app_style = TQStyleFactory::create( style );
+ if ( !app_style && // platform default style not available, try alternatives
+ !(app_style = TQStyleFactory::create( "Windows" ) ) &&
+ !(app_style = TQStyleFactory::create( "Platinum" ) ) &&
+ !(app_style = TQStyleFactory::create( "MotifPlus" ) ) &&
+ !(app_style = TQStyleFactory::create( "Motif" ) ) &&
+ !(app_style = TQStyleFactory::create( "CDE" ) ) &&
+ !(app_style = TQStyleFactory::create( "Aqua" ) ) &&
+ !(app_style = TQStyleFactory::create( "SGI" ) ) &&
+ !(app_style = TQStyleFactory::create( "Compact" ) )
+#ifndef TQT_NO_STRINGLIST
+ && !(app_style = TQStyleFactory::create( TQStyleFactory::keys()[0] ) )
+#endif
+ )
+ qFatal( "No %s style available!", style.latin1() );
+ }
+
+ TQPalette app_pal_copy ( *app_pal );
+ app_style->polish( *app_pal );
+
+ if ( is_app_running && !is_app_closing && (*app_pal != app_pal_copy) ) {
+ TQEvent e( TQEvent::ApplicationPaletteChange );
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets...
+ ++it;
+ sendEvent( w, &e );
+ }
+ }
+
+ app_style->polish( tqApp );
+#endif
+ return *app_style;
+}
+
+/*!
+ Sets the application's GUI style to \a style. Ownership of the style
+ object is transferred to TQApplication, so TQApplication will delete
+ the style object on application exit or when a new style is set.
+
+ Example usage:
+ \code
+ TQApplication::setStyle( new TQWindowsStyle );
+ \endcode
+
+ When switching application styles, the color palette is set back to
+ the initial colors or the system defaults. This is necessary since
+ certain styles have to adapt the color palette to be fully
+ style-guide compliant.
+
+ \sa style(), TQStyle, setPalette(), desktopSettingsAware()
+*/
+void TQApplication::setStyle( TQStyle *style )
+{
+ TQStyle* old = app_style;
+ app_style = style;
+#ifdef TQ_WS_X11
+ qt_explicit_app_style = TRUE;
+#endif // TQ_WS_X11
+
+ if ( startingUp() ) {
+ delete old;
+ return;
+ }
+
+ // clean up the old style
+ if (old) {
+ if ( is_app_running && !is_app_closing ) {
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets...
+ ++it;
+ if ( !w->testWFlags(WType_Desktop) && // except desktop
+ w->testWState(WState_Polished) ) { // has been polished
+ old->unPolish(w);
+ }
+ }
+ }
+ old->unPolish( tqApp );
+ }
+
+ // take care of possible palette requirements of certain gui
+ // styles. Do it before polishing the application since the style
+ // might call TQApplication::setStyle() itself
+ if ( !qt_std_pal )
+ qt_create_std_palette();
+ TQPalette tmpPal = *qt_std_pal;
+ setPalette( tmpPal, TRUE );
+
+ // initialize the application with the new style
+ app_style->polish( tqApp );
+
+ // re-polish existing widgets if necessary
+ if (old) {
+ if ( is_app_running && !is_app_closing ) {
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets...
+ ++it;
+ if ( !w->testWFlags(WType_Desktop) ) { // except desktop
+ if ( w->testWState(WState_Polished) )
+ app_style->polish(w); // repolish
+ w->styleChange( *old );
+ if ( w->isVisible() ){
+ w->update();
+ }
+ }
+ }
+ }
+ delete old;
+ }
+}
+
+/*!
+ \overload
+
+ Requests a TQStyle object for \a style from the TQStyleFactory.
+
+ The string must be one of the TQStyleFactory::keys(), typically one
+ of "windows", "motif", "cde", "motifplus", "platinum", "sgi" and
+ "compact". Depending on the platform, "windowsxp", "aqua" or
+ "macintosh" may be available.
+
+ A later call to the TQApplication constructor will override the
+ requested style when a "-style" option is passed in as a commandline
+ parameter.
+
+ Returns 0 if an unknown \a style is passed, otherwise the TQStyle object
+ returned is set as the application's GUI style.
+*/
+TQStyle* TQApplication::setStyle( const TQString& style )
+{
+#ifdef TQ_WS_X11
+ qt_explicit_app_style = TRUE;
+#endif // TQ_WS_X11
+
+ if ( startingUp() ) {
+ if(qt_style_override)
+ *qt_style_override = style;
+ else
+ qt_style_override = new TQString(style);
+ return 0;
+ }
+ TQStyle *s = TQStyleFactory::create( style );
+ if ( !s )
+ return 0;
+
+ setStyle( s );
+ return s;
+}
+
+#endif
+
+
+#if 1 /* OBSOLETE */
+
+TQApplication::ColorMode TQApplication::colorMode()
+{
+ return (TQApplication::ColorMode)app_cspec;
+}
+
+void TQApplication::setColorMode( TQApplication::ColorMode mode )
+{
+ app_cspec = mode;
+}
+#endif
+
+
+/*!
+ Returns the color specification.
+ \sa TQApplication::setColorSpec()
+ */
+
+int TQApplication::colorSpec()
+{
+ return app_cspec;
+}
+
+/*!
+ Sets the color specification for the application to \a spec.
+
+ The color specification controls how the application allocates colors
+ when run on a display with a limited amount of colors, e.g. 8 bit / 256
+ color displays.
+
+ The color specification must be set before you create the TQApplication
+ object.
+
+ The options are:
+ \list
+ \i TQApplication::NormalColor.
+ This is the default color allocation strategy. Use this option if
+ your application uses buttons, menus, texts and pixmaps with few
+ colors. With this option, the application uses system global
+ colors. This works fine for most applications under X11, but on
+ Windows machines it may cause dithering of non-standard colors.
+ \i TQApplication::CustomColor.
+ Use this option if your application needs a small number of custom
+ colors. On X11, this option is the same as NormalColor. On Windows, TQt
+ creates a Windows palette, and allocates colors to it on demand.
+ \i TQApplication::ManyColor.
+ Use this option if your application is very color hungry
+ (e.g. it requires thousands of colors).
+ Under X11 the effect is:
+ \list
+ \i For 256-color displays which have at best a 256 color true color
+ visual, the default visual is used, and colors are allocated
+ from a color cube. The color cube is the 6x6x6 (216 color) "Web
+ palette"<sup>*</sup>, but the number of colors can be changed
+ by the \e -ncols option. The user can force the application to
+ use the true color visual with the \link
+ TQApplication::TQApplication() -visual \endlink option.
+ \i For 256-color displays which have a true color visual with more
+ than 256 colors, use that visual. Silicon Graphics X servers
+ have this feature, for example. They provide an 8 bit visual
+ by default but can deliver true color when asked.
+ \endlist
+ On Windows, TQt creates a Windows palette, and fills it with a color cube.
+ \endlist
+
+ Be aware that the CustomColor and ManyColor choices may lead to colormap
+ flashing: The foreground application gets (most) of the available
+ colors, while the background windows will look less attractive.
+
+ Example:
+ \code
+ int main( int argc, char **argv )
+ {
+ TQApplication::setColorSpec( TQApplication::ManyColor );
+ TQApplication a( argc, argv );
+ ...
+ }
+ \endcode
+
+ TQColor provides more functionality for controlling color allocation and
+ freeing up certain colors. See TQColor::enterAllocContext() for more
+ information.
+
+ To check what mode you end up with, call TQColor::numBitPlanes() once
+ the TQApplication object exists. A value greater than 8 (typically
+ 16, 24 or 32) means true color.
+
+ <sup>*</sup> The color cube used by TQt has 216 colors whose red,
+ green, and blue components always have one of the following values:
+ 0x00, 0x33, 0x66, 0x99, 0xCC, or 0xFF.
+
+ \sa colorSpec(), TQColor::numBitPlanes(), TQColor::enterAllocContext() */
+
+void TQApplication::setColorSpec( int spec )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( tqApp ) {
+ qWarning( "TQApplication::setColorSpec: This function must be "
+ "called before the TQApplication object is created" );
+ }
+#endif
+ app_cspec = spec;
+}
+
+/*!
+ \fn TQSize TQApplication::globalStrut()
+
+ Returns the application's global strut.
+
+ The strut is a size object whose dimensions are the minimum that any
+ GUI element that the user can interact with should have. For example
+ no button should be resized to be smaller than the global strut size.
+
+ \sa setGlobalStrut()
+*/
+
+/*!
+ Sets the application's global strut to \a strut.
+
+ The strut is a size object whose dimensions are the minimum that any
+ GUI element that the user can interact with should have. For example
+ no button should be resized to be smaller than the global strut size.
+
+ The strut size should be considered when reimplementing GUI controls
+ that may be used on touch-screens or similar IO-tqdevices.
+
+ Example:
+ \code
+ TQSize& WidgetClass::tqsizeHint() const
+ {
+ return TQSize( 80, 25 ).expandedTo( TQApplication::globalStrut() );
+ }
+ \endcode
+
+ \sa globalStrut()
+*/
+
+void TQApplication::setGlobalStrut( const TQSize& strut )
+{
+ app_strut = strut;
+}
+
+#if defined( TQ_WS_WIN ) || defined( TQ_WS_MAC )
+extern const char *tqAppFileName();
+#endif
+
+#ifndef TQT_NO_DIR
+#ifndef TQ_WS_WIN
+static TQString resolveSymlinks( const TQString& path, int depth = 0 )
+{
+ bool foundLink = FALSE;
+ TQString linkTarget;
+ TQString part = path;
+ int slashPos = path.length();
+
+ // too deep; we give up
+ if ( depth == 128 )
+ return TQString::null;
+
+ do {
+ part = part.left( slashPos );
+ TQFileInfo fileInfo( part );
+ if ( fileInfo.isSymLink() ) {
+ foundLink = TRUE;
+ linkTarget = fileInfo.readLink();
+ break;
+ }
+ } while ( (slashPos = part.tqfindRev('/')) != -1 );
+
+ if ( foundLink ) {
+ TQString path2;
+ if ( linkTarget[0] == '/' ) {
+ path2 = linkTarget;
+ if ( slashPos < (int) path.length() )
+ path2 += "/" + path.right( path.length() - slashPos - 1 );
+ } else {
+ TQString relPath;
+ relPath = part.left( part.tqfindRev('/') + 1 ) + linkTarget;
+ if ( slashPos < (int) path.length() ) {
+ if ( !linkTarget.endsWith( "/" ) )
+ relPath += "/";
+ relPath += path.right( path.length() - slashPos - 1 );
+ }
+ path2 = TQDir::current().absFilePath( relPath );
+ }
+ path2 = TQDir::cleanDirPath( path2 );
+ return resolveSymlinks( path2, depth + 1 );
+ } else {
+ return path;
+ }
+}
+#endif // TQ_WS_WIN
+
+/*!
+ Returns the directory that tqcontains the application executable.
+
+ For example, if you have installed TQt in the \c{C:\Trolltech\TQt}
+ directory, and you run the \c{demo} example, this function will
+ return "C:/Trolltech/TQt/examples/demo".
+
+ On Mac OS X this will point to the directory actually containing the
+ executable, which may be inside of an application bundle (if the
+ application is bundled).
+
+ \warning On Unix, this function assumes that argv[0] tqcontains the file
+ name of the executable (which it normally does). It also assumes that
+ the current directory hasn't been changed by the application.
+
+ \sa applicationFilePath()
+*/
+TQString TQApplication::applicationDirPath()
+{
+ return TQFileInfo( applicationFilePath() ).dirPath();
+}
+
+/*!
+ Returns the file path of the application executable.
+
+ For example, if you have installed TQt in the \c{C:\Trolltech\TQt}
+ directory, and you run the \c{demo} example, this function will
+ return "C:/Trolltech/TQt/examples/demo/demo.exe".
+
+ \warning On Unix, this function assumes that argv[0] tqcontains the file
+ name of the executable (which it normally does). It also assumes that
+ the current directory hasn't been changed by the application.
+
+ \sa applicationDirPath()
+*/
+TQString TQApplication::applicationFilePath()
+{
+#if defined( TQ_WS_WIN )
+ TQFileInfo filePath;
+ TQT_WA({
+ WCHAR module_name[256];
+ GetModuleFileNameW(0, module_name, sizeof(module_name));
+ filePath = TQString::fromUcs2((const unsigned short *)module_name);
+ }, {
+ char module_name[256];
+ GetModuleFileNameA(0, module_name, sizeof(module_name));
+ filePath = TQString::fromLocal8Bit(module_name);
+ });
+
+ return filePath.filePath();
+#elif defined( TQ_WS_MAC )
+ return TQDir::cleanDirPath( TQFile::decodeName( tqAppFileName() ) );
+#else
+ TQString argv0 = TQFile::decodeName( argv()[0] );
+ TQString absPath;
+
+ if ( argv0[0] == '/' ) {
+ /*
+ If argv0 starts with a slash, it is already an absolute
+ file path.
+ */
+ absPath = argv0;
+ } else if ( argv0.tqfind('/') != -1 ) {
+ /*
+ If argv0 tqcontains one or more slashes, it is a file path
+ relative to the current directory.
+ */
+ absPath = TQDir::current().absFilePath( argv0 );
+ } else {
+ /*
+ Otherwise, the file path has to be determined using the
+ PATH environment variable.
+ */
+ char *pEnv = getenv( "PATH" );
+ TQStringList paths( TQStringList::split(TQChar(':'), pEnv) );
+ TQStringList::const_iterator p = paths.begin();
+ while ( p != paths.end() ) {
+ TQString candidate = TQDir::current().absFilePath( *p + "/" + argv0 );
+ if ( TQFile::exists(candidate) ) {
+ absPath = candidate;
+ break;
+ }
+ ++p;
+ }
+ }
+
+ absPath = TQDir::cleanDirPath( absPath );
+ if ( TQFile::exists(absPath) ) {
+ return resolveSymlinks( absPath );
+ } else {
+ return TQString::null;
+ }
+#endif
+}
+#endif // TQT_NO_DIR
+
+#ifndef TQT_NO_COMPONENT
+
+/*!
+ Returns a list of paths that the application will search when
+ dynamically loading libraries.
+ The installation directory for plugins is the only entry if no
+ paths have been set. The default installation directory for plugins
+ is \c INSTALL/plugins, where \c INSTALL is the directory where TQt was
+ installed. The directory of the application executable (NOT the
+ working directory) is also added to the plugin paths.
+
+ If you want to iterate over the list, you should iterate over a
+ copy, e.g.
+ \code
+ TQStringList list = app.libraryPaths();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ See the \link plugins-howto.html plugins documentation\endlink for a
+ description of how the library paths are used.
+
+ \sa tqsetLibraryPaths(), addLibraryPath(), removeLibraryPath(), TQLibrary
+*/
+TQStringList TQApplication::libraryPaths()
+{
+ if ( !app_libpaths ) {
+ app_libpaths = new TQStringList;
+ TQString installPathPlugins = TQString::fromLocal8Bit(qInstallPathPlugins());
+ if ( TQFile::exists(installPathPlugins) ) {
+#ifdef TQ_WS_WIN
+ installPathPlugins.tqreplace('\\', '/');
+#endif
+ app_libpaths->append(installPathPlugins);
+ }
+
+ TQString app_location;
+ if (tqApp)
+ app_location = tqApp->applicationFilePath();
+#ifdef TQ_WS_WIN
+ else {
+ app_location = TQString(tqAppFileName());
+ app_location.tqreplace('\\', '/');
+ }
+#endif
+ if (!app_location.isEmpty()) {
+ app_location.truncate( app_location.tqfindRev( '/' ) );
+ if ( app_location != qInstallPathPlugins() && TQFile::exists( app_location ) )
+ app_libpaths->append( app_location );
+ }
+ }
+ return *app_libpaths;
+}
+
+
+/*!
+ Sets the list of directories to search when loading libraries to \a paths.
+ All existing paths will be deleted and the path list will consist of the
+ paths given in \a paths.
+
+ \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), TQLibrary
+ */
+void TQApplication::tqsetLibraryPaths( const TQStringList &paths )
+{
+ delete app_libpaths;
+ app_libpaths = new TQStringList( paths );
+}
+
+/*!
+ Append \a path to the end of the library path list. If \a path is
+ empty or already in the path list, the path list is not changed.
+
+ The default path list consists of a single entry, the installation
+ directory for plugins. The default installation directory for plugins
+ is \c INSTALL/plugins, where \c INSTALL is the directory where TQt was
+ installed.
+
+ \sa removeLibraryPath(), libraryPaths(), tqsetLibraryPaths()
+ */
+void TQApplication::addLibraryPath( const TQString &path )
+{
+ if ( path.isEmpty() )
+ return;
+
+ // make sure that library paths is initialized
+ libraryPaths();
+
+ if ( !app_libpaths->tqcontains( path ) )
+ app_libpaths->prepend( path );
+}
+
+/*!
+ Removes \a path from the library path list. If \a path is empty or not
+ in the path list, the list is not changed.
+
+ \sa addLibraryPath(), libraryPaths(), tqsetLibraryPaths()
+*/
+void TQApplication::removeLibraryPath( const TQString &path )
+{
+ if ( path.isEmpty() )
+ return;
+
+ // make sure that library paths is initialized
+ libraryPaths();
+
+ if ( app_libpaths->tqcontains( path ) )
+ app_libpaths->remove( path );
+}
+#endif //TQT_NO_COMPONENT
+
+/*!
+ Returns the application palette.
+
+ If a widget is passed in \a w, the default palette for the
+ widget's class is returned. This may or may not be the application
+ palette. In most cases there isn't a special palette for certain
+ types of widgets, but one notable exception is the popup menu under
+ Windows, if the user has defined a special background color for
+ menus in the display settings.
+
+ \sa setPalette(), TQWidget::palette()
+*/
+#ifndef TQT_NO_PALETTE
+TQPalette TQApplication::palette(const TQWidget* w)
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !tqApp )
+ qWarning( "TQApplication::palette: This function can only be "
+ "called after the TQApplication object has been created" );
+#endif
+ if ( !app_pal ) {
+ if ( !qt_std_pal )
+ qt_create_std_palette();
+ app_pal = new TQPalette( *qt_std_pal );
+ qt_fix_tooltips();
+ }
+
+ if ( w && app_palettes ) {
+ TQPalette* wp = app_palettes->tqfind( w->className() );
+ if ( wp )
+ return *wp;
+ TQAsciiDictIterator<TQPalette> it( *app_palettes );
+ const char* name;
+ while ( (name=it.currentKey()) != 0 ) {
+ if ( w->inherits( name ) )
+ return *it.current();
+ ++it;
+ }
+ }
+ return *app_pal;
+}
+
+/*!
+ Changes the default application palette to \a palette. If \a
+ informWidgets is TRUE, then existing widgets are informed about the
+ change and may adjust themselves to the new application
+ setting. If \a informWidgets is FALSE, the change only affects newly
+ created widgets.
+
+ If \a className is passed, the change applies only to widgets that
+ inherit \a className (as reported by TQObject::inherits()). If
+ \a className is left 0, the change affects all widgets, thus overriding
+ any previously set class specific palettes.
+
+ The palette may be changed according to the current GUI style in
+ TQStyle::polish().
+
+ \sa TQWidget::setPalette(), palette(), TQStyle::polish()
+*/
+
+void TQApplication::setPalette( const TQPalette &palette, bool informWidgets,
+ const char* className )
+{
+ TQPalette pal = palette;
+ TQPalette *oldpal = 0;
+#ifndef TQT_NO_STYLE
+ if ( !startingUp() ) // on startup this has been done already
+ tqApp->style().polish( pal ); // NB: non-const reference
+#endif
+ bool all = FALSE;
+ if ( !className ) {
+ if ( !app_pal ) {
+ app_pal = new TQPalette( pal );
+ TQ_CHECK_PTR( app_pal );
+ } else {
+ *app_pal = pal;
+ }
+ all = app_palettes != 0;
+ delete app_palettes;
+ app_palettes = 0;
+ qt_fix_tooltips();
+ } else {
+ if ( !app_palettes ) {
+ app_palettes = new TQAsciiDict<TQPalette>;
+ TQ_CHECK_PTR( app_palettes );
+ app_palettes->setAutoDelete( TRUE );
+ }
+ oldpal = app_palettes->tqfind( className );
+ app_palettes->insert( className, new TQPalette( pal ) );
+ }
+ if ( informWidgets && is_app_running && !is_app_closing ) {
+ if ( !oldpal || ( *oldpal != pal ) ) {
+ TQEvent e( TQEvent::ApplicationPaletteChange );
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets...
+ ++it;
+ if ( all || (!className && w->isTopLevel() ) || w->inherits(className) ) // matching class
+ sendEvent( w, &e );
+ }
+ }
+ }
+}
+
+#endif // TQT_NO_PALETTE
+
+/*!
+ Returns the default font for the widget \a w, or the default
+ application font if \a w is 0.
+
+ \sa setFont(), fontMetrics(), TQWidget::font()
+*/
+
+TQFont TQApplication::font( const TQWidget *w )
+{
+ if ( w && app_fonts ) {
+ TQFont* wf = app_fonts->tqfind( w->className() );
+ if ( wf )
+ return *wf;
+ TQAsciiDictIterator<TQFont> it( *app_fonts );
+ const char* name;
+ while ( (name=it.currentKey()) != 0 ) {
+ if ( w->inherits( name ) )
+ return *it.current();
+ ++it;
+ }
+ }
+ if ( !app_font ) {
+ app_font = new TQFont( "Helvetica" );
+ TQ_CHECK_PTR( app_font );
+ }
+ return *app_font;
+}
+
+/*! Changes the default application font to \a font. If \a
+ informWidgets is TRUE, then existing widgets are informed about the
+ change and may adjust themselves to the new application
+ setting. If \a informWidgets is FALSE, the change only affects newly
+ created widgets. If \a className is passed, the change applies only
+ to classes that inherit \a className (as reported by
+ TQObject::inherits()).
+
+ On application start-up, the default font depends on the window
+ system. It can vary depending on both the window system version and
+ the locale. This function lets you override the default font; but
+ overriding may be a bad idea because, for example, some locales need
+ extra-large fonts to support their special characters.
+
+ \sa font(), fontMetrics(), TQWidget::setFont()
+*/
+
+void TQApplication::setFont( const TQFont &font, bool informWidgets,
+ const char* className )
+{
+ bool all = FALSE;
+ if ( !className ) {
+ qt_app_has_font = TRUE;
+ if ( !app_font ) {
+ app_font = new TQFont( font );
+ TQ_CHECK_PTR( app_font );
+ } else {
+ *app_font = font;
+ }
+
+ // make sure the application font is complete
+ app_font->detach();
+ app_font->d->tqmask = TQFontPrivate::Complete;
+
+ all = app_fonts != 0;
+ delete app_fonts;
+ app_fonts = 0;
+ } else {
+ if (!app_fonts){
+ app_fonts = new TQAsciiDict<TQFont>;
+ TQ_CHECK_PTR( app_fonts );
+ app_fonts->setAutoDelete( TRUE );
+ }
+ TQFont* fnt = new TQFont(font);
+ TQ_CHECK_PTR( fnt );
+ app_fonts->insert(className, fnt);
+ }
+ if ( informWidgets && is_app_running && !is_app_closing ) {
+ TQEvent e( TQEvent::ApplicationFontChange );
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets...
+ ++it;
+ if ( all || (!className && w->isTopLevel() ) || w->inherits(className) ) // matching class
+ sendEvent( w, &e );
+ }
+ }
+}
+
+
+/*!
+ Initialization of the appearance of the widget \a w \e before it is first
+ shown.
+
+ Usually widgets call this automatically when they are polished. It
+ may be used to do some style-based central customization of widgets.
+
+ Note that you are not limited to the public functions of TQWidget.
+ Instead, based on meta information like TQObject::className() you are
+ able to customize any kind of widget.
+
+ \sa TQStyle::polish(), TQWidget::polish(), setPalette(), setFont()
+*/
+
+void TQApplication::polish( TQWidget *w )
+{
+#ifndef TQT_NO_STYLE
+ w->style().polish( w );
+#endif
+}
+
+
+/*!
+ Returns a list of the top level widgets in the application.
+
+ The list is created using \c new and must be deleted by the caller.
+
+ The list is empty (TQPtrList::isEmpty()) if there are no top level
+ widgets.
+
+ Note that some of the top level widgets may be hidden, for example
+ the tooltip if no tooltip is currently shown.
+
+ Example:
+ \code
+ // Show all hidden top level widgets.
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ TQWidgetListIt it( *list ); // iterate over the widgets
+ TQWidget * w;
+ while ( (w=it.current()) != 0 ) { // for each top level widget...
+ ++it;
+ if ( !w->isVisible() )
+ w->show();
+ }
+ delete list; // delete the list, not the widgets
+ \endcode
+
+ \warning Delete the list as soon you have finished using it.
+ The widgets in the list may be deleted by someone else at any time.
+
+ \sa allWidgets(), TQWidget::isTopLevel(), TQWidget::isVisible(),
+ TQPtrList::isEmpty()
+*/
+
+TQWidgetList *TQApplication::tqtopLevelWidgets()
+{
+ return TQWidget::tlwList();
+}
+
+/*!
+ Returns a list of all the widgets in the application.
+
+ The list is created using \c new and must be deleted by the caller.
+
+ The list is empty (TQPtrList::isEmpty()) if there are no widgets.
+
+ Note that some of the widgets may be hidden.
+
+ Example that updates all widgets:
+ \code
+ TQWidgetList *list = TQApplication::allWidgets();
+ TQWidgetListIt it( *list ); // iterate over the widgets
+ TQWidget * w;
+ while ( (w=it.current()) != 0 ) { // for each widget...
+ ++it;
+ w->update();
+ }
+ delete list; // delete the list, not the widgets
+ \endcode
+
+ The TQWidgetList class is defined in the \c tqwidgetlist.h header
+ file.
+
+ \warning Delete the list as soon as you have finished using it.
+ The widgets in the list may be deleted by someone else at any time.
+
+ \sa tqtopLevelWidgets(), TQWidget::isVisible(), TQPtrList::isEmpty(),
+*/
+
+TQWidgetList *TQApplication::allWidgets()
+{
+ return TQWidget::wList();
+}
+
+/*!
+ \fn TQWidget *TQApplication::tqfocusWidget() const
+
+ Returns the application widget that has the keyboard input focus, or
+ 0 if no widget in this application has the focus.
+
+ \sa TQWidget::setFocus(), TQWidget::hasFocus(), activeWindow()
+*/
+
+/*!
+ \fn TQWidget *TQApplication::activeWindow() const
+
+ Returns the application top-level window that has the keyboard input
+ focus, or 0 if no application window has the focus. Note that
+ there might be an activeWindow() even if there is no tqfocusWidget(),
+ for example if no widget in that window accepts key events.
+
+ \sa TQWidget::setFocus(), TQWidget::hasFocus(), tqfocusWidget()
+*/
+
+/*!
+ Returns display (screen) font metrics for the application font.
+
+ \sa font(), setFont(), TQWidget::fontMetrics(), TQPainter::fontMetrics()
+*/
+
+TQFontMetrics TQApplication::fontMetrics()
+{
+ return desktop()->fontMetrics();
+}
+
+
+
+/*!
+ Tells the application to exit with return code 0 (success).
+ Equivalent to calling TQApplication::exit( 0 ).
+
+ It's common to connect the lastWindowClosed() signal to quit(), and
+ you also often connect e.g. TQButton::clicked() or Q_SIGNALS in
+ TQAction, TQPopupMenu or TQMenuBar to it.
+
+ Example:
+ \code
+ TQPushButton *quitButton = new TQPushButton( "Quit" );
+ connect( quitButton, TQT_SIGNAL(clicked()), tqApp, TQT_SLOT(quit()) );
+ \endcode
+
+ \sa exit() aboutToQuit() lastWindowClosed() TQAction
+*/
+
+void TQApplication::quit()
+{
+ TQApplication::exit( 0 );
+}
+
+
+/*!
+ Closes all top-level windows.
+
+ This function is particularly useful for applications with many
+ top-level windows. It could, for example, be connected to a "Quit"
+ entry in the file menu as shown in the following code example:
+
+ \code
+ // the "Quit" menu entry should try to close all windows
+ TQPopupMenu* file = new TQPopupMenu( this );
+ file->insertItem( "&Quit", tqApp, TQT_SLOT(closeAllWindows()), CTRL+Key_Q );
+
+ // when the last window is closed, the application should quit
+ connect( tqApp, TQT_SIGNAL( lastWindowClosed() ), tqApp, TQT_SLOT( quit() ) );
+ \endcode
+
+ The windows are closed in random order, until one window does not
+ accept the close event.
+
+ \sa TQWidget::close(), TQWidget::closeEvent(), lastWindowClosed(),
+ quit(), tqtopLevelWidgets(), TQWidget::isTopLevel()
+
+ */
+void TQApplication::closeAllWindows()
+{
+ bool did_close = TRUE;
+ TQWidget *w;
+ while((w = activeModalWidget()) && did_close) {
+ if(w->isHidden())
+ break;
+ did_close = w->close();
+ }
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ for ( w = list->first(); did_close && w; ) {
+ if ( !w->isHidden() ) {
+ did_close = w->close();
+ delete list;
+ list = TQApplication::tqtopLevelWidgets();
+ w = list->first();
+ } else {
+ w = list->next();
+ }
+ }
+ delete list;
+}
+
+/*!
+ Displays a simple message box about TQt. The message includes the
+ version number of TQt being used by the application.
+
+ This is useful for inclusion in the Help menu of an application.
+ See the examples/menu/menu.cpp example.
+
+ This function is a convenience slot for TQMessageBox::aboutTQt().
+*/
+void TQApplication::aboutTQt()
+{
+#ifndef TQT_NO_MESSAGEBOX
+ TQMessageBox::aboutTQt( mainWidget() );
+#endif // TQT_NO_MESSAGEBOX
+}
+
+
+/*!
+ \fn void TQApplication::lastWindowClosed()
+
+ This signal is emitted when the user has closed the last
+ top level window.
+
+ The signal is very useful when your application has many top level
+ widgets but no main widget. You can then connect it to the quit()
+ slot.
+
+ For convenience, this signal is \e not emitted for transient top level
+ widgets such as popup menus and dialogs.
+
+ \sa mainWidget(), tqtopLevelWidgets(), TQWidget::isTopLevel(), TQWidget::close()
+*/
+
+/*!
+ \fn void TQApplication::aboutToQuit()
+
+ This signal is emitted when the application is about to quit the
+ main event loop, e.g. when the event loop level drops to zero.
+ This may happen either after a call to quit() from inside the
+ application or when the users shuts down the entire desktop session.
+
+ The signal is particularly useful if your application has to do some
+ last-second cleanup. Note that no user interaction is possible in
+ this state.
+
+ \sa quit()
+*/
+
+
+/*!
+ \fn void TQApplication::guiThreadAwake()
+
+ This signal is emitted after the event loop returns from a function
+ that could block.
+
+ \sa wakeUpGuiThread()
+*/
+
+
+/*!
+ \fn bool TQApplication::sendEvent( TQObject *receiver, TQEvent *event )
+
+ Sends event \a event directly to receiver \a receiver, using the
+ notify() function. Returns the value that was returned from the event
+ handler.
+
+ The event is \e not deleted when the event has been sent. The normal
+ approach is to create the event on the stack, e.g.
+ \code
+ TQMouseEvent me( TQEvent::MouseButtonPress, pos, 0, 0 );
+ TQApplication::sendEvent( mainWindow, &me );
+ \endcode
+ If you create the event on the heap you must delete it.
+
+ \sa postEvent(), notify()
+*/
+
+/*!
+ Sends event \a e to \a receiver: \a {receiver}->event(\a e).
+ Returns the value that is returned from the receiver's event handler.
+
+ For certain types of events (e.g. mouse and key events),
+ the event will be propagated to the receiver's tqparent and so on up to
+ the top-level object if the receiver is not interested in the event
+ (i.e., it returns FALSE).
+
+ There are five different ways that events can be processed;
+ reimplementing this virtual function is just one of them. All five
+ approaches are listed below:
+ \list 1
+ \i Reimplementing this function. This is very powerful, providing
+ complete control; but only one subclass can be tqApp.
+
+ \i Installing an event filter on tqApp. Such an event filter is able
+ to process all events for all widgets, so it's just as powerful as
+ reimplementing notify(); furthermore, it's possible to have more
+ than one application-global event filter. Global event filters even
+ see mouse events for \link TQWidget::isEnabled() disabled
+ widgets, \endlink and if \link setGlobalMouseTracking() global mouse
+ tracking \endlink is enabled, as well as mouse move events for all
+ widgets.
+
+ \i Reimplementing TQObject::event() (as TQWidget does). If you do
+ this you get Tab key presses, and you get to see the events before
+ any widget-specific event filters.
+
+ \i Installing an event filter on the object. Such an event filter
+ gets all the events except Tab and Shift-Tab key presses.
+
+ \i Reimplementing paintEvent(), mousePressEvent() and so
+ on. This is the commonest, easiest and least powerful way.
+ \endlist
+
+ \sa TQObject::event(), installEventFilter()
+*/
+
+bool TQApplication::notify( TQObject *receiver, TQEvent *e )
+{
+ // no events are delivered after ~TQApplication() has started
+ if ( is_app_closing )
+ return FALSE;
+
+ if ( receiver == 0 ) { // serious error
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQApplication::notify: Unexpected null receiver" );
+#endif
+ return FALSE;
+ }
+
+ if ( e->type() == TQEvent::ChildRemoved && receiver->postedEvents && globalPostedEvents) {
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( postevent_mutex );
+#endif // TQT_THREAD_SUPPORT
+
+ // the TQObject destructor calls TQObject::removeChild, which calls
+ // TQApplication::sendEvent() directly. this can happen while the event
+ // loop is in the middle of posting events, and when we get here, we may
+ // not have any more posted events for this object.
+ if ( receiver->postedEvents ) {
+ // if this is a child remove event and the child insert
+ // hasn't been dispatched yet, kill that insert
+ TQPostEventList * l = receiver->postedEvents;
+ TQObject * c = ((TQChildEvent*)e)->child();
+ TQPostEvent * pe;
+ l->first();
+ while( ( pe = l->current()) != 0 ) {
+ if ( pe->event && pe->receiver == receiver &&
+ pe->event->type() == TQEvent::ChildInserted &&
+ ((TQChildEvent*)pe->event)->child() == c ) {
+ pe->event->posted = FALSE;
+ delete pe->event;
+ pe->event = 0;
+ l->remove();
+ continue;
+ }
+ l->next();
+ }
+ }
+ }
+
+ bool res = FALSE;
+ if ( !receiver->isWidgetType() )
+ res = internalNotify( receiver, e );
+ else switch ( e->type() ) {
+#ifndef TQT_NO_ACCEL
+ case TQEvent::Accel:
+ {
+ TQKeyEvent* key = (TQKeyEvent*) e;
+ res = internalNotify( receiver, e );
+
+ if ( !res && !key->isAccepted() )
+ res = qt_dispatchAccelEvent( (TQWidget*)receiver, key );
+
+ // next lines are for compatibility with TQt <= 3.0.x: old
+ // TQAccel was listening on toplevel widgets
+ if ( !res && !key->isAccepted() && !((TQWidget*)receiver)->isTopLevel() )
+ res = internalNotify( ((TQWidget*)receiver)->tqtopLevelWidget(), e );
+ }
+ break;
+#endif //TQT_NO_ACCEL
+ case TQEvent::KeyPress:
+ case TQEvent::KeyRelease:
+ case TQEvent::AccelOverride:
+ {
+ TQWidget* w = (TQWidget*)receiver;
+ TQKeyEvent* key = (TQKeyEvent*) e;
+#ifndef TQT_NO_ACCEL
+ if ( qt_tryComposeUnicode( w, key ) )
+ break;
+#endif
+ bool def = key->isAccepted();
+ while ( w ) {
+ if ( def )
+ key->accept();
+ else
+ key->ignore();
+ res = internalNotify( w, e );
+ if ( res || key->isAccepted() )
+ break;
+ w = w->parentWidget( TRUE );
+ }
+ }
+ break;
+ case TQEvent::MouseButtonPress:
+ if ( e->spontaneous() ) {
+ TQWidget* fw = (TQWidget*)receiver;
+ while ( fw->focusProxy() )
+ fw = fw->focusProxy();
+ if ( fw->isEnabled() && fw->focusPolicy() & TQWidget::ClickFocus ) {
+ TQFocusEvent::setReason( TQFocusEvent::Mouse);
+ fw->setFocus();
+ TQFocusEvent::resetReason();
+ }
+ }
+ // fall through intended
+ case TQEvent::MouseButtonRelease:
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::MouseMove:
+ {
+ TQWidget* w = (TQWidget*)receiver;
+ TQMouseEvent* mouse = (TQMouseEvent*) e;
+ TQPoint relpos = mouse->pos();
+ while ( w ) {
+ TQMouseEvent me(mouse->type(), relpos, mouse->globalPos(), mouse->button(), mouse->state());
+ me.spont = mouse->spontaneous();
+ res = internalNotify( w, w == receiver ? mouse : &me );
+ e->spont = FALSE;
+ if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ if ( res )
+ mouse->accept();
+ else
+ mouse->ignore();
+ }
+ break;
+#ifndef TQT_NO_WHEELEVENT
+ case TQEvent::Wheel:
+ {
+ if ( e->spontaneous() ) {
+ TQWidget* fw = (TQWidget*)receiver;
+ while ( fw->focusProxy() )
+ fw = fw->focusProxy();
+ if ( fw->isEnabled() && (fw->focusPolicy() & TQWidget::WheelFocus) == TQWidget::WheelFocus ) {
+ TQFocusEvent::setReason( TQFocusEvent::Mouse);
+ fw->setFocus();
+ TQFocusEvent::resetReason();
+ }
+ }
+
+ TQWidget* w = (TQWidget*)receiver;
+ TQWheelEvent* wheel = (TQWheelEvent*) e;
+ TQPoint relpos = wheel->pos();
+ while ( w ) {
+ TQWheelEvent we(relpos, wheel->globalPos(), wheel->delta(), wheel->state(), wheel->orientation());
+ we.spont = wheel->spontaneous();
+ res = internalNotify( w, w == receiver ? wheel : &we );
+ e->spont = FALSE;
+ if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ if ( res )
+ wheel->accept();
+ else
+ wheel->ignore();
+ }
+ break;
+#endif
+ case TQEvent::ContextMenu:
+ {
+ TQWidget* w = (TQWidget*)receiver;
+ TQContextMenuEvent *context = (TQContextMenuEvent*) e;
+ TQPoint relpos = context->pos();
+ while ( w ) {
+ TQContextMenuEvent ce(context->reason(), relpos, context->globalPos(), context->state());
+ ce.spont = e->spontaneous();
+ res = internalNotify( w, w == receiver ? context : &ce );
+ e->spont = FALSE;
+
+ if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ if ( res )
+ context->accept();
+ else
+ context->ignore();
+ }
+ break;
+#if defined (TQT_TABLET_SUPPORT)
+ case TQEvent::TabletMove:
+ case TQEvent::TabletPress:
+ case TQEvent::TabletRelease:
+ {
+ TQWidget *w = (TQWidget*)receiver;
+ TQTabletEvent *tablet = (TQTabletEvent*)e;
+ TQPoint relpos = tablet->pos();
+ while ( w ) {
+ TQTabletEvent te(tablet->pos(), tablet->globalPos(), tablet->tqdevice(),
+ tablet->pressure(), tablet->xTilt(), tablet->yTilt(),
+ tablet->uniqueId());
+ te.spont = e->spontaneous();
+ res = internalNotify( w, w == receiver ? tablet : &te );
+ e->spont = FALSE;
+ if (res || w->isTopLevel() || w->testWFlags(WNoMousePropagation))
+ break;
+
+ relpos += w->pos();
+ w = w->parentWidget();
+ }
+ if ( res )
+ tablet->accept();
+ else
+ tablet->ignore();
+ chokeMouse = tablet->isAccepted();
+ }
+ break;
+#endif
+ default:
+ res = internalNotify( receiver, e );
+ break;
+ }
+
+ return res;
+}
+
+/*!\reimp
+
+*/
+bool TQApplication::event( TQEvent *e )
+{
+ if(e->type() == TQEvent::Close) {
+ TQCloseEvent *ce = (TQCloseEvent*)e;
+ ce->accept();
+ closeAllWindows();
+
+ TQWidgetList *list = tqtopLevelWidgets();
+ for(TQWidget *w = list->first(); w; w = list->next()) {
+ if ( !w->isHidden() && !w->isDesktop() && !w->isPopup() &&
+ (!w->isDialog() || !w->parentWidget())) {
+ ce->ignore();
+ break;
+ }
+ }
+ if(ce->isAccepted())
+ return TRUE;
+ } else if (e->type() == TQEvent::Quit) {
+ quit();
+ return TRUE;
+ }
+ return TQObject::event(e);
+}
+
+/*!\internal
+
+ Helper function called by notify()
+ */
+bool TQApplication::internalNotify( TQObject *receiver, TQEvent * e)
+{
+ if ( eventFilters ) {
+ TQObjectListIt it( *eventFilters );
+ register TQObject *obj;
+ while ( (obj=it.current()) != 0 ) { // send to all filters
+ ++it; // until one returns TRUE
+ if ( obj->eventFilter(receiver,e) )
+ return TRUE;
+ }
+ }
+
+ bool consumed = FALSE;
+ bool handled = FALSE;
+ if ( receiver->isWidgetType() ) {
+ TQWidget *widget = (TQWidget*)receiver;
+
+ // toggle HasMouse widget state on enter and leave
+ if ( e->type() == TQEvent::Enter || e->type() == TQEvent::DragEnter )
+ widget->setWState( WState_HasMouse );
+ else if ( e->type() == TQEvent::Leave || e->type() == TQEvent::DragLeave )
+ widget->clearWState( WState_HasMouse );
+
+ // throw away any mouse-tracking-only mouse events
+ if ( e->type() == TQEvent::MouseMove &&
+ (((TQMouseEvent*)e)->state()&TQMouseEvent::MouseButtonMask) == 0 &&
+ !widget->hasMouseTracking() ) {
+ handled = TRUE;
+ consumed = TRUE;
+ } else if ( !widget->isEnabled() ) { // throw away mouse events to disabled widgets
+ switch(e->type()) {
+ case TQEvent::MouseButtonPress:
+ case TQEvent::MouseButtonRelease:
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::MouseMove:
+ ( (TQMouseEvent*) e)->ignore();
+ handled = TRUE;
+ consumed = TRUE;
+ break;
+#ifndef TQT_NO_DRAGANDDROP
+ case TQEvent::DragEnter:
+ case TQEvent::DragMove:
+ ( (TQDragMoveEvent*) e)->ignore();
+ handled = TRUE;
+ break;
+
+ case TQEvent::DragLeave:
+ case TQEvent::DragResponse:
+ handled = TRUE;
+ break;
+
+ case TQEvent::Drop:
+ ( (TQDropEvent*) e)->ignore();
+ handled = TRUE;
+ break;
+#endif
+#ifndef TQT_NO_WHEELEVENT
+ case TQEvent::Wheel:
+ ( (TQWheelEvent*) e)->ignore();
+ handled = TRUE;
+ break;
+#endif
+ case TQEvent::ContextMenu:
+ ( (TQContextMenuEvent*) e)->ignore();
+ handled = TRUE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ }
+
+ if (!handled)
+ consumed = receiver->event( e );
+ e->spont = FALSE;
+ return consumed;
+}
+
+/*!
+ Returns TRUE if an application object has not been created yet;
+ otherwise returns FALSE.
+
+ \sa closingDown()
+*/
+
+bool TQApplication::startingUp()
+{
+ return !is_app_running;
+}
+
+/*!
+ Returns TRUE if the application objects are being destroyed;
+ otherwise returns FALSE.
+
+ \sa startingUp()
+*/
+
+bool TQApplication::closingDown()
+{
+ return is_app_closing;
+}
+
+
+/*!
+ Processes pending events, for 3 seconds or until there are no more
+ events to process, whichever is shorter.
+
+ You can call this function occasionally when your program is busy
+ performing a long operation (e.g. copying a file).
+
+ \sa exec(), TQTimer, TQEventLoop::processEvents()
+*/
+
+void TQApplication::processEvents()
+{
+ processEvents( 3000 );
+}
+
+/*!
+ \overload
+
+ Processes pending events for \a maxtime milliseconds or until
+ there are no more events to process, whichever is shorter.
+
+ You can call this function occasionally when you program is busy
+ doing a long operation (e.g. copying a file).
+
+ \sa exec(), TQTimer, TQEventLoop::processEvents()
+*/
+void TQApplication::processEvents( int maxtime )
+{
+ eventLoop()->processEvents( TQEventLoop::AllEvents, maxtime );
+}
+
+/*! \obsolete
+ Waits for an event to occur, processes it, then returns.
+
+ This function is useful for adapting TQt to situations where the
+ event processing must be grafted onto existing program loops.
+
+ Using this function in new applications may be an indication of design
+ problems.
+
+ \sa processEvents(), exec(), TQTimer
+*/
+
+void TQApplication::processOneEvent()
+{
+ eventLoop()->processEvents( TQEventLoop::AllEvents |
+ TQEventLoop::WaitForMore );
+}
+
+/*****************************************************************************
+ Main event loop wrappers
+ *****************************************************************************/
+
+/*!
+ Returns the application event loop. This function will return
+ zero if called during and after destroying TQApplication.
+
+ To create your own instance of TQEventLoop or TQEventLoop subclass create
+ it before you create the TQApplication object.
+
+ \sa TQEventLoop
+*/
+TQEventLoop *TQApplication::eventLoop()
+{
+ if ( !eventloop && !is_app_closing )
+ (void) new TQEventLoop( tqApp, "default event loop" );
+ return eventloop;
+}
+
+
+/*!
+ Enters the main event loop and waits until exit() is called or the
+ main widget is destroyed, and returns the value that was set to
+ exit() (which is 0 if exit() is called via quit()).
+
+ It is necessary to call this function to start event handling. The
+ main event loop receives events from the window system and
+ dispatches these to the application widgets.
+
+ Generally speaking, no user interaction can take place before
+ calling exec(). As a special case, modal widgets like TQMessageBox
+ can be used before calling exec(), because modal widgets call
+ exec() to start a local event loop.
+
+ To make your application perform idle processing, i.e. executing a
+ special function whenever there are no pending events, use a
+ TQTimer with 0 timeout. More advanced idle processing schemes can
+ be achieved using processEvents().
+
+ \sa quit(), exit(), processEvents(), setMainWidget()
+*/
+int TQApplication::exec()
+{
+ return eventLoop()->exec();
+}
+
+/*!
+ Tells the application to exit with a return code.
+
+ After this function has been called, the application leaves the main
+ event loop and returns from the call to exec(). The exec() function
+ returns \a retcode.
+
+ By convention, a \a retcode of 0 means success, and any non-zero
+ value indicates an error.
+
+ Note that unlike the C library function of the same name, this
+ function \e does return to the caller -- it is event processing that
+ stops.
+
+ \sa quit(), exec()
+*/
+void TQApplication::exit( int retcode )
+{
+ tqApp->eventLoop()->exit( retcode );
+}
+
+/*!
+ \obsolete
+
+ This function enters the main event loop (recursively). Do not call
+ it unless you really know what you are doing.
+
+ Use TQApplication::eventLoop()->enterLoop() instead.
+
+*/
+int TQApplication::enter_loop()
+{
+ return eventLoop()->enterLoop();
+}
+
+/*!
+ \obsolete
+
+ This function exits from a recursive call to the main event loop.
+ Do not call it unless you are an expert.
+
+ Use TQApplication::eventLoop()->exitLoop() instead.
+
+*/
+void TQApplication::exit_loop()
+{
+ eventLoop()->exitLoop();
+}
+
+/*!
+ \obsolete
+
+ Returns the current loop level.
+
+ Use TQApplication::eventLoop()->loopLevel() instead.
+
+*/
+int TQApplication::loopLevel() const
+{
+ return eventLoop()->loopLevel();
+}
+
+/*!
+
+ Wakes up the GUI thread.
+
+ \sa guiThreadAwake() \link threads.html Thread Support in TQt\endlink
+*/
+void TQApplication::wakeUpGuiThread()
+{
+ eventLoop()->wakeUp();
+}
+
+/*!
+ This function returns TRUE if there are pending events; otherwise
+ returns FALSE. Pending events can be either from the window system
+ or posted events using TQApplication::postEvent().
+*/
+bool TQApplication::hasPendingEvents()
+{
+ return eventLoop()->hasPendingEvents();
+}
+
+#if !defined(TQ_WS_X11)
+
+// The doc and X implementation of these functions is in qapplication_x11.cpp
+
+void TQApplication::flushX() {} // do nothing
+
+void TQApplication::syncX() {} // do nothing
+
+#endif
+
+/*!
+ \fn void TQApplication::setWinStyleHighlightColor( const TQColor & )
+ \obsolete
+
+ Sets the color used to mark selections in windows style for all widgets
+ in the application. Will tqrepaint all widgets if the color is changed.
+
+ The default color is \c darkBlue.
+ \sa winStyleHighlightColor()
+*/
+
+/*!
+ \fn const TQColor& TQApplication::winStyleHighlightColor()
+ \obsolete
+
+ Returns the color used to mark selections in windows style.
+
+ \sa setWinStyleHighlightColor()
+*/
+
+/*!
+ Returns the version of the Windows operating system that is running:
+
+ \list
+ \i TQt::WV_95 - Windows 95
+ \i TQt::WV_98 - Windows 98
+ \i TQt::WV_Me - Windows Me
+ \i TQt::WV_NT - Windows NT 4.x
+ \i TQt::WV_2000 - Windows 2000 (NT5)
+ \i TQt::WV_XP - Windows XP
+ \i TQt::WV_2003 - Windows Server 2003 family
+ \i TQt::WV_CE - Windows CE
+ \i TQt::WV_CENET - Windows CE.NET
+ \endlist
+
+ Note that this function is implemented for the Windows version
+ of TQt only.
+*/
+
+#if defined(TQ_OS_CYGWIN)
+TQt::WindowsVersion TQApplication::winVersion()
+{
+ return qt_winver;
+}
+#endif
+
+#ifndef TQT_NO_TRANSLATION
+
+bool qt_detectRTLLanguage()
+{
+ return TQApplication::tr( "TQT_LAYOUT_DIRECTION",
+ "Translate this string to the string 'LTR' in left-to-right"
+ " languages or to 'RTL' in right-to-left languages (such as Hebrew"
+ " and Arabic) to get proper widget tqlayout." ) == "RTL";
+}
+
+/*!
+ Adds the message file \a mf to the list of message files to be used
+ for translations.
+
+ Multiple message files can be installed. Translations are searched
+ for in the last installed message file, then the one from last, and
+ so on, back to the first installed message file. The search stops as
+ soon as a matching translation is found.
+
+ \sa removeTranslator() translate() TQTranslator::load()
+*/
+
+void TQApplication::installTranslator( TQTranslator * mf )
+{
+ if ( !mf )
+ return;
+ if ( !translators )
+ translators = new TQValueList<TQTranslator*>;
+
+ translators->prepend( mf );
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ if ( mf->isEmpty() )
+ return;
+#endif
+
+ // hook to set the tqlayout direction of dialogs
+ setReverseLayout( qt_detectRTLLanguage() );
+
+ TQWidgetList *list = tqtopLevelWidgets();
+ TQWidgetListIt it( *list );
+ TQWidget *w;
+ while ( ( w=it.current() ) != 0 ) {
+ ++it;
+ if (!w->isDesktop())
+ postEvent( w, new TQEvent( TQEvent::LanguageChange ) );
+ }
+ delete list;
+}
+
+/*!
+ Removes the message file \a mf from the list of message files used by
+ this application. (It does not delete the message file from the file
+ system.)
+
+ \sa installTranslator() translate(), TQObject::tr()
+*/
+
+void TQApplication::removeTranslator( TQTranslator * mf )
+{
+ if ( !translators || !mf )
+ return;
+
+ if ( translators->remove( mf ) && ! tqApp->closingDown() ) {
+ setReverseLayout( qt_detectRTLLanguage() );
+
+ TQWidgetList *list = tqtopLevelWidgets();
+ TQWidgetListIt it( *list );
+ TQWidget *w;
+ while ( ( w=it.current() ) != 0 ) {
+ ++it;
+ postEvent( w, new TQEvent( TQEvent::LanguageChange ) );
+ }
+ delete list;
+ }
+}
+
+#ifndef TQT_NO_TEXTCODEC
+/*! \obsolete
+ This is the same as TQTextCodec::setCodecForTr().
+*/
+void TQApplication::setDefaultCodec( TQTextCodec* codec )
+{
+ TQTextCodec::setCodecForTr( codec );
+}
+
+/*! \obsolete
+ Returns TQTextCodec::codecForTr().
+*/
+TQTextCodec* TQApplication::defaultCodec() const
+{
+ return TQTextCodec::codecForTr();
+}
+#endif //TQT_NO_TEXTCODEC
+
+/*! \enum TQApplication::Encoding
+
+ This enum type defines the 8-bit encoding of character string
+ arguments to translate():
+
+ \value DefaultCodec - the encoding specified by
+ TQTextCodec::codecForTr() (Latin-1 if none has been set)
+ \value UnicodeUTF8 - UTF-8
+
+ \sa TQObject::tr(), TQObject::trUtf8(), TQString::fromUtf8()
+*/
+
+/*! \reentrant
+ Returns the translation text for \a sourceText, by querying the
+ installed messages files. The message files are searched from the most
+ recently installed message file back to the first installed message
+ file.
+
+ TQObject::tr() and TQObject::trUtf8() provide this functionality more
+ conveniently.
+
+ \a context is typically a class name (e.g., "MyDialog") and
+ \a sourceText is either English text or a short identifying text, if
+ the output text will be very long (as for help texts).
+
+ \a comment is a disambiguating comment, for when the same \a
+ sourceText is used in different roles within the same context. By
+ default, it is null. \a encoding indicates the 8-bit encoding of
+ character stings
+
+ See the \l TQTranslator documentation for more information about
+ contexts and comments.
+
+ If none of the message files contain a translation for \a
+ sourceText in \a context, this function returns a TQString
+ equivalent of \a sourceText. The encoding of \a sourceText is
+ specified by \e encoding; it defaults to \c DefaultCodec.
+
+ This function is not virtual. You can use alternative translation
+ techniques by subclassing \l TQTranslator.
+
+ \warning This method is reentrant only if all translators are
+ installed \e before calling this method. Installing or removing
+ translators while performing translations is not supported. Doing
+ so will most likely result in crashes or other undesirable behavior.
+
+ \sa TQObject::tr() installTranslator() defaultCodec()
+*/
+
+TQString TQApplication::translate( const char * context, const char * sourceText,
+ const char * comment, Encoding encoding ) const
+{
+ if ( !sourceText )
+ return TQString::null;
+
+ if ( translators ) {
+ TQValueList<TQTranslator*>::iterator it;
+ TQTranslator * mf;
+ TQString result;
+ for ( it = translators->begin(); it != translators->end(); ++it ) {
+ mf = *it;
+ result = mf->tqfindMessage( context, sourceText, comment ).translation();
+ if ( !result.isNull() )
+ return result;
+ }
+ }
+#ifndef TQT_NO_TEXTCODEC
+ if ( encoding == UnicodeUTF8 )
+ return TQString::fromUtf8( sourceText );
+ else if ( TQTextCodec::codecForTr() != 0 )
+ return TQTextCodec::codecForTr()->toUnicode( sourceText );
+ else
+#endif
+ return TQString::tqfromLatin1( sourceText );
+}
+
+#endif
+
+/*****************************************************************************
+ TQApplication management of posted events
+ *****************************************************************************/
+
+//see also notify(), which does the removal of ChildInserted when ChildRemoved.
+
+/*!
+ Adds the event \a event with the object \a receiver as the receiver of the
+ event, to an event queue and returns immediately.
+
+ The event must be allocated on the heap since the post event queue
+ will take ownership of the event and delete it once it has been posted.
+
+ When control returns to the main event loop, all events that are
+ stored in the queue will be sent using the notify() function.
+
+ \threadsafe
+
+ \sa sendEvent(), notify()
+*/
+
+void TQApplication::postEvent( TQObject *receiver, TQEvent *event )
+{
+ if ( receiver == 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQApplication::postEvent: Unexpected null receiver" );
+#endif
+ delete event;
+ return;
+ }
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( postevent_mutex );
+#endif // TQT_THREAD_SUPPORT
+
+ if ( !globalPostedEvents ) { // create list
+ globalPostedEvents = new TQPostEventList;
+ TQ_CHECK_PTR( globalPostedEvents );
+ globalPostedEvents->setAutoDelete( TRUE );
+ qapp_cleanup_events.set( &globalPostedEvents );
+ }
+
+ if ( !receiver->postedEvents )
+ receiver->postedEvents = new TQPostEventList;
+ TQPostEventList * l = receiver->postedEvents;
+
+ // if this is one of the compressible events, do compression
+ if ( event->type() == TQEvent::Paint ||
+ event->type() == TQEvent::LayoutHint ||
+ event->type() == TQEvent::Resize ||
+ event->type() == TQEvent::Move ||
+ event->type() == TQEvent::LanguageChange ) {
+ l->first();
+ TQPostEvent * cur = 0;
+ for ( ;; ) {
+ while ( (cur=l->current()) != 0 &&
+ ( cur->receiver != receiver ||
+ cur->event == 0 ||
+ cur->event->type() != event->type() ) )
+ l->next();
+ if ( l->current() != 0 ) {
+ if ( cur->event->type() == TQEvent::Paint ) {
+ TQPaintEvent * p = (TQPaintEvent*)(cur->event);
+ if ( p->erase != ((TQPaintEvent*)event)->erase ) {
+ l->next();
+ continue;
+ }
+ p->reg = p->reg.unite( ((TQPaintEvent *)event)->reg );
+ p->rec = p->rec.unite( ((TQPaintEvent *)event)->rec );
+ delete event;
+ return;
+ } else if ( cur->event->type() == TQEvent::LayoutHint ) {
+ delete event;
+ return;
+ } else if ( cur->event->type() == TQEvent::Resize ) {
+ ((TQResizeEvent *)(cur->event))->s = ((TQResizeEvent *)event)->s;
+ delete event;
+ return;
+ } else if ( cur->event->type() == TQEvent::Move ) {
+ ((TQMoveEvent *)(cur->event))->p = ((TQMoveEvent *)event)->p;
+ delete event;
+ return;
+ } else if ( cur->event->type() == TQEvent::LanguageChange ) {
+ delete event;
+ return;
+ }
+ }
+ break;
+ };
+ }
+
+ // if no compression could be done, just append something
+ event->posted = TRUE;
+ TQPostEvent * pe = new TQPostEvent( receiver, event );
+ l->append( pe );
+ globalPostedEvents->append( pe );
+
+ if (eventloop)
+ eventloop->wakeUp();
+}
+
+
+/*! \overload
+
+ Dispatches all posted events, i.e. empties the event queue.
+*/
+void TQApplication::sendPostedEvents()
+{
+ sendPostedEvents( 0, 0 );
+}
+
+
+
+/*!
+ Immediately dispatches all events which have been previously queued
+ with TQApplication::postEvent() and which are for the object \a receiver
+ and have the event type \a event_type.
+
+ Note that events from the window system are \e not dispatched by this
+ function, but by processEvents().
+
+ If \a receiver is null, the events of \a event_type are sent for all
+ objects. If \a event_type is 0, all the events are sent for \a receiver.
+*/
+
+void TQApplication::sendPostedEvents( TQObject *receiver, int event_type )
+{
+ // Make sure the object hierarchy is stable before processing events
+ // to avoid endless loops
+ if ( receiver == 0 && event_type == 0 )
+ sendPostedEvents( 0, TQEvent::ChildInserted );
+
+ if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) )
+ return;
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( postevent_mutex );
+#endif
+
+ bool sent = TRUE;
+ while ( sent ) {
+ sent = FALSE;
+
+ if ( !globalPostedEvents || ( receiver && !receiver->postedEvents ) )
+ return;
+
+ // if we have a receiver, use the local list. Otherwise, use the
+ // global list
+ TQPostEventList * l = receiver ? receiver->postedEvents : globalPostedEvents;
+
+ // okay. here is the tricky loop. be careful about optimizing
+ // this, it looks the way it does for good reasons.
+ TQPostEventListIt it( *l );
+ TQPostEvent *pe;
+ while ( (pe=it.current()) != 0 ) {
+ ++it;
+ if ( pe->event // hasn't been sent yet
+ && ( receiver == 0 // we send to all tqreceivers
+ || receiver == pe->receiver ) // we send to THAT receiver
+ && ( event_type == 0 // we send all types
+ || event_type == pe->event->type() ) ) { // we send THAT type
+ // first, we diddle the event so that we can deliver
+ // it, and that noone will try to touch it later.
+ pe->event->posted = FALSE;
+ TQEvent * e = pe->event;
+ TQObject * r = pe->receiver;
+ pe->event = 0;
+
+ // next, update the data structure so that we're ready
+ // for the next event.
+
+ // look for the local list, and take whatever we're
+ // delivering out of it. r->postedEvents maybe *l
+ if ( r->postedEvents ) {
+ r->postedEvents->removeRef( pe );
+ // if possible, get rid of that list. this is not
+ // ideal - we will create and delete a list for
+ // each update() call. it would be better if we'd
+ // leave the list empty here, and delete it
+ // somewhere else if it isn't being used.
+ if ( r->postedEvents->isEmpty() ) {
+ delete r->postedEvents;
+ r->postedEvents = 0;
+ }
+ }
+
+#ifdef TQT_THREAD_SUPPORT
+ if ( locker.mutex() ) locker.mutex()->unlock();
+#endif // TQT_THREAD_SUPPORT
+ // after all that work, it's time to deliver the event.
+ if ( e->type() == TQEvent::Paint && r->isWidgetType() ) {
+ TQWidget * w = (TQWidget*)r;
+ TQPaintEvent * p = (TQPaintEvent*)e;
+ if ( w->isVisible() )
+ w->tqrepaint( p->reg, p->erase );
+ } else {
+ sent = TRUE;
+ TQApplication::sendEvent( r, e );
+ }
+#ifdef TQT_THREAD_SUPPORT
+ if ( locker.mutex() ) locker.mutex()->lock();
+#endif // TQT_THREAD_SUPPORT
+
+ delete e;
+ // careful when adding anything below this point - the
+ // sendEvent() call might tqinvalidate any invariants this
+ // function depends on.
+ }
+ }
+
+ // clear the global list, i.e. remove everything that was
+ // delivered.
+ if ( l == globalPostedEvents ) {
+ globalPostedEvents->first();
+ while( (pe=globalPostedEvents->current()) != 0 ) {
+ if ( pe->event )
+ globalPostedEvents->next();
+ else
+ globalPostedEvents->remove();
+ }
+ }
+ }
+}
+
+/*!
+ Removes all events posted using postEvent() for \a receiver.
+
+ The events are \e not dispatched, instead they are removed from the
+ queue. You should never need to call this function. If you do call it,
+ be aware that killing events may cause \a receiver to break one or
+ more invariants.
+
+ \threadsafe
+*/
+
+void TQApplication::removePostedEvents( TQObject *receiver )
+{
+ if ( !receiver )
+ return;
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( postevent_mutex );
+#endif // TQT_THREAD_SUPPORT
+
+ // the TQObject destructor calls this function directly. this can
+ // happen while the event loop is in the middle of posting events,
+ // and when we get here, we may not have any more posted events
+ // for this object.
+ if ( !receiver->postedEvents )
+ return;
+
+ // iterate over the object-specifc list and delete the events.
+ // leave the TQPostEvent objects; they'll be deleted by
+ // sendPostedEvents().
+ TQPostEventList * l = receiver->postedEvents;
+ receiver->postedEvents = 0;
+ l->first();
+ TQPostEvent * pe;
+ while( (pe=l->current()) != 0 ) {
+ if ( pe->event ) {
+ pe->event->posted = FALSE;
+ delete pe->event;
+ pe->event = 0;
+ }
+ l->remove();
+ }
+ delete l;
+}
+
+
+/*!
+ Removes \a event from the queue of posted events, and emits a
+ warning message if appropriate.
+
+ \warning This function can be \e really slow. Avoid using it, if
+ possible.
+
+ \threadsafe
+*/
+
+void TQApplication::removePostedEvent( TQEvent * event )
+{
+ if ( !event || !event->posted )
+ return;
+
+ if ( !globalPostedEvents ) {
+#if defined(TQT_DEBUG)
+ qDebug( "TQApplication::removePostedEvent: %p %d is posted: impossible",
+ (void*)event, event->type() );
+ return;
+#endif
+ }
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( postevent_mutex );
+#endif // TQT_THREAD_SUPPORT
+
+ TQPostEventListIt it( *globalPostedEvents );
+ TQPostEvent * pe;
+ while( (pe = it.current()) != 0 ) {
+ ++it;
+ if ( pe->event == event ) {
+#if defined(TQT_DEBUG)
+ const char *n;
+ switch ( event->type() ) {
+ case TQEvent::Timer:
+ n = "Timer";
+ break;
+ case TQEvent::MouseButtonPress:
+ n = "MouseButtonPress";
+ break;
+ case TQEvent::MouseButtonRelease:
+ n = "MouseButtonRelease";
+ break;
+ case TQEvent::MouseButtonDblClick:
+ n = "MouseButtonDblClick";
+ break;
+ case TQEvent::MouseMove:
+ n = "MouseMove";
+ break;
+#ifndef TQT_NO_WHEELEVENT
+ case TQEvent::Wheel:
+ n = "Wheel";
+ break;
+#endif
+ case TQEvent::KeyPress:
+ n = "KeyPress";
+ break;
+ case TQEvent::KeyRelease:
+ n = "KeyRelease";
+ break;
+ case TQEvent::FocusIn:
+ n = "FocusIn";
+ break;
+ case TQEvent::FocusOut:
+ n = "FocusOut";
+ break;
+ case TQEvent::Enter:
+ n = "Enter";
+ break;
+ case TQEvent::Leave:
+ n = "Leave";
+ break;
+ case TQEvent::Paint:
+ n = "Paint";
+ break;
+ case TQEvent::Move:
+ n = "Move";
+ break;
+ case TQEvent::Resize:
+ n = "Resize";
+ break;
+ case TQEvent::Create:
+ n = "Create";
+ break;
+ case TQEvent::Destroy:
+ n = "Destroy";
+ break;
+ case TQEvent::Close:
+ n = "Close";
+ break;
+ case TQEvent::Quit:
+ n = "Quit";
+ break;
+ default:
+ n = "<other>";
+ break;
+ }
+ qWarning("TQEvent: Warning: %s event deleted while posted to %s %s",
+ n,
+ pe->receiver ? pe->receiver->className() : "null",
+ pe->receiver ? pe->receiver->name() : "object" );
+ // note the beautiful uglehack if !pe->receiver :)
+#endif
+ event->posted = FALSE;
+ delete pe->event;
+ pe->event = 0;
+ return;
+ }
+ }
+}
+
+/*!\internal
+
+ Sets the active window in reaction to a system event. Call this
+ from the platform specific event handlers.
+
+ It sets the activeWindow() and tqfocusWidget() attributes and sends
+ proper WindowActivate/WindowDeactivate and FocusIn/FocusOut events
+ to all appropriate widgets.
+
+ \sa activeWindow()
+ */
+void TQApplication::setActiveWindow( TQWidget* act )
+{
+ TQWidget* window = act?act->tqtopLevelWidget():0;
+
+ if ( active_window == window )
+ return;
+
+ // first the activation/deactivation events
+ if ( active_window ) {
+ TQWidgetList deacts;
+#ifndef TQT_NO_STYLE
+ if ( style().tqstyleHint(TQStyle::SH_Widget_ShareActivation, active_window ) ) {
+ TQWidgetList *list = tqtopLevelWidgets();
+ if ( list ) {
+ for ( TQWidget *w = list->first(); w; w = list->next() ) {
+ if ( w->isVisible() && w->isActiveWindow() )
+ deacts.append(w);
+ }
+ delete list;
+ }
+ } else
+#endif
+ deacts.append(active_window);
+ active_window = 0;
+ TQEvent e( TQEvent::WindowDeactivate );
+ for(TQWidget *w = deacts.first(); w; w = deacts.next())
+ TQApplication::sendSpontaneousEvent( w, &e );
+ }
+
+ active_window = window;
+ if ( active_window ) {
+ TQEvent e( TQEvent::WindowActivate );
+ TQWidgetList acts;
+#ifndef TQT_NO_STYLE
+ if ( style().tqstyleHint(TQStyle::SH_Widget_ShareActivation, active_window ) ) {
+ TQWidgetList *list = tqtopLevelWidgets();
+ if ( list ) {
+ for ( TQWidget *w = list->first(); w; w = list->next() ) {
+ if ( w->isVisible() && w->isActiveWindow() )
+ acts.append(w);
+ }
+ delete list;
+ }
+ } else
+#endif
+ acts.append(active_window);
+ for(TQWidget *w = acts.first(); w; w = acts.next())
+ TQApplication::sendSpontaneousEvent( w, &e );
+ }
+
+ // then focus events
+ TQFocusEvent::setReason( TQFocusEvent::ActiveWindow );
+ if ( !active_window && focus_widget ) {
+ TQFocusEvent out( TQEvent::FocusOut );
+ TQWidget *tmp = focus_widget;
+ focus_widget = 0;
+#ifdef TQ_WS_WIN
+ TQInputContext::accept( tmp );
+#endif
+ TQApplication::sendSpontaneousEvent( tmp, &out );
+ } else if ( active_window ) {
+ TQWidget *w = active_window->tqfocusWidget();
+ if ( w && w->focusPolicy() != TQWidget::NoFocus )
+ w->setFocus();
+ else
+ active_window->focusNextPrevChild( TRUE );
+ }
+ TQFocusEvent::resetReason();
+}
+
+
+/*!\internal
+
+ Creates the proper Enter/Leave event when widget \a enter is entered
+ and widget \a leave is left.
+ */
+TQ_EXPORT void qt_dispatchEnterLeave( TQWidget* enter, TQWidget* leave ) {
+#if 0
+ if ( leave ) {
+ TQEvent e( TQEvent::Leave );
+ TQApplication::sendEvent( leave, & e );
+ }
+ if ( enter ) {
+ TQEvent e( TQEvent::Enter );
+ TQApplication::sendEvent( enter, & e );
+ }
+ return;
+#endif
+
+ TQWidget* w ;
+ if ( !enter && !leave )
+ return;
+ TQWidgetList leaveList;
+ TQWidgetList enterList;
+
+ bool sameWindow = leave && enter && leave->tqtopLevelWidget() == enter->tqtopLevelWidget();
+ if ( leave && !sameWindow ) {
+ w = leave;
+ do {
+ leaveList.append( w );
+ } while ( (w = w->parentWidget( TRUE ) ) );
+ }
+ if ( enter && !sameWindow ) {
+ w = enter;
+ do {
+ enterList.prepend( w );
+ } while ( (w = w->parentWidget(TRUE) ) );
+ }
+ if ( sameWindow ) {
+ int enterDepth = 0;
+ int leaveDepth = 0;
+ w = enter;
+ while ( ( w = w->parentWidget( TRUE ) ) )
+ enterDepth++;
+ w = leave;
+ while ( ( w = w->parentWidget( TRUE ) ) )
+ leaveDepth++;
+ TQWidget* wenter = enter;
+ TQWidget* wleave = leave;
+ while ( enterDepth > leaveDepth ) {
+ wenter = wenter->parentWidget();
+ enterDepth--;
+ }
+ while ( leaveDepth > enterDepth ) {
+ wleave = wleave->parentWidget();
+ leaveDepth--;
+ }
+ while ( !wenter->isTopLevel() && wenter != wleave ) {
+ wenter = wenter->parentWidget();
+ wleave = wleave->parentWidget();
+ }
+
+ w = leave;
+ while ( w != wleave ) {
+ leaveList.append( w );
+ w = w->parentWidget();
+ }
+ w = enter;
+ while ( w != wenter ) {
+ enterList.prepend( w );
+ w = w->parentWidget();
+ }
+ }
+
+ TQEvent leaveEvent( TQEvent::Leave );
+ for ( w = leaveList.first(); w; w = leaveList.next() ) {
+ if ( !tqApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
+ TQApplication::sendEvent( w, &leaveEvent );
+ }
+ TQEvent enterEvent( TQEvent::Enter );
+ for ( w = enterList.first(); w; w = enterList.next() ) {
+ if ( !tqApp->activeModalWidget() || qt_tryModalHelper( w, 0 ))
+ TQApplication::sendEvent( w, &enterEvent );
+ }
+}
+
+
+#ifdef TQ_WS_MACX
+extern TQWidget *qt_tryModalHelperMac( TQWidget * top ); //qapplication_mac.cpp
+#endif
+
+
+/*!\internal
+
+ Called from qapplication_<platform>.cpp, returns TRUE
+ if the widget should accept the event.
+ */
+TQ_EXPORT bool qt_tryModalHelper( TQWidget *widget, TQWidget **rettop ) {
+ TQWidget *modal=0, *top=TQApplication::activeModalWidget();
+ if ( rettop ) *rettop = top;
+
+ if ( tqApp->activePopupWidget() )
+ return TRUE;
+
+#ifdef TQ_WS_MACX
+ top = qt_tryModalHelperMac( top );
+ if ( rettop ) *rettop = top;
+#endif
+
+ TQWidget* groupLeader = widget;
+ widget = widget->tqtopLevelWidget();
+
+ if ( widget->testWFlags(TQt::WShowModal) ) // widget is modal
+ modal = widget;
+ if ( !top || modal == top ) // don't block event
+ return TRUE;
+
+ TQWidget * p = widget->parentWidget(); // Check if the active modal widget is a tqparent of our widget
+ while ( p ) {
+ if ( p == top )
+ return TRUE;
+ p = p->parentWidget();
+ }
+
+ while ( groupLeader && !groupLeader->testWFlags( TQt::WGroupLeader ) )
+ groupLeader = groupLeader->parentWidget();
+
+ if ( groupLeader ) {
+ // Does groupLeader have a child in qt_modal_stack?
+ bool unrelated = TRUE;
+ modal = qt_modal_stack->first();
+ while (modal && unrelated) {
+ TQWidget* p = modal->parentWidget();
+ while ( p && p != groupLeader && !p->testWFlags( TQt::WGroupLeader) ) {
+ p = p->parentWidget();
+ }
+ modal = qt_modal_stack->next();
+ if ( p == groupLeader ) unrelated = FALSE;
+ }
+
+ if ( unrelated )
+ return TRUE; // don't block event
+ }
+ return FALSE;
+}
+
+
+/*!
+ Returns the desktop widget (also called the root window).
+
+ The desktop widget is useful for obtaining the size of the screen.
+ It may also be possible to draw on the desktop. We recommend against
+ assuming that it's possible to draw on the desktop, since this does
+ not work on all operating systems.
+
+ \code
+ TQDesktopWidget *d = TQApplication::desktop();
+ int w = d->width(); // returns desktop width
+ int h = d->height(); // returns desktop height
+ \endcode
+*/
+
+TQDesktopWidget *TQApplication::desktop()
+{
+ if ( !qt_desktopWidget || // not created yet
+ !qt_desktopWidget->isDesktop() ) { // reparented away
+ qt_desktopWidget = new TQDesktopWidget();
+ TQ_CHECK_PTR( qt_desktopWidget );
+ }
+ return qt_desktopWidget;
+}
+
+#ifndef TQT_NO_CLIPBOARD
+/*!
+ Returns a pointer to the application global clipboard.
+*/
+TQClipboard *TQApplication::clipboard()
+{
+ if ( qt_clipboard == 0 ) {
+ qt_clipboard = new TQClipboard;
+ TQ_CHECK_PTR( qt_clipboard );
+ }
+ return qt_clipboard;
+}
+#endif // TQT_NO_CLIPBOARD
+
+/*!
+ By default, TQt will try to use the current standard colors, fonts
+ etc., from the underlying window system's desktop settings,
+ and use them for all relevant widgets. This behavior can be switched off
+ by calling this function with \a on set to FALSE.
+
+ This static function must be called before creating the TQApplication
+ object, like this:
+
+ \code
+ int main( int argc, char** argv ) {
+ TQApplication::setDesktopSettingsAware( FALSE ); // I know better than the user
+ TQApplication myApp( argc, argv ); // Use default fonts & colors
+ ...
+ }
+ \endcode
+
+ \sa desktopSettingsAware()
+*/
+
+void TQApplication::setDesktopSettingsAware( bool on )
+{
+ obey_desktop_settings = on;
+}
+
+/*!
+ Returns the value set by setDesktopSettingsAware(); by default TRUE.
+
+ \sa setDesktopSettingsAware()
+*/
+
+bool TQApplication::desktopSettingsAware()
+{
+ return obey_desktop_settings;
+}
+
+/*! \fn void TQApplication::lock()
+
+ Lock the TQt Library Mutex. If another thread has already locked the
+ mutex, the calling thread will block until the other thread has
+ unlocked the mutex.
+
+ \sa unlock() locked() \link threads.html Thread Support in TQt\endlink
+*/
+
+
+/*! \fn void TQApplication::unlock(bool wakeUpGui)
+
+ Unlock the TQt Library Mutex. If \a wakeUpGui is TRUE (the default),
+ then the GUI thread will be woken with TQApplication::wakeUpGuiThread().
+
+ \sa lock(), locked() \link threads.html Thread Support in TQt\endlink
+*/
+
+
+/*! \fn bool TQApplication::locked()
+
+ Returns TRUE if the TQt Library Mutex is locked by a different thread;
+ otherwise returns FALSE.
+
+ \warning Due to different implementations of recursive mutexes on
+ the supported platforms, calling this function from the same thread
+ that previously locked the mutex will give undefined results.
+
+ \sa lock() unlock() \link threads.html Thread Support in TQt\endlink
+*/
+
+/*! \fn bool TQApplication::tryLock()
+
+ Attempts to lock the TQt Library Mutex, and returns immediately. If
+ the lock was obtained, this function returns TRUE. If another thread
+ has locked the mutex, this function returns FALSE, instead of
+ waiting for the lock to become available.
+
+ The mutex must be unlocked with unlock() before another thread can
+ successfully lock it.
+
+ \sa lock(), unlock() \link threads.html Thread Support in TQt\endlink
+*/
+
+#if defined(TQT_THREAD_SUPPORT)
+void TQApplication::lock()
+{
+ qt_mutex->lock();
+}
+
+void TQApplication::unlock(bool wakeUpGui)
+{
+ qt_mutex->unlock();
+
+ if (wakeUpGui)
+ wakeUpGuiThread();
+}
+
+bool TQApplication::locked()
+{
+ return qt_mutex->locked();
+}
+
+bool TQApplication::tryLock()
+{
+ return qt_mutex->tryLock();
+}
+#endif
+
+
+/*!
+ \fn bool TQApplication::isSessionRestored() const
+
+ Returns TRUE if the application has been restored from an earlier
+ \link session.html session\endlink; otherwise returns FALSE.
+
+ \sa sessionId(), commitData(), saveState()
+*/
+
+
+/*!
+ \fn TQString TQApplication::sessionId() const
+
+ Returns the current \link session.html session's\endlink identifier.
+
+ If the application has been restored from an earlier session, this
+ identifier is the same as it was in that previous session.
+
+ The session identifier is guaranteed to be unique both for different
+ applications and for different instances of the same application.
+
+ \sa isSessionRestored(), sessionKey(), commitData(), saveState()
+ */
+
+/*!
+ \fn TQString TQApplication::sessionKey() const
+
+ Returns the session key in the current \link session.html
+ session\endlink.
+
+ If the application has been restored from an earlier session, this
+ key is the same as it was when the previous session ended.
+
+ The session key changes with every call of commitData() or
+ saveState().
+
+ \sa isSessionRestored(), sessionId(), commitData(), saveState()
+ */
+
+
+/*!
+ \fn void TQApplication::commitData( TQSessionManager& sm )
+
+ This function deals with \link session.html session
+ management\endlink. It is invoked when the TQSessionManager wants the
+ application to commit all its data.
+
+ Usually this means saving all open files, after getting
+ permission from the user. Furthermore you may want to provide a means
+ by which the user can cancel the shutdown.
+
+ Note that you should not exit the application within this function.
+ Instead, the session manager may or may not do this afterwards,
+ depending on the context.
+
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the session manager \a sm for explicit permission.
+ See TQSessionManager::allowsInteraction() and
+ TQSessionManager::allowsErrorInteraction() for details and example
+ usage.
+
+ The default implementation requests interaction and sends a close
+ event to all visible top level widgets. If any event was
+ rejected, the shutdown is canceled.
+
+ \sa isSessionRestored(), sessionId(), saveState(), \link session.html the Session Management overview\endlink
+*/
+#ifndef TQT_NO_SESSIONMANAGER
+void TQApplication::commitData( TQSessionManager& sm )
+{
+
+ if ( sm.allowsInteraction() ) {
+ TQWidgetList done;
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ bool cancelled = FALSE;
+ TQWidget* w = list->first();
+ while ( !cancelled && w ) {
+ if ( !w->isHidden() ) {
+ TQCloseEvent e;
+ sendEvent( w, &e );
+ cancelled = !e.isAccepted();
+ if ( !cancelled )
+ done.append( w );
+ delete list; // one never knows...
+ list = TQApplication::tqtopLevelWidgets();
+ w = list->first();
+ } else {
+ w = list->next();
+ }
+ while ( w && done.tqcontainsRef( w ) )
+ w = list->next();
+ }
+ delete list;
+ if ( cancelled )
+ sm.cancel();
+ }
+}
+
+
+/*!
+ \fn void TQApplication::saveState( TQSessionManager& sm )
+
+ This function deals with \link session.html session
+ management\endlink. It is invoked when the
+ \link TQSessionManager session manager \endlink wants the application
+ to preserve its state for a future session.
+
+ For example, a text editor would create a temporary file that
+ includes the current contents of its edit buffers, the location of
+ the cursor and other aspects of the current editing session.
+
+ Note that you should never exit the application within this
+ function. Instead, the session manager may or may not do this
+ afterwards, depending on the context. Futhermore, most session
+ managers will very likely request a saved state immediately after
+ the application has been started. This permits the session manager
+ to learn about the application's restart policy.
+
+ \warning Within this function, no user interaction is possible, \e
+ unless you ask the session manager \a sm for explicit permission.
+ See TQSessionManager::allowsInteraction() and
+ TQSessionManager::allowsErrorInteraction() for details.
+
+ \sa isSessionRestored(), sessionId(), commitData(), \link session.html the Session Management overview\endlink
+*/
+
+void TQApplication::saveState( TQSessionManager& /* sm */ )
+{
+}
+#endif //TQT_NO_SESSIONMANAGER
+/*!
+ Sets the time after which a drag should start to \a ms ms.
+
+ \sa startDragTime()
+*/
+
+void TQApplication::setStartDragTime( int ms )
+{
+ drag_time = ms;
+}
+
+/*!
+ If you support drag and drop in you application and a drag should
+ start after a mouse click and after a certain time elapsed, you
+ should use the value which this method returns as the delay (in ms).
+
+ TQt also uses this delay internally, e.g. in TQTextEdit and TQLineEdit,
+ for starting a drag.
+
+ The default value is 500 ms.
+
+ \sa setStartDragTime(), startDragDistance()
+*/
+
+int TQApplication::startDragTime()
+{
+ return drag_time;
+}
+
+/*!
+ Sets the distance after which a drag should start to \a l pixels.
+
+ \sa startDragDistance()
+*/
+
+void TQApplication::setStartDragDistance( int l )
+{
+ drag_distance = l;
+}
+
+/*!
+ If you support drag and drop in you application and a drag should
+ start after a mouse click and after moving the mouse a certain
+ distance, you should use the value which this method returns as the
+ distance.
+
+ For example, if the mouse position of the click is stored in \c
+ startPos and the current position (e.g. in the mouse move event) is
+ \c currPos, you can tqfind out if a drag should be started with code
+ like this:
+ \code
+ if ( ( startPos - currPos ).manhattanLength() >
+ TQApplication::startDragDistance() )
+ startTheDrag();
+ \endcode
+
+ TQt uses this value internally, e.g. in TQFileDialog.
+
+ The default value is 4 pixels.
+
+ \sa setStartDragDistance(), startDragTime(), TQPoint::manhattanLength()
+*/
+
+int TQApplication::startDragDistance()
+{
+ return drag_distance;
+}
+
+/*!
+ If \a b is TRUE, all dialogs and widgets will be laid out in a
+ mirrored fashion, as required by right to left languages such as
+ Arabic and Hebrew. If \a b is FALSE, dialogs and widgets are laid
+ out left to right.
+
+ Changing this flag in runtime does not cause a retqlayout of already
+ instantiated widgets.
+
+ \sa reverseLayout()
+*/
+void TQApplication::setReverseLayout( bool b )
+{
+ if ( reverse_tqlayout == b )
+ return;
+
+ reverse_tqlayout = b;
+
+ TQWidgetList *list = tqtopLevelWidgets();
+ TQWidgetListIt it( *list );
+ TQWidget *w;
+ while ( ( w=it.current() ) != 0 ) {
+ ++it;
+ postEvent( w, new TQEvent( TQEvent::LayoutDirectionChange ) );
+ }
+ delete list;
+}
+
+/*!
+ Returns TRUE if all dialogs and widgets will be laid out in a
+ mirrored (right to left) fashion. Returns FALSE if dialogs and
+ widgets will be laid out left to right.
+
+ \sa setReverseLayout()
+*/
+bool TQApplication::reverseLayout()
+{
+ return reverse_tqlayout;
+}
+
+
+/*!
+ \class TQSessionManager tqsessionmanager.h
+ \brief The TQSessionManager class provides access to the session manager.
+
+ \ingroup application
+ \ingroup environment
+
+ The session manager is responsible for session management, most
+ importantly for interruption and resumption. A "session" is a kind
+ of record of the state of the system, e.g. which applications were
+ run at start up and which applications are currently running. The
+ session manager is used to save the session, e.g. when the machine
+ is shut down; and to restore a session, e.g. when the machine is
+ started up. Use TQSettings to save and restore an individual
+ application's settings, e.g. window positions, recently used files,
+ etc.
+
+ TQSessionManager provides an interface between the application and
+ the session manager so that the program can work well with the
+ session manager. In TQt, session management requests for action
+ are handled by the two virtual functions TQApplication::commitData()
+ and TQApplication::saveState(). Both provide a reference to
+ a session manager object as argument, to allow the application
+ to communicate with the session manager.
+
+ During a session management action (i.e. within commitData() and
+ saveState()), no user interaction is possible \e unless the
+ application got explicit permission from the session manager. You
+ ask for permission by calling allowsInteraction() or, if it's really
+ urgent, allowsErrorInteraction(). TQt does not enforce this, but the
+ session manager may.
+
+ You can try to abort the shutdown process by calling cancel(). The
+ default commitData() function does this if some top-level window
+ rejected its closeEvent().
+
+ For sophisticated session managers provided on Unix/X11, TQSessionManager
+ offers further possibilites to fine-tune an application's session
+ management behavior: setRestartCommand(), setDiscardCommand(),
+ setRestartHint(), setProperty(), requestPhase2(). See the respective
+ function descriptions for further details.
+*/
+
+/*! \enum TQSessionManager::RestartHint
+
+ This enum type defines the circumstances under which this
+ application wants to be restarted by the session manager. The
+ current values are
+
+ \value RestartIfRunning if the application is still running when
+ the session is shut down, it wants to be restarted at the start of
+ the next session.
+
+ \value RestartAnyway the application wants to be started at the
+ start of the next session, no matter what. (This is useful for
+ utilities that run just after startup and then quit.)
+
+ \value RestartImmediately the application wants to be started
+ immediately whenever it is not running.
+
+ \value RestartNever the application does not want to be restarted
+ automatically.
+
+ The default hint is \c RestartIfRunning.
+*/
+
+
+/*!
+ \fn TQString TQSessionManager::sessionId() const
+
+ Returns the identifier of the current session.
+
+ If the application has been restored from an earlier session, this
+ identifier is the same as it was in that earlier session.
+
+ \sa sessionKey(), TQApplication::sessionId()
+ */
+
+/*!
+ \fn TQString TQSessionManager::sessionKey() const
+
+ Returns the session key in the current session.
+
+ If the application has been restored from an earlier session, this
+ key is the same as it was when the previous session ended.
+
+ The session key changes with every call of commitData() or
+ saveState().
+
+ \sa sessionId(), TQApplication::sessionKey()
+ */
+
+// ### Note: This function is undocumented, since it is #ifdef'd.
+
+/*!
+ \fn void* TQSessionManager::handle() const
+
+ X11 only: returns a handle to the current \c SmcConnection.
+*/
+
+
+/*!
+ \fn bool TQSessionManager::allowsInteraction()
+
+ Asks the session manager for permission to interact with the
+ user. Returns TRUE if interaction is permitted; otherwise
+ returns FALSE.
+
+ The rationale behind this mechanism is to make it possible to
+ synchronize user interaction during a shutdown. Advanced session
+ managers may ask all applications simultaneously to commit their
+ data, resulting in a much faster shutdown.
+
+ When the interaction is completed we strongly recommend releasing the
+ user interaction semaphore with a call to release(). This way, other
+ applications may get the chance to interact with the user while your
+ application is still busy saving data. (The semaphore is implicitly
+ released when the application exits.)
+
+ If the user decides to cancel the shutdown process during the
+ interaction phase, you must tell the session manager that this has
+ happened by calling cancel().
+
+ Here's an example of how an application's TQApplication::commitData()
+ might be implemented:
+
+\code
+void MyApplication::commitData( TQSessionManager& sm ) {
+ if ( sm.allowsInteraction() ) {
+ switch ( TQMessageBox::warning(
+ yourMainWindow,
+ tr("Application Name"),
+ tr("Save changes to document Foo?"),
+ tr("&Yes"),
+ tr("&No"),
+ tr("Cancel"),
+ 0, 2) ) {
+ case 0: // yes
+ sm.release();
+ // save document here; if saving fails, call sm.cancel()
+ break;
+ case 1: // continue without saving
+ break;
+ default: // cancel
+ sm.cancel();
+ break;
+ }
+ } else {
+ // we did not get permission to interact, then
+ // do something reasonable instead.
+ }
+}
+\endcode
+
+ If an error occurred within the application while saving its data,
+ you may want to try allowsErrorInteraction() instead.
+
+ \sa TQApplication::commitData(), release(), cancel()
+*/
+
+
+/*!
+ \fn bool TQSessionManager::allowsErrorInteraction()
+
+ This is similar to allowsInteraction(), but also tells the session
+ manager that an error occurred. Session managers may give error
+ interaction request higher priority, which means that it is more likely
+ that an error interaction is permitted. However, you are still not
+ guaranteed that the session manager will allow interaction.
+
+ \sa allowsInteraction(), release(), cancel()
+*/
+
+/*!
+ \fn void TQSessionManager::release()
+
+ Releases the session manager's interaction semaphore after an
+ interaction phase.
+
+ \sa allowsInteraction(), allowsErrorInteraction()
+*/
+
+/*!
+ \fn void TQSessionManager::cancel()
+
+ Tells the session manager to cancel the shutdown process. Applications
+ should not call this function without first asking the user.
+
+ \sa allowsInteraction(), allowsErrorInteraction()
+
+*/
+
+/*!
+ \fn void TQSessionManager::setRestartHint( RestartHint hint )
+
+ Sets the application's restart hint to \a hint. On application
+ startup the hint is set to \c RestartIfRunning.
+
+ Note that these flags are only hints, a session manager may or may
+ not respect them.
+
+ We recommend setting the restart hint in TQApplication::saveState()
+ because most session managers perform a checkpoint shortly after an
+ application's startup.
+
+ \sa restartHint()
+*/
+
+/*!
+ \fn TQSessionManager::RestartHint TQSessionManager::restartHint() const
+
+ Returns the application's current restart hint. The default is
+ \c RestartIfRunning.
+
+ \sa setRestartHint()
+*/
+
+/*!
+ \fn void TQSessionManager::setRestartCommand( const TQStringList& command )
+
+ If the session manager is capable of restoring sessions it will
+ execute \a command in order to restore the application. The command
+ defaults to
+
+ \code
+ appname -session id
+ \endcode
+
+ The \c -session option is mandatory; otherwise TQApplication cannot
+ tell whether it has been restored or what the current session
+ identifier is. See TQApplication::isSessionRestored() and
+ TQApplication::sessionId() for details.
+
+ If your application is very simple, it may be possible to store the
+ entire application state in additional command line options. This
+ is usually a very bad idea because command lines are often limited
+ to a few hundred bytes. Instead, use TQSettings, or temporary files
+ or a database for this purpose. By marking the data with the unique
+ sessionId(), you will be able to restore the application in a future
+ session.
+
+ \sa restartCommand(), setDiscardCommand(), setRestartHint()
+*/
+
+/*!
+ \fn TQStringList TQSessionManager::restartCommand() const
+
+ Returns the currently set restart command.
+
+ Note that if you want to iterate over the list, you should
+ iterate over a copy, e.g.
+ \code
+ TQStringList list = mySession.restartCommand();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa setRestartCommand(), restartHint()
+*/
+
+/*!
+ \fn void TQSessionManager::setDiscardCommand( const TQStringList& )
+
+ \sa discardCommand(), setRestartCommand()
+*/
+
+
+/*!
+ \fn TQStringList TQSessionManager::discardCommand() const
+
+ Returns the currently set discard command.
+
+ Note that if you want to iterate over the list, you should
+ iterate over a copy, e.g.
+ \code
+ TQStringList list = mySession.discardCommand();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa setDiscardCommand(), restartCommand(), setRestartCommand()
+*/
+
+/*!
+ \overload void TQSessionManager::setManagerProperty( const TQString& name,
+ const TQString& value )
+
+ Low-level write access to the application's identification and state
+ records are kept in the session manager.
+
+ The property called \a name has its value set to the string \a value.
+*/
+
+/*!
+ \fn void TQSessionManager::setManagerProperty( const TQString& name,
+ const TQStringList& value )
+
+ Low-level write access to the application's identification and state
+ record are kept in the session manager.
+
+ The property called \a name has its value set to the string list \a value.
+*/
+
+/*!
+ \fn bool TQSessionManager::isPhase2() const
+
+ Returns TRUE if the session manager is currently performing a second
+ session management phase; otherwise returns FALSE.
+
+ \sa requestPhase2()
+*/
+
+/*!
+ \fn void TQSessionManager::requestPhase2()
+
+ Requests a second session management phase for the application. The
+ application may then return immediately from the
+ TQApplication::commitData() or TQApplication::saveState() function,
+ and they will be called again once most or all other applications have
+ finished their session management.
+
+ The two phases are useful for applications such as the X11 window manager
+ that need to store information about another application's windows
+ and therefore have to wait until these applications have completed their
+ respective session management tasks.
+
+ Note that if another application has requested a second phase it
+ may get called before, simultaneously with, or after your
+ application's second phase.
+
+ \sa isPhase2()
+*/
+
+/*!
+ \fn int TQApplication::horizontalAlignment( int align )
+
+ Strips out vertical tqalignment flags and transforms an
+ tqalignment \a align of AlignAuto into AlignLeft or
+ AlignRight according to the language used. The other horizontal
+ tqalignment flags are left untouched.
+*/
+
+
+/*****************************************************************************
+ Stubbed session management support
+ *****************************************************************************/
+#ifndef TQT_NO_SESSIONMANAGER
+#if defined( TQT_NO_SM_SUPPORT ) || defined( TQ_WS_WIN ) || defined( TQ_WS_MAC ) || defined( TQ_WS_TQWS )
+
+class TQSessionManagerData
+{
+public:
+ TQStringList restartCommand;
+ TQStringList discardCommand;
+ TQString sessionId;
+ TQString sessionKey;
+ TQSessionManager::RestartHint restartHint;
+};
+
+TQSessionManager* qt_session_manager_self = 0;
+TQSessionManager::TQSessionManager( TQApplication * app, TQString &id, TQString &key )
+ : TQObject( app, "qt_sessionmanager" )
+{
+ qt_session_manager_self = this;
+ d = new TQSessionManagerData;
+#if defined(TQ_WS_WIN) && !defined(TQ_OS_TEMP)
+ wchar_t guidstr[40];
+ GUID guid;
+ CoCreateGuid( &guid );
+ StringFromGUID2(guid, guidstr, 40);
+ id = TQString::fromUcs2((ushort*)guidstr);
+ CoCreateGuid( &guid );
+ StringFromGUID2(guid, guidstr, 40);
+ key = TQString::fromUcs2((ushort*)guidstr);
+#endif
+ d->sessionId = id;
+ d->sessionKey = key;
+ d->restartHint = RestartIfRunning;
+}
+
+TQSessionManager::~TQSessionManager()
+{
+ delete d;
+ qt_session_manager_self = 0;
+}
+
+TQString TQSessionManager::sessionId() const
+{
+ return d->sessionId;
+}
+
+TQString TQSessionManager::sessionKey() const
+{
+ return d->sessionKey;
+}
+
+
+#if defined(TQ_WS_X11) || defined(TQ_WS_MAC)
+void* TQSessionManager::handle() const
+{
+ return 0;
+}
+#endif
+
+#if !defined(TQ_WS_WIN)
+bool TQSessionManager::allowsInteraction()
+{
+ return TRUE;
+}
+
+bool TQSessionManager::allowsErrorInteraction()
+{
+ return TRUE;
+}
+void TQSessionManager::release()
+{
+}
+
+void TQSessionManager::cancel()
+{
+}
+#endif
+
+
+void TQSessionManager::setRestartHint( TQSessionManager::RestartHint hint)
+{
+ d->restartHint = hint;
+}
+
+TQSessionManager::RestartHint TQSessionManager::restartHint() const
+{
+ return d->restartHint;
+}
+
+void TQSessionManager::setRestartCommand( const TQStringList& command)
+{
+ d->restartCommand = command;
+}
+
+TQStringList TQSessionManager::restartCommand() const
+{
+ return d->restartCommand;
+}
+
+void TQSessionManager::setDiscardCommand( const TQStringList& command)
+{
+ d->discardCommand = command;
+}
+
+TQStringList TQSessionManager::discardCommand() const
+{
+ return d->discardCommand;
+}
+
+void TQSessionManager::setManagerProperty( const TQString&, const TQString&)
+{
+}
+
+void TQSessionManager::setManagerProperty( const TQString&, const TQStringList& )
+{
+}
+
+bool TQSessionManager::isPhase2() const
+{
+ return FALSE;
+}
+
+void TQSessionManager::requestPhase2()
+{
+}
+
+#endif // TQT_NO_SM_SUPPORT
+#endif //TQT_NO_SESSIONMANAGER
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqapplication.h b/tqtinterface/qt4/src/kernel/tqapplication.h
new file mode 100644
index 0000000..2be7c02
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqapplication.h
@@ -0,0 +1,724 @@
+/****************************************************************************
+**
+** Definition of TQApplication class
+**
+** Created : 931107
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQAPPLICATION_H
+#define TQAPPLICATION_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqdesktopwidget.h"
+#include "tqasciidict.h"
+#include "tqpalette.h"
+#include "tqtranslator.h"
+#include "tqstrlist.h"
+#include "tqstringlist.h"
+#include "tqwidgetlist.h"
+#include "tqclipboard.h"
+#include "tqcursor.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include "private/qt4_qapplication_p.h"
+#include <Qt/qapplication.h>
+#include <Qt/qstyle.h>
+
+#endif // USE_QT4
+
+class TQSessionManager;
+class TQStyle;
+class TQTranslator;
+class TQEventLoop;
+#if defined(TQ_WS_TQWS)
+class TQWSDecoration;
+#endif
+
+#ifdef TQT_THREAD_SUPPORT
+class TQMutex;
+#endif // TQT_THREAD_SUPPORT
+
+#ifdef USE_QT4
+
+#define TQAPPLICATION_GUI_VAR_INIT if (( QApplication::type() != QApplication::GuiClient ) && ( QApplication::type() != QApplication::GuiServer )) { qt_is_gui_used = FALSE; } else { qt_is_gui_used = TRUE; } tqAppReal = static_cast<TQApplication*>(qApp);
+#define TQAPPLICATION_GUI_CONDITIONAL_VAR_INIT if (GUIenabled == false) { qt_is_gui_used = FALSE; } else { qt_is_gui_used = TRUE; } tqAppReal = static_cast<TQApplication*>(qApp);
+#define TQAPPLICATION_XORG_FULL_INIT if (qt_is_gui_used == true) { qt_init( dpy, visual, cmap ); }
+#define TQAPPLICATION_XORG_PARTIAL_INIT qt_init( &argc, argv, t );
+#define TQAPPLICATION_XORG_CONDITIONAL_INIT if (GUIenabled == true) { qt_init( &argc, argv, QApplication::GuiClient ); }
+#define TQAPPLICATION_REGISTER_TQ_DATATYPES qRegisterMetaType<TQChar>("TQChar"); \
+ qRegisterMetaType<TQString>("TQString"); \
+ qRegisterMetaType<TQColor>("TQColor");
+
+class TQApplication;
+extern TQ_EXPORT TQApplication *tqAppReal; // global application object
+#define tqApp tqAppReal
+
+class TQ_EXPORT TQApplication : public QApplication, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQApplication( int &argc, char **argv );
+ TQApplication( int &argc, char **argv, bool GUIenabled );
+ TQApplication( int &argc, char **argv, Type t );
+#if defined(TQ_WS_X11)
+ TQApplication( Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0 );
+ TQApplication( Display *dpy, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0 );
+#endif
+
+#ifndef Q_QDOC
+ enum ColorMode { NormalColors, CustomColors };
+ static ColorMode colorMode();
+ static void setColorMode( TQApplication::ColorMode );
+#endif
+
+ int exec();
+
+ const char *tqname() const;
+ const char *name() const;
+ const char *name(const char *defaultName) const;
+ void setName(const char *aName);
+
+ virtual void commitData( TQSessionManager& sm );
+ virtual void saveState( TQSessionManager& sm );
+
+ // Qt4 session manager interconnect
+ virtual void commitData( QSessionManager& sm );
+ virtual void saveState( QSessionManager& sm );
+
+ static void exit_loop();
+ static int enter_loop();
+ static void processOneEvent();
+ void tqprocessEvents();
+ void tqprocessEvents( int maxtime );
+ int loopLevel() const;
+ static void flushX();
+ TQWidget *tqfocusWidget() const;
+ static TQWidget *widgetAt( const TQPoint &p, bool child=FALSE );
+ static TQWidget *widgetAt( int x, int y, bool child=FALSE );
+ static int horizontalAlignment( int align );
+
+ static void sendPostedEvents( QObject *receiver, int event_type );
+ static void sendPostedEvents();
+
+#ifndef TQT_NO_CURSOR
+// static void setOverrideCursor( const QCursor &cur, bool tqreplace=FALSE );
+ static void setOverrideCursor( const QCursor &cur, bool tqreplace=FALSE );
+#endif
+
+ static void setReverseLayout(bool b);
+ static bool reverseLayout();
+
+ static TQPalette tqpalette( const TQWidget*w = 0 );
+
+ static TQWidgetList *tqtopLevelWidgets();
+
+ static TQEventLoop *eventLoop();
+
+ static TQStyle &tqstyle();
+ static void setStyle( TQStyle* );
+ static TQStyle* setStyle( const TQString& );
+
+ static TQDesktopWidget *desktop();
+ static const QColor &winStyleHighlightColor();
+ static void tqsetPalette(const QPalette &pal, bool informWidgets=FALSE, const char* className = 0);
+ static void tqsetFont(const QFont &font, bool informWidgets=FALSE, const char* className = 0);
+ static void setWinStyleHighlightColor( const QColor c );
+#ifndef TQT_NO_CLIPBOARD
+// static inline TQClipboard *tqclipboard() { return TQT_TQCLIPBOARD(clipboard()); }
+ static TQClipboard *tqclipboard();
+#endif
+
+ static TQStringList libraryPaths();
+ static void tqsetLibraryPaths( const QStringList &qsl );
+// inline static void tqsetLibraryPaths( const TQStringList &tqsl ) { setLibraryPaths(static_cast<const QStringList*>(&tqsl)); }
+
+ static TQWidgetList *tqallWidgets();
+
+ virtual void polish( QWidget * );
+
+ TQMetaObject *tqmetaObject() const;
+
+ static bool hasGlobalMouseTracking();
+ static void setGlobalMouseTracking( bool enable );
+
+Q_SIGNALS:
+ void guiThreadAwake(); // Does not exist in Qt4; therefore will never be triggered
+
+public:
+ TQWidget *mainWidget();
+ void setMainWidget(QWidget *);
+
+ // [FIXME]
+#if defined(TQ_WS_X11)
+ static void create_xim();
+ static void close_xim();
+ static bool x11_apply_settings();
+#endif
+#ifndef TQT_NO_TRANSLATION
+#ifndef TQT_NO_TEXTCODEC
+ void setDefaultCodec( TQTextCodec * );
+ TQTextCodec* defaultCodec() const;
+#endif
+// void installTranslator( TQTranslator * );
+// void removeTranslator( TQTranslator * );
+#endif
+
+ void wakeUpGuiThread();
+#ifdef TQT_THREAD_SUPPORT
+ void lock();
+ void unlock(bool wakeUpGui = TRUE);
+ bool locked();
+ bool tryLock();
+#endif
+
+public slots:
+ void aboutTQt();
+
+private:
+ static TQEventLoop* eventloop; // Will this work as-is or do I need code behind it?
+ static int app_cspec;
+ static TQStyle *app_style;
+#ifndef TQT_NO_PALETTE
+ static TQPalette *app_pal;
+#endif
+ static TQPtrList<QEventLoop> tqt_event_loop_stack;
+ static TQWidgetList tqt_all_widgets_list;
+ static QWidget* current_app_main_widget;
+ mutable TQString static_object_name;
+ friend class TQWidget;
+ friend class TQETWidget;
+ friend class TQDialog;
+ friend class TQAccelManager;
+ friend class TQEvent;
+ friend class TQTranslator;
+ friend class TQEventLoop;
+ friend TQ_EXPORT void qt_ucm_initialize( TQApplication * );
+#if defined(TQ_WS_WIN)
+ friend bool qt_sendSpontaneousEvent( TQObject*, TQEvent* );
+#endif
+#if defined(TQ_WS_TQWS)
+ friend class TQInputContext;
+#endif
+
+ friend void qt_init(int *, char **, TQApplication::Type);
+
+#ifdef TQT_THREAD_SUPPORT
+ static TQMutex *qt_mutex;
+#endif // TQT_THREAD_SUPPORT
+
+public:
+ static int composedUnicode; // Value, meta-composed character
+ static bool metaComposeUnicode;
+
+protected:
+ inline bool event(QEvent *e) { TQT_TQOBJECT_CHILDEVENT_REQUIRED_HANDLER(e) return QApplication::event(e); }
+};
+
+#else // USE_QT4
+
+class TQApplication;
+extern TQ_EXPORT TQApplication *tqApp; // global application object
+
+
+class TQ_EXPORT TQApplication : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQApplication( int &argc, char **argv );
+ TQApplication( int &argc, char **argv, bool GUIenabled );
+ enum Type { Tty, GuiClient, GuiServer };
+ TQApplication( int &argc, char **argv, Type );
+#if defined(TQ_WS_X11)
+ TQApplication( Display* dpy, HANDLE visual = 0, HANDLE cmap = 0 );
+ TQApplication( Display *dpy, int argc, char **argv,
+ HANDLE visual = 0, HANDLE cmap= 0 );
+#endif
+ virtual ~TQApplication();
+
+ int argc() const;
+ char **argv() const;
+
+ Type type() const;
+
+#ifndef TQT_NO_STYLE
+ static TQStyle &tqstyle();
+ static void setStyle( TQStyle* );
+ static TQStyle* setStyle( const TQString& );
+#endif
+#ifndef TQ_TQDOC
+ enum ColorMode { NormalColors, CustomColors };
+ static ColorMode colorMode();
+ static void setColorMode( TQApplication::ColorMode );
+#endif
+
+ enum ColorSpec { NormalColor=0, CustomColor=1, ManyColor=2 };
+ static int colorSpec();
+ static void setColorSpec( int );
+#ifndef TQT_NO_CURSOR
+ static TQCursor *overrideCursor();
+ static void setOverrideCursor( const TQCursor &, bool tqreplace=FALSE );
+ static void restoreOverrideCursor();
+#endif
+ static bool hasGlobalMouseTracking();
+ static void setGlobalMouseTracking( bool enable );
+#ifndef TQT_NO_PALETTE
+ static TQPalette palette( const TQWidget* = 0 );
+ static void setPalette( const TQPalette &, bool informWidgets=FALSE,
+ const char* className = 0 );
+#endif
+ static TQFont font( const TQWidget* = 0 );
+ static void setFont( const TQFont &, bool informWidgets=FALSE,
+ const char* className = 0 );
+ static TQFontMetrics fontMetrics();
+
+ TQWidget *mainWidget() const;
+ virtual void setMainWidget( TQWidget * );
+ virtual void polish( TQWidget * );
+
+ static TQWidgetList *allWidgets();
+ static TQWidgetList *tqtopLevelWidgets();
+
+ static TQDesktopWidget *desktop();
+
+ static TQWidget *activePopupWidget();
+ static TQWidget *activeModalWidget();
+#ifndef TQT_NO_CLIPBOARD
+ static TQClipboard *clipboard();
+#endif
+ TQWidget *tqfocusWidget() const;
+ TQWidget *activeWindow() const;
+
+ static TQWidget *widgetAt( int x, int y, bool child=FALSE );
+ static TQWidget *widgetAt( const TQPoint &, bool child=FALSE );
+
+ static TQEventLoop *eventLoop();
+
+ int exec();
+ void processEvents();
+ void processEvents( int maxtime );
+ void processOneEvent();
+ bool hasPendingEvents();
+ int enter_loop();
+ void exit_loop();
+ int loopLevel() const;
+ static void exit( int retcode=0 );
+
+ static bool sendEvent( TQObject *receiver, TQEvent *event );
+ static void postEvent( TQObject *receiver, TQEvent *event );
+ static void sendPostedEvents( TQObject *receiver, int event_type );
+ static void sendPostedEvents();
+
+ static void removePostedEvents( TQObject *receiver );
+
+ virtual bool notify( TQObject *, TQEvent * );
+
+ static bool startingUp();
+ static bool closingDown();
+
+ static void flushX();
+ static void flush();
+ static void syncX();
+
+ static void beep();
+
+#ifndef TQT_NO_TRANSLATION
+# ifndef TQT_NO_TEXTCODEC
+ void setDefaultCodec( TQTextCodec * );
+ TQTextCodec* defaultCodec() const;
+# endif
+ void installTranslator( TQTranslator * );
+ void removeTranslator( TQTranslator * );
+#endif
+ enum Encoding { DefaultCodec, UnicodeUTF8 };
+ TQString translate( const char * context,
+ const char * key,
+ const char * comment = 0,
+ Encoding encoding = DefaultCodec ) const;
+#ifndef TQT_NO_DIR
+ TQString applicationDirPath();
+ TQString applicationFilePath();
+#endif
+#ifndef TQT_NO_PALETTE
+ // obsolete functions
+ static void setWinStyleHighlightColor( const TQColor &c ) {
+ TQPalette p( palette() );
+ p.setColor( TQColorGroup::Highlight, c );
+ setPalette( p, TRUE);
+ }
+ static const TQColor &winStyleHighlightColor() {
+ return palette().active().highlight();
+ }
+#endif
+ static void setDesktopSettingsAware( bool );
+ static bool desktopSettingsAware();
+
+ static void setCursorFlashTime( int );
+ static int cursorFlashTime();
+
+ static void setDoubleClickInterval( int );
+ static int doubleClickInterval();
+#ifndef TQT_NO_WHEELEVENT
+ static void setWheelScrollLines( int );
+ static int wheelScrollLines();
+#endif
+ static void setGlobalStrut( const TQSize & );
+ static TQSize globalStrut();
+
+#ifndef TQT_NO_COMPONENT
+ static void tqsetLibraryPaths( const TQStringList & );
+ static TQStringList libraryPaths();
+ static void addLibraryPath( const TQString & );
+ static void removeLibraryPath( const TQString & );
+#endif // TQT_NO_COMPONENT
+ static void setStartDragTime( int ms );
+ static int startDragTime();
+ static void setStartDragDistance( int l );
+ static int startDragDistance();
+
+ static void setReverseLayout( bool b );
+ static bool reverseLayout();
+
+ static int horizontalAlignment( int align );
+
+ static bool isEffectEnabled( TQt::UIEffect );
+ static void setEffectEnabled( TQt::UIEffect, bool enable = TRUE );
+
+#if defined(TQ_WS_MAC)
+ virtual bool macEventFilter( EventHandlerCallRef, EventRef );
+#endif
+#if defined(TQ_WS_WIN)
+ virtual bool winEventFilter( MSG * );
+#endif
+#if defined(TQ_WS_X11)
+ virtual bool x11EventFilter( XEvent * );
+ virtual int x11ClientMessage( TQWidget*, XEvent*, bool passive_only);
+ int x11ProcessEvent( XEvent* );
+#endif
+#if defined(TQ_WS_TQWS)
+ virtual bool qwsEventFilter( TQWSEvent * );
+ int qwsProcessEvent( TQWSEvent* );
+ void qwsSetCustomColors( TQRgb *colortable, int start, int numColors );
+/*!
+ \internal
+ Returns true if the process is GUI server
+*/
+ bool qwsIsGUIServer();
+#ifndef TQT_NO_TQWS_MANAGER
+ static TQWSDecoration &qwsDecoration();
+ static void qwsSetDecoration( TQWSDecoration *);
+#endif
+#endif
+
+#if defined(TQ_OS_WIN32) || defined(TQ_OS_CYGWIN)
+ static WindowsVersion winVersion();
+#elif defined(TQ_OS_MAC)
+ static MacintoshVersion macVersion();
+#endif
+#if defined(TQ_WS_WIN)
+ void winFocus( TQWidget *, bool );
+ static void winMouseButtonUp();
+#endif
+
+#ifndef TQT_NO_SESSIONMANAGER
+ // session management
+ bool isSessionRestored() const;
+ TQString sessionId() const;
+ TQString sessionKey() const;
+ virtual void commitData( TQSessionManager& sm );
+ virtual void saveState( TQSessionManager& sm );
+#endif
+#if defined(TQ_WS_X11)
+ static void create_xim();
+ static void close_xim();
+ static bool x11_apply_settings();
+#endif
+ void wakeUpGuiThread();
+#if defined(TQT_THREAD_SUPPORT)
+ void lock();
+ void unlock(bool wakeUpGui = TRUE);
+ bool locked();
+ bool tryLock();
+#endif
+
+Q_SIGNALS:
+ void lastWindowClosed();
+ void aboutToQuit();
+ void guiThreadAwake();
+
+public Q_SLOTS:
+ void quit();
+ void closeAllWindows();
+ void aboutTQt();
+
+#if defined(TQ_WS_TQWS)
+protected:
+ void setArgs(int, char **);
+#endif
+
+protected:
+ bool event(TQEvent *);
+
+private:
+ void construct( int &argc, char **argv, Type );
+ void initialize( int, char ** );
+ void init_precmdline();
+ void process_cmdline( int* argcptr, char ** argv );
+ bool internalNotify( TQObject *, TQEvent * );
+#if defined(TQ_WS_TQWS)
+ static TQWidget *tqfindChildWidget( const TQWidget *p, const TQPoint &pos );
+ static TQWidget *tqfindWidget( const TQObjectList&, const TQPoint &, bool rec );
+#endif
+
+#if defined(TQ_WS_MAC)
+ bool do_mouse_down(Point *, bool *);
+ static TQMAC_PASCAL OStqStatus globalEventProcessor(EventHandlerCallRef, EventRef, void *);
+ static TQMAC_PASCAL OStqStatus globalAppleEventProcessor(const AppleEvent *, AppleEvent *, long);
+ static TQMAC_PASCAL void qt_context_timer_callbk(EventLoopTimerRef, void *);
+ static TQMAC_PASCAL void qt_select_timer_callbk(EventLoopTimerRef, void *);
+ static bool qt_mac_apply_settings();
+ friend class TQMacInputMethod;
+ friend TQMAC_PASCAL OStqStatus qt_window_event(EventHandlerCallRef, EventRef, void *);
+ friend void qt_mac_update_os_settings();
+ friend bool qt_set_socket_handler( int, int, TQObject *, bool);
+ friend void qt_mac_destroy_widget(TQWidget *);
+ friend void qt_init(int *, char **, TQApplication::Type);
+#endif
+
+#ifdef TQT_THREAD_SUPPORT
+ static TQMutex *qt_mutex;
+#endif // TQT_THREAD_SUPPORT
+
+ int app_argc;
+ char **app_argv;
+ bool quit_now;
+ int quit_code;
+ static TQStyle *app_style;
+ static int app_cspec;
+#ifndef TQT_NO_PALETTE
+ static TQPalette *app_pal;
+#endif
+ static TQFont *app_font;
+#ifndef TQT_NO_CURSOR
+ static TQCursor *app_cursor;
+#endif
+ static TQEventLoop* eventloop;
+ static int app_tracking;
+ static bool is_app_running;
+ static bool is_app_closing;
+ static bool app_exit_loop;
+ static int loop_level;
+ static TQWidget *main_widget;
+ static TQWidget *focus_widget;
+ static TQWidget *active_window;
+ static bool obey_desktop_settings;
+ static int cursor_flash_time;
+ static int mouse_double_click_time;
+ static int wheel_scroll_lines;
+ static int composedUnicode; // Value, meta-composed character
+
+ static bool animate_ui;
+ static bool animate_menu;
+ static bool animate_tooltip;
+ static bool animate_combo;
+ static bool fade_menu;
+ static bool fade_tooltip;
+ static bool animate_toolbox;
+ static bool widgetCount; // Coupled with -widgetcount switch
+ static bool metaComposeUnicode;
+
+ TQValueList<TQTranslator*> *translators;
+#ifndef TQT_NO_SESSIONMANAGER
+ TQSessionManager *session_manager;
+ TQString session_id;
+ static TQString* session_key;
+ bool is_session_restored;
+#endif
+#if defined(TQ_WS_X11) && !defined (TQT_NO_STYLE )
+ static void x11_initialize_style();
+#endif
+
+ static TQSize app_strut;
+#ifndef TQT_NO_COMPONENT
+ static TQStringList *app_libpaths;
+#endif
+ static TQAsciiDict<TQPalette> *app_palettes;
+ static TQAsciiDict<TQFont> *app_fonts;
+
+ static TQWidgetList *popupWidgets;
+ bool inPopupMode() const;
+ void closePopup( TQWidget *popup );
+ void openPopup( TQWidget *popup );
+ void setActiveWindow( TQWidget* act );
+
+ static bool sendSpontaneousEvent( TQObject *receiver, TQEvent *event );
+ static void removePostedEvent( TQEvent * );
+
+ friend class TQWidget;
+ friend class TQETWidget;
+ friend class TQDialog;
+ friend class TQAccelManager;
+ friend class TQEvent;
+ friend class TQTranslator;
+ friend class TQEventLoop;
+ friend TQ_EXPORT void qt_ucm_initialize( TQApplication * );
+#if defined(TQ_WS_WIN)
+ friend bool qt_sendSpontaneousEvent( TQObject*, TQEvent* );
+#endif
+#if defined(TQ_WS_TQWS)
+ friend class TQInputContext;
+#endif
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQApplication( const TQApplication & );
+ TQApplication &operator=( const TQApplication & );
+#endif
+};
+
+inline int TQApplication::argc() const
+{
+ return app_argc;
+}
+
+inline char **TQApplication::argv() const
+{
+ return app_argv;
+}
+
+#if defined(TQ_WS_TQWS)
+inline void TQApplication::setArgs(int c, char **v)
+{
+ app_argc = c;
+ app_argv = v;
+}
+#endif
+
+#ifndef TQT_NO_CURSOR
+inline TQCursor *TQApplication::overrideCursor()
+{
+ return app_cursor;
+}
+#endif
+inline bool TQApplication::hasGlobalMouseTracking()
+{
+ return app_tracking > 0;
+}
+
+inline TQWidget *TQApplication::mainWidget() const
+{
+ return main_widget;
+}
+
+inline TQWidget *TQApplication::tqfocusWidget() const
+{
+ return focus_widget;
+}
+
+inline TQWidget *TQApplication::activeWindow() const
+{
+ return active_window;
+}
+
+inline TQWidget *TQApplication::widgetAt( const TQPoint &p, bool child )
+{
+ return widgetAt( p.x(), p.y(), child );
+}
+
+inline bool TQApplication::inPopupMode() const
+{
+ return popupWidgets != 0;
+}
+#ifndef TQT_NO_SESSIONMANAGER
+inline bool TQApplication::isSessionRestored() const
+{
+ return is_session_restored;
+}
+
+inline TQString TQApplication::sessionId() const
+{
+ return session_id;
+}
+
+inline TQString TQApplication::sessionKey() const
+{
+ return session_key ? *session_key : TQString::null;
+}
+#endif
+inline TQSize TQApplication::globalStrut()
+{
+ return app_strut;
+}
+
+inline bool TQApplication::sendEvent( TQObject *receiver, TQEvent *event )
+{ if ( event ) event->spont = FALSE; return tqApp ? tqApp->notify( receiver, event ) : FALSE; }
+
+inline bool TQApplication::sendSpontaneousEvent( TQObject *receiver, TQEvent *event )
+{ if ( event ) event->spont = TRUE; return tqApp ? tqApp->notify( receiver, event ) : FALSE; }
+
+#ifdef TQT_NO_TRANSLATION
+// Simple versions
+inline TQString TQApplication::translate( const char *, const char *sourceText,
+ const char *, Encoding encoding ) const
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( encoding == UnicodeUTF8 )
+ return TQString::fromUtf8( sourceText );
+ else
+#endif
+ return TQString::tqfromLatin1( sourceText );
+}
+#endif
+
+inline int TQApplication::horizontalAlignment( int align )
+{
+ align &= AlignHorizontal_Mask;
+ if ( align == AlignAuto ) {
+ if ( reverseLayout() )
+ align = AlignRight;
+ else
+ align = AlignLeft;
+ }
+ return align;
+}
+
+#endif // TQAPPLICATION_H
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqapplication.h~ b/tqtinterface/qt4/src/kernel/tqapplication.h~
new file mode 100644
index 0000000..44acad5
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqapplication.h~
@@ -0,0 +1,724 @@
+/****************************************************************************
+**
+** Definition of TQApplication class
+**
+** Created : 931107
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQAPPLICATION_H
+#define TQAPPLICATION_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqdesktopwidget.h"
+#include "tqasciidict.h"
+#include "tqpalette.h"
+#include "tqtranslator.h"
+#include "tqstrlist.h"
+#include "tqstringlist.h"
+#include "tqwidgetlist.h"
+#include "tqclipboard.h"
+#include "tqcursor.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include "private/qt4_qapplication_p.h"
+#include <Qt/qapplication.h>
+#include <Qt/qstyle.h>
+
+#endif // USE_QT4
+
+class TQSessionManager;
+class TQStyle;
+class TQTranslator;
+class TQEventLoop;
+#if defined(TQ_WS_TQWS)
+class TQWSDecoration;
+#endif
+
+#ifdef TQT_THREAD_SUPPORT
+class TQMutex;
+#endif // TQT_THREAD_SUPPORT
+
+#ifdef USE_QT4
+
+#define TQAPPLICATION_GUI_VAR_INIT if (( QApplication::type() != QApplication::GuiClient ) && ( QApplication::type() != QApplication::GuiServer )) { qt_is_gui_used = FALSE; } else { qt_is_gui_used = TRUE; } tqAppReal = static_cast<TQApplication*>(qApp);
+#define TQAPPLICATION_GUI_CONDITIONAL_VAR_INIT if (GUIenabled == false) { qt_is_gui_used = FALSE; } else { qt_is_gui_used = TRUE; } tqAppReal = static_cast<TQApplication*>(qApp);
+#define TQAPPLICATION_XORG_FULL_INIT if (qt_is_gui_used == true) { qt_init( dpy, visual, cmap ); }
+#define TQAPPLICATION_XORG_PARTIAL_INIT qt_init( &argc, argv, t );
+#define TQAPPLICATION_XORG_CONDITIONAL_INIT if (GUIenabled == true) { qt_init( &argc, argv, QApplication::GuiClient ); }
+#define TQAPPLICATION_REGISTER_TQ_DATATYPES qRegisterMetaType<TQChar>("TQChar"); \
+ qRegisterMetaType<TQString>("TQString"); \
+ qRegisterMetaType<TQColor>("TQColor");
+
+class TQApplication;
+extern TQ_EXPORT TQApplication *tqAppReal; // global application object
+#define tqApp tqAppReal
+
+class TQ_EXPORT TQApplication : public QApplication, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQApplication( int &argc, char **argv );
+ TQApplication( int &argc, char **argv, bool GUIenabled );
+ TQApplication( int &argc, char **argv, Type t );
+#if defined(TQ_WS_X11)
+ TQApplication( Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE cmap = 0 );
+ TQApplication( Display *dpy, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0 );
+#endif
+
+#ifndef Q_QDOC
+ enum ColorMode { NormalColors, CustomColors };
+ static ColorMode colorMode();
+ static void setColorMode( TQApplication::ColorMode );
+#endif
+
+ int exec();
+
+ const char *tqname() const;
+ const char *name() const;
+ const char *name(const char *defaultName) const;
+ void setName(const char *aName);
+
+ virtual void commitData( TQSessionManager& sm );
+ virtual void saveState( TQSessionManager& sm );
+
+ // Qt4 session manager interconnect
+ virtual void commitData( QSessionManager& sm );
+ virtual void saveState( QSessionManager& sm );
+
+ static void exit_loop();
+ static int enter_loop();
+ static void processOneEvent();
+ void tqprocessEvents();
+ void tqprocessEvents( int maxtime );
+ int loopLevel() const;
+ static void flushX();
+ TQWidget *tqfocusWidget() const;
+ static TQWidget *widgetAt( const TQPoint &p, bool child=FALSE );
+ static TQWidget *widgetAt( int x, int y, bool child=FALSE );
+ static int horizontalAlignment( int align );
+
+ inline static void sendPostedEvents( QObject *receiver, int event_type );
+ inline static void sendPostedEvents();
+
+#ifndef TQT_NO_CURSOR
+// static void setOverrideCursor( const QCursor &cur, bool tqreplace=FALSE );
+ static void setOverrideCursor( const QCursor &cur, bool tqreplace=FALSE );
+#endif
+
+ static void setReverseLayout(bool b);
+ static bool reverseLayout();
+
+ static TQPalette tqpalette( const TQWidget*w = 0 );
+
+ static TQWidgetList *tqtopLevelWidgets();
+
+ static TQEventLoop *eventLoop();
+
+ static TQStyle &tqstyle();
+ static void setStyle( TQStyle* );
+ static TQStyle* setStyle( const TQString& );
+
+ static TQDesktopWidget *desktop();
+ static const QColor &winStyleHighlightColor();
+ static void tqsetPalette(const QPalette &pal, bool informWidgets=FALSE, const char* className = 0);
+ static void tqsetFont(const QFont &font, bool informWidgets=FALSE, const char* className = 0);
+ static void setWinStyleHighlightColor( const QColor c );
+#ifndef TQT_NO_CLIPBOARD
+// static inline TQClipboard *tqclipboard() { return TQT_TQCLIPBOARD(clipboard()); }
+ static TQClipboard *tqclipboard();
+#endif
+
+ static TQStringList libraryPaths();
+ static void tqsetLibraryPaths( const QStringList &qsl );
+// inline static void tqsetLibraryPaths( const TQStringList &tqsl ) { setLibraryPaths(static_cast<const QStringList*>(&tqsl)); }
+
+ static TQWidgetList *tqallWidgets();
+
+ virtual void polish( QWidget * );
+
+ TQMetaObject *tqmetaObject() const;
+
+ static bool hasGlobalMouseTracking();
+ static void setGlobalMouseTracking( bool enable );
+
+Q_SIGNALS:
+ void guiThreadAwake(); // Does not exist in Qt4; therefore will never be triggered
+
+public:
+ TQWidget *mainWidget();
+ void setMainWidget(QWidget *);
+
+ // [FIXME]
+#if defined(TQ_WS_X11)
+ static void create_xim();
+ static void close_xim();
+ static bool x11_apply_settings();
+#endif
+#ifndef TQT_NO_TRANSLATION
+#ifndef TQT_NO_TEXTCODEC
+ void setDefaultCodec( TQTextCodec * );
+ TQTextCodec* defaultCodec() const;
+#endif
+// void installTranslator( TQTranslator * );
+// void removeTranslator( TQTranslator * );
+#endif
+
+ void wakeUpGuiThread();
+#ifdef TQT_THREAD_SUPPORT
+ void lock();
+ void unlock(bool wakeUpGui = TRUE);
+ bool locked();
+ bool tryLock();
+#endif
+
+public slots:
+ void aboutTQt();
+
+private:
+ static TQEventLoop* eventloop; // Will this work as-is or do I need code behind it?
+ static int app_cspec;
+ static TQStyle *app_style;
+#ifndef TQT_NO_PALETTE
+ static TQPalette *app_pal;
+#endif
+ static TQPtrList<QEventLoop> tqt_event_loop_stack;
+ static TQWidgetList tqt_all_widgets_list;
+ static QWidget* current_app_main_widget;
+ mutable TQString static_object_name;
+ friend class TQWidget;
+ friend class TQETWidget;
+ friend class TQDialog;
+ friend class TQAccelManager;
+ friend class TQEvent;
+ friend class TQTranslator;
+ friend class TQEventLoop;
+ friend TQ_EXPORT void qt_ucm_initialize( TQApplication * );
+#if defined(TQ_WS_WIN)
+ friend bool qt_sendSpontaneousEvent( TQObject*, TQEvent* );
+#endif
+#if defined(TQ_WS_TQWS)
+ friend class TQInputContext;
+#endif
+
+ friend void qt_init(int *, char **, TQApplication::Type);
+
+#ifdef TQT_THREAD_SUPPORT
+ static TQMutex *qt_mutex;
+#endif // TQT_THREAD_SUPPORT
+
+public:
+ static int composedUnicode; // Value, meta-composed character
+ static bool metaComposeUnicode;
+
+protected:
+ inline bool event(QEvent *e) { TQT_TQOBJECT_CHILDEVENT_REQUIRED_HANDLER(e) return QApplication::event(e); }
+};
+
+#else // USE_QT4
+
+class TQApplication;
+extern TQ_EXPORT TQApplication *tqApp; // global application object
+
+
+class TQ_EXPORT TQApplication : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQApplication( int &argc, char **argv );
+ TQApplication( int &argc, char **argv, bool GUIenabled );
+ enum Type { Tty, GuiClient, GuiServer };
+ TQApplication( int &argc, char **argv, Type );
+#if defined(TQ_WS_X11)
+ TQApplication( Display* dpy, HANDLE visual = 0, HANDLE cmap = 0 );
+ TQApplication( Display *dpy, int argc, char **argv,
+ HANDLE visual = 0, HANDLE cmap= 0 );
+#endif
+ virtual ~TQApplication();
+
+ int argc() const;
+ char **argv() const;
+
+ Type type() const;
+
+#ifndef TQT_NO_STYLE
+ static TQStyle &tqstyle();
+ static void setStyle( TQStyle* );
+ static TQStyle* setStyle( const TQString& );
+#endif
+#ifndef TQ_TQDOC
+ enum ColorMode { NormalColors, CustomColors };
+ static ColorMode colorMode();
+ static void setColorMode( TQApplication::ColorMode );
+#endif
+
+ enum ColorSpec { NormalColor=0, CustomColor=1, ManyColor=2 };
+ static int colorSpec();
+ static void setColorSpec( int );
+#ifndef TQT_NO_CURSOR
+ static TQCursor *overrideCursor();
+ static void setOverrideCursor( const TQCursor &, bool tqreplace=FALSE );
+ static void restoreOverrideCursor();
+#endif
+ static bool hasGlobalMouseTracking();
+ static void setGlobalMouseTracking( bool enable );
+#ifndef TQT_NO_PALETTE
+ static TQPalette palette( const TQWidget* = 0 );
+ static void setPalette( const TQPalette &, bool informWidgets=FALSE,
+ const char* className = 0 );
+#endif
+ static TQFont font( const TQWidget* = 0 );
+ static void setFont( const TQFont &, bool informWidgets=FALSE,
+ const char* className = 0 );
+ static TQFontMetrics fontMetrics();
+
+ TQWidget *mainWidget() const;
+ virtual void setMainWidget( TQWidget * );
+ virtual void polish( TQWidget * );
+
+ static TQWidgetList *allWidgets();
+ static TQWidgetList *tqtopLevelWidgets();
+
+ static TQDesktopWidget *desktop();
+
+ static TQWidget *activePopupWidget();
+ static TQWidget *activeModalWidget();
+#ifndef TQT_NO_CLIPBOARD
+ static TQClipboard *clipboard();
+#endif
+ TQWidget *tqfocusWidget() const;
+ TQWidget *activeWindow() const;
+
+ static TQWidget *widgetAt( int x, int y, bool child=FALSE );
+ static TQWidget *widgetAt( const TQPoint &, bool child=FALSE );
+
+ static TQEventLoop *eventLoop();
+
+ int exec();
+ void processEvents();
+ void processEvents( int maxtime );
+ void processOneEvent();
+ bool hasPendingEvents();
+ int enter_loop();
+ void exit_loop();
+ int loopLevel() const;
+ static void exit( int retcode=0 );
+
+ static bool sendEvent( TQObject *receiver, TQEvent *event );
+ static void postEvent( TQObject *receiver, TQEvent *event );
+ static void sendPostedEvents( TQObject *receiver, int event_type );
+ static void sendPostedEvents();
+
+ static void removePostedEvents( TQObject *receiver );
+
+ virtual bool notify( TQObject *, TQEvent * );
+
+ static bool startingUp();
+ static bool closingDown();
+
+ static void flushX();
+ static void flush();
+ static void syncX();
+
+ static void beep();
+
+#ifndef TQT_NO_TRANSLATION
+# ifndef TQT_NO_TEXTCODEC
+ void setDefaultCodec( TQTextCodec * );
+ TQTextCodec* defaultCodec() const;
+# endif
+ void installTranslator( TQTranslator * );
+ void removeTranslator( TQTranslator * );
+#endif
+ enum Encoding { DefaultCodec, UnicodeUTF8 };
+ TQString translate( const char * context,
+ const char * key,
+ const char * comment = 0,
+ Encoding encoding = DefaultCodec ) const;
+#ifndef TQT_NO_DIR
+ TQString applicationDirPath();
+ TQString applicationFilePath();
+#endif
+#ifndef TQT_NO_PALETTE
+ // obsolete functions
+ static void setWinStyleHighlightColor( const TQColor &c ) {
+ TQPalette p( palette() );
+ p.setColor( TQColorGroup::Highlight, c );
+ setPalette( p, TRUE);
+ }
+ static const TQColor &winStyleHighlightColor() {
+ return palette().active().highlight();
+ }
+#endif
+ static void setDesktopSettingsAware( bool );
+ static bool desktopSettingsAware();
+
+ static void setCursorFlashTime( int );
+ static int cursorFlashTime();
+
+ static void setDoubleClickInterval( int );
+ static int doubleClickInterval();
+#ifndef TQT_NO_WHEELEVENT
+ static void setWheelScrollLines( int );
+ static int wheelScrollLines();
+#endif
+ static void setGlobalStrut( const TQSize & );
+ static TQSize globalStrut();
+
+#ifndef TQT_NO_COMPONENT
+ static void tqsetLibraryPaths( const TQStringList & );
+ static TQStringList libraryPaths();
+ static void addLibraryPath( const TQString & );
+ static void removeLibraryPath( const TQString & );
+#endif // TQT_NO_COMPONENT
+ static void setStartDragTime( int ms );
+ static int startDragTime();
+ static void setStartDragDistance( int l );
+ static int startDragDistance();
+
+ static void setReverseLayout( bool b );
+ static bool reverseLayout();
+
+ static int horizontalAlignment( int align );
+
+ static bool isEffectEnabled( TQt::UIEffect );
+ static void setEffectEnabled( TQt::UIEffect, bool enable = TRUE );
+
+#if defined(TQ_WS_MAC)
+ virtual bool macEventFilter( EventHandlerCallRef, EventRef );
+#endif
+#if defined(TQ_WS_WIN)
+ virtual bool winEventFilter( MSG * );
+#endif
+#if defined(TQ_WS_X11)
+ virtual bool x11EventFilter( XEvent * );
+ virtual int x11ClientMessage( TQWidget*, XEvent*, bool passive_only);
+ int x11ProcessEvent( XEvent* );
+#endif
+#if defined(TQ_WS_TQWS)
+ virtual bool qwsEventFilter( TQWSEvent * );
+ int qwsProcessEvent( TQWSEvent* );
+ void qwsSetCustomColors( TQRgb *colortable, int start, int numColors );
+/*!
+ \internal
+ Returns true if the process is GUI server
+*/
+ bool qwsIsGUIServer();
+#ifndef TQT_NO_TQWS_MANAGER
+ static TQWSDecoration &qwsDecoration();
+ static void qwsSetDecoration( TQWSDecoration *);
+#endif
+#endif
+
+#if defined(TQ_OS_WIN32) || defined(TQ_OS_CYGWIN)
+ static WindowsVersion winVersion();
+#elif defined(TQ_OS_MAC)
+ static MacintoshVersion macVersion();
+#endif
+#if defined(TQ_WS_WIN)
+ void winFocus( TQWidget *, bool );
+ static void winMouseButtonUp();
+#endif
+
+#ifndef TQT_NO_SESSIONMANAGER
+ // session management
+ bool isSessionRestored() const;
+ TQString sessionId() const;
+ TQString sessionKey() const;
+ virtual void commitData( TQSessionManager& sm );
+ virtual void saveState( TQSessionManager& sm );
+#endif
+#if defined(TQ_WS_X11)
+ static void create_xim();
+ static void close_xim();
+ static bool x11_apply_settings();
+#endif
+ void wakeUpGuiThread();
+#if defined(TQT_THREAD_SUPPORT)
+ void lock();
+ void unlock(bool wakeUpGui = TRUE);
+ bool locked();
+ bool tryLock();
+#endif
+
+Q_SIGNALS:
+ void lastWindowClosed();
+ void aboutToQuit();
+ void guiThreadAwake();
+
+public Q_SLOTS:
+ void quit();
+ void closeAllWindows();
+ void aboutTQt();
+
+#if defined(TQ_WS_TQWS)
+protected:
+ void setArgs(int, char **);
+#endif
+
+protected:
+ bool event(TQEvent *);
+
+private:
+ void construct( int &argc, char **argv, Type );
+ void initialize( int, char ** );
+ void init_precmdline();
+ void process_cmdline( int* argcptr, char ** argv );
+ bool internalNotify( TQObject *, TQEvent * );
+#if defined(TQ_WS_TQWS)
+ static TQWidget *tqfindChildWidget( const TQWidget *p, const TQPoint &pos );
+ static TQWidget *tqfindWidget( const TQObjectList&, const TQPoint &, bool rec );
+#endif
+
+#if defined(TQ_WS_MAC)
+ bool do_mouse_down(Point *, bool *);
+ static TQMAC_PASCAL OStqStatus globalEventProcessor(EventHandlerCallRef, EventRef, void *);
+ static TQMAC_PASCAL OStqStatus globalAppleEventProcessor(const AppleEvent *, AppleEvent *, long);
+ static TQMAC_PASCAL void qt_context_timer_callbk(EventLoopTimerRef, void *);
+ static TQMAC_PASCAL void qt_select_timer_callbk(EventLoopTimerRef, void *);
+ static bool qt_mac_apply_settings();
+ friend class TQMacInputMethod;
+ friend TQMAC_PASCAL OStqStatus qt_window_event(EventHandlerCallRef, EventRef, void *);
+ friend void qt_mac_update_os_settings();
+ friend bool qt_set_socket_handler( int, int, TQObject *, bool);
+ friend void qt_mac_destroy_widget(TQWidget *);
+ friend void qt_init(int *, char **, TQApplication::Type);
+#endif
+
+#ifdef TQT_THREAD_SUPPORT
+ static TQMutex *qt_mutex;
+#endif // TQT_THREAD_SUPPORT
+
+ int app_argc;
+ char **app_argv;
+ bool quit_now;
+ int quit_code;
+ static TQStyle *app_style;
+ static int app_cspec;
+#ifndef TQT_NO_PALETTE
+ static TQPalette *app_pal;
+#endif
+ static TQFont *app_font;
+#ifndef TQT_NO_CURSOR
+ static TQCursor *app_cursor;
+#endif
+ static TQEventLoop* eventloop;
+ static int app_tracking;
+ static bool is_app_running;
+ static bool is_app_closing;
+ static bool app_exit_loop;
+ static int loop_level;
+ static TQWidget *main_widget;
+ static TQWidget *focus_widget;
+ static TQWidget *active_window;
+ static bool obey_desktop_settings;
+ static int cursor_flash_time;
+ static int mouse_double_click_time;
+ static int wheel_scroll_lines;
+ static int composedUnicode; // Value, meta-composed character
+
+ static bool animate_ui;
+ static bool animate_menu;
+ static bool animate_tooltip;
+ static bool animate_combo;
+ static bool fade_menu;
+ static bool fade_tooltip;
+ static bool animate_toolbox;
+ static bool widgetCount; // Coupled with -widgetcount switch
+ static bool metaComposeUnicode;
+
+ TQValueList<TQTranslator*> *translators;
+#ifndef TQT_NO_SESSIONMANAGER
+ TQSessionManager *session_manager;
+ TQString session_id;
+ static TQString* session_key;
+ bool is_session_restored;
+#endif
+#if defined(TQ_WS_X11) && !defined (TQT_NO_STYLE )
+ static void x11_initialize_style();
+#endif
+
+ static TQSize app_strut;
+#ifndef TQT_NO_COMPONENT
+ static TQStringList *app_libpaths;
+#endif
+ static TQAsciiDict<TQPalette> *app_palettes;
+ static TQAsciiDict<TQFont> *app_fonts;
+
+ static TQWidgetList *popupWidgets;
+ bool inPopupMode() const;
+ void closePopup( TQWidget *popup );
+ void openPopup( TQWidget *popup );
+ void setActiveWindow( TQWidget* act );
+
+ static bool sendSpontaneousEvent( TQObject *receiver, TQEvent *event );
+ static void removePostedEvent( TQEvent * );
+
+ friend class TQWidget;
+ friend class TQETWidget;
+ friend class TQDialog;
+ friend class TQAccelManager;
+ friend class TQEvent;
+ friend class TQTranslator;
+ friend class TQEventLoop;
+ friend TQ_EXPORT void qt_ucm_initialize( TQApplication * );
+#if defined(TQ_WS_WIN)
+ friend bool qt_sendSpontaneousEvent( TQObject*, TQEvent* );
+#endif
+#if defined(TQ_WS_TQWS)
+ friend class TQInputContext;
+#endif
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQApplication( const TQApplication & );
+ TQApplication &operator=( const TQApplication & );
+#endif
+};
+
+inline int TQApplication::argc() const
+{
+ return app_argc;
+}
+
+inline char **TQApplication::argv() const
+{
+ return app_argv;
+}
+
+#if defined(TQ_WS_TQWS)
+inline void TQApplication::setArgs(int c, char **v)
+{
+ app_argc = c;
+ app_argv = v;
+}
+#endif
+
+#ifndef TQT_NO_CURSOR
+inline TQCursor *TQApplication::overrideCursor()
+{
+ return app_cursor;
+}
+#endif
+inline bool TQApplication::hasGlobalMouseTracking()
+{
+ return app_tracking > 0;
+}
+
+inline TQWidget *TQApplication::mainWidget() const
+{
+ return main_widget;
+}
+
+inline TQWidget *TQApplication::tqfocusWidget() const
+{
+ return focus_widget;
+}
+
+inline TQWidget *TQApplication::activeWindow() const
+{
+ return active_window;
+}
+
+inline TQWidget *TQApplication::widgetAt( const TQPoint &p, bool child )
+{
+ return widgetAt( p.x(), p.y(), child );
+}
+
+inline bool TQApplication::inPopupMode() const
+{
+ return popupWidgets != 0;
+}
+#ifndef TQT_NO_SESSIONMANAGER
+inline bool TQApplication::isSessionRestored() const
+{
+ return is_session_restored;
+}
+
+inline TQString TQApplication::sessionId() const
+{
+ return session_id;
+}
+
+inline TQString TQApplication::sessionKey() const
+{
+ return session_key ? *session_key : TQString::null;
+}
+#endif
+inline TQSize TQApplication::globalStrut()
+{
+ return app_strut;
+}
+
+inline bool TQApplication::sendEvent( TQObject *receiver, TQEvent *event )
+{ if ( event ) event->spont = FALSE; return tqApp ? tqApp->notify( receiver, event ) : FALSE; }
+
+inline bool TQApplication::sendSpontaneousEvent( TQObject *receiver, TQEvent *event )
+{ if ( event ) event->spont = TRUE; return tqApp ? tqApp->notify( receiver, event ) : FALSE; }
+
+#ifdef TQT_NO_TRANSLATION
+// Simple versions
+inline TQString TQApplication::translate( const char *, const char *sourceText,
+ const char *, Encoding encoding ) const
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( encoding == UnicodeUTF8 )
+ return TQString::fromUtf8( sourceText );
+ else
+#endif
+ return TQString::tqfromLatin1( sourceText );
+}
+#endif
+
+inline int TQApplication::horizontalAlignment( int align )
+{
+ align &= AlignHorizontal_Mask;
+ if ( align == AlignAuto ) {
+ if ( reverseLayout() )
+ align = AlignRight;
+ else
+ align = AlignLeft;
+ }
+ return align;
+}
+
+#endif // TQAPPLICATION_H
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqapplication_p.h b/tqtinterface/qt4/src/kernel/tqapplication_p.h
new file mode 100644
index 0000000..cbedae7
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqapplication_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Definition of some TQt private functions.
+**
+** Created : 000228
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQAPPLICATION_P_H
+#define TQAPPLICATION_P_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp, qcolor_x11.cpp, qfiledialog.cpp
+// and many other. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#endif // TQT_H
+
+class TQWidget;
+class TQObject;
+class TQClipboard;
+class TQKeyEvent;
+class TQMouseEvent;
+class TQWheelEvent;
+
+extern TQ_EXPORT bool qt_modal_state();
+extern TQ_EXPORT void qt_enter_modal( TQWidget* );
+extern TQ_EXPORT void qt_leave_modal( TQWidget* );
+
+extern bool qt_is_gui_used;
+#ifndef TQT_NO_CLIPBOARD
+extern TQClipboard *qt_clipboard;
+#endif
+
+#if defined (TQ_OS_WIN32) || defined (TQ_OS_CYGWIN)
+extern TQt::WindowsVersion qt_winver;
+const int TQT_TABLET_NPACKETQSIZE = 128;
+# ifdef TQ_OS_TEMP
+ extern DWORD qt_cever;
+# endif
+#elif defined (TQ_OS_MAC)
+extern TQt::MacintoshVersion qt_macver;
+#endif
+
+#if defined (TQ_WS_X11)
+extern int qt_ncols_option;
+#endif
+
+
+extern void qt_dispatchEnterLeave( TQWidget*, TQWidget* );
+extern bool qt_tryModalHelper( TQWidget *, TQWidget ** = 0 );
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqapplication_x11.cpp b/tqtinterface/qt4/src/kernel/tqapplication_x11.cpp
new file mode 100644
index 0000000..48616bf
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqapplication_x11.cpp
@@ -0,0 +1,8984 @@
+/****************************************************************************
+**
+** Implementation of X11 startup routines and event handling
+**
+** Created : 931029
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// ### 4.0: examine TQ_EXPORT's below. The respective symbols had all
+// been in use (e.g. in the KDE wm ) before the introduction of a version
+// map. One might want to turn some of them into propert public API and
+// provide a proper alternative for others. See also the exports in
+// qapplication_win.cpp which suggest a unification.
+
+// ### needed for solaris-g++ in beta5
+#define TQT_CLEAN_NAMESPACE
+
+#include "tqplatformdefs.h"
+
+// POSIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
+#if defined(connect)
+# undef connect
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+#include "tqapplication.h"
+#include "tqapplication_p.h"
+#include "tqcolor_p.h"
+#include "tqcursor.h"
+#include "tqwidget.h"
+#include "tqwidget_p.h"
+#include "tqobjectlist.h"
+#include "tqwidgetlist.h"
+#include "tqwidgetintdict.h"
+#include "tqbitarray.h"
+#include "tqpainter.h"
+#include "tqpixmapcache.h"
+#include "tqdatetime.h"
+#include "tqtextcodec.h"
+#include "tqdatastream.h"
+#include "tqbuffer.h"
+#include "tqsocketnotifier.h"
+#include "tqsessionmanager.h"
+#include "tqvaluelist.h"
+#include "tqdict.h"
+#include "tqguardedptr.h"
+#include "tqclipboard.h"
+#include "tqwhatsthis.h" // ######## dependency
+#include "tqsettings.h"
+#include "tqstylefactory.h"
+#include "tqfileinfo.h"
+
+// Input method stuff - UNFINISHED
+#include "tqinputcontext_p.h"
+#include "tqinternal_p.h" // shared double buffer cleanup
+
+#if defined(TQT_THREAD_SUPPORT)
+# include "tqthread.h"
+#endif
+
+#if defined(TQT_DEBUG) && defined(TQ_OS_LINUX)
+# include "tqfile.h"
+#endif
+
+#include "tqt_x11_p.h"
+
+#if !defined(TQT_NO_XFTFREETYPE)
+// XFree86 4.0.3 implementation is missing XftInitFtLibrary forward
+extern "C" Bool XftInitFtLibrary(void);
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <locale.h>
+
+//#define X_NOT_BROKEN
+#ifdef X_NOT_BROKEN
+// Some X libraries are built with setlocale #defined to _Xsetlocale,
+// even though library users are then built WITHOUT such a definition.
+// This creates a problem - TQt might setlocale() one value, but then
+// X looks and doesn't see the value TQt set. The solution here is to
+// implement _Xsetlocale just in case X calls it - redirecting it to
+// the real libC version.
+//
+# ifndef setlocale
+extern "C" char *_Xsetlocale(int category, const char *locale);
+char *_Xsetlocale(int category, const char *locale)
+{
+ //qDebug("_Xsetlocale(%d,%s),category,locale");
+ return setlocale(category,locale);
+}
+# endif // setlocale
+#endif // X_NOT_BROKEN
+
+
+// resolve the conflict between X11's FocusIn and TQEvent::FocusIn
+const int XFocusOut = FocusOut;
+const int XFocusIn = FocusIn;
+#undef FocusOut
+#undef FocusIn
+
+const int XKeyPress = KeyPress;
+const int XKeyRelease = KeyRelease;
+#undef KeyPress
+#undef KeyRelease
+
+
+// Fix old X libraries
+#ifndef XK_KP_Home
+#define XK_KP_Home 0xFF95
+#endif
+#ifndef XK_KP_Left
+#define XK_KP_Left 0xFF96
+#endif
+#ifndef XK_KP_Up
+#define XK_KP_Up 0xFF97
+#endif
+#ifndef XK_KP_Right
+#define XK_KP_Right 0xFF98
+#endif
+#ifndef XK_KP_Down
+#define XK_KP_Down 0xFF99
+#endif
+#ifndef XK_KP_Prior
+#define XK_KP_Prior 0xFF9A
+#endif
+#ifndef XK_KP_Next
+#define XK_KP_Next 0xFF9B
+#endif
+#ifndef XK_KP_End
+#define XK_KP_End 0xFF9C
+#endif
+#ifndef XK_KP_Insert
+#define XK_KP_Insert 0xFF9E
+#endif
+#ifndef XK_KP_Delete
+#define XK_KP_Delete 0xFF9F
+#endif
+
+#ifdef USE_QT4
+
+/*****************************************************************************
+ Internal variables and functions
+ *****************************************************************************/
+static const char *appName; // application name
+static const char *appClass; // application class
+static const char *appFont = 0; // application font
+static const char *appBGCol = 0; // application bg color
+static const char *appFGCol = 0; // application fg color
+static const char *appBTNCol = 0; // application btn color
+static const char *mwGeometry = 0; // main widget tqgeometry
+static const char *mwTitle = 0; // main widget title
+//Ming-Che 10/10
+static char *ximServer = 0; // XIM Server will connect to
+static bool mwIconic = FALSE; // main widget iconified
+//Ming-Che 10/10
+static bool noxim = FALSE; // connect to xim or not
+// static Display *appDpy = 0; // X11 application display
+static char *appDpyName = 0; // X11 display name
+static bool appForeignDpy = FALSE; // we didn't create display
+static bool appSync = FALSE; // X11 synchronization
+#if defined(TQT_DEBUG)
+static bool appNoGrab = FALSE; // X11 grabbing enabled
+static bool appDoGrab = FALSE; // X11 grabbing override (gdb)
+#endif
+// static int appScreen; // X11 screen number
+static int appScreenCount; // X11 screen count
+static bool app_save_rootinfo = FALSE; // save root info
+static bool app_do_modal = FALSE; // modal mode
+static Window curWin = 0; // current window
+
+static GC* app_gc_ro = 0; // read-only GC
+static GC* app_gc_tmp = 0; // temporary GC
+static GC* app_gc_ro_m = 0; // read-only GC (monochrome)
+static GC* app_gc_tmp_m = 0; // temporary GC (monochrome)
+// symbols needed by extern TQXEmbed class
+TQ_EXPORT Atom qt_wm_protocols = 0; // window manager protocols
+TQ_EXPORT Atom qt_wm_delete_window = 0; // delete window protocol
+TQ_EXPORT Atom qt_wm_take_focus = 0; // take focus window protocol
+
+Atom qt_qt_scrolldone = 0; // scroll synchronization
+Atom qt_net_wm_context_help = 0; // context help
+Atom qt_net_wm_ping = 0; // _NET_WM_PING protocol
+
+static Atom qt_xsetroot_id = 0;
+Atom qt_xa_clipboard = 0;
+Atom qt_selection_property = 0;
+Atom qt_clipboard_sentinel = 0;
+Atom qt_selection_sentinel = 0;
+TQ_EXPORT Atom qt_wm_state = 0;
+Atom qt_wm_change_state = 0;
+static Atom qt_settings_timestamp = 0; // TQt >=3 settings timestamp
+static Atom qt_input_encoding = 0; // TQt desktop properties
+static Atom qt_resource_manager = 0; // X11 Resource manager
+Atom qt_sizegrip = 0; // sizegrip
+Atom qt_wm_client_leader = 0;
+TQ_EXPORT Atom qt_window_role = 0;
+TQ_EXPORT Atom qt_sm_client_id = 0;
+Atom qt_xa_motif_wm_hints = 0;
+Atom qt_cde_running = 0;
+Atom qt_kwin_running = 0;
+Atom qt_kwm_running = 0;
+Atom qt_gbackground_properties = 0;
+Atom qt_x_incr = 0;
+Atom qt_utf8_string = 0;
+
+// detect broken window managers
+Atom qt_sgi_desks_manager = 0;
+bool qt_broken_wm = FALSE;
+static void qt_detect_broken_window_manager();
+
+// NET WM support
+Atom qt_net_supported = 0;
+Atom qt_net_wm_name = 0;
+Atom qt_net_wm_icon_name = 0;
+Atom qt_net_virtual_roots = 0;
+Atom qt_net_workarea = 0;
+Atom qt_net_wm_state = 0;
+Atom qt_net_wm_state_modal = 0;
+Atom qt_net_wm_state_max_v = 0;
+Atom qt_net_wm_state_max_h = 0;
+Atom qt_net_wm_state_fullscreen = 0;
+Atom qt_net_wm_state_above = 0;
+Atom qt_net_wm_window_type = 0;
+Atom qt_net_wm_window_type_normal = 0;
+Atom qt_net_wm_window_type_dialog = 0;
+Atom qt_net_wm_window_type_toolbar = 0;
+Atom qt_net_wm_window_type_menu = 0;
+Atom qt_net_wm_window_type_utility = 0;
+Atom qt_net_wm_window_type_splash = 0;
+Atom qt_net_wm_window_type_override = 0; // KDE extension
+Atom qt_net_wm_frame_strut = 0; // KDE extension
+Atom qt_net_wm_state_stays_on_top = 0; // KDE extension
+Atom qt_net_wm_pid = 0;
+Atom qt_net_wm_user_time = 0;
+// Enlightenment support
+Atom qt_enlightenment_desktop = 0;
+
+// window managers list of supported "stuff"
+Atom *qt_net_supported_list = 0;
+// list of virtual root windows
+Window *qt_net_virtual_root_list = 0;
+
+
+
+// client leader window
+Window qt_x11_wm_client_leader = 0;
+
+// function to update the workarea of the screen - in qdesktopwidget_x11.cpp
+extern void qt_desktopwidget_update_workarea();
+
+// current focus model
+static const int FocusModel_Unknown = -1;
+static const int FocusModel_Other = 0;
+static const int FocusModel_PointerRoot = 1;
+static int qt_focus_model = -1;
+
+#ifndef TQT_NO_XRANDR
+// TRUE if TQt is compiled w/ XRandR support and XRandR exists on the connected
+// Display
+bool qt_use_xrandr = FALSE;
+static int xrandr_eventbase;
+#endif
+
+// TRUE if TQt is compiled w/ XRender support and XRender exists on the connected
+// Display
+TQ_EXPORT bool qt_use_xrender = FALSE;
+
+// modifier masks for alt/meta - detected when the application starts
+static long qt_alt_mask = 0;
+static long qt_meta_mask = 0;
+// modifier tqmask to remove mode switch from modifiers that have alt/meta set
+// this problem manifests itself on HP/UX 10.20 at least, and without it
+// modifiers do not work at all...
+static long qt_mode_switch_remove_mask = 0;
+
+// flags for extensions for special Languages, currently only for RTL languages
+static bool qt_use_rtl_extensions = FALSE;
+bool qt_hebrew_keyboard_hack = FALSE;
+
+static Window mouseActWindow = 0; // window where mouse is
+static int mouseButtonPressed = 0; // last mouse button pressed
+static int mouseButtonState = 0; // mouse button state
+static Time mouseButtonPressTime = 0; // when was a button pressed
+static short mouseXPos, mouseYPos; // mouse pres position in act window
+static short mouseGlobalXPos, mouseGlobalYPos; // global mouse press position
+
+extern TQWidgetList *qt_modal_stack; // stack of modal widgets
+static bool ignoreNextMouseReleaseEvent = FALSE; // ignore the next mouse release
+ // event if return from a modal
+ // widget
+
+static TQWidget *popupButtonFocus = 0;
+static TQWidget *popupOfPopupButtonFocus = 0;
+static bool popupCloseDownMode = FALSE;
+static bool popupGrabOk;
+
+static bool sm_blockUserInput = FALSE; // session management
+
+int qt_xfocusout_grab_counter = 0;
+
+#if defined (TQT_TABLET_SUPPORT)
+// since XInput event classes aren't created until we actually open an XInput
+// tqdevice, here is a static list that we will use later on...
+const int INVALID_EVENT = -1;
+const int TOTAL_XINPUT_EVENTS = 7;
+
+XDevice *devStylus = NULL;
+XDevice *devEraser = NULL;
+XEventClass event_list_stylus[TOTAL_XINPUT_EVENTS];
+XEventClass event_list_eraser[TOTAL_XINPUT_EVENTS];
+
+int qt_curr_events_stylus = 0;
+int qt_curr_events_eraser = 0;
+
+// well, luckily we only need to do this once.
+static int xinput_motion = INVALID_EVENT;
+static int xinput_key_press = INVALID_EVENT;
+static int xinput_key_release = INVALID_EVENT;
+static int xinput_button_press = INVALID_EVENT;
+static int xinput_button_release = INVALID_EVENT;
+
+// making this assumption on XFree86, since we can only use 1 tqdevice,
+// the pressure for the eraser and the stylus should be the same, if they aren't
+// well, they certainly have a strange pen then...
+static int max_pressure;
+extern bool chokeMouse;
+#endif
+
+// last timestamp read from TQSettings
+static uint appliedstamp = 0;
+
+
+typedef int (*QX11EventFilter) (XEvent*);
+QX11EventFilter qt_set_x11_event_filter(QX11EventFilter filter);
+
+static QX11EventFilter qt_x11_event_filter = 0;
+TQ_EXPORT QX11EventFilter qt_set_x11_event_filter(QX11EventFilter filter)
+{
+ QX11EventFilter old_filter = qt_x11_event_filter;
+ qt_x11_event_filter = filter;
+ return old_filter;
+}
+static bool qt_x11EventFilter( XEvent* ev )
+{
+ if ( qt_x11_event_filter && qt_x11_event_filter( ev ) )
+ return TRUE;
+ return tqApp->x11EventFilter( ev );
+}
+
+#if !defined(TQT_NO_XIM)
+XIM qt_xim = 0;
+XIMStyle qt_xim_style = 0;
+static XIMStyle xim_default_style = XIMPreeditCallbacks | XIMStatusNothing;
+static XIMStyle xim_preferred_style = 0;
+#endif
+
+static int composingKeycode=0;
+static TQTextCodec * input_mapper = 0;
+
+extern bool qt_check_clipboard_sentinel(); //def in qclipboard_x11.cpp
+extern bool qt_check_selection_sentinel(); //def in qclipboard_x11.cpp
+
+static void qt_save_rootinfo();
+bool qt_try_modal( TQWidget *, XEvent * );
+
+int qt_ncols_option = 216; // used in qcolor_x11.cpp
+int qt_visual_option = -1;
+bool qt_cmap_option = FALSE;
+TQWidget *qt_button_down = 0; // widget got last button-down
+
+extern bool qt_tryAccelEvent( TQWidget*, TQKeyEvent* ); // def in qaccel.cpp
+
+struct TQScrollInProgress {
+ static long serial;
+ TQScrollInProgress( TQWidget* w, int x, int y ) :
+ id( serial++ ), scrolled_widget( w ), dx( x ), dy( y ) {}
+ long id;
+ TQWidget* scrolled_widget;
+ int dx, dy;
+};
+long TQScrollInProgress::serial=0;
+static TQPtrList<TQScrollInProgress> *sip_list = 0;
+
+
+// stuff in qt_xdnd.cpp
+// setup
+extern void qt_xdnd_setup();
+// x event handling
+extern void qt_handle_xdnd_enter( TQWidget *, const XEvent *, bool );
+extern void qt_handle_xdnd_position( TQWidget *, const XEvent *, bool );
+extern void qt_handle_xdnd_status( TQWidget *, const XEvent *, bool );
+extern void qt_handle_xdnd_leave( TQWidget *, const XEvent *, bool );
+extern void qt_handle_xdnd_drop( TQWidget *, const XEvent *, bool );
+extern void qt_handle_xdnd_finished( TQWidget *, const XEvent *, bool );
+extern void qt_xdnd_handle_selection_request( const XSelectionRequestEvent * );
+extern bool qt_xdnd_handle_badwindow();
+
+extern void qt_motifdnd_handle_msg( TQWidget *, const XEvent *, bool );
+extern void qt_x11_motifdnd_init();
+
+// client message atoms
+extern Atom qt_xdnd_enter;
+extern Atom qt_xdnd_position;
+extern Atom qt_xdnd_status;
+extern Atom qt_xdnd_leave;
+extern Atom qt_xdnd_drop;
+extern Atom qt_xdnd_finished;
+// xdnd selection atom
+extern Atom qt_xdnd_selection;
+extern bool qt_xdnd_dragging;
+
+// gui or non-gui from qapplication.cpp
+extern bool qt_is_gui_used;
+extern bool qt_app_has_font;
+
+static bool qt_x11_cmdline_font = false;
+
+
+extern bool qt_resolve_symlinks; // from qapplication.cpp
+
+// Paint event clipping magic
+extern void qt_set_paintevent_clipping( TQPaintDevice* dev, const TQRegion& region);
+extern void qt_clear_paintevent_clipping();
+
+
+// Palette handling
+extern TQPalette *qt_std_pal;
+extern void qt_create_std_palette();
+
+void qt_x11_intern_atom( const char *, Atom * );
+
+static TQPtrList<TQWidget>* deferred_map_list = 0;
+static void qt_deferred_map_cleanup()
+{
+ delete deferred_map_list;
+ deferred_map_list = 0;
+}
+void qt_deferred_map_add( TQWidget* w)
+{
+ if ( !deferred_map_list ) {
+ deferred_map_list = new TQPtrList<TQWidget>;
+ qAddPostRoutine( qt_deferred_map_cleanup );
+ }
+ deferred_map_list->append( w );
+}
+void qt_deferred_map_take( TQWidget* w )
+{
+ if (deferred_map_list ) {
+ deferred_map_list->remove( w );
+ }
+}
+bool qt_deferred_map_tqcontains( TQWidget* w )
+{
+ if (!deferred_map_list)
+ return FALSE;
+ else
+ return deferred_map_list->tqcontains( w );
+}
+
+/*****************************************************************************
+ Default X error handlers
+ *****************************************************************************/
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static bool x11_ignore_badwindow;
+static bool x11_badwindow;
+
+ // starts to ignore bad window errors from X
+void qt_ignore_badwindow()
+{
+ x11_ignore_badwindow = TRUE;
+ x11_badwindow = FALSE;
+}
+
+ // ends ignoring bad window errors and returns whether an error
+ // had happen.
+bool qt_badwindow()
+{
+ x11_ignore_badwindow = FALSE;
+ return x11_badwindow;
+}
+
+static int (*original_x_errhandler)( Display *dpy, XErrorEvent * );
+static int (*original_xio_errhandler)( Display *dpy );
+
+static int qt_x_errhandler( Display *dpy, XErrorEvent *err )
+{
+ if ( err->error_code == BadWindow ) {
+ x11_badwindow = TRUE;
+ if ( err->request_code == 25 /* X_SendEvent */ &&
+ qt_xdnd_handle_badwindow() )
+ return 0;
+ if ( x11_ignore_badwindow )
+ return 0;
+ } else if ( err->error_code == BadMatch &&
+ err->request_code == 42 /* X_SetInputFocus */ ) {
+ return 0;
+ }
+
+ char errstr[256];
+ XGetErrorText( dpy, err->error_code, errstr, 256 );
+ qWarning( "X Error: %s %d\n"
+ " Major opcode: %d\n"
+ " Minor opcode: %d\n"
+ " Resource id: 0x%lx",
+ errstr, err->error_code,
+ err->request_code,
+ err->minor_code,
+ err->resourceid );
+
+ // ### we really should distinguish between severe, non-severe and
+ // ### application specific errors
+
+ return 0;
+}
+
+
+static int qt_xio_errhandler( Display * )
+{
+ qWarning( "%s: Fatal IO error: client killed", appName );
+ tqApp = 0;
+ exit( 1 );
+ //### give the application a chance for a proper shutdown instead,
+ //### exit(1) doesn't help.
+ return 0;
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+// Memory leak: if the app exits before qt_init_internal(), this dict
+// isn't released correctly.
+static TQAsciiDict<Atom> *atoms_to_be_created = 0;
+static bool create_atoms_now = 0;
+
+/*****************************************************************************
+ qt_x11_intern_atom() - efficiently interns an atom, now or later.
+
+ If the application is being initialized, this function stores the
+ adddress of the atom and qt_init_internal will do the actual work
+ quickly. If the application is running, the atom is created here.
+
+ Neither argument may point to temporary variables.
+ *****************************************************************************/
+
+void qt_x11_intern_atom( const char *name, Atom *result)
+{
+ if ( !name || !result || *result )
+ return;
+
+ if ( create_atoms_now ) {
+ *result = XInternAtom( QX11Info::display(), name, False );
+ } else {
+ if ( !atoms_to_be_created ) {
+ atoms_to_be_created = new TQAsciiDict<Atom>;
+ atoms_to_be_created->setAutoDelete( FALSE );
+ }
+ atoms_to_be_created->insert( name, result );
+ *result = 0;
+ }
+}
+
+
+static void qt_x11_process_intern_atoms()
+{
+ if ( atoms_to_be_created ) {
+#if defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 6)
+ int i = atoms_to_be_created->count();
+ Atom * res = (Atom *)malloc( i * sizeof( Atom ) );
+ Atom ** resp = (Atom **)malloc( i * sizeof( Atom* ) );
+ char ** names = (char **)malloc( i * sizeof(const char*));
+
+ i = 0;
+ TQAsciiDictIterator<Atom> it( *atoms_to_be_created );
+ while( it.current() ) {
+ res[i] = 0;
+ resp[i] = it.current();
+ names[i] = qstrdup(it.currentKey());
+ i++;
+ ++it;
+ }
+ XInternAtoms( QX11Info::display(), names, i, False, res );
+ while( i ) {
+ i--;
+ delete [] names[i];
+ if ( res[i] && resp[i] )
+ *(resp[i]) = res[i];
+ }
+ free( res );
+ free( resp );
+ free( names );
+#else
+ TQAsciiDictIterator<Atom> it( *atoms_to_be_created );
+ Atom * result;
+ const char * name;
+ while( (result = it.current()) != 0 ) {
+ name = it.currentKey();
+ ++it;
+ *result = XInternAtom( QX11Info::display(), name, False );
+ }
+#endif
+ delete atoms_to_be_created;
+ atoms_to_be_created = 0;
+ create_atoms_now = TRUE;
+ }
+}
+
+Display *qt_xdisplay() // get current X display
+{
+// return appDpy;
+ return QX11Info::display();
+}
+
+int qt_xscreen() // get current X screen
+{
+ return QX11Info::appScreen();
+}
+
+void applyX11SpecificCommandLineArguments(QWidget *main_widget)
+{
+ static bool beenHereDoneThat = false;
+ if (beenHereDoneThat)
+ return;
+ beenHereDoneThat = true;
+ if (!main_widget->testAttribute(Qt::WA_WState_Created)) {
+ printf("[WARNING] Attempted to set uncreated main widget!\n\r");
+ return;
+ }
+ Q_ASSERT(main_widget->testAttribute(Qt::WA_WState_Created));
+ if (mwTitle) {
+ XStoreName(qt_xdisplay(), main_widget->effectiveWinId(), (char*)mwTitle);
+ QByteArray net_wm_name = QString::fromLocal8Bit(mwTitle).toUtf8();
+ XChangeProperty(qt_xdisplay(), main_widget->effectiveWinId(), qt_net_wm_name, qt_utf8_string, 8,
+ PropModeReplace, (unsigned char *)net_wm_name.data(), net_wm_name.size());
+ }
+ if (mwGeometry) { // parse geometry
+ int x, y;
+ int w, h;
+ int m = XParseGeometry((char*)mwGeometry, &x, &y, (uint*)&w, (uint*)&h);
+ QSize minSize = main_widget->minimumSize();
+ QSize maxSize = main_widget->maximumSize();
+ if ((m & XValue) == 0)
+ x = main_widget->geometry().x();
+ if ((m & YValue) == 0)
+ y = main_widget->geometry().y();
+ if ((m & WidthValue) == 0)
+ w = main_widget->width();
+ if ((m & HeightValue) == 0)
+ h = main_widget->height();
+ w = qMin(w,maxSize.width());
+ h = qMin(h,maxSize.height());
+ w = qMax(w,minSize.width());
+ h = qMax(h,minSize.height());
+ if ((m & XNegative)) {
+ x = QApplication::desktop()->width() + x - w;
+ }
+ if ((m & YNegative)) {
+ y = QApplication::desktop()->height() + y - h;
+ }
+ main_widget->setGeometry(x, y, w, h);
+ }
+}
+
+void TQApplication::setMainWidget(QWidget *mainWidget)
+{
+// #ifndef QT_NO_DEBUG
+// if (mainWidget && mainWidget->parentWidget() && mainWidget->isWindow())
+// qWarning("QApplication::setMainWidget: New main widget (%s/%s) "
+// "has a parent",
+// mainWidget->metaObject()->className(), mainWidget->objectName().toLocal8Bit().constData());
+// #endif
+// if (mainWidget)
+// mainWidget->d_func()->createWinId();
+// QApplicationPrivate::main_widget = mainWidget;
+// if (QApplicationPrivate::main_widget) // give WM command line
+// QApplicationPrivate::applyX11SpecificCommandLineArguments(QApplicationPrivate::main_widget);
+
+ if (mainWidget)
+ mainWidget->effectiveWinId();
+ current_app_main_widget = mainWidget;
+ if (current_app_main_widget) // give WM command line
+ applyX11SpecificCommandLineArguments(current_app_main_widget);
+
+ // Is this needed?
+ connect(mainWidget, SIGNAL(destroyed(QObject*)), this, SLOT(quit()));
+}
+
+// ************************************************************************
+// X Input Method support
+// ************************************************************************
+
+#if !defined(TQT_NO_XIM)
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif // TQ_C_CALLBACKS
+
+#ifdef USE_X11R6_XIM
+ static void xim_create_callback(XIM /*im*/,
+ XPointer /*client_data*/,
+ XPointer /*call_data*/)
+ {
+ // qDebug("xim_create_callback");
+ TQApplication::create_xim();
+ }
+
+ static void xim_destroy_callback(XIM /*im*/,
+ XPointer /*client_data*/,
+ XPointer /*call_data*/)
+ {
+ // qDebug("xim_destroy_callback");
+ TQApplication::close_xim();
+ XRegisterIMInstantiateCallback(QX11Info::display(), 0, 0, 0,
+ (XIMProc) xim_create_callback, 0);
+ }
+
+#endif // USE_X11R6_XIM
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif // TQ_C_CALLBACKS
+
+#endif // TQT_NO_XIM
+
+// read the _TQT_INPUT_ENCODING property and apply the settings to
+// the application
+static void qt_set_input_encoding()
+{
+ Atom type;
+ int format;
+ ulong nitems, after = 1;
+ const char *data;
+
+ int e = XGetWindowProperty( QX11Info::display(), TQPaintDevice::x11AppRootWindow(),
+ qt_input_encoding, 0, 1024,
+ False, XA_STRING, &type, &format, &nitems,
+ &after, (unsigned char**)&data );
+ if ( e != Success || !nitems || type == None ) {
+ // Always use the locale codec, since we have no examples of non-local
+ // XIMs, and since we cannot get a sensible answer about the encoding
+ // from the XIM.
+ input_mapper = TQTextCodec::codecForLocale();
+
+ } else {
+ if ( !qstricmp( data, "locale" ) )
+ input_mapper = TQTextCodec::codecForLocale();
+ else
+ input_mapper = TQTextCodec::codecForName( data );
+ // make sure we have an input codec
+ if( !input_mapper )
+ input_mapper = TQTextCodec::codecForName( "ISO 8859-1" );
+ }
+ if ( input_mapper->mibEnum() == 11 ) // 8859-8
+ input_mapper = TQTextCodec::codecForName( "ISO 8859-8-I");
+ if( data )
+ XFree( (char *)data );
+}
+
+bool qt_net_supports(Atom atom)
+{
+ if (! qt_net_supported_list)
+ return FALSE;
+
+ bool supported = FALSE;
+ int i = 0;
+ while (qt_net_supported_list[i] != 0) {
+ if (qt_net_supported_list[i++] == atom) {
+ supported = TRUE;
+ break;
+ }
+ }
+
+ return supported;
+}
+
+// update the virtual roots array
+void qt_get_net_virtual_roots()
+{
+ if (qt_net_virtual_root_list)
+ delete [] qt_net_virtual_root_list;
+ qt_net_virtual_root_list = 0;
+
+ if (! qt_net_supports(qt_net_virtual_roots))
+ return;
+
+ Atom type;
+ int format;
+ long offset = 0;
+ unsigned long nitems, after;
+ unsigned char *data;
+
+ int e = XGetWindowProperty(QX11Info::display(), TQPaintDevice::x11AppRootWindow(),
+ qt_net_virtual_roots, 0, 0,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+ if (data)
+ XFree(data);
+
+ if (e == Success && type == XA_ATOM && format == 32) {
+ TQBuffer ts;
+ ts.open(IO_WriteOnly);
+
+ while (after > 0) {
+ XGetWindowProperty(QX11Info::display(), TQPaintDevice::x11AppRootWindow(),
+ qt_net_virtual_roots, offset, 1024,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+
+ if (type == XA_ATOM && format == 32) {
+ TQT_TQIODEVICE_OBJECT(ts).writeBlock((const char *) data, nitems * 4);
+ offset += nitems;
+ } else
+ after = 0;
+ if (data)
+ XFree(data);
+ }
+
+ // compute nitems
+ TQByteArray buffer(TQT_TQBYTEARRAY_OBJECT(ts.buffer()));
+ nitems = buffer.size() / sizeof(Window);
+ qt_net_virtual_root_list = new Window[nitems + 1];
+ Window *a = (Window *) buffer.data();
+ uint i;
+ for (i = 0; i < nitems; i++)
+ qt_net_virtual_root_list[i] = a[i];
+ qt_net_virtual_root_list[nitems] = 0;
+ }
+}
+
+/*
+ Returns a truecolor visual (if there is one). 8-bit TrueColor visuals
+ are ignored, unless the user has explicitly requested -visual TrueColor.
+ The SGI X server usually has an 8 bit default visual, but the application
+ can also ask for a truecolor visual. This is what we do if
+ TQApplication::colorSpec() is TQApplication::ManyColor.
+*/
+
+static Visual *tqfind_truecolor_visual( Display *dpy, int scr, int *depth, int *ncols )
+{
+ XVisualInfo *vi, rvi;
+ int best=0, n, i;
+ rvi.c_class = TrueColor;
+ rvi.screen = scr;
+ vi = XGetVisualInfo( dpy, VisualClassMask | VisualScreenMask,
+ &rvi, &n );
+ if ( vi ) {
+ for ( i=0; i<n; i++ ) {
+ if ( vi[i].depth > vi[best].depth )
+ best = i;
+ }
+ }
+ Visual *v = DefaultVisual(dpy,scr);
+ if ( !vi || (vi[best].visualid == XVisualIDFromVisual(v)) ||
+ (vi[best].depth <= 8 && qt_visual_option != TrueColor) )
+ {
+ *depth = DefaultDepth(dpy,scr);
+ *ncols = DisplayCells(dpy,scr);
+ } else {
+ v = vi[best].visual;
+ *depth = vi[best].depth;
+ *ncols = vi[best].colormap_size;
+ }
+ if ( vi )
+ XFree( (char *)vi );
+ return v;
+}
+
+// update the supported array
+void qt_get_net_supported()
+{
+ Atom type;
+ int format;
+ long offset = 0;
+ unsigned long nitems, after;
+ unsigned char *data = 0;
+
+ int e = XGetWindowProperty(QX11Info::display(), TQPaintDevice::x11AppRootWindow(),
+ qt_net_supported, 0, 0,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+ if (data)
+ XFree(data);
+
+ if (qt_net_supported_list)
+ delete [] qt_net_supported_list;
+ qt_net_supported_list = 0;
+
+ if (e == Success && type == XA_ATOM && format == 32) {
+ TQBuffer ts;
+ ts.open(IO_WriteOnly);
+
+ while (after > 0) {
+ XGetWindowProperty(QX11Info::display(), TQPaintDevice::x11AppRootWindow(),
+ qt_net_supported, offset, 1024,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+
+ if (type == XA_ATOM && format == 32) {
+ TQT_TQIODEVICE_OBJECT(ts).writeBlock((const char *) data, nitems * sizeof(long));
+ offset += nitems;
+ } else
+ after = 0;
+ if (data)
+ XFree(data);
+ }
+
+ // compute nitems
+ TQByteArray buffer(TQT_TQBYTEARRAY_OBJECT(ts.buffer()));
+ nitems = buffer.size() / sizeof(Atom);
+ qt_net_supported_list = new Atom[nitems + 1];
+ Atom *a = (Atom *) buffer.data();
+ uint i;
+ for (i = 0; i < nitems; i++)
+ qt_net_supported_list[i] = a[i];
+ qt_net_supported_list[nitems] = 0;
+ }
+}
+
+// set font, foreground and background from x11 resources. The
+// arguments may override the resource settings.
+static void qt_set_x11_resources( const char* font = 0, const char* fg = 0,
+ const char* bg = 0, const char* button = 0 )
+{
+ if ( !qt_std_pal )
+ qt_create_std_palette();
+
+ TQCString resFont, resFG, resBG, resEF, sysFont;
+
+ TQApplication::setEffectEnabled( Qt::UI_General, FALSE);
+ TQApplication::setEffectEnabled( Qt::UI_AnimateMenu, FALSE);
+ TQApplication::setEffectEnabled( Qt::UI_FadeMenu, FALSE);
+ TQApplication::setEffectEnabled( Qt::UI_AnimateCombo, FALSE );
+ TQApplication::setEffectEnabled( Qt::UI_AnimateTooltip, FALSE );
+ TQApplication::setEffectEnabled( Qt::UI_FadeTooltip, FALSE );
+ TQApplication::setEffectEnabled( Qt::UI_AnimateToolBox, FALSE );
+
+ if ( TQApplication::desktopSettingsAware() && !TQApplication::x11_apply_settings() ) {
+ int format;
+ ulong nitems, after = 1;
+ TQCString res;
+ long offset = 0;
+ Atom type = None;
+
+ while (after > 0) {
+ uchar *data;
+ XGetWindowProperty( QX11Info::display(), TQPaintDevice::x11AppRootWindow( 0 ),
+ qt_resource_manager,
+ offset, 8192, False, AnyPropertyType,
+ &type, &format, &nitems, &after,
+ &data );
+ res += (char*)data;
+ offset += 2048; // offset is in 32bit quantities... 8192/4 == 2048
+ if ( data )
+ XFree( (char *)data );
+ }
+
+ TQCString key, value;
+ int l = 0, r;
+ TQCString apn = appName;
+ TQCString apc = appClass;
+ int apnl = apn.length();
+ int apcl = apc.length();
+ int resl = res.length();
+
+ while (l < resl) {
+ r = res.tqfind( '\n', l );
+ if ( r < 0 )
+ r = resl;
+ while ( isspace((uchar) res[l]) )
+ l++;
+ bool mine = FALSE;
+ if ( res[l] == '*' &&
+ (res[l+1] == 'f' || res[l+1] == 'b' || res[l+1] == 'g' ||
+ res[l+1] == 'F' || res[l+1] == 'B' || res[l+1] == 'G' ||
+ res[l+1] == 's' || res[l+1] == 'S' ) ) {
+ // OPTIMIZED, since we only want "*[fbgs].."
+
+ TQCString item = res.mid( l, r - l ).simplifyWhiteSpace();
+ int i = item.tqfind( ":" );
+ key = item.left( i ).stripWhiteSpace().mid(1).lower();
+ value = item.right( item.length() - i - 1 ).stripWhiteSpace();
+ mine = TRUE;
+ } else if ( res[l] == appName[0] || (appClass && res[l] == appClass[0]) ) {
+ if (res.mid(l,apnl) == apn && (res[l+apnl] == '.' || res[l+apnl] == '*')) {
+ TQCString item = res.mid( l, r - l ).simplifyWhiteSpace();
+ int i = item.tqfind( ":" );
+ key = item.left( i ).stripWhiteSpace().mid(apnl+1).lower();
+ value = item.right( item.length() - i - 1 ).stripWhiteSpace();
+ mine = TRUE;
+ } else if (res.mid(l,apcl) == apc && (res[l+apcl] == '.' || res[l+apcl] == '*')) {
+ TQCString item = res.mid( l, r - l ).simplifyWhiteSpace();
+ int i = item.tqfind( ":" );
+ key = item.left( i ).stripWhiteSpace().mid(apcl+1).lower();
+ value = item.right( item.length() - i - 1 ).stripWhiteSpace();
+ mine = TRUE;
+ }
+ }
+
+ if ( mine ) {
+ if ( !font && key == "systemfont")
+ sysFont = value.left( value.tqfindRev(':') ).copy();
+ if ( !font && key == "font")
+ resFont = value.copy();
+ else if ( !fg && key == "foreground" )
+ resFG = value.copy();
+ else if ( !bg && key == "background")
+ resBG = value.copy();
+ else if ( key == "guieffects")
+ resEF = value.copy();
+ // NOTE: if you add more, change the [fbg] stuff above
+ }
+
+ l = r + 1;
+ }
+ }
+ if ( !sysFont.isEmpty() )
+ resFont = sysFont;
+ if ( resFont.isEmpty() )
+ resFont = font;
+ if ( resFG.isEmpty() )
+ resFG = fg;
+ if ( resBG.isEmpty() )
+ resBG = bg;
+// // [FIXME]
+// if ( (!qt_app_has_font || qt_x11_cmdline_font) && !resFont.isEmpty() ) { // set application font
+// TQFont fnt;
+// fnt.setRawName( resFont );
+//
+// // the font we get may actually be an alias for another font,
+// // so we reset the application font to the real font info.
+// if ( ! fnt.exactMatch() ) {
+// TQFontInfo fontinfo( fnt );
+// fnt.setFamily( fontinfo.family() );
+// fnt.setRawMode( fontinfo.rawMode() );
+//
+// if ( ! fnt.rawMode() ) {
+// fnt.setItalic( fontinfo.italic() );
+// fnt.setWeight( fontinfo.weight() );
+// fnt.setUnderline( fontinfo.underline() );
+// fnt.setStrikeOut( fontinfo.strikeOut() );
+// fnt.setStyleHint( fontinfo.tqstyleHint() );
+//
+// if ( fnt.pointSize() <= 0 && fnt.pixelSize() <= 0 )
+// // size is all wrong... fix it
+// fnt.setPointSize( (int) ( ( fontinfo.pixelSize() * 72. /
+// (float) TQPaintDevice::x11AppDpiY() ) +
+// 0.5 ) );
+// }
+// }
+//
+// if ( fnt != TQApplication::font() ) {
+// TQApplication::setFont( fnt, TRUE );
+// }
+// }
+
+ if ( button || !resBG.isEmpty() || !resFG.isEmpty() ) {// set app colors
+ TQColor btn;
+ TQColor bg;
+ TQColor fg;
+ if ( !resBG.isEmpty() )
+ bg = TQColor(TQString(resBG));
+ else
+ bg = qt_std_pal->active().background();
+ if ( !resFG.isEmpty() )
+ fg = TQColor(TQString(resFG));
+ else
+ fg = qt_std_pal->active().foreground();
+ if ( button )
+ btn = TQColor( button );
+ else if ( !resBG.isEmpty() )
+ btn = bg;
+ else
+ btn = qt_std_pal->active().button();
+
+ int h,s,v;
+ fg.hsv(&h,&s,&v);
+ TQColor base = TQt::white;
+ bool bright_mode = FALSE;
+ if (v >= 255-50) {
+ base = btn.dark(150);
+ bright_mode = TRUE;
+ }
+
+ TQColorGroup cg( fg, btn, btn.light(),
+ btn.dark(), btn.dark(150), fg, TQt::white, base, bg );
+ if (bright_mode) {
+ cg.setColor( TQColorGroup::HighlightedText, base );
+ cg.setColor( TQColorGroup::Highlight, TQt::white );
+ } else {
+ cg.setColor( TQColorGroup::HighlightedText, TQt::white );
+ cg.setColor( TQColorGroup::Highlight, TQt::darkBlue );
+ }
+ TQColor disabled( (fg.red()+btn.red())/2,
+ (fg.green()+btn.green())/2,
+ (fg.blue()+btn.blue())/2);
+ TQColorGroup dcg( disabled, btn, btn.light( 125 ), btn.dark(), btn.dark(150),
+ disabled, TQt::white, TQt::white, bg );
+ if (bright_mode) {
+ dcg.setColor( TQColorGroup::HighlightedText, base );
+ dcg.setColor( TQColorGroup::Highlight, TQt::white );
+ } else {
+ dcg.setColor( TQColorGroup::HighlightedText, TQt::white );
+ dcg.setColor( TQColorGroup::Highlight, TQt::darkBlue );
+ }
+ TQPalette pal( cg, dcg, cg );
+ if ( pal != *qt_std_pal && pal != TQApplication::palette() )
+ TQApplication::tqsetPalette( pal, TRUE );
+ *qt_std_pal = pal;
+ }
+
+ if ( !resEF.isEmpty() ) {
+ TQStringList effects = TQStringList::split(" ",resEF);
+ TQApplication::setEffectEnabled( Qt::UI_General, effects.tqcontains("general") );
+ TQApplication::setEffectEnabled( Qt::UI_AnimateMenu, effects.tqcontains("animatemenu") );
+ TQApplication::setEffectEnabled( Qt::UI_FadeMenu, effects.tqcontains("fademenu") );
+ TQApplication::setEffectEnabled( Qt::UI_AnimateCombo, effects.tqcontains("animatecombo") );
+ TQApplication::setEffectEnabled( Qt::UI_AnimateTooltip, effects.tqcontains("animatetooltip") );
+ TQApplication::setEffectEnabled( Qt::UI_FadeTooltip, effects.tqcontains("fadetooltip") );
+ TQApplication::setEffectEnabled( Qt::UI_AnimateToolBox, effects.tqcontains("animatetoolbox") );
+ }
+}
+
+static void qt_detect_broken_window_manager()
+{
+ Atom type;
+ int format;
+ ulong nitems, after;
+ uchar *data = 0;
+
+ // look for SGI's 4Dwm
+ int e = XGetWindowProperty(QX11Info::display(), TQPaintDevice::x11AppRootWindow(),
+ qt_sgi_desks_manager, 0, 1, False, XA_WINDOW,
+ &type, &format, &nitems, &after, &data);
+ if (data)
+ XFree(data);
+
+ if (e == Success && type == XA_WINDOW && format == 32 && nitems == 1 && after == 0) {
+ // detected SGI 4Dwm
+ qt_broken_wm = TRUE;
+ }
+}
+
+static GC create_gc( int scrn, bool monochrome )
+{
+ GC gc;
+ if ( monochrome ) {
+ Pixmap pm = XCreatePixmap( QX11Info::display(), RootWindow( QX11Info::display(), scrn ), 8, 8, 1 );
+ gc = XCreateGC( QX11Info::display(), pm, 0, 0 );
+ XFreePixmap( QX11Info::display(), pm );
+ } else {
+ if ( TQPaintDevice::x11AppDefaultVisual( scrn ) ) {
+ gc = XCreateGC( QX11Info::display(), RootWindow( QX11Info::display(), scrn ), 0, 0 );
+ } else {
+ Window w;
+ XSetWindowAttributes a;
+ a.background_pixel = TQt::black.pixel( scrn );
+ a.border_pixel = TQt::black.pixel( scrn );
+ a.colormap = TQPaintDevice::x11AppColormap( scrn );
+ w = XCreateWindow( QX11Info::display(), RootWindow( QX11Info::display(), scrn ), 0, 0, 100, 100,
+ 0, TQPaintDevice::x11AppDepth( scrn ), InputOutput,
+ (Visual*)TQPaintDevice::x11AppVisual( scrn ),
+ CWBackPixel|CWBorderPixel|CWColormap, &a );
+ gc = XCreateGC( QX11Info::display(), w, 0, 0 );
+ XDestroyWindow( QX11Info::display(), w );
+ }
+ }
+ XSetGraphicsExposures( QX11Info::display(), gc, False );
+ return gc;
+}
+
+GC qt_xget_temp_gc( int scrn, bool monochrome ) // get temporary GC
+{
+ if ( scrn < 0 || scrn >= appScreenCount ) {
+ qDebug("invalid screen (tmp) %d %d", scrn, appScreenCount );
+ TQWidget* bla = 0;
+ bla->setName("hello");
+ }
+ GC gc;
+ if ( monochrome ) {
+ if ( !app_gc_tmp_m ) // create GC for bitmap
+ memset( (app_gc_tmp_m = new GC[appScreenCount]), 0, appScreenCount * sizeof( GC ) );
+ if ( !app_gc_tmp_m[scrn] )
+ app_gc_tmp_m[scrn] = create_gc( scrn, TRUE );
+ gc = app_gc_tmp_m[scrn];
+ } else { // create standard GC
+ if ( !app_gc_tmp )
+ memset( (app_gc_tmp = new GC[appScreenCount]), 0, appScreenCount * sizeof( GC ) );
+ if ( !app_gc_tmp[scrn] )
+ app_gc_tmp[scrn] = create_gc( scrn, FALSE );
+ gc = app_gc_tmp[scrn];
+ }
+ return gc;
+}
+
+// ### REMOVE 4.0
+WId qt_xrootwin() // get X root window
+{
+ return TQPaintDevice::x11AppRootWindow();
+}
+
+WId qt_xrootwin( int scrn ) // get X root window for screen
+{
+ return TQPaintDevice::x11AppRootWindow( scrn );
+}
+
+bool qt_try_modal( TQWidget *widget, XEvent *event )
+{
+ if (qt_xdnd_dragging) {
+ // allow mouse events while DnD is active
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ return TRUE;
+ default:
+ break;
+ }
+ }
+
+ if ( qt_tryModalHelper( widget ) )
+ return TRUE;
+
+ bool block_event = FALSE;
+ switch ( event->type ) {
+ case ButtonPress: // disallow mouse/key events
+ case ButtonRelease:
+ case MotionNotify:
+ case XKeyPress:
+ case XKeyRelease:
+ case EnterNotify:
+ case LeaveNotify:
+ case ClientMessage:
+ block_event = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ return !block_event;
+}
+
+/*****************************************************************************
+ Platform specific global and internal functions
+ *****************************************************************************/
+
+void qt_save_rootinfo() // save new root info
+{
+ Atom type;
+ int format;
+ unsigned long length, after;
+ uchar *data;
+
+ if ( qt_xsetroot_id ) { // kill old pixmap
+ if ( XGetWindowProperty( QX11Info::display(), TQPaintDevice::x11AppRootWindow(),
+ qt_xsetroot_id, 0, 1,
+ True, AnyPropertyType, &type, &format,
+ &length, &after, &data ) == Success ) {
+ if ( type == XA_PIXMAP && format == 32 && length == 1 &&
+ after == 0 && data ) {
+ XKillClient( QX11Info::display(), *((Pixmap*)data) );
+ }
+ Pixmap dummy = XCreatePixmap( QX11Info::display(), TQPaintDevice::x11AppRootWindow(),
+ 1, 1, 1 );
+ XChangeProperty( QX11Info::display(), TQPaintDevice::x11AppRootWindow(),
+ qt_xsetroot_id, XA_PIXMAP, 32,
+ PropModeReplace, (uchar *)&dummy, 1 );
+ XSetCloseDownMode( QX11Info::display(), RetainPermanent );
+ }
+ }
+ if ( data )
+ XFree( (char *)data );
+}
+
+/*****************************************************************************
+ qt_init() - initializes TQt for X11
+ *****************************************************************************/
+
+#define XK_MISCELLANY
+#define XK_LATIN1
+#include <X11/keysymdef.h>
+
+// ### This should be static but it isn't because of the friend declaration
+// ### in tqpaintdevice.h which then should have a static too but can't have
+// ### it because "storage class specifiers invalid in friend function
+// ### declarations" :-) Ideas anyone?
+void qt_init_internal( int *argcptr, char **argv,
+ Display *display, TQt::HANDLE visual, TQt::HANDLE colormap )
+{
+ setlocale( LC_ALL, "" ); // use correct char set mapping
+ setlocale( LC_NUMERIC, "C" ); // make sprintf()/scanf() work
+
+ if ( display ) {
+ // TQt part of other application
+
+ appForeignDpy = TRUE;
+// appDpy = display;
+
+ // Set application name and class
+ appName = qstrdup( "TQt-subapplication" );
+ char *app_class = 0;
+ if (argv) {
+ const char* p = strrchr( argv[0], '/' );
+ app_class = qstrdup(p ? p + 1 : argv[0]);
+ if (app_class[0])
+ app_class[0] = toupper(app_class[0]);
+ }
+ appClass = app_class;
+
+ // Install default error handlers
+ original_x_errhandler = XSetErrorHandler( qt_x_errhandler );
+ original_xio_errhandler = XSetIOErrorHandler( qt_xio_errhandler );
+ } else {
+ // TQt controls everything (default)
+
+ int argc = *argcptr;
+ int j;
+
+ // Install default error handlers
+ original_x_errhandler = XSetErrorHandler( qt_x_errhandler );
+ original_xio_errhandler = XSetIOErrorHandler( qt_xio_errhandler );
+
+ // Set application name and class
+ char *app_class = 0;
+ if (argv) {
+ const char *p = strrchr( argv[0], '/' );
+ appName = p ? p + 1 : argv[0];
+ app_class = qstrdup(appName);
+ if (app_class[0])
+ app_class[0] = toupper(app_class[0]);
+ }
+ appClass = app_class;
+
+ // Get command line params
+ j = argc ? 1 : 0;
+ for ( int i=1; i<argc; i++ ) {
+ if ( argv[i] && *argv[i] != '-' ) {
+ argv[j++] = argv[i];
+ continue;
+ }
+ TQCString arg = argv[i];
+ if ( arg == "-display" ) {
+ if ( ++i < argc )
+ appDpyName = argv[i];
+ } else if ( arg == "-fn" || arg == "-font" ) {
+ if ( ++i < argc ) {
+ appFont = argv[i];
+ qt_x11_cmdline_font = true;
+ }
+ } else if ( arg == "-bg" || arg == "-background" ) {
+ if ( ++i < argc )
+ appBGCol = argv[i];
+ } else if ( arg == "-btn" || arg == "-button" ) {
+ if ( ++i < argc )
+ appBTNCol = argv[i];
+ } else if ( arg == "-fg" || arg == "-foreground" ) {
+ if ( ++i < argc )
+ appFGCol = argv[i];
+ } else if ( arg == "-name" ) {
+ if ( ++i < argc )
+ appName = argv[i];
+ } else if ( arg == "-title" ) {
+ if ( ++i < argc )
+ mwTitle = argv[i];
+ } else if ( arg == "-tqgeometry" ) {
+ if ( ++i < argc )
+ mwGeometry = argv[i];
+ //Ming-Che 10/10
+ } else if ( arg == "-im" ) {
+ if ( ++i < argc )
+ ximServer = argv[i];
+ } else if ( arg == "-noxim" ) {
+ noxim=TRUE;
+ //
+ } else if ( arg == "-iconic" ) {
+ mwIconic = !mwIconic;
+ } else if ( arg == "-ncols" ) { // xv and netscape use this name
+ if ( ++i < argc )
+ qt_ncols_option = TQMAX(0,atoi(argv[i]));
+ } else if ( arg == "-visual" ) { // xv and netscape use this name
+ if ( ++i < argc ) {
+ TQCString s = TQCString(argv[i]).lower();
+ if ( s == "truecolor" ) {
+ qt_visual_option = TrueColor;
+ } else {
+ // ### Should we honor any others?
+ }
+ }
+#ifndef TQT_NO_XIM
+ } else if ( arg == "-inputstyle" ) {
+ if ( ++i < argc ) {
+ TQCString s = TQCString(argv[i]).lower();
+ if ( s == "onthespot" )
+ xim_preferred_style = XIMPreeditCallbacks |
+ XIMStatusNothing;
+ else if ( s == "overthespot" )
+ xim_preferred_style = XIMPreeditPosition |
+ XIMStatusNothing;
+ else if ( s == "offthespot" )
+ xim_preferred_style = XIMPreeditArea |
+ XIMStatusArea;
+ else if ( s == "root" )
+ xim_preferred_style = XIMPreeditNothing |
+ XIMStatusNothing;
+ }
+#endif
+ } else if ( arg == "-cmap" ) { // xv uses this name
+ qt_cmap_option = TRUE;
+ }
+#if defined(TQT_DEBUG)
+ else if ( arg == "-sync" )
+ appSync = !appSync;
+ else if ( arg == "-nograb" )
+ appNoGrab = !appNoGrab;
+ else if ( arg == "-dograb" )
+ appDoGrab = !appDoGrab;
+#endif
+ else
+ argv[j++] = argv[i];
+ }
+
+ *argcptr = j;
+
+#if defined(TQT_DEBUG) && defined(TQ_OS_LINUX)
+ if ( !appNoGrab && !appDoGrab ) {
+ TQCString s;
+ s.sprintf( "/proc/%d/cmdline", getppid() );
+ TQFile f( s );
+ if ( f.open( IO_ReadOnly ) ) {
+ s.truncate( 0 );
+ int c;
+ while ( (c = TQT_TQIODEVICE_OBJECT(f).getch()) > 0 ) {
+ if ( c == '/' )
+ s.truncate( 0 );
+ else
+ s += (char)c;
+ }
+ if ( s == "gdb" ) {
+ appNoGrab = TRUE;
+ qDebug( "TQt: gdb: -nograb added to command-line options.\n"
+ "\t Use the -dograb option to enforce grabbing." );
+ }
+ f.close();
+ }
+ }
+#endif
+ // Connect to X server
+
+ if( qt_is_gui_used ) {
+// if ( ( appDpy = XOpenDisplay(appDpyName) ) == 0 ) {
+// qWarning( "%s: cannot connect to X server %s", appName,
+// XDisplayName(appDpyName) );
+// tqApp = 0;
+// exit( 1 );
+// }
+
+ if ( appSync ) // if "-sync" argument
+ XSynchronize( QX11Info::display(), TRUE );
+ }
+ }
+ // Common code, regardless of whether display is foreign.
+
+ // Get X parameters
+
+ if( qt_is_gui_used ) {
+// appScreen = DefaultScreen(QX11Info::display());
+ appScreenCount = ScreenCount(QX11Info::display());
+
+ TQPaintDevice::x_appdisplay = QX11Info::display();
+ TQPaintDevice::x_appscreen = QX11Info::appScreen();
+
+ // allocate the arrays for the TQPaintDevice data
+ TQPaintDevice::x_appdepth_arr = new int[ appScreenCount ];
+ TQPaintDevice::x_appcells_arr = new int[ appScreenCount ];
+ TQPaintDevice::x_approotwindow_arr = new TQt::HANDLE[ appScreenCount ];
+ TQPaintDevice::x_appcolormap_arr = new TQt::HANDLE[ appScreenCount ];
+ TQPaintDevice::x_appdefcolormap_arr = new bool[ appScreenCount ];
+ TQPaintDevice::x_appvisual_arr = new void*[ appScreenCount ];
+ TQPaintDevice::x_appdefvisual_arr = new bool[ appScreenCount ];
+ TQ_CHECK_PTR( TQPaintDevice::x_appdepth_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_appcells_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_approotwindow_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_appcolormap_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_appdefcolormap_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_appvisual_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_appdefvisual_arr );
+
+ int screen;
+ TQString serverVendor( ServerVendor( QX11Info::display()) );
+ if (serverVendor.tqcontains("XFree86") && VendorRelease(QX11Info::display()) < 40300000)
+ qt_hebrew_keyboard_hack = TRUE;
+
+ for ( screen = 0; screen < appScreenCount; ++screen ) {
+ TQPaintDevice::x_appdepth_arr[ screen ] = DefaultDepth(QX11Info::display(), screen);
+ TQPaintDevice::x_appcells_arr[ screen ] = DisplayCells(QX11Info::display(), screen);
+ TQPaintDevice::x_approotwindow_arr[ screen ] = RootWindow(QX11Info::display(), screen);
+
+ // setup the visual and colormap for each screen
+ Visual *vis = 0;
+ if ( visual && screen == QX11Info::appScreen() ) {
+ // use the provided visual on the default screen only
+ vis = (Visual *) visual;
+
+ // figure out the depth of the visual we are using
+ XVisualInfo *vi, rvi;
+ int n;
+ rvi.visualid = XVisualIDFromVisual(vis);
+ rvi.screen = screen;
+ vi = XGetVisualInfo( QX11Info::display(), VisualIDMask | VisualScreenMask, &rvi, &n );
+ if (vi) {
+ TQPaintDevice::x_appdepth_arr[ screen ] = vi->depth;
+ TQPaintDevice::x_appcells_arr[ screen ] = vi->visual->map_entries;
+ TQPaintDevice::x_appvisual_arr[ screen ] = vi->visual;
+ TQPaintDevice::x_appdefvisual_arr[ screen ] = FALSE;
+ XFree(vi);
+ } else {
+ // couldn't get info about the visual, use the default instead
+ vis = 0;
+ }
+ }
+
+ if (!vis) {
+ // use the default visual
+ vis = DefaultVisual(QX11Info::display(), screen);
+ TQPaintDevice::x_appdefvisual_arr[ screen ] = TRUE;
+
+ if ( qt_visual_option == TrueColor ||
+ TQApplication::colorSpec() == TQApplication::ManyColor ) {
+ // tqfind custom visual
+
+ int d, c;
+ vis = tqfind_truecolor_visual( QX11Info::display(), screen, &d, &c );
+ TQPaintDevice::x_appdepth_arr[ screen ] = d;
+ TQPaintDevice::x_appcells_arr[ screen ] = c;
+
+ TQPaintDevice::x_appvisual_arr[ screen ] = vis;
+ TQPaintDevice::x_appdefvisual_arr[ screen ] =
+ (XVisualIDFromVisual(vis) ==
+ XVisualIDFromVisual(DefaultVisual(QX11Info::display(), screen)));
+ }
+
+ TQPaintDevice::x_appvisual_arr[ screen ] = vis;
+ }
+
+ // we assume that 8bpp == pseudocolor, but this is not
+ // always the case (according to the X server), so we need
+ // to make sure that our internal data is setup in a way
+ // that is compatible with our assumptions
+ if ( vis->c_class == TrueColor &&
+ TQPaintDevice::x_appdepth_arr[ screen ] == 8 &&
+ TQPaintDevice::x_appcells_arr[ screen ] == 8 )
+ TQPaintDevice::x_appcells_arr[ screen ] = 256;
+
+ if ( colormap && screen == QX11Info::appScreen() ) {
+ // use the provided colormap for the default screen only
+ TQPaintDevice::x_appcolormap_arr[ screen ] = colormap;
+ TQPaintDevice::x_appdefcolormap_arr[ screen ] = FALSE;
+ } else {
+ if ( vis->c_class == TrueColor ) {
+ TQPaintDevice::x_appdefcolormap_arr[ screen ] =
+ TQPaintDevice::x_appdefvisual_arr[ screen ];
+ } else {
+ TQPaintDevice::x_appdefcolormap_arr[ screen ] =
+ !qt_cmap_option && TQPaintDevice::x_appdefvisual_arr[ screen ];
+ }
+
+ if ( TQPaintDevice::x_appdefcolormap_arr[ screen ] ) {
+ // use default colormap
+ XStandardColormap *stdcmap;
+ VisualID vid =
+ XVisualIDFromVisual((Visual *)
+ TQPaintDevice::x_appvisual_arr[ screen ]);
+ int i, count;
+
+ TQPaintDevice::x_appcolormap_arr[ screen ] = 0;
+
+ if ( ! serverVendor.tqcontains( "Hewlett-Packard" ) ) {
+ // on HPUX 10.20 local displays, the RGB_DEFAULT_MAP colormap
+ // doesn't give us correct colors. Why this happens, I have
+ // no clue, so we disable this for HPUX
+ if (XGetRGBColormaps(QX11Info::display(),
+ TQPaintDevice::x11AppRootWindow( screen ),
+ &stdcmap, &count, XA_RGB_DEFAULT_MAP)) {
+ i = 0;
+ while (i < count &&
+ TQPaintDevice::x_appcolormap_arr[ screen ] == 0) {
+ if (stdcmap[i].visualid == vid) {
+ TQPaintDevice::x_appcolormap_arr[ screen ] =
+ stdcmap[i].colormap;
+ }
+ i++;
+ }
+
+ XFree( (char *)stdcmap );
+ }
+ }
+
+ if (TQPaintDevice::x_appcolormap_arr[ screen ] == 0) {
+ TQPaintDevice::x_appcolormap_arr[ screen ] =
+ DefaultColormap(QX11Info::display(), screen);
+ }
+ } else {
+ // create a custom colormap
+ TQPaintDevice::x_appcolormap_arr[ screen ] =
+ XCreateColormap(QX11Info::display(), TQPaintDevice::x11AppRootWindow( screen ),
+ vis, AllocNone);
+ }
+ }
+ }
+
+ // Set X painttqdevice parameters for the default screen
+ TQPaintDevice::x_appdepth = TQPaintDevice::x_appdepth_arr[ QX11Info::appScreen() ];
+ TQPaintDevice::x_appcells = TQPaintDevice::x_appcells_arr[ QX11Info::appScreen() ];
+ TQPaintDevice::x_approotwindow = TQPaintDevice::x_approotwindow_arr[ QX11Info::appScreen() ];
+ TQPaintDevice::x_appcolormap = TQPaintDevice::x_appcolormap_arr[ QX11Info::appScreen() ];
+ TQPaintDevice::x_appdefcolormap = TQPaintDevice::x_appdefcolormap_arr[ QX11Info::appScreen() ];
+ TQPaintDevice::x_appvisual = TQPaintDevice::x_appvisual_arr[ QX11Info::appScreen() ];
+ TQPaintDevice::x_appdefvisual = TQPaintDevice::x_appdefvisual_arr[ QX11Info::appScreen() ];
+
+ // Support protocols
+
+ qt_x11_intern_atom( "WM_PROTOCOLS", &qt_wm_protocols );
+ qt_x11_intern_atom( "WM_DELETE_WINDOW", &qt_wm_delete_window );
+ qt_x11_intern_atom( "WM_STATE", &qt_wm_state );
+ qt_x11_intern_atom( "WM_CHANGE_STATE", &qt_wm_change_state );
+ qt_x11_intern_atom( "WM_TAKE_FOCUS", &qt_wm_take_focus );
+ qt_x11_intern_atom( "WM_CLIENT_LEADER", &qt_wm_client_leader);
+ qt_x11_intern_atom( "WM_WINDOW_ROLE", &qt_window_role);
+ qt_x11_intern_atom( "SM_CLIENT_ID", &qt_sm_client_id);
+ qt_x11_intern_atom( "CLIPBOARD", &qt_xa_clipboard );
+ qt_x11_intern_atom( "RESOURCE_MANAGER", &qt_resource_manager );
+ qt_x11_intern_atom( "INCR", &qt_x_incr );
+ qt_x11_intern_atom( "_XSETROOT_ID", &qt_xsetroot_id );
+ qt_x11_intern_atom( "_TQT_SELECTION", &qt_selection_property );
+ qt_x11_intern_atom( "_TQT_CLIPBOARD_SENTINEL", &qt_clipboard_sentinel );
+ qt_x11_intern_atom( "_TQT_SELECTION_SENTINEL", &qt_selection_sentinel );
+ qt_x11_intern_atom( "_TQT_SCROLL_DONE", &qt_qt_scrolldone );
+ qt_x11_intern_atom( "_TQT_INPUT_ENCODING", &qt_input_encoding );
+ qt_x11_intern_atom( "_TQT_SIZEGRIP", &qt_sizegrip );
+ qt_x11_intern_atom( "_NET_WM_CONTEXT_HELP", &qt_net_wm_context_help );
+ qt_x11_intern_atom( "_NET_WM_PING", &qt_net_wm_ping );
+ qt_x11_intern_atom( "_MOTIF_WM_HINTS", &qt_xa_motif_wm_hints );
+ qt_x11_intern_atom( "DTWM_IS_RUNNING", &qt_cde_running );
+ qt_x11_intern_atom( "KWIN_RUNNING", &qt_kwin_running );
+ qt_x11_intern_atom( "KWM_RUNNING", &qt_kwm_running );
+ qt_x11_intern_atom( "GNOME_BACKGROUND_PROPERTIES", &qt_gbackground_properties );
+
+ TQString atomname("_TQT_SETTINGS_TIMESTAMP_");
+ atomname += XDisplayName(appDpyName);
+ qt_x11_intern_atom( atomname.latin1(), &qt_settings_timestamp );
+
+ qt_x11_intern_atom( "_NET_SUPPORTED", &qt_net_supported );
+ qt_x11_intern_atom( "_NET_VIRTUAL_ROOTS", &qt_net_virtual_roots );
+ qt_x11_intern_atom( "_NET_WORKAREA", &qt_net_workarea );
+ qt_x11_intern_atom( "_NET_WM_STATE", &qt_net_wm_state );
+ qt_x11_intern_atom( "_NET_WM_STATE_MODAL", &qt_net_wm_state_modal );
+ qt_x11_intern_atom( "_NET_WM_STATE_MAXIMIZED_VERT", &qt_net_wm_state_max_v );
+ qt_x11_intern_atom( "_NET_WM_STATE_MAXIMIZED_HORZ", &qt_net_wm_state_max_h );
+ qt_x11_intern_atom( "_NET_WM_STATE_FULLSCREEN", &qt_net_wm_state_fullscreen );
+ qt_x11_intern_atom( "_NET_WM_STATE_ABOVE", &qt_net_wm_state_above );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE", &qt_net_wm_window_type );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_NORMAL", &qt_net_wm_window_type_normal );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_DIALOG", &qt_net_wm_window_type_dialog );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_TOOLBAR", &qt_net_wm_window_type_toolbar );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_MENU", &qt_net_wm_window_type_menu );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_UTILITY", &qt_net_wm_window_type_utility );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_SPLASH", &qt_net_wm_window_type_splash );
+ qt_x11_intern_atom( "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", &qt_net_wm_window_type_override );
+ qt_x11_intern_atom( "_KDE_NET_WM_FRAME_STRUT", &qt_net_wm_frame_strut );
+ qt_x11_intern_atom( "_NET_WM_STATE_STAYS_ON_TOP",
+ &qt_net_wm_state_stays_on_top );
+ qt_x11_intern_atom( "_NET_WM_PID", &qt_net_wm_pid );
+ qt_x11_intern_atom( "_NET_WM_USER_TIME", &qt_net_wm_user_time );
+ qt_x11_intern_atom( "ENLIGHTENMENT_DESKTOP", &qt_enlightenment_desktop );
+ qt_x11_intern_atom( "_NET_WM_NAME", &qt_net_wm_name );
+ qt_x11_intern_atom( "_NET_WM_ICON_NAME", &qt_net_wm_icon_name );
+ qt_x11_intern_atom( "UTF8_STRING", &qt_utf8_string );
+ qt_x11_intern_atom( "_SGI_DESKS_MANAGER", &qt_sgi_desks_manager );
+
+ qt_xdnd_setup();
+ qt_x11_motifdnd_init();
+
+ // Finally create all atoms
+ qt_x11_process_intern_atoms();
+
+ // look for broken window managers
+ qt_detect_broken_window_manager();
+
+ // initialize NET lists
+ qt_get_net_supported();
+ qt_get_net_virtual_roots();
+
+// #ifndef TQT_NO_XRANDR
+// // See if XRandR is supported on the connected display
+// int xrandr_errorbase;
+// TQ_UNUSED( xrandr_eventbase );
+// if ( XRRQueryExtension( QX11Info::display(), &xrandr_eventbase, &xrandr_errorbase ) ) {
+// // XRandR is supported
+// qt_use_xrandr = TRUE;
+// }
+// #endif // TQT_NO_XRANDR
+
+#ifndef TQT_NO_XRENDER
+ // See if XRender is supported on the connected display
+ int xrender_eventbase, xrender_errorbase;
+ if (XRenderQueryExtension(QX11Info::display(), &xrender_eventbase, &xrender_errorbase)) {
+ // XRender is supported, let's see if we have a PictFormat for the
+ // default visual
+ XRenderPictFormat *format =
+ XRenderFindVisualFormat(QX11Info::display(),
+ (Visual *) TQPaintDevice::x_appvisual);
+ qt_use_xrender = (format != 0) && (TQPaintDevice::x_appdepth != 8);
+ }
+#endif // TQT_NO_XRENDER
+
+#ifndef TQT_NO_XKB
+ // If XKB is detected, set the GrabsUseXKBState option so input method
+ // compositions continue to work (ie. deadkeys)
+ unsigned int state = XkbPCF_GrabsUseXKBStateMask;
+ (void) XkbSetPerClientControls(QX11Info::display(), state, &state);
+#endif
+
+// #if !defined(TQT_NO_XFTFREETYPE)
+// // defined in qfont_x11.cpp
+// extern bool qt_has_xft;
+// #ifndef TQT_XFT2
+// if (!qt_use_xrender)
+// qt_has_xft = FALSE;
+// else
+// #endif
+// qt_has_xft = XftInit(0) && XftInitFtLibrary();
+//
+// if (qt_has_xft) {
+// char *dpi_str = XGetDefault(QX11Info::display(), "Xft", "dpi");
+// if (dpi_str) {
+// // use a custom DPI
+// char *end = 0;
+// int dpi = strtol(dpi_str, &end, 0);
+// if (dpi_str != end) {
+// for (int s = 0; s < ScreenCount(QX11Info::display()); ++s) {
+// TQPaintDevice::x11SetAppDpiX(dpi, s);
+// TQPaintDevice::x11SetAppDpiY(dpi, s);
+// }
+// }
+// }
+// }
+// #endif // TQT_NO_XFTFREETYPE
+
+ // look at the modifier mapping, and get the correct masks for alt/meta
+ // tqfind the alt/meta masks
+ XModifierKeymap *map = XGetModifierMapping(QX11Info::display());
+ if (map) {
+ int i, maskIndex = 0, mapIndex = 0;
+ for (maskIndex = 0; maskIndex < 8; maskIndex++) {
+ for (i = 0; i < map->max_keypermod; i++) {
+ if (map->modifiermap[mapIndex]) {
+ KeySym sym =
+ XKeycodeToKeysym(QX11Info::display(), map->modifiermap[mapIndex], 0);
+ if ( qt_alt_mask == 0 &&
+ ( sym == XK_Alt_L || sym == XK_Alt_R ) ) {
+ qt_alt_mask = 1 << maskIndex;
+ }
+ if ( qt_meta_mask == 0 &&
+ (sym == XK_Meta_L || sym == XK_Meta_R ) ) {
+ qt_meta_mask = 1 << maskIndex;
+ }
+ }
+ mapIndex++;
+ }
+ }
+
+ // not look for mode_switch in qt_alt_mask and qt_meta_mask - if it is
+ // present in one or both, then we set qt_mode_switch_remove_mask.
+ // see TQETWidget::translateKeyEventInternal for an explanation
+ // of why this is needed
+ mapIndex = 0;
+ for ( maskIndex = 0; maskIndex < 8; maskIndex++ ) {
+ if ( qt_alt_mask != ( 1 << maskIndex ) &&
+ qt_meta_mask != ( 1 << maskIndex ) ) {
+ for ( i = 0; i < map->max_keypermod; i++ )
+ mapIndex++;
+ continue;
+ }
+
+ for ( i = 0; i < map->max_keypermod; i++ ) {
+ if ( map->modifiermap[ mapIndex ] ) {
+ KeySym sym =
+ XKeycodeToKeysym( QX11Info::display(), map->modifiermap[ mapIndex ], 0 );
+ if ( sym == XK_Mode_switch ) {
+ qt_mode_switch_remove_mask |= 1 << maskIndex;
+ }
+ }
+ mapIndex++;
+ }
+ }
+
+ XFreeModifiermap(map);
+ } else {
+ // assume defaults
+ qt_alt_mask = Mod1Mask;
+ qt_meta_mask = Mod4Mask;
+ qt_mode_switch_remove_mask = 0;
+ }
+
+ // Misc. initialization
+
+ TQColor::initialize();
+ TQFont::initialize();
+ TQCursor::initialize();
+ TQPainter::initialize();
+ }
+
+#if defined(TQT_THREAD_SUPPORT)
+ TQThread::initialize();
+#endif
+
+ if( qt_is_gui_used ) {
+ TQT_TQOBJECT(tqApp)->setName( appName );
+
+ int screen;
+ for ( screen = 0; screen < appScreenCount; ++screen ) {
+ XSelectInput( QX11Info::display(), TQPaintDevice::x11AppRootWindow( screen ),
+ KeymapStateMask | EnterWindowMask | LeaveWindowMask |
+ PropertyChangeMask );
+
+// #ifndef TQT_NO_XRANDR
+// if (qt_use_xrandr)
+// XRRSelectInput( QX11Info::display(), TQPaintDevice::x11AppRootWindow( screen ), True );
+// #endif // TQT_NO_XRANDR
+ }
+ }
+
+ if ( qt_is_gui_used ) {
+ qt_set_input_encoding();
+
+ qt_set_x11_resources( appFont, appFGCol, appBGCol, appBTNCol);
+
+ // be smart about the size of the default font. most X servers have helvetica
+ // 12 point available at 2 resolutions:
+ // 75dpi (12 pixels) and 100dpi (17 pixels).
+ // At 95 DPI, a 12 point font should be 16 pixels tall - in which case a 17
+ // pixel font is a closer match than a 12 pixel font
+ int ptsz =
+ (int) ( ( ( TQPaintDevice::x11AppDpiY() >= 95 ? 17. : 12. ) *
+ 72. / (float) TQPaintDevice::x11AppDpiY() ) + 0.5 );
+
+ if ( !qt_app_has_font && !qt_x11_cmdline_font ) {
+ TQFont f( "Helvetica", ptsz );
+ TQApplication::setFont( f );
+ }
+
+#ifndef TQT_NO_XIM
+ if ( ! xim_preferred_style ) // no configured input style, use the default
+ xim_preferred_style = xim_default_style;
+
+ qt_xim = 0;
+ TQString ximServerName(ximServer);
+ if (ximServer)
+ ximServerName.prepend("@im=");
+ else
+ ximServerName = "";
+
+ if ( !XSupportsLocale() )
+ qWarning("TQt: Locales not supported on X server");
+
+#ifdef USE_X11R6_XIM
+ else if ( XSetLocaleModifiers (ximServerName.ascii()) == 0 )
+ qWarning( "TQt: Cannot set locale modifiers: %s",
+ ximServerName.ascii());
+ else if (! noxim)
+ XRegisterIMInstantiateCallback(QX11Info::display(), 0, 0, 0,
+ (XIMProc) xim_create_callback, 0);
+#else // !USE_X11R6_XIM
+ else if ( XSetLocaleModifiers ("") == 0 )
+ qWarning("TQt: Cannot set locale modifiers");
+ else if (! noxim)
+ TQApplication::create_xim();
+#endif // USE_X11R6_XIM
+#endif // TQT_NO_XIM
+
+#if defined (TQT_TABLET_SUPPORT)
+ int ndev,
+ i,
+ j;
+ bool gotStylus,
+ gotEraser;
+ XDeviceInfo *tqdevices, *devs;
+ XInputClassInfo *ip;
+ XAnyClassPtr any;
+ XValuatorInfoPtr v;
+ XAxisInfoPtr a;
+ XDevice *dev;
+ XEventClass *ev_class;
+ int curr_event_count;
+
+#if !defined(TQ_OS_IRIX)
+ // XFree86 divides a stylus and eraser into 2 tqdevices, so we must do for both...
+ const TQString XFREENAMESTYLUS = "stylus";
+ const TQString XFREENAMEPEN = "pen";
+ const TQString XFREENAMEERASER = "eraser";
+#endif
+
+ tqdevices = XListInputDevices( QX11Info::display(), &ndev);
+ if ( tqdevices == NULL ) {
+ qWarning( "Failed to get list of tqdevices" );
+ ndev = -1;
+ }
+ dev = NULL;
+ for ( devs = tqdevices, i = 0; i < ndev; i++, devs++ ) {
+ gotEraser = FALSE;
+#if defined(TQ_OS_IRIX)
+
+ gotStylus = ( !strncmp(devs->name,
+ WACOM_NAME, sizeof(WACOM_NAME) - 1) );
+#else
+ TQString devName = devs->name;
+ devName = devName.lower();
+ gotStylus = ( devName.startsWith(XFREENAMEPEN)
+ || devName.startsWith(XFREENAMESTYLUS) );
+ if ( !gotStylus )
+ gotEraser = devName.startsWith( XFREENAMEERASER );
+
+#endif
+ if ( gotStylus || gotEraser ) {
+ // I only wanted to do this once, so wrap pointers around these
+ curr_event_count = 0;
+
+ if ( gotStylus ) {
+ devStylus = XOpenDevice( QX11Info::display(), devs->id );
+ dev = devStylus;
+ ev_class = event_list_stylus;
+ } else if ( gotEraser ) {
+ devEraser = XOpenDevice( QX11Info::display(), devs->id );
+ dev = devEraser;
+ ev_class = event_list_eraser;
+ }
+ if ( dev == NULL ) {
+ qWarning( "Failed to open tqdevice" );
+ } else {
+ if ( dev->num_classes > 0 ) {
+ for ( ip = dev->classes, j = 0; j < devs->num_classes;
+ ip++, j++ ) {
+ switch ( ip->input_class ) {
+ case KeyClass:
+ DeviceKeyPress( dev, xinput_key_press,
+ ev_class[curr_event_count] );
+ curr_event_count++;
+ DeviceKeyRelease( dev, xinput_key_release,
+ ev_class[curr_event_count] );
+ curr_event_count++;
+ break;
+ case ButtonClass:
+ DeviceButtonPress( dev, xinput_button_press,
+ ev_class[curr_event_count] );
+ curr_event_count++;
+ DeviceButtonRelease( dev, xinput_button_release,
+ ev_class[curr_event_count] );
+ curr_event_count++;
+ break;
+ case ValuatorClass:
+ // I'm only going to be interested in motion when the
+ // stylus is already down anyway!
+ DeviceMotionNotify( dev, xinput_motion,
+ ev_class[curr_event_count] );
+ curr_event_count++;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ // get the min/max value for pressure!
+ any = (XAnyClassPtr) ( devs->inputclassinfo );
+ if ( dev == devStylus ) {
+ qt_curr_events_stylus = curr_event_count;
+ for (j = 0; j < devs->num_classes; j++) {
+ if ( any->c_class == ValuatorClass ) {
+ v = (XValuatorInfoPtr) any;
+ a = (XAxisInfoPtr) ((char *) v +
+ sizeof (XValuatorInfo));
+#if defined (TQ_OS_IRIX)
+ max_pressure = a[WAC_PRESSURE_I].max_value;
+#else
+ max_pressure = a[2].max_value;
+#endif
+ // got the max pressure no need to go further...
+ break;
+ }
+ any = (XAnyClassPtr) ((char *) any + any->length);
+ }
+ } else {
+ qt_curr_events_eraser = curr_event_count;
+ }
+ // at this point we are assuming there is only one
+ // wacom tqdevice...
+#if defined (TQ_OS_IRIX)
+ if ( devStylus != NULL ) {
+#else
+ if ( devStylus != NULL && devEraser != NULL ) {
+#endif
+ break;
+ }
+ }
+ } // end for loop
+ XFreeDeviceList( tqdevices );
+#endif // TQT_TABLET_SUPPORT
+
+ } else {
+ // read some non-GUI settings when not using the X server...
+
+ if ( TQApplication::desktopSettingsAware() ) {
+ TQSettings settings;
+
+ // read library (ie. plugin) path list
+ TQString libpathkey = TQString("/qt/%1.%2/libraryPath")
+ .arg( TQT_VERSION >> 16 )
+ .arg( (TQT_VERSION & 0xff00 ) >> 8 );
+ TQStringList pathlist =
+ settings.readListEntry(libpathkey, ':');
+ if (! pathlist.isEmpty()) {
+ TQStringList::ConstIterator it = pathlist.begin();
+ while (it != pathlist.end())
+ TQApplication::addLibraryPath(*it++);
+ }
+
+ TQString defaultcodec = settings.readEntry("/qt/defaultCodec", "none");
+ if (defaultcodec != "none") {
+ TQTextCodec *codec = TQTextCodec::codecForName(defaultcodec);
+ if (codec)
+ tqApp->setDefaultCodec(codec);
+ }
+
+ qt_resolve_symlinks =
+ settings.readBoolEntry("/qt/resolveSymlinks", TRUE);
+ }
+ }
+ }
+
+void qt_init( int *argcptr, char **argv, TQApplication::Type )
+{
+ qt_init_internal( argcptr, argv, 0, 0, 0 );
+}
+
+void qt_init( Display *display, TQt::HANDLE visual, TQt::HANDLE colormap )
+{
+ qt_init_internal( 0, 0, display, visual, colormap );
+}
+
+/*****************************************************************************
+ qt_cleanup() - cleans up when the application is finished
+ *****************************************************************************/
+
+void qt_cleanup()
+{
+ appliedstamp = 0;
+
+ if ( app_save_rootinfo ) // root window must keep state
+ qt_save_rootinfo();
+
+ if ( qt_is_gui_used ) {
+ TQPixmapCache::clear();
+ TQPainter::cleanup();
+ TQCursor::cleanup();
+ TQFont::cleanup();
+ TQColor::cleanup();
+ TQSharedDoubleBuffer::cleanup();
+ }
+#if defined(TQT_THREAD_SUPPORT)
+ TQThread::cleanup();
+#endif
+
+#if defined (TQT_TABLET_SUPPORT)
+ if ( devStylus != NULL )
+ XCloseDevice( QX11Info::display(), devStylus );
+ if ( devEraser != NULL )
+ XCloseDevice( QX11Info::display(), devEraser );
+#endif
+
+#if !defined(TQT_NO_XIM)
+ if ( qt_xim )
+ TQApplication::close_xim();
+#endif
+
+ if ( qt_is_gui_used ) {
+ int screen;
+ for ( screen = 0; screen < appScreenCount; screen++ ) {
+ if ( ! TQPaintDevice::x11AppDefaultColormap( screen ) )
+ XFreeColormap( TQPaintDevice::x11AppDisplay(),
+ TQPaintDevice::x11AppColormap( screen ) );
+ }
+ }
+
+#define TQT_CLEANUP_GC(g) if (g) { for (int i=0;i<appScreenCount;i++){if(g[i])XFreeGC(QX11Info::display(),g[i]);} delete [] g; g = 0; }
+ TQT_CLEANUP_GC(app_gc_ro);
+ TQT_CLEANUP_GC(app_gc_ro_m);
+ TQT_CLEANUP_GC(app_gc_tmp);
+ TQT_CLEANUP_GC(app_gc_tmp_m);
+#undef TQT_CLEANUP_GC
+
+ delete sip_list;
+ sip_list = 0;
+
+ // Reset the error handlers
+ XSetErrorHandler( original_x_errhandler );
+ XSetIOErrorHandler( original_xio_errhandler );
+
+ if ( qt_is_gui_used && !appForeignDpy )
+ XCloseDisplay( QX11Info::display() ); // close X display
+// appDpy = 0;
+
+ qt_x11_wm_client_leader = 0;
+
+ if ( TQPaintDevice::x_appdepth_arr )
+ delete [] TQPaintDevice::x_appdepth_arr;
+ if ( TQPaintDevice::x_appcells_arr )
+ delete [] TQPaintDevice::x_appcells_arr;
+ if ( TQPaintDevice::x_appcolormap_arr )
+ delete []TQPaintDevice::x_appcolormap_arr;
+ if ( TQPaintDevice::x_appdefcolormap_arr )
+ delete [] TQPaintDevice::x_appdefcolormap_arr;
+ if ( TQPaintDevice::x_appvisual_arr )
+ delete [] TQPaintDevice::x_appvisual_arr;
+ if ( TQPaintDevice::x_appdefvisual_arr )
+ delete [] TQPaintDevice::x_appdefvisual_arr;
+
+ if ( appForeignDpy ) {
+ delete [] (char *)appName;
+ appName = 0;
+ delete [] (char *)appClass;
+ appClass = 0;
+ }
+
+ if (qt_net_supported_list)
+ delete [] qt_net_supported_list;
+ qt_net_supported_list = 0;
+
+ if (qt_net_virtual_root_list)
+ delete [] qt_net_virtual_root_list;
+ qt_net_virtual_root_list = 0;
+}
+
+const char *tqAppName() // get application name
+{
+ return appName;
+}
+
+const char *tqAppClass() // get application class
+{
+ return appClass;
+}
+
+// /*****************************************************************************
+// Session management support
+// *****************************************************************************/
+//
+// #ifndef TQT_NO_SM_SUPPORT
+//
+// #include <X11/SM/SMlib.h>
+//
+// class TQSessionManagerData
+// {
+// public:
+// TQSessionManagerData( TQSessionManager* mgr, TQString& id, TQString& key )
+// : sm( mgr ), sessionId( id ), sessionKey( key ) {}
+// TQSessionManager* sm;
+// TQStringList restartCommand;
+// TQStringList discardCommand;
+// TQString& sessionId;
+// TQString& sessionKey;
+// TQSessionManager::RestartHint restartHint;
+// };
+//
+// class TQSmSocketReceiver : public TQObject
+// {
+// Q_OBJECT
+// TQ_OBJECT
+// public:
+// TQSmSocketReceiver( int socket )
+// : TQObject(0,0)
+// {
+// TQSocketNotifier* sn = new TQSocketNotifier( socket, TQSocketNotifier::Read, this );
+// connect( sn, TQT_SIGNAL( activated(int) ), this, TQT_SLOT( socketActivated(int) ) );
+// }
+//
+// public Q_SLOTS:
+// void socketActivated(int);
+// };
+//
+//
+// static SmcConn smcConnection = 0;
+// static bool sm_interactionActive;
+// static bool sm_smActive;
+// static int sm_interactStyle;
+// static int sm_saveType;
+// static bool sm_cancel;
+// // static bool sm_waitingForPhase2; ### never used?!?
+// static bool sm_waitingForInteraction;
+// static bool sm_isshutdown;
+// // static bool sm_shouldbefast; ### never used?!?
+// static bool sm_phase2;
+// static bool sm_in_phase2;
+//
+// static TQSmSocketReceiver* sm_receiver = 0;
+//
+// static void resetSmState();
+// static void sm_setProperty( const char* name, const char* type,
+// int num_vals, SmPropValue* vals);
+// static void sm_saveYourselfCallback( SmcConn smcConn, SmPointer clientData,
+// int saveType, Bool shutdown , int interactStyle, Bool fast);
+// static void sm_saveYourselfPhase2Callback( SmcConn smcConn, SmPointer clientData ) ;
+// static void sm_dieCallback( SmcConn smcConn, SmPointer clientData ) ;
+// static void sm_shutdownCancelledCallback( SmcConn smcConn, SmPointer clientData );
+// static void sm_saveCompleteCallback( SmcConn smcConn, SmPointer clientData );
+// static void sm_interactCallback( SmcConn smcConn, SmPointer clientData );
+// static void sm_performSaveYourself( TQSessionManagerData* );
+//
+// static void resetSmState()
+// {
+// // sm_waitingForPhase2 = FALSE; ### never used?!?
+// sm_waitingForInteraction = FALSE;
+// sm_interactionActive = FALSE;
+// sm_interactStyle = SmInteractStyleNone;
+// sm_smActive = FALSE;
+// sm_blockUserInput = FALSE;
+// sm_isshutdown = FALSE;
+// // sm_shouldbefast = FALSE; ### never used?!?
+// sm_phase2 = FALSE;
+// sm_in_phase2 = FALSE;
+// }
+//
+//
+// // theoretically it's possible to set several properties at once. For
+// // simplicity, however, we do just one property at a time
+// static void sm_setProperty( const char* name, const char* type,
+// int num_vals, SmPropValue* vals)
+// {
+// if (num_vals ) {
+// SmProp prop;
+// prop.name = (char*)name;
+// prop.type = (char*)type;
+// prop.num_vals = num_vals;
+// prop.vals = vals;
+//
+// SmProp* props[1];
+// props[0] = &prop;
+// SmcSetProperties( smcConnection, 1, props );
+// }
+// else {
+// char* names[1];
+// names[0] = (char*) name;
+// SmcDeleteProperties( smcConnection, 1, names );
+// }
+// }
+//
+// static void sm_setProperty( const TQString& name, const TQString& value)
+// {
+// SmPropValue prop;
+// prop.length = value.length();
+// prop.value = (SmPointer) value.latin1();
+// sm_setProperty( name.latin1(), SmARRAY8, 1, &prop );
+// }
+//
+// static void sm_setProperty( const TQString& name, const TQStringList& value)
+// {
+// SmPropValue *prop = new SmPropValue[ value.count() ];
+// int count = 0;
+// for ( TQStringList::ConstIterator it = value.begin(); it != value.end(); ++it ) {
+// prop[ count ].length = (*it).length();
+// prop[ count ].value = (char*)(*it).latin1();
+// ++count;
+// }
+// sm_setProperty( name.latin1(), SmLISTofARRAY8, count, prop );
+// delete [] prop;
+// }
+//
+//
+// // workaround for broken libsm, see below
+// struct TQT_smcConn {
+// unsigned int save_yourself_in_progress : 1;
+// unsigned int shutdown_in_progress : 1;
+// };
+//
+// static void sm_saveYourselfCallback( SmcConn smcConn, SmPointer clientData,
+// int saveType, Bool shutdown , int interactStyle, Bool /*fast*/)
+// {
+// if (smcConn != smcConnection )
+// return;
+// sm_cancel = FALSE;
+// sm_smActive = TRUE;
+// sm_isshutdown = shutdown;
+// sm_saveType = saveType;
+// sm_interactStyle = interactStyle;
+// // sm_shouldbefast = fast; ### never used?!?
+//
+// // ugly workaround for broken libSM. libSM should do that _before_
+// // actually invoking the callback in sm_process.c
+// ( (TQT_smcConn*)smcConn )->save_yourself_in_progress = TRUE;
+// if ( sm_isshutdown )
+// ( (TQT_smcConn*)smcConn )->shutdown_in_progress = TRUE;
+//
+// sm_performSaveYourself( (TQSessionManagerData*) clientData );
+// if ( !sm_isshutdown ) // we cannot expect a confirmation message in that case
+// resetSmState();
+// }
+//
+// static void sm_performSaveYourself( TQSessionManagerData* smd )
+// {
+// if ( sm_isshutdown )
+// sm_blockUserInput = TRUE;
+//
+// TQSessionManager* sm = smd->sm;
+//
+// // generate a new session key
+// timeval tv;
+// gettimeofday( &tv, 0 );
+// smd->sessionKey = TQString::number( tv.tv_sec ) + "_" + TQString::number(tv.tv_usec);
+//
+// // tell the session manager about our program in best POSIX style
+// sm_setProperty( SmProgram, TQString( tqApp->argv()[0] ) );
+// // tell the session manager about our user as well.
+// struct passwd* entry = getpwuid( geteuid() );
+// if ( entry )
+// sm_setProperty( SmUserID, TQString::tqfromLatin1( entry->pw_name ) );
+//
+// // generate a restart and discard command that makes sense
+// TQStringList restart;
+// restart << tqApp->argv()[0] << "-session" << smd->sessionId + "_" + smd->sessionKey;
+// if (qstricmp(tqAppName(), tqAppClass()) != 0)
+// restart << "-name" << tqAppName();
+// sm->setRestartCommand( restart );
+// TQStringList discard;
+// sm->setDiscardCommand( discard );
+//
+// switch ( sm_saveType ) {
+// case SmSaveBoth:
+// tqApp->commitData( *sm );
+// if ( sm_isshutdown && sm_cancel)
+// break; // we cancelled the shutdown, no need to save state
+// // fall through
+// case SmSaveLocal:
+// tqApp->saveState( *sm );
+// break;
+// case SmSaveGlobal:
+// tqApp->commitData( *sm );
+// break;
+// default:
+// break;
+// }
+//
+// if ( sm_phase2 && !sm_in_phase2 ) {
+// SmcRequestSaveYourselfPhase2( smcConnection, sm_saveYourselfPhase2Callback, (SmPointer*) smd );
+// sm_blockUserInput = FALSE;
+// }
+// else {
+// // close eventual interaction monitors and cancel the
+// // shutdown, if required. Note that we can only cancel when
+// // performing a shutdown, it does not work for checkpoints
+// if ( sm_interactionActive ) {
+// SmcInteractDone( smcConnection, sm_isshutdown && sm_cancel);
+// sm_interactionActive = FALSE;
+// }
+// else if ( sm_cancel && sm_isshutdown ) {
+// if ( sm->allowsErrorInteraction() ) {
+// SmcInteractDone( smcConnection, True );
+// sm_interactionActive = FALSE;
+// }
+// }
+//
+// // set restart and discard command in session manager
+// sm_setProperty( SmRestartCommand, sm->restartCommand() );
+// sm_setProperty( SmDiscardCommand, sm->discardCommand() );
+//
+// // set the restart hint
+// SmPropValue prop;
+// prop.length = sizeof( int );
+// int value = sm->restartHint();
+// prop.value = (SmPointer) &value;
+// sm_setProperty( SmRestartStyleHint, SmCARD8, 1, &prop );
+//
+// // we are done
+// SmcSaveYourselfDone( smcConnection, !sm_cancel );
+// }
+// }
+//
+// static void sm_dieCallback( SmcConn smcConn, SmPointer /* clientData */)
+// {
+// if (smcConn != smcConnection )
+// return;
+// resetSmState();
+// TQEvent quitEvent(TQEvent::Quit);
+// TQApplication::sendEvent(tqApp, &quitEvent);
+// }
+//
+// static void sm_shutdownCancelledCallback( SmcConn smcConn, SmPointer /* clientData */)
+// {
+// if (smcConn != smcConnection )
+// return;
+// if ( sm_waitingForInteraction )
+// tqApp->exit_loop();
+// resetSmState();
+// }
+//
+// static void sm_saveCompleteCallback( SmcConn smcConn, SmPointer /*clientData */)
+// {
+// if (smcConn != smcConnection )
+// return;
+// resetSmState();
+// }
+//
+// static void sm_interactCallback( SmcConn smcConn, SmPointer /* clientData */ )
+// {
+// if (smcConn != smcConnection )
+// return;
+// if ( sm_waitingForInteraction )
+// tqApp->exit_loop();
+// }
+//
+// static void sm_saveYourselfPhase2Callback( SmcConn smcConn, SmPointer clientData )
+// {
+// if (smcConn != smcConnection )
+// return;
+// sm_in_phase2 = TRUE;
+// sm_performSaveYourself( (TQSessionManagerData*) clientData );
+// }
+//
+//
+// void TQSmSocketReceiver::socketActivated(int)
+// {
+// IceProcessMessages( SmcGetIceConnection( smcConnection ), 0, 0);
+// }
+//
+//
+// #undef Bool
+// #include "tqapplication_x11.tqmoc"
+//
+// TQSessionManager::TQSessionManager( TQApplication * app, TQString &id, TQString& key )
+// : TQObject( app, "session manager" )
+// {
+// d = new TQSessionManagerData( this, id, key );
+// d->restartHint = RestartIfRunning;
+//
+// resetSmState();
+// char cerror[256];
+// char* myId = 0;
+// char* prevId = (char*)id.latin1(); // we know what we are doing
+//
+// SmcCallbacks cb;
+// cb.save_yourself.callback = sm_saveYourselfCallback;
+// cb.save_yourself.client_data = (SmPointer) d;
+// cb.die.callback = sm_dieCallback;
+// cb.die.client_data = (SmPointer) d;
+// cb.save_complete.callback = sm_saveCompleteCallback;
+// cb.save_complete.client_data = (SmPointer) d;
+// cb.shutdown_cancelled.callback = sm_shutdownCancelledCallback;
+// cb.shutdown_cancelled.client_data = (SmPointer) d;
+//
+// // avoid showing a warning message below
+// const char* session_manager = getenv("SESSION_MANAGER");
+// if ( !session_manager || !session_manager[0] )
+// return;
+//
+// smcConnection = SmcOpenConnection( 0, 0, 1, 0,
+// SmcSaveYourselfProcMask |
+// SmcDieProcMask |
+// SmcSaveCompleteProcMask |
+// SmcShutdownCancelledProcMask,
+// &cb,
+// prevId,
+// &myId,
+// 256, cerror );
+//
+// id = TQString::tqfromLatin1( myId );
+// ::free( myId ); // it was allocated by C
+//
+// TQString error = cerror;
+// if (!smcConnection ) {
+// qWarning("Session management error: %s", error.latin1() );
+// }
+// else {
+// sm_receiver = new TQSmSocketReceiver( IceConnectionNumber( SmcGetIceConnection( smcConnection ) ) );
+// }
+// }
+//
+// TQSessionManager::~TQSessionManager()
+// {
+// if ( smcConnection )
+// SmcCloseConnection( smcConnection, 0, 0 );
+// smcConnection = 0;
+// delete sm_receiver;
+// delete d;
+// }
+//
+// TQString TQSessionManager::sessionId() const
+// {
+// return d->sessionId;
+// }
+//
+// TQString TQSessionManager::sessionKey() const
+// {
+// return d->sessionKey;
+// }
+//
+//
+// void* TQSessionManager::handle() const
+// {
+// return (void*) smcConnection;
+// }
+//
+//
+// bool TQSessionManager::allowsInteraction()
+// {
+// if ( sm_interactionActive )
+// return TRUE;
+//
+// if ( sm_waitingForInteraction )
+// return FALSE;
+//
+// if ( sm_interactStyle == SmInteractStyleAny ) {
+// sm_waitingForInteraction = SmcInteractRequest( smcConnection, SmDialogNormal,
+// sm_interactCallback, (SmPointer*) this );
+// }
+// if ( sm_waitingForInteraction ) {
+// tqApp->enter_loop();
+// sm_waitingForInteraction = FALSE;
+// if ( sm_smActive ) { // not cancelled
+// sm_interactionActive = TRUE;
+// sm_blockUserInput = FALSE;
+// return TRUE;
+// }
+// }
+// return FALSE;
+// }
+//
+// bool TQSessionManager::allowsErrorInteraction()
+// {
+// if ( sm_interactionActive )
+// return TRUE;
+//
+// if ( sm_waitingForInteraction )
+// return FALSE;
+//
+// if ( sm_interactStyle == SmInteractStyleAny || sm_interactStyle == SmInteractStyleErrors ) {
+// sm_waitingForInteraction = SmcInteractRequest( smcConnection, SmDialogError,
+// sm_interactCallback, (SmPointer*) this );
+// }
+// if ( sm_waitingForInteraction ) {
+// tqApp->enter_loop();
+// sm_waitingForInteraction = FALSE;
+// if ( sm_smActive ) { // not cancelled
+// sm_interactionActive = TRUE;
+// sm_blockUserInput = FALSE;
+// return TRUE;
+// }
+// }
+// return FALSE;
+// }
+//
+// void TQSessionManager::release()
+// {
+// if ( sm_interactionActive ) {
+// SmcInteractDone( smcConnection, False );
+// sm_interactionActive = FALSE;
+// if ( sm_smActive && sm_isshutdown )
+// sm_blockUserInput = TRUE;
+// }
+// }
+//
+// void TQSessionManager::cancel()
+// {
+// sm_cancel = TRUE;
+// }
+//
+// void TQSessionManager::setRestartHint( TQSessionManager::RestartHint hint)
+// {
+// d->restartHint = hint;
+// }
+//
+// TQSessionManager::RestartHint TQSessionManager::restartHint() const
+// {
+// return d->restartHint;
+// }
+//
+// void TQSessionManager::setRestartCommand( const TQStringList& command)
+// {
+// d->restartCommand = command;
+// }
+//
+// TQStringList TQSessionManager::restartCommand() const
+// {
+// return d->restartCommand;
+// }
+//
+// void TQSessionManager::setDiscardCommand( const TQStringList& command)
+// {
+// d->discardCommand = command;
+// }
+//
+// TQStringList TQSessionManager::discardCommand() const
+// {
+// return d->discardCommand;
+// }
+//
+// void TQSessionManager::setManagerProperty( const TQString& name, const TQString& value)
+// {
+// SmPropValue prop;
+// prop.length = value.length();
+// prop.value = (SmPointer) value.utf8().data();
+// sm_setProperty( name.latin1(), SmARRAY8, 1, &prop );
+// }
+//
+// void TQSessionManager::setManagerProperty( const TQString& name, const TQStringList& value)
+// {
+// SmPropValue *prop = new SmPropValue[ value.count() ];
+// int count = 0;
+// for ( TQStringList::ConstIterator it = value.begin(); it != value.end(); ++it ) {
+// prop[ count ].length = (*it).length();
+// prop[ count ].value = (char*)(*it).utf8().data();
+// ++count;
+// }
+// sm_setProperty( name.latin1(), SmLISTofARRAY8, count, prop );
+// delete [] prop;
+// }
+//
+// bool TQSessionManager::isPhase2() const
+// {
+// return sm_in_phase2;
+// }
+//
+// void TQSessionManager::requestPhase2()
+// {
+// sm_phase2 = TRUE;
+// }
+//
+// #endif // TQT_NO_SM_SUPPORT
+
+void qt_enter_modal( TQWidget *widget )
+{
+ if ( !qt_modal_stack ) { // create modal stack
+ qt_modal_stack = new TQWidgetList;
+ TQ_CHECK_PTR( qt_modal_stack );
+ }
+ if (widget->parentWidget()) {
+ TQEvent e(TQEvent::WindowBlocked);
+ TQApplication::sendEvent(widget->parentWidget(), &e);
+ }
+
+ qt_dispatchEnterLeave( 0, TQWidget::tqfind((WId)curWin) );
+ qt_modal_stack->insert( 0, widget );
+ app_do_modal = TRUE;
+ curWin = 0;
+ ignoreNextMouseReleaseEvent = FALSE;
+}
+
+
+void qt_leave_modal( TQWidget *widget )
+{
+ if ( qt_modal_stack && qt_modal_stack->removeRef(widget) ) {
+ if ( qt_modal_stack->isEmpty() ) {
+ delete qt_modal_stack;
+ qt_modal_stack = 0;
+ TQPoint p( TQCursor::pos() );
+ TQWidget* w = TQApplication::widgetAt( p.x(), p.y(), TRUE );
+ qt_dispatchEnterLeave( w, TQWidget::tqfind( curWin ) ); // send synthetic enter event
+ curWin = w? w->winId() : 0;
+ }
+ }
+ app_do_modal = qt_modal_stack != 0;
+ ignoreNextMouseReleaseEvent = TRUE;
+
+ if (widget->parentWidget()) {
+ TQEvent e(TQEvent::WindowUnblocked);
+ TQApplication::sendEvent(widget->parentWidget(), &e);
+ }
+}
+
+#else // USE_QT4
+
+/*****************************************************************************
+ Internal variables and functions
+ *****************************************************************************/
+static const char *appName; // application name
+static const char *appClass; // application class
+static const char *appFont = 0; // application font
+static const char *appBGCol = 0; // application bg color
+static const char *appFGCol = 0; // application fg color
+static const char *appBTNCol = 0; // application btn color
+static const char *mwGeometry = 0; // main widget tqgeometry
+static const char *mwTitle = 0; // main widget title
+//Ming-Che 10/10
+static char *ximServer = 0; // XIM Server will connect to
+static bool mwIconic = FALSE; // main widget iconified
+//Ming-Che 10/10
+static bool noxim = FALSE; // connect to xim or not
+static Display *appDpy = 0; // X11 application display
+static char *appDpyName = 0; // X11 display name
+static bool appForeignDpy = FALSE; // we didn't create display
+static bool appSync = FALSE; // X11 synchronization
+#if defined(TQT_DEBUG)
+static bool appNoGrab = FALSE; // X11 grabbing enabled
+static bool appDoGrab = FALSE; // X11 grabbing override (gdb)
+#endif
+static int appScreen; // X11 screen number
+static int appScreenCount; // X11 screen count
+static bool app_save_rootinfo = FALSE; // save root info
+static bool app_do_modal = FALSE; // modal mode
+static Window curWin = 0; // current window
+
+static GC* app_gc_ro = 0; // read-only GC
+static GC* app_gc_tmp = 0; // temporary GC
+static GC* app_gc_ro_m = 0; // read-only GC (monochrome)
+static GC* app_gc_tmp_m = 0; // temporary GC (monochrome)
+// symbols needed by extern TQXEmbed class
+TQ_EXPORT Atom qt_wm_protocols = 0; // window manager protocols
+TQ_EXPORT Atom qt_wm_delete_window = 0; // delete window protocol
+TQ_EXPORT Atom qt_wm_take_focus = 0; // take focus window protocol
+
+Atom qt_qt_scrolldone = 0; // scroll synchronization
+Atom qt_net_wm_context_help = 0; // context help
+Atom qt_net_wm_ping = 0; // _NET_WM_PING protocol
+
+static Atom qt_xsetroot_id = 0;
+Atom qt_xa_clipboard = 0;
+Atom qt_selection_property = 0;
+Atom qt_clipboard_sentinel = 0;
+Atom qt_selection_sentinel = 0;
+TQ_EXPORT Atom qt_wm_state = 0;
+Atom qt_wm_change_state = 0;
+static Atom qt_settings_timestamp = 0; // TQt >=3 settings timestamp
+static Atom qt_input_encoding = 0; // TQt desktop properties
+static Atom qt_resource_manager = 0; // X11 Resource manager
+Atom qt_sizegrip = 0; // sizegrip
+Atom qt_wm_client_leader = 0;
+TQ_EXPORT Atom qt_window_role = 0;
+TQ_EXPORT Atom qt_sm_client_id = 0;
+Atom qt_xa_motif_wm_hints = 0;
+Atom qt_cde_running = 0;
+Atom qt_kwin_running = 0;
+Atom qt_kwm_running = 0;
+Atom qt_gbackground_properties = 0;
+Atom qt_x_incr = 0;
+Atom qt_utf8_string = 0;
+
+// detect broken window managers
+Atom qt_sgi_desks_manager = 0;
+bool qt_broken_wm = FALSE;
+static void qt_detect_broken_window_manager();
+
+// NET WM support
+Atom qt_net_supported = 0;
+Atom qt_net_wm_name = 0;
+Atom qt_net_wm_icon_name = 0;
+Atom qt_net_virtual_roots = 0;
+Atom qt_net_workarea = 0;
+Atom qt_net_wm_state = 0;
+Atom qt_net_wm_state_modal = 0;
+Atom qt_net_wm_state_max_v = 0;
+Atom qt_net_wm_state_max_h = 0;
+Atom qt_net_wm_state_fullscreen = 0;
+Atom qt_net_wm_state_above = 0;
+Atom qt_net_wm_window_type = 0;
+Atom qt_net_wm_window_type_normal = 0;
+Atom qt_net_wm_window_type_dialog = 0;
+Atom qt_net_wm_window_type_toolbar = 0;
+Atom qt_net_wm_window_type_menu = 0;
+Atom qt_net_wm_window_type_utility = 0;
+Atom qt_net_wm_window_type_splash = 0;
+Atom qt_net_wm_window_type_override = 0; // KDE extension
+Atom qt_net_wm_frame_strut = 0; // KDE extension
+Atom qt_net_wm_state_stays_on_top = 0; // KDE extension
+Atom qt_net_wm_pid = 0;
+Atom qt_net_wm_user_time = 0;
+// Enlightenment support
+Atom qt_enlightenment_desktop = 0;
+
+// window managers list of supported "stuff"
+Atom *qt_net_supported_list = 0;
+// list of virtual root windows
+Window *qt_net_virtual_root_list = 0;
+
+
+
+// client leader window
+Window qt_x11_wm_client_leader = 0;
+
+// function to update the workarea of the screen - in qdesktopwidget_x11.cpp
+extern void qt_desktopwidget_update_workarea();
+
+// current focus model
+static const int FocusModel_Unknown = -1;
+static const int FocusModel_Other = 0;
+static const int FocusModel_PointerRoot = 1;
+static int qt_focus_model = -1;
+
+#ifndef TQT_NO_XRANDR
+// TRUE if TQt is compiled w/ XRandR support and XRandR exists on the connected
+// Display
+bool qt_use_xrandr = FALSE;
+static int xrandr_eventbase;
+#endif
+
+// TRUE if TQt is compiled w/ XRender support and XRender exists on the connected
+// Display
+TQ_EXPORT bool qt_use_xrender = FALSE;
+
+// modifier masks for alt/meta - detected when the application starts
+static long qt_alt_mask = 0;
+static long qt_meta_mask = 0;
+// modifier tqmask to remove mode switch from modifiers that have alt/meta set
+// this problem manifests itself on HP/UX 10.20 at least, and without it
+// modifiers do not work at all...
+static long qt_mode_switch_remove_mask = 0;
+
+// flags for extensions for special Languages, currently only for RTL languages
+static bool qt_use_rtl_extensions = FALSE;
+bool qt_hebrew_keyboard_hack = FALSE;
+
+static Window mouseActWindow = 0; // window where mouse is
+static int mouseButtonPressed = 0; // last mouse button pressed
+static int mouseButtonState = 0; // mouse button state
+static Time mouseButtonPressTime = 0; // when was a button pressed
+static short mouseXPos, mouseYPos; // mouse pres position in act window
+static short mouseGlobalXPos, mouseGlobalYPos; // global mouse press position
+
+extern TQWidgetList *qt_modal_stack; // stack of modal widgets
+static bool ignoreNextMouseReleaseEvent = FALSE; // ignore the next mouse release
+ // event if return from a modal
+ // widget
+
+static TQWidget *popupButtonFocus = 0;
+static TQWidget *popupOfPopupButtonFocus = 0;
+static bool popupCloseDownMode = FALSE;
+static bool popupGrabOk;
+
+static bool sm_blockUserInput = FALSE; // session management
+
+int qt_xfocusout_grab_counter = 0;
+
+#if defined (TQT_TABLET_SUPPORT)
+// since XInput event classes aren't created until we actually open an XInput
+// tqdevice, here is a static list that we will use later on...
+const int INVALID_EVENT = -1;
+const int TOTAL_XINPUT_EVENTS = 7;
+
+XDevice *devStylus = NULL;
+XDevice *devEraser = NULL;
+XEventClass event_list_stylus[TOTAL_XINPUT_EVENTS];
+XEventClass event_list_eraser[TOTAL_XINPUT_EVENTS];
+
+int qt_curr_events_stylus = 0;
+int qt_curr_events_eraser = 0;
+
+// well, luckily we only need to do this once.
+static int xinput_motion = INVALID_EVENT;
+static int xinput_key_press = INVALID_EVENT;
+static int xinput_key_release = INVALID_EVENT;
+static int xinput_button_press = INVALID_EVENT;
+static int xinput_button_release = INVALID_EVENT;
+
+// making this assumption on XFree86, since we can only use 1 tqdevice,
+// the pressure for the eraser and the stylus should be the same, if they aren't
+// well, they certainly have a strange pen then...
+static int max_pressure;
+extern bool chokeMouse;
+#endif
+
+// last timestamp read from TQSettings
+static uint appliedstamp = 0;
+
+
+typedef int (*QX11EventFilter) (XEvent*);
+QX11EventFilter qt_set_x11_event_filter(QX11EventFilter filter);
+
+static QX11EventFilter qt_x11_event_filter = 0;
+TQ_EXPORT QX11EventFilter qt_set_x11_event_filter(QX11EventFilter filter)
+{
+ QX11EventFilter old_filter = qt_x11_event_filter;
+ qt_x11_event_filter = filter;
+ return old_filter;
+}
+static bool qt_x11EventFilter( XEvent* ev )
+{
+ if ( qt_x11_event_filter && qt_x11_event_filter( ev ) )
+ return TRUE;
+ return tqApp->x11EventFilter( ev );
+}
+
+
+
+
+
+#if !defined(TQT_NO_XIM)
+XIM qt_xim = 0;
+XIMStyle qt_xim_style = 0;
+static XIMStyle xim_default_style = XIMPreeditCallbacks | XIMStatusNothing;
+static XIMStyle xim_preferred_style = 0;
+#endif
+
+static int composingKeycode=0;
+static TQTextCodec * input_mapper = 0;
+
+extern bool qt_check_clipboard_sentinel(); //def in qclipboard_x11.cpp
+extern bool qt_check_selection_sentinel(); //def in qclipboard_x11.cpp
+
+static void qt_save_rootinfo();
+bool qt_try_modal( TQWidget *, XEvent * );
+
+int qt_ncols_option = 216; // used in qcolor_x11.cpp
+int qt_visual_option = -1;
+bool qt_cmap_option = FALSE;
+TQWidget *qt_button_down = 0; // widget got last button-down
+
+extern bool qt_tryAccelEvent( TQWidget*, TQKeyEvent* ); // def in qaccel.cpp
+
+struct TQScrollInProgress {
+ static long serial;
+ TQScrollInProgress( TQWidget* w, int x, int y ) :
+ id( serial++ ), scrolled_widget( w ), dx( x ), dy( y ) {}
+ long id;
+ TQWidget* scrolled_widget;
+ int dx, dy;
+};
+long TQScrollInProgress::serial=0;
+static TQPtrList<TQScrollInProgress> *sip_list = 0;
+
+
+// stuff in qt_xdnd.cpp
+// setup
+extern void qt_xdnd_setup();
+// x event handling
+extern void qt_handle_xdnd_enter( TQWidget *, const XEvent *, bool );
+extern void qt_handle_xdnd_position( TQWidget *, const XEvent *, bool );
+extern void qt_handle_xdnd_status( TQWidget *, const XEvent *, bool );
+extern void qt_handle_xdnd_leave( TQWidget *, const XEvent *, bool );
+extern void qt_handle_xdnd_drop( TQWidget *, const XEvent *, bool );
+extern void qt_handle_xdnd_finished( TQWidget *, const XEvent *, bool );
+extern void qt_xdnd_handle_selection_request( const XSelectionRequestEvent * );
+extern bool qt_xdnd_handle_badwindow();
+
+extern void qt_motifdnd_handle_msg( TQWidget *, const XEvent *, bool );
+extern void qt_x11_motifdnd_init();
+
+// client message atoms
+extern Atom qt_xdnd_enter;
+extern Atom qt_xdnd_position;
+extern Atom qt_xdnd_status;
+extern Atom qt_xdnd_leave;
+extern Atom qt_xdnd_drop;
+extern Atom qt_xdnd_finished;
+// xdnd selection atom
+extern Atom qt_xdnd_selection;
+extern bool qt_xdnd_dragging;
+
+// gui or non-gui from qapplication.cpp
+extern bool qt_is_gui_used;
+extern bool qt_app_has_font;
+
+static bool qt_x11_cmdline_font = false;
+
+
+extern bool qt_resolve_symlinks; // from qapplication.cpp
+
+// Paint event clipping magic
+extern void qt_set_paintevent_clipping( TQPaintDevice* dev, const TQRegion& region);
+extern void qt_clear_paintevent_clipping();
+
+
+// Palette handling
+extern TQPalette *qt_std_pal;
+extern void qt_create_std_palette();
+
+void qt_x11_intern_atom( const char *, Atom * );
+
+static TQPtrList<TQWidget>* deferred_map_list = 0;
+static void qt_deferred_map_cleanup()
+{
+ delete deferred_map_list;
+ deferred_map_list = 0;
+}
+void qt_deferred_map_add( TQWidget* w)
+{
+ if ( !deferred_map_list ) {
+ deferred_map_list = new TQPtrList<TQWidget>;
+ qAddPostRoutine( qt_deferred_map_cleanup );
+ }
+ deferred_map_list->append( w );
+}
+void qt_deferred_map_take( TQWidget* w )
+{
+ if (deferred_map_list ) {
+ deferred_map_list->remove( w );
+ }
+}
+bool qt_deferred_map_tqcontains( TQWidget* w )
+{
+ if (!deferred_map_list)
+ return FALSE;
+ else
+ return deferred_map_list->tqcontains( w );
+}
+
+
+class TQETWidget : public TQWidget // event translator widget
+{
+public:
+ void setWState( WFlags f ) { TQWidget::setWState(f); }
+ void clearWState( WFlags f ) { TQWidget::clearWState(f); }
+ void setWFlags( WFlags f ) { TQWidget::setWFlags(f); }
+ void clearWFlags( WFlags f ) { TQWidget::clearWFlags(f); }
+ bool translateMouseEvent( const XEvent * );
+ bool translateKeyEventInternal( const XEvent *, int& count, TQString& text, int& state, char& ascii, int &code,
+ TQEvent::Type &type, bool willRepeat=FALSE );
+ bool translateKeyEvent( const XEvent *, bool grab );
+ bool translatePaintEvent( const XEvent * );
+ bool translateConfigEvent( const XEvent * );
+ bool translateCloseEvent( const XEvent * );
+ bool translateScrollDoneEvent( const XEvent * );
+ bool translateWheelEvent( int global_x, int global_y, int delta, int state, Orientation orient );
+#if defined (TQT_TABLET_SUPPORT)
+ bool translateXinputEvent( const XEvent* );
+#endif
+ bool translatePropertyEvent(const XEvent *);
+};
+
+
+
+
+// ************************************************************************
+// X Input Method support
+// ************************************************************************
+
+#if !defined(TQT_NO_XIM)
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif // TQ_C_CALLBACKS
+
+#ifdef USE_X11R6_XIM
+ static void xim_create_callback(XIM /*im*/,
+ XPointer /*client_data*/,
+ XPointer /*call_data*/)
+ {
+ // qDebug("xim_create_callback");
+ TQApplication::create_xim();
+ }
+
+ static void xim_destroy_callback(XIM /*im*/,
+ XPointer /*client_data*/,
+ XPointer /*call_data*/)
+ {
+ // qDebug("xim_destroy_callback");
+ TQApplication::close_xim();
+ XRegisterIMInstantiateCallback(appDpy, 0, 0, 0,
+ (XIMProc) xim_create_callback, 0);
+ }
+
+#endif // USE_X11R6_XIM
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif // TQ_C_CALLBACKS
+
+#endif // TQT_NO_XIM
+
+
+/*! \internal
+ Creates the application input method.
+ */
+void TQApplication::create_xim()
+{
+#ifndef TQT_NO_XIM
+ qt_xim = XOpenIM( appDpy, 0, 0, 0 );
+ if ( qt_xim ) {
+
+#ifdef USE_X11R6_XIM
+ XIMCallback destroy;
+ destroy.callback = (XIMProc) xim_destroy_callback;
+ destroy.client_data = 0;
+ if ( XSetIMValues( qt_xim, XNDestroyCallback, &destroy, (char *) 0 ) != 0 )
+ qWarning( "Xlib dosn't support destroy callback");
+#endif // USE_X11R6_XIM
+
+ XIMStyles *styles = 0;
+ XGetIMValues(qt_xim, XNQueryInputStyle, &styles, (char *) 0, (char *) 0);
+ if ( styles ) {
+ int i;
+ for ( i = 0; !qt_xim_style && i < styles->count_styles; i++ ) {
+ if ( styles->supported_styles[i] == xim_preferred_style ) {
+ qt_xim_style = xim_preferred_style;
+ break;
+ }
+ }
+ // if the preferred input style couldn't be found, look for
+ // Nothing
+ for ( i = 0; !qt_xim_style && i < styles->count_styles; i++ ) {
+ if ( styles->supported_styles[i] == (XIMPreeditNothing |
+ XIMStatusNothing) ) {
+ qt_xim_style = XIMPreeditNothing | XIMStatusNothing;
+ break;
+ }
+ }
+ // ... and failing that, None.
+ for ( i = 0; !qt_xim_style && i < styles->count_styles; i++ ) {
+ if ( styles->supported_styles[i] == (XIMPreeditNone |
+ XIMStatusNone) ) {
+ qt_xim_style = XIMPreeditNone | XIMStatusNone;
+ break;
+ }
+ }
+
+ // qDebug("TQApplication: using im style %lx", qt_xim_style);
+ XFree( (char *)styles );
+ }
+
+ if ( qt_xim_style ) {
+
+#ifdef USE_X11R6_XIM
+ XUnregisterIMInstantiateCallback(appDpy, 0, 0, 0,
+ (XIMProc) xim_create_callback, 0);
+#endif // USE_X11R6_XIM
+
+ TQWidgetList *list= tqApp->tqtopLevelWidgets();
+ TQWidgetListIt it(*list);
+ TQWidget * w;
+ while( (w=it.current()) != 0 ) {
+ ++it;
+ w->createTLSysExtra();
+ }
+ delete list;
+ } else {
+ // Give up
+ qWarning( "No supported input style found."
+ " See InputMethod documentation.");
+ close_xim();
+ }
+ }
+#endif // TQT_NO_XIM
+}
+
+
+/*! \internal
+ Closes the application input method.
+*/
+void TQApplication::close_xim()
+{
+#ifndef TQT_NO_XIM
+ // Calling XCloseIM gives a Purify FMR error
+ // XCloseIM( qt_xim );
+ // We prefer a less serious memory leak
+
+ qt_xim = 0;
+ TQWidgetList *list = tqApp->tqtopLevelWidgets();
+ TQWidgetListIt it(*list);
+ while(it.current()) {
+ it.current()->destroyInputContext();
+ ++it;
+ }
+ delete list;
+#endif // TQT_NO_XIM
+}
+
+
+/*****************************************************************************
+ Default X error handlers
+ *****************************************************************************/
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static bool x11_ignore_badwindow;
+static bool x11_badwindow;
+
+ // starts to ignore bad window errors from X
+void qt_ignore_badwindow()
+{
+ x11_ignore_badwindow = TRUE;
+ x11_badwindow = FALSE;
+}
+
+ // ends ignoring bad window errors and returns whether an error
+ // had happen.
+bool qt_badwindow()
+{
+ x11_ignore_badwindow = FALSE;
+ return x11_badwindow;
+}
+
+static int (*original_x_errhandler)( Display *dpy, XErrorEvent * );
+static int (*original_xio_errhandler)( Display *dpy );
+
+static int qt_x_errhandler( Display *dpy, XErrorEvent *err )
+{
+ if ( err->error_code == BadWindow ) {
+ x11_badwindow = TRUE;
+ if ( err->request_code == 25 /* X_SendEvent */ &&
+ qt_xdnd_handle_badwindow() )
+ return 0;
+ if ( x11_ignore_badwindow )
+ return 0;
+ } else if ( err->error_code == BadMatch &&
+ err->request_code == 42 /* X_SetInputFocus */ ) {
+ return 0;
+ }
+
+ char errstr[256];
+ XGetErrorText( dpy, err->error_code, errstr, 256 );
+ qWarning( "X Error: %s %d\n"
+ " Major opcode: %d\n"
+ " Minor opcode: %d\n"
+ " Resource id: 0x%lx",
+ errstr, err->error_code,
+ err->request_code,
+ err->minor_code,
+ err->resourceid );
+
+ // ### we really should distinguish between severe, non-severe and
+ // ### application specific errors
+
+ return 0;
+}
+
+
+static int qt_xio_errhandler( Display * )
+{
+ qWarning( "%s: Fatal IO error: client killed", appName );
+ tqApp = 0;
+ exit( 1 );
+ //### give the application a chance for a proper shutdown instead,
+ //### exit(1) doesn't help.
+ return 0;
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+// Memory leak: if the app exits before qt_init_internal(), this dict
+// isn't released correctly.
+static TQAsciiDict<Atom> *atoms_to_be_created = 0;
+static bool create_atoms_now = 0;
+
+/*****************************************************************************
+ qt_x11_intern_atom() - efficiently interns an atom, now or later.
+
+ If the application is being initialized, this function stores the
+ adddress of the atom and qt_init_internal will do the actual work
+ quickly. If the application is running, the atom is created here.
+
+ Neither argument may point to temporary variables.
+ *****************************************************************************/
+
+void qt_x11_intern_atom( const char *name, Atom *result)
+{
+ if ( !name || !result || *result )
+ return;
+
+ if ( create_atoms_now ) {
+ *result = XInternAtom( appDpy, name, False );
+ } else {
+ if ( !atoms_to_be_created ) {
+ atoms_to_be_created = new TQAsciiDict<Atom>;
+ atoms_to_be_created->setAutoDelete( FALSE );
+ }
+ atoms_to_be_created->insert( name, result );
+ *result = 0;
+ }
+}
+
+
+static void qt_x11_process_intern_atoms()
+{
+ if ( atoms_to_be_created ) {
+#if defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 6)
+ int i = atoms_to_be_created->count();
+ Atom * res = (Atom *)malloc( i * sizeof( Atom ) );
+ Atom ** resp = (Atom **)malloc( i * sizeof( Atom* ) );
+ char ** names = (char **)malloc( i * sizeof(const char*));
+
+ i = 0;
+ TQAsciiDictIterator<Atom> it( *atoms_to_be_created );
+ while( it.current() ) {
+ res[i] = 0;
+ resp[i] = it.current();
+ names[i] = qstrdup(it.currentKey());
+ i++;
+ ++it;
+ }
+ XInternAtoms( appDpy, names, i, False, res );
+ while( i ) {
+ i--;
+ delete [] names[i];
+ if ( res[i] && resp[i] )
+ *(resp[i]) = res[i];
+ }
+ free( res );
+ free( resp );
+ free( names );
+#else
+ TQAsciiDictIterator<Atom> it( *atoms_to_be_created );
+ Atom * result;
+ const char * name;
+ while( (result = it.current()) != 0 ) {
+ name = it.currentKey();
+ ++it;
+ *result = XInternAtom( appDpy, name, False );
+ }
+#endif
+ delete atoms_to_be_created;
+ atoms_to_be_created = 0;
+ create_atoms_now = TRUE;
+ }
+}
+
+
+/*! \internal
+ apply the settings to the application
+*/
+bool TQApplication::x11_apply_settings()
+{
+ if (! qt_std_pal)
+ qt_create_std_palette();
+
+ Atom type;
+ int format;
+ long offset = 0;
+ unsigned long nitems, after = 1;
+ unsigned char *data = 0;
+ TQDateTime timestamp, settingsstamp;
+ bool update_timestamp = FALSE;
+
+ if (XGetWindowProperty(appDpy, TQPaintDevice::x11AppRootWindow( 0 ),
+ qt_settings_timestamp, 0, 0,
+ False, AnyPropertyType, &type, &format, &nitems,
+ &after, &data) == Success && format == 8) {
+ if (data)
+ XFree(data);
+
+ TQBuffer ts;
+ ts.open(IO_WriteOnly);
+
+ while (after > 0) {
+ XGetWindowProperty(appDpy, TQPaintDevice::x11AppRootWindow( 0 ),
+ qt_settings_timestamp,
+ offset, 1024, False, AnyPropertyType,
+ &type, &format, &nitems, &after, &data);
+ if (format == 8) {
+ ts.writeBlock((const char *) data, nitems);
+ offset += nitems / 4;
+ }
+
+ XFree(data);
+ }
+
+ TQDataStream d(ts.buffer(), IO_ReadOnly);
+ d >> timestamp;
+ }
+
+ TQSettings settings;
+ settingsstamp = settings.lastModificationTime( "/qt/font" );
+ if (! settingsstamp.isValid())
+ return FALSE;
+
+ if ( appliedstamp && appliedstamp == settingsstamp.toTime_t() )
+ return TRUE;
+ appliedstamp = settingsstamp.toTime_t();
+
+ if (! timestamp.isValid() || settingsstamp > timestamp)
+ update_timestamp = TRUE;
+
+ /*
+ TQt settings. This is now they are written into the datastream.
+
+ /qt/Palette/ * - TQPalette
+ /qt/font - TQFont
+ /qt/libraryPath - TQStringList
+ /qt/style - TQString
+ /qt/doubleClickInterval - int
+ /qt/cursorFlashTime - int
+ /qt/wheelScrollLines - int
+ /qt/colorSpec - TQString
+ /qt/defaultCodec - TQString
+ /qt/globalStrut - TQSize
+ /qt/GUIEffects - TQStringList
+ /qt/Font Substitutions/ * - TQStringList
+ /qt/Font Substitutions/... - TQStringList
+ */
+
+ TQString str;
+ TQStringList strlist;
+ int i, num;
+ TQPalette pal(TQApplication::palette());
+ strlist = settings.readListEntry("/qt/Palette/active");
+ if (strlist.count() == TQColorGroup::NColorRoles) {
+ for (i = 0; i < TQColorGroup::NColorRoles; i++)
+ pal.setColor(TQPalette::Active, (TQColorGroup::ColorRole) i,
+ TQColor(strlist[i]));
+ }
+ strlist = settings.readListEntry("/qt/Palette/inactive");
+ if (strlist.count() == TQColorGroup::NColorRoles) {
+ for (i = 0; i < TQColorGroup::NColorRoles; i++)
+ pal.setColor(TQPalette::Inactive, (TQColorGroup::ColorRole) i,
+ TQColor(strlist[i]));
+ }
+ strlist = settings.readListEntry("/qt/Palette/disabled");
+ if (strlist.count() == TQColorGroup::NColorRoles) {
+ for (i = 0; i < TQColorGroup::NColorRoles; i++)
+ pal.setColor(TQPalette::Disabled, (TQColorGroup::ColorRole) i,
+ TQColor(strlist[i]));
+ }
+
+ // workaround for KDE 3.0, which messes up the buttonText value of
+ // the disabled palette in TQSettings
+ if ( pal.disabled().buttonText() == pal.active().buttonText() ) {
+ pal.setColor( TQPalette::Disabled, TQColorGroup::ButtonText,
+ pal.disabled().foreground() );
+ }
+
+ if (pal != *qt_std_pal && pal != TQApplication::palette()) {
+ TQApplication::setPalette(pal, TRUE);
+ *qt_std_pal = pal;
+ }
+
+ TQFont font(TQApplication::font());
+ if ( !qt_app_has_font && !qt_x11_cmdline_font ) {
+ // read new font
+ str = settings.readEntry("/qt/font");
+ if (! str.isNull() && ! str.isEmpty()) {
+ font.fromString(str);
+
+ if (font != TQApplication::font())
+ TQApplication::setFont(font, TRUE);
+ }
+ }
+
+ // read library (ie. plugin) path list
+ TQString libpathkey =
+ TQString("/qt/%1.%2/libraryPath").arg( TQT_VERSION >> 16 ).arg( (TQT_VERSION & 0xff00 ) >> 8 );
+ TQStringList pathlist = settings.readListEntry(libpathkey, ':');
+ if (! pathlist.isEmpty()) {
+ TQStringList::ConstIterator it = pathlist.begin();
+ while (it != pathlist.end())
+ TQApplication::addLibraryPath(*it++);
+ }
+
+ // read new TQStyle
+ extern bool qt_explicit_app_style; // defined in qapplication.cpp
+ TQString stylename = settings.readEntry( "/qt/style" );
+ if ( !stylename.isEmpty() && !qt_explicit_app_style ) {
+ TQApplication::setStyle( stylename );
+ // took the style from the user settings, so mark the explicit flag FALSE
+ qt_explicit_app_style = FALSE;
+ }
+
+ num =
+ settings.readNumEntry("/qt/doubleClickInterval",
+ TQApplication::doubleClickInterval());
+ TQApplication::setDoubleClickInterval(num);
+
+ num =
+ settings.readNumEntry("/qt/cursorFlashTime",
+ TQApplication::cursorFlashTime());
+ TQApplication::setCursorFlashTime(num);
+
+ num =
+ settings.readNumEntry("/qt/wheelScrollLines",
+ TQApplication::wheelScrollLines());
+ TQApplication::setWheelScrollLines(num);
+
+ TQString colorspec = settings.readEntry("/qt/colorSpec", "default");
+ if (colorspec == "normal")
+ TQApplication::setColorSpec(TQApplication::NormalColor);
+ else if (colorspec == "custom")
+ TQApplication::setColorSpec(TQApplication::CustomColor);
+ else if (colorspec == "many")
+ TQApplication::setColorSpec(TQApplication::ManyColor);
+ else if (colorspec != "default")
+ colorspec = "default";
+
+ TQString defaultcodec = settings.readEntry("/qt/defaultCodec", "none");
+ if (defaultcodec != "none") {
+ TQTextCodec *codec = TQTextCodec::codecForName(defaultcodec);
+ if (codec)
+ tqApp->setDefaultCodec(codec);
+ }
+
+ TQStringList strut = settings.readListEntry("/qt/globalStrut");
+ if (! strut.isEmpty()) {
+ if (strut.count() == 2) {
+ TQSize sz(strut[0].toUInt(), strut[1].toUInt());
+
+ if (sz.isValid())
+ TQApplication::setGlobalStrut(sz);
+ }
+ }
+
+ TQStringList effects = settings.readListEntry("/qt/GUIEffects");
+
+ TQApplication::setEffectEnabled( TQt::UI_General, effects.tqcontains("general") );
+ TQApplication::setEffectEnabled( TQt::UI_AnimateMenu, effects.tqcontains("animatemenu") );
+ TQApplication::setEffectEnabled( TQt::UI_FadeMenu, effects.tqcontains("fademenu") );
+ TQApplication::setEffectEnabled( TQt::UI_AnimateCombo, effects.tqcontains("animatecombo") );
+ TQApplication::setEffectEnabled( TQt::UI_AnimateTooltip, effects.tqcontains("animatetooltip") );
+ TQApplication::setEffectEnabled( TQt::UI_FadeTooltip, effects.tqcontains("fadetooltip") );
+ TQApplication::setEffectEnabled( TQt::UI_AnimateToolBox, effects.tqcontains("animatetoolbox") );
+
+ TQStringList fontsubs =
+ settings.entryList("/qt/Font Substitutions");
+ if (!fontsubs.isEmpty()) {
+ TQStringList subs;
+ TQString fam, skey;
+ TQStringList::Iterator it = fontsubs.begin();
+ while (it != fontsubs.end()) {
+ fam = (*it++);
+ skey = "/qt/Font Substitutions/" + fam;
+ subs = settings.readListEntry(skey);
+ TQFont::insertSubstitutions(fam, subs);
+ }
+ }
+
+ qt_broken_wm =
+ settings.readBoolEntry("/qt/brokenWindowManager", qt_broken_wm);
+
+ qt_resolve_symlinks =
+ settings.readBoolEntry("/qt/resolveSymlinks", TRUE);
+
+ qt_use_rtl_extensions =
+ settings.readBoolEntry("/qt/useRtlExtensions", FALSE);
+
+#ifndef TQT_NO_XIM
+ if (xim_preferred_style == 0) {
+ TQString ximInputStyle =
+ settings.readEntry( "/qt/XIMInputStyle",
+ TQObject::trUtf8( "On The Spot" ) ).lower();
+ if ( ximInputStyle == "on the spot" )
+ xim_preferred_style = XIMPreeditCallbacks | XIMStatusNothing;
+ else if ( ximInputStyle == "over the spot" )
+ xim_preferred_style = XIMPreeditPosition | XIMStatusNothing;
+ else if ( ximInputStyle == "off the spot" )
+ xim_preferred_style = XIMPreeditArea | XIMStatusArea;
+ else if ( ximInputStyle == "root" )
+ xim_preferred_style = XIMPreeditNothing | XIMStatusNothing;
+ }
+#endif
+
+ if (update_timestamp) {
+ TQBuffer stamp;
+ TQDataStream s(stamp.buffer(), IO_WriteOnly);
+ s << settingsstamp;
+
+ XChangeProperty(appDpy, TQPaintDevice::x11AppRootWindow( 0 ),
+ qt_settings_timestamp, qt_settings_timestamp, 8,
+ PropModeReplace, (unsigned char *) stamp.buffer().data(),
+ stamp.buffer().size());
+ }
+
+ return TRUE;
+}
+
+
+// read the _TQT_INPUT_ENCODING property and apply the settings to
+// the application
+static void qt_set_input_encoding()
+{
+ Atom type;
+ int format;
+ ulong nitems, after = 1;
+ const char *data;
+
+ int e = XGetWindowProperty( appDpy, TQPaintDevice::x11AppRootWindow(),
+ qt_input_encoding, 0, 1024,
+ False, XA_STRING, &type, &format, &nitems,
+ &after, (unsigned char**)&data );
+ if ( e != Success || !nitems || type == None ) {
+ // Always use the locale codec, since we have no examples of non-local
+ // XIMs, and since we cannot get a sensible answer about the encoding
+ // from the XIM.
+ input_mapper = TQTextCodec::codecForLocale();
+
+ } else {
+ if ( !qstricmp( data, "locale" ) )
+ input_mapper = TQTextCodec::codecForLocale();
+ else
+ input_mapper = TQTextCodec::codecForName( data );
+ // make sure we have an input codec
+ if( !input_mapper )
+ input_mapper = TQTextCodec::codecForName( "ISO 8859-1" );
+ }
+ if ( input_mapper->mibEnum() == 11 ) // 8859-8
+ input_mapper = TQTextCodec::codecForName( "ISO 8859-8-I");
+ if( data )
+ XFree( (char *)data );
+}
+
+// set font, foreground and background from x11 resources. The
+// arguments may override the resource settings.
+static void qt_set_x11_resources( const char* font = 0, const char* fg = 0,
+ const char* bg = 0, const char* button = 0 )
+{
+ if ( !qt_std_pal )
+ qt_create_std_palette();
+
+ TQCString resFont, resFG, resBG, resEF, sysFont;
+
+ TQApplication::setEffectEnabled( TQt::UI_General, FALSE);
+ TQApplication::setEffectEnabled( TQt::UI_AnimateMenu, FALSE);
+ TQApplication::setEffectEnabled( TQt::UI_FadeMenu, FALSE);
+ TQApplication::setEffectEnabled( TQt::UI_AnimateCombo, FALSE );
+ TQApplication::setEffectEnabled( TQt::UI_AnimateTooltip, FALSE );
+ TQApplication::setEffectEnabled( TQt::UI_FadeTooltip, FALSE );
+ TQApplication::setEffectEnabled( TQt::UI_AnimateToolBox, FALSE );
+
+ if ( TQApplication::desktopSettingsAware() && !TQApplication::x11_apply_settings() ) {
+ int format;
+ ulong nitems, after = 1;
+ TQCString res;
+ long offset = 0;
+ Atom type = None;
+
+ while (after > 0) {
+ uchar *data;
+ XGetWindowProperty( appDpy, TQPaintDevice::x11AppRootWindow( 0 ),
+ qt_resource_manager,
+ offset, 8192, False, AnyPropertyType,
+ &type, &format, &nitems, &after,
+ &data );
+ res += (char*)data;
+ offset += 2048; // offset is in 32bit quantities... 8192/4 == 2048
+ if ( data )
+ XFree( (char *)data );
+ }
+
+ TQCString key, value;
+ int l = 0, r;
+ TQCString apn = appName;
+ TQCString apc = appClass;
+ int apnl = apn.length();
+ int apcl = apc.length();
+ int resl = res.length();
+
+ while (l < resl) {
+ r = res.tqfind( '\n', l );
+ if ( r < 0 )
+ r = resl;
+ while ( isspace((uchar) res[l]) )
+ l++;
+ bool mine = FALSE;
+ if ( res[l] == '*' &&
+ (res[l+1] == 'f' || res[l+1] == 'b' || res[l+1] == 'g' ||
+ res[l+1] == 'F' || res[l+1] == 'B' || res[l+1] == 'G' ||
+ res[l+1] == 's' || res[l+1] == 'S' ) ) {
+ // OPTIMIZED, since we only want "*[fbgs].."
+
+ TQCString item = res.mid( l, r - l ).simplifyWhiteSpace();
+ int i = item.tqfind( ":" );
+ key = item.left( i ).stripWhiteSpace().mid(1).lower();
+ value = item.right( item.length() - i - 1 ).stripWhiteSpace();
+ mine = TRUE;
+ } else if ( res[l] == appName[0] || (appClass && res[l] == appClass[0]) ) {
+ if (res.mid(l,apnl) == apn && (res[l+apnl] == '.' || res[l+apnl] == '*')) {
+ TQCString item = res.mid( l, r - l ).simplifyWhiteSpace();
+ int i = item.tqfind( ":" );
+ key = item.left( i ).stripWhiteSpace().mid(apnl+1).lower();
+ value = item.right( item.length() - i - 1 ).stripWhiteSpace();
+ mine = TRUE;
+ } else if (res.mid(l,apcl) == apc && (res[l+apcl] == '.' || res[l+apcl] == '*')) {
+ TQCString item = res.mid( l, r - l ).simplifyWhiteSpace();
+ int i = item.tqfind( ":" );
+ key = item.left( i ).stripWhiteSpace().mid(apcl+1).lower();
+ value = item.right( item.length() - i - 1 ).stripWhiteSpace();
+ mine = TRUE;
+ }
+ }
+
+ if ( mine ) {
+ if ( !font && key == "systemfont")
+ sysFont = value.left( value.tqfindRev(':') ).copy();
+ if ( !font && key == "font")
+ resFont = value.copy();
+ else if ( !fg && key == "foreground" )
+ resFG = value.copy();
+ else if ( !bg && key == "background")
+ resBG = value.copy();
+ else if ( key == "guieffects")
+ resEF = value.copy();
+ // NOTE: if you add more, change the [fbg] stuff above
+ }
+
+ l = r + 1;
+ }
+ }
+ if ( !sysFont.isEmpty() )
+ resFont = sysFont;
+ if ( resFont.isEmpty() )
+ resFont = font;
+ if ( resFG.isEmpty() )
+ resFG = fg;
+ if ( resBG.isEmpty() )
+ resBG = bg;
+ if ( (!qt_app_has_font || qt_x11_cmdline_font) && !resFont.isEmpty() ) { // set application font
+ TQFont fnt;
+ fnt.setRawName( resFont );
+
+ // the font we get may actually be an alias for another font,
+ // so we reset the application font to the real font info.
+ if ( ! fnt.exactMatch() ) {
+ TQFontInfo fontinfo( fnt );
+ fnt.setFamily( fontinfo.family() );
+ fnt.setRawMode( fontinfo.rawMode() );
+
+ if ( ! fnt.rawMode() ) {
+ fnt.setItalic( fontinfo.italic() );
+ fnt.setWeight( fontinfo.weight() );
+ fnt.setUnderline( fontinfo.underline() );
+ fnt.setStrikeOut( fontinfo.strikeOut() );
+ fnt.setStyleHint( fontinfo.tqstyleHint() );
+
+ if ( fnt.pointSize() <= 0 && fnt.pixelSize() <= 0 )
+ // size is all wrong... fix it
+ fnt.setPointSize( (int) ( ( fontinfo.pixelSize() * 72. /
+ (float) TQPaintDevice::x11AppDpiY() ) +
+ 0.5 ) );
+ }
+ }
+
+ if ( fnt != TQApplication::font() ) {
+ TQApplication::setFont( fnt, TRUE );
+ }
+ }
+
+ if ( button || !resBG.isEmpty() || !resFG.isEmpty() ) {// set app colors
+ TQColor btn;
+ TQColor bg;
+ TQColor fg;
+ if ( !resBG.isEmpty() )
+ bg = TQColor(TQString(resBG));
+ else
+ bg = qt_std_pal->active().background();
+ if ( !resFG.isEmpty() )
+ fg = TQColor(TQString(resFG));
+ else
+ fg = qt_std_pal->active().foreground();
+ if ( button )
+ btn = TQColor( button );
+ else if ( !resBG.isEmpty() )
+ btn = bg;
+ else
+ btn = qt_std_pal->active().button();
+
+ int h,s,v;
+ fg.hsv(&h,&s,&v);
+ TQColor base = TQt::white;
+ bool bright_mode = FALSE;
+ if (v >= 255-50) {
+ base = btn.dark(150);
+ bright_mode = TRUE;
+ }
+
+ TQColorGroup cg( fg, btn, btn.light(),
+ btn.dark(), btn.dark(150), fg, TQt::white, base, bg );
+ if (bright_mode) {
+ cg.setColor( TQColorGroup::HighlightedText, base );
+ cg.setColor( TQColorGroup::Highlight, TQt::white );
+ } else {
+ cg.setColor( TQColorGroup::HighlightedText, TQt::white );
+ cg.setColor( TQColorGroup::Highlight, TQt::darkBlue );
+ }
+ TQColor disabled( (fg.red()+btn.red())/2,
+ (fg.green()+btn.green())/2,
+ (fg.blue()+btn.blue())/2);
+ TQColorGroup dcg( disabled, btn, btn.light( 125 ), btn.dark(), btn.dark(150),
+ disabled, TQt::white, TQt::white, bg );
+ if (bright_mode) {
+ dcg.setColor( TQColorGroup::HighlightedText, base );
+ dcg.setColor( TQColorGroup::Highlight, TQt::white );
+ } else {
+ dcg.setColor( TQColorGroup::HighlightedText, TQt::white );
+ dcg.setColor( TQColorGroup::Highlight, TQt::darkBlue );
+ }
+ TQPalette pal( cg, dcg, cg );
+ if ( pal != *qt_std_pal && pal != TQApplication::palette() )
+ TQApplication::setPalette( pal, TRUE );
+ *qt_std_pal = pal;
+ }
+
+ if ( !resEF.isEmpty() ) {
+ TQStringList effects = TQStringList::split(" ",resEF);
+ TQApplication::setEffectEnabled( TQt::UI_General, effects.tqcontains("general") );
+ TQApplication::setEffectEnabled( TQt::UI_AnimateMenu, effects.tqcontains("animatemenu") );
+ TQApplication::setEffectEnabled( TQt::UI_FadeMenu, effects.tqcontains("fademenu") );
+ TQApplication::setEffectEnabled( TQt::UI_AnimateCombo, effects.tqcontains("animatecombo") );
+ TQApplication::setEffectEnabled( TQt::UI_AnimateTooltip, effects.tqcontains("animatetooltip") );
+ TQApplication::setEffectEnabled( TQt::UI_FadeTooltip, effects.tqcontains("fadetooltip") );
+ TQApplication::setEffectEnabled( TQt::UI_AnimateToolBox, effects.tqcontains("animatetoolbox") );
+ }
+}
+
+
+static void qt_detect_broken_window_manager()
+{
+ Atom type;
+ int format;
+ ulong nitems, after;
+ uchar *data = 0;
+
+ // look for SGI's 4Dwm
+ int e = XGetWindowProperty(appDpy, TQPaintDevice::x11AppRootWindow(),
+ qt_sgi_desks_manager, 0, 1, False, XA_WINDOW,
+ &type, &format, &nitems, &after, &data);
+ if (data)
+ XFree(data);
+
+ if (e == Success && type == XA_WINDOW && format == 32 && nitems == 1 && after == 0) {
+ // detected SGI 4Dwm
+ qt_broken_wm = TRUE;
+ }
+}
+
+
+// update the supported array
+void qt_get_net_supported()
+{
+ Atom type;
+ int format;
+ long offset = 0;
+ unsigned long nitems, after;
+ unsigned char *data = 0;
+
+ int e = XGetWindowProperty(appDpy, TQPaintDevice::x11AppRootWindow(),
+ qt_net_supported, 0, 0,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+ if (data)
+ XFree(data);
+
+ if (qt_net_supported_list)
+ delete [] qt_net_supported_list;
+ qt_net_supported_list = 0;
+
+ if (e == Success && type == XA_ATOM && format == 32) {
+ TQBuffer ts;
+ ts.open(IO_WriteOnly);
+
+ while (after > 0) {
+ XGetWindowProperty(appDpy, TQPaintDevice::x11AppRootWindow(),
+ qt_net_supported, offset, 1024,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+
+ if (type == XA_ATOM && format == 32) {
+ ts.writeBlock((const char *) data, nitems * sizeof(long));
+ offset += nitems;
+ } else
+ after = 0;
+ if (data)
+ XFree(data);
+ }
+
+ // compute nitems
+ TQByteArray buffer(ts.buffer());
+ nitems = buffer.size() / sizeof(Atom);
+ qt_net_supported_list = new Atom[nitems + 1];
+ Atom *a = (Atom *) buffer.data();
+ uint i;
+ for (i = 0; i < nitems; i++)
+ qt_net_supported_list[i] = a[i];
+ qt_net_supported_list[nitems] = 0;
+ }
+}
+
+
+bool qt_net_supports(Atom atom)
+{
+ if (! qt_net_supported_list)
+ return FALSE;
+
+ bool supported = FALSE;
+ int i = 0;
+ while (qt_net_supported_list[i] != 0) {
+ if (qt_net_supported_list[i++] == atom) {
+ supported = TRUE;
+ break;
+ }
+ }
+
+ return supported;
+}
+
+
+// update the virtual roots array
+void qt_get_net_virtual_roots()
+{
+ if (qt_net_virtual_root_list)
+ delete [] qt_net_virtual_root_list;
+ qt_net_virtual_root_list = 0;
+
+ if (! qt_net_supports(qt_net_virtual_roots))
+ return;
+
+ Atom type;
+ int format;
+ long offset = 0;
+ unsigned long nitems, after;
+ unsigned char *data;
+
+ int e = XGetWindowProperty(appDpy, TQPaintDevice::x11AppRootWindow(),
+ qt_net_virtual_roots, 0, 0,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+ if (data)
+ XFree(data);
+
+ if (e == Success && type == XA_ATOM && format == 32) {
+ TQBuffer ts;
+ ts.open(IO_WriteOnly);
+
+ while (after > 0) {
+ XGetWindowProperty(appDpy, TQPaintDevice::x11AppRootWindow(),
+ qt_net_virtual_roots, offset, 1024,
+ False, XA_ATOM, &type, &format, &nitems, &after, &data);
+
+ if (type == XA_ATOM && format == 32) {
+ ts.writeBlock((const char *) data, nitems * 4);
+ offset += nitems;
+ } else
+ after = 0;
+ if (data)
+ XFree(data);
+ }
+
+ // compute nitems
+ TQByteArray buffer(ts.buffer());
+ nitems = buffer.size() / sizeof(Window);
+ qt_net_virtual_root_list = new Window[nitems + 1];
+ Window *a = (Window *) buffer.data();
+ uint i;
+ for (i = 0; i < nitems; i++)
+ qt_net_virtual_root_list[i] = a[i];
+ qt_net_virtual_root_list[nitems] = 0;
+ }
+}
+
+void qt_x11_create_wm_client_leader()
+{
+ if ( qt_x11_wm_client_leader ) return;
+
+ qt_x11_wm_client_leader =
+ XCreateSimpleWindow( TQPaintDevice::x11AppDisplay(),
+ TQPaintDevice::x11AppRootWindow(),
+ 0, 0, 1, 1, 0, 0, 0 );
+
+ // set client leader property to itself
+ XChangeProperty( TQPaintDevice::x11AppDisplay(),
+ qt_x11_wm_client_leader, qt_wm_client_leader,
+ XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)&qt_x11_wm_client_leader, 1 );
+
+ // If we are session managed, inform the window manager about it
+ TQCString session = tqApp->sessionId().latin1();
+ if ( !session.isEmpty() ) {
+ XChangeProperty( TQPaintDevice::x11AppDisplay(),
+ qt_x11_wm_client_leader, qt_sm_client_id,
+ XA_STRING, 8, PropModeReplace,
+ (unsigned char *)session.data(), session.length() );
+ }
+}
+
+static void qt_net_update_user_time(TQWidget *tlw)
+{
+ Time my_tqx_user_time = GET_QT_X_USER_TIME();
+ XChangeProperty(TQPaintDevice::x11AppDisplay(), tlw->winId(), qt_net_wm_user_time, XA_CARDINAL,
+ 32, PropModeReplace, (unsigned char *) &my_tqx_user_time, 1);
+ SET_QT_X_USER_TIME(my_tqx_user_time);
+}
+
+static void qt_check_focus_model()
+{
+ Window fw = None;
+ int unused;
+ XGetInputFocus( appDpy, &fw, &unused );
+ if ( fw == PointerRoot )
+ qt_focus_model = FocusModel_PointerRoot;
+ else
+ qt_focus_model = FocusModel_Other;
+}
+
+
+/*
+ Returns a truecolor visual (if there is one). 8-bit TrueColor visuals
+ are ignored, unless the user has explicitly requested -visual TrueColor.
+ The SGI X server usually has an 8 bit default visual, but the application
+ can also ask for a truecolor visual. This is what we do if
+ TQApplication::colorSpec() is TQApplication::ManyColor.
+*/
+
+static Visual *tqfind_truecolor_visual( Display *dpy, int scr, int *depth, int *ncols )
+{
+ XVisualInfo *vi, rvi;
+ int best=0, n, i;
+ rvi.c_class = TrueColor;
+ rvi.screen = scr;
+ vi = XGetVisualInfo( dpy, VisualClassMask | VisualScreenMask,
+ &rvi, &n );
+ if ( vi ) {
+ for ( i=0; i<n; i++ ) {
+ if ( vi[i].depth > vi[best].depth )
+ best = i;
+ }
+ }
+ Visual *v = DefaultVisual(dpy,scr);
+ if ( !vi || (vi[best].visualid == XVisualIDFromVisual(v)) ||
+ (vi[best].depth <= 8 && qt_visual_option != TrueColor) )
+ {
+ *depth = DefaultDepth(dpy,scr);
+ *ncols = DisplayCells(dpy,scr);
+ } else {
+ v = vi[best].visual;
+ *depth = vi[best].depth;
+ *ncols = vi[best].colormap_size;
+ }
+ if ( vi )
+ XFree( (char *)vi );
+ return v;
+}
+
+
+/*****************************************************************************
+ qt_init() - initializes TQt for X11
+ *****************************************************************************/
+
+#define XK_MISCELLANY
+#define XK_LATIN1
+#include <X11/keysymdef.h>
+
+// ### This should be static but it isn't because of the friend declaration
+// ### in tqpaintdevice.h which then should have a static too but can't have
+// ### it because "storage class specifiers invalid in friend function
+// ### declarations" :-) Ideas anyone?
+void qt_init_internal( int *argcptr, char **argv,
+ Display *display, TQt::HANDLE visual, TQt::HANDLE colormap )
+{
+ setlocale( LC_ALL, "" ); // use correct char set mapping
+ setlocale( LC_NUMERIC, "C" ); // make sprintf()/scanf() work
+
+ if ( display ) {
+ // TQt part of other application
+
+ appForeignDpy = TRUE;
+ appDpy = display;
+
+ // Set application name and class
+ appName = qstrdup( "TQt-subapplication" );
+ char *app_class = 0;
+ if (argv) {
+ const char* p = strrchr( argv[0], '/' );
+ app_class = qstrdup(p ? p + 1 : argv[0]);
+ if (app_class[0])
+ app_class[0] = toupper(app_class[0]);
+ }
+ appClass = app_class;
+
+ // Install default error handlers
+ original_x_errhandler = XSetErrorHandler( qt_x_errhandler );
+ original_xio_errhandler = XSetIOErrorHandler( qt_xio_errhandler );
+ } else {
+ // TQt controls everything (default)
+
+ int argc = *argcptr;
+ int j;
+
+ // Install default error handlers
+ original_x_errhandler = XSetErrorHandler( qt_x_errhandler );
+ original_xio_errhandler = XSetIOErrorHandler( qt_xio_errhandler );
+
+ // Set application name and class
+ char *app_class = 0;
+ if (argv) {
+ const char *p = strrchr( argv[0], '/' );
+ appName = p ? p + 1 : argv[0];
+ app_class = qstrdup(appName);
+ if (app_class[0])
+ app_class[0] = toupper(app_class[0]);
+ }
+ appClass = app_class;
+
+ // Get command line params
+ j = argc ? 1 : 0;
+ for ( int i=1; i<argc; i++ ) {
+ if ( argv[i] && *argv[i] != '-' ) {
+ argv[j++] = argv[i];
+ continue;
+ }
+ TQCString arg = argv[i];
+ if ( arg == "-display" ) {
+ if ( ++i < argc )
+ appDpyName = argv[i];
+ } else if ( arg == "-fn" || arg == "-font" ) {
+ if ( ++i < argc ) {
+ appFont = argv[i];
+ qt_x11_cmdline_font = true;
+ }
+ } else if ( arg == "-bg" || arg == "-background" ) {
+ if ( ++i < argc )
+ appBGCol = argv[i];
+ } else if ( arg == "-btn" || arg == "-button" ) {
+ if ( ++i < argc )
+ appBTNCol = argv[i];
+ } else if ( arg == "-fg" || arg == "-foreground" ) {
+ if ( ++i < argc )
+ appFGCol = argv[i];
+ } else if ( arg == "-name" ) {
+ if ( ++i < argc )
+ appName = argv[i];
+ } else if ( arg == "-title" ) {
+ if ( ++i < argc )
+ mwTitle = argv[i];
+ } else if ( arg == "-tqgeometry" ) {
+ if ( ++i < argc )
+ mwGeometry = argv[i];
+ //Ming-Che 10/10
+ } else if ( arg == "-im" ) {
+ if ( ++i < argc )
+ ximServer = argv[i];
+ } else if ( arg == "-noxim" ) {
+ noxim=TRUE;
+ //
+ } else if ( arg == "-iconic" ) {
+ mwIconic = !mwIconic;
+ } else if ( arg == "-ncols" ) { // xv and netscape use this name
+ if ( ++i < argc )
+ qt_ncols_option = TQMAX(0,atoi(argv[i]));
+ } else if ( arg == "-visual" ) { // xv and netscape use this name
+ if ( ++i < argc ) {
+ TQCString s = TQCString(argv[i]).lower();
+ if ( s == "truecolor" ) {
+ qt_visual_option = TrueColor;
+ } else {
+ // ### Should we honor any others?
+ }
+ }
+#ifndef TQT_NO_XIM
+ } else if ( arg == "-inputstyle" ) {
+ if ( ++i < argc ) {
+ TQCString s = TQCString(argv[i]).lower();
+ if ( s == "onthespot" )
+ xim_preferred_style = XIMPreeditCallbacks |
+ XIMStatusNothing;
+ else if ( s == "overthespot" )
+ xim_preferred_style = XIMPreeditPosition |
+ XIMStatusNothing;
+ else if ( s == "offthespot" )
+ xim_preferred_style = XIMPreeditArea |
+ XIMStatusArea;
+ else if ( s == "root" )
+ xim_preferred_style = XIMPreeditNothing |
+ XIMStatusNothing;
+ }
+#endif
+ } else if ( arg == "-cmap" ) { // xv uses this name
+ qt_cmap_option = TRUE;
+ }
+#if defined(TQT_DEBUG)
+ else if ( arg == "-sync" )
+ appSync = !appSync;
+ else if ( arg == "-nograb" )
+ appNoGrab = !appNoGrab;
+ else if ( arg == "-dograb" )
+ appDoGrab = !appDoGrab;
+#endif
+ else
+ argv[j++] = argv[i];
+ }
+
+ *argcptr = j;
+
+#if defined(TQT_DEBUG) && defined(TQ_OS_LINUX)
+ if ( !appNoGrab && !appDoGrab ) {
+ TQCString s;
+ s.sprintf( "/proc/%d/cmdline", getppid() );
+ TQFile f( s );
+ if ( f.open( IO_ReadOnly ) ) {
+ s.truncate( 0 );
+ int c;
+ while ( (c = f.getch()) > 0 ) {
+ if ( c == '/' )
+ s.truncate( 0 );
+ else
+ s += (char)c;
+ }
+ if ( s == "gdb" ) {
+ appNoGrab = TRUE;
+ qDebug( "TQt: gdb: -nograb added to command-line options.\n"
+ "\t Use the -dograb option to enforce grabbing." );
+ }
+ f.close();
+ }
+ }
+#endif
+ // Connect to X server
+
+ if( qt_is_gui_used ) {
+ if ( ( appDpy = XOpenDisplay(appDpyName) ) == 0 ) {
+ qWarning( "%s: cannot connect to X server %s", appName,
+ XDisplayName(appDpyName) );
+ tqApp = 0;
+ exit( 1 );
+ }
+
+ if ( appSync ) // if "-sync" argument
+ XSynchronize( appDpy, TRUE );
+ }
+ }
+ // Common code, regardless of whether display is foreign.
+
+ // Get X parameters
+
+ if( qt_is_gui_used ) {
+ appScreen = DefaultScreen(appDpy);
+ appScreenCount = ScreenCount(appDpy);
+
+ TQPaintDevice::x_appdisplay = appDpy;
+ TQPaintDevice::x_appscreen = appScreen;
+
+ // allocate the arrays for the TQPaintDevice data
+ TQPaintDevice::x_appdepth_arr = new int[ appScreenCount ];
+ TQPaintDevice::x_appcells_arr = new int[ appScreenCount ];
+ TQPaintDevice::x_approotwindow_arr = new TQt::HANDLE[ appScreenCount ];
+ TQPaintDevice::x_appcolormap_arr = new TQt::HANDLE[ appScreenCount ];
+ TQPaintDevice::x_appdefcolormap_arr = new bool[ appScreenCount ];
+ TQPaintDevice::x_appvisual_arr = new void*[ appScreenCount ];
+ TQPaintDevice::x_appdefvisual_arr = new bool[ appScreenCount ];
+ TQ_CHECK_PTR( TQPaintDevice::x_appdepth_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_appcells_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_approotwindow_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_appcolormap_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_appdefcolormap_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_appvisual_arr );
+ TQ_CHECK_PTR( TQPaintDevice::x_appdefvisual_arr );
+
+ int screen;
+ TQString serverVendor( ServerVendor( appDpy) );
+ if (serverVendor.tqcontains("XFree86") && VendorRelease(appDpy) < 40300000)
+ qt_hebrew_keyboard_hack = TRUE;
+
+ for ( screen = 0; screen < appScreenCount; ++screen ) {
+ TQPaintDevice::x_appdepth_arr[ screen ] = DefaultDepth(appDpy, screen);
+ TQPaintDevice::x_appcells_arr[ screen ] = DisplayCells(appDpy, screen);
+ TQPaintDevice::x_approotwindow_arr[ screen ] = RootWindow(appDpy, screen);
+
+ // setup the visual and colormap for each screen
+ Visual *vis = 0;
+ if ( visual && screen == appScreen ) {
+ // use the provided visual on the default screen only
+ vis = (Visual *) visual;
+
+ // figure out the depth of the visual we are using
+ XVisualInfo *vi, rvi;
+ int n;
+ rvi.visualid = XVisualIDFromVisual(vis);
+ rvi.screen = screen;
+ vi = XGetVisualInfo( appDpy, VisualIDMask | VisualScreenMask, &rvi, &n );
+ if (vi) {
+ TQPaintDevice::x_appdepth_arr[ screen ] = vi->depth;
+ TQPaintDevice::x_appcells_arr[ screen ] = vi->visual->map_entries;
+ TQPaintDevice::x_appvisual_arr[ screen ] = vi->visual;
+ TQPaintDevice::x_appdefvisual_arr[ screen ] = FALSE;
+ XFree(vi);
+ } else {
+ // couldn't get info about the visual, use the default instead
+ vis = 0;
+ }
+ }
+
+ if (!vis) {
+ // use the default visual
+ vis = DefaultVisual(appDpy, screen);
+ TQPaintDevice::x_appdefvisual_arr[ screen ] = TRUE;
+
+ if ( qt_visual_option == TrueColor ||
+ TQApplication::colorSpec() == TQApplication::ManyColor ) {
+ // tqfind custom visual
+
+ int d, c;
+ vis = tqfind_truecolor_visual( appDpy, screen, &d, &c );
+ TQPaintDevice::x_appdepth_arr[ screen ] = d;
+ TQPaintDevice::x_appcells_arr[ screen ] = c;
+
+ TQPaintDevice::x_appvisual_arr[ screen ] = vis;
+ TQPaintDevice::x_appdefvisual_arr[ screen ] =
+ (XVisualIDFromVisual(vis) ==
+ XVisualIDFromVisual(DefaultVisual(appDpy, screen)));
+ }
+
+ TQPaintDevice::x_appvisual_arr[ screen ] = vis;
+ }
+
+ // we assume that 8bpp == pseudocolor, but this is not
+ // always the case (according to the X server), so we need
+ // to make sure that our internal data is setup in a way
+ // that is compatible with our assumptions
+ if ( vis->c_class == TrueColor &&
+ TQPaintDevice::x_appdepth_arr[ screen ] == 8 &&
+ TQPaintDevice::x_appcells_arr[ screen ] == 8 )
+ TQPaintDevice::x_appcells_arr[ screen ] = 256;
+
+ if ( colormap && screen == appScreen ) {
+ // use the provided colormap for the default screen only
+ TQPaintDevice::x_appcolormap_arr[ screen ] = colormap;
+ TQPaintDevice::x_appdefcolormap_arr[ screen ] = FALSE;
+ } else {
+ if ( vis->c_class == TrueColor ) {
+ TQPaintDevice::x_appdefcolormap_arr[ screen ] =
+ TQPaintDevice::x_appdefvisual_arr[ screen ];
+ } else {
+ TQPaintDevice::x_appdefcolormap_arr[ screen ] =
+ !qt_cmap_option && TQPaintDevice::x_appdefvisual_arr[ screen ];
+ }
+
+ if ( TQPaintDevice::x_appdefcolormap_arr[ screen ] ) {
+ // use default colormap
+ XStandardColormap *stdcmap;
+ VisualID vid =
+ XVisualIDFromVisual((Visual *)
+ TQPaintDevice::x_appvisual_arr[ screen ]);
+ int i, count;
+
+ TQPaintDevice::x_appcolormap_arr[ screen ] = 0;
+
+ if ( ! serverVendor.tqcontains( "Hewlett-Packard" ) ) {
+ // on HPUX 10.20 local displays, the RGB_DEFAULT_MAP colormap
+ // doesn't give us correct colors. Why this happens, I have
+ // no clue, so we disable this for HPUX
+ if (XGetRGBColormaps(appDpy,
+ TQPaintDevice::x11AppRootWindow( screen ),
+ &stdcmap, &count, XA_RGB_DEFAULT_MAP)) {
+ i = 0;
+ while (i < count &&
+ TQPaintDevice::x_appcolormap_arr[ screen ] == 0) {
+ if (stdcmap[i].visualid == vid) {
+ TQPaintDevice::x_appcolormap_arr[ screen ] =
+ stdcmap[i].colormap;
+ }
+ i++;
+ }
+
+ XFree( (char *)stdcmap );
+ }
+ }
+
+ if (TQPaintDevice::x_appcolormap_arr[ screen ] == 0) {
+ TQPaintDevice::x_appcolormap_arr[ screen ] =
+ DefaultColormap(appDpy, screen);
+ }
+ } else {
+ // create a custom colormap
+ TQPaintDevice::x_appcolormap_arr[ screen ] =
+ XCreateColormap(appDpy, TQPaintDevice::x11AppRootWindow( screen ),
+ vis, AllocNone);
+ }
+ }
+ }
+
+ // Set X painttqdevice parameters for the default screen
+ TQPaintDevice::x_appdepth = TQPaintDevice::x_appdepth_arr[ appScreen ];
+ TQPaintDevice::x_appcells = TQPaintDevice::x_appcells_arr[ appScreen ];
+ TQPaintDevice::x_approotwindow = TQPaintDevice::x_approotwindow_arr[ appScreen ];
+ TQPaintDevice::x_appcolormap = TQPaintDevice::x_appcolormap_arr[ appScreen ];
+ TQPaintDevice::x_appdefcolormap = TQPaintDevice::x_appdefcolormap_arr[ appScreen ];
+ TQPaintDevice::x_appvisual = TQPaintDevice::x_appvisual_arr[ appScreen ];
+ TQPaintDevice::x_appdefvisual = TQPaintDevice::x_appdefvisual_arr[ appScreen ];
+
+ // Support protocols
+
+ qt_x11_intern_atom( "WM_PROTOCOLS", &qt_wm_protocols );
+ qt_x11_intern_atom( "WM_DELETE_WINDOW", &qt_wm_delete_window );
+ qt_x11_intern_atom( "WM_STATE", &qt_wm_state );
+ qt_x11_intern_atom( "WM_CHANGE_STATE", &qt_wm_change_state );
+ qt_x11_intern_atom( "WM_TAKE_FOCUS", &qt_wm_take_focus );
+ qt_x11_intern_atom( "WM_CLIENT_LEADER", &qt_wm_client_leader);
+ qt_x11_intern_atom( "WM_WINDOW_ROLE", &qt_window_role);
+ qt_x11_intern_atom( "SM_CLIENT_ID", &qt_sm_client_id);
+ qt_x11_intern_atom( "CLIPBOARD", &qt_xa_clipboard );
+ qt_x11_intern_atom( "RESOURCE_MANAGER", &qt_resource_manager );
+ qt_x11_intern_atom( "INCR", &qt_x_incr );
+ qt_x11_intern_atom( "_XSETROOT_ID", &qt_xsetroot_id );
+ qt_x11_intern_atom( "_TQT_SELECTION", &qt_selection_property );
+ qt_x11_intern_atom( "_TQT_CLIPBOARD_SENTINEL", &qt_clipboard_sentinel );
+ qt_x11_intern_atom( "_TQT_SELECTION_SENTINEL", &qt_selection_sentinel );
+ qt_x11_intern_atom( "_TQT_SCROLL_DONE", &qt_qt_scrolldone );
+ qt_x11_intern_atom( "_TQT_INPUT_ENCODING", &qt_input_encoding );
+ qt_x11_intern_atom( "_TQT_SIZEGRIP", &qt_sizegrip );
+ qt_x11_intern_atom( "_NET_WM_CONTEXT_HELP", &qt_net_wm_context_help );
+ qt_x11_intern_atom( "_NET_WM_PING", &qt_net_wm_ping );
+ qt_x11_intern_atom( "_MOTIF_WM_HINTS", &qt_xa_motif_wm_hints );
+ qt_x11_intern_atom( "DTWM_IS_RUNNING", &qt_cde_running );
+ qt_x11_intern_atom( "KWIN_RUNNING", &qt_kwin_running );
+ qt_x11_intern_atom( "KWM_RUNNING", &qt_kwm_running );
+ qt_x11_intern_atom( "GNOME_BACKGROUND_PROPERTIES", &qt_gbackground_properties );
+
+ TQString atomname("_TQT_SETTINGS_TIMESTAMP_");
+ atomname += XDisplayName(appDpyName);
+ qt_x11_intern_atom( atomname.latin1(), &qt_settings_timestamp );
+
+ qt_x11_intern_atom( "_NET_SUPPORTED", &qt_net_supported );
+ qt_x11_intern_atom( "_NET_VIRTUAL_ROOTS", &qt_net_virtual_roots );
+ qt_x11_intern_atom( "_NET_WORKAREA", &qt_net_workarea );
+ qt_x11_intern_atom( "_NET_WM_STATE", &qt_net_wm_state );
+ qt_x11_intern_atom( "_NET_WM_STATE_MODAL", &qt_net_wm_state_modal );
+ qt_x11_intern_atom( "_NET_WM_STATE_MAXIMIZED_VERT", &qt_net_wm_state_max_v );
+ qt_x11_intern_atom( "_NET_WM_STATE_MAXIMIZED_HORZ", &qt_net_wm_state_max_h );
+ qt_x11_intern_atom( "_NET_WM_STATE_FULLSCREEN", &qt_net_wm_state_fullscreen );
+ qt_x11_intern_atom( "_NET_WM_STATE_ABOVE", &qt_net_wm_state_above );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE", &qt_net_wm_window_type );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_NORMAL", &qt_net_wm_window_type_normal );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_DIALOG", &qt_net_wm_window_type_dialog );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_TOOLBAR", &qt_net_wm_window_type_toolbar );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_MENU", &qt_net_wm_window_type_menu );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_UTILITY", &qt_net_wm_window_type_utility );
+ qt_x11_intern_atom( "_NET_WM_WINDOW_TYPE_SPLASH", &qt_net_wm_window_type_splash );
+ qt_x11_intern_atom( "_KDE_NET_WM_WINDOW_TYPE_OVERRIDE", &qt_net_wm_window_type_override );
+ qt_x11_intern_atom( "_KDE_NET_WM_FRAME_STRUT", &qt_net_wm_frame_strut );
+ qt_x11_intern_atom( "_NET_WM_STATE_STAYS_ON_TOP",
+ &qt_net_wm_state_stays_on_top );
+ qt_x11_intern_atom( "_NET_WM_PID", &qt_net_wm_pid );
+ qt_x11_intern_atom( "_NET_WM_USER_TIME", &qt_net_wm_user_time );
+ qt_x11_intern_atom( "ENLIGHTENMENT_DESKTOP", &qt_enlightenment_desktop );
+ qt_x11_intern_atom( "_NET_WM_NAME", &qt_net_wm_name );
+ qt_x11_intern_atom( "_NET_WM_ICON_NAME", &qt_net_wm_icon_name );
+ qt_x11_intern_atom( "UTF8_STRING", &qt_utf8_string );
+ qt_x11_intern_atom( "_SGI_DESKS_MANAGER", &qt_sgi_desks_manager );
+
+ qt_xdnd_setup();
+ qt_x11_motifdnd_init();
+
+ // Finally create all atoms
+ qt_x11_process_intern_atoms();
+
+ // look for broken window managers
+ qt_detect_broken_window_manager();
+
+ // initialize NET lists
+ qt_get_net_supported();
+ qt_get_net_virtual_roots();
+
+#ifndef TQT_NO_XRANDR
+ // See if XRandR is supported on the connected display
+ int xrandr_errorbase;
+ TQ_UNUSED( xrandr_eventbase );
+ if ( XRRQueryExtension( appDpy, &xrandr_eventbase, &xrandr_errorbase ) ) {
+ // XRandR is supported
+ qt_use_xrandr = TRUE;
+ }
+#endif // TQT_NO_XRANDR
+
+#ifndef TQT_NO_XRENDER
+ // See if XRender is supported on the connected display
+ int xrender_eventbase, xrender_errorbase;
+ if (XRenderQueryExtension(appDpy, &xrender_eventbase, &xrender_errorbase)) {
+ // XRender is supported, let's see if we have a PictFormat for the
+ // default visual
+ XRenderPictFormat *format =
+ XRenderFindVisualFormat(appDpy,
+ (Visual *) TQPaintDevice::x_appvisual);
+ qt_use_xrender = (format != 0) && (TQPaintDevice::x_appdepth != 8);
+ }
+#endif // TQT_NO_XRENDER
+
+#ifndef TQT_NO_XKB
+ // If XKB is detected, set the GrabsUseXKBState option so input method
+ // compositions continue to work (ie. deadkeys)
+ unsigned int state = XkbPCF_GrabsUseXKBStateMask;
+ (void) XkbSetPerClientControls(appDpy, state, &state);
+#endif
+
+#if !defined(TQT_NO_XFTFREETYPE)
+ // defined in qfont_x11.cpp
+ extern bool qt_has_xft;
+#ifndef TQT_XFT2
+ if (!qt_use_xrender)
+ qt_has_xft = FALSE;
+ else
+#endif
+ qt_has_xft = XftInit(0) && XftInitFtLibrary();
+
+ if (qt_has_xft) {
+ char *dpi_str = XGetDefault(appDpy, "Xft", "dpi");
+ if (dpi_str) {
+ // use a custom DPI
+ char *end = 0;
+ int dpi = strtol(dpi_str, &end, 0);
+ if (dpi_str != end) {
+ for (int s = 0; s < ScreenCount(appDpy); ++s) {
+ TQPaintDevice::x11SetAppDpiX(dpi, s);
+ TQPaintDevice::x11SetAppDpiY(dpi, s);
+ }
+ }
+ }
+ }
+#endif // TQT_NO_XFTFREETYPE
+
+ // look at the modifier mapping, and get the correct masks for alt/meta
+ // tqfind the alt/meta masks
+ XModifierKeymap *map = XGetModifierMapping(appDpy);
+ if (map) {
+ int i, maskIndex = 0, mapIndex = 0;
+ for (maskIndex = 0; maskIndex < 8; maskIndex++) {
+ for (i = 0; i < map->max_keypermod; i++) {
+ if (map->modifiermap[mapIndex]) {
+ KeySym sym =
+ XKeycodeToKeysym(appDpy, map->modifiermap[mapIndex], 0);
+ if ( qt_alt_mask == 0 &&
+ ( sym == XK_Alt_L || sym == XK_Alt_R ) ) {
+ qt_alt_mask = 1 << maskIndex;
+ }
+ if ( qt_meta_mask == 0 &&
+ (sym == XK_Meta_L || sym == XK_Meta_R ) ) {
+ qt_meta_mask = 1 << maskIndex;
+ }
+ }
+ mapIndex++;
+ }
+ }
+
+ // not look for mode_switch in qt_alt_mask and qt_meta_mask - if it is
+ // present in one or both, then we set qt_mode_switch_remove_mask.
+ // see TQETWidget::translateKeyEventInternal for an explanation
+ // of why this is needed
+ mapIndex = 0;
+ for ( maskIndex = 0; maskIndex < 8; maskIndex++ ) {
+ if ( qt_alt_mask != ( 1 << maskIndex ) &&
+ qt_meta_mask != ( 1 << maskIndex ) ) {
+ for ( i = 0; i < map->max_keypermod; i++ )
+ mapIndex++;
+ continue;
+ }
+
+ for ( i = 0; i < map->max_keypermod; i++ ) {
+ if ( map->modifiermap[ mapIndex ] ) {
+ KeySym sym =
+ XKeycodeToKeysym( appDpy, map->modifiermap[ mapIndex ], 0 );
+ if ( sym == XK_Mode_switch ) {
+ qt_mode_switch_remove_mask |= 1 << maskIndex;
+ }
+ }
+ mapIndex++;
+ }
+ }
+
+ XFreeModifiermap(map);
+ } else {
+ // assume defaults
+ qt_alt_mask = Mod1Mask;
+ qt_meta_mask = Mod4Mask;
+ qt_mode_switch_remove_mask = 0;
+ }
+
+ // Misc. initialization
+
+ TQColor::initialize();
+ TQFont::initialize();
+ TQCursor::initialize();
+ TQPainter::initialize();
+ }
+
+#if defined(TQT_THREAD_SUPPORT)
+ TQThread::initialize();
+#endif
+
+ if( qt_is_gui_used ) {
+ tqApp->setName( appName );
+
+ int screen;
+ for ( screen = 0; screen < appScreenCount; ++screen ) {
+ XSelectInput( appDpy, TQPaintDevice::x11AppRootWindow( screen ),
+ KeymapStateMask | EnterWindowMask | LeaveWindowMask |
+ PropertyChangeMask );
+
+#ifndef TQT_NO_XRANDR
+ if (qt_use_xrandr)
+ XRRSelectInput( appDpy, TQPaintDevice::x11AppRootWindow( screen ), True );
+#endif // TQT_NO_XRANDR
+ }
+ }
+
+ if ( qt_is_gui_used ) {
+ qt_set_input_encoding();
+
+ qt_set_x11_resources( appFont, appFGCol, appBGCol, appBTNCol);
+
+ // be smart about the size of the default font. most X servers have helvetica
+ // 12 point available at 2 resolutions:
+ // 75dpi (12 pixels) and 100dpi (17 pixels).
+ // At 95 DPI, a 12 point font should be 16 pixels tall - in which case a 17
+ // pixel font is a closer match than a 12 pixel font
+ int ptsz =
+ (int) ( ( ( TQPaintDevice::x11AppDpiY() >= 95 ? 17. : 12. ) *
+ 72. / (float) TQPaintDevice::x11AppDpiY() ) + 0.5 );
+
+ if ( !qt_app_has_font && !qt_x11_cmdline_font ) {
+ TQFont f( "Helvetica", ptsz );
+ TQApplication::setFont( f );
+ }
+
+#ifndef TQT_NO_XIM
+ if ( ! xim_preferred_style ) // no configured input style, use the default
+ xim_preferred_style = xim_default_style;
+
+ qt_xim = 0;
+ TQString ximServerName(ximServer);
+ if (ximServer)
+ ximServerName.prepend("@im=");
+ else
+ ximServerName = "";
+
+ if ( !XSupportsLocale() )
+ qWarning("TQt: Locales not supported on X server");
+
+#ifdef USE_X11R6_XIM
+ else if ( XSetLocaleModifiers (ximServerName.ascii()) == 0 )
+ qWarning( "TQt: Cannot set locale modifiers: %s",
+ ximServerName.ascii());
+ else if (! noxim)
+ XRegisterIMInstantiateCallback(appDpy, 0, 0, 0,
+ (XIMProc) xim_create_callback, 0);
+#else // !USE_X11R6_XIM
+ else if ( XSetLocaleModifiers ("") == 0 )
+ qWarning("TQt: Cannot set locale modifiers");
+ else if (! noxim)
+ TQApplication::create_xim();
+#endif // USE_X11R6_XIM
+#endif // TQT_NO_XIM
+
+#if defined (TQT_TABLET_SUPPORT)
+ int ndev,
+ i,
+ j;
+ bool gotStylus,
+ gotEraser;
+ XDeviceInfo *tqdevices, *devs;
+ XInputClassInfo *ip;
+ XAnyClassPtr any;
+ XValuatorInfoPtr v;
+ XAxisInfoPtr a;
+ XDevice *dev;
+ XEventClass *ev_class;
+ int curr_event_count;
+
+#if !defined(TQ_OS_IRIX)
+ // XFree86 divides a stylus and eraser into 2 tqdevices, so we must do for both...
+ const TQString XFREENAMESTYLUS = "stylus";
+ const TQString XFREENAMEPEN = "pen";
+ const TQString XFREENAMEERASER = "eraser";
+#endif
+
+ tqdevices = XListInputDevices( appDpy, &ndev);
+ if ( tqdevices == NULL ) {
+ qWarning( "Failed to get list of tqdevices" );
+ ndev = -1;
+ }
+ dev = NULL;
+ for ( devs = tqdevices, i = 0; i < ndev; i++, devs++ ) {
+ gotEraser = FALSE;
+#if defined(TQ_OS_IRIX)
+
+ gotStylus = ( !strncmp(devs->name,
+ WACOM_NAME, sizeof(WACOM_NAME) - 1) );
+#else
+ TQString devName = devs->name;
+ devName = devName.lower();
+ gotStylus = ( devName.startsWith(XFREENAMEPEN)
+ || devName.startsWith(XFREENAMESTYLUS) );
+ if ( !gotStylus )
+ gotEraser = devName.startsWith( XFREENAMEERASER );
+
+#endif
+ if ( gotStylus || gotEraser ) {
+ // I only wanted to do this once, so wrap pointers around these
+ curr_event_count = 0;
+
+ if ( gotStylus ) {
+ devStylus = XOpenDevice( appDpy, devs->id );
+ dev = devStylus;
+ ev_class = event_list_stylus;
+ } else if ( gotEraser ) {
+ devEraser = XOpenDevice( appDpy, devs->id );
+ dev = devEraser;
+ ev_class = event_list_eraser;
+ }
+ if ( dev == NULL ) {
+ qWarning( "Failed to open tqdevice" );
+ } else {
+ if ( dev->num_classes > 0 ) {
+ for ( ip = dev->classes, j = 0; j < devs->num_classes;
+ ip++, j++ ) {
+ switch ( ip->input_class ) {
+ case KeyClass:
+ DeviceKeyPress( dev, xinput_key_press,
+ ev_class[curr_event_count] );
+ curr_event_count++;
+ DeviceKeyRelease( dev, xinput_key_release,
+ ev_class[curr_event_count] );
+ curr_event_count++;
+ break;
+ case ButtonClass:
+ DeviceButtonPress( dev, xinput_button_press,
+ ev_class[curr_event_count] );
+ curr_event_count++;
+ DeviceButtonRelease( dev, xinput_button_release,
+ ev_class[curr_event_count] );
+ curr_event_count++;
+ break;
+ case ValuatorClass:
+ // I'm only going to be interested in motion when the
+ // stylus is already down anyway!
+ DeviceMotionNotify( dev, xinput_motion,
+ ev_class[curr_event_count] );
+ curr_event_count++;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ // get the min/max value for pressure!
+ any = (XAnyClassPtr) ( devs->inputclassinfo );
+ if ( dev == devStylus ) {
+ qt_curr_events_stylus = curr_event_count;
+ for (j = 0; j < devs->num_classes; j++) {
+ if ( any->c_class == ValuatorClass ) {
+ v = (XValuatorInfoPtr) any;
+ a = (XAxisInfoPtr) ((char *) v +
+ sizeof (XValuatorInfo));
+#if defined (TQ_OS_IRIX)
+ max_pressure = a[WAC_PRESSURE_I].max_value;
+#else
+ max_pressure = a[2].max_value;
+#endif
+ // got the max pressure no need to go further...
+ break;
+ }
+ any = (XAnyClassPtr) ((char *) any + any->length);
+ }
+ } else {
+ qt_curr_events_eraser = curr_event_count;
+ }
+ // at this point we are assuming there is only one
+ // wacom tqdevice...
+#if defined (TQ_OS_IRIX)
+ if ( devStylus != NULL ) {
+#else
+ if ( devStylus != NULL && devEraser != NULL ) {
+#endif
+ break;
+ }
+ }
+ } // end for loop
+ XFreeDeviceList( tqdevices );
+#endif // TQT_TABLET_SUPPORT
+
+ } else {
+ // read some non-GUI settings when not using the X server...
+
+ if ( TQApplication::desktopSettingsAware() ) {
+ TQSettings settings;
+
+ // read library (ie. plugin) path list
+ TQString libpathkey = TQString("/qt/%1.%2/libraryPath")
+ .arg( TQT_VERSION >> 16 )
+ .arg( (TQT_VERSION & 0xff00 ) >> 8 );
+ TQStringList pathlist =
+ settings.readListEntry(libpathkey, ':');
+ if (! pathlist.isEmpty()) {
+ TQStringList::ConstIterator it = pathlist.begin();
+ while (it != pathlist.end())
+ TQApplication::addLibraryPath(*it++);
+ }
+
+ TQString defaultcodec = settings.readEntry("/qt/defaultCodec", "none");
+ if (defaultcodec != "none") {
+ TQTextCodec *codec = TQTextCodec::codecForName(defaultcodec);
+ if (codec)
+ tqApp->setDefaultCodec(codec);
+ }
+
+ qt_resolve_symlinks =
+ settings.readBoolEntry("/qt/resolveSymlinks", TRUE);
+ }
+ }
+ }
+
+
+#ifndef TQT_NO_STYLE
+ // run-time search for default style
+void TQApplication::x11_initialize_style()
+{
+ Atom type;
+ int format;
+ unsigned long length, after;
+ uchar *data;
+ if ( !app_style &&
+ XGetWindowProperty( appDpy, TQPaintDevice::x11AppRootWindow(), qt_kwin_running,
+ 0, 1, False, AnyPropertyType, &type, &format, &length,
+ &after, &data ) == Success && length ) {
+ if ( data ) XFree( (char *)data );
+ // kwin is there. check if KDE's styles are available,
+ // otherwise use windows style
+ if ( (app_style = TQStyleFactory::create("highcolor") ) == 0 )
+ app_style = TQStyleFactory::create("windows");
+ }
+ if ( !app_style &&
+ XGetWindowProperty( appDpy, TQPaintDevice::x11AppRootWindow(), qt_kwm_running,
+ 0, 1, False, AnyPropertyType, &type, &format, &length,
+ &after, &data ) == Success && length ) {
+ if ( data ) XFree( (char *)data );
+ app_style = TQStyleFactory::create("windows");
+ }
+ if ( !app_style &&
+ XGetWindowProperty( appDpy, TQPaintDevice::x11AppRootWindow(), qt_cde_running,
+ 0, 1, False, AnyPropertyType, &type, &format, &length,
+ &after, &data ) == Success && length ) {
+ // DTWM is running, meaning most likely CDE is running...
+ if ( data ) XFree( (char *) data );
+ app_style = TQStyleFactory::create( "cde" );
+ }
+ // maybe another desktop?
+ if ( !app_style &&
+ XGetWindowProperty( appDpy, TQPaintDevice::x11AppRootWindow(),
+ qt_gbackground_properties, 0, 1, False, AnyPropertyType,
+ &type, &format, &length, &after, &data ) == Success &&
+ length ) {
+ if ( data ) XFree( (char *)data );
+ // default to MotifPlus with hovering
+ app_style = TQStyleFactory::create("motifplus" );
+ }
+}
+#endif
+
+void qt_init( int *argcptr, char **argv, TQApplication::Type )
+{
+ qt_init_internal( argcptr, argv, 0, 0, 0 );
+}
+
+void qt_init( Display *display, TQt::HANDLE visual, TQt::HANDLE colormap )
+{
+ qt_init_internal( 0, 0, display, visual, colormap );
+}
+
+
+/*****************************************************************************
+ qt_cleanup() - cleans up when the application is finished
+ *****************************************************************************/
+
+void qt_cleanup()
+{
+ appliedstamp = 0;
+
+ if ( app_save_rootinfo ) // root window must keep state
+ qt_save_rootinfo();
+
+ if ( qt_is_gui_used ) {
+ TQPixmapCache::clear();
+ TQPainter::cleanup();
+ TQCursor::cleanup();
+ TQFont::cleanup();
+ TQColor::cleanup();
+ TQSharedDoubleBuffer::cleanup();
+ }
+#if defined(TQT_THREAD_SUPPORT)
+ TQThread::cleanup();
+#endif
+
+#if defined (TQT_TABLET_SUPPORT)
+ if ( devStylus != NULL )
+ XCloseDevice( appDpy, devStylus );
+ if ( devEraser != NULL )
+ XCloseDevice( appDpy, devEraser );
+#endif
+
+#if !defined(TQT_NO_XIM)
+ if ( qt_xim )
+ TQApplication::close_xim();
+#endif
+
+ if ( qt_is_gui_used ) {
+ int screen;
+ for ( screen = 0; screen < appScreenCount; screen++ ) {
+ if ( ! TQPaintDevice::x11AppDefaultColormap( screen ) )
+ XFreeColormap( TQPaintDevice::x11AppDisplay(),
+ TQPaintDevice::x11AppColormap( screen ) );
+ }
+ }
+
+#define TQT_CLEANUP_GC(g) if (g) { for (int i=0;i<appScreenCount;i++){if(g[i])XFreeGC(appDpy,g[i]);} delete [] g; g = 0; }
+ TQT_CLEANUP_GC(app_gc_ro);
+ TQT_CLEANUP_GC(app_gc_ro_m);
+ TQT_CLEANUP_GC(app_gc_tmp);
+ TQT_CLEANUP_GC(app_gc_tmp_m);
+#undef TQT_CLEANUP_GC
+
+ delete sip_list;
+ sip_list = 0;
+
+ // Reset the error handlers
+ XSetErrorHandler( original_x_errhandler );
+ XSetIOErrorHandler( original_xio_errhandler );
+
+ if ( qt_is_gui_used && !appForeignDpy )
+ XCloseDisplay( appDpy ); // close X display
+ appDpy = 0;
+
+ qt_x11_wm_client_leader = 0;
+
+ if ( TQPaintDevice::x_appdepth_arr )
+ delete [] TQPaintDevice::x_appdepth_arr;
+ if ( TQPaintDevice::x_appcells_arr )
+ delete [] TQPaintDevice::x_appcells_arr;
+ if ( TQPaintDevice::x_appcolormap_arr )
+ delete []TQPaintDevice::x_appcolormap_arr;
+ if ( TQPaintDevice::x_appdefcolormap_arr )
+ delete [] TQPaintDevice::x_appdefcolormap_arr;
+ if ( TQPaintDevice::x_appvisual_arr )
+ delete [] TQPaintDevice::x_appvisual_arr;
+ if ( TQPaintDevice::x_appdefvisual_arr )
+ delete [] TQPaintDevice::x_appdefvisual_arr;
+
+ if ( appForeignDpy ) {
+ delete [] (char *)appName;
+ appName = 0;
+ delete [] (char *)appClass;
+ appClass = 0;
+ }
+
+ if (qt_net_supported_list)
+ delete [] qt_net_supported_list;
+ qt_net_supported_list = 0;
+
+ if (qt_net_virtual_root_list)
+ delete [] qt_net_virtual_root_list;
+ qt_net_virtual_root_list = 0;
+}
+
+
+/*****************************************************************************
+ Platform specific global and internal functions
+ *****************************************************************************/
+
+void qt_save_rootinfo() // save new root info
+{
+ Atom type;
+ int format;
+ unsigned long length, after;
+ uchar *data;
+
+ if ( qt_xsetroot_id ) { // kill old pixmap
+ if ( XGetWindowProperty( appDpy, TQPaintDevice::x11AppRootWindow(),
+ qt_xsetroot_id, 0, 1,
+ True, AnyPropertyType, &type, &format,
+ &length, &after, &data ) == Success ) {
+ if ( type == XA_PIXMAP && format == 32 && length == 1 &&
+ after == 0 && data ) {
+ XKillClient( appDpy, *((Pixmap*)data) );
+ }
+ Pixmap dummy = XCreatePixmap( appDpy, TQPaintDevice::x11AppRootWindow(),
+ 1, 1, 1 );
+ XChangeProperty( appDpy, TQPaintDevice::x11AppRootWindow(),
+ qt_xsetroot_id, XA_PIXMAP, 32,
+ PropModeReplace, (uchar *)&dummy, 1 );
+ XSetCloseDownMode( appDpy, RetainPermanent );
+ }
+ }
+ if ( data )
+ XFree( (char *)data );
+}
+
+void qt_updated_rootinfo()
+{
+ app_save_rootinfo = TRUE;
+}
+
+bool qt_wstate_iconified( WId winid )
+{
+ Atom type;
+ int format;
+ unsigned long length, after;
+ uchar *data;
+ int r = XGetWindowProperty( appDpy, winid, qt_wm_state, 0, 2,
+ False, AnyPropertyType, &type, &format,
+ &length, &after, &data );
+ bool iconic = FALSE;
+ if ( r == Success && data && format == 32 ) {
+ // TQ_UINT32 *wstate = (TQ_UINT32*)data;
+ unsigned long *wstate = (unsigned long *) data;
+ iconic = (*wstate == IconicState );
+ XFree( (char *)data );
+ }
+ return iconic;
+}
+
+const char *tqAppName() // get application name
+{
+ return appName;
+}
+
+const char *tqAppClass() // get application class
+{
+ return appClass;
+}
+
+Display *qt_xdisplay() // get current X display
+{
+ return appDpy;
+}
+
+int qt_xscreen() // get current X screen
+{
+ return appScreen;
+}
+
+// ### REMOVE 4.0
+WId qt_xrootwin() // get X root window
+{
+ return TQPaintDevice::x11AppRootWindow();
+}
+
+WId qt_xrootwin( int scrn ) // get X root window for screen
+{
+ return TQPaintDevice::x11AppRootWindow( scrn );
+}
+
+bool qt_nograb() // application no-grab option
+{
+#if defined(TQT_DEBUG)
+ return appNoGrab;
+#else
+ return FALSE;
+#endif
+}
+
+static GC create_gc( int scrn, bool monochrome )
+{
+ GC gc;
+ if ( monochrome ) {
+ Pixmap pm = XCreatePixmap( appDpy, RootWindow( appDpy, scrn ), 8, 8, 1 );
+ gc = XCreateGC( appDpy, pm, 0, 0 );
+ XFreePixmap( appDpy, pm );
+ } else {
+ if ( TQPaintDevice::x11AppDefaultVisual( scrn ) ) {
+ gc = XCreateGC( appDpy, RootWindow( appDpy, scrn ), 0, 0 );
+ } else {
+ Window w;
+ XSetWindowAttributes a;
+ a.background_pixel = TQt::black.pixel( scrn );
+ a.border_pixel = TQt::black.pixel( scrn );
+ a.colormap = TQPaintDevice::x11AppColormap( scrn );
+ w = XCreateWindow( appDpy, RootWindow( appDpy, scrn ), 0, 0, 100, 100,
+ 0, TQPaintDevice::x11AppDepth( scrn ), InputOutput,
+ (Visual*)TQPaintDevice::x11AppVisual( scrn ),
+ CWBackPixel|CWBorderPixel|CWColormap, &a );
+ gc = XCreateGC( appDpy, w, 0, 0 );
+ XDestroyWindow( appDpy, w );
+ }
+ }
+ XSetGraphicsExposures( appDpy, gc, False );
+ return gc;
+}
+
+GC qt_xget_readonly_gc( int scrn, bool monochrome ) // get read-only GC
+{
+ if ( scrn < 0 || scrn >= appScreenCount ) {
+ qDebug("invalid screen %d %d", scrn, appScreenCount );
+ TQWidget* bla = 0;
+ bla->setName("hello");
+ }
+ GC gc;
+ if ( monochrome ) {
+ if ( !app_gc_ro_m ) // create GC for bitmap
+ memset( (app_gc_ro_m = new GC[appScreenCount]), 0, appScreenCount * sizeof( GC ) );
+ if ( !app_gc_ro_m[scrn] )
+ app_gc_ro_m[scrn] = create_gc( scrn, TRUE );
+ gc = app_gc_ro_m[scrn];
+ } else { // create standard GC
+ if ( !app_gc_ro )
+ memset( (app_gc_ro = new GC[appScreenCount]), 0, appScreenCount * sizeof( GC ) );
+ if ( !app_gc_ro[scrn] )
+ app_gc_ro[scrn] = create_gc( scrn, FALSE );
+ gc = app_gc_ro[scrn];
+ }
+ return gc;
+}
+
+GC qt_xget_temp_gc( int scrn, bool monochrome ) // get temporary GC
+{
+ if ( scrn < 0 || scrn >= appScreenCount ) {
+ qDebug("invalid screen (tmp) %d %d", scrn, appScreenCount );
+ TQWidget* bla = 0;
+ bla->setName("hello");
+ }
+ GC gc;
+ if ( monochrome ) {
+ if ( !app_gc_tmp_m ) // create GC for bitmap
+ memset( (app_gc_tmp_m = new GC[appScreenCount]), 0, appScreenCount * sizeof( GC ) );
+ if ( !app_gc_tmp_m[scrn] )
+ app_gc_tmp_m[scrn] = create_gc( scrn, TRUE );
+ gc = app_gc_tmp_m[scrn];
+ } else { // create standard GC
+ if ( !app_gc_tmp )
+ memset( (app_gc_tmp = new GC[appScreenCount]), 0, appScreenCount * sizeof( GC ) );
+ if ( !app_gc_tmp[scrn] )
+ app_gc_tmp[scrn] = create_gc( scrn, FALSE );
+ gc = app_gc_tmp[scrn];
+ }
+ return gc;
+}
+
+
+/*****************************************************************************
+ Platform specific TQApplication members
+ *****************************************************************************/
+
+/*!
+ \fn TQWidget *TQApplication::mainWidget() const
+
+ Returns the main application widget, or 0 if there is no main
+ widget.
+
+ \sa setMainWidget()
+*/
+
+/*!
+ Sets the application's main widget to \a mainWidget.
+
+ In most respects the main widget is like any other widget, except
+ that if it is closed, the application exits. Note that
+ TQApplication does \e not take ownership of the \a mainWidget, so
+ if you create your main widget on the heap you must delete it
+ yourself.
+
+ You need not have a main widget; connecting lastWindowClosed() to
+ quit() is an alternative.
+
+ For X11, this function also resizes and moves the main widget
+ according to the \e -tqgeometry command-line option, so you should
+ set the default tqgeometry (using \l TQWidget::setGeometry()) before
+ calling setMainWidget().
+
+ \sa mainWidget(), exec(), quit()
+*/
+
+void TQApplication::setMainWidget( TQWidget *mainWidget )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( mainWidget && mainWidget->parentWidget() &&
+ ! mainWidget->parentWidget()->isDesktop() )
+ qWarning( "TQApplication::setMainWidget(): New main widget (%s/%s) "
+ "has a tqparent!",
+ mainWidget->className(), mainWidget->name() );
+#endif
+ main_widget = mainWidget;
+ if ( main_widget ) { // give WM command line
+ XSetWMProperties( main_widget->x11Display(), main_widget->winId(),
+ 0, 0, app_argv, app_argc, 0, 0, 0 );
+ if ( mwTitle )
+ XStoreName( main_widget->x11Display(), main_widget->winId(), (char*)mwTitle );
+ if ( mwGeometry ) { // parse tqgeometry
+ int x, y;
+ int w, h;
+ int m = XParseGeometry( (char*)mwGeometry, &x, &y, (uint*)&w, (uint*)&h );
+ TQSize minSize = main_widget->tqminimumSize();
+ TQSize maxSize = main_widget->tqmaximumSize();
+ if ( (m & XValue) == 0 )
+ x = main_widget->tqgeometry().x();
+ if ( (m & YValue) == 0 )
+ y = main_widget->tqgeometry().y();
+ if ( (m & WidthValue) == 0 )
+ w = main_widget->width();
+ if ( (m & HeightValue) == 0 )
+ h = main_widget->height();
+ w = TQMIN(w,maxSize.width());
+ h = TQMIN(h,maxSize.height());
+ w = TQMAX(w,minSize.width());
+ h = TQMAX(h,minSize.height());
+ if ( (m & XNegative) ) {
+ x = desktop()->width() + x - w;
+ qt_widget_tlw_gravity = NorthEastGravity;
+ }
+ if ( (m & YNegative) ) {
+ y = desktop()->height() + y - h;
+ qt_widget_tlw_gravity = (m & XNegative) ? SouthEastGravity : SouthWestGravity;
+ }
+ main_widget->setGeometry( x, y, w, h );
+ }
+ }
+}
+
+#ifndef TQT_NO_CURSOR
+
+/*****************************************************************************
+ TQApplication cursor stack
+ *****************************************************************************/
+
+extern void qt_x11_enforce_cursor( TQWidget * w );
+
+typedef TQPtrList<TQCursor> TQCursorList;
+
+static TQCursorList *cursorStack = 0;
+
+/*!
+ \fn TQCursor *TQApplication::overrideCursor()
+
+ Returns the active application override cursor.
+
+ This function returns 0 if no application cursor has been defined
+ (i.e. the internal cursor stack is empty).
+
+ \sa setOverrideCursor(), restoreOverrideCursor()
+*/
+
+/*!
+ Sets the application override cursor to \a cursor.
+
+ Application override cursors are intended for showing the user
+ that the application is in a special state, for example during an
+ operation that might take some time.
+
+ This cursor will be displayed in all the application's widgets
+ until restoreOverrideCursor() or another setOverrideCursor() is
+ called.
+
+ Application cursors are stored on an internal stack.
+ setOverrideCursor() pushes the cursor onto the stack, and
+ restoreOverrideCursor() pops the active cursor off the stack.
+ Every setOverrideCursor() must eventually be followed by a
+ corresponding restoreOverrideCursor(), otherwise the stack will
+ never be emptied.
+
+ If \a tqreplace is TRUE, the new cursor will tqreplace the last
+ override cursor (the stack keeps its depth). If \a tqreplace is
+ FALSE, the new stack is pushed onto the top of the stack.
+
+ Example:
+ \code
+ TQApplication::setOverrideCursor( TQCursor(TQt::WaitCursor) );
+ calculateHugeMandelbrot(); // lunch time...
+ TQApplication::restoreOverrideCursor();
+ \endcode
+
+ \sa overrideCursor(), restoreOverrideCursor(), TQWidget::setCursor()
+*/
+
+void TQApplication::setOverrideCursor( const TQCursor &cursor, bool tqreplace )
+{
+ if ( !cursorStack ) {
+ cursorStack = new TQCursorList;
+ TQ_CHECK_PTR( cursorStack );
+ cursorStack->setAutoDelete( TRUE );
+ }
+ app_cursor = new TQCursor( cursor );
+ TQ_CHECK_PTR( app_cursor );
+ if ( tqreplace )
+ cursorStack->removeLast();
+ cursorStack->append( app_cursor );
+
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // for all widgets that have
+ if ( w->testWState( WState_OwnCursor ) )
+ qt_x11_enforce_cursor( w );
+ ++it;
+ }
+ XFlush( appDpy ); // make X execute it NOW
+}
+
+/*!
+ Undoes the last setOverrideCursor().
+
+ If setOverrideCursor() has been called twice, calling
+ restoreOverrideCursor() will activate the first cursor set.
+ Calling this function a second time restores the original widgets'
+ cursors.
+
+ \sa setOverrideCursor(), overrideCursor().
+*/
+
+void TQApplication::restoreOverrideCursor()
+{
+ if ( !cursorStack ) // no cursor stack
+ return;
+ cursorStack->removeLast();
+ app_cursor = cursorStack->last();
+ if ( TQWidget::wmapper() != 0 && !closingDown() ) {
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // set back to original cursors
+ if ( w->testWState( WState_OwnCursor ) )
+ qt_x11_enforce_cursor( w );
+ ++it;
+ }
+ XFlush( appDpy );
+ }
+ if ( !app_cursor ) {
+ delete cursorStack;
+ cursorStack = 0;
+ }
+}
+
+#endif
+
+/*!
+ \fn bool TQApplication::hasGlobalMouseTracking()
+
+ Returns TRUE if global mouse tracking is enabled; otherwise
+ returns FALSE.
+
+ \sa setGlobalMouseTracking()
+*/
+
+/*!
+ Enables global mouse tracking if \a enable is TRUE, or disables it
+ if \a enable is FALSE.
+
+ Enabling global mouse tracking makes it possible for widget event
+ filters or application event filters to get all mouse move events,
+ even when no button is depressed. This is useful for special GUI
+ elements, e.g. tooltips.
+
+ Global mouse tracking does not affect widgets and their
+ mouseMoveEvent(). For a widget to get mouse move events when no
+ button is depressed, it must do TQWidget::setMouseTracking(TRUE).
+
+ This function uses an internal counter. Each
+ setGlobalMouseTracking(TRUE) must have a corresponding
+ setGlobalMouseTracking(FALSE):
+ \code
+ // at this point global mouse tracking is off
+ TQApplication::setGlobalMouseTracking( TRUE );
+ TQApplication::setGlobalMouseTracking( TRUE );
+ TQApplication::setGlobalMouseTracking( FALSE );
+ // at this point it's still on
+ TQApplication::setGlobalMouseTracking( FALSE );
+ // but now it's off
+ \endcode
+
+ \sa hasGlobalMouseTracking(), TQWidget::hasMouseTracking()
+*/
+
+void TQApplication::setGlobalMouseTracking( bool enable )
+{
+ bool tellAllWidgets;
+ if ( enable ) {
+ tellAllWidgets = (++app_tracking == 1);
+ } else {
+ tellAllWidgets = (--app_tracking == 0);
+ }
+ if ( tellAllWidgets ) {
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)TQWidget::wmapper()) );
+ register TQWidget *w;
+ while ( (w=it.current()) ) {
+ if ( app_tracking > 0 ) { // switch on
+ if ( !w->testWState(WState_MouseTracking) ) {
+ w->setMouseTracking( TRUE );
+ w->clearWState( WState_MouseTracking );
+ }
+ } else { // switch off
+ if ( !w->testWState(WState_MouseTracking) ) {
+ w->setWState( WState_MouseTracking );
+ w->setMouseTracking( FALSE );
+ }
+ }
+ ++it;
+ }
+ }
+}
+
+
+/*****************************************************************************
+ Routines to tqfind a TQt widget from a screen position
+ *****************************************************************************/
+
+Window qt_x11_tqfindClientWindow( Window win, Atom property, bool leaf )
+{
+ Atom type = None;
+ int format, i;
+ ulong nitems, after;
+ uchar *data;
+ Window root, tqparent, target=0, *tqchildren=0;
+ uint ntqchildren;
+ if ( XGetWindowProperty( appDpy, win, property, 0, 0, FALSE, AnyPropertyType,
+ &type, &format, &nitems, &after, &data ) == Success ) {
+ if ( data )
+ XFree( (char *)data );
+ if ( type )
+ return win;
+ }
+ if ( !XQueryTree(appDpy,win,&root,&tqparent,&tqchildren,&ntqchildren) ) {
+ if ( tqchildren )
+ XFree( (char *)tqchildren );
+ return 0;
+ }
+ for ( i=ntqchildren-1; !target && i >= 0; i-- )
+ target = qt_x11_tqfindClientWindow( tqchildren[i], property, leaf );
+ if ( tqchildren )
+ XFree( (char *)tqchildren );
+ return target;
+}
+
+
+/*!
+ Returns a pointer to the widget at global screen position \a
+ (x, y), or 0 if there is no TQt widget there.
+
+ If \a child is FALSE and there is a child widget at position \a
+ (x, y), the top-level widget containing it is returned. If \a child
+ is TRUE the child widget at position \a (x, y) is returned.
+
+ This function is normally rather slow.
+
+ \sa TQCursor::pos(), TQWidget::grabMouse(), TQWidget::grabKeyboard()
+*/
+
+TQWidget *TQApplication::widgetAt( int x, int y, bool child )
+{
+ int screen = TQCursor::x11Screen();
+ int lx, ly;
+
+ Window target;
+ if ( !XTranslateCoordinates(appDpy,
+ TQPaintDevice::x11AppRootWindow(screen),
+ TQPaintDevice::x11AppRootWindow(screen),
+ x, y, &lx, &ly, &target) ) {
+ return 0;
+ }
+ if ( !target || target == TQPaintDevice::x11AppRootWindow(screen) )
+ return 0;
+ TQWidget *w, *c;
+ w = TQWidget::tqfind( (WId)target );
+
+ if ( !w ) {
+ qt_ignore_badwindow();
+ target = qt_x11_tqfindClientWindow( target, qt_wm_state, TRUE );
+ if (qt_badwindow() )
+ return 0;
+ w = TQWidget::tqfind( (WId)target );
+#if 0
+ if ( !w ) {
+ // Perhaps the widgets at (x,y) is inside a foreign application?
+ // Search all toplevel widgets to see if one is within target
+ TQWidgetList *list = tqtopLevelWidgets();
+ TQWidget *widget = list->first();
+ while ( widget && !w ) {
+ Window ctarget = target;
+ if ( widget->isVisible() && !widget->isDesktop() ) {
+ Window wid = widget->winId();
+ while ( ctarget && !w ) {
+ XTranslateCoordinates(appDpy,
+ TQPaintDevice::x11AppRootWindow(screen),
+ ctarget, x, y, &lx, &ly, &ctarget);
+ if ( ctarget == wid ) {
+ // Found
+ w = widget;
+ XTranslateCoordinates(appDpy,
+ TQPaintDevice::x11AppRootWindow(screen),
+ ctarget, x, y, &lx, &ly, &ctarget);
+ }
+ }
+ }
+ widget = list->next();
+ }
+ delete list;
+ }
+#endif
+ }
+ if ( child && w ) {
+ if ( (c = w->tqchildAt( w->mapFromGlobal(TQPoint(x, y ) ) ) ) )
+ return c;
+ }
+ return w;
+}
+
+/*!
+ \overload TQWidget *TQApplication::widgetAt( const TQPoint &pos, bool child )
+
+ Returns a pointer to the widget at global screen position \a pos,
+ or 0 if there is no TQt widget there.
+
+ If \a child is FALSE and there is a child widget at position \a
+ pos, the top-level widget containing it is returned. If \a child
+ is TRUE the child widget at position \a pos is returned.
+*/
+
+
+/*!
+ Flushes the X event queue in the X11 implementation. This normally
+ returns almost immediately. Does nothing on other platforms.
+
+ \sa syncX()
+*/
+
+void TQApplication::flushX()
+{
+ if ( appDpy )
+ XFlush( appDpy );
+}
+
+/*!
+ Flushes the window system specific event queues.
+
+ If you are doing graphical changes inside a loop that does not
+ return to the event loop on asynchronous window systems like X11
+ or double buffered window systems like MacOS X, and you want to
+ visualize these changes immediately (e.g. Splash Screens), call
+ this function.
+
+ \sa flushX() sendPostedEvents() TQPainter::flush()
+*/
+
+void TQApplication::flush()
+{
+ flushX();
+}
+
+/*!
+ Synchronizes with the X server in the X11 implementation. This
+ normally takes some time. Does nothing on other platforms.
+
+ \sa flushX()
+*/
+
+void TQApplication::syncX()
+{
+ if ( appDpy )
+ XSync( appDpy, False ); // don't discard events
+}
+
+
+/*!
+ Sounds the bell, using the default volume and sound.
+*/
+
+void TQApplication::beep()
+{
+ if ( appDpy )
+ XBell( appDpy, 0 );
+}
+
+
+
+/*****************************************************************************
+ Special lookup functions for windows that have been reparented recently
+ *****************************************************************************/
+
+static TQWidgetIntDict *wPRmapper = 0; // alternative widget mapper
+
+void qPRCreate( const TQWidget *widget, Window oldwin )
+{ // TQWidget::reparent mechanism
+ if ( !wPRmapper ) {
+ wPRmapper = new TQWidgetIntDict;
+ TQ_CHECK_PTR( wPRmapper );
+ }
+ wPRmapper->insert( (long)oldwin, widget ); // add old window to mapper
+ TQETWidget *w = (TQETWidget *)widget;
+ w->setWState( TQt::WState_Reparented ); // set reparented flag
+}
+
+void qPRCleanup( TQWidget *widget )
+{
+ TQETWidget *etw = (TQETWidget *)widget;
+ if ( !(wPRmapper && etw->testWState(TQt::WState_Reparented)) )
+ return; // not a reparented widget
+ TQWidgetIntDictIt it(*wPRmapper);
+ TQWidget *w;
+ while ( (w=it.current()) ) {
+ int key = it.currentKey();
+ ++it;
+ if ( w == etw ) { // found widget
+ etw->clearWState( TQt::WState_Reparented ); // clear flag
+ wPRmapper->remove( key );// old window no longer needed
+ if ( wPRmapper->count() == 0 ) { // became empty
+ delete wPRmapper; // then reset alt mapper
+ wPRmapper = 0;
+ return;
+ }
+ }
+ }
+}
+
+static TQETWidget *qPRFindWidget( Window oldwin )
+{
+ return wPRmapper ? (TQETWidget*)wPRmapper->tqfind((long)oldwin) : 0;
+}
+
+/*!
+ \internal
+*/
+int TQApplication::x11ClientMessage(TQWidget* w, XEvent* event, bool passive_only)
+{
+ TQETWidget *widget = (TQETWidget*)w;
+ if ( event->xclient.format == 32 && event->xclient.message_type ) {
+ if ( event->xclient.message_type == qt_wm_protocols ) {
+ Atom a = event->xclient.data.l[0];
+ if ( a == qt_wm_delete_window ) {
+ if ( passive_only ) return 0;
+ widget->translateCloseEvent(event);
+ }
+ else if ( a == qt_wm_take_focus ) {
+ TQWidget * amw = activeModalWidget();
+ if ( (ulong) event->xclient.data.l[1] > GET_QT_X_TIME() )
+ GET_QT_X_TIME() = event->xclient.data.l[1];
+ if ( amw && amw != widget ) {
+ TQWidget* groupLeader = widget;
+ while ( groupLeader && !groupLeader->testWFlags( TQt::WGroupLeader )
+ && groupLeader != amw )
+ groupLeader = groupLeader->parentWidget();
+ if ( !groupLeader ) {
+ TQWidget *p = amw->parentWidget();
+ while (p && p != widget)
+ p = p->parentWidget();
+ if (!p || !qt_net_supported_list)
+ amw->raise(); // help broken window managers
+ amw->setActiveWindow();
+ }
+ }
+#ifndef TQT_NO_WHATSTHIS
+ } else if ( a == qt_net_wm_context_help ) {
+ TQWhatsThis::enterWhatsThisMode();
+#endif // TQT_NO_WHATSTHIS
+ } else if ( a == qt_net_wm_ping ) {
+ // avoid send/reply loops
+ Window root = TQPaintDevice::x11AppRootWindow( w->x11Screen() );
+ if (event->xclient.window != root) {
+ event->xclient.window = root;
+ XSendEvent( event->xclient.display, event->xclient.window,
+ False, SubstructureNotifyMask|SubstructureRedirectMask, event );
+ }
+ }
+ } else if ( event->xclient.message_type == qt_qt_scrolldone ) {
+ widget->translateScrollDoneEvent(event);
+ } else if ( event->xclient.message_type == qt_xdnd_position ) {
+ qt_handle_xdnd_position( widget, event, passive_only );
+ } else if ( event->xclient.message_type == qt_xdnd_enter ) {
+ qt_handle_xdnd_enter( widget, event, passive_only );
+ } else if ( event->xclient.message_type == qt_xdnd_status ) {
+ qt_handle_xdnd_status( widget, event, passive_only );
+ } else if ( event->xclient.message_type == qt_xdnd_leave ) {
+ qt_handle_xdnd_leave( widget, event, passive_only );
+ } else if ( event->xclient.message_type == qt_xdnd_drop ) {
+ qt_handle_xdnd_drop( widget, event, passive_only );
+ } else if ( event->xclient.message_type == qt_xdnd_finished ) {
+ qt_handle_xdnd_finished( widget, event, passive_only );
+ } else {
+ if ( passive_only ) return 0;
+ // All other are interactions
+ }
+ } else {
+ qt_motifdnd_handle_msg( widget, event, passive_only );
+ }
+
+ return 0;
+}
+
+/*!
+ This function does the core processing of individual X
+ \a{event}s, normally by dispatching TQt events to the right
+ destination.
+
+ It returns 1 if the event was consumed by special handling, 0 if
+ the \a event was consumed by normal handling, and -1 if the \a
+ event was for an unrecognized widget.
+
+ \sa x11EventFilter()
+*/
+int TQApplication::x11ProcessEvent( XEvent* event )
+{
+ switch ( event->type ) {
+ case ButtonPress:
+ ignoreNextMouseReleaseEvent = FALSE;
+ SET_QT_X_USER_TIME(event->xbutton.time);
+ // fallthrough intended
+ case ButtonRelease:
+ SET_QT_X_TIME(event->xbutton.time);
+ break;
+ case MotionNotify:
+ SET_QT_X_TIME(event->xmotion.time);
+ break;
+ case XKeyPress:
+ SET_QT_X_USER_TIME(event->xkey.time);
+ // fallthrough intended
+ case XKeyRelease:
+ SET_QT_X_TIME(event->xkey.time);
+ break;
+ case PropertyNotify:
+ SET_QT_X_TIME(event->xproperty.time);
+ break;
+ case EnterNotify:
+ case LeaveNotify:
+ SET_QT_X_TIME(event->xcrossing.time);
+ break;
+ case SelectionClear:
+ SET_QT_X_TIME(event->xselectionclear.time);
+ break;
+ default:
+ break;
+ }
+
+ TQETWidget *widget = (TQETWidget*)TQWidget::tqfind( (WId)event->xany.window );
+
+ if ( wPRmapper ) { // just did a widget reparent?
+ if ( widget == 0 ) { // not in std widget mapper
+ switch ( event->type ) { // only for mouse/key events
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ case XKeyPress:
+ case XKeyRelease:
+ widget = qPRFindWidget( event->xany.window );
+ break;
+ }
+ }
+ else if ( widget->testWState(WState_Reparented) )
+ qPRCleanup( widget ); // remove from alt mapper
+ }
+
+ TQETWidget *keywidget=0;
+ bool grabbed=FALSE;
+ if ( event->type==XKeyPress || event->type==XKeyRelease ) {
+ keywidget = (TQETWidget*)TQWidget::keyboardGrabber();
+ if ( keywidget ) {
+ grabbed = TRUE;
+ } else {
+ if ( focus_widget )
+ keywidget = (TQETWidget*)focus_widget;
+ if ( !keywidget ) {
+ if ( inPopupMode() ) // no focus widget, see if we have a popup
+ keywidget = (TQETWidget*) activePopupWidget();
+ else if ( widget )
+ keywidget = (TQETWidget*)widget->tqtopLevelWidget();
+ }
+ }
+ }
+
+ int xkey_keycode = event->xkey.keycode;
+ if ( XFilterEvent( event,
+ keywidget ? keywidget->tqtopLevelWidget()->winId() : None ) ) {
+ if ( keywidget )
+ composingKeycode = xkey_keycode; // ### not documented in xlib
+
+#ifndef TQT_NO_XIM
+ if ( event->type != XKeyPress || ! (qt_xim_style & XIMPreeditCallbacks) )
+ return 1;
+
+ /*
+ * The Solaris htt input method will transform a ClientMessage
+ * event into a filtered KeyPress event, in which case our
+ * keywidget is still zero.
+ */
+ if ( ! keywidget ) {
+ keywidget = (TQETWidget*)TQWidget::keyboardGrabber();
+ if ( keywidget ) {
+ grabbed = TRUE;
+ } else {
+ if ( focus_widget )
+ keywidget = (TQETWidget*)focus_widget;
+ if ( !keywidget ) {
+ if ( inPopupMode() ) // no focus widget, see if we have a popup
+ keywidget = (TQETWidget*) activePopupWidget();
+ else if ( widget )
+ keywidget = (TQETWidget*)widget->tqtopLevelWidget();
+ }
+ }
+ }
+
+ /*
+ if the composition string has been emptied, we need to send
+ an IMEnd event. however, we have no way to tell if the user
+ has cancelled input, or if the user has accepted the
+ composition.
+
+ so, we have to look for the next keypress and see if it is
+ the 'commit' key press (keycode == 0). if it is, we deliver
+ an IMEnd event with the final text, otherwise we deliver an
+ IMEnd with empty text (meaning the user has cancelled the
+ input).
+ */
+ TQInputContext *qic =
+ (TQInputContext *) keywidget->tqtopLevelWidget()->topData()->xic;
+ extern bool qt_compose_emptied; // qinputcontext_x11.cpp
+ if ( qic && qic->composing && qic->tqfocusWidget && qt_compose_emptied ) {
+ XEvent event2;
+ bool found = FALSE;
+ if ( XCheckTypedEvent( TQPaintDevice::x11AppDisplay(),
+ XKeyPress, &event2 ) ) {
+ if ( event2.xkey.keycode == 0 ) {
+ // found a key event with the 'commit' string
+ found = TRUE;
+ XPutBackEvent( TQPaintDevice::x11AppDisplay(), &event2 );
+ }
+ }
+
+ if ( !found ) {
+ // no key event, so the user must have cancelled the composition
+ TQIMEvent endevent( TQEvent::IMEnd, TQString::null, -1 );
+ TQApplication::sendEvent( qic->tqfocusWidget, &endevent );
+
+ qic->tqfocusWidget = 0;
+ }
+
+ qt_compose_emptied = FALSE;
+ }
+#endif // TQT_NO_XIM
+
+ return 1;
+ }
+
+ if ( qt_x11EventFilter(event) ) // send through app filter
+ return 1;
+
+ if ( event->type == MappingNotify ) { // keyboard mapping changed
+ XRefreshKeyboardMapping( &event->xmapping );
+ return 0;
+ }
+
+ if ( event->type == PropertyNotify ) { // some properties changed
+ if ( event->xproperty.window == TQPaintDevice::x11AppRootWindow( 0 ) ) {
+ // root properties for the first screen
+ if ( event->xproperty.atom == qt_clipboard_sentinel ) {
+ if (qt_check_clipboard_sentinel() )
+ emit clipboard()->dataChanged();
+ } else if ( event->xproperty.atom == qt_selection_sentinel ) {
+ if (qt_check_selection_sentinel() )
+ emit clipboard()->selectionChanged();
+ } else if ( obey_desktop_settings ) {
+ if ( event->xproperty.atom == qt_resource_manager )
+ qt_set_x11_resources();
+ else if ( event->xproperty.atom == qt_settings_timestamp )
+ TQApplication::x11_apply_settings();
+ }
+ }
+ if ( event->xproperty.window == TQPaintDevice::x11AppRootWindow() ) {
+ // root properties for the default screen
+ if ( event->xproperty.atom == qt_input_encoding ) {
+ qt_set_input_encoding();
+ } else if ( event->xproperty.atom == qt_net_supported ) {
+ qt_get_net_supported();
+ } else if ( event->xproperty.atom == qt_net_virtual_roots ) {
+ qt_get_net_virtual_roots();
+ } else if ( event->xproperty.atom == qt_net_workarea ) {
+ qt_desktopwidget_update_workarea();
+ }
+ } else if ( widget ) {
+ widget->translatePropertyEvent(event);
+ } else {
+ return -1; // don't know this window
+ }
+ return 0;
+ }
+
+ if ( !widget ) { // don't know this windows
+ TQWidget* popup = TQApplication::activePopupWidget();
+ if ( popup ) {
+
+ /*
+ That is more than suboptimal. The real solution should
+ do some keyevent and buttonevent translation, so that
+ the popup still continues to work as the user expects.
+ Unfortunately this translation is currently only
+ possible with a known widget. I'll change that soon
+ (Matthias).
+ */
+
+ // Danger - make sure we don't lock the server
+ switch ( event->type ) {
+ case ButtonPress:
+ case ButtonRelease:
+ case XKeyPress:
+ case XKeyRelease:
+ do {
+ popup->close();
+ } while ( (popup = tqApp->activePopupWidget()) );
+ return 1;
+ }
+ }
+ return -1;
+ }
+
+ if ( event->type == XKeyPress || event->type == XKeyRelease )
+ widget = keywidget; // send XKeyEvents through keywidget->x11Event()
+
+ if ( app_do_modal ) // modal event handling
+ if ( !qt_try_modal(widget, event) ) {
+ if ( event->type == ClientMessage )
+ x11ClientMessage( widget, event, TRUE );
+ return 1;
+ }
+
+
+ if ( widget->x11Event(event) ) // send through widget filter
+ return 1;
+#if defined (TQT_TABLET_SUPPORT)
+ if ( event->type == xinput_motion ||
+ event->type == xinput_button_release ||
+ event->type == xinput_button_press ) {
+ widget->translateXinputEvent( event );
+ return 0;
+ }
+#endif
+
+#ifndef TQT_NO_XRANDR
+ if (event->type == xrandr_eventbase + RRScreenChangeNotify) {
+ // update Xlib internals with the latest screen configuration
+ XRRUpdateConfiguration(event);
+
+ // update the size for desktop widget
+ int scr = XRRRootToScreen( appDpy, event->xany.window );
+ TQWidget *w = desktop()->screen( scr );
+ TQSize oldSize( w->size() );
+ w->crect.setWidth( DisplayWidth( appDpy, scr ) );
+ w->crect.setHeight( DisplayHeight( appDpy, scr ) );
+ if ( w->size() != oldSize ) {
+ TQResizeEvent e( w->size(), oldSize );
+ TQApplication::sendEvent( w, &e );
+ emit desktop()->resized( scr );
+ }
+ }
+#endif // TQT_NO_XRANDR
+
+ switch ( event->type ) {
+
+ case ButtonRelease: // mouse event
+ if ( ignoreNextMouseReleaseEvent ) {
+ ignoreNextMouseReleaseEvent = FALSE;
+ break;
+ }
+ // fall through intended
+ case ButtonPress:
+ if (event->xbutton.root != RootWindow(widget->x11Display(), widget->x11Screen())
+ && ! qt_xdnd_dragging) {
+ while ( activePopupWidget() )
+ activePopupWidget()->close();
+ return 1;
+ }
+ if (event->type == ButtonPress)
+ qt_net_update_user_time(widget->tqtopLevelWidget());
+ // fall through intended
+ case MotionNotify:
+#if defined(TQT_TABLET_SUPPORT)
+ if ( !chokeMouse ) {
+#endif
+ widget->translateMouseEvent( event );
+#if defined(TQT_TABLET_SUPPORT)
+ } else {
+ chokeMouse = FALSE;
+ }
+#endif
+ break;
+
+ case XKeyPress: // keyboard event
+ qt_net_update_user_time(widget->tqtopLevelWidget());
+ // fallthrough intended
+ case XKeyRelease:
+ {
+ if ( keywidget && keywidget->isEnabled() ) { // should always exist
+#ifndef TQT_NO_XIM
+ TQInputContext *qic =
+ (TQInputContext *) keywidget->tqtopLevelWidget()->topData()->xic;
+
+ if ((qt_xim_style & XIMPreeditCallbacks) && event->xkey.keycode == 0 &&
+ qic && qic->composing && qic->tqfocusWidget) {
+ // input method has sent us a commit string
+ TQCString data(513);
+ KeySym sym; // unused
+ Status status; // unused
+ TQString text;
+ int count = qic->lookupString( &(event->xkey), data,
+ &sym, &status );
+ if ( count > 0 )
+ text = input_mapper->toUnicode( data, count );
+
+ // qDebug( "sending IMEnd with %d chars", text.length() );
+ TQIMEvent endevent( TQEvent::IMEnd, text, -1 );
+ TQApplication::sendEvent( qic->tqfocusWidget, &endevent );
+
+ qic->tqfocusWidget = 0;
+ qic->text = TQString::null;
+ } else
+#endif // !TQT_NO_XIM
+ {
+ // qDebug( "sending key event" );
+ keywidget->translateKeyEvent( event, grabbed );
+ }
+ }
+ break;
+ }
+
+ case GraphicsExpose:
+ case Expose: // paint event
+ widget->translatePaintEvent( event );
+ break;
+
+ case ConfigureNotify: // window move/resize event
+ if ( event->xconfigure.event == event->xconfigure.window )
+ widget->translateConfigEvent( event );
+ break;
+
+ case XFocusIn: { // got focus
+ if ( widget->isDesktop() )
+ break;
+ if ( inPopupMode() ) // some delayed focus event to ignore
+ break;
+ if ( !widget->isTopLevel() )
+ break;
+ if ( event->xfocus.detail != NotifyAncestor &&
+ event->xfocus.detail != NotifyInferior &&
+ event->xfocus.detail != NotifyNonlinear )
+ break;
+ widget->createInputContext();
+ setActiveWindow( widget );
+ if ( qt_focus_model == FocusModel_PointerRoot ) {
+ // We got real input focus from somewhere, but we were in PointerRoot
+ // mode, so we don't trust this event. Check the focus model to make
+ // sure we know what focus mode we are using...
+ qt_check_focus_model();
+ }
+ }
+ break;
+
+ case XFocusOut: // lost focus
+ if ( widget->isDesktop() )
+ break;
+ if ( !widget->isTopLevel() )
+ break;
+ if ( event->xfocus.mode == NotifyGrab )
+ qt_xfocusout_grab_counter++;
+ if ( event->xfocus.mode != NotifyNormal )
+ break;
+ if ( event->xfocus.detail != NotifyAncestor &&
+ event->xfocus.detail != NotifyNonlinearVirtual &&
+ event->xfocus.detail != NotifyNonlinear )
+ break;
+ if ( !inPopupMode() && widget == active_window )
+ setActiveWindow( 0 );
+ break;
+
+ case EnterNotify: { // enter window
+ if ( TQWidget::mouseGrabber() && widget != TQWidget::mouseGrabber() )
+ break;
+ if ( inPopupMode() && widget->tqtopLevelWidget() != activePopupWidget() )
+ break;
+ if ( event->xcrossing.mode != NotifyNormal ||
+ event->xcrossing.detail == NotifyVirtual ||
+ event->xcrossing.detail == NotifyNonlinearVirtual )
+ break;
+ if ( event->xcrossing.focus &&
+ !widget->isDesktop() && !widget->isActiveWindow() ) {
+ if ( qt_focus_model == FocusModel_Unknown ) // check focus model
+ qt_check_focus_model();
+ if ( qt_focus_model == FocusModel_PointerRoot ) // PointerRoot mode
+ setActiveWindow( widget );
+ }
+ qt_dispatchEnterLeave( widget, TQWidget::tqfind( curWin ) );
+ curWin = widget->winId();
+ widget->translateMouseEvent( event ); //we don't get MotionNotify, emulate it
+ }
+ break;
+
+ case LeaveNotify: { // leave window
+ if ( TQWidget::mouseGrabber() && widget != TQWidget::mouseGrabber() )
+ break;
+ if ( curWin && widget->winId() != curWin )
+ break;
+ if ( event->xcrossing.mode != NotifyNormal )
+ break;
+ if ( !widget->isDesktop() )
+ widget->translateMouseEvent( event ); //we don't get MotionNotify, emulate it
+
+ TQWidget* enter = 0;
+ XEvent ev;
+ while ( XCheckMaskEvent( widget->x11Display(), EnterWindowMask | LeaveWindowMask , &ev )
+ && !qt_x11EventFilter( &ev )) {
+ TQWidget* event_widget = TQWidget::tqfind( ev.xcrossing.window );
+ if( event_widget && event_widget->x11Event( &ev ) )
+ break;
+ if ( ev.type == LeaveNotify && ev.xcrossing.mode == NotifyNormal ){
+ enter = event_widget;
+ XPutBackEvent( widget->x11Display(), &ev );
+ break;
+ }
+ if ( ev.xcrossing.mode != NotifyNormal ||
+ ev.xcrossing.detail == NotifyVirtual ||
+ ev.xcrossing.detail == NotifyNonlinearVirtual )
+ continue;
+ enter = event_widget;
+ if ( ev.xcrossing.focus &&
+ enter && !enter->isDesktop() && !enter->isActiveWindow() ) {
+ if ( qt_focus_model == FocusModel_Unknown ) // check focus model
+ qt_check_focus_model();
+ if ( qt_focus_model == FocusModel_PointerRoot ) // PointerRoot mode
+ setActiveWindow( enter );
+ }
+ break;
+ }
+
+ if ( ( ! enter || enter->isDesktop() ) &&
+ event->xcrossing.focus && widget == active_window &&
+ qt_focus_model == FocusModel_PointerRoot // PointerRoot mode
+ ) {
+ setActiveWindow( 0 );
+ }
+
+ if ( !curWin )
+ qt_dispatchEnterLeave( widget, 0 );
+
+ qt_dispatchEnterLeave( enter, widget );
+ curWin = enter ? enter->winId() : 0;
+ }
+ break;
+
+ case UnmapNotify: // window hidden
+ if ( widget->isTopLevel() && widget->isShown() ) {
+ widget->topData()->spont_unmapped = 1;
+ TQHideEvent e;
+ TQApplication::sendSpontaneousEvent( widget, &e );
+ widget->hideChildren( TRUE );
+ }
+ break;
+
+ case MapNotify: // window shown
+ if ( widget->isTopLevel() &&
+ widget->topData()->spont_unmapped ) {
+ widget->topData()->spont_unmapped = 0;
+ widget->showChildren( TRUE );
+ TQShowEvent e;
+ TQApplication::sendSpontaneousEvent( widget, &e );
+ }
+ break;
+
+ case ClientMessage: // client message
+ return x11ClientMessage(widget,event,False);
+
+ case ReparentNotify: // window manager reparents
+ while ( XCheckTypedWindowEvent( widget->x11Display(),
+ widget->winId(),
+ ReparentNotify,
+ event ) )
+ ; // skip old reparent events
+ if ( event->xreparent.tqparent == TQPaintDevice::x11AppRootWindow() ) {
+ if ( widget->isTopLevel() ) {
+ widget->topData()->parentWinId = event->xreparent.tqparent;
+ if ( qt_deferred_map_tqcontains( widget ) ) {
+ qt_deferred_map_take( widget );
+ XMapWindow( appDpy, widget->winId() );
+ }
+ }
+ } else
+ // store the tqparent. Useful for many things, embedding for instance.
+ widget->topData()->parentWinId = event->xreparent.tqparent;
+ if ( widget->isTopLevel() ) {
+ // the widget frame strut should also be invalidated
+ widget->topData()->fleft = widget->topData()->fright =
+ widget->topData()->ftop = widget->topData()->fbottom = 0;
+
+ if ( qt_focus_model != FocusModel_Unknown ) {
+ // toplevel reparented...
+ TQWidget *newtqparent = TQWidget::tqfind( event->xreparent.tqparent );
+ if ( ! newtqparent || newtqparent->isDesktop() ) {
+ // we dont' know about the new tqparent (or we've been
+ // reparented to root), perhaps a window manager
+ // has been (re)started? reset the focus model to unknown
+ qt_focus_model = FocusModel_Unknown;
+ }
+ }
+ }
+ break;
+
+ case SelectionRequest: {
+ XSelectionRequestEvent *req = &event->xselectionrequest;
+ if (! req)
+ break;
+
+ if ( qt_xdnd_selection && req->selection == qt_xdnd_selection ) {
+ qt_xdnd_handle_selection_request( req );
+
+ } else if (qt_clipboard) {
+ TQCustomEvent e( TQEvent::Clipboard, event );
+ TQApplication::sendSpontaneousEvent( qt_clipboard, &e );
+ }
+ break;
+ }
+ case SelectionClear: {
+ XSelectionClearEvent *req = &event->xselectionclear;
+ // don't deliver dnd events to the clipboard, it gets confused
+ if (! req || qt_xdnd_selection && req->selection == qt_xdnd_selection)
+ break;
+
+ if (qt_clipboard) {
+ TQCustomEvent e( TQEvent::Clipboard, event );
+ TQApplication::sendSpontaneousEvent( qt_clipboard, &e );
+ }
+ break;
+ }
+
+ case SelectionNotify: {
+ XSelectionEvent *req = &event->xselection;
+ // don't deliver dnd events to the clipboard, it gets confused
+ if (! req || qt_xdnd_selection && req->selection == qt_xdnd_selection)
+ break;
+
+ if (qt_clipboard) {
+ TQCustomEvent e( TQEvent::Clipboard, event );
+ TQApplication::sendSpontaneousEvent( qt_clipboard, &e );
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/*!
+ This virtual function is only implemented under X11.
+
+ If you create an application that inherits TQApplication and
+ reimplement this function, you get direct access to all X events
+ that the are received from the X server.
+
+ Return TRUE if you want to stop the event from being processed.
+ Return FALSE for normal event dispatching.
+
+ \sa x11ProcessEvent()
+*/
+
+bool TQApplication::x11EventFilter( XEvent * )
+{
+ return FALSE;
+}
+
+
+
+/*****************************************************************************
+ Modal widgets; Since Xlib has little support for this we roll our own
+ modal widget mechanism.
+ A modal widget without a tqparent becomes application-modal.
+ A modal widget with a tqparent becomes modal to its tqparent and grandparents..
+
+ qt_enter_modal()
+ Enters modal state
+ Arguments:
+ TQWidget *widget A modal widget
+
+ qt_leave_modal()
+ Leaves modal state for a widget
+ Arguments:
+ TQWidget *widget A modal widget
+ *****************************************************************************/
+
+bool qt_modal_state()
+{
+ return app_do_modal;
+}
+
+void qt_enter_modal( TQWidget *widget )
+{
+ if ( !qt_modal_stack ) { // create modal stack
+ qt_modal_stack = new TQWidgetList;
+ TQ_CHECK_PTR( qt_modal_stack );
+ }
+ if (widget->parentWidget()) {
+ TQEvent e(TQEvent::WindowBlocked);
+ TQApplication::sendEvent(widget->parentWidget(), &e);
+ }
+
+ qt_dispatchEnterLeave( 0, TQWidget::tqfind((WId)curWin) );
+ qt_modal_stack->insert( 0, widget );
+ app_do_modal = TRUE;
+ curWin = 0;
+ ignoreNextMouseReleaseEvent = FALSE;
+}
+
+
+void qt_leave_modal( TQWidget *widget )
+{
+ if ( qt_modal_stack && qt_modal_stack->removeRef(widget) ) {
+ if ( qt_modal_stack->isEmpty() ) {
+ delete qt_modal_stack;
+ qt_modal_stack = 0;
+ TQPoint p( TQCursor::pos() );
+ TQWidget* w = TQApplication::widgetAt( p.x(), p.y(), TRUE );
+ qt_dispatchEnterLeave( w, TQWidget::tqfind( curWin ) ); // send synthetic enter event
+ curWin = w? w->winId() : 0;
+ }
+ }
+ app_do_modal = qt_modal_stack != 0;
+ ignoreNextMouseReleaseEvent = TRUE;
+
+ if (widget->parentWidget()) {
+ TQEvent e(TQEvent::WindowUnblocked);
+ TQApplication::sendEvent(widget->parentWidget(), &e);
+ }
+}
+
+
+bool qt_try_modal( TQWidget *widget, XEvent *event )
+{
+ if (qt_xdnd_dragging) {
+ // allow mouse events while DnD is active
+ switch (event->type) {
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ return TRUE;
+ default:
+ break;
+ }
+ }
+
+ if ( qt_tryModalHelper( widget ) )
+ return TRUE;
+
+ bool block_event = FALSE;
+ switch ( event->type ) {
+ case ButtonPress: // disallow mouse/key events
+ case ButtonRelease:
+ case MotionNotify:
+ case XKeyPress:
+ case XKeyRelease:
+ case EnterNotify:
+ case LeaveNotify:
+ case ClientMessage:
+ block_event = TRUE;
+ break;
+ default:
+ break;
+ }
+
+ return !block_event;
+}
+
+
+/*****************************************************************************
+ Popup widget mechanism
+
+ openPopup()
+ Adds a widget to the list of popup widgets
+ Arguments:
+ TQWidget *widget The popup widget to be added
+
+ closePopup()
+ Removes a widget from the list of popup widgets
+ Arguments:
+ TQWidget *widget The popup widget to be removed
+ *****************************************************************************/
+
+
+static int openPopupCount = 0;
+void TQApplication::openPopup( TQWidget *popup )
+{
+ openPopupCount++;
+ if ( !popupWidgets ) { // create list
+ popupWidgets = new TQWidgetList;
+ TQ_CHECK_PTR( popupWidgets );
+ }
+ popupWidgets->append( popup ); // add to end of list
+
+ if ( popupWidgets->count() == 1 && !qt_nograb() ){ // grab mouse/keyboard
+ int r = XGrabKeyboard( popup->x11Display(), popup->winId(), FALSE,
+ GrabModeSync, GrabModeAsync, CurrentTime );
+ if ( (popupGrabOk = (r == GrabSuccess)) ) {
+ r = XGrabPointer( popup->x11Display(), popup->winId(), TRUE,
+ (uint)(ButtonPressMask | ButtonReleaseMask |
+ ButtonMotionMask | EnterWindowMask |
+ LeaveWindowMask | PointerMotionMask),
+ GrabModeSync, GrabModeAsync,
+ None, None, CurrentTime );
+
+ if ( (popupGrabOk = (r == GrabSuccess)) )
+ XAllowEvents( popup->x11Display(), SyncPointer, CurrentTime );
+ else
+ XUngrabKeyboard( popup->x11Display(), CurrentTime );
+ }
+ } else if ( popupGrabOk ) {
+ XAllowEvents( popup->x11Display(), SyncPointer, CurrentTime );
+ }
+
+ // popups are not focus-handled by the window system (the first
+ // popup grabbed the keyboard), so we have to do that manually: A
+ // new popup gets the focus
+ TQFocusEvent::setReason( TQFocusEvent::Popup );
+ if ( popup->tqfocusWidget())
+ popup->tqfocusWidget()->setFocus();
+ else
+ popup->setFocus();
+ TQFocusEvent::resetReason();
+}
+
+void TQApplication::closePopup( TQWidget *popup )
+{
+ if ( !popupWidgets )
+ return;
+ popupWidgets->removeRef( popup );
+ if (popup == popupOfPopupButtonFocus) {
+ popupButtonFocus = 0;
+ popupOfPopupButtonFocus = 0;
+ }
+ if ( popupWidgets->count() == 0 ) { // this was the last popup
+ popupCloseDownMode = TRUE; // control mouse events
+ delete popupWidgets;
+ popupWidgets = 0;
+ if ( !qt_nograb() && popupGrabOk ) { // grabbing not disabled
+ if ( mouseButtonState != 0
+ || popup->tqgeometry(). tqcontains(TQPoint(mouseGlobalXPos, mouseGlobalYPos) ) )
+ { // mouse release event or inside
+ XAllowEvents( popup->x11Display(), AsyncPointer,
+ CurrentTime );
+ } else { // mouse press event
+ mouseButtonPressTime -= 10000; // avoid double click
+ XAllowEvents( popup->x11Display(), ReplayPointer,CurrentTime );
+ }
+ XUngrabPointer( popup->x11Display(), CurrentTime );
+ XFlush( popup->x11Display() );
+ }
+ if ( active_window ) {
+ TQFocusEvent::setReason( TQFocusEvent::Popup );
+ if ( active_window->tqfocusWidget() )
+ active_window->tqfocusWidget()->setFocus();
+ else
+ active_window->setFocus();
+ TQFocusEvent::resetReason();
+ }
+ } else {
+ // popups are not focus-handled by the window system (the
+ // first popup grabbed the keyboard), so we have to do that
+ // manually: A popup was closed, so the previous popup gets
+ // the focus.
+ TQFocusEvent::setReason( TQFocusEvent::Popup );
+ TQWidget* aw = popupWidgets->getLast();
+ if (aw->tqfocusWidget())
+ aw->tqfocusWidget()->setFocus();
+ else
+ aw->setFocus();
+ TQFocusEvent::resetReason();
+ if ( popupWidgets->count() == 1 && !qt_nograb() ){ // grab mouse/keyboard
+ int r = XGrabKeyboard( aw->x11Display(), aw->winId(), FALSE,
+ GrabModeSync, GrabModeAsync, CurrentTime );
+ if ( (popupGrabOk = (r == GrabSuccess)) ) {
+ r = XGrabPointer( aw->x11Display(), aw->winId(), TRUE,
+ (uint)(ButtonPressMask | ButtonReleaseMask |
+ ButtonMotionMask | EnterWindowMask |
+ LeaveWindowMask | PointerMotionMask),
+ GrabModeSync, GrabModeAsync,
+ None, None, CurrentTime );
+
+ if ( (popupGrabOk = (r == GrabSuccess)) )
+ XAllowEvents( aw->x11Display(), SyncPointer, CurrentTime );
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+ Event translation; translates X11 events to TQt events
+ *****************************************************************************/
+
+//
+// Mouse event translation
+//
+// Xlib doesn't give mouse double click events, so we generate them by
+// comparing window, time and position between two mouse press events.
+//
+
+//
+// Keyboard event translation
+//
+
+static int translateButtonState( int s )
+{
+ int bst = 0;
+ if ( s & Button1Mask )
+ bst |= TQt::LeftButton;
+ if ( s & Button2Mask )
+ bst |= TQt::MidButton;
+ if ( s & Button3Mask )
+ bst |= TQt::RightButton;
+ if ( s & ShiftMask )
+ bst |= TQt::ShiftButton;
+ if ( s & ControlMask )
+ bst |= TQt::ControlButton;
+ if ( s & qt_alt_mask )
+ bst |= TQt::AltButton;
+ if ( s & qt_meta_mask )
+ bst |= TQt::MetaButton;
+ return bst;
+}
+
+bool TQETWidget::translateMouseEvent( const XEvent *event )
+{
+ static bool manualGrab = FALSE;
+ TQEvent::Type type; // event parameters
+ TQPoint pos;
+ TQPoint globalPos;
+ int button = 0;
+ int state;
+ XEvent nextEvent;
+
+ if ( sm_blockUserInput ) // block user interaction during session management
+ return TRUE;
+
+ static int x_root_save = -1, y_root_save = -1;
+
+ if ( event->type == MotionNotify ) { // mouse move
+ if (event->xmotion.root != RootWindow(appDpy, x11Screen()) &&
+ ! qt_xdnd_dragging )
+ return FALSE;
+
+ XMotionEvent lastMotion = event->xmotion;
+ while( XPending( appDpy ) ) { // compres mouse moves
+ XNextEvent( appDpy, &nextEvent );
+ if ( nextEvent.type == ConfigureNotify
+ || nextEvent.type == PropertyNotify
+ || nextEvent.type == Expose
+ || nextEvent.type == NoExpose ) {
+ tqApp->x11ProcessEvent( &nextEvent );
+ continue;
+ } else if ( nextEvent.type != MotionNotify ||
+ nextEvent.xmotion.window != event->xmotion.window ||
+ nextEvent.xmotion.state != event->xmotion.state ) {
+ XPutBackEvent( appDpy, &nextEvent );
+ break;
+ }
+ if ( !qt_x11EventFilter(&nextEvent)
+ && !x11Event( &nextEvent ) ) // send event through filter
+ lastMotion = nextEvent.xmotion;
+ else
+ break;
+ }
+ type = TQEvent::MouseMove;
+ pos.rx() = lastMotion.x;
+ pos.ry() = lastMotion.y;
+ globalPos.rx() = lastMotion.x_root;
+ globalPos.ry() = lastMotion.y_root;
+ state = translateButtonState( lastMotion.state );
+ if ( qt_button_down && (state & (LeftButton |
+ MidButton |
+ RightButton ) ) == 0 )
+ qt_button_down = 0;
+
+ // throw away mouse move events that are sent multiple times to the same
+ // position
+ bool throw_away = FALSE;
+ if ( x_root_save == globalPos.x() &&
+ y_root_save == globalPos.y() )
+ throw_away = TRUE;
+ x_root_save = globalPos.x();
+ y_root_save = globalPos.y();
+ if ( throw_away )
+ return TRUE;
+ } else if ( event->type == EnterNotify || event->type == LeaveNotify) {
+ XEvent *xevent = (XEvent *)event;
+ //unsigned int xstate = event->xcrossing.state;
+ type = TQEvent::MouseMove;
+ pos.rx() = xevent->xcrossing.x;
+ pos.ry() = xevent->xcrossing.y;
+ globalPos.rx() = xevent->xcrossing.x_root;
+ globalPos.ry() = xevent->xcrossing.y_root;
+ state = translateButtonState( xevent->xcrossing.state );
+ if ( qt_button_down && (state & (LeftButton |
+ MidButton |
+ RightButton ) ) == 0 )
+ qt_button_down = 0;
+ if ( !qt_button_down )
+ state = state & ~(LeftButton | MidButton | RightButton );
+ } else { // button press or release
+ pos.rx() = event->xbutton.x;
+ pos.ry() = event->xbutton.y;
+ globalPos.rx() = event->xbutton.x_root;
+ globalPos.ry() = event->xbutton.y_root;
+ state = translateButtonState( event->xbutton.state );
+ switch ( event->xbutton.button ) {
+ case Button1: button = LeftButton; break;
+ case Button2: button = MidButton; break;
+ case Button3: button = RightButton; break;
+ case Button4:
+ case Button5:
+ case 6:
+ case 7:
+ // the fancy mouse wheel.
+
+ // take care about grabbing. We do this here since it
+ // is clear that we return anyway
+ if ( tqApp->inPopupMode() && popupGrabOk )
+ XAllowEvents( x11Display(), SyncPointer, CurrentTime );
+
+ // We are only interested in ButtonPress.
+ if (event->type == ButtonPress ){
+
+ // compress wheel events (the X Server will simply
+ // send a button press for each single notch,
+ // regardless whether the application can catch up
+ // or not)
+ int delta = 1;
+ XEvent xevent;
+ while ( XCheckTypedWindowEvent(x11Display(),winId(),
+ ButtonPress,&xevent) ){
+ if (xevent.xbutton.button != event->xbutton.button){
+ XPutBackEvent(x11Display(), &xevent);
+ break;
+ }
+ delta++;
+ }
+
+ // the delta is defined as multiples of
+ // WHEEL_DELTA, which is set to 120. Future wheels
+ // may offer a finer-resolution. A positive delta
+ // indicates forward rotation, a negative one
+ // backward rotation respectively.
+ int btn = event->xbutton.button;
+ delta *= 120 * ( (btn == Button4 || btn == 6) ? 1 : -1 );
+ bool hor = ( (btn == Button4 || btn == Button5) && (state&AltButton) ||
+ (btn == 6 || btn == 7) );
+ translateWheelEvent( globalPos.x(), globalPos.y(), delta, state, (hor)?Horizontal:Vertical );
+ }
+ return TRUE;
+ }
+ if ( event->type == ButtonPress ) { // mouse button pressed
+#if defined(TQ_OS_IRIX) && defined(TQT_TABLET_SUPPORT)
+ XEvent myEv;
+ if ( XCheckTypedEvent( appDpy, xinput_button_press, &myEv ) ) {
+ if ( translateXinputEvent( &myEv ) ) {
+ //Spontaneous event sent. Check if we need to continue.
+ if ( chokeMouse ) {
+ chokeMouse = FALSE;
+ return FALSE;
+ }
+ }
+ }
+#endif
+ qt_button_down = tqchildAt( pos ); //magic for masked widgets
+ if ( !qt_button_down || !qt_button_down->testWFlags(WMouseNoMask) )
+ qt_button_down = this;
+ if ( mouseActWindow == event->xbutton.window &&
+ mouseButtonPressed == button &&
+ (long)event->xbutton.time -(long)mouseButtonPressTime
+ < TQApplication::doubleClickInterval() &&
+ TQABS(event->xbutton.x - mouseXPos) < 5 &&
+ TQABS(event->xbutton.y - mouseYPos) < 5 ) {
+ type = TQEvent::MouseButtonDblClick;
+ mouseButtonPressTime -= 2000; // no double-click next time
+ } else {
+ type = TQEvent::MouseButtonPress;
+ mouseButtonPressTime = event->xbutton.time;
+ }
+ mouseButtonPressed = button; // save event params for
+ mouseXPos = pos.x(); // future double click tests
+ mouseYPos = pos.y();
+ mouseGlobalXPos = globalPos.x();
+ mouseGlobalYPos = globalPos.y();
+ } else { // mouse button released
+#if defined(TQ_OS_IRIX) && defined(TQT_TABLET_SUPPORT)
+ XEvent myEv;
+ if ( XCheckTypedEvent( appDpy, xinput_button_release, &myEv ) ) {
+ if ( translateXinputEvent( &myEv ) ) {
+ //Spontaneous event sent. Check if we need to continue.
+ if ( chokeMouse ) {
+ chokeMouse = FALSE;
+ return FALSE;
+ }
+ }
+ }
+#endif
+ if ( manualGrab ) { // release manual grab
+ manualGrab = FALSE;
+ XUngrabPointer( x11Display(), CurrentTime );
+ XFlush( x11Display() );
+ }
+
+ type = TQEvent::MouseButtonRelease;
+ }
+ }
+ mouseActWindow = winId(); // save some event params
+ mouseButtonState = state;
+ if ( type == 0 ) // don't send event
+ return FALSE;
+
+ if ( tqApp->inPopupMode() ) { // in popup mode
+ TQWidget *popup = tqApp->activePopupWidget();
+ if ( popup != this ) {
+ if ( testWFlags(WType_Popup) && rect().tqcontains(pos) )
+ popup = this;
+ else // send to last popup
+ pos = popup->mapFromGlobal( globalPos );
+ }
+ bool releaseAfter = FALSE;
+ TQWidget *popupChild = popup->tqchildAt( pos );
+ TQWidget *popupTarget = popupChild ? popupChild : popup;
+
+ if (popup != popupOfPopupButtonFocus){
+ popupButtonFocus = 0;
+ popupOfPopupButtonFocus = 0;
+ }
+
+ if ( !popupTarget->isEnabled() ) {
+ if ( popupGrabOk )
+ XAllowEvents( x11Display(), SyncPointer, CurrentTime );
+ }
+
+ switch ( type ) {
+ case TQEvent::MouseButtonPress:
+ case TQEvent::MouseButtonDblClick:
+ popupButtonFocus = popupChild;
+ popupOfPopupButtonFocus = popup;
+ break;
+ case TQEvent::MouseButtonRelease:
+ releaseAfter = TRUE;
+ break;
+ default:
+ break; // nothing for mouse move
+ }
+
+ Display* dpy = x11Display(); // store display, send() may destroy us
+
+
+ int oldOpenPopupCount = openPopupCount;
+
+ if ( popupButtonFocus ) {
+ TQMouseEvent e( type, popupButtonFocus->mapFromGlobal(globalPos),
+ globalPos, button, state );
+ TQApplication::sendSpontaneousEvent( popupButtonFocus, &e );
+ if ( releaseAfter ) {
+ popupButtonFocus = 0;
+ popupOfPopupButtonFocus = 0;
+ }
+ } else if ( popupChild ) {
+ TQMouseEvent e( type, popupChild->mapFromGlobal(globalPos),
+ globalPos, button, state );
+ TQApplication::sendSpontaneousEvent( popupChild, &e );
+ } else {
+ TQMouseEvent e( type, pos, globalPos, button, state );
+ TQApplication::sendSpontaneousEvent( popup, &e );
+ }
+
+ if ( type == TQEvent::MouseButtonPress && button == RightButton && ( openPopupCount == oldOpenPopupCount ) ) {
+ TQWidget *popupEvent = popup;
+ if(popupButtonFocus)
+ popupEvent = popupButtonFocus;
+ else if(popupChild)
+ popupEvent = popupChild;
+ TQContextMenuEvent e( TQContextMenuEvent::Mouse, pos, globalPos, state );
+ TQApplication::sendSpontaneousEvent( popupEvent, &e );
+ }
+
+ if ( releaseAfter )
+ qt_button_down = 0;
+
+ if ( tqApp->inPopupMode() ) { // still in popup mode
+ if ( popupGrabOk )
+ XAllowEvents( dpy, SyncPointer, CurrentTime );
+ } else {
+ if ( type != TQEvent::MouseButtonRelease && state != 0 &&
+ TQWidget::tqfind((WId)mouseActWindow) ) {
+ manualGrab = TRUE; // need to manually grab
+ XGrabPointer( dpy, mouseActWindow, False,
+ (uint)(ButtonPressMask | ButtonReleaseMask |
+ ButtonMotionMask |
+ EnterWindowMask | LeaveWindowMask),
+ GrabModeAsync, GrabModeAsync,
+ None, None, CurrentTime );
+ }
+ }
+
+ } else {
+ TQWidget *widget = this;
+ TQWidget *w = TQWidget::mouseGrabber();
+ if ( !w )
+ w = qt_button_down;
+ if ( w && w != this ) {
+ widget = w;
+ pos = w->mapFromGlobal( globalPos );
+ }
+
+ if ( popupCloseDownMode ) {
+ popupCloseDownMode = FALSE;
+ if ( testWFlags(WType_Popup) ) // ignore replayed event
+ return TRUE;
+ }
+
+ if ( type == TQEvent::MouseButtonRelease &&
+ (state & (~button) & ( LeftButton |
+ MidButton |
+ RightButton)) == 0 ) {
+ qt_button_down = 0;
+ }
+
+ int oldOpenPopupCount = openPopupCount;
+
+ TQMouseEvent e( type, pos, globalPos, button, state );
+ TQApplication::sendSpontaneousEvent( widget, &e );
+
+ if ( type == TQEvent::MouseButtonPress && button == RightButton && ( openPopupCount == oldOpenPopupCount ) ) {
+ TQContextMenuEvent e( TQContextMenuEvent::Mouse, pos, globalPos, state );
+ TQApplication::sendSpontaneousEvent( widget, &e );
+ }
+ }
+ return TRUE;
+}
+
+
+//
+// Wheel event translation
+//
+bool TQETWidget::translateWheelEvent( int global_x, int global_y, int delta, int state, Orientation orient )
+{
+ // send the event to the widget or its ancestors
+ {
+ TQWidget* popup = tqApp->activePopupWidget();
+ if ( popup && tqtopLevelWidget() != popup )
+ popup->close();
+ TQWheelEvent e( mapFromGlobal(TQPoint( global_x, global_y)),
+ TQPoint(global_x, global_y), delta, state, orient );
+ if ( TQApplication::sendSpontaneousEvent( this, &e ) )
+ return TRUE;
+ }
+
+ // send the event to the widget that has the focus or its ancestors, if different
+ TQWidget *w = this;
+ if ( w != tqApp->tqfocusWidget() && ( w = tqApp->tqfocusWidget() ) ) {
+ TQWidget* popup = tqApp->activePopupWidget();
+ if ( popup && w != popup )
+ popup->hide();
+ TQWheelEvent e( mapFromGlobal(TQPoint( global_x, global_y)),
+ TQPoint(global_x, global_y), delta, state, orient );
+ if ( TQApplication::sendSpontaneousEvent( w, &e ) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//
+// XInput Translation Event
+//
+#if defined (TQT_TABLET_SUPPORT)
+bool TQETWidget::translateXinputEvent( const XEvent *ev )
+{
+#if defined (TQ_OS_IRIX)
+ // Wacom has put defines in their wacom.h file so it would be quite wise
+ // to use them, need to think of a decent way of not using
+ // it when it doesn't exist...
+ XDeviceState *s;
+ XInputClass *iClass;
+ XValuatorState *vs;
+ int j;
+#endif
+ TQWidget *w = this;
+ TQPoint global,
+ curr;
+ static int pressure = 0;
+ static int xTilt = 0,
+ yTilt = 0;
+ int tqdeviceType = TQTabletEvent::NoDevice;
+ TQPair<int, int> tId;
+ XEvent xinputMotionEvent;
+ XEvent mouseMotionEvent;
+ XDevice *dev;
+ const XDeviceMotionEvent *motion = 0;
+ XDeviceButtonEvent *button = 0;
+ TQEvent::Type t;
+
+ if ( ev->type == xinput_motion ) {
+ motion = (const XDeviceMotionEvent*)ev;
+ for (;;) {
+ if (!XCheckTypedWindowEvent(x11Display(), winId(), MotionNotify, &mouseMotionEvent))
+ break;
+ if (!XCheckTypedWindowEvent(x11Display(), winId(), xinput_motion, &xinputMotionEvent)) {
+ XPutBackEvent(x11Display(), &mouseMotionEvent);
+ break;
+ }
+ if (mouseMotionEvent.xmotion.time != motion->time) {
+ XPutBackEvent(x11Display(), &mouseMotionEvent);
+ XPutBackEvent(x11Display(), &xinputMotionEvent);
+ break;
+ }
+ motion = ((const XDeviceMotionEvent*)&xinputMotionEvent);
+ }
+ t = TQEvent::TabletMove;
+ curr = TQPoint( motion->x, motion->y );
+ } else {
+ if ( ev->type == xinput_button_press ) {
+ t = TQEvent::TabletPress;
+ } else {
+ t = TQEvent::TabletRelease;
+ }
+ button = (XDeviceButtonEvent*)ev;
+/*
+ qDebug( "\n\nXInput Button Event" );
+ qDebug( "serial:\t%d", button->serial );
+ qDebug( "send_event:\t%d", button->send_event );
+ qDebug( "display:\t%p", button->display );
+ qDebug( "window:\t%d", button->window );
+ qDebug( "tqdeviceID:\t%d", button->tqdeviceid );
+ qDebug( "root:\t%d", button->root );
+ qDebug( "subwindot:\t%d", button->subwindow );
+ qDebug( "x:\t%d", button->x );
+ qDebug( "y:\t%d", button->y );
+ qDebug( "x_root:\t%d", button->x_root );
+ qDebug( "y_root:\t%d", button->y_root );
+ qDebug( "state:\t%d", button->state );
+ qDebug( "button:\t%d", button->button );
+ qDebug( "same_screen:\t%d", button->same_screen );
+ qDebug( "time:\t%d", button->time );
+*/
+ curr = TQPoint( button->x, button->y );
+ }
+#if defined(TQ_OS_IRIX)
+ // default...
+ dev = devStylus;
+#else
+ if ( ev->type == xinput_motion ) {
+ if ( motion->tqdeviceid == devStylus->tqdevice_id ) {
+ dev = devStylus;
+ tqdeviceType = TQTabletEvent::Stylus;
+ } else if ( motion->tqdeviceid == devEraser->tqdevice_id ) {
+ dev = devEraser;
+ tqdeviceType = TQTabletEvent::Eraser;
+ }
+ } else {
+ if ( button->tqdeviceid == devStylus->tqdevice_id ) {
+ dev = devStylus;
+ tqdeviceType = TQTabletEvent::Stylus;
+ } else if ( button->tqdeviceid == devEraser->tqdevice_id ) {
+ dev = devEraser;
+ tqdeviceType = TQTabletEvent::Eraser;
+ }
+ }
+#endif
+
+ const int PRESSURE_LEVELS = 255;
+ // we got the maximum pressure at start time, since various tablets have
+ // varying levels of distinguishing pressure changes, let's standardize and
+ // scale everything to 256 different levels...
+ static int scaleFactor = -1;
+ if ( scaleFactor == -1 ) {
+ if ( max_pressure > PRESSURE_LEVELS )
+ scaleFactor = max_pressure / PRESSURE_LEVELS;
+ else
+ scaleFactor = PRESSURE_LEVELS / max_pressure;
+ }
+#if defined (TQ_OS_IRIX)
+ s = XQueryDeviceState( appDpy, dev );
+ if ( s == NULL )
+ return FALSE;
+ iClass = s->data;
+ for ( j = 0; j < s->num_classes; j++ ) {
+ if ( iClass->c_class == ValuatorClass ) {
+ vs = (XValuatorState *)iClass;
+ // figure out what tqdevice we have, based on bitmasking...
+ if ( vs->valuators[WAC_TRANSDUCER_I]
+ & WAC_TRANSDUCER_PROX_MSK ) {
+ switch ( vs->valuators[WAC_TRANSDUCER_I]
+ & WAC_TRANSDUCER_MSK ) {
+ case WAC_PUCK_ID:
+ tqdeviceType = TQTabletEvent::Puck;
+ break;
+ case WAC_STYLUS_ID:
+ tqdeviceType = TQTabletEvent::Stylus;
+ break;
+ case WAC_ERASER_ID:
+ tqdeviceType = TQTabletEvent::Eraser;
+ break;
+ }
+ // Get a Unique Id for the tqdevice, Wacom gives us this ability
+ tId.first = vs->valuators[WAC_TRANSDUCER_I] & WAC_TRANSDUCER_ID_MSK;
+ tId.second = vs->valuators[WAC_SERIAL_NUM_I];
+ } else
+ tqdeviceType = TQTabletEvent::NoDevice;
+ // apparently Wacom needs a cast for the +/- values to make sense
+ xTilt = short(vs->valuators[WAC_XTILT_I]);
+ yTilt = short(vs->valuators[WAC_YTILT_I]);
+ if ( max_pressure > PRESSURE_LEVELS )
+ pressure = vs->valuators[WAC_PRESSURE_I] / scaleFactor;
+ else
+ pressure = vs->valuators[WAC_PRESSURE_I] * scaleFactor;
+ global = TQPoint( vs->valuators[WAC_XCOORD_I],
+ vs->valuators[WAC_YCOORD_I] );
+ break;
+ }
+ iClass = (XInputClass*)((char*)iClass + iClass->length);
+ }
+ XFreeDeviceState( s );
+#else
+ if ( motion ) {
+ xTilt = short(motion->axis_data[3]);
+ yTilt = short(motion->axis_data[4]);
+ if ( max_pressure > PRESSURE_LEVELS )
+ pressure = motion->axis_data[2] / scaleFactor;
+ else
+ pressure = motion->axis_data[2] * scaleFactor;
+ global = TQPoint( motion->axis_data[0], motion->axis_data[1] );
+ } else {
+ xTilt = short(button->axis_data[3]);
+ yTilt = short(button->axis_data[4]);
+ if ( max_pressure > PRESSURE_LEVELS )
+ pressure = button->axis_data[2] / scaleFactor;
+ else
+ pressure = button->axis_data[2] * scaleFactor;
+ global = TQPoint( button->axis_data[0], button->axis_data[1] );
+ }
+ // The only way to get these Ids is to scan the XFree86 log, which I'm not going to do.
+ tId.first = tId.second = -1;
+#endif
+
+ TQTabletEvent e( t, curr, global, tqdeviceType, pressure, xTilt, yTilt, tId );
+ TQApplication::sendSpontaneousEvent( w, &e );
+ return TRUE;
+}
+#endif
+
+bool TQETWidget::translatePropertyEvent(const XEvent *event)
+{
+ if (!isTopLevel()) return TRUE;
+
+ Atom ret;
+ int format, e;
+ unsigned char *data = 0;
+ unsigned long nitems, after;
+
+ if (event->xproperty.atom == qt_net_wm_frame_strut) {
+ topData()->fleft = topData()->fright = topData()->ftop = topData()->fbottom = 0;
+ fstrut_dirty = 1;
+
+ if (event->xproperty.state == PropertyNewValue) {
+ e = XGetWindowProperty(appDpy, event->xproperty.window, qt_net_wm_frame_strut,
+ 0, 4, // struts are 4 longs
+ False, XA_CARDINAL, &ret, &format, &nitems, &after, &data);
+
+ if (e == Success && ret == XA_CARDINAL &&
+ format == 32 && nitems == 4) {
+ long *strut = (long *) data;
+ topData()->fleft = strut[0];
+ topData()->fright = strut[1];
+ topData()->ftop = strut[2];
+ topData()->fbottom = strut[3];
+ fstrut_dirty = 0;
+ }
+ }
+ } else if (event->xproperty.atom == qt_net_wm_state) {
+ bool max = FALSE;
+ bool full = FALSE;
+
+ if (event->xproperty.state == PropertyNewValue) {
+ // using length of 1024 should be safe for all current and
+ // possible NET states...
+ e = XGetWindowProperty(appDpy, event->xproperty.window, qt_net_wm_state, 0, 1024,
+ False, XA_ATOM, &ret, &format, &nitems, &after, &data);
+
+ if (e == Success && ret == XA_ATOM && format == 32 && nitems > 0) {
+ Atom *states = (Atom *) data;
+
+ unsigned long i;
+ for (i = 0; i < nitems; i++) {
+ if (states[i] == qt_net_wm_state_max_v || states[i] == qt_net_wm_state_max_h)
+ max = TRUE;
+ else if (states[i] == qt_net_wm_state_fullscreen)
+ full = TRUE;
+ }
+ }
+ }
+
+ bool send_event = FALSE;
+
+ if (qt_net_supports(qt_net_wm_state_max_v)
+ && qt_net_supports(qt_net_wm_state_max_h)) {
+ if (max && !isMaximized()) {
+ setWState(WState_Maximized);
+ send_event = TRUE;
+ } else if (!max && isMaximized()) {
+ clearWState(WState_Maximized);
+ send_event = TRUE;
+ }
+ }
+
+ if (qt_net_supports(qt_net_wm_state_fullscreen)) {
+ if (full && !isFullScreen()) {
+ setWState(WState_FullScreen);
+ send_event = TRUE;
+ } else if (!full && isFullScreen()) {
+ clearWState(WState_FullScreen);
+ send_event = TRUE;
+ }
+ }
+
+ if (send_event) {
+ TQEvent e(TQEvent::WindowStateChange);
+ TQApplication::sendSpontaneousEvent(this, &e);
+ }
+ } else if (event->xproperty.atom == qt_wm_state) {
+ // the widget frame strut should also be invalidated
+ topData()->fleft = topData()->fright = topData()->ftop = topData()->fbottom = 0;
+ fstrut_dirty = 1;
+
+ if (event->xproperty.state == PropertyDelete) {
+ // the window manager has removed the WM State property,
+ // so it is now in the withdrawn state (ICCCM 4.1.3.1) and
+ // we are free to reuse this window
+ topData()->parentWinId = 0;
+ // map the window if we were waiting for a transition to
+ // withdrawn
+ if ( qt_deferred_map_tqcontains( this ) ) {
+ qt_deferred_map_take( this );
+ XMapWindow( appDpy, winId() );
+ }
+ } else if (topData()->parentWinId != TQPaintDevice::x11AppRootWindow(x11Screen())) {
+ // the window manager has changed the WM State property...
+ // we are wanting to see if we are withdrawn so that we
+ // can reuse this window... we only do this check *IF* we
+ // haven't been reparented to root - (the parentWinId !=
+ // TQPaintDevice::x11AppRootWindow(x11Screen())) check
+ // above
+
+ e = XGetWindowProperty(appDpy, winId(), qt_wm_state, 0, 2, False, qt_wm_state,
+ &ret, &format, &nitems, &after, &data );
+
+ if (e == Success && ret == qt_wm_state && format == 32 && nitems > 0) {
+ long *state = (long *) data;
+ switch (state[0]) {
+ case WithdrawnState:
+ // if we are in the withdrawn state, we are free
+ // to reuse this window provided we remove the
+ // WM_STATE property (ICCCM 4.1.3.1)
+ XDeleteProperty(appDpy, winId(), qt_wm_state);
+
+ // set the tqparent id to zero, so that show() will
+ // work again
+ topData()->parentWinId = 0;
+ // map the window if we were waiting for a
+ // transition to withdrawn
+ if ( qt_deferred_map_tqcontains( this ) ) {
+ qt_deferred_map_take( this );
+ XMapWindow( appDpy, winId() );
+ }
+ break;
+
+ case IconicState:
+ if (!isMinimized()) {
+ // window was minimized
+ setWState(WState_Minimized);
+ TQEvent e(TQEvent::WindowStateChange);
+ TQApplication::sendSpontaneousEvent(this, &e);
+ }
+ break;
+
+ default:
+ if (isMinimized()) {
+ // window was un-minimized
+ clearWState(WState_Minimized);
+ TQEvent e(TQEvent::WindowStateChange);
+ TQApplication::sendSpontaneousEvent(this, &e);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if (data)
+ XFree(data);
+
+ return TRUE;
+}
+
+#ifndef XK_ISO_Left_Tab
+#define XK_ISO_Left_Tab 0xFE20
+#endif
+
+// the next lines are taken from XFree > 4.0 (X11/XF86keysyms.h), defining some special
+// multimedia keys. They are included here as not every system has them.
+#define XF86XK_Standby 0x1008FF10
+#define XF86XK_AudioLowerVolume 0x1008FF11
+#define XF86XK_AudioMute 0x1008FF12
+#define XF86XK_AudioRaiseVolume 0x1008FF13
+#define XF86XK_AudioPlay 0x1008FF14
+#define XF86XK_AudioStop 0x1008FF15
+#define XF86XK_AudioPrev 0x1008FF16
+#define XF86XK_AudioNext 0x1008FF17
+#define XF86XK_HomePage 0x1008FF18
+#define XF86XK_Calculator 0x1008FF1D
+#define XF86XK_Mail 0x1008FF19
+#define XF86XK_Start 0x1008FF1A
+#define XF86XK_Search 0x1008FF1B
+#define XF86XK_AudioRecord 0x1008FF1C
+#define XF86XK_Back 0x1008FF26
+#define XF86XK_Forward 0x1008FF27
+#define XF86XK_Stop 0x1008FF28
+#define XF86XK_Refresh 0x1008FF29
+#define XF86XK_Favorites 0x1008FF30
+#define XF86XK_AudioPause 0x1008FF31
+#define XF86XK_AudioMedia 0x1008FF32
+#define XF86XK_MyComputer 0x1008FF33
+#define XF86XK_OpenURL 0x1008FF38
+#define XF86XK_Launch0 0x1008FF40
+#define XF86XK_Launch1 0x1008FF41
+#define XF86XK_Launch2 0x1008FF42
+#define XF86XK_Launch3 0x1008FF43
+#define XF86XK_Launch4 0x1008FF44
+#define XF86XK_Launch5 0x1008FF45
+#define XF86XK_Launch6 0x1008FF46
+#define XF86XK_Launch7 0x1008FF47
+#define XF86XK_Launch8 0x1008FF48
+#define XF86XK_Launch9 0x1008FF49
+#define XF86XK_LaunchA 0x1008FF4A
+#define XF86XK_LaunchB 0x1008FF4B
+#define XF86XK_LaunchC 0x1008FF4C
+#define XF86XK_LaunchD 0x1008FF4D
+#define XF86XK_LaunchE 0x1008FF4E
+#define XF86XK_LaunchF 0x1008FF4F
+// end of XF86keysyms.h
+
+
+
+static const KeySym KeyTbl[] = { // keyboard mapping table
+ XK_Escape, TQt::Key_Escape, // misc keys
+ XK_Tab, TQt::Key_Tab,
+ XK_ISO_Left_Tab, TQt::Key_Backtab,
+ XK_BackSpace, TQt::Key_Backspace,
+ XK_Return, TQt::Key_Return,
+ XK_Insert, TQt::Key_Insert,
+ XK_KP_Insert, TQt::Key_Insert,
+ XK_Delete, TQt::Key_Delete,
+ XK_KP_Delete, TQt::Key_Delete,
+ XK_Clear, TQt::Key_Delete,
+ XK_Pause, TQt::Key_Pause,
+ XK_Print, TQt::Key_Print,
+ XK_KP_Begin, TQt::Key_Clear,
+ 0x1005FF60, TQt::Key_SysReq, // hardcoded Sun SysReq
+ 0x1007ff00, TQt::Key_SysReq, // hardcoded X386 SysReq
+ XK_Home, TQt::Key_Home, // cursor movement
+ XK_End, TQt::Key_End,
+ XK_Left, TQt::Key_Left,
+ XK_Up, TQt::Key_Up,
+ XK_Right, TQt::Key_Right,
+ XK_Down, TQt::Key_Down,
+ XK_Prior, TQt::Key_Prior,
+ XK_Next, TQt::Key_Next,
+ XK_KP_Home, TQt::Key_Home,
+ XK_KP_End, TQt::Key_End,
+ XK_KP_Left, TQt::Key_Left,
+ XK_KP_Up, TQt::Key_Up,
+ XK_KP_Right, TQt::Key_Right,
+ XK_KP_Down, TQt::Key_Down,
+ XK_KP_Prior, TQt::Key_Prior,
+ XK_KP_Next, TQt::Key_Next,
+ XK_Shift_L, TQt::Key_Shift, // modifiers
+ XK_Shift_R, TQt::Key_Shift,
+ XK_Shift_Lock, TQt::Key_Shift,
+ XK_Control_L, TQt::Key_Control,
+ XK_Control_R, TQt::Key_Control,
+ XK_Meta_L, TQt::Key_Meta,
+ XK_Meta_R, TQt::Key_Meta,
+ XK_Alt_L, TQt::Key_Alt,
+ XK_Alt_R, TQt::Key_Alt,
+ XK_Caps_Lock, TQt::Key_CapsLock,
+ XK_Num_Lock, TQt::Key_NumLock,
+ XK_Scroll_Lock, TQt::Key_ScrollLock,
+ XK_KP_Space, TQt::Key_Space, // numeric keypad
+ XK_KP_Tab, TQt::Key_Tab,
+ XK_KP_Enter, TQt::Key_Enter,
+ XK_KP_Equal, TQt::Key_Equal,
+ XK_KP_Multiply, TQt::Key_Asterisk,
+ XK_KP_Add, TQt::Key_Plus,
+ XK_KP_Separator, TQt::Key_Comma,
+ XK_KP_Subtract, TQt::Key_Minus,
+ XK_KP_Decimal, TQt::Key_Period,
+ XK_KP_Divide, TQt::Key_Slash,
+ XK_Super_L, TQt::Key_Super_L,
+ XK_Super_R, TQt::Key_Super_R,
+ XK_Menu, TQt::Key_Menu,
+ XK_Hyper_L, TQt::Key_Hyper_L,
+ XK_Hyper_R, TQt::Key_Hyper_R,
+ XK_Help, TQt::Key_Help,
+ 0x1000FF74, TQt::Key_BackTab, // hardcoded HP backtab
+ 0x1005FF10, TQt::Key_F11, // hardcoded Sun F36 (labeled F11)
+ 0x1005FF11, TQt::Key_F12, // hardcoded Sun F37 (labeled F12)
+
+ // Special multimedia keys
+ // currently only tested with MS internet keyboard
+
+ // browsing keys
+ XF86XK_Back, TQt::Key_Back,
+ XF86XK_Forward, TQt::Key_Forward,
+ XF86XK_Stop, TQt::Key_Stop,
+ XF86XK_Refresh, TQt::Key_Refresh,
+ XF86XK_Favorites, TQt::Key_Favorites,
+ XF86XK_AudioMedia, TQt::Key_LaunchMedia,
+ XF86XK_OpenURL, TQt::Key_OpenUrl,
+ XF86XK_HomePage, TQt::Key_HomePage,
+ XF86XK_Search, TQt::Key_Search,
+
+ // media keys
+ XF86XK_AudioLowerVolume, TQt::Key_VolumeDown,
+ XF86XK_AudioMute, TQt::Key_VolumeMute,
+ XF86XK_AudioRaiseVolume, TQt::Key_VolumeUp,
+ XF86XK_AudioPlay, TQt::Key_MediaPlay,
+ XF86XK_AudioStop, TQt::Key_MediaStop,
+ XF86XK_AudioPrev, TQt::Key_MediaPrev,
+ XF86XK_AudioNext, TQt::Key_MediaNext,
+ XF86XK_AudioRecord, TQt::Key_MediaRecord,
+
+ // launch keys
+ XF86XK_Mail, TQt::Key_LaunchMail,
+ XF86XK_MyComputer, TQt::Key_Launch0,
+ XF86XK_Calculator, TQt::Key_Launch1,
+ XF86XK_Standby, TQt::Key_Standby,
+
+ XF86XK_Launch0, TQt::Key_Launch2,
+ XF86XK_Launch1, TQt::Key_Launch3,
+ XF86XK_Launch2, TQt::Key_Launch4,
+ XF86XK_Launch3, TQt::Key_Launch5,
+ XF86XK_Launch4, TQt::Key_Launch6,
+ XF86XK_Launch5, TQt::Key_Launch7,
+ XF86XK_Launch6, TQt::Key_Launch8,
+ XF86XK_Launch7, TQt::Key_Launch9,
+ XF86XK_Launch8, TQt::Key_LaunchA,
+ XF86XK_Launch9, TQt::Key_LaunchB,
+ XF86XK_LaunchA, TQt::Key_LaunchC,
+ XF86XK_LaunchB, TQt::Key_LaunchD,
+ XF86XK_LaunchC, TQt::Key_LaunchE,
+ XF86XK_LaunchD, TQt::Key_LaunchF,
+
+ 0, 0
+};
+
+
+static TQIntDict<void> *keyDict = 0;
+static TQIntDict<void> *textDict = 0;
+
+static void deleteKeyDicts()
+{
+ if ( keyDict )
+ delete keyDict;
+ keyDict = 0;
+ if ( textDict )
+ delete textDict;
+ textDict = 0;
+}
+
+#if !defined(TQT_NO_XIM)
+static const unsigned short katakanaKeysymsToUnicode[] = {
+ 0x0000, 0x3002, 0x300C, 0x300D, 0x3001, 0x30FB, 0x30F2, 0x30A1,
+ 0x30A3, 0x30A5, 0x30A7, 0x30A9, 0x30E3, 0x30E5, 0x30E7, 0x30C3,
+ 0x30FC, 0x30A2, 0x30A4, 0x30A6, 0x30A8, 0x30AA, 0x30AB, 0x30AD,
+ 0x30AF, 0x30B1, 0x30B3, 0x30B5, 0x30B7, 0x30B9, 0x30BB, 0x30BD,
+ 0x30BF, 0x30C1, 0x30C4, 0x30C6, 0x30C8, 0x30CA, 0x30CB, 0x30CC,
+ 0x30CD, 0x30CE, 0x30CF, 0x30D2, 0x30D5, 0x30D8, 0x30DB, 0x30DE,
+ 0x30DF, 0x30E0, 0x30E1, 0x30E2, 0x30E4, 0x30E6, 0x30E8, 0x30E9,
+ 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EF, 0x30F3, 0x309B, 0x309C
+};
+
+static const unsigned short cyrillicKeysymsToUnicode[] = {
+ 0x0000, 0x0452, 0x0453, 0x0451, 0x0454, 0x0455, 0x0456, 0x0457,
+ 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x0000, 0x045e, 0x045f,
+ 0x2116, 0x0402, 0x0403, 0x0401, 0x0404, 0x0405, 0x0406, 0x0407,
+ 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x0000, 0x040e, 0x040f,
+ 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433,
+ 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e,
+ 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432,
+ 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a,
+ 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413,
+ 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e,
+ 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412,
+ 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a
+};
+
+static const unsigned short greekKeysymsToUnicode[] = {
+ 0x0000, 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0x0000, 0x038c,
+ 0x038e, 0x03ab, 0x0000, 0x038f, 0x0000, 0x0000, 0x0385, 0x2015,
+ 0x0000, 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc,
+ 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397,
+ 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
+ 0x03a0, 0x03a1, 0x03a3, 0x0000, 0x03a4, 0x03a5, 0x03a6, 0x03a7,
+ 0x03a8, 0x03a9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7,
+ 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
+ 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7,
+ 0x03c8, 0x03c9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short technicalKeysymsToUnicode[] = {
+ 0x0000, 0x23B7, 0x250C, 0x2500, 0x2320, 0x2321, 0x2502, 0x23A1,
+ 0x23A3, 0x23A4, 0x23A6, 0x239B, 0x239D, 0x239E, 0x23A0, 0x23A8,
+ 0x23AC, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x2264, 0x2260, 0x2265, 0x222B,
+ 0x2234, 0x221D, 0x221E, 0x0000, 0x0000, 0x2207, 0x0000, 0x0000,
+ 0x223C, 0x2243, 0x0000, 0x0000, 0x0000, 0x21D4, 0x21D2, 0x2261,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x221A, 0x0000,
+ 0x0000, 0x0000, 0x2282, 0x2283, 0x2229, 0x222A, 0x2227, 0x2228,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2202,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0192, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x2190, 0x2191, 0x2192, 0x2193, 0x0000
+};
+
+static const unsigned short specialKeysymsToUnicode[] = {
+ 0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x0000, 0x0000,
+ 0x2424, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0x23BA,
+ 0x23BB, 0x2500, 0x23BC, 0x23BD, 0x251C, 0x2524, 0x2534, 0x252C,
+ 0x2502, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short publishingKeysymsToUnicode[] = {
+ 0x0000, 0x2003, 0x2002, 0x2004, 0x2005, 0x2007, 0x2008, 0x2009,
+ 0x200a, 0x2014, 0x2013, 0x0000, 0x0000, 0x0000, 0x2026, 0x2025,
+ 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a,
+ 0x2105, 0x0000, 0x0000, 0x2012, 0x2329, 0x0000, 0x232a, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, 0x0000,
+ 0x0000, 0x2122, 0x2613, 0x0000, 0x25c1, 0x25b7, 0x25cb, 0x25af,
+ 0x2018, 0x2019, 0x201c, 0x201d, 0x211e, 0x0000, 0x2032, 0x2033,
+ 0x0000, 0x271d, 0x0000, 0x25ac, 0x25c0, 0x25b6, 0x25cf, 0x25ae,
+ 0x25e6, 0x25ab, 0x25ad, 0x25b3, 0x25bd, 0x2606, 0x2022, 0x25aa,
+ 0x25b2, 0x25bc, 0x261c, 0x261e, 0x2663, 0x2666, 0x2665, 0x0000,
+ 0x2720, 0x2020, 0x2021, 0x2713, 0x2717, 0x266f, 0x266d, 0x2642,
+ 0x2640, 0x260e, 0x2315, 0x2117, 0x2038, 0x201a, 0x201e, 0x0000
+};
+
+static const unsigned short aplKeysymsToUnicode[] = {
+ 0x0000, 0x0000, 0x0000, 0x003c, 0x0000, 0x0000, 0x003e, 0x0000,
+ 0x2228, 0x2227, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x00af, 0x0000, 0x22a5, 0x2229, 0x230a, 0x0000, 0x005f, 0x0000,
+ 0x0000, 0x0000, 0x2218, 0x0000, 0x2395, 0x0000, 0x22a4, 0x25cb,
+ 0x0000, 0x0000, 0x0000, 0x2308, 0x0000, 0x0000, 0x222a, 0x0000,
+ 0x2283, 0x0000, 0x2282, 0x0000, 0x22a2, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x22a3, 0x0000, 0x0000, 0x0000
+};
+
+static const unsigned short koreanKeysymsToUnicode[] = {
+ 0x0000, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137,
+ 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f,
+ 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147,
+ 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f,
+ 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157,
+ 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f,
+ 0x3160, 0x3161, 0x3162, 0x3163, 0x11a8, 0x11a9, 0x11aa, 0x11ab,
+ 0x11ac, 0x11ad, 0x11ae, 0x11af, 0x11b0, 0x11b1, 0x11b2, 0x11b3,
+ 0x11b4, 0x11b5, 0x11b6, 0x11b7, 0x11b8, 0x11b9, 0x11ba, 0x11bb,
+ 0x11bc, 0x11bd, 0x11be, 0x11bf, 0x11c0, 0x11c1, 0x11c2, 0x316d,
+ 0x3171, 0x3178, 0x317f, 0x3181, 0x3184, 0x3186, 0x318d, 0x318e,
+ 0x11eb, 0x11f0, 0x11f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x20a9
+};
+
+
+static TQChar keysymToUnicode(unsigned char byte3, unsigned char byte4)
+{
+ if ( byte3 == 0x04 ) {
+ // katakana
+ if ( byte4 > 0xa0 && byte4 < 0xe0 )
+ return TQChar( katakanaKeysymsToUnicode[byte4 - 0xa0] );
+ else if ( byte4 == 0x7e )
+ return TQChar( 0x203e ); // Overline
+ } else if ( byte3 == 0x06 ) {
+ // russian, use lookup table
+ if ( byte4 > 0xa0 )
+ return TQChar( cyrillicKeysymsToUnicode[byte4 - 0xa0] );
+ } else if ( byte3 == 0x07 ) {
+ // greek
+ if ( byte4 > 0xa0 )
+ return TQChar( greekKeysymsToUnicode[byte4 - 0xa0] );
+ } else if ( byte3 == 0x08 ) {
+ // technical
+ if ( byte4 > 0xa0 )
+ return TQChar( technicalKeysymsToUnicode[byte4 - 0xa0] );
+ } else if ( byte3 == 0x09 ) {
+ // special
+ if ( byte4 >= 0xe0 )
+ return TQChar( specialKeysymsToUnicode[byte4 - 0xe0] );
+ } else if ( byte3 == 0x0a ) {
+ // publishing
+ if ( byte4 > 0xa0 )
+ return TQChar( publishingKeysymsToUnicode[byte4 - 0xa0] );
+ } else if ( byte3 == 0x0b ) {
+ // APL
+ if ( byte4 > 0xa0 )
+ return TQChar( aplKeysymsToUnicode[byte4 - 0xa0] );
+ } else if ( byte3 == 0x0e ) {
+ // Korean
+ if ( byte4 > 0xa0 )
+ return TQChar( koreanKeysymsToUnicode[byte4 - 0xa0] );
+ }
+ return TQChar(0x0);
+}
+#endif
+
+
+bool TQETWidget::translateKeyEventInternal( const XEvent *event, int& count,
+ TQString& text,
+ int& state,
+ char& ascii, int& code, TQEvent::Type &type, bool willRepeat )
+{
+ TQTextCodec *mapper = input_mapper;
+ // some XmbLookupString implementations don't return buffer overflow correctly,
+ // so we increase the input buffer to allow for long strings...
+ // 256 chars * 2 bytes + 1 null-term == 513 bytes
+ TQCString chars(513);
+ TQChar converted;
+ KeySym key = 0;
+
+ if ( !keyDict ) {
+ keyDict = new TQIntDict<void>( 13 );
+ keyDict->setAutoDelete( FALSE );
+ textDict = new TQIntDict<void>( 13 );
+ textDict->setAutoDelete( FALSE );
+ qAddPostRoutine( deleteKeyDicts );
+ }
+
+ TQWidget* tlw = tqtopLevelWidget();
+
+ XKeyEvent xkeyevent = event->xkey;
+
+ // save the modifier state, we will use the keystate uint later by passing
+ // it to translateButtonState
+ uint keystate = event->xkey.state;
+ // remove the modifiers where mode_switch exists... HPUX machines seem
+ // to have alt *AND* mode_switch both in Mod1Mask, which causes
+ // XLookupString to return things like '�' (aring) for ALT-A. This
+ // completely breaks modifiers. If we remove the modifier for Mode_switch,
+ // then things work correctly...
+ xkeyevent.state &= ~qt_mode_switch_remove_mask;
+
+ type = (event->type == XKeyPress)
+ ? TQEvent::KeyPress : TQEvent::KeyRelease;
+#if defined(TQT_NO_XIM)
+
+ count = XLookupString( &xkeyevent, chars.data(), chars.size(), &key, 0 );
+
+ if ( count == 1 )
+ ascii = chars[0];
+
+#else
+ // Implementation for X11R5 and newer, using XIM
+
+ int keycode = event->xkey.keycode;
+ Status status;
+
+ if ( type == TQEvent::KeyPress ) {
+ bool mb=FALSE;
+ if ( qt_xim ) {
+ TQTLWExtra* xd = tlw->topData();
+ TQInputContext *qic = (TQInputContext *) xd->xic;
+ if ( qic ) {
+ mb=TRUE;
+ count = qic->lookupString(&xkeyevent, chars, &key, &status);
+ }
+ }
+ if ( !mb ) {
+ count = XLookupString( &xkeyevent,
+ chars.data(), chars.size(), &key, 0 );
+ }
+ if ( count && !keycode ) {
+ keycode = composingKeycode;
+ composingKeycode = 0;
+ }
+ if ( key )
+ keyDict->tqreplace( keycode, (void*)key );
+ // all keysyms smaller than that are actally keys that can be mapped
+ // to tqunicode chars
+ if ( count == 0 && key < 0xff00 ) {
+ unsigned char byte3 = (unsigned char )(key >> 8);
+ int mib = -1;
+ switch( byte3 ) {
+ case 0: // Latin 1
+ case 1: // Latin 2
+ case 2: //latin 3
+ case 3: // latin4
+ mib = byte3 + 4; break;
+ case 5: // arabic
+ mib = 82; break;
+ case 12: // Hebrew
+ mib = 85; break;
+ case 13: // Thai
+ mib = 2259; break;
+ case 4: // kana
+ case 6: // cyrillic
+ case 7: // greek
+ case 8: // technical, no mapping here at the moment
+ case 9: // Special
+ case 10: // Publishing
+ case 11: // APL
+ case 14: // Korean, no mapping
+ mib = -1; // manual conversion
+ mapper = 0;
+ converted = keysymToUnicode( byte3, key & 0xff );
+ case 0x20:
+ // currency symbols
+ if ( key >= 0x20a0 && key <= 0x20ac ) {
+ mib = -1; // manual conversion
+ mapper = 0;
+ converted = (uint)key;
+ }
+ break;
+ default:
+ break;
+ }
+ if ( mib != -1 ) {
+ mapper = TQTextCodec::codecForMib( mib );
+ chars[0] = (unsigned char) (key & 0xff); // get only the fourth bit for conversion later
+ count++;
+ }
+ } else if ( key >= 0x1000000 && key <= 0x100ffff ) {
+ converted = (ushort) (key - 0x1000000);
+ mapper = 0;
+ }
+ if ( count < (int)chars.size()-1 )
+ chars[count] = '\0';
+ if ( count == 1 ) {
+ ascii = chars[0];
+ // +256 so we can store all eight-bit codes, including ascii 0,
+ // and independent of whether char is signed or not.
+ textDict->tqreplace( keycode, (void*)(long)(256+ascii) );
+ }
+ tlw = 0;
+ } else {
+ key = (int)(long)keyDict->tqfind( keycode );
+ if ( key )
+ if( !willRepeat ) // Take out key of dictionary only if this call.
+ keyDict->take( keycode );
+ long s = (long)textDict->tqfind( keycode );
+ if ( s ) {
+ textDict->take( keycode );
+ ascii = (char)(s-256);
+ }
+ }
+#endif // !TQT_NO_XIM
+
+ state = translateButtonState( keystate );
+
+ static int directionKeyEvent = 0;
+ if ( qt_use_rtl_extensions && type == TQEvent::KeyRelease ) {
+ if (directionKeyEvent == Key_Direction_R || directionKeyEvent == Key_Direction_L ) {
+ type = TQEvent::KeyPress;
+ code = directionKeyEvent;
+ chars[0] = 0;
+ directionKeyEvent = 0;
+ return TRUE;
+ } else {
+ directionKeyEvent = 0;
+ }
+ }
+
+ // Watch for keypresses and if its a key belonging to the Ctrl-Shift
+ // direction-changing accel, remember it.
+ // We keep track of those keys instead of using the event's state
+ // (to figure out whether the Ctrl modifier is held while Shift is pressed,
+ // or Shift is held while Ctrl is pressed) since the 'state' doesn't tell
+ // us whether the modifier held is Left or Right.
+ if (qt_use_rtl_extensions && type == TQEvent::KeyPress)
+ if (key == XK_Control_L || key == XK_Control_R || key == XK_Shift_L || key == XK_Shift_R) {
+ if (!directionKeyEvent)
+ directionKeyEvent = key;
+ } else {
+ // this can no longer be a direction-changing accel.
+ // if any other key was pressed.
+ directionKeyEvent = Key_Space;
+ }
+
+ // Commentary in X11/keysymdef says that X codes match ASCII, so it
+ // is safe to use the locale functions to process X codes in ISO8859-1.
+ //
+ // This is mainly for compatibility - applications should not use the
+ // TQt keycodes between 128 and 255, but should rather use the
+ // TQKeyEvent::text().
+ //
+ if ( key < 128 || (key < 256 && (!input_mapper || input_mapper->mibEnum()==4)) ) {
+ code = isprint((int)key) ? toupper((int)key) : 0; // upper-case key, if known
+ } else if ( key >= XK_F1 && key <= XK_F35 ) {
+ code = Key_F1 + ((int)key - XK_F1); // function keys
+ } else if ( key >= XK_KP_0 && key <= XK_KP_9) {
+ code = Key_0 + ((int)key - XK_KP_0); // numeric keypad keys
+ state |= Keypad;
+ } else {
+ int i = 0; // any other keys
+ while ( KeyTbl[i] ) {
+ if ( key == KeyTbl[i] ) {
+ code = (int)KeyTbl[i+1];
+ break;
+ }
+ i += 2;
+ }
+ switch ( key ) {
+ case XK_KP_Insert:
+ case XK_KP_Delete:
+ case XK_KP_Home:
+ case XK_KP_End:
+ case XK_KP_Left:
+ case XK_KP_Up:
+ case XK_KP_Right:
+ case XK_KP_Down:
+ case XK_KP_Prior:
+ case XK_KP_Next:
+ case XK_KP_Space:
+ case XK_KP_Tab:
+ case XK_KP_Enter:
+ case XK_KP_Equal:
+ case XK_KP_Multiply:
+ case XK_KP_Add:
+ case XK_KP_Separator:
+ case XK_KP_Subtract:
+ case XK_KP_Decimal:
+ case XK_KP_Divide:
+ state |= Keypad;
+ break;
+ default:
+ break;
+ }
+
+ if ( code == Key_Tab &&
+ (state & ShiftButton) == ShiftButton ) {
+ // map shift+tab to shift+backtab, TQAccel knows about it
+ // and will handle it.
+ code = Key_Backtab;
+ chars[0] = 0;
+ }
+
+ if ( qt_use_rtl_extensions && type == TQEvent::KeyPress ) {
+ if ( directionKeyEvent ) {
+ if ( key == XK_Shift_L && directionKeyEvent == XK_Control_L ||
+ key == XK_Control_L && directionKeyEvent == XK_Shift_L ) {
+ directionKeyEvent = Key_Direction_L;
+ } else if ( key == XK_Shift_R && directionKeyEvent == XK_Control_R ||
+ key == XK_Control_R && directionKeyEvent == XK_Shift_R ) {
+ directionKeyEvent = Key_Direction_R;
+ }
+ }
+ else if ( directionKeyEvent == Key_Direction_L || directionKeyEvent == Key_Direction_R ) {
+ directionKeyEvent = Key_Space; // invalid
+ }
+ }
+ }
+
+#if 0
+#ifndef TQ_EE
+ static int c = 0;
+ extern void qt_dialog_default_key();
+#define TQ_EE(x) c = (c == x || (!c && x == 0x1000) )? x+1 : 0
+ if ( tlw && state == '0' ) {
+ switch ( code ) {
+ case 0x4f: TQ_EE(Key_Backtab); break;
+ case 0x52: TQ_EE(Key_Tab); break;
+ case 0x54: TQ_EE(Key_Escape); break;
+ case 0x4c:
+ if (c == Key_Return )
+ qt_dialog_default_key();
+ else
+ TQ_EE(Key_Backspace);
+ break;
+ }
+ }
+#undef TQ_EE
+#endif
+#endif
+
+ // convert chars (8bit) to text (tqunicode).
+ if ( mapper )
+ text = mapper->toUnicode(chars,count);
+ else if ( !mapper && converted.tqunicode() != 0x0 )
+ text = converted;
+ else
+ text = chars;
+ return TRUE;
+}
+
+
+struct qt_auto_repeat_data
+{
+ // match the window and keycode with timestamp delta of 10ms
+ Window window;
+ KeyCode keycode;
+ Time timestamp;
+
+ // queue scanner state
+ bool release;
+ bool error;
+};
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static Bool qt_keypress_scanner(Display *, XEvent *event, XPointer arg)
+{
+ if (event->type != XKeyPress && event->type != XKeyRelease)
+ return FALSE;
+
+ qt_auto_repeat_data *d = (qt_auto_repeat_data *) arg;
+ if (d->error ||
+ event->xkey.window != d->window ||
+ event->xkey.keycode != d->keycode)
+ return FALSE;
+
+ if (event->type == XKeyPress) {
+ d->error = (! d->release || event->xkey.time - d->timestamp > 10);
+ return (! d->error);
+ }
+
+ // must be XKeyRelease event
+ if (d->release) {
+ // found a second release
+ d->error = TRUE;
+ return FALSE;
+ }
+
+ // found a single release
+ d->release = TRUE;
+ d->timestamp = event->xkey.time;
+
+ return FALSE;
+}
+
+static Bool qt_keyrelease_scanner(Display *, XEvent *event, XPointer arg)
+{
+ const qt_auto_repeat_data *d = (const qt_auto_repeat_data *) arg;
+ return (event->type == XKeyRelease &&
+ event->xkey.window == d->window &&
+ event->xkey.keycode == d->keycode);
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+bool TQETWidget::translateKeyEvent( const XEvent *event, bool grab )
+{
+ int code = -1;
+ int count = 0;
+ int state;
+ char ascii = 0;
+
+ if ( sm_blockUserInput ) // block user interaction during session management
+ return TRUE;
+
+ Display *dpy = x11Display();
+
+ if ( !isEnabled() )
+ return TRUE;
+
+ TQEvent::Type type;
+ bool autor = FALSE;
+ TQString text;
+
+ translateKeyEventInternal( event, count, text, state, ascii, code, type,
+ qt_mode_switch_remove_mask != 0 );
+
+ static uint curr_autorep = 0;
+ // was this the last auto-repeater?
+ qt_auto_repeat_data auto_repeat_data;
+ auto_repeat_data.window = event->xkey.window;
+ auto_repeat_data.keycode = event->xkey.keycode;
+ auto_repeat_data.timestamp = event->xkey.time;
+
+ if ( event->type == XKeyPress ) {
+ if ( curr_autorep == event->xkey.keycode ) {
+ autor = TRUE;
+ curr_autorep = 0;
+ }
+ } else {
+ // look ahead for auto-repeat
+ XEvent nextpress;
+
+ auto_repeat_data.release = TRUE;
+ auto_repeat_data.error = FALSE;
+ if (XCheckIfEvent(dpy, &nextpress, &qt_keypress_scanner,
+ (XPointer) &auto_repeat_data)) {
+ autor = TRUE;
+
+ // Put it back... we COULD send the event now and not need
+ // the static curr_autorep variable.
+ XPutBackEvent(dpy,&nextpress);
+ }
+ curr_autorep = autor ? event->xkey.keycode : 0;
+ }
+
+ // process accelerators before doing key compression
+ if ( type == TQEvent::KeyPress && !grab ) {
+ // send accel events if the keyboard is not grabbed
+ TQKeyEvent a( type, code, ascii, state, text, autor,
+ TQMAX( TQMAX(count,1), int(text.length())) );
+ if ( qt_tryAccelEvent( this, &a ) )
+ return TRUE;
+ }
+
+ long save = 0;
+ if ( qt_mode_switch_remove_mask != 0 ) {
+ save = qt_mode_switch_remove_mask;
+ qt_mode_switch_remove_mask = 0;
+
+ // translate the key event again, but this time apply any Mode_switch
+ // modifiers
+ translateKeyEventInternal( event, count, text, state, ascii, code, type );
+ }
+
+ // compress keys
+ if ( !text.isEmpty() && testWState(WState_CompressKeys) &&
+ // do not compress keys if the key event we just got above matches
+ // one of the key ranges used to compute stopCompression
+ ! ( ( code >= Key_Escape && code <= Key_SysReq ) ||
+ ( code >= Key_Home && code <= Key_Next ) ||
+ ( code >= Key_Super_L && code <= Key_Direction_R ) ||
+ ( ( code == 0 ) && ( ascii == '\n' ) ) ) ) {
+ // the widget wants key compression so it gets it
+ int codeIntern = -1;
+ int countIntern = 0;
+ int stateIntern;
+ char asciiIntern = 0;
+ XEvent evRelease;
+ XEvent evPress;
+
+ // sync the event queue, this makes key compress work better
+ XSync( dpy, FALSE );
+
+ for (;;) {
+ TQString textIntern;
+ if ( !XCheckTypedWindowEvent(dpy,event->xkey.window,
+ XKeyRelease,&evRelease) )
+ break;
+ if ( !XCheckTypedWindowEvent(dpy,event->xkey.window,
+ XKeyPress,&evPress) ) {
+ XPutBackEvent(dpy, &evRelease);
+ break;
+ }
+ TQEvent::Type t;
+ translateKeyEventInternal( &evPress, countIntern, textIntern,
+ stateIntern, asciiIntern, codeIntern, t );
+ // use stopCompression to stop key compression for the following
+ // key event ranges:
+ bool stopCompression =
+ // 1) misc keys
+ ( codeIntern >= Key_Escape && codeIntern <= Key_SysReq ) ||
+ // 2) cursor movement
+ ( codeIntern >= Key_Home && codeIntern <= Key_Next ) ||
+ // 3) extra keys
+ ( codeIntern >= Key_Super_L && codeIntern <= Key_Direction_R ) ||
+ // 4) something that a) doesn't translate to text or b) translates
+ // to newline text
+ ((codeIntern == 0) && (asciiIntern == '\n'));
+ if (stateIntern == state && !textIntern.isEmpty() && !stopCompression) {
+ text += textIntern;
+ count += countIntern;
+ } else {
+ XPutBackEvent(dpy, &evPress);
+ XPutBackEvent(dpy, &evRelease);
+ break;
+ }
+ }
+ }
+
+ if ( save != 0 )
+ qt_mode_switch_remove_mask = save;
+
+ // autorepeat compression makes sense for all widgets (Windows
+ // does it automatically .... )
+ if ( event->type == XKeyPress && text.length() <= 1 ) {
+ XEvent dummy;
+
+ for (;;) {
+ auto_repeat_data.release = FALSE;
+ auto_repeat_data.error = FALSE;
+ if (! XCheckIfEvent(dpy, &dummy, &qt_keypress_scanner,
+ (XPointer) &auto_repeat_data))
+ break;
+ if (! XCheckIfEvent(dpy, &dummy, &qt_keyrelease_scanner,
+ (XPointer) &auto_repeat_data))
+ break;
+
+ count++;
+ if (!text.isEmpty())
+ text += text[0];
+ }
+ }
+
+ if (code == 0 && ascii == '\n') {
+ code = Key_Return;
+ ascii = '\r';
+ text = "\r";
+ }
+
+ // try the menukey first
+ if ( type == TQEvent::KeyPress && code == TQt::Key_Menu ) {
+ TQContextMenuEvent e( TQContextMenuEvent::Keyboard, TQPoint( 5, 5 ), mapToGlobal( TQPoint( 5, 5 ) ), 0 );
+ TQApplication::sendSpontaneousEvent( this, &e );
+ if( e.isAccepted() )
+ return TRUE;
+ }
+
+ TQKeyEvent e( type, code, ascii, state, text, autor,
+ TQMAX(TQMAX(count,1), int(text.length())) );
+ return TQApplication::sendSpontaneousEvent( this, &e );
+}
+
+
+//
+// Paint event translation
+//
+// When receiving many expose events, we compress them (union of all expose
+// rectangles) into one event which is sent to the widget.
+
+struct PaintEventInfo {
+ Window window;
+};
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static Bool isPaintOrScrollDoneEvent( Display *, XEvent *ev, XPointer a )
+{
+ PaintEventInfo *info = (PaintEventInfo *)a;
+ if ( ev->type == Expose || ev->type == GraphicsExpose
+ || ev->type == ClientMessage
+ && ev->xclient.message_type == qt_qt_scrolldone )
+ {
+ if ( ev->xexpose.window == info->window )
+ return True;
+ }
+ return False;
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+// declared above: static TQPtrList<TQScrollInProgress> *sip_list = 0;
+
+void qt_insert_sip( TQWidget* scrolled_widget, int dx, int dy )
+{
+ if ( !sip_list ) {
+ sip_list = new TQPtrList<TQScrollInProgress>;
+ sip_list->setAutoDelete( TRUE );
+ }
+
+ TQScrollInProgress* sip = new TQScrollInProgress( scrolled_widget, dx, dy );
+ sip_list->append( sip );
+
+ XClientMessageEvent client_message;
+ client_message.type = ClientMessage;
+ client_message.window = scrolled_widget->winId();
+ client_message.format = 32;
+ client_message.message_type = qt_qt_scrolldone;
+ client_message.data.l[0] = sip->id;
+
+ XSendEvent( appDpy, scrolled_widget->winId(), False, NoEventMask,
+ (XEvent*)&client_message );
+}
+
+int qt_sip_count( TQWidget* scrolled_widget )
+{
+ if ( !sip_list )
+ return 0;
+
+ int sips=0;
+
+ for (TQScrollInProgress* sip = sip_list->first();
+ sip; sip=sip_list->next())
+ {
+ if ( sip->scrolled_widget == scrolled_widget )
+ sips++;
+ }
+
+ return sips;
+}
+
+static
+bool translateBySips( TQWidget* that, TQRect& paintRect )
+{
+ if ( sip_list ) {
+ int dx=0, dy=0;
+ int sips=0;
+ for (TQScrollInProgress* sip = sip_list->first();
+ sip; sip=sip_list->next())
+ {
+ if ( sip->scrolled_widget == that ) {
+ if ( sips ) {
+ dx += sip->dx;
+ dy += sip->dy;
+ }
+ sips++;
+ }
+ }
+ if ( sips > 1 ) {
+ paintRect.moveBy( dx, dy );
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool TQETWidget::translatePaintEvent( const XEvent *event )
+{
+ setWState( WState_Exposed );
+ TQRect paintRect( event->xexpose.x, event->xexpose.y,
+ event->xexpose.width, event->xexpose.height );
+ bool merging_okay = !testWFlags(WPaintClever);
+ XEvent xevent;
+ PaintEventInfo info;
+ info.window = winId();
+ bool should_clip = translateBySips( this, paintRect );
+
+ TQRegion paintRegion( paintRect );
+
+ if ( merging_okay ) {
+ // WARNING: this is O(number_of_events * number_of_matching_events)
+ while ( XCheckIfEvent(x11Display(),&xevent,isPaintOrScrollDoneEvent,
+ (XPointer)&info) &&
+ !qt_x11EventFilter(&xevent) &&
+ !x11Event( &xevent ) ) // send event through filter
+ {
+ if ( xevent.type == Expose || xevent.type == GraphicsExpose ) {
+ TQRect exposure(xevent.xexpose.x,
+ xevent.xexpose.y,
+ xevent.xexpose.width,
+ xevent.xexpose.height);
+ if ( translateBySips( this, exposure ) )
+ should_clip = TRUE;
+ paintRegion = paintRegion.unite( exposure );
+ } else {
+ translateScrollDoneEvent( &xevent );
+ }
+ }
+ }
+
+ if ( should_clip ) {
+ paintRegion = paintRegion.intersect( rect() );
+ if ( paintRegion.isEmpty() )
+ return TRUE;
+ }
+
+ TQPaintEvent e( paintRegion );
+ setWState( WState_InPaintEvent );
+ if ( !isTopLevel() && backgroundOrigin() != WidgetOrigin )
+ erase( paintRegion );
+ qt_set_paintevent_clipping( this, paintRegion );
+ TQApplication::sendSpontaneousEvent( this, &e );
+ qt_clear_paintevent_clipping();
+ clearWState( WState_InPaintEvent );
+ return TRUE;
+}
+
+//
+// Scroll-done event translation.
+//
+
+bool TQETWidget::translateScrollDoneEvent( const XEvent *event )
+{
+ if ( !sip_list ) return FALSE;
+
+ long id = event->xclient.data.l[0];
+
+ // Remove any scroll-in-progress record for the given id.
+ for (TQScrollInProgress* sip = sip_list->first(); sip; sip=sip_list->next()) {
+ if ( sip->id == id ) {
+ sip_list->remove( sip_list->current() );
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+//
+// ConfigureNotify (window move and resize) event translation
+
+bool TQETWidget::translateConfigEvent( const XEvent *event )
+{
+ // config pending is only set on resize, see qwidget_x11.cpp, internalSetGeometry()
+ bool was_resize = testWState( WState_ConfigPending );
+
+ clearWState(WState_ConfigPending);
+
+ if ( isTopLevel() ) {
+ TQPoint newCPos( tqgeometry().topLeft() );
+ TQSize newSize( event->xconfigure.width, event->xconfigure.height );
+
+ bool trust = (topData()->parentWinId == None ||
+ topData()->parentWinId == TQPaintDevice::x11AppRootWindow());
+
+ if (event->xconfigure.send_event || trust ) {
+ // if a ConfigureNotify comes from a real sendevent request, we can
+ // trust its values.
+ newCPos.rx() = event->xconfigure.x + event->xconfigure.border_width;
+ newCPos.ry() = event->xconfigure.y + event->xconfigure.border_width;
+ }
+
+ if ( isVisible() )
+ TQApplication::syncX();
+
+ if (! extra || extra->compress_events) {
+ // ConfigureNotify compression for faster opaque resizing
+ XEvent otherEvent;
+ while ( XCheckTypedWindowEvent( x11Display(), winId(), ConfigureNotify,
+ &otherEvent ) ) {
+ if ( qt_x11EventFilter( &otherEvent ) )
+ continue;
+
+ if (x11Event( &otherEvent ) )
+ continue;
+
+ if ( otherEvent.xconfigure.event != otherEvent.xconfigure.window )
+ continue;
+
+ newSize.setWidth( otherEvent.xconfigure.width );
+ newSize.setHeight( otherEvent.xconfigure.height );
+
+ if ( otherEvent.xconfigure.send_event || trust ) {
+ newCPos.rx() = otherEvent.xconfigure.x +
+ otherEvent.xconfigure.border_width;
+ newCPos.ry() = otherEvent.xconfigure.y +
+ otherEvent.xconfigure.border_width;
+ }
+ }
+ }
+
+ TQRect cr ( tqgeometry() );
+ if ( newSize != cr.size() ) { // size changed
+ was_resize = TRUE;
+ TQSize oldSize = size();
+ cr.setSize( newSize );
+ crect = cr;
+
+ if ( isVisible() ) {
+ TQResizeEvent e( newSize, oldSize );
+ TQApplication::sendSpontaneousEvent( this, &e );
+ } else {
+ TQResizeEvent * e = new TQResizeEvent( newSize, oldSize );
+ TQApplication::postEvent( this, e );
+ }
+ }
+
+ if ( newCPos != cr.topLeft() ) { // compare with cpos (exluding frame)
+ TQPoint oldPos = tqgeometry().topLeft();
+ cr.moveTopLeft( newCPos );
+ crect = cr;
+ if ( isVisible() ) {
+ TQMoveEvent e( newCPos, oldPos ); // pos (including frame), not cpos
+ TQApplication::sendSpontaneousEvent( this, &e );
+ } else {
+ TQMoveEvent * e = new TQMoveEvent( newCPos, oldPos );
+ TQApplication::postEvent( this, e );
+ }
+ }
+ } else {
+ XEvent xevent;
+ while ( XCheckTypedWindowEvent(x11Display(),winId(), ConfigureNotify,&xevent) &&
+ !qt_x11EventFilter(&xevent) &&
+ !x11Event( &xevent ) ) // send event through filter
+ ;
+ }
+
+ bool transbg = backgroundOrigin() != WidgetOrigin;
+ // we ignore NorthWestGravity at the moment for reversed tqlayout
+ if ( transbg ||
+ (!testWFlags( WStaticContents ) &&
+ testWState( WState_Exposed ) && was_resize ) ||
+ TQApplication::reverseLayout() ) {
+ // remove unnecessary paint events from the queue
+ XEvent xevent;
+ while ( XCheckTypedWindowEvent( x11Display(), winId(), Expose, &xevent ) &&
+ ! qt_x11EventFilter( &xevent ) &&
+ ! x11Event( &xevent ) ) // send event through filter
+ ;
+ tqrepaint( !testWFlags(WResizeNoErase) || transbg );
+ }
+
+ return TRUE;
+}
+
+
+//
+// Close window event translation.
+//
+bool TQETWidget::translateCloseEvent( const XEvent * )
+{
+ return close(FALSE);
+}
+
+
+/*!
+ Sets the text cursor's flash (blink) time to \a msecs
+ milliseconds. The flash time is the time required to display,
+ invert and restore the caret display. Usually the text cursor is
+ displayed for \a msecs/2 milliseconds, then hidden for \a msecs/2
+ milliseconds, but this may vary.
+
+ Note that on Microsoft Windows, calling this function sets the
+ cursor flash time for all windows.
+
+ \sa cursorFlashTime()
+*/
+void TQApplication::setCursorFlashTime( int msecs )
+{
+ cursor_flash_time = msecs;
+}
+
+
+/*!
+ Returns the text cursor's flash (blink) time in milliseconds. The
+ flash time is the time required to display, invert and restore the
+ caret display.
+
+ The default value on X11 is 1000 milliseconds. On Windows, the
+ control panel value is used.
+
+ Widgets should not cache this value since it may be changed at any
+ time by the user changing the global desktop settings.
+
+ \sa setCursorFlashTime()
+*/
+int TQApplication::cursorFlashTime()
+{
+ return cursor_flash_time;
+}
+
+/*!
+ Sets the time limit that distinguishes a double click from two
+ consecutive mouse clicks to \a ms milliseconds.
+
+ Note that on Microsoft Windows, calling this function sets the
+ double click interval for all windows.
+
+ \sa doubleClickInterval()
+*/
+
+void TQApplication::setDoubleClickInterval( int ms )
+{
+ mouse_double_click_time = ms;
+}
+
+
+/*!
+ Returns the maximum duration for a double click.
+
+ The default value on X11 is 400 milliseconds. On Windows, the
+ control panel value is used.
+
+ \sa setDoubleClickInterval()
+*/
+
+int TQApplication::doubleClickInterval()
+{
+ return mouse_double_click_time;
+}
+
+
+/*!
+ Sets the number of lines to scroll when the mouse wheel is rotated
+ to \a n.
+
+ If this number exceeds the number of visible lines in a certain
+ widget, the widget should interpret the scroll operation as a
+ single page up / page down operation instead.
+
+ \sa wheelScrollLines()
+*/
+void TQApplication::setWheelScrollLines( int n )
+{
+ wheel_scroll_lines = n;
+}
+
+/*!
+ Returns the number of lines to scroll when the mouse wheel is
+ rotated.
+
+ \sa setWheelScrollLines()
+*/
+int TQApplication::wheelScrollLines()
+{
+ return wheel_scroll_lines;
+}
+
+/*!
+ Enables the UI effect \a effect if \a enable is TRUE, otherwise
+ the effect will not be used.
+
+ Note: All effects are disabled on screens running at less than
+ 16-bit color depth.
+
+ \sa isEffectEnabled(), TQt::UIEffect, setDesktopSettingsAware()
+*/
+void TQApplication::setEffectEnabled( TQt::UIEffect effect, bool enable )
+{
+ switch (effect) {
+ case UI_AnimateMenu:
+ if ( enable ) fade_menu = FALSE;
+ animate_menu = enable;
+ break;
+ case UI_FadeMenu:
+ if ( enable )
+ animate_menu = TRUE;
+ fade_menu = enable;
+ break;
+ case UI_AnimateCombo:
+ animate_combo = enable;
+ break;
+ case UI_AnimateTooltip:
+ if ( enable ) fade_tooltip = FALSE;
+ animate_tooltip = enable;
+ break;
+ case UI_FadeTooltip:
+ if ( enable )
+ animate_tooltip = TRUE;
+ fade_tooltip = enable;
+ break;
+ case UI_AnimateToolBox:
+ animate_toolbox = enable;
+ break;
+ default:
+ animate_ui = enable;
+ break;
+ }
+}
+
+/*!
+ Returns TRUE if \a effect is enabled; otherwise returns FALSE.
+
+ By default, TQt will try to use the desktop settings. Call
+ setDesktopSettingsAware(FALSE) to prevent this.
+
+ Note: All effects are disabled on screens running at less than
+ 16-bit color depth.
+
+ \sa setEffectEnabled(), TQt::UIEffect
+*/
+bool TQApplication::isEffectEnabled( TQt::UIEffect effect )
+{
+ if ( TQColor::numBitPlanes() < 16 || !animate_ui )
+ return FALSE;
+
+ switch( effect ) {
+ case UI_AnimateMenu:
+ return animate_menu;
+ case UI_FadeMenu:
+ return fade_menu;
+ case UI_AnimateCombo:
+ return animate_combo;
+ case UI_AnimateTooltip:
+ return animate_tooltip;
+ case UI_FadeTooltip:
+ return fade_tooltip;
+ case UI_AnimateToolBox:
+ return animate_toolbox;
+ default:
+ return animate_ui;
+ }
+}
+
+/*****************************************************************************
+ Session management support
+ *****************************************************************************/
+
+#ifndef TQT_NO_SM_SUPPORT
+
+#include <X11/SM/SMlib.h>
+
+class TQSessionManagerData
+{
+public:
+ TQSessionManagerData( TQSessionManager* mgr, TQString& id, TQString& key )
+ : sm( mgr ), sessionId( id ), sessionKey( key ) {}
+ TQSessionManager* sm;
+ TQStringList restartCommand;
+ TQStringList discardCommand;
+ TQString& sessionId;
+ TQString& sessionKey;
+ TQSessionManager::RestartHint restartHint;
+};
+
+class TQSmSocketReceiver : public TQObject
+{
+ TQ_OBJECT
+public:
+ TQSmSocketReceiver( int socket )
+ : TQObject(0,0)
+ {
+ TQSocketNotifier* sn = new TQSocketNotifier( socket, TQSocketNotifier::Read, this );
+ connect( sn, TQT_SIGNAL( activated(int) ), this, TQT_SLOT( socketActivated(int) ) );
+ }
+
+public Q_SLOTS:
+ void socketActivated(int);
+};
+
+
+static SmcConn smcConnection = 0;
+static bool sm_interactionActive;
+static bool sm_smActive;
+static int sm_interactStyle;
+static int sm_saveType;
+static bool sm_cancel;
+// static bool sm_waitingForPhase2; ### never used?!?
+static bool sm_waitingForInteraction;
+static bool sm_isshutdown;
+// static bool sm_shouldbefast; ### never used?!?
+static bool sm_phase2;
+static bool sm_in_phase2;
+
+static TQSmSocketReceiver* sm_receiver = 0;
+
+static void resetSmState();
+static void sm_setProperty( const char* name, const char* type,
+ int num_vals, SmPropValue* vals);
+static void sm_saveYourselfCallback( SmcConn smcConn, SmPointer clientData,
+ int saveType, Bool shutdown , int interactStyle, Bool fast);
+static void sm_saveYourselfPhase2Callback( SmcConn smcConn, SmPointer clientData ) ;
+static void sm_dieCallback( SmcConn smcConn, SmPointer clientData ) ;
+static void sm_shutdownCancelledCallback( SmcConn smcConn, SmPointer clientData );
+static void sm_saveCompleteCallback( SmcConn smcConn, SmPointer clientData );
+static void sm_interactCallback( SmcConn smcConn, SmPointer clientData );
+static void sm_performSaveYourself( TQSessionManagerData* );
+
+static void resetSmState()
+{
+// sm_waitingForPhase2 = FALSE; ### never used?!?
+ sm_waitingForInteraction = FALSE;
+ sm_interactionActive = FALSE;
+ sm_interactStyle = SmInteractStyleNone;
+ sm_smActive = FALSE;
+ sm_blockUserInput = FALSE;
+ sm_isshutdown = FALSE;
+// sm_shouldbefast = FALSE; ### never used?!?
+ sm_phase2 = FALSE;
+ sm_in_phase2 = FALSE;
+}
+
+
+// theoretically it's possible to set several properties at once. For
+// simplicity, however, we do just one property at a time
+static void sm_setProperty( const char* name, const char* type,
+ int num_vals, SmPropValue* vals)
+{
+ if (num_vals ) {
+ SmProp prop;
+ prop.name = (char*)name;
+ prop.type = (char*)type;
+ prop.num_vals = num_vals;
+ prop.vals = vals;
+
+ SmProp* props[1];
+ props[0] = &prop;
+ SmcSetProperties( smcConnection, 1, props );
+ }
+ else {
+ char* names[1];
+ names[0] = (char*) name;
+ SmcDeleteProperties( smcConnection, 1, names );
+ }
+}
+
+static void sm_setProperty( const TQString& name, const TQString& value)
+{
+ SmPropValue prop;
+ prop.length = value.length();
+ prop.value = (SmPointer) value.latin1();
+ sm_setProperty( name.latin1(), SmARRAY8, 1, &prop );
+}
+
+static void sm_setProperty( const TQString& name, const TQStringList& value)
+{
+ SmPropValue *prop = new SmPropValue[ value.count() ];
+ int count = 0;
+ for ( TQStringList::ConstIterator it = value.begin(); it != value.end(); ++it ) {
+ prop[ count ].length = (*it).length();
+ prop[ count ].value = (char*)(*it).latin1();
+ ++count;
+ }
+ sm_setProperty( name.latin1(), SmLISTofARRAY8, count, prop );
+ delete [] prop;
+}
+
+
+// workaround for broken libsm, see below
+struct TQT_smcConn {
+ unsigned int save_yourself_in_progress : 1;
+ unsigned int shutdown_in_progress : 1;
+};
+
+static void sm_saveYourselfCallback( SmcConn smcConn, SmPointer clientData,
+ int saveType, Bool shutdown , int interactStyle, Bool /*fast*/)
+{
+ if (smcConn != smcConnection )
+ return;
+ sm_cancel = FALSE;
+ sm_smActive = TRUE;
+ sm_isshutdown = shutdown;
+ sm_saveType = saveType;
+ sm_interactStyle = interactStyle;
+// sm_shouldbefast = fast; ### never used?!?
+
+ // ugly workaround for broken libSM. libSM should do that _before_
+ // actually invoking the callback in sm_process.c
+ ( (TQT_smcConn*)smcConn )->save_yourself_in_progress = TRUE;
+ if ( sm_isshutdown )
+ ( (TQT_smcConn*)smcConn )->shutdown_in_progress = TRUE;
+
+ sm_performSaveYourself( (TQSessionManagerData*) clientData );
+ if ( !sm_isshutdown ) // we cannot expect a confirmation message in that case
+ resetSmState();
+}
+
+static void sm_performSaveYourself( TQSessionManagerData* smd )
+{
+ if ( sm_isshutdown )
+ sm_blockUserInput = TRUE;
+
+ TQSessionManager* sm = smd->sm;
+
+ // generate a new session key
+ timeval tv;
+ gettimeofday( &tv, 0 );
+ smd->sessionKey = TQString::number( tv.tv_sec ) + "_" + TQString::number(tv.tv_usec);
+
+ // tell the session manager about our program in best POSIX style
+ sm_setProperty( SmProgram, TQString( tqApp->argv()[0] ) );
+ // tell the session manager about our user as well.
+ struct passwd* entry = getpwuid( geteuid() );
+ if ( entry )
+ sm_setProperty( SmUserID, TQString::tqfromLatin1( entry->pw_name ) );
+
+ // generate a restart and discard command that makes sense
+ TQStringList restart;
+ restart << tqApp->argv()[0] << "-session" << smd->sessionId + "_" + smd->sessionKey;
+ if (qstricmp(tqAppName(), tqAppClass()) != 0)
+ restart << "-name" << tqAppName();
+ sm->setRestartCommand( restart );
+ TQStringList discard;
+ sm->setDiscardCommand( discard );
+
+ switch ( sm_saveType ) {
+ case SmSaveBoth:
+ tqApp->commitData( *sm );
+ if ( sm_isshutdown && sm_cancel)
+ break; // we cancelled the shutdown, no need to save state
+ // fall through
+ case SmSaveLocal:
+ tqApp->saveState( *sm );
+ break;
+ case SmSaveGlobal:
+ tqApp->commitData( *sm );
+ break;
+ default:
+ break;
+ }
+
+ if ( sm_phase2 && !sm_in_phase2 ) {
+ SmcRequestSaveYourselfPhase2( smcConnection, sm_saveYourselfPhase2Callback, (SmPointer*) smd );
+ sm_blockUserInput = FALSE;
+ }
+ else {
+ // close eventual interaction monitors and cancel the
+ // shutdown, if required. Note that we can only cancel when
+ // performing a shutdown, it does not work for checkpoints
+ if ( sm_interactionActive ) {
+ SmcInteractDone( smcConnection, sm_isshutdown && sm_cancel);
+ sm_interactionActive = FALSE;
+ }
+ else if ( sm_cancel && sm_isshutdown ) {
+ if ( sm->allowsErrorInteraction() ) {
+ SmcInteractDone( smcConnection, True );
+ sm_interactionActive = FALSE;
+ }
+ }
+
+ // set restart and discard command in session manager
+ sm_setProperty( SmRestartCommand, sm->restartCommand() );
+ sm_setProperty( SmDiscardCommand, sm->discardCommand() );
+
+ // set the restart hint
+ SmPropValue prop;
+ prop.length = sizeof( int );
+ int value = sm->restartHint();
+ prop.value = (SmPointer) &value;
+ sm_setProperty( SmRestartStyleHint, SmCARD8, 1, &prop );
+
+ // we are done
+ SmcSaveYourselfDone( smcConnection, !sm_cancel );
+ }
+}
+
+static void sm_dieCallback( SmcConn smcConn, SmPointer /* clientData */)
+{
+ if (smcConn != smcConnection )
+ return;
+ resetSmState();
+ TQEvent quitEvent(TQEvent::Quit);
+ TQApplication::sendEvent(tqApp, &quitEvent);
+}
+
+static void sm_shutdownCancelledCallback( SmcConn smcConn, SmPointer /* clientData */)
+{
+ if (smcConn != smcConnection )
+ return;
+ if ( sm_waitingForInteraction )
+ tqApp->exit_loop();
+ resetSmState();
+}
+
+static void sm_saveCompleteCallback( SmcConn smcConn, SmPointer /*clientData */)
+{
+ if (smcConn != smcConnection )
+ return;
+ resetSmState();
+}
+
+static void sm_interactCallback( SmcConn smcConn, SmPointer /* clientData */ )
+{
+ if (smcConn != smcConnection )
+ return;
+ if ( sm_waitingForInteraction )
+ tqApp->exit_loop();
+}
+
+static void sm_saveYourselfPhase2Callback( SmcConn smcConn, SmPointer clientData )
+{
+ if (smcConn != smcConnection )
+ return;
+ sm_in_phase2 = TRUE;
+ sm_performSaveYourself( (TQSessionManagerData*) clientData );
+}
+
+
+void TQSmSocketReceiver::socketActivated(int)
+{
+ IceProcessMessages( SmcGetIceConnection( smcConnection ), 0, 0);
+}
+
+
+#undef Bool
+#include "tqapplication_x11.tqmoc"
+
+TQSessionManager::TQSessionManager( TQApplication * app, TQString &id, TQString& key )
+ : TQObject( app, "session manager" )
+{
+ d = new TQSessionManagerData( this, id, key );
+ d->restartHint = RestartIfRunning;
+
+ resetSmState();
+ char cerror[256];
+ char* myId = 0;
+ char* prevId = (char*)id.latin1(); // we know what we are doing
+
+ SmcCallbacks cb;
+ cb.save_yourself.callback = sm_saveYourselfCallback;
+ cb.save_yourself.client_data = (SmPointer) d;
+ cb.die.callback = sm_dieCallback;
+ cb.die.client_data = (SmPointer) d;
+ cb.save_complete.callback = sm_saveCompleteCallback;
+ cb.save_complete.client_data = (SmPointer) d;
+ cb.shutdown_cancelled.callback = sm_shutdownCancelledCallback;
+ cb.shutdown_cancelled.client_data = (SmPointer) d;
+
+ // avoid showing a warning message below
+ const char* session_manager = getenv("SESSION_MANAGER");
+ if ( !session_manager || !session_manager[0] )
+ return;
+
+ smcConnection = SmcOpenConnection( 0, 0, 1, 0,
+ SmcSaveYourselfProcMask |
+ SmcDieProcMask |
+ SmcSaveCompleteProcMask |
+ SmcShutdownCancelledProcMask,
+ &cb,
+ prevId,
+ &myId,
+ 256, cerror );
+
+ id = TQString::tqfromLatin1( myId );
+ ::free( myId ); // it was allocated by C
+
+ TQString error = cerror;
+ if (!smcConnection ) {
+ qWarning("Session management error: %s", error.latin1() );
+ }
+ else {
+ sm_receiver = new TQSmSocketReceiver( IceConnectionNumber( SmcGetIceConnection( smcConnection ) ) );
+ }
+}
+
+TQSessionManager::~TQSessionManager()
+{
+ if ( smcConnection )
+ SmcCloseConnection( smcConnection, 0, 0 );
+ smcConnection = 0;
+ delete sm_receiver;
+ delete d;
+}
+
+TQString TQSessionManager::sessionId() const
+{
+ return d->sessionId;
+}
+
+TQString TQSessionManager::sessionKey() const
+{
+ return d->sessionKey;
+}
+
+
+void* TQSessionManager::handle() const
+{
+ return (void*) smcConnection;
+}
+
+
+bool TQSessionManager::allowsInteraction()
+{
+ if ( sm_interactionActive )
+ return TRUE;
+
+ if ( sm_waitingForInteraction )
+ return FALSE;
+
+ if ( sm_interactStyle == SmInteractStyleAny ) {
+ sm_waitingForInteraction = SmcInteractRequest( smcConnection, SmDialogNormal,
+ sm_interactCallback, (SmPointer*) this );
+ }
+ if ( sm_waitingForInteraction ) {
+ tqApp->enter_loop();
+ sm_waitingForInteraction = FALSE;
+ if ( sm_smActive ) { // not cancelled
+ sm_interactionActive = TRUE;
+ sm_blockUserInput = FALSE;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+bool TQSessionManager::allowsErrorInteraction()
+{
+ if ( sm_interactionActive )
+ return TRUE;
+
+ if ( sm_waitingForInteraction )
+ return FALSE;
+
+ if ( sm_interactStyle == SmInteractStyleAny || sm_interactStyle == SmInteractStyleErrors ) {
+ sm_waitingForInteraction = SmcInteractRequest( smcConnection, SmDialogError,
+ sm_interactCallback, (SmPointer*) this );
+ }
+ if ( sm_waitingForInteraction ) {
+ tqApp->enter_loop();
+ sm_waitingForInteraction = FALSE;
+ if ( sm_smActive ) { // not cancelled
+ sm_interactionActive = TRUE;
+ sm_blockUserInput = FALSE;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void TQSessionManager::release()
+{
+ if ( sm_interactionActive ) {
+ SmcInteractDone( smcConnection, False );
+ sm_interactionActive = FALSE;
+ if ( sm_smActive && sm_isshutdown )
+ sm_blockUserInput = TRUE;
+ }
+}
+
+void TQSessionManager::cancel()
+{
+ sm_cancel = TRUE;
+}
+
+void TQSessionManager::setRestartHint( TQSessionManager::RestartHint hint)
+{
+ d->restartHint = hint;
+}
+
+TQSessionManager::RestartHint TQSessionManager::restartHint() const
+{
+ return d->restartHint;
+}
+
+void TQSessionManager::setRestartCommand( const TQStringList& command)
+{
+ d->restartCommand = command;
+}
+
+TQStringList TQSessionManager::restartCommand() const
+{
+ return d->restartCommand;
+}
+
+void TQSessionManager::setDiscardCommand( const TQStringList& command)
+{
+ d->discardCommand = command;
+}
+
+TQStringList TQSessionManager::discardCommand() const
+{
+ return d->discardCommand;
+}
+
+void TQSessionManager::setManagerProperty( const TQString& name, const TQString& value)
+{
+ SmPropValue prop;
+ prop.length = value.length();
+ prop.value = (SmPointer) value.utf8().data();
+ sm_setProperty( name.latin1(), SmARRAY8, 1, &prop );
+}
+
+void TQSessionManager::setManagerProperty( const TQString& name, const TQStringList& value)
+{
+ SmPropValue *prop = new SmPropValue[ value.count() ];
+ int count = 0;
+ for ( TQStringList::ConstIterator it = value.begin(); it != value.end(); ++it ) {
+ prop[ count ].length = (*it).length();
+ prop[ count ].value = (char*)(*it).utf8().data();
+ ++count;
+ }
+ sm_setProperty( name.latin1(), SmLISTofARRAY8, count, prop );
+ delete [] prop;
+}
+
+bool TQSessionManager::isPhase2() const
+{
+ return sm_in_phase2;
+}
+
+void TQSessionManager::requestPhase2()
+{
+ sm_phase2 = TRUE;
+}
+
+
+#endif // TQT_NO_SM_SUPPORT
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqasyncimageio.cpp b/tqtinterface/qt4/src/kernel/tqasyncimageio.cpp
new file mode 100644
index 0000000..508002f
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqasyncimageio.cpp
@@ -0,0 +1,1316 @@
+/****************************************************************************
+**
+** Implementation of asynchronous image/movie loading classes
+**
+** Created : 970617
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqasyncimageio.h"
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+
+#include "tqptrlist.h"
+#include "tqgif.h"
+#include <stdlib.h>
+
+// #ifdef USE_QT4
+#if 0
+// [FIXME]
+void qt_init_image_handlers() { printf("[WARNING] void qt_init_image_handlers() unimplemented\n\r"); }
+void qt_init_image_plugins() { printf("[WARNING] void qt_init_image_plugins() unimplemented\n\r"); }
+#else // USE_QT4
+extern void qt_init_image_handlers();
+extern void qt_init_image_plugins();
+#endif // USE_QT4
+
+#define TQ_TRANSPARENT 0x00ffffff
+
+/*!
+ \class TQImageConsumer tqasyncimageio.h
+ \brief The TQImageConsumer class is an abstraction used by TQImageDecoder.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup multimedia
+
+ The TQMovie class, or TQLabel::setMovie(), are easy to use and for
+ most situations do what you want with regards animated images.
+
+ A TQImageConsumer consumes information about changes to the TQImage
+ maintained by a TQImageDecoder. Think of the TQImage as the model or
+ source of the image data, with the TQImageConsumer as a view of
+ that data and the TQImageDecoder being the controller that
+ orchestrates the relationship between the model and the view.
+
+ You'd use the TQImageConsumer class, for example, if you were
+ implementing a web browser with your own image loaders.
+
+ \sa TQImageDecoder
+*/
+
+/*!
+ \fn void TQImageConsumer::changed(const TQRect&)
+
+ Called when the given area of the image has changed.
+*/
+
+/*!
+ \fn void TQImageConsumer::end()
+
+ Called when all the data from all the frames has been decoded and
+ revealed as changed().
+*/
+
+/*!
+ \fn void TQImageConsumer::frameDone()
+
+ One of the two frameDone() functions will be called when a frame
+ of an animated image has ended and been revealed as changed().
+
+ When this function is called, the current image should be
+ displayed.
+
+ The decoder will not make any further changes to the image until
+ the next call to TQImageFormat::decode().
+*/
+
+/*!
+ \overload void TQImageConsumer::frameDone( const TQPoint& offset, const TQRect& rect )
+
+ One of the two frameDone() functions will be called when a frame
+ of an animated image has ended and been revealed as changed().
+
+ When this function is called, the area \a rect in the current
+ image should be moved by \a offset and displayed.
+
+ The decoder will not make any further changes to the image until
+ the next call to TQImageFormat::decode().
+*/
+
+/*!
+ \fn void TQImageConsumer::setLooping(int n)
+
+ Called to indicate that the sequence of frames in the image
+ should be repeated \a n times, including the sequence during
+ decoding.
+
+ \list
+ \i 0 = Forever
+ \i 1 = Only display frames the first time through
+ \i 2 = Repeat once after first pass through images
+ \i etc.
+ \endlist
+
+ To make the TQImageDecoder do this, just delete it and pass the
+ information to it again for decoding (setLooping() will be called
+ again, of course, but that can be ignored), or keep copies of the
+ changed areas at the ends of frames.
+*/
+
+/*!
+ \fn void TQImageConsumer::setFramePeriod(int milliseconds)
+
+ Notes that the frame about to be decoded should not be displayed
+ until the given number of \a milliseconds after the time that this
+ function is called. Of course, the image may not have been
+ decoded by then, in which case the frame should not be displayed
+ until it is complete. A value of -1 (the assumed default)
+ indicates that the image should be displayed even while it is only
+ partially loaded.
+*/
+
+/*!
+ \fn void TQImageConsumer::setSize(int, int)
+
+ This function is called as soon as the size of the image has been
+ determined.
+*/
+
+
+/*!
+ \class TQImageDecoder tqasyncimageio.h
+ \brief The TQImageDecoder class is an incremental image decoder for all supported image formats.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup multimedia
+
+ New formats are installed by creating objects of class
+ TQImageFormatType; the TQMovie class can be used for all installed
+ incremental image formats. TQImageDecoder is only useful for
+ creating new ways of feeding data to an TQImageConsumer.
+
+ A TQImageDecoder is a machine that decodes images. It takes encoded
+ image data via its decode() method and expresses its decoding by
+ supplying information to a TQImageConsumer. It implements its
+ decoding by using a TQImageFormat created by one of the
+ currently-existing TQImageFormatType factory objects.
+
+ TQImageFormatType and TQImageFormat are the classes that you might
+ need to implement support for additional image formats.
+
+ \legalese
+
+ TQt supports GIF reading if it is configured that way during
+ installation (see tqgif.h). If it is, we are required to state that
+ "The Graphics Interchange Format(c) is the Copyright property of
+ CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ CompuServe Incorporated."
+
+ \warning If you are in a country that recognizes software patents
+ and in which Unisys holds a patent on LZW compression and/or
+ decompression and you want to use GIF, Unisys may require you to
+ license that technology. Such countries include Canada, Japan,
+ the USA, France, Germany, Italy and the UK.
+
+ GIF support may be removed completely in a future version of TQt.
+ We recommend using the MNG or PNG format.
+*/
+
+static const int max_header = 32;
+
+
+
+
+
+// See tqgif.h for important information regarding this option
+#if defined(TQT_BUILTIN_GIF_READER) && TQT_BUILTIN_GIF_READER == 1
+class TQGIFFormat : public TQImageFormat {
+public:
+ TQGIFFormat();
+ virtual ~TQGIFFormat();
+
+ int decode(TQImage& img, TQImageConsumer* consumer,
+ const uchar* buffer, int length);
+
+private:
+ void fillRect(TQImage&, int x, int y, int w, int h, TQRgb col);
+ TQRgb color( uchar index ) const;
+
+ // GIF specific stuff
+ TQRgb* globalcmap;
+ TQRgb* localcmap;
+ TQImage backingstore;
+ unsigned char hold[16];
+ bool gif89;
+ int count;
+ int ccount;
+ int expectcount;
+ enum State {
+ Header,
+ LogicalScreenDescriptor,
+ GlobalColorMap,
+ LocalColorMap,
+ Introducer,
+ ImageDescriptor,
+ TableImageLZWSize,
+ ImageDataBlockSize,
+ ImageDataBlock,
+ ExtensionLabel,
+ GraphicControlExtension,
+ ApplicationExtension,
+ NetscapeExtensionBlockSize,
+ NetscapeExtensionBlock,
+ SkipBlockSize,
+ SkipBlock,
+ Done,
+ Error
+ } state;
+ int gncols;
+ int lncols;
+ int ncols;
+ int lzwsize;
+ bool lcmap;
+ int swidth, sheight;
+ int width, height;
+ int left, top, right, bottom;
+ enum Disposal { NoDisposal, DoNotChange, RestoreBackground, RestoreImage };
+ Disposal disposal;
+ bool disposed;
+ int trans_index;
+ bool gcmap;
+ int bgcol;
+ int interlace;
+ int accum;
+ int bitcount;
+
+ enum { max_lzw_bits=12 }; // (poor-compiler's static const int)
+
+ int code_size, clear_code, end_code, max_code_size, max_code;
+ int firstcode, oldcode, incode;
+ short table[2][1<< max_lzw_bits];
+ short stack[(1<<(max_lzw_bits))*2];
+ short *sp;
+ bool needfirst;
+ int x, y;
+ int frame;
+ bool out_of_bounds;
+ bool digress;
+ void nextY(TQImage& img, TQImageConsumer* consumer);
+ void disposePrevious( TQImage& img, TQImageConsumer* consumer );
+};
+
+class TQGIFFormatType : public TQImageFormatType
+{
+ TQImageFormat* decoderFor(const uchar* buffer, int length);
+ const char* formatName() const;
+};
+
+#endif
+
+
+class TQImageDecoderPrivate
+{
+public:
+ TQImageDecoderPrivate()
+ {
+ count = 0;
+ }
+
+ static void cleanup();
+
+ static void ensureFactories()
+ {
+ if ( !factories ) {
+ factories = new TQPtrList<TQImageFormatType>;
+// See tqgif.h for important information regarding this option
+#if defined(TQT_BUILTIN_GIF_READER) && TQT_BUILTIN_GIF_READER == 1
+ gif_decoder_factory = new TQGIFFormatType;
+#endif
+ qt_init_image_handlers();
+ qAddPostRoutine( cleanup );
+ }
+ }
+
+ static TQPtrList<TQImageFormatType> * factories;
+
+// See tqgif.h for important information regarding this option
+#if defined(TQT_BUILTIN_GIF_READER) && TQT_BUILTIN_GIF_READER == 1
+ static TQGIFFormatType * gif_decoder_factory;
+#endif
+
+ uchar header[max_header];
+ int count;
+};
+
+TQPtrList<TQImageFormatType> * TQImageDecoderPrivate::factories = 0;
+// See tqgif.h for important information regarding this option
+#if defined(TQT_BUILTIN_GIF_READER) && TQT_BUILTIN_GIF_READER == 1
+TQGIFFormatType * TQImageDecoderPrivate::gif_decoder_factory = 0;
+#endif
+
+
+void TQImageDecoderPrivate::cleanup()
+{
+ delete factories;
+ factories = 0;
+// See tqgif.h for important information regarding this option
+#if defined(TQT_BUILTIN_GIF_READER) && TQT_BUILTIN_GIF_READER == 1
+ delete gif_decoder_factory;
+ gif_decoder_factory = 0;
+#endif
+}
+
+
+/*!
+ Constructs a TQImageDecoder that will send change information to
+ the TQImageConsumer \a c.
+*/
+TQImageDecoder::TQImageDecoder(TQImageConsumer* c)
+{
+ qt_init_image_handlers();
+ d = new TQImageDecoderPrivate;
+ TQ_CHECK_PTR(d);
+ consumer = c;
+ actual_decoder = 0;
+}
+
+/*!
+ Destroys a TQImageDecoder. The image it built is destroyed. The
+ decoder built by the factory for the file format is destroyed. The
+ consumer for which it decoded the image is \e not destroyed.
+*/
+TQImageDecoder::~TQImageDecoder()
+{
+ delete d;
+ delete actual_decoder;
+}
+
+/*!
+ \fn const TQImage& TQImageDecoder::image()
+
+ Returns the image currently being decoded.
+*/
+
+static bool plugins_loaded = FALSE;
+
+/*!
+ Call this function to decode some data into image changes. The
+ data in \a buffer will be decoded, sending change information to
+ the TQImageConsumer of this TQImageDecoder until one of the change
+ functions of the consumer returns FALSE. The length of the data is
+ given in \a length.
+
+ Returns the number of bytes consumed: 0 if consumption is
+ complete, and -1 if decoding fails due to invalid data.
+*/
+int TQImageDecoder::decode(const uchar* buffer, int length)
+{
+ if (!actual_decoder) {
+ int i=0;
+
+ while (i < length && d->count < max_header)
+ d->header[d->count++] = buffer[i++];
+
+ TQImageDecoderPrivate::ensureFactories();
+
+ for (TQImageFormatType* f = TQImageDecoderPrivate::factories->first();
+ f && !actual_decoder;
+ f = TQImageDecoderPrivate::factories->next())
+ {
+ actual_decoder = f->decoderFor(d->header, d->count);
+ }
+ if ( !actual_decoder && !plugins_loaded) {
+ qt_init_image_plugins();
+ plugins_loaded = TRUE;
+
+ for (TQImageFormatType* f = TQImageDecoderPrivate::factories->first();
+ f && !actual_decoder;
+ f = TQImageDecoderPrivate::factories->next())
+ {
+ actual_decoder = f->decoderFor(d->header, d->count);
+ }
+ }
+
+ if (!actual_decoder) {
+ if ( d->count < max_header ) {
+ // not enough info yet
+ return i;
+ } else {
+ // failure - nothing matches max_header bytes
+ return -1;
+ }
+ }
+ }
+ return actual_decoder->decode(img, consumer, buffer, length);
+}
+
+/*!
+ Returns a TQImageFormatType by name. This might be used when the
+ user needs to force data to be interpreted as being in a certain
+ format. \a name is one of the formats listed by
+ TQImageDecoder::inputFormats(). Note that you will still need to
+ supply decodable data to result->decoderFor() before you can begin
+ decoding the data.
+*/
+TQImageFormatType* TQImageDecoder::format( const char* name )
+{
+ TQImageDecoderPrivate::ensureFactories();
+ qt_init_image_plugins();
+
+ for (TQImageFormatType* f = TQImageDecoderPrivate::factories->first();
+ f;
+ f = TQImageDecoderPrivate::factories->next())
+ {
+ if ( qstricmp(name,f->formatName())==0 )
+ return f;
+ }
+ return 0;
+}
+
+/*!
+ Call this function to tqfind the name of the format of the given
+ header. The returned string is statically allocated. The function
+ will look at the first \a length characters in the \a buffer.
+
+ Returns 0 if the format is not recognized.
+*/
+const char* TQImageDecoder::formatName(const uchar* buffer, int length)
+{
+ TQImageDecoderPrivate::ensureFactories();
+
+ const char* name = 0;
+ for (TQImageFormatType* f = TQImageDecoderPrivate::factories->first();
+ f && !name;
+ f = TQImageDecoderPrivate::factories->next())
+ {
+ TQImageFormat *decoder = f->decoderFor(buffer, length);
+ if (decoder) {
+ name = f->formatName();
+ delete decoder;
+ }
+ }
+ if ( !name && !plugins_loaded) {
+ qt_init_image_plugins();
+ plugins_loaded = TRUE;
+ for (TQImageFormatType* f = TQImageDecoderPrivate::factories->first();
+ f && !name;
+ f = TQImageDecoderPrivate::factories->next())
+ {
+ TQImageFormat *decoder = f->decoderFor(buffer, length);
+ if (decoder) {
+ name = f->formatName();
+ delete decoder;
+ }
+ }
+ }
+
+ return name;
+}
+
+/*!
+ Returns a sorted list of formats for which asynchronous loading is
+ supported.
+*/
+TQStrList TQImageDecoder::inputFormats()
+{
+ TQImageDecoderPrivate::ensureFactories();
+ qt_init_image_plugins();
+
+ TQStrList result;
+
+ for (TQImageFormatType* f = TQImageDecoderPrivate::factories->first();
+ f;
+ f = TQImageDecoderPrivate::factories->next())
+ {
+ if ( !result.tqcontains( f->formatName() ) ) {
+ result.inSort( f->formatName() );
+ }
+ }
+
+ return result;
+}
+
+/*!
+ Registers the new TQImageFormatType \a f. This is not needed in
+ application code because factories call this themselves.
+*/
+void TQImageDecoder::registerDecoderFactory(TQImageFormatType* f)
+{
+ TQImageDecoderPrivate::ensureFactories();
+
+ TQImageDecoderPrivate::factories->insert(0,f);
+}
+
+/*!
+ Unregisters the TQImageFormatType \a f. This is not needed in
+ application code because factories call this themselves.
+*/
+void TQImageDecoder::unregisterDecoderFactory(TQImageFormatType* f)
+{
+ if ( !TQImageDecoderPrivate::factories )
+ return;
+
+ TQImageDecoderPrivate::factories->remove(f);
+}
+
+/*!
+ \class TQImageFormat tqasyncimageio.h
+ \brief The TQImageFormat class is an incremental image decoder for a specific image format.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup multimedia
+
+ By making a derived class of TQImageFormatType, which in turn
+ creates objects that are a subclass of TQImageFormat, you can add
+ support for more incremental image formats, allowing such formats
+ to be sources for a TQMovie or for the first frame of the image
+ stream to be loaded as a TQImage or TQPixmap.
+
+ Your new subclass must reimplement the decode() function in order
+ to process your new format.
+
+ New TQImageFormat objects are generated by new TQImageFormatType
+ factories.
+*/
+
+/*!
+ Destroys the object.
+
+ \internal
+ More importantly, destroys derived classes.
+*/
+TQImageFormat::~TQImageFormat()
+{
+}
+
+/*!
+ \fn int TQImageFormat::decode(TQImage& img, TQImageConsumer* consumer, const uchar* buffer, int length)
+
+ New subclasses must reimplement this method.
+
+ It should decode some or all of the bytes from \a buffer into \a
+ img, calling the methods of \a consumer as the decoding proceeds
+ to inform that consumer of changes to the image. The length of the
+ data is given in \a length. The consumer may be 0, in which case
+ the function should just process the data into \a img without
+ telling any consumer about the changes. Note that the decoder must
+ store enough state to be able to continue in subsequent calls to
+ this method - this is the essence of the incremental image
+ loading.
+
+ The function should return without processing all the data if it
+ reaches the end of a frame in the input.
+
+ The function must return the number of bytes it has processed.
+*/
+
+/*!
+ \class TQImageFormatType tqasyncimageio.h
+ \brief The TQImageFormatType class is a factory that makes TQImageFormat objects.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup multimedia
+
+ Whereas the TQImageIO class allows for \e complete loading of
+ images, TQImageFormatType allows for \e incremental loading of
+ images.
+
+ New image file formats are installed by creating objects of
+ derived classes of TQImageFormatType. They must implement
+ decoderFor() and formatName().
+
+ TQImageFormatType is a very simple class. Its only task is to
+ recognize image data in some format and make a new object,
+ subclassed from TQImageFormat, which can decode that format.
+
+ The factories for formats built into TQt are automatically defined
+ before any other factory is initialized. If two factories would
+ recognize an image format, the factory created last will override
+ the earlier one; you can thus override current and future built-in
+ formats.
+*/
+
+/*!
+ \fn virtual TQImageFormat* TQImageFormatType::decoderFor(const uchar* buffer, int length)
+
+ Returns a decoder for decoding an image that starts with the bytes
+ in \a buffer. The length of the data is given in \a length. This
+ function should only return a decoder if it is certain that the
+ decoder applies to data with the given header. Returns 0 if there
+ is insufficient data in the header to make a positive
+ identification or if the data is not recognized.
+*/
+
+/*!
+ \fn virtual const char* TQImageFormatType::formatName() const
+
+ Returns the name of the format supported by decoders from this
+ factory. The string is statically allocated.
+*/
+
+/*!
+ Constructs a factory. It automatically registers itself with
+ TQImageDecoder.
+*/
+TQImageFormatType::TQImageFormatType()
+{
+ TQImageDecoder::registerDecoderFactory(this);
+}
+
+/*!
+ Destroys a factory. It automatically unregisters itself from
+ TQImageDecoder.
+*/
+TQImageFormatType::~TQImageFormatType()
+{
+ TQImageDecoder::unregisterDecoderFactory(this);
+}
+
+
+/*!
+ Returns TRUE if TQt was compiled with built-in GIF reading support;
+ otherwise returns FALSE.
+*/
+bool qt_builtin_gif_reader()
+{
+#if defined(TQT_BUILTIN_GIF_READER)
+ return TQT_BUILTIN_GIF_READER == 1;
+#else
+ return 0;
+#endif
+}
+
+// See tqgif.h for important information regarding this option
+#if defined(TQT_BUILTIN_GIF_READER) && TQT_BUILTIN_GIF_READER == 1
+
+/* -- NOTDOC
+ \class TQGIFFormat tqasyncimageio.h
+ \brief Incremental image decoder for GIF image format.
+
+ \ingroup images
+ \ingroup graphics
+
+ This subclass of TQImageFormat decodes GIF format images,
+ including animated GIFs. Internally in
+*/
+
+/*!
+ Constructs a TQGIFFormat.
+*/
+TQGIFFormat::TQGIFFormat()
+{
+ globalcmap = 0;
+ localcmap = 0;
+ lncols = 0;
+ gncols = 0;
+ disposal = NoDisposal;
+ out_of_bounds = FALSE;
+ disposed = TRUE;
+ frame = -1;
+ state = Header;
+ count = 0;
+ lcmap = FALSE;
+}
+
+/*!
+ Destroys a TQGIFFormat.
+*/
+TQGIFFormat::~TQGIFFormat()
+{
+ if (globalcmap) delete[] globalcmap;
+ if ( localcmap ) delete[] localcmap;
+}
+
+
+/* -- NOTDOC
+ \class TQGIFFormatType tqasyncimageio.h
+ \brief Incremental image decoder for GIF image format.
+
+ \ingroup images
+ \ingroup graphics
+
+ This subclass of TQImageFormatType recognizes GIF
+ format images, creating a TQGIFFormat when required. An instance
+ of this class is created automatically before any other factories,
+ so you should have no need for such objects.
+*/
+
+TQImageFormat* TQGIFFormatType::decoderFor(
+ const uchar* buffer, int length)
+{
+ if (length < 6) return 0;
+ if (buffer[0]=='G'
+ && buffer[1]=='I'
+ && buffer[2]=='F'
+ && buffer[3]=='8'
+ && (buffer[4]=='9' || buffer[4]=='7')
+ && buffer[5]=='a')
+ return new TQGIFFormat;
+ return 0;
+}
+
+const char* TQGIFFormatType::formatName() const
+{
+ return "GIF";
+}
+
+
+void TQGIFFormat::disposePrevious( TQImage& img, TQImageConsumer* consumer )
+{
+ if ( out_of_bounds ) // flush anything that survived
+ consumer->changed(TQRect(0,0,swidth,sheight));
+
+ // Handle disposal of previous image before processing next one
+
+ if ( disposed ) return;
+
+ int l = TQMIN(swidth-1,left);
+ int r = TQMIN(swidth-1,right);
+ int t = TQMIN(sheight-1,top);
+ int b = TQMIN(sheight-1,bottom);
+
+ switch (disposal) {
+ case NoDisposal:
+ break;
+ case DoNotChange:
+ break;
+ case RestoreBackground:
+ if (trans_index>=0) {
+ // Easy: we use the transtqparent color
+ fillRect(img, l, t, r-l+1, b-t+1, TQ_TRANSPARENT);
+ } else if (bgcol>=0) {
+ // Easy: we use the bgcol given
+ fillRect(img, l, t, r-l+1, b-t+1, color(bgcol));
+ } else {
+ // Impossible: We don't know of a bgcol - use pixel 0
+ TQRgb** line = (TQRgb **)img.jumpTable();
+ fillRect(img, l, t, r-l+1, b-t+1, line[0][0]);
+ }
+ if (consumer)
+ consumer->changed(TQRect(l, t, r-l+1, b-t+1));
+ break;
+ case RestoreImage: {
+ if ( frame >= 0 ) {
+ TQRgb** line = (TQRgb **)img.jumpTable();
+ for (int ln=t; ln<=b; ln++) {
+ memcpy(line[ln]+l,
+ backingstore.scanLine(ln-t),
+ (r-l+1)*sizeof(TQRgb) );
+ }
+ consumer->changed(TQRect(l, t, r-l+1, b-t+1));
+ }
+ }
+ }
+ disposal = NoDisposal; // Until an extension says otherwise.
+
+ disposed = TRUE;
+}
+
+/*!
+ This function decodes some data into image changes.
+
+ Returns the number of bytes consumed.
+*/
+int TQGIFFormat::decode(TQImage& img, TQImageConsumer* consumer,
+ const uchar* buffer, int length)
+{
+ // We are required to state that
+ // "The Graphics Interchange Format(c) is the Copyright property of
+ // CompuServe Incorporated. GIF(sm) is a Service Mark property of
+ // CompuServe Incorporated."
+
+#define LM(l, m) (((m)<<8)|l)
+ digress = FALSE;
+ int initial = length;
+ TQRgb** line = (TQRgb **)img.jumpTable();
+ while (!digress && length) {
+ length--;
+ unsigned char ch=*buffer++;
+ switch (state) {
+ case Header:
+ hold[count++]=ch;
+ if (count==6) {
+ // Header
+ gif89=(hold[3]!='8' || hold[4]!='7');
+ state=LogicalScreenDescriptor;
+ count=0;
+ }
+ break;
+ case LogicalScreenDescriptor:
+ hold[count++]=ch;
+ if (count==7) {
+ // Logical Screen Descriptor
+ swidth=LM(hold[0], hold[1]);
+ sheight=LM(hold[2], hold[3]);
+ gcmap=!!(hold[4]&0x80);
+ //UNUSED: bpchan=(((hold[4]&0x70)>>3)+1);
+ //UNUSED: gcmsortflag=!!(hold[4]&0x08);
+ gncols=2<<(hold[4]&0x7);
+ bgcol=(gcmap) ? hold[5] : -1;
+ //aspect=hold[6] ? double(hold[6]+15)/64.0 : 1.0;
+
+ trans_index = -1;
+ count=0;
+ ncols=gncols;
+ if (gcmap) {
+ ccount=0;
+ state=GlobalColorMap;
+ globalcmap = new TQRgb[gncols+1]; // +1 for trans_index
+ globalcmap[gncols] = TQ_TRANSPARENT;
+ } else {
+ state=Introducer;
+ }
+ }
+ break;
+ case GlobalColorMap: case LocalColorMap:
+ hold[count++]=ch;
+ if (count==3) {
+ TQRgb rgb = tqRgb(hold[0], hold[1], hold[2]);
+ if ( state == LocalColorMap ) {
+ if ( ccount < lncols )
+ localcmap[ccount] = rgb;
+ } else {
+ globalcmap[ccount] = rgb;
+ }
+ if (++ccount >= ncols) {
+ if ( state == LocalColorMap )
+ state=TableImageLZWSize;
+ else
+ state=Introducer;
+ }
+ count=0;
+ }
+ break;
+ case Introducer:
+ hold[count++]=ch;
+ switch (ch) {
+ case ',':
+ state=ImageDescriptor;
+ break;
+ case '!':
+ state=ExtensionLabel;
+ break;
+ case ';':
+ if (consumer) {
+ if ( out_of_bounds ) // flush anything that survived
+ consumer->changed(TQRect(0,0,swidth,sheight));
+ consumer->end();
+ }
+ state=Done;
+ break;
+ default:
+ digress=TRUE;
+ // Unexpected Introducer - ignore block
+ state=Error;
+ }
+ break;
+ case ImageDescriptor:
+ hold[count++]=ch;
+ if (count==10) {
+ int newleft=LM(hold[1], hold[2]);
+ int newtop=LM(hold[3], hold[4]);
+ int newwidth=LM(hold[5], hold[6]);
+ int newheight=LM(hold[7], hold[8]);
+
+ // disbelieve ridiculous logical screen sizes,
+ // unless the image frames are also large.
+ if ( swidth/10 > TQMAX(newwidth,200) )
+ swidth = -1;
+ if ( sheight/10 > TQMAX(newheight,200) )
+ sheight = -1;
+
+ if ( swidth <= 0 )
+ swidth = newleft + newwidth;
+ if ( sheight <= 0 )
+ sheight = newtop + newheight;
+
+ if (img.isNull()) {
+ img.create(swidth, sheight, 32);
+ memset( img.bits(), 0, img.numBytes() );
+ if (consumer) consumer->setSize(swidth, sheight);
+ }
+ img.setAlphaBuffer(trans_index >= 0);
+ line = (TQRgb **)img.jumpTable();
+
+ disposePrevious( img, consumer );
+ disposed = FALSE;
+
+ left = newleft;
+ top = newtop;
+ width = newwidth;
+ height = newheight;
+
+ right=TQMAX( 0, TQMIN(left+width, swidth)-1);
+ bottom=TQMAX(0, TQMIN(top+height, sheight)-1);
+ lcmap=!!(hold[9]&0x80);
+ interlace=!!(hold[9]&0x40);
+ //bool lcmsortflag=!!(hold[9]&0x20);
+ lncols=lcmap ? (2<<(hold[9]&0x7)) : 0;
+ if (lncols) {
+ if ( localcmap )
+ delete [] localcmap;
+ localcmap = new TQRgb[lncols+1];
+ localcmap[lncols] = TQ_TRANSPARENT;
+ ncols = lncols;
+ } else {
+ ncols = gncols;
+ }
+ frame++;
+ if ( frame == 0 ) {
+ if ( left || top || width<swidth || height<sheight ) {
+ // Not full-size image - erase with bg or transtqparent
+ if ( trans_index >= 0 ) {
+ fillRect(img, 0, 0, swidth, sheight, color(trans_index));
+ if (consumer) consumer->changed(TQRect(0,0,swidth,sheight));
+ } else if ( bgcol>=0 ) {
+ fillRect(img, 0, 0, swidth, sheight, color(bgcol));
+ if (consumer) consumer->changed(TQRect(0,0,swidth,sheight));
+ }
+ }
+ }
+
+ if ( disposal == RestoreImage ) {
+ int l = TQMIN(swidth-1,left);
+ int r = TQMIN(swidth-1,right);
+ int t = TQMIN(sheight-1,top);
+ int b = TQMIN(sheight-1,bottom);
+ int w = r-l+1;
+ int h = b-t+1;
+
+ if (backingstore.width() < w
+ || backingstore.height() < h) {
+ // We just use the backing store as a byte array
+ backingstore.create( TQMAX(backingstore.width(), w),
+ TQMAX(backingstore.height(), h),
+ 32);
+ memset( img.bits(), 0, img.numBytes() );
+ }
+ for (int ln=0; ln<h; ln++) {
+ memcpy(backingstore.scanLine(ln),
+ line[t+ln]+l, w*sizeof(TQRgb));
+ }
+ }
+
+ count=0;
+ if (lcmap) {
+ ccount=0;
+ state=LocalColorMap;
+ } else {
+ state=TableImageLZWSize;
+ }
+ x = left;
+ y = top;
+ accum = 0;
+ bitcount = 0;
+ sp = stack;
+ firstcode = oldcode = 0;
+ needfirst = FALSE;
+ out_of_bounds = left>=swidth || y>=sheight;
+ }
+ break;
+ case TableImageLZWSize: {
+ lzwsize=ch;
+ if ( lzwsize > max_lzw_bits ) {
+ state=Error;
+ } else {
+ code_size=lzwsize+1;
+ clear_code=1<<lzwsize;
+ end_code=clear_code+1;
+ max_code_size=2*clear_code;
+ max_code=clear_code+2;
+ int i;
+ for (i=0; i<clear_code && i<(1<<max_lzw_bits); i++) {
+ table[0][i]=0;
+ table[1][i]=i;
+ }
+ for (i=clear_code; i<(1<<max_lzw_bits); i++) {
+ table[0][i]=table[1][i]=0;
+ }
+ state=ImageDataBlockSize;
+ }
+ count=0;
+ break;
+ } case ImageDataBlockSize:
+ expectcount=ch;
+ if (expectcount) {
+ state=ImageDataBlock;
+ } else {
+ if (consumer) {
+ consumer->frameDone();
+ digress = TRUE;
+ }
+
+ state=Introducer;
+ }
+ break;
+ case ImageDataBlock:
+ count++;
+ accum|=(ch<<bitcount);
+ bitcount+=8;
+ while (bitcount>=code_size && state==ImageDataBlock) {
+ int code=accum&((1<<code_size)-1);
+ bitcount-=code_size;
+ accum>>=code_size;
+
+ if (code==clear_code) {
+ if (!needfirst) {
+ int i;
+ code_size=lzwsize+1;
+ max_code_size=2*clear_code;
+ max_code=clear_code+2;
+ for (i=0; i<clear_code; i++) {
+ table[0][i]=0;
+ table[1][i]=i;
+ }
+ for (i=clear_code; i<(1<<max_lzw_bits); i++) {
+ table[0][i]=table[1][i]=0;
+ }
+ }
+ needfirst=TRUE;
+ } else if (code==end_code) {
+ bitcount = -32768;
+ // Left the block end arrive
+ } else {
+ if (needfirst) {
+ firstcode=oldcode=code;
+ if (!out_of_bounds && line && firstcode!=trans_index)
+ line[y][x] = color(firstcode);
+ x++;
+ if (x>=swidth) out_of_bounds = TRUE;
+ needfirst=FALSE;
+ if (x>=left+width) {
+ x=left;
+ out_of_bounds = left>=swidth || y>=sheight;
+ nextY(img,consumer);
+ }
+ } else {
+ incode=code;
+ if (code>=max_code) {
+ *sp++=firstcode;
+ code=oldcode;
+ }
+ while (code>=clear_code) {
+ *sp++=table[1][code];
+ if (code==table[0][code]) {
+ state=Error;
+ break;
+ }
+ if (sp-stack>=(1<<(max_lzw_bits))*2) {
+ state=Error;
+ break;
+ }
+ code=table[0][code];
+ }
+ *sp++=firstcode=table[1][code];
+ code=max_code;
+ if (code<(1<<max_lzw_bits)) {
+ table[0][code]=oldcode;
+ table[1][code]=firstcode;
+ max_code++;
+ if ((max_code>=max_code_size)
+ && (max_code_size<(1<<max_lzw_bits)))
+ {
+ max_code_size*=2;
+ code_size++;
+ }
+ }
+ oldcode=incode;
+ while (sp>stack) {
+ --sp;
+ if (!out_of_bounds && line && *sp!=trans_index)
+ line[y][x] = color(*sp);
+ x++;
+ if (x>=swidth) out_of_bounds = TRUE;
+ if (x>=left+width) {
+ x=left;
+ out_of_bounds = left>=swidth || y>=sheight;
+ nextY(img,consumer);
+ }
+ }
+ }
+ }
+ }
+ if (count==expectcount) {
+ count=0;
+ state=ImageDataBlockSize;
+ }
+ break;
+ case ExtensionLabel:
+ switch (ch) {
+ case 0xf9:
+ state=GraphicControlExtension;
+ break;
+ case 0xff:
+ state=ApplicationExtension;
+ break;
+#if 0
+ case 0xfe:
+ state=CommentExtension;
+ break;
+ case 0x01:
+ break;
+#endif
+ default:
+ state=SkipBlockSize;
+ }
+ count=0;
+ break;
+ case ApplicationExtension:
+ if (count<11) hold[count]=ch;
+ count++;
+ if (count==hold[0]+1) {
+ if (tqstrncmp((char*)(hold+1), "NETSCAPE", 8)==0) {
+ // Looping extension
+ state=NetscapeExtensionBlockSize;
+ } else {
+ state=SkipBlockSize;
+ }
+ count=0;
+ }
+ break;
+ case NetscapeExtensionBlockSize:
+ expectcount=ch;
+ count=0;
+ if (expectcount) state=NetscapeExtensionBlock;
+ else state=Introducer;
+ break;
+ case NetscapeExtensionBlock:
+ if (count<3) hold[count]=ch;
+ count++;
+ if (count==expectcount) {
+ int loop = hold[0]+hold[1]*256;
+ if (consumer) consumer->setLooping(loop);
+ state=SkipBlockSize; // Ignore further blocks
+ }
+ break;
+ case GraphicControlExtension:
+ if (count<5) hold[count]=ch;
+ count++;
+ if (count==hold[0]+1) {
+ disposePrevious( img, consumer );
+ disposal=Disposal((hold[1]>>2)&0x7);
+ //UNUSED: waitforuser=!!((hold[1]>>1)&0x1);
+ int delay=count>3 ? LM(hold[2], hold[3]) : 1;
+ // IE and mozilla use a minimum delay of 10. With the minumum delay of 10
+ // we are compatible to them and avoid huge loads on the app and xserver.
+ if ( delay < 10 )
+ delay = 10;
+
+ bool havetrans=hold[1]&0x1;
+ trans_index = havetrans ? hold[4] : -1;
+
+ if (consumer) consumer->setFramePeriod(delay*10);
+ count=0;
+ state=SkipBlockSize;
+ }
+ break;
+ case SkipBlockSize:
+ expectcount=ch;
+ count=0;
+ if (expectcount) state=SkipBlock;
+ else state=Introducer;
+ break;
+ case SkipBlock:
+ count++;
+ if (count==expectcount) state=SkipBlockSize;
+ break;
+ case Done:
+ digress=TRUE;
+ /* Netscape ignores the junk, so we do too.
+ length++; // Unget
+ state=Error; // More calls to this is an error
+ */
+ break;
+ case Error:
+ return -1; // Called again after done.
+ }
+ }
+ return initial-length;
+}
+
+void TQGIFFormat::fillRect(TQImage& img, int col, int row, int w, int h, TQRgb color)
+{
+ if (w>0) {
+ TQRgb** line = (TQRgb **)img.jumpTable() + row;
+ for (int j=0; j<h; j++) {
+ for ( int i=0; i<w; i++ ) {
+ *(line[j]+col+i) = color;
+ }
+ }
+ }
+}
+
+void TQGIFFormat::nextY(TQImage& img, TQImageConsumer* consumer)
+{
+ int my;
+ switch (interlace) {
+ case 0:
+ // Non-interlaced
+ if (consumer && !out_of_bounds)
+ consumer->changed(TQRect(left, y, right-left+1, 1));
+ y++;
+ break;
+ case 1:
+ {
+ int i;
+ my = TQMIN(7, bottom-y);
+ if ( trans_index < 0 ) // Don't dup with transparency
+ for (i=1; i<=my; i++)
+ memcpy(img.scanLine(y+i)+left, img.scanLine(y)+left,
+ (right-left+1)*sizeof(TQRgb));
+ if (consumer && !out_of_bounds)
+ consumer->changed(TQRect(left, y, right-left+1, my+1));
+ y+=8;
+ if (y>bottom) {
+ interlace++; y=top+4;
+ if (y > bottom) { // for really broken GIFs with bottom < 5
+ interlace=2;
+ y = top + 2;
+ if (y > bottom) { // for really broken GIF with bottom < 3
+ interlace = 0;
+ y = top + 1;
+ }
+ }
+ }
+ } break;
+ case 2:
+ {
+ int i;
+ my = TQMIN(3, bottom-y);
+ if ( trans_index < 0 ) // Don't dup with transparency
+ for (i=1; i<=my; i++)
+ memcpy(img.scanLine(y+i)+left, img.scanLine(y)+left,
+ (right-left+1)*sizeof(TQRgb));
+ if (consumer && !out_of_bounds)
+ consumer->changed(TQRect(left, y, right-left+1, my+1));
+ y+=8;
+ if (y>bottom) {
+ interlace++; y=top+2;
+ if (y > bottom) { // for really broken GIF with bottom < 3
+ interlace = 3;
+ y = top + 1;
+ }
+ }
+ } break;
+ case 3:
+ {
+ int i;
+ my = TQMIN(1, bottom-y);
+ if ( trans_index < 0 ) // Don't dup with transparency
+ for (i=1; i<=my; i++)
+ memcpy(img.scanLine(y+i)+left, img.scanLine(y)+left,
+ (right-left+1)*sizeof(TQRgb));
+ if (consumer && !out_of_bounds)
+ consumer->changed(TQRect(left, y, right-left+1, my+1));
+ y+=4;
+ if (y>bottom) { interlace++; y=top+1; }
+ } break;
+ case 4:
+ if (consumer && !out_of_bounds)
+ consumer->changed(TQRect(left, y, right-left+1, 1));
+ y+=2;
+ }
+
+ // Consume bogus extra lines
+ if (y >= sheight) out_of_bounds=TRUE; //y=bottom;
+}
+
+TQRgb TQGIFFormat::color( uchar index ) const
+{
+ if ( index == trans_index || index > ncols )
+ return TQ_TRANSPARENT;
+ TQRgb *map = lcmap ? localcmap : globalcmap;
+ return map ? map[index] : 0;
+}
+
+
+
+#endif // TQT_BUILTIN_GIF_READER
+
+#endif // TQT_NO_ASYNC_IMAGE_IO
diff --git a/tqtinterface/qt4/src/kernel/tqasyncimageio.h b/tqtinterface/qt4/src/kernel/tqasyncimageio.h
new file mode 100644
index 0000000..75e1f60
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqasyncimageio.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Definition of asynchronous image/movie loading classes
+**
+** Created : 970617
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQASYNCIMAGEIO_H
+#define TQASYNCIMAGEIO_H
+
+#ifndef TQT_H
+#include "tqimage.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+
+#if __GNUC__ - 0 > 3
+#pragma GCC system_header
+#endif
+
+class TQ_EXPORT TQImageConsumer {
+public:
+ virtual void end()=0;
+
+ // Change transfer type 1.
+ virtual void changed( const TQRect& ) = 0;
+ virtual void frameDone() = 0;
+
+ // Change transfer type 2.
+ virtual void frameDone( const TQPoint&, const TQRect& ) = 0;
+
+ virtual void setLooping( int ) = 0;
+ virtual void setFramePeriod( int ) = 0;
+ virtual void setSize( int, int ) = 0;
+};
+
+class TQ_EXPORT TQImageFormat {
+public:
+ virtual ~TQImageFormat();
+ virtual int decode( TQImage& img, TQImageConsumer* consumer,
+ const uchar* buffer, int length ) = 0;
+};
+
+class TQ_EXPORT TQImageFormatType {
+public:
+ virtual ~TQImageFormatType();
+ virtual TQImageFormat* decoderFor( const uchar* buffer, int length ) = 0;
+ virtual const char* formatName() const = 0;
+protected:
+ TQImageFormatType();
+};
+
+class TQImageDecoderPrivate;
+class TQ_EXPORT TQImageDecoder {
+public:
+ TQImageDecoder( TQImageConsumer* c );
+ ~TQImageDecoder();
+
+ const TQImage& image() { return img; }
+ int decode( const uchar* buffer, int length );
+
+ static const char* formatName( const uchar* buffer, int length );
+ static TQImageFormatType* format( const char* name ); // direct use - no decode()
+
+ static TQStrList inputFormats();
+ static void registerDecoderFactory( TQImageFormatType* );
+ static void unregisterDecoderFactory( TQImageFormatType* );
+
+private:
+ TQImageFormat* actual_decoder;
+ TQImageConsumer* consumer;
+ TQImage img;
+ TQImageDecoderPrivate *d;
+};
+
+#endif // TQT_NO_ASYNC_IMAGE_IO
+
+#endif // TQASYNCIMAGEIO_H
diff --git a/tqtinterface/qt4/src/kernel/tqasyncio.cpp b/tqtinterface/qt4/src/kernel/tqasyncio.cpp
new file mode 100644
index 0000000..ee479e0
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqasyncio.cpp
@@ -0,0 +1,360 @@
+/****************************************************************************
+**
+** Implementation of asynchronous I/O classes
+**
+** Created : 970617
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqasyncio.h"
+#include "tqiodevice.h"
+#include <stdlib.h>
+
+#ifndef TQT_NO_ASYNC_IO
+
+/*!
+ \class TQAsyncIO tqasyncio.h
+ \obsolete
+ \brief The TQAsyncIO class encapsulates I/O asynchronicity.
+
+ The TQt classes for asynchronous input/output provide a simple
+ mechanism to allow large files or slow data sources to be processed
+ without using large amounts of memory or blocking the user interface.
+
+ This facility is used in TQt to drive animated images. See TQImageConsumer.
+*/
+
+
+/*!
+ Destroys the async IO object.
+*/
+TQAsyncIO::~TQAsyncIO()
+{
+}
+
+/*!
+ Ensures that only one object, \a obj and function, \a member, can
+ respond to changes in readiness.
+*/
+void TQAsyncIO::connect(TQObject* obj, const char *member)
+{
+ signal.disconnect(0, 0);
+ signal.connect(obj, member);
+}
+
+/*!
+ Derived classes should call this when they change from being
+ unready to ready.
+*/
+void TQAsyncIO::ready()
+{
+ signal.activate();
+}
+
+
+
+/*!
+ \class TQDataSink tqasyncio.h
+ \obsolete
+ \brief The TQDataSink class is an asynchronous consumer of data.
+
+ A data sink is an object which receives data from some source in an
+ asynchronous manner. This means that at some time not determined by
+ the data sink, blocks of data are given to it from processing. The
+ data sink is able to limit the maximum size of such blocks which it
+ is currently able to process.
+
+ \sa TQAsyncIO, TQDataSource, TQDataPump
+*/
+
+/*!
+ \fn int TQDataSink::readyToReceive()
+
+ The data sink should return a value indicating how much data it is ready
+ to consume. This may be 0.
+*/
+
+/*!
+ This should be called whenever readyToReceive() might have become non-zero.
+ It is merely calls TQAsyncIO::ready() if readyToReceive() is non-zero.
+*/
+void TQDataSink::maybeReady()
+{
+ if (readyToReceive()) ready();
+}
+
+/*!
+ \fn void TQDataSink::receive(const uchar*, int count)
+
+ This function is called to provide data for the data sink. The \a count
+ will be no more than the amount indicated by the most recent call to
+ readyToReceive(). The sink must use all the provided data.
+*/
+
+/*!
+ \fn void TQDataSink::eof()
+
+ This function will be called when no more data is available for
+ processing.
+*/
+
+
+/*!
+ \class TQDataSource tqasyncio.h
+ \obsolete
+ \brief The TQDataSource class is an asynchronous producer of data.
+
+ A data source is an object which provides data from some source in an
+ asynchronous manner. This means that at some time not determined by
+ the data source, blocks of data will be taken from it for processing.
+ The data source is able to limit the maximum size of such blocks which
+ it is currently able to provide.
+
+ \sa TQAsyncIO, TQDataSink, TQDataPump
+*/
+
+/*!
+ \fn int TQDataSource::readyToSend()
+
+ The data source should return a value indicating how much data it is ready
+ to provide. This may be 0. If the data source knows it will never be
+ able to provide any more data (until after a rewind()), it may return -1.
+*/
+
+/*!
+ This should be called whenever readyToSend() might have become non-zero.
+ It is merely calls TQAsyncIO::ready() if readyToSend() is non-zero.
+*/
+void TQDataSource::maybeReady()
+{
+ if (readyToSend()) ready();
+}
+
+/*!
+ \fn void TQDataSource::sendTo(TQDataSink*, int count)
+
+ This function is called to extract data from the source, by sending
+ it to the given data sink. The \a count will be no more than the amount
+ indicated by the most recent call to readyToSend(). The source must
+ use all the provided data, and the sink will be prepared to accept at
+ least this much data.
+*/
+
+/*!
+ This function should return TRUE if the data source can be rewound.
+
+ The default returns FALSE.
+*/
+bool TQDataSource::rewindable() const
+{
+ return FALSE;
+}
+
+/*!
+ If this function is called with \a on set to TRUE, and rewindable()
+ is TRUE, then the data source must take measures to allow the rewind()
+ function to subsequently operate as described. If rewindable() is FALSE,
+ the function should call TQDataSource::enableRewind(), which aborts with
+ a qFatal() error.
+
+ For example, a network connection may choose to use a disk cache
+ of input only if rewinding is enabled before the first buffer-full of
+ data is discarded, returning FALSE in rewindable() if that first buffer
+ is discarded.
+*/
+void TQDataSource::enableRewind( bool /* on */ )
+{
+ qFatal( "Attempted to make unrewindable TQDataSource rewindable" );
+}
+
+/*!
+ This function rewinds the data source. This may only be called if
+ enableRewind(TRUE) has been previously called.
+*/
+void TQDataSource::rewind()
+{
+ qFatal("Attempted to rewind unrewindable TQDataSource");
+}
+
+/*!
+ \class TQIODeviceSource tqasyncio.h
+ \obsolete
+ \brief The TQIODeviceSource class is a TQDataSource that draws data from a TQIODevice.
+
+ This class encapsulates retrieving data from a TQIODevice (such as a TQFile).
+*/
+
+/*!
+ Constructs a TQIODeviceSource from the TQIODevice \a tqdevice. The TQIODevice
+ \e must be dynamically allocated, becomes owned by the TQIODeviceSource,
+ and will be deleted when the TQIODeviceSource is destroyed. \a buffer_size
+ determines the size of buffering to use between asynchronous operations.
+ The higher the \a buffer_size, the more efficient, but the less interleaved
+ the operation will be with other processing.
+*/
+TQIODeviceSource::TQIODeviceSource(TQIODevice* tqdevice, int buffer_size) :
+ buf_size(buffer_size),
+ buffer(new uchar[buf_size]),
+ iod(tqdevice),
+ rew(FALSE)
+{
+}
+
+/*!
+ Destroys the TQIODeviceSource, deleting the TQIODevice from which it was
+ constructed.
+*/
+TQIODeviceSource::~TQIODeviceSource()
+{
+ delete iod;
+ delete [] buffer;
+}
+
+/*!
+ Ready until end-of-file.
+*/
+int TQIODeviceSource::readyToSend()
+{
+ if ( iod->status() != IO_Ok || !(iod->state() & IO_Open) )
+ return -1;
+
+ int n = TQMIN((uint)buf_size, iod->size()-iod->at()); // ### not 64-bit safe
+ // ### not large file safe
+ return n ? n : -1;
+}
+
+/*!
+ Reads a block of data and sends up to \a n bytes to the \a sink.
+*/
+void TQIODeviceSource::sendTo(TQDataSink* sink, int n)
+{
+ iod->readBlock((char*)buffer, n);
+ sink->receive(buffer, n);
+}
+
+/*!
+ All TQIODeviceSource's are rewindable.
+*/
+bool TQIODeviceSource::rewindable() const
+{
+ return TRUE;
+}
+
+/*!
+ If \a on is set to TRUE then rewinding is enabled.
+ No special action is taken. If \a on is set to
+ FALSE then rewinding is disabled.
+*/
+void TQIODeviceSource::enableRewind(bool on)
+{
+ rew = on;
+}
+
+/*!
+ Calls reset() on the TQIODevice.
+*/
+void TQIODeviceSource::rewind()
+{
+ if (!rew) {
+ TQDataSource::rewind();
+ } else {
+ iod->reset();
+ ready();
+ }
+}
+
+
+/*!
+ \class TQDataPump tqasyncio.h
+ \obsolete
+ \brief The TQDataPump class moves data from a TQDataSource to a TQDataSink during event processing.
+
+ For a TQDataSource to provide data to a TQDataSink, a controller must exist
+ to examine the TQDataSource::readyToSend() and TQDataSink::readyToReceive()
+ methods and respond to the TQASyncIO::activate() signal of the source and
+ sink. One very useful way to do this is interleaved with other event
+ processing. TQDataPump provides this - create a pipe between a source
+ and a sink, and data will be moved during subsequent event processing.
+
+ Note that each source can only provide data to one sink and each sink
+ can only receive data from one source (although it is quite possible
+ to write a multiplexing sink that is multiple sources).
+*/
+
+/*!
+ Constructs a TQDataPump to move data from a given \a data_source
+ to a given \a data_sink.
+*/
+TQDataPump::TQDataPump(TQDataSource* data_source, TQDataSink* data_sink) :
+ source(data_source), sink(data_sink)
+{
+ source->connect(this, TQT_SLOT(kickStart()));
+ sink->connect(this, TQT_SLOT(kickStart()));
+ connect(&timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(tryToPump()));
+ timer.start(0, TRUE);
+}
+
+void TQDataPump::kickStart()
+{
+ if (!timer.isActive()) {
+ interval = 0;
+ timer.start(0, TRUE);
+ }
+}
+
+void TQDataPump::tryToPump()
+{
+ int supply, demand;
+
+ supply = source->readyToSend();
+ demand = sink->readyToReceive();
+ if (demand <= 0) {
+ return;
+ }
+ interval = 0;
+ if (supply < 0) {
+ // All done (until source Q_SIGNALS change in readiness)
+ sink->eof();
+ return;
+ }
+ if (!supply)
+ return;
+ source->sendTo(sink, TQMIN(supply, demand));
+
+ timer.start(0, TRUE);
+}
+
+#endif // TQT_NO_ASYNC_IO
+
diff --git a/tqtinterface/qt4/src/kernel/tqasyncio.h b/tqtinterface/qt4/src/kernel/tqasyncio.h
new file mode 100644
index 0000000..76176a5
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqasyncio.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Definition of asynchronous I/O classes
+**
+** Created : 970617
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQASYNCIO_H
+#define TQASYNCIO_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqsignal.h"
+#include "tqtimer.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_ASYNC_IO
+
+class TQIODevice;
+
+class TQ_EXPORT TQAsyncIO {
+public:
+ virtual ~TQAsyncIO();
+ void connect(TQObject*, const char *member);
+
+protected:
+ void ready();
+
+private:
+ TQSignal signal;
+};
+
+class TQ_EXPORT TQDataSink : public TQAsyncIO {
+public:
+ // Call this to know how much I can take.
+ virtual int readyToReceive()=0;
+ virtual void receive(const uchar*, int count)=0;
+ virtual void eof()=0;
+ void maybeReady();
+};
+
+class TQ_EXPORT TQDataSource : public TQAsyncIO {
+public:
+ virtual int readyToSend()=0; // returns -1 when never any more ready
+ virtual void sendTo(TQDataSink*, int count)=0;
+ void maybeReady();
+
+ virtual bool rewindable() const;
+ virtual void enableRewind(bool);
+ virtual void rewind();
+};
+
+class TQ_EXPORT TQIODeviceSource : public TQDataSource {
+ const int buf_size;
+ uchar *buffer;
+ TQIODevice* iod;
+ bool rew;
+
+public:
+ TQIODeviceSource(TQIODevice*, int bufsize=4096);
+ ~TQIODeviceSource();
+
+ int readyToSend();
+ void sendTo(TQDataSink* sink, int n);
+ bool rewindable() const;
+ void enableRewind(bool on);
+ void rewind();
+};
+
+class TQ_EXPORT TQDataPump : public TQObject {
+ Q_OBJECT
+ TQ_OBJECT
+ int interval;
+ TQTimer timer;
+ TQDataSource* source;
+ TQDataSink* sink;
+
+public:
+ TQDataPump(TQDataSource*, TQDataSink*);
+
+private Q_SLOTS:
+ void kickStart();
+ void tryToPump();
+};
+
+#endif // TQT_NO_ASYNC_IO
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqbitmap.cpp b/tqtinterface/qt4/src/kernel/tqbitmap.cpp
new file mode 100644
index 0000000..3e2ee39
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqbitmap.cpp
@@ -0,0 +1,435 @@
+/****************************************************************************
+**
+** Implementation of TQBitmap class
+**
+** Created : 941020
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqbitmap.h"
+#include "tqimage.h"
+
+#ifdef USE_QT4
+
+TQBitmap::TQBitmap() : QBitmap() {
+}
+
+TQBitmap::TQBitmap( int w, int h, bool clear, TQPixmap::Optimization o ) : QBitmap( w, h ) {
+ TQ_UNUSED(o);
+ if (clear)
+ QBitmap::clear();
+}
+
+TQBitmap::TQBitmap( const QSize &s, bool clear, TQPixmap::Optimization o ) : QBitmap( s ) {
+ TQ_UNUSED(o);
+ if (clear)
+ QBitmap::clear();
+}
+
+TQBitmap::TQBitmap( int w, int h, const uchar *bits, bool isXbitmap ) : QBitmap( QBitmap::fromData ( QSize(w, h), bits, (isXbitmap)?QImage::Format_MonoLSB:QImage::Format_Mono ) ) {
+}
+
+TQBitmap::TQBitmap( const QSize &s, const uchar *bits, bool isXbitmap ) : QBitmap( QBitmap::fromData ( s, bits, (isXbitmap)?QImage::Format_MonoLSB:QImage::Format_Mono ) ) {
+}
+
+TQBitmap::TQBitmap( const QBitmap &b ) : QBitmap( b ) {
+}
+
+#ifndef TQT_NO_IMAGEIO
+TQBitmap::TQBitmap( const QString &fileName, const char *format ) : QBitmap( fileName, format ) {
+}
+#endif
+
+QImage TQBitmap::convertToImage() const {
+ return toImage();
+}
+
+bool TQBitmap::convertFromImage(const QImage &img, int flags) {
+ return QPixmap::convertFromImage(img, (Qt::ImageConversionFlag)flags);
+}
+
+TQBitmap TQBitmap::xForm(const QMatrix &matrix) const {
+ return transformed(QTransform(matrix));
+}
+
+void TQBitmap::resize(const QSize &s) {
+ resize_helper(s);
+}
+
+void TQBitmap::resize(int width, int height) {
+ resize_helper(QSize(width, height));
+}
+
+// void TQBitmap::resize_helper(const QSize &s)
+// {
+// int w = s.width();
+// int h = s.height();
+// if (w < 1 || h < 1) {
+// *this = TQBitmap();
+// return;
+// }
+//
+// *this = TQBitmap(copy(0, 0, w, h));
+// }
+
+void TQBitmap::resize_helper(const QSize s)
+{
+ int w = s.width();
+ int h = s.height();
+
+ if (w < 1 || h < 1) {
+ *this = TQBitmap();
+ return;
+ }
+
+ if (size() == s)
+ return;
+
+ TQBitmap pm(QSize(w, h));
+ if (!isNull()) {
+ // Copy old bitmap
+ pm.fill(Qt::color0);
+ QPainter p(&pm);
+ p.setBrush(Qt::color1);
+ p.drawPixmap(0, 0, *this, 0, 0, qMin(width(), w), qMin(height(), h));
+ p.end();
+ }
+
+ // Mask too....
+ if (!mask().isNull()) {
+ TQBitmap m = mask();
+ if (m.size() != QSize(w,h)) {
+ TQBitmap pmr(QSize(w, h));
+ pmr.fill(Qt::color0);
+ QPainter pr(&pmr);
+ pr.setBrush(Qt::color1);
+ pr.drawPixmap(0, 0, m, 0, 0, qMin(m.width(), w), qMin(m.height(), h));
+ pr.end();
+ pm.setMask(pmr);
+ }
+ else {
+ pm.setMask(m);
+ }
+ }
+
+ // [FIXME]
+ // Note that the Xorg pixmap and/or gc (if any) is not created via the above process
+ // Therefore resize is more of a copy operation than a true resize
+ #warning TQPixmap::resize() partially implemented
+
+ *this = pm;
+}
+
+// This is the only correct way to return a pointer to an object returned by another function
+const TQBitmap *TQBitmap::tqmask() const {
+ const QBitmap& ptrRef = mask();
+ if (ptrRef.isNull() == true) {
+ return 0;
+ }
+ return static_cast<const TQBitmap*>(&ptrRef);
+}
+
+TQBitmap TQBitmap::operator=( const TQPixmap &pixmap )
+{
+ return TQBitmap(QBitmap::operator=(pixmap));
+}
+
+TQBitmap &TQBitmap::operator=( const TQImage &image )
+{
+ convertFromImage( image );
+ return *this;
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQBitmap tqbitmap.h
+ \brief The TQBitmap class provides monochrome (1-bit depth) pixmaps.
+
+ \ingroup graphics
+ \ingroup images
+ \ingroup shared
+
+ The TQBitmap class is a monochrome off-screen paint tqdevice used
+ mainly for creating custom TQCursor and TQBrush objects, in
+ TQPixmap::setMask() and for TQRegion.
+
+ A TQBitmap is a TQPixmap with a \link TQPixmap::depth() depth\endlink
+ of 1. If a pixmap with a depth greater than 1 is assigned to a
+ bitmap, the bitmap will be dithered automatically. A TQBitmap is
+ guaranteed to always have the depth 1, unless it is
+ TQPixmap::isNull() which has depth 0.
+
+ When drawing in a TQBitmap (or TQPixmap with depth 1), we recommend
+ using the TQColor objects \c TQt::color0 and \c TQt::color1.
+ Painting with \c color0 sets the bitmap bits to 0, and painting
+ with \c color1 sets the bits to 1. For a bitmap, 0-bits indicate
+ background (or transtqparent) and 1-bits indicate foreground (or
+ opaque). Using the \c black and \c white TQColor objects make no
+ sense because the TQColor::pixel() value is not necessarily 0 for
+ black and 1 for white.
+
+ The TQBitmap can be transformed (translated, scaled, sheared or
+ rotated) using xForm().
+
+ Just like the TQPixmap class, TQBitmap is optimized by the use of
+ \link shclass.html implicit sharing\endlink, so it is very
+ efficient to pass TQBitmap objects as arguments.
+
+ \sa TQPixmap, TQPainter::drawPixmap(), bitBlt(), \link shclass.html Shared Classes\endlink
+*/
+
+
+/*!
+ Constructs a null bitmap.
+
+ \sa TQPixmap::isNull()
+*/
+
+TQBitmap::TQBitmap()
+{
+ data->bitmap = TRUE;
+}
+
+
+/*!
+ Constructs a bitmap with width \a w and height \a h.
+
+ The contents of the bitmap is uninitialized if \a clear is FALSE;
+ otherwise it is filled with pixel value 0 (the TQColor \c
+ TQt::color0).
+
+ The optional \a optimization argument specifies the optimization
+ setting for the bitmap. The default optimization should be used in
+ most cases. Games and other pixmap-intensive applications may
+ benefit from setting this argument; see \l{TQPixmap::Optimization}.
+
+ \sa TQPixmap::setOptimization(), TQPixmap::setDefaultOptimization()
+*/
+
+TQBitmap::TQBitmap( int w, int h, bool clear,
+ TQPixmap::Optimization optimization )
+ : TQPixmap( w, h, 1, optimization )
+{
+ data->bitmap = TRUE;
+ if ( clear )
+ fill( TQt::color0 );
+}
+
+
+/*!
+ \overload
+
+ Constructs a bitmap with the size \a size.
+
+ The contents of the bitmap is uninitialized if \a clear is FALSE;
+ otherwise it is filled with pixel value 0 (the TQColor \c
+ TQt::color0).
+
+ The optional \a optimization argument specifies the optimization
+ setting for the bitmap. The default optimization should be used in
+ most cases. Games and other pixmap-intensive applications may
+ benefit from setting this argument; see \l{TQPixmap::Optimization}.
+*/
+
+TQBitmap::TQBitmap( const TQSize &size, bool clear,
+ TQPixmap::Optimization optimization )
+ : TQPixmap( size, 1, optimization )
+{
+ data->bitmap = TRUE;
+ if ( clear )
+ fill( TQt::color0 );
+}
+
+
+/*!
+ Constructs a bitmap with width \a w and height \a h and sets the
+ contents to \a bits.
+
+ The \a isXbitmap flag should be TRUE if \a bits was generated by
+ the X11 bitmap program. The X bitmap bit order is little endian.
+ The TQImage documentation discusses bit order of monochrome images.
+
+ Example (creates an arrow bitmap):
+ \code
+ uchar arrow_bits[] = { 0x3f, 0x1f, 0x0f, 0x1f, 0x3b, 0x71, 0xe0, 0xc0 };
+ TQBitmap bm( 8, 8, arrow_bits, TRUE );
+ \endcode
+*/
+
+TQBitmap::TQBitmap( int w, int h, const uchar *bits, bool isXbitmap )
+ : TQPixmap( w, h, bits, isXbitmap )
+{
+ data->bitmap = TRUE;
+}
+
+
+/*!
+ \overload
+
+ Constructs a bitmap with the size \a size and sets the contents to
+ \a bits.
+
+ The \a isXbitmap flag should be TRUE if \a bits was generated by
+ the X11 bitmap program. The X bitmap bit order is little endian.
+ The TQImage documentation discusses bit order of monochrome images.
+*/
+
+TQBitmap::TQBitmap( const TQSize &size, const uchar *bits, bool isXbitmap )
+ : TQPixmap( size.width(), size.height(), bits, isXbitmap )
+{
+ data->bitmap = TRUE;
+}
+
+
+/*!
+ Constructs a bitmap that is a copy of \a bitmap.
+*/
+
+TQBitmap::TQBitmap( const TQBitmap &bitmap )
+ : TQPixmap( bitmap )
+{
+}
+
+#ifndef TQT_NO_IMAGEIO
+/*!
+ Constructs a bitmap from the file \a fileName. If the file does
+ not exist or is of an unknown format, the bitmap becomes a null
+ bitmap.
+
+ The parameters \a fileName and \a format are passed on to
+ TQPixmap::load(). Dithering will be performed if the file format
+ uses more than 1 bit per pixel.
+
+ \sa TQPixmap::isNull(), TQPixmap::load(), TQPixmap::loadFromData(),
+ TQPixmap::save(), TQPixmap::imageFormat()
+*/
+
+TQBitmap::TQBitmap( const TQString& fileName, const char *format )
+ : TQPixmap() // Will set bitmap to null bitmap, explicit call for clarity
+{
+ data->bitmap = TRUE;
+ load( fileName, format, Mono );
+}
+#endif
+
+/*!
+ Assigns the bitmap \a bitmap to this bitmap and returns a
+ reference to this bitmap.
+*/
+
+TQBitmap &TQBitmap::operator=( const TQBitmap &bitmap )
+{
+ TQPixmap::operator=(bitmap);
+#if defined(TQT_CHECK_STATE)
+ TQ_ASSERT( data->bitmap );
+#endif
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Assigns the pixmap \a pixmap to this bitmap and returns a
+ reference to this bitmap.
+
+ Dithering will be performed if the pixmap has a TQPixmap::depth()
+ greater than 1.
+*/
+
+TQBitmap &TQBitmap::operator=( const TQPixmap &pixmap )
+{
+ if ( pixmap.isNull() ) { // a null pixmap
+ TQBitmap bm( 0, 0, FALSE, pixmap.optimization() );
+ TQBitmap::operator=(bm);
+ } else if ( pixmap.depth() == 1 ) { // 1-bit pixmap
+ if ( pixmap.isTQBitmap() ) { // another TQBitmap
+ TQPixmap::operator=(pixmap); // shallow assignment
+ } else { // not a TQBitmap, but 1-bit
+ TQBitmap bm( pixmap.size(), FALSE, pixmap.optimization() );
+ bitBlt( &bm, 0,0, &pixmap, 0,0,pixmap.width(),pixmap.height() );
+ TQBitmap::operator=(bm);
+ }
+ } else { // n-bit depth pixmap
+ TQImage image;
+ image = pixmap; // convert pixmap to image
+ *this = image; // will dither image
+ }
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Converts the image \a image to a bitmap and assigns the result to
+ this bitmap. Returns a reference to the bitmap.
+
+ Dithering will be performed if the image has a TQImage::depth()
+ greater than 1.
+*/
+
+TQBitmap &TQBitmap::operator=( const TQImage &image )
+{
+ convertFromImage( image );
+ return *this;
+}
+
+
+#ifndef TQT_NO_PIXMAP_TRANSFORMATION
+/*!
+ Returns a transformed copy of this bitmap by using \a matrix.
+
+ This function does exactly the same as TQPixmap::xForm(), except
+ that it returns a TQBitmap instead of a TQPixmap.
+
+ \sa TQPixmap::xForm()
+*/
+
+TQBitmap TQBitmap::xForm( const TQWMatrix &matrix ) const
+{
+ TQPixmap pm = TQPixmap::xForm( matrix );
+ TQBitmap bm;
+ // Here we fake the pixmap to think it's a TQBitmap. With this trick,
+ // the TQBitmap::operator=(const TQPixmap&) will just refer the
+ // pm.data and we do not need to perform a bitBlt.
+ pm.data->bitmap = TRUE;
+ bm = pm;
+ return bm;
+}
+#endif // TQT_NO_TRANSFORMATIONS
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqbitmap.h b/tqtinterface/qt4/src/kernel/tqbitmap.h
new file mode 100644
index 0000000..e4a2fd9
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqbitmap.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Definition of TQBitmap class
+**
+** Created : 941020
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQBITMAP_H
+#define TQBITMAP_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqpixmap.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qbitmap.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQBitmap : public QBitmap, virtual public TQt
+{
+public:
+ TQBitmap();
+ TQBitmap( int w, int h, bool clear = FALSE, TQPixmap::Optimization o=TQPixmap::DefaultOptim );
+ TQBitmap( const QSize &s, bool clear = FALSE, TQPixmap::Optimization o=TQPixmap::DefaultOptim );
+ TQBitmap( int w, int h, const uchar *bits, bool isXbitmap=FALSE );
+ TQBitmap( const QSize &s, const uchar *bits, bool isXbitmap=FALSE );
+ TQBitmap( const QBitmap &b );
+#ifndef TQT_NO_IMAGEIO
+ TQBitmap( const QString &fileName, const char *format=0 );
+#endif
+// TQBitmap &operator=( const TQBitmap & );
+ TQBitmap operator=( const TQPixmap & );
+ TQBitmap &operator=( const TQImage & );
+
+ QImage convertToImage() const;
+
+ bool convertFromImage(const QImage &img, int flags = Qt::AutoColor);
+ TQBitmap xForm(const QMatrix &matrix) const;
+ const TQBitmap *tqmask() const;
+
+private:
+ void resize_helper(const QSize s);
+public:
+ void resize(const QSize &s);
+ void resize(int width, int height);
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQBitmap : public TQPixmap
+{
+public:
+ TQBitmap();
+ TQBitmap( int w, int h, bool clear = FALSE,
+ TQPixmap::Optimization = TQPixmap::DefaultOptim );
+ TQBitmap( const TQSize &, bool clear = FALSE,
+ TQPixmap::Optimization = TQPixmap::DefaultOptim );
+ TQBitmap( int w, int h, const uchar *bits, bool isXbitmap=FALSE );
+ TQBitmap( const TQSize &, const uchar *bits, bool isXbitmap=FALSE );
+ TQBitmap( const TQBitmap & );
+#ifndef TQT_NO_IMAGEIO
+ TQBitmap( const TQString &fileName, const char *format=0 );
+#endif
+ TQBitmap &operator=( const TQBitmap & );
+ TQBitmap &operator=( const TQPixmap & );
+ TQBitmap &operator=( const TQImage & );
+
+#ifndef TQT_NO_PIXMAP_TRANSFORMATION
+ TQBitmap xForm( const TQWMatrix & ) const;
+#endif
+};
+
+#endif // USE_QT4
+
+#endif // TQBITMAP_H
diff --git a/tqtinterface/qt4/src/kernel/tqbrush.h b/tqtinterface/qt4/src/kernel/tqbrush.h
new file mode 100644
index 0000000..ea5268f
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqbrush.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Definition of TQBrush class
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQBRUSH_H
+#define TQBRUSH_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqcolor.h"
+#include "tqshared.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include "tqpixmap.h"
+#include <Qt/qbrush.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQBrush : public QBrush, virtual public TQt
+{
+public:
+ TQBrush() : QBrush() {}
+ TQBrush( Qt::BrushStyle bs ) : QBrush( bs ) {}
+ TQBrush( const QColor &qc, Qt::BrushStyle bs=Qt::SolidPattern ) : QBrush( qc, bs ) {}
+ TQBrush( const QColor &qc, TQt::BrushStyle bs ) : QBrush( qc, (Qt::BrushStyle)bs ) {}
+ TQBrush( const QColor &qc, const QPixmap &qp ) : QBrush( qc, qp ) {}
+ TQBrush( const QBrush &qb ) : QBrush( qb ) {}
+
+ TQBrush(Qt::GlobalColor color, Qt::BrushStyle bs=Qt::SolidPattern) : QBrush( color, bs ) {}
+ TQBrush(Qt::GlobalColor color, TQt::BrushStyle bs) : QBrush( color, (Qt::BrushStyle)bs ) {}
+ TQBrush(Qt::GlobalColor color, const QPixmap &pixmap) : QBrush( color, pixmap ) {}
+
+ TQBrush(const QPixmap &pixmap) : QBrush( pixmap ) {}
+ TQBrush(const QImage &image) : QBrush( image ) {}
+ TQBrush(const QGradient &gradient) : QBrush( gradient ) {}
+
+ inline operator const QColor&() const;
+ TQPixmap *pixmap() const { return const_cast<TQPixmap*>(&TQT_TQPIXMAP_OBJECT(texture())); }
+ inline void setPixmap(const QPixmap &pixmap) { setTexture(pixmap); }
+
+ // Interoperability
+ static const TQBrush& convertFromQBrush( QBrush& qbr );
+
+ using QBrush::operator=;
+};
+
+// Interoperability
+inline static const TQBrush& convertFromQBrush( const QBrush& qbr ) {
+ return (*static_cast<const TQBrush*>(&qbr));
+}
+
+#else // USE_QT4
+
+class TQ_EXPORT TQBrush: public TQt
+{
+friend class TQPainter;
+public:
+ TQBrush();
+ TQBrush( BrushStyle );
+ TQBrush( const TQColor &, BrushStyle=SolidPattern );
+ TQBrush( const TQColor &, const TQPixmap & );
+ TQBrush( const TQBrush & );
+ ~TQBrush();
+ TQBrush &operator=( const TQBrush & );
+
+ BrushStyle style() const { return data->style; }
+ void setStyle( BrushStyle );
+ const TQColor &color()const { return data->color; }
+ void setColor( const TQColor & );
+ TQPixmap *pixmap() const { return data->pixmap; }
+ void setPixmap( const TQPixmap & );
+
+ bool operator==( const TQBrush &p ) const;
+ bool operator!=( const TQBrush &b ) const
+ { return !(operator==(b)); }
+
+private:
+ TQBrush copy() const;
+ void detach();
+ void init( const TQColor &, BrushStyle );
+ struct TQBrushData : public TQShared { // brush data
+ BrushStyle style;
+ TQColor color;
+ TQPixmap *pixmap;
+ } *data;
+};
+
+
+/*****************************************************************************
+ TQBrush stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQBrush & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQBrush & );
+#endif
+
+#endif // USE_QT4
+
+#endif // TQBRUSH_H
diff --git a/tqtinterface/qt4/src/kernel/tqclipboard.cpp b/tqtinterface/qt4/src/kernel/tqclipboard.cpp
new file mode 100644
index 0000000..9c7a318
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqclipboard.cpp
@@ -0,0 +1,754 @@
+/****************************************************************************
+**
+** Implementation of TQClipboard class
+**
+** Created : 960430
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqclipboard.h"
+
+#ifndef TQT_NO_CLIPBOARD
+
+#include "tqapplication.h"
+#include "tqapplication_p.h"
+#include "tqdragobject.h"
+#include "tqpixmap.h"
+
+// #ifdef USE_QT4
+#if 0
+
+#include "Qt/qbuffer.h"
+
+static TQClipboardPrivate *tqt_tqclipboard_tqcbp = 0;
+
+class TQMimeDataWrapper : public QMimeSource
+{
+public:
+ TQMimeDataWrapper() {}
+
+ const char* format(int n) const;
+ QByteArray encodedData(const char*) const;
+
+ mutable QList<QByteArray> formats;
+ const QMimeData *data;
+};
+
+const char* TQMimeDataWrapper::format(int n) const
+{
+ if (formats.isEmpty()) {
+ QStringList fmts = data->formats();
+ for (int i = 0; i < fmts.size(); ++i)
+ formats.append(fmts.at(i).toLatin1());
+ }
+ if (n < 0 || n >= formats.size())
+ return 0;
+ return formats.at(n).data();
+}
+
+QByteArray TQMimeDataWrapper::encodedData(const char *format) const
+{
+ if (QLatin1String(format) != QLatin1String("application/x-qt-image")){
+ return data->data(QLatin1String(format));
+ } else{
+ QVariant variant = data->imageData();
+ QImage img = qVariantValue<QImage>(variant);
+ QByteArray ba;
+ QBuffer buffer(&ba);
+ buffer.open(QIODevice::WriteOnly);
+ img.save(&buffer, "PNG");
+ return ba;
+ }
+}
+
+class TQMimeSourceWrapper : public QMimeData
+{
+public:
+ TQMimeSourceWrapper(QClipboard::Mode m);
+ ~TQMimeSourceWrapper();
+
+ bool hasFormat(const QString &mimetype) const;
+ QStringList formats() const;
+
+protected:
+ QVariant retrieveData(const QString &mimetype, QVariant::Type) const;
+private:
+ QClipboard::Mode mode;
+ QMimeSource *source;
+};
+
+QVariant TQMimeSourceWrapper::retrieveData(const QString &mimetype, QVariant::Type) const
+{
+ if (source == 0) {
+ printf("[WARNING] TQMimeSourceWrapper::retrieveData source==0 [check tqt_tqclipboard_tqcbp->compat_data[mode] assignment]\n\r");
+ return QString();
+ }
+ return source->encodedData(mimetype.toLatin1());
+}
+
+bool TQMimeSourceWrapper::hasFormat(const QString &mimetype) const
+{
+ if (source == 0) {
+ printf("[WARNING] TQMimeSourceWrapper::hasFormat source==0 [check tqt_tqclipboard_tqcbp->compat_data[mode] assignment]\n\r");
+ return false;
+ }
+ return source->provides(mimetype.toLatin1());
+}
+
+QStringList TQMimeSourceWrapper::formats() const
+{
+ QStringList fmts;
+ int i = 0;
+ const char *fmt;
+ if (source == 0) {
+ printf("[WARNING] TQMimeSourceWrapper::formats source==0 [check tqt_tqclipboard_tqcbp->compat_data[mode] assignment]\n\r");
+ return QStringList();
+ }
+ while ((fmt = source->format(i))) {
+ fmts.append(QLatin1String(fmt));
+ ++i;
+ }
+ return fmts;
+}
+
+class TQClipboardPrivate
+{
+public:
+ TQClipboardPrivate() {
+ for (int i = 0; i <= QClipboard::LastMode; ++i) {
+ compat_data[i] = 0;
+ wrapper[i] = new TQMimeDataWrapper();
+ }
+ }
+ ~TQClipboardPrivate() {
+ for (int i = 0; i <= QClipboard::LastMode; ++i) {
+ delete wrapper[i];
+ delete compat_data[i];
+ }
+ }
+
+ mutable TQMimeDataWrapper *wrapper[QClipboard::LastMode + 1];
+ mutable QMimeSource *compat_data[QClipboard::LastMode + 1];
+};
+
+inline TQMimeSourceWrapper::TQMimeSourceWrapper(QClipboard::Mode m)
+ : QMimeData()
+{
+ if (tqt_tqclipboard_tqcbp == 0) {
+ tqt_tqclipboard_tqcbp = new TQClipboardPrivate();
+ }
+
+ mode = m;
+ source = tqt_tqclipboard_tqcbp->compat_data[mode];
+}
+
+inline TQMimeSourceWrapper::~TQMimeSourceWrapper()
+{
+ if (tqt_tqclipboard_tqcbp->compat_data[mode] == source)
+ tqt_tqclipboard_tqcbp->compat_data[mode] = 0;
+ if (source != 0) delete source;
+}
+
+TQMimeSource *TQClipboard::data(Mode mode) const
+{
+// Q_D(const QClipboard);
+
+// if (supportsMode(mode) == false)
+// return 0;
+//
+// if (d->compat_data[mode])
+// return d->compat_data[mode];
+//
+// d->wrapper[mode]->data = mimeData(mode);
+// return d->wrapper[mode];
+
+ // Separate TQt implementation follows
+
+ if (tqt_tqclipboard_tqcbp == 0) {
+ tqt_tqclipboard_tqcbp = new TQClipboardPrivate();
+ }
+
+ tqt_tqclipboard_tqcbp->wrapper[mode]->data = mimeData(mode);
+ return TQT_TQMIMESOURCE(tqt_tqclipboard_tqcbp->wrapper[mode]);
+}
+
+
+/*!
+ \fn void QClipboard::setData(QMimeSource *src, Mode mode)
+ \compat
+
+ Use setMimeData() instead.
+*/
+void TQClipboard::setData(QMimeSource *source, Mode mode)
+{
+// Q_D(QClipboard);
+
+// if (supportsMode(mode) == false)
+// return;
+//
+// d->compat_data[mode] = source;
+// setMimeData(new TQMimeSourceWrapper(d, mode), mode);
+
+ // Separate TQt implementation follows
+
+ if (tqt_tqclipboard_tqcbp == 0) {
+ tqt_tqclipboard_tqcbp = new TQClipboardPrivate();
+ }
+
+ setMimeData(new TQMimeSourceWrapper(mode), mode);
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQClipboard tqclipboard.h
+ \brief The TQClipboard class provides access to the window system clipboard.
+
+ \ingroup io
+ \ingroup environment
+ \mainclass
+
+ The clipboard offers a simple mechanism to copy and paste data
+ between applications.
+
+ TQClipboard supports the same data types that TQDragObject does, and
+ uses similar mechanisms. For advanced clipboard usage
+ read \link dnd.html the drag-and-drop documentation\endlink.
+
+ There is a single TQClipboard object in an application, and you can
+ access it using TQApplication::clipboard().
+
+ Example:
+ \code
+ TQClipboard *cb = TQApplication::clipboard();
+
+ // Copy text from the clipboard (paste)
+ TQString text = cb->text(TQClipboard::Clipboard);
+ if ( !text.isNull() )
+ qDebug( "The clipboard tqcontains: " + text );
+
+ // Copy text into the clipboard
+ cb->setText( "This text can be pasted by other programs",
+ TQClipboard::Clipboard );
+ \endcode
+
+ TQClipboard features some convenience functions to access common data
+ types: setText() allows the exchange of Unicode text and
+ setPixmap() and setImage() allows the exchange of TQPixmaps
+ and TQImages between applications. The setData() function is the
+ ultimate in flexibility: it allows you to add any TQMimeSource into the
+ clipboard. There are corresponding getters for each of these, e.g.
+ text(), image() and pixmap().
+
+ You can clear the clipboard by calling clear().
+
+
+ \section1 Platform Specific Information
+
+ \section2 X11
+
+ \list
+
+ \i The X11 Window System has the concept of a separate selection
+ and clipboard. When text is selected, it is immediately available
+ as the global mouse selection. The global mouse selection may
+ later be copied to the clipboard. By convention, the middle mouse
+ button is used to paste the global mouse selection.
+
+ \i X11 also has the concept of ownership; if you change the
+ selection within a window, X11 will only notify the owner and the
+ previous owner of the change, i.e. it will not notify all
+ applications that the selection or clipboard data changed.
+
+ \i Lastly, the X11 clipboard is event driven, i.e. the clipboard
+ will not function properly if the event loop is not running.
+ Similarly, it is recommended that the contents of the clipboard
+ are stored or retrieved in direct response to user-input events,
+ e.g. mouse button or key presses and releases. You should not
+ store or retrieve the clipboard contents in response to timer or
+ non-user-input events.
+
+ \endlist
+
+ \section2 Windows
+
+ \list
+
+ \i Microsoft Windows does not support the global mouse selection;
+ it only supports the global clipboard, e.g. Windows only adds text
+ to the clipboard when an explicit copy or cut is made.
+
+ \i Windows does not have the concept of ownership; the clipboard
+ is a fully global resource so all applications are notified of
+ changes.
+
+ \endlist
+
+ See the multiclip example in the \e{TQt Designer} examples
+ directory for an example of a multiplatform clipboard application
+ that also demonstrates selection handling.
+*/
+
+
+/*!
+ \internal
+
+ Constructs a clipboard object.
+
+ Do not call this function.
+
+ Call TQApplication::clipboard() instead to get a pointer to the
+ application's global clipboard object.
+
+ There is only one clipboard in the window system, and creating
+ more than one object to represent it is almost certainly an error.
+*/
+
+TQClipboard::TQClipboard( TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name )
+{
+ // nothing
+}
+
+#ifndef TQ_WS_WIN32
+/*!
+ \internal
+
+ Destroys the clipboard.
+
+ You should never delete the clipboard. TQApplication will do this
+ when the application terminates.
+*/
+TQClipboard::~TQClipboard()
+{
+}
+#endif
+
+/*!
+ \fn void TQClipboard::dataChanged()
+
+ This signal is emitted when the clipboard data is changed.
+*/
+
+/*!
+ \fn void TQClipboard::selectionChanged()
+
+ This signal is emitted when the selection is changed. This only
+ applies to windowing systems that support selections, e.g. X11.
+ Windows doesn't support selections.
+*/
+
+/*! \enum TQClipboard::Mode
+ \keyword clipboard mode
+
+ This enum type is used to control which part of the system clipboard is
+ used by TQClipboard::data(), TQClipboard::setData() and related functions.
+
+ \value Clipboard indicates that data should be stored and retrieved from
+ the global clipboard.
+
+ \value Selection indicates that data should be stored and retrieved from
+ the global mouse selection.
+
+ \e Note: Support for \c Selection is provided only on systems with a
+ global mouse selection (e.g. X11).
+
+ \sa TQClipboard::supportsSelection()
+*/
+
+
+/*****************************************************************************
+ TQApplication member functions related to TQClipboard.
+ *****************************************************************************/
+
+#ifndef TQT_NO_MIMECLIPBOARD
+// text handling is done directly in qclipboard_qws, for now
+
+/*!
+ \overload
+
+ Returns the clipboard text in subtype \a subtype, or a null string
+ if the clipboard does not contain any text. If \a subtype is null,
+ any subtype is acceptable, and \a subtype is set to the chosen
+ subtype.
+
+ The \a mode argument is used to control which part of the system
+ clipboard is used. If \a mode is TQClipboard::Clipboard, the
+ text is retrieved from the global clipboard. If \a mode is
+ TQClipboard::Selection, the text is retrieved from the global
+ mouse selection.
+
+ Common values for \a subtype are "plain" and "html".
+
+ \sa setText(), data(), TQString::operator!()
+*/
+TQString TQClipboard::text( TQCString &subtype, Mode mode ) const
+{
+ TQString r;
+ TQTextDrag::decode( data( mode ) ,r, subtype );
+ return r;
+}
+
+/*!
+ \overload
+
+ Returns the clipboard text in subtype \a subtype, or a null string
+ if the clipboard does not contain any text. This function uses the
+ TQClipboard::text() function which takes a TQClipboard::Mode
+ argument. The value of the mode argument is determined by the
+ return value of selectionModeEnabled(). If selectionModeEnabled()
+ returns TRUE, the mode argument is TQClipboard::Selection,
+ otherwise the mode argument is TQClipboard::Clipboard.
+*/
+// ### remove 4.0
+TQString TQClipboard::text( TQCString& subtype ) const
+{
+ return text( subtype, selectionModeEnabled() ? Selection : Clipboard );
+}
+
+/*!
+ Returns the clipboard text as plain text, or a null string if the
+ clipboard does not contain any text.
+
+ The \a mode argument is used to control which part of the system
+ clipboard is used. If \a mode is TQClipboard::Clipboard, the
+ text is retrieved from the global clipboard. If \a mode is
+ TQClipboard::Selection, the text is retrieved from the global
+ mouse selection.
+
+ \sa setText(), data(), TQString::operator!()
+*/
+TQString TQClipboard::text( Mode mode ) const
+{
+ TQCString subtype = "plain";
+ return text( subtype, mode );
+}
+
+/*!
+ \overload
+
+ This function uses the TQClipboard::text() function which takes
+ a TQClipboard::Mode argument. The value of the mode argument is
+ determined by the return value of selectionModeEnabled().
+ If selectionModeEnabled() returns TRUE, the mode argument is
+ TQClipboard::Selection, otherwise the mode argument is
+ TQClipboard::Clipboard.
+*/
+
+TQString TQClipboard::text() const
+{
+ return text( selectionModeEnabled() ? Selection : Clipboard );
+}
+
+ /*!
+ Copies \a text into the clipboard as plain text.
+
+ The \a mode argument is used to control which part of the system
+ clipboard is used. If \a mode is TQClipboard::Clipboard, the
+ text is stored in the global clipboard. If \a mode is
+ TQClipboard::Selection, the text is stored in the global
+ mouse selection.
+
+ \sa text(), setData()
+*/
+
+void TQClipboard::setText( const TQString &text, Mode mode )
+{
+ setData( new TQTextDrag(text), mode );
+}
+
+/*!
+ \overload
+
+ This function uses the TQClipboard::setText() function which takes
+ a TQClipboard::Mode argument. The value of the mode argument is
+ determined by the return value of selectionModeEnabled().
+ If selectionModeEnabled() returns TRUE, the mode argument is
+ TQClipboard::Selection, otherwise the mode argument is
+ TQClipboard::Clipboard.
+*/
+// ### remove 4.0
+void TQClipboard::setText( const TQString &text )
+{
+ setText( text, selectionModeEnabled() ? Selection : Clipboard );
+}
+
+/*!
+ Returns the clipboard image, or returns a null image if the
+ clipboard does not contain an image or if it tqcontains an image in
+ an unsupported image format.
+
+ The \a mode argument is used to control which part of the system
+ clipboard is used. If \a mode is TQClipboard::Clipboard, the
+ image is retrieved from the global clipboard. If \a mode is
+ TQClipboard::Selection, the image is retrieved from the global
+ mouse selection.
+
+ \sa setImage() pixmap() data(), TQImage::isNull()
+*/
+TQImage TQClipboard::image( Mode mode ) const
+{
+ TQImage r;
+ TQImageDrag::decode( data( mode ), r );
+ return r;
+}
+
+/*!
+ \overload
+
+ This function uses the TQClipboard::image() function which takes
+ a TQClipboard::Mode argument. The value of the mode argument is
+ determined by the return value of selectionModeEnabled().
+ If selectionModeEnabled() returns TRUE, the mode argument is
+ TQClipboard::Selection, otherwise the mode argument is
+ TQClipboard::Clipboard.
+*/
+// ### remove 4.0
+TQImage TQClipboard::image() const
+{
+ return image( selectionModeEnabled() ? Selection : Clipboard );
+}
+
+/*!
+ Copies \a image into the clipboard.
+
+ The \a mode argument is used to control which part of the system
+ clipboard is used. If \a mode is TQClipboard::Clipboard, the
+ image is stored in the global clipboard. If \a mode is
+ TQClipboard::Selection, the data is stored in the global
+ mouse selection.
+
+ This is shorthand for:
+ \code
+ setData( new TQImageDrag(image), mode )
+ \endcode
+
+ \sa image(), setPixmap() setData()
+*/
+void TQClipboard::setImage( const TQImage &image, Mode mode )
+{
+ setData( new TQImageDrag( image ), mode );
+}
+
+/*!
+ \overload
+
+ This function uses the TQClipboard::setImage() function which takes
+ a TQClipboard::Mode argument. The value of the mode argument is
+ determined by the return value of selectionModeEnabled().
+ If selectionModeEnabled() returns TRUE, the mode argument is
+ TQClipboard::Selection, otherwise the mode argument is
+ TQClipboard::Clipboard.
+*/
+// ### remove 4.0
+void TQClipboard::setImage( const TQImage &image )
+{
+ setImage( image, selectionModeEnabled() ? Selection : Clipboard );
+}
+
+/*!
+ Returns the clipboard pixmap, or null if the clipboard does not
+ contain a pixmap. Note that this can lose information. For
+ example, if the image is 24-bit and the display is 8-bit, the
+ result is converted to 8 bits, and if the image has an alpha
+ channel, the result just has a tqmask.
+
+ The \a mode argument is used to control which part of the system
+ clipboard is used. If \a mode is TQClipboard::Clipboard, the
+ pixmap is retrieved from the global clipboard. If \a mode is
+ TQClipboard::Selection, the pixmap is retrieved from the global
+ mouse selection.
+
+ \sa setPixmap() image() data() TQPixmap::convertFromImage().
+*/
+TQPixmap TQClipboard::pixmap( Mode mode ) const
+{
+ TQPixmap r;
+ TQImageDrag::decode( data( mode ), r );
+ return r;
+}
+
+/*!
+ \overload
+
+ This function uses the TQClipboard::pixmap() function which takes
+ a TQClipboard::Mode argument. The value of the mode argument is
+ determined by the return value of selectionModeEnabled().
+ If selectionModeEnabled() returns TRUE, the mode argument is
+ TQClipboard::Selection, otherwise the mode argument is
+ TQClipboard::Clipboard.
+*/
+// ### remove 4.0
+TQPixmap TQClipboard::pixmap() const
+{
+ return pixmap( selectionModeEnabled() ? Selection : Clipboard );
+}
+
+/*!
+ Copies \a pixmap into the clipboard. Note that this is slower
+ than setImage() because it needs to convert the TQPixmap to a
+ TQImage first.
+
+ The \a mode argument is used to control which part of the system
+ clipboard is used. If \a mode is TQClipboard::Clipboard, the
+ pixmap is stored in the global clipboard. If \a mode is
+ TQClipboard::Selection, the pixmap is stored in the global
+ mouse selection.
+
+ \sa pixmap() setImage() setData()
+*/
+void TQClipboard::setPixmap( const TQPixmap &pixmap, Mode mode )
+{
+ // *could* just use the handle, but that is X hackery, MIME is better.
+ setData( new TQImageDrag( pixmap.convertToImage() ), mode );
+}
+
+/*!
+ \overload
+
+ This function uses the TQClipboard::setPixmap() function which takes
+ a TQClipboard::Mode argument. The value of the mode argument is
+ determined by the return value of selectionModeEnabled().
+ If selectionModeEnabled() returns TRUE, the mode argument is
+ TQClipboard::Selection, otherwise the mode argument is
+ TQClipboard::Clipboard.
+*/
+// ### remove 4.0
+void TQClipboard::setPixmap( const TQPixmap &pixmap )
+{
+ setPixmap( pixmap, selectionModeEnabled() ? Selection : Clipboard );
+}
+
+
+/*! \fn TQMimeSource *TQClipboard::data( Mode mode ) const
+ Returns a reference to a TQMimeSource representation of the current
+ clipboard data.
+
+ The \a mode argument is used to control which part of the system
+ clipboard is used. If \a mode is TQClipboard::Clipboard, the
+ data is retrieved from the global clipboard. If \a mode is
+ TQClipboard::Selection, the data is retrieved from the global
+ mouse selection.
+
+ \sa setData()
+*/
+
+/*!
+ \overload
+
+ This function uses the TQClipboard::data() function which takes
+ a TQClipboard::Mode argument. The value of the mode argument is
+ determined by the return value of selectionModeEnabled().
+ If selectionModeEnabled() returns TRUE, the mode argument is
+ TQClipboard::Selection, otherwise the mode argument is
+ TQClipboard::Clipboard.
+*/
+// ### remove 4.0
+TQMimeSource *TQClipboard::data() const
+{
+ return data( selectionModeEnabled() ? Selection : Clipboard );
+}
+
+/*! \fn void TQClipboard::setData( TQMimeSource *src, Mode mode )
+ Sets the clipboard data to \a src. Ownership of the data is
+ transferred to the clipboard. If you want to remove the data
+ either call clear() or call setData() again with new data.
+
+ The \a mode argument is used to control which part of the system
+ clipboard is used. If \a mode is TQClipboard::Clipboard, the
+ data is retrieved from the global clipboard. If \a mode is
+ TQClipboard::Selection, the data is retrieved from the global
+ mouse selection.
+
+ The TQDragObject subclasses are reasonable objects to put into the
+ clipboard (but do not try to call TQDragObject::drag() on the same
+ object). Any TQDragObject placed in the clipboard should have a
+ tqparent of 0. Do not put TQDragMoveEvent or TQDropEvent subclasses in
+ the clipboard, as they do not belong to the event handler which
+ receives them.
+
+ The setText(), setImage() and setPixmap() functions are simpler
+ wrappers for setting text, image and pixmap data respectively.
+
+ \sa data()
+*/
+
+/*!
+ \overload
+
+ This function uses the TQClipboard::setData() function which takes
+ a TQClipboard::Mode argument. The value of the mode argument is
+ determined by the return value of selectionModeEnabled().
+ If selectionModeEnabled() returns TRUE, the mode argument is
+ TQClipboard::Selection, otherwise the mode argument is
+ TQClipboard::Clipboard.
+*/
+// ### remove 4.0
+void TQClipboard::setData( TQMimeSource *src )
+{
+ setData( src, selectionModeEnabled() ? Selection : Clipboard );
+}
+
+/*! \fn void TQClipboard::clear( Mode mode )
+ Clear the clipboard contents.
+
+ The \a mode argument is used to control which part of the system
+ clipboard is used. If \a mode is TQClipboard::Clipboard, this
+ function clears the the global clipboard contents. If \a mode is
+ TQClipboard::Selection, this function clears the global mouse
+ selection contents.
+
+ \sa TQClipboard::Mode, supportsSelection()
+*/
+
+/*!
+ \overload
+
+ This function uses the TQClipboard::clear() function which takes
+ a TQClipboard::Mode argument. The value of the mode argument is
+ determined by the return value of selectionModeEnabled().
+ If selectionModeEnabled() returns TRUE, the mode argument is
+ TQClipboard::Selection, otherwise the mode argument is TQClipboard::Clipboard.
+*/
+// ### remove 4.0
+void TQClipboard::clear()
+{
+ clear( selectionModeEnabled() ? Selection : Clipboard );
+}
+
+#endif // TQT_NO_MIMECLIPBOARD
+#endif // TQT_NO_CLIPBOARD
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqclipboard.h b/tqtinterface/qt4/src/kernel/tqclipboard.h
new file mode 100644
index 0000000..8e49f8d
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqclipboard.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Definition of TQClipboard class
+**
+** Created : 960430
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCLIPBOARD_H
+#define TQCLIPBOARD_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqobject.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_CLIPBOARD
+
+#ifdef USE_QT4
+
+#include <Qt/qclipboard.h>
+
+#endif
+
+// #ifdef USE_QT4
+#if 0
+
+class TQClipboardPrivate;
+
+// extern TQClipboardPrivate *tqt_tqclipboard_tqcbp;
+
+class TQ_EXPORT TQClipboard : public QClipboard, virtual public TQt
+{
+public:
+// TQClipboard( TQT_BASE_OBJECT_NAME *tqparent=0, const char *name=0 ) : QClipboard( tqparent ) { setObjectName(QString::fromAscii(name)); }
+
+ TQMimeSource *data(Mode mode = Clipboard) const;
+ void setData(QMimeSource*, Mode mode = Clipboard);
+ TQString tqtext( TQCString& subtype, Mode mode ) const { TQString str = TQString(subtype); return QClipboard::text(str, (Mode)mode); }
+
+ #warning FIXME TQClipboard::setSelectionMode() and friends have no effect!
+ void setSelectionMode(bool enable);
+ bool selectionModeEnabled() const;
+};
+
+#else // USE_QT4
+
+class TQMimeSource;
+
+class TQ_EXPORT TQClipboard : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+private:
+ TQClipboard( TQObject *tqparent=0, const char *name=0 );
+ ~TQClipboard();
+
+public:
+ enum Mode { Clipboard, Selection };
+
+ void clear( Mode mode ); // ### default arg = Clipboard in 4.0
+ void clear(); // ### remove 4.0
+
+ bool supportsSelection() const;
+ bool ownsSelection() const;
+ bool ownsClipboard() const;
+
+ void setSelectionMode(bool enable); // ### remove 4.0
+ bool selectionModeEnabled() const; // ### remove 4.0
+
+ // ### default arg mode = Clipboard in 4.0 for all of these
+ TQString text( Mode mode ) const;
+ TQString text( TQCString& subtype, Mode mode ) const;
+ void setText( const TQString &, Mode mode );
+
+#ifndef TQT_NO_MIMECLIPBOARD
+ TQMimeSource *data( Mode mode ) const;
+ void setData( TQMimeSource*, Mode mode );
+
+ TQImage image( Mode mode ) const;
+ TQPixmap pixmap( Mode mode ) const;
+ void setImage( const TQImage &, Mode mode );
+ void setPixmap( const TQPixmap &, Mode mode );
+#endif
+
+ // ### remove all of these in 4.0
+ TQString text() const;
+ TQString text(TQCString& subtype) const;
+ void setText( const TQString &);
+
+#ifndef TQT_NO_MIMECLIPBOARD
+ TQMimeSource *data() const;
+ void setData( TQMimeSource* );
+
+ TQImage image() const;
+ TQPixmap pixmap() const;
+ void setImage( const TQImage & );
+ void setPixmap( const TQPixmap & );
+#endif
+
+Q_SIGNALS:
+ void selectionChanged();
+ void dataChanged();
+
+private Q_SLOTS:
+ void ownerDestroyed();
+
+protected:
+ void connectNotify( const char * );
+ bool event( TQEvent * );
+
+ friend class TQApplication;
+ friend class TQBaseApplication;
+ friend class TQDragManager;
+ friend class TQMimeSource;
+
+private:
+#if defined(TQ_WS_MAC)
+ void loadScrap(bool convert);
+ void saveScrap();
+#endif
+
+ // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQClipboard( const TQClipboard & );
+ TQClipboard &operator=( const TQClipboard & );
+#endif
+};
+
+#endif // USE_QT4
+
+#endif // TQT_NO_CLIPBOARD
+
+#endif // TQCLIPBOARD_H \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp b/tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp
new file mode 100644
index 0000000..14e7f08
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqclipboard_x11.cpp
@@ -0,0 +1,2020 @@
+/****************************************************************************
+**
+** Implementation of TQClipboard class for X11
+**
+** Created : 960430
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// #define TQCLIPBOARD_DEBUG
+// #define TQCLIPBOARD_DEBUG_VERBOSE
+
+#ifdef TQCLIPBOARD_DEBUG
+# define TQDEBUG qDebug
+#else
+# define TQDEBUG if (FALSE) qDebug
+#endif
+
+#ifdef TQCLIPBOARD_DEBUG_VERBOSE
+# define VTQDEBUG qDebug
+#else
+# define VTQDEBUG if (FALSE) qDebug
+#endif
+
+#include "tqplatformdefs.h"
+
+// POSIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+#include "tqclipboard.h"
+
+#ifndef TQT_NO_CLIPBOARD
+
+#include "tqapplication.h"
+#include "tqeventloop.h"
+#include "tqbitmap.h"
+#include "tqdatetime.h"
+#include "tqdragobject.h"
+#include "tqbuffer.h"
+#include "tqtextcodec.h"
+#include "tqvaluelist.h"
+#include "tqmap.h"
+#include "tqt_x11_p.h"
+#include "tqapplication_p.h"
+
+// #ifdef USE_QT4
+#if 0
+
+/*****************************************************************************
+ Internal TQClipboard functions for X11.
+ *****************************************************************************/
+
+// from qapplication_x11.cpp
+typedef int (*QX11EventFilter) (XEvent*);
+extern QX11EventFilter qt_set_x11_event_filter (QX11EventFilter filter);
+
+extern Time qt_x_incr; // def. in qapplication_x11.cpp
+extern Atom qt_xa_clipboard;
+extern Atom qt_selection_property;
+extern Atom qt_clipboard_sentinel;
+extern Atom qt_selection_sentinel;
+extern Atom qt_utf8_string;
+
+// from qdnd_x11.cpp
+extern Atom* qt_xdnd_str_to_atom( const char *mimeType );
+extern const char* qt_xdnd_atom_to_str( Atom );
+
+
+static int clipboard_timeout = 5000; // 5s timeout on clipboard operations
+
+static TQWidget * owner = 0;
+static TQWidget *requestor = 0;
+static bool inSelectionMode_obsolete = FALSE; // ### remove 4.0
+static bool timer_event_clear = FALSE;
+static int timer_id = 0;
+
+static int pending_timer_id = 0;
+static bool pending_clipboard_changed = FALSE;
+static bool pending_selection_changed = FALSE;
+
+
+// event capture mechanism for qt_xclb_wait_for_event
+static bool waiting_for_data = FALSE;
+static bool has_captured_event = FALSE;
+static Window capture_event_win = None;
+static int capture_event_type = -1;
+static XEvent captured_event;
+
+// event filter function... captures interesting events while
+// qt_xclb_wait_for_event is running the event loop
+static int qt_xclb_event_filter(XEvent *event)
+{
+ if (event->xany.type == capture_event_type &&
+ event->xany.window == capture_event_win) {
+ VTQDEBUG( "TQClipboard: event_filter(): caught event type %d", event->type );
+ has_captured_event = TRUE;
+ captured_event = *event;
+ return 1;
+ }
+
+ return 0;
+}
+
+static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer)
+{
+ return ((e->type == SelectionRequest && (e->xselectionrequest.selection == XA_PRIMARY
+ || e->xselectionrequest.selection == qt_xa_clipboard))
+ || (e->type == SelectionClear && (e->xselectionclear.selection == XA_PRIMARY
+ || e->xselectionclear.selection == qt_xa_clipboard)));
+}
+
+bool qt_xclb_wait_for_event( Display *dpy, Window win, int type, XEvent *event,
+ int timeout )
+{
+ TQTime started = TQTime::currentTime();
+ TQTime now = started;
+
+ if (tqApp->eventLoop()->inherits("TQMotif")) { // yes yes, evil hack, we know
+ if ( waiting_for_data )
+ qFatal( "TQClipboard: internal error, qt_xclb_wait_for_event recursed" );
+
+ waiting_for_data = TRUE;
+ has_captured_event = FALSE;
+ capture_event_win = win;
+ capture_event_type = type;
+
+ QX11EventFilter old_event_filter = qt_set_x11_event_filter(qt_xclb_event_filter);
+
+ do {
+ if ( XCheckTypedWindowEvent(dpy,win,type,event) ) {
+ waiting_for_data = FALSE;
+ qt_set_x11_event_filter(old_event_filter);
+ return TRUE;
+ }
+
+ now = TQTime::currentTime();
+ if ( started > now ) // crossed midnight
+ started = now;
+
+ // 0x08 == ExcludeTimers for X11 only
+ tqApp->eventLoop()->processEvents( TQEventLoop::ExcludeUserInput |
+ TQEventLoop::ExcludeSocketNotifiers |
+ TQEventLoop::WaitForMore | 0x08 );
+
+ if ( has_captured_event ) {
+ waiting_for_data = FALSE;
+ *event = captured_event;
+ qt_set_x11_event_filter(old_event_filter);
+ return TRUE;
+ }
+ } while ( started.msecsTo(now) < timeout );
+
+ waiting_for_data = FALSE;
+ qt_set_x11_event_filter(old_event_filter);
+
+ return FALSE;
+ }
+
+ bool flushed = FALSE;
+ do {
+ if ( XCheckTypedWindowEvent(dpy,win,type,event) )
+ return TRUE;
+
+ // process other clipboard events, since someone is probably requesting data from us
+ XEvent e;
+ if (XCheckIfEvent(dpy, &e, checkForClipboardEvents, 0))
+ tqApp->x11ProcessEvent(&e);
+
+ now = TQTime::currentTime();
+ if ( started > now ) // crossed midnight
+ started = now;
+
+ if(!flushed) {
+ XFlush( dpy );
+ flushed = TRUE;
+ }
+
+ // sleep 50ms, so we don't use up CPU cycles all the time.
+ struct timeval usleep_tv;
+ usleep_tv.tv_sec = 0;
+ usleep_tv.tv_usec = 50000;
+ select(0, 0, 0, 0, &usleep_tv);
+ } while ( started.msecsTo(now) < timeout );
+
+ return FALSE;
+}
+
+static inline int maxSelectionIncr( Display *dpy )
+{ return XMaxRequestSize(dpy) > 65536 ? 65536*4 : XMaxRequestSize(dpy)*4 - 100; }
+
+// uglyhack: externed into qt_xdnd.cpp. qt is really not designed for
+// single-platform, multi-purpose blocks of code...
+bool qt_xclb_read_property( Display *dpy, Window win, Atom property,
+ bool deleteProperty,
+ TQByteArray *buffer, int *size, Atom *type,
+ int *format, bool nullterm )
+{
+ int maxsize = maxSelectionIncr(dpy);
+ ulong bytes_left; // bytes_after
+ ulong length; // nitems
+ uchar *data;
+ Atom dummy_type;
+ int dummy_format;
+ int r;
+
+ if ( !type ) // allow null args
+ type = &dummy_type;
+ if ( !format )
+ format = &dummy_format;
+
+ // Don't read anything, just get the size of the property data
+ r = XGetWindowProperty( dpy, win, property, 0, 0, False,
+ AnyPropertyType, type, format,
+ &length, &bytes_left, &data );
+ if (r != Success || (type && *type == None)) {
+ buffer->resize( 0 );
+ return FALSE;
+ }
+ XFree( (char*)data );
+
+ int offset = 0, buffer_offset = 0, format_inc = 1, proplen = bytes_left;
+
+ VTQDEBUG("TQClipboard: read_property(): initial property length: %d", proplen);
+
+ switch (*format) {
+ case 8:
+ default:
+ format_inc = sizeof(char) / 1;
+ break;
+
+ case 16:
+ format_inc = sizeof(short) / 2;
+ proplen *= sizeof(short) / 2;
+ break;
+
+ case 32:
+ format_inc = sizeof(long) / 4;
+ proplen *= sizeof(long) / 4;
+ break;
+ }
+
+ bool ok = buffer->tqresize( proplen + (nullterm ? 1 : 0) );
+
+ VTQDEBUG("TQClipboard: read_property(): buffer resized to %d", buffer->size());
+
+ if ( ok ) {
+ // could allocate buffer
+
+ while ( bytes_left ) {
+ // more to read...
+
+ r = XGetWindowProperty( dpy, win, property, offset, maxsize/4,
+ False, AnyPropertyType, type, format,
+ &length, &bytes_left, &data );
+ if (r != Success || (type && *type == None))
+ break;
+
+ offset += length / (32 / *format);
+ length *= format_inc * (*format) / 8;
+
+ // Here we check if we get a buffer overflow and tries to
+ // recover -- this shouldn't normally happen, but it doesn't
+ // hurt to be defensive
+ if (buffer_offset + length > buffer->size()) {
+ length = buffer->size() - buffer_offset;
+
+ // escape loop
+ bytes_left = 0;
+ }
+
+ memcpy(buffer->data() + buffer_offset, data, length);
+ buffer_offset += length;
+
+ XFree( (char*)data );
+ }
+
+ static Atom xa_compound_text = *qt_xdnd_str_to_atom( "COMPOUND_TEXT" );
+ if ( *format == 8 && *type == xa_compound_text ) {
+ // convert COMPOUND_TEXT to a multibyte string
+ XTextProperty textprop;
+ textprop.encoding = *type;
+ textprop.format = *format;
+ textprop.nitems = length;
+ textprop.value = (unsigned char *) buffer->data();
+
+ char **list_ret = 0;
+ int count;
+ if ( XmbTextPropertyToTextList( dpy, &textprop, &list_ret,
+ &count ) == Success &&
+ count && list_ret ) {
+ offset = strlen( list_ret[0] );
+ buffer->resize( offset + ( nullterm ? 1 : 0 ) );
+ memcpy( buffer->data(), list_ret[0], offset );
+ }
+ if (list_ret) XFreeStringList(list_ret);
+ }
+
+ // zero-terminate (for text)
+ if (nullterm)
+ buffer->tqat(buffer_offset) = '\0';
+ }
+
+ // correct size, not 0-term.
+ if ( size )
+ *size = buffer_offset;
+
+ VTQDEBUG("TQClipboard: read_property(): buffer size %d, buffer offset %d, offset %d",
+ buffer->size(), buffer_offset, offset);
+
+ if ( deleteProperty )
+ XDeleteProperty( dpy, win, property );
+
+ XFlush( dpy );
+
+ return ok;
+}
+
+// this is externed into qt_xdnd.cpp too.
+TQByteArray qt_xclb_read_incremental_property( Display *dpy, Window win,
+ Atom property, int nbytes,
+ bool nullterm )
+{
+ XEvent event;
+
+ TQByteArray buf;
+ TQByteArray tmp_buf;
+ bool alloc_error = FALSE;
+ int length;
+ int offset = 0;
+
+ if ( nbytes > 0 ) {
+ // Reserve buffer + zero-terminator (for text data)
+ // We want to complete the INCR transfer even if we cannot
+ // allocate more memory
+ alloc_error = !buf.tqresize(nbytes+1);
+ }
+
+ for (;;) {
+ XFlush( dpy );
+ if ( !qt_xclb_wait_for_event(dpy,win,PropertyNotify,&event,clipboard_timeout) )
+ break;
+ if ( event.xproperty.atom != property ||
+ event.xproperty.state != PropertyNewValue )
+ continue;
+ if ( qt_xclb_read_property(dpy, win, property, TRUE, &tmp_buf,
+ &length,0, 0, FALSE) ) {
+ if ( length == 0 ) { // no more data, we're done
+ if ( nullterm ) {
+ buf.resize( offset+1 );
+ buf.tqat( offset ) = '\0';
+ } else {
+ buf.resize(offset);
+ }
+ return buf;
+ } else if ( !alloc_error ) {
+ if ( offset+length > (int)buf.size() ) {
+ if ( !buf.tqresize(offset+length+65535) ) {
+ alloc_error = TRUE;
+ length = buf.size() - offset;
+ }
+ }
+ memcpy( buf.data()+offset, tmp_buf.data(), length );
+ tmp_buf.resize( 0 );
+ offset += length;
+ }
+ } else {
+ break;
+ }
+ }
+
+ // timed out ... create a new requestor window, otherwise the requestor
+ // could consider next request to be still part of this timed out request
+ delete requestor;
+ requestor = new TQWidget( 0, "internal clipboard requestor" );
+
+ return TQByteArray();
+}
+
+/*! \obsolete
+
+ Use the TQClipboard::data(), TQClipboard::setData() and related functions
+ which take a TQClipboard::Mode argument.
+
+ Sets the clipboard selection mode. If \a enable is TRUE, then
+ subsequent calls to TQClipboard::setData() and other functions
+ which put data into the clipboard will put the data into the mouse
+ selection, otherwise the data will be put into the clipboard.
+
+ \sa supportsSelection(), selectionModeEnabled()
+*/
+void TQClipboard::setSelectionMode(bool enable)
+{ inSelectionMode_obsolete = enable; }
+
+
+/*! \obsolete
+
+ Use the TQClipboard::data(), TQClipboard::setData() and related functions
+ which take a TQClipboard::Mode argument.
+
+ Returns the selection mode.
+
+ \sa setSelectionMode(), supportsSelection()
+*/
+bool TQClipboard::selectionModeEnabled() const
+{ return inSelectionMode_obsolete; }
+
+#else // USE_QT4
+
+
+// REVISED: arnt
+
+/*****************************************************************************
+ Internal TQClipboard functions for X11.
+ *****************************************************************************/
+
+// from qapplication_x11.cpp
+typedef int (*QX11EventFilter) (XEvent*);
+extern QX11EventFilter qt_set_x11_event_filter (QX11EventFilter filter);
+
+extern Time qt_x_incr; // def. in qapplication_x11.cpp
+extern Atom qt_xa_clipboard;
+extern Atom qt_selection_property;
+extern Atom qt_clipboard_sentinel;
+extern Atom qt_selection_sentinel;
+extern Atom qt_utf8_string;
+
+// from qdnd_x11.cpp
+extern Atom* qt_xdnd_str_to_atom( const char *mimeType );
+extern const char* qt_xdnd_atom_to_str( Atom );
+
+
+static int clipboard_timeout = 5000; // 5s timeout on clipboard operations
+
+static TQWidget * owner = 0;
+static TQWidget *requestor = 0;
+static bool inSelectionMode_obsolete = FALSE; // ### remove 4.0
+static bool timer_event_clear = FALSE;
+static int timer_id = 0;
+
+static int pending_timer_id = 0;
+static bool pending_clipboard_changed = FALSE;
+static bool pending_selection_changed = FALSE;
+
+
+// event capture mechanism for qt_xclb_wait_for_event
+static bool waiting_for_data = FALSE;
+static bool has_captured_event = FALSE;
+static Window capture_event_win = None;
+static int capture_event_type = -1;
+static XEvent captured_event;
+
+class TQClipboardWatcher; // forward decl
+static TQClipboardWatcher *selection_watcher = 0;
+static TQClipboardWatcher *clipboard_watcher = 0;
+
+static void cleanup()
+{
+ delete owner;
+ delete requestor;
+ owner = 0;
+ requestor = 0;
+}
+
+static
+void setupOwner()
+{
+ if ( owner )
+ return;
+ owner = new TQWidget( 0, "internal clipboard owner" );
+ requestor = new TQWidget(0, "internal clipboard requestor");
+ qAddPostRoutine( cleanup );
+}
+
+static
+int sizeof_format(int format)
+{
+ int sz;
+ switch (format) {
+ default:
+ case 8: sz = sizeof( char); break;
+ case 16: sz = sizeof(short); break;
+ case 32: sz = sizeof( long); break;
+ }
+ return sz;
+}
+
+class TQClipboardWatcher : public TQMimeSource {
+public:
+ TQClipboardWatcher( TQClipboard::Mode mode );
+ ~TQClipboardWatcher();
+ bool empty() const;
+ const char* format( int n ) const;
+ TQByteArray tqencodedData( const char* fmt ) const;
+ TQByteArray getDataInFormat(Atom fmtatom) const;
+
+ Atom atom;
+ TQValueList<const char *> formatList;
+};
+
+
+
+class TQClipboardData
+{
+public:
+ TQClipboardData();
+ ~TQClipboardData();
+
+ void setSource(TQMimeSource* s)
+ {
+ clear(TRUE);
+ src = s;
+ }
+
+ TQMimeSource *source() const { return src; }
+
+ void addTransferredPixmap(TQPixmap pm)
+ {
+ /* TODO: queue them */
+ transferred[tindex] = pm;
+ tindex=(tindex+1)%2;
+ }
+ void clearTransfers()
+ {
+ transferred[0] = TQPixmap();
+ transferred[1] = TQPixmap();
+ }
+
+ void clear(bool destruct=TRUE);
+
+ TQMimeSource *src;
+ Time timestamp;
+
+ TQPixmap transferred[2];
+ int tindex;
+};
+
+TQClipboardData::TQClipboardData()
+{
+ src = 0;
+ timestamp = CurrentTime;
+ tindex=0;
+}
+
+TQClipboardData::~TQClipboardData()
+{ clear(); }
+
+void TQClipboardData::clear(bool destruct)
+{
+ if(destruct)
+ delete src;
+ src = 0;
+ timestamp = CurrentTime;
+}
+
+
+static TQClipboardData *internalCbData = 0;
+static TQClipboardData *internalSelData = 0;
+
+static void cleanupClipboardData()
+{
+ delete internalCbData;
+ internalCbData = 0;
+}
+
+static TQClipboardData *clipboardData()
+{
+ if ( internalCbData == 0 ) {
+ internalCbData = new TQClipboardData;
+ TQ_CHECK_PTR( internalCbData );
+ qAddPostRoutine( cleanupClipboardData );
+ }
+ return internalCbData;
+}
+
+void qt_clipboard_cleanup_mime_source(TQMimeSource *src)
+{
+ if(internalCbData && internalCbData->source() == src)
+ internalCbData->clear(FALSE);
+}
+
+static void cleanupSelectionData()
+{
+ delete internalSelData;
+ internalSelData = 0;
+}
+
+static TQClipboardData *selectionData()
+{
+ if (internalSelData == 0) {
+ internalSelData = new TQClipboardData;
+ TQ_CHECK_PTR(internalSelData);
+ qAddPostRoutine(cleanupSelectionData);
+ }
+ return internalSelData;
+}
+
+class TQClipboardINCRTransaction
+{
+public:
+ TQClipboardINCRTransaction(Window w, Atom p, Atom t, int f, TQByteArray d, unsigned int i);
+ ~TQClipboardINCRTransaction(void);
+
+ int x11Event(XEvent *event);
+
+ Window window;
+ Atom property, target;
+ int format;
+ TQByteArray data;
+ unsigned int increment;
+ unsigned int offset;
+};
+
+typedef TQMap<Window,TQClipboardINCRTransaction*> TransactionMap;
+static TransactionMap *transactions = 0;
+static QX11EventFilter prev_x11_event_filter = 0;
+static int incr_timer_id = 0;
+
+static int qt_xclb_transation_event_handler(XEvent *event)
+{
+ TransactionMap::Iterator it = transactions->tqfind(event->xany.window);
+ if (it != transactions->end()) {
+ if ((*it)->x11Event(event) != 0)
+ return 1;
+ }
+ if (prev_x11_event_filter)
+ return prev_x11_event_filter(event);
+ return 0;
+}
+
+/*
+ called when no INCR activity has happened for 'clipboard_timeout'
+ milliseconds... we assume that all unfinished transactions have
+ timed out and remove everything from the transaction map
+*/
+static void qt_xclb_incr_timeout(void)
+{
+ qWarning("TQClipboard: timed out while sending data");
+
+ while (transactions)
+ delete *transactions->begin();
+}
+
+TQClipboardINCRTransaction::TQClipboardINCRTransaction(Window w, Atom p, Atom t, int f,
+ TQByteArray d, unsigned int i)
+ : window(w), property(p), target(t), format(f), data(d), increment(i), offset(0u)
+{
+ TQDEBUG("TQClipboard: sending %d bytes (INCR transaction %p)", d.size(), this);
+
+ XSelectInput(TQPaintDevice::x11AppDisplay(), window, PropertyChangeMask);
+
+ if (! transactions) {
+ VTQDEBUG("TQClipboard: created INCR transaction map");
+ transactions = new TransactionMap;
+ prev_x11_event_filter = qt_set_x11_event_filter(qt_xclb_transation_event_handler);
+
+ incr_timer_id = TQApplication::clipboard()->startTimer(clipboard_timeout);
+ }
+ transactions->insert(window, this);
+}
+
+TQClipboardINCRTransaction::~TQClipboardINCRTransaction(void)
+{
+ VTQDEBUG("TQClipboard: destroyed INCR transacton %p", this);
+
+ XSelectInput(TQPaintDevice::x11AppDisplay(), window, NoEventMask);
+
+ transactions->remove(window);
+ if (transactions->isEmpty()) {
+ VTQDEBUG("TQClipboard: no more INCR transations");
+ delete transactions;
+ transactions = 0;
+ (void)qt_set_x11_event_filter(prev_x11_event_filter);
+
+ if (incr_timer_id != 0) {
+ TQApplication::clipboard()->killTimer(incr_timer_id);
+ incr_timer_id = 0;
+ }
+ }
+}
+
+int TQClipboardINCRTransaction::x11Event(XEvent *event)
+{
+ if (event->type != PropertyNotify
+ || (event->xproperty.state != PropertyDelete
+ || event->xproperty.atom != property))
+ return 0;
+
+ // restart the INCR timer
+ if (incr_timer_id) TQApplication::clipboard()->killTimer(incr_timer_id);
+ incr_timer_id = TQApplication::clipboard()->startTimer(clipboard_timeout);
+
+ unsigned int bytes_left = data.size() - offset;
+ if (bytes_left > 0) {
+ unsigned int xfer = TQMIN(increment, bytes_left);
+ VTQDEBUG("TQClipboard: sending %d bytes, %d remaining (INCR transaction %p)",
+ xfer, bytes_left - xfer, this);
+
+ XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property, target, format,
+ PropModeReplace, (uchar *) data.data() + offset, xfer);
+ offset += xfer;
+ } else {
+ // INCR transaction finished...
+ XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property, target, format,
+ PropModeReplace, (uchar *) data.data(), 0);
+ delete this;
+ }
+
+ return 1;
+}
+
+
+/*****************************************************************************
+ TQClipboard member functions for X11.
+ *****************************************************************************/
+
+
+void TQClipboard::clear( Mode mode )
+{ setData(0, mode); }
+
+
+/*!
+ Returns TRUE if the clipboard supports mouse selection; otherwise
+ returns FALSE.
+*/
+bool TQClipboard::supportsSelection() const
+{ return TRUE; }
+
+
+/*!
+ Returns TRUE if this clipboard object owns the mouse selection
+ data; otherwise returns FALSE.
+*/
+bool TQClipboard::ownsSelection() const
+{ return selectionData()->timestamp != CurrentTime; }
+
+/*!
+ Returns TRUE if this clipboard object owns the clipboard data;
+ otherwise returns FALSE.
+*/
+bool TQClipboard::ownsClipboard() const
+{ return clipboardData()->timestamp != CurrentTime; }
+
+
+/*! \obsolete
+
+ Use the TQClipboard::data(), TQClipboard::setData() and related functions
+ which take a TQClipboard::Mode argument.
+
+ Sets the clipboard selection mode. If \a enable is TRUE, then
+ subsequent calls to TQClipboard::setData() and other functions
+ which put data into the clipboard will put the data into the mouse
+ selection, otherwise the data will be put into the clipboard.
+
+ \sa supportsSelection(), selectionModeEnabled()
+*/
+void TQClipboard::setSelectionMode(bool enable)
+{ inSelectionMode_obsolete = enable; }
+
+
+/*! \obsolete
+
+ Use the TQClipboard::data(), TQClipboard::setData() and related functions
+ which take a TQClipboard::Mode argument.
+
+ Returns the selection mode.
+
+ \sa setSelectionMode(), supportsSelection()
+*/
+bool TQClipboard::selectionModeEnabled() const
+{ return inSelectionMode_obsolete; }
+
+
+// event filter function... captures interesting events while
+// qt_xclb_wait_for_event is running the event loop
+static int qt_xclb_event_filter(XEvent *event)
+{
+ if (event->xany.type == capture_event_type &&
+ event->xany.window == capture_event_win) {
+ VTQDEBUG( "TQClipboard: event_filter(): caught event type %d", event->type );
+ has_captured_event = TRUE;
+ captured_event = *event;
+ return 1;
+ }
+
+ return 0;
+}
+
+static Bool checkForClipboardEvents(Display *, XEvent *e, XPointer)
+{
+ return ((e->type == SelectionRequest && (e->xselectionrequest.selection == XA_PRIMARY
+ || e->xselectionrequest.selection == qt_xa_clipboard))
+ || (e->type == SelectionClear && (e->xselectionclear.selection == XA_PRIMARY
+ || e->xselectionclear.selection == qt_xa_clipboard)));
+}
+
+bool qt_xclb_wait_for_event( Display *dpy, Window win, int type, XEvent *event,
+ int timeout )
+{
+ TQTime started = TQTime::currentTime();
+ TQTime now = started;
+
+ if (tqApp->eventLoop()->inherits("TQMotif")) { // yes yes, evil hack, we know
+ if ( waiting_for_data )
+ qFatal( "TQClipboard: internal error, qt_xclb_wait_for_event recursed" );
+
+ waiting_for_data = TRUE;
+ has_captured_event = FALSE;
+ capture_event_win = win;
+ capture_event_type = type;
+
+ QX11EventFilter old_event_filter = qt_set_x11_event_filter(qt_xclb_event_filter);
+
+ do {
+ if ( XCheckTypedWindowEvent(dpy,win,type,event) ) {
+ waiting_for_data = FALSE;
+ qt_set_x11_event_filter(old_event_filter);
+ return TRUE;
+ }
+
+ now = TQTime::currentTime();
+ if ( started > now ) // crossed midnight
+ started = now;
+
+ // 0x08 == ExcludeTimers for X11 only
+ tqApp->eventLoop()->processEvents( TQEventLoop::ExcludeUserInput |
+ TQEventLoop::ExcludeSocketNotifiers |
+ TQEventLoop::WaitForMore | 0x08 );
+
+ if ( has_captured_event ) {
+ waiting_for_data = FALSE;
+ *event = captured_event;
+ qt_set_x11_event_filter(old_event_filter);
+ return TRUE;
+ }
+ } while ( started.msecsTo(now) < timeout );
+
+ waiting_for_data = FALSE;
+ qt_set_x11_event_filter(old_event_filter);
+
+ return FALSE;
+ }
+
+ bool flushed = FALSE;
+ do {
+ if ( XCheckTypedWindowEvent(dpy,win,type,event) )
+ return TRUE;
+
+ // process other clipboard events, since someone is probably requesting data from us
+ XEvent e;
+ if (XCheckIfEvent(dpy, &e, checkForClipboardEvents, 0))
+ tqApp->x11ProcessEvent(&e);
+
+ now = TQTime::currentTime();
+ if ( started > now ) // crossed midnight
+ started = now;
+
+ if(!flushed) {
+ XFlush( dpy );
+ flushed = TRUE;
+ }
+
+ // sleep 50ms, so we don't use up CPU cycles all the time.
+ struct timeval usleep_tv;
+ usleep_tv.tv_sec = 0;
+ usleep_tv.tv_usec = 50000;
+ select(0, 0, 0, 0, &usleep_tv);
+ } while ( started.msecsTo(now) < timeout );
+
+ return FALSE;
+}
+
+
+static inline int maxSelectionIncr( Display *dpy )
+{ return XMaxRequestSize(dpy) > 65536 ? 65536*4 : XMaxRequestSize(dpy)*4 - 100; }
+
+// uglyhack: externed into qt_xdnd.cpp. qt is really not designed for
+// single-platform, multi-purpose blocks of code...
+bool qt_xclb_read_property( Display *dpy, Window win, Atom property,
+ bool deleteProperty,
+ TQByteArray *buffer, int *size, Atom *type,
+ int *format, bool nullterm )
+{
+ int maxsize = maxSelectionIncr(dpy);
+ ulong bytes_left; // bytes_after
+ ulong length; // nitems
+ uchar *data;
+ Atom dummy_type;
+ int dummy_format;
+ int r;
+
+ if ( !type ) // allow null args
+ type = &dummy_type;
+ if ( !format )
+ format = &dummy_format;
+
+ // Don't read anything, just get the size of the property data
+ r = XGetWindowProperty( dpy, win, property, 0, 0, False,
+ AnyPropertyType, type, format,
+ &length, &bytes_left, &data );
+ if (r != Success || (type && *type == None)) {
+ buffer->resize( 0 );
+ return FALSE;
+ }
+ XFree( (char*)data );
+
+ int offset = 0, buffer_offset = 0, format_inc = 1, proplen = bytes_left;
+
+ VTQDEBUG("TQClipboard: read_property(): initial property length: %d", proplen);
+
+ switch (*format) {
+ case 8:
+ default:
+ format_inc = sizeof(char) / 1;
+ break;
+
+ case 16:
+ format_inc = sizeof(short) / 2;
+ proplen *= sizeof(short) / 2;
+ break;
+
+ case 32:
+ format_inc = sizeof(long) / 4;
+ proplen *= sizeof(long) / 4;
+ break;
+ }
+
+ bool ok = buffer->tqresize( proplen + (nullterm ? 1 : 0) );
+
+ VTQDEBUG("TQClipboard: read_property(): buffer resized to %d", buffer->size());
+
+ if ( ok ) {
+ // could allocate buffer
+
+ while ( bytes_left ) {
+ // more to read...
+
+ r = XGetWindowProperty( dpy, win, property, offset, maxsize/4,
+ False, AnyPropertyType, type, format,
+ &length, &bytes_left, &data );
+ if (r != Success || (type && *type == None))
+ break;
+
+ offset += length / (32 / *format);
+ length *= format_inc * (*format) / 8;
+
+ // Here we check if we get a buffer overflow and tries to
+ // recover -- this shouldn't normally happen, but it doesn't
+ // hurt to be defensive
+ if (buffer_offset + length > buffer->size()) {
+ length = buffer->size() - buffer_offset;
+
+ // escape loop
+ bytes_left = 0;
+ }
+
+ memcpy(buffer->data() + buffer_offset, data, length);
+ buffer_offset += length;
+
+ XFree( (char*)data );
+ }
+
+ static Atom xa_compound_text = *qt_xdnd_str_to_atom( "COMPOUND_TEXT" );
+ if ( *format == 8 && *type == xa_compound_text ) {
+ // convert COMPOUND_TEXT to a multibyte string
+ XTextProperty textprop;
+ textprop.encoding = *type;
+ textprop.format = *format;
+ textprop.nitems = length;
+ textprop.value = (unsigned char *) buffer->data();
+
+ char **list_ret = 0;
+ int count;
+ if ( XmbTextPropertyToTextList( dpy, &textprop, &list_ret,
+ &count ) == Success &&
+ count && list_ret ) {
+ offset = strlen( list_ret[0] );
+ buffer->resize( offset + ( nullterm ? 1 : 0 ) );
+ memcpy( buffer->data(), list_ret[0], offset );
+ }
+ if (list_ret) XFreeStringList(list_ret);
+ }
+
+ // zero-terminate (for text)
+ if (nullterm)
+ buffer->tqat(buffer_offset) = '\0';
+ }
+
+ // correct size, not 0-term.
+ if ( size )
+ *size = buffer_offset;
+
+ VTQDEBUG("TQClipboard: read_property(): buffer size %d, buffer offset %d, offset %d",
+ buffer->size(), buffer_offset, offset);
+
+ if ( deleteProperty )
+ XDeleteProperty( dpy, win, property );
+
+ XFlush( dpy );
+
+ return ok;
+}
+
+
+// this is externed into qt_xdnd.cpp too.
+TQByteArray qt_xclb_read_incremental_property( Display *dpy, Window win,
+ Atom property, int nbytes,
+ bool nullterm )
+{
+ XEvent event;
+
+ TQByteArray buf;
+ TQByteArray tmp_buf;
+ bool alloc_error = FALSE;
+ int length;
+ int offset = 0;
+
+ if ( nbytes > 0 ) {
+ // Reserve buffer + zero-terminator (for text data)
+ // We want to complete the INCR transfer even if we cannot
+ // allocate more memory
+ alloc_error = !buf.tqresize(nbytes+1);
+ }
+
+ for (;;) {
+ XFlush( dpy );
+ if ( !qt_xclb_wait_for_event(dpy,win,PropertyNotify,&event,clipboard_timeout) )
+ break;
+ if ( event.xproperty.atom != property ||
+ event.xproperty.state != PropertyNewValue )
+ continue;
+ if ( qt_xclb_read_property(dpy, win, property, TRUE, &tmp_buf,
+ &length,0, 0, FALSE) ) {
+ if ( length == 0 ) { // no more data, we're done
+ if ( nullterm ) {
+ buf.resize( offset+1 );
+ buf.tqat( offset ) = '\0';
+ } else {
+ buf.resize(offset);
+ }
+ return buf;
+ } else if ( !alloc_error ) {
+ if ( offset+length > (int)buf.size() ) {
+ if ( !buf.tqresize(offset+length+65535) ) {
+ alloc_error = TRUE;
+ length = buf.size() - offset;
+ }
+ }
+ memcpy( buf.data()+offset, tmp_buf.data(), length );
+ tmp_buf.resize( 0 );
+ offset += length;
+ }
+ } else {
+ break;
+ }
+ }
+
+ // timed out ... create a new requestor window, otherwise the requestor
+ // could consider next request to be still part of this timed out request
+ delete requestor;
+ requestor = new TQWidget( 0, "internal clipboard requestor" );
+
+ return TQByteArray();
+}
+
+static Atom send_selection(TQClipboardData *d, Atom target, Window window, Atom property,
+ int format = 0, TQByteArray data = TQByteArray());
+
+static Atom send_targets_selection(TQClipboardData *d, Window window, Atom property)
+{
+ int atoms = 0;
+ while (d->source()->format(atoms)) atoms++;
+ if (d->source()->provides("image/ppm")) atoms++;
+ if (d->source()->provides("image/pbm")) atoms++;
+ if (d->source()->provides("text/plain")) atoms+=4;
+
+ VTQDEBUG("TQClipboard: send_targets_selection(): %d provided types", atoms);
+
+ // for 64 bit cleanness... XChangeProperty expects long* for data with format == 32
+ TQByteArray data((atoms+3) * sizeof(long)); // plus TARGETS, MULTIPLE and TIMESTAMP
+ long *atarget = (long *) data.data();
+
+ const char *fmt;
+ int n = 0;
+ while ((fmt=d->source()->format(n)) && n < atoms)
+ atarget[n++] = *qt_xdnd_str_to_atom(fmt);
+
+ static Atom xa_text = *qt_xdnd_str_to_atom("TEXT");
+ static Atom xa_compound_text = *qt_xdnd_str_to_atom("COMPOUND_TEXT");
+ static Atom xa_targets = *qt_xdnd_str_to_atom("TARGETS");
+ static Atom xa_multiple = *qt_xdnd_str_to_atom("MULTIPLE");
+ static Atom xa_timestamp = *qt_xdnd_str_to_atom("TIMESTAMP");
+
+ if (d->source()->provides("image/ppm"))
+ atarget[n++] = XA_PIXMAP;
+ if (d->source()->provides("image/pbm"))
+ atarget[n++] = XA_BITMAP;
+ if (d->source()->provides("text/plain")) {
+ atarget[n++] = qt_utf8_string;
+ atarget[n++] = xa_text;
+ atarget[n++] = xa_compound_text;
+ atarget[n++] = XA_STRING;
+ }
+
+ atarget[n++] = xa_targets;
+ atarget[n++] = xa_multiple;
+ atarget[n++] = xa_timestamp;
+
+#if defined(TQCLIPBOARD_DEBUG_VERBOSE)
+ for (int index = 0; index < n; index++) {
+ VTQDEBUG(" atom %d: 0x%lx (%s)", index, atarget[index],
+ qt_xdnd_atom_to_str(atarget[index]));
+ }
+#endif
+
+ XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property, XA_ATOM, 32,
+ PropModeReplace, (uchar *) data.data(), n);
+ return property;
+}
+
+static Atom send_string_selection(TQClipboardData *d, Atom target, Window window, Atom property)
+{
+ static Atom xa_text = *qt_xdnd_str_to_atom("TEXT");
+ static Atom xa_compound_text = *qt_xdnd_str_to_atom("COMPOUND_TEXT");
+
+ TQDEBUG("TQClipboard: send_string_selection():\n"
+ " property type %lx\n"
+ " property name '%s'",
+ target, qt_xdnd_atom_to_str(target));
+
+ if (target == xa_text || target == xa_compound_text) {
+ // the ICCCM states that TEXT and COMPOUND_TEXT are in the
+ // encoding of choice, so we choose the encoding of the locale
+ TQByteArray data = d->source()->tqencodedData("text/plain");
+ if(data.tqresize(data.size() + 1))
+ data[int(data.size() - 1)] = '\0';
+ char *list[] = { data.data(), NULL };
+
+ XICCEncodingStyle style =
+ (target == xa_compound_text) ? XCompoundTextStyle : XStdICCTextStyle;
+ XTextProperty textprop;
+ if (list[0] != NULL
+ && XmbTextListToTextProperty(TQPaintDevice::x11AppDisplay(),
+ list, 1, style, &textprop) == Success) {
+ TQDEBUG(" textprop type %lx\n"
+ " textprop name '%s'\n"
+ " format %d\n"
+ " %ld items",
+ textprop.encoding, qt_xdnd_atom_to_str(textprop.encoding),
+ textprop.format, textprop.nitems);
+
+ int sz = sizeof_format(textprop.format);
+ data.duplicate((const char *) textprop.value, textprop.nitems * sz);
+ XFree(textprop.value);
+
+ return send_selection(d, textprop.encoding, window, property, textprop.format, data);
+ }
+
+ return None;
+ }
+
+ Atom xtarget = None;
+ const char *fmt = 0;
+ if (target == XA_STRING
+ || (target == xa_text && TQTextCodec::codecForLocale()->mibEnum() == 4)) {
+ // the ICCCM states that STRING is latin1 plus newline and tab
+ // see section 2.6.2
+ fmt = "text/plain;charset=ISO-8859-1";
+ xtarget = XA_STRING;
+ } else if (target == qt_utf8_string) {
+ // proposed UTF8_STRING conversion type
+ fmt = "text/plain;charset=UTF-8";
+ xtarget = qt_utf8_string;
+ }
+
+ if (xtarget == None) // should not happen
+ return None;
+
+ TQByteArray data = d->source()->tqencodedData(fmt);
+
+ TQDEBUG(" format 8\n %d bytes", data.size());
+
+ return send_selection(d, xtarget, window, property, 8, data);
+}
+
+static Atom send_pixmap_selection(TQClipboardData *d, Atom target, Window window, Atom property)
+{
+ TQPixmap pm;
+
+ if ( target == XA_PIXMAP ) {
+ TQByteArray data = d->source()->tqencodedData("image/ppm");
+ pm.loadFromData(data);
+ } else if ( target == XA_BITMAP ) {
+ TQByteArray data = d->source()->tqencodedData("image/pbm");
+ TQImage img;
+ img.loadFromData(data);
+ if ( img.depth() != 1 )
+ img = img.convertDepth(1);
+ }
+
+ if (pm.isNull()) // should never happen
+ return None;
+
+ Pixmap handle = pm.handle();
+ XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property,
+ target, 32, PropModeReplace, (uchar *) &handle, 1);
+ d->addTransferredPixmap(pm);
+ return property;
+
+}
+
+static Atom send_selection(TQClipboardData *d, Atom target, Window window, Atom property,
+ int format, TQByteArray data)
+{
+ if (format == 0) format = 8;
+
+ if (data.isEmpty()) {
+ const char *fmt = qt_xdnd_atom_to_str(target);
+ TQDEBUG("TQClipboard: send_selection(): converting to type '%s'", fmt);
+ if (fmt && !d->source()->provides(fmt)) // Not a MIME type we can produce
+ return None;
+ data = d->source()->tqencodedData(fmt);
+ }
+
+ TQDEBUG("TQClipboard: send_selection():\n"
+ " property type %lx\n"
+ " property name '%s'\n"
+ " format %d\n"
+ " %d bytes",
+ target, qt_xdnd_atom_to_str(target), format, data.size());
+
+ // don't allow INCR transfers when using MULTIPLE or to
+ // Motif clients (since Motif doesn't support INCR)
+ static Atom motif_clip_temporary = *qt_xdnd_str_to_atom("CLIP_TEMPORARY");
+ bool allow_incr = property != motif_clip_temporary;
+
+ // X_ChangeProperty protocol request is 24 bytes
+ const unsigned int increment = (XMaxRequestSize(TQPaintDevice::x11AppDisplay()) * 4) - 24;
+ if (data.size() > increment && allow_incr) {
+ long bytes = data.size();
+ XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property,
+ qt_x_incr, 32, PropModeReplace, (uchar *) &bytes, 1);
+
+ (void)new TQClipboardINCRTransaction(window, property, target, format, data, increment);
+ return qt_x_incr;
+ }
+
+ // make sure we can perform the XChangeProperty in a single request
+ if (data.size() > increment)
+ return None; // ### perhaps use several XChangeProperty calls w/ PropModeAppend?
+
+ // use a single request to transfer data
+ XChangeProperty(TQPaintDevice::x11AppDisplay(), window, property, target,
+ format, PropModeReplace, (uchar *) data.data(),
+ data.size() / sizeof_format(format));
+ return property;
+}
+
+/*! \internal
+ Internal cleanup for Windows.
+*/
+void TQClipboard::ownerDestroyed()
+{ }
+
+
+/*! \internal
+ Internal optimization for Windows.
+*/
+void TQClipboard::connectNotify( const char * )
+{ }
+
+
+/*! \reimp
+ */
+bool TQClipboard::event( TQEvent *e )
+{
+ if ( e->type() == TQEvent::Timer ) {
+ TQTimerEvent *te = (TQTimerEvent *) e;
+
+ if ( waiting_for_data ) // should never happen
+ return FALSE;
+
+ if (te->timerId() == timer_id) {
+ killTimer(timer_id);
+ timer_id = 0;
+
+ timer_event_clear = TRUE;
+ if ( selection_watcher ) // clear selection
+ selectionData()->clear();
+ if ( clipboard_watcher ) // clear clipboard
+ clipboardData()->clear();
+ timer_event_clear = FALSE;
+
+ return TRUE;
+ } else if ( te->timerId() == pending_timer_id ) {
+ // I hate klipper
+ killTimer( pending_timer_id );
+ pending_timer_id = 0;
+
+ if ( pending_clipboard_changed ) {
+ pending_clipboard_changed = FALSE;
+ clipboardData()->clear();
+ emit dataChanged();
+ }
+ if ( pending_selection_changed ) {
+ pending_selection_changed = FALSE;
+ selectionData()->clear();
+ emit selectionChanged();
+ }
+
+ return TRUE;
+ } else if (te->timerId() == incr_timer_id) {
+ killTimer(incr_timer_id);
+ incr_timer_id = 0;
+
+ qt_xclb_incr_timeout();
+
+ return TRUE;
+ } else {
+ return TQObject::event( e );
+ }
+ } else if ( e->type() != TQEvent::Clipboard ) {
+ return TQObject::event( e );
+ }
+
+ XEvent *xevent = (XEvent *)(((TQCustomEvent *)e)->data());
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+
+ if ( !xevent )
+ return TRUE;
+
+ switch ( xevent->type ) {
+
+ case SelectionClear:
+ // new selection owner
+ if (xevent->xselectionclear.selection == XA_PRIMARY) {
+ TQClipboardData *d = selectionData();
+
+ // ignore the event if it was generated before we gained selection ownership
+ if (d->timestamp != CurrentTime && xevent->xselectionclear.time < d->timestamp)
+ break;
+
+ TQDEBUG("TQClipboard: new selection owner 0x%lx at time %lx (ours %lx)",
+ XGetSelectionOwner(dpy, XA_PRIMARY),
+ xevent->xselectionclear.time, d->timestamp);
+
+ if ( ! waiting_for_data ) {
+ d->clear();
+ emit selectionChanged();
+ } else {
+ pending_selection_changed = TRUE;
+ if ( ! pending_timer_id )
+ pending_timer_id = TQApplication::clipboard()->startTimer( 0 );
+ }
+ } else if (xevent->xselectionclear.selection == qt_xa_clipboard) {
+ TQClipboardData *d = clipboardData();
+
+ // ignore the event if it was generated before we gained selection ownership
+ if (d->timestamp != CurrentTime && xevent->xselectionclear.time < d->timestamp)
+ break;
+
+ TQDEBUG("TQClipboard: new clipboard owner 0x%lx at time %lx (%lx)",
+ XGetSelectionOwner(dpy, qt_xa_clipboard),
+ xevent->xselectionclear.time, d->timestamp);
+
+ if ( ! waiting_for_data ) {
+ d->clear();
+ emit dataChanged();
+ } else {
+ pending_clipboard_changed = TRUE;
+ if ( ! pending_timer_id )
+ pending_timer_id = TQApplication::clipboard()->startTimer( 0 );
+ }
+ } else {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQClipboard: Unknown SelectionClear event received.");
+#endif
+ return FALSE;
+ }
+ break;
+
+ case SelectionNotify:
+ /*
+ Something has delivered data to us, but this was not caught
+ by TQClipboardWatcher::getDataInFormat()
+
+ Just skip the event to prevent Bad Things (tm) from
+ happening later on...
+ */
+ break;
+
+ case SelectionRequest:
+ {
+ // someone wants our data
+ XSelectionRequestEvent *req = &xevent->xselectionrequest;
+
+ if (requestor && req->requestor == requestor->winId())
+ break;
+
+ XEvent event;
+ event.xselection.type = SelectionNotify;
+ event.xselection.display = req->display;
+ event.xselection.requestor = req->requestor;
+ event.xselection.selection = req->selection;
+ event.xselection.target = req->target;
+ event.xselection.property = None;
+ event.xselection.time = req->time;
+
+ TQDEBUG("TQClipboard: SelectionRequest from %lx\n"
+ " selection 0x%lx (%s) target 0x%lx (%s)",
+ req->requestor,
+ req->selection,
+ qt_xdnd_atom_to_str(req->selection),
+ req->target,
+ qt_xdnd_atom_to_str(req->target));
+
+ TQClipboardData *d;
+
+ if ( req->selection == XA_PRIMARY ) {
+ d = selectionData();
+ } else if ( req->selection == qt_xa_clipboard ) {
+ d = clipboardData();
+ } else {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQClipboard: unknown selection '%lx'", req->selection);
+#endif // TQT_CHECK_RANGE
+
+ XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
+ break;
+ }
+
+ if (! d->source()) {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQClipboard: cannot transfer data, no data available");
+#endif // TQT_CHECK_STATE
+
+ XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
+ break;
+ }
+
+ TQDEBUG("TQClipboard: SelectionRequest at time %lx (ours %lx)",
+ req->time, d->timestamp);
+
+ if (d->timestamp == CurrentTime // we don't own the selection anymore
+ || (req->time != CurrentTime && req->time < d->timestamp)) {
+ TQDEBUG("TQClipboard: SelectionRequest too old");
+ XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
+ break;
+ }
+
+ static Atom xa_text = *qt_xdnd_str_to_atom("TEXT");
+ static Atom xa_compound_text = *qt_xdnd_str_to_atom("COMPOUND_TEXT");
+ static Atom xa_targets = *qt_xdnd_str_to_atom("TARGETS");
+ static Atom xa_multiple = *qt_xdnd_str_to_atom("MULTIPLE");
+ static Atom xa_timestamp = *qt_xdnd_str_to_atom("TIMESTAMP");
+
+ struct AtomPair { Atom target; Atom property; } *multi = 0;
+ Atom multi_type = None;
+ int multi_format = 0;
+ int nmulti = 0;
+ int imulti = -1;
+ bool multi_writeback = FALSE;
+
+ if ( req->target == xa_multiple ) {
+ TQByteArray multi_data;
+ if (req->property == None
+ || !qt_xclb_read_property(dpy, req->requestor, req->property,
+ FALSE, &multi_data, 0, &multi_type, &multi_format, 0)
+ || multi_format != 32) {
+ // MULTIPLE property not formatted correctly
+ XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
+ break;
+ }
+ nmulti = multi_data.size()/sizeof(*multi);
+ multi = new AtomPair[nmulti];
+ memcpy(multi,multi_data.data(),multi_data.size());
+ imulti = 0;
+ }
+
+ for (; imulti < nmulti; ++imulti) {
+ Atom target;
+ Atom property;
+
+ if ( multi ) {
+ target = multi[imulti].target;
+ property = multi[imulti].property;
+ } else {
+ target = req->target;
+ property = req->property;
+ if (property == None) // obsolete client
+ property = target;
+ }
+
+ Atom ret = None;
+ if (target == None || property == None) {
+ ;
+ } else if (target == xa_timestamp) {
+ if (d->timestamp != CurrentTime) {
+ XChangeProperty(dpy, req->requestor, property, xa_timestamp, 32,
+ PropModeReplace, (uchar *) &d->timestamp, 1);
+ ret = property;
+ } else {
+
+#ifdef TQT_CHECK_STATE
+ qWarning("TQClipboard: invalid data timestamp");
+#endif // TQT_CHECK_STATE
+ }
+ } else if (target == xa_targets) {
+ ret = send_targets_selection(d, req->requestor, property);
+ } else if (target == XA_STRING
+ || target == xa_text
+ || target == xa_compound_text
+ || target == qt_utf8_string) {
+ ret = send_string_selection(d, target, req->requestor, property);
+ } else if (target == XA_PIXMAP
+ || target == XA_BITMAP) {
+ ret = send_pixmap_selection(d, target, req->requestor, property);
+ } else {
+ ret = send_selection(d, target, req->requestor, property);
+ }
+
+ if (nmulti > 0) {
+ if (ret == None) {
+ multi[imulti].property = None;
+ multi_writeback = TRUE;
+ }
+ } else {
+ event.xselection.property = ret;
+ break;
+ }
+ }
+
+ if (nmulti > 0) {
+ if (multi_writeback) {
+ // according to ICCCM 2.6.2 says to put None back
+ // into the original property on the requestor window
+ XChangeProperty(dpy, req->requestor, req->property, multi_type, 32,
+ PropModeReplace, (uchar *) multi, nmulti * 2);
+ }
+
+ delete [] multi;
+ event.xselection.property = req->property;
+ }
+
+ // send selection notify to requestor
+ XSendEvent(dpy, req->requestor, False, NoEventMask, &event);
+
+ TQDEBUG("TQClipboard: SelectionNotify to 0x%lx\n"
+ " property 0x%lx (%s)",
+ req->requestor, event.xselection.property,
+ qt_xdnd_atom_to_str(event.xselection.property));
+ }
+ break;
+ }
+
+ return TRUE;
+}
+
+
+
+
+
+
+TQClipboardWatcher::TQClipboardWatcher( TQClipboard::Mode mode )
+{
+ switch ( mode ) {
+ case TQClipboard::Selection:
+ atom = XA_PRIMARY;
+ break;
+
+ case TQClipboard::Clipboard:
+ atom = qt_xa_clipboard;
+ break;
+
+#ifdef TQT_CHECK_RANGE
+ default:
+ qWarning( "TQClipboardWatcher: internal error, unknown clipboard mode" );
+ break;
+#endif // TQT_CHECK_RANGE
+ }
+
+ setupOwner();
+}
+
+TQClipboardWatcher::~TQClipboardWatcher()
+{
+ if( selection_watcher == this )
+ selection_watcher = 0;
+ if( clipboard_watcher == this )
+ clipboard_watcher = 0;
+}
+
+bool TQClipboardWatcher::empty() const
+{
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ Window win = XGetSelectionOwner( dpy, atom );
+
+#ifdef TQT_CHECK_STATE
+ if( win == requestor->winId()) {
+ qWarning( "TQClipboardWatcher::empty: internal error, app owns the selection" );
+ return TRUE;
+ }
+#endif // TQT_CHECK_STATE
+
+ return win == None;
+}
+
+const char* TQClipboardWatcher::format( int n ) const
+{
+ if ( empty() )
+ return 0;
+
+ if (! formatList.count()) {
+ // get the list of targets from the current clipboard owner - we do this
+ // once so that multiple calls to this function don't require multiple
+ // server round trips...
+ static Atom xa_targets = *qt_xdnd_str_to_atom( "TARGETS" );
+
+ TQClipboardWatcher *that = (TQClipboardWatcher *) this;
+ TQByteArray ba = getDataInFormat(xa_targets);
+ if (ba.size() > 0) {
+ Atom *unsorted_target = (Atom *) ba.data();
+ static Atom xa_text = *qt_xdnd_str_to_atom( "TEXT" );
+ static Atom xa_compound_text = *qt_xdnd_str_to_atom( "COMPOUND_TEXT" );
+ int i, size = ba.size() / sizeof(Atom);
+
+ // sort TARGETS to prefer some types over others. some apps
+ // will report XA_STRING before COMPOUND_TEXT, and we want the
+ // latter, not the former (if it is present).
+ Atom* target = new Atom[size+4];
+ memset( target, 0, (size+4) * sizeof(Atom) );
+
+ for ( i = 0; i < size; ++i ) {
+ if ( unsorted_target[i] == qt_utf8_string )
+ target[0] = unsorted_target[i];
+ else if ( unsorted_target[i] == xa_compound_text )
+ target[1] = unsorted_target[i];
+ else if ( unsorted_target[i] == xa_text )
+ target[2] = unsorted_target[i];
+ else if ( unsorted_target[i] == XA_STRING )
+ target[3] = unsorted_target[i];
+ else
+ target[i + 4] = unsorted_target[i];
+ }
+
+ for (i = 0; i < size + 4; ++i) {
+ if ( target[i] == 0 ) continue;
+
+ VTQDEBUG(" format: %s", qt_xdnd_atom_to_str(target[i]));
+
+ if ( target[i] == XA_PIXMAP )
+ that->formatList.append("image/ppm");
+ else if ( target[i] == XA_STRING )
+ that->formatList.append( "text/plain;charset=ISO-8859-1" );
+ else if ( target[i] == qt_utf8_string )
+ that->formatList.append( "text/plain;charset=UTF-8" );
+ else if ( target[i] == xa_text ||
+ target[i] == xa_compound_text )
+ that->formatList.append( "text/plain" );
+ else
+ that->formatList.append(qt_xdnd_atom_to_str(target[i]));
+ }
+ delete []target;
+
+ TQDEBUG("TQClipboardWatcher::format: %d formats available",
+ int(that->formatList.count()));
+ }
+ }
+
+ if (n >= 0 && n < (signed) formatList.count())
+ return formatList[n];
+ if (n == 0)
+ return "text/plain";
+ return 0;
+}
+
+TQByteArray TQClipboardWatcher::tqencodedData( const char* fmt ) const
+{
+ if ( !fmt || empty() )
+ return TQByteArray( 0 );
+
+ TQDEBUG("TQClipboardWatcher::tqencodedData: fetching format '%s'", fmt);
+
+ Atom fmtatom = 0;
+
+ if ( 0==qstricmp(fmt,"text/plain;charset=iso-8859-1") ) {
+ // ICCCM section 2.6.2 says STRING is latin1 text
+ fmtatom = XA_STRING;
+ } else if ( 0==qstricmp(fmt,"text/plain;charset=utf-8") ) {
+ // proprosed UTF8_STRING conversion type
+ fmtatom = *qt_xdnd_str_to_atom( "UTF8_STRING" );
+ } else if ( 0==qstrcmp(fmt,"text/plain") ) {
+ fmtatom = *qt_xdnd_str_to_atom( "COMPOUND_TEXT" );
+ } else if ( 0==qstrcmp(fmt,"image/ppm") ) {
+ fmtatom = XA_PIXMAP;
+ TQByteArray pmd = getDataInFormat(fmtatom);
+ if ( pmd.size() == sizeof(Pixmap) ) {
+ Pixmap xpm = *((Pixmap*)pmd.data());
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ Window r;
+ int x,y;
+ uint w,h,bw,d;
+ if ( ! xpm )
+ return TQByteArray( 0 );
+ XGetGeometry(dpy,xpm, &r,&x,&y,&w,&h,&bw,&d);
+ TQImageIO iio;
+ GC gc = XCreateGC( dpy, xpm, 0, 0 );
+ if ( d == 1 ) {
+ TQBitmap qbm(w,h);
+ XCopyArea(dpy,xpm,qbm.handle(),gc,0,0,w,h,0,0);
+ iio.setFormat("PBMRAW");
+ iio.setImage(qbm.convertToImage());
+ } else {
+ TQPixmap qpm(w,h);
+ XCopyArea(dpy,xpm,qpm.handle(),gc,0,0,w,h,0,0);
+ iio.setFormat("PPMRAW");
+ iio.setImage(qpm.convertToImage());
+ }
+ XFreeGC(dpy,gc);
+ TQBuffer buf;
+ buf.open(IO_WriteOnly);
+ iio.setIODevice(TQT_TQIODEVICE(&buf));
+ iio.write();
+ return buf.buffer();
+ } else {
+ fmtatom = *qt_xdnd_str_to_atom(fmt);
+ }
+ } else {
+ fmtatom = *qt_xdnd_str_to_atom(fmt);
+ }
+ return getDataInFormat(fmtatom);
+}
+
+TQByteArray TQClipboardWatcher::getDataInFormat(Atom fmtatom) const
+{
+ TQByteArray buf;
+
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ Window win = requestor->winId();
+
+ TQDEBUG("TQClipboardWatcher::getDataInFormat: selection '%s' format '%s'",
+ qt_xdnd_atom_to_str(atom), qt_xdnd_atom_to_str(fmtatom));
+
+ XSelectInput(dpy, win, NoEventMask); // don't listen for any events
+
+ XDeleteProperty(dpy, win, qt_selection_property);
+ XConvertSelection(dpy, atom, fmtatom, qt_selection_property, win, GET_QT_X_TIME());
+ XSync(dpy, FALSE);
+
+ VTQDEBUG("TQClipboardWatcher::getDataInFormat: waiting for SelectionNotify event");
+
+ XEvent xevent;
+ if ( !qt_xclb_wait_for_event(dpy,win,SelectionNotify,&xevent,clipboard_timeout) ||
+ xevent.xselection.property == None ) {
+ TQDEBUG("TQClipboardWatcher::getDataInFormat: format not available");
+ return buf;
+ }
+
+ VTQDEBUG("TQClipboardWatcher::getDataInFormat: fetching data...");
+
+ Atom type;
+ XSelectInput(dpy, win, PropertyChangeMask);
+
+ if ( qt_xclb_read_property(dpy,win,qt_selection_property,TRUE,
+ &buf,0,&type,0,FALSE) ) {
+ if ( type == qt_x_incr ) {
+ int nbytes = buf.size() >= 4 ? *((int*)buf.data()) : 0;
+ buf = qt_xclb_read_incremental_property( dpy, win,
+ qt_selection_property,
+ nbytes, FALSE );
+ }
+ }
+
+ XSelectInput(dpy, win, NoEventMask);
+
+ TQDEBUG("TQClipboardWatcher::getDataInFormat: %d bytes received", buf.size());
+
+ return buf;
+}
+
+
+TQMimeSource* TQClipboard::data( Mode mode ) const
+{
+ TQClipboardData *d;
+ switch ( mode ) {
+ case Selection: d = selectionData(); break;
+ case Clipboard: d = clipboardData(); break;
+
+ default:
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQClipboard::data: invalid mode '%d'", mode );
+#endif // TQT_CHECK_RANGE
+ return 0;
+ }
+
+ if ( ! d->source() && ! timer_event_clear ) {
+ if ( mode == Selection ) {
+ if ( ! selection_watcher )
+ selection_watcher = new TQClipboardWatcher( mode );
+ d->setSource( selection_watcher );
+ } else {
+ if ( ! clipboard_watcher )
+ clipboard_watcher = new TQClipboardWatcher( mode );
+ d->setSource( clipboard_watcher );
+ }
+
+ if (! timer_id) {
+ // start a zero timer - we will clear cached data when the timer
+ // times out, which will be the next time we hit the event loop...
+ // that way, the data is cached long enough for calls within a single
+ // loop/function, but the data doesn't linger around in case the selection
+ // changes
+ TQClipboard *that = ((TQClipboard *) this);
+ timer_id = that->startTimer(0);
+ }
+ }
+
+ return d->source();
+}
+
+
+void TQClipboard::setData( TQMimeSource* src, Mode mode )
+{
+ Atom atom, sentinel_atom;
+ TQClipboardData *d;
+ switch ( mode ) {
+ case Selection:
+ atom = XA_PRIMARY;
+ sentinel_atom = qt_selection_sentinel;
+ d = selectionData();
+ break;
+
+ case Clipboard:
+ atom = qt_xa_clipboard;
+ sentinel_atom = qt_clipboard_sentinel;
+ d = clipboardData();
+ break;
+
+ default:
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQClipboard::data: invalid mode '%d'", mode );
+#endif // TQT_CHECK_RANGE
+ return;
+ }
+
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ Window newOwner;
+
+ if (! src) { // no data, clear clipboard contents
+ newOwner = None;
+ d->clear();
+ } else {
+ setupOwner();
+
+ newOwner = owner->winId();
+
+ d->setSource(src);
+ d->timestamp = GET_QT_X_TIME();
+ }
+
+ Window prevOwner = XGetSelectionOwner( dpy, atom );
+ // use qt_x_time, since d->timestamp == CurrentTime when clearing
+ XSetSelectionOwner(dpy, atom, newOwner, GET_QT_X_TIME());
+
+ if ( mode == Selection )
+ emit selectionChanged();
+ else
+ emit dataChanged();
+
+ if (XGetSelectionOwner(dpy, atom) != newOwner) {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQClipboard::setData: Cannot set X11 selection owner for %s",
+ qt_xdnd_atom_to_str(atom));
+#endif // TQT_CHECK_STATE
+
+ d->clear();
+ return;
+ }
+
+ // Signal to other TQt processes that the selection has changed
+ Window owners[2];
+ owners[0] = newOwner;
+ owners[1] = prevOwner;
+ XChangeProperty( dpy, TQApplication::desktop()->screen(0)->winId(),
+ sentinel_atom, XA_WINDOW, 32, PropModeReplace,
+ (unsigned char*)&owners, 2 );
+}
+
+
+/*
+ Called by the main event loop in qapplication_x11.cpp when the
+ _TQT_SELECTION_SENTINEL property has been changed (i.e. when some TQt
+ process has performed TQClipboard::setData(). If it returns TRUE, the
+ TQClipBoard dataChanged() signal should be emitted.
+*/
+
+bool qt_check_selection_sentinel()
+{
+ bool doIt = TRUE;
+ if ( owner ) {
+ /*
+ Since the X selection mechanism cannot give any signal when
+ the selection has changed, we emulate it (for TQt processes) here.
+ The notification should be ignored in case of either
+ a) This is the process that did setData (because setData()
+ then has already emitted dataChanged())
+ b) This is the process that owned the selection when dataChanged()
+ was called (because we have then received a SelectionClear event,
+ and have already emitted dataChanged() as a result of that)
+ */
+
+ Window* owners;
+ Atom actualType;
+ int actualFormat;
+ ulong nitems;
+ ulong bytesLeft;
+
+ if (XGetWindowProperty(TQPaintDevice::x11AppDisplay(),
+ TQApplication::desktop()->screen(0)->winId(),
+ qt_selection_sentinel, 0, 2, False, XA_WINDOW,
+ &actualType, &actualFormat, &nitems,
+ &bytesLeft, (unsigned char**)&owners) == Success) {
+ if ( actualType == XA_WINDOW && actualFormat == 32 && nitems == 2 ) {
+ Window win = owner->winId();
+ if ( owners[0] == win || owners[1] == win )
+ doIt = FALSE;
+ }
+
+ XFree( owners );
+ }
+ }
+
+ if (doIt) {
+ if ( waiting_for_data ) {
+ pending_selection_changed = TRUE;
+ if ( ! pending_timer_id )
+ pending_timer_id = TQApplication::clipboard()->startTimer( 0 );
+ doIt = FALSE;
+ } else {
+ selectionData()->clear();
+ }
+ }
+
+ return doIt;
+}
+
+
+bool qt_check_clipboard_sentinel()
+{
+ bool doIt = TRUE;
+ if (owner) {
+ Window *owners;
+ Atom actualType;
+ int actualFormat;
+ unsigned long nitems, bytesLeft;
+
+ if (XGetWindowProperty(TQPaintDevice::x11AppDisplay(),
+ TQApplication::desktop()->screen(0)->winId(),
+ qt_clipboard_sentinel, 0, 2, False, XA_WINDOW,
+ &actualType, &actualFormat, &nitems, &bytesLeft,
+ (unsigned char **) &owners) == Success) {
+ if (actualType == XA_WINDOW && actualFormat == 32 && nitems == 2) {
+ Window win = owner->winId();
+ if (owners[0] == win || owners[1] == win)
+ doIt = FALSE;
+ }
+
+ XFree(owners);
+ }
+ }
+
+ if (doIt) {
+ if ( waiting_for_data ) {
+ pending_clipboard_changed = TRUE;
+ if ( ! pending_timer_id )
+ pending_timer_id = TQApplication::clipboard()->startTimer( 0 );
+ doIt = FALSE;
+ } else {
+ clipboardData()->clear();
+ }
+ }
+
+ return doIt;
+}
+
+#endif // TQT_NO_CLIPBOARD
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqcolor.cpp b/tqtinterface/qt4/src/kernel/tqcolor.cpp
new file mode 100644
index 0000000..f245773
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqcolor.cpp
@@ -0,0 +1,1174 @@
+/****************************************************************************
+**
+** Implementation of TQColor class
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcolor.h"
+#include "tqnamespace.h"
+#include "tqdatastream.h"
+
+#include <stdio.h>
+
+#ifdef USE_QT4
+
+#include "Qt/qcolormap.h"
+
+/*****************************************************************************
+ Global colors
+ *****************************************************************************/
+
+#if defined(TQ_WS_WIN)
+#define COLOR0_PIX 0x00ffffff
+#define COLOR1_PIX 0
+#else
+#define COLOR0_PIX 0
+#define COLOR1_PIX 1
+#endif
+
+#if (defined(TQ_CC_GNU) && defined(TQ_OS_WIN))
+// workaround - bug in mingw
+static TQColor stdcol[19] = {
+ TQColor( 255, 255, 255 ),
+ TQColor( 0, 0, 0 ),
+ TQColor( 0, 0, 0 ),
+ TQColor( 255, 255, 255 ),
+ TQColor( 128, 128, 128 ),
+ TQColor( 160, 160, 164 ),
+ TQColor( 192, 192, 192 ),
+ TQColor( 255, 0, 0 ),
+ TQColor( 0, 255, 0 ),
+ TQColor( 0, 0, 255 ),
+ TQColor( 0, 255, 255 ),
+ TQColor( 255, 0, 255 ),
+ TQColor( 255, 255, 0 ),
+ TQColor( 128, 0, 0 ),
+ TQColor( 0, 128, 0 ),
+ TQColor( 0, 0, 128 ),
+ TQColor( 0, 128, 128 ),
+ TQColor( 128, 0, 128 ),
+ TQColor( 128, 128, 0 ) };
+#else
+ static TQColor stdcol[19];
+#endif
+
+TQT_STATIC_CONST_IMPL TQColor & TQt::color0 = stdcol[0];
+TQT_STATIC_CONST_IMPL TQColor & TQt::color1 = stdcol[1];
+TQT_STATIC_CONST_IMPL TQColor & TQt::black = stdcol[2];
+TQT_STATIC_CONST_IMPL TQColor & TQt::white = stdcol[3];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkGray = stdcol[4];
+TQT_STATIC_CONST_IMPL TQColor & TQt::gray = stdcol[5];
+TQT_STATIC_CONST_IMPL TQColor & TQt::lightGray = stdcol[6];
+TQT_STATIC_CONST_IMPL TQColor & TQt::red = stdcol[7];
+TQT_STATIC_CONST_IMPL TQColor & TQt::green = stdcol[8];
+TQT_STATIC_CONST_IMPL TQColor & TQt::blue = stdcol[9];
+TQT_STATIC_CONST_IMPL TQColor & TQt::cyan = stdcol[10];
+TQT_STATIC_CONST_IMPL TQColor & TQt::magenta = stdcol[11];
+TQT_STATIC_CONST_IMPL TQColor & TQt::yellow = stdcol[12];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkRed = stdcol[13];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkGreen = stdcol[14];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkBlue = stdcol[15];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkCyan = stdcol[16];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkMagenta = stdcol[17];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkYellow = stdcol[18];
+
+/*****************************************************************************
+ TQColor member functions
+ *****************************************************************************/
+
+bool TQColor::color_init = FALSE; // color system not initialized
+bool TQColor::globals_init = FALSE; // global color not initialized
+TQColor::ColorModel TQColor::colormodel = d32;
+
+/*!
+ Returns the pixel value used by the underlying window system to refer to a
+ color.
+
+ Use QColormap::pixel() instead.
+
+ \oldcode
+ QColor myColor;
+ uint pixel = myColor.pixel(screen);
+ \newcode
+ QColormap cmap = QColormap::instance(screen);
+ uint pixel = cmap.pixel(*this);
+ \endcode
+*/
+uint TQColor::pixel(int screen) const
+{
+ QColormap cmap = QColormap::instance(screen);
+ return cmap.pixel(*this);
+}
+
+void TQColor::initGlobalColors()
+{
+ globals_init = TRUE;
+
+// #ifdef TQ_WS_X11
+// // HACK: we need a way to recognize color0 and color1 uniquely, so
+// // that we can use color0 and color1 with fixed pixel values on
+// // all screens
+// stdcol[ 0].d.argb = tqRgba(255, 255, 255, 1);
+// stdcol[ 1].d.argb = tqRgba( 0, 0, 0, 1);
+// #else
+// stdcol[ 0].d.argb = tqRgb(255,255,255);
+// stdcol[ 1].d.argb = 0;
+// #endif // TQ_WS_X11
+// stdcol[ 0].setPixel( COLOR0_PIX );
+// stdcol[ 1].setPixel( COLOR1_PIX );
+ stdcol[ 0] = Qt::color0;
+ stdcol[ 1] = Qt::color1;
+
+ // From the "The Palette Manager: How and Why" by Ron Gery, March 23,
+ // 1992, archived on MSDN:
+ // The Windows system palette is broken up into two sections,
+ // one with fixed colors and one with colors that can be changed
+ // by applications. The system palette predefines 20 entries;
+ // these colors are known as the static or reserved colors and
+ // consist of the 16 colors found in the Windows version 3.0 VGA
+ // driver and 4 additional colors chosen for their visual appeal.
+ // The DEFAULT_PALETTE stock object is, as the name implies, the
+ // default palette selected into a tqdevice context (DC) and consists
+ // of these static colors. Applications can set the remaining 236
+ // colors using the Palette Manager.
+ // The 20 reserved entries have indices in [0,9] and [246,255]. We
+ // reuse 17 of them.
+ stdcol[ 2].setRgb( 0, 0, 0 ); // index 0 black
+ stdcol[ 3].setRgb( 255, 255, 255 ); // index 255 white
+ stdcol[ 4].setRgb( 128, 128, 128 ); // index 248 medium gray
+ stdcol[ 5].setRgb( 160, 160, 164 ); // index 247 light gray
+ stdcol[ 6].setRgb( 192, 192, 192 ); // index 7 light gray
+ stdcol[ 7].setRgb( 255, 0, 0 ); // index 249 red
+ stdcol[ 8].setRgb( 0, 255, 0 ); // index 250 green
+ stdcol[ 9].setRgb( 0, 0, 255 ); // index 252 blue
+ stdcol[10].setRgb( 0, 255, 255 ); // index 254 cyan
+ stdcol[11].setRgb( 255, 0, 255 ); // index 253 magenta
+ stdcol[12].setRgb( 255, 255, 0 ); // index 251 yellow
+ stdcol[13].setRgb( 128, 0, 0 ); // index 1 dark red
+ stdcol[14].setRgb( 0, 128, 0 ); // index 2 dark green
+ stdcol[15].setRgb( 0, 0, 128 ); // index 4 dark blue
+ stdcol[16].setRgb( 0, 128, 128 ); // index 6 dark cyan
+ stdcol[17].setRgb( 128, 0, 128 ); // index 5 dark magenta
+ stdcol[18].setRgb( 128, 128, 0 ); // index 3 dark yellow
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQColor tqcolor.h
+ \brief The TQColor class provides colors based on RGB or HSV values.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup appearance
+
+ A color is normally specified in terms of RGB (red, green and blue)
+ components, but it is also possible to specify HSV (hue, saturation
+ and value) or set a color name (the names are copied from from the
+ X11 color database).
+
+ In addition to the RGB value, a TQColor also has a pixel value and a
+ validity. The pixel value is used by the underlying window system
+ to refer to a color. It can be thought of as an index into the
+ display hardware's color table.
+
+ The validity (isValid()) indicates whether the color is legal at
+ all. For example, a RGB color with RGB values out of range is
+ illegal. For performance reasons, TQColor mostly disregards illegal
+ colors. The result of using an invalid color is unspecified and
+ will usually be surprising.
+
+ There are 19 predefined TQColor objects: \c white, \c black, \c
+ red, \c darkRed, \c green, \c darkGreen, \c blue, \c darkBlue, \c
+ cyan, \c darkCyan, \c magenta, \c darkMagenta, \c yellow, \c
+ darkYellow, \c gray, \c darkGray, \c lightGray, \c color0 and \c
+ color1, accessible as members of the TQt namespace (ie. \c TQt::red).
+
+ \img qt-colors.png TQt Colors
+
+ The colors \c color0 (zero pixel value) and \c color1 (non-zero
+ pixel value) are special colors for drawing in \link TQBitmap
+ bitmaps\endlink. Painting with \c color0 sets the bitmap bits to 0
+ (transtqparent, i.e. background), and painting with \c color1 sets the
+ bits to 1 (opaque, i.e. foreground).
+
+ The TQColor class has an efficient, dynamic color allocation
+ strategy. A color is normally allocated the first time it is used
+ (lazy allocation), that is, whenever the pixel() function is called.
+ The following steps are taken to allocate a color. If, at any point,
+ a suitable color is found then the appropriate pixel value is
+ returned and the subsequent steps are not taken:
+
+ \list 1
+ \i Is the pixel value valid? If it is, just return it; otherwise,
+ allocate a pixel value.
+ \i Check an internal hash table to see if we allocated an equal RGB
+ value earlier. If we did, set the corresponding pixel value for the
+ color and return it.
+ \i Try to allocate the RGB value. If we succeed, we get a pixel value
+ that we save in the internal table with the RGB value.
+ Return the pixel value.
+ \i The color could not be allocated. Find the closest matching
+ color, save it in the internal table, and return it.
+ \endlist
+
+ A color can be set by passing setNamedColor() an RGB string like
+ "#112233", or a color name, e.g. "blue". The names are taken from
+ X11's rgb.txt database but can also be used under Windows. To get
+ a lighter or darker color use light() and dark() respectively.
+ Colors can also be set using setRgb() and setHsv(). The color
+ components can be accessed in one go with rgb() and hsv(), or
+ individually with red(), green() and blue().
+
+ Use maxColors() and numBitPlanes() to determine the maximum number
+ of colors and the number of bit planes supported by the underlying
+ window system,
+
+ If you need to allocate many colors temporarily, for example in an
+ image viewer application, enterAllocContext(), leaveAllocContext() and
+ destroyAllocContext() will prove useful.
+
+ \section1 HSV Colors
+
+ Because many people don't know the HSV color model very well, we'll
+ cover it briefly here.
+
+ The RGB model is hardware-oriented. Its representation is close to
+ what most monitors show. In contrast, HSV represents color in a way
+ more suited to the human perception of color. For example, the
+ relationships "stronger than", "darker than" and "the opposite of"
+ are easily expressed in HSV but are much harder to express in RGB.
+
+ HSV, like RGB, has three components:
+
+ \list
+
+ \i H, for hue, is either 0-359 if the color is chromatic (not
+ gray), or meaningless if it is gray. It represents degrees on the
+ color wheel familiar to most people. Red is 0 (degrees), green is
+ 120 and blue is 240.
+
+ \i S, for saturation, is 0-255, and the bigger it is, the
+ stronger the color is. Grayish colors have saturation near 0; very
+ strong colors have saturation near 255.
+
+ \i V, for value, is 0-255 and represents lightness or brightness
+ of the color. 0 is black; 255 is as far from black as possible.
+
+ \endlist
+
+ Here are some examples: Pure red is H=0, S=255, V=255. A dark red,
+ moving slightly towards the magenta, could be H=350 (equivalent to
+ -10), S=255, V=180. A grayish light red could have H about 0 (say
+ 350-359 or 0-10), S about 50-100, and S=255.
+
+ TQt returns a hue value of -1 for achromatic colors. If you pass a
+ too-big hue value, TQt forces it into range. Hue 360 or 720 is
+ treated as 0; hue 540 is treated as 180.
+
+ \sa TQPalette, TQColorGroup, TQApplication::setColorSpec(),
+ \link http://www.poynton.com/ColorFAQ.html Color FAQ\endlink
+*/
+
+/*****************************************************************************
+ Global colors
+ *****************************************************************************/
+
+#if defined(TQ_WS_WIN)
+#define COLOR0_PIX 0x00ffffff
+#define COLOR1_PIX 0
+#else
+#define COLOR0_PIX 0
+#define COLOR1_PIX 1
+#endif
+
+#if (defined(TQ_CC_GNU) && defined(TQ_OS_WIN))
+// workaround - bug in mingw
+static TQColor stdcol[19] = {
+ TQColor( 255, 255, 255 ),
+ TQColor( 0, 0, 0 ),
+ TQColor( 0, 0, 0 ),
+ TQColor( 255, 255, 255 ),
+ TQColor( 128, 128, 128 ),
+ TQColor( 160, 160, 164 ),
+ TQColor( 192, 192, 192 ),
+ TQColor( 255, 0, 0 ),
+ TQColor( 0, 255, 0 ),
+ TQColor( 0, 0, 255 ),
+ TQColor( 0, 255, 255 ),
+ TQColor( 255, 0, 255 ),
+ TQColor( 255, 255, 0 ),
+ TQColor( 128, 0, 0 ),
+ TQColor( 0, 128, 0 ),
+ TQColor( 0, 0, 128 ),
+ TQColor( 0, 128, 128 ),
+ TQColor( 128, 0, 128 ),
+ TQColor( 128, 128, 0 ) };
+#else
+ static TQColor stdcol[19];
+#endif
+
+TQT_STATIC_CONST_IMPL TQColor & TQt::color0 = stdcol[0];
+TQT_STATIC_CONST_IMPL TQColor & TQt::color1 = stdcol[1];
+TQT_STATIC_CONST_IMPL TQColor & TQt::black = stdcol[2];
+TQT_STATIC_CONST_IMPL TQColor & TQt::white = stdcol[3];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkGray = stdcol[4];
+TQT_STATIC_CONST_IMPL TQColor & TQt::gray = stdcol[5];
+TQT_STATIC_CONST_IMPL TQColor & TQt::lightGray = stdcol[6];
+TQT_STATIC_CONST_IMPL TQColor & TQt::red = stdcol[7];
+TQT_STATIC_CONST_IMPL TQColor & TQt::green = stdcol[8];
+TQT_STATIC_CONST_IMPL TQColor & TQt::blue = stdcol[9];
+TQT_STATIC_CONST_IMPL TQColor & TQt::cyan = stdcol[10];
+TQT_STATIC_CONST_IMPL TQColor & TQt::magenta = stdcol[11];
+TQT_STATIC_CONST_IMPL TQColor & TQt::yellow = stdcol[12];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkRed = stdcol[13];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkGreen = stdcol[14];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkBlue = stdcol[15];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkCyan = stdcol[16];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkMagenta = stdcol[17];
+TQT_STATIC_CONST_IMPL TQColor & TQt::darkYellow = stdcol[18];
+
+
+/*****************************************************************************
+ TQColor member functions
+ *****************************************************************************/
+
+bool TQColor::color_init = FALSE; // color system not initialized
+bool TQColor::globals_init = FALSE; // global color not initialized
+TQColor::ColorModel TQColor::colormodel = d32;
+
+
+TQColor* TQColor::globalColors()
+{
+ return stdcol;
+}
+
+
+/*!
+ Initializes the global colors. This function is called if a global
+ color variable is initialized before the constructors for our
+ global color objects are executed. Without this mechanism,
+ assigning a color might assign an uninitialized value.
+
+ Example:
+ \code
+ TQColor myColor = red; // will initialize red etc.
+
+ int main( int argc, char **argc )
+ {
+ }
+ \endcode
+*/
+
+void TQColor::initGlobalColors()
+{
+ globals_init = TRUE;
+
+ #ifdef TQ_WS_X11
+ // HACK: we need a way to recognize color0 and color1 uniquely, so
+ // that we can use color0 and color1 with fixed pixel values on
+ // all screens
+ stdcol[ 0].d.argb = tqRgba(255, 255, 255, 1);
+ stdcol[ 1].d.argb = tqRgba( 0, 0, 0, 1);
+ #else
+ stdcol[ 0].d.argb = tqRgb(255,255,255);
+ stdcol[ 1].d.argb = 0;
+ #endif // TQ_WS_X11
+ stdcol[ 0].setPixel( COLOR0_PIX );
+ stdcol[ 1].setPixel( COLOR1_PIX );
+
+ // From the "The Palette Manager: How and Why" by Ron Gery, March 23,
+ // 1992, archived on MSDN:
+ // The Windows system palette is broken up into two sections,
+ // one with fixed colors and one with colors that can be changed
+ // by applications. The system palette predefines 20 entries;
+ // these colors are known as the static or reserved colors and
+ // consist of the 16 colors found in the Windows version 3.0 VGA
+ // driver and 4 additional colors chosen for their visual appeal.
+ // The DEFAULT_PALETTE stock object is, as the name implies, the
+ // default palette selected into a tqdevice context (DC) and consists
+ // of these static colors. Applications can set the remaining 236
+ // colors using the Palette Manager.
+ // The 20 reserved entries have indices in [0,9] and [246,255]. We
+ // reuse 17 of them.
+ stdcol[ 2].setRgb( 0, 0, 0 ); // index 0 black
+ stdcol[ 3].setRgb( 255, 255, 255 ); // index 255 white
+ stdcol[ 4].setRgb( 128, 128, 128 ); // index 248 medium gray
+ stdcol[ 5].setRgb( 160, 160, 164 ); // index 247 light gray
+ stdcol[ 6].setRgb( 192, 192, 192 ); // index 7 light gray
+ stdcol[ 7].setRgb( 255, 0, 0 ); // index 249 red
+ stdcol[ 8].setRgb( 0, 255, 0 ); // index 250 green
+ stdcol[ 9].setRgb( 0, 0, 255 ); // index 252 blue
+ stdcol[10].setRgb( 0, 255, 255 ); // index 254 cyan
+ stdcol[11].setRgb( 255, 0, 255 ); // index 253 magenta
+ stdcol[12].setRgb( 255, 255, 0 ); // index 251 yellow
+ stdcol[13].setRgb( 128, 0, 0 ); // index 1 dark red
+ stdcol[14].setRgb( 0, 128, 0 ); // index 2 dark green
+ stdcol[15].setRgb( 0, 0, 128 ); // index 4 dark blue
+ stdcol[16].setRgb( 0, 128, 128 ); // index 6 dark cyan
+ stdcol[17].setRgb( 128, 0, 128 ); // index 5 dark magenta
+ stdcol[18].setRgb( 128, 128, 0 ); // index 3 dark yellow
+}
+
+/*!
+ \enum TQColor::Spec
+
+ The type of color specified, either RGB or HSV, e.g. in the
+ \c{TQColor::TQColor( x, y, z, colorSpec)} constructor.
+
+ \value Rgb
+ \value Hsv
+*/
+
+
+/*!
+ \fn TQColor::TQColor()
+
+ Constructs an invalid color with the RGB value (0, 0, 0). An
+ invalid color is a color that is not properly set up for the
+ underlying window system.
+
+ The alpha value of an invalid color is unspecified.
+
+ \sa isValid()
+*/
+
+
+/*!
+ \fn TQColor::TQColor( int r, int g, int b )
+
+ Constructs a color with the RGB value \a r, \a g, \a b, in the
+ same way as setRgb().
+
+ The color is left invalid if any or the arguments are illegal.
+
+ \sa setRgb()
+*/
+
+
+/*!
+ Constructs a color with the RGB value \a rgb and a custom pixel
+ value \a pixel.
+
+ If \a pixel == 0xffffffff (the default), then the color uses the
+ RGB value in a standard way. If \a pixel is something else, then
+ the pixel value is set directly to \a pixel, skipping the normal
+ allocation procedure.
+*/
+
+TQColor::TQColor( TQRgb rgb, uint pixel )
+{
+ if ( pixel == 0xffffffff ) {
+ setRgb( rgb );
+ } else {
+ d.argb = rgb;
+ setPixel( pixel );
+ }
+}
+
+void TQColor::setPixel( uint pixel )
+{
+ switch ( colormodel ) {
+ case d8:
+ d.d8.direct = TRUE;
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pixel;
+ break;
+ case d32:
+ d.d32.pix = pixel;
+ break;
+ }
+}
+
+
+/*!
+ Constructs a color with the RGB or HSV value \a x, \a y, \a z.
+
+ The arguments are an RGB value if \a colorSpec is TQColor::Rgb. \a
+ x (red), \a y (green), and \a z (blue). All of them must be in the
+ range 0-255.
+
+ The arguments are an HSV value if \a colorSpec is TQColor::Hsv. \a
+ x (hue) must be -1 for achromatic colors and 0-359 for chromatic
+ colors; \a y (saturation) and \a z (value) must both be in the
+ range 0-255.
+
+ \sa setRgb(), setHsv()
+*/
+
+TQColor::TQColor( int x, int y, int z, Spec colorSpec )
+{
+ d.d32.argb = Invalid;
+ d.d32.pix = Dirt;
+ if ( colorSpec == Hsv )
+ setHsv( x, y, z );
+ else
+ setRgb( x, y, z );
+}
+
+
+/*!
+ Constructs a named color in the same way as setNamedColor() using
+ name \a name.
+
+ The color is left invalid if \a name cannot be parsed.
+
+ \sa setNamedColor()
+*/
+
+TQColor::TQColor( const TQString& name )
+{
+ setNamedColor( name );
+}
+
+
+/*!
+ Constructs a named color in the same way as setNamedColor() using
+ name \a name.
+
+ The color is left invalid if \a name cannot be parsed.
+
+ \sa setNamedColor()
+*/
+
+TQColor::TQColor( const char *name )
+{
+ setNamedColor( TQString(name) );
+}
+
+
+
+/*!
+ Constructs a color that is a copy of \a c.
+*/
+
+TQColor::TQColor( const TQColor &c )
+{
+ if ( !globals_init )
+ initGlobalColors();
+ d.argb = c.d.argb;
+ d.d32.pix = c.d.d32.pix;
+}
+
+
+/*!
+ Assigns a copy of the color \a c and returns a reference to this
+ color.
+*/
+
+TQColor &TQColor::operator=( const TQColor &c )
+{
+ if ( !globals_init )
+ initGlobalColors();
+ d.argb = c.d.argb;
+ d.d32.pix = c.d.d32.pix;
+ return *this;
+}
+
+
+/*!
+ \fn bool TQColor::isValid() const
+
+ Returns FALSE if the color is invalid, i.e. it was constructed using the
+ default constructor; otherwise returns TRUE.
+*/
+
+/*!
+ \internal
+*/
+bool TQColor::isDirty() const
+{
+ if ( colormodel == d8 ) {
+ return d.d8.dirty;
+ } else {
+ return d.d32.probablyDirty();
+ }
+}
+
+/*!
+ Returns the name of the color in the format "#RRGGBB", i.e. a "#"
+ character followed by three two-digit hexadecimal numbers.
+
+ \sa setNamedColor()
+*/
+
+TQString TQColor::name() const
+{
+#ifndef TQT_NO_SPRINTF
+ TQString s;
+ s.sprintf( "#%02x%02x%02x", red(), green(), blue() );
+ return s;
+#else
+ char s[20];
+ sprintf( s, "#%02x%02x%02x", red(), green(), blue() );
+ return TQString(s);
+#endif
+}
+
+static int hex2int( TQChar hexchar )
+{
+ int v;
+ if ( hexchar.isDigit() )
+ v = hexchar.digitValue();
+ else if ( hexchar >= 'A' && hexchar <= 'F' )
+ v = hexchar.cell() - 'A' + 10;
+ else if ( hexchar >= 'a' && hexchar <= 'f' )
+ v = hexchar.cell() - 'a' + 10;
+ else
+ v = -1;
+ return v;
+}
+
+
+/*!
+ Sets the RGB value to \a name, which may be in one of these
+ formats:
+ \list
+ \i #RGB (each of R, G and B is a single hex digit)
+ \i #RRGGBB
+ \i #RRRGGGBBB
+ \i #RRRRGGGGBBBB
+ \i A name from the X color database (rgb.txt) (e.g.
+ "steelblue" or "gainsboro"). These color names also work
+ under Windows.
+ \endlist
+
+ The color is invalid if \a name cannot be parsed.
+*/
+
+void TQColor::setNamedColor( const TQString &name )
+{
+ if ( name.isEmpty() ) {
+ d.argb = 0;
+ if ( colormodel == d8 ) {
+ d.d8.invalid = TRUE;
+ } else {
+ d.d32.argb = Invalid;
+ }
+ } else if ( name[0] == '#' ) {
+ const TQChar *p = name.tqunicode()+1;
+ int len = name.length()-1;
+ int r, g, b;
+ if ( len == 12 ) {
+ r = (hex2int(p[0]) << 4) + hex2int(p[1]);
+ g = (hex2int(p[4]) << 4) + hex2int(p[5]);
+ b = (hex2int(p[8]) << 4) + hex2int(p[9]);
+ } else if ( len == 9 ) {
+ r = (hex2int(p[0]) << 4) + hex2int(p[1]);
+ g = (hex2int(p[3]) << 4) + hex2int(p[4]);
+ b = (hex2int(p[6]) << 4) + hex2int(p[7]);
+ } else if ( len == 6 ) {
+ r = (hex2int(p[0]) << 4) + hex2int(p[1]);
+ g = (hex2int(p[2]) << 4) + hex2int(p[3]);
+ b = (hex2int(p[4]) << 4) + hex2int(p[5]);
+ } else if ( len == 3 ) {
+ r = (hex2int(p[0]) << 4) + hex2int(p[0]);
+ g = (hex2int(p[1]) << 4) + hex2int(p[1]);
+ b = (hex2int(p[2]) << 4) + hex2int(p[2]);
+ } else {
+ r = g = b = -1;
+ }
+ if ( (uint)r > 255 || (uint)g > 255 || (uint)b > 255 ) {
+ d.d32.argb = Invalid;
+ d.d32.pix = Dirt;
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQColor::setNamedColor: could not parse color '%s'",
+ name.local8Bit().data() );
+#endif
+ } else {
+ setRgb( r, g, b );
+ }
+ } else {
+ setSystemNamedColor( name );
+ }
+}
+
+
+#undef max
+#undef min
+
+/*!
+ \fn void TQColor::getHsv( int &h, int &s, int &v ) const
+ \obsolete
+*/
+
+/*! \fn void TQColor::getHsv( int *h, int *s, int *v ) const
+
+ Returns the current RGB value as HSV. The contents of the \a h, \a
+ s and \a v pointers are set to the HSV values. If any of the three
+ pointers are null, the function does nothing.
+
+ The hue (which \a h points to) is set to -1 if the color is
+ achromatic.
+
+ \warning Colors are stored internally as RGB values, so getHSv()
+ may return slightly different values to those set by setHsv().
+
+ \sa setHsv(), rgb()
+*/
+
+/*! \obsolete Use getHsv() instead.
+ */
+void TQColor::hsv( int *h, int *s, int *v ) const
+{
+ if ( !h || !s || !v )
+ return;
+ int r = tqRed(d.argb);
+ int g = tqGreen(d.argb);
+ int b = tqBlue(d.argb);
+ uint max = r; // maximum RGB component
+ int whatmax = 0; // r=>0, g=>1, b=>2
+ if ( (uint)g > max ) {
+ max = g;
+ whatmax = 1;
+ }
+ if ( (uint)b > max ) {
+ max = b;
+ whatmax = 2;
+ }
+ uint min = r; // tqfind minimum value
+ if ( (uint)g < min ) min = g;
+ if ( (uint)b < min ) min = b;
+ int delta = max-min;
+ *v = max; // calc value
+ *s = max ? (510*delta+max)/(2*max) : 0;
+ if ( *s == 0 ) {
+ *h = -1; // undefined hue
+ } else {
+ switch ( whatmax ) {
+ case 0: // red is max component
+ if ( g >= b )
+ *h = (120*(g-b)+delta)/(2*delta);
+ else
+ *h = (120*(g-b+delta)+delta)/(2*delta) + 300;
+ break;
+ case 1: // green is max component
+ if ( b > r )
+ *h = 120 + (120*(b-r)+delta)/(2*delta);
+ else
+ *h = 60 + (120*(b-r+delta)+delta)/(2*delta);
+ break;
+ case 2: // blue is max component
+ if ( r > g )
+ *h = 240 + (120*(r-g)+delta)/(2*delta);
+ else
+ *h = 180 + (120*(r-g+delta)+delta)/(2*delta);
+ break;
+ }
+ }
+}
+
+
+/*!
+ Sets a HSV color value. \a h is the hue, \a s is the saturation
+ and \a v is the value of the HSV color.
+
+ If \a s or \a v are not in the range 0-255, or \a h is < -1, the
+ color is not changed.
+
+ \warning Colors are stored internally as RGB values, so getHSv()
+ may return slightly different values to those set by setHsv().
+
+ \sa hsv(), setRgb()
+*/
+
+void TQColor::setHsv( int h, int s, int v )
+{
+ if ( h < -1 || (uint)s > 255 || (uint)v > 255 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQColor::setHsv: HSV parameters out of range" );
+#endif
+ return;
+ }
+ int r=v, g=v, b=v;
+ if ( s == 0 || h == -1 ) { // achromatic case
+ // Ignore
+ } else { // chromatic case
+ if ( (uint)h >= 360 )
+ h %= 360;
+ uint f = h%60;
+ h /= 60;
+ uint p = (uint)(2*v*(255-s)+255)/510;
+ uint q, t;
+ if ( h&1 ) {
+ q = (uint)(2*v*(15300-s*f)+15300)/30600;
+ switch( h ) {
+ case 1: r=(int)q; g=(int)v, b=(int)p; break;
+ case 3: r=(int)p; g=(int)q, b=(int)v; break;
+ case 5: r=(int)v; g=(int)p, b=(int)q; break;
+ }
+ } else {
+ t = (uint)(2*v*(15300-(s*(60-f)))+15300)/30600;
+ switch( h ) {
+ case 0: r=(int)v; g=(int)t, b=(int)p; break;
+ case 2: r=(int)p; g=(int)v, b=(int)t; break;
+ case 4: r=(int)t; g=(int)p, b=(int)v; break;
+ }
+ }
+ }
+ setRgb( r, g, b );
+}
+
+
+/*!
+ \fn TQRgb TQColor::rgb() const
+
+ Returns the RGB value.
+
+ The return type \e TQRgb is equivalent to \c unsigned \c int.
+
+ For an invalid color, the alpha value of the returned color is
+ unspecified.
+
+ \sa setRgb(), hsv(), tqRed(), tqBlue(), tqGreen(), isValid()
+*/
+
+/*! \fn void TQColor::getRgb( int *r, int *g, int *b ) const
+
+ Sets the contents pointed to by \a r, \a g and \a b to the red,
+ green and blue components of the RGB value respectively. The value
+ range for a component is 0..255.
+
+ \sa rgb(), setRgb(), getHsv()
+*/
+
+/*! \obsolete Use getRgb() instead */
+void TQColor::rgb( int *r, int *g, int *b ) const
+{
+ *r = tqRed(d.argb);
+ *g = tqGreen(d.argb);
+ *b = tqBlue(d.argb);
+}
+
+
+/*!
+ Sets the RGB value to \a r, \a g, \a b. The arguments, \a r, \a g
+ and \a b must all be in the range 0..255. If any of them are
+ outside the legal range, the color is not changed.
+
+ \sa rgb(), setHsv()
+*/
+
+void TQColor::setRgb( int r, int g, int b )
+{
+ if ( (uint)r > 255 || (uint)g > 255 || (uint)b > 255 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQColor::setRgb: RGB parameter(s) out of range" );
+#endif
+ return;
+ }
+ d.argb = tqRgb( r, g, b );
+ if ( colormodel == d8 ) {
+ d.d8.invalid = FALSE;
+ d.d8.direct = FALSE;
+ d.d8.dirty = TRUE;
+ } else {
+ d.d32.pix = Dirt;
+ }
+}
+
+
+/*!
+ \overload
+ Sets the RGB value to \a rgb.
+
+ The type \e TQRgb is equivalent to \c unsigned \c int.
+
+ \sa rgb(), setHsv()
+*/
+
+void TQColor::setRgb( TQRgb rgb )
+{
+ d.argb = rgb;
+ if ( colormodel == d8 ) {
+ d.d8.invalid = FALSE;
+ d.d8.direct = FALSE;
+ d.d8.dirty = TRUE;
+ } else {
+ d.d32.pix = Dirt;
+ }
+}
+
+/*!
+ \fn int TQColor::red() const
+
+ Returns the R (red) component of the RGB value.
+*/
+
+
+/*!
+ \fn int TQColor::green() const
+
+ Returns the G (green) component of the RGB value.
+*/
+
+/*!
+ \fn int TQColor::blue() const
+
+ Returns the B (blue) component of the RGB value.
+*/
+
+
+/*!
+ Returns a lighter (or darker) color, but does not change this
+ object.
+
+ Returns a lighter color if \a factor is greater than 100. Setting
+ \a factor to 150 returns a color that is 50% brighter.
+
+ Returns a darker color if \a factor is less than 100. We recommend
+ using dark() for this purpose. If \a factor is 0 or negative, the
+ return value is unspecified.
+
+ (This function converts the current RGB color to HSV, multiplies V
+ by \a factor, and converts the result back to RGB.)
+
+ \sa dark()
+*/
+
+TQColor TQColor::light( int factor ) const
+{
+ if ( factor <= 0 ) // invalid lightness factor
+ return *this;
+ else if ( factor < 100 ) // makes color darker
+ return dark( 10000/factor );
+
+ int h, s, v;
+ hsv( &h, &s, &v );
+ v = (factor*v)/100;
+ if ( v > 255 ) { // overflow
+ s -= v-255; // adjust saturation
+ if ( s < 0 )
+ s = 0;
+ v = 255;
+ }
+ TQColor c;
+ c.setHsv( h, s, v );
+ return c;
+}
+
+
+/*!
+ Returns a darker (or lighter) color, but does not change this
+ object.
+
+ Returns a darker color if \a factor is greater than 100. Setting
+ \a factor to 300 returns a color that has one-third the
+ brightness.
+
+ Returns a lighter color if \a factor is less than 100. We
+ recommend using lighter() for this purpose. If \a factor is 0 or
+ negative, the return value is unspecified.
+
+ (This function converts the current RGB color to HSV, divides V by
+ \a factor and converts back to RGB.)
+
+ \sa light()
+*/
+
+TQColor TQColor::dark( int factor ) const
+{
+ if ( factor <= 0 ) // invalid darkness factor
+ return *this;
+ else if ( factor < 100 ) // makes color lighter
+ return light( 10000/factor );
+ int h, s, v;
+ hsv( &h, &s, &v );
+ v = (v*100)/factor;
+ TQColor c;
+ c.setHsv( h, s, v );
+ return c;
+}
+
+
+/*!
+ \fn bool TQColor::operator==( const TQColor &c ) const
+
+ Returns TRUE if this color has the same RGB value as \a c;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQColor::operator!=( const TQColor &c ) const
+ Returns TRUE if this color has a different RGB value from \a c;
+ otherwise returns FALSE.
+*/
+
+/*!
+ Returns the pixel value.
+
+ This value is used by the underlying window system to refer to a
+ color. It can be thought of as an index into the display
+ hardware's color table, but the value is an arbitrary 32-bit
+ value.
+
+ \sa alloc()
+*/
+uint TQColor::pixel() const
+{
+ if ( isDirty() )
+ return ((TQColor*)this)->alloc();
+ else if ( colormodel == d8 )
+#ifdef TQ_WS_WIN
+ // since d.d8.pix is uchar we have to use the PALETTEINDEX
+ // macro to get the respective palette entry index.
+ return (0x01000000 | (int)(short)(d.d8.pix));
+#else
+ return d.d8.pix;
+#endif
+ else
+ return d.d32.pix;
+}
+
+/*!
+ \fn TQStringList TQColor::colorNames()
+ Returns a TQStringList containing the color names TQt knows about.
+*/
+
+/*****************************************************************************
+ TQColor stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQColor
+ Writes a color object, \a c to the stream, \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQColor &c )
+{
+ TQ_UINT32 p = (TQ_UINT32)c.rgb();
+ if ( s.version() == 1 ) // Swap red and blue
+ p = ((p << 16) & 0xff0000) | ((p >> 16) & 0xff) | (p & 0xff00ff00);
+ return s << p;
+}
+
+/*!
+ \relates TQColor
+ Reads a color object, \a c, from the stream, \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQColor &c )
+{
+ TQ_UINT32 p;
+ s >> p;
+ if ( s.version() == 1 ) // Swap red and blue
+ p = ((p << 16) & 0xff0000) | ((p >> 16) & 0xff) | (p & 0xff00ff00);
+ c.setRgb( p );
+ return s;
+}
+#endif
+
+/*****************************************************************************
+ TQColor global functions (documentation only)
+ *****************************************************************************/
+
+/*!
+ \fn int tqRed( TQRgb rgb )
+ \relates TQColor
+
+ Returns the red component of the RGB triplet \a rgb.
+ \sa tqRgb(), TQColor::red()
+*/
+
+/*!
+ \fn int tqGreen( TQRgb rgb )
+ \relates TQColor
+
+ Returns the green component of the RGB triplet \a rgb.
+ \sa tqRgb(), TQColor::green()
+*/
+
+/*!
+ \fn int tqBlue( TQRgb rgb )
+ \relates TQColor
+
+ Returns the blue component of the RGB triplet \a rgb.
+ \sa tqRgb(), TQColor::blue()
+*/
+
+/*!
+ \fn int tqAlpha( TQRgb rgba )
+ \relates TQColor
+
+ Returns the alpha component of the RGBA quadruplet \a rgba.
+ */
+
+/*!
+ \fn TQRgb tqRgb( int r, int g, int b )
+ \relates TQColor
+
+ Returns the RGB triplet \a (r,g,b).
+
+ The return type TQRgb is equivalent to \c unsigned \c int.
+
+ \sa tqRgba(), tqRed(), tqGreen(), tqBlue()
+*/
+
+/*!
+ \fn TQRgb tqRgba( int r, int g, int b, int a )
+ \relates TQColor
+
+ Returns the RGBA quadruplet \a (r,g,b,a).
+
+ The return type TQRgba is equivalent to \c unsigned \c int.
+
+ \sa tqRgb(), tqRed(), tqGreen(), tqBlue()
+*/
+
+/*!
+ \fn int tqGray( int r, int g, int b )
+ \relates TQColor
+
+ Returns a gray value 0..255 from the (\a r, \a g, \a b) triplet.
+
+ The gray value is calculated using the formula (r*11 + g*16 +
+ b*5)/32.
+*/
+
+/*!
+ \overload int tqGray( tqRgb rgb )
+ \relates TQColor
+
+ Returns a gray value 0..255 from the given \a rgb colour.
+*/
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqcolor.h b/tqtinterface/qt4/src/kernel/tqcolor.h
new file mode 100644
index 0000000..38979a7
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqcolor.h
@@ -0,0 +1,348 @@
+/****************************************************************************
+**
+** Definition of TQColor class
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCOLOR_H
+#define TQCOLOR_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qcolor.h>
+#include <Qt/qmetatype.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+const TQRgb TQRGB_MASK = 0x00ffffff; // masks RGB values
+
+TQ_EXPORT inline int tqRed( TQRgb rgb ) // get red part of RGB
+{ return (int)((rgb >> 16) & 0xff); }
+
+TQ_EXPORT inline int tqGreen( TQRgb rgb ) // get green part of RGB
+{ return (int)((rgb >> 8) & 0xff); }
+
+TQ_EXPORT inline int tqBlue( TQRgb rgb ) // get blue part of RGB
+{ return (int)(rgb & 0xff); }
+
+TQ_EXPORT inline int tqAlpha( TQRgb rgb ) // get alpha part of RGBA
+{ return (int)((rgb >> 24) & 0xff); }
+
+TQ_EXPORT inline TQRgb tqRgb( int r, int g, int b )// set RGB value
+{ return (0xff << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
+
+TQ_EXPORT inline TQRgb tqRgba( int r, int g, int b, int a )// set RGBA value
+{ return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
+
+TQ_EXPORT inline int tqGray( int r, int g, int b )// convert R,G,B to gray 0..255
+{ return (r*11+g*16+b*5)/32; }
+
+TQ_EXPORT inline int tqGray( TQRgb rgb ) // convert RGB to gray 0..255
+{ return tqGray( tqRed(rgb), tqGreen(rgb), tqBlue(rgb) ); }
+
+class TQ_EXPORT TQColor : public QColor
+{
+public:
+ TQColor() : QColor() {}
+ TQColor( int r, int g, int b ) : QColor( r, g, b ) {}
+ TQColor( int x, int y, int z, Spec s ) : QColor() { if (s == Hsv) setHsv(x, y, z); else setRgb(x, y, z); }
+ TQColor( QRgb rgb, uint pixel=0xffffffff) : QColor( rgb ) { TQ_UNUSED(pixel); }
+ TQColor( const QString& name ) : QColor( name ) {}
+ TQColor( const char *name ) : QColor( name ) {}
+ TQColor( const QColor &cr ) : QColor( cr ) {}
+
+ inline TQRgb rgb() const { return QColor::rgb(); }
+ inline void rgb(int *r, int *g, int *b) const { getRgb(r, g, b); }
+ inline void hsv( int *h, int *s, int *v ) const { getHsv(h, s, v); }
+ inline void tqgetHsv( int &h, int &s, int &v ) const { getHsv(&h, &s, &v); }
+
+ static int enterAllocContext();
+ static void leaveAllocContext();
+ static int currentAllocContext();
+ static void destroyAllocContext( int );
+
+ inline void setRgba(int r, int g, int b, int a) { setRgb(r, g, b, a); }
+ inline void getRgba(int *r, int *g, int *b, int *a) const { getRgb(r, g, b, a); }
+
+ uint pixel(int screen = -1) const;
+
+ static int numBitPlanes();
+ uint alloc();
+// uint pixel() const;
+#if defined(TQ_WS_X11)
+ // ### in 4.0, make this take a default argument of -1 for default screen?
+ uint alloc( int screen );
+// uint pixel( int screen ) const;
+#endif
+
+ // [FIXME]
+ inline static void initialize() {
+ printf("[FIXME] TQColor static void initialize() partially implemented\n\r");
+ if ( !globals_init )
+ initGlobalColors();
+ }
+ inline static void cleanup() { printf("[WARNING] TQColor static void cleanup() not implemented\n\r"); }
+
+ enum { Dirt = 0x44495254, Invalid = 0x49000000 };
+private:
+ static bool globals_init;
+ static bool color_init;
+ static enum ColorModel { d8, d32 } colormodel;
+ union {
+ TQRgb argb;
+ struct D8 {
+ TQRgb argb;
+ uchar pix;
+ uchar invalid;
+ uchar dirty;
+ uchar direct;
+ } d8;
+ struct D32 {
+ TQRgb argb;
+ uint pix;
+ bool invalid() const { return argb == TQColor::Invalid && pix == TQColor::Dirt; }
+ bool probablyDirty() const { return pix == TQColor::Dirt; }
+ } d32;
+ } d;
+
+ static void initGlobalColors();
+public:
+ // Interoperability
+ static const TQColor& convertFromQColor( QColor& ql );
+};
+
+Q_DECLARE_METATYPE(TQColor)
+
+// Interoperability
+inline static const TQColor& convertFromQColor( const QColor& qs ) {
+ return (*static_cast<const TQColor*>(&qs));
+}
+
+#else // USE_QT4
+
+const TQRgb TQRGB_MASK = 0x00ffffff; // masks RGB values
+
+TQ_EXPORT inline int tqRed( TQRgb rgb ) // get red part of RGB
+{ return (int)((rgb >> 16) & 0xff); }
+
+TQ_EXPORT inline int tqGreen( TQRgb rgb ) // get green part of RGB
+{ return (int)((rgb >> 8) & 0xff); }
+
+TQ_EXPORT inline int tqBlue( TQRgb rgb ) // get blue part of RGB
+{ return (int)(rgb & 0xff); }
+
+TQ_EXPORT inline int tqAlpha( TQRgb rgb ) // get alpha part of RGBA
+{ return (int)((rgb >> 24) & 0xff); }
+
+TQ_EXPORT inline TQRgb tqRgb( int r, int g, int b )// set RGB value
+{ return (0xff << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
+
+TQ_EXPORT inline TQRgb tqRgba( int r, int g, int b, int a )// set RGBA value
+{ return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff); }
+
+TQ_EXPORT inline int tqGray( int r, int g, int b )// convert R,G,B to gray 0..255
+{ return (r*11+g*16+b*5)/32; }
+
+TQ_EXPORT inline int tqGray( TQRgb rgb ) // convert RGB to gray 0..255
+{ return tqGray( tqRed(rgb), tqGreen(rgb), tqBlue(rgb) ); }
+
+
+class TQ_EXPORT TQColor
+{
+public:
+ enum Spec { Rgb, Hsv };
+
+ TQColor();
+ TQColor( int r, int g, int b );
+ TQColor( int x, int y, int z, Spec );
+ TQColor( TQRgb rgb, uint pixel=0xffffffff);
+ TQColor( const TQString& name );
+ TQColor( const char *name );
+ TQColor( const TQColor & );
+ TQColor &operator=( const TQColor & );
+
+ bool isValid() const;
+ bool isDirty() const;
+ TQString name() const;
+ void setNamedColor( const TQString& name );
+
+ TQRgb rgb() const;
+ void setRgb( int r, int g, int b );
+ void setRgb( TQRgb rgb );
+ void getRgb( int *r, int *g, int *b ) const { rgb( r, g, b ); }
+ void rgb( int *r, int *g, int *b ) const; // obsolete
+
+ int red() const;
+ int green() const;
+ int blue() const;
+
+ void setHsv( int h, int s, int v );
+ void getHsv( int *h, int *s, int *v ) const { hsv( h, s, v ); }
+ void hsv( int *h, int *s, int *v ) const; // obsolete
+ void getHsv( int &h, int &s, int &v ) const { hsv( &h, &s, &v ); } // obsolete
+
+ TQColor light( int f = 150 ) const;
+ TQColor dark( int f = 200 ) const;
+
+ bool operator==( const TQColor &c ) const;
+ bool operator!=( const TQColor &c ) const;
+
+ uint alloc();
+ uint pixel() const;
+
+#if defined(TQ_WS_X11)
+ // ### in 4.0, make this take a default argument of -1 for default screen?
+ uint alloc( int screen );
+ uint pixel( int screen ) const;
+#endif
+
+ static int maxColors();
+ static int numBitPlanes();
+
+ static int enterAllocContext();
+ static void leaveAllocContext();
+ static int currentAllocContext();
+ static void destroyAllocContext( int );
+
+#if defined(TQ_WS_WIN)
+ static const TQRgb* palette( int* numEntries = 0 );
+ static int setPaletteEntries( const TQRgb* entries, int numEntries,
+ int base = -1 );
+ static HPALETTE hPal() { return hpal; }
+ static uint realizePal( TQWidget * );
+#endif
+
+ static void initialize();
+ static void cleanup();
+#ifndef TQT_NO_STRINGLIST
+ static TQStringList colorNames();
+#endif
+ enum { Dirt = 0x44495254, Invalid = 0x49000000 };
+
+private:
+ void setSystemNamedColor( const TQString& name );
+ void setPixel( uint pixel );
+ static void initGlobalColors();
+ static uint argbToPix32(TQRgb);
+ static TQColor* globalColors();
+ static bool color_init;
+ static bool globals_init;
+#if defined(TQ_WS_WIN)
+ static HPALETTE hpal;
+#endif
+ static enum ColorModel { d8, d32 } colormodel;
+ union {
+ TQRgb argb;
+ struct D8 {
+ TQRgb argb;
+ uchar pix;
+ uchar invalid;
+ uchar dirty;
+ uchar direct;
+ } d8;
+ struct D32 {
+ TQRgb argb;
+ uint pix;
+ bool invalid() const { return argb == TQColor::Invalid && pix == TQColor::Dirt; }
+ bool probablyDirty() const { return pix == TQColor::Dirt; }
+ } d32;
+ } d;
+};
+
+
+inline TQColor::TQColor()
+{ d.d32.argb = Invalid; d.d32.pix = Dirt; }
+
+inline TQColor::TQColor( int r, int g, int b )
+{
+ d.d32.argb = Invalid;
+ d.d32.pix = Dirt;
+ setRgb( r, g, b );
+}
+
+inline TQRgb TQColor::rgb() const
+{ return d.argb; }
+
+inline int TQColor::red() const
+{ return tqRed(d.argb); }
+
+inline int TQColor::green() const
+{ return tqGreen(d.argb); }
+
+inline int TQColor::blue() const
+{ return tqBlue(d.argb); }
+
+inline bool TQColor::isValid() const
+{
+ if ( colormodel == d8 )
+ return !d.d8.invalid;
+ else
+ return !d.d32.invalid();
+}
+
+inline bool TQColor::operator==( const TQColor &c ) const
+{
+ return d.argb == c.d.argb && isValid() == c.isValid();
+}
+
+inline bool TQColor::operator!=( const TQColor &c ) const
+{
+ return !operator==(c);
+}
+
+
+/*****************************************************************************
+ TQColor stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQColor & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQColor & );
+#endif
+
+#endif // USE_QT4
+
+#endif // TQCOLOR_H
diff --git a/tqtinterface/qt4/src/kernel/tqcolor_p.cpp b/tqtinterface/qt4/src/kernel/tqcolor_p.cpp
new file mode 100644
index 0000000..4f74408
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqcolor_p.cpp
@@ -0,0 +1,802 @@
+/****************************************************************************
+**
+** Named color support for non-X platforms.
+** The color names have been borrowed from X.
+**
+** Created : 000228
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqglobal.h"
+#if defined(TQ_CC_BOR)
+// needed for qsort() because of a std namespace problem on Borland
+#include "tqplatformdefs.h"
+#endif
+
+#include "tqcolor.h"
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+#ifndef TQT_NO_COLORNAMES
+
+#include <stdlib.h>
+
+#undef TQRGB
+#define TQRGB(r,g,b) (r*65536 + g*256 + b)
+
+const int rgbTblSize = 657;
+
+static const struct RGBData {
+ uint value;
+ const char *name;
+} rgbTbl[] = {
+ { TQRGB(240,248,255), "aliceblue" },
+ { TQRGB(250,235,215), "antiquewhite" },
+ { TQRGB(255,239,219), "antiquewhite1" },
+ { TQRGB(238,223,204), "antiquewhite2" },
+ { TQRGB(205,192,176), "antiquewhite3" },
+ { TQRGB(139,131,120), "antiquewhite4" },
+ { TQRGB(127,255,212), "aquamarine" },
+ { TQRGB(127,255,212), "aquamarine1" },
+ { TQRGB(118,238,198), "aquamarine2" },
+ { TQRGB(102,205,170), "aquamarine3" },
+ { TQRGB( 69,139,116), "aquamarine4" },
+ { TQRGB(240,255,255), "azure" },
+ { TQRGB(240,255,255), "azure1" },
+ { TQRGB(224,238,238), "azure2" },
+ { TQRGB(193,205,205), "azure3" },
+ { TQRGB(131,139,139), "azure4" },
+ { TQRGB(245,245,220), "beige" },
+ { TQRGB(255,228,196), "bisque" },
+ { TQRGB(255,228,196), "bisque1" },
+ { TQRGB(238,213,183), "bisque2" },
+ { TQRGB(205,183,158), "bisque3" },
+ { TQRGB(139,125,107), "bisque4" },
+ { TQRGB( 0, 0, 0), "black" },
+ { TQRGB(255,235,205), "blanchedalmond" },
+ { TQRGB( 0, 0,255), "blue" },
+ { TQRGB( 0, 0,255), "blue1" },
+ { TQRGB( 0, 0,238), "blue2" },
+ { TQRGB( 0, 0,205), "blue3" },
+ { TQRGB( 0, 0,139), "blue4" },
+ { TQRGB(138, 43,226), "blueviolet" },
+ { TQRGB(165, 42, 42), "brown" },
+ { TQRGB(255, 64, 64), "brown1" },
+ { TQRGB(238, 59, 59), "brown2" },
+ { TQRGB(205, 51, 51), "brown3" },
+ { TQRGB(139, 35, 35), "brown4" },
+ { TQRGB(222,184,135), "burlywood" },
+ { TQRGB(255,211,155), "burlywood1" },
+ { TQRGB(238,197,145), "burlywood2" },
+ { TQRGB(205,170,125), "burlywood3" },
+ { TQRGB(139,115, 85), "burlywood4" },
+ { TQRGB( 95,158,160), "cadetblue" },
+ { TQRGB(152,245,255), "cadetblue1" },
+ { TQRGB(142,229,238), "cadetblue2" },
+ { TQRGB(122,197,205), "cadetblue3" },
+ { TQRGB( 83,134,139), "cadetblue4" },
+ { TQRGB(127,255, 0), "chartreuse" },
+ { TQRGB(127,255, 0), "chartreuse1" },
+ { TQRGB(118,238, 0), "chartreuse2" },
+ { TQRGB(102,205, 0), "chartreuse3" },
+ { TQRGB( 69,139, 0), "chartreuse4" },
+ { TQRGB(210,105, 30), "chocolate" },
+ { TQRGB(255,127, 36), "chocolate1" },
+ { TQRGB(238,118, 33), "chocolate2" },
+ { TQRGB(205,102, 29), "chocolate3" },
+ { TQRGB(139, 69, 19), "chocolate4" },
+ { TQRGB(255,127, 80), "coral" },
+ { TQRGB(255,114, 86), "coral1" },
+ { TQRGB(238,106, 80), "coral2" },
+ { TQRGB(205, 91, 69), "coral3" },
+ { TQRGB(139, 62, 47), "coral4" },
+ { TQRGB(100,149,237), "cornflowerblue" },
+ { TQRGB(255,248,220), "cornsilk" },
+ { TQRGB(255,248,220), "cornsilk1" },
+ { TQRGB(238,232,205), "cornsilk2" },
+ { TQRGB(205,200,177), "cornsilk3" },
+ { TQRGB(139,136,120), "cornsilk4" },
+ { TQRGB( 0,255,255), "cyan" },
+ { TQRGB( 0,255,255), "cyan1" },
+ { TQRGB( 0,238,238), "cyan2" },
+ { TQRGB( 0,205,205), "cyan3" },
+ { TQRGB( 0,139,139), "cyan4" },
+ { TQRGB( 0, 0,139), "darkblue" },
+ { TQRGB( 0,139,139), "darkcyan" },
+ { TQRGB(184,134, 11), "darkgoldenrod" },
+ { TQRGB(255,185, 15), "darkgoldenrod1" },
+ { TQRGB(238,173, 14), "darkgoldenrod2" },
+ { TQRGB(205,149, 12), "darkgoldenrod3" },
+ { TQRGB(139,101, 8), "darkgoldenrod4" },
+ { TQRGB(169,169,169), "darkgray" },
+ { TQRGB( 0,100, 0), "darkgreen" },
+ { TQRGB(169,169,169), "darkgrey" },
+ { TQRGB(189,183,107), "darkkhaki" },
+ { TQRGB(139, 0,139), "darkmagenta" },
+ { TQRGB( 85,107, 47), "darkolivegreen" },
+ { TQRGB(202,255,112), "darkolivegreen1" },
+ { TQRGB(188,238,104), "darkolivegreen2" },
+ { TQRGB(162,205, 90), "darkolivegreen3" },
+ { TQRGB(110,139, 61), "darkolivegreen4" },
+ { TQRGB(255,140, 0), "darkorange" },
+ { TQRGB(255,127, 0), "darkorange1" },
+ { TQRGB(238,118, 0), "darkorange2" },
+ { TQRGB(205,102, 0), "darkorange3" },
+ { TQRGB(139, 69, 0), "darkorange4" },
+ { TQRGB(153, 50,204), "darkorchid" },
+ { TQRGB(191, 62,255), "darkorchid1" },
+ { TQRGB(178, 58,238), "darkorchid2" },
+ { TQRGB(154, 50,205), "darkorchid3" },
+ { TQRGB(104, 34,139), "darkorchid4" },
+ { TQRGB(139, 0, 0), "darkred" },
+ { TQRGB(233,150,122), "darksalmon" },
+ { TQRGB(143,188,143), "darkseagreen" },
+ { TQRGB(193,255,193), "darkseagreen1" },
+ { TQRGB(180,238,180), "darkseagreen2" },
+ { TQRGB(155,205,155), "darkseagreen3" },
+ { TQRGB(105,139,105), "darkseagreen4" },
+ { TQRGB( 72, 61,139), "darkslateblue" },
+ { TQRGB( 47, 79, 79), "darkslategray" },
+ { TQRGB(151,255,255), "darkslategray1" },
+ { TQRGB(141,238,238), "darkslategray2" },
+ { TQRGB(121,205,205), "darkslategray3" },
+ { TQRGB( 82,139,139), "darkslategray4" },
+ { TQRGB( 47, 79, 79), "darkslategrey" },
+ { TQRGB( 0,206,209), "darkturquoise" },
+ { TQRGB(148, 0,211), "darkviolet" },
+ { TQRGB(255, 20,147), "deeppink" },
+ { TQRGB(255, 20,147), "deeppink1" },
+ { TQRGB(238, 18,137), "deeppink2" },
+ { TQRGB(205, 16,118), "deeppink3" },
+ { TQRGB(139, 10, 80), "deeppink4" },
+ { TQRGB( 0,191,255), "deepskyblue" },
+ { TQRGB( 0,191,255), "deepskyblue1" },
+ { TQRGB( 0,178,238), "deepskyblue2" },
+ { TQRGB( 0,154,205), "deepskyblue3" },
+ { TQRGB( 0,104,139), "deepskyblue4" },
+ { TQRGB(105,105,105), "dimgray" },
+ { TQRGB(105,105,105), "dimgrey" },
+ { TQRGB( 30,144,255), "dodgerblue" },
+ { TQRGB( 30,144,255), "dodgerblue1" },
+ { TQRGB( 28,134,238), "dodgerblue2" },
+ { TQRGB( 24,116,205), "dodgerblue3" },
+ { TQRGB( 16, 78,139), "dodgerblue4" },
+ { TQRGB(178, 34, 34), "firebrick" },
+ { TQRGB(255, 48, 48), "firebrick1" },
+ { TQRGB(238, 44, 44), "firebrick2" },
+ { TQRGB(205, 38, 38), "firebrick3" },
+ { TQRGB(139, 26, 26), "firebrick4" },
+ { TQRGB(255,250,240), "floralwhite" },
+ { TQRGB( 34,139, 34), "forestgreen" },
+ { TQRGB(220,220,220), "gainsboro" },
+ { TQRGB(248,248,255), "ghostwhite" },
+ { TQRGB(255,215, 0), "gold" },
+ { TQRGB(255,215, 0), "gold1" },
+ { TQRGB(238,201, 0), "gold2" },
+ { TQRGB(205,173, 0), "gold3" },
+ { TQRGB(139,117, 0), "gold4" },
+ { TQRGB(218,165, 32), "goldenrod" },
+ { TQRGB(255,193, 37), "goldenrod1" },
+ { TQRGB(238,180, 34), "goldenrod2" },
+ { TQRGB(205,155, 29), "goldenrod3" },
+ { TQRGB(139,105, 20), "goldenrod4" },
+ { TQRGB(190,190,190), "gray" },
+ { TQRGB( 0, 0, 0), "gray0" },
+ { TQRGB( 3, 3, 3), "gray1" },
+ { TQRGB( 26, 26, 26), "gray10" },
+ { TQRGB(255,255,255), "gray100" },
+ { TQRGB( 28, 28, 28), "gray11" },
+ { TQRGB( 31, 31, 31), "gray12" },
+ { TQRGB( 33, 33, 33), "gray13" },
+ { TQRGB( 36, 36, 36), "gray14" },
+ { TQRGB( 38, 38, 38), "gray15" },
+ { TQRGB( 41, 41, 41), "gray16" },
+ { TQRGB( 43, 43, 43), "gray17" },
+ { TQRGB( 46, 46, 46), "gray18" },
+ { TQRGB( 48, 48, 48), "gray19" },
+ { TQRGB( 5, 5, 5), "gray2" },
+ { TQRGB( 51, 51, 51), "gray20" },
+ { TQRGB( 54, 54, 54), "gray21" },
+ { TQRGB( 56, 56, 56), "gray22" },
+ { TQRGB( 59, 59, 59), "gray23" },
+ { TQRGB( 61, 61, 61), "gray24" },
+ { TQRGB( 64, 64, 64), "gray25" },
+ { TQRGB( 66, 66, 66), "gray26" },
+ { TQRGB( 69, 69, 69), "gray27" },
+ { TQRGB( 71, 71, 71), "gray28" },
+ { TQRGB( 74, 74, 74), "gray29" },
+ { TQRGB( 8, 8, 8), "gray3" },
+ { TQRGB( 77, 77, 77), "gray30" },
+ { TQRGB( 79, 79, 79), "gray31" },
+ { TQRGB( 82, 82, 82), "gray32" },
+ { TQRGB( 84, 84, 84), "gray33" },
+ { TQRGB( 87, 87, 87), "gray34" },
+ { TQRGB( 89, 89, 89), "gray35" },
+ { TQRGB( 92, 92, 92), "gray36" },
+ { TQRGB( 94, 94, 94), "gray37" },
+ { TQRGB( 97, 97, 97), "gray38" },
+ { TQRGB( 99, 99, 99), "gray39" },
+ { TQRGB( 10, 10, 10), "gray4" },
+ { TQRGB(102,102,102), "gray40" },
+ { TQRGB(105,105,105), "gray41" },
+ { TQRGB(107,107,107), "gray42" },
+ { TQRGB(110,110,110), "gray43" },
+ { TQRGB(112,112,112), "gray44" },
+ { TQRGB(115,115,115), "gray45" },
+ { TQRGB(117,117,117), "gray46" },
+ { TQRGB(120,120,120), "gray47" },
+ { TQRGB(122,122,122), "gray48" },
+ { TQRGB(125,125,125), "gray49" },
+ { TQRGB( 13, 13, 13), "gray5" },
+ { TQRGB(127,127,127), "gray50" },
+ { TQRGB(130,130,130), "gray51" },
+ { TQRGB(133,133,133), "gray52" },
+ { TQRGB(135,135,135), "gray53" },
+ { TQRGB(138,138,138), "gray54" },
+ { TQRGB(140,140,140), "gray55" },
+ { TQRGB(143,143,143), "gray56" },
+ { TQRGB(145,145,145), "gray57" },
+ { TQRGB(148,148,148), "gray58" },
+ { TQRGB(150,150,150), "gray59" },
+ { TQRGB( 15, 15, 15), "gray6" },
+ { TQRGB(153,153,153), "gray60" },
+ { TQRGB(156,156,156), "gray61" },
+ { TQRGB(158,158,158), "gray62" },
+ { TQRGB(161,161,161), "gray63" },
+ { TQRGB(163,163,163), "gray64" },
+ { TQRGB(166,166,166), "gray65" },
+ { TQRGB(168,168,168), "gray66" },
+ { TQRGB(171,171,171), "gray67" },
+ { TQRGB(173,173,173), "gray68" },
+ { TQRGB(176,176,176), "gray69" },
+ { TQRGB( 18, 18, 18), "gray7" },
+ { TQRGB(179,179,179), "gray70" },
+ { TQRGB(181,181,181), "gray71" },
+ { TQRGB(184,184,184), "gray72" },
+ { TQRGB(186,186,186), "gray73" },
+ { TQRGB(189,189,189), "gray74" },
+ { TQRGB(191,191,191), "gray75" },
+ { TQRGB(194,194,194), "gray76" },
+ { TQRGB(196,196,196), "gray77" },
+ { TQRGB(199,199,199), "gray78" },
+ { TQRGB(201,201,201), "gray79" },
+ { TQRGB( 20, 20, 20), "gray8" },
+ { TQRGB(204,204,204), "gray80" },
+ { TQRGB(207,207,207), "gray81" },
+ { TQRGB(209,209,209), "gray82" },
+ { TQRGB(212,212,212), "gray83" },
+ { TQRGB(214,214,214), "gray84" },
+ { TQRGB(217,217,217), "gray85" },
+ { TQRGB(219,219,219), "gray86" },
+ { TQRGB(222,222,222), "gray87" },
+ { TQRGB(224,224,224), "gray88" },
+ { TQRGB(227,227,227), "gray89" },
+ { TQRGB( 23, 23, 23), "gray9" },
+ { TQRGB(229,229,229), "gray90" },
+ { TQRGB(232,232,232), "gray91" },
+ { TQRGB(235,235,235), "gray92" },
+ { TQRGB(237,237,237), "gray93" },
+ { TQRGB(240,240,240), "gray94" },
+ { TQRGB(242,242,242), "gray95" },
+ { TQRGB(245,245,245), "gray96" },
+ { TQRGB(247,247,247), "gray97" },
+ { TQRGB(250,250,250), "gray98" },
+ { TQRGB(252,252,252), "gray99" },
+ { TQRGB( 0,255, 0), "green" },
+ { TQRGB( 0,255, 0), "green1" },
+ { TQRGB( 0,238, 0), "green2" },
+ { TQRGB( 0,205, 0), "green3" },
+ { TQRGB( 0,139, 0), "green4" },
+ { TQRGB(173,255, 47), "greenyellow" },
+ { TQRGB(190,190,190), "grey" },
+ { TQRGB( 0, 0, 0), "grey0" },
+ { TQRGB( 3, 3, 3), "grey1" },
+ { TQRGB( 26, 26, 26), "grey10" },
+ { TQRGB(255,255,255), "grey100" },
+ { TQRGB( 28, 28, 28), "grey11" },
+ { TQRGB( 31, 31, 31), "grey12" },
+ { TQRGB( 33, 33, 33), "grey13" },
+ { TQRGB( 36, 36, 36), "grey14" },
+ { TQRGB( 38, 38, 38), "grey15" },
+ { TQRGB( 41, 41, 41), "grey16" },
+ { TQRGB( 43, 43, 43), "grey17" },
+ { TQRGB( 46, 46, 46), "grey18" },
+ { TQRGB( 48, 48, 48), "grey19" },
+ { TQRGB( 5, 5, 5), "grey2" },
+ { TQRGB( 51, 51, 51), "grey20" },
+ { TQRGB( 54, 54, 54), "grey21" },
+ { TQRGB( 56, 56, 56), "grey22" },
+ { TQRGB( 59, 59, 59), "grey23" },
+ { TQRGB( 61, 61, 61), "grey24" },
+ { TQRGB( 64, 64, 64), "grey25" },
+ { TQRGB( 66, 66, 66), "grey26" },
+ { TQRGB( 69, 69, 69), "grey27" },
+ { TQRGB( 71, 71, 71), "grey28" },
+ { TQRGB( 74, 74, 74), "grey29" },
+ { TQRGB( 8, 8, 8), "grey3" },
+ { TQRGB( 77, 77, 77), "grey30" },
+ { TQRGB( 79, 79, 79), "grey31" },
+ { TQRGB( 82, 82, 82), "grey32" },
+ { TQRGB( 84, 84, 84), "grey33" },
+ { TQRGB( 87, 87, 87), "grey34" },
+ { TQRGB( 89, 89, 89), "grey35" },
+ { TQRGB( 92, 92, 92), "grey36" },
+ { TQRGB( 94, 94, 94), "grey37" },
+ { TQRGB( 97, 97, 97), "grey38" },
+ { TQRGB( 99, 99, 99), "grey39" },
+ { TQRGB( 10, 10, 10), "grey4" },
+ { TQRGB(102,102,102), "grey40" },
+ { TQRGB(105,105,105), "grey41" },
+ { TQRGB(107,107,107), "grey42" },
+ { TQRGB(110,110,110), "grey43" },
+ { TQRGB(112,112,112), "grey44" },
+ { TQRGB(115,115,115), "grey45" },
+ { TQRGB(117,117,117), "grey46" },
+ { TQRGB(120,120,120), "grey47" },
+ { TQRGB(122,122,122), "grey48" },
+ { TQRGB(125,125,125), "grey49" },
+ { TQRGB( 13, 13, 13), "grey5" },
+ { TQRGB(127,127,127), "grey50" },
+ { TQRGB(130,130,130), "grey51" },
+ { TQRGB(133,133,133), "grey52" },
+ { TQRGB(135,135,135), "grey53" },
+ { TQRGB(138,138,138), "grey54" },
+ { TQRGB(140,140,140), "grey55" },
+ { TQRGB(143,143,143), "grey56" },
+ { TQRGB(145,145,145), "grey57" },
+ { TQRGB(148,148,148), "grey58" },
+ { TQRGB(150,150,150), "grey59" },
+ { TQRGB( 15, 15, 15), "grey6" },
+ { TQRGB(153,153,153), "grey60" },
+ { TQRGB(156,156,156), "grey61" },
+ { TQRGB(158,158,158), "grey62" },
+ { TQRGB(161,161,161), "grey63" },
+ { TQRGB(163,163,163), "grey64" },
+ { TQRGB(166,166,166), "grey65" },
+ { TQRGB(168,168,168), "grey66" },
+ { TQRGB(171,171,171), "grey67" },
+ { TQRGB(173,173,173), "grey68" },
+ { TQRGB(176,176,176), "grey69" },
+ { TQRGB( 18, 18, 18), "grey7" },
+ { TQRGB(179,179,179), "grey70" },
+ { TQRGB(181,181,181), "grey71" },
+ { TQRGB(184,184,184), "grey72" },
+ { TQRGB(186,186,186), "grey73" },
+ { TQRGB(189,189,189), "grey74" },
+ { TQRGB(191,191,191), "grey75" },
+ { TQRGB(194,194,194), "grey76" },
+ { TQRGB(196,196,196), "grey77" },
+ { TQRGB(199,199,199), "grey78" },
+ { TQRGB(201,201,201), "grey79" },
+ { TQRGB( 20, 20, 20), "grey8" },
+ { TQRGB(204,204,204), "grey80" },
+ { TQRGB(207,207,207), "grey81" },
+ { TQRGB(209,209,209), "grey82" },
+ { TQRGB(212,212,212), "grey83" },
+ { TQRGB(214,214,214), "grey84" },
+ { TQRGB(217,217,217), "grey85" },
+ { TQRGB(219,219,219), "grey86" },
+ { TQRGB(222,222,222), "grey87" },
+ { TQRGB(224,224,224), "grey88" },
+ { TQRGB(227,227,227), "grey89" },
+ { TQRGB( 23, 23, 23), "grey9" },
+ { TQRGB(229,229,229), "grey90" },
+ { TQRGB(232,232,232), "grey91" },
+ { TQRGB(235,235,235), "grey92" },
+ { TQRGB(237,237,237), "grey93" },
+ { TQRGB(240,240,240), "grey94" },
+ { TQRGB(242,242,242), "grey95" },
+ { TQRGB(245,245,245), "grey96" },
+ { TQRGB(247,247,247), "grey97" },
+ { TQRGB(250,250,250), "grey98" },
+ { TQRGB(252,252,252), "grey99" },
+ { TQRGB(240,255,240), "honeydew" },
+ { TQRGB(240,255,240), "honeydew1" },
+ { TQRGB(224,238,224), "honeydew2" },
+ { TQRGB(193,205,193), "honeydew3" },
+ { TQRGB(131,139,131), "honeydew4" },
+ { TQRGB(255,105,180), "hotpink" },
+ { TQRGB(255,110,180), "hotpink1" },
+ { TQRGB(238,106,167), "hotpink2" },
+ { TQRGB(205, 96,144), "hotpink3" },
+ { TQRGB(139, 58, 98), "hotpink4" },
+ { TQRGB(205, 92, 92), "indianred" },
+ { TQRGB(255,106,106), "indianred1" },
+ { TQRGB(238, 99, 99), "indianred2" },
+ { TQRGB(205, 85, 85), "indianred3" },
+ { TQRGB(139, 58, 58), "indianred4" },
+ { TQRGB(255,255,240), "ivory" },
+ { TQRGB(255,255,240), "ivory1" },
+ { TQRGB(238,238,224), "ivory2" },
+ { TQRGB(205,205,193), "ivory3" },
+ { TQRGB(139,139,131), "ivory4" },
+ { TQRGB(240,230,140), "khaki" },
+ { TQRGB(255,246,143), "khaki1" },
+ { TQRGB(238,230,133), "khaki2" },
+ { TQRGB(205,198,115), "khaki3" },
+ { TQRGB(139,134, 78), "khaki4" },
+ { TQRGB(230,230,250), "lavender" },
+ { TQRGB(255,240,245), "lavenderblush" },
+ { TQRGB(255,240,245), "lavenderblush1" },
+ { TQRGB(238,224,229), "lavenderblush2" },
+ { TQRGB(205,193,197), "lavenderblush3" },
+ { TQRGB(139,131,134), "lavenderblush4" },
+ { TQRGB(124,252, 0), "lawngreen" },
+ { TQRGB(255,250,205), "lemonchiffon" },
+ { TQRGB(255,250,205), "lemonchiffon1" },
+ { TQRGB(238,233,191), "lemonchiffon2" },
+ { TQRGB(205,201,165), "lemonchiffon3" },
+ { TQRGB(139,137,112), "lemonchiffon4" },
+ { TQRGB(173,216,230), "lightblue" },
+ { TQRGB(191,239,255), "lightblue1" },
+ { TQRGB(178,223,238), "lightblue2" },
+ { TQRGB(154,192,205), "lightblue3" },
+ { TQRGB(104,131,139), "lightblue4" },
+ { TQRGB(240,128,128), "lightcoral" },
+ { TQRGB(224,255,255), "lightcyan" },
+ { TQRGB(224,255,255), "lightcyan1" },
+ { TQRGB(209,238,238), "lightcyan2" },
+ { TQRGB(180,205,205), "lightcyan3" },
+ { TQRGB(122,139,139), "lightcyan4" },
+ { TQRGB(238,221,130), "lightgoldenrod" },
+ { TQRGB(255,236,139), "lightgoldenrod1" },
+ { TQRGB(238,220,130), "lightgoldenrod2" },
+ { TQRGB(205,190,112), "lightgoldenrod3" },
+ { TQRGB(139,129, 76), "lightgoldenrod4" },
+ { TQRGB(250,250,210), "lightgoldenrodyellow" },
+ { TQRGB(211,211,211), "lightgray" },
+ { TQRGB(144,238,144), "lightgreen" },
+ { TQRGB(211,211,211), "lightgrey" },
+ { TQRGB(255,182,193), "lightpink" },
+ { TQRGB(255,174,185), "lightpink1" },
+ { TQRGB(238,162,173), "lightpink2" },
+ { TQRGB(205,140,149), "lightpink3" },
+ { TQRGB(139, 95,101), "lightpink4" },
+ { TQRGB(255,160,122), "lightsalmon" },
+ { TQRGB(255,160,122), "lightsalmon1" },
+ { TQRGB(238,149,114), "lightsalmon2" },
+ { TQRGB(205,129, 98), "lightsalmon3" },
+ { TQRGB(139, 87, 66), "lightsalmon4" },
+ { TQRGB( 32,178,170), "lightseagreen" },
+ { TQRGB(135,206,250), "lightskyblue" },
+ { TQRGB(176,226,255), "lightskyblue1" },
+ { TQRGB(164,211,238), "lightskyblue2" },
+ { TQRGB(141,182,205), "lightskyblue3" },
+ { TQRGB( 96,123,139), "lightskyblue4" },
+ { TQRGB(132,112,255), "lightslateblue" },
+ { TQRGB(119,136,153), "lightslategray" },
+ { TQRGB(119,136,153), "lightslategrey" },
+ { TQRGB(176,196,222), "lightsteelblue" },
+ { TQRGB(202,225,255), "lightsteelblue1" },
+ { TQRGB(188,210,238), "lightsteelblue2" },
+ { TQRGB(162,181,205), "lightsteelblue3" },
+ { TQRGB(110,123,139), "lightsteelblue4" },
+ { TQRGB(255,255,224), "lightyellow" },
+ { TQRGB(255,255,224), "lightyellow1" },
+ { TQRGB(238,238,209), "lightyellow2" },
+ { TQRGB(205,205,180), "lightyellow3" },
+ { TQRGB(139,139,122), "lightyellow4" },
+ { TQRGB( 50,205, 50), "limegreen" },
+ { TQRGB(250,240,230), "linen" },
+ { TQRGB(255, 0,255), "magenta" },
+ { TQRGB(255, 0,255), "magenta1" },
+ { TQRGB(238, 0,238), "magenta2" },
+ { TQRGB(205, 0,205), "magenta3" },
+ { TQRGB(139, 0,139), "magenta4" },
+ { TQRGB(176, 48, 96), "maroon" },
+ { TQRGB(255, 52,179), "maroon1" },
+ { TQRGB(238, 48,167), "maroon2" },
+ { TQRGB(205, 41,144), "maroon3" },
+ { TQRGB(139, 28, 98), "maroon4" },
+ { TQRGB(102,205,170), "mediumaquamarine" },
+ { TQRGB( 0, 0,205), "mediumblue" },
+ { TQRGB(186, 85,211), "mediumorchid" },
+ { TQRGB(224,102,255), "mediumorchid1" },
+ { TQRGB(209, 95,238), "mediumorchid2" },
+ { TQRGB(180, 82,205), "mediumorchid3" },
+ { TQRGB(122, 55,139), "mediumorchid4" },
+ { TQRGB(147,112,219), "mediumpurple" },
+ { TQRGB(171,130,255), "mediumpurple1" },
+ { TQRGB(159,121,238), "mediumpurple2" },
+ { TQRGB(137,104,205), "mediumpurple3" },
+ { TQRGB( 93, 71,139), "mediumpurple4" },
+ { TQRGB( 60,179,113), "mediumseagreen" },
+ { TQRGB(123,104,238), "mediumslateblue" },
+ { TQRGB( 0,250,154), "mediumspringgreen" },
+ { TQRGB( 72,209,204), "mediumturquoise" },
+ { TQRGB(199, 21,133), "mediumvioletred" },
+ { TQRGB( 25, 25,112), "midnightblue" },
+ { TQRGB(245,255,250), "mintcream" },
+ { TQRGB(255,228,225), "mistyrose" },
+ { TQRGB(255,228,225), "mistyrose1" },
+ { TQRGB(238,213,210), "mistyrose2" },
+ { TQRGB(205,183,181), "mistyrose3" },
+ { TQRGB(139,125,123), "mistyrose4" },
+ { TQRGB(255,228,181), "tqmoccasin" },
+ { TQRGB(255,222,173), "navajowhite" },
+ { TQRGB(255,222,173), "navajowhite1" },
+ { TQRGB(238,207,161), "navajowhite2" },
+ { TQRGB(205,179,139), "navajowhite3" },
+ { TQRGB(139,121, 94), "navajowhite4" },
+ { TQRGB( 0, 0,128), "navy" },
+ { TQRGB( 0, 0,128), "navyblue" },
+ { TQRGB(253,245,230), "oldlace" },
+ { TQRGB(107,142, 35), "olivedrab" },
+ { TQRGB(192,255, 62), "olivedrab1" },
+ { TQRGB(179,238, 58), "olivedrab2" },
+ { TQRGB(154,205, 50), "olivedrab3" },
+ { TQRGB(105,139, 34), "olivedrab4" },
+ { TQRGB(255,165, 0), "orange" },
+ { TQRGB(255,165, 0), "orange1" },
+ { TQRGB(238,154, 0), "orange2" },
+ { TQRGB(205,133, 0), "orange3" },
+ { TQRGB(139, 90, 0), "orange4" },
+ { TQRGB(255, 69, 0), "orangered" },
+ { TQRGB(255, 69, 0), "orangered1" },
+ { TQRGB(238, 64, 0), "orangered2" },
+ { TQRGB(205, 55, 0), "orangered3" },
+ { TQRGB(139, 37, 0), "orangered4" },
+ { TQRGB(218,112,214), "orchid" },
+ { TQRGB(255,131,250), "orchid1" },
+ { TQRGB(238,122,233), "orchid2" },
+ { TQRGB(205,105,201), "orchid3" },
+ { TQRGB(139, 71,137), "orchid4" },
+ { TQRGB(238,232,170), "palegoldenrod" },
+ { TQRGB(152,251,152), "palegreen" },
+ { TQRGB(154,255,154), "palegreen1" },
+ { TQRGB(144,238,144), "palegreen2" },
+ { TQRGB(124,205,124), "palegreen3" },
+ { TQRGB( 84,139, 84), "palegreen4" },
+ { TQRGB(175,238,238), "paleturquoise" },
+ { TQRGB(187,255,255), "paleturquoise1" },
+ { TQRGB(174,238,238), "paleturquoise2" },
+ { TQRGB(150,205,205), "paleturquoise3" },
+ { TQRGB(102,139,139), "paleturquoise4" },
+ { TQRGB(219,112,147), "palevioletred" },
+ { TQRGB(255,130,171), "palevioletred1" },
+ { TQRGB(238,121,159), "palevioletred2" },
+ { TQRGB(205,104,137), "palevioletred3" },
+ { TQRGB(139, 71, 93), "palevioletred4" },
+ { TQRGB(255,239,213), "papayawhip" },
+ { TQRGB(255,218,185), "peachpuff" },
+ { TQRGB(255,218,185), "peachpuff1" },
+ { TQRGB(238,203,173), "peachpuff2" },
+ { TQRGB(205,175,149), "peachpuff3" },
+ { TQRGB(139,119,101), "peachpuff4" },
+ { TQRGB(205,133, 63), "peru" },
+ { TQRGB(255,192,203), "pink" },
+ { TQRGB(255,181,197), "pink1" },
+ { TQRGB(238,169,184), "pink2" },
+ { TQRGB(205,145,158), "pink3" },
+ { TQRGB(139, 99,108), "pink4" },
+ { TQRGB(221,160,221), "plum" },
+ { TQRGB(255,187,255), "plum1" },
+ { TQRGB(238,174,238), "plum2" },
+ { TQRGB(205,150,205), "plum3" },
+ { TQRGB(139,102,139), "plum4" },
+ { TQRGB(176,224,230), "powderblue" },
+ { TQRGB(160, 32,240), "purple" },
+ { TQRGB(155, 48,255), "purple1" },
+ { TQRGB(145, 44,238), "purple2" },
+ { TQRGB(125, 38,205), "purple3" },
+ { TQRGB( 85, 26,139), "purple4" },
+ { TQRGB(255, 0, 0), "red" },
+ { TQRGB(255, 0, 0), "red1" },
+ { TQRGB(238, 0, 0), "red2" },
+ { TQRGB(205, 0, 0), "red3" },
+ { TQRGB(139, 0, 0), "red4" },
+ { TQRGB(188,143,143), "rosybrown" },
+ { TQRGB(255,193,193), "rosybrown1" },
+ { TQRGB(238,180,180), "rosybrown2" },
+ { TQRGB(205,155,155), "rosybrown3" },
+ { TQRGB(139,105,105), "rosybrown4" },
+ { TQRGB( 65,105,225), "royalblue" },
+ { TQRGB( 72,118,255), "royalblue1" },
+ { TQRGB( 67,110,238), "royalblue2" },
+ { TQRGB( 58, 95,205), "royalblue3" },
+ { TQRGB( 39, 64,139), "royalblue4" },
+ { TQRGB(139, 69, 19), "saddlebrown" },
+ { TQRGB(250,128,114), "salmon" },
+ { TQRGB(255,140,105), "salmon1" },
+ { TQRGB(238,130, 98), "salmon2" },
+ { TQRGB(205,112, 84), "salmon3" },
+ { TQRGB(139, 76, 57), "salmon4" },
+ { TQRGB(244,164, 96), "sandybrown" },
+ { TQRGB( 46,139, 87), "seagreen" },
+ { TQRGB( 84,255,159), "seagreen1" },
+ { TQRGB( 78,238,148), "seagreen2" },
+ { TQRGB( 67,205,128), "seagreen3" },
+ { TQRGB( 46,139, 87), "seagreen4" },
+ { TQRGB(255,245,238), "seashell" },
+ { TQRGB(255,245,238), "seashell1" },
+ { TQRGB(238,229,222), "seashell2" },
+ { TQRGB(205,197,191), "seashell3" },
+ { TQRGB(139,134,130), "seashell4" },
+ { TQRGB(160, 82, 45), "sienna" },
+ { TQRGB(255,130, 71), "sienna1" },
+ { TQRGB(238,121, 66), "sienna2" },
+ { TQRGB(205,104, 57), "sienna3" },
+ { TQRGB(139, 71, 38), "sienna4" },
+ { TQRGB(135,206,235), "skyblue" },
+ { TQRGB(135,206,255), "skyblue1" },
+ { TQRGB(126,192,238), "skyblue2" },
+ { TQRGB(108,166,205), "skyblue3" },
+ { TQRGB( 74,112,139), "skyblue4" },
+ { TQRGB(106, 90,205), "slateblue" },
+ { TQRGB(131,111,255), "slateblue1" },
+ { TQRGB(122,103,238), "slateblue2" },
+ { TQRGB(105, 89,205), "slateblue3" },
+ { TQRGB( 71, 60,139), "slateblue4" },
+ { TQRGB(112,128,144), "slategray" },
+ { TQRGB(198,226,255), "slategray1" },
+ { TQRGB(185,211,238), "slategray2" },
+ { TQRGB(159,182,205), "slategray3" },
+ { TQRGB(108,123,139), "slategray4" },
+ { TQRGB(112,128,144), "slategrey" },
+ { TQRGB(255,250,250), "snow" },
+ { TQRGB(255,250,250), "snow1" },
+ { TQRGB(238,233,233), "snow2" },
+ { TQRGB(205,201,201), "snow3" },
+ { TQRGB(139,137,137), "snow4" },
+ { TQRGB( 0,255,127), "springgreen" },
+ { TQRGB( 0,255,127), "springgreen1" },
+ { TQRGB( 0,238,118), "springgreen2" },
+ { TQRGB( 0,205,102), "springgreen3" },
+ { TQRGB( 0,139, 69), "springgreen4" },
+ { TQRGB( 70,130,180), "steelblue" },
+ { TQRGB( 99,184,255), "steelblue1" },
+ { TQRGB( 92,172,238), "steelblue2" },
+ { TQRGB( 79,148,205), "steelblue3" },
+ { TQRGB( 54,100,139), "steelblue4" },
+ { TQRGB(210,180,140), "tan" },
+ { TQRGB(255,165, 79), "tan1" },
+ { TQRGB(238,154, 73), "tan2" },
+ { TQRGB(205,133, 63), "tan3" },
+ { TQRGB(139, 90, 43), "tan4" },
+ { TQRGB(216,191,216), "thistle" },
+ { TQRGB(255,225,255), "thistle1" },
+ { TQRGB(238,210,238), "thistle2" },
+ { TQRGB(205,181,205), "thistle3" },
+ { TQRGB(139,123,139), "thistle4" },
+ { TQRGB(255, 99, 71), "tomato" },
+ { TQRGB(255, 99, 71), "tomato1" },
+ { TQRGB(238, 92, 66), "tomato2" },
+ { TQRGB(205, 79, 57), "tomato3" },
+ { TQRGB(139, 54, 38), "tomato4" },
+ { TQRGB( 64,224,208), "turquoise" },
+ { TQRGB( 0,245,255), "turquoise1" },
+ { TQRGB( 0,229,238), "turquoise2" },
+ { TQRGB( 0,197,205), "turquoise3" },
+ { TQRGB( 0,134,139), "turquoise4" },
+ { TQRGB(238,130,238), "violet" },
+ { TQRGB(208, 32,144), "violetred" },
+ { TQRGB(255, 62,150), "violetred1" },
+ { TQRGB(238, 58,140), "violetred2" },
+ { TQRGB(205, 50,120), "violetred3" },
+ { TQRGB(139, 34, 82), "violetred4" },
+ { TQRGB(245,222,179), "wheat" },
+ { TQRGB(255,231,186), "wheat1" },
+ { TQRGB(238,216,174), "wheat2" },
+ { TQRGB(205,186,150), "wheat3" },
+ { TQRGB(139,126,102), "wheat4" },
+ { TQRGB(255,255,255), "white" },
+ { TQRGB(245,245,245), "whitesmoke" },
+ { TQRGB(255,255, 0), "yellow" },
+ { TQRGB(255,255, 0), "yellow1" },
+ { TQRGB(238,238, 0), "yellow2" },
+ { TQRGB(205,205, 0), "yellow3" },
+ { TQRGB(139,139, 0), "yellow4" },
+ { TQRGB(154,205, 50), "yellowgreen" } };
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+#ifdef TQ_OS_TEMP
+static int __cdecl rgb_cmp( const void *d1, const void *d2 )
+#else
+static int rgb_cmp( const void *d1, const void *d2 )
+#endif
+{
+ return qstricmp( ((RGBData *)d1)->name, ((RGBData *)d2)->name );
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+bool qt_get_named_rgb( const char *name, TQRgb* rgb )
+{
+ TQ_LONG len = strlen(name)+1;
+ char *name_no_space = (char *)malloc(len);
+ for(TQ_LONG o=0,i=0; i < len; i++) {
+ if(name[i] != '\t' && name[i] != ' ')
+ name_no_space[o++] = name[i];
+ }
+
+ RGBData x;
+ x.name = name_no_space;
+ // Funtion bsearch() is supposed to be
+ // void *bsearch(const void *key, const void *base, ...
+ // So why (char*)? Are there broken bsearch() declarations out there?
+ RGBData *r = (RGBData*)bsearch((char*)&x, (char*)rgbTbl, rgbTblSize,
+ sizeof(RGBData), rgb_cmp);
+ free(name_no_space);
+ if ( r ) {
+ *rgb = r->value;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+uint qt_get_rgb_val( const char *name )
+{
+ TQRgb r = 0;
+ qt_get_named_rgb(name,&r);
+ return r;
+}
+#ifndef TQT_NO_STRINGLIST
+TQStringList TQColor::colorNames()
+{
+ int i = 0;
+ TQStringList lst;
+ for ( i = 0; i < rgbTblSize; i++ )
+ lst << rgbTbl[i].name;
+
+ return lst;
+}
+#endif
+#else
+
+bool qt_get_named_rgb( const char *, TQRgb* )
+{
+ return FALSE;
+}
+
+uint qt_get_rgb_val( const char * )
+{
+ return 0;
+}
+#ifndef TQT_NO_STRINGLIST
+TQStringList TQColor::colorNames()
+{
+ return TQStringList();
+}
+#endif
+#endif // TQT_NO_COLORNAMES
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqcolor_p.h b/tqtinterface/qt4/src/kernel/tqcolor_p.h
new file mode 100644
index 0000000..be9df40
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqcolor_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Named color support for non-X platforms.
+** The color names have been borrowed from X.
+**
+** Created : 000228
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCOLOR_P_H
+#define TQCOLOR_P_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qmenudata.cpp, qmenubar.cpp, qmenubar.cpp, qpopupmenu.cpp,
+// qmotifstyle.cpp and qwindowssstyle.cpp. This header file may change
+// from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#endif // TQT_H
+
+extern uint qt_get_rgb_val( const char *name );
+extern bool qt_get_named_rgb( const char *, TQRgb* );
+extern void qt_reset_color_avail();
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqcolor_x11.cpp b/tqtinterface/qt4/src/kernel/tqcolor_x11.cpp
new file mode 100644
index 0000000..909ecbb
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqcolor_x11.cpp
@@ -0,0 +1,1336 @@
+/****************************************************************************
+**
+** Implementation of TQColor class for X11
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcolor.h"
+#include "tqcolor_p.h"
+#include "string.h"
+#include "tqpaintdevice.h"
+#include "tqapplication.h"
+#include "tqapplication_p.h"
+#include "tqt_x11_p.h"
+
+#ifdef USE_QT4
+
+#include "tqintdict.h"
+
+static const uint col_std_dict = 419;
+static const uint col_large_dict = 18397;
+
+struct TQColorData {
+ uint pix; // allocated pixel value
+ int context; // allocation context
+};
+
+typedef TQIntDict<TQColorData> TQColorDict;
+typedef TQIntDictIterator<TQColorData> TQColorDictIt;
+
+static int current_alloc_context = 0; // current color alloc context
+
+class TQColorScreenData {
+public:
+ TQColorScreenData()
+ {
+ colorDict = 0;
+ colors_avail = TRUE;
+ g_vis = 0;
+ g_carr = 0;
+ g_carr_fetch = TRUE;
+ g_cells = 0;
+ g_our_alloc = 0;
+ color_reduce = FALSE;
+ }
+
+ TQColorDict *colorDict; // dict of allocated colors
+ bool colors_avail; // X colors available
+ bool g_truecolor; // truecolor visual
+ Visual *g_vis; // visual
+ XColor *g_carr; // color array
+ bool g_carr_fetch; // perform XQueryColors?
+ int g_cells; // number of entries in g_carr
+ bool *g_our_alloc; // our allocated colors
+ uint red_mask , green_mask , blue_mask;
+ int red_shift, green_shift, blue_shift;
+ bool color_reduce;
+ int col_div_r;
+ int col_div_g;
+ int col_div_b;
+};
+
+static int screencount = 0;
+static TQColorScreenData **screendata = 0; // array of screendata pointers
+
+#define MAX_CONTEXTS 16
+static int context_stack[MAX_CONTEXTS];
+static int context_ptr = 0;
+
+static void init_context_stack()
+{
+ static bool did_init = FALSE;
+ if ( !did_init ) {
+ did_init = TRUE;
+ context_stack[0] = current_alloc_context = 0;
+ }
+}
+
+/*
+ This function is called from the event loop. It resets the colors_avail
+ flag so that the application can retry to allocate read-only colors
+ that other applications may have deallocated lately.
+
+ The g_our_alloc and g_carr are global arrays that optimize color
+ approximation when there are no more colors left to allocate.
+*/
+
+void qt_reset_color_avail()
+{
+ int i;
+ for ( i = 0; i < screencount; i++ ) {
+ screendata[i]->colors_avail = TRUE;
+ screendata[i]->g_carr_fetch = TRUE; // do XQueryColors if !colors_avail
+ }
+}
+
+/*!
+ Enters a color allocation context and returns a non-zero unique
+ identifier.
+
+ Color allocation contexts are useful for programs that need to
+ allocate many colors and throw them away later, like image
+ viewers. The allocation context functions work for true color
+ displays as well as for colormap displays, except that
+ TQColor::destroyAllocContext() does nothing for true color.
+
+ Example:
+ \code
+ TQPixmap loadPixmap( TQString fileName )
+ {
+ static int alloc_context = 0;
+ if ( alloc_context )
+ TQColor::destroyAllocContext( alloc_context );
+ alloc_context = TQColor::enterAllocContext();
+ TQPixmap pm( fileName );
+ TQColor::leaveAllocContext();
+ return pm;
+ }
+ \endcode
+
+ The example code loads a pixmap from file. It frees up all colors
+ that were allocated the last time loadPixmap() was called.
+
+ The initial/default context is 0. TQt keeps a list of colors
+ associated with their allocation contexts. You can call
+ destroyAllocContext() to get rid of all colors that were allocated
+ in a specific context.
+
+ Calling enterAllocContext() enters an allocation context. The
+ allocation context lasts until you call leaveAllocContext().
+ TQColor has an internal stack of allocation contexts. Each call to
+ enterAllocContex() must have a corresponding leaveAllocContext().
+
+ \code
+ // context 0 active
+ int c1 = TQColor::enterAllocContext(); // enter context c1
+ // context c1 active
+ int c2 = TQColor::enterAllocContext(); // enter context c2
+ // context c2 active
+ TQColor::leaveAllocContext(); // leave context c2
+ // context c1 active
+ TQColor::leaveAllocContext(); // leave context c1
+ // context 0 active
+ // Now, free all colors that were allocated in context c2
+ TQColor::destroyAllocContext( c2 );
+ \endcode
+
+ You may also want to set the application's color specification.
+ See TQApplication::setColorSpec() for more information.
+
+ \sa leaveAllocContext(), currentAllocContext(), destroyAllocContext(),
+ TQApplication::setColorSpec()
+*/
+
+int TQColor::enterAllocContext()
+{
+ static int context_seq_no = 0;
+ init_context_stack();
+ if ( context_ptr+1 == MAX_CONTEXTS ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQColor::enterAllocContext: Context stack overflow" );
+#endif
+ return 0;
+ }
+ current_alloc_context = context_stack[++context_ptr] = ++context_seq_no;
+ return current_alloc_context;
+}
+
+
+/*!
+ Leaves a color allocation context.
+
+ See enterAllocContext() for a detailed explanation.
+
+ \sa enterAllocContext(), currentAllocContext()
+*/
+
+void TQColor::leaveAllocContext()
+{
+ init_context_stack();
+ if ( context_ptr == 0 ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQColor::leaveAllocContext: Context stack underflow" );
+#endif
+ return;
+ }
+ current_alloc_context = context_stack[--context_ptr];
+}
+
+
+/*!
+ Returns the current color allocation context.
+
+ The default context is 0.
+
+ \sa enterAllocContext(), leaveAllocContext()
+*/
+
+int TQColor::currentAllocContext()
+{
+ return current_alloc_context;
+}
+
+
+/*!
+ Destroys a color allocation context, \e context.
+
+ This function deallocates all colors that were allocated in the
+ specified \a context. If \a context == -1, it frees up all colors
+ that the application has allocated. If \a context == -2, it frees
+ up all colors that the application has allocated, except those in
+ the default context.
+
+ The function does nothing for true color displays.
+
+ \sa enterAllocContext(), alloc()
+*/
+
+void TQColor::destroyAllocContext( int context )
+{
+ init_context_stack();
+ if ( !color_init )
+ return;
+
+ int screen;
+ for ( screen = 0; screen < screencount; ++screen ) {
+ if ( screendata[screen]->g_truecolor )
+ continue;
+
+ ulong pixels[256];
+ bool freeing[256];
+ memset( freeing, FALSE, screendata[screen]->g_cells*sizeof(bool) );
+ TQColorData *d;
+ TQColorDictIt it( *screendata[screen]->colorDict );
+ int i = 0;
+ uint rgbv;
+ while ( (d=it.current()) ) {
+ rgbv = (uint)it.currentKey();
+ if ( (d->context || context==-1) &&
+ (d->context == context || context < 0) ) {
+ if ( !screendata[screen]->g_our_alloc[d->pix] && !freeing[d->pix] ) {
+ // will free this color
+ pixels[i++] = d->pix;
+ freeing[d->pix] = TRUE;
+ }
+ // remove from dict
+ screendata[screen]->colorDict->remove( (long)rgbv );
+ }
+ ++it;
+ }
+ if ( i )
+ XFreeColors( TQPaintDevice::x11AppDisplay(),
+ TQPaintDevice::x11AppColormap( screen ),
+ pixels, i, 0 );
+ }
+}
+
+/*!
+ Returns the number of color bit planes for the underlying window
+ system.
+
+ The returned value is equal to the default pixmap depth.
+
+ \sa TQPixmap::defaultDepth()
+*/
+
+int TQColor::numBitPlanes()
+{
+ return TQPaintDevice::x11AppDepth();
+}
+
+/*
+ Finds the nearest color.
+*/
+
+static int tqfind_nearest_color( int r, int g, int b, int* mindist_out,
+ TQColorScreenData *sd )
+{
+ int mincol = -1;
+ int mindist = 200000;
+ int rx, gx, bx, dist;
+ XColor *xc = &sd->g_carr[0];
+ for ( int i=0; i<sd->g_cells; i++ ) {
+ rx = r - (xc->red >> 8);
+ gx = g - (xc->green >> 8);
+ bx = b - (xc->blue>> 8);
+ dist = rx*rx + gx*gx + bx*bx; // calculate distance
+ if ( dist < mindist ) { // minimal?
+ mindist = dist;
+ mincol = i;
+ }
+ xc++;
+ }
+ *mindist_out = mindist;
+ return mincol;
+}
+
+/*!
+ \internal
+ Allocates the color on screen \a screen. Only used in X11.
+
+ \sa alloc(), pixel()
+*/
+uint TQColor::alloc( int screen )
+{
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ if ( screen < 0 )
+ screen = TQPaintDevice::x11AppScreen();
+ if ( !color_init )
+ return dpy ? (uint)BlackPixel(dpy, screen) : 0;
+ int r = tqRed(d.argb);
+ int g = tqGreen(d.argb);
+ int b = tqBlue(d.argb);
+ uint pix = 0;
+ TQColorScreenData *sd = screendata[screen];
+ if ( sd->g_truecolor ) { // truecolor: map to pixel
+ r = sd->red_shift > 0 ? r << sd->red_shift : r >> -sd->red_shift;
+ g = sd->green_shift > 0 ? g << sd->green_shift : g >> -sd->green_shift;
+ b = sd->blue_shift > 0 ? b << sd->blue_shift : b >> -sd->blue_shift;
+ pix = (b & sd->blue_mask) | (g & sd->green_mask) | (r & sd->red_mask)
+ | ~(sd->blue_mask | sd->green_mask | sd->red_mask);
+ if ( screen == TQPaintDevice::x11AppScreen() )
+ d.d32.pix = pix;
+ return pix;
+ }
+ TQColorData *c = sd->colorDict->tqfind( (long)(d.argb) );
+ if ( c ) { // found color in dictionary
+ pix = c->pix;
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE; // color ok
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix; // use same pixel value
+ if ( c->context != current_alloc_context ) {
+ c->context = 0; // convert to default context
+ sd->g_our_alloc[pix] = TRUE; // reuse without XAllocColor
+ }
+ }
+ return pix;
+ }
+
+ XColor col;
+ col.red = r << 8;
+ col.green = g << 8;
+ col.blue = b << 8;
+
+ bool try_again = FALSE;
+ bool try_alloc = !sd->color_reduce;
+ int try_count = 0;
+
+ do {
+ // This loop is run until we manage to either allocate or
+ // tqfind an approximate color, it stops after a few iterations.
+
+ try_again = FALSE;
+
+ if ( try_alloc && sd->colors_avail &&
+ XAllocColor(dpy, TQPaintDevice::x11AppColormap( screen ),&col) ) {
+ // We could allocate the color
+ pix = (uint) col.pixel;
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.pix = pix;
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ sd->g_carr[d.d8.pix] = col; // update color array
+ if ( current_alloc_context == 0 )
+ sd->g_our_alloc[d.d8.pix] = TRUE; // reuse without XAllocColor
+ }
+ } else {
+ // No available colors, or we did not want to allocate one
+ int i;
+ sd->colors_avail = FALSE; // no more available colors
+ if ( sd->g_carr_fetch ) { // refetch color array
+ sd->g_carr_fetch = FALSE;
+ XQueryColors( dpy, TQPaintDevice::x11AppColormap( screen ), sd->g_carr,
+ sd->g_cells );
+ }
+ int mindist;
+ i = tqfind_nearest_color( r, g, b, &mindist, sd );
+
+ if ( mindist != 0 && !try_alloc ) {
+ // Not an exact match with an existing color
+ int rr = ((r+sd->col_div_r/2)/sd->col_div_r)*sd->col_div_r;
+ int rg = ((g+sd->col_div_g/2)/sd->col_div_g)*sd->col_div_g;
+ int rb = ((b+sd->col_div_b/2)/sd->col_div_b)*sd->col_div_b;
+ int rx = rr - r;
+ int gx = rg - g;
+ int bx = rb - b;
+ int dist = rx*rx + gx*gx + bx*bx; // calculate distance
+ if ( dist < mindist ) {
+ // reduced color is closer - try to alloc it
+ r = rr;
+ g = rg;
+ b = rb;
+ col.red = r << 8;
+ col.green = g << 8;
+ col.blue = b << 8;
+ try_alloc = TRUE;
+ try_again = TRUE;
+ sd->colors_avail = TRUE;
+ continue; // Try alloc reduced color
+ }
+ }
+
+ if ( i == -1 ) { // no nearest color?!
+ int unused, value;
+ hsv(&unused, &unused, &value);
+ if (value < 128) { // dark, use black
+ d.argb = tqRgb(0,0,0);
+ pix = (uint)BlackPixel( dpy, screen );
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix;
+ }
+ } else { // light, use white
+ d.argb = tqRgb(0xff,0xff,0xff);
+ pix = (uint)WhitePixel( dpy, screen );
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix;
+ }
+ }
+ return pix;
+ }
+ if ( sd->g_our_alloc[i] ) { // we've already allocated it
+ ; // i == g_carr[i].pixel
+ } else {
+ // Try to allocate existing color
+ col = sd->g_carr[i];
+ if ( XAllocColor(dpy, TQPaintDevice::x11AppColormap( screen ), &col) ) {
+ i = (uint)col.pixel;
+ sd->g_carr[i] = col; // update color array
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ if ( current_alloc_context == 0 )
+ sd->g_our_alloc[i] = TRUE; // only in the default context
+ }
+ } else {
+ // Oops, it's gone again
+ try_count++;
+ try_again = TRUE;
+ sd->colors_avail = TRUE;
+ sd->g_carr_fetch = TRUE;
+ }
+ }
+ if ( !try_again ) { // got it
+ pix = (uint)sd->g_carr[i].pixel;
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix; // allocated X11 color
+ }
+ }
+ }
+
+ } while ( try_again && try_count < 2 );
+
+ if ( try_again ) { // no hope of allocating color
+ int unused, value;
+ hsv(&unused, &unused, &value);
+ if (value < 128) { // dark, use black
+ d.argb = tqRgb(0,0,0);
+ pix = (uint)BlackPixel( dpy, screen );
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix;
+ }
+ } else { // light, use white
+ d.argb = tqRgb(0xff,0xff,0xff);
+ pix = (uint)WhitePixel( dpy, screen );
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix;
+ }
+ }
+ return pix;
+ }
+ // All colors outside context 0 must go into the dictionary
+ bool many = sd->colorDict->count() >= sd->colorDict->size() * 8;
+ if ( many && sd->colorDict->size() == col_std_dict ) {
+ sd->colorDict->resize( col_large_dict );
+ }
+ if ( !many || current_alloc_context != 0 ) {
+ c = new TQColorData; // insert into color dict
+ TQ_CHECK_PTR( c );
+ c->pix = pix;
+ c->context = current_alloc_context;
+ sd->colorDict->insert( (long)d.argb, c ); // store color in dict
+ }
+ return pix;
+}
+
+/*!
+ Allocates the RGB color and returns the pixel value.
+
+ Allocating a color means to obtain a pixel value from the RGB
+ specification. The pixel value is an index into the global color
+ table, but should be considered an arbitrary platform-dependent value.
+
+ The pixel() function calls alloc() if necessary, so in general you
+ don't need to call this function.
+
+ \sa enterAllocContext()
+*/
+// ### 4.0 - remove me?
+uint TQColor::alloc()
+{
+ return alloc( -1 );
+}
+
+#else // USE_QT4
+
+// NOT REVISED
+
+/*****************************************************************************
+ The color dictionary speeds up color allocation significantly for X11.
+ When there are no more colors, TQColor::alloc() will set the colors_avail
+ flag to FALSE and try to tqfind the nearest color.
+ NOTE: From deep within the event loop, the colors_avail flag is reset to
+ TRUE (calls the function qt_reset_color_avail()), because some other
+ application might free its colors, thereby making them available for
+ this TQt application.
+ *****************************************************************************/
+
+#include "tqintdict.h"
+
+struct TQColorData {
+ uint pix; // allocated pixel value
+ int context; // allocation context
+};
+
+typedef TQIntDict<TQColorData> TQColorDict;
+typedef TQIntDictIterator<TQColorData> TQColorDictIt;
+static int current_alloc_context = 0; // current color alloc context
+static const uint col_std_dict = 419;
+static const uint col_large_dict = 18397;
+
+class TQColorScreenData {
+public:
+ TQColorScreenData()
+ {
+ colorDict = 0;
+ colors_avail = TRUE;
+ g_vis = 0;
+ g_carr = 0;
+ g_carr_fetch = TRUE;
+ g_cells = 0;
+ g_our_alloc = 0;
+ color_reduce = FALSE;
+ }
+
+ TQColorDict *colorDict; // dict of allocated colors
+ bool colors_avail; // X colors available
+ bool g_truecolor; // truecolor visual
+ Visual *g_vis; // visual
+ XColor *g_carr; // color array
+ bool g_carr_fetch; // perform XQueryColors?
+ int g_cells; // number of entries in g_carr
+ bool *g_our_alloc; // our allocated colors
+ uint red_mask , green_mask , blue_mask;
+ int red_shift, green_shift, blue_shift;
+ bool color_reduce;
+ int col_div_r;
+ int col_div_g;
+ int col_div_b;
+};
+
+static int screencount = 0;
+static TQColorScreenData **screendata = 0; // array of screendata pointers
+
+
+/*
+ This function is called from the event loop. It resets the colors_avail
+ flag so that the application can retry to allocate read-only colors
+ that other applications may have deallocated lately.
+
+ The g_our_alloc and g_carr are global arrays that optimize color
+ approximation when there are no more colors left to allocate.
+*/
+
+void qt_reset_color_avail()
+{
+ int i;
+ for ( i = 0; i < screencount; i++ ) {
+ screendata[i]->colors_avail = TRUE;
+ screendata[i]->g_carr_fetch = TRUE; // do XQueryColors if !colors_avail
+ }
+}
+
+
+/*
+ Finds the nearest color.
+*/
+
+static int tqfind_nearest_color( int r, int g, int b, int* mindist_out,
+ TQColorScreenData *sd )
+{
+ int mincol = -1;
+ int mindist = 200000;
+ int rx, gx, bx, dist;
+ XColor *xc = &sd->g_carr[0];
+ for ( int i=0; i<sd->g_cells; i++ ) {
+ rx = r - (xc->red >> 8);
+ gx = g - (xc->green >> 8);
+ bx = b - (xc->blue>> 8);
+ dist = rx*rx + gx*gx + bx*bx; // calculate distance
+ if ( dist < mindist ) { // minimal?
+ mindist = dist;
+ mincol = i;
+ }
+ xc++;
+ }
+ *mindist_out = mindist;
+ return mincol;
+}
+
+
+/*****************************************************************************
+ TQColor misc internal functions
+ *****************************************************************************/
+
+static int highest_bit( uint v )
+{
+ int i;
+ uint b = (uint)1 << 31; // get pos of highest bit in v
+ for ( i=31; ((b & v) == 0) && i>=0; i-- )
+ b >>= 1;
+ return i;
+}
+
+
+/*****************************************************************************
+ TQColor static member functions
+ *****************************************************************************/
+
+/*!
+ Returns the maximum number of colors supported by the underlying
+ window system if the window system uses a palette.
+
+ Otherwise returns -1. Use numBitPlanes() to calculate the available
+ colors in that case.
+*/
+
+int TQColor::maxColors()
+{
+ Visual *visual = (Visual *) TQPaintDevice::x11AppVisual();
+ if (visual->c_class & 1)
+ return TQPaintDevice::x11AppCells();
+ return -1;
+}
+
+/*!
+ Returns the number of color bit planes for the underlying window
+ system.
+
+ The returned value is equal to the default pixmap depth.
+
+ \sa TQPixmap::defaultDepth()
+*/
+
+int TQColor::numBitPlanes()
+{
+ return TQPaintDevice::x11AppDepth();
+}
+
+
+/*!
+ Internal initialization required for TQColor.
+ This function is called from the TQApplication constructor.
+
+ \sa cleanup()
+*/
+
+void TQColor::initialize()
+{
+ static const int blackIdx = 2;
+ static const int whiteIdx = 3;
+
+ if ( color_init ) // already initialized
+ return;
+ color_init = TRUE;
+
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ int spec = TQApplication::colorSpec();
+
+ screencount = ScreenCount( dpy );
+ screendata = new TQColorScreenData*[ screencount ];
+
+ int scr;
+ for ( scr = 0; scr < screencount; ++scr ) {
+ screendata[scr] = new TQColorScreenData;
+ screendata[scr]->g_vis = (Visual *) TQPaintDevice::x11AppVisual( scr );
+ screendata[scr]->g_truecolor = screendata[scr]->g_vis->c_class == TrueColor
+ || screendata[scr]->g_vis->c_class == DirectColor;
+
+ int ncols = TQPaintDevice::x11AppCells( scr );
+
+ if ( screendata[scr]->g_truecolor ) {
+ if (scr == DefaultScreen(dpy))
+ colormodel = d32;
+ } else {
+ if (scr == DefaultScreen(dpy))
+ colormodel = d8;
+
+ // Create the g_our_alloc array, which remembers which color pixels
+ // we allocated.
+ screendata[scr]->g_cells = TQMIN(ncols,256);
+ screendata[scr]->g_carr = new XColor[screendata[scr]->g_cells];
+ TQ_CHECK_PTR( screendata[scr]->g_carr );
+ memset( screendata[scr]->g_carr, 0,
+ screendata[scr]->g_cells*sizeof(XColor) );
+ screendata[scr]->g_carr_fetch = TRUE; // run XQueryColors on demand
+ screendata[scr]->g_our_alloc = new bool[screendata[scr]->g_cells];
+ TQ_CHECK_PTR( screendata[scr]->g_our_alloc );
+ memset( screendata[scr]->g_our_alloc, FALSE,
+ screendata[scr]->g_cells*sizeof(bool) );
+ XColor *xc = &screendata[scr]->g_carr[0];
+ for ( int i=0; i<screendata[scr]->g_cells; i++ ) {
+ xc->pixel = i; // g_carr[i] = color i
+ xc++;
+ }
+ }
+
+ int dictsize;
+ if ( screendata[scr]->g_truecolor ) { // truecolor
+ dictsize = 1; // will not need color dict
+ screendata[scr]->red_mask = (uint)screendata[scr]->g_vis->red_mask;
+ screendata[scr]->green_mask = (uint)screendata[scr]->g_vis->green_mask;
+ screendata[scr]->blue_mask = (uint)screendata[scr]->g_vis->blue_mask;
+ screendata[scr]->red_shift =
+ highest_bit( screendata[scr]->red_mask ) - 7;
+ screendata[scr]->green_shift =
+ highest_bit( screendata[scr]->green_mask ) - 7;
+ screendata[scr]->blue_shift =
+ highest_bit( screendata[scr]->blue_mask ) - 7;
+ } else {
+ dictsize = col_std_dict;
+ }
+ screendata[scr]->colorDict = new TQColorDict(dictsize); // create dictionary
+ TQ_CHECK_PTR( screendata[scr]->colorDict );
+
+ if ( spec == (int)TQApplication::ManyColor ) {
+ screendata[scr]->color_reduce = TRUE;
+
+ switch ( qt_ncols_option ) {
+ case 216:
+ // 6:6:6
+ screendata[scr]->col_div_r = screendata[scr]->col_div_g =
+ screendata[scr]->col_div_b = (255/(6-1));
+ break;
+ default: {
+ // 2:3:1 proportions, solved numerically
+ if ( qt_ncols_option > 255 ) qt_ncols_option = 255;
+ if ( qt_ncols_option < 1 ) qt_ncols_option = 1;
+ int nr = 2;
+ int ng = 2;
+ int nb = 2;
+ for (;;) {
+ if ( nb*2 < nr && (nb+1)*nr*ng < qt_ncols_option )
+ nb++;
+ else if ( nr*3 < ng*2 && nb*(nr+1)*ng < qt_ncols_option )
+ nr++;
+ else if ( nb*nr*(ng+1) < qt_ncols_option )
+ ng++;
+ else break;
+ }
+ qt_ncols_option = nr*ng*nb;
+ screendata[scr]->col_div_r = (255/(nr-1));
+ screendata[scr]->col_div_g = (255/(ng-1));
+ screendata[scr]->col_div_b = (255/(nb-1));
+ }
+ }
+ }
+ }
+
+ scr = TQPaintDevice::x11AppScreen();
+
+ // Initialize global color objects
+ if ( TQPaintDevice::x11AppDefaultVisual(scr) &&
+ TQPaintDevice::x11AppDefaultColormap(scr) ) {
+ globalColors()[blackIdx].setPixel((uint) BlackPixel(dpy, scr));
+ globalColors()[whiteIdx].setPixel((uint) WhitePixel(dpy, scr));
+ } else {
+ globalColors()[blackIdx].alloc(scr);
+ globalColors()[whiteIdx].alloc(scr);
+ }
+
+#if 0 /* 0 == allocate colors on demand */
+ setLazyAlloc( FALSE ); // allocate global colors
+ ((TQColor*)(&darkGray))-> alloc();
+ ((TQColor*)(&gray))-> alloc();
+ ((TQColor*)(&lightGray))-> alloc();
+ ((TQColor*)(&::red))-> alloc();
+ ((TQColor*)(&::green))-> alloc();
+ ((TQColor*)(&::blue))-> alloc();
+ ((TQColor*)(&cyan))-> alloc();
+ ((TQColor*)(&magenta))-> alloc();
+ ((TQColor*)(&yellow))-> alloc();
+ ((TQColor*)(&darkRed))-> alloc();
+ ((TQColor*)(&darkGreen))-> alloc();
+ ((TQColor*)(&darkBlue))-> alloc();
+ ((TQColor*)(&darkCyan))-> alloc();
+ ((TQColor*)(&darkMagenta))-> alloc();
+ ((TQColor*)(&darkYellow))-> alloc();
+ setLazyAlloc( TRUE );
+#endif
+}
+
+/*!
+ Internal clean up required for TQColor.
+ This function is called from the TQApplication destructor.
+
+ \sa initialize()
+*/
+
+void TQColor::cleanup()
+{
+ if ( !color_init )
+ return;
+ color_init = FALSE;
+ int scr;
+ for ( scr = 0; scr < screencount; scr++ ) {
+ if ( screendata[scr]->g_carr ) {
+ delete [] screendata[scr]->g_carr;
+ screendata[scr]->g_carr = 0;
+ }
+ if ( screendata[scr]->g_our_alloc ) {
+ delete [] screendata[scr]->g_our_alloc;
+ screendata[scr]->g_our_alloc = 0;
+ }
+ if ( screendata[scr]->colorDict ) {
+ screendata[scr]->colorDict->setAutoDelete( TRUE );
+ screendata[scr]->colorDict->clear();
+ delete screendata[scr]->colorDict;
+ screendata[scr]->colorDict = 0;
+ }
+ delete screendata[scr];
+ screendata[scr] = 0;
+ }
+ delete [] screendata;
+ screendata = 0;
+ screencount = 0;
+}
+
+
+/*****************************************************************************
+ TQColor member functions
+ *****************************************************************************/
+
+/*!
+ \internal
+ Allocates the color on screen \a screen. Only used in X11.
+
+ \sa alloc(), pixel()
+*/
+uint TQColor::alloc( int screen )
+{
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ if ( screen < 0 )
+ screen = TQPaintDevice::x11AppScreen();
+ if ( !color_init )
+ return dpy ? (uint)BlackPixel(dpy, screen) : 0;
+ int r = tqRed(d.argb);
+ int g = tqGreen(d.argb);
+ int b = tqBlue(d.argb);
+ uint pix = 0;
+ TQColorScreenData *sd = screendata[screen];
+ if ( sd->g_truecolor ) { // truecolor: map to pixel
+ r = sd->red_shift > 0 ? r << sd->red_shift : r >> -sd->red_shift;
+ g = sd->green_shift > 0 ? g << sd->green_shift : g >> -sd->green_shift;
+ b = sd->blue_shift > 0 ? b << sd->blue_shift : b >> -sd->blue_shift;
+ pix = (b & sd->blue_mask) | (g & sd->green_mask) | (r & sd->red_mask)
+ | ~(sd->blue_mask | sd->green_mask | sd->red_mask);
+ if ( screen == TQPaintDevice::x11AppScreen() )
+ d.d32.pix = pix;
+ return pix;
+ }
+ TQColorData *c = sd->colorDict->tqfind( (long)(d.argb) );
+ if ( c ) { // found color in dictionary
+ pix = c->pix;
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE; // color ok
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix; // use same pixel value
+ if ( c->context != current_alloc_context ) {
+ c->context = 0; // convert to default context
+ sd->g_our_alloc[pix] = TRUE; // reuse without XAllocColor
+ }
+ }
+ return pix;
+ }
+
+ XColor col;
+ col.red = r << 8;
+ col.green = g << 8;
+ col.blue = b << 8;
+
+ bool try_again = FALSE;
+ bool try_alloc = !sd->color_reduce;
+ int try_count = 0;
+
+ do {
+ // This loop is run until we manage to either allocate or
+ // tqfind an approximate color, it stops after a few iterations.
+
+ try_again = FALSE;
+
+ if ( try_alloc && sd->colors_avail &&
+ XAllocColor(dpy, TQPaintDevice::x11AppColormap( screen ),&col) ) {
+ // We could allocate the color
+ pix = (uint) col.pixel;
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.pix = pix;
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ sd->g_carr[d.d8.pix] = col; // update color array
+ if ( current_alloc_context == 0 )
+ sd->g_our_alloc[d.d8.pix] = TRUE; // reuse without XAllocColor
+ }
+ } else {
+ // No available colors, or we did not want to allocate one
+ int i;
+ sd->colors_avail = FALSE; // no more available colors
+ if ( sd->g_carr_fetch ) { // refetch color array
+ sd->g_carr_fetch = FALSE;
+ XQueryColors( dpy, TQPaintDevice::x11AppColormap( screen ), sd->g_carr,
+ sd->g_cells );
+ }
+ int mindist;
+ i = tqfind_nearest_color( r, g, b, &mindist, sd );
+
+ if ( mindist != 0 && !try_alloc ) {
+ // Not an exact match with an existing color
+ int rr = ((r+sd->col_div_r/2)/sd->col_div_r)*sd->col_div_r;
+ int rg = ((g+sd->col_div_g/2)/sd->col_div_g)*sd->col_div_g;
+ int rb = ((b+sd->col_div_b/2)/sd->col_div_b)*sd->col_div_b;
+ int rx = rr - r;
+ int gx = rg - g;
+ int bx = rb - b;
+ int dist = rx*rx + gx*gx + bx*bx; // calculate distance
+ if ( dist < mindist ) {
+ // reduced color is closer - try to alloc it
+ r = rr;
+ g = rg;
+ b = rb;
+ col.red = r << 8;
+ col.green = g << 8;
+ col.blue = b << 8;
+ try_alloc = TRUE;
+ try_again = TRUE;
+ sd->colors_avail = TRUE;
+ continue; // Try alloc reduced color
+ }
+ }
+
+ if ( i == -1 ) { // no nearest color?!
+ int unused, value;
+ hsv(&unused, &unused, &value);
+ if (value < 128) { // dark, use black
+ d.argb = tqRgb(0,0,0);
+ pix = (uint)BlackPixel( dpy, screen );
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix;
+ }
+ } else { // light, use white
+ d.argb = tqRgb(0xff,0xff,0xff);
+ pix = (uint)WhitePixel( dpy, screen );
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix;
+ }
+ }
+ return pix;
+ }
+ if ( sd->g_our_alloc[i] ) { // we've already allocated it
+ ; // i == g_carr[i].pixel
+ } else {
+ // Try to allocate existing color
+ col = sd->g_carr[i];
+ if ( XAllocColor(dpy, TQPaintDevice::x11AppColormap( screen ), &col) ) {
+ i = (uint)col.pixel;
+ sd->g_carr[i] = col; // update color array
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ if ( current_alloc_context == 0 )
+ sd->g_our_alloc[i] = TRUE; // only in the default context
+ }
+ } else {
+ // Oops, it's gone again
+ try_count++;
+ try_again = TRUE;
+ sd->colors_avail = TRUE;
+ sd->g_carr_fetch = TRUE;
+ }
+ }
+ if ( !try_again ) { // got it
+ pix = (uint)sd->g_carr[i].pixel;
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix; // allocated X11 color
+ }
+ }
+ }
+
+ } while ( try_again && try_count < 2 );
+
+ if ( try_again ) { // no hope of allocating color
+ int unused, value;
+ hsv(&unused, &unused, &value);
+ if (value < 128) { // dark, use black
+ d.argb = tqRgb(0,0,0);
+ pix = (uint)BlackPixel( dpy, screen );
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix;
+ }
+ } else { // light, use white
+ d.argb = tqRgb(0xff,0xff,0xff);
+ pix = (uint)WhitePixel( dpy, screen );
+ if ( screen == TQPaintDevice::x11AppScreen() ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = FALSE;
+ d.d8.pix = pix;
+ }
+ }
+ return pix;
+ }
+ // All colors outside context 0 must go into the dictionary
+ bool many = sd->colorDict->count() >= sd->colorDict->size() * 8;
+ if ( many && sd->colorDict->size() == col_std_dict ) {
+ sd->colorDict->resize( col_large_dict );
+ }
+ if ( !many || current_alloc_context != 0 ) {
+ c = new TQColorData; // insert into color dict
+ TQ_CHECK_PTR( c );
+ c->pix = pix;
+ c->context = current_alloc_context;
+ sd->colorDict->insert( (long)d.argb, c ); // store color in dict
+ }
+ return pix;
+}
+
+/*!
+ Allocates the RGB color and returns the pixel value.
+
+ Allocating a color means to obtain a pixel value from the RGB
+ specification. The pixel value is an index into the global color
+ table, but should be considered an arbitrary platform-dependent value.
+
+ The pixel() function calls alloc() if necessary, so in general you
+ don't need to call this function.
+
+ \sa enterAllocContext()
+*/
+// ### 4.0 - remove me?
+uint TQColor::alloc()
+{
+ return alloc( -1 );
+}
+
+/*!
+ \overload
+
+ Returns the pixel value for screen \a screen.
+
+ This value is used by the underlying window system to refer to a color.
+ It can be thought of as an index into the display hardware's color table,
+ but the value is an arbitrary 32-bit value.
+
+ \sa alloc()
+*/
+uint TQColor::pixel( int screen ) const
+{
+ if (screen != TQPaintDevice::x11AppScreen() &&
+ // don't allocate color0 or color1, they have fixed pixel
+ // values for all screens
+ d.argb != tqRgba(255, 255, 255, 1) && d.argb != tqRgba(0, 0, 0, 1))
+ return ((TQColor*)this)->alloc( screen );
+ return pixel();
+}
+
+
+void TQColor::setSystemNamedColor( const TQString& name )
+{
+ // setSystemNamedColor should look up rgb values from the built in
+ // color tables first (see qcolor_p.cpp), and failing that, use
+ // the window system's interface for translating names to rgb values...
+ // we do this so that things like uic can load an XPM file with named colors
+ // and convert it to a png without having to use window system functions...
+ d.argb = qt_get_rgb_val( name.latin1() );
+ TQRgb rgb;
+ if ( qt_get_named_rgb( name.latin1(), &rgb ) ) {
+ setRgb( tqRed(rgb), tqGreen(rgb), tqBlue(rgb) );
+ if ( colormodel == d8 ) {
+ d.d8.invalid = FALSE;
+ d.d8.dirty = TRUE;
+ d.d8.pix = 0;
+ } else {
+ alloc();
+ }
+ } else if ( !color_init ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQColor::setSystemNamedColor: Cannot perform this operation "
+ "because TQApplication does not exist" );
+#endif
+ // set color to invalid
+ *this = TQColor();
+ } else {
+ XColor col, hw_col;
+ if ( XLookupColor(TQPaintDevice::x11AppDisplay(),
+ TQPaintDevice::x11AppColormap(), name.latin1(),
+ &col, &hw_col) ) {
+ setRgb( col.red>>8, col.green>>8, col.blue>>8 );
+ } else {
+ // set color to invalid
+ *this = TQColor();
+ }
+ }
+}
+
+
+#define MAX_CONTEXTS 16
+static int context_stack[MAX_CONTEXTS];
+static int context_ptr = 0;
+
+static void init_context_stack()
+{
+ static bool did_init = FALSE;
+ if ( !did_init ) {
+ did_init = TRUE;
+ context_stack[0] = current_alloc_context = 0;
+ }
+}
+
+
+/*!
+ Enters a color allocation context and returns a non-zero unique
+ identifier.
+
+ Color allocation contexts are useful for programs that need to
+ allocate many colors and throw them away later, like image
+ viewers. The allocation context functions work for true color
+ displays as well as for colormap displays, except that
+ TQColor::destroyAllocContext() does nothing for true color.
+
+ Example:
+ \code
+ TQPixmap loadPixmap( TQString fileName )
+ {
+ static int alloc_context = 0;
+ if ( alloc_context )
+ TQColor::destroyAllocContext( alloc_context );
+ alloc_context = TQColor::enterAllocContext();
+ TQPixmap pm( fileName );
+ TQColor::leaveAllocContext();
+ return pm;
+ }
+ \endcode
+
+ The example code loads a pixmap from file. It frees up all colors
+ that were allocated the last time loadPixmap() was called.
+
+ The initial/default context is 0. TQt keeps a list of colors
+ associated with their allocation contexts. You can call
+ destroyAllocContext() to get rid of all colors that were allocated
+ in a specific context.
+
+ Calling enterAllocContext() enters an allocation context. The
+ allocation context lasts until you call leaveAllocContext().
+ TQColor has an internal stack of allocation contexts. Each call to
+ enterAllocContex() must have a corresponding leaveAllocContext().
+
+ \code
+ // context 0 active
+ int c1 = TQColor::enterAllocContext(); // enter context c1
+ // context c1 active
+ int c2 = TQColor::enterAllocContext(); // enter context c2
+ // context c2 active
+ TQColor::leaveAllocContext(); // leave context c2
+ // context c1 active
+ TQColor::leaveAllocContext(); // leave context c1
+ // context 0 active
+ // Now, free all colors that were allocated in context c2
+ TQColor::destroyAllocContext( c2 );
+ \endcode
+
+ You may also want to set the application's color specification.
+ See TQApplication::setColorSpec() for more information.
+
+ \sa leaveAllocContext(), currentAllocContext(), destroyAllocContext(),
+ TQApplication::setColorSpec()
+*/
+
+int TQColor::enterAllocContext()
+{
+ static int context_seq_no = 0;
+ init_context_stack();
+ if ( context_ptr+1 == MAX_CONTEXTS ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQColor::enterAllocContext: Context stack overflow" );
+#endif
+ return 0;
+ }
+ current_alloc_context = context_stack[++context_ptr] = ++context_seq_no;
+ return current_alloc_context;
+}
+
+
+/*!
+ Leaves a color allocation context.
+
+ See enterAllocContext() for a detailed explanation.
+
+ \sa enterAllocContext(), currentAllocContext()
+*/
+
+void TQColor::leaveAllocContext()
+{
+ init_context_stack();
+ if ( context_ptr == 0 ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQColor::leaveAllocContext: Context stack underflow" );
+#endif
+ return;
+ }
+ current_alloc_context = context_stack[--context_ptr];
+}
+
+
+/*!
+ Returns the current color allocation context.
+
+ The default context is 0.
+
+ \sa enterAllocContext(), leaveAllocContext()
+*/
+
+int TQColor::currentAllocContext()
+{
+ return current_alloc_context;
+}
+
+
+/*!
+ Destroys a color allocation context, \e context.
+
+ This function deallocates all colors that were allocated in the
+ specified \a context. If \a context == -1, it frees up all colors
+ that the application has allocated. If \a context == -2, it frees
+ up all colors that the application has allocated, except those in
+ the default context.
+
+ The function does nothing for true color displays.
+
+ \sa enterAllocContext(), alloc()
+*/
+
+void TQColor::destroyAllocContext( int context )
+{
+ init_context_stack();
+ if ( !color_init )
+ return;
+
+ int screen;
+ for ( screen = 0; screen < screencount; ++screen ) {
+ if ( screendata[screen]->g_truecolor )
+ continue;
+
+ ulong pixels[256];
+ bool freeing[256];
+ memset( freeing, FALSE, screendata[screen]->g_cells*sizeof(bool) );
+ TQColorData *d;
+ TQColorDictIt it( *screendata[screen]->colorDict );
+ int i = 0;
+ uint rgbv;
+ while ( (d=it.current()) ) {
+ rgbv = (uint)it.currentKey();
+ if ( (d->context || context==-1) &&
+ (d->context == context || context < 0) ) {
+ if ( !screendata[screen]->g_our_alloc[d->pix] && !freeing[d->pix] ) {
+ // will free this color
+ pixels[i++] = d->pix;
+ freeing[d->pix] = TRUE;
+ }
+ // remove from dict
+ screendata[screen]->colorDict->remove( (long)rgbv );
+ }
+ ++it;
+ }
+ if ( i )
+ XFreeColors( TQPaintDevice::x11AppDisplay(),
+ TQPaintDevice::x11AppColormap( screen ),
+ pixels, i, 0 );
+ }
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqconnection.cpp b/tqtinterface/qt4/src/kernel/tqconnection.cpp
new file mode 100644
index 0000000..adffe1b
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqconnection.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Implementation of TQConnection class
+**
+** Created : 930417
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqconnection.h"
+
+/*! \class TQConnection tqconnection.h
+ \brief The TQConnection class is an internal class, used in the signal/slot mechanism.
+
+ \internal
+
+ Do not use this class directly in application programs.
+
+ TQObject has a list of TQConnection for each signal that is connected to the
+ outside world.
+*/
+
+TQConnection::TQConnection( const TQObject *object, int member,
+ const char *memberName, int memberType )
+{
+ obj = (TQObject *)object;
+ mbr = member;
+ mbr_name = memberName;
+ mbr_type = memberType;
+ nargs = 0;
+ if ( strstr(memberName,"()") == 0 ) {
+ const char *p = memberName;
+ nargs++;
+ while ( *p ) {
+ if ( *p++ == ',' )
+ nargs++;
+ }
+ }
+}
+
+/*!
+ \fn TQConnection::~TQConnection()
+*/
+
+/*!
+ \fn bool TQConnection::isConnected() const
+*/
+
+/*!
+ \fn TQObject *TQConnection::object() const
+*/
+
+/*!
+ \fn int TQConnection::member() const
+*/
+
+/*!
+ \fn const char *TQConnection::memberName() const
+*/
+
+/*!
+ \fn int TQConnection::numArgs() const
+*/
diff --git a/tqtinterface/qt4/src/kernel/tqconnection.h b/tqtinterface/qt4/src/kernel/tqconnection.h
new file mode 100644
index 0000000..fb62ca8
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqconnection.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Definition of TQConnection class
+**
+** Created : 930417
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCONNECTION_H
+#define TQCONNECTION_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+
+class TQ_EXPORT TQConnection
+{
+public:
+ TQConnection( const TQObject *, int, const char *memberName, int memberType );
+ ~TQConnection() {}
+
+ bool isConnected() const { return obj != 0; }
+
+ TQObject *object() const { return obj; } // get object/member pointer
+ int member() const { return mbr; }
+ const char *memberName() const { return mbr_name; }
+ int memberType() const { return mbr_type; }
+ int numArgs() const { return nargs; }
+
+private:
+ TQObject *obj; // object connected to
+ int mbr; // member connected to
+ const char *mbr_name;
+ int mbr_type;
+ int nargs;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQConnection( const TQConnection & );
+ TQConnection &operator=( const TQConnection & );
+#endif
+};
+
+#define TQ_DEFINED_TQCONNECTION
+#include "tqwinexport.h"
+#endif // TQCONNECTION_H
diff --git a/tqtinterface/qt4/src/kernel/tqcursor.cpp b/tqtinterface/qt4/src/kernel/tqcursor.cpp
new file mode 100644
index 0000000..16e74cf
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqcursor.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Implementation of TQCursor class
+**
+** Created : 940220
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcursor.h"
+
+#ifndef TQT_NO_CURSOR
+
+#include "tqbitmap.h"
+#include "tqimage.h"
+#include "tqdatastream.h"
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \class TQCursor tqcursor.h
+
+ \brief The TQCursor class provides a mouse cursor with an arbitrary
+ tqshape.
+
+ \ingroup appearance
+ \ingroup shared
+
+ This class is mainly used to create mouse cursors that are
+ associated with particular widgets and to get and set the position
+ of the mouse cursor.
+
+ TQt has a number of standard cursor tqshapes, but you can also make
+ custom cursor tqshapes based on a TQBitmap, a tqmask and a hotspot.
+
+ To associate a cursor with a widget, use TQWidget::setCursor(). To
+ associate a cursor with all widgets (normally for a short period
+ of time), use TQApplication::setOverrideCursor().
+
+ To set a cursor tqshape use TQCursor::setShape() or use the TQCursor
+ constructor which takes the tqshape as argument, or you can use one
+ of the predefined cursors defined in the \l tqCursorShape enum.
+
+ If you want to create a cursor with your own bitmap, either use
+ the TQCursor constructor which takes a bitmap and a tqmask or the
+ constructor which takes a pixmap as arguments.
+
+ To set or get the position of the mouse cursor use the static
+ methods TQCursor::pos() and TQCursor::setPos().
+
+ \img cursors.png Cursor Shapes
+
+ \sa TQWidget \link guibooks.html#fowler GUI Design Handbook:
+ Cursors\endlink
+
+ On X11, TQt supports the \link
+ http://www.xfree86.org/4.3.0/Xcursor.3.html Xcursor\endlink
+ library, which allows for full color icon themes. The table below
+ shows the cursor name used for each TQt::tqCursorShape value. If a
+ cursor cannot be found using the name shown below, a standard X11
+ cursor will be used instead. Note: X11 does not provide
+ appropriate cursors for all possible TQt::tqCursorShape values. It
+ is possible that some cursors will be taken from the Xcursor
+ theme, while others will use an internal bitmap cursor.
+
+ \table
+ \header \i TQt::tqCursorShape Values \i Cursor Names
+ \row \i TQt::ArrowCursor \i left_ptr
+ \row \i TQt::UpArrowCursor \i up_arrow
+ \row \i TQt::CrossCursor \i cross
+ \row \i TQt::WaitCursor \i wait
+ \row \i TQt::BusyCursor \i left_ptr_watch
+ \row \i TQt::IbeamCursor \i ibeam
+ \row \i TQt::SizeVerCursor \i size_ver
+ \row \i TQt::SizeHorCursor \i size_hor
+ \row \i TQt::SizeBDiagCursor \i size_bdiag
+ \row \i TQt::SizeFDiagCursor \i size_fdiag
+ \row \i TQt::SizeAllCursor \i size_all
+ \row \i TQt::SplitVCursor \i split_v
+ \row \i TQt::SplitHCursor \i split_h
+ \row \i TQt::PointingHandCursor \i pointing_hand
+ \row \i TQt::ForbiddenCursor \i forbidden
+ \row \i TQt::WhatsThisCursor \i whats_this
+ \endtable
+*/
+
+/*!
+ \enum TQt::tqCursorShape
+
+ This enum type defines the various cursors that can be used.
+
+ \value ArrowCursor standard arrow cursor
+ \value UpArrowCursor upwards arrow
+ \value CrossCursor crosshair
+ \value WaitCursor hourglass/watch
+ \value BusyCursor standard arrow with hourglass/watch
+ \value IbeamCursor ibeam/text entry
+ \value SizeVerCursor vertical resize
+ \value SizeHorCursor horizontal resize
+ \value SizeFDiagCursor diagonal resize (\)
+ \value SizeBDiagCursor diagonal resize (/)
+ \value SizeAllCursor all directions resize
+ \value BlankCursor blank/invisible cursor
+ \value SplitVCursor vertical splitting
+ \value SplitHCursor horizontal splitting
+ \value PointingHandCursor a pointing hand
+ \value ForbiddenCursor a slashed circle
+ \value WhatsThisCursor an arrow with a question mark
+ \value BitmapCursor
+
+ ArrowCursor is the default for widgets in a normal state.
+
+ \img cursors.png Cursor Shapes
+*/
+
+/*****************************************************************************
+ TQCursor stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+
+
+/*!
+ \relates TQCursor
+ Writes the cursor \a c to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQCursor &c )
+{
+ s << (TQ_INT16)c.tqshape(); // write tqshape id to stream
+ if ( c.tqshape() == TQt::BitmapCursor ) { // bitmap cursor
+#if !defined(TQT_NO_IMAGEIO)
+ s << *c.bitmap() << *c.tqmask();
+ s << c.hotSpot();
+#else
+ qWarning("No Image Cursor I/O");
+#endif
+ }
+ return s;
+}
+
+/*!
+ \relates TQCursor
+ Reads a cursor from the stream \a s and sets \a c to the read data.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQCursor &c )
+{
+ TQ_INT16 tqshape;
+ s >> tqshape; // read tqshape id from stream
+ if ( tqshape == TQt::BitmapCursor ) { // read bitmap cursor
+#if !defined(TQT_NO_IMAGEIO)
+ TQBitmap bm, bmm;
+ TQPoint hot;
+ s >> bm >> bmm >> hot;
+ c = TQCursor( bm, bmm, hot.x(), hot.y() );
+#else
+ qWarning("No Image Cursor I/O");
+#endif
+ } else {
+ c.setShape( (int)tqshape ); // create cursor with tqshape
+ }
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+
+/*!
+ Constructs a custom pixmap cursor.
+
+ \a pixmap is the image. It is usual to give it a tqmask (set using
+ TQPixmap::setMask()). \a hotX and \a hotY define the cursor's hot
+ spot.
+
+ If \a hotX is negative, it is set to the \c{pixmap().width()/2}.
+ If \a hotY is negative, it is set to the \c{pixmap().height()/2}.
+
+ Valid cursor sizes depend on the display hardware (or the
+ underlying window system). We recommend using 32x32 cursors,
+ because this size is supported on all platforms. Some platforms
+ also support 16x16, 48x48 and 64x64 cursors.
+
+ Currently, only black-and-white pixmaps can be used.
+
+ \sa TQPixmap::TQPixmap(), TQPixmap::setMask()
+*/
+
+TQCursor::TQCursor( const TQPixmap &pixmap, int hotX, int hotY )
+{
+ TQImage img = pixmap.convertToImage().
+ convertDepth( 8, TQt::ThresholdDither|TQt::AvoidDither );
+ TQBitmap bm;
+ bm.convertFromImage( img, TQt::ThresholdDither|TQt::AvoidDither );
+ TQBitmap bmm;
+ if ( bm.tqmask() ) {
+ bmm = *bm.tqmask();
+ TQBitmap nullBm;
+ bm.setMask( nullBm );
+ }
+ else if ( pixmap.tqmask() ) {
+ TQImage mimg = pixmap.tqmask()->convertToImage().
+ convertDepth( 8, TQt::ThresholdDither|TQt::AvoidDither );
+ bmm.convertFromImage( mimg, TQt::ThresholdDither|TQt::AvoidDither );
+ }
+ else {
+ bmm.resize( bm.size() );
+ bmm.fill( TQt::color1 );
+ }
+
+ setBitmap(bm,bmm,hotX,hotY);
+}
+
+
+
+/*!
+ Constructs a custom bitmap cursor.
+
+ \a bitmap and
+ \a tqmask make up the bitmap.
+ \a hotX and
+ \a hotY define the cursor's hot spot.
+
+ If \a hotX is negative, it is set to the \c{bitmap().width()/2}.
+ If \a hotY is negative, it is set to the \c{bitmap().height()/2}.
+
+ The cursor \a bitmap (B) and \a tqmask (M) bits are combined like this:
+ \list
+ \i B=1 and M=1 gives black.
+ \i B=0 and M=1 gives white.
+ \i B=0 and M=0 gives transtqparent.
+ \i B=1 and M=0 gives an undefined result.
+ \endlist
+
+ Use the global TQt color \c color0 to draw 0-pixels and \c color1 to
+ draw 1-pixels in the bitmaps.
+
+ Valid cursor sizes depend on the display hardware (or the
+ underlying window system). We recommend using 32x32 cursors,
+ because this size is supported on all platforms. Some platforms
+ also support 16x16, 48x48 and 64x64 cursors.
+
+ \sa TQBitmap::TQBitmap(), TQBitmap::setMask()
+*/
+
+TQCursor::TQCursor( const TQBitmap &bitmap, const TQBitmap &tqmask,
+ int hotX, int hotY )
+{
+ setBitmap(bitmap,tqmask,hotX,hotY);
+}
+
+#endif // USE_QT4
+
+#endif // TQT_NO_CURSOR
+
+
diff --git a/tqtinterface/qt4/src/kernel/tqcursor.h b/tqtinterface/qt4/src/kernel/tqcursor.h
new file mode 100644
index 0000000..9aa6437
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqcursor.h
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Definition of TQCursor class
+**
+** Created : 940219
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCURSOR_H
+#define TQCURSOR_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqpoint.h"
+#include "tqshared.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qcursor.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+struct TQCursorData;
+
+class TQ_EXPORT TQCursor : public QCursor, virtual public TQt
+{
+public:
+ TQCursor() : QCursor() {}
+ TQCursor( int tqshape ) : QCursor( tqshape ) {}
+ TQCursor( Qt::CursorShape shape ) : QCursor( shape ) {}
+ TQCursor( const QBitmap &bitmap, const QBitmap &tqmask, int hotX=-1, int hotY=-1 ) : QCursor( bitmap, tqmask, hotX, hotY ) {}
+ TQCursor( const QPixmap &pixmap, int hotX=-1, int hotY=-1 ) : QCursor( pixmap, hotX, hotY ) {}
+ TQCursor( const QCursor & c ) : QCursor( c ) {}
+
+ inline int tqshape() const { return shape(); }
+
+ static void initialize();
+ static void cleanup();
+
+private:
+ TQCursorData *data;
+};
+
+#else // USE_QT4
+
+/*
+ ### The fake cursor has to go first with old qdoc.
+*/
+#ifdef TQT_NO_CURSOR
+
+class TQ_EXPORT TQCursor : public TQt
+{
+public:
+ static TQPoint pos();
+ static void setPos( int x, int y );
+ static void setPos( const TQPoint & );
+private:
+ TQCursor();
+};
+
+#endif // TQT_NO_CURSOR
+
+#ifndef TQT_NO_CURSOR
+
+struct TQCursorData;
+
+
+class TQ_EXPORT TQCursor : public TQt
+{
+public:
+ TQCursor(); // create default arrow cursor
+ TQCursor( int tqshape );
+ TQCursor( const TQBitmap &bitmap, const TQBitmap &tqmask,
+ int hotX=-1, int hotY=-1 );
+ TQCursor( const TQPixmap &pixmap,
+ int hotX=-1, int hotY=-1 );
+ TQCursor( const TQCursor & );
+ ~TQCursor();
+ TQCursor &operator=( const TQCursor & );
+
+ int tqshape() const;
+ void setShape( int );
+
+ const TQBitmap *bitmap() const;
+ const TQBitmap *tqmask() const;
+ TQPoint hotSpot() const;
+
+#if defined(TQ_WS_WIN)
+ HCURSOR handle() const;
+ TQCursor( HCURSOR );
+#elif defined(TQ_WS_X11)
+ HANDLE handle() const;
+ TQCursor( HANDLE );
+#elif defined(TQ_WS_MAC)
+ HANDLE handle() const;
+#elif defined(TQ_WS_TQWS)
+ HANDLE handle() const;
+#endif
+
+ static TQPoint pos();
+ static void setPos( int x, int y );
+ static void setPos( const TQPoint & );
+
+ static void initialize();
+ static void cleanup();
+
+#if defined(TQ_WS_X11)
+ static int x11Screen();
+#endif
+private:
+ void setBitmap( const TQBitmap &bitmap, const TQBitmap &tqmask,
+ int hotX, int hotY );
+ void update() const;
+ TQCursorData *data;
+ TQCursor *tqfind_cur(int);
+#if defined(TQ_WS_MAC)
+ friend void qt_mac_set_cursor(const TQCursor *c, const Point *p);
+#endif
+};
+
+
+#if !defined(TQT_CLEAN_NAMESPACE)
+// tqCursorShape is defined in X11/X.h
+#ifdef tqCursorShape
+#define X_tqCursorShape tqCursorShape
+#undef tqCursorShape
+#endif
+typedef TQt::tqCursorShape TQtqCursorShape;
+#ifdef X_tqCursorShape
+#define tqCursorShape X_tqCursorShape
+#endif
+#endif
+
+
+/*****************************************************************************
+ TQCursor stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQCursor & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQCursor & );
+#endif
+#endif // TQT_NO_CURSOR
+
+
+inline void TQCursor::setPos( const TQPoint &p )
+{
+ setPos( p.x(), p.y() );
+}
+
+#endif // USE_QT4
+
+#endif // TQCURSOR_H \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqcursor_x11.cpp b/tqtinterface/qt4/src/kernel/tqcursor_x11.cpp
new file mode 100644
index 0000000..36f2504
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqcursor_x11.cpp
@@ -0,0 +1,1013 @@
+/****************************************************************************
+**
+** Implementation of TQCursor class for X11
+**
+** Created : 940219
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcursor.h"
+#include "tqbitmap.h"
+#include "tqimage.h"
+#include "tqapplication.h"
+#include "tqdatastream.h"
+#include "tqnamespace.h"
+#include "tqt_x11_p.h"
+#include <X11/cursorfont.h>
+
+#ifndef TQT_NO_XCURSOR
+# include <X11/Xcursor/Xcursor.h>
+#endif // TQT_NO_XCURSOR
+
+#ifdef USE_QT4
+
+/*****************************************************************************
+ Global cursors
+ *****************************************************************************/
+
+static TQCursor cursorTable[TQt::LastCursor+1];
+
+static const int arrowCursorIdx = 0;
+
+TQT_STATIC_CONST_IMPL TQCursor & TQt::arrowCursor = cursorTable[0];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::upArrowCursor = cursorTable[1];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::crossCursor = cursorTable[2];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::waitCursor = cursorTable[3];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::ibeamCursor = cursorTable[4];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeVerCursor = cursorTable[5];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeHorCursor = cursorTable[6];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeBDiagCursor = cursorTable[7];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeFDiagCursor = cursorTable[8];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeAllCursor = cursorTable[9];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::blankCursor = cursorTable[10];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::splitVCursor = cursorTable[11];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::splitHCursor = cursorTable[12];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::pointingHandCursor = cursorTable[13];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::forbiddenCursor = cursorTable[14];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::whatsThisCursor = cursorTable[15];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::busyCursor = cursorTable[16];
+
+// TQT_STATIC_CONST TQCursor & arrowCursor = Qt::ArrowCursor;
+// TQT_STATIC_CONST TQCursor & upArrowCursor = Qt::UpArrowCursor;
+// TQT_STATIC_CONST TQCursor & crossCursor = Qt::CrossCursor;
+// TQT_STATIC_CONST TQCursor & waitCursor = Qt::WaitCursor;
+// TQT_STATIC_CONST TQCursor & ibeamCursor = Qt::IBeamCursor;
+// TQT_STATIC_CONST TQCursor & sizeVerCursor = Qt::SizeVerCursor;
+// TQT_STATIC_CONST TQCursor & sizeHorCursor = Qt::SizeHorCursor;
+// TQT_STATIC_CONST TQCursor & sizeBDiagCursor = Qt::SizeBDiagCursor;
+// TQT_STATIC_CONST TQCursor & sizeFDiagCursor = Qt::SizeFDiagCursor;
+// TQT_STATIC_CONST TQCursor & sizeAllCursor = Qt::SizeAllCursor;
+// TQT_STATIC_CONST TQCursor & blankCursor = Qt::BlankCursor;
+// TQT_STATIC_CONST TQCursor & splitVCursor = Qt::SplitVCursor;
+// TQT_STATIC_CONST TQCursor & splitHCursor = Qt::SplitHCursor;
+// TQT_STATIC_CONST TQCursor & pointingHandCursor = Qt::PointingHandCursor;
+// TQT_STATIC_CONST TQCursor & forbiddenCursor = Qt::ForbiddenCursor;
+// TQT_STATIC_CONST TQCursor & whatsThisCursor = Qt::WhatsThisCursor;
+// TQT_STATIC_CONST TQCursor & busyCursor = Qt::BusyCursor;
+
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::arrowCursor = Qt::ArrowCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::upArrowCursor = Qt::UpArrowCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::crossCursor = Qt::CrossCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::waitCursor = Qt::WaitCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::ibeamCursor = Qt::IBeamCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeVerCursor = Qt::SizeVerCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeHorCursor = Qt::SizeHorCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeBDiagCursor = Qt::SizeBDiagCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeFDiagCursor = Qt::SizeFDiagCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeAllCursor = Qt::SizeAllCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::blankCursor = Qt::BlankCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::splitVCursor = Qt::SplitVCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::splitHCursor = Qt::SplitHCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::pointingHandCursor = Qt::PointingHandCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::forbiddenCursor = Qt::ForbiddenCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::whatsThisCursor = Qt::WhatsThisCursor;
+// TQT_STATIC_CONST_IMPL TQCursor & TQt::busyCursor = Qt::BusyCursor;
+
+/*****************************************************************************
+ Internal TQCursorData class
+ *****************************************************************************/
+
+// struct TQCursorData : public TQShared
+// {
+// TQCursorData( int s = 0 );
+// ~TQCursorData();
+// int ctqshape;
+// TQBitmap *bm, *bmm;
+// short hx, hy;
+// XColor fg,bg;
+// Cursor hcurs;
+// Pixmap pm, pmm;
+// };
+//
+// TQCursorData::TQCursorData( int s )
+// {
+// ctqshape = s;
+// hcurs = 0;
+// bm = bmm = 0;
+// hx = hy = 0;
+// pm = pmm = 0;
+// }
+
+// TQCursorData::~TQCursorData()
+// {
+// Display *dpy = TQPaintDevice::x11AppDisplay();
+//
+// // Add in checking for the display too as on HP-UX
+// // we seem to get a core dump as the cursor data is
+// // deleted again from main() on exit...
+// if ( hcurs && dpy )
+// XFreeCursor( dpy, hcurs );
+// if ( pm && dpy )
+// XFreePixmap( dpy, pm );
+// if ( pmm && dpy )
+// XFreePixmap( dpy, pmm );
+// delete bm;
+// delete bmm;
+// }
+
+static bool initialized = FALSE;
+
+/*!
+ Internal function that deinitializes the predefined cursors.
+ This function is called from the TQApplication destructor.
+
+ \sa initialize()
+*/
+void TQCursor::cleanup()
+{
+ if ( !initialized )
+ return;
+
+// int tqshape;
+// for( tqshape = 0; tqshape <= LastCursor; tqshape++ ) {
+// if ( cursorTable[tqshape].data && cursorTable[tqshape].data->deref() )
+// delete cursorTable[tqshape].data;
+// cursorTable[tqshape].data = 0;
+// }
+
+ initialized = FALSE;
+}
+
+
+/*!
+ Internal function that initializes the predefined cursors.
+ This function is called from the TQApplication constructor.
+
+ \sa cleanup()
+*/
+
+void TQCursor::initialize()
+{
+// int tqshape;
+// for( tqshape = 0; tqshape <= LastCursor; tqshape++ )
+// cursorTable[tqshape].data = new TQCursorData( tqshape );
+// initialized = TRUE;
+// qAddPostRoutine( cleanup );
+
+ int tqshape;
+ for( tqshape = 0; tqshape <= TQt::LastCursor; tqshape++ ) {
+ switch(tqshape) {
+ case 0: new(&cursorTable[tqshape]) TQCursor(Qt::ArrowCursor); break;
+ case 1: new(&cursorTable[tqshape]) TQCursor(Qt::UpArrowCursor); break;
+ case 2: new(&cursorTable[tqshape]) TQCursor(Qt::CrossCursor); break;
+ case 3: new(&cursorTable[tqshape]) TQCursor(Qt::WaitCursor); break;
+ case 4: new(&cursorTable[tqshape]) TQCursor(Qt::IBeamCursor); break;
+ case 5: new(&cursorTable[tqshape]) TQCursor(Qt::SizeVerCursor); break;
+ case 6: new(&cursorTable[tqshape]) TQCursor(Qt::SizeHorCursor); break;
+ case 7: new(&cursorTable[tqshape]) TQCursor(Qt::SizeBDiagCursor); break;
+ case 8: new(&cursorTable[tqshape]) TQCursor(Qt::SizeFDiagCursor); break;
+ case 9: new(&cursorTable[tqshape]) TQCursor(Qt::SizeAllCursor); break;
+ case 10: new(&cursorTable[tqshape]) TQCursor(Qt::BlankCursor); break;
+ case 11: new(&cursorTable[tqshape]) TQCursor(Qt::SplitVCursor); break;
+ case 12: new(&cursorTable[tqshape]) TQCursor(Qt::SplitHCursor); break;
+ case 13: new(&cursorTable[tqshape]) TQCursor(Qt::PointingHandCursor); break;
+ case 14: new(&cursorTable[tqshape]) TQCursor(Qt::ForbiddenCursor); break;
+ case 15: new(&cursorTable[tqshape]) TQCursor(Qt::WhatsThisCursor); break;
+ case 16: new(&cursorTable[tqshape]) TQCursor(Qt::BusyCursor); break;
+ case 17: new(&cursorTable[tqshape]) TQCursor(Qt::OpenHandCursor); break;
+ case 18: new(&cursorTable[tqshape]) TQCursor(Qt::ClosedHandCursor); break;
+ case 19: new(&cursorTable[tqshape]) TQCursor(Qt::DragCopyCursor); break;
+ case 20: new(&cursorTable[tqshape]) TQCursor(Qt::DragMoveCursor); break;
+ case 21: new(&cursorTable[tqshape]) TQCursor(Qt::DragLinkCursor); break;
+ }
+ }
+ initialized = TRUE;
+ qAddPostRoutine( cleanup );
+}
+
+#else // USE_QT4
+
+// Define TQT_USE_APPROXIMATE_CURSORS when compiling if you REALLY want to
+// use the ugly X11 cursors.
+
+/*****************************************************************************
+ Internal TQCursorData class
+ *****************************************************************************/
+
+struct TQCursorData : public TQShared
+{
+ TQCursorData( int s = 0 );
+ ~TQCursorData();
+ int ctqshape;
+ TQBitmap *bm, *bmm;
+ short hx, hy;
+ XColor fg,bg;
+ Cursor hcurs;
+ Pixmap pm, pmm;
+};
+
+TQCursorData::TQCursorData( int s )
+{
+ ctqshape = s;
+ hcurs = 0;
+ bm = bmm = 0;
+ hx = hy = 0;
+ pm = pmm = 0;
+}
+
+TQCursorData::~TQCursorData()
+{
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+
+ // Add in checking for the display too as on HP-UX
+ // we seem to get a core dump as the cursor data is
+ // deleted again from main() on exit...
+ if ( hcurs && dpy )
+ XFreeCursor( dpy, hcurs );
+ if ( pm && dpy )
+ XFreePixmap( dpy, pm );
+ if ( pmm && dpy )
+ XFreePixmap( dpy, pmm );
+ delete bm;
+ delete bmm;
+}
+
+
+/*****************************************************************************
+ Global cursors
+ *****************************************************************************/
+
+static TQCursor cursorTable[TQt::LastCursor+1];
+
+static const int arrowCursorIdx = 0;
+
+TQT_STATIC_CONST_IMPL TQCursor & TQt::arrowCursor = cursorTable[0];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::upArrowCursor = cursorTable[1];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::crossCursor = cursorTable[2];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::waitCursor = cursorTable[3];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::ibeamCursor = cursorTable[4];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeVerCursor = cursorTable[5];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeHorCursor = cursorTable[6];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeBDiagCursor = cursorTable[7];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeFDiagCursor = cursorTable[8];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::sizeAllCursor = cursorTable[9];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::blankCursor = cursorTable[10];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::splitVCursor = cursorTable[11];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::splitHCursor = cursorTable[12];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::pointingHandCursor = cursorTable[13];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::forbiddenCursor = cursorTable[14];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::whatsThisCursor = cursorTable[15];
+TQT_STATIC_CONST_IMPL TQCursor & TQt::busyCursor = cursorTable[16];
+
+
+TQCursor *TQCursor::tqfind_cur( int tqshape ) // tqfind predefined cursor
+{
+ return (uint)tqshape <= LastCursor ? &cursorTable[tqshape] : 0;
+}
+
+
+static bool initialized = FALSE;
+
+/*!
+ Internal function that deinitializes the predefined cursors.
+ This function is called from the TQApplication destructor.
+
+ \sa initialize()
+*/
+void TQCursor::cleanup()
+{
+ if ( !initialized )
+ return;
+
+ int tqshape;
+ for( tqshape = 0; tqshape <= LastCursor; tqshape++ ) {
+ if ( cursorTable[tqshape].data && cursorTable[tqshape].data->deref() )
+ delete cursorTable[tqshape].data;
+ cursorTable[tqshape].data = 0;
+ }
+ initialized = FALSE;
+}
+
+
+/*!
+ Internal function that initializes the predefined cursors.
+ This function is called from the TQApplication constructor.
+
+ \sa cleanup()
+*/
+
+void TQCursor::initialize()
+{
+ int tqshape;
+ for( tqshape = 0; tqshape <= LastCursor; tqshape++ )
+ cursorTable[tqshape].data = new TQCursorData( tqshape );
+ initialized = TRUE;
+ qAddPostRoutine( cleanup );
+}
+
+
+/*!
+ Constructs a cursor with the default arrow tqshape.
+*/
+TQCursor::TQCursor()
+{
+ if ( !initialized ) {
+ if ( tqApp->startingUp() ) {
+ data = 0;
+ return;
+ }
+ initialize();
+ }
+ TQCursor* c = &cursorTable[arrowCursorIdx];
+ c->data->ref();
+ data = c->data;
+}
+
+
+
+/*!
+ Constructs a cursor with the specified \a tqshape.
+
+ See \l tqCursorShape for a list of tqshapes.
+
+ \sa setShape()
+*/
+
+TQCursor::TQCursor( int tqshape )
+{
+ if ( !initialized )
+ initialize();
+ TQCursor *c = tqfind_cur( tqshape );
+ if ( !c ) // not found
+ c = &cursorTable[arrowCursorIdx]; // then use arrowCursor
+ c->data->ref();
+ data = c->data;
+}
+
+/*!
+ Constructs a cursor from the window system cursor \a cursor.
+
+ \warning Using this function is not portable. This function is only
+ available on X11 and Windows.
+*/
+TQCursor::TQCursor( HANDLE cursor )
+{
+ if ( !initialized )
+ initialize();
+
+ data = new TQCursorData;
+ TQ_CHECK_PTR( data );
+ data->hcurs = cursor;
+}
+
+
+
+void TQCursor::setBitmap( const TQBitmap &bitmap, const TQBitmap &tqmask,
+ int hotX, int hotY )
+{
+ if ( !initialized )
+ initialize();
+ if ( bitmap.depth() != 1 || tqmask.depth() != 1 ||
+ bitmap.size() != tqmask.size() ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQCursor: Cannot create bitmap cursor; invalid bitmap(s)" );
+#endif
+ TQCursor *c = &cursorTable[arrowCursorIdx];
+ c->data->ref();
+ data = c->data;
+ return;
+ }
+ data = new TQCursorData;
+ TQ_CHECK_PTR( data );
+ data->bm = new TQBitmap( bitmap );
+ data->bmm = new TQBitmap( tqmask );
+ data->hcurs = 0;
+ data->ctqshape = BitmapCursor;
+ data->hx = hotX >= 0 ? hotX : bitmap.width()/2;
+ data->hy = hotY >= 0 ? hotY : bitmap.height()/2;
+ data->fg.red = 0 << 8;
+ data->fg.green = 0 << 8;
+ data->fg.blue = 0 << 8;
+ data->bg.red = 255 << 8;
+ data->bg.green = 255 << 8;
+ data->bg.blue = 255 << 8;
+ update(); // Xcursor's backward compatibility hack needs the cursor to be created
+ // right after the bitmaps are created and filled with data
+}
+
+
+/*!
+ Constructs a copy of the cursor \a c.
+*/
+
+TQCursor::TQCursor( const TQCursor &c )
+{
+ if ( !initialized )
+ initialize();
+ data = c.data; // shallow copy
+ data->ref();
+}
+
+/*!
+ Destroys the cursor.
+*/
+
+TQCursor::~TQCursor()
+{
+ if ( data && data->deref() )
+ delete data;
+}
+
+
+/*!
+ Assigns \a c to this cursor and returns a reference to this
+ cursor.
+*/
+
+TQCursor &TQCursor::operator=( const TQCursor &c )
+{
+ if ( !initialized )
+ initialize();
+ c.data->ref(); // avoid c = c
+ if ( data->deref() )
+ delete data;
+ data = c.data;
+ return *this;
+}
+
+
+/*!
+ Returns the cursor tqshape identifier. The return value is one of
+ the \l tqCursorShape enum values (cast to an int).
+
+ \sa setShape()
+*/
+
+int TQCursor::tqshape() const
+{
+ if ( !initialized )
+ initialize();
+ return data->ctqshape;
+}
+
+/*!
+ Sets the cursor to the tqshape identified by \a tqshape.
+
+ See \l tqCursorShape for the list of cursor tqshapes.
+
+ \sa tqshape()
+*/
+
+void TQCursor::setShape( int tqshape )
+{
+ if ( !initialized )
+ initialize();
+ TQCursor *c = tqfind_cur( tqshape ); // tqfind one of the global ones
+ if ( !c ) // not found
+ c = &cursorTable[arrowCursorIdx]; // then use arrowCursor
+ c->data->ref();
+ if ( data->deref() ) // make shallow copy
+ delete data;
+ data = c->data;
+}
+
+
+/*!
+ Returns the cursor bitmap, or 0 if it is one of the standard
+ cursors.
+*/
+const TQBitmap *TQCursor::bitmap() const
+{
+ if ( !initialized )
+ initialize();
+ return data->bm;
+}
+
+/*!
+ Returns the cursor bitmap tqmask, or 0 if it is one of the standard
+ cursors.
+*/
+
+const TQBitmap *TQCursor::tqmask() const
+{
+ if ( !initialized )
+ initialize();
+ return data->bmm;
+}
+
+/*!
+ Returns the cursor hot spot, or (0, 0) if it is one of the
+ standard cursors.
+*/
+
+TQPoint TQCursor::hotSpot() const
+{
+ if ( !initialized )
+ initialize();
+ return TQPoint( data->hx, data->hy );
+}
+
+
+/*!
+ Returns the window system cursor handle.
+
+ \warning
+ Portable in principle, but if you use it you are probably about to
+ do something non-portable. Be careful.
+*/
+
+TQt::HANDLE TQCursor::handle() const
+{
+ if ( !initialized )
+ initialize();
+ if ( !data->hcurs )
+ update();
+ return data->hcurs;
+}
+
+/*!
+ \fn TQCursor::TQCursor( HCURSOR handle )
+
+ Creates a cursor with the specified window system handle \a
+ handle.
+
+ \warning
+ Portable in principle, but if you use it you are probably about to
+ do something non-portable. Be careful.
+*/
+
+/*!
+ Returns the position of the cursor (hot spot) in global screen
+ coordinates.
+
+ You can call TQWidget::mapFromGlobal() to translate it to widget
+ coordinates.
+
+ \sa setPos(), TQWidget::mapFromGlobal(), TQWidget::mapToGlobal()
+*/
+TQPoint TQCursor::pos()
+{
+ Window root;
+ Window child;
+ int root_x, root_y, win_x, win_y;
+ uint buttons;
+ Display* dpy = TQPaintDevice::x11AppDisplay();
+ for ( int i = 0; i < ScreenCount( dpy ); i++ ) {
+ if ( XQueryPointer( dpy, TQPaintDevice::x11AppRootWindow( i ), &root, &child,
+ &root_x, &root_y, &win_x, &win_y, &buttons ) )
+
+ return TQPoint( root_x, root_y );
+ }
+ return TQPoint();
+}
+
+/*! \internal
+*/
+int TQCursor::x11Screen()
+{
+ Window root;
+ Window child;
+ int root_x, root_y, win_x, win_y;
+ uint buttons;
+ Display* dpy = TQPaintDevice::x11AppDisplay();
+ for ( int i = 0; i < ScreenCount( dpy ); i++ ) {
+ if ( XQueryPointer( dpy, TQPaintDevice::x11AppRootWindow( i ), &root, &child,
+ &root_x, &root_y, &win_x, &win_y, &buttons ) )
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ Moves the cursor (hot spot) to the global screen position (\a x,
+ \a y).
+
+ You can call TQWidget::mapToGlobal() to translate widget
+ coordinates to global screen coordinates.
+
+ \sa pos(), TQWidget::mapFromGlobal(), TQWidget::mapToGlobal()
+*/
+
+void TQCursor::setPos( int x, int y )
+{
+ TQPoint current, target(x, y);
+
+ // this is copied from pos(), since we need the screen number for the correct
+ // root window in the XWarpPointer call
+ Window root;
+ Window child;
+ int root_x, root_y, win_x, win_y;
+ uint buttons;
+ Display* dpy = TQPaintDevice::x11AppDisplay();
+ int screen;
+ for ( screen = 0; screen < ScreenCount( dpy ); screen++ ) {
+ if ( XQueryPointer( dpy, TQPaintDevice::x11AppRootWindow( screen ), &root, &child,
+ &root_x, &root_y, &win_x, &win_y, &buttons ) ) {
+ current = TQPoint( root_x, root_y );
+ break;
+ }
+ }
+
+ if ( screen >= ScreenCount( dpy ) )
+ return;
+
+ // Need to check, since some X servers generate null mouse move
+ // events, causing looping in applications which call setPos() on
+ // every mouse move event.
+ //
+ if ( current == target )
+ return;
+
+ XWarpPointer( TQPaintDevice::x11AppDisplay(), None,
+ TQPaintDevice::x11AppRootWindow( screen ),
+ 0, 0, 0, 0, x, y );
+}
+
+/*!
+ \overload void TQCursor::setPos ( const TQPoint & )
+*/
+
+
+/*!
+ \internal
+
+ Creates the cursor.
+*/
+
+void TQCursor::update() const
+{
+ if ( !initialized )
+ initialize();
+ register TQCursorData *d = data; // cheat const!
+ if ( d->hcurs ) // already loaded
+ return;
+
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ Window rootwin = TQPaintDevice::x11AppRootWindow();
+
+ if ( d->ctqshape == BitmapCursor ) {
+ d->hcurs = XCreatePixmapCursor( dpy, d->bm->handle(), d->bmm->handle(),
+ &d->fg, &d->bg, d->hx, d->hy );
+ return;
+ }
+
+#ifndef TQT_NO_XCURSOR
+ static const char *cursorNames[] = {
+ "left_ptr",
+ "up_arrow",
+ "cross",
+ "wait",
+ "ibeam",
+ "size_ver",
+ "size_hor",
+ "size_bdiag",
+ "size_fdiag",
+ "size_all",
+ "blank",
+ "split_v",
+ "split_h",
+ "pointing_hand",
+ "forbidden",
+ "whats_this",
+ "left_ptr_watch"
+ };
+
+ d->hcurs = XcursorLibraryLoadCursor( dpy, cursorNames[d->ctqshape] );
+ if ( d->hcurs )
+ return;
+#endif // TQT_NO_XCURSOR
+
+ static uchar cur_blank_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+ // Non-standard X11 cursors are created from bitmaps
+
+#ifndef TQT_USE_APPROXIMATE_CURSORS
+ static const uchar cur_ver_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f,
+ 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0xf0, 0x0f,
+ 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00 };
+ static const uchar mcur_ver_bits[] = {
+ 0x00, 0x00, 0x80, 0x03, 0xc0, 0x07, 0xe0, 0x0f, 0xf0, 0x1f, 0xf8, 0x3f,
+ 0xfc, 0x7f, 0xc0, 0x07, 0xc0, 0x07, 0xc0, 0x07, 0xfc, 0x7f, 0xf8, 0x3f,
+ 0xf0, 0x1f, 0xe0, 0x0f, 0xc0, 0x07, 0x80, 0x03 };
+ static const uchar cur_hor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x30, 0x18,
+ 0x38, 0x38, 0xfc, 0x7f, 0xfc, 0x7f, 0x38, 0x38, 0x30, 0x18, 0x20, 0x08,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar mcur_hor_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x60, 0x0c, 0x70, 0x1c, 0x78, 0x3c,
+ 0xfc, 0x7f, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfc, 0x7f, 0x78, 0x3c,
+ 0x70, 0x1c, 0x60, 0x0c, 0x40, 0x04, 0x00, 0x00 };
+ static const uchar cur_bdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3c, 0x00, 0x3e,
+ 0x00, 0x37, 0x88, 0x23, 0xd8, 0x01, 0xf8, 0x00, 0x78, 0x00, 0xf8, 0x00,
+ 0xf8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar mcur_bdiag_bits[] = {
+ 0x00, 0x00, 0xc0, 0x7f, 0x80, 0x7f, 0x00, 0x7f, 0x00, 0x7e, 0x04, 0x7f,
+ 0x8c, 0x7f, 0xdc, 0x77, 0xfc, 0x63, 0xfc, 0x41, 0xfc, 0x00, 0xfc, 0x01,
+ 0xfc, 0x03, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar cur_fdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xf8, 0x00, 0x78, 0x00,
+ 0xf8, 0x00, 0xd8, 0x01, 0x88, 0x23, 0x00, 0x37, 0x00, 0x3e, 0x00, 0x3c,
+ 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar mcur_fdiag_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0xfc, 0x07, 0xfc, 0x03, 0xfc, 0x01, 0xfc, 0x00,
+ 0xfc, 0x41, 0xfc, 0x63, 0xdc, 0x77, 0x8c, 0x7f, 0x04, 0x7f, 0x00, 0x7e,
+ 0x00, 0x7f, 0x80, 0x7f, 0xc0, 0x7f, 0x00, 0x00 };
+ static const uchar *cursor_bits16[] = {
+ cur_ver_bits, mcur_ver_bits, cur_hor_bits, mcur_hor_bits,
+ cur_bdiag_bits, mcur_bdiag_bits, cur_fdiag_bits, mcur_fdiag_bits,
+ 0, 0, cur_blank_bits, cur_blank_bits };
+
+ static const uchar vsplit_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar vsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00, 0x80, 0xff, 0xff, 0x00,
+ 0x80, 0xff, 0xff, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00,
+ 0x00, 0xc0, 0x01, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x07, 0x00,
+ 0x00, 0xe0, 0x03, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar hsplit_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x41, 0x82, 0x00, 0x80, 0x41, 0x82, 0x01, 0xc0, 0x7f, 0xfe, 0x03,
+ 0x80, 0x41, 0x82, 0x01, 0x00, 0x41, 0x82, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00,
+ 0x00, 0x40, 0x02, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar hsplitm_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe3, 0xc7, 0x00,
+ 0x80, 0xe3, 0xc7, 0x01, 0xc0, 0xff, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x07,
+ 0xc0, 0xff, 0xff, 0x03, 0x80, 0xe3, 0xc7, 0x01, 0x00, 0xe3, 0xc7, 0x00,
+ 0x00, 0xe2, 0x47, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00,
+ 0x00, 0xe0, 0x07, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar whatsthis_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0xf0, 0x07, 0x00,
+ 0x09, 0x18, 0x0e, 0x00, 0x11, 0x1c, 0x0e, 0x00, 0x21, 0x1c, 0x0e, 0x00,
+ 0x41, 0x1c, 0x0e, 0x00, 0x81, 0x1c, 0x0e, 0x00, 0x01, 0x01, 0x07, 0x00,
+ 0x01, 0x82, 0x03, 0x00, 0xc1, 0xc7, 0x01, 0x00, 0x49, 0xc0, 0x01, 0x00,
+ 0x95, 0xc0, 0x01, 0x00, 0x93, 0xc0, 0x01, 0x00, 0x21, 0x01, 0x00, 0x00,
+ 0x20, 0xc1, 0x01, 0x00, 0x40, 0xc2, 0x01, 0x00, 0x40, 0x02, 0x00, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+ static const uchar whatsthism_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0xf0, 0x07, 0x00, 0x07, 0xf8, 0x0f, 0x00,
+ 0x0f, 0xfc, 0x1f, 0x00, 0x1f, 0x3e, 0x1f, 0x00, 0x3f, 0x3e, 0x1f, 0x00,
+ 0x7f, 0x3e, 0x1f, 0x00, 0xff, 0x3e, 0x1f, 0x00, 0xff, 0x9d, 0x0f, 0x00,
+ 0xff, 0xc3, 0x07, 0x00, 0xff, 0xe7, 0x03, 0x00, 0x7f, 0xe0, 0x03, 0x00,
+ 0xf7, 0xe0, 0x03, 0x00, 0xf3, 0xe0, 0x03, 0x00, 0xe1, 0xe1, 0x03, 0x00,
+ 0xe0, 0xe1, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00, 0xc0, 0xe3, 0x03, 0x00,
+ 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+ static const uchar busy_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
+ 0x09, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
+ 0x41, 0xe0, 0xff, 0x00, 0x81, 0x20, 0x80, 0x00, 0x01, 0xe1, 0xff, 0x00,
+ 0x01, 0x42, 0x40, 0x00, 0xc1, 0x47, 0x40, 0x00, 0x49, 0x40, 0x55, 0x00,
+ 0x95, 0x80, 0x2a, 0x00, 0x93, 0x00, 0x15, 0x00, 0x21, 0x01, 0x0a, 0x00,
+ 0x20, 0x01, 0x11, 0x00, 0x40, 0x82, 0x20, 0x00, 0x40, 0x42, 0x44, 0x00,
+ 0x80, 0x41, 0x4a, 0x00, 0x00, 0x40, 0x55, 0x00, 0x00, 0xe0, 0xff, 0x00,
+ 0x00, 0x20, 0x80, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ static const uchar busym_bits[] = {
+ 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
+ 0x0f, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00,
+ 0x7f, 0xe0, 0xff, 0x00, 0xff, 0xe0, 0xff, 0x00, 0xff, 0xe1, 0xff, 0x00,
+ 0xff, 0xc3, 0x7f, 0x00, 0xff, 0xc7, 0x7f, 0x00, 0x7f, 0xc0, 0x7f, 0x00,
+ 0xf7, 0x80, 0x3f, 0x00, 0xf3, 0x00, 0x1f, 0x00, 0xe1, 0x01, 0x0e, 0x00,
+ 0xe0, 0x01, 0x1f, 0x00, 0xc0, 0x83, 0x3f, 0x00, 0xc0, 0xc3, 0x7f, 0x00,
+ 0x80, 0xc1, 0x7f, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0xe0, 0xff, 0x00,
+ 0x00, 0xe0, 0xff, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ static const uchar * const cursor_bits32[] = {
+ vsplit_bits, vsplitm_bits, hsplit_bits, hsplitm_bits,
+ 0, 0, 0, 0, whatsthis_bits, whatsthism_bits, busy_bits, busym_bits
+ };
+
+ static const uchar forbidden_bits[] = {
+ 0x00,0x00,0x00,0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xf0,0x00,0x38,0xc0,0x01,
+ 0x7c,0x80,0x03,0xec,0x00,0x03,0xce,0x01,0x07,0x86,0x03,0x06,0x06,0x07,0x06,
+ 0x06,0x0e,0x06,0x06,0x1c,0x06,0x0e,0x38,0x07,0x0c,0x70,0x03,0x1c,0xe0,0x03,
+ 0x38,0xc0,0x01,0xf0,0xe0,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00,0x00,0x00,0x00 };
+
+ static const unsigned char forbiddenm_bits[] = {
+ 0x80,0x1f,0x00,0xe0,0x7f,0x00,0xf0,0xff,0x00,0xf8,0xff,0x01,0xfc,0xf0,0x03,
+ 0xfe,0xc0,0x07,0xfe,0x81,0x07,0xff,0x83,0x0f,0xcf,0x07,0x0f,0x8f,0x0f,0x0f,
+ 0x0f,0x1f,0x0f,0x0f,0x3e,0x0f,0x1f,0xfc,0x0f,0x1e,0xf8,0x07,0x3e,0xf0,0x07,
+ 0xfc,0xe0,0x03,0xf8,0xff,0x01,0xf0,0xff,0x00,0xe0,0x7f,0x00,0x80,0x1f,0x00};
+
+ static const uchar * const cursor_bits20[] = {
+ forbidden_bits, forbiddenm_bits
+ };
+
+ if ( d->ctqshape >= SizeVerCursor && d->ctqshape < SizeAllCursor ||
+ d->ctqshape == BlankCursor ) {
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ int i = (d->ctqshape - SizeVerCursor)*2;
+ d->pm = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits16[i],
+ 16, 16 );
+ d->pmm = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits16[i+1],
+ 16,16);
+ d->hcurs = XCreatePixmapCursor( dpy, d->pm, d->pmm, &fg, &bg, 8, 8 );
+ return;
+ }
+ if ( ( d->ctqshape >= SplitVCursor && d->ctqshape <= SplitHCursor ) ||
+ d->ctqshape == WhatsThisCursor || d->ctqshape == BusyCursor ) {
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ int i = (d->ctqshape - SplitVCursor)*2;
+ d->pm = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits32[i],
+ 32, 32 );
+ d->pmm = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits32[i+1],
+ 32, 32);
+ int hs = ( d->ctqshape == PointingHandCursor ||
+ d->ctqshape == WhatsThisCursor ||
+ d->ctqshape == BusyCursor ) ? 0 : 16;
+ d->hcurs = XCreatePixmapCursor( dpy, d->pm, d->pmm, &fg, &bg, hs, hs );
+ return;
+ }
+ if ( d->ctqshape == ForbiddenCursor ) {
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ int i = (d->ctqshape - ForbiddenCursor)*2;
+ d->pm = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits20[i],
+ 20, 20 );
+ d->pmm = XCreateBitmapFromData( dpy, rootwin, (char *)cursor_bits20[i+1],
+ 20, 20);
+ d->hcurs = XCreatePixmapCursor( dpy, d->pm, d->pmm, &fg, &bg, 10, 10 );
+ return;
+ }
+#endif /* ! TQT_USE_APPROXIMATE_CURSORS */
+
+ uint sh;
+ switch ( d->ctqshape ) { // map Q cursor to X cursor
+ case ArrowCursor:
+ sh = XC_left_ptr;
+ break;
+ case UpArrowCursor:
+ sh = XC_center_ptr;
+ break;
+ case CrossCursor:
+ sh = XC_crosshair;
+ break;
+ case WaitCursor:
+ sh = XC_watch;
+ break;
+ case IbeamCursor:
+ sh = XC_xterm;
+ break;
+ case SizeAllCursor:
+ sh = XC_fleur;
+ break;
+ case PointingHandCursor:
+ sh = XC_hand2;
+ break;
+#ifdef TQT_USE_APPROXIMATE_CURSORS
+ case SizeBDiagCursor:
+ sh = XC_top_right_corner;
+ break;
+ case SizeFDiagCursor:
+ sh = XC_bottom_right_corner;
+ break;
+ case BlankCursor:
+ XColor bg, fg;
+ bg.red = 255 << 8;
+ bg.green = 255 << 8;
+ bg.blue = 255 << 8;
+ fg.red = 0;
+ fg.green = 0;
+ fg.blue = 0;
+ d->pm = XCreateBitmapFromData( dpy, rootwin,
+ (char *)cur_blank_bits, 16, 16 );
+ d->pmm = XCreateBitmapFromData( dpy, rootwin,
+ (char *)cur_blank_bits, 16,16);
+ d->hcurs = XCreatePixmapCursor( dpy, d->pm, d->pmm, &fg,
+ &bg, 8, 8 );
+ return;
+ break;
+ case SizeVerCursor:
+ case SplitVCursor:
+ sh = XC_sb_v_double_arrow;
+ break;
+ case SizeHorCursor:
+ case SplitHCursor:
+ sh = XC_sb_h_double_arrow;
+ break;
+ case WhatsThisCursor:
+ sh = XC_question_arrow;
+ break;
+ case ForbiddenCursor:
+ sh = XC_circle;
+ break;
+ case BusyCursor:
+ sh = XC_watch;
+ break;
+#endif /* TQT_USE_APPROXIMATE_CURSORS */
+ default:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQCursor::update: Invalid cursor tqshape %d", d->ctqshape );
+#endif
+ return;
+ }
+ d->hcurs = XCreateFontCursor( dpy, sh );
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqdesktopwidget.h b/tqtinterface/qt4/src/kernel/tqdesktopwidget.h
new file mode 100644
index 0000000..d91a189
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqdesktopwidget.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Definition of TQDesktopWidget class.
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDESKTOPWIDGET_H
+#define TQDESKTOPWIDGET_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qdesktopwidget.h>
+
+#endif // USE_QT4
+
+class TQApplication;
+class TQDesktopWidgetPrivate; /* Don't touch! */
+
+#ifdef TQT_THREAD_SUPPORT
+class TQMutex;
+#endif // TQT_THREAD_SUPPORT
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQDesktopWidget : public QDesktopWidget, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQDesktopWidget( void ) : QDesktopWidget() {
+ TQT_TQWIDGET_INDEPENDENT_REQUIRED_INITIALIZATION
+ TQT_TQOBJECT_REQUIRED_INITIALIZATION()
+ }
+
+ inline const TQRect tqgeometry() const { return TQT_TQRECT_OBJECT(geometry()); }
+
+ Display * x11Display( void ) { return this->x11Info().display(); }
+ int x11Screen( void ) { return this->x11Info().screen(); }
+
+public Q_SLOTS:
+ void tqt_handle_qt_destroyed(QObject* obj) { emit destroyed(TQT_TQOBJECT(obj)); }
+
+Q_SIGNALS:
+ void destroyed( TQObject* obj );
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQDesktopWidget : public TQWidget
+{
+ TQ_OBJECT
+public:
+ TQDesktopWidget();
+ ~TQDesktopWidget();
+
+ bool isVirtualDesktop() const;
+
+ int numScreens() const;
+ int primaryScreen() const;
+
+ int screenNumber( TQWidget *widget = 0 ) const; // ### 4.0: const TQWidget*
+ int screenNumber( const TQPoint & ) const;
+
+ TQWidget *screen( int screen = -1 );
+
+ const TQRect& screenGeometry( int screen = -1 ) const;
+ const TQRect& screenGeometry( TQWidget *widget ) const
+ { return screenGeometry( screenNumber( widget ) ); }
+ const TQRect& screenGeometry( const TQPoint &point ) const
+ { return screenGeometry( screenNumber( point ) ); }
+
+ const TQRect& availableGeometry( int screen = -1 ) const;
+ const TQRect& availableGeometry( TQWidget *widget ) const
+ { return availableGeometry( screenNumber( widget ) ); }
+ const TQRect& availableGeometry( const TQPoint &point ) const
+ { return availableGeometry( screenNumber( point ) ); }
+
+ void insertChild( TQObject * );
+
+Q_SIGNALS:
+ void resized( int );
+ void workAreaResized( int );
+
+protected:
+ void resizeEvent( TQResizeEvent *e );
+
+private:
+ TQDesktopWidgetPrivate *d;
+
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQDesktopWidget( const TQDesktopWidget & );
+ TQDesktopWidget &operator=( const TQDesktopWidget & );
+#endif
+
+ friend class TQApplication;
+#ifdef TQ_WS_TQWS
+ friend class TQWSDisplay;
+#endif
+};
+
+#endif // USE_QT4
+
+#endif //TQDESKTOPWIDGET_H
diff --git a/tqtinterface/qt4/src/kernel/tqdesktopwidget_x11.cpp b/tqtinterface/qt4/src/kernel/tqdesktopwidget_x11.cpp
new file mode 100644
index 0000000..e2bd9f9
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqdesktopwidget_x11.cpp
@@ -0,0 +1,335 @@
+/****************************************************************************
+**
+** Implementation of TQDesktopWidget class.
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdesktopwidget.h"
+#include "tqapplication.h"
+#include "tqobjectlist.h"
+#include "tqt_x11_p.h"
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+// defined in qwidget_x11.cpp
+extern int qt_x11_create_desktop_on_screen;
+
+// defined in qapplication_x11.cpp
+extern Atom qt_net_workarea;
+extern bool qt_net_supports(Atom atom);
+
+// function to update the workarea of the screen
+static bool qt_desktopwidget_workarea_dirty = TRUE;
+void qt_desktopwidget_update_workarea()
+{
+ qt_desktopwidget_workarea_dirty = TRUE;
+}
+
+
+class TQSingleDesktopWidget : public TQWidget
+{
+public:
+ TQSingleDesktopWidget();
+ ~TQSingleDesktopWidget();
+};
+
+TQSingleDesktopWidget::TQSingleDesktopWidget()
+ : TQWidget( 0, "desktop", WType_Desktop )
+{
+}
+
+TQSingleDesktopWidget::~TQSingleDesktopWidget()
+{
+ while ( !childrenListObject().isEmpty() )
+ removeChild( childrenListObject().getFirst() );
+}
+
+
+class TQDesktopWidgetPrivate
+{
+public:
+ TQDesktopWidgetPrivate();
+ ~TQDesktopWidgetPrivate();
+
+ void init();
+
+ bool use_xinerama;
+ int defaultScreen;
+ int screenCount;
+
+ TQWidget **screens;
+ TQRect *rects;
+ TQRect *workareas;
+};
+
+TQDesktopWidgetPrivate::TQDesktopWidgetPrivate()
+ : use_xinerama(FALSE), defaultScreen(0), screenCount(1),
+ screens( 0 ), rects( 0 ), workareas( 0 )
+{
+}
+
+TQDesktopWidgetPrivate::~TQDesktopWidgetPrivate()
+{
+ if ( screens ) {
+ for ( int i = 0; i < screenCount; ++i ) {
+ if (i == defaultScreen) continue;
+ delete screens[i];
+ screens[i] = 0;
+ }
+
+ delete [] screens;
+ }
+
+ if ( rects ) delete [] rects;
+ if ( workareas ) delete [] workareas;
+}
+
+void TQDesktopWidgetPrivate::init()
+{
+ // get the screen count
+#ifndef TQT_NO_XINERAMA
+ XineramaScreenInfo *xinerama_screeninfo = 0;
+ int unused;
+ use_xinerama = (XineramaQueryExtension(TQPaintDevice::x11AppDisplay(),
+ &unused, &unused) &&
+ XineramaIsActive(TQPaintDevice::x11AppDisplay()));
+
+ if (use_xinerama) {
+ xinerama_screeninfo =
+ XineramaQueryScreens(TQPaintDevice::x11AppDisplay(), &screenCount);
+ defaultScreen = 0;
+ } else
+#endif // TQT_NO_XINERAMA
+ {
+ defaultScreen = DefaultScreen(TQPaintDevice::x11AppDisplay());
+ screenCount = ScreenCount(TQPaintDevice::x11AppDisplay());
+ }
+
+ delete [] rects;
+ rects = new TQRect[ screenCount ];
+ delete [] workareas;
+ workareas = new TQRect[ screenCount ];
+
+ // get the tqgeometry of each screen
+ int i, x, y, w, h;
+ for ( i = 0; i < screenCount; i++ ) {
+
+#ifndef TQT_NO_XINERAMA
+ if (use_xinerama) {
+ x = xinerama_screeninfo[i].x_org;
+ y = xinerama_screeninfo[i].y_org;
+ w = xinerama_screeninfo[i].width;
+ h = xinerama_screeninfo[i].height;
+ } else
+#endif // TQT_NO_XINERAMA
+ {
+ x = 0;
+ y = 0;
+ w = WidthOfScreen(ScreenOfDisplay(TQPaintDevice::x11AppDisplay(), i));
+ h = HeightOfScreen(ScreenOfDisplay(TQPaintDevice::x11AppDisplay(), i));
+ }
+
+ rects[i].setRect(x, y, w, h);
+ workareas[i] = TQRect();
+ }
+
+#ifndef TQT_NO_XINERAMA
+ if (xinerama_screeninfo)
+ XFree(xinerama_screeninfo);
+#endif // TQT_NO_XINERAMA
+
+}
+
+// the TQDesktopWidget itself will be created on the default screen
+// as qt_x11_create_desktop_on_screen defaults to -1
+TQDesktopWidget::TQDesktopWidget()
+ : TQWidget( 0, "desktop", WType_Desktop )
+{
+ d = new TQDesktopWidgetPrivate();
+
+ /*
+ we don't call d->init() here, since the initial resize event
+ will end up calling init() a second time, which is inefficient.
+ instead, for the sending of all posted event to the desktop
+ widget (including the initial resize event, which calls
+ d->init()).
+ */
+ TQApplication::sendPostedEvents( this, 0 );
+}
+
+TQDesktopWidget::~TQDesktopWidget()
+{
+ delete d;
+}
+
+bool TQDesktopWidget::isVirtualDesktop() const
+{
+ return d->use_xinerama;
+}
+
+int TQDesktopWidget::primaryScreen() const
+{
+ return d->defaultScreen;
+}
+
+int TQDesktopWidget::numScreens() const
+{
+ return d->screenCount;
+}
+
+TQWidget *TQDesktopWidget::screen( int screen )
+{
+ if (d->use_xinerama)
+ return this;
+
+ if ( screen < 0 || screen >= d->screenCount )
+ screen = d->defaultScreen;
+
+ if ( ! d->screens ) {
+ d->screens = new TQWidget*[ d->screenCount ];
+ memset( d->screens, 0, d->screenCount * sizeof( TQWidget * ) );
+ d->screens[ d->defaultScreen ] = this;
+ }
+
+ if ( ! d->screens[screen] || // not created yet
+ ! d->screens[screen]->isDesktop() ) { // reparented away
+ qt_x11_create_desktop_on_screen = screen;
+ d->screens[screen] = new TQSingleDesktopWidget;
+ qt_x11_create_desktop_on_screen = -1;
+ }
+
+ return d->screens[screen];
+}
+
+const TQRect& TQDesktopWidget::availableGeometry( int screen ) const
+{
+ if ( qt_desktopwidget_workarea_dirty ) {
+ // the workareas are dirty, tqinvalidate them
+ for ( int i = 0; i < d->screenCount; ++i )
+ d->workareas[i] = TQRect();
+ qt_desktopwidget_workarea_dirty = FALSE;
+ }
+
+ if ( screen < 0 || screen >= d->screenCount )
+ screen = d->defaultScreen;
+
+ if ( d->workareas[screen].isValid() )
+ return d->workareas[screen];
+
+ if ( ! isVirtualDesktop() && qt_net_supports( qt_net_workarea ) ) {
+ Atom ret;
+ int format, e;
+ unsigned char *data = 0;
+ unsigned long nitems, after;
+
+ e = XGetWindowProperty( TQPaintDevice::x11AppDisplay(),
+ TQPaintDevice::x11AppRootWindow( screen ),
+ qt_net_workarea, 0, 4, False, XA_CARDINAL,
+ &ret, &format, &nitems, &after, &data );
+
+ if (e == Success && ret == XA_CARDINAL &&
+ format == 32 && nitems == 4) {
+ long *workarea = (long *) data;
+ d->workareas[screen].setRect( workarea[0], workarea[1],
+ workarea[2], workarea[3] );
+ } else {
+ d->workareas[screen] = screenGeometry(screen);
+ }
+ if ( data )
+ XFree( data );
+ } else {
+ d->workareas[screen] = screenGeometry(screen);
+ }
+
+ return d->workareas[screen];
+}
+
+const TQRect& TQDesktopWidget::screenGeometry( int screen ) const
+{
+ if ( screen < 0 || screen >= d->screenCount )
+ screen = d->defaultScreen;
+
+ return d->rects[ screen ];
+}
+
+int TQDesktopWidget::screenNumber( TQWidget *widget ) const
+{
+ if ( !widget )
+ return d->defaultScreen;
+
+#ifndef TQT_NO_XINERAMA
+ if (d->use_xinerama) {
+ // this is how we do it for xinerama
+ TQRect frame = widget->frameGeometry();
+ if ( !widget->isTopLevel() )
+ frame.moveTopLeft( widget->mapToGlobal( TQPoint( 0, 0 ) ) );
+
+ int maxSize = -1;
+ int maxScreen = -1;
+
+ for ( int i = 0; i < d->screenCount; ++i ) {
+ TQRect sect = d->rects[i].intersect( frame );
+ int size = sect.width() * sect.height();
+ if ( size > maxSize && sect.width() > 0 && sect.height() > 0 ) {
+ maxSize = size;
+ maxScreen = i;
+ }
+ }
+ return maxScreen;
+ }
+#endif // TQT_NO_XINERAMA
+
+ return widget->x11Screen();
+}
+
+int TQDesktopWidget::screenNumber( const TQPoint &point ) const
+{
+ for ( int i = 0; i < d->screenCount; ++i ) {
+ if ( d->rects[i].tqcontains( point ) )
+ return i;
+ }
+ return -1;
+}
+
+void TQDesktopWidget::resizeEvent( TQResizeEvent *event )
+{
+ d->init();
+ qt_desktopwidget_workarea_dirty = TRUE;
+ TQWidget::resizeEvent( event );
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqdnd_x11.cpp b/tqtinterface/qt4/src/kernel/tqdnd_x11.cpp
new file mode 100644
index 0000000..7882349
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqdnd_x11.cpp
@@ -0,0 +1,1765 @@
+/****************************************************************************
+**
+** XDND implementation for TQt. See http://www.cco.caltech.edu/~jafl/xdnd/
+**
+** Created : 980320
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+#include "tqapplication.h"
+
+#ifndef TQT_NO_DRAGANDDROP
+
+#include "tqwidget.h"
+#include "tqintdict.h"
+#include "tqdatetime.h"
+#include "tqdict.h"
+#include "tqguardedptr.h"
+#include "tqdragobject.h"
+#include "tqobjectlist.h"
+#include "tqcursor.h"
+
+#include "tqt_x11_p.h"
+
+// conflict resolution
+
+// unused, may be used again later: const int XKeyPress = KeyPress;
+// unused, may be used again later: const int XKeyRelease = KeyRelease;
+#undef KeyPress
+#undef KeyRelease
+
+// this stuff is copied from qapp_x11.cpp
+
+extern void qt_x11_intern_atom( const char *, Atom * );
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+extern void qt_ignore_badwindow();
+extern bool qt_badwindow();
+extern void qt_enter_modal( TQWidget *widget );
+extern void qt_leave_modal( TQWidget *widget );
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+extern Window qt_x11_tqfindClientWindow( Window, Atom, bool );
+extern Atom qt_wm_state;
+
+// this stuff is copied from qclb_x11.cpp
+
+extern bool qt_xclb_wait_for_event( Display *dpy, Window win, int type,
+ XEvent *event, int timeout );
+extern bool qt_xclb_read_property( Display *dpy, Window win, Atom property,
+ bool deleteProperty,
+ TQByteArray *buffer, int *size, Atom *type,
+ int *format, bool nullterm );
+extern TQByteArray qt_xclb_read_incremental_property( Display *dpy, Window win,
+ Atom property,
+ int nbytes, bool nullterm );
+// and all this stuff is copied -into- qapp_x11.cpp
+
+void qt_xdnd_setup();
+void qt_handle_xdnd_enter( TQWidget *, const XEvent *, bool );
+void qt_handle_xdnd_position( TQWidget *, const XEvent *, bool );
+void qt_handle_xdnd_status( TQWidget *, const XEvent *, bool );
+void qt_handle_xdnd_leave( TQWidget *, const XEvent *, bool );
+void qt_handle_xdnd_drop( TQWidget *, const XEvent *, bool );
+void qt_handle_xdnd_finished( TQWidget *, const XEvent *, bool );
+void qt_xdnd_handle_selection_request( const XSelectionRequestEvent * );
+bool qt_xdnd_handle_badwindow();
+// client messages
+Atom qt_xdnd_enter;
+Atom qt_xdnd_position;
+Atom qt_xdnd_status;
+Atom qt_xdnd_leave;
+Atom qt_xdnd_drop;
+Atom qt_xdnd_finished;
+Atom qt_xdnd_type_list;
+const int qt_xdnd_version = 4;
+
+// Actions
+//
+// The Xdnd spec allows for user-defined actions. This could be implemented
+// with a registration process in TQt. WE SHOULD do that later.
+//
+Atom qt_xdnd_action_copy;
+Atom qt_xdnd_action_link;
+Atom qt_xdnd_action_move;
+Atom qt_xdnd_action_private;
+static
+TQDropEvent::Action xdndaction_to_qtaction(Atom atom)
+{
+ if ( atom == qt_xdnd_action_copy || atom == 0 )
+ return TQDropEvent::Copy;
+ if ( atom == qt_xdnd_action_link )
+ return TQDropEvent::Link;
+ if ( atom == qt_xdnd_action_move )
+ return TQDropEvent::Move;
+ return TQDropEvent::Private;
+}
+static
+int qtaction_to_xdndaction(TQDropEvent::Action a)
+{
+ switch ( a ) {
+ case TQDropEvent::Copy:
+ return qt_xdnd_action_copy;
+ case TQDropEvent::Link:
+ return qt_xdnd_action_link;
+ case TQDropEvent::Move:
+ return qt_xdnd_action_move;
+ case TQDropEvent::Private:
+ return qt_xdnd_action_private;
+ default:
+ return qt_xdnd_action_copy;
+ }
+}
+
+// clean up the stuff used.
+static void qt_xdnd_cleanup();
+
+static void qt_xdnd_send_leave();
+
+// XDND selection
+Atom qt_xdnd_selection;
+// other selection
+static Atom qt_selection_property;
+// INCR
+static Atom qt_incr_atom;
+
+// properties for XDND drop sites
+Atom qt_xdnd_aware;
+Atom qt_xdnd_proxy;
+
+// real variables:
+// xid of current drag source
+static Atom qt_xdnd_dragsource_xid = 0;
+
+// the types in this drop. 100 is no good, but at least it's big.
+const int qt_xdnd_max_type = 100;
+static Atom qt_xdnd_types[qt_xdnd_max_type];
+
+static TQIntDict<TQCString> * qt_xdnd_drag_types = 0;
+static TQDict<Atom> * qt_xdnd_atom_numbers = 0;
+
+// timer used when target wants "continuous" move messages (eg. scroll)
+static int heartbeat = -1;
+// rectangle in which the answer will be the same
+static TQRect qt_xdnd_source_sameanswer;
+//static TQRect qt_xdnd_target_sameanswer;
+static bool qt_xdnd_target_answerwas;
+// top-level window we sent position to last.
+static Window qt_xdnd_current_target;
+// window to send events to (always valid if qt_xdnd_current_target)
+static Window qt_xdnd_current_proxy_target;
+// widget we forwarded position to last, and local position
+static TQGuardedPtr<TQWidget> qt_xdnd_current_widget;
+static TQPoint qt_xdnd_current_position;
+// time of this drop, as type Atom to save on casts
+static Atom qt_xdnd_source_current_time;
+// timestamp from the XdndPosition and XdndDrop
+static Time qt_xdnd_target_current_time;
+// screen number containing the pointer... -1 means default
+static int qt_xdnd_current_screen = -1;
+// state of dragging... true if dragging, false if not
+bool qt_xdnd_dragging = FALSE;
+
+// dict of payload data, sorted by type atom
+static TQIntDict<TQByteArray> * qt_xdnd_target_data = 0;
+
+// first drag object, or 0
+static TQDragObject * qt_xdnd_source_object = 0;
+
+// Motif dnd
+extern void qt_motifdnd_enable( TQWidget *, bool );
+extern TQByteArray qt_motifdnd_obtain_data( const char *format );
+extern const char *qt_motifdnd_format( int n );
+
+bool qt_motifdnd_active = FALSE;
+static bool dndCancelled = FALSE;
+
+// Shift/Ctrl handling, and final drop status
+static TQDragObject::DragMode drag_mode;
+static TQDropEvent::Action global_requested_action = TQDropEvent::Copy;
+static TQDropEvent::Action global_accepted_action = TQDropEvent::Copy;
+
+// for embedding only
+static TQWidget* current_embedding_widget = 0;
+static XEvent last_enter_event;
+
+// cursors
+static TQCursor *noDropCursor = 0;
+static TQCursor *moveCursor = 0;
+static TQCursor *copyCursor = 0;
+static TQCursor *linkCursor = 0;
+
+static TQPixmap *defaultPm = 0;
+
+static const int default_pm_hotx = -2;
+static const int default_pm_hoty = -16;
+static const char* const default_pm[] = {
+"13 9 3 1",
+". c None",
+" c #000000",
+"X c #FFFFFF",
+"X X X X X X X",
+" X X X X X X ",
+"X ......... X",
+" X.........X ",
+"X ......... X",
+" X.........X ",
+"X ......... X",
+" X X X X X X ",
+"X X X X X X X"
+};
+
+#define WStyle_Tool Qt::Tool
+#define WStyle_NoBorder Qt::FramelessWindowHint
+
+class TQShapedPixmapWidget : public TQWidget {
+
+public:
+ TQShapedPixmapWidget(int screen = -1) :
+ TQWidget(TQApplication::desktop()->screen( screen ),
+ 0, (Qt::WindowType)(WStyle_Customize | WStyle_Tool | WStyle_NoBorder | WX11BypassWM) )
+ {
+ }
+
+ void setPixmap(TQPixmap pm)
+ {
+ const TQBitmap* mask = pm.tqmask();
+ if ( mask ) {
+ setMask( *mask );
+ } else {
+ clearMask();
+ }
+ resize(pm.width(),pm.height());
+ setErasePixmap(pm);
+ }
+};
+
+static TQShapedPixmapWidget * qt_xdnd_deco = 0;
+
+static TQWidget* desktop_proxy = 0;
+
+class TQExtraWidget : public TQWidget
+{
+public:
+ TQWExtra* extraData() { return TQWidget::extraData(); }
+ TQTLWExtra* topData() { return TQWidget::topData(); }
+};
+
+
+static bool qt_xdnd_enable( TQWidget* w, bool on )
+{
+ if ( on ) {
+ TQWidget * xdnd_widget = 0;
+ if ( w->isDesktop() ) {
+ if ( desktop_proxy ) // *WE* already have one.
+ return FALSE;
+
+ // As per Xdnd4, use XdndProxy
+ XGrabServer( w->x11Display() );
+ Atom type = None;
+ int f;
+ unsigned long n, a;
+ WId *proxy_id_ptr;
+ XGetWindowProperty( w->x11Display(), w->winId(),
+ qt_xdnd_proxy, 0, 1, False,
+ XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id_ptr );
+ WId proxy_id = 0;
+ if ( type == XA_WINDOW && proxy_id_ptr ) {
+ proxy_id = *proxy_id_ptr;
+ XFree(proxy_id_ptr);
+ proxy_id_ptr = 0;
+ // Already exists. Real?
+ qt_ignore_badwindow();
+ XGetWindowProperty( w->x11Display(), proxy_id,
+ qt_xdnd_proxy, 0, 1, False,
+ XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id_ptr );
+ if ( qt_badwindow() || type != XA_WINDOW || !proxy_id_ptr || *proxy_id_ptr != proxy_id ) {
+ // Bogus - we will overwrite.
+ proxy_id = 0;
+ }
+ }
+ if ( proxy_id_ptr )
+ XFree(proxy_id_ptr);
+
+ if ( !proxy_id ) {
+ xdnd_widget = desktop_proxy = new TQWidget;
+ proxy_id = desktop_proxy->winId();
+ XChangeProperty ( w->x11Display(),
+ w->winId(), qt_xdnd_proxy,
+ XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)&proxy_id, 1 );
+ XChangeProperty ( w->x11Display(),
+ proxy_id, qt_xdnd_proxy,
+ XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)&proxy_id, 1 );
+ }
+
+ XUngrabServer( w->x11Display() );
+ } else {
+ xdnd_widget = w->tqtopLevelWidget();
+ }
+ if ( xdnd_widget ) {
+ Atom atm = (Atom)qt_xdnd_version;
+ XChangeProperty ( xdnd_widget->x11Display(), xdnd_widget->winId(),
+ qt_xdnd_aware, XA_ATOM, 32, PropModeReplace,
+ (unsigned char *)&atm, 1 );
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else {
+ if ( w->isDesktop() ) {
+ XDeleteProperty( w->x11Display(), w->winId(),
+ qt_xdnd_proxy );
+ delete desktop_proxy;
+ desktop_proxy = 0;
+ }
+ return TRUE;
+ }
+}
+
+const char* qt_xdnd_atom_to_str( Atom a )
+{
+ if ( !a ) return 0;
+
+ if ( a == XA_STRING )
+ return "text/plain"; // some Xdnd clients are dumb
+
+ if ( !qt_xdnd_drag_types ) {
+ qt_xdnd_drag_types = new TQIntDict<TQCString>( 17 );
+ qt_xdnd_drag_types->setAutoDelete( TRUE );
+ }
+ TQCString* result;
+ if ( !(result=qt_xdnd_drag_types->tqfind( a )) ) {
+ const char* mimeType = XGetAtomName( TQPaintDevice::x11AppDisplay(), a );
+ if ( !mimeType )
+ return 0; // only happens on protocol error
+ result = new TQCString( mimeType );
+ qt_xdnd_drag_types->insert( (long)a, result );
+ XFree((void*)mimeType);
+ }
+ return *result;
+}
+
+Atom* qt_xdnd_str_to_atom( const char *mimeType )
+{
+ if ( !mimeType || !*mimeType )
+ return 0;
+ if ( !qt_xdnd_atom_numbers ) {
+ qt_xdnd_atom_numbers = new TQDict<Atom>( 17 );
+ qt_xdnd_atom_numbers->setAutoDelete( TRUE );
+ }
+
+ Atom * result;
+ if ( (result = qt_xdnd_atom_numbers->tqfind( mimeType )) )
+ return result;
+
+ result = new Atom;
+ *result = 0;
+ qt_x11_intern_atom( mimeType, result );
+ qt_xdnd_atom_numbers->insert( mimeType, result );
+ qt_xdnd_atom_to_str( *result );
+
+ return result;
+}
+
+
+void qt_xdnd_setup() {
+ // set up protocol atoms
+ qt_x11_intern_atom( "XdndEnter", &qt_xdnd_enter );
+ qt_x11_intern_atom( "XdndPosition", &qt_xdnd_position );
+ qt_x11_intern_atom( "XdndtqStatus", &qt_xdnd_status );
+ qt_x11_intern_atom( "XdndLeave", &qt_xdnd_leave );
+ qt_x11_intern_atom( "XdndDrop", &qt_xdnd_drop );
+ qt_x11_intern_atom( "XdndFinished", &qt_xdnd_finished );
+ qt_x11_intern_atom( "XdndTypeList", &qt_xdnd_type_list );
+
+ qt_x11_intern_atom( "XdndSelection", &qt_xdnd_selection );
+
+ qt_x11_intern_atom( "XdndAware", &qt_xdnd_aware );
+ qt_x11_intern_atom( "XdndProxy", &qt_xdnd_proxy );
+
+
+ qt_x11_intern_atom( "XdndActionCopy", &qt_xdnd_action_copy );
+ qt_x11_intern_atom( "XdndActionLink", &qt_xdnd_action_link );
+ qt_x11_intern_atom( "XdndActionMove", &qt_xdnd_action_move );
+ qt_x11_intern_atom( "XdndActionPrivate", &qt_xdnd_action_private );
+
+ qt_x11_intern_atom( "TQT_SELECTION", &qt_selection_property );
+ qt_x11_intern_atom( "INCR", &qt_incr_atom );
+
+ qAddPostRoutine( qt_xdnd_cleanup );
+}
+
+
+void qt_xdnd_cleanup()
+{
+ delete qt_xdnd_drag_types;
+ qt_xdnd_drag_types = 0;
+ delete qt_xdnd_atom_numbers;
+ qt_xdnd_atom_numbers = 0;
+ delete qt_xdnd_target_data;
+ qt_xdnd_target_data = 0;
+ delete noDropCursor;
+ noDropCursor = 0;
+ delete copyCursor;
+ copyCursor = 0;
+ delete moveCursor;
+ moveCursor = 0;
+ delete linkCursor;
+ linkCursor = 0;
+ delete defaultPm;
+ defaultPm = 0;
+ delete desktop_proxy;
+ desktop_proxy = 0;
+}
+
+
+static TQWidget * tqfind_child( TQWidget * tlw, TQPoint & p )
+{
+ TQWidget * w = tlw;
+
+ p = w->mapFromGlobal( p );
+ bool done = FALSE;
+ while ( !done ) {
+ done = TRUE;
+ if ( ((TQExtraWidget*)w)->extraData() &&
+ ((TQExtraWidget*)w)->extraData()->xDndProxy != 0 )
+ break; // stop searching for widgets under the mouse cursor if found widget is a proxy.
+ if ( !w->childrenListObject().isEmpty() ) {
+ TQObjectListIt it( w->childrenListObject() );
+ it.toLast();
+ TQObject * o;
+ while( (o=it.current()) ) {
+ --it;
+ if ( o->isWidgetType() &&
+ ((TQWidget*)o)->isVisible() &&
+ ((TQWidget*)o)->tqgeometry().contains( p ) &&
+ !((TQWidget*)o)->isTopLevel()) {
+ w = (TQWidget *)o;
+ done = FALSE;
+ p = w->mapFromParent( p );
+ break;
+ }
+ }
+ }
+ }
+ return w;
+}
+
+
+static bool checkEmbedded(TQWidget* w, const XEvent* xe)
+{
+ if (!w)
+ return FALSE;
+
+ if (current_embedding_widget != 0 && current_embedding_widget != w) {
+ qt_xdnd_current_target = ((TQExtraWidget*)current_embedding_widget)->extraData()->xDndProxy;
+ qt_xdnd_current_proxy_target = qt_xdnd_current_target;
+ qt_xdnd_send_leave();
+ qt_xdnd_current_target = 0;
+ qt_xdnd_current_proxy_target = 0;
+ current_embedding_widget = 0;
+ }
+
+ TQWExtra* extra = ((TQExtraWidget*)w)->extraData();
+ if ( extra && extra->xDndProxy != 0 ) {
+
+ if (current_embedding_widget != w) {
+
+ last_enter_event.xany.window = extra->xDndProxy;
+ XSendEvent( TQPaintDevice::x11AppDisplay(), extra->xDndProxy, False, NoEventMask,
+ &last_enter_event );
+ current_embedding_widget = w;
+ }
+
+ ((XEvent*)xe)->xany.window = extra->xDndProxy;
+ XSendEvent( TQPaintDevice::x11AppDisplay(), extra->xDndProxy, False, NoEventMask,
+ (XEvent*)xe );
+ qt_xdnd_current_widget = w;
+ return TRUE;
+ }
+ current_embedding_widget = 0;
+ return FALSE;
+}
+
+void qt_handle_xdnd_enter( TQWidget *, const XEvent * xe, bool /*passive*/ )
+{
+ //if ( !w->neveHadAChildWithDropEventsOn() )
+ //return; // haven't been set up for dnd
+
+ qt_motifdnd_active = FALSE;
+
+ last_enter_event.xclient = xe->xclient;
+
+ qt_xdnd_target_answerwas = FALSE;
+
+ const long *l = xe->xclient.data.l;
+ int version = (int)(((unsigned long)(l[1])) >> 24);
+
+ if ( version > qt_xdnd_version )
+ return;
+
+ qt_xdnd_dragsource_xid = l[0];
+
+ int j = 0;
+ if ( l[1] & 1 ) {
+ // get the types from XdndTypeList
+ Atom type = None;
+ int f;
+ unsigned long n, a;
+ Atom *data;
+ XGetWindowProperty( TQPaintDevice::x11AppDisplay(), qt_xdnd_dragsource_xid,
+ qt_xdnd_type_list, 0,
+ qt_xdnd_max_type, False, XA_ATOM, &type, &f,&n,&a,(uchar**)&data );
+ for ( ; j<qt_xdnd_max_type && j < (int)n; j++ ) {
+ qt_xdnd_types[j] = data[j];
+ }
+ if ( data )
+ XFree( (uchar*)data );
+ } else {
+ // get the types from the message
+ int i;
+ for( i=2; i < 5; i++ ) {
+ qt_xdnd_types[j++] = l[i];
+ }
+ }
+ qt_xdnd_types[j] = 0;
+}
+
+
+
+void qt_handle_xdnd_position( TQWidget *w, const XEvent * xe, bool passive )
+{
+ const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
+
+ TQPoint p( (l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff );
+ TQWidget * c = tqfind_child( w, p ); // changes p to to c-local coordinates
+
+ if (!passive && checkEmbedded(c, xe))
+ return;
+
+ if ( !c || (!c->acceptDrops() && c->isDesktop()) ) {
+ return;
+ }
+
+ if ( l[0] != qt_xdnd_dragsource_xid ) {
+ //qDebug( "xdnd drag position from unexpected source (%08lx not %08lx)",
+ // l[0], qt_xdnd_dragsource_xid );
+ return;
+ }
+
+ if (l[3] != 0) {
+ // timestamp from the source
+ SET_QT_X_USER_TIME(l[3]);
+ qt_xdnd_target_current_time = l[3];
+ }
+
+ XClientMessageEvent response;
+ response.type = ClientMessage;
+ response.window = qt_xdnd_dragsource_xid;
+ response.format = 32;
+ response.message_type = qt_xdnd_status;
+ response.data.l[0] = w->winId();
+ response.data.l[1] = 0; // flags
+ response.data.l[2] = 0; // x, y
+ response.data.l[3] = 0; // w, h
+ response.data.l[4] = 0; // action
+
+ if ( !passive ) { // otherwise just reject
+ while ( c && !c->acceptDrops() && !c->isTopLevel() ) {
+ p = c->mapToParent( p );
+ c = c->parentWidget();
+ }
+
+ TQRect answerRect( c->mapToGlobal( p ), TQSize( 1,1 ) );
+
+ TQDragMoveEvent me( p );
+ TQDropEvent::Action accepted_action = xdndaction_to_qtaction(l[4]);
+ me.setAction(accepted_action);
+
+ if ( c != qt_xdnd_current_widget ) {
+ qt_xdnd_target_answerwas = FALSE;
+ if ( qt_xdnd_current_widget ) {
+ TQDragLeaveEvent e;
+ TQApplication::sendEvent( qt_xdnd_current_widget, &e );
+ }
+ if ( c->acceptDrops() ) {
+ qt_xdnd_current_widget = c;
+ qt_xdnd_current_position = p;
+
+ TQDragEnterEvent de( p );
+ de.setAction(accepted_action);
+ TQApplication::sendEvent( c, &de );
+ if ( de.isAccepted() ) {
+ me.accept( de.answerRect() );
+ if ( !de.isActionAccepted() ) // only as a copy (move if we del)
+ accepted_action = TQDropEvent::Copy;
+ else
+ me.acceptAction(TRUE);
+ } else {
+ me.ignore( de.answerRect() );
+ }
+ }
+ } else {
+ if ( qt_xdnd_target_answerwas ) {
+ me.accept();
+ me.acceptAction(global_requested_action == global_accepted_action);
+ }
+ }
+
+ if ( !c->acceptDrops() ) {
+ qt_xdnd_current_widget = 0;
+ answerRect = TQRect( p, TQSize( 1, 1 ) );
+ } else if ( xdndaction_to_qtaction(l[4]) < TQDropEvent::Private ) {
+ qt_xdnd_current_widget = c;
+ qt_xdnd_current_position = p;
+
+ TQApplication::sendEvent( c, &me );
+ qt_xdnd_target_answerwas = me.isAccepted();
+ if ( me.isAccepted() ) {
+ response.data.l[1] = 1; // yes
+ if ( !me.isActionAccepted() ) // only as a copy (move if we del)
+ accepted_action = TQDropEvent::Copy;
+ } else {
+ response.data.l[0] = 0;
+ }
+ answerRect = me.answerRect().intersect( c->rect() );
+ } else {
+ response.data.l[0] = 0;
+ answerRect = TQRect( p, TQSize( 1, 1 ) );
+ }
+ answerRect = TQRect( c->mapToGlobal( answerRect.topLeft() ),
+ answerRect.size() );
+
+ if ( answerRect.left() < 0 )
+ answerRect.setLeft( 0 );
+ if ( answerRect.right() > 4096 )
+ answerRect.setRight( 4096 );
+ if ( answerRect.top() < 0 )
+ answerRect.setTop( 0 );
+ if ( answerRect.bottom() > 4096 )
+ answerRect.setBottom( 4096 );
+ if ( answerRect.width() < 0 )
+ answerRect.setWidth( 0 );
+ if ( answerRect.height() < 0 )
+ answerRect.setHeight( 0 );
+
+ response.data.l[2] = (answerRect.x() << 16) + answerRect.y();
+ response.data.l[3] = (answerRect.width() << 16) + answerRect.height();
+ response.data.l[4] = qtaction_to_xdndaction(accepted_action);
+ global_accepted_action = accepted_action;
+ }
+
+ // reset
+ qt_xdnd_target_current_time = CurrentTime;
+
+ TQWidget * source = TQWidget::tqfind( qt_xdnd_dragsource_xid );
+
+ if ( source && source->isDesktop() && !source->acceptDrops() )
+ source = 0;
+
+ if ( source )
+ qt_handle_xdnd_status( source, (const XEvent *)&response, passive );
+ else
+ XSendEvent( TQPaintDevice::x11AppDisplay(), qt_xdnd_dragsource_xid, False,
+ NoEventMask, (XEvent*)&response );
+}
+
+
+void qt_handle_xdnd_status( TQWidget * w, const XEvent * xe, bool /*passive*/ )
+{
+ const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
+ // Messy: TQDragResponseEvent is just a call to TQDragManager function
+ global_accepted_action = xdndaction_to_qtaction(l[4]);
+ TQDragResponseEvent e( (int)(l[1] & 1) );
+ TQApplication::sendEvent( w, &e );
+
+ if ( (int)(l[1] & 2) == 0 ) {
+ TQPoint p( (l[2] & 0xffff0000) >> 16, l[2] & 0x0000ffff );
+ TQSize s( (l[3] & 0xffff0000) >> 16, l[3] & 0x0000ffff );
+ qt_xdnd_source_sameanswer = TQRect( p, s );
+ if ( qt_xdnd_source_sameanswer.isNull() ) {
+ // Application wants "coninutous" move events
+ }
+ } else {
+ qt_xdnd_source_sameanswer = TQRect();
+ }
+}
+
+
+void qt_handle_xdnd_leave( TQWidget *w, const XEvent * xe, bool /*passive*/ )
+{
+ //qDebug( "xdnd leave" );
+ if ( !qt_xdnd_current_widget ||
+ w->tqtopLevelWidget() != qt_xdnd_current_widget->tqtopLevelWidget() ) {
+ return; // sanity
+ }
+
+ if (checkEmbedded(current_embedding_widget, xe)) {
+ current_embedding_widget = 0;
+ qt_xdnd_current_widget = 0;
+ return;
+ }
+
+ const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
+
+ TQDragLeaveEvent e;
+ TQApplication::sendEvent( qt_xdnd_current_widget, &e );
+
+ if ( l[0] != qt_xdnd_dragsource_xid ) {
+ // This often happens - leave other-process window quickly
+ //qDebug( "xdnd drag leave from unexpected source (%08lx not %08lx",
+ //l[0], qt_xdnd_dragsource_xid );
+ qt_xdnd_current_widget = 0;
+ return;
+ }
+
+ qt_xdnd_dragsource_xid = 0;
+ qt_xdnd_types[0] = 0;
+ qt_xdnd_current_widget = 0;
+}
+
+
+void qt_xdnd_send_leave()
+{
+ if ( !qt_xdnd_current_target )
+ return;
+
+ XClientMessageEvent leave;
+ leave.type = ClientMessage;
+ leave.window = qt_xdnd_current_target;
+ leave.format = 32;
+ leave.message_type = qt_xdnd_leave;
+ leave.data.l[0] = qt_xdnd_dragsource_xid;
+ leave.data.l[1] = 0; // flags
+ leave.data.l[2] = 0; // x, y
+ leave.data.l[3] = 0; // w, h
+ leave.data.l[4] = 0; // just null
+
+ TQWidget * w = TQWidget::tqfind( qt_xdnd_current_proxy_target );
+
+ if ( w && w->isDesktop() && !w->acceptDrops() )
+ w = 0;
+
+ if ( w )
+ qt_handle_xdnd_leave( w, (const XEvent *)&leave, FALSE );
+ else
+ XSendEvent( TQPaintDevice::x11AppDisplay(), qt_xdnd_current_proxy_target, False,
+ NoEventMask, (XEvent*)&leave );
+ qt_xdnd_current_target = 0;
+ qt_xdnd_current_proxy_target = 0;
+}
+
+
+
+void qt_handle_xdnd_drop( TQWidget *, const XEvent * xe, bool passive )
+{
+ if ( !qt_xdnd_current_widget ) {
+ qt_xdnd_dragsource_xid = 0;
+ return; // sanity
+ }
+
+ if (!passive && checkEmbedded(qt_xdnd_current_widget, xe)){
+ current_embedding_widget = 0;
+ qt_xdnd_dragsource_xid = 0;
+ qt_xdnd_current_widget = 0;
+ return;
+ }
+ const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
+
+ //qDebug( "xdnd drop" );
+
+ if ( l[0] != qt_xdnd_dragsource_xid ) {
+ //qDebug( "xdnd drop from unexpected source (%08lx not %08lx",
+ // l[0], qt_xdnd_dragsource_xid );
+ return;
+ }
+
+ if (l[2] != 0) {
+ // update the "user time" from the timestamp in the event.
+ SET_QT_X_USER_TIME(l[2]);
+ qt_xdnd_target_current_time = l[2];
+ }
+
+ if ( qt_xdnd_source_object )
+ qt_xdnd_source_object->setTarget( qt_xdnd_current_widget );
+
+ if ( !passive ) {
+ TQDropEvent de( qt_xdnd_current_position );
+ de.setAction( global_accepted_action );
+ TQApplication::sendEvent( qt_xdnd_current_widget, &de );
+ if ( !de.isAccepted() ) {
+ // Ignore a failed drag
+ global_accepted_action = TQDropEvent::Copy;
+ dndCancelled = TRUE;
+ }
+ XClientMessageEvent finished;
+ finished.type = ClientMessage;
+ finished.window = qt_xdnd_dragsource_xid;
+ finished.format = 32;
+ finished.message_type = qt_xdnd_finished;
+ finished.data.l[0] = qt_xdnd_current_widget?qt_xdnd_current_widget->tqtopLevelWidget()->winId():0;
+ finished.data.l[1] = 0; // flags
+ XSendEvent( TQPaintDevice::x11AppDisplay(), qt_xdnd_dragsource_xid, False,
+ NoEventMask, (XEvent*)&finished );
+ } else {
+ TQDragLeaveEvent e;
+ TQApplication::sendEvent( qt_xdnd_current_widget, &e );
+ }
+ qt_xdnd_dragsource_xid = 0;
+ qt_xdnd_current_widget = 0;
+
+ // reset
+ qt_xdnd_target_current_time = CurrentTime;
+}
+
+
+void qt_handle_xdnd_finished( TQWidget *, const XEvent * xe, bool passive )
+{
+ const unsigned long *l = (const unsigned long *)xe->xclient.data.l;
+
+ if ( l[0] && (l[0] == qt_xdnd_current_target
+ || l[0] == qt_xdnd_current_proxy_target) ) {
+ //
+ if ( !passive )
+ (void ) checkEmbedded( qt_xdnd_current_widget, xe);
+ current_embedding_widget = 0;
+ qt_xdnd_current_target = 0;
+ qt_xdnd_current_proxy_target = 0;
+ delete qt_xdnd_source_object;
+ qt_xdnd_source_object = 0;
+ }
+}
+
+
+void TQDragManager::timerEvent( TQTimerEvent* e )
+{
+ if ( e->timerId() == heartbeat && qt_xdnd_source_sameanswer.isNull() )
+ move( TQCursor::pos() );
+}
+
+bool TQDragManager::eventFilter( TQObject * o, TQEvent * e)
+{
+ if ( beingCancelled ) {
+ if ( e->type() == TQEvent::KeyRelease &&
+ ((TQKeyEvent*)e)->key() == Key_Escape ) {
+ tqApp->removeEventFilter( this );
+ object = 0;
+ dragSource = 0;
+ beingCancelled = FALSE;
+ tqApp->exit_loop();
+ return TRUE; // block the key release
+ }
+ return FALSE;
+ }
+
+ TQ_ASSERT( object != 0 );
+
+ if ( !o->isWidgetType() )
+ return FALSE;
+
+ if ( e->type() == TQEvent::MouseMove ) {
+ TQMouseEvent* me = (TQMouseEvent *)e;
+ updateMode(me->stateAfter());
+ move( me->globalPos() );
+ return TRUE;
+ } else if ( e->type() == TQEvent::MouseButtonRelease ) {
+ tqApp->removeEventFilter( this );
+ if ( willDrop )
+ drop();
+ else
+ cancel();
+ object = 0;
+ dragSource = 0;
+ beingCancelled = FALSE;
+ tqApp->exit_loop();
+ return TRUE;
+ } else if ( e->type() == TQEvent::DragResponse ) {
+ if ( ((TQDragResponseEvent *)e)->dragAccepted() ) {
+ if ( !willDrop ) {
+ willDrop = TRUE;
+ }
+ } else {
+ if ( willDrop ) {
+ willDrop = FALSE;
+ }
+ }
+ updateCursor();
+ return TRUE;
+ }
+
+ if ( e->type() == TQEvent::KeyPress
+ || e->type() == TQEvent::KeyRelease )
+ {
+ TQKeyEvent *ke = ((TQKeyEvent*)e);
+ if ( ke->key() == Key_Escape && e->type() == TQEvent::KeyPress ) {
+ cancel();
+ tqApp->removeEventFilter( this );
+ object = 0;
+ dragSource = 0;
+ beingCancelled = FALSE;
+ tqApp->exit_loop();
+ } else {
+ updateMode(ke->stateAfter());
+ qt_xdnd_source_sameanswer = TQRect(); // force move
+ move( TQCursor::pos() );
+ }
+ return TRUE; // Eat all key events
+ }
+
+ // ### We bind modality to widgets, so we have to do this
+ // ### "manually".
+ // DnD is modal - eat all other interactive events
+ switch ( e->type() ) {
+ case TQEvent::MouseButtonPress:
+ case TQEvent::MouseButtonRelease:
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::MouseMove:
+ case TQEvent::KeyPress:
+ case TQEvent::KeyRelease:
+ case TQEvent::Wheel:
+ case TQEvent::Accel:
+ case TQEvent::AccelAvailable:
+ case TQEvent::AccelOverride:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+
+static TQt::ButtonState oldstate;
+void TQDragManager::updateMode( TQt::ButtonState newstate )
+{
+ if ( newstate == oldstate )
+ return;
+ const int both = ShiftButton|ControlButton;
+ if ( (newstate & both) == both ) {
+ global_requested_action = TQDropEvent::Link;
+ } else {
+ bool local = qt_xdnd_source_object != 0;
+ if ( drag_mode == TQDragObject::DragMove )
+ global_requested_action = TQDropEvent::Move;
+ else if ( drag_mode == TQDragObject::DragCopy )
+ global_requested_action = TQDropEvent::Copy;
+ else if ( drag_mode == TQDragObject::DragLink )
+ global_requested_action = TQDropEvent::Link;
+ else {
+ if ( drag_mode == TQDragObject::DragDefault && local )
+ global_requested_action = TQDropEvent::Move;
+ else
+ global_requested_action = TQDropEvent::Copy;
+ if ( newstate & ShiftButton )
+ global_requested_action = TQDropEvent::Move;
+ else if ( newstate & ControlButton )
+ global_requested_action = TQDropEvent::Copy;
+ }
+ }
+ oldstate = newstate;
+}
+
+
+void TQDragManager::createCursors()
+{
+ if ( !noDropCursor ) {
+ noDropCursor = new TQCursor( Qt::ForbiddenCursor );
+ if ( !pm_cursor[0].isNull() )
+ moveCursor = new TQCursor(pm_cursor[0], 0,0);
+ if ( !pm_cursor[1].isNull() )
+ copyCursor = new TQCursor(pm_cursor[1], 0,0);
+ if ( !pm_cursor[2].isNull() )
+ linkCursor = new TQCursor(pm_cursor[2], 0,0);
+ }
+}
+
+void TQDragManager::updateCursor()
+{
+ TQCursor *c;
+ if ( willDrop ) {
+ if ( global_accepted_action == TQDropEvent::Copy ) {
+ if ( global_requested_action == TQDropEvent::Move )
+ c = moveCursor; // (source can delete)
+ else
+ c = copyCursor;
+ } else if ( global_accepted_action == TQDropEvent::Link ) {
+ c = linkCursor;
+ } else {
+ c = moveCursor;
+ }
+ if ( qt_xdnd_deco ) {
+ qt_xdnd_deco->show();
+ qt_xdnd_deco->raise();
+ }
+ } else {
+ c = noDropCursor;
+ //if ( qt_xdnd_deco )
+ // qt_xdnd_deco->hide();
+ }
+#ifndef TQT_NO_CURSOR
+ if ( c )
+ tqApp->setOverrideCursor( *c, TRUE );
+#endif
+}
+
+
+void TQDragManager::cancel( bool deleteSource )
+{
+ killTimer( heartbeat );
+ heartbeat = -1;
+ if ( object ) {
+ beingCancelled = TRUE;
+ object = 0;
+ }
+
+ if ( qt_xdnd_current_target ) {
+ qt_xdnd_send_leave();
+ }
+
+#ifndef TQT_NO_CURSOR
+ if ( restoreCursor ) {
+ TQApplication::restoreOverrideCursor();
+ restoreCursor = FALSE;
+ }
+#endif
+
+ if ( deleteSource )
+ delete qt_xdnd_source_object;
+ qt_xdnd_source_object = 0;
+ delete qt_xdnd_deco;
+ qt_xdnd_deco = 0;
+
+ dndCancelled = TRUE;
+}
+
+static
+Window tqfindRealWindow( const TQPoint & pos, Window w, int md )
+{
+ if ( qt_xdnd_deco && w == qt_xdnd_deco->winId() )
+ return 0;
+
+ if ( md ) {
+ qt_ignore_badwindow();
+ XWindowAttributes attr;
+ XGetWindowAttributes( TQPaintDevice::x11AppDisplay(), w, &attr );
+ if (qt_badwindow())
+ return 0;
+
+ if ( attr.map_state == IsViewable
+ && TQRect(attr.x,attr.y,attr.width,attr.height)
+ .contains(pos) )
+ {
+ {
+ Atom type = None;
+ int f;
+ unsigned long n, a;
+ unsigned char *data;
+
+ XGetWindowProperty( TQPaintDevice::x11AppDisplay(), w, qt_xdnd_aware, 0,
+ 0, False, AnyPropertyType, &type, &f,&n,&a,&data );
+ if ( data ) XFree(data);
+ if ( type ) return w;
+ }
+
+ Window r, p;
+ Window* c;
+ uint nc;
+ if ( XQueryTree( TQPaintDevice::x11AppDisplay(), w, &r, &p, &c, &nc ) ) {
+ r=0;
+ for (uint i=nc; !r && i--; ) {
+ r = tqfindRealWindow( pos-TQPoint(attr.x,attr.y),
+ c[i], md-1 );
+ }
+ XFree(c);
+ if ( r )
+ return r;
+
+ // We didn't tqfind a client window! Just use the
+ // innermost window.
+ }
+
+ // No tqchildren!
+ return w;
+ }
+ }
+ return 0;
+}
+
+void TQDragManager::move( const TQPoint & globalPos )
+{
+ if (!object) {
+ // perhaps the target crashed?
+ return;
+ }
+
+ int screen = TQCursor::x11Screen();
+ if ( ( qt_xdnd_current_screen == -1 && screen != TQPaintDevice::x11AppScreen() ) ||
+ ( screen != qt_xdnd_current_screen ) ) {
+ // recreate the pixmap on the new screen...
+ delete qt_xdnd_deco;
+ qt_xdnd_deco = new TQShapedPixmapWidget( screen );
+ if (!TQWidget::mouseGrabber()) {
+ updatePixmap();
+ qt_xdnd_deco->grabMouse();
+ }
+ }
+ updatePixmap();
+
+ if ( qt_xdnd_source_sameanswer.contains( globalPos ) &&
+ qt_xdnd_source_sameanswer.isValid() ) {
+ return;
+ }
+
+ qt_xdnd_current_screen = screen;
+ Window rootwin = TQPaintDevice::x11AppRootWindow( qt_xdnd_current_screen );
+ Window target = 0;
+ int lx = 0, ly = 0;
+ if ( !XTranslateCoordinates( TQPaintDevice::x11AppDisplay(), rootwin, rootwin,
+ globalPos.x(), globalPos.y(),
+ &lx, &ly, &target) )
+ // some wierd error...
+ return;
+
+ if ( target == rootwin ) {
+ // Ok.
+ } else if ( target ) {
+ //me
+ Window src = rootwin;
+ while (target != 0) {
+ int lx2, ly2;
+ Window t;
+ // translate coordinates
+ if (!XTranslateCoordinates(TQPaintDevice::x11AppDisplay(), src, target,
+ lx, ly, &lx2, &ly2, &t)) {
+ target = 0;
+ break;
+ }
+ lx = lx2;
+ ly = ly2;
+ src = target;
+
+ // check if it has XdndAware
+ Atom type = None;
+ int f;
+ unsigned long n, a;
+ unsigned char *data = 0;
+ XGetWindowProperty(TQPaintDevice::x11AppDisplay(), target, qt_xdnd_aware, 0, 0, False,
+ AnyPropertyType, &type, &f,&n,&a,&data);
+ if (data)
+ XFree(data);
+ if (type)
+ break;
+
+ // tqfind child at the coordinates
+ if (!XTranslateCoordinates( TQPaintDevice::x11AppDisplay(), src, src,
+ lx, ly, &lx2, &ly2, &target)) {
+ target = 0;
+ break;
+ }
+ }
+ if ( qt_xdnd_deco && (!target || target == qt_xdnd_deco->winId()) ) {
+ target = tqfindRealWindow(globalPos,rootwin,6);
+ }
+ }
+
+ TQWidget* w;
+ if ( target ) {
+ w = TQWidget::tqfind( (WId)target );
+ if ( w && w->isDesktop() && !w->acceptDrops() )
+ w = 0;
+ } else {
+ w = 0;
+ target = rootwin;
+ }
+
+ WId proxy_target = target;
+ int target_version = 1;
+
+ {
+ Atom type = None;
+ int r, f;
+ unsigned long n, a;
+ WId *proxy_id;
+ qt_ignore_badwindow();
+ r = XGetWindowProperty( qt_xdisplay(), target, qt_xdnd_proxy, 0,
+ 1, False, XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id );
+ if ( ( r != Success ) || qt_badwindow() ) {
+ proxy_target = target = 0;
+ } else if ( type == XA_WINDOW && proxy_id ) {
+ proxy_target = *proxy_id;
+ XFree(proxy_id);
+ proxy_id = 0;
+ r = XGetWindowProperty( qt_xdisplay(), proxy_target, qt_xdnd_proxy, 0,
+ 1, False, XA_WINDOW, &type, &f,&n,&a,(uchar**)&proxy_id );
+ if ( ( r != Success ) || qt_badwindow() || !type || !proxy_id || *proxy_id != proxy_target ) {
+ // Bogus
+ proxy_target = 0;
+ target = 0;
+ }
+ if ( proxy_id )
+ XFree(proxy_id);
+ }
+ if ( proxy_target ) {
+ int *tv;
+ qt_ignore_badwindow();
+ r = XGetWindowProperty( qt_xdisplay(), proxy_target, qt_xdnd_aware, 0,
+ 1, False, AnyPropertyType, &type, &f,&n,&a,(uchar**)&tv );
+ if ( r != Success ) {
+ target = 0;
+ } else {
+ target_version = TQMIN(qt_xdnd_version,tv ? *tv : 1);
+ if ( tv )
+ XFree( tv );
+ if (!(!qt_badwindow() && type))
+ target = 0;
+ }
+ }
+ }
+
+ if ( target != qt_xdnd_current_target ) {
+ if ( qt_xdnd_current_target )
+ qt_xdnd_send_leave();
+
+ qt_xdnd_current_target = target;
+ qt_xdnd_current_proxy_target = proxy_target;
+ if ( target ) {
+ TQMemArray<Atom> type;
+ int flags = target_version << 24;
+ const char* fmt;
+ int nfmt=0;
+ for (nfmt=0; (fmt=object->format(nfmt)); nfmt++) {
+ type.resize(nfmt+1);
+ type[nfmt] = *qt_xdnd_str_to_atom( fmt );
+ }
+ if ( nfmt >= 3 ) {
+ XChangeProperty( TQPaintDevice::x11AppDisplay(),
+ object->source()->winId(), qt_xdnd_type_list,
+ XA_ATOM, 32, PropModeReplace,
+ (unsigned char *)type.data(),
+ type.size() );
+ flags |= 0x0001;
+ }
+ XClientMessageEvent enter;
+ enter.type = ClientMessage;
+ enter.window = target;
+ enter.format = 32;
+ enter.message_type = qt_xdnd_enter;
+ enter.data.l[0] = object->source()->winId();
+ enter.data.l[1] = flags;
+ enter.data.l[2] = type.size()>0 ? type[0] : 0;
+ enter.data.l[3] = type.size()>1 ? type[1] : 0;
+ enter.data.l[4] = type.size()>2 ? type[2] : 0;
+ // provisionally set the rectangle to 5x5 pixels...
+ qt_xdnd_source_sameanswer = TQRect( globalPos.x() - 2,
+ globalPos.y() -2 , 5, 5 );
+
+ if ( w ) {
+ qt_handle_xdnd_enter( w, (const XEvent *)&enter, FALSE );
+ } else if ( target ) {
+ XSendEvent( TQPaintDevice::x11AppDisplay(), proxy_target, False, NoEventMask,
+ (XEvent*)&enter );
+ }
+ }
+ }
+
+ if ( target ) {
+ XClientMessageEvent move;
+ move.type = ClientMessage;
+ move.window = target;
+ move.format = 32;
+ move.message_type = qt_xdnd_position;
+ move.window = target;
+ move.data.l[0] = object->source()->winId();
+ move.data.l[1] = 0; // flags
+ move.data.l[2] = (globalPos.x() << 16) + globalPos.y();
+ move.data.l[3] = GET_QT_X_TIME();
+ move.data.l[4] = qtaction_to_xdndaction( global_requested_action );
+
+ if ( w )
+ qt_handle_xdnd_position( w, (const XEvent *)&move, FALSE );
+ else
+ XSendEvent( TQPaintDevice::x11AppDisplay(), proxy_target, False, NoEventMask,
+ (XEvent*)&move );
+ } else {
+ if ( willDrop ) {
+ willDrop = FALSE;
+ updateCursor();
+ }
+ }
+}
+
+
+void TQDragManager::drop()
+{
+ killTimer( heartbeat );
+ heartbeat = -1;
+ if ( !qt_xdnd_current_target )
+ return;
+
+ delete qt_xdnd_deco;
+ qt_xdnd_deco = 0;
+
+ XClientMessageEvent drop;
+ drop.type = ClientMessage;
+ drop.window = qt_xdnd_current_target;
+ drop.format = 32;
+ drop.message_type = qt_xdnd_drop;
+ drop.data.l[0] = object->source()->winId();
+ drop.data.l[1] = 0; // flags
+ drop.data.l[2] = GET_QT_X_TIME();
+ drop.data.l[3] = 0;
+ drop.data.l[4] = 0;
+
+ TQWidget * w = TQWidget::tqfind( qt_xdnd_current_proxy_target );
+
+ if ( w && w->isDesktop() && !w->acceptDrops() )
+ w = 0;
+
+ if ( w )
+ qt_handle_xdnd_drop( w, (const XEvent *)&drop, FALSE );
+ else
+ XSendEvent( TQPaintDevice::x11AppDisplay(), qt_xdnd_current_proxy_target, False,
+ NoEventMask, (XEvent*)&drop );
+
+#ifndef TQT_NO_CURSOR
+ if ( restoreCursor ) {
+ TQApplication::restoreOverrideCursor();
+ restoreCursor = FALSE;
+ }
+#endif
+}
+
+
+
+bool qt_xdnd_handle_badwindow()
+{
+ if ( qt_xdnd_source_object && qt_xdnd_current_target ) {
+ qt_xdnd_current_target = 0;
+ qt_xdnd_current_proxy_target = 0;
+ delete qt_xdnd_source_object;
+ qt_xdnd_source_object = 0;
+ delete qt_xdnd_deco;
+ qt_xdnd_deco = 0;
+ return TRUE;
+ }
+ if ( qt_xdnd_dragsource_xid ) {
+ qt_xdnd_dragsource_xid = 0;
+ if ( qt_xdnd_current_widget ) {
+ TQDragLeaveEvent e;
+ TQApplication::sendEvent( qt_xdnd_current_widget, &e );
+ qt_xdnd_current_widget = 0;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*!
+ \class TQDragMoveEvent tqevent.h
+ \ingroup events
+ \ingroup draganddrop
+ \brief The TQDragMoveEvent class provides an event which is sent while a drag and drop is in progress.
+
+ When a widget \link TQWidget::setAcceptDrops() accepts drop
+ events\endlink, it will receive this event repeatedly while the
+ drag is within the widget's boundaries. The widget should examine
+ the event to see what data it \link TQDragMoveEvent::provides()
+ provides\endlink, and accept() the drop if appropriate.
+
+ Note that this class inherits most of its functionality from
+ TQDropEvent.
+*/
+
+
+/*!
+ Returns TRUE if this event provides format \a mimeType; otherwise
+ returns FALSE.
+
+ \sa data()
+*/
+
+bool TQDropEvent::provides( const char *mimeType ) const
+{
+ if ( qt_motifdnd_active && qstrnicmp( mimeType, "text/", 5 ) == 0 )
+ return TRUE;
+
+ int n=0;
+ const char* f;
+ do {
+ f = format( n );
+ if ( !f )
+ return FALSE;
+ n++;
+ } while( qstricmp( mimeType, f ) );
+ return TRUE;
+}
+
+void qt_xdnd_handle_selection_request( const XSelectionRequestEvent * req )
+{
+ if ( !req )
+ return;
+ XEvent evt;
+ evt.xselection.type = SelectionNotify;
+ evt.xselection.display = req->display;
+ evt.xselection.requestor = req->requestor;
+ evt.xselection.selection = req->selection;
+ evt.xselection.target = req->target;
+ evt.xselection.property = None;
+ evt.xselection.time = req->time;
+ const char* format = qt_xdnd_atom_to_str( req->target );
+ if ( format && qt_xdnd_source_object &&
+ qt_xdnd_source_object->provides( format ) ) {
+ TQByteArray a = qt_xdnd_source_object->tqencodedData(format);
+ XChangeProperty ( TQPaintDevice::x11AppDisplay(), req->requestor, req->property,
+ req->target, 8, PropModeReplace,
+ (unsigned char *)a.data(), a.size() );
+ evt.xselection.property = req->property;
+ }
+ // ### this can die if req->requestor crashes at the wrong
+ // ### moment
+ XSendEvent( TQPaintDevice::x11AppDisplay(), req->requestor, False, 0, &evt );
+}
+
+/*
+ XChangeProperty ( TQPaintDevice::x11AppDisplay(), req->requestor, req->property,
+ XA_STRING, 8,
+ PropModeReplace,
+ (uchar *)d->text(), strlen(d->text()) );
+ evt.xselection.property = req->property;
+*/
+
+static TQByteArray qt_xdnd_obtain_data( const char *format )
+{
+ TQByteArray result;
+
+ TQWidget* w;
+ if ( qt_xdnd_dragsource_xid && qt_xdnd_source_object &&
+ (w=TQWidget::tqfind( qt_xdnd_dragsource_xid ))
+ && (!w->isDesktop() || w->acceptDrops()) )
+ {
+ TQDragObject * o = qt_xdnd_source_object;
+ if ( o->provides( format ) )
+ result = o->tqencodedData(format);
+ return result;
+ }
+
+ Atom * a = qt_xdnd_str_to_atom( format );
+ if ( !a || !*a )
+ return result;
+
+ if ( !qt_xdnd_target_data )
+ qt_xdnd_target_data = new TQIntDict<TQByteArray>( 17 );
+
+ if ( qt_xdnd_target_data->tqfind( (int)*a ) ) {
+ result = *(qt_xdnd_target_data->tqfind( (int)*a ));
+ } else {
+ if ( XGetSelectionOwner( TQPaintDevice::x11AppDisplay(),
+ qt_xdnd_selection ) == None )
+ return result; // should never happen?
+
+ TQWidget* tw = qt_xdnd_current_widget;
+ if ( !qt_xdnd_current_widget ||
+ qt_xdnd_current_widget->isDesktop() ) {
+ tw = new TQWidget;
+ }
+ XConvertSelection( TQPaintDevice::x11AppDisplay(),
+ qt_xdnd_selection,
+ *a,
+ qt_xdnd_selection,
+ tw->winId(),
+ qt_xdnd_target_current_time );
+ XFlush( TQPaintDevice::x11AppDisplay() );
+
+ XEvent xevent;
+ bool got=qt_xclb_wait_for_event( TQPaintDevice::x11AppDisplay(),
+ tw->winId(),
+ SelectionNotify, &xevent, 5000);
+ if ( got ) {
+ Atom type;
+
+ if ( qt_xclb_read_property( TQPaintDevice::x11AppDisplay(),
+ tw->winId(),
+ qt_xdnd_selection, TRUE,
+ &result, 0, &type, 0, FALSE ) ) {
+ if ( type == qt_incr_atom ) {
+ int nbytes = result.size() >= 4 ? *((int*)result.data()) : 0;
+ result = qt_xclb_read_incremental_property( TQPaintDevice::x11AppDisplay(),
+ tw->winId(),
+ qt_xdnd_selection,
+ nbytes, FALSE );
+ } else if ( type != *a ) {
+ // (includes None) qDebug( "TQt clipboard: unknown atom %ld", type);
+ }
+#if 0
+ // this needs to be matched by a qt_xdnd_target_data->clear()
+ // when each drag is finished. for 2.0, we do the safe thing
+ // and disable the entire caching.
+ if ( type != None )
+ qt_xdnd_target_data->insert( (int)((long)a), new TQByteArray(result) );
+#endif
+ }
+ }
+ if ( !qt_xdnd_current_widget ||
+ qt_xdnd_current_widget->isDesktop() ) {
+ delete tw;
+ }
+ }
+
+ return result;
+}
+
+
+/*
+ Enable drag and drop for widget w by installing the proper
+ properties on w's toplevel widget.
+*/
+bool qt_dnd_enable( TQWidget* w, bool on )
+{
+ w = w->tqtopLevelWidget();
+
+ if ( on ) {
+ if ( ( (TQExtraWidget*)w)->topData()->dnd )
+ return TRUE; // been there, done that
+ ((TQExtraWidget*)w)->topData()->dnd = 1;
+ }
+
+ qt_motifdnd_enable( w, on );
+ return qt_xdnd_enable( w, on );
+}
+
+
+/*!
+ \class TQDropEvent tqevent.h
+ \ingroup events
+ \ingroup draganddrop
+
+ \brief The TQDropEvent class provides an event which is sent when a drag and drop is completed.
+
+ When a widget \link TQWidget::setAcceptDrops() accepts drop
+ events\endlink, it will receive this event if it has accepted the
+ most recent TQDragEnterEvent or TQDragMoveEvent sent to it.
+
+ The widget should use data() to extract the data in an appropriate
+ format.
+*/
+
+
+/*!
+ \fn TQDropEvent::TQDropEvent (const TQPoint & pos, Type typ)
+
+ Constructs a drop event that drops a drop of type \a typ on point
+ \a pos.
+*/ // ### pos is in which coordinate system?
+
+
+/*!
+ Returns a byte array containing the drag's data, in \a format.
+
+ data() normally needs to get the data from the drag source, which
+ is potentially very slow, so it's advisable to call this function
+ only if you're sure that you will need the data in \a format.
+
+ The resulting data will have a size of 0 if the format was not
+ available.
+
+ \sa format() TQByteArray::size()
+*/
+
+TQByteArray TQDropEvent::tqencodedData( const char *format ) const
+{
+ if ( qt_motifdnd_active )
+ return qt_motifdnd_obtain_data( format );
+ return qt_xdnd_obtain_data( format );
+}
+
+/*!
+ Returns a string describing one of the available data types for
+ this drag. Common examples are "text/plain" and "image/gif". If \a
+ n is less than zero or greater than the number of available data
+ types, format() returns 0.
+
+ This function is provided mainly for debugging. Most drop targets
+ will use provides().
+
+ \sa data() provides()
+*/
+
+const char* TQDropEvent::format( int n ) const
+{
+ if ( qt_motifdnd_active )
+ return qt_motifdnd_format( n );
+
+ int i = 0;
+ while( i<n && qt_xdnd_types[i] )
+ i++;
+ if ( i < n )
+ return 0;
+
+ const char* name = qt_xdnd_atom_to_str( qt_xdnd_types[i] );
+ if ( !name )
+ return 0; // should never happen
+
+ return name;
+}
+
+bool TQDragManager::drag( TQDragObject * o, TQDragObject::DragMode mode )
+{
+ if ( object == o || !o || !o->tqparent() )
+ return FALSE;
+
+ if ( object ) {
+ cancel();
+ tqApp->removeEventFilter( this );
+ beingCancelled = FALSE;
+ }
+
+ if ( qt_xdnd_source_object ) {
+ // the last drag and drop operation hasn't finished, so we are going to wait
+ // for one second to see if it does... if the finish message comes after this,
+ // then we could still have problems, but this is highly unlikely
+ TQApplication::flushX();
+
+ TQTime started = TQTime::currentTime();
+ TQTime now = started;
+ do {
+ XEvent event;
+ if ( XCheckTypedEvent( TQPaintDevice::x11AppDisplay(),
+ ClientMessage, &event ) )
+ tqApp->x11ProcessEvent( &event );
+
+ now = TQTime::currentTime();
+ if ( started > now ) // crossed midnight
+ started = now;
+
+ // sleep 50ms, so we don't use up CPU cycles all the time.
+ struct timeval usleep_tv;
+ usleep_tv.tv_sec = 0;
+ usleep_tv.tv_usec = 50000;
+ select(0, 0, 0, 0, &usleep_tv);
+ } while ( qt_xdnd_source_object && started.msecsTo(now) < 1000 );
+ }
+
+ qt_xdnd_source_object = o;
+ qt_xdnd_source_object->setTarget( 0 );
+ qt_xdnd_deco = new TQShapedPixmapWidget();
+
+ willDrop = FALSE;
+
+ object = o;
+ updatePixmap();
+
+ dragSource = (TQWidget *)(object->tqparent());
+
+ tqApp->installEventFilter( this );
+ qt_xdnd_source_current_time = GET_QT_X_TIME();
+ XSetSelectionOwner( TQPaintDevice::x11AppDisplay(), qt_xdnd_selection,
+ dragSource->tqtopLevelWidget()->winId(),
+ qt_xdnd_source_current_time );
+ oldstate = TQt::ButtonState(-1); // #### Should use state that caused the drag
+ drag_mode = mode;
+ global_accepted_action = TQDropEvent::Copy;
+ updateMode(TQt::ButtonState(0));
+ qt_xdnd_source_sameanswer = TQRect();
+ move(TQCursor::pos());
+ heartbeat = startTimer(200);
+
+#ifndef TQT_NO_CURSOR
+ tqApp->setOverrideCursor( Qt::ArrowCursor );
+ restoreCursor = TRUE;
+ updateCursor();
+#endif
+
+ dndCancelled = FALSE;
+ qt_xdnd_dragging = TRUE;
+
+ if (!TQWidget::mouseGrabber())
+ qt_xdnd_deco->grabMouse();
+
+ tqApp->enter_loop(); // Do the DND.
+
+#ifndef TQT_NO_CURSOR
+ tqApp->restoreOverrideCursor();
+#endif
+
+ delete qt_xdnd_deco;
+ qt_xdnd_deco = 0;
+ killTimer( heartbeat );
+ heartbeat = -1;
+ qt_xdnd_current_screen = -1;
+ qt_xdnd_dragging = FALSE;
+
+ return ((! dndCancelled) && // source del?
+ (global_accepted_action == TQDropEvent::Copy &&
+ global_requested_action == TQDropEvent::Move));
+
+ // qt_xdnd_source_object persists until we get an xdnd_finish message
+}
+
+void TQDragManager::updatePixmap()
+{
+ if ( qt_xdnd_deco ) {
+ TQPixmap pm;
+ TQPoint pm_hot(default_pm_hotx,default_pm_hoty);
+ if ( object ) {
+ pm = object->pixmap();
+ if ( !pm.isNull() )
+ pm_hot = object->pixmapHotSpot();
+ }
+ if ( pm.isNull() ) {
+ if ( !defaultPm )
+ defaultPm = new TQPixmap(default_pm);
+ pm = *defaultPm;
+ }
+ qt_xdnd_deco->setPixmap(pm);
+ qt_xdnd_deco->move(TQCursor::pos()-pm_hot);
+ qt_xdnd_deco->tqrepaint(FALSE);
+ //if ( willDrop ) {
+ qt_xdnd_deco->show();
+ //} else {
+ // qt_xdnd_deco->hide();
+ //}
+ }
+}
+
+#endif // TQT_NO_DRAGANDDROP
diff --git a/tqtinterface/qt4/src/kernel/tqdragobject.cpp b/tqtinterface/qt4/src/kernel/tqdragobject.cpp
new file mode 100644
index 0000000..6e58f84
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqdragobject.cpp
@@ -0,0 +1,3378 @@
+#include "tqtglobaldefines.h"
+
+// #ifdef USE_QT4
+#if 0
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+
+#ifndef QT_NO_MIME
+
+#include "tqdragobject.h"
+#include "qpixmap.h"
+#include "qevent.h"
+#include "qfile.h"
+#include "qtextcodec.h"
+#include "qapplication.h"
+#include "qpoint.h"
+#include "qwidget.h"
+#include "qbuffer.h"
+#include "qimagereader.h"
+#include "qimagewriter.h"
+#include "qimage.h"
+#include "qregexp.h"
+#include "qdir.h"
+#include "qdrag.h"
+#include "tqstrlist.h"
+#include "tqcstring.h"
+
+// #include <private/qobject_p.h>
+
+#include <ctype.h>
+#if defined(Q_OS_WINCE)
+#include <winsock.h>
+#include "qfunctions_wince.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static QWidget *last_target = 0;
+
+class QDragMime;
+
+class TQDragObjectPrivate : public TQObjectPrivate
+{
+ Q_DECLARE_PUBLIC(TQDragObject)
+public:
+ TQDragObjectPrivate(): hot(0,0),pm_cursor(0) {}
+ QPixmap pixmap;
+ QPoint hot;
+ // store default cursors
+ QPixmap *pm_cursor;
+};
+
+class TQTextDragPrivate : public TQDragObjectPrivate
+{
+ Q_DECLARE_PUBLIC(TQTextDrag)
+public:
+ TQTextDragPrivate() { setSubType(QLatin1String("plain")); }
+ void setSubType(const QString & st) {
+ subtype = st;
+ fmt = "text/" + subtype.toLatin1();
+ }
+
+ QString txt;
+ QString subtype;
+ QByteArray fmt;
+};
+
+class TQStoredDragPrivate : public TQDragObjectPrivate
+{
+ Q_DECLARE_PUBLIC(TQStoredDrag)
+public:
+ TQStoredDragPrivate() {}
+ const char* fmt;
+ QByteArray enc;
+};
+
+class TQImageDragPrivate : public TQDragObjectPrivate
+{
+ Q_DECLARE_PUBLIC(TQImageDrag)
+public:
+ TQImage img;
+ QList<QByteArray> ofmts;
+};
+
+class QDragMime : public QMimeData
+{
+public:
+ QDragMime(TQDragObject *parent) : QMimeData(), dragObject(parent) { }
+ ~QDragMime();
+
+ QByteArray data(const QString &mimetype) const;
+ bool hasFormat(const QString &mimetype) const;
+ QStringList formats() const;
+
+ QPointer<TQDragObject> dragObject;
+};
+
+QDragMime::~QDragMime()
+{
+ delete dragObject;
+}
+QByteArray QDragMime::data(const QString &mimetype) const
+{
+ return dragObject->encodedData(mimetype.latin1());
+}
+
+bool QDragMime::hasFormat(const QString &mimetype) const
+{
+ return dragObject->provides(mimetype.latin1());
+}
+
+QStringList QDragMime::formats() const
+{
+ int i = 0;
+ const char *format;
+ QStringList f;
+ while ((format = dragObject->format(i))) {
+ f.append(QLatin1String(format));
+ ++i;
+ }
+ return f;
+}
+
+/*!
+ Constructs a drag object called \a name with a parent \a
+ dragSource.
+
+ Note that the drag object will be deleted when the \a dragSource is
+ deleted.
+*/
+
+TQDragObject::TQDragObject(QWidget * dragSource, const char * name)
+ :TQObject(*(new TQDragObjectPrivate), dragSource)
+{
+ setObjectName(QLatin1String(name));
+}
+
+/*! \internal */
+TQDragObject::TQDragObject(TQDragObjectPrivate &dd, QWidget *dragSource)
+ :TQObject(dd, dragSource)
+{
+}
+
+/*!
+ Destroys the drag object, canceling any drag and drop operation in
+ which it is involved.
+*/
+
+TQDragObject::~TQDragObject()
+{
+}
+
+#ifndef QT_NO_DRAGANDDROP
+/*!
+ Set the pixmap, \a pm, to display while dragging the object. The
+ platform-specific implementation will use this where it can - so
+ provide a small masked pixmap, and do not assume that the user
+ will actually see it.
+
+ The \a hotspot is the point on (or off) the pixmap that should be
+ under the cursor as it is dragged. It is relative to the top-left
+ pixel of the pixmap.
+
+ \warning We have seen problems with drag cursors on different
+ graphics hardware and driver software on Windows. Setting the
+ graphics acceleration in the display settings down one tick solved
+ the problems in all cases.
+*/
+void TQDragObject::setPixmap(QPixmap pm, const QPoint& hotspot)
+{
+ Q_D(TQDragObject);
+ d->pixmap = pm;
+ d->hot = hotspot;
+}
+
+/*!
+ \overload
+
+ Uses a hotspot that positions the pixmap below and to the right of
+ the mouse pointer. This allows the user to clearly see the point
+ on the window where they are dragging the data.
+*/
+void TQDragObject::setPixmap(QPixmap pm)
+{
+ setPixmap(pm,QPoint(-10, -10));
+}
+
+/*!
+ Returns the currently set pixmap, or a null pixmap if none is set.
+
+ \sa QPixmap::isNull()
+*/
+QPixmap TQDragObject::pixmap() const
+{
+ return d_func()->pixmap;
+}
+
+/*!
+ Returns the currently set pixmap hotspot.
+
+ \sa setPixmap()
+*/
+QPoint TQDragObject::pixmapHotSpot() const
+{
+ return d_func()->hot;
+}
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ DragDefault mode.
+
+ The function returns true if the caller should delete the original
+ copy of the dragged data (but see target()); otherwise returns
+ false.
+
+ If the drag contains \e references to information (e.g. file names
+ in a TQUriDrag are references) then the return value should always
+ be ignored, as the target is expected to directly manipulate the
+ content referred to by the drag object. On X11 the return value should
+ always be correct anyway, but on Windows this is not necessarily
+ the case; e.g. the file manager starts a background process to
+ move files, so the source \e{must not} delete the files!
+
+ Note that on Windows the drag operation will start a blocking modal
+ event loop that will not dispatch any QTimers.
+*/
+bool TQDragObject::drag()
+{
+ return drag(DragDefault);
+}
+
+/*!
+ After the drag completes, this function will return the QWidget
+ which received the drop, or 0 if the data was dropped on another
+ application.
+
+ This can be useful for detecting the case where drag and drop is
+ to and from the same widget.
+*/
+QWidget *TQDragObject::target()
+{
+ return last_target;
+}
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragMove mode. Be sure to read the constraints described in
+ drag().
+
+ Returns true if the data was dragged as a \e move, indicating that
+ the caller should remove the original source of the data (the drag
+ object must continue to have a copy); otherwise returns false.
+
+ \sa drag() dragCopy() dragLink()
+*/
+bool TQDragObject::dragMove()
+{
+ return drag(DragMove);
+}
+
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragCopy mode. Be sure to read the constraints described in
+ drag().
+
+ \sa drag() dragMove() dragLink()
+*/
+void TQDragObject::dragCopy()
+{
+ (void)drag(DragCopy);
+}
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragLink mode. Be sure to read the constraints described in
+ drag().
+
+ \sa drag() dragCopy() dragMove()
+*/
+void TQDragObject::dragLink()
+{
+ (void)drag(DragLink);
+}
+
+
+/*!
+ \enum TQDragObject::DragMode
+
+ This enum describes the possible drag modes.
+
+ \value DragDefault The mode is determined heuristically.
+ \value DragCopy The data is copied.
+ \value DragMove The data is moved.
+ \value DragLink The data is linked.
+ \value DragCopyOrMove The user chooses the mode by using the
+ \key{Shift} key to switch from the default
+ copy mode to move mode.
+*/
+
+
+/*!
+ \overload
+ Starts a drag operation using the contents of this object.
+
+ At this point, the object becomes owned by Qt, not the
+ application. You should not delete the drag object or anything it
+ references. The actual transfer of data to the target application
+ will be done during future event processing - after that time the
+ drag object will be deleted.
+
+ Returns true if the dragged data was dragged as a \e move,
+ indicating that the caller should remove the original source of
+ the data (the drag object must continue to have a copy); otherwise
+ returns false.
+
+ The \a mode specifies the drag mode (see
+ \l{TQDragObject::DragMode}.) Normally one of the simpler drag(),
+ dragMove(), or dragCopy() functions would be used instead.
+*/
+bool TQDragObject::drag(DragMode mode)
+{
+ Q_D(TQDragObject);
+ QDragMime *data = new QDragMime(this);
+ int i = 0;
+ const char *fmt;
+ while ((fmt = format(i))) {
+ data->setData(QLatin1String(fmt), encodedData(fmt));
+ ++i;
+ }
+
+ QDrag *drag = new QDrag(qobject_cast<QWidget *>(parent()));
+ drag->setMimeData(data);
+ drag->setPixmap(d->pixmap);
+ drag->setHotSpot(d->hot);
+
+ Qt::DropActions allowedOps;
+ Qt::DropAction defaultOp = Qt::IgnoreAction;
+ switch(mode) {
+ default:
+ case DragDefault:
+ case DragCopyOrMove:
+ allowedOps = Qt::CopyAction|Qt::MoveAction;
+ defaultOp = Qt::IgnoreAction;
+ break;
+ case DragCopy:
+ allowedOps = Qt::CopyAction;
+ defaultOp = Qt::CopyAction;
+ break;
+ case DragMove:
+ allowedOps = Qt::MoveAction;
+ defaultOp = Qt::MoveAction;
+ break;
+ case DragLink:
+ allowedOps = Qt::LinkAction;
+ defaultOp = Qt::LinkAction;
+ break;
+ }
+ bool retval = (drag->exec(allowedOps, defaultOp) == Qt::MoveAction);
+ last_target = drag->target();
+
+ return retval;
+}
+
+#endif
+
+
+/*!
+ Returns a pointer to the widget where this object originated (the drag
+ source).
+*/
+
+QWidget * TQDragObject::source()
+{
+ if (parent() && parent()->isWidgetType())
+ return (QWidget *)parent();
+ else
+ return 0;
+}
+
+
+/*!
+ \class TQDragObject
+
+ \brief The TQDragObject class encapsulates MIME-based data
+ transfer.
+
+ \compat
+
+ TQDragObject is the base class for all data that needs to be
+ transferred between and within applications, both for drag and
+ drop and for the clipboard.
+
+ See the \link dnd.html Drag and drop documentation\endlink for an
+ overview of how to provide drag and drop in your application.
+
+ See the QClipboard documentation for an overview of how to provide
+ cut and paste in your application.
+
+ The drag() function is used to start a drag operation. You can
+ specify the \l DragMode in the call or use one of the convenience
+ functions dragCopy(), dragMove(), or dragLink(). The drag source
+ where the data originated is retrieved with source(). If the data
+ was dropped on a widget within the application, target() will
+ return a pointer to that widget. Specify the pixmap to display
+ during the drag with setPixmap().
+*/
+
+static
+void stripws(QByteArray& s)
+{
+ int f;
+ while ((f = s.indexOf(' ')) >= 0)
+ s.remove(f,1);
+}
+
+/*!
+ \class TQTextDrag
+
+ \brief The TQTextDrag class is a drag and drop object for
+ transferring plain and Unicode text.
+
+ \compat
+
+ Plain text is passed in a QString which may contain multiple lines
+ (i.e. may contain newline characters). The drag target will receive
+ the newlines according to the runtime environment, e.g. LF on Unix,
+ and CRLF on Windows.
+
+ Qt provides no built-in mechanism for delivering only a single-line.
+
+ For more information about drag and drop, see the TQDragObject class
+ and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+
+/*!
+ Constructs a text drag object with the given \a name, and sets its data
+ to \a text. The \a dragSource is the widget that the drag operation started
+ from.
+*/
+
+TQTextDrag::TQTextDrag(const QString &text, QWidget * dragSource, const char * name)
+ : TQDragObject(*new TQTextDragPrivate, dragSource)
+{
+ setObjectName(QLatin1String(name));
+ setText(text);
+}
+
+
+/*!
+ Constructs a default text drag object with the given \a name.
+ The \a dragSource is the widget that the drag operation started from.
+*/
+
+TQTextDrag::TQTextDrag(QWidget * dragSource, const char * name)
+ : TQDragObject(*(new TQTextDragPrivate), dragSource)
+{
+ setObjectName(QLatin1String(name));
+}
+
+/*! \internal */
+TQTextDrag::TQTextDrag(TQTextDragPrivate &dd, QWidget *dragSource)
+ : TQDragObject(dd, dragSource)
+{
+
+}
+
+/*!
+ Destroys the text drag object.
+*/
+TQTextDrag::~TQTextDrag()
+{
+
+}
+
+/*!
+ \fn void TQTextDrag::setSubtype(const QString &subtype)
+
+ Sets the MIME \a subtype of the text being dragged. The default subtype
+ is "plain", so the default MIME type of the text is "text/plain".
+ You might use this to declare that the text is "text/html" by calling
+ setSubtype("html").
+*/
+void TQTextDrag::setSubtype(const QString & st)
+{
+ d_func()->setSubType(st);
+}
+
+/*!
+ Sets the \a text to be dragged. You will need to call this if you did
+ not pass the text during construction.
+*/
+void TQTextDrag::setText(const QString &text)
+{
+ d_func()->txt = text;
+}
+
+
+/*!
+ \reimp
+*/
+const char * TQTextDrag::format(int i) const
+{
+ if (i > 0)
+ return 0;
+ return d_func()->fmt.constData();
+}
+
+QTextCodec* qt_findcharset(const QByteArray& mimetype)
+{
+ int i=mimetype.indexOf("charset=");
+ if (i >= 0) {
+ QByteArray cs = mimetype.mid(i+8);
+ stripws(cs);
+ i = cs.indexOf(';');
+ if (i >= 0)
+ cs = cs.left(i);
+ // May return 0 if unknown charset
+ return QTextCodec::codecForName(cs);
+ }
+ // no charset=, use locale
+ return QTextCodec::codecForName("utf-8");
+}
+
+static QTextCodec *codecForHTML(const QByteArray &ba)
+{
+ // determine charset
+ int mib = 0;
+ int pos;
+ QTextCodec *c = 0;
+
+ if (ba.size() > 1 && (((uchar)ba[0] == 0xfe && (uchar)ba[1] == 0xff)
+ || ((uchar)ba[0] == 0xff && (uchar)ba[1] == 0xfe))) {
+ mib = 1015; // utf16
+ } else if (ba.size() > 2
+ && (uchar)ba[0] == 0xef
+ && (uchar)ba[1] == 0xbb
+ && (uchar)ba[2] == 0xbf) {
+ mib = 106; // utf-8
+ } else {
+ pos = 0;
+ while ((pos = ba.indexOf('<', pos)) != -1) {
+ int end = ba.indexOf('>', pos+1);
+ if (end == -1)
+ break;
+ const QString str(QString::fromLatin1(ba.mid(pos, end-pos)));
+ if (str.contains(QLatin1String("meta http-equiv="), Qt::CaseInsensitive)) {
+ pos = str.indexOf(QLatin1String("charset="), 0, Qt::CaseInsensitive) + int(strlen("charset="));
+ if (pos != -1) {
+ int pos2 = ba.indexOf('\"', pos+1);
+ QByteArray cs = ba.mid(pos, pos2-pos);
+ c = QTextCodec::codecForName(cs);
+ if (c)
+ return c;
+ }
+ }
+ pos = end;
+ }
+ }
+ if (mib)
+ c = QTextCodec::codecForMib(mib);
+
+ return c;
+}
+
+static
+QTextCodec* findcodec(const QMimeSource* e)
+{
+ QTextCodec* r = 0;
+ const char* f;
+ int i;
+ for (i=0; (f=e->format(i)); i++) {
+ bool html = !qstrnicmp(f, "text/html", 9);
+ if (html)
+ r = codecForHTML(e->encodedData(f));
+ if (!r)
+ r = qt_findcharset(QByteArray(f).toLower());
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+
+
+/*!
+ \reimp
+*/
+QByteArray TQTextDrag::encodedData(const char* mime) const
+{
+ Q_D(const TQTextDrag);
+ if (mime != d->fmt)
+ return QByteArray();
+ return d->txt.toUtf8();
+}
+
+/*!
+ \fn bool TQTextDrag::canDecode(const QMimeSource *source)
+
+ Returns true if the information in the MIME \a source can be decoded
+ into a QString; otherwise returns false.
+
+ \sa decode()
+*/
+bool TQTextDrag::canDecode(const QMimeSource* e)
+{
+ const char* f;
+ for (int i=0; (f=e->format(i)); i++) {
+ if (0==qstrnicmp(f,"text/",5)) {
+ return findcodec(e) != 0;
+ }
+ }
+ return false;
+}
+
+/*!
+ \fn bool TQTextDrag::decode(const QMimeSource *source, QString &string, QString &subtype)
+
+ \overload
+
+ Attempts to decode the dropped information in the MIME \a source into
+ the \a string given.
+ Returns true if successful; otherwise returns false. If \a subtype
+ is null, any text subtype is accepted; otherwise only the
+ specified \a subtype is accepted.
+
+ \sa canDecode()
+*/
+bool TQTextDrag::decode(const QMimeSource* e, QString& str, QString& subtype)
+{
+ if(!e)
+ return false;
+
+ const char* mime;
+ for (int i=0; (mime = e->format(i)); i++) {
+ if (0==qstrnicmp(mime,"text/",5)) {
+ QByteArray m(mime);
+ m = m.toLower();
+ int semi = m.indexOf(';');
+ if (semi < 0)
+ semi = m.length();
+ QString foundst(QString::fromLatin1(m.mid(5,semi-5)));
+ if (subtype.isNull() || foundst == subtype) {
+ bool html = !qstrnicmp(mime, "text/html", 9);
+ QTextCodec* codec = 0;
+ if (html)
+ // search for the charset tag in the HTML
+ codec = codecForHTML(e->encodedData(mime));
+ if (!codec)
+ codec = qt_findcharset(m);
+ if (codec) {
+ QByteArray payload;
+
+ payload = e->encodedData(mime);
+ if (payload.size()) {
+ int l;
+ if (codec->mibEnum() != 1015) {
+ // length is at NUL or payload.size()
+ l = 0;
+ while (l < (int)payload.size() && payload[l])
+ l++;
+ } else {
+ l = payload.size();
+ }
+
+ str = codec->toUnicode(payload,l);
+
+ if (subtype.isNull())
+ subtype = foundst;
+
+ return true;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+/*!
+ \fn bool TQTextDrag::decode(const QMimeSource *source, QString &string)
+
+ Attempts to decode the dropped information in the MIME \a source into
+ the \a string given.
+ Returns true if successful; otherwise returns false.
+
+ \sa canDecode()
+*/
+bool TQTextDrag::decode(const QMimeSource* e, QString& str)
+{
+ QString st;
+ return decode(e, str, st);
+}
+
+
+/*
+ TQImageDrag could use an internal MIME type for communicating QPixmaps
+ and TQImages rather than always converting to raw data. This is available
+ for that purpose and others. It is not currently used.
+*/
+
+/*!
+ \class TQImageDrag
+
+ \brief The TQImageDrag class provides a drag and drop object for
+ transferring images.
+
+ \compat
+
+ Images are offered to the receiving application in multiple
+ formats, determined by Qt's output formats.
+*/
+
+/*!
+ Constructs an image drag object with the given \a name, and sets its
+ data to \a image. The \a dragSource is the widget that the drag operation
+ started from.
+*/
+
+TQImageDrag::TQImageDrag(TQImage image,
+ QWidget * dragSource, const char * name)
+ : TQDragObject(*(new TQImageDragPrivate), dragSource)
+{
+ setObjectName(QLatin1String(name));
+ setImage(image);
+}
+
+/*!
+ Constructs a default image drag object with the given \a name.
+ The \a dragSource is the widget that the drag operation started from.
+*/
+
+TQImageDrag::TQImageDrag(QWidget * dragSource, const char * name)
+ : TQDragObject(*(new TQImageDragPrivate), dragSource)
+{
+ setObjectName(QLatin1String(name));
+}
+
+/*! \internal */
+TQImageDrag::TQImageDrag(TQImageDragPrivate &dd, QWidget *dragSource)
+ : TQDragObject(dd, dragSource)
+{
+}
+
+/*!
+ Destroys the image drag object.
+*/
+
+TQImageDrag::~TQImageDrag()
+{
+ // nothing
+}
+
+
+/*!
+ Sets the \a image to be dragged. You will need to call this if you did
+ not pass the image during construction.
+*/
+void TQImageDrag::setImage(TQImage image)
+{
+ Q_D(TQImageDrag);
+ d->img = image;
+ QList<QByteArray> formats = QImageWriter::supportedImageFormats();
+ formats.removeAll("PBM"); // remove non-raw PPM
+ if (image.depth()!=32) {
+ // BMP better than PPM for paletted images
+ if (formats.removeAll("BMP")) // move to front
+ formats.insert(0,"BMP");
+ }
+ // PNG is best of all
+ if (formats.removeAll("PNG")) // move to front
+ formats.insert(0,"PNG");
+
+ for(int i = 0; i < formats.count(); i++) {
+ QByteArray format("image/");
+ format += formats.at(i);
+ format = format.toLower();
+ if (format == "image/pbmraw")
+ format = "image/ppm";
+ d->ofmts.append(format);
+ }
+ d->ofmts.append("application/x-qt-image");
+}
+
+/*!
+ \reimp
+*/
+const char * TQImageDrag::format(int i) const
+{
+ Q_D(const TQImageDrag);
+ return i < d->ofmts.count() ? d->ofmts.at(i).data() : 0;
+}
+
+/*!
+ \reimp
+*/
+QByteArray TQImageDrag::encodedData(const char* fmt) const
+{
+ Q_D(const TQImageDrag);
+ QString imgFormat(fmt);
+ if (imgFormat == QLatin1String("application/x-qt-image"))
+ imgFormat = QLatin1String("image/PNG");
+
+ if (imgFormat.startsWith("image/")){
+ QByteArray f(imgFormat.mid(6).toAscii());
+ QByteArray dat;
+ QBuffer w(&dat);
+ w.open(QIODevice::WriteOnly);
+ QImageWriter writer(&w, f.toUpper());
+ if (!writer.write(d->img))
+ return QByteArray();
+ w.close();
+ return dat;
+ } else {
+ return QByteArray();
+ }
+}
+
+/*!
+ \fn bool TQImageDrag::canDecode(const QMimeSource *source)
+
+ Returns true if the information in the MIME \a source can be decoded
+ into an image; otherwise returns false.
+
+ \sa decode()
+*/
+bool TQImageDrag::canDecode(const QMimeSource* e)
+{
+ return e->provides("application/x-qt-image");
+}
+
+/*!
+ \fn bool TQImageDrag::decode(const QMimeSource *source, QImage &image)
+
+ Decode the dropped information in the MIME \a source into the \a image.
+ Returns true if successful; otherwise returns false.
+
+ \sa canDecode()
+*/
+bool TQImageDrag::decode(const QMimeSource* e, QImage& img)
+{
+ if (!e)
+ return false;
+
+ QByteArray payload = e->encodedData("application/x-qt-image");
+ if (payload.isEmpty())
+ return false;
+
+ img.loadFromData(payload);
+ if (img.isNull())
+ return false;
+
+ return true;
+}
+
+/*!
+ \fn bool TQImageDrag::decode(const QMimeSource *source, QPixmap &pixmap)
+
+ \overload
+
+ Decodes the dropped information in the MIME \a source into the \a pixmap.
+ Returns true if successful; otherwise returns false.
+
+ This is a convenience function that converts the information to a QPixmap
+ via a QImage.
+
+ \sa canDecode()
+*/
+bool TQImageDrag::decode(const QMimeSource* e, QPixmap& pm)
+{
+ if (!e)
+ return false;
+
+ QImage img;
+ // We avoid dither, since the image probably came from this display
+ if (decode(e, img)) {
+ pm = QPixmap::fromImage(img, Qt::AvoidDither);
+ if (pm.isNull())
+ return false;
+
+ return true;
+ }
+ return false;
+}
+
+
+
+
+/*!
+ \class TQStoredDrag
+ \brief The TQStoredDrag class provides a simple stored-value drag object for arbitrary MIME data.
+
+ \compat
+
+ When a block of data has only one representation, you can use a
+ TQStoredDrag to hold it.
+
+ For more information about drag and drop, see the TQDragObject
+ class and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+/*!
+ Constructs a TQStoredDrag. The \a dragSource and \a name are passed
+ to the TQDragObject constructor, and the format is set to \a
+ mimeType.
+
+ The data will be unset. Use setEncodedData() to set it.
+*/
+TQStoredDrag::TQStoredDrag(const char* mimeType, QWidget * dragSource, const char * name) :
+ TQDragObject(*new TQStoredDragPrivate, dragSource)
+{
+ Q_D(TQStoredDrag);
+ setObjectName(QLatin1String(name));
+ d->fmt = qstrdup(mimeType);
+}
+
+/*! \internal */
+TQStoredDrag::TQStoredDrag(TQStoredDragPrivate &dd, const char* mimeType, QWidget * dragSource)
+ : TQDragObject(dd, dragSource)
+{
+ d_func()->fmt = qstrdup(mimeType);
+}
+
+/*!
+ Destroys the drag object.
+*/
+TQStoredDrag::~TQStoredDrag()
+{
+ delete [] (char*)d_func()->fmt;
+}
+
+/*!
+ \reimp
+*/
+const char * TQStoredDrag::format(int i) const
+{
+ if (i==0)
+ return d_func()->fmt;
+ else
+ return 0;
+}
+
+
+/*!
+ \fn void TQStoredDrag::setEncodedData(const QByteArray &data)
+
+ Sets the encoded \a data of this drag object. The encoded data is
+ delivered to drop sites; it must be in a strictly defined and portable
+ format.
+
+ The drag object can't be dropped (by the user) until this function
+ has been called.
+*/
+
+void TQStoredDrag::setEncodedData(const QByteArray & encodedData)
+{
+ d_func()->enc = encodedData;
+}
+
+/*!
+ \fn QByteArray TQStoredDrag::encodedData(const char *format) const
+
+ Returns the stored data in the \a format given.
+
+ \sa setEncodedData()
+*/
+QByteArray TQStoredDrag::encodedData(const char* m) const
+{
+ if (!qstricmp(m, d_func()->fmt))
+ return d_func()->enc;
+ else
+ return QByteArray();
+}
+
+
+/*!
+ \class TQUriDrag
+ \brief The TQUriDrag class provides a drag object for a list of URI references.
+
+ \compat
+
+ URIs are a useful way to refer to files that may be distributed
+ across multiple machines. A URI will often refer to a file on a
+ machine local to both the drag source and the drop target, so the
+ URI can be equivalent to passing a file name but is more
+ extensible.
+
+ Use URIs in Unicode form so that the user can comfortably edit and
+ view them. For use in HTTP or other protocols, use the correctly
+ escaped ASCII form.
+
+ You can convert a list of file names to file URIs using
+ setFileNames(), or into human-readable form with setUnicodeUris().
+
+ Static functions are provided to convert between filenames and
+ URIs; e.g. uriToLocalFile() and localFileToUri(). Static functions
+ are also provided to convert URIs to and from human-readable form;
+ e.g. uriToUnicodeUri() and unicodeUriToUri().
+ You can also decode URIs from a MIME source into a list with
+ decodeLocalFiles() and decodeToUnicodeUris().
+*/
+
+/*!
+ Constructs an object to drag the list of \a uris.
+ The \a dragSource and \a name are passed to the TQStoredDrag constructor.
+
+ Note that URIs are always in escaped UTF8 encoding.
+*/
+TQUriDrag::TQUriDrag(const TQStrList &uris, QWidget * dragSource, const char * name) :
+ TQStoredDrag("text/uri-list", dragSource)
+{
+ setObjectName(QLatin1String(name));
+ setUris(uris);
+}
+
+/*!
+ Constructs an object to drag with the given \a name.
+ You must call setUris() before you start the drag().
+ Both the \a dragSource and the \a name are passed to the TQStoredDrag
+ constructor.
+*/
+TQUriDrag::TQUriDrag(QWidget * dragSource, const char * name) :
+ TQStoredDrag("text/uri-list", dragSource)
+{
+ setObjectName(QLatin1String(name));
+}
+#endif
+
+/*!
+ Destroys the URI drag object.
+*/
+TQUriDrag::~TQUriDrag()
+{
+}
+
+/*!
+ \fn void TQUriDrag::setUris(const QList<QByteArray> &list)
+
+ Changes the \a list of URIs to be dragged.
+
+ Note that URIs are always in escaped UTF8 encoding.
+*/
+void TQUriDrag::setUris(const QList<QByteArray> &uris)
+{
+ QByteArray a;
+ int c = 0;
+ int i;
+ int count = uris.count();
+ for (i = 0; i < count; ++i)
+ c += uris.at(i).size() + 2; //length + \r\n
+ a.reserve(c+1);
+ for (i = 0; i < count; ++i) {
+ a.append(uris.at(i));
+ a.append("\r\n");
+ }
+ a[c] = 0;
+ setEncodedData(a);
+}
+
+
+/*!
+ \fn bool TQUriDrag::canDecode(const QMimeSource *source)
+
+ Returns true if decode() can decode the MIME \a source; otherwise
+ returns false.
+*/
+bool TQUriDrag::canDecode(const QMimeSource* e)
+{
+ return e->provides("text/uri-list");
+}
+
+/*!
+ \fn bool TQUriDrag::decode(const QMimeSource* source, TQStrList& list)
+
+ Decodes URIs from the MIME \a source, placing the result in the \a list.
+ The list is cleared before any items are inserted.
+
+ Returns true if the MIME \a source contained a valid list of URIs;
+ otherwise returns false.
+*/
+bool TQUriDrag::decode(const QMimeSource* e, TQStrList& l)
+{
+ QByteArray payload = e->encodedData("text/uri-list");
+ if (payload.size()) {
+ l.clear();
+ l.setAutoDelete(true);
+ uint c=0;
+ const char* data = payload.data();
+ while ((int)c < payload.size() && data[c]) {
+ uint f = c;
+ // Find line end
+ while ((int)c < payload.size() && data[c] && data[c]!='\r'
+ && data[c] != '\n')
+ c++;
+ TQCString s(data+f,c-f+1);
+ if (s[0] != '#') // non-comment?
+ l.append(s);
+ // Skip junk
+ while ((int)c < payload.size() && data[c] &&
+ (data[c]=='\n' || data[c]=='\r'))
+ c++;
+ }
+ return true;
+ }
+ return false;
+}
+
+static uint htod(int h)
+{
+ if (isdigit(h))
+ return h - '0';
+ return tolower(h) - 'a' + 10;
+}
+
+/*!
+ \fn TQUriDrag::setFilenames(const QStringList &list)
+
+ \obsolete
+
+ Sets the filename's in the drag object to those in the given \a
+ list.
+
+ Use setFileNames() instead.
+*/
+
+/*!
+ \fn void TQUriDrag::setFileNames(const QStringList &filenames)
+
+ Sets the URIs to be local file URIs equivalent to the \a filenames.
+
+ \sa localFileToUri(), setUris()
+*/
+void TQUriDrag::setFileNames(const QStringList & fnames)
+{
+ QList<QByteArray> uris;
+ for (QStringList::ConstIterator i = fnames.begin();
+ i != fnames.end(); ++i) {
+ QByteArray fileUri = localFileToUri(*i);
+ if (!fileUri.isEmpty())
+ uris.append(fileUri);
+ }
+
+ setUris(uris);
+}
+
+/*!
+ \fn void TQUriDrag::setFileNames(const QString &name)
+ \fn void TQUriDrag::setFilenames(const QString &name)
+
+ Same as setFileNames(QStringList(\a name)).
+*/
+
+/*!
+ \fn void TQUriDrag::setUnicodeUris(const QStringList &list)
+
+ Sets the URIs in the \a list to be Unicode URIs (only useful for
+ displaying to humans).
+
+ \sa localFileToUri(), setUris()
+*/
+void TQUriDrag::setUnicodeUris(const QStringList & uuris)
+{
+ QList<QByteArray> uris;
+ for (int i = 0; i < uuris.count(); ++i)
+ uris.append(unicodeUriToUri(uuris.at(i)));
+ setUris(uris);
+}
+
+/*!
+ \fn QByteArray TQUriDrag::unicodeUriToUri(const QString &string)
+
+ Returns the URI equivalent of the Unicode URI given in the \a string
+ (only useful for displaying to humans).
+
+ \sa uriToLocalFile()
+*/
+QByteArray TQUriDrag::unicodeUriToUri(const QString& uuri)
+{
+ QByteArray utf8 = uuri.toUtf8();
+ QByteArray escutf8;
+ int n = utf8.length();
+ bool isFile = uuri.startsWith(QLatin1String("file://"));
+ for (int i=0; i<n; i++) {
+ if ((utf8[i] >= 'a' && utf8[i] <= 'z')
+ || utf8[i] == '/'
+ || (utf8[i] >= '0' && utf8[i] <= '9')
+ || (utf8[i] >= 'A' && utf8[i] <= 'Z')
+
+ || utf8[i] == '-' || utf8[i] == '_'
+ || utf8[i] == '.' || utf8[i] == '!'
+ || utf8[i] == '~' || utf8[i] == '*'
+ || utf8[i] == '(' || utf8[i] == ')'
+ || utf8[i] == '\''
+
+ // Allow this through, so that all URI-references work.
+ || (!isFile && utf8[i] == '#')
+
+ || utf8[i] == ';'
+ || utf8[i] == '?' || utf8[i] == ':'
+ || utf8[i] == '@' || utf8[i] == '&'
+ || utf8[i] == '=' || utf8[i] == '+'
+ || utf8[i] == '$' || utf8[i] == ',')
+ {
+ escutf8 += utf8[i];
+ } else {
+ // Everything else is escaped as %HH
+ QString s;
+ s.sprintf("%%%02x",(uchar)utf8[i]);
+ escutf8 += s.latin1();
+ }
+ }
+ return escutf8;
+}
+
+/*!
+ Returns the URI equivalent to the absolute local \a filename.
+
+ \sa uriToLocalFile()
+*/
+QByteArray TQUriDrag::localFileToUri(const QString& filename)
+{
+ QString r = filename;
+
+ //check that it is an absolute file
+ if (QDir::isRelativePath(r))
+ return QByteArray();
+#ifdef Q_WS_WIN
+
+
+ bool hasHost = false;
+ // convert form network path
+ if (r.left(2) == QLatin1String("\\\\") || r.left(2) == QLatin1String("//")) {
+ r.remove(0, 2);
+ hasHost = true;
+ }
+
+ // Slosh -> Slash
+ int slosh;
+ while ((slosh=r.indexOf(QLatin1Char('\\'))) >= 0) {
+ r[slosh] = QLatin1Char('/');
+ }
+
+ // Drive
+ if (r[0] != QLatin1Char('/') && !hasHost)
+ r.insert(0,QLatin1Char('/'));
+
+#endif
+#if defined (Q_WS_X11) && 0
+ // URL without the hostname is considered to be errorneous by XDnD.
+ // See: http://www.newplanetsoftware.com/xdnd/dragging_files.html
+ // This feature is not active because this would break dnd between old and new qt apps.
+ char hostname[257];
+ if (gethostname(hostname, 255) == 0) {
+ hostname[256] = '\0';
+ r.prepend(QString::fromLatin1(hostname));
+ }
+#endif
+ return unicodeUriToUri(QLatin1String("file://") + r);
+}
+
+/*!
+ \fn QString TQUriDrag::uriToUnicodeUri(const char *string)
+
+ Returns the Unicode URI (only useful for displaying to humans)
+ equivalent of the URI given in the \a string.
+
+ Note that URIs are always in escaped UTF8 encoding.
+
+ \sa localFileToUri()
+*/
+QString TQUriDrag::uriToUnicodeUri(const char* uri)
+{
+ QByteArray utf8;
+
+ while (*uri) {
+ switch (*uri) {
+ case '%': {
+ uint ch = (uchar) uri[1];
+ if (ch && uri[2]) {
+ ch = htod(ch) * 16 + htod((uchar) uri[2]);
+ utf8 += (char) ch;
+ uri += 2;
+ }
+ }
+ break;
+ default:
+ utf8 += *uri;
+ }
+ ++uri;
+ }
+
+ return QString::fromUtf8(utf8);
+}
+
+/*!
+ \fn QString TQUriDrag::uriToLocalFile(const char *string)
+
+ Returns the name of a local file equivalent to the URI given in the
+ \a string, or an empty string if it does not refer to a local file.
+
+ Note that URIs are always in escaped UTF8 encoding.
+
+ \sa localFileToUri()
+*/
+QString TQUriDrag::uriToLocalFile(const char* uri)
+{
+ QString file;
+
+ if (!uri)
+ return file;
+ if (0==qstrnicmp(uri,"file:/",6)) // It is a local file uri
+ uri += 6;
+ else if (QString::fromLatin1(uri).indexOf(QLatin1String(":/")) != -1) // It is a different scheme uri
+ return file;
+
+ bool local = uri[0] != '/' || (uri[0] != '\0' && uri[1] == '/');
+#ifdef Q_WS_X11
+ // do we have a hostname?
+ if (!local && uri[0] == '/' && uri[2] != '/') {
+ // then move the pointer to after the 'hostname/' part of the uri
+ const char* hostname_end = strchr(uri+1, '/');
+ if (hostname_end != NULL) {
+ char hostname[257];
+ if (gethostname(hostname, 255) == 0) {
+ hostname[256] = '\0';
+ if (qstrncmp(uri+1, hostname, hostname_end - (uri+1)) == 0) {
+ uri = hostname_end + 1; // point after the slash
+ local = true;
+ }
+ }
+ }
+ }
+#endif
+ if (local) {
+ file = uriToUnicodeUri(uri);
+ if (uri[1] == '/') {
+ file.remove((uint)0,1);
+ } else {
+ file.insert(0, QLatin1Char('/'));
+ }
+#ifdef Q_WS_WIN
+ if (file.length() > 2 && file[0] == QLatin1Char('/') && file[2] == QLatin1Char('|')) {
+ file[2] = QLatin1Char(':');
+ file.remove(0,1);
+ } else if (file.length() > 2 && file[0] == QLatin1Char('/') && file[1].isLetter() && file[2] == QLatin1Char(':')) {
+ file.remove(0, 1);
+ }
+ // Leave slash as slashes.
+#endif
+ }
+#ifdef Q_WS_WIN
+ else {
+ file = uriToUnicodeUri(uri);
+ // convert to network path
+ file.insert(1, QLatin1Char('/')); // leave as forward slashes
+ }
+#endif
+
+ return file;
+}
+
+/*!
+ \fn bool TQUriDrag::decodeLocalFiles(const QMimeSource *source, QStringList &list)
+
+ Decodes URIs from the MIME \a source, converting them to local filenames
+ where possible, and places them in the \a list (which is first cleared).
+
+ Returns true if the MIME \a source contained a valid list of URIs;
+ otherwise returns false. The list will be empty if no URIs referred to
+ local files.
+*/
+bool TQUriDrag::decodeLocalFiles(const QMimeSource* e, QStringList& l)
+{
+ TQStrList u;
+ if (!decode(e, u))
+ return false;
+
+ l.clear();
+ for (uint i = 0; i < u.count(); ++i) {
+ QString lf = uriToLocalFile(u.at(i));
+ if (!lf.isEmpty())
+ l.append(lf);
+ }
+ return true;
+}
+
+/*!
+ \fn bool TQUriDrag::decodeToUnicodeUris(const QMimeSource *source, QStringList &list)
+
+ Decodes URIs from the MIME \a source, converting them to Unicode URIs
+ (only useful for displaying to humans), and places them in the \a list
+ (which is first cleared).
+
+ Returns true if the MIME \a source contained a valid list of URIs;
+ otherwise returns false.
+*/
+bool TQUriDrag::decodeToUnicodeUris(const QMimeSource* e, QStringList& l)
+{
+ TQStrList u;
+ if (!decode(e, u))
+ return false;
+
+ l.clear();
+ for (uint i = 0; i < u.count(); ++i)
+ l.append(uriToUnicodeUri(u.at(i)));
+
+ return true;
+}
+
+/*!
+ \class TQColorDrag
+
+ \brief The TQColorDrag class provides a drag and drop object for
+ transferring colors between widgets.
+
+ \compat
+
+ This class provides a drag object which can be used to transfer data
+ about colors for drag and drop and in the clipboard. For example, it
+ is used in QColorDialog.
+
+ The color is set in the constructor but can be changed with
+ setColor().
+
+ For more information about drag and drop, see the TQDragObject class
+ and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+/*!
+ Constructs a color drag object with the given \a col. Passes \a
+ dragsource and \a name to the TQStoredDrag constructor.
+*/
+
+TQColorDrag::TQColorDrag(const QColor &col, QWidget *dragsource, const char *name)
+ : TQStoredDrag("application/x-color", dragsource)
+{
+ setObjectName(QLatin1String(name));
+ setColor(col);
+}
+
+/*!
+ Constructs a color drag object with a white color. Passes \a
+ dragsource and \a name to the TQStoredDrag constructor.
+*/
+
+TQColorDrag::TQColorDrag(QWidget *dragsource, const char *name)
+ : TQStoredDrag("application/x-color", dragsource)
+{
+ setObjectName(QLatin1String(name));
+ setColor(Qt::white);
+}
+
+/*!
+ \fn void TQColorDrag::setColor(const QColor &color)
+
+ Sets the \a color of the color drag.
+*/
+
+void TQColorDrag::setColor(const QColor &col)
+{
+ short r = (col.red() << 8) | col.red();
+ short g = (col.green() << 8) | col.green();
+ short b = (col.blue() << 8) | col.blue();
+
+ // make sure we transmit data in network order
+ r = htons(r);
+ g = htons(g);
+ b = htons(b);
+
+ ushort rgba[4] = {
+ r, g, b,
+ 0xffff // Alpha not supported yet.
+ };
+ QByteArray data;
+ data.resize(sizeof(rgba));
+ memcpy(data.data(), rgba, sizeof(rgba));
+ setEncodedData(data);
+}
+
+/*!
+ \fn bool TQColorDrag::canDecode(QMimeSource *source)
+
+ Returns true if the color drag object can decode the MIME \a source;
+ otherwise returns false.
+*/
+
+bool TQColorDrag::canDecode(QMimeSource *e)
+{
+ return e->provides("application/x-color");
+}
+
+/*!
+ \fn bool TQColorDrag::decode(QMimeSource *source, QColor &color)
+
+ Decodes the MIME \a source, and sets the decoded values to the
+ given \a color. Returns true if the decoding is successful.
+ Returns false if the size of the encoded data is not the
+ expected size.
+*/
+
+bool TQColorDrag::decode(QMimeSource *e, QColor &col)
+{
+ QByteArray data = e->encodedData("application/x-color");
+ ushort rgba[4];
+ if (data.size() != sizeof(rgba))
+ return false;
+
+ memcpy(rgba, data.constData(), sizeof(rgba));
+
+ short r = rgba[0];
+ short g = rgba[1];
+ short b = rgba[2];
+ short a = rgba[3];
+
+ // data is in network order
+ r = ntohs(r);
+ g = ntohs(g);
+ b = ntohs(b);
+ a = ntohs(a);
+
+ r = (r >> 8) & 0xff;
+ g = (g >> 8) & 0xff;
+ b = (b >> 8) & 0xff;
+ a = (a >> 8) & 0xff;
+
+ col.setRgb(r, g, b, a);
+ return true;
+}
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of Drag and Drop support
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// POSIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+#ifndef TQT_NO_MIME
+
+#include "tqdragobject.h"
+#include "tqtextcodec.h"
+#include "tqapplication.h"
+#include "tqpoint.h"
+#include "tqwidget.h"
+#include "tqbuffer.h"
+#include "tqgif.h"
+#include "tqregexp.h"
+#include "tqdir.h"
+#include <ctype.h>
+
+// both a struct for storing stuff in and a wrapper to avoid polluting
+// the name space
+
+class TQDragObjectData
+{
+public:
+ TQDragObjectData(): hot(0,0) {}
+ TQPixmap pixmap;
+ TQPoint hot;
+ // store default cursors
+ TQPixmap *pm_cursor;
+};
+
+static TQWidget* last_target;
+
+/*!
+ After the drag completes, this function will return the TQWidget
+ which received the drop, or 0 if the data was dropped on another
+ application.
+
+ This can be useful for detecting the case where drag and drop is
+ to and from the same widget.
+*/
+TQWidget * TQDragObject::target()
+{
+ return last_target;
+}
+
+/*!
+ \internal
+ Sets the target.
+*/
+void TQDragObject::setTarget(QWidget* t)
+{
+ last_target = TQT_TQWIDGET(t);
+}
+
+class TQStoredDragData
+{
+public:
+ TQStoredDragData() {}
+ const char* fmt;
+ TQByteArray enc;
+};
+
+
+// These pixmaps approximate the images in the Windows User Interface Guidelines.
+
+// XPM
+
+static const char * const move_xpm[] = {
+"11 20 3 1",
+". c None",
+#if defined(TQ_WS_WIN)
+"a c #000000",
+"X c #FFFFFF", // Windows cursor is traditionally white
+#else
+"a c #FFFFFF",
+"X c #000000", // X11 cursor is traditionally black
+#endif
+"aa.........",
+"aXa........",
+"aXXa.......",
+"aXXXa......",
+"aXXXXa.....",
+"aXXXXXa....",
+"aXXXXXXa...",
+"aXXXXXXXa..",
+"aXXXXXXXXa.",
+"aXXXXXXXXXa",
+"aXXXXXXaaaa",
+"aXXXaXXa...",
+"aXXaaXXa...",
+"aXa..aXXa..",
+"aa...aXXa..",
+"a.....aXXa.",
+"......aXXa.",
+".......aXXa",
+".......aXXa",
+"........aa."};
+
+/* XPM */
+static const char * const copy_xpm[] = {
+"24 30 3 1",
+". c None",
+"a c #000000",
+"X c #FFFFFF",
+#if defined(TQ_WS_WIN) // Windows cursor is traditionally white
+"aa......................",
+"aXa.....................",
+"aXXa....................",
+"aXXXa...................",
+"aXXXXa..................",
+"aXXXXXa.................",
+"aXXXXXXa................",
+"aXXXXXXXa...............",
+"aXXXXXXXXa..............",
+"aXXXXXXXXXa.............",
+"aXXXXXXaaaa.............",
+"aXXXaXXa................",
+"aXXaaXXa................",
+"aXa..aXXa...............",
+"aa...aXXa...............",
+"a.....aXXa..............",
+"......aXXa..............",
+".......aXXa.............",
+".......aXXa.............",
+"........aa...aaaaaaaaaaa",
+#else
+"XX......................",
+"XaX.....................",
+"XaaX....................",
+"XaaaX...................",
+"XaaaaX..................",
+"XaaaaaX.................",
+"XaaaaaaX................",
+"XaaaaaaaX...............",
+"XaaaaaaaaX..............",
+"XaaaaaaaaaX.............",
+"XaaaaaaXXXX.............",
+"XaaaXaaX................",
+"XaaXXaaX................",
+"XaX..XaaX...............",
+"XX...XaaX...............",
+"X.....XaaX..............",
+"......XaaX..............",
+".......XaaX.............",
+".......XaaX.............",
+"........XX...aaaaaaaaaaa",
+#endif
+".............aXXXXXXXXXa",
+".............aXXXXXXXXXa",
+".............aXXXXaXXXXa",
+".............aXXXXaXXXXa",
+".............aXXaaaaaXXa",
+".............aXXXXaXXXXa",
+".............aXXXXaXXXXa",
+".............aXXXXXXXXXa",
+".............aXXXXXXXXXa",
+".............aaaaaaaaaaa"};
+
+/* XPM */
+static const char * const link_xpm[] = {
+"24 30 3 1",
+". c None",
+"a c #000000",
+"X c #FFFFFF",
+#if defined(TQ_WS_WIN) // Windows cursor is traditionally white
+"aa......................",
+"aXa.....................",
+"aXXa....................",
+"aXXXa...................",
+"aXXXXa..................",
+"aXXXXXa.................",
+"aXXXXXXa................",
+"aXXXXXXXa...............",
+"aXXXXXXXXa..............",
+"aXXXXXXXXXa.............",
+"aXXXXXXaaaa.............",
+"aXXXaXXa................",
+"aXXaaXXa................",
+"aXa..aXXa...............",
+"aa...aXXa...............",
+"a.....aXXa..............",
+"......aXXa..............",
+".......aXXa.............",
+".......aXXa.............",
+"........aa...aaaaaaaaaaa",
+#else
+"XX......................",
+"XaX.....................",
+"XaaX....................",
+"XaaaX...................",
+"XaaaaX..................",
+"XaaaaaX.................",
+"XaaaaaaX................",
+"XaaaaaaaX...............",
+"XaaaaaaaaX..............",
+"XaaaaaaaaaX.............",
+"XaaaaaaXXXX.............",
+"XaaaXaaX................",
+"XaaXXaaX................",
+"XaX..XaaX...............",
+"XX...XaaX...............",
+"X.....XaaX..............",
+"......XaaX..............",
+".......XaaX.............",
+".......XaaX.............",
+"........XX...aaaaaaaaaaa",
+#endif
+".............aXXXXXXXXXa",
+".............aXXXaaaaXXa",
+".............aXXXXaaaXXa",
+".............aXXXaaaaXXa",
+".............aXXaaaXaXXa",
+".............aXXaaXXXXXa",
+".............aXXaXXXXXXa",
+".............aXXXaXXXXXa",
+".............aXXXXXXXXXa",
+".............aaaaaaaaaaa"};
+
+#ifndef TQT_NO_DRAGANDDROP
+
+// the universe's only drag manager
+TQDragManager * qt_dnd_manager = 0;
+
+
+TQDragManager::TQDragManager()
+ : TQObject( TQT_TQOBJECT(tqApp), "global drag manager" )
+{
+ n_cursor = 3;
+ pm_cursor = new TQPixmap[n_cursor];
+ pm_cursor[0] = TQPixmap((const char **)move_xpm);
+ pm_cursor[1] = TQPixmap((const char **)copy_xpm);
+ pm_cursor[2] = TQPixmap((const char **)link_xpm);
+#if defined(TQ_WS_X11)
+ createCursors(); // Xcursors cache can hold only 8 bitmaps (4 cursors)
+#endif
+ object = 0;
+ dragSource = 0;
+ dropWidget = 0;
+ if ( !qt_dnd_manager )
+ qt_dnd_manager = this;
+ beingCancelled = FALSE;
+ restoreCursor = FALSE;
+ willDrop = FALSE;
+}
+
+
+TQDragManager::~TQDragManager()
+{
+#ifndef TQT_NO_CURSOR
+ if ( restoreCursor )
+ TQApplication::restoreOverrideCursor();
+#endif
+ qt_dnd_manager = 0;
+ delete [] pm_cursor;
+}
+
+#endif
+
+
+/*!
+ Constructs a drag object called \a name, which is a child of \a
+ dragSource.
+
+ Note that the drag object will be deleted when \a dragSource is
+ deleted.
+*/
+
+TQDragObject::TQDragObject( QWidget * dragSource, const char * name )
+ : TQObject( TQT_TQOBJECT(dragSource), name )
+{
+ d = new TQDragObjectData();
+ d->pm_cursor = 0;
+#ifndef TQT_NO_DRAGANDDROP
+ if ( !qt_dnd_manager && tqApp )
+ (void)new TQDragManager();
+#endif
+}
+
+
+/*!
+ Destroys the drag object, canceling any drag and drop operation in
+ which it is involved, and frees up the storage used.
+*/
+
+TQDragObject::~TQDragObject()
+{
+#ifndef TQT_NO_DRAGANDDROP
+ if ( qt_dnd_manager && qt_dnd_manager->object == this )
+ qt_dnd_manager->cancel( FALSE );
+ if ( d->pm_cursor ) {
+ for ( int i = 0; i < qt_dnd_manager->n_cursor; i++ )
+ qt_dnd_manager->pm_cursor[i] = d->pm_cursor[i];
+ delete [] d->pm_cursor;
+ }
+#endif
+ delete d;
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+/*!
+ Set the pixmap \a pm to display while dragging the object. The
+ platform-specific implementation will use this where it can - so
+ provide a small masked pixmap, and do not assume that the user
+ will actually see it. For example, cursors on Windows 95 are of
+ limited size.
+
+ The \a hotspot is the point on (or off) the pixmap that should be
+ under the cursor as it is dragged. It is relative to the top-left
+ pixel of the pixmap.
+
+ \warning We have seen problems with drag cursors on different
+ graphics hardware and driver software on Windows. Setting the
+ graphics acceleration in the display settings down one tick solved
+ the problems in all cases.
+*/
+void TQDragObject::setPixmap(QPixmap pm, const QPoint& hotspot)
+{
+ d->pixmap = pm;
+ d->hot = hotspot;
+ if ( qt_dnd_manager && qt_dnd_manager->object == this )
+ qt_dnd_manager->updatePixmap();
+}
+
+/*!
+ \overload
+ Uses a hotspot that positions the pixmap below and to the right of
+ the mouse pointer. This allows the user to clearly see the point
+ on the window which they are dragging the data onto.
+*/
+void TQDragObject::setPixmap(QPixmap pm)
+{
+ setPixmap(pm,TQPoint(-10, -10));
+}
+
+/*!
+ Returns the currently set pixmap (which \link TQPixmap::isNull()
+ isNull()\endlink if none is set).
+*/
+TQPixmap TQDragObject::pixmap() const
+{
+ return d->pixmap;
+}
+
+/*!
+ Returns the currently set pixmap hotspot.
+*/
+TQPoint TQDragObject::pixmapHotSpot() const
+{
+ return d->hot;
+}
+
+#if 0
+
+// ## reevaluate for TQt 4
+/*!
+ Set the \a cursor used when dragging in mode \a m.
+ Note: X11 only allow bitmaps for cursors.
+*/
+void TQDragObject::setCursor( DragMode m, const TQPixmap &cursor )
+{
+ if ( d->pm_cursor == 0 ) {
+ // safe default cursors
+ d->pm_cursor = new TQPixmap[qt_dnd_manager->n_cursor];
+ for ( int i = 0; i < qt_dnd_manager->n_cursor; i++ )
+ d->pm_cursor[i] = qt_dnd_manager->pm_cursor[i];
+ }
+
+ int index;
+ switch ( m ) {
+ case DragCopy:
+ index = 1;
+ break;
+ case DragLink:
+ index = 2;
+ break;
+ default:
+ index = 0;
+ break;
+ }
+
+ // override default cursor
+ for ( index = 0; index < qt_dnd_manager->n_cursor; index++ )
+ qt_dnd_manager->pm_cursor[index] = cursor;
+}
+
+/*!
+ Returns the cursor used when dragging in mode \a m, or null if no cursor
+ has been set for that mode.
+*/
+TQPixmap *TQDragObject::cursor( DragMode m ) const
+{
+ if ( !d->pm_cursor )
+ return 0;
+
+ int index;
+ switch ( m ) {
+ case DragCopy:
+ index = 1;
+ break;
+ case DragLink:
+ index = 2;
+ break;
+ default:
+ index = 0;
+ break;
+ }
+
+ return qt_dnd_manager->pm_cursor+index;
+}
+
+#endif // 0
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ DragDefault mode.
+
+ The function returns TRUE if the caller should delete the original
+ copy of the dragged data (but see target()); otherwise returns
+ FALSE.
+
+ If the drag tqcontains \e references to information (e.g. file names
+ in a TQUriDrag are references) then the return value should always
+ be ignored, as the target is expected to manipulate the
+ referred-to content directly. On X11 the return value should
+ always be correct anyway, but on Windows this is not necessarily
+ the case (e.g. the file manager starts a background process to
+ move files, so the source \e{must not} delete the files!)
+*/
+bool TQDragObject::drag()
+{
+ return drag( DragDefault );
+}
+
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragMove mode. Be sure to read the constraints described in
+ drag().
+
+ \sa drag() dragCopy() dragLink()
+*/
+bool TQDragObject::dragMove()
+{
+ return drag( DragMove );
+}
+
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragCopy mode. Be sure to read the constraints described in
+ drag().
+
+ \sa drag() dragMove() dragLink()
+*/
+void TQDragObject::dragCopy()
+{
+ (void)drag( DragCopy );
+}
+
+/*!
+ Starts a drag operation using the contents of this object, using
+ \c DragLink mode. Be sure to read the constraints described in
+ drag().
+
+ \sa drag() dragCopy() dragMove()
+*/
+void TQDragObject::dragLink()
+{
+ (void)drag( DragLink );
+}
+
+
+/*!
+ \enum TQDragObject::DragMode
+
+ This enum describes the possible drag modes.
+
+ \value DragDefault The mode is determined heuristically.
+ \value DragCopy The data is copied, never moved.
+ \value DragMove The data is moved, if dragged at all.
+ \value DragLink The data is linked, if dragged at all.
+ \value DragCopyOrMove The user chooses the mode by using a
+ control key to switch from the default.
+*/
+
+
+/*!
+ \overload
+ Starts a drag operation using the contents of this object.
+
+ At this point, the object becomes owned by TQt, not the
+ application. You should not delete the drag object or anything it
+ references. The actual transfer of data to the target application
+ will be done during future event processing - after that time the
+ drag object will be deleted.
+
+ Returns TRUE if the dragged data was dragged as a \e move,
+ indicating that the caller should remove the original source of
+ the data (the drag object must continue to have a copy); otherwise
+ returns FALSE.
+
+ The \a mode specifies the drag mode (see
+ \l{TQDragObject::DragMode}.) Normally one of the simpler drag(),
+ dragMove(), or dragCopy() functions would be used instead.
+*/
+bool TQDragObject::drag( DragMode mode )
+{
+ if ( qt_dnd_manager )
+ return qt_dnd_manager->drag( this, mode );
+ else
+ return FALSE;
+}
+
+#endif
+
+
+/*!
+ Returns a pointer to the drag source where this object originated.
+*/
+
+TQWidget * TQDragObject::source()
+{
+ if ( tqparent() && tqparent()->isWidgetType() )
+ return (TQWidget *)tqparent();
+ else
+ return 0;
+}
+
+
+/*!
+ \class TQDragObject tqdragobject.h
+
+ \brief The TQDragObject class encapsulates MIME-based data
+ transfer.
+
+ \ingroup draganddrop
+
+ TQDragObject is the base class for all data that needs to be
+ transferred between and within applications, both for drag and
+ drop and for the \link tqclipboard.html clipboard\endlink.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag and drop in your application.
+
+ See the TQClipboard documentation for an overview of how to provide
+ cut-and-paste in your application.
+
+ The drag() function is used to start a drag operation. You can
+ specify the \l DragMode in the call or use one of the convenience
+ functions dragCopy(), dragMove() or dragLink(). The drag source
+ where the data originated is retrieved with source(). If the data
+ was dropped on a widget within the application, target() will
+ return a pointer to that widget. Specify the pixmap to display
+ during the drag with setPixmap().
+*/
+
+static
+void stripws(TQCString& s)
+{
+ int f;
+ while ( (f=s.tqfind(' ')) >= 0 )
+ s.remove(f,1);
+}
+
+static
+const char * staticCharset(int i)
+{
+ static TQCString localcharset;
+
+ switch ( i ) {
+ case 0:
+ return "UTF-8";
+ case 1:
+ return "ISO-10646-UCS-2";
+ case 2:
+ return ""; // in the 3rd place - some Xdnd targets might only look at 3
+ case 3:
+ if ( localcharset.isNull() ) {
+ TQTextCodec *localCodec = TQTextCodec::codecForLocale();
+ if ( localCodec ) {
+ localcharset = localCodec->name();
+ localcharset = localcharset.lower();
+ stripws(localcharset);
+ } else {
+ localcharset = "";
+ }
+ }
+ return localcharset;
+ }
+ return 0;
+}
+
+
+class TQTextDragPrivate {
+public:
+ TQTextDragPrivate();
+
+ enum { nfmt=4 };
+
+ TQString txt;
+ TQCString fmt[nfmt];
+ TQCString subtype;
+
+ void setSubType(const TQCString & st)
+ {
+ subtype = st.lower();
+ for ( int i=0; i<nfmt; i++ ) {
+ fmt[i] = "text/";
+ fmt[i].append(subtype);
+ TQCString cs = staticCharset(i);
+ if ( !cs.isEmpty() ) {
+ fmt[i].append(";charset=");
+ fmt[i].append(cs);
+ }
+ }
+ }
+};
+
+inline TQTextDragPrivate::TQTextDragPrivate()
+{
+ setSubType("plain");
+}
+
+/*!
+ Sets the MIME subtype of the text being dragged to \a st. The
+ default subtype is "plain", so the default MIME type of the text
+ is "text/plain". You might use this to declare that the text is
+ "text/html" by calling setSubtype("html").
+*/
+void TQTextDrag::setSubtype( const TQCString & st)
+{
+ d->setSubType(st);
+}
+
+/*!
+ \class TQTextDrag tqdragobject.h
+
+ \brief The TQTextDrag class is a drag and drop object for
+ transferring plain and Unicode text.
+
+ \ingroup draganddrop
+
+ Plain text is passed in a TQString which may contain multiple lines
+ (i.e. may contain newline characters). The drag target will receive
+ the newlines according to the runtime environment, e.g. LF on Unix,
+ and CRLF on Windows.
+
+ TQt provides no built-in mechanism for delivering only a single-line.
+
+ For more information about drag and drop, see the TQDragObject class
+ and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+
+/*!
+ Constructs a text drag object and sets its data to \a text. \a
+ dragSource must be the drag source; \a name is the object name.
+*/
+
+TQTextDrag::TQTextDrag( const TQString &text,
+ TQWidget * dragSource, const char * name )
+ : TQDragObject( dragSource, name )
+{
+ d = new TQTextDragPrivate;
+ setText( text );
+}
+
+
+/*!
+ Constructs a default text drag object. \a dragSource must be the
+ drag source; \a name is the object name.
+*/
+
+TQTextDrag::TQTextDrag( TQWidget * dragSource, const char * name )
+ : TQDragObject( dragSource, name )
+{
+ d = new TQTextDragPrivate;
+}
+
+
+/*!
+ Destroys the text drag object and frees up all allocated
+ resources.
+*/
+TQTextDrag::~TQTextDrag()
+{
+ delete d;
+}
+
+
+/*!
+ Sets the text to be dragged to \a text. You will need to call this
+ if you did not pass the text during construction.
+*/
+void TQTextDrag::setText( const TQString &text )
+{
+ d->txt = text;
+}
+
+
+/*!
+ \reimp
+*/
+const char * TQTextDrag::format(int i) const
+{
+ if ( i >= d->nfmt )
+ return 0;
+ return d->fmt[i];
+}
+
+TQTextCodec* qt_tqfindcharset(const TQCString& mimetype)
+{
+ int i=mimetype.tqfind("charset=");
+ if ( i >= 0 ) {
+ TQCString cs = mimetype.mid(i+8);
+ stripws(cs);
+ i = cs.tqfind(';');
+ if ( i >= 0 )
+ cs = cs.left(i);
+ // win98 often has charset=utf16, and we need to get the correct codec for
+ // it to be able to get Unicode text drops.
+ if ( cs == "utf16" )
+ cs = "ISO-10646-UCS-2";
+ // May return 0 if unknown charset
+ return TQTextCodec::codecForName(cs);
+ }
+ // no charset=, use locale
+ return TQTextCodec::codecForLocale();
+}
+
+static TQTextCodec *codecForHTML(const TQCString &ba)
+{
+ // determine charset
+ int mib = 0;
+ int pos;
+ TQTextCodec *c = 0;
+
+ if (ba.size() > 1 && (((uchar)ba[0] == 0xfe && (uchar)ba[1] == 0xff)
+ || ((uchar)ba[0] == 0xff && (uchar)ba[1] == 0xfe))) {
+ mib = 1000; // utf16
+ } else if (ba.size() > 2
+ && (uchar)ba[0] == 0xef
+ && (uchar)ba[1] == 0xbb
+ && (uchar)ba[2] == 0xbf) {
+ mib = 106; // utf-8
+ } else {
+ pos = 0;
+ while ((pos = ba.tqfind("<meta http-equiv=", pos, FALSE)) != -1) {
+ int end = ba.tqfind('>', pos+1);
+ if (end == -1)
+ break;
+ pos = ba.tqfind("charset=", pos, FALSE) + (int)strlen("charset=");
+ if (pos != -1 && pos < end) {
+ int pos2 = ba.tqfind('\"', pos+1);
+ TQCString cs = ba.mid(pos, pos2-pos);
+ c = TQTextCodec::codecForName(cs);
+ if (c)
+ return c;
+ }
+ pos = end;
+ }
+ }
+ if (mib)
+ c = TQTextCodec::codecForMib(mib);
+
+ return c;
+}
+
+static
+TQTextCodec* tqfindcodec(const TQMimeSource* e)
+{
+ TQTextCodec* r = 0;
+ const char* f;
+ int i;
+ for ( i=0; (f=e->format(i)); i++ ) {
+ bool html = !qstrnicmp(f, "text/html", 9);
+ if (html)
+ r = codecForHTML(TQCString(e->tqencodedData(f)));
+ if (!r)
+ r = qt_tqfindcharset(TQCString(f).lower());
+ if (r)
+ return r;
+ }
+ return 0;
+}
+
+
+
+/*!
+ \reimp
+*/
+TQByteArray TQTextDrag::tqencodedData(const char* mime) const
+{
+ TQCString r;
+ if ( 0==qstrnicmp(mime,"text/",5) ) {
+ TQCString m(mime);
+ m = m.lower();
+ TQTextCodec *codec = qt_tqfindcharset(m);
+ if ( !codec )
+ return r;
+ TQString text( d->txt );
+#if defined(TQ_WS_WIN)
+ int index = text.tqfind( TQString::tqfromLatin1("\r\n"), 0 );
+ while ( index != -1 ) {
+ text.tqreplace( index, 2, TQChar('\n') );
+ index = text.tqfind( "\r\n", index );
+ }
+#endif
+ r = codec->fromUnicode(text);
+ if (!codec || codec->mibEnum() != 1000) {
+ // Don't include NUL in size (TQCString::resize() adds NUL)
+#if defined(TQ_WS_WIN)
+ // This is needed to ensure the \0 isn't lost on Windows 95
+ if ( qWinVersion() & TQt::WV_DOS_based )
+ ((TQByteArray&)r).resize(r.length()+1);
+ else
+#endif
+ ((TQByteArray&)r).resize(r.length());
+ }
+ }
+ return r;
+}
+
+/*!
+ Returns TRUE if the information in \a e can be decoded into a
+ TQString; otherwise returns FALSE.
+
+ \sa decode()
+*/
+bool TQTextDrag::canDecode( const TQMimeSource* e )
+{
+ const char* f;
+ for (int i=0; (f=e->format(i)); i++) {
+ if ( 0==qstrnicmp(f,"text/",5) ) {
+ return tqfindcodec(e) != 0;
+ }
+ }
+ return 0;
+}
+
+/*!
+ \overload
+
+ Attempts to decode the dropped information in \a e into \a str.
+ Returns TRUE if successful; otherwise returns FALSE. If \a subtype
+ is null, any text subtype is accepted; otherwise only the
+ specified \a subtype is accepted.
+
+ \sa canDecode()
+*/
+bool TQTextDrag::decode( const TQMimeSource* e, TQString& str, TQCString& subtype )
+{
+ if(!e)
+ return FALSE;
+
+ if ( e->cacheType == TQMimeSource::Text ) {
+ str = *e->cache.txt.str;
+ subtype = *e->cache.txt.subtype;
+ return TRUE;
+ }
+
+ const char* mime;
+ for (int i=0; (mime = e->format(i)); i++) {
+ if ( 0==qstrnicmp(mime,"text/",5) ) {
+ TQCString m(mime);
+ m = m.lower();
+ int semi = m.tqfind(';');
+ if ( semi < 0 )
+ semi = m.length();
+ TQCString foundst = m.mid(5,semi-5);
+ if ( subtype.isNull() || foundst == subtype ) {
+ bool html = !qstrnicmp(mime, "text/html", 9);
+ TQTextCodec* codec = 0;
+ if (html) {
+ TQByteArray bytes = e->tqencodedData(mime);
+ // search for the charset tag in the HTML
+ codec = codecForHTML(TQCString(bytes.data(), bytes.size()));
+ }
+ if (!codec)
+ codec = qt_tqfindcharset(m);
+ if ( codec ) {
+ TQByteArray payload;
+
+ payload = e->tqencodedData(mime);
+ if ( payload.size() ) {
+ int l;
+ if ( codec->mibEnum() != 1000) {
+ // length is at NUL or payload.size()
+ l = 0;
+ while ( l < (int)payload.size() && payload[l] )
+ l++;
+ } else {
+ l = payload.size();
+ }
+
+ str = codec->toUnicode(payload,l);
+
+ if ( subtype.isNull() )
+ subtype = foundst;
+
+ TQMimeSource *m = (TQMimeSource*)e;
+ m->clearCache();
+ m->cacheType = TQMimeSource::Text;
+ m->cache.txt.str = new TQString( str );
+ m->cache.txt.subtype = new TQCString( subtype );
+
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+/*!
+ Attempts to decode the dropped information in \a e into \a str.
+ Returns TRUE if successful; otherwise returns FALSE.
+
+ \sa canDecode()
+*/
+bool TQTextDrag::decode( const TQMimeSource* e, TQString& str )
+{
+ TQCString st;
+ return decode(e,str,st);
+}
+
+
+/*
+ TQImageDrag could use an internal MIME type for communicating TQPixmaps
+ and TQImages rather than always converting to raw data. This is available
+ for that purpose and others. It is not currently used.
+*/
+class TQImageDragData
+{
+public:
+};
+
+
+/*!
+ \class TQImageDrag tqdragobject.h
+
+ \brief The TQImageDrag class provides a drag and drop object for
+ transferring images.
+
+ \ingroup draganddrop
+
+ Images are offered to the receiving application in multiple
+ formats, determined by TQt's \link TQImage::outputFormats() output
+ formats\endlink.
+
+ For more information about drag and drop, see the TQDragObject
+ class and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+/*!
+ Constructs an image drag object and sets its data to \a image. \a
+ dragSource must be the drag source; \a name is the object name.
+*/
+
+TQImageDrag::TQImageDrag( QImage image,
+ QWidget * dragSource, const char * name )
+ : TQDragObject( dragSource, name ),
+ d(0)
+{
+ setImage( image );
+}
+
+/*!
+ Constructs a default image drag object. \a dragSource must be the
+ drag source; \a name is the object name.
+*/
+
+TQImageDrag::TQImageDrag( QWidget * dragSource, const char * name )
+ : TQDragObject( dragSource, name ),
+ d(0)
+{
+}
+
+
+/*!
+ Destroys the image drag object and frees up all allocated
+ resources.
+*/
+
+TQImageDrag::~TQImageDrag()
+{
+ // nothing
+}
+
+
+/*!
+ Sets the image to be dragged to \a image. You will need to call
+ this if you did not pass the image during construction.
+*/
+void TQImageDrag::setImage( QImage image )
+{
+ img = image; // ### detach?
+ ofmts = TQImage::outputFormats();
+ ofmts.remove("PBM"); // remove non-raw PPM
+ if ( image.depth()!=32 ) {
+ // BMP better than PPM for paletted images
+ if ( ofmts.remove("BMP") ) // move to front
+ ofmts.insert(0,"BMP");
+ }
+ // PNG is best of all
+ if ( ofmts.remove("PNG") ) // move to front
+ ofmts.insert(0,"PNG");
+
+ if(cacheType == TQMimeSource::NoCache) { //cache it
+ cacheType = TQMimeSource::Graphics;
+ cache.gfx.img = new TQImage( img );
+ cache.gfx.pix = 0;
+ }
+}
+
+/*!
+ \reimp
+*/
+const char * TQImageDrag::format(int i) const
+{
+ if ( i < (int)ofmts.count() ) {
+ static TQCString str;
+ str.sprintf("image/%s",(((TQImageDrag*)this)->ofmts).at(i));
+ str = str.lower();
+ if ( str == "image/pbmraw" )
+ str = "image/ppm";
+ return str;
+ } else {
+ return 0;
+ }
+}
+
+/*!
+ \reimp
+*/
+TQByteArray TQImageDrag::tqencodedData(const char* fmt) const
+{
+ if ( qstrnicmp( fmt, "image/", 6 )==0 ) {
+ TQCString f = fmt+6;
+ TQByteArray data;
+ TQBuffer w( data );
+ w.open( IO_WriteOnly );
+ TQImageIO io( &w, f.upper() );
+ io.setImage( img );
+ if ( !io.write() )
+ return TQByteArray();
+ w.close();
+ return data;
+ } else {
+ return TQByteArray();
+ }
+}
+
+/*!
+ Returns TRUE if the information in mime source \a e can be decoded
+ into an image; otherwise returns FALSE.
+
+ \sa decode()
+*/
+bool TQImageDrag::canDecode( const TQMimeSource* e ) {
+ TQStrList fileFormats = TQImageIO::inputFormats();
+
+ fileFormats.first();
+ while ( fileFormats.current()) {
+ TQCString format = fileFormats.current();
+ TQCString type = "image/" + format.lower();
+ if ( e->provides(type.data()))
+ return TRUE;
+ fileFormats.next();
+ }
+
+ return FALSE;
+}
+
+/*!
+ Attempts to decode the dropped information in mime source \a e
+ into \a img. Returns TRUE if successful; otherwise returns FALSE.
+
+ \sa canDecode()
+*/
+bool TQImageDrag::decode( const TQMimeSource* e, QImage& img )
+{
+ if ( !e )
+ return FALSE;
+ if ( e->cacheType == TQMimeSource::Graphics ) {
+ img = *e->cache.gfx.img;
+ return TRUE;
+ }
+
+ TQByteArray payload;
+ TQStrList fileFormats = TQImageIO::inputFormats();
+ // PNG is best of all
+ if ( fileFormats.remove("PNG") ) // move to front
+ fileFormats.insert(0,"PNG");
+ fileFormats.first();
+ while ( fileFormats.current() ) {
+ TQCString format = fileFormats.current();
+ fileFormats.next();
+
+ TQCString type = "image/" + format.lower();
+ if ( ! e->provides( type.data() ) ) continue;
+ payload = e->tqencodedData( type.data() );
+ if ( !payload.isEmpty() )
+ break;
+ }
+
+ if ( payload.isEmpty() )
+ return FALSE;
+
+ img.loadFromData(payload);
+ if ( img.isNull() )
+ return FALSE;
+ TQMimeSource *m = (TQMimeSource*)e;
+ m->clearCache();
+ m->cacheType = TQMimeSource::Graphics;
+ m->cache.gfx.img = new TQImage( img );
+ m->cache.gfx.pix = 0;
+ return TRUE;
+}
+
+/*!
+ \overload
+
+ Attempts to decode the dropped information in mime source \a e
+ into pixmap \a pm. Returns TRUE if successful; otherwise returns
+ FALSE.
+
+ This is a convenience function that converts to a TQPixmap via a
+ TQImage.
+
+ \sa canDecode()
+*/
+bool TQImageDrag::decode( const TQMimeSource* e, QPixmap& pm )
+{
+ if ( !e )
+ return FALSE;
+
+ if ( e->cacheType == TQMimeSource::Graphics && e->cache.gfx.pix) {
+ pm = *e->cache.gfx.pix;
+ return TRUE;
+ }
+
+ TQImage img;
+ // We avoid dither, since the image probably came from this display
+ if ( decode( e, img ) ) {
+ if ( !pm.convertFromImage( img, Qt::AvoidDither ) )
+ return FALSE;
+ // decode initialized the cache for us
+
+ TQMimeSource *m = (TQMimeSource*)e;
+ m->cache.gfx.pix = new TQPixmap( pm );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+
+
+/*!
+ \class TQStoredDrag tqdragobject.h
+ \brief The TQStoredDrag class provides a simple stored-value drag object for arbitrary MIME data.
+
+ \ingroup draganddrop
+
+ When a block of data has only one representation, you can use a
+ TQStoredDrag to hold it.
+
+ For more information about drag and drop, see the TQDragObject
+ class and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+/*!
+ Constructs a TQStoredDrag. The \a dragSource and \a name are passed
+ to the TQDragObject constructor, and the format is set to \a
+ mimeType.
+
+ The data will be unset. Use setEncodedData() to set it.
+*/
+TQStoredDrag::TQStoredDrag( const char* mimeType, QWidget * dragSource, const char * name ) :
+ TQDragObject(dragSource,name)
+{
+ d = new TQStoredDragData();
+ d->fmt = qstrdup(mimeType);
+}
+
+/*!
+ Destroys the drag object and frees up all allocated resources.
+*/
+TQStoredDrag::~TQStoredDrag()
+{
+ delete [] (char*)d->fmt;
+ delete d;
+}
+
+/*!
+ \reimp
+*/
+const char * TQStoredDrag::format(int i) const
+{
+ if ( i==0 )
+ return d->fmt;
+ else
+ return 0;
+}
+
+
+/*!
+ Sets the encoded data of this drag object to \a tqencodedData. The
+ encoded data is what's delivered to the drop sites. It must be in
+ a strictly defined and portable format.
+
+ The drag object can't be dropped (by the user) until this function
+ has been called.
+*/
+
+void TQStoredDrag::setEncodedData( const TQByteArray & tqencodedData )
+{
+ d->enc = tqencodedData.copy();
+}
+
+/*!
+ Returns the stored data. \a m tqcontains the data's format.
+
+ \sa setEncodedData()
+*/
+TQByteArray TQStoredDrag::tqencodedData(const char* m) const
+{
+ if ( !qstricmp(m,d->fmt) )
+ return d->enc;
+ else
+ return TQByteArray();
+}
+
+
+/*!
+ \class TQUriDrag tqdragobject.h
+ \brief The TQUriDrag class provides a drag object for a list of URI references.
+
+ \ingroup draganddrop
+
+ URIs are a useful way to refer to files that may be distributed
+ across multiple machines. A URI will often refer to a file on a
+ machine local to both the drag source and the drop target, so the
+ URI can be equivalent to passing a file name but is more
+ extensible.
+
+ Use URIs in Unicode form so that the user can comfortably edit and
+ view them. For use in HTTP or other protocols, use the correctly
+ escaped ASCII form.
+
+ You can convert a list of file names to file URIs using
+ setFileNames(), or into human-readble form with setUnicodeUris().
+
+ Static functions are provided to convert between filenames and
+ URIs, e.g. uriToLocalFile() and localFileToUri(), and to and from
+ human-readable form, e.g. uriToUnicodeUri(), tqunicodeUriToUri().
+ You can also decode URIs from a mimesource into a list with
+ decodeLocalFiles() and decodeToUnicodeUris().
+*/
+
+/*!
+ Constructs an object to drag the list of URIs in \a uris. The \a
+ dragSource and \a name arguments are passed on to TQStoredDrag.
+ Note that URIs are always in escaped UTF8 encoding.
+*/
+TQUriDrag::TQUriDrag( TQStrList uris,
+ TQWidget * dragSource, const char * name ) :
+ TQStoredDrag( "text/uri-list", dragSource, name )
+{
+ setUris(uris);
+}
+
+/*!
+ Constructs an object to drag. You must call setUris() before you
+ start the drag(). Passes \a dragSource and \a name to the
+ TQStoredDrag constructor.
+*/
+TQUriDrag::TQUriDrag( TQWidget * dragSource, const char * name ) :
+ TQStoredDrag( "text/uri-list", dragSource, name )
+{
+}
+
+/*!
+ Destroys the object.
+*/
+TQUriDrag::~TQUriDrag()
+{
+}
+
+/*!
+ Changes the list of \a uris to be dragged.
+
+ Note that URIs are always in escaped UTF8 encoding.
+*/
+void TQUriDrag::setUris( TQStrList uris )
+{
+ TQByteArray a;
+ int c=0;
+ for ( const char* s = uris.first(); s; s = uris.next() ) {
+ int l = tqstrlen(s);
+ a.resize(c+l+2);
+ memcpy(a.data()+c,s,l);
+ memcpy(a.data()+c+l,"\r\n",2);
+ c+=l+2;
+ }
+ a.resize(c+1);
+ a[c] = 0;
+ setEncodedData(a);
+}
+
+
+/*!
+ Returns TRUE if decode() would be able to decode \a e; otherwise
+ returns FALSE.
+*/
+bool TQUriDrag::canDecode( const TQMimeSource* e )
+{
+ return e->provides( "text/uri-list" );
+}
+
+/*!
+ Decodes URIs from \a e, placing the result in \a l (which is first
+ cleared).
+
+ Returns TRUE if \a e contained a valid list of URIs; otherwise
+ returns FALSE.
+*/
+bool TQUriDrag::decode( const TQMimeSource* e, TQStrList& l )
+{
+ TQByteArray payload = e->tqencodedData( "text/uri-list" );
+ if ( payload.size() ) {
+ l.clear();
+ l.setAutoDelete(TRUE);
+ uint c=0;
+ const char* d = payload.data();
+ while (c < payload.size() && d[c]) {
+ uint f = c;
+ // Find line end
+ while (c < payload.size() && d[c] && d[c]!='\r'
+ && d[c] != '\n')
+ c++;
+ TQCString s(d+f,c-f+1);
+ if ( s[0] != '#' ) // non-comment?
+ l.append( s );
+ // Skip junk
+ while (c < payload.size() && d[c] &&
+ (d[c]=='\n' || d[c]=='\r'))
+ c++;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static uint htod( int h )
+{
+ if ( isdigit(h) )
+ return h - '0';
+ return tolower( h ) - 'a' + 10;
+}
+
+/*!
+ \fn TQUriDrag::setFilenames( const TQStringList & )
+ \obsolete
+
+ Use setFileNames() instead (notice the N).
+*/
+
+/*!
+ Sets the URIs to be the local-file URIs equivalent to \a fnames.
+
+ \sa localFileToUri(), setUris()
+*/
+void TQUriDrag::setFileNames( const TQStringList & fnames )
+{
+ TQStrList uris;
+ for ( TQStringList::ConstIterator i = fnames.begin();
+ i != fnames.end(); ++i ) {
+ TQCString fileUri = localFileToUri(*i);
+ if (!fileUri.isEmpty())
+ uris.append(fileUri);
+ }
+ setUris( uris );
+}
+
+/*!
+ Sets the URIs in \a uuris to be the Unicode URIs (only useful for
+ displaying to humans).
+
+ \sa localFileToUri(), setUris()
+*/
+void TQUriDrag::setUnicodeUris( const TQStringList & uuris )
+{
+ TQStrList uris;
+ for ( TQStringList::ConstIterator i = uuris.begin();
+ i != uuris.end(); ++i )
+ uris.append( tqunicodeUriToUri(*i) );
+ setUris( uris );
+}
+
+/*!
+ Returns the URI equivalent of the Unicode URI given in \a uuri
+ (only useful for displaying to humans).
+
+ \sa uriToLocalFile()
+*/
+TQCString TQUriDrag::tqunicodeUriToUri(const TQString& uuri)
+{
+ TQCString utf8 = uuri.utf8();
+ TQCString escutf8;
+ int n = utf8.length();
+ bool isFile = uuri.startsWith("file://");
+ for (int i=0; i<n; i++) {
+ if ( (utf8[i] >= 'a' && utf8[i] <= 'z')
+ || utf8[i] == '/'
+ || (utf8[i] >= '0' && utf8[i] <= '9')
+ || (utf8[i] >= 'A' && utf8[i] <= 'Z')
+
+ || utf8[i] == '-' || utf8[i] == '_'
+ || utf8[i] == '.' || utf8[i] == '!'
+ || utf8[i] == '~' || utf8[i] == '*'
+ || utf8[i] == '(' || utf8[i] == ')'
+ || utf8[i] == '\''
+
+ // Allow this through, so that all URI-references work.
+ || (!isFile && utf8[i] == '#')
+
+ || utf8[i] == ';'
+ || utf8[i] == '?' || utf8[i] == ':'
+ || utf8[i] == '@' || utf8[i] == '&'
+ || utf8[i] == '=' || utf8[i] == '+'
+ || utf8[i] == '$' || utf8[i] == ',' )
+ {
+ escutf8 += utf8[i];
+ } else {
+ // Everything else is escaped as %HH
+ TQCString s(4);
+ s.sprintf("%%%02x",(uchar)utf8[i]);
+ escutf8 += s;
+ }
+ }
+ return escutf8;
+}
+
+/*!
+ Returns the URI equivalent to the absolute local file \a filename.
+
+ \sa uriToLocalFile()
+*/
+TQCString TQUriDrag::localFileToUri(const TQString& filename)
+{
+ TQString r = filename;
+
+ //check that it is an absolute file
+ if (TQDir::isRelativePath(r))
+ return TQCString();
+
+#ifdef TQ_WS_WIN
+
+
+ bool hasHost = FALSE;
+ // convert form network path
+ if (r.left(2) == "\\\\" || r.left(2) == "//") {
+ r.remove(0, 2);
+ hasHost = TRUE;
+ }
+
+ // Slosh -> Slash
+ int slosh;
+ while ( (slosh=r.tqfind('\\')) >= 0 ) {
+ r[slosh] = '/';
+ }
+
+ // Drive
+ if ( r[0] != '/' && !hasHost)
+ r.insert(0,'/');
+
+#endif
+#if defined ( TQ_WS_X11 ) && 0
+ // URL without the hostname is considered to be errorneous by XDnD.
+ // See: http://www.newplanetsoftware.com/xdnd/dragging_files.html
+ // This feature is not active because this would break dnd between old and new qt apps.
+ char hostname[257];
+ if ( gethostname( hostname, 255 ) == 0 ) {
+ hostname[256] = '\0';
+ r.prepend( TQString::tqfromLatin1( hostname ) );
+ }
+#endif
+ return tqunicodeUriToUri(TQString("file://" + r));
+}
+
+/*!
+ Returns the Unicode URI (only useful for displaying to humans)
+ equivalent of \a uri.
+
+ Note that URIs are always in escaped UTF8 encoding.
+
+ \sa localFileToUri()
+*/
+TQString TQUriDrag::uriToUnicodeUri(const char* uri)
+{
+ TQCString utf8;
+
+ while (*uri) {
+ switch (*uri) {
+ case '%': {
+ uint ch = (uchar) uri[1];
+ if ( ch && uri[2] ) {
+ ch = htod( ch ) * 16 + htod( (uchar) uri[2] );
+ utf8 += (char) ch;
+ uri += 2;
+ }
+ }
+ break;
+ default:
+ utf8 += *uri;
+ }
+ ++uri;
+ }
+
+ return TQString::fromUtf8(utf8);
+}
+
+/*!
+ Returns the name of a local file equivalent to \a uri or a null
+ string if \a uri is not a local file.
+
+ Note that URIs are always in escaped UTF8 encoding.
+
+ \sa localFileToUri()
+*/
+TQString TQUriDrag::uriToLocalFile(const char* uri)
+{
+ TQString file;
+
+ if (!uri)
+ return file;
+ if (0==qstrnicmp(uri,"file:/",6)) // It is a local file uri
+ uri += 6;
+ else if (TQString(uri).tqfind(":/") != -1) // It is a different scheme uri
+ return file;
+
+ bool local = uri[0] != '/' || ( uri[0] != '\0' && uri[1] == '/' );
+#ifdef TQ_WS_X11
+ // do we have a hostname?
+ if ( !local && uri[0] == '/' && uri[2] != '/' ) {
+ // then move the pointer to after the 'hostname/' part of the uri
+ const char* hostname_end = strchr( uri+1, '/' );
+ if ( hostname_end != NULL ) {
+ char hostname[ 257 ];
+ if ( gethostname( hostname, 255 ) == 0 ) {
+ hostname[ 256 ] = '\0';
+ if ( tqstrncmp( uri+1, hostname, hostname_end - ( uri+1 )) == 0 ) {
+ uri = hostname_end + 1; // point after the slash
+ local = TRUE;
+ }
+ }
+ }
+ }
+#endif
+ if ( local ) {
+ file = uriToUnicodeUri(uri);
+ if ( uri[1] == '/' ) {
+ file.remove((uint)0,1);
+ } else {
+ file.insert(0,'/');
+ }
+#ifdef TQ_WS_WIN
+ if ( file.length() > 2 && file[0] == '/' && file[2] == '|' ) {
+ file[2] = ':';
+ file.remove(0,1);
+ } else if (file.length() > 2 && file[0] == '/' && file[1].isLetter() && file[2] == ':') {
+ file.remove(0, 1);
+ }
+ // Leave slash as slashes.
+#endif
+ }
+#ifdef TQ_WS_WIN
+ else {
+ file = uriToUnicodeUri(uri);
+ // convert to network path
+ file.insert(1, '/'); // leave as forward slashes
+ }
+#endif
+
+ return file;
+}
+
+/*!
+ Decodes URIs from the mime source event \a e, converts them to
+ local files if they refer to local files, and places them in \a l
+ (which is first cleared).
+
+ Returns TRUE if \e contained a valid list of URIs; otherwise
+ returns FALSE. The list will be empty if no URIs were local files.
+*/
+bool TQUriDrag::decodeLocalFiles( const TQMimeSource* e, TQStringList& l )
+{
+ TQStrList u;
+ if ( !decode( e, u ) )
+ return FALSE;
+
+ l.clear();
+ for (const char* s=u.first(); s; s=u.next()) {
+ TQString lf = uriToLocalFile(s);
+ if ( !lf.isNull() )
+ l.append( lf );
+ }
+ return TRUE;
+}
+
+/*!
+ Decodes URIs from the mime source event \a e, converts them to
+ Unicode URIs (only useful for displaying to humans), placing them
+ in \a l (which is first cleared).
+
+ Returns TRUE if \e contained a valid list of URIs; otherwise
+ returns FALSE.
+*/
+bool TQUriDrag::decodeToUnicodeUris( const TQMimeSource* e, TQStringList& l )
+{
+ TQStrList u;
+ if ( !decode( e, u ) )
+ return FALSE;
+
+ l.clear();
+ for (const char* s=u.first(); s; s=u.next())
+ l.append( uriToUnicodeUri(s) );
+
+ return TRUE;
+}
+
+
+#ifndef TQT_NO_DRAGANDDROP
+/*!
+ If the source of the drag operation is a widget in this
+ application, this function returns that source, otherwise it
+ returns 0. The source of the operation is the first parameter to
+ drag object subclasses.
+
+ This is useful if your widget needs special behavior when dragging
+ to itself, etc.
+
+ See TQDragObject::TQDragObject() and subclasses.
+*/
+TQWidget* TQDropEvent::source() const
+{
+ return qt_dnd_manager ? qt_dnd_manager->dragSource : 0;
+}
+#endif
+
+/*!
+ \class TQColorDrag tqdragobject.h
+
+ \brief The TQColorDrag class provides a drag and drop object for
+ transferring colors.
+
+ \ingroup draganddrop
+
+ This class provides a drag object which can be used to transfer data
+ about colors for drag and drop and in the clipboard. For example, it
+ is used in TQColorDialog.
+
+ The color is set in the constructor but can be changed with
+ setColor().
+
+ For more information about drag and drop, see the TQDragObject class
+ and the \link dnd.html drag and drop documentation\endlink.
+*/
+
+/*!
+ Constructs a color drag object with the color \a col. Passes \a
+ dragsource and \a name to the TQStoredDrag constructor.
+*/
+
+TQColorDrag::TQColorDrag( const TQColor &col, TQWidget *dragsource, const char *name )
+ : TQStoredDrag( "application/x-color", dragsource, name )
+{
+ setColor( col );
+}
+
+/*!
+ Constructs a color drag object with a white color. Passes \a
+ dragsource and \a name to the TQStoredDrag constructor.
+*/
+
+TQColorDrag::TQColorDrag( TQWidget *dragsource, const char *name )
+ : TQStoredDrag( "application/x-color", dragsource, name )
+{
+ setColor( TQt::white );
+}
+
+/*!
+ Sets the color of the color drag to \a col.
+*/
+
+void TQColorDrag::setColor( const TQColor &col )
+{
+ short r = (col.red() << 8) | col.red();
+ short g = (col.green() << 8) | col.green();
+ short b = (col.blue() << 8) | col.blue();
+
+ // make sure we transmit data in network order
+ r = htons(r);
+ g = htons(g);
+ b = htons(b);
+
+ ushort rgba[4] = {
+ r, g, b,
+ 0xffff // Alpha not supported yet.
+ };
+ TQByteArray data(sizeof(rgba));
+ memcpy(data.data(), rgba, sizeof(rgba));
+ setEncodedData(data);
+}
+
+/*!
+ Returns TRUE if the color drag object can decode the mime source
+ \a e; otherwise returns FALSE.
+*/
+
+bool TQColorDrag::canDecode( TQMimeSource *e )
+{
+ return e->provides( "application/x-color" );
+}
+
+/*!
+ Decodes the mime source \a e and sets the decoded values to \a
+ col.
+*/
+
+bool TQColorDrag::decode( TQMimeSource *e, TQColor &col )
+{
+ TQByteArray data = e->tqencodedData("application/x-color");
+ ushort rgba[4];
+ if (data.size() != sizeof(rgba))
+ return FALSE;
+
+ memcpy(rgba, data.data(), sizeof(rgba));
+
+ short r = rgba[0];
+ short g = rgba[1];
+ short b = rgba[2];
+
+ // data is in network order
+ r = ntohs(r);
+ g = ntohs(g);
+ b = ntohs(b);
+
+ r = (r >> 8) & 0xff;
+ g = (g >> 8) & 0xff;
+ b = (b >> 8) & 0xff;
+
+ col.setRgb(r, g, b);
+ return TRUE;
+}
+
+#endif // TQT_NO_MIME
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqdragobject.h b/tqtinterface/qt4/src/kernel/tqdragobject.h
new file mode 100644
index 0000000..3d55967
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqdragobject.h
@@ -0,0 +1,508 @@
+#include "tqtglobaldefines.h"
+
+// #ifdef USE_QT4
+#if 0
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TQDRAGOBJECT_H
+#define TQDRAGOBJECT_H
+
+#include <QtCore/qobject.h>
+#include <QtGui/qcolor.h>
+#include <QtGui/qmime.h>
+#include <tqimage.h>
+#include <tqstrlist.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3SupportLight)
+
+class QWidget;
+class TQTextDragPrivate;
+class TQDragObjectPrivate;
+class TQStoredDragPrivate;
+class TQImageDragPrivate;
+class TQImageDrag;
+class TQTextDrag;
+class TQStrList;
+class TQImage;
+class QPixmap;
+
+class TQDragObject : public TQObject, public QMimeSource {
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQDragObject(QWidget * dragSource = 0, const char *name = 0);
+ virtual ~TQDragObject();
+
+ bool drag();
+ bool dragMove();
+ void dragCopy();
+ void dragLink();
+
+ virtual void setPixmap(QPixmap);
+ virtual void setPixmap(QPixmap, const QPoint& hotspot);
+ QPixmap pixmap() const;
+ QPoint pixmapHotSpot() const;
+
+ QWidget * source();
+ static QWidget * target();
+
+ enum DragMode { DragDefault, DragCopy, DragMove, DragLink, DragCopyOrMove };
+
+protected:
+ TQDragObject(TQDragObjectPrivate &, QWidget *dragSource = 0);
+ virtual bool drag(DragMode);
+
+private:
+ friend class QDragMime;
+ Q_DISABLE_COPY(TQDragObject)
+};
+
+class TQStoredDrag: public TQDragObject {
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQStoredDrag(const char *mimeType, QWidget *dragSource = 0, const char *name = 0);
+ ~TQStoredDrag();
+
+ virtual void setEncodedData(const QByteArray &);
+
+ const char * format(int i) const;
+ virtual QByteArray encodedData(const char*) const;
+
+protected:
+ TQStoredDrag(TQStoredDragPrivate &, const char *mimeType, QWidget *dragSource = 0);
+
+private:
+ Q_DISABLE_COPY(TQStoredDrag)
+};
+
+class TQTextDrag: public TQDragObject {
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQTextDrag(const QString &, QWidget *dragSource = 0, const char *name = 0);
+ TQTextDrag(QWidget * dragSource = 0, const char * name = 0);
+ ~TQTextDrag();
+
+ virtual void setText(const QString &);
+ virtual void setSubtype(const QString &);
+
+ const char * format(int i) const;
+ virtual QByteArray encodedData(const char*) const;
+
+ static bool canDecode(const QMimeSource* e);
+ static bool decode(const QMimeSource* e, QString& s);
+ static bool decode(const QMimeSource* e, QString& s, QString& subtype);
+
+protected:
+ TQTextDrag(TQTextDragPrivate &, QWidget * dragSource = 0);
+
+private:
+ Q_DISABLE_COPY(TQTextDrag)
+};Q_COMPAT_EXPORT
+
+class TQImageDrag: public TQDragObject {
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQImageDrag(TQImage image, QWidget * dragSource = 0, const char * name = 0);
+ TQImageDrag(QWidget * dragSource = 0, const char * name = 0);
+ ~TQImageDrag();
+
+ virtual void setImage(TQImage image);
+
+ const char * format(int i) const;
+ virtual QByteArray encodedData(const char*) const;
+
+ static bool canDecode(const QMimeSource* e);
+ static bool decode(const QMimeSource* e, TQImage& i);
+ static bool decode(const QMimeSource* e, QPixmap& i);
+
+protected:
+ TQImageDrag(TQImageDragPrivate &, QWidget * dragSource = 0);
+
+private:
+ Q_DISABLE_COPY(TQImageDrag)
+};
+
+
+class TQUriDrag: public TQStoredDrag {
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQUriDrag(const TQStrList &uris, QWidget * dragSource = 0, const char * name = 0);
+ TQUriDrag(QWidget * dragSource = 0, const char * name = 0);
+ ~TQUriDrag();
+
+ void setFileNames(const QStringList & fnames);
+ inline void setFileNames(const QString & fname) { setFileNames(QStringList(fname)); }
+ void setFilenames(const QStringList & fnames) { setFileNames(fnames); }
+ inline void setFilenames(const QString & fname) { setFileNames(QStringList(fname)); }
+ void setUnicodeUris(const QStringList & uuris);
+ virtual void setUris(const QList<QByteArray> &uris);
+
+ static QString uriToLocalFile(const char*);
+ static QByteArray localFileToUri(const QString&);
+ static QString uriToUnicodeUri(const char*);
+ static QByteArray unicodeUriToUri(const QString&);
+ static bool canDecode(const QMimeSource* e);
+ static bool decode(const QMimeSource* e, TQStrList& i);
+ static bool decodeToUnicodeUris(const QMimeSource* e, QStringList& i);
+ static bool decodeLocalFiles(const QMimeSource* e, QStringList& i);
+
+private:
+ Q_DISABLE_COPY(TQUriDrag)
+};
+
+class TQColorDrag : public TQStoredDrag
+{
+ Q_OBJECT
+ TQ_OBJECT
+ QColor color;
+
+public:
+ TQColorDrag(const QColor &col, QWidget *dragsource = 0, const char *name = 0);
+ TQColorDrag(QWidget * dragSource = 0, const char * name = 0);
+ void setColor(const QColor &col);
+
+ static bool canDecode(QMimeSource *);
+ static bool decode(QMimeSource *, QColor &col);
+
+private:
+ Q_DISABLE_COPY(TQColorDrag)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // TQDRAGOBJECT_H
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Definition of TQDragObject
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDRAGOBJECT_H
+#define TQDRAGOBJECT_H
+
+class TQWidget;
+class TQTextDragPrivate;
+class TQDragObjectData;
+class TQStoredDragData;
+class TQImageDragData;
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqimage.h"
+#include "tqstrlist.h"
+#include "tqcolor.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_MIME
+
+class TQ_EXPORT TQDragObject: public TQObject, public TQMimeSource {
+ TQ_OBJECT
+public:
+ TQDragObject( QWidget * dragSource = 0, const char * name = 0 );
+ virtual ~TQDragObject();
+
+#ifndef TQT_NO_DRAGANDDROP
+ bool drag();
+ bool dragMove();
+ void dragCopy();
+ void dragLink();
+
+ virtual void setPixmap(QPixmap);
+ virtual void setPixmap(QPixmap, const QPoint& hotspot);
+ TQPixmap pixmap() const;
+ TQPoint pixmapHotSpot() const;
+#endif
+
+ TQWidget * source();
+ static TQWidget * target();
+
+ static void setTarget(QWidget*);
+
+#ifndef TQT_NO_DRAGANDDROP
+ enum DragMode { DragDefault, DragCopy, DragMove, DragLink, DragCopyOrMove };
+
+protected:
+ virtual bool drag(DragMode);
+#endif
+
+private:
+ TQDragObjectData * d;
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQDragObject( const TQDragObject & );
+ TQDragObject &operator=( const TQDragObject & );
+#endif
+};
+
+class TQ_EXPORT TQStoredDrag: public TQDragObject {
+ TQ_OBJECT
+ TQStoredDragData * d;
+
+public:
+ TQStoredDrag( const char * mimeType,
+ QWidget * dragSource = 0, const char * name = 0 );
+ ~TQStoredDrag();
+
+ virtual void setEncodedData( const TQByteArray & );
+
+ const char * format(int i) const;
+ virtual TQByteArray tqencodedData(const char*) const;
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQStoredDrag( const TQStoredDrag & );
+ TQStoredDrag &operator=( const TQStoredDrag & );
+#endif
+};
+
+class TQ_EXPORT TQTextDrag: public TQDragObject {
+ TQ_OBJECT
+ TQTextDragPrivate* d;
+public:
+ TQTextDrag( const TQString &,
+ TQWidget * dragSource = 0, const char * name = 0 );
+ TQTextDrag( TQWidget * dragSource = 0, const char * name = 0 );
+ ~TQTextDrag();
+
+ virtual void setText( const TQString &);
+ virtual void setSubtype( const TQCString &);
+
+ const char * format(int i) const;
+ virtual TQByteArray tqencodedData(const char*) const;
+
+ static bool canDecode( const TQMimeSource* e );
+ static bool decode( const TQMimeSource* e, TQString& s );
+ static bool decode( const TQMimeSource* e, TQString& s, TQCString& subtype );
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQTextDrag( const TQTextDrag & );
+ TQTextDrag &operator=( const TQTextDrag & );
+#endif
+};
+
+class TQ_EXPORT TQImageDrag: public TQDragObject {
+ TQ_OBJECT
+ TQImage img;
+ TQStrList ofmts;
+ TQImageDragData* d;
+
+public:
+ TQImageDrag( QImage image, QWidget * dragSource = 0, const char * name = 0 );
+ TQImageDrag( QWidget * dragSource = 0, const char * name = 0 );
+ ~TQImageDrag();
+
+ virtual void setImage( QImage image );
+
+ const char * format(int i) const;
+ virtual TQByteArray tqencodedData(const char*) const;
+
+ static bool canDecode( const TQMimeSource* e );
+ static bool decode( const TQMimeSource* e, QImage& i );
+ static bool decode( const TQMimeSource* e, QPixmap& i );
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQImageDrag( const TQImageDrag & );
+ TQImageDrag &operator=( const TQImageDrag & );
+#endif
+};
+
+
+class TQ_EXPORT TQUriDrag: public TQStoredDrag {
+ TQ_OBJECT
+
+public:
+ TQUriDrag( TQStrList uris, TQWidget * dragSource = 0, const char * name = 0 );
+ TQUriDrag( TQWidget * dragSource = 0, const char * name = 0 );
+ ~TQUriDrag();
+
+ void setFilenames( const TQStringList & fnames ) { setFileNames( fnames ); }
+ void setFileNames( const TQStringList & fnames );
+ void setUnicodeUris( const TQStringList & uuris );
+ virtual void setUris( TQStrList uris );
+
+ static TQString uriToLocalFile(const char*);
+ static TQCString localFileToUri(const TQString&);
+ static TQString uriToUnicodeUri(const char*);
+ static TQCString tqunicodeUriToUri(const TQString&);
+ static bool canDecode( const TQMimeSource* e );
+ static bool decode( const TQMimeSource* e, TQStrList& i );
+ static bool decodeToUnicodeUris( const TQMimeSource* e, TQStringList& i );
+ static bool decodeLocalFiles( const TQMimeSource* e, TQStringList& i );
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQUriDrag( const TQUriDrag & );
+ TQUriDrag &operator=( const TQUriDrag & );
+#endif
+};
+
+class TQ_EXPORT TQColorDrag : public TQStoredDrag
+{
+ TQ_OBJECT
+ TQColor color;
+
+public:
+ TQColorDrag( const TQColor &col, TQWidget *dragsource = 0, const char *name = 0 );
+ TQColorDrag( TQWidget * dragSource = 0, const char * name = 0 );
+ void setColor( const TQColor &col );
+
+ static bool canDecode( TQMimeSource * );
+ static bool decode( TQMimeSource *, TQColor &col );
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQColorDrag( const TQColorDrag & );
+ TQColorDrag &operator=( const TQColorDrag & );
+#endif
+};
+
+#ifndef TQT_NO_COMPAT
+typedef TQUriDrag TQUrlDrag;
+#endif
+
+#ifndef TQT_NO_DRAGANDDROP
+
+// TQDragManager is not part of the public API. It is defined in a
+// header file simply so different .cpp files can implement different
+// member functions.
+//
+
+class TQ_EXPORT TQDragManager: public TQObject {
+ TQ_OBJECT
+
+private:
+ TQDragManager();
+ ~TQDragManager();
+ // only friend classes can use TQDragManager.
+ friend class TQDragObject;
+ friend class TQDragMoveEvent;
+ friend class TQDropEvent;
+ friend class TQApplication;
+
+ bool eventFilter( TQObject *, TQEvent * );
+ void timerEvent( TQTimerEvent* );
+
+ bool drag( TQDragObject *, TQDragObject::DragMode );
+
+ void cancel( bool deleteSource = TRUE );
+ void move( const TQPoint & );
+ void drop();
+ void updatePixmap();
+
+private:
+ TQDragObject * object;
+ void updateMode( TQt::ButtonState newstate );
+ void updateCursor();
+#if defined(TQ_WS_X11)
+ void createCursors();
+#endif
+
+ TQWidget * dragSource;
+ TQWidget * dropWidget;
+ bool beingCancelled;
+ bool restoreCursor;
+ bool willDrop;
+
+ TQPixmap *pm_cursor;
+ int n_cursor;
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQDragManager( const TQDragManager & );
+ TQDragManager &operator=( const TQDragManager & );
+#endif
+};
+
+#endif
+
+#endif // TQT_NO_MIME
+
+#endif // TQDRAGOBJECT_H
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqdrawutil.cpp b/tqtinterface/qt4/src/kernel/tqdrawutil.cpp
new file mode 100644
index 0000000..6ce07d5
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqdrawutil.cpp
@@ -0,0 +1,957 @@
+/****************************************************************************
+**
+** Implementation of draw utilities
+**
+** Created : 950920
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdrawutil.h"
+#ifndef TQT_NO_DRAWUTIL
+#include "tqbitmap.h"
+#include "tqpixmapcache.h"
+#include "tqapplication.h"
+#include "tqpainter.h"
+
+/*!
+ \relates TQPainter
+
+ \c{#include <tqdrawutil.h>}
+
+ Draws a horizontal (\a y1 == \a y2) or vertical (\a x1 == \a x2)
+ shaded line using the painter \a p.
+
+ Nothing is drawn if \a y1 != \a y2 and \a x1 != \a x2 (i.e. the
+ line is neither horizontal nor vertical).
+
+ The color group argument \a g specifies the shading colors (\link
+ TQColorGroup::light() light\endlink, \link TQColorGroup::dark()
+ dark\endlink and \link TQColorGroup::mid() middle\endlink colors).
+
+ The line appears sunken if \a sunken is TRUE, or raised if \a
+ sunken is FALSE.
+
+ The \a lineWidth argument specifies the line width for each of the
+ lines. It is not the total line width.
+
+ The \a midLineWidth argument specifies the width of a middle line
+ drawn in the TQColorGroup::mid() color.
+
+ If you want to use a TQFrame widget instead, you can make it
+ display a shaded line, for example \c{TQFrame::setFrameStyle(
+ TQFrame::HLine | TQFrame::Sunken )}.
+
+ \warning This function does not look at TQWidget::style() or
+ TQApplication::style(). Use the drawing functions in TQStyle to make
+ widgets that follow the current GUI style.
+
+ \sa qDrawShadeRect(), qDrawShadePanel(), TQStyle::drawPrimitive()
+*/
+
+void qDrawShadeLine( TQPainter *p, int x1, int y1, int x2, int y2,
+ const TQColorGroup &g, bool sunken,
+ int lineWidth, int midLineWidth )
+{
+ if (!( p && lineWidth >= 0 && midLineWidth >= 0 ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "qDrawShadeLine invalid parameters." );
+#endif
+ return;
+ }
+ int tlw = lineWidth*2 + midLineWidth; // total line width
+ TQPen oldPen = p->pen(); // save pen
+ if ( sunken )
+ p->setPen( g.dark() );
+ else
+ p->setPen( g.light() );
+ TQPointArray a;
+ int i;
+ if ( y1 == y2 ) { // horizontal line
+ int y = y1 - tlw/2;
+ if ( x1 > x2 ) { // swap x1 and x2
+ int t = x1;
+ x1 = x2;
+ x2 = t;
+ }
+ x2--;
+ for ( i=0; i<lineWidth; i++ ) { // draw top shadow
+ a.setPoints( 3, x1+i, y+tlw-1-i,
+ x1+i, y+i,
+ x2-i, y+i );
+ p->drawPolyline( a );
+ }
+ if ( midLineWidth > 0 ) {
+ p->setPen( g.mid() );
+ for ( i=0; i<midLineWidth; i++ ) // draw lines in the middle
+ p->drawLine( x1+lineWidth, y+lineWidth+i,
+ x2-lineWidth, y+lineWidth+i );
+ }
+ if ( sunken )
+ p->setPen( g.light() );
+ else
+ p->setPen( g.dark() );
+ for ( i=0; i<lineWidth; i++ ) { // draw bottom shadow
+ a.setPoints( 3, x1+i, y+tlw-i-1,
+ x2-i, y+tlw-i-1,
+ x2-i, y+i+1 );
+ p->drawPolyline( a );
+ }
+ }
+ else if ( x1 == x2 ) { // vertical line
+ int x = x1 - tlw/2;
+ if ( y1 > y2 ) { // swap y1 and y2
+ int t = y1;
+ y1 = y2;
+ y2 = t;
+ }
+ y2--;
+ for ( i=0; i<lineWidth; i++ ) { // draw left shadow
+ a.setPoints( 3, x+i, y2,
+ x+i, y1+i,
+ x+tlw-1, y1+i );
+ p->drawPolyline( a );
+ }
+ if ( midLineWidth > 0 ) {
+ p->setPen( g.mid() );
+ for ( i=0; i<midLineWidth; i++ ) // draw lines in the middle
+ p->drawLine( x+lineWidth+i, y1+lineWidth, x+lineWidth+i, y2 );
+ }
+ if ( sunken )
+ p->setPen( g.light() );
+ else
+ p->setPen( g.dark() );
+ for ( i=0; i<lineWidth; i++ ) { // draw right shadow
+ a.setPoints( 3, x+lineWidth, y2-i,
+ x+tlw-i-1, y2-i,
+ x+tlw-i-1, y1+lineWidth );
+ p->drawPolyline( a );
+ }
+ }
+ p->setPen( oldPen );
+}
+
+
+/*!
+ \relates TQPainter
+
+ \c{#include <tqdrawutil.h>}
+
+ Draws the shaded rectangle specified by (\a x, \a y, \a w, \a h)
+ using the painter \a p.
+
+ The color group argument \a g specifies the shading colors (\link
+ TQColorGroup::light() light\endlink, \link TQColorGroup::dark()
+ dark\endlink and \link TQColorGroup::mid() middle\endlink colors).
+
+ The rectangle appears sunken if \a sunken is TRUE, or raised if \a
+ sunken is FALSE.
+
+ The \a lineWidth argument specifies the line width for each of the
+ lines. It is not the total line width.
+
+ The \a midLineWidth argument specifies the width of a middle line
+ drawn in the TQColorGroup::mid() color.
+
+ The rectangle's interior is filled with the \a fill brush unless
+ \a fill is 0.
+
+ If you want to use a TQFrame widget instead, you can make it
+ display a shaded rectangle, for example \c{TQFrame::setFrameStyle(
+ TQFrame::Box | TQFrame::Raised )}.
+
+ \warning This function does not look at TQWidget::style() or
+ TQApplication::style(). Use the drawing functions in TQStyle to make
+ widgets that follow the current GUI style.
+
+ \sa qDrawShadeLine(), qDrawShadePanel(), qDrawPlainRect(),
+ TQStyle::drawItem(), TQStyle::tqdrawControl()
+ TQStyle::tqdrawComplexControl()
+*/
+
+void qDrawShadeRect( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool sunken,
+ int lineWidth, int midLineWidth,
+ const TQBrush *fill )
+{
+ if ( w == 0 || h == 0 )
+ return;
+ if ( ! ( w > 0 && h > 0 && lineWidth >= 0 && midLineWidth >= 0 ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "qDrawShadeRect(): Invalid parameters" );
+#endif
+ return;
+ }
+ TQPen oldPen = p->pen();
+ if ( sunken )
+ p->setPen( g.dark() );
+ else
+ p->setPen( g.light() );
+ int x1=x, y1=y, x2=x+w-1, y2=y+h-1;
+ TQPointArray a;
+
+ if ( lineWidth == 1 && midLineWidth == 0 ) {// standard shade rectangle
+ p->drawRect( x1, y1, w-1, h-1 );
+ if ( sunken )
+ p->setPen( g.light() );
+ else
+ p->setPen( g.dark() );
+ a.setPoints( 8, x1+1,y1+1, x2-2,y1+1, x1+1,y1+2, x1+1,y2-2,
+ x1,y2, x2,y2, x2,y1, x2,y2-1 );
+ p->drawLineSegments( a ); // draw bottom/right lines
+ } else { // more complicated
+ int m = lineWidth+midLineWidth;
+ int i, j=0, k=m;
+ for ( i=0; i<lineWidth; i++ ) { // draw top shadow
+ a.setPoints( 8, x1+i, y2-i, x1+i, y1+i, x1+i, y1+i, x2-i, y1+i,
+ x1+k, y2-k, x2-k, y2-k, x2-k, y2-k, x2-k, y1+k );
+ p->drawLineSegments( a );
+ k++;
+ }
+ p->setPen( g.mid() );
+ j = lineWidth*2;
+ for ( i=0; i<midLineWidth; i++ ) { // draw lines in the middle
+ p->drawRect( x1+lineWidth+i, y1+lineWidth+i, w-j, h-j );
+ j += 2;
+ }
+ if ( sunken )
+ p->setPen( g.light() );
+ else
+ p->setPen( g.dark() );
+ k = m;
+ for ( i=0; i<lineWidth; i++ ) { // draw bottom shadow
+ a.setPoints( 8, x1+1+i,y2-i, x2-i, y2-i, x2-i, y2-i, x2-i, y1+i+1,
+ x1+k, y2-k, x1+k, y1+k, x1+k, y1+k, x2-k, y1+k );
+ p->drawLineSegments( a );
+ k++;
+ }
+ }
+ if ( fill ) {
+ TQBrush oldBrush = p->brush();
+ int tlw = lineWidth + midLineWidth;
+ p->setPen( TQt::NoPen );
+ p->setBrush( *fill );
+ p->drawRect( x+tlw, y+tlw, w-2*tlw, h-2*tlw );
+ p->setBrush( oldBrush );
+ }
+ p->setPen( oldPen ); // restore pen
+}
+
+
+/*!
+ \relates TQPainter
+
+ \c{#include <tqdrawutil.h>}
+
+ Draws the shaded panel specified by (\a x, \a y, \a w, \a h) using
+ the painter \a p.
+
+ The color group argument \a g specifies the shading colors (\link
+ TQColorGroup::light() light\endlink, \link TQColorGroup::dark()
+ dark\endlink and \link TQColorGroup::mid() middle\endlink colors).
+
+ The panel appears sunken if \a sunken is TRUE, or raised if \a
+ sunken is FALSE.
+
+ The \a lineWidth argument specifies the line width.
+
+ The panel's interior is filled with the \a fill brush unless \a
+ fill is 0.
+
+ If you want to use a TQFrame widget instead, you can make it
+ display a shaded panel, for example \c{TQFrame::setFrameStyle(
+ TQFrame::Panel | TQFrame::Sunken )}.
+
+ \warning This function does not look at TQWidget::style() or
+ TQApplication::style(). Use the drawing functions in TQStyle to make
+ widgets that follow the current GUI style.
+
+ \sa qDrawWinPanel(), qDrawShadeLine(), qDrawShadeRect(),
+ TQStyle::drawPrimitive()
+*/
+
+void qDrawShadePanel( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool sunken,
+ int lineWidth, const TQBrush *fill )
+{
+ if ( w == 0 || h == 0 )
+ return;
+ if ( !( w > 0 && h > 0 && lineWidth >= 0 ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "qDrawShadePanel() Invalid parameters." );
+#endif
+ }
+ TQColor shade = g.dark();
+ TQColor light = g.light();
+ if ( fill ) {
+ if ( fill->color() == shade )
+ shade = g.shadow();
+ if ( fill->color() == light )
+ light = g.midlight();
+ }
+ TQPen oldPen = p->pen(); // save pen
+ TQPointArray a( 4*lineWidth );
+ if ( sunken )
+ p->setPen( shade );
+ else
+ p->setPen( light );
+ int x1, y1, x2, y2;
+ int i;
+ int n = 0;
+ x1 = x;
+ y1 = y2 = y;
+ x2 = x+w-2;
+ for ( i=0; i<lineWidth; i++ ) { // top shadow
+ a.setPoint( n++, x1, y1++ );
+ a.setPoint( n++, x2--, y2++ );
+ }
+ x2 = x1;
+ y1 = y+h-2;
+ for ( i=0; i<lineWidth; i++ ) { // left shadow
+ a.setPoint( n++, x1++, y1 );
+ a.setPoint( n++, x2++, y2-- );
+ }
+ p->drawLineSegments( a );
+ n = 0;
+ if ( sunken )
+ p->setPen( light );
+ else
+ p->setPen( shade );
+ x1 = x;
+ y1 = y2 = y+h-1;
+ x2 = x+w-1;
+ for ( i=0; i<lineWidth; i++ ) { // bottom shadow
+ a.setPoint( n++, x1++, y1-- );
+ a.setPoint( n++, x2, y2-- );
+ }
+ x1 = x2;
+ y1 = y;
+ y2 = y+h-lineWidth-1;
+ for ( i=0; i<lineWidth; i++ ) { // right shadow
+ a.setPoint( n++, x1--, y1++ );
+ a.setPoint( n++, x2--, y2 );
+ }
+ p->drawLineSegments( a );
+ if ( fill ) { // fill with fill color
+ TQBrush oldBrush = p->brush();
+ p->setPen( TQt::NoPen );
+ p->setBrush( *fill );
+ p->drawRect( x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2 );
+ p->setBrush( oldBrush );
+ }
+ p->setPen( oldPen ); // restore pen
+}
+
+
+/*!
+ \internal
+ This function draws a rectangle with two pixel line width.
+ It is called from qDrawWinButton() and qDrawWinPanel().
+
+ c1..c4 and fill are used:
+
+ 1 1 1 1 1 2
+ 1 3 3 3 4 2
+ 1 3 F F 4 2
+ 1 3 F F 4 2
+ 1 4 4 4 4 2
+ 2 2 2 2 2 2
+*/
+
+static void qDrawWinShades( TQPainter *p,
+ int x, int y, int w, int h,
+ const TQColor &c1, const TQColor &c2,
+ const TQColor &c3, const TQColor &c4,
+ const TQBrush *fill )
+{
+ if ( w < 2 || h < 2 ) // can't do anything with that
+ return;
+ TQPen oldPen = p->pen();
+ TQPointArray a( 3 );
+ a.setPoints( 3, x, y+h-2, x, y, x+w-2, y );
+ p->setPen( c1 );
+ p->drawPolyline( a );
+ a.setPoints( 3, x, y+h-1, x+w-1, y+h-1, x+w-1, y );
+ p->setPen( c2 );
+ p->drawPolyline( a );
+ if ( w > 4 && h > 4 ) {
+ a.setPoints( 3, x+1, y+h-3, x+1, y+1, x+w-3, y+1 );
+ p->setPen( c3 );
+ p->drawPolyline( a );
+ a.setPoints( 3, x+1, y+h-2, x+w-2, y+h-2, x+w-2, y+1 );
+ p->setPen( c4 );
+ p->drawPolyline( a );
+ if ( fill ) {
+ TQBrush oldBrush = p->brush();
+ p->setBrush( *fill );
+ p->setPen( TQt::NoPen );
+ p->drawRect( x+2, y+2, w-4, h-4 );
+ p->setBrush( oldBrush );
+ }
+ }
+ p->setPen( oldPen );
+}
+
+
+/*!
+ \relates TQPainter
+
+ \c{#include <tqdrawutil.h>}
+
+ Draws the Windows-style button specified by (\a x, \a y, \a w, \a
+ h) using the painter \a p.
+
+ The color group argument \a g specifies the shading colors (\link
+ TQColorGroup::light() light\endlink, \link TQColorGroup::dark()
+ dark\endlink and \link TQColorGroup::mid() middle\endlink colors).
+
+ The button appears sunken if \a sunken is TRUE, or raised if \a
+ sunken is FALSE.
+
+ The line width is 2 pixels.
+
+ The button's interior is filled with the \a *fill brush unless \a
+ fill is 0.
+
+ \warning This function does not look at TQWidget::style() or
+ TQApplication::style(). Use the drawing functions in TQStyle to make
+ widgets that follow the current GUI style.
+
+ \sa qDrawWinPanel(), TQStyle::tqdrawControl()
+*/
+
+void qDrawWinButton( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool sunken,
+ const TQBrush *fill )
+{
+ if ( sunken )
+ qDrawWinShades( p, x, y, w, h,
+ g.shadow(), g.light(), g.dark(), g.button(), fill );
+ else
+ qDrawWinShades( p, x, y, w, h,
+ g.light(), g.shadow(), g.button(), g.dark(), fill );
+}
+
+/*!
+ \relates TQPainter
+
+ \c{#include <tqdrawutil.h>}
+
+ Draws the Windows-style panel specified by (\a x, \a y, \a w, \a
+ h) using the painter \a p.
+
+ The color group argument \a g specifies the shading colors.
+
+ The panel appears sunken if \a sunken is TRUE, or raised if \a
+ sunken is FALSE.
+
+ The line width is 2 pixels.
+
+ The button's interior is filled with the \a fill brush unless \a
+ fill is 0.
+
+ If you want to use a TQFrame widget instead, you can make it
+ display a shaded panel, for example \c{TQFrame::setFrameStyle(
+ TQFrame::WinPanel | TQFrame::Raised )}.
+
+ \warning This function does not look at TQWidget::style() or
+ TQApplication::style(). Use the drawing functions in TQStyle to make
+ widgets that follow the current GUI style.
+
+ \sa qDrawShadePanel(), qDrawWinButton(), TQStyle::drawPrimitive()
+*/
+
+void qDrawWinPanel( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool sunken,
+ const TQBrush *fill )
+{
+ if ( sunken )
+ qDrawWinShades( p, x, y, w, h,
+ g.dark(), g.light(), g.shadow(), g.midlight(), fill );
+ else
+ qDrawWinShades( p, x, y, w, h,
+ g.light(), g.shadow(), g.midlight(), g.dark(), fill );
+}
+
+
+/*!
+ \relates TQPainter
+
+ \c{#include <tqdrawutil.h>}
+
+ Draws the plain rectangle specified by (\a x, \a y, \a w, \a h)
+ using the painter \a p.
+
+ The color argument \a c specifies the line color.
+
+ The \a lineWidth argument specifies the line width.
+
+ The rectangle's interior is filled with the \a fill brush unless
+ \a fill is 0.
+
+ If you want to use a TQFrame widget instead, you can make it
+ display a plain rectangle, for example \c{TQFrame::setFrameStyle(
+ TQFrame::Box | TQFrame::Plain )}.
+
+ \warning This function does not look at TQWidget::style() or
+ TQApplication::style(). Use the drawing functions in TQStyle to make
+ widgets that follow the current GUI style.
+
+ \sa qDrawShadeRect(), TQStyle::drawPrimitive()
+*/
+
+void qDrawPlainRect( TQPainter *p, int x, int y, int w, int h, const TQColor &c,
+ int lineWidth, const TQBrush *fill )
+{
+ if ( w == 0 || h == 0 )
+ return;
+ if ( !( w > 0 && h > 0 && lineWidth >= 0 ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "qDrawPlainRect() Invalid parameters." );
+#endif
+ }
+ TQPen oldPen = p->pen();
+ TQBrush oldBrush = p->brush();
+ p->setPen( c );
+ p->setBrush( TQt::NoBrush );
+ for ( int i=0; i<lineWidth; i++ )
+ p->drawRect( x+i, y+i, w-i*2, h-i*2 );
+ if ( fill ) { // fill with fill color
+ p->setPen( TQt::NoPen );
+ p->setBrush( *fill );
+ p->drawRect( x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2 );
+ }
+ p->setPen( oldPen );
+ p->setBrush( oldBrush );
+}
+
+
+TQRect qItemRect( TQPainter *p, TQt::GUIStyle gs,
+ int x, int y, int w, int h,
+ int flags,
+ bool enabled,
+ const TQPixmap *pixmap,
+ const TQString& text, int len )
+{
+ TQRect result;
+
+ if ( pixmap ) {
+ if ( (flags & TQt::AlignVCenter) == TQt::AlignVCenter )
+ y += h/2 - pixmap->height()/2;
+ else if ( (flags & TQt::AlignBottom) == TQt::AlignBottom)
+ y += h - pixmap->height();
+ if ( (flags & TQt::AlignRight) == TQt::AlignRight )
+ x += w - pixmap->width();
+ else if ( (flags & TQt::AlignHCenter) == TQt::AlignHCenter )
+ x += w/2 - pixmap->width()/2;
+ else if ( (flags & TQt::AlignLeft) != TQt::AlignLeft && TQApplication::reverseLayout() )
+ x += w - pixmap->width();
+ result = TQRect(x, y, pixmap->width(), pixmap->height());
+ } else if ( !text.isNull() && p ) {
+ result = p->boundingRect( x, y, w, h, flags, text, len );
+ if ( gs == TQt::WindowsStyle && !enabled ) {
+ result.setWidth(result.width()+1);
+ result.setHeight(result.height()+1);
+ }
+ } else {
+ result = TQRect(x, y, w, h);
+ }
+
+ return result;
+}
+
+
+void qDrawItem( TQPainter *p, TQt::GUIStyle gs,
+ int x, int y, int w, int h,
+ int flags,
+ const TQColorGroup &g, bool enabled,
+ const TQPixmap *pixmap,
+ const TQString& text, int len , const TQColor* penColor )
+{
+ p->setPen( penColor?*penColor:g.foreground() );
+ if ( pixmap ) {
+ TQPixmap pm( *pixmap );
+ bool clip = (flags & TQt::DontClip) == 0;
+ if ( clip ) {
+ if ( pm.width() < w && pm.height() < h )
+ clip = FALSE;
+ else
+ p->setClipRect( x, y, w, h );
+ }
+ if ( (flags & TQt::AlignVCenter) == TQt::AlignVCenter )
+ y += h/2 - pm.height()/2;
+ else if ( (flags & TQt::AlignBottom) == TQt::AlignBottom)
+ y += h - pm.height();
+ if ( (flags & TQt::AlignRight) == TQt::AlignRight )
+ x += w - pm.width();
+ else if ( (flags & TQt::AlignHCenter) == TQt::AlignHCenter )
+ x += w/2 - pm.width()/2;
+ else if ( ((flags & TQt::AlignLeft) != TQt::AlignLeft) && TQApplication::reverseLayout() ) // AlignAuto && rightToLeft
+ x += w - pm.width();
+
+ if ( !enabled ) {
+ if ( pm.tqmask() ) { // pixmap with a tqmask
+ if ( !pm.selfMask() ) { // tqmask is not pixmap itself
+ TQPixmap pmm( *pm.tqmask() );
+ pmm.setMask( *((TQBitmap *)&pmm) );
+ pm = pmm;
+ }
+ } else if ( pm.depth() == 1 ) { // monochrome pixmap, no tqmask
+ pm.setMask( *((TQBitmap *)&pm) );
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+ } else { // color pixmap, no tqmask
+ TQString k;
+ k.sprintf( "$qt-drawitem-%x", pm.serialNumber() );
+ TQPixmap *tqmask = TQPixmapCache::tqfind(k);
+ bool del=FALSE;
+ if ( !tqmask ) {
+ tqmask = new TQPixmap( pm.createHeuristicMask() );
+ tqmask->setMask( *((TQBitmap*)tqmask) );
+ del = !TQPixmapCache::insert( k, tqmask );
+ }
+ pm = *tqmask;
+ if (del) delete tqmask;
+#endif
+ }
+ if ( gs == TQt::WindowsStyle ) {
+ p->setPen( g.light() );
+ p->drawPixmap( x+1, y+1, pm );
+ p->setPen( g.text() );
+ }
+ }
+ p->drawPixmap( x, y, pm );
+ if ( clip )
+ p->setClipping( FALSE );
+ } else if ( !text.isNull() ) {
+ if ( gs == TQt::WindowsStyle && !enabled ) {
+ p->setPen( g.light() );
+ p->drawText( x+1, y+1, w, h, flags, text, len );
+ p->setPen( g.text() );
+ }
+ p->drawText( x, y, w, h, flags, text, len );
+ }
+}
+
+
+/*****************************************************************************
+ Overloaded functions.
+ *****************************************************************************/
+
+/*!
+ \overload void qDrawShadeLine( TQPainter *p, const TQPoint &p1, const TQPoint &p2, const TQColorGroup &g, bool sunken, int lineWidth, int midLineWidth )
+*/
+
+void qDrawShadeLine( TQPainter *p, const TQPoint &p1, const TQPoint &p2,
+ const TQColorGroup &g, bool sunken,
+ int lineWidth, int midLineWidth )
+{
+ qDrawShadeLine( p, p1.x(), p1.y(), p2.x(), p2.y(), g, sunken,
+ lineWidth, midLineWidth );
+}
+
+/*!
+ \overload void qDrawShadeRect( TQPainter *p, const TQRect &r, const TQColorGroup &g, bool sunken, int lineWidth, int midLineWidth, const TQBrush *fill )
+*/
+
+void qDrawShadeRect( TQPainter *p, const TQRect &r,
+ const TQColorGroup &g, bool sunken,
+ int lineWidth, int midLineWidth,
+ const TQBrush *fill )
+{
+ qDrawShadeRect( p, r.x(), r.y(), r.width(), r.height(), g, sunken,
+ lineWidth, midLineWidth, fill );
+}
+
+/*!
+ \overload void qDrawShadePanel( TQPainter *p, const TQRect &r, const TQColorGroup &g, bool sunken, int lineWidth, const TQBrush *fill )
+*/
+
+void qDrawShadePanel( TQPainter *p, const TQRect &r,
+ const TQColorGroup &g, bool sunken,
+ int lineWidth, const TQBrush *fill )
+{
+ qDrawShadePanel( p, r.x(), r.y(), r.width(), r.height(), g, sunken,
+ lineWidth, fill );
+}
+
+/*!
+ \overload void qDrawWinButton( TQPainter *p, const TQRect &r, const TQColorGroup &g, bool sunken, const TQBrush *fill )
+*/
+
+void qDrawWinButton( TQPainter *p, const TQRect &r,
+ const TQColorGroup &g, bool sunken,
+ const TQBrush *fill )
+{
+ qDrawWinButton( p, r.x(), r.y(), r.width(), r.height(), g, sunken, fill );
+}
+
+/*!
+ \overload void qDrawWinPanel( TQPainter *p, const TQRect &r, const TQColorGroup &g, bool sunken, const TQBrush *fill )
+*/
+
+void qDrawWinPanel( TQPainter *p, const TQRect &r,
+ const TQColorGroup &g, bool sunken,
+ const TQBrush *fill )
+{
+ qDrawWinPanel( p, r.x(), r.y(), r.width(), r.height(), g, sunken, fill );
+}
+
+/*!
+ \overload void qDrawPlainRect( TQPainter *p, const TQRect &r, const TQColor &c, int lineWidth, const TQBrush *fill )
+*/
+
+// void qDrawPlainRect( TQPainter *p, const TQRect &r, const TQColor &c,
+// int lineWidth, const TQBrush *fill )
+// {
+// qDrawPlainRect( p, r.x(), r.y(), r.width(), r.height(), c,
+// lineWidth, fill );
+// }
+
+
+static void qDrawWinArrow( TQPainter *p, TQt::ArrowType type, bool down,
+ int x, int y, int w, int h,
+ const TQColorGroup &g, bool enabled )
+{
+ TQPointArray a; // arrow polygon
+ switch ( type ) {
+ case TQt::UpArrow:
+ a.setPoints( 7, -3,1, 3,1, -2,0, 2,0, -1,-1, 1,-1, 0,-2 );
+ break;
+ case TQt::DownArrow:
+ a.setPoints( 7, -3,-1, 3,-1, -2,0, 2,0, -1,1, 1,1, 0,2 );
+ break;
+ case TQt::LeftArrow:
+ a.setPoints( 7, 1,-3, 1,3, 0,-2, 0,2, -1,-1, -1,1, -2,0 );
+ break;
+ case TQt::RightArrow:
+ a.setPoints( 7, -1,-3, -1,3, 0,-2, 0,2, 1,-1, 1,1, 2,0 );
+ break;
+ }
+ if ( a.isNull() )
+ return;
+
+ if ( down ) {
+ x++;
+ y++;
+ }
+
+ TQPen savePen = p->pen(); // save current pen
+ if (down)
+ p->setBrushOrigin(p->brushOrigin() + TQPoint(1,1));
+ p->fillRect( x, y, w, h, g.brush( TQColorGroup::Button ) );
+ if (down)
+ p->setBrushOrigin(p->brushOrigin() - TQPoint(1,1));
+ if ( enabled ) {
+ a.translate( x+w/2, y+h/2 );
+ p->setPen( g.foreground() );
+ p->drawLineSegments( a, 0, 3 ); // draw arrow
+ p->drawPoint( a[6] );
+ } else {
+ a.translate( x+w/2+1, y+h/2+1 );
+ p->setPen( g.light() );
+ p->drawLineSegments( a, 0, 3 ); // draw arrow
+ p->drawPoint( a[6] );
+ a.translate( -1, -1 );
+ p->setPen( g.mid() );
+ p->drawLineSegments( a, 0, 3 ); // draw arrow
+ p->drawPoint( a[6] );
+ }
+ p->setPen( savePen ); // restore pen
+}
+
+
+#if defined(TQ_CC_MSVC)
+#pragma warning(disable: 4244)
+#endif
+
+#ifndef TQT_NO_STYLE_MOTIF
+// motif arrows look the same whether they are used or not
+// is this correct?
+static void qDrawMotifArrow( TQPainter *p, TQt::ArrowType type, bool down,
+ int x, int y, int w, int h,
+ const TQColorGroup &g, bool )
+{
+ TQPointArray bFill; // fill polygon
+ TQPointArray bTop; // top shadow.
+ TQPointArray bBot; // bottom shadow.
+ TQPointArray bLeft; // left shadow.
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix matrix; // xform matrix
+#endif
+ bool vertical = type == TQt::UpArrow || type == TQt::DownArrow;
+ bool horizontal = !vertical;
+ int dim = w < h ? w : h;
+ int colspec = 0x0000; // color specification array
+
+ if ( dim < 2 ) // too small arrow
+ return;
+
+ if ( dim > 3 ) {
+ if ( dim > 6 )
+ bFill.resize( dim & 1 ? 3 : 4 );
+ bTop.resize( (dim/2)*2 );
+ bBot.resize( dim & 1 ? dim + 1 : dim );
+ bLeft.resize( dim > 4 ? 4 : 2 );
+ bLeft.putPoints( 0, 2, 0,0, 0,dim-1 );
+ if ( dim > 4 )
+ bLeft.putPoints( 2, 2, 1,2, 1,dim-3 );
+ bTop.putPoints( 0, 4, 1,0, 1,1, 2,1, 3,1 );
+ bBot.putPoints( 0, 4, 1,dim-1, 1,dim-2, 2,dim-2, 3,dim-2 );
+
+ for( int i=0; i<dim/2-2 ; i++ ) {
+ bTop.putPoints( i*2+4, 2, 2+i*2,2+i, 5+i*2, 2+i );
+ bBot.putPoints( i*2+4, 2, 2+i*2,dim-3-i, 5+i*2,dim-3-i );
+ }
+ if ( dim & 1 ) // odd number size: extra line
+ bBot.putPoints( dim-1, 2, dim-3,dim/2, dim-1,dim/2 );
+ if ( dim > 6 ) { // dim>6: must fill interior
+ bFill.putPoints( 0, 2, 1,dim-3, 1,2 );
+ if ( dim & 1 ) // if size is an odd number
+ bFill.setPoint( 2, dim - 3, dim / 2 );
+ else
+ bFill.putPoints( 2, 2, dim-4,dim/2-1, dim-4,dim/2 );
+ }
+ }
+ else {
+ if ( dim == 3 ) { // 3x3 arrow pattern
+ bLeft.setPoints( 4, 0,0, 0,2, 1,1, 1,1 );
+ bTop .setPoints( 2, 1,0, 1,0 );
+ bBot .setPoints( 2, 1,2, 2,1 );
+ }
+ else { // 2x2 arrow pattern
+ bLeft.setPoints( 2, 0,0, 0,1 );
+ bTop .setPoints( 2, 1,0, 1,0 );
+ bBot .setPoints( 2, 1,1, 1,1 );
+ }
+ }
+
+ if ( type == TQt::UpArrow || type == TQt::LeftArrow ) {
+#ifndef TQT_NO_TRANSFORMATIONS // #### fix me!
+ matrix.translate( x, y );
+ if ( vertical ) {
+ matrix.translate( 0, h - 1 );
+ matrix.rotate( -90 );
+ } else {
+ matrix.translate( w - 1, h - 1 );
+ matrix.rotate( 180 );
+ }
+#endif
+ if ( down )
+ colspec = horizontal ? 0x2334 : 0x2343;
+ else
+ colspec = horizontal ? 0x1443 : 0x1434;
+ }
+ else if ( type == TQt::DownArrow || type == TQt::RightArrow ) {
+#ifndef TQT_NO_TRANSFORMATIONS // #### fix me!
+ matrix.translate( x, y );
+ if ( vertical ) {
+ matrix.translate( w-1, 0 );
+ matrix.rotate( 90 );
+ }
+#endif
+ if ( down )
+ colspec = horizontal ? 0x2443 : 0x2434;
+ else
+ colspec = horizontal ? 0x1334 : 0x1343;
+ }
+
+ TQColor *cols[5];
+ cols[0] = 0;
+ cols[1] = (TQColor *)&g.button();
+ cols[2] = (TQColor *)&g.mid();
+ cols[3] = (TQColor *)&g.light();
+ cols[4] = (TQColor *)&g.dark();
+#define CMID *cols[ (colspec>>12) & 0xf ]
+#define CLEFT *cols[ (colspec>>8) & 0xf ]
+#define CTOP *cols[ (colspec>>4) & 0xf ]
+#define CBOT *cols[ colspec & 0xf ]
+
+ TQPen savePen = p->pen(); // save current pen
+ TQBrush saveBrush = p->brush(); // save current brush
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix wxm = p->tqworldMatrix();
+#endif
+ TQPen pen( TQt::NoPen );
+ const TQBrush &brush = g.brush( TQColorGroup::Button );
+
+ p->setPen( pen );
+ p->setBrush( brush );
+#ifndef TQT_NO_TRANSFORMATIONS
+ p->setWorldMatrix( matrix, TRUE ); // set transformation matrix
+#endif
+ p->drawPolygon( bFill ); // fill arrow
+ p->setBrush( TQt::NoBrush ); // don't fill
+
+ p->setPen( CLEFT );
+ p->drawLineSegments( bLeft );
+ p->setPen( CTOP );
+ p->drawLineSegments( bTop );
+ p->setPen( CBOT );
+ p->drawLineSegments( bBot );
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ p->setWorldMatrix( wxm );
+#endif
+ p->setBrush( saveBrush ); // restore brush
+ p->setPen( savePen ); // restore pen
+
+#undef CMID
+#undef CLEFT
+#undef CTOP
+#undef CBOT
+}
+#endif
+
+void qDrawArrow( TQPainter *p, TQt::ArrowType type, TQt::GUIStyle style, bool down,
+ int x, int y, int w, int h,
+ const TQColorGroup &g, bool enabled )
+{
+ switch ( style ) {
+ case TQt::WindowsStyle:
+ qDrawWinArrow( p, type, down, x, y, w, h, g, enabled );
+ break;
+#ifndef TQT_NO_STYLE_MOTIF
+ case TQt::MotifStyle:
+ qDrawMotifArrow( p, type, down, x, y, w, h, g, enabled );
+ break;
+#endif
+ default:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "qDrawArrow: Requested GUI style not supported" );
+#else
+ ;
+#endif
+ }
+}
+#endif //TQT_NO_DRAWUTIL
diff --git a/tqtinterface/qt4/src/kernel/tqdrawutil.h b/tqtinterface/qt4/src/kernel/tqdrawutil.h
new file mode 100644
index 0000000..b92d5d9
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqdrawutil.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Definition of draw utilities
+**
+** Created : 950920
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDRAWUTIL_H
+#define TQDRAWUTIL_H
+
+#ifndef TQT_H
+#include "tqnamespace.h"
+#include "tqstring.h" // char*->TQString conversion
+#endif // TQT_H
+
+class TQPainter;
+class TQColorGroup;
+class TQPoint;
+class TQBrush;
+class TQRect;
+class TQPixmap;
+
+#ifndef TQT_NO_DRAWUTIL
+//
+// Standard shade drawing
+//
+
+TQ_EXPORT void qDrawShadeLine( TQPainter *p, int x1, int y1, int x2, int y2,
+ const TQColorGroup &g, bool sunken = TRUE,
+ int lineWidth = 1, int midLineWidth = 0 );
+
+TQ_EXPORT void qDrawShadeLine( TQPainter *p, const TQPoint &p1, const TQPoint &p2,
+ const TQColorGroup &g, bool sunken = TRUE,
+ int lineWidth = 1, int midLineWidth = 0 );
+
+TQ_EXPORT void qDrawShadeRect( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &, bool sunken=FALSE,
+ int lineWidth = 1, int midLineWidth = 0,
+ const TQBrush *fill = 0 );
+
+TQ_EXPORT void qDrawShadeRect( TQPainter *p, const TQRect &r,
+ const TQColorGroup &, bool sunken=FALSE,
+ int lineWidth = 1, int midLineWidth = 0,
+ const TQBrush *fill = 0 );
+
+TQ_EXPORT void qDrawShadePanel( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &, bool sunken=FALSE,
+ int lineWidth = 1, const TQBrush *fill = 0 );
+
+TQ_EXPORT void qDrawShadePanel( TQPainter *p, const TQRect &r,
+ const TQColorGroup &, bool sunken=FALSE,
+ int lineWidth = 1, const TQBrush *fill = 0 );
+
+TQ_EXPORT void qDrawWinButton( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool sunken = FALSE,
+ const TQBrush *fill = 0 );
+
+TQ_EXPORT void qDrawWinButton( TQPainter *p, const TQRect &r,
+ const TQColorGroup &g, bool sunken = FALSE,
+ const TQBrush *fill = 0 );
+
+TQ_EXPORT void qDrawWinPanel( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &, bool sunken=FALSE,
+ const TQBrush *fill = 0 );
+
+TQ_EXPORT void qDrawWinPanel( TQPainter *p, const TQRect &r,
+ const TQColorGroup &, bool sunken=FALSE,
+ const TQBrush *fill = 0 );
+
+TQ_EXPORT void qDrawPlainRect( TQPainter *p, int x, int y, int w, int h, const TQColor &,
+ int lineWidth = 1, const TQBrush *fill = 0 );
+
+// TQ_EXPORT void qDrawPlainRect( TQPainter *p, const TQRect &r, const TQColor &,
+// int lineWidth = 1, const TQBrush *fill = 0 );
+
+
+//
+// Other obsolete drawing functions.
+// Use TQStyle::tqitemRect(), TQStyle::drawItem() and TQStyle::drawArrow() instead.
+//
+TQ_EXPORT TQRect qItemRect( TQPainter *p, TQt::GUIStyle gs, int x, int y, int w, int h,
+ int flags, bool enabled,
+ const TQPixmap *pixmap, const TQString& text, int len=-1 );
+
+TQ_EXPORT void qDrawItem( TQPainter *p, TQt::GUIStyle gs, int x, int y, int w, int h,
+ int flags, const TQColorGroup &g, bool enabled,
+ const TQPixmap *pixmap, const TQString& text,
+ int len=-1, const TQColor* penColor = 0 );
+
+TQ_EXPORT void qDrawArrow( TQPainter *p, TQt::ArrowType type, TQt::GUIStyle style, bool down,
+ int x, int y, int w, int h,
+ const TQColorGroup &g, bool enabled );
+
+#endif // TQT_NO_DRAWUTIL
+#endif // TQDRAWUTIL_H
diff --git a/tqtinterface/qt4/src/kernel/tqdropsite.cpp b/tqtinterface/qt4/src/kernel/tqdropsite.cpp
new file mode 100644
index 0000000..60645b9
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqdropsite.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Implementation of Drag and Drop support
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdropsite.h"
+
+#ifndef TQT_NO_DRAGANDDROP
+
+#include "tqwidget.h"
+
+
+// NOT REVISED
+/*!
+ \class TQDropSite tqdropsite.h
+ \brief The TQDropSite class provides nothing and does nothing.
+
+ \obsolete
+
+ If your code uses it, you can safely delete it.
+
+ It was used in TQt 1.x to do some drag and drop; that has since been
+ folded into TQWidget.
+
+ For detailed information about drag-and-drop, see the TQDragObject class.
+
+ \sa TQDragObject, TQTextDrag, TQImageDrag
+*/
+
+/*!
+ Constructs a TQDropSite to handle events for the widget \a self.
+
+ Pass \c this as the \a self parameter.
+ This enables dropping by calling TQWidget::setAcceptDrops(TRUE).
+*/
+TQDropSite::TQDropSite( TQWidget* self )
+{
+ self->setAcceptDrops( TRUE );
+}
+
+/*!
+ Destroys the drop site.
+*/
+TQDropSite::~TQDropSite()
+{
+}
+
+#endif // TQT_NO_DRAGANDDROP
diff --git a/tqtinterface/qt4/src/kernel/tqdropsite.h b/tqtinterface/qt4/src/kernel/tqdropsite.h
new file mode 100644
index 0000000..cd650fa
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqdropsite.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Definitation of Drag and Drop support
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDROPSITE_H
+#define TQDROPSITE_H
+
+#ifndef TQT_H
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+#endif
+
+
+class TQWidget;
+
+
+class TQ_EXPORT TQDropSite {
+public:
+ TQDropSite( TQWidget* tqparent );
+ virtual ~TQDropSite();
+};
+
+
+#endif // TQDROPSITE_H
diff --git a/tqtinterface/qt4/src/kernel/tqevent.cpp b/tqtinterface/qt4/src/kernel/tqevent.cpp
new file mode 100644
index 0000000..b34f38d
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqevent.cpp
@@ -0,0 +1,2708 @@
+/****************************************************************************
+**
+** Implementation of event classes
+**
+** Created : 931029
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <tqtglobaldefines.h>
+#ifdef USE_QT4
+// Nasty, nasty horrid HACK to get access to QFont's private members
+// This is TERRIBLE and I wish there was a way around it
+// See also QRect
+#define private protected
+#include <Qt/qevent.h>
+#undef private
+#endif // USE_QT4
+
+#include "tqevent.h"
+#include "tqcursor.h"
+#include "tqapplication.h"
+
+#ifdef USE_QT4
+
+// TQFocusEvent::Reason TQFocusEvent::prev_reason = TQFocusEvent::Other;
+
+/*!
+ Sets the reason for all future focus events to \a reason.
+
+ \sa reason(), resetReason()
+ */
+void TQFocusEvent::setReason( Qt::FocusReason reason )
+{
+ prev_reason = m_reason;
+ m_reason = reason;
+}
+
+/*!
+ Resets the reason for all future focus events to the value before
+ the last setReason() call.
+
+ \sa reason(), setReason()
+ */
+void TQFocusEvent::resetReason()
+{
+ m_reason = prev_reason;
+}
+
+TQt::ButtonState TQContextMenuEvent::state() const {
+ return TQt::ButtonState(int(QApplication::keyboardModifiers())|QApplication::mouseButtons());
+}
+
+/*!
+ \class TQCustomEvent tqevent.h
+ \brief The TQCustomEvent class provides support for custom events.
+
+ \ingroup events
+
+ TQCustomEvent is a generic event class for user-defined events.
+ User defined events can be sent to widgets or other TQObject
+ instances using TQApplication::postEvent() or
+ TQApplication::sendEvent(). Subclasses of TQObject can easily
+ receive custom events by implementing the TQObject::customEvent()
+ event handler function.
+
+ TQCustomEvent objects should be created with a type ID that
+ uniquely identifies the event type. To avoid clashes with the
+ TQt-defined events types, the value should be at least as large as
+ the value of the "User" entry in the TQEvent::Type enum.
+
+ TQCustomEvent tqcontains a generic void* data member that may be used
+ for transferring event-specific data to the receiver. Note that
+ since events are normally delivered asynchronously, the data
+ pointer, if used, must remain valid until the event has been
+ received and processed.
+
+ TQCustomEvent can be used as-is for simple user-defined event
+ types, but normally you will want to make a subclass of it for
+ your event types. In a subclass, you can add data members that are
+ suitable for your event type.
+
+ Example:
+ \code
+ class ColorChangeEvent : public TQCustomEvent
+ {
+ public:
+ ColorChangeEvent( TQColor color )
+ : TQCustomEvent( 65432 ), c( color ) {}
+ TQColor color() const { return c; }
+ private:
+ TQColor c;
+ };
+
+ // To send an event of this custom event type:
+
+ ColorChangeEvent* ce = new ColorChangeEvent( blue );
+ TQApplication::postEvent( receiver, ce ); // TQt will delete it when done
+
+ // To receive an event of this custom event type:
+
+ void MyWidget::customEvent( TQCustomEvent * e )
+ {
+ if ( e->type() == 65432 ) { // It must be a ColorChangeEvent
+ ColorChangeEvent* ce = (ColorChangeEvent*)e;
+ newColor = ce->color();
+ }
+ }
+ \endcode
+
+ \sa TQWidget::customEvent(), TQApplication::notify()
+*/
+
+
+/*!
+ Constructs a custom event object with event type \a type. The
+ value of \a type must be at least as large as TQEvent::User. The
+ data pointer is set to 0.
+*/
+
+TQCustomEvent::TQCustomEvent( int type )
+ : TQEvent( (TQEvent::Type)type ), d( 0 )
+{
+}
+
+
+/*!
+ \fn TQCustomEvent::TQCustomEvent( Type type, void *data )
+
+ Constructs a custom event object with the event type \a type and a
+ pointer to \a data. (Note that any int value may safely be cast to
+ TQEvent::Type).
+*/
+
+
+/*!
+ \fn void TQCustomEvent::setData( void* data )
+
+ Sets the generic data pointer to \a data.
+
+ \sa data()
+*/
+
+/*!
+ \fn void *TQCustomEvent::data() const
+
+ Returns a pointer to the generic event data.
+
+ \sa setData()
+*/
+
+#else // USE_QT4
+
+/*!
+ \class TQEvent tqevent.h
+ \brief The TQEvent class is the base class of all
+ event classes. Event objects contain event parameters.
+
+ \ingroup events
+ \ingroup environment
+
+ TQt's main event loop (TQApplication::exec()) fetches native window
+ system events from the event queue, translates them into TQEvents
+ and sends the translated events to TQObjects.
+
+ In general, events come from the underlying window system
+ (spontaneous() returns TRUE) but it is also possible to manually
+ send events using TQApplication::sendEvent() and
+ TQApplication::postEvent() (spontaneous() returns FALSE).
+
+ TQObjects receive events by having their TQObject::event() function
+ called. The function can be reimplemented in subclasses to
+ customize event handling and add additional event types;
+ TQWidget::event() is a notable example. By default, events are
+ dispatched to event handlers like TQObject::timerEvent() and
+ TQWidget::mouseMoveEvent(). TQObject::installEventFilter() allows an
+ object to intercept events destined for another object.
+
+ The basic TQEvent tqcontains only an event type parameter.
+ Subclasses of TQEvent contain additional parameters that describe
+ the particular event.
+
+ \sa TQObject::event() TQObject::installEventFilter()
+ TQWidget::event() TQApplication::sendEvent()
+ TQApplication::postEvent() TQApplication::processEvents()
+*/
+
+
+/*!
+ \enum TQt::ButtonState
+
+ This enum type describes the state of the mouse and the modifier
+ buttons.
+
+ \value NoButton used when the button state does not refer to any
+ button (see TQMouseEvent::button()).
+ \value LeftButton set if the left button is pressed, or if this
+ event refers to the left button. (The left button may be
+ the right button on left-handed mice.)
+ \value RightButton the right button.
+ \value MidButton the middle button.
+ \value ShiftButton a Shift key on the keyboard is also pressed.
+ \value ControlButton a Ctrl key on the keyboard is also pressed.
+ \value AltButton an Alt key on the keyboard is also pressed.
+ \value MetaButton a Meta key on the keyboard is also pressed.
+ \value Keypad a keypad button is pressed.
+ \value KeyButtonMask a tqmask for ShiftButton, ControlButton,
+ AltButton and MetaButton.
+ \value MouseButtonMask a tqmask for LeftButton, RightButton and MidButton.
+*/
+
+/*!
+ \enum TQEvent::Type
+
+ This enum type defines the valid event types in TQt. The event
+ types and the specialized classes for each type are these:
+
+ \value None Not an event.
+ \value Accessibility Accessibility information is requested
+ \value Timer Regular timer events, \l{TQTimerEvent}.
+ \value MouseButtonPress Mouse press, \l{TQMouseEvent}.
+ \value MouseButtonRelease Mouse release, \l{TQMouseEvent}.
+ \value MouseButtonDblClick Mouse press again, \l{TQMouseEvent}.
+ \value MouseMove Mouse move, \l{TQMouseEvent}.
+ \value KeyPress Key press (including Shift, for example), \l{TQKeyEvent}.
+ \value KeyRelease Key release, \l{TQKeyEvent}.
+ \value IMStart The start of input method composition, \l{TQIMEvent}.
+ \value IMCompose Input method composition is taking place, \l{TQIMEvent}.
+ \value IMEnd The end of input method composition, \l{TQIMEvent}.
+ \value FocusIn Widget gains keyboard focus, \l{TQFocusEvent}.
+ \value FocusOut Widget loses keyboard focus, \l{TQFocusEvent}.
+ \value Enter Mouse enters widget's boundaries.
+ \value Leave Mouse leaves widget's boundaries.
+ \value Paint Screen update necessary, \l{TQPaintEvent}.
+ \value Move Widget's position changed, \l{TQMoveEvent}.
+ \value Resize Widget's size changed, \l{TQResizeEvent}.
+ \value Show Widget was shown on screen, \l{TQShowEvent}.
+ \value Hide Widget was hidden, \l{TQHideEvent}.
+ \value ShowToParent A child widget has been shown.
+ \value HideToParent A child widget has been hidden.
+ \value Close Widget was closed (permanently), \l{TQCloseEvent}.
+ \value ShowNormal Widget should be shown normally (obsolete).
+ \value ShowMaximized Widget should be shown maximized (obsolete).
+ \value ShowMinimized Widget should be shown minimized (obsolete).
+ \value ShowFullScreen Widget should be shown full-screen (obsolete).
+ \value ShowWindowRequest Widget's window should be shown (obsolete).
+ \value DeferredDelete The object will be deleted after it has
+ cleaned up.
+ \value Accel Key press in child for shortcut key handling, \l{TQKeyEvent}.
+ \value Wheel Mouse wheel rolled, \l{TQWheelEvent}.
+ \value ContextMenu Context popup menu, \l{TQContextMenuEvent}
+ \value AccelOverride Key press in child, for overriding shortcut key handling, \l{TQKeyEvent}.
+ \value AccelAvailable internal.
+ \value WindowActivate Window was activated.
+ \value WindowDeactivate Window was deactivated.
+ \value CaptionChange Widget's caption changed.
+ \value IconChange Widget's icon changed.
+ \value ParentFontChange Font of the tqparent widget changed.
+ \value ApplicationFontChange Default application font changed.
+ \value PaletteChange Palette of the widget changed.
+ \value ParentPaletteChange Palette of the tqparent widget changed.
+ \value ApplicationPaletteChange Default application palette changed.
+ \value Clipboard Clipboard contents have changed.
+ \value SockAct Socket activated, used to implement \l{TQSocketNotifier}.
+ \value DragEnter A drag-and-drop enters widget, \l{TQDragEnterEvent}.
+ \value DragMove A drag-and-drop is in progress, \l{TQDragMoveEvent}.
+ \value DragLeave A drag-and-drop leaves widget, \l{TQDragLeaveEvent}.
+ \value Drop A drag-and-drop is completed, \l{TQDropEvent}.
+ \value DragResponse Internal event used by TQt on some platforms.
+ \value ChildInserted Object gets a child, \l{TQChildEvent}.
+ \value ChildRemoved Object loses a child, \l{TQChildEvent}.
+ \value LayoutHint Widget child has changed tqlayout properties.
+ \value ActivateControl Internal event used by TQt on some platforms.
+ \value DeactivateControl Internal event used by TQt on some platforms.
+ \value LanguageChange The application translation changed, \l{TQTranslator}
+ \value LayoutDirectionChange The direction of layouts changed
+ \value LocaleChange The system locale changed
+ \value Quit Reserved.
+ \value Create Reserved.
+ \value Destroy Reserved.
+ \value Retqparent Reserved.
+ \value Speech Reserved for speech input.
+ \value TabletMove A Wacom Tablet Move Event.
+ \value Style Internal use only
+ \value TabletPress A Wacom Tablet Press Event
+ \value TabletRelease A Wacom Tablet Release Event
+ \value OkRequest Internal event used by TQt on some platforms.
+ \value HelpRequest Internal event used by TQt on some platforms.
+ \value IconDrag Internal event used by TQt on some platforms when proxy icon is dragged.
+ \value WindowStateChange The window's state, i.e. minimized,
+ maximized or full-screen, has changed. See \l{TQWidget::windowState()}.
+ \value WindowBlocked The window is modally blocked
+ \value WindowUnblocked The window leaves modal blocking
+
+ \value User User defined event.
+ \value MaxUser Last user event id.
+
+ User events should have values between User and MaxUser inclusive.
+*/
+/*!
+ \fn TQEvent::TQEvent( Type type )
+
+ Contructs an event object of type \a type.
+*/
+
+/*!
+ \fn TQEvent::Type TQEvent::type() const
+
+ Returns the event type.
+*/
+
+/*!
+ \fn bool TQEvent::spontaneous() const
+
+ Returns TRUE if the event originated outside the application, i.e.
+ it is a system event; otherwise returns FALSE.
+*/
+
+
+/*!
+ \class TQTimerEvent tqevent.h
+ \brief The TQTimerEvent class tqcontains parameters that describe a
+ timer event.
+
+ \ingroup events
+
+ Timer events are sent at regular intervals to objects that have
+ started one or more timers. Each timer has a unique identifier. A
+ timer is started with TQObject::startTimer().
+
+ The TQTimer class provides a high-level programming interface that
+ uses Q_SIGNALS instead of events. It also provides one-shot timers.
+
+ The event handler TQObject::timerEvent() receives timer events.
+
+ \sa TQTimer, TQObject::timerEvent(), TQObject::startTimer(),
+ TQObject::killTimer(), TQObject::killTimers()
+*/
+
+/*!
+ \fn TQTimerEvent::TQTimerEvent( int timerId )
+
+ Constructs a timer event object with the timer identifier set to
+ \a timerId.
+*/
+
+/*!
+ \fn int TQTimerEvent::timerId() const
+
+ Returns the unique timer identifier, which is the same identifier
+ as returned from TQObject::startTimer().
+*/
+
+
+/*!
+ \class TQMouseEvent tqevent.h
+ \ingroup events
+
+ \brief The TQMouseEvent class tqcontains parameters that describe a mouse event.
+
+ Mouse events occur when a mouse button is pressed or released
+ inside a widget or when the mouse cursor is moved.
+
+ Mouse move events will occur only when a mouse button is pressed
+ down, unless mouse tracking has been enabled with
+ TQWidget::setMouseTracking().
+
+ TQt automatically grabs the mouse when a mouse button is pressed
+ inside a widget; the widget will continue to receive mouse events
+ until the last mouse button is released.
+
+ A mouse event tqcontains a special accept flag that indicates
+ whether the receiver wants the event. You should call
+ TQMouseEvent::ignore() if the mouse event is not handled by your
+ widget. A mouse event is propagated up the tqparent widget chain
+ until a widget accepts it with TQMouseEvent::accept() or an event
+ filter consumes it.
+
+ The functions pos(), x() and y() give the cursor position relative
+ to the widget that receives the mouse event. If you move the
+ widget as a result of the mouse event, use the global position
+ returned by globalPos() to avoid a shaking motion.
+
+ The TQWidget::setEnabled() function can be used to enable or
+ disable mouse and keyboard events for a widget.
+
+ The event handlers TQWidget::mousePressEvent(),
+ TQWidget::mouseReleaseEvent(), TQWidget::mouseDoubleClickEvent() and
+ TQWidget::mouseMoveEvent() receive mouse events.
+
+ \sa TQWidget::setMouseTracking(), TQWidget::grabMouse(),
+ TQCursor::pos()
+*/
+
+/*!
+ \fn TQMouseEvent::TQMouseEvent( Type type, const TQPoint &pos, int button, int state )
+
+ Constructs a mouse event object.
+
+ The \a type parameter must be one of \c TQEvent::MouseButtonPress,
+ \c TQEvent::MouseButtonRelease, \c TQEvent::MouseButtonDblClick or
+ \c TQEvent::MouseMove.
+
+ The \a pos parameter specifies the position relative to the
+ receiving widget. \a button specifies the \link TQt::ButtonState
+ button\endlink that caused the event, which should be \c
+ TQt::NoButton (0), if \a type is \c MouseMove. \a state is the
+ \link TQt::ButtonState ButtonState\endlink at the time of the
+ event.
+
+ The globalPos() is initialized to TQCursor::pos(), which may not be
+ appropriate. Use the other constructor to specify the global
+ position explicitly.
+*/
+
+TQMouseEvent::TQMouseEvent( Type type, const TQPoint &pos, int button, int state )
+ : TQEvent(type), p(pos), b(button),s((ushort)state), accpt(TRUE){
+ g = TQCursor::pos();
+}
+
+
+/*!
+ \fn TQMouseEvent::TQMouseEvent( Type type, const TQPoint &pos, const TQPoint &globalPos, int button, int state )
+
+ Constructs a mouse event object.
+
+ The \a type parameter must be \c TQEvent::MouseButtonPress, \c
+ TQEvent::MouseButtonRelease, \c TQEvent::MouseButtonDblClick or \c
+ TQEvent::MouseMove.
+
+ The \a pos parameter specifies the position relative to the
+ receiving widget. \a globalPos is the position in absolute
+ coordinates. \a button specifies the \link TQt::ButtonState
+ button\endlink that caused the event, which should be \c
+ TQt::NoButton (0), if \a type is \c MouseMove. \a state is the
+ \link TQt::ButtonState ButtonState\endlink at the time of the
+ event.
+
+*/
+
+/*!
+ \fn const TQPoint &TQMouseEvent::pos() const
+
+ Returns the position of the mouse pointer relative to the widget
+ that received the event.
+
+ If you move the widget as a result of the mouse event, use the
+ global position returned by globalPos() to avoid a shaking motion.
+
+ \sa x(), y(), globalPos()
+*/
+
+/*!
+ \fn const TQPoint &TQMouseEvent::globalPos() const
+
+ Returns the global position of the mouse pointer \e{at the time
+ of the event}. This is important on asynchronous window systems
+ like X11. Whenever you move your widgets around in response to
+ mouse events, globalPos() may differ a lot from the current
+ pointer position TQCursor::pos(), and from TQWidget::mapToGlobal(
+ pos() ).
+
+ \sa globalX(), globalY()
+*/
+
+/*!
+ \fn int TQMouseEvent::x() const
+
+ Returns the x-position of the mouse pointer, relative to the
+ widget that received the event.
+
+ \sa y(), pos()
+*/
+
+/*!
+ \fn int TQMouseEvent::y() const
+
+ Returns the y-position of the mouse pointer, relative to the
+ widget that received the event.
+
+ \sa x(), pos()
+*/
+
+/*!
+ \fn int TQMouseEvent::globalX() const
+
+ Returns the global x-position of the mouse pointer at the time of
+ the event.
+
+ \sa globalY(), globalPos()
+*/
+
+/*!
+ \fn int TQMouseEvent::globalY() const
+
+ Returns the global y-position of the mouse pointer at the time of
+ the event.
+
+ \sa globalX(), globalPos()
+*/
+
+/*!
+ \fn ButtonState TQMouseEvent::button() const
+
+ Returns the button that caused the event.
+
+ Possible return values are \c LeftButton, \c RightButton, \c
+ MidButton and \c NoButton.
+
+ Note that the returned value is always \c NoButton for mouse move
+ events.
+
+ \sa state() TQt::ButtonState
+*/
+
+
+/*!
+ \fn ButtonState TQMouseEvent::state() const
+
+ Returns the button state (a combination of mouse buttons and
+ keyboard modifiers), i.e. what buttons and keys were being pressed
+ immediately before the event was generated.
+
+ This means that if you have a \c TQEvent::MouseButtonPress or a \c
+ TQEvent::MouseButtonDblClick state() will \e not include the mouse
+ button that's pressed. But once the mouse button has been
+ released, the \c TQEvent::MouseButtonRelease event will have the
+ button() that was pressed.
+
+ This value is mainly interesting for \c TQEvent::MouseMove; for the
+ other cases, button() is more useful.
+
+ The returned value is \c LeftButton, \c RightButton, \c MidButton,
+ \c ShiftButton, \c ControlButton and \c AltButton OR'ed together.
+
+ \sa button() stateAfter() TQt::ButtonState
+*/
+
+/*!
+ \fn ButtonState TQMouseEvent::stateAfter() const
+
+ Returns the state of buttons after the event.
+
+ \sa state() TQt::ButtonState
+*/
+TQt::ButtonState TQMouseEvent::stateAfter() const
+{
+ return TQt::ButtonState(state()^button());
+}
+
+
+
+/*!
+ \fn bool TQMouseEvent::isAccepted() const
+
+ Returns TRUE if the receiver of the event wants to keep the key;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn void TQMouseEvent::accept()
+
+ Sets the accept flag of the mouse event object.
+
+ Setting the accept parameter indicates that the receiver of the
+ event wants the mouse event. Unwanted mouse events are sent to the
+ tqparent widget.
+
+ The accept flag is set by default.
+
+ \sa ignore()
+*/
+
+
+/*!
+ \fn void TQMouseEvent::ignore()
+
+ Clears the accept flag parameter of the mouse event object.
+
+ Clearing the accept parameter indicates that the event receiver
+ does not want the mouse event. Unwanted mouse events are sent to
+ the tqparent widget.
+
+ The accept flag is set by default.
+
+ \sa accept()
+*/
+
+
+/*!
+ \class TQWheelEvent tqevent.h
+ \brief The TQWheelEvent class tqcontains parameters that describe a wheel event.
+
+ \ingroup events
+
+ Wheel events are sent to the widget under the mouse, and if that widget
+ does not handle the event they are sent to the focus widget. The rotation
+ distance is provided by delta(). The functions pos() and globalPos() return
+ the mouse pointer location at the time of the event.
+
+ A wheel event tqcontains a special accept flag that indicates
+ whether the receiver wants the event. You should call
+ TQWheelEvent::accept() if you handle the wheel event; otherwise it
+ will be sent to the tqparent widget.
+
+ The TQWidget::setEnable() function can be used to enable or disable
+ mouse and keyboard events for a widget.
+
+ The event handler TQWidget::wheelEvent() receives wheel events.
+
+ \sa TQMouseEvent, TQWidget::grabMouse()
+*/
+
+/*!
+ \fn Orientation TQWheelEvent::orientation() const
+
+ Returns the wheel's orientation.
+*/
+
+/*!
+ \fn TQWheelEvent::TQWheelEvent( const TQPoint &pos, int delta, int state, Orientation orient = Vertical );
+
+ Constructs a wheel event object.
+
+ The globalPos() is initialized to TQCursor::pos(), i.e. \a pos,
+ which is usually (but not always) right. Use the other constructor
+ if you need to specify the global position explicitly. \a delta
+ tqcontains the rotation distance, \a state holds the keyboard
+ modifier flags at the time of the event and \a orient holds the
+ wheel's orientation.
+
+ \sa pos(), delta(), state()
+*/
+#ifndef TQT_NO_WHEELEVENT
+TQWheelEvent::TQWheelEvent( const TQPoint &pos, int delta, int state, Orientation orient )
+ : TQEvent(Wheel), p(pos), d(delta), s((ushort)state),
+ accpt(TRUE), o(orient)
+{
+ g = TQCursor::pos();
+}
+#endif
+/*!
+ \fn TQWheelEvent::TQWheelEvent( const TQPoint &pos, const TQPoint& globalPos, int delta, int state, Orientation orient = Vertical )
+
+ Constructs a wheel event object. The position when the event
+ occurred is given in \a pos and \a globalPos. \a delta tqcontains
+ the rotation distance, \a state holds the keyboard modifier flags
+ at the time of the event and \a orient holds the wheel's
+ orientation.
+
+ \sa pos(), globalPos(), delta(), state()
+*/
+
+/*!
+ \fn int TQWheelEvent::delta() const
+
+ Returns the distance that the wheel is rotated expressed in
+ multiples or divisions of the \e{wheel delta}, which is currently
+ defined to be 120. A positive value indicates that the wheel was
+ rotated forwards away from the user; a negative value indicates
+ that the wheel was rotated backwards toward the user.
+
+ The \e{wheel delta} constant was defined to be 120 by wheel mouse
+ vendors to allow building finer-resolution wheels in the future,
+ including perhaps a freely rotating wheel with no notches. The
+ expectation is that such a tqdevice would send more messages per
+ rotation but with a smaller value in each message.
+*/
+
+/*!
+ \fn const TQPoint &TQWheelEvent::pos() const
+
+ Returns the position of the mouse pointer, relative to the widget
+ that received the event.
+
+ If you move your widgets around in response to mouse
+ events, use globalPos() instead of this function.
+
+ \sa x(), y(), globalPos()
+*/
+
+/*!
+ \fn int TQWheelEvent::x() const
+
+ Returns the x-position of the mouse pointer, relative to the
+ widget that received the event.
+
+ \sa y(), pos()
+*/
+
+/*!
+ \fn int TQWheelEvent::y() const
+
+ Returns the y-position of the mouse pointer, relative to the
+ widget that received the event.
+
+ \sa x(), pos()
+*/
+
+
+/*!
+ \fn const TQPoint &TQWheelEvent::globalPos() const
+
+ Returns the global position of the mouse pointer \e{at the time
+ of the event}. This is important on asynchronous window systems
+ such as X11; whenever you move your widgets around in response to
+ mouse events, globalPos() can differ a lot from the current
+ pointer position TQCursor::pos().
+
+ \sa globalX(), globalY()
+*/
+
+/*!
+ \fn int TQWheelEvent::globalX() const
+
+ Returns the global x-position of the mouse pointer at the time of
+ the event.
+
+ \sa globalY(), globalPos()
+*/
+
+/*!
+ \fn int TQWheelEvent::globalY() const
+
+ Returns the global y-position of the mouse pointer at the time of
+ the event.
+
+ \sa globalX(), globalPos()
+*/
+
+
+/*!
+ \fn ButtonState TQWheelEvent::state() const
+
+ Returns the keyboard modifier flags of the event.
+
+ The returned value is \c ShiftButton, \c ControlButton, and \c
+ AltButton OR'ed together.
+*/
+
+/*!
+ \fn bool TQWheelEvent::isAccepted() const
+
+ Returns TRUE if the receiver of the event handles the wheel event;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn void TQWheelEvent::accept()
+
+ Sets the accept flag of the wheel event object.
+
+ Setting the accept parameter indicates that the receiver of the
+ event wants the wheel event. Unwanted wheel events are sent to the
+ tqparent widget.
+
+ The accept flag is set by default.
+
+ \sa ignore()
+*/
+
+/*!
+ \fn void TQWheelEvent::ignore()
+
+ Clears the accept flag parameter of the wheel event object.
+
+ Clearing the accept parameter indicates that the event receiver
+ does not want the wheel event. Unwanted wheel events are sent to
+ the tqparent widget. The accept flag is set by default.
+
+ \sa accept()
+*/
+
+
+/*!
+ \enum TQt::Modifier
+
+ This enum type describes the keyboard modifier keys supported by
+ TQt.
+
+ \value SHIFT the Shift keys provided on all standard keyboards.
+ \value META the Meta keys.
+ \value CTRL the Ctrl keys.
+ \value ALT the normal Alt keys, but not e.g. AltGr.
+ \value MODIFIER_MASK is a tqmask of Shift, Ctrl, Alt and Meta.
+ \value UNICODE_ACCEL the accelerator is specified as a Unicode code
+ point, not as a TQt Key.
+*/
+
+/*!
+ \class TQKeyEvent tqevent.h
+ \brief The TQKeyEvent class tqcontains describes a key event.
+
+ \ingroup events
+
+ Key events occur when a key is pressed or released when a widget
+ has keyboard input focus.
+
+ A key event tqcontains a special accept flag that indicates whether the
+ receiver wants the key event. You should call TQKeyEvent::ignore() if the
+ key press or release event is not handled by your widget. A key event is
+ propagated up the tqparent widget chain until a widget accepts it with
+ TQKeyEvent::accept() or an event filter consumes it.
+ Key events for multi media keys are ignored by default. You should call
+ TQKeyEvent::accept() if your widget handles those events.
+
+ The TQWidget::setEnable() function can be used to enable or disable
+ mouse and keyboard events for a widget.
+
+ The event handlers TQWidget::keyPressEvent() and
+ TQWidget::keyReleaseEvent() receive key events.
+
+ \sa TQFocusEvent, TQWidget::grabKeyboard()
+*/
+
+/*!
+ \fn TQKeyEvent::TQKeyEvent( Type type, int key, int ascii, int state,
+ const TQString& text, bool autorep, ushort count )
+
+ Constructs a key event object.
+
+ The \a type parameter must be \c TQEvent::KeyPress or \c
+ TQEvent::KeyRelease. If \a key is 0 the event is not a result of a
+ known key (e.g. it may be the result of a compose sequence or
+ keyboard macro). \a ascii is the ASCII code of the key that was
+ pressed or released. \a state holds the keyboard modifiers. \a
+ text is the Unicode text that the key generated. If \a autorep is
+ TRUE, isAutoRepeat() will be TRUE. \a count is the number of
+ single keys.
+
+ The accept flag is set to TRUE.
+*/
+
+/*!
+ \fn int TQKeyEvent::key() const
+
+ Returns the code of the key that was pressed or released.
+
+ See \l TQt::Key for the list of keyboard codes. These codes are
+ independent of the underlying window system.
+
+ A value of either 0 or Key_unknown means that the event is not
+ the result of a known key (e.g. it may be the result of a compose
+ sequence or a keyboard macro, or due to key event compression).
+
+ \sa TQWidget::setKeyCompression()
+*/
+
+/*!
+ \fn int TQKeyEvent::ascii() const
+
+ Returns the ASCII code of the key that was pressed or released. We
+ recommend using text() instead.
+
+ \sa text()
+*/
+
+/*!
+ \fn TQString TQKeyEvent::text() const
+
+ Returns the Unicode text that this key generated. The text returned
+ migth be empty, which is the case when pressing or
+ releasing modifying keys as Shift, Control, Alt and Meta. In these
+ cases key() will contain a valid value.
+
+ \sa TQWidget::setKeyCompression()
+*/
+
+/*!
+ \fn ButtonState TQKeyEvent::state() const
+
+ Returns the keyboard modifier flags that existed immediately
+ before the event occurred.
+
+ The returned value is \c ShiftButton, \c ControlButton, \c AltButton
+ and \c MetaButton OR'ed together.
+
+ \sa stateAfter()
+*/
+
+/*!
+ \fn ButtonState TQKeyEvent::stateAfter() const
+
+ Returns the keyboard modifier flags that existed immediately after
+ the event occurred.
+
+ \warning This function cannot be trusted.
+
+ \sa state()
+*/
+//###### We must check with XGetModifierMapping
+TQt::ButtonState TQKeyEvent::stateAfter() const
+{
+ if ( key() == Key_Shift )
+ return TQt::ButtonState(state()^ShiftButton);
+ if ( key() == Key_Control )
+ return TQt::ButtonState(state()^ControlButton);
+ if ( key() == Key_Alt )
+ return TQt::ButtonState(state()^AltButton);
+ if ( key() == Key_Meta )
+ return TQt::ButtonState(state()^MetaButton);
+ return state();
+}
+
+/*!
+ \fn bool TQKeyEvent::isAccepted() const
+
+ Returns TRUE if the receiver of the event wants to keep the key;
+ otherwise returns FALSE
+*/
+
+/*!
+ \fn void TQKeyEvent::accept()
+
+ Sets the accept flag of the key event object.
+
+ Setting the accept parameter indicates that the receiver of the
+ event wants the key event. Unwanted key events are sent to the
+ tqparent widget.
+
+ The accept flag is set by default.
+
+ \sa ignore()
+*/
+
+/*!
+ \fn bool TQKeyEvent::isAutoRepeat() const
+
+ Returns TRUE if this event comes from an auto-repeating key and
+ FALSE if it comes from an initial key press.
+
+ Note that if the event is a multiple-key compressed event that is
+ partly due to auto-repeat, this function could return either TRUE
+ or FALSE indeterminately.
+*/
+
+/*!
+ \fn int TQKeyEvent::count() const
+
+ Returns the number of single keys for this event. If text() is not
+ empty, this is simply the length of the string.
+
+ \sa TQWidget::setKeyCompression()
+*/
+
+/*!
+ \fn void TQKeyEvent::ignore()
+
+ Clears the accept flag parameter of the key event object.
+
+ Clearing the accept parameter indicates that the event receiver
+ does not want the key event. Unwanted key events are sent to the
+ tqparent widget.
+
+ The accept flag is set by default.
+
+ \sa accept()
+*/
+
+/*!
+ \enum TQt::Key
+
+ The key names used by TQt.
+
+ \value Key_Escape
+ \value Key_Tab
+ \value Key_Backtab
+ \value Key_Backspace
+ \value Key_Return
+ \value Key_Enter
+ \value Key_Insert
+ \value Key_Delete
+ \value Key_Pause
+ \value Key_Print
+ \value Key_SysReq
+ \value Key_Home
+ \value Key_End
+ \value Key_Left
+ \value Key_Up
+ \value Key_Right
+ \value Key_Down
+ \value Key_Prior
+ \value Key_Next
+ \value Key_Shift
+ \value Key_Control
+ \value Key_Meta
+ \value Key_Alt
+ \value Key_CapsLock
+ \value Key_NumLock
+ \value Key_ScrollLock
+ \value Key_Clear
+ \value Key_F1
+ \value Key_F2
+ \value Key_F3
+ \value Key_F4
+ \value Key_F5
+ \value Key_F6
+ \value Key_F7
+ \value Key_F8
+ \value Key_F9
+ \value Key_F10
+ \value Key_F11
+ \value Key_F12
+ \value Key_F13
+ \value Key_F14
+ \value Key_F15
+ \value Key_F16
+ \value Key_F17
+ \value Key_F18
+ \value Key_F19
+ \value Key_F20
+ \value Key_F21
+ \value Key_F22
+ \value Key_F23
+ \value Key_F24
+ \value Key_F25
+ \value Key_F26
+ \value Key_F27
+ \value Key_F28
+ \value Key_F29
+ \value Key_F30
+ \value Key_F31
+ \value Key_F32
+ \value Key_F33
+ \value Key_F34
+ \value Key_F35
+ \value Key_Super_L
+ \value Key_Super_R
+ \value Key_Menu
+ \value Key_Hyper_L
+ \value Key_Hyper_R
+ \value Key_Help
+ \value Key_Space
+ \value Key_Any
+ \value Key_Exclam
+ \value Key_QuoteDbl
+ \value Key_NumberSign
+ \value Key_Dollar
+ \value Key_Percent
+ \value Key_Ampersand
+ \value Key_Apostrophe
+ \value Key_ParenLeft
+ \value Key_ParenRight
+ \value Key_Asterisk
+ \value Key_Plus
+ \value Key_Comma
+ \value Key_Minus
+ \value Key_Period
+ \value Key_Slash
+ \value Key_0
+ \value Key_1
+ \value Key_2
+ \value Key_3
+ \value Key_4
+ \value Key_5
+ \value Key_6
+ \value Key_7
+ \value Key_8
+ \value Key_9
+ \value Key_Colon
+ \value Key_Semicolon
+ \value Key_Less
+ \value Key_Equal
+ \value Key_Greater
+ \value Key_Question
+ \value Key_At
+ \value Key_A
+ \value Key_B
+ \value Key_C
+ \value Key_D
+ \value Key_E
+ \value Key_F
+ \value Key_G
+ \value Key_H
+ \value Key_I
+ \value Key_J
+ \value Key_K
+ \value Key_L
+ \value Key_M
+ \value Key_N
+ \value Key_O
+ \value Key_P
+ \value Key_Q
+ \value Key_R
+ \value Key_S
+ \value Key_T
+ \value Key_U
+ \value Key_V
+ \value Key_W
+ \value Key_X
+ \value Key_Y
+ \value Key_Z
+ \value Key_BracketLeft
+ \value Key_Backslash
+ \value Key_BracketRight
+ \value Key_AsciiCircum
+ \value Key_Underscore
+ \value Key_QuoteLeft
+ \value Key_BraceLeft
+ \value Key_Bar
+ \value Key_BraceRight
+ \value Key_AsciiTilde
+
+ \value Key_nobreakspace
+ \value Key_exclamdown
+ \value Key_cent
+ \value Key_sterling
+ \value Key_currency
+ \value Key_yen
+ \value Key_brokenbar
+ \value Key_section
+ \value Key_diaeresis
+ \value Key_copyright
+ \value Key_ordfeminine
+ \value Key_guillemotleft
+ \value Key_notsign
+ \value Key_hyphen
+ \value Key_registered
+ \value Key_macron
+ \value Key_degree
+ \value Key_plusminus
+ \value Key_twosuperior
+ \value Key_threesuperior
+ \value Key_acute
+ \value Key_mu
+ \value Key_paragraph
+ \value Key_periodcentered
+ \value Key_cedilla
+ \value Key_onesuperior
+ \value Key_masculine
+ \value Key_guillemotright
+ \value Key_onequarter
+ \value Key_onehalf
+ \value Key_threequarters
+ \value Key_questiondown
+ \value Key_Agrave
+ \value Key_Aacute
+ \value Key_Acircumflex
+ \value Key_Atilde
+ \value Key_Adiaeresis
+ \value Key_Aring
+ \value Key_AE
+ \value Key_Ccedilla
+ \value Key_Egrave
+ \value Key_Eacute
+ \value Key_Ecircumflex
+ \value Key_Ediaeresis
+ \value Key_Igrave
+ \value Key_Iacute
+ \value Key_Icircumflex
+ \value Key_Idiaeresis
+ \value Key_ETH
+ \value Key_Ntilde
+ \value Key_Ograve
+ \value Key_Oacute
+ \value Key_Ocircumflex
+ \value Key_Otilde
+ \value Key_Odiaeresis
+ \value Key_multiply
+ \value Key_Ooblique
+ \value Key_Ugrave
+ \value Key_Uacute
+ \value Key_Ucircumflex
+ \value Key_Udiaeresis
+ \value Key_Yacute
+ \value Key_THORN
+ \value Key_ssharp
+ \value Key_agrave
+ \value Key_aacute
+ \value Key_acircumflex
+ \value Key_atilde
+ \value Key_adiaeresis
+ \value Key_aring
+ \value Key_ae
+ \value Key_ccedilla
+ \value Key_egrave
+ \value Key_eacute
+ \value Key_ecircumflex
+ \value Key_ediaeresis
+ \value Key_igrave
+ \value Key_iacute
+ \value Key_icircumflex
+ \value Key_idiaeresis
+ \value Key_eth
+ \value Key_ntilde
+ \value Key_ograve
+ \value Key_oacute
+ \value Key_ocircumflex
+ \value Key_otilde
+ \value Key_odiaeresis
+ \value Key_division
+ \value Key_oslash
+ \value Key_ugrave
+ \value Key_uacute
+ \value Key_ucircumflex
+ \value Key_udiaeresis
+ \value Key_yacute
+ \value Key_thorn
+ \value Key_ydiaeresis
+
+ Multimedia keys
+
+ \value Key_Back
+ \value Key_Forward
+ \value Key_Stop
+ \value Key_Refresh
+
+ \value Key_VolumeDown
+ \value Key_VolumeMute
+ \value Key_VolumeUp
+ \value Key_BassBoost
+ \value Key_BassUp
+ \value Key_BassDown
+ \value Key_TrebleUp
+ \value Key_TrebleDown
+
+ \value Key_MediaPlay
+ \value Key_MediaStop
+ \value Key_MediaPrev
+ \value Key_MediaNext
+ \value Key_MediaRecord
+
+ \value Key_HomePage
+ \value Key_Favorites
+ \value Key_Search
+ \value Key_Standby
+ \value Key_OpenUrl
+
+ \value Key_LaunchMail
+ \value Key_LaunchMedia
+ \value Key_Launch0
+ \value Key_Launch1
+ \value Key_Launch2
+ \value Key_Launch3
+ \value Key_Launch4
+ \value Key_Launch5
+ \value Key_Launch6
+ \value Key_Launch7
+ \value Key_Launch8
+ \value Key_Launch9
+ \value Key_LaunchA
+ \value Key_LaunchB
+ \value Key_LaunchC
+ \value Key_LaunchD
+ \value Key_LaunchE
+ \value Key_LaunchF
+
+ \value Key_MediaLast
+
+ \value Key_unknown
+
+ \value Key_Direction_L internal use only
+ \value Key_Direction_R internal use only
+
+*/
+
+
+/*!
+ \class TQFocusEvent tqevent.h
+ \brief The TQFocusEvent class tqcontains event parameters for widget focus
+ events.
+
+ \ingroup events
+
+ Focus events are sent to widgets when the keyboard input focus
+ changes. Focus events occur due to mouse actions, keypresses (e.g.
+ Tab or Backtab), the window system, popup menus, keyboard
+ shortcuts or other application specific reasons. The reason for a
+ particular focus event is returned by reason() in the appropriate
+ event handler.
+
+ The event handlers TQWidget::focusInEvent() and
+ TQWidget::focusOutEvent() receive focus events.
+
+ Use setReason() to set the reason for all focus events, and
+ resetReason() to set the reason for all focus events to the reason
+ in force before the last setReason() call.
+
+ \sa TQWidget::setFocus(), TQWidget::setFocusPolicy()
+*/
+
+/*!
+ \fn TQFocusEvent::TQFocusEvent( Type type )
+
+ Constructs a focus event object.
+
+ The \a type parameter must be either \c TQEvent::FocusIn or \c
+ TQEvent::FocusOut.
+*/
+
+
+
+TQFocusEvent::Reason TQFocusEvent::m_reason = TQFocusEvent::Other;
+TQFocusEvent::Reason TQFocusEvent::prev_reason = TQFocusEvent::Other;
+
+
+/*!
+ \enum TQFocusEvent::Reason
+
+ This enum specifies why the focus changed.
+
+ \value Mouse because of a mouse action.
+ \value Tab because of a Tab press.
+ \value Backtab because of a Backtab press
+ (possibly including Shift/Control, e.g. Shift+Tab).
+ \value ActiveWindow because the window system made this window (in)active.
+ \value Popup because the application opened/closed a popup that grabbed/released focus.
+ \value Shortcut because of a keyboard shortcut.
+ \value Other any other reason, usually application-specific.
+
+ See the \link focus.html keyboard focus overview\endlink for more
+ about focus.
+*/
+
+/*!
+ Returns the reason for this focus event.
+
+ \sa setReason()
+ */
+TQFocusEvent::Reason TQFocusEvent::reason()
+{
+ return m_reason;
+}
+
+/*!
+ Sets the reason for all future focus events to \a reason.
+
+ \sa reason(), resetReason()
+ */
+void TQFocusEvent::setReason( Reason reason )
+{
+ prev_reason = m_reason;
+ m_reason = reason;
+}
+
+/*!
+ Resets the reason for all future focus events to the value before
+ the last setReason() call.
+
+ \sa reason(), setReason()
+ */
+void TQFocusEvent::resetReason()
+{
+ m_reason = prev_reason;
+}
+
+/*!
+ \fn bool TQFocusEvent::gotFocus() const
+
+ Returns TRUE if the widget received the text input focus;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQFocusEvent::lostFocus() const
+
+ Returns TRUE if the widget lost the text input focus; otherwise
+ returns FALSE.
+*/
+
+
+/*!
+ \class TQPaintEvent tqevent.h
+ \brief The TQPaintEvent class tqcontains event parameters for paint events.
+
+ \ingroup events
+
+ Paint events are sent to widgets that need to update themselves,
+ for instance when part of a widget is exposed because a covering
+ widget is moved.
+
+ The event tqcontains a region() that needs to be updated, and a
+ rect() that is the bounding rectangle of that region. Both are
+ provided because many widgets can't make much use of region(), and
+ rect() can be much faster than region().boundingRect(). Painting
+ is clipped to region() during processing of a paint event.
+
+ The erased() function returns TRUE if the region() has been
+ cleared to the widget's background (see
+ TQWidget::backgroundMode()), and FALSE if the region's contents are
+ arbitrary.
+
+ \sa TQPainter TQWidget::update() TQWidget::tqrepaint()
+ TQWidget::paintEvent() TQWidget::backgroundMode() TQRegion
+*/
+
+/*!
+ \fn TQPaintEvent::TQPaintEvent( const TQRegion &paintRegion, bool erased=TRUE )
+
+ Constructs a paint event object with the region that should be
+ updated. The region is given by \a paintRegion. If \a erased is
+ TRUE the region will be cleared before repainting.
+*/
+
+/*!
+ \fn TQPaintEvent::TQPaintEvent( const TQRect &paintRect, bool erased=TRUE )
+
+ Constructs a paint event object with the rectangle that should be
+ updated. The region is also given by \a paintRect. If \a erased is
+ TRUE the region will be cleared before repainting.
+*/
+
+/*!
+ \fn TQPaintEvent::TQPaintEvent( const TQRegion &paintRegion, const TQRect &paintRect, bool erased=TRUE )
+
+ Constructs a paint event object with the rectangle \a paintRect
+ that should be updated. The region is given by \a paintRegion. If
+ \a erased is TRUE the region will be cleared before repainting.
+*/
+
+/*!
+ \fn const TQRect &TQPaintEvent::rect() const
+
+ Returns the rectangle that should be updated.
+
+ \sa region(), TQPainter::setClipRect()
+*/
+
+/*!
+ \fn const TQRegion &TQPaintEvent::region() const
+
+ Returns the region that should be updated.
+
+ \sa rect(), TQPainter::setClipRegion()
+*/
+
+/*!
+ \fn bool TQPaintEvent::erased() const
+
+ Returns TRUE if the paint event region (or rectangle) has been
+ erased with the widget's background; otherwise returns FALSE.
+*/
+
+/*!
+ \class TQMoveEvent tqevent.h
+ \brief The TQMoveEvent class tqcontains event parameters for move events.
+
+ \ingroup events
+
+ Move events are sent to widgets that have been moved to a new position
+ relative to their tqparent.
+
+ The event handler TQWidget::moveEvent() receives move events.
+
+ \sa TQWidget::move(), TQWidget::setGeometry()
+*/
+
+/*!
+ \fn TQMoveEvent::TQMoveEvent( const TQPoint &pos, const TQPoint &oldPos )
+
+ Constructs a move event with the new and old widget positions, \a
+ pos and \a oldPos respectively.
+*/
+
+/*!
+ \fn const TQPoint &TQMoveEvent::pos() const
+
+ Returns the new position of the widget. This excludes the window
+ frame for top level widgets.
+*/
+
+/*!
+ \fn const TQPoint &TQMoveEvent::oldPos() const
+
+ Returns the old position of the widget.
+*/
+
+
+/*!
+ \class TQResizeEvent tqevent.h
+ \brief The TQResizeEvent class tqcontains event parameters for resize events.
+
+ \ingroup events
+
+ Resize events are sent to widgets that have been resized.
+
+ The event handler TQWidget::resizeEvent() receives resize events.
+
+ \sa TQWidget::resize(), TQWidget::setGeometry()
+*/
+
+/*!
+ \fn TQResizeEvent::TQResizeEvent( const TQSize &size, const TQSize &oldSize )
+
+ Constructs a resize event with the new and old widget sizes, \a
+ size and \a oldSize respectively.
+*/
+
+/*!
+ \fn const TQSize &TQResizeEvent::size() const
+
+ Returns the new size of the widget, which is the same as
+ TQWidget::size().
+*/
+
+/*!
+ \fn const TQSize &TQResizeEvent::oldSize() const
+
+ Returns the old size of the widget.
+*/
+
+
+/*!
+ \class TQCloseEvent tqevent.h
+ \brief The TQCloseEvent class tqcontains parameters that describe a close event.
+
+ \ingroup events
+
+ Close events are sent to widgets that the user wants to close,
+ usually by choosing "Close" from the window menu, or by clicking
+ the `X' titlebar button. They are also sent when you call
+ TQWidget::close() to close a widget programmatically.
+
+ Close events contain a flag that indicates whether the receiver
+ wants the widget to be closed or not. When a widget accepts the
+ close event, it is hidden (and destroyed if it was created with
+ the \c WDestructiveClose flag). If it refuses to accept the close
+ event nothing happens. (Under X11 it is possible that the window
+ manager will forcibly close the window; but at the time of writing
+ we are not aware of any window manager that does this.)
+
+ The application's main widget -- TQApplication::mainWidget() --
+ is a special case. When it accepts the close event, TQt leaves the
+ main event loop and the application is immediately terminated
+ (i.e. it returns from the call to TQApplication::exec() in the
+ main() function).
+
+ The event handler TQWidget::closeEvent() receives close events. The
+ default implementation of this event handler accepts the close
+ event. If you do not want your widget to be hidden, or want some
+ special handing, you should reimplement the event handler.
+
+ The \link simple-application.html#closeEvent closeEvent() in the
+ Application Walkthrough\endlink shows a close event handler that
+ asks whether to save a document before closing.
+
+ If you want the widget to be deleted when it is closed, create it
+ with the \c WDestructiveClose widget flag. This is very useful for
+ independent top-level windows in a multi-window application.
+
+ \l{TQObject}s emits the \link TQObject::destroyed()
+ destroyed()\endlink signal when they are deleted.
+
+ If the last top-level window is closed, the
+ TQApplication::lastWindowClosed() signal is emitted.
+
+ The isAccepted() function returns TRUE if the event's receiver has
+ agreed to close the widget; call accept() to agree to close the
+ widget and call ignore() if the receiver of this event does not
+ want the widget to be closed.
+
+ \sa TQWidget::close(), TQWidget::hide(), TQObject::destroyed(),
+ TQApplication::setMainWidget(), TQApplication::lastWindowClosed(),
+ TQApplication::exec(), TQApplication::quit()
+*/
+
+/*!
+ \fn TQCloseEvent::TQCloseEvent()
+
+ Constructs a close event object with the accept parameter flag set
+ to FALSE.
+
+ \sa accept()
+*/
+
+/*!
+ \fn bool TQCloseEvent::isAccepted() const
+
+ Returns TRUE if the receiver of the event has agreed to close the
+ widget; otherwise returns FALSE.
+
+ \sa accept(), ignore()
+*/
+
+/*!
+ \fn void TQCloseEvent::accept()
+
+ Sets the accept flag of the close event object.
+
+ Setting the accept flag indicates that the receiver of this event
+ agrees to close the widget.
+
+ The accept flag is \e not set by default.
+
+ If you choose to accept in TQWidget::closeEvent(), the widget will
+ be hidden. If the widget's \c WDestructiveClose flag is set, it
+ will also be destroyed.
+
+ \sa ignore(), TQWidget::hide()
+*/
+
+/*!
+ \fn void TQCloseEvent::ignore()
+
+ Clears the accept flag of the close event object.
+
+ Clearing the accept flag indicates that the receiver of this event
+ does not want the widget to be closed.
+
+ The close event is constructed with the accept flag cleared.
+
+ \sa accept()
+*/
+
+/*!
+ \class TQIconDragEvent tqevent.h
+ \brief The TQIconDragEvent class Q_SIGNALS that a main icon drag has begun.
+
+ \ingroup events
+
+ Icon drag events are sent to widgets when the main icon of a window has been dragged away.
+ On Mac OS X this is fired when the proxy icon of a window is dragged off titlebar, in response to
+ this event is is normal to begin using drag and drop.
+*/
+
+/*!
+ \fn TQIconDragEvent::TQIconDragEvent()
+
+ Constructs an icon drag event object with the accept parameter
+ flag set to FALSE.
+
+ \sa accept()
+*/
+
+/*!
+ \fn bool TQIconDragEvent::isAccepted() const
+
+ Returns TRUE if the receiver of the event has started a drag and
+ drop operation; otherwise returns FALSE.
+
+ \sa accept(), ignore()
+*/
+
+/*!
+ \fn void TQIconDragEvent::accept()
+
+ Sets the accept flag of the icon drag event object.
+
+ Setting the accept flag indicates that the receiver of this event
+ has started a drag and drop oeration.
+
+ The accept flag is \e not set by default.
+
+ \sa ignore(), TQWidget::hide()
+*/
+
+/*!
+ \fn void TQIconDragEvent::ignore()
+
+ Clears the accept flag of the icon drag object.
+
+ Clearing the accept flag indicates that the receiver of this event
+ has not handled the icon drag as a result other events can be sent.
+
+ The icon drag event is constructed with the accept flag cleared.
+
+ \sa accept()
+*/
+
+/*!
+ \class TQContextMenuEvent tqevent.h
+ \brief The TQContextMenuEvent class tqcontains parameters that describe a context menu event.
+
+ \ingroup events
+
+ Context menu events are sent to widgets when a user triggers a
+ context menu. What triggers this is platform dependent. For
+ example, on Windows, pressing the menu button or releasing the
+ right mouse button will cause this event to be sent.
+
+ When this event occurs it is customary to show a TQPopupMenu with a
+ context menu, if this is relevant to the context.
+
+ Context menu events contain a special accept flag that indicates
+ whether the receiver accepted the event. If the event handler does
+ not accept the event, then whatever triggered the event will be
+ handled as a regular input event if possible.
+
+ \sa TQPopupMenu
+*/
+
+/*!
+ \fn TQContextMenuEvent::TQContextMenuEvent( Reason reason, const TQPoint &pos, const TQPoint &globalPos, int state )
+
+ Constructs a context menu event object with the accept parameter
+ flag set to FALSE.
+
+ The \a reason parameter must be \c TQContextMenuEvent::Mouse or \c
+ TQContextMenuEvent::Keyboard.
+
+ The \a pos parameter specifies the mouse position relative to the
+ receiving widget. \a globalPos is the mouse position in absolute
+ coordinates. \a state is the ButtonState at the time of the event.
+*/
+
+
+/*!
+ \fn TQContextMenuEvent::TQContextMenuEvent( Reason reason, const TQPoint &pos, int state )
+
+ Constructs a context menu event object with the accept parameter
+ flag set to FALSE.
+
+ The \a reason parameter must be \c TQContextMenuEvent::Mouse or \c
+ TQContextMenuEvent::Keyboard.
+
+ The \a pos parameter specifies the mouse position relative to the
+ receiving widget. \a state is the ButtonState at the time of the
+ event.
+
+ The globalPos() is initialized to TQCursor::pos(), which may not be
+ appropriate. Use the other constructor to specify the global
+ position explicitly.
+*/
+
+TQContextMenuEvent::TQContextMenuEvent( Reason reason, const TQPoint &pos, int state )
+ : TQEvent( ContextMenu ), p( pos ), accpt(TRUE), consum(TRUE),
+ reas( reason ), s((ushort)state)
+{
+ gp = TQCursor::pos();
+}
+
+/*!
+ \fn const TQPoint &TQContextMenuEvent::pos() const
+
+ Returns the position of the mouse pointer relative to the widget
+ that received the event.
+
+ \sa x(), y(), globalPos()
+*/
+
+/*!
+ \fn int TQContextMenuEvent::x() const
+
+ Returns the x-position of the mouse pointer, relative to the
+ widget that received the event.
+
+ \sa y(), pos()
+*/
+
+/*!
+ \fn int TQContextMenuEvent::y() const
+
+ Returns the y-position of the mouse pointer, relative to the
+ widget that received the event.
+
+ \sa x(), pos()
+*/
+
+/*!
+ \fn const TQPoint &TQContextMenuEvent::globalPos() const
+
+ Returns the global position of the mouse pointer at the time of
+ the event.
+
+ \sa x(), y(), pos()
+*/
+
+/*!
+ \fn int TQContextMenuEvent::globalX() const
+
+ Returns the global x-position of the mouse pointer at the time of
+ the event.
+
+ \sa globalY(), globalPos()
+*/
+
+/*!
+ \fn int TQContextMenuEvent::globalY() const
+
+ Returns the global y-position of the mouse pointer at the time of
+ the event.
+
+ \sa globalX(), globalPos()
+*/
+
+/*!
+ \fn ButtonState TQContextMenuEvent::state() const
+
+ Returns the button state (a combination of mouse buttons and
+ keyboard modifiers), i.e. what buttons and keys were being
+ pressed immediately before the event was generated.
+
+ The returned value is \c LeftButton, \c RightButton, \c MidButton,
+ \c ShiftButton, \c ControlButton and \c AltButton OR'ed together.
+*/
+
+/*!
+ \fn bool TQContextMenuEvent::isConsumed() const
+
+ Returns TRUE (which stops propagation of the event) if the
+ receiver has blocked the event; otherwise returns FALSE.
+
+ \sa accept(), ignore(), consume()
+*/
+
+/*!
+ \fn void TQContextMenuEvent::consume()
+
+ Sets the consume flag of the context event object.
+
+ Setting the consume flag indicates that the receiver of this event
+ does not want the event to be propagated further (i.e. not sent to
+ tqparent classes.)
+
+ The consumed flag is not set by default.
+
+ \sa ignore() accept()
+*/
+
+/*!
+ \fn bool TQContextMenuEvent::isAccepted() const
+
+ Returns TRUE if the receiver has processed the event; otherwise
+ returns FALSE.
+
+ \sa accept(), ignore(), consume()
+*/
+
+/*!
+ \fn void TQContextMenuEvent::accept()
+
+ Sets the accept flag of the context event object.
+
+ Setting the accept flag indicates that the receiver of this event
+ has processed the event. Processing the event means you did
+ something with it and it will be implicitly consumed.
+
+ The accept flag is not set by default.
+
+ \sa ignore() consume()
+*/
+
+/*!
+ \fn void TQContextMenuEvent::ignore()
+
+ Clears the accept flag of the context event object.
+
+ Clearing the accept flag indicates that the receiver of this event
+ does not need to show a context menu. This will implicitly remove
+ the consumed flag as well.
+
+ The accept flag is not set by default.
+
+ \sa accept() consume()
+*/
+
+/*!
+ \enum TQContextMenuEvent::Reason
+
+ This enum describes the reason the ContextMenuEvent was sent. The
+ values are:
+
+ \value Mouse The mouse caused the event to be sent. Normally this
+ means the right mouse button was clicked, but this is platform
+ specific.
+
+ \value Keyboard The keyboard caused this event to be sent. On
+ Windows this means the menu button was pressed.
+
+ \value Other The event was sent by some other means (i.e. not by
+ the mouse or keyboard).
+*/
+
+
+/*!
+ \fn TQContextMenuEvent::Reason TQContextMenuEvent::reason() const
+
+ Returns the reason for this context event.
+*/
+
+
+/*!
+ \class TQIMEvent tqevent.h
+ \brief The TQIMEvent class provides parameters for input method events.
+
+ \ingroup events
+
+ Input method events are sent to widgets when an input method is
+ used to enter text into a widget. Input methods are widely used to
+ enter text in Asian and other complex languages.
+
+ The events are of interest to widgets that accept keyboard input
+ and want to be able to correctly handle complex languages. Text
+ input in such languages is usually a three step process.
+
+ \list 1
+ \i <b>Starting to Compose</b><br>
+ When the user presses the first key on a keyboard an input context
+ is created. This input context will contain a string with the
+ typed characters.
+
+ \i <b>Composing</b><br>
+ With every new key pressed, the input method will try to create a
+ matching string for the text typed so far. While the input context
+ is active, the user can only move the cursor inside the string
+ belonging to this input context.
+
+ \i <b>Completing</b><br>
+ At some point, e.g. when the user presses the Spacebar, they get
+ to this stage, where they can choose from a number of strings that
+ match the text they have typed so far. The user can press Enter to
+ confirm their choice or Escape to cancel the input; in either case
+ the input context will be closed.
+ \endlist
+
+ Note that the particular key presses used for a given input
+ context may differ from those we've mentioned here, i.e. they may
+ not be Spacebar, Enter and Escape.
+
+ These three stages are represented by three different types of
+ events. The IMStartEvent, IMComposeEvent and IMEndEvent. When a
+ new input context is created, an IMStartEvent will be sent to the
+ widget and delivered to the \l TQWidget::imStartEvent() function.
+ The widget can then update internal data structures to reflect
+ this.
+
+ After this, an IMComposeEvent will be sent to the widget for
+ every key the user presses. It will contain the current
+ composition string the widget has to show and the current cursor
+ position within the composition string. This string is temporary
+ and can change with every key the user types, so the widget will
+ need to store the state before the composition started (the state
+ it had when it received the IMStartEvent). IMComposeEvents will be
+ delivered to the \l TQWidget::imComposeEvent() function.
+
+ Usually, widgets try to mark the part of the text that is part of
+ the current composition in a way that is visible to the user. A
+ commonly used visual cue is to use a dotted underline.
+
+ After the user has selected the final string, an IMEndEvent will
+ be sent to the widget. The event tqcontains the final string the
+ user selected, and could be empty if they canceled the
+ composition. This string should be accepted as the final text the
+ user entered, and the intermediate composition string should be
+ cleared. These events are delivered to \l TQWidget::imEndEvent().
+
+ If the user clicks another widget, taking the focus out of the
+ widget where the composition is taking place the IMEndEvent will
+ be sent and the string it holds will be the result of the
+ composition up to that point (which may be an empty string).
+*/
+
+/*!
+ \fn TQIMEvent::TQIMEvent( Type type, const TQString &text, int cursorPosition )
+
+ Constructs a new TQIMEvent with the accept flag set to FALSE. \a
+ type can be one of TQEvent::IMStartEvent, TQEvent::IMComposeEvent
+ or TQEvent::IMEndEvent. \a text tqcontains the current compostion
+ string and \a cursorPosition the current position of the cursor
+ inside \a text.
+*/
+
+/*!
+ \fn const TQString &TQIMEvent::text() const
+
+ Returns the composition text. This is a null string for an
+ IMStartEvent, and tqcontains the final accepted string (which may be
+ empty) in the IMEndEvent.
+*/
+
+/*!
+ \fn int TQIMEvent::cursorPos() const
+
+ Returns the current cursor position inside the composition string.
+ Will return -1 for IMStartEvent and IMEndEvent.
+*/
+
+/*!
+ \fn int TQIMEvent::selectionLength() const
+
+ Returns the number of characters in the composition string (
+ starting at cursorPos() ) that should be marked as selected by the
+ input widget receiving the event.
+ Will return 0 for IMStartEvent and IMEndEvent.
+*/
+
+/*!
+ \fn bool TQIMEvent::isAccepted() const
+
+ Returns TRUE if the receiver of the event processed the event;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn void TQIMEvent::accept()
+
+ Sets the accept flag of the input method event object.
+
+ Setting the accept parameter indicates that the receiver of the
+ event processed the input method event.
+
+ The accept flag is not set by default.
+
+ \sa ignore()
+*/
+
+
+/*!
+ \fn void TQIMEvent::ignore()
+
+ Clears the accept flag parameter of the input method event object.
+
+ Clearing the accept parameter indicates that the event receiver
+ does not want the input method event.
+
+ The accept flag is cleared by default.
+
+ \sa accept()
+*/
+
+/*!
+ \class TQTabletEvent tqevent.h
+ \brief The TQTabletEvent class tqcontains parameters that describe a Tablet
+ event.
+
+ \ingroup events
+
+ Tablet Events are generated from a Wacom&copy; tablet. Most of
+ the time you will want to deal with events from the tablet as if
+ they were events from a mouse, for example retrieving the position
+ with x(), y(), pos(), globalX(), globalY() and globalPos(). In
+ some situations you may wish to retrieve the extra information
+ provided by the tablet tqdevice driver, for example, you might want
+ to adjust color brightness based on pressure. TQTabletEvent allows
+ you to get the pressure(), the xTilt() and yTilt(), as well as the
+ type of tqdevice being used with tqdevice() (see \l{TabletDevice}).
+
+ A tablet event tqcontains a special accept flag that indicates
+ whether the receiver wants the event. You should call
+ TQTabletEvent::accept() if you handle the tablet event; otherwise
+ it will be sent to the tqparent widget.
+
+ The TQWidget::setEnabled() function can be used to enable or
+ disable mouse and keyboard events for a widget.
+
+ The event handler TQWidget::tabletEvent() receives all three types of tablet
+ events. TQt will first send a tabletEvent and then, if it is not accepted,
+ it will send a mouse event. This allows applications that don't utilize
+ tablets to use a tablet like a mouse while also enabling those who want to
+ use both tablets and mouses differently.
+
+*/
+
+/*!
+ \enum TQTabletEvent::TabletDevice
+
+ This enum defines what type of tqdevice is generating the event.
+
+ \value NoDevice No tqdevice, or an unknown tqdevice.
+ \value Puck A Puck (a tqdevice that is similar to a flat mouse with
+ a transtqparent circle with cross-hairs).
+ \value Stylus A Stylus (the narrow end of the pen).
+ \value Eraser An Eraser (the broad end of the pen).
+ \omit
+ \value Menu A menu button was pressed (currently unimplemented).
+*/
+
+/*!
+ \fn TQTabletEvent::TQTabletEvent( Type t, const TQPoint &pos,
+ const TQPoint &globalPos, int tqdevice,
+ int pressure, int xTilt, int yTilt,
+ const TQPair<int,int> &uId )
+ Construct a tablet event of type \a t. The position of when the event occurred is given
+ int \a pos and \a globalPos. \a tqdevice tqcontains the \link TabletDevice tqdevice type\endlink,
+ \a pressure tqcontains the pressure exerted on the \a tqdevice, \a xTilt and \a yTilt contain
+ \a tqdevice's degree of tilt from the X and Y axis respectively. The \a uId tqcontains an
+ event id.
+
+ On Irix, \a globalPos will contain the high-resolution coordinates received from the
+ tablet tqdevice driver, instead of from the windowing system.
+
+ \sa pos(), globalPos(), tqdevice(), pressure(), xTilt(), yTilt()
+*/
+
+TQTabletEvent::TQTabletEvent( Type t, const TQPoint &pos, const TQPoint &globalPos, int tqdevice,
+ int pressure, int xTilt, int yTilt,
+ const TQPair<int, int> &uId )
+ : TQEvent( t ),
+ mPos( pos ),
+ mGPos( globalPos ),
+ mDev( tqdevice ),
+ mPress( pressure ),
+ mXT( xTilt ),
+ mYT( yTilt ),
+ mType( uId.first ),
+ mPhy( uId.second ),
+ mbAcc(TRUE)
+{}
+
+/*!
+ \obsolete
+ \fn TQTabletEvent::TQTabletEvent( const TQPoint &pos, const TQPoint &globalPos, int tqdevice, int pressure, int xTilt, int yTilt, const TQPair<int,int> &uId )
+
+ Constructs a tablet event object. The position when the event
+ occurred is is given in \a pos and \a globalPos. \a tqdevice
+ tqcontains the \link TabletDevice tqdevice type\endlink, \a pressure
+ tqcontains the pressure exerted on the \a tqdevice, \a xTilt and \a
+ yTilt contain the \a tqdevice's degrees of tilt from the X and Y
+ axis respectively. The \a uId tqcontains an event id.
+
+ On Irix, \a globalPos will contain the high-resolution coordinates
+ received from the tablet tqdevice driver, instead of from the
+ windowing system.
+
+ \sa pos(), globalPos(), tqdevice(), pressure(), xTilt(), yTilt()
+*/
+
+/*!
+ \fn TabletDevices TQTabletEvent::tqdevice() const
+
+ Returns the type of tqdevice that generated the event. Useful if you
+ want one end of the pen to do something different than the other.
+
+ \sa TabletDevice
+*/
+
+/*!
+ \fn int TQTabletEvent::pressure() const
+
+ Returns the pressure that is exerted on the tqdevice. This number is
+ a value from 0 (no pressure) to 255 (maximum pressure). The
+ pressure is always scaled to be within this range no matter how
+ many pressure levels the underlying hardware supports.
+*/
+
+/*!
+ \fn int TQTabletEvent::xTilt() const
+
+ Returns the difference from the perpendicular in the X Axis.
+ Positive values are towards the tablet's physical right. The angle
+ is in the range -60 to +60 degrees.
+
+ \sa yTilt()
+*/
+
+/*!
+ \fn int TQTabletEvent::yTilt() const
+
+ Returns the difference from the perpendicular in the Y Axis.
+ Positive values are towards the bottom of the tablet. The angle is
+ within the range -60 to +60 degrees.
+
+ \sa xTilt()
+*/
+
+/*!
+ \fn const TQPoint &TQTabletEvent::pos() const
+
+ Returns the position of the tqdevice, relative to the widget that
+ received the event.
+
+ If you move widgets around in response to mouse events, use
+ globalPos() instead of this function.
+
+ \sa x(), y(), globalPos()
+*/
+
+/*!
+ \fn int TQTabletEvent::x() const
+
+ Returns the x-position of the tqdevice, relative to the widget that
+ received the event.
+
+ \sa y(), pos()
+*/
+
+/*!
+ \fn int TQTabletEvent::y() const
+
+ Returns the y-position of the tqdevice, relative to the widget that
+ received the event.
+
+ \sa x(), pos()
+*/
+
+/*!
+ \fn const TQPoint &TQTabletEvent::globalPos() const
+
+ Returns the global position of the tqdevice \e{at the time of the
+ event}. This is important on asynchronous windows systems like X11;
+ whenever you move your widgets around in response to mouse events,
+ globalPos() can differ significantly from the current position
+ TQCursor::pos().
+
+ \sa globalX(), globalY()
+*/
+
+/*!
+ \fn int TQTabletEvent::globalX() const
+
+ Returns the global x-position of the mouse pointer at the time of
+ the event.
+
+ \sa globalY(), globalPos()
+*/
+
+/*!
+ \fn int TQTabletEvent::globalY() const
+
+ Returns the global y-position of the mouse pointer at the time of
+ the event.
+
+ \sa globalX(), globalPos()
+*/
+
+/*!
+ \fn bool TQTabletEvent::isAccepted() const
+
+ Returns TRUE if the receiver of the event handles the tablet
+ event; otherwise returns FALSE.
+*/
+
+/*!
+ \fn void TQTabletEvent::accept()
+
+ Sets the accept flag of the tablet event object.
+
+ Setting the accept flag indicates that the receiver of the event
+ wants the tablet event. Unwanted tablet events are sent to the
+ tqparent widget.
+
+ The accept flag is set by default.
+
+ \sa ignore()
+*/
+
+/*!
+ \fn void TQTabletEvent::ignore()
+
+ Clears the accept flag parameter of the tablet event object.
+
+ Clearing the accept flag indicates that the event receiver does
+ not want the tablet event. Unwanted tablet events are sent to the
+ tqparent widget.
+
+ The accept flag is set by default.
+
+ \sa accept()
+*/
+
+/*!
+ \fn TQPair<int, int> TQTabletEvent::uniqueId()
+
+ Returns a unique ID for the current tqdevice. It is possible to
+ generate a unique ID for any Wacom&copy; tqdevice. This makes it
+ possible to differentiate between multiple tqdevices being used at
+ the same time on the tablet. The \c first member tqcontains a value
+ for the type, the \c second member tqcontains a physical ID obtained
+ from the tqdevice. Each combination of these values is unique. Note:
+ for different platforms, the \c first value is different due to
+ different driver implementations.
+*/
+
+/*!
+ \class TQChildEvent tqevent.h
+ \brief The TQChildEvent class tqcontains event parameters for child object
+ events.
+
+ \ingroup events
+
+ Child events are sent to objects when tqchildren are inserted or
+ removed.
+
+ A \c ChildRemoved event is sent immediately, but a \c
+ ChildInserted event is \e posted (with TQApplication::postEvent()).
+
+ Note that if a child is removed immediately after it is inserted,
+ the \c ChildInserted event may be suppressed, but the \c
+ ChildRemoved event will always be sent. In this case there will be
+ a \c ChildRemoved event without a corresponding \c ChildInserted
+ event.
+
+ The handler for these events is TQObject::childEvent().
+*/
+
+/*!
+ \fn TQChildEvent::TQChildEvent( Type type, TQObject *child )
+
+ Constructs a child event object. The \a child is the object that
+ is to be removed or inserted.
+
+ The \a type parameter must be either \c TQEvent::ChildInserted or
+ \c TQEvent::ChildRemoved.
+*/
+
+/*!
+ \fn TQObject *TQChildEvent::child() const
+
+ Returns the child widget that was inserted or removed.
+*/
+
+/*!
+ \fn bool TQChildEvent::inserted() const
+
+ Returns TRUE if the widget received a new child; otherwise returns
+ FALSE.
+*/
+
+/*!
+ \fn bool TQChildEvent::removed() const
+
+ Returns TRUE if the object lost a child; otherwise returns FALSE.
+*/
+
+
+
+
+/*!
+ \class TQCustomEvent tqevent.h
+ \brief The TQCustomEvent class provides support for custom events.
+
+ \ingroup events
+
+ TQCustomEvent is a generic event class for user-defined events.
+ User defined events can be sent to widgets or other TQObject
+ instances using TQApplication::postEvent() or
+ TQApplication::sendEvent(). Subclasses of TQObject can easily
+ receive custom events by implementing the TQObject::customEvent()
+ event handler function.
+
+ TQCustomEvent objects should be created with a type ID that
+ uniquely identifies the event type. To avoid clashes with the
+ TQt-defined events types, the value should be at least as large as
+ the value of the "User" entry in the TQEvent::Type enum.
+
+ TQCustomEvent tqcontains a generic void* data member that may be used
+ for transferring event-specific data to the receiver. Note that
+ since events are normally delivered asynchronously, the data
+ pointer, if used, must remain valid until the event has been
+ received and processed.
+
+ TQCustomEvent can be used as-is for simple user-defined event
+ types, but normally you will want to make a subclass of it for
+ your event types. In a subclass, you can add data members that are
+ suitable for your event type.
+
+ Example:
+ \code
+ class ColorChangeEvent : public TQCustomEvent
+ {
+ public:
+ ColorChangeEvent( TQColor color )
+ : TQCustomEvent( 65432 ), c( color ) {}
+ TQColor color() const { return c; }
+ private:
+ TQColor c;
+ };
+
+ // To send an event of this custom event type:
+
+ ColorChangeEvent* ce = new ColorChangeEvent( blue );
+ TQApplication::postEvent( receiver, ce ); // TQt will delete it when done
+
+ // To receive an event of this custom event type:
+
+ void MyWidget::customEvent( TQCustomEvent * e )
+ {
+ if ( e->type() == 65432 ) { // It must be a ColorChangeEvent
+ ColorChangeEvent* ce = (ColorChangeEvent*)e;
+ newColor = ce->color();
+ }
+ }
+ \endcode
+
+ \sa TQWidget::customEvent(), TQApplication::notify()
+*/
+
+
+/*!
+ Constructs a custom event object with event type \a type. The
+ value of \a type must be at least as large as TQEvent::User. The
+ data pointer is set to 0.
+*/
+
+TQCustomEvent::TQCustomEvent( int type )
+ : TQEvent( (TQEvent::Type)type ), d( 0 )
+{
+}
+
+
+/*!
+ \fn TQCustomEvent::TQCustomEvent( Type type, void *data )
+
+ Constructs a custom event object with the event type \a type and a
+ pointer to \a data. (Note that any int value may safely be cast to
+ TQEvent::Type).
+*/
+
+
+/*!
+ \fn void TQCustomEvent::setData( void* data )
+
+ Sets the generic data pointer to \a data.
+
+ \sa data()
+*/
+
+/*!
+ \fn void *TQCustomEvent::data() const
+
+ Returns a pointer to the generic event data.
+
+ \sa setData()
+*/
+
+
+
+/*!
+ \fn TQDragMoveEvent::TQDragMoveEvent( const TQPoint& pos, Type type )
+
+ Creates a TQDragMoveEvent for which the mouse is at point \a pos,
+ and the event is of type \a type.
+
+ \warning Do not create a TQDragMoveEvent yourself since these
+ objects rely on TQt's internal state.
+*/
+
+/*!
+ \fn void TQDragMoveEvent::accept( const TQRect & r )
+
+ The same as accept(), but also notifies that future moves will
+ also be acceptable if they remain within the rectangle \a r on the
+ widget: this can improve performance, but may also be ignored by
+ the underlying system.
+
+ If the rectangle is \link TQRect::isEmpty() empty\endlink, then
+ drag move events will be sent continuously. This is useful if the
+ source is scrolling in a timer event.
+*/
+
+/*!
+ \fn void TQDragMoveEvent::ignore( const TQRect & r)
+
+ The opposite of accept(const TQRect&), i.e. says that moves within
+ rectangle \a r are not acceptable (will be ignored).
+*/
+
+/*!
+ \fn TQRect TQDragMoveEvent::answerRect() const
+
+ Returns the rectangle for which the acceptance of the move event
+ applies.
+*/
+
+
+
+/*!
+ \fn const TQPoint& TQDropEvent::pos() const
+
+ Returns the position where the drop was made.
+*/
+
+/*!
+ \fn bool TQDropEvent::isAccepted () const
+
+ Returns TRUE if the drop target accepts the event; otherwise
+ returns FALSE.
+*/
+
+/*!
+ \fn void TQDropEvent::accept(bool y=TRUE)
+
+ Call this function to indicate whether the event provided data
+ which your widget processed. Set \a y to TRUE (the default) if
+ your widget could process the data, otherwise set \a y to FALSE.
+ To get the data, use tqencodedData(), or preferably, the decode()
+ methods of existing TQDragObject subclasses, such as
+ TQTextDrag::decode(), or your own subclasses.
+
+ \sa acceptAction()
+*/
+
+/*!
+ \fn void TQDropEvent::acceptAction(bool y=TRUE)
+
+ Call this to indicate that the action described by action() is
+ accepted (i.e. if \a y is TRUE, which is the default), not merely
+ the default copy action. If you call acceptAction(TRUE), there is
+ no need to also call accept(TRUE).
+*/
+
+/*!
+ \fn void TQDragMoveEvent::accept( bool y )
+ \reimp
+ \internal
+ Remove in 3.0
+*/
+
+/*!
+ \fn void TQDragMoveEvent::ignore()
+ \reimp
+ \internal
+ Remove in 3.0
+*/
+
+
+/*!
+ \enum TQDropEvent::Action
+
+ This enum describes the action which a source requests that a
+ target perform with dropped data.
+
+ \value Copy The default action. The source simply uses the data
+ provided in the operation.
+ \value Link The source should somehow create a link to the
+ location specified by the data.
+ \value Move The source should somehow move the object from the
+ location specified by the data to a new location.
+ \value Private The target has special knowledge of the MIME type,
+ which the source should respond to in a similar way to
+ a Copy.
+ \value UserAction The source and target can co-operate using
+ special actions. This feature is not currently
+ supported.
+
+ The Link and Move actions only makes sense if the data is a
+ reference, for example, text/uri-list file lists (see TQUriDrag).
+*/
+
+/*!
+ \fn void TQDropEvent::setAction( Action a )
+
+ Sets the action to \a a. This is used internally, you should not
+ need to call this in your code: the \e source decides the action,
+ not the target.
+*/
+
+/*!
+ \fn Action TQDropEvent::action() const
+
+ Returns the Action which the target is requesting to be performed
+ with the data. If your application understands the action and can
+ process the supplied data, call acceptAction(); if your
+ application can process the supplied data but can only perform the
+ Copy action, call accept().
+*/
+
+/*!
+ \fn void TQDropEvent::ignore()
+
+ The opposite of accept(), i.e. you have ignored the drop event.
+*/
+
+/*!
+ \fn bool TQDropEvent::isActionAccepted () const
+
+ Returns TRUE if the drop action was accepted by the drop site;
+ otherwise returns FALSE.
+*/
+
+
+/*!
+ \fn void TQDropEvent::setPoint (const TQPoint & np)
+
+ Sets the drop to happen at point \a np. You do not normally need
+ to use this as it will be set internally before your widget
+ receives the drop event.
+*/ // ### here too - what coordinate system?
+
+
+/*!
+ \class TQDragEnterEvent tqevent.h
+ \brief The TQDragEnterEvent class provides an event which is sent to the widget when a drag and drop first drags onto the widget.
+
+ \ingroup events
+ \ingroup draganddrop
+
+ This event is always immediately followed by a TQDragMoveEvent, so
+ you only need to respond to one or the other event. This class
+ inherits most of its functionality from TQDragMoveEvent, which in
+ turn inherits most of its functionality from TQDropEvent.
+
+ \sa TQDragLeaveEvent, TQDragMoveEvent, TQDropEvent
+*/
+
+/*!
+ \fn TQDragEnterEvent::TQDragEnterEvent (const TQPoint & pos)
+
+ Constructs a TQDragEnterEvent entering at the given point, \a pos.
+
+ \warning Do not create a TQDragEnterEvent yourself since these
+ objects rely on TQt's internal state.
+*/
+
+/*!
+ \class TQDragLeaveEvent tqevent.h
+ \brief The TQDragLeaveEvent class provides an event which is sent to the widget when a drag and drop leaves the widget.
+
+ \ingroup events
+ \ingroup draganddrop
+
+ This event is always preceded by a TQDragEnterEvent and a series of
+ \l{TQDragMoveEvent}s. It is not sent if a TQDropEvent is sent
+ instead.
+
+ \sa TQDragEnterEvent, TQDragMoveEvent, TQDropEvent
+*/
+
+/*!
+ \fn TQDragLeaveEvent::TQDragLeaveEvent()
+
+ Constructs a TQDragLeaveEvent.
+
+ \warning Do not create a TQDragLeaveEvent yourself since these
+ objects rely on TQt's internal state.
+*/
+
+/*!
+ \class TQHideEvent tqevent.h
+ \brief The TQHideEvent class provides an event which is sent after a widget is hidden.
+
+ \ingroup events
+
+ This event is sent just before TQWidget::hide() returns, and also
+ when a top-level window has been hidden (iconified) by the user.
+
+ If spontaneous() is TRUE the event originated outside the
+ application, i.e. the user hid the window using the window manager
+ controls, either by iconifying the window or by switching to
+ another virtual desktop where the window isn't visible. The window
+ will become hidden but not withdrawn. If the window was iconified,
+ TQWidget::isMinimized() returns TRUE.
+
+ \sa TQShowEvent
+*/
+
+/*!
+ \fn TQHideEvent::TQHideEvent()
+
+ Constructs a TQHideEvent.
+*/
+
+/*!
+ \class TQShowEvent tqevent.h
+ \brief The TQShowEvent class provides an event which is sent when a widget is shown.
+
+ \ingroup events
+
+ There are two kinds of show events: show events caused by the
+ window system (spontaneous) and internal show events. Spontaneous
+ show events are sent just after the window system shows the
+ window, including after a top-level window has been shown
+ (un-iconified) by the user. Internal show events are delivered
+ just before the widget becomes visible.
+
+ \sa TQHideEvent
+*/
+
+/*!
+ \fn TQShowEvent::TQShowEvent()
+
+ Constructs a TQShowEvent.
+*/
+
+
+/*!
+ \fn TQByteArray TQDropEvent::data(const char* f) const
+
+ \obsolete
+
+ Use TQDropEvent::tqencodedData().
+*/
+
+
+/*!
+ Destroys the event. If it was \link
+ TQApplication::postEvent() posted \endlink,
+ it will be removed from the list of events to be posted.
+*/
+
+TQEvent::~TQEvent()
+{
+ if ( posted && tqApp )
+ TQApplication::removePostedEvent( this );
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqevent.h b/tqtinterface/qt4/src/kernel/tqevent.h
new file mode 100644
index 0000000..224759f
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqevent.h
@@ -0,0 +1,952 @@
+/****************************************************************************
+**
+** Definition of event classes
+**
+** Created : 931029
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQEVENT_H
+#define TQEVENT_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqregion.h"
+#include "tqnamespace.h"
+#include "tqmime.h"
+#include "tqpair.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qevent.h>
+#include "tqtenuminheritance.h"
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQEvent : public QEvent, virtual public TQt
+{
+public:
+ enum NewTypes {
+ Reparent = ParentChange,
+ ChildInsertedRequest = 67, // send ChildInserted compatibility events to receiver
+ ChildInserted = 70, // compatibility child inserted
+// LayoutHint = 72, // compatibility relayout request
+ LayoutHint = LayoutRequest, // compatibility relayout request
+ Accel = 30, // accelerator event
+ AccelAvailable = 32, // accelerator available event
+ AccelOverride = ShortcutOverride, // accelerator override event
+ CaptionChange = WindowTitleChange,
+ IconChange = WindowIconChange,
+ EnterEditFocus = 150, // enter edit mode in keypad navigation
+ LeaveEditFocus = 151, // enter edit mode in keypad navigation
+ IMStart = 500, // input method composition start
+ IMCompose = 501, // input method composition
+ IMEnd = 502, // input method composition end
+ ParentPaletteChange = 503, // parent palette changed [FIXME Not triggered anywhere]
+ ParentFontChange = 504, // parent font changed [FIXME Not triggered anywhere]
+ ShowMinimized = 600, // OBSOLETE [FIXME]
+ ShowMaximized = 601, // OBSOLETE [FIXME]
+ ShowFullScreen = 602, // OBSOLETE [FIXME]
+ ShowNormal = 603 // OBSOLETE [FIXME]
+ };
+
+ typedef TQTInheritEnum< NewTypes, QEvent::Type > Type;
+
+ TQEvent( Type type ) : QEvent( (QEvent::Type)((int)type) ) {}
+};
+
+class TQ_EXPORT TQTimerEvent : public QTimerEvent
+{
+public:
+ TQTimerEvent( int timerId ) : QTimerEvent( timerId ) {}
+};
+
+class TQ_EXPORT TQMouseEvent : public QMouseEvent
+{
+public:
+ TQMouseEvent( TQEvent::Type type, const TQPoint &pos, int button, int state ) : QMouseEvent( (QEvent::Type)((int)type), pos, (Qt::MouseButton)button, ((Qt::MouseButtons)state & Qt::MouseButtonMask), ((Qt::KeyboardModifiers)state & TQt::KeyButtonMask) ) {}
+ TQMouseEvent( TQEvent::Type type, const TQPoint &pos, const TQPoint&globalPos, int button, int state ) : QMouseEvent( (QEvent::Type)((int)type), pos, globalPos, (Qt::MouseButton)button, ((Qt::MouseButtons)state & Qt::MouseButtonMask), ((Qt::KeyboardModifiers)state & TQt::KeyButtonMask) ) {}
+
+ inline TQt::ButtonState state() const { return TQt::ButtonState((mouseState^b)|int(modifiers())); }
+ inline TQt::ButtonState stateAfter() const { return (buttons() | modifiers()); }
+};
+
+#ifndef TQT_NO_WHEELEVENT
+class TQ_EXPORT TQWheelEvent : public QWheelEvent
+{
+public:
+ TQWheelEvent( const TQPoint &pos, int delta, int state, Qt::Orientation orient = Qt::Vertical ) : QWheelEvent( pos, delta, ((Qt::MouseButtons)state & Qt::MouseButtonMask), ((Qt::KeyboardModifiers)state & TQt::KeyButtonMask), orient ) {}
+ TQWheelEvent( const TQPoint &pos, const TQPoint& globalPos, int delta, int state, Qt::Orientation orient = Qt::Vertical ) : QWheelEvent( pos, globalPos, delta, ((Qt::MouseButtons)state & Qt::MouseButtonMask), ((Qt::KeyboardModifiers)state & TQt::KeyButtonMask), orient ) {}
+
+ inline TQt::ButtonState state() const { return static_cast<TQt::ButtonState>(int(buttons())|int(modifiers())); }
+};
+#endif // TQT_NO_WHEELEVENT
+
+class TQ_EXPORT TQTabletEvent : public QTabletEvent
+{
+public:
+ TQTabletEvent( Type t, const TQPoint &pos, const TQPoint &globalPos, int tqdevice, int pressure, int xTilt, int yTilt, const TQPair<int,int> &uId ) : QTabletEvent( t, pos, globalPos, globalPos, tqdevice, QTabletEvent::UnknownPointer, pressure, xTilt, yTilt, 0, 0, 0, Qt::NoModifier, uId.first ) {}
+ TQTabletEvent( const TQPoint &pos, const TQPoint &globalPos, int tqdevice, int pressure, int xTilt, int yTilt, const TQPair<int,int> &uId ) : QTabletEvent( QEvent::None, pos, globalPos, globalPos, tqdevice, QTabletEvent::UnknownPointer, pressure, xTilt, yTilt, 0, 0, 0, Qt::NoModifier, uId.first ) {}
+};
+
+class TQ_EXPORT TQKeyEvent : public QKeyEvent
+{
+public:
+ TQKeyEvent( Type type, int key, int ascii, int state, const QString& text=QString::null, bool autorep=FALSE, ushort count=1 ) : QKeyEvent( type, key, ((Qt::KeyboardModifiers)state & Qt::KeyboardModifierMask), text, autorep, count ) { TQ_UNUSED(ascii); }
+ TQKeyEvent( TQEvent::NewTypes type, int key, int ascii, int state, const QString& text=QString::null, bool autorep=FALSE, ushort count=1 ) : QKeyEvent( (Type)type, key, ((Qt::KeyboardModifiers)state & Qt::KeyboardModifierMask), text, autorep, count ) { TQ_UNUSED(ascii); }
+ TQt::ButtonState stateAfter() const { return modifiers(); }
+ TQt::ButtonState state() const { return QInputEvent::modifiers(); }
+ int ascii() const { return (text().length() ? TQT_TQSTRING(text()).tqunicode()->toLatin1() : 0); }
+ friend class TQAccelManager;
+};
+
+class TQ_EXPORT TQFocusEvent : public QFocusEvent
+{
+public:
+ TQFocusEvent( Type type ) : QFocusEvent( type ), prev_reason( Qt::OtherFocusReason ) {}
+
+ enum Reason { Mouse=Qt::MouseFocusReason, Tab=Qt::TabFocusReason,
+ Backtab=Qt::BacktabFocusReason, MenuBar=Qt::MenuBarFocusReason,
+ ActiveWindow=Qt::ActiveWindowFocusReason, Other=Qt::OtherFocusReason,
+ Popup=Qt::PopupFocusReason, Shortcut=Qt::ShortcutFocusReason };
+
+ void setReason( Qt::FocusReason reason );
+ void resetReason();
+
+ inline void setReason( Reason reason ) { setReason((Qt::FocusReason)reason); }
+
+private:
+ Qt::FocusReason prev_reason;
+};
+
+class TQ_EXPORT TQPaintEvent : public QPaintEvent
+{
+public:
+ TQPaintEvent( const QRegion& paintRegion, bool erased = TRUE) : QPaintEvent( paintRegion ), erase(erased) {}
+ TQPaintEvent( const QRect &paintRect, bool erased = TRUE ) : QPaintEvent( paintRect ), erase(erased) {}
+ TQPaintEvent( const QRegion &paintRegion, const QRect &paintRect, bool erased = TRUE ) : QPaintEvent( paintRegion ), erase(erased) { TQ_UNUSED(paintRect); }
+
+ inline bool erased() const { return erase; }
+// inline const TQRect &rect() const { const TQRect &rect1 = QPaintEvent::rect(); return rect1; }
+ inline const TQRect rect() const { return TQRect(QPaintEvent::rect()); }
+protected:
+ bool erase;
+};
+
+class TQ_EXPORT TQMoveEvent : public QMoveEvent
+{
+public:
+ TQMoveEvent( const TQPoint &pos, const TQPoint &oldPos ) : QMoveEvent( pos, oldPos ) {}
+};
+
+class TQ_EXPORT TQResizeEvent : public QResizeEvent
+{
+public:
+ TQResizeEvent( const TQSize &size, const TQSize &oldSize ) : QResizeEvent( size, oldSize ) {};
+};
+
+class TQ_EXPORT TQCloseEvent : public QCloseEvent
+{
+public:
+ TQCloseEvent() : QCloseEvent() {}
+};
+
+class TQ_EXPORT TQIconDragEvent : public QIconDragEvent
+{
+public:
+ TQIconDragEvent() : QIconDragEvent() {}
+};
+
+class TQ_EXPORT TQShowEvent : public QShowEvent
+{
+public:
+ TQShowEvent() : QShowEvent() {}
+};
+
+
+class TQ_EXPORT TQHideEvent : public QHideEvent
+{
+public:
+ TQHideEvent() : QHideEvent() {}
+};
+
+class TQ_EXPORT TQContextMenuEvent : public QContextMenuEvent
+{
+public:
+ TQContextMenuEvent( Reason reason, const TQPoint &pos, const TQPoint &globalPos, int state ) : QContextMenuEvent( reason, pos, globalPos ) { TQ_UNUSED(state); }
+ TQContextMenuEvent( Reason reason, const TQPoint &pos, int state ) : QContextMenuEvent( reason, pos ) { TQ_UNUSED(state); }
+
+ bool isAccepted() const { return accpt; }
+ bool isConsumed() const { return consum; }
+ void consume() { accpt = FALSE; consum = TRUE; }
+ void accept() { accpt = TRUE; consum = TRUE; }
+ void ignore() { accpt = FALSE; consum = FALSE; }
+
+ TQt::ButtonState state() const;
+
+protected:
+ bool accpt;
+ bool consum;
+};
+
+// WARNING: Unimplemented in Qt4
+class TQ_EXPORT TQIMEvent : public TQEvent
+{
+public:
+ TQIMEvent( Type type, const TQString &text, int cursorPosition )
+ : TQEvent(type), txt(text), cpos(cursorPosition), a(TRUE) {}
+ const TQString &text() const { return txt; }
+ int cursorPos() const { return cpos; }
+ bool isAccepted() const { return a; }
+ void accept() { a = TRUE; }
+ void ignore() { a = FALSE; }
+ int selectionLength() const;
+
+private:
+ TQString txt;
+ int cpos;
+ bool a;
+};
+
+// WARNING: Unimplemented in Qt4
+class TQ_EXPORT TQIMComposeEvent : public TQIMEvent
+{
+public:
+ TQIMComposeEvent( Type type, const TQString &text, int cursorPosition,
+ int selLength )
+ : TQIMEvent( type, text, cursorPosition ), selLen( selLength ) { }
+
+private:
+ int selLen;
+
+ friend class TQIMEvent;
+};
+
+inline int TQIMEvent::selectionLength() const
+{
+ if ( (TQEvent::NewTypes)type() != IMCompose ) return 0;
+ TQIMComposeEvent *that = (TQIMComposeEvent *) this;
+ return that->selLen;
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+// WARNING: Unimplemented in Qt4
+
+// This class is rather closed at the moment. If you need to create your
+// own DND event objects, write to qt-bugs@trolltech.com and we'll try to
+// tqfind a way to extend it so it covers your needs.
+
+class TQ_EXPORT TQDropEvent : public TQEvent, public TQMimeSource
+{
+public:
+ TQDropEvent( const TQPoint& pos, Type typ=Drop )
+ : TQEvent(typ), p(pos),
+ act(0), accpt(0), accptact(0), resv(0),
+ d(0)
+ {}
+ const TQPoint &pos() const { return p; }
+ bool isAccepted() const { return accpt || accptact; }
+ void accept(bool y=TRUE) { accpt = y; }
+ void ignore() { accpt = FALSE; }
+
+ bool isActionAccepted() const { return accptact; }
+ void acceptAction(bool y=TRUE) { accptact = y; }
+ enum Action { Copy, Link, Move, Private, UserAction=100 };
+ void setAction( Action a ) { act = (uint)a; }
+ Action action() const { return Action(act); }
+
+ TQWidget* source() const;
+ const char* format( int n = 0 ) const;
+ TQByteArray tqencodedData( const char* ) const;
+ bool provides( const char* ) const;
+
+ TQByteArray data(const char* f) const { return tqencodedData(f); }
+
+ void setPoint( const TQPoint& np ) { p = np; }
+
+protected:
+ TQPoint p;
+ uint act:8;
+ uint accpt:1;
+ uint accptact:1;
+ uint resv:5;
+ void * d;
+};
+
+
+
+class TQ_EXPORT TQDragMoveEvent : public TQDropEvent
+{
+public:
+ TQDragMoveEvent( const TQPoint& pos, Type typ=DragMove )
+ : TQDropEvent(pos,typ),
+ rect( pos, TQSize( 1, 1 ) ) {}
+ TQRect answerRect() const { return rect; }
+ void accept( bool y=TRUE ) { TQDropEvent::accept(y); }
+ void accept( const TQRect & r) { accpt = TRUE; rect = r; }
+ void ignore( const TQRect & r) { accpt =FALSE; rect = r; }
+ void ignore() { TQDropEvent::ignore(); }
+
+protected:
+ TQRect rect;
+};
+
+
+class TQ_EXPORT TQDragEnterEvent : public TQDragMoveEvent
+{
+public:
+ TQDragEnterEvent( const TQPoint& pos ) :
+ TQDragMoveEvent(pos, DragEnter) { }
+};
+
+
+/* An internal class */
+class TQ_EXPORT TQDragResponseEvent : public TQEvent
+{
+public:
+ TQDragResponseEvent( bool accepted )
+ : TQEvent(DragResponse), a(accepted) {}
+ bool dragAccepted() const { return a; }
+protected:
+ bool a;
+};
+
+
+class TQ_EXPORT TQDragLeaveEvent : public TQEvent
+{
+public:
+ TQDragLeaveEvent()
+ : TQEvent(DragLeave) {}
+};
+
+#endif // TQT_NO_DRAGANDDROP
+
+class TQ_EXPORT TQChildEvent : public QChildEvent
+{
+public:
+ TQChildEvent( Type type, TQT_BASE_OBJECT_NAME *child ) : QChildEvent( type, child ) {}
+
+ //bool inserted() const { return type() == ChildAdded; } // Should be ChildInserted as below, they are NOT the same!
+ bool inserted() const { return (TQEvent::NewTypes)type() == TQEvent::ChildInserted; }
+};
+
+// WARNING: Unimplemented in Qt4
+class TQ_EXPORT TQCustomEvent : public TQEvent
+{
+public:
+ TQCustomEvent( int type );
+ TQCustomEvent( Type type, void *data )
+ : TQEvent(type), d(data) {};
+ void *data() const { return d; }
+ void setData( void* data ) { d = data; }
+private:
+ void *d;
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQEvent: public TQt // event base class
+{
+public:
+ enum Type {
+
+ /*
+ If you get a strange compiler error on the line with None,
+ it's probably because you're also including X11 headers,
+ which #define the symbol None. Put the X11 includes after
+ the TQt includes to solve this problem.
+ */
+
+ None = 0, // invalid event
+
+
+ Timer = 1, // timer event
+ MouseButtonPress = 2, // mouse button pressed
+ MouseButtonRelease = 3, // mouse button released
+ MouseButtonDblClick = 4, // mouse button double click
+ MouseMove = 5, // mouse move
+ KeyPress = 6, // key pressed
+ KeyRelease = 7, // key released
+ FocusIn = 8, // keyboard focus received
+ FocusOut = 9, // keyboard focus lost
+ Enter = 10, // mouse enters widget
+ Leave = 11, // mouse leaves widget
+ Paint = 12, // paint widget
+ Move = 13, // move widget
+ Resize = 14, // resize widget
+ Create = 15, // after object creation
+ Destroy = 16, // during object destruction
+ Show = 17, // widget is shown
+ Hide = 18, // widget is hidden
+ Close = 19, // request to close widget
+ Quit = 20, // request to quit application
+ Retqparent = 21, // widget has been reparented
+ ShowMinimized = 22, // widget is shown minimized
+ ShowNormal = 23, // widget is shown normal
+ WindowActivate = 24, // window was activated
+ WindowDeactivate = 25, // window was deactivated
+ ShowToParent = 26, // widget is shown to tqparent
+ HideToParent = 27, // widget is hidden to tqparent
+ ShowMaximized = 28, // widget is shown maximized
+ ShowFullScreen = 29, // widget is shown full-screen
+ Accel = 30, // accelerator event
+ Wheel = 31, // wheel event
+ AccelAvailable = 32, // accelerator available event
+ CaptionChange = 33, // caption changed
+ IconChange = 34, // icon changed
+ ParentFontChange = 35, // tqparent font changed
+ ApplicationFontChange = 36, // application font changed
+ ParentPaletteChange = 37, // tqparent palette changed
+ ApplicationPaletteChange = 38, // application palette changed
+ PaletteChange = 39, // widget palette changed
+ Clipboard = 40, // internal clipboard event
+ Speech = 42, // reserved for speech input
+ SockAct = 50, // socket activation
+ AccelOverride = 51, // accelerator override event
+ DeferredDelete = 52, // deferred delete event
+ DragEnter = 60, // drag moves into widget
+ DragMove = 61, // drag moves in widget
+ DragLeave = 62, // drag leaves or is cancelled
+ Drop = 63, // actual drop
+ DragResponse = 64, // drag accepted/rejected
+ ChildInserted = 70, // new child widget
+ ChildRemoved = 71, // deleted child widget
+ LayoutHint = 72, // child min/max size changed
+ ShowWindowRequest = 73, // widget's window should be mapped
+ WindowBlocked = 74, // window is about to be blocked modally
+ WindowUnblocked = 75, // windows modal blocking has ended
+ ActivateControl = 80, // ActiveX activation
+ DeactivateControl = 81, // ActiveX deactivation
+ ContextMenu = 82, // context popup menu
+ IMStart = 83, // input method composition start
+ IMCompose = 84, // input method composition
+ IMEnd = 85, // input method composition end
+ Accessibility = 86, // accessibility information is requested
+ TabletMove = 87, // Wacom tablet event
+ LocaleChange = 88, // the system locale changed
+ LanguageChange = 89, // the application language changed
+ LayoutDirectionChange = 90, // the tqlayout direction changed
+ Style = 91, // internal style event
+ TabletPress = 92, // tablet press
+ TabletRelease = 93, // tablet release
+ OkRequest = 94, // CE (Ok) button pressed
+ HelpRequest = 95, // CE (?) button pressed
+ WindowStateChange = 96, // window state has changed
+ IconDrag = 97, // proxy icon dragged
+ User = 1000, // first user event id
+ MaxUser = 65535 // last user event id
+ };
+
+
+ TQEvent( Type type ) : t(type), posted(FALSE), spont(FALSE) {}
+ virtual ~TQEvent();
+ Type type() const { return t; }
+ bool spontaneous() const { return spont; }
+protected:
+ Type t;
+private:
+ uint posted : 1;
+ uint spont : 1;
+
+
+ friend class TQApplication;
+ friend class TQAccelManager;
+ friend class TQBaseApplication;
+ friend class TQETWidget;
+};
+
+
+class TQ_EXPORT TQTimerEvent : public TQEvent
+{
+public:
+ TQTimerEvent( int timerId )
+ : TQEvent(Timer), id(timerId) {}
+ int timerId() const { return id; }
+protected:
+ int id;
+};
+
+
+class TQ_EXPORT TQMouseEvent : public TQEvent
+{
+public:
+ TQMouseEvent( Type type, const TQPoint &pos, int button, int state );
+
+ TQMouseEvent( Type type, const TQPoint &pos, const TQPoint&globalPos,
+ int button, int state )
+ : TQEvent(type), p(pos), g(globalPos), b((ushort)button),s((ushort)state),accpt(TRUE) {};
+
+ const TQPoint &pos() const { return p; }
+ const TQPoint &globalPos() const { return g; }
+ int x() const { return p.x(); }
+ int y() const { return p.y(); }
+ int globalX() const { return g.x(); }
+ int globalY() const { return g.y(); }
+ ButtonState button() const { return (ButtonState) b; }
+ ButtonState state() const { return (ButtonState) s; }
+ ButtonState stateAfter() const;
+ bool isAccepted() const { return accpt; }
+ void accept() { accpt = TRUE; }
+ void ignore() { accpt = FALSE; }
+protected:
+ TQPoint p;
+ TQPoint g;
+ ushort b;
+ ushort s;
+ uint accpt:1;
+};
+
+
+#ifndef TQT_NO_WHEELEVENT
+class TQ_EXPORT TQWheelEvent : public TQEvent
+{
+public:
+ TQWheelEvent( const TQPoint &pos, int delta, int state, Orientation orient = Vertical );
+ TQWheelEvent( const TQPoint &pos, const TQPoint& globalPos, int delta, int state, Orientation orient = Vertical )
+ : TQEvent(Wheel), p(pos), g(globalPos), d(delta), s((ushort)state),
+ accpt(TRUE), o(orient) {}
+ int delta() const { return d; }
+ const TQPoint &pos() const { return p; }
+ const TQPoint &globalPos() const { return g; }
+ int x() const { return p.x(); }
+ int y() const { return p.y(); }
+ int globalX() const { return g.x(); }
+ int globalY() const { return g.y(); }
+ ButtonState state() const { return ButtonState(s); }
+ Orientation orientation() const { return o; }
+ bool isAccepted() const { return accpt; }
+ void accept() { accpt = TRUE; }
+ void ignore() { accpt = FALSE; }
+protected:
+ TQPoint p;
+ TQPoint g;
+ int d;
+ ushort s;
+ bool accpt;
+ Orientation o;
+};
+#endif
+
+class TQ_EXPORT TQTabletEvent : public TQEvent
+{
+public:
+ enum TabletDevice { NoDevice = -1, Puck, Stylus, Eraser };
+ TQTabletEvent( Type t, const TQPoint &pos, const TQPoint &globalPos, int tqdevice,
+ int pressure, int xTilt, int yTilt, const TQPair<int,int> &uId );
+ TQTabletEvent( const TQPoint &pos, const TQPoint &globalPos, int tqdevice,
+ int pressure, int xTilt, int yTilt, const TQPair<int,int> &uId )
+ : TQEvent( TabletMove ), mPos( pos ), mGPos( globalPos ), mDev( tqdevice ),
+ mPress( pressure ), mXT( xTilt ), mYT( yTilt ), mType( uId.first ),
+ mPhy( uId.second ), mbAcc(TRUE)
+ {}
+ int pressure() const { return mPress; }
+ int xTilt() const { return mXT; }
+ int yTilt() const { return mYT; }
+ const TQPoint &pos() const { return mPos; }
+ const TQPoint &globalPos() const { return mGPos; }
+ int x() const { return mPos.x(); }
+ int y() const { return mPos.y(); }
+ int globalX() const { return mGPos.x(); }
+ int globalY() const { return mGPos.y(); }
+ TabletDevice tqdevice() const { return TabletDevice(mDev); }
+ int isAccepted() const { return mbAcc; }
+ void accept() { mbAcc = TRUE; }
+ void ignore() { mbAcc = FALSE; }
+ TQPair<int,int> uniqueId() { return TQPair<int,int>( mType, mPhy); }
+protected:
+ TQPoint mPos;
+ TQPoint mGPos;
+ int mDev,
+ mPress,
+ mXT,
+ mYT,
+ mType,
+ mPhy;
+ bool mbAcc;
+
+};
+
+class TQ_EXPORT TQKeyEvent : public TQEvent
+{
+public:
+ TQKeyEvent( Type type, int key, int ascii, int state,
+ const TQString& text=TQString::null, bool autorep=FALSE, ushort count=1 )
+ : TQEvent(type), txt(text), k((ushort)key), s((ushort)state),
+ a((uchar)ascii), accpt(TRUE), autor(autorep), c(count)
+ {
+ if ( key >= Key_Back && key <= Key_MediaLast )
+ accpt = FALSE;
+ }
+ int key() const { return k; }
+ int ascii() const { return a; }
+ ButtonState state() const { return ButtonState(s); }
+ ButtonState stateAfter() const;
+ bool isAccepted() const { return accpt; }
+ TQString text() const { return txt; }
+ bool isAutoRepeat() const { return autor; }
+ int count() const { return int(c); }
+ void accept() { accpt = TRUE; }
+ void ignore() { accpt = FALSE; }
+
+protected:
+ TQString txt;
+ ushort k, s;
+ uchar a;
+ uint accpt:1;
+ uint autor:1;
+ ushort c;
+};
+
+
+class TQ_EXPORT TQFocusEvent : public TQEvent
+{
+public:
+
+ TQFocusEvent( Type type )
+ : TQEvent(type) {}
+
+ bool gotFocus() const { return type() == FocusIn; }
+ bool lostFocus() const { return type() == FocusOut; }
+
+ enum Reason { Mouse, Tab, Backtab, ActiveWindow, Popup, Shortcut, Other };
+ static Reason reason();
+ static void setReason( Reason reason );
+ static void resetReason();
+
+private:
+ static Reason m_reason;
+ static Reason prev_reason;
+};
+
+
+class TQ_EXPORT TQPaintEvent : public TQEvent
+{
+public:
+ TQPaintEvent( const TQRegion& paintRegion, bool erased = TRUE)
+ : TQEvent(Paint),
+ rec(paintRegion.boundingRect()),
+ reg(paintRegion),
+ erase(erased){}
+ TQPaintEvent( const TQRect &paintRect, bool erased = TRUE )
+ : TQEvent(Paint),
+ rec(paintRect),
+ reg(paintRect),
+ erase(erased){}
+ TQPaintEvent( const TQRegion &paintRegion, const TQRect &paintRect, bool erased = TRUE )
+ : TQEvent(Paint),
+ rec(paintRect),
+ reg(paintRegion),
+ erase(erased){}
+
+ const TQRect &rect() const { return rec; }
+ const TQRegion &region() const { return reg; }
+ bool erased() const { return erase; }
+protected:
+ friend class TQApplication;
+ friend class TQBaseApplication;
+ TQRect rec;
+ TQRegion reg;
+ bool erase;
+};
+
+
+class TQ_EXPORT TQMoveEvent : public TQEvent
+{
+public:
+ TQMoveEvent( const TQPoint &pos, const TQPoint &oldPos )
+ : TQEvent(Move), p(pos), oldp(oldPos) {}
+ const TQPoint &pos() const { return p; }
+ const TQPoint &oldPos()const { return oldp;}
+protected:
+ TQPoint p, oldp;
+ friend class TQApplication;
+ friend class TQBaseApplication;
+};
+
+
+class TQ_EXPORT TQResizeEvent : public TQEvent
+{
+public:
+ TQResizeEvent( const TQSize &size, const TQSize &oldSize )
+ : TQEvent(Resize), s(size), olds(oldSize) {}
+ const TQSize &size() const { return s; }
+ const TQSize &oldSize()const { return olds;}
+protected:
+ TQSize s, olds;
+ friend class TQApplication;
+ friend class TQBaseApplication;
+};
+
+
+class TQ_EXPORT TQCloseEvent : public TQEvent
+{
+public:
+ TQCloseEvent()
+ : TQEvent(Close), accpt(FALSE) {}
+ bool isAccepted() const { return accpt; }
+ void accept() { accpt = TRUE; }
+ void ignore() { accpt = FALSE; }
+protected:
+ bool accpt;
+};
+
+
+class TQ_EXPORT TQIconDragEvent : public TQEvent
+{
+public:
+ TQIconDragEvent()
+ : TQEvent(IconDrag), accpt(FALSE) {}
+
+ bool isAccepted() const { return accpt; }
+ void accept() { accpt = TRUE; }
+ void ignore() { accpt = FALSE; }
+protected:
+ bool accpt;
+};
+
+class TQ_EXPORT TQShowEvent : public TQEvent
+{
+public:
+ TQShowEvent()
+ : TQEvent(Show) {}
+};
+
+
+class TQ_EXPORT TQHideEvent : public TQEvent
+{
+public:
+ TQHideEvent()
+ : TQEvent(Hide) {}
+};
+
+class TQ_EXPORT TQContextMenuEvent : public TQEvent
+{
+public:
+ enum Reason { Mouse, Keyboard, Other };
+ TQContextMenuEvent( Reason reason, const TQPoint &pos, const TQPoint &globalPos, int state )
+ : TQEvent( ContextMenu ), p( pos ), gp( globalPos ), accpt( TRUE ), consum( TRUE ),
+ reas( reason ), s((ushort)state) {}
+ TQContextMenuEvent( Reason reason, const TQPoint &pos, int state );
+
+ int x() const { return p.x(); }
+ int y() const { return p.y(); }
+ int globalX() const { return gp.x(); }
+ int globalY() const { return gp.y(); }
+
+ const TQPoint& pos() const { return p; }
+ const TQPoint& globalPos() const { return gp; }
+
+ ButtonState state() const { return (ButtonState) s; }
+ bool isAccepted() const { return accpt; }
+ bool isConsumed() const { return consum; }
+ void consume() { accpt = FALSE; consum = TRUE; }
+ void accept() { accpt = TRUE; consum = TRUE; }
+ void ignore() { accpt = FALSE; consum = FALSE; }
+
+ Reason reason() const { return Reason( reas ); }
+
+protected:
+ TQPoint p;
+ TQPoint gp;
+ bool accpt;
+ bool consum;
+ uint reas:8;
+ ushort s;
+};
+
+
+class TQ_EXPORT TQIMEvent : public TQEvent
+{
+public:
+ TQIMEvent( Type type, const TQString &text, int cursorPosition )
+ : TQEvent(type), txt(text), cpos(cursorPosition), a(TRUE) {}
+ const TQString &text() const { return txt; }
+ int cursorPos() const { return cpos; }
+ bool isAccepted() const { return a; }
+ void accept() { a = TRUE; }
+ void ignore() { a = FALSE; }
+ int selectionLength() const;
+
+private:
+ TQString txt;
+ int cpos;
+ bool a;
+};
+
+class TQ_EXPORT TQIMComposeEvent : public TQIMEvent
+{
+public:
+ TQIMComposeEvent( Type type, const TQString &text, int cursorPosition,
+ int selLength )
+ : TQIMEvent( type, text, cursorPosition ), selLen( selLength ) { }
+
+private:
+ int selLen;
+
+ friend class TQIMEvent;
+};
+
+inline int TQIMEvent::selectionLength() const
+{
+ if ( type() != IMCompose ) return 0;
+ TQIMComposeEvent *that = (TQIMComposeEvent *) this;
+ return that->selLen;
+}
+
+
+#ifndef TQT_NO_DRAGANDDROP
+
+// This class is rather closed at the moment. If you need to create your
+// own DND event objects, write to qt-bugs@trolltech.com and we'll try to
+// tqfind a way to extend it so it covers your needs.
+
+class TQ_EXPORT TQDropEvent : public TQEvent, public TQMimeSource
+{
+public:
+ TQDropEvent( const TQPoint& pos, Type typ=Drop )
+ : TQEvent(typ), p(pos),
+ act(0), accpt(0), accptact(0), resv(0),
+ d(0)
+ {}
+ const TQPoint &pos() const { return p; }
+ bool isAccepted() const { return accpt || accptact; }
+ void accept(bool y=TRUE) { accpt = y; }
+ void ignore() { accpt = FALSE; }
+
+ bool isActionAccepted() const { return accptact; }
+ void acceptAction(bool y=TRUE) { accptact = y; }
+ enum Action { Copy, Link, Move, Private, UserAction=100 };
+ void setAction( Action a ) { act = (uint)a; }
+ Action action() const { return Action(act); }
+
+ TQWidget* source() const;
+ const char* format( int n = 0 ) const;
+ TQByteArray tqencodedData( const char* ) const;
+ bool provides( const char* ) const;
+
+ TQByteArray data(const char* f) const { return tqencodedData(f); }
+
+ void setPoint( const TQPoint& np ) { p = np; }
+
+protected:
+ TQPoint p;
+ uint act:8;
+ uint accpt:1;
+ uint accptact:1;
+ uint resv:5;
+ void * d;
+};
+
+
+
+class TQ_EXPORT TQDragMoveEvent : public TQDropEvent
+{
+public:
+ TQDragMoveEvent( const TQPoint& pos, Type typ=DragMove )
+ : TQDropEvent(pos,typ),
+ rect( pos, TQSize( 1, 1 ) ) {}
+ TQRect answerRect() const { return rect; }
+ void accept( bool y=TRUE ) { TQDropEvent::accept(y); }
+ void accept( const TQRect & r) { accpt = TRUE; rect = r; }
+ void ignore( const TQRect & r) { accpt =FALSE; rect = r; }
+ void ignore() { TQDropEvent::ignore(); }
+
+protected:
+ TQRect rect;
+};
+
+
+class TQ_EXPORT TQDragEnterEvent : public TQDragMoveEvent
+{
+public:
+ TQDragEnterEvent( const TQPoint& pos ) :
+ TQDragMoveEvent(pos, DragEnter) { }
+};
+
+
+/* An internal class */
+class TQ_EXPORT TQDragResponseEvent : public TQEvent
+{
+public:
+ TQDragResponseEvent( bool accepted )
+ : TQEvent(DragResponse), a(accepted) {}
+ bool dragAccepted() const { return a; }
+protected:
+ bool a;
+};
+
+
+class TQ_EXPORT TQDragLeaveEvent : public TQEvent
+{
+public:
+ TQDragLeaveEvent()
+ : TQEvent(DragLeave) {}
+};
+
+#endif // TQT_NO_DRAGANDDROP
+
+class TQ_EXPORT TQChildEvent : public TQEvent
+{
+public:
+ TQChildEvent( Type type, TQObject *child )
+ : TQEvent(type), c(child) {}
+ TQObject *child() const { return c; }
+ bool inserted() const { return t == ChildInserted; }
+ bool removed() const { return t == ChildRemoved; }
+protected:
+ TQObject *c;
+};
+
+
+class TQ_EXPORT TQCustomEvent : public TQEvent
+{
+public:
+ TQCustomEvent( int type );
+ TQCustomEvent( Type type, void *data )
+ : TQEvent(type), d(data) {};
+ void *data() const { return d; }
+ void setData( void* data ) { d = data; }
+private:
+ void *d;
+};
+
+#endif // USE_QT4
+
+#endif // TQEVENT_H
diff --git a/tqtinterface/qt4/src/kernel/tqeventloop.cpp b/tqtinterface/qt4/src/kernel/tqeventloop.cpp
new file mode 100644
index 0000000..704fc43
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqeventloop.cpp
@@ -0,0 +1,394 @@
+/****************************************************************************
+**
+** Implementation of TQEventLoop class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqeventloop_p.h" // includes qplatformdefs.h
+#include "tqeventloop.h"
+#include "tqapplication.h"
+#include "tqdatetime.h"
+
+/*!
+ \class TQEventLoop
+ \brief The TQEventLoop class manages the event queue.
+
+ \ingroup application
+ \ingroup events
+
+ It receives events from the window system and other sources. It
+ then sends them to TQApplication for processing and delivery.
+
+ TQEventLoop allows the application programmer to have more control
+ over event delivery. Programs that perform long operations can
+ call either processOneEvent() or processEvents() with various
+ ProcessEvent values OR'ed together to control which events should
+ be delivered.
+
+ TQEventLoop also allows the integration of an external event loop
+ with the TQt event loop. The Motif Extension included with TQt
+ includes a reimplementation of TQEventLoop for merging TQt and Motif
+ events together.
+
+ To use your own instance of TQEventLoop or TQEventLoop subclass create
+ it before you create the TQApplication object.
+*/
+
+/*! \enum TQEventLoop::ProcessEvents
+
+ This enum controls the types of events processed by the
+ processEvents() functions.
+
+ \value AllEvents - All events are processed
+ \value ExcludeUserInput - Do not process user input events.
+ ( ButtonPress, KeyPress, etc. )
+ \value ExcludeSocketNotifiers - Do not process socket notifier
+ events.
+ \value WaitForMore - Wait for events if no pending events
+ are available.
+
+ \sa processEvents()
+*/
+
+/*! \enum TQEventLoop::ProcessEventsFlags
+ A \c typedef to allow various ProcessEvents values to be OR'ed together.
+
+ \sa ProcessEvents
+ */
+
+/*!
+ Creates a TQEventLoop object, this object becomes the global event loop object.
+ There can only be one event loop object. The TQEventLoop is usually constructed
+ by calling TQApplication::eventLoop(). To create your own event loop object create
+ it before you instantiate the TQApplication object.
+
+ The \a tqparent and \a name arguments are passed on to the TQObject constructor.
+*/
+TQEventLoop::TQEventLoop( TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( TQApplication::eventloop )
+ qFatal( "TQEventLoop: there must be only one event loop object. \nConstruct it before TQApplication." );
+ // for now ;)
+#endif // TQT_CHECK_STATE
+
+ d = new TQEventLoopPrivate;
+
+ init();
+ TQApplication::eventloop = this;
+}
+
+/*!
+ Destructs the TQEventLoop object.
+*/
+TQEventLoop::~TQEventLoop()
+{
+ cleanup();
+ delete d;
+ TQApplication::eventloop = 0;
+}
+
+/*!
+ Enters the main event loop and waits until exit() is called, and
+ returns the value that was set to exit().
+
+ It is necessary to call this function to start event handling. The
+ main event loop receives events from the window system and
+ dispatches these to the application widgets.
+
+ Generally speaking, no user interaction can take place before
+ calling exec(). As a special case, modal widgets like TQMessageBox
+ can be used before calling exec(), because modal widgets call
+ exec() to start a local event loop.
+
+ To make your application perform idle processing, i.e. executing a
+ special function whenever there are no pending events, use a
+ TQTimer with 0 timeout. More advanced idle processing schemes can
+ be achieved using processEvents().
+
+ \sa TQApplication::quit(), exit(), processEvents()
+*/
+int TQEventLoop::exec()
+{
+ d->reset();
+
+ enterLoop();
+
+ // cleanup
+ d->looplevel = 0;
+ d->quitnow = FALSE;
+ d->exitloop = FALSE;
+ d->shortcut = FALSE;
+ // don't reset quitcode!
+
+ return d->quitcode;
+}
+
+/*! \fn void TQEventLoop::exit( int retcode = 0 )
+
+ Tells the event loop to exit with a return code.
+
+ After this function has been called, the event loop returns from
+ the call to exec(). The exec() function returns \a retcode.
+
+ By convention, a \a retcode of 0 means success, and any non-zero
+ value indicates an error.
+
+ Note that unlike the C library function of the same name, this
+ function \e does return to the caller -- it is event processing that
+ stops.
+
+ \sa TQApplication::quit(), exec()
+*/
+void TQEventLoop::exit( int retcode )
+{
+ if ( d->quitnow ) // preserve existing quitcode
+ return;
+ d->quitcode = retcode;
+ d->quitnow = TRUE;
+ d->exitloop = TRUE;
+ d->shortcut = TRUE;
+}
+
+
+/*! \fn int TQEventLoop::enterLoop()
+
+ This function enters the main event loop (recursively). Do not call
+ it unless you really know what you are doing.
+ */
+int TQEventLoop::enterLoop()
+{
+ // save the current exitloop state
+ bool old_exitloop = d->exitloop;
+ d->exitloop = FALSE;
+ d->shortcut = FALSE;
+
+ d->looplevel++;
+ while ( ! d->exitloop )
+ processEvents( AllEvents | WaitForMore );
+ d->looplevel--;
+
+ // restore the exitloop state, but if quitnow is TRUE, we need to keep
+ // exitloop set so that all other event loops drop out.
+ d->exitloop = old_exitloop || d->quitnow;
+ d->shortcut = d->quitnow;
+
+ if ( d->looplevel < 1 ) {
+ d->quitnow = FALSE;
+ d->exitloop = FALSE;
+ d->shortcut = FALSE;
+ emit tqApp->aboutToQuit();
+
+ // send deferred deletes
+ TQApplication::sendPostedEvents( 0, TQEvent::DeferredDelete );
+ }
+
+ return d->looplevel;
+}
+
+/*! \fn void TQEventLoop::exitLoop()
+
+ This function exits from a recursive call to the main event loop.
+ Do not call it unless you really know what you are doing.
+*/
+void TQEventLoop::exitLoop()
+{
+ d->exitloop = TRUE;
+ d->shortcut = TRUE;
+}
+
+/*! \fn void TQEventLoop::loopLevel() const
+
+ Returns the current loop level.
+*/
+int TQEventLoop::loopLevel() const
+{
+ return d->looplevel;
+}
+
+/*!
+ Process pending events that match \a flags for a maximum of \a
+ maxTime milliseconds, or until there are no more events to
+ process, which ever is shorter.
+
+ This function is especially useful if you have a long running
+ operation and want to show its progress without allowing user
+ input, i.e. by using the \c ExcludeUserInput flag.
+
+ NOTE: This function will not process events continuously; it
+ returns after all available events are processed.
+
+ NOTE: Specifying the \c WaitForMore flag makes no sense and will
+ be ignored.
+*/
+void TQEventLoop::processEvents( ProcessEventsFlags flags, int maxTime )
+{
+ TQTime start = TQTime::currentTime();
+ TQTime now;
+ while ( ! d->quitnow && processEvents( flags & ~WaitForMore ) ) {
+ now = TQTime::currentTime();
+ if ( start.msecsTo( now ) > maxTime )
+ break;
+ }
+}
+
+/*!
+ \fn bool TQEventLoop::processEvents( ProcessEventsFlags flags )
+ \overload
+
+ Processes pending events that match \a flags until there are no
+ more events to process.
+
+ This function is especially useful if you have a long running
+ operation and want to show its progress without allowing user
+ input, i.e. by using the \c ExcludeUserInput flag.
+
+ If the \c WaitForMore flag is set in \a flags, the behavior of
+ this function is as follows:
+
+ \list
+
+ \i If events are available, this function returns after processing
+ them.
+
+ \i If no events are available, this function will wait until more
+ are available and return after processing newly available events.
+
+ \endlist
+
+ If the \c WaitForMore flag is \e not set in \a flags, and no
+ events are available, this function will return immediately.
+
+ NOTE: This function will not process events continuously; it
+ returns after all available events are processed.
+
+ This function returns TRUE if an event was processed; otherwise it
+ returns FALSE.
+
+ \sa ProcessEvents hasPendingEvents()
+*/
+
+/*! \fn bool TQEventLoop::hasPendingEvents() const
+
+ Returns TRUE if there is an event waiting, otherwise it returns FALSE.
+*/
+
+/*! \fn void TQEventLoop::registerSocketNotifier( TQSocketNotifier *notifier )
+
+ Registers \a notifier with the event loop. Subclasses need to
+ reimplement this method to tie a socket notifier into another
+ event loop. Reimplementations \e MUST call the base
+ implementation.
+*/
+
+/*! \fn void TQEventLoop::unregisterSocketNotifier( TQSocketNotifier *notifier )
+
+ Unregisters \a notifier from the event loop. Subclasses need to
+ reimplement this method to tie a socket notifier into another
+ event loop. Reimplementations \e MUST call the base
+ implementation.
+*/
+
+/*! \fn void TQEventLoop::setSocketNotifierPending( TQSocketNotifier *notifier )
+
+ Marks \a notifier as pending. The socket notifier will be
+ activated the next time activateSocketNotifiers() is called.
+*/
+
+/*! \fn int TQEventLoop::activateSocketNotifiers()
+
+ Activates all pending socket notifiers and returns the number of
+ socket notifiers that were activated.
+*/
+
+/*! \fn int TQEventLoop::activateTimers()
+
+ Activates all TQt timers and returns the number of timers that were
+ activated.
+
+ TQEventLoop subclasses that do their own timer handling need to
+ call this after the time returned by timeToWait() has elapsed.
+
+ Note: This function is only useful on systems where \c select() is
+ used to block the eventloop. On Windows, this function always
+ returns 0. On MacOS X, this function always returns 0 when the
+ GUI is enabled. On MacOS X, this function returns the documented
+ value when the GUI is disabled.
+*/
+
+/*! \fn int TQEventLoop::timeToWait() const
+
+ Returns the number of milliseconds that TQt needs to handle its
+ timers or -1 if there are no timers running.
+
+ TQEventLoop subclasses that do their own timer handling need to use
+ this to make sure that TQt's timers continue to work.
+
+ Note: This function is only useful on systems where \c select() is
+ used to block the eventloop. On Windows, this function always
+ returns -1. On MacOS X, this function always returns -1 when the
+ GUI is enabled. On MacOS X, this function returns the documented
+ value when the GUI is disabled.
+*/
+
+/*! \fn void TQEventLoop::wakeUp()
+ \threadsafe
+
+ Wakes up the event loop.
+
+ \sa awake()
+*/
+
+/*! \fn void TQEventLoop::awake()
+
+ This signal is emitted after the event loop returns from a
+ function that could block.
+
+ \sa wakeUp() aboutToBlock()
+*/
+
+/*! \fn void TQEventLoop::aboutToBlock()
+
+ This signal is emitted before the event loop calls a function that
+ could block.
+
+ \sa awake()
+*/
+
+#if !defined(TQ_WS_X11)
+void TQEventLoop::appStartingUp(){}
+void TQEventLoop::appClosingDown(){}
+#endif // TQ_WS_X11
diff --git a/tqtinterface/qt4/src/kernel/tqeventloop.h b/tqtinterface/qt4/src/kernel/tqeventloop.h
new file mode 100644
index 0000000..d837a75
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqeventloop.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Declaration of TQEventLoop class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQEVENTLOOP_H
+#define TQEVENTLOOP_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqsocketnotifier.h"
+#endif // TQT_H
+
+class TQEventLoopPrivate;
+class TQSocketNotifier;
+class TQTimer;
+#ifdef TQ_WS_MAC
+struct timeval; //stdc struct
+struct TimerInfo; //internal structure (qeventloop_mac.cpp)
+#endif
+
+#if defined(TQT_THREAD_SUPPORT)
+class TQMutex;
+#endif // TQT_THREAD_SUPPORT
+
+
+class TQ_EXPORT TQEventLoop : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQEventLoop( TQObject *tqparent = 0, const char *name = 0 );
+ ~TQEventLoop();
+
+ enum ProcessEvents {
+ AllEvents = 0x00,
+ ExcludeUserInput = 0x01,
+ ExcludeSocketNotifiers = 0x02,
+ WaitForMore = 0x04
+ };
+ typedef uint ProcessEventsFlags;
+
+ void processEvents( ProcessEventsFlags flags, int maxtime );
+ virtual bool processEvents( ProcessEventsFlags flags );
+
+ virtual bool hasPendingEvents() const;
+
+ virtual void registerSocketNotifier( TQSocketNotifier * );
+ virtual void unregisterSocketNotifier( TQSocketNotifier * );
+ void setSocketNotifierPending( TQSocketNotifier * );
+ int activateSocketNotifiers();
+
+ int activateTimers();
+ int timeToWait() const;
+
+ virtual int exec();
+ virtual void exit( int retcode = 0 );
+
+ virtual int enterLoop();
+ virtual void exitLoop();
+ virtual int loopLevel() const;
+
+ virtual void wakeUp();
+
+Q_SIGNALS:
+ void awake();
+ void aboutToBlock();
+
+private:
+#if defined(TQ_WS_MAC)
+ friend TQMAC_PASCAL void qt_mac_select_timer_callbk(EventLoopTimerRef, void *);
+ int macHandleSelect(timeval *);
+ void macHandleTimer(TimerInfo *);
+#endif // TQ_WS_MAC
+
+ // internal initialization/cleanup - implemented in various platform specific files
+ void init();
+ void cleanup();
+ virtual void appStartingUp();
+ virtual void appClosingDown();
+
+ // data for the default implementation - other implementations should not
+ // use/need this data
+ TQEventLoopPrivate *d;
+
+ friend class TQApplication;
+};
+
+#endif // TQEVENTLOOP_H
diff --git a/tqtinterface/qt4/src/kernel/tqeventloop_p.h b/tqtinterface/qt4/src/kernel/tqeventloop_p.h
new file mode 100644
index 0000000..92ef2f1
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqeventloop_p.h
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Definition of TQEventLoop class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQEVENTLOOP_P_H
+#define TQEVENTLOOP_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqplatformdefs.h"
+#endif // TQT_H
+
+// SCO OpenServer redefines raise -> kill
+#if defined(raise)
+# undef raise
+#endif
+
+#include "tqwindowdefs.h"
+
+class TQSocketNotifier;
+#ifdef TQ_OS_MAC
+class TQMacSockNotPrivate;
+#endif
+
+#if defined(TQ_OS_UNIX) || defined (TQ_WS_WIN)
+#include "tqptrlist.h"
+#endif // TQ_OS_UNIX || TQ_WS_WIN
+
+#if defined(TQ_OS_UNIX)
+struct TQSockNot
+{
+ TQSocketNotifier *obj;
+ int fd;
+ fd_set *queue;
+};
+
+class TQSockNotType
+{
+public:
+ TQSockNotType();
+ ~TQSockNotType();
+
+ TQPtrList<TQSockNot> *list;
+ fd_set select_fds;
+ fd_set enabled_fds;
+ fd_set pending_fds;
+
+};
+#endif // TQ_OS_UNIX
+
+#if defined(TQ_WS_WIN)
+struct TQSockNot {
+ TQSocketNotifier *obj;
+ int fd;
+};
+#endif // TQ_WS_WIN
+
+class TQEventLoopPrivate
+{
+public:
+ TQEventLoopPrivate()
+ {
+ reset();
+ }
+
+ void reset() {
+ looplevel = 0;
+ quitcode = 0;
+ quitnow = FALSE;
+ exitloop = FALSE;
+ shortcut = FALSE;
+ }
+
+ int looplevel;
+ int quitcode;
+ unsigned int quitnow : 1;
+ unsigned int exitloop : 1;
+ unsigned int shortcut : 1;
+
+#if defined(TQ_WS_MAC)
+ uchar next_select_timer;
+ EventLoopTimerRef select_timer;
+#endif
+
+#if defined(TQ_WS_X11)
+ int xfd;
+#endif // TQ_WS_X11
+
+#if defined(TQ_OS_UNIX)
+ int thread_pipe[2];
+
+ // pending socket notifiers list
+ TQPtrList<TQSockNot> sn_pending_list;
+ // highest fd for all socket notifiers
+ int sn_highest;
+ // 3 socket notifier types - read, write and exception
+ TQSockNotType sn_vec[3];
+#endif
+
+#ifdef TQ_WS_WIN
+ // pending socket notifiers list
+ TQPtrList<TQSockNot> sn_pending_list;
+#endif // TQ_WS_WIN
+
+};
+
+#endif // TQEVENTLOOP_P_H
diff --git a/tqtinterface/qt4/src/kernel/tqeventloop_unix.cpp b/tqtinterface/qt4/src/kernel/tqeventloop_unix.cpp
new file mode 100644
index 0000000..a865978
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqeventloop_unix.cpp
@@ -0,0 +1,587 @@
+/****************************************************************************
+**
+** Implementation of TQEventLoop class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqeventloop_p.h" // includes qplatformdefs.h
+#include "tqeventloop.h"
+#include "tqapplication.h"
+#include "tqbitarray.h"
+#include <stdlib.h>
+#include <sys/types.h>
+
+
+/*****************************************************************************
+ Timer handling; UNIX has no application timer support so we'll have to
+ make our own from scratch.
+
+ NOTE: These functions are for internal use. TQObject::startTimer() and
+ TQObject::killTimer() are for public use.
+ The TQTimer class provides a high-level interface which translates
+ timer events into Q_SIGNALS.
+
+ qStartTimer( interval, obj )
+ Starts a timer which will run until it is killed with qKillTimer()
+ Arguments:
+ int interval timer interval in milliseconds
+ TQObject *obj where to send the timer event
+ Returns:
+ int timer identifier, or zero if not successful
+
+ qKillTimer( timerId )
+ Stops a timer specified by a timer identifier.
+ Arguments:
+ int timerId timer identifier
+ Returns:
+ bool TRUE if successful
+
+ qKillTimer( obj )
+ Stops all timers that are sent to the specified object.
+ Arguments:
+ TQObject *obj object receiving timer events
+ Returns:
+ bool TRUE if successful
+ *****************************************************************************/
+
+//
+// Internal data structure for timers
+//
+
+struct TimerInfo { // internal timer info
+ int id; // - timer identifier
+ timeval interval; // - timer interval
+ timeval timeout; // - when to sent event
+ TQObject *obj; // - object to receive event
+};
+
+typedef TQPtrList<TimerInfo> TimerList; // list of TimerInfo structs
+
+static TQBitArray *timerBitVec; // timer bit vector
+static TimerList *timerList = 0; // timer list
+
+static void initTimers();
+void cleanupTimers();
+static timeval watchtime; // watch if time is turned back
+timeval *qt_wait_timer();
+timeval *qt_wait_timer_max = 0;
+
+//
+// Internal operator functions for timevals
+//
+
+static inline bool operator<( const timeval &t1, const timeval &t2 )
+{
+ return t1.tv_sec < t2.tv_sec ||
+ (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec);
+}
+
+static inline bool operator==( const timeval &t1, const timeval &t2 )
+{
+ return t1.tv_sec == t2.tv_sec && t1.tv_usec == t2.tv_usec;
+}
+
+static inline timeval &operator+=( timeval &t1, const timeval &t2 )
+{
+ t1.tv_sec += t2.tv_sec;
+ if ( (t1.tv_usec += t2.tv_usec) >= 1000000 ) {
+ t1.tv_sec++;
+ t1.tv_usec -= 1000000;
+ }
+ return t1;
+}
+
+static inline timeval operator+( const timeval &t1, const timeval &t2 )
+{
+ timeval tmp;
+ tmp.tv_sec = t1.tv_sec + t2.tv_sec;
+ if ( (tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000 ) {
+ tmp.tv_sec++;
+ tmp.tv_usec -= 1000000;
+ }
+ return tmp;
+}
+
+static inline timeval operator-( const timeval &t1, const timeval &t2 )
+{
+ timeval tmp;
+ tmp.tv_sec = t1.tv_sec - t2.tv_sec;
+ if ( (tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0 ) {
+ tmp.tv_sec--;
+ tmp.tv_usec += 1000000;
+ }
+ return tmp;
+}
+
+
+//
+// Internal functions for manipulating timer data structures.
+// The timerBitVec array is used for keeping track of timer identifiers.
+//
+
+static int allocTimerId() // tqfind avail timer identifier
+{
+ int i = timerBitVec->size()-1;
+ while ( i >= 0 && (*timerBitVec)[i] )
+ i--;
+ if ( i < 0 ) {
+ i = timerBitVec->size();
+ timerBitVec->resize( 4 * i );
+ for( int j=timerBitVec->size()-1; j > i; j-- )
+ timerBitVec->clearBit( j );
+ }
+ timerBitVec->setBit( i );
+ return i+1;
+}
+
+static void insertTimer( const TimerInfo *ti ) // insert timer info into list
+{
+ TimerInfo *t = timerList->first();
+ int index = 0;
+#if defined(TQT_DEBUG)
+ int dangerCount = 0;
+#endif
+ while ( t && t->timeout < ti->timeout ) { // list is sorted by timeout
+#if defined(TQT_DEBUG)
+ if ( t->obj == ti->obj )
+ dangerCount++;
+#endif
+ t = timerList->next();
+ index++;
+ }
+ timerList->insert( index, ti ); // inserts sorted
+#if defined(TQT_DEBUG)
+ if ( dangerCount > 16 )
+ qDebug( "TQObject: %d timers now exist for object %s::%s",
+ dangerCount, ti->obj->className(), ti->obj->name() );
+#endif
+}
+
+static inline void getTime( timeval &t ) // get time of day
+{
+ gettimeofday( &t, 0 );
+ while ( t.tv_usec >= 1000000 ) { // NTP-related fix
+ t.tv_usec -= 1000000;
+ t.tv_sec++;
+ }
+ while ( t.tv_usec < 0 ) {
+ if ( t.tv_sec > 0 ) {
+ t.tv_usec += 1000000;
+ t.tv_sec--;
+ } else {
+ t.tv_usec = 0;
+ break;
+ }
+ }
+}
+
+static void repairTimer( const timeval &time ) // repair broken timer
+{
+ timeval diff = watchtime - time;
+ register TimerInfo *t = timerList->first();
+ while ( t ) { // repair all timers
+ t->timeout = t->timeout - diff;
+ t = timerList->next();
+ }
+}
+
+//
+// Timer activation functions (called from the event loop)
+//
+
+/*
+ Returns the time to wait for the next timer, or null if no timers are
+ waiting.
+
+ The result is bounded to qt_wait_timer_max if this exists.
+*/
+
+timeval *qt_wait_timer()
+{
+ static timeval tm;
+ bool first = TRUE;
+ timeval currentTime;
+ if ( timerList && timerList->count() ) { // there are waiting timers
+ getTime( currentTime );
+ if ( first ) {
+ if ( currentTime < watchtime ) // clock was turned back
+ repairTimer( currentTime );
+ first = FALSE;
+ watchtime = currentTime;
+ }
+ TimerInfo *t = timerList->first(); // first waiting timer
+ if ( currentTime < t->timeout ) { // time to wait
+ tm = t->timeout - currentTime;
+ } else {
+ tm.tv_sec = 0; // no time to wait
+ tm.tv_usec = 0;
+ }
+ if ( qt_wait_timer_max && *qt_wait_timer_max < tm )
+ tm = *qt_wait_timer_max;
+ return &tm;
+ }
+ if ( qt_wait_timer_max ) {
+ tm = *qt_wait_timer_max;
+ return &tm;
+ }
+ return 0; // no timers
+}
+
+// Timer initialization
+static void initTimers() // initialize timers
+{
+ timerBitVec = new TQBitArray( 128 );
+ TQ_CHECK_PTR( timerBitVec );
+ int i = timerBitVec->size();
+ while( i-- > 0 )
+ timerBitVec->clearBit( i );
+ timerList = new TimerList;
+ TQ_CHECK_PTR( timerList );
+ timerList->setAutoDelete( TRUE );
+ gettimeofday( &watchtime, 0 );
+}
+
+// Timer cleanup
+void cleanupTimers()
+{
+ delete timerList;
+ timerList = 0;
+ delete timerBitVec;
+ timerBitVec = 0;
+}
+
+// Main timer functions for starting and killing timers
+int qStartTimer( int interval, TQObject *obj )
+{
+ if ( !timerList ) // initialize timer data
+ initTimers();
+ int id = allocTimerId(); // get free timer id
+ if ( id <= 0 ||
+ id > (int)timerBitVec->size() || !obj )// cannot create timer
+ return 0;
+ timerBitVec->setBit( id-1 ); // set timer active
+ TimerInfo *t = new TimerInfo; // create timer
+ TQ_CHECK_PTR( t );
+ t->id = id;
+ t->interval.tv_sec = interval/1000;
+ t->interval.tv_usec = (interval%1000)*1000;
+ timeval currentTime;
+ getTime( currentTime );
+ t->timeout = currentTime + t->interval;
+ t->obj = obj;
+ insertTimer( t ); // put timer in list
+ return id;
+}
+
+bool qKillTimer( int id )
+{
+ register TimerInfo *t;
+ if ( !timerList || id <= 0 ||
+ id > (int)timerBitVec->size() || !timerBitVec->testBit( id-1 ) )
+ return FALSE; // not init'd or invalid timer
+ t = timerList->first();
+ while ( t && t->id != id ) // tqfind timer info in list
+ t = timerList->next();
+ if ( t ) { // id found
+ timerBitVec->clearBit( id-1 ); // set timer inactive
+ return timerList->remove();
+ }
+ else // id not found
+ return FALSE;
+}
+
+bool qKillTimer( TQObject *obj )
+{
+ register TimerInfo *t;
+ if ( !timerList ) // not initialized
+ return FALSE;
+ t = timerList->first();
+ while ( t ) { // check all timers
+ if ( t->obj == obj ) { // object found
+ timerBitVec->clearBit( t->id-1 );
+ timerList->remove();
+ t = timerList->current();
+ } else {
+ t = timerList->next();
+ }
+ }
+ return TRUE;
+}
+
+/*****************************************************************************
+ Socket notifier type
+ *****************************************************************************/
+TQSockNotType::TQSockNotType()
+ : list( 0 )
+{
+ FD_ZERO( &select_fds );
+ FD_ZERO( &enabled_fds );
+ FD_ZERO( &pending_fds );
+}
+
+TQSockNotType::~TQSockNotType()
+{
+ if ( list )
+ delete list;
+ list = 0;
+}
+
+/*****************************************************************************
+ TQEventLoop implementations for UNIX
+ *****************************************************************************/
+void TQEventLoop::registerSocketNotifier( TQSocketNotifier *notifier )
+{
+ int sockfd = notifier->socket();
+ int type = notifier->type();
+ if ( sockfd < 0 || sockfd >= FD_SETSIZE || type < 0 || type > 2 || notifier == 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQSocketNotifier: Internal error" );
+#endif
+ return;
+ }
+
+ TQPtrList<TQSockNot> *list = d->sn_vec[type].list;
+ fd_set *fds = &d->sn_vec[type].enabled_fds;
+ TQSockNot *sn;
+
+ if ( ! list ) {
+ // create new list, the TQSockNotType destructor will delete it for us
+ list = new TQPtrList<TQSockNot>;
+ TQ_CHECK_PTR( list );
+ list->setAutoDelete( TRUE );
+ d->sn_vec[type].list = list;
+ }
+
+ sn = new TQSockNot;
+ TQ_CHECK_PTR( sn );
+ sn->obj = notifier;
+ sn->fd = sockfd;
+ sn->queue = &d->sn_vec[type].pending_fds;
+
+ if ( list->isEmpty() ) {
+ list->insert( 0, sn );
+ } else { // sort list by fd, decreasing
+ TQSockNot *p = list->first();
+ while ( p && p->fd > sockfd )
+ p = list->next();
+#if defined(TQT_CHECK_STATE)
+ if ( p && p->fd == sockfd ) {
+ static const char *t[] = { "read", "write", "exception" };
+ qWarning( "TQSocketNotifier: Multiple socket notifiers for "
+ "same socket %d and type %s", sockfd, t[type] );
+ }
+#endif
+ if ( p )
+ list->insert( list->at(), sn );
+ else
+ list->append( sn );
+ }
+
+ FD_SET( sockfd, fds );
+ d->sn_highest = TQMAX( d->sn_highest, sockfd );
+}
+
+void TQEventLoop::unregisterSocketNotifier( TQSocketNotifier *notifier )
+{
+ int sockfd = notifier->socket();
+ int type = notifier->type();
+ if ( sockfd < 0 || type < 0 || type > 2 || notifier == 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQSocketNotifier: Internal error" );
+#endif
+ return;
+ }
+
+ TQPtrList<TQSockNot> *list = d->sn_vec[type].list;
+ fd_set *fds = &d->sn_vec[type].enabled_fds;
+ TQSockNot *sn;
+ if ( ! list )
+ return;
+ sn = list->first();
+ while ( sn && !(sn->obj == notifier && sn->fd == sockfd) )
+ sn = list->next();
+ if ( !sn ) // not found
+ return;
+
+ FD_CLR( sockfd, fds ); // clear fd bit
+ FD_CLR( sockfd, sn->queue );
+ d->sn_pending_list.removeRef( sn ); // remove from activation list
+ list->remove(); // remove notifier found above
+
+ if ( d->sn_highest == sockfd ) { // tqfind highest fd
+ d->sn_highest = -1;
+ for ( int i=0; i<3; i++ ) {
+ if ( d->sn_vec[i].list && ! d->sn_vec[i].list->isEmpty() )
+ d->sn_highest = TQMAX( d->sn_highest, // list is fd-sorted
+ d->sn_vec[i].list->getFirst()->fd );
+ }
+ }
+}
+
+void TQEventLoop::setSocketNotifierPending( TQSocketNotifier *notifier )
+{
+ int sockfd = notifier->socket();
+ int type = notifier->type();
+ if ( sockfd < 0 || type < 0 || type > 2 || notifier == 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQSocketNotifier: Internal error" );
+#endif
+ return;
+ }
+
+ TQPtrList<TQSockNot> *list = d->sn_vec[type].list;
+ TQSockNot *sn;
+ if ( ! list )
+ return;
+ sn = list->first();
+ while ( sn && !(sn->obj == notifier && sn->fd == sockfd) )
+ sn = list->next();
+ if ( ! sn ) { // not found
+ return;
+ }
+
+ // We choose a random activation order to be more fair under high load.
+ // If a constant order is used and a peer early in the list can
+ // saturate the IO, it might grab our attention completely.
+ // Also, if we're using a straight list, the callback routines may
+ // delete other entries from the list before those other entries are
+ // processed.
+ if ( ! FD_ISSET( sn->fd, sn->queue ) ) {
+ d->sn_pending_list.insert( (rand() & 0xff) %
+ (d->sn_pending_list.count()+1), sn );
+ FD_SET( sn->fd, sn->queue );
+ }
+}
+
+void TQEventLoop::wakeUp()
+{
+ /*
+ Apparently, there is not consistency among different operating
+ systems on how to use FIONREAD.
+
+ FreeBSD, Linux and Solaris all expect the 3rd argument to
+ ioctl() to be an int, which is normally 32-bit even on 64-bit
+ machines.
+
+ IRIX, on the other hand, expects a size_t, which is 64-bit on
+ 64-bit machines.
+
+ So, the solution is to use size_t initialized to zero to make
+ sure all bits are set to zero, preventing underflow with the
+ FreeBSD/Linux/Solaris ioctls.
+ */
+ size_t nbytes = 0;
+ char c = 0;
+ if ( ::ioctl( d->thread_pipe[0], FIONREAD, (char*)&nbytes ) >= 0 && nbytes == 0 ) {
+ ::write( d->thread_pipe[1], &c, 1 );
+ }
+}
+
+int TQEventLoop::timeToWait() const
+{
+ timeval *tm = qt_wait_timer();
+ if ( ! tm ) // no active timers
+ return -1;
+ return (tm->tv_sec*1000) + (tm->tv_usec/1000);
+}
+
+int TQEventLoop::activateTimers()
+{
+ if ( !timerList || !timerList->count() ) // no timers
+ return 0;
+ bool first = TRUE;
+ timeval currentTime;
+ int n_act = 0, maxCount = timerList->count();
+ TimerInfo *begin = 0;
+ register TimerInfo *t;
+
+ for ( ;; ) {
+ if ( ! maxCount-- )
+ break;
+ getTime( currentTime ); // get current time
+ if ( first ) {
+ if ( currentTime < watchtime ) // clock was turned back
+ repairTimer( currentTime );
+ first = FALSE;
+ watchtime = currentTime;
+ }
+ t = timerList->first();
+ if ( !t || currentTime < t->timeout ) // no timer has expired
+ break;
+ if ( ! begin ) {
+ begin = t;
+ } else if ( begin == t ) {
+ // avoid sending the same timer multiple times
+ break;
+ } else if ( t->interval < begin->interval || t->interval == begin->interval ) {
+ begin = t;
+ }
+ timerList->take(); // unlink from list
+ t->timeout += t->interval;
+ if ( t->timeout < currentTime )
+ t->timeout = currentTime + t->interval;
+ insertTimer( t ); // relink timer
+ if ( t->interval.tv_usec > 0 || t->interval.tv_sec > 0 )
+ n_act++;
+ TQTimerEvent e( t->id );
+ TQApplication::sendEvent( t->obj, &e ); // send event
+ if ( timerList->tqfindRef( begin ) == -1 )
+ begin = 0;
+ }
+ return n_act;
+}
+
+int TQEventLoop::activateSocketNotifiers()
+{
+ if ( d->sn_pending_list.isEmpty() )
+ return 0;
+
+ // activate entries
+ int n_act = 0;
+ TQEvent event( TQEvent::SockAct );
+ TQPtrListIterator<TQSockNot> it( d->sn_pending_list );
+ TQSockNot *sn;
+ while ( (sn=it.current()) ) {
+ ++it;
+ d->sn_pending_list.removeRef( sn );
+ if ( FD_ISSET(sn->fd, sn->queue) ) {
+ FD_CLR( sn->fd, sn->queue );
+ TQApplication::sendEvent( sn->obj, &event );
+ n_act++;
+ }
+ }
+
+ return n_act;
+}
diff --git a/tqtinterface/qt4/src/kernel/tqeventloop_x11.cpp b/tqtinterface/qt4/src/kernel/tqeventloop_x11.cpp
new file mode 100644
index 0000000..2c60d10
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqeventloop_x11.cpp
@@ -0,0 +1,417 @@
+/****************************************************************************
+**
+** Implementation of TQEventLoop class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqeventloop_p.h" // includes qplatformdefs.h
+#include "tqeventloop.h"
+#include "tqapplication.h"
+#include "tqbitarray.h"
+#include "tqcolor_p.h"
+#include "tqt_x11_p.h"
+
+#if defined(TQT_THREAD_SUPPORT)
+# include "tqmutex.h"
+#endif // TQT_THREAD_SUPPORT
+
+#include <errno.h>
+
+
+// resolve the conflict between X11's FocusIn and TQEvent::FocusIn
+#undef FocusOut
+#undef FocusIn
+
+static const int XKeyPress = KeyPress;
+static const int XKeyRelease = KeyRelease;
+#undef KeyPress
+#undef KeyRelease
+
+// from qapplication.cpp
+extern bool qt_is_gui_used;
+
+// from qeventloop_unix.cpp
+extern timeval *qt_wait_timer();
+extern void cleanupTimers();
+
+// ### this needs to go away at some point...
+typedef void (*VFPTR)();
+typedef TQValueList<VFPTR> TQVFuncList;
+void qt_install_preselect_handler( VFPTR );
+void qt_remove_preselect_handler( VFPTR );
+static TQVFuncList *qt_preselect_handler = 0;
+void qt_install_postselect_handler( VFPTR );
+void qt_remove_postselect_handler( VFPTR );
+static TQVFuncList *qt_postselect_handler = 0;
+
+void qt_install_preselect_handler( VFPTR handler )
+{
+ if ( !qt_preselect_handler )
+ qt_preselect_handler = new TQVFuncList;
+ qt_preselect_handler->append( handler );
+}
+void qt_remove_preselect_handler( VFPTR handler )
+{
+ if ( qt_preselect_handler ) {
+ TQVFuncList::Iterator it = qt_preselect_handler->tqfind( handler );
+ if ( it != qt_preselect_handler->end() )
+ qt_preselect_handler->remove( it );
+ }
+}
+void qt_install_postselect_handler( VFPTR handler )
+{
+ if ( !qt_postselect_handler )
+ qt_postselect_handler = new TQVFuncList;
+ qt_postselect_handler->prepend( handler );
+}
+void qt_remove_postselect_handler( VFPTR handler )
+{
+ if ( qt_postselect_handler ) {
+ TQVFuncList::Iterator it = qt_postselect_handler->tqfind( handler );
+ if ( it != qt_postselect_handler->end() )
+ qt_postselect_handler->remove( it );
+ }
+}
+
+
+void TQEventLoop::init()
+{
+ // initialize the common parts of the event loop
+ pipe( d->thread_pipe );
+ fcntl(d->thread_pipe[0], F_SETFD, FD_CLOEXEC);
+ fcntl(d->thread_pipe[1], F_SETFD, FD_CLOEXEC);
+
+ d->sn_highest = -1;
+
+ // intitialize the X11 parts of the event loop
+ d->xfd = -1;
+ if ( qt_is_gui_used )
+ d->xfd = XConnectionNumber( TQPaintDevice::x11AppDisplay() );
+}
+
+void TQEventLoop::cleanup()
+{
+ // cleanup the common parts of the event loop
+ close( d->thread_pipe[0] );
+ close( d->thread_pipe[1] );
+ cleanupTimers();
+
+ // cleanup the X11 parts of the event loop
+ d->xfd = -1;
+}
+
+bool TQEventLoop::processEvents( ProcessEventsFlags flags )
+{
+ // process events from the X server
+ XEvent event;
+ int nevents = 0;
+
+#if defined(TQT_THREAD_SUPPORT)
+ TQMutexLocker locker( TQApplication::qt_mutex );
+#endif
+
+ // handle gui and posted events
+ if ( qt_is_gui_used ) {
+ TQApplication::sendPostedEvents();
+
+ // Two loops so that posted events accumulate
+ while ( XPending( TQPaintDevice::x11AppDisplay() ) ) {
+ // also flushes output buffer
+ while ( XPending( TQPaintDevice::x11AppDisplay() ) ) {
+ if ( d->shortcut ) {
+ return FALSE;
+ }
+
+ XNextEvent( TQPaintDevice::x11AppDisplay(), &event );
+
+ if ( flags & ExcludeUserInput ) {
+ switch ( event.type ) {
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ case XKeyPress:
+ case XKeyRelease:
+ case EnterNotify:
+ case LeaveNotify:
+ continue;
+
+ case ClientMessage:
+ {
+ // from qapplication_x11.cpp
+ extern Atom qt_wm_protocols;
+ extern Atom qt_wm_take_focus;
+ extern Atom qt_qt_scrolldone;
+
+ // only keep the wm_take_focus and
+ // qt_qt_scrolldone protocols, discard all
+ // other client messages
+ if ( event.xclient.format != 32 )
+ continue;
+
+ if ( event.xclient.message_type == qt_wm_protocols ||
+ (Atom) event.xclient.data.l[0] == qt_wm_take_focus )
+ break;
+ if ( event.xclient.message_type == qt_qt_scrolldone )
+ break;
+ }
+
+ default: break;
+ }
+ }
+
+ nevents++;
+ if ( tqApp->x11ProcessEvent( &event ) == 1 )
+ return TRUE;
+ }
+ }
+ }
+
+ if ( d->shortcut ) {
+ return FALSE;
+ }
+
+ TQApplication::sendPostedEvents();
+
+ const uint exclude_all = ExcludeSocketNotifiers | 0x08;
+ // 0x08 == ExcludeTimers for X11 only
+ if ( nevents > 0 && ( flags & exclude_all ) == exclude_all &&
+ ( flags & WaitForMore ) ) {
+ return TRUE;
+ }
+
+ // don't block if exitLoop() or exit()/quit() has been called.
+ bool canWait = d->exitloop || d->quitnow ? FALSE : (flags & WaitForMore);
+
+ // Process timers and socket notifiers - the common UNIX stuff
+
+ // return the maximum time we can wait for an event.
+ static timeval zerotm;
+ timeval *tm = 0;
+ if ( ! ( flags & 0x08 ) ) { // 0x08 == ExcludeTimers for X11 only
+ tm = qt_wait_timer(); // wait for timer or X event
+ if ( !canWait ) {
+ if ( !tm )
+ tm = &zerotm;
+ tm->tv_sec = 0; // no time to wait
+ tm->tv_usec = 0;
+ }
+ }
+
+ int highest = 0;
+ if ( ! ( flags & ExcludeSocketNotifiers ) ) {
+ // return the highest fd we can wait for input on
+ if ( d->sn_highest >= 0 ) { // has socket notifier(s)
+ if ( d->sn_vec[0].list && ! d->sn_vec[0].list->isEmpty() )
+ d->sn_vec[0].select_fds = d->sn_vec[0].enabled_fds;
+ else
+ FD_ZERO( &d->sn_vec[0].select_fds );
+
+ if ( d->sn_vec[1].list && ! d->sn_vec[1].list->isEmpty() )
+ d->sn_vec[1].select_fds = d->sn_vec[1].enabled_fds;
+ else
+ FD_ZERO( &d->sn_vec[1].select_fds );
+
+ if ( d->sn_vec[2].list && ! d->sn_vec[2].list->isEmpty() )
+ d->sn_vec[2].select_fds = d->sn_vec[2].enabled_fds;
+ else
+ FD_ZERO( &d->sn_vec[2].select_fds );
+ } else {
+ FD_ZERO( &d->sn_vec[0].select_fds );
+
+ FD_ZERO( &d->sn_vec[1].select_fds );
+ FD_ZERO( &d->sn_vec[2].select_fds );
+ }
+
+ highest = d->sn_highest;
+ } else {
+ FD_ZERO( &d->sn_vec[0].select_fds );
+ FD_ZERO( &d->sn_vec[1].select_fds );
+ FD_ZERO( &d->sn_vec[2].select_fds );
+ }
+
+ if ( qt_is_gui_used ) {
+ // select for events on the event socket - only on X11
+ FD_SET( d->xfd, &d->sn_vec[0].select_fds );
+ highest = TQMAX( highest, d->xfd );
+ }
+
+ FD_SET( d->thread_pipe[0], &d->sn_vec[0].select_fds );
+ highest = TQMAX( highest, d->thread_pipe[0] );
+
+ if ( canWait )
+ emit aboutToBlock();
+
+ if ( qt_preselect_handler ) {
+ TQVFuncList::Iterator it, end = qt_preselect_handler->end();
+ for ( it = qt_preselect_handler->begin(); it != end; ++it )
+ (**it)();
+ }
+
+ // unlock the GUI mutex and select. when we return from this function, there is
+ // something for us to do
+#if defined(TQT_THREAD_SUPPORT)
+ locker.mutex()->unlock();
+#endif
+
+ int nsel;
+ do {
+ nsel = select( highest + 1,
+ &d->sn_vec[0].select_fds,
+ &d->sn_vec[1].select_fds,
+ &d->sn_vec[2].select_fds,
+ tm );
+ } while (nsel == -1 && (errno == EINTR || errno == EAGAIN));
+
+ // relock the GUI mutex before processing any pending events
+#if defined(TQT_THREAD_SUPPORT)
+ locker.mutex()->lock();
+#endif
+
+ // we are awake, broadcast it
+ emit awake();
+ emit tqApp->guiThreadAwake();
+
+ if (nsel == -1) {
+ if (errno == EBADF) {
+ // it seems a socket notifier has a bad fd... tqfind out
+ // which one it is and disable it
+ fd_set fdset;
+ zerotm.tv_sec = zerotm.tv_usec = 0l;
+
+ for (int type = 0; type < 3; ++type) {
+ TQPtrList<TQSockNot> *list = d->sn_vec[type].list;
+ if (!list) continue;
+
+ TQSockNot *sn = list->first();
+ while (sn) {
+ FD_ZERO(&fdset);
+ FD_SET(sn->fd, &fdset);
+
+ int ret = -1;
+ do {
+ switch (type) {
+ case 0: // read
+ ret = select(sn->fd + 1, &fdset, 0, 0, &zerotm);
+ break;
+ case 1: // write
+ ret = select(sn->fd + 1, 0, &fdset, 0, &zerotm);
+ break;
+ case 2: // except
+ ret = select(sn->fd + 1, 0, 0, &fdset, &zerotm);
+ break;
+ }
+ } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+
+ if (ret == -1 && errno == EBADF) {
+ // disable the invalid socket notifier
+ static const char *t[] = { "Read", "Write", "Exception" };
+ qWarning("TQSocketNotifier: invalid socket %d and type '%s', disabling...",
+ sn->fd, t[type]);
+ sn->obj->setEnabled(FALSE);
+ }
+
+ sn = list->next();
+ }
+ }
+ } else {
+ // EINVAL... shouldn't happen, so let's complain to stderr
+ // and hope someone sends us a bug report
+ perror( "select" );
+ }
+ }
+
+ // some other thread woke us up... consume the data on the thread pipe so that
+ // select doesn't immediately return next time
+ if ( nsel > 0 && FD_ISSET( d->thread_pipe[0], &d->sn_vec[0].select_fds ) ) {
+ char c;
+ ::read( d->thread_pipe[0], &c, 1 );
+ }
+
+ if ( qt_postselect_handler ) {
+ TQVFuncList::Iterator it, end = qt_postselect_handler->end();
+ for ( it = qt_postselect_handler->begin(); it != end; ++it )
+ (**it)();
+ }
+
+ // activate socket notifiers
+ if ( ! ( flags & ExcludeSocketNotifiers ) && nsel > 0 && d->sn_highest >= 0 ) {
+ // if select says data is ready on any socket, then set the socket notifier
+ // to pending
+ int i;
+ for ( i=0; i<3; i++ ) {
+ if ( ! d->sn_vec[i].list )
+ continue;
+
+ TQPtrList<TQSockNot> *list = d->sn_vec[i].list;
+ TQSockNot *sn = list->first();
+ while ( sn ) {
+ if ( FD_ISSET( sn->fd, &d->sn_vec[i].select_fds ) )
+ setSocketNotifierPending( sn->obj );
+ sn = list->next();
+ }
+ }
+
+ nevents += activateSocketNotifiers();
+ }
+
+ // activate timers
+ if ( ! ( flags & 0x08 ) ) {
+ // 0x08 == ExcludeTimers for X11 only
+ nevents += activateTimers();
+ }
+
+ // color approx. optimization - only on X11
+ qt_reset_color_avail();
+
+ // return true if we handled events, false otherwise
+ return (nevents > 0);
+}
+
+bool TQEventLoop::hasPendingEvents() const
+{
+ extern uint qGlobalPostedEventsCount(); // from qapplication.cpp
+ return ( qGlobalPostedEventsCount() || XPending( TQPaintDevice::x11AppDisplay() ) );
+}
+
+void TQEventLoop::appStartingUp()
+{
+ if ( qt_is_gui_used )
+ d->xfd = XConnectionNumber( TQPaintDevice::x11AppDisplay() );
+}
+
+void TQEventLoop::appClosingDown()
+{
+ d->xfd = -1;
+}
diff --git a/tqtinterface/qt4/src/kernel/tqfocusdata.cpp b/tqtinterface/qt4/src/kernel/tqfocusdata.cpp
new file mode 100644
index 0000000..0259940
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfocusdata.cpp
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Implementation of TQFocusData class
+**
+** Created : 980622
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqfocusdata.h"
+
+/*!
+ \class TQFocusData tqfocusdata.h
+ \brief The TQFocusData class maintains the list of widgets in the focus
+ chain.
+
+ \ingroup misc
+
+ This read-only list always tqcontains at least one widget (i.e. the
+ top-level widget). It provides a simple cursor which can be reset
+ to the current focus widget using home(), or moved to its
+ neighboring widgets using next() and prev(). You can also retrieve
+ the count() of the number of widgets in the list. The list is a
+ loop, so if you keep iterating, for example using next(), you will
+ never come to the end.
+
+ Some widgets in the list may not accept focus. Widgets are added
+ to the list as necessary, but not removed from it. This lets
+ widgets change focus policy dynamically without disrupting the
+ focus chain the user experiences. When a widget disables and
+ re-enables tab focus, its position in the focus chain does not
+ change.
+
+ When reimplementing TQWidget::focusNextPrevChild() to provide
+ special focus flow, you will usually call TQWidget::focusData() to
+ retrieve the focus data stored at the top-level widget. A
+ top-level widget's focus data tqcontains the focus list for its
+ hierarchy of widgets.
+
+ The cursor may change at any time.
+
+ This class is \e not thread-safe.
+
+ \sa TQWidget::focusNextPrevChild() TQWidget::setTabOrder()
+ TQWidget::setFocusPolicy()
+*/
+
+/*!
+ \fn TQWidget* TQFocusData::tqfocusWidget() const
+
+ Returns the widgets in the hierarchy that are in the focus chain.
+*/
+
+/*!
+ \fn int TQFocusData::count() const
+
+ Returns the number of widgets in the focus chain.
+*/
+
+/*!
+ Moves the cursor to the tqfocusWidget() and returns that widget. You
+ must call this before next() or prev() to iterate meaningfully.
+*/
+TQWidget* TQFocusData::home()
+{
+ tqfocusWidgets.tqfind(it.current());
+ return tqfocusWidgets.current();
+}
+
+/*!
+ Moves the cursor to the next widget in the focus chain. There is
+ \e always a next widget because the list is a loop.
+*/
+TQWidget* TQFocusData::next()
+{
+ TQWidget* r = tqfocusWidgets.next();
+ if ( !r )
+ r = tqfocusWidgets.first();
+ return r;
+}
+
+/*!
+ Moves the cursor to the previous widget in the focus chain. There
+ is \e always a previous widget because the list is a loop.
+*/
+TQWidget* TQFocusData::prev()
+{
+ TQWidget* r = tqfocusWidgets.prev();
+ if ( !r )
+ r = tqfocusWidgets.last();
+ return r;
+}
+
+/*!
+ Returns the last widget in the focus chain.
+ The cursor is not modified.
+*/
+TQWidget *TQFocusData::last() const
+{
+ return tqfocusWidgets.getLast();
+}
+
+/*!
+ Returns the first widget in the focus chain.
+ The cursor is not modified.
+*/
+TQWidget *TQFocusData::first() const
+{
+ return tqfocusWidgets.getFirst();
+}
diff --git a/tqtinterface/qt4/src/kernel/tqfocusdata.h b/tqtinterface/qt4/src/kernel/tqfocusdata.h
new file mode 100644
index 0000000..c4f4c90
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfocusdata.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Definition of internal TQFocusData class
+**
+** Created : 980405
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFOCUSDATA_H
+#define TQFOCUSDATA_H
+
+#ifndef TQT_H
+#include "tqwidgetlist.h"
+#endif // TQT_H
+
+
+class TQ_EXPORT TQFocusData {
+public:
+ TQWidget* tqfocusWidget() const { return it.current(); }
+
+ TQWidget* home();
+ TQWidget* next();
+ TQWidget* prev();
+ TQWidget* first() const;
+ TQWidget* last() const;
+ int count() const { return tqfocusWidgets.count(); }
+
+private:
+ friend class TQWidget;
+
+ TQFocusData()
+ : it(tqfocusWidgets) {}
+ TQWidgetList tqfocusWidgets;
+ TQWidgetListIt it;
+};
+
+
+#endif // TQFOCUSDATA_H
diff --git a/tqtinterface/qt4/src/kernel/tqfont.cpp b/tqtinterface/qt4/src/kernel/tqfont.cpp
new file mode 100644
index 0000000..48fe5a0
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfont.cpp
@@ -0,0 +1,3376 @@
+/****************************************************************************
+**
+** Implementation of TQFont, TQFontMetrics and TQFontInfo classes
+**
+** Created : 941207
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <tqtglobaldefines.h>
+#ifdef USE_QT4
+// Nasty, nasty horrid HACK to get access to QFont's private members
+// This is TERRIBLE and I wish there was a way around it
+// See also QRect
+#define private protected
+#include <Qt/qfont.h>
+#undef private
+#endif // USE_QT4
+
+#define TQT_FATAL_ASSERT
+
+#include "tqfont.h"
+#include "tqfontdatabase.h"
+#include "tqfontmetrics.h"
+#include "tqfontinfo.h"
+#include "tqpainter.h"
+#include "tqdict.h"
+#include "tqcache.h"
+#include "tqdatastream.h"
+#include "tqapplication.h"
+#include "tqcleanuphandler.h"
+#include "tqstringlist.h"
+#ifdef TQ_WS_MAC
+#include "tqpaintdevicemetrics.h"
+#endif
+
+#include <private/tqunicodetables_p.h>
+#include "tqfontdata_p.h"
+#include "tqfontengine_p.h"
+#include "tqpainter_p.h"
+#include "tqtextengine_p.h"
+
+// #define TQFONTCACHE_DEBUG
+#ifdef TQFONTCACHE_DEBUG
+# define FC_DEBUG qDebug
+#else
+# define FC_DEBUG if (FALSE) qDebug
+#endif
+
+#ifdef USE_QT4
+
+void TQFont::tqt_x11SetScreen( int screen ) {
+ x11SetScreen(screen);
+}
+int TQFont::tqt_x11Screen() const {
+ return x11Screen();
+}
+
+#else // USE_QT4
+
+bool TQFontDef::operator==( const TQFontDef &other ) const
+{
+ /*
+ TQFontDef comparison is more complicated than just simple
+ per-member comparisons.
+
+ When comparing point/pixel sizes, either point or pixelsize
+ could be -1. in This case we have to compare the non negative
+ size value.
+
+ This test will fail if the point-sizes differ by 1/2 point or
+ more or they do not round to the same value. We have to do this
+ since our API still uses 'int' point-sizes in the API, but store
+ deci-point-sizes internally.
+
+ To compare the family members, we need to parse the font names
+ and compare the family/foundry strings separately. This allows
+ us to compare e.g. "Helvetica" and "Helvetica [Adobe]" with
+ positive results.
+ */
+ if (pixelSize != -1 && other.pixelSize != -1) {
+ if (pixelSize != other.pixelSize)
+ return FALSE;
+ } else if (pointSize != -1 && other.pointSize != -1) {
+ if (pointSize != other.pointSize
+ && (TQABS(pointSize - other.pointSize) >= 5
+ || tqRound(pointSize/10.) != tqRound(other.pointSize/10.)))
+ return FALSE;
+ } else {
+ return FALSE;
+ }
+
+ if (!ignorePitch && !other.ignorePitch && fixedPitch != other.fixedPitch)
+ return FALSE;
+
+ if (stretch != 0 && other.stretch != 0 && stretch != other.stretch)
+ return FALSE;
+
+ TQString this_family, this_foundry, other_family, other_foundry;
+ TQFontDatabase::parseFontName(family, this_foundry, this_family);
+ TQFontDatabase::parseFontName(other.family, other_foundry, other_family);
+
+ return ( tqstyleHint == other.tqstyleHint
+ && styleStrategy == other.styleStrategy
+ && weight == other.weight
+ && italic == other.italic
+ && this_family == other_family
+ && (this_foundry.isEmpty()
+ || other_foundry.isEmpty()
+ || this_foundry == other_foundry)
+#ifdef TQ_WS_X11
+ && addStyle == other.addStyle
+#endif // TQ_WS_X11
+ );
+}
+
+
+
+
+TQFontPrivate::TQFontPrivate()
+ : engineData( 0 ), painttqdevice( 0 ),
+ rawMode( FALSE ), underline( FALSE ), overline( FALSE ), strikeOut( FALSE ),
+ tqmask( 0 )
+{
+#ifdef TQ_WS_X11
+ screen = TQPaintDevice::x11AppScreen();
+#else
+ screen = 0;
+#endif // TQ_WS_X11
+}
+
+TQFontPrivate::TQFontPrivate( const TQFontPrivate &other )
+ : TQShared(), request( other.request ), engineData( 0 ),
+ painttqdevice( other.painttqdevice ), screen( other.screen ),
+ rawMode( other.rawMode ), underline( other.underline ), overline( other.overline ),
+ strikeOut( other.strikeOut ), tqmask( other.tqmask )
+{
+}
+
+TQFontPrivate::~TQFontPrivate()
+{
+ if ( engineData )
+ engineData->deref();
+ engineData = 0;
+}
+
+void TQFontPrivate::resolve( const TQFontPrivate *other )
+{
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( other != 0 );
+#endif
+
+ if ( ( tqmask & Complete ) == Complete ) return;
+
+ // assign the unset-bits with the set-bits of the other font def
+ if ( ! ( tqmask & Family ) )
+ request.family = other->request.family;
+
+ if ( ! ( tqmask & Size ) ) {
+ request.pointSize = other->request.pointSize;
+ request.pixelSize = other->request.pixelSize;
+ }
+
+ if ( ! ( tqmask & StyleHint ) )
+ request.tqstyleHint = other->request.tqstyleHint;
+
+ if ( ! ( tqmask & StyleStrategy ) )
+ request.styleStrategy = other->request.styleStrategy;
+
+ if ( ! ( tqmask & Weight ) )
+ request.weight = other->request.weight;
+
+ if ( ! ( tqmask & Italic ) )
+ request.italic = other->request.italic;
+
+ if ( ! ( tqmask & FixedPitch ) )
+ request.fixedPitch = other->request.fixedPitch;
+
+ if ( ! ( tqmask & Stretch ) )
+ request.stretch = other->request.stretch;
+
+ if ( ! ( tqmask & Underline ) )
+ underline = other->underline;
+
+ if ( ! ( tqmask & Overline ) )
+ overline = other->overline;
+
+ if ( ! ( tqmask & StrikeOut ) )
+ strikeOut = other->strikeOut;
+}
+
+
+
+
+TQFontEngineData::TQFontEngineData()
+ : lineWidth( 1 )
+{
+#if defined(TQ_WS_X11) || defined(TQ_WS_WIN)
+ memset( engines, 0, TQFont::LastPrivateScript * sizeof( TQFontEngine * ) );
+#else
+ engine = 0;
+#endif // TQ_WS_X11 || TQ_WS_WIN
+#ifndef TQ_WS_MAC
+ memset( widthCache, 0, widthCacheSize*sizeof( uchar ) );
+#endif
+}
+
+TQFontEngineData::~TQFontEngineData()
+{
+#if defined(TQ_WS_X11) || defined(TQ_WS_WIN)
+ for ( int i = 0; i < TQFont::LastPrivateScript; i++ ) {
+ if ( engines[i] )
+ engines[i]->deref();
+ engines[i] = 0;
+ }
+#else
+ if ( engine )
+ engine->deref();
+ engine = 0;
+#endif // TQ_WS_X11 || TQ_WS_WIN
+}
+
+
+
+
+/*!
+ \class TQFont tqfont.h
+ \brief The TQFont class specifies a font used for drawing text.
+
+ \ingroup graphics
+ \ingroup appearance
+ \ingroup shared
+ \mainclass
+
+ When you create a TQFont object you specify various attributes that
+ you want the font to have. TQt will use the font with the specified
+ attributes, or if no matching font exists, TQt will use the closest
+ matching installed font. The attributes of the font that is
+ actually used are retrievable from a TQFontInfo object. If the
+ window system provides an exact match exactMatch() returns TRUE.
+ Use TQFontMetrics to get measurements, e.g. the pixel length of a
+ string using TQFontMetrics::width().
+
+ Use TQApplication::setFont() to set the application's default font.
+
+ If a choosen X11 font does not include all the characters that
+ need to be displayed, TQFont will try to tqfind the characters in the
+ nearest equivalent fonts. When a TQPainter draws a character from a
+ font the TQFont will report whether or not it has the character; if
+ it does not, TQPainter will draw an unfilled square.
+
+ Create TQFonts like this:
+ \code
+ TQFont serifFont( "Times", 10, Bold );
+ TQFont sansFont( "Helvetica [Cronyx]", 12 );
+ \endcode
+
+ The attributes set in the constructor can also be set later, e.g.
+ setFamily(), setPointSize(), setPointSizeFloat(), setWeight() and
+ setItalic(). The remaining attributes must be set after
+ contstruction, e.g. setBold(), setUnderline(), setOverline(),
+ setStrikeOut() and setFixedPitch(). TQFontInfo objects should be
+ created \e after the font's attributes have been set. A TQFontInfo
+ object will not change, even if you change the font's
+ attributes. The corresponding "get" functions, e.g. family(),
+ pointSize(), etc., return the values that were set, even though
+ the values used may differ. The actual values are available from a
+ TQFontInfo object.
+
+ If the requested font family is unavailable you can influence the
+ \link #fontmatching font matching algorithm\endlink by choosing a
+ particular \l{TQFont::StyleHint} and \l{TQFont::StyleStrategy} with
+ setStyleHint(). The default family (corresponding to the current
+ style hint) is returned by defaultFamily().
+
+ The font-matching algorithm has a lastResortFamily() and
+ lastResortFont() in cases where a suitable match cannot be found.
+ You can provide substitutions for font family names using
+ insertSubstitution() and insertSubstitutions(). Substitutions can
+ be removed with removeSubstitution(). Use substitute() to retrieve
+ a family's first substitute, or the family name itself if it has
+ no substitutes. Use substitutes() to retrieve a list of a family's
+ substitutes (which may be empty).
+
+ Every TQFont has a key() which you can use, for example, as the key
+ in a cache or dictionary. If you want to store a user's font
+ preferences you could use TQSettings, writing the font information
+ with toString() and reading it back with fromString(). The
+ operator<<() and operator>>() functions are also available, but
+ they work on a data stream.
+
+ It is possible to set the height of characters shown on the screen
+ to a specified number of pixels with setPixelSize(); however using
+ setPointSize() has a similar effect and provides tqdevice
+ independence.
+
+ Under the X Window System you can set a font using its system
+ specific name with setRawName().
+
+ Loading fonts can be expensive, especially on X11. TQFont tqcontains
+ extensive optimizations to make the copying of TQFont objects fast,
+ and to cache the results of the slow window system functions it
+ depends upon.
+
+ \target fontmatching
+ The font matching algorithm works as follows:
+ \list 1
+ \i The specified font family is searched for.
+ \i If not found, the tqstyleHint() is used to select a tqreplacement
+ family.
+ \i Each tqreplacement font family is searched for.
+ \i If none of these are found or there was no tqstyleHint(), "helvetica"
+ will be searched for.
+ \i If "helvetica" isn't found TQt will try the lastResortFamily().
+ \i If the lastResortFamily() isn't found TQt will try the
+ lastResortFont() which will always return a name of some kind.
+ \endlist
+
+ Once a font is found, the remaining attributes are matched in order of
+ priority:
+ \list 1
+ \i fixedPitch()
+ \i pointSize() (see below)
+ \i weight()
+ \i italic()
+ \endlist
+
+ If you have a font which matches on family, even if none of the
+ other attributes match, this font will be chosen in preference to
+ a font which doesn't match on family but which does match on the
+ other attributes. This is because font family is the dominant
+ search criteria.
+
+ The point size is defined to match if it is within 20% of the
+ requested point size. When several fonts match and are only
+ distinguished by point size, the font with the closest point size
+ to the one requested will be chosen.
+
+ The actual family, font size, weight and other font attributes
+ used for drawing text will depend on what's available for the
+ chosen family under the window system. A TQFontInfo object can be
+ used to determine the actual values used for drawing the text.
+
+ Examples:
+
+ \code
+ TQFont f("Helvetica");
+ \endcode
+ If you had both an Adobe and a Cronyx Helvetica, you might get
+ either.
+
+ \code
+ TQFont f1( "Helvetica [Cronyx]" ); // TQt 3.x
+ TQFont f2( "Cronyx-Helvetica" ); // TQt 2.x compatibility
+ \endcode
+ You can specify the foundry you want in the family name. Both fonts,
+ f1 and f2, in the above example will be set to "Helvetica
+ [Cronyx]".
+
+ To determine the attributes of the font actually used in the window
+ system, use a TQFontInfo object, e.g.
+ \code
+ TQFontInfo info( f1 );
+ TQString family = info.family();
+ \endcode
+
+ To tqfind out font metrics use a TQFontMetrics object, e.g.
+ \code
+ TQFontMetrics fm( f1 );
+ int pixelWidth = fm.width( "How many pixels wide is this text?" );
+ int pixelHeight = fm.height();
+ \endcode
+
+ For more general information on fonts, see the
+ \link http://www.nwalsh.com/comp.fonts/FAQ/ comp.fonts FAQ.\endlink
+ Information on encodings can be found from
+ \link http://czyborra.com/ Roman Czyborra's\endlink page.
+
+ \sa TQFontMetrics TQFontInfo TQFontDatabase TQApplication::setFont()
+ TQWidget::setFont() TQPainter::setFont() TQFont::StyleHint
+ TQFont::Weight
+*/
+
+/*!
+ \enum TQFont::Script
+
+ This enum represents \link tqunicode.html Unicode \endlink allocated
+ scripts. For exhaustive coverage see \link
+ http://www.amazon.com/exec/obidos/ASIN/0201616335/trolltech/t The
+ Unicode Standard Version 3.0 \endlink. The following scripts are
+ supported:
+
+ Modern European alphabetic scripts (left to right):
+
+ \value Latin consists of most alphabets based on the original Latin alphabet.
+ \value Greek covers ancient and modern Greek and Coptic.
+ \value Cyrillic covers the Slavic and non-Slavic languages using
+ cyrillic alphabets.
+ \value Armenian tqcontains the Armenian alphabet used with the
+ Armenian language.
+ \value Georgian covers at least the language Georgian.
+ \value Runic covers the known constituents of the Runic alphabets used
+ by the early and medieval societies in the Germanic,
+ Scandinavian, and Anglo-Saxon areas.
+ \value Ogham is an alphabetical script used to write a very early
+ form of Irish.
+ \value SpacingModifiers are small signs indicating modifications
+ to the preceeding letter.
+ \value CombiningMarks consist of diacritical marks not specific to
+ a particular alphabet, diacritical marks used in
+ combination with mathematical and technical symbols, and
+ glyph encodings applied to multiple letterforms.
+
+ Middle Eastern scripts (right to left):
+
+ \value Hebrew is used for writing Hebrew, Yiddish, and some other languages.
+ \value Arabic covers the Arabic language as well as Persian, Urdu,
+ Kurdish and some others.
+ \value Syriac is used to write the active liturgical languages and
+ dialects of several Middle Eastern and Southeast Indian
+ communities.
+ \value Thaana is used to write the Maledivian Dhivehi language.
+
+ South and Southeast Asian scripts (left to right with few historical exceptions):
+
+ \value Devanagari covers classical Sanskrit and modern Hindi as
+ well as several other languages.
+ \value Bengali is a relative to Devanagari employed to write the
+ Bengali language used in West Bengal/India and Bangladesh
+ as well as several minority languages.
+ \value Gurmukhi is another Devanagari relative used to write Punjabi.
+ \value Gujarati is closely related to Devanagari and used to write
+ the Gujarati language of the Gujarat state in India.
+ \value Oriya is used to write the Oriya language of Orissa state/India.
+ \value Tamil is used to write the Tamil language of Tamil Nadu state/India,
+ Sri Lanka, Singapore and parts of Malaysia as well as some
+ minority languages.
+ \value Telugu is used to write the Telugu language of Andhra
+ Pradesh state/India and some minority languages.
+ \value Kannada is another South Indian script used to write the
+ Kannada language of Karnataka state/India and some minority
+ languages.
+ \value Malayalam is used to write the Malayalam language of Kerala
+ state/India.
+ \value Sinhala is used for Sri Lanka's majority language Sinhala
+ and is also employed to write Pali, Sanskrit, and Tamil.
+ \value Thai is used to write Thai and other Southeast Asian languages.
+ \value Lao is a language and script quite similar to Thai.
+ \value Tibetan is the script used to write Tibetan in several
+ countries like Tibet, the bordering Indian regions and
+ Nepal. It is also used in the Buddist philosophy and
+ liturgy of the Mongolian cultural area.
+ \value Myanmar is mainly used to write the Burmese language of
+ Myanmar (former Burma).
+ \value Khmer is the official language of Kampuchea.
+
+ East Asian scripts (traditionally top-down, right to left, modern
+ often horizontal left to right):
+
+ \value Han consists of the CJK (Chinese, Japanese, Korean)
+ idiographic characters.
+ \value Hiragana is a cursive syllabary used to indicate phonetics
+ and pronounciation of Japanese words.
+ \value Katakana is a non-cursive syllabic script used to write
+ Japanese words with visual emphasis and non-Japanese words
+ in a phonetical manner.
+ \value Hangul is a Korean script consisting of alphabetic components.
+ \value Bopomofo is a phonetic alphabet for Chinese (mainly Mandarin).
+ \value Yi (also called Cuan or Wei) is a syllabary used to write
+ the Yi language of Southwestern China, Myanmar, Laos, and Vietnam.
+
+ Additional scripts that do not fit well into the script categories above:
+
+ \value Ethiopic is a syllabary used by several Central East African languages.
+ \value Cherokee is a left-to-right syllabic script used to write
+ the Cherokee language.
+ \value CanadianAboriginal consists of the syllabics used by some
+ Canadian aboriginal societies.
+ \value Mongolian is the traditional (and recently reintroduced)
+ script used to write Mongolian.
+
+ Symbols:
+
+ \value CurrencySymbols tqcontains currency symbols not encoded in other scripts.
+ \value LetterlikeSymbols consists of symbols derived from
+ ordinary letters of an alphabetical script.
+ \value NumberForms are provided for compatibility with other
+ existing character sets.
+ \value MathematicalOperators consists of encodings for operators,
+ relations and other symbols like arrows used in a mathematical context.
+ \value TechnicalSymbols tqcontains representations for control
+ codes, the space symbol, APL symbols and other symbols
+ mainly used in the context of electronic data processing.
+ \value GeometricSymbols covers block elements and geometric tqshapes.
+ \value MiscellaneousSymbols consists of a heterogeneous collection
+ of symbols that do not fit any other Unicode character
+ block, e.g. Dingbats.
+ \value EnclosedAndSquare is provided for compatibility with some
+ East Asian standards.
+ \value Braille is an international writing system used by blind
+ people. This script encodes the 256 eight-dot patterns with
+ the 64 six-dot patterns as a subset.
+
+ \value Tagalog
+ \value Hanunoo
+ \value Buhid
+ \value Tagbanwa
+
+ \value KatakanaHalfWidth
+
+ \value Limbu (Unicode 4.0)
+ \value TaiLe (Unicode 4.0)
+
+ \value Unicode includes all the above scripts.
+*/
+
+/*! \internal
+
+ Constructs a font for use on the paint tqdevice \a pd using the
+ specified font \a data.
+*/
+TQFont::TQFont( TQFontPrivate *data, TQPaintDevice *pd )
+{
+ d = new TQFontPrivate( *data );
+ TQ_CHECK_PTR( d );
+ d->painttqdevice = pd;
+
+ // now a single reference
+ d->count = 1;
+}
+
+/*! \internal
+ Detaches the font object from common font data.
+*/
+void TQFont::detach()
+{
+ if (d->count == 1) {
+ if ( d->engineData )
+ d->engineData->deref();
+ d->engineData = 0;
+
+ return;
+ }
+
+ TQFontPrivate *old_d = d;
+ d = new TQFontPrivate( *old_d );
+
+ /*
+ if this font is a copy of the application default font, set the
+ fontdef tqmask to zero to indicate that *nothing* has been
+ explicitly set by the programmer.
+ */
+ const TQFont appfont = TQApplication::font();
+ if ( old_d == appfont.d )
+ d->tqmask = 0;
+
+ if ( old_d->deref() )
+ delete old_d;
+}
+
+/*!
+ Constructs a font object that uses the application's default font.
+
+ \sa TQApplication::setFont(), TQApplication::font()
+*/
+TQFont::TQFont()
+{
+ const TQFont appfont = TQApplication::font();
+ d = appfont.d;
+ d->ref();
+}
+
+/*!
+ Constructs a font object with the specified \a family, \a
+ pointSize, \a weight and \a italic settings.
+
+ If \a pointSize is <= 0 it is set to 1.
+
+ The \a family name may optionally also include a foundry name,
+ e.g. "Helvetica [Cronyx]". (The TQt 2.x syntax, i.e.
+ "Cronyx-Helvetica", is also supported.) If the \a family is
+ available from more than one foundry and the foundry isn't
+ specified, an arbitrary foundry is chosen. If the family isn't
+ available a family will be set using the \link #fontmatching font
+ matching\endlink algorithm.
+
+ \sa Weight, setFamily(), setPointSize(), setWeight(), setItalic(),
+ setStyleHint() TQApplication::font()
+*/
+TQFont::TQFont( const TQString &family, int pointSize, int weight, bool italic )
+{
+
+ d = new TQFontPrivate;
+ TQ_CHECK_PTR( d );
+
+ d->tqmask = TQFontPrivate::Family;
+
+ if (pointSize <= 0) {
+ pointSize = 12;
+ } else {
+ d->tqmask |= TQFontPrivate::Size;
+ }
+
+ if (weight < 0) {
+ weight = Normal;
+ } else {
+ d->tqmask |= TQFontPrivate::Weight | TQFontPrivate::Italic;
+ }
+
+ d->request.family = family;
+ d->request.pointSize = pointSize * 10;
+ d->request.pixelSize = -1;
+ d->request.weight = weight;
+ d->request.italic = italic;
+}
+
+/*!
+ Constructs a font that is a copy of \a font.
+*/
+TQFont::TQFont( const TQFont &font )
+{
+ d = font.d;
+ d->ref();
+}
+
+/*!
+ Destroys the font object and frees all allocated resources.
+*/
+TQFont::~TQFont()
+{
+ if ( d->deref() )
+ delete d;
+ d = 0;
+}
+
+/*!
+ Assigns \a font to this font and returns a reference to it.
+*/
+TQFont &TQFont::operator=( const TQFont &font )
+{
+ if ( font.d != d ) {
+ if ( d->deref() )
+ delete d;
+ d = font.d;
+ d->ref();
+ }
+
+ return *this;
+}
+
+/*!
+ Returns the requested font family name, i.e. the name set in the
+ constructor or the last setFont() call.
+
+ \sa setFamily() substitutes() substitute()
+*/
+TQString TQFont::family() const
+{
+ return d->request.family;
+}
+
+/*!
+ Sets the family name of the font. The name is case insensitive and
+ may include a foundry name.
+
+ The \a family name may optionally also include a foundry name,
+ e.g. "Helvetica [Cronyx]". (The TQt 2.x syntax, i.e.
+ "Cronyx-Helvetica", is also supported.) If the \a family is
+ available from more than one foundry and the foundry isn't
+ specified, an arbitrary foundry is chosen. If the family isn't
+ available a family will be set using the \link #fontmatching font
+ matching\endlink algorithm.
+
+ \sa family(), setStyleHint(), TQFontInfo
+*/
+void TQFont::setFamily( const TQString &family )
+{
+ detach();
+
+ d->request.family = family;
+#if defined(TQ_WS_X11)
+ d->request.addStyle = TQString::null;
+#endif // TQ_WS_X11
+
+ d->tqmask |= TQFontPrivate::Family;
+}
+
+/*!
+ Returns the point size in 1/10ths of a point.
+
+ The returned value will be -1 if the font size has been specified
+ in pixels.
+
+ \sa pointSize() pointSizeFloat()
+ */
+int TQFont::deciPointSize() const
+{
+ return d->request.pointSize;
+}
+
+/*!
+ Returns the point size of the font. Returns -1 if the font size
+ was specified in pixels.
+
+ \sa setPointSize() deciPointSize() pointSizeFloat()
+*/
+int TQFont::pointSize() const
+{
+ return d->request.pointSize == -1 ? -1 : (d->request.pointSize + 5) / 10;
+}
+
+/*!
+ Sets the point size to \a pointSize. The point size must be
+ greater than zero.
+
+ \sa pointSize() setPointSizeFloat()
+*/
+void TQFont::setPointSize( int pointSize )
+{
+ if ( pointSize <= 0 ) {
+
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQFont::setPointSize: Point size <= 0 (%d)", pointSize );
+#endif
+
+ return;
+ }
+
+ detach();
+
+ d->request.pointSize = pointSize * 10;
+ d->request.pixelSize = -1;
+
+ d->tqmask |= TQFontPrivate::Size;
+}
+
+/*!
+ Sets the point size to \a pointSize. The point size must be
+ greater than zero. The requested precision may not be achieved on
+ all platforms.
+
+ \sa pointSizeFloat() setPointSize() setPixelSize()
+*/
+void TQFont::setPointSizeFloat( float pointSize )
+{
+ if ( pointSize <= 0.0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQFont::setPointSize: Point size <= 0 (%f)", pointSize );
+#endif
+ return;
+ }
+
+ detach();
+
+ d->request.pointSize = tqRound(pointSize * 10.0);
+ d->request.pixelSize = -1;
+
+ d->tqmask |= TQFontPrivate::Size;
+}
+
+/*!
+ Returns the point size of the font. Returns -1 if the font size was
+ specified in pixels.
+
+ \sa pointSize() setPointSizeFloat() pixelSize() TQFontInfo::pointSize() TQFontInfo::pixelSize()
+*/
+float TQFont::pointSizeFloat() const
+{
+ return float( d->request.pointSize == -1 ? -10 : d->request.pointSize ) / 10.0;
+}
+
+/*!
+ Sets the font size to \a pixelSize pixels.
+
+ Using this function makes the font tqdevice dependent. Use
+ setPointSize() or setPointSizeFloat() to set the size of the font
+ in a tqdevice independent manner.
+
+ \sa pixelSize()
+*/
+void TQFont::setPixelSize( int pixelSize )
+{
+ if ( pixelSize <= 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQFont::setPixelSize: Pixel size <= 0 (%d)", pixelSize );
+#endif
+ return;
+ }
+
+ detach();
+
+ d->request.pixelSize = pixelSize;
+ d->request.pointSize = -1;
+
+ d->tqmask |= TQFontPrivate::Size;
+}
+
+/*!
+ Returns the pixel size of the font if it was set with
+ setPixelSize(). Returns -1 if the size was set with setPointSize()
+ or setPointSizeFloat().
+
+ \sa setPixelSize() pointSize() TQFontInfo::pointSize() TQFontInfo::pixelSize()
+*/
+int TQFont::pixelSize() const
+{
+ return d->request.pixelSize;
+}
+
+/*! \obsolete
+
+ Sets the logical pixel height of font characters when shown on
+ the screen to \a pixelSize.
+*/
+void TQFont::setPixelSizeFloat( float pixelSize )
+{
+ setPixelSize( (int)pixelSize );
+}
+
+/*!
+ Returns TRUE if italic has been set; otherwise returns FALSE.
+
+ \sa setItalic()
+*/
+bool TQFont::italic() const
+{
+ return d->request.italic;
+}
+
+/*!
+ If \a enable is TRUE, italic is set on; otherwise italic is set
+ off.
+
+ \sa italic(), TQFontInfo
+*/
+void TQFont::setItalic( bool enable )
+{
+ detach();
+
+ d->request.italic = enable;
+ d->tqmask |= TQFontPrivate::Italic;
+}
+
+/*!
+ Returns the weight of the font which is one of the enumerated
+ values from \l{TQFont::Weight}.
+
+ \sa setWeight(), Weight, TQFontInfo
+*/
+int TQFont::weight() const
+{
+ return d->request.weight;
+}
+
+/*!
+ \enum TQFont::Weight
+
+ TQt uses a weighting scale from 0 to 99 similar to, but not the
+ same as, the scales used in Windows or CSS. A weight of 0 is
+ ultralight, whilst 99 will be an extremely black.
+
+ This enum tqcontains the predefined font weights:
+
+ \value Light 25
+ \value Normal 50
+ \value DemiBold 63
+ \value Bold 75
+ \value Black 87
+*/
+
+/*!
+ Sets the weight the font to \a weight, which should be a value
+ from the \l TQFont::Weight enumeration.
+
+ \sa weight(), TQFontInfo
+*/
+void TQFont::setWeight( int weight )
+{
+ if ( weight < 0 || weight > 99 ) {
+
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQFont::setWeight: Value out of range (%d)", weight );
+#endif
+
+ return;
+ }
+
+ detach();
+
+ d->request.weight = weight;
+ d->tqmask |= TQFontPrivate::Weight;
+}
+
+/*!
+ \fn bool TQFont::bold() const
+
+ Returns TRUE if weight() is a value greater than \link Weight
+ TQFont::Normal \endlink; otherwise returns FALSE.
+
+ \sa weight(), setBold(), TQFontInfo::bold()
+*/
+
+/*!
+ \fn void TQFont::setBold( bool enable )
+
+ If \a enable is true sets the font's weight to \link Weight
+ TQFont::Bold \endlink; otherwise sets the weight to \link Weight
+ TQFont::Normal\endlink.
+
+ For finer boldness control use setWeight().
+
+ \sa bold(), setWeight()
+*/
+
+/*!
+ Returns TRUE if underline has been set; otherwise returns FALSE.
+
+ \sa setUnderline()
+*/
+bool TQFont::underline() const
+{
+ return d->underline;
+}
+
+/*!
+ If \a enable is TRUE, sets underline on; otherwise sets underline
+ off.
+
+ \sa underline(), TQFontInfo
+*/
+void TQFont::setUnderline( bool enable )
+{
+ detach();
+
+ d->underline = enable;
+ d->tqmask |= TQFontPrivate::Underline;
+}
+
+/*!
+ Returns TRUE if overline has been set; otherwise returns FALSE.
+
+ \sa setOverline()
+*/
+bool TQFont::overline() const
+{
+ return d->overline;
+}
+
+/*!
+ If \a enable is TRUE, sets overline on; otherwise sets overline off.
+
+ \sa overline(), TQFontInfo
+*/
+void TQFont::setOverline( bool enable )
+{
+ detach();
+
+ d->overline = enable;
+ d->tqmask |= TQFontPrivate::Overline;
+}
+
+/*!
+ Returns TRUE if strikeout has been set; otherwise returns FALSE.
+
+ \sa setStrikeOut()
+*/
+bool TQFont::strikeOut() const
+{
+ return d->strikeOut;
+}
+
+/*!
+ If \a enable is TRUE, sets strikeout on; otherwise sets strikeout
+ off.
+
+ \sa strikeOut(), TQFontInfo
+*/
+void TQFont::setStrikeOut( bool enable )
+{
+ detach();
+
+ d->strikeOut = enable;
+ d->tqmask |= TQFontPrivate::StrikeOut;
+}
+
+/*!
+ Returns TRUE if fixed pitch has been set; otherwise returns FALSE.
+
+ \sa setFixedPitch(), TQFontInfo::fixedPitch()
+*/
+bool TQFont::fixedPitch() const
+{
+ return d->request.fixedPitch;
+}
+
+/*!
+ If \a enable is TRUE, sets fixed pitch on; otherwise sets fixed
+ pitch off.
+
+ \sa fixedPitch(), TQFontInfo
+*/
+void TQFont::setFixedPitch( bool enable )
+{
+ detach();
+
+ d->request.fixedPitch = enable;
+ d->request.ignorePitch = FALSE;
+ d->tqmask |= TQFontPrivate::FixedPitch;
+}
+
+/*!
+ Returns the StyleStrategy.
+
+ The style strategy affects the \link #fontmatching font
+ matching\endlink algorithm. See \l TQFont::StyleStrategy for the
+ list of strategies.
+
+ \sa setStyleHint() TQFont::StyleHint
+*/
+TQFont::StyleStrategy TQFont::styleStrategy() const
+{
+ return (StyleStrategy) d->request.styleStrategy;
+}
+
+/*!
+ Returns the StyleHint.
+
+ The style hint affects the \link #fontmatching font
+ matching\endlink algorithm. See \l TQFont::StyleHint for the list
+ of strategies.
+
+ \sa setStyleHint(), TQFont::StyleStrategy TQFontInfo::tqstyleHint()
+*/
+TQFont::StyleHint TQFont::tqstyleHint() const
+{
+ return (StyleHint) d->request.tqstyleHint;
+}
+
+/*!
+ \enum TQFont::StyleHint
+
+ Style hints are used by the \link #fontmatching font
+ matching\endlink algorithm to tqfind an appropriate default family
+ if a selected font family is not available.
+
+ \value AnyStyle leaves the font matching algorithm to choose the
+ family. This is the default.
+
+ \value SansSerif the font matcher prefer sans serif fonts.
+ \value Helvetica is a synonym for \c SansSerif.
+
+ \value Serif the font matcher prefers serif fonts.
+ \value Times is a synonym for \c Serif.
+
+ \value TypeWriter the font matcher prefers fixed pitch fonts.
+ \value Courier a synonym for \c TypeWriter.
+
+ \value OldEnglish the font matcher prefers decorative fonts.
+ \value Decorative is a synonym for \c OldEnglish.
+
+ \value System the font matcher prefers system fonts.
+*/
+
+/*!
+ \enum TQFont::StyleStrategy
+
+ The style strategy tells the \link #fontmatching font
+ matching\endlink algorithm what type of fonts should be used to
+ tqfind an appropriate default family.
+
+ The following strategies are available:
+
+ \value PreferDefault the default style strategy. It does not prefer
+ any type of font.
+ \value PreferBitmap prefers bitmap fonts (as opposed to outline
+ fonts).
+ \value PreferDevice prefers tqdevice fonts.
+ \value PreferOutline prefers outline fonts (as opposed to bitmap fonts).
+ \value ForceOutline forces the use of outline fonts.
+ \value NoAntialias don't antialias the fonts.
+ \value PreferAntialias antialias if possible.
+ \value OpenGLCompatible forces the use of OpenGL compatible
+ fonts.
+
+ Any of these may be OR-ed with one of these flags:
+
+ \value PreferMatch prefer an exact match. The font matcher will try to
+ use the exact font size that has been specified.
+ \value PreferQuality prefer the best quality font. The font matcher
+ will use the nearest standard point size that the font
+ supports.
+*/
+
+/*!
+ Sets the style hint and strategy to \a hint and \a strategy,
+ respectively.
+
+ If these aren't set explicitly the style hint will default to
+ \c AnyStyle and the style strategy to \c PreferDefault.
+
+ TQt does not support style hints on X11 since this information
+ is not provided by the window system.
+
+ \sa StyleHint, tqstyleHint(), StyleStrategy, styleStrategy(), TQFontInfo
+*/
+void TQFont::setStyleHint( StyleHint hint, StyleStrategy strategy )
+{
+ detach();
+
+ if ( ( d->tqmask & ( TQFontPrivate::StyleHint | TQFontPrivate::StyleStrategy ) ) &&
+ (StyleHint) d->request.tqstyleHint == hint &&
+ (StyleStrategy) d->request.styleStrategy == strategy )
+ return;
+
+ d->request.tqstyleHint = hint;
+ d->request.styleStrategy = strategy;
+ d->tqmask |= TQFontPrivate::StyleHint;
+ d->tqmask |= TQFontPrivate::StyleStrategy;
+
+#if defined(TQ_WS_X11)
+ d->request.addStyle = TQString::null;
+#endif // TQ_WS_X11
+}
+
+/*!
+ Sets the style strategy for the font to \a s.
+
+ \sa TQFont::StyleStrategy
+*/
+void TQFont::setStyleStrategy( StyleStrategy s )
+{
+ detach();
+
+ if ( ( d->tqmask & TQFontPrivate::StyleStrategy ) &&
+ s == (StyleStrategy)d->request.styleStrategy )
+ return;
+
+ d->request.styleStrategy = s;
+ d->tqmask |= TQFontPrivate::StyleStrategy;
+}
+
+
+/*!
+ \enum TQFont::Stretch
+
+ Predefined stretch values that follow the CSS naming convention.
+
+ \value UltraCondensed 50
+ \value ExtraCondensed 62
+ \value Condensed 75
+ \value SemiCondensed 87
+ \value Unstretched 100
+ \value SemiExpanded 112
+ \value Expanded 125
+ \value ExtraExpanded 150
+ \value UltraExpanded 200
+
+ \sa setStretch() stretch()
+*/
+
+/*!
+ Returns the stretch factor for the font.
+
+ \sa setStretch()
+ */
+int TQFont::stretch() const
+{
+ return d->request.stretch;
+}
+
+/*!
+ Sets the stretch factor for the font.
+
+ The stretch factor changes the width of all characters in the font
+ by \a factor percent. For example, setting \a factor to 150
+ results in all characters in the font being 1.5 times ( ie. 150% )
+ wider. The default stretch factor is 100. The minimum stretch
+ factor is 1, and the maximum stretch factor is 4000.
+
+ The stretch factor is only applied to outline fonts. The stretch
+ factor is ignored for bitmap fonts.
+
+ NOTE: TQFont cannot stretch XLFD fonts. When loading XLFD fonts on
+ X11, the stretch factor is matched against a predefined set of
+ values for the SETWIDTH_NAME field of the XLFD.
+
+ \sa stretch() TQFont::StyleStrategy
+*/
+void TQFont::setStretch( int factor )
+{
+ if ( factor < 1 || factor > 4000 ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQFont::setStretch(): parameter '%d' out of range", factor );
+#endif // TQT_CHECK_RANGE
+
+ return;
+ }
+
+ detach();
+
+ if ( ( d->tqmask & TQFontPrivate::Stretch ) &&
+ d->request.stretch == (uint)factor )
+ return;
+
+ d->request.stretch = (uint)factor;
+ d->tqmask |= TQFontPrivate::Stretch;
+}
+
+/*!
+ If \a enable is TRUE, turns raw mode on; otherwise turns raw mode
+ off. This function only has an effect under X11.
+
+ If raw mode is enabled, TQt will search for an X font with a
+ complete font name matching the family name, ignoring all other
+ values set for the TQFont. If the font name matches several fonts,
+ TQt will use the first font returned by X. TQFontInfo \e cannot be
+ used to fetch information about a TQFont using raw mode (it will
+ return the values set in the TQFont for all parameters, including
+ the family name).
+
+ \warning Do not use raw mode unless you really, really need it! In
+ most (if not all) cases, setRawName() is a much better choice.
+
+ \sa rawMode(), setRawName()
+*/
+void TQFont::setRawMode( bool enable )
+{
+ detach();
+
+ if ( (bool) d->rawMode == enable ) return;
+
+ d->rawMode = enable;
+}
+
+/*!
+ Returns TRUE if a window system font exactly matching the settings
+ of this font is available.
+
+ \sa TQFontInfo
+*/
+bool TQFont::exactMatch() const
+{
+ TQFontEngine *engine = d->engineForScript( TQFont::NoScript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return d->rawMode ? engine->type() != TQFontEngine::Box
+ : d->request == engine->fontDef;
+}
+
+/*!
+ Returns TRUE if this font is equal to \a f; otherwise returns
+ FALSE.
+
+ Two TQFonts are considered equal if their font attributes are
+ equal. If rawMode() is enabled for both fonts, only the family
+ fields are compared.
+
+ \sa operator!=() isCopyOf()
+*/
+bool TQFont::operator==( const TQFont &f ) const
+{
+ return f.d == d || ( f.d->request == d->request &&
+ f.d->underline == d->underline &&
+ f.d->overline == d->overline &&
+ f.d->strikeOut == d->strikeOut );
+}
+
+/*!
+ Returns TRUE if this font is different from \a f; otherwise
+ returns FALSE.
+
+ Two TQFonts are considered to be different if their font attributes
+ are different. If rawMode() is enabled for both fonts, only the
+ family fields are compared.
+
+ \sa operator==()
+*/
+bool TQFont::operator!=( const TQFont &f ) const
+{
+ return !(operator==( f ));
+}
+
+/*!
+ Returns TRUE if this font and \a f are copies of each other, i.e.
+ one of them was created as a copy of the other and neither has
+ been modified since. This is much stricter than equality.
+
+ \sa operator=() operator==()
+*/
+bool TQFont::isCopyOf( const TQFont & f ) const
+{
+ return d == f.d;
+}
+
+/*!
+ Returns TRUE if raw mode is used for font name matching; otherwise
+ returns FALSE.
+
+ \sa setRawMode() rawName()
+*/
+bool TQFont::rawMode() const
+{
+ return d->rawMode;
+}
+
+/*!
+ Returns a new TQFont that has attributes copied from \a other.
+*/
+TQFont TQFont::resolve( const TQFont &other ) const
+{
+ if ( *this == other && d->tqmask == other.d->tqmask )
+ return *this;
+
+ TQFont font( *this );
+ font.detach();
+
+ /*
+ if this font is a copy of the application default font, set the
+ fontdef tqmask to zero to indicate that *nothing* has been
+ explicitly set by the programmer.
+ */
+ const TQFont appfont = TQApplication::font();
+ if ( d == appfont.d )
+ font.d->tqmask = 0;
+
+ font.d->resolve( other.d );
+
+ return font;
+}
+
+#ifndef TQT_NO_COMPAT
+
+/*! \obsolete
+
+ Please use TQApplication::font() instead.
+*/
+TQFont TQFont::defaultFont()
+{
+ return TQApplication::font();
+}
+
+/*! \obsolete
+
+ Please use TQApplication::setFont() instead.
+*/
+void TQFont::setDefaultFont( const TQFont &f )
+{
+ TQApplication::setFont( f );
+}
+
+
+#endif
+
+
+
+
+#ifndef TQT_NO_STRINGLIST
+
+/*****************************************************************************
+ TQFont substitution management
+ *****************************************************************************/
+
+typedef TQDict<TQStringList> TQFontSubst;
+static TQFontSubst *fontSubst = 0;
+static TQSingleCleanupHandler<TQFontSubst> qfont_cleanup_fontsubst;
+
+
+// create substitution dict
+static void initFontSubst()
+{
+ // default substitutions
+ static const char *initTbl[] = {
+
+#if defined(TQ_WS_X11)
+ "arial", "helvetica",
+ "helv", "helvetica",
+ "tms rmn", "times",
+#elif defined(TQ_WS_WIN)
+ "times", "Times New Roman",
+ "courier", "Courier New",
+ "helvetica", "Arial",
+#endif
+
+ 0, 0
+ };
+
+ if (fontSubst)
+ return;
+
+ fontSubst = new TQFontSubst(17, FALSE);
+ TQ_CHECK_PTR( fontSubst );
+ fontSubst->setAutoDelete( TRUE );
+ qfont_cleanup_fontsubst.set(&fontSubst);
+
+ for ( int i=0; initTbl[i] != 0; i += 2 )
+ TQFont::insertSubstitution(TQString::tqfromLatin1(initTbl[i]),
+ TQString::tqfromLatin1(initTbl[i+1]));
+}
+
+
+/*!
+ Returns the first family name to be used whenever \a familyName is
+ specified. The lookup is case insensitive.
+
+ If there is no substitution for \a familyName, \a familyName is
+ returned.
+
+ To obtain a list of substitutions use substitutes().
+
+ \sa setFamily() insertSubstitutions() insertSubstitution() removeSubstitution()
+*/
+TQString TQFont::substitute( const TQString &familyName )
+{
+ initFontSubst();
+
+ TQStringList *list = fontSubst->tqfind(familyName);
+ if (list && list->count() > 0)
+ return *(list->at(0));
+
+ return familyName;
+}
+
+
+/*!
+ Returns a list of family names to be used whenever \a familyName
+ is specified. The lookup is case insensitive.
+
+ If there is no substitution for \a familyName, an empty list is
+ returned.
+
+ \sa substitute() insertSubstitutions() insertSubstitution() removeSubstitution()
+ */
+TQStringList TQFont::substitutes(const TQString &familyName)
+{
+ initFontSubst();
+
+ TQStringList ret, *list = fontSubst->tqfind(familyName);
+ if (list)
+ ret += *list;
+ return ret;
+}
+
+
+/*!
+ Inserts the family name \a substituteName into the substitution
+ table for \a familyName.
+
+ \sa insertSubstitutions() removeSubstitution() substitutions() substitute() substitutes()
+*/
+void TQFont::insertSubstitution(const TQString &familyName,
+ const TQString &substituteName)
+{
+ initFontSubst();
+
+ TQStringList *list = fontSubst->tqfind(familyName);
+ if (! list) {
+ list = new TQStringList;
+ fontSubst->insert(familyName, list);
+ }
+
+ if (! list->tqcontains(substituteName))
+ list->append(substituteName);
+}
+
+
+/*!
+ Inserts the list of families \a substituteNames into the
+ substitution list for \a familyName.
+
+ \sa insertSubstitution(), removeSubstitution(), substitutions(), substitute()
+*/
+void TQFont::insertSubstitutions(const TQString &familyName,
+ const TQStringList &substituteNames)
+{
+ initFontSubst();
+
+ TQStringList *list = fontSubst->tqfind(familyName);
+ if (! list) {
+ list = new TQStringList;
+ fontSubst->insert(familyName, list);
+ }
+
+ TQStringList::ConstIterator it = substituteNames.begin();
+ while (it != substituteNames.end()) {
+ if (! list->tqcontains(*it))
+ list->append(*it);
+ it++;
+ }
+}
+
+// ### mark: should be called removeSubstitutions()
+/*!
+ Removes all the substitutions for \a familyName.
+
+ \sa insertSubstitutions(), insertSubstitution(), substitutions(), substitute()
+*/
+void TQFont::removeSubstitution( const TQString &familyName )
+{ // ### function name should be removeSubstitutions() or
+ // ### removeSubstitutionList()
+ initFontSubst();
+
+ fontSubst->remove(familyName);
+}
+
+
+/*!
+ Returns a sorted list of substituted family names.
+
+ \sa insertSubstitution(), removeSubstitution(), substitute()
+*/
+TQStringList TQFont::substitutions()
+{
+ initFontSubst();
+
+ TQStringList ret;
+ TQDictIterator<TQStringList> it(*fontSubst);
+
+ while (it.current()) {
+ ret.append(it.currentKey());
+ ++it;
+ }
+
+ ret.sort();
+
+ return ret;
+}
+
+#endif // TQT_NO_STRINGLIST
+
+
+/* \internal
+ Internal function. Converts boolean font settings to an unsigned
+ 8-bit number. Used for serialization etc.
+*/
+static TQ_UINT8 get_font_bits( const TQFontPrivate *f )
+{
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( f != 0 );
+#endif
+
+ TQ_UINT8 bits = 0;
+ if ( f->request.italic )
+ bits |= 0x01;
+ if ( f->underline )
+ bits |= 0x02;
+ if ( f->overline )
+ bits |= 0x40;
+ if ( f->strikeOut )
+ bits |= 0x04;
+ if ( f->request.fixedPitch )
+ bits |= 0x08;
+ // if ( f.hintSetByUser )
+ // bits |= 0x10;
+ if ( f->rawMode )
+ bits |= 0x20;
+ return bits;
+}
+
+
+#ifndef TQT_NO_DATASTREAM
+
+/* \internal
+ Internal function. Sets boolean font settings from an unsigned
+ 8-bit number. Used for serialization etc.
+*/
+static void set_font_bits( TQ_UINT8 bits, TQFontPrivate *f )
+{
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( f != 0 );
+#endif
+
+ f->request.italic = (bits & 0x01) != 0;
+ f->underline = (bits & 0x02) != 0;
+ f->overline = (bits & 0x40) != 0;
+ f->strikeOut = (bits & 0x04) != 0;
+ f->request.fixedPitch = (bits & 0x08) != 0;
+ // f->hintSetByUser = (bits & 0x10) != 0;
+ f->rawMode = (bits & 0x20) != 0;
+}
+
+#endif
+
+
+/*!
+ Returns the font's key, a textual representation of a font. It is
+ typically used as the key for a cache or dictionary of fonts.
+
+ \sa TQMap
+*/
+TQString TQFont::key() const
+{
+ return toString();
+}
+
+/*!
+ Returns a description of the font. The description is a
+ comma-separated list of the attributes, perfectly suited for use
+ in TQSettings.
+
+ \sa fromString() operator<<()
+ */
+TQString TQFont::toString() const
+{
+ const TQChar comma( ',' );
+ return family() + comma +
+ TQString::number( pointSizeFloat() ) + comma +
+ TQString::number( pixelSize() ) + comma +
+ TQString::number( (int) tqstyleHint() ) + comma +
+ TQString::number( weight() ) + comma +
+ TQString::number( (int) italic() ) + comma +
+ TQString::number( (int) underline() ) + comma +
+ TQString::number( (int) strikeOut() ) + comma +
+ TQString::number( (int)fixedPitch() ) + comma +
+ TQString::number( (int) rawMode() );
+}
+
+
+/*!
+ Sets this font to match the description \a descrip. The description
+ is a comma-separated list of the font attributes, as returned by
+ toString().
+
+ \sa toString() operator>>()
+ */
+bool TQFont::fromString(const TQString &descrip)
+{
+#ifndef TQT_NO_STRINGLIST
+ TQStringList l(TQStringList::split(',', descrip));
+
+ int count = (int)l.count();
+#else
+ int count = 0;
+ TQString l[11];
+ int from = 0;
+ int to = descrip.tqfind( ',' );
+ while ( to > 0 && count < 11 ) {
+ l[count] = descrip.mid( from, to-from );
+ count++;
+ from = to+1;
+ to = descrip.tqfind( ',', from );
+ }
+#endif // TQT_NO_STRINGLIST
+ if ( !count || ( count > 2 && count < 9 ) || count > 11 ) {
+
+#ifdef TQT_CHECK_STATE
+ qWarning("TQFont::fromString: invalid description '%s'",
+ descrip.isEmpty() ? "(empty)" : descrip.latin1());
+#endif
+
+ return FALSE;
+ }
+
+ setFamily(l[0]);
+ if ( count > 1 && l[1].toDouble() > 0.0 )
+ setPointSizeFloat(l[1].toDouble());
+ if ( count == 9 ) {
+ setStyleHint((StyleHint) l[2].toInt());
+ setWeight(l[3].toInt());
+ setItalic(l[4].toInt());
+ setUnderline(l[5].toInt());
+ setStrikeOut(l[6].toInt());
+ setFixedPitch(l[7].toInt());
+ setRawMode(l[8].toInt());
+ } else if ( count == 10 ) {
+ if ( l[2].toInt() > 0 )
+ setPixelSize( l[2].toInt() );
+ setStyleHint((StyleHint) l[3].toInt());
+ setWeight(l[4].toInt());
+ setItalic(l[5].toInt());
+ setUnderline(l[6].toInt());
+ setStrikeOut(l[7].toInt());
+ setFixedPitch(l[8].toInt());
+ setRawMode(l[9].toInt());
+ }
+
+ return TRUE;
+}
+
+#if !defined( TQ_WS_TQWS )
+/*! \internal
+
+ Internal function that dumps font cache statistics.
+*/
+void TQFont::cacheStatistics()
+{
+
+
+}
+#endif // !TQ_WS_TQWS
+
+
+
+/*****************************************************************************
+ TQFont stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+
+/*!
+ \relates TQFont
+
+ Writes the font \a font to the data stream \a s. (toString()
+ writes to a text stream.)
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+TQDataStream &operator<<( TQDataStream &s, const TQFont &font )
+{
+ if ( s.version() == 1 ) {
+ TQCString fam( font.d->request.family.latin1() );
+ s << fam;
+ } else {
+ s << font.d->request.family;
+ }
+
+ if ( s.version() <= 3 ) {
+ TQ_INT16 pointSize = (TQ_INT16) font.d->request.pointSize;
+ if ( pointSize == -1 ) {
+#ifdef TQ_WS_X11
+ pointSize = (TQ_INT16)(font.d->request.pixelSize*720/TQPaintDevice::x11AppDpiY());
+#else
+ pointSize = (TQ_INT16)TQFontInfo( font ).pointSize() * 10;
+#endif
+ }
+ s << pointSize;
+ } else {
+ s << (TQ_INT16) font.d->request.pointSize;
+ s << (TQ_INT16) font.d->request.pixelSize;
+ }
+
+ s << (TQ_UINT8) font.d->request.tqstyleHint;
+ if ( s.version() >= 5 )
+ s << (TQ_UINT8 ) font.d->request.styleStrategy;
+ return s << (TQ_UINT8) 0
+ << (TQ_UINT8) font.d->request.weight
+ << get_font_bits(font.d);
+}
+
+
+/*!
+ \relates TQFont
+
+ Reads the font \a font from the data stream \a s. (fromString()
+ reads from a text stream.)
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+TQDataStream &operator>>( TQDataStream &s, TQFont &font )
+{
+ if (font.d->deref()) delete font.d;
+
+ font.d = new TQFontPrivate;
+ font.d->tqmask = TQFontPrivate::Complete;
+
+ TQ_INT16 pointSize, pixelSize = -1;
+ TQ_UINT8 tqstyleHint, styleStrategy = TQFont::PreferDefault, charSet, weight, bits;
+
+ if ( s.version() == 1 ) {
+ TQCString fam;
+ s >> fam;
+ font.d->request.family = TQString( fam );
+ } else {
+ s >> font.d->request.family;
+ }
+
+ s >> pointSize;
+ if ( s.version() >= 4 )
+ s >> pixelSize;
+ s >> tqstyleHint;
+ if ( s.version() >= 5 )
+ s >> styleStrategy;
+ s >> charSet;
+ s >> weight;
+ s >> bits;
+
+ font.d->request.pointSize = pointSize;
+ font.d->request.pixelSize = pixelSize;
+ font.d->request.tqstyleHint = tqstyleHint;
+ font.d->request.styleStrategy = styleStrategy;
+ font.d->request.weight = weight;
+
+ set_font_bits( bits, font.d );
+
+ return s;
+}
+
+#endif // TQT_NO_DATASTREAM
+
+
+
+
+/*****************************************************************************
+ TQFontMetrics member functions
+ *****************************************************************************/
+
+/*!
+ \class TQFontMetrics tqfontmetrics.h
+ \brief The TQFontMetrics class provides font metrics information.
+
+ \ingroup graphics
+ \ingroup shared
+
+ TQFontMetrics functions calculate the size of characters and
+ strings for a given font. There are three ways you can create a
+ TQFontMetrics object:
+
+ \list 1
+ \i Calling the TQFontMetrics constructor with a TQFont creates a
+ font metrics object for a screen-compatible font, i.e. the font
+ cannot be a printer font<sup>*</sup>. If the font is changed
+ later, the font metrics object is \e not updated.
+
+ \i TQWidget::fontMetrics() returns the font metrics for a widget's
+ font. This is equivalent to TQFontMetrics(widget->font()). If the
+ widget's font is changed later, the font metrics object is \e not
+ updated.
+
+ \i TQPainter::fontMetrics() returns the font metrics for a
+ painter's current font. If the painter's font is changed later, the
+ font metrics object is \e not updated.
+ \endlist
+
+ <sup>*</sup> If you use a printer font the values returned may be
+ inaccurate. Printer fonts are not always accessible so the nearest
+ screen font is used if a printer font is supplied.
+
+ Once created, the object provides functions to access the
+ individual metrics of the font, its characters, and for strings
+ rendered in the font.
+
+ There are several functions that operate on the font: ascent(),
+ descent(), height(), leading() and lineSpacing() return the basic
+ size properties of the font. The underlinePos(), overlinePos(),
+ strikeOutPos() and lineWidth() functions, return the properties of
+ the line that underlines, overlines or strikes out the
+ characters. These functions are all fast.
+
+ There are also some functions that operate on the set of glyphs in
+ the font: minLeftBearing(), minRightBearing() and maxWidth().
+ These are by necessity slow, and we recommend avoiding them if
+ possible.
+
+ For each character, you can get its width(), leftBearing() and
+ rightBearing() and tqfind out whether it is in the font using
+ inFont(). You can also treat the character as a string, and use
+ the string functions on it.
+
+ The string functions include width(), to return the width of a
+ string in pixels (or points, for a printer), boundingRect(), to
+ return a rectangle large enough to contain the rendered string,
+ and size(), to return the size of that rectangle.
+
+ Example:
+ \code
+ TQFont font( "times", 24 );
+ TQFontMetrics fm( font );
+ int pixelsWide = fm.width( "What's the width of this text?" );
+ int pixelsHigh = fm.height();
+ \endcode
+
+ \sa TQFont TQFontInfo TQFontDatabase
+*/
+
+/*!
+ Constructs a font metrics object for \a font.
+
+ The font must be screen-compatible, i.e. a font you use when
+ drawing text in \link TQWidget widgets\endlink or \link TQPixmap
+ pixmaps\endlink, not TQPicture or TQPrinter.
+
+ The font metrics object holds the information for the font that is
+ passed in the constructor at the time it is created, and is not
+ updated if the font's attributes are changed later.
+
+ Use TQPainter::fontMetrics() to get the font metrics when painting.
+ This will give correct results also when painting on paint tqdevice
+ that is not screen-compatible.
+*/
+TQFontMetrics::TQFontMetrics( const TQFont &font )
+ : d( font.d ), painter( 0 ), fscript( TQFont::NoScript )
+{
+ d->ref();
+}
+
+/*!
+ \overload
+
+ Constructs a font metrics object for \a font using the given \a
+ script.
+*/
+TQFontMetrics::TQFontMetrics( const TQFont &font, TQFont::Script script )
+ : d( font.d ), painter( 0 ), fscript( script )
+{
+ d->ref();
+}
+
+/*! \internal
+
+ Constructs a font metrics object for the painter's font \a p.
+*/
+TQFontMetrics::TQFontMetrics( const TQPainter *p )
+ : painter ( (TQPainter *) p ), fscript( TQFont::NoScript )
+{
+#if defined(CHECK_STATE)
+ if ( !painter->isActive() )
+ qWarning( "TQFontMetrics: Get font metrics between TQPainter::begin() "
+ "and TQPainter::end()" );
+#endif
+
+ if ( painter->testf(TQPainter::DirtyFont) )
+ painter->updateFont();
+
+ d = painter->pfont ? painter->pfont->d : painter->cfont.d;
+
+#if defined(TQ_WS_X11)
+ if ( d->screen != p->scrn ) {
+ TQFontPrivate *new_d = new TQFontPrivate( *d );
+ TQ_CHECK_PTR( new_d );
+ d = new_d;
+ d->screen = p->scrn;
+ d->count = 1;
+ } else
+#endif // TQ_WS_X11
+ d->ref();
+}
+
+/*!
+ Constructs a copy of \a fm.
+*/
+TQFontMetrics::TQFontMetrics( const TQFontMetrics &fm )
+ : d( fm.d ), painter( 0 ), fscript( fm.fscript )
+{
+ d->ref();
+}
+
+/*!
+ Destroys the font metrics object and frees all allocated
+ resources.
+*/
+TQFontMetrics::~TQFontMetrics()
+{
+ if ( d->deref() )
+ delete d;
+}
+
+/*!
+ Assigns the font metrics \a fm.
+*/
+TQFontMetrics &TQFontMetrics::operator=( const TQFontMetrics &fm )
+{
+ if ( d != fm.d ) {
+ if ( d->deref() )
+ delete d;
+ d = fm.d;
+ d->ref();
+ }
+ painter = fm.painter;
+ return *this;
+}
+
+/*!
+ Returns the ascent of the font.
+
+ The ascent of a font is the distance from the baseline to the
+ highest position characters extend to. In practice, some font
+ designers break this rule, e.g. when they put more than one accent
+ on top of a character, or to accommodate an unusual character in
+ an exotic language, so it is possible (though rare) that this
+ value will be too small.
+
+ \sa descent()
+*/
+int TQFontMetrics::ascent() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+ TQFontEngine *latin_engine = d->engineForScript( TQFont::Latin );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+ TQ_ASSERT( latin_engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return TQMAX(engine->ascent(), latin_engine->ascent());
+}
+
+
+/*!
+ Returns the descent of the font.
+
+ The descent is the distance from the base line to the lowest point
+ characters extend to. (Note that this is different from X, which
+ adds 1 pixel.) In practice, some font designers break this rule,
+ e.g. to accommodate an unusual character in an exotic language, so
+ it is possible (though rare) that this value will be too small.
+
+ \sa ascent()
+*/
+int TQFontMetrics::descent() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+ TQFontEngine *latin_engine = d->engineForScript( TQFont::Latin );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+ TQ_ASSERT( latin_engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return TQMAX(engine->descent(), latin_engine->descent());
+}
+
+/*!
+ Returns the height of the font.
+
+ This is always equal to ascent()+descent()+1 (the 1 is for the
+ base line).
+
+ \sa leading(), lineSpacing()
+*/
+int TQFontMetrics::height() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+ TQFontEngine *latin_engine = d->engineForScript( TQFont::Latin );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+ TQ_ASSERT( latin_engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return (TQMAX(engine->ascent(), latin_engine->ascent()) +
+ TQMAX(engine->descent(), latin_engine->descent()) + 1);
+}
+
+/*!
+ Returns the leading of the font.
+
+ This is the natural inter-line spacing.
+
+ \sa height(), lineSpacing()
+*/
+int TQFontMetrics::leading() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+ TQFontEngine *latin_engine = d->engineForScript( TQFont::Latin );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+ TQ_ASSERT( latin_engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return TQMAX(engine->leading(), latin_engine->leading());
+}
+
+/*!
+ Returns the distance from one base line to the next.
+
+ This value is always equal to leading()+height().
+
+ \sa height(), leading()
+*/
+int TQFontMetrics::lineSpacing() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+ TQFontEngine *latin_engine = d->engineForScript( TQFont::Latin );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+ TQ_ASSERT( latin_engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return (TQMAX(engine->leading(), latin_engine->leading()) +
+ TQMAX(engine->ascent(), latin_engine->ascent()) +
+ TQMAX(engine->descent(), latin_engine->descent()) + 1);
+}
+
+/*!
+ Returns the minimum left bearing of the font.
+
+ This is the smallest leftBearing(char) of all characters in the
+ font.
+
+ Note that this function can be very slow if the font is large.
+
+ \sa minRightBearing(), leftBearing()
+*/
+int TQFontMetrics::minLeftBearing() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+ TQFontEngine *latin_engine = d->engineForScript( TQFont::Latin );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+ TQ_ASSERT( latin_engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return TQMIN(engine->minLeftBearing(), latin_engine->minLeftBearing());
+}
+
+/*!
+ Returns the minimum right bearing of the font.
+
+ This is the smallest rightBearing(char) of all characters in the
+ font.
+
+ Note that this function can be very slow if the font is large.
+
+ \sa minLeftBearing(), rightBearing()
+*/
+int TQFontMetrics::minRightBearing() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+ TQFontEngine *latin_engine = d->engineForScript( TQFont::Latin );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+ TQ_ASSERT( latin_engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return TQMIN(engine->minRightBearing(), latin_engine->minRightBearing());
+}
+
+/*!
+ Returns the width of the widest character in the font.
+*/
+int TQFontMetrics::maxWidth() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+ TQFontEngine *lengine = d->engineForScript( TQFont::Latin );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+ TQ_ASSERT( lengine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return TQMAX(engine->maxCharWidth(), lengine->maxCharWidth());
+}
+
+/*!
+ Returns TRUE if character \a ch is a valid character in the font;
+ otherwise returns FALSE.
+*/
+bool TQFontMetrics::inFont(TQChar ch) const
+{
+ TQFont::Script script;
+ SCRIPT_FOR_CHAR( script, ch );
+
+ TQFontEngine *engine = d->engineForScript( script );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ if ( engine->type() == TQFontEngine::Box ) return FALSE;
+ return engine->canRender( &ch, 1 );
+}
+
+/*! \fn int TQFontMetrics::leftBearing( TQChar ch ) const
+ Returns the left bearing of character \a ch in the font.
+
+ The left bearing is the right-ward distance of the left-most pixel
+ of the character from the logical origin of the character. This
+ value is negative if the pixels of the character extend to the
+ left of the logical origin.
+
+ See width(TQChar) for a graphical description of this metric.
+
+ \sa rightBearing(), minLeftBearing(), width()
+*/
+#if !defined(TQ_WS_WIN) && !defined(TQ_WS_TQWS)
+int TQFontMetrics::leftBearing(TQChar ch) const
+{
+ TQFont::Script script;
+ SCRIPT_FOR_CHAR( script, ch );
+
+ TQFontEngine *engine = d->engineForScript( script );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ if ( engine->type() == TQFontEngine::Box ) return 0;
+
+ glyph_t glyphs[10];
+ int nglyphs = 9;
+ engine->stringToCMap( &ch, 1, glyphs, 0, &nglyphs, FALSE );
+ // ### can nglyphs != 1 happen at all? Not currently I think
+ glyph_metrics_t gi = engine->boundingBox( glyphs[0] );
+ return gi.x;
+}
+#endif // !TQ_WS_WIN
+
+/*! \fn int TQFontMetrics::rightBearing(TQChar ch) const
+ Returns the right bearing of character \a ch in the font.
+
+ The right bearing is the left-ward distance of the right-most
+ pixel of the character from the logical origin of a subsequent
+ character. This value is negative if the pixels of the character
+ extend to the right of the width() of the character.
+
+ See width() for a graphical description of this metric.
+
+ \sa leftBearing(), minRightBearing(), width()
+*/
+#if !defined(TQ_WS_WIN) && !defined(TQ_WS_TQWS)
+int TQFontMetrics::rightBearing(TQChar ch) const
+{
+ TQFont::Script script;
+ SCRIPT_FOR_CHAR( script, ch );
+
+ TQFontEngine *engine = d->engineForScript( script );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ if ( engine->type() == TQFontEngine::Box ) return 0;
+
+ glyph_t glyphs[10];
+ int nglyphs = 9;
+ engine->stringToCMap( &ch, 1, glyphs, 0, &nglyphs, FALSE );
+ // ### can nglyphs != 1 happen at all? Not currently I think
+ glyph_metrics_t gi = engine->boundingBox( glyphs[0] );
+ return gi.xoff - gi.x - gi.width;
+}
+#endif // !TQ_WS_WIN
+
+
+#ifndef TQ_WS_TQWS
+/*!
+ Returns the width in pixels of the first \a len characters of \a
+ str. If \a len is negative (the default), the entire string is
+ used.
+
+ Note that this value is \e not equal to boundingRect().width();
+ boundingRect() returns a rectangle describing the pixels this
+ string will cover whereas width() returns the distance to where
+ the next string should be drawn.
+
+ \sa boundingRect()
+*/
+int TQFontMetrics::width( const TQString &str, int len ) const
+{
+ if (len < 0)
+ len = str.length();
+ if (len == 0)
+ return 0;
+
+ int pos = 0;
+ int width = 0;
+#ifndef TQ_WS_MAC
+ const TQChar *ch = str.tqunicode();
+
+ while (pos < len) {
+ unsigned short uc = ch->tqunicode();
+ if (uc < TQFontEngineData::widthCacheSize && d->engineData && d->engineData->widthCache[uc])
+ width += d->engineData->widthCache[uc];
+ else {
+ TQFont::Script script;
+ SCRIPT_FOR_CHAR( script, *ch );
+
+ if (script >= TQFont::Arabic && script <= TQFont::Khmer)
+ break;
+ if ( ::category( *ch ) != TQChar::Mark_NonSpacing && !qIsZeroWidthChar(ch->tqunicode())) {
+ TQFontEngine *engine = d->engineForScript( script );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ glyph_t glyphs[8];
+ advance_t advances[8];
+ int nglyphs = 7;
+ engine->stringToCMap( ch, 1, glyphs, advances, &nglyphs, FALSE );
+
+ // ### can nglyphs != 1 happen at all? Not currently I think
+ if ( uc < TQFontEngineData::widthCacheSize && advances[0] > 0 && advances[0] < 0x100 )
+ d->engineData->widthCache[ uc ] = advances[0];
+ width += advances[0];
+ }
+ }
+ ++pos;
+ ++ch;
+ }
+ if ( pos < len ) {
+#endif
+ TQTextEngine tqlayout( str, d );
+ tqlayout.itemize( TQTextEngine::WidthOnly );
+ width += tqlayout.width( pos, len-pos );
+#ifndef TQ_WS_MAC
+ }
+#endif
+ return width;
+}
+#endif
+
+/*! \fn int TQFontMetrics::width( TQChar ch ) const
+
+ <img src="bearings.png" align=right>
+
+ Returns the logical width of character \a ch in pixels. This is a
+ distance appropriate for drawing a subsequent character after \a
+ ch.
+
+ Some of the metrics are described in the image to the right. The
+ central dark rectangles cover the logical width() of each
+ character. The outer pale rectangles cover the leftBearing() and
+ rightBearing() of each character. Notice that the bearings of "f"
+ in this particular font are both negative, while the bearings of
+ "o" are both positive.
+
+ \warning This function will produce incorrect results for Arabic
+ characters or non spacing marks in the middle of a string, as the
+ glyph shaping and positioning of marks that happens when
+ processing strings cannot be taken into account. Use charWidth()
+ instead if you aren't looking for the width of isolated
+ characters.
+
+ \sa boundingRect(), charWidth()
+*/
+
+/*! \fn int TQFontMetrics::width( char c ) const
+
+ \overload
+ \obsolete
+
+ Provided to aid porting from TQt 1.x.
+*/
+
+/*! \fn int TQFontMetrics::charWidth( const TQString &str, int pos ) const
+ Returns the width of the character at position \a pos in the
+ string \a str.
+
+ The whole string is needed, as the glyph drawn may change
+ depending on the context (the letter before and after the current
+ one) for some languages (e.g. Arabic).
+
+ This function also takes non spacing marks and ligatures into
+ account.
+*/
+
+#ifndef TQ_WS_TQWS
+/*!
+ Returns the bounding rectangle of the first \a len characters of
+ \a str, which is the set of pixels the text would cover if drawn
+ at (0, 0).
+
+ If \a len is negative (the default), the entire string is used.
+
+ Note that the bounding rectangle may extend to the left of (0, 0),
+ e.g. for italicized fonts, and that the text output may cover \e
+ all pixels in the bounding rectangle.
+
+ Newline characters are processed as normal characters, \e not as
+ linebreaks.
+
+ Due to the different actual character heights, the height of the
+ bounding rectangle of e.g. "Yes" and "yes" may be different.
+
+ \sa width(), TQPainter::boundingRect()
+*/
+TQRect TQFontMetrics::boundingRect( const TQString &str, int len ) const
+{
+ if (len < 0)
+ len = str.length();
+ if (len == 0)
+ return TQRect();
+
+ TQTextEngine tqlayout( str, d );
+ tqlayout.itemize( TQTextEngine::NoBidi|TQTextEngine::SingleLine );
+ glyph_metrics_t gm = tqlayout.boundingBox( 0, len );
+ return TQRect( gm.x, gm.y, gm.width, gm.height );
+}
+#endif
+
+/*!
+ Returns the rectangle that is covered by ink if the character
+ specified by \a ch were to be drawn at the origin of the coordinate
+ system.
+
+ Note that the bounding rectangle may extend to the left of (0, 0),
+ e.g. for italicized fonts, and that the text output may cover \e
+ all pixels in the bounding rectangle. For a space character the rectangle
+ will usually be empty.
+
+ Note that the rectangle usually extends both above and below the
+ base line.
+
+ \warning The width of the returned rectangle is not the advance width
+ of the character. Use boundingRect(const TQString &) or width() instead.
+
+ \sa width()
+*/
+TQRect TQFontMetrics::boundingRect( TQChar ch ) const
+{
+ TQFont::Script script;
+ SCRIPT_FOR_CHAR( script, ch );
+
+ TQFontEngine *engine = d->engineForScript( script );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ glyph_t glyphs[10];
+ int nglyphs = 9;
+ engine->stringToCMap( &ch, 1, glyphs, 0, &nglyphs, FALSE );
+ glyph_metrics_t gi = engine->boundingBox( glyphs[0] );
+ return TQRect( gi.x, gi.y, gi.width, gi.height );
+}
+
+/*!
+ \overload
+
+ Returns the bounding rectangle of the first \a len characters of
+ \a str, which is the set of pixels the text would cover if drawn
+ at (0, 0). The drawing, and hence the bounding rectangle, is
+ constrained to the rectangle (\a x, \a y, \a w, \a h).
+
+ If \a len is negative (which is the default), the entire string is
+ used.
+
+ The \a flgs argument is the bitwise OR of the following flags:
+ \list
+ \i \c AlignAuto aligns to the left border for all languages except
+ Arabic and Hebrew where it aligns to the right.
+ \i \c AlignLeft aligns to the left border.
+ \i \c AlignRight aligns to the right border.
+ \i \c AlignJustify produces justified text.
+ \i \c AlignHCenter aligns horizontally centered.
+ \i \c AlignTop aligns to the top border.
+ \i \c AlignBottom aligns to the bottom border.
+ \i \c AlignVCenter aligns vertically centered
+ \i \c AlignCenter (== \c{AlignHCenter | AlignVCenter})
+ \i \c SingleLine ignores newline characters in the text.
+ \i \c ExpandTabs expands tabs (see below)
+ \i \c ShowPrefix interprets "&amp;x" as "<u>x</u>", i.e. underlined.
+ \i \c WordBreak breaks the text to fit the rectangle.
+ \endlist
+
+ Horizontal tqalignment defaults to \c AlignAuto and vertical
+ tqalignment defaults to \c AlignTop.
+
+ If several of the horizontal or several of the vertical tqalignment
+ flags are set, the resulting tqalignment is undefined.
+
+ These flags are defined in \c tqnamespace.h.
+
+ If \c ExpandTabs is set in \a flgs, then: if \a tabarray is
+ non-null, it specifies a 0-terminated sequence of pixel-positions
+ for tabs; otherwise if \a tabstops is non-zero, it is used as the
+ tab spacing (in pixels).
+
+ Note that the bounding rectangle may extend to the left of (0, 0),
+ e.g. for italicized fonts, and that the text output may cover \e
+ all pixels in the bounding rectangle.
+
+ Newline characters are processed as linebreaks.
+
+ Despite the different actual character heights, the heights of the
+ bounding rectangles of "Yes" and "yes" are the same.
+
+ The bounding rectangle given by this function is somewhat larger
+ than that calculated by the simpler boundingRect() function. This
+ function uses the \link minLeftBearing() maximum left \endlink and
+ \link minRightBearing() right \endlink font bearings as is
+ necessary for multi-line text to align correctly. Also,
+ fontHeight() and lineSpacing() are used to calculate the height,
+ rather than individual character heights.
+
+ The \a intern argument should not be used.
+
+ \sa width(), TQPainter::boundingRect(), TQt::AlignmentFlags
+*/
+TQRect TQFontMetrics::boundingRect( int x, int y, int w, int h, int flgs,
+ const TQString& str, int len, int tabstops,
+ int *tabarray, TQTextParag **intern ) const
+{
+ if ( len < 0 )
+ len = str.length();
+
+ int tabarraylen=0;
+ if (tabarray)
+ while (tabarray[tabarraylen])
+ tabarraylen++;
+
+ TQRect rb;
+ TQRect r(x, y, w, h);
+ qt_format_text( TQFont( d, d->painttqdevice ), r, flgs|TQt::DontPrint, str, len, &rb,
+ tabstops, tabarray, tabarraylen, intern, 0 );
+
+ return rb;
+}
+
+/*!
+ Returns the size in pixels of the first \a len characters of \a
+ str.
+
+ If \a len is negative (the default), the entire string is used.
+
+ The \a flgs argument is the bitwise OR of the following flags:
+ \list
+ \i \c SingleLine ignores newline characters.
+ \i \c ExpandTabs expands tabs (see below)
+ \i \c ShowPrefix interprets "&amp;x" as "<u>x</u>", i.e. underlined.
+ \i \c WordBreak breaks the text to fit the rectangle.
+ \endlist
+
+ These flags are defined in \c tqnamespace.h.
+
+ If \c ExpandTabs is set in \a flgs, then: if \a tabarray is
+ non-null, it specifies a 0-terminated sequence of pixel-positions
+ for tabs; otherwise if \a tabstops is non-zero, it is used as the
+ tab spacing (in pixels).
+
+ Newline characters are processed as linebreaks.
+
+ Despite the different actual character heights, the heights of the
+ bounding rectangles of "Yes" and "yes" are the same.
+
+ The \a intern argument should not be used.
+
+ \sa boundingRect()
+*/
+TQSize TQFontMetrics::size( int flgs, const TQString &str, int len, int tabstops,
+ int *tabarray, TQTextParag **intern ) const
+{
+ return boundingRect(0,0,0,0,flgs,str,len,tabstops,tabarray,intern).size();
+}
+
+/*!
+ Returns the distance from the base line to where an underscore
+ should be drawn.
+
+ \sa overlinePos(), strikeOutPos(), lineWidth()
+*/
+int TQFontMetrics::underlinePos() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return engine->underlinePosition();
+}
+
+/*!
+ Returns the distance from the base line to where an overline
+ should be drawn.
+
+ \sa underlinePos(), strikeOutPos(), lineWidth()
+*/
+int TQFontMetrics::overlinePos() const
+{
+ int pos = ascent() + 1;
+ return pos > 0 ? pos : 1;
+}
+
+/*!
+ Returns the distance from the base line to where the strikeout
+ line should be drawn.
+
+ \sa underlinePos(), overlinePos(), lineWidth()
+*/
+int TQFontMetrics::strikeOutPos() const
+{
+ int pos = ascent() / 3;
+ return pos > 0 ? pos : 1;
+}
+
+/*!
+ Returns the width of the underline and strikeout lines, adjusted
+ for the point size of the font.
+
+ \sa underlinePos(), overlinePos(), strikeOutPos()
+*/
+int TQFontMetrics::lineWidth() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return engine->lineThickness();
+}
+
+
+
+
+/*****************************************************************************
+ TQFontInfo member functions
+ *****************************************************************************/
+
+/*!
+ \class TQFontInfo tqfontinfo.h
+
+ \brief The TQFontInfo class provides general information about fonts.
+
+ \ingroup graphics
+ \ingroup shared
+
+ The TQFontInfo class provides the same access functions as TQFont,
+ e.g. family(), pointSize(), italic(), weight(), fixedPitch(),
+ tqstyleHint() etc. But whilst the TQFont access functions return the
+ values that were set, a TQFontInfo object returns the values that
+ apply to the font that will actually be used to draw the text.
+
+ For example, when the program asks for a 25pt Courier font on a
+ machine that has a non-scalable 24pt Courier font, TQFont will
+ (normally) use the 24pt Courier for rendering. In this case,
+ TQFont::pointSize() returns 25 and TQFontInfo::pointSize() returns
+ 24.
+
+ There are three ways to create a TQFontInfo object.
+ \list 1
+ \i Calling the TQFontInfo constructor with a TQFont creates a font
+ info object for a screen-compatible font, i.e. the font cannot be
+ a printer font<sup>*</sup>. If the font is changed later, the font
+ info object is \e not updated.
+
+ \i TQWidget::fontInfo() returns the font info for a widget's font.
+ This is equivalent to calling TQFontInfo(widget->font()). If the
+ widget's font is changed later, the font info object is \e not
+ updated.
+
+ \i TQPainter::fontInfo() returns the font info for a painter's
+ current font. If the painter's font is changed later, the font
+ info object is \e not updated.
+ \endlist
+
+ <sup>*</sup> If you use a printer font the values returned may be
+ inaccurate. Printer fonts are not always accessible so the nearest
+ screen font is used if a printer font is supplied.
+
+ \sa TQFont TQFontMetrics TQFontDatabase
+*/
+
+/*!
+ Constructs a font info object for \a font.
+
+ The font must be screen-compatible, i.e. a font you use when
+ drawing text in \link TQWidget widgets\endlink or \link TQPixmap
+ pixmaps\endlink, not TQPicture or TQPrinter.
+
+ The font info object holds the information for the font that is
+ passed in the constructor at the time it is created, and is not
+ updated if the font's attributes are changed later.
+
+ Use TQPainter::fontInfo() to get the font info when painting.
+ This will give correct results also when painting on paint tqdevice
+ that is not screen-compatible.
+*/
+TQFontInfo::TQFontInfo( const TQFont &font )
+ : d( font.d ), painter( 0 ), fscript( TQFont::NoScript )
+{
+ d->ref();
+}
+
+/*!
+ Constructs a font info object for \a font using the specified \a
+ script.
+*/
+TQFontInfo::TQFontInfo( const TQFont &font, TQFont::Script script )
+ : d( font.d ), painter( 0 ), fscript( script )
+{
+ d->ref();
+}
+
+/*! \internal
+
+ Constructs a font info object from the painter's font \a p.
+*/
+TQFontInfo::TQFontInfo( const TQPainter *p )
+ : painter( 0 ), fscript( TQFont::NoScript )
+{
+ TQPainter *painter = (TQPainter *) p;
+
+#if defined(CHECK_STATE)
+ if ( !painter->isActive() )
+ qWarning( "TQFontInfo: Get font info between TQPainter::begin() "
+ "and TQPainter::end()" );
+#endif
+
+ painter->setf( TQPainter::FontInf );
+ if ( painter->testf(TQPainter::DirtyFont) )
+ painter->updateFont();
+ if ( painter->pfont )
+ d = painter->pfont->d;
+ else
+ d = painter->cfont.d;
+ d->ref();
+}
+
+/*!
+ Constructs a copy of \a fi.
+*/
+TQFontInfo::TQFontInfo( const TQFontInfo &fi )
+ : d(fi.d), painter(0), fscript( fi.fscript )
+{
+ d->ref();
+}
+
+/*!
+ Destroys the font info object.
+*/
+TQFontInfo::~TQFontInfo()
+{
+ if ( d->deref() )
+ delete d;
+}
+
+/*!
+ Assigns the font info in \a fi.
+*/
+TQFontInfo &TQFontInfo::operator=( const TQFontInfo &fi )
+{
+ if ( d != fi.d ) {
+ if ( d->deref() )
+ delete d;
+ d = fi.d;
+ d->ref();
+ }
+ painter = 0;
+ fscript = fi.fscript;
+ return *this;
+}
+
+/*!
+ Returns the family name of the matched window system font.
+
+ \sa TQFont::family()
+*/
+TQString TQFontInfo::family() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+ return engine->fontDef.family;
+}
+
+/*!
+ Returns the point size of the matched window system font.
+
+ \sa TQFont::pointSize()
+*/
+int TQFontInfo::pointSize() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+ return ( engine->fontDef.pointSize + 5 ) / 10;
+}
+
+/*!
+ Returns the pixel size of the matched window system font.
+
+ \sa TQFont::pointSize()
+*/
+int TQFontInfo::pixelSize() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+ return engine->fontDef.pixelSize;
+}
+
+/*!
+ Returns the italic value of the matched window system font.
+
+ \sa TQFont::italic()
+*/
+bool TQFontInfo::italic() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+ return engine->fontDef.italic;
+}
+
+/*!
+ Returns the weight of the matched window system font.
+
+ \sa TQFont::weight(), bold()
+*/
+int TQFontInfo::weight() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+ return engine->fontDef.weight;
+
+}
+
+/*!
+ \fn bool TQFontInfo::bold() const
+
+ Returns TRUE if weight() would return a value greater than \c
+ TQFont::Normal; otherwise returns FALSE.
+
+ \sa weight(), TQFont::bold()
+*/
+
+/*!
+ Returns the underline value of the matched window system font.
+
+ \sa TQFont::underline()
+
+ \internal
+
+ Here we read the underline flag directly from the TQFont.
+ This is OK for X11 and for Windows because we always get what we want.
+*/
+bool TQFontInfo::underline() const
+{
+ return d->underline;
+}
+
+/*!
+ Returns the overline value of the matched window system font.
+
+ \sa TQFont::overline()
+
+ \internal
+
+ Here we read the overline flag directly from the TQFont.
+ This is OK for X11 and for Windows because we always get what we want.
+*/
+bool TQFontInfo::overline() const
+{
+ return d->overline;
+}
+
+/*!
+ Returns the strikeout value of the matched window system font.
+
+ \sa TQFont::strikeOut()
+
+ \internal Here we read the strikeOut flag directly from the TQFont.
+ This is OK for X11 and for Windows because we always get what we want.
+*/
+bool TQFontInfo::strikeOut() const
+{
+ return d->strikeOut;
+}
+
+/*!
+ Returns the fixed pitch value of the matched window system font.
+
+ \sa TQFont::fixedPitch()
+*/
+bool TQFontInfo::fixedPitch() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+#ifdef TQ_OS_MAC
+ if (!engine->fontDef.fixedPitchComputed) {
+ TQChar ch[2] = { TQChar('i'), TQChar('m') };
+ glyph_t g[2];
+ int l = 2;
+ advance_t a[2];
+ engine->stringToCMap(ch, 2, g, a, &l, FALSE);
+ engine->fontDef.fixedPitch = a[0] == a[1];
+ engine->fontDef.fixedPitchComputed = TRUE;
+ }
+#endif
+ return engine->fontDef.fixedPitch;
+}
+
+/*!
+ Returns the style of the matched window system font.
+
+ Currently only returns the style hint set in TQFont.
+
+ \sa TQFont::tqstyleHint() TQFont::StyleHint
+*/
+TQFont::StyleHint TQFontInfo::tqstyleHint() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+ return (TQFont::StyleHint) engine->fontDef.tqstyleHint;
+}
+
+/*!
+ Returns TRUE if the font is a raw mode font; otherwise returns
+ FALSE.
+
+ If it is a raw mode font, all other functions in TQFontInfo will
+ return the same values set in the TQFont, regardless of the font
+ actually used.
+
+ \sa TQFont::rawMode()
+*/
+bool TQFontInfo::rawMode() const
+{
+ return d->rawMode;
+}
+
+/*!
+ Returns TRUE if the matched window system font is exactly the same
+ as the one specified by the font; otherwise returns FALSE.
+
+ \sa TQFont::exactMatch()
+*/
+bool TQFontInfo::exactMatch() const
+{
+ TQFontEngine *engine = d->engineForScript( (TQFont::Script) fscript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return d->rawMode ? engine->type() != TQFontEngine::Box
+ : d->request == engine->fontDef;
+}
+
+
+
+
+// **********************************************************************
+// TQFontCache
+// **********************************************************************
+
+#ifdef TQFONTCACHE_DEBUG
+// fast timeouts for debugging
+static const int fast_timeout = 1000; // 1s
+static const int slow_timeout = 5000; // 5s
+#else
+static const int fast_timeout = 10000; // 10s
+static const int slow_timeout = 300000; // 5m
+#endif // TQFONTCACHE_DEBUG
+
+TQFontCache *TQFontCache::instance = 0;
+const uint TQFontCache::min_cost = 4*1024; // 4mb
+
+static TQSingleCleanupHandler<TQFontCache> cleanup_fontcache;
+
+
+TQFontCache::TQFontCache()
+ : TQObject( tqApp, "global font cache" ), total_cost( 0 ), max_cost( min_cost ),
+ current_timestamp( 0 ), fast( FALSE ), timer_id( -1 )
+{
+ TQ_ASSERT( instance == 0 );
+ instance = this;
+ cleanup_fontcache.set( &instance );
+}
+
+TQFontCache::~TQFontCache()
+{
+ {
+ EngineDataCache::Iterator it = engineDataCache.begin(),
+ end = engineDataCache.end();
+ while ( it != end ) {
+ if ( it.data()->count == 0 )
+ delete it.data();
+ else
+ FC_DEBUG("TQFontCache::~TQFontCache: engineData %p still has refcount %d",
+ it.data(), it.data()->count);
+ ++it;
+ }
+ }
+ EngineCache::Iterator it = engineCache.begin(),
+ end = engineCache.end();
+ while ( it != end ) {
+ if ( it.data().data->count == 0 ) {
+ if ( --it.data().data->cache_count == 0 ) {
+ FC_DEBUG("TQFontCache::~TQFontCache: deleting engine %p key=(%d / %d %d %d %d %d)",
+ it.data().data, it.key().script, it.key().def.pointSize,
+ it.key().def.pixelSize, it.key().def.weight, it.key().def.italic,
+ it.key().def.fixedPitch);
+
+ delete it.data().data;
+ }
+ } else {
+ FC_DEBUG("TQFontCache::~TQFontCache: engine = %p still has refcount %d",
+ it.data().data, it.data().data->count);
+ }
+ ++it;
+ }
+ instance = 0;
+}
+
+#ifdef TQ_WS_TQWS
+void TQFontCache::clear()
+{
+ {
+ EngineDataCache::Iterator it = engineDataCache.begin(),
+ end = engineDataCache.end();
+ while ( it != end ) {
+ TQFontEngineData *data = it.data();
+ if ( data->engine )
+ data->engine->deref();
+ data->engine = 0;
+ ++it;
+ }
+ }
+
+ EngineCache::Iterator it = engineCache.begin(),
+ end = engineCache.end();
+ while ( it != end ) {
+ if ( it.data().data->count == 0 ) {
+ if ( --it.data().data->cache_count == 0 ) {
+ FC_DEBUG("TQFontCache::~TQFontCache: deleting engine %p key=(%d / %d %d %d %d %d)",
+ it.data().data, it.key().script, it.key().def.pointSize,
+ it.key().def.pixelSize, it.key().def.weight, it.key().def.italic,
+ it.key().def.fixedPitch);
+ delete it.data().data;
+ }
+ } else {
+ FC_DEBUG("TQFontCache::~TQFontCache: engine = %p still has refcount %d",
+ it.data().data, it.data().data->count);
+ }
+ ++it;
+ }
+}
+#endif
+
+TQFontEngineData *TQFontCache::tqfindEngineData( const Key &key ) const
+{
+ EngineDataCache::ConstIterator it = engineDataCache.tqfind( key ),
+ end = engineDataCache.end();
+ if ( it == end ) return 0;
+
+ // found
+ return it.data();
+}
+
+void TQFontCache::insertEngineData( const Key &key, TQFontEngineData *engineData )
+{
+ FC_DEBUG( "TQFontCache: inserting new engine data %p", engineData );
+
+ engineDataCache.insert( key, engineData );
+ increaseCost( sizeof( TQFontEngineData ) );
+}
+
+TQFontEngine *TQFontCache::tqfindEngine( const Key &key )
+{
+ EngineCache::Iterator it = engineCache.tqfind( key ),
+ end = engineCache.end();
+ if ( it == end ) return 0;
+
+ // found... update the hitcount and timestamp
+ it.data().hits++;
+ it.data().timestamp = ++current_timestamp;
+
+ FC_DEBUG( "TQFontCache: found font engine\n"
+ " %p: timestamp %4u hits %3u ref %2d/%2d, type '%s'",
+ it.data().data, it.data().timestamp, it.data().hits,
+ it.data().data->count, it.data().data->cache_count,
+ it.data().data->name() );
+
+ return it.data().data;
+}
+
+void TQFontCache::insertEngine( const Key &key, TQFontEngine *engine )
+{
+ FC_DEBUG( "TQFontCache: inserting new engine %p", engine );
+
+ Engine data( engine );
+ data.timestamp = ++current_timestamp;
+
+ engineCache.insert( key, data );
+
+ // only increase the cost if this is the first time we insert the engine
+ if ( engine->cache_count == 0 )
+ increaseCost( engine->cache_cost );
+
+ ++engine->cache_count;
+}
+
+void TQFontCache::increaseCost( uint cost )
+{
+ cost = ( cost + 512 ) / 1024; // store cost in kb
+ cost = cost > 0 ? cost : 1;
+ total_cost += cost;
+
+ FC_DEBUG( " COST: increased %u kb, total_cost %u kb, max_cost %u kb",
+ cost, total_cost, max_cost );
+
+ if ( total_cost > max_cost) {
+ max_cost = total_cost;
+
+ if ( timer_id == -1 || ! fast ) {
+ FC_DEBUG( " TIMER: starting fast timer (%d ms)", fast_timeout );
+
+ if (timer_id != -1) killTimer( timer_id );
+ timer_id = startTimer( fast_timeout );
+ fast = TRUE;
+ }
+ }
+}
+
+void TQFontCache::decreaseCost( uint cost )
+{
+ cost = ( cost + 512 ) / 1024; // cost is stored in kb
+ cost = cost > 0 ? cost : 1;
+ TQ_ASSERT( cost <= total_cost );
+ total_cost -= cost;
+
+ FC_DEBUG( " COST: decreased %u kb, total_cost %u kb, max_cost %u kb",
+ cost, total_cost, max_cost );
+}
+
+#if defined(TQ_WS_WIN ) || defined (TQ_WS_TQWS)
+void TQFontCache::cleanupPrinterFonts()
+{
+ FC_DEBUG( "TQFontCache::cleanupPrinterFonts" );
+
+ {
+ FC_DEBUG( " CLEAN engine data:" );
+
+ // clean out all unused engine datas
+ EngineDataCache::Iterator it = engineDataCache.begin(),
+ end = engineDataCache.end();
+ while ( it != end ) {
+ if ( it.key().screen == 0 ) {
+ ++it;
+ continue;
+ }
+
+ if( it.data()->count > 0 ) {
+#ifdef TQ_WS_WIN
+ for(int i = 0; i < TQFont::LastPrivateScript; ++i) {
+ if( it.data()->engines[i] ) {
+ it.data()->engines[i]->deref();
+ it.data()->engines[i] = 0;
+ }
+ }
+#else
+ if ( it.data()->engine ) {
+ it.data()->engine->deref();
+ it.data()->engine = 0;
+ }
+#endif
+ ++it;
+ } else {
+
+ EngineDataCache::Iterator rem = it++;
+
+ decreaseCost( sizeof( TQFontEngineData ) );
+
+ FC_DEBUG( " %p", rem.data() );
+
+ delete rem.data();
+ engineDataCache.remove( rem );
+ }
+ }
+ }
+
+ EngineCache::Iterator it = engineCache.begin(),
+ end = engineCache.end();
+ while( it != end ) {
+ if ( it.data().data->count > 0 || it.key().screen == 0) {
+ ++it;
+ continue;
+ }
+
+ FC_DEBUG( " %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'",
+ it.data().data, it.data().timestamp, it.data().hits,
+ it.data().data->count, it.data().data->cache_count,
+ it.data().data->name() );
+
+ if ( --it.data().data->cache_count == 0 ) {
+ FC_DEBUG( " DELETE: last occurence in cache" );
+
+ decreaseCost( it.data().data->cache_cost );
+ delete it.data().data;
+ }
+
+ engineCache.remove( it++ );
+ }
+}
+#endif
+
+void TQFontCache::timerEvent( TQTimerEvent * )
+{
+ FC_DEBUG( "TQFontCache::timerEvent: performing cache maintenance (timestamp %u)",
+ current_timestamp );
+
+ if ( total_cost <= max_cost && max_cost <= min_cost ) {
+ FC_DEBUG( " cache redused sufficiently, stopping timer" );
+
+ killTimer( timer_id );
+ timer_id = -1;
+ fast = FALSE;
+
+ return;
+ }
+
+ // go through the cache and count up everything in use
+ uint in_use_cost = 0;
+
+ {
+ FC_DEBUG( " SWEEP engine data:" );
+
+ // make sure the cost of each engine data is at least 1kb
+ const uint engine_data_cost =
+ sizeof( TQFontEngineData ) > 1024 ? sizeof( TQFontEngineData ) : 1024;
+
+ EngineDataCache::ConstIterator it = engineDataCache.begin(),
+ end = engineDataCache.end();
+ for ( ; it != end; ++it ) {
+#ifdef TQFONTCACHE_DEBUG
+ FC_DEBUG( " %p: ref %2d", it.data(), it.data()->count );
+
+# if defined(TQ_WS_X11) || defined(TQ_WS_WIN)
+ // print out all engines
+ for ( int i = 0; i < TQFont::LastPrivateScript; ++i ) {
+ if ( ! it.data()->engines[i] ) continue;
+ FC_DEBUG( " tqcontains %p", it.data()->engines[i] );
+ }
+# endif // TQ_WS_X11 || TQ_WS_WIN
+#endif // TQFONTCACHE_DEBUG
+
+ if ( it.data()->count > 0 )
+ in_use_cost += engine_data_cost;
+ }
+ }
+
+ {
+ FC_DEBUG( " SWEEP engine:" );
+
+ EngineCache::ConstIterator it = engineCache.begin(),
+ end = engineCache.end();
+ for ( ; it != end; ++it ) {
+ FC_DEBUG( " %p: timestamp %4u hits %2u ref %2d/%2d, cost %u bytes",
+ it.data().data, it.data().timestamp, it.data().hits,
+ it.data().data->count, it.data().data->cache_count,
+ it.data().data->cache_cost );
+
+ if ( it.data().data->count > 0 )
+ in_use_cost += it.data().data->cache_cost / it.data().data->cache_count;
+ }
+
+ // attempt to make up for rounding errors
+ in_use_cost += (uint)engineCache.count();
+ }
+
+ in_use_cost = ( in_use_cost + 512 ) / 1024; // cost is stored in kb
+
+ /*
+ calculate the new maximum cost for the cache
+
+ NOTE: in_use_cost is *not* correct due to rounding errors in the
+ above algorithm. instead of worrying about getting the
+ calculation correct, we are more interested in speed, and use
+ in_use_cost as a floor for new_max_cost
+ */
+ uint new_max_cost = TQMAX( TQMAX( max_cost / 2, in_use_cost ), min_cost );
+
+ FC_DEBUG( " after sweep, in use %u kb, total %u kb, max %u kb, new max %u kb",
+ in_use_cost, total_cost, max_cost, new_max_cost );
+
+ if ( new_max_cost == max_cost ) {
+ if ( fast ) {
+ FC_DEBUG( " cannot shrink cache, slowing timer" );
+
+ killTimer( timer_id );
+ timer_id = startTimer( slow_timeout );
+ fast = FALSE;
+ }
+
+ return;
+ } else if ( ! fast ) {
+ FC_DEBUG( " dropping into passing gear" );
+
+ killTimer( timer_id );
+ timer_id = startTimer( fast_timeout );
+ fast = TRUE;
+ }
+
+ max_cost = new_max_cost;
+
+ {
+ FC_DEBUG( " CLEAN engine data:" );
+
+ // clean out all unused engine datas
+ EngineDataCache::Iterator it = engineDataCache.begin(),
+ end = engineDataCache.end();
+ while ( it != end ) {
+ if ( it.data()->count > 0 ) {
+ ++it;
+ continue;
+ }
+
+ EngineDataCache::Iterator rem = it++;
+
+ decreaseCost( sizeof( TQFontEngineData ) );
+
+ FC_DEBUG( " %p", rem.data() );
+
+ delete rem.data();
+ engineDataCache.remove( rem );
+ }
+ }
+
+ // clean out the engine cache just enough to get below our new max cost
+ uint current_cost;
+ do {
+ current_cost = total_cost;
+
+ EngineCache::Iterator it = engineCache.begin(),
+ end = engineCache.end();
+ // determine the oldest and least popular of the unused engines
+ uint oldest = ~0;
+ uint least_popular = ~0;
+
+ for ( ; it != end; ++it ) {
+ if ( it.data().data->count > 0 ) continue;
+
+ if ( it.data().timestamp < oldest &&
+ it.data().hits <= least_popular ) {
+ oldest = it.data().timestamp;
+ least_popular = it.data().hits;
+ }
+ }
+
+ FC_DEBUG( " oldest %u least popular %u", oldest, least_popular );
+
+ for ( it = engineCache.begin(); it != end; ++it ) {
+ if ( it.data().data->count == 0 &&
+ it.data().timestamp == oldest &&
+ it.data().hits == least_popular)
+ break;
+ }
+
+ if ( it != end ) {
+ FC_DEBUG( " %p: timestamp %4u hits %2u ref %2d/%2d, type '%s'",
+ it.data().data, it.data().timestamp, it.data().hits,
+ it.data().data->count, it.data().data->cache_count,
+ it.data().data->name() );
+
+ if ( --it.data().data->cache_count == 0 ) {
+ FC_DEBUG( " DELETE: last occurence in cache" );
+
+ decreaseCost( it.data().data->cache_cost );
+ delete it.data().data;
+ } else {
+ /*
+ this particular font engine is in the cache multiple
+ times... set current_cost to zero, so that we can
+ keep looping to get rid of all occurences
+ */
+ current_cost = 0;
+ }
+
+ engineCache.remove( it );
+ }
+ } while ( current_cost != total_cost && total_cost > max_cost );
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqfont.h b/tqtinterface/qt4/src/kernel/tqfont.h
new file mode 100644
index 0000000..68e9e07
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfont.h
@@ -0,0 +1,524 @@
+/****************************************************************************
+**
+** Definition of TQFont class
+**
+** Created : 940514
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFONT_H
+#define TQFONT_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qfont.h>
+
+#endif // USE_QT4
+
+#ifndef USE_QT4
+
+class TQFontPrivate; /* don't touch */
+
+#endif // USE_QT4
+
+class TQStringList;
+class TQTextFormatCollection;
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQFont : public QFont, virtual public TQt
+{
+public:
+ // default font
+ TQFont() : QFont() {}
+ // specific font
+#ifdef TQ_TQDOC
+ TQFont( const QString &family, int pointSize = 12, int weight = Normal, bool italic = FALSE ) : QFont( family, pointSize, weight, italic ) {}
+#else
+ TQFont( const QString &family, int pointSize = -1, int weight = -1, bool italic = FALSE ) : QFont( family, pointSize, weight, italic ) {}
+#endif
+ // copy constructor
+ TQFont( const QFont &qf ) : QFont( qf ) {}
+
+// static QT3_SUPPORT QFont defaultFont();
+// static QT3_SUPPORT void setDefaultFont(const QFont &);
+// QT3_SUPPORT void setPixelSizeFloat(qreal);
+ inline qreal pointSizeFloat() const { return pointSizeF(); }
+ inline void setPointSizeFloat(qreal size) { setPointSizeF(size); }
+
+ // a copy of this lives in qtqunicodetables.cpp, as we can't include
+ // tqfont.h it in tools/. Do not modify without changing the script
+ // enum in qtqunicodetable_p.h as well.
+ enum Script {
+ // European Alphabetic Scripts
+ Latin,
+ Greek,
+ Cyrillic,
+ Armenian,
+ Georgian,
+ Runic,
+ Ogham,
+ SpacingModifiers,
+ CombiningMarks,
+
+ // Middle Eastern Scripts
+ Hebrew,
+ Arabic,
+ Syriac,
+ Thaana,
+
+ // South and Southeast Asian Scripts
+ Devanagari,
+ Bengali,
+ Gurmukhi,
+ Gujarati,
+ Oriya,
+ Tamil,
+ Telugu,
+ Kannada,
+ Malayalam,
+ Sinhala,
+ Thai,
+ Lao,
+ Tibetan,
+ Myanmar,
+ Khmer,
+
+ // East Asian Scripts
+ Han,
+ Hiragana,
+ Katakana,
+ Hangul,
+ Bopomofo,
+ Yi,
+
+ // Additional Scripts
+ Ethiopic,
+ Cherokee,
+ CanadianAboriginal,
+ Mongolian,
+
+ // Symbols
+ CurrencySymbols,
+ LetterlikeSymbols,
+ NumberForms,
+ MathematicalOperators,
+ TechnicalSymbols,
+ GeometricSymbols,
+ MiscellaneousSymbols,
+ EnclosedAndSquare,
+ Braille,
+
+ Unicode,
+
+ // some scripts added in Unicode 3.2
+ Tagalog,
+ Hanunoo,
+ Buhid,
+ Tagbanwa,
+
+ KatakanaHalfWidth,
+
+ // from Unicode 4.0
+ Limbu,
+ TaiLe,
+
+ // End
+#if !defined(TQ_TQDOC)
+ NScripts,
+ UnknownScript = NScripts,
+
+ NoScript,
+
+ // ----------------------------------------
+ // Dear User, you can see values > NScript,
+ // but they are internal - do not touch.
+
+ Han_Japanese,
+ Han_SimplifiedChinese,
+ Han_TraditionalChinese,
+ Han_Korean,
+
+ LastPrivateScript
+#endif
+ };
+
+private:
+ // We need access to these members
+ void tqt_x11SetScreen( int screen = -1 );
+ int tqt_x11Screen() const;
+
+public:
+ friend class TQTextFormatCollection;
+
+public:
+ // Interoperability
+ static const TQFont& convertFromQFont( QFont& qf );
+};
+
+// Interoperability
+inline static const TQFont& convertFromQFont( const QFont& qf ) {
+ return (*static_cast<const TQFont*>(&qf));
+}
+
+#else // USE_QT4
+
+class TQ_EXPORT TQFont
+{
+public:
+ enum StyleHint {
+ Helvetica, SansSerif = Helvetica,
+ Times, Serif = Times,
+ Courier, TypeWriter = Courier,
+ OldEnglish, Decorative = OldEnglish,
+ System,
+ AnyStyle
+ };
+
+ enum StyleStrategy {
+ PreferDefault = 0x0001,
+ PreferBitmap = 0x0002,
+ PreferDevice = 0x0004,
+ PreferOutline = 0x0008,
+ ForceOutline = 0x0010,
+ PreferMatch = 0x0020,
+ PreferQuality = 0x0040,
+ PreferAntialias = 0x0080,
+ NoAntialias = 0x0100,
+ OpenGLCompatible = 0x0200
+ };
+
+ enum Weight {
+ Light = 25,
+ Normal = 50,
+ DemiBold = 63,
+ Bold = 75,
+ Black = 87
+ };
+
+ enum Stretch {
+ UltraCondensed = 50,
+ ExtraCondensed = 62,
+ Condensed = 75,
+ SemiCondensed = 87,
+ Unstretched = 100,
+ SemiExpanded = 112,
+ Expanded = 125,
+ ExtraExpanded = 150,
+ UltraExpanded = 200
+ };
+
+ // default font
+ TQFont();
+ // specific font
+#ifdef TQ_TQDOC
+ TQFont( const TQString &family, int pointSize = 12, int weight = Normal,
+ bool italic = FALSE );
+#else
+ TQFont( const TQString &family, int pointSize = -1, int weight = -1,
+ bool italic = FALSE );
+#endif
+ // copy constructor
+ TQFont( const TQFont & );
+
+ ~TQFont();
+
+ TQString family() const;
+ void setFamily( const TQString &);
+
+ int pointSize() const;
+ float pointSizeFloat() const;
+ void setPointSize( int );
+ void setPointSizeFloat( float );
+
+ int pixelSize() const;
+ void setPixelSize( int );
+ void setPixelSizeFloat( float );
+
+ int weight() const;
+ void setWeight( int );
+
+ bool bold() const;
+ void setBold( bool );
+
+ bool italic() const;
+ void setItalic( bool );
+
+ bool underline() const;
+ void setUnderline( bool );
+
+ bool overline() const;
+ void setOverline( bool );
+
+ bool strikeOut() const;
+ void setStrikeOut( bool );
+
+ bool fixedPitch() const;
+ void setFixedPitch( bool );
+
+ StyleHint tqstyleHint() const;
+ StyleStrategy styleStrategy() const;
+ void setStyleHint( StyleHint, StyleStrategy = PreferDefault );
+ void setStyleStrategy( StyleStrategy s );
+
+ int stretch() const;
+ void setStretch( int );
+
+ // is raw mode still needed?
+ bool rawMode() const;
+ void setRawMode( bool );
+
+ // dupicated from TQFontInfo
+ bool exactMatch() const;
+
+ TQFont &operator=( const TQFont & );
+ bool operator==( const TQFont & ) const;
+ bool operator!=( const TQFont & ) const;
+ bool isCopyOf( const TQFont & ) const;
+
+
+#ifdef TQ_WS_WIN
+ HFONT handle() const;
+#else // !TQ_WS_WIN
+ TQt::HANDLE handle() const;
+#endif // TQ_WS_WIN
+
+
+ // needed for X11
+ void setRawName( const TQString & );
+ TQString rawName() const;
+
+ TQString key() const;
+
+ TQString toString() const;
+ bool fromString(const TQString &);
+
+#ifndef TQT_NO_STRINGLIST
+ static TQString substitute(const TQString &);
+ static TQStringList substitutes(const TQString &);
+ static TQStringList substitutions();
+ static void insertSubstitution(const TQString&, const TQString &);
+ static void insertSubstitutions(const TQString&, const TQStringList &);
+ static void removeSubstitution(const TQString &);
+#endif //TQT_NO_STRINGLIST
+ static void initialize();
+ static void cleanup();
+#ifndef TQ_WS_TQWS
+ static void cacheStatistics();
+#endif
+
+#if defined(TQ_WS_TQWS)
+ void qwsRenderToDisk(bool all=TRUE);
+#endif
+
+
+ // a copy of this lives in qtqunicodetables.cpp, as we can't include
+ // tqfont.h it in tools/. Do not modify without changing the script
+ // enum in qtqunicodetable_p.h aswell.
+ enum Script {
+ // European Alphabetic Scripts
+ Latin,
+ Greek,
+ Cyrillic,
+ Armenian,
+ Georgian,
+ Runic,
+ Ogham,
+ SpacingModifiers,
+ CombiningMarks,
+
+ // Middle Eastern Scripts
+ Hebrew,
+ Arabic,
+ Syriac,
+ Thaana,
+
+ // South and Southeast Asian Scripts
+ Devanagari,
+ Bengali,
+ Gurmukhi,
+ Gujarati,
+ Oriya,
+ Tamil,
+ Telugu,
+ Kannada,
+ Malayalam,
+ Sinhala,
+ Thai,
+ Lao,
+ Tibetan,
+ Myanmar,
+ Khmer,
+
+ // East Asian Scripts
+ Han,
+ Hiragana,
+ Katakana,
+ Hangul,
+ Bopomofo,
+ Yi,
+
+ // Additional Scripts
+ Ethiopic,
+ Cherokee,
+ CanadianAboriginal,
+ Mongolian,
+
+ // Symbols
+ CurrencySymbols,
+ LetterlikeSymbols,
+ NumberForms,
+ MathematicalOperators,
+ TechnicalSymbols,
+ GeometricSymbols,
+ MiscellaneousSymbols,
+ EnclosedAndSquare,
+ Braille,
+
+ Unicode,
+
+ // some scripts added in Unicode 3.2
+ Tagalog,
+ Hanunoo,
+ Buhid,
+ Tagbanwa,
+
+ KatakanaHalfWidth,
+
+ // from Unicode 4.0
+ Limbu,
+ TaiLe,
+
+ // End
+#if !defined(TQ_TQDOC)
+ NScripts,
+ UnknownScript = NScripts,
+
+ NoScript,
+
+ // ----------------------------------------
+ // Dear User, you can see values > NScript,
+ // but they are internal - do not touch.
+
+ Han_Japanese,
+ Han_SimplifiedChinese,
+ Han_TraditionalChinese,
+ Han_Korean,
+
+ LastPrivateScript
+#endif
+ };
+
+ TQString defaultFamily() const;
+ TQString lastResortFamily() const;
+ TQString lastResortFont() const;
+
+#ifndef TQT_NO_COMPAT
+
+ static TQFont defaultFont();
+ static void setDefaultFont( const TQFont & );
+
+#endif // TQT_NO_COMPAT
+
+ TQFont resolve( const TQFont & ) const;
+
+protected:
+ // why protected?
+ bool dirty() const;
+ int deciPointSize() const;
+
+private:
+ TQFont( TQFontPrivate *, TQPaintDevice *pd );
+
+ void detach();
+
+#if defined(TQ_WS_MAC)
+ void macSetFont(TQPaintDevice *);
+#elif defined(TQ_WS_X11)
+ void x11SetScreen( int screen = -1 );
+ int x11Screen() const;
+#endif
+
+ friend class TQFontMetrics;
+ friend class TQFontInfo;
+ friend class TQPainter;
+ friend class TQPSPrinterFont;
+ friend class TQApplication;
+ friend class TQWidget;
+ friend class TQTextFormatCollection;
+ friend class TQTextLayout;
+ friend class TQTextItem;
+ friend class TQGLContext;
+#if defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)
+ friend TQt::HANDLE qt_xft_handle(const TQFont &font);
+#endif
+#ifndef TQT_NO_DATASTREAM
+ friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQFont & );
+ friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQFont & );
+#endif
+
+ TQFontPrivate *d;
+};
+
+
+inline bool TQFont::bold() const
+{ return weight() > Normal; }
+
+
+inline void TQFont::setBold( bool enable )
+{ setWeight( enable ? Bold : Normal ); }
+
+
+
+
+/*****************************************************************************
+ TQFont stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQFont & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQFont & );
+#endif
+
+#endif // USE_QT4
+
+#endif // TQFONT_H
diff --git a/tqtinterface/qt4/src/kernel/tqfont_x11.cpp b/tqtinterface/qt4/src/kernel/tqfont_x11.cpp
new file mode 100644
index 0000000..84ea2d6
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfont_x11.cpp
@@ -0,0 +1,747 @@
+/****************************************************************************
+**
+** Implementation of TQFont, TQFontMetrics and TQFontInfo classes for X11
+**
+** Created : 940515
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#define TQT_FATAL_ASSERT
+
+// REVISED: brad
+
+#include "tqplatformdefs.h"
+
+#include "tqfont.h"
+#include "tqapplication.h"
+#include "tqcleanuphandler.h"
+#include "tqfontinfo.h"
+#include "tqfontdatabase.h"
+#include "tqfontmetrics.h"
+#include "tqpaintdevice.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqtextcodec.h"
+
+#include <private/tqfontcodecs_p.h>
+#include <private/tqunicodetables_p.h>
+#include "tqfontdata_p.h"
+#include "tqfontengine_p.h"
+#include "tqtextengine_p.h"
+
+#include "tqt_x11_p.h"
+
+#include <time.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#define TQFONTLOADER_DEBUG
+#define TQFONTLOADER_DEBUG_VERBOSE
+
+#ifdef USE_QT4
+
+TQFont::Script TQFontPrivate::defaultScript = TQFont::UnknownScript;
+int TQFontPrivate::defaultEncodingID = -1;
+TQ_EXPORT bool qt_has_xft = FALSE;
+
+#else // USE_QT4
+
+TQ_EXPORT bool qt_has_xft = FALSE;
+
+#ifndef TQT_NO_XFTFREETYPE
+TQt::HANDLE qt_xft_handle(const TQFont &font)
+{
+ TQFontEngine *engine = font.d->engineForScript( TQFontPrivate::defaultScript );
+ if (!engine->type() == TQFontEngine::Xft)
+ return 0;
+ return (long)static_cast<TQFontEngineXft *>(engine)->font();
+}
+#endif
+
+double qt_pixelSize(double pointSize, TQPaintDevice *painttqdevice, int scr)
+{
+ if (pointSize < 0) return -1.;
+
+ double result = pointSize;
+ if (painttqdevice && TQPaintDeviceMetrics( painttqdevice ).logicalDpiY() != 75)
+ result *= TQPaintDeviceMetrics( painttqdevice ).logicalDpiY() / 72.;
+ else if (TQPaintDevice::x11AppDpiY( scr ) != 75)
+ result *= TQPaintDevice::x11AppDpiY( scr ) / 72.;
+
+ return result;
+}
+
+double qt_pointSize(double pixelSize, TQPaintDevice *painttqdevice, int scr)
+{
+ if (pixelSize < 0) return -1.;
+
+ double result = pixelSize;
+ if ( painttqdevice && TQPaintDeviceMetrics( painttqdevice ).logicalDpiY() != 75)
+ result *= 72. / TQPaintDeviceMetrics( painttqdevice ).logicalDpiY();
+ else if (TQPaintDevice::x11AppDpiY(scr) != 75)
+ result *= 72. / TQPaintDevice::x11AppDpiY( scr );
+
+ return result;
+}
+
+static inline double pixelSize( const TQFontDef &request, TQPaintDevice *painttqdevice,
+ int scr )
+{
+ return ((request.pointSize != -1) ?
+ qt_pixelSize(request.pointSize / 10., painttqdevice, scr) :
+ (double)request.pixelSize);
+}
+
+static inline double pointSize( const TQFontDef &request, TQPaintDevice *painttqdevice,
+ int scr )
+{
+ return ((request.pixelSize != -1) ?
+ qt_pointSize(request.pixelSize, painttqdevice, scr) * 10.:
+ (double)request.pointSize);
+}
+
+
+/*
+ Removes wildcards from an XLFD.
+
+ Returns \a xlfd with all wildcards removed if a match for \a xlfd is
+ found, otherwise it returns \a xlfd.
+*/
+static TQCString qt_fixXLFD( const TQCString &xlfd )
+{
+ TQCString ret = xlfd;
+ int count = 0;
+ char **fontNames =
+ XListFonts( TQPaintDevice::x11AppDisplay(), xlfd, 32768, &count );
+ if ( count > 0 )
+ ret = fontNames[0];
+ XFreeFontNames( fontNames );
+ return ret ;
+}
+
+typedef TQMap<TQFont::Script,TQString> FallbackMap;
+static FallbackMap *fallbackMap = 0;
+static TQSingleCleanupHandler<FallbackMap> qt_fallback_font_family_cleanup;
+
+static void ensure_fallback_map()
+{
+ if ( fallbackMap ) return;
+ fallbackMap = new FallbackMap;
+ qt_fallback_font_family_cleanup.set( &fallbackMap );
+}
+
+// Returns the user-configured fallback family for the specified script.
+TQString qt_fallback_font_family( TQFont::Script script )
+{
+ TQString ret;
+
+ if ( fallbackMap ) {
+ FallbackMap::ConstIterator it, end = fallbackMap->end();
+ it = fallbackMap->tqfind( script );
+ if ( it != end )
+ ret = it.data();
+ }
+
+ return ret;
+}
+
+// Sets the fallback family for the specified script.
+void qt_set_fallback_font_family( TQFont::Script script, const TQString &family )
+{
+ ensure_fallback_map();
+
+ if ( ! family.isEmpty() )
+ fallbackMap->insert( script, family );
+ else
+ fallbackMap->remove( script );
+}
+
+
+TQFont::Script TQFontPrivate::defaultScript = TQFont::UnknownScript;
+int TQFontPrivate::defaultEncodingID = -1;
+
+/*!
+ Internal function that initializes the font system.
+
+ \internal
+ The font cache and font dict do not alloc the keys. The key is a TQString
+ which is shared between TQFontPrivate and TQXFontName.
+*/
+void TQFont::initialize()
+{
+ // create global font cache
+ if ( ! TQFontCache::instance ) (void) new TQFontCache;
+
+#ifndef TQT_NO_CODECS
+#ifndef TQT_NO_BIG_CODECS
+ static bool codecs_once = FALSE;
+ if ( ! codecs_once ) {
+ (void) new TQFontJis0201Codec;
+ (void) new TQFontJis0208Codec;
+ (void) new TQFontKsc5601Codec;
+ (void) new TQFontGb2312Codec;
+ (void) new TQFontGbkCodec;
+ (void) new TQFontGb18030_0Codec;
+ (void) new TQFontBig5Codec;
+ (void) new TQFontBig5hkscsCodec;
+ (void) new TQFontLaoCodec;
+ codecs_once = TRUE;
+ }
+#endif // TQT_NO_BIG_CODECS
+#endif // TQT_NO_CODECS
+
+ extern int qt_encoding_id_for_mib( int mib ); // from qfontdatabase_x11.cpp
+ TQTextCodec *codec = TQTextCodec::codecForLocale();
+ // determine the default encoding id using the locale, otherwise
+ // fallback to latin1 ( mib == 4 )
+ int mib = codec ? codec->mibEnum() : 4;
+
+ // for asian locales, use the mib for the font codec instead of the locale codec
+ switch (mib) {
+ case 38: // eucKR
+ mib = 36;
+ break;
+
+ case 2025: // GB2312
+ mib = 57;
+ break;
+
+ case 113: // GBK
+ mib = -113;
+ break;
+
+ case 114: // GB18030
+ mib = -114;
+ break;
+
+ case 2026: // Big5
+ mib = -2026;
+ break;
+
+ case 2101: // Big5-HKSCS
+ mib = -2101;
+ break;
+
+ case 16: // JIS7
+ mib = 15;
+ break;
+
+ case 17: // SJIS
+ case 18: // eucJP
+ mib = 63;
+ break;
+ }
+
+ // get the default encoding id for the locale encoding...
+ TQFontPrivate::defaultEncodingID = qt_encoding_id_for_mib( mib );
+
+ // get some sample text based on the users locale. we use this to determine the
+ // default script for the font system
+ TQCString oldlctime = setlocale(LC_TIME, 0);
+ TQCString lctime = setlocale(LC_TIME, "");
+
+ time_t ttmp = time(0);
+ struct tm *tt = 0;
+ char samp[64];
+ TQString sample;
+
+ if ( ttmp != -1 ) {
+#if defined(TQT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant versions of localtime() where available
+ tm res;
+ tt = localtime_r( &ttmp, &res );
+#else
+ tt = localtime( &ttmp );
+#endif // TQT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
+
+ if ( tt != 0 && strftime( samp, 64, "%A%B", tt ) > 0 )
+ if ( codec )
+ sample = codec->toUnicode( samp );
+ }
+
+ if ( ! sample.isNull() && ! sample.isEmpty() ) {
+ TQFont::Script cs = TQFont::NoScript, tmp;
+ const TQChar *uc = sample.tqunicode();
+ TQFontPrivate *priv = new TQFontPrivate;
+
+ for ( uint i = 0; i < sample.length(); i++ ) {
+ SCRIPT_FOR_CHAR( tmp, *uc );
+ uc++;
+ if ( tmp != cs && tmp != TQFont::UnknownScript ) {
+ cs = tmp;
+ break;
+ }
+ }
+ delete priv;
+
+ if ( cs != TQFont::UnknownScript )
+ TQFontPrivate::defaultScript = cs;
+ }
+
+ setlocale( LC_TIME, oldlctime.data() );
+}
+
+/*! \internal
+
+ Internal function that cleans up the font system.
+*/
+void TQFont::cleanup()
+{
+ // delete the global font cache
+ delete TQFontCache::instance;
+}
+
+/*!
+ \internal
+ X11 Only: Returns the screen with which this font is associated.
+*/
+int TQFont::x11Screen() const
+{
+ return d->screen;
+}
+
+/*! \internal
+ X11 Only: Associate the font with the specified \a screen.
+*/
+void TQFont::x11SetScreen( int screen )
+{
+ if ( screen < 0 ) // assume default
+ screen = TQPaintDevice::x11AppScreen();
+
+ if ( screen == d->screen )
+ return; // nothing to do
+
+ detach();
+ d->screen = screen;
+}
+
+/*! \internal
+ Returns a TQFontEngine for the specified \a script that matches the
+ TQFontDef \e request member variable.
+*/
+void TQFontPrivate::load( TQFont::Script script )
+{
+ // NOTE: the X11 and Windows implementations of this function are
+ // identical... if you change one, change both.
+
+#ifdef TQT_CHECK_STATE
+ // sanity checks
+ if (!TQFontCache::instance)
+ qWarning("Must construct a TQApplication before a TQFont");
+ TQ_ASSERT( script >= 0 && script < TQFont::LastPrivateScript );
+#endif // TQT_CHECK_STATE
+
+ TQFontDef req = request;
+ req.pixelSize = tqRound(pixelSize(req, painttqdevice, screen));
+ req.pointSize = 0;
+
+ if ( ! engineData ) {
+ TQFontCache::Key key( req, TQFont::NoScript, screen, painttqdevice );
+
+ // look for the requested font in the engine data cache
+ engineData = TQFontCache::instance->tqfindEngineData( key );
+
+ if ( ! engineData ) {
+ // create a new one
+ engineData = new TQFontEngineData;
+ TQFontCache::instance->insertEngineData( key, engineData );
+ } else {
+ engineData->ref();
+ }
+ }
+
+ // the cached engineData could have already loaded the engine we want
+ if ( engineData->engines[script] ) return;
+
+ // load the font
+ TQFontEngine *engine = 0;
+ // double scale = 1.0; // ### TODO: fix the scale calculations
+
+ // list of families to try
+ TQStringList family_list;
+
+ if (!req.family.isEmpty()) {
+ family_list = TQStringList::split( ',', req.family );
+
+ // append the substitute list for each family in family_list
+ TQStringList subs_list;
+ TQStringList::ConstIterator it = family_list.begin(), end = family_list.end();
+ for ( ; it != end; ++it )
+ subs_list += TQFont::substitutes( *it );
+ family_list += subs_list;
+
+#ifndef TQT_XFT2
+ // with Xft2, we want to use fontconfig to determine better fallbacks,
+ // otherwise we might run into trouble with default fonts as "serif"
+
+ // append the default fallback font for the specified script
+ TQString fallback = qt_fallback_font_family( script );
+ if ( ! fallback.isEmpty() && ! family_list.tqcontains( fallback ) )
+ family_list << fallback;
+
+ // add the default family
+ TQString defaultFamily = TQApplication::font().family();
+ if ( ! family_list.tqcontains( defaultFamily ) )
+ family_list << defaultFamily;
+
+ // add TQFont::defaultFamily() to the list, for compatibility with
+ // previous versions
+ family_list << TQApplication::font().defaultFamily();
+#endif // TQT_XFT2
+ }
+
+ // null family means tqfind the first font matching the specified script
+ family_list << TQString::null;
+
+ TQStringList::ConstIterator it = family_list.begin(), end = family_list.end();
+ for ( ; ! engine && it != end; ++it ) {
+ req.family = *it;
+
+ engine = TQFontDatabase::tqfindFont( script, this, req );
+ if ( engine ) {
+ if ( engine->type() != TQFontEngine::Box )
+ break;
+
+ if ( ! req.family.isEmpty() )
+ engine = 0;
+
+ continue;
+ }
+ }
+
+ engine->ref();
+ engineData->engines[script] = engine;
+}
+
+/*!
+ Returns TRUE if the font attributes have been changed and the font
+ has to be (re)loaded; otherwise returns FALSE.
+*/
+bool TQFont::dirty() const
+{
+ return d->engineData == 0;
+}
+
+/*!
+ Returns the window system handle to the font, for low-level
+ access. Using this function is \e not portable.
+*/
+TQt::HANDLE TQFont::handle() const
+{
+ TQFontEngine *engine = d->engineForScript( TQFontPrivate::defaultScript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ switch ( engine->type() ) {
+ case TQFontEngine::XLFD:
+ return ((TQFontEngineXLFD *) engine)->handle();
+ case TQFontEngine::LatinXLFD:
+ return ((TQFontEngineLatinXLFD *) engine)->handle();
+
+ default: break;
+ }
+ return 0;
+}
+
+/*!
+ Returns the name of the font within the underlying window system.
+
+ On Windows, this is usually just the family name of a TrueType
+ font.
+
+ On X11, it is an XLFD (X Logical Font Description). When TQt is
+ build with Xft support on X11, the return value can be an Xft
+ pattern or an XLFD.
+
+ Using the return value of this function is usually \e not \e
+ portable.
+
+ \sa setRawName()
+*/
+TQString TQFont::rawName() const
+{
+ TQFontEngine *engine = d->engineForScript( TQFontPrivate::defaultScript );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ return TQString::tqfromLatin1( engine->name() );
+}
+
+/*!
+ Sets a font by its system specific name. The function is
+ particularly useful under X, where system font settings (for
+ example X resources) are usually available in XLFD (X Logical Font
+ Description) form only. You can pass an XLFD as \a name to this
+ function.
+
+ A font set with setRawName() is still a full-featured TQFont. It can
+ be queried (for example with italic()) or modified (for example with
+ setItalic()) and is therefore also suitable for rendering rich text.
+
+ If TQt's internal font database cannot resolve the raw name, the
+ font becomes a raw font with \a name as its family.
+
+ Note that the present implementation does not handle wildcards in
+ XLFDs well, and that font aliases (file \c fonts.alias in the font
+ directory on X11) are not supported.
+
+ \sa rawName(), setRawMode(), setFamily()
+*/
+void TQFont::setRawName( const TQString &name )
+{
+ detach();
+
+ // from qfontdatabase_x11.cpp
+ extern bool qt_fillFontDef( const TQCString &xlfd, TQFontDef *fd, int screen );
+
+ if ( ! qt_fillFontDef( qt_fixXLFD( name.latin1() ), &d->request, d->screen ) ) {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQFont::setRawName(): Invalid XLFD: \"%s\"", name.latin1());
+#endif // TQT_CHECK_STATE
+
+ setFamily( name );
+ setRawMode( TRUE );
+ } else {
+ d->tqmask = TQFontPrivate::Complete;
+ }
+}
+
+/*!
+ Returns the "last resort" font family name.
+
+ The current implementation tries a wide variety of common fonts,
+ returning the first one it tqfinds. Is is possible that no family is
+ found in which case a null string is returned.
+
+ \sa lastResortFont()
+*/
+TQString TQFont::lastResortFamily() const
+{
+ return TQString::tqfromLatin1( "Helvetica" );
+}
+
+/*!
+ Returns the family name that corresponds to the current style
+ hint.
+
+ \sa StyleHint tqstyleHint() setStyleHint()
+*/
+TQString TQFont::defaultFamily() const
+{
+ switch ( d->request.tqstyleHint ) {
+ case TQFont::Times:
+ return TQString::tqfromLatin1( "Times" );
+
+ case TQFont::Courier:
+ return TQString::tqfromLatin1( "Courier" );
+
+ case TQFont::Decorative:
+ return TQString::tqfromLatin1( "Old English" );
+
+ case TQFont::Helvetica:
+ case TQFont::System:
+ default:
+ return TQString::tqfromLatin1( "Helvetica" );
+ }
+}
+
+/*
+ Returns a last resort raw font name for the font matching algorithm.
+ This is used if even the last resort family is not available. It
+ returns \e something, almost no matter what. The current
+ implementation tries a wide variety of common fonts, returning the
+ first one it tqfinds. The implementation may change at any time.
+*/
+static const char * const tryFonts[] = {
+ "-*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-*",
+ "-*-courier-medium-r-*-*-*-120-*-*-*-*-*-*",
+ "-*-times-medium-r-*-*-*-120-*-*-*-*-*-*",
+ "-*-lucida-medium-r-*-*-*-120-*-*-*-*-*-*",
+ "-*-helvetica-*-*-*-*-*-120-*-*-*-*-*-*",
+ "-*-courier-*-*-*-*-*-120-*-*-*-*-*-*",
+ "-*-times-*-*-*-*-*-120-*-*-*-*-*-*",
+ "-*-lucida-*-*-*-*-*-120-*-*-*-*-*-*",
+ "-*-helvetica-*-*-*-*-*-*-*-*-*-*-*-*",
+ "-*-courier-*-*-*-*-*-*-*-*-*-*-*-*",
+ "-*-times-*-*-*-*-*-*-*-*-*-*-*-*",
+ "-*-lucida-*-*-*-*-*-*-*-*-*-*-*-*",
+ "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-*",
+ "6x13",
+ "7x13",
+ "8x13",
+ "9x15",
+ "fixed",
+ 0
+};
+
+// Returns TRUE if the font exists, FALSE otherwise
+static bool fontExists( const TQString &fontName )
+{
+ int count;
+ char **fontNames = XListFonts( TQPaintDevice::x11AppDisplay(),
+ (char*)fontName.latin1(), 32768, &count );
+ if ( fontNames ) XFreeFontNames( fontNames );
+
+ return count != 0;
+}
+
+/*!
+ Returns a "last resort" font name for the font matching algorithm.
+ This is used if the last resort family is not available. It will
+ always return a name, if necessary returning something like
+ "fixed" or "system".
+
+ The current implementation tries a wide variety of common fonts,
+ returning the first one it tqfinds. The implementation may change
+ at any time, but this function will always return a string
+ containing something.
+
+ It is theoretically possible that there really isn't a
+ lastResortFont() in which case TQt will abort with an error
+ message. We have not been able to identify a case where this
+ happens. Please \link bughowto.html report it as a bug\endlink if
+ it does, preferably with a list of the fonts you have installed.
+
+ \sa lastResortFamily() rawName()
+*/
+TQString TQFont::lastResortFont() const
+{
+ static TQString last;
+
+ // already found
+ if ( ! last.isNull() )
+ return last;
+
+ int i = 0;
+ const char* f;
+
+ while ( ( f = tryFonts[i] ) ) {
+ last = TQString::tqfromLatin1( f );
+
+ if ( fontExists( last ) )
+ return last;
+
+ i++;
+ }
+
+#if defined(CHECK_NULL)
+ qFatal( "TQFontPrivate::lastResortFont: Cannot find any reasonable font" );
+#endif
+
+ return last;
+}
+
+
+
+
+// **********************************************************************
+// TQFontMetrics member methods
+// **********************************************************************
+
+int TQFontMetrics::width( TQChar ch ) const
+{
+ unsigned short uc = ch.tqunicode();
+ if ( uc < TQFontEngineData::widthCacheSize &&
+ d->engineData && d->engineData->widthCache[ uc ] )
+ return d->engineData->widthCache[ uc ];
+
+ if ( ::category( ch ) == TQChar::Mark_NonSpacing || qIsZeroWidthChar(ch.tqunicode()))
+ return 0;
+
+ TQFont::Script script;
+ SCRIPT_FOR_CHAR( script, ch );
+
+ TQFontEngine *engine = d->engineForScript( script );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ glyph_t glyphs[8];
+ advance_t advances[8];
+ int nglyphs = 7;
+ engine->stringToCMap( &ch, 1, glyphs, advances, &nglyphs, FALSE );
+
+ // ### can nglyphs != 1 happen at all? Not currently I think
+ if ( uc < TQFontEngineData::widthCacheSize && advances[0] > 0 && advances[0] < 0x100 )
+ d->engineData->widthCache[ uc ] = advances[0];
+
+ return advances[0];
+}
+
+
+int TQFontMetrics::charWidth( const TQString &str, int pos ) const
+{
+ if ( pos < 0 || pos > (int)str.length() )
+ return 0;
+
+ const TQChar &ch = str.tqunicode()[ pos ];
+ if ( ch.tqunicode() < TQFontEngineData::widthCacheSize &&
+ d->engineData && d->engineData->widthCache[ ch.tqunicode() ] )
+ return d->engineData->widthCache[ ch.tqunicode() ];
+
+ TQFont::Script script;
+ SCRIPT_FOR_CHAR( script, ch );
+
+ int width;
+
+ if ( script >= TQFont::Arabic && script <= TQFont::Khmer ) {
+ // complex script shaping. Have to do some hard work
+ int from = TQMAX( 0, pos - 8 );
+ int to = TQMIN( (int)str.length(), pos + 8 );
+ TQConstString cstr( str.tqunicode()+from, to-from);
+ TQTextEngine tqlayout( cstr.string(), d );
+ tqlayout.itemize( TQTextEngine::WidthOnly );
+ width = tqlayout.width( pos-from, 1 );
+ } else if ( ::category( ch ) == TQChar::Mark_NonSpacing || qIsZeroWidthChar(ch.tqunicode())) {
+ width = 0;
+ } else {
+ TQFontEngine *engine = d->engineForScript( script );
+#ifdef TQT_CHECK_STATE
+ TQ_ASSERT( engine != 0 );
+#endif // TQT_CHECK_STATE
+
+ glyph_t glyphs[8];
+ advance_t advances[8];
+ int nglyphs = 7;
+ engine->stringToCMap( &ch, 1, glyphs, advances, &nglyphs, FALSE );
+ width = advances[0];
+ }
+ if ( ch.tqunicode() < TQFontEngineData::widthCacheSize && width > 0 && width < 0x100 )
+ d->engineData->widthCache[ ch.tqunicode() ] = width;
+ return width;
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqfontdata_p.h b/tqtinterface/qt4/src/kernel/tqfontdata_p.h
new file mode 100644
index 0000000..b6d7a54
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfontdata_p.h
@@ -0,0 +1,278 @@
+/****************************************************************************
+**
+** Definition of internal TQFontData struct
+**
+** Created : 941229
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFONTDATA_P_H
+#define TQFONTDATA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#include "tqobject.h"
+#include "tqfont.h"
+#include "tqpaintdevicemetrics.h"
+
+// forwards
+class TQFontEngine;
+class TQPaintDevice;
+
+
+struct TQFontDef
+{
+ inline TQFontDef()
+ : pointSize( -1 ), pixelSize( -1 ),
+ tqstyleHint( TQFont::AnyStyle ), styleStrategy( TQFont::PreferDefault ),
+ weight( 50 ), italic( FALSE ), fixedPitch( FALSE ), stretch( 100 ),
+ ignorePitch(TRUE)
+#ifdef TQ_WS_MAC
+ ,fixedPitchComputed(FALSE)
+#endif
+ {
+ }
+
+ TQString family;
+
+#ifdef TQ_WS_X11
+ TQString addStyle;
+#endif // TQ_WS_X11
+
+ int pointSize;
+ int pixelSize;
+
+ uint tqstyleHint : 8;
+ uint styleStrategy : 16;
+
+ uint weight : 7; // 0-99
+ uint italic : 1;
+ uint fixedPitch : 1;
+ uint stretch : 12; // 0-400
+
+ uint ignorePitch : 1;
+ uint fixedPitchComputed : 1; // for Mac OS X only
+ uint reserved : 14; // for future extensions
+
+ bool operator==( const TQFontDef &other ) const;
+ inline bool operator<( const TQFontDef &other ) const
+ {
+ if ( pixelSize != other.pixelSize ) return pixelSize < other.pixelSize;
+ if ( weight != other.weight ) return weight < other.weight;
+ if ( italic != other.italic ) return italic < other.italic;
+ if ( stretch != other.stretch ) return stretch < other.stretch;
+ if ( tqstyleHint != other.tqstyleHint ) return tqstyleHint < other.tqstyleHint;
+ if ( styleStrategy != other.styleStrategy ) return styleStrategy < other.styleStrategy;
+ if ( family != other.family ) return family < other.family;
+
+#ifdef TQ_WS_X11
+ if ( addStyle != other.addStyle ) return addStyle < other.addStyle;
+#endif // TQ_WS_X11
+
+ return FALSE;
+ }
+};
+
+class TQFontEngineData : public TQShared
+{
+public:
+ TQFontEngineData();
+ ~TQFontEngineData();
+
+ uint lineWidth;
+
+#if defined(TQ_WS_X11) || defined(TQ_WS_WIN)
+ TQFontEngine *engines[TQFont::LastPrivateScript];
+#else
+ TQFontEngine *engine;
+#endif // TQ_WS_X11 || TQ_WS_WIN
+#ifndef TQ_WS_MAC
+ enum { widthCacheSize = 0x500 };
+ uchar widthCache[widthCacheSize];
+#endif
+};
+
+
+class TQFontPrivate : public TQShared
+{
+public:
+ static TQFont::Script defaultScript;
+#ifdef TQ_WS_X11
+ static int defaultEncodingID;
+#endif // TQ_WS_X11
+
+ TQFontPrivate();
+ TQFontPrivate( const TQFontPrivate &other );
+ ~TQFontPrivate();
+
+ void load( TQFont::Script script );
+ TQFontEngine *engineForScript( TQFont::Script script ) const {
+ if ( script == TQFont::NoScript )
+ script = TQFontPrivate::defaultScript;
+#if defined(TQ_WS_X11) || defined(TQ_WS_WIN)
+ if ( ! engineData || ! engineData->engines[script] )
+ ((TQFontPrivate *) this)->load( script );
+ return engineData->engines[script];
+#else
+ if ( ! engineData || ! engineData->engine )
+ ((TQFontPrivate *) this)->load( script );
+ return engineData->engine;
+#endif // TQ_WS_X11 || TQ_WS_WIN
+ }
+
+ TQFontDef request;
+ TQFontEngineData *engineData;
+ TQPaintDevice *painttqdevice;
+ int screen;
+
+ uint rawMode : 1;
+ uint underline : 1;
+ uint overline : 1;
+ uint strikeOut : 1;
+
+ enum {
+ Family = 0x0001,
+ Size = 0x0002,
+ StyleHint = 0x0004,
+ StyleStrategy = 0x0008,
+ Weight = 0x0010,
+ Italic = 0x0020,
+ Underline = 0x0040,
+ Overline = 0x0080,
+ StrikeOut = 0x0100,
+ FixedPitch = 0x0200,
+ Stretch = 0x0400,
+ Complete = 0x07ff
+ };
+
+ uint tqmask;
+
+ void resolve( const TQFontPrivate *other );
+};
+
+
+class TQFontCache : public TQObject
+{
+public:
+ static TQFontCache *instance;
+
+ TQFontCache();
+ ~TQFontCache();
+
+#ifdef TQ_WS_TQWS
+ void clear();
+#endif
+ // universal key structure. TQFontEngineDatas and TQFontEngines are cached using
+ // the same keys
+ struct Key {
+ Key() : script(0), screen( 0 ), dpi(0) { }
+ Key( const TQFontDef &d, TQFont::Script c, int s, TQPaintDevice *pdev )
+ : script(c), screen(s) {
+ def = d;
+#ifdef TQ_WS_X11
+ dpi = pdev ? TQPaintDeviceMetrics(pdev).logicalDpiY() : 0;
+#else
+ TQ_UNUSED(pdev);
+ dpi = 0;
+#endif
+ }
+
+ TQFontDef def;
+ int script;
+ int screen;
+ int dpi;
+
+ inline bool operator<( const Key &other ) const
+ {
+ if ( script != other.script ) return script < other.script;
+ if ( screen != other.screen ) return screen < other.screen;
+ if ( dpi != other.dpi ) return dpi < other.dpi;
+ return def < other.def;
+ }
+ inline bool operator==( const Key &other ) const
+ { return def == other.def && script == other.script &&
+ screen == other.screen && dpi == other.dpi; }
+ };
+
+ // TQFontEngineData cache
+ typedef TQMap<Key,TQFontEngineData*> EngineDataCache;
+ EngineDataCache engineDataCache;
+
+ TQFontEngineData *tqfindEngineData( const Key &key ) const;
+ void insertEngineData( const Key &key, TQFontEngineData *engineData );
+
+ // TQFontEngine cache
+ struct Engine {
+ Engine() : data( 0 ), timestamp( 0 ), hits( 0 ) { }
+ Engine( TQFontEngine *d ) : data( d ), timestamp( 0 ), hits( 0 ) { }
+
+ TQFontEngine *data;
+ uint timestamp;
+ uint hits;
+ };
+
+ typedef TQMap<Key,Engine> EngineCache;
+ EngineCache engineCache;
+
+ TQFontEngine *tqfindEngine( const Key &key );
+ void insertEngine( const Key &key, TQFontEngine *engine );
+
+#if defined(TQ_WS_WIN) || defined(TQ_WS_TQWS)
+ void cleanupPrinterFonts();
+#endif
+
+ private:
+ void increaseCost( uint cost );
+ void decreaseCost( uint cost );
+ void timerEvent( TQTimerEvent *event );
+
+ static const uint min_cost;
+ uint total_cost, max_cost;
+ uint current_timestamp;
+ bool fast;
+ int timer_id;
+};
+
+#endif // TQFONTDATA_P_H
diff --git a/tqtinterface/qt4/src/kernel/tqfontdatabase.cpp b/tqtinterface/qt4/src/kernel/tqfontdatabase.cpp
new file mode 100644
index 0000000..f79c14b
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfontdatabase.cpp
@@ -0,0 +1,2505 @@
+/****************************************************************************
+**
+** Implementation of font database class.
+**
+** Created : 990603
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <tqtglobaldefines.h>
+// Nasty, nasty horrid HACK to get access to QFontDatabase's private members
+// This is TERRIBLE and I wish there was a way around it
+// This is a good example of the new, broken & irritating Qt4 API,
+// and the corresponding loss in functionality versus Qt3.
+// See also tqrect.cpp
+#define private protected
+#include <Qt/qfontdatabase.h>
+#undef private
+
+#include "tqfontdatabase.h"
+
+#ifndef TQT_NO_FONTDATABASE
+
+#include <tqtl.h>
+#include <tqapplication.h>
+
+#include <private/tqunicodetables_p.h>
+#include "tqfontengine_p.h"
+
+#include <tqcleanuphandler.h>
+
+#ifdef TQ_WS_X11
+#include <locale.h>
+#endif
+#include <stdlib.h>
+
+//#define TQFONTDATABASE_DEBUG
+#ifdef TQFONTDATABASE_DEBUG
+# define FD_DEBUG qDebug
+#else
+# define FD_DEBUG if (FALSE) qDebug
+#endif
+
+//#define FONT_MATCH_DEBUG
+#ifdef FONT_MATCH_DEBUG
+# define FM_DEBUG qDebug
+#else
+# define FM_DEBUG if (FALSE) qDebug
+#endif
+
+#if defined(TQ_CC_MSVC) && !defined(TQ_CC_MSVC_NET)
+# define for if(0){}else for
+#endif
+
+#ifdef USE_QT4
+
+void TQFontDatabase::tqparseFontName(const QString &name, QString &foundry, QString &family) {
+ parseFontName(name, foundry, family);
+}
+
+#else // USE_QT4
+
+static int ucstricmp( const TQString &as, const TQString &bs )
+{
+ const TQChar *a = as.tqunicode();
+ const TQChar *b = bs.tqunicode();
+ if ( a == b )
+ return 0;
+ if ( a == 0 )
+ return 1;
+ if ( b == 0 )
+ return -1;
+ int l=TQMIN(as.length(),bs.length());
+ while ( l-- && ::lower( *a ) == ::lower( *b ) )
+ a++,b++;
+ if ( l==-1 )
+ return ( as.length()-bs.length() );
+ return ::lower( *a ).tqunicode() - ::lower( *b ).tqunicode();
+}
+
+static int getFontWeight( const TQString &weightString )
+{
+ TQString s = weightString.lower();
+
+ // Test in decreasing order of commonness
+ if (s == "medium" ||
+ s == "normal")
+ return TQFont::Normal;
+ if (s == "bold")
+ return TQFont::Bold;
+ if (s == "demibold" || s == "demi bold")
+ return TQFont::DemiBold;
+ if (s == "black")
+ return TQFont::Black;
+ if (s == "light")
+ return TQFont::Light;
+
+ if (s.tqcontains("bold")) {
+ if (s.tqcontains("demi"))
+ return (int) TQFont::DemiBold;
+ return (int) TQFont::Bold;
+ }
+
+ if (s.tqcontains("light"))
+ return (int) TQFont::Light;
+
+ if (s.tqcontains("black"))
+ return (int) TQFont::Black;
+
+ return (int) TQFont::Normal;
+}
+
+#ifdef TQ_WS_X11
+struct TQtFontEncoding
+{
+ signed int encoding : 16;
+
+ uint xpoint : 16;
+ uint xres : 8;
+ uint yres : 8;
+ uint avgwidth : 16;
+ uchar pitch : 8;
+};
+#endif // TQ_WS_X11
+
+struct TQtFontSize
+{
+ unsigned short pixelSize;
+
+#ifdef TQ_WS_X11
+ int count;
+ TQtFontEncoding *encodings;
+ TQtFontEncoding *encodingID( int id, uint xpoint = 0, uint xres = 0,
+ uint yres = 0, uint avgwidth = 0, bool add = FALSE);
+#endif // TQ_WS_X11
+};
+
+
+#ifdef TQ_WS_X11
+TQtFontEncoding *TQtFontSize::encodingID( int id, uint xpoint, uint xres,
+ uint yres, uint avgwidth, bool add )
+{
+ // we don't match using the xpoint, xres and yres parameters, only the id
+ for ( int i = 0; i < count; ++i ) {
+ if ( encodings[i].encoding == id )
+ return encodings + i;
+ }
+
+ if ( !add ) return 0;
+
+ if ( !(count % 4) )
+ encodings = ( TQtFontEncoding * )
+ realloc( encodings,
+ (((count+4) >> 2 ) << 2 ) * sizeof( TQtFontEncoding ) );
+ encodings[count].encoding = id;
+ encodings[count].xpoint = xpoint;
+ encodings[count].xres = xres;
+ encodings[count].yres = yres;
+ encodings[count].avgwidth = avgwidth;
+ encodings[count].pitch = '*';
+ return encodings + count++;
+}
+#endif // TQ_WS_X11
+
+struct TQtFontStyle
+{
+ struct Key {
+ Key( const TQString &styleString );
+ Key() : italic( FALSE ), oblique( FALSE ),
+ weight( TQFont::Normal ), stretch( 0 ) { }
+ Key( const Key &o ) : italic( o.italic ), oblique( o.oblique ),
+ weight( o.weight ), stretch( o.stretch ) { }
+ uint italic : 1;
+ uint oblique : 1;
+ signed int weight : 8;
+ signed int stretch : 12;
+
+ bool operator==( const Key & other ) {
+ return ( italic == other.italic &&
+ oblique == other.oblique &&
+ weight == other.weight &&
+ (stretch == 0 || other.stretch == 0 || stretch == other.stretch) );
+ }
+ bool operator!=( const Key &other ) {
+ return !operator==(other);
+ }
+ bool operator <( const Key &o ) {
+ int x = (italic << 13) + (oblique << 12) + (weight << 14) + stretch;
+ int y = (o.italic << 13) + (o.oblique << 12) + (o.weight << 14) + o.stretch;
+ return ( x < y );
+ }
+ };
+
+ TQtFontStyle( const Key &k )
+ : key( k ), bitmapScalable( FALSE ), smoothScalable( FALSE ),
+ fakeOblique( FALSE ), count( 0 ), pixelSizes( 0 )
+ {
+#if defined(TQ_WS_X11)
+ weightName = setwidthName = 0;
+#endif // TQ_WS_X11
+ }
+
+ ~TQtFontStyle() {
+#ifdef TQ_WS_X11
+ delete [] weightName;
+ delete [] setwidthName;
+ while ( count-- )
+ free(pixelSizes[count].encodings);
+#endif
+ free( pixelSizes );
+ }
+
+ Key key;
+ bool bitmapScalable : 1;
+ bool smoothScalable : 1;
+ bool fakeOblique : 1;
+ int count : 29;
+ TQtFontSize *pixelSizes;
+
+#ifdef TQ_WS_X11
+ const char *weightName;
+ const char *setwidthName;
+#endif // TQ_WS_X11
+
+ TQtFontSize *pixelSize( unsigned short size, bool = FALSE );
+};
+
+TQtFontStyle::Key::Key( const TQString &styleString )
+ : italic( FALSE ), oblique( FALSE ), weight( TQFont::Normal ), stretch( 0 )
+{
+ weight = getFontWeight( styleString );
+
+ if ( styleString.tqcontains( "Italic" ) )
+ italic = TRUE;
+ else if ( styleString.tqcontains( "Oblique" ) )
+ oblique = TRUE;
+}
+
+TQtFontSize *TQtFontStyle::pixelSize( unsigned short size, bool add )
+{
+ for ( int i = 0; i < count; i++ ) {
+ if ( pixelSizes[i].pixelSize == size )
+ return pixelSizes + i;
+ }
+ if ( !add )
+ return 0;
+
+ if ( !(count % 8) )
+ pixelSizes = (TQtFontSize *)
+ realloc( pixelSizes,
+ (((count+8) >> 3 ) << 3) * sizeof(TQtFontSize) );
+ pixelSizes[count].pixelSize = size;
+#ifdef TQ_WS_X11
+ pixelSizes[count].count = 0;
+ pixelSizes[count].encodings = 0;
+#endif
+ return pixelSizes + (count++);
+}
+
+struct TQtFontFoundry
+{
+ TQtFontFoundry( const TQString &n ) : name( n ), count( 0 ), styles( 0 ) {}
+ ~TQtFontFoundry() {
+ while ( count-- )
+ delete styles[count];
+ free( styles );
+ }
+
+ TQString name;
+
+ int count;
+ TQtFontStyle **styles;
+ TQtFontStyle *style( const TQtFontStyle::Key &, bool = FALSE );
+};
+
+TQtFontStyle *TQtFontFoundry::style( const TQtFontStyle::Key &key, bool create )
+{
+ int pos = 0;
+ if ( count ) {
+ int low = 0;
+ int high = count;
+ pos = count / 2;
+ while ( high > low ) {
+ if ( styles[pos]->key == key )
+ return styles[pos];
+ if ( styles[pos]->key < key )
+ low = pos + 1;
+ else
+ high = pos;
+ pos = (high + low) / 2;
+ };
+ pos = low;
+ }
+ if ( !create )
+ return 0;
+
+// qDebug("adding key (weight=%d, italic=%d, oblique=%d stretch=%d) at %d", key.weight, key.italic, key.oblique, key.stretch, pos );
+ if ( !(count % 8) )
+ styles = (TQtFontStyle **)
+ realloc( styles, (((count+8) >> 3 ) << 3) * sizeof( TQtFontStyle * ) );
+
+ memmove( styles + pos + 1, styles + pos, (count-pos)*sizeof(TQtFontStyle *) );
+ styles[pos] = new TQtFontStyle( key );
+ count++;
+ return styles[pos];
+}
+
+
+struct TQtFontFamily
+{
+ enum ScriptqStatus { Unknown = 0, Supported = 1,
+ UnSupported_Xft= 2, UnSupported_Xlfd = 4, UnSupported = 6 };
+
+ TQtFontFamily(const TQString &n )
+ :
+#ifdef TQ_WS_X11
+ fixedPitch( TRUE ), hasXft( FALSE ), xftScriptCheck( FALSE ), xlfdLoaded( FALSE ), synthetic(FALSE),
+#else
+ fixedPitch( FALSE ),
+#endif
+#ifdef TQ_WS_WIN
+ scriptCheck( FALSE ),
+#endif
+#if defined(TQ_OS_MAC) && !defined(TQWS)
+ fixedPitchComputed(FALSE),
+#endif
+ fullyLoaded( FALSE ),
+ name( n ), count( 0 ), foundries( 0 ) {
+ memset( scripts, 0, sizeof( scripts ) );
+ }
+ ~TQtFontFamily() {
+ while ( count-- )
+ delete foundries[count];
+ free( foundries );
+ }
+
+ bool fixedPitch : 1;
+#ifdef TQ_WS_X11
+ bool hasXft : 1;
+ bool xftScriptCheck : 1;
+ bool xlfdLoaded : 1;
+ bool synthetic : 1;
+#endif
+#ifdef TQ_WS_WIN
+ bool scriptCheck : 1;
+#endif
+#if defined(TQ_OS_MAC) && !defined(TQWS)
+ bool fixedPitchComputed : 1;
+#endif
+ bool fullyLoaded : 1;
+ TQString name;
+ TQString rawName;
+#ifdef TQ_WS_X11
+ TQCString fontFilename;
+ int fontFileIndex;
+#endif
+#ifdef TQ_WS_MAC
+ FMFontFamily macFamily;
+#endif
+#ifdef TQ_WS_WIN
+ TQString english_name;
+#endif
+ int count;
+ TQtFontFoundry **foundries;
+
+ unsigned char scripts[TQFont::LastPrivateScript];
+
+ TQtFontFoundry *foundry( const TQString &f, bool = FALSE );
+};
+
+TQtFontFoundry *TQtFontFamily::foundry( const TQString &f, bool create )
+{
+ if ( f.isNull() && count == 1 )
+ return foundries[0];
+
+ for ( int i = 0; i < count; i++ ) {
+ if ( ucstricmp( foundries[i]->name, f ) == 0 )
+ return foundries[i];
+ }
+ if ( !create )
+ return 0;
+
+ if ( !(count % 8) )
+ foundries = (TQtFontFoundry **)
+ realloc( foundries,
+ (((count+8) >> 3 ) << 3) * sizeof( TQtFontFoundry * ) );
+
+ foundries[count] = new TQtFontFoundry( f );
+ return foundries[count++];
+}
+
+class TQFontDatabasePrivate {
+public:
+ TQFontDatabasePrivate() : count( 0 ), families( 0 ) { }
+ ~TQFontDatabasePrivate() {
+ while ( count-- )
+ delete families[count];
+ free( families );
+ }
+ TQtFontFamily *family( const TQString &f, bool = FALSE );
+
+ int count;
+ TQtFontFamily **families;
+};
+
+TQtFontFamily *TQFontDatabasePrivate::family( const TQString &f, bool create )
+{
+ int low = 0;
+ int high = count;
+ int pos = count / 2;
+ int res = 1;
+ if ( count ) {
+ while ( (res = ucstricmp( families[pos]->name, f )) && pos != low ) {
+ if ( res > 0 )
+ high = pos;
+ else
+ low = pos;
+ pos = (high + low) / 2;
+ };
+ if ( !res )
+ return families[pos];
+ }
+ if ( !create )
+ return 0;
+
+ if ( res < 0 )
+ pos++;
+
+ // qDebug("adding family %s at %d total=%d", f.latin1(), pos, count);
+ if ( !(count % 8) )
+ families = (TQtFontFamily **)
+ realloc( families,
+ (((count+8) >> 3 ) << 3) * sizeof( TQtFontFamily * ) );
+
+ memmove( families + pos + 1, families + pos, (count-pos)*sizeof(TQtFontFamily *) );
+ families[pos] = new TQtFontFamily( f );
+ count++;
+ return families[pos];
+}
+
+
+
+
+#if defined(TQ_WS_X11) || defined(TQ_WS_WIN)
+static const unsigned short sample_chars[TQFont::LastPrivateScript][14] =
+{
+ // European Alphabetic Scripts
+ // Latin,
+ { 0x0041, 0x0 },
+ // Greek,
+ { 0x0391, 0x0 },
+ // Cyrillic,
+ { 0x0410, 0x0 },
+ // Armenian,
+ { 0x0540, 0x0 },
+ // Georgian,
+ { 0x10d0, 0x0 },
+ // Runic,
+ { 0x16a0, 0x0 },
+ // Ogham,
+ { 0x1680, 0x0 },
+ // SpacingModifiers,
+ { 0x02c6, 0x0 },
+ // CombiningMarks,
+ { 0x0300, 0x0 },
+
+ // Middle Eastern Scripts
+ // Hebrew,
+ { 0x05d0, 0x0 },
+ // Arabic,
+ { 0x0630, 0x0 },
+ // Syriac,
+ { 0x0710, 0x0 },
+ // Thaana,
+ { 0x0780, 0x0 },
+
+ // South and Southeast Asian Scripts
+ // Devanagari,
+ { 0x0910, 0x0 },
+ // Bengali,
+ { 0x0990, 0x0 },
+ // Gurmukhi,
+ { 0x0a10, 0x0 },
+ // Gujarati,
+ { 0x0a90, 0x0 },
+ // Oriya,
+ { 0x0b10, 0x0 },
+ // Tamil,
+ { 0x0b90, 0x0 },
+ // Telugu,
+ { 0x0c10, 0x0 },
+ // Kannada,
+ { 0x0c90, 0x0 },
+ // Malayalam,
+ { 0x0d10, 0x0 },
+ // Sinhala,
+ { 0x0d90, 0x0 },
+ // Thai,
+ { 0x0e10, 0x0 },
+ // Lao,
+ { 0x0e81, 0x0 },
+ // Tibetan,
+ { 0x0f00, 0x0 },
+ // Myanmar,
+ { 0x1000, 0x0 },
+ // Khmer,
+ { 0x1780, 0x0 },
+
+ // East Asian Scripts
+ // Han,
+ { 0x4e00, 0x0 },
+ // Hiragana,
+ { 0x3050, 0x4e00, 0x25EF, 0x3012, 0x3013, 0x30FB, 0x30FC, 0x5CE0, 0 },
+ // Katakana,
+ { 0x30b0, 0x4e00, 0x25EF, 0x3012, 0x3013, 0x30FB, 0x30FC, 0x5CE0, 0 },
+ // Hangul,
+ { 0xac00, 0x0 },
+ // Bopomofo,
+ { 0x3110, 0x0 },
+ // Yi,
+ { 0xa000, 0x0 },
+
+ // Additional Scripts
+ // Ethiopic,
+ { 0x1200, 0x0 },
+ // Cherokee,
+ { 0x13a0, 0x0 },
+ // CanadianAboriginal,
+ { 0x1410, 0x0 },
+ // Mongolian,
+ { 0x1800, 0x0 },
+
+ // Symbols
+ // CurrencySymbols,
+ { 0x20aa, 0x0 },
+ // LetterlikeSymbols,
+ { 0x2103, 0x0 },
+ // NumberForms,
+ { 0x2160, 0x0 },
+ // MathematicalOperators,
+ { 0x222b, 0x0 },
+ // TechnicalSymbols,
+ { 0x2312, 0x0 },
+ // GeometricSymbols,
+ { 0x2500, 0x0 },
+ // MiscellaneousSymbols,
+ { 0x2640, 0x2714, 0x0 },
+ // EnclosedAndSquare,
+ { 0x2460, 0x0 },
+ // Braille,
+ { 0x2800, 0x0 },
+
+ // Unicode,
+ { 0xfffd, 0x0 },
+
+ // some scripts added in Unicode 3.2
+ // Tagalog,
+ { 0x1700, 0x0 },
+ // Hanunoo,
+ { 0x1720, 0x0 },
+ // Buhid,
+ { 0x1740, 0x0 },
+ // Tagbanwa,
+ { 0x1770, 0x0 },
+
+ // KatakanaHalfWidth
+ { 0xff65, 0x0 },
+
+ // Limbu
+ { 0x1901, 0x0 },
+ // TaiLe
+ { 0x1950, 0x0 },
+
+ // NScripts
+ { 0x0000, 0x0 },
+ // NoScript
+ { 0x0000, 0x0 },
+
+ // Han_Japanese
+ { 0x4e00, 0x25EF, 0x3012, 0x3013, 0x30FB, 0x5CE0, 0 },
+ // Han_SimplifiedChinese, 0x3400 is optional
+ { 0x4e00, 0x201C, 0x3002, 0x6237, 0x9555, 0xFFE5, 0 },
+ // Han_TraditionalChinese, 0xF6B1 is optional
+ // OR Han_HongkongChinese, 0x3435, 0xE000, 0xF6B1 are optional
+ { 0x4e00, 0x201C, 0x3002, 0x6236, 0x9F98, 0xFFE5, 0 },
+ // Han_Korean
+ { 0x4e00, 0 }
+ // Taiwan would be 0x201C, 0x3002, 0x4E00, 0x9F98, 0xFFE5
+};
+
+#if defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)
+static inline bool requiresOpenType(TQFont::Script s)
+{
+ return (s >= TQFont::Syriac && s <= TQFont::Sinhala)
+ || (s >= TQFont::Myanmar && s <= TQFont::Khmer);
+}
+#endif
+
+static inline bool canRender( TQFontEngine *fe, TQFont::Script script )
+{
+ if ( !fe ) return FALSE;
+
+ bool hasChar = true;
+
+ if (!sample_chars[script][0])
+ hasChar = false;
+
+ int i = 0;
+ while (hasChar && sample_chars[script][i]){
+ TQChar sample(sample_chars[script][i]);
+ if ( !fe->canRender( &sample, 1 ) ) {
+ hasChar = false;
+#ifdef FONT_MATCH_DEBUG
+ FM_DEBUG(" font has NOT char 0x%04x", sample.tqunicode() );
+ } else {
+ FM_DEBUG(" font has char 0x%04x", sample.tqunicode() );
+#endif
+ }
+ ++i;
+ }
+#if defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)
+ if (hasChar && requiresOpenType(script)) {
+ TQOpenType *ot = fe->openType();
+ if (!ot || !ot->supportsScript(script))
+ return FALSE;
+ }
+#endif
+
+ return hasChar;
+}
+#endif // TQ_WS_X11 || TQ_WS_WIN
+
+
+static TQSingleCleanupHandler<TQFontDatabasePrivate> qfontdatabase_cleanup;
+static TQFontDatabasePrivate *db=0;
+#define SMOOTH_SCALABLE 0xffff
+
+#if defined( TQ_WS_X11 )
+# include "tqfontdatabase_x11.cpp"
+#elif defined( TQ_WS_MAC )
+# include "tqfontdatabase_mac.cpp"
+#elif defined( TQ_WS_WIN )
+# include "tqfontdatabase_win.cpp"
+#elif defined( TQ_WS_TQWS )
+# include "tqfontdatabase_qws.cpp"
+#endif
+
+static TQtFontStyle *bestStyle(TQtFontFoundry *foundry, const TQtFontStyle::Key &styleKey)
+{
+ int best = 0;
+ int dist = 0xffff;
+
+ for ( int i = 0; i < foundry->count; i++ ) {
+ TQtFontStyle *style = foundry->styles[i];
+
+ int d = TQABS( styleKey.weight - style->key.weight );
+
+ if ( styleKey.stretch != 0 && style->key.stretch != 0 ) {
+ d += TQABS( styleKey.stretch - style->key.stretch );
+ }
+
+ if ( styleKey.italic ) {
+ if ( !style->key.italic )
+ d += style->key.oblique ? 0x0001 : 0x1000;
+ } else if ( styleKey.oblique ) {
+ if (!style->key.oblique )
+ d += style->key.italic ? 0x0001 : 0x1000;
+ } else if ( style->key.italic || style->key.oblique ) {
+ d += 0x1000;
+ }
+
+ if ( d < dist ) {
+ best = i;
+ dist = d;
+ }
+ }
+
+ FM_DEBUG( " best style has distance 0x%x", dist );
+ return foundry->styles[best];
+}
+
+#if defined(TQ_WS_X11)
+static TQtFontEncoding *tqfindEncoding(TQFont::Script script, int styleStrategy,
+ TQtFontSize *size, int force_encoding_id)
+{
+ TQtFontEncoding *encoding = 0;
+
+ if (force_encoding_id >= 0) {
+ encoding = size->encodingID(force_encoding_id);
+ if (!encoding)
+ FM_DEBUG(" required encoding_id not available");
+ return encoding;
+ }
+
+ if (styleStrategy & (TQFont::OpenGLCompatible | TQFont::PreferBitmap)) {
+ FM_DEBUG(" PreferBitmap and/or OpenGL set, skipping Xft");
+ } else {
+ encoding = size->encodingID(-1); // -1 == prefer Xft
+ if (encoding) return encoding;
+ }
+
+ // Xft not available, tqfind an XLFD font, trying the default encoding first
+ encoding = size->encodingID(TQFontPrivate::defaultEncodingID);
+
+ if (!encoding || !scripts_for_xlfd_encoding[encoding->encoding][script]) {
+ // tqfind the first encoding that supports the requested script
+ encoding = 0;
+ for (int x = 0; !encoding && x < size->count; ++x) {
+ const int enc = size->encodings[x].encoding;
+ if (scripts_for_xlfd_encoding[enc][script]) {
+ encoding = size->encodings + x;
+ break;
+ }
+ }
+ }
+
+ return encoding;
+}
+#endif // TQ_WS_X11
+
+
+#if defined(TQ_WS_X11) || defined(TQ_WS_WIN)
+static
+unsigned int bestFoundry( TQFont::Script script, unsigned int score, int styleStrategy,
+ const TQtFontFamily *family, const TQString &foundry_name,
+ TQtFontStyle::Key styleKey, int pixelSize, char pitch,
+ TQtFontFoundry **best_foundry, TQtFontStyle **best_style,
+ TQtFontSize **best_size
+#ifdef TQ_WS_X11
+ , TQtFontEncoding **best_encoding, int force_encoding_id
+#endif
+ )
+{
+ TQ_UNUSED( script );
+ TQ_UNUSED( pitch );
+
+ FM_DEBUG( " REMARK: looking for best foundry for family '%s'", family->name.latin1() );
+
+ for ( int x = 0; x < family->count; ++x ) {
+ TQtFontFoundry *foundry = family->foundries[x];
+ if ( ! foundry_name.isEmpty() &&
+ ucstricmp( foundry->name, foundry_name ) != 0 )
+ continue;
+
+ FM_DEBUG( " looking for matching style in foundry '%s'",
+ foundry->name.isEmpty() ? "-- none --" : foundry->name.latin1() );
+
+ TQtFontStyle *style = bestStyle(foundry, styleKey);
+
+ if ( ! style->smoothScalable && ( styleStrategy & TQFont::ForceOutline ) ) {
+ FM_DEBUG( " ForceOutline set, but not smoothly scalable" );
+ continue;
+ }
+
+ int px = -1;
+ TQtFontSize *size = 0;
+
+ // 1. see if we have an exact matching size
+ if (! (styleStrategy & TQFont::ForceOutline)) {
+ size = style->pixelSize(pixelSize);
+ if (size) {
+ FM_DEBUG(" found exact size match (%d pixels)", size->pixelSize);
+ px = size->pixelSize;
+ }
+ }
+
+ // 2. see if we have a smoothly scalable font
+ if (! size && style->smoothScalable && ! (styleStrategy & TQFont::PreferBitmap)) {
+ size = style->pixelSize(SMOOTH_SCALABLE);
+ if (size) {
+ FM_DEBUG(" found smoothly scalable font (%d pixels)", pixelSize);
+ px = pixelSize;
+ }
+ }
+
+ // 3. see if we have a bitmap scalable font
+ if (! size && style->bitmapScalable && (styleStrategy & TQFont::PreferMatch)) {
+ size = style->pixelSize(0);
+ if (size) {
+ FM_DEBUG(" found bitmap scalable font (%d pixels)", pixelSize);
+ px = pixelSize;
+ }
+ }
+
+#ifdef TQ_WS_X11
+ TQtFontEncoding *encoding = 0;
+#endif
+
+ // 4. tqfind closest size match
+ if (! size) {
+ unsigned int distance = ~0u;
+ for (int x = 0; x < style->count; ++x) {
+#ifdef TQ_WS_X11
+ encoding =
+ tqfindEncoding(script, styleStrategy, style->pixelSizes + x, force_encoding_id);
+ if (!encoding) {
+ FM_DEBUG(" size %3d does not support the script we want",
+ style->pixelSizes[x].pixelSize);
+ continue;
+ }
+#endif
+
+ unsigned int d = TQABS(style->pixelSizes[x].pixelSize - pixelSize);
+ if (d < distance) {
+ distance = d;
+ size = style->pixelSizes + x;
+ FM_DEBUG(" best size so far: %3d (%d)", size->pixelSize, pixelSize);
+ }
+ }
+
+ if (!size) {
+ FM_DEBUG(" no size supports the script we want");
+ continue;
+ }
+
+ if (style->bitmapScalable && ! (styleStrategy & TQFont::PreferQuality) &&
+ (distance * 10 / pixelSize) >= 2) {
+ // the closest size is not close enough, go ahead and
+ // use a bitmap scaled font
+ size = style->pixelSize(0);
+ px = pixelSize;
+ } else {
+ px = size->pixelSize;
+ }
+ }
+
+#ifdef TQ_WS_X11
+ if (size) {
+ encoding = tqfindEncoding(script, styleStrategy, size, force_encoding_id);
+ if (!encoding) size = 0;
+ }
+ if ( ! encoding ) {
+ FM_DEBUG( " foundry doesn't support the script we want" );
+ continue;
+ }
+#endif // TQ_WS_X11
+
+ unsigned int this_score = 0x0000;
+ enum {
+ PitchMismatch = 0x4000,
+ StyleMismatch = 0x2000,
+ BitmapScaledPenalty = 0x1000,
+ EncodingMismatch = 0x0002,
+ XLFDPenalty = 0x0001
+ };
+
+#ifdef TQ_WS_X11
+ if ( encoding->encoding != -1 ) {
+ this_score += XLFDPenalty;
+ if ( encoding->encoding != TQFontPrivate::defaultEncodingID )
+ this_score += EncodingMismatch;
+ }
+ if (pitch != '*') {
+ if ( !( pitch == 'm' && encoding->pitch == 'c' ) && pitch != encoding->pitch )
+ this_score += PitchMismatch;
+ }
+#else
+ // ignore pitch for asian fonts, some of them misreport it, and they are all
+ // fixed pitch anyway.
+ if (pitch != '*' && (script <= TQFont::NScripts && script != TQFont::KatakanaHalfWidth
+ && (script < TQFont::Han || script > TQFont::Yi))) {
+ if ((pitch == 'm' && !family->fixedPitch)
+ || (pitch == 'p' && family->fixedPitch))
+ this_score += PitchMismatch;
+ }
+#endif
+ if ( styleKey != style->key )
+ this_score += StyleMismatch;
+ if ( !style->smoothScalable && px != size->pixelSize ) // bitmap scaled
+ this_score += BitmapScaledPenalty;
+ if (px != pixelSize) // close, but not exact, size match
+ this_score += TQABS(px - pixelSize);
+
+ if ( this_score < score ) {
+ FM_DEBUG( " found a match: score %x best score so far %x",
+ this_score, score );
+
+ score = this_score;
+ *best_foundry = foundry;
+ *best_style = style;
+ *best_size = size;
+#ifdef TQ_WS_X11
+ *best_encoding = encoding;
+#endif // TQ_WS_X11
+ } else {
+ FM_DEBUG( " score %x no better than best %x", this_score, score);
+ }
+ }
+
+ return score;
+}
+
+/*!
+ \internal
+*/
+TQFontEngine *
+TQFontDatabase::tqfindFont( TQFont::Script script, const TQFontPrivate *fp,
+ const TQFontDef &request, int force_encoding_id )
+{
+#ifndef TQ_WS_X11
+ TQ_UNUSED( force_encoding_id );
+#endif
+
+ if ( !db )
+ initializeDb();
+
+ TQFontEngine *fe = 0;
+ if ( fp ) {
+ if ( fp->rawMode ) {
+ fe = loadEngine( script, fp, request, 0, 0, 0
+#ifdef TQ_WS_X11
+ , 0, 0, FALSE
+#endif
+ );
+
+ // if we fail to load the rawmode font, use a 12pixel box engine instead
+ if (! fe) fe = new TQFontEngineBox( 12 );
+ return fe;
+ }
+
+ TQFontCache::Key key( request, script,
+#ifdef TQ_WS_WIN
+ (int)fp->painttqdevice,
+#else
+ fp->screen,
+#endif
+ fp->painttqdevice
+ );
+ fe = TQFontCache::instance->tqfindEngine( key );
+ if ( fe ) return fe;
+ }
+
+#ifdef TQ_WS_WIN
+ if (request.styleStrategy & TQFont::PreferDevice) {
+ TQFontEngine *fe = loadEngine(script, fp, request, 0, 0, 0);
+ if(fe)
+ return fe;
+ }
+#endif
+
+ TQString family_name, foundry_name;
+ TQtFontStyle::Key styleKey;
+ styleKey.italic = request.italic;
+ styleKey.weight = request.weight;
+ styleKey.stretch = request.stretch;
+ char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';
+
+ parseFontName( request.family, foundry_name, family_name );
+
+#ifdef TQ_WS_X11
+ if (script == TQFont::Han) {
+ // modify script according to locale
+ static TQFont::Script defaultHan = TQFont::UnknownScript;
+ if (defaultHan == TQFont::UnknownScript) {
+ TQCString locale = setlocale(LC_ALL, NULL);
+ if (locale.tqcontains("ko"))
+ defaultHan = TQFont::Han_Korean;
+ else if (locale.tqcontains("zh_TW") || locale.tqcontains("zh_HK"))
+ defaultHan = TQFont::Han_TraditionalChinese;
+ else if (locale.tqcontains("zh"))
+ defaultHan = TQFont::Han_SimplifiedChinese;
+ else
+ defaultHan = TQFont::Han_Japanese;
+ }
+ script = defaultHan;
+ }
+#endif
+
+ FM_DEBUG( "TQFontDatabase::tqfindFont\n"
+ " request:\n"
+ " family: %s [%s], script: %d (%s)\n"
+ " weight: %d, italic: %d\n"
+ " stretch: %d\n"
+ " pixelSize: %d\n"
+ " pitch: %c",
+ family_name.isEmpty() ? "-- first in script --" : family_name.latin1(),
+ foundry_name.isEmpty() ? "-- any --" : foundry_name.latin1(),
+ script, scriptName( script ).latin1(),
+ request.weight, request.italic, request.stretch, request.pixelSize, pitch );
+
+ bool usesFontConfig = FALSE;
+#ifdef TQT_XFT2
+ if (family_name.isEmpty()
+ || family_name == "Sans Serif"
+ || family_name == "Serif"
+ || family_name == "Monospace") {
+ fe = loadFontConfigFont(fp, request, script);
+ usesFontConfig = (fe != 0);
+ }
+ if (!fe)
+#endif
+ {
+ TQtFontFamily *best_family = 0;
+ TQtFontFoundry *best_foundry = 0;
+ TQtFontStyle *best_style = 0;
+ TQtFontSize *best_size = 0;
+#ifdef TQ_WS_X11
+ TQtFontEncoding *best_encoding = 0;
+#endif // TQ_WS_X11
+
+ unsigned int score = ~0;
+
+ load( family_name, script );
+
+ for ( int x = 0; x < db->count; ++x ) {
+ TQtFontFamily *try_family = db->families[x];
+#ifdef TQ_WS_X11
+ if (try_family->synthetic) // skip generated fontconfig fonts
+ continue;
+#endif
+
+ if ( !family_name.isEmpty() &&
+ ucstricmp( try_family->name, family_name ) != 0
+#ifdef TQ_WS_WIN
+ && ucstricmp( try_family->english_name, family_name ) != 0
+#endif
+ )
+ continue;
+
+ if ( family_name.isEmpty() )
+ load( try_family->name, script );
+
+ uint score_adjust = 0;
+ TQFont::Script override_script = script;
+ if ( ! ( try_family->scripts[script] & TQtFontFamily::Supported )
+ && script != TQFont::Unicode) {
+ // family not supported in the script we want
+#ifdef TQ_WS_X11
+ if (script >= TQFont::Han_Japanese && script <= TQFont::Han_Korean
+ && try_family->scripts[TQFont::Han] == TQtFontFamily::Supported) {
+ // try with the han script instead, give it a penalty
+ if (override_script == TQFont::Han_TraditionalChinese
+ && (try_family->scripts[TQFont::Han_SimplifiedChinese] & TQtFontFamily::Supported)) {
+ override_script = TQFont::Han_SimplifiedChinese;
+ score_adjust = 200;
+ } else if (override_script == TQFont::Han_SimplifiedChinese
+ && (try_family->scripts[TQFont::Han_TraditionalChinese] & TQtFontFamily::Supported)) {
+ override_script = TQFont::Han_TraditionalChinese;
+ score_adjust = 200;
+ } else {
+ override_script = TQFont::Han;
+ score_adjust = 400;
+ }
+ } else
+#endif
+ if (family_name.isEmpty()) {
+ continue;
+ } else if (try_family->scripts[TQFont::UnknownScript] & TQtFontFamily::Supported) {
+ // try with the unknown script (for a symbol font)
+ override_script = TQFont::UnknownScript;
+#ifndef TQT_XFT2
+ } else if (try_family->scripts[TQFont::Unicode] & TQtFontFamily::Supported) {
+ // try with the tqunicode script instead
+ override_script = TQFont::Unicode;
+#endif
+ } else {
+ // family not supported by tqunicode/unknown scripts
+ continue;
+ }
+ }
+
+ TQtFontFoundry *try_foundry = 0;
+ TQtFontStyle *try_style = 0;
+ TQtFontSize *try_size = 0;
+#ifdef TQ_WS_X11
+ TQtFontEncoding *try_encoding = 0;
+#endif // TQ_WS_X11
+
+ // as we know the script is supported, we can be sure
+ // to tqfind a matching font here.
+ unsigned int newscore =
+ bestFoundry( override_script, score, request.styleStrategy,
+ try_family, foundry_name, styleKey, request.pixelSize, pitch,
+ &try_foundry, &try_style, &try_size
+#ifdef TQ_WS_X11
+ , &try_encoding, force_encoding_id
+#endif
+ );
+ if ( try_foundry == 0 ) {
+ // the specific foundry was not found, so look for
+ // any foundry matching our requirements
+ newscore = bestFoundry( override_script, score, request.styleStrategy, try_family,
+ TQString::null, styleKey, request.pixelSize,
+ pitch, &try_foundry, &try_style, &try_size
+#ifdef TQ_WS_X11
+ , &try_encoding, force_encoding_id
+#endif
+ );
+ }
+ newscore += score_adjust;
+
+ if ( newscore < score ) {
+ score = newscore;
+ best_family = try_family;
+ best_foundry = try_foundry;
+ best_style = try_style;
+ best_size = try_size;
+#ifdef TQ_WS_X11
+ best_encoding = try_encoding;
+#endif // TQ_WS_X11
+ }
+ if ( newscore < 10 ) // xlfd instead of xft... just accept it
+ break;
+ }
+
+ if ( best_family != 0 && best_foundry != 0 && best_style != 0
+#ifdef TQ_WS_X11
+ && best_size != 0 && best_encoding != 0
+#endif
+ ) {
+ FM_DEBUG( " BEST:\n"
+ " family: %s [%s]\n"
+ " weight: %d, italic: %d, oblique: %d\n"
+ " stretch: %d\n"
+ " pixelSize: %d\n"
+ " pitch: %c\n"
+ " encoding: %d\n",
+ best_family->name.latin1(),
+ best_foundry->name.isEmpty() ? "-- none --" : best_foundry->name.latin1(),
+ best_style->key.weight, best_style->key.italic, best_style->key.oblique,
+ best_style->key.stretch, best_size ? best_size->pixelSize : 0xffff,
+#ifdef TQ_WS_X11
+ best_encoding->pitch, best_encoding->encoding
+#else
+ 'p', 0
+#endif
+ );
+
+ fe = loadEngine( script, fp, request, best_family, best_foundry, best_style
+#ifdef TQ_WS_X11
+ , best_size, best_encoding, ( force_encoding_id >= 0 )
+#endif
+ );
+ }
+ if (fe) {
+ fe->fontDef.family = best_family->name;
+ if ( ! best_foundry->name.isEmpty() ) {
+ fe->fontDef.family += TQString::tqfromLatin1( " [" );
+ fe->fontDef.family += best_foundry->name;
+ fe->fontDef.family += TQString::tqfromLatin1( "]" );
+ }
+
+ if ( best_style->smoothScalable )
+ fe->fontDef.pixelSize = request.pixelSize;
+ else if ( best_style->bitmapScalable &&
+ ( request.styleStrategy & TQFont::PreferMatch ) )
+ fe->fontDef.pixelSize = request.pixelSize;
+ else
+ fe->fontDef.pixelSize = best_size->pixelSize;
+
+ fe->fontDef.tqstyleHint = request.tqstyleHint;
+ fe->fontDef.styleStrategy = request.styleStrategy;
+
+ fe->fontDef.weight = best_style->key.weight;
+ fe->fontDef.italic = best_style->key.italic || best_style->key.oblique;
+ fe->fontDef.fixedPitch = best_family->fixedPitch;
+ fe->fontDef.stretch = best_style->key.stretch;
+ fe->fontDef.ignorePitch = FALSE;
+ }
+ }
+
+ if ( fe ) {
+ if ( script != TQFont::Unicode && !canRender( fe, script ) ) {
+ FM_DEBUG( " WARN: font loaded cannot render a sample char" );
+
+ delete fe;
+ fe = 0;
+ } else if ( fp ) {
+ TQFontDef def = request;
+ if (def.family.isEmpty()) {
+ def.family = fp->request.family;
+ def.family = def.family.left(def.family.tqfind(','));
+ }
+ TQFontCache::Key key( def, script,
+#ifdef TQ_WS_WIN
+ (int)fp->painttqdevice,
+#else
+ fp->screen,
+#endif
+ fp->painttqdevice
+ );
+ TQFontCache::instance->insertEngine( key, fe );
+ if (!usesFontConfig) {
+ for ( int i = 0; i < TQFont::NScripts; ++i ) {
+ if ( i == script ) continue;
+
+ if (!canRender(fe, (TQFont::Script) i))
+ continue;
+
+ key.script = i;
+ TQFontCache::instance->insertEngine( key, fe );
+ }
+ }
+ }
+ }
+
+ if (!fe) {
+ if ( !request.family.isEmpty() )
+ return 0;
+
+ FM_DEBUG( "returning box engine" );
+
+ fe = new TQFontEngineBox( request.pixelSize );
+ fe->fontDef = request;
+
+ if ( fp ) {
+ TQFontCache::Key key( request, script,
+#ifdef TQ_WS_WIN
+ (int)fp->painttqdevice,
+#else
+ fp->screen,
+#endif
+ fp->painttqdevice
+ );
+ TQFontCache::instance->insertEngine( key, fe );
+ }
+ }
+
+ if ( fp ) {
+#if defined(TQ_WS_X11)
+ fe->fontDef.pointSize =
+ tqRound(10. * qt_pointSize(fe->fontDef.pixelSize, fp->painttqdevice, fp->screen));
+#elif defined(TQ_WS_WIN)
+ fe->fontDef.pointSize = int( double( fe->fontDef.pixelSize ) * 720.0 /
+ GetDeviceCaps(shared_dc,LOGPIXELSY) );
+#else
+ fe->fontDef.pointSize = int( double( fe->fontDef.pixelSize ) * 720.0 /
+ 96.0 );
+#endif
+ } else {
+ fe->fontDef.pointSize = request.pointSize;
+ }
+
+ return fe;
+}
+#endif // TQ_WS_X11 || TQ_WS_WIN
+
+
+
+
+static TQString styleString( int weight, bool italic, bool oblique )
+{
+ TQString result;
+ if ( weight >= TQFont::Black )
+ result = "Black";
+ else if ( weight >= TQFont::Bold )
+ result = "Bold";
+ else if ( weight >= TQFont::DemiBold )
+ result = "Demi Bold";
+ else if ( weight < TQFont::Normal )
+ result = "Light";
+
+ if ( italic )
+ result += " Italic";
+ else if ( oblique )
+ result += " Oblique";
+
+ if ( result.isEmpty() )
+ result = "Normal";
+
+ return result.simplifyWhiteSpace();
+}
+
+/*!
+ Returns a string that describes the style of the font \a f. For
+ example, "Bold Italic", "Bold", "Italic" or "Normal". An empty
+ string may be returned.
+*/
+TQString TQFontDatabase::styleString( const TQFont &f )
+{
+ // ### fix oblique here
+ return ::styleString( f.weight(), f.italic(), FALSE );
+}
+
+
+/*!
+ \class TQFontDatabase tqfontdatabase.h
+ \brief The TQFontDatabase class provides information about the fonts available in the underlying window system.
+
+ \ingroup environment
+ \ingroup graphics
+
+ The most common uses of this class are to query the database for
+ the list of font families() and for the pointSizes() and styles()
+ that are available for each family. An alternative to pointSizes()
+ is smoothSizes() which returns the sizes at which a given family
+ and style will look attractive.
+
+ If the font family is available from two or more foundries the
+ foundry name is included in the family name, e.g. "Helvetica
+ [Adobe]" and "Helvetica [Cronyx]". When you specify a family you
+ can either use the old hyphenated TQt 2.x "foundry-family" format,
+ e.g. "Cronyx-Helvetica", or the new bracketed TQt 3.x "family
+ [foundry]" format e.g. "Helvetica [Cronyx]". If the family has a
+ foundry it is always returned, e.g. by families(), using the
+ bracketed format.
+
+ The font() function returns a TQFont given a family, style and
+ point size.
+
+ A family and style combination can be checked to see if it is
+ italic() or bold(), and to retrieve its weight(). Similarly we can
+ call isBitmapScalable(), isSmoothlyScalable(), isScalable() and
+ isFixedPitch().
+
+ A text version of a style is given by styleString().
+
+ The TQFontDatabase class also supports some static functions, for
+ example, standardSizes(). You can retrieve the Unicode 3.0
+ description of a \link TQFont::Script script\endlink using
+ scriptName(), and a sample of characters in a script with
+ scriptSample().
+
+ Example:
+\code
+#include <tqapplication.h>
+#include <tqfontdatabase.h>
+#include <else.h>
+
+int main( int argc, char **argv )
+{
+ TQApplication app( argc, argv );
+ TQFontDatabase fdb;
+ TQStringList families = fdb.families();
+ for ( TQStringList::Iterator f = families.begin(); f != families.end(); ++f ) {
+ TQString family = *f;
+ qDebug( family );
+ TQStringList styles = fdb.styles( family );
+ for ( TQStringList::Iterator s = styles.begin(); s != styles.end(); ++s ) {
+ TQString style = *s;
+ TQString dstyle = "\t" + style + " (";
+ TQValueList<int> smoothies = fdb.smoothSizes( family, style );
+ for ( TQValueList<int>::Iterator points = smoothies.begin();
+ points != smoothies.end(); ++points ) {
+ dstyle += TQString::number( *points ) + " ";
+ }
+ dstyle = dstyle.left( dstyle.length() - 1 ) + ")";
+ qDebug( dstyle );
+ }
+ }
+ return 0;
+}
+\endcode
+ This example gets the list of font families, then the list of
+ styles for each family and the point sizes that are available for
+ each family/style combination.
+*/
+/*!
+ \obsolete
+ \fn inline TQStringList TQFontDatabase::families( bool ) const
+*/
+/*!
+ \obsolete
+ \fn inline TQStringList TQFontDatabase::styles( const TQString &family,
+ const TQString & ) const
+*/
+/*!
+ \obsolete
+ \fn inline TQValueList<int> TQFontDatabase::pointSizes( const TQString &family,
+ const TQString &style ,
+ const TQString & )
+*/
+
+/*!
+ \obsolete
+ \fn inline TQValueList<int> TQFontDatabase::smoothSizes( const TQString &family,
+ const TQString &style,
+ const TQString & )
+*/
+/*!
+ \obsolete
+ \fn inline TQFont TQFontDatabase::font( const TQString &familyName,
+ const TQString &style,
+ int pointSize,
+ const TQString &)
+*/
+/*!
+ \obsolete
+ \fn inline bool TQFontDatabase::isBitmapScalable( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+*/
+
+/*!
+ \obsolete
+ \fn inline bool TQFontDatabase::isSmoothlyScalable( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+*/
+
+/*!
+ \obsolete
+ \fn inline bool TQFontDatabase::isScalable( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+*/
+
+/*!
+ \obsolete
+ \fn inline bool TQFontDatabase::isFixedPitch( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+*/
+
+/*!
+ \obsolete
+ \fn inline bool TQFontDatabase::italic( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+*/
+
+/*!
+ \obsolete
+ \fn inline bool TQFontDatabase::bold( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+*/
+
+/*!
+ \obsolete
+ \fn inline int TQFontDatabase::weight( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+*/
+
+
+/*!
+ Creates a font database object.
+*/
+TQFontDatabase::TQFontDatabase()
+{
+ createDatabase();
+
+ d = db;
+}
+
+
+/*! Returns a sorted list of the names of the available font families.
+
+ If a family exists in several foundries, the returned name for
+ that font is in the form "family [foundry]". Examples: "Times
+ [Adobe]", "Times [Cronyx]", "Palatino".
+*/
+TQStringList TQFontDatabase::families() const
+{
+ load();
+
+ TQStringList flist;
+ for ( int i = 0; i < d->count; i++ ) {
+ TQtFontFamily *f = d->families[i];
+ if ( f->count == 0 )
+ continue;
+ if ( f->count == 1 ) {
+ flist.append( f->name );
+ } else {
+ for ( int j = 0; j < f->count; j++ ) {
+ TQString str = f->name;
+ TQString foundry = f->foundries[j]->name;
+ if ( !foundry.isEmpty() ) {
+ str += " [";
+ str += foundry;
+ str += "]";
+ }
+ flist.append( str );
+ }
+ }
+ }
+ return flist;
+}
+
+/*!
+ \overload
+
+ Returns a sorted list of the available font families which support
+ the Unicode script \a script.
+
+ If a family exists in several foundries, the returned name for
+ that font is in the form "family [foundry]". Examples: "Times
+ [Adobe]", "Times [Cronyx]", "Palatino".
+*/
+TQStringList TQFontDatabase::families( TQFont::Script script ) const
+{
+ load();
+
+ TQStringList flist;
+ for ( int i = 0; i < d->count; i++ ) {
+ TQtFontFamily *f = d->families[i];
+ if ( f->count == 0 )
+ continue;
+ if (!(f->scripts[script] & TQtFontFamily::Supported))
+ continue;
+ if ( f->count == 1 ) {
+ flist.append( f->name );
+ } else {
+ for ( int j = 0; j < f->count; j++ ) {
+ TQString str = f->name;
+ TQString foundry = f->foundries[j]->name;
+ if ( !foundry.isEmpty() ) {
+ str += " [";
+ str += foundry;
+ str += "]";
+ }
+ flist.append( str );
+ }
+ }
+ }
+ return flist;
+}
+
+/*!
+ Returns a list of the styles available for the font family \a
+ family. Some example styles: "Light", "Light Italic", "Bold",
+ "Oblique", "Demi". The list may be empty.
+*/
+TQStringList TQFontDatabase::styles( const TQString &family ) const
+{
+ TQString familyName, foundryName;
+ parseFontName( family, foundryName, familyName );
+
+ load( familyName );
+
+ TQStringList l;
+ TQtFontFamily *f = d->family( familyName );
+ if ( !f )
+ return l;
+
+ TQtFontFoundry allStyles( foundryName );
+ for ( int j = 0; j < f->count; j++ ) {
+ TQtFontFoundry *foundry = f->foundries[j];
+ if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
+ for ( int k = 0; k < foundry->count; k++ ) {
+ TQtFontStyle::Key ke( foundry->styles[k]->key );
+ ke.stretch = 0;
+ allStyles.style( ke, TRUE );
+ }
+ }
+ }
+
+ for ( int i = 0; i < allStyles.count; i++ )
+ l.append( ::styleString( allStyles.styles[i]->key.weight,
+ allStyles.styles[i]->key.italic,
+ allStyles.styles[i]->key.oblique ) );
+ return l;
+}
+
+/*!
+ Returns TRUE if the font that has family \a family and style \a
+ style is fixed pitch; otherwise returns FALSE.
+*/
+
+bool TQFontDatabase::isFixedPitch(const TQString &family,
+ const TQString &style) const
+{
+ TQ_UNUSED(style);
+
+ TQString familyName, foundryName;
+ parseFontName( family, foundryName, familyName );
+
+ load( familyName );
+
+ TQtFontFamily *f = d->family( familyName );
+#if defined(TQ_OS_MAC) && !defined(TQWS)
+ if (f) {
+ if (!f->fixedPitchComputed) {
+ TQFontMetrics fm(familyName);
+ f->fixedPitch = fm.width('i') == fm.width('m');
+ f->fixedPitchComputed = TRUE;
+ }
+ }
+#endif
+
+ return ( f && f->fixedPitch );
+}
+
+/*!
+ Returns TRUE if the font that has family \a family and style \a
+ style is a scalable bitmap font; otherwise returns FALSE. Scaling
+ a bitmap font usually produces an unattractive hardly readable
+ result, because the pixels of the font are scaled. If you need to
+ scale a bitmap font it is better to scale it to one of the fixed
+ sizes returned by smoothSizes().
+
+ \sa isScalable(), isSmoothlyScalable()
+*/
+bool TQFontDatabase::isBitmapScalable( const TQString &family,
+ const TQString &style) const
+{
+ bool bitmapScalable = FALSE;
+ TQString familyName, foundryName;
+ parseFontName( family, foundryName, familyName );
+
+ load( familyName );
+
+ TQtFontStyle::Key styleKey( style );
+
+ TQtFontFamily *f = d->family( familyName );
+ if ( !f ) return bitmapScalable;
+
+ for ( int j = 0; j < f->count; j++ ) {
+ TQtFontFoundry *foundry = f->foundries[j];
+ if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
+ for ( int k = 0; k < foundry->count; k++ )
+ if ((style.isEmpty() || foundry->styles[k]->key == styleKey) &&
+ foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
+ bitmapScalable = TRUE;
+ goto end;
+ }
+ }
+ }
+ end:
+ return bitmapScalable;
+}
+
+
+/*!
+ Returns TRUE if the font that has family \a family and style \a
+ style is smoothly scalable; otherwise returns FALSE. If this
+ function returns TRUE, it's safe to scale this font to any size,
+ and the result will always look attractive.
+
+ \sa isScalable(), isBitmapScalable()
+*/
+bool TQFontDatabase::isSmoothlyScalable( const TQString &family,
+ const TQString &style) const
+{
+ bool smoothScalable = FALSE;
+ TQString familyName, foundryName;
+ parseFontName( family, foundryName, familyName );
+
+ load( familyName );
+
+ TQtFontStyle::Key styleKey( style );
+
+ TQtFontFamily *f = d->family( familyName );
+ if ( !f ) return smoothScalable;
+
+ for ( int j = 0; j < f->count; j++ ) {
+ TQtFontFoundry *foundry = f->foundries[j];
+ if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
+ for ( int k = 0; k < foundry->count; k++ )
+ if ((style.isEmpty() || foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) {
+ smoothScalable = TRUE;
+ goto end;
+ }
+ }
+ }
+ end:
+ return smoothScalable;
+}
+
+/*!
+ Returns TRUE if the font that has family \a family and style \a
+ style is scalable; otherwise returns FALSE.
+
+ \sa isBitmapScalable(), isSmoothlyScalable()
+*/
+bool TQFontDatabase::isScalable( const TQString &family,
+ const TQString &style) const
+{
+ if ( isSmoothlyScalable( family, style) )
+ return TRUE;
+
+ return isBitmapScalable( family, style);
+}
+
+
+/*!
+ Returns a list of the point sizes available for the font that has
+ family \a family and style \a style. The list may be empty.
+
+ \sa smoothSizes(), standardSizes()
+*/
+TQValueList<int> TQFontDatabase::pointSizes( const TQString &family,
+ const TQString &style)
+{
+#if defined(TQ_WS_MAC)
+ // windows and macosx are always smoothly scalable
+ TQ_UNUSED( family );
+ TQ_UNUSED( style );
+ return standardSizes();
+#else
+ bool smoothScalable = FALSE;
+ TQString familyName, foundryName;
+ parseFontName( family, foundryName, familyName );
+
+ load( familyName );
+
+ TQtFontStyle::Key styleKey( style );
+
+ TQValueList<int> sizes;
+
+ TQtFontFamily *fam = d->family( familyName );
+ if ( !fam ) return sizes;
+
+ for ( int j = 0; j < fam->count; j++ ) {
+ TQtFontFoundry *foundry = fam->foundries[j];
+ if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
+ TQtFontStyle *style = foundry->style( styleKey );
+ if ( !style ) continue;
+
+ if ( style->smoothScalable ) {
+ smoothScalable = TRUE;
+ goto end;
+ }
+ for ( int l = 0; l < style->count; l++ ) {
+ const TQtFontSize *size = style->pixelSizes + l;
+
+ if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) {
+#ifdef TQ_WS_X11
+ const uint pointSize = tqRound(qt_pointSize(size->pixelSize, 0, -1));
+#else
+ const uint pointSize = size->pixelSize; // embedded uses 72dpi
+#endif
+ if (! sizes.tqcontains(pointSize))
+ sizes.append(pointSize);
+ }
+ }
+ }
+ }
+ end:
+ if ( smoothScalable )
+ return standardSizes();
+
+ qHeapSort( sizes );
+ return sizes;
+#endif
+}
+
+/*!
+ Returns a TQFont object that has family \a family, style \a style
+ and point size \a pointSize. If no matching font could be created,
+ a TQFont object that uses the application's default font is
+ returned.
+*/
+TQFont TQFontDatabase::font( const TQString &family, const TQString &style,
+ int pointSize)
+{
+ TQString familyName, foundryName;
+ parseFontName( family, foundryName, familyName );
+
+ load( familyName );
+
+ TQtFontFoundry allStyles( foundryName );
+ TQtFontFamily *f = d->family( familyName );
+ if ( !f ) return TQApplication::font();
+
+ for ( int j = 0; j < f->count; j++ ) {
+ TQtFontFoundry *foundry = f->foundries[j];
+ if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
+ for ( int k = 0; k < foundry->count; k++ )
+ allStyles.style( foundry->styles[k]->key, TRUE );
+ }
+ }
+
+ TQtFontStyle::Key styleKey( style );
+ TQtFontStyle *s = bestStyle(&allStyles, styleKey);
+
+ if ( !s ) // no styles found?
+ return TQApplication::font();
+ return TQFont( family, pointSize, s->key.weight,
+ s->key.italic ? TRUE : s->key.oblique ? TRUE : FALSE );
+}
+
+
+/*!
+ Returns the point sizes of a font that has family \a family and
+ style \a style that will look attractive. The list may be empty.
+ For non-scalable fonts and bitmap scalable fonts, this function
+ is equivalent to pointSizes().
+
+ \sa pointSizes(), standardSizes()
+*/
+TQValueList<int> TQFontDatabase::smoothSizes( const TQString &family,
+ const TQString &style)
+{
+#ifdef TQ_WS_WIN
+ TQ_UNUSED( family );
+ TQ_UNUSED( style );
+ return TQFontDatabase::standardSizes();
+#else
+ bool smoothScalable = FALSE;
+ TQString familyName, foundryName;
+ parseFontName( family, foundryName, familyName );
+
+ load( familyName );
+
+ TQtFontStyle::Key styleKey( style );
+
+ TQValueList<int> sizes;
+
+ TQtFontFamily *fam = d->family( familyName );
+ if ( !fam )
+ return sizes;
+
+ for ( int j = 0; j < fam->count; j++ ) {
+ TQtFontFoundry *foundry = fam->foundries[j];
+ if ( foundryName.isEmpty() ||
+ ucstricmp( foundry->name, foundryName ) == 0 ) {
+ TQtFontStyle *style = foundry->style( styleKey );
+ if ( !style ) continue;
+
+ if ( style->smoothScalable ) {
+ smoothScalable = TRUE;
+ goto end;
+ }
+ for ( int l = 0; l < style->count; l++ ) {
+ const TQtFontSize *size = style->pixelSizes + l;
+
+ if ( size->pixelSize != 0 && size->pixelSize != USHRT_MAX ) {
+#ifdef TQ_WS_X11
+ const uint pointSize = tqRound(qt_pointSize(size->pixelSize, 0, -1));
+#else
+ const uint pointSize = size->pixelSize; // embedded uses 72dpi
+#endif
+ if (! sizes.tqcontains(pointSize))
+ sizes.append( pointSize );
+ }
+ }
+ }
+ }
+ end:
+ if ( smoothScalable )
+ return TQFontDatabase::standardSizes();
+
+ qHeapSort( sizes );
+ return sizes;
+#endif
+}
+
+
+/*!
+ Returns a list of standard font sizes.
+
+ \sa smoothSizes(), pointSizes()
+*/
+TQValueList<int> TQFontDatabase::standardSizes()
+{
+ TQValueList<int> ret;
+ static const unsigned short standard[] =
+ { 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72, 0 };
+ const unsigned short *sizes = standard;
+ while ( *sizes ) ret << *sizes++;
+ return ret;
+}
+
+
+/*!
+ Returns TRUE if the font that has family \a family and style \a
+ style is italic; otherwise returns FALSE.
+
+ \sa weight(), bold()
+*/
+bool TQFontDatabase::italic( const TQString &family,
+ const TQString &style) const
+{
+ TQString familyName, foundryName;
+ parseFontName( family, foundryName, familyName );
+
+ load( familyName );
+
+ TQtFontFoundry allStyles( foundryName );
+ TQtFontFamily *f = d->family( familyName );
+ if ( !f ) return FALSE;
+
+ for ( int j = 0; j < f->count; j++ ) {
+ TQtFontFoundry *foundry = f->foundries[j];
+ if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
+ for ( int k = 0; k < foundry->count; k++ )
+ allStyles.style( foundry->styles[k]->key, TRUE );
+ }
+ }
+
+ TQtFontStyle::Key styleKey( style );
+ TQtFontStyle *s = allStyles.style( styleKey );
+ return s && s->key.italic;
+}
+
+
+/*!
+ Returns TRUE if the font that has family \a family and style \a
+ style is bold; otherwise returns FALSE.
+
+ \sa italic(), weight()
+*/
+bool TQFontDatabase::bold( const TQString &family,
+ const TQString &style) const
+{
+ TQString familyName, foundryName;
+ parseFontName( family, foundryName, familyName );
+
+ load( familyName );
+
+ TQtFontFoundry allStyles( foundryName );
+ TQtFontFamily *f = d->family( familyName );
+ if ( !f ) return FALSE;
+
+ for ( int j = 0; j < f->count; j++ ) {
+ TQtFontFoundry *foundry = f->foundries[j];
+ if ( foundryName.isEmpty() ||
+ ucstricmp( foundry->name, foundryName ) == 0 ) {
+ for ( int k = 0; k < foundry->count; k++ )
+ allStyles.style( foundry->styles[k]->key, TRUE );
+ }
+ }
+
+ TQtFontStyle::Key styleKey( style );
+ TQtFontStyle *s = allStyles.style( styleKey );
+ return s && s->key.weight >= TQFont::Bold;
+}
+
+
+/*!
+ Returns the weight of the font that has family \a family and style
+ \a style. If there is no such family and style combination,
+ returns -1.
+
+ \sa italic(), bold()
+*/
+int TQFontDatabase::weight( const TQString &family,
+ const TQString &style) const
+{
+ TQString familyName, foundryName;
+ parseFontName( family, foundryName, familyName );
+
+ load( familyName );
+
+ TQtFontFoundry allStyles( foundryName );
+ TQtFontFamily *f = d->family( familyName );
+ if ( !f ) return -1;
+
+ for ( int j = 0; j < f->count; j++ ) {
+ TQtFontFoundry *foundry = f->foundries[j];
+ if ( foundryName.isEmpty() ||
+ ucstricmp( foundry->name, foundryName ) == 0 ) {
+ for ( int k = 0; k < foundry->count; k++ )
+ allStyles.style( foundry->styles[k]->key, TRUE );
+ }
+ }
+
+ TQtFontStyle::Key styleKey( style );
+ TQtFontStyle *s = allStyles.style( styleKey );
+ return s ? s->key.weight : -1;
+}
+
+
+/*!
+ Returns a string that gives a default description of the \a script
+ (e.g. for displaying to the user in a dialog). The name matches
+ the name of the script as defined by the Unicode 3.0 standard.
+
+ \sa TQFont::Script
+*/
+TQString TQFontDatabase::scriptName(TQFont::Script script)
+{
+ const char *name = 0;
+
+ switch (script) {
+ case TQFont::Latin:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Latin");
+ break;
+ case TQFont::Greek:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Greek" );
+ break;
+ case TQFont::Cyrillic:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Cyrillic" );
+ break;
+ case TQFont::Armenian:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Armenian" );
+ break;
+ case TQFont::Georgian:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Georgian" );
+ break;
+ case TQFont::Runic:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Runic" );
+ break;
+ case TQFont::Ogham:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Ogham" );
+ break;
+ case TQFont::SpacingModifiers:
+ name = TQT_TRANSLATE_NOOP("TQFont", "SpacingModifiers" );
+ break;
+ case TQFont::CombiningMarks:
+ name = TQT_TRANSLATE_NOOP("TQFont", "CombiningMarks" );
+ break;
+ case TQFont::Hebrew:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Hebrew" );
+ break;
+ case TQFont::Arabic:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Arabic" );
+ break;
+ case TQFont::Syriac:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Syriac" );
+ break;
+ case TQFont::Thaana:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Thaana" );
+ break;
+ case TQFont::Devanagari:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Devanagari" );
+ break;
+ case TQFont::Bengali:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Bengali" );
+ break;
+ case TQFont::Gurmukhi:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Gurmukhi" );
+ break;
+ case TQFont::Gujarati:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Gujarati" );
+ break;
+ case TQFont::Oriya:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Oriya" );
+ break;
+ case TQFont::Tamil:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Tamil" );
+ break;
+ case TQFont::Telugu:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Telugu" );
+ break;
+ case TQFont::Kannada:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Kannada" );
+ break;
+ case TQFont::Malayalam:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Malayalam" );
+ break;
+ case TQFont::Sinhala:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Sinhala" );
+ break;
+ case TQFont::Thai:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Thai" );
+ break;
+ case TQFont::Lao:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Lao" );
+ break;
+ case TQFont::Tibetan:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Tibetan" );
+ break;
+ case TQFont::Myanmar:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Myanmar" );
+ break;
+ case TQFont::Khmer:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Khmer" );
+ break;
+ case TQFont::Han:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Han" );
+ break;
+ case TQFont::Hiragana:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Hiragana" );
+ break;
+ case TQFont::Katakana:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Katakana" );
+ break;
+ case TQFont::Hangul:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Hangul" );
+ break;
+ case TQFont::Bopomofo:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Bopomofo" );
+ break;
+ case TQFont::Yi:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Yi" );
+ break;
+ case TQFont::Ethiopic:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Ethiopic" );
+ break;
+ case TQFont::Cherokee:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Cherokee" );
+ break;
+ case TQFont::CanadianAboriginal:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Canadian Aboriginal" );
+ break;
+ case TQFont::Mongolian:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Mongolian" );
+ break;
+
+ case TQFont::CurrencySymbols:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Currency Symbols" );
+ break;
+
+ case TQFont::LetterlikeSymbols:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Letterlike Symbols" );
+ break;
+
+ case TQFont::NumberForms:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Number Forms" );
+ break;
+
+ case TQFont::MathematicalOperators:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Mathematical Operators" );
+ break;
+
+ case TQFont::TechnicalSymbols:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Technical Symbols" );
+ break;
+
+ case TQFont::GeometricSymbols:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Geometric Symbols" );
+ break;
+
+ case TQFont::MiscellaneousSymbols:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Miscellaneous Symbols" );
+ break;
+
+ case TQFont::EnclosedAndSquare:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Enclosed and Square" );
+ break;
+
+ case TQFont::Braille:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Braille" );
+ break;
+
+ case TQFont::Unicode:
+ name = TQT_TRANSLATE_NOOP("TQFont", "Unicode" );
+ break;
+
+ case TQFont::Tagalog:
+ name = TQT_TRANSLATE_NOOP( "TQFont", "Tagalog" );
+ break;
+
+ case TQFont::Hanunoo:
+ name = TQT_TRANSLATE_NOOP( "TQFont", "Hanunoo" );
+ break;
+
+ case TQFont::Buhid:
+ name = TQT_TRANSLATE_NOOP( "TQFont", "Buhid" );
+ break;
+
+ case TQFont::Tagbanwa:
+ name = TQT_TRANSLATE_NOOP( "TQFont", "Tagbanwa" );
+ break;
+
+ case TQFont::KatakanaHalfWidth:
+ name = TQT_TRANSLATE_NOOP( "TQFont", "Katakana Half-Width Forms" );
+ break;
+
+ case TQFont::Han_Japanese:
+ name = TQT_TRANSLATE_NOOP( "TQFont", "Han (Japanese)" );
+ break;
+
+ case TQFont::Han_SimplifiedChinese:
+ name = TQT_TRANSLATE_NOOP( "TQFont", "Han (Simplified Chinese)" );
+ break;
+
+ case TQFont::Han_TraditionalChinese:
+ name = TQT_TRANSLATE_NOOP( "TQFont", "Han (Traditional Chinese)" );
+ break;
+
+ case TQFont::Han_Korean:
+ name = TQT_TRANSLATE_NOOP( "TQFont", "Han (Korean)" );
+ break;
+
+ default:
+ name = TQT_TRANSLATE_NOOP( "TQFont", "Unknown Script" );
+ break;
+ }
+
+ return tqApp ? tqApp->translate("TQFont", name) : TQString::tqfromLatin1(name);
+}
+
+
+/*!
+ Returns a string with sample characters from \a script.
+
+ \sa TQFont::Script
+*/
+TQString TQFontDatabase::scriptSample(TQFont::Script script)
+{
+ TQString sample = "AaBb";
+
+ switch (script) {
+ case TQFont::Latin:
+ // This is cheating... we only show latin-1 characters so that we don't
+ // end up loading lots of fonts - at least on X11...
+ sample += TQChar(0x00C3);
+ sample += TQChar(0x00E1);
+ sample += "Zz";
+ break;
+ case TQFont::Greek:
+ sample += TQChar(0x0393);
+ sample += TQChar(0x03B1);
+ sample += TQChar(0x03A9);
+ sample += TQChar(0x03C9);
+ break;
+ case TQFont::Cyrillic:
+ sample += TQChar(0x0414);
+ sample += TQChar(0x0434);
+ sample += TQChar(0x0436);
+ sample += TQChar(0x0402);
+ break;
+ case TQFont::Armenian:
+ sample += TQChar(0x053f);
+ sample += TQChar(0x054f);
+ sample += TQChar(0x056f);
+ sample += TQChar(0x057f);
+ break;
+ case TQFont::Georgian:
+ sample += TQChar(0x10a0);
+ sample += TQChar(0x10b0);
+ sample += TQChar(0x10c0);
+ sample += TQChar(0x10d0);
+ break;
+ case TQFont::Runic:
+ sample += TQChar(0x16a0);
+ sample += TQChar(0x16b0);
+ sample += TQChar(0x16c0);
+ sample += TQChar(0x16d0);
+ break;
+ case TQFont::Ogham:
+ sample += TQChar(0x1681);
+ sample += TQChar(0x1687);
+ sample += TQChar(0x1693);
+ sample += TQChar(0x168d);
+ break;
+
+
+
+ case TQFont::Hebrew:
+ sample += TQChar(0x05D0);
+ sample += TQChar(0x05D1);
+ sample += TQChar(0x05D2);
+ sample += TQChar(0x05D3);
+ break;
+ case TQFont::Arabic:
+ sample += TQChar(0x0628);
+ sample += TQChar(0x0629);
+ sample += TQChar(0x062A);
+ sample += TQChar(0x063A);
+ break;
+ case TQFont::Syriac:
+ sample += TQChar(0x0715);
+ sample += TQChar(0x0725);
+ sample += TQChar(0x0716);
+ sample += TQChar(0x0726);
+ break;
+ case TQFont::Thaana:
+ sample += TQChar(0x0784);
+ sample += TQChar(0x0794);
+ sample += TQChar(0x078c);
+ sample += TQChar(0x078d);
+ break;
+
+
+
+ case TQFont::Devanagari:
+ sample += TQChar(0x0905);
+ sample += TQChar(0x0915);
+ sample += TQChar(0x0925);
+ sample += TQChar(0x0935);
+ break;
+ case TQFont::Bengali:
+ sample += TQChar(0x0986);
+ sample += TQChar(0x0996);
+ sample += TQChar(0x09a6);
+ sample += TQChar(0x09b6);
+ break;
+ case TQFont::Gurmukhi:
+ sample += TQChar(0x0a05);
+ sample += TQChar(0x0a15);
+ sample += TQChar(0x0a25);
+ sample += TQChar(0x0a35);
+ break;
+ case TQFont::Gujarati:
+ sample += TQChar(0x0a85);
+ sample += TQChar(0x0a95);
+ sample += TQChar(0x0aa5);
+ sample += TQChar(0x0ab5);
+ break;
+ case TQFont::Oriya:
+ sample += TQChar(0x0b06);
+ sample += TQChar(0x0b16);
+ sample += TQChar(0x0b2b);
+ sample += TQChar(0x0b36);
+ break;
+ case TQFont::Tamil:
+ sample += TQChar(0x0b89);
+ sample += TQChar(0x0b99);
+ sample += TQChar(0x0ba9);
+ sample += TQChar(0x0bb9);
+ break;
+ case TQFont::Telugu:
+ sample += TQChar(0x0c05);
+ sample += TQChar(0x0c15);
+ sample += TQChar(0x0c25);
+ sample += TQChar(0x0c35);
+ break;
+ case TQFont::Kannada:
+ sample += TQChar(0x0c85);
+ sample += TQChar(0x0c95);
+ sample += TQChar(0x0ca5);
+ sample += TQChar(0x0cb5);
+ break;
+ case TQFont::Malayalam:
+ sample += TQChar(0x0d05);
+ sample += TQChar(0x0d15);
+ sample += TQChar(0x0d25);
+ sample += TQChar(0x0d35);
+ break;
+ case TQFont::Sinhala:
+ sample += TQChar(0x0d90);
+ sample += TQChar(0x0da0);
+ sample += TQChar(0x0db0);
+ sample += TQChar(0x0dc0);
+ break;
+ case TQFont::Thai:
+ sample += TQChar(0x0e02);
+ sample += TQChar(0x0e12);
+ sample += TQChar(0x0e22);
+ sample += TQChar(0x0e32);
+ break;
+ case TQFont::Lao:
+ sample += TQChar(0x0e8d);
+ sample += TQChar(0x0e9d);
+ sample += TQChar(0x0ead);
+ sample += TQChar(0x0ebd);
+ break;
+ case TQFont::Tibetan:
+ sample += TQChar(0x0f00);
+ sample += TQChar(0x0f01);
+ sample += TQChar(0x0f02);
+ sample += TQChar(0x0f03);
+ break;
+ case TQFont::Myanmar:
+ sample += TQChar(0x1000);
+ sample += TQChar(0x1001);
+ sample += TQChar(0x1002);
+ sample += TQChar(0x1003);
+ break;
+ case TQFont::Khmer:
+ sample += TQChar(0x1780);
+ sample += TQChar(0x1790);
+ sample += TQChar(0x17b0);
+ sample += TQChar(0x17c0);
+ break;
+
+
+
+ case TQFont::Han:
+ sample += TQChar(0x6f84);
+ sample += TQChar(0x820a);
+ sample += TQChar(0x61a9);
+ sample += TQChar(0x9781);
+ break;
+ case TQFont::Hiragana:
+ sample += TQChar(0x3050);
+ sample += TQChar(0x3060);
+ sample += TQChar(0x3070);
+ sample += TQChar(0x3080);
+ break;
+ case TQFont::Katakana:
+ sample += TQChar(0x30b0);
+ sample += TQChar(0x30c0);
+ sample += TQChar(0x30d0);
+ sample += TQChar(0x30e0);
+ break;
+ case TQFont::Hangul:
+ sample += TQChar(0xac00);
+ sample += TQChar(0xac11);
+ sample += TQChar(0xac1a);
+ sample += TQChar(0xac2f);
+ break;
+ case TQFont::Bopomofo:
+ sample += TQChar(0x3105);
+ sample += TQChar(0x3115);
+ sample += TQChar(0x3125);
+ sample += TQChar(0x3129);
+ break;
+ case TQFont::Yi:
+ sample += TQChar(0xa1a8);
+ sample += TQChar(0xa1a6);
+ sample += TQChar(0xa200);
+ sample += TQChar(0xa280);
+ break;
+
+
+
+ case TQFont::Ethiopic:
+ sample += TQChar(0x1200);
+ sample += TQChar(0x1240);
+ sample += TQChar(0x1280);
+ sample += TQChar(0x12c0);
+ break;
+ case TQFont::Cherokee:
+ sample += TQChar(0x13a0);
+ sample += TQChar(0x13b0);
+ sample += TQChar(0x13c0);
+ sample += TQChar(0x13d0);
+ break;
+ case TQFont::CanadianAboriginal:
+ sample += TQChar(0x1410);
+ sample += TQChar(0x1500);
+ sample += TQChar(0x15f0);
+ sample += TQChar(0x1650);
+ break;
+ case TQFont::Mongolian:
+ sample += TQChar(0x1820);
+ sample += TQChar(0x1840);
+ sample += TQChar(0x1860);
+ sample += TQChar(0x1880);
+ break;
+
+
+ case TQFont::CurrencySymbols:
+ case TQFont::LetterlikeSymbols:
+ case TQFont::NumberForms:
+ case TQFont::MathematicalOperators:
+ case TQFont::TechnicalSymbols:
+ case TQFont::GeometricSymbols:
+ case TQFont::MiscellaneousSymbols:
+ case TQFont::EnclosedAndSquare:
+ case TQFont::Braille:
+ break;
+
+
+ case TQFont::Unicode:
+ sample += TQChar(0x0174);
+ sample += TQChar(0x0628);
+ sample += TQChar(0x0e02);
+ sample += TQChar(0x263A);
+ sample += TQChar(0x3129);
+ sample += TQChar(0x61a9);
+ sample += TQChar(0xac2f);
+ break;
+
+
+
+ default:
+ sample += TQChar(0xfffd);
+ sample += TQChar(0xfffd);
+ sample += TQChar(0xfffd);
+ sample += TQChar(0xfffd);
+ break;
+ }
+
+ return sample;
+}
+
+
+
+
+/*!
+ \internal
+
+ This makes sense of the font family name:
+
+ 1) if the family name tqcontains a '-' (ie. "Adobe-Courier"), then we
+ split at the '-', and use the string as the foundry, and the string to
+ the right as the family
+
+ 2) if the family name tqcontains a '[' and a ']', then we take the text
+ between the square brackets as the foundry, and the text before the
+ square brackets as the family (ie. "Arial [Monotype]")
+*/
+void TQFontDatabase::parseFontName(const TQString &name, TQString &foundry, TQString &family)
+{
+ if ( name.tqcontains('-') ) {
+ int i = name.tqfind('-');
+ foundry = name.left( i );
+ family = name.right( name.length() - i - 1 );
+ } else if ( name.tqcontains('[') && name.tqcontains(']')) {
+ int i = name.tqfind('[');
+ int li = name.tqfindRev(']');
+
+ if (i < li) {
+ foundry = name.mid(i + 1, li - i - 1);
+ if (name[i - 1] == ' ')
+ i--;
+ family = name.left(i);
+ }
+ } else {
+ foundry = TQString::null;
+ family = name;
+ }
+}
+
+#endif // USE_QT4
+
+#endif // TQT_NO_FONTDATABASE
diff --git a/tqtinterface/qt4/src/kernel/tqfontdatabase.h b/tqtinterface/qt4/src/kernel/tqfontdatabase.h
new file mode 100644
index 0000000..f2556ef
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfontdatabase.h
@@ -0,0 +1,306 @@
+/****************************************************************************
+**
+** Definition of the TQFontDatabase class
+**
+** Created : 981126
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFONTDATABASE_H
+#define TQFONTDATABASE_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqstring.h"
+#include "tqstringlist.h"
+#include "tqfont.h"
+#include "tqvaluelist.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qfontdatabase.h>
+#include <Qt/qstringlist.h>
+
+#endif // USE_QT4
+
+#ifndef TQT_NO_FONTDATABASE
+
+#ifndef USE_QT4
+
+class TQFontStylePrivate; /* Don't touch! */
+
+#endif // USE_QT4
+
+struct TQtFontStyle;
+struct TQtFontFamily;
+struct TQtFontFoundry;
+struct TQFontDef;
+class TQFontEngine;
+#ifdef TQ_WS_TQWS
+class TQDiskFont;
+#endif
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQFontDatabase : public QFontDatabase, virtual public TQt
+{
+public:
+ TQFontDatabase() : QFontDatabase() {}
+
+// private:
+// static inline TQFontEngine *tqfindFont( TQFont::Script script, const QFontPrivate *fp, const QFontDef &request, int force_encoding_id = -1 ) { return findFont(script, fp, request, force_encoding_id); }
+
+ static inline TQString scriptName( TQFont::Script s ) { return writingSystemName((QFontDatabase::WritingSystem)s); }
+ static inline TQString scriptSample( TQFont::Script s ) { return writingSystemSample((QFontDatabase::WritingSystem)s); }
+ inline TQStringList tqfamilies() const {
+ QStringList ql = families();
+ TQStringList tqsl;
+ tqsl.clear();
+ for (int i = 0; i < ql.size(); ++i) tqsl.append(ql.at(i));
+ return tqsl;
+ }
+ inline TQStringList tqfamilies( TQFont::Script s ) const {
+ QStringList ql = families((QFontDatabase::WritingSystem)s);
+ TQStringList tqsl;
+ tqsl.clear();
+ for (int i = 0; i < ql.size(); ++i) tqsl.append(ql.at(i));
+ return tqsl;
+ }
+ inline TQStringList tqstyles( const QString &s ) const {
+ QStringList ql = styles(s);
+ TQStringList tqsl;
+ tqsl.clear();
+ for (int i = 0; i < ql.size(); ++i) tqsl.append(ql.at(i));
+ return tqsl;
+ }
+ inline TQValueList<int> tqpointSizes(const QString &s, const QString &t = QString()) {
+ QList<int> ql = pointSizes(s, t);
+ TQValueList<int> tqsl;
+ tqsl.clear();
+ for (int i = 0; i < ql.size(); ++i) tqsl.append(ql.at(i));
+ return tqsl;
+ }
+
+ inline static TQValueList<int> tqstandardSizes() {
+ QList<int> ql = standardSizes();
+ TQValueList<int> tqsl;
+ tqsl.clear();
+ for (int i = 0; i < ql.size(); ++i) tqsl.append(ql.at(i));
+ return tqsl;
+ }
+ inline TQValueList<int> tqsmoothSizes( const TQString &s, const TQString &t) {
+ QList<int> ql = smoothSizes(s, t);
+ TQValueList<int> tqsl;
+ tqsl.clear();
+ for (int i = 0; i < ql.size(); ++i) tqsl.append(ql.at(i));
+ return tqsl;
+ }
+
+private:
+ static void tqparseFontName(const QString &name, QString &foundry, QString &family);
+
+ friend class TQFontDialog;
+};
+
+#else // USE_QT4
+
+class TQFontDatabasePrivate;
+
+class TQ_EXPORT TQFontDatabase
+{
+public:
+ static TQValueList<int> standardSizes();
+
+ TQFontDatabase();
+
+ TQStringList families() const;
+ TQStringList families( TQFont::Script ) const;
+ TQStringList styles( const TQString & ) const;
+ TQValueList<int> pointSizes( const TQString &, const TQString & = TQString::null);
+ TQValueList<int> smoothSizes( const TQString &, const TQString &);
+ TQString styleString( const TQFont &);
+
+ TQFont font( const TQString &, const TQString &, int);
+
+ bool isBitmapScalable( const TQString &, const TQString & = TQString::null) const;
+ bool isSmoothlyScalable( const TQString &, const TQString & = TQString::null) const;
+ bool isScalable( const TQString &, const TQString & = TQString::null) const;
+ bool isFixedPitch( const TQString &, const TQString & = TQString::null) const;
+
+ bool italic( const TQString &, const TQString &) const;
+ bool bold( const TQString &, const TQString &) const;
+ int weight( const TQString &, const TQString &) const;
+
+ static TQString scriptName(TQFont::Script);
+ static TQString scriptSample(TQFont::Script);
+
+#ifdef TQ_WS_TQWS
+ static void qwsAddDiskFont( TQDiskFont *qdf );
+#endif
+
+ // For source compatibility with < 3.0
+#ifndef TQT_NO_COMPAT
+
+ TQStringList families(bool) const;
+ TQStringList styles( const TQString &, const TQString & ) const;
+ TQValueList<int> pointSizes( const TQString &, const TQString &, const TQString & );
+ TQValueList<int> smoothSizes( const TQString &, const TQString &, const TQString & );
+
+ TQFont font( const TQString &, const TQString &, int, const TQString &);
+
+ bool isBitmapScalable( const TQString &, const TQString &, const TQString & ) const;
+ bool isSmoothlyScalable( const TQString &, const TQString &, const TQString & ) const;
+ bool isScalable( const TQString &, const TQString &, const TQString & ) const;
+ bool isFixedPitch( const TQString &, const TQString &, const TQString & ) const;
+
+ bool italic( const TQString &, const TQString &, const TQString & ) const;
+ bool bold( const TQString &, const TQString &, const TQString & ) const;
+ int weight( const TQString &, const TQString &, const TQString & ) const;
+
+#endif // TQT_NO_COMPAT
+
+private:
+#if defined(TQ_WS_X11) || defined(TQ_WS_WIN)
+ static TQFontEngine *tqfindFont( TQFont::Script script, const TQFontPrivate *fp,
+ const TQFontDef &request, int force_encoding_id = -1 );
+#endif // TQ_WS_X11
+
+ static void createDatabase();
+
+ static void parseFontName(const TQString &name, TQString &foundry, TQString &family);
+
+ friend struct TQFontDef;
+ friend class TQFontPrivate;
+ friend class TQFontDialog;
+ friend class TQFontEngineLatinXLFD;
+
+ TQFontDatabasePrivate *d;
+};
+
+
+#ifndef TQT_NO_COMPAT
+
+inline TQStringList TQFontDatabase::families( bool ) const
+{
+ return families();
+}
+
+inline TQStringList TQFontDatabase::styles( const TQString &family,
+ const TQString & ) const
+{
+ return styles(family);
+}
+
+inline TQValueList<int> TQFontDatabase::pointSizes( const TQString &family,
+ const TQString &style ,
+ const TQString & )
+{
+ return pointSizes(family, style);
+}
+
+inline TQValueList<int> TQFontDatabase::smoothSizes( const TQString &family,
+ const TQString &style,
+ const TQString & )
+{
+ return smoothSizes(family, style);
+}
+
+inline TQFont TQFontDatabase::font( const TQString &familyName,
+ const TQString &style,
+ int pointSize,
+ const TQString &)
+{
+ return font(familyName, style, pointSize);
+}
+
+inline bool TQFontDatabase::isBitmapScalable( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+{
+ return isBitmapScalable(family, style);
+}
+
+inline bool TQFontDatabase::isSmoothlyScalable( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+{
+ return isSmoothlyScalable(family, style);
+}
+
+inline bool TQFontDatabase::isScalable( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+{
+ return isScalable(family, style);
+}
+
+inline bool TQFontDatabase::isFixedPitch( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+{
+ return isFixedPitch(family, style);
+}
+
+inline bool TQFontDatabase::italic( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+{
+ return italic(family, style);
+}
+
+inline bool TQFontDatabase::bold( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+{
+ return bold(family, style);
+}
+
+inline int TQFontDatabase::weight( const TQString &family,
+ const TQString &style,
+ const TQString & ) const
+{
+ return weight(family, style);
+}
+
+#endif // TQT_NO_COMPAT
+
+#endif // USE_QT4
+
+#endif // TQT_NO_FONTDATABASE
+
+#endif // TQFONTDATABASE_H
diff --git a/tqtinterface/qt4/src/kernel/tqfontdatabase_x11.cpp b/tqtinterface/qt4/src/kernel/tqfontdatabase_x11.cpp
new file mode 100644
index 0000000..8ea403f
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfontdatabase_x11.cpp
@@ -0,0 +1,2008 @@
+/****************************************************************************
+**
+** Implementation of platform specific TQFontDatabase
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <tqplatformdefs.h>
+
+#include <tqdatetime.h>
+#include <tqpaintdevicemetrics.h>
+
+#include "tqt_x11_p.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#ifndef TQT_NO_XFTFREETYPE
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#endif
+
+#ifndef TQT_XFT2
+#define FcBool Bool
+#define FcTrue True
+#define FcFalse False
+#endif
+
+#ifdef TQFONTDATABASE_DEBUG
+# define FD_DEBUG qDebug
+#else
+# define FD_DEBUG if (FALSE) qDebug
+#endif // TQFONTDATABASE_DEBUG
+
+// from qfont_x11.cpp
+extern double qt_pointSize(double pixelSize, TQPaintDevice *painttqdevice, int screen);
+extern double qt_pixelSize(double pointSize, TQPaintDevice *painttqdevice, int screen);
+
+
+static inline void capitalize ( char *s )
+{
+ bool space = TRUE;
+ while( *s ) {
+ if ( space )
+ *s = toupper( *s );
+ space = ( *s == ' ' );
+ ++s;
+ }
+}
+
+
+// ----- begin of generated code -----
+
+#define make_tag( c1, c2, c3, c4 ) \
+( (((unsigned int)c1)<<24) | (((unsigned int)c2)<<16) | \
+(((unsigned int)c3)<<8) | ((unsigned int)c4) )
+
+struct XlfdEncoding {
+ const char *name;
+ int id;
+ int mib;
+ unsigned int hash1;
+ unsigned int hash2;
+};
+
+static const XlfdEncoding xlfd_encoding[] = {
+ { "iso8859-1", 0, 4, make_tag('i','s','o','8'), make_tag('5','9','-','1') },
+ { "iso8859-2", 1, 5, make_tag('i','s','o','8'), make_tag('5','9','-','2') },
+ { "iso8859-3", 2, 6, make_tag('i','s','o','8'), make_tag('5','9','-','3') },
+ { "iso8859-4", 3, 7, make_tag('i','s','o','8'), make_tag('5','9','-','4') },
+ { "iso8859-9", 4, 12, make_tag('i','s','o','8'), make_tag('5','9','-','9') },
+ { "iso8859-10", 5, 13, make_tag('i','s','o','8'), make_tag('9','-','1','0') },
+ { "iso8859-13", 6, 109, make_tag('i','s','o','8'), make_tag('9','-','1','3') },
+ { "iso8859-14", 7, 110, make_tag('i','s','o','8'), make_tag('9','-','1','4') },
+ { "iso8859-15", 8, 111, make_tag('i','s','o','8'), make_tag('9','-','1','5') },
+ { "hp-roman8", 9, 2004, make_tag('h','p','-','r'), make_tag('m','a','n','8') },
+ { "jisx0208*-0", 10, 63, make_tag('j','i','s','x'), 0 },
+#define LAST_LATIN_ENCODING 10
+ { "iso8859-5", 11, 8, make_tag('i','s','o','8'), make_tag('5','9','-','5') },
+ { "*-cp1251", 12, 2251, 0, make_tag('1','2','5','1') },
+ { "koi8-ru", 13, 2084, make_tag('k','o','i','8'), make_tag('8','-','r','u') },
+ { "koi8-u", 14, 2088, make_tag('k','o','i','8'), make_tag('i','8','-','u') },
+ { "koi8-r", 15, 2084, make_tag('k','o','i','8'), make_tag('i','8','-','r') },
+ { "iso8859-7", 16, 10, make_tag('i','s','o','8'), make_tag('5','9','-','7') },
+ { "iso10646-1", 17, 0, make_tag('i','s','o','1'), make_tag('4','6','-','1') },
+ { "iso8859-8", 18, 85, make_tag('i','s','o','8'), make_tag('5','9','-','8') },
+ { "gb18030-0", 19, -114, make_tag('g','b','1','8'), make_tag('3','0','-','0') },
+ { "gb18030.2000-0", 20, -113, make_tag('g','b','1','8'), make_tag('0','0','-','0') },
+ { "gbk-0", 21, -113, make_tag('g','b','k','-'), make_tag('b','k','-','0') },
+ { "gb2312.*-0", 22, 57, make_tag('g','b','2','3'), 0 },
+ { "jisx0201*-0", 23, 15, make_tag('j','i','s','x'), 0 },
+ { "ksc5601*-*", 24, 36, make_tag('k','s','c','5'), 0 },
+ { "big5hkscs-0", 25, -2101, make_tag('b','i','g','5'), make_tag('c','s','-','0') },
+ { "hkscs-1", 26, -2101, make_tag('h','k','s','c'), make_tag('c','s','-','1') },
+ { "big5*-*", 27, -2026, make_tag('b','i','g','5'), 0 },
+ { "tscii-*", 28, 2028, make_tag('t','s','c','i'), 0 },
+ { "tis620*-*", 29, 2259, make_tag('t','i','s','6'), 0 },
+ { "iso8859-11", 30, 2259, make_tag('i','s','o','8'), make_tag('9','-','1','1') },
+ { "mulelao-1", 31, -4242, make_tag('m','u','l','e'), make_tag('a','o','-','1') },
+ { "ethiopic-tqunicode", 32, 0, make_tag('e','t','h','i'), make_tag('c','o','d','e') },
+ { "tqunicode-*", 33, 0, make_tag('u','n','i','c'), 0 },
+ { "*-symbol", 34, 0, 0, make_tag('m','b','o','l') },
+ { "*-fontspecific", 35, 0, 0, make_tag('i','f','i','c') },
+ { "fontspecific-*", 36, 0, make_tag('f','o','n','t'), 0 },
+ { 0, 0, 0, 0, 0 }
+};
+
+static const char scripts_for_xlfd_encoding[37][61] = {
+ // iso8859-1
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-2
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-3
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-4
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-9
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-10
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-13
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-14
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-15
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // hp-roman8
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // jisx0208*-0
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0 },
+ // iso8859-5
+ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // *-cp1251
+ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // koi8-ru
+ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // koi8-u
+ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // koi8-r
+ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-7
+ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso10646-1
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-8
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // gb18030-0
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0 },
+ // gb18030.2000-0
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0 },
+ // gbk-0
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0 },
+ // gb2312.*-0
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0 },
+ // jisx0201*-0
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // ksc5601*-*
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1 },
+ // big5hkscs-0
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0 },
+ // hkscs-1
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0 },
+ // big5*-*
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 0 },
+ // tscii-*
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // tis620*-*
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // iso8859-11
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // mulelao-1
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // ethiopic-tqunicode
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // tqunicode-*
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0 },
+ // *-symbol
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+ 0 },
+ // *-fontspecific
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+ 0 },
+ // fontspecific-*
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
+ 0 }
+
+};
+
+// ----- end of generated code -----
+
+
+const int numEncodings = sizeof( xlfd_encoding ) / sizeof( XlfdEncoding ) - 1;
+
+int qt_xlfd_encoding_id( const char *encoding )
+{
+ // qDebug("looking for encoding id for '%s'", encoding );
+ int len = strlen( encoding );
+ if ( len < 4 )
+ return -1;
+ unsigned int hash1 = make_tag( encoding[0], encoding[1], encoding[2], encoding[3] );
+ const char *ch = encoding + len - 4;
+ unsigned int hash2 = make_tag( ch[0], ch[1], ch[2], ch[3] );
+
+ const XlfdEncoding *enc = xlfd_encoding;
+ for ( ; enc->name; ++enc ) {
+ if ( (enc->hash1 && enc->hash1 != hash1) ||
+ (enc->hash2 && enc->hash2 != hash2) )
+ continue;
+ // hashes match, do a compare if strings match
+ // the enc->name can contain '*'s we have to interpret correctly
+ const char *n = enc->name;
+ const char *e = encoding;
+ while ( 1 ) {
+ // qDebug("bol: *e='%c', *n='%c'", *e, *n );
+ if ( *e == '\0' ) {
+ if ( *n )
+ break;
+ // qDebug( "found encoding id %d", enc->id );
+ return enc->id;
+ }
+ if ( *e == *n ) {
+ ++e;
+ ++n;
+ continue;
+ }
+ if ( *n != '*' )
+ break;
+ ++n;
+ // qDebug("skip: *e='%c', *n='%c'", *e, *n );
+ while ( *e && *e != *n )
+ ++e;
+ }
+ }
+ // qDebug( "couldn't tqfind encoding %s", encoding );
+ return -1;
+}
+
+int qt_mib_for_xlfd_encoding( const char *encoding )
+{
+ int id = qt_xlfd_encoding_id( encoding );
+ if ( id != -1 ) return xlfd_encoding[id].mib;
+ return 0;
+}
+
+int qt_encoding_id_for_mib( int mib )
+{
+ const XlfdEncoding *enc = xlfd_encoding;
+ for ( ; enc->name; ++enc ) {
+ if ( enc->mib == mib )
+ return enc->id;
+ }
+ return -1;
+}
+
+static const char * xlfd_for_id( int id )
+{
+ // special case: -1 returns the "*-*" encoding, allowing us to do full
+ // database population in a single X server round trip.
+ if ( id < 0 || id > numEncodings )
+ return "*-*";
+ return xlfd_encoding[id].name;
+}
+
+enum XLFDFieldNames {
+ Foundry,
+ Family,
+ Weight,
+ Slant,
+ Width,
+ AddStyle,
+ PixelSize,
+ PointSize,
+ ResolutionX,
+ ResolutionY,
+ Spacing,
+ AverageWidth,
+ CharsetRegistry,
+ CharsetEncoding,
+ NFontFields
+};
+
+// Splits an X font name into fields separated by '-'
+static bool parseXFontName( char *fontName, char **tokens )
+{
+ if ( ! fontName || fontName[0] == '0' || fontName[0] != '-' ) {
+ tokens[0] = 0;
+ return FALSE;
+ }
+
+ int i;
+ ++fontName;
+ for ( i = 0; i < NFontFields && fontName && fontName[0]; ++i ) {
+ tokens[i] = fontName;
+ for ( ;; ++fontName ) {
+ if ( *fontName == '-' )
+ break;
+ if ( ! *fontName ) {
+ fontName = 0;
+ break;
+ }
+ }
+
+ if ( fontName ) *fontName++ = '\0';
+ }
+
+ if ( i < NFontFields ) {
+ for ( int j = i ; j < NFontFields; ++j )
+ tokens[j] = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static inline bool isZero(char *x)
+{
+ return (x[0] == '0' && x[1] == 0);
+}
+
+static inline bool isScalable( char **tokens )
+{
+ return (isZero(tokens[PixelSize]) &&
+ isZero(tokens[PointSize]) &&
+ isZero(tokens[AverageWidth]));
+}
+
+static inline bool isSmoothlyScalable( char **tokens )
+{
+ return (isZero(tokens[ResolutionX]) &&
+ isZero(tokens[ResolutionY]));
+}
+
+static inline bool isFixedPitch( char **tokens )
+{
+ return (tokens[Spacing][0] == 'm' ||
+ tokens[Spacing][0] == 'c' ||
+ tokens[Spacing][0] == 'M' ||
+ tokens[Spacing][0] == 'C');
+}
+
+/*
+ Fills in a font definition (TQFontDef) from an XLFD (X Logical Font
+ Description).
+
+ Returns TRUE if the the given xlfd is valid. The fields lbearing
+ and rbearing are not given any values.
+*/
+bool qt_fillFontDef( const TQCString &xlfd, TQFontDef *fd, int screen )
+{
+ char *tokens[NFontFields];
+ TQCString buffer = xlfd.copy();
+ if ( ! parseXFontName(buffer.data(), tokens) )
+ return FALSE;
+
+ capitalize(tokens[Family]);
+ capitalize(tokens[Foundry]);
+
+ fd->family = TQString::tqfromLatin1(tokens[Family]);
+ TQString foundry = TQString::tqfromLatin1(tokens[Foundry]);
+ if ( ! foundry.isEmpty() && foundry != TQString::tqfromLatin1("*") )
+ fd->family +=
+ TQString::tqfromLatin1(" [") + foundry + TQString::tqfromLatin1("]");
+
+ if ( tqstrlen( tokens[AddStyle] ) > 0 )
+ fd->addStyle = TQString::tqfromLatin1(tokens[AddStyle]);
+ else
+ fd->addStyle = TQString::null;
+
+ fd->pointSize = atoi(tokens[PointSize]);
+ fd->tqstyleHint = TQFont::AnyStyle; // ### any until we match families
+
+ char slant = tolower( (uchar) tokens[Slant][0] );
+ fd->italic = ( slant == 'o' || slant == 'i' );
+ char fixed = tolower( (uchar) tokens[Spacing][0] );
+ fd->fixedPitch = ( fixed == 'm' || fixed == 'c' );
+ fd->weight = getFontWeight( tokens[Weight] );
+
+ int r = atoi(tokens[ResolutionY]);
+ fd->pixelSize = atoi(tokens[PixelSize]);
+ // not "0" or "*", or required DPI
+ if ( r && fd->pixelSize && TQPaintDevice::x11AppDpiY( screen ) &&
+ r != TQPaintDevice::x11AppDpiY( screen ) ) {
+ // calculate actual pointsize for display DPI
+ fd->pointSize = tqRound(qt_pointSize(fd->pixelSize, 0, screen) * 10.);
+ } else if ( fd->pixelSize == 0 && fd->pointSize ) {
+ // calculate pixel size from pointsize/dpi
+ fd->pixelSize = tqRound(qt_pixelSize(fd->pointSize / 10., 0, screen));
+ }
+
+ return TRUE;
+}
+
+/*
+ Fills in a font definition (TQFontDef) from the font properties in an
+ XFontStruct.
+
+ Returns TRUE if the TQFontDef could be filled with properties from
+ the XFontStruct. The fields lbearing and rbearing are not given any
+ values.
+*/
+static bool qt_fillFontDef( XFontStruct *fs, TQFontDef *fd, int screen )
+{
+ unsigned long value;
+ if ( fs && !XGetFontProperty( fs, XA_FONT, &value ) )
+ return FALSE;
+
+ char *n = XGetAtomName( TQPaintDevice::x11AppDisplay(), value );
+ TQCString xlfd( n );
+ if ( n )
+ XFree( n );
+ return qt_fillFontDef( xlfd.lower(), fd, screen );
+}
+
+
+static TQtFontStyle::Key getStyle( char ** tokens )
+{
+ TQtFontStyle::Key key;
+
+ char slant0 = tolower( (uchar) tokens[Slant][0] );
+
+ if ( slant0 == 'r' ) {
+ if ( tokens[Slant][1]) {
+ char slant1 = tolower( (uchar) tokens[Slant][1] );
+
+ if ( slant1 == 'o' )
+ key.oblique = TRUE;
+ else if ( slant1 == 'i' )
+ key.italic = TRUE;
+ }
+ } else if ( slant0 == 'o' )
+ key.oblique = TRUE;
+ else if ( slant0 == 'i' )
+ key.italic = TRUE;
+
+ key.weight = getFontWeight( tokens[Weight] );
+
+ if ( qstrcmp( tokens[Width], "normal" ) == 0 ) {
+ key.stretch = 100;
+ } else if ( qstrcmp( tokens[Width], "semi condensed" ) == 0 ||
+ qstrcmp( tokens[Width], "semicondensed" ) == 0 ) {
+ key.stretch = 90;
+ } else if ( qstrcmp( tokens[Width], "condensed" ) == 0 ) {
+ key.stretch = 80;
+ } else if ( qstrcmp( tokens[Width], "narrow" ) == 0 ) {
+ key.stretch = 60;
+ }
+
+ return key;
+}
+
+
+extern bool qt_has_xft; // defined in qfont_x11.cpp
+
+static bool xlfdsFullyLoaded = FALSE;
+static unsigned char encodingLoaded[numEncodings];
+
+static void loadXlfds( const char *reqFamily, int encoding_id )
+{
+ TQtFontFamily *fontFamily = reqFamily ? db->family( reqFamily ) : 0;
+
+ // make sure we don't load twice
+ if ( (encoding_id == -1 && xlfdsFullyLoaded) || (encoding_id != -1 && encodingLoaded[encoding_id]) )
+ return;
+ if ( fontFamily && fontFamily->xlfdLoaded )
+ return;
+
+ int fontCount;
+ // force the X server to give us XLFDs
+ TQCString xlfd_pattern = "-*-";
+ xlfd_pattern += reqFamily ? reqFamily : "*";
+ xlfd_pattern += "-*-*-*-*-*-*-*-*-*-*-";
+ xlfd_pattern += xlfd_for_id( encoding_id );
+
+ char **fontList = XListFonts( TQPaintDevice::x11AppDisplay(),
+ xlfd_pattern.data(),
+ 0xffff, &fontCount );
+ // qDebug("requesting xlfd='%s', got %d fonts", xlfd_pattern.data(), fontCount );
+
+
+ char *tokens[NFontFields];
+
+ for( int i = 0 ; i < fontCount ; i++ ) {
+ if ( ! parseXFontName( fontList[i], tokens ) ) continue;
+
+ // get the encoding_id for this xlfd. we need to do this
+ // here, since we can pass -1 to this function to do full
+ // database population
+ *(tokens[CharsetEncoding]-1) = '-';
+ int encoding_id = qt_xlfd_encoding_id( tokens[CharsetRegistry] );
+ if ( encoding_id == -1 )
+ continue;
+
+ char *familyName = tokens[Family];
+ capitalize( familyName );
+ char *foundryName = tokens[Foundry];
+ capitalize( foundryName );
+ TQtFontStyle::Key styleKey = getStyle( tokens );
+
+ bool smooth_scalable = FALSE;
+ bool bitmap_scalable = FALSE;
+ if ( isScalable(tokens) ) {
+ if ( isSmoothlyScalable( tokens ) )
+ smooth_scalable = TRUE;
+ else
+ bitmap_scalable = TRUE;
+ }
+ uint pixelSize = atoi( tokens[PixelSize] );
+ uint xpointSize = atoi( tokens[PointSize] );
+ uint xres = atoi( tokens[ResolutionX] );
+ uint yres = atoi( tokens[ResolutionY] );
+ uint avgwidth = atoi( tokens[AverageWidth] );
+ bool fixedPitch = isFixedPitch( tokens );
+
+ if (avgwidth == 0 && pixelSize != 0) {
+ /*
+ Ignore bitmap scalable fonts that are automatically
+ generated by some X servers. We know they are bitmap
+ scalable because even though they have a specified pixel
+ size, the average width is zero.
+ */
+ continue;
+ }
+
+ TQtFontFamily *family = fontFamily ? fontFamily : db->family( familyName, TRUE );
+ family->fontFileIndex = -1;
+ TQtFontFoundry *foundry = family->foundry( foundryName, TRUE );
+ TQtFontStyle *style = foundry->style( styleKey, TRUE );
+
+ delete [] style->weightName;
+ style->weightName = qstrdup( tokens[Weight] );
+ delete [] style->setwidthName;
+ style->setwidthName = qstrdup( tokens[Width] );
+
+ if ( smooth_scalable ) {
+ style->smoothScalable = TRUE;
+ style->bitmapScalable = FALSE;
+ pixelSize = SMOOTH_SCALABLE;
+ }
+ if ( !style->smoothScalable && bitmap_scalable )
+ style->bitmapScalable = TRUE;
+ if ( !fixedPitch )
+ family->fixedPitch = FALSE;
+
+ TQtFontSize *size = style->pixelSize( pixelSize, TRUE );
+ TQtFontEncoding *enc =
+ size->encodingID( encoding_id, xpointSize, xres, yres, avgwidth, TRUE );
+ enc->pitch = *tokens[Spacing];
+ if ( !enc->pitch ) enc->pitch = '*';
+
+ for ( int script = 0; script < TQFont::LastPrivateScript; ++script ) {
+ if ( scripts_for_xlfd_encoding[encoding_id][script] )
+ family->scripts[script] = TQtFontFamily::Supported;
+ else
+ family->scripts[script] |= TQtFontFamily::UnSupported_Xlfd;
+ }
+ if ( encoding_id == -1 )
+ family->xlfdLoaded = TRUE;
+ }
+ if ( !reqFamily ) {
+ // mark encoding as loaded
+ if ( encoding_id == -1 )
+ xlfdsFullyLoaded = TRUE;
+ else
+ encodingLoaded[encoding_id] = TRUE;
+ }
+
+ XFreeFontNames( fontList );
+}
+
+
+#ifndef TQT_NO_XFTFREETYPE
+static int getXftWeight(int xftweight)
+{
+ int qtweight = TQFont::Black;
+ if (xftweight <= (XFT_WEIGHT_LIGHT + XFT_WEIGHT_MEDIUM) / 2)
+ qtweight = TQFont::Light;
+ else if (xftweight <= (XFT_WEIGHT_MEDIUM + XFT_WEIGHT_DEMIBOLD) / 2)
+ qtweight = TQFont::Normal;
+ else if (xftweight <= (XFT_WEIGHT_DEMIBOLD + XFT_WEIGHT_BOLD) / 2)
+ qtweight = TQFont::DemiBold;
+ else if (xftweight <= (XFT_WEIGHT_BOLD + XFT_WEIGHT_BLACK) / 2)
+ qtweight = TQFont::Bold;
+
+ return qtweight;
+}
+
+static void loadXft()
+{
+ if (!qt_has_xft)
+ return;
+
+#ifdef TQT_XFT2
+ struct XftDefaultFont {
+ const char *qtname;
+ const char *rawname;
+ bool fixed;
+ };
+ const XftDefaultFont defaults[] = {
+ { "Serif", "serif", FALSE },
+ { "Sans Serif", "sans-serif", FALSE },
+ { "Monospace", "monospace", TRUE },
+ { 0, 0, FALSE }
+ };
+ const XftDefaultFont *f = defaults;
+ while (f->qtname) {
+ TQtFontFamily *family = db->family( f->qtname, TRUE );
+ family->fixedPitch = f->fixed;
+ family->rawName = f->rawname;
+ family->hasXft = TRUE;
+ family->synthetic = TRUE;
+ TQtFontFoundry *foundry
+ = family->foundry( TQString::null, TRUE );
+
+ for ( int i = 0; i < TQFont::LastPrivateScript; ++i ) {
+ if (i == TQFont::UnknownScript)
+ continue;
+ family->scripts[i] = TQtFontFamily::Supported;
+ }
+
+ TQtFontStyle::Key styleKey;
+ styleKey.oblique = FALSE;
+ for (int i = 0; i < 4; ++i) {
+ styleKey.italic = (i%2);
+ styleKey.weight = (i > 1) ? TQFont::Bold : TQFont::Normal;
+ TQtFontStyle *style = foundry->style( styleKey, TRUE );
+ style->smoothScalable = TRUE;
+ TQtFontSize *size = style->pixelSize( SMOOTH_SCALABLE, TRUE );
+ TQtFontEncoding *enc = size->encodingID( -1, 0, 0, 0, 0, TRUE );
+ enc->pitch = (f->fixed ? 'm' : 'p');
+ }
+ ++f;
+ }
+#endif
+}
+
+#ifdef XFT_MATRIX
+static void checkXftMatrix( TQtFontFamily* family ) {
+ for ( int j = 0; j < family->count; ++j ) { // each foundry
+ TQtFontFoundry *foundry = family->foundries[j];
+ for ( int k = 0; k < foundry->count; ++k ) {
+ TQtFontStyle *style = foundry->styles[k];
+ if ( style->key.italic || style->key.oblique ) continue;
+
+ TQtFontSize *size = style->pixelSize( SMOOTH_SCALABLE );
+ if ( ! size ) continue;
+ TQtFontEncoding *enc = size->encodingID( -1, 0, 0, 0, 0, TRUE );
+ if ( ! enc ) continue;
+
+ TQtFontStyle::Key key = style->key;
+
+ // does this style have an italic equivalent?
+ key.italic = TRUE;
+ TQtFontStyle *equiv = foundry->style( key );
+ if ( equiv ) continue;
+
+ // does this style have an oblique equivalent?
+ key.italic = FALSE;
+ key.oblique = TRUE;
+ equiv = foundry->style( key );
+ if ( equiv ) continue;
+
+ // let's fake one...
+ equiv = foundry->style( key, TRUE );
+ equiv->fakeOblique = TRUE;
+ equiv->smoothScalable = TRUE;
+
+ TQtFontSize *equiv_size = equiv->pixelSize( SMOOTH_SCALABLE, TRUE );
+ TQtFontEncoding *equiv_enc = equiv_size->encodingID( -1, 0, 0, 0, 0, TRUE );
+
+ // keep the same pitch
+ equiv_enc->pitch = enc->pitch;
+ }
+ }
+}
+#endif // XFT_MATRIX
+
+static bool loadXftFont( FcPattern* font )
+{
+ TQString familyName;
+ TQString rawName;
+ char *value;
+ int weight_value;
+ int slant_value;
+ int spacing_value;
+ char *file_value;
+ int index_value;
+ char *foundry_value = 0;
+ FcBool scalable = FcTrue;
+
+ if (XftPatternGetString( font,
+ XFT_FAMILY, 0, &value) != XftResultMatch )
+ return false;
+ // capitalize( value );
+ rawName = familyName = TQString::fromUtf8(value);
+ familyName.tqreplace('-', ' ');
+ familyName.tqreplace("/", "");
+
+ slant_value = XFT_SLANT_ROMAN;
+ weight_value = XFT_WEIGHT_MEDIUM;
+ spacing_value = XFT_PROPORTIONAL;
+ file_value = 0;
+ index_value = 0;
+ XftPatternGetInteger (font, XFT_SLANT, 0, &slant_value);
+ XftPatternGetInteger (font, XFT_WEIGHT, 0, &weight_value);
+ XftPatternGetInteger (font, XFT_SPACING, 0, &spacing_value);
+ XftPatternGetString (font, XFT_FILE, 0, &file_value);
+ XftPatternGetInteger (font, XFT_INDEX, 0, &index_value);
+#ifdef TQT_XFT2
+ FcPatternGetBool(font, FC_SCALABLE, 0, &scalable);
+ foundry_value = 0;
+ XftPatternGetString(font, FC_FOUNDRY, 0, &foundry_value);
+#endif
+ TQtFontFamily *family = db->family( familyName, TRUE );
+ family->rawName = rawName;
+ family->hasXft = TRUE;
+
+#ifdef TQT_XFT2
+ FcCharSet *charset = 0;
+ FcResult res = FcPatternGetCharSet(font, FC_CHARSET, 0, &charset);
+ if (res == FcResultMatch && FcCharSetCount(charset) > 1) {
+ for (int i = 0; i < TQFont::LastPrivateScript; ++i) {
+ bool supported = sample_chars[i][0];
+ for (int j = 0; sample_chars[i][j]; ++j){
+ if (!FcCharSetHasChar(charset, sample_chars[i][j])) {
+ supported = false;
+ break;
+ }
+ }
+ if ( supported ){
+ family->scripts[i] = TQtFontFamily::Supported;
+ } else {
+ family->scripts[i] |= TQtFontFamily::UnSupported_Xft;
+ }
+ }
+ family->xftScriptCheck = TRUE;
+ } else {
+ // we set UnknownScript to supported for symbol fonts. It makes no sense to merge these
+ // with other ones, as they are special in a way.
+ for ( int i = 0; i < TQFont::LastPrivateScript; ++i )
+ family->scripts[i] |= TQtFontFamily::UnSupported_Xft;
+ family->scripts[TQFont::UnknownScript] = TQtFontFamily::Supported;
+ }
+#endif // TQT_XFT2
+
+ TQCString file = (file_value ? file_value : "");
+ family->fontFilename = file;
+ family->fontFileIndex = index_value;
+
+ TQtFontStyle::Key styleKey;
+ styleKey.italic = (slant_value == XFT_SLANT_ITALIC);
+ styleKey.oblique = (slant_value == XFT_SLANT_OBLIQUE);
+ styleKey.weight = getXftWeight( weight_value );
+#ifdef TQT_XFT2
+ if (!scalable) {
+ int width = 100;
+#if FC_VERSION >= 20193
+ XftPatternGetInteger (font, FC_WIDTH, 0, &width);
+#endif
+ styleKey.stretch = width;
+ }
+#endif
+
+ TQtFontFoundry *foundry
+ = family->foundry( foundry_value ? TQString::fromUtf8(foundry_value) : TQString::null, TRUE );
+ TQtFontStyle *style = foundry->style( styleKey, TRUE );
+
+ if (spacing_value < XFT_MONO )
+ family->fixedPitch = FALSE;
+
+ TQtFontSize *size;
+ if (scalable) {
+ style->smoothScalable = TRUE;
+ size = style->pixelSize( SMOOTH_SCALABLE, TRUE );
+ }
+#ifdef TQT_XFT2
+ else {
+ double pixel_size = 0;
+ XftPatternGetDouble (font, FC_PIXEL_SIZE, 0, &pixel_size);
+ size = style->pixelSize( (int)pixel_size, TRUE );
+ }
+#endif
+ TQtFontEncoding *enc = size->encodingID( -1, 0, 0, 0, 0, TRUE );
+ enc->pitch = ( spacing_value >= XFT_CHARCELL ? 'c' :
+ ( spacing_value >= XFT_MONO ? 'm' : 'p' ) );
+
+ checkXftMatrix( family );
+
+ return true;
+}
+
+#ifndef TQT_XFT2
+
+#define MAKE_TAG( _x1, _x2, _x3, _x4 ) \
+ ( ( (TQ_UINT32)_x1 << 24 ) | \
+ ( (TQ_UINT32)_x2 << 16 ) | \
+ ( (TQ_UINT32)_x3 << 8 ) | \
+ (TQ_UINT32)_x4 )
+
+#ifdef _POSIX_MAPPED_FILES
+static inline TQ_UINT32 getUInt(unsigned char *p)
+{
+ TQ_UINT32 val;
+ val = *p++ << 24;
+ val |= *p++ << 16;
+ val |= *p++ << 8;
+ val |= *p;
+
+ return val;
+}
+
+static inline TQ_UINT16 getUShort(unsigned char *p)
+{
+ TQ_UINT16 val;
+ val = *p++ << 8;
+ val |= *p;
+
+ return val;
+}
+
+static inline void tag_to_string( char *string, TQ_UINT32 tag )
+{
+ string[0] = (tag >> 24)&0xff;
+ string[1] = (tag >> 16)&0xff;
+ string[2] = (tag >> 8)&0xff;
+ string[3] = tag&0xff;
+ string[4] = 0;
+}
+
+static TQ_UINT16 getGlyphIndex( unsigned char *table, TQ_UINT16 format, unsigned short tqunicode )
+{
+ if ( format == 0 ) {
+ if ( tqunicode < 256 )
+ return (int) *(table+6+tqunicode);
+ } else if ( format == 2 ) {
+ qWarning("format 2 encoding table for Unicode, not implemented!");
+ } else if ( format == 4 ) {
+ TQ_UINT16 segCountX2 = getUShort( table + 6 );
+ unsigned char *ends = table + 14;
+ TQ_UINT16 endIndex = 0;
+ int i = 0;
+ for ( ; i < segCountX2/2 && (endIndex = getUShort( ends + 2*i )) < tqunicode; i++ );
+
+ unsigned char *idx = ends + segCountX2 + 2 + 2*i;
+ TQ_UINT16 startIndex = getUShort( idx );
+
+ if ( startIndex > tqunicode )
+ return 0;
+
+ idx += segCountX2;
+ TQ_INT16 idDelta = (TQ_INT16)getUShort( idx );
+ idx += segCountX2;
+ TQ_UINT16 idRangeoffset_t = (TQ_UINT16)getUShort( idx );
+
+ TQ_UINT16 glyphIndex;
+ if ( idRangeoffset_t ) {
+ TQ_UINT16 id = getUShort( idRangeoffset_t + 2*(tqunicode - startIndex) + idx);
+ if ( id )
+ glyphIndex = ( idDelta + id ) % 0x10000;
+ else
+ glyphIndex = 0;
+ } else {
+ glyphIndex = (idDelta + tqunicode) % 0x10000;
+ }
+ return glyphIndex;
+ }
+
+ return 0;
+}
+#endif // _POSIX_MAPPED_FILES
+
+static inline void checkXftCoverage( TQtFontFamily *family )
+{
+#ifdef _POSIX_MAPPED_FILES
+ TQCString ext = family->fontFilename.mid( family->fontFilename.tqfindRev( '.' ) ).lower();
+ if ( family->fontFileIndex == 0 && ( ext == ".ttf" || ext == ".otf" ) ) {
+ void *map;
+ // qDebug("using own ttf code coverage checking of '%s'!", family->name.latin1() );
+ int fd = open( family->fontFilename.data(), O_RDONLY );
+ size_t pagesize = getpagesize();
+ off_t offset = 0;
+ size_t length = (8192 / pagesize + 1) * pagesize;
+
+ if ( fd == -1 )
+ goto xftCheck;
+ {
+ if ( (map = mmap( 0, length, PROT_READ, MAP_SHARED, fd, offset ) ) == MAP_FAILED )
+ goto error;
+
+ unsigned char *ttf = (unsigned char *)map;
+ TQ_UINT32 version = getUInt( ttf );
+ if ( version != 0x00010000 ) {
+ // qDebug("file has wrong version %x", version );
+ goto error1;
+ }
+ TQ_UINT16 numTables = getUShort( ttf+4 );
+
+ unsigned char *table_dir = ttf + 12;
+ TQ_UINT32 cmap_offset = 0;
+ TQ_UINT32 cmap_length = 0;
+ for ( int n = 0; n < numTables; n++ ) {
+ TQ_UINT32 tag = getUInt( table_dir + 16*n );
+ if ( tag == MAKE_TAG( 'c', 'm', 'a', 'p' ) ) {
+ cmap_offset = getUInt( table_dir + 16*n + 8 );
+ cmap_length = getUInt( table_dir + 16*n + 12 );
+ break;
+ }
+ }
+ if ( !cmap_offset ) {
+ // qDebug("no cmap found" );
+ goto error1;
+ }
+
+ if ( cmap_offset + cmap_length > length ) {
+ munmap( map, length );
+ offset = cmap_offset / pagesize * pagesize;
+ cmap_offset -= offset;
+ length = (cmap_offset + cmap_length);
+ if ( (map = mmap( 0, length, PROT_READ, MAP_SHARED, fd, offset ) ) == MAP_FAILED )
+ goto error;
+ }
+
+ unsigned char *cmap = ((unsigned char *)map) + cmap_offset;
+
+ version = getUShort( cmap );
+ if ( version != 0 ) {
+ // qDebug("wrong cmap version" );
+ goto error1;
+ }
+ numTables = getUShort( cmap + 2 );
+ unsigned char *tqunicode_table = 0;
+ bool symbol_table = TRUE;
+ for ( int n = 0; n < numTables; n++ ) {
+ TQ_UINT32 version = getUInt( cmap + 4 + 8*n );
+ // accept both symbol and Unicode encodings. prefer tqunicode.
+ if ( version == 0x00030001 || version == 0x00030000 ) {
+ tqunicode_table = cmap + getUInt( cmap + 4 + 8*n + 4 );
+ if ( version == 0x00030001 ) {
+ symbol_table = FALSE;
+ break;
+ }
+ }
+ }
+
+ if ( !tqunicode_table ) {
+ // qDebug("no tqunicode table found" );
+ goto error1;
+ }
+
+ TQ_UINT16 format = getUShort( tqunicode_table );
+ if ( format != 4 )
+ goto error1;
+
+ if (symbol_table) {
+ // we set UnknownScript to supported for symbol fonts. It makes no sense to merge these
+ // with other ones, as they are special in a way.
+ for ( int i = 0; i < TQFont::LastPrivateScript; ++i )
+ family->scripts[i] |= TQtFontFamily::UnSupported_Xft;
+ family->scripts[TQFont::UnknownScript] = TQtFontFamily::Supported;
+ } else {
+ for ( int i = 0; i < TQFont::LastPrivateScript; ++i ) {
+
+ bool supported = sample_chars[i][0];
+ for (int j = 0; sample_chars[i][j]; ++j) {
+ if (!getGlyphIndex(tqunicode_table, format, sample_chars[i][j])) {
+ supported=false;
+ break;
+ }
+ }
+ if ( supported ){
+ // qDebug("font can render script %d", i );
+ family->scripts[i] = TQtFontFamily::Supported;
+ } else {
+ family->scripts[i] |= TQtFontFamily::UnSupported_Xft;
+ }
+ }
+ }
+ family->xftScriptCheck = TRUE;
+ }
+ error1:
+ munmap( map, length );
+ error:
+ close( fd );
+ if ( family->xftScriptCheck )
+ return;
+ }
+ xftCheck:
+#endif // _POSIX_MAPPED_FILES
+
+ FD_DEBUG("using Freetype for checking of '%s'", family->name.latin1() );
+
+ FT_Library ft_lib;
+ FT_Error error = FT_Init_FreeType( &ft_lib );
+ if ( error ) return;
+ FT_Face face;
+ error = FT_New_Face( ft_lib, family->fontFilename, family->fontFileIndex, &face );
+ if ( error ) return;
+
+ for ( int i = 0; i < TQFont::LastPrivateScript; ++i ) {
+ bool supported = sample_chars[i][j];
+ for (int j = 0; sample_chars[i][j]; ++j){
+ if (!FT_Get_Char_Index(face, sample_chars[i][j])) {
+ supported=false;
+ break;
+ }
+ }
+ if ( supported ){
+ FD_DEBUG("font can render char %04x, %04x script %d '%s'",
+ ch.tqunicode(), FT_Get_Char_Index ( face, ch.tqunicode() ),
+ i, TQFontDatabase::scriptName( (TQFont::Script)i ).latin1() );
+
+ family->scripts[i] = TQtFontFamily::Supported;
+ } else {
+ family->scripts[i] |= TQtFontFamily::UnSupported_Xft;
+ }
+ }
+ FT_Done_Face( face );
+ FT_Done_FreeType( ft_lib );
+ family->xftScriptCheck = TRUE;
+}
+#endif // TQT_XFT2
+#endif // TQT_NO_XFTFREETYPE
+
+static void load( const TQString &family = TQString::null, int script = -1 )
+{
+#ifdef TQFONTDATABASE_DEBUG
+ TQTime t;
+ t.start();
+#endif
+
+ if ( family.isNull() ) {
+#ifndef TQT_NO_XFTFREETYPE
+ static bool xft_readall_done = false;
+ if (qt_has_xft && !xft_readall_done) {
+ xft_readall_done = true;
+ XftFontSet *fonts =
+ XftListFonts(TQPaintDevice::x11AppDisplay(),
+ TQPaintDevice::x11AppScreen(),
+ (const char *)0,
+ XFT_FAMILY, XFT_WEIGHT, XFT_SLANT,
+ XFT_SPACING, XFT_FILE, XFT_INDEX,
+#ifdef TQT_XFT2
+ FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
+#if FC_VERSION >= 20193
+ FC_WIDTH,
+#endif
+#endif // TQT_XFT2
+ (const char *)0);
+ for (int i = 0; i < fonts->nfont; i++)
+ loadXftFont( fonts->fonts[i] );
+ XftFontSetDestroy (fonts);
+ }
+#ifdef TQT_XFT2
+ if (qt_has_xft)
+ return;
+#endif
+#endif // TQT_NO_XFTFREETYPE
+ if ( script == -1 )
+ loadXlfds( 0, -1 );
+ else {
+ for ( int i = 0; i < numEncodings; i++ ) {
+ if ( scripts_for_xlfd_encoding[i][script] )
+ loadXlfds( 0, i );
+ }
+ }
+ } else {
+ TQtFontFamily *f = db->family( family, TRUE );
+ if ( !f->fullyLoaded ) {
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (qt_has_xft) {
+ TQString mfamily = family;
+ redo:
+ XftFontSet *fonts =
+ XftListFonts(TQPaintDevice::x11AppDisplay(),
+ TQPaintDevice::x11AppScreen(),
+ XFT_FAMILY, XftTypeString, mfamily.utf8().data(),
+ (const char *)0,
+ XFT_FAMILY, XFT_WEIGHT, XFT_SLANT,
+ XFT_SPACING, XFT_FILE, XFT_INDEX,
+#ifdef TQT_XFT2
+ FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE,
+#if FC_VERSION >= 20193
+ FC_WIDTH,
+#endif
+#endif // TQT_XFT2
+ (const char *)0);
+ for (int i = 0; i < fonts->nfont; i++)
+ loadXftFont( fonts->fonts[i] );
+ XftFontSetDestroy (fonts);
+ if (mfamily.tqcontains(' ')) {
+ mfamily.tqreplace(TQChar(' '), TQChar('-'));
+ goto redo;
+ }
+ f->fullyLoaded = TRUE;
+#ifdef TQT_XFT2
+ return;
+#endif
+ }
+#ifndef TQT_XFT2
+ // need to check Xft coverage
+ if ( f->hasXft && !f->xftScriptCheck ) {
+ checkXftCoverage( f );
+ }
+#endif
+#endif // TQT_NO_XFTFREETYPE
+ // could reduce this further with some more magic:
+ // would need to remember the encodings loaded for the family.
+ if ( ( script == -1 && !f->xlfdLoaded ) ||
+ ( !f->hasXft && !(f->scripts[script] & TQtFontFamily::Supported) &&
+ !(f->scripts[script] & TQtFontFamily::UnSupported_Xlfd) ) ) {
+ loadXlfds( family, -1 );
+ f->fullyLoaded = TRUE;
+ }
+ }
+ }
+
+#ifdef TQFONTDATABASE_DEBUG
+ FD_DEBUG("TQFontDatabase: load( %s, %d) took %d ms", family.latin1(), script, t.elapsed() );
+#endif
+}
+
+
+static void initializeDb()
+{
+ if ( db ) return;
+ db = new TQFontDatabasePrivate;
+ qfontdatabase_cleanup.set(&db);
+
+#ifndef TQT_XFT2
+ memset( encodingLoaded, FALSE, sizeof( encodingLoaded ) );
+#endif
+
+ TQTime t;
+ t.start();
+
+#ifndef TQT_NO_XFTFREETYPE
+ loadXft();
+ FD_DEBUG("TQFontDatabase: loaded Xft: %d ms", t.elapsed() );
+#endif
+
+ t.start();
+
+#ifndef TQT_NO_XFTFREETYPE
+ for ( int i = 0; i < db->count; i++ ) {
+#ifndef TQT_XFT2
+ checkXftCoverage( db->families[i] );
+ FD_DEBUG("TQFontDatabase: xft coverage check: %d ms", t.elapsed() );
+#endif // TQT_XFT2
+
+#ifdef XFT_MATRIX
+ checkXftMatrix( db->families[i] );
+#endif // XFT_MATRIX
+ }
+#endif
+
+
+#ifdef TQFONTDATABASE_DEBUG
+#ifdef TQT_XFT2
+ if (!qt_has_xft)
+#endif
+ // load everything at startup in debug mode.
+ loadXlfds( 0, -1 );
+
+ // print the database
+ for ( int f = 0; f < db->count; f++ ) {
+ TQtFontFamily *family = db->families[f];
+ FD_DEBUG("'%s' %s hasXft=%s", family->name.latin1(), (family->fixedPitch ? "fixed" : ""),
+ (family->hasXft ? "yes" : "no") );
+ for ( int i = 0; i < TQFont::LastPrivateScript; ++i ) {
+ FD_DEBUG("\t%s: %s", TQFontDatabase::scriptName((TQFont::Script) i).latin1(),
+ ((family->scripts[i] & TQtFontFamily::Supported) ? "Supported" :
+ (family->scripts[i] & TQtFontFamily::UnSupported) == TQtFontFamily::UnSupported ?
+ "UnSupported" : "Unknown"));
+ }
+
+ for ( int fd = 0; fd < family->count; fd++ ) {
+ TQtFontFoundry *foundry = family->foundries[fd];
+ FD_DEBUG("\t\t'%s'", foundry->name.latin1() );
+ for ( int s = 0; s < foundry->count; s++ ) {
+ TQtFontStyle *style = foundry->styles[s];
+ FD_DEBUG("\t\t\tstyle: italic=%d oblique=%d (fake=%d) weight=%d (%s)\n"
+ "\t\t\tstretch=%d (%s)",
+ style->key.italic, style->key.oblique, style->fakeOblique, style->key.weight,
+ style->weightName, style->key.stretch,
+ style->setwidthName ? style->setwidthName : "nil" );
+ if ( style->smoothScalable )
+ FD_DEBUG("\t\t\t\tsmooth scalable" );
+ else if ( style->bitmapScalable )
+ FD_DEBUG("\t\t\t\tbitmap scalable" );
+ if ( style->pixelSizes ) {
+ qDebug("\t\t\t\t%d pixel sizes", style->count );
+ for ( int z = 0; z < style->count; ++z ) {
+ TQtFontSize *size = style->pixelSizes + z;
+ for ( int e = 0; e < size->count; ++e ) {
+ FD_DEBUG( "\t\t\t\t size %5d pitch %c encoding %s",
+ size->pixelSize,
+ size->encodings[e].pitch,
+ xlfd_for_id( size->encodings[e].encoding ) );
+ }
+ }
+ }
+ }
+ }
+ }
+#endif // TQFONTDATABASE_DEBUG
+}
+
+void TQFontDatabase::createDatabase()
+{
+ initializeDb();
+}
+
+
+// --------------------------------------------------------------------------------------
+// font loader
+// --------------------------------------------------------------------------------------
+#define MAXFONTSIZE_XFT 256
+#define MAXFONTSIZE_XLFD 128
+#ifndef TQT_NO_XFTFREETYPE
+static double addPatternProps(XftPattern *pattern, const TQtFontStyle::Key &key, bool fakeOblique,
+ bool smoothScalable, const TQFontPrivate *fp, const TQFontDef &request)
+{
+ int weight_value = XFT_WEIGHT_BLACK;
+ if ( key.weight == 0 )
+ weight_value = XFT_WEIGHT_MEDIUM;
+ else if ( key.weight < (TQFont::Light + TQFont::Normal) / 2 )
+ weight_value = XFT_WEIGHT_LIGHT;
+ else if ( key.weight < (TQFont::Normal + TQFont::DemiBold) / 2 )
+ weight_value = XFT_WEIGHT_MEDIUM;
+ else if ( key.weight < (TQFont::DemiBold + TQFont::Bold) / 2 )
+ weight_value = XFT_WEIGHT_DEMIBOLD;
+ else if ( key.weight < (TQFont::Bold + TQFont::Black) / 2 )
+ weight_value = XFT_WEIGHT_BOLD;
+ XftPatternAddInteger( pattern, XFT_WEIGHT, weight_value );
+
+ int slant_value = XFT_SLANT_ROMAN;
+ if ( key.italic )
+ slant_value = XFT_SLANT_ITALIC;
+ else if ( key.oblique && !fakeOblique )
+ slant_value = XFT_SLANT_OBLIQUE;
+ XftPatternAddInteger( pattern, XFT_SLANT, slant_value );
+
+ /*
+ Xft1 doesn't obey user settings for turning off anti-aliasing using
+ the following:
+
+ match any size > 6 size < 12 edit antialias = false;
+
+ ... if we request pixel sizes. so, work around this limitiation and
+ convert the pixel size to a point size and request that.
+ */
+ double size_value = request.pixelSize;
+ double scale = 1.;
+ if ( size_value > MAXFONTSIZE_XFT ) {
+ scale = (double)size_value/(double)MAXFONTSIZE_XFT;
+ size_value = MAXFONTSIZE_XFT;
+ }
+
+ size_value = size_value*72./TQPaintDevice::x11AppDpiY(fp->screen);
+ XftPatternAddDouble( pattern, XFT_SIZE, size_value );
+
+#ifdef XFT_MATRIX
+# ifdef TQT_XFT2
+ if (!smoothScalable) {
+# if FC_VERSION >= 20193
+ int stretch = request.stretch;
+ if (!stretch)
+ stretch = 100;
+ XftPatternAddInteger(pattern, FC_WIDTH, stretch);
+# endif
+ } else
+# endif
+ if ( ( request.stretch > 0 && request.stretch != 100 ) ||
+ ( key.oblique && fakeOblique ) ) {
+ XftMatrix matrix;
+ XftMatrixInit( &matrix );
+
+ if ( request.stretch > 0 && request.stretch != 100 )
+ XftMatrixScale( &matrix, double( request.stretch ) / 100.0, 1.0 );
+ if ( key.oblique && fakeOblique )
+ XftMatrixShear( &matrix, 0.20, 0.0 );
+
+ XftPatternAddMatrix( pattern, XFT_MATRIX, &matrix );
+ }
+#endif // XFT_MATRIX
+ if (request.styleStrategy & (TQFont::PreferAntialias|TQFont::NoAntialias)) {
+ XftPatternDel(pattern, XFT_ANTIALIAS);
+ XftPatternAddBool(pattern, XFT_ANTIALIAS,
+ !(request.styleStrategy & TQFont::NoAntialias));
+ }
+
+ return scale;
+}
+#endif // TQT_NO_XFTFREETYPE
+
+static
+TQFontEngine *loadEngine( TQFont::Script script,
+ const TQFontPrivate *fp, const TQFontDef &request,
+ TQtFontFamily *family, TQtFontFoundry *foundry,
+ TQtFontStyle *style, TQtFontSize *size,
+ TQtFontEncoding *encoding, bool forced_encoding )
+{
+ TQ_UNUSED(script);
+
+ if ( fp && fp->rawMode ) {
+ TQCString xlfd = request.family.latin1();
+ FM_DEBUG( "Loading XLFD (rawmode) '%s'", xlfd.data() );
+
+ XFontStruct *xfs;
+ if (! (xfs = XLoadQueryFont(TQPaintDevice::x11AppDisplay(), xlfd.data() ) ) )
+ return 0;
+
+ TQFontEngine *fe = new TQFontEngineXLFD( xfs, xlfd.data(), 0 );
+ if ( ! qt_fillFontDef( xfs, &fe->fontDef, TQPaintDevice::x11AppScreen() ) &&
+ ! qt_fillFontDef( xlfd, &fe->fontDef, TQPaintDevice::x11AppScreen() ) )
+ fe->fontDef = TQFontDef();
+
+ return fe;
+ }
+
+#ifndef TQT_NO_XFTFREETYPE
+ if ( encoding->encoding == -1 ) {
+
+ FM_DEBUG( " using Xft" );
+
+ XftPattern *pattern = XftPatternCreate();
+ if ( !pattern ) return 0;
+
+ bool symbol = (family->scripts[TQFont::UnknownScript] == TQtFontFamily::Supported);
+# ifdef TQT_XFT2
+ if (!symbol && script != TQFont::Unicode) {
+ FcCharSet *cs = FcCharSetCreate();
+ for ( int j=0; sample_chars[script][j]; j++ )
+ FcCharSetAddChar(cs, sample_chars[script][j]);
+ if (script == TQFont::Latin)
+ // add Euro character
+ FcCharSetAddChar(cs, 0x20ac);
+ FcPatternAddCharSet(pattern, FC_CHARSET, cs);
+ FcCharSetDestroy(cs);
+ }
+# else
+ XftPatternAddString( pattern, XFT_ENCODING, symbol ? "adobe-fontspecific" : "iso10646-1");
+# endif // TQT_XFT2
+
+ if ( !foundry->name.isEmpty() )
+ XftPatternAddString( pattern, XFT_FOUNDRY,
+ foundry->name.utf8().data() );
+
+ if ( !family->rawName.isEmpty() )
+ XftPatternAddString( pattern, XFT_FAMILY,
+ family->rawName.utf8().data() );
+
+
+ char pitch_value = ( encoding->pitch == 'c' ? XFT_CHARCELL :
+ ( encoding->pitch == 'm' ? XFT_MONO : XFT_PROPORTIONAL ) );
+ XftPatternAddInteger( pattern, XFT_SPACING, pitch_value );
+
+ double scale = addPatternProps(pattern, style->key, style->fakeOblique,
+ style->smoothScalable, fp, request);
+
+ XftResult res;
+ XftPattern *result =
+ XftFontMatch( TQPaintDevice::x11AppDisplay(), fp->screen, pattern, &res );
+#ifdef TQT_XFT2
+ if (result && script == TQFont::Latin) {
+ // since we added the Euro char on top, check we actually got the family
+ // we requested. If we didn't get it correctly, remove the Euro from the pattern
+ // and try again.
+ FcChar8 *f;
+ res = FcPatternGetString(result, FC_FAMILY, 0, &f);
+ if (res == FcResultMatch && TQString::fromUtf8((char *)f) != family->rawName) {
+ FcPatternDel(pattern, FC_CHARSET);
+ FcCharSet *cs = FcCharSetCreate();
+ for ( int j=0; sample_chars[script][j]; j++ )
+ FcCharSetAddChar(cs, sample_chars[script][j]);
+ FcPatternAddCharSet(pattern, FC_CHARSET, cs);
+ FcCharSetDestroy(cs);
+ result = XftFontMatch( TQPaintDevice::x11AppDisplay(), fp->screen, pattern, &res );
+ }
+ }
+#endif
+ XftPatternDestroy(pattern);
+ if (!result)
+ return 0;
+
+ // somehow this gets lost in the XftMatch call, reset the anitaliasing property correctly.
+ if (request.styleStrategy & (TQFont::PreferAntialias|TQFont::NoAntialias)) {
+ XftPatternDel(result, XFT_ANTIALIAS);
+ XftPatternAddBool(result, XFT_ANTIALIAS,
+ !(request.styleStrategy & TQFont::NoAntialias));
+ }
+ // We pass a duplicate to XftFontOpenPattern because either xft font
+ // will own the pattern after the call or the pattern will be
+ // destroyed.
+ XftPattern *dup = XftPatternDuplicate( result );
+ XftFont *xftfs = XftFontOpenPattern( TQPaintDevice::x11AppDisplay(), dup );
+
+ if ( ! xftfs ) // Xft couldn't tqfind a font?
+ return 0;
+
+ TQFontEngine *fe = new TQFontEngineXft( xftfs, result, symbol ? 1 : 0 );
+ if (fp->painttqdevice
+ && TQPaintDeviceMetrics(fp->painttqdevice).logicalDpiY() != TQPaintDevice::x11AppDpiY()) {
+ double px;
+ XftPatternGetDouble(result, XFT_PIXEL_SIZE, 0, &px);
+ scale = (double)request.pixelSize/px;
+ }
+ fe->setScale( scale );
+ return fe;
+ }
+#endif // TQT_NO_XFTFREETYPE
+
+ FM_DEBUG( " using XLFD" );
+
+ TQCString xlfd = "-";
+ xlfd += foundry->name.isEmpty() ? "*" : foundry->name.latin1();
+ xlfd += "-";
+ xlfd += family->name.isEmpty() ? "*" : family->name.latin1();
+
+ xlfd += "-";
+ xlfd += style->weightName ? style->weightName : "*";
+ xlfd += "-";
+ xlfd += ( style->key.italic ? "i" : ( style->key.oblique ? "o" : "r" ) );
+
+ xlfd += "-";
+ xlfd += style->setwidthName ? style->setwidthName : "*";
+ // ### handle add-style
+ xlfd += "-*-";
+
+ int px = size->pixelSize;
+ if ( style->smoothScalable && px == SMOOTH_SCALABLE )
+ px = request.pixelSize;
+ else if ( style->bitmapScalable && px == 0 )
+ px = request.pixelSize;
+ double scale = 1.;
+ if ( px > MAXFONTSIZE_XLFD ) {
+ scale = (double)px/(double)MAXFONTSIZE_XLFD;
+ px = MAXFONTSIZE_XLFD;
+ }
+ if (fp && fp->painttqdevice
+ && TQPaintDeviceMetrics(fp->painttqdevice).logicalDpiY() != TQPaintDevice::x11AppDpiY())
+ scale = (double)request.pixelSize/(double)px;
+
+ xlfd += TQString::number( px ).latin1();
+ xlfd += "-";
+ xlfd += TQString::number( encoding->xpoint );
+ xlfd += "-";
+ xlfd += TQString::number( encoding->xres );
+ xlfd += "-";
+ xlfd += TQString::number( encoding->yres );
+ xlfd += "-";
+
+ // ### handle cell spaced fonts
+ xlfd += encoding->pitch;
+ xlfd += "-";
+ xlfd += TQString::number( encoding->avgwidth );
+ xlfd += "-";
+ xlfd += xlfd_for_id( encoding->encoding );
+
+ FM_DEBUG( " xlfd: '%s'", xlfd.data() );
+
+ XFontStruct *xfs;
+ if (! (xfs = XLoadQueryFont(TQPaintDevice::x11AppDisplay(), xlfd.data() ) ) )
+ return 0;
+
+ TQFontEngine *fe = 0;
+ const int mib = xlfd_encoding[ encoding->encoding ].mib;
+ if (script == TQFont::Latin && encoding->encoding <= LAST_LATIN_ENCODING && !forced_encoding) {
+ fe = new TQFontEngineLatinXLFD( xfs, xlfd.data(), mib );
+ } else {
+ fe = new TQFontEngineXLFD( xfs, xlfd.data(), mib );
+ }
+
+ fe->setScale( scale );
+
+ return fe;
+}
+
+
+#ifdef TQT_XFT2
+
+static void parseFontName(const TQString &name, TQString &foundry, TQString &family)
+{
+ if ( name.tqcontains('[') && name.tqcontains(']')) {
+ int i = name.tqfind('[');
+ int li = name.tqfindRev(']');
+
+ if (i < li) {
+ foundry = name.mid(i + 1, li - i - 1);
+ if (name[i - 1] == ' ')
+ i--;
+ family = name.left(i);
+ }
+ } else {
+ foundry = TQString::null;
+ family = name;
+ }
+}
+
+
+static TQFontEngine *loadFontConfigFont(const TQFontPrivate *fp, const TQFontDef &request, TQFont::Script script)
+{
+ if (!qt_has_xft)
+ return 0;
+
+ TQStringList family_list;
+ if (request.family.isEmpty()) {
+ family_list = TQStringList::split(TQChar(','), fp->request.family);
+
+ TQString stylehint;
+ switch ( request.tqstyleHint ) {
+ case TQFont::SansSerif:
+ stylehint = "sans-serif";
+ break;
+ case TQFont::Serif:
+ stylehint = "serif";
+ break;
+ case TQFont::TypeWriter:
+ stylehint = "monospace";
+ break;
+ default:
+ if (request.fixedPitch)
+ stylehint = "monospace";
+ break;
+ }
+ if (!stylehint.isEmpty())
+ family_list << stylehint;
+ } else {
+ family_list << request.family;
+ }
+
+ FcPattern *pattern = FcPatternCreate();
+
+ {
+ TQString family, foundry;
+ for (TQStringList::ConstIterator it = family_list.begin(); it != family_list.end(); ++it) {
+ parseFontName(*it, foundry, family);
+ XftPatternAddString(pattern, XFT_FAMILY, family.utf8().data());
+ }
+ }
+
+ TQtFontStyle::Key key;
+ key.italic = request.italic;
+ key.weight = request.weight;
+ key.stretch = request.stretch;
+
+ double scale = addPatternProps(pattern, key, FALSE, TRUE, fp, request);
+#ifdef FONT_MATCH_DEBUG
+ qDebug("original pattern tqcontains:");
+ FcPatternPrint(pattern);
+#endif
+
+ // XftFontMatch calls the right ConfigSubstitute variants, but as we use
+ // FcFontMatch/Sort here we have to do it manually.
+ FcConfigSubstitute(0, pattern, FcMatchPattern);
+ XftDefaultSubstitute(TQPaintDevice::x11AppDisplay(), TQPaintDevice::x11AppScreen(), pattern);
+
+// qDebug("1: pattern tqcontains:");
+// FcPatternPrint(pattern);
+
+ {
+ FcValue value;
+ value.type = FcTypeString;
+
+ // these should only get added to the pattern _after_ substitution
+ // append the default fallback font for the specified script
+ extern TQString qt_fallback_font_family( TQFont::Script );
+ TQString fallback = qt_fallback_font_family( script );
+ if ( ! fallback.isEmpty() && ! family_list.tqcontains( fallback ) ) {
+ TQCString cs = fallback.utf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
+ }
+
+ // add the default family
+ TQString defaultFamily = TQApplication::font().family();
+ if ( ! family_list.tqcontains( defaultFamily ) ) {
+ TQCString cs = defaultFamily.utf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
+ }
+
+ // add TQFont::defaultFamily() to the list, for compatibility with
+ // previous versions
+ defaultFamily = TQApplication::font().defaultFamily();
+ if ( ! family_list.tqcontains( defaultFamily ) ) {
+ TQCString cs = defaultFamily.utf8();
+ value.u.s = (const FcChar8 *)cs.data();
+ FcPatternAddWeak(pattern, FC_FAMILY, value, FcTrue);
+ }
+ }
+
+ if (script != TQFont::Unicode) {
+ FcCharSet *cs = FcCharSetCreate();
+ for ( int j=0; sample_chars[script][j]; j++ )
+ FcCharSetAddChar(cs, sample_chars[script][j]);
+ if (script == TQFont::Latin)
+ // add Euro character
+ FcCharSetAddChar(cs, 0x20ac);
+ FcPatternAddCharSet(pattern, FC_CHARSET, cs);
+ FcCharSetDestroy(cs);
+ }
+
+#ifdef FONT_MATCH_DEBUG
+ printf("final pattern tqcontains:\n");
+ FcPatternPrint(pattern);
+#endif
+
+ TQFontEngine *fe = 0;
+
+ for( int jj = (FcGetVersion() >= 20392 ? 0 : 1); jj < 2; ++jj ) {
+ bool use_fontsort = ( jj == 1 );
+
+ FcResult result;
+ FcFontSet *fs = 0;
+ FcPattern *fsp = 0;
+ if( use_fontsort ) {
+ fs = FcFontSort(0, pattern, FcFalse, 0, &result);
+ if (!fs)
+ continue;
+ } else {
+ fsp = FcFontMatch(0, pattern, &result);
+ if (!fsp)
+ continue;
+ }
+
+#ifdef FONT_MATCH_DEBUG
+ if( use_fontsort ) {
+ printf("fontset tqcontains:\n");
+ for (int i = 0; i < fs->nfont; ++i) {
+ FcPattern *test = fs->fonts[i];
+ FcChar8 *fam;
+ FcPatternGetString(test, FC_FAMILY, 0, &fam);
+ printf(" %s\n", fam);
+ }
+ } else {
+ printf("fontmatch:");
+ FcChar8 *fam;
+ FcPatternGetString(fsp, FC_FAMILY, 0, &fam);
+ printf(" %s\n", fam);
+ }
+#endif
+
+ double size_value = request.pixelSize;
+ if ( size_value > MAXFONTSIZE_XFT )
+ size_value = MAXFONTSIZE_XFT;
+
+ int cnt = use_fontsort ? fs->nfont : 1;
+
+ for (int i = 0; i < cnt; ++i) {
+ FcPattern *font = use_fontsort ? fs->fonts[i] : fsp;
+ FcCharSet *cs;
+ FcResult res = FcPatternGetCharSet(font, FC_CHARSET, 0, &cs);
+ if (res != FcResultMatch)
+ continue;
+ bool do_break=true;
+ for ( int j=0; sample_chars[script][j]; j++ ){
+ do_break=false;
+ if (!FcCharSetHasChar(cs, sample_chars[script][j])) {
+ do_break=true;
+ break;
+ }
+ }
+ if ( do_break )
+ continue;
+ FcBool scalable;
+ res = FcPatternGetBool(font, FC_SCALABLE, 0, &scalable);
+ if (res != FcResultMatch || !scalable) {
+ int pixelSize;
+ res = FcPatternGetInteger(font, FC_PIXEL_SIZE, 0, &pixelSize);
+ if (res != FcResultMatch || TQABS((size_value-pixelSize)/size_value) > 0.2)
+ continue;
+ }
+
+ XftPattern *pattern = XftPatternDuplicate(font);
+ // add properties back in as the font selected from the list doesn't contain them.
+ addPatternProps(pattern, key, FALSE, TRUE, fp, request);
+
+ XftPattern *result =
+ XftFontMatch( TQPaintDevice::x11AppDisplay(), fp->screen, pattern, &res );
+ XftPatternDestroy(pattern);
+
+ // We pass a duplicate to XftFontOpenPattern because either xft font
+ // will own the pattern after the call or the pattern will be
+ // destroyed.
+ XftPattern *dup = XftPatternDuplicate( result );
+ XftFont *xftfs = XftFontOpenPattern( TQPaintDevice::x11AppDisplay(), dup );
+
+ if ( !xftfs ) {
+ // Xft couldn't tqfind a font?
+ qDebug("couldn't open fontconfigs chosen font with Xft!!!");
+ } else {
+ fe = new TQFontEngineXft( xftfs, result, 0 );
+ if (fp->painttqdevice
+ && TQPaintDeviceMetrics(fp->painttqdevice).logicalDpiY() != TQPaintDevice::x11AppDpiY()) {
+ double px;
+ XftPatternGetDouble(result, XFT_PIXEL_SIZE, 0, &px);
+ scale = request.pixelSize/px;
+ }
+ fe->setScale( scale );
+ fe->fontDef = request;
+ if ( script != TQFont::Unicode && !canRender(fe, script) ) {
+ FM_DEBUG( " WARN: font loaded cannot render samples" );
+ delete fe;
+ fe = 0;
+ }else
+ FM_DEBUG( " USE: %s", fe->fontDef.family.latin1() );
+ }
+ if (fe) {
+ TQFontEngineXft *xft = (TQFontEngineXft *)fe;
+ char *family;
+ if (XftPatternGetString(xft->pattern(), XFT_FAMILY, 0, &family) == XftResultMatch)
+ xft->fontDef.family = TQString::fromUtf8(family);
+
+ double px;
+ if (XftPatternGetDouble(xft->pattern(), XFT_PIXEL_SIZE, 0, &px) == XftResultMatch)
+ xft->fontDef.pixelSize = tqRound(px);
+
+ int weight = XFT_WEIGHT_MEDIUM;
+ XftPatternGetInteger(xft->pattern(), XFT_WEIGHT, 0, &weight);
+ xft->fontDef.weight = getXftWeight(weight);
+
+ int slant = XFT_SLANT_ROMAN;
+ XftPatternGetInteger(xft->pattern(), XFT_SLANT, 0, &slant);
+ xft->fontDef.italic = (slant != XFT_SLANT_ROMAN);
+
+ int spacing = XFT_PROPORTIONAL;
+ XftPatternGetInteger(xft->pattern(), XFT_SPACING, 0, &spacing);
+ xft->fontDef.fixedPitch = spacing != XFT_PROPORTIONAL;
+
+ xft->fontDef.ignorePitch = FALSE;
+ break;
+ }
+ }
+
+ if( use_fontsort )
+ FcFontSetDestroy(fs);
+ else
+ FcPatternDestroy(fsp);
+
+ if( fe )
+ break;
+
+ } // for( jj )
+
+ FcPatternDestroy(pattern);
+
+ return fe;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqfontengine_p.h b/tqtinterface/qt4/src/kernel/tqfontengine_p.h
new file mode 100644
index 0000000..cba46a7
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfontengine_p.h
@@ -0,0 +1,642 @@
+/****************************************************************************
+**
+** ???
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFONTENGINE_P_H
+#define TQFONTENGINE_P_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+// FIXME
+
+#else // USE_QT4
+
+#ifdef TQ_WS_WIN
+#include "tqt_windows.h"
+#include "tqptrdict.h"
+#endif
+
+#include "tqtextengine_p.h"
+
+class TQPaintDevice;
+
+struct glyph_metrics_t;
+class TQChar;
+typedef unsigned short glyph_t;
+struct qoffset_t;
+typedef int advance_t;
+class TQOpenType;
+struct TransformedFont;
+
+#if defined( TQ_WS_X11 ) || defined( TQ_WS_WIN) || defined( TQ_WS_MAC )
+class TQFontEngine : public TQShared
+{
+public:
+ enum Error {
+ NoError,
+ OutOfMemory
+ };
+
+ enum Type {
+ // X11 types
+ Box,
+ XLFD,
+ LatinXLFD,
+ Xft,
+
+ // MS Windows types
+ Win,
+ Uniscribe,
+
+ // Apple MacOS types
+ Mac,
+
+ // Trolltech TQWS types
+ TQWS
+ };
+
+ TQFontEngine() {
+ count = 0; cache_count = 0;
+#ifdef TQ_WS_X11
+ transformed_fonts = 0;
+#endif
+ }
+ virtual ~TQFontEngine();
+
+ /* returns 0 as glyph index for non existant glyphs */
+ virtual Error stringToCMap( const TQChar *str, int len, glyph_t *glyphs,
+ advance_t *advances, int *nglyphs, bool mirrored ) const = 0;
+
+#ifdef TQ_WS_X11
+ virtual int cmap() const { return -1; }
+ virtual TQOpenType *openType() const { return 0; }
+#endif
+
+ virtual void draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags ) = 0;
+
+ virtual glyph_metrics_t boundingBox( const glyph_t *glyphs,
+ const advance_t *advances,
+ const qoffset_t *offsets, int numGlyphs ) = 0;
+ virtual glyph_metrics_t boundingBox( glyph_t glyph ) = 0;
+
+ virtual int ascent() const = 0;
+ virtual int descent() const = 0;
+ virtual int leading() const = 0;
+
+ virtual int lineThickness() const;
+ virtual int underlinePosition() const;
+
+ virtual int maxCharWidth() const = 0;
+ virtual int minLeftBearing() const { return 0; }
+ virtual int minRightBearing() const { return 0; }
+
+ virtual const char *name() const = 0;
+
+ virtual bool canRender( const TQChar *string, int len ) = 0;
+
+ virtual void setScale( double ) {}
+ virtual double scale() const { return 1.; }
+
+ virtual Type type() const = 0;
+
+ TQFontDef fontDef;
+ uint cache_cost; // amount of mem used in kb by the font
+ int cache_count;
+
+#ifdef TQ_WS_WIN
+ HDC dc() const;
+ void getGlyphIndexes( const TQChar *ch, int numChars, glyph_t *glyphs, bool mirrored ) const;
+ void getCMap();
+
+ TQCString _name;
+ HDC hdc;
+ HFONT hfont;
+ LOGFONT logfont;
+ uint stockFont : 1;
+ uint paintDevice : 1;
+ uint useTextOutA : 1;
+ uint ttf : 1;
+ uint symbol : 1;
+ union {
+ TEXTMETRICW w;
+ TEXTMETRICA a;
+ } tm;
+ int lw;
+ unsigned char *cmap;
+ void *script_cache;
+ static TQPtrDict<TQFontEngine> cacheDict;
+ short lbearing;
+ short rbearing;
+#endif // TQ_WS_WIN
+#ifdef TQ_WS_X11
+ TransformedFont *transformed_fonts;
+#endif
+};
+#elif defined( TQ_WS_TQWS )
+class TQGfx;
+
+class TQFontEngine : public TQShared
+{
+public:
+ TQFontEngine( const TQFontDef&, const TQPaintDevice * = 0 );
+ ~TQFontEngine();
+ /*TQMemoryManager::FontID*/ void *handle() const;
+
+ enum Type {
+ // X11 types
+ Box,
+ XLFD,
+ Xft,
+
+ // MS Windows types
+ Win,
+ Uniscribe,
+
+ // Apple MacOS types
+ Mac,
+
+ // Trolltech TQWS types
+ Qws
+ };
+
+ enum TextFlags {
+ Underline = 0x01,
+ Overline = 0x02,
+ StrikeOut = 0x04
+ };
+
+ enum Error {
+ NoError,
+ OutOfMemory
+ };
+ /* returns 0 as glyph index for non existant glyphs */
+ Error stringToCMap( const TQChar *str, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool mirrored ) const;
+
+ void draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags );
+
+ glyph_metrics_t boundingBox( const glyph_t *glyphs,
+ const advance_t *advances, const qoffset_t *offsets, int numGlyphs );
+ glyph_metrics_t boundingBox( glyph_t glyph );
+
+ int ascent() const;
+ int descent() const;
+ int leading() const;
+ int maxCharWidth() const;
+ int minLeftBearing() const;
+ int minRightBearing() const;
+ int underlinePosition() const;
+ int lineThickness() const;
+
+ Type type() { return Qws; }
+
+ bool canRender( const TQChar *string, int len );
+ inline const char *name() const { return 0; }
+ TQFontDef fontDef;
+ /*TQMemoryManager::FontID*/ void *id;
+ int cache_cost;
+ int cache_count;
+ int scale;
+};
+#endif // WIN || X11 || MAC
+
+
+
+enum IndicFeatures {
+ CcmpFeature,
+ InitFeature,
+ NuktaFeature,
+ AkhantFeature,
+ RephFeature,
+ BelowFormFeature,
+ HalfFormFeature,
+ PostFormFeature,
+ VattuFeature,
+ PreSubstFeature,
+ AboveSubstFeature,
+ BelowSubstFeature,
+ PostSubstFeature,
+ HalantFeature
+};
+
+#if defined(TQ_WS_X11) || defined(TQ_WS_WIN)
+class TQFontEngineBox : public TQFontEngine
+{
+public:
+ TQFontEngineBox( int size );
+ ~TQFontEngineBox();
+
+ Error stringToCMap( const TQChar *str, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool mirrored ) const;
+
+ void draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags );
+
+ virtual glyph_metrics_t boundingBox( const glyph_t *glyphs,
+ const advance_t *advances, const qoffset_t *offsets, int numGlyphs );
+ glyph_metrics_t boundingBox( glyph_t glyph );
+
+ int ascent() const;
+ int descent() const;
+ int leading() const;
+ int maxCharWidth() const;
+ int minLeftBearing() const { return 0; }
+ int minRightBearing() const { return 0; }
+
+#ifdef TQ_WS_X11
+ int cmap() const;
+#endif
+ const char *name() const;
+
+ bool canRender( const TQChar *string, int len );
+
+ Type type() const;
+ inline int size() const { return _size; }
+
+private:
+ friend class TQFontPrivate;
+ int _size;
+};
+#endif
+
+#ifdef TQ_WS_X11
+#include "tqt_x11_p.h"
+
+
+struct TransformedFont
+{
+ float xx;
+ float xy;
+ float yx;
+ float yy;
+ union {
+ Font xlfd_font;
+#ifndef TQT_NO_XFTFREETYPE
+ XftFont *xft_font;
+#endif
+ };
+ TransformedFont *next;
+};
+
+#ifndef TQT_NO_XFTFREETYPE
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include "ftxopen.h"
+
+class TQTextCodec;
+
+class TQFontEngineXft : public TQFontEngine
+{
+public:
+ TQFontEngineXft( XftFont *font, XftPattern *pattern, int cmap );
+ ~TQFontEngineXft();
+
+ TQOpenType *openType() const;
+
+ Error stringToCMap( const TQChar *str, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool mirrored ) const;
+
+ void draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags );
+
+ virtual glyph_metrics_t boundingBox( const glyph_t *glyphs,
+ const advance_t *advances, const qoffset_t *offsets, int numGlyphs );
+ glyph_metrics_t boundingBox( glyph_t glyph );
+
+ int ascent() const;
+ int descent() const;
+ int leading() const;
+ int lineThickness() const;
+ int underlinePosition() const;
+ int maxCharWidth() const;
+ int minLeftBearing() const;
+ int minRightBearing() const;
+
+ int cmap() const;
+ const char *name() const;
+
+ void setScale( double scale );
+ double scale() const { return _scale; }
+
+ bool canRender( const TQChar *string, int len );
+
+ Type type() const;
+ XftPattern *pattern() const { return _pattern; }
+ FT_Face face() const { return _face; }
+ XftFont *font() const { return _font; }
+
+ void recalcAdvances( int len, glyph_t *glyphs, advance_t *advances );
+
+private:
+ friend class TQFontPrivate;
+ friend class TQOpenType;
+ XftFont *_font;
+ XftPattern *_pattern;
+ FT_Face _face;
+ TQOpenType *_openType;
+ int _cmap;
+ short lbearing;
+ short rbearing;
+ float _scale;
+ enum { widthCacheSize = 0x800, cmapCacheSize = 0x500 };
+ unsigned char widthCache[widthCacheSize];
+ glyph_t cmapCache[cmapCacheSize];
+};
+#endif
+
+class TQFontEngineLatinXLFD;
+
+class TQFontEngineXLFD : public TQFontEngine
+{
+public:
+ TQFontEngineXLFD( XFontStruct *fs, const char *name, int cmap );
+ ~TQFontEngineXLFD();
+
+ Error stringToCMap( const TQChar *str, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool mirrored ) const;
+
+ void draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags );
+
+ virtual glyph_metrics_t boundingBox( const glyph_t *glyphs,
+ const advance_t *advances, const qoffset_t *offsets, int numGlyphs );
+ glyph_metrics_t boundingBox( glyph_t glyph );
+
+ int ascent() const;
+ int descent() const;
+ int leading() const;
+ int maxCharWidth() const;
+ int minLeftBearing() const;
+ int minRightBearing() const;
+
+ int cmap() const;
+ const char *name() const;
+
+ bool canRender( const TQChar *string, int len );
+
+ void setScale( double scale );
+ double scale() const { return _scale; }
+ Type type() const;
+
+ TQt::HANDLE handle() const { return (TQt::HANDLE) _fs->fid; }
+
+private:
+ friend class TQFontPrivate;
+ XFontStruct *_fs;
+ TQCString _name;
+ TQTextCodec *_codec;
+ float _scale; // needed for printing, to correctly scale font metrics for bitmap fonts
+ int _cmap;
+ short lbearing;
+ short rbearing;
+ enum XlfdTransformations {
+ XlfdTrUnknown,
+ XlfdTrSupported,
+ XlfdTrUnsupported
+ };
+ XlfdTransformations xlfd_transformations;
+
+ friend class TQFontEngineLatinXLFD;
+};
+
+class TQFontEngineLatinXLFD : public TQFontEngine
+{
+public:
+ TQFontEngineLatinXLFD( XFontStruct *xfs, const char *name, int cmap );
+ ~TQFontEngineLatinXLFD();
+
+ Error stringToCMap( const TQChar *str, int len, glyph_t *glyphs,
+ advance_t *advances, int *nglyphs, bool mirrored ) const;
+
+ void draw( TQPainter *p, int x, int y, const TQTextEngine *engine,
+ const TQScriptItem *si, int textFlags );
+
+ virtual glyph_metrics_t boundingBox( const glyph_t *glyphs,
+ const advance_t *advances,
+ const qoffset_t *offsets, int numGlyphs );
+ glyph_metrics_t boundingBox( glyph_t glyph );
+
+ int ascent() const;
+ int descent() const;
+ int leading() const;
+ int maxCharWidth() const;
+ int minLeftBearing() const;
+ int minRightBearing() const;
+
+ int cmap() const { return -1; } // ###
+ const char *name() const;
+
+ bool canRender( const TQChar *string, int len );
+
+ void setScale( double scale );
+ double scale() const { return _engines[0]->scale(); }
+ Type type() const { return LatinXLFD; }
+
+ TQt::HANDLE handle() const { return ((TQFontEngineXLFD *) _engines[0])->handle(); }
+
+private:
+ void tqfindEngine( const TQChar &ch );
+
+ TQFontEngine **_engines;
+ int _count;
+
+ glyph_t glyphIndices [0x200];
+ advance_t glyphAdvances[0x200];
+ glyph_t euroIndex;
+ advance_t euroAdvance;
+};
+
+class TQScriptItem;
+class TQTextEngine;
+
+#ifndef TQT_NO_XFTFREETYPE
+
+#include "tqscriptengine_p.h"
+#include "tqtextengine_p.h"
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include "ftxopen.h"
+
+enum { PositioningProperties = 0x80000000 };
+
+class TQOpenType
+{
+public:
+ TQOpenType(TQFontEngineXft *fe);
+ ~TQOpenType();
+
+ struct Features {
+ uint tag;
+ uint property;
+ };
+
+ bool supportsScript(unsigned int script) {
+ TQ_ASSERT(script < TQFont::NScripts);
+ return supported_scripts[script];
+ }
+ void selectScript(unsigned int script, const Features *features = 0);
+
+ bool tqshape(TQShaperItem *item, const unsigned int *properties = 0);
+ bool positionAndAdd(TQShaperItem *item, bool doLogClusters = TRUE);
+
+ OTL_GlyphItem glyphs() const { return otl_buffer->in_string; }
+ int len() const { return otl_buffer->in_length; }
+ void setProperty(int index, uint property) { otl_buffer->in_string[index].properties = property; }
+
+
+private:
+ bool checkScript(unsigned int script);
+ TQFontEngine *fontEngine;
+ FT_Face face;
+ TTO_GDEF gdef;
+ TTO_GSUB gsub;
+ TTO_GPOS gpos;
+ bool supported_scripts[TQFont::NScripts];
+ FT_ULong current_script;
+ bool positioned : 1;
+ OTL_Buffer otl_buffer;
+ GlyphAttributes *tmpAttributes;
+ unsigned int *tmpLogClusters;
+ int length;
+ int orig_nglyphs;
+ int loadFlags;
+};
+
+#endif // TQT_NO_XFTFREETYPE
+
+#elif defined( TQ_WS_MAC )
+#include "tqt_mac.h"
+#include <tqmap.h>
+#include <tqcache.h>
+
+class TQFontEngineMac : public TQFontEngine
+{
+#if 0
+ ATSFontMetrics *info;
+#else
+ FontInfo *info;
+#endif
+ int psize;
+ FMFontFamily fmfam;
+ TQMacFontInfo *internal_fi;
+ mutable ATSUTextLayout mTextLayout;
+ enum { widthCacheSize = 0x500 };
+ mutable unsigned char widthCache[widthCacheSize];
+ friend class TQFont;
+ friend class TQGLContext;
+ friend class TQFontPrivate;
+ friend class TQMacSetFontInfo;
+
+public:
+ TQFontEngineMac();
+ ~TQFontEngineMac();
+
+ Error stringToCMap( const TQChar *str, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool mirrored ) const;
+
+ void draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags );
+
+ glyph_metrics_t boundingBox( const glyph_t *glyphs,
+ const advance_t *advances, const qoffset_t *offsets, int numGlyphs );
+ glyph_metrics_t boundingBox( glyph_t glyph );
+
+ int ascent() const { return (int)info->ascent; }
+ int descent() const { return (int)info->descent; }
+ int leading() const { return (int)info->leading; }
+#if 0
+ int maxCharWidth() const { return (int)info->maxAdvanceWidth; }
+#else
+ int maxCharWidth() const { return info->widMax; }
+#endif
+
+ const char *name() const { return "ATSUI"; }
+
+ bool canRender( const TQChar *string, int len );
+
+ Type type() const { return TQFontEngine::Mac; }
+
+ void calculateCost();
+
+ enum { WIDTH=0x01, DRAW=0x02, EXISTS=0x04 };
+ int doTextTask(const TQChar *s, int pos, int use_len, int len, uchar task, int =-1, int y=-1,
+ TQPaintDevice *dev=NULL, const TQRegion *rgn=NULL) const;
+};
+
+#elif defined( TQ_WS_WIN )
+
+class TQFontEngineWin : public TQFontEngine
+{
+public:
+ TQFontEngineWin( const char *name, HDC, HFONT, bool, LOGFONT );
+
+ Error stringToCMap( const TQChar *str, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool mirrored ) const;
+
+ void draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags );
+
+ glyph_metrics_t boundingBox( const glyph_t *glyphs,
+ const advance_t *advances, const qoffset_t *offsets, int numGlyphs );
+ glyph_metrics_t boundingBox( glyph_t glyph );
+
+ int ascent() const;
+ int descent() const;
+ int leading() const;
+ int maxCharWidth() const;
+ int minLeftBearing() const;
+ int minRightBearing() const;
+
+ const char *name() const;
+
+ bool canRender( const TQChar *string, int len );
+
+ Type type() const;
+
+ enum { widthCacheSize = 0x800, cmapCacheSize = 0x500 };
+ unsigned char widthCache[widthCacheSize];
+};
+
+#if 0
+class TQFontEngineUniscribe : public TQFontEngineWin
+{
+public:
+ void draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags );
+ bool canRender( const TQChar *string, int len );
+
+ Type type() const;
+};
+#endif
+
+#endif // TQ_WS_WIN
+
+#endif // USE_QT4
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqfontengine_x11.cpp b/tqtinterface/qt4/src/kernel/tqfontengine_x11.cpp
new file mode 100644
index 0000000..0b45ec9
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfontengine_x11.cpp
@@ -0,0 +1,2752 @@
+/****************************************************************************
+**
+** ???
+**
+** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+#include <Qt/qdatastream.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+#else // USE_QT4
+#include "tqfontengine_p.h"
+#endif // USE_QT4
+
+// #define FONTENGINE_DEBUG
+
+#include <tqwidget.h>
+#include <tqcstring.h>
+#include <tqtextcodec.h>
+
+#include "tqbitmap.h"
+#include "tqfontdatabase.h"
+#include "tqpaintdevice.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqpainter.h"
+#include "tqimage.h"
+
+#include "tqt_x11_p.h"
+
+#include "tqfont.h"
+#include "tqtextengine_p.h"
+
+#include <private/tqunicodetables_p.h>
+
+#ifdef USE_QT4
+#include "tqfontengine_p.h"
+#endif // USE_QT4
+
+#include <limits.h>
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+// defined in qfontdatbase_x11.cpp
+extern int qt_mib_for_xlfd_encoding( const char *encoding );
+extern int qt_xlfd_encoding_id( const char *encoding );
+
+extern void qt_draw_transformed_rect( TQPainter *p, int x, int y, int w, int h, bool fill );
+
+static void drawLines( TQPainter *p, TQFontEngine *fe, int baseline, int x1, int w, int textFlags )
+{
+ int lw = fe->lineThickness();
+ if ( textFlags & TQt::Underline ) {
+ int pos = fe->underlinePosition();
+ qt_draw_transformed_rect( p, x1, baseline+pos, w, lw, TRUE );
+ }
+ if ( textFlags & TQt::Overline ) {
+ int pos = fe->ascent()+1;
+ if ( !pos ) pos = 1;
+ qt_draw_transformed_rect( p, x1, baseline-pos, w, lw, TRUE );
+ }
+ if ( textFlags & TQt::StrikeOut ) {
+ int pos = fe->ascent()/3;
+ if ( !pos ) pos = 1;
+ qt_draw_transformed_rect( p, x1, baseline-pos, w, lw, TRUE );
+ }
+}
+
+
+inline static void qSafeXDestroyImage( XImage *x )
+{
+ if ( x->data ) {
+ free( x->data );
+ x->data = 0;
+ }
+ XDestroyImage( x );
+}
+
+extern bool qt_xForm_helper( const TQWMatrix &trueMat, int xoffset,
+ int type, int depth,
+ uchar *dptr, int dbpl, int p_inc, int dHeight,
+ uchar *sptr, int sbpl, int sWidth, int sHeight
+ );
+
+static TQBitmap transform(Display *dpy, const TQBitmap &source, int xoff, int yoff, int w, int h, const TQWMatrix &matrix)
+{
+ int ws = source.width();
+ int hs = source.height();
+
+ bool invertible;
+ TQWMatrix mat = matrix.invert( &invertible ); // invert matrix
+
+ if (!invertible )
+ return TQBitmap();
+ mat.translate(xoff, yoff);
+
+ XImage *xi = XGetImage(dpy, source.handle(), 0, 0, ws, hs, AllPlanes, XYPixmap);
+
+ if ( !xi )
+ return TQBitmap();
+
+ int sbpl = xi->bytes_per_line;
+ uchar *sptr = (uchar *)xi->data;
+
+ int dbpl = (w+7)/8;
+ int dbytes = dbpl*h;
+
+ uchar *dptr = (uchar *)malloc( dbytes ); // create buffer for bits
+ memset( dptr, 0, dbytes );
+
+ int type = xi->bitmap_bit_order == MSBFirst ? TQT_XFORM_TYPE_MSBFIRST : TQT_XFORM_TYPE_LSBFIRST;
+ int xbpl, p_inc;
+ xbpl = (w+7)/8;
+ p_inc = dbpl - xbpl;
+
+ bool ok = qt_xForm_helper( mat, xi->xoffset, type, 1, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs );
+ qSafeXDestroyImage(xi);
+ TQBitmap bm;
+ if (ok) {
+ bm = TQBitmap( w, h, dptr, TQImage::systemBitOrder() != TQImage::BigEndian );
+ } else {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQFontEngineXft::tranform: xform failed");
+#endif
+ }
+
+ free( dptr );
+ return bm;
+}
+
+
+static void drawScaled(int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags,
+ Display *dpy, GC gc, TQPaintDevice *pdev, TQFontEngine *fe,
+ const TQWMatrix &xmat, float scale)
+{
+ // font doesn't support transformations, need to do it by hand
+ int w = tqRound(si->width/scale);
+ int h = tqRound((si->ascent + si->descent + 1)/scale);
+ if (w == 0 || h == 0)
+ return;
+ TQWMatrix mat1 = xmat;
+ mat1.scale(scale, scale);
+
+ w += h; // add some pixels to width because of italic correction
+ TQBitmap bm( w, h, TRUE ); // create bitmap
+ TQPainter paint;
+ paint.begin( &bm ); // draw text in bitmap
+ fe->draw( &paint, 0, si->ascent/scale, engine, si, textFlags );
+ paint.end();
+
+ TQRect pdevRect;
+ if (pdev->devType() == TQInternal::Widget)
+ pdevRect = ((TQWidget *)pdev)->rect();
+ else if (pdev->devType() == TQInternal::Pixmap)
+ pdevRect = ((TQPixmap *)pdev)->rect();
+ else
+ return;
+
+
+ TQRect br = mat1.mapRect(TQRect(x, y - si->ascent, w, h));
+ TQRect br2 = br & pdevRect;
+ if (br2.width() <= 0 || br2.height() <= 0
+ || br2.width() >= 32768 || br2.height() >= 32768)
+ return;
+ TQWMatrix mat = TQT_TQWMATRIX_OBJECT(TQPixmap::trueMatrix( mat1, w, h ));
+ TQBitmap wx_bm = ::transform(dpy, bm, br2.x() - br.x(), br2.y() - br.y(), br2.width(), br2.height(), mat);
+ if ( wx_bm.isNull() )
+ return;
+
+ x = br2.x();
+ y = br2.y();
+
+ TQt::HANDLE hd = pdev->handle();
+ XSetFillStyle( dpy, gc, FillStippled );
+ XSetStipple( dpy, gc, wx_bm.handle() );
+ XSetTSOrigin( dpy, gc, x, y );
+ XFillRectangle( dpy, hd, gc, x, y, wx_bm.width(), wx_bm.height() );
+ XSetTSOrigin( dpy, gc, 0, 0 );
+ XSetFillStyle( dpy, gc, FillSolid );
+}
+
+
+TQFontEngine::~TQFontEngine()
+{
+}
+
+int TQFontEngine::lineThickness() const
+{
+ // ad hoc algorithm
+ int score = fontDef.weight * fontDef.pixelSize;
+ int lw = score / 700;
+
+ // looks better with thicker line for small pointsizes
+ if ( lw < 2 && score >= 1050 ) lw = 2;
+ if ( lw == 0 ) lw = 1;
+
+ return lw;
+}
+
+int TQFontEngine::underlinePosition() const
+{
+ int pos = ( ( lineThickness() * 2 ) + 3 ) / 6;
+ return pos ? pos : 1;
+}
+
+// ------------------------------------------------------------------
+// The box font engine
+// ------------------------------------------------------------------
+
+
+TQFontEngineBox::TQFontEngineBox( int size )
+ : _size( size )
+{
+ cache_cost = sizeof( TQFontEngineBox );
+}
+
+TQFontEngineBox::~TQFontEngineBox()
+{
+}
+
+TQFontEngine::Error TQFontEngineBox::stringToCMap( const TQChar *, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool ) const
+{
+ if ( *nglyphs < len ) {
+ *nglyphs = len;
+ return OutOfMemory;
+ }
+
+ memset( glyphs, 0, len * sizeof( glyph_t ) );
+ *nglyphs = len;
+
+ if ( advances ) {
+ for ( int i = 0; i < len; i++ )
+ *(advances++) = _size;
+ }
+ return NoError;
+}
+
+void TQFontEngineBox::draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags )
+{
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ TQt::HANDLE hd = p->tqdevice()->handle();
+ GC gc = p->gc;
+
+#ifdef FONTENGINE_DEBUG
+ p->save();
+ p->setBrush( TQt::white );
+ glyph_metrics_t ci = boundingBox( glyphs, offsets, numGlyphs );
+ p->drawRect( x + ci.x, y + ci.y, ci.width, ci.height );
+ p->drawRect( x + ci.x, y + 50 + ci.y, ci.width, ci.height );
+ qDebug("bounding rect=%d %d (%d/%d)", ci.x, ci.y, ci.width, ci.height );
+ p->restore();
+ int xp = x;
+ int yp = y;
+#endif
+
+ GlyphAttributes *glyphAttributes = engine->glyphAttributes( si );
+
+ if ( p->txop > TQPainter::TxTranslate ) {
+ int xp = x;
+ int yp = _size + 2;
+ int s = _size - 3;
+ for (int k = 0; k < si->num_glyphs; k++) {
+ if (!glyphAttributes[k].zeroWidth)
+ qt_draw_transformed_rect( p, xp, yp, s, s, FALSE );
+ xp += _size;
+ }
+ } else {
+ if ( p->txop == TQPainter::TxTranslate )
+ p->map( x, y, &x, &y );
+
+ XRectangle rects[64];
+
+ int gl = 0;
+ while (gl < si->num_glyphs) {
+ int toDraw = TQMIN(64, si->num_glyphs-gl);
+ int adv = toDraw*_size;
+ if (x + adv < SHRT_MAX && x > SHRT_MIN) {
+ int ng = 0;
+ for (int k = 0; k < toDraw; k++) {
+ if (!glyphAttributes[gl + k].zeroWidth) {
+ rects[ng].x = x + (k * _size);
+ rects[ng].y = y - _size + 2;
+ rects[ng].width = rects[k].height = _size - 3;
+ ++ng;
+ }
+ }
+ XDrawRectangles(dpy, hd, gc, rects, ng);
+ }
+ gl += toDraw;
+ x += adv;
+ }
+ }
+
+ if ( textFlags != 0 )
+ drawLines( p, this, y, x, si->num_glyphs*_size, textFlags );
+
+#ifdef FONTENGINE_DEBUG
+ x = xp;
+ y = yp;
+ p->save();
+ p->setPen( TQt::red );
+ for ( int i = 0; i < numGlyphs; i++ ) {
+ glyph_metrics_t ci = boundingBox( glyphs[i] );
+ x += offsets[i].x;
+ y += offsets[i].y;
+ p->drawRect( x + ci.x, y + 50 + ci.y, ci.width, ci.height );
+ qDebug("bounding ci[%d]=%d %d (%d/%d) / %d %d offset=(%d/%d)", i, ci.x, ci.y, ci.width, ci.height,
+ ci.xoff, ci.yoff, offsets[i].x, offsets[i].y );
+ x += ci.xoff;
+ y += ci.yoff;
+ }
+ p->restore();
+#endif
+}
+
+glyph_metrics_t TQFontEngineBox::boundingBox( const glyph_t *, const advance_t *, const qoffset_t *, int numGlyphs )
+{
+ glyph_metrics_t overall;
+ overall.x = overall.y = 0;
+ overall.width = _size*numGlyphs;
+ overall.height = _size;
+ overall.xoff = overall.width;
+ overall.yoff = 0;
+ return overall;
+}
+
+glyph_metrics_t TQFontEngineBox::boundingBox( glyph_t )
+{
+ return glyph_metrics_t( 0, _size, _size, _size, _size, 0 );
+}
+
+
+
+int TQFontEngineBox::ascent() const
+{
+ return _size;
+}
+
+int TQFontEngineBox::descent() const
+{
+ return 0;
+}
+
+int TQFontEngineBox::leading() const
+{
+ int l = tqRound( _size * 0.15 );
+ return (l > 0) ? l : 1;
+}
+
+int TQFontEngineBox::maxCharWidth() const
+{
+ return _size;
+}
+
+int TQFontEngineBox::cmap() const
+{
+ return -1;
+}
+
+const char *TQFontEngineBox::name() const
+{
+ return "null";
+}
+
+bool TQFontEngineBox::canRender( const TQChar *, int )
+{
+ return TRUE;
+}
+
+TQFontEngine::Type TQFontEngineBox::type() const
+{
+ return Box;
+}
+
+
+
+
+// ------------------------------------------------------------------
+// Xlfd cont engine
+// ------------------------------------------------------------------
+
+static inline XCharStruct *charStruct( XFontStruct *xfs, uint ch )
+{
+ XCharStruct *xcs = 0;
+ unsigned char r = ch>>8;
+ unsigned char c = ch&0xff;
+ if ( r >= xfs->min_byte1 &&
+ r <= xfs->max_byte1 &&
+ c >= xfs->min_char_or_byte2 &&
+ c <= xfs->max_char_or_byte2) {
+ if ( !xfs->per_char )
+ xcs = &(xfs->min_bounds);
+ else {
+ xcs = xfs->per_char + ((r - xfs->min_byte1) *
+ (xfs->max_char_or_byte2 -
+ xfs->min_char_or_byte2 + 1)) +
+ (c - xfs->min_char_or_byte2);
+ if (xcs->width == 0 && xcs->ascent == 0 && xcs->descent == 0)
+ xcs = 0;
+ }
+ }
+ return xcs;
+}
+
+TQFontEngineXLFD::TQFontEngineXLFD( XFontStruct *fs, const char *name, int mib )
+ : _fs( fs ), _name( name ), _codec( 0 ), _scale( 1. ), _cmap( mib )
+{
+ if ( _cmap ) _codec = TQTextCodec::codecForMib( _cmap );
+
+ cache_cost = (((fs->max_byte1 - fs->min_byte1) *
+ (fs->max_char_or_byte2 - fs->min_char_or_byte2 + 1)) +
+ fs->max_char_or_byte2 - fs->min_char_or_byte2);
+ cache_cost = ((fs->max_bounds.ascent + fs->max_bounds.descent) *
+ (fs->max_bounds.width * cache_cost / 8));
+ lbearing = SHRT_MIN;
+ rbearing = SHRT_MIN;
+
+#if 1
+ // Server side transformations do not seem to work correctly for
+ // all types of fonts (for example, it works for bdf/pcf fonts,
+ // but not for ttf). It also seems to be extermely server
+ // dependent. The best thing is to just disable server side
+ // transformations until either server support matures or we
+ // figure out a better way to do it.
+ xlfd_transformations = XlfdTrUnsupported;
+#else
+ xlfd_transformations = XlfdTrUnknown;
+
+ // Hummingbird's Exceed X server will substitute 'fixed' for any
+ // known fonts, and it doesn't seem to support transformations, so
+ // we should never try to use xlfd transformations with it
+ if (strstr(ServerVendor(TQPaintDevice::x11AppDisplay()), "Hummingbird"))
+ xlfd_transformations = XlfdTrUnsupported;
+#endif
+}
+
+TQFontEngineXLFD::~TQFontEngineXLFD()
+{
+ XFreeFont( TQPaintDevice::x11AppDisplay(), _fs );
+ _fs = 0;
+ TransformedFont *trf = transformed_fonts;
+ while ( trf ) {
+ XUnloadFont( TQPaintDevice::x11AppDisplay(), trf->xlfd_font );
+ TransformedFont *tmp = trf;
+ trf = trf->next;
+ delete tmp;
+ }
+}
+
+TQFontEngine::Error TQFontEngineXLFD::stringToCMap( const TQChar *str, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool mirrored ) const
+{
+ if ( *nglyphs < len ) {
+ *nglyphs = len;
+ return OutOfMemory;
+ }
+
+ if ( _codec ) {
+ bool haveNbsp = FALSE;
+ for ( int i = 0; i < len; i++ )
+ if ( str[i].tqunicode() == 0xa0 ) {
+ haveNbsp = TRUE;
+ break;
+ }
+
+ TQChar *chars = (TQChar *)str;
+ if ( haveNbsp || mirrored ) {
+ chars = (TQChar *)malloc( len*sizeof(TQChar) );
+ for ( int i = 0; i < len; i++ )
+ chars[i] = (str[i].tqunicode() == 0xa0 ? 0x20 :
+ (mirrored ? ::mirroredChar(str[i]).tqunicode() : str[i].tqunicode()));
+ }
+ _codec->fromUnicodeInternal( chars, glyphs, len );
+ if (chars != str)
+ free( chars );
+ } else {
+ glyph_t *g = glyphs + len;
+ const TQChar *c = str + len;
+ if ( mirrored ) {
+ while ( c != str )
+ *(--g) = (--c)->tqunicode() == 0xa0 ? 0x20 : ::mirroredChar(*c).tqunicode();
+ } else {
+ while ( c != str )
+ *(--g) = (--c)->tqunicode() == 0xa0 ? 0x20 : c->tqunicode();
+ }
+ }
+ *nglyphs = len;
+
+ if ( advances ) {
+ glyph_t *g = glyphs + len;
+ advance_t *a = advances + len;
+ XCharStruct *xcs;
+ // inlined for better perfomance
+ if ( !_fs->per_char ) {
+ xcs = &_fs->min_bounds;
+ while ( a != advances )
+ *(--a) = xcs->width;
+ }
+ else if ( !_fs->max_byte1 ) {
+ XCharStruct *base = _fs->per_char - _fs->min_char_or_byte2;
+ while ( g-- != glyphs ) {
+ unsigned int gl = *g;
+ xcs = (gl >= _fs->min_char_or_byte2 && gl <= _fs->max_char_or_byte2) ?
+ base + gl : 0;
+ *(--a) = (!xcs || (!xcs->width && !xcs->ascent && !xcs->descent)) ? _fs->ascent : xcs->width;
+ }
+ }
+ else {
+ while ( g != glyphs ) {
+ xcs = charStruct( _fs, *(--g) );
+ *(--a) = (xcs ? xcs->width : _fs->ascent);
+ }
+ }
+ if ( _scale != 1. ) {
+ for ( int i = 0; i < len; i++ )
+ advances[i] = tqRound(advances[i]*_scale);
+ }
+ }
+ return NoError;
+}
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static bool x_font_load_error = FALSE;
+static int x_font_errorhandler(Display *, XErrorEvent *)
+{
+ x_font_load_error = TRUE;
+ return 0;
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+void TQFontEngineXLFD::draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags )
+{
+ if ( !si->num_glyphs )
+ return;
+
+// qDebug("TQFontEngineXLFD::draw( %d, %d, numglyphs=%d", x, y, si->num_glyphs );
+
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ TQt::HANDLE hd = p->tqdevice()->handle();
+ GC gc = p->gc;
+
+ bool transform = FALSE;
+ int xorig = x;
+ int yorig = y;
+
+ TQt::HANDLE font_id = _fs->fid;
+ if ( p->txop > TQPainter::TxTranslate || _scale < 0.9999 || _scale > 1.0001 ) {
+ bool degenerate = TQABS( p->m11()*p->m22() - p->m12()*p->m21() ) < 0.01;
+ if ( !degenerate && xlfd_transformations != XlfdTrUnsupported ) {
+ // need a transformed font from the server
+ TQCString xlfd_transformed = _name;
+ int field = 0;
+ char *data = xlfd_transformed.data();
+ int pos = 0;
+ while ( field < 7 ) {
+ if ( data[pos] == '-' )
+ field++;
+ pos++;
+ }
+ int endPos = pos;
+ while ( data[endPos] != '-' )
+ endPos++;
+ float size = xlfd_transformed.mid( pos, endPos-pos ).toInt();
+ float mat[4];
+ mat[0] = p->m11()*size*_scale;
+ mat[1] = -p->m12()*size*_scale;
+ mat[2] = -p->m21()*size*_scale;
+ mat[3] = p->m22()*size*_scale;
+
+ // check if we have it cached
+ TransformedFont *trf = transformed_fonts;
+ TransformedFont *prev = 0;
+ int i = 0;
+ while ( trf ) {
+ if ( trf->xx == mat[0] &&
+ trf->xy == mat[1] &&
+ trf->yx == mat[2] &&
+ trf->yy == mat[3] )
+ break;
+ TransformedFont *tmp = trf;
+ trf = trf->next;
+ if (i > 10) {
+ XUnloadFont( TQPaintDevice::x11AppDisplay(), tmp->xlfd_font );
+ delete tmp;
+ prev->next = trf;
+ } else {
+ prev = tmp;
+ }
+ ++i;
+ }
+ if ( trf ) {
+ if ( prev ) {
+ // move to beginning of list
+ prev->next = trf->next;
+ trf->next = transformed_fonts;
+ transformed_fonts = trf;
+ }
+ font_id = trf->xlfd_font;
+ } else {
+ TQCString matrix="[";
+ for ( int i = 0; i < 4; i++ ) {
+ float f = mat[i];
+ if ( f < 0 ) {
+ matrix += '~';
+ f = -f;
+ }
+ matrix += TQString::number( f, 'f', 5 ).latin1();
+ matrix += ' ';
+ }
+ matrix += ']';
+ //qDebug("m: %2.2f %2.2f %2.2f %2.2f, matrix=%s", p->m11(), p->m12(), p->m21(), p->m22(), matrix.data());
+ xlfd_transformed.tqreplace( pos, endPos-pos, matrix );
+
+ x_font_load_error = FALSE;
+ XErrorHandler old_handler = XSetErrorHandler( x_font_errorhandler );
+ font_id = XLoadFont( dpy, xlfd_transformed.data() );
+ XSync( dpy, FALSE );
+ XSetErrorHandler( old_handler );
+ if ( x_font_load_error ) {
+ //qDebug( "couldn't load transformed font" );
+ font_id = _fs->fid;
+ xlfd_transformations = XlfdTrUnsupported;
+ } else {
+ TransformedFont *trf = new TransformedFont;
+ trf->xx = mat[0];
+ trf->xy = mat[1];
+ trf->yx = mat[2];
+ trf->yy = mat[3];
+ trf->xlfd_font = font_id;
+ trf->next = transformed_fonts;
+ transformed_fonts = trf;
+ }
+ }
+ }
+ if ( degenerate || xlfd_transformations == XlfdTrUnsupported ) {
+ // XServer or font don't support server side transformations, need to do it by hand
+ float tmp = _scale;
+ _scale = 1.;
+ drawScaled(x, y, engine, si, textFlags, dpy, p->gc, p->tqdevice(), this, p->xmat, tmp);
+ _scale = tmp;
+ return;
+ }
+ transform = TRUE;
+ } else if ( p->txop == TQPainter::TxTranslate ) {
+ p->map( x, y, &x, &y );
+ }
+
+ XSetFont(dpy, gc, font_id);
+
+#ifdef FONTENGINE_DEBUG
+ p->save();
+ p->setBrush( TQt::white );
+ glyph_metrics_t ci = boundingBox( glyphs, advances, offsets, si->num_glyphs );
+ p->drawRect( x + ci.x, y + ci.y, ci.width, ci.height );
+ p->drawRect( x + ci.x, y + 100 + ci.y, ci.width, ci.height );
+ qDebug("bounding rect=%d %d (%d/%d)", ci.x, ci.y, ci.width, ci.height );
+ p->restore();
+ int xp = x;
+ int yp = y;
+#endif
+
+ glyph_t *glyphs = engine->glyphs( si );
+ advance_t *advances = engine->advances( si );
+ qoffset_t *offsets = engine->offsets( si );
+
+ XChar2b ch[256];
+ XChar2b *chars = ch;
+ if ( si->num_glyphs > 255 )
+ chars = (XChar2b *)malloc( si->num_glyphs*sizeof(XChar2b) );
+
+ for (int i = 0; i < si->num_glyphs; i++) {
+ chars[i].byte1 = glyphs[i] >> 8;
+ chars[i].byte2 = glyphs[i] & 0xff;
+ }
+
+ int xpos = x;
+ GlyphAttributes *glyphAttributes = engine->glyphAttributes( si );
+
+ if ( si->analysis.bidiLevel % 2 ) {
+ int i = si->num_glyphs;
+ while( i-- ) {
+ advance_t adv = advances[i];
+ // qDebug("advance = %d/%d", adv.x, adv.y );
+ x += adv;
+ glyph_metrics_t gi = boundingBox( glyphs[i] );
+ int xp = x-offsets[i].x-gi.xoff;
+ int yp = y+offsets[i].y-gi.yoff;
+ if ( transform )
+ p->map( xp, yp, &xp, &yp );
+ if (!glyphAttributes[i].zeroWidth && xp < SHRT_MAX && xp > SHRT_MIN)
+ XDrawString16(dpy, hd, gc, xp, yp, chars+i, 1 );
+ }
+ } else {
+ if ( transform || si->hasPositioning ) {
+ int i = 0;
+ while( i < si->num_glyphs ) {
+ int xp = x+offsets[i].x;
+ int yp = y+offsets[i].y;
+ if ( transform )
+ p->map( xp, yp, &xp, &yp );
+ if (!glyphAttributes[i].zeroWidth && xp < SHRT_MAX && xp > SHRT_MIN)
+ XDrawString16(dpy, hd, gc, xp, yp, chars+i, 1 );
+ advance_t adv = advances[i];
+ // qDebug("advance = %d/%d", adv.x, adv.y );
+ x += adv;
+ i++;
+ }
+ } else {
+ // we can take a shortcut
+ int gl = 0;
+ while (gl < si->num_glyphs) {
+ int toDraw = TQMIN(64, si->num_glyphs-gl);
+ int adv = 0;
+ for (int i = gl; i < gl+toDraw; ++i)
+ adv += advances[i];
+ if (x + adv < SHRT_MAX && x > SHRT_MIN)
+ XDrawString16(dpy, hd, gc, x, y, chars+gl, toDraw);
+ gl += toDraw;
+ x += adv;
+ }
+ }
+ }
+
+ if ( chars != ch )
+ free( chars );
+
+ if ( textFlags != 0 )
+ drawLines( p, this, yorig, xorig, x-xpos, textFlags );
+
+#ifdef FONTENGINE_DEBUG
+ x = xp;
+ y = yp;
+ p->save();
+ p->setPen( TQt::red );
+ for ( int i = 0; i < si->num_glyphs; i++ ) {
+ glyph_metrics_t ci = boundingBox( glyphs[i] );
+ p->drawRect( x + ci.x + offsets[i].x, y + 100 + ci.y + offsets[i].y, ci.width, ci.height );
+ qDebug("bounding ci[%d]=%d %d (%d/%d) / %d %d offs=(%d/%d) advance=(%d/%d)", i, ci.x, ci.y, ci.width, ci.height,
+ ci.xoff, ci.yoff, offsets[i].x, offsets[i].y,
+ advances[i].x, advances[i].y);
+ x += advances[i].x;
+ y += advances[i].y;
+ }
+ p->restore();
+#endif
+}
+
+glyph_metrics_t TQFontEngineXLFD::boundingBox( const glyph_t *glyphs, const advance_t *advances, const qoffset_t *offsets, int numGlyphs )
+{
+ int i;
+
+ glyph_metrics_t overall;
+ int ymax = 0;
+ int xmax = 0;
+ for (i = 0; i < numGlyphs; i++) {
+ XCharStruct *xcs = charStruct( _fs, glyphs[i] );
+ if (xcs) {
+ int x = overall.xoff + offsets[i].x - xcs->lbearing;
+ int y = overall.yoff + offsets[i].y - xcs->ascent;
+ overall.x = TQMIN( overall.x, x );
+ overall.y = TQMIN( overall.y, y );
+ xmax = TQMAX( xmax, overall.xoff + offsets[i].x + xcs->rbearing );
+ ymax = TQMAX( ymax, y + xcs->ascent + xcs->descent );
+ overall.xoff += tqRound(advances[i]/_scale);
+ } else {
+ int size = _fs->ascent;
+ overall.x = TQMIN(overall.x, overall.xoff );
+ overall.y = TQMIN(overall.y, overall.yoff - size );
+ ymax = TQMAX( ymax, overall.yoff );
+ overall.xoff += size;
+ xmax = TQMAX( xmax, overall.xoff );
+ }
+ }
+ overall.height = ymax - overall.y;
+ overall.width = xmax - overall.x;
+
+ if ( _scale != 1. ) {
+ overall.x = tqRound(overall.x * _scale);
+ overall.y = tqRound(overall.y * _scale);
+ overall.height = tqRound(overall.height * _scale);
+ overall.width = tqRound(overall.width * _scale);
+ overall.xoff = tqRound(overall.xoff * _scale);
+ overall.yoff = tqRound(overall.yoff * _scale);
+ }
+ return overall;
+}
+
+glyph_metrics_t TQFontEngineXLFD::boundingBox( glyph_t glyph )
+{
+ glyph_metrics_t gm;
+ // ### scale missing!
+ XCharStruct *xcs = charStruct( _fs, glyph );
+ if (xcs) {
+ gm = glyph_metrics_t( xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent, xcs->width, 0 );
+ } else {
+ int size = _fs->ascent;
+ gm = glyph_metrics_t( 0, size, size, size, size, 0 );
+ }
+ if ( _scale != 1. ) {
+ gm.x = tqRound(gm.x * _scale);
+ gm.y = tqRound(gm.y * _scale);
+ gm.height = tqRound(gm.height * _scale);
+ gm.width = tqRound(gm.width * _scale);
+ gm.xoff = tqRound(gm.xoff * _scale);
+ gm.yoff = tqRound(gm.yoff * _scale);
+ }
+ return gm;
+}
+
+
+int TQFontEngineXLFD::ascent() const
+{
+ return tqRound(_fs->ascent*_scale);
+}
+
+int TQFontEngineXLFD::descent() const
+{
+ return tqRound((_fs->descent-1)*_scale);
+}
+
+int TQFontEngineXLFD::leading() const
+{
+ int l = tqRound((TQMIN(_fs->ascent, _fs->max_bounds.ascent)
+ + TQMIN(_fs->descent, _fs->max_bounds.descent)) * _scale * 0.15 );
+ return (l > 0) ? l : 1;
+}
+
+int TQFontEngineXLFD::maxCharWidth() const
+{
+ return tqRound(_fs->max_bounds.width*_scale);
+}
+
+
+// Loads the font for the specified script
+static inline int maxIndex(XFontStruct *f) {
+ return (((f->max_byte1 - f->min_byte1) *
+ (f->max_char_or_byte2 - f->min_char_or_byte2 + 1)) +
+ f->max_char_or_byte2 - f->min_char_or_byte2);
+}
+
+int TQFontEngineXLFD::minLeftBearing() const
+{
+ if ( lbearing == SHRT_MIN ) {
+ if ( _fs->per_char ) {
+ XCharStruct *cs = _fs->per_char;
+ int nc = maxIndex(_fs) + 1;
+ int mx = cs->lbearing;
+
+ for (int c = 1; c < nc; c++) {
+ // ignore the bearings for characters whose ink is
+ // completely outside the normal bounding box
+ if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
+ (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
+ continue;
+
+ int nmx = cs[c].lbearing;
+
+ if (nmx < mx)
+ mx = nmx;
+ }
+
+ ((TQFontEngineXLFD *)this)->lbearing = mx;
+ } else
+ ((TQFontEngineXLFD *)this)->lbearing = _fs->min_bounds.lbearing;
+ }
+ return tqRound (lbearing*_scale);
+}
+
+int TQFontEngineXLFD::minRightBearing() const
+{
+ if ( rbearing == SHRT_MIN ) {
+ if ( _fs->per_char ) {
+ XCharStruct *cs = _fs->per_char;
+ int nc = maxIndex(_fs) + 1;
+ int mx = cs->rbearing;
+
+ for (int c = 1; c < nc; c++) {
+ // ignore the bearings for characters whose ink is
+ // completely outside the normal bounding box
+ if ((cs[c].lbearing <= 0 && cs[c].rbearing <= 0) ||
+ (cs[c].lbearing >= cs[c].width && cs[c].rbearing >= cs[c].width))
+ continue;
+
+ int nmx = cs[c].rbearing;
+
+ if (nmx < mx)
+ mx = nmx;
+ }
+
+ ((TQFontEngineXLFD *)this)->rbearing = mx;
+ } else
+ ((TQFontEngineXLFD *)this)->rbearing = _fs->min_bounds.rbearing;
+ }
+ return tqRound (rbearing*_scale);
+}
+
+int TQFontEngineXLFD::cmap() const
+{
+ return _cmap;
+}
+
+const char *TQFontEngineXLFD::name() const
+{
+ return _name;
+}
+
+bool TQFontEngineXLFD::canRender( const TQChar *string, int len )
+{
+ glyph_t glyphs[256];
+ int nglyphs = 255;
+ glyph_t *g = glyphs;
+ if ( stringToCMap( string, len, g, 0, &nglyphs, FALSE ) == OutOfMemory ) {
+ g = (glyph_t *)malloc( nglyphs*sizeof(glyph_t) );
+ stringToCMap( string, len, g, 0, &nglyphs, FALSE );
+ }
+
+ bool allExist = TRUE;
+ for ( int i = 0; i < nglyphs; i++ ) {
+ if ( !g[i] || !charStruct( _fs, g[i] ) ) {
+ allExist = FALSE;
+ break;
+ }
+ }
+
+ if ( g != glyphs )
+ free( g );
+
+ return allExist;
+}
+
+
+void TQFontEngineXLFD::setScale( double scale )
+{
+ _scale = scale;
+}
+
+
+TQFontEngine::Type TQFontEngineXLFD::type() const
+{
+ return XLFD;
+}
+
+
+// ------------------------------------------------------------------
+// LatinXLFD engine
+// ------------------------------------------------------------------
+
+static const int engine_array_inc = 4;
+
+TQFontEngineLatinXLFD::TQFontEngineLatinXLFD( XFontStruct *xfs, const char *name,
+ int mib )
+{
+ _engines = new TQFontEngine*[ engine_array_inc ];
+ _engines[0] = new TQFontEngineXLFD( xfs, name, mib );
+ _count = 1;
+
+ cache_cost = _engines[0]->cache_cost;
+
+ memset( glyphIndices, 0, sizeof( glyphIndices ) );
+ memset( glyphAdvances, 0, sizeof( glyphAdvances ) );
+ euroIndex = 0;
+ euroAdvance = 0;
+}
+
+TQFontEngineLatinXLFD::~TQFontEngineLatinXLFD()
+{
+ for ( int i = 0; i < _count; ++i ) {
+ delete _engines[i];
+ _engines[i] = 0;
+ }
+ delete [] _engines;
+ _engines = 0;
+}
+
+void TQFontEngineLatinXLFD::tqfindEngine( const TQChar &ch )
+{
+ if ( ch.tqunicode() == 0 ) return;
+
+ static const char *alternate_encodings[] = {
+ "iso8859-1",
+ "iso8859-2",
+ "iso8859-3",
+ "iso8859-4",
+ "iso8859-9",
+ "iso8859-10",
+ "iso8859-13",
+ "iso8859-14",
+ "iso8859-15",
+ "hp-roman8"
+ };
+ static const int mib_count = sizeof( alternate_encodings ) / sizeof( const char * );
+
+ // see if one of the above mibs can map the char we want
+ TQTextCodec *codec = 0;
+ int which = -1;
+ int i;
+ for ( i = 0; i < mib_count; ++i ) {
+ const int mib = qt_mib_for_xlfd_encoding( alternate_encodings[i] );
+ bool skip = FALSE;
+ for ( int e = 0; e < _count; ++e ) {
+ if ( _engines[e]->cmap() == mib ) {
+ skip = TRUE;
+ break;
+ }
+ }
+ if ( skip ) continue;
+
+ codec = TQTextCodec::codecForMib( mib );
+ if ( codec && codec->canEncode( ch ) ) {
+ which = i;
+ break;
+ }
+ }
+
+ if ( ! codec || which == -1 )
+ return;
+
+ const int enc_id = qt_xlfd_encoding_id( alternate_encodings[which] );
+ TQFontDef req = fontDef;
+ TQFontEngine *engine = TQFontDatabase::tqfindFont( TQFont::Latin, 0, req, enc_id );
+ if ( ! engine ) {
+ req.family = TQString::null;
+ engine = TQFontDatabase::tqfindFont( TQFont::Latin, 0, req, enc_id );
+ if ( ! engine ) return;
+ }
+ engine->setScale( scale() );
+
+ if ( ! ( _count % engine_array_inc ) ) {
+ // grow the engines array
+ TQFontEngine **old = _engines;
+ int new_size =
+ ( ( ( _count+engine_array_inc ) / engine_array_inc ) * engine_array_inc );
+ _engines = new TQFontEngine*[new_size];
+ for ( i = 0; i < _count; ++i )
+ _engines[i] = old[i];
+ delete [] old;
+ }
+
+ _engines[_count] = engine;
+ const int hi = _count << 8;
+ ++_count;
+
+ unsigned short chars[0x201];
+ glyph_t glyphs[0x201];
+ advance_t advances[0x201];
+ for ( i = 0; i < 0x200; ++i )
+ chars[i] = i;
+ chars[0x200] = 0x20ac;
+ int glyphCount = 0x201;
+ engine->stringToCMap( (const TQChar *) chars, 0x201, glyphs, advances, &glyphCount, FALSE );
+
+ // merge member data with the above
+ for ( i = 0; i < 0x200; ++i ) {
+ if ( glyphIndices[i] != 0 || glyphs[i] == 0 ) continue;
+ glyphIndices[i] = glyphs[i] >= 0x2100 ? glyphs[i] : hi | glyphs[i];
+ glyphAdvances[i] = advances[i];
+ }
+ if (!euroIndex && glyphs[0x200]) {
+ euroIndex = hi | glyphs[0x200];
+ euroAdvance = advances[0x200];
+ }
+}
+
+TQFontEngine::Error
+TQFontEngineLatinXLFD::stringToCMap( const TQChar *str, int len, glyph_t *glyphs,
+ advance_t *advances, int *nglyphs, bool mirrored ) const
+{
+ if ( *nglyphs < len ) {
+ *nglyphs = len;
+ return OutOfMemory;
+ }
+
+ int i;
+ bool missing = FALSE;
+ const TQChar *c = str+len;
+ glyph_t *g = glyphs+len;
+ if ( advances ) {
+ int asc = ascent();
+ advance_t *a = advances+len;
+ if ( mirrored ) {
+ while ( c != str ) {
+ --c;
+ --g;
+ --a;
+ if ( c->tqunicode() < 0x200 ) {
+ unsigned short ch = ::mirroredChar(*c).tqunicode();
+ *g = glyphIndices[ch];
+ *a = glyphAdvances[ch];
+ } else {
+ if ( c->tqunicode() == 0x20ac ) {
+ *g = euroIndex;
+ *a = euroAdvance;
+ } else {
+ *g = 0;
+ *a = asc;
+ }
+ }
+ missing = ( missing || ( *g == 0 ) );
+ }
+ } else {
+ while ( c != str ) {
+ --c;
+ --g;
+ --a;
+ if ( c->tqunicode() < 0x200 ) {
+ *g = glyphIndices[c->tqunicode()];
+ *a = glyphAdvances[c->tqunicode()];
+ } else {
+ if ( c->tqunicode() == 0x20ac ) {
+ *g = euroIndex;
+ *a = euroAdvance;
+ } else {
+ *g = 0;
+ *a = asc;
+ }
+ }
+ missing = ( missing || ( *g == 0 ) );
+ }
+ }
+ } else {
+ if ( mirrored ) {
+ while ( c != str ) {
+ --c;
+ --g;
+ *g = ( ( c->tqunicode() < 0x200 ) ? glyphIndices[::mirroredChar(*c).tqunicode()]
+ : (c->tqunicode() == 0x20ac) ? euroIndex : 0 );
+ missing = ( missing || ( *g == 0 ) );
+ }
+ } else {
+ while ( c != str ) {
+ --c;
+ --g;
+ *g = ( ( c->tqunicode() < 0x200 ) ? glyphIndices[c->tqunicode()]
+ : (c->tqunicode() == 0x20ac) ? euroIndex : 0 );
+ missing = ( missing || ( *g == 0 ) );
+ }
+ }
+ }
+
+ if ( missing ) {
+ for ( i = 0; i < len; ++i ) {
+ unsigned short uc = str[i].tqunicode();
+ if ( glyphs[i] != 0 || (uc >= 0x200 && uc != 0x20ac) )
+ continue;
+
+ TQFontEngineLatinXLFD *that = (TQFontEngineLatinXLFD *) this;
+ that->tqfindEngine( str[i] );
+ glyphs[i] = (uc == 0x20ac ? euroIndex : that->glyphIndices[uc]);
+ if ( advances )
+ advances[i] = (uc == 0x20ac ? euroAdvance : glyphAdvances[uc]);
+ }
+ }
+
+ *nglyphs = len;
+ return NoError;
+}
+
+void TQFontEngineLatinXLFD::draw( TQPainter *p, int x, int y, const TQTextEngine *engine,
+ const TQScriptItem *si, int textFlags )
+{
+ if ( !si->num_glyphs ) return;
+
+ glyph_t *glyphs = engine->glyphs( si );
+ advance_t *advances = engine->advances( si );
+ int which = glyphs[0] >> 8;
+ if (which > 0x20)
+ which = 0;
+
+ int start = 0;
+ int end, i;
+ for ( end = 0; end < si->num_glyphs; ++end ) {
+ int e = glyphs[end] >> 8;
+ if (e > 0x20)
+ e = 0;
+ if ( e == which ) continue;
+
+ // set the high byte to zero
+ if (which != 0) {
+ for ( i = start; i < end; ++i )
+ glyphs[i] = glyphs[i] & 0xff;
+ }
+
+ // draw the text
+ TQScriptItem si2 = *si;
+ si2.glyph_data_offset = si->glyph_data_offset + start;
+ si2.num_glyphs = end - start;
+ _engines[which]->draw( p, x, y, engine, &si2, textFlags );
+
+ // reset the high byte for all glyphs and advance to the next sub-string
+ const int hi = which << 8;
+ for ( i = start; i < end; ++i ) {
+ glyphs[i] = hi | glyphs[i];
+ x += advances[i];
+ }
+
+ // change engine
+ start = end;
+ which = e;
+ }
+
+ // set the high byte to zero
+ if (which != 0) {
+ for ( i = start; i < end; ++i )
+ glyphs[i] = glyphs[i] & 0xff;
+ }
+ // draw the text
+ TQScriptItem si2 = *si;
+ si2.glyph_data_offset = si->glyph_data_offset + start;
+ si2.num_glyphs = end - start;
+ _engines[which]->draw( p, x, y, engine, &si2, textFlags );
+
+ // reset the high byte for all glyphs
+ if (which != 0) {
+ const int hi = which << 8;
+ for ( i = start; i < end; ++i )
+ glyphs[i] = hi | glyphs[i];
+ }
+}
+
+glyph_metrics_t TQFontEngineLatinXLFD::boundingBox( const glyph_t *glyphs_const,
+ const advance_t *advances,
+ const qoffset_t *offsets,
+ int numGlyphs )
+{
+ if ( numGlyphs <= 0 ) return glyph_metrics_t();
+
+ glyph_metrics_t overall;
+
+ glyph_t *glyphs = (glyph_t *) glyphs_const;
+ int which = glyphs[0] >> 8;
+ if (which > 0x20)
+ which = 0;
+
+ int start = 0;
+ int end, i;
+ for ( end = 0; end < numGlyphs; ++end ) {
+ int e = glyphs[end] >> 8;
+ if (e > 0x20)
+ e = 0;
+ if ( e == which ) continue;
+
+ // set the high byte to zero
+ if (which != 0) {
+ for ( i = start; i < end; ++i )
+ glyphs[i] = glyphs[i] & 0xff;
+ }
+
+ // merge the bounding box for this run
+ const glyph_metrics_t gm =
+ _engines[which]->boundingBox( glyphs + start,
+ advances + start,
+ offsets + start,
+ end - start );
+
+ overall.x = TQMIN( overall.x, gm.x );
+ overall.y = TQMIN( overall.y, gm.y );
+ overall.width = overall.xoff + gm.width;
+ overall.height = TQMAX( overall.height + overall.y, gm.height + gm.y ) -
+ TQMIN( overall.y, gm.y );
+ overall.xoff += gm.xoff;
+ overall.yoff += gm.yoff;
+
+ // reset the high byte for all glyphs
+ if (which != 0) {
+ const int hi = which << 8;
+ for ( i = start; i < end; ++i )
+ glyphs[i] = hi | glyphs[i];
+ }
+
+ // change engine
+ start = end;
+ which = e;
+ }
+
+ // set the high byte to zero
+ if (which != 0) {
+ for ( i = start; i < end; ++i )
+ glyphs[i] = glyphs[i] & 0xff;
+ }
+
+ // merge the bounding box for this run
+ const glyph_metrics_t gm =
+ _engines[which]->boundingBox( glyphs + start,
+ advances + start,
+ offsets + start,
+ end - start );
+
+ overall.x = TQMIN( overall.x, gm.x );
+ overall.y = TQMIN( overall.y, gm.y );
+ overall.width = overall.xoff + gm.width;
+ overall.height = TQMAX( overall.height + overall.y, gm.height + gm.y ) -
+ TQMIN( overall.y, gm.y );
+ overall.xoff += gm.xoff;
+ overall.yoff += gm.yoff;
+
+ // reset the high byte for all glyphs
+ if (which != 0) {
+ const int hi = which << 8;
+ for ( i = start; i < end; ++i )
+ glyphs[i] = hi | glyphs[i];
+ }
+
+ return overall;
+}
+
+glyph_metrics_t TQFontEngineLatinXLFD::boundingBox( glyph_t glyph )
+{
+ int engine = glyph >> 8;
+ if (engine > 0x20)
+ engine = 0;
+ TQ_ASSERT( engine < _count );
+ return _engines[engine]->boundingBox( engine > 0 ? glyph & 0xff : glyph );
+}
+
+int TQFontEngineLatinXLFD::ascent() const
+{
+ return _engines[0]->ascent();
+}
+
+int TQFontEngineLatinXLFD::descent() const
+{
+ return _engines[0]->descent();
+}
+
+int TQFontEngineLatinXLFD::leading() const
+{
+ return _engines[0]->leading();
+}
+
+int TQFontEngineLatinXLFD::maxCharWidth() const
+{
+ return _engines[0]->maxCharWidth();
+}
+
+int TQFontEngineLatinXLFD::minLeftBearing() const
+{
+ return _engines[0]->minLeftBearing();
+}
+
+int TQFontEngineLatinXLFD::minRightBearing() const
+{
+ return _engines[0]->minRightBearing();
+}
+
+const char *TQFontEngineLatinXLFD::name() const
+{
+ return _engines[0]->name();
+}
+
+bool TQFontEngineLatinXLFD::canRender( const TQChar *string, int len )
+{
+ bool all = TRUE;
+ int i;
+ for ( i = 0; i < len; ++i ) {
+ if ( string[i].tqunicode() >= 0x200 ||
+ glyphIndices[string[i].tqunicode()] == 0 ) {
+ if (string[i].tqunicode() != 0x20ac || euroIndex == 0)
+ all = FALSE;
+ break;
+ }
+ }
+
+ if ( all )
+ return TRUE;
+
+ all = TRUE;
+ for ( i = 0; i < len; ++i ) {
+ if ( string[i].tqunicode() >= 0x200 ) {
+ if (string[i].tqunicode() == 0x20ac) {
+ if (euroIndex)
+ continue;
+
+ tqfindEngine(string[i]);
+ if (euroIndex)
+ continue;
+ }
+ all = FALSE;
+ break;
+ }
+ if ( glyphIndices[string[i].tqunicode()] != 0 ) continue;
+
+ tqfindEngine( string[i] );
+ if ( glyphIndices[string[i].tqunicode()] == 0 ) {
+ all = FALSE;
+ break;
+ }
+ }
+
+ return all;
+}
+
+void TQFontEngineLatinXLFD::setScale( double scale )
+{
+ int i;
+ for ( i = 0; i < _count; ++i )
+ _engines[i]->setScale( scale );
+ unsigned short chars[0x200];
+ for ( i = 0; i < 0x200; ++i )
+ chars[i] = i;
+ int glyphCount = 0x200;
+ _engines[0]->stringToCMap( (const TQChar *)chars, 0x200,
+ glyphIndices, glyphAdvances, &glyphCount, FALSE );
+}
+
+
+// ------------------------------------------------------------------
+// Xft cont engine
+// ------------------------------------------------------------------
+// #define FONTENGINE_DEBUG
+
+#ifndef TQT_NO_XFTFREETYPE
+class TQ_HackPaintDevice : public TQPaintDevice
+{
+public:
+ inline TQ_HackPaintDevice() : TQPaintDevice( 0 ) {}
+ inline XftDraw *xftDrawHandle() const {
+ return (XftDraw *)rendhd;
+ }
+
+};
+
+#ifdef TQT_XFT2
+static inline void getGlyphInfo( XGlyphInfo *xgi, XftFont *font, int glyph )
+{
+ FT_UInt x = glyph;
+ XftGlyphExtents( TQPaintDevice::x11AppDisplay(), font, &x, 1, xgi );
+}
+#else
+static inline XftFontStruct *getFontStruct( XftFont *font )
+{
+ if (font->core)
+ return 0;
+ return font->u.ft.font;
+}
+
+static inline void getGlyphInfo(XGlyphInfo *xgi, XftFont *font, int glyph)
+{
+
+ XftTextExtents32(TQPaintDevice::x11AppDisplay(), font, (XftChar32 *) &glyph, 1, xgi);
+}
+#endif // TQT_XFT2
+
+static inline FT_Face lockFTFace( XftFont *font )
+{
+#ifdef TQT_XFT2
+ return XftLockFace( font );
+#else
+ if (font->core) return 0;
+ return font->u.ft.font->face;
+#endif // TQT_XFT2
+}
+
+static inline void unlockFTFace( XftFont *font )
+{
+#ifdef TQT_XFT2
+ XftUnlockFace( font );
+#else
+ TQ_UNUSED( font );
+#endif // TQT_XFT2
+}
+
+
+
+TQFontEngineXft::TQFontEngineXft( XftFont *font, XftPattern *pattern, int cmap )
+ : _font( font ), _pattern( pattern ), _openType( 0 ), _cmap( cmap )
+{
+ _face = lockFTFace( _font );
+
+#ifndef TQT_XFT2
+ XftFontStruct *xftfs = getFontStruct( _font );
+ if ( xftfs ) {
+ // dirty hack: we set the charmap in the Xftfreetype to -1, so
+ // XftFreetype assumes no encoding and really draws glyph
+ // indices. The FT_Face still has the Unicode encoding to we
+ // can convert from Unicode to glyph index
+ xftfs->charmap = -1;
+ }
+#else
+ _cmap = -1;
+ // Xft maps Unicode and adobe roman for us.
+ for (int i = 0; i < _face->num_charmaps; ++i) {
+ FT_CharMap cm = _face->charmaps[i];
+// qDebug("font has charmap %x", cm->encoding);
+ if (cm->encoding == ft_encoding_adobe_custom
+ || cm->encoding == ft_encoding_symbol) {
+// qDebug("font has adobe custom or ms symbol charmap");
+ _cmap = i;
+ break;
+ }
+ }
+#endif // TQT_XFT2
+
+
+ cache_cost = _font->height * _font->max_advance_width *
+ ( _face ? _face->num_glyphs : 1024 );
+
+ // if the Xft font is not antialiased, it uses bitmaps instead of
+ // 8-bit alpha maps... adjust the cache_cost to reflect this
+ Bool antialiased = TRUE;
+ if ( XftPatternGetBool( pattern, XFT_ANTIALIAS,
+ 0, &antialiased ) == XftResultMatch &&
+ ! antialiased ) {
+ cache_cost /= 8;
+ }
+ lbearing = SHRT_MIN;
+ rbearing = SHRT_MIN;
+
+ memset( widthCache, 0, sizeof(widthCache) );
+ memset( cmapCache, 0, sizeof(cmapCache) );
+}
+
+TQFontEngineXft::~TQFontEngineXft()
+{
+ delete _openType;
+ unlockFTFace( _font );
+
+ XftFontClose( TQPaintDevice::x11AppDisplay(),_font );
+ XftPatternDestroy( _pattern );
+ _font = 0;
+ _pattern = 0;
+ TransformedFont *trf = transformed_fonts;
+ while ( trf ) {
+ XftFontClose( TQPaintDevice::x11AppDisplay(), trf->xft_font );
+ TransformedFont *tmp = trf;
+ trf = trf->next;
+ delete tmp;
+ }
+}
+
+#ifdef TQT_XFT2
+static glyph_t getAdobeCharIndex(XftFont *font, int cmap, uint ucs4)
+{
+ FT_Face _face = XftLockFace( font );
+ FT_Set_Charmap(_face, _face->charmaps[cmap]);
+ glyph_t g = FT_Get_Char_Index(_face, ucs4);
+ XftUnlockFace(font);
+ return g;
+}
+#endif
+
+TQFontEngine::Error TQFontEngineXft::stringToCMap( const TQChar *str, int len, glyph_t *glyphs, advance_t *advances, int *nglyphs, bool mirrored ) const
+{
+ if ( *nglyphs < len ) {
+ *nglyphs = len;
+ return OutOfMemory;
+ }
+
+#ifdef TQT_XFT2
+ if (_cmap != -1) {
+ for ( int i = 0; i < len; ++i ) {
+ unsigned short uc = str[i].tqunicode();
+ if (mirrored)
+ uc = ::mirroredChar(str[i]).tqunicode();
+ glyphs[i] = uc < cmapCacheSize ? cmapCache[uc] : 0;
+ if ( !glyphs[i] ) {
+ glyph_t glyph = XftCharIndex(0, _font, uc);
+ if (!glyph)
+ glyph = getAdobeCharIndex(_font, _cmap, uc);
+ glyphs[i] = glyph;
+ if ( uc < cmapCacheSize )
+ ((TQFontEngineXft *)this)->cmapCache[uc] = glyph;
+ }
+ }
+ } else if ( mirrored ) {
+ for ( int i = 0; i < len; ++i ) {
+ unsigned short uc = ::mirroredChar(str[i]).tqunicode();
+ glyphs[i] = uc < cmapCacheSize ? cmapCache[uc] : 0;
+ if ( !glyphs[i] ) {
+ if (uc == 0xa0)
+ uc = 0x20;
+ glyph_t glyph = XftCharIndex(0, _font, uc);
+ glyphs[i] = glyph;
+ if ( uc < cmapCacheSize )
+ ((TQFontEngineXft *)this)->cmapCache[uc] = glyph;
+ }
+ }
+ } else {
+ for ( int i = 0; i < len; ++i ) {
+ unsigned short uc = str[i].tqunicode();
+ glyphs[i] = uc < cmapCacheSize ? cmapCache[uc] : 0;
+ if ( !glyphs[i] ) {
+ if (uc == 0xa0)
+ uc = 0x20;
+ glyph_t glyph = XftCharIndex(0, _font, uc);
+ glyphs[i] = glyph;
+ if ( uc < cmapCacheSize )
+ ((TQFontEngineXft *)this)->cmapCache[uc] = glyph;
+ }
+ }
+ }
+
+ if ( advances ) {
+ for ( int i = 0; i < len; i++ ) {
+ FT_UInt glyph = *(glyphs + i);
+ advances[i] = (glyph < widthCacheSize) ? widthCache[glyph] : 0;
+ if ( !advances[i] ) {
+ XGlyphInfo gi;
+ XftGlyphExtents( TQPaintDevice::x11AppDisplay(), _font, &glyph, 1, &gi );
+ advances[i] = gi.xOff;
+ if ( glyph < widthCacheSize && gi.xOff > 0 && gi.xOff < 0x100 )
+ ((TQFontEngineXft *)this)->widthCache[glyph] = gi.xOff;
+ }
+ }
+ if ( _scale != 1. ) {
+ for ( int i = 0; i < len; i++ )
+ advances[i] = tqRound(advances[i]*_scale);
+ }
+ }
+#else
+ if ( !_face ) {
+ if ( mirrored ) {
+ for ( int i = 0; i < len; i++ )
+ glyphs[i] = ::mirroredChar(str[i]).tqunicode();
+ } else {
+ for ( int i = 0; i < len; i++ )
+ glyphs[i] = str[i].tqunicode();
+ }
+ } else {
+ if ( _cmap == 1 ) {
+ // symbol font
+ for ( int i = 0; i < len; i++ ) {
+ unsigned short uc = str[i].tqunicode();
+ glyphs[i] = uc < cmapCacheSize ? cmapCache[uc] : 0;
+ if ( !glyphs[i] ) {
+ glyph_t glyph = FT_Get_Char_Index( _face, uc );
+ if(!glyph && uc < 0x100)
+ glyph = FT_Get_Char_Index( _face, uc+0xf000 );
+ glyphs[i] = glyph;
+ if ( uc < cmapCacheSize )
+ ((TQFontEngineXft *)this)->cmapCache[uc] = glyph;
+ }
+ }
+ } else if ( mirrored ) {
+ for ( int i = 0; i < len; i++ ) {
+ unsigned short uc = ::mirroredChar(str[i]).tqunicode();
+ glyphs[i] = uc < cmapCacheSize ? cmapCache[uc] : 0;
+ if ( !glyphs[i] ) {
+ glyph_t glyph = FT_Get_Char_Index( _face, uc );
+ glyphs[i] = glyph;
+ if ( uc < cmapCacheSize )
+ ((TQFontEngineXft *)this)->cmapCache[uc] = glyph;
+ }
+ }
+ } else {
+ for ( int i = 0; i < len; i++ ) {
+ unsigned short uc = str[i].tqunicode();
+ glyphs[i] = uc < cmapCacheSize ? cmapCache[uc] : 0;
+ if ( !glyphs[i] ) {
+ glyph_t glyph = FT_Get_Char_Index( _face, uc );
+ glyphs[i] = glyph;
+ if ( uc < cmapCacheSize )
+ ((TQFontEngineXft *)this)->cmapCache[uc] = glyph;
+ }
+ }
+ }
+ }
+
+ if ( advances ) {
+ for ( int i = 0; i < len; i++ ) {
+ XftChar16 glyph = *(glyphs + i);
+ advances[i] = (glyph < widthCacheSize) ? widthCache[glyph] : 0;
+ if ( !advances[i] ) {
+ XGlyphInfo gi;
+ XftTextExtents16(TQPaintDevice::x11AppDisplay(), _font, &glyph, 1, &gi);
+ advances[i] = gi.xOff;
+ if ( glyph < widthCacheSize && gi.xOff > 0 && gi.xOff < 0x100 )
+ ((TQFontEngineXft *)this)->widthCache[glyph] = gi.xOff;
+ }
+ }
+ if ( _scale != 1. ) {
+ for ( int i = 0; i < len; i++ )
+ advances[i] = tqRound(advances[i]*_scale);
+ }
+ }
+#endif // TQT_XFT2
+
+ *nglyphs = len;
+ return NoError;
+}
+
+
+void TQFontEngineXft::recalcAdvances( int len, glyph_t *glyphs, advance_t *advances )
+{
+
+#ifdef TQT_XFT2
+ for ( int i = 0; i < len; i++ ) {
+ FT_UInt glyph = *(glyphs + i);
+ advances[i] = (glyph < widthCacheSize) ? widthCache[glyph] : 0;
+ if ( !advances[i] ) {
+ XGlyphInfo gi;
+ XftGlyphExtents( TQPaintDevice::x11AppDisplay(), _font, &glyph, 1, &gi );
+ advances[i] = gi.xOff;
+ if ( glyph < widthCacheSize && gi.xOff > 0 && gi.xOff < 0x100 )
+ ((TQFontEngineXft *)this)->widthCache[glyph] = gi.xOff;
+ }
+ if ( _scale != 1. ) {
+ for ( int i = 0; i < len; i++ )
+ advances[i] = tqRound(advances[i]*_scale);
+ }
+ }
+#else
+ for ( int i = 0; i < len; i++ ) {
+ XftChar16 glyph = *(glyphs + i);
+ advances[i] = (glyph < widthCacheSize) ? widthCache[glyph] : 0;
+ if ( !advances[i] ) {
+ XGlyphInfo gi;
+ XftTextExtents16(TQPaintDevice::x11AppDisplay(), _font, &glyph, 1, &gi);
+ advances[i] = gi.xOff;
+ if ( glyph < widthCacheSize && gi.xOff > 0 && gi.xOff < 0x100 )
+ ((TQFontEngineXft *)this)->widthCache[glyph] = gi.xOff;
+ }
+ }
+ if ( _scale != 1. ) {
+ for ( int i = 0; i < len; i++ )
+ advances[i] = tqRound(advances[i]*_scale);
+ }
+#endif // TQT_XFT2
+}
+
+//#define FONTENGINE_DEBUG
+void TQFontEngineXft::draw( TQPainter *p, int x, int y, const TQTextEngine *engine, const TQScriptItem *si, int textFlags )
+{
+ if ( !si->num_glyphs )
+ return;
+
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+
+ int xorig = x;
+ int yorig = y;
+
+ GlyphAttributes *glyphAttributes = engine->glyphAttributes( si );
+
+ XftFont *fnt = _font;
+ bool transform = FALSE;
+ if ( p->txop >= TQPainter::TxScale || p->rop != TQt::CopyROP || _scale < 0.9999 || _scale > 1.001) {
+ bool can_scale = (_face->face_flags & FT_FACE_FLAG_SCALABLE) && p->rop == TQt::CopyROP;
+ double size = (p->m11()*p->m22() - p->m12()*p->m21())*_scale*_scale*fontDef.pixelSize*fontDef.pixelSize;
+ if (size > 256*256 || _scale < .9999 || _scale > 1.001)
+ can_scale = FALSE;
+ if (!can_scale) {
+ // font doesn't support transformations, need to do it by hand
+ float tmp = _scale;
+ _scale = 1.;
+ drawScaled(x, y, engine, si, textFlags, dpy, p->gc, p->tqdevice(), this, p->xmat, tmp);
+ _scale = tmp;
+ return;
+ }
+
+ XftMatrix *mat = 0;
+ XftPatternGetMatrix( _pattern, XFT_MATRIX, 0, &mat );
+ XftMatrix m2;
+ m2.xx = p->m11()*_scale;
+ m2.xy = -p->m21()*_scale;
+ m2.yx = -p->m12()*_scale;
+ m2.yy = p->m22()*_scale;
+
+ // check if we have it cached
+ TransformedFont *trf = transformed_fonts;
+ TransformedFont *prev = 0;
+ int i = 0;
+ while ( trf ) {
+ if ( trf->xx == (float)m2.xx &&
+ trf->xy == (float)m2.xy &&
+ trf->yx == (float)m2.yx &&
+ trf->yy == (float)m2.yy )
+ break;
+ TransformedFont *tmp = trf;
+ trf = trf->next;
+ if (i > 10) {
+ XftFontClose( TQPaintDevice::x11AppDisplay(), tmp->xft_font );
+ delete tmp;
+ prev->next = trf;
+ } else {
+ prev = tmp;
+ }
+ ++i;
+ }
+ if ( trf ) {
+ if ( prev ) {
+ // move to beginning of list
+ prev->next = trf->next;
+ trf->next = transformed_fonts;
+ transformed_fonts = trf;
+ }
+ fnt = trf->xft_font;
+ } else {
+ if ( mat )
+ XftMatrixMultiply( &m2, &m2, mat );
+
+ XftPattern *pattern = XftPatternDuplicate( _pattern );
+ XftPatternDel( pattern, XFT_MATRIX );
+ XftPatternAddMatrix( pattern, XFT_MATRIX, &m2 );
+
+ fnt = XftFontOpenPattern( dpy, pattern );
+#ifndef TQT_XFT2
+ XftFontStruct *xftfs = getFontStruct( fnt );
+ if ( xftfs ) {
+ // dirty hack: we set the charmap in the Xftfreetype to -1, so
+ // XftFreetype assumes no encoding and really draws glyph
+ // indices. The FT_Face still has the Unicode encoding to we
+ // can convert from Unicode to glyph index
+ xftfs->charmap = -1;
+ }
+#endif // TQT_XFT2
+ TransformedFont *trf = new TransformedFont;
+ trf->xx = (float)m2.xx;
+ trf->xy = (float)m2.xy;
+ trf->yx = (float)m2.yx;
+ trf->yy = (float)m2.yy;
+ trf->xft_font = fnt;
+ trf->next = transformed_fonts;
+ transformed_fonts = trf;
+ }
+ transform = TRUE;
+ } else if ( p->txop == TQPainter::TxTranslate ) {
+ p->map( x, y, &x, &y );
+ }
+
+ glyph_t *glyphs = engine->glyphs( si );
+ advance_t *advances = engine->advances( si );
+ qoffset_t *offsets = engine->offsets( si );
+
+ const TQColor &pen = p->cpen.color();
+ XftDraw *draw = ((TQ_HackPaintDevice *)p->pdev)->xftDrawHandle();
+
+ XftColor col;
+ col.color.red = pen.red () | pen.red() << 8;
+ col.color.green = pen.green () | pen.green() << 8;
+ col.color.blue = pen.blue () | pen.blue() << 8;
+ col.color.alpha = 0xffff;
+ col.pixel = pen.pixel();
+#ifdef FONTENGINE_DEBUG
+ qDebug("===== drawing %d glyphs reverse=%s ======", si->num_glyphs, si->analysis.bidiLevel % 2?"TRUE":"FALSE" );
+ p->save();
+ p->setBrush( TQt::white );
+ glyph_metrics_t ci = boundingBox( glyphs, advances, offsets, si->num_glyphs );
+ p->drawRect( x + ci.x, y + ci.y, ci.width, ci.height );
+ p->drawRect( x + ci.x, y + 100 + ci.y, ci.width, ci.height );
+ qDebug("bounding rect=%d %d (%d/%d)", ci.x, ci.y, ci.width, ci.height );
+ p->restore();
+ int yp = y;
+ int xp = x;
+#endif
+
+ if ( textFlags != 0 )
+ drawLines( p, this, yorig, xorig, si->width, textFlags );
+
+
+ if ( si->isSpace )
+ return;
+
+ if ( transform || si->hasPositioning ) {
+ if ( si->analysis.bidiLevel % 2 ) {
+ int i = si->num_glyphs;
+ while( i-- ) {
+ int xp = x + offsets[i].x;
+ int yp = y + offsets[i].y;
+ if ( transform )
+ p->map( xp, yp, &xp, &yp );
+#ifdef TQT_XFT2
+ FT_UInt glyph = *(glyphs + i);
+ if (!glyphAttributes[i].zeroWidth && xp < SHRT_MAX && xp > SHRT_MIN)
+ XftDrawGlyphs( draw, &col, fnt, xp, yp, &glyph, 1 );
+#else
+ if (!glyphAttributes[i].zeroWidth && xp < SHRT_MAX && xp > SHRT_MIN)
+ XftDrawString16( draw, &col, fnt, xp, yp, (XftChar16 *) (glyphs+i), 1);
+#endif // TQT_XFT2
+#ifdef FONTENGINE_DEBUG
+ glyph_metrics_t gi = boundingBox( glyphs[i] );
+ p->drawRect( x+offsets[i].x+gi.x, y+offsets[i].y+100+gi.y, gi.width, gi.height );
+ p->drawLine( x+offsets[i].x, y + 150 + 5*i , x+offsets[i].x+advances[i], y + 150 + 5*i );
+ p->drawLine( x+offsets[i].x, y + 152 + 5*i , x+offsets[i].x+gi.xoff, y + 152 + 5*i );
+ qDebug("bounding ci[%d]=%d %d (%d/%d) / %d %d offs=(%d/%d) advance=%d", i, gi.x, gi.y, gi.width, gi.height,
+ gi.xoff, gi.yoff, offsets[i].x, offsets[i].y, advances[i]);
+#endif
+ x += advances[i];
+ }
+ } else {
+ int i = 0;
+ while ( i < si->num_glyphs ) {
+ int xp = x + offsets[i].x;
+ int yp = y + offsets[i].y;
+ if ( transform )
+ p->map( xp, yp, &xp, &yp );
+#ifdef TQT_XFT2
+ FT_UInt glyph = *(glyphs + i);
+ if (!glyphAttributes[i].zeroWidth && xp < SHRT_MAX && xp > SHRT_MIN)
+ XftDrawGlyphs( draw, &col, fnt, xp, yp, &glyph, 1 );
+#else
+ if (!glyphAttributes[i].zeroWidth && xp < SHRT_MAX && xp > SHRT_MIN)
+ XftDrawString16( draw, &col, fnt, xp, yp, (XftChar16 *) (glyphs+i), 1 );
+#endif // TQT_XFT2
+ // qDebug("advance = %d/%d", adv.x, adv.y );
+ x += advances[i];
+ i++;
+ }
+ }
+ } else {
+ // Xft has real trouble drawing the glyphs on their own.
+ // Drawing them as one string increases performance significantly.
+#ifdef TQT_XFT2
+ // #### we should use a different method anyways on Xft2
+ FT_UInt g[64];
+ int gl = 0;
+ while (gl < si->num_glyphs) {
+ int toDraw = TQMIN(64, si->num_glyphs-gl);
+ int adv = 0;
+ if ( si->analysis.bidiLevel % 2 ) {
+ for ( int i = 0; i < toDraw; i++ ) {
+ g[i] = glyphs[si->num_glyphs-1-(gl+i)];
+ adv += advances[si->num_glyphs-1-(gl+i)];
+ }
+ } else {
+ for ( int i = 0; i < toDraw; i++ ) {
+ g[i] = glyphs[gl+i];
+ adv += advances[gl+i];
+ }
+ }
+ if (x + adv < SHRT_MAX && x > SHRT_MIN)
+ XftDrawGlyphs( draw, &col, fnt, x, y, g, toDraw );
+ gl += toDraw;
+ x += adv;
+ }
+#else
+ XftChar16 g[64];
+ int gl = 0;
+ while (gl < si->num_glyphs) {
+ int toDraw = TQMIN(64, si->num_glyphs-gl);
+ int adv = 0;
+ if ( si->analysis.bidiLevel % 2 ) {
+ for ( int i = 0; i < toDraw; i++ ) {
+ g[i] = glyphs[si->num_glyphs-1-(gl+i)];
+ adv += advances[si->num_glyphs-1-(gl+i)];
+ }
+ } else {
+ for ( int i = 0; i < toDraw; i++ ) {
+ g[i] = glyphs[gl+i];
+ adv += advances[gl+i];
+ }
+ }
+ if (x + adv < SHRT_MAX && x > SHRT_MIN)
+ XftDrawString16( draw, &col, fnt, x, y, g, toDraw );
+ gl += toDraw;
+ x += adv;
+ }
+#endif // TQT_XFT2
+ }
+
+#ifdef FONTENGINE_DEBUG
+ if ( !si->analysis.bidiLevel % 2 ) {
+ x = xp;
+ y = yp;
+ p->save();
+ p->setPen( TQt::red );
+ for ( int i = 0; i < si->num_glyphs; i++ ) {
+ glyph_metrics_t ci = boundingBox( glyphs[i] );
+ p->drawRect( x + ci.x + offsets[i].x, y + 100 + ci.y + offsets[i].y, ci.width, ci.height );
+ qDebug("bounding ci[%d]=%d %d (%d/%d) / %d %d offs=(%d/%d) advance=%d", i, ci.x, ci.y, ci.width, ci.height,
+ ci.xoff, ci.yoff, offsets[i].x, offsets[i].y, advances[i]);
+ x += advances[i];
+ }
+ p->restore();
+ }
+#endif
+}
+
+glyph_metrics_t TQFontEngineXft::boundingBox( const glyph_t *glyphs, const advance_t *advances, const qoffset_t *offsets, int numGlyphs )
+{
+ XGlyphInfo xgi;
+
+ glyph_metrics_t overall;
+ int ymax = 0;
+ int xmax = 0;
+ if (_scale != 1) {
+ for (int i = 0; i < numGlyphs; i++) {
+ getGlyphInfo( &xgi, _font, glyphs[i] );
+ int x = overall.xoff + offsets[i].x - xgi.x;
+ int y = overall.yoff + offsets[i].y - xgi.y;
+ overall.x = TQMIN( overall.x, x );
+ overall.y = TQMIN( overall.y, y );
+ xmax = TQMAX( xmax, x + xgi.width );
+ ymax = TQMAX( ymax, y + xgi.height );
+ overall.xoff += tqRound(advances[i]/_scale);
+ }
+ overall.x = tqRound(overall.x * _scale);
+ overall.y = tqRound(overall.y * _scale);
+ overall.xoff = tqRound(overall.xoff * _scale);
+ overall.yoff = tqRound(overall.yoff * _scale);
+ xmax = tqRound(xmax * _scale);
+ ymax = tqRound(ymax * _scale);
+ } else {
+ for (int i = 0; i < numGlyphs; i++) {
+ getGlyphInfo( &xgi, _font, glyphs[i] );
+ int x = overall.xoff + offsets[i].x - xgi.x;
+ int y = overall.yoff + offsets[i].y - xgi.y;
+ overall.x = TQMIN( overall.x, x );
+ overall.y = TQMIN( overall.y, y );
+ xmax = TQMAX( xmax, x + xgi.width );
+ ymax = TQMAX( ymax, y + xgi.height );
+ overall.xoff += advances[i];
+ }
+ }
+ overall.height = ymax - overall.y;
+ overall.width = xmax - overall.x;
+ return overall;
+}
+
+glyph_metrics_t TQFontEngineXft::boundingBox( glyph_t glyph )
+{
+ XGlyphInfo xgi;
+ getGlyphInfo( &xgi, _font, glyph );
+ glyph_metrics_t gm = glyph_metrics_t( -xgi.x, -xgi.y, xgi.width, xgi.height, xgi.xOff, -xgi.yOff );
+ if ( _scale != 1. ) {
+ gm.x = tqRound(gm.x * _scale);
+ gm.y = tqRound(gm.y * _scale);
+ gm.height = tqRound(gm.height * _scale);
+ gm.width = tqRound(gm.width * _scale);
+ gm.xoff = tqRound(gm.xoff * _scale);
+ gm.yoff = tqRound(gm.yoff * _scale);
+ }
+ return gm;
+}
+
+
+
+int TQFontEngineXft::ascent() const
+{
+ return tqRound(_font->ascent*_scale);
+}
+
+int TQFontEngineXft::descent() const
+{
+ return tqRound((_font->descent-1)*_scale);
+}
+
+// #### use Freetype to determine this
+int TQFontEngineXft::leading() const
+{
+ int l = tqRound(TQMIN( _font->height - (_font->ascent + _font->descent),
+ ((_font->ascent + _font->descent) >> 4)*_scale ));
+ return (l > 0) ? l : 1;
+}
+
+// #### use Freetype to determine this
+int TQFontEngineXft::lineThickness() const
+{
+ // ad hoc algorithm
+ int score = fontDef.weight * fontDef.pixelSize;
+ int lw = score / 700;
+
+ // looks better with thicker line for small pointsizes
+ if ( lw < 2 && score >= 1050 ) lw = 2;
+ if ( lw == 0 ) lw = 1;
+
+ return lw;
+}
+
+// #### use Freetype to determine this
+int TQFontEngineXft::underlinePosition() const
+{
+ int pos = ( ( lineThickness() * 2 ) + 3 ) / 6;
+ return pos ? pos : 1;
+}
+
+int TQFontEngineXft::maxCharWidth() const
+{
+ return tqRound(_font->max_advance_width*_scale);
+}
+
+static const ushort char_table[] = {
+ 40,
+ 67,
+ 70,
+ 75,
+ 86,
+ 88,
+ 89,
+ 91,
+ 102,
+ 114,
+ 124,
+ 127,
+ 205,
+ 645,
+ 884,
+ 922,
+ 1070,
+ 12386
+};
+
+static const int char_table_entries = sizeof(char_table)/sizeof(ushort);
+
+
+int TQFontEngineXft::minLeftBearing() const
+{
+ if ( lbearing == SHRT_MIN )
+ minRightBearing(); // calculates both
+
+ return lbearing;
+}
+
+int TQFontEngineXft::minRightBearing() const
+{
+ if ( rbearing == SHRT_MIN ) {
+ TQFontEngineXft *that = (TQFontEngineXft *)this;
+ that->lbearing = that->rbearing = 0;
+ TQChar *ch = (TQChar *)char_table;
+ glyph_t glyphs[char_table_entries];
+ int ng = char_table_entries;
+ stringToCMap(ch, char_table_entries, glyphs, 0, &ng, FALSE);
+ while (--ng) {
+ if (glyphs[ng]) {
+ glyph_metrics_t gi = that->boundingBox( glyphs[ng] );
+ if (gi.xoff) {
+ that->lbearing = TQMIN(lbearing, gi.x);
+ that->rbearing = TQMIN(rbearing, gi.xoff - gi.x - gi.width);
+ }
+ }
+ }
+ }
+
+ return rbearing;
+}
+
+int TQFontEngineXft::cmap() const
+{
+ return _cmap;
+}
+
+const char *TQFontEngineXft::name() const
+{
+ return "xft";
+}
+
+void TQFontEngineXft::setScale( double scale )
+{
+ _scale = scale;
+}
+
+bool TQFontEngineXft::canRender( const TQChar *string, int len )
+{
+ bool allExist = TRUE;
+
+#ifdef TQT_XFT2
+ if (_cmap != -1) {
+ for ( int i = 0; i < len; i++ ) {
+ if (!XftCharExists(0, _font, string[i].tqunicode())
+ && getAdobeCharIndex(_font, _cmap, string[i].tqunicode()) == 0) {
+ allExist = FALSE;
+ break;
+ }
+ }
+ } else {
+ for ( int i = 0; i < len; i++ ) {
+ if (!XftCharExists(0, _font, string[i].tqunicode())) {
+ allExist = FALSE;
+ break;
+ }
+ }
+ }
+#else
+ glyph_t glyphs[256];
+ int nglyphs = 255;
+ glyph_t *g = glyphs;
+ if ( stringToCMap( string, len, g, 0, &nglyphs, FALSE ) == OutOfMemory ) {
+ g = (glyph_t *)malloc( nglyphs*sizeof(glyph_t) );
+ stringToCMap( string, len, g, 0, &nglyphs, FALSE );
+ }
+
+ for ( int i = 0; i < nglyphs; i++ ) {
+ if ( !XftGlyphExists(TQPaintDevice::x11AppDisplay(), _font, g[i]) ) {
+ allExist = FALSE;
+ break;
+ }
+ }
+
+ if ( g != glyphs )
+ free( g );
+#endif // TQT_XFT2
+
+ return allExist;
+}
+
+TQOpenType *TQFontEngineXft::openType() const
+{
+// qDebug("openTypeIface requested!");
+ if ( _openType )
+ return _openType;
+
+ if ( !_face || ! FT_IS_SFNT( _face ) )
+ return 0;
+
+ TQFontEngineXft *that = (TQFontEngineXft *)this;
+ that->_openType = new TQOpenType(that);
+ return _openType;
+}
+
+
+TQFontEngine::Type TQFontEngineXft::type() const
+{
+ return Xft;
+}
+#endif
+
+
+// --------------------------------------------------------------------------------------------------------------------
+// Open type support
+// --------------------------------------------------------------------------------------------------------------------
+
+#ifndef TQT_NO_XFTFREETYPE
+
+#include "tqscriptengine_p.h"
+
+//#define OT_DEBUG
+
+#ifdef OT_DEBUG
+static inline char *tag_to_string(FT_ULong tag)
+{
+ static char string[5];
+ string[0] = (tag >> 24)&0xff;
+ string[1] = (tag >> 16)&0xff;
+ string[2] = (tag >> 8)&0xff;
+ string[3] = tag&0xff;
+ string[4] = 0;
+ return string;
+}
+#endif
+
+#define DefaultLangSys 0xffff
+#define DefaultScript FT_MAKE_TAG('D', 'F', 'L', 'T')
+
+enum {
+ RequiresGsub = 1,
+ RequiresGpos = 2
+};
+
+struct OTScripts {
+ unsigned int tag;
+ int flags;
+};
+
+static const OTScripts ot_scripts [] = {
+// // European Alphabetic Scripts
+// Latin,
+ { FT_MAKE_TAG( 'l', 'a', 't', 'n' ), 0 },
+// Greek,
+ { FT_MAKE_TAG( 'g', 'r', 'e', 'k' ), 0 },
+// Cyrillic,
+ { FT_MAKE_TAG( 'c', 'y', 'r', 'l' ), 0 },
+// Armenian,
+ { FT_MAKE_TAG( 'a', 'r', 'm', 'n' ), 0 },
+// Georgian,
+ { FT_MAKE_TAG( 'g', 'e', 'o', 'r' ), 0 },
+// Runic,
+ { FT_MAKE_TAG( 'r', 'u', 'n', 'r' ), 0 },
+// Ogham,
+ { FT_MAKE_TAG( 'o', 'g', 'a', 'm' ), 0 },
+// SpacingModifiers,
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+// CombiningMarks,
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+
+// // Middle Eastern Scripts
+// Hebrew,
+ { FT_MAKE_TAG( 'h', 'e', 'b', 'r' ), 1 },
+// Arabic,
+ { FT_MAKE_TAG( 'a', 'r', 'a', 'b' ), 1 },
+// Syriac,
+ { FT_MAKE_TAG( 's', 'y', 'r', 'c' ), 1 },
+// Thaana,
+ { FT_MAKE_TAG( 't', 'h', 'a', 'a' ), 1 },
+
+// // South and Southeast Asian Scripts
+// Devanagari,
+ { FT_MAKE_TAG( 'd', 'e', 'v', 'a' ), 1 },
+// Bengali,
+ { FT_MAKE_TAG( 'b', 'e', 'n', 'g' ), 1 },
+// Gurmukhi,
+ { FT_MAKE_TAG( 'g', 'u', 'r', 'u' ), 1 },
+// Gujarati,
+ { FT_MAKE_TAG( 'g', 'u', 'j', 'r' ), 1 },
+// Oriya,
+ { FT_MAKE_TAG( 'o', 'r', 'y', 'a' ), 1 },
+// Tamil,
+ { FT_MAKE_TAG( 't', 'a', 'm', 'l' ), 1 },
+// Telugu,
+ { FT_MAKE_TAG( 't', 'e', 'l', 'u' ), 1 },
+// Kannada,
+ { FT_MAKE_TAG( 'k', 'n', 'd', 'a' ), 1 },
+// Malayalam,
+ { FT_MAKE_TAG( 'm', 'l', 'y', 'm' ), 1 },
+// Sinhala,
+ // ### could not tqfind any OT specs on this
+ { FT_MAKE_TAG( 's', 'i', 'n', 'h' ), 1 },
+// Thai,
+ { FT_MAKE_TAG( 't', 'h', 'a', 'i' ), 1 },
+// Lao,
+ { FT_MAKE_TAG( 'l', 'a', 'o', ' ' ), 1 },
+// Tibetan,
+ { FT_MAKE_TAG( 't', 'i', 'b', 't' ), 1 },
+// Myanmar,
+ { FT_MAKE_TAG( 'm', 'y', 'm', 'r' ), 1 },
+// Khmer,
+ { FT_MAKE_TAG( 'k', 'h', 'm', 'r' ), 1 },
+
+// // East Asian Scripts
+// Han,
+ { FT_MAKE_TAG( 'h', 'a', 'n', 'i' ), 0 },
+// Hiragana,
+ { FT_MAKE_TAG( 'k', 'a', 'n', 'a' ), 0 },
+// Katakana,
+ { FT_MAKE_TAG( 'k', 'a', 'n', 'a' ), 0 },
+// Hangul,
+ { FT_MAKE_TAG( 'h', 'a', 'n', 'g' ), 1 },
+// Bopomofo,
+ { FT_MAKE_TAG( 'b', 'o', 'p', 'o' ), 0 },
+// Yi,
+ { FT_MAKE_TAG( 'y', 'i', ' ', ' ' ), 0 },
+
+// // Additional Scripts
+// Ethiopic,
+ { FT_MAKE_TAG( 'e', 't', 'h', 'i' ), 0 },
+// Cherokee,
+ { FT_MAKE_TAG( 'c', 'h', 'e', 'r' ), 0 },
+// CanadianAboriginal,
+ { FT_MAKE_TAG( 'c', 'a', 'n', 's' ), 0 },
+// Mongolian,
+ { FT_MAKE_TAG( 'm', 'o', 'n', 'g' ), 0 },
+// // Symbols
+// CurrencySymbols,
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+// LetterlikeSymbols,
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+// NumberForms,
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+// MathematicalOperators,
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+// TechnicalSymbols,
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+// GeometricSymbols,
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+// MiscellaneousSymbols,
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+// EnclosedAndSquare,
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+// Braille,
+ { FT_MAKE_TAG( 'b', 'r', 'a', 'i' ), 0 },
+// Unicode, should be used
+ { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 }
+ // ### where are these?
+// { FT_MAKE_TAG( 'b', 'y', 'z', 'm' ), 0 },
+// { FT_MAKE_TAG( 'D', 'F', 'L', 'T' ), 0 },
+ // ### Hangul Jamo
+// { FT_MAKE_TAG( 'j', 'a', 'm', 'o' ), 0 },
+};
+
+TQOpenType::TQOpenType(TQFontEngineXft *fe)
+ : fontEngine(fe), gdef(0), gsub(0), gpos(0), current_script(0)
+{
+ face = fe->face();
+ otl_buffer_new(face->memory, &otl_buffer);
+ tmpAttributes = 0;
+ tmpLogClusters = 0;
+
+ FT_Error error;
+ if ((error = TT_Load_GDEF_Table(face, &gdef))) {
+#ifdef OT_DEBUG
+ qDebug("error loading gdef table: %d", error);
+#endif
+ gdef = 0;
+ }
+
+ if ((error = TT_Load_GSUB_Table(face, &gsub, gdef))) {
+ gsub = 0;
+#ifdef OT_DEBUG
+ if (error != FT_Err_Table_Missing) {
+ qDebug("error loading gsub table: %d", error);
+ } else {
+ qDebug("face doesn't have a gsub table");
+ }
+#endif
+ }
+
+ if ((error = TT_Load_GPOS_Table(face, &gpos, gdef))) {
+ gpos = 0;
+#ifdef OT_DEBUG
+ qDebug("error loading gpos table: %d", error);
+#endif
+ }
+
+ for (uint i = 0; i < TQFont::NScripts; ++i)
+ supported_scripts[i] = checkScript(i);
+}
+
+TQOpenType::~TQOpenType()
+{
+ if (gpos)
+ TT_Done_GPOS_Table(gpos);
+ if (gsub)
+ TT_Done_GSUB_Table(gsub);
+ if (gdef)
+ TT_Done_GDEF_Table(gdef);
+ if (otl_buffer)
+ otl_buffer_free(otl_buffer);
+ if (tmpAttributes)
+ free(tmpAttributes);
+ if (tmpLogClusters)
+ free(tmpLogClusters);
+}
+
+bool TQOpenType::checkScript(unsigned int script)
+{
+ assert(script < TQFont::NScripts);
+
+ uint tag = ot_scripts[script].tag;
+ int requirements = ot_scripts[script].flags;
+
+ if (requirements & RequiresGsub) {
+ if (!gsub)
+ return FALSE;
+
+ FT_UShort script_index;
+ FT_Error error = TT_GSUB_Select_Script(gsub, tag, &script_index);
+ if (error) {
+#ifdef OT_DEBUG
+ qDebug("could not select script %d in GSub table: %d", (int)script, error);
+#endif
+ return FALSE;
+ }
+ }
+
+ if (requirements & RequiresGpos) {
+ if (!gpos)
+ return FALSE;
+
+ FT_UShort script_index;
+ FT_Error error = TT_GPOS_Select_Script(gpos, script, &script_index);
+ if (error) {
+#ifdef OT_DEBUG
+ qDebug("could not select script in gpos table: %d", error);
+#endif
+ return FALSE;
+ }
+
+ }
+ return TRUE;
+}
+
+
+void TQOpenType::selectScript(unsigned int script, const Features *features)
+{
+ if (current_script == script)
+ return;
+
+ assert(script < TQFont::NScripts);
+ // tqfind script in our list of supported scripts.
+ uint tag = ot_scripts[script].tag;
+
+ if (gsub && features) {
+#ifdef OT_DEBUG
+ {
+ TTO_FeatureList featurelist = gsub->FeatureList;
+ int numfeatures = featurelist.FeatureCount;
+ qDebug("gsub table has %d features", numfeatures);
+ for(int i = 0; i < numfeatures; i++) {
+ TTO_FeatureRecord *r = featurelist.FeatureRecord + i;
+ qDebug(" feature '%s'", tag_to_string(r->FeatureTag));
+ }
+ }
+#endif
+ TT_GSUB_Clear_Features(gsub);
+ FT_UShort script_index;
+ FT_Error error = TT_GSUB_Select_Script(gsub, tag, &script_index);
+ if (!error) {
+#ifdef OT_DEBUG
+ qDebug("script %s has script index %d", tag_to_string(script), script_index);
+#endif
+ while (features->tag) {
+ FT_UShort feature_index;
+ error = TT_GSUB_Select_Feature(gsub, features->tag, script_index, 0xffff, &feature_index);
+ if (!error) {
+#ifdef OT_DEBUG
+ qDebug(" adding feature %s", tag_to_string(features->tag));
+#endif
+ TT_GSUB_Add_Feature(gsub, feature_index, features->property);
+ }
+ ++features;
+ }
+ }
+ }
+
+ if (gpos) {
+ TT_GPOS_Clear_Features(gpos);
+ FT_UShort script_index;
+ FT_Error error = TT_GPOS_Select_Script(gpos, tag, &script_index);
+ if (!error) {
+#ifdef OT_DEBUG
+ {
+ TTO_FeatureList featurelist = gpos->FeatureList;
+ int numfeatures = featurelist.FeatureCount;
+ qDebug("gpos table has %d features", numfeatures);
+ for(int i = 0; i < numfeatures; i++) {
+ TTO_FeatureRecord *r = featurelist.FeatureRecord + i;
+ FT_UShort feature_index;
+ TT_GPOS_Select_Feature(gpos, r->FeatureTag, script_index, 0xffff, &feature_index);
+ qDebug(" feature '%s'", tag_to_string(r->FeatureTag));
+ }
+ }
+#endif
+ FT_ULong *feature_tag_list;
+ error = TT_GPOS_Query_Features(gpos, script_index, 0xffff, &feature_tag_list);
+ if (!error) {
+ while (*feature_tag_list) {
+ FT_UShort feature_index;
+ error = TT_GPOS_Select_Feature(gpos, *feature_tag_list, script_index, 0xffff, &feature_index);
+ if (!error)
+ TT_GPOS_Add_Feature(gpos, feature_index, PositioningProperties);
+ ++feature_tag_list;
+ }
+ }
+ }
+ }
+
+ current_script = script;
+}
+
+#ifdef OT_DEBUG
+static void dump_string(OTL_Buffer buffer)
+{
+ for (uint i = 0; i < buffer->in_length; ++i) {
+ qDebug(" %x: cluster=%d", buffer->in_string[i].gindex, buffer->in_string[i].cluster);
+ }
+}
+#endif
+
+extern void qt_heuristicPosition(TQShaperItem *item);
+
+bool TQOpenType::tqshape(TQShaperItem *item, const unsigned int *properties)
+{
+ length = item->num_glyphs;
+
+ otl_buffer_clear(otl_buffer);
+
+ tmpAttributes = (GlyphAttributes *) realloc(tmpAttributes, length*sizeof(GlyphAttributes));
+ tmpLogClusters = (unsigned int *) realloc(tmpLogClusters, length*sizeof(unsigned int));
+ for (int i = 0; i < length; ++i) {
+ otl_buffer_add_glyph(otl_buffer, item->glyphs[i], properties ? properties[i] : 0, i);
+ tmpAttributes[i] = item->attributes[i];
+ tmpLogClusters[i] = item->log_clusters[i];
+ }
+
+#ifdef OT_DEBUG
+ qDebug("-----------------------------------------");
+// qDebug("log clusters before shaping:");
+// for (int j = 0; j < length; j++)
+// qDebug(" log[%d] = %d", j, item->log_clusters[j]);
+ qDebug("original glyphs: %p", item->glyphs);
+ for (int i = 0; i < length; ++i)
+ qDebug(" glyph=%4x", otl_buffer->in_string[i].gindex);
+// dump_string(otl_buffer);
+#endif
+
+ loadFlags = FT_LOAD_DEFAULT;
+
+ if (gsub) {
+ uint error = TT_GSUB_Apply_String(gsub, otl_buffer);
+ if (error && error != TTO_Err_Not_Covered)
+ return false;
+ }
+
+#ifdef OT_DEBUG
+// qDebug("log clusters before shaping:");
+// for (int j = 0; j < length; j++)
+// qDebug(" log[%d] = %d", j, item->log_clusters[j]);
+ qDebug("tqshaped glyphs:");
+ for (int i = 0; i < length; ++i)
+ qDebug(" glyph=%4x", otl_buffer->in_string[i].gindex);
+ qDebug("-----------------------------------------");
+// dump_string(otl_buffer);
+#endif
+
+ return true;
+}
+
+bool TQOpenType::positionAndAdd(TQShaperItem *item, bool doLogClusters)
+{
+ if (gpos) {
+#ifdef TQ_WS_X11
+ TQ_ASSERT(fontEngine->type() == TQFontEngine::Xft);
+ face = lockFTFace(static_cast<TQFontEngineXft *>(fontEngine)->font());
+#endif
+ memset(otl_buffer->positions, 0, otl_buffer->in_length*sizeof(OTL_PositionRec));
+ // #### check that passing "FALSE,FALSE" is correct
+ TT_GPOS_Apply_String(face, gpos, loadFlags, otl_buffer, FALSE, FALSE);
+#ifdef TQ_WS_X11
+ unlockFTFace(static_cast<TQFontEngineXft *>(fontEngine)->font());
+#endif
+ }
+
+ // make sure we have enough space to write everything back
+ if (item->num_glyphs < (int)otl_buffer->in_length) {
+ item->num_glyphs = otl_buffer->in_length;
+ return FALSE;
+ }
+
+ for (unsigned int i = 0; i < otl_buffer->in_length; ++i) {
+ item->glyphs[i] = otl_buffer->in_string[i].gindex;
+ item->attributes[i] = tmpAttributes[otl_buffer->in_string[i].cluster];
+ if (i && otl_buffer->in_string[i].cluster == otl_buffer->in_string[i-1].cluster)
+ item->attributes[i].clusterStart = FALSE;
+ }
+ item->num_glyphs = otl_buffer->in_length;
+
+ if (doLogClusters) {
+ // we can't do this for indic, as we pass the stuf in syllables and it's easier to do it in the tqshaper.
+ unsigned short *logClusters = item->log_clusters;
+ int clusterStart = 0;
+ int oldCi = 0;
+ for (unsigned int i = 0; i < otl_buffer->in_length; ++i) {
+ int ci = otl_buffer->in_string[i].cluster;
+ // qDebug(" ci[%d] = %d mark=%d, cmb=%d, cs=%d",
+ // i, ci, glyphAttributes[i].mark, glyphAttributes[i].combiningClass, glyphAttributes[i].clusterStart);
+ if (!item->attributes[i].mark && item->attributes[i].clusterStart && ci != oldCi) {
+ for (int j = oldCi; j < ci; j++)
+ logClusters[j] = clusterStart;
+ clusterStart = i;
+ oldCi = ci;
+ }
+ }
+ for (int j = oldCi; j < length; j++)
+ logClusters[j] = clusterStart;
+ }
+
+ // calulate the advances for the tqshaped glyphs
+// qDebug("unpositioned: ");
+ static_cast<TQFontEngineXft *>(item->font)->recalcAdvances(item->num_glyphs, item->glyphs, item->advances);
+
+ // positioning code:
+ if (gpos) {
+ float scale = item->font->scale();
+ OTL_Position positions = otl_buffer->positions;
+
+// qDebug("positioned glyphs:");
+ for (unsigned int i = 0; i < otl_buffer->in_length; i++) {
+// qDebug(" %d:\t orig advance: (%d/%d)\tadv=(%d/%d)\tpos=(%d/%d)\tback=%d\tnew_advance=%d", i,
+// glyphs[i].advance.x.toInt(), glyphs[i].advance.y.toInt(),
+// (int)(positions[i].x_advance >> 6), (int)(positions[i].y_advance >> 6),
+// (int)(positions[i].x_pos >> 6), (int)(positions[i].y_pos >> 6),
+// positions[i].back, positions[i].new_advance);
+ // ###### fix the case where we have y advances. How do we handle this in Uniscribe?????
+ if (positions[i].new_advance) {
+ item->advances[i] = item->flags & TQTextEngine::RightToLeft
+ ? -tqRound((positions[i].x_advance >> 6)*scale)
+ : tqRound((positions[i].x_advance >> 6)*scale);
+ } else {
+ item->advances[i] += item->flags & TQTextEngine::RightToLeft
+ ? -tqRound((positions[i].x_advance >> 6)*scale)
+ : tqRound((positions[i].x_advance >> 6)*scale);
+ }
+ int back = 0;
+ item->offsets[i].x = tqRound((positions[i].x_pos >> 6)*scale);
+ item->offsets[i].y = tqRound((positions[i].y_pos >> 6)*scale);
+ while (positions[i-back].back) {
+ back += positions[i - back].back;
+ item->offsets[i].x += tqRound((positions[i - back].x_pos >> 6)*scale);
+ item->offsets[i].y += tqRound((positions[i - back].y_pos >> 6)*scale);
+ }
+ item->offsets[i].y = -item->offsets[i].y;
+ back = positions[i].back;
+ if (item->flags & TQTextEngine::RightToLeft) {
+ while (back--) {
+ item->offsets[i].x -= item->advances[i-back];
+ }
+ } else {
+ while (back) {
+ item->offsets[i].x -= item->advances[i-back];
+ --back;
+ }
+ }
+// qDebug(" ->\tadv=%d\tpos=(%d/%d)",
+// glyphs[i].advance.x.toInt(), glyphs[i].offset.x.toInt(), glyphs[i].offset.y.toInt());
+ }
+ item->has_positioning = TRUE;
+ } else {
+ qt_heuristicPosition(item);
+ }
+
+#ifdef OT_DEBUG
+// if (doLogClusters) {
+// qDebug("log clusters after shaping:");
+// for (int j = 0; j < length; j++)
+// qDebug(" log[%d] = %d", j, item->log_clusters[j]);
+// }
+ qDebug("final glyphs:");
+ for (int i = 0; i < (int)otl_buffer->in_length; ++i)
+ qDebug(" glyph=%4x char_index=%d mark: %d cmp: %d, clusterStart: %d advance=%d offset=%d/%d",
+ item->glyphs[i], otl_buffer->in_string[i].cluster, item->attributes[i].mark,
+ item->attributes[i].combiningClass, item->attributes[i].clusterStart,
+ item->advances[i],
+ item->offsets[i].x, item->offsets[i].y);
+ qDebug("-----------------------------------------");
+#endif
+ return TRUE;
+}
+
+#endif
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqfontinfo.h b/tqtinterface/qt4/src/kernel/tqfontinfo.h
new file mode 100644
index 0000000..916169e
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfontinfo.h
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Definition of TQFontInfo class
+**
+** Created : 950131
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFONTINFO_H
+#define TQFONTINFO_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqfont.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qfontinfo.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQFontInfo : public QFontInfo, virtual public TQt
+{
+public:
+ TQFontInfo( const TQFont &fn ) : QFontInfo ( fn ) {}
+ TQFontInfo( const TQFont &fn, TQFont::Script sc ) : QFontInfo ( fn ) { TQ_UNUSED(sc); }
+ TQFontInfo( const TQFontInfo &fi ) : QFontInfo ( fi ) {}
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQFontInfo
+{
+public:
+ TQFontInfo( const TQFont & );
+ TQFontInfo( const TQFont &, TQFont::Script );
+ TQFontInfo( const TQFontInfo & );
+ ~TQFontInfo();
+
+ TQFontInfo &operator=( const TQFontInfo & );
+
+ TQString family() const;
+ int pixelSize() const;
+ int pointSize() const;
+ bool italic() const;
+ int weight() const;
+ bool bold() const;
+ bool underline() const;
+ bool overline() const;
+ bool strikeOut() const;
+ bool fixedPitch() const;
+ TQFont::StyleHint tqstyleHint() const;
+ bool rawMode() const;
+
+ bool exactMatch() const;
+
+
+private:
+ TQFontInfo( const TQPainter * );
+
+ TQFontPrivate *d;
+ TQPainter *painter;
+ int fscript;
+
+ friend class TQWidget;
+ friend class TQPainter;
+};
+
+
+inline bool TQFontInfo::bold() const
+{ return weight() > TQFont::Normal; }
+
+#endif // USE_QT4
+
+#endif // TQFONTINFO_H
diff --git a/tqtinterface/qt4/src/kernel/tqfontmetrics.h b/tqtinterface/qt4/src/kernel/tqfontmetrics.h
new file mode 100644
index 0000000..aca4c58
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqfontmetrics.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Definition of TQFontMetrics class
+**
+** Created : 940514
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFONTMETRICS_H
+#define TQFONTMETRICS_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqfont.h"
+#include "tqrect.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qfontmetrics.h>
+
+#endif // USE_QT4
+
+#ifdef TQ_WS_TQWS
+class TQFontEngine;
+#endif
+
+class TQTextCodec;
+class TQTextParag;
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQFontMetrics : public QFontMetrics, virtual public TQt
+{
+public:
+ TQFontMetrics( const QFont &fn ) : QFontMetrics( fn ) {}
+ TQFontMetrics( const QFont &fn, TQFont::Script sc ) : QFontMetrics( fn ) { TQ_UNUSED(sc); }
+ TQFontMetrics( const QFontMetrics &fm ) : QFontMetrics( fm ) {}
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQFontMetrics
+{
+public:
+ TQFontMetrics( const TQFont & );
+ TQFontMetrics( const TQFont &, TQFont::Script );
+ TQFontMetrics( const TQFontMetrics & );
+ ~TQFontMetrics();
+
+ TQFontMetrics &operator=( const TQFontMetrics & );
+
+ int ascent() const;
+ int descent() const;
+ int height() const;
+ int leading() const;
+ int lineSpacing() const;
+ int minLeftBearing() const;
+ int minRightBearing() const;
+ int maxWidth() const;
+
+ bool inFont(TQChar) const;
+
+ int leftBearing(TQChar) const;
+ int rightBearing(TQChar) const;
+ int width( const TQString &, int len = -1 ) const;
+
+ int width( TQChar ) const;
+#ifndef TQT_NO_COMPAT
+ int width( char c ) const { return width( (TQChar) c ); }
+#endif
+
+ int charWidth( const TQString &str, int pos ) const;
+ TQRect boundingRect( const TQString &, int len = -1 ) const;
+ TQRect boundingRect( TQChar ) const;
+ TQRect boundingRect( int x, int y, int w, int h, int flags,
+ const TQString& str, int len=-1, int tabstops=0,
+ int *tabarray=0, TQTextParag **intern=0 ) const;
+ TQSize size( int flags,
+ const TQString& str, int len=-1, int tabstops=0,
+ int *tabarray=0, TQTextParag **intern=0 ) const;
+
+ int underlinePos() const;
+ int overlinePos() const;
+ int strikeOutPos() const;
+ int lineWidth() const;
+
+private:
+ TQFontMetrics( const TQPainter * );
+
+ friend class TQWidget;
+ friend class TQPainter;
+ friend class TQTextFormat;
+#if defined( TQ_WS_MAC )
+ friend class TQFontPrivate;
+#endif
+
+ TQFontPrivate *d;
+ TQPainter *painter;
+ int fscript;
+};
+
+#endif // USE_QT4
+
+#endif // TQFONTMETRICS_H
diff --git a/tqtinterface/qt4/src/kernel/tqgif.h b/tqtinterface/qt4/src/kernel/tqgif.h
new file mode 100644
index 0000000..749b637
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqgif.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** To enable built-in reading of GIF images in TQt, change the definition
+** below to "#define TQT_BUILTIN_GIF_READER 1".
+**
+** To disable built-in reading of GIF images in TQt, change the definition
+** below to "#define TQT_BUILTIN_GIF_READER 0".
+**
+** WARNING:
+** A separate license from Unisys may be required to use the gif
+** reader. See http://www.unisys.com/about__unisys/lzw/
+** for information from Unisys
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGIF_H
+#define TQGIF_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#ifndef TQT_BUILTIN_GIF_READER
+#define TQT_BUILTIN_GIF_READER 0
+#endif
+
+bool qt_builtin_gif_reader();
+
+#endif // TQGIF_H
diff --git a/tqtinterface/qt4/src/kernel/tqgplugin.cpp b/tqtinterface/qt4/src/kernel/tqgplugin.cpp
new file mode 100644
index 0000000..848e6c7
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqgplugin.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqgplugin.h"
+
+#ifndef TQT_NO_COMPONENT
+
+#include <private/tqcom_p.h>
+
+TQGPlugin::TQGPlugin()
+ : _iface( 0 )
+{
+}
+
+TQGPlugin::TQGPlugin( TQUnknownInterface *i )
+ : _iface( i )
+{
+}
+
+TQGPlugin::~TQGPlugin()
+{
+}
+
+TQUnknownInterface* TQGPlugin::iface()
+{
+ TQ_ASSERT( _iface );
+ TQUnknownInterface *i;
+ _iface->queryInterface( IID_TQUnknown, &i );
+ return i;
+}
+
+void TQGPlugin::setIface( TQUnknownInterface *iface )
+{
+ _iface = iface;
+}
+
+#endif // TQT_NO_COMPONENT
diff --git a/tqtinterface/qt4/src/kernel/tqgplugin.h b/tqtinterface/qt4/src/kernel/tqgplugin.h
new file mode 100644
index 0000000..f892d77
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqgplugin.h
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGPLUGIN_H
+#define TQGPLUGIN_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_COMPONENT
+
+#ifndef TQ_EXTERN_C
+#ifdef __cplusplus
+#define TQ_EXTERN_C extern "C"
+#else
+#define TQ_EXTERN_C extern
+#endif
+#endif
+
+#ifndef TQ_EXPORT_PLUGIN
+#if defined(TQT_THREAD_SUPPORT)
+#define TQT_THREADED_BUILD 1
+#define TQ_PLUGIN_FLAGS_STRING "11"
+#else
+#define TQT_THREADED_BUILD 0
+#define TQ_PLUGIN_FLAGS_STRING "01"
+#endif
+
+// this is duplicated at TQ_UCM_VERIFICATION_DATA in qcom_p.h
+// NOTE: if you change pattern, you MUST change the pattern in
+// qcomlibrary.cpp as well. changing the pattern will break all
+// backwards compatibility as well (no old plugins will be loaded).
+#ifndef TQ_PLUGIN_VERIFICATION_DATA
+# define TQ_PLUGIN_VERIFICATION_DATA \
+ static const char *qt_ucm_verification_data = \
+ "pattern=""TQT_UCM_VERIFICATION_DATA""\n" \
+ "version="TQT_VERSION_STR"\n" \
+ "flags="TQ_PLUGIN_FLAGS_STRING"\n" \
+ "buildkey="TQT_BUILD_KEY"\0";
+#endif // TQ_PLUGIN_VERIFICATION_DATA
+
+#define TQ_PLUGIN_INSTANTIATE( IMPLEMENTATION ) \
+ { \
+ IMPLEMENTATION *i = new IMPLEMENTATION; \
+ return i->iface(); \
+ }
+
+# ifdef TQ_WS_WIN
+# ifdef TQ_CC_BOR
+# define TQ_EXPORT_PLUGIN(PLUGIN) \
+ TQ_PLUGIN_VERIFICATION_DATA \
+ TQ_EXTERN_C __declspec(dllexport) \
+ const char * __stdcall qt_ucm_query_verification_data() \
+ { return qt_ucm_verification_data; } \
+ TQ_EXTERN_C __declspec(dllexport) TQUnknownInterface* \
+ __stdcall ucm_instantiate() \
+ TQ_PLUGIN_INSTANTIATE( PLUGIN )
+# else
+# define TQ_EXPORT_PLUGIN(PLUGIN) \
+ TQ_PLUGIN_VERIFICATION_DATA \
+ TQ_EXTERN_C __declspec(dllexport) \
+ const char *qt_ucm_query_verification_data() \
+ { return qt_ucm_verification_data; } \
+ TQ_EXTERN_C __declspec(dllexport) TQUnknownInterface* ucm_instantiate() \
+ TQ_PLUGIN_INSTANTIATE( PLUGIN )
+# endif
+# else
+# define TQ_EXPORT_PLUGIN(PLUGIN) \
+ TQ_PLUGIN_VERIFICATION_DATA \
+ TQ_EXTERN_C \
+ const char *qt_ucm_query_verification_data() \
+ { return qt_ucm_verification_data; } \
+ TQ_EXTERN_C TQUnknownInterface* ucm_instantiate() \
+ TQ_PLUGIN_INSTANTIATE( PLUGIN )
+# endif
+
+#endif
+
+struct TQUnknownInterface;
+
+class TQ_EXPORT TQGPlugin : public TQObject
+{
+ TQ_OBJECT
+public:
+ TQGPlugin( TQUnknownInterface *i );
+ ~TQGPlugin();
+
+ TQUnknownInterface* iface();
+ void setIface( TQUnknownInterface *iface );
+
+private:
+ TQGPlugin();
+ TQUnknownInterface* _iface;
+};
+
+#endif // TQT_NO_COMPONENT
+
+#endif // TQGPLUGIN_H
diff --git a/tqtinterface/qt4/src/kernel/tqguardedptr.cpp b/tqtinterface/qt4/src/kernel/tqguardedptr.cpp
new file mode 100644
index 0000000..ca41d8d
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqguardedptr.cpp
@@ -0,0 +1,226 @@
+/****************************************************************************
+**
+** Implementation of TQGuardedPtr class
+**
+** Created : 990929
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqguardedptr.h"
+
+/*!
+ \class TQGuardedPtr tqguardedptr.h
+ \brief The TQGuardedPtr class is a template class that provides guarded pointers to TQObjects.
+
+ \ingroup objectmodel
+ \mainclass
+
+ A guarded pointer, \c{TQGuardedPtr<X>}, behaves like a normal C++
+ pointer \c{X*}, except that it is automatically set to 0 when
+ the referenced object is destroyed (unlike normal C++ pointers,
+ which become "dangling pointers" in such cases). \c X must be a
+ subclass of TQObject.
+
+ Guarded pointers are useful whenever you need to store a pointer
+ to a TQObject that is owned by someone else and therefore might be
+ destroyed while you still hold a reference to it. You can safely
+ test the pointer for validity.
+
+ Example:
+ \code
+ TQGuardedPtr<TQLabel> label = new TQLabel( 0, "label" );
+ label->setText( "I like guarded pointers" );
+
+ delete (TQLabel*) label; // simulate somebody destroying the label
+
+ if ( label)
+ label->show();
+ else
+ qDebug("The label has been destroyed");
+ \endcode
+
+ The program will output \c{The label has been destroyed} rather
+ than dereferencing an invalid address in \c label->show().
+
+ The functions and operators available with a TQGuardedPtr are the
+ same as those available with a normal unguarded pointer, except
+ the pointer arithmetic operators (++, --, -, and +), which are
+ normally used only with arrays of objects. Use them like normal
+ pointers and you will not need to read this class documentation.
+
+ For creating guarded pointers, you can construct or assign to them
+ from an X* or from another guarded pointer of the same type. You
+ can compare them with each other using operator==() and
+ operator!=(), or test for 0 with isNull(). And you can dereference
+ them using either the \c *x or the \c x->member notation.
+
+ A guarded pointer will automatically cast to an X*, so you can
+ freely mix guarded and unguarded pointers. This means that if you
+ have a TQGuardedPtr<TQWidget>, you can pass it to a function that
+ requires a TQWidget*. For this reason, it is of little value to
+ declare functions to take a TQGuardedPtr as a parameter; just use
+ normal pointers. Use a TQGuardedPtr when you are storing a pointer
+ over time.
+
+ Note again that class \e X must inherit TQObject, or a compilation
+ or link error will result.
+*/
+
+/*!
+ \fn TQGuardedPtr::TQGuardedPtr()
+
+ Constructs a 0 guarded pointer.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn TQGuardedPtr::TQGuardedPtr( T* p )
+
+ Constructs a guarded pointer that points to same object as \a p
+ points to.
+*/
+
+/*!
+ \fn TQGuardedPtr::TQGuardedPtr(const TQGuardedPtr<T> &p)
+
+ Copy one guarded pointer from another. The constructed guarded
+ pointer points to the same object that \a p points to (which may
+ be 0).
+*/
+
+/*!
+ \fn TQGuardedPtr::~TQGuardedPtr()
+
+ Destroys the guarded pointer. Just like a normal pointer,
+ destroying a guarded pointer does \e not destroy the object being
+ pointed to.
+*/
+
+/*!
+ \fn TQGuardedPtr<T>& TQGuardedPtr::operator=(const TQGuardedPtr<T> &p)
+
+ Assignment operator. This guarded pointer then points to the same
+ object as \a p points to.
+*/
+
+/*!
+ \overload TQGuardedPtr<T> & TQGuardedPtr::operator=(T* p)
+
+ Assignment operator. This guarded pointer then points to the same
+ object as \a p points to.
+*/
+
+/*!
+ \fn bool TQGuardedPtr::operator==( const TQGuardedPtr<T> &p ) const
+
+ Equality operator; implements traditional pointer semantics.
+ Returns TRUE if both \a p and this guarded pointer are 0, or if
+ both \a p and this pointer point to the same object; otherwise
+ returns FALSE.
+
+ \sa operator!=()
+*/
+
+/*!
+ \fn bool TQGuardedPtr::operator!= ( const TQGuardedPtr<T>& p ) const
+
+ Inequality operator; implements pointer semantics, the negation of
+ operator==(). Returns TRUE if \a p and this guarded pointer are
+ not pointing to the same object; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQGuardedPtr::isNull() const
+
+ Returns \c TRUE if the referenced object has been destroyed or if
+ there is no referenced object; otherwise returns FALSE.
+*/
+
+/*!
+ \fn T* TQGuardedPtr::operator->() const
+
+ Overloaded arrow operator; implements pointer semantics. Just use
+ this operator as you would with a normal C++ pointer.
+*/
+
+/*!
+ \fn T& TQGuardedPtr::operator*() const
+
+ Dereference operator; implements pointer semantics. Just use this
+ operator as you would with a normal C++ pointer.
+*/
+
+/*!
+ \fn TQGuardedPtr::operator T*() const
+
+ Cast operator; implements pointer semantics. Because of this
+ function you can pass a TQGuardedPtr\<X\> to a function where an X*
+ is required.
+*/
+
+
+/* Internal classes */
+
+
+TQGuardedPtrPrivate::TQGuardedPtrPrivate( TQObject* o)
+ : TQObject(0, "_ptrpriv" ), obj( o )
+{
+ if ( obj )
+ connect( obj, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( objectDestroyed() ) );
+}
+
+
+TQGuardedPtrPrivate::~TQGuardedPtrPrivate()
+{
+}
+
+void TQGuardedPtrPrivate::reconnect( TQObject *o )
+{
+ if ( obj == o )
+ return;
+ if ( obj )
+ disconnect( obj, TQT_SIGNAL( destroyed() ),
+ this, TQT_SLOT( objectDestroyed() ) );
+ obj = o;
+ if ( obj )
+ connect( obj, TQT_SIGNAL( destroyed() ),
+ this, TQT_SLOT( objectDestroyed() ) );
+}
+
+void TQGuardedPtrPrivate::objectDestroyed()
+{
+ obj = 0;
+}
diff --git a/tqtinterface/qt4/src/kernel/tqguardedptr.h b/tqtinterface/qt4/src/kernel/tqguardedptr.h
new file mode 100644
index 0000000..d786d12
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqguardedptr.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Definition of TQGuardedPtr class
+**
+** Created : 990929
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGUARDEDPTR_H
+#define TQGUARDEDPTR_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+
+// ### 4.0: rename to something without Private in it. Not really internal.
+class TQ_EXPORT TQGuardedPtrPrivate : public TQObject, public TQShared
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQGuardedPtrPrivate( TQObject* );
+ ~TQGuardedPtrPrivate();
+
+ TQObject* object() const;
+ void reconnect( TQObject* );
+
+private Q_SLOTS:
+ void objectDestroyed();
+
+private:
+ TQObject* obj;
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQGuardedPtrPrivate( const TQGuardedPtrPrivate & );
+ TQGuardedPtrPrivate &operator=( const TQGuardedPtrPrivate & );
+#endif
+};
+
+template <class T>
+class TQGuardedPtr
+{
+public:
+ TQGuardedPtr() : priv( new TQGuardedPtrPrivate( 0 ) ) {}
+
+ TQGuardedPtr( T* o) {
+ priv = new TQGuardedPtrPrivate( (TQObject*)o );
+ }
+
+ TQGuardedPtr(const TQGuardedPtr<T> &p) {
+ priv = p.priv;
+ ref();
+ }
+
+ ~TQGuardedPtr() { deref(); }
+
+ TQGuardedPtr<T> &operator=(const TQGuardedPtr<T> &p) {
+ if ( priv != p.priv ) {
+ deref();
+ priv = p.priv;
+ ref();
+ }
+ return *this;
+ }
+
+ TQGuardedPtr<T> &operator=(T* o) {
+ if ( priv && priv->count == 1 ) {
+ priv->reconnect( (TQObject*)o );
+ } else {
+ deref();
+ priv = new TQGuardedPtrPrivate( (TQObject*)o );
+ }
+ return *this;
+ }
+
+ bool operator==( const TQGuardedPtr<T> &p ) const {
+ return (T*)(*this) == (T*) p;
+ }
+
+ bool operator!= ( const TQGuardedPtr<T>& p ) const {
+ return !( *this == p );
+ }
+
+ bool isNull() const { return !priv || !priv->object(); }
+
+ T* operator->() const { return (T*)(priv?priv->object():0); }
+
+ T& operator*() const { return *((T*)(priv?priv->object():0)); }
+
+ operator T*() const { return (T*)(priv?priv->object():0); }
+
+private:
+
+ void ref() { if (priv) priv->ref(); }
+
+ void deref() {
+ if ( priv && priv->deref() )
+ delete priv;
+ }
+
+ TQGuardedPtrPrivate* priv;
+};
+
+
+
+
+inline TQObject* TQGuardedPtrPrivate::object() const
+{
+ return obj;
+}
+
+#define TQ_DEFINED_TQGUARDEDPTR
+#include "tqwinexport.h"
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqiconset.cpp b/tqtinterface/qt4/src/kernel/tqiconset.cpp
new file mode 100644
index 0000000..e5769f8
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqiconset.cpp
@@ -0,0 +1,949 @@
+/****************************************************************************
+**
+** Implementation of TQIconSet class
+**
+** Created : 980318
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqiconset.h"
+
+#ifndef TQT_NO_ICONSET
+
+#include "tqapplication.h"
+#include "tqbitmap.h"
+#include "tqcleanuphandler.h"
+#include "tqimage.h"
+#include "tqpainter.h"
+
+enum { NumSizes = 2, NumModes = 3, NumStates = 2 };
+
+static TQIconFactory *defaultFac = 0;
+static TQSingleCleanupHandler<TQIconFactory> q_cleanup_icon_factory;
+
+static short widths[2] = { 22, 32 };
+static short heights[2] = { 22, 32 };
+
+enum TQIconSetIconOrigin {
+ SuppliedFileName, // 'fileName' tqcontains the name of the file
+ SuppliedPixmap, // 'pixmap' is a pointer to the user-supplied pixmap
+ Manufactured, // 'pixmap' is a factory-generated pixmap (or 0)
+ Generated // 'pixmap' is a TQIconSet-generated pixmap (or 0)
+};
+
+struct TQIconSetIcon
+{
+ TQIconSetIconOrigin origin;
+ union {
+ TQString *fileName;
+ TQPixmap *pixmap;
+ };
+
+ TQIconSetIcon() : origin( Generated ) { pixmap = 0; }
+ TQIconSetIcon( const TQIconSetIcon& other )
+ : origin( Generated ) {
+ pixmap = 0;
+ operator=( other );
+ }
+ ~TQIconSetIcon() {
+ if ( origin == SuppliedFileName ) {
+ delete fileName;
+ } else {
+ delete pixmap;
+ }
+ }
+
+ TQIconSetIcon& operator=( const TQIconSetIcon& other );
+
+ void clearCached() {
+ if ( pixmap && (origin == Manufactured || origin == Generated) ) {
+ origin = Generated;
+ delete pixmap;
+ pixmap = 0;
+ }
+ }
+};
+
+TQIconSetIcon& TQIconSetIcon::operator=( const TQIconSetIcon& other )
+{
+ TQPixmap *oldPixmap = 0;
+ TQString *oldFileName = 0;
+ if ( origin == SuppliedFileName ) {
+ oldFileName = fileName;
+ } else {
+ oldPixmap = pixmap;
+ }
+
+ origin = other.origin;
+ if ( other.origin == SuppliedFileName ) {
+ fileName = new TQString( *other.fileName );
+ } else {
+ if ( other.pixmap ) {
+ pixmap = new TQPixmap( *other.pixmap );
+ } else {
+ pixmap = 0;
+ }
+ }
+ delete oldPixmap;
+ delete oldFileName;
+ return *this;
+}
+
+class TQIconSetPrivate : public TQShared
+{
+public:
+ TQIconSetIcon icons[NumSizes][NumModes][NumStates];
+ TQPixmap defaultPix;
+ TQIconFactory *factory;
+
+ TQIconSetPrivate() : factory( 0 ) { }
+ TQIconSetPrivate( const TQIconSetPrivate& other ) : TQShared() {
+ count = 1;
+ for ( int i = 0; i < NumSizes; i++ ) {
+ for ( int j = 0; j < NumModes; j++ ) {
+ for ( int k = 0; k < NumStates; k++ ) {
+ icons[i][j][k] = other.icons[i][j][k];
+ }
+ }
+ }
+ defaultPix = other.defaultPix;
+ factory = other.factory;
+ if ( factory )
+ factory->ref();
+ }
+ ~TQIconSetPrivate() {
+ setFactory( 0 );
+ }
+
+ TQIconSetIcon *icon( const TQIconSet *iconSet, TQIconSet::Size size,
+ TQIconSet::Mode mode, TQIconSet::State state );
+ void setFactory( TQIconFactory *newFactory ) {
+ if ( newFactory )
+ newFactory->ref();
+ if ( factory && factory->deref() && factory->autoDelete() )
+ delete factory;
+ factory = newFactory;
+ }
+
+ TQ_DUMMY_COMPARISON_OPERATOR( TQIconSetPrivate )
+};
+
+TQIconSetIcon *TQIconSetPrivate::icon( const TQIconSet *iconSet,
+ TQIconSet::Size size, TQIconSet::Mode mode,
+ TQIconSet::State state )
+{
+ TQIconSetIcon *ik = &icons[(int) size - 1][(int) mode][(int) state];
+
+ if ( iconSet ) {
+ if ( ik->origin == SuppliedFileName ) {
+ TQPixmap *newPixmap = new TQPixmap( *ik->fileName );
+ delete ik->fileName;
+
+ if ( newPixmap->isNull() ) {
+ delete newPixmap;
+ ik->origin = Generated;
+ ik->pixmap = 0;
+ } else {
+ ik->origin = SuppliedPixmap;
+ ik->pixmap = newPixmap;
+ }
+ }
+
+ if ( !ik->pixmap && ik->origin == Generated ) {
+ TQIconFactory *f = factory;
+ if ( !f )
+ f = defaultFac;
+
+ if ( f ) {
+ /*
+ We set 'origin' to Manufactured half a second too
+ early to prevent recursive calls to this function.
+ (This can happen if createPixmap() calls
+ TQIconSet::pixmap(), which in turn calls this
+ function.)
+ */
+ ik->origin = Manufactured;
+ ik->pixmap = f->createPixmap( *iconSet, size, mode, state );
+ if ( !ik->pixmap )
+ ik->origin = Generated;
+ }
+ }
+ }
+ return ik;
+}
+
+/*! \class TQIconSet
+
+ \brief The TQIconSet class provides a set of icons with different
+ styles and sizes.
+
+ \ingroup graphics
+ \ingroup images
+ \ingroup shared
+ \mainclass
+
+ A TQIconSet can generate smaller, larger, active, and disabled pixmaps
+ from the set of icons it is given. Such pixmaps are used by
+ TQToolButton, TQHeader, TQPopupMenu, etc. to show an icon representing a
+ particular action.
+
+ The simplest use of TQIconSet is to create one from a TQPixmap and then
+ use it, allowing TQt to work out all the required icon styles and
+ sizes. For example:
+
+ \code
+ TQToolButton *but = new TQToolButton( TQIconSet( TQPixmap("open.xpm") ), ... );
+ \endcode
+
+ Using whichever pixmaps you specify as a base, TQIconSet provides a
+ set of six icons, each with a \l Size and a \l Mode: Small Normal,
+ Small Disabled, Small Active, Large Normal, Large Disabled, and
+ Large Active.
+
+ An additional set of six icons can be provided for widgets that have
+ an "On" or "Off" state, like checkable menu items or toggleable
+ toolbuttons. If you provide pixmaps for the "On" state, but not for
+ the "Off" state, the TQIconSet will provide the "Off" pixmaps. You may
+ specify icons for both states in you wish.
+
+ You can set any of the icons using setPixmap().
+
+ When you retrieve a pixmap using pixmap(Size, Mode, State),
+ TQIconSet will return the icon that has been set or previously
+ generated for that size, mode and state combination. If none is
+ available, TQIconSet will ask the icon factory. If the icon factory
+ cannot provide any (the default), TQIconSet generates a pixmap based
+ on the pixmaps it has been given and returns it.
+
+ The \c Disabled appearance is computed using an algorithm that
+ produces results very similar to those used in Microsoft Windows
+ 95. The \c Active appearance is identical to the \c Normal
+ appearance unless you use setPixmap() to set it to something
+ special.
+
+ When scaling icons, TQIconSet uses \link TQImage::smoothScale()
+ smooth scaling\endlink, which can partially blend the color component
+ of pixmaps. If the results look poor, the best solution
+ is to supply pixmaps in both large and small sizes.
+
+ You can use the static function setIconSize() to set the preferred
+ size of the generated large/small icons. The default small size is
+ 22 x 22, while the default large size is 32 x 32. These sizes only
+ affect generated icons.
+
+ The isGenerated() function returns TRUE if an icon was generated by
+ TQIconSet or by a factory; clearGenerated() clears all cached
+ pixmaps.
+
+ \section1 Making Classes that Use TQIconSet
+
+ If you write your own widgets that have an option to set a small
+ pixmap, consider allowing a TQIconSet to be set for that pixmap. The
+ TQt class TQToolButton is an example of such a widget.
+
+ Provide a method to set a TQIconSet, and when you draw the icon, choose
+ whichever icon is appropriate for the current state of your widget.
+ For example:
+ \code
+ void MyWidget::drawIcon( TQPainter* p, TQPoint pos )
+ {
+ p->drawPixmap( pos, icons->pixmap(
+ TQIconSet::Small,
+ isEnabled() ? TQIconSet::Normal :
+ TQIconSet::Disabled,
+ isEnabled() ? TQIconSet::On :
+ TQIconSet::Off));
+ }
+ \endcode
+
+ You might also make use of the \c Active mode, perhaps making your
+ widget \c Active when the mouse is over the widget (see \l
+ TQWidget::enterEvent()), while the mouse is pressed pending the
+ release that will activate the function, or when it is the currently
+ selected item. If the widget can be toggled, the "On" mode might be
+ used to draw a different icon.
+
+ \img iconset.png TQIconSet
+
+ \sa TQIconFactory TQPixmap TQMainWindow::setUsesBigPixmaps()
+ \link guibooks.html#fowler GUI Design Handbook: Iconic Label \endlink
+*/
+
+
+/*!
+ \enum TQIconSet::Size
+
+ This enum type describes the size at which a pixmap is intended to be
+ used.
+ The currently defined sizes are:
+
+ \value Automatic The size of the pixmap is determined from its
+ pixel size. This is a useful default.
+ \value Small The pixmap is the smaller of two.
+ \value Large The pixmap is the larger of two.
+
+ If a Small pixmap is not set by TQIconSet::setPixmap(), the Large
+ pixmap will be automatically scaled down to the size of a small pixmap
+ to generate the Small pixmap when required. Similarly, a Small pixmap
+ will be automatically scaled up to generate a Large pixmap. The
+ preferred sizes for large/small generated icons can be set using
+ setIconSize().
+
+ \sa setIconSize() iconSize() setPixmap() pixmap() TQMainWindow::setUsesBigPixmaps()
+*/
+
+/*!
+ \enum TQIconSet::Mode
+
+ This enum type describes the mode for which a pixmap is intended to be
+ used.
+ The currently defined modes are:
+
+ \value Normal
+ Display the pixmap when the user is
+ not interacting with the icon, but the
+ functionality represented by the icon is available.
+ \value Disabled
+ Display the pixmap when the
+ functionality represented by the icon is not available.
+ \value Active
+ Display the pixmap when the
+ functionality represented by the icon is available and
+ the user is interacting with the icon, for example, moving the
+ mouse over it or clicking it.
+*/
+
+/*!
+ \enum TQIconSet::State
+
+ This enum describes the state for which a pixmap is intended to be
+ used. The \e state can be:
+
+ \value Off Display the pixmap when the widget is in an "off" state
+ \value On Display the pixmap when the widget is in an "on" state
+
+ \sa setPixmap() pixmap()
+*/
+
+/*!
+ Constructs a null icon set.
+
+ \sa setPixmap(), reset()
+*/
+TQIconSet::TQIconSet()
+ : d( 0 )
+{
+}
+
+/*!
+ Constructs an icon set for which the Normal pixmap is \a pixmap,
+ which is assumed to be of size \a size.
+
+ The default for \a size is \c Automatic, which means that TQIconSet
+ will determine whether the pixmap is Small or Large from its pixel
+ size. Pixmaps less than the width of a small generated icon are
+ considered to be Small. You can use setIconSize() to set the
+ preferred size of a generated icon.
+
+ \sa setIconSize() reset()
+*/
+TQIconSet::TQIconSet( const TQPixmap& pixmap, Size size )
+ : d( 0 )
+{
+ reset( pixmap, size );
+}
+
+/*! Creates an iconset which uses the pixmap \a smallPix for for
+ displaying a small icon, and the pixmap \a largePix for displaying a
+ large icon.
+*/
+TQIconSet::TQIconSet( const TQPixmap& smallPix, const TQPixmap& largePix )
+ : d( 0 )
+{
+ reset( smallPix, Small );
+ reset( largePix, Large );
+}
+
+/*!
+ Constructs a copy of \a other. This is very fast.
+*/
+TQIconSet::TQIconSet( const TQIconSet& other )
+ : d( other.d )
+{
+ if ( d )
+ d->ref();
+}
+
+/*!
+ Destroys the icon set and frees any allocated resources.
+*/
+TQIconSet::~TQIconSet()
+{
+ if ( d && d->deref() )
+ delete d;
+}
+
+/*!
+ Sets this icon set to use pixmap \a pixmap for the Normal pixmap,
+ assuming it to be of size \a size.
+
+ This is equivalent to assigning TQIconSet(\a pixmap, \a size) to this
+ icon set.
+
+ This function does nothing if \a pixmap is a null pixmap.
+*/
+void TQIconSet::reset( const TQPixmap& pixmap, Size size )
+{
+ if ( pixmap.isNull() )
+ return;
+
+ detach();
+ normalize( size, pixmap.size() );
+ setPixmap( pixmap, size, Normal );
+ d->defaultPix = pixmap;
+ d->setFactory( 0 );
+}
+
+/*!
+ Sets this icon set to provide pixmap \a pixmap for size \a size, mode \a
+ mode and state \a state. The icon set may also use \a pixmap for
+ generating other pixmaps if they are not explicitly set.
+
+ The \a size can be one of Automatic, Large or Small. If Automatic is
+ used, TQIconSet will determine if the pixmap is Small or Large from its
+ pixel size.
+
+ Pixmaps less than the width of a small generated icon are
+ considered to be Small. You can use setIconSize() to set the preferred
+ size of a generated icon.
+
+ This function does nothing if \a pixmap is a null pixmap.
+
+ \sa reset()
+*/
+void TQIconSet::setPixmap( const TQPixmap& pixmap, Size size, Mode mode,
+ State state )
+{
+ if ( pixmap.isNull() )
+ return;
+
+ normalize( size, pixmap.size() );
+
+ detach();
+ clearGenerated();
+
+ TQIconSetIcon *icon = d->icon( 0, size, mode, state );
+ if ( icon->origin == SuppliedFileName ) {
+ delete icon->fileName;
+ icon->pixmap = 0;
+ }
+ icon->origin = SuppliedPixmap;
+ if ( icon->pixmap == 0 ) {
+ icon->pixmap = new TQPixmap( pixmap );
+ } else {
+ *icon->pixmap = pixmap;
+ }
+}
+
+/*!
+ \overload
+
+ The pixmap is loaded from \a fileName when it becomes necessary.
+*/
+void TQIconSet::setPixmap( const TQString& fileName, Size size, Mode mode,
+ State state )
+{
+ if ( size == Automatic ) {
+ setPixmap( TQPixmap(fileName), size, mode, state );
+ } else {
+ detach();
+ clearGenerated();
+
+ TQIconSetIcon *icon = d->icon( 0, size, mode, state );
+ if ( icon->origin == SuppliedFileName ) {
+ *icon->fileName = fileName;
+ } else {
+ delete icon->pixmap;
+ icon->fileName = new TQString( fileName );
+ icon->origin = SuppliedFileName;
+ }
+ }
+}
+
+/*!
+ Returns a pixmap with size \a size, mode \a mode and state \a
+ state, generating one if necessary. Generated pixmaps are cached.
+*/
+TQPixmap TQIconSet::pixmap( Size size, Mode mode, State state ) const
+{
+ if ( !d ) {
+ if ( defaultFac ) {
+ TQIconSet *that = (TQIconSet *) this;
+ that->detach();
+ } else {
+ return TQPixmap();
+ }
+ }
+
+ if ( size == Automatic )
+ size = Small;
+
+ TQIconSetIcon *icon = d->icon( this, size, mode, state );
+ if ( icon->pixmap )
+ return *icon->pixmap;
+ if ( icon->origin == Manufactured ) {
+ /*
+ This can only occur during the half a second's time when
+ the icon is being manufactured. If TQIconFactory somehow
+ tries to access the pixmap it's supposed to be creating, it
+ will get a null pixmap.
+ */
+ return TQPixmap();
+ }
+
+ if ( mode == Active )
+ return pixmap( size, Normal, state );
+
+ Size otherSize = ( size == Large ) ? Small : Large;
+ TQIconSetIcon *otherSizeIcon = d->icon( this, otherSize, mode, state );
+
+ if ( state == Off ) {
+ if ( mode == Disabled &&
+ d->icon(this, size, Normal, Off)->origin != Generated ) {
+ icon->pixmap = createDisabled( size, Off );
+ } else if ( otherSizeIcon->origin != Generated ) {
+ icon->pixmap = createScaled( size, otherSizeIcon->pixmap );
+ } else if ( mode == Disabled ) {
+ icon->pixmap = createDisabled( size, Off );
+ } else if ( !d->defaultPix.isNull() ) {
+ icon->pixmap = new TQPixmap( d->defaultPix );
+ } else {
+ /*
+ No icons are available for { TRUE, Normal, Off } and
+ { FALSE, Normal, Off }. Try the other 10 combinaisons,
+ best ones first.
+ */
+ const int N = 10;
+ static const struct {
+ bool sameSize;
+ Mode mode;
+ State state;
+ } tryList[N] = {
+ { TRUE, Active, Off },
+ { TRUE, Normal, On },
+ { TRUE, Active, On },
+ { FALSE, Active, Off },
+ { FALSE, Normal, On },
+ { FALSE, Active, On },
+ { TRUE, Disabled, Off },
+ { TRUE, Disabled, On },
+ { FALSE, Disabled, Off },
+ { FALSE, Disabled, On }
+ };
+
+ for ( int i = 0; i < N; i++ ) {
+ bool sameSize = tryList[i].sameSize;
+ TQIconSetIcon *tryIcon =
+ d->icon( this, sameSize ? size : otherSize,
+ tryList[i].mode, tryList[i].state );
+ if ( tryIcon->origin != Generated ) {
+ if ( sameSize ) {
+ if ( tryIcon->pixmap )
+ icon->pixmap = new TQPixmap( *tryIcon->pixmap );
+ } else {
+ icon->pixmap = createScaled( size, tryIcon->pixmap );
+ }
+ break;
+ }
+ }
+ }
+ } else { /* ( state == On ) */
+ if ( mode == Normal ) {
+ if ( otherSizeIcon->origin != Generated ) {
+ icon->pixmap = createScaled( size, otherSizeIcon->pixmap );
+ } else {
+ icon->pixmap = new TQPixmap( pixmap(size, mode, Off) );
+ }
+ } else { /* ( mode == Disabled ) */
+ TQIconSetIcon *offIcon = d->icon( this, size, mode, Off );
+ TQIconSetIcon *otherSizeOffIcon = d->icon( this, otherSize, mode,
+ Off );
+
+ if ( offIcon->origin != Generated ) {
+ if ( offIcon->pixmap )
+ icon->pixmap = new TQPixmap( *offIcon->pixmap );
+ } else if ( d->icon(this, size, Normal, On)->origin != Generated ) {
+ icon->pixmap = createDisabled( size, On );
+ } else if ( otherSizeIcon->origin != Generated ) {
+ icon->pixmap = createScaled( size, otherSizeIcon->pixmap );
+ } else if ( otherSizeOffIcon->origin != Generated ) {
+ icon->pixmap = createScaled( size, otherSizeOffIcon->pixmap );
+ } else {
+ icon->pixmap = createDisabled( size, On );
+ }
+ }
+ }
+ if ( icon->pixmap ) {
+ return *icon->pixmap;
+ } else {
+ return TQPixmap();
+ }
+}
+
+/*! \overload
+ \obsolete
+
+ This is the same as pixmap(\a size, \a enabled, \a state).
+*/
+TQPixmap TQIconSet::pixmap( Size size, bool enabled, State state ) const
+{
+ return pixmap( size, enabled ? Normal : Disabled, state );
+}
+
+/*!
+ \overload
+
+ Returns the pixmap originally provided to the constructor or to
+ reset(). This is the Normal pixmap of unspecified Size.
+
+ \sa reset()
+*/
+TQPixmap TQIconSet::pixmap() const
+{
+ if ( !d )
+ return TQPixmap();
+ return d->defaultPix;
+}
+
+/*!
+ Returns TRUE if the pixmap with size \a size, mode \a mode and
+ state \a state is generated from other pixmaps; otherwise returns
+ FALSE.
+
+ A pixmap obtained from a TQIconFactory is considered non-generated.
+*/
+bool TQIconSet::isGenerated( Size size, Mode mode, State state ) const
+{
+ if ( !d )
+ return TRUE;
+ return d->icon( this, size, mode, state )->origin == Generated;
+}
+
+/*!
+ Clears all cached pixmaps, including those obtained from an
+ eventual TQIconFactory.
+*/
+void TQIconSet::clearGenerated()
+{
+ if ( !d )
+ return;
+
+ for ( int i = 0; i < NumSizes; i++ ) {
+ for ( int j = 0; j < NumModes; j++ ) {
+ for ( int k = 0; k < NumStates; k++ ) {
+ d->icons[i][j][k].clearCached();
+ }
+ }
+ }
+}
+
+/*!
+ Installs \a factory as the icon factory for this iconset. The
+ icon factory is used to generates pixmaps not set by the user.
+
+ If no icon factory is installed, TQIconFactory::defaultFactory()
+ is used.
+*/
+void TQIconSet::installIconFactory( TQIconFactory *factory )
+{
+ detach();
+ d->setFactory( factory );
+}
+
+/*!
+ Returns TRUE if the icon set is empty; otherwise returns FALSE.
+*/
+bool TQIconSet::isNull() const
+{
+ return !d;
+}
+
+/*!
+ Detaches this icon set from others with which it may share data.
+
+ You will never need to call this function; other TQIconSet functions
+ call it as necessary.
+*/
+void TQIconSet::detach()
+{
+ if ( !d ) {
+ d = new TQIconSetPrivate;
+ return;
+ }
+ if ( d->count != 1 ) {
+ d->deref();
+ d = new TQIconSetPrivate( *d );
+ }
+}
+
+/*!
+ Assigns \a other to this icon set and returns a reference to this
+ icon set.
+
+ \sa detach()
+*/
+TQIconSet& TQIconSet::operator=( const TQIconSet& other )
+{
+ if ( other.d )
+ other.d->ref();
+
+ if ( d && d->deref() )
+ delete d;
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Set the preferred size for all small or large icons that are
+ generated after this call. If \a which is Small, sets the preferred
+ size of small generated icons to \a size. Similarly, if \a which is
+ Large, sets the preferred size of large generated icons to \a size.
+
+ Note that cached icons will not be regenerated, so it is recommended
+ that you set the preferred icon sizes before generating any icon sets.
+ Also note that the preferred icon sizes will be ignored for icon sets
+ that have been created using both small and large pixmaps.
+
+ \sa iconSize()
+*/
+void TQIconSet::setIconSize( Size which, const TQSize& size )
+{
+ widths[(int) which - 1] = size.width();
+ heights[(int) which - 1] = size.height();
+}
+
+/*!
+ If \a which is Small, returns the preferred size of a small
+ generated icon; if \a which is Large, returns the preferred size
+ of a large generated icon.
+
+ \sa setIconSize()
+*/
+const TQSize& TQIconSet::iconSize( Size which )
+{
+ // ### tqreplace 'const TQSize&' with TQSize in TQt 4 and simply this code
+ static TQSize size;
+ size = TQSize( widths[(int) which - 1], heights[(int) which - 1] );
+ return size;
+}
+
+void TQIconSet::normalize( Size& which, const TQSize& pixSize )
+{
+ if ( which == Automatic )
+ which = pixSize.width() > iconSize( Small ).width() ? Large : Small;
+}
+
+/*!
+ Returns a new pixmap that is a copy of \a suppliedPix, scaled to
+ the icon size \a size.
+*/
+TQPixmap *TQIconSet::createScaled( Size size, const TQPixmap *suppliedPix ) const
+{
+ if ( !suppliedPix || suppliedPix->isNull() )
+ return 0;
+
+ TQImage img = suppliedPix->convertToImage();
+ TQSize imgSize = iconSize( size );
+ if ( size == Small ) {
+ imgSize = imgSize.boundedTo( img.size() );
+ } else {
+ imgSize = imgSize.expandedTo( img.size() );
+ }
+ img = img.smoothScale( imgSize );
+
+ TQPixmap *pixmap = new TQPixmap( img );
+ if ( !pixmap->tqmask() ) {
+ TQBitmap tqmask;
+ tqmask.convertFromImage( img.createHeuristicMask(),
+ TQt::MonoOnly | TQt::ThresholdDither );
+ pixmap->setMask( tqmask );
+ }
+ return pixmap;
+}
+
+/*!
+ Returns a new pixmap that has a 'disabled' look, taking as its
+ base the iconset's icon with size \a size and state \a state.
+*/
+TQPixmap *TQIconSet::createDisabled( Size size, State state ) const
+{
+ TQPixmap normalPix = pixmap( size, Normal, state );
+ if ( normalPix.isNull() )
+ return 0;
+
+ TQImage img;
+ TQPixmap *pixmap = 0;
+ TQBitmap normalMask;
+ if ( normalPix.tqmask() ) {
+ normalMask = *normalPix.tqmask();
+ } else {
+ img = normalPix.convertToImage();
+ normalMask.convertFromImage( img.createHeuristicMask(),
+ TQt::MonoOnly | TQt::ThresholdDither );
+ }
+
+ pixmap = new TQPixmap( normalPix.width() + 1,
+ normalPix.height() + 1 );
+ const TQColorGroup &dis = TQApplication::tqpalette().disabled();
+ pixmap->fill( dis.background() );
+
+ TQPainter painter;
+ painter.begin( pixmap );
+ painter.setPen( dis.base() );
+ painter.drawPixmap( 1, 1, normalMask );
+ painter.setPen( dis.foreground() );
+ painter.drawPixmap( 0, 0, normalMask );
+ painter.end();
+
+ if ( !normalMask.tqmask() )
+ normalMask.setMask( normalMask );
+
+ TQBitmap tqmask( pixmap->size() );
+ tqmask.fill( TQt::color0 );
+ painter.begin( &tqmask );
+ painter.drawPixmap( 0, 0, normalMask );
+ painter.drawPixmap( 1, 1, normalMask );
+ painter.end();
+ pixmap->setMask( tqmask );
+ return pixmap;
+}
+
+/*! \class TQIconFactory
+ \ingroup advanced
+ \brief The TQIconFactory class is used to create pixmaps for a TQIconSet.
+
+ By reimplementing createPixmap(), you can override TQIconSet's
+ default algorithm for computing pixmaps not supplied by the user.
+
+ Call setAutoDelete(TRUE) if you want the factory to automatically
+ delete itself when it is no longer needed by TQIconSet.
+
+ \sa TQIconSet
+*/
+
+/*!
+ Constructs an icon factory.
+*/
+TQIconFactory::TQIconFactory()
+ : autoDel( 0 )
+{
+ count = 0;
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+TQIconFactory::~TQIconFactory()
+{
+}
+
+/*!
+ Ceates a pixmap for \a iconSet with a certain \a size, \a mode, and
+ \a state. Returns 0 if the default TQIconSet algorithm should be
+ used to create a pixmap that wasn't supplied by the user.
+
+ It is the caller's responsibility to delete the returned pixmap.
+
+ The default implementation always returns 0.
+*/
+TQPixmap *TQIconFactory::createPixmap( const TQIconSet& /* iconSet */,
+ TQIconSet::Size /* size */,
+ TQIconSet::Mode /* mode */,
+ TQIconSet::State /* state */ )
+{
+ return 0;
+}
+
+/*!
+ \fn void TQIconFactory::setAutoDelete( bool autoDelete )
+
+ If \a autoDelete is TRUE, sets the icon factory to automatically
+ delete itself when it is no longer referenced by any TQIconSet and
+ isn't the default factory. If \a autoDelete is FALSE (the default)
+ auto-deletion is disabled.
+
+ \sa autoDelete(), defaultFactory()
+*/
+
+/*!
+ \fn bool TQIconFactory::autoDelete() const
+
+ Returns TRUE if auto-deletion is enabled; otherwise returns FALSE.
+
+ \sa setAutoDelete()
+*/
+
+/*!
+ Returns the default icon factory.
+
+ \sa installDefaultFactory()
+*/
+TQIconFactory *TQIconFactory::defaultFactory()
+{
+ if ( !defaultFac ) {
+ defaultFac = new TQIconFactory;
+ defaultFac->setAutoDelete( TRUE );
+ defaultFac->ref();
+ q_cleanup_icon_factory.set( &defaultFac );
+ }
+ return defaultFac;
+}
+
+/*!
+ Replaces the default icon factory with \a factory.
+*/
+void TQIconFactory::installDefaultFactory( TQIconFactory *factory )
+{
+ if ( !factory )
+ return;
+
+ factory->ref();
+ if ( defaultFac && defaultFac->deref() && defaultFac->autoDelete() )
+ delete defaultFac;
+ defaultFac = factory;
+ q_cleanup_icon_factory.set( &defaultFac );
+}
+
+#endif // TQT_NO_ICONSET
diff --git a/tqtinterface/qt4/src/kernel/tqiconset.h b/tqtinterface/qt4/src/kernel/tqiconset.h
new file mode 100644
index 0000000..31249ab
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqiconset.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Definition of TQIconSet class
+**
+** Created : 980318
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQICONSET_H
+#define TQICONSET_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqpixmap.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_ICONSET
+
+class TQIconFactory;
+class TQIconSetPrivate;
+
+// ### Remove all 'virtual' functions in TQIconSet (but not TQIconFactory) in TQt 4.0
+class TQ_EXPORT TQIconSet
+{
+public:
+ // the implementation makes assumptions about the value of these
+ enum Size { Automatic, Small, Large };
+ enum Mode { Normal, Disabled, Active };
+ enum State { On, Off };
+
+ TQIconSet();
+ TQIconSet( const TQPixmap& pixmap, Size size = Automatic );
+ TQIconSet( const TQPixmap& smallPix, const TQPixmap& largePix );
+ TQIconSet( const TQIconSet& other );
+ virtual ~TQIconSet();
+
+ void reset( const TQPixmap& pixmap, Size size );
+
+ virtual void setPixmap( const TQPixmap& pixmap, Size size,
+ Mode mode = Normal, State state = Off );
+ virtual void setPixmap( const TQString& fileName, Size size,
+ Mode mode = Normal, State state = Off );
+ TQPixmap pixmap( Size size, Mode mode, State state = Off ) const;
+ TQPixmap pixmap( Size size, bool enabled, State state = Off ) const;
+ TQPixmap pixmap() const;
+ bool isGenerated( Size size, Mode mode, State state = Off ) const;
+ void clearGenerated();
+ void installIconFactory( TQIconFactory *factory );
+
+ bool isNull() const;
+
+ void detach();
+
+ TQIconSet& operator=( const TQIconSet& other );
+
+ // static functions
+ static void setIconSize( Size which, const TQSize& size );
+ static const TQSize& iconSize( Size which );
+
+#ifndef TQ_TQDOC
+ TQ_DUMMY_COMPARISON_OPERATOR(TQIconSet)
+#endif
+
+private:
+ void normalize( Size& which, const TQSize& pixSize );
+ TQPixmap *createScaled( Size size, const TQPixmap *suppliedPix ) const;
+ TQPixmap *createDisabled( Size size, State state ) const;
+
+ TQIconSetPrivate *d;
+};
+
+class TQ_EXPORT TQIconFactory : private TQShared
+{
+public:
+ TQIconFactory();
+ virtual ~TQIconFactory();
+
+ virtual TQPixmap *createPixmap( const TQIconSet& iconSet, TQIconSet::Size size,
+ TQIconSet::Mode mode, TQIconSet::State state );
+ void setAutoDelete( bool autoDelete ) { autoDel = autoDelete; }
+ bool autoDelete() const { return autoDel; }
+
+ static TQIconFactory *defaultFactory();
+ static void installDefaultFactory( TQIconFactory *factory );
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQIconFactory( const TQIconFactory & );
+ TQIconFactory &operator=( const TQIconFactory & );
+#endif
+
+ friend class TQIconSet;
+ friend class TQIconSetPrivate;
+
+ uint autoDel : 1;
+ uint unused : 31;
+};
+
+#endif // TQT_NO_ICONSET
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqimage.cpp b/tqtinterface/qt4/src/kernel/tqimage.cpp
new file mode 100644
index 0000000..0c97e64
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqimage.cpp
@@ -0,0 +1,9526 @@
+/****************************************************************************
+**
+** Implementation of TQImage and TQImageIO classes
+**
+** Created : 950207
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <tqtglobaldefines.h>
+// Nasty, nasty horrid HACK to get access to QImage's private members
+// This is TERRIBLE and I wish there was a way around it
+// This is a good example of the new, broken & irritating Qt4 API,
+// and the corresponding loss in functionality versus Qt3.
+// See also tqrect.cpp
+#define private protected
+#include <Qt/qimage.h>
+#undef private
+
+#include "tqimage.h"
+#include "tqregexp.h"
+#include "tqfile.h"
+#include "tqdatastream.h"
+#include "tqtextstream.h"
+#include "tqbuffer.h"
+#include "tqptrlist.h"
+#include "tqasyncimageio.h"
+#include "tqpngio.h"
+#include "tqmngio.h"
+#include "tqjpegio.h"
+#include "tqmap.h"
+#include <private/tqpluginmanager_p.h>
+#include "tqimageformatinterface_p.h"
+#include "tqwmatrix.h"
+#include "tqapplication.h"
+#include "tqmime.h"
+#include "tqdragobject.h"
+#include <ctype.h>
+#include <stdlib.h>
+
+#ifdef TQ_WS_TQWS
+#include "tqgfx_qws.h"
+#endif
+
+#ifdef USE_QT4
+
+#include <Qt/qx11info_x11.h>
+
+#include "private/tqt_x11_p.h"
+#include "private/qt4_qimage_p.h"
+
+QImage::Format TQImage::formatFor(int depth, TQImage::Endian bitOrder)
+{
+ QImage::Format format;
+ if (depth == 1) {
+ format = bitOrder == TQImage::BigEndian ? QImage::Format_Mono : QImage::Format_MonoLSB;
+ } else if (depth == 8) {
+ format = QImage::Format_Indexed8;
+ } else if (depth == 32) {
+ format = QImage::Format_ARGB32;
+ } else if (depth == 24) {
+ format = QImage::Format_RGB888;
+ } else if (depth == 16) {
+ format = QImage::Format_RGB16;
+ } else {
+ qWarning("QImage: Depth %d not supported", depth);
+ format = QImage::Format_Invalid;
+ }
+ return format;
+}
+
+static QImage::Format tqformatFor(int depth, TQImage::Endian bitOrder)
+{
+ QImage::Format format;
+ if (depth == 1) {
+ format = bitOrder == TQImage::BigEndian ? QImage::Format_Mono : QImage::Format_MonoLSB;
+ } else if (depth == 8) {
+ format = QImage::Format_Indexed8;
+ } else if (depth == 32) {
+ format = QImage::Format_RGB32;
+ } else if (depth == 24) {
+ format = QImage::Format_RGB888;
+ } else if (depth == 16) {
+ format = QImage::Format_RGB16;
+ } else {
+ qWarning("QImage: Depth %d not supported", depth);
+ format = QImage::Format_Invalid;
+ }
+ return format;
+}
+
+/*!
+ Converts the depth (bpp) of the image to the given \a depth and
+ returns the converted image. The original image is not changed.
+ Returns this image if \a depth is equal to the image depth, or a
+ null image if this image cannot be converted. The \a depth
+ argument must be 1, 8 or 32. If the image needs to be modified to
+ fit in a lower-resolution result (e.g. converting from 32-bit to
+ 8-bit), use the \a flags to specify how you'd prefer this to
+ happen.
+
+ Use the convertToFormat() function instead.
+*/
+
+TQImage TQImage::convertDepth(int newdepth, Qt::ImageConversionFlags flags) const
+{
+ if (depth() == newdepth)
+ return *this;
+
+ Format format = tqformatFor(newdepth, LittleEndian);
+ return convertToFormat(format, flags);
+}
+
+#ifndef TQT_NO_IMAGEIO
+/*!
+ Returns a string that specifies the image format of the file \a
+ fileName, or 0 if the file cannot be read or if the format is not
+ recognized.
+
+ The TQImageIO documentation lists the guaranteed supported image
+ formats, or use TQImage::inputFormats() and TQImage::outputFormats()
+ to get lists that include the installed formats.
+
+ \sa load() save()
+*/
+
+const char* TQImage::imageFormat( const TQString &fileName )
+{
+ return TQImageIO::imageFormat( fileName );
+}
+#endif
+
+/*!
+ Returns true if alpha buffer mode is enabled; otherwise returns
+ false.
+
+ Use the hasAlphaChannel() function instead.
+
+*/
+bool TQImage::hasAlphaBuffer() const
+{
+ switch (format()) {
+ case Format_ARGB32:
+ case Format_ARGB32_Premultiplied:
+ case Format_ARGB8565_Premultiplied:
+ case Format_ARGB8555_Premultiplied:
+ case Format_ARGB6666_Premultiplied:
+ case Format_ARGB4444_Premultiplied:
+ return true;
+ default:
+ return false;
+ }
+}
+
+/*!
+ Enables alpha buffer mode if \a enable is true, otherwise disables
+ it. The alpha buffer is used to set a mask when a QImage is
+ translated to a QPixmap.
+
+ If a monochrome or indexed 8-bit image has alpha channels in their
+ color tables they will automatically detect that they have an
+ alpha channel, so this function is not required. To force alpha
+ channels on 32-bit images, use the convertToFormat() function.
+*/
+
+void TQImage::setAlphaBuffer(bool enable)
+{
+ if (format() == Format_Mono
+ || format() == Format_MonoLSB
+ || format() == Format_Indexed8)
+ return;
+ if (enable && (format() == Format_ARGB32 ||
+ format() == Format_ARGB32_Premultiplied ||
+ format() == Format_ARGB8565_Premultiplied ||
+ format() == Format_ARGB6666_Premultiplied ||
+ format() == Format_ARGB8555_Premultiplied ||
+ format() == Format_ARGB4444_Premultiplied))
+ {
+ return;
+ }
+ else {
+ // Emulate Ye Olde Tyme Qt3.x behaviour, where the alpha channel is always present
+ // in bits 24:31. This is to allow code that purposefully shuts down the alpha channel
+ // so that it may be initialized unhindered to function correctly under Qt4.
+ // The only side effect that I am aware of is that disabling the alpha channel will clear it out.
+ if (format() == Format_ARGB32 ||
+ format() == Format_ARGB32_Premultiplied ||
+ format() == Format_ARGB8565_Premultiplied ||
+ format() == Format_ARGB6666_Premultiplied ||
+ format() == Format_ARGB8555_Premultiplied ||
+ format() == Format_ARGB4444_Premultiplied)
+ {
+ if (!enable) {
+ // Set the alpha buffer to opaque
+ // This may be a bit slow/memory intensive! Alternative suggestions are welcome.
+ detach();
+ *this=convertToFormat(Format_RGB32);
+ detach();
+ *this=convertToFormat(Format_ARGB32);
+ }
+ }
+ // As mentioned above, we get an alpha channel whether we wanted one or not!
+ detach();
+ *this=convertToFormat(Format_ARGB32);
+ }
+}
+
+/*!
+ Returns a pointer to the scanline pointer table. This is the
+ beginning of the data block for the image.
+ Returns 0 in case of an error.
+
+ Use the bits() or scanLine() function instead.
+*/
+uchar **TQImage::jumpTable()
+{
+// if (!d)
+// return 0;
+// detach();
+//
+// // in case detach() ran out of memory..
+// if (!d)
+// return 0;
+//
+// if (!d->jumptable) {
+// d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *));
+// if (!d->jumptable)
+// return 0;
+// uchar *data = d->data;
+// int height = d->height;
+// uchar **p = d->jumptable;
+// while (height--) {
+// *p++ = data;
+// data += d->bytes_per_line;
+// }
+// }
+// return d->jumptable;
+
+ // Qt4 does not have native jumpTable support; here is an approximate replacement
+ // We essentially reconstruct the jumptable here
+ if (jumptable)
+ free(jumptable);
+ jumptable = (uchar **)malloc(height()*sizeof(uchar *));
+ if (!jumptable)
+ return 0;
+ uchar *data = scanLine(0);
+ int h = height();
+ uchar **p = jumptable;
+ while (h--) {
+ *p++ = data;
+ data += bytesPerLine();
+ }
+ return jumptable;
+}
+
+/*!
+ \overload
+*/
+const uchar * const *TQImage::jumpTable() const
+{
+// if (!d)
+// return 0;
+// if (!d->jumptable) {
+// d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *));
+// if (!d->jumptable)
+// return 0;
+// uchar *data = d->data;
+// int height = d->height;
+// uchar **p = d->jumptable;
+// while (height--) {
+// *p++ = data;
+// data += d->bytes_per_line;
+// }
+// }
+// return d->jumptable;
+
+
+ // Qt4 does not have native jumpTable support; here is an approximate replacement
+ // We essentially reconstruct the jumptable here
+ if (jumptable)
+ free(jumptable);
+ jumptable = (uchar **)malloc(height()*sizeof(uchar *));
+ if (!jumptable)
+ return 0;
+ const uchar *data = scanLine(0);
+ int h = height();
+ uchar **p = jumptable;
+ while (h--) {
+ *p++ = const_cast<uchar*>(data);
+ data += bytesPerLine();
+ }
+ return jumptable;
+}
+
+/*!
+ \internal
+ Deallocates the image data and sets the bits pointer to 0.
+*/
+
+void TQImage::freeBits()
+{
+// if ( data->bits ) { // dealloc image bits
+// free( data->bits );
+// data->bits = 0;
+// }
+
+ // [FIXME]
+ printf("[WARNING] TQImage::freeBits() unimplemented\n\r");
+}
+
+void TQImage::reinit()
+{
+// data->w = data->h = data->d = data->ncols = 0;
+// data->nbytes = 0;
+// data->ctbl = 0;
+// data->bits = 0;
+// data->bitordr = TQImage::IgnoreEndian;
+// data->alpha = FALSE;
+// #ifndef TQT_NO_IMAGE_TEXT
+// data->misc = 0;
+// #endif
+// data->dpmx = 0;
+// data->dpmy = 0;
+// data->offset = TQPoint(0,0);
+
+ // [FIXME]
+ printf("[WARNING] TQImage::reinit() unimplemented\n\r");
+}
+
+/*!
+ \fn bool TQImage::create(int width, int height, int depth, int numColors, Endian bitOrder)
+
+ Sets the image \a width, \a height, \a depth, its number of colors
+ (in \a numColors), and bit order. Returns true if successful, or
+ false if the parameters are incorrect or if memory cannot be
+ allocated.
+
+ The \a width and \a height is limited to 32767. \a depth must be
+ 1, 8, or 32. If \a depth is 1, \a bitOrder must be set to
+ either QImage::LittleEndian or QImage::BigEndian. For other depths
+ \a bitOrder must be QImage::IgnoreEndian.
+
+ This function allocates a color table and a buffer for the image
+ data. The image data is not initialized. The image buffer is
+ allocated as a single block that consists of a table of scanLine()
+ pointers (jumpTable()) and the image data (bits()).
+
+ Use a QImage constructor instead.
+*/
+bool TQImage::create(int width, int height, int depth, int numColors, Endian bitOrder)
+{
+ if (d && !d->ref.deref())
+ delete d;
+ d = QImageData::create(QSize(width, height), formatFor(depth, bitOrder), numColors);
+ return true;
+}
+
+/*!
+ \fn bool TQImage::create(const QSize& size, int depth, int numColors, Endian bitOrder)
+ \overload
+
+ The width and height are specified in the \a size argument.
+
+ Use a QImage constructor instead.
+*/
+bool TQImage::create(const TQSize& size, int depth, int numColors, TQImage::Endian bitOrder)
+{
+ if (d && !d->ref.deref())
+ delete d;
+ d = QImageData::create(size, formatFor(depth, bitOrder), numColors);
+ return true;
+}
+
+// [FIXME] [CRITICAL] [MEMLEAK] Memory leak!
+// BUT any attempt to define this destructor will cause a glibc invalid pointer crash
+// [FIXME] [CRITICAL] [MEMLEAK]
+// TQImage::~TQImage()
+// {
+// if (jumptable)
+// free(jumptable);
+// jumptable = 0;
+// }
+
+#if 0
+/*!
+ Sets the image IO status to \a status. A non-zero value indicates
+ an error, whereas 0 means that the IO operation was successful.
+
+ \sa status()
+*/
+
+void TQImageIO::setqStatus( int status )
+{
+ static_cast<TQIODevice*>(QImageReader::device())->setqStatus(status);
+ static_cast<TQIODevice*>(QImageWriter::device())->setqStatus(status);
+}
+#else
+
+/*!
+ Returns a list of image formats that are supported for image
+ input.
+
+ \sa outputFormats() inputFormatList() TQImageIO
+*/
+TQStrList TQImage::inputFormats()
+{
+ return TQImageIO::inputFormats();
+}
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Returns a list of image formats that are supported for image
+ input.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myImage.inputFormatList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa outputFormatList() inputFormats() TQImageIO
+*/
+TQStringList TQImage::inputFormatList()
+{
+ return TQStringList::fromStrList(TQImageIO::inputFormats());
+}
+
+
+/*!
+ Returns a list of image formats that are supported for image
+ output.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myImage.outputFormatList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa inputFormatList() outputFormats() TQImageIO
+*/
+TQStringList TQImage::outputFormatList()
+{
+ return TQStringList::fromStrList(TQImageIO::outputFormats());
+}
+#endif //TQT_NO_STRINGLIST
+
+/*!
+ Returns a list of image formats that are supported for image
+ output.
+
+ \sa inputFormats() outputFormatList() TQImageIO
+*/
+TQStrList TQImage::outputFormats()
+{
+ return TQImageIO::outputFormats();
+}
+
+
+/*!
+ Loads an image from the file \a fileName. Returns TRUE if the
+ image was successfully loaded; otherwise returns FALSE.
+
+ If \a format is specified, the loader attempts to read the image
+ using the specified format. If \a format is not specified (which
+ is the default), the loader reads a few bytes from the header to
+ guess the file format.
+
+ The TQImageIO documentation lists the supported image formats and
+ explains how to add extra formats.
+
+ \sa loadFromData() save() imageFormat() TQPixmap::load() TQImageIO
+*/
+
+bool TQImage::load( const TQString &fileName, const char* format )
+{
+ TQImageIO io( fileName, format );
+ bool result = io.read();
+ if ( result )
+ operator=( io.image() );
+ return result;
+}
+
+/*!
+ Loads an image from the first \a len bytes of binary data in \a
+ buf. Returns TRUE if the image was successfully loaded; otherwise
+ returns FALSE.
+
+ If \a format is specified, the loader attempts to read the image
+ using the specified format. If \a format is not specified (which
+ is the default), the loader reads a few bytes from the header to
+ guess the file format.
+
+ The TQImageIO documentation lists the supported image formats and
+ explains how to add extra formats.
+
+ \sa load() save() imageFormat() TQPixmap::loadFromData() TQImageIO
+*/
+
+bool TQImage::loadFromData( const uchar *buf, uint len, const char *format )
+{
+ TQByteArray a;
+ a.setRawData( (char *)buf, len );
+ TQBuffer b( a );
+ b.open( IO_ReadOnly );
+ TQImageIO io( &b, format );
+ bool result = io.read();
+ b.close();
+ a.resetRawData( (char *)buf, len );
+ if ( result )
+ operator=( io.image() );
+ return result;
+}
+
+/*!
+ \overload
+
+ Loads an image from the TQByteArray \a buf.
+*/
+bool TQImage::loadFromData( TQByteArray buf, const char *format )
+{
+ return loadFromData( (const uchar *)(buf.data()), buf.size(), format );
+}
+
+/*!
+ Saves the image to the file \a fileName, using the image file
+ format \a format and a quality factor of \a quality. \a quality
+ must be in the range 0..100 or -1. Specify 0 to obtain small
+ compressed files, 100 for large uncompressed files, and -1 (the
+ default) to use the default settings.
+
+ Returns TRUE if the image was successfully saved; otherwise
+ returns FALSE.
+
+ \sa load() loadFromData() imageFormat() TQPixmap::save() TQImageIO
+*/
+
+bool TQImage::save( const TQString &fileName, const char* format, int quality ) const
+{
+ if ( isNull() )
+ return FALSE; // nothing to save
+ TQImageIO io( fileName, format );
+ return doImageIO( &io, quality );
+}
+
+/*!
+ \overload
+
+ This function writes a TQImage to the TQIODevice, \a tqdevice. This
+ can be used, for example, to save an image directly into a
+ TQByteArray:
+ \code
+ TQImage image;
+ TQByteArray ba;
+ TQBuffer buffer( ba );
+ buffer.open( IO_WriteOnly );
+ image.save( &buffer, "PNG" ); // writes image into ba in PNG format
+ \endcode
+*/
+
+bool TQImage::save( QIODevice* tqdevice, const char* format, int quality ) const
+{
+ if ( isNull() )
+ return FALSE; // nothing to save
+ TQImageIO io( tqdevice, format );
+ return doImageIO( &io, quality );
+}
+
+/* \internal
+*/
+
+bool TQImage::doImageIO( TQImageIO* io, int quality ) const
+{
+ if ( !io )
+ return FALSE;
+ io->setImage( *this );
+#if defined(TQT_CHECK_RANGE)
+ if ( quality > 100 || quality < -1 )
+ qWarning( "TQPixmap::save: quality out of range [-1,100]" );
+#endif
+ if ( quality >= 0 )
+ io->setQuality( TQMIN(quality,100) );
+ return io->write();
+}
+
+/*****************************************************************************
+ Standard image io handlers (defined below)
+ *****************************************************************************/
+
+// standard image io handlers (defined below)
+#ifndef TQT_NO_IMAGEIO_BMP
+static void read_bmp_image( TQImageIO * );
+static void write_bmp_image( TQImageIO * );
+#endif
+#ifndef TQT_NO_IMAGEIO_PPM
+static void read_pbm_image( TQImageIO * );
+static void write_pbm_image( TQImageIO * );
+#endif
+#ifndef TQT_NO_IMAGEIO_XBM
+static void read_xbm_image( TQImageIO * );
+static void write_xbm_image( TQImageIO * );
+#endif
+#ifndef TQT_NO_IMAGEIO_XPM
+static void read_xpm_image( TQImageIO * );
+static void write_xpm_image( TQImageIO * );
+#endif
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+static void read_async_image( TQImageIO * ); // Not in table of handlers
+#endif
+
+/*****************************************************************************
+ Misc. utility functions
+ *****************************************************************************/
+#if !defined(TQT_NO_IMAGEIO_XPM) || !defined(TQT_NO_IMAGEIO_XBM)
+static TQString fbname( const TQString &fileName ) // get file basename (sort of)
+{
+ TQString s = fileName;
+ if ( !s.isEmpty() ) {
+ int i;
+ if ( (i = s.tqfindRev('/')) >= 0 )
+ s = s.mid( i );
+ if ( (i = s.tqfindRev('\\')) >= 0 )
+ s = s.mid( i );
+ TQRegExp r( TQString::tqfromLatin1("[a-zA-Z][a-zA-Z0-9_]*") );
+ int p = r.search( s );
+ if ( p == -1 )
+ s.truncate( 0 );
+ else
+ s = s.mid( p, r.matchedLength() );
+ }
+ if ( s.isEmpty() )
+ s = TQString::tqfromLatin1( "dummy" );
+ return s;
+}
+#endif
+
+#ifndef TQT_NO_IMAGEIO_BMP
+static void swapPixel01( TQImage *image ) // 1-bpp: swap 0 and 1 pixels
+{
+ int i;
+ if ( image->depth() == 1 && image->numColors() == 2 ) {
+ register uint *p = (uint *)image->bits();
+ int nbytes = image->numBytes();
+ for ( i=0; i<nbytes/4; i++ ) {
+ *p = ~*p;
+ p++;
+ }
+ uchar *p2 = (uchar *)p;
+ for ( i=0; i<(nbytes&3); i++ ) {
+ *p2 = ~*p2;
+ p2++;
+ }
+ TQRgb t = image->color(0); // swap color 0 and 1
+ image->setColor( 0, image->color(1) );
+ image->setColor( 1, t );
+ }
+}
+#endif
+
+
+/*****************************************************************************
+ TQImageIO member functions
+ *****************************************************************************/
+
+/*!
+ \class TQImageIO tqimage.h
+
+ \brief The TQImageIO class tqcontains parameters for loading and
+ saving images.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup io
+
+ TQImageIO tqcontains a TQIODevice object that is used for image data
+ I/O. The programmer can install new image file formats in addition
+ to those that TQt provides.
+
+ TQt currently supports the following image file formats: PNG, BMP,
+ XBM, XPM and PNM. It may also support JPEG, MNG and GIF, if
+ specially configured during compilation. The different PNM formats
+ are: PBM (P1 or P4), PGM (P2 or P5), and PPM (P3 or P6).
+
+ You don't normally need to use this class; TQPixmap::load(),
+ TQPixmap::save(), and TQImage contain sufficient functionality.
+
+ For image files that contain sequences of images, only the first
+ is read. See TQMovie for loading multiple images.
+
+ PBM, PGM, and PPM format \e output is always in the more condensed
+ raw format. PPM and PGM files with more than 256 levels of
+ intensity are scaled down when reading.
+
+ \warning If you are in a country which recognizes software patents
+ and in which Unisys holds a patent on LZW compression and/or
+ decompression and you want to use GIF, Unisys may require you to
+ license the technology. Such countries include Canada, Japan, the
+ USA, France, Germany, Italy and the UK. It is believed that as of
+ this writing (March 15, 2011) all GIF software patents have expired.
+ However, this does not constitute legal advice! Check with a lawyer
+ if you want to know if the patents have expired in your country.
+
+ GIF support may be removed completely in a future version of TQt.
+ We strongly recommend using the lossless PNG format.
+
+ \sa TQImage TQPixmap TQFile TQMovie
+*/
+
+#ifndef TQT_NO_IMAGEIO
+struct TQImageIOData
+{
+ const char *parameters;
+ int quality;
+ float gamma;
+};
+
+/*!
+ Constructs a TQImageIO object with all parameters set to zero.
+*/
+
+TQImageIO::TQImageIO()
+{
+ init();
+}
+
+/*!
+ Constructs a TQImageIO object with the I/O tqdevice \a ioDevice and a
+ \a format tag.
+*/
+
+TQImageIO::TQImageIO( QIODevice *ioDevice, const char *format )
+ : frmt(format)
+{
+ init();
+ iodev = TQT_TQIODEVICE(ioDevice);
+}
+
+/*!
+ Constructs a TQImageIO object with the file name \a fileName and a
+ \a format tag.
+*/
+
+TQImageIO::TQImageIO( const TQString &fileName, const char* format )
+ : frmt(format), fname(fileName)
+{
+ init();
+}
+
+/*!
+ Contains initialization common to all TQImageIO constructors.
+*/
+
+void TQImageIO::init()
+{
+ d = new TQImageIOData();
+ d->parameters = 0;
+ d->quality = -1; // default quality of the current format
+ d->gamma=0.0f;
+ iostat = 0;
+ iodev = 0;
+}
+
+/*!
+ Destroys the object and all related data.
+*/
+
+TQImageIO::~TQImageIO()
+{
+ if ( d->parameters )
+ delete [] (char*)d->parameters;
+ delete d;
+}
+
+
+/*****************************************************************************
+ TQImageIO image handler functions
+ *****************************************************************************/
+
+class TQImageHandler
+{
+public:
+ TQImageHandler( const char *f, const char *h, const TQCString& fl,
+ image_io_handler r, image_io_handler w );
+ TQCString format; // image format
+ TQRegExp header; // image header pattern
+ enum TMode { Untranslated=0, TranslateIn, TranslateInOut } text_mode;
+ image_io_handler read_image; // image read function
+ image_io_handler write_image; // image write function
+ bool obsolete; // support not "published"
+};
+
+TQImageHandler::TQImageHandler( const char *f, const char *h, const TQCString& fl,
+ image_io_handler r, image_io_handler w )
+ : format(f), header(TQString::tqfromLatin1(h))
+{
+ text_mode = Untranslated;
+ if ( fl.tqcontains('t') )
+ text_mode = TranslateIn;
+ else if ( fl.tqcontains('T') )
+ text_mode = TranslateInOut;
+ obsolete = fl.tqcontains('O');
+ read_image = r;
+ write_image = w;
+}
+
+typedef TQPtrList<TQImageHandler> TQIHList;// list of image handlers
+static TQIHList *imageHandlers = 0;
+#ifndef TQT_NO_COMPONENT
+static TQPluginManager<TQImageFormatInterface> *plugin_manager = 0;
+#else
+static void *plugin_manager = 0;
+#endif
+
+void qt_init_image_plugins()
+{
+#ifndef TQT_NO_COMPONENT
+ if ( plugin_manager )
+ return;
+
+ plugin_manager = new TQPluginManager<TQImageFormatInterface>( IID_TQImageFormat, TQApplication::libraryPaths(), "/imageformats" );
+
+ TQStringList features = plugin_manager->featureList();
+ TQStringList::Iterator it = features.begin();
+ while ( it != features.end() ) {
+ TQString str = *it;
+ ++it;
+ TQInterfacePtr<TQImageFormatInterface> iface;
+ plugin_manager->queryInterface( str, &iface );
+ if ( iface )
+ iface->installIOHandler( str );
+ }
+#endif
+}
+
+static void cleanup()
+{
+ // make sure that image handlers are deleted before plugin manager
+ delete imageHandlers;
+ imageHandlers = 0;
+#ifndef TQT_NO_COMPONENT
+ delete plugin_manager;
+ plugin_manager = 0;
+#endif
+}
+
+void qt_init_image_handlers() // initialize image handlers
+{
+ if ( !imageHandlers ) {
+ imageHandlers = new TQIHList;
+ TQ_CHECK_PTR( imageHandlers );
+ imageHandlers->setAutoDelete( TRUE );
+ qAddPostRoutine( cleanup );
+#ifndef TQT_NO_IMAGEIO_BMP
+ TQImageIO::defineIOHandler( "BMP", "^BM", 0,
+ read_bmp_image, write_bmp_image );
+#endif
+#ifndef TQT_NO_IMAGEIO_PPM
+ TQImageIO::defineIOHandler( "PBM", "^P1", "t",
+ read_pbm_image, write_pbm_image );
+ TQImageIO::defineIOHandler( "PBMRAW", "^P4", "O",
+ read_pbm_image, write_pbm_image );
+ TQImageIO::defineIOHandler( "PGM", "^P2", "t",
+ read_pbm_image, write_pbm_image );
+ TQImageIO::defineIOHandler( "PGMRAW", "^P5", "O",
+ read_pbm_image, write_pbm_image );
+ TQImageIO::defineIOHandler( "PPM", "^P3", "t",
+ read_pbm_image, write_pbm_image );
+ TQImageIO::defineIOHandler( "PPMRAW", "^P6", "O",
+ read_pbm_image, write_pbm_image );
+#endif
+#ifndef TQT_NO_IMAGEIO_XBM
+ TQImageIO::defineIOHandler( "XBM", "^((/\\*(?!.XPM.\\*/))|#define)", "T",
+ read_xbm_image, write_xbm_image );
+#endif
+#ifndef TQT_NO_IMAGEIO_XPM
+ TQImageIO::defineIOHandler( "XPM", "/\\*.XPM.\\*/", "T",
+ read_xpm_image, write_xpm_image );
+#endif
+#ifndef TQT_NO_IMAGEIO_MNG
+ qInitMngIO();
+#endif
+#ifndef TQT_NO_IMAGEIO_PNG
+ qInitPngIO();
+#endif
+#ifndef TQT_NO_IMAGEIO_JPEG
+ qInitJpegIO();
+#endif
+ }
+}
+
+static TQImageHandler *get_image_handler( const char *format )
+{ // get pointer to handler
+ qt_init_image_handlers();
+ qt_init_image_plugins();
+ register TQImageHandler *p = imageHandlers->first();
+ while ( p ) { // traverse list
+ if ( p->format == format )
+ return p;
+ p = imageHandlers->next();
+ }
+ return 0; // no such handler
+}
+
+
+/*!
+ Defines an image I/O handler for the image format called \a
+ format, which is recognized using the \link tqregexp.html#details
+ regular expression\endlink \a header, read using \a readImage and
+ written using \a writeImage.
+
+ \a flags is a string of single-character flags for this format.
+ The only flag defined currently is T (upper case), so the only
+ legal value for \a flags are "T" and the empty string. The "T"
+ flag means that the image file is a text file, and TQt should treat
+ all newline conventions as equivalent. (XPM files and some PPM
+ files are text files for example.)
+
+ \a format is used to select a handler to write a TQImage; \a header
+ is used to select a handler to read an image file.
+
+ If \a readImage is a null pointer, the TQImageIO will not be able
+ to read images in \a format. If \a writeImage is a null pointer,
+ the TQImageIO will not be able to write images in \a format. If
+ both are null, the TQImageIO object is valid but useless.
+
+ Example:
+ \code
+ void readGIF( TQImageIO *image )
+ {
+ // read the image using the image->ioDevice()
+ }
+
+ void writeGIF( TQImageIO *image )
+ {
+ // write the image using the image->ioDevice()
+ }
+
+ // add the GIF image handler
+
+ TQImageIO::defineIOHandler( "GIF",
+ "^GIF[0-9][0-9][a-z]",
+ 0,
+ readGIF,
+ writeGIF );
+ \endcode
+
+ Before the regex test, all the 0 bytes in the file header are
+ converted to 1 bytes. This is done because when TQt was
+ ASCII-based, TQRegExp could not handle 0 bytes in strings.
+
+ The regexp is only applied on the first 14 bytes of the file.
+
+ Note that TQt assumes that there is only one handler per format; if
+ two handlers support the same format, TQt will choose one
+ arbitrarily. It is not possible to have one handler support
+ reading, and another support writing.
+*/
+
+void TQImageIO::defineIOHandler( const char *format,
+ const char *header,
+ const char *flags,
+ image_io_handler readImage,
+ image_io_handler writeImage )
+{
+ qt_init_image_handlers();
+ TQImageHandler *p;
+ p = new TQImageHandler( format, header, flags,
+ readImage, writeImage );
+ TQ_CHECK_PTR( p );
+ imageHandlers->insert( 0, p );
+}
+
+
+/*****************************************************************************
+ TQImageIO normal member functions
+ *****************************************************************************/
+
+/*!
+ \fn const TQImage &TQImageIO::image() const
+
+ Returns the image currently set.
+
+ \sa setImage()
+*/
+
+/*!
+ \fn int TQImageIO::status() const
+
+ Returns the image's IO status. A non-zero value indicates an
+ error, whereas 0 means that the IO operation was successful.
+
+ \sa setqStatus()
+*/
+
+/*!
+ \fn const char *TQImageIO::format() const
+
+ Returns the image format string or 0 if no format has been
+ explicitly set.
+*/
+
+/*!
+ \fn TQIODevice *TQImageIO::ioDevice() const
+
+ Returns the IO tqdevice currently set.
+
+ \sa setIODevice()
+*/
+
+/*!
+ \fn TQString TQImageIO::fileName() const
+
+ Returns the file name currently set.
+
+ \sa setFileName()
+*/
+
+/*!
+ \fn TQString TQImageIO::description() const
+
+ Returns the image description string.
+
+ \sa setDescription()
+*/
+
+
+/*!
+ Sets the image to \a image.
+
+ \sa image()
+*/
+
+void TQImageIO::setImage( const QImage &image )
+{
+ im = image;
+}
+
+/*!
+ Sets the image IO status to \a status. A non-zero value indicates
+ an error, whereas 0 means that the IO operation was successful.
+
+ \sa status()
+*/
+
+void TQImageIO::setqStatus( int status )
+{
+ iostat = status;
+}
+
+/*!
+ Sets the image format to \a format for the image to be read or
+ written.
+
+ It is necessary to specify a format before writing an image, but
+ it is not necessary to specify a format before reading an image.
+
+ If no format has been set, TQt guesses the image format before
+ reading it. If a format is set the image will only be read if it
+ has that format.
+
+ \sa read() write() format()
+*/
+
+void TQImageIO::setFormat( const char *format )
+{
+ frmt = format;
+}
+
+/*!
+ Sets the IO tqdevice to be used for reading or writing an image.
+
+ Setting the IO tqdevice allows images to be read/written to any
+ block-oriented TQIODevice.
+
+ If \a ioDevice is not null, this IO tqdevice will override file name
+ settings.
+
+ \sa setFileName()
+*/
+
+void TQImageIO::setIODevice( TQIODevice *ioDevice )
+{
+ iodev = ioDevice;
+}
+
+/*!
+ Sets the name of the file to read or write an image from to \a
+ fileName.
+
+ \sa setIODevice()
+*/
+
+void TQImageIO::setFileName( const TQString &fileName )
+{
+ fname = fileName;
+}
+
+/*!
+ Returns the quality of the written image, related to the
+ compression ratio.
+
+ \sa setQuality() TQImage::save()
+*/
+
+int TQImageIO::quality() const
+{
+ return d->quality;
+}
+
+/*!
+ Sets the quality of the written image to \a q, related to the
+ compression ratio.
+
+ \a q must be in the range -1..100. Specify 0 to obtain small
+ compressed files, 100 for large uncompressed files. (-1 signifies
+ the default compression.)
+
+ \sa quality() TQImage::save()
+*/
+
+void TQImageIO::setQuality( int q )
+{
+ d->quality = q;
+}
+
+/*!
+ Returns the image's parameters string.
+
+ \sa setParameters()
+*/
+
+const char *TQImageIO::parameters() const
+{
+ return d->parameters;
+}
+
+/*!
+ Sets the image's parameter string to \a parameters. This is for
+ image handlers that require special parameters.
+
+ Although the current image formats supported by TQt ignore the
+ parameters string, it may be used in future extensions or by
+ contributions (for example, JPEG).
+
+ \sa parameters()
+*/
+
+void TQImageIO::setParameters( const char *parameters )
+{
+ if ( d && d->parameters )
+ delete [] (char*)d->parameters;
+ d->parameters = qstrdup( parameters );
+}
+
+/*!
+ Sets the gamma value at which the image will be viewed to \a
+ gamma. If the image format stores a gamma value for which the
+ image is intended to be used, then this setting will be used to
+ modify the image. Setting to 0.0 will disable gamma correction
+ (i.e. any specification in the file will be ignored).
+
+ The default value is 0.0.
+
+ \sa gamma()
+*/
+void TQImageIO::setGamma( float gamma )
+{
+ d->gamma=gamma;
+}
+
+/*!
+ Returns the gamma value at which the image will be viewed.
+
+ \sa setGamma()
+*/
+float TQImageIO::gamma() const
+{
+ return d->gamma;
+}
+
+/*!
+ Sets the image description string for image handlers that support
+ image descriptions to \a description.
+
+ Currently, no image format supported by TQt uses the description
+ string.
+*/
+
+void TQImageIO::setDescription( const TQString &description )
+{
+ descr = description;
+}
+
+
+/*!
+ Returns a string that specifies the image format of the file \a
+ fileName, or null if the file cannot be read or if the format is
+ not recognized.
+*/
+
+const char* TQImageIO::imageFormat( const TQString &fileName )
+{
+ TQFile file( fileName );
+ if ( !file.open(IO_ReadOnly) )
+ return 0;
+ const char* format = imageFormat( TQT_TQIODEVICE(&file) );
+ file.close();
+ return format;
+}
+
+/*!
+ \overload
+
+ Returns a string that specifies the image format of the image read
+ from IO tqdevice \a d, or 0 if the tqdevice cannot be read or if the
+ format is not recognized.
+
+ Make sure that \a d is at the right position in the tqdevice (for
+ example, at the beginning of the file).
+
+ \sa TQIODevice::at()
+*/
+
+const char *TQImageIO::imageFormat( TQIODevice *d )
+{
+ // if you change this change the documentation for defineIOHandler()
+ const int buflen = 14;
+
+ char buf[buflen];
+ char buf2[buflen];
+ qt_init_image_handlers();
+ qt_init_image_plugins();
+ int pos = d->at(); // save position
+ int rdlen = d->readBlock( buf, buflen ); // read a few bytes
+
+ if ( rdlen != buflen )
+ return 0;
+
+ memcpy( buf2, buf, buflen );
+
+ const char* format = 0;
+ for ( int n = 0; n < rdlen; n++ )
+ if ( buf[n] == '\0' )
+ buf[n] = '\001';
+ if ( d->status() == IO_Ok && rdlen > 0 ) {
+ buf[rdlen - 1] = '\0';
+ TQString bufStr = TQString::tqfromLatin1(buf);
+ TQImageHandler *p = imageHandlers->first();
+ int bestMatch = -1;
+ while ( p ) {
+ if ( p->read_image && p->header.search(bufStr) != -1 ) {
+ // try match with header if a read function is available
+ if (p->header.matchedLength() > bestMatch) {
+ // keep looking for best match
+ format = p->format;
+ bestMatch = p->header.matchedLength();
+ }
+ }
+ p = imageHandlers->next();
+ }
+ }
+ d->at( pos ); // restore position
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+ if ( !format )
+ format = TQImageDecoder::formatName( (uchar*)buf2, rdlen );
+#endif
+
+ return format;
+}
+
+/*!
+ Returns a sorted list of image formats that are supported for
+ image input.
+*/
+TQStrList TQImageIO::inputFormats()
+{
+ TQStrList result;
+
+ qt_init_image_handlers();
+ qt_init_image_plugins();
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+ // Include asynchronous loaders first.
+ result = TQImageDecoder::inputFormats();
+#endif
+
+ TQImageHandler *p = imageHandlers->first();
+ while ( p ) {
+ if ( p->read_image
+ && !p->obsolete
+ && !result.tqcontains(p->format) )
+ {
+ result.inSort(p->format);
+ }
+ p = imageHandlers->next();
+ }
+
+ return result;
+}
+
+/*!
+ Returns a sorted list of image formats that are supported for
+ image output.
+*/
+TQStrList TQImageIO::outputFormats()
+{
+ TQStrList result;
+
+ qt_init_image_handlers();
+ qt_init_image_plugins();
+
+ // Include asynchronous writers (!) first.
+ // (None)
+
+ TQImageHandler *p = imageHandlers->first();
+ while ( p ) {
+ if ( p->write_image
+ && !p->obsolete
+ && !result.tqcontains(p->format) )
+ {
+ result.inSort(p->format);
+ }
+ p = imageHandlers->next();
+ }
+
+ return result;
+}
+
+
+
+/*!
+ Reads an image into memory and returns TRUE if the image was
+ successfully read; otherwise returns FALSE.
+
+ Before reading an image you must set an IO tqdevice or a file name.
+ If both an IO tqdevice and a file name have been set, the IO tqdevice
+ will be used.
+
+ Setting the image file format string is optional.
+
+ Note that this function does \e not set the \link format()
+ format\endlink used to read the image. If you need that
+ information, use the imageFormat() static functions.
+
+ Example:
+
+ \code
+ TQImageIO iio;
+ TQPixmap pixmap;
+ iio.setFileName( "vegeburger.bmp" );
+ if ( image.read() ) // ok
+ pixmap = iio.image(); // convert to pixmap
+ \endcode
+
+ \sa setIODevice() setFileName() setFormat() write() TQPixmap::load()
+*/
+
+bool TQImageIO::read()
+{
+ TQFile file;
+ const char *image_format;
+ TQImageHandler *h;
+
+ if ( iodev ) { // read from io tqdevice
+ // ok, already open
+ } else if ( !fname.isEmpty() ) { // read from file
+ file.setName( fname );
+ if ( !file.open(IO_ReadOnly) )
+ return FALSE; // cannot open file
+ iodev = TQT_TQIODEVICE(&file);
+ } else { // no file name or io tqdevice
+ return FALSE;
+ }
+ if (frmt.isEmpty()) {
+ // Try to guess format
+ image_format = imageFormat( iodev ); // get image format
+ if ( !image_format ) {
+ if ( file.isOpen() ) { // unknown format
+ file.close();
+ iodev = 0;
+ }
+ return FALSE;
+ }
+ } else {
+ image_format = frmt;
+ }
+
+ h = get_image_handler( image_format );
+ if ( file.isOpen() ) {
+#if !defined(TQ_OS_UNIX)
+ if ( h && h->text_mode ) { // reopen in translated mode
+ file.close();
+ file.open( IO_ReadOnly | IO_Translate );
+ }
+ else
+#endif
+ file.at( 0 ); // position to start
+ }
+ iostat = 1; // assume error
+
+ if ( h && h->read_image ) {
+ (*h->read_image)( this );
+ }
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+ else {
+ // Format name, but no handler - must be an asychronous reader
+ read_async_image( this );
+ }
+#endif
+
+ if ( file.isOpen() ) { // image was read using file
+ file.close();
+ iodev = 0;
+ }
+ return iostat == 0; // image successfully read?
+}
+
+
+/*!
+ Writes an image to an IO tqdevice and returns TRUE if the image was
+ successfully written; otherwise returns FALSE.
+
+ Before writing an image you must set an IO tqdevice or a file name.
+ If both an IO tqdevice and a file name have been set, the IO tqdevice
+ will be used.
+
+ The image will be written using the specified image format.
+
+ Example:
+ \code
+ TQImageIO iio;
+ TQImage im;
+ im = pixmap; // convert to image
+ iio.setImage( im );
+ iio.setFileName( "vegeburger.bmp" );
+ iio.setFormat( "BMP" );
+ if ( iio.write() )
+ // returned TRUE if written successfully
+ \endcode
+
+ \sa setIODevice() setFileName() setFormat() read() TQPixmap::save()
+*/
+
+bool TQImageIO::write()
+{
+ if ( frmt.isEmpty() )
+ return FALSE;
+ TQImageHandler *h = get_image_handler( frmt );
+ if ( !h && !plugin_manager) {
+ qt_init_image_plugins();
+ h = get_image_handler( frmt );
+ }
+ if ( !h || !h->write_image ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImageIO::write: No such image format handler: %s",
+ format() );
+#endif
+ return FALSE;
+ }
+ TQFile file;
+ if ( !iodev && !fname.isEmpty() ) {
+ file.setName( fname );
+ bool translate = h->text_mode==TQImageHandler::TranslateInOut;
+ int fmode = translate ? IO_WriteOnly|IO_Translate : IO_WriteOnly;
+ if ( !file.open(fmode) ) // couldn't create file
+ return FALSE;
+ iodev = TQT_TQIODEVICE(&file);
+ }
+ iostat = 1;
+ (*h->write_image)( this );
+ if ( file.isOpen() ) { // image was written using file
+ file.close();
+ iodev = 0;
+ }
+ return iostat == 0; // image successfully written?
+}
+
+#ifndef TQT_NO_IMAGEIO_BMP
+
+/*****************************************************************************
+ BMP (DIB) image read/write functions
+ *****************************************************************************/
+
+const int BMP_FILEHDR_SIZE = 14; // size of BMP_FILEHDR data
+
+struct BMP_FILEHDR { // BMP file header
+ char bfType[2]; // "BM"
+ TQ_INT32 bfSize; // size of file
+ TQ_INT16 bfReserved1;
+ TQ_INT16 bfReserved2;
+ TQ_INT32 bfOffBits; // pointer to the pixmap bits
+};
+
+TQDataStream &operator>>( TQDataStream &s, BMP_FILEHDR &bf )
+{ // read file header
+ s.readRawBytes( bf.bfType, 2 );
+ s >> bf.bfSize >> bf.bfReserved1 >> bf.bfReserved2 >> bf.bfOffBits;
+ return s;
+}
+
+TQDataStream &operator<<( TQDataStream &s, const BMP_FILEHDR &bf )
+{ // write file header
+ s.writeRawBytes( bf.bfType, 2 );
+ s << bf.bfSize << bf.bfReserved1 << bf.bfReserved2 << bf.bfOffBits;
+ return s;
+}
+
+
+const int BMP_OLD = 12; // old Windows/OS2 BMP size
+const int BMP_WIN = 40; // new Windows BMP size
+const int BMP_OS2 = 64; // new OS/2 BMP size
+
+const int BMP_RGB = 0; // no compression
+const int BMP_RLE8 = 1; // run-length encoded, 8 bits
+const int BMP_RLE4 = 2; // run-length encoded, 4 bits
+const int BMP_BITFIELDS = 3; // RGB values encoded in data as bit-fields
+
+struct BMP_INFOHDR { // BMP information header
+ TQ_INT32 biSize; // size of this struct
+ TQ_INT32 biWidth; // pixmap width
+ TQ_INT32 biHeight; // pixmap height
+ TQ_INT16 biPlanes; // should be 1
+ TQ_INT16 biBitCount; // number of bits per pixel
+ TQ_INT32 biCompression; // compression method
+ TQ_INT32 biSizeImage; // size of image
+ TQ_INT32 biXPelsPerMeter; // horizontal resolution
+ TQ_INT32 biYPelsPerMeter; // vertical resolution
+ TQ_INT32 biClrUsed; // number of colors used
+ TQ_INT32 biClrImportant; // number of important colors
+};
+
+
+TQDataStream &operator>>( TQDataStream &s, BMP_INFOHDR &bi )
+{
+ s >> bi.biSize;
+ if ( bi.biSize == BMP_WIN || bi.biSize == BMP_OS2 ) {
+ s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount;
+ s >> bi.biCompression >> bi.biSizeImage;
+ s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter;
+ s >> bi.biClrUsed >> bi.biClrImportant;
+ }
+ else { // probably old Windows format
+ TQ_INT16 w, h;
+ s >> w >> h >> bi.biPlanes >> bi.biBitCount;
+ bi.biWidth = w;
+ bi.biHeight = h;
+ bi.biCompression = BMP_RGB; // no compression
+ bi.biSizeImage = 0;
+ bi.biXPelsPerMeter = bi.biYPelsPerMeter = 0;
+ bi.biClrUsed = bi.biClrImportant = 0;
+ }
+ return s;
+}
+
+TQDataStream &operator<<( TQDataStream &s, const BMP_INFOHDR &bi )
+{
+ s << bi.biSize;
+ s << bi.biWidth << bi.biHeight;
+ s << bi.biPlanes;
+ s << bi.biBitCount;
+ s << bi.biCompression;
+ s << bi.biSizeImage;
+ s << bi.biXPelsPerMeter << bi.biYPelsPerMeter;
+ s << bi.biClrUsed << bi.biClrImportant;
+ return s;
+}
+
+static
+int calc_shift(int tqmask)
+{
+ int result = 0;
+ while (!(tqmask & 1)) {
+ result++;
+ tqmask >>= 1;
+ }
+ return result;
+}
+
+static
+bool read_dib( TQDataStream& s, int offset, int startpos, TQImage& image )
+{
+ BMP_INFOHDR bi;
+ TQIODevice* d = s.tqdevice();
+
+ s >> bi; // read BMP info header
+ if ( d->atEnd() ) // end of stream/file
+ return FALSE;
+#if 0
+ qDebug( "offset...........%d", offset );
+ qDebug( "startpos.........%d", startpos );
+ qDebug( "biSize...........%d", bi.biSize );
+ qDebug( "biWidth..........%d", bi.biWidth );
+ qDebug( "biHeight.........%d", bi.biHeight );
+ qDebug( "biPlanes.........%d", bi.biPlanes );
+ qDebug( "biBitCount.......%d", bi.biBitCount );
+ qDebug( "biCompression....%d", bi.biCompression );
+ qDebug( "biSizeImage......%d", bi.biSizeImage );
+ qDebug( "biXPelsPerMeter..%d", bi.biXPelsPerMeter );
+ qDebug( "biYPelsPerMeter..%d", bi.biYPelsPerMeter );
+ qDebug( "biClrUsed........%d", bi.biClrUsed );
+ qDebug( "biClrImportant...%d", bi.biClrImportant );
+#endif
+ int w = bi.biWidth, h = bi.biHeight, nbits = bi.biBitCount;
+ int t = bi.biSize, comp = bi.biCompression;
+ int red_mask, green_mask, blue_mask;
+ int red_shift = 0;
+ int green_shift = 0;
+ int blue_shift = 0;
+ int red_scale = 0;
+ int green_scale = 0;
+ int blue_scale = 0;
+
+ if ( !(nbits == 1 || nbits == 4 || nbits == 8 || nbits == 16 || nbits == 24 || nbits == 32) ||
+ bi.biPlanes != 1 || comp > BMP_BITFIELDS )
+ return FALSE; // weird BMP image
+ if ( !(comp == BMP_RGB || (nbits == 4 && comp == BMP_RLE4) ||
+ (nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS)) )
+ return FALSE; // weird compression type
+
+ int ncols;
+ int depth;
+ switch ( nbits ) {
+ case 32:
+ case 24:
+ case 16:
+ depth = 32;
+ break;
+ case 8:
+ case 4:
+ depth = 8;
+ break;
+ default:
+ depth = 1;
+ }
+ if ( depth == 32 ) // there's no colormap
+ ncols = 0;
+ else // # colors used
+ ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
+
+ image.create( w, h, depth, ncols, nbits == 1 ?
+ TQImage::BigEndian : TQImage::IgnoreEndian );
+ if ( image.isNull() ) // could not create image
+ return FALSE;
+
+ image.setDotsPerMeterX( bi.biXPelsPerMeter );
+ image.setDotsPerMeterY( bi.biYPelsPerMeter );
+
+ d->at( startpos + BMP_FILEHDR_SIZE + bi.biSize ); // goto start of colormap
+
+ if ( ncols > 0 ) { // read color table
+ uchar rgb[4];
+ int rgb_len = t == BMP_OLD ? 3 : 4;
+ for ( int i=0; i<ncols; i++ ) {
+ if ( d->readBlock( (char *)rgb, rgb_len ) != rgb_len )
+ return FALSE;
+ image.setColor( i, tqRgb(rgb[2],rgb[1],rgb[0]) );
+ if ( d->atEnd() ) // truncated file
+ return FALSE;
+ }
+ } else if (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32)) {
+ if ( (TQ_ULONG)d->readBlock( (char *)&red_mask, sizeof(red_mask) ) != sizeof(red_mask) )
+ return FALSE;
+ if ( (TQ_ULONG)d->readBlock( (char *)&green_mask, sizeof(green_mask) ) != sizeof(green_mask) )
+ return FALSE;
+ if ( (TQ_ULONG)d->readBlock( (char *)&blue_mask, sizeof(blue_mask) ) != sizeof(blue_mask) )
+ return FALSE;
+ red_shift = calc_shift(red_mask);
+ red_scale = 256 / ((red_mask >> red_shift) + 1);
+ green_shift = calc_shift(green_mask);
+ green_scale = 256 / ((green_mask >> green_shift) + 1);
+ blue_shift = calc_shift(blue_mask);
+ blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
+ } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
+ blue_mask = 0x000000ff;
+ green_mask = 0x0000ff00;
+ red_mask = 0x00ff0000;
+ blue_shift = 0;
+ green_shift = 8;
+ red_shift = 16;
+ blue_scale = green_scale = red_scale = 1;
+ } else if (comp == BMP_RGB && nbits == 16) // don't support RGB values for 15/16 bpp
+ return FALSE;
+
+ // offset can be bogus, be careful
+ if (offset>=0 && startpos + offset > (TQ_LONG)d->at() )
+ d->at( startpos + offset ); // start of image data
+
+ int bpl = image.bytesPerLine();
+#ifdef TQ_WS_TQWS
+ //
+ // Guess the number of bytes-per-line if we don't know how much
+ // image data is in the file (bogus image ?).
+ //
+ int bmpbpl = bi.biSizeImage > 0 ?
+ bi.biSizeImage / bi.biHeight :
+ (d->size() - offset) / bi.biHeight;
+ int pad = bmpbpl-bpl;
+#endif
+ uchar **line = image.jumpTable();
+
+ if ( nbits == 1 ) { // 1 bit BMP image
+ while ( --h >= 0 ) {
+ if ( d->readBlock((char*)line[h],bpl) != bpl )
+ break;
+#ifdef TQ_WS_TQWS
+ if ( pad > 0 )
+ d->at(d->at()+pad);
+#endif
+ }
+ if ( ncols == 2 && tqGray(image.color(0)) < tqGray(image.color(1)) )
+ swapPixel01( &image ); // pixel 0 is white!
+ }
+
+ else if ( nbits == 4 ) { // 4 bit BMP image
+ int buflen = ((w+7)/8)*4;
+ uchar *buf = new uchar[buflen];
+ TQ_CHECK_PTR( buf );
+ if ( comp == BMP_RLE4 ) { // run length compression
+ int x=0, y=0, b, c, i;
+ register uchar *p = line[h-1];
+ uchar *endp = line[h-1]+w;
+ while ( y < h ) {
+ if ( (b=d->getch()) == EOF )
+ break;
+ if ( b == 0 ) { // escape code
+ switch ( (b=d->getch()) ) {
+ case 0: // end of line
+ x = 0;
+ y++;
+ p = line[h-y-1];
+ break;
+ case 1: // end of image
+ case EOF: // end of file
+ y = h; // exit loop
+ break;
+ case 2: // delta (jump)
+ x += d->getch();
+ y += d->getch();
+
+ // Protection
+ if ( (uint)x >= (uint)w )
+ x = w-1;
+ if ( (uint)y >= (uint)h )
+ y = h-1;
+
+ p = line[h-y-1] + x;
+ break;
+ default: // absolute mode
+ // Protection
+ if ( p + b > endp )
+ b = endp-p;
+
+ i = (c = b)/2;
+ while ( i-- ) {
+ b = d->getch();
+ *p++ = b >> 4;
+ *p++ = b & 0x0f;
+ }
+ if ( c & 1 )
+ *p++ = d->getch() >> 4;
+ if ( (((c & 3) + 1) & 2) == 2 )
+ d->getch(); // align on word boundary
+ x += c;
+ }
+ } else { // encoded mode
+ // Protection
+ if ( p + b > endp )
+ b = endp-p;
+
+ i = (c = b)/2;
+ b = d->getch(); // 2 pixels to be repeated
+ while ( i-- ) {
+ *p++ = b >> 4;
+ *p++ = b & 0x0f;
+ }
+ if ( c & 1 )
+ *p++ = b >> 4;
+ x += c;
+ }
+ }
+ } else if ( comp == BMP_RGB ) { // no compression
+ while ( --h >= 0 ) {
+ if ( d->readBlock((char*)buf,buflen) != buflen )
+ break;
+ register uchar *p = line[h];
+ uchar *b = buf;
+ for ( int i=0; i<w/2; i++ ) { // convert nibbles to bytes
+ *p++ = *b >> 4;
+ *p++ = *b++ & 0x0f;
+ }
+ if ( w & 1 ) // the last nibble
+ *p = *b >> 4;
+ }
+ }
+ delete [] buf;
+ }
+
+ else if ( nbits == 8 ) { // 8 bit BMP image
+ if ( comp == BMP_RLE8 ) { // run length compression
+ int x=0, y=0, b;
+ register uchar *p = line[h-1];
+ const uchar *endp = line[h-1]+w;
+ while ( y < h ) {
+ if ( (b=d->getch()) == EOF )
+ break;
+ if ( b == 0 ) { // escape code
+ switch ( (b=d->getch()) ) {
+ case 0: // end of line
+ x = 0;
+ y++;
+ p = line[h-y-1];
+ break;
+ case 1: // end of image
+ case EOF: // end of file
+ y = h; // exit loop
+ break;
+ case 2: // delta (jump)
+ x += d->getch();
+ y += d->getch();
+
+ // Protection
+ if ( (uint)x >= (uint)w )
+ x = w-1;
+ if ( (uint)y >= (uint)h )
+ y = h-1;
+
+ p = line[h-y-1] + x;
+ break;
+ default: // absolute mode
+ // Protection
+ if ( p + b > endp )
+ b = endp-p;
+
+ if ( d->readBlock( (char *)p, b ) != b )
+ return FALSE;
+ if ( (b & 1) == 1 )
+ d->getch(); // align on word boundary
+ x += b;
+ p += b;
+ }
+ } else { // encoded mode
+ // Protection
+ if ( p + b > endp )
+ b = endp-p;
+
+ memset( p, d->getch(), b ); // repeat pixel
+ x += b;
+ p += b;
+ }
+ }
+ } else if ( comp == BMP_RGB ) { // uncompressed
+ while ( --h >= 0 ) {
+ if ( d->readBlock((char *)line[h],bpl) != bpl )
+ break;
+#ifdef TQ_WS_TQWS
+ if ( pad > 0 )
+ d->at(d->at()+pad);
+#endif
+ }
+ }
+ }
+
+ else if ( nbits == 16 || nbits == 24 || nbits == 32 ) { // 16,24,32 bit BMP image
+ register TQRgb *p;
+ TQRgb *end;
+ uchar *buf24 = new uchar[bpl];
+ int bpl24 = ((w*nbits+31)/32)*4;
+ uchar *b;
+ int c;
+
+ while ( --h >= 0 ) {
+ p = (TQRgb *)line[h];
+ end = p + w;
+ if ( d->readBlock( (char *)buf24,bpl24) != bpl24 )
+ break;
+ b = buf24;
+ while ( p < end ) {
+ c = *(uchar*)b | (*(uchar*)(b+1)<<8);
+ if (nbits != 16)
+ c |= *(uchar*)(b+2)<<16;
+ *p++ = tqRgb(((c & red_mask) >> red_shift) * red_scale,
+ ((c & green_mask) >> green_shift) * green_scale,
+ ((c & blue_mask) >> blue_shift) * blue_scale);
+ b += nbits/8;
+ }
+ }
+ delete[] buf24;
+ }
+
+ return TRUE;
+}
+
+bool qt_read_dib( TQDataStream& s, TQImage& image )
+{
+ return read_dib(s,-1,-BMP_FILEHDR_SIZE,image);
+}
+
+
+static void read_bmp_image( TQImageIO *iio )
+{
+ TQIODevice *d = iio->ioDevice();
+ TQDataStream s( d );
+ BMP_FILEHDR bf;
+ int startpos = d->at();
+
+ s.setByteOrder( TQDataStream::LittleEndian );// Intel byte order
+ s >> bf; // read BMP file header
+
+ if ( tqstrncmp(bf.bfType,"BM",2) != 0 ) // not a BMP image
+ return;
+
+ TQImage image;
+ if (read_dib( s, bf.bfOffBits, startpos, image )) {
+ iio->setImage( image );
+ iio->setqStatus( 0 ); // image ok
+ }
+}
+
+bool qt_write_dib( TQDataStream& s, TQImage image )
+{
+ int nbits;
+ int bpl_bmp;
+ int bpl = image.bytesPerLine();
+
+ TQIODevice* d = s.tqdevice();
+
+ if ( image.depth() == 8 && image.numColors() <= 16 ) {
+ bpl_bmp = (((bpl+1)/2+3)/4)*4;
+ nbits = 4;
+ } else if ( image.depth() == 32 ) {
+ bpl_bmp = ((image.width()*24+31)/32)*4;
+ nbits = 24;
+#ifdef TQ_WS_TQWS
+ } else if ( image.depth() == 1 || image.depth() == 8 ) {
+ // TQt/E doesn't word align.
+ bpl_bmp = ((image.width()*image.depth()+31)/32)*4;
+ nbits = image.depth();
+#endif
+ } else {
+ bpl_bmp = bpl;
+ nbits = image.depth();
+ }
+
+ BMP_INFOHDR bi;
+ bi.biSize = BMP_WIN; // build info header
+ bi.biWidth = image.width();
+ bi.biHeight = image.height();
+ bi.biPlanes = 1;
+ bi.biBitCount = nbits;
+ bi.biCompression = BMP_RGB;
+ bi.biSizeImage = bpl_bmp*image.height();
+ bi.biXPelsPerMeter = image.dotsPerMeterX() ? image.dotsPerMeterX()
+ : 2834; // 72 dpi default
+ bi.biYPelsPerMeter = image.dotsPerMeterY() ? image.dotsPerMeterY() : 2834;
+ bi.biClrUsed = image.numColors();
+ bi.biClrImportant = image.numColors();
+ s << bi; // write info header
+
+ if ( image.depth() != 32 ) { // write color table
+ uchar *color_table = new uchar[4*image.numColors()];
+ uchar *rgb = color_table;
+ TQRgb *c = image.tqcolorTable();
+ for ( int i=0; i<image.numColors(); i++ ) {
+ *rgb++ = tqBlue ( c[i] );
+ *rgb++ = tqGreen( c[i] );
+ *rgb++ = tqRed ( c[i] );
+ *rgb++ = 0;
+ }
+ d->writeBlock( (char *)color_table, 4*image.numColors() );
+ delete [] color_table;
+ }
+
+ if ( image.depth() == 1 && image.bitOrder() != TQImage::BigEndian )
+ image = image.convertBitOrder( TQImage::BigEndian );
+
+ int y;
+
+ if ( nbits == 1 || nbits == 8 ) { // direct output
+#ifdef TQ_WS_TQWS
+ // TQt/E doesn't word align.
+ int pad = bpl_bmp - bpl;
+ char padding[4];
+#endif
+ for ( y=image.height()-1; y>=0; y-- ) {
+ d->writeBlock( (char*)image.scanLine(y), bpl );
+#ifdef TQ_WS_TQWS
+ d->writeBlock( padding, pad );
+#endif
+ }
+ return TRUE;
+ }
+
+ uchar *buf = new uchar[bpl_bmp];
+ uchar *b, *end;
+ register uchar *p;
+
+ memset( buf, 0, bpl_bmp );
+ for ( y=image.height()-1; y>=0; y-- ) { // write the image bits
+ if ( nbits == 4 ) { // convert 8 -> 4 bits
+ p = image.scanLine(y);
+ b = buf;
+ end = b + image.width()/2;
+ while ( b < end ) {
+ *b++ = (*p << 4) | (*(p+1) & 0x0f);
+ p += 2;
+ }
+ if ( image.width() & 1 )
+ *b = *p << 4;
+ } else { // 32 bits
+ TQRgb *p = (TQRgb *)image.scanLine( y );
+ TQRgb *end = p + image.width();
+ b = buf;
+ while ( p < end ) {
+ *b++ = tqBlue(*p);
+ *b++ = tqGreen(*p);
+ *b++ = tqRed(*p);
+ p++;
+ }
+ }
+ if ( bpl_bmp != d->writeBlock( (char*)buf, bpl_bmp ) ) {
+ delete[] buf;
+ return FALSE;
+ }
+ }
+ delete[] buf;
+ return TRUE;
+}
+
+
+static void write_bmp_image( TQImageIO *iio )
+{
+ TQIODevice *d = iio->ioDevice();
+ TQImage image = iio->image();
+ TQDataStream s( d );
+ BMP_FILEHDR bf;
+ int bpl_bmp;
+ int bpl = image.bytesPerLine();
+
+ // Code partially repeated in qt_write_dib
+ if ( image.depth() == 8 && image.numColors() <= 16 ) {
+ bpl_bmp = (((bpl+1)/2+3)/4)*4;
+ } else if ( image.depth() == 32 ) {
+ bpl_bmp = ((image.width()*24+31)/32)*4;
+ } else {
+ bpl_bmp = bpl;
+ }
+
+ iio->setqStatus( 0 );
+ s.setByteOrder( TQDataStream::LittleEndian );// Intel byte order
+ strncpy( bf.bfType, "BM", 2 ); // build file header
+ bf.bfReserved1 = bf.bfReserved2 = 0; // reserved, should be zero
+ bf.bfOffBits = BMP_FILEHDR_SIZE + BMP_WIN + image.numColors()*4;
+ bf.bfSize = bf.bfOffBits + bpl_bmp*image.height();
+ s << bf; // write file header
+
+ if ( !qt_write_dib( s, image ) )
+ iio->setqStatus( 1 );
+
+}
+
+#endif // TQT_NO_IMAGEIO_BMP
+
+#ifndef TQT_NO_IMAGEIO_PPM
+
+/*****************************************************************************
+ PBM/PGM/PPM (ASCII and RAW) image read/write functions
+ *****************************************************************************/
+
+static int read_pbm_int( TQIODevice *d )
+{
+ int c;
+ int val = -1;
+ bool digit;
+ const int buflen = 100;
+ char buf[buflen];
+ for ( ;; ) {
+ if ( (c=d->getch()) == EOF ) // end of file
+ break;
+ digit = isdigit( (uchar) c );
+ if ( val != -1 ) {
+ if ( digit ) {
+ val = 10*val + c - '0';
+ continue;
+ } else {
+ if ( c == '#' ) // comment
+ d->readLine( buf, buflen );
+ break;
+ }
+ }
+ if ( digit ) // first digit
+ val = c - '0';
+ else if ( isspace((uchar) c) )
+ continue;
+ else if ( c == '#' )
+ d->readLine( buf, buflen );
+ else
+ break;
+ }
+ return val;
+}
+
+static void read_pbm_image( TQImageIO *iio ) // read PBM image data
+{
+ const int buflen = 300;
+ char buf[buflen];
+ TQIODevice *d = iio->ioDevice();
+ int w, h, nbits, mcc, y;
+ int pbm_bpl;
+ char type;
+ bool raw;
+ TQImage image;
+
+ if ( d->readBlock( buf, 3 ) != 3 ) // read P[1-6]<white-space>
+ return;
+ if ( !(buf[0] == 'P' && isdigit((uchar) buf[1]) && isspace((uchar) buf[2])) )
+ return;
+ switch ( (type=buf[1]) ) {
+ case '1': // ascii PBM
+ case '4': // raw PBM
+ nbits = 1;
+ break;
+ case '2': // ascii PGM
+ case '5': // raw PGM
+ nbits = 8;
+ break;
+ case '3': // ascii PPM
+ case '6': // raw PPM
+ nbits = 32;
+ break;
+ default:
+ return;
+ }
+ raw = type >= '4';
+ w = read_pbm_int( d ); // get image width
+ h = read_pbm_int( d ); // get image height
+ if ( nbits == 1 )
+ mcc = 1; // ignore max color component
+ else
+ mcc = read_pbm_int( d ); // get max color component
+ if ( w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0 )
+ return; // weird P.M image
+
+ int maxc = mcc;
+ if ( maxc > 255 )
+ maxc = 255;
+ image.create( w, h, nbits, 0,
+ nbits == 1 ? TQImage::BigEndian : TQImage::IgnoreEndian );
+ if ( image.isNull() )
+ return;
+
+ pbm_bpl = (nbits*w+7)/8; // bytes per scanline in PBM
+
+ if ( raw ) { // read raw data
+ if ( nbits == 32 ) { // type 6
+ pbm_bpl = 3*w;
+ uchar *buf24 = new uchar[pbm_bpl], *b;
+ TQRgb *p;
+ TQRgb *end;
+ for ( y=0; y<h; y++ ) {
+ if ( d->readBlock( (char *)buf24, pbm_bpl ) != pbm_bpl ) {
+ delete[] buf24;
+ return;
+ }
+ p = (TQRgb *)image.scanLine( y );
+ end = p + w;
+ b = buf24;
+ while ( p < end ) {
+ *p++ = tqRgb(b[0],b[1],b[2]);
+ b += 3;
+ }
+ }
+ delete[] buf24;
+ } else { // type 4,5
+ for ( y=0; y<h; y++ ) {
+ if ( d->readBlock( (char *)image.scanLine(y), pbm_bpl )
+ != pbm_bpl )
+ return;
+ }
+ }
+ } else { // read ascii data
+ register uchar *p;
+ int n;
+ for ( y=0; y<h; y++ ) {
+ p = image.scanLine( y );
+ n = pbm_bpl;
+ if ( nbits == 1 ) {
+ int b;
+ while ( n-- ) {
+ b = 0;
+ for ( int i=0; i<8; i++ )
+ b = (b << 1) | (read_pbm_int(d) & 1);
+ *p++ = b;
+ }
+ } else if ( nbits == 8 ) {
+ if ( mcc == maxc ) {
+ while ( n-- ) {
+ *p++ = read_pbm_int( d );
+ }
+ } else {
+ while ( n-- ) {
+ *p++ = read_pbm_int( d ) * maxc / mcc;
+ }
+ }
+ } else { // 32 bits
+ n /= 4;
+ int r, g, b;
+ if ( mcc == maxc ) {
+ while ( n-- ) {
+ r = read_pbm_int( d );
+ g = read_pbm_int( d );
+ b = read_pbm_int( d );
+ *((TQRgb*)p) = tqRgb( r, g, b );
+ p += 4;
+ }
+ } else {
+ while ( n-- ) {
+ r = read_pbm_int( d ) * maxc / mcc;
+ g = read_pbm_int( d ) * maxc / mcc;
+ b = read_pbm_int( d ) * maxc / mcc;
+ *((TQRgb*)p) = tqRgb( r, g, b );
+ p += 4;
+ }
+ }
+ }
+ }
+ }
+
+ if ( nbits == 1 ) { // bitmap
+ image.setNumColors( 2 );
+ image.setColor( 0, tqRgb(255,255,255) ); // white
+ image.setColor( 1, tqRgb(0,0,0) ); // black
+ } else if ( nbits == 8 ) { // graymap
+ image.setNumColors( maxc+1 );
+ for ( int i=0; i<=maxc; i++ )
+ image.setColor( i, tqRgb(i*255/maxc,i*255/maxc,i*255/maxc) );
+ }
+
+ iio->setImage( image );
+ iio->setqStatus( 0 ); // image ok
+}
+
+
+static void write_pbm_image( TQImageIO *iio )
+{
+ TQIODevice* out = iio->ioDevice();
+ TQCString str;
+
+ TQImage image = iio->image();
+ TQCString format = iio->format();
+ format = format.left(3); // ignore RAW part
+ bool gray = format == "PGM";
+
+ if ( format == "PBM" ) {
+ image = image.convertDepth(1);
+ } else if ( image.depth() == 1 ) {
+ image = image.convertDepth(8);
+ }
+
+ if ( image.depth() == 1 && image.numColors() == 2 ) {
+ if ( tqGray(image.color(0)) < tqGray(image.color(1)) ) {
+ // 0=dark/black, 1=light/white - invert
+ image.detach();
+ for ( int y=0; y<image.height(); y++ ) {
+ uchar *p = image.scanLine(y);
+ uchar *end = p + image.bytesPerLine();
+ while ( p < end )
+ *p++ ^= 0xff;
+ }
+ }
+ }
+
+ uint w = image.width();
+ uint h = image.height();
+
+ str.sprintf("P\n%d %d\n", w, h);
+
+ switch (image.depth()) {
+ case 1: {
+ str.insert(1, '4');
+ if ((uint)out->writeBlock(str, str.length()) != str.length()) {
+ iio->setqStatus(1);
+ return;
+ }
+ w = (w+7)/8;
+ for (uint y=0; y<h; y++) {
+ uchar* line = image.scanLine(y);
+ if ( w != (uint)out->writeBlock((char*)line, w) ) {
+ iio->setqStatus(1);
+ return;
+ }
+ }
+ }
+ break;
+
+ case 8: {
+ str.insert(1, gray ? '5' : '6');
+ str.append("255\n");
+ if ((uint)out->writeBlock(str, str.length()) != str.length()) {
+ iio->setqStatus(1);
+ return;
+ }
+ TQRgb *color = image.tqcolorTable();
+ uint bpl = w*(gray ? 1 : 3);
+ uchar *buf = new uchar[bpl];
+ for (uint y=0; y<h; y++) {
+ uchar *b = image.scanLine(y);
+ uchar *p = buf;
+ uchar *end = buf+bpl;
+ if ( gray ) {
+ while ( p < end ) {
+ uchar g = (uchar)tqGray(color[*b++]);
+ *p++ = g;
+ }
+ } else {
+ while ( p < end ) {
+ TQRgb rgb = color[*b++];
+ *p++ = tqRed(rgb);
+ *p++ = tqGreen(rgb);
+ *p++ = tqBlue(rgb);
+ }
+ }
+ if ( bpl != (uint)out->writeBlock((char*)buf, bpl) ) {
+ iio->setqStatus(1);
+ return;
+ }
+ }
+ delete [] buf;
+ }
+ break;
+
+ case 32: {
+ str.insert(1, gray ? '5' : '6');
+ str.append("255\n");
+ if ((uint)out->writeBlock(str, str.length()) != str.length()) {
+ iio->setqStatus(1);
+ return;
+ }
+ uint bpl = w*(gray ? 1 : 3);
+ uchar *buf = new uchar[bpl];
+ for (uint y=0; y<h; y++) {
+ TQRgb *b = (TQRgb*)image.scanLine(y);
+ uchar *p = buf;
+ uchar *end = buf+bpl;
+ if ( gray ) {
+ while ( p < end ) {
+ uchar g = (uchar)tqGray(*b++);
+ *p++ = g;
+ }
+ } else {
+ while ( p < end ) {
+ TQRgb rgb = *b++;
+ *p++ = tqRed(rgb);
+ *p++ = tqGreen(rgb);
+ *p++ = tqBlue(rgb);
+ }
+ }
+ if ( bpl != (uint)out->writeBlock((char*)buf, bpl) ) {
+ iio->setqStatus(1);
+ return;
+ }
+ }
+ delete [] buf;
+ }
+ }
+
+ iio->setqStatus(0);
+}
+
+#endif // TQT_NO_IMAGEIO_PPM
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+
+class TQImageIOFrameGrabber : public TQImageConsumer {
+public:
+ TQImageIOFrameGrabber() : framecount(0) { }
+
+ TQImageDecoder *decoder;
+ int framecount;
+
+ void changed(const TQRect&) { }
+ void end() { }
+ void frameDone(const TQPoint&, const TQRect&) { framecount++; }
+ void frameDone() { framecount++; }
+ void setLooping(int) { }
+ void setFramePeriod(int) { }
+ void setSize(int, int) { }
+};
+
+static void read_async_image( TQImageIO *iio )
+{
+ const int buf_len = 2048;
+ uchar buffer[buf_len];
+ TQIODevice *d = iio->ioDevice();
+ TQImageIOFrameGrabber* consumer = new TQImageIOFrameGrabber();
+ TQImageDecoder *decoder = new TQImageDecoder(consumer);
+ consumer->decoder = decoder;
+ int startAt = d->at();
+ int totLen = 0;
+
+ for (;;) {
+ int length = d->readBlock((char*)buffer, buf_len);
+ if ( length <= 0 ) {
+ iio->setqStatus(length);
+ break;
+ }
+ uchar* b = buffer;
+ int r = -1;
+ while (length > 0 && consumer->framecount==0) {
+ r = decoder->decode(b, length);
+ if ( r <= 0 ) break;
+ b += r;
+ totLen += r;
+ length -= r;
+ }
+ if ( consumer->framecount ) {
+ // Stopped after first frame
+ if ( d->isDirectAccess() )
+ d->at( startAt + totLen );
+ else {
+ // ### We have (probably) read too much from the stream into
+ // the buffer, and there is no way to put it back!
+ }
+ iio->setImage(decoder->image());
+ iio->setqStatus(0);
+ break;
+ }
+ if ( r <= 0 ) {
+ iio->setqStatus(r);
+ break;
+ }
+ }
+
+ consumer->decoder = 0;
+ delete decoder;
+ delete consumer;
+}
+
+#endif // TQT_NO_ASYNC_IMAGE_IO
+
+#ifndef TQT_NO_IMAGEIO_XBM
+
+/*****************************************************************************
+ X bitmap image read/write functions
+ *****************************************************************************/
+
+static inline int hex2byte( register char *p )
+{
+ return ( (isdigit((uchar) *p) ? *p - '0' : toupper((uchar) *p) - 'A' + 10) << 4 ) |
+ ( isdigit((uchar) *(p+1)) ? *(p+1) - '0' : toupper((uchar) *(p+1)) - 'A' + 10 );
+}
+
+static void read_xbm_image( TQImageIO *iio )
+{
+ const int buflen = 300;
+ char buf[buflen];
+ TQRegExp r1, r2;
+ TQIODevice *d = iio->ioDevice();
+ int w=-1, h=-1;
+ TQImage image;
+
+ r1 = TQString::tqfromLatin1("^#define[ \t]+[a-zA-Z0-9._]+[ \t]+");
+ r2 = TQString::tqfromLatin1("[0-9]+");
+ d->readLine( buf, buflen ); // "#define .._width <num>"
+
+ while (!d->atEnd() && buf[0] != '#') //skip leading comment, if any
+ d->readLine( buf, buflen );
+
+ TQString sbuf;
+ sbuf = TQString::tqfromLatin1(buf);
+
+ if ( r1.search(sbuf) == 0 &&
+ r2.search(sbuf, r1.matchedLength()) == r1.matchedLength() )
+ w = atoi( &buf[r1.matchedLength()] );
+
+ d->readLine( buf, buflen ); // "#define .._height <num>"
+ sbuf = TQString::tqfromLatin1(buf);
+
+ if ( r1.search(sbuf) == 0 &&
+ r2.search(sbuf, r1.matchedLength()) == r1.matchedLength() )
+ h = atoi( &buf[r1.matchedLength()] );
+
+ if ( w <= 0 || w > 32767 || h <= 0 || h > 32767 )
+ return; // format error
+
+ for ( ;; ) { // scan for data
+ if ( d->readLine(buf, buflen) <= 0 ) // end of file
+ return;
+ if ( strstr(buf,"0x") != 0 ) // does line contain data?
+ break;
+ }
+
+ image.create( w, h, 1, 2, TQImage::LittleEndian );
+ if ( image.isNull() )
+ return;
+
+ image.setColor( 0, tqRgb(255,255,255) ); // white
+ image.setColor( 1, tqRgb(0,0,0) ); // black
+
+ int x = 0, y = 0;
+ uchar *b = image.scanLine(0);
+ char *p = strstr( buf, "0x" );
+ w = (w+7)/8; // byte width
+
+ while ( y < h ) { // for all encoded bytes...
+ if ( p ) { // p = "0x.."
+ *b++ = hex2byte(p+2);
+ p += 2;
+ if ( ++x == w && ++y < h ) {
+ b = image.scanLine(y);
+ x = 0;
+ }
+ p = strstr( p, "0x" );
+ } else { // read another line
+ if ( d->readLine(buf,buflen) <= 0 ) // EOF ==> truncated image
+ break;
+ p = strstr( buf, "0x" );
+ }
+ }
+
+ iio->setImage( image );
+ iio->setqStatus( 0 ); // image ok
+}
+
+
+static void write_xbm_image( TQImageIO *iio )
+{
+ TQIODevice *d = iio->ioDevice();
+ TQImage image = iio->image();
+ int w = image.width();
+ int h = image.height();
+ int i;
+ TQString s = fbname(iio->fileName()); // get file base name
+ char *buf = new char[s.length() + 100];
+
+ sprintf( buf, "#define %s_width %d\n", s.ascii(), w );
+ d->writeBlock( buf, tqstrlen(buf) );
+ sprintf( buf, "#define %s_height %d\n", s.ascii(), h );
+ d->writeBlock( buf, tqstrlen(buf) );
+ sprintf( buf, "static char %s_bits[] = {\n ", s.ascii() );
+ d->writeBlock( buf, tqstrlen(buf) );
+
+ iio->setqStatus( 0 );
+
+ if ( image.depth() != 1 )
+ image = image.convertDepth( 1 ); // dither
+ if ( image.bitOrder() != TQImage::LittleEndian )
+ image = image.convertBitOrder( TQImage::LittleEndian );
+
+ bool invert = tqGray(image.color(0)) < tqGray(image.color(1));
+ char hexrep[16];
+ for ( i=0; i<10; i++ )
+ hexrep[i] = '0' + i;
+ for ( i=10; i<16; i++ )
+ hexrep[i] = 'a' -10 + i;
+ if ( invert ) {
+ char t;
+ for ( i=0; i<8; i++ ) {
+ t = hexrep[15-i];
+ hexrep[15-i] = hexrep[i];
+ hexrep[i] = t;
+ }
+ }
+ int bcnt = 0;
+ register char *p = buf;
+ int bpl = (w+7)/8;
+ for (int y = 0; y < h; ++y) {
+ uchar *b = image.scanLine(y);
+ for (i = 0; i < bpl; ++i) {
+ *p++ = '0'; *p++ = 'x';
+ *p++ = hexrep[*b >> 4];
+ *p++ = hexrep[*b++ & 0xf];
+
+ if ( i < bpl - 1 || y < h - 1 ) {
+ *p++ = ',';
+ if ( ++bcnt > 14 ) {
+ *p++ = '\n';
+ *p++ = ' ';
+ *p = '\0';
+ if ( (int)tqstrlen(buf) != d->writeBlock( buf, tqstrlen(buf) ) ) {
+ iio->setqStatus( 1 );
+ delete [] buf;
+ return;
+ }
+ p = buf;
+ bcnt = 0;
+ }
+ }
+ }
+ }
+ strcpy( p, " };\n" );
+ if ( (int)tqstrlen(buf) != d->writeBlock( buf, tqstrlen(buf) ) )
+ iio->setqStatus( 1 );
+ delete [] buf;
+}
+
+#endif // TQT_NO_IMAGEIO_XBM
+
+
+#ifndef TQT_NO_IMAGEIO_XPM
+
+/*****************************************************************************
+ XPM image read/write functions
+ *****************************************************************************/
+
+
+// Skip until ", read until the next ", return the rest in *buf
+// Returns FALSE on error, TRUE on success
+
+static bool read_xpm_string( TQCString &buf, TQIODevice *d,
+ const char * const *source, int &index )
+{
+ if ( source ) {
+ buf = source[index++];
+ return TRUE;
+ }
+
+ if ( buf.size() < 69 ) //# just an approximation
+ buf.resize( 123 );
+
+ buf[0] = '\0';
+ int c;
+ int i;
+ while ( (c=d->getch()) != EOF && c != '"' ) { }
+ if ( c == EOF ) {
+ return FALSE;
+ }
+ i = 0;
+ while ( (c=d->getch()) != EOF && c != '"' ) {
+ if ( i == (int)buf.size() )
+ buf.resize( i*2+42 );
+ buf[i++] = c;
+ }
+ if ( c == EOF ) {
+ return FALSE;
+ }
+
+ if ( i == (int)buf.size() ) // always use a 0 terminator
+ buf.resize( i+1 );
+ buf[i] = '\0';
+ return TRUE;
+}
+
+
+
+static int nextColorSpec(const TQCString & buf)
+{
+ int i = buf.tqfind(" c ");
+ if (i < 0)
+ i = buf.tqfind(" g ");
+ if (i < 0)
+ i = buf.tqfind(" g4 ");
+ if (i < 0)
+ i = buf.tqfind(" m ");
+ if (i < 0)
+ i = buf.tqfind(" s ");
+ return i;
+}
+
+//
+// INTERNAL
+//
+// Reads an .xpm from either the TQImageIO or from the TQString *.
+// One of the two HAS to be 0, the other one is used.
+//
+
+static void read_xpm_image_or_array( TQImageIO * iio, const char * const * source,
+ TQImage & image)
+{
+ TQCString buf;
+ TQIODevice *d = 0;
+ buf.resize( 200 );
+
+ int i, cpp, ncols, w, h, index = 0;
+
+ if ( iio ) {
+ iio->setqStatus( 1 );
+ d = iio ? iio->ioDevice() : 0;
+ d->readLine( buf.data(), buf.size() ); // "/* XPM */"
+ TQRegExp r( TQString::tqfromLatin1("/\\*.XPM.\\*/") );
+ if ( buf.tqfind(r) == -1 )
+ return; // bad magic
+ } else if ( !source ) {
+ return;
+ }
+
+ if ( !read_xpm_string( buf, d, source, index ) )
+ return;
+
+ if ( sscanf( buf, "%d %d %d %d", &w, &h, &ncols, &cpp ) < 4 )
+ return; // < 4 numbers parsed
+
+ if ( cpp > 15 )
+ return;
+
+ if ( ncols > 256 ) {
+ image.create( w, h, 32 );
+ } else {
+ image.create( w, h, 8, ncols );
+ }
+
+ if (image.isNull())
+ return;
+
+ TQMap<TQString, int> colorMap;
+ int currentColor;
+
+ for( currentColor=0; currentColor < ncols; ++currentColor ) {
+ if ( !read_xpm_string( buf, d, source, index ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage: XPM color specification missing");
+#endif
+ return;
+ }
+ TQString index;
+ index = buf.left( cpp );
+ buf = buf.mid( cpp ).simplifyWhiteSpace().lower();
+ buf.prepend( " " );
+ i = nextColorSpec(buf);
+ if ( i < 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage: XPM color specification is missing: %s", buf.data());
+#endif
+ return; // no c/g/g4/m/s specification at all
+ }
+ buf = buf.mid( i+3 );
+ // Strip any other colorspec
+ int end = nextColorSpec(buf);
+ if (end != -1)
+ buf.truncate(end);
+ buf = buf.stripWhiteSpace();
+ if ( buf == "none" ) {
+ image.setAlphaBuffer( TRUE );
+ int transparentColor = currentColor;
+ if ( image.depth() == 8 ) {
+ image.setColor( transparentColor,
+ TQRGB_MASK & tqRgb(198,198,198) );
+ colorMap.insert( index, transparentColor );
+ } else {
+ TQRgb rgb = TQRGB_MASK & tqRgb(198,198,198);
+ colorMap.insert( index, rgb );
+ }
+ } else {
+ if ( ((buf.length()-1) % 3) && (buf[0] == '#') ) {
+ buf.truncate (((buf.length()-1) / 4 * 3) + 1); // remove alpha channel left by imagemagick
+ }
+ TQColor c( buf.data() );
+ if ( image.depth() == 8 ) {
+ image.setColor( currentColor, 0xff000000 | c.rgb() );
+ colorMap.insert( index, currentColor );
+ } else {
+ TQRgb rgb = 0xff000000 | c.rgb();
+ colorMap.insert( index, rgb );
+ }
+ }
+ }
+
+ // Read pixels
+ for( int y=0; y<h; y++ ) {
+ if ( !read_xpm_string( buf, d, source, index ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage: XPM pixels missing on image line %d", y);
+#endif
+ return;
+ }
+ if ( image.depth() == 8 ) {
+ uchar *p = image.scanLine(y);
+ uchar *d = (uchar *)buf.data();
+ uchar *end = d + buf.length();
+ int x;
+ if ( cpp == 1 ) {
+ char b[2];
+ b[1] = '\0';
+ for ( x=0; x<w && d<end; x++ ) {
+ b[0] = *d++;
+ *p++ = (uchar)colorMap[b];
+ }
+ } else {
+ char b[16];
+ b[cpp] = '\0';
+ for ( x=0; x<w && d<end; x++ ) {
+ strncpy( b, (char *)d, cpp );
+ *p++ = (uchar)colorMap[b];
+ d += cpp;
+ }
+ }
+ } else {
+ TQRgb *p = (TQRgb*)image.scanLine(y);
+ uchar *d = (uchar *)buf.data();
+ uchar *end = d + buf.length();
+ int x;
+ char b[16];
+ b[cpp] = '\0';
+ for ( x=0; x<w && d<end; x++ ) {
+ strncpy( b, (char *)d, cpp );
+ *p++ = (TQRgb)colorMap[b];
+ d += cpp;
+ }
+ }
+ }
+ if ( iio ) {
+ iio->setImage( image );
+ iio->setqStatus( 0 ); // image ok
+ }
+}
+
+
+static void read_xpm_image( TQImageIO * iio )
+{
+ TQImage i;
+ (void)read_xpm_image_or_array( iio, 0, i );
+ return;
+}
+
+
+static const char* xpm_color_name( int cpp, int index )
+{
+ static char returnable[5];
+ static const char code[] = ".#abcdefghijklmnopqrstuvwxyzABCD"
+ "EFGHIJKLMNOPTQRSTUVWXYZ0123456789";
+ // cpp is limited to 4 and index is limited to 64^cpp
+ if ( cpp > 1 ) {
+ if ( cpp > 2 ) {
+ if ( cpp > 3 ) {
+ returnable[3] = code[index % 64];
+ index /= 64;
+ } else
+ returnable[3] = '\0';
+ returnable[2] = code[index % 64];
+ index /= 64;
+ } else
+ returnable[2] = '\0';
+ // the following 4 lines are a joke!
+ if ( index == 0 )
+ index = 64*44+21;
+ else if ( index == 64*44+21 )
+ index = 0;
+ returnable[1] = code[index % 64];
+ index /= 64;
+ } else
+ returnable[1] = '\0';
+ returnable[0] = code[index];
+
+ return returnable;
+}
+
+
+// write XPM image data
+static void write_xpm_image( TQImageIO * iio )
+{
+ if ( iio )
+ iio->setqStatus( 1 );
+ else
+ return;
+
+ // ### 8-bit case could be made faster
+ TQImage image;
+ if ( iio->image().depth() != 32 )
+ image = iio->image().convertDepth( 32 );
+ else
+ image = iio->image();
+
+ TQMap<TQRgb, int> colorMap;
+
+ int w = image.width(), h = image.height(), ncolors = 0;
+ int x, y;
+
+ // build color table
+ for( y=0; y<h; y++ ) {
+ TQRgb * yp = (TQRgb *)image.scanLine( y );
+ for( x=0; x<w; x++ ) {
+ TQRgb color = *(yp + x);
+ if ( !colorMap.tqcontains(color) )
+ colorMap.insert( color, ncolors++ );
+ }
+ }
+
+ // number of 64-bit characters per pixel needed to encode all colors
+ int cpp = 1;
+ for ( int k = 64; ncolors > k; k *= 64 ) {
+ ++cpp;
+ // limit to 4 characters per pixel
+ // 64^4 colors is enough for a 4096x4096 image
+ if ( cpp > 4)
+ break;
+ }
+
+ TQString line;
+
+ // write header
+ TQTextStream s( iio->ioDevice() );
+ s << "/* XPM */" << endl
+ << "static char *" << fbname(iio->fileName()) << "[]={" << endl
+ << "\"" << w << " " << h << " " << ncolors << " " << cpp << "\"";
+
+ // write palette
+ TQMap<TQRgb, int>::Iterator c = colorMap.begin();
+ while ( c != colorMap.end() ) {
+ TQRgb color = c.key();
+ if ( image.hasAlphaBuffer() && color == (color & TQRGB_MASK) )
+ line.sprintf( "\"%s c None\"",
+ xpm_color_name(cpp, *c) );
+ else
+ line.sprintf( "\"%s c #%02x%02x%02x\"",
+ xpm_color_name(cpp, *c),
+ tqRed(color),
+ tqGreen(color),
+ tqBlue(color) );
+ ++c;
+ s << "," << endl << line;
+ }
+
+ // write pixels, limit to 4 characters per pixel
+ line.truncate( cpp*w );
+ for( y=0; y<h; y++ ) {
+ TQRgb * yp = (TQRgb *) image.scanLine( y );
+ int cc = 0;
+ for( x=0; x<w; x++ ) {
+ int color = (int)(*(yp + x));
+ TQCString chars = xpm_color_name( cpp, colorMap[color] );
+ line[cc++] = chars[0];
+ if ( cpp > 1 ) {
+ line[cc++] = chars[1];
+ if ( cpp > 2 ) {
+ line[cc++] = chars[2];
+ if ( cpp > 3 ) {
+ line[cc++] = chars[3];
+ }
+ }
+ }
+ }
+ s << "," << endl << "\"" << line << "\"";
+ }
+ s << "};" << endl;
+
+ iio->setqStatus( 0 );
+}
+
+#endif // TQT_NO_IMAGEIO_XPM
+#endif //TQT_NO_IMAGEIO
+#endif
+
+// table to flip bits
+static const uchar bitflip[256] = {
+ /*
+ open OUT, "| fmt";
+ for $i (0..255) {
+ print OUT (($i >> 7) & 0x01) | (($i >> 5) & 0x02) |
+ (($i >> 3) & 0x04) | (($i >> 1) & 0x08) |
+ (($i << 7) & 0x80) | (($i << 5) & 0x40) |
+ (($i << 3) & 0x20) | (($i << 1) & 0x10), ", ";
+ }
+ close OUT;
+ */
+ 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
+ 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
+ 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
+ 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
+ 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
+ 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
+ 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
+ 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
+ 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
+ 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
+ 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
+ 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
+ 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
+ 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
+ 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
+ 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
+};
+
+/*!
+ Converts the bit order of the image to the given \a bitOrder and
+ returns the converted image. The original image is not changed.
+ Returns this image if the given \a bitOrder is equal to the image
+ current bit order, or a null image if this image cannot be
+ converted.
+
+ Use convertToFormat() instead.
+*/
+
+TQImage TQImage::convertBitOrder(Endian bitOrder) const
+{
+ if (isNull() || depth() != 1 || !(bitOrder == BigEndian || bitOrder == LittleEndian))
+ return QImage();
+
+ if ((format() == Format_Mono && bitOrder == BigEndian)
+ || (format() == Format_MonoLSB && bitOrder == LittleEndian))
+ return *this;
+
+ TQImage image(width(), height(), format() == Format_Mono ? Format_MonoLSB : Format_Mono);
+
+ const uchar *data = bits();
+ const uchar *end = data + byteCount();
+ uchar *ndata = image.bits();
+ while (data < end)
+ *ndata++ = bitflip[*data++];
+
+ image.setDotsPerMeterX(dotsPerMeterX());
+ image.setDotsPerMeterY(dotsPerMeterY());
+
+ image.setColorTable(colorTable());
+ return image;
+}
+
+TQImage::Endian TQImage::systemBitOrder() {
+#if defined(Q_WS_X11)
+ return BitmapBitOrder(QX11Info::display()) == MSBFirst ? BigEndian : LittleEndian;
+#else
+ return BigEndian;
+#endif
+}
+
+/*!
+ \fn TQImage TQImage::convertDepthWithPalette(int depth, QRgb* palette, int palette_count, Qt::ImageConversionFlags flags) const
+
+ Returns an image with the given \a depth, using the \a
+ palette_count colors pointed to by \a palette. If \a depth is 1 or
+ 8, the returned image will have its color table ordered in the
+ same way as \a palette.
+
+ If the image needs to be modified to fit in a lower-resolution
+ result (e.g. converting from 32-bit to 8-bit), use the \a flags to
+ specify how you'd prefer this to happen.
+
+ Note: currently no closest-color search is made. If colors are
+ found that are not in the palette, the palette may not be used at
+ all. This result should not be considered valid because it may
+ change in future implementations.
+
+ Currently inefficient for non-32-bit images.
+
+ Use the convertToFormat() function in combination with the
+ setColorTable() function instead.
+*/
+TQImage TQImage::convertDepthWithPalette(int d, QRgb* palette, int palette_count, Qt::ImageConversionFlags flags) const
+{
+ Format f = const_cast<TQImage*>(this)->formatFor(d, TQImage::LittleEndian);
+ QVector<QRgb> colortable;
+ for (int i = 0; i < palette_count; ++i)
+ colortable.append(palette[i]);
+ return convertToFormat(f, colortable, flags);
+}
+
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+TQImage TQImage::createHeuristicMask( bool clipTight ) const {
+ return TQImage(QImage::createHeuristicMask(clipTight));
+}
+#endif
+
+#else // USE_QT4
+
+// 16bpp images on supported on TQt/Embedded
+#if !defined( TQ_WS_TQWS ) && !defined(TQT_NO_IMAGE_16_BIT)
+#define TQT_NO_IMAGE_16_BIT
+#endif
+
+
+/*!
+ \class TQImage
+ \brief The TQImage class provides a hardware-independent pixmap
+ representation with direct access to the pixel data.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup shared
+ \mainclass
+
+ It is one of the two classes TQt provides for dealing with images,
+ the other being TQPixmap. TQImage is designed and optimized for I/O
+ and for direct pixel access/manipulation. TQPixmap is designed and
+ optimized for drawing. There are (slow) functions to convert
+ between TQImage and TQPixmap: TQPixmap::convertToImage() and
+ TQPixmap::convertFromImage().
+
+ An image has the parameters \link width() width\endlink, \link
+ height() height\endlink and \link depth() depth\endlink (bits per
+ pixel, bpp), a color table and the actual \link bits()
+ pixels\endlink. TQImage supports 1-bpp, 8-bpp and 32-bpp image
+ data. 1-bpp and 8-bpp images use a color lookup table; the pixel
+ value is a color table index.
+
+ 32-bpp images encode an RGB value in 24 bits and ignore the color
+ table. The most significant byte is used for the \link
+ setAlphaBuffer() alpha buffer\endlink.
+
+ An entry in the color table is an RGB triplet encoded as a \c
+ uint. Use the \link ::tqRed() tqRed()\endlink, \link ::tqGreen()
+ tqGreen()\endlink and \link ::tqBlue() tqBlue()\endlink functions (\c
+ tqcolor.h) to access the components, and \link ::tqRgb()
+ tqRgb\endlink to make an RGB triplet (see the TQColor class
+ documentation).
+
+ 1-bpp (monochrome) images have a color table with a most two
+ colors. There are two different formats: big endian (MSB first) or
+ little endian (LSB first) bit order. To access a single bit you
+ will must do some bit shifts:
+
+ \code
+ TQImage image;
+ // sets bit at (x,y) to 1
+ if ( image.bitOrder() == TQImage::LittleEndian )
+ *(image.scanLine(y) + (x >> 3)) |= 1 << (x & 7);
+ else
+ *(image.scanLine(y) + (x >> 3)) |= 1 << (7 - (x & 7));
+ \endcode
+
+ If this looks complicated, it might be a good idea to convert the
+ 1-bpp image to an 8-bpp image using convertDepth().
+
+ 8-bpp images are much easier to work with than 1-bpp images
+ because they have a single byte per pixel:
+
+ \code
+ TQImage image;
+ // set entry 19 in the color table to yellow
+ image.setColor( 19, tqRgb(255,255,0) );
+ // set 8 bit pixel at (x,y) to value yellow (in color table)
+ *(image.scanLine(y) + x) = 19;
+ \endcode
+
+ 32-bpp images ignore the color table; instead, each pixel tqcontains
+ the RGB triplet. 24 bits contain the RGB value; the most
+ significant byte is reserved for the alpha buffer.
+
+ \code
+ TQImage image;
+ // sets 32 bit pixel at (x,y) to yellow.
+ uint *p = (uint *)image.scanLine(y) + x;
+ *p = tqRgb(255,255,0);
+ \endcode
+
+ On TQt/Embedded, scanlines are aligned to the pixel depth and may
+ be padded to any degree, while on all other platforms, the
+ scanlines are 32-bit aligned for all depths. The constructor
+ taking a \c{uchar*} argument always expects 32-bit aligned data.
+ On TQt/Embedded, an additional constructor allows the number of
+ bytes-per-line to be specified.
+
+ TQImage supports a variety of methods for getting information about
+ the image, for example, colorTable(), allGray(), isGrayscale(),
+ bitOrder(), bytesPerLine(), depth(), dotsPerMeterX() and
+ dotsPerMeterY(), hasAlphaBuffer(), numBytes(), numColors(), and
+ width() and height().
+
+ Pixel colors are retrieved with pixel() and set with setPixel().
+
+ TQImage also supports a number of functions for creating a new
+ image that is a transformed version of the original. For example,
+ copy(), convertBitOrder(), convertDepth(), createAlphaMask(),
+ createHeuristicMask(), mirror(), scale(), smoothScale(), swapRGB()
+ and xForm(). There are also functions for changing attributes of
+ an image in-place, for example, setAlphaBuffer(), setColor(),
+ setDotsPerMeterX() and setDotsPerMeterY() and setNumColors().
+
+ Images can be loaded and saved in the supported formats. Images
+ are saved to a file with save(). Images are loaded from a file
+ with load() (or in the constructor) or from an array of data with
+ loadFromData(). The lists of supported formats are available from
+ inputFormatList() and outputFormatList().
+
+ Strings of text may be added to images using setText().
+
+ The TQImage class uses explicit \link shclass.html sharing\endlink,
+ similar to that used by TQMemArray.
+
+ New image formats can be added as \link plugins-howto.html
+ plugins\endlink.
+
+ \sa TQImageIO TQPixmap \link shclass.html Shared Classes\endlink
+*/
+
+
+/*!
+ \enum TQImage::Endian
+
+ This enum type is used to describe the endianness of the CPU and
+ graphics hardware.
+
+ \value IgnoreEndian Endianness does not matter. Useful for some
+ operations that are independent of endianness.
+ \value BigEndian Network byte order, as on SPARC and Motorola CPUs.
+ \value LittleEndian PC/Alpha byte order.
+*/
+
+/*!
+ \enum TQt::ImageConversionFlags
+
+ The conversion flag is a bitwise-OR of the following values. The
+ options marked "(default)" are set if no other values from the
+ list are included (since the defaults are zero):
+
+ Color/Mono preference (ignored for TQBitmap)
+ \value AutoColor (default) - If the image has \link
+ TQImage::depth() depth\endlink 1 and tqcontains only
+ black and white pixels, the pixmap becomes monochrome.
+ \value ColorOnly The pixmap is dithered/converted to the
+ \link TQPixmap::defaultDepth() native display depth\endlink.
+ \value MonoOnly The pixmap becomes monochrome. If necessary,
+ it is dithered using the chosen dithering algorithm.
+
+ Dithering mode preference for RGB channels
+ \value DiffuseDither (default) - A high-quality dither.
+ \value OrderedDither A faster, more ordered dither.
+ \value ThresholdDither No dithering; closest color is used.
+
+ Dithering mode preference for alpha channel
+ \value ThresholdAlphaDither (default) - No dithering.
+ \value OrderedAlphaDither A faster, more ordered dither.
+ \value DiffuseAlphaDither A high-quality dither.
+ \value NoAlpha Not supported.
+
+ Color matching versus dithering preference
+ \value PreferDither (default when converting to a pixmap) - Always dither
+ 32-bit images when the image is converted to 8 bits.
+ \value AvoidDither (default when converting for the purpose of saving to
+ file) - Dither 32-bit images only if the image has more than 256
+ colors and it is being converted to 8 bits.
+ \value AutoDither Not supported.
+
+ The following are not values that are used directly, but masks for
+ the above classes:
+ \value ColorMode_Mask Mask for the color mode.
+ \value Dither_Mask Mask for the dithering mode for RGB channels.
+ \value AlphaDither_Mask Mask for the dithering mode for the alpha channel.
+ \value DitherMode_Mask Mask for the mode that determines the preference of
+ color matching versus dithering.
+
+ Using 0 as the conversion flag sets all the default options.
+*/
+
+#if defined(TQ_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001)
+#pragma message disable narrowptr
+#endif
+
+#ifndef TQT_NO_IMAGE_TEXT
+class TQImageDataMisc {
+public:
+ TQImageDataMisc() { }
+ TQImageDataMisc( const TQImageDataMisc& o ) :
+ text_lang(o.text_lang) { }
+
+ TQImageDataMisc& operator=(const TQImageDataMisc& o)
+ {
+ text_lang = o.text_lang;
+ return *this;
+ }
+ TQValueList<TQImageTextKeyLang> list()
+ {
+ return text_lang.keys();
+ }
+
+ TQStringList languages()
+ {
+ TQStringList r;
+ TQMap<TQImageTextKeyLang,TQString>::Iterator it = text_lang.begin();
+ for ( ; it != text_lang.end(); ++it ) {
+ r.remove( it.key().lang );
+ r.append( it.key().lang );
+ }
+ return r;
+ }
+ TQStringList keys()
+ {
+ TQStringList r;
+ TQMap<TQImageTextKeyLang,TQString>::Iterator it = text_lang.begin();
+ for ( ; it != text_lang.end(); ++it ) {
+ r.remove( it.key().key );
+ r.append( it.key().key );
+ }
+ return r;
+ }
+
+ TQMap<TQImageTextKeyLang,TQString> text_lang;
+};
+#endif // TQT_NO_IMAGE_TEXT
+
+
+
+/*****************************************************************************
+ TQImage member functions
+ *****************************************************************************/
+
+// table to flip bits
+static const uchar bitflip[256] = {
+ /*
+ open OUT, "| fmt";
+ for $i (0..255) {
+ print OUT (($i >> 7) & 0x01) | (($i >> 5) & 0x02) |
+ (($i >> 3) & 0x04) | (($i >> 1) & 0x08) |
+ (($i << 7) & 0x80) | (($i << 5) & 0x40) |
+ (($i << 3) & 0x20) | (($i << 1) & 0x10), ", ";
+ }
+ close OUT;
+ */
+ 0, 128, 64, 192, 32, 160, 96, 224, 16, 144, 80, 208, 48, 176, 112, 240,
+ 8, 136, 72, 200, 40, 168, 104, 232, 24, 152, 88, 216, 56, 184, 120, 248,
+ 4, 132, 68, 196, 36, 164, 100, 228, 20, 148, 84, 212, 52, 180, 116, 244,
+ 12, 140, 76, 204, 44, 172, 108, 236, 28, 156, 92, 220, 60, 188, 124, 252,
+ 2, 130, 66, 194, 34, 162, 98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
+ 10, 138, 74, 202, 42, 170, 106, 234, 26, 154, 90, 218, 58, 186, 122, 250,
+ 6, 134, 70, 198, 38, 166, 102, 230, 22, 150, 86, 214, 54, 182, 118, 246,
+ 14, 142, 78, 206, 46, 174, 110, 238, 30, 158, 94, 222, 62, 190, 126, 254,
+ 1, 129, 65, 193, 33, 161, 97, 225, 17, 145, 81, 209, 49, 177, 113, 241,
+ 9, 137, 73, 201, 41, 169, 105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
+ 5, 133, 69, 197, 37, 165, 101, 229, 21, 149, 85, 213, 53, 181, 117, 245,
+ 13, 141, 77, 205, 45, 173, 109, 237, 29, 157, 93, 221, 61, 189, 125, 253,
+ 3, 131, 67, 195, 35, 163, 99, 227, 19, 147, 83, 211, 51, 179, 115, 243,
+ 11, 139, 75, 203, 43, 171, 107, 235, 27, 155, 91, 219, 59, 187, 123, 251,
+ 7, 135, 71, 199, 39, 167, 103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
+ 15, 143, 79, 207, 47, 175, 111, 239, 31, 159, 95, 223, 63, 191, 127, 255
+};
+
+const uchar *qt_get_bitflip_array() // called from TQPixmap code
+{
+ return bitflip;
+}
+
+
+/*!
+ Constructs a null image.
+
+ \sa isNull()
+*/
+
+TQImage::TQImage()
+{
+ init();
+}
+
+/*!
+ Constructs an image with \a w width, \a h height, \a depth bits
+ per pixel, \a numColors colors and bit order \a bitOrder.
+
+ Using this constructor is the same as first constructing a null
+ image and then calling the create() function.
+
+ \sa create()
+*/
+
+TQImage::TQImage( int w, int h, int depth, int numColors, Endian bitOrder )
+{
+ init();
+ create( w, h, depth, numColors, bitOrder );
+}
+
+/*!
+ Constructs an image with size \a size pixels, depth \a depth bits,
+ \a numColors and \a bitOrder endianness.
+
+ Using this constructor is the same as first constructing a null
+ image and then calling the create() function.
+
+ \sa create()
+*/
+TQImage::TQImage( const TQSize& size, int depth, int numColors, Endian bitOrder )
+{
+ init();
+ create( size, depth, numColors, bitOrder );
+}
+
+#ifndef TQT_NO_IMAGEIO
+/*!
+ Constructs an image and tries to load the image from the file \a
+ fileName.
+
+ If \a format is specified, the loader attempts to read the image
+ using the specified format. If \a format is not specified (which
+ is the default), the loader reads a few bytes from the header to
+ guess the file format.
+
+ If the loading of the image failed, this object is a \link
+ isNull() null\endlink image.
+
+ The TQImageIO documentation lists the supported image formats and
+ explains how to add extra formats.
+
+ \sa load() isNull() TQImageIO
+*/
+
+TQImage::TQImage( const TQString &fileName, const char* format )
+{
+ init();
+ load( fileName, format );
+}
+
+#ifndef TQT_NO_IMAGEIO_XPM
+// helper
+static void read_xpm_image_or_array( TQImageIO *, const char * const *, TQImage & );
+#endif
+/*!
+ Constructs an image from \a xpm, which must be a valid XPM image.
+
+ Errors are silently ignored.
+
+ Note that it's possible to squeeze the XPM variable a little bit
+ by using an unusual declaration:
+
+ \code
+ static const char * const start_xpm[]={
+ "16 15 8 1",
+ "a c #cec6bd",
+ ....
+ \endcode
+
+ The extra \c const makes the entire definition read-only, which is
+ slightly more efficient (e.g. when the code is in a shared
+ library) and ROMable when the application is to be stored in ROM.
+*/
+
+TQImage::TQImage( const char * const xpm[] )
+{
+ init();
+#ifndef TQT_NO_IMAGEIO_XPM
+ read_xpm_image_or_array( 0, xpm, *this );
+#else
+ // We use a qFatal rather than disabling the whole function, as this
+ // constructor may be ambiguous.
+ qFatal("XPM not supported");
+#endif
+}
+
+/*!
+ Constructs an image from the binary data \a array. It tries to
+ guess the file format.
+
+ If the loading of the image failed, this object is a \link
+ isNull() null\endlink image.
+
+ \sa loadFromData() isNull() imageFormat()
+*/
+TQImage::TQImage( const TQByteArray &array )
+{
+ init();
+ loadFromData(array);
+}
+#endif //TQT_NO_IMAGEIO
+
+
+/*!
+ Constructs a \link shclass.html shallow copy\endlink of \a image.
+*/
+
+TQImage::TQImage( const TQImage &image )
+{
+ data = image.data;
+ data->ref();
+}
+
+/*!
+ Constructs an image \a w pixels wide, \a h pixels high with a
+ color depth of \a depth, that uses an existing memory buffer, \a
+ yourdata. The buffer must remain valid throughout the life of the
+ TQImage. The image does not delete the buffer at destruction.
+
+ If \a colortable is 0, a color table sufficient for \a numColors
+ will be allocated (and destructed later).
+
+ Note that \a yourdata must be 32-bit aligned.
+
+ The endianness is given in \a bitOrder.
+*/
+TQImage::TQImage( uchar* yourdata, int w, int h, int depth,
+ TQRgb* colortable, int numColors,
+ Endian bitOrder )
+{
+ init();
+ int bpl = ((w*depth+31)/32)*4; // bytes per scanline
+ if ( w <= 0 || h <= 0 || depth <= 0 || numColors < 0
+ || INT_MAX / sizeof(uchar *) < uint(h)
+ || INT_MAX / uint(depth) < uint(w)
+ || bpl <= 0
+ || INT_MAX / uint(bpl) < uint(h) )
+ return; // invalid parameter(s)
+ data->w = w;
+ data->h = h;
+ data->d = depth;
+ data->ncols = depth != 32 ? numColors : 0;
+ if ( !yourdata )
+ return; // Image header info can be saved without needing to allocate memory.
+ data->nbytes = bpl*h;
+ if ( colortable || !data->ncols ) {
+ data->ctbl = colortable;
+ data->ctbl_mine = FALSE;
+ } else {
+ // calloc since we realloc, etc. later (ick)
+ data->ctbl = (TQRgb*)calloc( data->ncols*sizeof(TQRgb), data->ncols );
+ TQ_CHECK_PTR(data->ctbl);
+ data->ctbl_mine = TRUE;
+ }
+ uchar** jt = (uchar**)malloc(h*sizeof(uchar*));
+ TQ_CHECK_PTR(jt);
+ for (int j=0; j<h; j++) {
+ jt[j] = yourdata+j*bpl;
+ }
+ data->bits = jt;
+ data->bitordr = bitOrder;
+}
+
+#ifdef TQ_WS_TQWS
+
+/*!
+ Constructs an image that uses an existing memory buffer. The
+ buffer must remain valid for the life of the TQImage. The image
+ does not delete the buffer at destruction. The buffer is passed as
+ \a yourdata. The image's width is \a w and its height is \a h. The
+ color depth is \a depth. \a bpl specifies the number of bytes per
+ line.
+
+ If \a colortable is 0, a color table sufficient for \a numColors
+ will be allocated (and destructed later).
+
+ The endianness is specified by \a bitOrder.
+
+ \warning This constructor is only available on TQt/Embedded.
+*/
+TQImage::TQImage( uchar* yourdata, int w, int h, int depth,
+ int bpl, TQRgb* colortable, int numColors,
+ Endian bitOrder )
+{
+ init();
+ if ( !yourdata || w <= 0 || h <= 0 || depth <= 0 || numColors < 0
+ || INT_MAX / sizeof(uchar *) < uint(h)
+ || INT_MAX / uint(bpl) < uint(h)
+ )
+ return; // invalid parameter(s)
+ data->w = w;
+ data->h = h;
+ data->d = depth;
+ data->ncols = numColors;
+ data->nbytes = bpl * h;
+ if ( colortable || !numColors ) {
+ data->ctbl = colortable;
+ data->ctbl_mine = FALSE;
+ } else {
+ // calloc since we realloc, etc. later (ick)
+ data->ctbl = (TQRgb*)calloc( numColors*sizeof(TQRgb), numColors );
+ TQ_CHECK_PTR(data->ctbl);
+ data->ctbl_mine = TRUE;
+ }
+ uchar** jt = (uchar**)malloc(h*sizeof(uchar*));
+ TQ_CHECK_PTR(jt);
+ for (int j=0; j<h; j++) {
+ jt[j] = yourdata+j*bpl;
+ }
+ data->bits = jt;
+ data->bitordr = bitOrder;
+}
+#endif // TQ_WS_TQWS
+
+/*!
+ Destroys the image and cleans up.
+*/
+
+TQImage::~TQImage()
+{
+ if ( data && data->deref() ) {
+ reset();
+ delete data;
+ }
+}
+
+
+
+
+/*! Convenience function. Gets the data associated with the absolute
+ name \a abs_name from the default mime source factory and decodes it
+ to an image.
+
+ \sa TQMimeSourceFactory, TQImage::fromMimeSource(), TQImageDrag::decode()
+*/
+#ifndef TQT_NO_MIME
+TQImage TQImage::fromMimeSource( const TQString &abs_name )
+{
+ const TQMimeSource *m = TQMimeSourceFactory::defaultFactory()->data( abs_name );
+ if ( !m ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQImage::fromMimeSource: Cannot find image \"%s\" in the mime source factory", abs_name.latin1() );
+#endif
+ return TQImage();
+ }
+ TQImage img;
+ TQImageDrag::decode( m, img );
+ return img;
+}
+#endif
+
+
+/*!
+ Assigns a \link shclass.html shallow copy\endlink of \a image to
+ this image and returns a reference to this image.
+
+ \sa copy()
+*/
+
+TQImage &TQImage::operator=( const TQImage &image )
+{
+ image.data->ref(); // avoid 'x = x'
+ if ( data->deref() ) {
+ reset();
+ delete data;
+ }
+ data = image.data;
+ return *this;
+}
+
+/*!
+ \overload
+
+ Sets the image bits to the \a pixmap contents and returns a
+ reference to the image.
+
+ If the image shares data with other images, it will first
+ dereference the shared data.
+
+ Makes a call to TQPixmap::convertToImage().
+*/
+
+TQImage &TQImage::operator=( const TQPixmap &pixmap )
+{
+ *this = pixmap.convertToImage();
+ return *this;
+}
+
+/*!
+ Detaches from shared image data and makes sure that this image is
+ the only one referring to the data.
+
+ If multiple images share common data, this image makes a copy of
+ the data and detaches itself from the sharing mechanism.
+ Nothing is done if there is just a single reference.
+
+ \sa copy()
+*/
+
+void TQImage::detach()
+{
+ if ( data->count != 1 )
+ *this = copy();
+}
+
+/*!
+ Returns a \link shclass.html deep copy\endlink of the image.
+
+ \sa detach()
+*/
+
+TQImage TQImage::copy() const
+{
+ if ( isNull() ) {
+ // maintain the fields of invalid TQImages when copied
+ return TQImage( 0, width(), height(), depth(), colorTable(), numColors(), bitOrder() );
+ } else {
+ TQImage image;
+ image.create( width(), height(), depth(), numColors(), bitOrder() );
+#ifdef TQ_WS_TQWS
+ // TQt/Embedded can create images with non-default bpl
+ // make sure we don't crash.
+ if ( image.numBytes() != numBytes() )
+ for ( int i = 0; i < height(); i++ )
+ memcpy( image.scanLine(i), scanLine(i), image.bytesPerLine() );
+ else
+#endif
+ memcpy( image.bits(), bits(), numBytes() );
+ memcpy( image.colorTable(), colorTable(), numColors() * sizeof(TQRgb) );
+ image.setAlphaBuffer( hasAlphaBuffer() );
+ image.data->dpmx = dotsPerMeterX();
+ image.data->dpmy = dotsPerMeterY();
+ image.data->offset = offset();
+#ifndef TQT_NO_IMAGE_TEXT
+ if ( data->misc ) {
+ image.data->misc = new TQImageDataMisc;
+ *image.data->misc = misc();
+ }
+#endif
+ return image;
+ }
+}
+
+/*!
+ \overload
+
+ Returns a \link shclass.html deep copy\endlink of a sub-area of
+ the image.
+
+ The returned image is always \a w by \a h pixels in size, and is
+ copied from position \a x, \a y in this image. In areas beyond
+ this image pixels are filled with pixel 0.
+
+ If the image needs to be modified to fit in a lower-resolution
+ result (e.g. converting from 32-bit to 8-bit), use the \a
+ conversion_flags to specify how you'd prefer this to happen.
+
+ \sa bitBlt() TQt::ImageConversionFlags
+*/
+
+TQImage TQImage::copy(int x, int y, int w, int h, int conversion_flags) const
+{
+ int dx = 0;
+ int dy = 0;
+ if ( w <= 0 || h <= 0 ) return TQImage(); // Nothing to copy
+
+ TQImage image( w, h, depth(), numColors(), bitOrder() );
+
+ if ( x < 0 || y < 0 || x + w > width() || y + h > height() ) {
+ // bitBlt will not cover entire image - clear it.
+ // ### should deal with each side separately for efficiency
+ image.fill(0);
+ if ( x < 0 ) {
+ dx = -x;
+ x = 0;
+ }
+ if ( y < 0 ) {
+ dy = -y;
+ y = 0;
+ }
+ }
+
+ bool has_alpha = hasAlphaBuffer();
+ if ( has_alpha ) {
+ // alpha channel should be only copied, not used by bitBlt(), and
+ // this is mutable, we will restore the image state before returning
+ TQImage *that = (TQImage *) this;
+ that->setAlphaBuffer( FALSE );
+ }
+ memcpy( image.colorTable(), colorTable(), numColors()*sizeof(TQRgb) );
+ bitBlt( &image, dx, dy, this, x, y, -1, -1, conversion_flags );
+ if ( has_alpha ) {
+ // restore image state
+ TQImage *that = (TQImage *) this;
+ that->setAlphaBuffer( TRUE );
+ }
+ image.setAlphaBuffer(hasAlphaBuffer());
+ image.data->dpmx = dotsPerMeterX();
+ image.data->dpmy = dotsPerMeterY();
+ image.data->offset = offset();
+#ifndef TQT_NO_IMAGE_TEXT
+ if ( data->misc ) {
+ image.data->misc = new TQImageDataMisc;
+ *image.data->misc = misc();
+ }
+#endif
+ return image;
+}
+
+/*!
+ \overload TQImage TQImage::copy(const TQRect& r) const
+
+ Returns a \link shclass.html deep copy\endlink of a sub-area of
+ the image.
+
+ The returned image always has the size of the rectangle \a r. In
+ areas beyond this image pixels are filled with pixel 0.
+*/
+
+/*!
+ \fn bool TQImage::isNull() const
+
+ Returns TRUE if it is a null image; otherwise returns FALSE.
+
+ A null image has all parameters set to zero and no allocated data.
+*/
+
+
+/*!
+ \fn int TQImage::width() const
+
+ Returns the width of the image.
+
+ \sa height() size() rect()
+*/
+
+/*!
+ \fn int TQImage::height() const
+
+ Returns the height of the image.
+
+ \sa width() size() rect()
+*/
+
+/*!
+ \fn TQSize TQImage::size() const
+
+ Returns the size of the image, i.e. its width and height.
+
+ \sa width() height() rect()
+*/
+
+/*!
+ \fn TQRect TQImage::rect() const
+
+ Returns the enclosing rectangle (0, 0, width(), height()) of the
+ image.
+
+ \sa width() height() size()
+*/
+
+/*!
+ \fn int TQImage::depth() const
+
+ Returns the depth of the image.
+
+ The image depth is the number of bits used to encode a single
+ pixel, also called bits per pixel (bpp) or bit planes of an image.
+
+ The supported depths are 1, 8, 16 (TQt/Embedded only) and 32.
+
+ \sa convertDepth()
+*/
+
+/*!
+ \fn int TQImage::numColors() const
+
+ Returns the size of the color table for the image.
+
+ Notice that numColors() returns 0 for 16-bpp (TQt/Embedded only)
+ and 32-bpp images because these images do not use color tables,
+ but instead encode pixel values as RGB triplets.
+
+ \sa setNumColors() colorTable()
+*/
+
+/*!
+ \fn TQImage::Endian TQImage::bitOrder() const
+
+ Returns the bit order for the image.
+
+ If it is a 1-bpp image, this function returns either
+ TQImage::BigEndian or TQImage::LittleEndian.
+
+ If it is not a 1-bpp image, this function returns
+ TQImage::IgnoreEndian.
+
+ \sa depth()
+*/
+
+/*!
+ \fn uchar **TQImage::jumpTable() const
+
+ Returns a pointer to the scanline pointer table.
+
+ This is the beginning of the data block for the image.
+
+ \sa bits() scanLine()
+*/
+
+/*!
+ \fn TQRgb *TQImage::colorTable() const
+
+ Returns a pointer to the color table.
+
+ \sa numColors()
+*/
+
+/*!
+ \fn int TQImage::numBytes() const
+
+ Returns the number of bytes occupied by the image data.
+
+ \sa bytesPerLine() bits()
+*/
+
+/*!
+ \fn int TQImage::bytesPerLine() const
+
+ Returns the number of bytes per image scanline. This is equivalent
+ to numBytes()/height().
+
+ \sa numBytes() scanLine()
+*/
+
+/*!
+ \fn TQRgb TQImage::color( int i ) const
+
+ Returns the color in the color table at index \a i. The first
+ color is at index 0.
+
+ A color value is an RGB triplet. Use the \link ::tqRed()
+ tqRed()\endlink, \link ::tqGreen() tqGreen()\endlink and \link
+ ::tqBlue() tqBlue()\endlink functions (defined in \c tqcolor.h) to
+ get the color value components.
+
+ \sa setColor() numColors() TQColor
+*/
+
+/*!
+ \fn void TQImage::setColor( int i, TQRgb c )
+
+ Sets a color in the color table at index \a i to \a c.
+
+ A color value is an RGB triplet. Use the \link ::tqRgb()
+ tqRgb()\endlink function (defined in \c tqcolor.h) to make RGB
+ triplets.
+
+ \sa color() setNumColors() numColors()
+*/
+
+/*!
+ \fn uchar *TQImage::scanLine( int i ) const
+
+ Returns a pointer to the pixel data at the scanline with index \a
+ i. The first scanline is at index 0.
+
+ The scanline data is aligned on a 32-bit boundary.
+
+ \warning If you are accessing 32-bpp image data, cast the returned
+ pointer to \c{TQRgb*} (TQRgb has a 32-bit size) and use it to
+ read/write the pixel value. You cannot use the \c{uchar*} pointer
+ directly, because the pixel format depends on the byte order on
+ the underlying platform. Hint: use \link ::tqRed() tqRed()\endlink,
+ \link ::tqGreen() tqGreen()\endlink and \link ::tqBlue()
+ tqBlue()\endlink, etc. (tqcolor.h) to access the pixels.
+
+ \warning If you are accessing 16-bpp image data, you must handle
+ endianness yourself. (TQt/Embedded only)
+
+ \sa bytesPerLine() bits() jumpTable()
+*/
+
+/*!
+ \fn uchar *TQImage::bits() const
+
+ Returns a pointer to the first pixel data. This is equivalent to
+ scanLine(0).
+
+ \sa numBytes() scanLine() jumpTable()
+*/
+
+
+
+void TQImage::warningIndexRange( const char *func, int i )
+{
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage::%s: Index %d out of range", func, i );
+#else
+ TQ_UNUSED( func )
+ TQ_UNUSED( i )
+#endif
+}
+
+
+/*!
+ Resets all image parameters and deallocates the image data.
+*/
+
+void TQImage::reset()
+{
+ freeBits();
+ setNumColors( 0 );
+#ifndef TQT_NO_IMAGE_TEXT
+ delete data->misc;
+#endif
+ reinit();
+}
+
+
+/*!
+ Fills the entire image with the pixel value \a pixel.
+
+ If the \link depth() depth\endlink of this image is 1, only the
+ lowest bit is used. If you say fill(0), fill(2), etc., the image
+ is filled with 0s. If you say fill(1), fill(3), etc., the image is
+ filled with 1s. If the depth is 8, the lowest 8 bits are used.
+
+ If the depth is 32 and the image has no alpha buffer, the \a pixel
+ value is written to each pixel in the image. If the image has an
+ alpha buffer, only the 24 RGB bits are set and the upper 8 bits
+ (alpha value) are left unchanged.
+
+ Note: TQImage::pixel() returns the color of the pixel at the given
+ coordinates; TQColor::pixel() returns the pixel value of the
+ underlying window system (essentially an index value), so normally
+ you will want to use TQImage::pixel() to use a color from an
+ existing image or TQColor::rgb() to use a specific color.
+
+ \sa invertPixels() depth() hasAlphaBuffer() create()
+*/
+
+void TQImage::fill( uint pixel )
+{
+ if ( depth() == 1 || depth() == 8 ) {
+ if ( depth() == 1 ) {
+ if ( pixel & 1 )
+ pixel = 0xffffffff;
+ else
+ pixel = 0;
+ } else {
+ uint c = pixel & 0xff;
+ pixel = c | ((c << 8) & 0xff00) | ((c << 16) & 0xff0000) |
+ ((c << 24) & 0xff000000);
+ }
+ int bpl = bytesPerLine();
+ for ( int i=0; i<height(); i++ )
+ memset( scanLine(i), pixel, bpl );
+#ifndef TQT_NO_IMAGE_16_BIT
+ } else if ( depth() == 16 ) {
+ for ( int i=0; i<height(); i++ ) {
+ //optimize with 32-bit writes, since image is always aligned
+ uint *p = (uint *)scanLine(i);
+ uint *end = (uint*)(((ushort*)p) + width());
+ uint fill;
+ ushort *f = (ushort*)&fill;
+ f[0]=pixel;
+ f[1]=pixel;
+ while ( p < end )
+ *p++ = fill;
+ }
+#endif // TQT_NO_IMAGE_16_BIT
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ } else if ( depth() == 32 ) {
+ if ( hasAlphaBuffer() ) {
+ pixel &= 0x00ffffff;
+ for ( int i=0; i<height(); i++ ) {
+ uint *p = (uint *)scanLine(i);
+ uint *end = p + width();
+ while ( p < end ) {
+ *p = (*p & 0xff000000) | pixel;
+ p++;
+ }
+ }
+ } else {
+ for ( int i=0; i<height(); i++ ) {
+ uint *p = (uint *)scanLine(i);
+ uint *end = p + width();
+ while ( p < end )
+ *p++ = pixel;
+ }
+ }
+#endif // TQT_NO_IMAGE_TRUECOLOR
+ }
+}
+
+
+/*!
+ Inverts all pixel values in the image.
+
+ If the depth is 32: if \a invertAlpha is TRUE, the alpha bits are
+ also inverted, otherwise they are left unchanged.
+
+ If the depth is not 32, the argument \a invertAlpha has no
+ meaning.
+
+ Note that inverting an 8-bit image means to tqreplace all pixels
+ using color index \e i with a pixel using color index 255 minus \e
+ i. Similarly for a 1-bit image. The color table is not changed.
+
+ \sa fill() depth() hasAlphaBuffer()
+*/
+
+void TQImage::invertPixels( bool invertAlpha )
+{
+ TQ_UINT32 n = numBytes();
+ if ( n % 4 ) {
+ TQ_UINT8 *p = (TQ_UINT8*)bits();
+ TQ_UINT8 *end = p + n;
+ while ( p < end )
+ *p++ ^= 0xff;
+ } else {
+ TQ_UINT32 *p = (TQ_UINT32*)bits();
+ TQ_UINT32 *end = p + n/4;
+ uint xorbits = invertAlpha && depth() == 32 ? 0x00ffffff : 0xffffffff;
+ while ( p < end )
+ *p++ ^= xorbits;
+ }
+}
+
+
+/*!
+ Determines the host computer byte order. Returns
+ TQImage::LittleEndian (LSB first) or TQImage::BigEndian (MSB first).
+
+ \sa systemBitOrder()
+*/
+
+TQImage::Endian TQImage::systemByteOrder()
+{
+ static Endian sbo = IgnoreEndian;
+ if ( sbo == IgnoreEndian ) { // initialize
+ int ws;
+ bool be;
+ qSysInfo( &ws, &be );
+ sbo = be ? BigEndian : LittleEndian;
+ }
+ return sbo;
+}
+
+
+#if defined(TQ_WS_X11)
+#include <X11/Xlib.h> // needed for systemBitOrder
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#if defined(TQ_OS_WIN32)
+#undef open
+#undef close
+#undef read
+#undef write
+#endif
+#endif
+
+// POSIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+/*!
+ Determines the bit order of the display hardware. Returns
+ TQImage::LittleEndian (LSB first) or TQImage::BigEndian (MSB first).
+
+ \sa systemByteOrder()
+*/
+
+TQImage::Endian TQImage::systemBitOrder()
+{
+#if defined(TQ_WS_X11)
+ return BitmapBitOrder(qt_xdisplay()) == MSBFirst ? BigEndian :LittleEndian;
+#else
+ return BigEndian;
+#endif
+}
+
+
+/*!
+ Resizes the color table to \a numColors colors.
+
+ If the color table is expanded all the extra colors will be set to
+ black (RGB 0,0,0).
+
+ \sa numColors() color() setColor() colorTable()
+*/
+
+void TQImage::setNumColors( int numColors )
+{
+ if ( numColors == data->ncols )
+ return;
+ if ( numColors == 0 ) { // use no color table
+ if ( data->ctbl ) {
+ if ( data->ctbl_mine )
+ free( data->ctbl );
+ else
+ data->ctbl_mine = TRUE;
+ data->ctbl = 0;
+ }
+ data->ncols = 0;
+ return;
+ }
+ if ( data->ctbl && data->ctbl_mine ) { // already has color table
+ data->ctbl = (TQRgb*)realloc( data->ctbl, numColors*sizeof(TQRgb) );
+ if ( data->ctbl && numColors > data->ncols )
+ memset( (char *)&data->ctbl[data->ncols], 0,
+ (numColors-data->ncols)*sizeof(TQRgb) );
+ } else { // create new color table
+ data->ctbl = (TQRgb*)calloc( numColors*sizeof(TQRgb), 1 );
+ TQ_CHECK_PTR(data->ctbl);
+ data->ctbl_mine = TRUE;
+ }
+ data->ncols = data->ctbl == 0 ? 0 : numColors;
+}
+
+
+/*!
+ \fn bool TQImage::hasAlphaBuffer() const
+
+ Returns TRUE if alpha buffer mode is enabled; otherwise returns
+ FALSE.
+
+ \sa setAlphaBuffer()
+*/
+
+/*!
+ Enables alpha buffer mode if \a enable is TRUE, otherwise disables
+ it. The default setting is disabled.
+
+ An 8-bpp image has 8-bit pixels. A pixel is an index into the
+ \link color() color table\endlink, which tqcontains 32-bit color
+ values. In a 32-bpp image, the 32-bit pixels are the color values.
+
+ This 32-bit value is encoded as follows: The lower 24 bits are
+ used for the red, green, and blue components. The upper 8 bits
+ contain the alpha component.
+
+ The alpha component specifies the transparency of a pixel. 0 means
+ completely transtqparent and 255 means opaque. The alpha component
+ is ignored if you do not enable alpha buffer mode.
+
+ The alpha buffer is used to set a tqmask when a TQImage is translated
+ to a TQPixmap.
+
+ \sa hasAlphaBuffer() createAlphaMask()
+*/
+
+void TQImage::setAlphaBuffer( bool enable )
+{
+ data->alpha = enable;
+}
+
+
+/*!
+ Sets the image \a width, \a height, \a depth, its number of colors
+ (in \a numColors), and bit order. Returns TRUE if successful, or
+ FALSE if the parameters are incorrect or if memory cannot be
+ allocated.
+
+ The \a width and \a height is limited to 32767. \a depth must be
+ 1, 8, or 32. If \a depth is 1, \a bitOrder must be set to
+ either TQImage::LittleEndian or TQImage::BigEndian. For other depths
+ \a bitOrder must be TQImage::IgnoreEndian.
+
+ This function allocates a color table and a buffer for the image
+ data. The image data is not initialized.
+
+ The image buffer is allocated as a single block that consists of a
+ table of \link scanLine() scanline\endlink pointers (jumpTable())
+ and the image data (bits()).
+
+ \sa fill() width() height() depth() numColors() bitOrder()
+ jumpTable() scanLine() bits() bytesPerLine() numBytes()
+*/
+
+bool TQImage::create( int width, int height, int depth, int numColors,
+ Endian bitOrder )
+{
+ reset(); // reset old data
+ if ( width <= 0 || height <= 0 || depth <= 0 || numColors < 0 )
+ return FALSE; // invalid parameter(s)
+ if ( depth == 1 && bitOrder == IgnoreEndian ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage::create: Bit order is required for 1 bpp images" );
+#endif
+ return FALSE;
+ }
+ if ( depth != 1 )
+ bitOrder = IgnoreEndian;
+
+#if defined(TQT_CHECK_RANGE)
+ if ( depth == 24 )
+ qWarning( "TQImage::create: 24-bpp images no longer supported, "
+ "use 32-bpp instead" );
+#endif
+ switch ( depth ) {
+ case 1:
+ case 8:
+#ifndef TQT_NO_IMAGE_16_BIT
+ case 16:
+#endif
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ case 32:
+#endif
+ break;
+ default: // invalid depth
+ return FALSE;
+ }
+
+ if ( depth == 32 )
+ numColors = 0;
+ setNumColors( numColors );
+ if ( data->ncols != numColors ) // could not alloc color table
+ return FALSE;
+
+ if ( INT_MAX / uint(depth) < uint(width) ) { // sanity check for potential overflow
+ setNumColors( 0 );
+ return FALSE;
+ }
+// TQt/Embedded doesn't waste memory on unnecessary padding.
+#ifdef TQ_WS_TQWS
+ const int bpl = (width*depth+7)/8; // bytes per scanline
+ const int pad = 0;
+#else
+ const int bpl = ((width*depth+31)/32)*4; // bytes per scanline
+ // #### WWA: shouldn't this be (width*depth+7)/8:
+ const int pad = bpl - (width*depth)/8; // pad with zeros
+#endif
+ if ( INT_MAX / uint(bpl) < uint(height)
+ || bpl < 0
+ || INT_MAX / sizeof(uchar *) < uint(height) ) { // sanity check for potential overflow
+ setNumColors( 0 );
+ return FALSE;
+ }
+ int nbytes = bpl*height; // image size
+ int ptbl = height*sizeof(uchar*); // pointer table size
+ int size = nbytes + ptbl; // total size of data block
+ uchar **p = (uchar **)malloc( size ); // alloc image bits
+ TQ_CHECK_PTR(p);
+ if ( !p ) { // no memory
+ setNumColors( 0 );
+ return FALSE;
+ }
+ data->w = width;
+ data->h = height;
+ data->d = depth;
+ data->nbytes = nbytes;
+ data->bitordr = bitOrder;
+ data->bits = p; // set image pointer
+ //uchar *d = (uchar*)p + ptbl; // setup scanline pointers
+ uchar *d = (uchar*)(p + height); // setup scanline pointers
+ while ( height-- ) {
+ *p++ = d;
+ if ( pad )
+ memset( d+bpl-pad, 0, pad );
+ d += bpl;
+ }
+ return TRUE;
+}
+
+/*!
+ \overload bool TQImage::create( const TQSize&, int depth, int numColors, Endian bitOrder )
+*/
+bool TQImage::create( const TQSize& size, int depth, int numColors,
+ TQImage::Endian bitOrder )
+{
+ return create(size.width(), size.height(), depth, numColors, bitOrder);
+}
+
+/*!
+ \internal
+ Initializes the image data structure.
+*/
+
+void TQImage::init()
+{
+ data = new TQImageData;
+ TQ_CHECK_PTR( data );
+ reinit();
+}
+
+void TQImage::reinit()
+{
+ data->w = data->h = data->d = data->ncols = 0;
+ data->nbytes = 0;
+ data->ctbl = 0;
+ data->bits = 0;
+ data->bitordr = TQImage::IgnoreEndian;
+ data->alpha = FALSE;
+#ifndef TQT_NO_IMAGE_TEXT
+ data->misc = 0;
+#endif
+ data->dpmx = 0;
+ data->dpmy = 0;
+ data->offset = TQPoint(0,0);
+}
+
+/*!
+ \internal
+ Deallocates the image data and sets the bits pointer to 0.
+*/
+
+void TQImage::freeBits()
+{
+ if ( data->bits ) { // dealloc image bits
+ free( data->bits );
+ data->bits = 0;
+ }
+}
+
+
+/*****************************************************************************
+ Internal routines for converting image depth.
+ *****************************************************************************/
+
+//
+// convert_32_to_8: Converts a 32 bits depth (true color) to an 8 bit
+// image with a colormap. If the 32 bit image has more than 256 colors,
+// we convert the red,green and blue bytes into a single byte encoded
+// as 6 shades of each of red, green and blue.
+//
+// if dithering is needed, only 1 color at most is available for alpha.
+//
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+struct TQRgbMap {
+ TQRgbMap() : rgb(0xffffffff) { }
+ bool used() const { return rgb!=0xffffffff; }
+ uchar pix;
+ TQRgb rgb;
+};
+
+static bool convert_32_to_8( const TQImage *src, TQImage *dst, int conversion_flags, TQRgb* palette=0, int palette_count=0 )
+{
+ register TQRgb *p;
+ uchar *b;
+ bool do_quant = FALSE;
+ int y, x;
+
+ if ( !dst->create(src->width(), src->height(), 8, 256) )
+ return FALSE;
+
+ const int tablesize = 997; // prime
+ TQRgbMap table[tablesize];
+ int pix=0;
+ TQRgb atqmask = src->hasAlphaBuffer() ? 0xffffffff : 0x00ffffff;
+ if ( src->hasAlphaBuffer() )
+ dst->setAlphaBuffer(TRUE);
+
+ if ( palette ) {
+ // Preload palette into table.
+
+ p = palette;
+ // Almost same code as pixel insertion below
+ while ( palette_count-- > 0 ) {
+ // Find in table...
+ int hash = (*p & atqmask) % tablesize;
+ for (;;) {
+ if ( table[hash].used() ) {
+ if ( table[hash].rgb == (*p & atqmask) ) {
+ // Found previous insertion - use it
+ break;
+ } else {
+ // Keep searching...
+ if (++hash == tablesize) hash = 0;
+ }
+ } else {
+ // Cannot be in table
+ TQ_ASSERT ( pix != 256 ); // too many colors
+ // Insert into table at this unused position
+ dst->setColor( pix, (*p & atqmask) );
+ table[hash].pix = pix++;
+ table[hash].rgb = *p & atqmask;
+ break;
+ }
+ }
+ p++;
+ }
+ }
+
+ if ( (conversion_flags & TQt::DitherMode_Mask) == TQt::PreferDither ) {
+ do_quant = TRUE;
+ } else {
+ for ( y=0; y<src->height(); y++ ) { // check if <= 256 colors
+ p = (TQRgb *)src->scanLine(y);
+ b = dst->scanLine(y);
+ x = src->width();
+ while ( x-- ) {
+ // Find in table...
+ int hash = (*p & atqmask) % tablesize;
+ for (;;) {
+ if ( table[hash].used() ) {
+ if ( table[hash].rgb == (*p & atqmask) ) {
+ // Found previous insertion - use it
+ break;
+ } else {
+ // Keep searching...
+ if (++hash == tablesize) hash = 0;
+ }
+ } else {
+ // Cannot be in table
+ if ( pix == 256 ) { // too many colors
+ do_quant = TRUE;
+ // Break right out
+ x = 0;
+ y = src->height();
+ } else {
+ // Insert into table at this unused position
+ dst->setColor( pix, (*p & atqmask) );
+ table[hash].pix = pix++;
+ table[hash].rgb = (*p & atqmask);
+ }
+ break;
+ }
+ }
+ *b++ = table[hash].pix; // May occur once incorrectly
+ p++;
+ }
+ }
+ }
+ int ncols = do_quant ? 256 : pix;
+
+ static uint bm[16][16];
+ static int init=0;
+ if (!init) {
+ // Build a Bayer Matrix for dithering
+
+ init = 1;
+ int n, i, j;
+
+ bm[0][0]=0;
+
+ for (n=1; n<16; n*=2) {
+ for (i=0; i<n; i++) {
+ for (j=0; j<n; j++) {
+ bm[i][j]*=4;
+ bm[i+n][j]=bm[i][j]+2;
+ bm[i][j+n]=bm[i][j]+3;
+ bm[i+n][j+n]=bm[i][j]+1;
+ }
+ }
+ }
+
+ for (i=0; i<16; i++)
+ for (j=0; j<16; j++)
+ bm[i][j]<<=8;
+ }
+
+ dst->setNumColors( ncols );
+
+ if ( do_quant ) { // quantization needed
+
+#define MAX_R 5
+#define MAX_G 5
+#define MAX_B 5
+#define INDEXOF(r,g,b) (((r)*(MAX_G+1)+(g))*(MAX_B+1)+(b))
+
+ int rc, gc, bc;
+
+ for ( rc=0; rc<=MAX_R; rc++ ) // build 6x6x6 color cube
+ for ( gc=0; gc<=MAX_G; gc++ )
+ for ( bc=0; bc<=MAX_B; bc++ ) {
+ dst->setColor( INDEXOF(rc,gc,bc),
+ (atqmask&0xff000000)
+ | tqRgb( rc*255/MAX_R, gc*255/MAX_G, bc*255/MAX_B ) );
+ }
+
+ int sw = src->width();
+
+ int* line1[3];
+ int* line2[3];
+ int* pv[3];
+ if ( ( conversion_flags & TQt::Dither_Mask ) == TQt::DiffuseDither ) {
+ line1[0] = new int[src->width()];
+ line2[0] = new int[src->width()];
+ line1[1] = new int[src->width()];
+ line2[1] = new int[src->width()];
+ line1[2] = new int[src->width()];
+ line2[2] = new int[src->width()];
+ pv[0] = new int[sw];
+ pv[1] = new int[sw];
+ pv[2] = new int[sw];
+ }
+
+ for ( y=0; y < src->height(); y++ ) {
+ p = (TQRgb *)src->scanLine(y);
+ b = dst->scanLine(y);
+ TQRgb *end = p + sw;
+
+ // perform quantization
+ if ( ( conversion_flags & TQt::Dither_Mask ) == TQt::ThresholdDither ) {
+#define DITHER(p,m) ((uchar) ((p * (m) + 127) / 255))
+ while ( p < end ) {
+ rc = tqRed( *p );
+ gc = tqGreen( *p );
+ bc = tqBlue( *p );
+
+ *b++ =
+ INDEXOF(
+ DITHER(rc, MAX_R),
+ DITHER(gc, MAX_G),
+ DITHER(bc, MAX_B)
+ );
+
+ p++;
+ }
+#undef DITHER
+ } else if ( ( conversion_flags & TQt::Dither_Mask ) == TQt::OrderedDither ) {
+#define DITHER(p,d,m) ((uchar) ((((256 * (m) + (m) + 1)) * (p) + (d)) / 65536 ))
+
+ int x = 0;
+ while ( p < end ) {
+ uint d = bm[y&15][x&15];
+
+ rc = tqRed( *p );
+ gc = tqGreen( *p );
+ bc = tqBlue( *p );
+
+ *b++ =
+ INDEXOF(
+ DITHER(rc, d, MAX_R),
+ DITHER(gc, d, MAX_G),
+ DITHER(bc, d, MAX_B)
+ );
+
+ p++;
+ x++;
+ }
+#undef DITHER
+ } else { // Diffuse
+ int endian = (TQImage::systemByteOrder() == TQImage::BigEndian);
+ int x;
+ uchar* q = src->scanLine(y);
+ uchar* q2 = src->scanLine(y+1 < src->height() ? y + 1 : 0);
+ for (int chan = 0; chan < 3; chan++) {
+ b = dst->scanLine(y);
+ int *l1 = (y&1) ? line2[chan] : line1[chan];
+ int *l2 = (y&1) ? line1[chan] : line2[chan];
+ if ( y == 0 ) {
+ for (int i=0; i<sw; i++)
+ l1[i] = q[i*4+chan+endian];
+ }
+ if ( y+1 < src->height() ) {
+ for (int i=0; i<sw; i++)
+ l2[i] = q2[i*4+chan+endian];
+ }
+ // Bi-directional error diffusion
+ if ( y&1 ) {
+ for (x=0; x<sw; x++) {
+ int pix = TQMAX(TQMIN(5, (l1[x] * 5 + 128)/ 255), 0);
+ int err = l1[x] - pix * 255 / 5;
+ pv[chan][x] = pix;
+
+ // Spread the error around...
+ if ( x+1<sw ) {
+ l1[x+1] += (err*7)>>4;
+ l2[x+1] += err>>4;
+ }
+ l2[x]+=(err*5)>>4;
+ if (x>1)
+ l2[x-1]+=(err*3)>>4;
+ }
+ } else {
+ for (x=sw; x-->0; ) {
+ int pix = TQMAX(TQMIN(5, (l1[x] * 5 + 128)/ 255), 0);
+ int err = l1[x] - pix * 255 / 5;
+ pv[chan][x] = pix;
+
+ // Spread the error around...
+ if ( x > 0 ) {
+ l1[x-1] += (err*7)>>4;
+ l2[x-1] += err>>4;
+ }
+ l2[x]+=(err*5)>>4;
+ if (x+1 < sw)
+ l2[x+1]+=(err*3)>>4;
+ }
+ }
+ }
+ if (endian) {
+ for (x=0; x<sw; x++) {
+ *b++ = INDEXOF(pv[0][x],pv[1][x],pv[2][x]);
+ }
+ } else {
+ for (x=0; x<sw; x++) {
+ *b++ = INDEXOF(pv[2][x],pv[1][x],pv[0][x]);
+ }
+ }
+ }
+ }
+
+#ifndef TQT_NO_IMAGE_DITHER_TO_1
+ if ( src->hasAlphaBuffer() ) {
+ const int trans = 216;
+ dst->setColor(trans, 0x00000000); // transtqparent
+ TQImage tqmask = src->createAlphaMask(conversion_flags);
+ uchar* m;
+ for ( y=0; y < src->height(); y++ ) {
+ uchar bit = 0x80;
+ m = tqmask.scanLine(y);
+ b = dst->scanLine(y);
+ int w = src->width();
+ for ( x = 0; x<w; x++ ) {
+ if ( !(*m&bit) )
+ b[x] = trans;
+ if (!(bit >>= 1)) {
+ bit = 0x80;
+ while ( x<w-1 && *++m == 0xff ) // skip chunks
+ x+=8;
+ }
+ }
+ }
+ }
+#endif
+
+ if ( ( conversion_flags & TQt::Dither_Mask ) == TQt::DiffuseDither ) {
+ delete [] line1[0];
+ delete [] line2[0];
+ delete [] line1[1];
+ delete [] line2[1];
+ delete [] line1[2];
+ delete [] line2[2];
+ delete [] pv[0];
+ delete [] pv[1];
+ delete [] pv[2];
+ }
+
+#undef MAX_R
+#undef MAX_G
+#undef MAX_B
+#undef INDEXOF
+
+ }
+
+ return TRUE;
+}
+
+
+static bool convert_8_to_32( const TQImage *src, TQImage *dst )
+{
+ if ( !dst->create(src->width(), src->height(), 32) )
+ return FALSE; // create failed
+ dst->setAlphaBuffer( src->hasAlphaBuffer() );
+ for ( int y=0; y<dst->height(); y++ ) { // for each scan line...
+ register uint *p = (uint *)dst->scanLine(y);
+ uchar *b = src->scanLine(y);
+ uint *end = p + dst->width();
+ while ( p < end )
+ *p++ = src->color(*b++);
+ }
+ return TRUE;
+}
+
+
+static bool convert_1_to_32( const TQImage *src, TQImage *dst )
+{
+ if ( !dst->create(src->width(), src->height(), 32) )
+ return FALSE; // could not create
+ dst->setAlphaBuffer( src->hasAlphaBuffer() );
+ for ( int y=0; y<dst->height(); y++ ) { // for each scan line...
+ register uint *p = (uint *)dst->scanLine(y);
+ uchar *b = src->scanLine(y);
+ int x;
+ if ( src->bitOrder() == TQImage::BigEndian ) {
+ for ( x=0; x<dst->width(); x++ ) {
+ *p++ = src->color( (*b >> (7 - (x & 7))) & 1 );
+ if ( (x & 7) == 7 )
+ b++;
+ }
+ } else {
+ for ( x=0; x<dst->width(); x++ ) {
+ *p++ = src->color( (*b >> (x & 7)) & 1 );
+ if ( (x & 7) == 7 )
+ b++;
+ }
+ }
+ }
+ return TRUE;
+}
+#endif // TQT_NO_IMAGE_TRUECOLOR
+
+static bool convert_1_to_8( const TQImage *src, TQImage *dst )
+{
+ if ( !dst->create(src->width(), src->height(), 8, 2) )
+ return FALSE; // something failed
+ dst->setAlphaBuffer( src->hasAlphaBuffer() );
+ if (src->numColors() >= 2) {
+ dst->setColor( 0, src->color(0) ); // copy color table
+ dst->setColor( 1, src->color(1) );
+ } else {
+ // Unlikely, but they do exist
+ if (src->numColors() >= 1)
+ dst->setColor( 0, src->color(0) );
+ else
+ dst->setColor( 0, 0xffffffff );
+ dst->setColor( 1, 0xff000000 );
+ }
+ for ( int y=0; y<dst->height(); y++ ) { // for each scan line...
+ register uchar *p = dst->scanLine(y);
+ uchar *b = src->scanLine(y);
+ int x;
+ if ( src->bitOrder() == TQImage::BigEndian ) {
+ for ( x=0; x<dst->width(); x++ ) {
+ *p++ = (*b >> (7 - (x & 7))) & 1;
+ if ( (x & 7) == 7 )
+ b++;
+ }
+ } else {
+ for ( x=0; x<dst->width(); x++ ) {
+ *p++ = (*b >> (x & 7)) & 1;
+ if ( (x & 7) == 7 )
+ b++;
+ }
+ }
+ }
+ return TRUE;
+}
+
+#ifndef TQT_NO_IMAGE_DITHER_TO_1
+//
+// dither_to_1: Uses selected dithering algorithm.
+//
+
+static bool dither_to_1( const TQImage *src, TQImage *dst,
+ int conversion_flags, bool fromalpha )
+{
+ if ( !dst->create(src->width(), src->height(), 1, 2, TQImage::BigEndian) )
+ return FALSE; // something failed
+
+ enum { Threshold, Ordered, Diffuse } dithermode;
+
+ if ( fromalpha ) {
+ if ( ( conversion_flags & TQt::AlphaDither_Mask ) == TQt::DiffuseAlphaDither )
+ dithermode = Diffuse;
+ else if ( ( conversion_flags & TQt::AlphaDither_Mask ) == TQt::OrderedAlphaDither )
+ dithermode = Ordered;
+ else
+ dithermode = Threshold;
+ } else {
+ if ( ( conversion_flags & TQt::Dither_Mask ) == TQt::ThresholdDither )
+ dithermode = Threshold;
+ else if ( ( conversion_flags & TQt::Dither_Mask ) == TQt::OrderedDither )
+ dithermode = Ordered;
+ else
+ dithermode = Diffuse;
+ }
+
+ dst->setColor( 0, tqRgb(255, 255, 255) );
+ dst->setColor( 1, tqRgb( 0, 0, 0) );
+ int w = src->width();
+ int h = src->height();
+ int d = src->depth();
+ uchar gray[256]; // gray map for 8 bit images
+ bool use_gray = d == 8;
+ if ( use_gray ) { // make gray map
+ if ( fromalpha ) {
+ // Alpha 0x00 -> 0 pixels (white)
+ // Alpha 0xFF -> 1 pixels (black)
+ for ( int i=0; i<src->numColors(); i++ )
+ gray[i] = (255 - (src->color(i) >> 24));
+ } else {
+ // Pixel 0x00 -> 1 pixels (black)
+ // Pixel 0xFF -> 0 pixels (white)
+ for ( int i=0; i<src->numColors(); i++ )
+ gray[i] = tqGray( src->color(i) & 0x00ffffff );
+ }
+ }
+
+ switch ( dithermode ) {
+ case Diffuse: {
+ int *line1 = new int[w];
+ int *line2 = new int[w];
+ int bmwidth = (w+7)/8;
+ if ( !(line1 && line2) )
+ return FALSE;
+ register uchar *p;
+ uchar *end;
+ int *b1, *b2;
+ int wbytes = w * (d/8);
+ p = src->bits();
+ end = p + wbytes;
+ b2 = line2;
+ if ( use_gray ) { // 8 bit image
+ while ( p < end )
+ *b2++ = gray[*p++];
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ } else { // 32 bit image
+ if ( fromalpha ) {
+ while ( p < end ) {
+ *b2++ = 255 - (*(uint*)p >> 24);
+ p += 4;
+ }
+ } else {
+ while ( p < end ) {
+ *b2++ = tqGray(*(uint*)p);
+ p += 4;
+ }
+ }
+#endif
+ }
+ int x, y;
+ for ( y=0; y<h; y++ ) { // for each scan line...
+ int *tmp = line1; line1 = line2; line2 = tmp;
+ bool not_last_line = y < h - 1;
+ if ( not_last_line ) { // calc. grayvals for next line
+ p = src->scanLine(y+1);
+ end = p + wbytes;
+ b2 = line2;
+ if ( use_gray ) { // 8 bit image
+ while ( p < end )
+ *b2++ = gray[*p++];
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ } else { // 24 bit image
+ if ( fromalpha ) {
+ while ( p < end ) {
+ *b2++ = 255 - (*(uint*)p >> 24);
+ p += 4;
+ }
+ } else {
+ while ( p < end ) {
+ *b2++ = tqGray(*(uint*)p);
+ p += 4;
+ }
+ }
+#endif
+ }
+ }
+
+ int err;
+ p = dst->scanLine( y );
+ memset( p, 0, bmwidth );
+ b1 = line1;
+ b2 = line2;
+ int bit = 7;
+ for ( x=1; x<=w; x++ ) {
+ if ( *b1 < 128 ) { // black pixel
+ err = *b1++;
+ *p |= 1 << bit;
+ } else { // white pixel
+ err = *b1++ - 255;
+ }
+ if ( bit == 0 ) {
+ p++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ if ( x < w )
+ *b1 += (err*7)>>4; // spread error to right pixel
+ if ( not_last_line ) {
+ b2[0] += (err*5)>>4; // pixel below
+ if ( x > 1 )
+ b2[-1] += (err*3)>>4; // pixel below left
+ if ( x < w )
+ b2[1] += err>>4; // pixel below right
+ }
+ b2++;
+ }
+ }
+ delete [] line1;
+ delete [] line2;
+ } break;
+ case Ordered: {
+ static uint bm[16][16];
+ static int init=0;
+ if (!init) {
+ // Build a Bayer Matrix for dithering
+
+ init = 1;
+ int n, i, j;
+
+ bm[0][0]=0;
+
+ for (n=1; n<16; n*=2) {
+ for (i=0; i<n; i++) {
+ for (j=0; j<n; j++) {
+ bm[i][j]*=4;
+ bm[i+n][j]=bm[i][j]+2;
+ bm[i][j+n]=bm[i][j]+3;
+ bm[i+n][j+n]=bm[i][j]+1;
+ }
+ }
+ }
+
+ // Force black to black
+ bm[0][0]=1;
+ }
+
+ dst->fill( 0 );
+ uchar** mline = dst->jumpTable();
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ if ( d == 32 ) {
+ uint** line = (uint**)src->jumpTable();
+ for ( int i=0; i<h; i++ ) {
+ uint *p = line[i];
+ uint *end = p + w;
+ uchar *m = mline[i];
+ int bit = 7;
+ int j = 0;
+ if ( fromalpha ) {
+ while ( p < end ) {
+ if ( (*p++ >> 24) >= bm[j++&15][i&15] )
+ *m |= 1 << bit;
+ if ( bit == 0 ) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ } else {
+ while ( p < end ) {
+ if ( (uint)tqGray(*p++) < bm[j++&15][i&15] )
+ *m |= 1 << bit;
+ if ( bit == 0 ) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ }
+ }
+ } else
+#endif // TQT_NO_IMAGE_TRUECOLOR
+ /* ( d == 8 ) */ {
+ uchar** line = src->jumpTable();
+ for ( int i=0; i<h; i++ ) {
+ uchar *p = line[i];
+ uchar *end = p + w;
+ uchar *m = mline[i];
+ int bit = 7;
+ int j = 0;
+ while ( p < end ) {
+ if ( (uint)gray[*p++] < bm[j++&15][i&15] )
+ *m |= 1 << bit;
+ if ( bit == 0 ) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ }
+ }
+ } break;
+ default: { // Threshold:
+ dst->fill( 0 );
+ uchar** mline = dst->jumpTable();
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ if ( d == 32 ) {
+ uint** line = (uint**)src->jumpTable();
+ for ( int i=0; i<h; i++ ) {
+ uint *p = line[i];
+ uint *end = p + w;
+ uchar *m = mline[i];
+ int bit = 7;
+ if ( fromalpha ) {
+ while ( p < end ) {
+ if ( (*p++ >> 24) >= 128 )
+ *m |= 1 << bit; // Set tqmask "on"
+ if ( bit == 0 ) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ } else {
+ while ( p < end ) {
+ if ( tqGray(*p++) < 128 )
+ *m |= 1 << bit; // Set pixel "black"
+ if ( bit == 0 ) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ }
+ }
+ } else
+#endif //TQT_NO_IMAGE_TRUECOLOR
+ if ( d == 8 ) {
+ uchar** line = src->jumpTable();
+ for ( int i=0; i<h; i++ ) {
+ uchar *p = line[i];
+ uchar *end = p + w;
+ uchar *m = mline[i];
+ int bit = 7;
+ while ( p < end ) {
+ if ( gray[*p++] < 128 )
+ *m |= 1 << bit; // Set tqmask "on"/ pixel "black"
+ if ( bit == 0 ) {
+ m++;
+ bit = 7;
+ } else {
+ bit--;
+ }
+ }
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+#endif
+
+#ifndef TQT_NO_IMAGE_16_BIT
+//###### Endianness issues!
+static inline bool is16BitGray( ushort c )
+{
+ int r=(c & 0xf800) >> 11;
+ int g=(c & 0x07e0) >> 6; //green/2
+ int b=(c & 0x001f);
+ return r == g && g == b;
+}
+
+
+static bool convert_16_to_32( const TQImage *src, TQImage *dst )
+{
+ if ( !dst->create(src->width(), src->height(), 32) )
+ return FALSE; // create failed
+ dst->setAlphaBuffer( src->hasAlphaBuffer() );
+ for ( int y=0; y<dst->height(); y++ ) { // for each scan line...
+ register uint *p = (uint *)dst->scanLine(y);
+ ushort *s = (ushort*)src->scanLine(y);
+ uint *end = p + dst->width();
+ while ( p < end )
+ *p++ = qt_conv16ToRgb( *s++ );
+ }
+ return TRUE;
+}
+
+
+static bool convert_32_to_16( const TQImage *src, TQImage *dst )
+{
+ if ( !dst->create(src->width(), src->height(), 16) )
+ return FALSE; // create failed
+ dst->setAlphaBuffer( src->hasAlphaBuffer() );
+ for ( int y=0; y<dst->height(); y++ ) { // for each scan line...
+ register ushort *p = (ushort *)dst->scanLine(y);
+ uint *s = (uint*)src->scanLine(y);
+ ushort *end = p + dst->width();
+ while ( p < end )
+ *p++ = qt_convRgbTo16( *s++ );
+ }
+ return TRUE;
+}
+
+
+#endif
+
+/*!
+ Converts the depth (bpp) of the image to \a depth and returns the
+ converted image. The original image is not changed.
+
+ The \a depth argument must be 1, 8, 16 (TQt/Embedded only) or 32.
+
+ Returns \c *this if \a depth is equal to the image depth, or a
+ \link isNull() null\endlink image if this image cannot be
+ converted.
+
+ If the image needs to be modified to fit in a lower-resolution
+ result (e.g. converting from 32-bit to 8-bit), use the \a
+ conversion_flags to specify how you'd prefer this to happen.
+
+ \sa TQt::ImageConversionFlags depth() isNull()
+*/
+
+TQImage TQImage::convertDepth( int depth, int conversion_flags ) const
+{
+ TQImage image;
+ if ( data->d == depth )
+ image = *this; // no conversion
+#ifndef TQT_NO_IMAGE_DITHER_TO_1
+ else if ( (data->d == 8 || data->d == 32) && depth == 1 ) // dither
+ dither_to_1( this, &image, conversion_flags, FALSE );
+#endif
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ else if ( data->d == 32 && depth == 8 ) // 32 -> 8
+ convert_32_to_8( this, &image, conversion_flags );
+ else if ( data->d == 8 && depth == 32 ) // 8 -> 32
+ convert_8_to_32( this, &image );
+#endif
+ else if ( data->d == 1 && depth == 8 ) // 1 -> 8
+ convert_1_to_8( this, &image );
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ else if ( data->d == 1 && depth == 32 ) // 1 -> 32
+ convert_1_to_32( this, &image );
+#endif
+#ifndef TQT_NO_IMAGE_16_BIT
+ else if ( data->d == 16 && depth != 16 ) {
+ TQImage tmp;
+ convert_16_to_32( this, &tmp );
+ image = tmp.convertDepth( depth, conversion_flags );
+ } else if ( data->d != 16 && depth == 16 ) {
+ TQImage tmp = convertDepth( 32, conversion_flags );
+ convert_32_to_16( &tmp, &image );
+ }
+#endif
+ else {
+#if defined(TQT_CHECK_RANGE)
+ if ( isNull() )
+ qWarning( "TQImage::convertDepth: Image is a null image" );
+ else
+ qWarning( "TQImage::convertDepth: Depth %d not supported", depth );
+#endif
+ }
+ return image;
+}
+
+/*!
+ \overload
+*/
+
+TQImage TQImage::convertDepth( int depth ) const
+{
+ return convertDepth( depth, 0 );
+}
+
+/*!
+ Returns TRUE if ( \a x, \a y ) is a valid coordinate in the image;
+ otherwise returns FALSE.
+
+ \sa width() height() pixelIndex()
+*/
+
+bool TQImage::valid( int x, int y ) const
+{
+ return x >= 0 && x < width()
+ && y >= 0 && y < height();
+}
+
+/*!
+ Returns the pixel index at the given coordinates.
+
+ If (\a x, \a y) is not \link valid() valid\endlink, or if the
+ image is not a paletted image (depth() \> 8), the results are
+ undefined.
+
+ \sa valid() depth()
+*/
+
+int TQImage::pixelIndex( int x, int y ) const
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( x < 0 || x >= width() ) {
+ qWarning( "TQImage::pixel: x=%d out of range", x );
+ return -12345;
+ }
+#endif
+ uchar * s = scanLine( y );
+ switch( depth() ) {
+ case 1:
+ if ( bitOrder() == TQImage::LittleEndian )
+ return (*(s + (x >> 3)) >> (x & 7)) & 1;
+ else
+ return (*(s + (x >> 3)) >> (7- (x & 7))) & 1;
+ case 8:
+ return (int)s[x];
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+#ifndef TQT_NO_IMAGE_16_BIT
+ case 16:
+#endif
+ case 32:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage::pixelIndex: Not applicable for %d-bpp images "
+ "(no palette)", depth() );
+#endif
+ return 0;
+#endif //TQT_NO_IMAGE_TRUECOLOR
+ }
+ return 0;
+}
+
+
+/*!
+ Returns the color of the pixel at the coordinates (\a x, \a y).
+
+ If (\a x, \a y) is not \link valid() on the image\endlink, the
+ results are undefined.
+
+ \sa setPixel() tqRed() tqGreen() tqBlue() valid()
+*/
+
+TQRgb TQImage::pixel( int x, int y ) const
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( x < 0 || x >= width() ) {
+ qWarning( "TQImage::pixel: x=%d out of range", x );
+ return 12345;
+ }
+#endif
+ uchar * s = scanLine( y );
+ switch( depth() ) {
+ case 1:
+ if ( bitOrder() == TQImage::LittleEndian )
+ return color( (*(s + (x >> 3)) >> (x & 7)) & 1 );
+ else
+ return color( (*(s + (x >> 3)) >> (7- (x & 7))) & 1 );
+ case 8:
+ return color( (int)s[x] );
+#ifndef TQT_NO_IMAGE_16_BIT
+ case 16:
+ return qt_conv16ToRgb(((ushort*)s)[x]);
+#endif
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ case 32:
+ return ((TQRgb*)s)[x];
+#endif
+ default:
+ return 100367;
+ }
+}
+
+
+/*!
+ Sets the pixel index or color at the coordinates (\a x, \a y) to
+ \a index_or_rgb.
+
+ If (\a x, \a y) is not \link valid() valid\endlink, the result is
+ undefined.
+
+ If the image is a paletted image (depth() \<= 8) and \a
+ index_or_rgb \>= numColors(), the result is undefined.
+
+ \sa pixelIndex() pixel() tqRgb() tqRgba() valid()
+*/
+
+void TQImage::setPixel( int x, int y, uint index_or_rgb )
+{
+ if ( x < 0 || x >= width() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage::setPixel: x=%d out of range", x );
+#endif
+ return;
+ }
+ if ( depth() == 1 ) {
+ uchar * s = scanLine( y );
+ if ( index_or_rgb > 1) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage::setPixel: index=%d out of range",
+ index_or_rgb );
+#endif
+ } else if ( bitOrder() == TQImage::LittleEndian ) {
+ if (index_or_rgb==0)
+ *(s + (x >> 3)) &= ~(1 << (x & 7));
+ else
+ *(s + (x >> 3)) |= (1 << (x & 7));
+ } else {
+ if (index_or_rgb==0)
+ *(s + (x >> 3)) &= ~(1 << (7-(x & 7)));
+ else
+ *(s + (x >> 3)) |= (1 << (7-(x & 7)));
+ }
+ } else if ( depth() == 8 ) {
+ if (index_or_rgb > (uint)numColors()) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage::setPixel: index=%d out of range",
+ index_or_rgb );
+#endif
+ return;
+ }
+ uchar * s = scanLine( y );
+ s[x] = index_or_rgb;
+#ifndef TQT_NO_IMAGE_16_BIT
+ } else if ( depth() == 16 ) {
+ ushort * s = (ushort*)scanLine( y );
+ s[x] = qt_convRgbTo16(index_or_rgb);
+#endif
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ } else if ( depth() == 32 ) {
+ TQRgb * s = (TQRgb*)scanLine( y );
+ s[x] = index_or_rgb;
+#endif
+ }
+}
+
+
+/*!
+ Converts the bit order of the image to \a bitOrder and returns the
+ converted image. The original image is not changed.
+
+ Returns \c *this if the \a bitOrder is equal to the image bit
+ order, or a \link isNull() null\endlink image if this image cannot
+ be converted.
+
+ \sa bitOrder() systemBitOrder() isNull()
+*/
+
+TQImage TQImage::convertBitOrder( Endian bitOrder ) const
+{
+ if ( isNull() || data->d != 1 || // invalid argument(s)
+ !(bitOrder == BigEndian || bitOrder == LittleEndian) ) {
+ TQImage nullImage;
+ return nullImage;
+ }
+ if ( data->bitordr == bitOrder ) // nothing to do
+ return copy();
+
+ TQImage image( data->w, data->h, 1, data->ncols, bitOrder );
+
+ int bpl = (width() + 7) / 8;
+ for ( int y = 0; y < data->h; y++ ) {
+ register uchar *p = jumpTable()[y];
+ uchar *end = p + bpl;
+ uchar *b = image.jumpTable()[y];
+ while ( p < end )
+ *b++ = bitflip[*p++];
+ }
+ memcpy( image.colorTable(), colorTable(), numColors()*sizeof(TQRgb) );
+ return image;
+}
+
+// ### Candidate (renamed) for tqcolor.h
+static
+bool isGray(TQRgb c)
+{
+ return tqRed(c) == tqGreen(c)
+ && tqRed(c) == tqBlue(c);
+}
+
+/*!
+ Returns TRUE if all the colors in the image are shades of gray
+ (i.e. their red, green and blue components are equal); otherwise
+ returns FALSE.
+
+ This function is slow for large 16-bit (TQt/Embedded only) and 32-bit images.
+
+ \sa isGrayscale()
+*/
+bool TQImage::allGray() const
+{
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ if (depth()==32) {
+ int p = width()*height();
+ TQRgb* b = (TQRgb*)bits();
+ while (p--)
+ if (!isGray(*b++))
+ return FALSE;
+#ifndef TQT_NO_IMAGE_16_BIT
+ } else if (depth()==16) {
+ int p = width()*height();
+ ushort* b = (ushort*)bits();
+ while (p--)
+ if (!is16BitGray(*b++))
+ return FALSE;
+#endif
+ } else
+#endif //TQT_NO_IMAGE_TRUECOLOR
+ {
+ if (!data->ctbl) return TRUE;
+ for (int i=0; i<numColors(); i++)
+ if (!isGray(data->ctbl[i]))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*!
+ For 16-bit (TQt/Embedded only) and 32-bit images, this function is
+ equivalent to allGray().
+
+ For 8-bpp images, this function returns TRUE if color(i) is
+ TQRgb(i,i,i) for all indices of the color table; otherwise returns
+ FALSE.
+
+ \sa allGray() depth()
+*/
+bool TQImage::isGrayscale() const
+{
+ switch (depth()) {
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ case 32:
+#ifndef TQT_NO_IMAGE_16_BIT
+ case 16:
+#endif
+ return allGray();
+#endif //TQT_NO_IMAGE_TRUECOLOR
+ case 8: {
+ for (int i=0; i<numColors(); i++)
+ if (data->ctbl[i] != tqRgb(i,i,i))
+ return FALSE;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+static
+void pnmscale(const TQImage& src, TQImage& dst)
+{
+ TQRgb* xelrow = 0;
+ TQRgb* tempxelrow = 0;
+ register TQRgb* xP;
+ register TQRgb* nxP;
+ int rows, cols, rowsread, newrows, newcols;
+ register int row, col, needtoreadrow;
+ const uchar maxval = 255;
+ double xscale, yscale;
+ long sxscale, syscale;
+ register long fracrowtofill, fracrowleft;
+ long* as;
+ long* rs;
+ long* gs;
+ long* bs;
+ int rowswritten = 0;
+
+ cols = src.width();
+ rows = src.height();
+ newcols = dst.width();
+ newrows = dst.height();
+
+ long SCALE;
+ long HALFSCALE;
+
+ if (cols > 4096)
+ {
+ SCALE = 4096;
+ HALFSCALE = 2048;
+ }
+ else
+ {
+ int fac = 4096;
+
+ while (cols * fac > 4096)
+ {
+ fac /= 2;
+ }
+
+ SCALE = fac * cols;
+ HALFSCALE = fac * cols / 2;
+ }
+
+ xscale = (double) newcols / (double) cols;
+ yscale = (double) newrows / (double) rows;
+
+ sxscale = (long)(xscale * SCALE);
+ syscale = (long)(yscale * SCALE);
+
+ if ( newrows != rows ) /* shortcut Y scaling if possible */
+ tempxelrow = new TQRgb[cols];
+
+ if ( src.hasAlphaBuffer() ) {
+ dst.setAlphaBuffer(TRUE);
+ as = new long[cols];
+ for ( col = 0; col < cols; ++col )
+ as[col] = HALFSCALE;
+ } else {
+ as = 0;
+ }
+ rs = new long[cols];
+ gs = new long[cols];
+ bs = new long[cols];
+ rowsread = 0;
+ fracrowleft = syscale;
+ needtoreadrow = 1;
+ for ( col = 0; col < cols; ++col )
+ rs[col] = gs[col] = bs[col] = HALFSCALE;
+ fracrowtofill = SCALE;
+
+ for ( row = 0; row < newrows; ++row ) {
+ /* First scale Y from xelrow into tempxelrow. */
+ if ( newrows == rows ) {
+ /* shortcut Y scaling if possible */
+ tempxelrow = xelrow = (TQRgb*)src.scanLine(rowsread++);
+ } else {
+ while ( fracrowleft < fracrowtofill ) {
+ if ( needtoreadrow && rowsread < rows )
+ xelrow = (TQRgb*)src.scanLine(rowsread++);
+ for ( col = 0, xP = xelrow; col < cols; ++col, ++xP ) {
+ if (as) {
+ as[col] += fracrowleft * tqAlpha( *xP );
+ rs[col] += fracrowleft * tqRed( *xP ) * tqAlpha( *xP ) / 255;
+ gs[col] += fracrowleft * tqGreen( *xP ) * tqAlpha( *xP ) / 255;
+ bs[col] += fracrowleft * tqBlue( *xP ) * tqAlpha( *xP ) / 255;
+ } else {
+ rs[col] += fracrowleft * tqRed( *xP );
+ gs[col] += fracrowleft * tqGreen( *xP );
+ bs[col] += fracrowleft * tqBlue( *xP );
+ }
+ }
+ fracrowtofill -= fracrowleft;
+ fracrowleft = syscale;
+ needtoreadrow = 1;
+ }
+ /* Now fracrowleft is >= fracrowtofill, so we can produce a row. */
+ if ( needtoreadrow && rowsread < rows ) {
+ xelrow = (TQRgb*)src.scanLine(rowsread++);
+ needtoreadrow = 0;
+ }
+ register long a=0;
+ for ( col = 0, xP = xelrow, nxP = tempxelrow;
+ col < cols; ++col, ++xP, ++nxP )
+ {
+ register long r, g, b;
+
+ if ( as ) {
+ r = rs[col] + fracrowtofill * tqRed( *xP ) * tqAlpha( *xP ) / 255;
+ g = gs[col] + fracrowtofill * tqGreen( *xP ) * tqAlpha( *xP ) / 255;
+ b = bs[col] + fracrowtofill * tqBlue( *xP ) * tqAlpha( *xP ) / 255;
+ a = as[col] + fracrowtofill * tqAlpha( *xP );
+ if ( a ) {
+ r = r * 255 / a * SCALE;
+ g = g * 255 / a * SCALE;
+ b = b * 255 / a * SCALE;
+ }
+ } else {
+ r = rs[col] + fracrowtofill * tqRed( *xP );
+ g = gs[col] + fracrowtofill * tqGreen( *xP );
+ b = bs[col] + fracrowtofill * tqBlue( *xP );
+ }
+ r /= SCALE;
+ if ( r > maxval ) r = maxval;
+ g /= SCALE;
+ if ( g > maxval ) g = maxval;
+ b /= SCALE;
+ if ( b > maxval ) b = maxval;
+ if ( as ) {
+ a /= SCALE;
+ if ( a > maxval ) a = maxval;
+ *nxP = tqRgba( (int)r, (int)g, (int)b, (int)a );
+ as[col] = HALFSCALE;
+ } else {
+ *nxP = tqRgb( (int)r, (int)g, (int)b );
+ }
+ rs[col] = gs[col] = bs[col] = HALFSCALE;
+ }
+ fracrowleft -= fracrowtofill;
+ if ( fracrowleft == 0 ) {
+ fracrowleft = syscale;
+ needtoreadrow = 1;
+ }
+ fracrowtofill = SCALE;
+ }
+
+ /* Now scale X from tempxelrow into dst and write it out. */
+ if ( newcols == cols ) {
+ /* shortcut X scaling if possible */
+ memcpy(dst.scanLine(rowswritten++), tempxelrow, newcols*4);
+ } else {
+ register long a, r, g, b;
+ register long fraccoltofill, fraccolleft = 0;
+ register int needcol;
+
+ nxP = (TQRgb*)dst.scanLine(rowswritten++);
+ fraccoltofill = SCALE;
+ a = r = g = b = HALFSCALE;
+ needcol = 0;
+ for ( col = 0, xP = tempxelrow; col < cols; ++col, ++xP ) {
+ fraccolleft = sxscale;
+ while ( fraccolleft >= fraccoltofill ) {
+ if ( needcol ) {
+ ++nxP;
+ a = r = g = b = HALFSCALE;
+ }
+ if ( as ) {
+ r += fraccoltofill * tqRed( *xP ) * tqAlpha( *xP ) / 255;
+ g += fraccoltofill * tqGreen( *xP ) * tqAlpha( *xP ) / 255;
+ b += fraccoltofill * tqBlue( *xP ) * tqAlpha( *xP ) / 255;
+ a += fraccoltofill * tqAlpha( *xP );
+ if ( a ) {
+ r = r * 255 / a * SCALE;
+ g = g * 255 / a * SCALE;
+ b = b * 255 / a * SCALE;
+ }
+ } else {
+ r += fraccoltofill * tqRed( *xP );
+ g += fraccoltofill * tqGreen( *xP );
+ b += fraccoltofill * tqBlue( *xP );
+ }
+ r /= SCALE;
+ if ( r > maxval ) r = maxval;
+ g /= SCALE;
+ if ( g > maxval ) g = maxval;
+ b /= SCALE;
+ if ( b > maxval ) b = maxval;
+ if (as) {
+ a /= SCALE;
+ if ( a > maxval ) a = maxval;
+ *nxP = tqRgba( (int)r, (int)g, (int)b, (int)a );
+ } else {
+ *nxP = tqRgb( (int)r, (int)g, (int)b );
+ }
+ fraccolleft -= fraccoltofill;
+ fraccoltofill = SCALE;
+ needcol = 1;
+ }
+ if ( fraccolleft > 0 ) {
+ if ( needcol ) {
+ ++nxP;
+ a = r = g = b = HALFSCALE;
+ needcol = 0;
+ }
+ if (as) {
+ a += fraccolleft * tqAlpha( *xP );
+ r += fraccolleft * tqRed( *xP ) * tqAlpha( *xP ) / 255;
+ g += fraccolleft * tqGreen( *xP ) * tqAlpha( *xP ) / 255;
+ b += fraccolleft * tqBlue( *xP ) * tqAlpha( *xP ) / 255;
+ } else {
+ r += fraccolleft * tqRed( *xP );
+ g += fraccolleft * tqGreen( *xP );
+ b += fraccolleft * tqBlue( *xP );
+ }
+ fraccoltofill -= fraccolleft;
+ }
+ }
+ if ( fraccoltofill > 0 ) {
+ --xP;
+ if (as) {
+ a += fraccolleft * tqAlpha( *xP );
+ r += fraccoltofill * tqRed( *xP ) * tqAlpha( *xP ) / 255;
+ g += fraccoltofill * tqGreen( *xP ) * tqAlpha( *xP ) / 255;
+ b += fraccoltofill * tqBlue( *xP ) * tqAlpha( *xP ) / 255;
+ if ( a ) {
+ r = r * 255 / a * SCALE;
+ g = g * 255 / a * SCALE;
+ b = b * 255 / a * SCALE;
+ }
+ } else {
+ r += fraccoltofill * tqRed( *xP );
+ g += fraccoltofill * tqGreen( *xP );
+ b += fraccoltofill * tqBlue( *xP );
+ }
+ }
+ if ( ! needcol ) {
+ r /= SCALE;
+ if ( r > maxval ) r = maxval;
+ g /= SCALE;
+ if ( g > maxval ) g = maxval;
+ b /= SCALE;
+ if ( b > maxval ) b = maxval;
+ if (as) {
+ a /= SCALE;
+ if ( a > maxval ) a = maxval;
+ *nxP = tqRgba( (int)r, (int)g, (int)b, (int)a );
+ } else {
+ *nxP = tqRgb( (int)r, (int)g, (int)b );
+ }
+ }
+ }
+ }
+
+ if ( newrows != rows && tempxelrow )// Robust, tempxelrow might be 0 1 day
+ delete [] tempxelrow;
+ if ( as ) // Avoid purify complaint
+ delete [] as;
+ if ( rs ) // Robust, rs might be 0 one day
+ delete [] rs;
+ if ( gs ) // Robust, gs might be 0 one day
+ delete [] gs;
+ if ( bs ) // Robust, bs might be 0 one day
+ delete [] bs;
+}
+#endif
+
+/*!
+ \enum TQImage::ScaleMode
+
+ The functions scale() and smoothScale() use different modes for
+ scaling the image. The purpose of these modes is to retain the
+ ratio of the image if this is required.
+
+ \img scaling.png
+
+ \value ScaleFree The image is scaled freely: the resulting image
+ fits exactly into the specified size; the ratio will not
+ necessarily be preserved.
+ \value ScaleMin The ratio of the image is preserved and the
+ resulting image is guaranteed to fit into the specified size
+ (it is as large as possible within these constraints) - the
+ image might be smaller than the requested size.
+ \value ScaleMax The ratio of the image is preserved and the
+ resulting image fills the whole specified rectangle (it is as
+ small as possible within these constraints) - the image might
+ be larger than the requested size.
+*/
+
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+/*!
+ Returns a smoothly scaled copy of the image. The returned image
+ has a size of width \a w by height \a h pixels if \a mode is \c
+ ScaleFree. The modes \c ScaleMin and \c ScaleMax may be used to
+ preserve the ratio of the image: if \a mode is \c ScaleMin, the
+ returned image is guaranteed to fit into the rectangle specified
+ by \a w and \a h (it is as large as possible within the
+ constraints); if \a mode is \c ScaleMax, the returned image fits
+ at least into the specified rectangle (it is a small as possible
+ within the constraints).
+
+ For 32-bpp images and 1-bpp/8-bpp color images the result will be
+ 32-bpp, whereas \link allGray() all-gray \endlink images
+ (including black-and-white 1-bpp) will produce 8-bit \link
+ isGrayscale() grayscale \endlink images with the palette spanning
+ 256 grays from black to white.
+
+ This function uses code based on pnmscale.c by Jef Poskanzer.
+
+ pnmscale.c - read a portable anymap and scale it
+
+ \legalese
+
+ Copyright (C) 1989, 1991 by Jef Poskanzer.
+
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that copyright notice and this permission
+ notice appear in supporting documentation. This software is
+ provided "as is" without express or implied warranty.
+
+ \sa scale() mirror()
+*/
+TQImage TQImage::smoothScale( int w, int h, ScaleMode mode ) const
+{
+ return smoothScale( TQSize( w, h ), mode );
+}
+#endif
+
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+/*!
+ \overload
+
+ The requested size of the image is \a s.
+*/
+TQImage TQImage::smoothScale( const TQSize& s, ScaleMode mode ) const
+{
+ if ( isNull() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage::smoothScale: Image is a null image" );
+#endif
+ return copy();
+ }
+
+ TQSize newSize = size();
+ newSize.scale( s, (TQSize::ScaleMode)mode ); // ### remove cast in TQt 4.0
+ if ( newSize == size() )
+ return copy();
+
+ if ( depth() == 32 ) {
+ TQImage img( newSize, 32 );
+ // 32-bpp to 32-bpp
+ pnmscale( *this, img );
+ return img;
+ } else if ( depth() != 16 && allGray() && !hasAlphaBuffer() ) {
+ // Inefficient
+ return convertDepth(32).smoothScale(newSize, mode).convertDepth(8);
+ } else {
+ // Inefficient
+ return convertDepth(32).smoothScale(newSize, mode);
+ }
+}
+#endif
+
+/*!
+ Returns a copy of the image scaled to a rectangle of width \a w
+ and height \a h according to the ScaleMode \a mode.
+
+ \list
+ \i If \a mode is \c ScaleFree, the image is scaled to (\a w,
+ \a h).
+ \i If \a mode is \c ScaleMin, the image is scaled to a rectangle
+ as large as possible inside (\a w, \a h), preserving the aspect
+ ratio.
+ \i If \a mode is \c ScaleMax, the image is scaled to a rectangle
+ as small as possible outside (\a w, \a h), preserving the aspect
+ ratio.
+ \endlist
+
+ If either the width \a w or the height \a h is 0 or negative, this
+ function returns a \link isNull() null\endlink image.
+
+ This function uses a simple, fast algorithm. If you need better
+ quality, use smoothScale() instead.
+
+ \sa scaleWidth() scaleHeight() smoothScale() xForm()
+*/
+#ifndef TQT_NO_IMAGE_TRANSFORMATION
+TQImage TQImage::scale( int w, int h, ScaleMode mode ) const
+{
+ return scale( TQSize( w, h ), mode );
+}
+#endif
+
+/*!
+ \overload
+
+ The requested size of the image is \a s.
+*/
+#ifndef TQT_NO_IMAGE_TRANSFORMATION
+TQImage TQImage::scale( const TQSize& s, ScaleMode mode ) const
+{
+ if ( isNull() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage::scale: Image is a null image" );
+#endif
+ return copy();
+ }
+ if ( s.isEmpty() )
+ return TQImage();
+
+ TQSize newSize = size();
+ newSize.scale( s, (TQSize::ScaleMode)mode ); // ### remove cast in TQt 4.0
+ if ( newSize == size() )
+ return copy();
+
+ TQImage img;
+ TQWMatrix wm;
+ wm.scale( (double)newSize.width() / width(), (double)newSize.height() / height() );
+ img = xForm( wm );
+ // ### I should test and resize the image if it has not the right size
+// if ( img.width() != newSize.width() || img.height() != newSize.height() )
+// img.resize( newSize.width(), newSize.height() );
+ return img;
+}
+#endif
+
+/*!
+ Returns a scaled copy of the image. The returned image has a width
+ of \a w pixels. This function automatically calculates the height
+ of the image so that the ratio of the image is preserved.
+
+ If \a w is 0 or negative a \link isNull() null\endlink image is
+ returned.
+
+ \sa scale() scaleHeight() smoothScale() xForm()
+*/
+#ifndef TQT_NO_IMAGE_TRANSFORMATION
+TQImage TQImage::scaleWidth( int w ) const
+{
+ if ( isNull() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage::scaleWidth: Image is a null image" );
+#endif
+ return copy();
+ }
+ if ( w <= 0 )
+ return TQImage();
+
+ TQWMatrix wm;
+ double factor = (double) w / width();
+ wm.scale( factor, factor );
+ return xForm( wm );
+}
+#endif
+
+/*!
+ Returns a scaled copy of the image. The returned image has a
+ height of \a h pixels. This function automatically calculates the
+ width of the image so that the ratio of the image is preserved.
+
+ If \a h is 0 or negative a \link isNull() null\endlink image is
+ returned.
+
+ \sa scale() scaleWidth() smoothScale() xForm()
+*/
+#ifndef TQT_NO_IMAGE_TRANSFORMATION
+TQImage TQImage::scaleHeight( int h ) const
+{
+ if ( isNull() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage::scaleHeight: Image is a null image" );
+#endif
+ return copy();
+ }
+ if ( h <= 0 )
+ return TQImage();
+
+ TQWMatrix wm;
+ double factor = (double) h / height();
+ wm.scale( factor, factor );
+ return xForm( wm );
+}
+#endif
+
+
+/*!
+ Returns a copy of the image that is transformed using the
+ transformation matrix, \a matrix.
+
+ The transformation \a matrix is internally adjusted to compensate
+ for unwanted translation, i.e. xForm() returns the smallest image
+ that tqcontains all the transformed points of the original image.
+
+ \sa scale() TQPixmap::xForm() TQPixmap::trueMatrix() TQWMatrix
+*/
+#ifndef TQT_NO_IMAGE_TRANSFORMATION
+TQImage TQImage::xForm( const TQWMatrix &matrix ) const
+{
+ // This function uses the same algorithm as (and steals quite some
+ // code from) TQPixmap::xForm().
+
+ if ( isNull() )
+ return copy();
+
+ if ( depth() == 16 ) {
+ // inefficient
+ return convertDepth( 32 ).xForm( matrix );
+ }
+
+ // source image data
+ int ws = width();
+ int hs = height();
+ int sbpl = bytesPerLine();
+ uchar *sptr = bits();
+
+ // target image data
+ int wd;
+ int hd;
+
+ int bpp = depth();
+
+ // compute size of target image
+ TQWMatrix mat = TQPixmap::trueMatrix( matrix, ws, hs );
+ if ( mat.m12() == 0.0F && mat.m21() == 0.0F ) {
+ if ( mat.m11() == 1.0F && mat.m22() == 1.0F ) // identity matrix
+ return copy();
+ hd = tqRound( mat.m22() * hs );
+ wd = tqRound( mat.m11() * ws );
+ hd = TQABS( hd );
+ wd = TQABS( wd );
+ } else { // rotation or shearing
+ TQPointArray a( TQRect(0, 0, ws, hs) );
+ a = mat.map( a );
+ TQRect r = a.boundingRect().normalize();
+ wd = r.width();
+ hd = r.height();
+ }
+
+ bool invertible;
+ mat = mat.invert( &invertible ); // invert matrix
+ if ( hd == 0 || wd == 0 || !invertible ) // error, return null image
+ return TQImage();
+
+ // create target image (some of the code is from TQImage::copy())
+ TQImage dImage( wd, hd, depth(), numColors(), bitOrder() );
+
+ // If the image allocation failed, we need to gracefully abort.
+ if (dImage.isNull())
+ return dImage;
+
+ memcpy( dImage.colorTable(), colorTable(), numColors()*sizeof(TQRgb) );
+ dImage.setAlphaBuffer( hasAlphaBuffer() );
+ dImage.data->dpmx = dotsPerMeterX();
+ dImage.data->dpmy = dotsPerMeterY();
+
+ switch ( bpp ) {
+ // initizialize the data
+ case 1:
+ memset( dImage.bits(), 0, dImage.numBytes() );
+ break;
+ case 8:
+ if ( dImage.data->ncols < 256 ) {
+ // colors are left in the color table, so pick that one as transtqparent
+ dImage.setNumColors( dImage.data->ncols+1 );
+ dImage.setColor( dImage.data->ncols-1, 0x00 );
+ memset( dImage.bits(), dImage.data->ncols-1, dImage.numBytes() );
+ } else {
+ memset( dImage.bits(), 0, dImage.numBytes() );
+ }
+ break;
+ case 16:
+ memset( dImage.bits(), 0xff, dImage.numBytes() );
+ break;
+ case 32:
+ memset( dImage.bits(), 0x00, dImage.numBytes() );
+ break;
+ }
+
+ int type;
+ if ( bitOrder() == BigEndian )
+ type = TQT_XFORM_TYPE_MSBFIRST;
+ else
+ type = TQT_XFORM_TYPE_LSBFIRST;
+ int dbpl = dImage.bytesPerLine();
+ qt_xForm_helper( mat, 0, type, bpp, dImage.bits(), dbpl, 0, hd, sptr, sbpl,
+ ws, hs );
+ return dImage;
+}
+#endif
+
+/*!
+ Builds and returns a 1-bpp tqmask from the alpha buffer in this
+ image. Returns a \link isNull() null\endlink image if \link
+ setAlphaBuffer() alpha buffer mode\endlink is disabled.
+
+ See TQPixmap::convertFromImage() for a description of the \a
+ conversion_flags argument.
+
+ The returned image has little-endian bit order, which you can
+ convert to big-endianness using convertBitOrder().
+
+ \sa createHeuristicMask() hasAlphaBuffer() setAlphaBuffer()
+*/
+#ifndef TQT_NO_IMAGE_DITHER_TO_1
+TQImage TQImage::createAlphaMask( int conversion_flags ) const
+{
+ if ( conversion_flags == 1 ) {
+ // Old code is passing "TRUE".
+ conversion_flags = TQt::DiffuseAlphaDither;
+ }
+
+ if ( isNull() || !hasAlphaBuffer() )
+ return TQImage();
+
+ if ( depth() == 1 ) {
+ // A monochrome pixmap, with alpha channels on those two colors.
+ // Pretty unlikely, so use less efficient solution.
+ return convertDepth(8, conversion_flags)
+ .createAlphaMask( conversion_flags );
+ }
+
+ TQImage tqmask1;
+ dither_to_1( this, &tqmask1, conversion_flags, TRUE );
+ return tqmask1;
+}
+#endif
+
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+/*!
+ Creates and returns a 1-bpp heuristic tqmask for this image. It
+ works by selecting a color from one of the corners, then chipping
+ away pixels of that color starting at all the edges.
+
+ The four corners vote for which color is to be masked away. In
+ case of a draw (this generally means that this function is not
+ applicable to the image), the result is arbitrary.
+
+ The returned image has little-endian bit order, which you can
+ convert to big-endianness using convertBitOrder().
+
+ If \a clipTight is TRUE the tqmask is just large enough to cover the
+ pixels; otherwise, the tqmask is larger than the data pixels.
+
+ This function disregards the \link hasAlphaBuffer() alpha buffer
+ \endlink.
+
+ \sa createAlphaMask()
+*/
+
+TQImage TQImage::createHeuristicMask( bool clipTight ) const
+{
+ if ( isNull() ) {
+ TQImage nullImage;
+ return nullImage;
+ }
+ if ( depth() != 32 ) {
+ TQImage img32 = convertDepth(32);
+ return img32.createHeuristicMask(clipTight);
+ }
+
+#define PIX(x,y) (*((TQRgb*)scanLine(y)+x) & 0x00ffffff)
+
+ int w = width();
+ int h = height();
+ TQImage m(w, h, 1, 2, TQImage::LittleEndian);
+ m.setColor( 0, 0xffffff );
+ m.setColor( 1, 0 );
+ m.fill( 0xff );
+
+ TQRgb background = PIX(0,0);
+ if ( background != PIX(w-1,0) &&
+ background != PIX(0,h-1) &&
+ background != PIX(w-1,h-1) ) {
+ background = PIX(w-1,0);
+ if ( background != PIX(w-1,h-1) &&
+ background != PIX(0,h-1) &&
+ PIX(0,h-1) == PIX(w-1,h-1) ) {
+ background = PIX(w-1,h-1);
+ }
+ }
+
+ int x,y;
+ bool done = FALSE;
+ uchar *ypp, *ypc, *ypn;
+ while( !done ) {
+ done = TRUE;
+ ypn = m.scanLine(0);
+ ypc = 0;
+ for ( y = 0; y < h; y++ ) {
+ ypp = ypc;
+ ypc = ypn;
+ ypn = (y == h-1) ? 0 : m.scanLine(y+1);
+ TQRgb *p = (TQRgb *)scanLine(y);
+ for ( x = 0; x < w; x++ ) {
+ // slowness here - it's possible to do six of these tests
+ // together in one go. oh well.
+ if ( ( x == 0 || y == 0 || x == w-1 || y == h-1 ||
+ !(*(ypc + ((x-1) >> 3)) & (1 << ((x-1) & 7))) ||
+ !(*(ypc + ((x+1) >> 3)) & (1 << ((x+1) & 7))) ||
+ !(*(ypp + (x >> 3)) & (1 << (x & 7))) ||
+ !(*(ypn + (x >> 3)) & (1 << (x & 7))) ) &&
+ ( (*(ypc + (x >> 3)) & (1 << (x & 7))) ) &&
+ ( (*p & 0x00ffffff) == background ) ) {
+ done = FALSE;
+ *(ypc + (x >> 3)) &= ~(1 << (x & 7));
+ }
+ p++;
+ }
+ }
+ }
+
+ if ( !clipTight ) {
+ ypn = m.scanLine(0);
+ ypc = 0;
+ for ( y = 0; y < h; y++ ) {
+ ypp = ypc;
+ ypc = ypn;
+ ypn = (y == h-1) ? 0 : m.scanLine(y+1);
+ TQRgb *p = (TQRgb *)scanLine(y);
+ for ( x = 0; x < w; x++ ) {
+ if ( (*p & 0x00ffffff) != background ) {
+ if ( x > 0 )
+ *(ypc + ((x-1) >> 3)) |= (1 << ((x-1) & 7));
+ if ( x < w-1 )
+ *(ypc + ((x+1) >> 3)) |= (1 << ((x+1) & 7));
+ if ( y > 0 )
+ *(ypp + (x >> 3)) |= (1 << (x & 7));
+ if ( y < h-1 )
+ *(ypn + (x >> 3)) |= (1 << (x & 7));
+ }
+ p++;
+ }
+ }
+ }
+
+#undef PIX
+
+ return m;
+}
+#endif //TQT_NO_IMAGE_HEURISTIC_MASK
+
+#ifndef TQT_NO_IMAGE_MIRROR
+/*
+ This code is contributed by Philipp Lang,
+ GeneriCom Software Germany (www.generi.com)
+ under the terms of the TQPL, Version 1.0
+*/
+
+/*!
+ \overload
+
+ Returns a mirror of the image, mirrored in the horizontal and/or
+ the vertical direction depending on whether \a horizontal and \a
+ vertical are set to TRUE or FALSE. The original image is not
+ changed.
+
+ \sa smoothScale()
+*/
+TQImage TQImage::mirror(bool horizontal, bool vertical) const
+{
+ int w = width();
+ int h = height();
+ if ( (w <= 1 && h <= 1) || (!horizontal && !vertical) )
+ return copy();
+
+ // Create result image, copy colormap
+ TQImage result(w, h, depth(), numColors(), bitOrder());
+ memcpy(result.colorTable(), colorTable(), numColors()*sizeof(TQRgb));
+ result.setAlphaBuffer(hasAlphaBuffer());
+
+ if (depth() == 1)
+ w = (w+7)/8;
+ int dxi = horizontal ? -1 : 1;
+ int dxs = horizontal ? w-1 : 0;
+ int dyi = vertical ? -1 : 1;
+ int dy = vertical ? h-1: 0;
+
+ // 1 bit, 8 bit
+ if (depth() == 1 || depth() == 8) {
+ for (int sy = 0; sy < h; sy++, dy += dyi) {
+ TQ_UINT8* ssl = (TQ_UINT8*)(data->bits[sy]);
+ TQ_UINT8* dsl = (TQ_UINT8*)(result.data->bits[dy]);
+ int dx = dxs;
+ for (int sx = 0; sx < w; sx++, dx += dxi)
+ dsl[dx] = ssl[sx];
+ }
+ }
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+#ifndef TQT_NO_IMAGE_16_BIT
+ // 16 bit
+ else if (depth() == 16) {
+ for (int sy = 0; sy < h; sy++, dy += dyi) {
+ TQ_UINT16* ssl = (TQ_UINT16*)(data->bits[sy]);
+ TQ_UINT16* dsl = (TQ_UINT16*)(result.data->bits[dy]);
+ int dx = dxs;
+ for (int sx = 0; sx < w; sx++, dx += dxi)
+ dsl[dx] = ssl[sx];
+ }
+ }
+#endif
+ // 32 bit
+ else if (depth() == 32) {
+ for (int sy = 0; sy < h; sy++, dy += dyi) {
+ TQ_UINT32* ssl = (TQ_UINT32*)(data->bits[sy]);
+ TQ_UINT32* dsl = (TQ_UINT32*)(result.data->bits[dy]);
+ int dx = dxs;
+ for (int sx = 0; sx < w; sx++, dx += dxi)
+ dsl[dx] = ssl[sx];
+ }
+ }
+#endif
+
+ // special handling of 1 bit images for horizontal mirroring
+ if (horizontal && depth() == 1) {
+ int shift = width() % 8;
+ for (int y = h-1; y >= 0; y--) {
+ TQ_UINT8* a0 = (TQ_UINT8*)(result.data->bits[y]);
+ // Swap bytes
+ TQ_UINT8* a = a0+dxs;
+ while (a >= a0) {
+ *a = bitflip[*a];
+ a--;
+ }
+ // Shift bits if unaligned
+ if (shift != 0) {
+ a = a0+dxs;
+ TQ_UINT8 c = 0;
+ if (bitOrder() == TQImage::LittleEndian) {
+ while (a >= a0) {
+ TQ_UINT8 nc = *a << shift;
+ *a = (*a >> (8-shift)) | c;
+ --a;
+ c = nc;
+ }
+ } else {
+ while (a >= a0) {
+ TQ_UINT8 nc = *a >> shift;
+ *a = (*a << (8-shift)) | c;
+ --a;
+ c = nc;
+ }
+ }
+ }
+ }
+ }
+
+ return result;
+}
+
+/*!
+ Returns a TQImage which is a vertically mirrored copy of this
+ image. The original TQImage is not changed.
+*/
+
+TQImage TQImage::mirror() const
+{
+ return mirror(FALSE,TRUE);
+}
+#endif //TQT_NO_IMAGE_MIRROR
+
+/*!
+ Returns a TQImage in which the values of the red and blue
+ components of all pixels have been swapped, effectively converting
+ an RGB image to a BGR image. The original TQImage is not changed.
+*/
+
+TQImage TQImage::swapRGB() const
+{
+ TQImage res = copy();
+ if ( !isNull() ) {
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ if ( depth() == 32 ) {
+ for ( int i=0; i < height(); i++ ) {
+ uint *p = (uint*)scanLine( i );
+ uint *q = (uint*)res.scanLine( i );
+ uint *end = p + width();
+ while ( p < end ) {
+ *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) |
+ (*p & 0xff00ff00);
+ p++;
+ q++;
+ }
+ }
+#ifndef TQT_NO_IMAGE_16_BIT
+ } else if ( depth() == 16 ) {
+ qWarning( "TQImage::swapRGB not implemented for 16bpp" );
+#endif
+ } else
+#endif //TQT_NO_IMAGE_TRUECOLOR
+ {
+ uint* p = (uint*)colorTable();
+ uint* q = (uint*)res.colorTable();
+ if ( p && q ) {
+ for ( int i=0; i < numColors(); i++ ) {
+ *q = ((*p << 16) & 0xff0000) | ((*p >> 16) & 0xff) |
+ (*p & 0xff00ff00);
+ p++;
+ q++;
+ }
+ }
+ }
+ }
+ return res;
+}
+
+#ifndef TQT_NO_IMAGEIO
+/*!
+ Returns a string that specifies the image format of the file \a
+ fileName, or 0 if the file cannot be read or if the format is not
+ recognized.
+
+ The TQImageIO documentation lists the guaranteed supported image
+ formats, or use TQImage::inputFormats() and TQImage::outputFormats()
+ to get lists that include the installed formats.
+
+ \sa load() save()
+*/
+
+const char* TQImage::imageFormat( const TQString &fileName )
+{
+ return TQImageIO::imageFormat( fileName );
+}
+
+/*!
+ Returns a list of image formats that are supported for image
+ input.
+
+ \sa outputFormats() inputFormatList() TQImageIO
+*/
+TQStrList TQImage::inputFormats()
+{
+ return TQImageIO::inputFormats();
+}
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Returns a list of image formats that are supported for image
+ input.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myImage.inputFormatList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa outputFormatList() inputFormats() TQImageIO
+*/
+TQStringList TQImage::inputFormatList()
+{
+ return TQStringList::fromStrList(TQImageIO::inputFormats());
+}
+
+
+/*!
+ Returns a list of image formats that are supported for image
+ output.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myImage.outputFormatList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa inputFormatList() outputFormats() TQImageIO
+*/
+TQStringList TQImage::outputFormatList()
+{
+ return TQStringList::fromStrList(TQImageIO::outputFormats());
+}
+#endif //TQT_NO_STRINGLIST
+
+/*!
+ Returns a list of image formats that are supported for image
+ output.
+
+ \sa inputFormats() outputFormatList() TQImageIO
+*/
+TQStrList TQImage::outputFormats()
+{
+ return TQImageIO::outputFormats();
+}
+
+
+/*!
+ Loads an image from the file \a fileName. Returns TRUE if the
+ image was successfully loaded; otherwise returns FALSE.
+
+ If \a format is specified, the loader attempts to read the image
+ using the specified format. If \a format is not specified (which
+ is the default), the loader reads a few bytes from the header to
+ guess the file format.
+
+ The TQImageIO documentation lists the supported image formats and
+ explains how to add extra formats.
+
+ \sa loadFromData() save() imageFormat() TQPixmap::load() TQImageIO
+*/
+
+bool TQImage::load( const TQString &fileName, const char* format )
+{
+ TQImageIO io( fileName, format );
+ bool result = io.read();
+ if ( result )
+ operator=( io.image() );
+ return result;
+}
+
+/*!
+ Loads an image from the first \a len bytes of binary data in \a
+ buf. Returns TRUE if the image was successfully loaded; otherwise
+ returns FALSE.
+
+ If \a format is specified, the loader attempts to read the image
+ using the specified format. If \a format is not specified (which
+ is the default), the loader reads a few bytes from the header to
+ guess the file format.
+
+ The TQImageIO documentation lists the supported image formats and
+ explains how to add extra formats.
+
+ \sa load() save() imageFormat() TQPixmap::loadFromData() TQImageIO
+*/
+
+bool TQImage::loadFromData( const uchar *buf, uint len, const char *format )
+{
+ TQByteArray a;
+ a.setRawData( (char *)buf, len );
+ TQBuffer b( a );
+ b.open( IO_ReadOnly );
+ TQImageIO io( &b, format );
+ bool result = io.read();
+ b.close();
+ a.resetRawData( (char *)buf, len );
+ if ( result )
+ operator=( io.image() );
+ return result;
+}
+
+/*!
+ \overload
+
+ Loads an image from the TQByteArray \a buf.
+*/
+bool TQImage::loadFromData( TQByteArray buf, const char *format )
+{
+ return loadFromData( (const uchar *)(buf.data()), buf.size(), format );
+}
+
+/*!
+ Saves the image to the file \a fileName, using the image file
+ format \a format and a quality factor of \a quality. \a quality
+ must be in the range 0..100 or -1. Specify 0 to obtain small
+ compressed files, 100 for large uncompressed files, and -1 (the
+ default) to use the default settings.
+
+ Returns TRUE if the image was successfully saved; otherwise
+ returns FALSE.
+
+ \sa load() loadFromData() imageFormat() TQPixmap::save() TQImageIO
+*/
+
+bool TQImage::save( const TQString &fileName, const char* format, int quality ) const
+{
+ if ( isNull() )
+ return FALSE; // nothing to save
+ TQImageIO io( fileName, format );
+ return doImageIO( &io, quality );
+}
+
+/*!
+ \overload
+
+ This function writes a TQImage to the TQIODevice, \a tqdevice. This
+ can be used, for example, to save an image directly into a
+ TQByteArray:
+ \code
+ TQImage image;
+ TQByteArray ba;
+ TQBuffer buffer( ba );
+ buffer.open( IO_WriteOnly );
+ image.save( &buffer, "PNG" ); // writes image into ba in PNG format
+ \endcode
+*/
+
+bool TQImage::save( TQIODevice* tqdevice, const char* format, int quality ) const
+{
+ if ( isNull() )
+ return FALSE; // nothing to save
+ TQImageIO io( tqdevice, format );
+ return doImageIO( &io, quality );
+}
+
+/* \internal
+*/
+
+bool TQImage::doImageIO( TQImageIO* io, int quality ) const
+{
+ if ( !io )
+ return FALSE;
+ io->setImage( *this );
+#if defined(TQT_CHECK_RANGE)
+ if ( quality > 100 || quality < -1 )
+ qWarning( "TQPixmap::save: quality out of range [-1,100]" );
+#endif
+ if ( quality >= 0 )
+ io->setQuality( TQMIN(quality,100) );
+ return io->write();
+}
+#endif //TQT_NO_IMAGEIO
+
+/*****************************************************************************
+ TQImage stream functions
+ *****************************************************************************/
+#if !defined(TQT_NO_DATASTREAM) && !defined(TQT_NO_IMAGEIO)
+/*!
+ \relates TQImage
+
+ Writes the image \a image to the stream \a s as a PNG image, or as a
+ BMP image if the stream's version is 1.
+
+ Note that writing the stream to a file will not produce a valid image file.
+
+ \sa TQImage::save()
+ \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQImage &image )
+{
+ if ( s.version() >= 5 ) {
+ if ( image.isNull() ) {
+ s << (TQ_INT32) 0; // null image marker
+ return s;
+ } else {
+ s << (TQ_INT32) 1;
+ // continue ...
+ }
+ }
+ TQImageIO io;
+ io.setIODevice( s.tqdevice() );
+ if ( s.version() == 1 )
+ io.setFormat( "BMP" );
+ else
+ io.setFormat( "PNG" );
+
+ io.setImage( image );
+ io.write();
+ return s;
+}
+
+/*!
+ \relates TQImage
+
+ Reads an image from the stream \a s and stores it in \a image.
+
+ \sa TQImage::load()
+ \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQImage &image )
+{
+ if ( s.version() >= 5 ) {
+ TQ_INT32 nullMarker;
+ s >> nullMarker;
+ if ( !nullMarker ) {
+ image = TQImage(); // null image
+ return s;
+ }
+ }
+ TQImageIO io( s.tqdevice(), 0 );
+ if ( io.read() )
+ image = io.image();
+ return s;
+}
+#endif
+
+/*****************************************************************************
+ Standard image io handlers (defined below)
+ *****************************************************************************/
+
+// standard image io handlers (defined below)
+#ifndef TQT_NO_IMAGEIO_BMP
+static void read_bmp_image( TQImageIO * );
+static void write_bmp_image( TQImageIO * );
+#endif
+#ifndef TQT_NO_IMAGEIO_PPM
+static void read_pbm_image( TQImageIO * );
+static void write_pbm_image( TQImageIO * );
+#endif
+#ifndef TQT_NO_IMAGEIO_XBM
+static void read_xbm_image( TQImageIO * );
+static void write_xbm_image( TQImageIO * );
+#endif
+#ifndef TQT_NO_IMAGEIO_XPM
+static void read_xpm_image( TQImageIO * );
+static void write_xpm_image( TQImageIO * );
+#endif
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+static void read_async_image( TQImageIO * ); // Not in table of handlers
+#endif
+
+/*****************************************************************************
+ Misc. utility functions
+ *****************************************************************************/
+#if !defined(TQT_NO_IMAGEIO_XPM) || !defined(TQT_NO_IMAGEIO_XBM)
+static TQString fbname( const TQString &fileName ) // get file basename (sort of)
+{
+ TQString s = fileName;
+ if ( !s.isEmpty() ) {
+ int i;
+ if ( (i = s.tqfindRev('/')) >= 0 )
+ s = s.mid( i );
+ if ( (i = s.tqfindRev('\\')) >= 0 )
+ s = s.mid( i );
+ TQRegExp r( TQString::tqfromLatin1("[a-zA-Z][a-zA-Z0-9_]*") );
+ int p = r.search( s );
+ if ( p == -1 )
+ s.truncate( 0 );
+ else
+ s = s.mid( p, r.matchedLength() );
+ }
+ if ( s.isEmpty() )
+ s = TQString::tqfromLatin1( "dummy" );
+ return s;
+}
+#endif
+
+#ifndef TQT_NO_IMAGEIO_BMP
+static void swapPixel01( TQImage *image ) // 1-bpp: swap 0 and 1 pixels
+{
+ int i;
+ if ( image->depth() == 1 && image->numColors() == 2 ) {
+ register uint *p = (uint *)image->bits();
+ int nbytes = image->numBytes();
+ for ( i=0; i<nbytes/4; i++ ) {
+ *p = ~*p;
+ p++;
+ }
+ uchar *p2 = (uchar *)p;
+ for ( i=0; i<(nbytes&3); i++ ) {
+ *p2 = ~*p2;
+ p2++;
+ }
+ TQRgb t = image->color(0); // swap color 0 and 1
+ image->setColor( 0, image->color(1) );
+ image->setColor( 1, t );
+ }
+}
+#endif
+
+
+/*****************************************************************************
+ TQImageIO member functions
+ *****************************************************************************/
+
+/*!
+ \class TQImageIO tqimage.h
+
+ \brief The TQImageIO class tqcontains parameters for loading and
+ saving images.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup io
+
+ TQImageIO tqcontains a TQIODevice object that is used for image data
+ I/O. The programmer can install new image file formats in addition
+ to those that TQt provides.
+
+ TQt currently supports the following image file formats: PNG, BMP,
+ XBM, XPM and PNM. It may also support JPEG, MNG and GIF, if
+ specially configured during compilation. The different PNM formats
+ are: PBM (P1 or P4), PGM (P2 or P5), and PPM (P3 or P6).
+
+ You don't normally need to use this class; TQPixmap::load(),
+ TQPixmap::save(), and TQImage contain sufficient functionality.
+
+ For image files that contain sequences of images, only the first
+ is read. See TQMovie for loading multiple images.
+
+ PBM, PGM, and PPM format \e output is always in the more condensed
+ raw format. PPM and PGM files with more than 256 levels of
+ intensity are scaled down when reading.
+
+ \warning If you are in a country which recognizes software patents
+ and in which Unisys holds a patent on LZW compression and/or
+ decompression and you want to use GIF, Unisys may require you to
+ license the technology. Such countries include Canada, Japan, the
+ USA, France, Germany, Italy and the UK.
+
+ GIF support may be removed completely in a future version of TQt.
+ We recommend using the PNG format.
+
+ \sa TQImage TQPixmap TQFile TQMovie
+*/
+
+#ifndef TQT_NO_IMAGEIO
+struct TQImageIOData
+{
+ const char *parameters;
+ int quality;
+ float gamma;
+};
+
+/*!
+ Constructs a TQImageIO object with all parameters set to zero.
+*/
+
+TQImageIO::TQImageIO()
+{
+ init();
+}
+
+/*!
+ Constructs a TQImageIO object with the I/O tqdevice \a ioDevice and a
+ \a format tag.
+*/
+
+TQImageIO::TQImageIO( TQIODevice *ioDevice, const char *format )
+ : frmt(format)
+{
+ init();
+ iodev = ioDevice;
+}
+
+/*!
+ Constructs a TQImageIO object with the file name \a fileName and a
+ \a format tag.
+*/
+
+TQImageIO::TQImageIO( const TQString &fileName, const char* format )
+ : frmt(format), fname(fileName)
+{
+ init();
+}
+
+/*!
+ Contains initialization common to all TQImageIO constructors.
+*/
+
+void TQImageIO::init()
+{
+ d = new TQImageIOData();
+ d->parameters = 0;
+ d->quality = -1; // default quality of the current format
+ d->gamma=0.0f;
+ iostat = 0;
+ iodev = 0;
+}
+
+/*!
+ Destroys the object and all related data.
+*/
+
+TQImageIO::~TQImageIO()
+{
+ if ( d->parameters )
+ delete [] (char*)d->parameters;
+ delete d;
+}
+
+
+/*****************************************************************************
+ TQImageIO image handler functions
+ *****************************************************************************/
+
+class TQImageHandler
+{
+public:
+ TQImageHandler( const char *f, const char *h, const TQCString& fl,
+ image_io_handler r, image_io_handler w );
+ TQCString format; // image format
+ TQRegExp header; // image header pattern
+ enum TMode { Untranslated=0, TranslateIn, TranslateInOut } text_mode;
+ image_io_handler read_image; // image read function
+ image_io_handler write_image; // image write function
+ bool obsolete; // support not "published"
+};
+
+TQImageHandler::TQImageHandler( const char *f, const char *h, const TQCString& fl,
+ image_io_handler r, image_io_handler w )
+ : format(f), header(TQString::tqfromLatin1(h))
+{
+ text_mode = Untranslated;
+ if ( fl.tqcontains('t') )
+ text_mode = TranslateIn;
+ else if ( fl.tqcontains('T') )
+ text_mode = TranslateInOut;
+ obsolete = fl.tqcontains('O');
+ read_image = r;
+ write_image = w;
+}
+
+typedef TQPtrList<TQImageHandler> TQIHList;// list of image handlers
+static TQIHList *imageHandlers = 0;
+#ifndef TQT_NO_COMPONENT
+static TQPluginManager<TQImageFormatInterface> *plugin_manager = 0;
+#else
+static void *plugin_manager = 0;
+#endif
+
+void qt_init_image_plugins()
+{
+#ifndef TQT_NO_COMPONENT
+ if ( plugin_manager )
+ return;
+
+ plugin_manager = new TQPluginManager<TQImageFormatInterface>( IID_TQImageFormat, TQApplication::libraryPaths(), "/imageformats" );
+
+ TQStringList features = plugin_manager->featureList();
+ TQStringList::Iterator it = features.begin();
+ while ( it != features.end() ) {
+ TQString str = *it;
+ ++it;
+ TQInterfacePtr<TQImageFormatInterface> iface;
+ plugin_manager->queryInterface( str, &iface );
+ if ( iface )
+ iface->installIOHandler( str );
+ }
+#endif
+}
+
+static void cleanup()
+{
+ // make sure that image handlers are delete before plugin manager
+ delete imageHandlers;
+ imageHandlers = 0;
+#ifndef TQT_NO_COMPONENT
+ delete plugin_manager;
+ plugin_manager = 0;
+#endif
+}
+
+void qt_init_image_handlers() // initialize image handlers
+{
+ if ( !imageHandlers ) {
+ imageHandlers = new TQIHList;
+ TQ_CHECK_PTR( imageHandlers );
+ imageHandlers->setAutoDelete( TRUE );
+ qAddPostRoutine( cleanup );
+#ifndef TQT_NO_IMAGEIO_BMP
+ TQImageIO::defineIOHandler( "BMP", "^BM", 0,
+ read_bmp_image, write_bmp_image );
+#endif
+#ifndef TQT_NO_IMAGEIO_PPM
+ TQImageIO::defineIOHandler( "PBM", "^P1", "t",
+ read_pbm_image, write_pbm_image );
+ TQImageIO::defineIOHandler( "PBMRAW", "^P4", "O",
+ read_pbm_image, write_pbm_image );
+ TQImageIO::defineIOHandler( "PGM", "^P2", "t",
+ read_pbm_image, write_pbm_image );
+ TQImageIO::defineIOHandler( "PGMRAW", "^P5", "O",
+ read_pbm_image, write_pbm_image );
+ TQImageIO::defineIOHandler( "PPM", "^P3", "t",
+ read_pbm_image, write_pbm_image );
+ TQImageIO::defineIOHandler( "PPMRAW", "^P6", "O",
+ read_pbm_image, write_pbm_image );
+#endif
+#ifndef TQT_NO_IMAGEIO_XBM
+ TQImageIO::defineIOHandler( "XBM", "^((/\\*(?!.XPM.\\*/))|#define)", "T",
+ read_xbm_image, write_xbm_image );
+#endif
+#ifndef TQT_NO_IMAGEIO_XPM
+ TQImageIO::defineIOHandler( "XPM", "/\\*.XPM.\\*/", "T",
+ read_xpm_image, write_xpm_image );
+#endif
+#ifndef TQT_NO_IMAGEIO_MNG
+ qInitMngIO();
+#endif
+#ifndef TQT_NO_IMAGEIO_PNG
+ qInitPngIO();
+#endif
+#ifndef TQT_NO_IMAGEIO_JPEG
+ qInitJpegIO();
+#endif
+ }
+}
+
+static TQImageHandler *get_image_handler( const char *format )
+{ // get pointer to handler
+ qt_init_image_handlers();
+ qt_init_image_plugins();
+ register TQImageHandler *p = imageHandlers->first();
+ while ( p ) { // traverse list
+ if ( p->format == format )
+ return p;
+ p = imageHandlers->next();
+ }
+ return 0; // no such handler
+}
+
+
+/*!
+ Defines an image I/O handler for the image format called \a
+ format, which is recognized using the \link tqregexp.html#details
+ regular expression\endlink \a header, read using \a readImage and
+ written using \a writeImage.
+
+ \a flags is a string of single-character flags for this format.
+ The only flag defined currently is T (upper case), so the only
+ legal value for \a flags are "T" and the empty string. The "T"
+ flag means that the image file is a text file, and TQt should treat
+ all newline conventions as equivalent. (XPM files and some PPM
+ files are text files for example.)
+
+ \a format is used to select a handler to write a TQImage; \a header
+ is used to select a handler to read an image file.
+
+ If \a readImage is a null pointer, the TQImageIO will not be able
+ to read images in \a format. If \a writeImage is a null pointer,
+ the TQImageIO will not be able to write images in \a format. If
+ both are null, the TQImageIO object is valid but useless.
+
+ Example:
+ \code
+ void readGIF( TQImageIO *image )
+ {
+ // read the image using the image->ioDevice()
+ }
+
+ void writeGIF( TQImageIO *image )
+ {
+ // write the image using the image->ioDevice()
+ }
+
+ // add the GIF image handler
+
+ TQImageIO::defineIOHandler( "GIF",
+ "^GIF[0-9][0-9][a-z]",
+ 0,
+ readGIF,
+ writeGIF );
+ \endcode
+
+ Before the regex test, all the 0 bytes in the file header are
+ converted to 1 bytes. This is done because when TQt was
+ ASCII-based, TQRegExp could not handle 0 bytes in strings.
+
+ The regexp is only applied on the first 14 bytes of the file.
+
+ Note that TQt assumes that there is only one handler per format; if
+ two handlers support the same format, TQt will choose one
+ arbitrarily. It is not possible to have one handler support
+ reading, and another support writing.
+*/
+
+void TQImageIO::defineIOHandler( const char *format,
+ const char *header,
+ const char *flags,
+ image_io_handler readImage,
+ image_io_handler writeImage )
+{
+ qt_init_image_handlers();
+ TQImageHandler *p;
+ p = new TQImageHandler( format, header, flags,
+ readImage, writeImage );
+ TQ_CHECK_PTR( p );
+ imageHandlers->insert( 0, p );
+}
+
+
+/*****************************************************************************
+ TQImageIO normal member functions
+ *****************************************************************************/
+
+/*!
+ \fn const TQImage &TQImageIO::image() const
+
+ Returns the image currently set.
+
+ \sa setImage()
+*/
+
+/*!
+ \fn int TQImageIO::status() const
+
+ Returns the image's IO status. A non-zero value indicates an
+ error, whereas 0 means that the IO operation was successful.
+
+ \sa setqStatus()
+*/
+
+/*!
+ \fn const char *TQImageIO::format() const
+
+ Returns the image format string or 0 if no format has been
+ explicitly set.
+*/
+
+/*!
+ \fn TQIODevice *TQImageIO::ioDevice() const
+
+ Returns the IO tqdevice currently set.
+
+ \sa setIODevice()
+*/
+
+/*!
+ \fn TQString TQImageIO::fileName() const
+
+ Returns the file name currently set.
+
+ \sa setFileName()
+*/
+
+/*!
+ \fn TQString TQImageIO::description() const
+
+ Returns the image description string.
+
+ \sa setDescription()
+*/
+
+
+/*!
+ Sets the image to \a image.
+
+ \sa image()
+*/
+
+void TQImageIO::setImage( const TQImage &image )
+{
+ im = image;
+}
+
+/*!
+ Sets the image IO status to \a status. A non-zero value indicates
+ an error, whereas 0 means that the IO operation was successful.
+
+ \sa status()
+*/
+
+void TQImageIO::setqStatus( int status )
+{
+ iostat = status;
+}
+
+/*!
+ Sets the image format to \a format for the image to be read or
+ written.
+
+ It is necessary to specify a format before writing an image, but
+ it is not necessary to specify a format before reading an image.
+
+ If no format has been set, TQt guesses the image format before
+ reading it. If a format is set the image will only be read if it
+ has that format.
+
+ \sa read() write() format()
+*/
+
+void TQImageIO::setFormat( const char *format )
+{
+ frmt = format;
+}
+
+/*!
+ Sets the IO tqdevice to be used for reading or writing an image.
+
+ Setting the IO tqdevice allows images to be read/written to any
+ block-oriented TQIODevice.
+
+ If \a ioDevice is not null, this IO tqdevice will override file name
+ settings.
+
+ \sa setFileName()
+*/
+
+void TQImageIO::setIODevice( TQIODevice *ioDevice )
+{
+ iodev = ioDevice;
+}
+
+/*!
+ Sets the name of the file to read or write an image from to \a
+ fileName.
+
+ \sa setIODevice()
+*/
+
+void TQImageIO::setFileName( const TQString &fileName )
+{
+ fname = fileName;
+}
+
+/*!
+ Returns the quality of the written image, related to the
+ compression ratio.
+
+ \sa setQuality() TQImage::save()
+*/
+
+int TQImageIO::quality() const
+{
+ return d->quality;
+}
+
+/*!
+ Sets the quality of the written image to \a q, related to the
+ compression ratio.
+
+ \a q must be in the range -1..100. Specify 0 to obtain small
+ compressed files, 100 for large uncompressed files. (-1 signifies
+ the default compression.)
+
+ \sa quality() TQImage::save()
+*/
+
+void TQImageIO::setQuality( int q )
+{
+ d->quality = q;
+}
+
+/*!
+ Returns the image's parameters string.
+
+ \sa setParameters()
+*/
+
+const char *TQImageIO::parameters() const
+{
+ return d->parameters;
+}
+
+/*!
+ Sets the image's parameter string to \a parameters. This is for
+ image handlers that require special parameters.
+
+ Although the current image formats supported by TQt ignore the
+ parameters string, it may be used in future extensions or by
+ contributions (for example, JPEG).
+
+ \sa parameters()
+*/
+
+void TQImageIO::setParameters( const char *parameters )
+{
+ if ( d && d->parameters )
+ delete [] (char*)d->parameters;
+ d->parameters = qstrdup( parameters );
+}
+
+/*!
+ Sets the gamma value at which the image will be viewed to \a
+ gamma. If the image format stores a gamma value for which the
+ image is intended to be used, then this setting will be used to
+ modify the image. Setting to 0.0 will disable gamma correction
+ (i.e. any specification in the file will be ignored).
+
+ The default value is 0.0.
+
+ \sa gamma()
+*/
+void TQImageIO::setGamma( float gamma )
+{
+ d->gamma=gamma;
+}
+
+/*!
+ Returns the gamma value at which the image will be viewed.
+
+ \sa setGamma()
+*/
+float TQImageIO::gamma() const
+{
+ return d->gamma;
+}
+
+/*!
+ Sets the image description string for image handlers that support
+ image descriptions to \a description.
+
+ Currently, no image format supported by TQt uses the description
+ string.
+*/
+
+void TQImageIO::setDescription( const TQString &description )
+{
+ descr = description;
+}
+
+
+/*!
+ Returns a string that specifies the image format of the file \a
+ fileName, or null if the file cannot be read or if the format is
+ not recognized.
+*/
+
+const char* TQImageIO::imageFormat( const TQString &fileName )
+{
+ TQFile file( fileName );
+ if ( !file.open(IO_ReadOnly) )
+ return 0;
+ const char* format = imageFormat( &file );
+ file.close();
+ return format;
+}
+
+/*!
+ \overload
+
+ Returns a string that specifies the image format of the image read
+ from IO tqdevice \a d, or 0 if the tqdevice cannot be read or if the
+ format is not recognized.
+
+ Make sure that \a d is at the right position in the tqdevice (for
+ example, at the beginning of the file).
+
+ \sa TQIODevice::at()
+*/
+
+const char *TQImageIO::imageFormat( TQIODevice *d )
+{
+ // if you change this change the documentation for defineIOHandler()
+ const int buflen = 14;
+
+ char buf[buflen];
+ char buf2[buflen];
+ qt_init_image_handlers();
+ qt_init_image_plugins();
+ int pos = d->at(); // save position
+ int rdlen = d->readBlock( buf, buflen ); // read a few bytes
+
+ if ( rdlen != buflen )
+ return 0;
+
+ memcpy( buf2, buf, buflen );
+
+ const char* format = 0;
+ for ( int n = 0; n < rdlen; n++ )
+ if ( buf[n] == '\0' )
+ buf[n] = '\001';
+ if ( d->status() == IO_Ok && rdlen > 0 ) {
+ buf[rdlen - 1] = '\0';
+ TQString bufStr = TQString::tqfromLatin1(buf);
+ TQImageHandler *p = imageHandlers->first();
+ int bestMatch = -1;
+ while ( p ) {
+ if ( p->read_image && p->header.search(bufStr) != -1 ) {
+ // try match with header if a read function is available
+ if (p->header.matchedLength() > bestMatch) {
+ // keep looking for best match
+ format = p->format;
+ bestMatch = p->header.matchedLength();
+ }
+ }
+ p = imageHandlers->next();
+ }
+ }
+ d->at( pos ); // restore position
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+ if ( !format )
+ format = TQImageDecoder::formatName( (uchar*)buf2, rdlen );
+#endif
+
+ return format;
+}
+
+/*!
+ Returns a sorted list of image formats that are supported for
+ image input.
+*/
+TQStrList TQImageIO::inputFormats()
+{
+ TQStrList result;
+
+ qt_init_image_handlers();
+ qt_init_image_plugins();
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+ // Include asynchronous loaders first.
+ result = TQImageDecoder::inputFormats();
+#endif
+
+ TQImageHandler *p = imageHandlers->first();
+ while ( p ) {
+ if ( p->read_image
+ && !p->obsolete
+ && !result.tqcontains(p->format) )
+ {
+ result.inSort(p->format);
+ }
+ p = imageHandlers->next();
+ }
+
+ return result;
+}
+
+/*!
+ Returns a sorted list of image formats that are supported for
+ image output.
+*/
+TQStrList TQImageIO::outputFormats()
+{
+ TQStrList result;
+
+ qt_init_image_handlers();
+ qt_init_image_plugins();
+
+ // Include asynchronous writers (!) first.
+ // (None)
+
+ TQImageHandler *p = imageHandlers->first();
+ while ( p ) {
+ if ( p->write_image
+ && !p->obsolete
+ && !result.tqcontains(p->format) )
+ {
+ result.inSort(p->format);
+ }
+ p = imageHandlers->next();
+ }
+
+ return result;
+}
+
+
+
+/*!
+ Reads an image into memory and returns TRUE if the image was
+ successfully read; otherwise returns FALSE.
+
+ Before reading an image you must set an IO tqdevice or a file name.
+ If both an IO tqdevice and a file name have been set, the IO tqdevice
+ will be used.
+
+ Setting the image file format string is optional.
+
+ Note that this function does \e not set the \link format()
+ format\endlink used to read the image. If you need that
+ information, use the imageFormat() static functions.
+
+ Example:
+
+ \code
+ TQImageIO iio;
+ TQPixmap pixmap;
+ iio.setFileName( "vegeburger.bmp" );
+ if ( image.read() ) // ok
+ pixmap = iio.image(); // convert to pixmap
+ \endcode
+
+ \sa setIODevice() setFileName() setFormat() write() TQPixmap::load()
+*/
+
+bool TQImageIO::read()
+{
+ TQFile file;
+ const char *image_format;
+ TQImageHandler *h;
+
+ if ( iodev ) { // read from io tqdevice
+ // ok, already open
+ } else if ( !fname.isEmpty() ) { // read from file
+ file.setName( fname );
+ if ( !file.open(IO_ReadOnly) )
+ return FALSE; // cannot open file
+ iodev = &file;
+ } else { // no file name or io tqdevice
+ return FALSE;
+ }
+ if (frmt.isEmpty()) {
+ // Try to guess format
+ image_format = imageFormat( iodev ); // get image format
+ if ( !image_format ) {
+ if ( file.isOpen() ) { // unknown format
+ file.close();
+ iodev = 0;
+ }
+ return FALSE;
+ }
+ } else {
+ image_format = frmt;
+ }
+
+ h = get_image_handler( image_format );
+ if ( file.isOpen() ) {
+#if !defined(TQ_OS_UNIX)
+ if ( h && h->text_mode ) { // reopen in translated mode
+ file.close();
+ file.open( IO_ReadOnly | IO_Translate );
+ }
+ else
+#endif
+ file.at( 0 ); // position to start
+ }
+ iostat = 1; // assume error
+
+ if ( h && h->read_image ) {
+ (*h->read_image)( this );
+ }
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+ else {
+ // Format name, but no handler - must be an asychronous reader
+ read_async_image( this );
+ }
+#endif
+
+ if ( file.isOpen() ) { // image was read using file
+ file.close();
+ iodev = 0;
+ }
+ return iostat == 0; // image successfully read?
+}
+
+
+/*!
+ Writes an image to an IO tqdevice and returns TRUE if the image was
+ successfully written; otherwise returns FALSE.
+
+ Before writing an image you must set an IO tqdevice or a file name.
+ If both an IO tqdevice and a file name have been set, the IO tqdevice
+ will be used.
+
+ The image will be written using the specified image format.
+
+ Example:
+ \code
+ TQImageIO iio;
+ TQImage im;
+ im = pixmap; // convert to image
+ iio.setImage( im );
+ iio.setFileName( "vegeburger.bmp" );
+ iio.setFormat( "BMP" );
+ if ( iio.write() )
+ // returned TRUE if written successfully
+ \endcode
+
+ \sa setIODevice() setFileName() setFormat() read() TQPixmap::save()
+*/
+
+bool TQImageIO::write()
+{
+ if ( frmt.isEmpty() )
+ return FALSE;
+ TQImageHandler *h = get_image_handler( frmt );
+ if ( !h && !plugin_manager) {
+ qt_init_image_plugins();
+ h = get_image_handler( frmt );
+ }
+ if ( !h || !h->write_image ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImageIO::write: No such image format handler: %s",
+ format() );
+#endif
+ return FALSE;
+ }
+ TQFile file;
+ if ( !iodev && !fname.isEmpty() ) {
+ file.setName( fname );
+ bool translate = h->text_mode==TQImageHandler::TranslateInOut;
+ int fmode = translate ? IO_WriteOnly|IO_Translate : IO_WriteOnly;
+ if ( !file.open(fmode) ) // couldn't create file
+ return FALSE;
+ iodev = &file;
+ }
+ iostat = 1;
+ (*h->write_image)( this );
+ if ( file.isOpen() ) { // image was written using file
+ file.close();
+ iodev = 0;
+ }
+ return iostat == 0; // image successfully written?
+}
+#endif //TQT_NO_IMAGEIO
+
+#ifndef TQT_NO_IMAGEIO_BMP
+
+/*****************************************************************************
+ BMP (DIB) image read/write functions
+ *****************************************************************************/
+
+const int BMP_FILEHDR_SIZE = 14; // size of BMP_FILEHDR data
+
+struct BMP_FILEHDR { // BMP file header
+ char bfType[2]; // "BM"
+ TQ_INT32 bfSize; // size of file
+ TQ_INT16 bfReserved1;
+ TQ_INT16 bfReserved2;
+ TQ_INT32 bfOffBits; // pointer to the pixmap bits
+};
+
+TQDataStream &operator>>( TQDataStream &s, BMP_FILEHDR &bf )
+{ // read file header
+ s.readRawBytes( bf.bfType, 2 );
+ s >> bf.bfSize >> bf.bfReserved1 >> bf.bfReserved2 >> bf.bfOffBits;
+ return s;
+}
+
+TQDataStream &operator<<( TQDataStream &s, const BMP_FILEHDR &bf )
+{ // write file header
+ s.writeRawBytes( bf.bfType, 2 );
+ s << bf.bfSize << bf.bfReserved1 << bf.bfReserved2 << bf.bfOffBits;
+ return s;
+}
+
+
+const int BMP_OLD = 12; // old Windows/OS2 BMP size
+const int BMP_WIN = 40; // new Windows BMP size
+const int BMP_OS2 = 64; // new OS/2 BMP size
+
+const int BMP_RGB = 0; // no compression
+const int BMP_RLE8 = 1; // run-length encoded, 8 bits
+const int BMP_RLE4 = 2; // run-length encoded, 4 bits
+const int BMP_BITFIELDS = 3; // RGB values encoded in data as bit-fields
+
+struct BMP_INFOHDR { // BMP information header
+ TQ_INT32 biSize; // size of this struct
+ TQ_INT32 biWidth; // pixmap width
+ TQ_INT32 biHeight; // pixmap height
+ TQ_INT16 biPlanes; // should be 1
+ TQ_INT16 biBitCount; // number of bits per pixel
+ TQ_INT32 biCompression; // compression method
+ TQ_INT32 biSizeImage; // size of image
+ TQ_INT32 biXPelsPerMeter; // horizontal resolution
+ TQ_INT32 biYPelsPerMeter; // vertical resolution
+ TQ_INT32 biClrUsed; // number of colors used
+ TQ_INT32 biClrImportant; // number of important colors
+};
+
+
+TQDataStream &operator>>( TQDataStream &s, BMP_INFOHDR &bi )
+{
+ s >> bi.biSize;
+ if ( bi.biSize == BMP_WIN || bi.biSize == BMP_OS2 ) {
+ s >> bi.biWidth >> bi.biHeight >> bi.biPlanes >> bi.biBitCount;
+ s >> bi.biCompression >> bi.biSizeImage;
+ s >> bi.biXPelsPerMeter >> bi.biYPelsPerMeter;
+ s >> bi.biClrUsed >> bi.biClrImportant;
+ }
+ else { // probably old Windows format
+ TQ_INT16 w, h;
+ s >> w >> h >> bi.biPlanes >> bi.biBitCount;
+ bi.biWidth = w;
+ bi.biHeight = h;
+ bi.biCompression = BMP_RGB; // no compression
+ bi.biSizeImage = 0;
+ bi.biXPelsPerMeter = bi.biYPelsPerMeter = 0;
+ bi.biClrUsed = bi.biClrImportant = 0;
+ }
+ return s;
+}
+
+TQDataStream &operator<<( TQDataStream &s, const BMP_INFOHDR &bi )
+{
+ s << bi.biSize;
+ s << bi.biWidth << bi.biHeight;
+ s << bi.biPlanes;
+ s << bi.biBitCount;
+ s << bi.biCompression;
+ s << bi.biSizeImage;
+ s << bi.biXPelsPerMeter << bi.biYPelsPerMeter;
+ s << bi.biClrUsed << bi.biClrImportant;
+ return s;
+}
+
+static
+int calc_shift(int tqmask)
+{
+ int result = 0;
+ while (!(tqmask & 1)) {
+ result++;
+ tqmask >>= 1;
+ }
+ return result;
+}
+
+static
+bool read_dib( TQDataStream& s, int offset, int startpos, TQImage& image )
+{
+ BMP_INFOHDR bi;
+ TQIODevice* d = s.tqdevice();
+
+ s >> bi; // read BMP info header
+ if ( d->atEnd() ) // end of stream/file
+ return FALSE;
+#if 0
+ qDebug( "offset...........%d", offset );
+ qDebug( "startpos.........%d", startpos );
+ qDebug( "biSize...........%d", bi.biSize );
+ qDebug( "biWidth..........%d", bi.biWidth );
+ qDebug( "biHeight.........%d", bi.biHeight );
+ qDebug( "biPlanes.........%d", bi.biPlanes );
+ qDebug( "biBitCount.......%d", bi.biBitCount );
+ qDebug( "biCompression....%d", bi.biCompression );
+ qDebug( "biSizeImage......%d", bi.biSizeImage );
+ qDebug( "biXPelsPerMeter..%d", bi.biXPelsPerMeter );
+ qDebug( "biYPelsPerMeter..%d", bi.biYPelsPerMeter );
+ qDebug( "biClrUsed........%d", bi.biClrUsed );
+ qDebug( "biClrImportant...%d", bi.biClrImportant );
+#endif
+ int w = bi.biWidth, h = bi.biHeight, nbits = bi.biBitCount;
+ int t = bi.biSize, comp = bi.biCompression;
+ int red_mask, green_mask, blue_mask;
+ int red_shift = 0;
+ int green_shift = 0;
+ int blue_shift = 0;
+ int red_scale = 0;
+ int green_scale = 0;
+ int blue_scale = 0;
+
+ if ( !(nbits == 1 || nbits == 4 || nbits == 8 || nbits == 16 || nbits == 24 || nbits == 32) ||
+ bi.biPlanes != 1 || comp > BMP_BITFIELDS )
+ return FALSE; // weird BMP image
+ if ( !(comp == BMP_RGB || (nbits == 4 && comp == BMP_RLE4) ||
+ (nbits == 8 && comp == BMP_RLE8) || ((nbits == 16 || nbits == 32) && comp == BMP_BITFIELDS)) )
+ return FALSE; // weird compression type
+
+ int ncols;
+ int depth;
+ switch ( nbits ) {
+ case 32:
+ case 24:
+ case 16:
+ depth = 32;
+ break;
+ case 8:
+ case 4:
+ depth = 8;
+ break;
+ default:
+ depth = 1;
+ }
+ if ( depth == 32 ) // there's no colormap
+ ncols = 0;
+ else // # colors used
+ ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits;
+
+ image.create( w, h, depth, ncols, nbits == 1 ?
+ TQImage::BigEndian : TQImage::IgnoreEndian );
+ if ( image.isNull() ) // could not create image
+ return FALSE;
+
+ image.setDotsPerMeterX( bi.biXPelsPerMeter );
+ image.setDotsPerMeterY( bi.biYPelsPerMeter );
+
+ d->at( startpos + BMP_FILEHDR_SIZE + bi.biSize ); // goto start of colormap
+
+ if ( ncols > 0 ) { // read color table
+ uchar rgb[4];
+ int rgb_len = t == BMP_OLD ? 3 : 4;
+ for ( int i=0; i<ncols; i++ ) {
+ if ( d->readBlock( (char *)rgb, rgb_len ) != rgb_len )
+ return FALSE;
+ image.setColor( i, tqRgb(rgb[2],rgb[1],rgb[0]) );
+ if ( d->atEnd() ) // truncated file
+ return FALSE;
+ }
+ } else if (comp == BMP_BITFIELDS && (nbits == 16 || nbits == 32)) {
+ if ( (TQ_ULONG)d->readBlock( (char *)&red_mask, sizeof(red_mask) ) != sizeof(red_mask) )
+ return FALSE;
+ if ( (TQ_ULONG)d->readBlock( (char *)&green_mask, sizeof(green_mask) ) != sizeof(green_mask) )
+ return FALSE;
+ if ( (TQ_ULONG)d->readBlock( (char *)&blue_mask, sizeof(blue_mask) ) != sizeof(blue_mask) )
+ return FALSE;
+ red_shift = calc_shift(red_mask);
+ red_scale = 256 / ((red_mask >> red_shift) + 1);
+ green_shift = calc_shift(green_mask);
+ green_scale = 256 / ((green_mask >> green_shift) + 1);
+ blue_shift = calc_shift(blue_mask);
+ blue_scale = 256 / ((blue_mask >> blue_shift) + 1);
+ } else if (comp == BMP_RGB && (nbits == 24 || nbits == 32)) {
+ blue_mask = 0x000000ff;
+ green_mask = 0x0000ff00;
+ red_mask = 0x00ff0000;
+ blue_shift = 0;
+ green_shift = 8;
+ red_shift = 16;
+ blue_scale = green_scale = red_scale = 1;
+ } else if (comp == BMP_RGB && nbits == 16) // don't support RGB values for 15/16 bpp
+ return FALSE;
+
+ // offset can be bogus, be careful
+ if (offset>=0 && startpos + offset > (TQ_LONG)d->at() )
+ d->at( startpos + offset ); // start of image data
+
+ int bpl = image.bytesPerLine();
+#ifdef TQ_WS_TQWS
+ //
+ // Guess the number of bytes-per-line if we don't know how much
+ // image data is in the file (bogus image ?).
+ //
+ int bmpbpl = bi.biSizeImage > 0 ?
+ bi.biSizeImage / bi.biHeight :
+ (d->size() - offset) / bi.biHeight;
+ int pad = bmpbpl-bpl;
+#endif
+ uchar **line = image.jumpTable();
+
+ if ( nbits == 1 ) { // 1 bit BMP image
+ while ( --h >= 0 ) {
+ if ( d->readBlock((char*)line[h],bpl) != bpl )
+ break;
+#ifdef TQ_WS_TQWS
+ if ( pad > 0 )
+ d->at(d->at()+pad);
+#endif
+ }
+ if ( ncols == 2 && tqGray(image.color(0)) < tqGray(image.color(1)) )
+ swapPixel01( &image ); // pixel 0 is white!
+ }
+
+ else if ( nbits == 4 ) { // 4 bit BMP image
+ int buflen = ((w+7)/8)*4;
+ uchar *buf = new uchar[buflen];
+ TQ_CHECK_PTR( buf );
+ if ( comp == BMP_RLE4 ) { // run length compression
+ int x=0, y=0, b, c, i;
+ register uchar *p = line[h-1];
+ uchar *endp = line[h-1]+w;
+ while ( y < h ) {
+ if ( (b=d->getch()) == EOF )
+ break;
+ if ( b == 0 ) { // escape code
+ switch ( (b=d->getch()) ) {
+ case 0: // end of line
+ x = 0;
+ y++;
+ p = line[h-y-1];
+ break;
+ case 1: // end of image
+ case EOF: // end of file
+ y = h; // exit loop
+ break;
+ case 2: // delta (jump)
+ x += d->getch();
+ y += d->getch();
+
+ // Protection
+ if ( (uint)x >= (uint)w )
+ x = w-1;
+ if ( (uint)y >= (uint)h )
+ y = h-1;
+
+ p = line[h-y-1] + x;
+ break;
+ default: // absolute mode
+ // Protection
+ if ( p + b > endp )
+ b = endp-p;
+
+ i = (c = b)/2;
+ while ( i-- ) {
+ b = d->getch();
+ *p++ = b >> 4;
+ *p++ = b & 0x0f;
+ }
+ if ( c & 1 )
+ *p++ = d->getch() >> 4;
+ if ( (((c & 3) + 1) & 2) == 2 )
+ d->getch(); // align on word boundary
+ x += c;
+ }
+ } else { // encoded mode
+ // Protection
+ if ( p + b > endp )
+ b = endp-p;
+
+ i = (c = b)/2;
+ b = d->getch(); // 2 pixels to be repeated
+ while ( i-- ) {
+ *p++ = b >> 4;
+ *p++ = b & 0x0f;
+ }
+ if ( c & 1 )
+ *p++ = b >> 4;
+ x += c;
+ }
+ }
+ } else if ( comp == BMP_RGB ) { // no compression
+ while ( --h >= 0 ) {
+ if ( d->readBlock((char*)buf,buflen) != buflen )
+ break;
+ register uchar *p = line[h];
+ uchar *b = buf;
+ for ( int i=0; i<w/2; i++ ) { // convert nibbles to bytes
+ *p++ = *b >> 4;
+ *p++ = *b++ & 0x0f;
+ }
+ if ( w & 1 ) // the last nibble
+ *p = *b >> 4;
+ }
+ }
+ delete [] buf;
+ }
+
+ else if ( nbits == 8 ) { // 8 bit BMP image
+ if ( comp == BMP_RLE8 ) { // run length compression
+ int x=0, y=0, b;
+ register uchar *p = line[h-1];
+ const uchar *endp = line[h-1]+w;
+ while ( y < h ) {
+ if ( (b=d->getch()) == EOF )
+ break;
+ if ( b == 0 ) { // escape code
+ switch ( (b=d->getch()) ) {
+ case 0: // end of line
+ x = 0;
+ y++;
+ p = line[h-y-1];
+ break;
+ case 1: // end of image
+ case EOF: // end of file
+ y = h; // exit loop
+ break;
+ case 2: // delta (jump)
+ x += d->getch();
+ y += d->getch();
+
+ // Protection
+ if ( (uint)x >= (uint)w )
+ x = w-1;
+ if ( (uint)y >= (uint)h )
+ y = h-1;
+
+ p = line[h-y-1] + x;
+ break;
+ default: // absolute mode
+ // Protection
+ if ( p + b > endp )
+ b = endp-p;
+
+ if ( d->readBlock( (char *)p, b ) != b )
+ return FALSE;
+ if ( (b & 1) == 1 )
+ d->getch(); // align on word boundary
+ x += b;
+ p += b;
+ }
+ } else { // encoded mode
+ // Protection
+ if ( p + b > endp )
+ b = endp-p;
+
+ memset( p, d->getch(), b ); // repeat pixel
+ x += b;
+ p += b;
+ }
+ }
+ } else if ( comp == BMP_RGB ) { // uncompressed
+ while ( --h >= 0 ) {
+ if ( d->readBlock((char *)line[h],bpl) != bpl )
+ break;
+#ifdef TQ_WS_TQWS
+ if ( pad > 0 )
+ d->at(d->at()+pad);
+#endif
+ }
+ }
+ }
+
+ else if ( nbits == 16 || nbits == 24 || nbits == 32 ) { // 16,24,32 bit BMP image
+ register TQRgb *p;
+ TQRgb *end;
+ uchar *buf24 = new uchar[bpl];
+ int bpl24 = ((w*nbits+31)/32)*4;
+ uchar *b;
+ int c;
+
+ while ( --h >= 0 ) {
+ p = (TQRgb *)line[h];
+ end = p + w;
+ if ( d->readBlock( (char *)buf24,bpl24) != bpl24 )
+ break;
+ b = buf24;
+ while ( p < end ) {
+ c = *(uchar*)b | (*(uchar*)(b+1)<<8);
+ if (nbits != 16)
+ c |= *(uchar*)(b+2)<<16;
+ *p++ = tqRgb(((c & red_mask) >> red_shift) * red_scale,
+ ((c & green_mask) >> green_shift) * green_scale,
+ ((c & blue_mask) >> blue_shift) * blue_scale);
+ b += nbits/8;
+ }
+ }
+ delete[] buf24;
+ }
+
+ return TRUE;
+}
+
+bool qt_read_dib( TQDataStream& s, TQImage& image )
+{
+ return read_dib(s,-1,-BMP_FILEHDR_SIZE,image);
+}
+
+
+static void read_bmp_image( TQImageIO *iio )
+{
+ TQIODevice *d = iio->ioDevice();
+ TQDataStream s( d );
+ BMP_FILEHDR bf;
+ int startpos = d->at();
+
+ s.setByteOrder( TQDataStream::LittleEndian );// Intel byte order
+ s >> bf; // read BMP file header
+
+ if ( tqstrncmp(bf.bfType,"BM",2) != 0 ) // not a BMP image
+ return;
+
+ TQImage image;
+ if (read_dib( s, bf.bfOffBits, startpos, image )) {
+ iio->setImage( image );
+ iio->setqStatus( 0 ); // image ok
+ }
+}
+
+bool qt_write_dib( TQDataStream& s, TQImage image )
+{
+ int nbits;
+ int bpl_bmp;
+ int bpl = image.bytesPerLine();
+
+ TQIODevice* d = s.tqdevice();
+
+ if ( image.depth() == 8 && image.numColors() <= 16 ) {
+ bpl_bmp = (((bpl+1)/2+3)/4)*4;
+ nbits = 4;
+ } else if ( image.depth() == 32 ) {
+ bpl_bmp = ((image.width()*24+31)/32)*4;
+ nbits = 24;
+#ifdef TQ_WS_TQWS
+ } else if ( image.depth() == 1 || image.depth() == 8 ) {
+ // TQt/E doesn't word align.
+ bpl_bmp = ((image.width()*image.depth()+31)/32)*4;
+ nbits = image.depth();
+#endif
+ } else {
+ bpl_bmp = bpl;
+ nbits = image.depth();
+ }
+
+ BMP_INFOHDR bi;
+ bi.biSize = BMP_WIN; // build info header
+ bi.biWidth = image.width();
+ bi.biHeight = image.height();
+ bi.biPlanes = 1;
+ bi.biBitCount = nbits;
+ bi.biCompression = BMP_RGB;
+ bi.biSizeImage = bpl_bmp*image.height();
+ bi.biXPelsPerMeter = image.dotsPerMeterX() ? image.dotsPerMeterX()
+ : 2834; // 72 dpi default
+ bi.biYPelsPerMeter = image.dotsPerMeterY() ? image.dotsPerMeterY() : 2834;
+ bi.biClrUsed = image.numColors();
+ bi.biClrImportant = image.numColors();
+ s << bi; // write info header
+
+ if ( image.depth() != 32 ) { // write color table
+ uchar *color_table = new uchar[4*image.numColors()];
+ uchar *rgb = color_table;
+ TQRgb *c = image.colorTable();
+ for ( int i=0; i<image.numColors(); i++ ) {
+ *rgb++ = tqBlue ( c[i] );
+ *rgb++ = tqGreen( c[i] );
+ *rgb++ = tqRed ( c[i] );
+ *rgb++ = 0;
+ }
+ d->writeBlock( (char *)color_table, 4*image.numColors() );
+ delete [] color_table;
+ }
+
+ if ( image.depth() == 1 && image.bitOrder() != TQImage::BigEndian )
+ image = image.convertBitOrder( TQImage::BigEndian );
+
+ int y;
+
+ if ( nbits == 1 || nbits == 8 ) { // direct output
+#ifdef TQ_WS_TQWS
+ // TQt/E doesn't word align.
+ int pad = bpl_bmp - bpl;
+ char padding[4];
+#endif
+ for ( y=image.height()-1; y>=0; y-- ) {
+ d->writeBlock( (char*)image.scanLine(y), bpl );
+#ifdef TQ_WS_TQWS
+ d->writeBlock( padding, pad );
+#endif
+ }
+ return TRUE;
+ }
+
+ uchar *buf = new uchar[bpl_bmp];
+ uchar *b, *end;
+ register uchar *p;
+
+ memset( buf, 0, bpl_bmp );
+ for ( y=image.height()-1; y>=0; y-- ) { // write the image bits
+ if ( nbits == 4 ) { // convert 8 -> 4 bits
+ p = image.scanLine(y);
+ b = buf;
+ end = b + image.width()/2;
+ while ( b < end ) {
+ *b++ = (*p << 4) | (*(p+1) & 0x0f);
+ p += 2;
+ }
+ if ( image.width() & 1 )
+ *b = *p << 4;
+ } else { // 32 bits
+ TQRgb *p = (TQRgb *)image.scanLine( y );
+ TQRgb *end = p + image.width();
+ b = buf;
+ while ( p < end ) {
+ *b++ = tqBlue(*p);
+ *b++ = tqGreen(*p);
+ *b++ = tqRed(*p);
+ p++;
+ }
+ }
+ if ( bpl_bmp != d->writeBlock( (char*)buf, bpl_bmp ) ) {
+ delete[] buf;
+ return FALSE;
+ }
+ }
+ delete[] buf;
+ return TRUE;
+}
+
+
+static void write_bmp_image( TQImageIO *iio )
+{
+ TQIODevice *d = iio->ioDevice();
+ TQImage image = iio->image();
+ TQDataStream s( d );
+ BMP_FILEHDR bf;
+ int bpl_bmp;
+ int bpl = image.bytesPerLine();
+
+ // Code partially repeated in qt_write_dib
+ if ( image.depth() == 8 && image.numColors() <= 16 ) {
+ bpl_bmp = (((bpl+1)/2+3)/4)*4;
+ } else if ( image.depth() == 32 ) {
+ bpl_bmp = ((image.width()*24+31)/32)*4;
+ } else {
+ bpl_bmp = bpl;
+ }
+
+ iio->setqStatus( 0 );
+ s.setByteOrder( TQDataStream::LittleEndian );// Intel byte order
+ strncpy( bf.bfType, "BM", 2 ); // build file header
+ bf.bfReserved1 = bf.bfReserved2 = 0; // reserved, should be zero
+ bf.bfOffBits = BMP_FILEHDR_SIZE + BMP_WIN + image.numColors()*4;
+ bf.bfSize = bf.bfOffBits + bpl_bmp*image.height();
+ s << bf; // write file header
+
+ if ( !qt_write_dib( s, image ) )
+ iio->setqStatus( 1 );
+
+}
+
+#endif // TQT_NO_IMAGEIO_BMP
+
+#ifndef TQT_NO_IMAGEIO_PPM
+
+/*****************************************************************************
+ PBM/PGM/PPM (ASCII and RAW) image read/write functions
+ *****************************************************************************/
+
+static int read_pbm_int( TQIODevice *d )
+{
+ int c;
+ int val = -1;
+ bool digit;
+ const int buflen = 100;
+ char buf[buflen];
+ for ( ;; ) {
+ if ( (c=d->getch()) == EOF ) // end of file
+ break;
+ digit = isdigit( (uchar) c );
+ if ( val != -1 ) {
+ if ( digit ) {
+ val = 10*val + c - '0';
+ continue;
+ } else {
+ if ( c == '#' ) // comment
+ d->readLine( buf, buflen );
+ break;
+ }
+ }
+ if ( digit ) // first digit
+ val = c - '0';
+ else if ( isspace((uchar) c) )
+ continue;
+ else if ( c == '#' )
+ d->readLine( buf, buflen );
+ else
+ break;
+ }
+ return val;
+}
+
+static void read_pbm_image( TQImageIO *iio ) // read PBM image data
+{
+ const int buflen = 300;
+ char buf[buflen];
+ TQIODevice *d = iio->ioDevice();
+ int w, h, nbits, mcc, y;
+ int pbm_bpl;
+ char type;
+ bool raw;
+ TQImage image;
+
+ if ( d->readBlock( buf, 3 ) != 3 ) // read P[1-6]<white-space>
+ return;
+ if ( !(buf[0] == 'P' && isdigit((uchar) buf[1]) && isspace((uchar) buf[2])) )
+ return;
+ switch ( (type=buf[1]) ) {
+ case '1': // ascii PBM
+ case '4': // raw PBM
+ nbits = 1;
+ break;
+ case '2': // ascii PGM
+ case '5': // raw PGM
+ nbits = 8;
+ break;
+ case '3': // ascii PPM
+ case '6': // raw PPM
+ nbits = 32;
+ break;
+ default:
+ return;
+ }
+ raw = type >= '4';
+ w = read_pbm_int( d ); // get image width
+ h = read_pbm_int( d ); // get image height
+ if ( nbits == 1 )
+ mcc = 1; // ignore max color component
+ else
+ mcc = read_pbm_int( d ); // get max color component
+ if ( w <= 0 || w > 32767 || h <= 0 || h > 32767 || mcc <= 0 )
+ return; // weird P.M image
+
+ int maxc = mcc;
+ if ( maxc > 255 )
+ maxc = 255;
+ image.create( w, h, nbits, 0,
+ nbits == 1 ? TQImage::BigEndian : TQImage::IgnoreEndian );
+ if ( image.isNull() )
+ return;
+
+ pbm_bpl = (nbits*w+7)/8; // bytes per scanline in PBM
+
+ if ( raw ) { // read raw data
+ if ( nbits == 32 ) { // type 6
+ pbm_bpl = 3*w;
+ uchar *buf24 = new uchar[pbm_bpl], *b;
+ TQRgb *p;
+ TQRgb *end;
+ for ( y=0; y<h; y++ ) {
+ if ( d->readBlock( (char *)buf24, pbm_bpl ) != pbm_bpl ) {
+ delete[] buf24;
+ return;
+ }
+ p = (TQRgb *)image.scanLine( y );
+ end = p + w;
+ b = buf24;
+ while ( p < end ) {
+ *p++ = tqRgb(b[0],b[1],b[2]);
+ b += 3;
+ }
+ }
+ delete[] buf24;
+ } else { // type 4,5
+ for ( y=0; y<h; y++ ) {
+ if ( d->readBlock( (char *)image.scanLine(y), pbm_bpl )
+ != pbm_bpl )
+ return;
+ }
+ }
+ } else { // read ascii data
+ register uchar *p;
+ int n;
+ for ( y=0; y<h; y++ ) {
+ p = image.scanLine( y );
+ n = pbm_bpl;
+ if ( nbits == 1 ) {
+ int b;
+ while ( n-- ) {
+ b = 0;
+ for ( int i=0; i<8; i++ )
+ b = (b << 1) | (read_pbm_int(d) & 1);
+ *p++ = b;
+ }
+ } else if ( nbits == 8 ) {
+ if ( mcc == maxc ) {
+ while ( n-- ) {
+ *p++ = read_pbm_int( d );
+ }
+ } else {
+ while ( n-- ) {
+ *p++ = read_pbm_int( d ) * maxc / mcc;
+ }
+ }
+ } else { // 32 bits
+ n /= 4;
+ int r, g, b;
+ if ( mcc == maxc ) {
+ while ( n-- ) {
+ r = read_pbm_int( d );
+ g = read_pbm_int( d );
+ b = read_pbm_int( d );
+ *((TQRgb*)p) = tqRgb( r, g, b );
+ p += 4;
+ }
+ } else {
+ while ( n-- ) {
+ r = read_pbm_int( d ) * maxc / mcc;
+ g = read_pbm_int( d ) * maxc / mcc;
+ b = read_pbm_int( d ) * maxc / mcc;
+ *((TQRgb*)p) = tqRgb( r, g, b );
+ p += 4;
+ }
+ }
+ }
+ }
+ }
+
+ if ( nbits == 1 ) { // bitmap
+ image.setNumColors( 2 );
+ image.setColor( 0, tqRgb(255,255,255) ); // white
+ image.setColor( 1, tqRgb(0,0,0) ); // black
+ } else if ( nbits == 8 ) { // graymap
+ image.setNumColors( maxc+1 );
+ for ( int i=0; i<=maxc; i++ )
+ image.setColor( i, tqRgb(i*255/maxc,i*255/maxc,i*255/maxc) );
+ }
+
+ iio->setImage( image );
+ iio->setqStatus( 0 ); // image ok
+}
+
+
+static void write_pbm_image( TQImageIO *iio )
+{
+ TQIODevice* out = iio->ioDevice();
+ TQCString str;
+
+ TQImage image = iio->image();
+ TQCString format = iio->format();
+ format = format.left(3); // ignore RAW part
+ bool gray = format == "PGM";
+
+ if ( format == "PBM" ) {
+ image = image.convertDepth(1);
+ } else if ( image.depth() == 1 ) {
+ image = image.convertDepth(8);
+ }
+
+ if ( image.depth() == 1 && image.numColors() == 2 ) {
+ if ( tqGray(image.color(0)) < tqGray(image.color(1)) ) {
+ // 0=dark/black, 1=light/white - invert
+ image.detach();
+ for ( int y=0; y<image.height(); y++ ) {
+ uchar *p = image.scanLine(y);
+ uchar *end = p + image.bytesPerLine();
+ while ( p < end )
+ *p++ ^= 0xff;
+ }
+ }
+ }
+
+ uint w = image.width();
+ uint h = image.height();
+
+ str.sprintf("P\n%d %d\n", w, h);
+
+ switch (image.depth()) {
+ case 1: {
+ str.insert(1, '4');
+ if ((uint)out->writeBlock(str, str.length()) != str.length()) {
+ iio->setqStatus(1);
+ return;
+ }
+ w = (w+7)/8;
+ for (uint y=0; y<h; y++) {
+ uchar* line = image.scanLine(y);
+ if ( w != (uint)out->writeBlock((char*)line, w) ) {
+ iio->setqStatus(1);
+ return;
+ }
+ }
+ }
+ break;
+
+ case 8: {
+ str.insert(1, gray ? '5' : '6');
+ str.append("255\n");
+ if ((uint)out->writeBlock(str, str.length()) != str.length()) {
+ iio->setqStatus(1);
+ return;
+ }
+ TQRgb *color = image.colorTable();
+ uint bpl = w*(gray ? 1 : 3);
+ uchar *buf = new uchar[bpl];
+ for (uint y=0; y<h; y++) {
+ uchar *b = image.scanLine(y);
+ uchar *p = buf;
+ uchar *end = buf+bpl;
+ if ( gray ) {
+ while ( p < end ) {
+ uchar g = (uchar)tqGray(color[*b++]);
+ *p++ = g;
+ }
+ } else {
+ while ( p < end ) {
+ TQRgb rgb = color[*b++];
+ *p++ = tqRed(rgb);
+ *p++ = tqGreen(rgb);
+ *p++ = tqBlue(rgb);
+ }
+ }
+ if ( bpl != (uint)out->writeBlock((char*)buf, bpl) ) {
+ iio->setqStatus(1);
+ return;
+ }
+ }
+ delete [] buf;
+ }
+ break;
+
+ case 32: {
+ str.insert(1, gray ? '5' : '6');
+ str.append("255\n");
+ if ((uint)out->writeBlock(str, str.length()) != str.length()) {
+ iio->setqStatus(1);
+ return;
+ }
+ uint bpl = w*(gray ? 1 : 3);
+ uchar *buf = new uchar[bpl];
+ for (uint y=0; y<h; y++) {
+ TQRgb *b = (TQRgb*)image.scanLine(y);
+ uchar *p = buf;
+ uchar *end = buf+bpl;
+ if ( gray ) {
+ while ( p < end ) {
+ uchar g = (uchar)tqGray(*b++);
+ *p++ = g;
+ }
+ } else {
+ while ( p < end ) {
+ TQRgb rgb = *b++;
+ *p++ = tqRed(rgb);
+ *p++ = tqGreen(rgb);
+ *p++ = tqBlue(rgb);
+ }
+ }
+ if ( bpl != (uint)out->writeBlock((char*)buf, bpl) ) {
+ iio->setqStatus(1);
+ return;
+ }
+ }
+ delete [] buf;
+ }
+ }
+
+ iio->setqStatus(0);
+}
+
+#endif // TQT_NO_IMAGEIO_PPM
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+
+class TQImageIOFrameGrabber : public TQImageConsumer {
+public:
+ TQImageIOFrameGrabber() : framecount(0) { }
+
+ TQImageDecoder *decoder;
+ int framecount;
+
+ void changed(const TQRect&) { }
+ void end() { }
+ void frameDone(const TQPoint&, const TQRect&) { framecount++; }
+ void frameDone() { framecount++; }
+ void setLooping(int) { }
+ void setFramePeriod(int) { }
+ void setSize(int, int) { }
+};
+
+static void read_async_image( TQImageIO *iio )
+{
+ const int buf_len = 2048;
+ uchar buffer[buf_len];
+ TQIODevice *d = iio->ioDevice();
+ TQImageIOFrameGrabber* consumer = new TQImageIOFrameGrabber();
+ TQImageDecoder *decoder = new TQImageDecoder(consumer);
+ consumer->decoder = decoder;
+ int startAt = d->at();
+ int totLen = 0;
+
+ for (;;) {
+ int length = d->readBlock((char*)buffer, buf_len);
+ if ( length <= 0 ) {
+ iio->setqStatus(length);
+ break;
+ }
+ uchar* b = buffer;
+ int r = -1;
+ while (length > 0 && consumer->framecount==0) {
+ r = decoder->decode(b, length);
+ if ( r <= 0 ) break;
+ b += r;
+ totLen += r;
+ length -= r;
+ }
+ if ( consumer->framecount ) {
+ // Stopped after first frame
+ if ( d->isDirectAccess() )
+ d->at( startAt + totLen );
+ else {
+ // ### We have (probably) read too much from the stream into
+ // the buffer, and there is no way to put it back!
+ }
+ iio->setImage(decoder->image());
+ iio->setqStatus(0);
+ break;
+ }
+ if ( r <= 0 ) {
+ iio->setqStatus(r);
+ break;
+ }
+ }
+
+ consumer->decoder = 0;
+ delete decoder;
+ delete consumer;
+}
+
+#endif // TQT_NO_ASYNC_IMAGE_IO
+
+#ifndef TQT_NO_IMAGEIO_XBM
+
+/*****************************************************************************
+ X bitmap image read/write functions
+ *****************************************************************************/
+
+static inline int hex2byte( register char *p )
+{
+ return ( (isdigit((uchar) *p) ? *p - '0' : toupper((uchar) *p) - 'A' + 10) << 4 ) |
+ ( isdigit((uchar) *(p+1)) ? *(p+1) - '0' : toupper((uchar) *(p+1)) - 'A' + 10 );
+}
+
+static void read_xbm_image( TQImageIO *iio )
+{
+ const int buflen = 300;
+ char buf[buflen];
+ TQRegExp r1, r2;
+ TQIODevice *d = iio->ioDevice();
+ int w=-1, h=-1;
+ TQImage image;
+
+ r1 = TQString::tqfromLatin1("^#define[ \t]+[a-zA-Z0-9._]+[ \t]+");
+ r2 = TQString::tqfromLatin1("[0-9]+");
+ d->readLine( buf, buflen ); // "#define .._width <num>"
+
+ while (!d->atEnd() && buf[0] != '#') //skip leading comment, if any
+ d->readLine( buf, buflen );
+
+ TQString sbuf;
+ sbuf = TQString::tqfromLatin1(buf);
+
+ if ( r1.search(sbuf) == 0 &&
+ r2.search(sbuf, r1.matchedLength()) == r1.matchedLength() )
+ w = atoi( &buf[r1.matchedLength()] );
+
+ d->readLine( buf, buflen ); // "#define .._height <num>"
+ sbuf = TQString::tqfromLatin1(buf);
+
+ if ( r1.search(sbuf) == 0 &&
+ r2.search(sbuf, r1.matchedLength()) == r1.matchedLength() )
+ h = atoi( &buf[r1.matchedLength()] );
+
+ if ( w <= 0 || w > 32767 || h <= 0 || h > 32767 )
+ return; // format error
+
+ for ( ;; ) { // scan for data
+ if ( d->readLine(buf, buflen) <= 0 ) // end of file
+ return;
+ if ( strstr(buf,"0x") != 0 ) // does line contain data?
+ break;
+ }
+
+ image.create( w, h, 1, 2, TQImage::LittleEndian );
+ if ( image.isNull() )
+ return;
+
+ image.setColor( 0, tqRgb(255,255,255) ); // white
+ image.setColor( 1, tqRgb(0,0,0) ); // black
+
+ int x = 0, y = 0;
+ uchar *b = image.scanLine(0);
+ char *p = strstr( buf, "0x" );
+ w = (w+7)/8; // byte width
+
+ while ( y < h ) { // for all encoded bytes...
+ if ( p ) { // p = "0x.."
+ *b++ = hex2byte(p+2);
+ p += 2;
+ if ( ++x == w && ++y < h ) {
+ b = image.scanLine(y);
+ x = 0;
+ }
+ p = strstr( p, "0x" );
+ } else { // read another line
+ if ( d->readLine(buf,buflen) <= 0 ) // EOF ==> truncated image
+ break;
+ p = strstr( buf, "0x" );
+ }
+ }
+
+ iio->setImage( image );
+ iio->setqStatus( 0 ); // image ok
+}
+
+
+static void write_xbm_image( TQImageIO *iio )
+{
+ TQIODevice *d = iio->ioDevice();
+ TQImage image = iio->image();
+ int w = image.width();
+ int h = image.height();
+ int i;
+ TQString s = fbname(iio->fileName()); // get file base name
+ char *buf = new char[s.length() + 100];
+
+ sprintf( buf, "#define %s_width %d\n", s.ascii(), w );
+ d->writeBlock( buf, tqstrlen(buf) );
+ sprintf( buf, "#define %s_height %d\n", s.ascii(), h );
+ d->writeBlock( buf, tqstrlen(buf) );
+ sprintf( buf, "static char %s_bits[] = {\n ", s.ascii() );
+ d->writeBlock( buf, tqstrlen(buf) );
+
+ iio->setqStatus( 0 );
+
+ if ( image.depth() != 1 )
+ image = image.convertDepth( 1 ); // dither
+ if ( image.bitOrder() != TQImage::LittleEndian )
+ image = image.convertBitOrder( TQImage::LittleEndian );
+
+ bool invert = tqGray(image.color(0)) < tqGray(image.color(1));
+ char hexrep[16];
+ for ( i=0; i<10; i++ )
+ hexrep[i] = '0' + i;
+ for ( i=10; i<16; i++ )
+ hexrep[i] = 'a' -10 + i;
+ if ( invert ) {
+ char t;
+ for ( i=0; i<8; i++ ) {
+ t = hexrep[15-i];
+ hexrep[15-i] = hexrep[i];
+ hexrep[i] = t;
+ }
+ }
+ int bcnt = 0;
+ register char *p = buf;
+ int bpl = (w+7)/8;
+ for (int y = 0; y < h; ++y) {
+ uchar *b = image.scanLine(y);
+ for (i = 0; i < bpl; ++i) {
+ *p++ = '0'; *p++ = 'x';
+ *p++ = hexrep[*b >> 4];
+ *p++ = hexrep[*b++ & 0xf];
+
+ if ( i < bpl - 1 || y < h - 1 ) {
+ *p++ = ',';
+ if ( ++bcnt > 14 ) {
+ *p++ = '\n';
+ *p++ = ' ';
+ *p = '\0';
+ if ( (int)tqstrlen(buf) != d->writeBlock( buf, tqstrlen(buf) ) ) {
+ iio->setqStatus( 1 );
+ delete [] buf;
+ return;
+ }
+ p = buf;
+ bcnt = 0;
+ }
+ }
+ }
+ }
+ strcpy( p, " };\n" );
+ if ( (int)tqstrlen(buf) != d->writeBlock( buf, tqstrlen(buf) ) )
+ iio->setqStatus( 1 );
+ delete [] buf;
+}
+
+#endif // TQT_NO_IMAGEIO_XBM
+
+
+#ifndef TQT_NO_IMAGEIO_XPM
+
+/*****************************************************************************
+ XPM image read/write functions
+ *****************************************************************************/
+
+
+// Skip until ", read until the next ", return the rest in *buf
+// Returns FALSE on error, TRUE on success
+
+static bool read_xpm_string( TQCString &buf, TQIODevice *d,
+ const char * const *source, int &index )
+{
+ if ( source ) {
+ buf = source[index++];
+ return TRUE;
+ }
+
+ if ( buf.size() < 69 ) //# just an approximation
+ buf.resize( 123 );
+
+ buf[0] = '\0';
+ int c;
+ int i;
+ while ( (c=d->getch()) != EOF && c != '"' ) { }
+ if ( c == EOF ) {
+ return FALSE;
+ }
+ i = 0;
+ while ( (c=d->getch()) != EOF && c != '"' ) {
+ if ( i == (int)buf.size() )
+ buf.resize( i*2+42 );
+ buf[i++] = c;
+ }
+ if ( c == EOF ) {
+ return FALSE;
+ }
+
+ if ( i == (int)buf.size() ) // always use a 0 terminator
+ buf.resize( i+1 );
+ buf[i] = '\0';
+ return TRUE;
+}
+
+
+
+static int nextColorSpec(const TQCString & buf)
+{
+ int i = buf.tqfind(" c ");
+ if (i < 0)
+ i = buf.tqfind(" g ");
+ if (i < 0)
+ i = buf.tqfind(" g4 ");
+ if (i < 0)
+ i = buf.tqfind(" m ");
+ if (i < 0)
+ i = buf.tqfind(" s ");
+ return i;
+}
+
+//
+// INTERNAL
+//
+// Reads an .xpm from either the TQImageIO or from the TQString *.
+// One of the two HAS to be 0, the other one is used.
+//
+
+static void read_xpm_image_or_array( TQImageIO * iio, const char * const * source,
+ TQImage & image)
+{
+ TQCString buf;
+ TQIODevice *d = 0;
+ buf.resize( 200 );
+
+ int i, cpp, ncols, w, h, index = 0;
+
+ if ( iio ) {
+ iio->setqStatus( 1 );
+ d = iio ? iio->ioDevice() : 0;
+ d->readLine( buf.data(), buf.size() ); // "/* XPM */"
+ TQRegExp r( TQString::tqfromLatin1("/\\*.XPM.\\*/") );
+ if ( buf.tqfind(r) == -1 )
+ return; // bad magic
+ } else if ( !source ) {
+ return;
+ }
+
+ if ( !read_xpm_string( buf, d, source, index ) )
+ return;
+
+ if ( sscanf( buf, "%d %d %d %d", &w, &h, &ncols, &cpp ) < 4 )
+ return; // < 4 numbers parsed
+
+ if ( cpp > 15 )
+ return;
+
+ if ( ncols > 256 ) {
+ image.create( w, h, 32 );
+ } else {
+ image.create( w, h, 8, ncols );
+ }
+
+ if (image.isNull())
+ return;
+
+ TQMap<TQString, int> colorMap;
+ int currentColor;
+
+ for( currentColor=0; currentColor < ncols; ++currentColor ) {
+ if ( !read_xpm_string( buf, d, source, index ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage: XPM color specification missing");
+#endif
+ return;
+ }
+ TQString index;
+ index = buf.left( cpp );
+ buf = buf.mid( cpp ).simplifyWhiteSpace().lower();
+ buf.prepend( " " );
+ i = nextColorSpec(buf);
+ if ( i < 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage: XPM color specification is missing: %s", buf.data());
+#endif
+ return; // no c/g/g4/m/s specification at all
+ }
+ buf = buf.mid( i+3 );
+ // Strip any other colorspec
+ int end = nextColorSpec(buf);
+ if (end != -1)
+ buf.truncate(end);
+ buf = buf.stripWhiteSpace();
+ if ( buf == "none" ) {
+ image.setAlphaBuffer( TRUE );
+ int transparentColor = currentColor;
+ if ( image.depth() == 8 ) {
+ image.setColor( transparentColor,
+ TQRGB_MASK & tqRgb(198,198,198) );
+ colorMap.insert( index, transparentColor );
+ } else {
+ TQRgb rgb = TQRGB_MASK & tqRgb(198,198,198);
+ colorMap.insert( index, rgb );
+ }
+ } else {
+ if ( ((buf.length()-1) % 3) && (buf[0] == '#') ) {
+ buf.truncate (((buf.length()-1) / 4 * 3) + 1); // remove alpha channel left by imagemagick
+ }
+ TQColor c( buf.data() );
+ if ( image.depth() == 8 ) {
+ image.setColor( currentColor, 0xff000000 | c.rgb() );
+ colorMap.insert( index, currentColor );
+ } else {
+ TQRgb rgb = 0xff000000 | c.rgb();
+ colorMap.insert( index, rgb );
+ }
+ }
+ }
+
+ // Read pixels
+ for( int y=0; y<h; y++ ) {
+ if ( !read_xpm_string( buf, d, source, index ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQImage: XPM pixels missing on image line %d", y);
+#endif
+ return;
+ }
+ if ( image.depth() == 8 ) {
+ uchar *p = image.scanLine(y);
+ uchar *d = (uchar *)buf.data();
+ uchar *end = d + buf.length();
+ int x;
+ if ( cpp == 1 ) {
+ char b[2];
+ b[1] = '\0';
+ for ( x=0; x<w && d<end; x++ ) {
+ b[0] = *d++;
+ *p++ = (uchar)colorMap[b];
+ }
+ } else {
+ char b[16];
+ b[cpp] = '\0';
+ for ( x=0; x<w && d<end; x++ ) {
+ strncpy( b, (char *)d, cpp );
+ *p++ = (uchar)colorMap[b];
+ d += cpp;
+ }
+ }
+ } else {
+ TQRgb *p = (TQRgb*)image.scanLine(y);
+ uchar *d = (uchar *)buf.data();
+ uchar *end = d + buf.length();
+ int x;
+ char b[16];
+ b[cpp] = '\0';
+ for ( x=0; x<w && d<end; x++ ) {
+ strncpy( b, (char *)d, cpp );
+ *p++ = (TQRgb)colorMap[b];
+ d += cpp;
+ }
+ }
+ }
+ if ( iio ) {
+ iio->setImage( image );
+ iio->setqStatus( 0 ); // image ok
+ }
+}
+
+
+static void read_xpm_image( TQImageIO * iio )
+{
+ TQImage i;
+ (void)read_xpm_image_or_array( iio, 0, i );
+ return;
+}
+
+
+static const char* xpm_color_name( int cpp, int index )
+{
+ static char returnable[5];
+ static const char code[] = ".#abcdefghijklmnopqrstuvwxyzABCD"
+ "EFGHIJKLMNOPTQRSTUVWXYZ0123456789";
+ // cpp is limited to 4 and index is limited to 64^cpp
+ if ( cpp > 1 ) {
+ if ( cpp > 2 ) {
+ if ( cpp > 3 ) {
+ returnable[3] = code[index % 64];
+ index /= 64;
+ } else
+ returnable[3] = '\0';
+ returnable[2] = code[index % 64];
+ index /= 64;
+ } else
+ returnable[2] = '\0';
+ // the following 4 lines are a joke!
+ if ( index == 0 )
+ index = 64*44+21;
+ else if ( index == 64*44+21 )
+ index = 0;
+ returnable[1] = code[index % 64];
+ index /= 64;
+ } else
+ returnable[1] = '\0';
+ returnable[0] = code[index];
+
+ return returnable;
+}
+
+
+// write XPM image data
+static void write_xpm_image( TQImageIO * iio )
+{
+ if ( iio )
+ iio->setqStatus( 1 );
+ else
+ return;
+
+ // ### 8-bit case could be made faster
+ TQImage image;
+ if ( iio->image().depth() != 32 )
+ image = iio->image().convertDepth( 32 );
+ else
+ image = iio->image();
+
+ TQMap<TQRgb, int> colorMap;
+
+ int w = image.width(), h = image.height(), ncolors = 0;
+ int x, y;
+
+ // build color table
+ for( y=0; y<h; y++ ) {
+ TQRgb * yp = (TQRgb *)image.scanLine( y );
+ for( x=0; x<w; x++ ) {
+ TQRgb color = *(yp + x);
+ if ( !colorMap.tqcontains(color) )
+ colorMap.insert( color, ncolors++ );
+ }
+ }
+
+ // number of 64-bit characters per pixel needed to encode all colors
+ int cpp = 1;
+ for ( int k = 64; ncolors > k; k *= 64 ) {
+ ++cpp;
+ // limit to 4 characters per pixel
+ // 64^4 colors is enough for a 4096x4096 image
+ if ( cpp > 4)
+ break;
+ }
+
+ TQString line;
+
+ // write header
+ TQTextStream s( iio->ioDevice() );
+ s << "/* XPM */" << endl
+ << "static char *" << fbname(iio->fileName()) << "[]={" << endl
+ << "\"" << w << " " << h << " " << ncolors << " " << cpp << "\"";
+
+ // write palette
+ TQMap<TQRgb, int>::Iterator c = colorMap.begin();
+ while ( c != colorMap.end() ) {
+ TQRgb color = c.key();
+ if ( image.hasAlphaBuffer() && color == (color & TQRGB_MASK) )
+ line.sprintf( "\"%s c None\"",
+ xpm_color_name(cpp, *c) );
+ else
+ line.sprintf( "\"%s c #%02x%02x%02x\"",
+ xpm_color_name(cpp, *c),
+ tqRed(color),
+ tqGreen(color),
+ tqBlue(color) );
+ ++c;
+ s << "," << endl << line;
+ }
+
+ // write pixels, limit to 4 characters per pixel
+ line.truncate( cpp*w );
+ for( y=0; y<h; y++ ) {
+ TQRgb * yp = (TQRgb *) image.scanLine( y );
+ int cc = 0;
+ for( x=0; x<w; x++ ) {
+ int color = (int)(*(yp + x));
+ TQCString chars = xpm_color_name( cpp, colorMap[color] );
+ line[cc++] = chars[0];
+ if ( cpp > 1 ) {
+ line[cc++] = chars[1];
+ if ( cpp > 2 ) {
+ line[cc++] = chars[2];
+ if ( cpp > 3 ) {
+ line[cc++] = chars[3];
+ }
+ }
+ }
+ }
+ s << "," << endl << "\"" << line << "\"";
+ }
+ s << "};" << endl;
+
+ iio->setqStatus( 0 );
+}
+
+#endif // TQT_NO_IMAGEIO_XPM
+
+/*!
+ Returns an image with depth \a d, using the \a palette_count
+ colors pointed to by \a palette. If \a d is 1 or 8, the returned
+ image will have its color table ordered the same as \a palette.
+
+ If the image needs to be modified to fit in a lower-resolution
+ result (e.g. converting from 32-bit to 8-bit), use the \a
+ conversion_flags to specify how you'd prefer this to happen.
+
+ Note: currently no closest-color search is made. If colors are
+ found that are not in the palette, the palette may not be used at
+ all. This result should not be considered valid because it may
+ change in future implementations.
+
+ Currently inefficient for non-32-bit images.
+
+ \sa TQt::ImageConversionFlags
+*/
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+TQImage TQImage::convertDepthWithPalette( int d, TQRgb* palette, int palette_count, int conversion_flags ) const
+{
+ if ( depth() == 1 ) {
+ return convertDepth( 8, conversion_flags )
+ .convertDepthWithPalette( d, palette, palette_count, conversion_flags );
+ } else if ( depth() == 8 ) {
+ // ### this could be easily made more efficient
+ return convertDepth( 32, conversion_flags )
+ .convertDepthWithPalette( d, palette, palette_count, conversion_flags );
+ } else {
+ TQImage result;
+ convert_32_to_8( this, &result,
+ (conversion_flags&~TQt::DitherMode_Mask) | TQt::AvoidDither,
+ palette, palette_count );
+ return result.convertDepth( d );
+ }
+}
+#endif
+static
+bool
+haveSamePalette(const TQImage& a, const TQImage& b)
+{
+ if (a.depth() != b.depth()) return FALSE;
+ if (a.numColors() != b.numColors()) return FALSE;
+ TQRgb* ca = a.colorTable();
+ TQRgb* cb = b.colorTable();
+ for (int i=a.numColors(); i--; ) {
+ if (*ca++ != *cb++) return FALSE;
+ }
+ return TRUE;
+}
+
+/*!
+ \relates TQImage
+
+ Copies a block of pixels from \a src to \a dst. The pixels
+ copied from source (src) are converted according to
+ \a conversion_flags if it is incompatible with the destination
+ (\a dst).
+
+ \a sx, \a sy is the top-left pixel in \a src, \a dx, \a dy
+ is the top-left position in \a dst and \a sw, \a sh is the
+ size of the copied block.
+
+ The copying is clipped if areas outside \a src or \a dst are
+ specified.
+
+ If \a sw is -1, it is adjusted to src->width(). Similarly, if \a
+ sh is -1, it is adjusted to src->height().
+
+ Currently inefficient for non 32-bit images.
+*/
+void bitBlt( TQImage* dst, int dx, int dy, const TQImage* src,
+ int sx, int sy, int sw, int sh, int conversion_flags )
+{
+ // Parameter correction
+ if ( sw < 0 ) sw = src->width();
+ if ( sh < 0 ) sh = src->height();
+ if ( sx < 0 ) { dx -= sx; sw += sx; sx = 0; }
+ if ( sy < 0 ) { dy -= sy; sh += sy; sy = 0; }
+ if ( dx < 0 ) { sx -= dx; sw += dx; dx = 0; }
+ if ( dy < 0 ) { sy -= dy; sh += dy; dy = 0; }
+ if ( sx + sw > src->width() ) sw = src->width() - sx;
+ if ( sy + sh > src->height() ) sh = src->height() - sy;
+ if ( dx + sw > dst->width() ) sw = dst->width() - dx;
+ if ( dy + sh > dst->height() ) sh = dst->height() - dy;
+ if ( sw <= 0 || sh <= 0 ) return; // Nothing left to copy
+ if ( (dst->data == src->data) && dx==sx && dy==sy ) return; // Same pixels
+
+ // "Easy" to copy if both same depth and one of:
+ // - 32 bit
+ // - 8 bit, identical palette
+ // - 1 bit, identical palette and byte-aligned area
+ //
+ if ( haveSamePalette(*dst,*src)
+ && ( dst->depth() != 1 ||
+ !( (dx&7) || (sx&7) ||
+ ((sw&7) && (sx+sw < src->width()) ||
+ (dx+sw < dst->width()) ) ) ) )
+ {
+ // easy to copy
+ } else if ( dst->depth() != 32 ) {
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+
+ TQImage dstconv = dst->convertDepth( 32 );
+ bitBlt( &dstconv, dx, dy, src, sx, sy, sw, sh,
+ (conversion_flags&~TQt::DitherMode_Mask) | TQt::AvoidDither );
+ *dst = dstconv.convertDepthWithPalette( dst->depth(),
+ dst->colorTable(), dst->numColors() );
+#endif
+ return;
+ }
+
+ // Now assume palette can be ignored
+
+ if ( dst->depth() != src->depth() ) {
+ if ( sw == src->width() && sh == src->height() || dst->depth()==32 ) {
+ TQImage srcconv = src->convertDepth( dst->depth(), conversion_flags );
+ bitBlt( dst, dx, dy, &srcconv, sx, sy, sw, sh, conversion_flags );
+ } else {
+ TQImage srcconv = src->copy( sx, sy, sw, sh ); // ie. bitBlt
+ bitBlt( dst, dx, dy, &srcconv, 0, 0, sw, sh, conversion_flags );
+ }
+ return;
+ }
+
+ // Now assume both are the same depth.
+
+ // Now assume both are 32-bit or 8-bit with compatible palettes.
+
+ // "Easy"
+
+ switch ( dst->depth() ) {
+ case 1:
+ {
+ uchar* d = dst->scanLine(dy) + dx/8;
+ uchar* s = src->scanLine(sy) + sx/8;
+ const int bw = (sw+7)/8;
+ if ( bw < 64 ) {
+ // Trust ourselves
+ const int dd = dst->bytesPerLine() - bw;
+ const int ds = src->bytesPerLine() - bw;
+ while ( sh-- ) {
+ for ( int t=bw; t--; )
+ *d++ = *s++;
+ d += dd;
+ s += ds;
+ }
+ } else {
+ // Trust libc
+ const int dd = dst->bytesPerLine();
+ const int ds = src->bytesPerLine();
+ while ( sh-- ) {
+ memcpy( d, s, bw );
+ d += dd;
+ s += ds;
+ }
+ }
+ }
+ break;
+ case 8:
+ {
+ uchar* d = dst->scanLine(dy) + dx;
+ uchar* s = src->scanLine(sy) + sx;
+ if ( sw < 64 ) {
+ // Trust ourselves
+ const int dd = dst->bytesPerLine() - sw;
+ const int ds = src->bytesPerLine() - sw;
+ while ( sh-- ) {
+ for ( int t=sw; t--; )
+ *d++ = *s++;
+ d += dd;
+ s += ds;
+ }
+ } else {
+ // Trust libc
+ const int dd = dst->bytesPerLine();
+ const int ds = src->bytesPerLine();
+ while ( sh-- ) {
+ memcpy( d, s, sw );
+ d += dd;
+ s += ds;
+ }
+ }
+ }
+ break;
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ case 32:
+ if ( src->hasAlphaBuffer() ) {
+ TQRgb* d = (TQRgb*)dst->scanLine(dy) + dx;
+ TQRgb* s = (TQRgb*)src->scanLine(sy) + sx;
+ const int dd = dst->width() - sw;
+ const int ds = src->width() - sw;
+ while ( sh-- ) {
+ for ( int t=sw; t--; ) {
+ unsigned char a = tqAlpha(*s);
+ if ( a == 255 )
+ *d++ = *s++;
+ else if ( a == 0 )
+ ++d,++s; // nothing
+ else {
+ unsigned char r = ((tqRed(*s)-tqRed(*d)) * a) / 256 + tqRed(*d);
+ unsigned char g = ((tqGreen(*s)-tqGreen(*d)) * a) / 256 + tqGreen(*d);
+ unsigned char b = ((tqBlue(*s)-tqBlue(*d)) * a) / 256 + tqBlue(*d);
+ a = TQMAX(tqAlpha(*d),a); // alternatives...
+ *d++ = tqRgba(r,g,b,a);
+ ++s;
+ }
+ }
+ d += dd;
+ s += ds;
+ }
+ } else {
+ TQRgb* d = (TQRgb*)dst->scanLine(dy) + dx;
+ TQRgb* s = (TQRgb*)src->scanLine(sy) + sx;
+ if ( sw < 64 ) {
+ // Trust ourselves
+ const int dd = dst->width() - sw;
+ const int ds = src->width() - sw;
+ while ( sh-- ) {
+ for ( int t=sw; t--; )
+ *d++ = *s++;
+ d += dd;
+ s += ds;
+ }
+ } else {
+ // Trust libc
+ const int dd = dst->width();
+ const int ds = src->width();
+ const int b = sw*sizeof(TQRgb);
+ while ( sh-- ) {
+ memcpy( d, s, b );
+ d += dd;
+ s += ds;
+ }
+ }
+ }
+ break;
+#endif // TQT_NO_IMAGE_TRUECOLOR
+ }
+}
+
+
+/*!
+ Returns TRUE if this image and image \a i have the same contents;
+ otherwise returns FALSE. The comparison can be slow, unless there
+ is some obvious difference, such as different widths, in which
+ case the function will return quickly.
+
+ \sa operator=()
+*/
+
+bool TQImage::operator==( const TQImage & i ) const
+{
+ // same object, or shared?
+ if ( i.data == data )
+ return TRUE;
+ // obviously different stuff?
+ if ( i.data->h != data->h ||
+ i.data->w != data->w )
+ return FALSE;
+ // not equal if one has alphabuffer and the other does not
+ if ( i.hasAlphaBuffer() != hasAlphaBuffer() )
+ return FALSE;
+ // that was the fast bit...
+ TQImage i1 = convertDepth( 32 );
+ TQImage i2 = i.convertDepth( 32 );
+ int l;
+ // if no alpha buffer used, there might still be junk in the
+ // alpha bits; thus, we can't do memcmp-style comparison of scanlines
+ if ( !hasAlphaBuffer() ) {
+ int m;
+ TQRgb *i1line;
+ TQRgb *i2line;
+ for( l=0; l < data->h; l++ ) {
+ i1line = (uint *)i1.scanLine( l );
+ i2line = (uint *)i2.scanLine( l );
+ // compare pixels of scanline individually
+ for ( m=0; m < data->w; m++ )
+ if ( (i1line[m] ^ i2line[m]) & 0x00FFFFFF )
+ return FALSE;
+ }
+ } else {
+ // yay, we can do fast binary comparison on entire scanlines
+ for( l=0; l < data->h; l++ )
+ if ( memcmp( i1.scanLine( l ), i2.scanLine( l ), 4*data->w ) )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*!
+ Returns TRUE if this image and image \a i have different contents;
+ otherwise returns FALSE. The comparison can be slow, unless there
+ is some obvious difference, such as different widths, in which
+ case the function will return quickly.
+
+ \sa operator=()
+*/
+
+bool TQImage::operator!=( const TQImage & i ) const
+{
+ return !(*this == i);
+}
+
+
+
+
+/*!
+ \fn int TQImage::dotsPerMeterX() const
+
+ Returns the number of pixels that fit horizontally in a physical
+ meter. This and dotsPerMeterY() define the intended scale and
+ aspect ratio of the image.
+
+ \sa setDotsPerMeterX()
+*/
+
+/*!
+ \fn int TQImage::dotsPerMeterY() const
+
+ Returns the number of pixels that fit vertically in a physical
+ meter. This and dotsPerMeterX() define the intended scale and
+ aspect ratio of the image.
+
+ \sa setDotsPerMeterY()
+*/
+
+/*!
+ Sets the value returned by dotsPerMeterX() to \a x.
+*/
+void TQImage::setDotsPerMeterX(int x)
+{
+ data->dpmx = x;
+}
+
+/*!
+ Sets the value returned by dotsPerMeterY() to \a y.
+*/
+void TQImage::setDotsPerMeterY(int y)
+{
+ data->dpmy = y;
+}
+
+/*!
+ \fn TQPoint TQImage::offset() const
+
+ Returns the number of pixels by which the image is intended to be
+ offset by when positioning relative to other images.
+*/
+
+/*!
+ Sets the value returned by offset() to \a p.
+*/
+void TQImage::setOffset(const TQPoint& p)
+{
+ data->offset = p;
+}
+#ifndef TQT_NO_IMAGE_TEXT
+/*!
+ \internal
+
+ Returns the internal TQImageDataMisc object. This object will be
+ created if it doesn't already exist.
+*/
+TQImageDataMisc& TQImage::misc() const
+{
+ if ( !data->misc )
+ data->misc = new TQImageDataMisc;
+ return *data->misc;
+}
+
+/*!
+ Returns the string recorded for the keyword \a key in language \a
+ lang, or in a default language if \a lang is 0.
+*/
+TQString TQImage::text(const char* key, const char* lang) const
+{
+ TQImageTextKeyLang x(key,lang);
+ return misc().text_lang[x];
+}
+
+/*!
+ \overload
+
+ Returns the string recorded for the keyword and language \a kl.
+*/
+TQString TQImage::text(const TQImageTextKeyLang& kl) const
+{
+ return misc().text_lang[kl];
+}
+
+/*!
+ Returns the language identifiers for which some texts are
+ recorded.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myImage.textLanguages();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa textList() text() setText() textKeys()
+*/
+TQStringList TQImage::textLanguages() const
+{
+ if ( !data->misc )
+ return TQStringList();
+ return misc().languages();
+}
+
+/*!
+ Returns the keywords for which some texts are recorded.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myImage.textKeys();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa textList() text() setText() textLanguages()
+*/
+TQStringList TQImage::textKeys() const
+{
+ if ( !data->misc )
+ return TQStringList();
+ return misc().keys();
+}
+
+/*!
+ Returns a list of TQImageTextKeyLang objects that enumerate all the
+ texts key/language pairs set by setText() for this image.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQImageTextKeyLang> list = myImage.textList();
+ TQValueList<TQImageTextKeyLang>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQValueList<TQImageTextKeyLang> TQImage::textList() const
+{
+ if ( !data->misc )
+ return TQValueList<TQImageTextKeyLang>();
+ return misc().list();
+}
+
+/*!
+ Records string \a s for the keyword \a key. The \a key should be a
+ portable keyword recognizable by other software - some suggested
+ values can be found in \link
+ http://www.libpng.org/pub/png/spec/1.2/png-1.2-pdg.html#C.Anc-text
+ the PNG specification \endlink. \a s can be any text. \a lang
+ should specify the language code (see
+ \link http://www.rfc-editor.org/rfc/rfc1766.txt RFC 1766 \endlink) or 0.
+*/
+void TQImage::setText(const char* key, const char* lang, const TQString& s)
+{
+ TQImageTextKeyLang x(key,lang);
+ misc().text_lang.tqreplace(x,s);
+}
+
+#endif // TQT_NO_IMAGE_TEXT
+
+#ifdef TQ_WS_TQWS
+/*!
+ \internal
+*/
+TQGfx * TQImage::graphicsContext()
+{
+ TQGfx * ret=0;
+ if(depth()) {
+ int w = qt_screen->mapToDevice( TQSize(width(),height()) ).width();
+ int h = qt_screen->mapToDevice( TQSize(width(),height()) ).height();
+ ret=TQGfx::createGfx(depth(),bits(),w,h,bytesPerLine());
+ } else {
+ qDebug("Trying to create image for null depth");
+ return 0;
+ }
+ if(depth()<=8) {
+ TQRgb * tmp=colorTable();
+ int nc=numColors();
+ if(tmp==0) {
+ static TQRgb table[2] = { tqRgb(255,255,255), tqRgb(0,0,0) };
+ tmp=table;
+ nc=2;
+ }
+ ret->setClut(tmp,nc);
+ }
+ return ret;
+}
+
+#endif
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqimage.h b/tqtinterface/qt4/src/kernel/tqimage.h
new file mode 100644
index 0000000..19dc1a0
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqimage.h
@@ -0,0 +1,695 @@
+/****************************************************************************
+**
+** Definition of TQImage and TQImageIO classes
+**
+** Created : 950207
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQIMAGE_H
+#define TQIMAGE_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqpixmap.h"
+#include "tqstrlist.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qbitmap.h>
+#include <Qt/qstringlist.h>
+#include <Qt/qimagereader.h>
+#include <Qt/qimagewriter.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+#ifndef TQT_NO_IMAGE_TEXT
+class TQ_EXPORT TQImageTextKeyLang : public QImageTextKeyLang, virtual public TQt {
+public:
+ TQImageTextKeyLang(const char* k, const char* l) : QImageTextKeyLang(k, l) { }
+ TQImageTextKeyLang() : QImageTextKeyLang() { }
+
+ bool operator< (const TQImageTextKeyLang& other) const { return key < other.key || (key==other.key && lang < other.lang); }
+ bool operator== (const TQImageTextKeyLang& other) const { return key==other.key && lang==other.lang; }
+
+ // Interoperability
+ static const TQImageTextKeyLang& convertFromQImageTextKeyLang( QImageTextKeyLang& qbr );
+};
+
+// Interoperability
+inline static const TQImageTextKeyLang& convertFromQImageTextKeyLang( const QImageTextKeyLang& qbr ) {
+ return (*static_cast<const TQImageTextKeyLang*>(&qbr));
+}
+#endif //TQT_NO_IMAGE_TEXT
+
+class TQ_EXPORT TQImage : public QImage, virtual public TQt
+{
+public:
+ enum Endian { IgnoreEndian, BigEndian, LittleEndian };
+
+ QImage::Format formatFor(int depth, Endian bitOrder);
+
+ TQImage() : QImage() { jumptable=NULL; }
+ TQImage( int width, int height, int depth, int numColors=0, Endian bitOrder=IgnoreEndian ) : QImage( width, height, formatFor(depth, bitOrder) ) { jumptable=NULL; setColorCount(numColors); }
+ TQImage( const QSize&ts, int depth, int numColors=0, Endian bitOrder=IgnoreEndian ) : QImage( ts, formatFor(depth, bitOrder) ) { jumptable=NULL; setColorCount(numColors); }
+#ifndef TQT_NO_IMAGEIO
+ TQImage( const QString &fileName, const char* format=0 ) : QImage( fileName, format ) { jumptable=NULL; }
+ TQImage( const char * const xpm[] ) : QImage( xpm ) { jumptable=NULL; }
+// TQImage( const QByteArray &data ) : QImage( data ) {}
+#endif
+ TQImage( uchar* data, int w, int h, int depth, QRgb* colortable, int numColors, Endian bitOrder ) : QImage( data, w, h, formatFor(depth, bitOrder) ) {
+ jumptable=NULL;
+ setColorCount(numColors);
+ if (colortable) {
+ setColorCount(numColors);
+ for (int i = 0; i < numColors; ++i) {
+ setColor(i, colortable[i]);
+ }
+ }
+ }
+// ~TQImage();
+
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+ TQImage createHeuristicMask( bool clipTight=TRUE ) const;
+#endif
+
+ Endian bitOrder() const {
+ Format f = format();
+ return f == Format_Mono ? BigEndian : (f == Format_MonoLSB ? LittleEndian : IgnoreEndian);
+ }
+#ifdef TQ_WS_TQWS
+ TQImage( uchar* data, int w, int h, int depth, int pbl, QRgb* colortable, int numColors, Endian bitOrder ) : QImage( data, w, h, depth, pbl, colortable, numColors, bitOrder ) { jumptable=NULL; }
+#endif
+ TQImage( const QImage &im ) : QImage( im ) { jumptable=NULL; }
+
+// static TQStrList inputFormats() { return TQT_TQSTRLIST_OBJECT(QImageReader::supportedImageFormats()); }
+// static TQStrList outputFormats() { return TQT_TQSTRLIST_OBJECT(QImageWriter::supportedImageFormats()); }
+
+ inline TQImage smoothScale(int w, int h, AspectRatioMode mode = IgnoreAspectRatio) const { return scaled(QSize(w, h), (Qt::AspectRatioMode)mode, Qt::SmoothTransformation); }
+ inline TQImage smoothScale(const QSize &s, AspectRatioMode mode = IgnoreAspectRatio) const { return scaled(s, (Qt::AspectRatioMode)mode, Qt::SmoothTransformation); }
+ inline TQImage swapRGB() const { return rgbSwapped(); }
+ inline TQImage mirror(bool horizontally = false, bool vertically = true) const { return mirrored(horizontally, vertically); }
+
+#ifndef TQT_NO_IMAGE_TRANSFORMATION
+ inline TQImage scale( int w, int h, ScaleMode mode=ScaleFree ) const { return scaled(QSize(w, h), (Qt::AspectRatioMode)mode, Qt::FastTransformation); }
+ inline TQImage scale( const TQSize& s, ScaleMode mode=ScaleFree ) const { return scaled(s, (Qt::AspectRatioMode)mode, Qt::FastTransformation); }
+ inline TQImage scaleWidth( int w ) const { return scaledToWidth(w, Qt::FastTransformation); }
+ inline TQImage scaleHeight( int h ) const { return scaledToHeight(h, Qt::FastTransformation); }
+ inline TQImage xForm(const QMatrix &matrix) const { return transformed(QTransform(matrix)); }
+#endif
+
+ TQImage convertDepth(int, Qt::ImageConversionFlags flags = Qt::AutoColor) const;
+ TQImage convertDepthWithPalette(int, QRgb* p, int pc, Qt::ImageConversionFlags flags = Qt::AutoColor) const;
+ TQImage convertBitOrder(Endian) const;
+
+ inline void tqinvertPixels( bool invertAlpha = TRUE ) { if (invertAlpha) invertPixels(InvertRgba); else invertPixels(InvertRgb); }
+
+ bool hasAlphaBuffer() const;
+ void setAlphaBuffer(bool);
+
+ static inline Endian systemByteOrder() { return QSysInfo::ByteOrder == QSysInfo::BigEndian ? BigEndian : LittleEndian; }
+ static Endian systemBitOrder();
+
+ uchar **jumpTable();
+ const uchar * const *jumpTable() const;
+
+ bool create( int width, int height, int depth, int numColors=0, Endian bitOrder=IgnoreEndian );
+ bool create( const TQSize&, int depth, int numColors=0, Endian bitOrder=IgnoreEndian );
+ inline void reset() { *this = QImage(); }
+
+ inline TQValueList<TQImageTextKeyLang> tqtextList() const {
+ QList<QImageTextKeyLang> qs = textList();
+ TQValueList<TQImageTextKeyLang> qn;
+ for (int i = 0; i < qs.size(); ++i) qn.append(convertFromQImageTextKeyLang(qs.at(i)));
+ return qn;
+ }
+
+ inline TQRgb *tqcolorTable() const {
+ return colorTable().data();
+ }
+
+#ifndef TQT_NO_IMAGEIO
+ static const char* imageFormat( const TQString &fileName );
+ static TQStrList inputFormats();
+ static TQStrList outputFormats();
+#ifndef TQT_NO_STRINGLIST
+ static TQStringList inputFormatList();
+ static TQStringList outputFormatList();
+#endif
+ bool load( const TQString &fileName, const char* format=0 );
+ bool loadFromData( const uchar *buf, uint len, const char *format=0 );
+ bool loadFromData( TQByteArray data, const char* format=0 );
+ bool save( const TQString &fileName, const char* format, int quality=-1 ) const;
+ bool save( QIODevice * tqdevice, const char* format, int quality=-1 ) const;
+#endif //TQT_NO_IMAGEIO
+
+private:
+ mutable uchar **jumptable;
+ void reinit();
+ void freeBits();
+#ifndef TQT_NO_IMAGEIO
+ bool doImageIO( TQImageIO* io, int quality ) const;
+#endif
+
+public:
+ // Interoperability
+ static const TQImage& convertFromQImage( QImage& qi );
+
+ using QImage::operator=;
+};
+
+// Interoperability
+inline static const TQImage& convertFromQImage( const QImage& qi ) {
+ return (*static_cast<const TQImage*>(&qi));
+}
+
+#if 0
+typedef void (*image_io_handler)( TQImageIO * ); // image IO handler
+
+class TQ_EXPORT TQImageIO : public QImageReader, public QImageWriter, virtual public TQt
+{
+public:
+ TQImageIO() : QImageReader(), QImageWriter() {}
+ TQImageIO( QIODevice *ioDevice, const char *format ) : QImageReader( ioDevice, format ), QImageWriter( ioDevice, format ) {}
+ TQImageIO( const QString &fileName, const char* format ) : QImageReader( fileName, format ), QImageWriter( fileName, format ) {}
+
+ static TQStrList inputFormats() { return TQT_TQSTRLIST_OBJECT(QImageReader::supportedImageFormats()); }
+ static TQStrList outputFormats() { return TQT_TQSTRLIST_OBJECT(QImageWriter::supportedImageFormats()); }
+
+ inline void setImage( const QImage &qi ) { internalImage = qi; }
+ inline bool write() { return QImageWriter::write( internalImage ); }
+ inline bool read() { if (QImageReader::read().isNull() == true) return false; else return true; }
+ inline int quality() const { return QImageWriter::quality(); }
+ inline const TQImage &image() { return TQT_TQIMAGE_OBJECT(QImageReader::read()); }
+
+ inline static void defineIOHandler( const char *format, const char *header, const char *flags, image_io_handler read_image, image_io_handler write_image ) {
+ // [FIXME] Is this now automatic in Qt4??
+ TQ_UNUSED(format);
+ TQ_UNUSED(header);
+ TQ_UNUSED(flags);
+ TQ_UNUSED(read_image);
+ TQ_UNUSED(write_image);
+ printf("[WARNING] static void defineIOHandler( const char *format, const char *header, const char *flags, image_io_handler read_image, image_io_handler write_image ) unimplemented\n\r");
+ }
+
+ void setqStatus( int );
+ inline TQIODevice *ioDevice() const { if (QImageReader::device() != 0) return static_cast<TQIODevice*>(QImageReader::device()); else return static_cast<TQIODevice*>(QImageWriter::device()); }
+ inline const char *format() const { if (QImageReader::format() != "") return QImageReader::format(); else return QImageWriter::format(); }
+ inline TQString fileName() const { if (QImageReader::fileName() != "") return QImageReader::fileName(); else return QImageWriter::fileName(); }
+ inline const char *parameters() const { printf("[WARNING] const char *parameters() const unimplemented\n\r"); return 0; }
+ inline void setFileName( const QString &qs ) { QImageReader::setFileName(qs); QImageWriter::setFileName(qs); }
+ inline void setQuality( int ql ) { QImageReader::setQuality(ql); QImageWriter::setQuality(ql); }
+ inline void setIODevice( TQIODevice *tqiod ) { QImageReader::setDevice(tqiod); QImageWriter::setDevice(tqiod); }
+ inline void setParameters( const char * ) { printf("[WARNING] void setParameters(const char *) unimplemented\n\r"); }
+ inline void setFormat( const char * format ) { QImageReader::setFormat(format); QImageWriter::setFormat(format); }
+
+private:
+ QImage internalImage;
+};
+#else
+class TQIODevice;
+typedef void (*image_io_handler)( TQImageIO * ); // image IO handler
+
+
+struct TQImageIOData;
+
+
+class TQ_EXPORT TQImageIO
+{
+public:
+ TQImageIO();
+ TQImageIO( QIODevice *ioDevice, const char *format );
+ TQImageIO( const TQString &fileName, const char* format );
+ ~TQImageIO();
+
+
+ const TQImage &image() const { return im; }
+ int status() const { return iostat; }
+ const char *format() const { return frmt; }
+ TQIODevice *ioDevice() const { return iodev; }
+ TQString fileName() const { return fname; }
+ int quality() const;
+ TQString description() const { return descr; }
+ const char *parameters() const;
+ float gamma() const;
+
+ void setImage( const QImage & );
+ void setqStatus( int );
+ void setFormat( const char * );
+ void setIODevice( TQIODevice * );
+ void setFileName( const TQString & );
+ void setQuality( int );
+ void setDescription( const TQString & );
+ void setParameters( const char * );
+ void setGamma( float );
+
+ bool read();
+ bool write();
+
+ static const char* imageFormat( const TQString &fileName );
+ static const char *imageFormat( TQIODevice * );
+ static TQStrList inputFormats();
+ static TQStrList outputFormats();
+
+ static void defineIOHandler( const char *format,
+ const char *header,
+ const char *flags,
+ image_io_handler read_image,
+ image_io_handler write_image );
+
+private:
+ void init();
+
+ TQImage im; // image
+ int iostat; // IO status
+ TQCString frmt; // image format
+ TQIODevice *iodev; // IO tqdevice
+ TQString fname; // file name
+ char *params; // image parameters //### change to TQImageIOData *d in 3.0
+ TQString descr; // image description
+ TQImageIOData *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQImageIO( const TQImageIO & );
+ TQImageIO &operator=( const TQImageIO & );
+#endif
+};
+#endif
+
+#else // USE_QT4
+
+class TQImageDataMisc; // internal
+#ifndef TQT_NO_IMAGE_TEXT
+class TQ_EXPORT TQImageTextKeyLang {
+public:
+ TQImageTextKeyLang(const char* k, const char* l) : key(k), lang(l) { }
+ TQImageTextKeyLang() { }
+
+ TQCString key;
+ TQCString lang;
+
+ bool operator< (const TQImageTextKeyLang& other) const
+ { return key < other.key || (key==other.key && lang < other.lang); }
+ bool operator== (const TQImageTextKeyLang& other) const
+ { return key==other.key && lang==other.lang; }
+};
+#endif //TQT_NO_IMAGE_TEXT
+
+
+class TQ_EXPORT TQImage
+{
+public:
+ enum Endian { IgnoreEndian, BigEndian, LittleEndian };
+
+ TQImage();
+ TQImage( int width, int height, int depth, int numColors=0,
+ Endian bitOrder=IgnoreEndian );
+ TQImage( const TQSize&, int depth, int numColors=0,
+ Endian bitOrder=IgnoreEndian );
+#ifndef TQT_NO_IMAGEIO
+ TQImage( const TQString &fileName, const char* format=0 );
+ TQImage( const char * const xpm[] );
+ TQImage( const TQByteArray &data );
+#endif
+ TQImage( uchar* data, int w, int h, int depth,
+ TQRgb* colortable, int numColors,
+ Endian bitOrder );
+#ifdef TQ_WS_TQWS
+ TQImage( uchar* data, int w, int h, int depth, int pbl,
+ TQRgb* colortable, int numColors,
+ Endian bitOrder );
+#endif
+ TQImage( const TQImage & );
+ ~TQImage();
+
+ TQImage &operator=( const TQImage & );
+ TQImage &operator=( const TQPixmap & );
+ bool operator==( const TQImage & ) const;
+ bool operator!=( const TQImage & ) const;
+ void detach();
+ TQImage copy() const;
+ TQImage copy(int x, int y, int w, int h, int conversion_flags=0) const;
+ TQImage copy(const TQRect&) const;
+#ifndef TQT_NO_MIME
+ static TQImage fromMimeSource( const TQString& abs_name );
+#endif
+ bool isNull() const { return data->bits == 0; }
+
+ int width() const { return data->w; }
+ int height() const { return data->h; }
+ TQSize size() const { return TQSize(data->w,data->h); }
+ TQRect rect() const { return TQRect(0,0,data->w,data->h); }
+ int depth() const { return data->d; }
+ int numColors() const { return data->ncols; }
+ Endian bitOrder() const { return (Endian) data->bitordr; }
+
+ TQRgb color( int i ) const;
+ void setColor( int i, TQRgb c );
+ void setNumColors( int );
+
+ bool hasAlphaBuffer() const;
+ void setAlphaBuffer( bool );
+
+ bool allGray() const;
+ bool isGrayscale() const;
+
+ uchar *bits() const;
+ uchar *scanLine( int ) const;
+ uchar **jumpTable() const;
+ TQRgb *colorTable() const;
+ int numBytes() const;
+ int bytesPerLine() const;
+
+#ifdef TQ_WS_TQWS
+ TQGfx * graphicsContext();
+#endif
+
+ bool create( int width, int height, int depth, int numColors=0,
+ Endian bitOrder=IgnoreEndian );
+ bool create( const TQSize&, int depth, int numColors=0,
+ Endian bitOrder=IgnoreEndian );
+ void reset();
+
+ void fill( uint pixel );
+ void invertPixels( bool invertAlpha = TRUE );
+
+ TQImage convertDepth( int ) const;
+#ifndef TQT_NO_IMAGE_TRUECOLOR
+ TQImage convertDepthWithPalette( int, TQRgb* p, int pc, int cf=0 ) const;
+#endif
+ TQImage convertDepth( int, int conversion_flags ) const;
+ TQImage convertBitOrder( Endian ) const;
+
+ enum ScaleMode {
+ ScaleFree,
+ ScaleMin,
+ ScaleMax
+ };
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+ TQImage smoothScale( int w, int h, ScaleMode mode=ScaleFree ) const;
+ TQImage smoothScale( const TQSize& s, ScaleMode mode=ScaleFree ) const;
+#endif
+#ifndef TQT_NO_IMAGE_TRANSFORMATION
+ TQImage scale( int w, int h, ScaleMode mode=ScaleFree ) const;
+ TQImage scale( const TQSize& s, ScaleMode mode=ScaleFree ) const;
+ TQImage scaleWidth( int w ) const;
+ TQImage scaleHeight( int h ) const;
+ TQImage xForm( const TQWMatrix &matrix ) const;
+#endif
+
+#ifndef TQT_NO_IMAGE_DITHER_TO_1
+ TQImage createAlphaMask( int conversion_flags=0 ) const;
+#endif
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+ TQImage createHeuristicMask( bool clipTight=TRUE ) const;
+#endif
+#ifndef TQT_NO_IMAGE_MIRROR
+ TQImage mirror() const;
+ TQImage mirror(bool horizontally, bool vertically) const;
+#endif
+ TQImage swapRGB() const;
+
+ static Endian systemBitOrder();
+ static Endian systemByteOrder();
+
+#ifndef TQT_NO_IMAGEIO
+ static const char* imageFormat( const TQString &fileName );
+ static TQStrList inputFormats();
+ static TQStrList outputFormats();
+#ifndef TQT_NO_STRINGLIST
+ static TQStringList inputFormatList();
+ static TQStringList outputFormatList();
+#endif
+ bool load( const TQString &fileName, const char* format=0 );
+ bool loadFromData( const uchar *buf, uint len,
+ const char *format=0 );
+ bool loadFromData( TQByteArray data, const char* format=0 );
+ bool save( const TQString &fileName, const char* format,
+ int quality=-1 ) const;
+ bool save( TQIODevice * tqdevice, const char* format,
+ int quality=-1 ) const;
+#endif //TQT_NO_IMAGEIO
+
+ bool valid( int x, int y ) const;
+ int pixelIndex( int x, int y ) const;
+ TQRgb pixel( int x, int y ) const;
+ void setPixel( int x, int y, uint index_or_rgb );
+
+ // Auxiliary data
+ int dotsPerMeterX() const;
+ int dotsPerMeterY() const;
+ void setDotsPerMeterX(int);
+ void setDotsPerMeterY(int);
+ TQPoint offset() const;
+ void setOffset(const TQPoint&);
+#ifndef TQT_NO_IMAGE_TEXT
+ TQValueList<TQImageTextKeyLang> textList() const;
+ TQStringList textLanguages() const;
+ TQStringList textKeys() const;
+ TQString text(const char* key, const char* lang=0) const;
+ TQString text(const TQImageTextKeyLang&) const;
+ void setText(const char* key, const char* lang, const TQString&);
+#endif
+private:
+ void init();
+ void reinit();
+ void freeBits();
+ static void warningIndexRange( const char *, int );
+
+ struct TQImageData : public TQShared { // internal image data
+ int w; // image width
+ int h; // image height
+ int d; // image depth
+ int ncols; // number of colors
+ int nbytes; // number of bytes data
+ int bitordr; // bit order (1 bit depth)
+ TQRgb *ctbl; // color table
+ uchar **bits; // image data
+ bool alpha; // alpha buffer
+ int dpmx; // dots per meter X (or 0)
+ int dpmy; // dots per meter Y (or 0)
+ TQPoint offset; // offset in pixels
+#ifndef TQT_NO_IMAGE_TEXT
+ TQImageDataMisc* misc; // less common stuff
+#endif
+ bool ctbl_mine; // this allocated ctbl
+ } *data;
+#ifndef TQT_NO_IMAGE_TEXT
+ TQImageDataMisc& misc() const;
+#endif
+#ifndef TQT_NO_IMAGEIO
+ bool doImageIO( TQImageIO* io, int quality ) const;
+#endif
+ friend TQ_EXPORT void bitBlt( TQImage* dst, int dx, int dy,
+ const TQImage* src, int sx, int sy,
+ int sw, int sh, int conversion_flags );
+};
+
+
+// TQImage stream functions
+
+#if !defined(TQT_NO_DATASTREAM) && !defined(TQT_NO_IMAGEIO)
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQImage & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQImage & );
+#endif
+
+#ifndef TQT_NO_IMAGEIO
+class TQIODevice;
+typedef void (*image_io_handler)( TQImageIO * ); // image IO handler
+
+
+struct TQImageIOData;
+
+
+class TQ_EXPORT TQImageIO
+{
+public:
+ TQImageIO();
+ TQImageIO( TQIODevice *ioDevice, const char *format );
+ TQImageIO( const TQString &fileName, const char* format );
+ ~TQImageIO();
+
+
+ const TQImage &image() const { return im; }
+ int status() const { return iostat; }
+ const char *format() const { return frmt; }
+ TQIODevice *ioDevice() const { return iodev; }
+ TQString fileName() const { return fname; }
+ int quality() const;
+ TQString description() const { return descr; }
+ const char *parameters() const;
+ float gamma() const;
+
+ void setImage( const TQImage & );
+ void setqStatus( int );
+ void setFormat( const char * );
+ void setIODevice( TQIODevice * );
+ void setFileName( const TQString & );
+ void setQuality( int );
+ void setDescription( const TQString & );
+ void setParameters( const char * );
+ void setGamma( float );
+
+ bool read();
+ bool write();
+
+ static const char* imageFormat( const TQString &fileName );
+ static const char *imageFormat( TQIODevice * );
+ static TQStrList inputFormats();
+ static TQStrList outputFormats();
+
+ static void defineIOHandler( const char *format,
+ const char *header,
+ const char *flags,
+ image_io_handler read_image,
+ image_io_handler write_image );
+
+private:
+ void init();
+
+ TQImage im; // image
+ int iostat; // IO status
+ TQCString frmt; // image format
+ TQIODevice *iodev; // IO tqdevice
+ TQString fname; // file name
+ char *params; // image parameters //### change to TQImageIOData *d in 3.0
+ TQString descr; // image description
+ TQImageIOData *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQImageIO( const TQImageIO & );
+ TQImageIO &operator=( const TQImageIO & );
+#endif
+};
+
+#endif //TQT_NO_IMAGEIO
+
+TQ_EXPORT void bitBlt( TQImage* dst, int dx, int dy, const TQImage* src,
+ int sx=0, int sy=0, int sw=-1, int sh=-1,
+ int conversion_flags=0 );
+
+
+/*****************************************************************************
+ TQImage member functions
+ *****************************************************************************/
+
+inline bool TQImage::hasAlphaBuffer() const
+{
+ return data->alpha;
+}
+
+inline uchar *TQImage::bits() const
+{
+ return data->bits ? data->bits[0] : 0;
+}
+
+inline uchar **TQImage::jumpTable() const
+{
+ return data->bits;
+}
+
+inline TQRgb *TQImage::colorTable() const
+{
+ return data->ctbl;
+}
+
+inline int TQImage::numBytes() const
+{
+ return data->nbytes;
+}
+
+inline int TQImage::bytesPerLine() const
+{
+ return data->h ? data->nbytes/data->h : 0;
+}
+
+inline TQImage TQImage::copy(const TQRect& r) const
+{
+ return copy(r.x(), r.y(), r.width(), r.height());
+}
+
+inline TQRgb TQImage::color( int i ) const
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( i >= data->ncols )
+ warningIndexRange( "color", i );
+#endif
+ return data->ctbl ? data->ctbl[i] : (TQRgb)-1;
+}
+
+inline void TQImage::setColor( int i, TQRgb c )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( i >= data->ncols )
+ warningIndexRange( "setColor", i );
+#endif
+ if ( data->ctbl )
+ data->ctbl[i] = c;
+}
+
+inline uchar *TQImage::scanLine( int i ) const
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( i >= data->h )
+ warningIndexRange( "scanLine", i );
+#endif
+ return data->bits ? data->bits[i] : 0;
+}
+
+inline int TQImage::dotsPerMeterX() const
+{
+ return data->dpmx;
+}
+
+inline int TQImage::dotsPerMeterY() const
+{
+ return data->dpmy;
+}
+
+inline TQPoint TQImage::offset() const
+{
+ return data->offset;
+}
+
+#endif // USE_QT4
+
+#endif // TQIMAGE_H
diff --git a/tqtinterface/qt4/src/kernel/tqimageformatinterface_p.h b/tqtinterface/qt4/src/kernel/tqimageformatinterface_p.h
new file mode 100644
index 0000000..f851ff1
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqimageformatinterface_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQIMAGEFORMATINTERFACE_P_H
+#define TQIMAGEFORMATINTERFACE_P_H
+
+#ifndef TQT_H
+#include <private/tqcom_p.h>
+#endif // TQT_H
+
+#if __GNUC__ - 0 > 3
+#pragma GCC system_header
+#endif
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_NO_COMPONENT
+
+// {04903F05-54B1-4726-A849-FB5CB097CA87}
+#ifndef IID_TQImageFormat
+#define IID_TQImageFormat TQUuid( 0x04903f05, 0x54b1, 0x4726, 0xa8, 0x49, 0xfb, 0x5c, 0xb0, 0x97, 0xca, 0x87 )
+#endif
+
+class TQImage;
+
+struct TQ_EXPORT TQImageFormatInterface : public TQFeatureListInterface
+{
+ virtual TQRESULT loadImage( const TQString &format, const TQString &filename, TQImage * ) = 0;
+ virtual TQRESULT saveImage( const TQString &format, const TQString &filename, const TQImage & ) = 0;
+
+ virtual TQRESULT installIOHandler( const TQString & ) = 0;
+};
+
+#endif // TQT_NO_COMPONENT
+
+#endif // TQIMAGEFORMATINTERFACE_P_H
diff --git a/tqtinterface/qt4/src/kernel/tqimageformatplugin.cpp b/tqtinterface/qt4/src/kernel/tqimageformatplugin.cpp
new file mode 100644
index 0000000..536b9c8
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqimageformatplugin.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqimageformatplugin.h"
+#ifndef TQT_NO_IMAGEFORMATPLUGIN
+#include "tqimageformatinterface_p.h"
+#include "tqimage.h"
+
+/*!
+ \class TQImageFormatPlugin tqimageformatplugin.h
+ \brief The TQImageFormatPlugin class provides an abstract base for custom image format plugins.
+
+ \ingroup plugins
+
+ The image format plugin is a simple plugin interface that makes
+ it easy to create custom image formats that can be used
+ transparently by applications.
+
+ Writing an image format plugin is achieved by subclassing this
+ base class, reimplementing the pure virtual functions keys() and
+ installIOHandler(), and exporting the class with the
+ TQ_EXPORT_PLUGIN macro. See the \link plugins-howto.html Plugins
+ documentation\endlink for details.
+*/
+
+/*!
+ \fn TQStringList TQImageFormatPlugin::keys() const
+
+ Returns the list of image formats this plugin supports.
+
+ \sa installIOHandler()
+*/
+
+
+/*!
+ \fn bool TQImageFormatPlugin::installIOHandler( const TQString &format )
+
+ Installs a TQImageIO image I/O handler for the image format \a
+ format.
+
+ \sa keys()
+*/
+
+class TQImageFormatPluginPrivate : public TQImageFormatInterface
+{
+public:
+ TQImageFormatPluginPrivate( TQImageFormatPlugin *p )
+ : plugin( p )
+ {
+ }
+ virtual ~TQImageFormatPluginPrivate();
+
+ TQRESULT queryInterface( const TQUuid &iid, TQUnknownInterface **iface );
+ TQ_REFCOUNT;
+
+ TQStringList featureList() const;
+
+ TQRESULT loadImage( const TQString &format, const TQString &filename, TQImage * );
+ TQRESULT saveImage( const TQString &format, const TQString &filename, const TQImage & );
+
+ TQRESULT installIOHandler( const TQString & );
+
+private:
+ TQImageFormatPlugin *plugin;
+};
+
+TQImageFormatPluginPrivate::~TQImageFormatPluginPrivate()
+{
+ delete plugin;
+}
+
+TQRESULT TQImageFormatPluginPrivate::queryInterface( const TQUuid &iid, TQUnknownInterface **iface )
+{
+ *iface = 0;
+
+ if ( iid == IID_TQUnknown )
+ *iface = this;
+ else if ( iid == IID_TQFeatureList )
+ *iface = this;
+ else if ( iid == IID_TQImageFormat )
+ *iface = this;
+ else
+ return TQE_NOINTERFACE;
+
+ (*iface)->addRef();
+ return TQS_OK;
+}
+
+TQStringList TQImageFormatPluginPrivate::featureList() const
+{
+ return plugin->keys();
+}
+
+TQRESULT TQImageFormatPluginPrivate::loadImage( const TQString &format, const TQString &filename, TQImage *image )
+{
+ return plugin->loadImage( format, filename, image ) ? TQS_FALSE : TQS_OK;
+}
+
+TQRESULT TQImageFormatPluginPrivate::saveImage( const TQString &format, const TQString &filename, const TQImage &image )
+{
+ return plugin->saveImage( format, filename, image ) ? TQS_FALSE : TQS_OK;
+}
+
+TQRESULT TQImageFormatPluginPrivate::installIOHandler( const TQString &format )
+{
+ return plugin->installIOHandler( format ) ? TQS_FALSE : TQS_OK;
+}
+
+/*!
+ Constructs an image format plugin. This is invoked automatically
+ by the TQ_EXPORT_PLUGIN macro.
+*/
+TQImageFormatPlugin::TQImageFormatPlugin()
+ : TQGPlugin( d = new TQImageFormatPluginPrivate( this ) )
+{
+}
+
+/*!
+ Destroys the image format plugin.
+
+ You never have to call this explicitly. TQt destroys a plugin
+ automatically when it is no longer used.
+*/
+TQImageFormatPlugin::~TQImageFormatPlugin()
+{
+}
+
+
+/*!\internal
+ */
+bool TQImageFormatPlugin::loadImage( const TQString &format, const TQString &filename, TQImage *image )
+{
+ TQ_UNUSED( format )
+ TQ_UNUSED( filename )
+ TQ_UNUSED( image )
+ return FALSE;
+}
+
+/*! \internal
+ */
+bool TQImageFormatPlugin::saveImage( const TQString &format, const TQString &filename, const TQImage &image )
+{
+ TQ_UNUSED( format )
+ TQ_UNUSED( filename )
+ TQ_UNUSED( image )
+ return FALSE;
+}
+
+#endif // TQT_NO_IMAGEFORMATPLUGIN
diff --git a/tqtinterface/qt4/src/kernel/tqimageformatplugin.h b/tqtinterface/qt4/src/kernel/tqimageformatplugin.h
new file mode 100644
index 0000000..ac9d873
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqimageformatplugin.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Definition of ???
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQIMAGEFORMATPLUGIN_H
+#define TQIMAGEFORMATPLUGIN_H
+
+#ifndef TQT_H
+#include "tqgplugin.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_IMAGEFORMATPLUGIN
+class TQImageFormat;
+class TQImageFormatPluginPrivate;
+
+class TQ_EXPORT TQImageFormatPlugin : public TQGPlugin
+{
+ TQ_OBJECT
+public:
+ TQImageFormatPlugin();
+ ~TQImageFormatPlugin();
+
+ virtual TQStringList keys() const = 0;
+ virtual bool loadImage( const TQString &format, const TQString &filename, TQImage *image );
+ virtual bool saveImage( const TQString &format, const TQString &filename, const TQImage &image );
+ virtual bool installIOHandler( const TQString &format ) = 0;
+
+private:
+ TQImageFormatPluginPrivate *d;
+};
+#endif // TQT_NO_IMAGEFORMATPLUGIN
+#endif // TQIMAGEFORMATPLUGIN_H
diff --git a/tqtinterface/qt4/src/kernel/tqinputcontext_p.h b/tqtinterface/qt4/src/kernel/tqinputcontext_p.h
new file mode 100644
index 0000000..03ecaf6
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqinputcontext_p.h
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Definition of ???
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQINPUTCONTEXT_P_H
+#define TQINPUTCONTEXT_P_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#include "tqglobal.h"
+
+class TQKeyEvent;
+class TQWidget;
+class TQFont;
+class TQString;
+
+
+#ifdef TQ_WS_X11
+#include "tqarray.h"
+#include "tqwindowdefs.h"
+#include "tqt_x11_p.h"
+#endif
+
+#ifdef TQ_WS_WIN
+#include "tqt_windows.h"
+#endif
+
+#ifdef TQ_WS_TQWS
+class TQWSIMEvent;
+#endif
+
+class TQInputContext
+{
+public:
+#ifdef TQ_WS_X11
+ TQInputContext(TQWidget *); // should be a toplevel widget
+ ~TQInputContext();
+
+ void setFocus();
+ void setComposePosition(int, int);
+ void setComposeArea(int, int, int, int);
+ void reset();
+
+ int lookupString(XKeyEvent *, TQCString &, KeySym *, Status *) const;
+ void setXFontSet(const TQFont &);
+
+ void *ic;
+ TQString text;
+ TQWidget *tqfocusWidget;
+ bool composing;
+ TQFont font;
+ XFontSet fontset;
+ TQMemArray<bool> selectedChars;
+#endif // TQ_WS_X11
+
+#ifdef TQ_WS_TQWS
+ static void translateIMEvent( TQWSIMEvent *, TQWidget * );
+ static void reset();
+private:
+ static TQWidget* tqfocusWidget;
+ static TQString* composition;
+#endif //TQ_WS_TQWS
+
+#ifdef TQ_WS_WIN
+ static void init();
+ static void shutdown();
+
+ static void TranslateMessage( const MSG *msg);
+ static LRESULT DefWindowProc( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
+
+ static void setFont( const TQWidget *w, const TQFont & );
+ static void setFocusHint( int x, int y, int w, int h, const TQWidget *widget );
+ static bool startComposition();
+ static bool endComposition( TQWidget *fw = 0 );
+ static bool composition( LPARAM lparam );
+
+ static void accept( TQWidget *fw = 0 );
+ static void enable( TQWidget *w, bool b );
+#endif
+};
+
+#endif // TQINPUTCONTEXT_P_H
diff --git a/tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp b/tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp
new file mode 100644
index 0000000..758b56d
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqinputcontext_x11.cpp
@@ -0,0 +1,535 @@
+/****************************************************************************
+**
+** Implementation of TQInputContext class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+#include "tqapplication.h"
+#include "tqwidget.h"
+#include "tqinputcontext_p.h"
+
+#include <stdlib.h>
+#include <limits.h>
+
+
+bool qt_compose_emptied = FALSE;
+
+#if !defined(TQT_NO_XIM)
+
+#define XK_MISCELLANY
+#define XK_LATIN1
+#include <X11/keysymdef.h>
+
+// #define TQT_XIM_DEBUG
+
+// from qapplication_x11.cpp
+extern XIM qt_xim;
+extern XIMStyle qt_xim_style;
+
+/* The cache here is needed, as X11 leaks a few kb for every
+ XFreeFontSet call, so we avoid creating and deletion of fontsets as
+ much as possible
+*/
+static XFontSet fontsetCache[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+static int fontsetRefCount = 0;
+
+static const char * const fontsetnames[] = {
+ "-*-fixed-medium-r-*-*-16-*,-*-*-medium-r-*-*-16-*",
+ "-*-fixed-medium-i-*-*-16-*,-*-*-medium-i-*-*-16-*",
+ "-*-fixed-bold-r-*-*-16-*,-*-*-bold-r-*-*-16-*",
+ "-*-fixed-bold-i-*-*-16-*,-*-*-bold-i-*-*-16-*",
+ "-*-fixed-medium-r-*-*-24-*,-*-*-medium-r-*-*-24-*",
+ "-*-fixed-medium-i-*-*-24-*,-*-*-medium-i-*-*-24-*",
+ "-*-fixed-bold-r-*-*-24-*,-*-*-bold-r-*-*-24-*",
+ "-*-fixed-bold-i-*-*-24-*,-*-*-bold-i-*-*-24-*"
+};
+
+static XFontSet getFontSet( const TQFont &f )
+{
+ int i = 0;
+ if (f.italic())
+ i |= 1;
+ if (f.bold())
+ i |= 2;
+
+ if ( f.pointSize() > 20 )
+ i += 4;
+
+ if ( !fontsetCache[i] ) {
+ Display* dpy = TQPaintDevice::x11AppDisplay();
+ int missCount;
+ char** missList;
+ fontsetCache[i] = XCreateFontSet(dpy, fontsetnames[i], &missList, &missCount, 0);
+ if(missCount > 0)
+ XFreeStringList(missList);
+ if ( !fontsetCache[i] ) {
+ fontsetCache[i] = XCreateFontSet(dpy, "-*-fixed-*-*-*-*-16-*", &missList, &missCount, 0);
+ if(missCount > 0)
+ XFreeStringList(missList);
+ if ( !fontsetCache[i] )
+ fontsetCache[i] = (XFontSet)-1;
+ }
+ }
+ return (fontsetCache[i] == (XFontSet)-1) ? 0 : fontsetCache[i];
+}
+
+
+#ifdef TQ_C_CALLBACKS
+extern "C" {
+#endif // TQ_C_CALLBACKS
+
+ static int xic_start_callback(XIC, XPointer client_data, XPointer) {
+ TQInputContext *qic = (TQInputContext *) client_data;
+ if (! qic) {
+#ifdef TQT_XIM_DEBUG
+ qDebug("compose start: no qic");
+#endif // TQT_XIM_DEBUG
+
+ return 0;
+ }
+
+ qic->composing = TRUE;
+ qic->text = TQString::null;
+ qic->tqfocusWidget = 0;
+
+ if ( qic->selectedChars.size() < 128 )
+ qic->selectedChars.resize( 128 );
+ qic->selectedChars.fill( 0 );
+
+#ifdef TQT_XIM_DEBUG
+ qDebug("compose start");
+#endif // TQT_XIM_DEBUG
+
+ return 0;
+ }
+
+ static int xic_draw_callback(XIC, XPointer client_data, XPointer call_data) {
+ TQInputContext *qic = (TQInputContext *) client_data;
+ if (! qic) {
+#ifdef TQT_XIM_DEBUG
+ qDebug("compose event: invalid compose event %p", qic);
+#endif // TQT_XIM_DEBUG
+
+ return 0;
+ }
+
+ bool send_imstart = FALSE;
+ if (tqApp->tqfocusWidget() != qic->tqfocusWidget && qic->text.isEmpty()) {
+ if (qic->tqfocusWidget) {
+#ifdef TQT_XIM_DEBUG
+ qDebug( "sending IMEnd (empty) to %p", qic->tqfocusWidget );
+#endif // TQT_XIM_DEBUG
+
+ TQIMEvent endevent(TQEvent::IMEnd, TQString::null, -1);
+ TQApplication::sendEvent(qic->tqfocusWidget, &endevent);
+ }
+
+ qic->text = TQString::null;
+ qic->tqfocusWidget = tqApp->tqfocusWidget();
+ qic->composing = FALSE;
+
+ if ( qic->selectedChars.size() < 128 )
+ qic->selectedChars.resize( 128 );
+ qic->selectedChars.fill( 0 );
+
+ if (qic->tqfocusWidget) {
+ qic->composing = TRUE;
+ send_imstart = TRUE;
+ }
+ }
+
+ if (! qic->composing || ! qic->tqfocusWidget) {
+#ifdef TQT_XIM_DEBUG
+ qDebug("compose event: invalid compose event %d %p",
+ qic->composing, qic->tqfocusWidget);
+#endif // TQT_XIM_DEBUG
+
+ return 0;
+ }
+
+ if ( send_imstart ) {
+#ifdef TQT_XIM_DEBUG
+ qDebug( "sending IMStart to %p", qic->tqfocusWidget );
+#endif // TQT_XIM_DEBUG
+
+ qt_compose_emptied = FALSE;
+ TQIMEvent startevent(TQEvent::IMStart, TQString::null, -1);
+ TQApplication::sendEvent(qic->tqfocusWidget, &startevent);
+ }
+
+ XIMPreeditDrawCallbackStruct *drawstruct =
+ (XIMPreeditDrawCallbackStruct *) call_data;
+ XIMText *text = (XIMText *) drawstruct->text;
+ int cursor = drawstruct->caret, sellen = 0;
+
+ if ( ! drawstruct->caret && ! drawstruct->chg_first &&
+ ! drawstruct->chg_length && ! text ) {
+ // nothing to do
+ return 0;
+ }
+
+ if (text) {
+ char *str = 0;
+ if (text->encoding_is_wchar) {
+ int l = wcstombs(NULL, text->string.wide_char, text->length);
+ if (l != -1) {
+ str = new char[l + 1];
+ wcstombs(str, text->string.wide_char, l);
+ str[l] = 0;
+ }
+ } else
+ str = text->string.multi_byte;
+
+ if (! str)
+ return 0;
+
+ TQString s = TQString::fromLocal8Bit(str);
+
+ if (text->encoding_is_wchar)
+ delete [] str;
+
+ if (drawstruct->chg_length < 0)
+ qic->text.tqreplace(drawstruct->chg_first, UINT_MAX, s);
+ else
+ qic->text.tqreplace(drawstruct->chg_first, drawstruct->chg_length, s);
+
+ if ( qic->selectedChars.size() < qic->text.length() ) {
+ // expand the selectedChars array if the compose string is longer
+ uint from = qic->selectedChars.size();
+ qic->selectedChars.resize( qic->text.length() );
+ for ( uint x = from; from < qic->selectedChars.size(); ++x )
+ qic->selectedChars[x] = 0;
+ }
+
+ uint x;
+ bool *p = qic->selectedChars.data() + drawstruct->chg_first;
+ // determine if the changed chars are selected based on text->feedback
+ for ( x = 0; x < s.length(); ++x )
+ *p++ = ( text->feedback ? ( text->feedback[x] & XIMReverse ) : 0 );
+
+ // figure out where the selection starts, and how long it is
+ p = qic->selectedChars.data();
+ bool started = FALSE;
+ for ( x = 0; x < TQMIN(qic->text.length(), qic->selectedChars.size()); ++x ) {
+ if ( started ) {
+ if ( *p ) ++sellen;
+ else break;
+ } else {
+ if ( *p ) {
+ cursor = x;
+ started = TRUE;
+ sellen = 1;
+ }
+ }
+ ++p;
+ }
+ } else {
+ if (drawstruct->chg_length == 0)
+ drawstruct->chg_length = -1;
+
+ qic->text.remove(drawstruct->chg_first, drawstruct->chg_length);
+ qt_compose_emptied = qic->text.isEmpty();
+ if ( qt_compose_emptied ) {
+#ifdef TQT_XIM_DEBUG
+ qDebug( "compose emptied" );
+#endif // TQT_XIM_DEBUG
+
+ // don't send an empty compose, since we will send an IMEnd with
+ // either the correct compose text (or null text if the user has
+ // cancelled the compose or deleted all chars).
+ return 0;
+ }
+ }
+
+#ifdef TQT_XIM_DEBUG
+ qDebug( "sending IMCompose to %p with %d chars",
+ qic->tqfocusWidget, qic->text.length() );
+#endif // TQT_XIM_DEBUG
+
+ TQIMComposeEvent event( TQEvent::IMCompose, qic->text, cursor, sellen );
+ TQApplication::sendEvent(qic->tqfocusWidget, &event);
+ return 0;
+ }
+
+ static int xic_done_callback(XIC, XPointer client_data, XPointer) {
+ TQInputContext *qic = (TQInputContext *) client_data;
+ if (! qic)
+ return 0;
+
+ if (qic->composing && qic->tqfocusWidget) {
+#ifdef TQT_XIM_DEBUG
+ qDebug( "sending IMEnd (empty) to %p", qic->tqfocusWidget );
+#endif // TQT_XIM_DEBUG
+
+ TQIMEvent event(TQEvent::IMEnd, TQString::null, -1);
+ TQApplication::sendEvent(qic->tqfocusWidget, &event);
+ }
+
+ qic->composing = FALSE;
+ qic->tqfocusWidget = 0;
+
+ if ( qic->selectedChars.size() < 128 )
+ qic->selectedChars.resize( 128 );
+ qic->selectedChars.fill( 0 );
+
+ return 0;
+ }
+
+#ifdef TQ_C_CALLBACKS
+}
+#endif // TQ_C_CALLBACKS
+
+#endif // !TQT_NO_XIM
+
+
+
+TQInputContext::TQInputContext(TQWidget *widget)
+ : ic(0), tqfocusWidget(0), composing(FALSE), fontset(0)
+{
+#if !defined(TQT_NO_XIM)
+ fontsetRefCount++;
+ if (! qt_xim) {
+ qWarning("TQInputContext: no input method context available");
+ return;
+ }
+
+ if (! widget->isTopLevel()) {
+ qWarning("TQInputContext: cannot create input context for non-toplevel widgets");
+ return;
+ }
+
+ XPoint spot;
+ XRectangle rect;
+ XVaNestedList preedit_attr = 0;
+ XIMCallback startcallback, drawcallback, donecallback;
+
+ font = widget->font();
+ fontset = getFontSet( font );
+
+ if (qt_xim_style & XIMPreeditArea) {
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = widget->width();
+ rect.height = widget->height();
+
+ preedit_attr = XVaCreateNestedList(0,
+ XNArea, &rect,
+ XNFontSet, fontset,
+ (char *) 0);
+ } else if (qt_xim_style & XIMPreeditPosition) {
+ spot.x = 1;
+ spot.y = 1;
+
+ preedit_attr = XVaCreateNestedList(0,
+ XNSpotLocation, &spot,
+ XNFontSet, fontset,
+ (char *) 0);
+ } else if (qt_xim_style & XIMPreeditCallbacks) {
+ startcallback.client_data = (XPointer) this;
+ startcallback.callback = (XIMProc) xic_start_callback;
+ drawcallback.client_data = (XPointer) this;
+ drawcallback.callback = (XIMProc)xic_draw_callback;
+ donecallback.client_data = (XPointer) this;
+ donecallback.callback = (XIMProc) xic_done_callback;
+
+ preedit_attr = XVaCreateNestedList(0,
+ XNPreeditStartCallback, &startcallback,
+ XNPreeditDrawCallback, &drawcallback,
+ XNPreeditDoneCallback, &donecallback,
+ (char *) 0);
+ }
+
+ if (preedit_attr) {
+ ic = XCreateIC(qt_xim,
+ XNInputStyle, qt_xim_style,
+ XNClientWindow, widget->winId(),
+ XNPreeditAttributes, preedit_attr,
+ (char *) 0);
+ XFree(preedit_attr);
+ } else
+ ic = XCreateIC(qt_xim,
+ XNInputStyle, qt_xim_style,
+ XNClientWindow, widget->winId(),
+ (char *) 0);
+
+ if (! ic)
+ qFatal("Failed to create XIM input context!");
+
+ // when resetting the input context, preserve the input state
+ (void) XSetICValues((XIC) ic, XNResetState, XIMPreserveState, (char *) 0);
+#endif // !TQT_NO_XIM
+}
+
+
+TQInputContext::~TQInputContext()
+{
+
+#if !defined(TQT_NO_XIM)
+ if (ic)
+ XDestroyIC((XIC) ic);
+
+ if ( --fontsetRefCount == 0 ) {
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ for ( int i = 0; i < 8; i++ ) {
+ if ( fontsetCache[i] && fontsetCache[i] != (XFontSet)-1 ) {
+ XFreeFontSet(dpy, fontsetCache[i]);
+ fontsetCache[i] = 0;
+ }
+ }
+ }
+
+#endif // !TQT_NO_XIM
+
+ ic = 0;
+ tqfocusWidget = 0;
+ composing = FALSE;
+}
+
+
+void TQInputContext::reset()
+{
+#if !defined(TQT_NO_XIM)
+ if (tqfocusWidget && composing && ! text.isNull()) {
+#ifdef TQT_XIM_DEBUG
+ qDebug("TQInputContext::reset: composing - sending IMEnd (empty) to %p",
+ tqfocusWidget);
+#endif // TQT_XIM_DEBUG
+
+ TQIMEvent endevent(TQEvent::IMEnd, TQString::null, -1);
+ TQApplication::sendEvent(tqfocusWidget, &endevent);
+ tqfocusWidget = 0;
+ text = TQString::null;
+ if ( selectedChars.size() < 128 )
+ selectedChars.resize( 128 );
+ selectedChars.fill( 0 );
+
+ char *mb = XmbResetIC((XIC) ic);
+ if (mb)
+ XFree(mb);
+ }
+#endif // !TQT_NO_XIM
+}
+
+
+void TQInputContext::setComposePosition(int x, int y)
+{
+#if !defined(TQT_NO_XIM)
+ if (qt_xim && ic) {
+ XPoint point;
+ point.x = x;
+ point.y = y;
+
+ XVaNestedList preedit_attr =
+ XVaCreateNestedList(0,
+ XNSpotLocation, &point,
+
+ (char *) 0);
+ XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0);
+ XFree(preedit_attr);
+ }
+#endif // !TQT_NO_XIM
+}
+
+
+void TQInputContext::setComposeArea(int x, int y, int w, int h)
+{
+#if !defined(TQT_NO_XIM)
+ if (qt_xim && ic) {
+ XRectangle rect;
+ rect.x = x;
+ rect.y = y;
+ rect.width = w;
+ rect.height = h;
+
+ XVaNestedList preedit_attr = XVaCreateNestedList(0,
+ XNArea, &rect,
+
+ (char *) 0);
+ XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0);
+ XFree(preedit_attr);
+ }
+#endif
+}
+
+
+int TQInputContext::lookupString(XKeyEvent *event, TQCString &chars,
+ KeySym *key, Status *status) const
+{
+ int count = 0;
+
+#if !defined(TQT_NO_XIM)
+ if (qt_xim && ic) {
+ count = XmbLookupString((XIC) ic, event, chars.data(),
+ chars.size(), key, status);
+
+ if ((*status) == XBufferOverflow ) {
+ chars.resize(count + 1);
+ count = XmbLookupString((XIC) ic, event, chars.data(),
+ chars.size(), key, status);
+ }
+ }
+
+#endif // TQT_NO_XIM
+
+ return count;
+}
+
+void TQInputContext::setFocus()
+{
+#if !defined(TQT_NO_XIM)
+ if (qt_xim && ic)
+ XSetICFocus((XIC) ic);
+#endif // !TQT_NO_XIM
+}
+
+void TQInputContext::setXFontSet(const TQFont &f)
+{
+#if !defined(TQT_NO_XIM)
+ if (font == f) return; // nothing to do
+ font = f;
+
+ XFontSet fs = getFontSet(font);
+ if (fontset == fs) return; // nothing to do
+ fontset = fs;
+
+ XVaNestedList preedit_attr = XVaCreateNestedList(0, XNFontSet, fontset, (char *) 0);
+ XSetICValues((XIC) ic, XNPreeditAttributes, preedit_attr, (char *) 0);
+ XFree(preedit_attr);
+#else
+ TQ_UNUSED( f );
+#endif
+}
diff --git a/tqtinterface/qt4/src/kernel/tqinternal.cpp b/tqtinterface/qt4/src/kernel/tqinternal.cpp
new file mode 100644
index 0000000..7ad13f1
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqinternal.cpp
@@ -0,0 +1,785 @@
+/****************************************************************************
+**
+** Implementation of some internal classes
+**
+** Created : 010427
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "private/tqinternal_p.h"
+#include "tqwidget.h"
+#include "tqpixmap.h"
+#include "tqpainter.h"
+#include "tqcleanuphandler.h"
+
+static TQPixmap* qdb_shared_pixmap = 0;
+static TQPixmap *qdb_force_pixmap = 0;
+static TQSharedDoubleBuffer* qdb_owner = 0;
+
+TQCleanupHandler<TQPixmap> qdb_pixmap_cleanup;
+
+#ifdef TQ_WS_MACX
+bool TQSharedDoubleBuffer::dblbufr = FALSE;
+#else
+bool TQSharedDoubleBuffer::dblbufr = TRUE;
+#endif
+
+
+/*
+ hardLimitWidth/Height: if >= 0, the maximum number of pixels that
+ get double buffered.
+
+ sharedLimitWidth/Height: if >= 0, the maximum number of pixels the
+ shared double buffer can keep.
+
+ For x with sharedLimitSize < x <= hardLimitSize, temporary buffers
+ are constructed.
+ */
+static const int hardLimitWidth = -1;
+static const int hardLimitHeight = -1;
+// #if defined( TQ_WS_TQWS ) || defined( TQ_WS_MAC9 )
+// // Small in TQt/Embedded / Mac9 - 5K on 32bpp
+// static const int sharedLimitWidth = 64;
+// static const int sharedLimitHeight = 20;
+// #else
+// 240K on 32bpp
+static const int sharedLimitWidth = 640;
+static const int sharedLimitHeight = 100;
+// #endif
+
+// *******************************************************************
+// TQSharedDoubleBufferCleaner declaration and implementation
+// *******************************************************************
+
+/* \internal
+ This class is responsible for cleaning up the pixmaps created by the
+ TQSharedDoubleBuffer class. When TQSharedDoubleBuffer creates a
+ pixmap larger than the shared limits, this class deletes it after a
+ specified amount of time.
+
+ When the large pixmap is created/used, you must call start(). If the
+ large pixmap is ever deleted, you must call stop(). The start()
+ method always restarts the timer, so if the large pixmap is
+ constantly in use, the timer will never fire, and the pixmap will
+ not be constantly created and destroyed.
+*/
+
+static const int shared_double_buffer_cleanup_timeout = 30000; // 30 seconds
+
+// declaration
+
+class TQSharedDoubleBufferCleaner : public TQObject
+{
+public:
+ TQSharedDoubleBufferCleaner( void );
+
+ void start( void );
+ void stop( void );
+
+ void doCleanup( void );
+
+ bool event( TQEvent *e );
+
+private:
+ int timer_id;
+};
+
+// implementation
+
+/* \internal
+ Creates a TQSharedDoubleBufferCleaner object. The timer is not
+ started when creating the object.
+*/
+TQSharedDoubleBufferCleaner::TQSharedDoubleBufferCleaner( void )
+ : TQObject( 0, "internal shared double buffer cleanup object" ),
+ timer_id( -1 )
+{
+}
+
+/* \internal
+ Starts the cleanup timer. Any previously running timer is stopped.
+*/
+void TQSharedDoubleBufferCleaner::start( void )
+{
+ stop();
+ timer_id = startTimer( shared_double_buffer_cleanup_timeout );
+}
+
+/* \internal
+ Stops the cleanup timer, if it is running.
+*/
+void TQSharedDoubleBufferCleaner::stop( void )
+{
+ if ( timer_id != -1 )
+ killTimer( timer_id );
+ timer_id = -1;
+}
+
+/* \internal
+ */
+void TQSharedDoubleBufferCleaner::doCleanup( void )
+{
+ qdb_pixmap_cleanup.remove( &qdb_force_pixmap );
+ delete qdb_force_pixmap;
+ qdb_force_pixmap = 0;
+}
+
+/* \internal
+ Event handler reimplementation. Calls doCleanup() when the timer
+ fires.
+*/
+bool TQSharedDoubleBufferCleaner::event( TQEvent *e )
+{
+ if ( e->type() != TQEvent::Timer )
+ return FALSE;
+
+ TQTimerEvent *event = (TQTimerEvent *) e;
+ if ( event->timerId() == timer_id ) {
+ doCleanup();
+ stop();
+ }
+#ifdef TQT_CHECK_STATE
+ else {
+ qWarning( "TQSharedDoubleBufferCleaner::event: invalid timer event received." );
+ return FALSE;
+ }
+#endif // TQT_CHECK_STATE
+
+ return TRUE;
+}
+
+// static instance
+static TQSharedDoubleBufferCleaner *static_cleaner = 0;
+TQSingleCleanupHandler<TQSharedDoubleBufferCleaner> cleanup_static_cleaner;
+
+inline static TQSharedDoubleBufferCleaner *staticCleaner()
+{
+ if ( ! static_cleaner ) {
+ static_cleaner = new TQSharedDoubleBufferCleaner();
+ cleanup_static_cleaner.set( &static_cleaner );
+ }
+ return static_cleaner;
+}
+
+
+// *******************************************************************
+// TQSharedDoubleBuffer implementation
+// *******************************************************************
+
+/* \internal
+ \enum DoubleBufferFlags
+
+ \value InitBG initialize the background of the double buffer.
+
+ \value Force disable shared buffer size limits.
+
+ \value Default InitBG and Force are used by default.
+*/
+
+/* \internal
+ \enum DoubleBufferState
+
+ \value Active indicates that the buffer may be used.
+
+ \value BufferActive indicates that painting with painter() will be
+ double buffered.
+
+ \value ExternalPainter indicates that painter() will return a
+ painter that was not created by TQSharedDoubleBuffer.
+*/
+
+/* \internal
+ \class TQSharedDoubleBuffer
+
+ This class provides a single, reusable double buffer. This class
+ is used internally by TQt widgets that need double buffering, which
+ prevents each individual widget form creating a double buffering
+ pixmap.
+
+ Using a single pixmap double buffer and sharing it across all
+ widgets is nicer on window system resources.
+*/
+
+/* \internal
+ Creates a TQSharedDoubleBuffer with flags \f.
+
+ \sa DoubleBufferFlags
+*/
+TQSharedDoubleBuffer::TQSharedDoubleBuffer( DBFlags f )
+ : wid( 0 ), rx( 0 ), ry( 0 ), rw( 0 ), rh( 0 ), flags( f ), state( 0 ),
+ p( 0 ), external_p( 0 ), pix( 0 )
+{
+}
+
+/* \internal
+ Creates a TQSharedDoubleBuffer with flags \f. The \a widget, \a x,
+ \a y, \a w and \a h arguments are passed to begin().
+
+ \sa DoubleBufferFlags begin()
+*/
+TQSharedDoubleBuffer::TQSharedDoubleBuffer( TQWidget* widget,
+ int x, int y, int w, int h,
+ DBFlags f )
+ : wid( 0 ), rx( 0 ), ry( 0 ), rw( 0 ), rh( 0 ), flags( f ), state( 0 ),
+ p( 0 ), external_p( 0 ), pix( 0 )
+{
+ begin( widget, x, y, w, h );
+}
+
+/* \internal
+ Creates a TQSharedDoubleBuffer with flags \f. The \a painter, \a x,
+ \a y, \a w and \a h arguments are passed to begin().
+
+ \sa DoubleBufferFlags begin()
+*/
+TQSharedDoubleBuffer::TQSharedDoubleBuffer( TQPainter* painter,
+ int x, int y, int w, int h,
+ DBFlags f)
+ : wid( 0 ), rx( 0 ), ry( 0 ), rw( 0 ), rh( 0 ), flags( f ), state( 0 ),
+ p( 0 ), external_p( 0 ), pix( 0 )
+{
+ begin( painter, x, y, w, h );
+}
+
+/* \internal
+ Creates a TQSharedDoubleBuffer with flags \f. The \a widget and
+ \a r arguments are passed to begin().
+
+ \sa DoubleBufferFlags begin()
+*/
+TQSharedDoubleBuffer::TQSharedDoubleBuffer( TQWidget *widget, const TQRect &r, DBFlags f )
+ : wid( 0 ), rx( 0 ), ry( 0 ), rw( 0 ), rh( 0 ), flags( f ), state( 0 ),
+ p( 0 ), external_p( 0 ), pix( 0 )
+{
+ begin( widget, r );
+}
+
+/* \internal
+ Creates a TQSharedDoubleBuffer with flags \f. The \a painter and
+ \a r arguments are passed to begin().
+
+ \sa DoubleBufferFlags begin()
+*/
+TQSharedDoubleBuffer::TQSharedDoubleBuffer( TQPainter *painter, const TQRect &r, DBFlags f )
+ : wid( 0 ), rx( 0 ), ry( 0 ), rw( 0 ), rh( 0 ), flags( f ), state( 0 ),
+ p( 0 ), external_p( 0 ), pix( 0 )
+{
+ begin( painter, r );
+}
+
+/* \internal
+ Destructs the TQSharedDoubleBuffer and calls end() if the buffer is
+ active.
+
+ \sa isActive() end()
+*/
+TQSharedDoubleBuffer::~TQSharedDoubleBuffer()
+{
+ if ( isActive() )
+ end();
+}
+
+/* \internal
+ Starts double buffered painting in the area specified by \a x,
+ \a y, \a w and \a h on \a painter. Painting should be done using the
+ TQPainter returned by TQSharedDoubleBuffer::painter().
+
+ The double buffered area will be updated when calling end().
+
+ \sa painter() isActive() end()
+*/
+bool TQSharedDoubleBuffer::begin( TQPainter* painter, int x, int y, int w, int h )
+{
+ if ( isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSharedDoubleBuffer::begin: Buffer is already active."
+ "\n\tYou must end() the buffer before a second begin()" );
+#endif // TQT_CHECK_STATE
+ return FALSE;
+ }
+
+ external_p = painter;
+
+ if ( painter->tqdevice()->devType() == TQInternal::Widget )
+// return begin( (TQWidget *) painter->tqdevice(), x, y, w, h ); // This was very lazy code on Trolltech's part! Nothing like a bad reinterpret cast, completely ignoring the different base object addresses, to ruin your week...
+ return begin( static_cast<TQWidget*>(static_cast<QWidget*>(static_cast<QPaintDevice*>(painter->tqdevice()))), x, y, w, h );
+
+ state = Active;
+
+ rx = x;
+ ry = y;
+ rw = w;
+ rh = h;
+
+ if ( ( pix = getPixmap() ) ) {
+#ifdef TQ_WS_X11
+ if ( painter->tqdevice()->x11Screen() != pix->x11Screen() )
+ pix->x11SetScreen( painter->tqdevice()->x11Screen() );
+ TQPixmap::x11SetDefaultScreen( pix->x11Screen() );
+#endif // TQ_WS_X11
+
+ state |= BufferActive;
+ p = new TQPainter( pix );
+ if ( p->isActive() ) {
+ p->setPen( external_p->pen() );
+ p->setBackgroundColor( external_p->backgroundColor() );
+ p->setFont( external_p->font() );
+ }
+ } else {
+ state |= ExternalPainter;
+ p = external_p;
+ }
+
+ return TRUE;
+}
+
+/* \internal
+
+
+ Starts double buffered painting in the area specified by \a x,
+ \a y, \a w and \a h on \a widget. Painting should be done using the
+ TQPainter returned by TQSharedDoubleBuffer::painter().
+
+ The double buffered area will be updated when calling end().
+
+ \sa painter() isActive() end()
+*/
+bool TQSharedDoubleBuffer::begin( TQWidget* widget, int x, int y, int w, int h )
+{
+ if ( isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSharedDoubleBuffer::begin: Buffer is already active."
+ "\n\tYou must end() the buffer before a second begin()" );
+#endif // TQT_CHECK_STATE
+ return FALSE;
+ }
+
+ state = Active;
+
+ wid = widget;
+ rx = x;
+ ry = y;
+ rw = w <= 0 ? wid->width() : w;
+ rh = h <= 0 ? wid->height() : h;
+
+ if ( ( pix = getPixmap() ) ) {
+#ifdef TQ_WS_X11
+ if ( wid->x11Screen() != pix->x11Screen() )
+ pix->x11SetScreen( wid->x11Screen() );
+ TQPixmap::x11SetDefaultScreen( pix->x11Screen() );
+#endif // TQ_WS_X11
+
+ state |= BufferActive;
+ if ( flags & InitBG ) {
+ pix->fill( wid, rx, ry );
+ }
+ p = new TQPainter( static_cast<QPaintDevice*>(pix), wid );
+ // newly created painters should be translated to the origin
+ // of the widget, so that paint methods can draw onto the double
+ // buffered painter in widget coordinates.
+ p->setBrushOrigin( -rx, -ry );
+ p->translate( -rx, -ry );
+ } else {
+ if ( external_p ) {
+ state |= ExternalPainter;
+ p = external_p;
+ } else {
+ p = new TQPainter( wid );
+ }
+
+ if ( flags & InitBG ) {
+ wid->erase( rx, ry, rw, rh );
+ }
+ }
+ return TRUE;
+}
+
+/* \internal
+ Ends double buffered painting. The contents of the shared double
+ buffer pixmap are drawn onto the destination by calling flush(),
+ and ownership of the shared double buffer pixmap is released.
+
+ \sa begin() flush()
+*/
+bool TQSharedDoubleBuffer::end()
+{
+ if ( ! isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSharedDoubleBuffer::end: Buffer is not active."
+ "\n\tYou must call begin() before calling end()." );
+#endif // TQT_CHECK_STATE
+ return FALSE;
+ }
+
+ if ( ! ( state & ExternalPainter ) ) {
+ p->end();
+ delete p;
+ }
+
+ flush();
+
+ if ( pix ) {
+ releasePixmap();
+ }
+
+ wid = 0;
+ rx = ry = rw = rh = 0;
+ // do not reset flags!
+ state = 0;
+
+ p = external_p = 0;
+ pix = 0;
+
+ return TRUE;
+}
+
+/* \internal
+ Paints the contents of the shared double buffer pixmap onto the
+ destination. The destination is determined from the arguments
+ based to begin().
+
+ Note: You should not need to call this function, since it is called
+ from end().
+
+ \sa begin() end()
+*/
+void TQSharedDoubleBuffer::flush()
+{
+ if ( ! isActive() || ! ( state & BufferActive ) )
+ return;
+
+ if ( external_p )
+ external_p->drawPixmap( rx, ry, *pix, 0, 0, rw, rh );
+ else if ( wid && wid->isVisible() )
+ bitBlt( wid, rx, ry, pix, 0, 0, rw, rh );
+}
+
+/* \internal
+ Aquire ownership of the shared double buffer pixmap, subject to the
+ following conditions:
+
+ \list 1
+ \i double buffering is enabled globally.
+ \i the shared double buffer pixmap is not in use.
+ \i the size specified in begin() is valid, and within limits.
+ \endlist
+
+ If all of these conditions are met, then this TQSharedDoubleBuffer
+ object becomes the owner of the shared double buffer pixmap. The
+ shared double buffer pixmap is resize if necessary, and this
+ function returns a pointer to the pixmap. Ownership must later be
+ relinquished by calling releasePixmap().
+
+ If none of the above conditions are met, this function returns
+ zero.
+
+ \sa releasePixmap()
+*/
+TQPixmap *TQSharedDoubleBuffer::getPixmap()
+{
+ if ( isDisabled() ) {
+ // double buffering disabled globally
+ return 0;
+ }
+
+ if ( qdb_owner ) {
+ // shared pixmap already in use
+ return 0;
+ }
+
+ if ( rw <= 0 || rh <= 0 ||
+ ( hardLimitWidth > 0 && rw >= hardLimitWidth ) ||
+ ( hardLimitHeight > 0 && rh >= hardLimitHeight ) ) {
+ // invalid size, or hard limit reached
+ return 0;
+ }
+
+ if ( rw >= sharedLimitWidth || rh >= sharedLimitHeight ) {
+ if ( flags & Force ) {
+#ifdef USE_QT4
+ printf("[WARNING] Working around mysterious TQSharedDoubleBuffer [tqinternal.cpp] resize problem\n\r");
+ rw = 4000; // 32MB seems reasonable enough, but the usage is likely to be wider than it is tall (think of multiple wide monitors)
+ rh = 2000;
+#else // USE_QT4
+ rw = TQMIN(rw, 8000);
+ rh = TQMIN(rh, 8000);
+#endif // USE_QT4
+ // need to create a big pixmap and start the cleaner
+ if ( ! qdb_force_pixmap ) {
+ qdb_force_pixmap = new TQPixmap( rw, rh );
+ qdb_pixmap_cleanup.add( &qdb_force_pixmap );
+ } else if ( qdb_force_pixmap->width () < rw ||
+ qdb_force_pixmap->height() < rh ) {
+// qdb_force_pixmap->resize( rw, rh );
+ qdb_force_pixmap->resize( TQMAX(rw,qdb_force_pixmap->width()), TQMAX(rh,qdb_force_pixmap->height()) );
+ }
+ qdb_owner = this;
+ staticCleaner()->start();
+ return qdb_force_pixmap;
+ }
+
+ // size is outside shared limit
+ return 0;
+ }
+
+ if ( ! qdb_shared_pixmap ) {
+#ifdef USE_QT4
+ printf("[WARNING] Working around mysterious TQSharedDoubleBuffer [tqinternal.cpp] resize problem\n\r");
+ qdb_shared_pixmap = new TQPixmap( sharedLimitWidth, sharedLimitHeight );
+#else // USE_QT4
+ qdb_shared_pixmap = new TQPixmap( rw, rh );
+#endif // USE_QT4
+ qdb_pixmap_cleanup.add( &qdb_shared_pixmap );
+ } else if ( qdb_shared_pixmap->width() < rw ||
+ qdb_shared_pixmap->height() < rh ) {
+// qdb_shared_pixmap->resize( rw, rh );
+ qdb_shared_pixmap->resize( TQMAX(rw,qdb_shared_pixmap->width()), TQMAX(rh,qdb_shared_pixmap->height()) );
+ }
+ qdb_owner = this;
+ return qdb_shared_pixmap;
+}
+
+/* \internal
+ Releases ownership of the shared double buffer pixmap.
+
+ \sa getPixmap()
+*/
+void TQSharedDoubleBuffer::releasePixmap()
+{
+ if ( qdb_owner != this ) {
+ // sanity check
+
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQSharedDoubleBuffer::releasePixmap: internal error."
+ "\n\t%p does not own shared pixmap, %p does.",
+ (void*)this, (void*)qdb_owner );
+#endif // TQT_CHECK_STATE
+
+ return;
+ }
+
+ qdb_owner = 0;
+}
+
+/* \internal
+ \fn bool TQSharedDoubleBuffer::isDisabled()
+
+ Returns TRUE if double buffering is disabled globally, FALSE otherwise.
+*/
+
+/* \internal
+ \fn void TQSharedDoubleBuffer::setDisabled( bool off )
+
+ Disables global double buffering \a off is TRUE, otherwise global
+ double buffering is enabled.
+*/
+
+/* \internal
+ Deletes the shared double buffer pixmap. You should not need to
+ call this function, since it is called from the TQApplication
+ destructor.
+*/
+void TQSharedDoubleBuffer::cleanup()
+{
+ qdb_pixmap_cleanup.remove( &qdb_shared_pixmap );
+ qdb_pixmap_cleanup.remove( &qdb_force_pixmap );
+ delete qdb_shared_pixmap;
+ delete qdb_force_pixmap;
+ qdb_shared_pixmap = 0;
+ qdb_force_pixmap = 0;
+ qdb_owner = 0;
+}
+
+/* \internal
+ \fn bool TQSharedDoubleBuffer::begin( TQWidget *widget, const TQRect &r )
+ \overload
+*/
+
+/* \internal
+ \fn bool TQSharedDoubleBuffer::begin( TQPainter *painter, const TQRect &r )
+ \overload
+*/
+
+/* \internal
+ \fn TQPainter *TQSharedDoubleBuffer::painter() const
+
+ Returns the active painter on the double buffered area,
+ or zero if double buffered painting is not active.
+*/
+
+/* \internal
+ \fn bool TQSharedDoubleBuffer::isActive() const
+
+ Returns TRUE if double buffered painting is active, FALSE otherwise.
+*/
+
+/* \internal
+ \fn bool TQSharedDoubleBuffer::isBuffered() const
+
+ Returns TRUE if painting is double buffered, FALSE otherwise.
+*/
+
+
+// *******************************************************************
+// TQMembuf declaration and implementation
+// *******************************************************************
+
+/* \internal
+ This class implements an efficient buffering of data that is often used by
+ asynchronous IO classes like TQSocket, TQHttp and TQProcess.
+*/
+
+TQMembuf::TQMembuf() : _size(0), _index(0)
+{
+ buf = new TQPtrList<TQByteArray>;
+ buf->setAutoDelete( TRUE );
+}
+
+TQMembuf::~TQMembuf()
+{
+ delete buf;
+}
+
+/*! \internal
+ This function consumes \a nbytes bytes of data from the
+ buffer and copies it into \a sink. If \a sink is a 0 pointer
+ the data goes into the nirvana.
+*/
+bool TQMembuf::consumeBytes( TQ_ULONG nbytes, char *sink )
+{
+ if ( nbytes <= 0 || nbytes > _size )
+ return FALSE;
+ _size -= nbytes;
+ for ( ;; ) {
+ TQByteArray *a = buf->first();
+ if ( _index + nbytes >= a->size() ) {
+ // Here we skip the whole byte array and get the next later
+ int len = a->size() - _index;
+ if ( sink ) {
+ memcpy( sink, a->data()+_index, len );
+ sink += len;
+ }
+ nbytes -= len;
+ buf->remove();
+ _index = 0;
+ if ( nbytes == 0 )
+ break;
+ } else {
+ // Here we skip only a part of the first byte array
+ if ( sink )
+ memcpy( sink, a->data()+_index, nbytes );
+ _index += nbytes;
+ break;
+ }
+ }
+ return TRUE;
+}
+
+/*! \internal
+ Scans for any occurrence of '\n' in the buffer. If \a store
+ is not 0 the text up to the first '\n' (or terminating 0) is
+ written to \a store, and a terminating 0 is appended to \a store
+ if necessary. Returns TRUE if a '\n' was found; otherwise returns
+ FALSE.
+*/
+bool TQMembuf::scanNewline( TQByteArray *store )
+{
+ if ( _size == 0 )
+ return FALSE;
+ int i = 0; // index into 'store'
+ TQByteArray *a = 0;
+ char *p;
+ int n;
+ for ( ;; ) {
+ if ( !a ) {
+ a = buf->first();
+ if ( !a || a->size() == 0 )
+ return FALSE;
+ p = a->data() + _index;
+ n = a->size() - _index;
+ } else {
+ a = buf->next();
+ if ( !a || a->size() == 0 )
+ return FALSE;
+ p = a->data();
+ n = a->size();
+ }
+ if ( store ) {
+ while ( n-- > 0 ) {
+ *(store->data()+i) = *p;
+ if ( ++i == (int)store->size() )
+ store->resize( store->size() < 256
+ ? 1024 : store->size()*4 );
+ switch ( *p ) {
+ case '\0':
+ store->resize( i );
+ return FALSE;
+ case '\n':
+ *(store->data()+i) = '\0';
+ store->resize( i );
+ return TRUE;
+ }
+ p++;
+ }
+ } else {
+ while ( n-- > 0 ) {
+ switch ( *p++ ) {
+ case '\0':
+ return FALSE;
+ case '\n':
+ return TRUE;
+ }
+ }
+ }
+ }
+}
+
+int TQMembuf::ungetch( int ch )
+{
+ if ( buf->isEmpty() || _index==0 ) {
+ // we need a new TQByteArray
+ TQByteArray *ba = new TQByteArray( 1 );
+ buf->insert( 0, ba );
+ _size++;
+ ba->tqat( 0 ) = ch;
+ } else {
+ // we can reuse a place in the buffer
+ TQByteArray *ba = buf->first();
+ _index--;
+ _size++;
+ ba->tqat( _index ) = ch;
+ }
+ return ch;
+}
diff --git a/tqtinterface/qt4/src/kernel/tqinternal_p.h b/tqtinterface/qt4/src/kernel/tqinternal_p.h
new file mode 100644
index 0000000..08c5c8a
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqinternal_p.h
@@ -0,0 +1,213 @@
+/****************************************************************************
+**
+** Definition of some shared interal classes
+**
+** Created : 010427
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQINTERNAL_P_H
+#define TQINTERNAL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+#ifndef TQT_H
+#include "tqnamespace.h"
+#include "tqrect.h"
+#include "tqptrlist.h"
+#include "tqcstring.h"
+#include "tqiodevice.h"
+#endif // TQT_H
+
+class TQWidget;
+class TQPainter;
+class TQPixmap;
+
+class TQ_EXPORT TQSharedDoubleBuffer
+{
+public:
+ enum DoubleBufferFlags {
+ NoFlags = 0x00,
+ InitBG = 0x01,
+ Force = 0x02,
+ Default = InitBG | Force
+ };
+ typedef uint DBFlags;
+
+ TQSharedDoubleBuffer( DBFlags f = Default );
+ TQSharedDoubleBuffer( TQWidget* widget,
+ int x = 0, int y = 0, int w = -1, int h = -1,
+ DBFlags f = Default );
+ TQSharedDoubleBuffer( TQPainter* painter,
+ int x = 0, int y = 0, int w = -1, int h = -1,
+ DBFlags f = Default );
+ TQSharedDoubleBuffer( TQWidget *widget, const TQRect &r, DBFlags f = Default );
+ TQSharedDoubleBuffer( TQPainter *painter, const TQRect &r, DBFlags f = Default );
+ ~TQSharedDoubleBuffer();
+
+ bool begin( TQWidget* widget, int x = 0, int y = 0, int w = -1, int h = -1 );
+ bool begin( TQPainter* painter, int x = 0, int y = 0, int w = -1, int h = -1);
+ bool begin( TQWidget* widget, const TQRect &r );
+ bool begin( TQPainter* painter, const TQRect &r );
+ bool end();
+
+ TQPainter* painter() const;
+
+ bool isActive() const;
+ bool isBuffered() const;
+ void flush();
+
+ static bool isDisabled() { return !dblbufr; }
+ static void setDisabled( bool off ) { dblbufr = !off; }
+
+ static void cleanup();
+
+private:
+ enum DoubleBufferState {
+ Active = 0x0100,
+ BufferActive = 0x0200,
+ ExternalPainter = 0x0400
+ };
+ typedef uint DBState;
+
+ TQPixmap *getPixmap();
+ void releasePixmap();
+
+ TQWidget *wid;
+ int rx, ry, rw, rh;
+ DBFlags flags;
+ DBState state;
+
+ TQPainter *p, *external_p;
+ TQPixmap *pix;
+
+ static bool dblbufr;
+};
+
+inline bool TQSharedDoubleBuffer::begin( TQWidget* widget, const TQRect &r )
+{ return begin( widget, r.x(), r.y(), r.width(), r.height() ); }
+
+inline bool TQSharedDoubleBuffer::begin( TQPainter *painter, const TQRect &r )
+{ return begin( painter, r.x(), r.y(), r.width(), r.height() ); }
+
+inline TQPainter* TQSharedDoubleBuffer::painter() const
+{ return p; }
+
+inline bool TQSharedDoubleBuffer::isActive() const
+{ return ( state & Active ); }
+
+inline bool TQSharedDoubleBuffer::isBuffered() const
+{ return ( state & BufferActive ); }
+
+
+class TQVirtualDestructor {
+public:
+ virtual ~TQVirtualDestructor() {}
+};
+
+template <class T>
+class TQAutoDeleter : public TQVirtualDestructor {
+public:
+ TQAutoDeleter( T* p ) : ptr( p ) {}
+ ~TQAutoDeleter() { delete ptr; }
+ T* data() const { return ptr; }
+private:
+ T* ptr;
+};
+
+template <class T>
+T* qAutoDeleterData( TQAutoDeleter<T>* ad )
+{
+ if ( !ad )
+ return 0;
+ return ad->data();
+}
+
+template <class T>
+TQAutoDeleter<T>* qAutoDeleter( T* p )
+{
+ return new TQAutoDeleter<T>( p );
+}
+
+class TQ_EXPORT TQMembuf
+{
+public:
+ TQMembuf();
+ ~TQMembuf();
+
+ void append( TQByteArray *ba );
+ void clear();
+
+ bool consumeBytes( TQ_ULONG nbytes, char *sink );
+ TQByteArray readAll();
+ bool scanNewline( TQByteArray *store );
+ bool canReadLine() const;
+
+ int ungetch( int ch );
+
+ TQIODevice::Offset size() const;
+
+private:
+
+ TQPtrList<TQByteArray> *buf;
+ TQIODevice::Offset _size;
+ TQIODevice::Offset _index;
+};
+
+inline void TQMembuf::append( TQByteArray *ba )
+{ buf->append( ba ); _size += ba->size(); }
+
+inline void TQMembuf::clear()
+{ buf->clear(); _size=0; _index=0; }
+
+inline TQByteArray TQMembuf::readAll()
+{ TQByteArray ba(_size); consumeBytes(_size,ba.data()); return ba; }
+
+inline bool TQMembuf::canReadLine() const
+{ return ((TQMembuf*)this)->scanNewline( 0 ); }
+
+inline TQIODevice::Offset TQMembuf::size() const
+{ return _size; }
+
+#endif // TQINTERNAL_P_H
diff --git a/tqtinterface/qt4/src/kernel/tqjpegio.cpp b/tqtinterface/qt4/src/kernel/tqjpegio.cpp
new file mode 100644
index 0000000..20b7b17
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqjpegio.cpp
@@ -0,0 +1,599 @@
+/****************************************************************************
+**
+** Implementation of JPEG TQImage IOHandler
+**
+** Created : 990521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQT_CLEAN_NAMESPACE
+#define TQT_CLEAN_NAMESPACE
+#endif
+
+#include "tqimage.h"
+
+#ifndef TQT_NO_IMAGEIO_JPEG
+
+#include "tqiodevice.h"
+#include "tqjpegio.h"
+
+#include <stdio.h> // jpeglib needs this to be pre-included
+#include <setjmp.h>
+
+
+// including jpeglib.h seems to be a little messy
+extern "C" {
+#define XMD_H // shut JPEGlib up
+#if defined(TQ_OS_UNIXWARE)
+# define HAVE_BOOLEAN // libjpeg under Unixware seems to need this
+#endif
+#include <jpeglib.h>
+#ifdef const
+# undef const // remove crazy C hackery in jconfig.h
+#endif
+}
+
+
+struct my_error_mgr : public jpeg_error_mgr {
+ jmp_buf setjmp_buffer;
+};
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static
+void my_error_exit (j_common_ptr cinfo)
+{
+ my_error_mgr* myerr = (my_error_mgr*) cinfo->err;
+ char buffer[JMSG_LENGTH_MAX];
+ (*cinfo->err->format_message)(cinfo, buffer);
+ qWarning(buffer);
+ longjmp(myerr->setjmp_buffer, 1);
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+static const int max_buf = 4096;
+
+struct my_jpeg_source_mgr : public jpeg_source_mgr {
+ // Nothing dynamic - cannot rely on destruction over longjump
+ TQImageIO* iio;
+ JOCTET buffer[max_buf];
+
+public:
+ my_jpeg_source_mgr(TQImageIO* iio);
+};
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static
+void qt_init_source(j_decompress_ptr)
+{
+}
+
+static
+boolean qt_fill_input_buffer(j_decompress_ptr cinfo)
+{
+ int num_read;
+ my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;
+ TQIODevice* dev = src->iio->ioDevice();
+ src->next_input_byte = src->buffer;
+ num_read = dev->readBlock((char*)src->buffer, max_buf);
+ if ( num_read <= 0 ) {
+ // Insert a fake EOI marker - as per jpeglib recommendation
+ src->buffer[0] = (JOCTET) 0xFF;
+ src->buffer[1] = (JOCTET) JPEG_EOI;
+ src->bytes_in_buffer = 2;
+ } else {
+ src->bytes_in_buffer = num_read;
+ }
+#if defined(TQ_OS_UNIXWARE)
+ return B_TRUE;
+#else
+ return TRUE;
+#endif
+}
+
+static
+void qt_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
+{
+ my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;
+
+ // `dumb' implementation from jpeglib
+
+ /* Just a dumb implementation for now. Could use fseek() except
+ * it doesn't work on pipes. Not clear that being smart is worth
+ * any trouble anyway --- large skips are infrequent.
+ */
+ if (num_bytes > 0) {
+ while (num_bytes > (long) src->bytes_in_buffer) {
+ num_bytes -= (long) src->bytes_in_buffer;
+ (void) qt_fill_input_buffer(cinfo);
+ /* note we assume that qt_fill_input_buffer will never return FALSE,
+ * so suspension need not be handled.
+ */
+ }
+ src->next_input_byte += (size_t) num_bytes;
+ src->bytes_in_buffer -= (size_t) num_bytes;
+ }
+}
+
+static
+void qt_term_source(j_decompress_ptr)
+{
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+inline my_jpeg_source_mgr::my_jpeg_source_mgr(TQImageIO* iioptr)
+{
+ jpeg_source_mgr::init_source = qt_init_source;
+ jpeg_source_mgr::fill_input_buffer = qt_fill_input_buffer;
+ jpeg_source_mgr::skip_input_data = qt_skip_input_data;
+ jpeg_source_mgr::resync_to_restart = jpeg_resync_to_restart;
+ jpeg_source_mgr::term_source = qt_term_source;
+ iio = iioptr;
+ bytes_in_buffer = 0;
+ next_input_byte = buffer;
+}
+
+
+static
+void scaleSize( int &reqW, int &reqH, int imgW, int imgH, TQ_ScaleMode mode )
+{
+ if ( mode == TQ_ScaleFree )
+ return;
+ int t1 = imgW * reqH;
+ int t2 = reqW * imgH;
+ if (( mode == TQ_ScaleMin && (t1 > t2) ) || ( mode == TQ_ScaleMax && (t1 < t2) ))
+ reqH = t2 / imgW;
+ else
+ reqW = t1 / imgH;
+}
+
+
+static
+void read_jpeg_image(TQImageIO* iio)
+{
+ TQImage image;
+
+ struct jpeg_decompress_struct cinfo;
+
+ struct my_jpeg_source_mgr *iod_src = new my_jpeg_source_mgr(iio);
+ struct my_error_mgr jerr;
+
+ jpeg_create_decompress(&cinfo);
+
+ cinfo.src = iod_src;
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jerr.error_exit = my_error_exit;
+
+ if (!setjmp(jerr.setjmp_buffer)) {
+#if defined(TQ_OS_UNIXWARE)
+ (void) jpeg_read_header(&cinfo, B_TRUE);
+#else
+ (void) jpeg_read_header(&cinfo, TRUE);
+#endif
+
+ (void) jpeg_start_decompress(&cinfo);
+
+ TQString params = iio->parameters();
+ params.simplifyWhiteSpace();
+ int sWidth = 0, sHeight = 0;
+ char sModeStr[1024] = "";
+ TQ_ScaleMode sMode;
+
+ if ( params.tqcontains( "GetHeaderInformation" ) ) {
+
+ // Create TQImage's without allocating the data
+ if ( cinfo.output_components == 3 || cinfo.output_components == 4) {
+ image = TQImage( NULL, cinfo.output_width, cinfo.output_height, 32, NULL, 0, TQImage::IgnoreEndian );
+ } else if ( cinfo.output_components == 1 ) {
+ image = TQImage( NULL, cinfo.output_width, cinfo.output_height, 8, NULL, 0, TQImage::IgnoreEndian );
+ } else {
+ // Unsupported format
+ }
+
+
+ } else if ( params.tqcontains( "Scale" ) ) {
+ sscanf( params.latin1(), "Scale( %i, %i, %1023s )",
+ &sWidth, &sHeight, sModeStr );
+
+ TQString sModeTQStr( sModeStr );
+ if ( sModeTQStr == "ScaleFree" ) {
+ sMode = TQ_ScaleFree;
+ } else if ( sModeTQStr == "ScaleMin" ) {
+ sMode = TQ_ScaleMin;
+ } else if ( sModeTQStr == "ScaleMax" ) {
+ sMode = TQ_ScaleMax;
+ } else {
+ qDebug("read_jpeg_image: invalid scale mode \"%s\", see TTQ_ScaleMode documentation", sModeStr);
+ sMode = TQ_ScaleFree;
+ }
+
+// qDebug( "Parameters ask to scale the image to %i x %i ScaleMode: %s", sWidth, sHeight, sModeStr );
+ scaleSize( sWidth, sHeight, cinfo.output_width, cinfo.output_height, sMode );
+// qDebug( "Scaling the jpeg to %i x %i", sWidth, sHeight, sModeStr );
+
+ bool created = FALSE;
+ if ( cinfo.output_components == 3 || cinfo.output_components == 4) {
+ created = image.create( sWidth, sHeight, 32 );
+ } else if ( cinfo.output_components == 1 ) {
+ created = image.create( sWidth, sHeight, 8, 256 );
+ for (int i=0; i<256; i++)
+ image.setColor(i, tqRgb(i,i,i));
+ } else {
+ // Unsupported format
+ }
+ if (!created)
+ image = TQImage();
+
+ if (!image.isNull()) {
+ TQImage tmpImage( cinfo.output_width, 1, 32 );
+ uchar** inLines = tmpImage.jumpTable();
+ uchar** outLines = image.jumpTable();
+ while (cinfo.output_scanline < cinfo.output_height) {
+ int outputLine = sHeight * cinfo.output_scanline / cinfo.output_height;
+ (void) jpeg_read_scanlines(&cinfo, inLines, 1);
+ if ( cinfo.output_components == 3 ) {
+ uchar *in = inLines[0];
+ TQRgb *out = (TQRgb*)outLines[outputLine];
+ for (uint i=0; i<cinfo.output_width; i++ ) {
+// ### Only scaling down an image works, I don't think scaling up will work at the moment
+// ### An idea I have to make this a smooth scale is to progressively add the pixel values up
+// When scaling down, multiple values are being over drawn in to the output buffer.
+// Instead, a weighting based on the distance the line or pixel is from the output pixel determines
+// the weight of it when added to the output buffer. At present it is a non-smooth scale which is
+// inefficently implemented, it still uncompresses all the jpeg, an optimization for progressive
+// jpegs could be made if scaling by say 50% or some other special cases
+ out[sWidth * i / cinfo.output_width] = tqRgb( in[0], in[1], in[2] );
+ in += 3;
+ }
+ } else {
+// ### Need to test the case where the jpeg is grayscale, need some black and white jpegs to test
+// this code. (also only scales down and probably won't scale to a larger size)
+ uchar *in = inLines[0];
+ uchar *out = outLines[outputLine];
+ for (uint i=0; i<cinfo.output_width; i++ ) {
+ out[sWidth * i / cinfo.output_width] = in[i];
+ }
+ }
+ }
+ (void) jpeg_finish_decompress(&cinfo);
+ }
+
+ } else {
+
+ bool created = FALSE;
+ if ( cinfo.output_components == 3 || cinfo.output_components == 4) {
+ created = image.create( cinfo.output_width, cinfo.output_height, 32 );
+ } else if ( cinfo.output_components == 1 ) {
+ created = image.create( cinfo.output_width, cinfo.output_height, 8, 256 );
+ for (int i=0; i<256; i++)
+ image.setColor(i, tqRgb(i,i,i));
+ } else {
+ // Unsupported format
+ }
+ if (!created)
+ image = TQImage();
+
+ if (!image.isNull()) {
+ uchar** lines = image.jumpTable();
+ while (cinfo.output_scanline < cinfo.output_height)
+ (void) jpeg_read_scanlines(&cinfo,
+ lines + cinfo.output_scanline,
+ cinfo.output_height);
+ (void) jpeg_finish_decompress(&cinfo);
+
+ if ( cinfo.output_components == 3 ) {
+ // Expand 24->32 bpp.
+ for (uint j=0; j<cinfo.output_height; j++) {
+ uchar *in = image.scanLine(j) + cinfo.output_width * 3;
+ TQRgb *out = (TQRgb*)image.scanLine(j);
+
+ for (uint i=cinfo.output_width; i--; ) {
+ in-=3;
+ out[i] = tqRgb(in[0], in[1], in[2]);
+ }
+ }
+ }
+ }
+ }
+
+ if (!image.isNull()) {
+ if ( cinfo.density_unit == 1 ) {
+ image.setDotsPerMeterX( int(100. * cinfo.X_density / 2.54) );
+ image.setDotsPerMeterY( int(100. * cinfo.Y_density / 2.54) );
+ } else if ( cinfo.density_unit == 2 ) {
+ image.setDotsPerMeterX( int(100. * cinfo.X_density) );
+ image.setDotsPerMeterY( int(100. * cinfo.Y_density) );
+ }
+ }
+
+ iio->setImage(image);
+ iio->setqStatus(image.isNull());
+ }
+
+ jpeg_destroy_decompress(&cinfo);
+ delete iod_src;
+}
+
+
+struct my_jpeg_destination_mgr : public jpeg_destination_mgr {
+ // Nothing dynamic - cannot rely on destruction over longjump
+ TQImageIO* iio;
+ JOCTET buffer[max_buf];
+
+public:
+ my_jpeg_destination_mgr(TQImageIO*);
+};
+
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static
+void qt_init_destination(j_compress_ptr)
+{
+}
+
+static
+void qt_exit_on_error(j_compress_ptr cinfo, TQIODevice* dev)
+{
+ if (dev->status() == IO_Ok) {
+ return;
+ } else {
+ // cinfo->err->msg_code = JERR_FILE_WRITE;
+ (*cinfo->err->error_exit)((j_common_ptr)cinfo);
+ }
+}
+
+static
+boolean qt_empty_output_buffer(j_compress_ptr cinfo)
+{
+ my_jpeg_destination_mgr* dest = (my_jpeg_destination_mgr*)cinfo->dest;
+ TQIODevice* dev = dest->iio->ioDevice();
+
+ if ( dev->writeBlock( (char*)dest->buffer, max_buf ) != max_buf )
+ qt_exit_on_error(cinfo, dev);
+
+ dest->next_output_byte = dest->buffer;
+ dest->free_in_buffer = max_buf;
+
+#if defined(TQ_OS_UNIXWARE)
+ return B_TRUE;
+#else
+ return TRUE;
+#endif
+}
+
+static
+void qt_term_destination(j_compress_ptr cinfo)
+{
+ my_jpeg_destination_mgr* dest = (my_jpeg_destination_mgr*)cinfo->dest;
+ TQIODevice* dev = dest->iio->ioDevice();
+ TQ_LONG n = max_buf - dest->free_in_buffer;
+
+ if ( dev->writeBlock( (char*)dest->buffer, n ) != n )
+ qt_exit_on_error(cinfo, dev);
+
+ dev->flush();
+
+ qt_exit_on_error(cinfo, dev);
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+inline
+my_jpeg_destination_mgr::my_jpeg_destination_mgr(TQImageIO* iioptr)
+{
+ jpeg_destination_mgr::init_destination = qt_init_destination;
+ jpeg_destination_mgr::empty_output_buffer = qt_empty_output_buffer;
+ jpeg_destination_mgr::term_destination = qt_term_destination;
+ iio = iioptr;
+ next_output_byte = buffer;
+ free_in_buffer = max_buf;
+}
+
+
+static
+void write_jpeg_image(TQImageIO* iio)
+{
+ TQImage image = iio->image();
+
+ struct jpeg_compress_struct cinfo;
+ JSAMPROW row_pointer[1];
+ row_pointer[0] = 0;
+
+ struct my_jpeg_destination_mgr *iod_dest = new my_jpeg_destination_mgr(iio);
+ struct my_error_mgr jerr;
+
+ cinfo.err = jpeg_std_error(&jerr);
+
+ jerr.error_exit = my_error_exit;
+
+ if (!setjmp(jerr.setjmp_buffer)) {
+ jpeg_create_compress(&cinfo);
+
+ cinfo.dest = iod_dest;
+
+ cinfo.image_width = image.width();
+ cinfo.image_height = image.height();
+
+ TQRgb* cmap=0;
+ bool gray=FALSE;
+ switch ( image.depth() ) {
+ case 1:
+ case 8:
+ cmap = image.tqcolorTable();
+ gray = TRUE;
+ int i;
+ for (i=image.numColors(); gray && i--; ) {
+ gray = gray & ( tqRed(cmap[i]) == tqGreen(cmap[i]) &&
+ tqRed(cmap[i]) == tqBlue(cmap[i]) );
+ }
+ cinfo.input_components = gray ? 1 : 3;
+ cinfo.in_color_space = gray ? JCS_GRAYSCALE : JCS_RGB;
+ break;
+ case 32:
+ cinfo.input_components = 3;
+ cinfo.in_color_space = JCS_RGB;
+ }
+
+ jpeg_set_defaults(&cinfo);
+
+ float diffInch = TQABS(image.dotsPerMeterX()*2.54/100. - tqRound(image.dotsPerMeterX()*2.54/100.))
+ + TQABS(image.dotsPerMeterY()*2.54/100. - tqRound(image.dotsPerMeterY()*2.54/100.));
+ float diffCm = (TQABS(image.dotsPerMeterX()/100. - tqRound(image.dotsPerMeterX()/100.))
+ + TQABS(image.dotsPerMeterY()/100. - tqRound(image.dotsPerMeterY()/100.)))*2.54;
+ if (diffInch < diffCm) {
+ cinfo.density_unit = 1; // dots/inch
+ cinfo.X_density = tqRound(image.dotsPerMeterX()*2.54/100.);
+ cinfo.Y_density = tqRound(image.dotsPerMeterY()*2.54/100.);
+ } else {
+ cinfo.density_unit = 2; // dots/cm
+ cinfo.X_density = (image.dotsPerMeterX()+50) / 100;
+ cinfo.Y_density = (image.dotsPerMeterY()+50) / 100;
+ }
+
+ int quality = iio->quality() >= 0 ? TQMIN(iio->quality(),100) : 75;
+#if defined(TQ_OS_UNIXWARE)
+ jpeg_set_quality(&cinfo, quality, B_TRUE /* limit to baseline-JPEG values */);
+ jpeg_start_compress(&cinfo, B_TRUE);
+#else
+ jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
+ jpeg_start_compress(&cinfo, TRUE);
+#endif
+
+ row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
+ int w = cinfo.image_width;
+ while (cinfo.next_scanline < cinfo.image_height) {
+ uchar *row = row_pointer[0];
+ switch ( image.depth() ) {
+ case 1:
+ if (gray) {
+ uchar* data = image.scanLine(cinfo.next_scanline);
+ if ( image.bitOrder() == TQImage::LittleEndian ) {
+ for (int i=0; i<w; i++) {
+ bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));
+ row[i] = tqRed(cmap[bit]);
+ }
+ } else {
+ for (int i=0; i<w; i++) {
+ bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));
+ row[i] = tqRed(cmap[bit]);
+ }
+ }
+ } else {
+ uchar* data = image.scanLine(cinfo.next_scanline);
+ if ( image.bitOrder() == TQImage::LittleEndian ) {
+ for (int i=0; i<w; i++) {
+ bool bit = !!(*(data + (i >> 3)) & (1 << (i & 7)));
+ *row++ = tqRed(cmap[bit]);
+ *row++ = tqGreen(cmap[bit]);
+ *row++ = tqBlue(cmap[bit]);
+ }
+ } else {
+ for (int i=0; i<w; i++) {
+ bool bit = !!(*(data + (i >> 3)) & (1 << (7 -(i & 7))));
+ *row++ = tqRed(cmap[bit]);
+ *row++ = tqGreen(cmap[bit]);
+ *row++ = tqBlue(cmap[bit]);
+ }
+ }
+ }
+ break;
+ case 8:
+ if (gray) {
+ uchar* pix = image.scanLine(cinfo.next_scanline);
+ for (int i=0; i<w; i++) {
+ *row = tqRed(cmap[*pix]);
+ ++row; ++pix;
+ }
+ } else {
+ uchar* pix = image.scanLine(cinfo.next_scanline);
+ for (int i=0; i<w; i++) {
+ *row++ = tqRed(cmap[*pix]);
+ *row++ = tqGreen(cmap[*pix]);
+ *row++ = tqBlue(cmap[*pix]);
+ ++pix;
+ }
+ }
+ break;
+ case 32: {
+ TQRgb* rgb = (TQRgb*)image.scanLine(cinfo.next_scanline);
+ for (int i=0; i<w; i++) {
+ *row++ = tqRed(*rgb);
+ *row++ = tqGreen(*rgb);
+ *row++ = tqBlue(*rgb);
+ ++rgb;
+ }
+ }
+ }
+ jpeg_write_scanlines(&cinfo, row_pointer, 1);
+ }
+
+ jpeg_finish_compress(&cinfo);
+ jpeg_destroy_compress(&cinfo);
+
+ iio->setqStatus(0);
+ }
+
+ delete iod_dest;
+ delete [] row_pointer[0];
+}
+
+void qInitJpegIO()
+{
+ // Not much to go on - just 3 bytes: 0xFF, M_SOI, 0xFF
+ // Even the third is not strictly specified as required.
+ TQImageIO::defineIOHandler("JPEG", "^\377\330\377", 0, read_jpeg_image, write_jpeg_image);
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqjpegio.h b/tqtinterface/qt4/src/kernel/tqjpegio.h
new file mode 100644
index 0000000..c27c4fb
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqjpegio.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Definition of JPEG TQImage IOHandler
+**
+** Created : 970621
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQJPEGIO_H
+#define TQJPEGIO_H
+
+#include "tqglobal.h"
+
+#ifndef TQT_NO_IMAGEIO_JPEG
+
+void qInitJpegIO();
+
+#endif // TQT_NO_IMAGEIO_JPEG
+
+#endif // TQJPEGIO_H
diff --git a/tqtinterface/qt4/src/kernel/tqkeycode.h b/tqtinterface/qt4/src/kernel/tqkeycode.h
new file mode 100644
index 0000000..1d376e1
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqkeycode.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Definition of keyboard codes
+**
+** Created : 931030
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQKEYCODE_H
+#define TQKEYCODE_H
+
+#ifndef TQT_H
+#include "tqnamespace.h"
+#endif // TQT_H
+
+// all key codes are now in the TQt namespace class
+
+#endif // TQKEYCODE_H
diff --git a/tqtinterface/qt4/src/kernel/tqkeysequence.cpp b/tqtinterface/qt4/src/kernel/tqkeysequence.cpp
new file mode 100644
index 0000000..f34f697
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqkeysequence.cpp
@@ -0,0 +1,731 @@
+/****************************************************************************
+**
+** Implementation of TQKeySequence class
+**
+** Created : 0108007
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqkeysequence.h"
+
+#ifndef TQT_NO_ACCEL
+
+#include "tqaccel.h"
+#include "tqshared.h"
+#include "tqvaluelist.h"
+#ifndef TQT_NO_REGEXP
+# include "tqregexp.h"
+#endif
+
+#ifdef TQ_WS_MAC
+#define TQMAC_CTRL (TQString(TQChar(0x2318)))
+#define TQMAC_META (TQString(TQChar(0x2303)))
+#define TQMAC_ALT (TQString(TQChar(0x2325)))
+#define TQMAC_SHIFT (TQString(TQChar(0x21E7)))
+#endif
+
+/*!
+ \class TQKeySequence tqkeysequence.h
+ \brief The TQKeySequence class encapsulates a key sequence as used
+ by accelerators.
+
+ \ingroup misc
+
+ A key sequence consists of up to four keyboard codes, each
+ optionally combined with modifiers, e.g. \c SHIFT, \c CTRL, \c
+ ALT, \c META, or \c UNICODE_ACCEL. For example, \c{CTRL + Key_P}
+ might be a sequence used as a shortcut for printing a document.
+ The key codes are listed in \c{tqnamespace.h}. As an alternative,
+ use \c UNICODE_ACCEL with the tqunicode code point of the character.
+ For example, \c{UNICODE_ACCEL + 'A'} gives the same key sequence
+ as \c Key_A.
+
+ Key sequences can be constructed either from an integer key code,
+ or from a human readable translatable string such as
+ "Ctrl+X,Alt+Space". A key sequence can be cast to a TQString to
+ obtain a human readable translated version of the sequence.
+ Translations are done in the "TQAccel" context.
+
+ \sa TQAccel
+*/
+
+/*!
+ \enum TQt::SequenceMatch
+
+ \value NoMatch Sequences have nothing in common
+ \value PartialMatch Sequences match partially, but are not complete
+ \value Identical Sequences do not differ
+*/
+
+static struct {
+ int key;
+ const char* name;
+} keyname[] = {
+ { TQt::Key_Space, TQT_TRANSLATE_NOOP( "TQAccel", "Space" ) },
+ { TQt::Key_Escape, TQT_TRANSLATE_NOOP( "TQAccel", "Esc" ) },
+ { TQt::Key_Tab, TQT_TRANSLATE_NOOP( "TQAccel", "Tab" ) },
+ { TQt::Key_Backtab, TQT_TRANSLATE_NOOP( "TQAccel", "Backtab" ) },
+ { TQt::Key_Backspace, TQT_TRANSLATE_NOOP( "TQAccel", "Backspace" ) },
+ { TQt::Key_Return, TQT_TRANSLATE_NOOP( "TQAccel", "Return" ) },
+ { TQt::Key_Enter, TQT_TRANSLATE_NOOP( "TQAccel", "Enter" ) },
+ { TQt::Key_Insert, TQT_TRANSLATE_NOOP( "TQAccel", "Ins" ) },
+ { TQt::Key_Delete, TQT_TRANSLATE_NOOP( "TQAccel", "Del" ) },
+ { TQt::Key_Pause, TQT_TRANSLATE_NOOP( "TQAccel", "Pause" ) },
+ { TQt::Key_Print, TQT_TRANSLATE_NOOP( "TQAccel", "Print" ) },
+ { TQt::Key_SysReq, TQT_TRANSLATE_NOOP( "TQAccel", "SysReq" ) },
+ { TQt::Key_Home, TQT_TRANSLATE_NOOP( "TQAccel", "Home" ) },
+ { TQt::Key_End, TQT_TRANSLATE_NOOP( "TQAccel", "End" ) },
+ { TQt::Key_Left, TQT_TRANSLATE_NOOP( "TQAccel", "Left" ) },
+ { TQt::Key_Up, TQT_TRANSLATE_NOOP( "TQAccel", "Up" ) },
+ { TQt::Key_Right, TQT_TRANSLATE_NOOP( "TQAccel", "Right" ) },
+ { TQt::Key_Down, TQT_TRANSLATE_NOOP( "TQAccel", "Down" ) },
+ { TQt::Key_Prior, TQT_TRANSLATE_NOOP( "TQAccel", "PgUp" ) },
+ { TQt::Key_Next, TQT_TRANSLATE_NOOP( "TQAccel", "PgDown" ) },
+ { TQt::Key_CapsLock, TQT_TRANSLATE_NOOP( "TQAccel", "CapsLock" ) },
+ { TQt::Key_NumLock, TQT_TRANSLATE_NOOP( "TQAccel", "NumLock" ) },
+ { TQt::Key_ScrollLock, TQT_TRANSLATE_NOOP( "TQAccel", "ScrollLock" ) },
+ { TQt::Key_Menu, TQT_TRANSLATE_NOOP( "TQAccel", "Menu" ) },
+ { TQt::Key_Help, TQT_TRANSLATE_NOOP( "TQAccel", "Help" ) },
+
+ // Multimedia keys
+ { TQt::Key_Back, TQT_TRANSLATE_NOOP( "TQAccel", "Back" ) },
+ { TQt::Key_Forward, TQT_TRANSLATE_NOOP( "TQAccel", "Forward" ) },
+ { TQt::Key_Stop, TQT_TRANSLATE_NOOP( "TQAccel", "Stop" ) },
+ { TQt::Key_Refresh, TQT_TRANSLATE_NOOP( "TQAccel", "Refresh" ) },
+ { TQt::Key_VolumeDown, TQT_TRANSLATE_NOOP( "TQAccel", "Volume Down" ) },
+ { TQt::Key_VolumeMute, TQT_TRANSLATE_NOOP( "TQAccel", "Volume Mute" ) },
+ { TQt::Key_VolumeUp, TQT_TRANSLATE_NOOP( "TQAccel", "Volume Up" ) },
+ { TQt::Key_BassBoost, TQT_TRANSLATE_NOOP( "TQAccel", "Bass Boost" ) },
+ { TQt::Key_BassUp, TQT_TRANSLATE_NOOP( "TQAccel", "Bass Up" ) },
+ { TQt::Key_BassDown, TQT_TRANSLATE_NOOP( "TQAccel", "Bass Down" ) },
+ { TQt::Key_TrebleUp, TQT_TRANSLATE_NOOP( "TQAccel", "Treble Up" ) },
+ { TQt::Key_TrebleDown, TQT_TRANSLATE_NOOP( "TQAccel", "Treble Down" ) },
+ { TQt::Key_MediaPlay, TQT_TRANSLATE_NOOP( "TQAccel", "Media Play" ) },
+ { TQt::Key_MediaStop, TQT_TRANSLATE_NOOP( "TQAccel", "Media Stop" ) },
+ { TQt::Key_MediaPrev, TQT_TRANSLATE_NOOP( "TQAccel", "Media Previous" ) },
+ { TQt::Key_MediaNext, TQT_TRANSLATE_NOOP( "TQAccel", "Media Next" ) },
+ { TQt::Key_MediaRecord, TQT_TRANSLATE_NOOP( "TQAccel", "Media Record" ) },
+ { TQt::Key_HomePage, TQT_TRANSLATE_NOOP( "TQAccel", "Home" ) },
+ { TQt::Key_Favorites, TQT_TRANSLATE_NOOP( "TQAccel", "Favorites" ) },
+ { TQt::Key_Search, TQT_TRANSLATE_NOOP( "TQAccel", "Search" ) },
+ { TQt::Key_Standby, TQT_TRANSLATE_NOOP( "TQAccel", "Standby" ) },
+ { TQt::Key_OpenUrl, TQT_TRANSLATE_NOOP( "TQAccel", "Open URL" ) },
+ { TQt::Key_LaunchMail, TQT_TRANSLATE_NOOP( "TQAccel", "Launch Mail" ) },
+ { TQt::Key_LaunchMedia, TQT_TRANSLATE_NOOP( "TQAccel", "Launch Media" ) },
+ { TQt::Key_Launch0, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (0)" ) },
+ { TQt::Key_Launch1, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (1)" ) },
+ { TQt::Key_Launch2, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (2)" ) },
+ { TQt::Key_Launch3, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (3)" ) },
+ { TQt::Key_Launch4, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (4)" ) },
+ { TQt::Key_Launch5, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (5)" ) },
+ { TQt::Key_Launch6, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (6)" ) },
+ { TQt::Key_Launch7, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (7)" ) },
+ { TQt::Key_Launch8, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (8)" ) },
+ { TQt::Key_Launch9, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (9)" ) },
+ { TQt::Key_LaunchA, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (A)" ) },
+ { TQt::Key_LaunchB, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (B)" ) },
+ { TQt::Key_LaunchC, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (C)" ) },
+ { TQt::Key_LaunchD, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (D)" ) },
+ { TQt::Key_LaunchE, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (E)" ) },
+ { TQt::Key_LaunchF, TQT_TRANSLATE_NOOP( "TQAccel", "Launch (F)" ) },
+
+ // --------------------------------------------------------------
+ // More consistent namings
+ { TQt::Key_Print, TQT_TRANSLATE_NOOP( "TQAccel", "Print Screen" ) },
+ { TQt::Key_Prior, TQT_TRANSLATE_NOOP( "TQAccel", "Page Up" ) },
+ { TQt::Key_Next, TQT_TRANSLATE_NOOP( "TQAccel", "Page Down" ) },
+ { TQt::Key_CapsLock, TQT_TRANSLATE_NOOP( "TQAccel", "Caps Lock" ) },
+ { TQt::Key_NumLock, TQT_TRANSLATE_NOOP( "TQAccel", "Num Lock" ) },
+ { TQt::Key_NumLock, TQT_TRANSLATE_NOOP( "TQAccel", "Number Lock" ) },
+ { TQt::Key_ScrollLock, TQT_TRANSLATE_NOOP( "TQAccel", "Scroll Lock" ) },
+ { TQt::Key_Insert, TQT_TRANSLATE_NOOP( "TQAccel", "Insert" ) },
+ { TQt::Key_Delete, TQT_TRANSLATE_NOOP( "TQAccel", "Delete" ) },
+ { TQt::Key_Escape, TQT_TRANSLATE_NOOP( "TQAccel", "Escape" ) },
+ { TQt::Key_SysReq, TQT_TRANSLATE_NOOP( "TQAccel", "System Request" ) },
+
+ { 0, 0 }
+};
+
+
+class TQKeySequencePrivate : public TQShared
+{
+public:
+ inline TQKeySequencePrivate()
+ {
+ key[0] = key[1] = key[2] = key[3] = 0;
+ }
+ inline TQKeySequencePrivate( TQKeySequencePrivate *copy )
+ {
+ key[0] = copy->key[0];
+ key[1] = copy->key[1];
+ key[2] = copy->key[2];
+ key[3] = copy->key[3];
+ }
+ int key[4];
+};
+
+
+/*!
+ Constructs an empty key sequence.
+*/
+TQKeySequence::TQKeySequence()
+{
+ d = new TQKeySequencePrivate();
+ TQ_CHECK_PTR( d );
+}
+
+/*!
+ Creates a key sequence from the string \a key. For example
+ "Ctrl+O" gives CTRL+UNICODE_ACCEL+'O'. The strings "Ctrl",
+ "Shift", "Alt" and "Meta" are recognized, as well as their
+ translated equivalents in the "TQAccel" context (using
+ TQObject::tr()).
+
+ Multiple key codes (up to four) may be entered by separating them
+ with commas, e.g. "Alt+X,Ctrl+S,Q".
+
+ This contructor is typically used with \link TQObject::tr() tr
+ \endlink(), so that accelerator keys can be tqreplaced in
+ translations:
+
+ \code
+ TQPopupMenu *file = new TQPopupMenu( this );
+ file->insertItem( tr("&Open..."), this, TQT_SLOT(open()),
+ TQKeySequence( tr("Ctrl+O", "File|Open") ) );
+ \endcode
+
+ Note the \c "File|Open" translator comment. It is by no means
+ necessary, but it provides some context for the human translator.
+*/
+TQKeySequence::TQKeySequence( const TQString& key )
+{
+ d = new TQKeySequencePrivate();
+ TQ_CHECK_PTR( d );
+ assign( key );
+}
+
+
+// ### BCI: Merge with constructor below for 4.0
+/*!
+ Constructs a key sequence that has a single \a key.
+
+ The key codes are listed in \c{tqnamespace.h} and can be
+ combined with modifiers, e.g. with \c SHIFT, \c CTRL, \c
+ ALT, \c META or \c UNICODE_ACCEL.
+*/
+TQKeySequence::TQKeySequence( int key )
+{
+ d = new TQKeySequencePrivate();
+ TQ_CHECK_PTR( d );
+ d->key[0] = key;
+}
+
+/*!
+ Constructs a key sequence with up to 4 keys \a k1, \a k2,
+ \a k3 and \a k4.
+
+ The key codes are listed in \c{tqnamespace.h} and can be
+ combined with modifiers, e.g. with \c SHIFT, \c CTRL, \c
+ ALT, \c META or \c UNICODE_ACCEL.
+*/
+TQKeySequence::TQKeySequence( int k1, int k2, int k3, int k4 )
+{
+ d = new TQKeySequencePrivate();
+ TQ_CHECK_PTR( d );
+ d->key[0] = k1;
+ d->key[1] = k2;
+ d->key[2] = k3;
+ d->key[3] = k4;
+}
+
+/*!
+ Copy constructor. Makes a copy of \a keysequence.
+ */
+TQKeySequence::TQKeySequence( const TQKeySequence& keysequence )
+ : d( keysequence.d )
+{
+ d->ref();
+}
+
+
+/*!
+ Destroys the key sequence.
+ */
+TQKeySequence::~TQKeySequence()
+{
+ if ( d->deref() )
+ delete d;
+}
+
+/*!
+ \internal
+ KeySequences should never be modified, but rather just created.
+ Internally though we do need to modify to keep pace in event
+ delivery.
+*/
+
+void TQKeySequence::setKey( int key, int index )
+{
+#ifdef TQT_CHECK_STATE
+ if ( 0 > index && 4 < index ) {
+ qWarning( "TQKeySequence::setKey: index %u out of range", index );
+ return;
+ }
+#endif // TQT_CHECK_STATE
+
+ if ( 1 < d->count ) {
+ TQKeySequencePrivate *newd = new TQKeySequencePrivate( d );
+ d->deref();
+ d = newd;
+ }
+ d->key[index] = key;
+}
+
+/*!
+ Returns the number of keys in the key sequence.
+ The maximum is 4.
+ */
+uint TQKeySequence::count() const
+{
+ if ( ! d->key[0] )
+ return 0;
+ if ( ! d->key[1] )
+ return 1;
+ if ( ! d->key[2] )
+ return 2;
+ if ( ! d->key[3] )
+ return 3;
+ return 4;
+}
+
+
+/*!
+ Returns TRUE if the key sequence is empty; otherwise returns
+ FALSE.
+*/
+bool TQKeySequence::isEmpty() const
+{
+ return !d->key[0];
+}
+
+
+/*!
+ Adds the string \a keyseq to the key sequence. \a keyseq may
+ contain up to four key codes, provided they are seperated by a
+ comma, e.g. "Alt+X,Ctrl+S,Z"). Returns the number of key codes
+ added.
+*/
+int TQKeySequence::assign( TQString keyseq )
+{
+ TQString part;
+ int n = 0;
+ int p = 0, diff = 0;
+
+ // Run through the whole string, but stop
+ // if we have 4 keys before the end.
+ while ( keyseq.length() && n < 4 ) {
+ // We MUST use something to seperate each sequence, and space
+ // does not cut it, since some of the key names have space
+ // in them.. (Let's hope no one translate with a comma in it:)
+ p = keyseq.tqfind( ',' );
+ if ( -1 != p ) {
+ if ( ',' == keyseq[p+1] ) // e.g. 'Ctrl+,, Shift+,,'
+ p++;
+ if ( ' ' == keyseq[p+1] ) { // Space after comma
+ diff = 1;
+ p++;
+ } else if ( '\0' == keyseq[p+1] ) { // Last comma 'Ctrl+,'
+ p = -1;
+ } else {
+ diff = 0;
+ }
+ }
+ part = keyseq.left( -1==p?keyseq.length():p-diff );
+ keyseq = keyseq.right( -1==p?0:keyseq.length() - ( p + 1 ) );
+ d->key[n] = decodeString( part );
+ n++;
+ }
+ return n;
+}
+
+struct ModifKeyName {
+ ModifKeyName() { }
+ ModifKeyName(int q, TQString n) : qt_key(q), name(n) { }
+ int qt_key;
+ TQString name;
+};
+
+/*!
+ Constructs a single key from the string \str.
+ */
+int TQKeySequence::decodeString( const TQString& str )
+{
+ int ret = 0;
+ TQString accel = str;
+
+ TQValueList<ModifKeyName> modifs;
+#ifdef TQMAC_CTRL
+ modifs << ModifKeyName( CTRL, TQMAC_CTRL );
+#endif
+#ifdef TQMAC_ALT
+ modifs << ModifKeyName( ALT, TQMAC_ALT );
+#endif
+#ifdef TQMAC_META
+ modifs << ModifKeyName( META, TQMAC_META );
+#endif
+#ifdef TQMAC_SHIFT
+ modifs << ModifKeyName( SHIFT, TQMAC_SHIFT );
+#endif
+ modifs << ModifKeyName( CTRL, "ctrl+" ) << ModifKeyName( CTRL, TQAccel::tqtr("Ctrl").lower().append('+') );
+ modifs << ModifKeyName( SHIFT, "shift+" ) << ModifKeyName( SHIFT, TQAccel::tqtr("Shift").lower().append('+') );
+ modifs << ModifKeyName( ALT, "alt+" ) << ModifKeyName( ALT, TQAccel::tqtr("Alt").lower().append('+') );
+ modifs << ModifKeyName( META, "meta+" ) << ModifKeyName( ALT, TQAccel::tqtr("Meta").lower().append('+') );
+ TQString sl = accel.lower();
+ for( TQValueList<ModifKeyName>::iterator it = modifs.begin(); it != modifs.end(); ++it ) {
+ if ( sl.tqcontains( (*it).name ) ) {
+ ret |= (*it).qt_key;
+#ifndef TQT_NO_REGEXP
+ accel.remove( TQRegExp(TQRegExp::escape((*it).name), FALSE) );
+#else
+ accel.remove( (*it).name );
+#endif
+ sl = accel.lower();
+ }
+ }
+
+ int p = accel.tqfindRev( '+', str.length() - 2 ); // -2 so that Ctrl++ works
+ if( p > 0 )
+ accel = accel.mid( p + 1 );
+
+ int fnum = 0;
+ if ( accel.length() == 1 ) {
+ char ltr = TQChar(accel[0]).upper().latin1();
+ // We can only upper A-Z without problems.
+ if ( ltr < (char)Key_A || ltr > (char)Key_Z )
+ ret |= TQChar(accel[0]).tqunicode();
+ else
+ ret |= TQChar(accel[0]).upper().tqunicode();
+ ret |= UNICODE_ACCEL;
+ } else if ( accel[0] == 'F' && (fnum = accel.mid(1).toInt()) && (fnum >= 1) && (fnum <= 35) ) {
+ ret |= Key_F1 + fnum - 1;
+ } else {
+ // Check through translation table for the correct key name
+ // ...or fall back on english table.
+ bool found = FALSE;
+ for ( int tran = 0; tran < 2; tran++ ) {
+ for ( int i = 0; keyname[i].name; i++ ) {
+ if ( tran ? accel == TQAccel::tr(keyname[i].name)
+ : accel == keyname[i].name ) {
+ ret |= keyname[i].key;
+ found = TRUE;
+ break;
+ }
+ }
+ if(found)
+ break;
+ }
+ }
+ return ret;
+}
+
+
+/*!
+ Creates an accelerator string for \a key. For example,
+ CTRL+Key_O gives "Ctrl+O". The strings, "Ctrl", "Shift", etc. are
+ translated (using TQObject::tr()) in the "TQAccel" context.
+ */
+TQString TQKeySequence::encodeString( int key )
+{
+ TQString s;
+#if defined(TQ_OS_MAC) && !defined(TQWS)
+ // On MAC the order is Meta, Alt, Shift, Control.
+ if ( (key & META) == META )
+ s += TQMAC_META;
+ if ( (key & ALT) == ALT )
+ s += TQMAC_ALT;
+ if ( (key & SHIFT) == SHIFT )
+ s += TQMAC_SHIFT;
+ if ( (key & CTRL) == CTRL )
+ s += TQMAC_CTRL;
+#else
+ // On other systems the order is Meta, Control, Alt, Shift
+ if ( (key & META) == META )
+ s += TQAccel::tqtr( "Meta" );
+ if ( (key & CTRL) == CTRL ) {
+ if ( !s.isEmpty() )
+ s += TQAccel::tqtr( "+" );
+ s += TQAccel::tqtr( "Ctrl" );
+ }
+ if ( (key & ALT) == ALT ) {
+ if ( !s.isEmpty() )
+ s += TQAccel::tqtr( "+" );
+ s += TQAccel::tqtr( "Alt" );
+ }
+ if ( (key & SHIFT) == SHIFT ) {
+ if ( !s.isEmpty() )
+ s += TQAccel::tqtr( "+" );
+ s += TQAccel::tqtr( "Shift" );
+ }
+#endif
+
+
+ key &= ~(SHIFT | CTRL | ALT | META );
+ TQString p;
+
+ if ( (key & UNICODE_ACCEL) == UNICODE_ACCEL ) {
+ // Note: This character should NOT be upper()'ed, since
+ // the encoded string should indicate EXACTLY what the
+ // key represents! Hence a 'Ctrl+Shift+c' is posible to
+ // represent, but is clearly impossible to trigger...
+ p = TQChar(key & 0xffff);
+ } else if ( key >= Key_F1 && key <= Key_F35 ) {
+ p = TQAccel::tqtr( "F%1" ).arg(key - Key_F1 + 1);
+ } else if ( key > Key_Space && key <= Key_AsciiTilde ) {
+ p.sprintf( "%c", key );
+ } else {
+ int i=0;
+ while (keyname[i].name) {
+ if ( key == keyname[i].key ) {
+ p = TQAccel::tqtr(keyname[i].name);
+ break;
+ }
+ ++i;
+ }
+ // If we can't tqfind the actual translatable keyname,
+ // fall back on the tqunicode representation of it...
+ // Or else characters like Key_aring may not get displayed
+ // ( Really depends on you locale )
+ if ( !keyname[i].name )
+ // Note: This character should NOT be upper()'ed, see above!
+ p = TQChar(key & 0xffff);
+ }
+
+#ifndef TQ_OS_MAC
+ if ( !s.isEmpty() )
+ s += TQAccel::tqtr( "+" );
+#endif
+
+ s += p;
+ return s;
+}
+
+/*!
+ Matches the sequence with \a seq. Returns \c TQt::Identical if
+ successful, \c TQt::PartialMatch for matching but incomplete \a seq,
+ and \c TQt::NoMatch if the sequences have nothing in common.
+ Returns \c TQt::NoMatch if \a seq is shorter.
+*/
+TQt::SequenceMatch TQKeySequence::matches( const TQKeySequence& seq ) const
+{
+ uint userN = count(),
+ seqN = seq.count();
+
+ if ( userN > seqN )
+ return NoMatch;
+
+ // If equal in length, we have a potential Identical sequence,
+ // else we already know it can only be partial.
+ SequenceMatch match = ( userN == seqN ? Identical : PartialMatch );
+
+ for ( uint i = 0; i < userN; i++ ) {
+ int userKey = (*this)[i],
+ sequenceKey = seq[i];
+
+ if ( (userKey & ~TQt::UNICODE_ACCEL) !=
+ (sequenceKey & ~TQt::UNICODE_ACCEL) )
+ return NoMatch;
+ }
+ return match;
+}
+
+
+/*!
+ Creates an accelerator string for the key sequence.
+ For instance CTRL+Key_O gives "Ctrl+O". If the key sequence has
+ multiple key codes they are returned comma-separated, e.g.
+ "Alt+X, Ctrl+Y, Z". The strings, "Ctrl", "Shift", etc. are
+ translated (using TQObject::tr()) in the "TQAccel" scope. If the key
+ sequence has no keys, TQString::null is returned.
+
+ On Mac OS X, the string returned resembles the sequence that is shown in
+ the menubar.
+*/
+TQKeySequence::operator TQString() const
+{
+ int end = count();
+ if ( !end ) return TQString::null;
+
+ TQString complete;
+ int i = 0;
+ while ( i < end ) {
+ complete += encodeString( d->key[i] );
+ i++;
+ if ( i != end)
+ complete += ", ";
+ }
+ return complete;
+}
+
+
+/*!
+ \obsolete
+ For backward compatibility: returns the first keycode
+ as integer. If the key sequence is empty, 0 is returned.
+ */
+TQKeySequence::operator int () const
+{
+ if ( 1 <= count() )
+ return d->key[0];
+ return 0;
+}
+
+
+/*!
+ Returns a reference to the element at position \a index in the key
+ sequence. This can only be used to read an element.
+ */
+int TQKeySequence::operator[]( uint index ) const
+{
+#ifdef TQT_CHECK_STATE
+ if ( index > 4 ) {
+ qWarning( "TQKeySequence::operator[]: index %u out of range", index );
+ return 0;
+ }
+#endif // TQT_CHECK_STATE
+ return d->key[index];
+}
+
+
+/*!
+ Assignment operator. Assigns \a keysequence to this
+ object.
+ */
+TQKeySequence &TQKeySequence::operator=( const TQKeySequence & keysequence )
+{
+ keysequence.d->ref();
+ if ( d->deref() )
+ delete d;
+ d = keysequence.d;
+ return *this;
+}
+
+
+/*!
+ Returns TRUE if \a keysequence is equal to this key
+ sequence; otherwise returns FALSE.
+ */
+
+
+bool TQKeySequence::operator==( const TQKeySequence& keysequence ) const
+{
+ return ( (d->key[0]&~UNICODE_ACCEL) == (keysequence.d->key[0]&~UNICODE_ACCEL) &&
+ (d->key[1]&~UNICODE_ACCEL) == (keysequence.d->key[1]&~UNICODE_ACCEL) &&
+ (d->key[2]&~UNICODE_ACCEL) == (keysequence.d->key[2]&~UNICODE_ACCEL) &&
+ (d->key[3]&~UNICODE_ACCEL) == (keysequence.d->key[3]&~UNICODE_ACCEL) );
+}
+
+
+/*!
+ Returns TRUE if \a keysequence is not equal to this key sequence;
+ otherwise returns FALSE.
+*/
+bool TQKeySequence::operator!= ( const TQKeySequence& keysequence ) const
+{
+ TQKeySequence *that = (TQKeySequence*)this;
+ return !( (*that) == keysequence );
+}
+
+
+/*****************************************************************************
+ TQKeySequence stream functions
+ *****************************************************************************/
+#if !defined(TQT_NO_DATASTREAM) && !defined(TQT_NO_IMAGEIO)
+/*!
+ \relates TQKeySequence
+
+ Writes the key sequence \a keysequence to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+TQDataStream &operator<<( TQDataStream &s, const TQKeySequence &keysequence )
+{
+ TQValueList<int> list;
+ list += keysequence.d->key[0];
+ list += keysequence.d->key[1];
+ list += keysequence.d->key[2];
+ list += keysequence.d->key[3];
+ s << list;
+
+ return s;
+}
+
+
+/*!
+ \relates TQKeySequence
+
+ Reads a key sequence from the stream \a s into the key sequence \a
+ keysequence.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+TQDataStream &operator>>( TQDataStream &s, TQKeySequence &keysequence )
+{
+ TQValueList<int> list;
+ s >> list;
+
+#ifdef TQT_CHECK_STATE
+ if ( 1 != list.count() && 4 != list.count() ) {
+ qWarning( "Invalid TQKeySequence data in the datastream." );
+ return s;
+ }
+#endif
+
+ if ( 1 == list.count() ) {
+ keysequence.d->key[0] = *list.at( 0 );
+ keysequence.d->key[1] =
+ keysequence.d->key[2] =
+ keysequence.d->key[3] = 0;
+ } else {
+ keysequence.d->key[0] = *list.at( 0 );
+ keysequence.d->key[1] = *list.at( 1 );
+ keysequence.d->key[2] = *list.at( 2 );
+ keysequence.d->key[3] = *list.at( 3 );
+ }
+ return s;
+}
+
+#endif //TQT_NO_DATASTREAM
+
+#endif //TQT_NO_ACCEL
diff --git a/tqtinterface/qt4/src/kernel/tqkeysequence.h b/tqtinterface/qt4/src/kernel/tqkeysequence.h
new file mode 100644
index 0000000..a1274ac
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqkeysequence.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Definition of TQKeySequence class
+**
+** Created : 0108007
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQKEYSETQUENCE_H
+#define TQKEYSETQUENCE_H
+
+#ifndef TQT_H
+#ifndef TQT_H
+#include "tqnamespace.h"
+#include "tqstring.h"
+#endif // TQT_H
+#endif
+
+#ifndef TQT_NO_ACCEL
+
+/*****************************************************************************
+ TQKeySequence stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+class TQKeySequence;
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQKeySequence & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQKeySequence & );
+#endif
+
+class TQKeySequencePrivate;
+
+class TQ_EXPORT TQKeySequence : public TQt
+{
+public:
+ TQKeySequence();
+ TQKeySequence( const TQString& key );
+ TQKeySequence( int key );
+ TQKeySequence( int k1, int k2, int k3 = 0, int k4 = 0 );
+ TQKeySequence( const TQKeySequence & );
+ ~TQKeySequence();
+
+ uint count() const;
+ bool isEmpty() const;
+ TQt::SequenceMatch matches( const TQKeySequence & ) const;
+
+ operator TQString() const;
+ operator int () const;
+ int operator[]( uint ) const;
+ TQKeySequence &operator=( const TQKeySequence & );
+ bool operator==( const TQKeySequence& ) const;
+ bool operator!= ( const TQKeySequence& ) const;
+
+private:
+ static int decodeString( const TQString & );
+ static TQString encodeString( int );
+ int assign( TQString );
+ void setKey( int key, int index );
+
+ TQKeySequencePrivate* d;
+
+ friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQKeySequence & );
+ friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQKeySequence & );
+ friend class TQAccelManager;
+};
+
+#else
+
+class TQ_EXPORT TQKeySequence : public TQt
+{
+public:
+ TQKeySequence() {}
+ TQKeySequence( int ) {}
+};
+
+#endif //TQT_NO_ACCEL
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqlayout.cpp b/tqtinterface/qt4/src/kernel/tqlayout.cpp
new file mode 100644
index 0000000..e9f5493
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqlayout.cpp
@@ -0,0 +1,4056 @@
+/****************************************************************************
+**
+** Implementation of tqlayout classes
+**
+** Created : 960416
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqlayout.h"
+
+#ifndef TQT_NO_LAYOUT
+
+#include "tqapplication.h"
+#include "tqwidget.h"
+#include "tqmenubar.h"
+#include "tqptrlist.h"
+#include "tqsizepolicy.h"
+
+#include "tqlayoutengine_p.h"
+
+#ifdef USE_QT4
+
+int menuBarHeightForWidth( QWidget *menubar_w, int w )
+{
+#ifndef TQT_NO_MENUBAR
+ TQMenuBar *menubar = static_cast<TQMenuBar*>(TQT_TQWIDGET(menubar_w));
+ if ( menubar && !menubar->isHidden() && !menubar->isTopLevel() )
+ return menubar->heightForWidth( TQMAX(w, menubar->minimumWidth()) );
+ else
+#endif
+ return 0;
+}
+
+TQLayout::TQLayout( QWidget *tqparent, int margin, int spacing, const char *name ) : QLayout( tqparent ), autoNewChild(false)
+{
+ setObjectName(QString::fromAscii(name));
+ setMargin(margin);
+ if (spacing < 0)
+ setSpacing(margin);
+ else
+ setSpacing(spacing);
+ if ( tqparent ) tqparent->installEventFilter( this );
+ TQT_TQOBJECT_REQUIRED_INITIALIZATION(tqparent)
+}
+
+TQLayout::TQLayout( QLayout *parentLayout, int spacing, const char *name ) : QLayout(), autoNewChild(false)
+{
+ setObjectName(QString::fromAscii(name));
+ setSpacing(spacing);
+ if ( parentLayout ) parentLayout->addItem(this);
+ if ( parentLayout ) parentLayout->installEventFilter( this );
+ TQT_TQOBJECT_REQUIRED_INITIALIZATION(parentLayout)
+}
+
+TQLayout::TQLayout( int spacing, const char *name ) : QLayout(), autoNewChild(false)
+{
+ setObjectName(QString::fromAscii(name));
+ setSpacing(spacing);
+}
+
+TQ_SPExpandData TQLayout::expandingDirections() const {
+ return (Qt::Orientations)TQSizePolicy::BothDirections;
+}
+
+TQLayout *TQLayout::tqlayout() {
+ return this;
+}
+
+TQSize TQLayout::tqsizeHint() const {
+ return sizeHint();
+}
+
+TQSize TQLayout::tqminimumSize() const {
+ return QLayout::minimumSize();
+}
+
+TQSize TQLayout::tqmaximumSize() const {
+ return QLayout::maximumSize();
+}
+
+TQWidget *TQLayout::mainWidget() {
+ return TQT_TQWIDGET(parentWidget());
+}
+
+void TQLayout::tqinvalidate() {
+ QLayout::invalidate();
+}
+
+void TQLayout::invalidate() {
+ tqinvalidate();
+}
+
+TQRect TQLayout::tqgeometry() const {
+ return QLayout::geometry();
+}
+
+const char *TQLayout::tqname() const {
+ if (dynamic_cast<const TQLayout*>(static_cast<const QLayout*>(static_cast<const QObject*>(this)))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ printf("[WARNING] Attempted to call TQLayout::tqname() on an object without a constructed TQLayout object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+const char *TQLayout::name() const {
+ if (dynamic_cast<const TQLayout*>(static_cast<const QLayout*>(static_cast<const QObject*>(this)))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ printf("[WARNING] Attempted to call TQLayout::tqname() on an object without a constructed TQLayout object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+int TQLayout::tqalignment() const {
+ return alignment();
+}
+
+TQWidget *TQLayout::mainWidget() const {
+ return TQT_TQWIDGET(parentWidget());
+}
+
+void TQLayout::remove(QWidget *w) {
+ removeWidget(w);
+}
+
+void TQLayout::add(QWidget *w) {
+ addWidget(w);
+}
+
+void TQLayout::setResizeMode(SizeConstraint s) {
+ setSizeConstraint(s);
+}
+
+void TQLayout::setResizeMode(ResizeMode s) {
+ setResizeMode((SizeConstraint)s);
+}
+
+TQLayout::SizeConstraint TQLayout::resizeMode() const {
+ return sizeConstraint();
+}
+
+TQLayout::ResizeMode TQLayout::tqresizeMode() const {
+ return (ResizeMode)sizeConstraint();
+}
+
+void TQLayout::setAutoAdd(bool a) {
+ autoNewChild = a;
+}
+
+bool TQLayout::autoAdd() const {
+ return autoNewChild;
+}
+
+void TQLayout::tqsetAlignment( int a ) {
+ return setAlignment((Qt::Alignment)a);
+}
+
+// Qt4 handler interface
+bool TQLayout::eventFilter( QObject *q, QEvent *e ) {
+ return eventFilter(static_cast<TQObject*>(q), static_cast<TQEvent*>(e));
+}
+
+bool TQLayout::event( QEvent *e ) {
+ return event(static_cast<TQEvent*>(e));
+}
+
+void TQLayout::timerEvent(QTimerEvent *e) {
+ timerEvent(static_cast<TQTimerEvent*>(e));
+}
+
+void TQLayout::childEvent(QChildEvent *e) {
+ TQT_TQOBJECT_CHILDEVENT_CONDITIONAL childEvent(static_cast<TQChildEvent*>(e));
+}
+
+void TQLayout::customEvent(QEvent *e) {
+ customEvent(static_cast<TQCustomEvent*>(e));
+}
+
+bool TQLayout::eventFilter( TQObject *o, TQEvent *e ) {
+ TQ_UNUSED(o);
+
+ if (e->type() == TQEvent::Resize) {
+ activate();
+ TQResizeEvent *r = (TQResizeEvent *)e;
+ int mbh = 0;
+#ifndef TQT_NO_MENUBAR
+ mbh = menuBarHeightForWidth( menuBar(), r->size().width() );
+#endif
+// int b = marginImpl ? 0 : outsideBorder;
+ int b = 0;
+ setGeometry( TQRect( b, mbh + b, r->size().width() - 2 * b, r->size().height() - mbh - 2 * b ) );
+ }
+
+ else if (e->type() == TQEvent::ChildInserted) {
+ if (autoNewChild) {
+ QChildEvent *c = (QChildEvent *)e;
+ if (c->child()->isWidgetType()) {
+ QWidget *w = (QWidget *)c->child();
+ if (!w->isWindow()) {
+// #if !defined(QT_NO_MENUBAR) && !defined(QT_NO_TOOLBAR)
+// if (qobject_cast<QMenuBar*>(w) && !qobject_cast<QToolBar*>(w->parentWidget())) {
+// setMenuBar( (QMenuBar *)w );
+// invalidate();
+// } else
+// #endif
+// #ifndef QT_NO_SIZEGRIP
+// if (qobject_cast<QSizeGrip*>(w) ) {
+// //SizeGrip is handled by the dialog itself.
+// } else
+// #endif
+// addItem(QLayoutPrivate::createWidgetItem(this, w));
+ addWidget(w);
+ }
+ }
+ }
+ }
+ else if (e->type() == TQEvent::LayoutHint) {
+// d->d = false;
+// if (parent()) {
+// if (static_cast<QWidget *>(parent())->isVisible()) {
+ activate();
+// }
+// }
+ }
+// return FALSE;
+ return QLayout::eventFilter( o, e );
+// return TQObject::eventFilter( o, e );
+}
+
+TQLayoutIterator TQLayout::iterator() {
+ return TQLayoutIterator(this,true);
+}
+
+/*!
+ \compat
+
+ Sets this layout's parent widget to a fixed size with width \a w
+ and height \a h, stopping the user from resizing it, and also
+ prevents the layout from resizing it, even if the layout's size
+ hint should change. Does nothing if this is not a top-level
+ layout (i.e., if parent()->isWidgetType()).
+
+ As a special case, if both \a w and \a h are 0, then the layout's
+ current sizeHint() is used.
+
+ Use \c setResizeMode(Fixed) to stop the widget from being resized
+ by the user, while still allowing the layout to resize it when
+ the sizeHint() changes.
+
+ Use \c setResizeMode(FreeResize) to allow the user to resize the
+ widget, while preventing the layout from resizing it.
+
+*/
+void TQLayout::freeze(int w, int h)
+{
+// if (!isTopLevel())
+// return;
+ if (w <= 0 || h <= 0) {
+ QSize s = totalSizeHint();
+ w = s.width();
+ h = s.height();
+ }
+ setSizeConstraint(SetNoConstraint); // layout will not change min/max size
+ QWidget *parent = parentWidget();
+ if (parent)
+ parent->setFixedSize(w, h);
+}
+
+// Use the TQt virtual functions, not the built in Qt ones...
+// This requires that the base virtual Qt functions be reimplemented so as to point to the TQt virtual functions instead as shown below.
+// This way, when Trinity overrides a TQt virtual function, the calling Qt code will blithely use the overriden TQt function instead.
+QLayout *TQLayout::layout() {
+ return tqlayout();
+}
+
+void TQLayout::setGeometry(const TQRect &r) {
+ return QLayout::setGeometry(r);
+}
+
+TQRect TQLayout::alignmentRect( const TQRect& qr ) const {
+ return alignmentRect(qr);
+}
+
+void TQLayout::tqt_handle_qt_destroyed(QObject* obj) {
+ emit destroyed(TQT_TQOBJECT(obj));
+}
+
+TQLayoutIterator::TQLayoutIterator(QLayout *i) : layout(static_cast<TQLayout*>(i)), index(0) {
+}
+
+TQLayoutIterator::TQLayoutIterator(QLayout *i, bool) : layout(static_cast<TQLayout*>(i)), index(0) {
+}
+
+TQLayoutItem *TQLayoutIterator::operator++() {
+ return static_cast<TQLayoutItem*>(layout->itemAt(++index));
+}
+
+TQLayoutItem *TQLayoutIterator::current() {
+ return static_cast<TQLayoutItem*>(layout->itemAt(index));
+}
+
+TQLayoutItem *TQLayoutIterator::takeCurrent() {
+ return static_cast<TQLayoutItem*>(layout->takeAt(index));
+}
+
+void TQLayoutIterator::deleteCurrent() {
+ delete layout->takeAt(index);
+}
+
+TQSpacerItem *TQLayoutItem::tqspacerItem()
+{
+ return static_cast<TQSpacerItem*>(QLayoutItem::spacerItem());
+}
+
+/*!
+ This virtual function receives events to an object and should
+ return TRUE if the event \a e was recognized and processed.
+
+ The event() function can be reimplemented to customize the
+ behavior of an object.
+
+ \sa installEventFilter(), timerEvent(), TQApplication::sendEvent(),
+ TQApplication::postEvent(), TQWidget::event()
+*/
+
+bool TQLayout::event( TQEvent *e )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( e == 0 )
+ qWarning( "TQLayout::event: Null events are not permitted" );
+#endif
+// if ( eventFilters ) { // try filters
+// if ( activate_filters(e) ) // stopped by a filter
+// return TRUE;
+// }
+//
+ switch ( e->type() ) {
+// case TQEvent::Timer:
+// timerEvent( (TQTimerEvent*)e );
+// return TRUE;
+//
+// case TQEvent::DeferredDelete:
+// delete this;
+// return TRUE;
+//
+// default:
+// if ( e->type() >= TQEvent::User ) {
+// customEvent( (TQCustomEvent*) e );
+// return TRUE;
+// }
+// break;
+// }
+
+ case TQEvent::ChildInserted:
+// case TQEvent::ChildRemoved: // Causes a recursion loop if uncommented
+ childEvent( (TQChildEvent*)e );
+ return TRUE;
+
+ default:
+ return QLayout::event(e);
+ }
+
+ return FALSE;
+}
+
+#if 0
+void TQGridLayout::tqsetAlignment( int a )
+{
+ setAlignment((Qt::AlignmentFlag)a);
+}
+#endif
+
+#if 0
+
+// NOTE
+// The following functions are cloned from TQWidget
+// They are only required for TQLayout and TQGridLayout becase those classes do not inherit TQObject or TQWidget
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse move events for the widget.
+
+ If mouse tracking is switched off, mouse move events only occur if
+ a mouse button is pressed while the mouse is being moved. If mouse
+ tracking is switched on, mouse move events occur even if no mouse
+ button is pressed.
+
+ TQMouseEvent::pos() reports the position of the mouse cursor,
+ relative to this widget. For press and release events, the
+ position is usually the same as the position of the last mouse
+ move event, but it might be different if the user's hand shakes.
+ This is a feature of the underlying window system, not TQt.
+
+ \sa setMouseTracking(), mousePressEvent(), mouseReleaseEvent(),
+ mouseDoubleClickEvent(), event(), TQMouseEvent
+*/
+
+void TQLayout::mouseMoveEvent( TQMouseEvent * e)
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse press events for the widget.
+
+ If you create new widgets in the mousePressEvent() the
+ mouseReleaseEvent() may not end up where you expect, depending on
+ the underlying window system (or X11 window manager), the widgets'
+ location and maybe more.
+
+ The default implementation implements the closing of popup widgets
+ when you click outside the window. For other widget types it does
+ nothing.
+
+ \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
+ mouseMoveEvent(), event(), TQMouseEvent
+*/
+
+void TQLayout::mousePressEvent( TQMouseEvent * )
+{
+// TQT_TQWIDGET_CONST(this)->mousePressEvent(e);
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse release events for the widget.
+
+ \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
+ mouseMoveEvent(), event(), TQMouseEvent
+*/
+
+void TQLayout::mouseReleaseEvent( TQMouseEvent * e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse double click events for the widget.
+
+ The default implementation generates a normal mouse press event.
+
+ Note that the widgets gets a mousePressEvent() and a
+ mouseReleaseEvent() before the mouseDoubleClickEvent().
+
+ \sa mousePressEvent(), mouseReleaseEvent() mouseMoveEvent(),
+ event(), TQMouseEvent
+*/
+
+void TQLayout::mouseDoubleClickEvent( TQMouseEvent *e )
+{
+ mousePressEvent( e ); // try mouse press event
+}
+
+#ifndef TQT_NO_WHEELEVENT
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive wheel events for the widget.
+
+ If you reimplement this handler, it is very important that you
+ \link TQWheelEvent ignore()\endlink the event if you do not handle
+ it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa TQWheelEvent::ignore(), TQWheelEvent::accept(), event(),
+ TQWheelEvent
+*/
+
+void TQLayout::wheelEvent( TQWheelEvent *e )
+{
+ e->ignore();
+}
+#endif
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive tablet events for the widget.
+
+ If you reimplement this handler, it is very important that you
+ \link TQTabletEvent ignore()\endlink the event if you do not handle
+ it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa TQTabletEvent::ignore(), TQTabletEvent::accept(), event(),
+ TQTabletEvent
+*/
+
+void TQLayout::tabletEvent( TQTabletEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive key press events for the widget.
+
+ A widget must call setFocusPolicy() to accept focus initially and
+ have focus in order to receive a key press event.
+
+ If you reimplement this handler, it is very important that you
+ explicitly \link TQKeyEvent::ignore() ignore\endlink the event
+ if you do not understand it, so that the widget's tqparent can
+ interpret it; otherwise, the event will be implicitly accepted.
+ Although top-level widgets are able to choose whether to accept
+ or ignore unknown events because they have no tqparent widgets that
+ could otherwise handle them, it is good practice to explicitly
+ ignore events to make widgets as reusable as possible.
+
+ The default implementation closes popup widgets if the user
+ presses <b>Esc</b>. Otherwise the event is ignored.
+
+ \sa keyReleaseEvent(), TQKeyEvent::ignore(), setFocusPolicy(),
+ focusInEvent(), focusOutEvent(), event(), TQKeyEvent
+*/
+
+void TQLayout::keyPressEvent( TQKeyEvent * )
+{
+// TQT_TQWIDGET_CONST(this)->keyPressEvent(e);
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive key release events for the widget.
+
+ A widget must \link setFocusPolicy() accept focus\endlink
+ initially and \link hasFocus() have focus\endlink in order to
+ receive a key release event.
+
+ If you reimplement this handler, it is very important that you
+ \link TQKeyEvent ignore()\endlink the release if you do not
+ understand it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa keyPressEvent(), TQKeyEvent::ignore(), setFocusPolicy(),
+ focusInEvent(), focusOutEvent(), event(), TQKeyEvent
+*/
+
+void TQLayout::keyReleaseEvent( TQKeyEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ keyboard focus events (focus received) for the widget.
+
+ A widget normally must setFocusPolicy() to something other than
+ \c NoFocus in order to receive focus events. (Note that the
+ application programmer can call setFocus() on any widget, even
+ those that do not normally accept focus.)
+
+ The default implementation updates the widget (except for toplevel
+ widgets that do not specify a focusPolicy() ). It also calls
+ setMicroFocusHint(), hinting any system-specific input tools about
+ the focus of the user's attention.
+
+ \sa focusOutEvent(), setFocusPolicy(), keyPressEvent(),
+ keyReleaseEvent(), event(), TQFocusEvent
+*/
+
+void TQLayout::focusInEvent( TQFocusEvent * )
+{
+// TQT_TQWIDGET_CONST(this)->focusInEvent(e);
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ keyboard focus events (focus lost) for the widget.
+
+ A widget normally must setFocusPolicy() to something other than
+ \c NoFocus in order to receive focus events. (Note that the
+ application programmer can call setFocus() on any widget, even
+ those that do not normally accept focus.)
+
+ The default implementation updates the widget (except for toplevel
+ widgets that do not specify a focusPolicy() ). It also calls
+ setMicroFocusHint(), hinting any system-specific input tools about
+ the focus of the user's attention.
+
+ \sa focusInEvent(), setFocusPolicy(), keyPressEvent(),
+ keyReleaseEvent(), event(), TQFocusEvent
+*/
+
+void TQLayout::focusOutEvent( TQFocusEvent * )
+{
+// TQT_TQWIDGET_CONST(this)->focusOutEvent(e);
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget enter events.
+
+ An event is sent to the widget when the mouse cursor enters the
+ widget.
+
+ \sa leaveEvent(), mouseMoveEvent(), event()
+*/
+
+void TQLayout::enterEvent( TQEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget leave events.
+
+ A leave event is sent to the widget when the mouse cursor leaves
+ the widget.
+
+ \sa enterEvent(), mouseMoveEvent(), event()
+*/
+
+void TQLayout::leaveEvent( TQEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ paint events.
+
+ A paint event is a request to tqrepaint all or part of the widget.
+ It can happen as a result of tqrepaint() or update(), or because the
+ widget was obscured and has now been uncovered, or for many other
+ reasons.
+
+ Many widgets can simply tqrepaint their entire surface when asked
+ to, but some slow widgets need to optimize by painting only the
+ requested region: TQPaintEvent::region(). This speed optimization
+ does not change the result, as painting is clipped to that region
+ during event processing. TQListView and TQCanvas do this, for
+ example.
+
+ TQt also tries to speed up painting by merging multiple paint
+ events into one. When update() is called several times or the
+ window system sends several paint events, TQt merges these events
+ into one event with a larger region (see TQRegion::unite()).
+ tqrepaint() does not permit this optimization, so we suggest using
+ update() when possible.
+
+ When the paint event occurs, the update region has normally been
+ erased, so that you're painting on the widget's background. There
+ are a couple of exceptions and TQPaintEvent::erased() tells you
+ whether the widget has been erased or not.
+
+ The background can be set using setBackgroundMode(),
+ setPaletteBackgroundColor() or setBackgroundPixmap(). The
+ documentation for setBackgroundMode() elaborates on the
+ background; we recommend reading it.
+
+ \sa event(), tqrepaint(), update(), TQPainter, TQPixmap, TQPaintEvent
+*/
+
+void TQLayout::paintEvent( TQPaintEvent *e )
+{
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget move events. When the widget receives this event, it is
+ already at the new position.
+
+ The old position is accessible through TQMoveEvent::oldPos().
+
+ \sa resizeEvent(), event(), move(), TQMoveEvent
+*/
+
+void TQLayout::moveEvent( TQMoveEvent * )
+{
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget resize events. When resizeEvent() is called, the widget
+ already has its new tqgeometry. The old size is accessible through
+ TQResizeEvent::oldSize().
+
+ The widget will be erased and receive a paint event immediately
+ after processing the resize event. No drawing need be (or should
+ be) done inside this handler.
+
+ Widgets that have been created with the \c WNoAutoErase flag
+ will not be erased. Nevertheless, they will receive a paint event
+ for their entire area afterwards. Again, no drawing needs to be
+ done inside this handler.
+
+ The default implementation calls updateMask() if the widget has
+ \link TQLayout::setAutoMask() automatic masking\endlink enabled.
+
+ \sa moveEvent(), event(), resize(), TQResizeEvent, paintEvent()
+*/
+
+void TQLayout::resizeEvent( TQResizeEvent * )
+{
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive widget close events.
+
+ The default implementation calls e->accept(), which hides this
+ widget. See the \l TQCloseEvent documentation for more details.
+
+ \sa event(), hide(), close(), TQCloseEvent
+*/
+
+void TQLayout::closeEvent( TQCloseEvent *e )
+{
+ e->accept();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive widget context menu events.
+
+ The default implementation calls e->ignore(), which rejects the
+ context event. See the \l TQContextMenuEvent documentation for
+ more details.
+
+ \sa event(), TQContextMenuEvent
+*/
+
+void TQLayout::contextMenuEvent( TQContextMenuEvent *e )
+{
+ e->ignore();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user begins entering text using an Input Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQLayout::imStartEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user has entered some text using an Input Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQLayout::imComposeEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user has finished inputting text via an Input
+ Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQLayout::imEndEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse enters this widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragEnterEvent
+*/
+void TQLayout::dragEnterEvent( TQDragEnterEvent * )
+{
+}
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse enters this widget, and whenever it moves within the widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragMoveEvent
+*/
+void TQLayout::dragMoveEvent( TQDragMoveEvent * )
+{
+}
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse leaves this widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragLeaveEvent
+*/
+void TQLayout::dragLeaveEvent( TQDragLeaveEvent * )
+{
+}
+
+/*!
+ This event handler is called when the drag is dropped on this
+ widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDropEvent
+*/
+void TQLayout::dropEvent( TQDropEvent * )
+{
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget show events.
+
+ Non-spontaneous show events are sent to widgets immediately before
+ they are shown. The spontaneous show events of top-level widgets
+ are delivered afterwards.
+
+ \sa event(), TQShowEvent
+*/
+void TQLayout::showEvent( TQShowEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget hide events.
+
+ Hide events are sent to widgets immediately after they have been
+ hidden.
+
+ \sa event(), TQHideEvent
+*/
+void TQLayout::hideEvent( TQHideEvent * )
+{
+}
+
+#endif
+
+void TQLayout::timerEvent( TQTimerEvent * )
+{
+}
+
+void TQLayout::childEvent( TQChildEvent * )
+{
+}
+
+void TQLayout::customEvent( TQCustomEvent * )
+{
+}
+
+#if 0
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse move events for the widget.
+
+ If mouse tracking is switched off, mouse move events only occur if
+ a mouse button is pressed while the mouse is being moved. If mouse
+ tracking is switched on, mouse move events occur even if no mouse
+ button is pressed.
+
+ TQMouseEvent::pos() reports the position of the mouse cursor,
+ relative to this widget. For press and release events, the
+ position is usually the same as the position of the last mouse
+ move event, but it might be different if the user's hand shakes.
+ This is a feature of the underlying window system, not TQt.
+
+ \sa setMouseTracking(), mousePressEvent(), mouseReleaseEvent(),
+ mouseDoubleClickEvent(), event(), TQMouseEvent
+*/
+
+void TQGridLayout::mouseMoveEvent( TQMouseEvent * e)
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse press events for the widget.
+
+ If you create new widgets in the mousePressEvent() the
+ mouseReleaseEvent() may not end up where you expect, depending on
+ the underlying window system (or X11 window manager), the widgets'
+ location and maybe more.
+
+ The default implementation implements the closing of popup widgets
+ when you click outside the window. For other widget types it does
+ nothing.
+
+ \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
+ mouseMoveEvent(), event(), TQMouseEvent
+*/
+
+void TQGridLayout::mousePressEvent( TQMouseEvent * )
+{
+// TQT_TQLAYOUT_CONST(this)->mousePressEvent(e);
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse release events for the widget.
+
+ \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
+ mouseMoveEvent(), event(), TQMouseEvent
+*/
+
+void TQGridLayout::mouseReleaseEvent( TQMouseEvent * e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse double click events for the widget.
+
+ The default implementation generates a normal mouse press event.
+
+ Note that the widgets gets a mousePressEvent() and a
+ mouseReleaseEvent() before the mouseDoubleClickEvent().
+
+ \sa mousePressEvent(), mouseReleaseEvent() mouseMoveEvent(),
+ event(), TQMouseEvent
+*/
+
+void TQGridLayout::mouseDoubleClickEvent( TQMouseEvent *e )
+{
+ mousePressEvent( e ); // try mouse press event
+}
+
+#ifndef TQT_NO_WHEELEVENT
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive wheel events for the widget.
+
+ If you reimplement this handler, it is very important that you
+ \link TQWheelEvent ignore()\endlink the event if you do not handle
+ it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa TQWheelEvent::ignore(), TQWheelEvent::accept(), event(),
+ TQWheelEvent
+*/
+
+void TQGridLayout::wheelEvent( TQWheelEvent *e )
+{
+ e->ignore();
+}
+#endif
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive tablet events for the widget.
+
+ If you reimplement this handler, it is very important that you
+ \link TQTabletEvent ignore()\endlink the event if you do not handle
+ it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa TQTabletEvent::ignore(), TQTabletEvent::accept(), event(),
+ TQTabletEvent
+*/
+
+void TQGridLayout::tabletEvent( TQTabletEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive key press events for the widget.
+
+ A widget must call setFocusPolicy() to accept focus initially and
+ have focus in order to receive a key press event.
+
+ If you reimplement this handler, it is very important that you
+ explicitly \link TQKeyEvent::ignore() ignore\endlink the event
+ if you do not understand it, so that the widget's tqparent can
+ interpret it; otherwise, the event will be implicitly accepted.
+ Although top-level widgets are able to choose whether to accept
+ or ignore unknown events because they have no tqparent widgets that
+ could otherwise handle them, it is good practice to explicitly
+ ignore events to make widgets as reusable as possible.
+
+ The default implementation closes popup widgets if the user
+ presses <b>Esc</b>. Otherwise the event is ignored.
+
+ \sa keyReleaseEvent(), TQKeyEvent::ignore(), setFocusPolicy(),
+ focusInEvent(), focusOutEvent(), event(), TQKeyEvent
+*/
+
+void TQGridLayout::keyPressEvent( TQKeyEvent * )
+{
+// TQT_TQLAYOUT_CONST(this)->keyPressEvent(e);
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive key release events for the widget.
+
+ A widget must \link setFocusPolicy() accept focus\endlink
+ initially and \link hasFocus() have focus\endlink in order to
+ receive a key release event.
+
+ If you reimplement this handler, it is very important that you
+ \link TQKeyEvent ignore()\endlink the release if you do not
+ understand it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa keyPressEvent(), TQKeyEvent::ignore(), setFocusPolicy(),
+ focusInEvent(), focusOutEvent(), event(), TQKeyEvent
+*/
+
+void TQGridLayout::keyReleaseEvent( TQKeyEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ keyboard focus events (focus received) for the widget.
+
+ A widget normally must setFocusPolicy() to something other than
+ \c NoFocus in order to receive focus events. (Note that the
+ application programmer can call setFocus() on any widget, even
+ those that do not normally accept focus.)
+
+ The default implementation updates the widget (except for toplevel
+ widgets that do not specify a focusPolicy() ). It also calls
+ setMicroFocusHint(), hinting any system-specific input tools about
+ the focus of the user's attention.
+
+ \sa focusOutEvent(), setFocusPolicy(), keyPressEvent(),
+ keyReleaseEvent(), event(), TQFocusEvent
+*/
+
+void TQGridLayout::focusInEvent( TQFocusEvent * )
+{
+// TQT_TQLAYOUT_CONST(this)->focusInEvent(e);
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ keyboard focus events (focus lost) for the widget.
+
+ A widget normally must setFocusPolicy() to something other than
+ \c NoFocus in order to receive focus events. (Note that the
+ application programmer can call setFocus() on any widget, even
+ those that do not normally accept focus.)
+
+ The default implementation updates the widget (except for toplevel
+ widgets that do not specify a focusPolicy() ). It also calls
+ setMicroFocusHint(), hinting any system-specific input tools about
+ the focus of the user's attention.
+
+ \sa focusInEvent(), setFocusPolicy(), keyPressEvent(),
+ keyReleaseEvent(), event(), TQFocusEvent
+*/
+
+void TQGridLayout::focusOutEvent( TQFocusEvent * )
+{
+// TQT_TQLAYOUT_CONST(this)->focusOutEvent(e);
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget enter events.
+
+ An event is sent to the widget when the mouse cursor enters the
+ widget.
+
+ \sa leaveEvent(), mouseMoveEvent(), event()
+*/
+
+void TQGridLayout::enterEvent( TQEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget leave events.
+
+ A leave event is sent to the widget when the mouse cursor leaves
+ the widget.
+
+ \sa enterEvent(), mouseMoveEvent(), event()
+*/
+
+void TQGridLayout::leaveEvent( TQEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ paint events.
+
+ A paint event is a request to tqrepaint all or part of the widget.
+ It can happen as a result of tqrepaint() or update(), or because the
+ widget was obscured and has now been uncovered, or for many other
+ reasons.
+
+ Many widgets can simply tqrepaint their entire surface when asked
+ to, but some slow widgets need to optimize by painting only the
+ requested region: TQPaintEvent::region(). This speed optimization
+ does not change the result, as painting is clipped to that region
+ during event processing. TQListView and TQCanvas do this, for
+ example.
+
+ TQt also tries to speed up painting by merging multiple paint
+ events into one. When update() is called several times or the
+ window system sends several paint events, TQt merges these events
+ into one event with a larger region (see TQRegion::unite()).
+ tqrepaint() does not permit this optimization, so we suggest using
+ update() when possible.
+
+ When the paint event occurs, the update region has normally been
+ erased, so that you're painting on the widget's background. There
+ are a couple of exceptions and TQPaintEvent::erased() tells you
+ whether the widget has been erased or not.
+
+ The background can be set using setBackgroundMode(),
+ setPaletteBackgroundColor() or setBackgroundPixmap(). The
+ documentation for setBackgroundMode() elaborates on the
+ background; we recommend reading it.
+
+ \sa event(), tqrepaint(), update(), TQPainter, TQPixmap, TQPaintEvent
+*/
+
+void TQGridLayout::paintEvent( TQPaintEvent *e )
+{
+// // At least let Qt4 get a shot at painting it
+// QWidget::paintEvent(e);
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget move events. When the widget receives this event, it is
+ already at the new position.
+
+ The old position is accessible through TQMoveEvent::oldPos().
+
+ \sa resizeEvent(), event(), move(), TQMoveEvent
+*/
+
+void TQGridLayout::moveEvent( TQMoveEvent * )
+{
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget resize events. When resizeEvent() is called, the widget
+ already has its new tqgeometry. The old size is accessible through
+ TQResizeEvent::oldSize().
+
+ The widget will be erased and receive a paint event immediately
+ after processing the resize event. No drawing need be (or should
+ be) done inside this handler.
+
+ Widgets that have been created with the \c WNoAutoErase flag
+ will not be erased. Nevertheless, they will receive a paint event
+ for their entire area afterwards. Again, no drawing needs to be
+ done inside this handler.
+
+ The default implementation calls updateMask() if the widget has
+ \link TQGridLayout::setAutoMask() automatic masking\endlink enabled.
+
+ \sa moveEvent(), event(), resize(), TQResizeEvent, paintEvent()
+*/
+
+void TQGridLayout::resizeEvent( TQResizeEvent * )
+{
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive widget close events.
+
+ The default implementation calls e->accept(), which hides this
+ widget. See the \l TQCloseEvent documentation for more details.
+
+ \sa event(), hide(), close(), TQCloseEvent
+*/
+
+void TQGridLayout::closeEvent( TQCloseEvent *e )
+{
+ e->accept();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive widget context menu events.
+
+ The default implementation calls e->ignore(), which rejects the
+ context event. See the \l TQContextMenuEvent documentation for
+ more details.
+
+ \sa event(), TQContextMenuEvent
+*/
+
+void TQGridLayout::contextMenuEvent( TQContextMenuEvent *e )
+{
+ e->ignore();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user begins entering text using an Input Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQGridLayout::imStartEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user has entered some text using an Input Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQGridLayout::imComposeEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user has finished inputting text via an Input
+ Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQGridLayout::imEndEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse enters this widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragEnterEvent
+*/
+void TQGridLayout::dragEnterEvent( TQDragEnterEvent * )
+{
+}
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse enters this widget, and whenever it moves within the widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragMoveEvent
+*/
+void TQGridLayout::dragMoveEvent( TQDragMoveEvent * )
+{
+}
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse leaves this widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragLeaveEvent
+*/
+void TQGridLayout::dragLeaveEvent( TQDragLeaveEvent * )
+{
+}
+
+/*!
+ This event handler is called when the drag is dropped on this
+ widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDropEvent
+*/
+void TQGridLayout::dropEvent( TQDropEvent * )
+{
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget show events.
+
+ Non-spontaneous show events are sent to widgets immediately before
+ they are shown. The spontaneous show events of top-level widgets
+ are delivered afterwards.
+
+ \sa event(), TQShowEvent
+*/
+void TQGridLayout::showEvent( TQShowEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget hide events.
+
+ Hide events are sent to widgets immediately after they have been
+ hidden.
+
+ \sa event(), TQHideEvent
+*/
+void TQGridLayout::hideEvent( TQHideEvent * )
+{
+}
+
+void TQGridLayout::timerEvent( TQTimerEvent * )
+{
+}
+
+void TQGridLayout::childEvent( TQChildEvent * )
+{
+}
+
+void TQGridLayout::customEvent( TQCustomEvent * )
+{
+}
+
+#endif
+
+TQMetaObject *TQLayout::tqmetaObject() const {
+ return TQT_TQOBJECT_CONST(this)->tqmetaObject();
+}
+
+#else // USE_QT4
+
+#endif // USE_QT4
+
+/*
+ Three internal classes related to TQGridLayout: (1) TQGridBox is a
+ TQLayoutItem with (row, column) information; (2) TQGridMultiBox is a
+ TQGridBox with (torow, tocolumn) information; (3) TQGridLayoutData is
+ the internal representation of a TQGridLayout.
+*/
+
+class TQGridBox
+{
+public:
+ TQGridBox( TQLayoutItem *lit ) { item_ = lit; }
+
+ TQGridBox( TQWidget *wid ) { item_ = new TQWidgetItem( wid ); }
+ TQGridBox( int w, int h, TQSizePolicy::SizeType hData = TQSizePolicy::Minimum,
+ TQSizePolicy::SizeType vData = TQSizePolicy::Minimum )
+ { item_ = TQT_TQLAYOUTITEM(new TQSpacerItem( w, h, hData, vData )); }
+ ~TQGridBox() { delete item_; }
+
+ QSize tqsizeHint() const { return item_->sizeHint(); }
+ QSize tqminimumSize() const { return item_->minimumSize(); }
+ QSize tqmaximumSize() const { return item_->maximumSize(); }
+ TQ_SPExpandData expandingDirections() const { return item_->expandingDirections(); }
+ bool isEmpty() const { return item_->isEmpty(); }
+
+ bool hasHeightForWidth() const { return item_->hasHeightForWidth(); }
+ int heightForWidth( int w ) const { return item_->heightForWidth(w); }
+
+ void tqsetAlignment( int a ) { item_->tqsetAlignment( a ); }
+ void setGeometry( const TQRect &r ) { item_->setGeometry( r ); }
+ int tqalignment() const { return item_->tqalignment(); }
+ TQLayoutItem *item() { return item_; }
+ TQLayoutItem *takeItem() { TQLayoutItem *i = item_; item_ = 0; return i; }
+
+ int hStretch() { return item_->widget() ?
+ TQT_TQSIZEPOLICY_OBJECT(item_->widget()->sizePolicy()).horStretch() : 0; }
+ int vStretch() { return item_->widget() ?
+ TQT_TQSIZEPOLICY_OBJECT(item_->widget()->sizePolicy()).verStretch() : 0; }
+
+private:
+ friend class TQGridLayoutData;
+ friend class TQGridLayoutDataIterator;
+
+ TQLayoutItem *item_;
+ int row, col;
+};
+
+class TQGridMultiBox
+{
+public:
+ TQGridMultiBox( TQGridBox *box, int toRow, int toCol )
+ : box_( box ), torow( toRow ), tocol( toCol ) { }
+ ~TQGridMultiBox() { delete box_; }
+ TQGridBox *box() { return box_; }
+ TQLayoutItem *takeItem() { return box_->takeItem(); }
+
+private:
+ friend class TQGridLayoutData;
+ friend class TQGridLayoutDataIterator;
+
+ TQGridBox *box_;
+ int torow, tocol;
+};
+
+class TQGridLayoutData
+{
+public:
+ TQGridLayoutData();
+ TQGridLayoutData( int nRows, int nCols );
+ ~TQGridLayoutData();
+
+ void add( TQGridBox*, int row, int col );
+ void add( TQGridBox*, int row1, int row2, int col1, int col2 );
+ QSize tqsizeHint( int ) const;
+ QSize tqminimumSize( int ) const;
+ QSize tqmaximumSize( int ) const;
+
+ TQ_SPExpandData expanding( int spacing );
+
+ void distribute( TQRect, int );
+ inline int numRows() const { return rr; }
+ inline int numCols() const { return cc; }
+ inline void expand( int rows, int cols )
+ { setSize( TQMAX(rows, rr), TQMAX(cols, cc) ); }
+ inline void setRowStretch( int r, int s )
+ { expand( r + 1, 0 ); rStretch[r] = s; setDirty(); }
+ inline void setColStretch( int c, int s )
+ { expand( 0, c + 1 ); cStretch[c] = s; setDirty(); }
+ inline int rowStretch( int r ) const { return rStretch[r]; }
+ inline int colStretch( int c ) const { return cStretch[c]; }
+ inline void setRowSpacing( int r, int s )
+ { expand( r + 1, 0 ); rSpacing[r] = s; setDirty(); }
+ inline void setColSpacing( int c, int s )
+ { expand( 0, c + 1 ); cSpacing[c] = s; setDirty(); }
+ inline int rowSpacing( int r ) const { return rSpacing[r]; }
+ inline int colSpacing( int c ) const { return cSpacing[c]; }
+
+ inline void setReversed( bool r, bool c ) { hReversed = c; vReversed = r; }
+ inline bool horReversed() const { return hReversed; }
+ inline bool verReversed() const { return vReversed; }
+ inline void setDirty() { needRecalc = TRUE; hfw_width = -1; }
+ inline bool isDirty() const { return needRecalc; }
+ bool hasHeightForWidth( int space );
+ int heightForWidth( int, int, int );
+ int minimumHeightForWidth( int, int, int );
+
+ bool tqfindWidget( TQWidget* w, int *row, int *col );
+
+ inline void getNextPos( int &row, int &col ) { row = nextR; col = nextC; }
+ inline uint count() const
+ { return things.count() + ( multi ? multi->count() : 0 ); }
+ TQRect cellGeometry( int row, int col ) const;
+
+private:
+ void setNextPosAfter( int r, int c );
+ void recalcHFW( int w, int s );
+ void addHfwData ( TQGridBox *box, int width );
+ void init();
+ TQSize tqfindSize( TQCOORD TQLayoutStruct::*, int ) const;
+ void addData( TQGridBox *b, bool r = TRUE, bool c = TRUE );
+ void setSize( int rows, int cols );
+ void setupLayoutData( int space );
+ void setupHfwLayoutData( int space );
+
+ int rr;
+ int cc;
+ TQMemArray<TQLayoutStruct> rowData;
+ TQMemArray<TQLayoutStruct> colData;
+ TQMemArray<TQLayoutStruct> *hfwData;
+ TQMemArray<int> rStretch;
+ TQMemArray<int> cStretch;
+ TQMemArray<int> rSpacing;
+ TQMemArray<int> cSpacing;
+ TQPtrList<TQGridBox> things;
+ TQPtrList<TQGridMultiBox> *multi;
+
+ int hfw_width;
+ int hfw_height;
+ int hfw_minheight;
+ int nextR;
+ int nextC;
+
+ uint hReversed : 1;
+ uint vReversed : 1;
+ uint needRecalc : 1;
+ uint has_hfw : 1;
+ uint addVertical : 1;
+
+ friend class TQGridLayoutDataIterator;
+};
+
+TQGridLayoutData::TQGridLayoutData()
+{
+ init();
+}
+
+TQGridLayoutData::TQGridLayoutData( int nRows, int nCols )
+ : rowData( 0 ), colData( 0 )
+{
+ init();
+ if ( nRows < 0 ) {
+ nRows = 1;
+ addVertical = FALSE;
+ }
+ if ( nCols < 0 ) {
+ nCols = 1;
+ addVertical = TRUE;
+ }
+ setSize( nRows, nCols );
+}
+
+TQGridLayoutData::~TQGridLayoutData()
+{
+ // must be cleared while the data is still in a stable state
+ things.clear();
+
+ delete multi;
+ delete hfwData;
+}
+
+void TQGridLayoutData::init()
+{
+ addVertical = FALSE;
+ setDirty();
+ multi = 0;
+ rr = cc = 0;
+ nextR = nextC = 0;
+ hfwData = 0;
+ things.setAutoDelete( TRUE );
+ hReversed = FALSE;
+ vReversed = FALSE;
+}
+
+bool TQGridLayoutData::hasHeightForWidth( int spacing )
+{
+ setupLayoutData( spacing );
+ return has_hfw;
+}
+
+/*
+ Assumes that setupLayoutData() has been called, and that
+ qGeomCalc() has filled in colData with appropriate values.
+*/
+void TQGridLayoutData::recalcHFW( int w, int spacing )
+{
+ /*
+ Go through all tqchildren, using colData and heightForWidth()
+ and put the results in hfw_rowData.
+ */
+ if ( !hfwData )
+ hfwData = new TQMemArray<TQLayoutStruct>( rr );
+ setupHfwLayoutData( spacing );
+ TQMemArray<TQLayoutStruct> &rData = *hfwData;
+
+ int h = 0;
+ int mh = 0;
+ int n = 0;
+ for ( int r = 0; r < rr; r++ ) {
+ h += rData[r].tqsizeHint;
+ mh += rData[r].tqminimumSize;
+ if ( !rData[r].empty )
+ n++;
+ }
+ if ( n ) {
+ h += ( n - 1 ) * spacing;
+ mh += ( n - 1 ) * spacing;
+ }
+
+ hfw_width = w;
+ hfw_height = TQMIN( TQLAYOUTSIZE_MAX, h );
+ hfw_minheight = TQMIN( TQLAYOUTSIZE_MAX, mh );
+}
+
+int TQGridLayoutData::heightForWidth( int w, int margin, int spacing )
+{
+ setupLayoutData( spacing );
+ if ( !has_hfw )
+ return -1;
+ if ( w + 2*margin != hfw_width ) {
+ qGeomCalc( colData, 0, cc, 0, w+2*margin, spacing );
+ recalcHFW( w+2*margin, spacing );
+ }
+ return hfw_height + 2*margin;
+}
+
+int TQGridLayoutData::minimumHeightForWidth( int w, int margin, int spacing )
+{
+ (void) heightForWidth( w, margin, spacing );
+ return has_hfw ? (hfw_minheight + 2*margin) : -1;
+}
+
+bool TQGridLayoutData::tqfindWidget( TQWidget* w, int *row, int *col )
+{
+ TQPtrListIterator<TQGridBox> it( things );
+ TQGridBox * box;
+ while ( (box = it.current()) != 0 ) {
+ ++it;
+ if ( box->item()->widget() == w ) {
+ if ( row )
+ *row = box->row;
+ if ( col )
+ *col = box->col;
+ return TRUE;
+ }
+ }
+ if ( multi ) {
+ TQPtrListIterator<TQGridMultiBox> it( *multi );
+ TQGridMultiBox * mbox;
+ while ( (mbox = it.current()) != 0 ) {
+ ++it;
+ box = mbox->box();
+ if ( box->item()->widget() == w ) {
+ if ( row )
+ *row = box->row;
+ if ( col )
+ *col = box->col;
+ return TRUE;
+ }
+
+ }
+ }
+ return FALSE;
+}
+
+TQSize TQGridLayoutData::tqfindSize( TQCOORD TQLayoutStruct::*size, int spacer ) const
+{
+ TQGridLayoutData *that = (TQGridLayoutData *)this;
+ that->setupLayoutData( spacer );
+
+ int w = 0;
+ int h = 0;
+ int n = 0;
+ for ( int r = 0; r < rr; r++ ) {
+ h = h + rowData[r].*size;
+ if ( !rowData[r].empty )
+ n++;
+ }
+ if ( n )
+ h += ( n - 1 ) * spacer;
+ n = 0;
+ for ( int c = 0; c < cc; c++ ) {
+ w = w + colData[c].*size;
+ if ( !colData[c].empty )
+ n++;
+ }
+ if ( n )
+ w += ( n - 1 ) * spacer;
+ w = TQMIN( TQLAYOUTSIZE_MAX, w );
+ h = TQMIN( TQLAYOUTSIZE_MAX, h );
+
+ return TQSize( w, h );
+}
+
+TQ_SPExpandData TQGridLayoutData::expanding( int spacing )
+{
+ setupLayoutData( spacing );
+ int ret = 0;
+
+ for ( int r = 0; r < rr; r++ ) {
+ if ( rowData[r].expansive ) {
+ ret |= (int) TQSizePolicy::Vertically;
+ break;
+ }
+ }
+ for ( int c = 0; c < cc; c++ ) {
+ if ( colData[c].expansive ) {
+ ret |= (int) TQSizePolicy::Horizontally;
+ break;
+ }
+ }
+ return (TQ_SPExpandData) ret;
+}
+
+QSize TQGridLayoutData::tqsizeHint( int spacer ) const
+{
+ return tqfindSize( &TQLayoutStruct::tqsizeHint, spacer );
+}
+
+QSize TQGridLayoutData::tqmaximumSize( int spacer ) const
+{
+ return tqfindSize( &TQLayoutStruct::tqmaximumSize, spacer );
+}
+
+QSize TQGridLayoutData::tqminimumSize( int spacer ) const
+{
+ return tqfindSize( &TQLayoutStruct::tqminimumSize, spacer );
+}
+
+void TQGridLayoutData::setSize( int r, int c )
+{
+ if ( (int)rowData.size() < r ) {
+ int newR = TQMAX( r, rr * 2 );
+ rowData.resize( newR );
+ rStretch.resize( newR );
+ rSpacing.resize( newR );
+ for ( int i = rr; i < newR; i++ ) {
+ rowData[i].init();
+ rStretch[i] = 0;
+ rSpacing[i] = 0;
+ }
+ }
+ if ( (int)colData.size() < c ) {
+ int newC = TQMAX( c, cc * 2 );
+ colData.resize( newC );
+ cStretch.resize( newC );
+ cSpacing.resize( newC );
+ for ( int i = cc; i < newC; i++ ) {
+ colData[i].init();
+ cStretch[i] = 0;
+ cSpacing[i] = 0;
+ }
+ }
+
+ if ( hfwData && (int)hfwData->size() < r ) {
+ delete hfwData;
+ hfwData = 0;
+ hfw_width = -1;
+ }
+ rr = r;
+ cc = c;
+}
+
+void TQGridLayoutData::setNextPosAfter( int row, int col )
+{
+ if ( addVertical ) {
+ if ( col > nextC || (col == nextC && row >= nextR) ) {
+ nextR = row + 1;
+ nextC = col;
+ if ( nextR >= rr ) {
+ nextR = 0;
+ nextC++;
+ }
+ }
+ } else {
+ if ( row > nextR || (row == nextR && col >= nextC) ) {
+ nextR = row;
+ nextC = col + 1;
+ if ( nextC >= cc ) {
+ nextC = 0;
+ nextR++;
+ }
+ }
+ }
+}
+
+void TQGridLayoutData::add( TQGridBox *box, int row, int col )
+{
+ expand( row+1, col+1 );
+ box->row = row;
+ box->col = col;
+ things.append( box );
+ setDirty();
+ setNextPosAfter( row, col );
+}
+
+void TQGridLayoutData::add( TQGridBox *box, int row1, int row2, int col1,
+ int col2 )
+{
+#ifdef TQT_CHECK_RANGE
+ if ( row2 >= 0 && row2 < row1 )
+ qWarning( "TQGridLayout: Multi-cell fromRow greater than toRow" );
+ if ( col2 >= 0 && col2 < col1 )
+ qWarning( "TQGridLayout: Multi-cell fromCol greater than toCol" );
+#endif
+ if ( row1 == row2 && col1 == col2 ) {
+ add( box, row1, col1 );
+ return;
+ }
+ expand( row2+1, col2+1 );
+ box->row = row1;
+ box->col = col1;
+ TQGridMultiBox *mbox = new TQGridMultiBox( box, row2, col2 );
+ if ( !multi ) {
+ multi = new TQPtrList<TQGridMultiBox>;
+ multi->setAutoDelete( TRUE );
+ }
+ multi->append( mbox );
+ setDirty();
+ if ( col2 < 0 )
+ col2 = cc - 1;
+
+ setNextPosAfter( row2, col2 );
+}
+
+void TQGridLayoutData::addData( TQGridBox *box, bool r, bool c )
+{
+ TQSize hint = box->tqsizeHint();
+ TQSize minS = box->tqminimumSize();
+ TQSize maxS = box->tqmaximumSize();
+
+ if ( c ) {
+ if ( !cStretch[box->col] )
+ colData[box->col].stretch = TQMAX( colData[box->col].stretch,
+ box->hStretch() );
+ colData[box->col].tqsizeHint = TQMAX( hint.width(),
+ colData[box->col].tqsizeHint );
+ colData[box->col].tqminimumSize = TQMAX( minS.width(),
+ colData[box->col].tqminimumSize );
+
+ qMaxExpCalc( colData[box->col].tqmaximumSize, colData[box->col].expansive,
+ maxS.width(),
+ box->expandingDirections() & TQSizePolicy::Horizontally );
+ }
+ if ( r ) {
+ if ( !rStretch[box->row] )
+ rowData[box->row].stretch = TQMAX( rowData[box->row].stretch,
+ box->vStretch() );
+ rowData[box->row].tqsizeHint = TQMAX( hint.height(),
+ rowData[box->row].tqsizeHint );
+ rowData[box->row].tqminimumSize = TQMAX( minS.height(),
+ rowData[box->row].tqminimumSize );
+
+ qMaxExpCalc( rowData[box->row].tqmaximumSize, rowData[box->row].expansive,
+ maxS.height(),
+ box->expandingDirections() & TQSizePolicy::Vertically );
+ }
+ if ( box->isEmpty() ) {
+ if ( box->item()->widget() != 0 ) {
+ /*
+ Hidden widgets should behave exactly the same as if
+ there were no widgets at all in the cell. We could have
+ TQWidgetItem::tqmaximumSize() to return
+ TQSize(TQLAYOUTSIZE_MAX, TQLAYOUTSIZE_MAX). However, that
+ value is not suitable for TQBoxLayouts. So let's fix it
+ here.
+ */
+ if ( c )
+ colData[box->col].tqmaximumSize = TQLAYOUTSIZE_MAX;
+ if ( r )
+ rowData[box->row].tqmaximumSize = TQLAYOUTSIZE_MAX;
+ }
+ } else {
+ // Empty boxes (i.e. spacers) do not get borders. This is
+ // hacky, but compatible.
+ if ( c )
+ colData[box->col].empty = FALSE;
+ if ( r )
+ rowData[box->row].empty = FALSE;
+ }
+}
+
+static void distributeMultiBox( TQMemArray<TQLayoutStruct> &chain, int spacing,
+ int start, int end,
+ int minSize, int tqsizeHint,
+ TQMemArray<int> &stretchArray, int stretch )
+{
+ int i;
+ int w = 0;
+ int wh = 0;
+ int max = 0;
+ for ( i = start; i <= end; i++ ) {
+ w += chain[i].tqminimumSize;
+ wh += chain[i].tqsizeHint;
+ max += chain[i].tqmaximumSize;
+ chain[i].empty = FALSE;
+ if ( stretchArray[i] == 0 )
+ chain[i].stretch = TQMAX(chain[i].stretch,stretch);
+ }
+ w += spacing * ( end - start );
+ wh += spacing * ( end - start );
+ max += spacing * ( end - start );
+
+ if ( max < minSize ) { // implies w < minSize
+ /*
+ We must increase the maximum size of at least one of the
+ items. qGeomCalc() will put the extra space in between the
+ items. We must recover that extra space and put it
+ somewhere. It does not really matter where, since the user
+ can always specify stretch factors and avoid this code.
+ */
+ qGeomCalc( chain, start, end - start + 1, 0, minSize, spacing );
+ int pos = 0;
+ for ( i = start; i <= end; i++ ) {
+ int nextPos = ( i == end ) ? minSize - 1 : chain[i + 1].pos;
+ int realSize = nextPos - pos;
+ if ( i != end )
+ realSize -= spacing;
+ if ( chain[i].tqminimumSize < realSize )
+ chain[i].tqminimumSize = realSize;
+ if ( chain[i].tqmaximumSize < chain[i].tqminimumSize )
+ chain[i].tqmaximumSize = chain[i].tqminimumSize;
+ pos = nextPos;
+ }
+ } else if ( w < minSize ) {
+ qGeomCalc( chain, start, end - start + 1, 0, minSize, spacing );
+ for ( i = start; i <= end; i++ ) {
+ if ( chain[i].tqminimumSize < chain[i].size )
+ chain[i].tqminimumSize = chain[i].size;
+ }
+ }
+
+ if ( wh < tqsizeHint ) {
+ qGeomCalc( chain, start, end - start + 1, 0, tqsizeHint, spacing );
+ for ( i = start; i <= end; i++ ) {
+ if ( chain[i].tqsizeHint < chain[i].size )
+ chain[i].tqsizeHint = chain[i].size;
+ }
+ }
+}
+
+//#define TQT_LAYOUT_DISABLE_CACHING
+
+void TQGridLayoutData::setupLayoutData( int spacing )
+{
+#ifndef TQT_LAYOUT_DISABLE_CACHING
+ if ( !needRecalc )
+ return;
+#endif
+ has_hfw = FALSE;
+ int i;
+
+ for ( i = 0; i < rr; i++ )
+ rowData[i].init( rStretch[i], rSpacing[i] );
+ for ( i = 0; i < cc; i++ )
+ colData[i].init( cStretch[i], cSpacing[i] );
+
+ TQPtrListIterator<TQGridBox> it( things );
+ TQGridBox * box;
+ while ( (box = it.current()) != 0 ) {
+ ++it;
+ addData( box );
+ has_hfw = has_hfw || box->item()->hasHeightForWidth();
+ }
+
+ if ( multi ) {
+ TQPtrListIterator<TQGridMultiBox> it( *multi );
+ TQGridMultiBox * mbox;
+ while ( (mbox = it.current()) != 0 ) {
+ ++it;
+ TQGridBox *box = mbox->box();
+ int r1 = box->row;
+ int c1 = box->col;
+ int r2 = mbox->torow;
+ int c2 = mbox->tocol;
+ if ( r2 < 0 )
+ r2 = rr - 1;
+ if ( c2 < 0 )
+ c2 = cc - 1;
+
+ TQSize hint = box->tqsizeHint();
+ TQSize min = box->tqminimumSize();
+ if ( box->hasHeightForWidth() )
+ has_hfw = TRUE;
+
+ if ( r1 == r2 ) {
+ addData( box, TRUE, FALSE );
+ } else {
+ distributeMultiBox( rowData, spacing, r1, r2,
+ min.height(), hint.height(),
+ rStretch, box->vStretch() );
+ }
+ if ( c1 == c2 ) {
+ addData( box, FALSE, TRUE );
+ } else {
+ distributeMultiBox( colData, spacing, c1, c2,
+ min.width(), hint.width(),
+ cStretch, box->hStretch() );
+ }
+ }
+ }
+ for ( i = 0; i < rr; i++ )
+ rowData[i].expansive = rowData[i].expansive || rowData[i].stretch > 0;
+ for ( i = 0; i < cc; i++ )
+ colData[i].expansive = colData[i].expansive || colData[i].stretch > 0;
+
+ needRecalc = FALSE;
+}
+
+void TQGridLayoutData::addHfwData( TQGridBox *box, int width )
+{
+ TQMemArray<TQLayoutStruct> &rData = *hfwData;
+ if ( box->hasHeightForWidth() ) {
+ int hint = box->heightForWidth( width );
+ rData[box->row].tqsizeHint = TQMAX( hint, rData[box->row].tqsizeHint );
+ rData[box->row].tqminimumSize = TQMAX( hint, rData[box->row].tqminimumSize );
+ } else {
+ TQSize hint = box->tqsizeHint();
+ TQSize minS = box->tqminimumSize();
+ rData[box->row].tqsizeHint = TQMAX( hint.height(),
+ rData[box->row].tqsizeHint );
+ rData[box->row].tqminimumSize = TQMAX( minS.height(),
+ rData[box->row].tqminimumSize );
+ }
+}
+
+/*
+ Similar to setupLayoutData(), but uses heightForWidth(colData)
+ instead of tqsizeHint(). Assumes that setupLayoutData() and
+ qGeomCalc(colData) has been called.
+*/
+void TQGridLayoutData::setupHfwLayoutData( int spacing )
+{
+ TQMemArray<TQLayoutStruct> &rData = *hfwData;
+ int i;
+ for ( i = 0; i < rr; i++ ) {
+ rData[i] = rowData[i];
+ rData[i].tqminimumSize = rData[i].tqsizeHint = 0;
+ }
+ TQPtrListIterator<TQGridBox> it( things );
+ TQGridBox * box;
+ while ( (box=it.current()) != 0 ) {
+ ++it;
+ addHfwData( box, colData[box->col].size );
+ }
+ if ( multi ) {
+ TQPtrListIterator<TQGridMultiBox> it( *multi );
+ TQGridMultiBox * mbox;
+ while ( (mbox=it.current()) != 0 ) {
+ ++it;
+ TQGridBox *box = mbox->box();
+ int r1 = box->row;
+ int c1 = box->col;
+ int r2 = mbox->torow;
+ int c2 = mbox->tocol;
+ if ( r2 < 0 )
+ r2 = rr-1;
+ if ( c2 < 0 )
+ c2 = cc-1;
+ int w = colData[c2].pos + colData[c2].size - colData[c1].pos;
+ if ( r1 == r2 ) {
+ addHfwData( box, w );
+ } else {
+ TQSize hint = box->tqsizeHint();
+ TQSize min = box->tqminimumSize();
+ if ( box->hasHeightForWidth() ) {
+ int hfwh = box->heightForWidth( w );
+ if ( hfwh > hint.height() )
+ hint.setHeight( hfwh );
+ if ( hfwh > min.height() )
+ min.setHeight( hfwh );
+ }
+ distributeMultiBox( rData, spacing, r1, r2,
+ min.height(), hint.height(),
+ rStretch, box->vStretch() );
+ }
+ }
+ }
+ for ( i = 0; i < rr; i++ )
+ rData[i].expansive = rData[i].expansive || rData[i].stretch > 0;
+}
+
+void TQGridLayoutData::distribute( TQRect r, int spacing )
+{
+ bool visualHReversed = hReversed;
+ if ( TQApplication::reverseLayout() )
+ visualHReversed = !visualHReversed;
+
+ setupLayoutData( spacing );
+
+ qGeomCalc( colData, 0, cc, r.x(), r.width(), spacing );
+ TQMemArray<TQLayoutStruct> *rDataPtr;
+ if ( has_hfw ) {
+ recalcHFW( r.width(), spacing );
+ qGeomCalc( *hfwData, 0, rr, r.y(), r.height(), spacing );
+ rDataPtr = hfwData;
+ } else {
+ qGeomCalc( rowData, 0, rr, r.y(), r.height(), spacing );
+ rDataPtr = &rowData;
+ }
+ TQMemArray<TQLayoutStruct> &rData = *rDataPtr;
+
+ TQPtrListIterator<TQGridBox> it( things );
+ TQGridBox * box;
+ while ( (box=it.current()) != 0 ) {
+ ++it;
+ int x = colData[box->col].pos;
+ int y = rData[box->row].pos;
+ int w = colData[box->col].size;
+ int h = rData[box->row].size;
+ if ( visualHReversed )
+ x = r.left() + r.right() - x - w + 1;
+ if ( vReversed )
+ y = r.top() + r.bottom() - y - h + 1;
+ box->setGeometry( TQRect( x, y, w, h ) );
+ }
+ if ( multi ) {
+ TQPtrListIterator<TQGridMultiBox> it( *multi );
+ TQGridMultiBox * mbox;
+ while ( (mbox=it.current()) != 0 ) {
+ ++it;
+ TQGridBox *box = mbox->box();
+ int r2 = mbox->torow;
+ int c2 = mbox->tocol;
+ if ( r2 < 0 )
+ r2 = rr-1;
+ if ( c2 < 0 )
+ c2 = cc-1;
+
+ int x = colData[box->col].pos;
+ int y = rData[box->row].pos;
+ int x2p = colData[c2].pos + colData[c2].size; // x2+1
+ int y2p = rData[r2].pos + rData[r2].size; // y2+1
+ int w = x2p - x;
+ int h = y2p - y;
+ // this code is copied from above:
+ if ( visualHReversed )
+ x = r.left() + r.right() - x - w + 1;
+ if ( vReversed )
+ y = r.top() + r.bottom() - y - h + 1;
+ box->setGeometry( TQRect( x, y, w, h ) );
+ }
+ }
+}
+
+TQRect TQGridLayoutData::cellGeometry( int row, int col ) const
+{
+ if ( row < 0 || row >= rr || col < 0 || col >= cc )
+ return TQRect();
+
+ const TQMemArray<TQLayoutStruct> *rDataPtr;
+ if ( has_hfw )
+ rDataPtr = hfwData;
+ else
+ rDataPtr = &rowData;
+ return TQRect( colData[col].pos, (*rDataPtr)[row].pos,
+ colData[col].size, (*rDataPtr)[row].size );
+}
+
+class TQGridLayoutDataIterator : public TQGLayoutIterator
+{
+public:
+ TQGridLayoutDataIterator( TQGridLayoutData *d );
+ uint count() const { return data->count(); }
+ TQLayoutItem *current() {
+ if ( multi ) {
+ if ( !data->multi || idx >= (int)data->multi->count() )
+ return 0;
+ return data->multi->at( idx )->box()->item();
+ } else {
+ if ( idx >= (int)data->things.count() )
+ return 0;
+ return data->things.at( idx )->item();
+ }
+ }
+ void toFirst() {
+ multi = data->things.isEmpty();
+ idx = 0;
+ }
+ TQLayoutItem *next() {
+ idx++;
+ if ( !multi && idx >= (int)data->things.count() ) {
+ multi = TRUE;
+ idx = 0;
+ }
+ return current();
+ }
+ TQLayoutItem *takeCurrent() {
+ TQLayoutItem *item = 0;
+ if ( multi ) {
+ if ( !data->multi || idx >= (int)data->multi->count() )
+ return 0;
+ TQGridMultiBox *b = data->multi->take( idx );
+ item = b->takeItem();
+ delete b;
+ } else {
+ if ( idx >= (int)data->things.count() )
+ return 0;
+ TQGridBox *b = data->things.take( idx );
+ item = b->takeItem();
+ delete b;
+ }
+ return item;
+ }
+
+private:
+ TQGridLayoutData *data;
+ bool multi;
+ int idx;
+};
+
+inline TQGridLayoutDataIterator::TQGridLayoutDataIterator( TQGridLayoutData *d )
+ : data( d )
+{
+ toFirst();
+}
+
+/*!
+ \class TQGridLayout
+
+ \brief The TQGridLayout class lays out widgets in a grid.
+
+ \ingroup geomanagement
+ \ingroup appearance
+ \mainclass
+
+ TQGridLayout takes the space made available to it (by its tqparent
+ tqlayout or by the mainWidget()), divides it up into rows and
+ columns, and puts each widget it manages into the correct cell.
+
+ Columns and rows behave identically; we will discuss columns, but
+ there are equivalent functions for rows.
+
+ Each column has a minimum width and a stretch factor. The minimum
+ width is the greatest of that set using addColSpacing() and the
+ minimum width of each widget in that column. The stretch factor is
+ set using setColStretch() and determines how much of the available
+ space the column will get over and above its necessary minimum.
+
+ Normally, each managed widget or tqlayout is put into a cell of its
+ own using addWidget(), addLayout() or by the \link
+ TQLayout::setAutoAdd() auto-add facility\endlink. It is also
+ possible for a widget to occupy multiple cells using
+ addMultiCellWidget(). If you do this, TQGridLayout will guess how
+ to distribute the size over the columns/rows (based on the stretch
+ factors).
+
+ To remove a widget from a tqlayout, call remove(). Calling
+ TQWidget::hide() on a widget also effectively removes the widget
+ from the tqlayout until TQWidget::show() is called.
+
+ This illustration shows a fragment of a dialog with a five-column,
+ three-row grid (the grid is shown overlaid in magenta):
+
+ \img gridtqlayout.png
+
+ Columns 0, 2 and 4 in this dialog fragment are made up of a
+ TQLabel, a TQLineEdit, and a TQListBox. Columns 1 and 3 are
+ placeholders made with addColSpacing(). Row 0 consists of three
+ TQLabel objects, row 1 of three TQLineEdit objects and row 2 of
+ three TQListBox objects. We used placeholder columns (1 and 3) to
+ get the right amount of space between the columns.
+
+ Note that the columns and rows are not equally wide or tall. If
+ you want two columns to have the same width, you must set their
+ minimum widths and stretch factors to be the same yourself. You do
+ this using addColSpacing() and setColStretch().
+
+ If the TQGridLayout is not the top-level tqlayout (i.e. does not
+ manage all of the widget's area and tqchildren), you must add it to
+ its tqparent tqlayout when you create it, but before you do anything
+ with it. The normal way to add a tqlayout is by calling
+ parentLayout-\>addLayout().
+
+ Once you have added your tqlayout you can start putting widgets and
+ other layouts into the cells of your grid tqlayout using
+ addWidget(), addLayout() and addMultiCellWidget().
+
+ TQGridLayout also includes two margin widths: the border and the
+ spacing. The border is the width of the reserved space along each
+ of the TQGridLayout's four sides. The spacing is the width of the
+ automatically allocated spacing between neighboring boxes.
+
+ Both the border and the spacing are parameters of the constructor
+ and default to 0.
+
+ \sa TQGrid, \link tqlayout.html Layout Overview \endlink
+*/
+
+/*
+ Returns TRUE if the widget \a w can be added to the tqlayout \a l;
+ otherwise returns FALSE.
+*/
+static bool checkWidget( TQLayout *l, TQWidget *w )
+{
+ if ( !w ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQLayout: Cannot add null widget to %s/%s", l->className(),
+ l->name() );
+#endif
+ return FALSE;
+ }
+ if ( w->parentWidget() != l->mainWidget() && l->mainWidget() ) {
+#if defined(TQT_CHECK_STATE)
+ if ( w->parentWidget() )
+ qWarning( "TQLayout: Adding %s/%s (child of %s/%s) to tqlayout for "
+ "%s/%s", w->className(), w->name(),
+ w->parentWidget()->className(), w->parentWidget()->name(),
+ l->mainWidget()->className(), l->mainWidget()->name() );
+ else
+ qWarning( "TQLayout: Adding %s/%s (top-level widget) to tqlayout for"
+ " %s/%s", w->className(), w->name(),
+ l->mainWidget()->className(), l->mainWidget()->name() );
+#endif
+ return FALSE;
+ }
+ return TRUE;
+}
+
+// #ifdef USE_QT4
+//
+// #else // USE_QT4
+
+/*!
+ \enum TQGridLayout::Corner
+
+ This enum identifies which corner is the origin (0, 0) of the
+ tqlayout.
+
+ \value TopLeft the top-left corner
+ \value TopRight the top-right corner
+ \value BottomLeft the bottom-left corner
+ \value BottomRight the bottom-right corner
+*/
+
+/*!
+ Constructs a new TQGridLayout with \a nRows rows, \a nCols columns
+ and tqparent widget, \a tqparent. \a tqparent may not be 0. The grid
+ tqlayout is called \a name.
+
+ \a margin is the number of pixels between the edge of the widget
+ and its managed tqchildren. \a space is the default number of pixels
+ between cells. If \a space is -1, the value of \a margin is used.
+*/
+TQGridLayout::TQGridLayout( TQWidget *tqparent, int nRows, int nCols, int margin,
+ int space, const char *name )
+ : TQLayout( tqparent, margin, space, name )
+{
+ init( nRows, nCols );
+}
+
+/*!
+ Constructs a new grid that is placed inside \a parentLayout with
+ \a nRows rows and \a nCols columns. If \a spacing is -1, this
+ TQGridLayout inherits its tqparent's spacing(); otherwise \a spacing
+ is used. The grid tqlayout is called \a name.
+
+ This grid is placed according to \a parentLayout's default
+ placement rules.
+*/
+TQGridLayout::TQGridLayout( TQLayout *parentLayout, int nRows, int nCols,
+ int spacing, const char *name )
+ : TQLayout( parentLayout, spacing, name )
+{
+ init( nRows, nCols );
+}
+
+/*!
+ Constructs a new grid with \a nRows rows and \a nCols columns. If
+ \a spacing is -1, this TQGridLayout inherits its tqparent's
+ spacing(); otherwise \a spacing is used. The grid tqlayout is called
+ \a name.
+
+ You must insert this grid into another tqlayout. You can insert
+ widgets and layouts into this tqlayout at any time, but laying out
+ will not be performed before this is inserted into another tqlayout.
+*/
+TQGridLayout::TQGridLayout( int nRows, int nCols,
+ int spacing, const char *name )
+ : TQLayout( spacing, name )
+{
+ init( nRows, nCols );
+}
+
+/*!
+ Destroys the grid tqlayout. Geometry management is terminated if
+ this is a top-level grid.
+
+ The tqlayout's widgets aren't destroyed.
+*/
+TQGridLayout::~TQGridLayout()
+{
+ delete data;
+}
+
+/*!
+ Returns the number of rows in this grid.
+*/
+int TQGridLayout::numRows() const
+{
+ return data->numRows();
+}
+
+/*!
+ Returns the number of columns in this grid.
+*/
+int TQGridLayout::numCols() const
+{
+ return data->numCols();
+}
+
+/*!
+ Returns the preferred size of this grid.
+*/
+TQSize TQGridLayout::tqsizeHint() const
+{
+ return data->tqsizeHint( spacing() ) + TQSize( 2 * margin(), 2 * margin() );
+}
+
+/*!
+ Returns the minimum size needed by this grid.
+*/
+TQSize TQGridLayout::tqminimumSize() const
+{
+ return data->tqminimumSize( spacing() ) + TQSize( 2 * margin(), 2 * margin() );
+}
+
+/*!
+ Returns the maximum size needed by this grid.
+*/
+TQSize TQGridLayout::tqmaximumSize() const
+{
+ TQSize s = data->tqmaximumSize( spacing() ) +
+ TQSize( 2 * margin(), 2 * margin() );
+ s = s.boundedTo( TQSize(TQLAYOUTSIZE_MAX, TQLAYOUTSIZE_MAX) );
+ if ( tqalignment() & TQt::AlignHorizontal_Mask )
+ s.setWidth( TQLAYOUTSIZE_MAX );
+ if ( tqalignment() & TQt::AlignVertical_Mask )
+ s.setHeight( TQLAYOUTSIZE_MAX );
+ return s;
+}
+
+/*!
+ Returns TRUE if this tqlayout's preferred height depends on its
+ width; otherwise returns FALSE.
+*/
+bool TQGridLayout::hasHeightForWidth() const
+{
+ return ((TQGridLayout*)this)->data->hasHeightForWidth( spacing() );
+}
+
+/*!
+ Returns the tqlayout's preferred height when it is \a w pixels wide.
+*/
+int TQGridLayout::heightForWidth( int w ) const
+{
+ TQGridLayout *that = (TQGridLayout*)this;
+ return that->data->heightForWidth( w, margin(), spacing() );
+}
+
+/*! \internal */
+int TQGridLayout::minimumHeightForWidth( int w ) const
+{
+ TQGridLayout *that = (TQGridLayout*)this;
+ return that->data->minimumHeightForWidth( w, margin(), spacing() );
+}
+
+/*!
+ Searches for widget \a w in this tqlayout (not including child
+ layouts). If \a w is found, it sets \c \a row and \c \a col to
+ the row and column and returns TRUE; otherwise returns FALSE.
+
+ Note: if a widget spans multiple rows/columns, the top-left cell
+ is returned.
+*/
+bool TQGridLayout::tqfindWidget( TQWidget* w, int *row, int *col )
+{
+ return data->tqfindWidget( w, row, col );
+}
+
+/*!
+ Resizes managed widgets within the rectangle \a r.
+*/
+void TQGridLayout::setGeometry( const TQRect &r )
+{
+ if ( data->isDirty() || r != tqgeometry() ) {
+ TQLayout::setGeometry( r );
+ TQRect cr = tqalignment() ? alignmentRect( r ) : r;
+ TQRect s( cr.x() + margin(), cr.y() + margin(),
+ cr.width() - 2 * margin(), cr.height() - 2 * margin() );
+ data->distribute( s, spacing() );
+ }
+}
+
+/*!
+ Returns the tqgeometry of the cell with row \a row and column \a col
+ in the grid. Returns an invalid rectangle if \a row or \a col is
+ outside the grid.
+
+ \warning in the current version of TQt this function does not
+ return valid results until setGeometry() has been called, i.e.
+ after the mainWidget() is visible.
+*/
+TQRect TQGridLayout::cellGeometry( int row, int col ) const
+{
+ return data->cellGeometry( row, col );
+}
+
+/*!
+ Expands this grid so that it will have \a nRows rows and \a nCols
+ columns. Will not shrink the grid. You should not need to call
+ this function because TQGridLayout expands automatically as new
+ items are inserted.
+*/
+void TQGridLayout::expand( int nRows, int nCols )
+{
+ data->expand( nRows, nCols );
+}
+
+/*!
+ Sets up the grid.
+*/
+void TQGridLayout::init( int nRows, int nCols )
+{
+ setSupportsMargin( TRUE );
+ data = new TQGridLayoutData( nRows, nCols );
+}
+
+/*!
+ \overload
+
+ Adds \a item to the next free position of this tqlayout.
+*/
+void TQGridLayout::addItem( QLayoutItem *item )
+{
+ int r, c;
+ data->getNextPos( r, c );
+ add( TQT_TQLAYOUTITEM(item), r, c );
+}
+
+/*!
+ Adds \a item at position \a row, \a col. The tqlayout takes
+ ownership of the \a item.
+*/
+void TQGridLayout::addItem( QLayoutItem *item, int row, int col )
+{
+ add( TQT_TQLAYOUTITEM(item), row, col );
+}
+
+/*!
+ Adds \a item at position \a row, \a col. The tqlayout takes
+ ownership of the \a item.
+*/
+void TQGridLayout::add( TQLayoutItem *item, int row, int col )
+{
+ TQGridBox *box = new TQGridBox( item );
+ data->add( box, row, col );
+}
+
+/*!
+ Adds the \a item to the cell grid, spanning multiple rows/columns.
+
+ The cell will span from \a fromRow, \a fromCol to \a toRow, \a
+ toCol. Alignment is specified by \a tqalignment, which is a bitwise
+ OR of \l TQt::AlignmentFlags values. The default tqalignment is 0,
+ which means that the widget fills the entire cell.
+*/
+void TQGridLayout::addMultiCell( QLayoutItem *item, int fromRow, int toRow,
+ int fromCol, int toCol, int tqalignment )
+{
+ TQGridBox *b = new TQGridBox( TQT_TQLAYOUTITEM(item) );
+ b->tqsetAlignment( tqalignment );
+ data->add( b, fromRow, toRow, fromCol, toCol );
+}
+
+/*!
+ Adds the widget \a w to the cell grid at \a row, \a col. The
+ top-left position is (0, 0) by default.
+
+ Alignment is specified by \a tqalignment, which is a bitwise OR of
+ \l TQt::AlignmentFlags values. The default tqalignment is 0, which
+ means that the widget fills the entire cell.
+
+ \list
+ \i You should not call this if you have enabled the
+ \link TQLayout::setAutoAdd() auto-add facility of the tqlayout\endlink.
+
+ \i From TQt 3.0, the \a tqalignment parameter is interpreted more
+ aggressively than in previous versions of TQt. A non-default
+ tqalignment now indicates that the widget should not grow to fill
+ the available space, but should be sized according to tqsizeHint().
+ \endlist
+
+ \sa addMultiCellWidget()
+*/
+void TQGridLayout::addWidget( TQWidget *w, int row, int col, int tqalignment )
+{
+ if ( !checkWidget( this, w ) )
+ return;
+ if ( row < 0 || col < 0 ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQGridLayout: Cannot add %s/%s to %s/%s at row %d col %d",
+ w->className(), w->name(), className(), name(), row, col );
+#endif
+ return;
+ }
+ TQWidgetItem *b = new TQWidgetItem( w );
+ b->tqsetAlignment( tqalignment );
+ add( b, row, col );
+}
+
+/*!
+ Adds the widget \a w to the cell grid, spanning multiple
+ rows/columns. The cell will span from \a fromRow, \a fromCol to \a
+ toRow, \a toCol.
+
+ Alignment is specified by \a tqalignment, which is a bitwise OR of
+ \l TQt::AlignmentFlags values. The default tqalignment is 0, which
+ means that the widget fills the entire cell.
+
+ A non-zero tqalignment indicates that the widget should not grow to
+ fill the available space but should be sized according to
+ tqsizeHint().
+
+ \sa addWidget()
+*/
+void TQGridLayout::addMultiCellWidget( TQWidget *w, int fromRow, int toRow,
+ int fromCol, int toCol, int tqalignment )
+{
+ TQGridBox *b = new TQGridBox( w );
+ b->tqsetAlignment( tqalignment );
+ data->add( b, fromRow, toRow, fromCol, toCol );
+}
+
+/*!
+ Places the \a tqlayout at position (\a row, \a col) in the grid. The
+ top-left position is (0, 0).
+
+ \a tqlayout becomes a child of the grid tqlayout.
+
+ When a tqlayout is constructed with another tqlayout as its tqparent,
+ you don't need to call addLayout(); the child tqlayout is
+ automatically added to the tqparent tqlayout as it is constructed.
+
+ \sa addMultiCellLayout()
+*/
+void TQGridLayout::addLayout( TQLayout *tqlayout, int row, int col )
+{
+ addChildLayout( tqlayout );
+ add( TQT_TQLAYOUTITEM(tqlayout), row, col );
+}
+
+/*!
+ Adds the tqlayout \a tqlayout to the cell grid, spanning multiple
+ rows/columns. The cell will span from \a fromRow, \a fromCol to \a
+ toRow, \a toCol.
+
+ Alignment is specified by \a tqalignment, which is a bitwise OR of
+ \l TQt::AlignmentFlags values. The default tqalignment is 0, which
+ means that the widget fills the entire cell.
+
+ A non-zero tqalignment indicates that the tqlayout should not grow to
+ fill the available space but should be sized according to
+ tqsizeHint().
+
+ \a tqlayout becomes a child of the grid tqlayout.
+
+ \sa addLayout()
+*/
+void TQGridLayout::addMultiCellLayout( TQLayout *tqlayout, int fromRow, int toRow,
+ int fromCol, int toCol, int tqalignment )
+{
+ addChildLayout( tqlayout );
+ TQGridBox *b = new TQGridBox( TQT_TQLAYOUTITEM(tqlayout) );
+ b->tqsetAlignment( tqalignment );
+ data->add( b, fromRow, toRow, fromCol, toCol );
+}
+
+/*!
+ Sets the stretch factor of row \a row to \a stretch. The first row
+ is number 0.
+
+ The stretch factor is relative to the other rows in this grid.
+ Rows with a higher stretch factor take more of the available
+ space.
+
+ The default stretch factor is 0. If the stretch factor is 0 and no
+ other row in this table can grow at all, the row may still grow.
+
+ \sa rowStretch(), setRowSpacing(), setColStretch()
+*/
+void TQGridLayout::setRowStretch( int row, int stretch )
+{
+ data->setRowStretch( row, stretch );
+}
+
+/*!
+ Returns the stretch factor for row \a row.
+
+ \sa setRowStretch()
+*/
+int TQGridLayout::rowStretch( int row ) const
+{
+ return data->rowStretch( row );
+}
+
+/*!
+ Returns the stretch factor for column \a col.
+
+ \sa setColStretch()
+*/
+int TQGridLayout::colStretch( int col ) const
+{
+ return data->colStretch( col );
+}
+
+/*!
+ Sets the stretch factor of column \a col to \a stretch. The first
+ column is number 0.
+
+ The stretch factor is relative to the other columns in this grid.
+ Columns with a higher stretch factor take more of the available
+ space.
+
+ The default stretch factor is 0. If the stretch factor is 0 and no
+ other column in this table can grow at all, the column may still
+ grow.
+
+ \sa colStretch(), addColSpacing(), setRowStretch()
+*/
+void TQGridLayout::setColStretch( int col, int stretch )
+{
+ data->setColStretch( col, stretch );
+}
+
+#if TQT_VERSION >= 0x040000
+#error "Make add{Row,Col}Spacing() inline TQT_NO_COMPAT functions defined in terms of set{Row,Col}Spacing()"
+#endif
+
+/*!
+ \obsolete
+
+ Sets the minimum height of row \a row to \a minsize pixels.
+
+ Use setRowSpacing() instead.
+*/
+void TQGridLayout::addRowSpacing( int row, int minsize )
+{
+ TQLayoutItem *b = TQT_TQLAYOUTITEM(new TQSpacerItem( 0, minsize ));
+ add( b, row, 0 );
+}
+
+/*!
+ \obsolete
+
+ Sets the minimum width of column \a col to \a minsize pixels.
+
+ Use setColSpacing() instead.
+*/
+void TQGridLayout::addColSpacing( int col, int minsize )
+{
+ TQLayoutItem *b = TQT_TQLAYOUTITEM(new TQSpacerItem( minsize, 0 ));
+ add( b, 0, col );
+}
+
+/*!
+ Sets the minimum height of row \a row to \a minSize pixels.
+
+ \sa rowSpacing(), setColSpacing()
+*/
+void TQGridLayout::setRowSpacing( int row, int minSize )
+{
+ data->setRowSpacing( row, minSize );
+}
+
+/*!
+ Returns the row spacing for row \a row.
+
+ \sa setRowSpacing()
+*/
+int TQGridLayout::rowSpacing( int row ) const
+{
+ return data->rowSpacing( row );
+}
+
+/*!
+ Sets the minimum width of column \a col to \a minSize pixels.
+
+ \sa colSpacing(), setRowSpacing()
+*/
+void TQGridLayout::setColSpacing( int col, int minSize )
+{
+ data->setColSpacing( col, minSize );
+}
+
+/*!
+ Returns the column spacing for column \a col.
+
+ \sa setColSpacing()
+*/
+int TQGridLayout::colSpacing( int col ) const
+{
+ return data->colSpacing( col );
+}
+
+/*!
+ Returns whether this tqlayout can make use of more space than
+ tqsizeHint(). A value of \c Vertical or \c Horizontal means that it wants
+ to grow in only one dimension, whereas \c BothDirections means that
+ it wants to grow in both dimensions.
+*/
+TQ_SPExpandData TQGridLayout::expandingDirections() const
+{
+ return data->expanding( spacing() );
+}
+
+/*!
+ Sets the grid's origin corner, i.e. position (0, 0), to \a c.
+*/
+void TQGridLayout::setOrigin( Corner c )
+{
+ data->setReversed( c == BottomLeft || c == BottomRight,
+ c == TopRight || c == BottomRight );
+}
+
+/*!
+ Returns the corner that's used for the grid's origin, i.e. for
+ position (0, 0).
+*/
+TQGridLayout::Corner TQGridLayout::origin() const
+{
+ if ( data->horReversed() ) {
+ return data->verReversed() ? BottomRight : TopRight;
+ } else {
+ return data->verReversed() ? BottomLeft : TopLeft;
+ }
+}
+
+/*!
+ Resets cached information.
+*/
+void TQGridLayout::tqinvalidate()
+{
+ TQLayout::tqinvalidate();
+ TQLayout::setGeometry( TQRect() ); // for binary compatibility (?)
+ data->setDirty();
+}
+
+/*! \reimp */
+// TQLayoutIterator TQGridLayout::iterator()
+// {
+// return TQLayoutIterator( new TQGridLayoutDataIterator(data) );
+// }
+
+#ifdef USE_QT4
+
+/*!
+ \reimp
+*/
+int TQGridLayout::count() const {
+ return data->count();
+}
+
+/*!
+ \reimp
+*/
+TQLayoutItem* TQGridLayout::itemAt(int index) const {
+ TQGridLayoutDataIterator tqgli = TQGridLayoutDataIterator(data);
+ for (int i=0; i<index; i++) { tqgli.next(); }
+ return index >= 0 && index < data->count() ? tqgli.current() : 0;
+}
+
+/*!
+ \reimp
+*/
+TQLayoutItem* TQGridLayout::takeAt(int index) {
+ if (index < 0 || index >= data->count())
+ return 0;
+ TQGridLayoutDataIterator tqgli = TQGridLayoutDataIterator(data);
+ for (int i=0; i<index; i++) { tqgli.next(); }
+ return tqgli.takeCurrent();
+}
+
+#endif // USE_QT4
+
+// #endif // USE_QT4
+
+struct TQBoxLayoutItem
+{
+ TQBoxLayoutItem( TQLayoutItem *it, int stretch_ = 0 )
+ : item( it ), stretch( stretch_ ), magic( FALSE ) { }
+ ~TQBoxLayoutItem() { delete item; }
+
+ int hfw( int w ) {
+ if ( item->hasHeightForWidth() ) {
+ return item->heightForWidth( w );
+ } else {
+ return item->sizeHint().height();
+ }
+ }
+ int mhfw( int w ) {
+ if ( item->hasHeightForWidth() ) {
+ return item->heightForWidth( w );
+ } else {
+ return item->minimumSize().height();
+ }
+ }
+ int hStretch() {
+ if ( stretch == 0 && item->widget() ) {
+ return TQT_TQSIZEPOLICY_OBJECT(item->widget()->sizePolicy()).horStretch();
+ } else {
+ return stretch;
+ }
+ }
+ int vStretch() {
+ if ( stretch == 0 && item->widget() ) {
+ return TQT_TQSIZEPOLICY_OBJECT(item->widget()->sizePolicy()).verStretch();
+ } else {
+ return stretch;
+ }
+ }
+
+ TQLayoutItem *item;
+ int stretch;
+ bool magic;
+};
+
+class TQBoxLayoutData
+{
+public:
+ TQBoxLayoutData() : geomArray( 0 ), hfwWidth( -1 ), dirty( TRUE )
+ { list.setAutoDelete( TRUE ); }
+
+ ~TQBoxLayoutData() { delete geomArray; }
+ void setDirty() {
+ delete geomArray;
+ geomArray = 0;
+ hfwWidth = -1;
+ hfwHeight = -1;
+ dirty = TRUE;
+ }
+
+ TQPtrList<TQBoxLayoutItem> list;
+ TQMemArray<TQLayoutStruct> *geomArray;
+ int hfwWidth;
+ int hfwHeight;
+ int hfwMinHeight;
+ TQSize tqsizeHint;
+ TQSize minSize;
+ TQSize maxSize;
+ TQ_SPExpandData expanding;
+ uint hasHfw : 1;
+ uint dirty : 1;
+};
+
+class TQBoxLayoutIterator : public TQGLayoutIterator
+{
+public:
+ TQBoxLayoutIterator( TQBoxLayoutData *d ) : data( d ), idx( 0 ) {}
+ TQLayoutItem *current() {
+ if ( idx >= int(data->list.count()) )
+ return 0;
+ return data->list.at(idx)->item;
+ }
+ TQLayoutItem *next() {
+ idx++;
+ return current();
+ }
+ TQLayoutItem *takeCurrent() {
+ TQLayoutItem *item = 0;
+
+ TQBoxLayoutItem *b = data->list.take( idx );
+ if ( b ) {
+ item = b->item;
+ b->item = 0;
+ delete b;
+ }
+ data->setDirty();
+ return item;
+ }
+
+private:
+ TQBoxLayoutData *data;
+ int idx;
+};
+
+/*!
+ \class TQBoxLayout
+
+ \brief The TQBoxLayout class lines up child widgets horizontally or
+ vertically.
+
+ \ingroup geomanagement
+ \ingroup appearance
+
+ TQBoxLayout takes the space it gets (from its tqparent tqlayout or from
+ the mainWidget()), divides it up into a row of boxes, and makes
+ each managed widget fill one box.
+
+ \img qhbox-m.png Horizontal box with five child widgets
+
+ If the TQBoxLayout's orientation is \c Horizontal the boxes are
+ placed in a row, with suitable sizes. Each widget (or other box)
+ will get at least its minimum size and at most its maximum size.
+ Any excess space is shared according to the stretch factors (more
+ about that below).
+
+ \img qvbox-m.png Vertical box with five child widgets
+
+ If the TQBoxLayout's orientation is \c Vertical, the boxes are
+ placed in a column, again with suitable sizes.
+
+ The easiest way to create a TQBoxLayout is to use one of the
+ convenience classes, e.g. TQHBoxLayout (for \c Horizontal boxes) or
+ TQVBoxLayout (for \c Vertical boxes). You can also use the
+ TQBoxLayout constructor directly, specifying its direction as \c
+ LeftToRight, \c Down, \c RightToLeft or \c Up.
+
+ If the TQBoxLayout is not the top-level tqlayout (i.e. it is not
+ managing all of the widget's area and tqchildren), you must add it
+ to its tqparent tqlayout before you can do anything with it. The
+ normal way to add a tqlayout is by calling
+ parentLayout-\>addLayout().
+
+ Once you have done this, you can add boxes to the TQBoxLayout using
+ one of four functions:
+
+ \list
+ \i addWidget() to add a widget to the TQBoxLayout and set the
+ widget's stretch factor. (The stretch factor is along the row of
+ boxes.)
+
+ \i addSpacing() to create an empty box; this is one of the
+ functions you use to create nice and spacious dialogs. See below
+ for ways to set margins.
+
+ \i addStretch() to create an empty, stretchable box.
+
+ \i addLayout() to add a box containing another TQLayout to the row
+ and set that tqlayout's stretch factor.
+ \endlist
+
+ Use insertWidget(), insertSpacing(), insertStretch() or
+ insertLayout() to insert a box at a specified position in the
+ tqlayout.
+
+ TQBoxLayout also includes two margin widths:
+
+ \list
+ \i setMargin() sets the width of the outer border. This is the width
+ of the reserved space along each of the TQBoxLayout's four sides.
+ \i setSpacing() sets the width between neighboring boxes. (You
+ can use addSpacing() to get more space at a particular spot.)
+ \endlist
+
+ The margin defaults to 0. The spacing defaults to the same as the
+ margin width for a top-level tqlayout, or to the same as the tqparent
+ tqlayout. Both are parameters to the constructor.
+
+ To remove a widget from a tqlayout, call remove(). Calling
+ TQWidget::hide() on a widget also effectively removes the widget
+ from the tqlayout until TQWidget::show() is called.
+
+ You will almost always want to use TQVBoxLayout and TQHBoxLayout
+ rather than TQBoxLayout because of their convenient constructors.
+
+ \sa TQGrid \link tqlayout.html Layout Overview \endlink
+*/
+
+/*!
+ \enum TQBoxLayout::Direction
+
+ This type is used to determine the direction of a box tqlayout.
+
+ \value LeftToRight Horizontal, from left to right
+ \value RightToLeft Horizontal, from right to left
+ \value TopToBottom Vertical, from top to bottom
+ \value Down The same as \c TopToBottom
+ \value BottomToTop Vertical, from bottom to top
+ \value Up The same as \c BottomToTop
+*/
+
+static inline bool horz( TQBoxLayout::Direction dir )
+{
+ return dir == TQBoxLayout::RightToLeft || dir == TQBoxLayout::LeftToRight;
+}
+
+/*!
+ Constructs a new TQBoxLayout with direction \a d and main widget \a
+ tqparent. \a tqparent may not be 0.
+
+ The \a margin is the number of pixels between the edge of the
+ widget and its managed tqchildren. The \a spacing is the default
+ number of pixels between neighboring tqchildren. If \a spacing is -1
+ the value of \a margin is used for \a spacing.
+
+ \a name is the internal object name.
+
+ \sa direction()
+*/
+TQBoxLayout::TQBoxLayout( TQWidget *tqparent, Direction d,
+ int margin, int spacing, const char *name )
+ : TQLayout( tqparent, margin, spacing, name )
+{
+ data = new TQBoxLayoutData;
+ dir = d;
+ setSupportsMargin( TRUE );
+}
+
+/*!
+ Constructs a new TQBoxLayout called \a name, with direction \a d,
+ and inserts it into \a parentLayout.
+
+ The \a spacing is the default number of pixels between neighboring
+ tqchildren. If \a spacing is -1, the tqlayout will inherit its
+ tqparent's spacing().
+*/
+TQBoxLayout::TQBoxLayout( TQLayout *parentLayout, Direction d, int spacing,
+ const char *name )
+ : TQLayout( parentLayout, spacing, name )
+{
+ data = new TQBoxLayoutData;
+ dir = d;
+ setSupportsMargin( TRUE );
+}
+
+/*!
+ Constructs a new TQBoxLayout called \a name, with direction \a d.
+
+ If \a spacing is -1, the tqlayout will inherit its tqparent's
+ spacing(); otherwise \a spacing is used.
+
+ You must insert this box into another tqlayout.
+*/
+TQBoxLayout::TQBoxLayout( Direction d, int spacing, const char *name )
+ : TQLayout( spacing, name )
+{
+ data = new TQBoxLayoutData;
+ dir = d;
+ setSupportsMargin( TRUE );
+}
+
+/*!
+ Destroys this box tqlayout.
+
+ The tqlayout's widgets aren't destroyed.
+*/
+TQBoxLayout::~TQBoxLayout()
+{
+ delete data;
+}
+
+/*!
+ Returns the preferred size of this box tqlayout.
+*/
+TQSize TQBoxLayout::tqsizeHint() const
+{
+ if ( data->dirty ) {
+ TQBoxLayout *that = (TQBoxLayout*)this;
+ that->setupGeom();
+ }
+ return data->tqsizeHint + TQSize( 2 * margin(), 2 * margin() );
+}
+
+/*!
+ Returns the minimum size needed by this box tqlayout.
+*/
+TQSize TQBoxLayout::tqminimumSize() const
+{
+ if ( data->dirty ) {
+ TQBoxLayout *that = (TQBoxLayout*)this;
+ that->setupGeom();
+ }
+ return data->minSize + TQSize( 2 * margin(), 2 * margin() );
+}
+
+/*!
+ Returns the maximum size needed by this box tqlayout.
+*/
+TQSize TQBoxLayout::tqmaximumSize() const
+{
+ if ( data->dirty ) {
+ TQBoxLayout *that = (TQBoxLayout*)this;
+ that->setupGeom();
+ }
+ TQSize s = ( data->maxSize + TQSize(2 * margin(), 2 * margin()) )
+ .boundedTo(TQSize(TQLAYOUTSIZE_MAX, TQLAYOUTSIZE_MAX));
+ if ( tqalignment() & TQt::AlignHorizontal_Mask )
+ s.setWidth( TQLAYOUTSIZE_MAX );
+ if ( tqalignment() & TQt::AlignVertical_Mask )
+ s.setHeight( TQLAYOUTSIZE_MAX );
+ return s;
+}
+
+/*!
+ Returns TRUE if this tqlayout's preferred height depends on its width;
+ otherwise returns FALSE.
+*/
+bool TQBoxLayout::hasHeightForWidth() const
+{
+ if ( data->dirty ) {
+ TQBoxLayout *that = (TQBoxLayout*)this;
+ that->setupGeom();
+ }
+ return data->hasHfw;
+}
+
+/*!
+ Returns the tqlayout's preferred height when it is \a w pixels wide.
+*/
+int TQBoxLayout::heightForWidth( int w ) const
+{
+ if ( !hasHeightForWidth() )
+ return -1;
+ w -= 2 * margin();
+ if ( w != data->hfwWidth ) {
+ TQBoxLayout *that = (TQBoxLayout*)this;
+ that->calcHfw( w );
+ }
+ return data->hfwHeight + 2 * margin();
+}
+
+/*! \internal */
+int TQBoxLayout::minimumHeightForWidth( int w ) const
+{
+ (void) heightForWidth( w );
+ return data->hasHfw ? (data->hfwMinHeight + 2 * margin() ) : -1;
+}
+
+/*!
+ Resets cached information.
+*/
+void TQBoxLayout::tqinvalidate()
+{
+ TQLayout::tqinvalidate();
+ data->setDirty();
+}
+
+/*!
+ \reimp
+*/
+int TQBoxLayout::count() const {
+ return data->list.count();
+}
+
+/*!
+ \reimp
+*/
+TQLayoutItem* TQBoxLayout::itemAt(int index) const {
+ return index >= 0 && index < data->list.count() ? data->list.at(index)->item : 0;
+}
+
+/*!
+ \reimp
+*/
+TQLayoutItem* TQBoxLayout::takeAt(int index) {
+ if (index < 0 || index >= data->list.count())
+ return 0;
+ TQBoxLayoutItem *b = data->list.take(index);
+ TQLayoutItem *item = b->item;
+ b->item = 0;
+ delete b;
+
+ invalidate();
+ return item;
+}
+
+/*!
+ \reimp
+*/
+// TQLayoutIterator TQBoxLayout::iterator()
+// {
+// return TQLayoutIterator( new TQBoxLayoutIterator(data) );
+// }
+
+/*!
+ Returns whether this tqlayout can make use of more space than
+ tqsizeHint(). A value of \c Vertical or \c Horizontal means that it wants
+ to grow in only one dimension, whereas \c BothDirections means that
+ it wants to grow in both dimensions.
+*/
+TQ_SPExpandData TQBoxLayout::expandingDirections() const
+{
+ if ( data->dirty ) {
+ TQBoxLayout *that = (TQBoxLayout*)this;
+ that->setupGeom();
+ }
+ return data->expanding;
+}
+
+/*!
+ Resizes managed widgets within the rectangle \a r.
+*/
+void TQBoxLayout::setGeometry( const TQRect &r )
+{
+ if ( !data->geomArray || r != tqgeometry() ) {
+ TQLayout::setGeometry( r );
+ if ( !data->geomArray )
+ setupGeom();
+ TQRect cr = tqalignment() ? alignmentRect( r ) : r;
+ TQRect s( cr.x() + margin(), cr.y() + margin(),
+ cr.width() - 2 * margin(), cr.height() - 2 * margin() );
+
+ TQMemArray<TQLayoutStruct> a = *data->geomArray;
+ int pos = horz( dir ) ? s.x() : s.y();
+ int space = horz( dir ) ? s.width() : s.height();
+ int n = a.count();
+ if ( data->hasHfw && !horz(dir) ) {
+ for ( int i = 0; i < n; i++ ) {
+ TQBoxLayoutItem *box = data->list.at( i );
+ if ( box->item->hasHeightForWidth() )
+ a[i].tqsizeHint = a[i].tqminimumSize =
+ box->item->heightForWidth( s.width() );
+ }
+ }
+
+ Direction visualDir = dir;
+ if ( TQApplication::reverseLayout() ) {
+ if ( dir == LeftToRight )
+ visualDir = RightToLeft;
+ else if ( dir == RightToLeft )
+ visualDir = LeftToRight;
+ }
+
+ qGeomCalc( a, 0, n, pos, space, spacing() );
+ for ( int i = 0; i < n; i++ ) {
+ TQBoxLayoutItem *box = data->list.at( i );
+
+ switch ( visualDir ) {
+ case LeftToRight:
+ box->item->setGeometry( TQRect(a[i].pos, s.y(),
+ a[i].size, s.height()) );
+ break;
+ case RightToLeft:
+ box->item->setGeometry( TQRect(s.left() + s.right()
+ - a[i].pos - a[i].size + 1, s.y(),
+ a[i].size, s.height()) );
+ break;
+ case TopToBottom:
+ box->item->setGeometry( TQRect(s.x(), a[i].pos,
+ s.width(), a[i].size) );
+ break;
+ case BottomToTop:
+ box->item->setGeometry( TQRect(s.x(), s.top() + s.bottom()
+ - a[i].pos - a[i].size + 1,
+ s.width(), a[i].size) );
+ }
+ }
+ }
+}
+
+/*!
+ Adds \a item to the end of this box tqlayout.
+*/
+void TQBoxLayout::addItem( QLayoutItem *item )
+{
+ TQBoxLayoutItem *it = new TQBoxLayoutItem( static_cast<TQLayoutItem*>(item) );
+ data->list.append( it );
+ tqinvalidate();
+}
+
+/*!
+ Inserts \a item into this box tqlayout at position \a index. If \a
+ index is negative, the item is added at the end.
+
+ \warning Does not call TQLayout::insertChildLayout() if \a item is
+ a TQLayout.
+
+ \sa addItem(), tqfindWidget()
+*/
+void TQBoxLayout::insertItem( int index, TQLayoutItem *item )
+{
+ if ( index < 0 ) // append
+ index = data->list.count();
+
+ TQBoxLayoutItem *it = new TQBoxLayoutItem( item );
+ data->list.insert( index, it );
+ tqinvalidate();
+}
+
+/*!
+ Inserts a non-stretchable space at position \a index, with size \a
+ size. If \a index is negative the space is added at the end.
+
+ The box tqlayout has default margin and spacing. This function adds
+ additional space.
+
+ \sa insertStretch()
+*/
+void TQBoxLayout::insertSpacing( int index, int size )
+{
+ if ( index < 0 ) // append
+ index = data->list.count();
+
+ // hack in TQGridLayoutData: spacers do not get insideSpacing
+ TQLayoutItem *b;
+ if ( horz( dir ) )
+ b = TQT_TQLAYOUTITEM(new TQSpacerItem( size, 0, TQSizePolicy::Fixed,
+ TQSizePolicy::Minimum ));
+ else
+ b = TQT_TQLAYOUTITEM(new TQSpacerItem( 0, size, TQSizePolicy::Minimum,
+ TQSizePolicy::Fixed ));
+
+ TQBoxLayoutItem *it = new TQBoxLayoutItem( b );
+ it->magic = TRUE;
+ data->list.insert( index, it );
+ tqinvalidate();
+}
+
+/*!
+ Inserts a stretchable space at position \a index, with zero
+ minimum size and stretch factor \a stretch. If \a index is
+ negative the space is added at the end.
+
+ \sa insertSpacing()
+*/
+void TQBoxLayout::insertStretch( int index, int stretch )
+{
+ if ( index < 0 ) // append
+ index = data->list.count();
+
+ // hack in TQGridLayoutData: spacers do not get insideSpacing
+ TQLayoutItem *b;
+ if ( horz( dir ) )
+ b = TQT_TQLAYOUTITEM(new TQSpacerItem( 0, 0, TQSizePolicy::Expanding,
+ TQSizePolicy::Minimum ));
+ else
+ b = TQT_TQLAYOUTITEM(new TQSpacerItem( 0, 0, TQSizePolicy::Minimum,
+ TQSizePolicy::Expanding ));
+
+ TQBoxLayoutItem *it = new TQBoxLayoutItem( b, stretch );
+ it->magic = TRUE;
+ data->list.insert( index, it );
+ tqinvalidate();
+}
+
+/*!
+ Inserts \a tqlayout at position \a index, with stretch factor \a
+ stretch. If \a index is negative, the tqlayout is added at the end.
+
+ \a tqlayout becomes a child of the box tqlayout.
+
+ \sa setAutoAdd(), insertWidget(), insertSpacing()
+*/
+void TQBoxLayout::insertLayout( int index, TQLayout *tqlayout, int stretch )
+{
+ if ( index < 0 ) // append
+ index = data->list.count();
+
+ addChildLayout( tqlayout );
+ TQBoxLayoutItem *it = new TQBoxLayoutItem( TQT_TQLAYOUTITEM(tqlayout), stretch );
+ data->list.insert( index, it );
+ tqinvalidate();
+}
+
+/*!
+ Inserts \a widget at position \a index, with stretch factor \a
+ stretch and tqalignment \a tqalignment. If \a index is negative, the
+ widget is added at the end.
+
+ The stretch factor applies only in the \link direction() direction
+ \endlink of the TQBoxLayout, and is relative to the other boxes and
+ widgets in this TQBoxLayout. Widgets and boxes with higher stretch
+ factors grow more.
+
+ If the stretch factor is 0 and nothing else in the TQBoxLayout has
+ a stretch factor greater than zero, the space is distributed
+ according to the TQWidget:sizePolicy() of each widget that's
+ involved.
+
+ Alignment is specified by \a tqalignment, which is a bitwise OR of
+ \l TQt::AlignmentFlags values. The default tqalignment is 0, which
+ means that the widget fills the entire cell.
+
+ From TQt 3.0, the \a tqalignment parameter is interpreted more
+ aggressively than in previous versions of TQt. A non-default
+ tqalignment now indicates that the widget should not grow to fill
+ the available space, but should be sized according to tqsizeHint().
+
+ \sa setAutoAdd(), insertLayout(), insertSpacing()
+*/
+void TQBoxLayout::insertWidget( int index, TQWidget *widget, int stretch,
+ int tqalignment )
+{
+ if ( !checkWidget(this, widget) )
+ return;
+
+ if ( index < 0 ) // append
+ index = data->list.count();
+
+ TQWidgetItem *b = new TQWidgetItem( widget );
+ b->tqsetAlignment( tqalignment );
+ TQBoxLayoutItem *it = new TQBoxLayoutItem( b, stretch );
+ data->list.insert( index, it );
+ tqinvalidate();
+}
+
+/*!
+ Adds a non-stretchable space with size \a size to the end of this
+ box tqlayout. TQBoxLayout provides default margin and spacing. This
+ function adds additional space.
+
+ \sa insertSpacing(), addStretch()
+*/
+void TQBoxLayout::addSpacing( int size )
+{
+ insertSpacing( -1, size );
+}
+
+/*!
+ Adds a stretchable space with zero minimum size and stretch factor
+ \a stretch to the end of this box tqlayout.
+
+ \sa addSpacing()
+*/
+void TQBoxLayout::addStretch( int stretch )
+{
+ insertStretch( -1, stretch );
+}
+
+/*!
+ Adds \a widget to the end of this box tqlayout, with a stretch
+ factor of \a stretch and tqalignment \a tqalignment.
+
+ The stretch factor applies only in the \link direction() direction
+ \endlink of the TQBoxLayout, and is relative to the other boxes and
+ widgets in this TQBoxLayout. Widgets and boxes with higher stretch
+ factors grow more.
+
+ If the stretch factor is 0 and nothing else in the TQBoxLayout has
+ a stretch factor greater than zero, the space is distributed
+ according to the TQWidget:sizePolicy() of each widget that's
+ involved.
+
+ Alignment is specified by \a tqalignment which is a bitwise OR of \l
+ TQt::AlignmentFlags values. The default tqalignment is 0, which means
+ that the widget fills the entire cell.
+
+ From TQt 3.0, the \a tqalignment parameter is interpreted more
+ aggressively than in previous versions of TQt. A non-default
+ tqalignment now indicates that the widget should not grow to fill
+ the available space, but should be sized according to tqsizeHint().
+
+ \sa insertWidget(), setAutoAdd(), addLayout(), addSpacing()
+*/
+void TQBoxLayout::addWidget( TQWidget *widget, int stretch,
+ int tqalignment )
+{
+ insertWidget( -1, widget, stretch, tqalignment );
+}
+
+/*!
+ Adds \a tqlayout to the end of the box, with serial stretch factor
+ \a stretch.
+
+ When a tqlayout is constructed with another tqlayout as its tqparent,
+ you don't need to call addLayout(); the child tqlayout is
+ automatically added to the tqparent tqlayout as it is constructed.
+
+ \sa insertLayout(), setAutoAdd(), addWidget(), addSpacing()
+*/
+void TQBoxLayout::addLayout( TQLayout *tqlayout, int stretch )
+{
+ insertLayout( -1, tqlayout, stretch );
+}
+
+/*!
+ Limits the perpendicular dimension of the box (e.g. height if the
+ box is LeftToRight) to a minimum of \a size. Other constraints may
+ increase the limit.
+*/
+void TQBoxLayout::addStrut( int size )
+{
+ TQLayoutItem *b;
+ if ( horz( dir ) )
+ b = TQT_TQLAYOUTITEM(new TQSpacerItem( 0, size, TQSizePolicy::Fixed,
+ TQSizePolicy::Minimum ));
+ else
+ b = TQT_TQLAYOUTITEM(new TQSpacerItem( size, 0, TQSizePolicy::Minimum,
+ TQSizePolicy::Fixed ));
+
+ TQBoxLayoutItem *it = new TQBoxLayoutItem( b );
+ it->magic = TRUE;
+ data->list.append( it );
+ tqinvalidate();
+}
+
+/*!
+ Searches for widget \a w in this tqlayout (not including child
+ layouts).
+
+ Returns the index of \a w, or -1 if \a w is not found.
+*/
+int TQBoxLayout::tqfindWidget( TQWidget* w )
+{
+ const int n = data->list.count();
+ for ( int i = 0; i < n; i++ ) {
+ if ( data->list.at(i)->item->widget() == w )
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ Sets the stretch factor for widget \a w to \a stretch and returns
+ TRUE if \a w is found in this tqlayout (not including child
+ layouts); otherwise returns FALSE.
+*/
+bool TQBoxLayout::setStretchFactor( TQWidget *w, int stretch )
+{
+ TQPtrListIterator<TQBoxLayoutItem> it( data->list );
+ TQBoxLayoutItem *box;
+ while ( (box=it.current()) != 0 ) {
+ ++it;
+ if ( box->item->widget() == w ) {
+ box->stretch = stretch;
+ tqinvalidate();
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*!
+ \overload
+
+ Sets the stretch factor for the tqlayout \a l to \a stretch and
+ returns TRUE if \a l is found in this tqlayout (not including child
+ layouts); otherwise returns FALSE.
+*/
+bool TQBoxLayout::setStretchFactor( TQLayout *l, int stretch )
+{
+ TQPtrListIterator<TQBoxLayoutItem> it( data->list );
+ TQBoxLayoutItem *box;
+ while ( (box=it.current()) != 0 ) {
+ ++it;
+ if ( box->item->tqlayout() == l ) {
+ box->stretch = stretch;
+ tqinvalidate();
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*!
+ Sets the direction of this tqlayout to \a direction.
+*/
+void TQBoxLayout::setDirection( Direction direction )
+{
+ if ( dir == direction )
+ return;
+ if ( horz(dir) != horz(direction) ) {
+ //swap around the spacers (the "magic" bits)
+ //#### a bit yucky, knows too much.
+ //#### probably best to add access functions to tqspacerItem
+ //#### or even a TQSpacerItem::flip()
+ TQPtrListIterator<TQBoxLayoutItem> it( data->list );
+ TQBoxLayoutItem *box;
+ while ( (box=it.current()) != 0 ) {
+ ++it;
+ if ( box->magic ) {
+ TQSpacerItem *sp = box->item->tqspacerItem();
+ if ( sp ) {
+ if ( sp->expandingDirections() == TQSizePolicy::NoDirection ) {
+ //spacing or strut
+ TQSize s = sp->tqsizeHint();
+ sp->changeSize( s.height(), s.width(),
+ horz(direction) ? TQSizePolicy::Fixed:TQSizePolicy::Minimum,
+ horz(direction) ? TQSizePolicy::Minimum:TQSizePolicy::Fixed );
+
+ } else {
+ //stretch
+ if ( horz(direction) )
+ sp->changeSize( 0, 0, TQSizePolicy::Expanding,
+ TQSizePolicy::Minimum );
+ else
+ sp->changeSize( 0, 0, TQSizePolicy::Minimum,
+ TQSizePolicy::Expanding );
+ }
+ }
+ }
+ }
+ }
+ dir = direction;
+ tqinvalidate();
+ if ( mainWidget() ) {
+ TQEvent *lh = new TQEvent( TQEvent::LayoutHint );
+ TQApplication::postEvent( mainWidget(), lh );
+ }
+
+}
+
+/*
+ Initializes the data structure needed by qGeomCalc and
+ recalculates max/min and size hint.
+*/
+void TQBoxLayout::setupGeom()
+{
+ if ( !data->dirty )
+ return;
+
+ int maxw = horz( dir ) ? 0 : TQLAYOUTSIZE_MAX;
+ int maxh = horz( dir ) ? TQLAYOUTSIZE_MAX : 0;
+ int minw = 0;
+ int minh = 0;
+ int hintw = 0;
+ int hinth = 0;
+
+ bool horexp = FALSE;
+ bool verexp = FALSE;
+
+ data->hasHfw = FALSE;
+
+ delete data->geomArray;
+ int n = data->list.count();
+ data->geomArray = new TQMemArray<TQLayoutStruct>( n );
+ TQMemArray<TQLayoutStruct>& a = *data->geomArray;
+
+ bool first = TRUE;
+ for ( int i = 0; i < n; i++ ) {
+ TQBoxLayoutItem *box = data->list.at( i );
+ TQSize max = box->item->maximumSize();
+ TQSize min = box->item->minimumSize();
+ TQSize hint = box->item->sizeHint();
+
+ TQ_SPExpandData exp = box->item->expandingDirections();
+ bool empty = box->item->isEmpty();
+ // space before non-empties, except the first:
+ int space = ( empty || first ) ? 0 : spacing();
+ bool ignore = empty && box->item->widget(); // ignore hidden widgets
+
+ if ( horz(dir) ) {
+ bool expand = exp & TQSizePolicy::Horizontally || box->stretch > 0;
+ horexp = horexp || expand;
+ maxw += max.width() + space;
+ minw += min.width() + space;
+ hintw += hint.width() + space;
+ if ( !ignore )
+ qMaxExpCalc( maxh, verexp,
+ max.height(), exp & TQSizePolicy::Vertically );
+ minh = TQMAX( minh, min.height() );
+ hinth = TQMAX( hinth, hint.height() );
+
+ a[i].tqsizeHint = hint.width();
+ a[i].tqmaximumSize = max.width();
+ a[i].tqminimumSize = min.width();
+ a[i].expansive = expand;
+ a[i].stretch = box->stretch ? box->stretch : box->hStretch();
+ } else {
+ bool expand = ( exp & TQSizePolicy::Vertically || box->stretch > 0 );
+ verexp = verexp || expand;
+ maxh += max.height() + space;
+ minh += min.height() + space;
+ hinth += hint.height() + space;
+ if ( !ignore )
+ qMaxExpCalc( maxw, horexp,
+ max.width(), exp & TQSizePolicy::Horizontally );
+ minw = TQMAX( minw, min.width() );
+ hintw = TQMAX( hintw, hint.width() );
+
+ a[i].tqsizeHint = hint.height();
+ a[i].tqmaximumSize = max.height();
+ a[i].tqminimumSize = min.height();
+ a[i].expansive = expand;
+ a[i].stretch = box->stretch ? box->stretch : box->vStretch();
+ }
+
+ a[i].empty = empty;
+ data->hasHfw = data->hasHfw || box->item->hasHeightForWidth();
+ first = first && empty;
+ }
+
+ data->minSize = TQSize( minw, minh );
+ data->maxSize = TQSize( maxw, maxh ).expandedTo( data->minSize );
+
+ data->expanding = (TQ_SPExpandData)
+ ( (horexp ? TQSizePolicy::Horizontally : 0)
+ | (verexp ? TQSizePolicy::Vertically : 0) );
+
+ data->tqsizeHint = TQSize( hintw, hinth )
+ .expandedTo( data->minSize )
+ .boundedTo( data->maxSize );
+
+ data->dirty = FALSE;
+}
+
+/*
+ Calculates and stores the preferred height given the width \a w.
+*/
+void TQBoxLayout::calcHfw( int w )
+{
+ int h = 0;
+ int mh = 0;
+
+ if ( horz(dir) ) {
+ TQMemArray<TQLayoutStruct> &a = *data->geomArray;
+ int n = a.count();
+ qGeomCalc( a, 0, n, 0, w, spacing() );
+ for ( int i = 0; i < n; i++ ) {
+ TQBoxLayoutItem *box = data->list.at(i);
+ h = TQMAX( h, box->hfw(a[i].size) );
+ mh = TQMAX( mh, box->mhfw(a[i].size) );
+ }
+ } else {
+ TQPtrListIterator<TQBoxLayoutItem> it( data->list );
+ TQBoxLayoutItem *box;
+ bool first = TRUE;
+ while ( (box = it.current()) != 0 ) {
+ ++it;
+ bool empty = box->item->isEmpty();
+ h += box->hfw( w );
+ mh += box->mhfw( w );
+ if ( !first && !empty ) {
+ h += spacing();
+ mh += spacing();
+ }
+ first = first && empty;
+ }
+ }
+ data->hfwWidth = w;
+ data->hfwHeight = h;
+ data->hfwMinHeight = mh;
+}
+
+/*!
+ \fn TQBoxLayout::Direction TQBoxLayout::direction() const
+
+ Returns the direction of the box. addWidget() and addSpacing()
+ work in this direction; the stretch stretches in this direction.
+
+ \sa TQBoxLayout::Direction addWidget() addSpacing()
+*/
+
+/*!
+ \class TQHBoxLayout
+ \brief The TQHBoxLayout class lines up widgets horizontally.
+
+ \ingroup geomanagement
+ \ingroup appearance
+ \mainclass
+
+ This class is used to construct horizontal box tqlayout objects. See
+ \l TQBoxLayout for more details.
+
+ The simplest use of the class is like this:
+ \code
+ TQBoxLayout * l = new TQHBoxLayout( widget );
+ l->setAutoAdd( TRUE );
+ new TQSomeWidget( widget );
+ new TQSomeOtherWidget( widget );
+ new TQAnotherWidget( widget );
+ \endcode
+
+ or like this:
+ \code
+ TQBoxLayout * l = new TQHBoxLayout( widget );
+ l->addWidget( existingChildOfWidget );
+ l->addWidget( anotherChildOfWidget );
+ \endcode
+
+ \img qhboxtqlayout.png TQHBox
+
+ \sa TQVBoxLayout TQGridLayout
+ \link tqlayout.html the Layout overview \endlink
+*/
+
+/*!
+ Constructs a new top-level horizontal box called \a name, with
+ tqparent \a tqparent.
+
+ The \a margin is the number of pixels between the edge of the
+ widget and its managed tqchildren. The \a spacing is the default
+ number of pixels between neighboring tqchildren. If \a spacing is -1
+ the value of \a margin is used for \a spacing.
+*/
+TQHBoxLayout::TQHBoxLayout( TQWidget *tqparent, int margin,
+ int spacing, const char *name )
+ : TQBoxLayout( tqparent, LeftToRight, margin, spacing, name )
+{
+}
+
+/*!
+ Constructs a new horizontal box called name \a name and adds it to
+ \a parentLayout.
+
+ The \a spacing is the default number of pixels between neighboring
+ tqchildren. If \a spacing is -1, this TQHBoxLayout will inherit its
+ tqparent's spacing().
+*/
+TQHBoxLayout::TQHBoxLayout( TQLayout *parentLayout, int spacing,
+ const char *name )
+ : TQBoxLayout( parentLayout, LeftToRight, spacing, name )
+{
+}
+
+/*!
+ Constructs a new horizontal box called name \a name. You must add
+ it to another tqlayout.
+
+ The \a spacing is the default number of pixels between neighboring
+ tqchildren. If \a spacing is -1, this TQHBoxLayout will inherit its
+ tqparent's spacing().
+*/
+TQHBoxLayout::TQHBoxLayout( int spacing, const char *name )
+ : TQBoxLayout( LeftToRight, spacing, name )
+{
+}
+
+/*!
+ Destroys this box tqlayout.
+
+ The tqlayout's widgets aren't destroyed.
+*/
+TQHBoxLayout::~TQHBoxLayout()
+{
+}
+
+/*!
+ \class TQVBoxLayout
+
+ \brief The TQVBoxLayout class lines up widgets vertically.
+
+ \ingroup geomanagement
+ \ingroup appearance
+ \mainclass
+
+ This class is used to construct vertical box tqlayout objects. See
+ TQBoxLayout for more details.
+
+ The simplest use of the class is like this:
+ \code
+ TQBoxLayout * l = new TQVBoxLayout( widget );
+ l->addWidget( aWidget );
+ l->addWidget( anotherWidget );
+ \endcode
+
+ \img qvboxtqlayout.png TQVBox
+
+ \sa TQHBoxLayout TQGridLayout \link tqlayout.html the Layout overview \endlink
+*/
+
+/*!
+ Constructs a new top-level vertical box called \a name, with
+ tqparent \a tqparent.
+
+ The \a margin is the number of pixels between the edge of the
+ widget and its managed tqchildren. The \a spacing is the default
+ number of pixels between neighboring tqchildren. If \a spacing is -1
+ the value of \a margin is used for \a spacing.
+*/
+TQVBoxLayout::TQVBoxLayout( TQWidget *tqparent, int margin, int spacing,
+ const char *name )
+ : TQBoxLayout( tqparent, TopToBottom, margin, spacing, name )
+{
+
+}
+
+/*!
+ Constructs a new vertical box called name \a name and adds it to
+ \a parentLayout.
+
+ The \a spacing is the default number of pixels between neighboring
+ tqchildren. If \a spacing is -1, this TQVBoxLayout will inherit its
+ tqparent's spacing().
+*/
+TQVBoxLayout::TQVBoxLayout( TQLayout *parentLayout, int spacing,
+ const char *name )
+ : TQBoxLayout( parentLayout, TopToBottom, spacing, name )
+{
+}
+
+/*!
+ Constructs a new vertical box called name \a name. You must add
+ it to another tqlayout.
+
+ The \a spacing is the default number of pixels between neighboring
+ tqchildren. If \a spacing is -1, this TQVBoxLayout will inherit its
+ tqparent's spacing().
+*/
+TQVBoxLayout::TQVBoxLayout( int spacing, const char *name )
+ : TQBoxLayout( TopToBottom, spacing, name )
+{
+}
+
+/*!
+ Destroys this box tqlayout.
+
+ The tqlayout's widgets aren't destroyed.
+*/
+TQVBoxLayout::~TQVBoxLayout()
+{
+}
+
+TQBoxLayout *TQBoxLayout::createTmpCopy()
+{
+ TQBoxLayout *bl = new TQBoxLayout( direction() );
+ delete bl->data;
+ bl->data = data;
+ return bl;
+}
+
+#endif // TQT_NO_LAYOUT
diff --git a/tqtinterface/qt4/src/kernel/tqlayout.h b/tqtinterface/qt4/src/kernel/tqlayout.h
new file mode 100644
index 0000000..5423cad
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqlayout.h
@@ -0,0 +1,1146 @@
+/****************************************************************************
+**
+** Definition of tqlayout classes
+**
+** Created : 960416
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// TQT TODO:
+// 1. TQLayout and TQGridLayout addItem functions may not be able to be subclassed by TQt classes
+// This will probably require an inline redirect from the Qt4 method addItem(QLayoutItem) to the TQt method addItem(TQLayoutItem)
+// See also TQLayout::setGeometry() for an example of how to do this
+// See tqlayout.cpp line 3074 for why this is needed
+// MAYBE?????
+
+#ifndef TQLAYOUT_H
+#define TQLAYOUT_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqsizepolicy.h"
+#include "tqwidget.h"
+#endif // TQT_H
+
+#include <limits.h>
+
+#ifndef TQT_NO_LAYOUT
+
+#ifdef USE_QT4
+
+#include <Qt/qlayout.h>
+
+#endif // USE_QT4
+
+#if 0
+TQ_OBJECT
+#endif
+
+static const int TQLAYOUTSIZE_MAX = INT_MAX/256/16;
+
+class TQGridLayoutBox;
+class TQGridLayoutData;
+class TQLayout;
+class TQLayoutItem;
+struct TQLayoutData;
+class TQMenuBar;
+class TQSpacerItem;
+class TQWidget;
+
+class TQ_EXPORT TQGLayoutIterator : public TQShared
+{
+public:
+ virtual ~TQGLayoutIterator();
+ virtual TQLayoutItem *next() = 0;
+ virtual TQLayoutItem *current() = 0;
+ virtual TQLayoutItem *takeCurrent() = 0;
+};
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQLayoutIterator
+{
+public:
+ TQLayoutIterator(QLayout *i);
+ inline TQLayoutIterator(const TQLayoutIterator &i)
+ : layout(i.layout), index(i.index) {}
+ inline TQLayoutIterator &operator=(const TQLayoutIterator &i) {
+ layout = i.layout;
+ index = i.index;
+ return *this;
+ }
+ TQLayoutItem *operator++();
+ TQLayoutItem *current();
+ TQLayoutItem *takeCurrent();
+ void deleteCurrent();
+
+private:
+ // hack to avoid deprecated warning
+ friend class QLayout;
+ friend class TQLayout;
+ TQLayoutIterator(QLayout *i, bool);
+ TQLayout *layout;
+ int index;
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQLayoutIterator
+{
+public:
+ TQLayoutIterator( TQGLayoutIterator *i ) : it( i ) { }
+ TQLayoutIterator( const TQLayoutIterator &i ) : it( i.it ) {
+ if ( it )
+ it->ref();
+ }
+ ~TQLayoutIterator() { if ( it && it->deref() ) delete it; }
+ TQLayoutIterator &operator=( const TQLayoutIterator &i ) {
+ if ( i.it )
+ i.it->ref();
+ if ( it && it->deref() )
+ delete it;
+ it = i.it;
+ return *this;
+ }
+ TQLayoutItem *operator++() { return it ? it->next() : 0; }
+ TQLayoutItem *current() { return it ? it->current() : 0; }
+ TQLayoutItem *takeCurrent() { return it ? it->takeCurrent() : 0; }
+ void deleteCurrent();
+
+private:
+ TQGLayoutIterator *it;
+};
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+// Abstract base classes cannot have their abstract methods modified or added to
+// Also, all TQt functions MUST be NON VIRTUAL (and are recommended to be inline as well) <-- this may not always be true
+// Virtual functions are resolved at run time, causing all kinds of problems at runtime with the interface layer
+class TQ_EXPORT TQLayoutItem : public QLayoutItem, virtual public TQt
+{
+public:
+ TQLayoutItem( int tqalignment = 0 ) : QLayoutItem( (Qt::Alignment)tqalignment ) {}
+
+ inline int tqalignment() const { return alignment(); }
+
+ TQSpacerItem *tqspacerItem();
+ inline TQLayout *tqlayout() { return 0; }
+ inline TQWidget *widget() { return static_cast<TQWidget*>(QLayoutItem::widget()); }
+// inline bool hasHeightForWidth() const { return QLayoutItem::hasHeightForWidth(); }
+// inline int heightForWidth( int i ) const { return QLayoutItem::heightForWidth( i ); }
+// inline virtual TQLayoutIterator iterator() { return TQLayoutIterator( 0 ); }
+ inline TQLayoutIterator iterator() { return TQLayoutIterator( 0 ); }
+ inline void tqsetAlignment( int a ) { QLayoutItem::setAlignment((Qt::AlignmentFlag)a); }
+ virtual inline void tqinvalidate() { QLayoutItem::invalidate(); }
+ virtual inline void invalidate() { tqinvalidate(); }
+
+// inline virtual TQSize tqsizeHint() const { return QLayoutItem::sizeHint(); }
+// inline virtual TQSize tqminimumSize() const { return QLayoutItem::minimumSize(); }
+// inline virtual TQSize tqmaximumSize() const { return QLayoutItem::maximumSize(); }
+// inline virtual void setGeometry( const TQRect&r ) { QLayoutItem::setGeometry(r); }
+// inline virtual TQRect tqgeometry() const { return QLayoutItem::geometry(); }
+// inline virtual TQ_SPExpandData expandingDirections() const { return QLayoutItem::expandingDirections(); }
+
+ // These functions are pure virtual in Qt4
+ inline TQSize tqsizeHint() const { return sizeHint(); }
+ inline TQSize tqminimumSize() const { return minimumSize(); }
+ inline TQSize tqmaximumSize() const { return maximumSize(); }
+// inline void setGeometry( const TQRect&r ) { TQ_UNUSED(r); }
+ inline TQRect tqgeometry() const { return geometry(); }
+};
+
+ // Use the TQt virtual functions, not the built in Qt ones...
+ // This requires that the base virtual Qt functions be reimplemented so as to point to the TQt virtual functions instead as shown below.
+ // This way, when Trinity overrides a TQt virtual function, the calling Qt code will blithely use the overriden TQt function instead.
+#define QLAYOUTITEM_REQUIRED_FUNCTIONS \
+ virtual inline QSize sizeHint() const { return tqsizeHint(); } \
+ virtual inline QSize minimumSize() const { return tqminimumSize(); } \
+ virtual inline QSize maximumSize() const { return tqmaximumSize(); } \
+ virtual inline void setGeometry( const QRect &r ) { return setGeometry( TQT_TQRECT_OBJECT(r) ); } \
+ virtual inline QRect geometry() const { return tqgeometry(); }
+ // inline void setAlignment( Qt::AlignmentFlag a ) { return tqsetAlignment(a); }
+
+// class TQ_EXPORT TQLayoutItem : public QLayoutItem, virtual public TQt
+// {
+// public:
+// TQLayoutItem( int tqalignment = 0 ) : QLayoutItem( (Qt::Alignment)tqalignment ) {}
+// virtual ~TQLayoutItem();
+//
+// inline int tqalignment() const { return alignment(); }
+//
+// virtual TQSpacerItem *tqspacerItem();
+// virtual TQLayout *tqlayout();
+// virtual TQWidget *widget();
+// virtual bool hasHeightForWidth() const;
+// virtual int heightForWidth( int ) const;
+// virtual TQLayoutIterator iterator();
+//
+// virtual TQSize tqsizeHint() const = 0;
+// virtual TQSize tqminimumSize() const = 0;
+// virtual TQSize tqmaximumSize() const = 0;
+// virtual void setGeometry( const TQRect& ) = 0;
+// virtual TQRect tqgeometry() const = 0;
+// virtual void tqsetAlignment( int a );
+// virtual void tqinvalidate();
+// virtual TQ_SPExpandData expandingDirections() const;
+//
+// // Use the TQt virtual functions, not the built in Qt ones...
+// // This requires that the base virtual Qt functions be reimplemented so as to point to the TQt virtual functions instead as shown below.
+// // This way, when Trinity overrides a TQt virtual function, the calling Qt code will blithely use the overriden TQt function instead.
+// inline QSize sizeHint() const { return tqsizeHint(); }
+// inline QSize minimumSize() const { return tqminimumSize(); }
+// inline QSize maximumSize() const { return tqmaximumSize(); }
+// inline void setGeometry( const QRect &r ) { return TQLayoutItem::setGeometry( r ); }
+// inline QRect geometry() const { return tqgeometry(); }
+// inline void setAlignment( Qt::AlignmentFlag a ) { return tqsetAlignment(a); }
+// inline void invalidate() { return tqinvalidate(); }
+// inline Qt::Orientations expandingDirections() const { return TQLayoutItem::expandingDirections(); }
+// };
+
+#else // USE_QT4
+
+class TQ_EXPORT TQLayoutItem
+{
+public:
+ TQLayoutItem( int tqalignment = 0 ) : align( tqalignment ) { }
+ virtual ~TQLayoutItem();
+ virtual TQSize tqsizeHint() const = 0;
+ virtual TQSize tqminimumSize() const = 0;
+ virtual TQSize tqmaximumSize() const = 0;
+ virtual TQ_SPExpandData expandingDirections() const = 0;
+ virtual void setGeometry( const TQRect& ) = 0;
+ virtual TQRect tqgeometry() const = 0;
+ virtual bool isEmpty() const = 0;
+ virtual bool hasHeightForWidth() const;
+ virtual int heightForWidth( int ) const;
+ // ### add minimumHeightForWidth( int ) in TQt 4.0
+ virtual void tqinvalidate();
+
+ virtual TQWidget *widget();
+ virtual TQLayoutIterator iterator();
+ virtual TQLayout *tqlayout();
+ virtual TQSpacerItem *tqspacerItem();
+
+ int tqalignment() const { return align; }
+ virtual void tqsetAlignment( int a );
+
+protected:
+ int align;
+};
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQSpacerItem : public QSpacerItem, virtual public TQt
+{
+public:
+ TQSpacerItem( int w, int h, TQSizePolicy::SizeType hData = TQSizePolicy::Minimum, TQSizePolicy::SizeType vData = TQSizePolicy::Minimum ) : QSpacerItem( w, h, hData, vData ) {}
+
+ TQSpacerItem *tqspacerItem(); // Used by tqabstractlayout.cpp
+ inline void changeSize( int w, int h, TQSizePolicy::SizeType hData = TQSizePolicy::Minimum, TQSizePolicy::SizeType vData = TQSizePolicy::Minimum ) { return QSpacerItem::changeSize( w, h, hData, vData ); }
+ TQ_SPExpandData expandingDirections() const; // Used by tqabstractlayout.cpp
+ bool isEmpty() const; // Used by tqabstractlayout.cpp
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSize() const;
+ TQSize tqmaximumSize() const;
+ void setGeometry( const TQRect &qr );
+ TQRect tqgeometry() const;
+
+ // Use the TQt virtual functions, not the built in Qt ones...
+ // This requires that the base virtual Qt functions be reimplemented so as to point to the TQt virtual functions instead as shown below.
+ // This way, when Trinity overrides a TQt virtual function, the calling Qt code will blithely use the overriden TQt function instead.
+ inline QSize sizeHint() const { return tqsizeHint(); }
+ inline QSize minimumSize() const { return tqminimumSize(); }
+ inline QSize maximumSize() const { return tqmaximumSize(); }
+ inline void setGeometry( const QRect &r ) { return TQSpacerItem::setGeometry( TQT_TQRECT_OBJECT(r) ); }
+ inline QRect geometry() { return tqgeometry(); }
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQSpacerItem : public TQLayoutItem
+{
+public:
+ TQSpacerItem( int w, int h,
+ TQSizePolicy::SizeType hData = TQSizePolicy::Minimum,
+ TQSizePolicy::SizeType vData = TQSizePolicy::Minimum )
+ : width( w ), height( h ), sizeP( hData, vData ) { }
+ void changeSize( int w, int h,
+ TQSizePolicy::SizeType hData = TQSizePolicy::Minimum,
+ TQSizePolicy::SizeType vData = TQSizePolicy::Minimum );
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSize() const;
+ TQSize tqmaximumSize() const;
+ TQ_SPExpandData expandingDirections() const;
+ bool isEmpty() const;
+ void setGeometry( const TQRect& );
+ TQRect tqgeometry() const;
+ TQSpacerItem *tqspacerItem();
+
+private:
+ int width;
+ int height;
+ TQSizePolicy sizeP;
+ TQRect rect;
+};
+
+#endif // USE_QT4
+
+class TQ_EXPORT TQWidgetItem : public TQLayoutItem
+{
+public:
+ TQWidgetItem( TQWidget *w ) : wid( w ) { }
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSize() const;
+ TQSize tqmaximumSize() const;
+ TQ_SPExpandData expandingDirections() const;
+ bool isEmpty() const;
+ void setGeometry( const TQRect& );
+ TQRect tqgeometry() const;
+ virtual TQWidget *widget();
+
+ bool hasHeightForWidth() const;
+ int heightForWidth( int ) const;
+
+ QLAYOUTITEM_REQUIRED_FUNCTIONS
+
+private:
+ TQWidget *wid;
+};
+
+#ifdef USE_QT4
+// #if 0
+
+extern int menuBarHeightForWidth( QWidget *menubar, int w );
+
+class TQ_EXPORT TQLayout : public QLayout, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ enum ResizeMode {
+ FreeResize = QLayout::SetNoConstraint,
+ Minimum = QLayout::SetMinimumSize,
+ Fixed = QLayout::SetFixedSize,
+ Auto = QLayout::SetDefaultConstraint
+ };
+
+ TQLayout( QWidget *tqparent, int margin = 0, int spacing = -1, const char *name = 0 );
+ TQLayout( QLayout *parentLayout, int spacing = -1, const char *name = 0 );
+ TQLayout( int spacing = -1, const char *name = 0 );
+ virtual TQ_SPExpandData expandingDirections() const;
+
+ TQLayout *tqlayout();
+ virtual TQSize tqsizeHint() const;
+ virtual TQSize tqminimumSize() const;
+ virtual TQSize tqmaximumSize() const;
+
+ TQWidget *mainWidget();
+ virtual void tqinvalidate();
+ virtual void invalidate();
+ virtual TQRect tqgeometry() const;
+ const char *tqname() const;
+ const char *name() const;
+ int tqalignment() const;
+
+ TQWidget *mainWidget() const;
+ void remove(QWidget *w);
+ void add(QWidget *w);
+ void setResizeMode(SizeConstraint s);
+ void setResizeMode(ResizeMode s);
+ SizeConstraint resizeMode() const;
+ ResizeMode tqresizeMode() const;
+ void setAutoAdd(bool a);
+ bool autoAdd() const;
+ void tqsetAlignment( int a );
+
+// bool isTopLevel() const;
+ void freeze( int w, int h );
+ void freeze() { setResizeMode( Fixed ); }
+
+ TQMetaObject *tqmetaObject() const;
+
+ // Required to interface correctly, as QLayout is not a derived class of TQWidget or TQObject
+public:
+ // TQt handler
+// virtual bool eventFilter( TQObject *, TQEvent * );
+
+ // Qt4 handler interface
+ bool eventFilter( QObject *q, QEvent *e );
+
+// TQt event handlers
+protected:
+ virtual bool event( TQEvent *e );
+
+// TQFocusData *focusData();
+ bool event( QEvent *e );
+// virtual void mousePressEvent( TQMouseEvent * ); // NOTE: All event handlers that can be subclassed must be declared here, and
+// virtual void mouseReleaseEvent( TQMouseEvent * ); // declared virtual, so that run time dynamic call resolution will occur
+// virtual void mouseDoubleClickEvent( TQMouseEvent * );
+// virtual void mouseMoveEvent( TQMouseEvent * );
+// #ifndef TQT_NO_WHEELEVENT
+// virtual void wheelEvent( TQWheelEvent * );
+// #endif
+// virtual void keyPressEvent( TQKeyEvent * );
+// virtual void keyReleaseEvent( TQKeyEvent * );
+// virtual void focusInEvent( TQFocusEvent * );
+// virtual void focusOutEvent( TQFocusEvent * );
+// virtual void enterEvent( TQEvent * );
+// virtual void leaveEvent( TQEvent * );
+// virtual void paintEvent( TQPaintEvent * );
+// virtual void moveEvent( TQMoveEvent * );
+// virtual void resizeEvent( TQResizeEvent * );
+// virtual void closeEvent( TQCloseEvent * );
+// virtual void contextMenuEvent( TQContextMenuEvent * );
+// virtual void imStartEvent( TQIMEvent * );
+// virtual void imComposeEvent( TQIMEvent * );
+// virtual void imEndEvent( TQIMEvent * );
+// virtual void tabletEvent( TQTabletEvent * );
+//
+// #ifndef TQT_NO_DRAGANDDROP
+// virtual void dragEnterEvent( TQDragEnterEvent * );
+// virtual void dragMoveEvent( TQDragMoveEvent * );
+// virtual void dragLeaveEvent( TQDragLeaveEvent * );
+// virtual void dropEvent( TQDropEvent * );
+// #endif
+//
+// virtual void showEvent( TQShowEvent * );
+// virtual void hideEvent( TQHideEvent * );
+
+// // Qt4 event handler interface
+// protected:
+// inline virtual void mousePressEvent(QMouseEvent *e) { mousePressEvent(static_cast<TQMouseEvent*>(e)); } // QLayout::mousePressEvent(e) }
+// inline virtual void mouseReleaseEvent(QMouseEvent *e) { mouseReleaseEvent(static_cast<TQMouseEvent*>(e)); } // QLayout::mouseReleaseEvent(e) }
+// inline virtual void mouseDoubleClickEvent(QMouseEvent *e) { mouseDoubleClickEvent(static_cast<TQMouseEvent*>(e)); } // QLayout::mouseDoubleClickEvent(e) }
+// inline virtual void mouseMoveEvent(QMouseEvent *e) { mouseMoveEvent(static_cast<TQMouseEvent*>(e)); } // QLayout::mouseMoveEvent(e) }
+// #ifndef QT_NO_WHEELEVENT
+// inline virtual void wheelEvent(QWheelEvent *e) { wheelEvent(static_cast<TQWheelEvent*>(e)); } // QLayout::wheelEvent(e) }
+// #endif
+// inline virtual void keyPressEvent(QKeyEvent *e) { keyPressEvent(static_cast<TQKeyEvent*>(e)); } // QLayout::keyPressEvent(e) }
+// inline virtual void keyReleaseEvent(QKeyEvent *e) { keyReleaseEvent(static_cast<TQKeyEvent*>(e)); } // QLayout::keyReleaseEvent(e) }
+// inline virtual void focusInEvent(QFocusEvent *e) { focusInEvent(static_cast<TQFocusEvent*>(e)); } // QLayout::focusInEvent(e) }
+// inline virtual void focusOutEvent(QFocusEvent *e) { focusOutEvent(static_cast<TQFocusEvent*>(e)); } // QLayout::focusOutEvent(e) }
+// inline virtual void enterEvent(QEvent *e) { enterEvent(static_cast<TQEvent*>(e)); } // QLayout::enterEvent(e) }
+// inline virtual void leaveEvent(QEvent *e) { leaveEvent(static_cast<TQEvent*>(e)); } // QLayout::leaveEvent(e) }
+// inline virtual void paintEvent(QPaintEvent *e) { paintEvent(static_cast<TQPaintEvent*>(e)); } // QLayout::paintEvent(e) }
+// inline virtual void moveEvent(QMoveEvent *e) { moveEvent(static_cast<TQMoveEvent*>(e)); } // QLayout::moveEvent(e) }
+// inline virtual void resizeEvent(QResizeEvent *e) { resizeEvent(static_cast<TQResizeEvent*>(e)); } // QLayout::resizeEvent(e) }
+// inline virtual void closeEvent(QCloseEvent *e) { closeEvent(static_cast<TQCloseEvent*>(e)); } // QLayout::closeEvent(e) }
+// #ifndef QT_NO_CONTEXTMENU
+// inline virtual void contextMenuEvent(QContextMenuEvent *e) { contextMenuEvent(static_cast<TQContextMenuEvent*>(e)); } // QLayout::contextMenuEvent(e); }
+// #endif
+// #ifndef QT_NO_TABLETEVENT
+// inline virtual void tabletEvent(QTabletEvent *e) { tabletEvent(static_cast<TQTabletEvent*>(e)); } // QLayout::tabletEvent(e) }
+// #endif
+// #ifndef QT_NO_ACTION
+// // inline virtual void actionEvent(QActionEvent *e) { actionEvent(static_cast<TQActionEvent*>(e)); QLayout::actionEvent(e) }
+// #endif
+//
+// // #ifndef QT_NO_DRAGANDDROP
+// // inline virtual void dragEnterEvent(QDragEnterEvent *e) { dragEnterEvent(static_cast<TQDragEnterEvent*>(e)); QLayout::dragEnterEvent(e) }
+// // inline virtual void dragMoveEvent(QDragMoveEvent *e) { dragMoveEvent(static_cast<TQDragMoveEvent*>(e)); QLayout::dragMoveEvent(e) }
+// // inline virtual void dragLeaveEvent(QDragLeaveEvent *e) { dragLeaveEvent(static_cast<TQDragLeaveEvent*>(e)); QLayout::dragLeaveEvent(e) }
+// // inline virtual void dropEvent(QDropEvent *e) { dropEvent(static_cast<TQDropEvent*>(e)); QLayout::dropEvent(e) }
+// // #endif
+//
+// inline virtual void showEvent(QShowEvent *e) { showEvent(static_cast<TQShowEvent*>(e)); } // QLayout::showEvent(e) }
+// inline virtual void hideEvent(QHideEvent *e) { hideEvent(static_cast<TQHideEvent*>(e)); } // QLayout::hideEvent(e) }
+
+// TQt event handlers
+protected:
+ virtual void timerEvent( TQTimerEvent * );
+ virtual void childEvent( TQChildEvent * );
+ virtual void customEvent( TQCustomEvent * );
+
+// Qt4 event handler interface
+protected:
+ virtual void timerEvent(QTimerEvent *e);
+ virtual void childEvent(QChildEvent *e);
+ virtual void customEvent(QEvent *e);
+
+protected:
+ bool eventFilter( TQObject *o, TQEvent *e );
+
+public:
+ // Interoperability
+ static const TQLayout& convertFromQLayout( QLayout& ql );
+
+// virtual void addItem( TQLayoutItem * ) = 0;
+ TQLayoutIterator iterator();
+
+ QLayout *layout();
+ virtual void setGeometry(const TQRect &r);
+
+ QLAYOUTITEM_REQUIRED_FUNCTIONS
+
+protected:
+ void setSupportsMargin( bool ); // Implemented in tqabstractlayout.cpp
+ TQRect alignmentRect( const TQRect& qr ) const;
+ void deleteAllItems();
+
+public Q_SLOTS:
+ void tqt_handle_qt_destroyed(QObject* obj);
+
+Q_SIGNALS:
+ void destroyed( TQObject* obj );
+
+private:
+ bool autoNewChild;
+ mutable TQString static_object_name;
+};
+
+// Interoperability
+inline static const TQLayout& convertFromQLayout( const QLayout& ql ) {
+ return (*static_cast<const TQLayout*>(&ql));
+}
+
+#else // USE_QT4
+
+class TQ_EXPORT TQLayout : public TQObject, public TQLayoutItem
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( ResizeMode )
+ Q_PROPERTY( int margin READ margin WRITE setMargin )
+ Q_PROPERTY( int spacing READ spacing WRITE setSpacing )
+ Q_PROPERTY( ResizeMode resizeMode READ resizeMode WRITE setResizeMode )
+
+public:
+ // ### TQt 4.0: put 'Auto' first in enum
+ enum ResizeMode { FreeResize, Minimum, Fixed, Auto };
+
+ TQLayout( TQWidget *tqparent, int margin = 0, int spacing = -1,
+ const char *name = 0 );
+ TQLayout( TQLayout *parentLayout, int spacing = -1, const char *name = 0 );
+ TQLayout( int spacing = -1, const char *name = 0 );
+ ~TQLayout();
+
+ int margin() const { return outsideBorder; }
+ int spacing() const { return insideSpacing; }
+
+ virtual void setMargin( int );
+ virtual void setSpacing( int );
+
+ int defaultBorder() const { return insideSpacing; }
+ void freeze( int w, int h );
+ void freeze() { setResizeMode( Fixed ); }
+
+ void setResizeMode( ResizeMode );
+ ResizeMode resizeMode() const;
+
+#ifndef TQT_NO_MENUBAR
+ virtual void setMenuBar( TQMenuBar *w );
+ TQMenuBar *menuBar() const { return menubar; }
+#endif
+
+ TQWidget *mainWidget();
+ bool isTopLevel() const { return topLevel; }
+
+ virtual void setAutoAdd( bool );
+ bool autoAdd() const { return autoNewChild; }
+
+ void tqinvalidate();
+ TQRect tqgeometry() const;
+ bool activate();
+
+ void add( TQWidget *w ) { addItem( new TQWidgetItem(w) ); }
+ virtual void addItem( TQLayoutItem * ) = 0;
+
+ void remove( TQWidget *w );
+ void removeItem( TQLayoutItem * );
+
+ TQ_SPExpandData expandingDirections() const;
+ TQSize tqminimumSize() const;
+ TQSize tqmaximumSize() const;
+ void setGeometry( const TQRect& ) = 0;
+ TQLayoutIterator iterator() = 0;
+ bool isEmpty() const;
+
+ int totalHeightForWidth( int w ) const;
+ TQSize totalMinimumSize() const;
+ TQSize totalMaximumSize() const;
+ TQSize totalSizeHint() const;
+ TQLayout *tqlayout();
+
+ bool supportsMargin() const { return marginImpl; }
+
+ void setEnabled( bool );
+ bool isEnabled() const;
+
+protected:
+ bool eventFilter( TQObject *, TQEvent * );
+ void childEvent( TQChildEvent *e );
+ void addChildLayout( TQLayout *l );
+ void deleteAllItems();
+
+ void setSupportsMargin( bool );
+ TQRect alignmentRect( const TQRect& ) const;
+
+private:
+ void setWidgetLayout( TQWidget *, TQLayout * );
+ void init();
+ int insideSpacing;
+ int outsideBorder;
+ uint topLevel : 1;
+ uint enabled : 1;
+ uint autoNewChild : 1;
+ uint frozen : 1;
+ uint activated : 1;
+ uint marginImpl : 1;
+ uint autoMinimum : 1;
+ uint autoResizeMode : 1;
+ TQRect rect;
+ TQLayoutData *extraData;
+#ifndef TQT_NO_MENUBAR
+ TQMenuBar *menubar;
+#endif
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQLayout( const TQLayout & );
+ TQLayout &operator=( const TQLayout & );
+#endif
+
+ static void propagateSpacing( TQLayout *tqlayout );
+};
+
+inline void TQLayoutIterator::deleteCurrent()
+{
+ delete takeCurrent();
+}
+#endif // USE_QT4
+
+#define QLAYOUT_REQUIRED_METHOD_DECLARATIONS \
+ int count() const; \
+ TQLayoutItem* itemAt(int index) const; \
+ TQLayoutItem* takeAt(int index); \
+ virtual inline QSize sizeHint() const { return tqsizeHint(); } \
+ virtual inline QSize minimumSize() const { return tqminimumSize(); } \
+ virtual inline QSize maximumSize() const { return tqmaximumSize(); } \
+ virtual inline void setGeometry( const QRect &r ) { return setGeometry( TQT_TQRECT_OBJECT(r) ); } \
+ virtual inline QRect geometry() const { return tqgeometry(); }
+
+#define QLAYOUT_REQUIRED_METHOD_IMPLEMENTATIONS \
+ inline int count() const { \
+ return data->list.count(); \
+ } \
+ \
+ inline TQLayoutItem* itemAt(int index) const { \
+ return index >= 0 && index < data->list.count() ? data->list.at(index)->item : 0; \
+ } \
+ \
+ inline TQLayoutItem* takeAt(int index) { \
+ if (index < 0 || index >= data->list.count()) \
+ return 0; \
+ TQBoxLayoutItem *b = data->list.take(index); \
+ TQLayoutItem *item = b->item; \
+ b->item = 0; \
+ delete b; \
+ \
+ invalidate(); \
+ return item; \
+ }
+
+#if 0
+
+class TQ_EXPORT TQGridLayout : public QGridLayout, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQGridLayout( TQWidget *tqparent, int nRows = 1, int nCols = 1, int border = 0, int spacing = -1, const char *name = 0 ) : QGridLayout( tqparent ), autoNewChild(false)
+ {
+ expand(nRows, nCols);
+ setMargin(border);
+ setSpacing(spacing < 0 ? border : spacing);
+ setObjectName(QString::fromAscii(name));
+ if ( tqparent ) tqparent->installEventFilter( this );
+ TQT_TQOBJECT_REQUIRED_INITIALIZATION(tqparent)
+ }
+ TQGridLayout( int nRows = 1, int nCols = 1, int spacing = -1, const char *name = 0 ) : QGridLayout(), autoNewChild(false)
+ {
+ expand(nRows, nCols);
+ setSpacing(spacing);
+ setObjectName(QString::fromAscii(name));
+ }
+ TQGridLayout( QLayout *parentLayout, int nRows = 1, int nCols = 1, int spacing = -1, const char *name = 0 ) : QGridLayout(), autoNewChild(false)
+ {
+ expand(nRows, nCols);
+ if (spacing == -1) {setSpacing(parentLayout->spacing());} else {setSpacing(spacing);};
+ setObjectName(QString::fromAscii(name));
+ if ( parentLayout ) parentLayout->addItem(this);
+ if ( parentLayout ) parentLayout->installEventFilter( this );
+ TQT_TQOBJECT_REQUIRED_INITIALIZATION(parentLayout)
+ }
+
+ void expand( int rows, int cols ) {
+ // Nasty, nasty HACK
+ // Yet another example of lost functionality in Qt4...sigh...
+ QSpacerItem *hack= new QSpacerItem(1,1);
+ addItem(hack, (rows != -1) ? rows-1 : 0, (cols != -1) ? cols-1 : 0);
+ QGridLayout::removeItem(hack);
+ delete hack;
+ }
+
+ inline TQSize tqsizeHint() const { return sizeHint(); }
+ inline TQSize tqminimumSize() const { return minimumSize(); }
+ inline TQSize tqmaximumSize() const { return maximumSize(); }
+ inline void tqinvalidate() { invalidate(); }
+
+ inline TQRect tqgeometry() const { return geometry(); }
+
+ inline TQWidget *mainWidget() const { return TQT_TQWIDGET(parentWidget()); }
+ inline void remove(QWidget *w) { removeWidget(w); }
+ inline void add(QWidget *w) { addWidget(w); }
+ inline void setResizeMode(SizeConstraint s) {setSizeConstraint(s);}
+ inline void setResizeMode(TQLayout::ResizeMode s) {setResizeMode((SizeConstraint)s);}
+ inline SizeConstraint resizeMode() const {return sizeConstraint();}
+ inline void setAutoAdd(bool a) { autoNewChild = a; }
+ inline bool autoAdd() const { return autoNewChild; }
+
+ inline void addRowSpacing(int row, int minsize) { addItem(new QSpacerItem(0,minsize), row, 0); }
+ inline void addColSpacing(int col, int minsize) { addItem(new QSpacerItem(minsize,0), 0, col); }
+ inline void addMultiCellWidget(QWidget *w, int fromRow, int toRow, int fromCol, int toCol, Qt::Alignment _align = 0) { addWidget(w, fromRow, fromCol, (toRow < 0) ? -1 : toRow - fromRow + 1, (toCol < 0) ? -1 : toCol - fromCol + 1, _align); }
+ inline void addMultiCell(QLayoutItem *l, int fromRow, int toRow, int fromCol, int toCol, Qt::Alignment _align = 0) { addItem(l, fromRow, fromCol, (toRow < 0) ? -1 : toRow - fromRow + 1, (toCol < 0) ? -1 : toCol - fromCol + 1, _align); }
+ inline void addMultiCellLayout(QLayout *layout, int fromRow, int toRow, int fromCol, int toCol, Qt::Alignment _align = 0) { addLayout(layout, fromRow, fromCol, (toRow < 0) ? -1 : toRow - fromRow + 1, (toCol < 0) ? -1 : toCol - fromCol + 1, _align); }
+
+ inline int numRows() const { return rowCount(); }
+ inline int numCols() const { return columnCount(); }
+ inline void setColStretch(int col, int stretch) {setColumnStretch(col, stretch); }
+ inline int colStretch(int col) const {return columnStretch(col); }
+ inline void setColSpacing(int col, int minSize) { setColumnMinimumWidth(col, minSize); }
+ inline int colSpacing(int col) const { return columnMinimumWidth(col); }
+ inline void setRowSpacing(int row, int minSize) {setRowMinimumHeight(row, minSize); }
+ inline int rowSpacing(int row) const {return rowMinimumHeight(row); }
+
+ virtual void tqsetAlignment( int a );
+
+ // Required to interface correctly, as QLayout is not a derived class of TQWidget or TQObject
+public:
+ // TQt handler
+// virtual bool eventFilter( TQObject *, TQEvent * );
+
+ // Qt4 handler interface
+ inline bool eventFilter( QObject *q, QEvent *e ) { return eventFilter(static_cast<TQObject*>(q), static_cast<TQEvent*>(e)); }
+
+// TQt event handlers
+protected:
+// virtual bool event( TQEvent *e );
+
+// TQFocusData *focusData();
+// inline bool event( QEvent *e ) { return event(static_cast<TQEvent*>(e)); }
+ virtual void mousePressEvent( TQMouseEvent * ); // NOTE: All event handlers that can be subclassed must be declared here, and
+ virtual void mouseReleaseEvent( TQMouseEvent * ); // declared virtual, so that run time dynamic call resolution will occur
+ virtual void mouseDoubleClickEvent( TQMouseEvent * );
+ virtual void mouseMoveEvent( TQMouseEvent * );
+#ifndef TQT_NO_WHEELEVENT
+ virtual void wheelEvent( TQWheelEvent * );
+#endif
+ virtual void keyPressEvent( TQKeyEvent * );
+ virtual void keyReleaseEvent( TQKeyEvent * );
+ virtual void focusInEvent( TQFocusEvent * );
+ virtual void focusOutEvent( TQFocusEvent * );
+ virtual void enterEvent( TQEvent * );
+ virtual void leaveEvent( TQEvent * );
+ virtual void paintEvent( TQPaintEvent * );
+ virtual void moveEvent( TQMoveEvent * );
+ virtual void resizeEvent( TQResizeEvent * );
+ virtual void closeEvent( TQCloseEvent * );
+ virtual void contextMenuEvent( TQContextMenuEvent * );
+ virtual void imStartEvent( TQIMEvent * );
+ virtual void imComposeEvent( TQIMEvent * );
+ virtual void imEndEvent( TQIMEvent * );
+ virtual void tabletEvent( TQTabletEvent * );
+
+#ifndef TQT_NO_DRAGANDDROP
+ virtual void dragEnterEvent( TQDragEnterEvent * );
+ virtual void dragMoveEvent( TQDragMoveEvent * );
+ virtual void dragLeaveEvent( TQDragLeaveEvent * );
+ virtual void dropEvent( TQDropEvent * );
+#endif
+
+ virtual void showEvent( TQShowEvent * );
+ virtual void hideEvent( TQHideEvent * );
+
+// Qt4 event handler interface
+protected:
+ inline virtual void mousePressEvent(QMouseEvent *e) { mousePressEvent(static_cast<TQMouseEvent*>(e)); } // QGridLayout::mousePressEvent(e) }
+ inline virtual void mouseReleaseEvent(QMouseEvent *e) { mouseReleaseEvent(static_cast<TQMouseEvent*>(e)); } // QGridLayout::mouseReleaseEvent(e) }
+ inline virtual void mouseDoubleClickEvent(QMouseEvent *e) { mouseDoubleClickEvent(static_cast<TQMouseEvent*>(e)); } // QGridLayout::mouseDoubleClickEvent(e) }
+ inline virtual void mouseMoveEvent(QMouseEvent *e) { mouseMoveEvent(static_cast<TQMouseEvent*>(e)); } // QGridLayout::mouseMoveEvent(e) }
+#ifndef QT_NO_WHEELEVENT
+ inline virtual void wheelEvent(QWheelEvent *e) { wheelEvent(static_cast<TQWheelEvent*>(e)); } // QGridLayout::wheelEvent(e) }
+#endif
+ inline virtual void keyPressEvent(QKeyEvent *e) { keyPressEvent(static_cast<TQKeyEvent*>(e)); } // QGridLayout::keyPressEvent(e) }
+ inline virtual void keyReleaseEvent(QKeyEvent *e) { keyReleaseEvent(static_cast<TQKeyEvent*>(e)); } // QGridLayout::keyReleaseEvent(e) }
+ inline virtual void focusInEvent(QFocusEvent *e) { focusInEvent(static_cast<TQFocusEvent*>(e)); } // QGridLayout::focusInEvent(e) }
+ inline virtual void focusOutEvent(QFocusEvent *e) { focusOutEvent(static_cast<TQFocusEvent*>(e)); } // QGridLayout::focusOutEvent(e) }
+ inline virtual void enterEvent(QEvent *e) { enterEvent(static_cast<TQEvent*>(e)); } // QGridLayout::enterEvent(e) }
+ inline virtual void leaveEvent(QEvent *e) { leaveEvent(static_cast<TQEvent*>(e)); } // QGridLayout::leaveEvent(e) }
+ inline virtual void paintEvent(QPaintEvent *e) { paintEvent(static_cast<TQPaintEvent*>(e)); } // QGridLayout::paintEvent(e) }
+ inline virtual void moveEvent(QMoveEvent *e) { moveEvent(static_cast<TQMoveEvent*>(e)); } // QGridLayout::moveEvent(e) }
+ inline virtual void resizeEvent(QResizeEvent *e) { resizeEvent(static_cast<TQResizeEvent*>(e)); } // QGridLayout::resizeEvent(e) }
+ inline virtual void closeEvent(QCloseEvent *e) { closeEvent(static_cast<TQCloseEvent*>(e)); } // QGridLayout::closeEvent(e) }
+#ifndef QT_NO_CONTEXTMENU
+ inline virtual void contextMenuEvent(QContextMenuEvent *e { contextMenuEvent(static_cast<TQContextMenuEvent*>(e)); QGridLayout::contextMenuEvent(e) }
+#endif
+#ifndef QT_NO_TABLETEVENT
+ inline virtual void tabletEvent(QTabletEvent *e) { tabletEvent(static_cast<TQTabletEvent*>(e)); } // QGridLayout::tabletEvent(e) }
+#endif
+#ifndef QT_NO_ACTION
+// inline virtual void actionEvent(QActionEvent *e) { actionEvent(static_cast<TQActionEvent*>(e)); QGridLayout::actionEvent(e) }
+#endif
+
+// #ifndef QT_NO_DRAGANDDROP
+// inline virtual void dragEnterEvent(QDragEnterEvent *e) { dragEnterEvent(static_cast<TQDragEnterEvent*>(e)); QGridLayout::dragEnterEvent(e) }
+// inline virtual void dragMoveEvent(QDragMoveEvent *e) { dragMoveEvent(static_cast<TQDragMoveEvent*>(e)); QGridLayout::dragMoveEvent(e) }
+// inline virtual void dragLeaveEvent(QDragLeaveEvent *e) { dragLeaveEvent(static_cast<TQDragLeaveEvent*>(e)); QGridLayout::dragLeaveEvent(e) }
+// inline virtual void dropEvent(QDropEvent *e) { dropEvent(static_cast<TQDropEvent*>(e)); QGridLayout::dropEvent(e) }
+// #endif
+
+ inline virtual void showEvent(QShowEvent *e) { showEvent(static_cast<TQShowEvent*>(e)); } // QGridLayout::showEvent(e) }
+ inline virtual void hideEvent(QHideEvent *e) { hideEvent(static_cast<TQHideEvent*>(e)); } // QGridLayout::hideEvent(e) }
+
+// TQt event handlers
+protected:
+ virtual void timerEvent( TQTimerEvent * );
+ virtual void childEvent( TQChildEvent * );
+ virtual void customEvent( TQCustomEvent * );
+
+// Qt4 event handler interface
+protected:
+ inline virtual void timerEvent(QTimerEvent *e) { timerEvent(static_cast<TQTimerEvent*>(e)); } // QGridLayout::timerEvent(e) }
+ inline virtual void childEvent(QChildEvent *e) { TQT_TQOBJECT_CHILDEVENT_CONDITIONAL childEvent(static_cast<TQChildEvent*>(e)); } // QGridLayout::childEvent(e) }
+// inline virtual void customEvent(QCustomEvent *e) { customEvent(static_cast<TQCustomEvent*>(e)); }
+
+// protected:
+// bool eventFilter( TQObject *o, TQEvent *e ) {
+// TQ_UNUSED(o);
+// if (e->type() == TQEvent::ChildInserted) {
+// if (autoNewChild) {
+// QChildEvent *c = (QChildEvent *)e;
+// if (c->child()->isWidgetType()) {
+// QWidget *w = (QWidget *)c->child();
+// if (!w->isWindow()) {
+// addWidget(w);
+// }
+// }
+// }
+// }
+// else if (e->type() == TQEvent::LayoutHint) {
+// // d->activated = false;
+// if (parent()) {
+// if (static_cast<QWidget *>(parent())->isVisible()) {
+// activate();
+// }
+// }
+// }
+// return FALSE;
+// }
+
+// Taken from TQLayout above
+protected:
+ bool eventFilter( TQObject *o, TQEvent *e ) {
+ TQ_UNUSED(o);
+
+ if (e->type() == TQEvent::Resize) {
+ activate();
+ TQResizeEvent *r = (TQResizeEvent *)e;
+ int mbh = 0;
+#ifndef TQT_NO_MENUBAR
+ mbh = menuBarHeightForWidth( menuBar(), r->size().width() );
+#endif
+// int b = marginImpl ? 0 : outsideBorder;
+ int b = 0;
+ setGeometry( TQRect( b, mbh + b, r->size().width() - 2 * b, r->size().height() - mbh - 2 * b ) );
+ }
+
+ else if (e->type() == TQEvent::ChildInserted) {
+ if (autoNewChild) {
+ QChildEvent *c = (QChildEvent *)e;
+ if (c->child()->isWidgetType()) {
+ QWidget *w = (QWidget *)c->child();
+ if (!w->isWindow()) {
+// #if !defined(QT_NO_MENUBAR) && !defined(QT_NO_TOOLBAR)
+// if (qobject_cast<QMenuBar*>(w) && !qobject_cast<QToolBar*>(w->parentWidget())) {
+// setMenuBar( (QMenuBar *)w );
+// invalidate();
+// } else
+// #endif
+// #ifndef QT_NO_SIZEGRIP
+// if (qobject_cast<QSizeGrip*>(w) ) {
+// //SizeGrip is handled by the dialog itself.
+// } else
+// #endif
+// addItem(QLayoutPrivate::createWidgetItem(this, w));
+ addWidget(w);
+ }
+ }
+ }
+ }
+ else if (e->type() == TQEvent::LayoutHint) {
+// d->d = false;
+ if (parent()) {
+ if (static_cast<QWidget *>(parent())->isVisible()) {
+ activate();
+ }
+ }
+ }
+ return FALSE;
+ }
+
+public:
+ virtual void setGeometry(const TQRect &r) { return QGridLayout::setGeometry(r); }
+ virtual inline void setGeometry(const QRect &r) { return setGeometry(TQT_TQRECT_OBJECT(r)); }
+
+public Q_SLOTS:
+ void tqt_handle_qt_destroyed(QObject* obj) { emit destroyed(TQT_TQOBJECT(obj)); }
+
+Q_SIGNALS:
+ void destroyed( TQObject* obj );
+
+private:
+ bool autoNewChild;
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQGridLayout : public TQLayout
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQGridLayout( TQWidget *tqparent, int nRows = 1, int nCols = 1, int border = 0,
+ int spacing = -1, const char *name = 0 );
+ TQGridLayout( int nRows = 1, int nCols = 1, int spacing = -1,
+ const char *name = 0 );
+ TQGridLayout( TQLayout *parentLayout, int nRows = 1, int nCols = 1,
+ int spacing = -1, const char *name = 0 );
+ ~TQGridLayout();
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSize() const;
+ TQSize tqmaximumSize() const;
+
+ // ### remove 'virtual' in 4.0 (or add 'virtual' to set{Row,Col}Spacing())
+ virtual void setRowStretch( int row, int stretch );
+ virtual void setColStretch( int col, int stretch );
+ int rowStretch( int row ) const;
+ int colStretch( int col ) const;
+
+ void setRowSpacing( int row, int minSize );
+ void setColSpacing( int col, int minSize );
+ int rowSpacing( int row ) const;
+ int colSpacing( int col ) const;
+
+ int numRows() const;
+ int numCols() const;
+ TQRect cellGeometry( int row, int col ) const;
+
+ bool hasHeightForWidth() const;
+ int heightForWidth( int ) const;
+ int minimumHeightForWidth( int ) const;
+
+ TQ_SPExpandData expandingDirections() const;
+ void tqinvalidate();
+
+ void addItem( QLayoutItem * );
+ void addItem( QLayoutItem *item, int row, int col );
+ void addMultiCell( QLayoutItem *, int fromRow, int toRow,
+ int fromCol, int toCol, int align = 0 );
+
+ void addWidget( TQWidget *, int row, int col, int align = 0 );
+ void addMultiCellWidget( TQWidget *, int fromRow, int toRow,
+ int fromCol, int toCol, int align = 0 );
+ void addLayout( TQLayout *tqlayout, int row, int col);
+ void addMultiCellLayout( TQLayout *tqlayout, int fromRow, int toRow,
+ int fromCol, int toCol, int align = 0 );
+ void addRowSpacing( int row, int minsize );
+ void addColSpacing( int col, int minsize );
+
+ void expand( int rows, int cols );
+
+ enum Corner { TopLeft, TopRight, BottomLeft, BottomRight };
+ void setOrigin( Corner );
+ Corner origin() const;
+// TQLayoutIterator iterator();
+ void setGeometry( const TQRect& );
+
+#ifdef USE_QT4
+
+ QLAYOUT_REQUIRED_METHOD_DECLARATIONS
+
+#endif // USE_QT4
+
+protected:
+ bool tqfindWidget( TQWidget* w, int *r, int *c );
+ void add( TQLayoutItem*, int row, int col );
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQGridLayout( const TQGridLayout & );
+ TQGridLayout &operator=( const TQGridLayout & );
+#endif
+
+ void init( int rows, int cols );
+ TQGridLayoutData *data;
+};
+
+#endif // USE_QT4
+
+class TQBoxLayoutData;
+class TQDockWindow;
+
+class TQ_EXPORT TQBoxLayout : public TQLayout
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ enum Direction { LeftToRight, RightToLeft, TopToBottom, BottomToTop,
+ Down = TopToBottom, Up = BottomToTop };
+
+ TQBoxLayout( TQWidget *tqparent, Direction, int border = 0, int spacing = -1,
+ const char *name = 0 );
+ TQBoxLayout( TQLayout *parentLayout, Direction, int spacing = -1,
+ const char *name = 0 );
+ TQBoxLayout( Direction, int spacing = -1, const char *name = 0 );
+ ~TQBoxLayout();
+
+ void addItem( QLayoutItem * );
+
+ Direction direction() const { return dir; }
+ void setDirection( Direction );
+
+ void addSpacing( int size );
+ void addStretch( int stretch = 0 );
+ void addWidget( TQWidget *, int stretch = 0, int tqalignment = 0 );
+ void addLayout( TQLayout *tqlayout, int stretch = 0 );
+ void addStrut( int );
+
+ void insertSpacing( int index, int size );
+ void insertStretch( int index, int stretch = 0 );
+ void insertWidget( int index, TQWidget *widget, int stretch = 0,
+ int tqalignment = 0 );
+ void insertLayout( int index, TQLayout *tqlayout, int stretch = 0 );
+
+ bool setStretchFactor( TQWidget*, int stretch );
+ bool setStretchFactor( TQLayout *l, int stretch );
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSize() const;
+ TQSize tqmaximumSize() const;
+
+ bool hasHeightForWidth() const;
+ int heightForWidth( int ) const;
+ int minimumHeightForWidth( int ) const;
+
+ TQ_SPExpandData expandingDirections() const;
+ void tqinvalidate();
+// TQLayoutIterator iterator();
+ void setGeometry( const TQRect& );
+
+ int tqfindWidget( TQWidget* w );
+
+#ifdef USE_QT4
+
+ QLAYOUT_REQUIRED_METHOD_DECLARATIONS
+
+#endif // USE_QT4
+
+protected:
+ void insertItem( int index, TQLayoutItem * );
+
+private:
+ friend class TQDockWindow;
+#if defined(TQ_DISABLE_COPY)
+ TQBoxLayout( const TQBoxLayout & );
+ TQBoxLayout &operator=( const TQBoxLayout & );
+#endif
+
+ void setupGeom();
+ void calcHfw( int );
+ TQBoxLayoutData *data;
+ Direction dir;
+ TQBoxLayout *createTmpCopy();
+};
+
+class TQ_EXPORT TQHBoxLayout : public TQBoxLayout
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQHBoxLayout( TQWidget *tqparent, int border = 0,
+ int spacing = -1, const char *name = 0 );
+ TQHBoxLayout( TQLayout *parentLayout,
+ int spacing = -1, const char *name = 0 );
+ TQHBoxLayout( int spacing = -1, const char *name = 0 );
+
+ ~TQHBoxLayout();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQHBoxLayout( const TQHBoxLayout & );
+ TQHBoxLayout &operator=( const TQHBoxLayout & );
+#endif
+};
+
+class TQ_EXPORT TQVBoxLayout : public TQBoxLayout
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQVBoxLayout( TQWidget *tqparent, int border = 0,
+ int spacing = -1, const char *name = 0 );
+ TQVBoxLayout( TQLayout *parentLayout,
+ int spacing = -1, const char *name = 0 );
+ TQVBoxLayout( int spacing = -1, const char *name = 0 );
+
+ ~TQVBoxLayout();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQVBoxLayout( const TQVBoxLayout & );
+ TQVBoxLayout &operator=( const TQVBoxLayout & );
+#endif
+};
+
+#endif // TQT_NO_LAYOUT
+#endif // TQLAYOUT_H
diff --git a/tqtinterface/qt4/src/kernel/tqlayoutengine.cpp b/tqtinterface/qt4/src/kernel/tqlayoutengine.cpp
new file mode 100644
index 0000000..7dca5e0
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqlayoutengine.cpp
@@ -0,0 +1,322 @@
+/****************************************************************************
+**
+** Implementation of TQLayout functionality
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqlayout.h"
+#include "private/tqlayoutengine_p.h"
+
+#ifndef TQT_NO_LAYOUT
+
+static inline int toFixed( int i ) { return i * 256; }
+static inline int fRound( int i ) {
+ return ( i % 256 < 128 ) ? i / 256 : 1 + i / 256;
+}
+
+/*
+ This is the main workhorse of the TQGridLayout. It portions out
+ available space to the chain's tqchildren.
+
+ The calculation is done in fixed point: "fixed" variables are
+ scaled by a factor of 256.
+
+ If the tqlayout runs "backwards" (i.e. RightToLeft or Up) the tqlayout
+ is computed mirror-reversed, and it's the caller's responsibility
+ do reverse the values before use.
+
+ chain tqcontains input and output parameters describing the tqgeometry.
+ count is the count of items in the chain; pos and space give the
+ interval (relative to parentWidget topLeft).
+*/
+TQ_EXPORT void qGeomCalc( TQMemArray<TQLayoutStruct> &chain, int start, int count,
+ int pos, int space, int spacer )
+{
+ typedef int fixed;
+ int cHint = 0;
+ int cMin = 0;
+ int cMax = 0;
+ int sumStretch = 0;
+ int spacerCount = 0;
+
+ bool wannaGrow = FALSE; // anyone who really wants to grow?
+ // bool canShrink = FALSE; // anyone who could be persuaded to shrink?
+
+ int i;
+ for ( i = start; i < start + count; i++ ) {
+ chain[i].done = FALSE;
+ cHint += chain[i].smartSizeHint();
+ cMin += chain[i].tqminimumSize;
+ cMax += chain[i].tqmaximumSize;
+ sumStretch += chain[i].stretch;
+ if ( !chain[i].empty )
+ spacerCount++;
+ wannaGrow = wannaGrow || chain[i].expansive || chain[i].stretch > 0;
+ }
+
+ int extraspace = 0;
+ if ( spacerCount )
+ spacerCount--; // only spacers between things
+ if ( space < cMin + spacerCount * spacer ) {
+ for ( i = start; i < start+count; i++ ) {
+ chain[i].size = chain[i].tqminimumSize;
+ chain[i].done = TRUE;
+ }
+ } else if ( space < cHint + spacerCount*spacer ) {
+ /*
+ Less space than smartSizeHint(), but more than tqminimumSize.
+ Currently take space equally from each, as in TQt 2.x.
+ Commented-out lines will give more space to stretchier
+ items.
+ */
+ int n = count;
+ int space_left = space - spacerCount*spacer;
+ int overdraft = cHint - space_left;
+
+ // first give to the fixed ones:
+ for ( i = start; i < start + count; i++ ) {
+ if ( !chain[i].done
+ && chain[i].tqminimumSize >= chain[i].smartSizeHint() ) {
+ chain[i].size = chain[i].smartSizeHint();
+ chain[i].done = TRUE;
+ space_left -= chain[i].smartSizeHint();
+ // sumStretch -= chain[i].stretch;
+ n--;
+ }
+ }
+ bool finished = n == 0;
+ while ( !finished ) {
+ finished = TRUE;
+ fixed fp_over = toFixed( overdraft );
+ fixed fp_w = 0;
+
+ for ( i = start; i < start+count; i++ ) {
+ if ( chain[i].done )
+ continue;
+ // if ( sumStretch <= 0 )
+ fp_w += fp_over / n;
+ // else
+ // fp_w += (fp_over * chain[i].stretch) / sumStretch;
+ int w = fRound( fp_w );
+ chain[i].size = chain[i].smartSizeHint() - w;
+ fp_w -= toFixed( w ); // give the difference to the next
+ if ( chain[i].size < chain[i].tqminimumSize ) {
+ chain[i].done = TRUE;
+ chain[i].size = chain[i].tqminimumSize;
+ finished = FALSE;
+ overdraft -= ( chain[i].smartSizeHint()
+ - chain[i].tqminimumSize );
+ // sumStretch -= chain[i].stretch;
+ n--;
+ break;
+ }
+ }
+ }
+ } else { // extra space
+ int n = count;
+ int space_left = space - spacerCount*spacer;
+ // first give to the fixed ones, and handle non-expansiveness
+ for ( i = start; i < start + count; i++ ) {
+ if ( !chain[i].done
+ && (chain[i].tqmaximumSize <= chain[i].smartSizeHint()
+ || (wannaGrow && !chain[i].expansive && chain[i].stretch == 0)) ) {
+ chain[i].size = chain[i].smartSizeHint();
+ chain[i].done = TRUE;
+ space_left -= chain[i].smartSizeHint();
+ sumStretch -= chain[i].stretch;
+ n--;
+ }
+ }
+ extraspace = space_left;
+
+ /*
+ Do a trial distribution and calculate how much it is off.
+ If there are more deficit pixels than surplus pixels, give
+ the minimum size items what they need, and repeat.
+ Otherwise give to the maximum size items, and repeat.
+
+ Paul Olav Tvete has a wonderful mathematical proof of the
+ correctness of this principle, but unfortunately this
+ comment is too small to contain it.
+ */
+ int surplus, deficit;
+ do {
+ surplus = deficit = 0;
+ fixed fp_space = toFixed( space_left );
+ fixed fp_w = 0;
+ for ( i = start; i < start+count; i++ ) {
+ if ( chain[i].done )
+ continue;
+ extraspace = 0;
+ if ( sumStretch <= 0 )
+ fp_w += fp_space / n;
+ else
+ fp_w += (fp_space * chain[i].stretch) / sumStretch;
+ int w = fRound( fp_w );
+ chain[i].size = w;
+ fp_w -= toFixed( w ); // give the difference to the next
+ if ( w < chain[i].smartSizeHint() ) {
+ deficit += chain[i].smartSizeHint() - w;
+ } else if ( w > chain[i].tqmaximumSize ) {
+ surplus += w - chain[i].tqmaximumSize;
+ }
+ }
+ if ( deficit > 0 && surplus <= deficit ) {
+ // give to the ones that have too little
+ for ( i = start; i < start+count; i++ ) {
+ if ( !chain[i].done &&
+ chain[i].size < chain[i].smartSizeHint() ) {
+ chain[i].size = chain[i].smartSizeHint();
+ chain[i].done = TRUE;
+ space_left -= chain[i].smartSizeHint();
+ sumStretch -= chain[i].stretch;
+ n--;
+ }
+ }
+ }
+ if ( surplus > 0 && surplus >= deficit ) {
+ // take from the ones that have too much
+ for ( i = start; i < start+count; i++ ) {
+ if ( !chain[i].done &&
+ chain[i].size > chain[i].tqmaximumSize ) {
+ chain[i].size = chain[i].tqmaximumSize;
+ chain[i].done = TRUE;
+ space_left -= chain[i].tqmaximumSize;
+ sumStretch -= chain[i].stretch;
+ n--;
+ }
+ }
+ }
+ } while ( n > 0 && surplus != deficit );
+ if ( n == 0 )
+ extraspace = space_left;
+ }
+
+ /*
+ As a last resort, we distribute the unwanted space equally
+ among the spacers (counting the start and end of the chain). We
+ could, but don't, attempt a sub-pixel allocation of the extra
+ space.
+ */
+ int extra = extraspace / ( spacerCount + 2 );
+ int p = pos + extra;
+ for ( i = start; i < start+count; i++ ) {
+ chain[i].pos = p;
+ p = p + chain[i].size;
+ if ( !chain[i].empty )
+ p += spacer+extra;
+ }
+}
+
+TQ_EXPORT TQSize tqSmartMinSize( const TQWidgetItem *i )
+{
+ TQWidget *w = ((TQWidgetItem *)i)->widget();
+
+ TQSize s( 0, 0 );
+ if ( w->tqlayout() ) {
+ s = w->tqlayout()->totalMinimumSize();
+ } else {
+ TQSize sh;
+
+ if ( TQT_TQSIZEPOLICY_OBJECT(w->sizePolicy()).horData() != TQSizePolicy::Ignored ) {
+ if ( TQT_TQSIZEPOLICY_OBJECT(w->sizePolicy()).mayShrinkHorizontally() ) {
+ s.setWidth( w->tqminimumSizeHint().width() );
+ } else {
+ sh = w->tqsizeHint();
+ s.setWidth( sh.width() );
+ }
+ }
+
+ if ( TQT_TQSIZEPOLICY_OBJECT(w->sizePolicy()).verData() != TQSizePolicy::Ignored ) {
+ if ( TQT_TQSIZEPOLICY_OBJECT(w->sizePolicy()).mayShrinkVertically() ) {
+ s.setHeight( w->tqminimumSizeHint().height() );
+ } else {
+ s.setHeight( sh.isValid() ? sh.height()
+ : w->tqsizeHint().height() );
+ }
+ }
+ }
+ s = s.boundedTo( w->tqmaximumSize() );
+ TQSize min = w->tqminimumSize();
+ if ( min.width() > 0 )
+ s.setWidth( min.width() );
+ if ( min.height() > 0 )
+ s.setHeight( min.height() );
+
+ if ( i->hasHeightForWidth() && min.height() == 0 && min.width() > 0 )
+ s.setHeight( i->heightForWidth(s.width()) );
+
+ s = s.expandedTo( TQSize(1, 1) );
+ return s;
+}
+
+TQ_EXPORT TQSize tqSmartMinSize( TQWidget *w )
+{
+ TQWidgetItem item( w );
+ return tqSmartMinSize( &item );
+}
+
+TQ_EXPORT TQSize tqSmartMaxSize( const TQWidgetItem *i, int align )
+{
+ TQWidget *w = ( (TQWidgetItem*)i )->widget();
+ if ( align & TQt::AlignHorizontal_Mask && align & TQt::AlignVertical_Mask )
+ return TQSize( TQLAYOUTSIZE_MAX, TQLAYOUTSIZE_MAX );
+ TQSize s = w->tqmaximumSize();
+ if ( s.width() == TQWIDGETSIZE_MAX && !(align & TQt::AlignHorizontal_Mask) )
+ if ( !TQT_TQSIZEPOLICY_OBJECT(w->sizePolicy()).mayGrowHorizontally() )
+ s.setWidth( w->tqsizeHint().width() );
+
+ if ( s.height() == TQWIDGETSIZE_MAX && !(align & TQt::AlignVertical_Mask) )
+ if ( !TQT_TQSIZEPOLICY_OBJECT(w->sizePolicy()).mayGrowVertically() )
+ s.setHeight( w->tqsizeHint().height() );
+
+ s = s.expandedTo( w->tqminimumSize() );
+
+ if ( align & TQt::AlignHorizontal_Mask )
+ s.setWidth( TQLAYOUTSIZE_MAX );
+ if ( align & TQt::AlignVertical_Mask )
+ s.setHeight( TQLAYOUTSIZE_MAX );
+ return s;
+}
+
+TQ_EXPORT TQSize tqSmartMaxSize( TQWidget *w, int align )
+{
+ TQWidgetItem item( w );
+ return tqSmartMaxSize( &item, align );
+}
+
+#endif // TQT_NO_LAYOUT
diff --git a/tqtinterface/qt4/src/kernel/tqlayoutengine_p.h b/tqtinterface/qt4/src/kernel/tqlayoutengine_p.h
new file mode 100644
index 0000000..9c8064b
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqlayoutengine_p.h
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Internal header file.
+**
+** Created : 981027
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLAYOUTENGINE_P_H
+#define TQLAYOUTENGINE_P_H
+
+#ifndef TQLAYOUT_H
+ #error "Need to include tqlayout.h before including qtqlayoutengine_p.h"
+#endif
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qtqlayout.cpp, tqlayoutengine.cpp, qmainwindow.cpp and qsplitter.cpp.
+// This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+//
+
+
+#ifndef TQT_H
+#include "tqabstractlayout.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_LAYOUT
+
+struct TQLayoutStruct
+{
+ inline void init( int stretchFactor = 0, int spacing = 0 ) {
+ stretch = stretchFactor;
+ tqminimumSize = tqsizeHint = spacing;
+ tqmaximumSize = TQLAYOUTSIZE_MAX;
+ expansive = FALSE;
+ empty = TRUE;
+ }
+
+ TQCOORD smartSizeHint() {
+ return ( stretch > 0 ) ? tqminimumSize : tqsizeHint;
+ }
+
+ // parameters
+ int stretch;
+ TQCOORD tqsizeHint;
+ TQCOORD tqmaximumSize;
+ TQCOORD tqminimumSize;
+ bool expansive;
+ bool empty;
+
+ // temporary storage
+ bool done;
+
+ // result
+ int pos;
+ int size;
+};
+
+
+TQ_EXPORT void qGeomCalc( TQMemArray<TQLayoutStruct> &chain, int start, int count,
+ int pos, int space, int spacer );
+TQ_EXPORT TQSize tqSmartMinSize( const TQWidgetItem *i );
+TQ_EXPORT TQSize tqSmartMinSize( TQWidget *w );
+TQ_EXPORT TQSize tqSmartMaxSize( const TQWidgetItem *i, int align = 0 );
+TQ_EXPORT TQSize tqSmartMaxSize( TQWidget *w, int align = 0 );
+
+
+/*
+ Modify total maximum (max) and total expansion (exp)
+ when adding boxmax/boxexp.
+
+ Expansive boxes win over non-expansive boxes.
+*/
+static inline void qMaxExpCalc( TQCOORD & max, bool &exp,
+ TQCOORD boxmax, bool boxexp )
+{
+ if ( exp ) {
+ if ( boxexp )
+ max = TQMAX( max, boxmax );
+ } else {
+ if ( boxexp )
+ max = boxmax;
+ else
+ max = TQMIN( max, boxmax );
+ }
+ exp = exp || boxexp;
+}
+
+#endif //TQT_NO_LAYOUT
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqlocalfs.cpp b/tqtinterface/qt4/src/kernel/tqlocalfs.cpp
new file mode 100644
index 0000000..c26c9f4
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqlocalfs.cpp
@@ -0,0 +1,407 @@
+/****************************************************************************
+**
+** Implementation of TQLocalFs class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqlocalfs.h"
+
+#ifndef TQT_NO_NETWORKPROTOCOL
+
+#include "tqfileinfo.h"
+#include "tqfile.h"
+#include "tqurlinfo.h"
+#include "tqapplication.h"
+#include "tqurloperator.h"
+#include "tqguardedptr.h"
+
+//#define TQLOCALFS_DEBUG
+
+
+/*!
+ \class TQLocalFs tqlocalfs.h
+ \brief The TQLocalFs class is an implementation of a
+ TQNetworkProtocol that works on the local file system.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module network
+
+ \ingroup io
+
+ This class is derived from TQNetworkProtocol. TQLocalFs is not
+ normally used directly, but rather through a TQUrlOperator, for
+ example:
+ \code
+ TQUrlOperator op( "file:///tmp" );
+ op.listChildren(); // Asks the server to provide a directory listing
+ \endcode
+
+ This code will only work if the TQLocalFs class is registered; to
+ register the class, you must call qInitNetworkProtocols() before
+ using a TQUrlOperator with TQLocalFs.
+
+ If you really need to use TQLocalFs directly, don't forget
+ to set its TQUrlOperator with setUrl().
+
+ \sa \link network.html TQt Network Documentation \endlink TQNetworkProtocol, TQUrlOperator
+*/
+
+/*!
+ Constructor.
+*/
+
+TQLocalFs::TQLocalFs()
+ : TQNetworkProtocol()
+{
+}
+
+static int convertPermissions(TQFileInfo *fi)
+{
+ int p = 0;
+ if ( fi->permission( TQFileInfo::ReadOwner ) )
+ p |= TQUrlInfo::ReadOwner;
+ if ( fi->permission( TQFileInfo::WriteOwner ) )
+ p |= TQUrlInfo::WriteOwner;
+ if ( fi->permission( TQFileInfo::ExeOwner ) )
+ p |= TQUrlInfo::ExeOwner;
+ if ( fi->permission( TQFileInfo::ReadGroup ) )
+ p |= TQUrlInfo::ReadGroup;
+ if ( fi->permission( TQFileInfo::WriteGroup ) )
+ p |= TQUrlInfo::WriteGroup;
+ if ( fi->permission( TQFileInfo::ExeGroup ) )
+ p |= TQUrlInfo::ExeGroup;
+ if ( fi->permission( TQFileInfo::ReadOther ) )
+ p |= TQUrlInfo::ReadOther;
+ if ( fi->permission( TQFileInfo::WriteOther ) )
+ p |= TQUrlInfo::WriteOther;
+ if ( fi->permission( TQFileInfo::ExeOther ) )
+ p |= TQUrlInfo::ExeOther;
+ return p;
+}
+
+/*!
+ \reimp
+*/
+
+void TQLocalFs::operationListChildren( TQNetworkOperation *op )
+{
+#ifdef TQLOCALFS_DEBUG
+ qDebug( "TQLocalFs: operationListChildren" );
+#endif
+ op->setState( StInProgress );
+
+ dir = TQDir( url()->path() );
+ dir.setNameFilter( url()->nameFilter() );
+ dir.setMatchAllDirs( TRUE );
+ if ( !dir.isReadable() ) {
+ TQString msg = tr( "Could not read directory\n%1" ).arg( url()->path() );
+ op->setState( StFailed );
+ op->setProtocolDetail( msg );
+ op->setErrorCode( (int)ErrListChildren );
+ emit finished( op );
+ return;
+ }
+
+ const TQFileInfoList *filist = dir.entryInfoList( TQDir::All | TQDir::Hidden | TQDir::System );
+ if ( !filist ) {
+ TQString msg = tr( "Could not read directory\n%1" ).arg( url()->path() );
+ op->setState( StFailed );
+ op->setProtocolDetail( msg );
+ op->setErrorCode( (int)ErrListChildren );
+ emit finished( op );
+ return;
+ }
+
+ emit start( op );
+
+ TQFileInfoListIterator it( *filist );
+ TQFileInfo *fi;
+ TQValueList<TQUrlInfo> infos;
+ while ( ( fi = it.current() ) != 0 ) {
+ ++it;
+ infos << TQUrlInfo( fi->fileName(), convertPermissions(fi), fi->owner(), fi->group(),
+ fi->size(), fi->lastModified(), fi->lastRead(), fi->isDir(), fi->isFile(),
+ fi->isSymLink(), fi->isWritable(), fi->isReadable(), fi->isExecutable() );
+ }
+ emit newChildren( infos, op );
+ op->setState( StDone );
+ emit finished( op );
+}
+
+/*!
+ \reimp
+*/
+
+void TQLocalFs::operationMkDir( TQNetworkOperation *op )
+{
+#ifdef TQLOCALFS_DEBUG
+ qDebug( "TQLocalFs: operationMkDir" );
+#endif
+ op->setState( StInProgress );
+ TQString dirname = op->arg( 0 );
+
+ dir = TQDir( url()->path() );
+ if ( dir.mkdir( dirname ) ) {
+ TQFileInfo fi( dir, dirname );
+ TQUrlInfo inf( fi.fileName(), convertPermissions(&fi), fi.owner(), fi.group(),
+ fi.size(), fi.lastModified(), fi.lastRead(), fi.isDir(), fi.isFile(),
+ fi.isSymLink(), fi.isWritable(), fi.isReadable(), fi.isExecutable() );
+ emit newChild( inf, op );
+ op->setState( StDone );
+ emit createdDirectory( inf, op );
+ emit finished( op );
+ } else {
+ TQString msg = tr( "Could not create directory\n%1" ).arg( dirname );
+ op->setState( StFailed );
+ op->setProtocolDetail( msg );
+ op->setErrorCode( (int)ErrMkDir );
+ emit finished( op );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQLocalFs::operationRemove( TQNetworkOperation *op )
+{
+#ifdef TQLOCALFS_DEBUG
+ qDebug( "TQLocalFs: operationRemove" );
+#endif
+ op->setState( StInProgress );
+ TQString name = TQUrl( op->arg( 0 ) ).path();
+ bool deleted = FALSE;
+
+ dir = TQDir( url()->path() );
+
+ TQFileInfo fi( dir, name );
+ if ( fi.isDir() ) {
+ if ( dir.rmdir( name ) )
+ deleted = TRUE;
+ }
+
+ if ( deleted || dir.remove( name ) ) {
+ op->setState( StDone );
+ emit removed( op );
+ emit finished( op );
+ } else {
+ TQString msg = tr( "Could not remove file or directory\n%1" ).arg( name );
+ op->setState( StFailed );
+ op->setProtocolDetail( msg );
+ op->setErrorCode( (int)ErrRemove );
+ emit finished( op );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQLocalFs::operationRename( TQNetworkOperation *op )
+{
+#ifdef TQLOCALFS_DEBUG
+ qDebug( "TQLocalFs: operationRename" );
+#endif
+ op->setState( StInProgress );
+ TQString oldname = op->arg( 0 );
+ TQString newname = op->arg( 1 );
+
+ dir = TQDir( url()->path() );
+ if ( dir.rename( oldname, newname ) ) {
+ op->setState( StDone );
+ emit itemChanged( op );
+ emit finished( op );
+ } else {
+ TQString msg = tr( "Could not rename\n%1\nto\n%2" ).arg( oldname ).arg( newname );
+ op->setState( StFailed );
+ op->setProtocolDetail( msg );
+ op->setErrorCode( (int)ErrRename );
+ emit finished( op );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQLocalFs::operationGet( TQNetworkOperation *op )
+{
+#ifdef TQLOCALFS_DEBUG
+ qDebug( "TQLocalFs: operationGet" );
+#endif
+ op->setState( StInProgress );
+ TQString from = TQUrl( op->arg( 0 ) ).path();
+
+ TQFile f( from );
+ if ( !f.open( IO_ReadOnly ) ) {
+#ifdef TQLOCALFS_DEBUG
+ qDebug( "TQLocalFs: could not open %s", from.latin1() );
+#endif
+ TQString msg = tr( "Could not open\n%1" ).arg( from );
+ op->setState( StFailed );
+ op->setProtocolDetail( msg );
+ op->setErrorCode( (int)ErrGet );
+ emit finished( op );
+ return;
+ }
+
+ TQByteArray s;
+ emit dataTransferProgress( 0, f.size(), op );
+ if ( f.size() != 0 ) {
+ int blockSize = calcBlockSize( f.size() );
+ if ( (int)f.size() < blockSize ) {
+ s.resize( f.size() );
+ f.readBlock( s.data(), f.size() );
+ emit data( s, op );
+ emit dataTransferProgress( f.size(), f.size(), op );
+#ifdef TQLOCALFS_DEBUG
+ qDebug( "TQLocalFs: got all %d bytes at once", f.size() );
+#endif
+ } else {
+ s.resize( blockSize );
+ int remaining = f.size();
+ TQGuardedPtr<TQObject> that = this;
+ while ( that && remaining > 0 ) {
+ if ( operationInProgress() != op )
+ return;
+ if ( remaining >= blockSize ) {
+ f.readBlock( s.data(), blockSize );
+ emit data( s, op );
+ emit dataTransferProgress( f.size() - remaining, f.size(), op );
+ remaining -= blockSize;
+ } else {
+ s.resize( remaining );
+ f.readBlock( s.data(), remaining );
+ emit data( s, op );
+ emit dataTransferProgress( f.size() - remaining, f.size(), op );
+ remaining -= remaining;
+ }
+ tqApp->processEvents();
+ }
+ if (!that)
+ return;
+#ifdef TQLOCALFS_DEBUG
+ qDebug( "TQLocalFs: got all %d bytes step by step", f.size() );
+#endif
+ emit dataTransferProgress( f.size(), f.size(), op );
+ }
+ }
+ op->setState( StDone );
+ f.close();
+ emit finished( op );
+}
+
+/*!
+ \reimp
+*/
+
+void TQLocalFs::operationPut( TQNetworkOperation *op )
+{
+#ifdef TQLOCALFS_DEBUG
+ qDebug( "TQLocalFs: operationPut" );
+#endif
+ op->setState( StInProgress );
+ TQString to = TQUrl( op->arg( 0 ) ).path();
+
+ TQFile f( to );
+ if ( !f.open( IO_WriteOnly ) ) {
+ TQString msg = tr( "Could not write\n%1" ).arg( to );
+ op->setState( StFailed );
+ op->setProtocolDetail( msg );
+ op->setErrorCode( (int)ErrPut );
+ emit finished( op );
+ return;
+ }
+
+ TQByteArray ba( op->rawArg( 1 ) );
+ emit dataTransferProgress( 0, ba.size(), op );
+ int blockSize = calcBlockSize( ba.size() );
+ if ( (int)ba.size() < blockSize ) {
+ f.writeBlock( ba.data(), ba.size() );
+ emit dataTransferProgress( ba.size(), ba.size(), op );
+ } else {
+ int i = 0;
+ while ( i + blockSize < (int)ba.size() - 1 ) {
+ if ( operationInProgress() != op )
+ return;
+ f.writeBlock( &ba.data()[ i ], blockSize );
+ f.flush();
+ emit dataTransferProgress( i + blockSize, ba.size(), op );
+ i += blockSize;
+ TQGuardedPtr<TQObject> that = this;
+ tqApp->processEvents();
+ if (!that)
+ return;
+ }
+ if ( i < (int)ba.size() - 1 )
+ f.writeBlock( &ba.data()[ i ], ba.size() - i );
+ emit dataTransferProgress( ba.size(), ba.size(), op );
+ }
+ op->setState( StDone );
+ f.close();
+ emit finished( op );
+}
+
+/*!
+ \reimp
+*/
+
+int TQLocalFs::supportedOperations() const
+{
+ return OpListChildren | OpMkDir | OpRemove | OpRename | OpGet | OpPut;
+}
+
+/*!
+ \internal
+*/
+
+int TQLocalFs::calcBlockSize( int totalSize ) const
+{
+ if ( totalSize == 0 )
+ return 1024;
+ int s = totalSize / 100;
+ // we want a block size between 1KB and 1MB
+ if ( s < 1024 )
+ s = 1024;
+ if ( s > 1048576 )
+ s = 1048576;
+ return s;
+}
+
+#endif // TQT_NO_NETWORKPROTOCOL
diff --git a/tqtinterface/qt4/src/kernel/tqlocalfs.h b/tqtinterface/qt4/src/kernel/tqlocalfs.h
new file mode 100644
index 0000000..d327d63
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqlocalfs.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Definition of TQLocalFs class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLOCALFS_H
+#define TQLOCALFS_H
+
+#ifndef TQT_H
+#include "tqnetworkprotocol.h"
+#include "tqdir.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_NETWORKPROTOCOL
+
+class TQ_EXPORT TQLocalFs : public TQNetworkProtocol
+{
+ TQ_OBJECT
+
+public:
+ TQLocalFs();
+ virtual int supportedOperations() const;
+
+protected:
+ virtual void operationListChildren( TQNetworkOperation *op );
+ virtual void operationMkDir( TQNetworkOperation *op );
+ virtual void operationRemove( TQNetworkOperation *op );
+ virtual void operationRename( TQNetworkOperation *op );
+ virtual void operationGet( TQNetworkOperation *op );
+ virtual void operationPut( TQNetworkOperation *op );
+
+private:
+ int calcBlockSize( int totalSize ) const;
+ TQDir dir;
+
+};
+
+#endif // TQT_NO_NETWORKPROTOCOL
+
+#endif // TQLOCALFS_H
diff --git a/tqtinterface/qt4/src/kernel/tqlock.cpp b/tqtinterface/qt4/src/kernel/tqlock.cpp
new file mode 100644
index 0000000..8e32602
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqlock.cpp
@@ -0,0 +1,297 @@
+/****************************************************************************
+**
+** Definition of TQLock class. This manages interprocess locking
+**
+** Created : 20000406
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqlock_p.h"
+
+#ifndef TQT_NO_TQWS_MULTIPROCESS
+
+#include <unistd.h>
+#include <sys/types.h>
+#if defined(TQ_OS_MACX)
+#define TQ_NO_SEMAPHORE
+#include <sys/stat.h>
+#include <sys/file.h>
+#else
+#include <sys/sem.h>
+#if defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED) \
+ || defined(TQ_OS_FREEBSD) || defined(TQ_OS_OPENBSD) || defined(TQ_OS_NETBSD) || defined(TQ_OS_BSDI)
+/* union semun is defined by including <sys/sem.h> */
+#else
+/* according to X/OPEN we have to define it ourselves */
+union semun {
+ int val; /* value for SETVAL */
+ struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */
+ unsigned short *array; /* array for GETALL, SETALL */
+};
+#endif
+#endif
+#include <sys/ipc.h>
+#include <string.h>
+#include <errno.h>
+
+#define MAX_LOCKS 200 // maximum simultaneous read locks
+
+class TQLockData
+{
+public:
+#ifdef TQ_NO_SEMAPHORE
+ TQCString file;
+#endif
+ int id;
+ int count;
+ bool owned;
+};
+
+#endif
+
+/*!
+ \class TQLock qlock_p.h
+ \brief The TQLock class is a wrapper for a System V shared semaphore.
+
+ \ingroup qws
+ \ingroup io
+
+ \internal
+
+ It is used by TQt/Embedded for synchronizing access to the graphics
+ card and shared memory region between processes.
+*/
+
+/*!
+ \enum TQLock::Type
+
+ \value Read
+ \value Write
+*/
+
+/*!
+ \fn TQLock::TQLock( const TQString &filename, char id, bool create )
+
+ Creates a lock. \a filename is the file path of the Unix-domain
+ socket the TQt/Embedded client is using. \a id is the name of the
+ particular lock to be created on that socket. If \a create is TRUE
+ the lock is to be created (as the TQt/Embedded server does); if \a
+ create is FALSE the lock should exist already (as the TQt/Embedded
+ client expects).
+*/
+
+TQLock::TQLock( const TQString &filename, char id, bool create )
+{
+#ifndef TQT_NO_TQWS_MULTIPROCESS
+ data = new TQLockData;
+ data->count = 0;
+#ifdef TQ_NO_SEMAPHORE
+ data->file = TQString(filename+id).local8Bit();
+ for(int x = 0; x < 2; x++) {
+ data->id = open(data->file, O_RDWR | (x ? O_CREAT : 0), S_IRWXU);
+ if(data->id != -1 || !create) {
+ data->owned = x;
+ break;
+ }
+ }
+#else
+ key_t semkey = ftok(filename, id);
+ data->id = semget(semkey,0,0);
+ data->owned = create;
+ if ( create ) {
+ semun arg; arg.val = 0;
+ if ( data->id != -1 )
+ semctl(data->id,0,IPC_RMID,arg);
+ data->id = semget(semkey,1,IPC_CREAT|0600);
+ arg.val = MAX_LOCKS;
+ semctl(data->id,0,SETVAL,arg);
+ }
+#endif
+ if ( data->id == -1 ) {
+ qWarning( "Cannot %s semaphore %s \'%c\'",
+ create ? "create" : "get", filename.latin1(), id );
+ qDebug("Error %d %s\n",errno,strerror(errno));
+ }
+#endif
+}
+
+/*!
+ \fn TQLock::~TQLock()
+
+ Destroys a lock
+*/
+
+TQLock::~TQLock()
+{
+#ifndef TQT_NO_TQWS_MULTIPROCESS
+ if ( locked() )
+ unlock();
+#ifdef TQ_NO_SEMAPHORE
+ if(isValid()) {
+ close(data->id);
+ if( data->owned )
+ unlink( data->file );
+ }
+#else
+ if(data->owned) {
+ semun arg; arg.val = 0;
+ semctl( data->id, 0, IPC_RMID, arg );
+ }
+#endif
+ delete data;
+#endif
+}
+
+/*!
+ \fn bool TQLock::isValid() const
+
+ Returns TRUE if the lock constructor was succesful; returns FALSE if
+ the lock could not be created or was not available to connect to.
+*/
+
+bool TQLock::isValid() const
+{
+#ifndef TQT_NO_TQWS_MULTIPROCESS
+ return (data->id != -1);
+#else
+ return TRUE;
+#endif
+}
+
+/*!
+ Locks the semaphore with a lock of type \a t. Locks can either be
+ \c Read or \c Write. If a lock is \c Read, attempts by other
+ processes to obtain \c Read locks will succeed, and \c Write
+ attempts will block until the lock is unlocked. If locked as \c
+ Write, all attempts to lock by other processes will block until
+ the lock is unlocked. Locks are stacked: i.e. a given TQLock can be
+ locked multiple times by the same process without blocking, and
+ will only be unlocked after a corresponding number of unlock()
+ calls.
+*/
+
+void TQLock::lock( Type t )
+{
+#ifndef TQT_NO_TQWS_MULTIPROCESS
+ if ( !data->count ) {
+#ifdef TQ_NO_SEMAPHORE
+ int op = LOCK_SH;
+ if(t == Write)
+ op = LOCK_EX;
+ for( int rv=1; rv; ) {
+ rv = flock(data->id, op);
+ if (rv == -1 && errno != EINTR)
+ qDebug("Semop lock failure %s",strerror(errno));
+ }
+#else
+ sembuf sops;
+ sops.sem_num = 0;
+ sops.sem_flg = SEM_UNDO;
+
+ if ( t == Write ) {
+ sops.sem_op = -MAX_LOCKS;
+ type = Write;
+ } else {
+ sops.sem_op = -1;
+ type = Read;
+ }
+
+ int rv;
+ do {
+ rv = semop(data->id,&sops,1);
+ if (rv == -1 && errno != EINTR)
+ qDebug("Semop lock failure %s",strerror(errno));
+ } while ( rv == -1 && errno == EINTR );
+#endif
+ }
+ data->count++;
+#endif
+}
+
+/*!
+ \fn void TQLock::unlock()
+
+ Unlocks the semaphore. If other processes were blocking waiting to
+ lock() the semaphore, one of them will wake up and succeed in
+ lock()ing.
+*/
+
+void TQLock::unlock()
+{
+#ifndef TQT_NO_TQWS_MULTIPROCESS
+ if( data->count ) {
+ data->count--;
+ if( !data->count ) {
+#ifdef TQ_NO_SEMAPHORE
+ for( int rv=1; rv; ) {
+ rv = flock(data->id, LOCK_UN);
+ if (rv == -1 && errno != EINTR)
+ qDebug("Semop lock failure %s",strerror(errno));
+ }
+#else
+ sembuf sops;
+ sops.sem_num = 0;
+ sops.sem_op = 1;
+ sops.sem_flg = SEM_UNDO;
+ if ( type == Write )
+ sops.sem_op = MAX_LOCKS;
+
+ int rv;
+ do {
+ rv = semop(data->id,&sops,1);
+ if (rv == -1 && errno != EINTR)
+ qDebug("Semop unlock failure %s",strerror(errno));
+ } while ( rv == -1 && errno == EINTR );
+#endif
+ }
+ } else {
+ qDebug("Unlock without corresponding lock");
+ }
+#endif
+}
+
+/*!
+ \fn bool TQLock::locked() const
+
+ Returns TRUE if the lock is currently held by the current process;
+ otherwise returns FALSE.
+*/
+
+bool TQLock::locked() const
+{
+#ifndef TQT_NO_TQWS_MULTIPROCESS
+ return (data->count > 0);
+#else
+ return FALSE;
+#endif
+}
diff --git a/tqtinterface/qt4/src/kernel/tqlock_p.h b/tqtinterface/qt4/src/kernel/tqlock_p.h
new file mode 100644
index 0000000..0f45144
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqlock_p.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Definition of TQLock class. This manages interprocess locking
+**
+** Created : 20000406
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLOCK_P_H
+#define TQLOCK_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+class TQLockData;
+
+class TQLock
+{
+public:
+ TQLock( const TQString &filename, char id, bool create = FALSE );
+ ~TQLock();
+
+ enum Type { Read, Write };
+
+ bool isValid() const;
+ void lock( Type type );
+ void unlock();
+ bool locked() const;
+
+private:
+ Type type;
+ TQLockData *data;
+};
+
+
+// Nice class for ensuring the lock is released.
+// Just create one on the stack and the lock is automatically released
+// when TQLockHolder is destructed.
+class TQLockHolder
+{
+public:
+ TQLockHolder( TQLock *l, TQLock::Type type ) : qlock(l) {
+ qlock->lock( type );
+ }
+ ~TQLockHolder() { if ( locked() ) qlock->unlock(); }
+
+ void lock( TQLock::Type type ) { qlock->lock( type ); }
+ void unlock() { qlock->unlock(); }
+ bool locked() const { return qlock->locked(); }
+
+private:
+ TQLock *qlock;
+};
+
+#endif
+
diff --git a/tqtinterface/qt4/src/kernel/tqmetaobject.cpp b/tqtinterface/qt4/src/kernel/tqmetaobject.cpp
new file mode 100644
index 0000000..09d8439
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmetaobject.cpp
@@ -0,0 +1,1792 @@
+/****************************************************************************
+**
+** Implementation of TQMetaObject class
+**
+** Created : 930419
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmetaobject.h"
+#include "tqasciidict.h"
+
+#ifdef TQT_THREAD_SUPPORT
+#include <private/tqmutexpool_p.h>
+#endif // TQT_THREAD_SUPPORT
+
+#include <private/tqucom_p.h>
+
+#ifdef USE_QT4
+
+// #include <private/qt4_qmetaobject_p.h>
+
+/*!
+ Returns a list with the names of all this class's properties.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa property()
+*/
+TQStrList TQMetaObject::propertyNames( bool super ) const
+{
+ TQStrList l( FALSE );
+ int n = numProperties( super );
+ for( int i = 0; i < n; ++i ) {
+ if (property( i, super))
+ l.append( property( i, super)->name() );
+ else
+ l.append( "[TQt TQMetaObject::propertyNames was unable to find the Qt4 name for this property]" );
+ }
+ return l;
+}
+
+const char * TQMetaData::name() const {
+ return signature(); // Member name
+}
+
+const TQUMethod* TQMetaData::method() const {
+ // FIXME
+ // Verify that this routine accurately fills internal_method_information!
+ printf("[WARNING] const TQUMethod* TQMetaData::method() partially implemented!\n\r");
+
+ if (!internal_method_information) {
+ internal_method_information = new TQUMethod;
+ internal_method_information->parameters = 0;
+ }
+ internal_method_information->name = QMetaMethod::signature();
+ internal_method_information->count = QMetaMethod::parameterNames().count();
+ if (internal_method_information->parameters) {
+ for (int i=0; i<internal_method_information->count; i++) {
+ if (internal_method_information->parameters[i].type)
+ delete internal_method_information->parameters[i].type;
+ }
+ delete [] internal_method_information->parameters;
+ }
+ internal_method_information->parameters = new TQUParameter[internal_method_information->count];
+ for (int i=0; i<internal_method_information->count; i++) {
+ const_cast<TQUParameter&>(internal_method_information->parameters[i]).name = QMetaMethod::parameterNames().at(i).data();
+// const_cast<TQUParameter&>(internal_method_information->parameters[i]).type = new TQUType;
+// const_cast<TQUParameter&>(internal_method_information->parameters[i]).type.desc = QMetaMethod::parameterTypes().at(i).data();
+ const_cast<TQUParameter&>(internal_method_information->parameters[i]).typeExtra = 0;
+ const_cast<TQUParameter&>(internal_method_information->parameters[i]).inOut = 3;
+ }
+ return internal_method_information;
+}
+
+TQMetaEnum::TQMetaEnum() : QMetaEnum() { internal_item_list = 0; }
+
+uint TQMetaEnum::count() const {
+ return QMetaEnum::keyCount();
+}
+
+TQMetaEnum::Item* TQMetaEnum::items() const {
+ if (internal_item_list)
+ delete [] internal_item_list;
+ int internal_item_count = count();
+ internal_item_list = new Item[internal_item_count];
+ for (int i=0; i<internal_item_count;i++) {
+ internal_item_list[i].key = QMetaEnum::key(i);
+ internal_item_list[i].value = QMetaEnum::value(i);
+ }
+ return internal_item_list;
+}
+
+TQMetaData::TQMetaData() : QMetaMethod() {}
+
+TQMetaProperty::TQMetaProperty() : QMetaProperty() {}
+
+/*!
+ Returns the possible enumeration keys if this property is an
+ enumeration type (or a set type).
+
+ \sa isEnumType()
+*/
+TQStrList TQMetaProperty::enumKeys() const
+{
+ TQStrList l( FALSE );
+ QMetaEnum ed = enumerator();
+ for( uint i = 0; i < ed.keyCount(); ++i ) {
+ uint j = 0;
+ while ( j < i && ed.value(j) != ed.value(i) )
+ ++j;
+ if ( i == j )
+ l.append( ed.key(i) );
+ }
+ return l;
+}
+
+bool TQMetaProperty::isSetType() const {
+ return isFlagType ();
+}
+
+int TQMetaProperty::keyToValue( const char* key ) const {
+ return enumerator().keyToValue(key);
+}
+
+const char* TQMetaProperty::valueToKey( int value ) const {
+ return enumerator().valueToKey(value);
+}
+
+int TQMetaProperty::keysToValue( const TQStrList& keys_in ) const {
+ TQString tqs = "";
+ TQStrList keys = keys_in;
+ char *key;
+ for ( key = keys.first(); key; key = keys.next() ) {
+ tqs = tqs + "|" + key;
+ }
+ tqs.remove(0,1);
+ return enumerator().keysToValue(TQCString(tqs));
+}
+
+TQStrList TQMetaProperty::valueToKeys( int value ) const {
+ TQStrList keys;
+ QByteArray qba = enumerator().valueToKeys(value);
+ TQStringList keys_out = TQStringList::split("|", TQString(TQCString(qba)));
+ for ( TQStringList::Iterator it = keys_out.begin(); it != keys_out.end(); ++it ) {
+ keys.append(*it);
+ }
+ return keys;
+}
+
+bool TQMetaProperty::writable() const {
+ return isWritable();
+}
+
+const char* TQMetaProperty::type() const {
+ return QMetaProperty::typeName();
+}
+
+bool TQMetaProperty::designable( TQT_BASE_OBJECT_NAME *o ) const {
+ return isDesignable(o);
+}
+
+bool TQMetaProperty::scriptable( TQT_BASE_OBJECT_NAME *o ) const {
+ return isScriptable(o);
+}
+
+bool TQMetaProperty::stored( TQT_BASE_OBJECT_NAME *o ) const {
+ return isStored(o);
+}
+
+/*!\internal
+ */
+bool TQMetaProperty::stdSet() const
+{
+// if ( !testFlags( Override ) || testFlags( Writable ) )
+// return testFlags( StdSet );
+// const TQMetaObject* mo = (*meta);
+// const TQMetaProperty* tqparent = mo->resolveProperty( this );
+// return tqparent ? tqparent->stdSet() : FALSE;
+
+ // [FIXME]
+ printf("[WARNING] bool TQMetaProperty::stdSet() const unimplemented\n\r");
+ return FALSE;
+}
+
+TQMetaObject::TQMetaObject( const char * const class_name, TQMetaObject *superclass, const TQMetaData * const slot_data, int n_Q_SLOTS, const TQMetaData * const signal_data, int n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *const prop_data, int n_props, const TQMetaEnum *const enum_data, int n_enums,
+#endif // TQT_NO_PROPERTIES
+ const TQClassInfo *const class_info, int n_info ) : QMetaObject() {
+ printf("[WARNING] TQMetaObject() constructor unimplemented\n\r"); // [FIXME]
+}
+
+#ifndef TQT_NO_PROPERTIES
+TQMetaObject::TQMetaObject( const char * const class_name, TQMetaObject *superclass, const TQMetaData * const slot_data, int n_Q_SLOTS, const TQMetaData * const signal_data, int n_Q_SIGNALS, const TQMetaProperty *const prop_data, int n_props, const TQMetaEnum *const enum_data, int n_enums, bool (*qt_static_property)(TQObject*, int, int, TQVariant*), const TQClassInfo *const class_info, int n_info ) : QMetaObject() {
+ printf("[WARNING] TQMetaObject() constructor unimplemented\n\r"); // [FIXME]
+}
+#endif // TQT_NO_PROPERTIES
+
+TQStrList TQMetaObject::slotNames( bool super ) const {
+ printf("[WARNING] TQStrList slotNames( bool super = FALSE ) unimplemented\n\r");
+ return TQStrList();
+}
+
+TQStrList TQMetaObject::signalNames( bool super ) const {
+ printf("[WARNING] TQStrList signalNames( bool super = FALSE ) const unimplemented\n\r");
+ return TQStrList();
+}
+
+/*!
+ Returns the number of Q_SLOTS for this class.
+
+ If \a super is TRUE, inherited Q_SLOTS are included.
+
+ \sa slotNames()
+*/
+int TQMetaObject::numSlots( bool super ) const // number of Q_SLOTS
+{
+ int i;
+ int n=0;
+ for (i=0;i<methodCount();i++) {
+ if (method(i).methodType() == QMetaMethod::Slot) {
+ n++;
+ }
+ }
+
+ if ( !super || !superClass() )
+ return n;
+ return n + tqsuperClass()->numSlots( super );
+}
+
+/*!
+ Returns the number of items of class information available for
+ this class.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+int TQMetaObject::numClassInfo( bool super ) const
+{
+ return classInfoCount() + ((super && tqsuperClass())?tqsuperClass()->numClassInfo(super):0);
+}
+
+/*!
+ Returns the number of Q_SIGNALS for this class.
+
+ If \a super is TRUE, inherited Q_SIGNALS are included.
+
+ \sa signalNames()
+*/
+int TQMetaObject::numSignals( bool super ) const // number of Q_SIGNALS
+{
+ int i;
+ int n=0;
+ for (i=0;i<methodCount();i++) {
+ if (method(i).methodType() == QMetaMethod::Signal) {
+ n++;
+ }
+ }
+
+ if ( !super || !superClass() )
+ return n;
+ return n + tqsuperClass()->numSignals( super );
+}
+
+#if 0
+/*! \internal
+
+ Returns the meta data of the slot with the name \a n or 0 if no
+ such slot exists.
+
+ If \a super is TRUE, inherited slots are included.
+
+ [FIXME]: Superclass handling is badly broken
+ */
+const TQMetaData* TQMetaObject::slot( int index, bool super ) const
+{
+ QMetaMethod mm;
+ const QMetaMethod *mr;
+ int idx = index - ( super ? methodOffset() : 0 );
+// if ( slotDict && idx >= 0 && idx < (int) slotDict->count() ) {
+ if ( idx >= 0 && idx < numSlots(true) ) {
+// return slotData + idx;
+ mm = method(idx);
+ mr = &mm;
+ return static_cast<const TQMetaData*>(mr);
+ }
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->slot( index, super );
+}
+
+/*! \internal
+
+ Returns the meta data of the signal with the name \a n or 0 if no
+ such signal exists.
+
+ If \a super is TRUE, inherited signals are included.
+
+ [FIXME]: Superclass handling is badly broken
+ */
+const TQMetaData* TQMetaObject::signal( int index, bool super ) const
+{
+ QMetaMethod mm;
+ const QMetaMethod *mr;
+ int idx = index - ( super ? methodOffset() : 0 );
+// if ( signalDict && idx >= 0 && idx < (int) signalDict->count() ) {
+ if ( idx >= 0 && idx < numSignals(true) ) {
+// return signalData + idx;
+ mm = method(idx);
+ mr = &mm;
+ return static_cast<const TQMetaData*>(mr);
+ }
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->signal( index, super );
+}
+#endif
+
+/*! \internal
+
+ Returns the meta data of the slot with the name \a n or 0 if no
+ such slot exists.
+
+ If \a super is TRUE, inherited slots are included.
+
+ [FIXME]: Superclass handling is badly broken
+ */
+const TQMetaData* TQMetaObject::slot( int index, bool super ) const
+{
+ QMetaMethod mm;
+ const QMetaMethod *mr;
+ int idx = index - ( super ? methodOffset() : 0 );
+// if ( slotDict && idx >= 0 && idx < (int) slotDict->count() ) {
+ if ( idx >= 0 && idx < numSlots(true) ) {
+// return slotData + idx;
+ mm = method(idx);
+ mr = &mm;
+ return static_cast<const TQMetaData*>(mr);
+ }
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->slot( index, super );
+}
+
+/*! \internal
+
+ Returns the meta data of the signal with the name \a n or 0 if no
+ such signal exists.
+
+ If \a super is TRUE, inherited signals are included.
+
+ [FIXME]: Superclass handling is badly broken
+ */
+const TQMetaData* TQMetaObject::signal( int index, bool super ) const
+{
+ QMetaMethod mm;
+ const QMetaMethod *mr;
+ int idx = index - ( super ? methodOffset() : 0 );
+// if ( signalDict && idx >= 0 && idx < (int) signalDict->count() ) {
+ if ( idx >= 0 && idx < numSignals(true) ) {
+// return signalData + idx;
+ mm = method(idx);
+ mr = &mm;
+ return static_cast<const TQMetaData*>(mr);
+ }
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->signal( index, super );
+}
+
+/*! \internal
+ Returns the index of the slot with name \n or -1 if no such slot exists.
+
+ If \a super is TRUE, inherited slots are included.
+
+ [FIXME]: Superclass handling is badly broken
+ */
+int TQMetaObject::tqfindSlot( const char* n, bool super ) const
+{
+// TQStrList l( FALSE );
+// int m = methodCount();
+// for( int i = 0; i < m; ++i ) {
+// // if ( normalizedSignature(slot( i, super)->signature()) == QByteArray(n) ) {
+// if ( normalizedSignature(method(i).signature()) == QByteArray(n) ) {
+// if (method(i).methodType() == QMetaMethod::Slot) {
+// return i;
+// }
+// }
+// }
+// return -1;
+
+ if (super) printf("[WARNING] In TQMetaObject::tqfindSlot(), superclasses are not being searched for the slot\n\r");
+ return indexOfSlot(normalizedSignature(n));
+}
+
+/*! \internal
+ Returns the index of the signal with name \n or -1 if no such signal exists.
+
+ If \a super is TRUE, inherited signals are included.
+
+ [FIXME]: Superclass handling is badly broken
+*/
+int TQMetaObject::tqfindSignal( const char* n, bool super ) const
+{
+// TQStrList l( FALSE );
+// int m = methodCount();
+// for( int i = 0; i < m; ++i ) {
+// // if ( normalizedSignature(signal( i, super)->signature()) == QByteArray(n) ) {
+// if ( normalizedSignature(method(i).signature()) == QByteArray(n) ) {
+// if (method(i).methodType() == QMetaMethod::Signal) {
+// return i;
+// }
+// }
+// }
+// return -1;
+
+ if (super) printf("[WARNING] In TQMetaObject::tqfindSignal(), superclasses are not being searched for the signal\n\r");
+ return indexOfSignal(normalizedSignature(n));
+}
+
+#ifndef QT_NO_PROPERTIES
+
+/*!
+ Returns the number of properties for this class.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa propertyNames()
+ */
+int TQMetaObject::numProperties( bool super ) const // number of properties
+{
+ int i;
+ int n=0;
+ for (i=0;i<propertyCount();i++) {
+// if (property(i).propertyType() == QMetaProperty::Property) {
+ n++;
+// }
+ }
+
+ if ( !super || !superClass() )
+ return n;
+ return n + tqsuperClass()->numProperties( super );
+}
+
+/*!
+ Returns the property meta data for the property at index \a index
+ or 0 if no such property exists.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa propertyNames()
+
+ [FIXME]: Superclass handling is badly broken
+ */
+static QMetaProperty tqmo_propmethod_curprop;
+const TQMetaProperty* TQMetaObject::property( int index, bool super ) const
+{
+ QMetaProperty mp;
+ const QMetaProperty *pr;
+ int idx = index - ( super ? propertyOffset() : 0 );
+// if ( d->propData && idx >= 0 && idx < (int)d->numPropData )
+ if ( idx >= 0 && idx < numProperties(true) )
+ tqmo_propmethod_curprop = QMetaObject::property(idx);
+ return static_cast<const TQMetaProperty*>(&tqmo_propmethod_curprop);
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->property( index, super );
+}
+
+int TQMetaObject::tqfindProperty( const char *name, bool super ) const {
+ TQ_UNUSED(name);
+ return indexOfProperty(name);
+}
+
+TQMetaObject * TQMetaObject::tqsuperClass() const {
+ return static_cast<TQMetaObject*>(const_cast<QMetaObject*>(superClass()));
+}
+
+const char * TQMetaObject::tqsuperClassName() const {
+ return static_cast<TQMetaObject*>(const_cast<QMetaObject*>(superClass()))->className();
+}
+
+#endif // QT_NO_PROPERTIES
+
+/*!
+ Returns the class information with index \a index or 0 if no such
+ information exists.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+const TQClassInfo* TQMetaObject::classInfo( int index, bool super ) const
+{
+ if ( index < 0 )
+ return 0;
+ if ( index < QMetaObject::classInfoCount() )
+ return static_cast<TQClassInfo*>(&(QMetaObject::classInfo(index)));
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->classInfo( index - QMetaObject::classInfoCount(), super );
+}
+
+/*!
+ \overload
+ Returns the class information with name \a name or 0 if no such
+ information exists.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+const char* TQMetaObject::classInfo( const char* name, bool super ) const
+{
+ for( int i = 0; i < QMetaObject::classInfoCount(); ++i ) {
+ if ( qstrcmp( QMetaObject::classInfo(i).name(), name ) == 0 )
+ return QMetaObject::classInfo(i).value();
+ }
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->classInfo( name, super );
+}
+
+/*!\internal
+
+ */
+TQStrList TQMetaObject::enumeratorNames( bool super ) const
+{
+ TQStrList l( FALSE );
+
+ if ( tqsuperClass() && super ) {
+ TQStrList sl = tqsuperClass()->enumeratorNames( super );
+ for ( TQStrListIterator slit( sl ); slit.current(); ++slit )
+ l.append( slit.current() );
+ }
+
+ for( int i = 0; i < QMetaObject::enumeratorCount(); ++i ) {
+// if ( d->enumData[i].items )
+ if (QMetaObject::enumerator(i).name() != "")
+ l.append( QMetaObject::enumerator(i).name() );
+ }
+
+ return l;
+}
+
+/*!\internal
+ */
+const TQMetaEnum* TQMetaObject::enumerator( const char* name, bool super ) const
+{
+ for( int i = 0; i < QMetaObject::enumeratorCount(); ++i )
+ if ( qstrcmp( QMetaObject::enumerator(i).name(), name ) == 0 )
+ return static_cast<TQMetaEnum*>(&(QMetaObject::enumerator(i)));
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->enumerator( name, super );
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQMetaData tqmetaobject.h
+ \reentrant
+
+ \brief The TQMetaData class provides information about a member function that is known to the meta object system.
+
+ \internal
+
+ The struct consists of three members, \e name, \e method and \e access:
+
+ \code
+ const char *name; // - member name
+ const TQUMethod* method; // - detailed method description
+ enum Access { Private, Protected, Public };
+ Access access; // - access permission
+ \endcode
+ */
+
+/*!
+ \class TQClassInfo tqmetaobject.h
+
+ \brief The TQClassInfo class provides a struct that stores some basic information about a single class.
+
+ \internal
+
+ The class information is a simple \e name - \e value pair:
+
+ \code
+ const char* name;
+ const char* value;
+ \endcode
+
+ */
+
+
+/*!
+ \class TQMetaObject tqmetaobject.h
+ \brief The TQMetaObject class tqcontains meta information about TQt objects.
+
+ \ingroup objectmodel
+
+ The Meta Object System in TQt is responsible for the Q_SIGNALS and
+ Q_SLOTS inter-object communication mechanism, runtime type
+ information and the property system. All meta information in TQt is
+ kept in a single instance of TQMetaObject per class.
+
+ This class is not normally required for application programming.
+ But if you write meta applications, such as scripting engines or
+ GUI builders, you might tqfind these functions useful:
+ \list
+ \i className() to get the name of a class.
+ \i superClassName() to get the name of the superclass.
+ \i inherits(), the function called by TQObject::inherits().
+ \i superClass() to access the superclass's meta object.
+ \i numSlots(), numSignals(), slotNames(), and signalNames() to get
+ information about a class's Q_SIGNALS and Q_SLOTS.
+ \i property() and propertyNames() to obtain information about a
+ class's properties.
+ \endlist
+
+ Classes may have a list of name-value pairs of class information.
+ The number of pairs is returned by numClassInfo(), and values are
+ returned by classInfo().
+
+ \sa \link tqmoc.html tqmoc (Meta Object Compiler)\endlink
+
+*/
+
+
+/*****************************************************************************
+ The private object.
+ *****************************************************************************/
+
+// extra flags from tqmoc.y
+enum Flags {
+ Invalid = 0x00000000,
+ Readable = 0x00000001,
+ Writable = 0x00000002,
+ EnumOrSet = 0x00000004,
+ UnresolvedEnum = 0x00000008,
+ StdSet = 0x00000100,
+ Override = 0x00000200,
+ NotDesignable = 0x00001000,
+ DesignableOverride = 0x00002000,
+ NotScriptable = 0x00004000,
+ ScriptableOverride = 0x00008000,
+ NotStored = 0x00010000,
+ StoredOverride = 0x00020000
+};
+
+static TQAsciiDict<void> *qt_metaobjects = 0;
+static int qt_metaobjects_count = 0;
+
+class TQMetaObjectPrivate
+{
+public:
+ TQMetaObjectPrivate() :
+#ifndef TQT_NO_PROPERTIES
+ enumData(0), numEnumData(0),
+ propData(0),numPropData(0),
+ qt_static_property(0),
+#endif
+ classInfo(0), numClassInfo(0) {}
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaEnum *enumData;
+ int numEnumData;
+ const TQMetaProperty *propData;
+ int numPropData;
+ bool (*qt_static_property)(TQObject*, int, int, TQVariant*);
+#endif
+ const TQClassInfo *classInfo;
+ int numClassInfo;
+};
+
+
+/*****************************************************************************
+ Internal dictionary for fast access to class members
+ *****************************************************************************/
+
+#if defined(TQ_CANNOT_DELETE_CONSTANT)
+typedef TQMetaData TQConstMetaData;
+#else
+typedef const TQMetaData TQConstMetaData;
+#endif
+
+class TQ_EXPORT TQMemberDict : public TQAsciiDict<TQConstMetaData>
+{
+public:
+ TQMemberDict( int size = 17, bool cs = TRUE, bool ck = TRUE ) :
+ TQAsciiDict<TQConstMetaData>(size,cs,ck) {}
+ TQMemberDict( const TQMemberDict &dict ) : TQAsciiDict<TQConstMetaData>(dict) {}
+ ~TQMemberDict() { clear(); }
+ TQMemberDict &operator=(const TQMemberDict &dict)
+ { return (TQMemberDict&)TQAsciiDict<TQConstMetaData>::operator=(dict); }
+};
+
+
+/*
+ Calculate optimal dictionary size for n entries using prime numbers,
+ and assuming there are no more than 40 entries.
+*/
+
+static int optDictSize( int n )
+{
+ if ( n < 6 )
+ n = 5;
+ else if ( n < 10 )
+ n = 11;
+ else if ( n < 14 )
+ n = 17;
+ else
+ n = 23;
+ return n;
+}
+
+
+/*****************************************************************************
+ TQMetaObject member functions
+ *****************************************************************************/
+
+/*!\internal
+ */
+TQMetaObject::TQMetaObject( const char *const class_name, TQMetaObject *super_class,
+ const TQMetaData *const slot_data, int n_Q_SLOTS,
+ const TQMetaData *const signal_data, int n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+#endif
+ const TQClassInfo *const class_info, int n_info )
+{
+ classname = class_name; // set meta data
+ superclass = super_class;
+ superclassname = superclass ? superclass->className() : 0;
+ slotDict = init( slotData = slot_data, n_Q_SLOTS );
+ signalDict = init( signalData = signal_data, n_Q_SIGNALS );
+
+ d = new TQMetaObjectPrivate;
+ reserved = 0;
+
+#ifndef TQT_NO_PROPERTIES
+ d->propData = prop_data;
+ d->numPropData = n_props;
+ d->enumData = enum_data;
+ d->numEnumData = n_enums;
+#endif
+ d->classInfo = class_info;
+ d->numClassInfo = n_info;
+
+ signaloffset = superclass ? ( superclass->signalOffset() + superclass->numSignals() ) : 0;
+ slotoffset = superclass ? ( superclass->slotOffset() + superclass->numSlots() ) : 0;
+#ifndef TQT_NO_PROPERTIES
+ propertyoffset = superclass ? ( superclass->propertyOffset() + superclass->numProperties() ) : 0;
+#endif
+}
+
+#ifndef TQT_NO_PROPERTIES
+/*!\internal
+ */
+TQMetaObject::TQMetaObject( const char *const class_name, TQMetaObject *super_class,
+ const TQMetaData *const slot_data, int n_Q_SLOTS,
+ const TQMetaData *const signal_data, int n_Q_SIGNALS,
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+ bool (*qt_static_property)(TQObject*, int, int, TQVariant*),
+ const TQClassInfo *const class_info, int n_info )
+{
+ classname = class_name; // set meta data
+ superclass = super_class;
+ superclassname = superclass ? superclass->className() : 0;
+ slotDict = init( slotData = slot_data, n_Q_SLOTS );
+ signalDict = init( signalData = signal_data, n_Q_SIGNALS );
+
+ d = new TQMetaObjectPrivate;
+ reserved = 0;
+
+ d->propData = prop_data;
+ d->numPropData = n_props;
+ d->enumData = enum_data;
+ d->numEnumData = n_enums;
+ d->qt_static_property = qt_static_property;
+ d->classInfo = class_info;
+ d->numClassInfo = n_info;
+
+ signaloffset = superclass ? ( superclass->signalOffset() + superclass->numSignals() ) : 0;
+ slotoffset = superclass ? ( superclass->slotOffset() + superclass->numSlots() ) : 0;
+ propertyoffset = superclass ? ( superclass->propertyOffset() + superclass->numProperties() ) : 0;
+}
+#endif
+
+/*!\internal
+ */
+TQMetaObject::~TQMetaObject()
+{
+ delete slotDict; // delete dicts
+ delete signalDict;
+ delete d;
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &qt_metaobjects ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+ if ( qt_metaobjects ) {
+ qt_metaobjects->remove( classname );
+ if ( qt_metaobjects->isEmpty() ) {
+ delete qt_metaobjects;
+ qt_metaobjects = 0;
+ }
+ }
+
+ // delete reserved; // Unused void*
+}
+
+
+/*!
+ \fn const char *TQMetaObject::className() const
+
+ Returns the class name.
+
+ \sa TQObject::className(), superClassName()
+*/
+
+/*!
+ \fn const char *TQMetaObject::superClassName() const
+
+ Returns the class name of the superclass or 0 if there is no
+ superclass in the TQObject hierachy.
+
+ \sa className()
+*/
+
+/*!
+ \fn TQMetaObject *TQMetaObject::superClass() const
+
+ Returns the meta object of the super class or 0 if there is no
+ such object.
+*/
+
+/*!
+ Returns the number of Q_SLOTS for this class.
+
+ If \a super is TRUE, inherited Q_SLOTS are included.
+
+ \sa slotNames()
+*/
+int TQMetaObject::numSlots( bool super ) const // number of Q_SLOTS
+{
+ int n = slotDict ? slotDict->count() : 0;
+ if ( !super || !superclass )
+ return n;
+ return n + superclass->numSlots( super );
+}
+
+/*!
+ Returns the number of Q_SIGNALS for this class.
+
+ If \a super is TRUE, inherited Q_SIGNALS are included.
+
+ \sa signalNames()
+*/
+int TQMetaObject::numSignals( bool super ) const // number of Q_SIGNALS
+{
+ int n = signalDict ? signalDict->count() : 0;
+ if ( !super || !superclass )
+ return n;
+ return n + superclass->numSignals( super );
+}
+
+
+/*! \internal
+
+ Returns the meta data of the slot with the name \a n or 0 if no
+ such slot exists.
+
+ If \a super is TRUE, inherited Q_SLOTS are included.
+ */
+const TQMetaData* TQMetaObject::slot( int index, bool super ) const
+{
+ int idx = index - ( super ? slotOffset() : 0 );
+ if ( slotDict && idx >= 0 && idx < (int) slotDict->count() ) {
+ return slotData + idx;
+ }
+ if ( !super || !superclass )
+ return 0;
+ return superclass->slot( index, super );
+}
+
+/*! \internal
+
+ Returns the meta data of the signal with the name \a n or 0 if no
+ such signal exists.
+
+ If \a super is TRUE, inherited Q_SIGNALS are included.
+ */
+const TQMetaData* TQMetaObject::signal( int index, bool super ) const
+{
+ int idx = index - ( super ? signalOffset() : 0 );
+ if ( signalDict && idx >= 0 && idx < (int) signalDict->count() ) {
+ return signalData + idx;
+ }
+ if ( !super || !superclass )
+ return 0;
+ return superclass->signal( index, super );
+}
+
+
+/*!
+ \fn int TQMetaObject::signalOffset() const
+
+ \internal
+
+ Returns the signal offset for this metaobject.
+
+*/
+
+/*!
+ \fn int TQMetaObject::propertyOffset() const
+
+ \internal
+
+ Returns the property offset for this metaobject.
+
+*/
+
+/*! \internal
+ Returns the index of the signal with name \n or -1 if no such signal exists.
+
+ If \a super is TRUE, inherited Q_SIGNALS are included.
+*/
+int TQMetaObject::tqfindSignal( const char* n, bool super ) const
+{
+ const TQMetaObject *mo = this;
+ int offset = -1;
+
+ do {
+ const TQMetaData *md = mo->signalDict ? mo->signalDict->tqfind( n ) : 0;
+ if ( md ) {
+#if defined(TQT_CHECK_RANGE)
+ if ( offset != -1 ) {
+ qWarning( "TQMetaObject::tqfindSignal:%s: Conflict with %s::%s",
+ className(), mo->className(), n );
+ return offset;
+ }
+#endif
+ offset = mo->signalOffset() + ( md - mo->signalData );
+#if !defined(TQT_CHECK_RANGE)
+ return offset;
+#endif
+ }
+ } while ( super && (mo = mo->superclass) );
+
+ return offset;
+}
+
+/*!
+ \fn int TQMetaObject::slotOffset() const
+
+ \internal
+
+ Returns the slot offset for this metaobject.
+
+*/
+
+/*! \internal
+ Returns the index of the slot with name \n or -1 if no such slot exists.
+
+ If \a super is TRUE, inherited Q_SLOTS are included.
+ */
+int TQMetaObject::tqfindSlot( const char* n, bool super ) const
+{
+ const TQMetaData *md = slotDict ? slotDict->tqfind( n ) : 0;
+ if ( md )
+ return slotOffset() + ( md - slotData );
+ if ( !super || !superclass)
+ return -1;
+ return superclass->tqfindSlot( n, super );
+}
+
+/*!\internal
+ */
+TQMetaObject *TQMetaObject::new_metaobject( const char *classname,
+ TQMetaObject *superclassobject,
+ const TQMetaData * const slot_data, int n_Q_SLOTS,
+ const TQMetaData * const signal_data, int n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty * const prop_data, int n_props,
+ const TQMetaEnum * const enum_data, int n_enums,
+#endif
+ const TQClassInfo * const class_info, int n_info )
+{
+ return new TQMetaObject( classname, superclassobject, slot_data, n_Q_SLOTS,
+ signal_data, n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ prop_data, n_props,
+ enum_data, n_enums,
+#endif
+ class_info, n_info );
+}
+
+#ifndef TQT_NO_PROPERTIES
+/*!\internal
+ */
+TQMetaObject *TQMetaObject::new_metaobject( const char *classname,
+ TQMetaObject *superclassobject,
+ const TQMetaData * const slot_data, int n_Q_SLOTS,
+ const TQMetaData * const signal_data, int n_Q_SIGNALS,
+ const TQMetaProperty * const prop_data, int n_props,
+ const TQMetaEnum * const enum_data, int n_enums,
+ bool (*qt_static_property)(TQObject*, int, int, TQVariant*),
+ const TQClassInfo * const class_info, int n_info )
+{
+ return new TQMetaObject( classname, superclassobject, slot_data, n_Q_SLOTS,
+ signal_data, n_Q_SIGNALS,
+ prop_data, n_props,
+ enum_data, n_enums,
+ qt_static_property,
+ class_info, n_info );
+}
+#endif
+
+/*!\internal
+ */
+TQMemberDict *TQMetaObject::init( const TQMetaData * data, int n )
+{
+ if ( n == 0 ) // nothing, then make no dict
+ return 0;
+ TQMemberDict *dict = new TQMemberDict( optDictSize(n), TRUE, FALSE );
+ TQ_CHECK_PTR( dict );
+ while ( n-- ) { // put all members into dict
+ dict->insert( data->name, data );
+ data++;
+ }
+ return dict;
+}
+
+/*!
+ Returns the number of items of class information available for
+ this class.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+int TQMetaObject::numClassInfo( bool super ) const
+{
+ return d->numClassInfo + ((super && superclass)?superclass->numClassInfo(super):0);
+}
+
+/*!
+ Returns the class information with index \a index or 0 if no such
+ information exists.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+const TQClassInfo* TQMetaObject::classInfo( int index, bool super ) const
+{
+ if ( index < 0 )
+ return 0;
+ if ( index < d->numClassInfo )
+ return &(d->classInfo[ index ]);
+ if ( !super || !superclass )
+ return 0;
+ return superclass->classInfo( index - d->numClassInfo, super );
+}
+
+/*!
+ \overload
+ Returns the class information with name \a name or 0 if no such
+ information exists.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+const char* TQMetaObject::classInfo( const char* name, bool super ) const
+{
+ for( int i = 0; i < d->numClassInfo; ++i ) {
+ if ( qstrcmp( d->classInfo[i].name, name ) == 0 )
+ return d->classInfo[i].value;
+ }
+ if ( !super || !superclass )
+ return 0;
+ return superclass->classInfo( name, super );
+}
+
+#ifndef TQT_NO_PROPERTIES
+
+/*!
+ Returns the number of properties for this class.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa propertyNames()
+ */
+int TQMetaObject::numProperties( bool super ) const // number of Q_SIGNALS
+{
+ int n = d->numPropData;
+ if ( !super || !superclass )
+ return n;
+ return n + superclass->numProperties( super );
+}
+
+/*!
+ Returns the property meta data for the property at index \a index
+ or 0 if no such property exists.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa propertyNames()
+ */
+const TQMetaProperty* TQMetaObject::property( int index, bool super ) const
+{
+ int idx = index - ( super ? propertyOffset() : 0 );
+ if ( d->propData && idx >= 0 && idx < (int)d->numPropData )
+ return d->propData + idx;
+ if ( !super || !superclass )
+ return 0;
+ return superclass->property( index, super );
+}
+
+
+/*!
+ Returns the index for the property with name \a name or -1 if no
+ such property exists.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa property(), propertyNames()
+*/
+
+int TQMetaObject::tqfindProperty( const char *name, bool super ) const
+{
+ for( int i = 0; i < d->numPropData; ++i ) {
+ if ( d->propData[i].isValid() && qstrcmp( d->propData[i].name(), name ) == 0 ) {
+ return ( super ? propertyOffset() : 0 ) + i;
+ }
+ }
+ if ( !super || !superclass )
+ return -1;
+ return superclass->tqfindProperty( name, super );
+}
+
+/*! \internal
+
+ Returns the index for the property \a prop
+ or -1 if the property can not be found.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa property(), propertyNames()
+*/
+
+int TQMetaObject::indexOfProperty( const TQMetaProperty* prop, bool super ) const
+{
+ if ( *prop->meta == this )
+ return ( super ? propertyOffset() : 0 ) + ( prop - d->propData);
+ if ( !super || !superclass )
+ return -1;
+ return superclass->indexOfProperty( prop, super );
+}
+
+/*!\internal
+
+ Returns the tqparent property of property \a p or 0, if the property
+ cannot be resolved.
+
+ \a p has to be contained in this meta object
+*/
+
+const TQMetaProperty* TQMetaObject::resolveProperty( const TQMetaProperty* p ) const
+{
+ if ( !superclass )
+ return 0;
+ return superclass->property( superclass->tqfindProperty( p->n, TRUE ), TRUE );
+}
+
+/*!\internal
+
+ \overload
+
+ The version of resolveProperty that is used by tqmoc generated code
+*/
+
+int TQMetaObject::resolveProperty( int index ) const
+{
+ if ( !superclass )
+ return -1;
+ const TQMetaProperty* p = d->propData + ( index - propertyOffset() );
+ return superclass->tqfindProperty( p->n, TRUE );
+}
+
+
+/*!
+ Returns a list with the names of all this class's properties.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa property()
+*/
+TQStrList TQMetaObject::propertyNames( bool super ) const
+{
+ TQStrList l( FALSE );
+
+ if ( superclass && super ) {
+ TQStrList sl = superclass->propertyNames( super );
+ for ( TQStrListIterator slit( sl ); slit.current(); ++slit )
+ l.append( slit.current() );
+ }
+
+ for( int i = 0; i < d->numPropData; ++i ) {
+ if ( d->propData[i].isValid() )
+ l.append( d->propData[i].name() );
+ }
+
+ return l;
+}
+
+/*!
+ Returns a list with the names of all this class's Q_SIGNALS.
+
+ If \a super is TRUE, inherited Q_SIGNALS are included.
+*/
+TQStrList TQMetaObject::signalNames( bool super ) const
+{
+ TQStrList l( FALSE );
+ int n = numSignals( super );
+ for( int i = 0; i < n; ++i ) {
+ l.append( signal(i, super)->name );
+ }
+ return l;
+}
+
+/*!
+ Returns a list with the names of all this class's Q_SLOTS.
+
+ If \a super is TRUE, inherited Q_SLOTS are included.
+
+ \sa numSlots()
+*/
+TQStrList TQMetaObject::slotNames( bool super ) const
+{
+ TQStrList l( FALSE );
+ int n = numSlots( super );
+ for( int i = 0; i < n; ++i )
+ l.append( slot( i, super)->name );
+ return l;
+}
+
+/*!\internal
+
+ */
+
+int TQMetaObject::numEnumerators( bool super ) const
+{
+ int n = 0;
+ if ( superclass && super )
+ n += superclass->numEnumerators( super );
+ return n + d->numEnumData;
+}
+
+/*!\internal
+
+ */
+TQStrList TQMetaObject::enumeratorNames( bool super ) const
+{
+ TQStrList l( FALSE );
+
+ if ( superclass && super ) {
+ TQStrList sl = superclass->enumeratorNames( super );
+ for ( TQStrListIterator slit( sl ); slit.current(); ++slit )
+ l.append( slit.current() );
+ }
+
+ for( int i = 0; i < d->numEnumData; ++i ) {
+ if ( d->enumData[i].items )
+ l.append( d->enumData[i].name );
+ }
+
+ return l;
+}
+
+/*!\internal
+ */
+const TQMetaEnum* TQMetaObject::enumerator( const char* name, bool super ) const
+{
+ for( int i = 0; i < d->numEnumData; ++i )
+ if ( qstrcmp( d->enumData[i].name, name ) == 0 )
+ return &(d->enumData[i]);
+ if ( !super || !superclass )
+ return 0;
+ return superclass->enumerator( name, super );
+}
+
+#endif // TQT_NO_PROPERTIES
+
+
+/*!
+ Returns TRUE if this class inherits \a clname within the meta
+ object inheritance chain; otherwise returns FALSE.
+
+ (A class is considered to inherit itself.)
+*/
+bool TQMetaObject::inherits( const char* clname ) const
+{
+ const TQMetaObject *meta = this;
+ while ( meta ) {
+ if ( qstrcmp(clname, meta->className()) == 0 )
+ return TRUE;
+ meta = meta->superclass;
+ }
+ return FALSE;
+}
+
+/*! \internal */
+
+TQMetaObject *TQMetaObject::tqmetaObject( const char *class_name )
+{
+ if ( !qt_metaobjects )
+ return 0;
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &qt_metaobjects ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+ TQtStaticMetaObjectFunction func = (TQtStaticMetaObjectFunction)qt_metaobjects->tqfind( class_name );
+ if ( func )
+ return func();
+ return 0;
+}
+
+/*! \internal */
+bool TQMetaObject::hasMetaObject( const char *class_name )
+{
+ if ( !qt_metaobjects )
+ return FALSE;
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &qt_metaobjects ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+ return !!qt_metaobjects->tqfind( class_name );
+}
+
+#ifndef TQT_NO_PROPERTIES
+/*! \internal
+
+### this functions will go away. It exists purely for the sake of meta
+### object code generated with TQt 3.1.0
+*/
+bool TQMetaObject::qt_static_property( TQObject* o, int id, int f, TQVariant* v)
+{
+ if ( d->qt_static_property )
+ return d->qt_static_property( o, id, f, v );
+ else if ( o ) // compatibility
+ return o->qt_property( id, f, v );
+ else if ( superclass )
+ return superclass->qt_static_property( o, id, f, v );
+ switch ( f ) {
+ case 3: case 4: case 5:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+
+/*!
+ \class TQMetaProperty tqmetaobject.h
+
+ \brief The TQMetaProperty class stores meta data about a property.
+
+ \ingroup objectmodel
+
+ Property meta data includes type(), name(), and whether a property
+ is writable(), designable() and stored().
+
+ The functions isSetType(), isEnumType() and enumKeys() provide
+ further information about a property's type. The conversion
+ functions keyToValue(), valueToKey(), keysToValue() and
+ valueToKeys() allow conversion between the integer representation
+ of an enumeration or set value and its literal representation.
+
+ Actual property values are set and received through TQObject's set
+ and get functions. See TQObject::setProperty() and
+ TQObject::property() for details.
+
+ You receive meta property data through an object's meta object.
+ See TQMetaObject::property() and TQMetaObject::propertyNames() for
+ details.
+*/
+
+/*!
+ Returns the possible enumeration keys if this property is an
+ enumeration type (or a set type).
+
+ \sa isEnumType()
+*/
+TQStrList TQMetaProperty::enumKeys() const
+{
+ TQStrList l( FALSE );
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ if ( !ed )
+ return l;
+ if ( ed != 0 ) {
+ for( uint i = 0; i < ed->count; ++i ) {
+ uint j = 0;
+ while ( j < i &&
+ ed->items[j].value != ed->items[i].value )
+ ++j;
+ if ( i == j )
+ l.append( ed->items[i].key );
+ }
+ }
+ return l;
+}
+
+/*!
+ Converts the enumeration key \a key to its integer value.
+
+ For set types, use keysToValue().
+
+ \sa valueToKey(), isSetType(), keysToValue()
+*/
+int TQMetaProperty::keyToValue( const char* key ) const
+{
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ if ( !ed )
+ return -1;
+ for ( uint i = 0; i < ed->count; ++i ) {
+ if ( !qstrcmp( key, ed->items[i].key) )
+ return ed->items[i].value;
+ }
+ return -1;
+}
+
+/*!
+ Converts the enumeration value \a value to its literal key.
+
+ For set types, use valueToKeys().
+
+ \sa valueToKey(), isSetType(), valueToKeys()
+*/
+const char* TQMetaProperty::valueToKey( int value ) const
+{
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ if ( !ed )
+ return 0;
+ for ( uint i = 0; i < ed->count; ++i ) {
+ if ( value == ed->items[i].value )
+ return ed->items[i].key ;
+ }
+ return 0;
+}
+
+/*!
+ Converts the list of keys \a keys to their combined (OR-ed)
+ integer value.
+
+ \sa isSetType(), valueToKey(), keysToValue()
+*/
+int TQMetaProperty::keysToValue( const TQStrList& keys ) const
+{
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ if ( !ed )
+ return -1;
+ int value = 0;
+ for ( TQStrListIterator it( keys ); it.current(); ++it ) {
+ uint i;
+ for( i = ed->count; i > 0; --i ) {
+ if ( !qstrcmp( it.current(), ed->items[i-1].key) ) {
+ value |= ed->items[i-1].value;
+ break;
+ }
+ }
+ if ( i == 0 )
+ value |= -1;
+ }
+ return value;
+}
+
+/*!
+ Converts the set value \a value to a list of keys.
+
+ \sa isSetType(), valueToKey(), valueToKeys()
+*/
+TQStrList TQMetaProperty::valueToKeys( int value ) const
+{
+ TQStrList keys;
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ if ( !ed )
+ return keys;
+
+ int v = value;
+ for( uint i = ed->count; i > 0; --i ) {
+ int k = ed->items[i-1].value;
+ if ( ( k != 0 && (v & k) == k ) || ( k == value) ) {
+ v = v & ~k;
+ keys.append( ed->items[i-1].key );
+ }
+ }
+ return keys;
+}
+
+bool TQMetaProperty::writable() const
+{
+ if ( !testFlags( Override ) || testFlags( Writable ) )
+ return testFlags( Writable );
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->writable() : FALSE;
+}
+
+/*!\internal
+ */
+bool TQMetaProperty::stdSet() const
+{
+ if ( !testFlags( Override ) || testFlags( Writable ) )
+ return testFlags( StdSet );
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->stdSet() : FALSE;
+}
+
+/*!\internal
+ */
+int TQMetaProperty::id() const
+{
+ return _id < 0 ? (*meta)->indexOfProperty( this, TRUE ) : _id;
+}
+
+/*! \internal
+*/
+void TQMetaProperty::clear()
+{
+ t = n = 0;
+ meta = 0;
+ enumData = 0;
+ _id = -1;
+ flags = 0;
+}
+
+bool TQMetaProperty::isValid() const
+{
+ if ( testFlags( UnresolvedEnum ) ) {
+ if ( !enumData && (!meta || !(*meta)->enumerator( t, TRUE ) ) )
+ return FALSE;
+ }
+ if ( !testFlags( Override ) || testFlags( Readable ) )
+ return testFlags( Readable );
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->isValid() : FALSE;
+}
+
+bool TQMetaProperty::isSetType() const
+{
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ return ( ed != 0 && ed->set );
+}
+
+bool TQMetaProperty::isEnumType() const
+{
+ return testFlags( EnumOrSet );
+}
+
+
+
+/*!
+ \fn const char* TQMetaProperty::type() const
+
+ Returns the type of the property.
+*/
+
+/*!
+ \fn const char* TQMetaProperty::name() const
+
+ Returns the name of the property.
+*/
+
+/*!
+ \fn bool TQMetaProperty::writable() const
+
+ Returns TRUE if the property is writable; otherwise returns FALSE.
+
+*/
+
+/*! \fn bool TQMetaProperty::isValid() const
+
+ \internal
+
+ Returns whether the property is valid.
+*/
+
+/*!
+ \fn bool TQMetaProperty::isEnumType() const
+
+ Returns TRUE if the property's type is an enumeration value;
+ otherwise returns FALSE.
+
+ \sa isSetType(), enumKeys()
+*/
+
+/*!
+ \fn bool TQMetaProperty::isSetType() const
+
+ Returns TRUE if the property's type is an enumeration value that
+ is used as set, i.e. if the enumeration values can be OR-ed
+ together; otherwise returns FALSE. A set type is implicitly also
+ an enum type.
+
+ \sa isEnumType(), enumKeys()
+*/
+
+
+/*! Returns TRUE if the property is designable for object \a o;
+ otherwise returns FALSE.
+
+ If no object \a o is given, the function returns a static
+ approximation.
+ */
+bool TQMetaProperty::designable( TQObject* o ) const
+{
+ if ( !isValid() || !writable() )
+ return FALSE;
+ if ( o ) {
+ int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
+ return idx >= 0 && o->qt_property( idx, 3, 0 );
+ }
+ if ( testFlags( DesignableOverride ) ) {
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->designable() : FALSE;
+ }
+ return !testFlags( NotDesignable );
+}
+
+/*!
+ Returns TRUE if the property is scriptable for object \a o;
+ otherwise returns FALSE.
+
+ If no object \a o is given, the function returns a static
+ approximation.
+ */
+bool TQMetaProperty::scriptable( TQObject* o ) const
+{
+ if ( o ) {
+ int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
+ return idx >= 0 && o->qt_property( idx, 4, 0 );
+ }
+ if ( testFlags( ScriptableOverride ) ) {
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->scriptable() : FALSE;
+ }
+ return !testFlags( NotScriptable );
+}
+
+/*!
+ Returns TRUE if the property shall be stored for object \a o;
+ otherwise returns FALSE.
+
+ If no object \a o is given, the function returns a static
+ approximation.
+ */
+bool TQMetaProperty::stored( TQObject* o ) const
+{
+ if ( !isValid() || !writable() )
+ return FALSE;
+ if ( o ) {
+ int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
+ return idx >= 0 && o->qt_property( idx, 5, 0 );
+ }
+ if ( testFlags( StoredOverride ) ) {
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->stored() : FALSE;
+ }
+ return !testFlags( NotStored );
+}
+
+
+/*!
+ Tries to reset the property for object \a o with a reset method.
+ On success, returns TRUE; otherwise returns FALSE.
+
+ Reset methods are optional, usually only a few properties support
+ them.
+*/
+bool TQMetaProperty::reset( TQObject* o ) const
+{
+ if ( !o )
+ return FALSE;
+ int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
+ if ( idx < 0 )
+ return 0;
+ return o->qt_property( idx, 2, 0 );
+}
+
+
+/*! \enum TQMetaProperty::Flags
+
+ \internal
+*/
+
+#endif // TQT_NO_PROPERTIES
+
+/*
+ * TQMetaObjectCleanUp is used as static global object in the tqmoc-generated cpp
+ * files and deletes the TQMetaObject provided with setMetaObject. It sets the
+ * TQObject reference to the metaObj to NULL when it is destroyed.
+ */
+TQMetaObjectCleanUp::TQMetaObjectCleanUp( const char *mo_name, TQtStaticMetaObjectFunction func )
+ : tqmetaObject( 0 )
+{
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &qt_metaobjects ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+ if ( !qt_metaobjects )
+ qt_metaobjects = new TQAsciiDict<void>( 257 );
+ qt_metaobjects->insert( mo_name, (void*)func );
+
+ qt_metaobjects_count++;
+}
+
+TQMetaObjectCleanUp::TQMetaObjectCleanUp()
+ : tqmetaObject( 0 )
+{
+}
+
+/*! \fn bool TQMetaProperty::testFlags( uint f ) const
+ \internal
+*/
+
+TQMetaObjectCleanUp::~TQMetaObjectCleanUp()
+{
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &qt_metaobjects ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+ if ( !--qt_metaobjects_count ) {
+ delete qt_metaobjects;
+ qt_metaobjects = 0;
+ }
+ if ( tqmetaObject ) {
+ delete *tqmetaObject;
+ *tqmetaObject = 0;
+ tqmetaObject = 0;
+ }
+}
+
+void TQMetaObjectCleanUp::setMetaObject( TQMetaObject *&mo )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( tqmetaObject )
+ qWarning( "TQMetaObjectCleanUp::setMetaObject: Double use of TQMetaObjectCleanUp!" );
+#endif
+ tqmetaObject = &mo;
+}
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqmetaobject.cpp~ b/tqtinterface/qt4/src/kernel/tqmetaobject.cpp~
new file mode 100644
index 0000000..09d8439
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmetaobject.cpp~
@@ -0,0 +1,1792 @@
+/****************************************************************************
+**
+** Implementation of TQMetaObject class
+**
+** Created : 930419
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmetaobject.h"
+#include "tqasciidict.h"
+
+#ifdef TQT_THREAD_SUPPORT
+#include <private/tqmutexpool_p.h>
+#endif // TQT_THREAD_SUPPORT
+
+#include <private/tqucom_p.h>
+
+#ifdef USE_QT4
+
+// #include <private/qt4_qmetaobject_p.h>
+
+/*!
+ Returns a list with the names of all this class's properties.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa property()
+*/
+TQStrList TQMetaObject::propertyNames( bool super ) const
+{
+ TQStrList l( FALSE );
+ int n = numProperties( super );
+ for( int i = 0; i < n; ++i ) {
+ if (property( i, super))
+ l.append( property( i, super)->name() );
+ else
+ l.append( "[TQt TQMetaObject::propertyNames was unable to find the Qt4 name for this property]" );
+ }
+ return l;
+}
+
+const char * TQMetaData::name() const {
+ return signature(); // Member name
+}
+
+const TQUMethod* TQMetaData::method() const {
+ // FIXME
+ // Verify that this routine accurately fills internal_method_information!
+ printf("[WARNING] const TQUMethod* TQMetaData::method() partially implemented!\n\r");
+
+ if (!internal_method_information) {
+ internal_method_information = new TQUMethod;
+ internal_method_information->parameters = 0;
+ }
+ internal_method_information->name = QMetaMethod::signature();
+ internal_method_information->count = QMetaMethod::parameterNames().count();
+ if (internal_method_information->parameters) {
+ for (int i=0; i<internal_method_information->count; i++) {
+ if (internal_method_information->parameters[i].type)
+ delete internal_method_information->parameters[i].type;
+ }
+ delete [] internal_method_information->parameters;
+ }
+ internal_method_information->parameters = new TQUParameter[internal_method_information->count];
+ for (int i=0; i<internal_method_information->count; i++) {
+ const_cast<TQUParameter&>(internal_method_information->parameters[i]).name = QMetaMethod::parameterNames().at(i).data();
+// const_cast<TQUParameter&>(internal_method_information->parameters[i]).type = new TQUType;
+// const_cast<TQUParameter&>(internal_method_information->parameters[i]).type.desc = QMetaMethod::parameterTypes().at(i).data();
+ const_cast<TQUParameter&>(internal_method_information->parameters[i]).typeExtra = 0;
+ const_cast<TQUParameter&>(internal_method_information->parameters[i]).inOut = 3;
+ }
+ return internal_method_information;
+}
+
+TQMetaEnum::TQMetaEnum() : QMetaEnum() { internal_item_list = 0; }
+
+uint TQMetaEnum::count() const {
+ return QMetaEnum::keyCount();
+}
+
+TQMetaEnum::Item* TQMetaEnum::items() const {
+ if (internal_item_list)
+ delete [] internal_item_list;
+ int internal_item_count = count();
+ internal_item_list = new Item[internal_item_count];
+ for (int i=0; i<internal_item_count;i++) {
+ internal_item_list[i].key = QMetaEnum::key(i);
+ internal_item_list[i].value = QMetaEnum::value(i);
+ }
+ return internal_item_list;
+}
+
+TQMetaData::TQMetaData() : QMetaMethod() {}
+
+TQMetaProperty::TQMetaProperty() : QMetaProperty() {}
+
+/*!
+ Returns the possible enumeration keys if this property is an
+ enumeration type (or a set type).
+
+ \sa isEnumType()
+*/
+TQStrList TQMetaProperty::enumKeys() const
+{
+ TQStrList l( FALSE );
+ QMetaEnum ed = enumerator();
+ for( uint i = 0; i < ed.keyCount(); ++i ) {
+ uint j = 0;
+ while ( j < i && ed.value(j) != ed.value(i) )
+ ++j;
+ if ( i == j )
+ l.append( ed.key(i) );
+ }
+ return l;
+}
+
+bool TQMetaProperty::isSetType() const {
+ return isFlagType ();
+}
+
+int TQMetaProperty::keyToValue( const char* key ) const {
+ return enumerator().keyToValue(key);
+}
+
+const char* TQMetaProperty::valueToKey( int value ) const {
+ return enumerator().valueToKey(value);
+}
+
+int TQMetaProperty::keysToValue( const TQStrList& keys_in ) const {
+ TQString tqs = "";
+ TQStrList keys = keys_in;
+ char *key;
+ for ( key = keys.first(); key; key = keys.next() ) {
+ tqs = tqs + "|" + key;
+ }
+ tqs.remove(0,1);
+ return enumerator().keysToValue(TQCString(tqs));
+}
+
+TQStrList TQMetaProperty::valueToKeys( int value ) const {
+ TQStrList keys;
+ QByteArray qba = enumerator().valueToKeys(value);
+ TQStringList keys_out = TQStringList::split("|", TQString(TQCString(qba)));
+ for ( TQStringList::Iterator it = keys_out.begin(); it != keys_out.end(); ++it ) {
+ keys.append(*it);
+ }
+ return keys;
+}
+
+bool TQMetaProperty::writable() const {
+ return isWritable();
+}
+
+const char* TQMetaProperty::type() const {
+ return QMetaProperty::typeName();
+}
+
+bool TQMetaProperty::designable( TQT_BASE_OBJECT_NAME *o ) const {
+ return isDesignable(o);
+}
+
+bool TQMetaProperty::scriptable( TQT_BASE_OBJECT_NAME *o ) const {
+ return isScriptable(o);
+}
+
+bool TQMetaProperty::stored( TQT_BASE_OBJECT_NAME *o ) const {
+ return isStored(o);
+}
+
+/*!\internal
+ */
+bool TQMetaProperty::stdSet() const
+{
+// if ( !testFlags( Override ) || testFlags( Writable ) )
+// return testFlags( StdSet );
+// const TQMetaObject* mo = (*meta);
+// const TQMetaProperty* tqparent = mo->resolveProperty( this );
+// return tqparent ? tqparent->stdSet() : FALSE;
+
+ // [FIXME]
+ printf("[WARNING] bool TQMetaProperty::stdSet() const unimplemented\n\r");
+ return FALSE;
+}
+
+TQMetaObject::TQMetaObject( const char * const class_name, TQMetaObject *superclass, const TQMetaData * const slot_data, int n_Q_SLOTS, const TQMetaData * const signal_data, int n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *const prop_data, int n_props, const TQMetaEnum *const enum_data, int n_enums,
+#endif // TQT_NO_PROPERTIES
+ const TQClassInfo *const class_info, int n_info ) : QMetaObject() {
+ printf("[WARNING] TQMetaObject() constructor unimplemented\n\r"); // [FIXME]
+}
+
+#ifndef TQT_NO_PROPERTIES
+TQMetaObject::TQMetaObject( const char * const class_name, TQMetaObject *superclass, const TQMetaData * const slot_data, int n_Q_SLOTS, const TQMetaData * const signal_data, int n_Q_SIGNALS, const TQMetaProperty *const prop_data, int n_props, const TQMetaEnum *const enum_data, int n_enums, bool (*qt_static_property)(TQObject*, int, int, TQVariant*), const TQClassInfo *const class_info, int n_info ) : QMetaObject() {
+ printf("[WARNING] TQMetaObject() constructor unimplemented\n\r"); // [FIXME]
+}
+#endif // TQT_NO_PROPERTIES
+
+TQStrList TQMetaObject::slotNames( bool super ) const {
+ printf("[WARNING] TQStrList slotNames( bool super = FALSE ) unimplemented\n\r");
+ return TQStrList();
+}
+
+TQStrList TQMetaObject::signalNames( bool super ) const {
+ printf("[WARNING] TQStrList signalNames( bool super = FALSE ) const unimplemented\n\r");
+ return TQStrList();
+}
+
+/*!
+ Returns the number of Q_SLOTS for this class.
+
+ If \a super is TRUE, inherited Q_SLOTS are included.
+
+ \sa slotNames()
+*/
+int TQMetaObject::numSlots( bool super ) const // number of Q_SLOTS
+{
+ int i;
+ int n=0;
+ for (i=0;i<methodCount();i++) {
+ if (method(i).methodType() == QMetaMethod::Slot) {
+ n++;
+ }
+ }
+
+ if ( !super || !superClass() )
+ return n;
+ return n + tqsuperClass()->numSlots( super );
+}
+
+/*!
+ Returns the number of items of class information available for
+ this class.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+int TQMetaObject::numClassInfo( bool super ) const
+{
+ return classInfoCount() + ((super && tqsuperClass())?tqsuperClass()->numClassInfo(super):0);
+}
+
+/*!
+ Returns the number of Q_SIGNALS for this class.
+
+ If \a super is TRUE, inherited Q_SIGNALS are included.
+
+ \sa signalNames()
+*/
+int TQMetaObject::numSignals( bool super ) const // number of Q_SIGNALS
+{
+ int i;
+ int n=0;
+ for (i=0;i<methodCount();i++) {
+ if (method(i).methodType() == QMetaMethod::Signal) {
+ n++;
+ }
+ }
+
+ if ( !super || !superClass() )
+ return n;
+ return n + tqsuperClass()->numSignals( super );
+}
+
+#if 0
+/*! \internal
+
+ Returns the meta data of the slot with the name \a n or 0 if no
+ such slot exists.
+
+ If \a super is TRUE, inherited slots are included.
+
+ [FIXME]: Superclass handling is badly broken
+ */
+const TQMetaData* TQMetaObject::slot( int index, bool super ) const
+{
+ QMetaMethod mm;
+ const QMetaMethod *mr;
+ int idx = index - ( super ? methodOffset() : 0 );
+// if ( slotDict && idx >= 0 && idx < (int) slotDict->count() ) {
+ if ( idx >= 0 && idx < numSlots(true) ) {
+// return slotData + idx;
+ mm = method(idx);
+ mr = &mm;
+ return static_cast<const TQMetaData*>(mr);
+ }
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->slot( index, super );
+}
+
+/*! \internal
+
+ Returns the meta data of the signal with the name \a n or 0 if no
+ such signal exists.
+
+ If \a super is TRUE, inherited signals are included.
+
+ [FIXME]: Superclass handling is badly broken
+ */
+const TQMetaData* TQMetaObject::signal( int index, bool super ) const
+{
+ QMetaMethod mm;
+ const QMetaMethod *mr;
+ int idx = index - ( super ? methodOffset() : 0 );
+// if ( signalDict && idx >= 0 && idx < (int) signalDict->count() ) {
+ if ( idx >= 0 && idx < numSignals(true) ) {
+// return signalData + idx;
+ mm = method(idx);
+ mr = &mm;
+ return static_cast<const TQMetaData*>(mr);
+ }
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->signal( index, super );
+}
+#endif
+
+/*! \internal
+
+ Returns the meta data of the slot with the name \a n or 0 if no
+ such slot exists.
+
+ If \a super is TRUE, inherited slots are included.
+
+ [FIXME]: Superclass handling is badly broken
+ */
+const TQMetaData* TQMetaObject::slot( int index, bool super ) const
+{
+ QMetaMethod mm;
+ const QMetaMethod *mr;
+ int idx = index - ( super ? methodOffset() : 0 );
+// if ( slotDict && idx >= 0 && idx < (int) slotDict->count() ) {
+ if ( idx >= 0 && idx < numSlots(true) ) {
+// return slotData + idx;
+ mm = method(idx);
+ mr = &mm;
+ return static_cast<const TQMetaData*>(mr);
+ }
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->slot( index, super );
+}
+
+/*! \internal
+
+ Returns the meta data of the signal with the name \a n or 0 if no
+ such signal exists.
+
+ If \a super is TRUE, inherited signals are included.
+
+ [FIXME]: Superclass handling is badly broken
+ */
+const TQMetaData* TQMetaObject::signal( int index, bool super ) const
+{
+ QMetaMethod mm;
+ const QMetaMethod *mr;
+ int idx = index - ( super ? methodOffset() : 0 );
+// if ( signalDict && idx >= 0 && idx < (int) signalDict->count() ) {
+ if ( idx >= 0 && idx < numSignals(true) ) {
+// return signalData + idx;
+ mm = method(idx);
+ mr = &mm;
+ return static_cast<const TQMetaData*>(mr);
+ }
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->signal( index, super );
+}
+
+/*! \internal
+ Returns the index of the slot with name \n or -1 if no such slot exists.
+
+ If \a super is TRUE, inherited slots are included.
+
+ [FIXME]: Superclass handling is badly broken
+ */
+int TQMetaObject::tqfindSlot( const char* n, bool super ) const
+{
+// TQStrList l( FALSE );
+// int m = methodCount();
+// for( int i = 0; i < m; ++i ) {
+// // if ( normalizedSignature(slot( i, super)->signature()) == QByteArray(n) ) {
+// if ( normalizedSignature(method(i).signature()) == QByteArray(n) ) {
+// if (method(i).methodType() == QMetaMethod::Slot) {
+// return i;
+// }
+// }
+// }
+// return -1;
+
+ if (super) printf("[WARNING] In TQMetaObject::tqfindSlot(), superclasses are not being searched for the slot\n\r");
+ return indexOfSlot(normalizedSignature(n));
+}
+
+/*! \internal
+ Returns the index of the signal with name \n or -1 if no such signal exists.
+
+ If \a super is TRUE, inherited signals are included.
+
+ [FIXME]: Superclass handling is badly broken
+*/
+int TQMetaObject::tqfindSignal( const char* n, bool super ) const
+{
+// TQStrList l( FALSE );
+// int m = methodCount();
+// for( int i = 0; i < m; ++i ) {
+// // if ( normalizedSignature(signal( i, super)->signature()) == QByteArray(n) ) {
+// if ( normalizedSignature(method(i).signature()) == QByteArray(n) ) {
+// if (method(i).methodType() == QMetaMethod::Signal) {
+// return i;
+// }
+// }
+// }
+// return -1;
+
+ if (super) printf("[WARNING] In TQMetaObject::tqfindSignal(), superclasses are not being searched for the signal\n\r");
+ return indexOfSignal(normalizedSignature(n));
+}
+
+#ifndef QT_NO_PROPERTIES
+
+/*!
+ Returns the number of properties for this class.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa propertyNames()
+ */
+int TQMetaObject::numProperties( bool super ) const // number of properties
+{
+ int i;
+ int n=0;
+ for (i=0;i<propertyCount();i++) {
+// if (property(i).propertyType() == QMetaProperty::Property) {
+ n++;
+// }
+ }
+
+ if ( !super || !superClass() )
+ return n;
+ return n + tqsuperClass()->numProperties( super );
+}
+
+/*!
+ Returns the property meta data for the property at index \a index
+ or 0 if no such property exists.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa propertyNames()
+
+ [FIXME]: Superclass handling is badly broken
+ */
+static QMetaProperty tqmo_propmethod_curprop;
+const TQMetaProperty* TQMetaObject::property( int index, bool super ) const
+{
+ QMetaProperty mp;
+ const QMetaProperty *pr;
+ int idx = index - ( super ? propertyOffset() : 0 );
+// if ( d->propData && idx >= 0 && idx < (int)d->numPropData )
+ if ( idx >= 0 && idx < numProperties(true) )
+ tqmo_propmethod_curprop = QMetaObject::property(idx);
+ return static_cast<const TQMetaProperty*>(&tqmo_propmethod_curprop);
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->property( index, super );
+}
+
+int TQMetaObject::tqfindProperty( const char *name, bool super ) const {
+ TQ_UNUSED(name);
+ return indexOfProperty(name);
+}
+
+TQMetaObject * TQMetaObject::tqsuperClass() const {
+ return static_cast<TQMetaObject*>(const_cast<QMetaObject*>(superClass()));
+}
+
+const char * TQMetaObject::tqsuperClassName() const {
+ return static_cast<TQMetaObject*>(const_cast<QMetaObject*>(superClass()))->className();
+}
+
+#endif // QT_NO_PROPERTIES
+
+/*!
+ Returns the class information with index \a index or 0 if no such
+ information exists.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+const TQClassInfo* TQMetaObject::classInfo( int index, bool super ) const
+{
+ if ( index < 0 )
+ return 0;
+ if ( index < QMetaObject::classInfoCount() )
+ return static_cast<TQClassInfo*>(&(QMetaObject::classInfo(index)));
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->classInfo( index - QMetaObject::classInfoCount(), super );
+}
+
+/*!
+ \overload
+ Returns the class information with name \a name or 0 if no such
+ information exists.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+const char* TQMetaObject::classInfo( const char* name, bool super ) const
+{
+ for( int i = 0; i < QMetaObject::classInfoCount(); ++i ) {
+ if ( qstrcmp( QMetaObject::classInfo(i).name(), name ) == 0 )
+ return QMetaObject::classInfo(i).value();
+ }
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->classInfo( name, super );
+}
+
+/*!\internal
+
+ */
+TQStrList TQMetaObject::enumeratorNames( bool super ) const
+{
+ TQStrList l( FALSE );
+
+ if ( tqsuperClass() && super ) {
+ TQStrList sl = tqsuperClass()->enumeratorNames( super );
+ for ( TQStrListIterator slit( sl ); slit.current(); ++slit )
+ l.append( slit.current() );
+ }
+
+ for( int i = 0; i < QMetaObject::enumeratorCount(); ++i ) {
+// if ( d->enumData[i].items )
+ if (QMetaObject::enumerator(i).name() != "")
+ l.append( QMetaObject::enumerator(i).name() );
+ }
+
+ return l;
+}
+
+/*!\internal
+ */
+const TQMetaEnum* TQMetaObject::enumerator( const char* name, bool super ) const
+{
+ for( int i = 0; i < QMetaObject::enumeratorCount(); ++i )
+ if ( qstrcmp( QMetaObject::enumerator(i).name(), name ) == 0 )
+ return static_cast<TQMetaEnum*>(&(QMetaObject::enumerator(i)));
+ if ( !super || !superClass() )
+ return 0;
+ return tqsuperClass()->enumerator( name, super );
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQMetaData tqmetaobject.h
+ \reentrant
+
+ \brief The TQMetaData class provides information about a member function that is known to the meta object system.
+
+ \internal
+
+ The struct consists of three members, \e name, \e method and \e access:
+
+ \code
+ const char *name; // - member name
+ const TQUMethod* method; // - detailed method description
+ enum Access { Private, Protected, Public };
+ Access access; // - access permission
+ \endcode
+ */
+
+/*!
+ \class TQClassInfo tqmetaobject.h
+
+ \brief The TQClassInfo class provides a struct that stores some basic information about a single class.
+
+ \internal
+
+ The class information is a simple \e name - \e value pair:
+
+ \code
+ const char* name;
+ const char* value;
+ \endcode
+
+ */
+
+
+/*!
+ \class TQMetaObject tqmetaobject.h
+ \brief The TQMetaObject class tqcontains meta information about TQt objects.
+
+ \ingroup objectmodel
+
+ The Meta Object System in TQt is responsible for the Q_SIGNALS and
+ Q_SLOTS inter-object communication mechanism, runtime type
+ information and the property system. All meta information in TQt is
+ kept in a single instance of TQMetaObject per class.
+
+ This class is not normally required for application programming.
+ But if you write meta applications, such as scripting engines or
+ GUI builders, you might tqfind these functions useful:
+ \list
+ \i className() to get the name of a class.
+ \i superClassName() to get the name of the superclass.
+ \i inherits(), the function called by TQObject::inherits().
+ \i superClass() to access the superclass's meta object.
+ \i numSlots(), numSignals(), slotNames(), and signalNames() to get
+ information about a class's Q_SIGNALS and Q_SLOTS.
+ \i property() and propertyNames() to obtain information about a
+ class's properties.
+ \endlist
+
+ Classes may have a list of name-value pairs of class information.
+ The number of pairs is returned by numClassInfo(), and values are
+ returned by classInfo().
+
+ \sa \link tqmoc.html tqmoc (Meta Object Compiler)\endlink
+
+*/
+
+
+/*****************************************************************************
+ The private object.
+ *****************************************************************************/
+
+// extra flags from tqmoc.y
+enum Flags {
+ Invalid = 0x00000000,
+ Readable = 0x00000001,
+ Writable = 0x00000002,
+ EnumOrSet = 0x00000004,
+ UnresolvedEnum = 0x00000008,
+ StdSet = 0x00000100,
+ Override = 0x00000200,
+ NotDesignable = 0x00001000,
+ DesignableOverride = 0x00002000,
+ NotScriptable = 0x00004000,
+ ScriptableOverride = 0x00008000,
+ NotStored = 0x00010000,
+ StoredOverride = 0x00020000
+};
+
+static TQAsciiDict<void> *qt_metaobjects = 0;
+static int qt_metaobjects_count = 0;
+
+class TQMetaObjectPrivate
+{
+public:
+ TQMetaObjectPrivate() :
+#ifndef TQT_NO_PROPERTIES
+ enumData(0), numEnumData(0),
+ propData(0),numPropData(0),
+ qt_static_property(0),
+#endif
+ classInfo(0), numClassInfo(0) {}
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaEnum *enumData;
+ int numEnumData;
+ const TQMetaProperty *propData;
+ int numPropData;
+ bool (*qt_static_property)(TQObject*, int, int, TQVariant*);
+#endif
+ const TQClassInfo *classInfo;
+ int numClassInfo;
+};
+
+
+/*****************************************************************************
+ Internal dictionary for fast access to class members
+ *****************************************************************************/
+
+#if defined(TQ_CANNOT_DELETE_CONSTANT)
+typedef TQMetaData TQConstMetaData;
+#else
+typedef const TQMetaData TQConstMetaData;
+#endif
+
+class TQ_EXPORT TQMemberDict : public TQAsciiDict<TQConstMetaData>
+{
+public:
+ TQMemberDict( int size = 17, bool cs = TRUE, bool ck = TRUE ) :
+ TQAsciiDict<TQConstMetaData>(size,cs,ck) {}
+ TQMemberDict( const TQMemberDict &dict ) : TQAsciiDict<TQConstMetaData>(dict) {}
+ ~TQMemberDict() { clear(); }
+ TQMemberDict &operator=(const TQMemberDict &dict)
+ { return (TQMemberDict&)TQAsciiDict<TQConstMetaData>::operator=(dict); }
+};
+
+
+/*
+ Calculate optimal dictionary size for n entries using prime numbers,
+ and assuming there are no more than 40 entries.
+*/
+
+static int optDictSize( int n )
+{
+ if ( n < 6 )
+ n = 5;
+ else if ( n < 10 )
+ n = 11;
+ else if ( n < 14 )
+ n = 17;
+ else
+ n = 23;
+ return n;
+}
+
+
+/*****************************************************************************
+ TQMetaObject member functions
+ *****************************************************************************/
+
+/*!\internal
+ */
+TQMetaObject::TQMetaObject( const char *const class_name, TQMetaObject *super_class,
+ const TQMetaData *const slot_data, int n_Q_SLOTS,
+ const TQMetaData *const signal_data, int n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+#endif
+ const TQClassInfo *const class_info, int n_info )
+{
+ classname = class_name; // set meta data
+ superclass = super_class;
+ superclassname = superclass ? superclass->className() : 0;
+ slotDict = init( slotData = slot_data, n_Q_SLOTS );
+ signalDict = init( signalData = signal_data, n_Q_SIGNALS );
+
+ d = new TQMetaObjectPrivate;
+ reserved = 0;
+
+#ifndef TQT_NO_PROPERTIES
+ d->propData = prop_data;
+ d->numPropData = n_props;
+ d->enumData = enum_data;
+ d->numEnumData = n_enums;
+#endif
+ d->classInfo = class_info;
+ d->numClassInfo = n_info;
+
+ signaloffset = superclass ? ( superclass->signalOffset() + superclass->numSignals() ) : 0;
+ slotoffset = superclass ? ( superclass->slotOffset() + superclass->numSlots() ) : 0;
+#ifndef TQT_NO_PROPERTIES
+ propertyoffset = superclass ? ( superclass->propertyOffset() + superclass->numProperties() ) : 0;
+#endif
+}
+
+#ifndef TQT_NO_PROPERTIES
+/*!\internal
+ */
+TQMetaObject::TQMetaObject( const char *const class_name, TQMetaObject *super_class,
+ const TQMetaData *const slot_data, int n_Q_SLOTS,
+ const TQMetaData *const signal_data, int n_Q_SIGNALS,
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+ bool (*qt_static_property)(TQObject*, int, int, TQVariant*),
+ const TQClassInfo *const class_info, int n_info )
+{
+ classname = class_name; // set meta data
+ superclass = super_class;
+ superclassname = superclass ? superclass->className() : 0;
+ slotDict = init( slotData = slot_data, n_Q_SLOTS );
+ signalDict = init( signalData = signal_data, n_Q_SIGNALS );
+
+ d = new TQMetaObjectPrivate;
+ reserved = 0;
+
+ d->propData = prop_data;
+ d->numPropData = n_props;
+ d->enumData = enum_data;
+ d->numEnumData = n_enums;
+ d->qt_static_property = qt_static_property;
+ d->classInfo = class_info;
+ d->numClassInfo = n_info;
+
+ signaloffset = superclass ? ( superclass->signalOffset() + superclass->numSignals() ) : 0;
+ slotoffset = superclass ? ( superclass->slotOffset() + superclass->numSlots() ) : 0;
+ propertyoffset = superclass ? ( superclass->propertyOffset() + superclass->numProperties() ) : 0;
+}
+#endif
+
+/*!\internal
+ */
+TQMetaObject::~TQMetaObject()
+{
+ delete slotDict; // delete dicts
+ delete signalDict;
+ delete d;
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &qt_metaobjects ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+ if ( qt_metaobjects ) {
+ qt_metaobjects->remove( classname );
+ if ( qt_metaobjects->isEmpty() ) {
+ delete qt_metaobjects;
+ qt_metaobjects = 0;
+ }
+ }
+
+ // delete reserved; // Unused void*
+}
+
+
+/*!
+ \fn const char *TQMetaObject::className() const
+
+ Returns the class name.
+
+ \sa TQObject::className(), superClassName()
+*/
+
+/*!
+ \fn const char *TQMetaObject::superClassName() const
+
+ Returns the class name of the superclass or 0 if there is no
+ superclass in the TQObject hierachy.
+
+ \sa className()
+*/
+
+/*!
+ \fn TQMetaObject *TQMetaObject::superClass() const
+
+ Returns the meta object of the super class or 0 if there is no
+ such object.
+*/
+
+/*!
+ Returns the number of Q_SLOTS for this class.
+
+ If \a super is TRUE, inherited Q_SLOTS are included.
+
+ \sa slotNames()
+*/
+int TQMetaObject::numSlots( bool super ) const // number of Q_SLOTS
+{
+ int n = slotDict ? slotDict->count() : 0;
+ if ( !super || !superclass )
+ return n;
+ return n + superclass->numSlots( super );
+}
+
+/*!
+ Returns the number of Q_SIGNALS for this class.
+
+ If \a super is TRUE, inherited Q_SIGNALS are included.
+
+ \sa signalNames()
+*/
+int TQMetaObject::numSignals( bool super ) const // number of Q_SIGNALS
+{
+ int n = signalDict ? signalDict->count() : 0;
+ if ( !super || !superclass )
+ return n;
+ return n + superclass->numSignals( super );
+}
+
+
+/*! \internal
+
+ Returns the meta data of the slot with the name \a n or 0 if no
+ such slot exists.
+
+ If \a super is TRUE, inherited Q_SLOTS are included.
+ */
+const TQMetaData* TQMetaObject::slot( int index, bool super ) const
+{
+ int idx = index - ( super ? slotOffset() : 0 );
+ if ( slotDict && idx >= 0 && idx < (int) slotDict->count() ) {
+ return slotData + idx;
+ }
+ if ( !super || !superclass )
+ return 0;
+ return superclass->slot( index, super );
+}
+
+/*! \internal
+
+ Returns the meta data of the signal with the name \a n or 0 if no
+ such signal exists.
+
+ If \a super is TRUE, inherited Q_SIGNALS are included.
+ */
+const TQMetaData* TQMetaObject::signal( int index, bool super ) const
+{
+ int idx = index - ( super ? signalOffset() : 0 );
+ if ( signalDict && idx >= 0 && idx < (int) signalDict->count() ) {
+ return signalData + idx;
+ }
+ if ( !super || !superclass )
+ return 0;
+ return superclass->signal( index, super );
+}
+
+
+/*!
+ \fn int TQMetaObject::signalOffset() const
+
+ \internal
+
+ Returns the signal offset for this metaobject.
+
+*/
+
+/*!
+ \fn int TQMetaObject::propertyOffset() const
+
+ \internal
+
+ Returns the property offset for this metaobject.
+
+*/
+
+/*! \internal
+ Returns the index of the signal with name \n or -1 if no such signal exists.
+
+ If \a super is TRUE, inherited Q_SIGNALS are included.
+*/
+int TQMetaObject::tqfindSignal( const char* n, bool super ) const
+{
+ const TQMetaObject *mo = this;
+ int offset = -1;
+
+ do {
+ const TQMetaData *md = mo->signalDict ? mo->signalDict->tqfind( n ) : 0;
+ if ( md ) {
+#if defined(TQT_CHECK_RANGE)
+ if ( offset != -1 ) {
+ qWarning( "TQMetaObject::tqfindSignal:%s: Conflict with %s::%s",
+ className(), mo->className(), n );
+ return offset;
+ }
+#endif
+ offset = mo->signalOffset() + ( md - mo->signalData );
+#if !defined(TQT_CHECK_RANGE)
+ return offset;
+#endif
+ }
+ } while ( super && (mo = mo->superclass) );
+
+ return offset;
+}
+
+/*!
+ \fn int TQMetaObject::slotOffset() const
+
+ \internal
+
+ Returns the slot offset for this metaobject.
+
+*/
+
+/*! \internal
+ Returns the index of the slot with name \n or -1 if no such slot exists.
+
+ If \a super is TRUE, inherited Q_SLOTS are included.
+ */
+int TQMetaObject::tqfindSlot( const char* n, bool super ) const
+{
+ const TQMetaData *md = slotDict ? slotDict->tqfind( n ) : 0;
+ if ( md )
+ return slotOffset() + ( md - slotData );
+ if ( !super || !superclass)
+ return -1;
+ return superclass->tqfindSlot( n, super );
+}
+
+/*!\internal
+ */
+TQMetaObject *TQMetaObject::new_metaobject( const char *classname,
+ TQMetaObject *superclassobject,
+ const TQMetaData * const slot_data, int n_Q_SLOTS,
+ const TQMetaData * const signal_data, int n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty * const prop_data, int n_props,
+ const TQMetaEnum * const enum_data, int n_enums,
+#endif
+ const TQClassInfo * const class_info, int n_info )
+{
+ return new TQMetaObject( classname, superclassobject, slot_data, n_Q_SLOTS,
+ signal_data, n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ prop_data, n_props,
+ enum_data, n_enums,
+#endif
+ class_info, n_info );
+}
+
+#ifndef TQT_NO_PROPERTIES
+/*!\internal
+ */
+TQMetaObject *TQMetaObject::new_metaobject( const char *classname,
+ TQMetaObject *superclassobject,
+ const TQMetaData * const slot_data, int n_Q_SLOTS,
+ const TQMetaData * const signal_data, int n_Q_SIGNALS,
+ const TQMetaProperty * const prop_data, int n_props,
+ const TQMetaEnum * const enum_data, int n_enums,
+ bool (*qt_static_property)(TQObject*, int, int, TQVariant*),
+ const TQClassInfo * const class_info, int n_info )
+{
+ return new TQMetaObject( classname, superclassobject, slot_data, n_Q_SLOTS,
+ signal_data, n_Q_SIGNALS,
+ prop_data, n_props,
+ enum_data, n_enums,
+ qt_static_property,
+ class_info, n_info );
+}
+#endif
+
+/*!\internal
+ */
+TQMemberDict *TQMetaObject::init( const TQMetaData * data, int n )
+{
+ if ( n == 0 ) // nothing, then make no dict
+ return 0;
+ TQMemberDict *dict = new TQMemberDict( optDictSize(n), TRUE, FALSE );
+ TQ_CHECK_PTR( dict );
+ while ( n-- ) { // put all members into dict
+ dict->insert( data->name, data );
+ data++;
+ }
+ return dict;
+}
+
+/*!
+ Returns the number of items of class information available for
+ this class.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+int TQMetaObject::numClassInfo( bool super ) const
+{
+ return d->numClassInfo + ((super && superclass)?superclass->numClassInfo(super):0);
+}
+
+/*!
+ Returns the class information with index \a index or 0 if no such
+ information exists.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+const TQClassInfo* TQMetaObject::classInfo( int index, bool super ) const
+{
+ if ( index < 0 )
+ return 0;
+ if ( index < d->numClassInfo )
+ return &(d->classInfo[ index ]);
+ if ( !super || !superclass )
+ return 0;
+ return superclass->classInfo( index - d->numClassInfo, super );
+}
+
+/*!
+ \overload
+ Returns the class information with name \a name or 0 if no such
+ information exists.
+
+ If \a super is TRUE, inherited class information is included.
+*/
+const char* TQMetaObject::classInfo( const char* name, bool super ) const
+{
+ for( int i = 0; i < d->numClassInfo; ++i ) {
+ if ( qstrcmp( d->classInfo[i].name, name ) == 0 )
+ return d->classInfo[i].value;
+ }
+ if ( !super || !superclass )
+ return 0;
+ return superclass->classInfo( name, super );
+}
+
+#ifndef TQT_NO_PROPERTIES
+
+/*!
+ Returns the number of properties for this class.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa propertyNames()
+ */
+int TQMetaObject::numProperties( bool super ) const // number of Q_SIGNALS
+{
+ int n = d->numPropData;
+ if ( !super || !superclass )
+ return n;
+ return n + superclass->numProperties( super );
+}
+
+/*!
+ Returns the property meta data for the property at index \a index
+ or 0 if no such property exists.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa propertyNames()
+ */
+const TQMetaProperty* TQMetaObject::property( int index, bool super ) const
+{
+ int idx = index - ( super ? propertyOffset() : 0 );
+ if ( d->propData && idx >= 0 && idx < (int)d->numPropData )
+ return d->propData + idx;
+ if ( !super || !superclass )
+ return 0;
+ return superclass->property( index, super );
+}
+
+
+/*!
+ Returns the index for the property with name \a name or -1 if no
+ such property exists.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa property(), propertyNames()
+*/
+
+int TQMetaObject::tqfindProperty( const char *name, bool super ) const
+{
+ for( int i = 0; i < d->numPropData; ++i ) {
+ if ( d->propData[i].isValid() && qstrcmp( d->propData[i].name(), name ) == 0 ) {
+ return ( super ? propertyOffset() : 0 ) + i;
+ }
+ }
+ if ( !super || !superclass )
+ return -1;
+ return superclass->tqfindProperty( name, super );
+}
+
+/*! \internal
+
+ Returns the index for the property \a prop
+ or -1 if the property can not be found.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa property(), propertyNames()
+*/
+
+int TQMetaObject::indexOfProperty( const TQMetaProperty* prop, bool super ) const
+{
+ if ( *prop->meta == this )
+ return ( super ? propertyOffset() : 0 ) + ( prop - d->propData);
+ if ( !super || !superclass )
+ return -1;
+ return superclass->indexOfProperty( prop, super );
+}
+
+/*!\internal
+
+ Returns the tqparent property of property \a p or 0, if the property
+ cannot be resolved.
+
+ \a p has to be contained in this meta object
+*/
+
+const TQMetaProperty* TQMetaObject::resolveProperty( const TQMetaProperty* p ) const
+{
+ if ( !superclass )
+ return 0;
+ return superclass->property( superclass->tqfindProperty( p->n, TRUE ), TRUE );
+}
+
+/*!\internal
+
+ \overload
+
+ The version of resolveProperty that is used by tqmoc generated code
+*/
+
+int TQMetaObject::resolveProperty( int index ) const
+{
+ if ( !superclass )
+ return -1;
+ const TQMetaProperty* p = d->propData + ( index - propertyOffset() );
+ return superclass->tqfindProperty( p->n, TRUE );
+}
+
+
+/*!
+ Returns a list with the names of all this class's properties.
+
+ If \a super is TRUE, inherited properties are included.
+
+ \sa property()
+*/
+TQStrList TQMetaObject::propertyNames( bool super ) const
+{
+ TQStrList l( FALSE );
+
+ if ( superclass && super ) {
+ TQStrList sl = superclass->propertyNames( super );
+ for ( TQStrListIterator slit( sl ); slit.current(); ++slit )
+ l.append( slit.current() );
+ }
+
+ for( int i = 0; i < d->numPropData; ++i ) {
+ if ( d->propData[i].isValid() )
+ l.append( d->propData[i].name() );
+ }
+
+ return l;
+}
+
+/*!
+ Returns a list with the names of all this class's Q_SIGNALS.
+
+ If \a super is TRUE, inherited Q_SIGNALS are included.
+*/
+TQStrList TQMetaObject::signalNames( bool super ) const
+{
+ TQStrList l( FALSE );
+ int n = numSignals( super );
+ for( int i = 0; i < n; ++i ) {
+ l.append( signal(i, super)->name );
+ }
+ return l;
+}
+
+/*!
+ Returns a list with the names of all this class's Q_SLOTS.
+
+ If \a super is TRUE, inherited Q_SLOTS are included.
+
+ \sa numSlots()
+*/
+TQStrList TQMetaObject::slotNames( bool super ) const
+{
+ TQStrList l( FALSE );
+ int n = numSlots( super );
+ for( int i = 0; i < n; ++i )
+ l.append( slot( i, super)->name );
+ return l;
+}
+
+/*!\internal
+
+ */
+
+int TQMetaObject::numEnumerators( bool super ) const
+{
+ int n = 0;
+ if ( superclass && super )
+ n += superclass->numEnumerators( super );
+ return n + d->numEnumData;
+}
+
+/*!\internal
+
+ */
+TQStrList TQMetaObject::enumeratorNames( bool super ) const
+{
+ TQStrList l( FALSE );
+
+ if ( superclass && super ) {
+ TQStrList sl = superclass->enumeratorNames( super );
+ for ( TQStrListIterator slit( sl ); slit.current(); ++slit )
+ l.append( slit.current() );
+ }
+
+ for( int i = 0; i < d->numEnumData; ++i ) {
+ if ( d->enumData[i].items )
+ l.append( d->enumData[i].name );
+ }
+
+ return l;
+}
+
+/*!\internal
+ */
+const TQMetaEnum* TQMetaObject::enumerator( const char* name, bool super ) const
+{
+ for( int i = 0; i < d->numEnumData; ++i )
+ if ( qstrcmp( d->enumData[i].name, name ) == 0 )
+ return &(d->enumData[i]);
+ if ( !super || !superclass )
+ return 0;
+ return superclass->enumerator( name, super );
+}
+
+#endif // TQT_NO_PROPERTIES
+
+
+/*!
+ Returns TRUE if this class inherits \a clname within the meta
+ object inheritance chain; otherwise returns FALSE.
+
+ (A class is considered to inherit itself.)
+*/
+bool TQMetaObject::inherits( const char* clname ) const
+{
+ const TQMetaObject *meta = this;
+ while ( meta ) {
+ if ( qstrcmp(clname, meta->className()) == 0 )
+ return TRUE;
+ meta = meta->superclass;
+ }
+ return FALSE;
+}
+
+/*! \internal */
+
+TQMetaObject *TQMetaObject::tqmetaObject( const char *class_name )
+{
+ if ( !qt_metaobjects )
+ return 0;
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &qt_metaobjects ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+ TQtStaticMetaObjectFunction func = (TQtStaticMetaObjectFunction)qt_metaobjects->tqfind( class_name );
+ if ( func )
+ return func();
+ return 0;
+}
+
+/*! \internal */
+bool TQMetaObject::hasMetaObject( const char *class_name )
+{
+ if ( !qt_metaobjects )
+ return FALSE;
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &qt_metaobjects ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+ return !!qt_metaobjects->tqfind( class_name );
+}
+
+#ifndef TQT_NO_PROPERTIES
+/*! \internal
+
+### this functions will go away. It exists purely for the sake of meta
+### object code generated with TQt 3.1.0
+*/
+bool TQMetaObject::qt_static_property( TQObject* o, int id, int f, TQVariant* v)
+{
+ if ( d->qt_static_property )
+ return d->qt_static_property( o, id, f, v );
+ else if ( o ) // compatibility
+ return o->qt_property( id, f, v );
+ else if ( superclass )
+ return superclass->qt_static_property( o, id, f, v );
+ switch ( f ) {
+ case 3: case 4: case 5:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+
+/*!
+ \class TQMetaProperty tqmetaobject.h
+
+ \brief The TQMetaProperty class stores meta data about a property.
+
+ \ingroup objectmodel
+
+ Property meta data includes type(), name(), and whether a property
+ is writable(), designable() and stored().
+
+ The functions isSetType(), isEnumType() and enumKeys() provide
+ further information about a property's type. The conversion
+ functions keyToValue(), valueToKey(), keysToValue() and
+ valueToKeys() allow conversion between the integer representation
+ of an enumeration or set value and its literal representation.
+
+ Actual property values are set and received through TQObject's set
+ and get functions. See TQObject::setProperty() and
+ TQObject::property() for details.
+
+ You receive meta property data through an object's meta object.
+ See TQMetaObject::property() and TQMetaObject::propertyNames() for
+ details.
+*/
+
+/*!
+ Returns the possible enumeration keys if this property is an
+ enumeration type (or a set type).
+
+ \sa isEnumType()
+*/
+TQStrList TQMetaProperty::enumKeys() const
+{
+ TQStrList l( FALSE );
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ if ( !ed )
+ return l;
+ if ( ed != 0 ) {
+ for( uint i = 0; i < ed->count; ++i ) {
+ uint j = 0;
+ while ( j < i &&
+ ed->items[j].value != ed->items[i].value )
+ ++j;
+ if ( i == j )
+ l.append( ed->items[i].key );
+ }
+ }
+ return l;
+}
+
+/*!
+ Converts the enumeration key \a key to its integer value.
+
+ For set types, use keysToValue().
+
+ \sa valueToKey(), isSetType(), keysToValue()
+*/
+int TQMetaProperty::keyToValue( const char* key ) const
+{
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ if ( !ed )
+ return -1;
+ for ( uint i = 0; i < ed->count; ++i ) {
+ if ( !qstrcmp( key, ed->items[i].key) )
+ return ed->items[i].value;
+ }
+ return -1;
+}
+
+/*!
+ Converts the enumeration value \a value to its literal key.
+
+ For set types, use valueToKeys().
+
+ \sa valueToKey(), isSetType(), valueToKeys()
+*/
+const char* TQMetaProperty::valueToKey( int value ) const
+{
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ if ( !ed )
+ return 0;
+ for ( uint i = 0; i < ed->count; ++i ) {
+ if ( value == ed->items[i].value )
+ return ed->items[i].key ;
+ }
+ return 0;
+}
+
+/*!
+ Converts the list of keys \a keys to their combined (OR-ed)
+ integer value.
+
+ \sa isSetType(), valueToKey(), keysToValue()
+*/
+int TQMetaProperty::keysToValue( const TQStrList& keys ) const
+{
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ if ( !ed )
+ return -1;
+ int value = 0;
+ for ( TQStrListIterator it( keys ); it.current(); ++it ) {
+ uint i;
+ for( i = ed->count; i > 0; --i ) {
+ if ( !qstrcmp( it.current(), ed->items[i-1].key) ) {
+ value |= ed->items[i-1].value;
+ break;
+ }
+ }
+ if ( i == 0 )
+ value |= -1;
+ }
+ return value;
+}
+
+/*!
+ Converts the set value \a value to a list of keys.
+
+ \sa isSetType(), valueToKey(), valueToKeys()
+*/
+TQStrList TQMetaProperty::valueToKeys( int value ) const
+{
+ TQStrList keys;
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ if ( !ed )
+ return keys;
+
+ int v = value;
+ for( uint i = ed->count; i > 0; --i ) {
+ int k = ed->items[i-1].value;
+ if ( ( k != 0 && (v & k) == k ) || ( k == value) ) {
+ v = v & ~k;
+ keys.append( ed->items[i-1].key );
+ }
+ }
+ return keys;
+}
+
+bool TQMetaProperty::writable() const
+{
+ if ( !testFlags( Override ) || testFlags( Writable ) )
+ return testFlags( Writable );
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->writable() : FALSE;
+}
+
+/*!\internal
+ */
+bool TQMetaProperty::stdSet() const
+{
+ if ( !testFlags( Override ) || testFlags( Writable ) )
+ return testFlags( StdSet );
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->stdSet() : FALSE;
+}
+
+/*!\internal
+ */
+int TQMetaProperty::id() const
+{
+ return _id < 0 ? (*meta)->indexOfProperty( this, TRUE ) : _id;
+}
+
+/*! \internal
+*/
+void TQMetaProperty::clear()
+{
+ t = n = 0;
+ meta = 0;
+ enumData = 0;
+ _id = -1;
+ flags = 0;
+}
+
+bool TQMetaProperty::isValid() const
+{
+ if ( testFlags( UnresolvedEnum ) ) {
+ if ( !enumData && (!meta || !(*meta)->enumerator( t, TRUE ) ) )
+ return FALSE;
+ }
+ if ( !testFlags( Override ) || testFlags( Readable ) )
+ return testFlags( Readable );
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->isValid() : FALSE;
+}
+
+bool TQMetaProperty::isSetType() const
+{
+ const TQMetaEnum* ed = enumData;
+ if ( !enumData && meta )
+ ed = (*meta)->enumerator( t, TRUE );
+ return ( ed != 0 && ed->set );
+}
+
+bool TQMetaProperty::isEnumType() const
+{
+ return testFlags( EnumOrSet );
+}
+
+
+
+/*!
+ \fn const char* TQMetaProperty::type() const
+
+ Returns the type of the property.
+*/
+
+/*!
+ \fn const char* TQMetaProperty::name() const
+
+ Returns the name of the property.
+*/
+
+/*!
+ \fn bool TQMetaProperty::writable() const
+
+ Returns TRUE if the property is writable; otherwise returns FALSE.
+
+*/
+
+/*! \fn bool TQMetaProperty::isValid() const
+
+ \internal
+
+ Returns whether the property is valid.
+*/
+
+/*!
+ \fn bool TQMetaProperty::isEnumType() const
+
+ Returns TRUE if the property's type is an enumeration value;
+ otherwise returns FALSE.
+
+ \sa isSetType(), enumKeys()
+*/
+
+/*!
+ \fn bool TQMetaProperty::isSetType() const
+
+ Returns TRUE if the property's type is an enumeration value that
+ is used as set, i.e. if the enumeration values can be OR-ed
+ together; otherwise returns FALSE. A set type is implicitly also
+ an enum type.
+
+ \sa isEnumType(), enumKeys()
+*/
+
+
+/*! Returns TRUE if the property is designable for object \a o;
+ otherwise returns FALSE.
+
+ If no object \a o is given, the function returns a static
+ approximation.
+ */
+bool TQMetaProperty::designable( TQObject* o ) const
+{
+ if ( !isValid() || !writable() )
+ return FALSE;
+ if ( o ) {
+ int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
+ return idx >= 0 && o->qt_property( idx, 3, 0 );
+ }
+ if ( testFlags( DesignableOverride ) ) {
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->designable() : FALSE;
+ }
+ return !testFlags( NotDesignable );
+}
+
+/*!
+ Returns TRUE if the property is scriptable for object \a o;
+ otherwise returns FALSE.
+
+ If no object \a o is given, the function returns a static
+ approximation.
+ */
+bool TQMetaProperty::scriptable( TQObject* o ) const
+{
+ if ( o ) {
+ int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
+ return idx >= 0 && o->qt_property( idx, 4, 0 );
+ }
+ if ( testFlags( ScriptableOverride ) ) {
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->scriptable() : FALSE;
+ }
+ return !testFlags( NotScriptable );
+}
+
+/*!
+ Returns TRUE if the property shall be stored for object \a o;
+ otherwise returns FALSE.
+
+ If no object \a o is given, the function returns a static
+ approximation.
+ */
+bool TQMetaProperty::stored( TQObject* o ) const
+{
+ if ( !isValid() || !writable() )
+ return FALSE;
+ if ( o ) {
+ int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
+ return idx >= 0 && o->qt_property( idx, 5, 0 );
+ }
+ if ( testFlags( StoredOverride ) ) {
+ const TQMetaObject* mo = (*meta);
+ const TQMetaProperty* tqparent = mo->resolveProperty( this );
+ return tqparent ? tqparent->stored() : FALSE;
+ }
+ return !testFlags( NotStored );
+}
+
+
+/*!
+ Tries to reset the property for object \a o with a reset method.
+ On success, returns TRUE; otherwise returns FALSE.
+
+ Reset methods are optional, usually only a few properties support
+ them.
+*/
+bool TQMetaProperty::reset( TQObject* o ) const
+{
+ if ( !o )
+ return FALSE;
+ int idx = _id >= 0 ? _id : (*meta)->indexOfProperty( this, TRUE );
+ if ( idx < 0 )
+ return 0;
+ return o->qt_property( idx, 2, 0 );
+}
+
+
+/*! \enum TQMetaProperty::Flags
+
+ \internal
+*/
+
+#endif // TQT_NO_PROPERTIES
+
+/*
+ * TQMetaObjectCleanUp is used as static global object in the tqmoc-generated cpp
+ * files and deletes the TQMetaObject provided with setMetaObject. It sets the
+ * TQObject reference to the metaObj to NULL when it is destroyed.
+ */
+TQMetaObjectCleanUp::TQMetaObjectCleanUp( const char *mo_name, TQtStaticMetaObjectFunction func )
+ : tqmetaObject( 0 )
+{
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &qt_metaobjects ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+ if ( !qt_metaobjects )
+ qt_metaobjects = new TQAsciiDict<void>( 257 );
+ qt_metaobjects->insert( mo_name, (void*)func );
+
+ qt_metaobjects_count++;
+}
+
+TQMetaObjectCleanUp::TQMetaObjectCleanUp()
+ : tqmetaObject( 0 )
+{
+}
+
+/*! \fn bool TQMetaProperty::testFlags( uint f ) const
+ \internal
+*/
+
+TQMetaObjectCleanUp::~TQMetaObjectCleanUp()
+{
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &qt_metaobjects ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+ if ( !--qt_metaobjects_count ) {
+ delete qt_metaobjects;
+ qt_metaobjects = 0;
+ }
+ if ( tqmetaObject ) {
+ delete *tqmetaObject;
+ *tqmetaObject = 0;
+ tqmetaObject = 0;
+ }
+}
+
+void TQMetaObjectCleanUp::setMetaObject( TQMetaObject *&mo )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( tqmetaObject )
+ qWarning( "TQMetaObjectCleanUp::setMetaObject: Double use of TQMetaObjectCleanUp!" );
+#endif
+ tqmetaObject = &mo;
+}
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqmetaobject.h b/tqtinterface/qt4/src/kernel/tqmetaobject.h
new file mode 100644
index 0000000..5502743
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmetaobject.h
@@ -0,0 +1,404 @@
+/****************************************************************************
+**
+** Definition of TQMetaObject class
+**
+** Created : 930419
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMETAOBJECT_H
+#define TQMETAOBJECT_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqconnection.h"
+#include "tqstrlist.h"
+#endif // TQT_H
+
+#ifndef TQ_TQMOC_OUTPUT_REVISION
+#define TQ_TQMOC_OUTPUT_REVISION 26
+#endif
+
+#ifdef USE_QT4
+
+#include <Qt/qmetaobject.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+struct TQUMethod;
+
+class TQ_EXPORT TQMetaEnum : public QMetaEnum, virtual public TQt
+{
+public:
+ TQMetaEnum();
+
+ struct Item // - a name/value pair
+ {
+ const char *key;
+ int value;
+ };
+
+ uint count() const;
+ Item* items() const;
+
+private:
+ mutable Item* internal_item_list;
+ mutable int internal_item_count;
+};
+
+class TQ_EXPORT TQMetaData : public QMetaMethod, virtual public TQt
+{
+public:
+ TQMetaData();
+
+ const char *name() const;
+ const TQUMethod* method() const;
+
+ mutable TQUMethod* internal_method_information;
+};
+
+class TQ_EXPORT TQMetaProperty : public QMetaProperty, virtual public TQt
+{
+public:
+ TQMetaProperty();
+
+ bool isSetType() const;
+ int keyToValue( const char* key ) const;
+ const char* valueToKey( int value ) const;
+ int keysToValue( const TQStrList& keys_in ) const;
+ TQStrList valueToKeys( int value ) const;
+ bool writable() const;
+ const char* type() const;
+ TQStrList enumKeys() const;
+
+ bool designable( TQT_BASE_OBJECT_NAME *o = 0 ) const;
+ bool scriptable( TQT_BASE_OBJECT_NAME *o = 0 ) const;
+ bool stored( TQT_BASE_OBJECT_NAME *o = 0 ) const;
+
+ bool stdSet() const; // internal
+
+// inline bool reset( TQT_BASE_OBJECT_NAME *o ) const { return isResettable(o); }
+};
+
+class TQ_EXPORT TQClassInfo : public QMetaClassInfo, virtual public TQt
+{
+public:
+ TQClassInfo() : QMetaClassInfo() {}
+};
+
+class TQ_EXPORT TQMetaObject : public QMetaObject, virtual public TQt
+{
+public:
+ TQMetaObject( const char * const class_name, TQMetaObject *superclass, const TQMetaData * const slot_data, int n_Q_SLOTS, const TQMetaData * const signal_data, int n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *const prop_data, int n_props, const TQMetaEnum *const enum_data, int n_enums,
+#endif // TQT_NO_PROPERTIES
+ const TQClassInfo *const class_info, int n_info );
+
+#ifndef TQT_NO_PROPERTIES
+ TQMetaObject( const char * const class_name, TQMetaObject *superclass, const TQMetaData * const slot_data, int n_Q_SLOTS, const TQMetaData * const signal_data, int n_Q_SIGNALS, const TQMetaProperty *const prop_data, int n_props, const TQMetaEnum *const enum_data, int n_enums, bool (*qt_static_property)(TQObject*, int, int, TQVariant*), const TQClassInfo *const class_info, int n_info );
+#endif // TQT_NO_PROPERTIES
+
+ TQStrList slotNames( bool super = FALSE ) const;
+ TQStrList signalNames( bool super = FALSE ) const;
+
+#ifndef TQT_NO_PROPERTIES
+ int tqfindProperty( const char *name, bool super = FALSE ) const;
+ TQMetaObject *tqsuperClass() const;
+ const char *tqsuperClassName() const;
+ TQStrList propertyNames( bool super = FALSE ) const;
+
+ int numSlots( bool super = FALSE ) const;
+ int numSignals( bool super = FALSE ) const;
+ int numClassInfo( bool super = FALSE ) const;
+
+ const TQMetaData *slot( int index, bool super = FALSE ) const;
+ const TQMetaData *signal( int index, bool super = FALSE ) const;
+
+ int tqfindSlot( const char *, bool super = FALSE ) const;
+ int tqfindSignal( const char *, bool super = FALSE ) const;
+
+ int numProperties( bool super = FALSE ) const;
+ const TQMetaProperty *property( int index, bool super = FALSE ) const;
+
+ const TQMetaEnum *enumerator( const char* name, bool super = FALSE ) const;
+ TQStrList enumeratorNames( bool super = FALSE ) const;
+#endif // TQT_NO_PROPERTIES
+
+ const TQClassInfo *classInfo( int index, bool super = FALSE ) const;
+ const char *classInfo( const char* name, bool super = FALSE ) const;
+};
+
+#else // USE_QT4
+
+class TQObject;
+struct TQUMethod;
+class TQMetaObjectPrivate;
+
+struct TQMetaData // - member function meta data
+{ // for signal and Q_SLOTS
+ const char *name; // - member name
+ const TQUMethod* method; // - detailed method description
+ enum Access { Private, Protected, Public };
+ Access access; // - access permission
+};
+
+#ifndef TQT_NO_PROPERTIES
+struct TQMetaEnum // enumerator meta data
+{ // for properties
+ const char *name; // - enumerator name
+ uint count; // - number of values
+ struct Item // - a name/value pair
+ {
+ const char *key;
+ int value;
+ };
+ const Item *items; // - the name/value pairs
+ bool set; // whether enum has to be treated as a set
+};
+#endif
+
+#ifndef TQT_NO_PROPERTIES
+
+class TQ_EXPORT TQMetaProperty // property meta data
+{
+public:
+ const char* type() const { return t; } // type of the property
+ const char* name() const { return n; } // name of the property
+
+ bool writable() const;
+ bool isValid() const;
+
+ bool isSetType() const;
+ bool isEnumType() const;
+ TQStrList enumKeys() const; // enumeration names
+
+ int keyToValue( const char* key ) const; // enum and set conversion functions
+ const char* valueToKey( int value ) const;
+ int keysToValue( const TQStrList& keys ) const;
+ TQStrList valueToKeys( int value ) const;
+
+ bool designable( TQObject* = 0 ) const;
+ bool scriptable( TQObject* = 0 ) const;
+ bool stored( TQObject* = 0 ) const;
+
+ bool reset( TQObject* ) const;
+
+ const char* t; // internal
+ const char* n; // internal
+
+ enum Flags {
+ Invalid = 0x00000000,
+ Readable = 0x00000001,
+ Writable = 0x00000002,
+ EnumOrSet = 0x00000004,
+ UnresolvedEnum = 0x00000008,
+ StdSet = 0x00000100,
+ Override = 0x00000200
+ };
+
+ uint flags; // internal
+ bool testFlags( uint f ) const; // internal
+ bool stdSet() const; // internal
+ int id() const; // internal
+
+ TQMetaObject** meta; // internal
+
+ const TQMetaEnum* enumData; // internal
+ int _id; // internal
+ void clear(); // internal
+};
+
+inline bool TQMetaProperty::testFlags( uint f ) const
+{ return (flags & (uint)f) != (uint)0; }
+
+#endif // TQT_NO_PROPERTIES
+
+struct TQClassInfo // class info meta data
+{
+ const char* name; // - name of the info
+ const char* value; // - value of the info
+};
+
+class TQ_EXPORT TQMetaObject // meta object class
+{
+public:
+ TQMetaObject( const char * const class_name, TQMetaObject *superclass,
+ const TQMetaData * const slot_data, int n_Q_SLOTS,
+ const TQMetaData * const signal_data, int n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+#endif
+ const TQClassInfo *const class_info, int n_info );
+
+#ifndef TQT_NO_PROPERTIES
+ TQMetaObject( const char * const class_name, TQMetaObject *superclass,
+ const TQMetaData * const slot_data, int n_Q_SLOTS,
+ const TQMetaData * const signal_data, int n_Q_SIGNALS,
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+ bool (*qt_static_property)(TQObject*, int, int, TQVariant*),
+ const TQClassInfo *const class_info, int n_info );
+#endif
+
+
+ virtual ~TQMetaObject();
+
+ const char *className() const { return classname; }
+ const char *superClassName() const { return superclassname; }
+
+ TQMetaObject *superClass() const { return superclass; }
+
+ bool inherits( const char* clname ) const;
+
+ int numSlots( bool super = FALSE ) const;
+ int numSignals( bool super = FALSE ) const;
+
+ int tqfindSlot( const char *, bool super = FALSE ) const;
+ int tqfindSignal( const char *, bool super = FALSE ) const;
+
+ const TQMetaData *slot( int index, bool super = FALSE ) const;
+ const TQMetaData *signal( int index, bool super = FALSE ) const;
+
+ TQStrList slotNames( bool super = FALSE ) const;
+ TQStrList signalNames( bool super = FALSE ) const;
+
+ int slotOffset() const;
+ int signalOffset() const;
+ int propertyOffset() const;
+
+ int numClassInfo( bool super = FALSE ) const;
+ const TQClassInfo *classInfo( int index, bool super = FALSE ) const;
+ const char *classInfo( const char* name, bool super = FALSE ) const;
+
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *property( int index, bool super = FALSE ) const;
+ int tqfindProperty( const char *name, bool super = FALSE ) const;
+ int indexOfProperty( const TQMetaProperty*, bool super = FALSE ) const;
+ const TQMetaProperty* resolveProperty( const TQMetaProperty* ) const;
+ int resolveProperty( int ) const;
+ TQStrList propertyNames( bool super = FALSE ) const;
+ int numProperties( bool super = FALSE ) const;
+#endif
+
+ // static wrappers around constructors, necessary to work around a
+ // Windows-DLL limitation: objects can only be deleted within a
+ // DLL if they were actually created within that DLL.
+ static TQMetaObject *new_metaobject( const char *, TQMetaObject *,
+ const TQMetaData *const, int,
+ const TQMetaData *const, int,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+#endif
+ const TQClassInfo *const class_info, int n_info );
+#ifndef TQT_NO_PROPERTIES
+ static TQMetaObject *new_metaobject( const char *, TQMetaObject *,
+ const TQMetaData *const, int,
+ const TQMetaData *const, int,
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+ bool (*qt_static_property)(TQObject*, int, int, TQVariant*),
+ const TQClassInfo *const class_info, int n_info );
+ TQStrList enumeratorNames( bool super = FALSE ) const;
+ int numEnumerators( bool super = FALSE ) const;
+ const TQMetaEnum *enumerator( const char* name, bool super = FALSE ) const;
+#endif
+
+ static TQMetaObject *tqmetaObject( const char *class_name );
+ static bool hasMetaObject( const char *class_name );
+
+private:
+ TQMemberDict *init( const TQMetaData *, int );
+
+ const char *classname; // class name
+ const char *superclassname; // super class name
+ TQMetaObject *superclass; // super class meta object
+ TQMetaObjectPrivate *d; // private data for...
+ void *reserved; // ...binary compatibility
+ const TQMetaData *slotData; // slot meta data
+ TQMemberDict *slotDict; // slot dictionary
+ const TQMetaData *signalData; // signal meta data
+ TQMemberDict *signalDict; // signal dictionary
+ int signaloffset;
+ int slotoffset;
+#ifndef TQT_NO_PROPERTIES
+ int propertyoffset;
+public:
+ bool qt_static_property( TQObject* o, int id, int f, TQVariant* v);
+private:
+ friend class TQMetaProperty;
+#endif
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQMetaObject( const TQMetaObject & );
+ TQMetaObject &operator=( const TQMetaObject & );
+#endif
+};
+
+inline int TQMetaObject::slotOffset() const
+{ return slotoffset; }
+
+inline int TQMetaObject::signalOffset() const
+{ return signaloffset; }
+
+#ifndef TQT_NO_PROPERTIES
+inline int TQMetaObject::propertyOffset() const
+{ return propertyoffset; }
+#endif
+
+typedef TQMetaObject *(*TQtStaticMetaObjectFunction)();
+
+class TQ_EXPORT TQMetaObjectCleanUp
+{
+public:
+ TQMetaObjectCleanUp( const char *mo_name, TQtStaticMetaObjectFunction );
+ TQMetaObjectCleanUp();
+ ~TQMetaObjectCleanUp();
+
+ void setMetaObject( TQMetaObject *&mo );
+
+private:
+ TQMetaObject **tqmetaObject;
+};
+
+#endif // USE_QT4
+
+#endif // TQMETAOBJECT_H
diff --git a/tqtinterface/qt4/src/kernel/tqmetaobject.h~ b/tqtinterface/qt4/src/kernel/tqmetaobject.h~
new file mode 100644
index 0000000..ecb6c23
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmetaobject.h~
@@ -0,0 +1,403 @@
+/****************************************************************************
+**
+** Definition of TQMetaObject class
+**
+** Created : 930419
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMETAOBJECT_H
+#define TQMETAOBJECT_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqconnection.h"
+#include "tqstrlist.h"
+#endif // TQT_H
+
+#ifndef TQ_TQMOC_OUTPUT_REVISION
+#define TQ_TQMOC_OUTPUT_REVISION 26
+#endif
+
+#ifdef USE_QT4
+
+#include <Qt/qmetaobject.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+struct TQUMethod;
+
+class TQ_EXPORT TQMetaEnum : public QMetaEnum, virtual public TQt
+{
+public:
+ TQMetaEnum();
+
+ struct Item // - a name/value pair
+ {
+ const char *key;
+ int value;
+ };
+
+ uint count() const;
+ Item* items() const;
+
+private:
+ mutable Item* internal_item_list;
+};
+
+class TQ_EXPORT TQMetaData : public QMetaMethod, virtual public TQt
+{
+public:
+ TQMetaData();
+
+ const char *name() const;
+ const TQUMethod* method() const;
+
+ mutable TQUMethod* internal_method_information;
+};
+
+class TQ_EXPORT TQMetaProperty : public QMetaProperty, virtual public TQt
+{
+public:
+ TQMetaProperty();
+
+ bool isSetType() const;
+ int keyToValue( const char* key ) const;
+ const char* valueToKey( int value ) const;
+ int keysToValue( const TQStrList& keys_in ) const;
+ TQStrList valueToKeys( int value ) const;
+ bool writable() const;
+ const char* type() const;
+ TQStrList enumKeys() const;
+
+ bool designable( TQT_BASE_OBJECT_NAME *o = 0 ) const;
+ bool scriptable( TQT_BASE_OBJECT_NAME *o = 0 ) const;
+ bool stored( TQT_BASE_OBJECT_NAME *o = 0 ) const;
+
+ bool stdSet() const; // internal
+
+// inline bool reset( TQT_BASE_OBJECT_NAME *o ) const { return isResettable(o); }
+};
+
+class TQ_EXPORT TQClassInfo : public QMetaClassInfo, virtual public TQt
+{
+public:
+ TQClassInfo() : QMetaClassInfo() {}
+};
+
+class TQ_EXPORT TQMetaObject : public QMetaObject, virtual public TQt
+{
+public:
+ TQMetaObject( const char * const class_name, TQMetaObject *superclass, const TQMetaData * const slot_data, int n_Q_SLOTS, const TQMetaData * const signal_data, int n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *const prop_data, int n_props, const TQMetaEnum *const enum_data, int n_enums,
+#endif // TQT_NO_PROPERTIES
+ const TQClassInfo *const class_info, int n_info );
+
+#ifndef TQT_NO_PROPERTIES
+ TQMetaObject( const char * const class_name, TQMetaObject *superclass, const TQMetaData * const slot_data, int n_Q_SLOTS, const TQMetaData * const signal_data, int n_Q_SIGNALS, const TQMetaProperty *const prop_data, int n_props, const TQMetaEnum *const enum_data, int n_enums, bool (*qt_static_property)(TQObject*, int, int, TQVariant*), const TQClassInfo *const class_info, int n_info );
+#endif // TQT_NO_PROPERTIES
+
+ TQStrList slotNames( bool super = FALSE ) const;
+ TQStrList signalNames( bool super = FALSE ) const;
+
+#ifndef TQT_NO_PROPERTIES
+ int tqfindProperty( const char *name, bool super = FALSE ) const;
+ TQMetaObject *tqsuperClass() const;
+ const char *tqsuperClassName() const;
+ TQStrList propertyNames( bool super = FALSE ) const;
+
+ int numSlots( bool super = FALSE ) const;
+ int numSignals( bool super = FALSE ) const;
+ int numClassInfo( bool super = FALSE ) const;
+
+ const TQMetaData *slot( int index, bool super = FALSE ) const;
+ const TQMetaData *signal( int index, bool super = FALSE ) const;
+
+ int tqfindSlot( const char *, bool super = FALSE ) const;
+ int tqfindSignal( const char *, bool super = FALSE ) const;
+
+ int numProperties( bool super = FALSE ) const;
+ const TQMetaProperty *property( int index, bool super = FALSE ) const;
+
+ const TQMetaEnum *enumerator( const char* name, bool super = FALSE ) const;
+ TQStrList enumeratorNames( bool super = FALSE ) const;
+#endif // TQT_NO_PROPERTIES
+
+ const TQClassInfo *classInfo( int index, bool super = FALSE ) const;
+ const char *classInfo( const char* name, bool super = FALSE ) const;
+};
+
+#else // USE_QT4
+
+class TQObject;
+struct TQUMethod;
+class TQMetaObjectPrivate;
+
+struct TQMetaData // - member function meta data
+{ // for signal and Q_SLOTS
+ const char *name; // - member name
+ const TQUMethod* method; // - detailed method description
+ enum Access { Private, Protected, Public };
+ Access access; // - access permission
+};
+
+#ifndef TQT_NO_PROPERTIES
+struct TQMetaEnum // enumerator meta data
+{ // for properties
+ const char *name; // - enumerator name
+ uint count; // - number of values
+ struct Item // - a name/value pair
+ {
+ const char *key;
+ int value;
+ };
+ const Item *items; // - the name/value pairs
+ bool set; // whether enum has to be treated as a set
+};
+#endif
+
+#ifndef TQT_NO_PROPERTIES
+
+class TQ_EXPORT TQMetaProperty // property meta data
+{
+public:
+ const char* type() const { return t; } // type of the property
+ const char* name() const { return n; } // name of the property
+
+ bool writable() const;
+ bool isValid() const;
+
+ bool isSetType() const;
+ bool isEnumType() const;
+ TQStrList enumKeys() const; // enumeration names
+
+ int keyToValue( const char* key ) const; // enum and set conversion functions
+ const char* valueToKey( int value ) const;
+ int keysToValue( const TQStrList& keys ) const;
+ TQStrList valueToKeys( int value ) const;
+
+ bool designable( TQObject* = 0 ) const;
+ bool scriptable( TQObject* = 0 ) const;
+ bool stored( TQObject* = 0 ) const;
+
+ bool reset( TQObject* ) const;
+
+ const char* t; // internal
+ const char* n; // internal
+
+ enum Flags {
+ Invalid = 0x00000000,
+ Readable = 0x00000001,
+ Writable = 0x00000002,
+ EnumOrSet = 0x00000004,
+ UnresolvedEnum = 0x00000008,
+ StdSet = 0x00000100,
+ Override = 0x00000200
+ };
+
+ uint flags; // internal
+ bool testFlags( uint f ) const; // internal
+ bool stdSet() const; // internal
+ int id() const; // internal
+
+ TQMetaObject** meta; // internal
+
+ const TQMetaEnum* enumData; // internal
+ int _id; // internal
+ void clear(); // internal
+};
+
+inline bool TQMetaProperty::testFlags( uint f ) const
+{ return (flags & (uint)f) != (uint)0; }
+
+#endif // TQT_NO_PROPERTIES
+
+struct TQClassInfo // class info meta data
+{
+ const char* name; // - name of the info
+ const char* value; // - value of the info
+};
+
+class TQ_EXPORT TQMetaObject // meta object class
+{
+public:
+ TQMetaObject( const char * const class_name, TQMetaObject *superclass,
+ const TQMetaData * const slot_data, int n_Q_SLOTS,
+ const TQMetaData * const signal_data, int n_Q_SIGNALS,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+#endif
+ const TQClassInfo *const class_info, int n_info );
+
+#ifndef TQT_NO_PROPERTIES
+ TQMetaObject( const char * const class_name, TQMetaObject *superclass,
+ const TQMetaData * const slot_data, int n_Q_SLOTS,
+ const TQMetaData * const signal_data, int n_Q_SIGNALS,
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+ bool (*qt_static_property)(TQObject*, int, int, TQVariant*),
+ const TQClassInfo *const class_info, int n_info );
+#endif
+
+
+ virtual ~TQMetaObject();
+
+ const char *className() const { return classname; }
+ const char *superClassName() const { return superclassname; }
+
+ TQMetaObject *superClass() const { return superclass; }
+
+ bool inherits( const char* clname ) const;
+
+ int numSlots( bool super = FALSE ) const;
+ int numSignals( bool super = FALSE ) const;
+
+ int tqfindSlot( const char *, bool super = FALSE ) const;
+ int tqfindSignal( const char *, bool super = FALSE ) const;
+
+ const TQMetaData *slot( int index, bool super = FALSE ) const;
+ const TQMetaData *signal( int index, bool super = FALSE ) const;
+
+ TQStrList slotNames( bool super = FALSE ) const;
+ TQStrList signalNames( bool super = FALSE ) const;
+
+ int slotOffset() const;
+ int signalOffset() const;
+ int propertyOffset() const;
+
+ int numClassInfo( bool super = FALSE ) const;
+ const TQClassInfo *classInfo( int index, bool super = FALSE ) const;
+ const char *classInfo( const char* name, bool super = FALSE ) const;
+
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *property( int index, bool super = FALSE ) const;
+ int tqfindProperty( const char *name, bool super = FALSE ) const;
+ int indexOfProperty( const TQMetaProperty*, bool super = FALSE ) const;
+ const TQMetaProperty* resolveProperty( const TQMetaProperty* ) const;
+ int resolveProperty( int ) const;
+ TQStrList propertyNames( bool super = FALSE ) const;
+ int numProperties( bool super = FALSE ) const;
+#endif
+
+ // static wrappers around constructors, necessary to work around a
+ // Windows-DLL limitation: objects can only be deleted within a
+ // DLL if they were actually created within that DLL.
+ static TQMetaObject *new_metaobject( const char *, TQMetaObject *,
+ const TQMetaData *const, int,
+ const TQMetaData *const, int,
+#ifndef TQT_NO_PROPERTIES
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+#endif
+ const TQClassInfo *const class_info, int n_info );
+#ifndef TQT_NO_PROPERTIES
+ static TQMetaObject *new_metaobject( const char *, TQMetaObject *,
+ const TQMetaData *const, int,
+ const TQMetaData *const, int,
+ const TQMetaProperty *const prop_data, int n_props,
+ const TQMetaEnum *const enum_data, int n_enums,
+ bool (*qt_static_property)(TQObject*, int, int, TQVariant*),
+ const TQClassInfo *const class_info, int n_info );
+ TQStrList enumeratorNames( bool super = FALSE ) const;
+ int numEnumerators( bool super = FALSE ) const;
+ const TQMetaEnum *enumerator( const char* name, bool super = FALSE ) const;
+#endif
+
+ static TQMetaObject *tqmetaObject( const char *class_name );
+ static bool hasMetaObject( const char *class_name );
+
+private:
+ TQMemberDict *init( const TQMetaData *, int );
+
+ const char *classname; // class name
+ const char *superclassname; // super class name
+ TQMetaObject *superclass; // super class meta object
+ TQMetaObjectPrivate *d; // private data for...
+ void *reserved; // ...binary compatibility
+ const TQMetaData *slotData; // slot meta data
+ TQMemberDict *slotDict; // slot dictionary
+ const TQMetaData *signalData; // signal meta data
+ TQMemberDict *signalDict; // signal dictionary
+ int signaloffset;
+ int slotoffset;
+#ifndef TQT_NO_PROPERTIES
+ int propertyoffset;
+public:
+ bool qt_static_property( TQObject* o, int id, int f, TQVariant* v);
+private:
+ friend class TQMetaProperty;
+#endif
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQMetaObject( const TQMetaObject & );
+ TQMetaObject &operator=( const TQMetaObject & );
+#endif
+};
+
+inline int TQMetaObject::slotOffset() const
+{ return slotoffset; }
+
+inline int TQMetaObject::signalOffset() const
+{ return signaloffset; }
+
+#ifndef TQT_NO_PROPERTIES
+inline int TQMetaObject::propertyOffset() const
+{ return propertyoffset; }
+#endif
+
+typedef TQMetaObject *(*TQtStaticMetaObjectFunction)();
+
+class TQ_EXPORT TQMetaObjectCleanUp
+{
+public:
+ TQMetaObjectCleanUp( const char *mo_name, TQtStaticMetaObjectFunction );
+ TQMetaObjectCleanUp();
+ ~TQMetaObjectCleanUp();
+
+ void setMetaObject( TQMetaObject *&mo );
+
+private:
+ TQMetaObject **tqmetaObject;
+};
+
+#endif // USE_QT4
+
+#endif // TQMETAOBJECT_H
diff --git a/tqtinterface/qt4/src/kernel/tqmime.cpp b/tqtinterface/qt4/src/kernel/tqmime.cpp
new file mode 100644
index 0000000..46d07d3
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmime.cpp
@@ -0,0 +1,1158 @@
+/****************************************************************************
+**
+** Implementation of MIME support
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmime.h"
+
+#ifndef TQT_NO_MIME
+
+#include "tqmap.h"
+#include "tqstringlist.h"
+#include "tqfileinfo.h"
+#include "tqdir.h"
+#include "tqdragobject.h"
+#include "tqcleanuphandler.h"
+#include "tqapplication.h" // ### for now
+#include "tqclipboard.h" // ### for now
+
+#ifdef USE_QT4
+
+#include "Qt/qmap.h"
+#include "Qt/qstringlist.h"
+#include "Qt/qfileinfo.h"
+#include "Qt/qdir.h"
+#include "tqdragobject.h"
+#include "Qt/qpixmap.h"
+#include "Qt/qimagereader.h"
+#include "tqcleanuphandler.h"
+#include "private/qt4_qtextimagehandler_p.h"
+
+#endif // USE_QT4
+
+static int qt_mime_serial_number = 0;
+static TQMimeSourceFactory* defaultfactory = 0;
+static TQSingleCleanupHandler<TQMimeSourceFactory> qmime_cleanup_factory;
+
+#ifdef USE_QT4
+// #if 0
+
+TQMimeSource::TQMimeSource() : QMimeSource() {
+ cacheType = NoCache;
+ ser_no = qt_mime_serial_number++;
+}
+
+/*!
+ \fn int TQMimeSource::serialNumber() const
+
+ Returns the mime source's globally unique serial number.
+*/
+
+
+void TQMimeSource::clearCache()
+{
+ if ( cacheType == Text ) {
+ delete cache.txt.str;
+ delete cache.txt.subtype;
+ cache.txt.str = 0;
+ cache.txt.subtype = 0;
+ } else if ( cacheType == Graphics ) {
+ delete cache.gfx.img;
+ delete cache.gfx.pix;
+ cache.gfx.img = 0;
+ cache.gfx.pix = 0;
+ }
+ cacheType = NoCache;
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQMimeSource tqmime.h
+ \brief The TQMimeSource class is an abstraction of objects which provide formatted data of a certain MIME type.
+
+ \ingroup io
+ \ingroup draganddrop
+ \ingroup misc
+
+ \link dnd.html Drag-and-drop\endlink and
+ \link TQClipboard clipboard\endlink use this abstraction.
+
+ \sa \link http://www.isi.edu/in-notes/iana/assignments/media-types/
+ IANA list of MIME media types\endlink
+*/
+
+/*!
+ Constructs a mime source and assigns a globally unique serial
+ number to it.
+
+ \sa serialNumber()
+*/
+
+TQMimeSource::TQMimeSource()
+{
+ ser_no = qt_mime_serial_number++;
+ cacheType = NoCache;
+}
+
+/*!
+ \fn int TQMimeSource::serialNumber() const
+
+ Returns the mime source's globally unique serial number.
+*/
+
+
+void TQMimeSource::clearCache()
+{
+ if ( cacheType == Text ) {
+ delete cache.txt.str;
+ delete cache.txt.subtype;
+ cache.txt.str = 0;
+ cache.txt.subtype = 0;
+ } else if ( cacheType == Graphics ) {
+ delete cache.gfx.img;
+ delete cache.gfx.pix;
+ cache.gfx.img = 0;
+ cache.gfx.pix = 0;
+ }
+ cacheType = NoCache;
+}
+
+/*!
+ Provided to ensure that subclasses destroy themselves correctly.
+*/
+TQMimeSource::~TQMimeSource()
+{
+#ifndef TQT_NO_CLIPBOARD
+ extern void qt_clipboard_cleanup_mime_source(TQMimeSource *);
+ qt_clipboard_cleanup_mime_source(this);
+#endif
+ clearCache();
+}
+
+/*!
+ \fn TQByteArray TQMimeSource::tqencodedData(const char*) const
+
+ Returns the encoded data of this object in the specified MIME
+ format.
+
+ Subclasses must reimplement this function.
+*/
+
+
+
+/*!
+ Returns TRUE if the object can provide the data in format \a
+ mimeType; otherwise returns FALSE.
+
+ If you inherit from TQMimeSource, for consistency reasons it is
+ better to implement the more abstract canDecode() functions such
+ as TQTextDrag::canDecode() and TQImageDrag::canDecode().
+*/
+bool TQMimeSource::provides(const char* mimeType) const
+{
+ const char* fmt;
+ for (int i=0; (fmt = format(i)); i++) {
+ if ( !qstricmp(mimeType,fmt) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#endif // USE_QT4
+
+// #ifdef USE_QT4
+#if 0
+
+QT_BEGIN_NAMESPACE
+
+class TQMimeSourceFactoryData {
+public:
+ TQMimeSourceFactoryData() :
+ last(0)
+ {
+ }
+
+ ~TQMimeSourceFactoryData()
+ {
+ QMap<QString, QMimeSource*>::Iterator it = stored.begin();
+ while (it != stored.end()) {
+ delete *it;
+ ++it;
+ }
+ delete last;
+ }
+
+ QMap<QString, QMimeSource*> stored;
+ QMap<QString, QString> extensions;
+ QStringList path;
+ QMimeSource* last;
+ QList<TQMimeSourceFactory*> factories;
+};
+
+static QImage richTextImageLoader(const QString &name, const QString &context)
+{
+ QImage img;
+
+ const TQMimeSource *src = static_cast<const TQMimeSource*>(TQMimeSourceFactory::defaultFactory()->data(name, context));
+ if (src && TQImageDrag::decode(src, img))
+ return img;
+
+ return QImage();
+}
+
+/*!
+ \class TQMimeSourceFactory
+ \brief The TQMimeSourceFactory class is an extensible provider of mime-typed data.
+
+ \compat
+
+ A TQMimeSourceFactory provides an abstract interface to a
+ collection of information. Each piece of information is
+ represented by a QMimeSource object which can be examined and
+ converted to concrete data types by functions such as
+ TQImageDrag::canDecode() and TQImageDrag::decode().
+
+ The base TQMimeSourceFactory can be used in two ways: as an
+ abstraction of a collection of files or as specifically stored
+ data. For it to access files, call setFilePath() before accessing
+ data. For stored data, call setData() for each item (there are
+ also convenience functions, e.g. setText(), setImage() and
+ setPixmap(), that simply call setData() with appropriate
+ parameters).
+
+ The rich text widgets, QTextEdit and QTextBrowser, use
+ TQMimeSourceFactory to resolve references such as images or links
+ within rich text documents. They either access the default factory
+ (see \l{defaultFactory()}) or their own. Other classes that are
+ capable of displaying rich text (such as QLabel, QWhatsThis or
+ QMessageBox) always use the default factory.
+
+ A factory can also be used as a container to store data associated
+ with a name. This technique is useful whenever rich text contains
+ images that are stored in the program itself, not loaded from the
+ hard disk. Your program may, for example, define some image data
+ as:
+ \snippet doc/src/snippets/code/src_qt3support_other_q3mimefactory.cpp 0
+
+ To be able to use this image within some rich text, for example
+ inside a QLabel, you must create a QImage from the raw data and
+ insert it into the factory with a unique name:
+ \snippet doc/src/snippets/code/src_qt3support_other_q3mimefactory.cpp 1
+
+ Now you can create a rich text QLabel with
+
+ \snippet doc/src/snippets/code/src_qt3support_other_q3mimefactory.cpp 2
+
+ When no longer needed, you can clear the data from the factory:
+
+ \snippet doc/src/snippets/code/src_qt3support_other_q3mimefactory.cpp 3
+*/
+
+
+/*!
+ Constructs a TQMimeSourceFactory that has no file path and no
+ stored content.
+*/
+TQMimeSourceFactory::TQMimeSourceFactory() :
+ d(new TQMimeSourceFactoryData)
+{
+// addFilePath(QLatin1String(":/qt/q3mimesourcefactory/")); //to get from the resources // Where did this come from??!?!?!?
+ // add some reasonable defaults
+ setExtensionType(QLatin1String("htm"), "text/html;charset=iso8859-1");
+ setExtensionType(QLatin1String("html"), "text/html;charset=iso8859-1");
+ setExtensionType(QLatin1String("txt"), "text/plain");
+ setExtensionType(QLatin1String("xml"), "text/xml;charset=UTF-8");
+ setExtensionType(QLatin1String("jpg"), "image/jpeg"); // support misspelled jpeg files
+}
+
+/*!
+ Destroys the TQMimeSourceFactory, deleting all stored content.
+*/
+TQMimeSourceFactory::~TQMimeSourceFactory()
+{
+ if (defaultFactory() == this)
+ defaultfactory = 0;
+ delete d;
+}
+
+QMimeSource* TQMimeSourceFactory::dataInternal(const QString& abs_name, const QMap<QString, QString> &extensions) const
+{
+ QMimeSource* r = 0;
+ QStringList attempted_names(abs_name);
+ TQFileInfo fi(abs_name);
+ if (fi.isReadable()) {
+ // get the right mimetype
+ QString e = fi.extension(false);
+ QByteArray mimetype("application/octet-stream");
+ if (extensions.contains(e))
+ mimetype = TQT_TQSTRING(extensions[e]).latin1();
+ if (!QImageReader::imageFormat(abs_name).isEmpty())
+ mimetype = "application/x-qt-image";
+
+ TQFile f(abs_name);
+ if (f.open(QIODevice::ReadOnly) && f.size()) {
+ QByteArray ba;
+ ba.resize(f.size());
+ f.readBlock(ba.data(), ba.size());
+ TQStoredDrag* sr = new TQStoredDrag(mimetype);
+ sr->setEncodedData(TQT_TQBYTEARRAY_OBJECT(ba));
+ delete d->last;
+ d->last = r = sr;
+ }
+ }
+
+ // we didn't find the mime-source, so ask the default factory for
+ // the mime-source (this one will iterate over all installed ones)
+ //
+ // this looks dangerous, as this dataInternal() function will be
+ // called again when the default factory loops over all installed
+ // factories (including this), but the static bool looping in
+ // data() avoids endless recursions
+ if (!r && this != defaultFactory())
+ r = (QMimeSource*)defaultFactory()->data(abs_name);
+
+ return r;
+}
+
+
+/*!
+ Returns a reference to the data associated with \a abs_name. The
+ return value remains valid only until the next data() or setData()
+ call, so you should immediately decode the result.
+
+ If there is no data associated with \a abs_name in the factory's
+ store, the factory tries to access the local filesystem. If \a
+ abs_name isn't an absolute file name, the factory will search for
+ it in all defined paths (see \l{setFilePath()}).
+
+ The factory understands all the image formats supported by
+ QImageReader. Any other mime types are determined by the file name
+ extension. The default settings are
+ \snippet doc/src/snippets/code/src_qt3support_other_q3mimefactory.cpp 4
+ The effect of these is that file names ending in "txt" will be
+ treated as text encoded in the local encoding; those ending in
+ "xml" will be treated as text encoded in Unicode UTF-8 encoding.
+ The text/html type is treated specially, since the encoding can be
+ specified in the html file itself. "html" or "htm" will be treated
+ as text encoded in the encoding specified by the html meta tag, if
+ none could be found, the charset of the mime type will be used.
+ The text subtype ("html", "plain", or "xml") does not affect the
+ factory, but users of the factory may behave differently. We
+ recommend creating "xml" files where practical. These files can be
+ viewed regardless of the runtime encoding and can encode any
+ Unicode characters without resorting to encoding definitions
+ inside the file.
+
+ Any file data that is not recognized will be retrieved as a
+ QMimeSource providing the "application/octet-stream" mime type,
+ meaning uninterpreted binary data.
+
+ You can add further extensions or change existing ones with
+ subsequent calls to setExtensionType(). If the extension mechanism
+ is not sufficient for your problem domain, you can inherit
+ TQMimeSourceFactory and reimplement this function to perform some
+ more specialized mime-type detection. The same applies if you want
+ to use the mime source factory to access URL referenced data over
+ a network.
+*/
+const TQMimeSource *TQMimeSourceFactory::data(const QString& abs_name) const
+{
+ if (d->stored.contains(abs_name))
+ return static_cast<TQMimeSource*>(d->stored[abs_name]);
+
+ const QMimeSource *r = 0;
+ if (abs_name.isEmpty())
+ return static_cast<const TQMimeSource*>(r);
+ QStringList::Iterator it;
+ if (abs_name[0] == QLatin1Char('/')
+#ifdef Q_WS_WIN
+ || (abs_name[0].isLetter() && abs_name[1] == QLatin1Char(':')) || abs_name.startsWith(QLatin1String("\\\\"))
+#endif
+ )
+ {
+ // handle absolute file names directly
+ r = dataInternal(abs_name, d->extensions);
+ }
+ else { // check list of paths
+ for (it = d->path.begin(); !r && it != d->path.end(); ++it) {
+ QString filename = *it;
+ if (filename[(int)filename.length()-1] != QLatin1Char('/'))
+ filename += QLatin1Char('/');
+ filename += abs_name;
+ r = dataInternal(filename, d->extensions);
+ }
+ }
+
+ static bool looping = false;
+ if (!r && this == defaultFactory()) {
+ // we found no mime-source and we are the default factory, so
+ // we know all the other installed mime-source factories, so
+ // ask them
+ if (!looping) {
+ // to avoid endless recustions, don't enter the loop below
+ // if data() got called from within the loop below
+ looping = true;
+ for (int i = 0; i < d->factories.size(); ++i) {
+ const TQMimeSourceFactory *f = d->factories.at(i);
+ if (f == this)
+ continue;
+ r = static_cast<const QMimeSource *>(f->data(abs_name));
+ if (r) {
+ looping = false;
+ return static_cast<const TQMimeSource*>(r);
+ }
+ }
+ looping = false;
+ }
+ } else if (!r) {
+ // we are not the default mime-source factory, so ask the
+ // default one for the mime-source, as this one will loop over
+ // all installed mime-source factories and ask these
+ r = static_cast<const QMimeSource *>(defaultFactory()->data(abs_name));
+ }
+ return static_cast<const TQMimeSource*>(r);
+}
+
+/*!
+ \fn void TQMimeSourceFactory::setFilePath(const QStringList &path)
+ \fn void TQMimeSourceFactory::setFilePath(const QString &path)
+
+ Sets the list of directories that will be searched when named data
+ is requested to those given in the string list \a path.
+
+ \sa filePath()
+*/
+void TQMimeSourceFactory::setFilePath(const QStringList& path)
+{
+ d->path = path;
+}
+
+/*!
+ Returns the currently set search paths.
+*/
+TQStringList TQMimeSourceFactory::filePath() const
+{
+ return TQT_TQSTRINGLIST_OBJECT(d->path);
+}
+
+/*!
+ Adds another search path, \a p to the existing search paths.
+
+ \sa setFilePath()
+*/
+void TQMimeSourceFactory::addFilePath(const QString& p)
+{
+ d->path += p;
+}
+
+/*!
+ Sets the mime-type to be associated with the file name extension,
+ \a ext to \a mimetype. This determines the mime-type for files
+ found via the paths set by setFilePath().
+*/
+void TQMimeSourceFactory::setExtensionType(const QString& ext, const char* mimetype)
+{
+ d->extensions.insert(ext, QLatin1String(mimetype));
+}
+
+/*!
+ Converts the absolute or relative data item name \a
+ abs_or_rel_name to an absolute name, interpreted within the
+ context (path) of the data item named \a context (this must be an
+ absolute name).
+*/
+TQString TQMimeSourceFactory::makeAbsolute(const QString& abs_or_rel_name, const QString& context) const
+{
+ if (context.isNull() ||
+ !(context[0] == QLatin1Char('/')
+#ifdef Q_WS_WIN
+ || (context[0].isLetter() && context[1] == QLatin1Char(':'))
+#endif
+ ))
+ return abs_or_rel_name;
+ if (abs_or_rel_name.isEmpty())
+ return context;
+ TQFileInfo c(context);
+ if (!c.isDir()) {
+ TQFileInfo r(c.dir(true), abs_or_rel_name);
+ return r.absFilePath();
+ } else {
+ TQDir d(context);
+ TQFileInfo r(d, abs_or_rel_name);
+ return r.absFilePath();
+ }
+}
+
+/*!
+ \overload
+ A convenience function. See data(const QString& abs_name). The
+ file name is given in \a abs_or_rel_name and the path is in \a
+ context.
+*/
+const TQMimeSource* TQMimeSourceFactory::data(const QString& abs_or_rel_name, const QString& context) const
+{
+ const QMimeSource* r = data(makeAbsolute(abs_or_rel_name,context));
+ if (!r && !d->path.isEmpty())
+ r = data(abs_or_rel_name);
+ return static_cast<const TQMimeSource*>(r);
+}
+
+
+/*!
+ Sets \a text to be the data item associated with the absolute name
+ \a abs_name.
+
+ Equivalent to setData(abs_name, new TQTextDrag(text)).
+*/
+void TQMimeSourceFactory::setText(const QString& abs_name, const QString& text)
+{
+ setData(abs_name, new TQTextDrag(text));
+}
+
+/*!
+ Sets \a image to be the data item associated with the absolute
+ name \a abs_name.
+
+ Equivalent to setData(abs_name, new TQImageDrag(image)).
+*/
+void TQMimeSourceFactory::setImage(const QString& abs_name, const QImage& image)
+{
+ setData(abs_name, new TQImageDrag(image));
+}
+
+/*!
+ Sets \a pixmap to be the data item associated with the absolute
+ name \a abs_name.
+*/
+void TQMimeSourceFactory::setPixmap(const QString& abs_name, const QPixmap& pixmap)
+{
+ setData(abs_name, new TQImageDrag(TQT_TQPIXMAP_OBJECT(pixmap).convertToImage()));
+}
+
+/*!
+ Sets \a data to be the data item associated with
+ the absolute name \a abs_name. Note that the ownership of \a data is
+ transferred to the factory: do not delete or access the pointer after
+ passing it to this function.
+
+ Passing 0 for data removes previously stored data.
+*/
+void TQMimeSourceFactory::setData(const QString& abs_name, QMimeSource* data)
+{
+ if (d->stored.contains(abs_name))
+ delete d->stored[abs_name];
+ d->stored.insert(abs_name,data);
+}
+
+
+/*!
+ Returns the application-wide default mime source factory. This
+ factory is used by rich text rendering classes such as
+ QSimpleRichText, QWhatsThis and QMessageBox to resolve named
+ references within rich text documents. It serves also as the
+ initial factory for the more complex render widgets, QTextEdit and
+ QTextBrowser.
+
+ \sa setDefaultFactory()
+*/
+TQMimeSourceFactory* TQMimeSourceFactory::defaultFactory()
+{
+ if (!defaultfactory)
+ {
+ defaultfactory = new TQMimeSourceFactory();
+ qmime_cleanup_factory.set(&defaultfactory);
+ QTextImageHandler::externalLoader = richTextImageLoader;
+ }
+ return defaultfactory;
+}
+
+/*!
+ Sets the default \a factory, destroying any previously set mime
+ source provider. The ownership of the factory is transferred to
+ Qt.
+
+ \sa defaultFactory()
+*/
+void TQMimeSourceFactory::setDefaultFactory(TQMimeSourceFactory* factory)
+{
+ if (!defaultfactory)
+ qmime_cleanup_factory.set(&defaultfactory);
+ else if (defaultfactory != factory)
+ delete defaultfactory;
+ defaultfactory = factory;
+}
+
+/*!
+ Sets the defaultFactory() to 0 and returns the previous one.
+*/
+
+TQMimeSourceFactory* TQMimeSourceFactory::takeDefaultFactory()
+{
+ TQMimeSourceFactory *f = defaultfactory;
+ defaultfactory = 0;
+ return f;
+}
+
+/*!
+ Adds the TQMimeSourceFactory \a f to the list of available
+ mimesource factories. If the defaultFactory() can't resolve a
+ data() it iterates over the list of installed mimesource factories
+ until the data can be resolved.
+
+ \sa removeFactory()
+*/
+
+void TQMimeSourceFactory::addFactory(TQMimeSourceFactory *f)
+{
+ TQMimeSourceFactory::defaultFactory()->d->factories.append(f);
+}
+
+/*!
+ Removes the mimesource factory \a f from the list of available
+ mimesource factories.
+
+ \sa addFactory()
+*/
+
+void TQMimeSourceFactory::removeFactory(TQMimeSourceFactory *f)
+{
+ TQMimeSourceFactory::defaultFactory()->d->factories.removeAll(f);
+}
+
+QPixmap qPixmapFromMimeSource(const QString &abs_name)
+{
+ const TQMimeSource *m = TQT_TQMIMESOURCE_CONST(TQMimeSourceFactory::defaultFactory()->data(abs_name));
+ if (!m) {
+ if (QFile::exists(abs_name))
+ return QPixmap(abs_name);
+ if (!abs_name.isEmpty())
+ qWarning("QPixmap::fromMimeSource: Cannot find pixmap \"%s\" in the mime source factory",
+ TQT_TQSTRING(abs_name).latin1());
+ return QPixmap();
+ }
+ QPixmap pix;
+ TQImageDrag::decode(m, pix);
+ return pix;
+}
+
+QImage qImageFromMimeSource(const QString &abs_name)
+{
+ const TQMimeSource *m = TQT_TQMIMESOURCE_CONST(TQMimeSourceFactory::defaultFactory()->data(abs_name));
+ if (!m) {
+ qWarning("QImage::fromMimeSource: Cannot find image \"%s\" in the mime source factory", TQT_TQSTRING(abs_name).latin1());
+ return QImage();
+ }
+ QImage img;
+ TQImageDrag::decode(m, img);
+ return img;
+}
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/*!
+ \fn const char * TQMimeSource::format(int i) const
+
+ Returns the \a{i}-th supported MIME format, or 0.
+*/
+
+
+
+class TQMimeSourceFactoryData {
+public:
+ TQMimeSourceFactoryData() :
+ last(0)
+ {
+ }
+
+ ~TQMimeSourceFactoryData()
+ {
+ TQMap<TQString, TQMimeSource*>::Iterator it = stored.begin();
+ while ( it != stored.end() ) {
+ delete *it;
+ ++it;
+ }
+ delete last;
+ }
+
+ TQMap<TQString, TQMimeSource*> stored;
+ TQMap<TQString, TQString> extensions;
+ TQStringList path;
+ TQMimeSource* last;
+ TQPtrList<TQMimeSourceFactory> factories;
+};
+
+/*!
+ \class TQMimeSourceFactory tqmime.h
+ \brief The TQMimeSourceFactory class is an extensible provider of mime-typed data.
+
+ \ingroup io
+ \ingroup environment
+
+ A TQMimeSourceFactory provides an abstract interface to a
+ collection of information. Each piece of information is
+ represented by a TQMimeSource object which can be examined and
+ converted to concrete data types by functions such as
+ TQImageDrag::canDecode() and TQImageDrag::decode().
+
+ The base TQMimeSourceFactory can be used in two ways: as an
+ abstraction of a collection of files or as specifically stored
+ data. For it to access files, call setFilePath() before accessing
+ data. For stored data, call setData() for each item (there are
+ also convenience functions, e.g. setText(), setImage() and
+ setPixmap(), that simply call setData() with appropriate
+ parameters).
+
+ The rich text widgets, TQTextEdit and TQTextBrowser, use
+ TQMimeSourceFactory to resolve references such as images or links
+ within rich text documents. They either access the default factory
+ (see \l{defaultFactory()}) or their own (see
+ \l{TQTextEdit::setMimeSourceFactory()}). Other classes that are
+ capable of displaying rich text (such as TQLabel, TQWhatsThis or
+ TQMessageBox) always use the default factory.
+
+ A factory can also be used as a container to store data associated
+ with a name. This technique is useful whenever rich text tqcontains
+ images that are stored in the program itself, not loaded from the
+ hard disk. Your program may, for example, define some image data
+ as:
+ \code
+ static const char* myimage_data[]={
+ "...",
+ ...
+ "..."};
+ \endcode
+
+ To be able to use this image within some rich text, for example
+ inside a TQLabel, you must create a TQImage from the raw data and
+ insert it into the factory with a unique name:
+ \code
+ TQMimeSourceFactory::defaultFactory()->setImage( "myimage", TQImage(myimage_data) );
+ \endcode
+
+ Now you can create a rich text TQLabel with
+
+ \code
+ TQLabel* label = new TQLabel(
+ "Rich text with embedded image:<img source=\"myimage\">"
+ "Isn't that <em>cute</em>?" );
+ \endcode
+
+ When no longer needed, you can clear the data from the factory:
+
+ \code
+ delete label;
+ TQMimeSourceFactory::defaultFactory()->setData( "myimage", 0 );
+ \endcode
+*/
+
+
+/*!
+ Constructs a TQMimeSourceFactory that has no file path and no
+ stored content.
+*/
+TQMimeSourceFactory::TQMimeSourceFactory() :
+ d(new TQMimeSourceFactoryData)
+{
+ // add some reasonable defaults
+ setExtensionType("htm", "text/html;charset=iso8859-1");
+ setExtensionType("html", "text/html;charset=iso8859-1");
+ setExtensionType("txt", "text/plain");
+ setExtensionType("xml", "text/xml;charset=UTF-8");
+ setExtensionType("jpg", "image/jpeg"); // support misspelled jpeg files
+}
+
+/*!
+ Destroys the TQMimeSourceFactory, deleting all stored content.
+*/
+TQMimeSourceFactory::~TQMimeSourceFactory()
+{
+ if ( defaultFactory() == this )
+ defaultfactory = 0;
+ delete d;
+}
+
+TQMimeSource* TQMimeSourceFactory::dataInternal(const TQString& abs_name, const TQMap<TQString, TQString> &extensions ) const
+{
+ TQMimeSource* r = 0;
+ TQFileInfo fi(abs_name);
+ if ( fi.isReadable() ) {
+
+ // get the right mimetype
+ TQString e = fi.extension(FALSE);
+ TQCString mimetype = "application/octet-stream";
+ const char* imgfmt;
+ if ( extensions.tqcontains(e) )
+ mimetype = extensions[e].latin1();
+ else if ( ( imgfmt = TQImage::imageFormat( abs_name ) ) )
+ mimetype = TQCString("image/")+TQCString(imgfmt).lower();
+
+ TQFile f(abs_name);
+ if ( f.open(IO_ReadOnly) && f.size() ) {
+ TQByteArray ba(f.size());
+ f.readBlock(ba.data(), ba.size());
+ TQStoredDrag* sr = new TQStoredDrag( mimetype );
+ sr->setEncodedData( ba );
+ delete d->last;
+ d->last = r = sr;
+ }
+ }
+
+ // we didn't tqfind the mime-source, so ask the default factory for
+ // the mime-source (this one will iterate over all installed ones)
+ //
+ // this looks dangerous, as this dataInternal() function will be
+ // called again when the default factory loops over all installed
+ // factories (including this), but the static bool looping in
+ // data() avoids endless recursions
+ if ( !r && this != defaultFactory() )
+ r = (TQMimeSource*)defaultFactory()->data( abs_name );
+
+ return r;
+}
+
+
+/*!
+ Returns a reference to the data associated with \a abs_name. The
+ return value remains valid only until the next data() or setData()
+ call, so you should immediately decode the result.
+
+ If there is no data associated with \a abs_name in the factory's
+ store, the factory tries to access the local filesystem. If \a
+ abs_name isn't an absolute file name, the factory will search for
+ it in all defined paths (see \l{setFilePath()}).
+
+ The factory understands all the image formats supported by
+ TQImageIO. Any other mime types are determined by the file name
+ extension. The default settings are
+ \code
+ setExtensionType("html", "text/html;charset=iso8859-1");
+ setExtensionType("htm", "text/html;charset=iso8859-1");
+ setExtensionType("txt", "text/plain");
+ setExtensionType("xml", "text/xml;charset=UTF-8");
+ \endcode
+ The effect of these is that file names ending in "txt" will be
+ treated as text encoded in the local encoding; those ending in
+ "xml" will be treated as text encoded in Unicode UTF-8 encoding.
+ The text/html type is treated specially, since the encoding can be
+ specified in the html file itself. "html" or "htm" will be treated
+ as text encoded in the encoding specified by the html meta tag, if
+ none could be found, the charset of the mime type will be used.
+ The text subtype ("html", "plain", or "xml") does not affect the
+ factory, but users of the factory may behave differently. We
+ recommend creating "xml" files where practical. These files can be
+ viewed regardless of the runtime encoding and can encode any
+ Unicode characters without resorting to encoding definitions
+ inside the file.
+
+ Any file data that is not recognized will be retrieved as a
+ TQMimeSource providing the "application/octet-stream" mime type,
+ meaning uninterpreted binary data.
+
+ You can add further extensions or change existing ones with
+ subsequent calls to setExtensionType(). If the extension mechanism
+ is not sufficient for your problem domain, you can inherit
+ TQMimeSourceFactory and reimplement this function to perform some
+ more specialized mime-type detection. The same applies if you want
+ to use the mime source factory to access URL referenced data over
+ a network.
+*/
+const TQMimeSource* TQMimeSourceFactory::data(const TQString& abs_name) const
+{
+ if ( d->stored.tqcontains(abs_name) )
+ return d->stored[abs_name];
+
+ TQMimeSource* r = 0;
+ TQStringList::Iterator it;
+ if ( abs_name[0] == '/'
+#ifdef TQ_WS_WIN
+ || ( abs_name[0] && abs_name[1] == ':' ) || abs_name.startsWith("\\\\")
+#endif
+ )
+ {
+ // handle absolute file names directly
+ r = dataInternal( abs_name, d->extensions);
+ }
+ else { // check list of paths
+ for ( it = d->path.begin(); !r && it != d->path.end(); ++it ) {
+ TQString filename = *it;
+ if ( filename[(int)filename.length()-1] != '/' )
+ filename += '/';
+ filename += abs_name;
+ r = dataInternal( filename, d->extensions );
+ }
+ }
+
+ static bool looping = FALSE;
+ if ( !r && this == defaultFactory() ) {
+ // we found no mime-source and we are the default factory, so
+ // we know all the other installed mime-source factories, so
+ // ask them
+ if ( !looping ) {
+ // to avoid endless recursions, don't enter the loop below
+ // if data() got called from within the loop below
+ looping = TRUE;
+ TQPtrListIterator<TQMimeSourceFactory> it( d->factories );
+ TQMimeSourceFactory *f;
+ while ( ( f = it.current() ) ) {
+ ++it;
+ if ( f == this )
+ continue;
+ r = (TQMimeSource*)f->data( abs_name );
+ if ( r ) {
+ looping = FALSE;
+ return r;
+ }
+ }
+ looping = FALSE;
+ }
+ } else if ( !r ) {
+ // we are not the default mime-source factory, so ask the
+ // default one for the mime-source, as this one will loop over
+ // all installed mime-source factories and ask these
+ r = (TQMimeSource*)defaultFactory()->data( abs_name );
+ }
+
+ return r;
+}
+
+/*!
+ Sets the list of directories that will be searched when named data
+ is requested to the those given in the string list \a path.
+
+ \sa filePath()
+*/
+void TQMimeSourceFactory::setFilePath( const TQStringList& path )
+{
+ d->path = path;
+}
+
+/*!
+ Returns the currently set search paths.
+*/
+TQStringList TQMimeSourceFactory::filePath() const
+{
+ return d->path;
+}
+
+/*!
+ Adds another search path, \a p to the existing search paths.
+
+ \sa setFilePath()
+*/
+void TQMimeSourceFactory::addFilePath( const TQString& p )
+{
+ d->path += p;
+}
+
+/*!
+ Sets the mime-type to be associated with the file name extension,
+ \a ext to \a mimetype. This determines the mime-type for files
+ found via the paths set by setFilePath().
+*/
+void TQMimeSourceFactory::setExtensionType( const TQString& ext, const char* mimetype )
+{
+ d->extensions.tqreplace(ext, mimetype);
+}
+
+/*!
+ Converts the absolute or relative data item name \a
+ abs_or_rel_name to an absolute name, interpreted within the
+ context (path) of the data item named \a context (this must be an
+ absolute name).
+*/
+TQString TQMimeSourceFactory::makeAbsolute(const TQString& abs_or_rel_name, const TQString& context) const
+{
+ if ( context.isNull() ||
+ !(context[0] == '/'
+#ifdef TQ_WS_WIN
+ || ( context[0] && context[1] == ':')
+#endif
+ ))
+ return abs_or_rel_name;
+ if ( abs_or_rel_name.isEmpty() )
+ return context;
+ TQFileInfo c( context );
+ if (!c.isDir()) {
+ TQFileInfo r( c.dir(TRUE), abs_or_rel_name );
+ return r.absFilePath();
+ } else {
+ TQDir d(context);
+ TQFileInfo r(d, abs_or_rel_name);
+ return r.absFilePath();
+ }
+}
+
+/*!
+ \overload
+ A convenience function. See data(const TQString& abs_name). The
+ file name is given in \a abs_or_rel_name and the path is in \a
+ context.
+*/
+const TQMimeSource* TQMimeSourceFactory::data(const TQString& abs_or_rel_name, const TQString& context) const
+{
+ const TQMimeSource* r = data(makeAbsolute(abs_or_rel_name,context));
+ if ( !r && !d->path.isEmpty() )
+ r = data(abs_or_rel_name);
+ return r;
+}
+
+
+/*!
+ Sets \a text to be the data item associated with the absolute name
+ \a abs_name.
+
+ Equivalent to setData(abs_name, new TQTextDrag(text)).
+*/
+void TQMimeSourceFactory::setText( const TQString& abs_name, const TQString& text )
+{
+ setData(abs_name, new TQTextDrag(text));
+}
+
+/*!
+ Sets \a image to be the data item associated with the absolute
+ name \a abs_name.
+
+ Equivalent to setData(abs_name, new TQImageDrag(image)).
+*/
+void TQMimeSourceFactory::setImage( const TQString& abs_name, const TQImage& image )
+{
+ setData(abs_name, new TQImageDrag(image));
+}
+
+/*!
+ Sets \a pixmap to be the data item associated with the absolute
+ name \a abs_name.
+*/
+void TQMimeSourceFactory::setPixmap( const TQString& abs_name, const TQPixmap& pixmap )
+{
+ setData(abs_name, new TQImageDrag(pixmap.convertToImage()));
+}
+
+/*!
+ Sets \a data to be the data item associated with
+ the absolute name \a abs_name. Note that the ownership of \a data is
+ transferred to the factory: do not delete or access the pointer after
+ passing it to this function.
+
+ Passing 0 for data removes previously stored data.
+*/
+void TQMimeSourceFactory::setData( const TQString& abs_name, TQMimeSource* data )
+{
+ if ( d->stored.tqcontains(abs_name) )
+ delete d->stored[abs_name];
+ d->stored.tqreplace(abs_name,data);
+}
+
+
+/*!
+ Returns the application-wide default mime source factory. This
+ factory is used by rich text rendering classes such as
+ TQSimpleRichText, TQWhatsThis and TQMessageBox to resolve named
+ references within rich text documents. It serves also as the
+ initial factory for the more complex render widgets, TQTextEdit and
+ TQTextBrowser.
+
+ \sa setDefaultFactory()
+*/
+TQMimeSourceFactory* TQMimeSourceFactory::defaultFactory()
+{
+ if (!defaultfactory)
+ {
+ defaultfactory = new TQMimeSourceFactory();
+ qmime_cleanup_factory.set( &defaultfactory );
+ }
+ return defaultfactory;
+}
+
+/*!
+ Sets the default \a factory, destroying any previously set mime
+ source provider. The ownership of the factory is transferred to
+ TQt.
+
+ \sa defaultFactory()
+*/
+void TQMimeSourceFactory::setDefaultFactory( TQMimeSourceFactory* factory)
+{
+ if ( !defaultfactory )
+ qmime_cleanup_factory.set( &defaultfactory );
+ else if ( defaultfactory != factory )
+ delete defaultfactory;
+ defaultfactory = factory;
+}
+
+/*!
+ Sets the defaultFactory() to 0 and returns the previous one.
+*/
+
+TQMimeSourceFactory* TQMimeSourceFactory::takeDefaultFactory()
+{
+ TQMimeSourceFactory *f = defaultfactory;
+ defaultfactory = 0;
+ return f;
+}
+
+/*!
+ Adds the TQMimeSourceFactory \a f to the list of available
+ mimesource factories. If the defaultFactory() can't resolve a
+ data() it iterates over the list of installed mimesource factories
+ until the data can be resolved.
+
+ \sa removeFactory();
+*/
+
+void TQMimeSourceFactory::addFactory( TQMimeSourceFactory *f )
+{
+ TQMimeSourceFactory::defaultFactory()->d->factories.append( f );
+}
+
+/*!
+ Removes the mimesource factory \a f from the list of available
+ mimesource factories.
+
+ \sa addFactory();
+*/
+
+void TQMimeSourceFactory::removeFactory( TQMimeSourceFactory *f )
+{
+ TQMimeSourceFactory::defaultFactory()->d->factories.removeRef( f );
+}
+
+#endif // USE_QT4
+
+#endif // TQT_NO_MIME
diff --git a/tqtinterface/qt4/src/kernel/tqmime.h b/tqtinterface/qt4/src/kernel/tqmime.h
new file mode 100644
index 0000000..b683f48
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmime.h
@@ -0,0 +1,312 @@
+/****************************************************************************
+**
+** Definition of mime classes
+**
+** Created : 981204
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMIME_H
+#define TQMIME_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqmap.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qmime.h>
+#include <QtGui/qwindowdefs.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qmap.h>
+#include <QtGui/qpixmap.h>
+
+#endif // USE_QT4
+
+#ifndef TQT_NO_MIME
+
+#ifdef USE_QT4
+// #if 0
+
+class TQ_EXPORT TQMimeSource : public QMimeSource, virtual public TQt
+{
+ friend class TQClipboardData;
+
+public:
+ TQMimeSource();
+
+ virtual TQByteArray tqencodedData( const char* ) const = 0;
+ inline QByteArray encodedData( const char *ch ) const { return tqencodedData(ch); } // Qt4 connection
+ inline int serialNumber() const { return ser_no; }
+
+private:
+ int ser_no;
+ enum { NoCache, Text, Graphics } cacheType;
+ union
+ {
+ struct
+ {
+ TQString *str;
+ TQCString *subtype;
+ } txt;
+ struct
+ {
+ TQImage *img;
+ TQPixmap *pix;
+ } gfx;
+ } cache;
+ void clearCache();
+
+ // friends for caching
+ friend class TQImageDrag;
+ friend class TQTextDrag;
+};
+
+#else // USE_QT4
+
+class TQImageDrag;
+class TQTextDrag;
+
+class TQ_EXPORT TQMimeSource
+{
+ friend class TQClipboardData;
+
+public:
+ TQMimeSource();
+ virtual ~TQMimeSource();
+ virtual const char* format( int n = 0 ) const = 0;
+ virtual bool provides( const char* ) const;
+ virtual TQByteArray tqencodedData( const char* ) const = 0;
+ int serialNumber() const;
+
+private:
+ int ser_no;
+ enum { NoCache, Text, Graphics } cacheType;
+ union
+ {
+ struct
+ {
+ TQString *str;
+ TQCString *subtype;
+ } txt;
+ struct
+ {
+ TQImage *img;
+ TQPixmap *pix;
+ } gfx;
+ } cache;
+ void clearCache();
+
+ // friends for caching
+ friend class TQImageDrag;
+ friend class TQTextDrag;
+
+};
+
+inline int TQMimeSource::serialNumber() const
+{ return ser_no; }
+
+#endif // USE_QT4
+
+class TQStringList;
+class TQMimeSourceFactoryData;
+
+// NOTE:
+// For an unknown reason the Qt3Support TQMimeSourceFactory will not work with embedded text images (s/a Trinity Desktop's ktip application)
+// Do not reactivate this Qt3Support code until that problem is fixed!
+
+// #ifdef USE_QT4
+#if 0
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3SupportLight)
+
+#ifndef QT_NO_MIMEFACTORY
+
+class QStringList;
+class QMimeSource;
+class TQMimeSourceFactoryData;
+
+class Q_COMPAT_EXPORT TQMimeSourceFactory {
+public:
+ TQMimeSourceFactory();
+ virtual ~TQMimeSourceFactory();
+
+ static TQMimeSourceFactory* defaultFactory();
+ static void setDefaultFactory(TQMimeSourceFactory*);
+ static TQMimeSourceFactory* takeDefaultFactory();
+ static void addFactory(TQMimeSourceFactory *f);
+ static void removeFactory(TQMimeSourceFactory *f);
+
+ virtual const TQMimeSource* data(const QString& abs_name) const;
+ virtual TQString makeAbsolute(const QString& abs_or_rel_name, const QString& context) const;
+ const TQMimeSource* data(const QString& abs_or_rel_name, const QString& context) const;
+
+ virtual void setText(const QString& abs_name, const QString& text);
+ virtual void setImage(const QString& abs_name, const QImage& im);
+ virtual void setPixmap(const QString& abs_name, const QPixmap& pm);
+ virtual void setData(const QString& abs_name, QMimeSource* data);
+ virtual void setFilePath(const QStringList&);
+ inline void setFilePath(const QString &path) { setFilePath(QStringList(path)); }
+ virtual TQStringList filePath() const;
+ void addFilePath(const QString&);
+ virtual void setExtensionType(const QString& ext, const char* mimetype);
+
+private:
+ QMimeSource *dataInternal(const QString& abs_name, const QMap<QString, QString> &extensions) const;
+ TQMimeSourceFactoryData* d;
+};
+
+Q_COMPAT_EXPORT QPixmap qPixmapFromMimeSource(const QString &abs_name);
+
+Q_COMPAT_EXPORT QImage qImageFromMimeSource(const QString &abs_name);
+
+#endif // QT_NO_MIMEFACTORY
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+class TQ_EXPORT TQMimeSourceFactory {
+public:
+ TQMimeSourceFactory();
+ virtual ~TQMimeSourceFactory();
+
+ static TQMimeSourceFactory* defaultFactory();
+ static void setDefaultFactory( TQMimeSourceFactory* );
+ static TQMimeSourceFactory* takeDefaultFactory();
+ static void addFactory( TQMimeSourceFactory *f );
+ static void removeFactory( TQMimeSourceFactory *f );
+
+ virtual const TQMimeSource* data(const TQString& abs_name) const;
+ virtual TQString makeAbsolute(const TQString& abs_or_rel_name, const TQString& context) const;
+ const TQMimeSource* data(const TQString& abs_or_rel_name, const TQString& context) const;
+
+ virtual void setText( const TQString& abs_name, const TQString& text );
+ virtual void setImage( const TQString& abs_name, const TQImage& im );
+ virtual void setPixmap( const TQString& abs_name, const TQPixmap& pm );
+ virtual void setData( const TQString& abs_name, TQMimeSource* data );
+ virtual void setFilePath( const TQStringList& );
+ virtual TQStringList filePath() const;
+ void addFilePath( const TQString& );
+ virtual void setExtensionType( const TQString& ext, const char* mimetype );
+
+private:
+ TQMimeSource *dataInternal(const TQString& abs_name, const TQMap<TQString, TQString> &extensions ) const;
+ TQMimeSourceFactoryData* d;
+};
+
+#endif // USE_QT4
+
+#if defined(TQ_WS_WIN)
+
+#ifndef TQT_H
+#include "tqptrlist.h" // down here for GCC 2.7.* compatibility
+#endif // TQT_H
+
+/*
+ Encapsulation of conversion between MIME and Windows CLIPFORMAT.
+ Not need on X11, as the underlying protocol uses the MIME standard
+ directly.
+*/
+
+class TQ_EXPORT TQWindowsMime {
+public:
+ TQWindowsMime();
+ virtual ~TQWindowsMime();
+
+ static void initialize();
+
+ static TQPtrList<TQWindowsMime> all();
+ static TQWindowsMime* convertor( const char* mime, int cf );
+ static const char* cfToMime(int cf);
+
+ static int registerMimeType(const char *mime);
+
+ virtual const char* convertorName()=0;
+ virtual int countCf()=0;
+ virtual int cf(int index)=0;
+ virtual bool canConvert( const char* mime, int cf )=0;
+ virtual const char* mimeFor(int cf)=0;
+ virtual int cfFor(const char* )=0;
+ virtual TQByteArray convertToMime( TQByteArray data, const char* mime, int cf )=0;
+ virtual TQByteArray convertFromMime( TQByteArray data, const char* mime, int cf )=0;
+};
+
+#endif
+#if defined(TQ_WS_MAC)
+
+#ifndef TQT_H
+#include "tqptrlist.h" // down here for GCC 2.7.* compatibility
+#endif // TQT_H
+
+/*
+ Encapsulation of conversion between MIME and Mac flavor.
+ Not need on X11, as the underlying protocol uses the MIME standard
+ directly.
+*/
+
+class TQ_EXPORT TQMacMime {
+ char type;
+public:
+ enum TQMacMimeType { MIME_DND=0x01, MIME_CLIP=0x02, MIME_TQT_CONVERTOR=0x04, MIME_ALL=MIME_DND|MIME_CLIP };
+ TQMacMime(char);
+ virtual ~TQMacMime();
+
+ static void initialize();
+
+ static TQPtrList<TQMacMime> all(TQMacMimeType);
+ static TQMacMime* convertor(TQMacMimeType, const char* mime, int flav);
+ static const char* flavorToMime(TQMacMimeType, int flav);
+
+ virtual const char* convertorName()=0;
+ virtual int countFlavors()=0;
+ virtual int flavor(int index)=0;
+ virtual bool canConvert(const char* mime, int flav)=0;
+ virtual const char* mimeFor(int flav)=0;
+ virtual int flavorFor(const char*)=0;
+ virtual TQByteArray convertToMime(TQValueList<TQByteArray> data, const char* mime, int flav)=0;
+ virtual TQValueList<TQByteArray> convertFromMime(TQByteArray data, const char* mime, int flav)=0;
+};
+
+#endif // TQ_WS_MAC
+
+#endif // TQT_NO_MIME
+
+#endif // TQMIME_H
diff --git a/tqtinterface/qt4/src/kernel/tqmngio.cpp b/tqtinterface/qt4/src/kernel/tqmngio.cpp
new file mode 100644
index 0000000..250fda1
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmngio.cpp
@@ -0,0 +1,464 @@
+/****************************************************************************
+**
+** Implementation of MNG TQImage IOHandler
+**
+** Created : 970521
+**
+** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQT_CLEAN_NAMESPACE
+#define TQT_CLEAN_NAMESPACE
+#endif
+
+#include "tqdatetime.h"
+
+#ifndef TQT_NO_IMAGEIO_MNG
+
+#include "tqimage.h"
+#include "tqasyncimageio.h"
+#include "tqiodevice.h"
+#include "tqmngio.h"
+
+// Define XMD_H prohibits the included headers of libmng.h to typedef INT32.
+// This is needed for Borland with STL support, since in that case, INT32 is
+// already defined by some Borland header.
+#define XMD_H
+#if defined(TQ_OS_UNIXWARE)
+# define HAVE_BOOLEAN // libjpeg under Unixware seems to need this
+#endif
+#include <libmng.h>
+#include <stdlib.h>
+
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+
+class TQMNGFormat : public TQImageFormat {
+public:
+ TQMNGFormat();
+ virtual ~TQMNGFormat();
+
+ int decode(TQImage& img, TQImageConsumer* consumer,
+ const uchar* buffer, int length);
+
+ bool openstream()
+ {
+ // ### We should figure out how many loops an MNG has, but for now always assume infinite.
+ if (consumer)
+ consumer->setLooping(0);
+ return TRUE;
+ }
+ bool closestream( )
+ {
+ if (consumer)
+ consumer->end();
+ return TRUE;
+ }
+ bool readdata( mng_ptr pBuf, mng_uint32 iBuflen, mng_uint32p pRead )
+ {
+ uint m = ndata + nbuffer - ubuffer;
+ if ( iBuflen > m ) {
+ iBuflen = m;
+ }
+ *pRead = iBuflen;
+ uint n = nbuffer-ubuffer;
+ if ( iBuflen < n ) {
+ // enough in buffer
+ memcpy(pBuf, buffer+ubuffer, iBuflen);
+ ubuffer += iBuflen;
+ return TRUE;
+ }
+ if ( n ) {
+ // consume buffer
+ memcpy(pBuf, buffer+ubuffer, n );
+ pBuf = (mng_ptr)((char*)pBuf + n);
+ iBuflen -= n;
+ ubuffer = nbuffer;
+ }
+ if ( iBuflen ) {
+ // fill from incoming data
+ memcpy(pBuf, data, iBuflen);
+ data += iBuflen;
+ ndata -= iBuflen;
+ }
+ return TRUE;
+ }
+ bool errorproc( mng_int32 iErrorcode,
+ mng_int8 /*iSeverity*/,
+ mng_chunkid iChunkname,
+ mng_uint32 /*iChunkseq*/,
+ mng_int32 iExtra1,
+ mng_int32 iExtra2,
+ mng_pchar zErrortext )
+ {
+ qWarning("MNG error %d: %s; chunk %c%c%c%c; subcode %d:%d",
+ iErrorcode, zErrortext ? zErrortext : "",
+ (iChunkname>>24)&0xff,
+ (iChunkname>>16)&0xff,
+ (iChunkname>>8)&0xff,
+ (iChunkname>>0)&0xff,
+ iExtra1,iExtra2);
+ return TRUE;
+ }
+ bool processheader( mng_uint32 iWidth, mng_uint32 iHeight )
+ {
+ image->create(iWidth,iHeight,32);
+ image->setAlphaBuffer(TRUE);
+ memset(image->bits(),0,iWidth*iHeight*4);
+ consumer->setSize(iWidth,iHeight);
+ mng_set_canvasstyle(handle,
+ TQImage::systemByteOrder() == TQImage::LittleEndian
+ ? MNG_CANVAS_BGRA8 : MNG_CANVAS_ARGB8 );
+ return TRUE;
+ }
+ mng_ptr getcanvasline( mng_uint32 iLinenr )
+ {
+ return image->scanLine(iLinenr);
+ }
+ mng_bool refresh( mng_uint32 x, mng_uint32 y, mng_uint32 w, mng_uint32 h )
+ {
+ TQRect r(x,y,w,h);
+ consumer->changed(r);
+ consumer->setFramePeriod(0);
+ consumer->frameDone();
+ return TRUE;
+ }
+ mng_uint32 gettickcount( )
+ {
+ return timer.elapsed() - losttime;
+ }
+ bool settimer( mng_uint32 iMsecs )
+ {
+ consumer->setFramePeriod(iMsecs);
+ consumer->frameDone();
+ state = Time;
+ losingtimer.start();
+ losttime -= iMsecs;
+ return TRUE;
+ }
+
+private:
+ // Animation-level information
+ enum { MovieStart, Time, Data, Data2 } state;
+
+ // Image-level information
+ mng_handle handle;
+
+ // For storing unused data
+ uchar *buffer;
+ uint maxbuffer;
+ uint nbuffer;
+
+ // Timing
+ TQTime timer;
+ TQTime losingtimer;
+ int losttime;
+
+ void enlargeBuffer(uint n)
+ {
+ if ( n > maxbuffer ) {
+ maxbuffer = n;
+ buffer = (uchar*)realloc(buffer,n);
+ }
+ }
+
+ // Temporary locals during single data-chunk processing
+ const uchar* data;
+ uint ndata;
+ uint ubuffer;
+ TQImageConsumer* consumer;
+ TQImage* image;
+};
+
+class TQMNGFormatType : public TQImageFormatType
+{
+ TQImageFormat* decoderFor(const uchar* buffer, int length);
+ const char* formatName() const;
+};
+
+
+/*
+ \class TQMNGFormat tqmngio.h
+ \brief Incremental image decoder for MNG image format.
+
+ \ingroup images
+ \ingroup graphics
+
+ This subclass of TQImageFormat decodes MNG format images,
+ including animated MNGs.
+
+ Animated MNG images are standard MNG images. The MNG standard
+ defines two extension chunks that are useful for animations:
+
+ <dl>
+ <dt>gIFg - GIF-like Graphic Control Extension
+ <dd>Includes frame disposal, user input flag (we ignore this),
+ and inter-frame delay.
+ <dt>gIFx - GIF-like Application Extension
+ <dd>Multi-purpose, but we just use the Netscape extension
+ which specifies looping.
+ </dl>
+
+ The subimages usually contain a offset chunk (oFFs) but need not.
+
+ The first image defines the "screen" size. Any subsequent image that
+ doesn't fit is clipped.
+
+TODO: decide on this point. gIFg gives disposal types, so it can be done.
+ All images paste (\e not composite, just place all-channel copying)
+ over the previous image to produce a subsequent frame.
+*/
+
+/*
+ \class TQMNGFormatType tqasyncimageio.h
+ \brief Incremental image decoder for MNG image format.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup io
+
+ This subclass of TQImageFormatType recognizes MNG
+ format images, creating a TQMNGFormat when required. An instance
+ of this class is created automatically before any other factories,
+ so you should have no need for such objects.
+*/
+
+TQImageFormat* TQMNGFormatType::decoderFor( const uchar* buffer, int length )
+{
+ if (length < 8) return 0;
+
+ if (buffer[0]==138 // MNG signature
+ && buffer[1]=='M'
+ && buffer[2]=='N'
+ && buffer[3]=='G'
+ && buffer[4]==13
+ && buffer[5]==10
+ && buffer[6]==26
+ && buffer[7]==10
+ || buffer[0]==139 // JNG signature
+ && buffer[1]=='J'
+ && buffer[2]=='N'
+ && buffer[3]=='G'
+ && buffer[4]==13
+ && buffer[5]==10
+ && buffer[6]==26
+ && buffer[7]==10
+#ifdef TQT_NO_IMAGEIO_PNG // if we don't have native PNG support use libmng
+ || buffer[0]==137 // PNG signature
+ && buffer[1]=='P'
+ && buffer[2]=='N'
+ && buffer[3]=='G'
+ && buffer[4]==13
+ && buffer[5]==10
+ && buffer[6]==26
+ && buffer[7]==10
+#endif
+ )
+ return new TQMNGFormat;
+ return 0;
+}
+
+const char* TQMNGFormatType::formatName() const
+{
+ return "MNG";
+}
+
+
+/*!
+ Constructs a TQMNGFormat.
+*/
+TQMNGFormat::TQMNGFormat()
+{
+ state = MovieStart;
+ handle = 0;
+ nbuffer = 0;
+ maxbuffer = 0;
+ buffer = 0;
+ losttime = 0;
+}
+
+/*
+ Destroys a TQMNGFormat.
+*/
+TQMNGFormat::~TQMNGFormat()
+{
+ // We're setting the consumer to 0 since it may have been
+ // deleted by read_async_image in qimage.cpp
+ consumer = 0;
+ if (handle) mng_cleanup(&handle);
+}
+
+
+// C-callback to C++-member-function conversion
+//
+static mng_bool openstream( mng_handle handle )
+{
+ return ((TQMNGFormat*)mng_get_userdata(handle))->openstream();
+}
+static mng_bool closestream( mng_handle handle )
+{
+ return ((TQMNGFormat*)mng_get_userdata(handle))->closestream();
+}
+static mng_bool readdata( mng_handle handle, mng_ptr pBuf, mng_uint32 iBuflen, mng_uint32p pRead )
+{
+ return ((TQMNGFormat*)mng_get_userdata(handle))->readdata(pBuf,iBuflen,pRead);
+}
+static mng_bool errorproc( mng_handle handle,
+ mng_int32 iErrorcode,
+ mng_int8 iSeverity,
+ mng_chunkid iChunkname,
+ mng_uint32 iChunkseq,
+ mng_int32 iExtra1,
+ mng_int32 iExtra2,
+ mng_pchar zErrortext )
+{
+ return ((TQMNGFormat*)mng_get_userdata(handle))->errorproc(iErrorcode,
+ iSeverity,iChunkname,iChunkseq,iExtra1,iExtra2,zErrortext);
+}
+static mng_bool processheader( mng_handle handle,
+ mng_uint32 iWidth, mng_uint32 iHeight )
+{
+ return ((TQMNGFormat*)mng_get_userdata(handle))->processheader(iWidth,iHeight);
+}
+static mng_ptr getcanvasline( mng_handle handle, mng_uint32 iLinenr )
+{
+ return ((TQMNGFormat*)mng_get_userdata(handle))->getcanvasline(iLinenr);
+}
+static mng_bool refresh( mng_handle handle,
+ mng_uint32 iTop,
+ mng_uint32 iLeft,
+ mng_uint32 iBottom,
+ mng_uint32 iRight )
+{
+ return ((TQMNGFormat*)mng_get_userdata(handle))->refresh(iTop,iLeft,iBottom,iRight);
+}
+static mng_uint32 gettickcount( mng_handle handle )
+{
+ return ((TQMNGFormat*)mng_get_userdata(handle))->gettickcount();
+}
+static mng_bool settimer( mng_handle handle, mng_uint32 iMsecs )
+{
+ return ((TQMNGFormat*)mng_get_userdata(handle))->settimer(iMsecs);
+}
+
+static mng_ptr memalloc( mng_size_t iLen )
+{
+ return calloc(1,iLen);
+}
+static void memfree( mng_ptr iPtr, mng_size_t /*iLen*/ )
+{
+ free(iPtr);
+}
+
+/*!
+ This function decodes some data into image changes.
+
+ Returns the number of bytes consumed.
+*/
+int TQMNGFormat::decode( TQImage& img, TQImageConsumer* cons,
+ const uchar* buf, int length )
+{
+ consumer = cons;
+ image = &img;
+
+ data = buf;
+ ndata = length;
+ ubuffer = 0;
+
+ if ( state == MovieStart ) {
+ handle = mng_initialize( (mng_ptr)this, ::memalloc, ::memfree, 0 );
+ mng_set_suspensionmode( handle, MNG_TRUE );
+ mng_setcb_openstream( handle, ::openstream );
+ mng_setcb_closestream( handle, ::closestream );
+ mng_setcb_readdata( handle, ::readdata );
+ mng_setcb_errorproc( handle, ::errorproc );
+ mng_setcb_processheader( handle, ::processheader );
+ mng_setcb_getcanvasline( handle, ::getcanvasline );
+ mng_setcb_refresh( handle, ::refresh );
+ mng_setcb_gettickcount( handle, ::gettickcount );
+ mng_setcb_settimer( handle, ::settimer );
+ state = Data;
+ mng_readdisplay(handle);
+ losingtimer.start();
+ }
+
+ losttime += losingtimer.elapsed();
+ if ( ndata || !length )
+ mng_display_resume(handle);
+ losingtimer.start();
+
+ image = 0;
+
+ nbuffer -= ubuffer;
+ if ( nbuffer ) {
+ // Move back unused tail
+ memcpy(buffer,buffer+ubuffer,nbuffer);
+ }
+ if ( ndata ) {
+ // Not all used.
+ enlargeBuffer(nbuffer+ndata);
+ memcpy(buffer+nbuffer,data,ndata);
+ nbuffer += ndata;
+ }
+
+ return length;
+}
+
+static TQMNGFormatType* globalMngFormatTypeObject = 0;
+
+#endif // TQT_NO_ASYNC_IMAGE_IO
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+void qCleanupMngIO()
+{
+ if ( globalMngFormatTypeObject ) {
+ delete globalMngFormatTypeObject;
+ globalMngFormatTypeObject = 0;
+ }
+}
+#endif
+
+void qInitMngIO()
+{
+ static bool done = FALSE;
+ if ( !done ) {
+ done = TRUE;
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+ globalMngFormatTypeObject = new TQMNGFormatType;
+ qAddPostRoutine( qCleanupMngIO );
+#endif
+ }
+}
+
+#endif // TQT_NO_IMAGEIO_MNG
diff --git a/tqtinterface/qt4/src/kernel/tqmngio.h b/tqtinterface/qt4/src/kernel/tqmngio.h
new file mode 100644
index 0000000..3467350
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmngio.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Definition of MNG TQImage IOHandler
+**
+** Created : 970521
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMNGIO_H
+#define TQMNGIO_H
+
+#ifndef TQT_H
+#endif // TQT_H
+
+#ifndef TQT_NO_IMAGEIO_MNG
+
+void qInitMngIO();
+
+#endif // TQT_NO_IMAGEIO_MNG
+
+#endif // TQMNGIO_H
diff --git a/tqtinterface/qt4/src/kernel/tqmotifdnd_x11.cpp b/tqtinterface/qt4/src/kernel/tqmotifdnd_x11.cpp
new file mode 100644
index 0000000..7c17e68
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmotifdnd_x11.cpp
@@ -0,0 +1,978 @@
+/****************************************************************************
+**
+** Implementation of Motif Dynamic Drag and Drop class
+**
+** Created : 950419
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/* The following copyright notice pertains to the code as contributed
+to Trolltech, not to Trolltech's modifications. It is replicated
+in doc/dnd.doc, where the documentation system can see it. */
+
+/* Copyright 1996 Daniel Dardailler.
+
+ Permission to use, copy, modify, distribute, and sell this software
+ for any purpose is hereby granted without fee, provided that the above
+ copyright notice appear in all copies and that both that copyright
+ notice and this permission notice appear in supporting documentation,
+ and that the name of Daniel Dardailler not be used in advertising or
+ publicity pertaining to distribution of the software without specific,
+ written prior permission. Daniel Dardailler makes no representations
+ about the suitability of this software for any purpose. It is
+ provided "as is" without express or implied warranty.
+
+ Modifications Copyright 1999 Matt Koss, under the same license as
+ above.
+************************************************************/
+
+/***********************************************************/
+/* Motif Drag&Drop Dynamic Protocol messaging API code */
+/* Only requires Xlib layer - not MT safe */
+/* Author: Daniel Dardailler, daniel@x.org */
+/* Adapted by : Matt Koss, koss@napri.sk */
+/* Further adaptions by : Trolltech ASA */
+/***********************************************************/
+
+#include "tqplatformdefs.h"
+
+#include "tqapplication.h"
+
+#ifndef TQT_NO_DRAGANDDROP
+
+#include "tqwidget.h"
+#include "tqt_x11_p.h"
+
+#include <stdlib.h>
+
+
+static Atom atom_message_type, atom_receiver_info, atom_src_property_type;
+static Atom atom_motif_window, atom_target_list ;
+
+static bool in_drop_site = FALSE;
+static Window cur_window = 0;
+static TQWidget *drop_widget = 0L;
+
+static Atom Dnd_transfer_success, Dnd_transfer_failure;
+
+static Atom Dnd_selection;
+static Time Dnd_selection_time;
+
+static Atom * src_targets ;
+static ushort num_src_targets ;
+
+extern bool qt_motifdnd_active;
+
+// this stuff is copied from qclipboard_x11.cpp
+
+extern bool qt_xclb_wait_for_event( Display *dpy, Window win, int type,
+ XEvent *event, int timeout );
+extern bool qt_xclb_read_property( Display *dpy, Window win, Atom property,
+ bool deleteProperty,
+ TQByteArray *buffer, int *size, Atom *type,
+ int *format, bool nullterm );
+
+extern Atom* qt_xdnd_str_to_atom( const char *mimeType );
+extern const char* qt_xdnd_atom_to_str( Atom );
+
+
+// Motif definitions
+#define DndVersion 1
+#define DndRevision 0
+#define DndIncludeVersion (DndVersion * 10 + DndRevision)
+
+/* The following values are used in the DndData structure */
+
+/* protocol style */
+#define DND_DRAG_NONE 0
+#define DND_DRAG_DROP_ONLY 1
+#define DND_DRAG_DYNAMIC 5
+
+/* message type */
+#define DND_TOP_LEVEL_ENTER 0
+#define DND_TOP_LEVEL_LEAVE 1
+#define DND_DRAG_MOTION 2
+#define DND_DROP_SITE_ENTER 3
+#define DND_DROP_SITE_LEAVE 4
+#define DND_DROP_START 5
+#define DND_OPERATION_CHANGED 8
+
+/* operation(s) */
+#define DND_NOOP 0L
+#define DND_MOVE (1L << 0)
+#define DND_COPY (1L << 1)
+#define DND_LINK (1L << 2)
+
+/* status */
+#define DND_NO_DROP_SITE 1
+#define DND_INVALID_DROP_SITE 2
+#define DND_VALID_DROP_SITE 3
+
+/* completion */
+#define DND_DROP 0
+#define DND_DROP_HELP 1
+#define DND_DROP_CANCEL 2
+
+#define BYTE unsigned char
+#define CARD32 unsigned int
+#define CARD16 unsigned short
+#define INT16 signed short
+
+/* Client side structure used in the API */
+typedef struct {
+ unsigned char reason; /* message type: DND_TOP_LEVEL_ENTER, etc */
+ Time time ;
+ unsigned char operation;
+ unsigned char operations;
+ unsigned char status;
+ unsigned char completion;
+ short x ;
+ short y ;
+ Window src_window ;
+ Atom property ;
+} DndData ;
+
+
+typedef struct _DndSrcProp {
+ BYTE byte_order ;
+ BYTE protocol_version ;
+ CARD16 target_index ;
+ CARD32 selection ;
+} DndSrcProp ;
+
+typedef struct _DndReceiverProp {
+ BYTE byte_order ;
+ BYTE protocol_version ;
+ BYTE protocol_style ;
+ BYTE pad1;
+ CARD32 proxy_window;
+ CARD16 num_drop_sites ;
+ CARD16 pad2;
+ CARD32 total_size;
+} DndReceiverProp ;
+
+/* need to use some union hack since window and property are in
+ different order depending on the message ... */
+typedef struct _DndTop {
+ CARD32 src_window;
+ CARD32 property;
+} DndTop ;
+
+typedef struct _DndPot {
+ INT16 x;
+ INT16 y;
+ CARD32 property;
+ CARD32 src_window;
+} DndPot ;
+
+typedef struct _DndMessage {
+ BYTE reason;
+ BYTE byte_order;
+ CARD16 flags;
+ CARD32 time;
+ union {
+ DndTop top ;
+ DndPot pot ;
+ } data ;
+} DndMessage ;
+
+typedef struct {
+ BYTE byte_order;
+ BYTE protocol_version;
+ CARD16 num_target_lists;
+ CARD32 data_size;
+ /* then come series of CARD16,CARD32,CARD32,CARD32... */
+} DndTargets;
+
+
+/* protocol version */
+#define DND_PROTOCOL_VERSION 0
+
+
+#define DND_EVENT_TYPE_MASK ((BYTE)0x80)
+#define DND_EVENT_TYPE_SHIFT 7
+#define DND_CLEAR_EVENT_TYPE ((BYTE)0x7F)
+
+/* message_type is data[0] of the client_message
+ this return 1 (receiver bit up) or 0 (initiator) */
+#define DND_GET_EVENT_TYPE(message_type) \
+((char) (((message_type) & DND_EVENT_TYPE_MASK) >> DND_EVENT_TYPE_SHIFT))
+
+/* event_type can be 0 (initiator) or 1 (receiver) */
+#define DND_SET_EVENT_TYPE(event_type) \
+(((BYTE)(event_type) << DND_EVENT_TYPE_SHIFT) & DND_EVENT_TYPE_MASK)
+
+
+#define DND_OPERATION_MASK ((CARD16) 0x000F)
+#define DND_OPERATION_SHIFT 0
+#define DND_STATUS_MASK ((CARD16) 0x00F0)
+#define DND_STATUS_SHIFT 4
+#define DND_OPERATIONS_MASK ((CARD16) 0x0F00)
+#define DND_OPERATIONS_SHIFT 8
+#define DND_COMPLETION_MASK ((CARD16) 0xF000)
+#define DND_COMPLETION_SHIFT 12
+
+#define DND_GET_OPERATION(flags) \
+((unsigned char) \
+(((flags) & DND_OPERATION_MASK) >> DND_OPERATION_SHIFT))
+
+#define DND_SET_OPERATION(operation) \
+(((CARD16)(operation) << DND_OPERATION_SHIFT)\
+& DND_OPERATION_MASK)
+
+#define DND_GET_STATUS(flags) \
+((unsigned char) \
+(((flags) & DND_STATUS_MASK) >> DND_STATUS_SHIFT))
+
+#define DND_SET_STATUS(status) \
+(((CARD16)(status) << DND_STATUS_SHIFT)\
+& DND_STATUS_MASK)
+
+#define DND_GET_OPERATIONS(flags) \
+((unsigned char) \
+(((flags) & DND_OPERATIONS_MASK) >> DND_OPERATIONS_SHIFT))
+
+#define DND_SET_OPERATIONS(operation) \
+(((CARD16)(operation) << DND_OPERATIONS_SHIFT)\
+& DND_OPERATIONS_MASK)
+
+#define DND_GET_COMPLETION(flags) \
+((unsigned char) \
+(((flags) & DND_COMPLETION_MASK) >> DND_COMPLETION_SHIFT))
+
+#define DND_SET_COMPLETION(completion) \
+(((CARD16)(completion) << DND_COMPLETION_SHIFT)\
+& DND_COMPLETION_MASK)
+
+
+#define SWAP4BYTES(l) {\
+struct { unsigned t :32;} bit32;\
+char n, *tp = (char *) &bit32;\
+bit32.t = l;\
+n = tp[0]; tp[0] = tp[3]; tp[3] = n;\
+n = tp[1]; tp[1] = tp[2]; tp[2] = n;\
+l = bit32.t;\
+}
+
+#define SWAP2BYTES(s) {\
+struct { unsigned t :16; } bit16;\
+char n, *tp = (char *) &bit16;\
+bit16.t = s;\
+n = tp[0]; tp[0] = tp[1]; tp[1] = n;\
+s = bit16.t;\
+}
+
+
+/** Private extern functions */
+
+static unsigned char DndByteOrder ();
+
+
+/***** Targets/Index stuff */
+
+typedef struct {
+ int num_targets;
+ Atom *targets;
+} DndTargetsTableEntryRec, * DndTargetsTableEntry;
+
+typedef struct {
+ int num_entries;
+ DndTargetsTableEntry entries;
+} DndTargetsTableRec, * DndTargetsTable;
+
+
+static int _DndIndexToTargets(Display * display,
+ int index,
+ Atom ** targets);
+
+extern void qt_x11_intern_atom( const char *, Atom * );
+
+/////////////////////////////////////////////////////////////////
+
+void qt_x11_motifdnd_init()
+{
+ /* Init atoms used in the com */
+
+ qt_x11_intern_atom( "_MOTIF_DRAG_AND_DROP_MESSAGE", &atom_message_type );
+ qt_x11_intern_atom( "_MOTIF_DRAG_INITIATOR_INFO", &atom_src_property_type );
+ qt_x11_intern_atom( "_MOTIF_DRAG_RECEIVER_INFO", &atom_receiver_info );
+ qt_x11_intern_atom( "_MOTIF_DRAG_WINDOW", &atom_motif_window );
+ qt_x11_intern_atom( "_MOTIF_DRAG_TARGETS", &atom_target_list );
+
+ qt_x11_intern_atom( "XmTRANSFER_SUCCESS", &Dnd_transfer_success );
+ qt_x11_intern_atom( "XmTRANSFER_FAILURE", &Dnd_transfer_failure );
+
+ char my_dnd_selection_name[30]; // 11-digit number should be enough
+ sprintf(my_dnd_selection_name, "_MY_DND_SELECTION_%d", (int)getpid());
+ qt_x11_intern_atom( my_dnd_selection_name, &Dnd_selection );
+}
+
+static unsigned char DndByteOrder ()
+{
+ static unsigned char byte_order = 0;
+
+ if (!byte_order) {
+ unsigned int endian = 1;
+ byte_order = (*((char *)&endian))?'l':'B';
+ }
+ return byte_order ;
+}
+
+
+
+static void DndReadSourceProperty(Display * dpy,
+ Window window, Atom dnd_selection,
+ Atom ** targets, unsigned short * num_targets)
+{
+ DndSrcProp * src_prop = 0;
+ Atom type ;
+ int format ;
+ unsigned long bytesafter, lengthRtn;
+
+ if ((XGetWindowProperty (dpy, window, dnd_selection, 0L, 100000L,
+ False, atom_src_property_type, &type,
+ &format, &lengthRtn, &bytesafter,
+ (unsigned char **) &src_prop) != Success)
+ || (type == None)) {
+ *num_targets = 0;
+ return ;
+ }
+
+ if (src_prop->byte_order != DndByteOrder()) {
+ SWAP2BYTES(src_prop->target_index);
+ SWAP4BYTES(src_prop->selection);
+ }
+
+ *num_targets = _DndIndexToTargets(dpy, src_prop->target_index, targets);
+
+ XFree((char*)src_prop);
+}
+
+
+/* Position the _MOTIF_DRAG_RECEIVER_INFO property on the dropsite window.
+ Called by the receiver of the drop to indicate the
+ supported protocol style : dynamic, drop_only or none */
+static void DndWriteReceiverProperty(Display * dpy, Window window,
+ unsigned char protocol_style)
+{
+ DndReceiverProp receiver_prop ;
+
+ receiver_prop.byte_order = DndByteOrder() ;
+ receiver_prop.protocol_version = DND_PROTOCOL_VERSION;
+ receiver_prop.protocol_style = protocol_style ;
+ receiver_prop.proxy_window = None ;
+ receiver_prop.num_drop_sites = 0 ;
+ receiver_prop.total_size = sizeof(DndReceiverProp);
+
+ /* write the buffer to the property */
+ XChangeProperty (dpy, window, atom_receiver_info, atom_receiver_info,
+ 8, PropModeReplace,
+ (unsigned char *)&receiver_prop,
+ sizeof(DndReceiverProp));
+}
+
+
+/* protocol style equiv (preregister stuff really) */
+#define DND_DRAG_DROP_ONLY_ETQUIV 3
+#define DND_DRAG_DYNAMIC_ETQUIV1 2
+#define DND_DRAG_DYNAMIC_ETQUIV2 4
+
+
+/* Produce a client message to be sent by the caller */
+static void DndFillClientMessage(Display * dpy, Window window,
+ XClientMessageEvent *cm,
+ DndData * dnd_data,
+ char receiver)
+{
+ DndMessage * dnd_message = (DndMessage*)&cm->data.b[0] ;
+
+ cm->display = dpy;
+ cm->type = ClientMessage;
+ cm->serial = LastKnownRequestProcessed(dpy);
+ cm->send_event = True;
+ cm->window = window;
+ cm->format = 8;
+ cm->message_type = atom_message_type ;/* _MOTIF_DRAG_AND_DROP_MESSAGE */
+
+ dnd_message->reason = dnd_data->reason | DND_SET_EVENT_TYPE(receiver);
+
+ dnd_message->byte_order = DndByteOrder();
+
+ /* we're filling in flags with more stuff that necessary,
+ depending on the reason, but it doesn't matter */
+ dnd_message->flags = 0 ;
+ dnd_message->flags |= DND_SET_STATUS(dnd_data->status) ;
+ dnd_message->flags |= DND_SET_OPERATION(dnd_data->operation) ;
+ dnd_message->flags |= DND_SET_OPERATIONS(dnd_data->operations) ;
+ dnd_message->flags |= DND_SET_COMPLETION(dnd_data->completion) ;
+
+ dnd_message->time = dnd_data->time ;
+
+ switch(dnd_data->reason) {
+ case DND_DROP_SITE_LEAVE: break ;
+ case DND_TOP_LEVEL_ENTER:
+ case DND_TOP_LEVEL_LEAVE:
+ dnd_message->data.top.src_window = dnd_data->src_window ;
+ dnd_message->data.top.property = dnd_data->property ;
+ break ; /* cannot fall thru since the byte tqlayout is different in
+ both set of messages, see top and pot union stuff */
+
+ case DND_DRAG_MOTION:
+ case DND_OPERATION_CHANGED:
+ case DND_DROP_SITE_ENTER:
+ case DND_DROP_START:
+ dnd_message->data.pot.x = dnd_data->x ; /* mouse position */
+ dnd_message->data.pot.y = dnd_data->y ;
+ dnd_message->data.pot.src_window = dnd_data->src_window ;
+ dnd_message->data.pot.property = dnd_data->property ;
+ break ;
+ default:
+ break ;
+ }
+
+}
+
+static Bool DndParseClientMessage(XClientMessageEvent *cm, DndData * dnd_data,
+ char * receiver)
+{
+ DndMessage * dnd_message = (DndMessage*)&cm->data.b[0] ;
+
+ if (cm->message_type != atom_message_type) {
+ return False ;
+ }
+
+ if (dnd_message->byte_order != DndByteOrder()) {
+ SWAP2BYTES(dnd_message->flags);
+ SWAP4BYTES(dnd_message->time);
+ } /* do the rest in the switch */
+
+ dnd_data->reason = dnd_message->reason ;
+ if (DND_GET_EVENT_TYPE(dnd_data->reason))
+ *receiver = 1 ;
+ else
+ *receiver = 0 ;
+ dnd_data->reason &= DND_CLEAR_EVENT_TYPE ;
+
+ dnd_data->time = dnd_message->time ;
+
+ /* we're reading in more stuff that necessary. but who cares */
+ dnd_data->status = DND_GET_STATUS(dnd_message->flags) ;
+ dnd_data->operation = DND_GET_OPERATION(dnd_message->flags) ;
+ dnd_data->operations = DND_GET_OPERATIONS(dnd_message->flags) ;
+ dnd_data->completion = DND_GET_COMPLETION(dnd_message->flags) ;
+
+ switch(dnd_data->reason) {
+ case DND_TOP_LEVEL_ENTER:
+ case DND_TOP_LEVEL_LEAVE:
+ if (dnd_message->byte_order != DndByteOrder()) {
+ SWAP4BYTES(dnd_message->data.top.src_window);
+ SWAP4BYTES(dnd_message->data.top.property);
+ }
+ dnd_data->src_window = dnd_message->data.top.src_window ;
+ dnd_data->property = dnd_message->data.top.property ;
+ break ; /* cannot fall thru, see above comment in write msg */
+
+ case DND_DRAG_MOTION:
+ case DND_OPERATION_CHANGED:
+ case DND_DROP_SITE_ENTER:
+ case DND_DROP_START:
+ if (dnd_message->byte_order != DndByteOrder()) {
+ SWAP2BYTES(dnd_message->data.pot.x);
+ SWAP2BYTES(dnd_message->data.pot.y);
+ SWAP4BYTES(dnd_message->data.pot.property);
+ SWAP4BYTES(dnd_message->data.pot.src_window);
+ }
+ dnd_data->x = dnd_message->data.pot.x ;
+ dnd_data->y = dnd_message->data.pot.y ;
+ dnd_data->property = dnd_message->data.pot.property ;
+ dnd_data->src_window = dnd_message->data.pot.src_window ;
+ break ;
+
+ case DND_DROP_SITE_LEAVE:
+ break;
+ default:
+ break ;
+ }
+
+ return True ;
+}
+
+
+static Window MotifWindow(Display *display )
+{
+ Atom type;
+ int format;
+ unsigned long size;
+ unsigned long bytes_after;
+ Window *property = 0;
+ Window motif_window ;
+
+ /* this version does no caching, so it's slow: round trip each time */
+
+ if ((XGetWindowProperty (display, DefaultRootWindow(display),
+ atom_motif_window,
+ 0L, 100000L, False, AnyPropertyType,
+ &type, &format, &size, &bytes_after,
+ (unsigned char **) &property) == Success) &&
+ (type != None)) {
+ motif_window = *property;
+ } else {
+ XSetWindowAttributes sAttributes;
+
+ /* really, this should be done on a separate connection,
+ with XSetCloseDownMode (RetainPermanent), so that
+ others don't have to recreate it; hopefully, some real
+ Motif application will be around to do it */
+
+ sAttributes.override_redirect = True;
+ sAttributes.event_mask = PropertyChangeMask;
+ motif_window = XCreateWindow (display,
+ DefaultRootWindow (display),
+ -170, -560, 1, 1, 0, 0,
+ InputOnly, CopyFromParent,
+ (CWOverrideRedirect |CWEventMask),
+ &sAttributes);
+ XMapWindow (display, motif_window);
+ }
+
+ if (property) {
+ XFree ((char *)property);
+ }
+
+ return (motif_window);
+}
+
+
+static DndTargetsTable TargetsTable(Display *display)
+{
+ Atom type;
+ int format;
+ unsigned long size;
+ unsigned long bytes_after;
+ Window motif_window = MotifWindow(display) ;
+ DndTargets * target_prop;
+ DndTargetsTable targets_table ;
+ int i,j ;
+ char * target_data ;
+
+ /* this version does no caching, so it's slow: round trip each time */
+ /* ideally, register for property notify on this target_list
+ atom and update when necessary only */
+
+ if ((XGetWindowProperty (display, motif_window,
+ atom_target_list, 0L, 100000L,
+ False, atom_target_list,
+ &type, &format, &size, &bytes_after,
+ (unsigned char **) &target_prop) != Success) ||
+ type == None) {
+ qWarning("TQMotifDND: cannot get property on motif window");
+ return 0;
+ }
+
+ if (target_prop->protocol_version != DND_PROTOCOL_VERSION) {
+ qWarning("TQMotifDND: protocol mismatch");
+ }
+
+ if (target_prop->byte_order != DndByteOrder()) {
+ /* need to swap num_target_lists and size */
+ SWAP2BYTES(target_prop->num_target_lists);
+ SWAP4BYTES(target_prop->data_size);
+ }
+
+ /* now parse DndTarget prop data in a TargetsTable */
+
+ targets_table = (DndTargetsTable)malloc(sizeof(DndTargetsTableRec));
+ targets_table->num_entries = target_prop->num_target_lists ;
+ targets_table->entries = (DndTargetsTableEntry)
+ malloc(sizeof(DndTargetsTableEntryRec) * target_prop->num_target_lists);
+
+ target_data = (char*)target_prop + sizeof(*target_prop) ;
+
+ for (i = 0 ; i < targets_table->num_entries; i++) {
+ CARD16 num_targets ;
+ CARD32 atom ;
+
+ memcpy(&num_targets, target_data, 2);
+ target_data += 2;
+
+ /* potential swap needed here */
+ if (target_prop->byte_order != DndByteOrder())
+ SWAP2BYTES(num_targets);
+
+ targets_table->entries[i].num_targets = num_targets ;
+ targets_table->entries[i].targets = (Atom *)
+ malloc(sizeof(Atom) * targets_table->entries[i].num_targets);
+
+
+ for (j = 0; j < num_targets; j++) {
+ memcpy(&atom, target_data, 4 );
+ target_data += 4;
+
+ /* another potential swap needed here */
+ if (target_prop->byte_order != DndByteOrder())
+ SWAP4BYTES(atom);
+
+ targets_table->entries[i].targets[j] = (Atom) atom ;
+ }
+ }
+
+ if (target_prop) {
+ XFree((char *)target_prop);
+ }
+
+ return targets_table ;
+}
+
+
+static int _DndIndexToTargets(Display * display,
+ int index,
+ Atom ** targets)
+{
+ DndTargetsTable targets_table;
+ int i ;
+
+ /* again, slow: no caching here, alloc/free each time */
+
+ if (!(targets_table = TargetsTable (display)) ||
+ (index >= targets_table->num_entries)) {
+ return -1;
+ }
+
+ /* transfer the correct target list index */
+ *targets = (Atom*)malloc(sizeof(Atom)*targets_table->
+ entries[index].num_targets);
+ memcpy((char*)*targets,
+ (char*)targets_table->entries[index].targets,
+ sizeof(Atom)*targets_table->entries[index].num_targets);
+
+ /* free the target table and its guts */
+ for (i=0 ; i < targets_table->num_entries; i++)
+ XFree((char*)targets_table->entries[i].targets);
+
+ int tmp = targets_table->entries[index].num_targets;
+ XFree((char*)targets_table);
+
+ return tmp; // targets_table->entries[index].num_targets;
+}
+
+
+const char *qt_motifdnd_format( int n )
+{
+ if ( ! qt_motifdnd_active )
+ return 0; // should not happen
+
+ if ( n == 0 )
+ return "text/plain";
+ if ( n == 1 )
+ return "text/uri-list";
+ n -= 2;
+
+ if ( n >= num_src_targets )
+ return 0;
+
+ Atom target = src_targets[n];
+
+ // duplicated from qclipboard_x11.cpp - not the best solution
+ static Atom xa_utf8_string = *qt_xdnd_str_to_atom( "UTF8_STRING" );
+ static Atom xa_text = *qt_xdnd_str_to_atom( "TEXT" );
+ static Atom xa_compound_text = *qt_xdnd_str_to_atom( "COMPOUND_TEXT" );
+
+ if ( target == XA_STRING )
+ return "text/plain;charset=ISO-8859-1";
+ if ( target == xa_utf8_string )
+ return "text/plain;charset=UTF-8";
+ if ( target == xa_text ||
+ target == xa_compound_text )
+ return "text/plain";
+
+ return qt_xdnd_atom_to_str( target );
+}
+
+
+TQByteArray qt_motifdnd_obtain_data( const char *mimeType )
+{
+ TQByteArray result;
+
+ // try to convert the selection to the requested property
+ // qDebug( "trying to convert to '%s'", mimeType );
+
+ int n=0;
+ const char* f;
+ do {
+ f = qt_motifdnd_format( n );
+ if ( !f )
+ return result;
+ n++;
+ } while( qstricmp( mimeType, f ) );
+
+ // found one
+ Atom conversion_type;
+
+ if ( qstrnicmp( f, "text/", 5 ) == 0 ) {
+ // always convert text to XA_STRING for compatibility with
+ // prior TQt versions
+ conversion_type = XA_STRING;
+ } else {
+ conversion_type = *qt_xdnd_str_to_atom( f );
+ // qDebug( "found format '%s' 0x%lx '%s'", f, conversion_type,
+ // qt_xdnd_atom_to_str( conversion_type ) );
+ }
+
+ if ( XGetSelectionOwner( qt_xdisplay(),
+ Dnd_selection ) == None ) {
+ return result; // should never happen?
+ }
+
+ TQWidget* tw = drop_widget;
+ if ( drop_widget->isDesktop() ) {
+ tw = new TQWidget;
+ }
+
+ // convert selection to the appropriate type
+ XConvertSelection (qt_xdisplay(), Dnd_selection, conversion_type,
+ Dnd_selection, tw->winId(), Dnd_selection_time);
+
+ XFlush( qt_xdisplay() );
+
+ XEvent xevent;
+ bool got=qt_xclb_wait_for_event( qt_xdisplay(),
+ tw->winId(),
+ SelectionNotify, &xevent, 5000);
+ if ( got ) {
+ Atom type;
+
+ if ( qt_xclb_read_property( qt_xdisplay(),
+ tw->winId(),
+ Dnd_selection, TRUE,
+ &result, 0, &type, 0, TRUE ) ) {
+ }
+ }
+
+ // we have to convert selection in order to indicate success to the initiator
+ XConvertSelection (qt_xdisplay(), Dnd_selection, Dnd_transfer_success,
+ Dnd_selection, tw->winId(), Dnd_selection_time);
+
+ // wait again for SelectionNotify event
+ qt_xclb_wait_for_event( qt_xdisplay(),
+ tw->winId(),
+ SelectionNotify, &xevent, 5000);
+
+ if ( drop_widget->isDesktop() ) {
+ delete tw;
+ }
+
+ return result;
+}
+
+
+void qt_motifdnd_enable( TQWidget *widget, bool )
+{
+ DndWriteReceiverProperty( widget->x11Display(), widget->winId(),
+ DND_DRAG_DYNAMIC);
+}
+
+
+void qt_motifdnd_handle_msg( TQWidget * /* w */ , const XEvent * xe, bool /* passive */ )
+{
+
+ XEvent event = *xe;
+ XClientMessageEvent cm ;
+ DndData dnd_data ;
+ char receiver ;
+
+ if (!(DndParseClientMessage ((XClientMessageEvent*)&event,
+ &dnd_data, &receiver))) {
+ return;
+ }
+
+ switch ( dnd_data.reason ) {
+
+ case DND_DRAG_MOTION:
+
+ {
+ /* check if in drop site, and depending on the state,
+ send a drop site enter or drop site leave or echo */
+
+ TQPoint p( dnd_data.x, dnd_data.y );
+ TQWidget *c = TQApplication::widgetAt( p, TRUE );
+ if (c)
+ p = c->mapFromGlobal(p);
+
+ while ( c && !c->acceptDrops() && !c->isTopLevel() ) {
+ p = c->mapToParent( p );
+ c = c->parentWidget();
+ }
+
+ TQDragMoveEvent me( p );
+ TQDropEvent::Action accepted_action = TQDropEvent::Copy;
+ me.setAction(accepted_action);
+
+ if ( c != 0L && c->acceptDrops() ) {
+
+ if ( drop_widget != 0L && drop_widget->acceptDrops() &&
+ drop_widget != c ) {
+ TQDragLeaveEvent e;
+ TQApplication::sendEvent( drop_widget, &e );
+ TQDragEnterEvent de( p );
+ TQApplication::sendEvent( c, &de );
+ }
+
+ drop_widget = c;
+
+ if (!in_drop_site) {
+ in_drop_site = True ;
+
+ dnd_data.reason = DND_DROP_SITE_ENTER ;
+ dnd_data.time = CurrentTime ;
+ dnd_data.operation = DND_MOVE|DND_COPY;
+ dnd_data.operations = DND_MOVE|DND_COPY;
+
+ DndFillClientMessage (event.xclient.display,
+ cur_window,
+ &cm, &dnd_data, 0);
+
+ XSendEvent(event.xbutton.display,
+ cur_window, False, 0,
+ (XEvent *)&cm) ;
+
+ TQDragEnterEvent de( p );
+ TQApplication::sendEvent( drop_widget, &de );
+ if ( de.isAccepted() ) {
+ me.accept( de.answerRect() );
+ } else {
+ me.ignore( de.answerRect() );
+ }
+
+ } else {
+ dnd_data.reason = DND_DRAG_MOTION ;
+ dnd_data.time = CurrentTime ;
+ dnd_data.operation = DND_MOVE|DND_COPY;
+ dnd_data.operations = DND_MOVE|DND_COPY;
+
+ DndFillClientMessage (event.xclient.display,
+ cur_window,
+ &cm, &dnd_data, 0);
+
+ XSendEvent(event.xbutton.display,
+ cur_window, False, 0,
+ (XEvent *)&cm) ;
+
+ TQApplication::sendEvent( drop_widget, &me );
+ }
+ } else {
+ if (in_drop_site) {
+ in_drop_site = False ;
+
+ dnd_data.reason = DND_DROP_SITE_LEAVE ;
+ dnd_data.time = CurrentTime ;
+
+ DndFillClientMessage (event.xclient.display,
+ cur_window,
+ &cm, &dnd_data, 0);
+
+ XSendEvent(event.xbutton.display,
+ cur_window, False, 0,
+ (XEvent *)&cm) ;
+
+ TQDragLeaveEvent e;
+ TQApplication::sendEvent( drop_widget, &e );
+ }
+ }
+ }
+ break;
+
+ case DND_TOP_LEVEL_ENTER:
+
+ /* get the size of our drop site for later use */
+
+ cur_window = dnd_data.src_window ;
+ qt_motifdnd_active = TRUE;
+
+ /* no answer needed, just read source property */
+ DndReadSourceProperty (event.xclient.display,
+ cur_window,
+ dnd_data.property,
+ &src_targets, &num_src_targets);
+ break;
+
+ case DND_TOP_LEVEL_LEAVE:
+ /* no need to do anything */
+ break;
+
+ case DND_OPERATION_CHANGED:
+ /* need to echo */
+ break;
+
+ case DND_DROP_START:
+ if (!in_drop_site) {
+ // we have to convert selection in order to indicate failure to the initiator
+ XConvertSelection (qt_xdisplay(), dnd_data.property, Dnd_transfer_failure,
+ dnd_data.property, cur_window, dnd_data.time);
+ TQDragLeaveEvent e;
+ TQApplication::sendEvent( drop_widget, &e );
+ drop_widget = 0;
+ return;
+ }
+
+ /* need to echo and then request a convert */
+ dnd_data.reason = DND_DROP_START ;
+
+ DndFillClientMessage (event.xclient.display,
+ drop_widget->winId(),
+ &cm, &dnd_data, 0);
+
+ XSendEvent(event.xbutton.display,
+ cur_window, False, 0,
+ (XEvent *)&cm) ;
+
+ // store selection and its time
+ Dnd_selection = dnd_data.property;
+ Dnd_selection_time = dnd_data.time;
+
+ TQPoint p( dnd_data.x, dnd_data.y );
+ TQDropEvent de( drop_widget->mapFromGlobal(p) );
+ de.setAction( TQDropEvent::Copy );
+ TQApplication::sendEvent( drop_widget, &de );
+
+ if (in_drop_site)
+ in_drop_site = False ;
+
+ drop_widget = 0;
+ cur_window = 0;
+ break;
+ } // end of switch ( dnd_data.reason )
+}
+
+#endif // TQT_NO_DRAGANDDROP
diff --git a/tqtinterface/qt4/src/kernel/tqmovie.cpp b/tqtinterface/qt4/src/kernel/tqmovie.cpp
new file mode 100644
index 0000000..4b77249
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmovie.cpp
@@ -0,0 +1,1082 @@
+/****************************************************************************
+**
+** Implementation of movie classes
+**
+** Created : 970617
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// #define TQT_SAVE_MOVIE_HACK
+
+#include "tqtimer.h"
+#include "tqpainter.h"
+#include "tqptrlist.h"
+#include "tqbitmap.h"
+#include "tqmovie.h"
+#include "tqfile.h"
+#include "tqbuffer.h"
+#include "tqobject.h"
+#include "tqpixmapcache.h"
+
+#ifndef TQT_NO_MOVIE
+
+#ifdef TQ_WS_TQWS
+#include "tqgfx_qws.h"
+#endif
+
+#include "tqasyncio.h"
+#include "tqasyncimageio.h"
+
+#include <stdlib.h>
+
+/*!
+ \class TQMovie tqmovie.h
+ \brief The TQMovie class provides incremental loading of animations or images, signalling as it progresses.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup multimedia
+ \mainclass
+
+ The simplest way to display a TQMovie is to use a TQLabel and
+ TQLabel::setMovie().
+
+ A TQMovie provides a TQPixmap as the framePixmap(); connections can
+ be made via connectResize() and connectUpdate() to receive
+ notification of size and pixmap changes. All decoding is driven
+ by the normal event-processing mechanisms.
+
+ The movie begins playing as soon as the TQMovie is created
+ (actually, once control returns to the event loop). When the last
+ frame in the movie has been played, it may loop back to the start
+ if such looping is defined in the input source.
+
+ TQMovie objects are explicitly shared. This means that a TQMovie
+ copied from another TQMovie will be displaying the same frame at
+ all times. If one shared movie pauses, all pause. To make \e
+ independent movies, they must be constructed separately.
+
+ The set of data formats supported by TQMovie is determined by the
+ decoder factories that have been installed; the format of the
+ input is determined as the input is decoded.
+
+ The supported formats are MNG (if TQt is configured with MNG
+ support enabled) and GIF (if TQt is configured with GIF support
+ enabled, see tqgif.h).
+
+ If TQt is configured to support GIF reading, we are required to
+ state that "The Graphics Interchange Format(c) is the Copyright
+ property of CompuServe Incorporated. GIF(sm) is a Service Mark
+ property of CompuServe Incorporated.
+
+ \warning If you are in a country that recognizes software patents
+ and in which Unisys holds a patent on LZW compression and/or
+ decompression and you want to use GIF, Unisys may require you to
+ license that technology. Such countries include Canada, Japan,
+ the USA, France, Germany, Italy and the UK.
+
+ GIF support may be removed completely in a future version of TQt.
+ We recommend using the MNG or PNG format.
+
+ \img qmovie.png TQMovie
+
+ \sa TQLabel::setMovie()
+*/
+
+/*!
+ \enum TQMovie::tqStatus
+
+ \value SourceEmpty
+ \value UnrecognizedFormat
+ \value Paused
+ \value EndOfFrame
+ \value EndOfLoop
+ \value EndOfMovie
+ \value SpeedChanged
+*/
+
+class TQMoviePrivate : public TQObject, public TQShared,
+ private TQDataSink, private TQImageConsumer
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public: // for TQMovie
+
+ // Creates a null Private
+ TQMoviePrivate();
+
+ // NOTE: The ownership of the TQDataSource is transferred to the Private
+ TQMoviePrivate(TQDataSource* src, TQMovie* movie, int bufsize);
+
+ virtual ~TQMoviePrivate();
+
+ bool isNull() const;
+
+ // Initialize, possibly to the null state
+ void init(bool fully);
+ void flushBuffer();
+ void updatePixmapFromImage();
+ void updatePixmapFromImage(const TQPoint& off, const TQRect& area);
+ void showChanges();
+
+ // This as TQImageConsumer
+ void changed(const TQRect& rect);
+ void end();
+ void preFrameDone(); //util func
+ void frameDone();
+ void frameDone(const TQPoint&, const TQRect& rect);
+ void restartTimer();
+ void setLooping(int l);
+ void setFramePeriod(int milliseconds);
+ void setSize(int w, int h);
+
+ // This as TQDataSink
+ int readyToReceive();
+ void receive(const uchar* b, int bytecount);
+ void eof();
+ void pause();
+
+Q_SIGNALS:
+ void sizeChanged(const TQSize&);
+ void areaChanged(const TQRect&);
+ void datatqStatus(int);
+
+public Q_SLOTS:
+ void refresh();
+
+public:
+ TQMovie *that;
+ TQWidget * display_widget;
+
+ TQImageDecoder *decoder;
+
+ // Cyclic buffer
+ int buf_size;
+ uchar *buffer;
+ int buf_r, buf_w, buf_usage;
+
+ int framenumber;
+ int frameperiod;
+ int speed;
+ TQTimer *frametimer;
+ int lasttimerinterval;
+ int loop;
+ bool movie_ended;
+ bool dirty_cache;
+ bool waitingForFrameTick;
+ int stepping;
+ TQRect changed_area;
+ TQRect valid_area;
+ TQDataPump *pump;
+ TQDataSource *source;
+ TQPixmap mypixmap;
+ TQBitmap mytqmask;
+ TQColor bg;
+
+ int error;
+ bool empty;
+
+#ifdef TQT_SAVE_MOVIE_HACK
+ bool save_image;
+ int image_number;
+#endif
+};
+
+
+TQMoviePrivate::TQMoviePrivate()
+{
+ dirty_cache = FALSE;
+ buffer = 0;
+ pump = 0;
+ source = 0;
+ decoder = 0;
+ display_widget=0;
+ buf_size = 0;
+ init(FALSE);
+}
+
+// NOTE: The ownership of the TQDataSource is transferred to the Private
+TQMoviePrivate::TQMoviePrivate(TQDataSource* src, TQMovie* movie, int bufsize) :
+ that(movie),
+ buf_size(bufsize)
+{
+ frametimer = new TQTimer(this);
+ pump = src ? new TQDataPump(src, this) : 0;
+ TQObject::connect(frametimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(refresh()));
+ dirty_cache = FALSE;
+ source = src;
+ buffer = 0;
+ decoder = 0;
+ speed = 100;
+ display_widget=0;
+ init(TRUE);
+}
+
+TQMoviePrivate::~TQMoviePrivate()
+{
+ if ( buffer ) // Avoid purify complaint
+ delete [] buffer;
+ delete pump;
+ delete decoder;
+ delete source;
+
+ // Too bad.. but better be safe than sorry
+ if ( dirty_cache )
+ TQPixmapCache::clear();
+}
+
+bool TQMoviePrivate::isNull() const
+{
+ return !buf_size;
+}
+
+// Initialize. Only actually allocate any space if \a fully is TRUE,
+// otherwise, just enough to be a valid null Private.
+void TQMoviePrivate::init(bool fully)
+{
+#ifdef TQT_SAVE_MOVIE_HACK
+ save_image = TRUE;
+ image_number = 0;
+#endif
+
+ buf_usage = buf_r = buf_w = 0;
+ if ( buffer ) // Avoid purify complaint
+ delete [] buffer;
+ buffer = fully ? new uchar[buf_size] : 0;
+ if ( buffer )
+ memset( buffer, 0, buf_size );
+
+ delete decoder;
+ decoder = fully ? new TQImageDecoder(this) : 0;
+
+#ifdef AVOID_OPEN_FDS
+ if ( source && !source->isOpen() )
+ source->open(IO_ReadOnly);
+#endif
+
+ waitingForFrameTick = FALSE;
+ stepping = -1;
+ framenumber = 0;
+ frameperiod = -1;
+ if (fully) frametimer->stop();
+ lasttimerinterval = -1;
+ changed_area.setRect(0,0,-1,-1);
+ valid_area = changed_area;
+ loop = -1;
+ movie_ended = FALSE;
+ error = 0;
+ empty = TRUE;
+}
+
+void TQMoviePrivate::flushBuffer()
+{
+ int used;
+ while (buf_usage && !waitingForFrameTick && stepping != 0 && !error) {
+ used = decoder->decode(buffer + buf_r, TQMIN(buf_usage, buf_size - buf_r));
+ if (used <= 0) {
+ if ( used < 0 ) {
+ error = 1;
+ emit datatqStatus(TQMovie::UnrecognizedFormat);
+ }
+ break;
+ }
+ buf_r = (buf_r + used) % buf_size;
+ buf_usage -= used;
+ }
+
+ // Some formats, like MNG, can make stuff happen without any extra data.
+ // Only do this if the movie hasn't ended, however or we'll never get the end of loop signal.
+ if (!movie_ended) {
+ used = decoder->decode(buffer + buf_r, 0);
+ if (used <= 0) {
+ if ( used < 0 ) {
+ error = 1;
+ emit datatqStatus(TQMovie::UnrecognizedFormat);
+ }
+ }
+ }
+
+ if (error)
+ frametimer->stop();
+ maybeReady();
+}
+
+void TQMoviePrivate::updatePixmapFromImage()
+{
+ if (changed_area.isEmpty()) return;
+ updatePixmapFromImage(TQPoint(0,0),changed_area);
+}
+
+void TQMoviePrivate::updatePixmapFromImage(const TQPoint& off,
+ const TQRect& area)
+{
+ // Create temporary TQImage to hold the part we want
+ const TQImage& gimg = decoder->image();
+ TQImage img = gimg.copy(area);
+
+#ifdef TQT_SAVE_MOVIE_HACK
+ if ( save_image ) {
+ TQString name;
+ name.sprintf("movie%i.ppm",image_number++);
+ gimg.save( name, "PPM" );
+ }
+#endif
+
+ // Resize to size of image
+ if (mypixmap.width() != gimg.width() || mypixmap.height() != gimg.height())
+ mypixmap.resize(gimg.width(), gimg.height());
+
+ // Convert to pixmap and paste that onto myself
+ TQPixmap lines;
+
+#ifndef TQT_NO_SPRINTF
+ if (!(frameperiod < 0 && loop == -1)) {
+ // its an animation, lets see if we converted
+ // this frame already.
+ TQString key;
+ key.sprintf( "%08lx:%04d", ( long )this, framenumber );
+ if ( !TQPixmapCache::tqfind( key, lines ) ) {
+ lines.convertFromImage(img, TQt::ColorOnly);
+ TQPixmapCache::insert( key, lines );
+ dirty_cache = TRUE;
+ }
+ } else
+#endif
+ {
+ lines.convertFromImage(img, TQt::ColorOnly);
+ }
+
+ if (bg.isValid()) {
+ TQPainter p;
+ p.begin(&mypixmap);
+ p.fillRect(area, bg);
+ p.drawPixmap(area, lines);
+ p.end();
+ } else {
+ if (gimg.hasAlphaBuffer()) {
+ // Resize to size of image
+ if (mytqmask.isNull()) {
+ mytqmask.resize(gimg.width(), gimg.height());
+ mytqmask.fill( TQt::color1 );
+ }
+ }
+ mypixmap.setMask(TQBitmap()); // Remove reference to my tqmask
+ copyBlt( &mypixmap, area.left(), area.top(),
+ &lines, off.x(), off.y(), area.width(), area.height() );
+ }
+
+#ifdef TQ_WS_TQWS
+ if(display_widget) {
+ TQGfx * mygfx=display_widget->graphicsContext();
+ if(mygfx) {
+ double xscale,yscale;
+ xscale=display_widget->width();
+ yscale=display_widget->height();
+ xscale=xscale/((double)mypixmap.width());
+ yscale=yscale/((double)mypixmap.height());
+ double xh,yh;
+ xh=xscale*((double)area.left());
+ yh=yscale*((double)area.top());
+ mygfx->setSource(&mypixmap);
+ mygfx->setAlphaType(TQGfx::IgnoreAlpha);
+ mygfx->stretchBlt(0,0,display_widget->width(),
+ display_widget->height(),mypixmap.width(),
+ mypixmap.height());
+ delete mygfx;
+ }
+ }
+#endif
+}
+
+void TQMoviePrivate::showChanges()
+{
+ if (changed_area.isValid()) {
+ updatePixmapFromImage();
+
+ valid_area = valid_area.unite(changed_area);
+ emit areaChanged(changed_area);
+
+ changed_area.setWidth(-1); // make empty
+ }
+}
+
+// Private as TQImageConsumer
+void TQMoviePrivate::changed(const TQRect& rect)
+{
+ if (!frametimer->isActive())
+ frametimer->start(0);
+ changed_area = changed_area.unite(rect);
+}
+
+void TQMoviePrivate::end()
+{
+ movie_ended = TRUE;
+}
+
+void TQMoviePrivate::preFrameDone()
+{
+ if (stepping > 0) {
+ stepping--;
+ if (!stepping) {
+ frametimer->stop();
+ emit datatqStatus( TQMovie::Paused );
+ }
+ } else {
+ waitingForFrameTick = TRUE;
+ restartTimer();
+ }
+}
+void TQMoviePrivate::frameDone()
+{
+ preFrameDone();
+ showChanges();
+ emit datatqStatus(TQMovie::EndOfFrame);
+ framenumber++;
+}
+void TQMoviePrivate::frameDone(const TQPoint& p,
+ const TQRect& rect)
+{
+ preFrameDone();
+ const TQImage& gimg = decoder->image();
+ TQPoint point = p - gimg.offset();
+ if (framenumber==0)
+ emit sizeChanged(gimg.size());
+ valid_area = valid_area.unite(TQRect(point,rect.size()));
+ updatePixmapFromImage(point,rect);
+ emit areaChanged(TQRect(point,rect.size()));
+ emit datatqStatus(TQMovie::EndOfFrame);
+ framenumber++;
+}
+
+void TQMoviePrivate::restartTimer()
+{
+ if (speed > 0) {
+ int i = frameperiod >= 0 ? frameperiod * 100/speed : 0;
+ if ( i != lasttimerinterval || !frametimer->isActive() ) {
+ lasttimerinterval = i;
+ frametimer->start( i );
+ }
+ } else {
+ frametimer->stop();
+ }
+}
+
+void TQMoviePrivate::setLooping(int nloops)
+{
+ if (loop == -1) { // Only if we don't already know how many loops!
+ if (source && source->rewindable()) {
+ source->enableRewind(TRUE);
+ loop = nloops;
+ } else {
+ // Cannot loop from this source
+ loop = -2;
+ }
+ }
+}
+
+void TQMoviePrivate::setFramePeriod(int milliseconds)
+{
+ // Animation: only show complete frame
+ frameperiod = milliseconds;
+ if (stepping<0 && frameperiod >= 0) restartTimer();
+}
+
+void TQMoviePrivate::setSize(int w, int h)
+{
+ if (mypixmap.width() != w || mypixmap.height() != h) {
+ mypixmap.resize(w, h);
+ emit sizeChanged(TQSize(w, h));
+ }
+}
+
+
+// Private as TQDataSink
+
+int TQMoviePrivate::readyToReceive()
+{
+ // Could pre-fill buffer, but more efficient to just leave the
+ // data back at the source.
+ return (waitingForFrameTick || !stepping || buf_usage || error)
+ ? 0 : buf_size;
+}
+
+void TQMoviePrivate::receive(const uchar* b, int bytecount)
+{
+ if ( bytecount ) empty = FALSE;
+
+ while (bytecount && !waitingForFrameTick && stepping != 0) {
+ int used = decoder->decode(b, bytecount);
+ if (used<=0) {
+ if ( used < 0 ) {
+ error = 1;
+ emit datatqStatus(TQMovie::UnrecognizedFormat);
+ }
+ break;
+ }
+ b+=used;
+ bytecount-=used;
+ }
+
+ // Append unused to buffer
+ while (bytecount--) {
+ buffer[buf_w] = *b++;
+ buf_w = (buf_w+1)%buf_size;
+ buf_usage++;
+ }
+}
+
+void TQMoviePrivate::eof()
+{
+ if ( !movie_ended )
+ return;
+
+ if ( empty )
+ emit datatqStatus(TQMovie::SourceEmpty);
+
+#ifdef TQT_SAVE_MOVIE_HACK
+ save_image = FALSE;
+#endif
+
+ emit datatqStatus(TQMovie::EndOfLoop);
+
+ if (loop >= 0) {
+ if (loop) {
+ loop--;
+ if (!loop) return;
+ }
+ delete decoder;
+ decoder = new TQImageDecoder(this);
+ source->rewind();
+ framenumber = 0;
+ movie_ended = FALSE;
+ } else {
+ delete decoder;
+ decoder = 0;
+ if ( buffer ) // Avoid purify complaint
+ delete [] buffer;
+ buffer = 0;
+ emit datatqStatus(TQMovie::EndOfMovie);
+#ifdef AVOID_OPEN_FDS
+ if ( source )
+ source->close();
+#endif
+ }
+}
+
+void TQMoviePrivate::pause()
+{
+ if ( stepping ) {
+ stepping = 0;
+ frametimer->stop();
+ emit datatqStatus( TQMovie::Paused );
+ }
+}
+
+void TQMoviePrivate::refresh()
+{
+ if (!decoder) {
+ frametimer->stop();
+ return;
+ }
+
+ if (frameperiod < 0 && loop == -1) {
+ // Only show changes if probably not an animation
+ showChanges();
+ }
+
+ if (!buf_usage) {
+ frametimer->stop();
+ }
+
+ waitingForFrameTick = FALSE;
+ flushBuffer();
+}
+
+///////////////// End of Private /////////////////
+
+
+
+
+
+/*!
+ Constructs a null TQMovie. The only interesting thing to do with
+ such a movie is to assign another movie to it.
+
+ \sa isNull()
+*/
+TQMovie::TQMovie()
+{
+ d = new TQMoviePrivate();
+}
+
+/*!
+ Constructs a TQMovie with an external data source. You should later
+ call pushData() to send incoming animation data to the movie.
+
+ The \a bufsize argument sets the maximum amount of data the movie
+ will transfer from the data source per event loop. The lower this
+ value, the better interleaved the movie playback will be with
+ other event processing, but the slower the overall processing will
+ be.
+
+ \sa pushData()
+*/
+TQMovie::TQMovie(int bufsize)
+{
+ d = new TQMoviePrivate(0, this, bufsize);
+}
+
+/*!
+ Returns the maximum amount of data that can currently be pushed
+ into the movie by a call to pushData(). This is affected by the
+ initial buffer size, but varies as the movie plays and data is
+ consumed.
+*/
+int TQMovie::pushSpace() const
+{
+ return d->readyToReceive();
+}
+
+/*!
+ Pushes \a length bytes from \a data into the movie. \a length must
+ be no more than the amount returned by pushSpace() since the
+ previous call to pushData().
+*/
+void TQMovie::pushData(const uchar* data, int length)
+{
+ d->receive(data,length);
+}
+
+#ifdef TQ_WS_TQWS // ##### Temporary performance experiment
+/*!
+ \internal
+*/
+void TQMovie::setDisplayWidget(TQWidget * w)
+{
+ d->display_widget=w;
+}
+#endif
+
+/*!
+ Constructs a TQMovie that reads an image sequence from the given
+ data source, \a src. The source must be allocated dynamically,
+ because TQMovie will take ownership of it and will destroy it when
+ the movie is destroyed. The movie starts playing as soon as event
+ processing continues.
+
+ The \a bufsize argument sets the maximum amount of data the movie
+ will transfer from the data source per event loop. The lower this
+ value, the better interleaved the movie playback will be with
+ other event processing, but the slower the overall processing will
+ be.
+*/
+TQMovie::TQMovie(TQDataSource* src, int bufsize)
+{
+ d = new TQMoviePrivate(src, this, bufsize);
+}
+
+/*!
+ Constructs a TQMovie that reads an image sequence from the file, \a
+ fileName.
+
+ The \a bufsize argument sets the maximum amount of data the movie
+ will transfer from the data source per event loop. The lower this
+ value, the better interleaved the movie playback will be with
+ other event processing, but the slower the overall processing will
+ be.
+*/
+TQMovie::TQMovie(const TQString &fileName, int bufsize)
+{
+ TQFile* file = new TQFile(fileName);
+ if ( !fileName.isEmpty() )
+ file->open(IO_ReadOnly);
+ d = new TQMoviePrivate(new TQIODeviceSource(TQT_TQIODEVICE(file), bufsize), this, bufsize);
+}
+
+/*!
+ Constructs a TQMovie that reads an image sequence from the byte
+ array, \a data.
+
+ The \a bufsize argument sets the maximum amount of data the movie
+ will transfer from the data source per event loop. The lower this
+ value, the better interleaved the movie playback will be with
+ other event processing, but the slower the overall processing will
+ be.
+*/
+TQMovie::TQMovie(TQByteArray data, int bufsize)
+{
+ TQBuffer* buffer = new TQBuffer(data);
+ buffer->open(IO_ReadOnly);
+ d = new TQMoviePrivate(new TQIODeviceSource(TQT_TQIODEVICE(buffer), bufsize), this, bufsize);
+}
+
+/*!
+ Constructs a movie that uses the same data as movie \a movie.
+ TQMovies use explicit sharing, so operations on the copy will
+ affect both.
+*/
+TQMovie::TQMovie(const TQMovie& movie)
+{
+ d = movie.d;
+ d->ref();
+}
+
+/*!
+ Destroys the TQMovie. If this is the last reference to the data of
+ the movie, the data is deallocated.
+*/
+TQMovie::~TQMovie()
+{
+ if (d->deref()) delete d;
+}
+
+/*!
+ Returns TRUE if the movie is null; otherwise returns FALSE.
+*/
+bool TQMovie::isNull() const
+{
+ return d->isNull();
+}
+
+/*!
+ Makes this movie use the same data as movie \a movie. TQMovies use
+ explicit sharing.
+*/
+TQMovie& TQMovie::operator=(const TQMovie& movie)
+{
+ movie.d->ref();
+ if (d->deref()) delete d;
+ d = movie.d;
+ return *this;
+}
+
+
+/*!
+ Sets the background color of the pixmap to \a c. If the background
+ color isValid(), the pixmap will never have a tqmask because the
+ background color will be used in transtqparent regions of the image.
+
+ \sa backgroundColor()
+*/
+void TQMovie::setBackgroundColor(const TQColor& c)
+{
+ d->bg = c;
+}
+
+/*!
+ Returns the background color of the movie set by
+ setBackgroundColor().
+*/
+const TQColor& TQMovie::backgroundColor() const
+{
+ return d->bg;
+}
+
+/*!
+ Returns the area of the pixmap for which pixels have been
+ generated.
+*/
+const TQRect& TQMovie::getValidRect() const
+{
+ return d->valid_area;
+}
+
+/*!
+ Returns the current frame of the movie, as a TQPixmap. It is not
+ generally useful to keep a copy of this pixmap. It is better to
+ keep a copy of the TQMovie and get the framePixmap() only when
+ needed for drawing.
+
+ \sa frameImage()
+*/
+const TQPixmap& TQMovie::framePixmap() const
+{
+ return d->mypixmap;
+}
+
+/*!
+ Returns the current frame of the movie, as a TQImage. It is not
+ generally useful to keep a copy of this image. Also note that you
+ must not call this function if the movie is finished(), since by
+ then the image will not be available.
+
+ \sa framePixmap()
+*/
+const TQImage& TQMovie::frameImage() const
+{
+ return d->decoder->image();
+}
+
+/*!
+ Returns the number of steps remaining after a call to step(). If
+ the movie is paused, steps() returns 0. If it's running normally
+ or is finished, steps() returns a negative number.
+*/
+int TQMovie::steps() const
+{
+ return d->stepping;
+}
+
+/*!
+ Returns the number of times EndOfFrame has been emitted since the
+ start of the current loop of the movie. Thus, before any
+ EndOfFrame has been emitted the value will be 0; within Q_SLOTS
+ processing the first signal, frameNumber() will be 1, and so on.
+*/
+int TQMovie::frameNumber() const { return d->framenumber; }
+
+/*!
+ Returns TRUE if the image is paused; otherwise returns FALSE.
+*/
+bool TQMovie::paused() const
+{
+ return d->stepping == 0;
+}
+
+/*!
+ Returns TRUE if the image is no longer playing: this happens when
+ all loops of all frames are complete; otherwise returns FALSE.
+*/
+bool TQMovie::finished() const
+{
+ return !d->decoder;
+}
+
+/*!
+ Returns TRUE if the image is not single-stepping, not paused, and
+ not finished; otherwise returns FALSE.
+*/
+bool TQMovie::running() const
+{
+ return d->stepping<0 && d->decoder;
+}
+
+/*!
+ Pauses the progress of the animation.
+
+ \sa unpause()
+*/
+void TQMovie::pause()
+{
+ d->pause();
+}
+
+/*!
+ Unpauses the progress of the animation.
+
+ \sa pause()
+*/
+void TQMovie::unpause()
+{
+ if ( d->stepping >= 0 ) {
+ if (d->isNull())
+ return;
+ d->stepping = -1;
+ d->restartTimer();
+ }
+}
+
+/*!
+ \overload
+
+ Steps forward, showing \a steps frames, and then pauses.
+*/
+void TQMovie::step(int steps)
+{
+ if (d->isNull())
+ return;
+ d->stepping = steps;
+ d->frametimer->start(0);
+ d->waitingForFrameTick = FALSE; // Full speed ahead!
+}
+
+/*!
+ Steps forward 1 frame and then pauses.
+*/
+void TQMovie::step()
+{
+ step(1);
+}
+
+/*!
+ Rewinds the movie to the beginning. If the movie has not been
+ paused, it begins playing again.
+*/
+void TQMovie::restart()
+{
+ if (d->isNull())
+ return;
+ if (d->source->rewindable()) {
+ d->source->enableRewind(TRUE);
+ d->source->rewind();
+ int s = d->stepping;
+ d->init(TRUE);
+ if ( s>0 )
+ step(s);
+ else if ( s==0 )
+ pause();
+ }
+}
+
+/*!
+ Returns the movie's play speed as a percentage. The default is 100
+ percent.
+
+ \sa setSpeed()
+*/
+int TQMovie::speed() const
+{
+ return d->speed;
+}
+
+/*!
+ Sets the movie's play speed as a percentage, to \a percent. This
+ is a percentage of the speed dictated by the input data format.
+ The default is 100 percent.
+*/
+void TQMovie::setSpeed(int percent)
+{
+ int oldspeed = d->speed;
+ if ( oldspeed != percent && percent >= 0 ) {
+ d->speed = percent;
+ // Restart timer only if really needed
+ if (d->stepping < 0) {
+ if ( !percent || !oldspeed // To or from zero
+ || oldspeed*4 / percent > 4 // More than 20% slower
+ || percent*4 / oldspeed > 4 // More than 20% faster
+ )
+ d->restartTimer();
+ }
+ }
+}
+
+/*!
+ Connects the \a{receiver}'s \a member of type \c{void member(const
+ TQSize&)} so that it is signalled when the movie changes size.
+
+ Note that due to the explicit sharing of TQMovie objects, these
+ connections persist until they are explicitly disconnected with
+ disconnectResize() or until \e every shared copy of the movie is
+ deleted.
+*/
+void TQMovie::connectResize(TQT_BASE_OBJECT_NAME* receiver, const char *member)
+{
+ TQObject::connect(d, TQT_SIGNAL(sizeChanged(const TQSize&)), TQT_TQOBJECT(receiver), member);
+}
+
+/*!
+ Disconnects the \a{receiver}'s \a member (or all members if \a
+ member is zero) that were previously connected by connectResize().
+*/
+void TQMovie::disconnectResize(TQT_BASE_OBJECT_NAME* receiver, const char *member)
+{
+ TQObject::disconnect(d, TQT_SIGNAL(sizeChanged(const TQSize&)), TQT_TQOBJECT(receiver), member);
+}
+
+/*!
+ Connects the \a{receiver}'s \a member of type \c{void member(const
+ TQRect&)} so that it is signalled when an area of the framePixmap()
+ has changed since the previous frame.
+
+ Note that due to the explicit sharing of TQMovie objects, these
+ connections persist until they are explicitly disconnected with
+ disconnectUpdate() or until \e every shared copy of the movie is
+ deleted.
+*/
+void TQMovie::connectUpdate(TQT_BASE_OBJECT_NAME* receiver, const char *member)
+{
+ TQObject::connect(d, TQT_SIGNAL(areaChanged(const TQRect&)), TQT_TQOBJECT(receiver), member);
+}
+
+/*!
+ Disconnects the \a{receiver}'s \a member (or all members if \q
+ member is zero) that were previously connected by connectUpdate().
+*/
+void TQMovie::disconnectUpdate(TQT_BASE_OBJECT_NAME* receiver, const char *member)
+{
+ TQObject::disconnect(d, TQT_SIGNAL(areaChanged(const TQRect&)), TQT_TQOBJECT(receiver), member);
+}
+
+/*!
+ Connects the \a{receiver}'s \a member, of type \c{void
+ member(int)} so that it is signalled when the movie changes
+ status. The status codes are negative for errors and positive for
+ information.
+
+ \table
+ \header \i tqStatus Code \i Meaning
+ \row \i TQMovie::SourceEmpty
+ \i signalled if the input cannot be read.
+ \row \i TQMovie::UnrecognizedFormat
+ \i signalled if the input data is unrecognized.
+ \row \i TQMovie::Paused
+ \i signalled when the movie is paused by a call to paused()
+ or by after \link step() stepping \endlink pauses.
+ \row \i TQMovie::EndOfFrame
+ \i signalled at end-of-frame after any update and Paused Q_SIGNALS.
+ \row \i TQMovie::EndOfLoop
+ \i signalled at end-of-loop, after any update Q_SIGNALS,
+ EndOfFrame - but before EndOfMovie.
+ \row \i TQMovie::EndOfMovie
+ \i signalled when the movie completes and is not about to loop.
+ \endtable
+
+ More status messages may be added in the future, so a general test
+ for errors would test for negative.
+
+ Note that due to the explicit sharing of TQMovie objects, these
+ connections persist until they are explicitly disconnected with
+ disconnectqStatus() or until \e every shared copy of the movie is
+ deleted.
+*/
+void TQMovie::connectqStatus(TQObject* receiver, const char *member)
+{
+ TQObject::connect(d, TQT_SIGNAL(datatqStatus(int)), receiver, member);
+}
+
+/*!
+ Disconnects the \a{receiver}'s \a member (or all members if \a
+ member is zero) that were previously connected by connectqStatus().
+*/
+void TQMovie::disconnectqStatus(TQObject* receiver, const char *member)
+{
+ TQObject::disconnect(d, TQT_SIGNAL(datatqStatus(int)), receiver, member);
+}
+
+
+#include "tqmovie.tqmoc"
+
+#endif // TQT_NO_MOVIE
diff --git a/tqtinterface/qt4/src/kernel/tqmovie.h b/tqtinterface/qt4/src/kernel/tqmovie.h
new file mode 100644
index 0000000..1c63a5e
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqmovie.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Definition of movie classes
+**
+** Created : 970617
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMOVIE_H
+#define TQMOVIE_H
+
+#ifndef TQT_H
+#include "tqpixmap.h" // ### remove or keep for users' convenience?
+#endif // TQT_H
+
+#ifndef TQT_NO_MOVIE
+
+class TQDataSource;
+class TQObject;
+class TQMoviePrivate;
+
+class TQ_EXPORT TQMovie {
+public:
+ TQMovie();
+ TQMovie(int bufsize);
+ TQMovie(TQDataSource*, int bufsize=1024);
+ TQMovie(const TQString &fileName, int bufsize=1024);
+ TQMovie(TQByteArray data, int bufsize=1024);
+ TQMovie(const TQMovie&);
+ ~TQMovie();
+
+ TQMovie& operator=(const TQMovie&);
+
+ int pushSpace() const;
+ void pushData(const uchar* data, int length);
+
+ const TQColor& backgroundColor() const;
+ void setBackgroundColor(const TQColor&);
+
+ const TQRect& getValidRect() const;
+ const TQPixmap& framePixmap() const;
+ const TQImage& frameImage() const;
+
+ bool isNull() const;
+
+ int frameNumber() const;
+ int steps() const;
+ bool paused() const;
+ bool finished() const;
+ bool running() const;
+
+ void unpause();
+ void pause();
+ void step();
+ void step(int);
+ void restart();
+
+ int speed() const;
+ void setSpeed(int);
+
+ void connectResize(TQT_BASE_OBJECT_NAME* receiver, const char *member);
+ void disconnectResize(TQT_BASE_OBJECT_NAME* receiver, const char *member=0);
+
+ void connectUpdate(TQT_BASE_OBJECT_NAME* receiver, const char *member);
+ void disconnectUpdate(TQT_BASE_OBJECT_NAME* receiver, const char *member=0);
+
+#ifdef TQ_WS_TQWS
+ // Temporary hack
+ void setDisplayWidget(TQWidget * w);
+#endif
+
+ enum tqStatus { SourceEmpty=-2,
+ UnrecognizedFormat=-1,
+ Paused=1,
+ EndOfFrame=2,
+ EndOfLoop=3,
+ EndOfMovie=4,
+ SpeedChanged=5 };
+ void connectqStatus(TQObject* receiver, const char *member);
+ void disconnectqStatus(TQObject* receiver, const char *member=0);
+
+ inline void connectStatus(TQObject* receiver, const char *member) { connectqStatus(receiver, member); }
+ inline void disconnectStatus(TQObject* receiver, const char *member=0) { disconnectqStatus(receiver, member); }
+
+private:
+ TQMoviePrivate *d;
+};
+
+#endif // TQT_NO_MOVIE
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqnamespace.h b/tqtinterface/qt4/src/kernel/tqnamespace.h
new file mode 100644
index 0000000..b158936
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqnamespace.h
@@ -0,0 +1,1159 @@
+/****************************************************************************
+**
+** Definition of TQt namespace (as class for compiler compatibility)
+**
+** Created : 980927
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQNAMESPACE_H
+#define TQNAMESPACE_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#include "tqtglobalsettings.h"
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+#include <Qt/qglobal.h>
+#include <Qt/qnamespace.h>
+#include "tqtenuminheritance.h"
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+enum AspectRatioMode {
+ IgnoreAspectRatio,
+ KeepAspectRatio,
+ KeepAspectRatioByExpanding,
+ ScaleFree = IgnoreAspectRatio,
+ ScaleMin = KeepAspectRatio,
+ ScaleMax = KeepAspectRatioByExpanding
+};
+typedef AspectRatioMode ScaleMode;
+
+enum CursorShape {
+ ArrowCursor,
+ UpArrowCursor,
+ CrossCursor,
+ WaitCursor,
+ IBeamCursor,
+ SizeVerCursor,
+ SizeHorCursor,
+ SizeBDiagCursor,
+ SizeFDiagCursor,
+ SizeAllCursor,
+ BlankCursor,
+ SplitVCursor,
+ SplitHCursor,
+ PointingHandCursor,
+ ForbiddenCursor,
+ WhatsThisCursor,
+ BusyCursor,
+ OpenHandCursor,
+ ClosedHandCursor,
+ DragCopyCursor,
+ DragMoveCursor,
+ DragLinkCursor,
+ LastCursor = DragLinkCursor,
+ BitmapCursor = 24,
+ CustomCursor = 25
+};
+
+#endif
+
+class TQColor;
+class TQCursor;
+
+class TQ_EXPORT TQt {
+public:
+ TQT_STATIC_CONST TQColor & color0;
+ TQT_STATIC_CONST TQColor & color1;
+ TQT_STATIC_CONST TQColor & black;
+ TQT_STATIC_CONST TQColor & white;
+ TQT_STATIC_CONST TQColor & darkGray;
+ TQT_STATIC_CONST TQColor & gray;
+ TQT_STATIC_CONST TQColor & lightGray;
+ TQT_STATIC_CONST TQColor & red;
+ TQT_STATIC_CONST TQColor & green;
+ TQT_STATIC_CONST TQColor & blue;
+ TQT_STATIC_CONST TQColor & cyan;
+ TQT_STATIC_CONST TQColor & magenta;
+ TQT_STATIC_CONST TQColor & yellow;
+ TQT_STATIC_CONST TQColor & darkRed;
+ TQT_STATIC_CONST TQColor & darkGreen;
+ TQT_STATIC_CONST TQColor & darkBlue;
+ TQT_STATIC_CONST TQColor & darkCyan;
+ TQT_STATIC_CONST TQColor & darkMagenta;
+ TQT_STATIC_CONST TQColor & darkYellow;
+
+#ifdef USE_QT4
+
+ enum ButtonState_enum {
+ ShiftButton = ((int)Qt::ShiftModifier),
+ ControlButton = ((int)Qt::ControlModifier),
+ AltButton = ((int)Qt::AltModifier),
+ MetaButton = ((int)Qt::MetaModifier),
+ Keypad = ((int)Qt::KeypadModifier),
+ KeyButtonMask = ((int)Qt::KeyboardModifierMask)
+ };
+ typedef int ButtonState;
+
+#else // USE_QT4
+
+ // documented in qevent.cpp
+ enum ButtonState { // mouse/keyboard state values
+ NoButton = 0x0000,
+ LeftButton = 0x0001,
+ RightButton = 0x0002,
+ MidButton = 0x0004,
+ MouseButtonMask = 0x0007,
+ ShiftButton = 0x0100,
+ ControlButton = 0x0200,
+ AltButton = 0x0400,
+ MetaButton = 0x0800,
+ KeyButtonMask = 0x0f00,
+ Keypad = 0x4000
+ };
+
+#endif // USE_QT4
+
+
+#ifdef USE_QT4
+
+typedef Qt::Orientation Orientation;
+
+#else // USE_QT4
+
+ // documented in qobject.cpp
+ // ideally would start at 1, as in TQSizePolicy, but that breaks other things
+ enum Orientation {
+ Horizontal = 0,
+ Vertical
+ };
+
+#endif // USE_QT4
+
+ // documented in qlistview.cpp
+ enum SortOrder {
+ Ascending,
+ Descending
+ };
+
+ // Text formatting flags for TQPainter::drawText and TQLabel
+ // the following four enums can be combined to one integer which
+ // is passed as textflag to drawText and qt_format_text.
+
+ // documented in qpainter.cpp
+
+#ifdef USE_QT4
+ enum AlignmentFlags {
+ AlignAuto = ((int)Qt::AlignLeft), // text tqalignment
+ AlignLeft = ((int)Qt::AlignLeft),
+ AlignRight = ((int)Qt::AlignRight),
+ AlignHCenter = ((int)Qt::AlignHCenter),
+ AlignJustify = ((int)Qt::AlignJustify),
+ AlignAbsolute = ((int)Qt::AlignAbsolute),
+ AlignHorizontal_Mask = AlignLeft | AlignRight | AlignHCenter | AlignJustify | AlignAbsolute,
+ AlignTop = ((int)Qt::AlignTop),
+ AlignBottom = ((int)Qt::AlignBottom),
+ AlignVCenter = ((int)Qt::AlignVCenter),
+ AlignVertical_Mask = AlignTop | AlignBottom | AlignVCenter,
+ AlignCenter = AlignVCenter | AlignHCenter
+ };
+#else // USE_QT4
+ enum AlignmentFlags {
+ AlignAuto = 0x0000, // text tqalignment
+ AlignLeft = 0x0001,
+ AlignRight = 0x0002,
+ AlignHCenter = 0x0004,
+ AlignJustify = 0x0008,
+ AlignHorizontal_Mask = AlignLeft | AlignRight | AlignHCenter | AlignJustify,
+ AlignTop = 0x0010,
+ AlignBottom = 0x0020,
+ AlignVCenter = 0x0040,
+ AlignVertical_Mask = AlignTop | AlignBottom | AlignVCenter,
+ AlignCenter = AlignVCenter | AlignHCenter
+ };
+#endif // USE_QT4
+
+#ifdef USE_QT4
+ enum TextFlags {
+ SingleLine = Qt::TextSingleLine,
+ DontClip = Qt::TextDontClip,
+ ExpandTabs = Qt::TextExpandTabs,
+ ShowPrefix = Qt::TextShowMnemonic,
+ WordBreak = Qt::TextWordWrap,
+ BreakAnywhere = Qt::TextWrapAnywhere,
+#ifndef TQ_TQDOC
+ DontPrint = Qt::TextDontPrint,
+ Underline = 0x01000000,
+ Overline = 0x02000000,
+ StrikeOut = 0x04000000,
+ IncludeTrailingSpaces = Qt::TextIncludeTrailingSpaces,
+#endif
+ NoAccel = 0x4000
+ };
+#else // USE_QT4
+ // documented in qpainter.cpp
+ enum TextFlags {
+ SingleLine = 0x0080, // misc. flags
+ DontClip = 0x0100,
+ ExpandTabs = 0x0200,
+ ShowPrefix = 0x0400,
+ WordBreak = 0x0800,
+ BreakAnywhere = 0x1000,
+#ifndef TQ_TQDOC
+ DontPrint = 0x2000,
+ Underline = 0x01000000,
+ Overline = 0x02000000,
+ StrikeOut = 0x04000000,
+ IncludeTrailingSpaces = 0x08000000,
+#endif
+ NoAccel = 0x4000
+ };
+#endif // USE_QT4
+
+#ifdef USE_QT4
+ typedef Qt::WindowStates WState;
+#else // USE_QT4
+ // Widget flags; documented in qwidget.cpp
+ typedef uint WState;
+#endif // USE_QT4
+
+ // TQWidget state flags (internal, barely documented in qwidget.cpp)
+ enum WidgetState {
+ WState_Created = 0x00000001,
+ WState_Disabled = 0x00000002,
+ WState_Visible = 0x00000004,
+ WState_ForceHide = 0x00000008,
+ WState_OwnCursor = 0x00000010,
+ WState_MouseTracking = 0x00000020,
+ WState_CompressKeys = 0x00000040,
+ WState_BlockUpdates = 0x00000080,
+ WState_InPaintEvent = 0x00000100,
+ WState_Reparented = 0x00000200,
+ WState_ConfigPending = 0x00000400,
+ WState_Resized = 0x00000800,
+ WState_AutoMask = 0x00001000,
+ WState_Polished = 0x00002000,
+ WState_DND = 0x00004000,
+ WState_Reserved0 = 0x00008000,
+ WState_FullScreen = 0x00010000,
+ WState_OwnSizePolicy = 0x00020000,
+ WState_CreatedHidden = 0x00040000,
+ WState_Maximized = 0x00080000,
+ WState_Minimized = 0x00100000,
+ WState_ForceDisabled = 0x00200000,
+ WState_Exposed = 0x00400000,
+ WState_HasMouse = 0x00800000
+ };
+
+// #ifdef USE_QT4
+//
+// typedef Qt::WindowFlags WindowFlags;
+//
+// #else // USE_QT4
+//
+// // Widget flags2; documented in qwidget.cpp
+// typedef uint WFlags;
+//
+// #endif // USE_QT4
+
+// typedef unsigned long long WFlags;
+
+#ifdef USE_QT4
+
+ // documented in qwidget.cpp
+ enum WidgetFlags {
+ WType_TopLevel = ((int)Qt::Window), // widget type flags
+ WType_Dialog = 0x00000002 | WType_TopLevel,
+ WType_Popup = 0x00000008 | WType_TopLevel,
+ WType_Desktop = 0x00000010 | WType_TopLevel,
+ WType_Mask = 0x000000ff,
+
+ WStyle_Customize = 0x00000000, // window style flags
+ WStyle_NormalBorder = 0x00000000,
+ WStyle_DialogBorder = ((int)Qt::MSWindowsFixedSizeDialogHint), // MS-Windows only
+ WStyle_NoBorder = ((int)Qt::FramelessWindowHint),
+ WStyle_Title = ((int)Qt::WindowTitleHint),
+ WStyle_SysMenu = ((int)Qt::WindowSystemMenuHint),
+ WStyle_Minimize = ((int)Qt::WindowMinimizeButtonHint),
+ WStyle_Maximize = ((int)Qt::WindowMaximizeButtonHint),
+ WStyle_MinMax = WStyle_Minimize | WStyle_Maximize,
+// WStyle_Tool = ((int)Qt::Tool), // This is NOT the Qt4 equivalent...using Qt::Tool will cause undocked toolbar handles to stay in the top left corner of the screen
+ WStyle_Tool = ((int)0), // [FIXME] Huh? Why do the toolbars work in Qt4 when Qt::Tool is not set?!?!? [FIXME] [UNDEFINED BEHAVIOUR]
+ WStyle_StaysOnTop = ((int)Qt::WindowStaysOnTopHint),
+ WStyle_ContextHelp = ((int)Qt::WindowContextHelpButtonHint),
+// WStyle_Reserved = 0x00008000,
+ WStyle_Reserved = 0x00000000,
+ WStyle_Mask = 0x0000fff0,
+
+ WDestructiveClose = 0x00100000, // misc flags
+ WPaintDesktop = 0x00000000,
+ WPaintClever = 0x00000000,
+ WStaticContents = 0x00200000,
+
+ WX11BypassWM = ((int)Qt::X11BypassWindowManagerHint),
+ WWinOwnDC = ((int)Qt::MSWindowsOwnDC),
+ WMacNoSheet = 0x00000000,
+ WMacDrawer = ((int)Qt::Drawer),
+
+ WGroupLeader = 0x00400000,
+ WShowModal = 0x00800000,
+ WNoMousePropagation = 0x01000000,
+ WSubWindow = ((int)Qt::SubWindow),
+
+ WStyle_Splash = ((int)Qt::SplashScreen),
+
+ // TQt specific flags
+ WNoAutoErase = 0x0000000100000000ULL,
+ WRepaintNoErase = WNoAutoErase, // OBSOLETE
+ WResizeNoErase = WNoAutoErase, // OBSOLETE
+ WMouseNoMask = 0x0000000200000000ULL,
+ WPaintOnScreen = 0x0000000400000000ULL, // NOTE: This disables Qt4 composition (i.e. transparent windows) to allow fast direct access to the X11 screen. Use with caution!
+ WPaintUnclipped = 0x0000000800000000ULL, // NOTE: This implicitly enables WPaintOnScreen, which disables composition
+ WTQtFlagMask = 0xffffffff00000000ULL
+#ifndef TQT_NO_COMPAT
+ ,
+ WNorthWestGravity = WStaticContents,
+ WType_Modal = WType_Dialog | WShowModal,
+ WStyle_Dialog = WType_Dialog,
+ WStyle_NoBorderEx = WStyle_NoBorder
+#endif
+ };
+
+ typedef unsigned long long WFlags;
+
+#else // USE_QT4
+
+ // documented in qwidget.cpp
+ enum WidgetFlags {
+ WType_TopLevel = 0x00000001, // widget type flags
+ WType_Dialog = 0x00000002,
+ WType_Popup = 0x00000004,
+ WType_Desktop = 0x00000008,
+ WType_Mask = 0x0000000f,
+
+ WStyle_Customize = 0x00000010, // window style flags
+ WStyle_NormalBorder = 0x00000020,
+ WStyle_DialogBorder = 0x00000040, // MS-Windows only
+ WStyle_NoBorder = 0x00002000,
+ WStyle_Title = 0x00000080,
+ WStyle_SysMenu = 0x00000100,
+ WStyle_Minimize = 0x00000200,
+ WStyle_Maximize = 0x00000400,
+ WStyle_MinMax = WStyle_Minimize | WStyle_Maximize,
+ WStyle_Tool = 0x00000800,
+ WStyle_StaysOnTop = 0x00001000,
+ WStyle_ContextHelp = 0x00004000,
+ WStyle_Reserved = 0x00008000,
+ WStyle_Mask = 0x0000fff0,
+
+ WDestructiveClose = 0x00010000, // misc flags
+ WPaintDesktop = 0x00020000,
+ WPaintUnclipped = 0x00040000,
+ WPaintClever = 0x00080000,
+ WResizeNoErase = 0x00100000, // OBSOLETE
+ WMouseNoMask = 0x00200000,
+ WStaticContents = 0x00400000,
+ WRepaintNoErase = 0x00800000, // OBSOLETE
+#if defined(TQ_WS_X11)
+ WX11BypassWM = 0x01000000,
+ WWinOwnDC = 0x00000000,
+ WMacNoSheet = 0x00000000,
+ WMacDrawer = 0x00000000,
+#elif defined(TQ_WS_MAC)
+ WX11BypassWM = 0x00000000,
+ WWinOwnDC = 0x00000000,
+ WMacNoSheet = 0x01000000,
+ WMacDrawer = 0x20000000,
+#else
+ WX11BypassWM = 0x00000000,
+ WWinOwnDC = 0x01000000,
+ WMacNoSheet = 0x00000000,
+ WMacDrawer = 0x00000000,
+#endif
+ WGroupLeader = 0x02000000,
+ WShowModal = 0x04000000,
+ WNoMousePropagation = 0x08000000,
+ WSubWindow = 0x10000000,
+#if defined(TQ_WS_X11)
+ WStyle_Splash = 0x20000000,
+#else
+ WStyle_Splash = WStyle_NoBorder | WMacNoSheet | WStyle_Tool | WWinOwnDC,
+#endif
+ WNoAutoErase = WRepaintNoErase | WResizeNoErase
+#ifndef TQT_NO_COMPAT
+ ,
+ WNorthWestGravity = WStaticContents,
+ WType_Modal = WType_Dialog | WShowModal,
+ WStyle_Dialog = WType_Dialog,
+ WStyle_NoBorderEx = WStyle_NoBorder
+#endif
+ };
+
+#endif // USE_QT4
+
+ enum WindowState {
+ WindowNoState = 0x00000000,
+ WindowMinimized = 0x00000001,
+ WindowMaximized = 0x00000002,
+ WindowFullScreen = 0x00000004,
+ WindowActive = 0x00000008
+ };
+
+
+ // Image conversion flags. The unusual ordering is caused by
+ // compatibility and default requirements.
+ // Documented in qimage.cpp
+
+ enum ImageConversionFlags {
+ ColorMode_Mask = 0x00000003,
+ AutoColor = 0x00000000,
+ ColorOnly = 0x00000003,
+ MonoOnly = 0x00000002,
+ // Reserved = 0x00000001,
+
+ AlphaDither_Mask = 0x0000000c,
+ ThresholdAlphaDither = 0x00000000,
+ OrderedAlphaDither = 0x00000004,
+ DiffuseAlphaDither = 0x00000008,
+ NoAlpha = 0x0000000c, // Not supported
+
+ Dither_Mask = 0x00000030,
+ DiffuseDither = 0x00000000,
+ OrderedDither = 0x00000010,
+ ThresholdDither = 0x00000020,
+ // ReservedDither= 0x00000030,
+
+ DitherMode_Mask = 0x000000c0,
+ AutoDither = 0x00000000,
+ PreferDither = 0x00000040,
+ AvoidDither = 0x00000080
+ };
+
+ // documented in qpainter.cpp
+ enum BGMode { // background mode
+ TransparentMode,
+ OpaqueMode
+ };
+
+#ifdef USE_QT4
+
+ enum PaintUnit { // paint unit
+ PixelUnit,
+ LoMetricUnit, // obsolete
+ HiMetricUnit, // obsolete
+ LoEnglishUnit, // obsolete
+ HiEnglishUnit, // obsolete
+ TwipsUnit // obsolete
+ };
+
+ enum GUIStyle {
+ MacStyle,
+ WindowsStyle,
+ Win3Style,
+ PMStyle,
+ MotifStyle
+ };
+
+#else // USE_QT4
+
+#ifndef TQT_NO_COMPAT
+ // documented in qpainter.cpp
+ enum PaintUnit { // paint unit
+ PixelUnit,
+ LoMetricUnit, // OBSOLETE
+ HiMetricUnit, // OBSOLETE
+ LoEnglishUnit, // OBSOLETE
+ HiEnglishUnit, // OBSOLETE
+ TwipsUnit // OBSOLETE
+ };
+#endif
+
+ // documented in qstyle.cpp
+#ifdef TQT_NO_COMPAT
+ enum GUIStyle {
+ WindowsStyle = 1, // ### TQt 4.0: either remove the obsolete enums or clean up compat vs.
+ MotifStyle = 4 // ### TQT_NO_COMPAT by reordering or combination into one enum.
+ };
+#else
+ enum GUIStyle {
+ MacStyle, // OBSOLETE
+ WindowsStyle,
+ Win3Style, // OBSOLETE
+ PMStyle, // OBSOLETE
+ MotifStyle
+ };
+#endif
+
+#endif // USE_QT4
+
+ // documented in qkeysequence.cpp
+ enum SequenceMatch {
+ NoMatch,
+ PartialMatch,
+ Identical
+ };
+
+#ifdef USE_QT4
+ //shorter names for shortcuts
+ enum Modifier {
+ META = Qt::MetaModifier,
+ SHIFT = Qt::ShiftModifier,
+ CTRL = Qt::ControlModifier,
+ ALT = Qt::AltModifier,
+ MODIFIER_MASK = Qt::KeyboardModifierMask,
+ UNICODE_ACCEL = 0x00000000,
+
+ ASCII_ACCEL = UNICODE_ACCEL // 1.x compat
+ };
+#else // USE_QT4
+ // documented in qevent.cpp
+ enum Modifier { // accelerator modifiers
+ META = 0x00100000,
+ SHIFT = 0x00200000,
+ CTRL = 0x00400000,
+ ALT = 0x00800000,
+ MODIFIER_MASK = 0x00f00000,
+ UNICODE_ACCEL = 0x10000000,
+
+ ASCII_ACCEL = UNICODE_ACCEL // 1.x compat
+ };
+#endif // USE_QT4
+
+ // documented in tqevent.cpp
+ enum Key {
+ Key_Escape = (int)Qt::Key_Escape, // misc keys
+ Key_Tab = (int)Qt::Key_Tab,
+ Key_Backtab = (int)Qt::Key_Backtab, Key_BackTab = Key_Backtab,
+ Key_Backspace = (int)Qt::Key_Backspace, Key_BackSpace = Key_Backspace,
+ Key_Return = (int)Qt::Key_Return,
+ Key_Enter = (int)Qt::Key_Enter,
+ Key_Insert = (int)Qt::Key_Insert,
+ Key_Delete = (int)Qt::Key_Delete,
+ Key_Pause = (int)Qt::Key_Pause,
+ Key_Print = (int)Qt::Key_Print,
+ Key_SysReq = (int)Qt::Key_SysReq,
+ Key_Clear = (int)Qt::Key_Clear,
+ Key_Home = (int)Qt::Key_Home, // cursor movement
+ Key_End = (int)Qt::Key_End,
+ Key_Left = (int)Qt::Key_Left,
+ Key_Up = (int)Qt::Key_Up,
+ Key_Right = (int)Qt::Key_Right,
+ Key_Down = (int)Qt::Key_Down,
+ Key_Prior = (int)Qt::Key_PageUp, Key_PageUp = Key_Prior,
+ Key_Next = (int)Qt::Key_PageDown, Key_PageDown = Key_Next,
+ Key_Shift = (int)Qt::Key_Shift, // modifiers
+ Key_Control = (int)Qt::Key_Control,
+ Key_Meta = (int)Qt::Key_Meta,
+ Key_Alt = (int)Qt::Key_Alt,
+ Key_CapsLock = (int)Qt::Key_CapsLock,
+ Key_NumLock = (int)Qt::Key_NumLock,
+ Key_ScrollLock = (int)Qt::Key_ScrollLock,
+ Key_F1 = (int)Qt::Key_F1, // function keys
+ Key_F2 = (int)Qt::Key_F2,
+ Key_F3 = (int)Qt::Key_F3,
+ Key_F4 = (int)Qt::Key_F4,
+ Key_F5 = (int)Qt::Key_F5,
+ Key_F6 = (int)Qt::Key_F6,
+ Key_F7 = (int)Qt::Key_F7,
+ Key_F8 = (int)Qt::Key_F8,
+ Key_F9 = (int)Qt::Key_F9,
+ Key_F10 = (int)Qt::Key_F10,
+ Key_F11 = (int)Qt::Key_F11,
+ Key_F12 = (int)Qt::Key_F12,
+ Key_F13 = (int)Qt::Key_F13,
+ Key_F14 = (int)Qt::Key_F14,
+ Key_F15 = (int)Qt::Key_F15,
+ Key_F16 = (int)Qt::Key_F16,
+ Key_F17 = (int)Qt::Key_F17,
+ Key_F18 = (int)Qt::Key_F18,
+ Key_F19 = (int)Qt::Key_F19,
+ Key_F20 = (int)Qt::Key_F20,
+ Key_F21 = (int)Qt::Key_F21,
+ Key_F22 = (int)Qt::Key_F22,
+ Key_F23 = (int)Qt::Key_F23,
+ Key_F24 = (int)Qt::Key_F24,
+ Key_F25 = (int)Qt::Key_F25, // F25 .. F35 only on X11
+ Key_F26 = (int)Qt::Key_F26,
+ Key_F27 = (int)Qt::Key_F27,
+ Key_F28 = (int)Qt::Key_F28,
+ Key_F29 = (int)Qt::Key_F29,
+ Key_F30 = (int)Qt::Key_F30,
+ Key_F31 = (int)Qt::Key_F31,
+ Key_F32 = (int)Qt::Key_F32,
+ Key_F33 = (int)Qt::Key_F33,
+ Key_F34 = (int)Qt::Key_F34,
+ Key_F35 = (int)Qt::Key_F35,
+ Key_Super_L = (int)Qt::Key_Super_L, // extra keys
+ Key_Super_R = (int)Qt::Key_Super_R,
+ Key_Menu = (int)Qt::Key_Menu,
+ Key_Hyper_L = (int)Qt::Key_Hyper_L,
+ Key_Hyper_R = (int)Qt::Key_Hyper_R,
+ Key_Help = (int)Qt::Key_Help,
+ Key_Direction_L = (int)Qt::Key_Direction_L,
+ Key_Direction_R = (int)Qt::Key_Direction_R,
+ Key_Space = (int)Qt::Key_Space, // 7 bit printable ASCII
+ Key_Any = Key_Space,
+ Key_Exclam = (int)Qt::Key_Exclam,
+ Key_QuoteDbl = (int)Qt::Key_QuoteDbl,
+ Key_NumberSign = (int)Qt::Key_NumberSign,
+ Key_Dollar = (int)Qt::Key_Dollar,
+ Key_Percent = (int)Qt::Key_Percent,
+ Key_Ampersand = (int)Qt::Key_Ampersand,
+ Key_Apostrophe = (int)Qt::Key_Apostrophe,
+ Key_ParenLeft = (int)Qt::Key_ParenLeft,
+ Key_ParenRight = (int)Qt::Key_ParenRight,
+ Key_Asterisk = (int)Qt::Key_Asterisk,
+ Key_Plus = (int)Qt::Key_Plus,
+ Key_Comma = (int)Qt::Key_Comma,
+ Key_Minus = (int)Qt::Key_Minus,
+ Key_Period = (int)Qt::Key_Period,
+ Key_Slash = (int)Qt::Key_Slash,
+ Key_0 = (int)Qt::Key_0,
+ Key_1 = (int)Qt::Key_1,
+ Key_2 = (int)Qt::Key_2,
+ Key_3 = (int)Qt::Key_3,
+ Key_4 = (int)Qt::Key_4,
+ Key_5 = (int)Qt::Key_5,
+ Key_6 = (int)Qt::Key_6,
+ Key_7 = (int)Qt::Key_7,
+ Key_8 = (int)Qt::Key_8,
+ Key_9 = (int)Qt::Key_9,
+ Key_Colon = (int)Qt::Key_Colon,
+ Key_Semicolon = (int)Qt::Key_Semicolon,
+ Key_Less = (int)Qt::Key_Less,
+ Key_Equal = (int)Qt::Key_Equal,
+ Key_Greater = (int)Qt::Key_Greater,
+ Key_Question = (int)Qt::Key_Question,
+ Key_At = (int)Qt::Key_At,
+ Key_A = (int)Qt::Key_A,
+ Key_B = (int)Qt::Key_B,
+ Key_C = (int)Qt::Key_C,
+ Key_D = (int)Qt::Key_D,
+ Key_E = (int)Qt::Key_E,
+ Key_F = (int)Qt::Key_F,
+ Key_G = (int)Qt::Key_G,
+ Key_H = (int)Qt::Key_H,
+ Key_I = (int)Qt::Key_I,
+ Key_J = (int)Qt::Key_J,
+ Key_K = (int)Qt::Key_K,
+ Key_L = (int)Qt::Key_L,
+ Key_M = (int)Qt::Key_M,
+ Key_N = (int)Qt::Key_N,
+ Key_O = (int)Qt::Key_O,
+ Key_P = (int)Qt::Key_P,
+ Key_Q = (int)Qt::Key_Q,
+ Key_R = (int)Qt::Key_R,
+ Key_S = (int)Qt::Key_S,
+ Key_T = (int)Qt::Key_T,
+ Key_U = (int)Qt::Key_U,
+ Key_V = (int)Qt::Key_V,
+ Key_W = (int)Qt::Key_W,
+ Key_X = (int)Qt::Key_X,
+ Key_Y = (int)Qt::Key_Y,
+ Key_Z = (int)Qt::Key_Z,
+ Key_BracketLeft = (int)Qt::Key_BracketLeft,
+ Key_Backslash = (int)Qt::Key_Backslash,
+ Key_BracketRight = (int)Qt::Key_BracketRight,
+ Key_AsciiCircum = (int)Qt::Key_AsciiCircum,
+ Key_Underscore = (int)Qt::Key_Underscore,
+ Key_QuoteLeft = (int)Qt::Key_QuoteLeft,
+ Key_BraceLeft = (int)Qt::Key_BraceLeft,
+ Key_Bar = (int)Qt::Key_Bar,
+ Key_BraceRight = (int)Qt::Key_BraceRight,
+ Key_AsciiTilde = (int)Qt::Key_AsciiTilde,
+
+ // Latin 1 codes adapted from X: keysymdef.h,v 1.21 94/08/28 16:17:06
+
+ Key_nobreakspace = (int)Qt::Key_nobreakspace,
+ Key_exclamdown = (int)Qt::Key_exclamdown,
+ Key_cent = (int)Qt::Key_cent,
+ Key_sterling = (int)Qt::Key_sterling,
+ Key_currency = (int)Qt::Key_currency,
+ Key_yen = (int)Qt::Key_yen,
+ Key_brokenbar = (int)Qt::Key_brokenbar,
+ Key_section = (int)Qt::Key_section,
+ Key_diaeresis = (int)Qt::Key_diaeresis,
+ Key_copyright = (int)Qt::Key_copyright,
+ Key_ordfeminine = (int)Qt::Key_ordfeminine,
+ Key_guillemotleft = (int)Qt::Key_guillemotleft, // left angle quotation mark
+ Key_notsign = (int)Qt::Key_notsign,
+ Key_hyphen = (int)Qt::Key_hyphen,
+ Key_registered = (int)Qt::Key_registered,
+ Key_macron = (int)Qt::Key_macron,
+ Key_degree = (int)Qt::Key_degree,
+ Key_plusminus = (int)Qt::Key_plusminus,
+ Key_twosuperior = (int)Qt::Key_twosuperior,
+ Key_threesuperior = (int)Qt::Key_threesuperior,
+ Key_acute = (int)Qt::Key_acute,
+ Key_mu = (int)Qt::Key_mu,
+ Key_paragraph = (int)Qt::Key_paragraph,
+ Key_periodcentered = (int)Qt::Key_periodcentered,
+ Key_cedilla = (int)Qt::Key_cedilla,
+ Key_onesuperior = (int)Qt::Key_onesuperior,
+ Key_masculine = (int)Qt::Key_masculine,
+ Key_guillemotright = (int)Qt::Key_guillemotright, // right angle quotation mark
+ Key_onequarter = (int)Qt::Key_onequarter,
+ Key_onehalf = (int)Qt::Key_onehalf,
+ Key_threequarters = (int)Qt::Key_threequarters,
+ Key_questiondown = (int)Qt::Key_questiondown,
+ Key_Agrave = (int)Qt::Key_Agrave,
+ Key_Aacute = (int)Qt::Key_Aacute,
+ Key_Acircumflex = (int)Qt::Key_Acircumflex,
+ Key_Atilde = (int)Qt::Key_Atilde,
+ Key_Adiaeresis = (int)Qt::Key_Adiaeresis,
+ Key_Aring = (int)Qt::Key_Aring,
+ Key_AE = (int)Qt::Key_AE,
+ Key_Ccedilla = (int)Qt::Key_Ccedilla,
+ Key_Egrave = (int)Qt::Key_Egrave,
+ Key_Eacute = (int)Qt::Key_Eacute,
+ Key_Ecircumflex = (int)Qt::Key_Ecircumflex,
+ Key_Ediaeresis = (int)Qt::Key_Ediaeresis,
+ Key_Igrave = (int)Qt::Key_Igrave,
+ Key_Iacute = (int)Qt::Key_Iacute,
+ Key_Icircumflex = (int)Qt::Key_Icircumflex,
+ Key_Idiaeresis = (int)Qt::Key_Idiaeresis,
+ Key_ETH = (int)Qt::Key_ETH,
+ Key_Ntilde = (int)Qt::Key_Ntilde,
+ Key_Ograve = (int)Qt::Key_Ograve,
+ Key_Oacute = (int)Qt::Key_Oacute,
+ Key_Ocircumflex = (int)Qt::Key_Ocircumflex,
+ Key_Otilde = (int)Qt::Key_Otilde,
+ Key_Odiaeresis = (int)Qt::Key_Odiaeresis,
+ Key_multiply = (int)Qt::Key_multiply,
+ Key_Ooblique = (int)Qt::Key_Ooblique,
+ Key_Ugrave = (int)Qt::Key_Ugrave,
+ Key_Uacute = (int)Qt::Key_Uacute,
+ Key_Ucircumflex = (int)Qt::Key_Ucircumflex,
+ Key_Udiaeresis = (int)Qt::Key_Udiaeresis,
+ Key_Yacute = (int)Qt::Key_Yacute,
+ Key_THORN = (int)Qt::Key_THORN,
+ Key_ssharp = (int)Qt::Key_ssharp,
+ Key_agrave = (int)Qt::Key_Agrave,
+ Key_aacute = (int)Qt::Key_Aacute,
+ Key_acircumflex = (int)Qt::Key_Acircumflex,
+ Key_atilde = (int)Qt::Key_Atilde,
+ Key_adiaeresis = (int)Qt::Key_Adiaeresis,
+ Key_aring = (int)Qt::Key_Aring,
+ Key_ae = (int)Qt::Key_AE,
+ Key_ccedilla = (int)Qt::Key_Ccedilla,
+ Key_egrave = (int)Qt::Key_Egrave,
+ Key_eacute = (int)Qt::Key_Eacute,
+ Key_ecircumflex = (int)Qt::Key_Ecircumflex,
+ Key_ediaeresis = (int)Qt::Key_Ediaeresis,
+ Key_igrave = (int)Qt::Key_Igrave,
+ Key_iacute = (int)Qt::Key_Iacute,
+ Key_icircumflex = (int)Qt::Key_Icircumflex,
+ Key_idiaeresis = (int)Qt::Key_Idiaeresis,
+ Key_eth = (int)Qt::Key_ETH ,
+ Key_ntilde = (int)Qt::Key_Ntilde,
+ Key_ograve = (int)Qt::Key_Ograve,
+ Key_oacute = (int)Qt::Key_Oacute,
+ Key_ocircumflex = (int)Qt::Key_Ocircumflex,
+ Key_otilde = (int)Qt::Key_Otilde,
+ Key_odiaeresis = (int)Qt::Key_Odiaeresis,
+ Key_division = (int)Qt::Key_division,
+ Key_oslash = (int)Qt::Key_Ooblique,
+ Key_ugrave = (int)Qt::Key_Ugrave,
+ Key_uacute = (int)Qt::Key_Uacute,
+ Key_ucircumflex = (int)Qt::Key_Ucircumflex,
+ Key_udiaeresis = (int)Qt::Key_Udiaeresis,
+ Key_yacute = (int)Qt::Key_Yacute,
+ Key_thorn = (int)Qt::Key_THORN,
+ Key_ydiaeresis = (int)Qt::Key_ydiaeresis,
+
+ // multimedia/internet keys - ignored by default - see TQKeyEvent c'tor
+
+ Key_Back = (int)Qt::Key_Back,
+ Key_Forward = (int)Qt::Key_Forward,
+ Key_Stop = (int)Qt::Key_Stop,
+ Key_Refresh = (int)Qt::Key_Refresh,
+
+ Key_VolumeDown = (int)Qt::Key_VolumeDown,
+ Key_VolumeMute = (int)Qt::Key_VolumeMute,
+ Key_VolumeUp = (int)Qt::Key_VolumeUp,
+ Key_BassBoost = (int)Qt::Key_BassBoost,
+ Key_BassUp = (int)Qt::Key_BassUp,
+ Key_BassDown = (int)Qt::Key_BassDown,
+ Key_TrebleUp = (int)Qt::Key_TrebleUp,
+ Key_TrebleDown = (int)Qt::Key_TrebleDown,
+
+ Key_MediaPlay = (int)Qt::Key_MediaPlay,
+ Key_MediaStop = (int)Qt::Key_MediaStop,
+ Key_MediaPrev = (int)Qt::Key_MediaPrevious,
+ Key_MediaNext = (int)Qt::Key_MediaNext,
+ Key_MediaRecord = (int)Qt::Key_MediaRecord,
+
+ Key_HomePage = (int)Qt::Key_HomePage,
+ Key_Favorites = (int)Qt::Key_Favorites,
+ Key_Search = (int)Qt::Key_Search,
+ Key_Standby = (int)Qt::Key_Standby,
+ Key_OpenUrl = (int)Qt::Key_OpenUrl,
+
+ Key_LaunchMail = (int)Qt::Key_LaunchMail,
+ Key_LaunchMedia = (int)Qt::Key_LaunchMedia,
+ Key_Launch0 = (int)Qt::Key_Launch0,
+ Key_Launch1 = (int)Qt::Key_Launch1,
+ Key_Launch2 = (int)Qt::Key_Launch2,
+ Key_Launch3 = (int)Qt::Key_Launch3,
+ Key_Launch4 = (int)Qt::Key_Launch4,
+ Key_Launch5 = (int)Qt::Key_Launch5,
+ Key_Launch6 = (int)Qt::Key_Launch6,
+ Key_Launch7 = (int)Qt::Key_Launch7,
+ Key_Launch8 = (int)Qt::Key_Launch8,
+ Key_Launch9 = (int)Qt::Key_Launch9,
+ Key_LaunchA = (int)Qt::Key_LaunchA,
+ Key_LaunchB = (int)Qt::Key_LaunchB,
+ Key_LaunchC = (int)Qt::Key_LaunchC,
+ Key_LaunchD = (int)Qt::Key_LaunchD,
+ Key_LaunchE = (int)Qt::Key_LaunchE,
+ Key_LaunchF = (int)Qt::Key_LaunchF,
+
+ Key_MediaLast = (int)Qt::Key_MediaLast,
+
+ Key_unknown = (int)Qt::Key_unknown
+ };
+
+ // documented in qcommonstyle.cpp
+ enum ArrowType {
+ UpArrow,
+ DownArrow,
+ LeftArrow,
+ RightArrow
+ };
+
+ // documented in qpainter.cpp
+ enum RasterOp { // raster op mode
+ CopyROP,
+ OrROP,
+ XorROP,
+ NotAndROP, EraseROP=NotAndROP,
+ NotCopyROP,
+ NotOrROP,
+ NotXorROP,
+ AndROP, NotEraseROP=AndROP,
+ NotROP,
+ ClearROP,
+ SetROP,
+ NopROP,
+ AndNotROP,
+ OrNotROP,
+ NandROP,
+ NorROP, LastROP=NorROP
+ };
+
+ // documented in qpainter.cpp
+ enum PenStyle { // pen style
+ NoPen,
+ SolidLine,
+ DashLine,
+ DotLine,
+ DashDotLine,
+ DashDotDotLine,
+ MPenStyle = 0x0f
+ };
+
+ // documented in qpainter.cpp
+ enum PenCapStyle { // line endcap style
+ FlatCap = 0x00,
+ SquareCap = 0x10,
+ RoundCap = 0x20,
+ MPenCapStyle = 0x30
+ };
+
+ // documented in qpainter.cpp
+ enum PenJoinStyle { // line join style
+ MiterJoin = 0x00,
+ BevelJoin = 0x40,
+ RoundJoin = 0x80,
+ MPenJoinStyle = 0xc0
+ };
+
+ // documented in qpainter.cpp
+ enum BrushStyle { // brush style
+ NoBrush,
+ SolidPattern,
+ Dense1Pattern,
+ Dense2Pattern,
+ Dense3Pattern,
+ Dense4Pattern,
+ Dense5Pattern,
+ Dense6Pattern,
+ Dense7Pattern,
+ HorPattern,
+ VerPattern,
+ CrossPattern,
+ BDiagPattern,
+ FDiagPattern,
+ DiagCrossPattern,
+ CustomPattern=24
+ };
+
+ // documented in qapplication_mac.cpp
+ enum MacintoshVersion {
+ //Unknown
+ MV_Unknown = 0x0000,
+
+ //Version numbers
+ MV_9 = 0x0001,
+ MV_10_DOT_0 = 0x0002,
+ MV_10_DOT_1 = 0x0003,
+ MV_10_DOT_2 = 0x0004,
+ MV_10_DOT_3 = 0x0005,
+ MV_10_DOT_4 = 0x0006,
+
+ //Code names
+ MV_CHEETAH = MV_10_DOT_0,
+ MV_PUMA = MV_10_DOT_1,
+ MV_JAGUAR = MV_10_DOT_2,
+ MV_PANTHER = MV_10_DOT_3,
+ MV_TIGER = MV_10_DOT_4
+ };
+
+ // documented in qapplication_win.cpp
+ enum WindowsVersion {
+ WV_32s = 0x0001,
+ WV_95 = 0x0002,
+ WV_98 = 0x0003,
+ WV_Me = 0x0004,
+ WV_DOS_based = 0x000f,
+
+ WV_NT = 0x0010,
+ WV_2000 = 0x0020,
+ WV_XP = 0x0030,
+ WV_2003 = 0x0040,
+ WV_VISTA = 0x0080,
+ WV_NT_based = 0x00f0,
+
+ WV_CE = 0x0100,
+ WV_CENET = 0x0200,
+ WV_CE_based = 0x0f00
+ };
+
+ // documented in qstyle.cpp
+ enum UIEffect {
+ UI_General,
+ UI_AnimateMenu,
+ UI_FadeMenu,
+ UI_AnimateCombo,
+ UI_AnimateTooltip,
+ UI_FadeTooltip,
+ UI_AnimateToolBox
+ };
+
+ // documented in qcursor.cpp
+ enum tqCursorShape {
+ ArrowCursor,
+ UpArrowCursor,
+ CrossCursor,
+ WaitCursor,
+ IbeamCursor,
+ SizeVerCursor,
+ SizeHorCursor,
+ SizeBDiagCursor,
+ SizeFDiagCursor,
+ SizeAllCursor,
+ BlankCursor,
+ SplitVCursor,
+ SplitHCursor,
+ PointingHandCursor,
+ ForbiddenCursor,
+ WhatsThisCursor,
+ BusyCursor,
+ LastCursor = BusyCursor,
+ BitmapCursor = 24
+ };
+
+ // Global cursors
+ TQT_STATIC_CONST TQCursor & arrowCursor; // standard arrow cursor
+ TQT_STATIC_CONST TQCursor & upArrowCursor; // upwards arrow
+ TQT_STATIC_CONST TQCursor & crossCursor; // crosshair
+ TQT_STATIC_CONST TQCursor & waitCursor; // hourglass/watch
+ TQT_STATIC_CONST TQCursor & ibeamCursor; // ibeam/text entry
+ TQT_STATIC_CONST TQCursor & sizeVerCursor; // vertical resize
+ TQT_STATIC_CONST TQCursor & sizeHorCursor; // horizontal resize
+ TQT_STATIC_CONST TQCursor & sizeBDiagCursor; // diagonal resize (/)
+ TQT_STATIC_CONST TQCursor & sizeFDiagCursor; // diagonal resize (\)
+ TQT_STATIC_CONST TQCursor & sizeAllCursor; // all directions resize
+ TQT_STATIC_CONST TQCursor & blankCursor; // blank/invisible cursor
+ TQT_STATIC_CONST TQCursor & splitVCursor; // vertical bar with left-right
+ // arrows
+ TQT_STATIC_CONST TQCursor & splitHCursor; // horizontal bar with up-down
+ // arrows
+ TQT_STATIC_CONST TQCursor & pointingHandCursor; // pointing hand
+ TQT_STATIC_CONST TQCursor & forbiddenCursor; // forbidden cursor (slashed circle)
+ TQT_STATIC_CONST TQCursor & whatsThisCursor; // arrow with a question mark
+ TQT_STATIC_CONST TQCursor & busyCursor; // arrow with hourglass
+
+ enum TextFormat {
+ PlainText,
+ RichText,
+ AutoText,
+ LogText
+ };
+
+ // Documented in qtextedit.cpp
+ enum AnchorAttribute {
+ AnchorName,
+ AnchorHref
+ };
+
+ // Documented in qmainwindow.cpp
+ enum Dock {
+ DockUnmanaged,
+ DockTornOff,
+ DockTop,
+ DockBottom,
+ DockRight,
+ DockLeft,
+ DockMinimized
+#ifndef TQT_NO_COMPAT
+ ,
+ Unmanaged = DockUnmanaged,
+ TornOff = DockTornOff,
+ Top = DockTop,
+ Bottom = DockBottom,
+ Right = DockRight,
+ Left = DockLeft,
+ Minimized = DockMinimized
+#endif
+ };
+ // compatibility
+ typedef Dock ToolBarDock;
+
+#ifdef USE_QT4
+ enum DateFormat_NewTypes {
+ TextDate = Qt::TextDate,
+ ISODate = Qt::ISODate,
+ LocalDate = Qt::LocalDate
+ };
+// typedef TQTInheritEnum< DateFormat_NewTypes, Qt::DateFormat > DateFormat;
+ typedef int DateFormat_NewTypes;
+#else // USE_QT4
+ // documented in qdatetime.cpp
+ enum DateFormat {
+ TextDate, // default TQt
+ ISODate, // ISO 8601
+ LocalDate // locale dependent
+ };
+#endif
+
+ // documented in qdatetime.cpp
+ enum TimeSpec {
+ LocalTime,
+ UTC
+ };
+
+ // documented in qwidget.cpp
+ enum BackgroundMode {
+ FixedColor,
+ FixedPixmap,
+ NoBackground,
+ PaletteForeground,
+ PaletteButton,
+ PaletteLight,
+ PaletteMidlight,
+ PaletteDark,
+ PaletteMid,
+ PaletteText,
+ PaletteBrightText,
+ PaletteBase,
+ PaletteBackground,
+ PaletteShadow,
+ PaletteHighlight,
+ PaletteHighlightedText,
+ PaletteButtonText,
+ PaletteLink,
+ PaletteLinkVisited,
+ X11ParentRelative
+ };
+
+ typedef uint ComparisonFlags;
+
+ // Documented in qstring.cpp
+ enum StringComparisonMode {
+ CaseSensitive = 0x00001, // 0 0001
+ BeginsWith = 0x00002, // 0 0010
+ EndsWith = 0x00004, // 0 0100
+ Contains = 0x00008, // 0 1000
+ ExactMatch = 0x00010 // 1 0000
+ };
+
+ // Documented in qtabwidget.cpp
+ enum Corner {
+ TopLeft = 0x00000,
+ TopRight = 0x00001,
+ BottomLeft = 0x00002,
+ BottomRight = 0x00003
+ };
+
+ // "handle" type for system objects. Documented as \internal in
+ // qapplication.cpp
+#if defined(TQ_WS_MAC)
+ typedef void * HANDLE;
+#elif defined(TQ_WS_WIN)
+ typedef void *HANDLE;
+#elif defined(TQ_WS_X11)
+ typedef unsigned long HANDLE;
+#elif defined(TQ_WS_TQWS)
+ typedef void * HANDLE;
+#endif
+};
+
+
+class TQ_EXPORT TQInternal {
+public:
+ enum PaintDeviceFlags {
+ UndefinedDevice = 0x00,
+ Widget = 0x01,
+ Pixmap = 0x02,
+ Printer = 0x03,
+ Picture = 0x04,
+ System = 0x05,
+ DeviceTypeMask = 0x0f,
+ ExternalDevice = 0x10,
+ // used to emulate some of the behaviour different between TQt2 and TQt3 (mainly for printing)
+ CompatibilityMode = 0x20
+ };
+};
+
+#endif // TQNAMESPACE_H
diff --git a/tqtinterface/qt4/src/kernel/tqnetworkprotocol.cpp b/tqtinterface/qt4/src/kernel/tqnetworkprotocol.cpp
new file mode 100644
index 0000000..83cc094
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqnetworkprotocol.cpp
@@ -0,0 +1,1265 @@
+/****************************************************************************
+**
+** Implementation of TQNetworkProtocol class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqnetworkprotocol.h"
+
+#ifndef TQT_NO_NETWORKPROTOCOL
+
+#include "tqlocalfs.h"
+#include "tqurloperator.h"
+#include "tqtimer.h"
+#include "tqmap.h"
+#include "tqptrqueue.h"
+
+//#define TQNETWORKPROTOCOL_DEBUG
+#define NETWORK_OP_DELAY 1000
+
+extern TQ_EXPORT TQNetworkProtocolDict *qNetworkProtocolRegister;
+
+TQNetworkProtocolDict *qNetworkProtocolRegister = 0;
+
+class TQNetworkProtocolPrivate
+{
+public:
+ TQNetworkProtocolPrivate( TQNetworkProtocol *p )
+ {
+ url = 0;
+ opInProgress = 0;
+ opStartTimer = new TQTimer( p );
+ removeTimer = new TQTimer( p );
+ operationQueue.setAutoDelete( FALSE );
+ autoDelete = FALSE;
+ removeInterval = 10000;
+ oldOps.setAutoDelete( FALSE );
+ }
+
+ ~TQNetworkProtocolPrivate()
+ {
+ removeTimer->stop();
+ if ( opInProgress ) {
+ if ( opInProgress == operationQueue.head() )
+ operationQueue.dequeue();
+ opInProgress->free();
+ }
+ while ( operationQueue.head() ) {
+ operationQueue.head()->free();
+ operationQueue.dequeue();
+ }
+ while ( oldOps.first() ) {
+ oldOps.first()->free();
+ oldOps.removeFirst();
+ }
+ delete opStartTimer;
+ }
+
+ TQUrlOperator *url;
+ TQPtrQueue< TQNetworkOperation > operationQueue;
+ TQNetworkOperation *opInProgress;
+ TQTimer *opStartTimer, *removeTimer;
+ int removeInterval;
+ bool autoDelete;
+ TQPtrList< TQNetworkOperation > oldOps;
+};
+
+/*!
+ \class TQNetworkProtocol tqnetworkprotocol.h
+ \brief The TQNetworkProtocol class provides a common API for network protocols.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module network
+ \ingroup io
+ \module network
+ \mainclass
+
+ This is a base class which should be used for network protocols
+ implementations that can then be used in TQt (e.g. in the file
+ dialog) together with the TQUrlOperator.
+
+ The easiest way to implement a new network protocol is to
+ reimplement the operation*() methods, e.g. operationGet(), etc.
+ Only the supported operations should be reimplemented. To specify
+ which operations are supported, also reimplement
+ supportedOperations() and return an int that is OR'd together
+ using the supported operations from the \l
+ TQNetworkProtocol::Operation enum.
+
+ When you implement a network protocol this way, it is important to
+ emit the correct Q_SIGNALS. Also, always emit the finished() signal
+ when an operation is done (on success \e and on failure). TQt
+ relies on correctly emitted finished() Q_SIGNALS.
+
+ For a detailed description of the TQt Network Architecture and how
+ to implement and use network protocols in TQt, see the \link
+ network.html TQt Network Documentation\endlink.
+*/
+
+/*!
+ \fn void TQNetworkProtocol::newChildren( const TQValueList<TQUrlInfo> &i, TQNetworkOperation *op )
+
+ This signal is emitted after listChildren() was called and new
+ tqchildren (files) have been read from the list of files. \a i holds
+ the information about the new tqchildren. \a op is the pointer to
+ the operation object which tqcontains all the information about the
+ operation, including the state, etc.
+
+ When a protocol emits this signal, TQNetworkProtocol is smart
+ enough to let the TQUrlOperator, which is used by the network
+ protocol, emit its corresponding signal.
+
+ When implementing your own network protocol and reading tqchildren,
+ you usually don't read one child at once, but rather a list of
+ them. That's why this signal takes a list of TQUrlInfo objects. If
+ you prefer to read just one child at a time you can use the
+ convenience signal newChild(), which takes a single TQUrlInfo
+ object.
+*/
+
+/*!
+ \fn void TQNetworkProtocol::newChild( const TQUrlInfo &i, TQNetworkOperation *op )
+
+ This signal is emitted if a new child (file) has been read.
+ TQNetworkProtocol automatically connects it to a slot which creates
+ a list of TQUrlInfo objects (with just one TQUrlInfo \a i) and emits
+ the newChildren() signal with this list. \a op is the pointer to
+ the operation object which tqcontains all the information about the
+ operation that has finished, including the state, etc.
+
+ This is just a convenience signal useful for implementing your own
+ network protocol. In all other cases connect to the newChildren()
+ signal with its list of TQUrlInfo objects.
+*/
+
+/*!
+ \fn void TQNetworkProtocol::finished( TQNetworkOperation *op )
+
+ This signal is emitted when an operation finishes. This signal is
+ always emitted, for both success and failure. \a op is the pointer
+ to the operation object which tqcontains all the information about
+ the operation, including the state, etc. Check the state and error
+ code of the operation object to determine whether or not the
+ operation was successful.
+
+ When a protocol emits this signal, TQNetworkProtocol is smart
+ enough to let the TQUrlOperator, which is used by the network
+ protocol, emit its corresponding signal.
+*/
+
+/*!
+ \fn void TQNetworkProtocol::start( TQNetworkOperation *op )
+
+ Some operations (such as listChildren()) emit this signal when
+ they start processing the operation. \a op is the pointer to the
+ operation object which tqcontains all the information about the
+ operation, including the state, etc.
+
+ When a protocol emits this signal, TQNetworkProtocol is smart
+ enough to let the TQUrlOperator, which is used by the network
+ protocol, emit its corresponding signal.
+*/
+
+/*!
+ \fn void TQNetworkProtocol::createdDirectory( const TQUrlInfo &i, TQNetworkOperation *op )
+
+ This signal is emitted when mkdir() has been succesful and the
+ directory has been created. \a i holds the information about the
+ new directory. \a op is the pointer to the operation object which
+ tqcontains all the information about the operation, including the
+ state, etc. Using op->arg( 0 ), you can get the file name of the
+ new directory.
+
+ When a protocol emits this signal, TQNetworkProtocol is smart
+ enough to let the TQUrlOperator, which is used by the network
+ protocol, emit its corresponding signal.
+*/
+
+/*!
+ \fn void TQNetworkProtocol::removed( TQNetworkOperation *op )
+
+ This signal is emitted when remove() has been succesful and the
+ file has been removed. \a op holds the file name of the removed
+ file in the first argument, accessible with op->arg( 0 ). \a op is
+ the pointer to the operation object which tqcontains all the
+ information about the operation, including the state, etc.
+
+ When a protocol emits this signal, TQNetworkProtocol is smart
+ enough to let the TQUrlOperator, which is used by the network
+ protocol, emit its corresponding signal.
+*/
+
+/*!
+ \fn void TQNetworkProtocol::itemChanged( TQNetworkOperation *op )
+
+ This signal is emitted whenever a file which is a child of this
+ URL has been changed, e.g. by successfully calling rename(). \a op
+ holds the original and the new file names in the first and second
+ arguments, accessible with op->arg( 0 ) and op->arg( 1 )
+ respectively. \a op is the pointer to the operation object which
+ tqcontains all the information about the operation, including the
+ state, etc.
+
+ When a protocol emits this signal, TQNetworkProtocol is smart
+ enough to let the TQUrlOperator, which is used by the network
+ protocol, emit its corresponding signal.
+*/
+
+/*!
+ \fn void TQNetworkProtocol::data( const TQByteArray &data,
+ TQNetworkOperation *op )
+
+ This signal is emitted when new \a data has been received after
+ calling get() or put(). \a op holds the name of the file from
+ which data is retrieved or uploaded in its first argument, and the
+ (raw) data in its second argument. You can get them with
+ op->arg( 0 ) and op->rawArg( 1 ). \a op is the pointer to the
+ operation object, which tqcontains all the information about the
+ operation, including the state, etc.
+
+ When a protocol emits this signal, TQNetworkProtocol is smart
+ enough to let the TQUrlOperator (which is used by the network
+ protocol) emit its corresponding signal.
+*/
+
+/*!
+ \fn void TQNetworkProtocol::dataTransferProgress( int bytesDone, int bytesTotal, TQNetworkOperation *op )
+
+ This signal is emitted during the transfer of data (using put() or
+ get()). \a bytesDone is how many bytes of \a bytesTotal have been
+ transferred. \a bytesTotal may be -1, which means that the total
+ number of bytes is not known. \a op is the pointer to the
+ operation object which tqcontains all the information about the
+ operation, including the state, etc.
+
+ When a protocol emits this signal, TQNetworkProtocol is smart
+ enough to let the TQUrlOperator, which is used by the network
+ protocol, emit its corresponding signal.
+*/
+
+/*!
+ \fn void TQNetworkProtocol::connectionStateChanged( int state, const TQString &data )
+
+ This signal is emitted whenever the state of the connection of the
+ network protocol is changed. \a state describes the new state,
+ which is one of, \c ConHostFound, \c ConConnected or \c ConClosed.
+ \a data is a message text.
+*/
+
+/*!
+ \enum TQNetworkProtocol::State
+
+ This enum tqcontains the state that a TQNetworkOperation can have.
+
+ \value StWaiting The operation is in the TQNetworkProtocol's queue
+ waiting to be prcessed.
+
+ \value StInProgress The operation is being processed.
+
+ \value StDone The operation has been processed succesfully.
+
+ \value StFailed The operation has been processed but an error occurred.
+
+ \value StStopped The operation has been processed but has been
+ stopped before it finished, and is waiting to be processed.
+
+*/
+
+/*!
+ \enum TQNetworkProtocol::Operation
+
+ This enum lists the possible operations that a network protocol
+ can support. supportedOperations() returns an int of these that is
+ OR'd together. Also, the type() of a TQNetworkOperation is always
+ one of these values.
+
+ \value OpListChildren List the tqchildren of a URL, e.g. of a directory.
+ \value OpMkDir Create a directory.
+ \value OpRemove Remove a child (e.g. a file).
+ \value OpRename Rename a child (e.g. a file).
+ \value OpGet Get data from a location.
+ \value OpPut Put data to a location.
+*/
+
+/*!
+ \enum TQNetworkProtocol::ConnectionState
+
+ When the connection state of a network protocol changes it emits
+ the signal connectionStateChanged(). The first argument is one of
+ the following values:
+
+ \value ConHostFound Host has been found.
+ \value ConConnected Connection to the host has been established.
+ \value ConClosed Connection has been closed.
+*/
+
+/*!
+ \enum TQNetworkProtocol::Error
+
+ When an operation fails (finishes unsuccessfully), the
+ TQNetworkOperation of the operation returns an error code which has
+ one of the following values:
+
+ \value NoError No error occurred.
+
+ \value ErrValid The URL you are operating on is not valid.
+
+ \value ErrUnknownProtocol There is no protocol implementation
+ available for the protocol of the URL you are operating on (e.g.
+ if the protocol is http and no http implementation has been
+ registered).
+
+ \value ErrUnsupported The operation is not supported by the
+ protocol.
+
+ \value ErrParse The URL could not be parsed correctly.
+
+ \value ErrLoginIncorrect You needed to login but the username
+ or password is wrong.
+
+ \value ErrHostNotFound The specified host (in the URL) couldn't
+ be found.
+
+ \value ErrListChildren An error occurred while listing the
+ tqchildren (files).
+
+ \value ErrMkDir An error occurred when creating a directory.
+
+ \value ErrRemove An error occurred when removing a child (file).
+
+ \value ErrRename An error occurred when renaming a child (file).
+
+ \value ErrGet An error occurred while getting (retrieving) data.
+
+ \value ErrPut An error occurred while putting (uploading) data.
+
+ \value ErrFileNotExisting A file which is needed by the operation
+ doesn't exist.
+
+ \value ErrPermissionDenied Permission for doing the operation has
+ been denied.
+
+ You should also use these error codes when implementing custom
+ network protocols. If this is not possible, you can define your own
+ error codes by using integer values that don't conflict with any
+ of these values.
+*/
+
+/*!
+ Constructor of the network protocol base class. Does some
+ initialization and connecting of Q_SIGNALS and Q_SLOTS.
+*/
+
+TQNetworkProtocol::TQNetworkProtocol()
+ : TQObject()
+{
+ d = new TQNetworkProtocolPrivate( this );
+
+ connect( d->opStartTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( startOps() ) );
+ connect( d->removeTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( removeMe() ) );
+
+ if ( url() ) {
+ connect( this, TQT_SIGNAL( data(const TQByteArray&,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( data(const TQByteArray&,TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( finished(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( finished(TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( start(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( start(TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( newChildren(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( newChildren(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( newChildren(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ),
+ url(), TQT_SLOT( addEntry(const TQValueList<TQUrlInfo>&) ) );
+ connect( this, TQT_SIGNAL( createdDirectory(const TQUrlInfo&,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( createdDirectory(const TQUrlInfo&,TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( removed(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( removed(TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( itemChanged(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( itemChanged(TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( connectionStateChanged(int,const TQString&) ),
+ url(), TQT_SIGNAL( connectionStateChanged(int,const TQString&) ) );
+ }
+
+ connect( this, TQT_SIGNAL( finished(TQNetworkOperation*) ),
+ this, TQT_SLOT( processNextOperation(TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( newChild(const TQUrlInfo&,TQNetworkOperation*) ),
+ this, TQT_SLOT( emitNewChildren(const TQUrlInfo&,TQNetworkOperation*) ) );
+
+}
+
+/*!
+ Destructor.
+*/
+
+TQNetworkProtocol::~TQNetworkProtocol()
+{
+ delete d;
+}
+
+/*!
+ Sets the TQUrlOperator, on which the protocol works, to \a u.
+
+ \sa TQUrlOperator
+*/
+
+void TQNetworkProtocol::setUrl( TQUrlOperator *u )
+{
+ if ( url() ) {
+ disconnect( this, TQT_SIGNAL( data(const TQByteArray&,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( data(const TQByteArray&,TQNetworkOperation*) ) );
+ disconnect( this, TQT_SIGNAL( finished(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( finished(TQNetworkOperation*) ) );
+ disconnect( this, TQT_SIGNAL( start(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( start(TQNetworkOperation*) ) );
+ disconnect( this, TQT_SIGNAL( newChildren(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( newChildren(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ) );
+ disconnect( this, TQT_SIGNAL( newChildren(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ),
+ url(), TQT_SLOT( addEntry(const TQValueList<TQUrlInfo>&) ) );
+ disconnect( this, TQT_SIGNAL( createdDirectory(const TQUrlInfo&,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( createdDirectory(const TQUrlInfo&,TQNetworkOperation*) ) );
+ disconnect( this, TQT_SIGNAL( removed(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( removed(TQNetworkOperation*) ) );
+ disconnect( this, TQT_SIGNAL( itemChanged(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( itemChanged(TQNetworkOperation*) ) );
+ disconnect( this, TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ) );
+ disconnect( this, TQT_SIGNAL( connectionStateChanged(int,const TQString&) ),
+ url(), TQT_SIGNAL( connectionStateChanged(int,const TQString&) ) );
+ }
+
+
+ // ### if autoDelete is TRUE, we should delete the TQUrlOperator (something
+ // like below; but that is not possible since it would delete this, too).
+ //if ( d->autoDelete && (d->url!=u) ) {
+ // delete d->url; // destructor deletes the network protocol
+ //}
+ d->url = u;
+
+ if ( url() ) {
+ connect( this, TQT_SIGNAL( data(const TQByteArray&,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( data(const TQByteArray&,TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( finished(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( finished(TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( start(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( start(TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( newChildren(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( newChildren(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( newChildren(const TQValueList<TQUrlInfo>&,TQNetworkOperation*) ),
+ url(), TQT_SLOT( addEntry(const TQValueList<TQUrlInfo>&) ) );
+ connect( this, TQT_SIGNAL( createdDirectory(const TQUrlInfo&,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( createdDirectory(const TQUrlInfo&,TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( removed(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( removed(TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( itemChanged(TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( itemChanged(TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ),
+ url(), TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ) );
+ connect( this, TQT_SIGNAL( connectionStateChanged(int,const TQString&) ),
+ url(), TQT_SIGNAL( connectionStateChanged(int,const TQString&) ) );
+ }
+
+ if ( !d->opInProgress && !d->operationQueue.isEmpty() )
+ d->opStartTimer->start( 0, TRUE );
+}
+
+/*!
+ For processing operations the network protocol base class calls
+ this method quite often. This should be reimplemented by new
+ network protocols. It should return TRUE if the connection is OK
+ (open); otherwise it should return FALSE. If the connection is not
+ open the protocol should open it.
+
+ If the connection can't be opened (e.g. because you already tried
+ but the host couldn't be found), set the state of \a op to
+ TQNetworkProtocol::StFailed and emit the finished() signal with
+ this TQNetworkOperation as argument.
+
+ \a op is the operation that needs an open connection.
+*/
+
+bool TQNetworkProtocol::checkConnection( TQNetworkOperation * )
+{
+ return TRUE;
+}
+
+/*!
+ Returns an int that is OR'd together using the enum values of
+ \l{TQNetworkProtocol::Operation}, which describes which operations
+ are supported by the network protocol. Should be reimplemented by
+ new network protocols.
+*/
+
+int TQNetworkProtocol::supportedOperations() const
+{
+ return 0;
+}
+
+/*!
+ Adds the operation \a op to the operation queue. The operation
+ will be processed as soon as possible. This method returns
+ immediately.
+*/
+
+void TQNetworkProtocol::addOperation( TQNetworkOperation *op )
+{
+#ifdef TQNETWORKPROTOCOL_DEBUG
+ qDebug( "TQNetworkOperation: addOperation: %p %d", op, op->operation() );
+#endif
+ d->operationQueue.enqueue( op );
+ if ( !d->opInProgress )
+ d->opStartTimer->start( 0, TRUE );
+}
+
+/*!
+ Static method to register a network protocol for TQt. For example,
+ if you have an implementation of NNTP (called Nntp) which is
+ derived from TQNetworkProtocol, call:
+ \code
+ TQNetworkProtocol::registerNetworkProtocol( "nntp", new TQNetworkProtocolFactory<Nntp> );
+ \endcode
+ after which your implementation is registered for future nntp
+ operations.
+
+ The name of the protocol is given in \a protocol and a pointer to
+ the protocol factory is given in \a protocolFactory.
+*/
+
+void TQNetworkProtocol::registerNetworkProtocol( const TQString &protocol,
+ TQNetworkProtocolFactoryBase *protocolFactory )
+{
+ if ( !qNetworkProtocolRegister ) {
+ qNetworkProtocolRegister = new TQNetworkProtocolDict;
+ TQNetworkProtocol::registerNetworkProtocol( "file", new TQNetworkProtocolFactory< TQLocalFs > );
+ }
+
+ qNetworkProtocolRegister->insert( protocol, protocolFactory );
+}
+
+/*!
+ Static method to get a new instance of the network protocol \a
+ protocol. For example, if you need to do some FTP operations, do
+ the following:
+ \code
+ TQFtp *ftp = TQNetworkProtocol::getNetworkProtocol( "ftp" );
+ \endcode
+ This returns a pointer to a new instance of an ftp implementation
+ or null if no protocol for ftp was registered. The ownership of
+ the pointer is transferred to you, so you must delete it if you
+ don't need it anymore.
+
+ Normally you should not work directly with network protocols, so
+ you will not need to call this method yourself. Instead, use
+ TQUrlOperator, which makes working with network protocols much more
+ convenient.
+
+ \sa TQUrlOperator
+*/
+
+TQNetworkProtocol *TQNetworkProtocol::getNetworkProtocol( const TQString &protocol )
+{
+ if ( !qNetworkProtocolRegister ) {
+ qNetworkProtocolRegister = new TQNetworkProtocolDict;
+ TQNetworkProtocol::registerNetworkProtocol( "file", new TQNetworkProtocolFactory< TQLocalFs > );
+ }
+
+ if ( protocol.isNull() )
+ return 0;
+
+ TQNetworkProtocolFactoryBase *factory = qNetworkProtocolRegister->tqfind( protocol );
+ if ( factory )
+ return factory->createObject();
+
+ return 0;
+}
+
+/*!
+ Returns TRUE if the only protocol registered is for working on the
+ local filesystem; returns FALSE if other network protocols are
+ also registered.
+*/
+
+bool TQNetworkProtocol::hasOnlyLocalFileSystem()
+{
+ if ( !qNetworkProtocolRegister )
+ return FALSE;
+
+ TQDictIterator< TQNetworkProtocolFactoryBase > it( *qNetworkProtocolRegister );
+ for ( ; it.current(); ++it )
+ if ( it.currentKey() != "file" )
+ return FALSE;
+ return TRUE;
+}
+
+/*!
+ \internal
+ Starts processing network operations.
+*/
+
+void TQNetworkProtocol::startOps()
+{
+#ifdef TQNETWORKPROTOCOL_DEBUG
+ qDebug( "TQNetworkOperation: start processing operations" );
+#endif
+ processNextOperation( 0 );
+}
+
+/*!
+ \internal
+ Processes the operation \a op. It calls the
+ corresponding operation[something]( TQNetworkOperation * )
+ methods.
+*/
+
+void TQNetworkProtocol::processOperation( TQNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+ switch ( op->operation() ) {
+ case OpListChildren:
+ operationListChildren( op );
+ break;
+ case OpMkDir:
+ operationMkDir( op );
+ break;
+ case OpRemove:
+ operationRemove( op );
+ break;
+ case OpRename:
+ operationRename( op );
+ break;
+ case OpGet:
+ operationGet( op );
+ break;
+ case OpPut:
+ operationPut( op );
+ break;
+ }
+}
+
+/*!
+ When implementing a new network protocol, this method should be
+ reimplemented if the protocol supports listing tqchildren (files);
+ this method should then process this TQNetworkOperation.
+
+ When you reimplement this method it's very important that you emit
+ the correct Q_SIGNALS at the correct time (especially the finished()
+ signal after processing an operation). Take a look at the \link
+ network.html TQt Network Documentation\endlink which describes in
+ detail how to reimplement this method. You may also want to look
+ at the example implementation in
+ examples/network/networkprotocol/nntp.cpp.
+
+ \a op is the pointer to the operation object which tqcontains all
+ the information on the operation that has finished, including the
+ state, etc.
+*/
+
+void TQNetworkProtocol::operationListChildren( TQNetworkOperation * )
+{
+}
+
+/*!
+ When implementing a new network protocol, this method should be
+ reimplemented if the protocol supports making directories; this
+ method should then process this TQNetworkOperation.
+
+ When you reimplement this method it's very important that you emit
+ the correct Q_SIGNALS at the correct time (especially the finished()
+ signal after processing an operation). Take a look at the \link
+ network.html TQt Network Documentation\endlink which describes in
+ detail how to reimplement this method. You may also want to look
+ at the example implementation in
+ examples/network/networkprotocol/nntp.cpp.
+
+ \a op is the pointer to the operation object which tqcontains all
+ the information on the operation that has finished, including the
+ state, etc.
+*/
+
+void TQNetworkProtocol::operationMkDir( TQNetworkOperation * )
+{
+}
+
+/*!
+ When implementing a new network protocol, this method should be
+ reimplemented if the protocol supports removing tqchildren (files);
+ this method should then process this TQNetworkOperation.
+
+ When you reimplement this method it's very important that you emit
+ the correct Q_SIGNALS at the correct time (especially the finished()
+ signal after processing an operation). Take a look at the \link
+ network.html TQt Network Documentation\endlink which is describes
+ in detail how to reimplement this method. You may also want to
+ look at the example implementation in
+ examples/network/networkprotocol/nntp.cpp.
+
+ \a op is the pointer to the operation object which tqcontains all
+ the information on the operation that has finished, including the
+ state, etc.
+*/
+
+void TQNetworkProtocol::operationRemove( TQNetworkOperation * )
+{
+}
+
+/*!
+ When implementing a new newtork protocol, this method should be
+ reimplemented if the protocol supports renaming tqchildren (files);
+ this method should then process this TQNetworkOperation.
+
+ When you reimplement this method it's very important that you emit
+ the correct Q_SIGNALS at the correct time (especially the finished()
+ signal after processing an operation). Take a look at the \link
+ network.html TQt Network Documentation\endlink which describes in
+ detail how to reimplement this method. You may also want to look
+ at the example implementation in
+ examples/network/networkprotocol/nntp.cpp.
+
+ \a op is the pointer to the operation object which tqcontains all
+ the information on the operation that has finished, including the
+ state, etc.
+*/
+
+void TQNetworkProtocol::operationRename( TQNetworkOperation * )
+{
+}
+
+/*!
+ When implementing a new network protocol, this method should be
+ reimplemented if the protocol supports getting data; this method
+ should then process the TQNetworkOperation.
+
+ When you reimplement this method it's very important that you emit
+ the correct Q_SIGNALS at the correct time (especially the finished()
+ signal after processing an operation). Take a look at the \link
+ network.html TQt Network Documentation\endlink which describes in
+ detail how to reimplement this method. You may also want to look
+ at the example implementation in
+ examples/network/networkprotocol/nntp.cpp.
+
+ \a op is the pointer to the operation object which tqcontains all
+ the information on the operation that has finished, including the
+ state, etc.
+*/
+
+void TQNetworkProtocol::operationGet( TQNetworkOperation * )
+{
+}
+
+/*!
+ When implementing a new network protocol, this method should be
+ reimplemented if the protocol supports putting (uploading) data;
+ this method should then process the TQNetworkOperation.
+
+ When you reimplement this method it's very important that you emit
+ the correct Q_SIGNALS at the correct time (especially the finished()
+ signal after processing an operation). Take a look at the \link
+ network.html TQt Network Documentation\endlink which describes in
+ detail how to reimplement this method. You may also want to look
+ at the example implementation in
+ examples/network/networkprotocol/nntp.cpp.
+
+ \a op is the pointer to the operation object which tqcontains all
+ the information on the operation that has finished, including the
+ state, etc.
+*/
+
+void TQNetworkProtocol::operationPut( TQNetworkOperation * )
+{
+}
+
+/*! \internal
+*/
+
+void TQNetworkProtocol::operationPutChunk( TQNetworkOperation * )
+{
+}
+
+/*!
+ \internal
+ Handles operations. Deletes the previous operation object and
+ tries to process the next operation. It also checks the connection state
+ and only processes the next operation, if the connection of the protocol
+ is open. Otherwise it waits until the protocol opens the connection.
+*/
+
+void TQNetworkProtocol::processNextOperation( TQNetworkOperation *old )
+{
+#ifdef TQNETWORKPROTOCOL_DEBUG
+ qDebug( "TQNetworkOperation: process next operation, old: %p", old );
+#endif
+ d->removeTimer->stop();
+
+ if ( old )
+ d->oldOps.append( old );
+ if ( d->opInProgress && d->opInProgress!=old )
+ d->oldOps.append( d->opInProgress );
+
+ if ( d->operationQueue.isEmpty() ) {
+ d->opInProgress = 0;
+ if ( d->autoDelete )
+ d->removeTimer->start( d->removeInterval, TRUE );
+ return;
+ }
+
+ TQNetworkOperation *op = d->operationQueue.head();
+
+ d->opInProgress = op;
+
+ if ( !checkConnection( op ) ) {
+ if ( op->state() != TQNetworkProtocol::StFailed ) {
+ d->opStartTimer->start( 0, TRUE );
+ } else {
+ d->operationQueue.dequeue();
+ clearOperationQueue();
+ emit finished( op );
+ }
+
+ return;
+ }
+
+ d->opInProgress = op;
+ d->operationQueue.dequeue();
+ processOperation( op );
+}
+
+/*!
+ Returns the TQUrlOperator on which the protocol works.
+*/
+
+TQUrlOperator *TQNetworkProtocol::url() const
+{
+ return d->url;
+}
+
+/*!
+ Returns the operation, which is being processed, or 0 of no
+ operation is being processed at the moment.
+*/
+
+TQNetworkOperation *TQNetworkProtocol::operationInProgress() const
+{
+ return d->opInProgress;
+}
+
+/*!
+ Clears the operation queue.
+*/
+
+void TQNetworkProtocol::clearOperationQueue()
+{
+ d->operationQueue.dequeue();
+ d->operationQueue.setAutoDelete( TRUE );
+ d->operationQueue.clear();
+}
+
+/*!
+ Stops the current operation that is being processed and clears all
+ waiting operations.
+*/
+
+void TQNetworkProtocol::stop()
+{
+ TQNetworkOperation *op = d->opInProgress;
+ clearOperationQueue();
+ if ( op ) {
+ op->setState( StStopped );
+ op->setProtocolDetail( tr( "Operation stopped by the user" ) );
+ emit finished( op );
+ setUrl( 0 );
+ op->free();
+ }
+}
+
+/*!
+ Because it's sometimes hard to take care of removing network
+ protocol instances, TQNetworkProtocol provides an auto-delete
+ mechanism. If you set \a b to TRUE, the network protocol instance
+ is removed after it has been inactive for \a i milliseconds (i.e.
+ \a i milliseconds after the last operation has been processed).
+ If you set \a b to FALSE the auto-delete mechanism is switched
+ off.
+
+ If you switch on auto-delete, the TQNetworkProtocol also deletes
+ its TQUrlOperator.
+*/
+
+void TQNetworkProtocol::setAutoDelete( bool b, int i )
+{
+ d->autoDelete = b;
+ d->removeInterval = i;
+}
+
+/*!
+ Returns TRUE if auto-deleting is enabled; otherwise returns FALSE.
+
+ \sa TQNetworkProtocol::setAutoDelete()
+*/
+
+bool TQNetworkProtocol::autoDelete() const
+{
+ return d->autoDelete;
+}
+
+/*!
+ \internal
+*/
+
+void TQNetworkProtocol::removeMe()
+{
+ if ( d->autoDelete ) {
+#ifdef TQNETWORKPROTOCOL_DEBUG
+ qDebug( "TQNetworkOperation: autodelete of TQNetworkProtocol %p", this );
+#endif
+ delete d->url; // destructor deletes the network protocol
+ }
+}
+
+void TQNetworkProtocol::emitNewChildren( const TQUrlInfo &i, TQNetworkOperation *op )
+{
+ TQValueList<TQUrlInfo> lst;
+ lst << i;
+ emit newChildren( lst, op );
+}
+
+class TQNetworkOperationPrivate
+{
+public:
+ TQNetworkProtocol::Operation operation;
+ TQNetworkProtocol::State state;
+ TQMap<int, TQString> args;
+ TQMap<int, TQByteArray> rawArgs;
+ TQString protocolDetail;
+ int errorCode;
+ TQTimer *deleteTimer;
+};
+
+/*!
+ \class TQNetworkOperation
+
+ \brief The TQNetworkOperation class provides common operations for network protocols.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module network
+ \ingroup io
+
+ An object is created to describe the operation and the current
+ state for each operation that a network protocol should process.
+
+ For a detailed description of the TQt Network Architecture and how
+ to implement and use network protocols in TQt, see the \link
+ network.html TQt Network Documentation\endlink.
+
+ \sa TQNetworkProtocol
+*/
+
+/*!
+ Constructs a network operation object. \a operation is the type of
+ the operation, and \a arg0, \a arg1 and \a arg2 are the first
+ three arguments of the operation. The state is initialized to
+ TQNetworkProtocol::StWaiting.
+
+ \sa TQNetworkProtocol::Operation TQNetworkProtocol::State
+*/
+
+TQNetworkOperation::TQNetworkOperation( TQNetworkProtocol::Operation operation,
+ const TQString &arg0, const TQString &arg1,
+ const TQString &arg2 )
+{
+ d = new TQNetworkOperationPrivate;
+ d->deleteTimer = new TQTimer( this );
+ connect( d->deleteTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( deleteMe() ) );
+ d->operation = operation;
+ d->state = TQNetworkProtocol::StWaiting;
+ d->args[ 0 ] = arg0;
+ d->args[ 1 ] = arg1;
+ d->args[ 2 ] = arg2;
+ d->rawArgs[ 0 ] = TQByteArray( 0 );
+ d->rawArgs[ 1 ] = TQByteArray( 0 );
+ d->rawArgs[ 2 ] = TQByteArray( 0 );
+ d->protocolDetail = TQString::null;
+ d->errorCode = (int)TQNetworkProtocol::NoError;
+}
+
+/*!
+ Constructs a network operation object. \a operation is the type of
+ the operation, and \a arg0, \a arg1 and \a arg2 are the first
+ three raw data arguments of the operation. The state is
+ initialized to TQNetworkProtocol::StWaiting.
+
+ \sa TQNetworkProtocol::Operation TQNetworkProtocol::State
+*/
+
+TQNetworkOperation::TQNetworkOperation( TQNetworkProtocol::Operation operation,
+ const TQByteArray &arg0, const TQByteArray &arg1,
+ const TQByteArray &arg2 )
+{
+ d = new TQNetworkOperationPrivate;
+ d->deleteTimer = new TQTimer( this );
+ connect( d->deleteTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( deleteMe() ) );
+ d->operation = operation;
+ d->state = TQNetworkProtocol::StWaiting;
+ d->args[ 0 ] = TQString::null;
+ d->args[ 1 ] = TQString::null;
+ d->args[ 2 ] = TQString::null;
+ d->rawArgs[ 0 ] = arg0;
+ d->rawArgs[ 1 ] = arg1;
+ d->rawArgs[ 2 ] = arg2;
+ d->protocolDetail = TQString::null;
+ d->errorCode = (int)TQNetworkProtocol::NoError;
+}
+
+/*!
+ Destructor.
+*/
+
+TQNetworkOperation::~TQNetworkOperation()
+{
+ delete d;
+}
+
+/*!
+ Sets the \a state of the operation object. This should be done by
+ the network protocol during processing; at the end it should be
+ set to TQNetworkProtocol::StDone or TQNetworkProtocol::StFailed,
+ depending on success or failure.
+
+ \sa TQNetworkProtocol::State
+*/
+
+void TQNetworkOperation::setState( TQNetworkProtocol::State state )
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ d->state = state;
+}
+
+/*!
+ If the operation failed, the error message can be specified as \a
+ detail.
+*/
+
+void TQNetworkOperation::setProtocolDetail( const TQString &detail )
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ d->protocolDetail = detail;
+}
+
+/*!
+ Sets the error code to \a ec.
+
+ If the operation failed, the protocol should set an error code to
+ describe the error in more detail. If possible, one of the error
+ codes defined in TQNetworkProtocol should be used.
+
+ \sa setProtocolDetail() TQNetworkProtocol::Error
+*/
+
+void TQNetworkOperation::setErrorCode( int ec )
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ d->errorCode = ec;
+}
+
+/*!
+ Sets the network operation's \a{num}-th argument to \a arg.
+*/
+
+void TQNetworkOperation::setArg( int num, const TQString &arg )
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ d->args[ num ] = arg;
+}
+
+/*!
+ Sets the network operation's \a{num}-th raw data argument to \a arg.
+*/
+
+void TQNetworkOperation::setRawArg( int num, const TQByteArray &arg )
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ d->rawArgs[ num ] = arg;
+}
+
+/*!
+ Returns the type of the operation.
+*/
+
+TQNetworkProtocol::Operation TQNetworkOperation::operation() const
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ return d->operation;
+}
+
+/*!
+ Returns the state of the operation. You can determine whether an
+ operation is still waiting to be processed, is being processed,
+ has been processed successfully, or failed.
+*/
+
+TQNetworkProtocol::State TQNetworkOperation::state() const
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ return d->state;
+}
+
+/*!
+ Returns the operation's \a{num}-th argument. If this argument was
+ not already set, an empty string is returned.
+*/
+
+TQString TQNetworkOperation::arg( int num ) const
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ return d->args[ num ];
+}
+
+/*!
+ Returns the operation's \a{num}-th raw data argument. If this
+ argument was not already set, an empty bytearray is returned.
+*/
+
+TQByteArray TQNetworkOperation::rawArg( int num ) const
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ return d->rawArgs[ num ];
+}
+
+/*!
+ Returns a detailed error message for the last error. This must
+ have been set using setProtocolDetail().
+*/
+
+TQString TQNetworkOperation::protocolDetail() const
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ return d->protocolDetail;
+}
+
+/*!
+ Returns the error code for the last error that occurred.
+*/
+
+int TQNetworkOperation::errorCode() const
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ return d->errorCode;
+}
+
+/*!
+ \internal
+*/
+
+TQByteArray& TQNetworkOperation::raw( int num ) const
+{
+ if ( d->deleteTimer->isActive() ) {
+ d->deleteTimer->stop();
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+ }
+ return d->rawArgs[ num ];
+}
+
+/*!
+ Sets this object to delete itself when it hasn't been used for one
+ second.
+
+ Because TQNetworkOperation pointers are passed around a lot the
+ TQNetworkProtocol generally does not have enough knowledge to
+ delete these at the correct time. If a TQNetworkProtocol doesn't
+ need an operation any more it will call this function instead.
+
+ Note: you should never need to call the method yourself.
+*/
+
+void TQNetworkOperation::free()
+{
+ d->deleteTimer->start( NETWORK_OP_DELAY );
+}
+
+/*!
+ \internal
+ Internal slot for auto-deletion.
+*/
+
+void TQNetworkOperation::deleteMe()
+{
+ delete this;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqnetworkprotocol.h b/tqtinterface/qt4/src/kernel/tqnetworkprotocol.h
new file mode 100644
index 0000000..e0594a6
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqnetworkprotocol.h
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Definition of TQNetworkProtocol class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQNETWORKPROTOCOL_H
+#define TQNETWORKPROTOCOL_H
+
+#ifndef TQT_H
+#include "tqurlinfo.h"
+#include "tqstring.h"
+#include "tqdict.h"
+#include "tqobject.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_NETWORKPROTOCOL
+
+#if __GNUC__ - 0 > 3
+#pragma GCC system_header
+#endif
+
+class TQNetworkProtocol;
+class TQNetworkOperation;
+class TQTimer;
+class TQUrlOperator;
+class TQNetworkProtocolPrivate;
+template <class T> class TQValueList;
+
+class TQ_EXPORT TQNetworkProtocolFactoryBase
+{
+public:
+ virtual TQNetworkProtocol *createObject() = 0;
+
+};
+
+template< class T >
+class TQNetworkProtocolFactory : public TQNetworkProtocolFactoryBase
+{
+public:
+ TQNetworkProtocol *createObject() {
+ return new T;
+ }
+
+};
+
+typedef TQDict< TQNetworkProtocolFactoryBase > TQNetworkProtocolDict;
+
+class TQ_EXPORT TQNetworkProtocol : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ enum State {
+ StWaiting = 0,
+ StInProgress,
+ StDone,
+ StFailed,
+ StStopped
+ };
+
+ enum Operation {
+ OpListChildren = 1,
+ OpMkDir = 2,
+ OpMkdir = OpMkDir, // ### remove in 4.0
+ OpRemove = 4,
+ OpRename = 8,
+ OpGet = 32,
+ OpPut = 64
+ };
+
+ enum ConnectionState {
+ ConHostFound,
+ ConConnected,
+ ConClosed
+ };
+
+ enum Error {
+ // no error
+ NoError = 0,
+ // general errors
+ ErrValid,
+ ErrUnknownProtocol,
+ ErrUnsupported,
+ ErrParse,
+ // errors on connect
+ ErrLoginIncorrect,
+ ErrHostNotFound,
+ // protocol errors
+ ErrListChildren,
+ ErrListChlidren = ErrListChildren, // ### remove in 4.0
+ ErrMkDir,
+ ErrMkdir = ErrMkDir, // ### remove in 4.0
+ ErrRemove,
+ ErrRename,
+ ErrGet,
+ ErrPut,
+ ErrFileNotExisting,
+ ErrPermissionDenied
+ };
+
+ TQNetworkProtocol();
+ virtual ~TQNetworkProtocol();
+
+ virtual void setUrl( TQUrlOperator *u );
+
+ virtual void setAutoDelete( bool b, int i = 10000 );
+ bool autoDelete() const;
+
+ static void registerNetworkProtocol( const TQString &protocol,
+ TQNetworkProtocolFactoryBase *protocolFactory );
+ static TQNetworkProtocol *getNetworkProtocol( const TQString &protocol );
+ static bool hasOnlyLocalFileSystem();
+
+ virtual int supportedOperations() const;
+ virtual void addOperation( TQNetworkOperation *op );
+
+ TQUrlOperator *url() const;
+ TQNetworkOperation *operationInProgress() const;
+ virtual void clearOperationQueue();
+ virtual void stop();
+
+Q_SIGNALS:
+ void data( const TQByteArray &, TQNetworkOperation *res );
+ void connectionStateChanged( int state, const TQString &data );
+ void finished( TQNetworkOperation *res );
+ void start( TQNetworkOperation *res );
+ void newChildren( const TQValueList<TQUrlInfo> &, TQNetworkOperation *res );
+ void newChild( const TQUrlInfo &, TQNetworkOperation *res );
+ void createdDirectory( const TQUrlInfo &, TQNetworkOperation *res );
+ void removed( TQNetworkOperation *res );
+ void itemChanged( TQNetworkOperation *res );
+ void dataTransferProgress( int bytesDone, int bytesTotal, TQNetworkOperation *res );
+
+protected:
+ virtual void processOperation( TQNetworkOperation *op );
+ virtual void operationListChildren( TQNetworkOperation *op );
+ virtual void operationMkDir( TQNetworkOperation *op );
+ virtual void operationRemove( TQNetworkOperation *op );
+ virtual void operationRename( TQNetworkOperation *op );
+ virtual void operationGet( TQNetworkOperation *op );
+ virtual void operationPut( TQNetworkOperation *op );
+ virtual void operationPutChunk( TQNetworkOperation *op );
+ virtual bool checkConnection( TQNetworkOperation *op );
+
+private:
+ TQNetworkProtocolPrivate *d;
+
+private Q_SLOTS:
+ void processNextOperation( TQNetworkOperation *old );
+ void startOps();
+ void emitNewChildren( const TQUrlInfo &i, TQNetworkOperation *op );
+
+ void removeMe();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQNetworkProtocol( const TQNetworkProtocol & );
+ TQNetworkProtocol &operator=( const TQNetworkProtocol & );
+#endif
+};
+
+class TQNetworkOperationPrivate;
+
+class TQ_EXPORT TQNetworkOperation : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+ friend class TQUrlOperator;
+
+public:
+ TQNetworkOperation( TQNetworkProtocol::Operation operation,
+ const TQString &arg0, const TQString &arg1,
+ const TQString &arg2 );
+ TQNetworkOperation( TQNetworkProtocol::Operation operation,
+ const TQByteArray &arg0, const TQByteArray &arg1,
+ const TQByteArray &arg2 );
+ ~TQNetworkOperation();
+
+ void setState( TQNetworkProtocol::State state );
+ void setProtocolDetail( const TQString &detail );
+ void setErrorCode( int ec );
+ void setArg( int num, const TQString &arg );
+ void setRawArg( int num, const TQByteArray &arg );
+
+ TQNetworkProtocol::Operation operation() const;
+ TQNetworkProtocol::State state() const;
+ TQString arg( int num ) const;
+ TQByteArray rawArg( int num ) const;
+ TQString protocolDetail() const;
+ int errorCode() const;
+
+ void free();
+
+private Q_SLOTS:
+ void deleteMe();
+
+private:
+ TQByteArray &raw( int num ) const;
+ TQNetworkOperationPrivate *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQNetworkOperation( const TQNetworkOperation & );
+ TQNetworkOperation &operator=( const TQNetworkOperation & );
+#endif
+};
+
+#endif // TQT_NO_NETWORKPROTOCOL
+
+#endif // TQNETWORKPROTOCOL_H
diff --git a/tqtinterface/qt4/src/kernel/tqobject.cpp b/tqtinterface/qt4/src/kernel/tqobject.cpp
new file mode 100644
index 0000000..9bec024
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqobject.cpp
@@ -0,0 +1,3666 @@
+/****************************************************************************
+**
+** Implementation of TQObject class
+**
+****************************************************************************/
+
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+#include "tqobject.h"
+#include "tqwidget.h"
+
+#include "tqvariant.h"
+#include "tqapplication.h"
+#include "tqobject.h"
+#include "tqobjectlist.h"
+#include "tqsignalslotimp.h"
+#include "tqregexp.h"
+#include "tqmetaobject.h"
+#include <private/tqucom_p.h>
+#include "tqucomextra_p.h"
+#include "tqptrvector.h"
+#include "tqlayout.h"
+#include <Qt/qabstracteventdispatcher.h>
+
+#ifdef TQT_THREAD_SUPPORT
+#include <tqmutex.h>
+#include <private/tqmutexpool_p.h>
+#endif
+
+#include <ctype.h>
+
+// Event functions, implemented in qapplication_xxx.cpp
+
+// int qStartTimer( int interval, TQObject *obj );
+// bool tqKillTimer( int id );
+// bool tqKillTimer( TQObject *obj );
+
+#ifndef TQT_NO_USERDATA
+class TQObjectPrivate : public TQPtrVector<TQObjectUserData>
+{
+public:
+ TQObjectPrivate( uint s ) : TQPtrVector<TQObjectUserData>(s){ setAutoDelete( TRUE ); }
+};
+#else
+class TQObjectPrivate {
+}
+#endif
+
+class TQSenderObjectList : public TQObjectList, public TQShared
+{
+public:
+ TQSenderObjectList() : currentSender( 0 ) { }
+ TQObject *currentSender;
+};
+
+/*!
+ \class TQt tqnamespace.h
+
+ \brief The TQt class is a namespace for miscellaneous identifiers
+ that need to be global-like.
+
+ \ingroup misc
+
+ Normally, you can ignore this class. TQObject and a few other
+ classes inherit it, so all the identifiers in the TQt namespace are
+ normally usable without qualification.
+
+ However, you may occasionally need to say \c TQt::black instead of
+ just \c black, particularly in static utility functions (such as
+ many class factories).
+
+*/
+
+TQObject::TQObject( TQT_BASE_OBJECT_NAME *tqparent, const char *name ) : TQT_BASE_OBJECT_NAME ( tqparent ) {
+ setObjectName(QString::fromAscii(name));
+ TQT_TQOBJECT_REQUIRED_INITIALIZATION(tqparent)
+}
+
+const char * TQObject::name(const char *defaultName) const {
+ TQString s = objectName();
+ return s.isEmpty()?defaultName:s.latin1_helper();
+}
+
+void TQObject::insertChild( TQObject *object ) {
+ TQChildEvent *e = new TQChildEvent( (QEvent::Type)TQEvent::ChildInserted, object );
+ QApplication::postEvent( this, e );
+ object->setParent(this);
+}
+
+void TQObject::removeChild( TQObject *object ) {
+ object->setParent(0);
+}
+
+void TQObject::setName(const char *aName) {
+ setObjectName(aName);
+}
+
+TQVariant TQObject::property( const char *name ) const {
+ return TQT_TQVARIANT_OBJECT(TQT_BASE_OBJECT_NAME::property(name));
+}
+
+// Qt4 handler interface
+bool TQObject::eventFilter( QObject *q, QEvent *e ) {
+ return eventFilter(static_cast<TQObject*>(q), static_cast<TQEvent*>(e));
+}
+
+bool TQObject::event( QEvent *e ) {
+ return event(static_cast<TQEvent*>(e));
+}
+
+bool TQObject::checkConnectArgs(const char *signal, const TQT_BASE_OBJECT_NAME*, const char *member) {
+ return QMetaObject::checkConnectArgs(signal, member);
+}
+
+void TQObject::timerEvent(QTimerEvent *e) {
+ timerEvent(static_cast<TQTimerEvent*>(e));
+}
+
+void TQObject::childEvent(QChildEvent *e) {
+ TQT_TQOBJECT_CHILDEVENT_CONDITIONAL childEvent(static_cast<TQChildEvent*>(e));
+}
+
+void TQObject::customEvent(QEvent *e) {
+ customEvent(static_cast<TQCustomEvent*>(e));
+}
+
+// [FIXME]
+// Verify that this is truly equivalent to its Qt3 counterpart!
+void TQObject::activate_signal( int signal ) {
+ QMetaMethod method = metaObject()->method(signal);
+ method.invoke(this, Qt::QueuedConnection);
+}
+
+void TQObject::tqt_handle_qt_destroyed(QObject* obj) {
+ emit destroyed(TQT_TQOBJECT(obj));
+}
+
+bool TQObject::tqsignalsBlocked() const {
+ return signalsBlocked();
+}
+
+/*!
+ \enum Orientation
+
+ This type is used to signify an object's orientation.
+
+ \value Horizontal
+ \value Vertical
+
+ Orientation is used with TQScrollBar for example.
+*/
+
+// See http://doc.trolltech.com/4.0/porting4.html#qobject
+// [FIXME] Yet ANOTHER feature missing in Qt4...kinda gets old doesn't it?
+// Just think of having to "fix" it 50 times in the Trinity source code (without TQt), each and every time the Qt API changes!
+
+const TQObjectList *objectTrees() {
+ printf("[WARNING] static const TQObjectList *objectTrees() unimplemented\n\r");
+ return 0;
+}
+
+const TQObjectList TQObject::objectTreesListObject() {
+ printf("[WARNING] const TQObjectList *objectTreesListObject() unimplemented\n\r");
+ return TQObjectList();
+}
+
+TQObject *TQObject::tqparent() const {
+ return static_cast<TQObject*>(parent());
+}
+
+TQObjectList TQObject::childrenListObject() {
+ QObjectList qlr;
+ TQObjectList tqt_tqobject_list;
+ qlr = this->children();
+ tqt_tqobject_list.clear();
+ for (int i = 0; i < qlr.size(); ++i) {
+ tqt_tqobject_list.append(static_cast<TQObject*>(qlr.at(i)));
+ }
+ return tqt_tqobject_list;
+}
+
+const TQObjectList TQObject::childrenListObject() const {
+ QObjectList qlr;
+ TQObjectList tqt_tqobject_list;
+ qlr = this->children();
+ tqt_tqobject_list.clear();
+ for (int i = 0; i < qlr.size(); ++i) {
+ tqt_tqobject_list.append(static_cast<TQObject*>(qlr.at(i)));
+ }
+ return tqt_tqobject_list;
+}
+
+const char *TQObject::tqname() const {
+ if (dynamic_cast<const TQObject*>(static_cast<const QObject*>(this))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ if (dynamic_cast<const TQWidget*>(static_cast<const QWidget*>(static_cast<const QObject*>(this)))) {
+ return TQT_TQWIDGET_CONST(this)->tqname();
+ }
+ else if (dynamic_cast<const TQLayout*>(static_cast<const QLayout*>(static_cast<const QObject*>(this)))) {
+ return dynamic_cast<const TQLayout*>(static_cast<const QLayout*>(static_cast<const QObject*>(this)))->tqname();
+ }
+ else if (dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))) {
+ return dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))->tqname();
+ }
+ printf("[WARNING] Attempted to call TQObject::tqname() on an object without a constructed TQObject object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+const char *TQObject::name() const {
+ if (dynamic_cast<const TQObject*>(static_cast<const QObject*>(this))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ if (dynamic_cast<const TQWidget*>(static_cast<const QWidget*>(static_cast<const QObject*>(this)))) {
+ return TQT_TQWIDGET_CONST(this)->name();
+ }
+ else if (dynamic_cast<const TQLayout*>(static_cast<const QLayout*>(static_cast<const QObject*>(this)))) {
+ return dynamic_cast<const TQLayout*>(static_cast<const QLayout*>(static_cast<const QObject*>(this)))->name();
+ }
+ else if (dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))) {
+ return dynamic_cast<const TQApplication*>(static_cast<const QApplication*>(static_cast<const QObject*>(this)))->name();
+ }
+ printf("[WARNING] Attempted to call TQObject::name() on an object without a constructed TQObject object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+/*! \internal
+ TQT_BASE_OBJECT_NAME::child is compat but needs to call itself recursively,
+ that's why we need this helper.
+*/
+static TQT_BASE_OBJECT_NAME *qChildHelper(const char *objName, const char *inheritsClass,
+ bool recursiveSearch, const QObjectList &children)
+{
+ if (children.isEmpty())
+ return 0;
+
+ bool onlyWidgets = (inheritsClass && qstrcmp(inheritsClass, "QWidget") == 0);
+ const QLatin1String oName(objName);
+ for (int i = 0; i < children.size(); ++i) {
+ TQT_BASE_OBJECT_NAME *obj = children.at(i);
+ if (onlyWidgets) {
+ if (obj->isWidgetType() && (!objName || obj->objectName() == oName))
+ return obj;
+ } else if ((!inheritsClass || obj->inherits(inheritsClass))
+ && (!objName || obj->objectName() == oName))
+ return obj;
+ if (recursiveSearch && (obj = qChildHelper(objName, inheritsClass,
+ recursiveSearch, obj->children())))
+ return obj;
+ }
+ return 0;
+}
+
+TQObject *TQObject::child( const char *objName, const char *inheritsClass, bool recursiveSearch ) {
+ return static_cast<TQObject*>(qChildHelper(objName, inheritsClass, recursiveSearch, children()));
+}
+
+#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+/*
+ Preliminary signal spy
+ */
+TQ_EXPORT TQObject* qt_preliminary_signal_spy = 0;
+static TQObject* qt_spy_signal_sender = 0;
+
+// static void qt_spy_signal( TQObject* sender, int signal, TQUObject* o )
+// {
+// QMetaObject* mo = sender->metaObject();
+// while ( mo && signal - mo->signalOffset() < 0 )
+// mo = mo->superClass();
+// if ( !mo )
+// return;
+// const TQMetaData* sigData = mo->signal( signal - mo->signalOffset() );
+// if ( !sigData )
+// return;
+// TQCString s;
+// mo = sender->tqmetaObject();
+// while ( mo ) {
+// s.sprintf( "%s_%s", mo->className(), sigData->name );
+// int slot = qt_preliminary_signal_spy->tqmetaObject()->tqfindSlot( s, TRUE );
+// if ( slot >= 0 ) {
+// #ifdef TQT_THREAD_SUPPORT
+// // protect access to qt_spy_signal_sender
+// void * const address = &qt_spy_signal_sender;
+// TQMutexLocker locker( tqt_global_mutexpool ?
+// tqt_global_mutexpool->get( address ) : 0 );
+// #endif // TQT_THREAD_SUPPORT
+//
+// TQObject* old_sender = qt_spy_signal_sender;
+// qt_spy_signal_sender = sender;
+// qt_preliminary_signal_spy->qt_invoke( slot, o );
+// qt_spy_signal_sender = old_sender;
+// break;
+// }
+// mo = mo->superClass();
+// }
+// }
+
+/*
+ End Preliminary signal spy
+ */
+#endif // TQT_NO_PRELIMINARY_SIGNAL_SPY
+
+//
+// Remove white space from TQT_SIGNAL and TQT_SLOT names.
+// Internal for TQObject::connect() and TQObject::disconnect()
+//
+
+static inline bool isIdentChar( char x )
+{ // Avoid bug in isalnum
+ return x == '_' || (x >= '0' && x <= '9') ||
+ (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z');
+}
+
+static inline bool isSpace( char x )
+{
+#if defined(TQ_CC_BOR)
+ /*
+ Borland C++ 4.5 has a weird isspace() bug.
+ isspace() usually works, but not here.
+ This implementation is sufficient for our internal use: rmWS()
+ */
+ return (uchar) x <= 32;
+#else
+ return isspace( (uchar) x );
+#endif
+}
+
+static TQCString qt_rmWS( const char *s )
+{
+ TQCString result( tqstrlen(s)+1 );
+ char *d = result.data();
+ char last = 0;
+ while( *s && isSpace(*s) ) // skip leading space
+ s++;
+ while ( *s ) {
+ while ( *s && !isSpace(*s) )
+ last = *d++ = *s++;
+ while ( *s && isSpace(*s) )
+ s++;
+ if ( *s && isIdentChar(*s) && isIdentChar(last) )
+ last = *d++ = ' ';
+ }
+ *d = '\0';
+ result.truncate( (int)(d - result.data()) );
+ int void_pos = result.tqfind("(void)");
+ if ( void_pos >= 0 )
+ result.remove( void_pos+1, (uint)strlen("void") );
+ return result;
+}
+
+TQConnectionList *TQObject::tqreceivers( const char* signal ) const
+{
+ TQConnectionList* clist = new TQConnectionList;
+ clist->setAutoDelete( TRUE );
+ if (receivers(signal) > 0) {
+ printf("[WARNING] TQConnectionList *TQObject::tqreceivers( const char* signal ) is UNIMPLEMENTED and connected signals were detected!\n\r");
+ }
+ return clist;
+}
+
+TQConnectionList *TQObject::tqreceivers( int signal ) const
+{
+ TQConnectionList* clist = new TQConnectionList;
+ clist->setAutoDelete( TRUE );
+ printf("[WARNING] TQConnectionList *TQObject::tqreceivers( int signal ) const UNIMPLEMENTED\n\r");
+ return clist;
+}
+
+/*! \internal
+
+ Returns a list of objects/slot pairs that are connected to the
+ \a signal, or 0 if nothing is connected to it.
+*/
+
+// TQConnectionList *TQObject::tqreceivers( const char* signal ) const
+// {
+// if ( connections && signal ) {
+// if ( *signal == '2' ) { // tag == 2, i.e. signal
+// TQCString s = qt_rmWS( signal+1 );
+// return tqreceivers( metaObject()->indexOfSignal( (const char*)s ) );
+// } else {
+// return tqreceivers( metaObject()->indexOfSignal(signal ) );
+// }
+// }
+// return 0;
+// }
+
+/*! \internal
+
+ Returns a list of objects/slot pairs that are connected to the
+ signal, or 0 if nothing is connected to it.
+*/
+
+// TQConnectionList *TQObject::tqreceivers( int signal ) const
+// {
+// #ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+// if ( qt_preliminary_signal_spy && signal >= 0 ) {
+// if ( !connections ) {
+// TQObject* that = (TQObject*) this;
+// that->connections = new TQSignalVec( signal+1 );
+// that->connections->setAutoDelete( TRUE );
+// }
+// if ( !connections->at( signal ) ) {
+// TQConnectionList* clist = new TQConnectionList;
+// clist->setAutoDelete( TRUE );
+// connections->insert( signal, clist );
+// return clist;
+// }
+// }
+// #endif
+// if ( connections && signal >= 0 )
+// return connections->at( signal );
+// return 0;
+// }
+
+#if 0
+
+/*!
+ \internal
+
+ Signal activation with the most frequently used parameter/argument
+ types. All other combinations are generated by the meta object
+ compiler.
+ */
+void TQObject::activate_signal( int signal )
+{
+#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+ if ( qt_preliminary_signal_spy ) {
+ if ( !tqsignalsBlocked() && signal >= 0 &&
+ ( !connections || !connections->at( signal ) ) ) {
+ TQUObject o[1];
+ qt_spy_signal( this, signal, o );
+ return;
+ }
+ }
+#endif
+
+ if ( !connections || tqsignalsBlocked() || signal < 0 )
+ return;
+ TQConnectionList *clist = connections->at( signal );
+ if ( !clist )
+ return;
+ TQUObject o[1];
+ activate_signal( clist, o );
+}
+
+#endif
+
+/*! \internal */
+
+void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o )
+{
+ if ( !clist )
+ return;
+
+// #ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+// if ( qt_preliminary_signal_spy )
+// qt_spy_signal( this, connections->tqfindRef( clist), o );
+// #endif
+
+ TQObject *object;
+ TQSenderObjectList* sol;
+ TQObject* oldSender = 0;
+ TQConnection *c;
+ if ( clist->count() == 1 ) { // save iterator
+ c = clist->first();
+ object = c->object();
+ sol = object->senderObjects;
+ if ( sol ) {
+ oldSender = sol->currentSender;
+ sol->ref();
+ sol->currentSender = this;
+ }
+ if ( c->memberType() == TQSIGNAL_CODE ) {
+// object->qt_emit( c->member(), o );
+ QMetaMethod method = metaObject()->method(c->member());
+ method.invoke(this, Qt::QueuedConnection);
+ }
+ else {
+// object->qt_invoke( c->member(), o );
+ QMetaMethod method = metaObject()->method(c->member());
+ method.invoke(this, Qt::QueuedConnection);
+ }
+ if ( sol ) {
+ sol->currentSender = oldSender;
+ if ( sol->deref() )
+ delete sol;
+ }
+ } else {
+ TQConnection *cd = 0;
+ TQConnectionListIt it(*clist);
+ while ( (c=it.current()) ) {
+ ++it;
+ if ( c == cd )
+ continue;
+ cd = c;
+ object = c->object();
+ sol = object->senderObjects;
+ if ( sol ) {
+ oldSender = sol->currentSender;
+ sol->ref();
+ sol->currentSender = this;
+ }
+ if ( c->memberType() == TQSIGNAL_CODE ) {
+// object->qt_emit( c->member(), o );
+ QMetaMethod method = metaObject()->method(c->member());
+ method.invoke(this, Qt::QueuedConnection);
+ }
+ else {
+// object->qt_invoke( c->member(), o );
+ QMetaMethod method = metaObject()->method(c->member());
+ method.invoke(this, Qt::QueuedConnection);
+ }
+ if (sol ) {
+ sol->currentSender = oldSender;
+ if ( sol->deref() )
+ delete sol;
+ }
+ }
+ }
+}
+
+/*!
+ \overload void TQObject::activate_signal( int signal, int )
+*/
+
+/*!
+ \overload void TQObject::activate_signal( int signal, double )
+*/
+
+/*!
+ \overload void TQObject::activate_signal( int signal, TQString )
+*/
+
+/*!
+ \fn void TQObject::activate_signal_bool( int signal, bool )
+ \internal
+
+ Like the above functions, but since bool is sometimes
+ only a typedef it cannot be a simple overload.
+*/
+
+// #ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+// #define ACTIVATE_SIGNAL_WITH_PARAM(FNAME,TYPE) \
+// void TQObject::FNAME( int signal, TYPE param ) \
+// { \
+// if ( qt_preliminary_signal_spy ) { \
+// if ( !tqsignalsBlocked() && signal >= 0 && \
+// ( !connections || !connections->at( signal ) ) ) { \
+// TQUObject o[2]; \
+// static_TQUType_##TYPE.set( o+1, param ); \
+// qt_spy_signal( this, signal, o ); \
+// return; \
+// } \
+// } \
+// if ( !connections || tqsignalsBlocked() || signal < 0 ) \
+// return; \
+// TQConnectionList *clist = connections->at( signal ); \
+// if ( !clist ) \
+// return; \
+// TQUObject o[2]; \
+// static_TQUType_##TYPE.set( o+1, param ); \
+// activate_signal( clist, o ); \
+// }
+// #else
+// #define ACTIVATE_SIGNAL_WITH_PARAM(FNAME,TYPE) \
+// void TQObject::FNAME( int signal, TYPE param ) \
+// { \
+// if ( !connections || tqsignalsBlocked() || signal < 0 ) \
+// return; \
+// TQConnectionList *clist = connections->at( signal ); \
+// if ( !clist ) \
+// return; \
+// TQUObject o[2]; \
+// static_TQUType_##TYPE.set( o+1, param ); \
+// activate_signal( clist, o ); \
+// }
+//
+// #endif
+// // We don't want to duplicate too much text so...
+//
+// ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, int )
+// ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, double )
+// ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, TQString )
+// ACTIVATE_SIGNAL_WITH_PARAM( activate_signal_bool, bool )
+
+static void objSearch( TQObjectList *result,
+ TQObjectList *list,
+ const char *inheritsClass,
+ bool onlyWidgets,
+ const char *objName,
+ TQRegExp *rx,
+ bool recurse )
+{
+ if ( !list || list->isEmpty() ) // nothing to search
+ return;
+ TQObject *obj = list->first();
+ while ( obj ) {
+ bool ok = TRUE;
+ if ( onlyWidgets )
+ ok = obj->isWidgetType();
+ else if ( inheritsClass && !obj->inherits(inheritsClass) )
+ ok = FALSE;
+ if ( ok ) {
+ if ( objName )
+ ok = ( qstrcmp(objName,obj->name()) == 0 );
+#ifndef TQT_NO_REGEXP
+ else if ( rx )
+ ok = ( rx->search(TQString::tqfromLatin1(obj->name())) != -1 );
+#endif
+ }
+ if ( ok ) // match!
+ result->append( obj );
+ if ( recurse && !obj->childrenListObject().isEmpty() ) {
+ TQObjectList tqlist = obj->childrenListObject();
+ objSearch( result, &tqlist, inheritsClass,
+ onlyWidgets, objName, rx, recurse );
+ }
+ obj = list->next();
+ }
+}
+
+/*!
+ Searches the tqchildren and optionally grandtqchildren of this object,
+ and returns a list of those objects that are named or that match
+ \a objName and inherit \a inheritsClass. If \a inheritsClass is 0
+ (the default), all classes match. If \a objName is 0 (the
+ default), all object names match.
+
+ If \a regexpMatch is TRUE (the default), \a objName is a regular
+ expression that the objects's names must match. The syntax is that
+ of a TQRegExp. If \a regexpMatch is FALSE, \a objName is a string
+ and object names must match it exactly.
+
+ Note that \a inheritsClass uses single inheritance from TQObject,
+ the way inherits() does. According to inherits(), TQMenuBar
+ inherits TQWidget but not TQMenuData. This does not quite match
+ reality, but is the best that can be done on the wide variety of
+ compilers TQt supports.
+
+ Finally, if \a recursiveSearch is TRUE (the default), queryList()
+ searches \e{n}th-generation as well as first-generation tqchildren.
+
+ If all this seems a bit complex for your needs, the simpler
+ child() function may be what you want.
+
+ This somewhat contrived example disables all the buttons in this
+ window:
+ \code
+ TQObjectList *l = tqtopLevelWidget()->queryList( "TQButton" );
+ TQObjectListIt it( *l ); // iterate over the buttons
+ TQObject *obj;
+
+ while ( (obj = it.current()) != 0 ) {
+ // for each found object...
+ ++it;
+ ((TQButton*)obj)->setEnabled( FALSE );
+ }
+ delete l; // delete the list, not the objects
+ \endcode
+
+ The TQObjectList class is defined in the \c tqobjectlist.h header
+ file.
+
+ \warning Delete the list as soon you have finished using it. The
+ list tqcontains pointers that may become invalid at almost any time
+ without notice (as soon as the user closes a window you may have
+ dangling pointers, for example).
+
+ \sa child() childrenListObject(), tqparent(), inherits(), name(), TQRegExp
+*/
+
+TQObjectList *TQObject::queryList( const char *inheritsClass,
+ const char *objName,
+ bool regexpMatch,
+ bool recursiveSearch ) const
+{
+ TQObjectList *list = new TQObjectList;
+ TQ_CHECK_PTR( list );
+ bool onlyWidgets = ( inheritsClass && qstrcmp(inheritsClass, "TQWidget") == 0 );
+#ifndef TQT_NO_REGEXP
+ if ( regexpMatch && objName ) { // regexp matching
+ TQRegExp rx(TQString::tqfromLatin1(objName));
+ TQObjectList tqlist = childrenListObject();
+ objSearch( list, &tqlist, inheritsClass, onlyWidgets,
+ 0, &rx, recursiveSearch );
+ } else
+#endif
+ {
+ TQObjectList tqlist = childrenListObject();
+ objSearch( list, &tqlist, inheritsClass, onlyWidgets,
+ objName, 0, recursiveSearch );
+ }
+ return list;
+}
+
+/*!
+ Normlizes the signal or slot definition \a signalSlot by removing
+ unnecessary whitespace.
+*/
+
+TQCString TQObject::normalizeSignalSlot( const char *signalSlot )
+{
+ if ( !signalSlot )
+ return TQCString();
+ return qt_rmWS( signalSlot );
+}
+
+TQMetaObject *TQObject::tqmetaObject() const {
+ return const_cast<TQMetaObject*>(static_cast<const TQMetaObject*>(metaObject()));
+}
+
+// TQMetaObject* TQObject::tqstaticMetaObject()
+// {
+// return const_cast<TQMetaObject*>(static_cast<const TQMetaObject*>(&TQT_BASE_OBJECT_NAME::staticMetaObject));
+// }
+
+TQMetaObject* tqstaticMetaObject_helper(const QMetaObject* mobj)
+{
+ return const_cast<TQMetaObject*>(static_cast<const TQMetaObject*>(mobj));
+}
+
+/*!
+ This virtual function receives events to an object and should
+ return TRUE if the event \a e was recognized and processed.
+
+ The event() function can be reimplemented to customize the
+ behavior of an object.
+
+ \sa installEventFilter(), timerEvent(), TQApplication::sendEvent(),
+ TQApplication::postEvent(), TQWidget::event()
+*/
+
+bool TQObject::event( TQEvent *e )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( e == 0 )
+ qWarning( "TQObject::event: Null events are not permitted" );
+#endif
+// if ( eventFilters ) { // try filters
+// if ( activate_filters(e) ) // stopped by a filter
+// return TRUE;
+// }
+//
+ switch ( e->type() ) {
+// case TQEvent::Timer:
+// timerEvent( (TQTimerEvent*)e );
+// return TRUE;
+//
+// case TQEvent::DeferredDelete:
+// delete this;
+// return TRUE;
+//
+// default:
+// if ( e->type() >= TQEvent::User ) {
+// customEvent( (TQCustomEvent*) e );
+// return TRUE;
+// }
+// break;
+// }
+
+ case TQEvent::ChildInserted:
+// case TQEvent::ChildRemoved: // Causes a recursion loop if uncommented
+ childEvent( (TQChildEvent*)e );
+ return TRUE;
+
+ default:
+ return QObject::event(e);
+ }
+
+ return FALSE;
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ timer events for the object.
+
+ TQTimer provides a higher-level interface to the timer
+ functionality, and also more general information about timers.
+
+ \sa startTimer(), killTimer(), killTimers(), event()
+*/
+
+void TQObject::timerEvent( TQTimerEvent * )
+{
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ child events.
+
+ Child events are sent to objects when tqchildren are inserted or
+ removed.
+
+ Note that events with TQEvent::type() \c TQEvent::ChildInserted are
+ posted (with \l{TQApplication::postEvent()}) to make sure that the
+ child's construction is completed before this function is called.
+
+ If a child is removed immediately after it is inserted, the \c
+ ChildInserted event may be suppressed, but the \c ChildRemoved
+ event will always be sent. In such cases it is possible that there
+ will be a \c ChildRemoved event without a corresponding \c
+ ChildInserted event.
+
+ If you change state based on \c ChildInserted events, call
+ TQWidget::constPolish(), or do
+ \code
+ TQApplication::sendPostedEvents( this, TQEvent::ChildInserted );
+ \endcode
+ in functions that depend on the state. One notable example is
+ TQWidget::tqsizeHint().
+
+ \sa event(), TQChildEvent
+*/
+
+void TQObject::childEvent( TQChildEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ custom events. Custom events are user-defined events with a type
+ value at least as large as the "User" item of the \l TQEvent::Type
+ enum, and is typically a TQCustomEvent or TQCustomEvent subclass.
+
+ \sa event(), TQCustomEvent
+*/
+void TQObject::customEvent( TQCustomEvent * )
+{
+}
+
+/*!
+ Filters events if this object has been installed as an event
+ filter for the \a watched object.
+
+ In your reimplementation of this function, if you want to filter
+ the event \a e, out, i.e. stop it being handled further, return
+ TRUE; otherwise return FALSE.
+
+ Example:
+ \code
+ class MyMainWindow : public TQMainWindow
+ {
+ public:
+ MyMainWindow( TQWidget *tqparent = 0, const char *name = 0 );
+
+ protected:
+ bool eventFilter( TQObject *obj, TQEvent *ev );
+
+ private:
+ TQTextEdit *textEdit;
+ };
+
+ MyMainWindow::MyMainWindow( TQWidget *tqparent, const char *name )
+ : TQMainWindow( tqparent, name )
+ {
+ textEdit = new TQTextEdit( this );
+ setCentralWidget( textEdit );
+ textEdit->installEventFilter( this );
+ }
+
+ bool MyMainWindow::eventFilter( TQObject *obj, TQEvent *ev )
+ {
+ if ( obj == textEdit ) {
+ if ( e->type() == TQEvent::KeyPress ) {
+ TQKeyEvent *k = (TQKeyEvent*)ev;
+ qDebug( "Ate key press %d", k->key() );
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else {
+ // pass the event on to the tqparent class
+ return TQMainWindow::eventFilter( obj, ev );
+ }
+ }
+ \endcode
+
+ Notice in the example above that unhandled events are passed to
+ the base class's eventFilter() function, since the base class
+ might have reimplemented eventFilter() for its own internal
+ purposes.
+
+ \warning If you delete the receiver object in this function, be
+ sure to return TRUE. Otherwise, TQt will forward the event to the
+ deleted object and the program might crash.
+
+ \sa installEventFilter()
+*/
+
+bool TQObject::eventFilter( TQObject * /* watched */, TQEvent * /* e */ )
+{
+ return FALSE;
+}
+
+/*!
+ \relates TQObject
+
+ Returns a pointer to the object named \a name that inherits \a
+ type and with a given \a tqparent.
+
+ Returns 0 if there is no such child.
+
+ \code
+ TQListBox *c = (TQListBox *) qt_tqfind_obj_child( myWidget, "TQListBox",
+ "my list box" );
+ if ( c )
+ c->insertItem( "another string" );
+ \endcode
+*/
+
+void *qt_tqfind_obj_child( TQObject *tqparent, const char *type, const char *name )
+{
+ if ( !tqparent->childrenListObject().isEmpty() ) {
+ TQObjectListIt it( tqparent->childrenListObject() );
+ TQObject *obj;
+ while ( (obj = it.current()) ) {
+ ++it;
+ if ( qstrcmp(name,obj->name()) == 0 &&
+ obj->inherits(type) )
+ return obj;
+ }
+ }
+ return 0;
+}
+
+/*!
+ Kills all timers that this object has started.
+
+ \warning Using this function can cause hard-to-find bugs: it kills
+ timers started by sub- and superclasses as well as those started
+ by you, which is often not what you want. We recommend using a
+ TQTimer or perhaps killTimer().
+
+ \sa timerEvent(), startTimer(), killTimer()
+*/
+
+void TQObject::killTimers()
+{
+ QAbstractEventDispatcher *qed = QAbstractEventDispatcher::instance();
+ qed->unregisterTimers(this);
+}
+
+bool TQObject::isA( const char *classname ) const
+{
+ if (tqstrcmp(classname, metaObject()->className()) == 0) return true;
+ else {
+ TQString cn = metaObject()->className();
+ if (cn[0] == 'T')
+ cn = cn.remove(0,1);
+ return (tqstrcmp(classname, cn.ascii()) == 0);
+ }
+}
+
+bool TQObject::inherits( const char *classname ) const {
+ if (QObject::inherits(classname)) return true;
+ else {
+ TQString cn = classname;
+ if (cn[0] != 'T')
+ cn = cn.prepend('T');
+ return QObject::inherits(cn.ascii());
+ }
+}
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of TQObject class
+**
+** Created : 930418
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqvariant.h"
+#include "tqapplication.h"
+#include "tqobject.h"
+#include "tqobjectlist.h"
+#include "tqsignalslotimp.h"
+#include "tqregexp.h"
+#include "tqmetaobject.h"
+#include <private/tqucom_p.h>
+#include "tqucomextra_p.h"
+#include "tqptrvector.h"
+
+#ifdef TQT_THREAD_SUPPORT
+#include <tqmutex.h>
+#include <private/tqmutexpool_p.h>
+#endif
+
+#include <ctype.h>
+
+
+#ifndef TQT_NO_USERDATA
+class TQObjectPrivate : public TQPtrVector<TQObjectUserData>
+{
+public:
+ TQObjectPrivate( uint s ) : TQPtrVector<TQObjectUserData>(s){ setAutoDelete( TRUE ); }
+};
+#else
+class TQObjectPrivate {
+}
+#endif
+
+class TQSenderObjectList : public TQObjectList, public TQShared
+{
+public:
+ TQSenderObjectList() : currentSender( 0 ) { }
+ TQObject *currentSender;
+};
+
+/*!
+ \class TQt tqnamespace.h
+
+ \brief The TQt class is a namespace for miscellaneous identifiers
+ that need to be global-like.
+
+ \ingroup misc
+
+ Normally, you can ignore this class. TQObject and a few other
+ classes inherit it, so all the identifiers in the TQt namespace are
+ normally usable without qualification.
+
+ However, you may occasionally need to say \c TQt::black instead of
+ just \c black, particularly in static utility functions (such as
+ many class factories).
+
+*/
+
+/*!
+ \enum Orientation
+
+ This type is used to signify an object's orientation.
+
+ \value Horizontal
+ \value Vertical
+
+ Orientation is used with TQScrollBar for example.
+*/
+
+
+/*!
+ \class TQObject tqobject.h
+ \brief The TQObject class is the base class of all TQt objects.
+
+ \ingroup objectmodel
+ \mainclass
+ \reentrant
+
+ TQObject is the heart of the \link object.html TQt object model.
+ \endlink The central feature in this model is a very powerful
+ mechanism for seamless object communication called \link
+ Q_SIGNALSandQ_SLOTS.html Q_SIGNALS and Q_SLOTS \endlink. You can
+ connect a signal to a slot with connect() and destroy the
+ connection with disconnect(). To avoid never ending notification
+ loops you can temporarily block Q_SIGNALS with blockSignals(). The
+ protected functions connectNotify() and disconnectNotify() make it
+ possible to track connections.
+
+ TQObjects organize themselves in object trees. When you create a
+ TQObject with another object as tqparent, the object will
+ automatically do an insertChild() on the tqparent and thus show up
+ in the tqparent's childrenListObject() list. The tqparent takes ownership of the
+ object i.e. it will automatically delete its tqchildren in its
+ destructor. You can look for an object by name and optionally type
+ using child() or queryList(), and get the list of tree roots using
+ objectTrees().
+
+ Every object has an object name() and can report its className()
+ and whether it inherits() another class in the TQObject inheritance
+ hierarchy.
+
+ When an object is deleted, it emits a destroyed() signal. You can
+ catch this signal to avoid dangling references to TQObjects. The
+ TQGuardedPtr class provides an elegant way to use this feature.
+
+ TQObjects can receive events through event() and filter the events
+ of other objects. See installEventFilter() and eventFilter() for
+ details. A convenience handler, childEvent(), can be reimplemented
+ to catch child events.
+
+ Last but not least, TQObject provides the basic timer support in
+ TQt; see TQTimer for high-level support for timers.
+
+ Notice that the TQ_OBJECT macro is mandatory for any object that
+ implements Q_SIGNALS, Q_SLOTS or properties. You also need to run the
+ \link tqmoc.html tqmoc program (Meta Object Compiler) \endlink on the
+ source file. We strongly recommend the use of this macro in \e all
+ subclasses of TQObject regardless of whether or not they actually
+ use Q_SIGNALS, Q_SLOTS and properties, since failure to do so may lead
+ certain functions to exhibit undefined behaviour.
+
+ All TQt widgets inherit TQObject. The convenience function
+ isWidgetType() returns whether an object is actually a widget. It
+ is much faster than inherits( "TQWidget" ).
+
+ Some TQObject functions, e.g. childrenListObject(), objectTrees() and
+ queryList() return a TQObjectList. A TQObjectList is a TQPtrList of
+ TQObjects. TQObjectLists support the same operations as TQPtrLists
+ and have an iterator class, TQObjectListIt.
+*/
+
+
+//
+// Remove white space from TQT_SIGNAL and TQT_SLOT names.
+// Internal for TQObject::connect() and TQObject::disconnect()
+//
+
+static inline bool isIdentChar( char x )
+{ // Avoid bug in isalnum
+ return x == '_' || (x >= '0' && x <= '9') ||
+ (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z');
+}
+
+static inline bool isSpace( char x )
+{
+#if defined(TQ_CC_BOR)
+ /*
+ Borland C++ 4.5 has a weird isspace() bug.
+ isspace() usually works, but not here.
+ This implementation is sufficient for our internal use: rmWS()
+ */
+ return (uchar) x <= 32;
+#else
+ return isspace( (uchar) x );
+#endif
+}
+
+static TQCString qt_rmWS( const char *s )
+{
+ TQCString result( tqstrlen(s)+1 );
+ char *d = result.data();
+ char last = 0;
+ while( *s && isSpace(*s) ) // skip leading space
+ s++;
+ while ( *s ) {
+ while ( *s && !isSpace(*s) )
+ last = *d++ = *s++;
+ while ( *s && isSpace(*s) )
+ s++;
+ if ( *s && isIdentChar(*s) && isIdentChar(last) )
+ last = *d++ = ' ';
+ }
+ *d = '\0';
+ result.truncate( (int)(d - result.data()) );
+ int void_pos = result.tqfind("(void)");
+ if ( void_pos >= 0 )
+ result.remove( void_pos+1, (uint)strlen("void") );
+ return result;
+}
+
+
+// Event functions, implemented in qapplication_xxx.cpp
+
+int qStartTimer( int interval, TQObject *obj );
+bool qKillTimer( int id );
+bool qKillTimer( TQObject *obj );
+
+static void removeObjFromList( TQObjectList *objList, const TQObject *obj,
+ bool single=FALSE )
+{
+ if ( !objList )
+ return;
+ int index = objList->tqfindRef( obj );
+ while ( index >= 0 ) {
+ objList->remove();
+ if ( single )
+ return;
+ index = objList->tqfindNextRef( obj );
+ }
+}
+
+
+/*!
+ \relates TQObject
+
+ Returns a pointer to the object named \a name that inherits \a
+ type and with a given \a tqparent.
+
+ Returns 0 if there is no such child.
+
+ \code
+ TQListBox *c = (TQListBox *) qt_tqfind_obj_child( myWidget, "TQListBox",
+ "my list box" );
+ if ( c )
+ c->insertItem( "another string" );
+ \endcode
+*/
+
+void *qt_tqfind_obj_child( TQObject *tqparent, const char *type, const char *name )
+{
+ if ( !tqparent->childrenListObject().isEmpty() ) {
+ TQObjectListIt it( tqparent->childrenListObject() );
+ TQObject *obj;
+ while ( (obj = it.current()) ) {
+ ++it;
+ if ( qstrcmp(name,obj->name()) == 0 &&
+ obj->inherits(type) )
+ return obj;
+ }
+ }
+ return 0;
+}
+
+
+
+#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+/*
+ Preliminary signal spy
+ */
+TQ_EXPORT TQObject* qt_preliminary_signal_spy = 0;
+static TQObject* qt_spy_signal_sender = 0;
+
+static void qt_spy_signal( TQObject* sender, int signal, TQUObject* o )
+{
+ TQMetaObject* mo = sender->tqmetaObject();
+ while ( mo && signal - mo->signalOffset() < 0 )
+ mo = mo->superClass();
+ if ( !mo )
+ return;
+ const TQMetaData* sigData = mo->signal( signal - mo->signalOffset() );
+ if ( !sigData )
+ return;
+ TQCString s;
+ mo = sender->tqmetaObject();
+ while ( mo ) {
+ s.sprintf( "%s_%s", mo->className(), sigData->name );
+ int slot = qt_preliminary_signal_spy->tqmetaObject()->tqfindSlot( s, TRUE );
+ if ( slot >= 0 ) {
+#ifdef TQT_THREAD_SUPPORT
+ // protect access to qt_spy_signal_sender
+ void * const address = &qt_spy_signal_sender;
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( address ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+
+ TQObject* old_sender = qt_spy_signal_sender;
+ qt_spy_signal_sender = sender;
+ qt_preliminary_signal_spy->qt_invoke( slot, o );
+ qt_spy_signal_sender = old_sender;
+ break;
+ }
+ mo = mo->superClass();
+ }
+}
+
+/*
+ End Preliminary signal spy
+ */
+#endif // TQT_NO_PRELIMINARY_SIGNAL_SPY
+
+static TQObjectList* object_trees = 0;
+
+#ifdef TQT_THREAD_SUPPORT
+static TQMutex *obj_trees_mutex = 0;
+#endif
+
+static void cleanup_object_trees()
+{
+ delete object_trees;
+ object_trees = 0;
+#ifdef TQT_THREAD_SUPPORT
+ delete obj_trees_mutex;
+ obj_trees_mutex = 0;
+#endif
+}
+
+static void ensure_object_trees()
+{
+ object_trees = new TQObjectList;
+ qAddPostRoutine( cleanup_object_trees );
+}
+
+static void insert_tree( TQObject* obj )
+{
+#ifdef TQT_THREAD_SUPPORT
+ if ( !obj_trees_mutex )
+ obj_trees_mutex = new TQMutex();
+ TQMutexLocker locker( obj_trees_mutex );
+#endif
+ if ( !object_trees )
+ ensure_object_trees();
+ object_trees->insert(0, obj );
+}
+
+static void remove_tree( TQObject* obj )
+{
+ if ( object_trees ) {
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( obj_trees_mutex );
+#endif
+ object_trees->removeRef( obj );
+ }
+}
+
+
+/*****************************************************************************
+ TQObject member functions
+ *****************************************************************************/
+
+/*!
+ Constructs an object called \a name with tqparent object, \a tqparent.
+
+ The tqparent of an object may be viewed as the object's owner. For
+ instance, a \link TQDialog dialog box\endlink is the tqparent of the
+ "OK" and "Cancel" buttons it tqcontains.
+
+ The destructor of a tqparent object destroys all child objects.
+
+ Setting \a tqparent to 0 constructs an object with no tqparent. If the
+ object is a widget, it will become a top-level window.
+
+ The object name is some text that can be used to identify a
+ TQObject. It's particularly useful in conjunction with \link
+ designer-manual.book <i>TQt Designer</i>\endlink. You can tqfind an
+ object by name (and type) using child(). To tqfind several objects
+ use queryList().
+
+ \sa tqparent(), name(), child(), queryList()
+*/
+
+TQObject::TQObject( TQObject *tqparent, const char *name )
+ :
+ isSignal( FALSE ), // assume not a signal object
+ isWidget( FALSE ), // assume not a widget object
+ pendTimer( FALSE ), // no timers yet
+ blockSig( FALSE ), // not blocking Q_SIGNALS
+ wasDeleted( FALSE ), // double-delete catcher
+ isTree( FALSE ), // no tree yet
+ objname( name ? qstrdup(name) : 0 ), // set object name
+ parentObj( 0 ), // no tqparent yet. It is set by insertChild()
+ childObjects( 0 ), // no tqchildren yet
+ connections( 0 ), // no connections yet
+ senderObjects( 0 ), // no Q_SIGNALS connected yet
+ eventFilters( 0 ), // no filters installed
+ postedEvents( 0 ), // no events posted
+ d( 0 )
+{
+ if ( !metaObj ) // will create object dict
+ (void) staticMetaObject();
+
+ if ( tqparent ) { // add object to tqparent
+ tqparent->insertChild( this );
+ } else {
+ insert_tree( this );
+ isTree = TRUE;
+ }
+}
+
+
+/*!
+ Destroys the object, deleting all its child objects.
+
+ All Q_SIGNALS to and from the object are automatically disconnected.
+
+ \warning All child objects are deleted. If any of these objects
+ are on the stack or global, sooner or later your program will
+ crash. We do not recommend holding pointers to child objects from
+ outside the tqparent. If you still do, the TQObject::destroyed()
+ signal gives you an opportunity to detect when an object is
+ destroyed.
+
+ \warning Deleting a TQObject while pending events are waiting to be
+ delivered can cause a crash. You must not delete the TQObject
+ directly from a thread that is not the GUI thread. Use the
+ TQObject::deleteLater() method instead, which will cause the event
+ loop to delete the object after all pending events have been
+ delivered to the object.
+*/
+
+TQObject::~TQObject()
+{
+ if ( wasDeleted ) {
+#if defined(TQT_DEBUG)
+ qWarning( "Double TQObject deletion detected." );
+#endif
+ return;
+ }
+ wasDeleted = 1;
+ blockSig = 0; // unblock Q_SIGNALS to keep TQGuardedPtr happy
+ emit destroyed( this );
+ emit destroyed();
+ if ( objname )
+ delete [] (char*)objname;
+ objname = 0;
+ if ( pendTimer ) // might be pending timers
+ qKillTimer( this );
+ TQApplication::removePostedEvents( this );
+ if ( isTree ) {
+ remove_tree( this ); // remove from global root list
+ isTree = FALSE;
+ }
+ if ( parentObj ) // remove it from tqparent object
+ parentObj->removeChild( this );
+ register TQObject *obj;
+ if ( senderObjects ) { // disconnect from senders
+ TQSenderObjectList *tmp = senderObjects;
+ senderObjects = 0;
+ obj = tmp->first();
+ while ( obj ) { // for all senders...
+ obj->disconnect( this );
+ obj = tmp->next();
+ }
+ if ( tmp->deref() )
+ delete tmp;
+ }
+ if ( connections ) { // disconnect tqreceivers
+ for ( int i = 0; i < (int) connections->size(); i++ ) {
+ TQConnectionList* clist = (*connections)[i]; // for each signal...
+ if ( !clist )
+ continue;
+ register TQConnection *c;
+ TQConnectionListIt cit(*clist);
+ while( (c=cit.current()) ) { // for each connected slot...
+ ++cit;
+ if ( (obj=c->object()) )
+ removeObjFromList( obj->senderObjects, this );
+ }
+ }
+ delete connections;
+ connections = 0;
+ }
+ if ( eventFilters ) {
+ delete eventFilters;
+ eventFilters = 0;
+ }
+ if ( childObjects ) { // delete tqchildren objects
+ TQObjectListIt it(*childObjects);
+ while ( (obj=it.current()) ) {
+ ++it;
+ obj->parentObj = 0;
+ childObjects->removeRef( obj );
+ delete obj;
+ }
+ delete childObjects;
+ }
+
+ delete d;
+}
+
+
+/*!
+ \fn TQMetaObject *TQObject::tqmetaObject() const
+
+ Returns a pointer to the meta object of this object.
+
+ A meta object tqcontains information about a class that inherits
+ TQObject, e.g. class name, superclass name, properties, Q_SIGNALS and
+ Q_SLOTS. Every class that tqcontains the TQ_OBJECT macro will also have
+ a meta object.
+
+ The meta object information is required by the signal/slot
+ connection mechanism and the property system. The functions isA()
+ and inherits() also make use of the meta object.
+*/
+
+/*!
+ \fn const char *TQObject::className() const
+
+ Returns the class name of this object.
+
+ This function is generated by the \link metaobjects.html Meta
+ Object Compiler. \endlink
+
+ \warning This function will return the wrong name if the class
+ definition lacks the TQ_OBJECT macro.
+
+ \sa name(), inherits(), isA(), isWidgetType()
+*/
+
+/*!
+ Returns TRUE if this object is an instance of the class \a clname;
+ otherwise returns FALSE.
+
+ Example:
+ \code
+ TQTimer *t = new TQTimer; // TQTimer inherits TQObject
+ t->isA( "TQTimer" ); // returns TRUE
+ t->isA( "TQObject" ); // returns FALSE
+ \endcode
+
+ \sa inherits() tqmetaObject()
+*/
+
+bool TQObject::isA( const char *clname ) const
+{
+ return qstrcmp( clname, className() ) == 0;
+}
+
+/*!
+ Returns TRUE if this object is an instance of a class that
+ inherits \a clname, and \a clname inherits TQObject; otherwise
+ returns FALSE.
+
+ A class is considered to inherit itself.
+
+ Example:
+ \code
+ TQTimer *t = new TQTimer; // TQTimer inherits TQObject
+ t->inherits( "TQTimer" ); // returns TRUE
+ t->inherits( "TQObject" ); // returns TRUE
+ t->inherits( "TQButton" ); // returns FALSE
+
+ // TQScrollBar inherits TQWidget and TQRangeControl
+ TQScrollBar *s = new TQScrollBar( 0 );
+ s->inherits( "TQWidget" ); // returns TRUE
+ s->inherits( "TQRangeControl" ); // returns FALSE
+ \endcode
+
+ (\l TQRangeControl is not a TQObject.)
+
+ \sa isA(), tqmetaObject()
+*/
+
+bool TQObject::inherits( const char *clname ) const
+{
+ return tqmetaObject()->inherits( clname );
+}
+
+/*!
+ \internal
+
+ Returns TRUE if \a object inherits \a superClass within
+ the meta object inheritance chain; otherwise returns FALSE.
+
+ \sa inherits()
+*/
+void *qt_inheritedBy( TQMetaObject *superClass, const TQObject *object )
+{
+ if (!object)
+ return 0;
+ register TQMetaObject *mo = object->tqmetaObject();
+ while (mo) {
+ if (mo == superClass)
+ return (void*)object;
+ mo = mo->superClass();
+ }
+ return 0;
+}
+
+/*!
+ \property TQObject::name
+
+ \brief the name of this object
+
+ You can tqfind an object by name (and type) using child(). You can
+ tqfind a set of objects with queryList().
+
+ The object name is set by the constructor or by the setName()
+ function. The object name is not very useful in the current
+ version of TQt, but will become increasingly important in the
+ future.
+
+ If the object does not have a name, the name() function returns
+ "unnamed", so printf() (used in qDebug()) will not be asked to
+ output a null pointer. If you want a null pointer to be returned
+ for unnamed objects, you can call name( 0 ).
+
+ \code
+ qDebug( "MyClass::setPrecision(): (%s) invalid precision %f",
+ name(), newPrecision );
+ \endcode
+
+ \sa className(), child(), queryList()
+*/
+
+const char * TQObject::name() const
+{
+ // If you change the name here, the builder will be broken
+ return objname ? objname : "unnamed";
+}
+
+/*!
+ Sets the object's name to \a name.
+*/
+void TQObject::setName( const char *name )
+{
+ if ( objname )
+ delete [] (char*) objname;
+ objname = name ? qstrdup(name) : 0;
+}
+
+/*!
+ \overload
+
+ Returns the name of this object, or \a defaultName if the object
+ does not have a name.
+*/
+
+const char * TQObject::name( const char * defaultName ) const
+{
+ return objname ? objname : defaultName;
+}
+
+
+/*!
+ Searches the tqchildren and optionally grandtqchildren of this object,
+ and returns a child that is called \a objName that inherits \a
+ inheritsClass. If \a inheritsClass is 0 (the default), any class
+ matches.
+
+ If \a recursiveSearch is TRUE (the default), child() performs a
+ depth-first search of the object's tqchildren.
+
+ If there is no such object, this function returns 0. If there are
+ more than one, the first one found is retured; if you need all of
+ them, use queryList().
+*/
+TQObject* TQObject::child( const char *objName, const char *inheritsClass,
+ bool recursiveSearch )
+{
+ if ( childrenListObject().isEmpty() )
+ return 0;
+
+ bool onlyWidgets = ( inheritsClass && qstrcmp( inheritsClass, "TQWidget" ) == 0 );
+ TQObjectListIt it( childrenListObject() );
+ TQObject *obj;
+ while ( ( obj = it.current() ) ) {
+ ++it;
+ if ( onlyWidgets ) {
+ if ( obj->isWidgetType() && ( !objName || qstrcmp( objName, obj->name() ) == 0 ) )
+ break;
+ } else if ( ( !inheritsClass || obj->inherits(inheritsClass) ) && ( !objName || qstrcmp( objName, obj->name() ) == 0 ) )
+ break;
+ if ( recursiveSearch && (obj = obj->child( objName, inheritsClass, recursiveSearch ) ) )
+ break;
+ }
+ return obj;
+}
+
+/*!
+ \fn bool TQObject::isWidgetType() const
+
+ Returns TRUE if the object is a widget; otherwise returns FALSE.
+
+ Calling this function is equivalent to calling
+ inherits("TQWidget"), except that it is much faster.
+*/
+
+/*!
+ \fn bool TQObject::highPriority() const
+
+ Returns TRUE if the object is a high-priority object, or FALSE if
+ it is a standard-priority object.
+
+ High-priority objects are placed first in TQObject's list of
+ tqchildren on the assumption that they will be referenced very
+ often.
+*/
+
+
+/*!
+ This virtual function receives events to an object and should
+ return TRUE if the event \a e was recognized and processed.
+
+ The event() function can be reimplemented to customize the
+ behavior of an object.
+
+ \sa installEventFilter(), timerEvent(), TQApplication::sendEvent(),
+ TQApplication::postEvent(), TQWidget::event()
+*/
+
+bool TQObject::event( TQEvent *e )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( e == 0 )
+ qWarning( "TQObject::event: Null events are not permitted" );
+#endif
+ if ( eventFilters ) { // try filters
+ if ( activate_filters(e) ) // stopped by a filter
+ return TRUE;
+ }
+
+ switch ( e->type() ) {
+ case TQEvent::Timer:
+ timerEvent( (TQTimerEvent*)e );
+ return TRUE;
+
+ case TQEvent::ChildInserted:
+ case TQEvent::ChildRemoved:
+ childEvent( (TQChildEvent*)e );
+ return TRUE;
+
+ case TQEvent::DeferredDelete:
+ delete this;
+ return TRUE;
+
+ default:
+ if ( e->type() >= TQEvent::User ) {
+ customEvent( (TQCustomEvent*) e );
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ timer events for the object.
+
+ TQTimer provides a higher-level interface to the timer
+ functionality, and also more general information about timers.
+
+ \sa startTimer(), killTimer(), killTimers(), event()
+*/
+
+void TQObject::timerEvent( TQTimerEvent * )
+{
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ child events.
+
+ Child events are sent to objects when tqchildren are inserted or
+ removed.
+
+ Note that events with TQEvent::type() \c TQEvent::ChildInserted are
+ posted (with \l{TQApplication::postEvent()}) to make sure that the
+ child's construction is completed before this function is called.
+
+ If a child is removed immediately after it is inserted, the \c
+ ChildInserted event may be suppressed, but the \c ChildRemoved
+ event will always be sent. In such cases it is possible that there
+ will be a \c ChildRemoved event without a corresponding \c
+ ChildInserted event.
+
+ If you change state based on \c ChildInserted events, call
+ TQWidget::constPolish(), or do
+ \code
+ TQApplication::sendPostedEvents( this, TQEvent::ChildInserted );
+ \endcode
+ in functions that depend on the state. One notable example is
+ TQWidget::tqsizeHint().
+
+ \sa event(), TQChildEvent
+*/
+
+void TQObject::childEvent( TQChildEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ custom events. Custom events are user-defined events with a type
+ value at least as large as the "User" item of the \l TQEvent::Type
+ enum, and is typically a TQCustomEvent or TQCustomEvent subclass.
+
+ \sa event(), TQCustomEvent
+*/
+void TQObject::customEvent( TQCustomEvent * )
+{
+}
+
+
+
+/*!
+ Filters events if this object has been installed as an event
+ filter for the \a watched object.
+
+ In your reimplementation of this function, if you want to filter
+ the event \a e, out, i.e. stop it being handled further, return
+ TRUE; otherwise return FALSE.
+
+ Example:
+ \code
+ class MyMainWindow : public TQMainWindow
+ {
+ public:
+ MyMainWindow( TQWidget *tqparent = 0, const char *name = 0 );
+
+ protected:
+ bool eventFilter( TQObject *obj, TQEvent *ev );
+
+ private:
+ TQTextEdit *textEdit;
+ };
+
+ MyMainWindow::MyMainWindow( TQWidget *tqparent, const char *name )
+ : TQMainWindow( tqparent, name )
+ {
+ textEdit = new TQTextEdit( this );
+ setCentralWidget( textEdit );
+ textEdit->installEventFilter( this );
+ }
+
+ bool MyMainWindow::eventFilter( TQObject *obj, TQEvent *ev )
+ {
+ if ( obj == textEdit ) {
+ if ( e->type() == TQEvent::KeyPress ) {
+ TQKeyEvent *k = (TQKeyEvent*)ev;
+ qDebug( "Ate key press %d", k->key() );
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else {
+ // pass the event on to the tqparent class
+ return TQMainWindow::eventFilter( obj, ev );
+ }
+ }
+ \endcode
+
+ Notice in the example above that unhandled events are passed to
+ the base class's eventFilter() function, since the base class
+ might have reimplemented eventFilter() for its own internal
+ purposes.
+
+ \warning If you delete the receiver object in this function, be
+ sure to return TRUE. Otherwise, TQt will forward the event to the
+ deleted object and the program might crash.
+
+ \sa installEventFilter()
+*/
+
+bool TQObject::eventFilter( TQObject * /* watched */, TQEvent * /* e */ )
+{
+ return FALSE;
+}
+
+
+/*!
+ \internal
+ Activates all event filters for this object.
+ This function is normally called from TQObject::event() or TQWidget::event().
+*/
+
+bool TQObject::activate_filters( TQEvent *e )
+{
+ if ( !eventFilters ) // no event filter
+ return FALSE;
+ TQObjectListIt it( *eventFilters );
+ register TQObject *obj = it.current();
+ while ( obj ) { // send to all filters
+ ++it; // until one returns TRUE
+ if ( obj->eventFilter(this,e) ) {
+ return TRUE;
+ }
+ obj = it.current();
+ }
+ return FALSE; // don't do anything with it
+}
+
+
+/*!
+ \fn bool TQObject::tqsignalsBlocked() const
+
+ Returns TRUE if Q_SIGNALS are blocked; otherwise returns FALSE.
+
+ Signals are not blocked by default.
+
+ \sa blockSignals()
+*/
+
+/*!
+ Blocks Q_SIGNALS if \a block is TRUE, or unblocks Q_SIGNALS if \a
+ block is FALSE.
+
+ Emitted Q_SIGNALS disappear into hyperspace if Q_SIGNALS are blocked.
+ Note that the destroyed() Q_SIGNALS will be emitted even if the Q_SIGNALS
+ for this object have been blocked.
+*/
+
+void TQObject::blockSignals( bool block )
+{
+ blockSig = block;
+}
+
+
+//
+// The timer flag hasTimer is set when startTimer is called.
+// It is not reset when killing the timer because more than
+// one timer might be active.
+//
+
+/*!
+ Starts a timer and returns a timer identifier, or returns zero if
+ it could not start a timer.
+
+ A timer event will occur every \a interval milliseconds until
+ killTimer() or killTimers() is called. If \a interval is 0, then
+ the timer event occurs once every time there are no more window
+ system events to process.
+
+ The virtual timerEvent() function is called with the TQTimerEvent
+ event parameter class when a timer event occurs. Reimplement this
+ function to get timer events.
+
+ If multiple timers are running, the TQTimerEvent::timerId() can be
+ used to tqfind out which timer was activated.
+
+ Example:
+ \code
+ class MyObject : public TQObject
+ {
+ TQ_OBJECT
+ public:
+ MyObject( TQObject *tqparent = 0, const char *name = 0 );
+
+ protected:
+ void timerEvent( TQTimerEvent * );
+ };
+
+ MyObject::MyObject( TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name )
+ {
+ startTimer( 50 ); // 50-millisecond timer
+ startTimer( 1000 ); // 1-second timer
+ startTimer( 60000 ); // 1-minute timer
+ }
+
+ void MyObject::timerEvent( TQTimerEvent *e )
+ {
+ qDebug( "timer event, id %d", e->timerId() );
+ }
+ \endcode
+
+ Note that TQTimer's accuracy depends on the underlying operating
+ system and hardware. Most platforms support an accuracy of 20 ms;
+ some provide more. If TQt is unable to deliver the requested
+ number of timer clicks, it will silently discard some.
+
+ The TQTimer class provides a high-level programming interface with
+ one-shot timers and timer Q_SIGNALS instead of events.
+
+ \sa timerEvent(), killTimer(), killTimers(), TQEventLoop::awake(),
+ TQEventLoop::aboutToBlock()
+*/
+
+int TQObject::startTimer( int interval )
+{
+ pendTimer = TRUE; // set timer flag
+ return qStartTimer( interval, (TQObject *)this );
+}
+
+/*!
+ Kills the timer with timer identifier, \a id.
+
+ The timer identifier is returned by startTimer() when a timer
+ event is started.
+
+ \sa timerEvent(), startTimer(), killTimers()
+*/
+
+void TQObject::killTimer( int id )
+{
+ qKillTimer( id );
+}
+
+/*!
+ Kills all timers that this object has started.
+
+ \warning Using this function can cause hard-to-tqfind bugs: it kills
+ timers started by sub- and superclasses as well as those started
+ by you, which is often not what you want. We recommend using a
+ TQTimer or perhaps killTimer().
+
+ \sa timerEvent(), startTimer(), killTimer()
+*/
+
+void TQObject::killTimers()
+{
+ qKillTimer( this );
+}
+
+static void objSearch( TQObjectList *result,
+ TQObjectList *list,
+ const char *inheritsClass,
+ bool onlyWidgets,
+ const char *objName,
+ TQRegExp *rx,
+ bool recurse )
+{
+ if ( !list || list->isEmpty() ) // nothing to search
+ return;
+ TQObject *obj = list->first();
+ while ( obj ) {
+ bool ok = TRUE;
+ if ( onlyWidgets )
+ ok = obj->isWidgetType();
+ else if ( inheritsClass && !obj->inherits(inheritsClass) )
+ ok = FALSE;
+ if ( ok ) {
+ if ( objName )
+ ok = ( qstrcmp(objName,obj->name()) == 0 );
+#ifndef TQT_NO_REGEXP
+ else if ( rx )
+ ok = ( rx->search(TQString::tqfromLatin1(obj->name())) != -1 );
+#endif
+ }
+ if ( ok ) // match!
+ result->append( obj );
+ if ( recurse && !obj->childrenListObject().isEmpty ) {
+ TQObjectList tqlist = obj->childrenListObject();
+ objSearch( result, &tqlist, inheritsClass,
+ onlyWidgets, objName, rx, recurse );
+ }
+ obj = list->next();
+ }
+}
+
+/*!
+ \fn TQObject *TQObject::tqparent() const
+
+ Returns a pointer to the tqparent object.
+
+ \sa childrenListObject()
+*/
+
+/*!
+ \fn const TQObjectList *TQObject::childrenListObject() const
+
+ Returns a list of child objects, or 0 if this object has no
+ tqchildren.
+
+ The TQObjectList class is defined in the \c tqobjectlist.h header
+ file.
+
+ The first child added is the \link TQPtrList::first() first\endlink
+ object in the list and the last child added is the \link
+ TQPtrList::last() last\endlink object in the list, i.e. new
+ tqchildren are appended at the end.
+
+ Note that the list order changes when TQWidget tqchildren are \link
+ TQWidget::raise() raised\endlink or \link TQWidget::lower()
+ lowered.\endlink A widget that is raised becomes the last object
+ in the list, and a widget that is lowered becomes the first object
+ in the list.
+
+ \sa child(), queryList(), tqparent(), insertChild(), removeChild()
+*/
+
+
+/*!
+ Returns a pointer to the list of all object trees (their root
+ objects), or 0 if there are no objects.
+
+ The TQObjectList class is defined in the \c tqobjectlist.h header
+ file.
+
+ The most recent root object created is the \link TQPtrList::first()
+ first\endlink object in the list and the first root object added
+ is the \link TQPtrList::last() last\endlink object in the list.
+
+ \sa childrenListObject(), tqparent(), insertChild(), removeChild()
+*/
+const TQObjectList *TQObject::objectTrees()
+{
+ return object_trees;
+}
+
+
+/*!
+ Searches the tqchildren and optionally grandtqchildren of this object,
+ and returns a list of those objects that are named or that match
+ \a objName and inherit \a inheritsClass. If \a inheritsClass is 0
+ (the default), all classes match. If \a objName is 0 (the
+ default), all object names match.
+
+ If \a regexpMatch is TRUE (the default), \a objName is a regular
+ expression that the objects's names must match. The syntax is that
+ of a TQRegExp. If \a regexpMatch is FALSE, \a objName is a string
+ and object names must match it exactly.
+
+ Note that \a inheritsClass uses single inheritance from TQObject,
+ the way inherits() does. According to inherits(), TQMenuBar
+ inherits TQWidget but not TQMenuData. This does not quite match
+ reality, but is the best that can be done on the wide variety of
+ compilers TQt supports.
+
+ Finally, if \a recursiveSearch is TRUE (the default), queryList()
+ searches \e{n}th-generation as well as first-generation tqchildren.
+
+ If all this seems a bit complex for your needs, the simpler
+ child() function may be what you want.
+
+ This somewhat contrived example disables all the buttons in this
+ window:
+ \code
+ TQObjectList *l = tqtopLevelWidget()->queryList( "TQButton" );
+ TQObjectListIt it( *l ); // iterate over the buttons
+ TQObject *obj;
+
+ while ( (obj = it.current()) != 0 ) {
+ // for each found object...
+ ++it;
+ ((TQButton*)obj)->setEnabled( FALSE );
+ }
+ delete l; // delete the list, not the objects
+ \endcode
+
+ The TQObjectList class is defined in the \c tqobjectlist.h header
+ file.
+
+ \warning Delete the list as soon you have finished using it. The
+ list tqcontains pointers that may become invalid at almost any time
+ without notice (as soon as the user closes a window you may have
+ dangling pointers, for example).
+
+ \sa child() childrenListObject(), tqparent(), inherits(), name(), TQRegExp
+*/
+
+TQObjectList *TQObject::queryList( const char *inheritsClass,
+ const char *objName,
+ bool regexpMatch,
+ bool recursiveSearch ) const
+{
+ TQObjectList *list = new TQObjectList;
+ TQ_CHECK_PTR( list );
+ bool onlyWidgets = ( inheritsClass && qstrcmp(inheritsClass, "TQWidget") == 0 );
+#ifndef TQT_NO_REGEXP
+ if ( regexpMatch && objName ) { // regexp matching
+ TQRegExp rx(TQString::tqfromLatin1(objName));
+ TQObjectList tqlist = childrenListObject();
+ objSearch( list, &tqlist, inheritsClass, onlyWidgets,
+ 0, &rx, recursiveSearch );
+ } else
+#endif
+ {
+ TQObjectList tqlist = childrenListObject();
+ objSearch( list, &tqlist, inheritsClass, onlyWidgets,
+ objName, 0, recursiveSearch );
+ }
+ return list;
+}
+
+/*! \internal
+
+ Returns a list of objects/slot pairs that are connected to the
+ \a signal, or 0 if nothing is connected to it.
+*/
+
+TQConnectionList *TQObject::tqreceivers( const char* signal ) const
+{
+ if ( connections && signal ) {
+ if ( *signal == '2' ) { // tag == 2, i.e. signal
+ TQCString s = qt_rmWS( signal+1 );
+ return tqreceivers( tqmetaObject()->tqfindSignal( (const char*)s, TRUE ) );
+ } else {
+ return tqreceivers( tqmetaObject()->tqfindSignal(signal, TRUE ) );
+ }
+ }
+ return 0;
+}
+
+/*! \internal
+
+ Returns a list of objects/slot pairs that are connected to the
+ signal, or 0 if nothing is connected to it.
+*/
+
+TQConnectionList *TQObject::tqreceivers( int signal ) const
+{
+#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+ if ( qt_preliminary_signal_spy && signal >= 0 ) {
+ if ( !connections ) {
+ TQObject* that = (TQObject*) this;
+ that->connections = new TQSignalVec( signal+1 );
+ that->connections->setAutoDelete( TRUE );
+ }
+ if ( !connections->at( signal ) ) {
+ TQConnectionList* clist = new TQConnectionList;
+ clist->setAutoDelete( TRUE );
+ connections->insert( signal, clist );
+ return clist;
+ }
+ }
+#endif
+ if ( connections && signal >= 0 )
+ return connections->at( signal );
+ return 0;
+}
+
+
+/*!
+ Inserts an object \a obj into the list of child objects.
+
+ \warning This function cannot be used to make one widget the child
+ widget of another widget. Child widgets can only be created by
+ setting the tqparent widget in the constructor or by calling
+ TQWidget::reparent().
+
+ \sa removeChild(), TQWidget::reparent()
+*/
+
+void TQObject::insertChild( TQObject *obj )
+{
+ if ( obj->isTree ) {
+ remove_tree( obj );
+ obj->isTree = FALSE;
+ }
+ if ( obj->parentObj && obj->parentObj != this ) {
+#if defined(TQT_CHECK_STATE)
+ if ( obj->parentObj != this && obj->isWidgetType() )
+ qWarning( "TQObject::insertChild: Cannot reparent a widget, "
+ "use TQWidget::reparent() instead" );
+#endif
+ obj->parentObj->removeChild( obj );
+ }
+
+ if ( !childObjects ) {
+ childObjects = new TQObjectList;
+ TQ_CHECK_PTR( childObjects );
+ } else if ( obj->parentObj == this ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQObject::insertChild: Object %s::%s already in list",
+ obj->className(), obj->name( "unnamed" ) );
+#endif
+ return;
+ }
+ obj->parentObj = this;
+ childObjects->append( obj );
+
+ TQChildEvent *e = new TQChildEvent( TQEvent::ChildInserted, obj );
+ TQApplication::postEvent( this, e );
+}
+
+/*!
+ Removes the child object \a obj from the list of tqchildren.
+
+ \warning This function will not remove a child widget from the
+ screen. It will only remove it from the tqparent widget's list of
+ tqchildren.
+
+ \sa insertChild(), TQWidget::reparent()
+*/
+
+void TQObject::removeChild( TQObject *obj )
+{
+ if ( childObjects && childObjects->removeRef(obj) ) {
+ obj->parentObj = 0;
+ if ( !obj->wasDeleted ) {
+ insert_tree( obj ); // it's a root object now
+ obj->isTree = TRUE;
+ }
+ if ( childObjects->isEmpty() ) {
+ delete childObjects; // last child removed
+ childObjects = 0; // reset tqchildren list
+ }
+
+ // remove events must be sent, not posted!!!
+ TQChildEvent ce( TQEvent::ChildRemoved, obj );
+ TQApplication::sendEvent( this, &ce );
+ }
+}
+
+
+/*!
+ \fn void TQObject::installEventFilter( const TQObject *filterObj )
+
+ Installs an event filter \a filterObj on this object. For example:
+ \code
+ monitoredObj->installEventFilter( filterObj );
+ \endcode
+
+ An event filter is an object that receives all events that are
+ sent to this object. The filter can either stop the event or
+ forward it to this object. The event filter \a filterObj receives
+ events via its eventFilter() function. The eventFilter() function
+ must return TRUE if the event should be filtered, (i.e. stopped);
+ otherwise it must return FALSE.
+
+ If multiple event filters are installed on a single object, the
+ filter that was installed last is activated first.
+
+ Here's a \c KeyPressEater class that eats the key presses of its
+ monitored objects:
+ \code
+ class KeyPressEater : public TQObject
+ {
+ ...
+ protected:
+ bool eventFilter( TQObject *o, TQEvent *e );
+ };
+
+ bool KeyPressEater::eventFilter( TQObject *o, TQEvent *e )
+ {
+ if ( e->type() == TQEvent::KeyPress ) {
+ // special processing for key press
+ TQKeyEvent *k = (TQKeyEvent *)e;
+ qDebug( "Ate key press %d", k->key() );
+ return TRUE; // eat event
+ } else {
+ // standard event processing
+ return FALSE;
+ }
+ }
+ \endcode
+
+ And here's how to install it on two widgets:
+ \code
+ KeyPressEater *keyPressEater = new KeyPressEater( this );
+ TQPushButton *pushButton = new TQPushButton( this );
+ TQListView *listView = new TQListView( this );
+
+ pushButton->installEventFilter( keyPressEater );
+ listView->installEventFilter( keyPressEater );
+ \endcode
+
+ The TQAccel class, for example, uses this technique to intercept
+ accelerator key presses.
+
+ \warning If you delete the receiver object in your eventFilter()
+ function, be sure to return TRUE. If you return FALSE, TQt sends
+ the event to the deleted object and the program will crash.
+
+ \sa removeEventFilter(), eventFilter(), event()
+*/
+
+void TQObject::installEventFilter( const TQObject *obj )
+{
+ if ( !obj )
+ return;
+ if ( eventFilters ) {
+ int c = eventFilters->tqfindRef( obj );
+ if ( c >= 0 )
+ eventFilters->take( c );
+ disconnect( obj, TQT_SIGNAL(destroyed(TQObject*)),
+ this, TQT_SLOT(cleanupEventFilter(TQObject*)) );
+ } else {
+ eventFilters = new TQObjectList;
+ TQ_CHECK_PTR( eventFilters );
+ }
+ eventFilters->insert( 0, obj );
+ connect( obj, TQT_SIGNAL(destroyed(TQObject*)), this, TQT_SLOT(cleanupEventFilter(TQObject*)) );
+}
+
+/*!
+ Removes an event filter object \a obj from this object. The
+ request is ignored if such an event filter has not been installed.
+
+ All event filters for this object are automatically removed when
+ this object is destroyed.
+
+ It is always safe to remove an event filter, even during event
+ filter activation (i.e. from the eventFilter() function).
+
+ \sa installEventFilter(), eventFilter(), event()
+*/
+
+void TQObject::removeEventFilter( const TQObject *obj )
+{
+ if ( eventFilters && eventFilters->removeRef(obj) ) {
+ if ( eventFilters->isEmpty() ) { // last event filter removed
+ delete eventFilters;
+ eventFilters = 0; // reset event filter list
+ }
+ disconnect( obj, TQT_SIGNAL(destroyed(TQObject*)),
+ this, TQT_SLOT(cleanupEventFilter(TQObject*)) );
+ }
+}
+
+
+/*****************************************************************************
+ Signal connection management
+ *****************************************************************************/
+
+#if defined(TQT_CHECK_RANGE)
+
+static bool check_signal_macro( const TQObject *sender, const char *signal,
+ const char *func, const char *op )
+{
+ int sigcode = (int)(*signal) - '0';
+ if ( sigcode != TQSIGNAL_CODE ) {
+ if ( sigcode == TQSLOT_CODE )
+ qWarning( "TQObject::%s: Attempt to %s non-signal %s::%s",
+ func, op, sender->className(), signal+1 );
+ else
+ qWarning( "TQObject::%s: Use the TQT_SIGNAL macro to %s %s::%s",
+ func, op, sender->className(), signal );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static bool check_member_code( int code, const TQObject *object,
+ const char *member, const char *func )
+{
+ if ( code != TQSLOT_CODE && code != TQSIGNAL_CODE ) {
+ qWarning( "TQObject::%s: Use the TQT_SLOT or TQT_SIGNAL macro to "
+ "%s %s::%s", func, func, object->className(), member );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void err_member_notfound( int code, const TQObject *object,
+ const char *member, const char *func )
+{
+ const char *type = 0;
+ switch ( code ) {
+ case TQSLOT_CODE: type = "slot"; break;
+ case TQSIGNAL_CODE: type = "signal"; break;
+ }
+ if ( strchr(member,')') == 0 ) // common typing mistake
+ qWarning( "TQObject::%s: Parentheses expected, %s %s::%s",
+ func, type, object->className(), member );
+ else
+ qWarning( "TQObject::%s: No such %s %s::%s",
+ func, type, object->className(), member );
+}
+
+
+static void err_info_about_objects( const char * func,
+ const TQObject * sender,
+ const TQObject * receiver )
+{
+ const char * a = sender->name(), * b = receiver->name();
+ if ( a )
+ qWarning( "TQObject::%s: (sender name: '%s')", func, a );
+ if ( b )
+ qWarning( "TQObject::%s: (receiver name: '%s')", func, b );
+}
+
+static void err_info_about_candidates( int code,
+ const TQMetaObject* mo,
+ const char* member,
+ const char *func )
+{
+ if ( strstr(member,"const char*") ) {
+ // porting help
+ TQCString newname = member;
+ int p;
+ while ( (p=newname.tqfind("const char*")) >= 0 ) {
+ newname.tqreplace(p, 11, "const TQString&");
+ }
+ const TQMetaData *rm = 0;
+ switch ( code ) {
+ case TQSLOT_CODE:
+ rm = mo->slot( mo->tqfindSlot( newname, TRUE ), TRUE );
+ break;
+ case TQSIGNAL_CODE:
+ rm = mo->signal( mo->tqfindSignal( newname, TRUE ), TRUE );
+ break;
+ }
+ if ( rm ) {
+ qWarning("TQObject::%s: Candidate: %s", func, newname.data());
+ }
+ }
+}
+
+
+#endif // TQT_CHECK_RANGE
+
+
+/*!
+ Returns a pointer to the object that sent the signal, if called in
+ a slot activated by a signal; otherwise it returns 0. The pointer
+ is valid only during the execution of the slot that calls this
+ function.
+
+ The pointer returned by this function becomes invalid if the
+ sender is destroyed, or if the slot is disconnected from the
+ sender's signal.
+
+ \warning This function violates the object-oriented principle of
+ modularity. However, getting access to the sender might be useful
+ when many Q_SIGNALS are connected to a single slot. The sender is
+ undefined if the slot is called as a normal C++ function.
+*/
+
+const TQObject *TQObject::sender()
+{
+#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+ if ( this == qt_preliminary_signal_spy ) {
+# ifdef TQT_THREAD_SUPPORT
+ // protect access to qt_spy_signal_sender
+ void * const address = &qt_spy_signal_sender;
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( address ) : 0 );
+# endif // TQT_THREAD_SUPPORT
+ return qt_spy_signal_sender;
+ }
+#endif
+ if ( senderObjects &&
+ senderObjects->currentSender &&
+ /*
+ * currentSender may be a dangling pointer in case the object
+ * it was pointing to was destructed from inside a slot. Thus
+ * verify it still is contained inside the senderObjects list
+ * which gets cleaned on both destruction and disconnect.
+ */
+
+ senderObjects->tqfindRef( senderObjects->currentSender ) != -1 )
+ return senderObjects->currentSender;
+ return 0;
+}
+
+
+/*!
+ \fn void TQObject::connectNotify( const char *signal )
+
+ This virtual function is called when something has been connected
+ to \a signal in this object.
+
+ \warning This function violates the object-oriented principle of
+ modularity. However, it might be useful when you need to perform
+ expensive initialization only if something is connected to a
+ signal.
+
+ \sa connect(), disconnectNotify()
+*/
+
+void TQObject::connectNotify( const char * )
+{
+}
+
+/*!
+ \fn void TQObject::disconnectNotify( const char *signal )
+
+ This virtual function is called when something has been
+ disconnected from \a signal in this object.
+
+ \warning This function violates the object-oriented principle of
+ modularity. However, it might be useful for optimizing access to
+ expensive resources.
+
+ \sa disconnect(), connectNotify()
+*/
+
+void TQObject::disconnectNotify( const char * )
+{
+}
+
+
+/*!
+ \fn bool TQObject::checkConnectArgs( const char *signal, const TQObject *receiver, const char *member )
+
+ Returns TRUE if the \a signal and the \a member arguments are
+ compatible; otherwise returns FALSE. (The \a receiver argument is
+ currently ignored.)
+
+ \warning We recommend that you use the default implementation and
+ do not reimplement this function.
+
+ \omit
+ TRUE: "signal(<anything>)", "member()"
+ TRUE: "signal(a,b,c)", "member(a,b,c)"
+ TRUE: "signal(a,b,c)", "member(a,b)", "member(a)" etc.
+ FALSE: "signal(const a)", "member(a)"
+ FALSE: "signal(a)", "member(const a)"
+ FALSE: "signal(a)", "member(b)"
+ FALSE: "signal(a)", "member(a,b)"
+ \endomit
+*/
+
+bool TQObject::checkConnectArgs( const char *signal,
+ const TQObject *,
+ const char *member )
+{
+ const char *s1 = signal;
+ const char *s2 = member;
+ while ( *s1++ != '(' ) { } // scan to first '('
+ while ( *s2++ != '(' ) { }
+ if ( *s2 == ')' || qstrcmp(s1,s2) == 0 ) // member has no args or
+ return TRUE; // exact match
+ int s1len = tqstrlen(s1);
+ int s2len = tqstrlen(s2);
+ if ( s2len < s1len && tqstrncmp(s1,s2,s2len-1)==0 && s1[s2len-1]==',' )
+ return TRUE; // member has less args
+ return FALSE;
+}
+
+/*!
+ Normlizes the signal or slot definition \a signalSlot by removing
+ unnecessary whitespace.
+*/
+
+TQCString TQObject::normalizeSignalSlot( const char *signalSlot )
+{
+ if ( !signalSlot )
+ return TQCString();
+ return qt_rmWS( signalSlot );
+}
+
+
+
+/*!
+ \overload bool TQObject::connect( const TQObject *sender, const char *signal, const char *member ) const
+
+ Connects \a signal from the \a sender object to this object's \a
+ member.
+
+ Equivalent to: \c{TQObject::connect(sender, signal, this, member)}.
+
+ \sa disconnect()
+*/
+
+/*!
+ Connects \a signal from the \a sender object to \a member in object
+ \a receiver, and returns TRUE if the connection succeeds; otherwise
+ returns FALSE.
+
+ You must use the TQT_SIGNAL() and TQT_SLOT() macros when specifying the \a signal
+ and the \a member, for example:
+ \code
+ TQLabel *label = new TQLabel;
+ TQScrollBar *scroll = new TQScrollBar;
+ TQObject::connect( scroll, TQT_SIGNAL(valueChanged(int)),
+ label, TQT_SLOT(setNum(int)) );
+ \endcode
+
+ This example ensures that the label always displays the current
+ scroll bar value. Note that the signal and Q_SLOTS parameters must not
+ contain any variable names, only the type. E.g. the following would
+ not work and return FALSE:
+ TQObject::connect( scroll, TQT_SIGNAL(valueChanged(int v)),
+ label, TQT_SLOT(setNum(int v)) );
+
+ A signal can also be connected to another signal:
+
+ \code
+ class MyWidget : public TQWidget
+ {
+ TQ_OBJECT
+ public:
+ MyWidget();
+
+ Q_SIGNALS:
+ void myUsefulSignal();
+
+ private:
+ TQPushButton *aButton;
+ };
+
+ MyWidget::MyWidget()
+ {
+ aButton = new TQPushButton( this );
+ connect( aButton, TQT_SIGNAL(clicked()), TQT_SIGNAL(myUsefulSignal()) );
+ }
+ \endcode
+
+ In this example, the MyWidget constructor relays a signal from a
+ private member variable, and makes it available under a name that
+ relates to MyWidget.
+
+ A signal can be connected to many Q_SLOTS and Q_SIGNALS. Many Q_SIGNALS
+ can be connected to one slot.
+
+ If a signal is connected to several Q_SLOTS, the Q_SLOTS are activated
+ in an arbitrary order when the signal is emitted.
+
+ The function returns TRUE if it successfully connects the signal
+ to the slot. It will return FALSE if it cannot create the
+ connection, for example, if TQObject is unable to verify the
+ existence of either \a signal or \a member, or if their signatures
+ aren't compatible.
+
+ A signal is emitted for \e{every} connection you make, so if you
+ duplicate a connection, two Q_SIGNALS will be emitted. You can
+ always break a connection using \c{disconnect()}.
+
+ \sa disconnect()
+*/
+
+bool TQObject::connect( const TQObject *sender, const char *signal,
+ const TQObject *receiver, const char *member )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( sender == 0 || receiver == 0 || signal == 0 || member == 0 ) {
+ qWarning( "TQObject::connect: Cannot connect %s::%s to %s::%s",
+ sender ? sender->className() : "(null)",
+ signal ? signal+1 : "(null)",
+ receiver ? receiver->className() : "(null)",
+ member ? member+1 : "(null)" );
+ return FALSE;
+ }
+#endif
+ TQMetaObject *smeta = sender->tqmetaObject();
+
+#if defined(TQT_CHECK_RANGE)
+ if ( !check_signal_macro( sender, signal, "connect", "bind" ) )
+ return FALSE;
+#endif
+ TQCString nw_signal(signal); // Assume already normalized
+ ++signal; // skip member type code
+
+ int signal_index = smeta->tqfindSignal( signal, TRUE );
+ if ( signal_index < 0 ) { // normalize and retry
+ nw_signal = qt_rmWS( signal-1 ); // remove whitespace
+ signal = nw_signal.data()+1; // skip member type code
+ signal_index = smeta->tqfindSignal( signal, TRUE );
+ }
+
+ if ( signal_index < 0 ) { // no such signal
+#if defined(TQT_CHECK_RANGE)
+ err_member_notfound( TQSIGNAL_CODE, sender, signal, "connect" );
+ err_info_about_candidates( TQSIGNAL_CODE, smeta, signal, "connect" );
+ err_info_about_objects( "connect", sender, receiver );
+#endif
+ return FALSE;
+ }
+ const TQMetaData *sm = smeta->signal( signal_index, TRUE );
+ signal = sm->name; // use name from meta object
+
+ int membcode = member[0] - '0'; // get member code
+
+ TQObject *s = (TQObject *)sender; // we need to change them
+ TQObject *r = (TQObject *)receiver; // internally
+
+#if defined(TQT_CHECK_RANGE)
+ if ( !check_member_code( membcode, r, member, "connect" ) )
+ return FALSE;
+#endif
+ member++; // skip code
+
+ TQCString nw_member ;
+ TQMetaObject *rmeta = r->tqmetaObject();
+ int member_index = -1;
+ switch ( membcode ) { // get receiver member
+ case TQSLOT_CODE:
+ member_index = rmeta->tqfindSlot( member, TRUE );
+ if ( member_index < 0 ) { // normalize and retry
+ nw_member = qt_rmWS(member); // remove whitespace
+ member = nw_member;
+ member_index = rmeta->tqfindSlot( member, TRUE );
+ }
+ break;
+ case TQSIGNAL_CODE:
+ member_index = rmeta->tqfindSignal( member, TRUE );
+ if ( member_index < 0 ) { // normalize and retry
+ nw_member = qt_rmWS(member); // remove whitespace
+ member = nw_member;
+ member_index = rmeta->tqfindSignal( member, TRUE );
+ }
+ break;
+ }
+ if ( member_index < 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ err_member_notfound( membcode, r, member, "connect" );
+ err_info_about_candidates( membcode, rmeta, member, "connect" );
+ err_info_about_objects( "connect", sender, receiver );
+#endif
+ return FALSE;
+ }
+#if defined(TQT_CHECK_RANGE)
+ if ( !s->checkConnectArgs(signal,receiver,member) ) {
+ qWarning( "TQObject::connect: Incompatible sender/receiver arguments"
+ "\n\t%s::%s --> %s::%s",
+ s->className(), signal,
+ r->className(), member );
+ return FALSE;
+ } else {
+ const TQMetaData *rm = membcode == TQSLOT_CODE ?
+ rmeta->slot( member_index, TRUE ) :
+ rmeta->signal( member_index, TRUE );
+ if ( rm ) {
+ int si = 0;
+ int ri = 0;
+ while ( si < sm->method->count && ri < rm->method->count ) {
+ if ( sm->method->parameters[si].inOut == TQUParameter::Out )
+ si++;
+ else if ( rm->method->parameters[ri].inOut == TQUParameter::Out )
+ ri++;
+ else if ( !TQUType::isEqual( sm->method->parameters[si++].type,
+ rm->method->parameters[ri++].type ) ) {
+ if ( ( TQUType::isEqual( sm->method->parameters[si-1].type, &static_TQUType_ptr )
+ && TQUType::isEqual( rm->method->parameters[ri-1].type, &static_TQUType_varptr ) )
+ || ( TQUType::isEqual( sm->method->parameters[si-1].type, &static_TQUType_varptr )
+ && TQUType::isEqual( rm->method->parameters[ri-1].type, &static_TQUType_ptr ) ) )
+ continue; // varptr got introduced in 3.1 and is binary compatible with ptr
+ qWarning( "TQObject::connect: Incompatible sender/receiver marshalling"
+ "\n\t%s::%s --> %s::%s",
+ s->className(), signal,
+ r->className(), member );
+ return FALSE;
+ }
+ }
+ }
+ }
+#endif
+ connectInternal( sender, signal_index, receiver, membcode, member_index );
+ s->connectNotify( nw_signal );
+ return TRUE;
+}
+
+/*! \internal */
+
+void TQObject::connectInternal( const TQObject *sender, int signal_index, const TQObject *receiver,
+ int membcode, int member_index )
+{
+ TQObject *s = (TQObject*)sender;
+ TQObject *r = (TQObject*)receiver;
+
+ if ( !s->connections ) { // create connections lookup table
+ s->connections = new TQSignalVec( signal_index+1 );
+ TQ_CHECK_PTR( s->connections );
+ s->connections->setAutoDelete( TRUE );
+ }
+
+ TQConnectionList *clist = s->connections->at( signal_index );
+ if ( !clist ) { // create receiver list
+ clist = new TQConnectionList;
+ TQ_CHECK_PTR( clist );
+ clist->setAutoDelete( TRUE );
+ s->connections->insert( signal_index, clist );
+ }
+
+ TQMetaObject *rmeta = r->tqmetaObject();
+ const TQMetaData *rm = 0;
+
+ switch ( membcode ) { // get receiver member
+ case TQSLOT_CODE:
+ rm = rmeta->slot( member_index, TRUE );
+ break;
+ case TQSIGNAL_CODE:
+ rm = rmeta->signal( member_index, TRUE );
+ break;
+ }
+
+ TQConnection *c = new TQConnection( r, member_index, rm ? rm->name : "qt_invoke", membcode );
+ TQ_CHECK_PTR( c );
+ clist->append( c );
+ if ( !r->senderObjects ) // create list of senders
+ r->senderObjects = new TQSenderObjectList;
+ r->senderObjects->append( s ); // add sender to list
+}
+
+
+/*!
+ \overload bool TQObject::disconnect( const char *signal, const TQObject *receiver, const char *member )
+
+ Disconnects \a signal from \a member of \a receiver.
+
+ A signal-slot connection is removed when either of the objects
+ involved are destroyed.
+*/
+
+/*!
+ \overload bool TQObject::disconnect( const TQObject *receiver, const char *member )
+
+ Disconnects all Q_SIGNALS in this object from \a receiver's \a
+ member.
+
+ A signal-slot connection is removed when either of the objects
+ involved are destroyed.
+*/
+
+/*!
+ Disconnects \a signal in object \a sender from \a member in object
+ \a receiver.
+
+ A signal-slot connection is removed when either of the objects
+ involved are destroyed.
+
+ disconnect() is typically used in three ways, as the following
+ examples demonstrate.
+ \list 1
+ \i Disconnect everything connected to an object's Q_SIGNALS:
+ \code
+ disconnect( myObject, 0, 0, 0 );
+ \endcode
+ equivalent to the non-static overloaded function
+ \code
+ myObject->disconnect();
+ \endcode
+ \i Disconnect everything connected to a specific signal:
+ \code
+ disconnect( myObject, TQT_SIGNAL(mySignal()), 0, 0 );
+ \endcode
+ equivalent to the non-static overloaded function
+ \code
+ myObject->disconnect( TQT_SIGNAL(mySignal()) );
+ \endcode
+ \i Disconnect a specific receiver:
+ \code
+ disconnect( myObject, 0, myReceiver, 0 );
+ \endcode
+ equivalent to the non-static overloaded function
+ \code
+ myObject->disconnect( myReceiver );
+ \endcode
+ \endlist
+
+ 0 may be used as a wildcard, meaning "any signal", "any receiving
+ object", or "any slot in the receiving object", respectively.
+
+ The \a sender may never be 0. (You cannot disconnect Q_SIGNALS from
+ more than one object in a single call.)
+
+ If \a signal is 0, it disconnects \a receiver and \a member from
+ any signal. If not, only the specified signal is disconnected.
+
+ If \a receiver is 0, it disconnects anything connected to \a
+ signal. If not, Q_SLOTS in objects other than \a receiver are not
+ disconnected.
+
+ If \a member is 0, it disconnects anything that is connected to \a
+ receiver. If not, only Q_SLOTS named \a member will be disconnected,
+ and all other Q_SLOTS are left alone. The \a member must be 0 if \a
+ receiver is left out, so you cannot disconnect a
+ specifically-named slot on all objects.
+
+ \sa connect()
+*/
+
+bool TQObject::disconnect( const TQObject *sender, const char *signal,
+ const TQObject *receiver, const char *member )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( sender == 0 || (receiver == 0 && member != 0) ) {
+ qWarning( "TQObject::disconnect: Unexpected null parameter" );
+ return FALSE;
+ }
+#endif
+ if ( !sender->connections ) // no connected Q_SIGNALS
+ return FALSE;
+ TQObject *s = (TQObject *)sender;
+ TQObject *r = (TQObject *)receiver;
+ int member_index = -1;
+ int membcode = -1;
+ TQCString nw_member;
+ if ( member ) {
+ membcode = member[0] - '0';
+#if defined(TQT_CHECK_RANGE)
+ if ( !check_member_code( membcode, r, member, "disconnect" ) )
+ return FALSE;
+#endif
+ ++member;
+ TQMetaObject *rmeta = r->tqmetaObject();
+
+ switch ( membcode ) { // get receiver member
+ case TQSLOT_CODE:
+ member_index = rmeta->tqfindSlot( member, TRUE );
+ if ( member_index < 0 ) { // normalize and retry
+ nw_member = qt_rmWS(member); // remove whitespace
+ member = nw_member;
+ member_index = rmeta->tqfindSlot( member, TRUE );
+ }
+ break;
+ case TQSIGNAL_CODE:
+ member_index = rmeta->tqfindSignal( member, TRUE );
+ if ( member_index < 0 ) { // normalize and retry
+ nw_member = qt_rmWS(member); // remove whitespace
+ member = nw_member;
+ member_index = rmeta->tqfindSignal( member, TRUE );
+ }
+ break;
+ }
+ if ( member_index < 0 ) { // no such member
+#if defined(TQT_CHECK_RANGE)
+ err_member_notfound( membcode, r, member, "disconnect" );
+ err_info_about_candidates( membcode, rmeta, member, "connect" );
+ err_info_about_objects( "disconnect", sender, receiver );
+#endif
+ return FALSE;
+ }
+ }
+
+ if ( signal == 0 ) { // any/all Q_SIGNALS
+ if ( disconnectInternal( s, -1, r, membcode, member_index ) )
+ s->disconnectNotify( 0 );
+ else
+ return FALSE;
+ } else { // specific signal
+#if defined(TQT_CHECK_RANGE)
+ if ( !check_signal_macro( s, signal, "disconnect", "unbind" ) )
+ return FALSE;
+#endif
+ TQCString nw_signal(signal); // Assume already normalized
+ ++signal; // skip member type code
+
+ TQMetaObject *smeta = s->tqmetaObject();
+ if ( !smeta ) // no meta object
+ return FALSE;
+ int signal_index = smeta->tqfindSignal( signal, TRUE );
+ if ( signal_index < 0 ) { // normalize and retry
+ nw_signal = qt_rmWS( signal-1 ); // remove whitespace
+ signal = nw_signal.data()+1; // skip member type code
+ signal_index = smeta->tqfindSignal( signal, TRUE );
+ }
+ if ( signal_index < 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQObject::disconnect: No such signal %s::%s",
+ s->className(), signal );
+#endif
+ return FALSE;
+ }
+
+ /* compatibility and safety: If a receiver has several Q_SLOTS
+ * with the same name, disconnect them all*/
+ bool res = FALSE;
+ if ( membcode == TQSLOT_CODE && r ) {
+ TQMetaObject * rmeta = r->tqmetaObject();
+ do {
+ int mi = rmeta->tqfindSlot( member );
+ if ( mi != -1 )
+ res |= disconnectInternal( s, signal_index, r, membcode, mi );
+ } while ( (rmeta = rmeta->superClass()) );
+ } else {
+ res = disconnectInternal( s, signal_index, r, membcode, member_index );
+ }
+ if ( res )
+ s->disconnectNotify( nw_signal );
+ return res;
+ }
+ return TRUE;
+}
+
+/*! \internal */
+
+bool TQObject::disconnectInternal( const TQObject *sender, int signal_index,
+ const TQObject *receiver, int membcode, int member_index )
+{
+ TQObject *s = (TQObject*)sender;
+ TQObject *r = (TQObject*)receiver;
+
+ if ( !s->connections )
+ return FALSE;
+
+ bool success = FALSE;
+ TQConnectionList *clist;
+ register TQConnection *c;
+ if ( signal_index == -1 ) {
+ for ( int i = 0; i < (int) s->connections->size(); i++ ) {
+ clist = (*s->connections)[i]; // for all Q_SIGNALS...
+ if ( !clist )
+ continue;
+ c = clist->first();
+ while ( c ) { // for all tqreceivers...
+ if ( r == 0 ) { // remove all tqreceivers
+ removeObjFromList( c->object()->senderObjects, s );
+ success = TRUE;
+ c = clist->next();
+ } else if ( r == c->object() &&
+ ( member_index == -1 ||
+ member_index == c->member() && c->memberType() == membcode ) ) {
+ removeObjFromList( c->object()->senderObjects, s, TRUE );
+ success = TRUE;
+ clist->remove();
+ c = clist->current();
+ } else {
+ c = clist->next();
+ }
+ }
+ if ( r == 0 ) // disconnect all tqreceivers
+ s->connections->insert( i, 0 );
+ }
+ } else {
+ clist = s->connections->at( signal_index );
+ if ( !clist )
+ return FALSE;
+
+ c = clist->first();
+ while ( c ) { // for all tqreceivers...
+ if ( r == 0 ) { // remove all tqreceivers
+ removeObjFromList( c->object()->senderObjects, s, TRUE );
+ success = TRUE;
+ c = clist->next();
+ } else if ( r == c->object() &&
+ ( member_index == -1 ||
+ member_index == c->member() && c->memberType() == membcode ) ) {
+ removeObjFromList( c->object()->senderObjects, s, TRUE );
+ success = TRUE;
+ clist->remove();
+ c = clist->current();
+ } else {
+ c = clist->next();
+ }
+ }
+ if ( r == 0 ) // disconnect all tqreceivers
+ s->connections->insert( signal_index, 0 );
+ }
+ return success;
+}
+
+/*!
+ \fn TQObject::destroyed()
+
+ This signal is emitted when the object is being destroyed.
+
+ Note that the signal is emitted by the TQObject destructor, so
+ the object's virtual table is already degenerated at this point,
+ and it is not safe to call any functions on the object emitting
+ the signal. This signal can not be blocked.
+
+ All the objects's tqchildren are destroyed immediately after this
+ signal is emitted.
+*/
+
+/*!
+ \overload TQObject::destroyed( TQObject* obj)
+
+ This signal is emitted immediately before the object \a obj is
+ destroyed, and can not be blocked.
+
+ All the objects's tqchildren are destroyed immediately after this
+ signal is emitted.
+*/
+
+/*!
+ Performs a deferred deletion of this object.
+
+ Instead of an immediate deletion this function schedules a
+ deferred delete event for processing when TQt returns to the main
+ event loop.
+*/
+void TQObject::deleteLater()
+{
+ TQApplication::postEvent( this, new TQEvent( TQEvent::DeferredDelete) );
+}
+
+/*!
+ This slot is connected to the destroyed() signal of other objects
+ that have installed event filters on this object. When the other
+ object, \a obj, is destroyed, we want to remove its event filter.
+*/
+
+void TQObject::cleanupEventFilter(TQObject* obj)
+{
+ removeEventFilter( obj );
+}
+
+
+/*!
+ \fn TQString TQObject::tr( const char *sourceText, const char * comment )
+ \reentrant
+
+ Returns a translated version of \a sourceText, or \a sourceText
+ itself if there is no appropriate translated version. The
+ translation context is TQObject with \a comment (0 by default).
+ All TQObject subclasses using the TQ_OBJECT macro automatically have
+ a reimplementation of this function with the subclass name as
+ context.
+
+ \warning This method is reentrant only if all translators are
+ installed \e before calling this method. Installing or removing
+ translators while performing translations is not supported. Doing
+ so will probably result in crashes or other undesirable behavior.
+
+ \sa trUtf8() TQApplication::translate()
+ \link i18n.html Internationalization with TQt\endlink
+*/
+
+/*!
+ \fn TQString TQObject::trUtf8( const char *sourceText,
+ const char *comment )
+ \reentrant
+
+ Returns a translated version of \a sourceText, or
+ TQString::fromUtf8(\a sourceText) if there is no appropriate
+ version. It is otherwise identical to tr(\a sourceText, \a
+ comment).
+
+ \warning This method is reentrant only if all translators are
+ installed \e before calling this method. Installing or removing
+ translators while performing translations is not supported. Doing
+ so will probably result in crashes or other undesirable behavior.
+
+ \sa tr() TQApplication::translate()
+*/
+
+static TQMetaObjectCleanUp cleanUp_TQt = TQMetaObjectCleanUp( "TQObject", &TQObject::staticMetaObject );
+
+TQMetaObject* TQObject::staticTQtMetaObject()
+{
+ static TQMetaObject* qtMetaObject = 0;
+ if ( qtMetaObject )
+ return qtMetaObject;
+
+#ifndef TQT_NO_PROPERTIES
+ static const TQMetaEnum::Item enum_0[] = {
+ { "AlignLeft", (int) TQt::AlignLeft },
+ { "AlignRight", (int) TQt::AlignRight },
+ { "AlignHCenter", (int) TQt::AlignHCenter },
+ { "AlignTop", (int) TQt::AlignTop },
+ { "AlignBottom", (int) TQt::AlignBottom },
+ { "AlignVCenter", (int) TQt::AlignVCenter },
+ { "AlignCenter", (int) TQt::AlignCenter },
+ { "AlignAuto", (int) TQt::AlignAuto },
+ { "AlignJustify", (int) TQt::AlignJustify },
+ { "WordBreak", (int) TQt::WordBreak }
+ };
+
+ static const TQMetaEnum::Item enum_1[] = {
+ { "Horizontal", (int) Qt::Horizontal },
+ { "Vertical", (int) Qt::Vertical }
+ };
+
+ static const TQMetaEnum::Item enum_2[] = {
+ { "PlainText", (int) TQt::PlainText },
+ { "RichText", (int) TQt::RichText },
+ { "AutoText", (int) TQt::AutoText },
+ { "LogText", (int) TQt::LogText }
+ };
+
+ static const TQMetaEnum::Item enum_3[] = {
+ { "NoBackground", (int) TQt::NoBackground },
+ { "PaletteForeground", (int) TQt::PaletteForeground },
+ { "PaletteButton", (int) TQt::PaletteButton },
+ { "PaletteLight", (int) TQt::PaletteLight },
+ { "PaletteMidlight", (int) TQt::PaletteMidlight },
+ { "PaletteDark", (int) TQt::PaletteDark },
+ { "PaletteMid", (int) TQt::PaletteMid },
+ { "PaletteText", (int) TQt::PaletteText },
+ { "PaletteBrightText", (int) TQt::PaletteBrightText },
+ { "PaletteBase", (int) TQt::PaletteBase },
+ { "PaletteBackground", (int) TQt::PaletteBackground },
+ { "PaletteShadow", (int) TQt::PaletteShadow },
+ { "PaletteHighlight", (int) TQt::PaletteHighlight },
+ { "PaletteHighlightedText", (int) TQt::PaletteHighlightedText },
+ { "PaletteButtonText", (int) TQt::PaletteButtonText },
+ { "PaletteLink", (int) TQt::PaletteLink },
+ { "PaletteLinkVisited", (int) TQt::PaletteLinkVisited }
+ };
+
+ static const TQMetaEnum::Item enum_4[] = {
+ { "TextDate", (int) TQt::TextDate },
+ { "ISODate", (int) TQt::ISODate },
+ { "LocalDate", (int) TQt::LocalDate }
+ };
+
+
+ static const TQMetaEnum enum_tbl[] = {
+ { "Alignment", 10, enum_0, TRUE },
+ { "Orientation", 2, enum_1, FALSE },
+ { "TextFormat", 4, enum_2, FALSE },
+ { "BackgroundMode", 17, enum_3, FALSE },
+ { "DateFormat", 3, enum_4, FALSE }
+ };
+#endif
+
+ qtMetaObject = new TQMetaObject( "TQt", 0,
+ 0, 0,
+ 0, 0,
+#ifndef TQT_NO_PROPERTIES
+ 0, 0,
+ enum_tbl, 5,
+#endif
+ 0, 0 );
+ cleanUp_TQt.setMetaObject( qtMetaObject );
+
+ return qtMetaObject;
+}
+
+/*!
+ \internal
+
+ Signal activation with the most frequently used parameter/argument
+ types. All other combinations are generated by the meta object
+ compiler.
+ */
+void TQObject::activate_signal( int signal )
+{
+#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+ if ( qt_preliminary_signal_spy ) {
+ if ( !tqsignalsBlocked() && signal >= 0 &&
+ ( !connections || !connections->at( signal ) ) ) {
+ TQUObject o[1];
+ qt_spy_signal( this, signal, o );
+ return;
+ }
+ }
+#endif
+
+ if ( !connections || tqsignalsBlocked() || signal < 0 )
+ return;
+ TQConnectionList *clist = connections->at( signal );
+ if ( !clist )
+ return;
+ TQUObject o[1];
+ activate_signal( clist, o );
+}
+
+/*! \internal */
+
+void TQObject::activate_signal( TQConnectionList *clist, TQUObject *o )
+{
+ if ( !clist )
+ return;
+
+#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+ if ( qt_preliminary_signal_spy )
+ qt_spy_signal( this, connections->tqfindRef( clist), o );
+#endif
+
+ TQObject *object;
+ TQSenderObjectList* sol;
+ TQObject* oldSender = 0;
+ TQConnection *c;
+ if ( clist->count() == 1 ) { // save iterator
+ c = clist->first();
+ object = c->object();
+ sol = object->senderObjects;
+ if ( sol ) {
+ oldSender = sol->currentSender;
+ sol->ref();
+ sol->currentSender = this;
+ }
+ if ( c->memberType() == TQSIGNAL_CODE )
+ object->qt_emit( c->member(), o );
+ else
+ object->qt_invoke( c->member(), o );
+ if ( sol ) {
+ sol->currentSender = oldSender;
+ if ( sol->deref() )
+ delete sol;
+ }
+ } else {
+ TQConnection *cd = 0;
+ TQConnectionListIt it(*clist);
+ while ( (c=it.current()) ) {
+ ++it;
+ if ( c == cd )
+ continue;
+ cd = c;
+ object = c->object();
+ sol = object->senderObjects;
+ if ( sol ) {
+ oldSender = sol->currentSender;
+ sol->ref();
+ sol->currentSender = this;
+ }
+ if ( c->memberType() == TQSIGNAL_CODE )
+ object->qt_emit( c->member(), o );
+ else
+ object->qt_invoke( c->member(), o );
+ if (sol ) {
+ sol->currentSender = oldSender;
+ if ( sol->deref() )
+ delete sol;
+ }
+ }
+ }
+}
+
+/*!
+ \overload void TQObject::activate_signal( int signal, int )
+*/
+
+/*!
+ \overload void TQObject::activate_signal( int signal, double )
+*/
+
+/*!
+ \overload void TQObject::activate_signal( int signal, TQString )
+*/
+
+/*!
+ \fn void TQObject::activate_signal_bool( int signal, bool )
+ \internal
+
+ Like the above functions, but since bool is sometimes
+ only a typedef it cannot be a simple overload.
+*/
+
+#ifndef TQT_NO_PRELIMINARY_SIGNAL_SPY
+#define ACTIVATE_SIGNAL_WITH_PARAM(FNAME,TYPE) \
+void TQObject::FNAME( int signal, TYPE param ) \
+{ \
+ if ( qt_preliminary_signal_spy ) { \
+ if ( !tqsignalsBlocked() && signal >= 0 && \
+ ( !connections || !connections->at( signal ) ) ) { \
+ TQUObject o[2]; \
+ static_TQUType_##TYPE.set( o+1, param ); \
+ qt_spy_signal( this, signal, o ); \
+ return; \
+ } \
+ } \
+ if ( !connections || tqsignalsBlocked() || signal < 0 ) \
+ return; \
+ TQConnectionList *clist = connections->at( signal ); \
+ if ( !clist ) \
+ return; \
+ TQUObject o[2]; \
+ static_TQUType_##TYPE.set( o+1, param ); \
+ activate_signal( clist, o ); \
+}
+#else
+#define ACTIVATE_SIGNAL_WITH_PARAM(FNAME,TYPE) \
+void TQObject::FNAME( int signal, TYPE param ) \
+{ \
+ if ( !connections || tqsignalsBlocked() || signal < 0 ) \
+ return; \
+ TQConnectionList *clist = connections->at( signal ); \
+ if ( !clist ) \
+ return; \
+ TQUObject o[2]; \
+ static_TQUType_##TYPE.set( o+1, param ); \
+ activate_signal( clist, o ); \
+}
+
+#endif
+// We don't want to duplicate too much text so...
+
+ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, int )
+ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, double )
+ACTIVATE_SIGNAL_WITH_PARAM( activate_signal, TQString )
+ACTIVATE_SIGNAL_WITH_PARAM( activate_signal_bool, bool )
+
+
+/*****************************************************************************
+ TQObject debugging output routines.
+ *****************************************************************************/
+
+static void dumpRecursive( int level, TQObject *object )
+{
+#if defined(TQT_DEBUG)
+ if ( object ) {
+ TQString buf;
+ buf.fill( '\t', level/2 );
+ if ( level % 2 )
+ buf += " ";
+ const char *name = object->name();
+ TQString flags="";
+ if ( tqApp->tqfocusWidget() == object )
+ flags += 'F';
+ if ( object->isWidgetType() ) {
+ TQWidget * w = (TQWidget *)object;
+ if ( w->isVisible() ) {
+ TQString t( "<%1,%2,%3,%4>" );
+ flags += t.arg(w->x()).arg(w->y()).arg(w->width()).arg(w->height());
+ } else {
+ flags += 'I';
+ }
+ }
+ qDebug( "%s%s::%s %s", (const char*)buf, object->className(), name,
+ flags.latin1() );
+ if ( !object->childrenListObject().isEmpty() ) {
+ TQObjectListIt it(object->childrenListObject());
+ TQObject * c;
+ while ( (c=it.current()) != 0 ) {
+ ++it;
+ dumpRecursive( level+1, c );
+ }
+ }
+ }
+#else
+ TQ_UNUSED( level )
+ TQ_UNUSED( object )
+#endif
+}
+
+/*!
+ Dumps a tree of tqchildren to the debug output.
+
+ This function is useful for debugging, but does nothing if the
+ library has been compiled in release mode (i.e. without debugging
+ information).
+*/
+
+void TQObject::dumpObjectTree()
+{
+ dumpRecursive( 0, this );
+}
+
+/*!
+ Dumps information about signal connections, etc. for this object
+ to the debug output.
+
+ This function is useful for debugging, but does nothing if the
+ library has been compiled in release mode (i.e. without debugging
+ information).
+*/
+
+void TQObject::dumpObjectInfo()
+{
+#if defined(TQT_DEBUG)
+ qDebug( "OBJECT %s::%s", className(), name( "unnamed" ) );
+ int n = 0;
+ qDebug( " SIGNALS OUT" );
+ if ( connections ) {
+ TQConnectionList *clist;
+ for ( uint i = 0; i < connections->size(); i++ ) {
+ if ( ( clist = connections->at( i ) ) ) {
+ qDebug( "\t%s", tqmetaObject()->signal( i, TRUE )->name );
+ n++;
+ register TQConnection *c;
+ TQConnectionListIt cit(*clist);
+ while ( (c=cit.current()) ) {
+ ++cit;
+ qDebug( "\t --> %s::%s %s", c->object()->className(),
+ c->object()->name( "unnamed" ), c->memberName() );
+ }
+ }
+ }
+ }
+ if ( n == 0 )
+ qDebug( "\t<None>" );
+
+ qDebug( " SIGNALS IN" );
+ n = 0;
+ if ( senderObjects ) {
+ TQObject *sender = senderObjects->first();
+ while ( sender ) {
+ qDebug( "\t%s::%s",
+ sender->className(), sender->name( "unnamed" ) );
+ n++;
+ sender = senderObjects->next();
+ }
+ }
+ if ( n == 0 )
+ qDebug( "\t<None>" );
+#endif
+}
+
+#ifndef TQT_NO_PROPERTIES
+
+/*!
+ Sets the value of the object's \a name property to \a value.
+
+ Returns TRUE if the operation was successful; otherwise returns
+ FALSE.
+
+ Information about all available properties is provided through the
+ tqmetaObject().
+
+ \sa property(), tqmetaObject(), TQMetaObject::propertyNames(), TQMetaObject::property()
+*/
+bool TQObject::setProperty( const char *name, const TQVariant& value )
+{
+ if ( !value.isValid() )
+ return FALSE;
+
+ TQVariant v = value;
+
+ TQMetaObject* meta = tqmetaObject();
+ if ( !meta )
+ return FALSE;
+ int id = meta->tqfindProperty( name, TRUE );
+ const TQMetaProperty* p = meta->property( id, TRUE );
+ if ( !p || !p->isValid() || !p->writable() ) {
+ qWarning( "%s::setProperty( \"%s\", value ) failed: property invalid, read-only or does not exist",
+ className(), name );
+ return FALSE;
+ }
+
+ if ( p->isEnumType() ) {
+ if ( v.type() == TQVariant::String || v.type() == TQVariant::CString ) {
+ if ( p->isSetType() ) {
+ TQString s = value.toString();
+ // TQStrList does not support split, use TQStringList for that.
+ TQStringList l = TQStringList::split( '|', s );
+ TQStrList keys;
+ for ( TQStringList::Iterator it = l.begin(); it != l.end(); ++it )
+ keys.append( (*it).stripWhiteSpace().latin1() );
+ v = TQVariant( p->keysToValue( keys ) );
+ } else {
+ v = TQVariant( p->keyToValue( value.toCString().data() ) );
+ }
+ } else if ( v.type() != TQVariant::Int && v.type() != TQVariant::UInt ) {
+ return FALSE;
+ }
+ return qt_property( id, 0, &v );
+ }
+
+ TQVariant::Type type = (TQVariant::Type)(p->flags >> 24);
+ if ( type == TQVariant::Invalid )
+ type = TQVariant::nameToType( p->type() );
+ if ( type != TQVariant::Invalid && !v.canCast( type ) )
+ return FALSE;
+ return qt_property( id, 0, &v );
+}
+
+/*!
+ Returns the value of the object's \a name property.
+
+ If no such property exists, the returned variant is invalid.
+
+ Information about all available properties are provided through
+ the tqmetaObject().
+
+ \sa setProperty(), TQVariant::isValid(), tqmetaObject(),
+ TQMetaObject::propertyNames(), TQMetaObject::property()
+*/
+TQVariant TQObject::property( const char *name ) const
+{
+ TQVariant v;
+ TQMetaObject* meta = tqmetaObject();
+ if ( !meta )
+ return v;
+ int id = meta->tqfindProperty( name, TRUE );
+ const TQMetaProperty* p = meta->property( id, TRUE );
+ if ( !p || !p->isValid() ) {
+ qWarning( "%s::property( \"%s\" ) failed: property invalid or does not exist",
+ className(), name );
+ return v;
+ }
+ TQObject* that = (TQObject*) this; // tqmoc ensures constness for the qt_property call
+ that->qt_property( id, 1, &v );
+ return v;
+}
+
+#endif // TQT_NO_PROPERTIES
+
+#ifndef TQT_NO_USERDATA
+/*!\internal
+ */
+uint TQObject::registerUserData()
+{
+ static int user_data_registration = 0;
+ return user_data_registration++;
+}
+
+/*!\internal
+ */
+TQObjectUserData::~TQObjectUserData()
+{
+}
+
+/*!\internal
+ */
+void TQObject::setUserData( uint id, TQObjectUserData* data)
+{
+ if ( !d )
+ d = new TQObjectPrivate( id+1 );
+ if ( id >= d->size() )
+ d->resize( id+1 );
+ d->insert( id, data );
+}
+
+/*!\internal
+ */
+TQObjectUserData* TQObject::userData( uint id ) const
+{
+ if ( d && id < d->size() )
+ return d->at( id );
+ return 0;
+}
+
+#endif // TQT_NO_USERDATA
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqobject.h b/tqtinterface/qt4/src/kernel/tqobject.h
new file mode 100644
index 0000000..347cafe
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqobject.h
@@ -0,0 +1,417 @@
+/****************************************************************************
+**
+** Definition of TQObject class
+**
+** Created : 930418
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQOBJECT_H
+#define TQOBJECT_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqobjectdefs.h"
+#include "tqwindowdefs.h"
+#include "tqstring.h"
+#include "tqevent.h"
+#include "tqnamespace.h"
+#include "tqobjectlist.h"
+#endif // TQT_H
+
+#define TQT_TR_NOOP(x) (x)
+#define TQT_TRANSLATE_NOOP(scope,x) (x)
+
+class TQMetaObject;
+class TQVariant;
+class TQMetaProperty;
+class TQPostEventList;
+class TQSenderObjectList;
+class TQObjectPrivate;
+#ifndef TQT_NO_USERDATA
+class TQObjectUserData;
+#endif
+struct TQUObject;
+
+#ifdef USE_QT4
+
+#include <Qt/qobject.h>
+#include <Qt/qapplication.h>
+
+#define TQT_TQOBJECT_REQUIRED_INITIALIZATION(x) connect(this, SIGNAL(destroyed(QObject*)), SLOT(tqt_handle_qt_destroyed(QObject*)));
+
+#define TQT_TQOBJECT_CHILDEVENT_REQUIRED_HANDLER(x) \
+ if (x->type() == QEvent::ChildAdded) { \
+ QChildEvent *tqce = new QChildEvent( (QEvent::Type)TQEvent::ChildInserted, ((QChildEvent*)x)->child() ); \
+ QApplication::postEvent( this, tqce ); \
+ }
+
+#define TQT_TQOBJECT_CHILDEVENT_CONDITIONAL if ((e->type() != QEvent::ChildAdded) && (e->type() != QEvent::ChildPolished))
+
+// Defined in tqwidget.cpp
+extern TQObject* convertFromTQT_BASE_OBJECT_NAMEPointer( TQT_BASE_OBJECT_NAME* x );
+extern const TQObject* convertFromTQT_BASE_OBJECT_NAMEPointerConst( const TQT_BASE_OBJECT_NAME* x );
+
+// Defined in tqobject.cpp
+extern TQMetaObject* tqstaticMetaObject_helper(const QMetaObject* mobj);
+
+class TQObject: public QObject, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQObject( TQT_BASE_OBJECT_NAME *tqparent=0, const char *name=0 );
+
+ TQObject *tqparent() const;
+ TQObjectList childrenListObject();
+ const TQObjectList childrenListObject() const;
+ const char *tqname() const;
+ const char *name() const;
+ const char *name(const char *defaultName) const;
+ TQObject *child( const char *objName, const char *inheritsClass = 0, bool recursiveSearch = TRUE );
+ bool tqsignalsBlocked() const;
+
+ virtual bool event( TQEvent * );
+ void killTimers();
+
+ void insertChild( TQObject *object );
+ void removeChild( TQObject *object );
+ bool isA(const char *classname) const;
+ bool inherits( const char * ) const;
+
+ void setName(const char *aName);
+
+ TQObjectList *queryList( const char *inheritsClass = 0, const char *objName = 0, bool regexpMatch = TRUE, bool recursiveSearch = TRUE ) const;
+
+ TQMetaObject *tqmetaObject() const;
+
+ virtual TQVariant property( const char *name ) const;
+
+ static const TQObjectList *objectTrees();
+ static const TQObjectList objectTreesListObject();
+
+ // TQt handler
+ virtual bool eventFilter( TQObject *, TQEvent * );
+
+ // Qt4 handler interface
+ virtual bool eventFilter( QObject *q, QEvent *e );
+ bool event( QEvent *e );
+
+ // Interoperability
+ static const TQObject& convertFromTQT_BASE_OBJECT_NAME( TQT_BASE_OBJECT_NAME& ql );
+
+protected:
+ bool checkConnectArgs(const char *signal, const TQT_BASE_OBJECT_NAME*, const char *member);
+
+// TQt event handlers
+protected:
+ virtual void timerEvent( TQTimerEvent * );
+ virtual void childEvent( TQChildEvent * );
+ virtual void customEvent( TQCustomEvent * );
+
+// Qt4 event handler interface
+protected:
+ virtual void timerEvent(QTimerEvent *e);
+ virtual void childEvent(QChildEvent *e);
+ virtual void customEvent(QEvent *e);
+
+public:
+ friend class TQApplication;
+ friend class TQBaseApplication;
+ friend class TQWidget;
+ friend class TQSignal;
+ friend class TQDialog;
+
+//protected:
+public:
+// // [FIXME]
+// // All of these need to be defined in terms of the Qt4 signal/slot mechanism somehow!
+// // It is possible that the tqmoc needs to remain completely separate from the Qt moc
+// // However, I am concerned that signal/slot mechanisms would then not work at all from TQt to Qt
+ TQConnectionList *tqreceivers( const char* signal ) const;
+ TQConnectionList *tqreceivers( int signal ) const;
+
+ // [FIXME]
+ // Verify that these are truly equivalent to their Qt3 counterparts!
+ void activate_signal( int signal );
+// void activate_signal( int signal, int );
+// void activate_signal( int signal, double );
+// void activate_signal( int signal, TQString );
+// void activate_signal_bool( int signal, bool );
+ void activate_signal( TQConnectionList *clist, TQUObject *o );
+
+ static TQCString normalizeSignalSlot( const char *signalSlot );
+
+public Q_SLOTS:
+ void tqt_handle_qt_destroyed(QObject* obj);
+
+Q_SIGNALS:
+ void destroyed( TQObject* obj );
+
+private:
+ TQSignalVec *connections;
+ TQSenderObjectList *senderObjects;
+ mutable TQString static_object_name;
+
+// Will these work as-is or do they need serious help?
+private:
+ uint isSignal : 1;
+ uint isWidget : 1;
+ uint pendTimer : 1;
+ uint blockSig : 1;
+ uint wasDeleted : 1;
+ uint isTree : 1;
+};
+
+// Interoperability
+inline static const TQObject& convertFromTQT_BASE_OBJECT_NAME( const TQT_BASE_OBJECT_NAME& qo ) {
+ return (*static_cast<const TQObject*>(&qo));
+}
+
+#else // USE_QT4
+
+#define TQT_TR_NOOP(x) (x)
+#define TQT_TRANSLATE_NOOP(scope,x) (x)
+
+class TQMetaObject;
+class TQVariant;
+class TQMetaProperty;
+class TQPostEventList;
+class TQSenderObjectList;
+class TQObjectPrivate;
+#ifndef TQT_NO_USERDATA
+class TQObjectUserData;
+#endif
+struct TQUObject;
+
+class TQ_EXPORT TQObject: public TQt
+{
+ TQ_OBJECT
+ Q_PROPERTY( TQCString name READ name WRITE setName )
+
+public:
+ TQObject( TQObject *tqparent=0, const char *name=0 );
+ virtual ~TQObject();
+
+#ifdef TQ_TQDOC
+ virtual const char *className() const;
+ static TQString tr( const char *, const char * );
+ static TQString trUtf8( const char *, const char * );
+ virtual TQMetaObject *tqmetaObject() const;
+#endif
+
+ virtual bool event( TQEvent * );
+ virtual bool eventFilter( TQObject *, TQEvent * );
+
+ bool isA( const char * ) const;
+ bool inherits( const char * ) const;
+
+ const char *name() const;
+ const char *name( const char * defaultName ) const;
+
+ virtual void setName( const char *name );
+ bool isWidgetType() const { return isWidget; }
+ bool highPriority() const { return FALSE; }
+
+ bool tqsignalsBlocked() const { return blockSig; }
+ void blockSignals( bool b );
+
+ int startTimer( int interval );
+ void killTimer( int id );
+ void killTimers();
+
+ TQObject *child( const char *objName, const char *inheritsClass = 0, bool recursiveSearch = TRUE ); //### const in 4.0
+ const TQObjectList *childrenListObject() const { return childObjects; }
+
+ static const TQObjectList *objectTrees();
+
+ TQObjectList *queryList( const char *inheritsClass = 0,
+ const char *objName = 0,
+ bool regexpMatch = TRUE,
+ bool recursiveSearch = TRUE ) const;
+
+ virtual void insertChild( TQObject * );
+ virtual void removeChild( TQObject * );
+
+ void installEventFilter( const TQObject * );
+ void removeEventFilter( const TQObject * );
+
+ static bool connect( const TQObject *sender, const char *signal,
+ const TQObject *receiver, const char *member );
+ bool connect( const TQObject *sender, const char *signal,
+ const char *member ) const;
+ static bool disconnect( const TQObject *sender, const char *signal,
+ const TQObject *receiver, const char *member );
+ bool disconnect( const char *signal=0,
+ const TQObject *receiver=0, const char *member=0 );
+ bool disconnect( const TQObject *receiver, const char *member=0 );
+ static void connectInternal( const TQObject *sender, int signal_index,
+ const TQObject *receiver, int membcode, int member_index );
+ static bool disconnectInternal( const TQObject *sender, int signal_index,
+ const TQObject *receiver, int membcode, int member_index );
+
+ void dumpObjectTree();
+ void dumpObjectInfo();
+
+#ifndef TQT_NO_PROPERTIES
+ virtual bool setProperty( const char *name, const TQVariant& value );
+ virtual TQVariant property( const char *name ) const;
+#endif // TQT_NO_PROPERTIES
+#ifdef TQT_NO_TRANSLATION
+ static TQString tr( const char *sourceText, const char * = 0);
+#ifndef TQT_NO_TEXTCODEC
+ static TQString trUtf8( const char *sourceText, const char * = 0);
+#endif
+#endif //TQT_NO_TRANSLATION
+
+#ifndef TQT_NO_USERDATA
+ static uint registerUserData();
+ void setUserData( uint id, TQObjectUserData* data);
+ TQObjectUserData* userData( uint id ) const;
+#endif // TQT_NO_USERDATA
+
+Q_SIGNALS:
+ void destroyed();
+ void destroyed( TQObject* obj );
+
+public:
+ TQObject *tqparent() const { return parentObj; }
+
+public Q_SLOTS:
+ void deleteLater();
+
+private Q_SLOTS:
+ void cleanupEventFilter( TQObject* );
+
+protected:
+ bool activate_filters( TQEvent * );
+ TQConnectionList *tqreceivers( const char* signal ) const;
+ TQConnectionList *tqreceivers( int signal ) const;
+ void activate_signal( int signal );
+ void activate_signal( int signal, int );
+ void activate_signal( int signal, double );
+ void activate_signal( int signal, TQString );
+ void activate_signal_bool( int signal, bool );
+ void activate_signal( TQConnectionList *clist, TQUObject *o );
+
+ const TQObject *sender();
+
+ virtual void timerEvent( TQTimerEvent * );
+ virtual void childEvent( TQChildEvent * );
+ virtual void customEvent( TQCustomEvent * );
+
+ virtual void connectNotify( const char *signal );
+ virtual void disconnectNotify( const char *signal );
+ virtual bool checkConnectArgs( const char *signal, const TQObject *receiver,
+ const char *member );
+ static TQCString normalizeSignalSlot( const char *signalSlot );
+
+private:
+ uint isSignal : 1;
+ uint isWidget : 1;
+ uint pendTimer : 1;
+ uint blockSig : 1;
+ uint wasDeleted : 1;
+ uint isTree : 1;
+
+ const char *objname;
+ TQObject *parentObj;
+ TQObjectList *childObjects;
+ TQSignalVec *connections;
+ TQSenderObjectList *senderObjects;
+ TQObjectList *eventFilters;
+ TQPostEventList *postedEvents;
+ TQObjectPrivate* d;
+
+ static TQMetaObject* staticTQtMetaObject();
+
+ friend class TQApplication;
+ friend class TQBaseApplication;
+ friend class TQWidget;
+ friend class TQSignal;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQObject( const TQObject & );
+ TQObject &operator=( const TQObject & );
+#endif
+};
+
+
+#ifndef TQT_NO_USERDATA
+class TQ_EXPORT TQObjectUserData {
+public:
+ virtual ~TQObjectUserData();
+};
+#endif
+
+
+inline bool TQObject::connect( const TQObject *sender, const char *signal,
+ const char *member ) const
+{
+ return connect( sender, signal, this, member );
+}
+
+
+inline bool TQObject::disconnect( const char *signal,
+ const TQObject *receiver, const char *member )
+{
+ return disconnect( this, signal, receiver, member );
+}
+
+
+inline bool TQObject::disconnect( const TQObject *receiver, const char *member )
+{
+ return disconnect( this, 0, receiver, member );
+}
+
+
+#ifdef TQT_NO_TRANSLATION
+inline TQString TQObject::tr( const char *sourceText, const char * ) {
+ return TQString::tqfromLatin1( sourceText );
+}
+#ifndef TQT_NO_TEXTCODEC
+inline TQString TQObject::trUtf8( const char *sourceText, const char * ) {
+ return TQString::fromUtf8( sourceText );
+}
+#endif
+#endif //TQT_NO_TRANSLATION
+
+
+#define TQ_DEFINED_TQOBJECT
+#include "tqwinexport.h"
+#endif // USE_QT4
+#endif // TQOBJECT_H
diff --git a/tqtinterface/qt4/src/kernel/tqobjectcleanuphandler.cpp b/tqtinterface/qt4/src/kernel/tqobjectcleanuphandler.cpp
new file mode 100644
index 0000000..fdee282
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqobjectcleanuphandler.cpp
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Implementation of TQObjectCleanupHandler class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqobjectcleanuphandler.h"
+#include "tqobjectlist.h"
+
+/*!
+ \class TQObjectCleanupHandler tqobjectcleanuphandler.h
+ \brief The TQObjectCleanupHandler class watches the lifetime of multiple TQObjects.
+
+ \ingroup objectmodel
+
+ A TQObjectCleanupHandler is useful whenever you need to know when a
+ number of \l{TQObject}s that are owned by someone else have been
+ deleted. This is important, for example, when referencing memory
+ in an application that has been allocated in a shared library.
+
+ Example:
+
+ \code
+ class FactoryComponent : public FactoryInterface, public TQLibraryInterface
+ {
+ public:
+ ...
+
+ TQObject *createObject();
+
+ bool init();
+ void cleanup();
+ bool canUnload() const;
+
+ private:
+ TQObjectCleanupHandler objects;
+ };
+
+ // allocate a new object, and add it to the cleanup handler
+ TQObject *FactoryComponent::createObject()
+ {
+ return objects.add( new TQObject() );
+ }
+
+ // TQLibraryInterface implementation
+ bool FactoryComponent::init()
+ {
+ return TRUE;
+ }
+
+ void FactoryComponent::cleanup()
+ {
+ }
+
+ // it is only safe to unload the library when all TQObject's have been destroyed
+ bool FactoryComponent::canUnload() const
+ {
+ return objects.isEmpty();
+ }
+ \endcode
+*/
+
+/*!
+ Constructs an empty TQObjectCleanupHandler.
+*/
+TQObjectCleanupHandler::TQObjectCleanupHandler()
+: TQObject(), cleanupObjects( 0 )
+{
+}
+
+/*!
+ Destroys the cleanup handler. All objects in this cleanup handler
+ will be deleted.
+*/
+TQObjectCleanupHandler::~TQObjectCleanupHandler()
+{
+ clear();
+}
+
+/*!
+ Adds \a object to this cleanup handler and returns the pointer to
+ the object.
+*/
+TQObject* TQObjectCleanupHandler::add( TQObject* object )
+{
+ if ( !object )
+ return 0;
+
+ if ( !cleanupObjects ) {
+ cleanupObjects = new TQObjectList;
+ cleanupObjects->setAutoDelete( TRUE );
+ }
+ connect( object, TQT_SIGNAL(destroyed(TQObject*)), this, TQT_SLOT(objectDestroyed(TQObject*)) );
+ cleanupObjects->insert( 0, object );
+ return object;
+}
+
+/*!
+ Removes the \a object from this cleanup handler. The object will
+ not be destroyed.
+*/
+void TQObjectCleanupHandler::remove( TQObject *object )
+{
+ if ( !cleanupObjects )
+ return;
+ if ( cleanupObjects->tqfindRef( object ) >= 0 ) {
+ (void) cleanupObjects->take();
+ disconnect( object, TQT_SIGNAL(destroyed(TQObject*)), this, TQT_SLOT(objectDestroyed(TQObject*)) );
+ }
+}
+
+/*!
+ Returns TRUE if this cleanup handler is empty or if all objects in
+ this cleanup handler have been destroyed; otherwise return FALSE.
+*/
+bool TQObjectCleanupHandler::isEmpty() const
+{
+ return cleanupObjects ? cleanupObjects->isEmpty() : TRUE;
+}
+
+/*!
+ Deletes all objects in this cleanup handler. The cleanup handler
+ becomes empty.
+*/
+void TQObjectCleanupHandler::clear()
+{
+ delete cleanupObjects;
+ cleanupObjects = 0;
+}
+
+void TQObjectCleanupHandler::objectDestroyed( TQObject*object )
+{
+ if ( cleanupObjects )
+ cleanupObjects->setAutoDelete( FALSE );
+
+ remove( object );
+
+ if ( cleanupObjects )
+ cleanupObjects->setAutoDelete( TRUE );
+}
diff --git a/tqtinterface/qt4/src/kernel/tqobjectcleanuphandler.h b/tqtinterface/qt4/src/kernel/tqobjectcleanuphandler.h
new file mode 100644
index 0000000..0069167
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqobjectcleanuphandler.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Definition of ???
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQOBJECTCLEANUPHANDLER_H
+#define TQOBJECTCLEANUPHANDLER_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+
+class TQObjectList;
+
+class TQ_EXPORT TQObjectCleanupHandler : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQObjectCleanupHandler();
+ ~TQObjectCleanupHandler();
+
+ TQObject* add( TQObject* object );
+ void remove( TQObject *object );
+ bool isEmpty() const;
+ void clear();
+
+private:
+ TQObjectList *cleanupObjects;
+
+private Q_SLOTS:
+ void objectDestroyed( TQObject * );
+};
+
+#endif // TQOBJECTCLEANUPHANDLER_H
diff --git a/tqtinterface/qt4/src/kernel/tqobjectdefs.h b/tqtinterface/qt4/src/kernel/tqobjectdefs.h
new file mode 100644
index 0000000..794d1f0
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqobjectdefs.h
@@ -0,0 +1,277 @@
+/****************************************************************************
+**
+** Macros and definitions related to TQObject
+**
+** Created : 930419
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQOBJECTDEFS_H
+#define TQOBJECTDEFS_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qobject.h>
+#include <Qt/qmetaobject.h>
+#undef TQT_H
+#include "tqvariant.h"
+
+#endif
+
+
+#ifndef TQT_NO_TRANSLATION
+# ifndef TQT_NO_TEXTCODEC
+// full set of tr functions
+# define TQT_TR_FUNCTIONS \
+ static TQString tr( const char *, const char * = 0 ); \
+ static TQString trUtf8( const char *, const char * = 0 );
+# else
+// no TQTextCodec, no utf8
+# define TQT_TR_FUNCTIONS \
+ static TQString tr( const char *, const char * = 0 );
+# endif
+#else
+// inherit the ones from TQObject
+# define TQT_TR_FUNCTIONS
+#endif
+
+#ifdef USE_QT4
+
+#ifndef TQT_NO_PROPERTIES
+# define TQT_PROP_FUNCTIONS \
+ inline virtual bool qt_property( int id, int f, TQVariant* v) { \
+ /* f==0 is write and f==1 is read */ \
+ QMetaProperty p = metaObject()->property(id); \
+ switch (f) { \
+ case 0: \
+ p.write(this, *v); \
+ break; \
+ case 1: \
+ *static_cast<QVariant*>(v) = p.read(this); \
+ break; \
+ } \
+ return true; /* Always assume success */ \
+ } \
+ //static bool qt_static_property( TQObject* , int, int, TQVariant* );
+#else
+# define TQT_PROP_FUNCTIONS
+#endif
+
+#else // USE_QT4
+
+#ifndef TQT_NO_PROPERTIES
+# define TQT_PROP_FUNCTIONS \
+ virtual bool qt_property( int id, int f, TQVariant* v); \
+ static bool qt_static_property( TQObject* , int, int, TQVariant* );
+#else
+# define TQT_PROP_FUNCTIONS
+#endif
+
+#endif // USE_QT4
+
+// The following macros are our "extensions" to C++
+// They are used, strictly speaking, only by the tqmoc.
+struct TQUObject;
+
+#ifdef TQT_TQMOC_CPP
+#define Q_SLOTS Q_SLOTS
+#define Q_SIGNALS Q_SIGNALS
+#define TQ_CLASSINFO( name, value ) TQ_CLASSINFO( name, value )
+#define TQ_PROPERTY( text ) TQ_PROPERTY( text )
+#define TQ_OVERRIDE( text ) TQ_OVERRIDE( text )
+#define TQ_ENUMS( x ) TQ_ENUMS( x )
+#define TQ_SETS( x ) TQ_SETS( x )
+
+#ifdef USE_QT4
+// /* tmake ignore TQ_OBJECT */
+#define TQ_OBJECT //
+// /* tmake ignore TQ_OBJECT */
+#define TQ_OBJECT_FAKE //
+#else // USE_QT4
+ /* tmake ignore TQ_OBJECT */
+#define TQ_OBJECT TQ_OBJECT
+ /* tmake ignore TQ_OBJECT */
+#define TQ_OBJECT_FAKE TQ_OBJECT_FAKE
+#endif // USE_QT4
+
+#else
+#define Q_SLOTS // Q_SLOTS: in class
+#define Q_SIGNALS protected // Q_SIGNALS: in class
+#ifndef TQT_NO_EMIT
+#define emit // emit signal
+#endif
+#define TQ_CLASSINFO( name, value ) // class info
+#define TQ_PROPERTY( text ) // property
+#define TQ_OVERRIDE( text ) // override property
+#define TQ_ENUMS( x )
+#define TQ_SETS( x )
+
+#ifdef USE_QT4
+
+# ifndef TQT_NO_TEXTCODEC
+// full set of tr functions
+# define TQT_TR_FUNCTIONS_QT4 \
+ inline static TQString tqtr( const char *ch1, const char *ch2 = 0 ) { return TQT_TQSTRING(tr(ch1, ch2)); } \
+ inline static TQString tqtrUtf8( const char *ch1, const char *ch2 = 0 ) { return TQT_TQSTRING(tr(ch1, ch2)); }
+# else
+// no TQTextCodec, no utf8
+# define TQT_TR_FUNCTIONS_QT4 \
+ inline static TQString tqtr( const char *ch1, const char *ch2 = 0 ) { return TQT_TQSTRING(tr(ch1, ch2)); }
+# endif
+
+#define TQ_OBJECT \
+public: \
+ inline static TQMetaObject* tqstaticMetaObject() \
+ { return tqstaticMetaObject_helper(&staticMetaObject); } \
+ inline virtual const char *className() const \
+ { return metaObject()->className(); } \
+ inline virtual void* tqqt_cast( const char* ctname ) \
+ { if (inherits(ctname)) \
+ return const_cast<TQT_BASE_OBJECT_NAME *>(reinterpret_cast<TQT_BASE_OBJECT_NAME *>(0)->staticMetaObject.cast(const_cast<QObject *>(static_cast<const QObject*>(TQT_TQOBJECT_CONST(this))))); \
+ return 0; } /* [FIXME] VERIFY THIS!!! */ \
+ inline void* qt_cast( const char* ctname ) \
+ { if (inherits(ctname)) \
+ return const_cast<TQT_BASE_OBJECT_NAME *>(reinterpret_cast<TQT_BASE_OBJECT_NAME *>(0)->staticMetaObject.cast(const_cast<QObject *>(static_cast<const QObject*>(TQT_TQOBJECT_CONST(this))))); \
+ return 0; } /* [FIXME] VERIFY THIS!!! */ \
+ inline virtual bool qt_invoke( int, TQUObject* ) \
+ { printf("[WARNING] qt_invoke unimplemented\n\r"); return false; } \
+ inline virtual bool qt_emit( int, TQUObject* ) \
+ { printf("[WARNING] qt_emit unimplemented\n\r"); return false; } \
+ TQT_PROP_FUNCTIONS \
+ TQT_TR_FUNCTIONS_QT4
+
+#else // USE_QT4
+/* tmake ignore TQ_OBJECT */
+#define TQ_OBJECT \
+public: \
+ virtual TQMetaObject *tqmetaObject() const { \
+ return staticMetaObject(); \
+ } \
+ virtual const char *className() const; \
+ virtual void* tqqt_cast( const char* ); \
+ virtual bool qt_invoke( int, TQUObject* ); \
+ virtual bool qt_emit( int, TQUObject* ); \
+ TQT_PROP_FUNCTIONS \
+ static TQMetaObject* staticMetaObject(); \
+ TQObject* qObject() { return (TQObject*)this; } \
+ TQT_TR_FUNCTIONS \
+private: \
+ static TQMetaObject *metaObj;
+
+#endif // USE_QT4
+
+/* tmake ignore TQ_OBJECT */
+#define TQ_OBJECT_FAKE TQ_OBJECT
+
+#endif
+
+// macro for naming members
+#ifdef TQT_METHOD
+#undef TQT_METHOD
+#endif
+#ifdef TQT_SLOT
+#undef TQT_SLOT
+#endif
+#ifdef TQT_SIGNAL
+#undef TQT_SIGNAL
+#endif
+
+#if defined(_OLD_CPP_)
+#define TQT_METHOD(a) "0""a"
+#define TQT_SLOT(a) "1""a"
+#define TQT_SIGNAL(a) "2""a"
+#else
+#define TQT_METHOD(a) "0"#a
+#define TQT_SLOT(a) "1"#a
+#define TQT_SIGNAL(a) "2"#a
+#endif
+
+#ifndef TQT_CLEAN_NAMESPACE
+#define METHOD_CODE 0 // member type codes
+#define SLOT_CODE 1
+#define SIGNAL_CODE 2
+#endif
+
+#define TQMETHOD_CODE 0 // member type codes
+#define TQSLOT_CODE 1
+#define TQSIGNAL_CODE 2
+
+class TQObject;
+class TQMetaObject;
+class TQSignal;
+class TQConnection;
+class TQEvent;
+struct TQMetaData;
+class TQConnectionList;
+class TQConnectionListIt;
+class TQSignalVec;
+class TQObjectList;
+class TQObjectListIt;
+class TQMemberDict;
+
+TQ_EXPORT void *qt_tqfind_obj_child( TQObject *, const char *, const char * );
+#define TQ_CHILD(tqparent,type,name) \
+ ((type*)qt_tqfind_obj_child(tqparent,#type,name))
+
+TQ_EXPORT void *qt_inheritedBy( TQMetaObject *super, const TQObject *cls );
+
+// template <typename T>
+// TQ_INLINE_TEMPLATES T tqqt_cast(const TQObject *object)
+// { return (T)qt_inheritedBy( ((T)0)->staticMetaObject(), object ); }
+
+// template <typename T>
+// TQ_INLINE_TEMPLATES T tqqt_cast(const TQT_BASE_OBJECT_NAME *object)
+// { return (T)qt_inheritedBy( ((T)0)->staticMetaObject(), TQT_TQOBJECT_CONST(object) ); }
+
+template <typename T>
+TQ_INLINE_TEMPLATES T tqqt_cast(const TQT_BASE_OBJECT_NAME *object)
+//{ return (const T)qobject_cast<const T>(object); }
+{
+// // this will cause a compilation error if T is not const
+// register T ptr = static_cast<T>(object);
+// Q_UNUSED(ptr);
+
+#if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(QT_NO_QOBJECT_CHECK)
+ reinterpret_cast<T>(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast<T>(const_cast<TQT_BASE_OBJECT_NAME *>(object)));
+#endif
+ return static_cast<T>(const_cast<TQT_BASE_OBJECT_NAME *>(reinterpret_cast<T>(0)->staticMetaObject.cast(const_cast<TQT_BASE_OBJECT_NAME *>(object))));
+}
+#endif // TQOBJECTDEFS_H
diff --git a/tqtinterface/qt4/src/kernel/tqobjectdict.h b/tqtinterface/qt4/src/kernel/tqobjectdict.h
new file mode 100644
index 0000000..1e9e93e
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqobjectdict.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Definition of TQObjectDictionary
+**
+** Created : 940807
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQOBJECTDICT_H
+#define TQOBJECTDICT_H
+
+#ifndef TQT_H
+#include "tqmetaobject.h"
+#include "tqasciidict.h"
+#endif // TQT_H
+
+
+//
+// The object dictionary is a collection of TQMetaObjects
+//
+
+class TQ_EXPORT TQObjectDictionary : public TQAsciiDict<TQMetaObject>
+{
+public:
+ TQObjectDictionary(int size=17,bool cs=TRUE,bool ck=TRUE)
+ : TQAsciiDict<TQMetaObject>(size,cs,ck) {}
+ TQObjectDictionary( const TQObjectDictionary &dict )
+ : TQAsciiDict<TQMetaObject>(dict) {}
+ ~TQObjectDictionary() { clear(); }
+ TQObjectDictionary &operator=(const TQObjectDictionary &dict)
+ { return (TQObjectDictionary&)TQAsciiDict<TQMetaObject>::operator=(dict);}
+};
+
+#endif // TQOBJECTDICT_H
diff --git a/tqtinterface/qt4/src/kernel/tqobjectlist.h b/tqtinterface/qt4/src/kernel/tqobjectlist.h
new file mode 100644
index 0000000..337a795
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqobjectlist.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Definition of TQObjectList
+**
+** Created : 940807
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQOBJECTLIST_H
+#define TQOBJECTLIST_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqptrlist.h"
+#endif // TQT_H
+
+
+#if defined(TQ_TEMPLATEDLL)
+//TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrList<TQObject>;
+//TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrListIterator<TQObject>;
+#endif
+
+
+class TQ_EXPORT TQObjectList : public TQPtrList<TQObject>
+{
+public:
+ TQObjectList() : TQPtrList<TQObject>() {}
+ TQObjectList( const TQObjectList &list ) : TQPtrList<TQObject>(list) {}
+ ~TQObjectList() { clear(); }
+ TQObjectList &operator=(const TQObjectList &list)
+ { return (TQObjectList&)TQPtrList<TQObject>::operator=(list); }
+};
+
+class TQ_EXPORT TQObjectListIterator : public TQPtrListIterator<TQObject>
+{
+public:
+ TQObjectListIterator( const TQObjectList &l )
+ : TQPtrListIterator<TQObject>( l ) { }
+ TQObjectListIterator &operator=( const TQObjectListIterator &i )
+ { return (TQObjectListIterator&)
+ TQPtrListIterator<TQObject>::operator=( i ); }
+};
+
+#if (TQT_VERSION-0 >= 0x040000)
+#if defined(TQ_CC_GNU)
+#warning "remove the TQObjectListIt class"
+#warning "remove the typedef too, maybe"
+#endif
+typedef TQObjectListIterator TQObjectListIt;
+#else
+class TQ_EXPORT TQObjectListIt : public TQPtrListIterator<TQObject>
+{
+public:
+ TQObjectListIt( const TQObjectList &l ) : TQPtrListIterator<TQObject>(l) {}
+ TQObjectListIt &operator=(const TQObjectListIt &i)
+ { return (TQObjectListIt&)TQPtrListIterator<TQObject>::operator=(i); }
+};
+#endif
+
+#endif // TQOBJECTLIST_H
diff --git a/tqtinterface/qt4/src/kernel/tqpaintdevice.h b/tqtinterface/qt4/src/kernel/tqpaintdevice.h
new file mode 100644
index 0000000..5c7a2c7
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpaintdevice.h
@@ -0,0 +1,688 @@
+/****************************************************************************
+**
+** Definition of TQPaintDevice class
+**
+** Created : 940721
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPAINTDEVICE_H
+#define TQPAINTDEVICE_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqrect.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qapplication.h>
+#include <Qt/qx11info_x11.h>
+#include <Qt/qpaintdevice.h>
+#include <Qt/qpaintengine.h>
+
+#endif // USE_QT4
+
+#if defined(TQ_WS_TQWS)
+class TQWSDisplay;
+class TQGfx;
+#endif
+
+class TQIODevice;
+class TQString;
+class TQTextItem;
+
+#ifdef USE_QT4
+
+#if defined(TQ_WS_X11)
+struct TQPaintDeviceX11Data;
+#endif
+
+// There does not seem to be a Qt4 equivalent for this
+union TQPDevCmdParam {
+ int ival;
+ int *ivec;
+ TQString *str;
+ const TQPoint *point;
+ const TQRect *rect;
+ const TQPointArray *ptarr;
+ const TQPixmap *pixmap;
+ const TQImage *image;
+ const TQColor *color;
+ const TQFont *font;
+ const TQPen *pen;
+ const TQBrush *brush;
+ const TQRegion *rgn;
+ const TQWMatrix *matrix;
+ const TQTextItem *textItem;
+ TQIODevice *tqdevice;
+};
+
+class TQPaintDevice;
+
+class TQ_EXPORT TQPaintDeviceEngineTranslator : public QPaintEngine
+{
+public:
+ TQPaintDeviceEngineTranslator() : QPaintEngine() {}
+ TQPaintDeviceEngineTranslator(TQPaintDevice* tqpd) : QPaintEngine() { parent_paintdevice = tqpd; }
+
+ inline void setPaintDevice(TQPaintDevice* tqpd) { parent_paintdevice = tqpd; }
+
+ // Reimplemented QPaintEngine methods
+ virtual bool begin(QPaintDevice*);
+ virtual bool end();
+ virtual void updateState(const QPaintEngineState&);
+ virtual void drawPixmap(const QRectF&, const QPixmap&, const QRectF&);
+ virtual QPaintEngine::Type type() const;
+
+private:
+ TQPaintDevice* parent_paintdevice;
+};
+
+class TQ_EXPORT TQPaintDevice : public QPaintDevice, virtual public TQt
+{
+public:
+ TQPaintDevice() : QPaintDevice() { tqpet.setPaintDevice(this); }
+// TQPaintDevice( const QPaintDevice &pd ) : QPaintDevice( pd ) {}
+
+ inline static void *x11AppVisual( void ) { return x11AppVisual(-1); }
+ inline static void *x11AppVisual( int screen ) { return QX11Info::appVisual(screen); }
+ inline static int x11AppCells( void ) { return x11AppCells(-1); }
+ inline static int x11AppCells( int screen ) { return QX11Info::appCells(screen); }
+ inline static int x11AppDepth( void ) { return x11AppDepth(-1); }
+ inline static int x11AppDepth( int screen ) { return QX11Info::appDepth(screen); }
+ inline static Display *x11AppDisplay( void ) { return QX11Info::display(); }
+ inline static int x11AppScreen( void ) { return QX11Info::appScreen(); }
+ inline static bool x11AppDefaultVisual( void ) { return x11AppDefaultVisual(-1); }
+ inline static bool x11AppDefaultVisual( int screen ) { return QX11Info::appDefaultVisual(screen); }
+ inline static TQt::HANDLE x11AppColormap( void ) { return x11AppColormap(-1); }
+ inline static TQt::HANDLE x11AppColormap( int screen ) { return QX11Info::appColormap(screen); }
+ inline static bool x11AppDefaultColormap( void ) { return x11AppDefaultColormap(-1); }
+ inline static bool x11AppDefaultColormap( int screen ) { return QX11Info::appDefaultColormap(screen); }
+ inline static TQt::HANDLE x11AppRootWindow( void ) { return x11AppRootWindow(-1); }
+ inline static TQt::HANDLE x11AppRootWindow( int screen ) { return QX11Info::appRootWindow(screen); }
+
+ bool isExtDev() const;
+
+ // Windows: get tqdevice context
+ // X-Windows: get drawable
+#if defined(TQ_WS_WIN)
+// virtual HDC handle() const;
+#elif defined(TQ_WS_X11)
+ virtual TQt::HANDLE handle() const;
+ virtual TQt::HANDLE x11RenderHandle() const;
+#elif defined(TQ_WS_MAC)
+// virtual TQt::HANDLE handle() const;
+#elif defined(TQ_WS_TQWS)
+// virtual TQt::HANDLE handle() const;
+#endif
+
+#if defined(TQ_WS_X11)
+ Display *x11Display() const;
+ int x11Screen() const;
+ int x11Depth() const;
+ int x11Cells() const;
+ Qt::HANDLE x11Colormap() const;
+ bool x11DefaultColormap() const;
+ void *x11Visual() const;
+ bool x11DefaultVisual() const;
+
+ static int x11AppDpiX(int screen = -1);
+ static int x11AppDpiY(int screen = -1);
+ static void x11SetAppDpiX(int, int);
+ static void x11SetAppDpiY(int, int);
+#endif
+
+public:
+ // There does not seem to be a Qt4 equivalent for this
+ enum PDevCmd {
+ PdcNOP = 0, // <void>
+ PdcDrawPoint = 1, // point
+ PdcDrawFirst = PdcDrawPoint,
+ PdcMoveTo = 2, // point
+ PdcLineTo = 3, // point
+ PdcDrawLine = 4, // point,point
+ PdcDrawRect = 5, // rect
+ PdcDrawRoundRect = 6, // rect,ival,ival
+ PdcDrawEllipse = 7, // rect
+ PdcDrawArc = 8, // rect,ival,ival
+ PdcDrawPie = 9, // rect,ival,ival
+ PdcDrawChord = 10, // rect,ival,ival
+ PdcDrawLineSegments = 11, // ptarr
+ PdcDrawPolyline = 12, // ptarr
+ PdcDrawPolygon = 13, // ptarr,ival
+ PdcDrawCubicBezier = 14, // ptarr
+ PdcDrawText = 15, // point,str
+ PdcDrawTextFormatted = 16, // rect,ival,str
+ PdcDrawPixmap = 17, // rect,pixmap
+ PdcDrawImage = 18, // rect,image
+ PdcDrawText2 = 19, // point,str
+ PdcDrawText2Formatted = 20, // rect,ival,str
+ PdcDrawTextItem = 21,
+ PdcDrawLast = PdcDrawTextItem,
+
+ // no painting commands below PdcDrawLast.
+
+ PdcBegin = 30, // <void>
+ PdcEnd = 31, // <void>
+ PdcSave = 32, // <void>
+ PdcRestore = 33, // <void>
+ PdcSetdev = 34, // tqdevice - PRIVATE
+ PdcSetBkColor = 40, // color
+ PdcSetBkMode = 41, // ival
+ PdcSetROP = 42, // ival
+ PdcSetBrushOrigin = 43, // point
+ PdcSetFont = 45, // font
+ PdcSetPen = 46, // pen
+ PdcSetBrush = 47, // brush
+ PdcSetTabStops = 48, // ival
+ PdcSetTabArray = 49, // ival,ivec
+ PdcSetUnit = 50, // ival
+ PdcSetVXform = 51, // ival
+ PdcSetWindow = 52, // rect
+ PdcSetViewport = 53, // rect
+ PdcSetWXform = 54, // ival
+ PdcSetWMatrix = 55, // matrix,ival
+ PdcSaveWMatrix = 56,
+ PdcRestoreWMatrix = 57,
+ PdcSetClip = 60, // ival
+ PdcSetClipRegion = 61, // rgn
+
+ PdcReservedStart = 0, // codes 0-199 are reserved
+ PdcReservedStop = 199 // for TQt
+ };
+
+protected:
+ TQPaintDevice( uint devflags );
+#if defined(TQ_WS_X11)
+ friend void qt_init_internal( int *, char **, Display *, TQt::HANDLE, TQt::HANDLE );
+ friend void qt_cleanup();
+ virtual bool cmd( int, TQPainter *, TQPDevCmdParam * );
+ virtual QPaintEngine* paintEngine() const;
+#endif
+
+private:
+#if defined(TQ_WS_X11)
+ static Display *x_appdisplay;
+ static int x_appscreen;
+
+ static int x_appdepth;
+ static int x_appcells;
+ static TQt::HANDLE x_approotwindow;
+ static TQt::HANDLE x_appcolormap;
+ static bool x_appdefcolormap;
+ static void *x_appvisual;
+ static bool x_appdefvisual;
+
+ // ### in 4.0, remove the above, and tqreplace with the below
+ static int *x_appdepth_arr;
+ static int *x_appcells_arr;
+ static TQt::HANDLE *x_approotwindow_arr;
+ static TQt::HANDLE *x_appcolormap_arr;
+ static bool *x_appdefcolormap_arr;
+ static void **x_appvisual_arr;
+ static bool *x_appdefvisual_arr;
+
+ TQPaintDeviceX11Data* x11Data;
+
+ TQPaintDeviceEngineTranslator tqpet;
+#endif
+
+public:
+ // Interoperability
+ static const TQPaintDevice& convertFromQPaintDevice( QPaintDevice& qpd );
+};
+
+// Interoperability
+inline static const TQPaintDevice& convertFromQPaintDevice( const QPaintDevice& qpd ) {
+ return (*static_cast<const TQPaintDevice*>(&qpd));
+}
+
+void bitBlt(QPaintDevice *dst, int dx, int dy,
+ const QPaintDevice *src, int sx=0, int sy=0, int sw=-1, int sh=-1,
+ bool ignoreMask=false);
+
+void bitBlt(QPaintDevice *dst, int dx, int dy,
+ const QImage *src, int sx=0, int sy=0, int sw=-1, int sh=-1,
+ int conversion_flags=0);
+
+void bitBlt(QPaintDevice *dst, const QPoint &dp,
+ const QPaintDevice *src, const QRect &sr=QRect(0,0,-1,-1),
+ bool ignoreMask=false);
+
+TQ_EXPORT void bitBlt( TQPaintDevice *dst, int dx, int dy, const TQPaintDevice *src, int sx=0, int sy=0, int sw=-1, int sh=-1, TQt::RasterOp = TQt::CopyROP, bool ignoreMask=FALSE );
+
+// [FIXME]
+inline bool TQPaintDevice::isExtDev() const
+//{ return (devFlags & TQInternal::ExternalDevice) != 0; }
+{ return false; }
+
+#if defined(TQ_WS_X11)
+
+struct TQ_EXPORT TQPaintDeviceX11Data : public TQShared {
+ Display* x_display;
+ int x_screen;
+ int x_depth;
+ int x_cells;
+ TQt::HANDLE x_colormap;
+ bool x_defcolormap;
+ void* x_visual;
+ bool x_defvisual;
+};
+
+#endif
+
+// This provides a default interface from the old Qt3 cmd based API to the new Qt4 QPaintEngine based API
+// It can (obviously) be overridden if someone desires to use QPaintEngine instead of the cmd based API!
+inline QPaintEngine* TQPaintDevice::paintEngine() const {
+ // Provide the address of the translator class...
+ return const_cast<TQPaintDeviceEngineTranslator*>(&tqpet);
+}
+
+TQ_EXPORT
+inline void bitBlt( TQPaintDevice *dst, const TQPoint &dp,
+ const TQPaintDevice *src, const TQRect &sr =TQRect(0,0,-1,-1),
+ TQt::RasterOp rop=TQt::CopyROP, bool ignoreMask=FALSE )
+{
+ bitBlt( dst, dp.x(), dp.y(), src, sr.x(), sr.y(), sr.width(), sr.height(),
+ rop, ignoreMask );
+}
+
+#else // USE_QT4
+
+#if defined(TQ_WS_X11)
+struct TQPaintDeviceX11Data;
+#endif
+
+union TQPDevCmdParam {
+ int ival;
+ int *ivec;
+ TQString *str;
+ const TQPoint *point;
+ const TQRect *rect;
+ const TQPointArray *ptarr;
+ const TQPixmap *pixmap;
+ const TQImage *image;
+ const TQColor *color;
+ const TQFont *font;
+ const TQPen *pen;
+ const TQBrush *brush;
+ const TQRegion *rgn;
+ const TQWMatrix *matrix;
+ const TQTextItem *textItem;
+ TQIODevice *tqdevice;
+};
+
+
+
+class TQ_EXPORT TQPaintDevice // tqdevice for TQPainter
+{
+public:
+ virtual ~TQPaintDevice();
+
+ int devType() const;
+ bool isExtDev() const;
+ bool paintingActive() const;
+
+ virtual void setResolution( int );
+ virtual int resolution() const;
+
+ // Windows: get tqdevice context
+ // X-Windows: get drawable
+#if defined(TQ_WS_WIN)
+ virtual HDC handle() const;
+#elif defined(TQ_WS_X11)
+ virtual TQt::HANDLE handle() const;
+ virtual TQt::HANDLE x11RenderHandle() const;
+#elif defined(TQ_WS_MAC)
+ virtual TQt::HANDLE handle() const;
+#elif defined(TQ_WS_TQWS)
+ virtual TQt::HANDLE handle() const;
+#endif
+
+#if defined(TQ_WS_X11)
+ Display *x11Display() const;
+ int x11Screen() const;
+ int x11Depth() const;
+ int x11Cells() const;
+ TQt::HANDLE x11Colormap() const;
+ bool x11DefaultColormap() const;
+ void *x11Visual() const;
+ bool x11DefaultVisual() const;
+
+ static Display *x11AppDisplay();
+ static int x11AppScreen();
+
+ static int x11AppDpiX();
+ static int x11AppDpiY();
+ static void x11SetAppDpiX(int);
+ static void x11SetAppDpiY(int);
+ static int x11AppDepth();
+ static int x11AppCells();
+ static TQt::HANDLE x11AppRootWindow();
+ static TQt::HANDLE x11AppColormap();
+ static bool x11AppDefaultColormap();
+ static void *x11AppVisual();
+ static bool x11AppDefaultVisual();
+
+ // ### in 4.0, the above need to go away, the below needs to take a -1 default
+ // argument, signifying the default screen...
+ static int x11AppDepth( int screen );
+ static int x11AppCells( int screen );
+ static TQt::HANDLE x11AppRootWindow( int screen );
+ static TQt::HANDLE x11AppColormap( int screen );
+ static void *x11AppVisual( int screen );
+ static bool x11AppDefaultColormap( int screen );
+ static bool x11AppDefaultVisual( int screen );
+ static int x11AppDpiX( int );
+ static int x11AppDpiY( int );
+ static void x11SetAppDpiX( int, int );
+ static void x11SetAppDpiY( int, int );
+#endif
+
+#if defined(TQ_WS_TQWS)
+ static TQWSDisplay *qwsDisplay();
+ virtual unsigned char * scanLine(int) const;
+ virtual int bytesPerLine() const;
+ virtual TQGfx * graphicsContext(bool clip_tqchildren=TRUE) const;
+#endif
+
+ enum PDevCmd {
+ PdcNOP = 0, // <void>
+ PdcDrawPoint = 1, // point
+ PdcDrawFirst = PdcDrawPoint,
+ PdcMoveTo = 2, // point
+ PdcLineTo = 3, // point
+ PdcDrawLine = 4, // point,point
+ PdcDrawRect = 5, // rect
+ PdcDrawRoundRect = 6, // rect,ival,ival
+ PdcDrawEllipse = 7, // rect
+ PdcDrawArc = 8, // rect,ival,ival
+ PdcDrawPie = 9, // rect,ival,ival
+ PdcDrawChord = 10, // rect,ival,ival
+ PdcDrawLineSegments = 11, // ptarr
+ PdcDrawPolyline = 12, // ptarr
+ PdcDrawPolygon = 13, // ptarr,ival
+ PdcDrawCubicBezier = 14, // ptarr
+ PdcDrawText = 15, // point,str
+ PdcDrawTextFormatted = 16, // rect,ival,str
+ PdcDrawPixmap = 17, // rect,pixmap
+ PdcDrawImage = 18, // rect,image
+ PdcDrawText2 = 19, // point,str
+ PdcDrawText2Formatted = 20, // rect,ival,str
+ PdcDrawTextItem = 21,
+ PdcDrawLast = PdcDrawTextItem,
+
+ // no painting commands below PdcDrawLast.
+
+ PdcBegin = 30, // <void>
+ PdcEnd = 31, // <void>
+ PdcSave = 32, // <void>
+ PdcRestore = 33, // <void>
+ PdcSetdev = 34, // tqdevice - PRIVATE
+ PdcSetBkColor = 40, // color
+ PdcSetBkMode = 41, // ival
+ PdcSetROP = 42, // ival
+ PdcSetBrushOrigin = 43, // point
+ PdcSetFont = 45, // font
+ PdcSetPen = 46, // pen
+ PdcSetBrush = 47, // brush
+ PdcSetTabStops = 48, // ival
+ PdcSetTabArray = 49, // ival,ivec
+ PdcSetUnit = 50, // ival
+ PdcSetVXform = 51, // ival
+ PdcSetWindow = 52, // rect
+ PdcSetViewport = 53, // rect
+ PdcSetWXform = 54, // ival
+ PdcSetWMatrix = 55, // matrix,ival
+ PdcSaveWMatrix = 56,
+ PdcRestoreWMatrix = 57,
+ PdcSetClip = 60, // ival
+ PdcSetClipRegion = 61, // rgn
+
+ PdcReservedStart = 0, // codes 0-199 are reserved
+ PdcReservedStop = 199 // for TQt
+ };
+
+protected:
+ TQPaintDevice( uint devflags );
+
+#if defined(TQ_WS_WIN)
+ HDC hdc; // tqdevice context
+#elif defined(TQ_WS_X11)
+ TQt::HANDLE hd; // handle to drawable
+ TQt::HANDLE rendhd; // handle to RENDER pict
+
+ void copyX11Data( const TQPaintDevice * );
+ void cloneX11Data( const TQPaintDevice * );
+ virtual void setX11Data( const TQPaintDeviceX11Data* );
+ TQPaintDeviceX11Data* getX11Data( bool def=FALSE ) const;
+#elif defined(TQ_WS_MAC)
+#if !defined( TQMAC_NO_TQUARTZ )
+ CGContextRef ctx;
+#endif
+ void * hd;
+#elif defined(TQ_WS_TQWS)
+ TQt::HANDLE hd;
+#endif
+
+ virtual bool cmd( int, TQPainter *, TQPDevCmdParam * );
+ virtual int metric( int ) const;
+ virtual int fontMet( TQFont *, int, const char * = 0, int = 0 ) const;
+ virtual int fontInf( TQFont *, int ) const;
+
+ ushort devFlags; // tqdevice flags
+ ushort painters; // refcount
+
+ friend class TQPainter;
+ friend class TQPaintDeviceMetrics;
+#if defined(TQ_WS_MAC)
+#ifndef TQMAC_NO_TQUARTZ
+ virtual CGContextRef macCGContext(bool clipped=TRUE) const;
+#endif
+ friend TQ_EXPORT void unclippedScaledBitBlt( TQPaintDevice *, int, int, int, int,
+ const TQPaintDevice *, int, int, int, int, TQt::RasterOp, bool, bool );
+#else
+ friend TQ_EXPORT void bitBlt( TQPaintDevice *, int, int,
+ const TQPaintDevice *,
+ int, int, int, int, TQt::RasterOp, bool );
+#endif
+#if defined(TQ_WS_X11)
+ friend void qt_init_internal( int *, char **, Display *, TQt::HANDLE, TQt::HANDLE );
+ friend void qt_cleanup();
+#endif
+
+private:
+#if defined(TQ_WS_X11)
+ static Display *x_appdisplay;
+ static int x_appscreen;
+
+ static int x_appdepth;
+ static int x_appcells;
+ static TQt::HANDLE x_approotwindow;
+ static TQt::HANDLE x_appcolormap;
+ static bool x_appdefcolormap;
+ static void *x_appvisual;
+ static bool x_appdefvisual;
+
+ // ### in 4.0, remove the above, and tqreplace with the below
+ static int *x_appdepth_arr;
+ static int *x_appcells_arr;
+ static TQt::HANDLE *x_approotwindow_arr;
+ static TQt::HANDLE *x_appcolormap_arr;
+ static bool *x_appdefcolormap_arr;
+ static void **x_appvisual_arr;
+ static bool *x_appdefvisual_arr;
+
+ TQPaintDeviceX11Data* x11Data;
+#endif
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQPaintDevice( const TQPaintDevice & );
+ TQPaintDevice &operator=( const TQPaintDevice & );
+#endif
+};
+
+
+TQ_EXPORT
+void bitBlt( TQPaintDevice *dst, int dx, int dy,
+ const TQPaintDevice *src, int sx=0, int sy=0, int sw=-1, int sh=-1,
+ TQt::RasterOp = TQt::CopyROP, bool ignoreMask=FALSE );
+
+TQ_EXPORT
+void bitBlt( TQPaintDevice *dst, int dx, int dy,
+ const TQImage *src, int sx=0, int sy=0, int sw=-1, int sh=-1,
+ int conversion_flags=0 );
+
+
+#if defined(TQ_WS_X11)
+
+struct TQ_EXPORT TQPaintDeviceX11Data : public TQShared {
+ Display* x_display;
+ int x_screen;
+ int x_depth;
+ int x_cells;
+ TQt::HANDLE x_colormap;
+ bool x_defcolormap;
+ void* x_visual;
+ bool x_defvisual;
+};
+
+#endif
+
+/*****************************************************************************
+ Inline functions
+ *****************************************************************************/
+
+inline int TQPaintDevice::devType() const
+{ return devFlags & TQInternal::DeviceTypeMask; }
+
+inline bool TQPaintDevice::isExtDev() const
+{ return (devFlags & TQInternal::ExternalDevice) != 0; }
+
+inline bool TQPaintDevice::paintingActive() const
+{ return painters != 0; }
+
+#if defined(TQ_WS_X11)
+inline Display *TQPaintDevice::x11Display() const
+{ return x11Data ? x11Data->x_display : x_appdisplay; }
+
+inline int TQPaintDevice::x11Screen() const
+{ return x11Data ? x11Data->x_screen : x_appscreen; }
+
+inline int TQPaintDevice::x11Depth() const
+{ return x11Data ? x11Data->x_depth : x_appdepth; }
+
+inline int TQPaintDevice::x11Cells() const
+{ return x11Data ? x11Data->x_cells : x_appcells; }
+
+inline TQt::HANDLE TQPaintDevice::x11Colormap() const
+{ return x11Data ? x11Data->x_colormap : x_appcolormap; }
+
+inline bool TQPaintDevice::x11DefaultColormap() const
+{ return x11Data ? x11Data->x_defcolormap : x_appdefcolormap; }
+
+inline void *TQPaintDevice::x11Visual() const
+{ return x11Data ? x11Data->x_visual : x_appvisual; }
+
+inline bool TQPaintDevice::x11DefaultVisual() const
+{ return x11Data ? x11Data->x_defvisual : x_appdefvisual; }
+
+inline Display *TQPaintDevice::x11AppDisplay()
+{ return x_appdisplay; }
+
+inline int TQPaintDevice::x11AppScreen()
+{ return x_appscreen; }
+
+inline int TQPaintDevice::x11AppDepth( int screen )
+{ return x_appdepth_arr[ screen == -1 ? x_appscreen : screen ]; }
+
+inline int TQPaintDevice::x11AppCells( int screen )
+{ return x_appcells_arr[ screen == -1 ? x_appscreen : screen ]; }
+
+inline TQt::HANDLE TQPaintDevice::x11AppRootWindow( int screen )
+{ return x_approotwindow_arr[ screen == -1 ? x_appscreen : screen ]; }
+
+inline TQt::HANDLE TQPaintDevice::x11AppColormap( int screen )
+{ return x_appcolormap_arr[ screen == -1 ? x_appscreen : screen ]; }
+
+inline bool TQPaintDevice::x11AppDefaultColormap( int screen )
+{ return x_appdefcolormap_arr[ screen == -1 ? x_appscreen : screen ]; }
+
+inline void *TQPaintDevice::x11AppVisual( int screen )
+{ return x_appvisual_arr[ screen == -1 ? x_appscreen : screen ]; }
+
+inline bool TQPaintDevice::x11AppDefaultVisual( int screen )
+{ return x_appdefvisual_arr[ screen == -1 ? x_appscreen : screen ]; }
+
+inline int TQPaintDevice::x11AppDepth()
+{ return x_appdepth; }
+
+inline int TQPaintDevice::x11AppCells()
+{ return x_appcells; }
+
+inline TQt::HANDLE TQPaintDevice::x11AppRootWindow()
+{ return x_approotwindow; }
+
+inline TQt::HANDLE TQPaintDevice::x11AppColormap()
+{ return x_appcolormap; }
+
+inline bool TQPaintDevice::x11AppDefaultColormap()
+{ return x_appdefcolormap; }
+
+inline void *TQPaintDevice::x11AppVisual()
+{ return x_appvisual; }
+
+inline bool TQPaintDevice::x11AppDefaultVisual()
+{ return x_appdefvisual; }
+
+#endif // TQ_WS_X11
+
+
+TQ_EXPORT
+inline void bitBlt( TQPaintDevice *dst, const TQPoint &dp,
+ const TQPaintDevice *src, const TQRect &sr =TQRect(0,0,-1,-1),
+ TQt::RasterOp rop=TQt::CopyROP, bool ignoreMask=FALSE )
+{
+ bitBlt( dst, dp.x(), dp.y(), src, sr.x(), sr.y(), sr.width(), sr.height(),
+ rop, ignoreMask );
+}
+
+#endif // USE_QT4
+
+#endif // TQPAINTDEVICE_H
diff --git a/tqtinterface/qt4/src/kernel/tqpaintdevice_x11.cpp b/tqtinterface/qt4/src/kernel/tqpaintdevice_x11.cpp
new file mode 100644
index 0000000..2432607
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpaintdevice_x11.cpp
@@ -0,0 +1,1746 @@
+/****************************************************************************
+**
+** Implementation of TQPaintDevice class for X11
+**
+** Created : 940721
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpaintdevice.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqpainter.h"
+#include "tqwidget.h"
+#include "tqbitmap.h"
+#include "tqapplication.h"
+#include "tqt_x11_p.h"
+
+#ifdef USE_QT4
+
+//
+// Some global variables - these are initialized by TQColor::initialize()
+//
+
+Display *TQPaintDevice::x_appdisplay = 0;
+int TQPaintDevice::x_appscreen;
+
+int TQPaintDevice::x_appdepth;
+int TQPaintDevice::x_appcells;
+TQt::HANDLE TQPaintDevice::x_approotwindow;
+TQt::HANDLE TQPaintDevice::x_appcolormap;
+bool TQPaintDevice::x_appdefcolormap;
+void *TQPaintDevice::x_appvisual;
+bool TQPaintDevice::x_appdefvisual;
+
+// ### in 4.0, remove the above, and use the below
+int *TQPaintDevice::x_appdepth_arr;
+int *TQPaintDevice::x_appcells_arr;
+TQt::HANDLE *TQPaintDevice::x_approotwindow_arr;
+TQt::HANDLE *TQPaintDevice::x_appcolormap_arr;
+bool *TQPaintDevice::x_appdefcolormap_arr;
+void **TQPaintDevice::x_appvisual_arr;
+bool *TQPaintDevice::x_appdefvisual_arr;
+
+/*!
+ Constructs a paint tqdevice with internal flags \a devflags. This
+ constructor can be invoked only from TQPaintDevice subclasses.
+*/
+
+TQPaintDevice::TQPaintDevice( uint devflags )
+{
+ if ( !tqApp ) { // global constructor
+#if defined(TQT_CHECK_STATE)
+ qFatal( "TQPaintDevice: Must construct a TQApplication before a "
+ "TQPaintDevice" );
+#endif
+ return;
+ }
+
+ // [FIXME]
+ printf("[WARNING] TQPaintDevice::TQPaintDevice( uint devflags ) unimplemented\n\r");
+// devFlags = devflags;
+// painters = 0;
+// hd = 0;
+// rendhd = 0;
+// x11Data = 0;
+}
+
+/*!
+ Returns the window system handle of the paint tqdevice, for
+ low-level access. Using this function is not portable.
+
+ The HANDLE type varies with platform; see \c tqpaintdevice.h and
+ \c tqwindowdefs.h for details.
+
+ \sa x11Display()
+*/
+TQt::HANDLE TQPaintDevice::handle() const
+{
+// return hd;
+
+ // [FIXME]
+ printf("[WARNING] TQPaintDevice::handle() const unimplemented\n\r");
+ return 0;
+}
+
+/*!
+ Returns the window system handle of the paint tqdevice for XRender
+ support. Use of this function is not portable. This function will
+ return 0 if XRender support is not compiled into TQt, if the
+ XRender extension is not supported on the X11 display, or if the
+ handle could not be created.
+*/
+TQt::HANDLE TQPaintDevice::x11RenderHandle() const
+{
+// #ifndef TQT_NO_XFTFREETYPE
+// return rendhd ? XftDrawPicture( (XftDraw *) rendhd ) : 0;
+// #else
+// return 0;
+// #endif // TQT_NO_XFTFREETYPE
+
+ // [FIXME]
+ printf("[WARNING] TQPaintDevice::x11RenderHandle() const unimplemented\n\r");
+ return 0;
+}
+
+/*!
+ \relates QPaintDevice
+
+ Returns the QX11Info structure for the \a pd paint device. 0 is
+ returned if it can't be obtained.
+*/
+const Q_GUI_EXPORT QX11Info *qt_x11Info(const QPaintDevice *pd)
+{
+ if (!pd) return 0;
+ if (pd->devType() == QInternal::Widget)
+ return &static_cast<const QWidget *>(pd)->x11Info();
+ else if (pd->devType() == QInternal::Pixmap)
+ return &static_cast<const QPixmap *>(pd)->x11Info();
+ return 0;
+}
+
+Display *TQPaintDevice::x11Display() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->display();
+ return QX11Info::display();
+}
+
+int TQPaintDevice::x11Screen() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->screen();
+ return QX11Info::appScreen();
+}
+
+void *TQPaintDevice::x11Visual() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->visual();
+ return QX11Info::appVisual();
+}
+
+int TQPaintDevice::x11Depth() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->depth();
+ return QX11Info::appDepth();
+}
+
+int TQPaintDevice::x11Cells() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->cells();
+ return QX11Info::appCells();
+}
+
+Qt::HANDLE TQPaintDevice::x11Colormap() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->colormap();
+ return QX11Info::appColormap();
+}
+
+bool TQPaintDevice::x11DefaultColormap() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->defaultColormap();
+ return QX11Info::appDefaultColormap();
+}
+
+bool TQPaintDevice::x11DefaultVisual() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->defaultVisual();
+ return QX11Info::appDefaultVisual();
+}
+
+void TQPaintDevice::x11SetAppDpiX(int dpi, int screen)
+{
+ QX11Info::setAppDpiX(dpi, screen);
+}
+
+void TQPaintDevice::x11SetAppDpiY(int dpi, int screen)
+{
+ QX11Info::setAppDpiY(dpi, screen);
+}
+
+int TQPaintDevice::x11AppDpiX(int screen)
+{
+ return QX11Info::appDpiX(screen);
+}
+
+int TQPaintDevice::x11AppDpiY(int screen)
+{
+ return QX11Info::appDpiY(screen);
+}
+
+/*!
+ \relates TQPaintDevice
+
+ Copies a block of pixels from \a src to \a dst, perhaps merging
+ each pixel according to the \link TQt::RasterOp raster operation \endlink
+ \a rop. \a sx, \a sy
+ is the top-left pixel in \a src (0, 0) by default, \a dx, \a dy is
+ the top-left position in \a dst and \a sw, \a sh is the size of
+ the copied block (all of \a src by default).
+
+ The most common values for \a rop are CopyROP and XorROP; the \l
+ TQt::RasterOp documentation defines all the possible values.
+
+ If \a ignoreMask is FALSE (the default) and \a src is a
+ masked TQPixmap, the entire blit is masked by \a{src}->tqmask().
+
+ If \a src, \a dst, \a sw or \a sh is 0, bitBlt() does nothing. If
+ \a sw or \a sh is negative bitBlt() copies starting at \a sx (and
+ respectively, \a sy) and ending at the right end (respectively,
+ bottom) of \a src.
+
+ \a src must be a TQWidget or TQPixmap. You cannot blit from a
+ TQPrinter, for example. bitBlt() does nothing if you attempt to
+ blit from an unsupported tqdevice.
+
+ bitBlt() does nothing if \a src has a greater depth than \e dst.
+ If you need to for example, draw a 24-bit pixmap on an 8-bit
+ widget, you must use drawPixmap().
+*/
+
+void bitBlt( TQPaintDevice *dst, int dx, int dy,
+ const TQPaintDevice *src, int sx, int sy, int sw, int sh,
+ TQt::RasterOp rop, bool ignoreMask )
+{
+// [FIXME] Implement this for Qt4!
+printf("[WARNING] bitBlt( TQPaintDevice *dst, int dx, int dy, const TQPaintDevice *src, int sx, int sy, int sw, int sh, TQt::RasterOp rop, bool ignoreMask ) unimplemented\n\r");
+
+// if ( !src || !dst ) {
+// #if defined(TQT_CHECK_NULL)
+// TQ_ASSERT( src != 0 );
+// TQ_ASSERT( dst != 0 );
+// #endif
+// return;
+// }
+// if ( !src->handle() || src->isExtDev() )
+// return;
+//
+// TQPaintDevice *pdev = TQPainter::redirect( dst );
+// if ( pdev )
+// dst = pdev;
+//
+// int ts = src->devType(); // from tqdevice type
+// int td = dst->devType(); // to tqdevice type
+// Display *dpy = src->x11Display();
+//
+// if ( sw <= 0 ) { // special width
+// if ( sw < 0 )
+// sw = src->metric( TQPaintDeviceMetrics::PdmWidth ) - sx;
+// else
+// return;
+// }
+// if ( sh <= 0 ) { // special height
+// if ( sh < 0 )
+// sh = src->metric( TQPaintDeviceMetrics::PdmHeight ) - sy;
+// else
+// return;
+// }
+//
+// if ( dst->paintingActive() && dst->isExtDev() ) {
+// TQPixmap *pm; // output to picture/printer
+// bool tmp_pm = TRUE;
+// if ( ts == TQInternal::Pixmap ) {
+// pm = (TQPixmap*)src;
+// if ( sx != 0 || sy != 0 ||
+// sw != pm->width() || sh != pm->height() || ignoreMask ) {
+// TQPixmap *tmp = new TQPixmap( sw, sh, pm->depth() );
+// bitBlt( tmp, 0, 0, pm, sx, sy, sw, sh, TQt::CopyROP, TRUE );
+// if ( pm->tqmask() && !ignoreMask ) {
+// TQBitmap tqmask( sw, sh );
+// bitBlt( &tqmask, 0, 0, pm->tqmask(), sx, sy, sw, sh,
+// TQt::CopyROP, TRUE );
+// tmp->setMask( tqmask );
+// }
+// pm = tmp;
+// } else {
+// tmp_pm = FALSE;
+// }
+// } else if ( ts == TQInternal::Widget ) {// bitBlt to temp pixmap
+// pm = new TQPixmap( sw, sh );
+// TQ_CHECK_PTR( pm );
+// bitBlt( pm, 0, 0, src, sx, sy, sw, sh );
+// } else {
+// #if defined(TQT_CHECK_RANGE)
+// qWarning( "bitBlt: Cannot bitBlt from tqdevice" );
+// #endif
+// return;
+// }
+// TQPDevCmdParam param[3];
+// TQRect r(dx, dy, pm->width(), pm->height());
+// param[0].rect = &r;
+// param[1].pixmap = pm;
+// dst->cmd( TQPaintDevice::PdcDrawPixmap, 0, param );
+// if ( tmp_pm )
+// delete pm;
+// return;
+// }
+//
+// switch ( ts ) {
+// case TQInternal::Widget:
+// case TQInternal::Pixmap:
+// case TQInternal::System: // OK, can blt from these
+// break;
+// default:
+// #if defined(TQT_CHECK_RANGE)
+// qWarning( "bitBlt: Cannot bitBlt from tqdevice type %x", ts );
+// #endif
+// return;
+// }
+// switch ( td ) {
+// case TQInternal::Widget:
+// case TQInternal::Pixmap:
+// case TQInternal::System: // OK, can blt to these
+// break;
+// default:
+// #if defined(TQT_CHECK_RANGE)
+// qWarning( "bitBlt: Cannot bitBlt to tqdevice type %x", td );
+// #endif
+// return;
+// }
+//
+// static const short ropCodes[] = { // ROP translation table
+// GXcopy, GXor, GXxor, GXandInverted,
+// GXcopyInverted, GXorInverted, GXequiv, GXand,
+// GXinvert, GXclear, GXset, GXnoop,
+// GXandReverse, GXorReverse, GXnand, GXnor
+// };
+// if ( rop > TQt::LastROP ) {
+// #if defined(TQT_CHECK_RANGE)
+// qWarning( "bitBlt: Invalid ROP code" );
+// #endif
+// return;
+// }
+//
+// if ( dst->handle() == 0 ) {
+// #if defined(TQT_CHECK_NULL)
+// qWarning( "bitBlt: Cannot bitBlt to tqdevice" );
+// #endif
+// return;
+// }
+//
+// bool mono_src;
+// bool mono_dst;
+// bool include_inferiors = FALSE;
+// bool graphics_exposure = FALSE;
+// TQPixmap *src_pm;
+// TQBitmap *tqmask;
+//
+// if ( ts == TQInternal::Pixmap ) {
+// src_pm = (TQPixmap*)src;
+// if ( src_pm->x11Screen() != dst->x11Screen() )
+// src_pm->x11SetScreen( dst->x11Screen() );
+// mono_src = src_pm->depth() == 1;
+// tqmask = ignoreMask ? 0 : src_pm->data->tqmask;
+// } else {
+// src_pm = 0;
+// mono_src = FALSE;
+// tqmask = 0;
+// include_inferiors = ((TQWidget*)src)->testWFlags(TQt::WPaintUnclipped);
+// graphics_exposure = td == TQInternal::Widget;
+// }
+// if ( td == TQInternal::Pixmap ) {
+// if ( dst->x11Screen() != src->x11Screen() )
+// ((TQPixmap*)dst)->x11SetScreen( src->x11Screen() );
+// mono_dst = ((TQPixmap*)dst)->depth() == 1;
+// ((TQPixmap*)dst)->detach(); // changes shared pixmap
+// } else {
+// mono_dst = FALSE;
+// include_inferiors = include_inferiors ||
+// ((TQWidget*)dst)->testWFlags(TQt::WPaintUnclipped);
+// }
+//
+// if ( mono_dst && !mono_src ) { // dest is 1-bit pixmap, source is not
+// #if defined(TQT_CHECK_RANGE)
+// qWarning( "bitBlt: Incompatible destination pixmap" );
+// #endif
+// return;
+// }
+//
+// #ifndef TQT_NO_XRENDER
+// if (src_pm && !mono_src && src_pm->data->alphapm && !ignoreMask ) {
+// // use RENDER to do the blit
+// TQPixmap *alpha = src_pm->data->alphapm;
+// if (src->x11RenderHandle() &&
+// alpha->x11RenderHandle() &&
+// dst->x11RenderHandle()) {
+// XRenderPictureAttributes pattr;
+// ulong pictqmask = 0;
+// if (include_inferiors) {
+// pattr.subwindow_mode = IncludeInferiors;
+// pictqmask |= CPSubwindowMode;
+// }
+// if (graphics_exposure) {
+// pattr.graphics_exposures = TRUE;
+// pictqmask |= CPGraphicsExposure;
+// }
+// if (pictqmask)
+// XRenderChangePicture(dpy, dst->x11RenderHandle(), pictqmask, &pattr);
+// XRenderComposite(dpy, PictOpOver, src->x11RenderHandle(),
+// alpha->x11RenderHandle(), dst->x11RenderHandle(),
+// sx, sy, sx, sy, dx, dy, sw, sh);
+// // restore attributes
+// pattr.subwindow_mode = ClipByChildren;
+// pattr.graphics_exposures = FALSE;
+// if (pictqmask)
+// XRenderChangePicture(dpy, dst->x11RenderHandle(), pictqmask, &pattr);
+// return;
+// }
+// }
+// #endif
+//
+// GC gc;
+//
+// if ( tqmask && !mono_src ) { // fast masked blt
+// bool temp_gc = FALSE;
+// if ( tqmask->data->maskgc ) {
+// gc = (GC)tqmask->data->maskgc; // we have a premade tqmask GC
+// } else {
+// if ( FALSE && src_pm->optimization() == TQPixmap::NormalOptim ) { // #### cache disabled
+// // Compete for the global cache
+// gc = cache_mask_gc( dpy, dst->handle(),
+// tqmask->data->ser_no,
+// tqmask->handle() );
+// } else {
+// // Create a new tqmask GC. If BestOptim, we store the tqmask GC
+// // with the tqmask (not at the pixmap). This way, many pixmaps
+// // which have a common tqmask will be optimized at no extra cost.
+// gc = XCreateGC( dpy, dst->handle(), 0, 0 );
+// XSetGraphicsExposures( dpy, gc, False );
+// XSetClipMask( dpy, gc, tqmask->handle() );
+// if ( src_pm->optimization() == TQPixmap::BestOptim ) {
+// tqmask->data->maskgc = gc;
+// } else {
+// temp_gc = TRUE;
+// }
+// }
+// }
+// XSetClipOrigin( dpy, gc, dx-sx, dy-sy );
+// if ( rop != TQt::CopyROP ) // use non-default ROP code
+// XSetFunction( dpy, gc, ropCodes[rop] );
+// if ( include_inferiors ) {
+// XSetSubwindowMode( dpy, gc, IncludeInferiors );
+// XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh,
+// dx, dy );
+// XSetSubwindowMode( dpy, gc, ClipByChildren );
+// } else {
+// XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh,
+// dx, dy );
+// }
+//
+// if ( temp_gc ) // delete temporary GC
+// XFreeGC( dpy, gc );
+// else if ( rop != TQt::CopyROP ) // restore ROP
+// XSetFunction( dpy, gc, GXcopy );
+// return;
+// }
+//
+// gc = qt_xget_temp_gc( dst->x11Screen(), mono_dst ); // get a reusable GC
+//
+// if ( rop != TQt::CopyROP ) // use non-default ROP code
+// XSetFunction( dpy, gc, ropCodes[rop] );
+//
+// if ( mono_src && mono_dst && src == dst ) { // dst and src are the same bitmap
+// XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, dx, dy );
+// } else if ( mono_src ) { // src is bitmap
+// XGCValues gcvals;
+// ulong valtqmask = GCBackground | GCForeground | GCFillStyle |
+// GCStipple | GCTileStipXOrigin | GCTileStipYOrigin;
+// if ( td == TQInternal::Widget ) { // set GC colors
+// TQWidget *w = (TQWidget *)dst;
+// gcvals.background = w->backgroundColor().pixel( dst->x11Screen() );
+// gcvals.foreground = w->foregroundColor().pixel( dst->x11Screen() );
+// if ( include_inferiors ) {
+// valtqmask |= GCSubwindowMode;
+// gcvals.subwindow_mode = IncludeInferiors;
+// }
+// } else if ( mono_dst ) {
+// gcvals.background = 0;
+// gcvals.foreground = 1;
+// } else {
+// gcvals.background = TQt::white.pixel( dst->x11Screen() );
+// gcvals.foreground = TQt::black.pixel( dst->x11Screen() );
+// }
+//
+// gcvals.fill_style = FillOpaqueStippled;
+// gcvals.stipple = src->handle();
+// gcvals.ts_x_origin = dx - sx;
+// gcvals.ts_y_origin = dy - sy;
+//
+// bool cliptqmask = FALSE;
+// if ( tqmask ) {
+// if ( ((TQPixmap*)src)->data->selfmask ) {
+// gcvals.fill_style = FillStippled;
+// } else {
+// XSetClipMask( dpy, gc, tqmask->handle() );
+// XSetClipOrigin( dpy, gc, dx-sx, dy-sy );
+// cliptqmask = TRUE;
+// }
+// }
+//
+// XChangeGC( dpy, gc, valtqmask, &gcvals );
+// XFillRectangle( dpy,dst->handle(), gc, dx, dy, sw, sh );
+//
+// valtqmask = GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+// gcvals.fill_style = FillSolid;
+// gcvals.ts_x_origin = 0;
+// gcvals.ts_y_origin = 0;
+// if ( include_inferiors ) {
+// valtqmask |= GCSubwindowMode;
+// gcvals.subwindow_mode = ClipByChildren;
+// }
+// XChangeGC( dpy, gc, valtqmask, &gcvals );
+//
+// if ( cliptqmask ) {
+// XSetClipOrigin( dpy, gc, 0, 0 );
+// XSetClipMask( dpy, gc, None );
+// }
+//
+// } else { // src is pixmap/widget
+//
+// if ( graphics_exposure ) // widget to widget
+// XSetGraphicsExposures( dpy, gc, True );
+// if ( include_inferiors ) {
+// XSetSubwindowMode( dpy, gc, IncludeInferiors );
+// XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh,
+// dx, dy );
+// XSetSubwindowMode( dpy, gc, ClipByChildren );
+// } else {
+// XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh,
+// dx, dy );
+// }
+// if ( graphics_exposure ) // reset graphics exposure
+// XSetGraphicsExposures( dpy, gc, False );
+// }
+//
+// if ( rop != TQt::CopyROP ) // restore ROP
+// XSetFunction( dpy, gc, GXcopy );
+}
+
+/*!
+ Internal virtual function that interprets drawing commands from
+ the painter.
+
+ Implemented by subclasses that have no direct support for drawing
+ graphics (external paint tqdevices, for example, TQPicture).
+*/
+
+bool TQPaintDevice::cmd( int, TQPainter *, TQPDevCmdParam * )
+{
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPaintDevice::cmd: Device has no command interface" );
+#endif
+ return FALSE;
+}
+
+// Reimplemented QPaintEngine methods
+// These need to call their equivalent Qt3 cmd methods
+bool TQPaintDeviceEngineTranslator::begin(QPaintDevice* qpd) {
+ printf("[WARNING] TQPaintDeviceEngineTranslator::begin() unimplemented\n\r");
+}
+
+bool TQPaintDeviceEngineTranslator::end() {
+ printf("[WARNING] TQPaintDeviceEngineTranslator::end() unimplemented\n\r");
+}
+
+void TQPaintDeviceEngineTranslator::updateState(const QPaintEngineState& qpes) {
+ printf("[WARNING] TQPaintDeviceEngineTranslator::updateState() unimplemented\n\r");
+}
+
+void TQPaintDeviceEngineTranslator::drawPixmap(const QRectF& rect1, const QPixmap& pixmap, const QRectF& rect2) {
+ printf("[WARNING] TQPaintDeviceEngineTranslator::drawPixmap() unimplemented\n\r");
+}
+
+QPaintEngine::Type TQPaintDeviceEngineTranslator::type() const {
+ printf("[WARNING] TQPaintDeviceEngineTranslator::type() unimplemented\n\r");
+ return QPaintEngine::X11;
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQPaintDevice tqpaintdevice.h
+ \brief The TQPaintDevice class is the base class of objects that
+ can be painted.
+
+ \ingroup graphics
+ \ingroup images
+
+ A paint tqdevice is an abstraction of a two-dimensional space that
+ can be drawn using a TQPainter. The drawing capabilities are
+ implemented by the subclasses TQWidget, TQPixmap, TQPicture and
+ TQPrinter.
+
+ The default coordinate system of a paint tqdevice has its origin
+ located at the top-left position. X increases to the right and Y
+ increases downward. The unit is one pixel. There are several ways
+ to set up a user-defined coordinate system using the painter, for
+ example, using TQPainter::setWorldMatrix().
+
+ Example (draw on a paint tqdevice):
+ \code
+ void MyWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPainter p; // our painter
+ p.begin( this ); // start painting the widget
+ p.setPen( red ); // red outline
+ p.setBrush( yellow ); // yellow fill
+ p.drawEllipse( 10, 20, 100,100 ); // 100x100 ellipse at position (10, 20)
+ p.end(); // painting done
+ }
+ \endcode
+
+ The bit block transfer is an extremely useful operation for
+ copying pixels from one paint tqdevice to another (or to itself). It
+ is implemented as the global function bitBlt().
+
+ Example (scroll widget contents 10 pixels to the right):
+ \code
+ bitBlt( myWidget, 10, 0, myWidget );
+ \endcode
+
+ \warning TQt requires that a TQApplication object exists before
+ any paint tqdevices can be created. Paint tqdevices access window
+ system resources, and these resources are not initialized before
+ an application object is created.
+*/
+
+
+//
+// Some global variables - these are initialized by TQColor::initialize()
+//
+
+Display *TQPaintDevice::x_appdisplay = 0;
+int TQPaintDevice::x_appscreen;
+
+int TQPaintDevice::x_appdepth;
+int TQPaintDevice::x_appcells;
+TQt::HANDLE TQPaintDevice::x_approotwindow;
+TQt::HANDLE TQPaintDevice::x_appcolormap;
+bool TQPaintDevice::x_appdefcolormap;
+void *TQPaintDevice::x_appvisual;
+bool TQPaintDevice::x_appdefvisual;
+
+// ### in 4.0, remove the above, and use the below
+int *TQPaintDevice::x_appdepth_arr;
+int *TQPaintDevice::x_appcells_arr;
+TQt::HANDLE *TQPaintDevice::x_approotwindow_arr;
+TQt::HANDLE *TQPaintDevice::x_appcolormap_arr;
+bool *TQPaintDevice::x_appdefcolormap_arr;
+void **TQPaintDevice::x_appvisual_arr;
+bool *TQPaintDevice::x_appdefvisual_arr;
+
+/*!
+ \enum TQPaintDevice::PDevCmd
+ \internal
+*/
+
+/*!
+ Constructs a paint tqdevice with internal flags \a devflags. This
+ constructor can be invoked only from TQPaintDevice subclasses.
+*/
+
+TQPaintDevice::TQPaintDevice( uint devflags )
+{
+ if ( !tqApp ) { // global constructor
+#if defined(TQT_CHECK_STATE)
+ qFatal( "TQPaintDevice: Must construct a TQApplication before a "
+ "TQPaintDevice" );
+#endif
+ return;
+ }
+ devFlags = devflags;
+ painters = 0;
+ hd = 0;
+ rendhd = 0;
+ x11Data = 0;
+}
+
+/*!
+ Destroys the paint tqdevice and frees window system resources.
+*/
+
+TQPaintDevice::~TQPaintDevice()
+{
+#if defined(TQT_CHECK_STATE)
+ if ( paintingActive() )
+ qWarning( "TQPaintDevice: Cannot destroy paint tqdevice that is being "
+ "painted" );
+#endif
+ if ( x11Data && x11Data->deref() ) {
+ delete x11Data;
+ x11Data = 0;
+ }
+}
+
+
+/*
+ \internal
+ Makes a shallow copy of the X11-specific data of \a fromDevice, if it is not
+ null. Otherwise this function sets it to null.
+*/
+
+void TQPaintDevice::copyX11Data( const TQPaintDevice *fromDevice )
+{
+ setX11Data( fromDevice ? fromDevice->x11Data : 0 );
+}
+
+/*
+ \internal
+ Makes a deep copy of the X11-specific data of \a fromDevice, if it is not
+ null. Otherwise this function sets it to null.
+*/
+
+void TQPaintDevice::cloneX11Data( const TQPaintDevice *fromDevice )
+{
+ if ( fromDevice && fromDevice->x11Data ) {
+ TQPaintDeviceX11Data *d = new TQPaintDeviceX11Data;
+ *d = *fromDevice->x11Data;
+ d->count = 0;
+ setX11Data( d );
+ } else {
+ setX11Data( 0 );
+ }
+}
+
+/*
+ \internal
+ Makes a shallow copy of the X11-specific data \a d and assigns it to this
+ class. This function increments the reference code of \a d.
+*/
+
+void TQPaintDevice::setX11Data( const TQPaintDeviceX11Data* d )
+{
+ if ( x11Data && x11Data->deref() )
+ delete x11Data;
+ x11Data = (TQPaintDeviceX11Data*)d;
+ if ( x11Data )
+ x11Data->ref();
+}
+
+
+/*
+ \internal
+ If \a def is FALSE, returns a deep copy of the x11Data, or 0 if x11Data is 0.
+ If \a def is TRUE, makes a TQPaintDeviceX11Data struct filled with the default
+ values.
+
+ In either case the caller is responsible for deleting the returned
+ struct. But notice that the struct is a shared class, so other
+ classes might also have a reference to it. The reference count of
+ the returned TQPaintDeviceX11Data* is 0.
+*/
+
+TQPaintDeviceX11Data* TQPaintDevice::getX11Data( bool def ) const
+{
+ TQPaintDeviceX11Data* res = 0;
+ if ( def ) {
+ res = new TQPaintDeviceX11Data;
+ res->x_display = x11AppDisplay();
+ res->x_screen = x11AppScreen();
+ res->x_depth = x11AppDepth();
+ res->x_cells = x11AppCells();
+ res->x_colormap = x11Colormap();
+ res->x_defcolormap = x11AppDefaultColormap();
+ res->x_visual = x11AppVisual();
+ res->x_defvisual = x11AppDefaultVisual();
+ res->deref();
+ } else if ( x11Data ) {
+ res = new TQPaintDeviceX11Data;
+ *res = *x11Data;
+ res->count = 0;
+ }
+ return res;
+}
+
+
+/*!
+ \fn int TQPaintDevice::devType() const
+
+ \internal
+
+ Returns the tqdevice type identifier, which is \c TQInternal::Widget
+ if the tqdevice is a TQWidget, \c TQInternal::Pixmap if it's a
+ TQPixmap, \c TQInternal::Printer if it's a TQPrinter, \c
+ TQInternal::Picture if it's a TQPicture or \c
+ TQInternal::UndefinedDevice in other cases (which should never
+ happen).
+*/
+
+/*!
+ \fn bool TQPaintDevice::isExtDev() const
+
+ Returns TRUE if the tqdevice is an external paint tqdevice; otherwise
+ returns FALSE.
+
+ External paint tqdevices cannot be bitBlt()'ed from. TQPicture and
+ TQPrinter are external paint tqdevices.
+*/
+
+/*!
+ Returns the window system handle of the paint tqdevice, for
+ low-level access. Using this function is not portable.
+
+ The HANDLE type varies with platform; see \c tqpaintdevice.h and
+ \c tqwindowdefs.h for details.
+
+ \sa x11Display()
+*/
+TQt::HANDLE TQPaintDevice::handle() const
+{
+ return hd;
+}
+
+/*!
+ Returns the window system handle of the paint tqdevice for XRender
+ support. Use of this function is not portable. This function will
+ return 0 if XRender support is not compiled into TQt, if the
+ XRender extension is not supported on the X11 display, or if the
+ handle could not be created.
+*/
+TQt::HANDLE TQPaintDevice::x11RenderHandle() const
+{
+#ifndef TQT_NO_XFTFREETYPE
+ return rendhd ? XftDrawPicture( (XftDraw *) rendhd ) : 0;
+#else
+ return 0;
+#endif // TQT_NO_XFTFREETYPE
+}
+
+
+/*!
+ \fn Display *TQPaintDevice::x11AppDisplay()
+
+ Returns a pointer to the X display global to the application (X11
+ only). Using this function is not portable.
+
+ \sa handle()
+*/
+
+/*!
+ \fn int TQPaintDevice::x11AppScreen()
+
+ Returns the screen number on the X display global to the
+ application (X11 only). Using this function is not portable.
+*/
+
+/*!
+ \overload
+ \fn int TQPaintDevice::x11AppDepth()
+
+ Returns the depth for the default screen of the X display global
+ to the application (X11 only). Using this function is not
+ portable.
+
+ \sa TQPixmap::defaultDepth()
+*/
+
+/*!
+ \fn int TQPaintDevice::x11AppCells()
+
+ Returns the number of entries in the colormap for the default
+ screen of the X display global to the application (X11
+ only). Using this function is not portable.
+
+ \sa x11Colormap()
+*/
+
+/*!
+ \fn HANDLE TQPaintDevice::x11AppRootWindow()
+
+ Returns the root window for the default screen of the X display
+ global to the applicatoin (X11 only). Using this function is not
+ portable.
+*/
+
+/*!
+ \fn HANDLE TQPaintDevice::x11AppColormap()
+
+ Returns the colormap for the default screen of the X display
+ global to the application (X11 only). Using this function is not
+ portable.
+
+ \sa x11Cells()
+*/
+
+/*!
+ \fn bool TQPaintDevice::x11AppDefaultColormap ()
+
+ Returns the default colormap for the default screen of the X
+ display global to the application (X11 only). Using this function
+ is not portable.
+
+ \sa x11Cells()
+*/
+
+/*!
+ \fn void* TQPaintDevice::x11AppVisual ()
+
+ Returns the Visual for the default screen of the X display global
+ to the application (X11 only). Using this function is not
+ portable.
+*/
+
+/*!
+ \fn bool TQPaintDevice::x11AppDefaultVisual ()
+
+ Returns TRUE if the Visual used is the default for the default
+ screen of the X display global to the application (X11 only);
+ otherwise returns FALSE. Using this function is not portable.
+*/
+
+/*!
+ \fn int TQPaintDevice::x11AppDepth( int screen )
+
+ Returns the depth for screen \a screen of the X display global to
+ the application (X11 only). Using this function is not portable.
+
+ \sa TQPixmap::defaultDepth()
+*/
+
+/*!
+ \overload
+ \fn int TQPaintDevice::x11AppCells( int screen )
+
+ Returns the number of entries in the colormap for screen \a screen
+ of the X display global to the application (X11 only). Using this
+ function is not portable.
+
+ \sa x11Colormap()
+*/
+
+/*!
+ \overload
+ \fn HANDLE TQPaintDevice::x11AppRootWindow( int screen )
+
+ Returns the root window for screen \a screen of the X display
+ global to the applicatoin (X11 only). Using this function is not
+ portable.
+*/
+
+/*!
+ \overload
+ \fn HANDLE TQPaintDevice::x11AppColormap( int screen )
+
+ Returns the colormap for screen \a screen of the X display global
+ to the application (X11 only). Using this function is not
+ portable.
+
+ \sa x11Cells()
+*/
+
+/*!
+ \overload
+ \fn bool TQPaintDevice::x11AppDefaultColormap( int screen )
+
+ Returns the default colormap for screen \a screen of the X display
+ global to the application (X11 only). Using this function is not
+ portable.
+
+ \sa x11Cells()
+*/
+
+/*!
+ \overload
+ \fn void* TQPaintDevice::x11AppVisual( int screen )
+
+ Returns the Visual for screen \a screen of the X display global to
+ the application (X11 only). Using this function is not portable.
+*/
+
+/*!
+ \overload
+ \fn bool TQPaintDevice::x11AppDefaultVisual( int screen )
+
+ Returns TRUE if the Visual used is the default for screen
+ \a screen of the X display global to the application (X11 only);
+ otherwise returns FALSE. Using this function is not portable.
+*/
+
+
+/*!
+ \fn Display *TQPaintDevice::x11Display() const
+
+ Returns a pointer to the X display for the paint tqdevice (X11
+ only). Using this function is not portable.
+
+ \sa handle()
+*/
+
+/*!
+ \fn int TQPaintDevice::x11Screen () const
+
+ Returns the screen number on the X display for the paint tqdevice
+ (X11 only). Using this function is not portable.
+*/
+
+/*!
+ \fn int TQPaintDevice::x11Depth () const
+
+ Returns the depth of the X display for the paint tqdevice (X11
+ only). Using this function is not portable.
+
+ \sa TQPixmap::defaultDepth()
+*/
+
+/*!
+ \fn int TQPaintDevice::x11Cells () const
+
+ Returns the number of entries in the colormap of the X display for
+ the paint tqdevice (X11 only). Using this function is not portable.
+
+ \sa x11Colormap()
+*/
+
+/*!
+ \fn HANDLE TQPaintDevice::x11Colormap () const
+
+ Returns the colormap of the X display for the paint tqdevice (X11
+ only). Using this function is not portable.
+
+ \sa x11Cells()
+*/
+
+/*!
+ \fn bool TQPaintDevice::x11DefaultColormap () const
+
+ Returns the default colormap of the X display for the paint tqdevice
+ (X11 only). Using this function is not portable.
+
+ \sa x11Cells()
+*/
+
+/*!
+ \fn void* TQPaintDevice::x11Visual () const
+
+ Returns the Visual of the X display for the paint tqdevice (X11
+ only). Using this function is not portable.
+*/
+
+/*!
+ \fn bool TQPaintDevice::x11DefaultVisual () const
+
+ Returns the default Visual of the X display for the paint tqdevice
+ (X11 only). Using this function is not portable.
+*/
+
+static int *dpisX=0, *dpisY=0;
+static void create_dpis()
+{
+ if ( dpisX )
+ return;
+
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ if ( ! dpy )
+ return;
+
+ int i, screens = ScreenCount( dpy );
+ dpisX = new int[ screens ];
+ dpisY = new int[ screens ];
+ TQ_CHECK_PTR( dpisX );
+ TQ_CHECK_PTR( dpisY );
+ for ( i = 0; i < screens; i++ ) {
+ dpisX[ i ] = (DisplayWidth(dpy,i) * 254 + DisplayWidthMM(dpy,i)*5)
+
+ / (DisplayWidthMM(dpy,i)*10);
+ dpisY[ i ] = (DisplayHeight(dpy,i) * 254 + DisplayHeightMM(dpy,i)*5)
+ / (DisplayHeightMM(dpy,i)*10);
+ }
+}
+
+/*!
+ Sets the value returned by x11AppDpiX() to \a dpi for screen
+ \a screen. The default is determined by the display configuration.
+ Changing this value will alter the scaling of fonts and many other
+ metrics and is not recommended. Using this function is not
+ portable.
+
+ \sa x11SetAppDpiY()
+*/
+void TQPaintDevice::x11SetAppDpiX(int dpi, int screen)
+{
+ create_dpis();
+ if ( ! dpisX )
+ return;
+ if ( screen < 0 )
+ screen = TQPaintDevice::x11AppScreen();
+ if ( screen > ScreenCount( TQPaintDevice::x11AppDisplay() ) )
+ return;
+ dpisX[ screen ] = dpi;
+}
+
+/*!
+ \overload
+
+ Sets the value returned by x11AppDpiX() to \a dpi for the default
+ screen. The default is determined by the display configuration.
+ Changing this value will alter the scaling of fonts and many other
+ metrics and is not recommended. Using this function is not
+ portable.
+
+*/
+// ### REMOVE 4.0
+void TQPaintDevice::x11SetAppDpiX( int dpi )
+{
+ TQPaintDevice::x11SetAppDpiX( dpi, -1 );
+}
+
+/*!
+ Sets the value returned by x11AppDpiY() to \a dpi for screen
+ \a screen. The default is determined by the display configuration.
+ Changing this value will alter the scaling of fonts and many other
+ metrics and is not recommended. Using this function is not
+ portable.
+
+ \sa x11SetAppDpiX()
+*/
+void TQPaintDevice::x11SetAppDpiY(int dpi, int screen)
+{
+ create_dpis();
+ if ( ! dpisY )
+ return;
+ if ( screen < 0 )
+ screen = TQPaintDevice::x11AppScreen();
+ if ( screen > ScreenCount( TQPaintDevice::x11AppDisplay() ) )
+ return;
+ dpisY[ screen ] = dpi;
+}
+
+/*!
+ \overload
+
+ Sets the value returned by x11AppDpiY() to \a dpi for the default
+ screen. The default is determined by the display configuration.
+ Changing this value will alter the scaling of fonts and many other
+ metrics and is not recommended. Using this function is not
+ portable.
+*/
+// ### REMOVE 4.0
+void TQPaintDevice::x11SetAppDpiY( int dpi )
+{
+ TQPaintDevice::x11SetAppDpiY( dpi, -1 );
+}
+
+/*!
+ Returns the horizontal DPI of the X display (X11 only) for screen
+ \a screen. Using this function is not portable. See
+ TQPaintDeviceMetrics for portable access to related information.
+ Using this function is not portable.
+
+ \sa x11AppDpiY(), x11SetAppDpiX(), TQPaintDeviceMetrics::logicalDpiX()
+*/
+int TQPaintDevice::x11AppDpiX(int screen)
+{
+ create_dpis();
+ if ( ! dpisX )
+ return 0;
+ if ( screen < 0 )
+ screen = TQPaintDevice::x11AppScreen();
+ if ( screen > ScreenCount( TQPaintDevice::x11AppDisplay() ) )
+ return 0;
+ return dpisX[ screen ];
+}
+
+/*!
+ \overload
+
+ Returns the horizontal DPI of the X display (X11 only) for the
+ default screen. Using this function is not portable. See
+ TQPaintDeviceMetrics for portable access to related information.
+ Using this function is not portable.
+*/
+int TQPaintDevice::x11AppDpiX()
+{
+ return TQPaintDevice::x11AppDpiX( -1 );
+}
+
+/*!
+ Returns the vertical DPI of the X11 display (X11 only) for screen
+ \a screen. Using this function is not portable. See
+ TQPaintDeviceMetrics for portable access to related information.
+ Using this function is not portable.
+
+ \sa x11AppDpiX(), x11SetAppDpiY(), TQPaintDeviceMetrics::logicalDpiY()
+*/
+int TQPaintDevice::x11AppDpiY( int screen )
+{
+ create_dpis();
+ if ( ! dpisY )
+ return 0;
+ if ( screen < 0 )
+ screen = TQPaintDevice::x11AppScreen();
+ if ( screen > ScreenCount( TQPaintDevice::x11AppDisplay() ) )
+ return 0;
+ return dpisY[ screen ];
+}
+
+/*!
+ \overload
+
+ Returns the vertical DPI of the X11 display (X11 only) for the
+ default screen. Using this function is not portable. See
+ TQPaintDeviceMetrics for portable access to related information.
+ Using this function is not portable.
+
+ \sa x11AppDpiX(), x11SetAppDpiY(), TQPaintDeviceMetrics::logicalDpiY()
+*/
+int TQPaintDevice::x11AppDpiY()
+{
+ return TQPaintDevice::x11AppDpiY( -1 );
+}
+
+/*!
+ \fn bool TQPaintDevice::paintingActive() const
+
+ Returns TRUE if the tqdevice is being painted, i.e. someone has
+ called TQPainter::begin() but not yet called TQPainter::end() for
+ this tqdevice; otherwise returns FALSE.
+
+ \sa TQPainter::isActive()
+*/
+
+/*!
+ Internal virtual function that interprets drawing commands from
+ the painter.
+
+ Implemented by subclasses that have no direct support for drawing
+ graphics (external paint tqdevices, for example, TQPicture).
+*/
+
+bool TQPaintDevice::cmd( int, TQPainter *, TQPDevCmdParam * )
+{
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPaintDevice::cmd: Device has no command interface" );
+#endif
+ return FALSE;
+}
+
+/*!
+ \internal
+
+ Internal virtual function that returns paint tqdevice metrics.
+
+ Please use the TQPaintDeviceMetrics class instead.
+*/
+
+int TQPaintDevice::metric( int ) const
+{
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPaintDevice::metrics: Device has no metric information" );
+#endif
+ return 0;
+}
+
+/*!
+ \internal
+
+ Internal virtual function. Reserved for future use.
+
+ Please use the TQFontMetrics class instead.
+*/
+
+int TQPaintDevice::fontMet( TQFont *, int, const char *, int ) const
+{
+ return 0;
+}
+
+/*!
+ \internal
+
+ Internal virtual function. Reserved for future use.
+
+ Please use the TQFontInfo class instead.
+*/
+
+int TQPaintDevice::fontInf( TQFont *, int ) const
+{
+ return 0;
+}
+
+
+//
+// Internal functions for simple GC caching for blt'ing masked pixmaps.
+// This cache is used when the pixmap optimization is set to Normal
+// and the pixmap size doesn't exceed 128x128.
+//
+
+static bool init_mask_gc = FALSE;
+static const int max_mask_gcs = 11; // suitable for hashing
+
+struct mask_gc {
+ GC gc;
+ int mask_no;
+};
+
+static mask_gc gc_vec[max_mask_gcs];
+
+
+static void cleanup_mask_gc()
+{
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ init_mask_gc = FALSE;
+ for ( int i=0; i<max_mask_gcs; i++ ) {
+ if ( gc_vec[i].gc )
+ XFreeGC( dpy, gc_vec[i].gc );
+ }
+}
+
+static GC cache_mask_gc( Display *dpy, Drawable hd, int mask_no, Pixmap tqmask )
+{
+ if ( !init_mask_gc ) { // first time initialization
+ init_mask_gc = TRUE;
+ qAddPostRoutine( cleanup_mask_gc );
+ for ( int i=0; i<max_mask_gcs; i++ )
+ gc_vec[i].gc = 0;
+ }
+ mask_gc *p = &gc_vec[mask_no % max_mask_gcs];
+ if ( !p->gc || p->mask_no != mask_no ) { // not a perfect match
+ if ( !p->gc ) { // no GC
+ p->gc = XCreateGC( dpy, hd, 0, 0 );
+ XSetGraphicsExposures( dpy, p->gc, False );
+ }
+ XSetClipMask( dpy, p->gc, tqmask );
+ p->mask_no = mask_no;
+ }
+ return p->gc;
+}
+
+
+/*!
+ \relates TQPaintDevice
+
+ Copies a block of pixels from \a src to \a dst, perhaps merging
+ each pixel according to the \link TQt::RasterOp raster operation \endlink
+ \a rop. \a sx, \a sy
+ is the top-left pixel in \a src (0, 0) by default, \a dx, \a dy is
+ the top-left position in \a dst and \a sw, \a sh is the size of
+ the copied block (all of \a src by default).
+
+ The most common values for \a rop are CopyROP and XorROP; the \l
+ TQt::RasterOp documentation defines all the possible values.
+
+ If \a ignoreMask is FALSE (the default) and \a src is a
+ masked TQPixmap, the entire blit is masked by \a{src}->tqmask().
+
+ If \a src, \a dst, \a sw or \a sh is 0, bitBlt() does nothing. If
+ \a sw or \a sh is negative bitBlt() copies starting at \a sx (and
+ respectively, \a sy) and ending at the right end (respectively,
+ bottom) of \a src.
+
+ \a src must be a TQWidget or TQPixmap. You cannot blit from a
+ TQPrinter, for example. bitBlt() does nothing if you attempt to
+ blit from an unsupported tqdevice.
+
+ bitBlt() does nothing if \a src has a greater depth than \e dst.
+ If you need to for example, draw a 24-bit pixmap on an 8-bit
+ widget, you must use drawPixmap().
+*/
+
+void bitBlt( TQPaintDevice *dst, int dx, int dy,
+ const TQPaintDevice *src, int sx, int sy, int sw, int sh,
+ TQt::RasterOp rop, bool ignoreMask )
+{
+ if ( !src || !dst ) {
+#if defined(TQT_CHECK_NULL)
+ TQ_ASSERT( src != 0 );
+ TQ_ASSERT( dst != 0 );
+#endif
+ return;
+ }
+ if ( !src->handle() || src->isExtDev() )
+ return;
+
+ TQPaintDevice *pdev = TQPainter::redirect( dst );
+ if ( pdev )
+ dst = pdev;
+
+ int ts = src->devType(); // from tqdevice type
+ int td = dst->devType(); // to tqdevice type
+ Display *dpy = src->x11Display();
+
+ if ( sw <= 0 ) { // special width
+ if ( sw < 0 )
+ sw = src->metric( TQPaintDeviceMetrics::PdmWidth ) - sx;
+ else
+ return;
+ }
+ if ( sh <= 0 ) { // special height
+ if ( sh < 0 )
+ sh = src->metric( TQPaintDeviceMetrics::PdmHeight ) - sy;
+ else
+ return;
+ }
+
+ if ( dst->paintingActive() && dst->isExtDev() ) {
+ TQPixmap *pm; // output to picture/printer
+ bool tmp_pm = TRUE;
+ if ( ts == TQInternal::Pixmap ) {
+ pm = (TQPixmap*)src;
+ if ( sx != 0 || sy != 0 ||
+ sw != pm->width() || sh != pm->height() || ignoreMask ) {
+ TQPixmap *tmp = new TQPixmap( sw, sh, pm->depth() );
+ bitBlt( tmp, 0, 0, pm, sx, sy, sw, sh, TQt::CopyROP, TRUE );
+ if ( pm->tqmask() && !ignoreMask ) {
+ TQBitmap tqmask( sw, sh );
+ bitBlt( &tqmask, 0, 0, pm->tqmask(), sx, sy, sw, sh,
+ TQt::CopyROP, TRUE );
+ tmp->setMask( tqmask );
+ }
+ pm = tmp;
+ } else {
+ tmp_pm = FALSE;
+ }
+ } else if ( ts == TQInternal::Widget ) {// bitBlt to temp pixmap
+ pm = new TQPixmap( sw, sh );
+ TQ_CHECK_PTR( pm );
+ bitBlt( pm, 0, 0, src, sx, sy, sw, sh );
+ } else {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "bitBlt: Cannot bitBlt from tqdevice" );
+#endif
+ return;
+ }
+ TQPDevCmdParam param[3];
+ TQRect r(dx, dy, pm->width(), pm->height());
+ param[0].rect = &r;
+ param[1].pixmap = pm;
+ dst->cmd( TQPaintDevice::PdcDrawPixmap, 0, param );
+ if ( tmp_pm )
+ delete pm;
+ return;
+ }
+
+ switch ( ts ) {
+ case TQInternal::Widget:
+ case TQInternal::Pixmap:
+ case TQInternal::System: // OK, can blt from these
+ break;
+ default:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "bitBlt: Cannot bitBlt from tqdevice type %x", ts );
+#endif
+ return;
+ }
+ switch ( td ) {
+ case TQInternal::Widget:
+ case TQInternal::Pixmap:
+ case TQInternal::System: // OK, can blt to these
+ break;
+ default:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "bitBlt: Cannot bitBlt to tqdevice type %x", td );
+#endif
+ return;
+ }
+
+ static const short ropCodes[] = { // ROP translation table
+ GXcopy, GXor, GXxor, GXandInverted,
+ GXcopyInverted, GXorInverted, GXequiv, GXand,
+ GXinvert, GXclear, GXset, GXnoop,
+ GXandReverse, GXorReverse, GXnand, GXnor
+ };
+ if ( rop > TQt::LastROP ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "bitBlt: Invalid ROP code" );
+#endif
+ return;
+ }
+
+ if ( dst->handle() == 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "bitBlt: Cannot bitBlt to tqdevice" );
+#endif
+ return;
+ }
+
+ bool mono_src;
+ bool mono_dst;
+ bool include_inferiors = FALSE;
+ bool graphics_exposure = FALSE;
+ TQPixmap *src_pm;
+ TQBitmap *tqmask;
+
+ if ( ts == TQInternal::Pixmap ) {
+ src_pm = (TQPixmap*)src;
+ if ( src_pm->x11Screen() != dst->x11Screen() )
+ src_pm->x11SetScreen( dst->x11Screen() );
+ mono_src = src_pm->depth() == 1;
+ tqmask = ignoreMask ? 0 : src_pm->data->tqmask;
+ } else {
+ src_pm = 0;
+ mono_src = FALSE;
+ tqmask = 0;
+ include_inferiors = ((TQWidget*)src)->testWFlags(TQt::WPaintUnclipped);
+ graphics_exposure = td == TQInternal::Widget;
+ }
+ if ( td == TQInternal::Pixmap ) {
+ if ( dst->x11Screen() != src->x11Screen() )
+ ((TQPixmap*)dst)->x11SetScreen( src->x11Screen() );
+ mono_dst = ((TQPixmap*)dst)->depth() == 1;
+ ((TQPixmap*)dst)->detach(); // changes shared pixmap
+ } else {
+ mono_dst = FALSE;
+ include_inferiors = include_inferiors ||
+ ((TQWidget*)dst)->testWFlags(TQt::WPaintUnclipped);
+ }
+
+ if ( mono_dst && !mono_src ) { // dest is 1-bit pixmap, source is not
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "bitBlt: Incompatible destination pixmap" );
+#endif
+ return;
+ }
+
+#ifndef TQT_NO_XRENDER
+ if (src_pm && !mono_src && src_pm->data->alphapm && !ignoreMask ) {
+ // use RENDER to do the blit
+ TQPixmap *alpha = src_pm->data->alphapm;
+ if (src->x11RenderHandle() &&
+ alpha->x11RenderHandle() &&
+ dst->x11RenderHandle()) {
+ XRenderPictureAttributes pattr;
+ ulong pictqmask = 0;
+ if (include_inferiors) {
+ pattr.subwindow_mode = IncludeInferiors;
+ pictqmask |= CPSubwindowMode;
+ }
+ if (graphics_exposure) {
+ pattr.graphics_exposures = TRUE;
+ pictqmask |= CPGraphicsExposure;
+ }
+ if (pictqmask)
+ XRenderChangePicture(dpy, dst->x11RenderHandle(), pictqmask, &pattr);
+ XRenderComposite(dpy, PictOpOver, src->x11RenderHandle(),
+ alpha->x11RenderHandle(), dst->x11RenderHandle(),
+ sx, sy, sx, sy, dx, dy, sw, sh);
+ // restore attributes
+ pattr.subwindow_mode = ClipByChildren;
+ pattr.graphics_exposures = FALSE;
+ if (pictqmask)
+ XRenderChangePicture(dpy, dst->x11RenderHandle(), pictqmask, &pattr);
+ return;
+ }
+ }
+#endif
+
+ GC gc;
+
+ if ( tqmask && !mono_src ) { // fast masked blt
+ bool temp_gc = FALSE;
+ if ( tqmask->data->maskgc ) {
+ gc = (GC)tqmask->data->maskgc; // we have a premade tqmask GC
+ } else {
+ if ( FALSE && src_pm->optimization() == TQPixmap::NormalOptim ) { // #### cache disabled
+ // Compete for the global cache
+ gc = cache_mask_gc( dpy, dst->handle(),
+ tqmask->data->ser_no,
+ tqmask->handle() );
+ } else {
+ // Create a new tqmask GC. If BestOptim, we store the tqmask GC
+ // with the tqmask (not at the pixmap). This way, many pixmaps
+ // which have a common tqmask will be optimized at no extra cost.
+ gc = XCreateGC( dpy, dst->handle(), 0, 0 );
+ XSetGraphicsExposures( dpy, gc, False );
+ XSetClipMask( dpy, gc, tqmask->handle() );
+ if ( src_pm->optimization() == TQPixmap::BestOptim ) {
+ tqmask->data->maskgc = gc;
+ } else {
+ temp_gc = TRUE;
+ }
+ }
+ }
+ XSetClipOrigin( dpy, gc, dx-sx, dy-sy );
+ if ( rop != TQt::CopyROP ) // use non-default ROP code
+ XSetFunction( dpy, gc, ropCodes[rop] );
+ if ( include_inferiors ) {
+ XSetSubwindowMode( dpy, gc, IncludeInferiors );
+ XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh,
+ dx, dy );
+ XSetSubwindowMode( dpy, gc, ClipByChildren );
+ } else {
+ XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh,
+ dx, dy );
+ }
+
+ if ( temp_gc ) // delete temporary GC
+ XFreeGC( dpy, gc );
+ else if ( rop != TQt::CopyROP ) // restore ROP
+ XSetFunction( dpy, gc, GXcopy );
+ return;
+ }
+
+ gc = qt_xget_temp_gc( dst->x11Screen(), mono_dst ); // get a reusable GC
+
+ if ( rop != TQt::CopyROP ) // use non-default ROP code
+ XSetFunction( dpy, gc, ropCodes[rop] );
+
+ if ( mono_src && mono_dst && src == dst ) { // dst and src are the same bitmap
+ XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh, dx, dy );
+ } else if ( mono_src ) { // src is bitmap
+ XGCValues gcvals;
+ ulong valtqmask = GCBackground | GCForeground | GCFillStyle |
+ GCStipple | GCTileStipXOrigin | GCTileStipYOrigin;
+ if ( td == TQInternal::Widget ) { // set GC colors
+ TQWidget *w = (TQWidget *)dst;
+ gcvals.background = w->backgroundColor().pixel( dst->x11Screen() );
+ gcvals.foreground = w->foregroundColor().pixel( dst->x11Screen() );
+ if ( include_inferiors ) {
+ valtqmask |= GCSubwindowMode;
+ gcvals.subwindow_mode = IncludeInferiors;
+ }
+ } else if ( mono_dst ) {
+ gcvals.background = 0;
+ gcvals.foreground = 1;
+ } else {
+ gcvals.background = TQt::white.pixel( dst->x11Screen() );
+ gcvals.foreground = TQt::black.pixel( dst->x11Screen() );
+ }
+
+ gcvals.fill_style = FillOpaqueStippled;
+ gcvals.stipple = src->handle();
+ gcvals.ts_x_origin = dx - sx;
+ gcvals.ts_y_origin = dy - sy;
+
+ bool cliptqmask = FALSE;
+ if ( tqmask ) {
+ if ( ((TQPixmap*)src)->data->selfmask ) {
+ gcvals.fill_style = FillStippled;
+ } else {
+ XSetClipMask( dpy, gc, tqmask->handle() );
+ XSetClipOrigin( dpy, gc, dx-sx, dy-sy );
+ cliptqmask = TRUE;
+ }
+ }
+
+ XChangeGC( dpy, gc, valtqmask, &gcvals );
+ XFillRectangle( dpy,dst->handle(), gc, dx, dy, sw, sh );
+
+ valtqmask = GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin;
+ gcvals.fill_style = FillSolid;
+ gcvals.ts_x_origin = 0;
+ gcvals.ts_y_origin = 0;
+ if ( include_inferiors ) {
+ valtqmask |= GCSubwindowMode;
+ gcvals.subwindow_mode = ClipByChildren;
+ }
+ XChangeGC( dpy, gc, valtqmask, &gcvals );
+
+ if ( cliptqmask ) {
+ XSetClipOrigin( dpy, gc, 0, 0 );
+ XSetClipMask( dpy, gc, None );
+ }
+
+ } else { // src is pixmap/widget
+
+ if ( graphics_exposure ) // widget to widget
+ XSetGraphicsExposures( dpy, gc, True );
+ if ( include_inferiors ) {
+ XSetSubwindowMode( dpy, gc, IncludeInferiors );
+ XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh,
+ dx, dy );
+ XSetSubwindowMode( dpy, gc, ClipByChildren );
+ } else {
+ XCopyArea( dpy, src->handle(), dst->handle(), gc, sx, sy, sw, sh,
+ dx, dy );
+ }
+ if ( graphics_exposure ) // reset graphics exposure
+ XSetGraphicsExposures( dpy, gc, False );
+ }
+
+ if ( rop != TQt::CopyROP ) // restore ROP
+ XSetFunction( dpy, gc, GXcopy );
+}
+
+
+/*!
+ \relates TQPaintDevice
+
+ \overload void bitBlt( TQPaintDevice *dst, const TQPoint &dp, const TQPaintDevice *src, const TQRect &sr, RasterOp rop )
+
+ Overloaded bitBlt() with the destination point \a dp and source
+ rectangle \a sr.
+*/
+
+
+/*!
+ \internal
+*/
+// makes it possible to add a setResolution as we have in TQPrinter for all
+// painttqdevices without breaking bin compatibility.
+void TQPaintDevice::setResolution( int )
+{
+}
+
+/*!\internal
+*/
+int TQPaintDevice::resolution() const
+{
+ return metric( TQPaintDeviceMetrics::PdmDpiY );
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqpaintdevicedefs.h b/tqtinterface/qt4/src/kernel/tqpaintdevicedefs.h
new file mode 100644
index 0000000..e36bedc
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpaintdevicedefs.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Definition of TQPaintDevice constants and flags
+**
+** Created : 940721
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPAINTDEVICEDEFS_H
+#define TQPAINTDEVICEDEFS_H
+
+#error "this file is gone. the #defines it contained are in"
+#error "tq1xcompatibility.h; the functionality is in TQPaintDevice"
+#error "and TQPaintDeviceMetrics."
+
+#endif // TQPAINTDEVICEDEFS_H
diff --git a/tqtinterface/qt4/src/kernel/tqpaintdevicemetrics.cpp b/tqtinterface/qt4/src/kernel/tqpaintdevicemetrics.cpp
new file mode 100644
index 0000000..6013062
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpaintdevicemetrics.cpp
@@ -0,0 +1,304 @@
+#include "tqpaintdevicemetrics.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class TQPaintDeviceMetrics
+ \brief The TQPaintDeviceMetrics class provides information about a
+ paint tqdevice.
+
+ \compat
+
+ Sometimes when drawing graphics it is necessary to obtain
+ information about the physical characteristics of a paint tqdevice.
+ This class provides the information. For example, to compute the
+ aspect ratio of a paint tqdevice:
+
+ \snippet doc/src/snippets/code/src_qt3support_painting_q3painttqdevicemetrics.cpp 0
+
+ TQPaintDeviceMetrics tqcontains methods to provide the width and
+ height of a tqdevice in both pixels (width() and height()) and
+ millimeters (widthMM() and heightMM()), the number of colors the
+ tqdevice supports (numColors()), the number of bit planes (depth()),
+ and the resolution of the tqdevice (logicalDpiX() and
+ logicalDpiY()).
+
+ It is not always possible for TQPaintDeviceMetrics to compute the
+ values you ask for, particularly for external tqdevices. The
+ ultimate example is asking for the resolution of of a QPrinter
+ that is set to "print to file": who knows what printer that file
+ will end up on?
+*/
+
+/*!
+ \fn TQPaintDeviceMetrics::TQPaintDeviceMetrics(const QPaintDevice *pd)
+
+ Constructs a metric for the paint tqdevice \a pd.
+*/
+
+
+/*!
+ \fn int TQPaintDeviceMetrics::width() const
+
+ Returns the width of the paint tqdevice in default coordinate system
+ units (e.g. pixels for QPixmap and QWidget).
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::height() const
+
+ Returns the height of the paint tqdevice in default coordinate
+ system units (e.g. pixels for QPixmap and QWidget).
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::widthMM() const
+
+ Returns the width of the paint tqdevice, measured in millimeters.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::heightMM() const
+
+ Returns the height of the paint tqdevice, measured in millimeters.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::numColors() const
+
+ Returns the number of different colors available for the paint
+ tqdevice. Since this value is an int will not be sufficient to represent
+ the number of colors on 32 bit displays, in which case INT_MAX is
+ returned instead.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::depth() const
+
+ Returns the bit depth (number of bit planes) of the paint tqdevice.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::logicalDpiX() const
+
+ Returns the horizontal resolution of the tqdevice in dots per inch,
+ which is used when computing font sizes. For X, this is usually
+ the same as could be computed from widthMM(), but it varies on
+ Windows.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::logicalDpiY() const
+
+ Returns the vertical resolution of the tqdevice in dots per inch,
+ which is used when computing font sizes. For X, this is usually
+ the same as could be computed from heightMM(), but it varies on
+ Windows.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::physicalDpiX() const
+ \internal
+*/
+/*!
+ \fn int TQPaintDeviceMetrics::physicalDpiY() const
+ \internal
+*/
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of TQPaintDeviceMetrics class
+**
+** Created : 941109
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/*!
+ \class TQPaintDeviceMetrics tqpaintdevicemetrics.h
+ \brief The TQPaintDeviceMetrics class provides information about a
+ paint tqdevice.
+
+ \ingroup graphics
+ \ingroup images
+
+ Sometimes when drawing graphics it is necessary to obtain
+ information about the physical characteristics of a paint tqdevice.
+ This class provides the information. For example, to compute the
+ aspect ratio of a paint tqdevice:
+
+ \code
+ TQPaintDeviceMetrics pdm( myWidget );
+ double aspect = (double)pdm.widthMM() / (double)pdm.heightMM();
+ \endcode
+
+ TQPaintDeviceMetrics tqcontains methods to provide the width and
+ height of a tqdevice in both pixels (width() and height()) and
+ millimeters (widthMM() and heightMM()), the number of colors the
+ tqdevice supports (numColors()), the number of bit planes (depth()),
+ and the resolution of the tqdevice (logicalDpiX() and
+ logicalDpiY()).
+
+ It is not always possible for TQPaintDeviceMetrics to compute the
+ values you ask for, particularly for external tqdevices. The
+ ultimate example is asking for the resolution of of a TQPrinter
+ that is set to "print to file": who knows what printer that file
+ will end up on?
+*/
+
+/*!
+ Constructs a metric for the paint tqdevice \a pd.
+*/
+TQPaintDeviceMetrics::TQPaintDeviceMetrics( const TQPaintDevice *pd )
+{
+ pdev = (TQPaintDevice *)pd;
+}
+
+
+/*!
+ \fn int TQPaintDeviceMetrics::width() const
+
+ Returns the width of the paint tqdevice in default coordinate system
+ units (e.g. pixels for TQPixmap and TQWidget).
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::height() const
+
+ Returns the height of the paint tqdevice in default coordinate
+ system units (e.g. pixels for TQPixmap and TQWidget).
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::widthMM() const
+
+ Returns the width of the paint tqdevice, measured in millimeters.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::heightMM() const
+
+ Returns the height of the paint tqdevice, measured in millimeters.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::numColors() const
+
+ Returns the number of different colors available for the paint
+ tqdevice. Since this value is an int will not be sufficient to represent
+ the number of colors on 32 bit displays, in which case INT_MAX is
+ returned instead.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::depth() const
+
+ Returns the bit depth (number of bit planes) of the paint tqdevice.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::logicalDpiX() const
+
+ Returns the horizontal resolution of the tqdevice in dots per inch,
+ which is used when computing font sizes. For X, this is usually
+ the same as could be computed from widthMM(), but it varies on
+ Windows.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::logicalDpiY() const
+
+ Returns the vertical resolution of the tqdevice in dots per inch,
+ which is used when computing font sizes. For X, this is usually
+ the same as could be computed from heightMM(), but it varies on
+ Windows.
+*/
+
+/*!
+ \fn int TQPaintDeviceMetrics::physicalDpiX() const
+ \internal
+*/
+/*!
+ \fn int TQPaintDeviceMetrics::physicalDpiY() const
+ \internal
+*/
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqpaintdevicemetrics.h b/tqtinterface/qt4/src/kernel/tqpaintdevicemetrics.h
new file mode 100644
index 0000000..4db2a39
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpaintdevicemetrics.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Definition of TQPaintDeviceMetrics class
+**
+** Created : 941109
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPAINTDEVICEMETRICS_H
+#define TQPAINTDEVICEMETRICS_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqpaintdevice.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q3PAINTDEVICEMETRICS_H
+#define Q3PAINTDEVICEMETRICS_H
+
+#include <QtGui/qpaintdevice.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3SupportLight)
+
+class Q_COMPAT_EXPORT TQPaintDeviceMetrics // paint tqdevice metrics
+{
+public:
+ TQPaintDeviceMetrics(const QPaintDevice *tqdevice) : pdev(tqdevice) {}
+
+ // [FIXME] Integrate with Qt4 enum
+ enum {
+ PdmWidth = 1,
+ PdmHeight,
+ PdmWidthMM,
+ PdmHeightMM,
+ PdmNumColors,
+ PdmDepth,
+ PdmDpiX,
+ PdmDpiY,
+ PdmPhysicalDpiX,
+ PdmPhysicalDpiY
+ };
+
+ int width() const { return pdev->width(); }
+ int height() const { return pdev->height(); }
+ int widthMM() const { return pdev->widthMM(); }
+ int heightMM() const { return pdev->heightMM(); }
+ int logicalDpiX() const { return pdev->logicalDpiX(); }
+ int logicalDpiY() const { return pdev->logicalDpiY(); }
+ int physicalDpiX() const { return pdev->physicalDpiX(); }
+ int physicalDpiY() const { return pdev->physicalDpiY(); }
+ int numColors() const { return pdev->colorCount(); }
+ int depth() const { return pdev->depth(); }
+
+private:
+ const QPaintDevice *pdev;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // Q3PAINTDEVICEMETRICS_H
+
+#else // USE_QT4
+
+class TQ_EXPORT TQPaintDeviceMetrics // paint tqdevice metrics
+{
+public:
+ TQPaintDeviceMetrics( const TQPaintDevice * );
+
+ enum {
+ PdmWidth = 1,
+ PdmHeight,
+ PdmWidthMM,
+ PdmHeightMM,
+ PdmNumColors,
+ PdmDepth,
+ PdmDpiX,
+ PdmDpiY,
+ PdmPhysicalDpiX,
+ PdmPhysicalDpiY
+ };
+
+ int width() const { return (int)pdev->metric(PdmWidth); }
+ int height() const { return (int)pdev->metric(PdmHeight); }
+ int widthMM() const { return (int)pdev->metric(PdmWidthMM); }
+ int heightMM() const { return (int)pdev->metric(PdmHeightMM); }
+ int logicalDpiX() const { return (int)pdev->metric(PdmDpiX); }
+ int logicalDpiY() const { return (int)pdev->metric(PdmDpiY); }
+ int physicalDpiX()const { return (int)pdev->metric(PdmPhysicalDpiX); }
+ int physicalDpiY()const { return (int)pdev->metric(PdmPhysicalDpiY); }
+ int numColors() const { return (int)pdev->metric(PdmNumColors); }
+ int depth() const { return (int)pdev->metric(PdmDepth); }
+
+private:
+ TQPaintDevice *pdev;
+};
+
+#endif // USE_QT4
+
+#endif // TQPAINTDEVICEMETRICS_H
diff --git a/tqtinterface/qt4/src/kernel/tqpainter.cpp b/tqtinterface/qt4/src/kernel/tqpainter.cpp
new file mode 100644
index 0000000..66596f5
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpainter.cpp
@@ -0,0 +1,5382 @@
+#include "tqpainter.h"
+
+#include "tqpicture.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqpainter.h"
+#include "tqimage.h"
+#include "Qt/qpaintengine.h"
+
+// #include <private/qpainter_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// TAKEN FROM QT4 qbrush.cpp
+// THIS BLOCK MAY NEED TO BE UPDATED FROM TIME TO TIME
+// BEGIN BLOCK
+struct QTexturedBrushData : public QBrushData
+{
+ QTexturedBrushData() {
+ m_has_pixmap_texture = false;
+ m_pixmap = 0;
+ }
+ ~QTexturedBrushData() {
+ delete m_pixmap;
+ }
+
+ void setPixmap(const QPixmap &pm) {
+ delete m_pixmap;
+
+ if (pm.isNull()) {
+ m_pixmap = 0;
+ m_has_pixmap_texture = false;
+ } else {
+ m_pixmap = new QPixmap(pm);
+ m_has_pixmap_texture = true;
+ }
+
+ m_image = QImage();
+ }
+
+ void setImage(const QImage &image) {
+ m_image = image;
+ delete m_pixmap;
+ m_pixmap = 0;
+ m_has_pixmap_texture = false;
+ }
+
+ QPixmap &pixmap() {
+ if (!m_pixmap) {
+ m_pixmap = new QPixmap(QPixmap::fromImage(m_image));
+ }
+ return *m_pixmap;
+ }
+
+ QImage &image() {
+ if (m_image.isNull() && m_pixmap)
+ m_image = m_pixmap->toImage();
+ return m_image;
+ }
+
+ QPixmap *m_pixmap;
+ QImage m_image;
+ bool m_has_pixmap_texture;
+};
+// END BLOCK
+
+/*!
+ \class TQPainter
+ \brief The TQPainter class is a Qt 3 compatibility wrapper for QPainter.
+
+ \compat
+
+ Prior to Qt 4, QPainter specialized the pen drawing for rectangle
+ based functions (in particular: drawRect, drawEllipse,
+ drawRoundRect, drawArc, drawChord and drawPie). When stroking a
+ rectangle of width 10, the pen would draw a rectangle of width 10.
+ Drawing a polygon defined by the corner points of the same
+ rectangle the stroke would have a width of 11.
+
+ The reason for this is best explained using the picture below:
+
+ \img q3painter_rationale.png
+
+ As we can see, stroking the rectangle so it gets a width of 10,
+ means the pen is drawn on a rectangle on width 9. The polygon,
+ however follows a consistent model.
+
+ In Qt 4, all rectangle based functions have changed to follow the
+ polygon approach, which means that the rectangle defines the size of
+ the fill, and the pen follows the edges of the shape. For pen widths
+ of 0 and 1 this means that the stroke will be inside the shape on the
+ left and the top and outside on the bottom and right.
+
+ The reason for the change in Qt 4 is so that we provide consistency
+ for all drawing functions even with complex transformations.
+*/
+
+TQPainter::TQPainter() : QPainter(), has_qwidget(FALSE), current_penpos(0,0) {
+}
+
+TQPainter::TQPainter( const QWidget *pdev, bool unclipped) : QPainter((QWidget*)pdev), has_qwidget(TRUE), current_penpos(0,0) {
+ qwidget_ptr = (QWidget*)pdev;
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+}
+
+TQPainter::TQPainter( QPaintDevice *pdev, bool unclipped) : QPainter(pdev), has_qwidget(FALSE), current_penpos(0,0) {
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+}
+
+TQPainter::TQPainter( QWidget *pdev, const QWidget *w, bool unclipped) : QPainter(pdev), has_qwidget(TRUE), current_penpos(0,0) {
+ qwidget_ptr = pdev;
+ initFrom(w);
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+}
+
+TQPainter::TQPainter( QPaintDevice *pdev, const QWidget *w, bool unclipped ) : QPainter(pdev), has_qwidget(FALSE), current_penpos(0,0) {
+ initFrom(w);
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+}
+
+// [FIXME]
+void TQPainter::flush() {
+ printf("[WARNING] void TQPainter::flush() unimplemented\n\r");
+}
+
+// [FIXME]
+void TQPainter::flush( const TQRegion &region, TQPainter::CoordinateMode cm ) {
+ printf("[WARNING] void TQPainter::flush( const TQRegion &region, CoordinateMode cm = CoordDevice ) unimplemented\n\r");
+}
+
+void TQPainter::setBrush(const QBrush &brush) {
+ return QPainter::setBrush(brush);
+}
+
+void TQPainter::setBrush(Qt::BrushStyle style) {
+ return QPainter::setBrush(style);
+}
+
+void TQPainter::setBrush(TQt::BrushStyle style) {
+ this->QPainter::setBrush((Qt::BrushStyle)style);
+}
+
+TQPoint TQPainter::pos() const {
+ return current_penpos;
+}
+
+bool TQPainter::tqbegin( QPaintDevice *pdev, bool unclipped ) {
+ bool ret = begin(pdev);
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+ return ret;
+}
+
+bool TQPainter::tqbegin( QPaintDevice *pdev, const QWidget *init, bool unclipped ) {
+ bool ret = begin(pdev);
+ initFrom(init);
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+ return ret;
+}
+
+QRectF TQPainter::boundingRect(const QRectF &rect, int flags, const QString &text) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ QRectF tqbr = QPainter::boundingRect(rect, flags, text);
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+QRect TQPainter::boundingRect(const QRect &rect, int flags, const QString &text) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ QRect tqbr = QPainter::boundingRect(rect, flags, text);
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+QRect TQPainter::boundingRect(int x, int y, int w, int h, int flags, const QString &text) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ QRect tqbr = QPainter::boundingRect(x, y, w, h, flags, text);
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+QRectF TQPainter::boundingRect(const QRectF &rect, const QString &text, const QTextOption &o) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ QRectF tqbr = QPainter::boundingRect(rect, text, o);
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+TQRect TQPainter::boundingRect(const QRect &rect, int flags, const QString &text, int len) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ TQRect tqbr = QPainter::boundingRect(rect, flags, text.left(len));
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+TQRect TQPainter::boundingRect(int x, int y, int w, int h, int flags, const QString &text, int len) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ TQRect tqbr = QPainter::boundingRect(QRect(x, y, w, h), flags, text.left(len));
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+void TQPainter::drawText(const QPointF &p, const QString &s) {
+ QPainter::drawText(p, s);
+}
+
+void TQPainter::drawText(const QPoint &p, const QString &s) {
+ QPainter::drawText(p, s);
+}
+
+void TQPainter::drawText(int x, int y, const QString &s) {
+ QPainter::drawText(x, y, s);
+}
+
+void TQPainter::drawText(const QPointF &p, const QString &str, int tf, int justificationPadding) {
+ QPainter::drawText(p, str, tf, justificationPadding);
+}
+
+void TQPainter::drawText(const QRectF &r, int flags, const QString &text, QRectF *br) {
+ QPainter::drawText(r, flags, text, br);
+}
+
+void TQPainter::drawText(const QRect &r, int flags, const QString &text, QRect *br) {
+ QPainter::drawText(r, flags, text, br);
+}
+
+void TQPainter::drawText(int x, int y, int w, int h, int flags, const QString &text, QRect *br) {
+ QPainter::drawText(x, y, w, h, flags, text, br);
+}
+
+void TQPainter::drawText(const QRectF &r, const QString &text, const QTextOption &o) {
+ QPainter::drawText(r, text, o);
+}
+
+void TQPainter::drawText( int x, int y, const TQString &s, int len, TextDirection dir ) {
+ Qt::LayoutDirection old = layoutDirection();
+ if (dir == RTL)
+ setLayoutDirection(Qt::RightToLeft);
+ else if (dir == LTR)
+ setLayoutDirection(Qt::LeftToRight);
+ QPainter::drawText(x, y, s.left(len));
+ setLayoutDirection(old);
+}
+void TQPainter::drawText( const TQPoint &p, const TQString &s, int len, TextDirection dir ) {
+ Qt::LayoutDirection old = layoutDirection();
+ if (dir == RTL)
+ setLayoutDirection(Qt::RightToLeft);
+ else if (dir == LTR)
+ setLayoutDirection(Qt::LeftToRight);
+ QPainter::drawText(p, s.left(len));
+ setLayoutDirection(old);
+}
+void TQPainter::drawText( int x, int y, const TQString &s, int pos, int len, TextDirection dir ) {
+ Qt::LayoutDirection old = layoutDirection();
+ if (dir == RTL)
+ setLayoutDirection(Qt::RightToLeft);
+ else if (dir == LTR)
+ setLayoutDirection(Qt::LeftToRight);
+ QPainter::drawText(x, y, s.mid(pos, len));
+ setLayoutDirection(old);
+}
+void TQPainter::drawText( const TQPoint &p, const TQString &s, int pos, int len, TextDirection dir ) {
+ Qt::LayoutDirection old = layoutDirection();
+ if (dir == RTL)
+ setLayoutDirection(Qt::RightToLeft);
+ else if (dir == LTR)
+ setLayoutDirection(Qt::LeftToRight);
+ QPainter::drawText(p, s.mid(pos, len));
+ setLayoutDirection(old);
+}
+
+void TQPainter::drawText(int x, int y, const QString &s, int pos, int len) {
+ drawText(x, y, s.mid(pos, len));
+}
+
+void TQPainter::drawText(const QPoint &p, const QString &s, int pos, int len) {
+ drawText(p, s.mid(pos, len));
+}
+
+void TQPainter::drawText(int x, int y, const QString &s, int len) {
+ drawText(x, y, s.left(len));
+}
+
+void TQPainter::drawText(const QPoint &p, const QString &s, int len) {
+ drawText(p, s.left(len));
+}
+
+void TQPainter::drawText(const QRect &r, int flags, const QString &str, int len, QRect *br) {
+ drawText(r, flags, str.left(len), br);
+}
+
+void TQPainter::drawText(int x, int y, int w, int h, int flags, const QString &text, int len, QRect *br) {
+ drawText(QRect(x, y, w, h), flags, text.left(len), br);
+}
+
+int TQPainter::tabStops() const
+{
+ printf("[WARNING] TQPainter::tabStops unimplemented!\n\r");
+}
+
+void TQPainter::setTabStops( int ts )
+{
+ printf("[WARNING] TQPainter::setTabStops unimplemented!\n\r");
+
+// #if defined(TQT_CHECK_STATE)
+// if ( !isActive() )
+// qWarning( "TQPainter::setTabStops: Will be reset by begin()" );
+// #endif
+// tabstops = ts;
+// if ( isActive() && testf(ExtDev) ) { // tell extended tqdevice
+// TQPDevCmdParam param[1];
+// param[0].ival = ts;
+// pdev->cmd( TQPaintDevice::PdcSetTabStops, this, param );
+// }
+}
+
+int *TQPainter::tabArray() const
+{
+ printf("[WARNING] TQPainter::tabArray unimplemented!\n\r");
+}
+
+void TQPainter::setTabArray( int *ta )
+{
+ printf("[WARNING] TQPainter::setTabArray unimplemented!\n\r");
+
+// #if defined(TQT_CHECK_STATE)
+// if ( !isActive() )
+// qWarning( "TQPainter::setTabArray: Will be reset by begin()" );
+// #endif
+// if ( ta != tabarray ) {
+// tabarraylen = 0;
+// if ( tabarray ) // Avoid purify complaint
+// delete [] tabarray; // delete old array
+// if ( ta ) { // tabarray = copy of 'ta'
+// while ( ta[tabarraylen] )
+// tabarraylen++;
+// tabarraylen++; // and 0 terminator
+// tabarray = new int[tabarraylen]; // duplicate ta
+// memcpy( tabarray, ta, sizeof(int)*tabarraylen );
+// } else {
+// tabarray = 0;
+// }
+// }
+// if ( isActive() && testf(ExtDev) ) { // tell extended tqdevice
+// TQPDevCmdParam param[2];
+// param[0].ival = tabarraylen;
+// param[1].ivec = tabarray;
+// pdev->cmd( TQPaintDevice::PdcSetTabArray, this, param );
+// }
+}
+
+void TQPainter::drawImage( int x, int y, const TQImage image, int sx, int sy, int sw, int sh, int conversionFlags ) {
+ QPainter::drawImage(x, y, image, sx, sy, sw, sh, (Qt::ImageConversionFlags)conversionFlags);
+}
+
+void TQPainter::drawImage( const TQPoint p, const TQImage image, const TQRect sr, int conversionFlags ) {
+ QPainter::drawImage(p, image, sr, (Qt::ImageConversionFlags)conversionFlags);
+}
+
+void TQPainter::drawImage( const TQPoint p, const TQImage image, int conversion_flags ) {
+ TQ_UNUSED(conversion_flags);
+ QPainter::drawImage(p, image);
+}
+
+void TQPainter::drawImage( const TQRect r, const TQImage image ) {
+ QPainter::drawImage(r, image);
+}
+
+void TQPainter::resetXForm() {
+ resetTransform();
+}
+
+// [FIXME] The drawWinFocusRect methods below probably need tweaking to exactly match the old Qt3 behaviour
+void TQPainter::drawWinFocusRect( int x, int y, int w, int h ) {
+ drawWinFocusRect( x, y, w, h, TRUE, TQt::color0 );
+}
+
+void TQPainter::drawWinFocusRect( int x, int y, int w, int h, const TQColor &bgColor ) {
+ drawWinFocusRect( x, y, w, h, FALSE, bgColor );
+}
+
+void TQPainter::drawWinFocusRect( const TQRect &tqr ) {
+ drawWinFocusRect( tqr.x(), tqr.y(), tqr.width(), tqr.height() );
+}
+
+void TQPainter::drawWinFocusRect( const TQRect &tqr, const TQColor &bgColor ) {
+ drawWinFocusRect( tqr.x(), tqr.y(), tqr.width(), tqr.height(), bgColor );
+}
+
+void TQPainter::setBackgroundColor(const QColor &color) {
+ setBackground(color);
+}
+
+const QColor &TQPainter::backgroundColor() const {
+ return background().color();
+}
+
+void TQPainter::setClipRect(const QRectF &qrf, Qt::ClipOperation op) {
+ QPainter::setClipRect(qrf, op);
+}
+
+void TQPainter::setClipRect(const QRect &qr, Qt::ClipOperation op) {
+ QPainter::setClipRect(qr, op);
+}
+
+void TQPainter::setClipRect( int x, int y, int w, int h, TQPainter::CoordinateMode cm ) {
+ TQRect r(x, y, w, h);
+ setClipRect(r, cm);
+}
+
+void TQPainter::redirect(QPaintDevice *pdev, QPaintDevice *replacement) {
+ if (replacement == 0) {
+ restoreRedirected(pdev);
+ }
+ else {
+ setRedirected(pdev, replacement);
+ }
+}
+
+TQPaintDevice *TQPainter::redirect(QPaintDevice *pdev) {
+ return static_cast<TQPaintDevice*>(const_cast<QPaintDevice*>(redirected(pdev)));
+}
+
+void TQPainter::setWorldXForm(bool enabled) {
+ setMatrixEnabled(enabled);
+}
+
+bool TQPainter::hasWorldXForm() const {
+ return matrixEnabled();
+}
+
+void TQPainter::setViewXForm(bool enabled) {
+ setViewTransformEnabled(enabled);
+}
+
+bool TQPainter::hasViewXForm() const {
+ return viewTransformEnabled();
+}
+
+// [FIXME]
+void TQPainter::initialize() {
+ printf("[WARNING] TQColor static void initialize() not implemented\n\r");
+}
+
+// [FIXME]
+void TQPainter::cleanup() {
+ printf("[WARNING] TQColor static void cleanup() not implemented\n\r");
+}
+
+void TQPainter::moveTo( const TQPoint &p )
+{
+ moveTo( p.x(), p.y() );
+}
+
+void TQPainter::lineTo( const TQPoint &p )
+{
+ lineTo( p.x(), p.y() );
+}
+
+void TQPainter::drawRect(const QRect &r)
+{
+ QPainter::drawRect(adjustedRectangle(r));
+}
+
+void TQPainter::drawEllipse(const QRect &r)
+{
+ QPainter::drawEllipse(adjustedRectangle(r));
+}
+
+void TQPainter::drawRoundRect(const QRect &r, int xrnd, int yrnd)
+{
+ QPainter::drawRoundRect(adjustedRectangle(r), xrnd, yrnd);
+}
+
+void TQPainter::drawArc(const QRect &r, int angle, int arcLength)
+{
+ QPainter::drawArc(adjustedRectangle(r), angle, arcLength);
+}
+
+void TQPainter::drawPie(const QRect &r, int angle, int arcLength)
+{
+ QPainter::drawPie(adjustedRectangle(r), angle, arcLength);
+}
+
+void TQPainter::drawChord(const QRect &r, int angle, int arcLength)
+{
+ QPainter::drawChord(adjustedRectangle(r), angle, arcLength);
+}
+
+void TQPainter::tqdrawTextItem( const TQPoint& p, const TQTextItem &ti, int textflags )
+{
+ tqdrawTextItem( p.x(), p.y(), ti, textflags );
+}
+
+// [FIXME]
+// Verify these mappings...
+// They will need to be kept in sync with the code inside tqpainter_x11.cpp
+TQt::RasterOp TQPainter::rasterOp() const
+{
+ TQt::RasterOp cm;
+ switch (rop) {
+ case QPainter::CompositionMode_SourceOver:
+ cm=CopyROP;
+ break;
+ case QPainter::RasterOp_SourceOrDestination:
+ cm=OrROP;
+ break;
+ case QPainter::RasterOp_SourceXorDestination:
+ cm=XorROP;
+ break;
+ case QPainter::RasterOp_NotSourceAndDestination:
+ cm=NotAndROP;
+ break;
+ case QPainter::RasterOp_NotSource:
+ cm=NotCopyROP;
+ break;
+ case QPainter::RasterOp_NotSourceXorDestination:
+ cm=NotXorROP;
+ break;
+ case QPainter::RasterOp_SourceAndDestination:
+ cm=AndROP;
+ break;
+ case QPainter::CompositionMode_Clear:
+ cm=ClearROP;
+ break;
+ case QPainter::CompositionMode_Destination:
+ cm=NopROP;
+ break;
+ case QPainter::RasterOp_SourceAndNotDestination:
+ cm=AndNotROP;
+ break;
+ case QPainter::RasterOp_NotSourceOrNotDestination:
+ cm=NandROP;
+ break;
+ case QPainter::RasterOp_NotSourceAndNotDestination:
+ cm=NorROP;
+ break;
+ default:
+ cm=CopyROP;
+ break;
+ }
+ return cm;
+}
+
+/*!
+ \fn TQPainter::TQPainter()
+
+ Constructs a TQPainter.
+*/
+
+/*!
+ \fn TQPainter::TQPainter(QPaintDevice *pdev)
+
+ Constructs a TQPainter that operates on tqdevice \a pdev.
+*/
+
+/*!
+ \internal
+*/
+
+int TQPainter::rectSubtraction() const {
+ return pen().style() != Qt::NoPen && pen().width() == 0 ? 1 : 0;
+}
+
+/*!
+ \internal
+*/
+QRect TQPainter::adjustedRectangle(const QRect &r)
+{
+ QRect rect = r.normalized();
+ int subtract = rectSubtraction();
+ if (subtract != 0)
+ rect.setSize(QSize(rect.width() - subtract, rect.height() - subtract));
+ return rect;
+}
+
+
+/*!
+ \fn void TQPainter::drawRect(int x, int y, int w, int h)
+
+ \overload
+
+ Draws the rectangle that fits inside the bounds specified by \a x,
+ \a y, \a w and \a h using the current pen and brush.
+*/
+
+/*!
+ \fn void TQPainter::drawRect(const QRect &r)
+
+ Draws a rectangle that fits inside the rectangle \a r using the
+ current pen and brush.
+
+*/
+
+
+
+/*!
+ \fn TQPainter::drawEllipse(const QRect &r)
+
+ Draws the ellipse that fits inside the bounds \a r using the
+ current pen and brush.
+
+*/
+
+/*!
+ \fn TQPainter::drawEllipse(int x, int y, int width, int height)
+
+ \overload
+
+ Draws an ellipse that fits inside the bounds specified by \a x,
+ \a y, \a width and \a height using the current pen and brush.
+
+*/
+
+/*!
+ \fn void TQPainter::drawPie(int x, int y, int w, int h, int
+ startAngle, int spanAngle)
+
+ \overload
+
+ Draws a pie segment that fits inside the bounds (\a{x}, \a{y},
+ \a{w}, \a{h}) with the given \a startAngle and \a spanAngle.
+*/
+
+/*!
+ \fn void TQPainter::drawPie(const QRect &r, int a, int alen)
+
+ Draws a pie defined by the rectangle \a r, the start angle \a a
+ and the arc length \a alen.
+
+ The pie is filled with the current brush().
+
+ The angles \a a and \a alen are 1/16th of a degree, i.e. a full
+ circle equals 5760 (16*360). Positive values of \a a and \a alen
+ mean counter-clockwise while negative values mean the clockwise
+ direction. Zero degrees is at the 3 o'clock position.
+
+ \sa drawArc(), drawChord()
+*/
+
+/*!
+ \fn void TQPainter::drawArc(int x, int y, int w, int h, int
+ startAngle, int spanAngle)
+
+ \overload
+
+ Draws the arc that fits inside the rectangle (\a{x}, \a{y}, \a{w},
+ \a{h}), with the given \a startAngle and \a spanAngle.
+*/
+
+/*!
+ \fn void TQPainter::drawArc(const QRect &r, int a, int alen)
+
+ Draws an arc defined by the rectangle \a r, the start angle \a a
+ and the arc length \a alen.
+
+ The angles \a a and \a alen are 1/16th of a degree, i.e. a full
+ circle equals 5760 (16*360). Positive values of \a a and \a alen
+ mean counter-clockwise while negative values mean the clockwise
+ direction. Zero degrees is at the 3 o'clock position.
+
+ Example:
+ \snippet doc/src/snippets/code/src_qt3support_painting_q3painter.cpp 0
+
+ \sa drawPie(), drawChord()
+*/
+
+/*!
+ \fn void TQPainter::drawChord(int x, int y, int w, int h, int
+ startAngle, int spanAngle)
+
+ \overload
+
+ Draws a chord that fits inside the rectangle (\a{x}, \a{y}, \a{w},
+ \a{h}) with the given \a startAngle and \a spanAngle.
+*/
+
+
+/*!
+ \fn void TQPainter::drawChord(const QRect &r, int a, int alen)
+
+ Draws a chord defined by the rectangle \a r, the start angle \a a
+ and the arc length \a alen.
+
+ The chord is filled with the current brush().
+
+ The angles \a a and \a alen are 1/16th of a degree, i.e. a full
+ circle equals 5760 (16*360). Positive values of \a a and \a alen
+ mean counter-clockwise while negative values mean the clockwise
+ direction. Zero degrees is at the 3 o'clock position.
+
+ \sa drawArc(), drawPie()
+*/
+
+/*!
+ \fn void TQPainter::drawRoundRect(const QRect &r, int xrnd, int yrnd)
+
+ Draws a rounded rect that fits into the bounds \a r using the current
+ pen and brush. The parameters \a xrnd and \a yrnd specifies the roundness
+ in x and y direction.
+*/
+
+/*!
+ \fn void TQPainter::drawRoundRect(int x, int y, int w, int h, int xrnd, int yrnd)
+
+ \overload
+
+ Draws a rounded rect that fits into the bounds \a x, \a y, \a w
+ and \a h using the current pen and brush. The parameters \a xrnd
+ and \a yrnd specifies the roundness in x and y direction.
+*/
+
+/*!
+ \fn void QPainter::drawLineSegments(const QPolygon &polygon, int
+ index, int count)
+
+ Draws \a count separate lines from points defined by the \a
+ polygon, starting at \a{polygon}\e{[index]} (\a index defaults to
+ 0). If \a count is -1 (the default) all points until the end of
+ the array are used.
+
+ Use drawLines() combined with QPolygon::constData() instead.
+
+ \oldcode
+ QPainter painter(this);
+ painter.drawLineSegments(polygon, index, count);
+ \newcode
+ int lineCount = (count == -1) ? (polygon.size() - index) / 2 : count;
+
+ QPainter painter(this);
+ painter.drawLines(polygon.constData() + index * 2, lineCount);
+ \endcode
+*/
+
+void TQPainter::drawLineSegments(const QPolygon &polygon, int index, int count)
+{
+ int lineCount = (count == -1) ? (polygon.size() - index) / 2 : count;
+
+ drawLines(polygon.constData() + index * 2, lineCount);
+}
+
+/*!
+ \obsolete
+
+ Use the worldTransform() combined with QTransform::dx() instead.
+
+ \oldcode
+ QPainter painter(this);
+ qreal x = painter.translationX();
+ \newcode
+ QPainter painter(this);
+ qreal x = painter.worldTransform().dx();
+ \endcode
+*/
+qreal TQPainter::translationX() const
+{
+ return worldTransform().dx();
+}
+
+/*!
+ \obsolete
+
+ Use the worldTransform() combined with QTransform::dy() instead.
+
+ \oldcode
+ QPainter painter(this);
+ qreal y = painter.translationY();
+ \newcode
+ QPainter painter(this);
+ qreal y = painter.worldTransform().dy();
+ \endcode
+*/
+qreal TQPainter::translationY() const
+{
+ return worldTransform().dy();
+}
+
+/*!
+ \fn void TQPainter::map(int x, int y, int *rx, int *ry) const
+
+ \internal
+
+ Sets (\a{rx}, \a{ry}) to the point that results from applying the
+ painter's current transformation on the point (\a{x}, \a{y}).
+*/
+void TQPainter::map(int x, int y, int *rx, int *ry) const
+{
+ QPoint p(x, y);
+ p = p * combinedMatrix();
+ *rx = p.x();
+ *ry = p.y();
+}
+
+/*!
+ \internal
+ Maps a rectangle from logical coordinates to device coordinates.
+ This internal function does not handle rotation and/or shear.
+*/
+
+void TQPainter::map( int x, int y, int w, int h, int *rx, int *ry, int *rw, int *rh ) const
+{
+ TQRect qr(x, y, w, h);
+ QTransform dtrans = combinedTransform();
+ TQRect tqr = dtrans.mapRect(qr);
+ *rx = tqr.x();
+ *ry = tqr.y();
+ *rw = tqr.width();
+ *rh = tqr.height();
+}
+
+/*!
+ \fn TQPoint TQPainter::xForm(const QPoint &point) const
+
+ Use combinedTransform() instead.
+*/
+
+TQPoint TQPainter::xForm(const QPoint &p) const
+{
+ if (combinedTransform().type() == QTransform::TxNone)
+ return p;
+ return p * combinedMatrix();
+}
+
+
+/*!
+ \fn TQRect TQPainter::xForm(const QRect &rectangle) const
+ \overload
+
+ Use combinedTransform() instead of this function and call
+ mapRect() on the result to obtain a QRect.
+*/
+
+TQRect TQPainter::xForm(const QRect &r) const
+{
+ if (combinedTransform().type() == QTransform::TxNone)
+ return r;
+ return combinedMatrix().mapRect(r);
+}
+
+bool TQPainter::testf( uint b ) const {
+// printf("[WARNING] QPainter::testf() disabled\n\r");
+// return 0;
+
+ // Map to Qt4 flags and functions...
+ if ((b&IsActive)!=0) {
+ if (QPainter::isActive()) return TRUE;
+ }
+// if ((b&ExtDev)!=0) {
+// printf("[WARNING] Assuming ExtDev==false in QPainter::testf()\n\r");
+// }
+// if ((b&IsStartingUp)!=0) {
+// }
+// if ((b&NoCache)!=0) {
+// }
+ if ((b&VxF)!=0) {
+ if (QPainter::viewTransformEnabled()) return TRUE;
+ }
+ if ((b&WxF)!=0) {
+ if (QPainter::worldMatrixEnabled()) return TRUE;
+ }
+ if ((b&ClipOn)!=0) {
+ if (QPainter::hasClipping()) return TRUE;
+ }
+
+ printf("[WARNING] Assuming test flag 0x%x == false in QPainter::testf()\n\r", b);
+ return 0;
+}
+
+/*!
+ \fn TQPolygon TQPainter::xForm(const QPolygon &polygon) const
+ \overload
+
+ Use combinedTransform() instead.
+*/
+
+// TQPolygon TQPainter::xForm(const QPolygon &a) const
+// {
+// Q_D(const QPainter);
+// if (!d->engine) {
+// qWarning("QPainter::xForm: Painter not active");
+// return QPolygon();
+// }
+// if (d->state->matrix.type() == QTransform::TxNone)
+// return a;
+// return a * combinedMatrix();
+// }
+
+/*!
+ \fn TQPolygon TQPainter::xForm(const QPolygon &polygon, int index, int count) const
+ \overload
+
+ Use combinedTransform() combined with QPolygon::mid() instead.
+
+ \oldcode
+ QPainter painter(this);
+ QPolygon transformed = painter.xForm(polygon, index, count)
+ \newcode
+ QPainter painter(this);
+ QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform();
+ \endcode
+*/
+
+// TQPolygon TQPainter::xForm(const QPolygon &av, int index, int npoints) const
+// {
+// int lastPoint = npoints < 0 ? av.size() : index+npoints;
+// QPolygon a(lastPoint-index);
+// memcpy(a.data(), av.data()+index, (lastPoint-index)*sizeof(QPoint));
+// return a * combinedMatrix();
+// }
+
+/*!
+ \fn TQPoint TQPainter::xFormDev(const QPoint &point) const
+ \overload
+ \obsolete
+
+ Use combinedTransform() combined with QTransform::inverted() instead.
+
+ \oldcode
+ QPainter painter(this);
+ QPoint transformed = painter.xFormDev(point);
+ \newcode
+ QPainter painter(this);
+ QPoint transformed = point * painter.combinedTransform().inverted();
+ \endcode
+*/
+
+TQPoint TQPainter::xFormDev(const QPoint &p) const
+{
+ if(combinedTransform().type() == QTransform::TxNone)
+ return p;
+ return p * combinedMatrix().inverted();
+}
+
+/*!
+ \fn TQRect TQPainter::xFormDev(const QRect &rectangle) const
+ \overload
+ \obsolete
+
+ Use combinedTransform() combined with QTransform::inverted() instead.
+
+ \oldcode
+ QPainter painter(this);
+ QRect transformed = painter.xFormDev(rectangle);
+ \newcode
+ QPainter painter(this);
+ QRegion region = QRegion(rectangle) * painter.combinedTransform().inverted();
+ QRect transformed = region.boundingRect();
+ \endcode
+*/
+
+TQRect TQPainter::xFormDev(const QRect &r) const
+{
+ if (combinedTransform().type() == QTransform::TxNone)
+ return r;
+ return combinedMatrix().inverted().mapRect(r);
+}
+
+/*!
+ \overload
+
+ \fn TQPoint TQPainter::xFormDev(const QPolygon &polygon) const
+ \obsolete
+
+ Use combinedTransform() combined with QTransform::inverted() instead.
+
+ \oldcode
+ QPainter painter(this);
+ QPolygon transformed = painter.xFormDev(rectangle);
+ \newcode
+ QPainter painter(this);
+ QPolygon transformed = polygon * painter.combinedTransform().inverted();
+ \endcode
+*/
+
+// TQPolygon TQPainter::xFormDev(const QPolygon &a) const
+// {
+// Q_D(const QPainter);
+// if (!d->engine) {
+// qWarning("QPainter::xFormDev: Painter not active");
+// return QPolygon();
+// }
+// if (d->state->matrix.type() == QTransform::TxNone)
+// return a;
+// return a * combinedMatrix().inverted();
+// }
+
+/*!
+ \fn TQPolygon TQPainter::xFormDev(const QPolygon &polygon, int index, int count) const
+ \overload
+ \obsolete
+
+ Use combinedTransform() combined with QPolygon::mid() and QTransform::inverted() instead.
+
+ \oldcode
+ QPainter painter(this);
+ QPolygon transformed = painter.xFormDev(polygon, index, count);
+ \newcode
+ QPainter painter(this);
+ QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform().inverted();
+ \endcode
+*/
+
+// TQPolygon TQPainter::xFormDev(const QPolygon &ad, int index, int npoints) const
+// {
+// Q_D(const QPainter);
+// int lastPoint = npoints < 0 ? ad.size() : index+npoints;
+// QPolygon a(lastPoint-index);
+// memcpy(a.data(), ad.data()+index, (lastPoint-index)*sizeof(QPoint));
+// if (d->state->matrix.type() == QTransform::TxNone)
+// return a;
+// return a * combinedMatrix().inverted();
+// }
+
+/*! \obsolete
+ Sets the current pen position to \a (x, y)
+
+ \sa lineTo(), pos()
+*/
+
+void TQPainter::moveTo( int x, int y )
+{
+ QPainterPath path;
+ path.moveTo(x, y);
+ drawPath(path);
+ current_penpos = QPoint(x, y);
+}
+
+/*! \obsolete
+ Use drawLine() instead.
+
+ Draws a line from the current pen position to \a (x, y) and sets
+ \a (x, y) to be the new current pen position.
+
+ \sa TQPen moveTo(), drawLine(), pos()
+*/
+
+void TQPainter::lineTo( int x, int y )
+{
+ QPainterPath path;
+ path.moveTo(current_penpos.x(), current_penpos.y());
+ path.lineTo(x, y);
+ drawPath(path);
+ current_penpos = QPoint(x, y);
+}
+
+static void bitBlt_helper(QPaintDevice *dst, const QPoint &dp,
+ const QPaintDevice *src, const QRect &sr, bool)
+{
+ Q_ASSERT(dst);
+ Q_ASSERT(src);
+
+ if (src->devType() == QInternal::Pixmap) {
+ const QPixmap *pixmap = static_cast<const QPixmap *>(src);
+ QPainter pt(dst);
+ pt.drawPixmap(dp, *pixmap, sr);
+
+ } else {
+ qWarning("QPainter: bitBlt only works when source is of type pixmap");
+ }
+}
+
+void bitBlt(QPaintDevice *dst, int dx, int dy,
+ const QPaintDevice *src, int sx, int sy, int sw, int sh,
+ bool ignoreMask )
+{
+ bitBlt_helper(dst, QPoint(dx, dy), src, QRect(sx, sy, sw, sh), ignoreMask);
+}
+
+void bitBlt(QPaintDevice *dst, const QPoint &dp, const QPaintDevice *src, const QRect &sr, bool ignoreMask)
+{
+ bitBlt_helper(dst, dp, src, sr, ignoreMask);
+}
+
+void bitBlt(QPaintDevice *dst, int dx, int dy,
+ const QImage *src, int sx, int sy, int sw, int sh, int fl)
+{
+ Qt::ImageConversionFlags flags(fl);
+ QPixmap srcPixmap = QPixmap::fromImage(*src, flags);
+ bitBlt_helper(dst, QPoint(dx, dy), &srcPixmap, QRect(sx, sy, sw, sh), false);
+}
+
+const TQWMatrix &TQPainter::tqworldMatrix() const {
+ return (*(static_cast<const TQWMatrix*>(&worldMatrix())));
+}
+
+/*!
+ \fn void TQPainter::tqdrawTextItem(const TQPoint &, const TQTextItem &, int)
+ \internal
+*/
+
+static inline void fix_neg_rect( int *x, int *y, int *w, int *h )
+{
+ if ( *w < 0 ) {
+ *w = -*w + 2;
+ *x -= *w - 1;
+ }
+ if ( *h < 0 ) {
+ *h = -*h + 2;
+ *y -= *h - 1;
+ }
+}
+void TQPainter::fix_neg_rect( int *x, int *y, int *w, int *h )
+{
+ ::fix_neg_rect(x,y,w,h);
+}
+
+TQRegion TQPainter::clipRegion( CoordinateMode cm ) const {
+ QRegion qr = QPainter::clipRegion();
+ QRegion tqr = qr;
+ if (cm == CoordDevice) {
+ // Convert to device coordinates
+ QTransform dtrans = combinedTransform();
+ tqr = dtrans.map(qr);
+ }
+ return tqr;
+}
+
+void TQPainter::setClipRegion( const QRegion &qr, CoordinateMode cm ) {
+ QRegion tqr = qr;
+
+ if (cm == CoordDevice) {
+ // Convert from device coordinates
+ QTransform itrans = combinedTransform().inverted();
+ tqr = itrans.map(qr);
+
+ QPainter::setClipRegion( tqr, Qt::ReplaceClip );
+ }
+ else {
+ QPainter::setClipRegion( tqr, Qt::ReplaceClip );
+ }
+}
+
+void TQPainter::setClipRect( const TQRect &qr, CoordinateMode cm ) {
+ QRect tqr = qr;
+
+ if (cm == CoordDevice) {
+ // Convert from device coordinates
+ QTransform itrans = combinedTransform().inverted();
+ tqr = itrans.mapRect(qr);
+
+ QPainter::setClipRect( tqr, Qt::ReplaceClip );
+ }
+ else {
+ QPainter::setClipRect( tqr, Qt::ReplaceClip );
+ }
+}
+
+#ifndef TQT_NO_BEZIER
+void TQPainter::drawCubicBezier(const TQPointArray &a, int index)
+{
+ if ((int)a.size() - index < 4) {
+ qWarning("QPainter::drawCubicBezier: Cubic Bezier needs 4 control "
+ "points");
+ return;
+ }
+
+ QPainterPath path;
+ path.moveTo(a.at(index));
+ path.cubicTo(a.at(index+1), a.at(index+2), a.at(index+3));
+ strokePath(path, pen());
+}
+#endif // TQT_NO_BEZIER
+
+#ifndef TQT_NO_PICTURE
+void TQPainter::drawPicture( const QPicture pic ) {
+ QPainter::drawPicture(0, 0, pic);
+}
+
+void TQPainter::drawPicture( int x, int y, const QPicture pic ) {
+ QPainter::drawPicture(x, y, pic);
+}
+
+void TQPainter::drawPicture( const QPoint point, const QPicture pic ) {
+ QPainter::drawPicture(point.x(), point.y(), pic);
+}
+#endif // TQT_NO_PICTURE
+
+/*! \obsolete
+
+ We recommend using save() instead.
+*/
+
+void TQPainter::saveWorldMatrix() {
+ save();
+}
+
+/*! \obsolete
+ We recommend using restore() instead.
+*/
+
+void TQPainter::restoreWorldMatrix() {
+ restore();
+}
+
+/*!
+ \overload
+
+ Returns the point array \a av transformed from model coordinates
+ to tqdevice coordinates.
+
+ \sa xFormDev(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xForm( const TQPointArray &av ) const
+{
+ TQPointArray a = av;
+ if ( combinedTransform().type() != QTransform::TxNone )
+ {
+ return TQT_TQWMATRIX_OBJECT(combinedMatrix()) * av;
+ }
+ return a;
+}
+
+/*!
+ \overload
+
+ Returns the point array \a av transformed from model coordinates
+ to tqdevice coordinates. The \a index is the first point in the
+ array and \a npoints denotes the number of points to be
+ transformed. If \a npoints is negative, all points from \a
+ av[index] until the last point in the array are transformed.
+
+ The returned point array consists of the number of points that
+ were transformed.
+
+ Example:
+ \code
+ TQPointArray a(10);
+ TQPointArray b;
+ b = painter.xForm(a, 2, 4); // b.size() == 4
+ b = painter.xForm(a, 2, -1); // b.size() == 8
+ \endcode
+
+ \sa xFormDev(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xForm( const TQPointArray &av, int index,
+ int npoints ) const
+{
+ int lastPoint = npoints < 0 ? av.size() : index+npoints;
+ TQPointArray a( lastPoint-index );
+ memcpy( a.data(), av.data()+index, (lastPoint-index)*sizeof( TQPoint ) );
+ return TQT_TQWMATRIX_OBJECT(combinedMatrix()) * a;
+}
+
+/*!
+ \overload
+
+ Returns the point array \a ad transformed from tqdevice coordinates
+ to model coordinates.
+
+ \sa xForm(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xFormDev( const TQPointArray &ad ) const
+{
+ if ( combinedTransform().type() == QTransform::TxNone )
+ return ad;
+ return TQT_TQWMATRIX_OBJECT(combinedMatrix().inverted()) * ad;
+}
+
+/*!
+ \overload
+
+ Returns the point array \a ad transformed from tqdevice coordinates
+ to model coordinates. The \a index is the first point in the array
+ and \a npoints denotes the number of points to be transformed. If
+ \a npoints is negative, all points from \a ad[index] until the
+ last point in the array are transformed.
+
+ The returned point array consists of the number of points that
+ were transformed.
+
+ Example:
+ \code
+ TQPointArray a(10);
+ TQPointArray b;
+ b = painter.xFormDev(a, 1, 3); // b.size() == 3
+ b = painter.xFormDev(a, 1, -1); // b.size() == 9
+ \endcode
+
+ \sa xForm(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xFormDev( const TQPointArray &ad, int index, int npoints ) const
+{
+ int lastPoint = npoints < 0 ? ad.size() : index+npoints;
+ TQPointArray a( lastPoint-index );
+ memcpy( a.data(), ad.data()+index, (lastPoint-index)*sizeof( TQPoint ) );
+ if ( combinedTransform().type() == QTransform::TxNone )
+ return a;
+ return TQT_TQWMATRIX_OBJECT(combinedMatrix().inverted()) * a;
+}
+
+/*!
+ Draws/plots an array of points, \a a, using the current pen.
+
+ If \a index is non-zero (the default is zero) only points from \a
+ index are drawn. If \a npoints is negative (the default) the rest
+ of the points from \a index are drawn. If \a npoints is zero or
+ greater, \a npoints points are drawn.
+
+ \warning On X11, coordinates that do not fit into 16-bit signed
+ values are truncated. This limitation is expected to go away in
+ TQt 4.
+*/
+
+void TQPainter::drawPoints( const TQPointArray& a, int index, int npoints )
+{
+ if ( npoints < 0 )
+ npoints = a.size() - index;
+ if ( index + npoints > (int)a.size() )
+ npoints = a.size() - index;
+ if ( !isActive() || npoints < 1 || index < 0 )
+ return;
+ TQPointArray pa = a;
+ for (int i=0; i<npoints; i++) {
+ TQPoint p( pa[index+i].x(), pa[index+i].y() );
+ drawPoint(p);
+ }
+}
+
+/*!
+ Returns the font info for the painter, if the painter is active.
+ It is not possible to obtain font information for an inactive
+ painter, so the return value is undefined if the painter is not
+ active.
+
+ \sa fontMetrics(), isActive()
+*/
+
+TQFontInfo TQPainter::fontInfo() const
+{
+ printf("[WARNING] TQFontInfo TQPainter::fontInfo() partially implemented!\n\r");
+
+ QFontInfo qfi = QPainter::fontInfo();
+ TQFontInfo tqfi = TQFontInfo(*static_cast<TQFontInfo*>(&qfi));
+ return tqfi;
+
+// if ( pdev && pdev->devType() == TQInternal::Picture )
+// return TQFontInfo( cfont );
+//
+// return TQFontInfo(this);
+}
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of TQPainter, TQPen and TQBrush classes
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpainter_p.h"
+#include "tqbitmap.h"
+#include "tqptrstack.h"
+#include "tqptrdict.h"
+#include "tqdatastream.h"
+#include "tqwidget.h"
+#include "tqimage.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqapplication.h"
+#include "tqrichtext_p.h"
+#include "tqregexp.h"
+#include "tqcleanuphandler.h"
+#ifdef TQ_WS_TQWS
+#include "tqgfx_qws.h"
+#endif
+#include <string.h>
+
+#include "tqtextlayout_p.h"
+#include "tqfontengine_p.h"
+
+#ifndef TQT_NO_TRANSFORMATIONS
+typedef TQPtrStack<TQWMatrix> TQWMatrixStack;
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+/*!
+ \class TQPainter tqpainter.h
+ \brief The TQPainter class does low-level painting e.g. on widgets.
+
+ \ingroup graphics
+ \ingroup images
+ \mainclass
+
+ The painter provides highly optimized functions to do most of the
+ drawing GUI programs require. TQPainter can draw everything from
+ simple lines to complex tqshapes like pies and chords. It can also
+ draw aligned text and pixmaps. Normally, it draws in a "natural"
+ coordinate system, but it can also do view and world
+ transformation.
+
+ The typical use of a painter is:
+
+ \list
+ \i Construct a painter.
+ \i Set a pen, a brush etc.
+ \i Draw.
+ \i Destroy the painter.
+ \endlist
+
+ Mostly, all this is done inside a paint event. (In fact, 99% of
+ all TQPainter use is in a reimplementation of
+ TQWidget::paintEvent(), and the painter is heavily optimized for
+ such use.) Here's one very simple example:
+
+ \code
+ void SimpleExampleWidget::paintEvent()
+ {
+ TQPainter paint( this );
+ paint.setPen( TQt::blue );
+ paint.drawText( rect(), AlignCenter, "The Text" );
+ }
+ \endcode
+
+ Usage is simple, and there are many settings you can use:
+
+ \list
+
+ \i font() is the currently set font. If you set a font that isn't
+ available, TQt tqfinds a close match. In fact font() returns what
+ you set using setFont() and fontInfo() returns the font actually
+ being used (which may be the same).
+
+ \i brush() is the currently set brush; the color or pattern that's
+ used for filling e.g. circles.
+
+ \i pen() is the currently set pen; the color or stipple that's
+ used for drawing lines or boundaries.
+
+ \i backgroundMode() is \c Opaque or \c Transtqparent, i.e. whether
+ backgroundColor() is used or not.
+
+ \i backgroundColor() only applies when backgroundMode() is Opaque
+ and pen() is a stipple. In that case, it describes the color of
+ the background pixels in the stipple.
+
+ \i rasterOp() is how pixels drawn interact with the pixels already
+ there.
+
+ \i brushOrigin() is the origin of the tiled brushes, normally the
+ origin of the window.
+
+ \i viewport(), window(), tqworldMatrix() and many more make up the
+ painter's coordinate transformation system. See \link
+ coordsys.html The Coordinate System \endlink for an explanation of
+ this, or see below for a very brief overview of the functions.
+
+ \i hasClipping() is whether the painter clips at all. (The paint
+ tqdevice clips, too.) If the painter clips, it clips to clipRegion().
+
+ \i pos() is the current position, set by moveTo() and used by
+ lineTo().
+
+ \endlist
+
+ Note that some of these settings mirror settings in some paint
+ tqdevices, e.g. TQWidget::font(). TQPainter::begin() (or the TQPainter
+ constructor) copies these attributes from the paint tqdevice.
+ Calling, for example, TQWidget::setFont() doesn't take effect until
+ the next time a painter begins painting on it.
+
+ save() saves all of these settings on an internal stack, restore()
+ pops them back.
+
+ The core functionality of TQPainter is drawing, and there are
+ functions to draw most primitives: drawPoint(), drawPoints(),
+ drawLine(), drawRect(), drawWinFocusRect(), drawRoundRect(),
+ drawEllipse(), drawArc(), drawPie(), drawChord(),
+ drawLineSegments(), drawPolyline(), drawPolygon(),
+ drawConvexPolygon() and drawCubicBezier(). All of these functions
+ take integer coordinates; there are no floating-point versions
+ since we want drawing to be as fast as possible.
+
+ There are functions to draw pixmaps/images, namely drawPixmap(),
+ drawImage() and drawTiledPixmap(). drawPixmap() and drawImage()
+ produce the same result, except that drawPixmap() is faster
+ on-screen and drawImage() faster and sometimes better on TQPrinter
+ and TQPicture.
+
+ Text drawing is done using drawText(), and when you need
+ fine-grained positioning, boundingRect() tells you where a given
+ drawText() command would draw.
+
+ There is a drawPicture() function that draws the contents of an
+ entire TQPicture using this painter. drawPicture() is the only
+ function that disregards all the painter's settings: the TQPicture
+ has its own settings.
+
+ Normally, the TQPainter operates on the tqdevice's own coordinate
+ system (usually pixels), but TQPainter has good support for
+ coordinate transformation. See \link coordsys.html The Coordinate
+ System \endlink for a more general overview and a simple example.
+
+ The most common functions used are scale(), rotate(), translate()
+ and shear(), all of which operate on the tqworldMatrix().
+ setWorldMatrix() can tqreplace or add to the currently set
+ tqworldMatrix().
+
+ setViewport() sets the rectangle on which TQPainter operates. The
+ default is the entire tqdevice, which is usually fine, except on
+ printers. setWindow() sets the coordinate system, that is, the
+ rectangle that maps to viewport(). What's drawn inside the
+ window() ends up being inside the viewport(). The window's
+ default is the same as the viewport, and if you don't use the
+ transformations, they are optimized away, gaining another little
+ bit of speed.
+
+ After all the coordinate transformation is done, TQPainter can clip
+ the drawing to an arbitrary rectangle or region. hasClipping() is
+ TRUE if TQPainter clips, and clipRegion() returns the clip region.
+ You can set it using either setClipRegion() or setClipRect().
+ Note that the clipping can be slow. It's all system-dependent,
+ but as a rule of thumb, you can assume that drawing speed is
+ inversely proportional to the number of rectangles in the clip
+ region.
+
+ After TQPainter's clipping, the paint tqdevice may also clip. For
+ example, most widgets clip away the pixels used by child widgets,
+ and most printers clip away an area near the edges of the paper.
+ This additional clipping is not reflected by the return value of
+ clipRegion() or hasClipping().
+
+ TQPainter also includes some less-used functions that are very
+ useful on those occasions when they're needed.
+
+ isActive() indicates whether the painter is active. begin() (and
+ the most usual constructor) makes it active. end() (and the
+ destructor) deactivates it. If the painter is active, tqdevice()
+ returns the paint tqdevice on which the painter paints.
+
+ Sometimes it is desirable to make someone else paint on an unusual
+ TQPaintDevice. TQPainter supports a static function to do this,
+ redirect(). We recommend not using it, but for some hacks it's
+ perfect.
+
+ setTabStops() and setTabArray() can change where the tab stops
+ are, but these are very seldomly used.
+
+ \warning Note that TQPainter does not attempt to work around
+ coordinate limitations in the underlying window system. Some
+ platforms may behave incorrectly with coordinates as small as
+ +/-4000.
+
+ \headerfile tqdrawutil.h
+
+ \sa TQPaintDevice TQWidget TQPixmap TQPrinter TQPicture
+ \link simple-application.html Application Walkthrough \endlink
+ \link coordsys.html Coordinate System Overview \endlink
+*/
+
+/*!
+ \fn TQGfx * TQPainter::internalGfx()
+
+ \internal
+*/
+
+/*!
+ \enum TQPainter::CoordinateMode
+ \value CoordDevice
+ \value CoordPainter
+
+ \sa clipRegion()
+*/
+/*!
+ \enum TQPainter::TextDirection
+ \value Auto
+ \value RTL right to left
+ \value LTR left to right
+
+ \sa drawText()
+*/
+
+/*!
+ \enum TQt::PaintUnit
+ \value PixelUnit
+ \value LoMetricUnit \e obsolete
+ \value HiMetricUnit \e obsolete
+ \value LoEnglishUnit \e obsolete
+ \value HiEnglishUnit \e obsolete
+ \value TwipsUnit \e obsolete
+*/
+
+/*!
+ \enum TQt::BrushStyle
+
+ \value NoBrush
+ \value SolidPattern
+ \value Dense1Pattern
+ \value Dense2Pattern
+ \value Dense3Pattern
+ \value Dense4Pattern
+ \value Dense5Pattern
+ \value Dense6Pattern
+ \value Dense7Pattern
+ \value HorPattern
+ \value VerPattern
+ \value CrossPattern
+ \value BDiagPattern
+ \value FDiagPattern
+ \value DiagCrossPattern
+ \value CustomPattern
+
+ \img brush-styles.png Brush Styles
+
+*/
+
+/*!
+ \enum TQt::RasterOp
+
+ This enum type is used to describe the way things are written to
+ the paint tqdevice. Each bit of the \e src (what you write)
+ interacts with the corresponding bit of the \e dst pixel.
+
+ \value CopyROP dst = src
+ \value OrROP dst = src OR dst
+ \value XorROP dst = src XOR dst
+ \value NotAndROP dst = (NOT src) AND dst
+ \value EraseROP an alias for \c NotAndROP
+ \value NotCopyROP dst = NOT src
+ \value NotOrROP dst = (NOT src) OR dst
+ \value NotXorROP dst = (NOT src) XOR dst
+ \value AndROP dst = src AND dst
+ \value NotEraseROP an alias for \c AndROP
+ \value NotROP dst = NOT dst
+ \value ClearROP dst = 0
+ \value SetROP dst = 1
+ \value NopROP dst = dst
+ \value AndNotROP dst = src AND (NOT dst)
+ \value OrNotROP dst = src OR (NOT dst)
+ \value NandROP dst = NOT (src AND dst)
+ \value NorROP dst = NOT (src OR dst)
+
+ By far the most useful ones are \c CopyROP and \c XorROP.
+
+ On TQt/Embedded, only \c CopyROP, \c XorROP, and \c NotROP are supported.
+*/
+
+/*!
+ \enum TQt::AlignmentFlags
+
+ This enum type is used to describe tqalignment. It tqcontains
+ horizontal and vertical flags.
+
+ The horizontal flags are:
+
+ \value AlignAuto Aligns according to the language. Left for most,
+ right for Arabic and Hebrew.
+ \value AlignLeft Aligns with the left edge.
+ \value AlignRight Aligns with the right edge.
+ \value AlignHCenter Centers horizontally in the available space.
+ \value AlignJustify Justifies the text in the available space.
+ Does not work for everything and may be interpreted as
+ AlignAuto in some cases.
+
+ The vertical flags are:
+
+ \value AlignTop Aligns with the top.
+ \value AlignBottom Aligns with the bottom.
+ \value AlignVCenter Centers vertically in the available space.
+
+ You can use only one of the horizontal flags at a time. There is
+ one two-dimensional flag:
+
+ \value AlignCenter Centers in both dimensions.
+
+ You can use at most one horizontal and one vertical flag at a time. \c
+ AlignCenter counts as both horizontal and vertical.
+
+ Masks:
+
+ \value AlignHorizontal_Mask
+ \value AlignVertical_Mask
+
+ Conflicting combinations of flags have undefined meanings.
+*/
+
+/*!
+ \enum TQt::TextFlags
+
+ This enum type is used to define some modifier flags. Some of
+ these flags only make sense in the context of printing:
+
+ \value SingleLine Treats all whitespace as spaces and prints just
+ one line.
+ \value DontClip If it's impossible to stay within the given bounds,
+ it prints outside.
+ \value ExpandTabs Makes the U+0009 (ASCII tab) character move to
+ the next tab stop.
+ \value ShowPrefix Displays the string "\&P" as <u>P</u>
+ (see TQButton for an example). For an ampersand, use "\&\&".
+ \value WordBreak Breaks lines at appropriate points, e.g. at word
+ boundaries.
+ \value BreakAnywhere Breaks lines anywhere, even within words.
+ \value NoAccel Same as ShowPrefix but doesn't draw the underlines.
+
+ You can use as many modifier flags as you want, except that \c
+ SingleLine and \c WordBreak cannot be combined.
+
+ Flags that are inappropriate for a given use (e.g. ShowPrefix to
+ TQGridLayout::addWidget()) are generally ignored.
+
+*/
+
+/*!
+ \enum TQt::PenStyle
+
+ This enum type defines the pen styles that can be drawn using
+ TQPainter. The styles are
+
+ \value NoPen no line at all. For example, TQPainter::drawRect()
+ fills but does not draw any boundary line.
+
+ \value SolidLine a simple line.
+
+ \value DashLine dashes separated by a few pixels.
+
+ \value DotLine dots separated by a few pixels.
+
+ \value DashDotLine alternate dots and dashes.
+
+ \value DashDotDotLine one dash, two dots, one dash, two dots.
+
+ \value MPenStyle tqmask of the pen styles.
+
+ \img pen-styles.png Pen Styles
+*/
+
+/*!
+ \enum TQt::PenCapStyle
+
+ This enum type defines the pen cap styles supported by TQt, i.e.
+ the line end caps that can be drawn using TQPainter.
+
+ \value FlatCap a square line end that does not cover the end
+ point of the line.
+ \value SquareCap a square line end that covers the end point and
+ extends beyond it with half the line width.
+ \value RoundCap a rounded line end.
+ \value MPenCapStyle tqmask of the pen cap styles.
+
+ \img pen-cap-styles.png Pen Cap Styles
+*/
+
+/*!
+ \enum TQt::PenJoinStyle
+
+ This enum type defines the pen join styles supported by TQt, i.e.
+ which joins between two connected lines can be drawn using
+ TQPainter.
+
+ \value MiterJoin The outer edges of the lines are extended to
+ meet at an angle, and this area is filled.
+ \value BevelJoin The triangular notch between the two lines is filled.
+ \value RoundJoin A circular arc between the two lines is filled.
+ \value MPenJoinStyle tqmask of the pen join styles.
+
+ \img pen-join-styles.png Pen Join Styles
+*/
+
+/*!
+ \enum TQt::BGMode
+
+ Background mode
+
+ \value TransparentMode
+ \value OpaqueMode
+*/
+
+/*!
+ Constructs a painter.
+
+ Notice that all painter settings (setPen, setBrush etc.) are reset
+ to default values when begin() is called.
+
+ \sa begin(), end()
+*/
+
+TQPainter::TQPainter()
+{
+ init();
+}
+
+
+/*!
+ Constructs a painter that begins painting the paint tqdevice \a pd
+ immediately. Depending on the underlying graphic system the
+ painter will paint over tqchildren of the painttqdevice if \a
+ unclipped is TRUE.
+
+ This constructor is convenient for short-lived painters, e.g. in a
+ \link TQWidget::paintEvent() paint event\endlink and should be used
+ only once. The constructor calls begin() for you and the TQPainter
+ destructor automatically calls end().
+
+ Here's an example using begin() and end():
+ \code
+ void MyWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPainter p;
+ p.begin( this );
+ p.drawLine( ... ); // drawing code
+ p.end();
+ }
+ \endcode
+
+ The same example using this constructor:
+ \code
+ void MyWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPainter p( this );
+ p.drawLine( ... ); // drawing code
+ }
+ \endcode
+
+ Since the constructor cannot provide feedback when the initialization
+ of the painter failed you should rather use begin() and end() to paint
+ on external tqdevices, e.g. printers.
+
+ \sa begin(), end()
+*/
+
+TQPainter::TQPainter( const TQPaintDevice *pd, bool unclipped )
+{
+ init();
+ if ( begin( pd, unclipped ) )
+ flags |= CtorBegin;
+}
+
+
+/*!
+ Constructs a painter that begins painting the paint tqdevice \a pd
+ immediately, with the default arguments taken from \a
+ copyAttributes. The painter will paint over tqchildren of the paint
+ tqdevice if \a unclipped is TRUE (although this is not supported on
+ all platforms).
+
+ \sa begin()
+*/
+
+TQPainter::TQPainter( const TQPaintDevice *pd,
+ const TQWidget *copyAttributes, bool unclipped )
+{
+ init();
+ if ( begin( pd, copyAttributes, unclipped ) )
+ flags |= CtorBegin;
+}
+
+
+/*!
+ Destroys the painter.
+*/
+
+TQPainter::~TQPainter()
+{
+ if ( isActive() )
+ end();
+ else
+ killPStack();
+ if ( tabarray ) // delete tab array
+ delete [] tabarray;
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( wm_stack )
+ delete (TQWMatrixStack *)wm_stack;
+#endif
+ destroy();
+}
+
+
+/*!
+ \overload bool TQPainter::begin( const TQPaintDevice *pd, const TQWidget *copyAttributes, bool unclipped )
+
+ This version opens the painter on a paint tqdevice \a pd and sets
+ the initial pen, background color and font from \a copyAttributes,
+ painting over the paint tqdevice's tqchildren when \a unclipped is
+ TRUE. This is equivalent to:
+
+ \code
+ TQPainter p;
+ p.begin( pd );
+ p.setPen( copyAttributes->foregroundColor() );
+ p.setBackgroundColor( copyAttributes->backgroundColor() );
+ p.setFont( copyAttributes->font() );
+ \endcode
+
+ This begin function is convenient for double buffering. When you
+ draw in a pixmap instead of directly in a widget (to later bitBlt
+ the pixmap into the widget) you will need to set the widget's
+ font etc. This function does exactly that.
+
+ Example:
+ \code
+ void MyWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPixmap pm(size());
+ TQPainter p;
+ p.begin(&pm, this);
+ // ... potentially flickering paint operation ...
+ p.end();
+ bitBlt(this, 0, 0, &pm);
+ }
+ \endcode
+
+ \sa end()
+*/
+
+bool TQPainter::begin( const TQPaintDevice *pd, const TQWidget *copyAttributes, bool unclipped )
+{
+ if ( copyAttributes == 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQPainter::begin: The widget to copy attributes from cannot "
+ "be null" );
+#endif
+ return FALSE;
+ }
+ if ( begin( pd, unclipped ) ) {
+ setPen( copyAttributes->foregroundColor() );
+ setBackgroundColor( copyAttributes->backgroundColor() );
+ setFont( copyAttributes->font() );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*!
+ \internal
+ Sets or clears a pointer flag.
+*/
+
+void TQPainter::setf( uint b, bool v )
+{
+ if ( v )
+ setf( b );
+ else
+ clearf( b );
+}
+
+
+/*!
+ \fn bool TQPainter::isActive() const
+
+ Returns TRUE if the painter is active painting, i.e. begin() has
+ been called and end() has not yet been called; otherwise returns
+ FALSE.
+
+ \sa TQPaintDevice::paintingActive()
+*/
+
+/*!
+ \fn TQPaintDevice *TQPainter::tqdevice() const
+
+ Returns the paint tqdevice on which this painter is currently
+ painting, or 0 if the painter is not active.
+
+ \sa TQPaintDevice::paintingActive()
+*/
+
+
+struct TQPState { // painter state
+ TQFont font;
+ TQPen pen;
+ TQPoint curPt;
+ TQBrush brush;
+ TQColor bgc;
+ uchar bgm;
+ uchar rop;
+ TQPoint bro;
+ TQRect wr, vr;
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix wm;
+#else
+ int xlatex;
+ int xlatey;
+#endif
+ bool vxf;
+ bool wxf;
+ TQRegion rgn;
+ bool clip;
+ int ts;
+ int *ta;
+ void* wm_stack;
+};
+
+//TODO lose the worldmatrix stack
+
+typedef TQPtrStack<TQPState> TQPStateStack;
+
+
+void TQPainter::killPStack()
+{
+#if defined(TQT_CHECK_STATE)
+ if ( ps_stack && !((TQPStateStack *)ps_stack)->isEmpty() )
+ qWarning( "TQPainter::killPStack: non-empty save/restore stack when "
+ "end() was called" );
+#endif
+ delete (TQPStateStack *)ps_stack;
+ ps_stack = 0;
+}
+
+/*!
+ Saves the current painter state (pushes the state onto a stack). A
+ save() must be followed by a corresponding restore(). end()
+ unwinds the stack.
+
+ \sa restore()
+*/
+
+void TQPainter::save()
+{
+ if ( testf(ExtDev) ) {
+ if ( testf(DirtyFont) )
+ updateFont();
+ if ( testf(DirtyPen) )
+ updatePen();
+ if ( testf(DirtyBrush) )
+ updateBrush();
+ pdev->cmd( TQPaintDevice::PdcSave, this, 0 );
+ }
+ TQPStateStack *pss = (TQPStateStack *)ps_stack;
+ if ( pss == 0 ) {
+ pss = new TQPtrStack<TQPState>;
+ TQ_CHECK_PTR( pss );
+ pss->setAutoDelete( TRUE );
+ ps_stack = pss;
+ }
+ TQPState *ps = new TQPState;
+ TQ_CHECK_PTR( ps );
+ ps->font = cfont;
+ ps->pen = cpen;
+ ps->curPt = pos();
+ ps->brush = cbrush;
+ ps->bgc = bg_col;
+ ps->bgm = bg_mode;
+ ps->rop = rop;
+ ps->bro = bro;
+#ifndef TQT_NO_TRANSFORMATIONS
+ ps->wr = TQRect( wx, wy, ww, wh );
+ ps->vr = TQRect( vx, vy, vw, vh );
+ ps->wm = wxmat;
+ ps->vxf = testf(VxF);
+ ps->wxf = testf(WxF);
+#else
+ ps->xlatex = xlatex;
+ ps->xlatey = xlatey;
+#endif
+ ps->rgn = crgn;
+ ps->clip = testf(ClipOn);
+ ps->ts = tabstops;
+ ps->ta = tabarray;
+ ps->wm_stack = wm_stack;
+ wm_stack = 0;
+ pss->push( ps );
+}
+
+/*!
+ Restores the current painter state (pops a saved state off the
+ stack).
+
+ \sa save()
+*/
+
+void TQPainter::restore()
+{
+ if ( testf(ExtDev) ) {
+ pdev->cmd( TQPaintDevice::PdcRestore, this, 0 );
+ if ( pdev->devType() == TQInternal::Picture )
+ block_ext = TRUE;
+ }
+ TQPStateStack *pss = (TQPStateStack *)ps_stack;
+ if ( pss == 0 || pss->isEmpty() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::restore: Empty stack error" );
+#endif
+ return;
+ }
+ TQPState *ps = pss->pop();
+ bool hardRestore = testf(VolatileDC);
+
+ if ( ps->font != cfont || hardRestore )
+ setFont( ps->font );
+ if ( ps->pen != cpen || hardRestore )
+ setPen( ps->pen );
+ if ( ps->brush != cbrush || hardRestore )
+ setBrush( ps->brush );
+ if ( ps->bgc != bg_col || hardRestore )
+ setBackgroundColor( ps->bgc );
+ if ( ps->bgm != bg_mode || hardRestore )
+ setBackgroundMode( (BGMode)ps->bgm );
+ if ( ps->rop != rop || hardRestore )
+ setRasterOp( (RasterOp)ps->rop );
+ if ( ps->bro != bro || hardRestore )
+ setBrushOrigin( ps->bro );
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQRect wr( wx, wy, ww, wh );
+ TQRect vr( vx, vy, vw, vh );
+ if ( ps->wr != wr || hardRestore )
+ setWindow( ps->wr );
+ if ( ps->vr != vr || hardRestore )
+ setViewport( ps->vr );
+ if ( ps->wm != wxmat || hardRestore )
+ setWorldMatrix( ps->wm );
+ if ( ps->vxf != testf(VxF) || hardRestore )
+ setViewXForm( ps->vxf );
+ if ( ps->wxf != testf(WxF) || hardRestore )
+ setWorldXForm( ps->wxf );
+#else
+ xlatex = ps->xlatex;
+ xlatey = ps->xlatey;
+ setf( VxF, xlatex || xlatey );
+#endif
+ if ( ps->curPt != pos() || hardRestore )
+ moveTo( ps->curPt );
+ if ( ps->rgn != crgn || hardRestore )
+ setClipRegion( ps->rgn );
+ if ( ps->clip != testf(ClipOn) || hardRestore )
+ setClipping( ps->clip );
+ tabstops = ps->ts;
+ tabarray = ps->ta;
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( wm_stack )
+ delete (TQWMatrixStack *)wm_stack;
+ wm_stack = ps->wm_stack;
+#endif
+ delete ps;
+ block_ext = FALSE;
+}
+
+typedef TQPtrDict<TQPaintDevice> TQPaintDeviceDict;
+static TQPaintDeviceDict *pdev_dict = 0;
+
+/*!
+ Redirects all paint commands for a paint tqdevice, \a pdev, to
+ another paint tqdevice, \a tqreplacement, unless \a tqreplacement is 0.
+ If \a tqreplacement is 0, the redirection for \a pdev is removed.
+
+ In general, you'll probably tqfind calling TQPixmap::grabWidget() or
+ TQPixmap::grabWindow() is an easier solution.
+*/
+
+void TQPainter::redirect( TQPaintDevice *pdev, TQPaintDevice *tqreplacement )
+{
+ if ( pdev_dict == 0 ) {
+ if ( tqreplacement == 0 )
+ return;
+ pdev_dict = new TQPaintDeviceDict;
+ TQ_CHECK_PTR( pdev_dict );
+ }
+#if defined(TQT_CHECK_NULL)
+ if ( pdev == 0 )
+ qWarning( "TQPainter::redirect: The pdev argument cannot be 0" );
+#endif
+ if ( tqreplacement ) {
+ pdev_dict->insert( pdev, tqreplacement );
+ } else {
+ pdev_dict->remove( pdev );
+ if ( pdev_dict->count() == 0 ) {
+ delete pdev_dict;
+ pdev_dict = 0;
+ }
+ }
+}
+
+/*!
+ \internal
+ Returns the tqreplacement for \a pdev, or 0 if there is no tqreplacement.
+*/
+TQPaintDevice *TQPainter::redirect( TQPaintDevice *pdev )
+{
+ return pdev_dict ? pdev_dict->tqfind( pdev ) : 0;
+}
+
+/*!
+ Returns the font metrics for the painter, if the painter is
+ active. It is not possible to obtain metrics for an inactive
+ painter, so the return value is undefined if the painter is not
+ active.
+
+ \sa fontInfo(), isActive()
+*/
+
+TQFontMetrics TQPainter::fontMetrics() const
+{
+ if ( pdev && pdev->devType() == TQInternal::Picture )
+ return TQFontMetrics( cfont );
+
+ return TQFontMetrics(this);
+}
+
+/*!
+ Returns the font info for the painter, if the painter is active.
+ It is not possible to obtain font information for an inactive
+ painter, so the return value is undefined if the painter is not
+ active.
+
+ \sa fontMetrics(), isActive()
+*/
+
+TQFontInfo TQPainter::fontInfo() const
+{
+ if ( pdev && pdev->devType() == TQInternal::Picture )
+ return TQFontInfo( cfont );
+
+ return TQFontInfo(this);
+}
+
+
+/*!
+ \fn const TQPen &TQPainter::pen() const
+
+ Returns the painter's current pen.
+
+ \sa setPen()
+*/
+
+/*!
+ Sets a new painter pen.
+
+ The \a pen defines how to draw lines and outlines, and it also
+ defines the text color.
+
+ \sa pen()
+*/
+
+void TQPainter::setPen( const TQPen &pen )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setPen: Will be reset by begin()" );
+#endif
+ if ( cpen == pen )
+ return;
+ cpen = pen;
+ updatePen();
+}
+
+/*!
+ \overload
+
+ Sets the painter's pen to have style \a style, width 0 and black
+ color.
+
+ \sa pen(), TQPen
+*/
+
+void TQPainter::setPen( PenStyle style )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setPen: Will be reset by begin()" );
+#endif
+ TQPen::TQPenData *d = cpen.data; // low level access
+ if ( d->style == style && d->linest == style && !d->width && d->color == TQt::black )
+ return;
+ if ( d->count != 1 ) {
+ cpen.detach();
+ d = cpen.data;
+ }
+ d->style = style;
+ d->width = 0;
+ d->color = TQt::black;
+ d->linest = style;
+ updatePen();
+}
+
+/*!
+ \overload
+
+ Sets the painter's pen to have style \c SolidLine, width 0 and the
+ specified \a color.
+
+ \sa pen(), TQPen
+*/
+
+void TQPainter::setPen( const TQColor &color )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setPen: Will be reset by begin()" );
+#endif
+ TQPen::TQPenData *d = cpen.data; // low level access
+ if ( d->color == color && !d->width && d->style == SolidLine && d->linest == SolidLine )
+ return;
+ if ( d->count != 1 ) {
+ cpen.detach();
+ d = cpen.data;
+ }
+ d->style = SolidLine;
+ d->width = 0;
+ d->color = color;
+ d->linest = SolidLine;
+ updatePen();
+}
+
+/*!
+ \fn const TQBrush &TQPainter::brush() const
+
+ Returns the painter's current brush.
+
+ \sa TQPainter::setBrush()
+*/
+
+/*!
+ \overload
+
+ Sets the painter's brush to \a brush.
+
+ The \a brush defines how tqshapes are filled.
+
+ \sa brush()
+*/
+
+void TQPainter::setBrush( const TQBrush &brush )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setBrush: Will be reset by begin()" );
+#endif
+ if ( cbrush == brush )
+ return;
+ cbrush = brush;
+ updateBrush();
+}
+
+/*!
+ Sets the painter's brush to black color and the specified \a
+ style.
+
+ \sa brush(), TQBrush
+*/
+
+void TQPainter::setBrush( BrushStyle style )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setBrush: Will be reset by begin()" );
+#endif
+ TQBrush::TQBrushData *d = cbrush.data; // low level access
+ if ( d->style == style && d->color == TQt::black && !d->pixmap )
+ return;
+ if ( d->count != 1 ) {
+ cbrush.detach();
+ d = cbrush.data;
+ }
+ d->style = style;
+ d->color = TQt::black;
+ if ( d->pixmap ) {
+ delete d->pixmap;
+ d->pixmap = 0;
+ }
+ updateBrush();
+}
+
+/*!
+ \overload
+
+ Sets the painter's brush to have style \c SolidPattern and the
+ specified \a color.
+
+ \sa brush(), TQBrush
+*/
+
+void TQPainter::setBrush( const TQColor &color )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setBrush: Will be reset by begin()" );
+#endif
+ TQBrush::TQBrushData *d = cbrush.data; // low level access
+ if ( d->color == color && d->style == SolidPattern && !d->pixmap )
+ return;
+ if ( d->count != 1 ) {
+ cbrush.detach();
+ d = cbrush.data;
+ }
+ d->style = SolidPattern;
+ d->color = color;
+ if ( d->pixmap ) {
+ delete d->pixmap;
+ d->pixmap = 0;
+ }
+ updateBrush();
+}
+
+
+/*!
+ \fn const TQColor &TQPainter::backgroundColor() const
+
+ Returns the current background color.
+
+ \sa setBackgroundColor() TQColor
+*/
+
+/*!
+ \fn BGMode TQPainter::backgroundMode() const
+
+ Returns the current background mode.
+
+ \sa setBackgroundMode() BGMode
+*/
+
+/*!
+ \fn RasterOp TQPainter::rasterOp() const
+
+ Returns the current \link TQt::RasterOp raster operation \endlink.
+
+ \sa setRasterOp() RasterOp
+*/
+
+/*!
+ \fn const TQPoint &TQPainter::brushOrigin() const
+
+ Returns the brush origin currently set.
+
+ \sa setBrushOrigin()
+*/
+
+
+/*!
+ \fn int TQPainter::tabStops() const
+
+ Returns the tab stop setting.
+
+ \sa setTabStops()
+*/
+
+/*!
+ Set the tab stop width to \a ts, i.e. locates tab stops at \a ts,
+ 2*\a ts, 3*\a ts and so on.
+
+ Tab stops are used when drawing formatted text with \c ExpandTabs
+ set. This fixed tab stop value is used only if no tab array is set
+ (which is the default case).
+
+ A value of 0 (the default) implies a tabstop setting of 8 times the width of the
+ character 'x' in the font currently set on the painter.
+
+ \sa tabStops(), setTabArray(), drawText(), fontMetrics()
+*/
+
+void TQPainter::setTabStops( int ts )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setTabStops: Will be reset by begin()" );
+#endif
+ tabstops = ts;
+ if ( isActive() && testf(ExtDev) ) { // tell extended tqdevice
+ TQPDevCmdParam param[1];
+ param[0].ival = ts;
+ pdev->cmd( TQPaintDevice::PdcSetTabStops, this, param );
+ }
+}
+
+/*!
+ \fn int *TQPainter::tabArray() const
+
+ Returns the currently set tab stop array.
+
+ \sa setTabArray()
+*/
+
+/*!
+ Sets the tab stop array to \a ta. This puts tab stops at \a ta[0],
+ \a ta[1] and so on. The array is null-terminated.
+
+ If both a tab array and a tab top size is set, the tab array wins.
+
+ \sa tabArray(), setTabStops(), drawText(), fontMetrics()
+*/
+
+void TQPainter::setTabArray( int *ta )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setTabArray: Will be reset by begin()" );
+#endif
+ if ( ta != tabarray ) {
+ tabarraylen = 0;
+ if ( tabarray ) // Avoid purify complaint
+ delete [] tabarray; // delete old array
+ if ( ta ) { // tabarray = copy of 'ta'
+ while ( ta[tabarraylen] )
+ tabarraylen++;
+ tabarraylen++; // and 0 terminator
+ tabarray = new int[tabarraylen]; // duplicate ta
+ memcpy( tabarray, ta, sizeof(int)*tabarraylen );
+ } else {
+ tabarray = 0;
+ }
+ }
+ if ( isActive() && testf(ExtDev) ) { // tell extended tqdevice
+ TQPDevCmdParam param[2];
+ param[0].ival = tabarraylen;
+ param[1].ivec = tabarray;
+ pdev->cmd( TQPaintDevice::PdcSetTabArray, this, param );
+ }
+}
+
+
+/*!
+ \fn HANDLE TQPainter::handle() const
+
+ Returns the platform-dependent handle used for drawing. Using this
+ function is not portable.
+*/
+
+
+/*****************************************************************************
+ TQPainter xform settings
+ *****************************************************************************/
+
+#ifndef TQT_NO_TRANSFORMATIONS
+
+/*!
+ Enables view transformations if \a enable is TRUE, or disables
+ view transformations if \a enable is FALSE.
+
+ \sa hasViewXForm(), setWindow(), setViewport(), setWorldMatrix(),
+ setWorldXForm(), xForm()
+*/
+
+void TQPainter::setViewXForm( bool enable )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setViewXForm: Will be reset by begin()" );
+#endif
+ if ( !isActive() || enable == testf(VxF) )
+ return;
+ setf( VxF, enable );
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ param[0].ival = enable;
+ pdev->cmd( TQPaintDevice::PdcSetVXform, this, param );
+ }
+ updateXForm();
+}
+
+/*!
+ \fn bool TQPainter::hasViewXForm() const
+
+ Returns TRUE if view transformation is enabled; otherwise returns
+ FALSE.
+
+ \sa setViewXForm(), xForm()
+*/
+
+/*!
+ Returns the window rectangle.
+
+ \sa setWindow(), setViewXForm()
+*/
+
+TQRect TQPainter::window() const
+{
+ return TQRect( wx, wy, ww, wh );
+}
+
+/*!
+ Sets the window rectangle view transformation for the painter and
+ enables view transformation.
+
+ The window rectangle is part of the view transformation. The
+ window specifies the logical coordinate system and is specified by
+ the \a x, \a y, \a w width and \a h height parameters. Its sister,
+ the viewport(), specifies the tqdevice coordinate system.
+
+ The default window rectangle is the same as the tqdevice's
+ rectangle. See the \link coordsys.html Coordinate System Overview
+ \endlink for an overview of coordinate transformation.
+
+ \sa window(), setViewport(), setViewXForm(), setWorldMatrix(),
+ setWorldXForm()
+*/
+
+void TQPainter::setWindow( int x, int y, int w, int h )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setWindow: Will be reset by begin()" );
+#endif
+ wx = x;
+ wy = y;
+ ww = w;
+ wh = h;
+ if ( testf(ExtDev) ) {
+ TQRect r( x, y, w, h );
+ TQPDevCmdParam param[1];
+ param[0].rect = (TQRect*)&r;
+ pdev->cmd( TQPaintDevice::PdcSetWindow, this, param );
+ }
+ if ( testf(VxF) )
+ updateXForm();
+ else
+ setViewXForm( TRUE );
+}
+
+/*!
+ Returns the viewport rectangle.
+
+ \sa setViewport(), setViewXForm()
+*/
+
+TQRect TQPainter::viewport() const // get viewport
+{
+ return TQRect( vx, vy, vw, vh );
+}
+
+/*!
+ Sets the viewport rectangle view transformation for the painter
+ and enables view transformation.
+
+ The viewport rectangle is part of the view transformation. The
+ viewport specifies the tqdevice coordinate system and is specified
+ by the \a x, \a y, \a w width and \a h height parameters. Its
+ sister, the window(), specifies the logical coordinate system.
+
+ The default viewport rectangle is the same as the tqdevice's
+ rectangle. See the \link coordsys.html Coordinate System Overview
+ \endlink for an overview of coordinate transformation.
+
+ \sa viewport(), setWindow(), setViewXForm(), setWorldMatrix(),
+ setWorldXForm(), xForm()
+*/
+
+void TQPainter::setViewport( int x, int y, int w, int h )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setViewport: Will be reset by begin()" );
+#endif
+ vx = x;
+ vy = y;
+ vw = w;
+ vh = h;
+ if ( testf(ExtDev) ) {
+ TQRect r( x, y, w, h );
+ TQPDevCmdParam param[1];
+ param[0].rect = (TQRect*)&r;
+ pdev->cmd( TQPaintDevice::PdcSetViewport, this, param );
+ }
+ if ( testf(VxF) )
+ updateXForm();
+ else
+ setViewXForm( TRUE );
+}
+
+
+/*!
+ Enables world transformations if \a enable is TRUE, or disables
+ world transformations if \a enable is FALSE. The world
+ transformation matrix is not changed.
+
+ \sa setWorldMatrix(), setWindow(), setViewport(), setViewXForm(),
+ xForm()
+*/
+
+void TQPainter::setWorldXForm( bool enable )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setWorldXForm: Will be reset by begin()" );
+#endif
+ if ( !isActive() || enable == testf(WxF) )
+ return;
+ setf( WxF, enable );
+ if ( testf(ExtDev) && !block_ext ) {
+ TQPDevCmdParam param[1];
+ param[0].ival = enable;
+ pdev->cmd( TQPaintDevice::PdcSetWXform, this, param );
+ }
+ updateXForm();
+}
+
+/*!
+ \fn bool TQPainter::hasWorldXForm() const
+
+ Returns TRUE if world transformation is enabled; otherwise returns
+ FALSE.
+
+ \sa setWorldXForm()
+*/
+
+/*!
+ Returns the world transformation matrix.
+
+ \sa setWorldMatrix()
+*/
+
+const TQWMatrix &TQPainter::tqworldMatrix() const
+{
+ return wxmat;
+}
+
+/*!
+ Sets the world transformation matrix to \a m and enables world
+ transformation.
+
+ If \a combine is TRUE, then \a m is combined with the current
+ transformation matrix, otherwise \a m tqreplaces the current
+ transformation matrix.
+
+ If \a m is the identity matrix and \a combine is FALSE, this
+ function calls setWorldXForm(FALSE). (The identity matrix is the
+ matrix where TQWMatrix::m11() and TQWMatrix::m22() are 1.0 and the
+ rest are 0.0.)
+
+ World transformations are applied after the view transformations
+ (i.e. \link setWindow() window\endlink and \link setViewport()
+ viewport\endlink).
+
+ The following functions can transform the coordinate system without using
+ a TQWMatrix:
+ \list
+ \i translate()
+ \i scale()
+ \i shear()
+ \i rotate()
+ \endlist
+
+ They operate on the painter's tqworldMatrix() and are implemented like this:
+
+ \code
+ void TQPainter::rotate( double a )
+ {
+ TQWMatrix m;
+ m.rotate( a );
+ setWorldMatrix( m, TRUE );
+ }
+ \endcode
+
+ Note that you should always use \a combine when you are drawing
+ into a TQPicture. Otherwise it may not be possible to replay the
+ picture with additional transformations. Using translate(),
+ scale(), etc., is safe.
+
+ For a brief overview of coordinate transformation, see the \link
+ coordsys.html Coordinate System Overview. \endlink
+
+ \sa tqworldMatrix() setWorldXForm() setWindow() setViewport()
+ setViewXForm() xForm() TQWMatrix
+*/
+
+void TQPainter::setWorldMatrix( const TQWMatrix &m, bool combine )
+{
+ if ( !isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::setWorldMatrix: Will be reset by begin()" );
+#endif
+ return;
+ }
+ if ( combine )
+ wxmat = m * wxmat; // combines
+ else
+ wxmat = m; // set new matrix
+ bool identity = wxmat.m11() == 1.0F && wxmat.m22() == 1.0F &&
+ wxmat.m12() == 0.0F && wxmat.m21() == 0.0F &&
+ wxmat.dx() == 0.0F && wxmat.dy() == 0.0F;
+ if ( testf(ExtDev) && !block_ext ) {
+ TQPDevCmdParam param[2];
+ param[0].matrix = &m;
+ param[1].ival = combine;
+ pdev->cmd( TQPaintDevice::PdcSetWMatrix, this, param );
+ }
+ if ( identity && pdev->devType() != TQInternal::Picture )
+ setWorldXForm( FALSE );
+ else if ( !testf(WxF) )
+ setWorldXForm( TRUE );
+ else
+ updateXForm();
+}
+
+/*! \obsolete
+
+ We recommend using save() instead.
+*/
+
+void TQPainter::saveWorldMatrix()
+{
+ TQWMatrixStack *stack = (TQWMatrixStack *)wm_stack;
+ if ( stack == 0 ) {
+ stack = new TQPtrStack<TQWMatrix>;
+ TQ_CHECK_PTR( stack );
+ stack->setAutoDelete( TRUE );
+ wm_stack = stack;
+ }
+
+ stack->push( new TQWMatrix( wxmat ) );
+
+}
+
+/*! \obsolete
+ We recommend using restore() instead.
+*/
+
+void TQPainter::restoreWorldMatrix()
+{
+ TQWMatrixStack *stack = (TQWMatrixStack *)wm_stack;
+ if ( stack == 0 || stack->isEmpty() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::restoreWorldMatrix: Empty stack error" );
+#endif
+ return;
+ }
+ TQWMatrix* m = stack->pop();
+ setWorldMatrix( *m );
+ delete m;
+}
+
+#endif // TQT_NO_TRANSFORMATIONS
+
+/*!
+ Translates the coordinate system by \a (dx, dy). After this call,
+ \a (dx, dy) is added to points.
+
+ For example, the following code draws the same point twice:
+ \code
+ void MyWidget::paintEvent()
+ {
+ TQPainter paint( this );
+
+ paint.drawPoint( 0, 0 );
+
+ paint.translate( 100.0, 40.0 );
+ paint.drawPoint( -100, -40 );
+ }
+ \endcode
+
+ \sa scale(), shear(), rotate(), resetXForm(), setWorldMatrix(), xForm()
+*/
+
+void TQPainter::translate( double dx, double dy )
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix m;
+ m.translate( dx, dy );
+ setWorldMatrix( m, TRUE );
+#else
+ xlatex += (int)dx;
+ xlatey += (int)dy;
+ setf( VxF, xlatex || xlatey );
+#endif
+}
+
+
+#ifndef TQT_NO_TRANSFORMATIONS
+/*!
+ Scales the coordinate system by \a (sx, sy).
+
+ \sa translate(), shear(), rotate(), resetXForm(), setWorldMatrix(),
+ xForm()
+*/
+
+void TQPainter::scale( double sx, double sy )
+{
+ TQWMatrix m;
+ m.scale( sx, sy );
+ setWorldMatrix( m, TRUE );
+}
+
+/*!
+ Shears the coordinate system by \a (sh, sv).
+
+ \sa translate(), scale(), rotate(), resetXForm(), setWorldMatrix(),
+ xForm()
+*/
+
+void TQPainter::shear( double sh, double sv )
+{
+ TQWMatrix m;
+ m.shear( sv, sh );
+ setWorldMatrix( m, TRUE );
+}
+
+/*!
+ Rotates the coordinate system \a a degrees counterclockwise.
+
+ \sa translate(), scale(), shear(), resetXForm(), setWorldMatrix(),
+ xForm()
+*/
+
+void TQPainter::rotate( double a )
+{
+ TQWMatrix m;
+ m.rotate( a );
+ setWorldMatrix( m, TRUE );
+}
+
+
+/*!
+ Resets any transformations that were made using translate(), scale(),
+ shear(), rotate(), setWorldMatrix(), setViewport() and
+ setWindow().
+
+ \sa tqworldMatrix(), viewport(), window()
+*/
+
+void TQPainter::resetXForm()
+{
+ if ( !isActive() )
+ return;
+ wx = wy = vx = vy = 0; // default view origins
+ ww = vw = pdev->metric( TQPaintDeviceMetrics::PdmWidth );
+ wh = vh = pdev->metric( TQPaintDeviceMetrics::PdmHeight );
+ wxmat = TQWMatrix();
+ setWorldXForm( FALSE );
+ setViewXForm( FALSE );
+}
+
+/*!
+ \internal
+ Updates an internal integer transformation matrix.
+*/
+
+void TQPainter::updateXForm()
+{
+ TQWMatrix m;
+ if ( testf(VxF) ) {
+ double scaleW = (double)vw/(double)ww;
+ double scaleH = (double)vh/(double)wh;
+ m.setMatrix( scaleW, 0, 0, scaleH, vx - wx*scaleW, vy - wy*scaleH );
+ }
+ if ( testf(WxF) ) {
+ if ( testf(VxF) )
+ m = wxmat * m;
+ else
+ m = wxmat;
+ }
+ xmat = m;
+
+ txinv = FALSE; // no inverted matrix
+ txop = TxNone;
+ if ( m12()==0.0 && m21()==0.0 && m11() >= 0.0 && m22() >= 0.0 ) {
+ if ( m11()==1.0 && m22()==1.0 ) {
+ if ( dx()!=0.0 || dy()!=0.0 )
+ txop = TxTranslate;
+ } else {
+ txop = TxScale;
+#if defined(TQ_WS_WIN)
+ setf(DirtyFont);
+#endif
+ }
+ } else {
+ txop = TxRotShear;
+#if defined(TQ_WS_WIN)
+ setf(DirtyFont);
+#endif
+ }
+}
+
+
+/*!
+ \internal
+ Updates an internal integer inverse transformation matrix.
+*/
+
+void TQPainter::updateInvXForm()
+{
+#if defined(TQT_CHECK_STATE)
+ TQ_ASSERT( txinv == FALSE );
+#endif
+ txinv = TRUE; // creating inverted matrix
+ bool invertible;
+ TQWMatrix m;
+ if ( testf(VxF) ) {
+ m.translate( vx, vy );
+ m.scale( 1.0*vw/ww, 1.0*vh/wh );
+ m.translate( -wx, -wy );
+ }
+ if ( testf(WxF) ) {
+ if ( testf(VxF) )
+ m = wxmat * m;
+ else
+ m = wxmat;
+ }
+ ixmat = m.invert( &invertible ); // invert matrix
+}
+
+#else
+void TQPainter::resetXForm()
+{
+ xlatex = 0;
+ xlatey = 0;
+ clearf( VxF );
+}
+#endif // TQT_NO_TRANSFORMATIONS
+
+
+extern bool qt_old_transformations;
+
+/*!
+ \internal
+ Maps a point from logical coordinates to tqdevice coordinates.
+*/
+
+void TQPainter::map( int x, int y, int *rx, int *ry ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( qt_old_transformations ) {
+ switch ( txop ) {
+ case TxNone:
+ *rx = x; *ry = y;
+ break;
+ case TxTranslate:
+ // #### "Why no rounding here?", Warwick asked of Haavard.
+ *rx = int(x + dx());
+ *ry = int(y + dy());
+ break;
+ case TxScale: {
+ double tx = m11()*x + dx();
+ double ty = m22()*y + dy();
+ *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
+ *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
+ } break;
+ default: {
+ double tx = m11()*x + m21()*y+dx();
+ double ty = m12()*x + m22()*y+dy();
+ *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
+ *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
+ } break;
+ }
+ } else {
+ switch ( txop ) {
+ case TxNone:
+ *rx = x;
+ *ry = y;
+ break;
+ case TxTranslate:
+ *rx = tqRound( x + dx() );
+ *ry = tqRound( y + dy() );
+ break;
+ case TxScale:
+ *rx = tqRound( m11()*x + dx() );
+ *ry = tqRound( m22()*y + dy() );
+ break;
+ default:
+ *rx = tqRound( m11()*x + m21()*y+dx() );
+ *ry = tqRound( m12()*x + m22()*y+dy() );
+ break;
+ }
+ }
+#else
+ *rx = x + xlatex;
+ *ry = y + xlatey;
+#endif
+}
+
+/*!
+ \internal
+ Maps a rectangle from logical coordinates to tqdevice coordinates.
+ This internal function does not handle rotation and/or shear.
+*/
+
+void TQPainter::map( int x, int y, int w, int h,
+ int *rx, int *ry, int *rw, int *rh ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( qt_old_transformations ) {
+ switch ( txop ) {
+ case TxNone:
+ *rx = x; *ry = y;
+ *rw = w; *rh = h;
+ break;
+ case TxTranslate:
+ // #### "Why no rounding here?", Warwick asked of Haavard.
+ *rx = int(x + dx());
+ *ry = int(y + dy());
+ *rw = w; *rh = h;
+ break;
+ case TxScale: {
+ double tx1 = m11()*x + dx();
+ double ty1 = m22()*y + dy();
+ double tx2 = m11()*(x + w - 1) + dx();
+ double ty2 = m22()*(y + h - 1) + dy();
+ *rx = tqRound( tx1 );
+ *ry = tqRound( ty1 );
+ *rw = tqRound( tx2 ) - *rx + 1;
+ *rh = tqRound( ty2 ) - *ry + 1;
+ } break;
+ default:
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::map: Internal error" );
+#endif
+ break;
+ }
+ } else {
+ switch ( txop ) {
+ case TxNone:
+ *rx = x; *ry = y;
+ *rw = w; *rh = h;
+ break;
+ case TxTranslate:
+ *rx = tqRound(x + dx() );
+ *ry = tqRound(y + dy() );
+ *rw = w; *rh = h;
+ break;
+ case TxScale:
+ *rx = tqRound( m11()*x + dx() );
+ *ry = tqRound( m22()*y + dy() );
+ *rw = tqRound( m11()*w );
+ *rh = tqRound( m22()*h );
+ break;
+ default:
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::map: Internal error" );
+#endif
+ break;
+ }
+ }
+#else
+ *rx = x + xlatex;
+ *ry = y + xlatey;
+ *rw = w; *rh = h;
+#endif
+}
+
+/*!
+ \internal
+ Maps a point from tqdevice coordinates to logical coordinates.
+*/
+
+void TQPainter::mapInv( int x, int y, int *rx, int *ry ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+#if defined(TQT_CHECK_STATE)
+ if ( !txinv )
+ qWarning( "TQPainter::mapInv: Internal error" );
+#endif
+ if ( qt_old_transformations ) {
+ double tx = im11()*x + im21()*y+idx();
+ double ty = im12()*x + im22()*y+idy();
+ *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
+ *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
+ } else {
+ *rx = tqRound( im11()*x + im21()*y + idx() );
+ *ry = tqRound( im12()*x + im22()*y + idy() );
+ }
+#else
+ *rx = x - xlatex;
+ *ry = y - xlatey;
+#endif
+}
+
+/*!
+ \internal
+ Maps a rectangle from tqdevice coordinates to logical coordinates.
+ Cannot handle rotation and/or shear.
+*/
+
+void TQPainter::mapInv( int x, int y, int w, int h,
+ int *rx, int *ry, int *rw, int *rh ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+#if defined(TQT_CHECK_STATE)
+ if ( !txinv || txop == TxRotShear )
+ qWarning( "TQPainter::mapInv: Internal error" );
+#endif
+ if ( qt_old_transformations ) {
+ double tx = im11()*x + idx();
+ double ty = im22()*y + idy();
+ double tw = im11()*w;
+ double th = im22()*h;
+ *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
+ *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
+ *rw = tw >= 0 ? int(tw + 0.5) : int(tw - 0.5);
+ *rh = th >= 0 ? int(th + 0.5) : int(th - 0.5);
+ } else {
+ *rx = tqRound( im11()*x + idx() );
+ *ry = tqRound( im22()*y + idy() );
+ *rw = tqRound( im11()*w );
+ *rh = tqRound( im22()*h );
+ }
+#else
+ *rx = x - xlatex;
+ *ry = y - xlatey;
+ *rw = w;
+ *rh = h;
+#endif
+}
+
+
+/*!
+ Returns the point \a pv transformed from model coordinates to
+ tqdevice coordinates.
+
+ \sa xFormDev(), TQWMatrix::map()
+*/
+
+TQPoint TQPainter::xForm( const TQPoint &pv ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return pv;
+ int x=pv.x(), y=pv.y();
+ map( x, y, &x, &y );
+ return TQPoint( x, y );
+#else
+ return TQPoint( pv.x()+xlatex, pv.y()+xlatey );
+#endif
+}
+
+/*!
+ \overload
+
+ Returns the rectangle \a rv transformed from model coordinates to
+ tqdevice coordinates.
+
+ If world transformation is enabled and rotation or shearing has
+ been specified, then the bounding rectangle is returned.
+
+ \sa xFormDev(), TQWMatrix::map()
+*/
+
+TQRect TQPainter::xForm( const TQRect &rv ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return rv;
+ if ( txop == TxRotShear ) { // rotation/shear
+ return xmat.mapRect( rv );
+ }
+ // Just translation/scale
+ int x, y, w, h;
+ rv.rect( &x, &y, &w, &h );
+ map( x, y, w, h, &x, &y, &w, &h );
+ return TQRect( x, y, w, h );
+#else
+ return TQRect( rv.x()+xlatex, rv.y()+xlatey, rv.width(), rv.height() );
+#endif
+}
+
+/*!
+ \overload
+
+ Returns the point array \a av transformed from model coordinates
+ to tqdevice coordinates.
+
+ \sa xFormDev(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xForm( const TQPointArray &av ) const
+{
+ TQPointArray a = av;
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop != TxNone )
+ {
+ return xmat * av;
+ }
+#else
+ a.translate( xlatex, xlatey );
+#endif
+ return a;
+}
+
+/*!
+ \overload
+
+ Returns the point array \a av transformed from model coordinates
+ to tqdevice coordinates. The \a index is the first point in the
+ array and \a npoints denotes the number of points to be
+ transformed. If \a npoints is negative, all points from \a
+ av[index] until the last point in the array are transformed.
+
+ The returned point array consists of the number of points that
+ were transformed.
+
+ Example:
+ \code
+ TQPointArray a(10);
+ TQPointArray b;
+ b = painter.xForm(a, 2, 4); // b.size() == 4
+ b = painter.xForm(a, 2, -1); // b.size() == 8
+ \endcode
+
+ \sa xFormDev(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xForm( const TQPointArray &av, int index,
+ int npoints ) const
+{
+ int lastPoint = npoints < 0 ? av.size() : index+npoints;
+ TQPointArray a( lastPoint-index );
+ memcpy( a.data(), av.data()+index, (lastPoint-index)*sizeof( TQPoint ) );
+#ifndef TQT_NO_TRANSFORMATIONS
+ return xmat*a;
+#else
+ a.translate( xlatex, xlatey );
+ return a;
+#endif
+}
+
+/*!
+ \overload
+
+ Returns the point \a pd transformed from tqdevice coordinates to
+ model coordinates.
+
+ \sa xForm(), TQWMatrix::map()
+*/
+
+TQPoint TQPainter::xFormDev( const TQPoint &pd ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return pd;
+ if ( !txinv ) {
+ TQPainter *that = (TQPainter*)this; // mutable
+ that->updateInvXForm();
+ }
+#endif
+ int x=pd.x(), y=pd.y();
+ mapInv( x, y, &x, &y );
+ return TQPoint( x, y );
+}
+
+/*!
+ Returns the rectangle \a rd transformed from tqdevice coordinates to
+ model coordinates.
+
+ If world transformation is enabled and rotation or shearing is
+ used, then the bounding rectangle is returned.
+
+ \sa xForm(), TQWMatrix::map()
+*/
+
+TQRect TQPainter::xFormDev( const TQRect &rd ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return rd;
+ if ( !txinv ) {
+ TQPainter *that = (TQPainter*)this; // mutable
+ that->updateInvXForm();
+ }
+ if ( txop == TxRotShear ) { // rotation/shear
+ return ixmat.mapRect( rd );
+ }
+#endif
+ // Just translation/scale
+ int x, y, w, h;
+ rd.rect( &x, &y, &w, &h );
+ mapInv( x, y, w, h, &x, &y, &w, &h );
+ return TQRect( x, y, w, h );
+}
+
+/*!
+ \overload
+
+ Returns the point array \a ad transformed from tqdevice coordinates
+ to model coordinates.
+
+ \sa xForm(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xFormDev( const TQPointArray &ad ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return ad;
+ if ( !txinv ) {
+ TQPainter *that = (TQPainter*)this; // mutable
+ that->updateInvXForm();
+ }
+ return ixmat * ad;
+#else
+ // ###
+ return ad;
+#endif
+}
+
+/*!
+ \overload
+
+ Returns the point array \a ad transformed from tqdevice coordinates
+ to model coordinates. The \a index is the first point in the array
+ and \a npoints denotes the number of points to be transformed. If
+ \a npoints is negative, all points from \a ad[index] until the
+ last point in the array are transformed.
+
+ The returned point array consists of the number of points that
+ were transformed.
+
+ Example:
+ \code
+ TQPointArray a(10);
+ TQPointArray b;
+ b = painter.xFormDev(a, 1, 3); // b.size() == 3
+ b = painter.xFormDev(a, 1, -1); // b.size() == 9
+ \endcode
+
+ \sa xForm(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xFormDev( const TQPointArray &ad, int index,
+ int npoints ) const
+{
+ int lastPoint = npoints < 0 ? ad.size() : index+npoints;
+ TQPointArray a( lastPoint-index );
+ memcpy( a.data(), ad.data()+index, (lastPoint-index)*sizeof( TQPoint ) );
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return a;
+ if ( !txinv ) {
+ TQPainter *that = (TQPainter*)this; // mutable
+ that->updateInvXForm();
+ }
+ return ixmat * a;
+#else
+ // ###
+ return a;
+#endif
+}
+
+
+/*!
+ Fills the rectangle \a (x, y, w, h) with the \a brush.
+
+ You can specify a TQColor as \a brush, since there is a TQBrush
+ constructor that takes a TQColor argument and creates a solid
+ pattern brush.
+
+ \sa drawRect()
+*/
+
+void TQPainter::fillRect( int x, int y, int w, int h, const TQBrush &brush )
+{
+ TQPen oldPen = pen(); // save pen
+ TQBrush oldBrush = this->brush(); // save brush
+ setPen( NoPen );
+ setBrush( brush );
+ drawRect( x, y, w, h ); // draw filled rect
+ setBrush( oldBrush ); // restore brush
+ setPen( oldPen ); // restore pen
+}
+
+
+/*!
+ \overload void TQPainter::setBrushOrigin( const TQPoint &p )
+
+ Sets the brush origin to point \a p.
+*/
+
+/*!
+ \overload void TQPainter::setWindow( const TQRect &r )
+
+ Sets the painter's window to rectangle \a r.
+*/
+
+
+/*!
+ \overload void TQPainter::setViewport( const TQRect &r )
+
+ Sets the painter's viewport to rectangle \a r.
+*/
+
+
+/*!
+ \fn bool TQPainter::hasClipping() const
+
+ Returns TRUE if clipping has been set; otherwise returns FALSE.
+
+ \sa setClipping()
+*/
+
+/*!
+ Returns the currently set clip region. Note that the clip region
+ is given in physical tqdevice coordinates and \e not subject to any
+ \link coordsys.html coordinate transformation \endlink if \a m is
+ equal to \c CoordDevice (the default). If \a m equals \c
+ CoordPainter the returned region is in model coordinates.
+
+ \sa setClipRegion(), setClipRect(), setClipping() TQPainter::CoordinateMode
+*/
+TQRegion TQPainter::clipRegion( CoordinateMode m ) const
+{
+ // ### FIXME in 4.0:
+ // If the transformation mode is CoordPainter, we should transform the
+ // clip region with painter transformations.
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQRegion r;
+ if ( m == CoordDevice ) {
+ r = crgn;
+ } else {
+ if ( !txinv ) {
+ TQPainter *that = (TQPainter*)this; // mutable
+ that->updateInvXForm();
+ }
+
+ r = ixmat * crgn;
+ }
+ return r;
+#else
+ return crgn;
+#endif
+}
+
+/*!
+ \fn void TQPainter::setClipRect( int x, int y, int w, int h, CoordinateMode m)
+
+ Sets the clip region to the rectangle \a x, \a y, \a w, \a h and
+ enables clipping. The clip mode is set to \a m.
+
+ If \a m is \c CoordDevice (the default), the coordinates given for
+ the clip region are taken to be physical tqdevice coordinates and
+ are \e not subject to any \link coordsys.html coordinate
+ transformations\endlink. If \a m is \c CoordPainter, the
+ coordinates given for the clip region are taken to be model
+ coordinates.
+
+ \sa setClipRegion(), clipRegion(), setClipping() TQPainter::CoordinateMode
+*/
+
+/*!
+ \overload void TQPainter::drawPoint( const TQPoint &p )
+
+ Draws the point \a p.
+*/
+
+
+/*!
+ \overload void TQPainter::moveTo( const TQPoint &p )
+
+ Moves to the point \a p.
+*/
+
+/*!
+ \overload void TQPainter::lineTo( const TQPoint &p )
+
+ Draws a line to the point \a p.
+*/
+
+/*!
+ \overload void TQPainter::drawLine( const TQPoint &p1, const TQPoint &p2 )
+
+ Draws a line from point \a p1 to point \a p2.
+*/
+
+/*!
+ \overload void TQPainter::drawRect( const TQRect &r )
+
+ Draws the rectangle \a r.
+*/
+
+/*!
+ \overload void TQPainter::drawWinFocusRect( const TQRect &r )
+
+ Draws rectangle \a r as a window focus rectangle.
+*/
+
+/*!
+ \overload void TQPainter::drawWinFocusRect( const TQRect &r, const TQColor &bgColor )
+
+ Draws rectangle \a r as a window focus rectangle using background
+ color \a bgColor.
+*/
+
+
+#if !defined(TQ_WS_X11) && !defined(TQ_WS_TQWS) && !defined(TQ_WS_MAC)
+// The doc and X implementation of this functions is in qpainter_x11.cpp
+void TQPainter::drawWinFocusRect( int, int, int, int,
+ bool, const TQColor & )
+{
+ // do nothing, only called from X11 specific functions
+}
+#endif
+
+
+/*!
+ \overload void TQPainter::drawRoundRect( const TQRect &r, int xRnd, int yRnd )
+
+ Draws a rounded rectangle \a r, rounding to the x position \a xRnd
+ and the y position \a yRnd on each corner.
+*/
+
+/*!
+ \overload void TQPainter::drawEllipse( const TQRect &r )
+
+ Draws the ellipse that fits inside rectangle \a r.
+*/
+
+/*!
+ \overload void TQPainter::drawArc( const TQRect &r, int a, int alen )
+
+ Draws the arc that fits inside the rectangle \a r with start angle
+ \a a and arc length \a alen.
+*/
+
+/*!
+ \overload void TQPainter::drawPie( const TQRect &r, int a, int alen )
+
+ Draws a pie segment that fits inside the rectangle \a r with start
+ angle \a a and arc length \a alen.
+*/
+
+/*!
+ \overload void TQPainter::drawChord( const TQRect &r, int a, int alen )
+
+ Draws a chord that fits inside the rectangle \a r with start angle
+ \a a and arc length \a alen.
+*/
+
+/*!
+ \overload void TQPainter::drawPixmap( const TQPoint &p, const TQPixmap &pm, const TQRect &sr )
+
+ Draws the rectangle \a sr of pixmap \a pm with its origin at point
+ \a p.
+*/
+
+/*!
+ \overload void TQPainter::drawPixmap( const TQPoint &p, const TQPixmap &pm )
+
+ Draws the pixmap \a pm with its origin at point \a p.
+*/
+
+void TQPainter::drawPixmap( const TQPoint &p, const TQPixmap &pm )
+{
+ drawPixmap( p.x(), p.y(), pm, 0, 0, pm.width(), pm.height() );
+}
+
+#if !defined(TQT_NO_IMAGE_SMOOTHSCALE) || !defined(TQT_NO_PIXMAP_TRANSFORMATION)
+
+/*!
+ \overload
+
+ Draws the pixmap \a pm into the rectangle \a r. The pixmap is
+ scaled to fit the rectangle, if image and rectangle size disagree.
+*/
+void TQPainter::drawPixmap( const TQRect &r, const TQPixmap &pm )
+{
+ int rw = r.width();
+ int rh = r.height();
+ int iw= pm.width();
+ int ih = pm.height();
+ if ( rw <= 0 || rh <= 0 || iw <= 0 || ih <= 0 )
+ return;
+ bool scale = ( rw != iw || rh != ih );
+ float scaleX = (float)rw/(float)iw;
+ float scaleY = (float)rh/(float)ih;
+ bool smooth = ( scaleX < 1.5 || scaleY < 1.5 );
+
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[2];
+ param[0].rect = &r;
+ param[1].pixmap = &pm;
+#if defined(TQ_WS_WIN)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawPixmap, this, param ) || !hdc )
+ return;
+#elif defined(TQ_WS_TQWS)
+ pdev->cmd( TQPaintDevice::PdcDrawPixmap, this, param );
+ return;
+#elif defined(TQ_WS_MAC)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawPixmap, this, param ) || !pdev->handle())
+ return;
+#else
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawPixmap, this, param ) || !hd )
+ return;
+#endif
+ }
+
+ TQPixmap pixmap = pm;
+
+ if ( scale ) {
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+# ifndef TQT_NO_PIXMAP_TRANSFORMATION
+ if ( smooth )
+# endif
+ {
+ TQImage i = pm.convertToImage();
+ pixmap = TQPixmap( i.smoothScale( rw, rh ) );
+ }
+# ifndef TQT_NO_PIXMAP_TRANSFORMATION
+ else
+# endif
+#endif
+#ifndef TQT_NO_PIXMAP_TRANSFORMATION
+ {
+ pixmap = pm.xForm( TQWMatrix( scaleX, 0, 0, scaleY, 0, 0 ) );
+ }
+#endif
+ }
+ drawPixmap( r.x(), r.y(), pixmap );
+}
+
+#endif
+
+/*!
+ \overload void TQPainter::drawImage( const TQPoint &, const TQImage &, const TQRect &sr, int conversionFlags = 0 );
+
+ Draws the rectangle \a sr from the image at the given point.
+*/
+
+/*
+ Draws at point \a p the \sr rect from image \a pm, using \a
+ conversionFlags if the image needs to be converted to a pixmap.
+ The default value for \a conversionFlags is 0; see
+ convertFromImage() for information about what other values do.
+
+ This function may convert \a image to a pixmap and then draw it, if
+ tqdevice() is a TQPixmap or a TQWidget, or else draw it directly, if
+ tqdevice() is a TQPrinter or TQPicture.
+*/
+
+/*!
+ Draws at (\a x, \a y) the \a sw by \a sh area of pixels from (\a
+ sx, \a sy) in \a image, using \a conversionFlags if the image
+ needs to be converted to a pixmap. The default value for \a
+ conversionFlags is 0; see convertFromImage() for information about
+ what other values do.
+
+ This function may convert \a image to a pixmap and then draw it,
+ if tqdevice() is a TQPixmap or a TQWidget, or else draw it directly,
+ if tqdevice() is a TQPrinter or TQPicture.
+
+ Currently alpha masks of the image are ignored when painting on a TQPrinter.
+
+ \sa drawPixmap() TQPixmap::convertFromImage()
+*/
+void TQPainter::drawImage( int x, int y, const TQImage & image,
+ int sx, int sy, int sw, int sh,
+ int conversionFlags )
+{
+#ifdef TQ_WS_TQWS
+ //### Hackish
+# ifndef TQT_NO_TRANSFORMATIONS
+ if ( !image.isNull() && gfx &&
+ (txop==TxNone||txop==TxTranslate) && !testf(ExtDev) )
+# else
+ if ( !image.isNull() && gfx && !testf(ExtDev) )
+# endif
+ {
+ if(sw<0)
+ sw=image.width();
+ if(sh<0)
+ sh=image.height();
+
+ TQImage image2 = qt_screen->mapToDevice( image );
+
+ // This is a bit dubious
+ if(image2.depth()==1) {
+ image2.setNumColors( 2 );
+ image2.setColor( 0, tqRgb(255,255,255) );
+ image2.setColor( 1, tqRgb(0,0,0) );
+ }
+ if ( image2.hasAlphaBuffer() )
+ gfx->setAlphaType(TQGfx::InlineAlpha);
+ else
+ gfx->setAlphaType(TQGfx::IgnoreAlpha);
+ gfx->setSource(&image2);
+ if ( testf(VxF|WxF) ) {
+ map( x, y, &x, &y );
+ }
+ gfx->blt(x,y,sw,sh,sx,sy);
+ return;
+ }
+#endif
+
+ if ( !isActive() || image.isNull() )
+ return;
+
+ // right/bottom
+ if ( sw < 0 )
+ sw = image.width() - sx;
+ if ( sh < 0 )
+ sh = image.height() - sy;
+
+ // Sanity-check clipping
+ if ( sx < 0 ) {
+ x -= sx;
+ sw += sx;
+ sx = 0;
+ }
+ if ( sw + sx > image.width() )
+ sw = image.width() - sx;
+ if ( sy < 0 ) {
+ y -= sy;
+ sh += sy;
+ sy = 0;
+ }
+ if ( sh + sy > image.height() )
+ sh = image.height() - sy;
+
+ if ( sw <= 0 || sh <= 0 )
+ return;
+
+ bool all = image.rect().intersect(TQRect(sx,sy,sw,sh)) == image.rect();
+ TQImage subimage = all ? image : image.copy(sx,sy,sw,sh);
+
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[2];
+ TQRect r( x, y, subimage.width(), subimage.height() );
+ param[0].rect = &r;
+ param[1].image = &subimage;
+#if defined(TQ_WS_WIN)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !hdc )
+ return;
+#elif defined (TQ_WS_TQWS)
+ pdev->cmd( TQPaintDevice::PdcDrawImage, this, param );
+ return;
+#elif defined(TQ_WS_MAC)
+ if(!pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !pdev->handle() )
+ return;
+#else
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !hd )
+ return;
+#endif
+ }
+
+ TQPixmap pm;
+ pm.convertFromImage( subimage, conversionFlags );
+ drawPixmap( x, y, pm );
+}
+
+/*!
+ \overload void TQPainter::drawImage( const TQPoint &p, const TQImage &i, int conversion_flags )
+
+ Draws the image \a i at point \a p.
+
+ If the image needs to be modified to fit in a lower-resolution
+ result (e.g. converting from 32-bit to 8-bit), use the \a
+ conversion_flags to specify how you'd prefer this to happen.
+
+ \sa TQt::ImageConversionFlags
+*/
+void TQPainter::drawImage( const TQPoint & p, const TQImage & i,
+ int conversion_flags )
+{
+ drawImage(p, i, i.rect(), conversion_flags);
+}
+
+#if !defined(TQT_NO_IMAGE_TRANSFORMATION) || !defined(TQT_NO_IMAGE_SMOOTHSCALE)
+
+/*!
+ \overload
+
+ Draws the image \a i into the rectangle \a r. The image will be
+ scaled to fit the rectangle if image and rectangle dimensions
+ differ.
+*/
+void TQPainter::drawImage( const TQRect &r, const TQImage &i )
+{
+ int rw = r.width();
+ int rh = r.height();
+ int iw= i.width();
+ int ih = i.height();
+ if ( rw <= 0 || rh <= 0 || iw <= 0 || ih <= 0 )
+ return;
+
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[2];
+ param[0].rect = &r;
+ param[1].image = &i;
+#if defined(TQ_WS_WIN)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !hdc )
+ return;
+#elif defined(TQ_WS_TQWS)
+ pdev->cmd( TQPaintDevice::PdcDrawImage, this, param );
+ return;
+#elif defined(TQ_WS_MAC)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !pdev->handle() )
+ return;
+#else
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !hd )
+ return;
+#endif
+ }
+
+
+ bool scale = ( rw != iw || rh != ih );
+ float scaleX = (float)rw/(float)iw;
+ float scaleY = (float)rh/(float)ih;
+ bool smooth = ( scaleX < 1.5 || scaleY < 1.5 );
+
+ TQImage img = scale
+ ? (
+#if defined(TQT_NO_IMAGE_TRANSFORMATION)
+ i.smoothScale( rw, rh )
+#elif defined(TQT_NO_IMAGE_SMOOTHSCALE)
+ i.scale( rw, rh )
+#else
+ smooth ? i.smoothScale( rw, rh ) : i.scale( rw, rh )
+#endif
+ )
+ : i;
+
+ drawImage( r.x(), r.y(), img );
+}
+
+#endif
+
+
+void bitBlt( TQPaintDevice *dst, int dx, int dy,
+ const TQImage *src, int sx, int sy, int sw, int sh,
+ int conversion_flags )
+{
+ TQPixmap tmp;
+ if ( sx == 0 && sy == 0
+ && (sw<0 || sw==src->width()) && (sh<0 || sh==src->height()) )
+ {
+ tmp.convertFromImage( *src, conversion_flags );
+ } else {
+ tmp.convertFromImage( src->copy( sx, sy, sw, sh, conversion_flags),
+ conversion_flags );
+ }
+ bitBlt( dst, dx, dy, &tmp );
+}
+
+
+/*!
+ \overload void TQPainter::drawTiledPixmap( const TQRect &r, const TQPixmap &pm, const TQPoint &sp )
+
+ Draws a tiled pixmap, \a pm, inside rectangle \a r with its origin
+ at point \a sp.
+*/
+
+/*!
+ \overload void TQPainter::drawTiledPixmap( const TQRect &r, const TQPixmap &pm )
+
+ Draws a tiled pixmap, \a pm, inside rectangle \a r.
+*/
+
+/*!
+ \overload void TQPainter::fillRect( const TQRect &r, const TQBrush &brush )
+
+ Fills the rectangle \a r using brush \a brush.
+*/
+
+/*!
+ \fn void TQPainter::eraseRect( int x, int y, int w, int h )
+
+ Erases the area inside \a x, \a y, \a w, \a h. Equivalent to
+ \c{fillRect( x, y, w, h, backgroundColor() )}.
+*/
+
+/*!
+ \overload void TQPainter::eraseRect( const TQRect &r )
+
+ Erases the area inside the rectangle \a r.
+*/
+
+/*!
+ \fn TQPainter::drawText( int x, int y, const TQString &, int len = -1, TextDirection dir = Auto )
+
+ \overload
+
+ Draws the given text at position \a x, \a y. If \a len is -1 (the
+ default) all the text is drawn, otherwise the first \a len
+ characters are drawn. The text's direction is given by \a dir.
+
+ \sa TQPainter::TextDirection
+*/
+
+/*!
+ \fn void TQPainter::drawText( int x, int y, int w, int h, int flags,
+ const TQString&, int len = -1, TQRect *br=0,
+ TQTextParag **internal=0 )
+
+ \overload
+
+ Draws the given text within the rectangle starting at \a x, \a y,
+ with width \a w and height \a h. If \a len is -1 (the default) all
+ the text is drawn, otherwise the first \a len characters are
+ drawn. The text's flags that are given in the \a flags parameter
+ are \l{TQt::AlignmentFlags} and \l{TQt::TextFlags} OR'd together. \a
+ br (if not null) is set to the actual bounding rectangle of the
+ output. The \a internal parameter is for internal use only.
+*/
+
+/*!
+ \fn void TQPainter::drawText( const TQPoint &, const TQString &, int len = -1, TextDirection dir = Auto );
+
+ \overload
+
+ Draws the text at the given point.
+
+ \sa TQPainter::TextDirection
+*/
+
+/*
+ Draws the text in \a s at point \a p. If \a len is -1 the entire
+ string is drawn, otherwise just the first \a len characters. The
+ text's direction is specified by \a dir.
+*/
+
+
+/*!
+ \fn void TQPainter::drawText( int x, int y, const TQString &, int pos, int len, TextDirection dir = Auto );
+
+ \overload
+
+ Draws the text from position \a pos, at point \a (x, y). If \a len is
+ -1 the entire string is drawn, otherwise just the first \a len
+ characters. The text's direction is specified by \a dir.
+*/
+
+/*!
+ \fn void TQPainter::drawText( const TQPoint &p, const TQString &, int pos, int len, TextDirection dir = Auto );
+
+ Draws the text from position \a pos, at point \a p. If \a len is
+ -1 the entire string is drawn, otherwise just the first \a len
+ characters. The text's direction is specified by \a dir.
+
+ Note that the meaning of \e y is not the same for the two
+ drawText() varieties. For overloads that take a simple \e x, \e y
+ pair (or a point), the \e y value is the text's baseline; for
+ overloads that take a rectangle, \e rect.y() is the top of the
+ rectangle and the text is aligned within that rectangle in
+ accordance with the tqalignment flags.
+
+ \sa TQPainter::TextDirection
+*/
+
+/*!
+ \fn void TQPainter::tqdrawTextItem(const TQPoint &, const TQTextItem &, int)
+ \internal
+*/
+
+static inline void fix_neg_rect( int *x, int *y, int *w, int *h )
+{
+ if ( *w < 0 ) {
+ *w = -*w + 2;
+ *x -= *w - 1;
+ }
+ if ( *h < 0 ) {
+ *h = -*h + 2;
+ *y -= *h - 1;
+ }
+}
+void TQPainter::fix_neg_rect( int *x, int *y, int *w, int *h )
+{
+ ::fix_neg_rect(x,y,w,h);
+}
+
+//
+// The drawText function takes two special parameters; 'internal' and 'brect'.
+//
+// The 'internal' parameter tqcontains a pointer to an array of encoded
+// information that keeps internal tqgeometry data.
+// If the drawText function is called repeatedly to display the same text,
+// it makes sense to calculate text width and linebreaks the first time,
+// and use these parameters later to print the text because we save a lot of
+// CPU time.
+// The 'internal' parameter will not be used if it is a null pointer.
+// The 'internal' parameter will be generated if it is not null, but points
+// to a null pointer, i.e. internal != 0 && *internal == 0.
+// The 'internal' parameter will be used if it tqcontains a non-null pointer.
+//
+// If the 'brect parameter is a non-null pointer, then the bounding rectangle
+// of the text will be returned in 'brect'.
+//
+
+/*!
+ \overload
+
+ Draws at most \a len characters from \a str in the rectangle \a r.
+
+ This function draws formatted text. The \a tf text format is
+ really of type \l TQt::AlignmentFlags and \l TQt::TextFlags OR'd
+ together.
+
+ Horizontal tqalignment defaults to AlignAuto and vertical tqalignment
+ defaults to AlignTop.
+
+ \a brect (if not null) is set to the actual bounding rectangle of
+ the output. \a internal is, yes, internal.
+
+ \sa boundingRect()
+*/
+
+void TQPainter::drawText( const TQRect &r, int tf,
+ const TQString& str, int len, TQRect *brect,
+ TQTextParag **internal )
+{
+ if ( !isActive() )
+ return;
+ if ( len < 0 )
+ len = str.length();
+ if ( len == 0 ) // empty string
+ return;
+
+ if ( testf(DirtyFont|ExtDev) ) {
+ if ( testf(DirtyFont) )
+ updateFont();
+ if ( testf(ExtDev) && (tf & DontPrint) == 0 ) {
+ TQPDevCmdParam param[3];
+ TQString newstr = str;
+ newstr.truncate( len );
+ param[0].rect = &r;
+ param[1].ival = tf;
+ param[2].str = &newstr;
+ if ( pdev->devType() != TQInternal::Printer ) {
+#if defined(TQ_WS_WIN)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawText2Formatted,
+ this, param) ||
+ !hdc )
+ return; // TQPrinter wants PdcDrawText2
+#elif defined(TQ_WS_TQWS)
+ pdev->cmd( TQPaintDevice::PdcDrawText2Formatted, this, param);
+ return;
+#elif defined(TQ_WS_MAC)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawText2Formatted, this, param) ||
+ !pdev->handle())
+ return; // TQPrinter wants PdcDrawText2
+#else
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawText2Formatted,
+ this, param) ||
+ !hd )
+ return; // TQPrinter wants PdcDrawText2
+#endif
+ }
+ }
+ }
+
+ qt_format_text(font(), r, tf, str, len, brect,
+ tabstops, tabarray, tabarraylen, internal, this);
+}
+
+//#define TQT_FORMAT_TEXT_DEBUG
+
+#define TQChar_linesep TQChar(0x2028U)
+
+void qt_format_text( const TQFont& font, const TQRect &_r,
+ int tf, const TQString& str, int len, TQRect *brect,
+ int tabstops, int* tabarray, int tabarraylen,
+ TQTextParag **, TQPainter* painter )
+{
+ // we need to copy r here to protect against the case (&r == brect).
+ TQRect r( _r );
+
+ bool dontclip = (tf & TQt::DontClip) == TQt::DontClip;
+ bool wordbreak = (tf & TQt::WordBreak) == TQt::WordBreak;
+ bool singleline = (tf & TQt::SingleLine) == TQt::SingleLine;
+ bool showprefix = (tf & TQt::ShowPrefix) == TQt::ShowPrefix;
+ bool noaccel = ( tf & TQt::NoAccel ) == TQt::NoAccel;
+
+ bool isRightToLeft = str.isRightToLeft();
+ if ( ( tf & TQt::AlignHorizontal_Mask ) == TQt::AlignAuto )
+ tf |= isRightToLeft ? TQt::AlignRight : TQt::AlignLeft;
+
+ bool expandtabs = ( (tf & TQt::ExpandTabs) &&
+ ( ( (tf & TQt::AlignLeft) && !isRightToLeft ) ||
+ ( (tf & TQt::AlignRight) && isRightToLeft ) ) );
+
+ if ( !painter )
+ tf |= TQt::DontPrint;
+
+ int maxUnderlines = 0;
+ int numUnderlines = 0;
+ int underlinePositionStack[32];
+ int *underlinePositions = underlinePositionStack;
+
+ TQFont fnt(painter ? (painter->pfont ? *painter->pfont : painter->cfont) : font);
+ TQFontMetrics fm( fnt );
+
+ TQString text = str;
+ // str.setLength() always does a deep copy, so the tqreplacement
+ // code below is safe.
+ text.setLength( len );
+ // compatible behaviour to the old implementation. Replace
+ // tabs by spaces
+ TQChar *chr = (TQChar*)text.tqunicode();
+ const TQChar *end = chr + len;
+ bool haveLineSep = FALSE;
+ while ( chr != end ) {
+ if ( *chr == '\r' || ( singleline && *chr == '\n' ) ) {
+ *chr = ' ';
+ } else if ( *chr == '\n' ) {
+ *chr = TQChar_linesep;
+ haveLineSep = TRUE;
+ } else if ( *chr == '&' ) {
+ ++maxUnderlines;
+ }
+ ++chr;
+ }
+ if ( !expandtabs ) {
+ chr = (TQChar*)text.tqunicode();
+ while ( chr != end ) {
+ if ( *chr == '\t' )
+ *chr = ' ';
+ ++chr;
+ }
+ } else if (!tabarraylen && !tabstops) {
+ tabstops = fm.width('x')*8;
+ }
+
+ if ( noaccel || showprefix ) {
+ if ( maxUnderlines > 32 )
+ underlinePositions = new int[maxUnderlines];
+ TQChar *cout = (TQChar*)text.tqunicode();
+ TQChar *cin = cout;
+ int l = len;
+ while ( l ) {
+ if ( *cin == '&' ) {
+ ++cin;
+ --l;
+ if ( !l )
+ break;
+ if ( *cin != '&' )
+ underlinePositions[numUnderlines++] = cout - text.tqunicode();
+ }
+ *cout = *cin;
+ ++cout;
+ ++cin;
+ --l;
+ }
+ uint newlen = cout - text.tqunicode();
+ if ( newlen != text.length())
+ text.setLength( newlen );
+ }
+
+ // no need to do extra work for underlines if we don't paint
+ if ( tf & TQt::DontPrint )
+ numUnderlines = 0;
+
+ int height = 0;
+ int left = r.width();
+ int right = 0;
+
+ TQTextLayout textLayout( text, fnt );
+ int rb = TQMAX( 0, -fm.minRightBearing() );
+ int lb = TQMAX( 0, -fm.minLeftBearing() );
+
+ if ( text.isEmpty() ) {
+ height = fm.height();
+ left = right = 0;
+ tf |= TQPainter::DontPrint;
+ } else {
+ textLayout.beginLayout((haveLineSep || expandtabs || wordbreak) ?
+ TQTextLayout::MultiLine :
+ (tf & TQt::DontPrint) ? TQTextLayout::NoBidi : TQTextLayout::SingleLine );
+
+ // break underline chars into items of their own
+ for( int i = 0; i < numUnderlines; i++ ) {
+ textLayout.setBoundary( underlinePositions[i] );
+ textLayout.setBoundary( underlinePositions[i]+1 );
+ }
+
+ int lineWidth = wordbreak ? TQMAX(0, r.width()-rb-lb) : INT_MAX;
+ if(!wordbreak)
+ tf |= TQt::IncludeTrailingSpaces;
+
+ int leading = fm.leading();
+ int asc = fm.ascent();
+ int desc = fm.descent();
+ height = -leading;
+
+ //qDebug("\n\nbeginLayout: lw = %d, rectwidth=%d", lineWidth , r.width());
+ while ( !textLayout.atEnd() ) {
+ height += leading;
+ textLayout.beginLine( lineWidth == INT_MAX ? lineWidth : lineWidth );
+ //qDebug("-----beginLine( %d )-----", lineWidth );
+ bool linesep = FALSE;
+ while ( 1 ) {
+ TQTextItem ti = textLayout.currentItem();
+ //qDebug("item: from=%d, ch=%x", ti.from(), text.tqunicode()[ti.from()].tqunicode() );
+ if ( expandtabs && ti.isTab() ) {
+ int tw = 0;
+ int x = textLayout.widthUsed();
+ if ( tabarraylen ) {
+// qDebug("tabarraylen=%d", tabarraylen );
+ int tab = 0;
+ while ( tab < tabarraylen ) {
+ if ( tabarray[tab] > x ) {
+ tw = tabarray[tab] - x;
+ break;
+ }
+ ++tab;
+ }
+ } else {
+ tw = tabstops - (x % tabstops);
+ }
+ //qDebug("tw = %d", tw );
+ if ( tw )
+ ti.setWidth( tw );
+ }
+ if ( ti.isObject() && text.tqunicode()[ti.from()] == TQChar_linesep )
+ linesep = TRUE;
+
+ if ( linesep || textLayout.addCurrentItem() != TQTextLayout::Ok || textLayout.atEnd() )
+ break;
+ }
+
+ int ascent = asc, descent = desc, lineLeft, lineRight;
+ textLayout.setLineWidth( r.width()-rb-lb );
+ textLayout.endLine( 0, height, tf, &ascent, &descent,
+ &lineLeft, &lineRight );
+ //qDebug("finalizing line: lw=%d ascent = %d, descent=%d lineleft=%d lineright=%d", lineWidth, ascent, descent,lineLeft, lineRight );
+ left = TQMIN( left, lineLeft );
+ right = TQMAX( right, lineRight );
+ height += ascent + descent + 1;
+ if ( linesep )
+ textLayout.nextItem();
+ }
+ }
+
+ int yoff = 0;
+ if ( tf & TQt::AlignBottom )
+ yoff = r.height() - height;
+ else if ( tf & TQt::AlignVCenter )
+ yoff = (r.height() - height)/2;
+
+ if ( brect ) {
+ *brect = TQRect( r.x() + left, r.y() + yoff, right-left + lb+rb, height );
+ //qDebug("br = %d %d %d/%d, left=%d, right=%d", brect->x(), brect->y(), brect->width(), brect->height(), left, right);
+ }
+
+ if (!(tf & TQPainter::DontPrint)) {
+ bool restoreClipping = FALSE;
+ bool painterHasClip = FALSE;
+ TQRegion painterClipRegion;
+ if ( !dontclip ) {
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQRegion reg = painter->xmat * r;
+#else
+ TQRegion reg = r;
+ reg.translate( painter->xlatex, painter->xlatey );
+#endif
+ if ( painter->hasClipping() )
+ reg &= painter->clipRegion();
+
+ painterHasClip = painter->hasClipping();
+ painterClipRegion = painter->clipRegion();
+ restoreClipping = TRUE;
+ painter->setClipRegion( reg );
+ } else {
+ if ( painter->hasClipping() ){
+ painterHasClip = painter->hasClipping();
+ painterClipRegion = painter->clipRegion();
+ restoreClipping = TRUE;
+ painter->setClipping( FALSE );
+ }
+ }
+
+ int cUlChar = 0;
+ int _tf = 0;
+ if (fnt.underline()) _tf |= TQt::Underline;
+ if (fnt.overline()) _tf |= TQt::Overline;
+ if (fnt.strikeOut()) _tf |= TQt::StrikeOut;
+
+ //qDebug("have %d items",textLayout.numItems());
+ for ( int i = 0; i < textLayout.numItems(); i++ ) {
+ TQTextItem ti = textLayout.itemAt( i );
+ //qDebug("Item %d: from=%d, length=%d, space=%d x=%d", i, ti.from(), ti.length(), ti.isSpace(), ti.x() );
+ if ( ti.isTab() || ti.isObject() )
+ continue;
+ int textFlags = _tf;
+ if ( !noaccel && numUnderlines > cUlChar && ti.from() == underlinePositions[cUlChar] ) {
+ textFlags |= TQt::Underline;
+ cUlChar++;
+ }
+#if defined(TQ_WS_X11) || defined(TQ_WS_TQWS)
+ if ( painter->bg_mode == TQt::OpaqueMode ) {
+ int h = ti.ascent() + ti.descent() + 1;
+ if (ti.y() + h < height)
+ // don't add leading to last line
+ h += fm.leading();
+ qt_draw_background( painter, r.x()+lb + ti.x(), r.y() + yoff + ti.y() - ti.ascent(),
+ ti.width(), h);
+ }
+#endif
+ painter->tqdrawTextItem( r.x()+lb, r.y() + yoff, ti, textFlags );
+ }
+
+ if ( restoreClipping ) {
+ painter->setClipRegion( painterClipRegion );
+ painter->setClipping( painterHasClip );
+ }
+ }
+
+ if ( underlinePositions != underlinePositionStack )
+ delete [] underlinePositions;
+}
+
+/*!
+ \overload
+
+ Returns the bounding rectangle of the aligned text that would be
+ printed with the corresponding drawText() function using the first
+ \a len characters from \a str if \a len is > -1, or the whole of
+ \a str if \a len is -1. The drawing, and hence the bounding
+ rectangle, is constrained to the rectangle \a r, or to the
+ rectangle required to draw the text, whichever is the larger.
+
+ The \a internal parameter should not be used.
+
+ \sa drawText(), fontMetrics(), TQFontMetrics::boundingRect(), TQt::TextFlags
+*/
+
+TQRect TQPainter::boundingRect( const TQRect &r, int flags,
+ const TQString& str, int len, TQTextParag **internal )
+{
+ TQRect brect;
+ if ( str.isEmpty() )
+ brect.setRect( r.x(),r.y(), 0,0 );
+ else
+ drawText( r, flags | DontPrint, str, len, &brect, internal );
+ return brect;
+}
+
+/*!
+ \fn TQRect TQPainter::boundingRect( int x, int y, int w, int h, int flags, const TQString&, int len = -1, TQTextParag **intern=0 );
+
+ Returns the bounding rectangle of the aligned text that would be
+ printed with the corresponding drawText() function using the first
+ \a len characters of the string if \a len is > -1, or the whole of
+ the string if \a len is -1. The drawing, and hence the bounding
+ rectangle, is constrained to the rectangle that begins at point \a
+ (x, y) with width \a w and hight \a h, or to the
+ rectangle required to draw the text, whichever is the larger.
+
+ The \a flags argument is
+ the bitwise OR of the following flags:
+ \table
+ \header \i Flag \i Meaning
+ \row \i \c AlignAuto \i aligns according to the language, usually left.
+ \row \i \c AlignLeft \i aligns to the left border.
+ \row \i \c AlignRight \i aligns to the right border.
+ \row \i \c AlignHCenter \i aligns horizontally centered.
+ \row \i \c AlignTop \i aligns to the top border.
+ \row \i \c AlignBottom \i aligns to the bottom border.
+ \row \i \c AlignVCenter \i aligns vertically centered.
+ \row \i \c AlignCenter \i (== \c AlignHCenter | \c AlignVCenter).
+ \row \i \c SingleLine \i ignores newline characters in the text.
+ \row \i \c ExpandTabs \i expands tabs.
+ \row \i \c ShowPrefix \i interprets "&x" as "<u>x</u>".
+ \row \i \c WordBreak \i breaks the text to fit the rectangle.
+ \endtable
+
+ Horizontal tqalignment defaults to \c AlignLeft and vertical
+ tqalignment defaults to \c AlignTop.
+
+ If several of the horizontal or several of the vertical tqalignment flags
+ are set, the resulting tqalignment is undefined.
+
+ The \a intern parameter should not be used.
+
+ \sa TQt::TextFlags
+*/
+
+
+
+/*****************************************************************************
+ TQPen member functions
+ *****************************************************************************/
+
+/*!
+ \class TQPen tqpen.h
+ \brief The TQPen class defines how a TQPainter should draw lines and outlines
+ of tqshapes.
+
+ \ingroup graphics
+ \ingroup images
+ \ingroup shared
+ \mainclass
+
+ A pen has a style, width, color, cap style and join style.
+
+ The pen style defines the line type. The default pen style is \c
+ TQt::SolidLine. Setting the style to \c NoPen tells the painter to
+ not draw lines or outlines.
+
+ When drawing 1 pixel wide diagonal lines you can either use a very
+ fast algorithm (specified by a line width of 0, which is the
+ default), or a slower but more accurate algorithm (specified by a
+ line width of 1). For horizontal and vertical lines a line width
+ of 0 is the same as a line width of 1. The cap and join style have
+ no effect on 0-width lines.
+
+ The pen color defines the color of lines and text. The default
+ line color is black. The TQColor documentation lists predefined
+ colors.
+
+ The cap style defines how the end points of lines are drawn. The
+ join style defines how the joins between two lines are drawn when
+ multiple connected lines are drawn (TQPainter::drawPolyline()
+ etc.). The cap and join styles only apply to wide lines, i.e. when
+ the width is 1 or greater.
+
+ Use the TQBrush class to specify fill styles.
+
+ Example:
+ \code
+ TQPainter painter;
+ TQPen pen( red, 2 ); // red solid line, 2 pixels wide
+ painter.begin( &anyPaintDevice ); // paint something
+ painter.setPen( pen ); // set the red, wide pen
+ painter.drawRect( 40,30, 200,100 ); // draw a rectangle
+ painter.setPen( blue ); // set blue pen, 0 pixel width
+ painter.drawLine( 40,30, 240,130 ); // draw a diagonal in rectangle
+ painter.end(); // painting done
+ \endcode
+
+ See the \l TQt::PenStyle enum type for a complete list of pen
+ styles.
+
+ With reference to the end points of lines, for wide (non-0-width)
+ pens it depends on the cap style whether the end point is drawn or
+ not. TQPainter will try to make sure that the end point is drawn
+ for 0-width pens, but this cannot be absolutely guaranteed because
+ the underlying drawing engine is free to use any (typically
+ accelerated) algorithm for drawing 0-width lines. On all tested
+ systems, however, the end point of at least all non-diagonal lines
+ are drawn.
+
+ A pen's color(), width(), style(), capStyle() and joinStyle() can
+ be set in the constructor or later with setColor(), setWidth(),
+ setStyle(), setCapStyle() and setJoinStyle(). Pens may also be
+ compared and streamed.
+
+ \img pen-styles.png Pen styles
+
+ \sa TQPainter, TQPainter::setPen()
+*/
+
+
+/*!
+ \internal
+ Initializes the pen.
+*/
+
+void TQPen::init( const TQColor &color, uint width, uint linestyle )
+{
+ data = new TQPenData;
+ TQ_CHECK_PTR( data );
+ data->style = (PenStyle)(linestyle & MPenStyle);
+ data->width = width;
+ data->color = color;
+ data->linest = linestyle;
+}
+
+/*!
+ Constructs a default black solid line pen with 0 width, which
+ renders lines 1 pixel wide (fast diagonals).
+*/
+
+TQPen::TQPen()
+{
+ init( TQt::black, 0, SolidLine ); // default pen
+}
+
+/*!
+ Constructs a black pen with 0 width (fast diagonals) and style \a
+ style.
+
+ \sa setStyle()
+*/
+
+TQPen::TQPen( PenStyle style )
+{
+ init( TQt::black, 0, style );
+}
+
+/*!
+ Constructs a pen with the specified \a color, \a width and \a
+ style.
+
+ \sa setWidth(), setStyle(), setColor()
+*/
+
+TQPen::TQPen( const TQColor &color, uint width, PenStyle style )
+{
+ init( color, width, style );
+}
+
+/*!
+ Constructs a pen with the specified color \a cl and width \a w.
+ The pen style is set to \a s, the pen cap style to \a c and the
+ pen join style to \a j.
+
+ A line width of 0 will produce a 1 pixel wide line using a fast
+ algorithm for diagonals. A line width of 1 will also produce a 1
+ pixel wide line, but uses a slower more accurate algorithm for
+ diagonals. For horizontal and vertical lines a line width of 0 is
+ the same as a line width of 1. The cap and join style have no
+ effect on 0-width lines.
+
+ \sa setWidth(), setStyle(), setColor()
+*/
+
+TQPen::TQPen( const TQColor &cl, uint w, PenStyle s, PenCapStyle c,
+ PenJoinStyle j )
+{
+ init( cl, w, s | c | j );
+}
+
+/*!
+ Constructs a pen that is a copy of \a p.
+*/
+
+TQPen::TQPen( const TQPen &p )
+{
+ data = p.data;
+ data->ref();
+}
+
+/*!
+ Destroys the pen.
+*/
+
+TQPen::~TQPen()
+{
+ if ( data->deref() )
+ delete data;
+}
+
+
+/*!
+ Detaches from shared pen data to make sure that this pen is the
+ only one referring the data.
+
+ If multiple pens share common data, this pen dereferences the data
+ and gets a copy of the data. Nothing is done if there is just a
+ single reference.
+*/
+
+void TQPen::detach()
+{
+ if ( data->count != 1 )
+ *this = copy();
+}
+
+
+/*!
+ Assigns \a p to this pen and returns a reference to this pen.
+*/
+
+TQPen &TQPen::operator=( const TQPen &p )
+{
+ p.data->ref();
+ if ( data->deref() )
+ delete data;
+ data = p.data;
+ return *this;
+}
+
+
+/*!
+ Returns a \link shclass.html deep copy\endlink of the pen.
+*/
+
+TQPen TQPen::copy() const
+{
+ TQPen p( data->color, data->width, data->style, capStyle(), joinStyle() );
+ return p;
+}
+
+
+/*!
+ \fn PenStyle TQPen::style() const
+
+ Returns the pen style.
+
+ \sa setStyle()
+*/
+
+/*!
+ Sets the pen style to \a s.
+
+ See the \l TQt::PenStyle documentation for a list of all the
+ styles.
+
+ \warning On Mac OS X the style setting (other than \c NoPen and \c
+ SolidLine) have no effect as they are not implemented by the
+ underlying system.
+
+ \warning On Windows 95/98, the style setting (other than \c NoPen
+ and \c SolidLine) has no effect for lines with width greater than
+ 1.
+
+ \sa style()
+*/
+
+void TQPen::setStyle( PenStyle s )
+{
+ if ( data->style == s )
+ return;
+ detach();
+ data->style = s;
+ data->linest = (data->linest & ~MPenStyle) | s;
+}
+
+
+/*!
+ \fn uint TQPen::width() const
+
+ Returns the pen width.
+
+ \sa setWidth()
+*/
+
+/*!
+ Sets the pen width to \a w.
+
+ A line width of 0 will produce a 1 pixel wide line using a fast
+ algorithm for diagonals. A line width of 1 will also produce a 1
+ pixel wide line, but uses a slower more accurate algorithm for
+ diagonals. For horizontal and vertical lines a line width of 0 is
+ the same as a line width of 1. The cap and join style have no
+ effect on 0-width lines.
+
+ \sa width()
+*/
+
+void TQPen::setWidth( uint w )
+{
+ if ( data->width == w )
+ return;
+ detach();
+ data->width = w;
+}
+
+
+/*!
+ Returns the pen's cap style.
+
+ \sa setCapStyle()
+*/
+TQt::PenCapStyle TQPen::capStyle() const
+{
+ return (PenCapStyle)(data->linest & MPenCapStyle);
+}
+
+/*!
+ Sets the pen's cap style to \a c.
+
+ The default value is \c FlatCap. The cap style has no effect on
+ 0-width pens.
+
+ \img pen-cap-styles.png Pen Cap Styles
+
+ \warning On Windows 95/98 and Macintosh, the cap style setting has
+ no effect. Wide lines are rendered as if the cap style was \c
+ SquareCap.
+
+ \sa capStyle()
+*/
+
+void TQPen::setCapStyle( PenCapStyle c )
+{
+ if ( (data->linest & MPenCapStyle) == c )
+ return;
+ detach();
+ data->linest = (data->linest & ~MPenCapStyle) | c;
+}
+
+/*!
+ Returns the pen's join style.
+
+ \sa setJoinStyle()
+*/
+TQt::PenJoinStyle TQPen::joinStyle() const
+{
+ return (PenJoinStyle)(data->linest & MPenJoinStyle);
+}
+
+/*!
+ Sets the pen's join style to \a j.
+
+ The default value is \c MiterJoin. The join style has no effect on
+ 0-width pens.
+
+ \img pen-join-styles.png Pen Join Styles
+
+ \warning On Windows 95/98 and Macintosh, the join style setting
+ has no effect. Wide lines are rendered as if the join style was \c
+ BevelJoin.
+
+ \sa joinStyle()
+*/
+
+void TQPen::setJoinStyle( PenJoinStyle j )
+{
+ if ( (data->linest & MPenJoinStyle) == j )
+ return;
+ detach();
+ data->linest = (data->linest & ~MPenJoinStyle) | j;
+}
+
+/*!
+ \fn const TQColor &TQPen::color() const
+
+ Returns the pen color.
+
+ \sa setColor()
+*/
+
+/*!
+ Sets the pen color to \a c.
+
+ \sa color()
+*/
+
+void TQPen::setColor( const TQColor &c )
+{
+ detach();
+ data->color = c;
+}
+
+
+/*!
+ \fn bool TQPen::operator!=( const TQPen &p ) const
+
+ Returns TRUE if the pen is different from \a p; otherwise returns
+ FALSE.
+
+ Two pens are different if they have different styles, widths or
+ colors.
+
+ \sa operator==()
+*/
+
+/*!
+ Returns TRUE if the pen is equal to \a p; otherwise returns FALSE.
+
+ Two pens are equal if they have equal styles, widths and colors.
+
+ \sa operator!=()
+*/
+
+bool TQPen::operator==( const TQPen &p ) const
+{
+ return (p.data == data) || (p.data->linest == data->linest &&
+ p.data->width == data->width && p.data->color == data->color);
+}
+
+
+/*****************************************************************************
+ TQPen stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQPen
+
+ Writes the pen \a p to the stream \a s and returns a reference to
+ the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQPen &p )
+{
+ // ### width() should not be restricted to 8-bit values
+ if ( s.version() < 3 )
+ return s << (TQ_UINT8)p.style() << (TQ_UINT8)p.width() << p.color();
+ else
+ return s << (TQ_UINT8)( p.style() | p.capStyle() | p.joinStyle() )
+ << (TQ_UINT8)p.width() << p.color();
+}
+
+/*!
+ \relates TQPen
+
+ Reads a pen from the stream \a s into \a p and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQPen &p )
+{
+ TQ_UINT8 style, width;
+ TQColor color;
+ s >> style;
+ s >> width;
+ s >> color;
+ p = TQPen( color, (uint)width, (TQt::PenStyle)style ); // owl
+ return s;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*****************************************************************************
+ TQBrush member functions
+ *****************************************************************************/
+
+/*!
+ \class TQBrush tqbrush.h
+
+ \brief The TQBrush class defines the fill pattern of tqshapes drawn by a TQPainter.
+
+ \ingroup graphics
+ \ingroup images
+ \ingroup shared
+
+ A brush has a style and a color. One of the brush styles is a
+ custom pattern, which is defined by a TQPixmap.
+
+ The brush style defines the fill pattern. The default brush style
+ is \c NoBrush (depending on how you construct a brush). This style
+ tells the painter to not fill tqshapes. The standard style for
+ filling is \c SolidPattern.
+
+ The brush color defines the color of the fill pattern. The TQColor
+ documentation lists the predefined colors.
+
+ Use the TQPen class for specifying line/outline styles.
+
+ Example:
+ \code
+ TQPainter painter;
+ TQBrush brush( yellow ); // yellow solid pattern
+ painter.begin( &anyPaintDevice ); // paint something
+ painter.setBrush( brush ); // set the yellow brush
+ painter.setPen( NoPen ); // do not draw outline
+ painter.drawRect( 40,30, 200,100 ); // draw filled rectangle
+ painter.setBrush( NoBrush ); // do not fill
+ painter.setPen( black ); // set black pen, 0 pixel width
+ painter.drawRect( 10,10, 30,20 ); // draw rectangle outline
+ painter.end(); // painting done
+ \endcode
+
+ See the setStyle() function for a complete list of brush styles.
+
+ \img brush-styles.png Brush Styles
+
+ \sa TQPainter, TQPainter::setBrush(), TQPainter::setBrushOrigin()
+*/
+
+inline TQPixmap *TQBrush::pixmap() const {
+ if (style() != Qt::TexturePattern)
+ return 0;
+ QTexturedBrushData *data = static_cast<QTexturedBrushData*>(d.data());
+ QPixmap &pixmap = data->pixmap();
+ return pixmap.isNull() ? 0 : &pixmap;
+}
+
+/*!
+ \internal
+ Initializes the brush.
+*/
+
+void TQBrush::init( const TQColor &color, BrushStyle style )
+{
+ data = new TQBrushData;
+ TQ_CHECK_PTR( data );
+ data->style = style;
+ data->color = color;
+ data->pixmap = 0;
+}
+
+/*!
+ Constructs a default black brush with the style \c NoBrush (will
+ not fill tqshapes).
+*/
+
+TQBrush::TQBrush()
+{
+ static TQBrushData* defBrushData = 0;
+ if ( !defBrushData ) {
+ static TQSharedCleanupHandler<TQBrushData> defBrushCleanup;
+ defBrushData = new TQBrushData;
+ defBrushData->style = NoBrush;
+ defBrushData->color = TQt::black;
+ defBrushData->pixmap = 0;
+ defBrushCleanup.set( &defBrushData );
+ }
+ data = defBrushData;
+ data->ref();
+}
+
+/*!
+ Constructs a black brush with the style \a style.
+
+ \sa setStyle()
+*/
+
+TQBrush::TQBrush( BrushStyle style )
+{
+ init( TQt::black, style );
+}
+
+/*!
+ Constructs a brush with the color \a color and the style \a style.
+
+ \sa setColor(), setStyle()
+*/
+
+TQBrush::TQBrush( const TQColor &color, BrushStyle style )
+{
+ init( color, style );
+}
+
+/*!
+ Constructs a brush with the color \a color and a custom pattern
+ stored in \a pixmap.
+
+ The color will only have an effect for monochrome pixmaps, i.e.
+ for TQPixmap::depth() == 1.
+
+ Pixmap brushes are currently not supported when printing on X11.
+
+ \sa setColor(), setPixmap()
+*/
+
+TQBrush::TQBrush( const TQColor &color, const TQPixmap &pixmap )
+{
+ init( color, CustomPattern );
+ setPixmap( pixmap );
+}
+
+/*!
+ Constructs a brush that is a \link shclass.html shallow
+ copy\endlink of \a b.
+*/
+
+TQBrush::TQBrush( const TQBrush &b )
+{
+ data = b.data;
+ data->ref();
+}
+
+/*!
+ Destroys the brush.
+*/
+
+TQBrush::~TQBrush()
+{
+ if ( data->deref() ) {
+ delete data->pixmap;
+ delete data;
+ }
+}
+
+
+/*!
+ Detaches from shared brush data to make sure that this brush is
+ the only one referring the data.
+
+ If multiple brushes share common data, this brush dereferences the
+ data and gets a copy of the data. Nothing is done if there is just
+ a single reference.
+*/
+
+void TQBrush::detach()
+{
+ if ( data->count != 1 )
+ *this = copy();
+}
+
+
+/*!
+ Assigns \a b to this brush and returns a reference to this brush.
+*/
+
+TQBrush &TQBrush::operator=( const TQBrush &b )
+{
+ b.data->ref(); // beware of b = b
+ if ( data->deref() ) {
+ delete data->pixmap;
+ delete data;
+ }
+ data = b.data;
+ return *this;
+}
+
+
+/*!
+ Returns a \link shclass.html deep copy\endlink of the brush.
+*/
+
+TQBrush TQBrush::copy() const
+{
+ if ( data->style == CustomPattern ) { // brush has pixmap
+ TQBrush b( data->color, *data->pixmap );
+ return b;
+ } else { // brush has std pattern
+ TQBrush b( data->color, data->style );
+ return b;
+ }
+}
+
+
+/*!
+ \fn BrushStyle TQBrush::style() const
+
+ Returns the brush style.
+
+ \sa setStyle()
+*/
+
+/*!
+ Sets the brush style to \a s.
+
+ The brush styles are:
+ \table
+ \header \i Pattern \i Meaning
+ \row \i NoBrush \i will not fill tqshapes (default).
+ \row \i SolidPattern \i solid (100%) fill pattern.
+ \row \i Dense1Pattern \i11 94% fill pattern.
+ \row \i Dense2Pattern \i11 88% fill pattern.
+ \row \i Dense3Pattern \i11 63% fill pattern.
+ \row \i Dense4Pattern \i11 50% fill pattern.
+ \row \i Dense5Pattern \i11 37% fill pattern.
+ \row \i Dense6Pattern \i11 12% fill pattern.
+ \row \i Dense7Pattern \i11 6% fill pattern.
+ \row \i HorPattern \i horizontal lines pattern.
+ \row \i VerPattern \i vertical lines pattern.
+ \row \i CrossPattern \i crossing lines pattern.
+ \row \i BDiagPattern \i diagonal lines (directed /) pattern.
+ \row \i FDiagPattern \i diagonal lines (directed \) pattern.
+ \row \i DiagCrossPattern \i diagonal crossing lines pattern.
+ \row \i CustomPattern \i set when a pixmap pattern is being used.
+ \endtable
+
+ On Windows, dense and custom patterns cannot be transtqparent.
+
+ See the \link #details Detailed Description\endlink for a picture
+ of all the styles.
+
+ \sa style()
+*/
+
+void TQBrush::setStyle( BrushStyle s ) // set brush style
+{
+ if ( data->style == s )
+ return;
+#if defined(TQT_CHECK_RANGE)
+ if ( s == CustomPattern )
+ qWarning( "TQBrush::setStyle: CustomPattern is for internal use" );
+#endif
+ detach();
+ data->style = s;
+}
+
+
+/*!
+ \fn const TQColor &TQBrush::color() const
+
+ Returns the brush color.
+
+ \sa setColor()
+*/
+
+/*!
+ Sets the brush color to \a c.
+
+ \sa color(), setStyle()
+*/
+
+void TQBrush::setColor( const TQColor &c )
+{
+ detach();
+ data->color = c;
+}
+
+
+/*!
+ \fn TQPixmap *TQBrush::pixmap() const
+
+ Returns a pointer to the custom brush pattern, or 0 if no custom
+ brush pattern has been set.
+
+ \sa setPixmap()
+*/
+
+/*!
+ Sets the brush pixmap to \a pixmap. The style is set to \c
+ CustomPattern.
+
+ The current brush color will only have an effect for monochrome
+ pixmaps, i.e. for TQPixmap::depth() == 1.
+
+ Pixmap brushes are currently not supported when printing on X11.
+
+ \sa pixmap(), color()
+*/
+
+void TQBrush::setPixmap( const TQPixmap &pixmap )
+{
+ detach();
+ if ( data->pixmap )
+ delete data->pixmap;
+ if ( pixmap.isNull() ) {
+ data->style = NoBrush;
+ data->pixmap = 0;
+ } else {
+ data->style = CustomPattern;
+ data->pixmap = new TQPixmap( pixmap );
+ if ( data->pixmap->optimization() == TQPixmap::MemoryOptim )
+ data->pixmap->setOptimization( TQPixmap::NormalOptim );
+ }
+}
+
+
+/*!
+ \fn bool TQBrush::operator!=( const TQBrush &b ) const
+
+ Returns TRUE if the brush is different from \a b; otherwise
+ returns FALSE.
+
+ Two brushes are different if they have different styles, colors or
+ pixmaps.
+
+ \sa operator==()
+*/
+
+/*!
+ Returns TRUE if the brush is equal to \a b; otherwise returns
+ FALSE.
+
+ Two brushes are equal if they have equal styles, colors and
+ pixmaps.
+
+ \sa operator!=()
+*/
+
+bool TQBrush::operator==( const TQBrush &b ) const
+{
+ return (b.data == data) || (b.data->style == data->style &&
+ b.data->color == data->color &&
+ b.data->pixmap == data->pixmap);
+}
+
+
+/*!
+ \fn inline double TQPainter::translationX() const
+ \internal
+*/
+
+/*!
+ \fn inline double TQPainter::translationY() const
+ \internal
+*/
+
+
+/*****************************************************************************
+ TQBrush stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQBrush
+
+ Writes the brush \a b to the stream \a s and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQBrush &b )
+{
+ s << (TQ_UINT8)b.style() << b.color();
+ if ( b.style() == TQt::CustomPattern )
+#ifndef TQT_NO_IMAGEIO
+ s << *b.pixmap();
+#else
+ qWarning("No Image Brush I/O");
+#endif
+ return s;
+}
+
+/*!
+ \relates TQBrush
+
+ Reads the brush \a b from the stream \a s and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQBrush &b )
+{
+ TQ_UINT8 style;
+ TQColor color;
+ s >> style;
+ s >> color;
+ if ( style == TQt::CustomPattern ) {
+#ifndef TQT_NO_IMAGEIO
+ TQPixmap pm;
+ s >> pm;
+ b = TQBrush( color, pm );
+#else
+ qWarning("No Image Brush I/O");
+#endif
+ }
+ else
+ b = TQBrush( color, (TQt::BrushStyle)style );
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqpainter.cpp~ b/tqtinterface/qt4/src/kernel/tqpainter.cpp~
new file mode 100644
index 0000000..44e7577
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpainter.cpp~
@@ -0,0 +1,5161 @@
+#include "tqpainter.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqpainter.h"
+#include "tqimage.h"
+#include "Qt/qpaintengine.h"
+
+// #include <private/qpainter_p.h>
+
+QT_BEGIN_NAMESPACE
+
+// TAKEN FROM QT4 qbrush.cpp
+// THIS BLOCK MAY NEED TO BE UPDATED FROM TIME TO TIME
+// BEGIN BLOCK
+struct QTexturedBrushData : public QBrushData
+{
+ QTexturedBrushData() {
+ m_has_pixmap_texture = false;
+ m_pixmap = 0;
+ }
+ ~QTexturedBrushData() {
+ delete m_pixmap;
+ }
+
+ void setPixmap(const QPixmap &pm) {
+ delete m_pixmap;
+
+ if (pm.isNull()) {
+ m_pixmap = 0;
+ m_has_pixmap_texture = false;
+ } else {
+ m_pixmap = new QPixmap(pm);
+ m_has_pixmap_texture = true;
+ }
+
+ m_image = QImage();
+ }
+
+ void setImage(const QImage &image) {
+ m_image = image;
+ delete m_pixmap;
+ m_pixmap = 0;
+ m_has_pixmap_texture = false;
+ }
+
+ QPixmap &pixmap() {
+ if (!m_pixmap) {
+ m_pixmap = new QPixmap(QPixmap::fromImage(m_image));
+ }
+ return *m_pixmap;
+ }
+
+ QImage &image() {
+ if (m_image.isNull() && m_pixmap)
+ m_image = m_pixmap->toImage();
+ return m_image;
+ }
+
+ QPixmap *m_pixmap;
+ QImage m_image;
+ bool m_has_pixmap_texture;
+};
+// END BLOCK
+
+/*!
+ \class TQPainter
+ \brief The TQPainter class is a Qt 3 compatibility wrapper for QPainter.
+
+ \compat
+
+ Prior to Qt 4, QPainter specialized the pen drawing for rectangle
+ based functions (in particular: drawRect, drawEllipse,
+ drawRoundRect, drawArc, drawChord and drawPie). When stroking a
+ rectangle of width 10, the pen would draw a rectangle of width 10.
+ Drawing a polygon defined by the corner points of the same
+ rectangle the stroke would have a width of 11.
+
+ The reason for this is best explained using the picture below:
+
+ \img q3painter_rationale.png
+
+ As we can see, stroking the rectangle so it gets a width of 10,
+ means the pen is drawn on a rectangle on width 9. The polygon,
+ however follows a consistent model.
+
+ In Qt 4, all rectangle based functions have changed to follow the
+ polygon approach, which means that the rectangle defines the size of
+ the fill, and the pen follows the edges of the shape. For pen widths
+ of 0 and 1 this means that the stroke will be inside the shape on the
+ left and the top and outside on the bottom and right.
+
+ The reason for the change in Qt 4 is so that we provide consistency
+ for all drawing functions even with complex transformations.
+*/
+
+TQPainter::TQPainter() : QPainter(), has_qwidget(FALSE), current_penpos(0,0) {
+}
+
+TQPainter::TQPainter( const QWidget *pdev, bool unclipped) : QPainter((QWidget*)pdev), has_qwidget(TRUE), current_penpos(0,0) {
+ qwidget_ptr = (QWidget*)pdev;
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+}
+
+TQPainter::TQPainter( QPaintDevice *pdev, bool unclipped) : QPainter(pdev), has_qwidget(FALSE), current_penpos(0,0) {
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+}
+
+TQPainter::TQPainter( QWidget *pdev, const QWidget *w, bool unclipped) : QPainter(pdev), has_qwidget(TRUE), current_penpos(0,0) {
+ qwidget_ptr = pdev;
+ initFrom(w);
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+}
+
+TQPainter::TQPainter( QPaintDevice *pdev, const QWidget *w, bool unclipped ) : QPainter(pdev), has_qwidget(FALSE), current_penpos(0,0) {
+ initFrom(w);
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+}
+
+// [FIXME]
+void TQPainter::flush() {
+ printf("[WARNING] void TQPainter::flush() unimplemented\n\r");
+}
+
+// [FIXME]
+void TQPainter::flush( const TQRegion &region, TQPainter::CoordinateMode cm ) {
+ printf("[WARNING] void TQPainter::flush( const TQRegion &region, CoordinateMode cm = CoordDevice ) unimplemented\n\r");
+}
+
+void TQPainter::setBrush(const QBrush &brush) {
+ return QPainter::setBrush(brush);
+}
+
+void TQPainter::setBrush(Qt::BrushStyle style) {
+ return QPainter::setBrush(style);
+}
+
+void TQPainter::setBrush(TQt::BrushStyle style) {
+ this->QPainter::setBrush((Qt::BrushStyle)style);
+}
+
+TQPoint TQPainter::pos() const {
+ return current_penpos;
+}
+
+bool TQPainter::tqbegin( QPaintDevice *pdev, bool unclipped ) {
+ bool ret = begin(pdev);
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+ return ret;
+}
+
+bool TQPainter::tqbegin( QPaintDevice *pdev, const QWidget *init, bool unclipped ) {
+ bool ret = begin(pdev);
+ initFrom(init);
+ if (unclipped) {
+ printf("[WARNING] Qt4 does not support drawing under child widgets in TQPainter via the unclipped==TRUE flag in any form! Blame Nokia and change your code...\n\r");
+ fflush(stdout);
+ }
+ return ret;
+}
+
+QRectF TQPainter::boundingRect(const QRectF &rect, int flags, const QString &text) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ QRectF tqbr = QPainter::boundingRect(rect, flags, text);
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+QRect TQPainter::boundingRect(const QRect &rect, int flags, const QString &text) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ QRect tqbr = QPainter::boundingRect(rect, flags, text);
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+QRect TQPainter::boundingRect(int x, int y, int w, int h, int flags, const QString &text) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ QRect tqbr = QPainter::boundingRect(x, y, w, h, flags, text);
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+QRectF TQPainter::boundingRect(const QRectF &rect, const QString &text, const QTextOption &o) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ QRectF tqbr = QPainter::boundingRect(rect, text, o);
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+TQRect TQPainter::boundingRect(const QRect &rect, int flags, const QString &text, int len) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ TQRect tqbr = QPainter::boundingRect(rect, flags, text.left(len));
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+TQRect TQPainter::boundingRect(int x, int y, int w, int h, int flags, const QString &text, int len) {
+ TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ TQRect tqbr = QPainter::boundingRect(QRect(x, y, w, h), flags, text.left(len));
+ TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL
+ return tqbr;
+}
+
+void TQPainter::drawText(const QPointF &p, const QString &s) {
+ QPainter::drawText(p, s);
+}
+
+void TQPainter::drawText(const QPoint &p, const QString &s) {
+ QPainter::drawText(p, s);
+}
+
+void TQPainter::drawText(int x, int y, const QString &s) {
+ QPainter::drawText(x, y, s);
+}
+
+void TQPainter::drawText(const QPointF &p, const QString &str, int tf, int justificationPadding) {
+ QPainter::drawText(p, str, tf, justificationPadding);
+}
+
+void TQPainter::drawText(const QRectF &r, int flags, const QString &text, QRectF *br) {
+ QPainter::drawText(r, flags, text, br);
+}
+
+void TQPainter::drawText(const QRect &r, int flags, const QString &text, QRect *br) {
+ QPainter::drawText(r, flags, text, br);
+}
+
+void TQPainter::drawText(int x, int y, int w, int h, int flags, const QString &text, QRect *br) {
+ QPainter::drawText(x, y, w, h, flags, text, br);
+}
+
+void TQPainter::drawText(const QRectF &r, const QString &text, const QTextOption &o) {
+ QPainter::drawText(r, text, o);
+}
+
+void TQPainter::drawText( int x, int y, const TQString &s, int len, TextDirection dir ) {
+ Qt::LayoutDirection old = layoutDirection();
+ if (dir == RTL)
+ setLayoutDirection(Qt::RightToLeft);
+ else if (dir == LTR)
+ setLayoutDirection(Qt::LeftToRight);
+ QPainter::drawText(x, y, s.left(len));
+ setLayoutDirection(old);
+}
+void TQPainter::drawText( const TQPoint &p, const TQString &s, int len, TextDirection dir ) {
+ Qt::LayoutDirection old = layoutDirection();
+ if (dir == RTL)
+ setLayoutDirection(Qt::RightToLeft);
+ else if (dir == LTR)
+ setLayoutDirection(Qt::LeftToRight);
+ QPainter::drawText(p, s.left(len));
+ setLayoutDirection(old);
+}
+void TQPainter::drawText( int x, int y, const TQString &s, int pos, int len, TextDirection dir ) {
+ Qt::LayoutDirection old = layoutDirection();
+ if (dir == RTL)
+ setLayoutDirection(Qt::RightToLeft);
+ else if (dir == LTR)
+ setLayoutDirection(Qt::LeftToRight);
+ QPainter::drawText(x, y, s.mid(pos, len));
+ setLayoutDirection(old);
+}
+void TQPainter::drawText( const TQPoint &p, const TQString &s, int pos, int len, TextDirection dir ) {
+ Qt::LayoutDirection old = layoutDirection();
+ if (dir == RTL)
+ setLayoutDirection(Qt::RightToLeft);
+ else if (dir == LTR)
+ setLayoutDirection(Qt::LeftToRight);
+ QPainter::drawText(p, s.mid(pos, len));
+ setLayoutDirection(old);
+}
+
+void TQPainter::drawText(int x, int y, const QString &s, int pos, int len) {
+ drawText(x, y, s.mid(pos, len));
+}
+
+void TQPainter::drawText(const QPoint &p, const QString &s, int pos, int len) {
+ drawText(p, s.mid(pos, len));
+}
+
+void TQPainter::drawText(int x, int y, const QString &s, int len) {
+ drawText(x, y, s.left(len));
+}
+
+void TQPainter::drawText(const QPoint &p, const QString &s, int len) {
+ drawText(p, s.left(len));
+}
+
+void TQPainter::drawText(const QRect &r, int flags, const QString &str, int len, QRect *br) {
+ drawText(r, flags, str.left(len), br);
+}
+
+void TQPainter::drawText(int x, int y, int w, int h, int flags, const QString &text, int len, QRect *br) {
+ drawText(QRect(x, y, w, h), flags, text.left(len), br);
+}
+
+int *TQPainter::tabArray() const
+{
+ printf("[WARNING] TQPainter::tabArray unimplemented!\n\r");
+}
+
+void TQPainter::setTabArray( int *ta )
+{
+ printf("[WARNING] TQPainter::setTabArray unimplemented!\n\r");
+
+// #if defined(TQT_CHECK_STATE)
+// if ( !isActive() )
+// qWarning( "TQPainter::setTabArray: Will be reset by begin()" );
+// #endif
+// if ( ta != tabarray ) {
+// tabarraylen = 0;
+// if ( tabarray ) // Avoid purify complaint
+// delete [] tabarray; // delete old array
+// if ( ta ) { // tabarray = copy of 'ta'
+// while ( ta[tabarraylen] )
+// tabarraylen++;
+// tabarraylen++; // and 0 terminator
+// tabarray = new int[tabarraylen]; // duplicate ta
+// memcpy( tabarray, ta, sizeof(int)*tabarraylen );
+// } else {
+// tabarray = 0;
+// }
+// }
+// if ( isActive() && testf(ExtDev) ) { // tell extended tqdevice
+// TQPDevCmdParam param[2];
+// param[0].ival = tabarraylen;
+// param[1].ivec = tabarray;
+// pdev->cmd( TQPaintDevice::PdcSetTabArray, this, param );
+// }
+}
+
+void TQPainter::drawImage( int x, int y, const TQImage image, int sx, int sy, int sw, int sh, int conversionFlags ) {
+ QPainter::drawImage(x, y, image, sx, sy, sw, sh, (Qt::ImageConversionFlags)conversionFlags);
+}
+
+void TQPainter::drawImage( const TQPoint p, const TQImage image, const TQRect sr, int conversionFlags ) {
+ QPainter::drawImage(p, image, sr, (Qt::ImageConversionFlags)conversionFlags);
+}
+
+void TQPainter::drawImage( const TQPoint p, const TQImage image, int conversion_flags ) {
+ TQ_UNUSED(conversion_flags);
+ QPainter::drawImage(p, image);
+}
+
+void TQPainter::drawImage( const TQRect r, const TQImage image ) {
+ QPainter::drawImage(r, image);
+}
+
+void TQPainter::resetXForm() {
+ resetTransform();
+}
+
+// [FIXME] The drawWinFocusRect methods below probably need tweaking to exactly match the old Qt3 behaviour
+void TQPainter::drawWinFocusRect( int x, int y, int w, int h ) {
+ drawWinFocusRect( x, y, w, h, TRUE, TQt::color0 );
+}
+
+void TQPainter::drawWinFocusRect( int x, int y, int w, int h, const TQColor &bgColor ) {
+ drawWinFocusRect( x, y, w, h, FALSE, bgColor );
+}
+
+void TQPainter::drawWinFocusRect( const TQRect &tqr ) {
+ drawWinFocusRect( tqr.x(), tqr.y(), tqr.width(), tqr.height() );
+}
+
+void TQPainter::drawWinFocusRect( const TQRect &tqr, const TQColor &bgColor ) {
+ drawWinFocusRect( tqr.x(), tqr.y(), tqr.width(), tqr.height(), bgColor );
+}
+
+void TQPainter::setBackgroundColor(const QColor &color) {
+ setBackground(color);
+}
+
+const QColor &TQPainter::backgroundColor() const {
+ return background().color();
+}
+
+void TQPainter::setClipRect(const QRectF &qrf, Qt::ClipOperation op) {
+ QPainter::setClipRect(qrf, op);
+}
+
+void TQPainter::setClipRect(const QRect &qr, Qt::ClipOperation op) {
+ QPainter::setClipRect(qr, op);
+}
+
+void TQPainter::setClipRect( int x, int y, int w, int h, TQPainter::CoordinateMode cm ) {
+ TQRect r(x, y, w, h);
+ setClipRect(r, cm);
+}
+
+void TQPainter::redirect(QPaintDevice *pdev, QPaintDevice *replacement) {
+ if (replacement == 0) {
+ restoreRedirected(pdev);
+ }
+ else {
+ setRedirected(pdev, replacement);
+ }
+}
+
+TQPaintDevice *TQPainter::redirect(QPaintDevice *pdev) {
+ return static_cast<TQPaintDevice*>(const_cast<QPaintDevice*>(redirected(pdev)));
+}
+
+void TQPainter::setWorldXForm(bool enabled) {
+ setMatrixEnabled(enabled);
+}
+
+bool TQPainter::hasWorldXForm() const {
+ return matrixEnabled();
+}
+
+void TQPainter::setViewXForm(bool enabled) {
+ setViewTransformEnabled(enabled);
+}
+
+bool TQPainter::hasViewXForm() const {
+ return viewTransformEnabled();
+}
+
+// [FIXME]
+void TQPainter::initialize() {
+ printf("[WARNING] TQColor static void initialize() not implemented\n\r");
+}
+
+// [FIXME]
+void TQPainter::cleanup() {
+ printf("[WARNING] TQColor static void cleanup() not implemented\n\r");
+}
+
+void TQPainter::moveTo( const TQPoint &p )
+{
+ moveTo( p.x(), p.y() );
+}
+
+void TQPainter::lineTo( const TQPoint &p )
+{
+ lineTo( p.x(), p.y() );
+}
+
+void TQPainter::drawRect(const QRect &r)
+{
+ QPainter::drawRect(adjustedRectangle(r));
+}
+
+void TQPainter::drawEllipse(const QRect &r)
+{
+ QPainter::drawEllipse(adjustedRectangle(r));
+}
+
+void TQPainter::drawRoundRect(const QRect &r, int xrnd, int yrnd)
+{
+ QPainter::drawRoundRect(adjustedRectangle(r), xrnd, yrnd);
+}
+
+void TQPainter::drawArc(const QRect &r, int angle, int arcLength)
+{
+ QPainter::drawArc(adjustedRectangle(r), angle, arcLength);
+}
+
+void TQPainter::drawPie(const QRect &r, int angle, int arcLength)
+{
+ QPainter::drawPie(adjustedRectangle(r), angle, arcLength);
+}
+
+void TQPainter::drawChord(const QRect &r, int angle, int arcLength)
+{
+ QPainter::drawChord(adjustedRectangle(r), angle, arcLength);
+}
+
+void TQPainter::tqdrawTextItem( const TQPoint& p, const TQTextItem &ti, int textflags )
+{
+ tqdrawTextItem( p.x(), p.y(), ti, textflags );
+}
+
+// [FIXME]
+// Verify these mappings...
+// They will need to be kept in sync with the code inside tqpainter_x11.cpp
+TQt::RasterOp TQPainter::rasterOp() const
+{
+ TQt::RasterOp cm;
+ switch (rop) {
+ case QPainter::CompositionMode_SourceOver:
+ cm=CopyROP;
+ break;
+ case QPainter::RasterOp_SourceOrDestination:
+ cm=OrROP;
+ break;
+ case QPainter::RasterOp_SourceXorDestination:
+ cm=XorROP;
+ break;
+ case QPainter::RasterOp_NotSourceAndDestination:
+ cm=NotAndROP;
+ break;
+ case QPainter::RasterOp_NotSource:
+ cm=NotCopyROP;
+ break;
+ case QPainter::RasterOp_NotSourceXorDestination:
+ cm=NotXorROP;
+ break;
+ case QPainter::RasterOp_SourceAndDestination:
+ cm=AndROP;
+ break;
+ case QPainter::CompositionMode_Clear:
+ cm=ClearROP;
+ break;
+ case QPainter::CompositionMode_Destination:
+ cm=NopROP;
+ break;
+ case QPainter::RasterOp_SourceAndNotDestination:
+ cm=AndNotROP;
+ break;
+ case QPainter::RasterOp_NotSourceOrNotDestination:
+ cm=NandROP;
+ break;
+ case QPainter::RasterOp_NotSourceAndNotDestination:
+ cm=NorROP;
+ break;
+ default:
+ cm=CopyROP;
+ break;
+ }
+ return cm;
+}
+
+/*!
+ \fn TQPainter::TQPainter()
+
+ Constructs a TQPainter.
+*/
+
+/*!
+ \fn TQPainter::TQPainter(QPaintDevice *pdev)
+
+ Constructs a TQPainter that operates on tqdevice \a pdev.
+*/
+
+/*!
+ \internal
+*/
+
+int TQPainter::rectSubtraction() const {
+ return pen().style() != Qt::NoPen && pen().width() == 0 ? 1 : 0;
+}
+
+/*!
+ \internal
+*/
+QRect TQPainter::adjustedRectangle(const QRect &r)
+{
+ QRect rect = r.normalized();
+ int subtract = rectSubtraction();
+ if (subtract != 0)
+ rect.setSize(QSize(rect.width() - subtract, rect.height() - subtract));
+ return rect;
+}
+
+
+/*!
+ \fn void TQPainter::drawRect(int x, int y, int w, int h)
+
+ \overload
+
+ Draws the rectangle that fits inside the bounds specified by \a x,
+ \a y, \a w and \a h using the current pen and brush.
+*/
+
+/*!
+ \fn void TQPainter::drawRect(const QRect &r)
+
+ Draws a rectangle that fits inside the rectangle \a r using the
+ current pen and brush.
+
+*/
+
+
+
+/*!
+ \fn TQPainter::drawEllipse(const QRect &r)
+
+ Draws the ellipse that fits inside the bounds \a r using the
+ current pen and brush.
+
+*/
+
+/*!
+ \fn TQPainter::drawEllipse(int x, int y, int width, int height)
+
+ \overload
+
+ Draws an ellipse that fits inside the bounds specified by \a x,
+ \a y, \a width and \a height using the current pen and brush.
+
+*/
+
+/*!
+ \fn void TQPainter::drawPie(int x, int y, int w, int h, int
+ startAngle, int spanAngle)
+
+ \overload
+
+ Draws a pie segment that fits inside the bounds (\a{x}, \a{y},
+ \a{w}, \a{h}) with the given \a startAngle and \a spanAngle.
+*/
+
+/*!
+ \fn void TQPainter::drawPie(const QRect &r, int a, int alen)
+
+ Draws a pie defined by the rectangle \a r, the start angle \a a
+ and the arc length \a alen.
+
+ The pie is filled with the current brush().
+
+ The angles \a a and \a alen are 1/16th of a degree, i.e. a full
+ circle equals 5760 (16*360). Positive values of \a a and \a alen
+ mean counter-clockwise while negative values mean the clockwise
+ direction. Zero degrees is at the 3 o'clock position.
+
+ \sa drawArc(), drawChord()
+*/
+
+/*!
+ \fn void TQPainter::drawArc(int x, int y, int w, int h, int
+ startAngle, int spanAngle)
+
+ \overload
+
+ Draws the arc that fits inside the rectangle (\a{x}, \a{y}, \a{w},
+ \a{h}), with the given \a startAngle and \a spanAngle.
+*/
+
+/*!
+ \fn void TQPainter::drawArc(const QRect &r, int a, int alen)
+
+ Draws an arc defined by the rectangle \a r, the start angle \a a
+ and the arc length \a alen.
+
+ The angles \a a and \a alen are 1/16th of a degree, i.e. a full
+ circle equals 5760 (16*360). Positive values of \a a and \a alen
+ mean counter-clockwise while negative values mean the clockwise
+ direction. Zero degrees is at the 3 o'clock position.
+
+ Example:
+ \snippet doc/src/snippets/code/src_qt3support_painting_q3painter.cpp 0
+
+ \sa drawPie(), drawChord()
+*/
+
+/*!
+ \fn void TQPainter::drawChord(int x, int y, int w, int h, int
+ startAngle, int spanAngle)
+
+ \overload
+
+ Draws a chord that fits inside the rectangle (\a{x}, \a{y}, \a{w},
+ \a{h}) with the given \a startAngle and \a spanAngle.
+*/
+
+
+/*!
+ \fn void TQPainter::drawChord(const QRect &r, int a, int alen)
+
+ Draws a chord defined by the rectangle \a r, the start angle \a a
+ and the arc length \a alen.
+
+ The chord is filled with the current brush().
+
+ The angles \a a and \a alen are 1/16th of a degree, i.e. a full
+ circle equals 5760 (16*360). Positive values of \a a and \a alen
+ mean counter-clockwise while negative values mean the clockwise
+ direction. Zero degrees is at the 3 o'clock position.
+
+ \sa drawArc(), drawPie()
+*/
+
+/*!
+ \fn void TQPainter::drawRoundRect(const QRect &r, int xrnd, int yrnd)
+
+ Draws a rounded rect that fits into the bounds \a r using the current
+ pen and brush. The parameters \a xrnd and \a yrnd specifies the roundness
+ in x and y direction.
+*/
+
+/*!
+ \fn void TQPainter::drawRoundRect(int x, int y, int w, int h, int xrnd, int yrnd)
+
+ \overload
+
+ Draws a rounded rect that fits into the bounds \a x, \a y, \a w
+ and \a h using the current pen and brush. The parameters \a xrnd
+ and \a yrnd specifies the roundness in x and y direction.
+*/
+
+/*!
+ \fn void QPainter::drawLineSegments(const QPolygon &polygon, int
+ index, int count)
+
+ Draws \a count separate lines from points defined by the \a
+ polygon, starting at \a{polygon}\e{[index]} (\a index defaults to
+ 0). If \a count is -1 (the default) all points until the end of
+ the array are used.
+
+ Use drawLines() combined with QPolygon::constData() instead.
+
+ \oldcode
+ QPainter painter(this);
+ painter.drawLineSegments(polygon, index, count);
+ \newcode
+ int lineCount = (count == -1) ? (polygon.size() - index) / 2 : count;
+
+ QPainter painter(this);
+ painter.drawLines(polygon.constData() + index * 2, lineCount);
+ \endcode
+*/
+
+void TQPainter::drawLineSegments(const QPolygon &polygon, int index, int count)
+{
+ int lineCount = (count == -1) ? (polygon.size() - index) / 2 : count;
+
+ drawLines(polygon.constData() + index * 2, lineCount);
+}
+
+/*!
+ \obsolete
+
+ Use the worldTransform() combined with QTransform::dx() instead.
+
+ \oldcode
+ QPainter painter(this);
+ qreal x = painter.translationX();
+ \newcode
+ QPainter painter(this);
+ qreal x = painter.worldTransform().dx();
+ \endcode
+*/
+qreal TQPainter::translationX() const
+{
+ return worldTransform().dx();
+}
+
+/*!
+ \obsolete
+
+ Use the worldTransform() combined with QTransform::dy() instead.
+
+ \oldcode
+ QPainter painter(this);
+ qreal y = painter.translationY();
+ \newcode
+ QPainter painter(this);
+ qreal y = painter.worldTransform().dy();
+ \endcode
+*/
+qreal TQPainter::translationY() const
+{
+ return worldTransform().dy();
+}
+
+/*!
+ \fn void TQPainter::map(int x, int y, int *rx, int *ry) const
+
+ \internal
+
+ Sets (\a{rx}, \a{ry}) to the point that results from applying the
+ painter's current transformation on the point (\a{x}, \a{y}).
+*/
+void TQPainter::map(int x, int y, int *rx, int *ry) const
+{
+ QPoint p(x, y);
+ p = p * combinedMatrix();
+ *rx = p.x();
+ *ry = p.y();
+}
+
+/*!
+ \internal
+ Maps a rectangle from logical coordinates to device coordinates.
+ This internal function does not handle rotation and/or shear.
+*/
+
+void TQPainter::map( int x, int y, int w, int h, int *rx, int *ry, int *rw, int *rh ) const
+{
+ TQRect qr(x, y, w, h);
+ QTransform dtrans = combinedTransform();
+ TQRect tqr = dtrans.mapRect(qr);
+ *rx = tqr.x();
+ *ry = tqr.y();
+ *rw = tqr.width();
+ *rh = tqr.height();
+}
+
+/*!
+ \fn TQPoint TQPainter::xForm(const QPoint &point) const
+
+ Use combinedTransform() instead.
+*/
+
+TQPoint TQPainter::xForm(const QPoint &p) const
+{
+ if (combinedTransform().type() == QTransform::TxNone)
+ return p;
+ return p * combinedMatrix();
+}
+
+
+/*!
+ \fn TQRect TQPainter::xForm(const QRect &rectangle) const
+ \overload
+
+ Use combinedTransform() instead of this function and call
+ mapRect() on the result to obtain a QRect.
+*/
+
+TQRect TQPainter::xForm(const QRect &r) const
+{
+ if (combinedTransform().type() == QTransform::TxNone)
+ return r;
+ return combinedMatrix().mapRect(r);
+}
+
+bool TQPainter::testf( uint b ) const {
+// printf("[WARNING] QPainter::testf() disabled\n\r");
+// return 0;
+
+ // Map to Qt4 flags and functions...
+ if ((b&IsActive)!=0) {
+ if (QPainter::isActive()) return TRUE;
+ }
+// if ((b&ExtDev)!=0) {
+// printf("[WARNING] Assuming ExtDev==false in QPainter::testf()\n\r");
+// }
+// if ((b&IsStartingUp)!=0) {
+// }
+// if ((b&NoCache)!=0) {
+// }
+ if ((b&VxF)!=0) {
+ if (QPainter::viewTransformEnabled()) return TRUE;
+ }
+ if ((b&WxF)!=0) {
+ if (QPainter::worldMatrixEnabled()) return TRUE;
+ }
+ if ((b&ClipOn)!=0) {
+ if (QPainter::hasClipping()) return TRUE;
+ }
+
+ printf("[WARNING] Assuming test flag 0x%x == false in QPainter::testf()\n\r", b);
+ return 0;
+}
+
+/*!
+ \fn TQPolygon TQPainter::xForm(const QPolygon &polygon) const
+ \overload
+
+ Use combinedTransform() instead.
+*/
+
+// TQPolygon TQPainter::xForm(const QPolygon &a) const
+// {
+// Q_D(const QPainter);
+// if (!d->engine) {
+// qWarning("QPainter::xForm: Painter not active");
+// return QPolygon();
+// }
+// if (d->state->matrix.type() == QTransform::TxNone)
+// return a;
+// return a * combinedMatrix();
+// }
+
+/*!
+ \fn TQPolygon TQPainter::xForm(const QPolygon &polygon, int index, int count) const
+ \overload
+
+ Use combinedTransform() combined with QPolygon::mid() instead.
+
+ \oldcode
+ QPainter painter(this);
+ QPolygon transformed = painter.xForm(polygon, index, count)
+ \newcode
+ QPainter painter(this);
+ QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform();
+ \endcode
+*/
+
+// TQPolygon TQPainter::xForm(const QPolygon &av, int index, int npoints) const
+// {
+// int lastPoint = npoints < 0 ? av.size() : index+npoints;
+// QPolygon a(lastPoint-index);
+// memcpy(a.data(), av.data()+index, (lastPoint-index)*sizeof(QPoint));
+// return a * combinedMatrix();
+// }
+
+/*!
+ \fn TQPoint TQPainter::xFormDev(const QPoint &point) const
+ \overload
+ \obsolete
+
+ Use combinedTransform() combined with QTransform::inverted() instead.
+
+ \oldcode
+ QPainter painter(this);
+ QPoint transformed = painter.xFormDev(point);
+ \newcode
+ QPainter painter(this);
+ QPoint transformed = point * painter.combinedTransform().inverted();
+ \endcode
+*/
+
+TQPoint TQPainter::xFormDev(const QPoint &p) const
+{
+ if(combinedTransform().type() == QTransform::TxNone)
+ return p;
+ return p * combinedMatrix().inverted();
+}
+
+/*!
+ \fn TQRect TQPainter::xFormDev(const QRect &rectangle) const
+ \overload
+ \obsolete
+
+ Use combinedTransform() combined with QTransform::inverted() instead.
+
+ \oldcode
+ QPainter painter(this);
+ QRect transformed = painter.xFormDev(rectangle);
+ \newcode
+ QPainter painter(this);
+ QRegion region = QRegion(rectangle) * painter.combinedTransform().inverted();
+ QRect transformed = region.boundingRect();
+ \endcode
+*/
+
+TQRect TQPainter::xFormDev(const QRect &r) const
+{
+ if (combinedTransform().type() == QTransform::TxNone)
+ return r;
+ return combinedMatrix().inverted().mapRect(r);
+}
+
+/*!
+ \overload
+
+ \fn TQPoint TQPainter::xFormDev(const QPolygon &polygon) const
+ \obsolete
+
+ Use combinedTransform() combined with QTransform::inverted() instead.
+
+ \oldcode
+ QPainter painter(this);
+ QPolygon transformed = painter.xFormDev(rectangle);
+ \newcode
+ QPainter painter(this);
+ QPolygon transformed = polygon * painter.combinedTransform().inverted();
+ \endcode
+*/
+
+// TQPolygon TQPainter::xFormDev(const QPolygon &a) const
+// {
+// Q_D(const QPainter);
+// if (!d->engine) {
+// qWarning("QPainter::xFormDev: Painter not active");
+// return QPolygon();
+// }
+// if (d->state->matrix.type() == QTransform::TxNone)
+// return a;
+// return a * combinedMatrix().inverted();
+// }
+
+/*!
+ \fn TQPolygon TQPainter::xFormDev(const QPolygon &polygon, int index, int count) const
+ \overload
+ \obsolete
+
+ Use combinedTransform() combined with QPolygon::mid() and QTransform::inverted() instead.
+
+ \oldcode
+ QPainter painter(this);
+ QPolygon transformed = painter.xFormDev(polygon, index, count);
+ \newcode
+ QPainter painter(this);
+ QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform().inverted();
+ \endcode
+*/
+
+// TQPolygon TQPainter::xFormDev(const QPolygon &ad, int index, int npoints) const
+// {
+// Q_D(const QPainter);
+// int lastPoint = npoints < 0 ? ad.size() : index+npoints;
+// QPolygon a(lastPoint-index);
+// memcpy(a.data(), ad.data()+index, (lastPoint-index)*sizeof(QPoint));
+// if (d->state->matrix.type() == QTransform::TxNone)
+// return a;
+// return a * combinedMatrix().inverted();
+// }
+
+/*! \obsolete
+ Sets the current pen position to \a (x, y)
+
+ \sa lineTo(), pos()
+*/
+
+void TQPainter::moveTo( int x, int y )
+{
+ QPainterPath path;
+ path.moveTo(x, y);
+ drawPath(path);
+ current_penpos = QPoint(x, y);
+}
+
+/*! \obsolete
+ Use drawLine() instead.
+
+ Draws a line from the current pen position to \a (x, y) and sets
+ \a (x, y) to be the new current pen position.
+
+ \sa TQPen moveTo(), drawLine(), pos()
+*/
+
+void TQPainter::lineTo( int x, int y )
+{
+ QPainterPath path;
+ path.moveTo(current_penpos.x(), current_penpos.y());
+ path.lineTo(x, y);
+ drawPath(path);
+ current_penpos = QPoint(x, y);
+}
+
+static void bitBlt_helper(QPaintDevice *dst, const QPoint &dp,
+ const QPaintDevice *src, const QRect &sr, bool)
+{
+ Q_ASSERT(dst);
+ Q_ASSERT(src);
+
+ if (src->devType() == QInternal::Pixmap) {
+ const QPixmap *pixmap = static_cast<const QPixmap *>(src);
+ QPainter pt(dst);
+ pt.drawPixmap(dp, *pixmap, sr);
+
+ } else {
+ qWarning("QPainter: bitBlt only works when source is of type pixmap");
+ }
+}
+
+void bitBlt(QPaintDevice *dst, int dx, int dy,
+ const QPaintDevice *src, int sx, int sy, int sw, int sh,
+ bool ignoreMask )
+{
+ bitBlt_helper(dst, QPoint(dx, dy), src, QRect(sx, sy, sw, sh), ignoreMask);
+}
+
+void bitBlt(QPaintDevice *dst, const QPoint &dp, const QPaintDevice *src, const QRect &sr, bool ignoreMask)
+{
+ bitBlt_helper(dst, dp, src, sr, ignoreMask);
+}
+
+void bitBlt(QPaintDevice *dst, int dx, int dy,
+ const QImage *src, int sx, int sy, int sw, int sh, int fl)
+{
+ Qt::ImageConversionFlags flags(fl);
+ QPixmap srcPixmap = QPixmap::fromImage(*src, flags);
+ bitBlt_helper(dst, QPoint(dx, dy), &srcPixmap, QRect(sx, sy, sw, sh), false);
+}
+
+const TQWMatrix &TQPainter::tqworldMatrix() const {
+ return (*(static_cast<const TQWMatrix*>(&worldMatrix())));
+}
+
+/*!
+ \fn void TQPainter::tqdrawTextItem(const TQPoint &, const TQTextItem &, int)
+ \internal
+*/
+
+static inline void fix_neg_rect( int *x, int *y, int *w, int *h )
+{
+ if ( *w < 0 ) {
+ *w = -*w + 2;
+ *x -= *w - 1;
+ }
+ if ( *h < 0 ) {
+ *h = -*h + 2;
+ *y -= *h - 1;
+ }
+}
+void TQPainter::fix_neg_rect( int *x, int *y, int *w, int *h )
+{
+ ::fix_neg_rect(x,y,w,h);
+}
+
+TQRegion TQPainter::clipRegion( CoordinateMode cm ) const {
+ QRegion qr = QPainter::clipRegion();
+ QRegion tqr = qr;
+ if (cm == CoordDevice) {
+ // Convert to device coordinates
+ QTransform dtrans = combinedTransform();
+ tqr = dtrans.map(qr);
+ }
+ return tqr;
+}
+
+void TQPainter::setClipRegion( const QRegion &qr, CoordinateMode cm ) {
+ QRegion tqr = qr;
+
+ if (cm == CoordDevice) {
+ // Convert from device coordinates
+ QTransform itrans = combinedTransform().inverted();
+ tqr = itrans.map(qr);
+
+ QPainter::setClipRegion( tqr, Qt::ReplaceClip );
+ }
+ else {
+ QPainter::setClipRegion( tqr, Qt::ReplaceClip );
+ }
+}
+
+void TQPainter::setClipRect( const TQRect &qr, CoordinateMode cm ) {
+ QRect tqr = qr;
+
+ if (cm == CoordDevice) {
+ // Convert from device coordinates
+ QTransform itrans = combinedTransform().inverted();
+ tqr = itrans.mapRect(qr);
+
+ QPainter::setClipRect( tqr, Qt::ReplaceClip );
+ }
+ else {
+ QPainter::setClipRect( tqr, Qt::ReplaceClip );
+ }
+}
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of TQPainter, TQPen and TQBrush classes
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpainter_p.h"
+#include "tqbitmap.h"
+#include "tqptrstack.h"
+#include "tqptrdict.h"
+#include "tqdatastream.h"
+#include "tqwidget.h"
+#include "tqimage.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqapplication.h"
+#include "tqrichtext_p.h"
+#include "tqregexp.h"
+#include "tqcleanuphandler.h"
+#ifdef TQ_WS_TQWS
+#include "tqgfx_qws.h"
+#endif
+#include <string.h>
+
+#include "tqtextlayout_p.h"
+#include "tqfontengine_p.h"
+
+#ifndef TQT_NO_TRANSFORMATIONS
+typedef TQPtrStack<TQWMatrix> TQWMatrixStack;
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+/*!
+ \class TQPainter tqpainter.h
+ \brief The TQPainter class does low-level painting e.g. on widgets.
+
+ \ingroup graphics
+ \ingroup images
+ \mainclass
+
+ The painter provides highly optimized functions to do most of the
+ drawing GUI programs require. TQPainter can draw everything from
+ simple lines to complex tqshapes like pies and chords. It can also
+ draw aligned text and pixmaps. Normally, it draws in a "natural"
+ coordinate system, but it can also do view and world
+ transformation.
+
+ The typical use of a painter is:
+
+ \list
+ \i Construct a painter.
+ \i Set a pen, a brush etc.
+ \i Draw.
+ \i Destroy the painter.
+ \endlist
+
+ Mostly, all this is done inside a paint event. (In fact, 99% of
+ all TQPainter use is in a reimplementation of
+ TQWidget::paintEvent(), and the painter is heavily optimized for
+ such use.) Here's one very simple example:
+
+ \code
+ void SimpleExampleWidget::paintEvent()
+ {
+ TQPainter paint( this );
+ paint.setPen( TQt::blue );
+ paint.drawText( rect(), AlignCenter, "The Text" );
+ }
+ \endcode
+
+ Usage is simple, and there are many settings you can use:
+
+ \list
+
+ \i font() is the currently set font. If you set a font that isn't
+ available, TQt tqfinds a close match. In fact font() returns what
+ you set using setFont() and fontInfo() returns the font actually
+ being used (which may be the same).
+
+ \i brush() is the currently set brush; the color or pattern that's
+ used for filling e.g. circles.
+
+ \i pen() is the currently set pen; the color or stipple that's
+ used for drawing lines or boundaries.
+
+ \i backgroundMode() is \c Opaque or \c Transtqparent, i.e. whether
+ backgroundColor() is used or not.
+
+ \i backgroundColor() only applies when backgroundMode() is Opaque
+ and pen() is a stipple. In that case, it describes the color of
+ the background pixels in the stipple.
+
+ \i rasterOp() is how pixels drawn interact with the pixels already
+ there.
+
+ \i brushOrigin() is the origin of the tiled brushes, normally the
+ origin of the window.
+
+ \i viewport(), window(), tqworldMatrix() and many more make up the
+ painter's coordinate transformation system. See \link
+ coordsys.html The Coordinate System \endlink for an explanation of
+ this, or see below for a very brief overview of the functions.
+
+ \i hasClipping() is whether the painter clips at all. (The paint
+ tqdevice clips, too.) If the painter clips, it clips to clipRegion().
+
+ \i pos() is the current position, set by moveTo() and used by
+ lineTo().
+
+ \endlist
+
+ Note that some of these settings mirror settings in some paint
+ tqdevices, e.g. TQWidget::font(). TQPainter::begin() (or the TQPainter
+ constructor) copies these attributes from the paint tqdevice.
+ Calling, for example, TQWidget::setFont() doesn't take effect until
+ the next time a painter begins painting on it.
+
+ save() saves all of these settings on an internal stack, restore()
+ pops them back.
+
+ The core functionality of TQPainter is drawing, and there are
+ functions to draw most primitives: drawPoint(), drawPoints(),
+ drawLine(), drawRect(), drawWinFocusRect(), drawRoundRect(),
+ drawEllipse(), drawArc(), drawPie(), drawChord(),
+ drawLineSegments(), drawPolyline(), drawPolygon(),
+ drawConvexPolygon() and drawCubicBezier(). All of these functions
+ take integer coordinates; there are no floating-point versions
+ since we want drawing to be as fast as possible.
+
+ There are functions to draw pixmaps/images, namely drawPixmap(),
+ drawImage() and drawTiledPixmap(). drawPixmap() and drawImage()
+ produce the same result, except that drawPixmap() is faster
+ on-screen and drawImage() faster and sometimes better on TQPrinter
+ and TQPicture.
+
+ Text drawing is done using drawText(), and when you need
+ fine-grained positioning, boundingRect() tells you where a given
+ drawText() command would draw.
+
+ There is a drawPicture() function that draws the contents of an
+ entire TQPicture using this painter. drawPicture() is the only
+ function that disregards all the painter's settings: the TQPicture
+ has its own settings.
+
+ Normally, the TQPainter operates on the tqdevice's own coordinate
+ system (usually pixels), but TQPainter has good support for
+ coordinate transformation. See \link coordsys.html The Coordinate
+ System \endlink for a more general overview and a simple example.
+
+ The most common functions used are scale(), rotate(), translate()
+ and shear(), all of which operate on the tqworldMatrix().
+ setWorldMatrix() can tqreplace or add to the currently set
+ tqworldMatrix().
+
+ setViewport() sets the rectangle on which TQPainter operates. The
+ default is the entire tqdevice, which is usually fine, except on
+ printers. setWindow() sets the coordinate system, that is, the
+ rectangle that maps to viewport(). What's drawn inside the
+ window() ends up being inside the viewport(). The window's
+ default is the same as the viewport, and if you don't use the
+ transformations, they are optimized away, gaining another little
+ bit of speed.
+
+ After all the coordinate transformation is done, TQPainter can clip
+ the drawing to an arbitrary rectangle or region. hasClipping() is
+ TRUE if TQPainter clips, and clipRegion() returns the clip region.
+ You can set it using either setClipRegion() or setClipRect().
+ Note that the clipping can be slow. It's all system-dependent,
+ but as a rule of thumb, you can assume that drawing speed is
+ inversely proportional to the number of rectangles in the clip
+ region.
+
+ After TQPainter's clipping, the paint tqdevice may also clip. For
+ example, most widgets clip away the pixels used by child widgets,
+ and most printers clip away an area near the edges of the paper.
+ This additional clipping is not reflected by the return value of
+ clipRegion() or hasClipping().
+
+ TQPainter also includes some less-used functions that are very
+ useful on those occasions when they're needed.
+
+ isActive() indicates whether the painter is active. begin() (and
+ the most usual constructor) makes it active. end() (and the
+ destructor) deactivates it. If the painter is active, tqdevice()
+ returns the paint tqdevice on which the painter paints.
+
+ Sometimes it is desirable to make someone else paint on an unusual
+ TQPaintDevice. TQPainter supports a static function to do this,
+ redirect(). We recommend not using it, but for some hacks it's
+ perfect.
+
+ setTabStops() and setTabArray() can change where the tab stops
+ are, but these are very seldomly used.
+
+ \warning Note that TQPainter does not attempt to work around
+ coordinate limitations in the underlying window system. Some
+ platforms may behave incorrectly with coordinates as small as
+ +/-4000.
+
+ \headerfile tqdrawutil.h
+
+ \sa TQPaintDevice TQWidget TQPixmap TQPrinter TQPicture
+ \link simple-application.html Application Walkthrough \endlink
+ \link coordsys.html Coordinate System Overview \endlink
+*/
+
+/*!
+ \fn TQGfx * TQPainter::internalGfx()
+
+ \internal
+*/
+
+/*!
+ \enum TQPainter::CoordinateMode
+ \value CoordDevice
+ \value CoordPainter
+
+ \sa clipRegion()
+*/
+/*!
+ \enum TQPainter::TextDirection
+ \value Auto
+ \value RTL right to left
+ \value LTR left to right
+
+ \sa drawText()
+*/
+
+/*!
+ \enum TQt::PaintUnit
+ \value PixelUnit
+ \value LoMetricUnit \e obsolete
+ \value HiMetricUnit \e obsolete
+ \value LoEnglishUnit \e obsolete
+ \value HiEnglishUnit \e obsolete
+ \value TwipsUnit \e obsolete
+*/
+
+/*!
+ \enum TQt::BrushStyle
+
+ \value NoBrush
+ \value SolidPattern
+ \value Dense1Pattern
+ \value Dense2Pattern
+ \value Dense3Pattern
+ \value Dense4Pattern
+ \value Dense5Pattern
+ \value Dense6Pattern
+ \value Dense7Pattern
+ \value HorPattern
+ \value VerPattern
+ \value CrossPattern
+ \value BDiagPattern
+ \value FDiagPattern
+ \value DiagCrossPattern
+ \value CustomPattern
+
+ \img brush-styles.png Brush Styles
+
+*/
+
+/*!
+ \enum TQt::RasterOp
+
+ This enum type is used to describe the way things are written to
+ the paint tqdevice. Each bit of the \e src (what you write)
+ interacts with the corresponding bit of the \e dst pixel.
+
+ \value CopyROP dst = src
+ \value OrROP dst = src OR dst
+ \value XorROP dst = src XOR dst
+ \value NotAndROP dst = (NOT src) AND dst
+ \value EraseROP an alias for \c NotAndROP
+ \value NotCopyROP dst = NOT src
+ \value NotOrROP dst = (NOT src) OR dst
+ \value NotXorROP dst = (NOT src) XOR dst
+ \value AndROP dst = src AND dst
+ \value NotEraseROP an alias for \c AndROP
+ \value NotROP dst = NOT dst
+ \value ClearROP dst = 0
+ \value SetROP dst = 1
+ \value NopROP dst = dst
+ \value AndNotROP dst = src AND (NOT dst)
+ \value OrNotROP dst = src OR (NOT dst)
+ \value NandROP dst = NOT (src AND dst)
+ \value NorROP dst = NOT (src OR dst)
+
+ By far the most useful ones are \c CopyROP and \c XorROP.
+
+ On TQt/Embedded, only \c CopyROP, \c XorROP, and \c NotROP are supported.
+*/
+
+/*!
+ \enum TQt::AlignmentFlags
+
+ This enum type is used to describe tqalignment. It tqcontains
+ horizontal and vertical flags.
+
+ The horizontal flags are:
+
+ \value AlignAuto Aligns according to the language. Left for most,
+ right for Arabic and Hebrew.
+ \value AlignLeft Aligns with the left edge.
+ \value AlignRight Aligns with the right edge.
+ \value AlignHCenter Centers horizontally in the available space.
+ \value AlignJustify Justifies the text in the available space.
+ Does not work for everything and may be interpreted as
+ AlignAuto in some cases.
+
+ The vertical flags are:
+
+ \value AlignTop Aligns with the top.
+ \value AlignBottom Aligns with the bottom.
+ \value AlignVCenter Centers vertically in the available space.
+
+ You can use only one of the horizontal flags at a time. There is
+ one two-dimensional flag:
+
+ \value AlignCenter Centers in both dimensions.
+
+ You can use at most one horizontal and one vertical flag at a time. \c
+ AlignCenter counts as both horizontal and vertical.
+
+ Masks:
+
+ \value AlignHorizontal_Mask
+ \value AlignVertical_Mask
+
+ Conflicting combinations of flags have undefined meanings.
+*/
+
+/*!
+ \enum TQt::TextFlags
+
+ This enum type is used to define some modifier flags. Some of
+ these flags only make sense in the context of printing:
+
+ \value SingleLine Treats all whitespace as spaces and prints just
+ one line.
+ \value DontClip If it's impossible to stay within the given bounds,
+ it prints outside.
+ \value ExpandTabs Makes the U+0009 (ASCII tab) character move to
+ the next tab stop.
+ \value ShowPrefix Displays the string "\&P" as <u>P</u>
+ (see TQButton for an example). For an ampersand, use "\&\&".
+ \value WordBreak Breaks lines at appropriate points, e.g. at word
+ boundaries.
+ \value BreakAnywhere Breaks lines anywhere, even within words.
+ \value NoAccel Same as ShowPrefix but doesn't draw the underlines.
+
+ You can use as many modifier flags as you want, except that \c
+ SingleLine and \c WordBreak cannot be combined.
+
+ Flags that are inappropriate for a given use (e.g. ShowPrefix to
+ TQGridLayout::addWidget()) are generally ignored.
+
+*/
+
+/*!
+ \enum TQt::PenStyle
+
+ This enum type defines the pen styles that can be drawn using
+ TQPainter. The styles are
+
+ \value NoPen no line at all. For example, TQPainter::drawRect()
+ fills but does not draw any boundary line.
+
+ \value SolidLine a simple line.
+
+ \value DashLine dashes separated by a few pixels.
+
+ \value DotLine dots separated by a few pixels.
+
+ \value DashDotLine alternate dots and dashes.
+
+ \value DashDotDotLine one dash, two dots, one dash, two dots.
+
+ \value MPenStyle tqmask of the pen styles.
+
+ \img pen-styles.png Pen Styles
+*/
+
+/*!
+ \enum TQt::PenCapStyle
+
+ This enum type defines the pen cap styles supported by TQt, i.e.
+ the line end caps that can be drawn using TQPainter.
+
+ \value FlatCap a square line end that does not cover the end
+ point of the line.
+ \value SquareCap a square line end that covers the end point and
+ extends beyond it with half the line width.
+ \value RoundCap a rounded line end.
+ \value MPenCapStyle tqmask of the pen cap styles.
+
+ \img pen-cap-styles.png Pen Cap Styles
+*/
+
+/*!
+ \enum TQt::PenJoinStyle
+
+ This enum type defines the pen join styles supported by TQt, i.e.
+ which joins between two connected lines can be drawn using
+ TQPainter.
+
+ \value MiterJoin The outer edges of the lines are extended to
+ meet at an angle, and this area is filled.
+ \value BevelJoin The triangular notch between the two lines is filled.
+ \value RoundJoin A circular arc between the two lines is filled.
+ \value MPenJoinStyle tqmask of the pen join styles.
+
+ \img pen-join-styles.png Pen Join Styles
+*/
+
+/*!
+ \enum TQt::BGMode
+
+ Background mode
+
+ \value TransparentMode
+ \value OpaqueMode
+*/
+
+/*!
+ Constructs a painter.
+
+ Notice that all painter settings (setPen, setBrush etc.) are reset
+ to default values when begin() is called.
+
+ \sa begin(), end()
+*/
+
+TQPainter::TQPainter()
+{
+ init();
+}
+
+
+/*!
+ Constructs a painter that begins painting the paint tqdevice \a pd
+ immediately. Depending on the underlying graphic system the
+ painter will paint over tqchildren of the painttqdevice if \a
+ unclipped is TRUE.
+
+ This constructor is convenient for short-lived painters, e.g. in a
+ \link TQWidget::paintEvent() paint event\endlink and should be used
+ only once. The constructor calls begin() for you and the TQPainter
+ destructor automatically calls end().
+
+ Here's an example using begin() and end():
+ \code
+ void MyWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPainter p;
+ p.begin( this );
+ p.drawLine( ... ); // drawing code
+ p.end();
+ }
+ \endcode
+
+ The same example using this constructor:
+ \code
+ void MyWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPainter p( this );
+ p.drawLine( ... ); // drawing code
+ }
+ \endcode
+
+ Since the constructor cannot provide feedback when the initialization
+ of the painter failed you should rather use begin() and end() to paint
+ on external tqdevices, e.g. printers.
+
+ \sa begin(), end()
+*/
+
+TQPainter::TQPainter( const TQPaintDevice *pd, bool unclipped )
+{
+ init();
+ if ( begin( pd, unclipped ) )
+ flags |= CtorBegin;
+}
+
+
+/*!
+ Constructs a painter that begins painting the paint tqdevice \a pd
+ immediately, with the default arguments taken from \a
+ copyAttributes. The painter will paint over tqchildren of the paint
+ tqdevice if \a unclipped is TRUE (although this is not supported on
+ all platforms).
+
+ \sa begin()
+*/
+
+TQPainter::TQPainter( const TQPaintDevice *pd,
+ const TQWidget *copyAttributes, bool unclipped )
+{
+ init();
+ if ( begin( pd, copyAttributes, unclipped ) )
+ flags |= CtorBegin;
+}
+
+
+/*!
+ Destroys the painter.
+*/
+
+TQPainter::~TQPainter()
+{
+ if ( isActive() )
+ end();
+ else
+ killPStack();
+ if ( tabarray ) // delete tab array
+ delete [] tabarray;
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( wm_stack )
+ delete (TQWMatrixStack *)wm_stack;
+#endif
+ destroy();
+}
+
+
+/*!
+ \overload bool TQPainter::begin( const TQPaintDevice *pd, const TQWidget *copyAttributes, bool unclipped )
+
+ This version opens the painter on a paint tqdevice \a pd and sets
+ the initial pen, background color and font from \a copyAttributes,
+ painting over the paint tqdevice's tqchildren when \a unclipped is
+ TRUE. This is equivalent to:
+
+ \code
+ TQPainter p;
+ p.begin( pd );
+ p.setPen( copyAttributes->foregroundColor() );
+ p.setBackgroundColor( copyAttributes->backgroundColor() );
+ p.setFont( copyAttributes->font() );
+ \endcode
+
+ This begin function is convenient for double buffering. When you
+ draw in a pixmap instead of directly in a widget (to later bitBlt
+ the pixmap into the widget) you will need to set the widget's
+ font etc. This function does exactly that.
+
+ Example:
+ \code
+ void MyWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPixmap pm(size());
+ TQPainter p;
+ p.begin(&pm, this);
+ // ... potentially flickering paint operation ...
+ p.end();
+ bitBlt(this, 0, 0, &pm);
+ }
+ \endcode
+
+ \sa end()
+*/
+
+bool TQPainter::begin( const TQPaintDevice *pd, const TQWidget *copyAttributes, bool unclipped )
+{
+ if ( copyAttributes == 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQPainter::begin: The widget to copy attributes from cannot "
+ "be null" );
+#endif
+ return FALSE;
+ }
+ if ( begin( pd, unclipped ) ) {
+ setPen( copyAttributes->foregroundColor() );
+ setBackgroundColor( copyAttributes->backgroundColor() );
+ setFont( copyAttributes->font() );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*!
+ \internal
+ Sets or clears a pointer flag.
+*/
+
+void TQPainter::setf( uint b, bool v )
+{
+ if ( v )
+ setf( b );
+ else
+ clearf( b );
+}
+
+
+/*!
+ \fn bool TQPainter::isActive() const
+
+ Returns TRUE if the painter is active painting, i.e. begin() has
+ been called and end() has not yet been called; otherwise returns
+ FALSE.
+
+ \sa TQPaintDevice::paintingActive()
+*/
+
+/*!
+ \fn TQPaintDevice *TQPainter::tqdevice() const
+
+ Returns the paint tqdevice on which this painter is currently
+ painting, or 0 if the painter is not active.
+
+ \sa TQPaintDevice::paintingActive()
+*/
+
+
+struct TQPState { // painter state
+ TQFont font;
+ TQPen pen;
+ TQPoint curPt;
+ TQBrush brush;
+ TQColor bgc;
+ uchar bgm;
+ uchar rop;
+ TQPoint bro;
+ TQRect wr, vr;
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix wm;
+#else
+ int xlatex;
+ int xlatey;
+#endif
+ bool vxf;
+ bool wxf;
+ TQRegion rgn;
+ bool clip;
+ int ts;
+ int *ta;
+ void* wm_stack;
+};
+
+//TODO lose the worldmatrix stack
+
+typedef TQPtrStack<TQPState> TQPStateStack;
+
+
+void TQPainter::killPStack()
+{
+#if defined(TQT_CHECK_STATE)
+ if ( ps_stack && !((TQPStateStack *)ps_stack)->isEmpty() )
+ qWarning( "TQPainter::killPStack: non-empty save/restore stack when "
+ "end() was called" );
+#endif
+ delete (TQPStateStack *)ps_stack;
+ ps_stack = 0;
+}
+
+/*!
+ Saves the current painter state (pushes the state onto a stack). A
+ save() must be followed by a corresponding restore(). end()
+ unwinds the stack.
+
+ \sa restore()
+*/
+
+void TQPainter::save()
+{
+ if ( testf(ExtDev) ) {
+ if ( testf(DirtyFont) )
+ updateFont();
+ if ( testf(DirtyPen) )
+ updatePen();
+ if ( testf(DirtyBrush) )
+ updateBrush();
+ pdev->cmd( TQPaintDevice::PdcSave, this, 0 );
+ }
+ TQPStateStack *pss = (TQPStateStack *)ps_stack;
+ if ( pss == 0 ) {
+ pss = new TQPtrStack<TQPState>;
+ TQ_CHECK_PTR( pss );
+ pss->setAutoDelete( TRUE );
+ ps_stack = pss;
+ }
+ TQPState *ps = new TQPState;
+ TQ_CHECK_PTR( ps );
+ ps->font = cfont;
+ ps->pen = cpen;
+ ps->curPt = pos();
+ ps->brush = cbrush;
+ ps->bgc = bg_col;
+ ps->bgm = bg_mode;
+ ps->rop = rop;
+ ps->bro = bro;
+#ifndef TQT_NO_TRANSFORMATIONS
+ ps->wr = TQRect( wx, wy, ww, wh );
+ ps->vr = TQRect( vx, vy, vw, vh );
+ ps->wm = wxmat;
+ ps->vxf = testf(VxF);
+ ps->wxf = testf(WxF);
+#else
+ ps->xlatex = xlatex;
+ ps->xlatey = xlatey;
+#endif
+ ps->rgn = crgn;
+ ps->clip = testf(ClipOn);
+ ps->ts = tabstops;
+ ps->ta = tabarray;
+ ps->wm_stack = wm_stack;
+ wm_stack = 0;
+ pss->push( ps );
+}
+
+/*!
+ Restores the current painter state (pops a saved state off the
+ stack).
+
+ \sa save()
+*/
+
+void TQPainter::restore()
+{
+ if ( testf(ExtDev) ) {
+ pdev->cmd( TQPaintDevice::PdcRestore, this, 0 );
+ if ( pdev->devType() == TQInternal::Picture )
+ block_ext = TRUE;
+ }
+ TQPStateStack *pss = (TQPStateStack *)ps_stack;
+ if ( pss == 0 || pss->isEmpty() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::restore: Empty stack error" );
+#endif
+ return;
+ }
+ TQPState *ps = pss->pop();
+ bool hardRestore = testf(VolatileDC);
+
+ if ( ps->font != cfont || hardRestore )
+ setFont( ps->font );
+ if ( ps->pen != cpen || hardRestore )
+ setPen( ps->pen );
+ if ( ps->brush != cbrush || hardRestore )
+ setBrush( ps->brush );
+ if ( ps->bgc != bg_col || hardRestore )
+ setBackgroundColor( ps->bgc );
+ if ( ps->bgm != bg_mode || hardRestore )
+ setBackgroundMode( (BGMode)ps->bgm );
+ if ( ps->rop != rop || hardRestore )
+ setRasterOp( (RasterOp)ps->rop );
+ if ( ps->bro != bro || hardRestore )
+ setBrushOrigin( ps->bro );
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQRect wr( wx, wy, ww, wh );
+ TQRect vr( vx, vy, vw, vh );
+ if ( ps->wr != wr || hardRestore )
+ setWindow( ps->wr );
+ if ( ps->vr != vr || hardRestore )
+ setViewport( ps->vr );
+ if ( ps->wm != wxmat || hardRestore )
+ setWorldMatrix( ps->wm );
+ if ( ps->vxf != testf(VxF) || hardRestore )
+ setViewXForm( ps->vxf );
+ if ( ps->wxf != testf(WxF) || hardRestore )
+ setWorldXForm( ps->wxf );
+#else
+ xlatex = ps->xlatex;
+ xlatey = ps->xlatey;
+ setf( VxF, xlatex || xlatey );
+#endif
+ if ( ps->curPt != pos() || hardRestore )
+ moveTo( ps->curPt );
+ if ( ps->rgn != crgn || hardRestore )
+ setClipRegion( ps->rgn );
+ if ( ps->clip != testf(ClipOn) || hardRestore )
+ setClipping( ps->clip );
+ tabstops = ps->ts;
+ tabarray = ps->ta;
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( wm_stack )
+ delete (TQWMatrixStack *)wm_stack;
+ wm_stack = ps->wm_stack;
+#endif
+ delete ps;
+ block_ext = FALSE;
+}
+
+typedef TQPtrDict<TQPaintDevice> TQPaintDeviceDict;
+static TQPaintDeviceDict *pdev_dict = 0;
+
+/*!
+ Redirects all paint commands for a paint tqdevice, \a pdev, to
+ another paint tqdevice, \a tqreplacement, unless \a tqreplacement is 0.
+ If \a tqreplacement is 0, the redirection for \a pdev is removed.
+
+ In general, you'll probably tqfind calling TQPixmap::grabWidget() or
+ TQPixmap::grabWindow() is an easier solution.
+*/
+
+void TQPainter::redirect( TQPaintDevice *pdev, TQPaintDevice *tqreplacement )
+{
+ if ( pdev_dict == 0 ) {
+ if ( tqreplacement == 0 )
+ return;
+ pdev_dict = new TQPaintDeviceDict;
+ TQ_CHECK_PTR( pdev_dict );
+ }
+#if defined(TQT_CHECK_NULL)
+ if ( pdev == 0 )
+ qWarning( "TQPainter::redirect: The pdev argument cannot be 0" );
+#endif
+ if ( tqreplacement ) {
+ pdev_dict->insert( pdev, tqreplacement );
+ } else {
+ pdev_dict->remove( pdev );
+ if ( pdev_dict->count() == 0 ) {
+ delete pdev_dict;
+ pdev_dict = 0;
+ }
+ }
+}
+
+/*!
+ \internal
+ Returns the tqreplacement for \a pdev, or 0 if there is no tqreplacement.
+*/
+TQPaintDevice *TQPainter::redirect( TQPaintDevice *pdev )
+{
+ return pdev_dict ? pdev_dict->tqfind( pdev ) : 0;
+}
+
+/*!
+ Returns the font metrics for the painter, if the painter is
+ active. It is not possible to obtain metrics for an inactive
+ painter, so the return value is undefined if the painter is not
+ active.
+
+ \sa fontInfo(), isActive()
+*/
+
+TQFontMetrics TQPainter::fontMetrics() const
+{
+ if ( pdev && pdev->devType() == TQInternal::Picture )
+ return TQFontMetrics( cfont );
+
+ return TQFontMetrics(this);
+}
+
+/*!
+ Returns the font info for the painter, if the painter is active.
+ It is not possible to obtain font information for an inactive
+ painter, so the return value is undefined if the painter is not
+ active.
+
+ \sa fontMetrics(), isActive()
+*/
+
+TQFontInfo TQPainter::fontInfo() const
+{
+ if ( pdev && pdev->devType() == TQInternal::Picture )
+ return TQFontInfo( cfont );
+
+ return TQFontInfo(this);
+}
+
+
+/*!
+ \fn const TQPen &TQPainter::pen() const
+
+ Returns the painter's current pen.
+
+ \sa setPen()
+*/
+
+/*!
+ Sets a new painter pen.
+
+ The \a pen defines how to draw lines and outlines, and it also
+ defines the text color.
+
+ \sa pen()
+*/
+
+void TQPainter::setPen( const TQPen &pen )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setPen: Will be reset by begin()" );
+#endif
+ if ( cpen == pen )
+ return;
+ cpen = pen;
+ updatePen();
+}
+
+/*!
+ \overload
+
+ Sets the painter's pen to have style \a style, width 0 and black
+ color.
+
+ \sa pen(), TQPen
+*/
+
+void TQPainter::setPen( PenStyle style )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setPen: Will be reset by begin()" );
+#endif
+ TQPen::TQPenData *d = cpen.data; // low level access
+ if ( d->style == style && d->linest == style && !d->width && d->color == TQt::black )
+ return;
+ if ( d->count != 1 ) {
+ cpen.detach();
+ d = cpen.data;
+ }
+ d->style = style;
+ d->width = 0;
+ d->color = TQt::black;
+ d->linest = style;
+ updatePen();
+}
+
+/*!
+ \overload
+
+ Sets the painter's pen to have style \c SolidLine, width 0 and the
+ specified \a color.
+
+ \sa pen(), TQPen
+*/
+
+void TQPainter::setPen( const TQColor &color )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setPen: Will be reset by begin()" );
+#endif
+ TQPen::TQPenData *d = cpen.data; // low level access
+ if ( d->color == color && !d->width && d->style == SolidLine && d->linest == SolidLine )
+ return;
+ if ( d->count != 1 ) {
+ cpen.detach();
+ d = cpen.data;
+ }
+ d->style = SolidLine;
+ d->width = 0;
+ d->color = color;
+ d->linest = SolidLine;
+ updatePen();
+}
+
+/*!
+ \fn const TQBrush &TQPainter::brush() const
+
+ Returns the painter's current brush.
+
+ \sa TQPainter::setBrush()
+*/
+
+/*!
+ \overload
+
+ Sets the painter's brush to \a brush.
+
+ The \a brush defines how tqshapes are filled.
+
+ \sa brush()
+*/
+
+void TQPainter::setBrush( const TQBrush &brush )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setBrush: Will be reset by begin()" );
+#endif
+ if ( cbrush == brush )
+ return;
+ cbrush = brush;
+ updateBrush();
+}
+
+/*!
+ Sets the painter's brush to black color and the specified \a
+ style.
+
+ \sa brush(), TQBrush
+*/
+
+void TQPainter::setBrush( BrushStyle style )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setBrush: Will be reset by begin()" );
+#endif
+ TQBrush::TQBrushData *d = cbrush.data; // low level access
+ if ( d->style == style && d->color == TQt::black && !d->pixmap )
+ return;
+ if ( d->count != 1 ) {
+ cbrush.detach();
+ d = cbrush.data;
+ }
+ d->style = style;
+ d->color = TQt::black;
+ if ( d->pixmap ) {
+ delete d->pixmap;
+ d->pixmap = 0;
+ }
+ updateBrush();
+}
+
+/*!
+ \overload
+
+ Sets the painter's brush to have style \c SolidPattern and the
+ specified \a color.
+
+ \sa brush(), TQBrush
+*/
+
+void TQPainter::setBrush( const TQColor &color )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setBrush: Will be reset by begin()" );
+#endif
+ TQBrush::TQBrushData *d = cbrush.data; // low level access
+ if ( d->color == color && d->style == SolidPattern && !d->pixmap )
+ return;
+ if ( d->count != 1 ) {
+ cbrush.detach();
+ d = cbrush.data;
+ }
+ d->style = SolidPattern;
+ d->color = color;
+ if ( d->pixmap ) {
+ delete d->pixmap;
+ d->pixmap = 0;
+ }
+ updateBrush();
+}
+
+
+/*!
+ \fn const TQColor &TQPainter::backgroundColor() const
+
+ Returns the current background color.
+
+ \sa setBackgroundColor() TQColor
+*/
+
+/*!
+ \fn BGMode TQPainter::backgroundMode() const
+
+ Returns the current background mode.
+
+ \sa setBackgroundMode() BGMode
+*/
+
+/*!
+ \fn RasterOp TQPainter::rasterOp() const
+
+ Returns the current \link TQt::RasterOp raster operation \endlink.
+
+ \sa setRasterOp() RasterOp
+*/
+
+/*!
+ \fn const TQPoint &TQPainter::brushOrigin() const
+
+ Returns the brush origin currently set.
+
+ \sa setBrushOrigin()
+*/
+
+
+/*!
+ \fn int TQPainter::tabStops() const
+
+ Returns the tab stop setting.
+
+ \sa setTabStops()
+*/
+
+/*!
+ Set the tab stop width to \a ts, i.e. locates tab stops at \a ts,
+ 2*\a ts, 3*\a ts and so on.
+
+ Tab stops are used when drawing formatted text with \c ExpandTabs
+ set. This fixed tab stop value is used only if no tab array is set
+ (which is the default case).
+
+ A value of 0 (the default) implies a tabstop setting of 8 times the width of the
+ character 'x' in the font currently set on the painter.
+
+ \sa tabStops(), setTabArray(), drawText(), fontMetrics()
+*/
+
+void TQPainter::setTabStops( int ts )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setTabStops: Will be reset by begin()" );
+#endif
+ tabstops = ts;
+ if ( isActive() && testf(ExtDev) ) { // tell extended tqdevice
+ TQPDevCmdParam param[1];
+ param[0].ival = ts;
+ pdev->cmd( TQPaintDevice::PdcSetTabStops, this, param );
+ }
+}
+
+/*!
+ \fn int *TQPainter::tabArray() const
+
+ Returns the currently set tab stop array.
+
+ \sa setTabArray()
+*/
+
+/*!
+ Sets the tab stop array to \a ta. This puts tab stops at \a ta[0],
+ \a ta[1] and so on. The array is null-terminated.
+
+ If both a tab array and a tab top size is set, the tab array wins.
+
+ \sa tabArray(), setTabStops(), drawText(), fontMetrics()
+*/
+
+void TQPainter::setTabArray( int *ta )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setTabArray: Will be reset by begin()" );
+#endif
+ if ( ta != tabarray ) {
+ tabarraylen = 0;
+ if ( tabarray ) // Avoid purify complaint
+ delete [] tabarray; // delete old array
+ if ( ta ) { // tabarray = copy of 'ta'
+ while ( ta[tabarraylen] )
+ tabarraylen++;
+ tabarraylen++; // and 0 terminator
+ tabarray = new int[tabarraylen]; // duplicate ta
+ memcpy( tabarray, ta, sizeof(int)*tabarraylen );
+ } else {
+ tabarray = 0;
+ }
+ }
+ if ( isActive() && testf(ExtDev) ) { // tell extended tqdevice
+ TQPDevCmdParam param[2];
+ param[0].ival = tabarraylen;
+ param[1].ivec = tabarray;
+ pdev->cmd( TQPaintDevice::PdcSetTabArray, this, param );
+ }
+}
+
+
+/*!
+ \fn HANDLE TQPainter::handle() const
+
+ Returns the platform-dependent handle used for drawing. Using this
+ function is not portable.
+*/
+
+
+/*****************************************************************************
+ TQPainter xform settings
+ *****************************************************************************/
+
+#ifndef TQT_NO_TRANSFORMATIONS
+
+/*!
+ Enables view transformations if \a enable is TRUE, or disables
+ view transformations if \a enable is FALSE.
+
+ \sa hasViewXForm(), setWindow(), setViewport(), setWorldMatrix(),
+ setWorldXForm(), xForm()
+*/
+
+void TQPainter::setViewXForm( bool enable )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setViewXForm: Will be reset by begin()" );
+#endif
+ if ( !isActive() || enable == testf(VxF) )
+ return;
+ setf( VxF, enable );
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ param[0].ival = enable;
+ pdev->cmd( TQPaintDevice::PdcSetVXform, this, param );
+ }
+ updateXForm();
+}
+
+/*!
+ \fn bool TQPainter::hasViewXForm() const
+
+ Returns TRUE if view transformation is enabled; otherwise returns
+ FALSE.
+
+ \sa setViewXForm(), xForm()
+*/
+
+/*!
+ Returns the window rectangle.
+
+ \sa setWindow(), setViewXForm()
+*/
+
+TQRect TQPainter::window() const
+{
+ return TQRect( wx, wy, ww, wh );
+}
+
+/*!
+ Sets the window rectangle view transformation for the painter and
+ enables view transformation.
+
+ The window rectangle is part of the view transformation. The
+ window specifies the logical coordinate system and is specified by
+ the \a x, \a y, \a w width and \a h height parameters. Its sister,
+ the viewport(), specifies the tqdevice coordinate system.
+
+ The default window rectangle is the same as the tqdevice's
+ rectangle. See the \link coordsys.html Coordinate System Overview
+ \endlink for an overview of coordinate transformation.
+
+ \sa window(), setViewport(), setViewXForm(), setWorldMatrix(),
+ setWorldXForm()
+*/
+
+void TQPainter::setWindow( int x, int y, int w, int h )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setWindow: Will be reset by begin()" );
+#endif
+ wx = x;
+ wy = y;
+ ww = w;
+ wh = h;
+ if ( testf(ExtDev) ) {
+ TQRect r( x, y, w, h );
+ TQPDevCmdParam param[1];
+ param[0].rect = (TQRect*)&r;
+ pdev->cmd( TQPaintDevice::PdcSetWindow, this, param );
+ }
+ if ( testf(VxF) )
+ updateXForm();
+ else
+ setViewXForm( TRUE );
+}
+
+/*!
+ Returns the viewport rectangle.
+
+ \sa setViewport(), setViewXForm()
+*/
+
+TQRect TQPainter::viewport() const // get viewport
+{
+ return TQRect( vx, vy, vw, vh );
+}
+
+/*!
+ Sets the viewport rectangle view transformation for the painter
+ and enables view transformation.
+
+ The viewport rectangle is part of the view transformation. The
+ viewport specifies the tqdevice coordinate system and is specified
+ by the \a x, \a y, \a w width and \a h height parameters. Its
+ sister, the window(), specifies the logical coordinate system.
+
+ The default viewport rectangle is the same as the tqdevice's
+ rectangle. See the \link coordsys.html Coordinate System Overview
+ \endlink for an overview of coordinate transformation.
+
+ \sa viewport(), setWindow(), setViewXForm(), setWorldMatrix(),
+ setWorldXForm(), xForm()
+*/
+
+void TQPainter::setViewport( int x, int y, int w, int h )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setViewport: Will be reset by begin()" );
+#endif
+ vx = x;
+ vy = y;
+ vw = w;
+ vh = h;
+ if ( testf(ExtDev) ) {
+ TQRect r( x, y, w, h );
+ TQPDevCmdParam param[1];
+ param[0].rect = (TQRect*)&r;
+ pdev->cmd( TQPaintDevice::PdcSetViewport, this, param );
+ }
+ if ( testf(VxF) )
+ updateXForm();
+ else
+ setViewXForm( TRUE );
+}
+
+
+/*!
+ Enables world transformations if \a enable is TRUE, or disables
+ world transformations if \a enable is FALSE. The world
+ transformation matrix is not changed.
+
+ \sa setWorldMatrix(), setWindow(), setViewport(), setViewXForm(),
+ xForm()
+*/
+
+void TQPainter::setWorldXForm( bool enable )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setWorldXForm: Will be reset by begin()" );
+#endif
+ if ( !isActive() || enable == testf(WxF) )
+ return;
+ setf( WxF, enable );
+ if ( testf(ExtDev) && !block_ext ) {
+ TQPDevCmdParam param[1];
+ param[0].ival = enable;
+ pdev->cmd( TQPaintDevice::PdcSetWXform, this, param );
+ }
+ updateXForm();
+}
+
+/*!
+ \fn bool TQPainter::hasWorldXForm() const
+
+ Returns TRUE if world transformation is enabled; otherwise returns
+ FALSE.
+
+ \sa setWorldXForm()
+*/
+
+/*!
+ Returns the world transformation matrix.
+
+ \sa setWorldMatrix()
+*/
+
+const TQWMatrix &TQPainter::tqworldMatrix() const
+{
+ return wxmat;
+}
+
+/*!
+ Sets the world transformation matrix to \a m and enables world
+ transformation.
+
+ If \a combine is TRUE, then \a m is combined with the current
+ transformation matrix, otherwise \a m tqreplaces the current
+ transformation matrix.
+
+ If \a m is the identity matrix and \a combine is FALSE, this
+ function calls setWorldXForm(FALSE). (The identity matrix is the
+ matrix where TQWMatrix::m11() and TQWMatrix::m22() are 1.0 and the
+ rest are 0.0.)
+
+ World transformations are applied after the view transformations
+ (i.e. \link setWindow() window\endlink and \link setViewport()
+ viewport\endlink).
+
+ The following functions can transform the coordinate system without using
+ a TQWMatrix:
+ \list
+ \i translate()
+ \i scale()
+ \i shear()
+ \i rotate()
+ \endlist
+
+ They operate on the painter's tqworldMatrix() and are implemented like this:
+
+ \code
+ void TQPainter::rotate( double a )
+ {
+ TQWMatrix m;
+ m.rotate( a );
+ setWorldMatrix( m, TRUE );
+ }
+ \endcode
+
+ Note that you should always use \a combine when you are drawing
+ into a TQPicture. Otherwise it may not be possible to replay the
+ picture with additional transformations. Using translate(),
+ scale(), etc., is safe.
+
+ For a brief overview of coordinate transformation, see the \link
+ coordsys.html Coordinate System Overview. \endlink
+
+ \sa tqworldMatrix() setWorldXForm() setWindow() setViewport()
+ setViewXForm() xForm() TQWMatrix
+*/
+
+void TQPainter::setWorldMatrix( const TQWMatrix &m, bool combine )
+{
+ if ( !isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::setWorldMatrix: Will be reset by begin()" );
+#endif
+ return;
+ }
+ if ( combine )
+ wxmat = m * wxmat; // combines
+ else
+ wxmat = m; // set new matrix
+ bool identity = wxmat.m11() == 1.0F && wxmat.m22() == 1.0F &&
+ wxmat.m12() == 0.0F && wxmat.m21() == 0.0F &&
+ wxmat.dx() == 0.0F && wxmat.dy() == 0.0F;
+ if ( testf(ExtDev) && !block_ext ) {
+ TQPDevCmdParam param[2];
+ param[0].matrix = &m;
+ param[1].ival = combine;
+ pdev->cmd( TQPaintDevice::PdcSetWMatrix, this, param );
+ }
+ if ( identity && pdev->devType() != TQInternal::Picture )
+ setWorldXForm( FALSE );
+ else if ( !testf(WxF) )
+ setWorldXForm( TRUE );
+ else
+ updateXForm();
+}
+
+/*! \obsolete
+
+ We recommend using save() instead.
+*/
+
+void TQPainter::saveWorldMatrix()
+{
+ TQWMatrixStack *stack = (TQWMatrixStack *)wm_stack;
+ if ( stack == 0 ) {
+ stack = new TQPtrStack<TQWMatrix>;
+ TQ_CHECK_PTR( stack );
+ stack->setAutoDelete( TRUE );
+ wm_stack = stack;
+ }
+
+ stack->push( new TQWMatrix( wxmat ) );
+
+}
+
+/*! \obsolete
+ We recommend using restore() instead.
+*/
+
+void TQPainter::restoreWorldMatrix()
+{
+ TQWMatrixStack *stack = (TQWMatrixStack *)wm_stack;
+ if ( stack == 0 || stack->isEmpty() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::restoreWorldMatrix: Empty stack error" );
+#endif
+ return;
+ }
+ TQWMatrix* m = stack->pop();
+ setWorldMatrix( *m );
+ delete m;
+}
+
+#endif // TQT_NO_TRANSFORMATIONS
+
+/*!
+ Translates the coordinate system by \a (dx, dy). After this call,
+ \a (dx, dy) is added to points.
+
+ For example, the following code draws the same point twice:
+ \code
+ void MyWidget::paintEvent()
+ {
+ TQPainter paint( this );
+
+ paint.drawPoint( 0, 0 );
+
+ paint.translate( 100.0, 40.0 );
+ paint.drawPoint( -100, -40 );
+ }
+ \endcode
+
+ \sa scale(), shear(), rotate(), resetXForm(), setWorldMatrix(), xForm()
+*/
+
+void TQPainter::translate( double dx, double dy )
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix m;
+ m.translate( dx, dy );
+ setWorldMatrix( m, TRUE );
+#else
+ xlatex += (int)dx;
+ xlatey += (int)dy;
+ setf( VxF, xlatex || xlatey );
+#endif
+}
+
+
+#ifndef TQT_NO_TRANSFORMATIONS
+/*!
+ Scales the coordinate system by \a (sx, sy).
+
+ \sa translate(), shear(), rotate(), resetXForm(), setWorldMatrix(),
+ xForm()
+*/
+
+void TQPainter::scale( double sx, double sy )
+{
+ TQWMatrix m;
+ m.scale( sx, sy );
+ setWorldMatrix( m, TRUE );
+}
+
+/*!
+ Shears the coordinate system by \a (sh, sv).
+
+ \sa translate(), scale(), rotate(), resetXForm(), setWorldMatrix(),
+ xForm()
+*/
+
+void TQPainter::shear( double sh, double sv )
+{
+ TQWMatrix m;
+ m.shear( sv, sh );
+ setWorldMatrix( m, TRUE );
+}
+
+/*!
+ Rotates the coordinate system \a a degrees counterclockwise.
+
+ \sa translate(), scale(), shear(), resetXForm(), setWorldMatrix(),
+ xForm()
+*/
+
+void TQPainter::rotate( double a )
+{
+ TQWMatrix m;
+ m.rotate( a );
+ setWorldMatrix( m, TRUE );
+}
+
+
+/*!
+ Resets any transformations that were made using translate(), scale(),
+ shear(), rotate(), setWorldMatrix(), setViewport() and
+ setWindow().
+
+ \sa tqworldMatrix(), viewport(), window()
+*/
+
+void TQPainter::resetXForm()
+{
+ if ( !isActive() )
+ return;
+ wx = wy = vx = vy = 0; // default view origins
+ ww = vw = pdev->metric( TQPaintDeviceMetrics::PdmWidth );
+ wh = vh = pdev->metric( TQPaintDeviceMetrics::PdmHeight );
+ wxmat = TQWMatrix();
+ setWorldXForm( FALSE );
+ setViewXForm( FALSE );
+}
+
+/*!
+ \internal
+ Updates an internal integer transformation matrix.
+*/
+
+void TQPainter::updateXForm()
+{
+ TQWMatrix m;
+ if ( testf(VxF) ) {
+ double scaleW = (double)vw/(double)ww;
+ double scaleH = (double)vh/(double)wh;
+ m.setMatrix( scaleW, 0, 0, scaleH, vx - wx*scaleW, vy - wy*scaleH );
+ }
+ if ( testf(WxF) ) {
+ if ( testf(VxF) )
+ m = wxmat * m;
+ else
+ m = wxmat;
+ }
+ xmat = m;
+
+ txinv = FALSE; // no inverted matrix
+ txop = TxNone;
+ if ( m12()==0.0 && m21()==0.0 && m11() >= 0.0 && m22() >= 0.0 ) {
+ if ( m11()==1.0 && m22()==1.0 ) {
+ if ( dx()!=0.0 || dy()!=0.0 )
+ txop = TxTranslate;
+ } else {
+ txop = TxScale;
+#if defined(TQ_WS_WIN)
+ setf(DirtyFont);
+#endif
+ }
+ } else {
+ txop = TxRotShear;
+#if defined(TQ_WS_WIN)
+ setf(DirtyFont);
+#endif
+ }
+}
+
+
+/*!
+ \internal
+ Updates an internal integer inverse transformation matrix.
+*/
+
+void TQPainter::updateInvXForm()
+{
+#if defined(TQT_CHECK_STATE)
+ TQ_ASSERT( txinv == FALSE );
+#endif
+ txinv = TRUE; // creating inverted matrix
+ bool invertible;
+ TQWMatrix m;
+ if ( testf(VxF) ) {
+ m.translate( vx, vy );
+ m.scale( 1.0*vw/ww, 1.0*vh/wh );
+ m.translate( -wx, -wy );
+ }
+ if ( testf(WxF) ) {
+ if ( testf(VxF) )
+ m = wxmat * m;
+ else
+ m = wxmat;
+ }
+ ixmat = m.invert( &invertible ); // invert matrix
+}
+
+#else
+void TQPainter::resetXForm()
+{
+ xlatex = 0;
+ xlatey = 0;
+ clearf( VxF );
+}
+#endif // TQT_NO_TRANSFORMATIONS
+
+
+extern bool qt_old_transformations;
+
+/*!
+ \internal
+ Maps a point from logical coordinates to tqdevice coordinates.
+*/
+
+void TQPainter::map( int x, int y, int *rx, int *ry ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( qt_old_transformations ) {
+ switch ( txop ) {
+ case TxNone:
+ *rx = x; *ry = y;
+ break;
+ case TxTranslate:
+ // #### "Why no rounding here?", Warwick asked of Haavard.
+ *rx = int(x + dx());
+ *ry = int(y + dy());
+ break;
+ case TxScale: {
+ double tx = m11()*x + dx();
+ double ty = m22()*y + dy();
+ *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
+ *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
+ } break;
+ default: {
+ double tx = m11()*x + m21()*y+dx();
+ double ty = m12()*x + m22()*y+dy();
+ *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
+ *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
+ } break;
+ }
+ } else {
+ switch ( txop ) {
+ case TxNone:
+ *rx = x;
+ *ry = y;
+ break;
+ case TxTranslate:
+ *rx = tqRound( x + dx() );
+ *ry = tqRound( y + dy() );
+ break;
+ case TxScale:
+ *rx = tqRound( m11()*x + dx() );
+ *ry = tqRound( m22()*y + dy() );
+ break;
+ default:
+ *rx = tqRound( m11()*x + m21()*y+dx() );
+ *ry = tqRound( m12()*x + m22()*y+dy() );
+ break;
+ }
+ }
+#else
+ *rx = x + xlatex;
+ *ry = y + xlatey;
+#endif
+}
+
+/*!
+ \internal
+ Maps a rectangle from logical coordinates to tqdevice coordinates.
+ This internal function does not handle rotation and/or shear.
+*/
+
+void TQPainter::map( int x, int y, int w, int h,
+ int *rx, int *ry, int *rw, int *rh ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( qt_old_transformations ) {
+ switch ( txop ) {
+ case TxNone:
+ *rx = x; *ry = y;
+ *rw = w; *rh = h;
+ break;
+ case TxTranslate:
+ // #### "Why no rounding here?", Warwick asked of Haavard.
+ *rx = int(x + dx());
+ *ry = int(y + dy());
+ *rw = w; *rh = h;
+ break;
+ case TxScale: {
+ double tx1 = m11()*x + dx();
+ double ty1 = m22()*y + dy();
+ double tx2 = m11()*(x + w - 1) + dx();
+ double ty2 = m22()*(y + h - 1) + dy();
+ *rx = tqRound( tx1 );
+ *ry = tqRound( ty1 );
+ *rw = tqRound( tx2 ) - *rx + 1;
+ *rh = tqRound( ty2 ) - *ry + 1;
+ } break;
+ default:
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::map: Internal error" );
+#endif
+ break;
+ }
+ } else {
+ switch ( txop ) {
+ case TxNone:
+ *rx = x; *ry = y;
+ *rw = w; *rh = h;
+ break;
+ case TxTranslate:
+ *rx = tqRound(x + dx() );
+ *ry = tqRound(y + dy() );
+ *rw = w; *rh = h;
+ break;
+ case TxScale:
+ *rx = tqRound( m11()*x + dx() );
+ *ry = tqRound( m22()*y + dy() );
+ *rw = tqRound( m11()*w );
+ *rh = tqRound( m22()*h );
+ break;
+ default:
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::map: Internal error" );
+#endif
+ break;
+ }
+ }
+#else
+ *rx = x + xlatex;
+ *ry = y + xlatey;
+ *rw = w; *rh = h;
+#endif
+}
+
+/*!
+ \internal
+ Maps a point from tqdevice coordinates to logical coordinates.
+*/
+
+void TQPainter::mapInv( int x, int y, int *rx, int *ry ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+#if defined(TQT_CHECK_STATE)
+ if ( !txinv )
+ qWarning( "TQPainter::mapInv: Internal error" );
+#endif
+ if ( qt_old_transformations ) {
+ double tx = im11()*x + im21()*y+idx();
+ double ty = im12()*x + im22()*y+idy();
+ *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
+ *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
+ } else {
+ *rx = tqRound( im11()*x + im21()*y + idx() );
+ *ry = tqRound( im12()*x + im22()*y + idy() );
+ }
+#else
+ *rx = x - xlatex;
+ *ry = y - xlatey;
+#endif
+}
+
+/*!
+ \internal
+ Maps a rectangle from tqdevice coordinates to logical coordinates.
+ Cannot handle rotation and/or shear.
+*/
+
+void TQPainter::mapInv( int x, int y, int w, int h,
+ int *rx, int *ry, int *rw, int *rh ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+#if defined(TQT_CHECK_STATE)
+ if ( !txinv || txop == TxRotShear )
+ qWarning( "TQPainter::mapInv: Internal error" );
+#endif
+ if ( qt_old_transformations ) {
+ double tx = im11()*x + idx();
+ double ty = im22()*y + idy();
+ double tw = im11()*w;
+ double th = im22()*h;
+ *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
+ *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
+ *rw = tw >= 0 ? int(tw + 0.5) : int(tw - 0.5);
+ *rh = th >= 0 ? int(th + 0.5) : int(th - 0.5);
+ } else {
+ *rx = tqRound( im11()*x + idx() );
+ *ry = tqRound( im22()*y + idy() );
+ *rw = tqRound( im11()*w );
+ *rh = tqRound( im22()*h );
+ }
+#else
+ *rx = x - xlatex;
+ *ry = y - xlatey;
+ *rw = w;
+ *rh = h;
+#endif
+}
+
+
+/*!
+ Returns the point \a pv transformed from model coordinates to
+ tqdevice coordinates.
+
+ \sa xFormDev(), TQWMatrix::map()
+*/
+
+TQPoint TQPainter::xForm( const TQPoint &pv ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return pv;
+ int x=pv.x(), y=pv.y();
+ map( x, y, &x, &y );
+ return TQPoint( x, y );
+#else
+ return TQPoint( pv.x()+xlatex, pv.y()+xlatey );
+#endif
+}
+
+/*!
+ \overload
+
+ Returns the rectangle \a rv transformed from model coordinates to
+ tqdevice coordinates.
+
+ If world transformation is enabled and rotation or shearing has
+ been specified, then the bounding rectangle is returned.
+
+ \sa xFormDev(), TQWMatrix::map()
+*/
+
+TQRect TQPainter::xForm( const TQRect &rv ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return rv;
+ if ( txop == TxRotShear ) { // rotation/shear
+ return xmat.mapRect( rv );
+ }
+ // Just translation/scale
+ int x, y, w, h;
+ rv.rect( &x, &y, &w, &h );
+ map( x, y, w, h, &x, &y, &w, &h );
+ return TQRect( x, y, w, h );
+#else
+ return TQRect( rv.x()+xlatex, rv.y()+xlatey, rv.width(), rv.height() );
+#endif
+}
+
+/*!
+ \overload
+
+ Returns the point array \a av transformed from model coordinates
+ to tqdevice coordinates.
+
+ \sa xFormDev(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xForm( const TQPointArray &av ) const
+{
+ TQPointArray a = av;
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop != TxNone )
+ {
+ return xmat * av;
+ }
+#else
+ a.translate( xlatex, xlatey );
+#endif
+ return a;
+}
+
+/*!
+ \overload
+
+ Returns the point array \a av transformed from model coordinates
+ to tqdevice coordinates. The \a index is the first point in the
+ array and \a npoints denotes the number of points to be
+ transformed. If \a npoints is negative, all points from \a
+ av[index] until the last point in the array are transformed.
+
+ The returned point array consists of the number of points that
+ were transformed.
+
+ Example:
+ \code
+ TQPointArray a(10);
+ TQPointArray b;
+ b = painter.xForm(a, 2, 4); // b.size() == 4
+ b = painter.xForm(a, 2, -1); // b.size() == 8
+ \endcode
+
+ \sa xFormDev(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xForm( const TQPointArray &av, int index,
+ int npoints ) const
+{
+ int lastPoint = npoints < 0 ? av.size() : index+npoints;
+ TQPointArray a( lastPoint-index );
+ memcpy( a.data(), av.data()+index, (lastPoint-index)*sizeof( TQPoint ) );
+#ifndef TQT_NO_TRANSFORMATIONS
+ return xmat*a;
+#else
+ a.translate( xlatex, xlatey );
+ return a;
+#endif
+}
+
+/*!
+ \overload
+
+ Returns the point \a pd transformed from tqdevice coordinates to
+ model coordinates.
+
+ \sa xForm(), TQWMatrix::map()
+*/
+
+TQPoint TQPainter::xFormDev( const TQPoint &pd ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return pd;
+ if ( !txinv ) {
+ TQPainter *that = (TQPainter*)this; // mutable
+ that->updateInvXForm();
+ }
+#endif
+ int x=pd.x(), y=pd.y();
+ mapInv( x, y, &x, &y );
+ return TQPoint( x, y );
+}
+
+/*!
+ Returns the rectangle \a rd transformed from tqdevice coordinates to
+ model coordinates.
+
+ If world transformation is enabled and rotation or shearing is
+ used, then the bounding rectangle is returned.
+
+ \sa xForm(), TQWMatrix::map()
+*/
+
+TQRect TQPainter::xFormDev( const TQRect &rd ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return rd;
+ if ( !txinv ) {
+ TQPainter *that = (TQPainter*)this; // mutable
+ that->updateInvXForm();
+ }
+ if ( txop == TxRotShear ) { // rotation/shear
+ return ixmat.mapRect( rd );
+ }
+#endif
+ // Just translation/scale
+ int x, y, w, h;
+ rd.rect( &x, &y, &w, &h );
+ mapInv( x, y, w, h, &x, &y, &w, &h );
+ return TQRect( x, y, w, h );
+}
+
+/*!
+ \overload
+
+ Returns the point array \a ad transformed from tqdevice coordinates
+ to model coordinates.
+
+ \sa xForm(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xFormDev( const TQPointArray &ad ) const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return ad;
+ if ( !txinv ) {
+ TQPainter *that = (TQPainter*)this; // mutable
+ that->updateInvXForm();
+ }
+ return ixmat * ad;
+#else
+ // ###
+ return ad;
+#endif
+}
+
+/*!
+ \overload
+
+ Returns the point array \a ad transformed from tqdevice coordinates
+ to model coordinates. The \a index is the first point in the array
+ and \a npoints denotes the number of points to be transformed. If
+ \a npoints is negative, all points from \a ad[index] until the
+ last point in the array are transformed.
+
+ The returned point array consists of the number of points that
+ were transformed.
+
+ Example:
+ \code
+ TQPointArray a(10);
+ TQPointArray b;
+ b = painter.xFormDev(a, 1, 3); // b.size() == 3
+ b = painter.xFormDev(a, 1, -1); // b.size() == 9
+ \endcode
+
+ \sa xForm(), TQWMatrix::map()
+*/
+
+TQPointArray TQPainter::xFormDev( const TQPointArray &ad, int index,
+ int npoints ) const
+{
+ int lastPoint = npoints < 0 ? ad.size() : index+npoints;
+ TQPointArray a( lastPoint-index );
+ memcpy( a.data(), ad.data()+index, (lastPoint-index)*sizeof( TQPoint ) );
+#ifndef TQT_NO_TRANSFORMATIONS
+ if ( txop == TxNone )
+ return a;
+ if ( !txinv ) {
+ TQPainter *that = (TQPainter*)this; // mutable
+ that->updateInvXForm();
+ }
+ return ixmat * a;
+#else
+ // ###
+ return a;
+#endif
+}
+
+
+/*!
+ Fills the rectangle \a (x, y, w, h) with the \a brush.
+
+ You can specify a TQColor as \a brush, since there is a TQBrush
+ constructor that takes a TQColor argument and creates a solid
+ pattern brush.
+
+ \sa drawRect()
+*/
+
+void TQPainter::fillRect( int x, int y, int w, int h, const TQBrush &brush )
+{
+ TQPen oldPen = pen(); // save pen
+ TQBrush oldBrush = this->brush(); // save brush
+ setPen( NoPen );
+ setBrush( brush );
+ drawRect( x, y, w, h ); // draw filled rect
+ setBrush( oldBrush ); // restore brush
+ setPen( oldPen ); // restore pen
+}
+
+
+/*!
+ \overload void TQPainter::setBrushOrigin( const TQPoint &p )
+
+ Sets the brush origin to point \a p.
+*/
+
+/*!
+ \overload void TQPainter::setWindow( const TQRect &r )
+
+ Sets the painter's window to rectangle \a r.
+*/
+
+
+/*!
+ \overload void TQPainter::setViewport( const TQRect &r )
+
+ Sets the painter's viewport to rectangle \a r.
+*/
+
+
+/*!
+ \fn bool TQPainter::hasClipping() const
+
+ Returns TRUE if clipping has been set; otherwise returns FALSE.
+
+ \sa setClipping()
+*/
+
+/*!
+ Returns the currently set clip region. Note that the clip region
+ is given in physical tqdevice coordinates and \e not subject to any
+ \link coordsys.html coordinate transformation \endlink if \a m is
+ equal to \c CoordDevice (the default). If \a m equals \c
+ CoordPainter the returned region is in model coordinates.
+
+ \sa setClipRegion(), setClipRect(), setClipping() TQPainter::CoordinateMode
+*/
+TQRegion TQPainter::clipRegion( CoordinateMode m ) const
+{
+ // ### FIXME in 4.0:
+ // If the transformation mode is CoordPainter, we should transform the
+ // clip region with painter transformations.
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQRegion r;
+ if ( m == CoordDevice ) {
+ r = crgn;
+ } else {
+ if ( !txinv ) {
+ TQPainter *that = (TQPainter*)this; // mutable
+ that->updateInvXForm();
+ }
+
+ r = ixmat * crgn;
+ }
+ return r;
+#else
+ return crgn;
+#endif
+}
+
+/*!
+ \fn void TQPainter::setClipRect( int x, int y, int w, int h, CoordinateMode m)
+
+ Sets the clip region to the rectangle \a x, \a y, \a w, \a h and
+ enables clipping. The clip mode is set to \a m.
+
+ If \a m is \c CoordDevice (the default), the coordinates given for
+ the clip region are taken to be physical tqdevice coordinates and
+ are \e not subject to any \link coordsys.html coordinate
+ transformations\endlink. If \a m is \c CoordPainter, the
+ coordinates given for the clip region are taken to be model
+ coordinates.
+
+ \sa setClipRegion(), clipRegion(), setClipping() TQPainter::CoordinateMode
+*/
+
+/*!
+ \overload void TQPainter::drawPoint( const TQPoint &p )
+
+ Draws the point \a p.
+*/
+
+
+/*!
+ \overload void TQPainter::moveTo( const TQPoint &p )
+
+ Moves to the point \a p.
+*/
+
+/*!
+ \overload void TQPainter::lineTo( const TQPoint &p )
+
+ Draws a line to the point \a p.
+*/
+
+/*!
+ \overload void TQPainter::drawLine( const TQPoint &p1, const TQPoint &p2 )
+
+ Draws a line from point \a p1 to point \a p2.
+*/
+
+/*!
+ \overload void TQPainter::drawRect( const TQRect &r )
+
+ Draws the rectangle \a r.
+*/
+
+/*!
+ \overload void TQPainter::drawWinFocusRect( const TQRect &r )
+
+ Draws rectangle \a r as a window focus rectangle.
+*/
+
+/*!
+ \overload void TQPainter::drawWinFocusRect( const TQRect &r, const TQColor &bgColor )
+
+ Draws rectangle \a r as a window focus rectangle using background
+ color \a bgColor.
+*/
+
+
+#if !defined(TQ_WS_X11) && !defined(TQ_WS_TQWS) && !defined(TQ_WS_MAC)
+// The doc and X implementation of this functions is in qpainter_x11.cpp
+void TQPainter::drawWinFocusRect( int, int, int, int,
+ bool, const TQColor & )
+{
+ // do nothing, only called from X11 specific functions
+}
+#endif
+
+
+/*!
+ \overload void TQPainter::drawRoundRect( const TQRect &r, int xRnd, int yRnd )
+
+ Draws a rounded rectangle \a r, rounding to the x position \a xRnd
+ and the y position \a yRnd on each corner.
+*/
+
+/*!
+ \overload void TQPainter::drawEllipse( const TQRect &r )
+
+ Draws the ellipse that fits inside rectangle \a r.
+*/
+
+/*!
+ \overload void TQPainter::drawArc( const TQRect &r, int a, int alen )
+
+ Draws the arc that fits inside the rectangle \a r with start angle
+ \a a and arc length \a alen.
+*/
+
+/*!
+ \overload void TQPainter::drawPie( const TQRect &r, int a, int alen )
+
+ Draws a pie segment that fits inside the rectangle \a r with start
+ angle \a a and arc length \a alen.
+*/
+
+/*!
+ \overload void TQPainter::drawChord( const TQRect &r, int a, int alen )
+
+ Draws a chord that fits inside the rectangle \a r with start angle
+ \a a and arc length \a alen.
+*/
+
+/*!
+ \overload void TQPainter::drawPixmap( const TQPoint &p, const TQPixmap &pm, const TQRect &sr )
+
+ Draws the rectangle \a sr of pixmap \a pm with its origin at point
+ \a p.
+*/
+
+/*!
+ \overload void TQPainter::drawPixmap( const TQPoint &p, const TQPixmap &pm )
+
+ Draws the pixmap \a pm with its origin at point \a p.
+*/
+
+void TQPainter::drawPixmap( const TQPoint &p, const TQPixmap &pm )
+{
+ drawPixmap( p.x(), p.y(), pm, 0, 0, pm.width(), pm.height() );
+}
+
+#if !defined(TQT_NO_IMAGE_SMOOTHSCALE) || !defined(TQT_NO_PIXMAP_TRANSFORMATION)
+
+/*!
+ \overload
+
+ Draws the pixmap \a pm into the rectangle \a r. The pixmap is
+ scaled to fit the rectangle, if image and rectangle size disagree.
+*/
+void TQPainter::drawPixmap( const TQRect &r, const TQPixmap &pm )
+{
+ int rw = r.width();
+ int rh = r.height();
+ int iw= pm.width();
+ int ih = pm.height();
+ if ( rw <= 0 || rh <= 0 || iw <= 0 || ih <= 0 )
+ return;
+ bool scale = ( rw != iw || rh != ih );
+ float scaleX = (float)rw/(float)iw;
+ float scaleY = (float)rh/(float)ih;
+ bool smooth = ( scaleX < 1.5 || scaleY < 1.5 );
+
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[2];
+ param[0].rect = &r;
+ param[1].pixmap = &pm;
+#if defined(TQ_WS_WIN)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawPixmap, this, param ) || !hdc )
+ return;
+#elif defined(TQ_WS_TQWS)
+ pdev->cmd( TQPaintDevice::PdcDrawPixmap, this, param );
+ return;
+#elif defined(TQ_WS_MAC)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawPixmap, this, param ) || !pdev->handle())
+ return;
+#else
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawPixmap, this, param ) || !hd )
+ return;
+#endif
+ }
+
+ TQPixmap pixmap = pm;
+
+ if ( scale ) {
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+# ifndef TQT_NO_PIXMAP_TRANSFORMATION
+ if ( smooth )
+# endif
+ {
+ TQImage i = pm.convertToImage();
+ pixmap = TQPixmap( i.smoothScale( rw, rh ) );
+ }
+# ifndef TQT_NO_PIXMAP_TRANSFORMATION
+ else
+# endif
+#endif
+#ifndef TQT_NO_PIXMAP_TRANSFORMATION
+ {
+ pixmap = pm.xForm( TQWMatrix( scaleX, 0, 0, scaleY, 0, 0 ) );
+ }
+#endif
+ }
+ drawPixmap( r.x(), r.y(), pixmap );
+}
+
+#endif
+
+/*!
+ \overload void TQPainter::drawImage( const TQPoint &, const TQImage &, const TQRect &sr, int conversionFlags = 0 );
+
+ Draws the rectangle \a sr from the image at the given point.
+*/
+
+/*
+ Draws at point \a p the \sr rect from image \a pm, using \a
+ conversionFlags if the image needs to be converted to a pixmap.
+ The default value for \a conversionFlags is 0; see
+ convertFromImage() for information about what other values do.
+
+ This function may convert \a image to a pixmap and then draw it, if
+ tqdevice() is a TQPixmap or a TQWidget, or else draw it directly, if
+ tqdevice() is a TQPrinter or TQPicture.
+*/
+
+/*!
+ Draws at (\a x, \a y) the \a sw by \a sh area of pixels from (\a
+ sx, \a sy) in \a image, using \a conversionFlags if the image
+ needs to be converted to a pixmap. The default value for \a
+ conversionFlags is 0; see convertFromImage() for information about
+ what other values do.
+
+ This function may convert \a image to a pixmap and then draw it,
+ if tqdevice() is a TQPixmap or a TQWidget, or else draw it directly,
+ if tqdevice() is a TQPrinter or TQPicture.
+
+ Currently alpha masks of the image are ignored when painting on a TQPrinter.
+
+ \sa drawPixmap() TQPixmap::convertFromImage()
+*/
+void TQPainter::drawImage( int x, int y, const TQImage & image,
+ int sx, int sy, int sw, int sh,
+ int conversionFlags )
+{
+#ifdef TQ_WS_TQWS
+ //### Hackish
+# ifndef TQT_NO_TRANSFORMATIONS
+ if ( !image.isNull() && gfx &&
+ (txop==TxNone||txop==TxTranslate) && !testf(ExtDev) )
+# else
+ if ( !image.isNull() && gfx && !testf(ExtDev) )
+# endif
+ {
+ if(sw<0)
+ sw=image.width();
+ if(sh<0)
+ sh=image.height();
+
+ TQImage image2 = qt_screen->mapToDevice( image );
+
+ // This is a bit dubious
+ if(image2.depth()==1) {
+ image2.setNumColors( 2 );
+ image2.setColor( 0, tqRgb(255,255,255) );
+ image2.setColor( 1, tqRgb(0,0,0) );
+ }
+ if ( image2.hasAlphaBuffer() )
+ gfx->setAlphaType(TQGfx::InlineAlpha);
+ else
+ gfx->setAlphaType(TQGfx::IgnoreAlpha);
+ gfx->setSource(&image2);
+ if ( testf(VxF|WxF) ) {
+ map( x, y, &x, &y );
+ }
+ gfx->blt(x,y,sw,sh,sx,sy);
+ return;
+ }
+#endif
+
+ if ( !isActive() || image.isNull() )
+ return;
+
+ // right/bottom
+ if ( sw < 0 )
+ sw = image.width() - sx;
+ if ( sh < 0 )
+ sh = image.height() - sy;
+
+ // Sanity-check clipping
+ if ( sx < 0 ) {
+ x -= sx;
+ sw += sx;
+ sx = 0;
+ }
+ if ( sw + sx > image.width() )
+ sw = image.width() - sx;
+ if ( sy < 0 ) {
+ y -= sy;
+ sh += sy;
+ sy = 0;
+ }
+ if ( sh + sy > image.height() )
+ sh = image.height() - sy;
+
+ if ( sw <= 0 || sh <= 0 )
+ return;
+
+ bool all = image.rect().intersect(TQRect(sx,sy,sw,sh)) == image.rect();
+ TQImage subimage = all ? image : image.copy(sx,sy,sw,sh);
+
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[2];
+ TQRect r( x, y, subimage.width(), subimage.height() );
+ param[0].rect = &r;
+ param[1].image = &subimage;
+#if defined(TQ_WS_WIN)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !hdc )
+ return;
+#elif defined (TQ_WS_TQWS)
+ pdev->cmd( TQPaintDevice::PdcDrawImage, this, param );
+ return;
+#elif defined(TQ_WS_MAC)
+ if(!pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !pdev->handle() )
+ return;
+#else
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !hd )
+ return;
+#endif
+ }
+
+ TQPixmap pm;
+ pm.convertFromImage( subimage, conversionFlags );
+ drawPixmap( x, y, pm );
+}
+
+/*!
+ \overload void TQPainter::drawImage( const TQPoint &p, const TQImage &i, int conversion_flags )
+
+ Draws the image \a i at point \a p.
+
+ If the image needs to be modified to fit in a lower-resolution
+ result (e.g. converting from 32-bit to 8-bit), use the \a
+ conversion_flags to specify how you'd prefer this to happen.
+
+ \sa TQt::ImageConversionFlags
+*/
+void TQPainter::drawImage( const TQPoint & p, const TQImage & i,
+ int conversion_flags )
+{
+ drawImage(p, i, i.rect(), conversion_flags);
+}
+
+#if !defined(TQT_NO_IMAGE_TRANSFORMATION) || !defined(TQT_NO_IMAGE_SMOOTHSCALE)
+
+/*!
+ \overload
+
+ Draws the image \a i into the rectangle \a r. The image will be
+ scaled to fit the rectangle if image and rectangle dimensions
+ differ.
+*/
+void TQPainter::drawImage( const TQRect &r, const TQImage &i )
+{
+ int rw = r.width();
+ int rh = r.height();
+ int iw= i.width();
+ int ih = i.height();
+ if ( rw <= 0 || rh <= 0 || iw <= 0 || ih <= 0 )
+ return;
+
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[2];
+ param[0].rect = &r;
+ param[1].image = &i;
+#if defined(TQ_WS_WIN)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !hdc )
+ return;
+#elif defined(TQ_WS_TQWS)
+ pdev->cmd( TQPaintDevice::PdcDrawImage, this, param );
+ return;
+#elif defined(TQ_WS_MAC)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !pdev->handle() )
+ return;
+#else
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawImage, this, param ) || !hd )
+ return;
+#endif
+ }
+
+
+ bool scale = ( rw != iw || rh != ih );
+ float scaleX = (float)rw/(float)iw;
+ float scaleY = (float)rh/(float)ih;
+ bool smooth = ( scaleX < 1.5 || scaleY < 1.5 );
+
+ TQImage img = scale
+ ? (
+#if defined(TQT_NO_IMAGE_TRANSFORMATION)
+ i.smoothScale( rw, rh )
+#elif defined(TQT_NO_IMAGE_SMOOTHSCALE)
+ i.scale( rw, rh )
+#else
+ smooth ? i.smoothScale( rw, rh ) : i.scale( rw, rh )
+#endif
+ )
+ : i;
+
+ drawImage( r.x(), r.y(), img );
+}
+
+#endif
+
+
+void bitBlt( TQPaintDevice *dst, int dx, int dy,
+ const TQImage *src, int sx, int sy, int sw, int sh,
+ int conversion_flags )
+{
+ TQPixmap tmp;
+ if ( sx == 0 && sy == 0
+ && (sw<0 || sw==src->width()) && (sh<0 || sh==src->height()) )
+ {
+ tmp.convertFromImage( *src, conversion_flags );
+ } else {
+ tmp.convertFromImage( src->copy( sx, sy, sw, sh, conversion_flags),
+ conversion_flags );
+ }
+ bitBlt( dst, dx, dy, &tmp );
+}
+
+
+/*!
+ \overload void TQPainter::drawTiledPixmap( const TQRect &r, const TQPixmap &pm, const TQPoint &sp )
+
+ Draws a tiled pixmap, \a pm, inside rectangle \a r with its origin
+ at point \a sp.
+*/
+
+/*!
+ \overload void TQPainter::drawTiledPixmap( const TQRect &r, const TQPixmap &pm )
+
+ Draws a tiled pixmap, \a pm, inside rectangle \a r.
+*/
+
+/*!
+ \overload void TQPainter::fillRect( const TQRect &r, const TQBrush &brush )
+
+ Fills the rectangle \a r using brush \a brush.
+*/
+
+/*!
+ \fn void TQPainter::eraseRect( int x, int y, int w, int h )
+
+ Erases the area inside \a x, \a y, \a w, \a h. Equivalent to
+ \c{fillRect( x, y, w, h, backgroundColor() )}.
+*/
+
+/*!
+ \overload void TQPainter::eraseRect( const TQRect &r )
+
+ Erases the area inside the rectangle \a r.
+*/
+
+/*!
+ \fn TQPainter::drawText( int x, int y, const TQString &, int len = -1, TextDirection dir = Auto )
+
+ \overload
+
+ Draws the given text at position \a x, \a y. If \a len is -1 (the
+ default) all the text is drawn, otherwise the first \a len
+ characters are drawn. The text's direction is given by \a dir.
+
+ \sa TQPainter::TextDirection
+*/
+
+/*!
+ \fn void TQPainter::drawText( int x, int y, int w, int h, int flags,
+ const TQString&, int len = -1, TQRect *br=0,
+ TQTextParag **internal=0 )
+
+ \overload
+
+ Draws the given text within the rectangle starting at \a x, \a y,
+ with width \a w and height \a h. If \a len is -1 (the default) all
+ the text is drawn, otherwise the first \a len characters are
+ drawn. The text's flags that are given in the \a flags parameter
+ are \l{TQt::AlignmentFlags} and \l{TQt::TextFlags} OR'd together. \a
+ br (if not null) is set to the actual bounding rectangle of the
+ output. The \a internal parameter is for internal use only.
+*/
+
+/*!
+ \fn void TQPainter::drawText( const TQPoint &, const TQString &, int len = -1, TextDirection dir = Auto );
+
+ \overload
+
+ Draws the text at the given point.
+
+ \sa TQPainter::TextDirection
+*/
+
+/*
+ Draws the text in \a s at point \a p. If \a len is -1 the entire
+ string is drawn, otherwise just the first \a len characters. The
+ text's direction is specified by \a dir.
+*/
+
+
+/*!
+ \fn void TQPainter::drawText( int x, int y, const TQString &, int pos, int len, TextDirection dir = Auto );
+
+ \overload
+
+ Draws the text from position \a pos, at point \a (x, y). If \a len is
+ -1 the entire string is drawn, otherwise just the first \a len
+ characters. The text's direction is specified by \a dir.
+*/
+
+/*!
+ \fn void TQPainter::drawText( const TQPoint &p, const TQString &, int pos, int len, TextDirection dir = Auto );
+
+ Draws the text from position \a pos, at point \a p. If \a len is
+ -1 the entire string is drawn, otherwise just the first \a len
+ characters. The text's direction is specified by \a dir.
+
+ Note that the meaning of \e y is not the same for the two
+ drawText() varieties. For overloads that take a simple \e x, \e y
+ pair (or a point), the \e y value is the text's baseline; for
+ overloads that take a rectangle, \e rect.y() is the top of the
+ rectangle and the text is aligned within that rectangle in
+ accordance with the tqalignment flags.
+
+ \sa TQPainter::TextDirection
+*/
+
+/*!
+ \fn void TQPainter::tqdrawTextItem(const TQPoint &, const TQTextItem &, int)
+ \internal
+*/
+
+static inline void fix_neg_rect( int *x, int *y, int *w, int *h )
+{
+ if ( *w < 0 ) {
+ *w = -*w + 2;
+ *x -= *w - 1;
+ }
+ if ( *h < 0 ) {
+ *h = -*h + 2;
+ *y -= *h - 1;
+ }
+}
+void TQPainter::fix_neg_rect( int *x, int *y, int *w, int *h )
+{
+ ::fix_neg_rect(x,y,w,h);
+}
+
+//
+// The drawText function takes two special parameters; 'internal' and 'brect'.
+//
+// The 'internal' parameter tqcontains a pointer to an array of encoded
+// information that keeps internal tqgeometry data.
+// If the drawText function is called repeatedly to display the same text,
+// it makes sense to calculate text width and linebreaks the first time,
+// and use these parameters later to print the text because we save a lot of
+// CPU time.
+// The 'internal' parameter will not be used if it is a null pointer.
+// The 'internal' parameter will be generated if it is not null, but points
+// to a null pointer, i.e. internal != 0 && *internal == 0.
+// The 'internal' parameter will be used if it tqcontains a non-null pointer.
+//
+// If the 'brect parameter is a non-null pointer, then the bounding rectangle
+// of the text will be returned in 'brect'.
+//
+
+/*!
+ \overload
+
+ Draws at most \a len characters from \a str in the rectangle \a r.
+
+ This function draws formatted text. The \a tf text format is
+ really of type \l TQt::AlignmentFlags and \l TQt::TextFlags OR'd
+ together.
+
+ Horizontal tqalignment defaults to AlignAuto and vertical tqalignment
+ defaults to AlignTop.
+
+ \a brect (if not null) is set to the actual bounding rectangle of
+ the output. \a internal is, yes, internal.
+
+ \sa boundingRect()
+*/
+
+void TQPainter::drawText( const TQRect &r, int tf,
+ const TQString& str, int len, TQRect *brect,
+ TQTextParag **internal )
+{
+ if ( !isActive() )
+ return;
+ if ( len < 0 )
+ len = str.length();
+ if ( len == 0 ) // empty string
+ return;
+
+ if ( testf(DirtyFont|ExtDev) ) {
+ if ( testf(DirtyFont) )
+ updateFont();
+ if ( testf(ExtDev) && (tf & DontPrint) == 0 ) {
+ TQPDevCmdParam param[3];
+ TQString newstr = str;
+ newstr.truncate( len );
+ param[0].rect = &r;
+ param[1].ival = tf;
+ param[2].str = &newstr;
+ if ( pdev->devType() != TQInternal::Printer ) {
+#if defined(TQ_WS_WIN)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawText2Formatted,
+ this, param) ||
+ !hdc )
+ return; // TQPrinter wants PdcDrawText2
+#elif defined(TQ_WS_TQWS)
+ pdev->cmd( TQPaintDevice::PdcDrawText2Formatted, this, param);
+ return;
+#elif defined(TQ_WS_MAC)
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawText2Formatted, this, param) ||
+ !pdev->handle())
+ return; // TQPrinter wants PdcDrawText2
+#else
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawText2Formatted,
+ this, param) ||
+ !hd )
+ return; // TQPrinter wants PdcDrawText2
+#endif
+ }
+ }
+ }
+
+ qt_format_text(font(), r, tf, str, len, brect,
+ tabstops, tabarray, tabarraylen, internal, this);
+}
+
+//#define TQT_FORMAT_TEXT_DEBUG
+
+#define TQChar_linesep TQChar(0x2028U)
+
+void qt_format_text( const TQFont& font, const TQRect &_r,
+ int tf, const TQString& str, int len, TQRect *brect,
+ int tabstops, int* tabarray, int tabarraylen,
+ TQTextParag **, TQPainter* painter )
+{
+ // we need to copy r here to protect against the case (&r == brect).
+ TQRect r( _r );
+
+ bool dontclip = (tf & TQt::DontClip) == TQt::DontClip;
+ bool wordbreak = (tf & TQt::WordBreak) == TQt::WordBreak;
+ bool singleline = (tf & TQt::SingleLine) == TQt::SingleLine;
+ bool showprefix = (tf & TQt::ShowPrefix) == TQt::ShowPrefix;
+ bool noaccel = ( tf & TQt::NoAccel ) == TQt::NoAccel;
+
+ bool isRightToLeft = str.isRightToLeft();
+ if ( ( tf & TQt::AlignHorizontal_Mask ) == TQt::AlignAuto )
+ tf |= isRightToLeft ? TQt::AlignRight : TQt::AlignLeft;
+
+ bool expandtabs = ( (tf & TQt::ExpandTabs) &&
+ ( ( (tf & TQt::AlignLeft) && !isRightToLeft ) ||
+ ( (tf & TQt::AlignRight) && isRightToLeft ) ) );
+
+ if ( !painter )
+ tf |= TQt::DontPrint;
+
+ int maxUnderlines = 0;
+ int numUnderlines = 0;
+ int underlinePositionStack[32];
+ int *underlinePositions = underlinePositionStack;
+
+ TQFont fnt(painter ? (painter->pfont ? *painter->pfont : painter->cfont) : font);
+ TQFontMetrics fm( fnt );
+
+ TQString text = str;
+ // str.setLength() always does a deep copy, so the tqreplacement
+ // code below is safe.
+ text.setLength( len );
+ // compatible behaviour to the old implementation. Replace
+ // tabs by spaces
+ TQChar *chr = (TQChar*)text.tqunicode();
+ const TQChar *end = chr + len;
+ bool haveLineSep = FALSE;
+ while ( chr != end ) {
+ if ( *chr == '\r' || ( singleline && *chr == '\n' ) ) {
+ *chr = ' ';
+ } else if ( *chr == '\n' ) {
+ *chr = TQChar_linesep;
+ haveLineSep = TRUE;
+ } else if ( *chr == '&' ) {
+ ++maxUnderlines;
+ }
+ ++chr;
+ }
+ if ( !expandtabs ) {
+ chr = (TQChar*)text.tqunicode();
+ while ( chr != end ) {
+ if ( *chr == '\t' )
+ *chr = ' ';
+ ++chr;
+ }
+ } else if (!tabarraylen && !tabstops) {
+ tabstops = fm.width('x')*8;
+ }
+
+ if ( noaccel || showprefix ) {
+ if ( maxUnderlines > 32 )
+ underlinePositions = new int[maxUnderlines];
+ TQChar *cout = (TQChar*)text.tqunicode();
+ TQChar *cin = cout;
+ int l = len;
+ while ( l ) {
+ if ( *cin == '&' ) {
+ ++cin;
+ --l;
+ if ( !l )
+ break;
+ if ( *cin != '&' )
+ underlinePositions[numUnderlines++] = cout - text.tqunicode();
+ }
+ *cout = *cin;
+ ++cout;
+ ++cin;
+ --l;
+ }
+ uint newlen = cout - text.tqunicode();
+ if ( newlen != text.length())
+ text.setLength( newlen );
+ }
+
+ // no need to do extra work for underlines if we don't paint
+ if ( tf & TQt::DontPrint )
+ numUnderlines = 0;
+
+ int height = 0;
+ int left = r.width();
+ int right = 0;
+
+ TQTextLayout textLayout( text, fnt );
+ int rb = TQMAX( 0, -fm.minRightBearing() );
+ int lb = TQMAX( 0, -fm.minLeftBearing() );
+
+ if ( text.isEmpty() ) {
+ height = fm.height();
+ left = right = 0;
+ tf |= TQPainter::DontPrint;
+ } else {
+ textLayout.beginLayout((haveLineSep || expandtabs || wordbreak) ?
+ TQTextLayout::MultiLine :
+ (tf & TQt::DontPrint) ? TQTextLayout::NoBidi : TQTextLayout::SingleLine );
+
+ // break underline chars into items of their own
+ for( int i = 0; i < numUnderlines; i++ ) {
+ textLayout.setBoundary( underlinePositions[i] );
+ textLayout.setBoundary( underlinePositions[i]+1 );
+ }
+
+ int lineWidth = wordbreak ? TQMAX(0, r.width()-rb-lb) : INT_MAX;
+ if(!wordbreak)
+ tf |= TQt::IncludeTrailingSpaces;
+
+ int leading = fm.leading();
+ int asc = fm.ascent();
+ int desc = fm.descent();
+ height = -leading;
+
+ //qDebug("\n\nbeginLayout: lw = %d, rectwidth=%d", lineWidth , r.width());
+ while ( !textLayout.atEnd() ) {
+ height += leading;
+ textLayout.beginLine( lineWidth == INT_MAX ? lineWidth : lineWidth );
+ //qDebug("-----beginLine( %d )-----", lineWidth );
+ bool linesep = FALSE;
+ while ( 1 ) {
+ TQTextItem ti = textLayout.currentItem();
+ //qDebug("item: from=%d, ch=%x", ti.from(), text.tqunicode()[ti.from()].tqunicode() );
+ if ( expandtabs && ti.isTab() ) {
+ int tw = 0;
+ int x = textLayout.widthUsed();
+ if ( tabarraylen ) {
+// qDebug("tabarraylen=%d", tabarraylen );
+ int tab = 0;
+ while ( tab < tabarraylen ) {
+ if ( tabarray[tab] > x ) {
+ tw = tabarray[tab] - x;
+ break;
+ }
+ ++tab;
+ }
+ } else {
+ tw = tabstops - (x % tabstops);
+ }
+ //qDebug("tw = %d", tw );
+ if ( tw )
+ ti.setWidth( tw );
+ }
+ if ( ti.isObject() && text.tqunicode()[ti.from()] == TQChar_linesep )
+ linesep = TRUE;
+
+ if ( linesep || textLayout.addCurrentItem() != TQTextLayout::Ok || textLayout.atEnd() )
+ break;
+ }
+
+ int ascent = asc, descent = desc, lineLeft, lineRight;
+ textLayout.setLineWidth( r.width()-rb-lb );
+ textLayout.endLine( 0, height, tf, &ascent, &descent,
+ &lineLeft, &lineRight );
+ //qDebug("finalizing line: lw=%d ascent = %d, descent=%d lineleft=%d lineright=%d", lineWidth, ascent, descent,lineLeft, lineRight );
+ left = TQMIN( left, lineLeft );
+ right = TQMAX( right, lineRight );
+ height += ascent + descent + 1;
+ if ( linesep )
+ textLayout.nextItem();
+ }
+ }
+
+ int yoff = 0;
+ if ( tf & TQt::AlignBottom )
+ yoff = r.height() - height;
+ else if ( tf & TQt::AlignVCenter )
+ yoff = (r.height() - height)/2;
+
+ if ( brect ) {
+ *brect = TQRect( r.x() + left, r.y() + yoff, right-left + lb+rb, height );
+ //qDebug("br = %d %d %d/%d, left=%d, right=%d", brect->x(), brect->y(), brect->width(), brect->height(), left, right);
+ }
+
+ if (!(tf & TQPainter::DontPrint)) {
+ bool restoreClipping = FALSE;
+ bool painterHasClip = FALSE;
+ TQRegion painterClipRegion;
+ if ( !dontclip ) {
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQRegion reg = painter->xmat * r;
+#else
+ TQRegion reg = r;
+ reg.translate( painter->xlatex, painter->xlatey );
+#endif
+ if ( painter->hasClipping() )
+ reg &= painter->clipRegion();
+
+ painterHasClip = painter->hasClipping();
+ painterClipRegion = painter->clipRegion();
+ restoreClipping = TRUE;
+ painter->setClipRegion( reg );
+ } else {
+ if ( painter->hasClipping() ){
+ painterHasClip = painter->hasClipping();
+ painterClipRegion = painter->clipRegion();
+ restoreClipping = TRUE;
+ painter->setClipping( FALSE );
+ }
+ }
+
+ int cUlChar = 0;
+ int _tf = 0;
+ if (fnt.underline()) _tf |= TQt::Underline;
+ if (fnt.overline()) _tf |= TQt::Overline;
+ if (fnt.strikeOut()) _tf |= TQt::StrikeOut;
+
+ //qDebug("have %d items",textLayout.numItems());
+ for ( int i = 0; i < textLayout.numItems(); i++ ) {
+ TQTextItem ti = textLayout.itemAt( i );
+ //qDebug("Item %d: from=%d, length=%d, space=%d x=%d", i, ti.from(), ti.length(), ti.isSpace(), ti.x() );
+ if ( ti.isTab() || ti.isObject() )
+ continue;
+ int textFlags = _tf;
+ if ( !noaccel && numUnderlines > cUlChar && ti.from() == underlinePositions[cUlChar] ) {
+ textFlags |= TQt::Underline;
+ cUlChar++;
+ }
+#if defined(TQ_WS_X11) || defined(TQ_WS_TQWS)
+ if ( painter->bg_mode == TQt::OpaqueMode ) {
+ int h = ti.ascent() + ti.descent() + 1;
+ if (ti.y() + h < height)
+ // don't add leading to last line
+ h += fm.leading();
+ qt_draw_background( painter, r.x()+lb + ti.x(), r.y() + yoff + ti.y() - ti.ascent(),
+ ti.width(), h);
+ }
+#endif
+ painter->tqdrawTextItem( r.x()+lb, r.y() + yoff, ti, textFlags );
+ }
+
+ if ( restoreClipping ) {
+ painter->setClipRegion( painterClipRegion );
+ painter->setClipping( painterHasClip );
+ }
+ }
+
+ if ( underlinePositions != underlinePositionStack )
+ delete [] underlinePositions;
+}
+
+/*!
+ \overload
+
+ Returns the bounding rectangle of the aligned text that would be
+ printed with the corresponding drawText() function using the first
+ \a len characters from \a str if \a len is > -1, or the whole of
+ \a str if \a len is -1. The drawing, and hence the bounding
+ rectangle, is constrained to the rectangle \a r, or to the
+ rectangle required to draw the text, whichever is the larger.
+
+ The \a internal parameter should not be used.
+
+ \sa drawText(), fontMetrics(), TQFontMetrics::boundingRect(), TQt::TextFlags
+*/
+
+TQRect TQPainter::boundingRect( const TQRect &r, int flags,
+ const TQString& str, int len, TQTextParag **internal )
+{
+ TQRect brect;
+ if ( str.isEmpty() )
+ brect.setRect( r.x(),r.y(), 0,0 );
+ else
+ drawText( r, flags | DontPrint, str, len, &brect, internal );
+ return brect;
+}
+
+/*!
+ \fn TQRect TQPainter::boundingRect( int x, int y, int w, int h, int flags, const TQString&, int len = -1, TQTextParag **intern=0 );
+
+ Returns the bounding rectangle of the aligned text that would be
+ printed with the corresponding drawText() function using the first
+ \a len characters of the string if \a len is > -1, or the whole of
+ the string if \a len is -1. The drawing, and hence the bounding
+ rectangle, is constrained to the rectangle that begins at point \a
+ (x, y) with width \a w and hight \a h, or to the
+ rectangle required to draw the text, whichever is the larger.
+
+ The \a flags argument is
+ the bitwise OR of the following flags:
+ \table
+ \header \i Flag \i Meaning
+ \row \i \c AlignAuto \i aligns according to the language, usually left.
+ \row \i \c AlignLeft \i aligns to the left border.
+ \row \i \c AlignRight \i aligns to the right border.
+ \row \i \c AlignHCenter \i aligns horizontally centered.
+ \row \i \c AlignTop \i aligns to the top border.
+ \row \i \c AlignBottom \i aligns to the bottom border.
+ \row \i \c AlignVCenter \i aligns vertically centered.
+ \row \i \c AlignCenter \i (== \c AlignHCenter | \c AlignVCenter).
+ \row \i \c SingleLine \i ignores newline characters in the text.
+ \row \i \c ExpandTabs \i expands tabs.
+ \row \i \c ShowPrefix \i interprets "&x" as "<u>x</u>".
+ \row \i \c WordBreak \i breaks the text to fit the rectangle.
+ \endtable
+
+ Horizontal tqalignment defaults to \c AlignLeft and vertical
+ tqalignment defaults to \c AlignTop.
+
+ If several of the horizontal or several of the vertical tqalignment flags
+ are set, the resulting tqalignment is undefined.
+
+ The \a intern parameter should not be used.
+
+ \sa TQt::TextFlags
+*/
+
+
+
+/*****************************************************************************
+ TQPen member functions
+ *****************************************************************************/
+
+/*!
+ \class TQPen tqpen.h
+ \brief The TQPen class defines how a TQPainter should draw lines and outlines
+ of tqshapes.
+
+ \ingroup graphics
+ \ingroup images
+ \ingroup shared
+ \mainclass
+
+ A pen has a style, width, color, cap style and join style.
+
+ The pen style defines the line type. The default pen style is \c
+ TQt::SolidLine. Setting the style to \c NoPen tells the painter to
+ not draw lines or outlines.
+
+ When drawing 1 pixel wide diagonal lines you can either use a very
+ fast algorithm (specified by a line width of 0, which is the
+ default), or a slower but more accurate algorithm (specified by a
+ line width of 1). For horizontal and vertical lines a line width
+ of 0 is the same as a line width of 1. The cap and join style have
+ no effect on 0-width lines.
+
+ The pen color defines the color of lines and text. The default
+ line color is black. The TQColor documentation lists predefined
+ colors.
+
+ The cap style defines how the end points of lines are drawn. The
+ join style defines how the joins between two lines are drawn when
+ multiple connected lines are drawn (TQPainter::drawPolyline()
+ etc.). The cap and join styles only apply to wide lines, i.e. when
+ the width is 1 or greater.
+
+ Use the TQBrush class to specify fill styles.
+
+ Example:
+ \code
+ TQPainter painter;
+ TQPen pen( red, 2 ); // red solid line, 2 pixels wide
+ painter.begin( &anyPaintDevice ); // paint something
+ painter.setPen( pen ); // set the red, wide pen
+ painter.drawRect( 40,30, 200,100 ); // draw a rectangle
+ painter.setPen( blue ); // set blue pen, 0 pixel width
+ painter.drawLine( 40,30, 240,130 ); // draw a diagonal in rectangle
+ painter.end(); // painting done
+ \endcode
+
+ See the \l TQt::PenStyle enum type for a complete list of pen
+ styles.
+
+ With reference to the end points of lines, for wide (non-0-width)
+ pens it depends on the cap style whether the end point is drawn or
+ not. TQPainter will try to make sure that the end point is drawn
+ for 0-width pens, but this cannot be absolutely guaranteed because
+ the underlying drawing engine is free to use any (typically
+ accelerated) algorithm for drawing 0-width lines. On all tested
+ systems, however, the end point of at least all non-diagonal lines
+ are drawn.
+
+ A pen's color(), width(), style(), capStyle() and joinStyle() can
+ be set in the constructor or later with setColor(), setWidth(),
+ setStyle(), setCapStyle() and setJoinStyle(). Pens may also be
+ compared and streamed.
+
+ \img pen-styles.png Pen styles
+
+ \sa TQPainter, TQPainter::setPen()
+*/
+
+
+/*!
+ \internal
+ Initializes the pen.
+*/
+
+void TQPen::init( const TQColor &color, uint width, uint linestyle )
+{
+ data = new TQPenData;
+ TQ_CHECK_PTR( data );
+ data->style = (PenStyle)(linestyle & MPenStyle);
+ data->width = width;
+ data->color = color;
+ data->linest = linestyle;
+}
+
+/*!
+ Constructs a default black solid line pen with 0 width, which
+ renders lines 1 pixel wide (fast diagonals).
+*/
+
+TQPen::TQPen()
+{
+ init( TQt::black, 0, SolidLine ); // default pen
+}
+
+/*!
+ Constructs a black pen with 0 width (fast diagonals) and style \a
+ style.
+
+ \sa setStyle()
+*/
+
+TQPen::TQPen( PenStyle style )
+{
+ init( TQt::black, 0, style );
+}
+
+/*!
+ Constructs a pen with the specified \a color, \a width and \a
+ style.
+
+ \sa setWidth(), setStyle(), setColor()
+*/
+
+TQPen::TQPen( const TQColor &color, uint width, PenStyle style )
+{
+ init( color, width, style );
+}
+
+/*!
+ Constructs a pen with the specified color \a cl and width \a w.
+ The pen style is set to \a s, the pen cap style to \a c and the
+ pen join style to \a j.
+
+ A line width of 0 will produce a 1 pixel wide line using a fast
+ algorithm for diagonals. A line width of 1 will also produce a 1
+ pixel wide line, but uses a slower more accurate algorithm for
+ diagonals. For horizontal and vertical lines a line width of 0 is
+ the same as a line width of 1. The cap and join style have no
+ effect on 0-width lines.
+
+ \sa setWidth(), setStyle(), setColor()
+*/
+
+TQPen::TQPen( const TQColor &cl, uint w, PenStyle s, PenCapStyle c,
+ PenJoinStyle j )
+{
+ init( cl, w, s | c | j );
+}
+
+/*!
+ Constructs a pen that is a copy of \a p.
+*/
+
+TQPen::TQPen( const TQPen &p )
+{
+ data = p.data;
+ data->ref();
+}
+
+/*!
+ Destroys the pen.
+*/
+
+TQPen::~TQPen()
+{
+ if ( data->deref() )
+ delete data;
+}
+
+
+/*!
+ Detaches from shared pen data to make sure that this pen is the
+ only one referring the data.
+
+ If multiple pens share common data, this pen dereferences the data
+ and gets a copy of the data. Nothing is done if there is just a
+ single reference.
+*/
+
+void TQPen::detach()
+{
+ if ( data->count != 1 )
+ *this = copy();
+}
+
+
+/*!
+ Assigns \a p to this pen and returns a reference to this pen.
+*/
+
+TQPen &TQPen::operator=( const TQPen &p )
+{
+ p.data->ref();
+ if ( data->deref() )
+ delete data;
+ data = p.data;
+ return *this;
+}
+
+
+/*!
+ Returns a \link shclass.html deep copy\endlink of the pen.
+*/
+
+TQPen TQPen::copy() const
+{
+ TQPen p( data->color, data->width, data->style, capStyle(), joinStyle() );
+ return p;
+}
+
+
+/*!
+ \fn PenStyle TQPen::style() const
+
+ Returns the pen style.
+
+ \sa setStyle()
+*/
+
+/*!
+ Sets the pen style to \a s.
+
+ See the \l TQt::PenStyle documentation for a list of all the
+ styles.
+
+ \warning On Mac OS X the style setting (other than \c NoPen and \c
+ SolidLine) have no effect as they are not implemented by the
+ underlying system.
+
+ \warning On Windows 95/98, the style setting (other than \c NoPen
+ and \c SolidLine) has no effect for lines with width greater than
+ 1.
+
+ \sa style()
+*/
+
+void TQPen::setStyle( PenStyle s )
+{
+ if ( data->style == s )
+ return;
+ detach();
+ data->style = s;
+ data->linest = (data->linest & ~MPenStyle) | s;
+}
+
+
+/*!
+ \fn uint TQPen::width() const
+
+ Returns the pen width.
+
+ \sa setWidth()
+*/
+
+/*!
+ Sets the pen width to \a w.
+
+ A line width of 0 will produce a 1 pixel wide line using a fast
+ algorithm for diagonals. A line width of 1 will also produce a 1
+ pixel wide line, but uses a slower more accurate algorithm for
+ diagonals. For horizontal and vertical lines a line width of 0 is
+ the same as a line width of 1. The cap and join style have no
+ effect on 0-width lines.
+
+ \sa width()
+*/
+
+void TQPen::setWidth( uint w )
+{
+ if ( data->width == w )
+ return;
+ detach();
+ data->width = w;
+}
+
+
+/*!
+ Returns the pen's cap style.
+
+ \sa setCapStyle()
+*/
+TQt::PenCapStyle TQPen::capStyle() const
+{
+ return (PenCapStyle)(data->linest & MPenCapStyle);
+}
+
+/*!
+ Sets the pen's cap style to \a c.
+
+ The default value is \c FlatCap. The cap style has no effect on
+ 0-width pens.
+
+ \img pen-cap-styles.png Pen Cap Styles
+
+ \warning On Windows 95/98 and Macintosh, the cap style setting has
+ no effect. Wide lines are rendered as if the cap style was \c
+ SquareCap.
+
+ \sa capStyle()
+*/
+
+void TQPen::setCapStyle( PenCapStyle c )
+{
+ if ( (data->linest & MPenCapStyle) == c )
+ return;
+ detach();
+ data->linest = (data->linest & ~MPenCapStyle) | c;
+}
+
+/*!
+ Returns the pen's join style.
+
+ \sa setJoinStyle()
+*/
+TQt::PenJoinStyle TQPen::joinStyle() const
+{
+ return (PenJoinStyle)(data->linest & MPenJoinStyle);
+}
+
+/*!
+ Sets the pen's join style to \a j.
+
+ The default value is \c MiterJoin. The join style has no effect on
+ 0-width pens.
+
+ \img pen-join-styles.png Pen Join Styles
+
+ \warning On Windows 95/98 and Macintosh, the join style setting
+ has no effect. Wide lines are rendered as if the join style was \c
+ BevelJoin.
+
+ \sa joinStyle()
+*/
+
+void TQPen::setJoinStyle( PenJoinStyle j )
+{
+ if ( (data->linest & MPenJoinStyle) == j )
+ return;
+ detach();
+ data->linest = (data->linest & ~MPenJoinStyle) | j;
+}
+
+/*!
+ \fn const TQColor &TQPen::color() const
+
+ Returns the pen color.
+
+ \sa setColor()
+*/
+
+/*!
+ Sets the pen color to \a c.
+
+ \sa color()
+*/
+
+void TQPen::setColor( const TQColor &c )
+{
+ detach();
+ data->color = c;
+}
+
+
+/*!
+ \fn bool TQPen::operator!=( const TQPen &p ) const
+
+ Returns TRUE if the pen is different from \a p; otherwise returns
+ FALSE.
+
+ Two pens are different if they have different styles, widths or
+ colors.
+
+ \sa operator==()
+*/
+
+/*!
+ Returns TRUE if the pen is equal to \a p; otherwise returns FALSE.
+
+ Two pens are equal if they have equal styles, widths and colors.
+
+ \sa operator!=()
+*/
+
+bool TQPen::operator==( const TQPen &p ) const
+{
+ return (p.data == data) || (p.data->linest == data->linest &&
+ p.data->width == data->width && p.data->color == data->color);
+}
+
+
+/*****************************************************************************
+ TQPen stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQPen
+
+ Writes the pen \a p to the stream \a s and returns a reference to
+ the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQPen &p )
+{
+ // ### width() should not be restricted to 8-bit values
+ if ( s.version() < 3 )
+ return s << (TQ_UINT8)p.style() << (TQ_UINT8)p.width() << p.color();
+ else
+ return s << (TQ_UINT8)( p.style() | p.capStyle() | p.joinStyle() )
+ << (TQ_UINT8)p.width() << p.color();
+}
+
+/*!
+ \relates TQPen
+
+ Reads a pen from the stream \a s into \a p and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQPen &p )
+{
+ TQ_UINT8 style, width;
+ TQColor color;
+ s >> style;
+ s >> width;
+ s >> color;
+ p = TQPen( color, (uint)width, (TQt::PenStyle)style ); // owl
+ return s;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*****************************************************************************
+ TQBrush member functions
+ *****************************************************************************/
+
+/*!
+ \class TQBrush tqbrush.h
+
+ \brief The TQBrush class defines the fill pattern of tqshapes drawn by a TQPainter.
+
+ \ingroup graphics
+ \ingroup images
+ \ingroup shared
+
+ A brush has a style and a color. One of the brush styles is a
+ custom pattern, which is defined by a TQPixmap.
+
+ The brush style defines the fill pattern. The default brush style
+ is \c NoBrush (depending on how you construct a brush). This style
+ tells the painter to not fill tqshapes. The standard style for
+ filling is \c SolidPattern.
+
+ The brush color defines the color of the fill pattern. The TQColor
+ documentation lists the predefined colors.
+
+ Use the TQPen class for specifying line/outline styles.
+
+ Example:
+ \code
+ TQPainter painter;
+ TQBrush brush( yellow ); // yellow solid pattern
+ painter.begin( &anyPaintDevice ); // paint something
+ painter.setBrush( brush ); // set the yellow brush
+ painter.setPen( NoPen ); // do not draw outline
+ painter.drawRect( 40,30, 200,100 ); // draw filled rectangle
+ painter.setBrush( NoBrush ); // do not fill
+ painter.setPen( black ); // set black pen, 0 pixel width
+ painter.drawRect( 10,10, 30,20 ); // draw rectangle outline
+ painter.end(); // painting done
+ \endcode
+
+ See the setStyle() function for a complete list of brush styles.
+
+ \img brush-styles.png Brush Styles
+
+ \sa TQPainter, TQPainter::setBrush(), TQPainter::setBrushOrigin()
+*/
+
+inline TQPixmap *TQBrush::pixmap() const {
+ if (style() != Qt::TexturePattern)
+ return 0;
+ QTexturedBrushData *data = static_cast<QTexturedBrushData*>(d.data());
+ QPixmap &pixmap = data->pixmap();
+ return pixmap.isNull() ? 0 : &pixmap;
+}
+
+/*!
+ \internal
+ Initializes the brush.
+*/
+
+void TQBrush::init( const TQColor &color, BrushStyle style )
+{
+ data = new TQBrushData;
+ TQ_CHECK_PTR( data );
+ data->style = style;
+ data->color = color;
+ data->pixmap = 0;
+}
+
+/*!
+ Constructs a default black brush with the style \c NoBrush (will
+ not fill tqshapes).
+*/
+
+TQBrush::TQBrush()
+{
+ static TQBrushData* defBrushData = 0;
+ if ( !defBrushData ) {
+ static TQSharedCleanupHandler<TQBrushData> defBrushCleanup;
+ defBrushData = new TQBrushData;
+ defBrushData->style = NoBrush;
+ defBrushData->color = TQt::black;
+ defBrushData->pixmap = 0;
+ defBrushCleanup.set( &defBrushData );
+ }
+ data = defBrushData;
+ data->ref();
+}
+
+/*!
+ Constructs a black brush with the style \a style.
+
+ \sa setStyle()
+*/
+
+TQBrush::TQBrush( BrushStyle style )
+{
+ init( TQt::black, style );
+}
+
+/*!
+ Constructs a brush with the color \a color and the style \a style.
+
+ \sa setColor(), setStyle()
+*/
+
+TQBrush::TQBrush( const TQColor &color, BrushStyle style )
+{
+ init( color, style );
+}
+
+/*!
+ Constructs a brush with the color \a color and a custom pattern
+ stored in \a pixmap.
+
+ The color will only have an effect for monochrome pixmaps, i.e.
+ for TQPixmap::depth() == 1.
+
+ Pixmap brushes are currently not supported when printing on X11.
+
+ \sa setColor(), setPixmap()
+*/
+
+TQBrush::TQBrush( const TQColor &color, const TQPixmap &pixmap )
+{
+ init( color, CustomPattern );
+ setPixmap( pixmap );
+}
+
+/*!
+ Constructs a brush that is a \link shclass.html shallow
+ copy\endlink of \a b.
+*/
+
+TQBrush::TQBrush( const TQBrush &b )
+{
+ data = b.data;
+ data->ref();
+}
+
+/*!
+ Destroys the brush.
+*/
+
+TQBrush::~TQBrush()
+{
+ if ( data->deref() ) {
+ delete data->pixmap;
+ delete data;
+ }
+}
+
+
+/*!
+ Detaches from shared brush data to make sure that this brush is
+ the only one referring the data.
+
+ If multiple brushes share common data, this brush dereferences the
+ data and gets a copy of the data. Nothing is done if there is just
+ a single reference.
+*/
+
+void TQBrush::detach()
+{
+ if ( data->count != 1 )
+ *this = copy();
+}
+
+
+/*!
+ Assigns \a b to this brush and returns a reference to this brush.
+*/
+
+TQBrush &TQBrush::operator=( const TQBrush &b )
+{
+ b.data->ref(); // beware of b = b
+ if ( data->deref() ) {
+ delete data->pixmap;
+ delete data;
+ }
+ data = b.data;
+ return *this;
+}
+
+
+/*!
+ Returns a \link shclass.html deep copy\endlink of the brush.
+*/
+
+TQBrush TQBrush::copy() const
+{
+ if ( data->style == CustomPattern ) { // brush has pixmap
+ TQBrush b( data->color, *data->pixmap );
+ return b;
+ } else { // brush has std pattern
+ TQBrush b( data->color, data->style );
+ return b;
+ }
+}
+
+
+/*!
+ \fn BrushStyle TQBrush::style() const
+
+ Returns the brush style.
+
+ \sa setStyle()
+*/
+
+/*!
+ Sets the brush style to \a s.
+
+ The brush styles are:
+ \table
+ \header \i Pattern \i Meaning
+ \row \i NoBrush \i will not fill tqshapes (default).
+ \row \i SolidPattern \i solid (100%) fill pattern.
+ \row \i Dense1Pattern \i11 94% fill pattern.
+ \row \i Dense2Pattern \i11 88% fill pattern.
+ \row \i Dense3Pattern \i11 63% fill pattern.
+ \row \i Dense4Pattern \i11 50% fill pattern.
+ \row \i Dense5Pattern \i11 37% fill pattern.
+ \row \i Dense6Pattern \i11 12% fill pattern.
+ \row \i Dense7Pattern \i11 6% fill pattern.
+ \row \i HorPattern \i horizontal lines pattern.
+ \row \i VerPattern \i vertical lines pattern.
+ \row \i CrossPattern \i crossing lines pattern.
+ \row \i BDiagPattern \i diagonal lines (directed /) pattern.
+ \row \i FDiagPattern \i diagonal lines (directed \) pattern.
+ \row \i DiagCrossPattern \i diagonal crossing lines pattern.
+ \row \i CustomPattern \i set when a pixmap pattern is being used.
+ \endtable
+
+ On Windows, dense and custom patterns cannot be transtqparent.
+
+ See the \link #details Detailed Description\endlink for a picture
+ of all the styles.
+
+ \sa style()
+*/
+
+void TQBrush::setStyle( BrushStyle s ) // set brush style
+{
+ if ( data->style == s )
+ return;
+#if defined(TQT_CHECK_RANGE)
+ if ( s == CustomPattern )
+ qWarning( "TQBrush::setStyle: CustomPattern is for internal use" );
+#endif
+ detach();
+ data->style = s;
+}
+
+
+/*!
+ \fn const TQColor &TQBrush::color() const
+
+ Returns the brush color.
+
+ \sa setColor()
+*/
+
+/*!
+ Sets the brush color to \a c.
+
+ \sa color(), setStyle()
+*/
+
+void TQBrush::setColor( const TQColor &c )
+{
+ detach();
+ data->color = c;
+}
+
+
+/*!
+ \fn TQPixmap *TQBrush::pixmap() const
+
+ Returns a pointer to the custom brush pattern, or 0 if no custom
+ brush pattern has been set.
+
+ \sa setPixmap()
+*/
+
+/*!
+ Sets the brush pixmap to \a pixmap. The style is set to \c
+ CustomPattern.
+
+ The current brush color will only have an effect for monochrome
+ pixmaps, i.e. for TQPixmap::depth() == 1.
+
+ Pixmap brushes are currently not supported when printing on X11.
+
+ \sa pixmap(), color()
+*/
+
+void TQBrush::setPixmap( const TQPixmap &pixmap )
+{
+ detach();
+ if ( data->pixmap )
+ delete data->pixmap;
+ if ( pixmap.isNull() ) {
+ data->style = NoBrush;
+ data->pixmap = 0;
+ } else {
+ data->style = CustomPattern;
+ data->pixmap = new TQPixmap( pixmap );
+ if ( data->pixmap->optimization() == TQPixmap::MemoryOptim )
+ data->pixmap->setOptimization( TQPixmap::NormalOptim );
+ }
+}
+
+
+/*!
+ \fn bool TQBrush::operator!=( const TQBrush &b ) const
+
+ Returns TRUE if the brush is different from \a b; otherwise
+ returns FALSE.
+
+ Two brushes are different if they have different styles, colors or
+ pixmaps.
+
+ \sa operator==()
+*/
+
+/*!
+ Returns TRUE if the brush is equal to \a b; otherwise returns
+ FALSE.
+
+ Two brushes are equal if they have equal styles, colors and
+ pixmaps.
+
+ \sa operator!=()
+*/
+
+bool TQBrush::operator==( const TQBrush &b ) const
+{
+ return (b.data == data) || (b.data->style == data->style &&
+ b.data->color == data->color &&
+ b.data->pixmap == data->pixmap);
+}
+
+
+/*!
+ \fn inline double TQPainter::translationX() const
+ \internal
+*/
+
+/*!
+ \fn inline double TQPainter::translationY() const
+ \internal
+*/
+
+
+/*****************************************************************************
+ TQBrush stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQBrush
+
+ Writes the brush \a b to the stream \a s and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQBrush &b )
+{
+ s << (TQ_UINT8)b.style() << b.color();
+ if ( b.style() == TQt::CustomPattern )
+#ifndef TQT_NO_IMAGEIO
+ s << *b.pixmap();
+#else
+ qWarning("No Image Brush I/O");
+#endif
+ return s;
+}
+
+/*!
+ \relates TQBrush
+
+ Reads the brush \a b from the stream \a s and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQBrush &b )
+{
+ TQ_UINT8 style;
+ TQColor color;
+ s >> style;
+ s >> color;
+ if ( style == TQt::CustomPattern ) {
+#ifndef TQT_NO_IMAGEIO
+ TQPixmap pm;
+ s >> pm;
+ b = TQBrush( color, pm );
+#else
+ qWarning("No Image Brush I/O");
+#endif
+ }
+ else
+ b = TQBrush( color, (TQt::BrushStyle)style );
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqpainter.h b/tqtinterface/qt4/src/kernel/tqpainter.h
new file mode 100644
index 0000000..c491f8b
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpainter.h
@@ -0,0 +1,1019 @@
+/****************************************************************************
+**
+** Definition of TQPainter class
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPAINTER_H
+#define TQPAINTER_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqcolor.h"
+#include "tqfontmetrics.h"
+#include "tqfontinfo.h"
+#include "tqregion.h"
+#include "tqpen.h"
+#include "tqbrush.h"
+#include "tqpointarray.h"
+#include "tqwmatrix.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqwidget.h"
+#include "tqpaintdevice.h"
+#include <QtGui/qpainter.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class Q_COMPAT_EXPORT TQPainter : public QPainter, virtual public TQt
+{
+public:
+ enum TextDirection {
+ Auto,
+ RTL,
+ LTR
+ };
+
+ enum CoordinateMode { CoordDevice, CoordPainter };
+
+ TQPainter();
+ TQPainter( const QWidget *pdev, bool unclipped = FALSE);
+ TQPainter( QPaintDevice *pdev, bool unclipped = FALSE);
+ TQPainter( QWidget *pdev, const QWidget *w, bool unclipped = FALSE );
+ TQPainter( QPaintDevice *pdev, const QWidget *w, bool unclipped = FALSE );
+
+ void flush();
+ void flush( const TQRegion &region, CoordinateMode cm = CoordDevice );
+
+ void drawRect(const QRect &rect);
+ inline void drawRect(int x1, int y1, int w, int h)
+ { drawRect(QRect(x1, y1, w, h)); }
+
+ void drawRoundRect(const QRect &r, int xround = 25, int yround = 25);
+ inline void drawRoundRect(int x, int y, int w, int h, int xround = 25, int yround = 25)
+ { drawRoundRect(QRect(x, y, w, h), xround, yround); }
+
+ void drawEllipse(const QRect &r);
+ inline void drawEllipse(int x, int y, int w, int h)
+ { drawEllipse(QRect(x, y, w, h)); }
+
+ void drawArc(const QRect &r, int a, int alen);
+ inline void drawArc(int x, int y, int w, int h, int a, int alen)
+ { drawArc(QRect(x, y, w, h), a, alen); }
+
+ void drawPie(const QRect &r, int a, int alen);
+ inline void drawPie(int x, int y, int w, int h, int a, int alen)
+ { drawPie(QRect(x, y, w, h), a, alen); }
+
+ void drawChord(const QRect &r, int a, int alen);
+ inline void drawChord(int x, int y, int w, int h, int a, int alen)
+ { drawChord(QRect(x, y, w, h), a, alen); }
+
+ void drawImage( int x, int y, const TQImage image, int sx = 0, int sy = 0, int sw = -1, int sh = -1, int conversionFlags = 0 );
+ void drawImage( const TQPoint p, const TQImage image, const TQRect sr, int conversionFlags = 0 );
+ void drawImage( const TQPoint p, const TQImage image, int conversion_flags = 0 );
+ void drawImage( const TQRect r, const TQImage image );
+
+ void drawLineSegments(const QPolygon &points, int index = 0, int nlines = -1);
+
+ void setBrush(const QBrush &brush);
+ void setBrush(Qt::BrushStyle style);
+ void setBrush(TQt::BrushStyle style);
+
+ inline void tqdrawPixmap( int x, int y, const TQPixmap &tqpm, int sx=0, int sy=0, int sw=-1, int sh=-1 ) { drawPixmap(x, y, tqpm, sx, sy, sw, sh); }
+
+ TQPoint pos() const;
+
+ // Qt4 requires the QPainter to have a valid QPaintDevice (engine) for boundingRect() to work
+ // So, we create one off-screen!
+ #define TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL \
+ bool neededEngine = FALSE; \
+ if (QPainter::isActive() == 0) { \
+ printf("[WARNING] Painter was inactive when TQPainter::boundingRect was called; this indicates a likely problem in painting within your application (check Qt::WA_PaintOutsidePaintEvent == true)\n\r"); \
+ QImage image(1,1,QImage::Format_RGB32); \
+ neededEngine = TRUE; \
+ QPainter::begin(&image); \
+ }
+
+ #define TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL \
+ if (neededEngine == TRUE) { \
+ QPainter::end(); \
+ }
+
+ QRectF boundingRect(const QRectF &rect, int flags, const QString &text);
+ QRect boundingRect(const QRect &rect, int flags, const QString &text);
+ QRect boundingRect(int x, int y, int w, int h, int flags, const QString &text);
+ QRectF boundingRect(const QRectF &rect, const QString &text, const QTextOption &o = QTextOption());
+
+ TQRect boundingRect(const QRect &rect, int flags, const QString &text, int len);
+ TQRect boundingRect(int x, int y, int w, int h, int flags, const QString &text, int len);
+
+ void drawText(const QPointF &p, const QString &s);
+ void drawText(const QPoint &p, const QString &s);
+ void drawText(int x, int y, const QString &s);
+ void drawText(const QPointF &p, const QString &str, int tf, int justificationPadding);
+ void drawText(const QRectF &r, int flags, const QString &text, QRectF *br=0);
+ void drawText(const QRect &r, int flags, const QString &text, QRect *br=0);
+ void drawText(int x, int y, int w, int h, int flags, const QString &text, QRect *br=0);
+ void drawText(const QRectF &r, const QString &text, const QTextOption &o = QTextOption());
+
+ void drawText( int x, int y, const TQString &s, int len = -1, TextDirection dir = Auto );
+ void drawText( const TQPoint &p, const TQString &s, int len = -1, TextDirection dir = Auto );
+ void drawText( int x, int y, const TQString &s, int pos, int len, TextDirection dir = Auto );
+ void drawText( const TQPoint &p, const TQString &s, int pos, int len, TextDirection dir = Auto );
+
+ void drawText(int x, int y, const QString &s, int pos, int len);
+ void drawText(const QPoint &p, const QString &s, int pos, int len);
+ void drawText(int x, int y, const QString &s, int len);
+ void drawText(const QPoint &p, const QString &s, int len);
+ void drawText(const QRect &r, int flags, const QString &str, int len, QRect *br=0);
+ void drawText(int x, int y, int w, int h, int flags, const QString &text, int len, QRect *br=0);
+
+#ifndef TQT_NO_PICTURE
+ void drawPicture( const QPicture );
+ void drawPicture( int x, int y, const QPicture );
+ void drawPicture( const QPoint, const QPicture );
+#endif
+
+ void drawPoints( const TQPointArray& a, int index=0, int npoints=-1 );
+
+ int tabStops() const;
+ void setTabStops( int );
+ int *tabArray() const;
+ void setTabArray( int * );
+
+ TQFontInfo fontInfo() const;
+
+ void map(int x, int y, int *rx, int *ry) const;
+ void map( int, int, int, int, int *, int *, int *, int * ) const;
+ TQPoint xForm(const QPoint &) const; // map virtual -> deviceb
+ TQRect xForm(const QRect &) const;
+// TQPolygon xForm(const QPolygon &) const;
+// TQPolygon xForm(const QPolygon &, int index, int npoints) const;
+ TQPoint xFormDev(const QPoint &) const; // map device -> virtual
+ TQRect xFormDev(const QRect &) const;
+ TQPointArray xForm( const TQPointArray & ) const;
+ TQPointArray xForm( const TQPointArray &, int index, int npoints ) const;
+// TQPolygon xFormDev(const QPolygon &) const;
+// TQPolygon xFormDev(const QPolygon &, int index, int npoints) const;
+ TQPointArray xFormDev( const TQPointArray & ) const;
+ TQPointArray xFormDev( const TQPointArray &, int index, int npoints ) const;
+ qreal translationX() const;
+ qreal translationY() const;
+
+ void resetXForm();
+
+ // [FIXME] The drawWinFocusRect methods below probably need tweaking to exactly match the old Qt3 behaviour
+ void drawWinFocusRect( int x, int y, int w, int h );
+ void drawWinFocusRect( int x, int y, int w, int h, const TQColor &bgColor );
+ void drawWinFocusRect( const TQRect &tqr );
+ void drawWinFocusRect( const TQRect &tqr, const TQColor &bgColor );
+
+// inline const TQWMatrix &tqworldMatrix() const { return (*(static_cast<const TQWMatrix*>(&worldMatrix()))); }
+ const TQWMatrix &tqworldMatrix() const;
+
+ void saveWorldMatrix();
+ void restoreWorldMatrix();
+
+ inline TQPaintDevice *tqdevice() const { return static_cast<TQPaintDevice*>(device()); }
+
+ TQRegion clipRegion( CoordinateMode cm = CoordDevice ) const;
+
+ void setClipRegion( const QRegion &qr, CoordinateMode cm = CoordDevice );
+
+ void setBackgroundColor(const QColor &color);
+ const QColor &backgroundColor() const;
+
+ void setClipRect(const QRectF &qrf, Qt::ClipOperation op = Qt::ReplaceClip);
+ void setClipRect(const QRect &qr, Qt::ClipOperation op = Qt::ReplaceClip);
+ void setClipRect( const TQRect &qr, CoordinateMode cm = CoordDevice );
+ void setClipRect( int x, int y, int w, int h, CoordinateMode cm = CoordDevice );
+
+ inline double m11() const { return deviceTransform().m11(); }
+ inline double m12() const { return deviceTransform().m12(); }
+ inline double m21() const { return deviceTransform().m21(); }
+ inline double m22() const { return deviceTransform().m22(); }
+ inline double dx() const { return deviceTransform().dx(); }
+ inline double dy() const { return deviceTransform().dy(); }
+ inline double im11() const { return deviceTransform().inverted().m11(); }
+ inline double im12() const { return deviceTransform().inverted().m12(); }
+ inline double im21() const { return deviceTransform().inverted().m21(); }
+ inline double im22() const { return deviceTransform().inverted().m22(); }
+ inline double idx() const { return deviceTransform().inverted().dx(); }
+ inline double idy() const { return deviceTransform().inverted().dy(); }
+
+ void moveTo( int x, int y );
+ void moveTo( const TQPoint & );
+ void lineTo( int x, int y );
+ void lineTo( const TQPoint & );
+
+ void tqdrawTextItem( int x, int y, const TQTextItem &ti, int textflags = 0 );
+ void tqdrawTextItem( const TQPoint& p, const TQTextItem &ti, int textflags = 0 );
+
+ static void redirect(QPaintDevice *pdev, QPaintDevice *replacement);
+ static TQPaintDevice *redirect(QPaintDevice *pdev);
+
+ TQt::RasterOp rasterOp() const;
+ void setRasterOp( TQt::RasterOp );
+
+ bool tqbegin( QPaintDevice *pdev, bool unclipped = FALSE );
+ bool tqbegin( QPaintDevice *pdev, const QWidget *init, bool unclipped = FALSE );
+
+ inline void tqdrawPolyline(const QPolygon &pa, int index, int npoints = -1) { drawPolyline(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints); }
+ inline void tqdrawPolygon(const QPolygon &pa, bool winding, int index = 0, int npoints = -1) { drawPolygon(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints, winding ? Qt::WindingFill : Qt::OddEvenFill); }
+ inline void tqdrawPolygon(const QPolygonF &polygon, bool winding, int index = 0, int npoints = -1) { drawPolygon(polygon.constData() + index, npoints == -1 ? polygon.size() - index : npoints, winding ? Qt::WindingFill : Qt::OddEvenFill); }
+ inline void tqdrawConvexPolygon(const QPolygonF &polygon, int index, int npoints = -1) { drawConvexPolygon(polygon.constData() + index, npoints == -1 ? polygon.size() - index : npoints); }
+ inline void tqdrawConvexPolygon(const QPolygon &pa, int index, int npoints = -1) { drawConvexPolygon(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints); }
+// static inline void redirect(QPaintDevice *pdev, QPaintDevice *replacement) { setRedirected(pdev, replacement); }
+// static inline TQPaintDevice *redirect(QPaintDevice *pdev) { return const_cast<QPaintDevice*>(redirected(pdev)); }
+ void setWorldXForm(bool enabled);
+ bool hasWorldXForm() const;
+// inline void resetXForm() { resetTransform(); }
+ void setViewXForm(bool enabled);
+ bool hasViewXForm() const;
+
+#ifndef TQT_NO_BEZIER
+ void drawCubicBezier( const TQPointArray &, int index=0 );
+#endif
+
+ // [FIXME]
+ static void initialize();
+ static void cleanup();
+
+ bool has_qwidget;
+ mutable QWidget* qwidget_ptr;
+
+private:
+ QRect adjustedRectangle(const QRect &r);
+ int rectSubtraction() const;
+ uchar rop;
+ enum { IsActive=0x01, ExtDev=0x02, IsStartingUp=0x04, NoCache=0x08,
+ VxF=0x10, WxF=0x20, ClipOn=0x40, SafePolygon=0x80, MonoDev=0x100,
+ DirtyFont=0x200, DirtyPen=0x400, DirtyBrush=0x800,
+ RGBColor=0x1000, FontMet=0x2000, FontInf=0x4000, CtorBegin=0x8000,
+ UsePrivateCx = 0x10000, VolatileDC = 0x20000, TQt2Compat = 0x40000 };
+// uint flags;
+// bool testf( uint b ) const { return (flags&b)!=0; }
+ bool testf( uint b ) const;
+ void drawWinFocusRect( int x, int y, int w, int h, bool xorPaint, const QColor &penColor );
+ void fix_neg_rect( int *x, int *y, int *w, int *h );
+
+ TQPoint current_penpos;
+
+ Q_DISABLE_COPY(TQPainter)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#else // USE_QT4
+
+class TQGfx;
+class TQTextCodec;
+class TQTextParag;
+class TQPaintDevice;
+class TQTextItem;
+#if defined( TQ_WS_MAC )
+class TQMacSavedPortInfo;
+#endif
+class TQPainterPrivate;
+
+#if defined(TQ_WS_TQWS)
+class TQScreen;
+#endif
+
+class TQ_EXPORT TQPainter : public TQt
+{
+public:
+ enum CoordinateMode { CoordDevice, CoordPainter };
+
+ TQPainter();
+ TQPainter( const TQPaintDevice *, bool unclipped = FALSE );
+ TQPainter( const TQPaintDevice *, const TQWidget *, bool unclipped = FALSE );
+ ~TQPainter();
+
+ bool begin( const TQPaintDevice *, bool unclipped = FALSE );
+ bool begin( const TQPaintDevice *, const TQWidget *, bool unclipped = FALSE );
+ bool end();
+ TQPaintDevice *tqdevice() const;
+
+#ifdef TQ_WS_TQWS
+ TQGfx * internalGfx();
+#ifdef TQT_TQWS_EXPERIMENTAL_SCREENPAINTER
+ bool begin(TQScreen *screen);
+#endif
+#endif
+
+ static void redirect( TQPaintDevice *pdev, TQPaintDevice *tqreplacement );
+ static TQPaintDevice *redirect( TQPaintDevice *pdev );
+
+ bool isActive() const;
+
+ void flush( const TQRegion &region, CoordinateMode cm = CoordDevice );
+ void flush();
+ void save();
+ void restore();
+
+ // Drawing tools
+
+ TQFontMetrics fontMetrics() const;
+ TQFontInfo fontInfo() const;
+
+ const TQFont &font() const;
+ void setFont( const TQFont & );
+ const TQPen &pen() const;
+ void setPen( const TQPen & );
+ void setPen( PenStyle );
+ void setPen( const TQColor & );
+ const TQBrush &brush() const;
+ void setBrush( const TQBrush & );
+ void setBrush( BrushStyle );
+ void setBrush( const TQColor & );
+ TQPoint pos() const;
+
+ // Drawing attributes/modes
+
+ const TQColor &backgroundColor() const;
+ void setBackgroundColor( const TQColor & );
+ BGMode backgroundMode() const;
+ void setBackgroundMode( BGMode );
+ RasterOp rasterOp() const;
+ void setRasterOp( RasterOp );
+ const TQPoint &brushOrigin() const;
+ void setBrushOrigin( int x, int y );
+ void setBrushOrigin( const TQPoint & );
+
+ // Scaling and transformations
+
+// PaintUnit unit() const; // get set painter unit
+// void setUnit( PaintUnit ); // NOT IMPLEMENTED!!!
+
+ bool hasViewXForm() const;
+ bool hasWorldXForm() const;
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ void setViewXForm( bool ); // set xform on/off
+ TQRect window() const; // get window
+ void setWindow( const TQRect & ); // set window
+ void setWindow( int x, int y, int w, int h );
+ TQRect viewport() const; // get viewport
+ void setViewport( const TQRect & ); // set viewport
+ void setViewport( int x, int y, int w, int h );
+
+ void setWorldXForm( bool ); // set world xform on/off
+ const TQWMatrix &tqworldMatrix() const; // get/set world xform matrix
+ void setWorldMatrix( const TQWMatrix &, bool combine=FALSE );
+
+ void saveWorldMatrix();
+ void restoreWorldMatrix();
+
+ void scale( double sx, double sy );
+ void shear( double sh, double sv );
+ void rotate( double a );
+#endif
+ void translate( double dx, double dy );
+ void resetXForm();
+ double translationX() const;
+ double translationY() const;
+
+ TQPoint xForm( const TQPoint & ) const; // map virtual -> tqdevice
+ TQRect xForm( const TQRect & ) const;
+ TQPointArray xForm( const TQPointArray & ) const;
+ TQPointArray xForm( const TQPointArray &, int index, int npoints ) const;
+ TQPoint xFormDev( const TQPoint & ) const; // map tqdevice -> virtual
+ TQRect xFormDev( const TQRect & ) const;
+ TQPointArray xFormDev( const TQPointArray & ) const;
+ TQPointArray xFormDev( const TQPointArray &, int index, int npoints ) const;
+
+ // Clipping
+
+ void setClipping( bool ); // set clipping on/off
+ bool hasClipping() const;
+ TQRegion clipRegion( CoordinateMode = CoordDevice ) const;
+ void setClipRect( const TQRect &, CoordinateMode = CoordDevice ); // set clip rectangle
+ void setClipRect( int x, int y, int w, int h, CoordinateMode = CoordDevice );
+ void setClipRegion( const TQRegion &, CoordinateMode = CoordDevice );// set clip region
+
+ // Graphics drawing functions
+
+ void drawPoint( int x, int y );
+ void drawPoint( const TQPoint & );
+ void drawPoints( const TQPointArray& a,
+ int index=0, int npoints=-1 );
+ void moveTo( int x, int y );
+ void moveTo( const TQPoint & );
+ void lineTo( int x, int y );
+ void lineTo( const TQPoint & );
+ void drawLine( int x1, int y1, int x2, int y2 );
+ void drawLine( const TQPoint &, const TQPoint & );
+ void drawRect( int x, int y, int w, int h );
+ void drawRect( const TQRect & );
+ void drawWinFocusRect( int x, int y, int w, int h );
+ void drawWinFocusRect( int x, int y, int w, int h,
+ const TQColor &bgColor );
+ void drawWinFocusRect( const TQRect & );
+ void drawWinFocusRect( const TQRect &,
+ const TQColor &bgColor );
+ void drawRoundRect( int x, int y, int w, int h, int = 25, int = 25 );
+ void drawRoundRect( const TQRect &, int = 25, int = 25 );
+ void drawEllipse( int x, int y, int w, int h );
+ void drawEllipse( const TQRect & );
+ void drawArc( int x, int y, int w, int h, int a, int alen );
+ void drawArc( const TQRect &, int a, int alen );
+ void drawPie( int x, int y, int w, int h, int a, int alen );
+ void drawPie( const TQRect &, int a, int alen );
+ void drawChord( int x, int y, int w, int h, int a, int alen );
+ void drawChord( const TQRect &, int a, int alen );
+ void drawLineSegments( const TQPointArray &,
+ int index=0, int nlines=-1 );
+ void drawPolyline( const TQPointArray &,
+ int index=0, int npoints=-1 );
+ void drawPolygon( const TQPointArray &, bool winding=FALSE,
+ int index=0, int npoints=-1 );
+ void drawConvexPolygon( const TQPointArray &,
+ int index=0, int npoints=-1 );
+#ifndef TQT_NO_BEZIER
+ void drawCubicBezier( const TQPointArray &, int index=0 );
+#endif
+ void drawPixmap( int x, int y, const TQPixmap &,
+ int sx=0, int sy=0, int sw=-1, int sh=-1 );
+ void drawPixmap( const TQPoint &, const TQPixmap &,
+ const TQRect &sr );
+ void drawPixmap( const TQPoint &, const TQPixmap & );
+ void drawPixmap( const TQRect &, const TQPixmap & );
+ void drawImage( int x, int y, const TQImage &,
+ int sx = 0, int sy = 0, int sw = -1, int sh = -1,
+ int conversionFlags = 0 );
+ void drawImage( const TQPoint &, const TQImage &,
+ const TQRect &sr, int conversionFlags = 0 );
+ void drawImage( const TQPoint &, const TQImage &,
+ int conversion_flags = 0 );
+ void drawImage( const TQRect &, const TQImage & );
+ void drawTiledPixmap( int x, int y, int w, int h, const TQPixmap &,
+ int sx=0, int sy=0 );
+ void drawTiledPixmap( const TQRect &, const TQPixmap &,
+ const TQPoint & );
+ void drawTiledPixmap( const TQRect &, const TQPixmap & );
+#ifndef TQT_NO_PICTURE
+ void drawPicture( const TQPicture & );
+ void drawPicture( int x, int y, const TQPicture & );
+ void drawPicture( const TQPoint &, const TQPicture & );
+#endif
+
+ void fillRect( int x, int y, int w, int h, const TQBrush & );
+ void fillRect( const TQRect &, const TQBrush & );
+ void eraseRect( int x, int y, int w, int h );
+ void eraseRect( const TQRect & );
+
+ // Text drawing functions
+
+ enum TextDirection {
+ Auto,
+ RTL,
+ LTR
+ };
+
+ void drawText( int x, int y, const TQString &, int len = -1, TextDirection dir = Auto );
+ void drawText( const TQPoint &, const TQString &, int len = -1, TextDirection dir = Auto );
+
+ void drawText( int x, int y, const TQString &, int pos, int len, TextDirection dir = Auto );
+ void drawText( const TQPoint &p, const TQString &, int pos, int len, TextDirection dir = Auto );
+
+ void drawText( int x, int y, int w, int h, int flags,
+ const TQString&, int len = -1, TQRect *br=0,
+ TQTextParag **intern=0 );
+ void drawText( const TQRect &, int flags,
+ const TQString&, int len = -1, TQRect *br=0,
+ TQTextParag **intern=0 );
+
+ void tqdrawTextItem( int x, int y, const TQTextItem &ti, int textflags = 0 );
+ void tqdrawTextItem( const TQPoint& p, const TQTextItem &ti, int textflags = 0 );
+
+ TQRect boundingRect( int x, int y, int w, int h, int flags,
+ const TQString&, int len = -1, TQTextParag **intern=0 );
+ TQRect boundingRect( const TQRect &, int flags,
+ const TQString&, int len = -1, TQTextParag **intern=0 );
+
+ int tabStops() const;
+ void setTabStops( int );
+ int *tabArray() const;
+ void setTabArray( int * );
+
+ // Other functions
+
+#if defined(TQ_WS_WIN)
+ HDC handle() const;
+#elif defined(TQ_WS_X11) || defined(TQ_WS_MAC)
+ HANDLE handle() const;
+#endif
+
+
+ static void initialize();
+ static void cleanup();
+
+private:
+ void init();
+ void destroy();
+ void updateFont();
+ void updatePen();
+ void updateBrush();
+#ifndef TQT_NO_TRANSFORMATIONS
+ void updateXForm();
+ void updateInvXForm();
+#endif
+ void map( int, int, int *rx, int *ry ) const;
+ void map( int, int, int, int, int *, int *, int *, int * ) const;
+ void mapInv( int, int, int *, int * ) const;
+ void mapInv( int, int, int, int, int *, int *, int *, int * ) const;
+ void drawPolyInternal( const TQPointArray &, bool close=TRUE );
+ void drawWinFocusRect( int x, int y, int w, int h, bool xorPaint,
+ const TQColor &penColor );
+
+ enum { IsActive=0x01, ExtDev=0x02, IsStartingUp=0x04, NoCache=0x08,
+ VxF=0x10, WxF=0x20, ClipOn=0x40, SafePolygon=0x80, MonoDev=0x100,
+ DirtyFont=0x200, DirtyPen=0x400, DirtyBrush=0x800,
+ RGBColor=0x1000, FontMet=0x2000, FontInf=0x4000, CtorBegin=0x8000,
+ UsePrivateCx = 0x10000, VolatileDC = 0x20000, TQt2Compat = 0x40000 };
+ uint flags;
+ bool testf( uint b ) const { return (flags&b)!=0; }
+ void setf( uint b ) { flags |= b; }
+ void setf( uint b, bool v );
+ void clearf( uint b ) { flags &= (uint)(~b); }
+ void fix_neg_rect( int *x, int *y, int *w, int *h );
+
+ TQPainterPrivate *d;
+ TQPaintDevice *pdev;
+ TQColor bg_col;
+ uchar bg_mode;
+ uchar rop;
+ uchar pu;
+ TQPoint bro;
+ TQFont cfont;
+ TQFont *pfont; // font used for metrics (might be different for printers)
+ TQPen cpen;
+ TQBrush cbrush;
+ TQRegion crgn;
+ int tabstops;
+ int *tabarray;
+ int tabarraylen;
+ bool block_ext; // for temporary blocking of external tqdevices
+
+ // Transformations
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQCOORD wx, wy, ww, wh;
+ TQCOORD vx, vy, vw, vh;
+ TQWMatrix wxmat;
+
+ // Cached composition (and inverse) of transformations
+ TQWMatrix xmat;
+ TQWMatrix ixmat;
+
+
+
+ double m11() const { return xmat.m11(); }
+ double m12() const { return xmat.m12(); }
+ double m21() const { return xmat.m21(); }
+ double m22() const { return xmat.m22(); }
+ double dx() const { return xmat.dx(); }
+ double dy() const { return xmat.dy(); }
+ double im11() const { return ixmat.m11(); }
+ double im12() const { return ixmat.m12(); }
+ double im21() const { return ixmat.m21(); }
+ double im22() const { return ixmat.m22(); }
+ double idx() const { return ixmat.dx(); }
+ double idy() const { return ixmat.dy(); }
+
+ int txop;
+ bool txinv;
+
+#else
+ // even without transformations we still have translations
+ int xlatex;
+ int xlatey;
+#endif
+
+ void *penRef; // pen cache ref
+ void *brushRef; // brush cache ref
+ void *ps_stack;
+ void *wm_stack;
+ void killPStack();
+
+protected:
+#ifdef TQ_OS_TEMP
+ TQPoint internalCurrentPos;
+ uint old_pix; // ### All win platforms in 4.0
+#endif
+#if defined(TQ_WS_WIN)
+ friend class TQFontEngineWin;
+ friend class TQFontEngineBox;
+ TQT_WIN_PAINTER_MEMBERS
+#elif defined(TQ_WS_X11)
+ friend class TQFontEngineXLFD;
+ friend class TQFontEngineXft;
+ friend class TQFontEngineBox;
+ Display *dpy; // current display
+ int scrn; // current screen
+ TQt::HANDLE hd; // handle to drawable
+ TQt::HANDLE rendhd; // handle to Xft draw
+ GC gc; // graphics context (standard)
+ GC gc_brush; // graphics contect for brush
+ TQPoint curPt; // current point
+ uint clip_serial; // clipping serial number
+#elif defined(TQ_WS_MAC)
+ TQt::HANDLE hd; // handle to drawable
+ void initPaintDevice(bool force=FALSE, TQPoint *off=NULL, TQRegion *rgn=NULL);
+ friend const TQRegion &qt_mac_update_painter(TQPainter *, bool);
+ friend class TQFontEngineMac;
+ friend class TQMacPainter;
+#elif defined(TQ_WS_TQWS)
+ friend class TQFontEngine;
+ TQGfx * gfx;
+ friend void qwsUpdateActivePainters();
+#endif
+ friend class TQFontMetrics;
+ friend class TQFontInfo;
+ friend class TQTextLayout;
+ friend void qt_format_text( const TQFont &, const TQRect &r,
+ int tf, const TQString& str, int len, TQRect *brect,
+ int tabstops, int* tabarray, int tabarraylen,
+ TQTextParag **internal, TQPainter* painter );
+ friend void qt_draw_background( TQPainter *p, int x, int y, int w, int h );
+ friend void qt_draw_transformed_rect( TQPainter *p, int x, int y, int w, int h, bool fill );
+ friend class TQPrinter;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQPainter( const TQPainter & );
+ TQPainter &operator=( const TQPainter & );
+#endif
+
+ enum TransformationCodes {
+ TxNone = 0, // transformation codes
+ TxTranslate = 1, // copy in qpainter_*.cpp
+ TxScale = 2,
+ TxRotShear = 3
+ };
+};
+
+
+/*****************************************************************************
+ TQPainter member functions
+ *****************************************************************************/
+
+inline TQPaintDevice *TQPainter::tqdevice() const
+{
+ return pdev;
+}
+
+inline bool TQPainter::isActive() const
+{
+ return testf(IsActive);
+}
+
+inline const TQFont &TQPainter::font() const
+{
+ return cfont;
+}
+
+inline const TQPen &TQPainter::pen() const
+{
+ return cpen;
+}
+
+inline const TQBrush &TQPainter::brush() const
+{
+ return cbrush;
+}
+
+/*
+inline PaintUnit TQPainter::unit() const
+{
+ return (PaintUnit)pu;
+}
+*/
+
+inline const TQColor &TQPainter::backgroundColor() const
+{
+ return bg_col;
+}
+
+inline TQt::BGMode TQPainter::backgroundMode() const
+{
+ return (BGMode)bg_mode;
+}
+
+inline TQt::RasterOp TQPainter::rasterOp() const
+{
+ return (RasterOp)rop;
+}
+
+inline const TQPoint &TQPainter::brushOrigin() const
+{
+ return bro;
+}
+
+inline bool TQPainter::hasViewXForm() const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ return testf(VxF);
+#else
+ return xlatex || xlatey;
+#endif
+}
+
+inline bool TQPainter::hasWorldXForm() const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ return testf(WxF);
+#else
+ return xlatex || xlatey;
+#endif
+}
+
+inline double TQPainter::translationX() const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ return tqworldMatrix().dx();
+#else
+ return xlatex;
+#endif
+}
+
+inline double TQPainter::translationY() const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ return tqworldMatrix().dy();
+#else
+ return xlatey;
+#endif
+}
+
+
+inline bool TQPainter::hasClipping() const
+{
+ return testf(ClipOn);
+}
+
+inline int TQPainter::tabStops() const
+{
+ return tabstops;
+}
+
+inline int *TQPainter::tabArray() const
+{
+ return tabarray;
+}
+
+#if defined(TQ_WS_WIN)
+inline HDC TQPainter::handle() const
+{
+ return hdc;
+}
+#elif defined(TQ_WS_X11) || defined(TQ_WS_MAC)
+inline TQt::HANDLE TQPainter::handle() const
+{
+ return hd;
+}
+#endif
+
+inline void TQPainter::setBrushOrigin( const TQPoint &p )
+{
+ setBrushOrigin( p.x(), p.y() );
+}
+
+#ifndef TQT_NO_TRANSFORMATIONS
+inline void TQPainter::setWindow( const TQRect &r )
+{
+ setWindow( r.x(), r.y(), r.width(), r.height() );
+}
+
+inline void TQPainter::setViewport( const TQRect &r )
+{
+ setViewport( r.x(), r.y(), r.width(), r.height() );
+}
+#endif
+
+inline void TQPainter::setClipRect( int x, int y, int w, int h, CoordinateMode m )
+{
+ setClipRect( TQRect(x,y,w,h), m );
+}
+
+inline void TQPainter::drawPoint( const TQPoint &p )
+{
+ drawPoint( p.x(), p.y() );
+}
+
+inline void TQPainter::moveTo( const TQPoint &p )
+{
+ moveTo( p.x(), p.y() );
+}
+
+inline void TQPainter::lineTo( const TQPoint &p )
+{
+ lineTo( p.x(), p.y() );
+}
+
+inline void TQPainter::drawLine( const TQPoint &p1, const TQPoint &p2 )
+{
+ drawLine( p1.x(), p1.y(), p2.x(), p2.y() );
+}
+
+inline void TQPainter::drawRect( const TQRect &r )
+{
+ drawRect( r.x(), r.y(), r.width(), r.height() );
+}
+
+inline void TQPainter::drawWinFocusRect( const TQRect &r )
+{
+ drawWinFocusRect( r.x(), r.y(), r.width(), r.height() );
+}
+
+inline void TQPainter::drawWinFocusRect( const TQRect &r,const TQColor &penColor )
+{
+ drawWinFocusRect( r.x(), r.y(), r.width(), r.height(), penColor );
+}
+
+inline void TQPainter::drawRoundRect( const TQRect &r, int xRnd, int yRnd )
+{
+ drawRoundRect( r.x(), r.y(), r.width(), r.height(), xRnd, yRnd );
+}
+
+inline void TQPainter::drawEllipse( const TQRect &r )
+{
+ drawEllipse( r.x(), r.y(), r.width(), r.height() );
+}
+
+inline void TQPainter::drawArc( const TQRect &r, int a, int alen )
+{
+ drawArc( r.x(), r.y(), r.width(), r.height(), a, alen );
+}
+
+inline void TQPainter::drawPie( const TQRect &r, int a, int alen )
+{
+ drawPie( r.x(), r.y(), r.width(), r.height(), a, alen );
+}
+
+inline void TQPainter::drawChord( const TQRect &r, int a, int alen )
+{
+ drawChord( r.x(), r.y(), r.width(), r.height(), a, alen );
+}
+
+inline void TQPainter::drawPixmap( const TQPoint &p, const TQPixmap &pm,
+ const TQRect &sr )
+{
+ drawPixmap( p.x(), p.y(), pm, sr.x(), sr.y(), sr.width(), sr.height() );
+}
+
+inline void TQPainter::drawImage( const TQPoint &p, const TQImage &pm,
+ const TQRect &sr, int conversionFlags )
+{
+ drawImage( p.x(), p.y(), pm,
+ sr.x(), sr.y(), sr.width(), sr.height(), conversionFlags );
+}
+
+inline void TQPainter::drawTiledPixmap( const TQRect &r, const TQPixmap &pm,
+ const TQPoint &sp )
+{
+ drawTiledPixmap( r.x(), r.y(), r.width(), r.height(), pm, sp.x(), sp.y() );
+}
+
+inline void TQPainter::drawTiledPixmap( const TQRect &r, const TQPixmap &pm )
+{
+ drawTiledPixmap( r.x(), r.y(), r.width(), r.height(), pm, 0, 0 );
+}
+
+inline void TQPainter::fillRect( const TQRect &r, const TQBrush &brush )
+{
+ fillRect( r.x(), r.y(), r.width(), r.height(), brush );
+}
+
+inline void TQPainter::eraseRect( int x, int y, int w, int h )
+{
+ fillRect( x, y, w, h, backgroundColor() );
+}
+
+inline void TQPainter::eraseRect( const TQRect &r )
+{
+ fillRect( r.x(), r.y(), r.width(), r.height(), backgroundColor() );
+}
+
+inline void TQPainter::drawText( const TQPoint &p, const TQString &s, int len, TextDirection dir )
+{
+ drawText( p.x(), p.y(), s, 0, len, dir );
+}
+
+inline void TQPainter::drawText( const TQPoint &p, const TQString &s, int pos, int len, TextDirection dir )
+{
+ drawText( p.x(), p.y(), s, pos, len, dir );
+}
+
+inline void TQPainter::drawText( int x, int y, int w, int h, int tf,
+ const TQString& str, int len, TQRect *br, TQTextParag **i )
+{
+ TQRect r(x, y, w, h);
+ drawText( r, tf, str, len, br, i );
+}
+
+inline void TQPainter::tqdrawTextItem( const TQPoint& p, const TQTextItem &ti, int textflags )
+{
+ tqdrawTextItem( p.x(), p.y(), ti, textflags );
+}
+
+inline TQRect TQPainter::boundingRect( int x, int y, int w, int h, int tf,
+ const TQString& str, int len, TQTextParag **i )
+{
+ TQRect r(x, y, w, h);
+ return boundingRect( r, tf, str, len, i );
+}
+
+#if defined(TQ_WS_TQWS)
+inline TQGfx * TQPainter::internalGfx()
+{
+ return gfx;
+}
+#endif
+
+#endif // USE_QT4
+
+#endif // TQPAINTER_H
diff --git a/tqtinterface/qt4/src/kernel/tqpainter.h~ b/tqtinterface/qt4/src/kernel/tqpainter.h~
new file mode 100644
index 0000000..f391c79
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpainter.h~
@@ -0,0 +1,993 @@
+/****************************************************************************
+**
+** Definition of TQPainter class
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPAINTER_H
+#define TQPAINTER_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqcolor.h"
+#include "tqfontmetrics.h"
+#include "tqfontinfo.h"
+#include "tqregion.h"
+#include "tqpen.h"
+#include "tqbrush.h"
+#include "tqpointarray.h"
+#include "tqwmatrix.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqwidget.h"
+#include "tqpaintdevice.h"
+#include <QtGui/qpainter.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class Q_COMPAT_EXPORT TQPainter : public QPainter, virtual public TQt
+{
+public:
+ enum TextDirection {
+ Auto,
+ RTL,
+ LTR
+ };
+
+ enum CoordinateMode { CoordDevice, CoordPainter };
+
+ TQPainter();
+ TQPainter( const QWidget *pdev, bool unclipped = FALSE);
+ TQPainter( QPaintDevice *pdev, bool unclipped = FALSE);
+ TQPainter( QWidget *pdev, const QWidget *w, bool unclipped = FALSE );
+ TQPainter( QPaintDevice *pdev, const QWidget *w, bool unclipped = FALSE );
+
+ void flush();
+ void flush( const TQRegion &region, CoordinateMode cm = CoordDevice );
+
+ void drawRect(const QRect &rect);
+ inline void drawRect(int x1, int y1, int w, int h)
+ { drawRect(QRect(x1, y1, w, h)); }
+
+ void drawRoundRect(const QRect &r, int xround = 25, int yround = 25);
+ inline void drawRoundRect(int x, int y, int w, int h, int xround = 25, int yround = 25)
+ { drawRoundRect(QRect(x, y, w, h), xround, yround); }
+
+ void drawEllipse(const QRect &r);
+ inline void drawEllipse(int x, int y, int w, int h)
+ { drawEllipse(QRect(x, y, w, h)); }
+
+ void drawArc(const QRect &r, int a, int alen);
+ inline void drawArc(int x, int y, int w, int h, int a, int alen)
+ { drawArc(QRect(x, y, w, h), a, alen); }
+
+ void drawPie(const QRect &r, int a, int alen);
+ inline void drawPie(int x, int y, int w, int h, int a, int alen)
+ { drawPie(QRect(x, y, w, h), a, alen); }
+
+ void drawChord(const QRect &r, int a, int alen);
+ inline void drawChord(int x, int y, int w, int h, int a, int alen)
+ { drawChord(QRect(x, y, w, h), a, alen); }
+
+ void drawImage( int x, int y, const TQImage image, int sx = 0, int sy = 0, int sw = -1, int sh = -1, int conversionFlags = 0 );
+ void drawImage( const TQPoint &p, const TQImage image, const TQRect &sr, int conversionFlags = 0 );
+ void drawImage( const TQPoint &p, const TQImage image, int conversion_flags = 0 );
+ void drawImage( const TQRect &r, const TQImage image );
+
+ void drawLineSegments(const QPolygon &points, int index = 0, int nlines = -1);
+
+ void setBrush(const QBrush &brush);
+ void setBrush(Qt::BrushStyle style);
+ void setBrush(TQt::BrushStyle style);
+
+ inline void tqdrawPixmap( int x, int y, const TQPixmap &tqpm, int sx=0, int sy=0, int sw=-1, int sh=-1 ) { drawPixmap(x, y, tqpm, sx, sy, sw, sh); }
+
+ TQPoint pos() const;
+
+ // Qt4 requires the QPainter to have a valid QPaintDevice (engine) for boundingRect() to work
+ // So, we create one off-screen!
+ #define TQT_INITIALIZE_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL \
+ bool neededEngine = FALSE; \
+ if (QPainter::isActive() == 0) { \
+ printf("[WARNING] Painter was inactive when TQPainter::boundingRect was called; this indicates a likely problem in painting within your application (check Qt::WA_PaintOutsidePaintEvent == true)\n\r"); \
+ QImage image(1,1,QImage::Format_RGB32); \
+ neededEngine = TRUE; \
+ QPainter::begin(&image); \
+ }
+
+ #define TQT_DESTROY_QPAINTER_TEMPORARY_ENGINE_CONDITIONAL \
+ if (neededEngine == TRUE) { \
+ QPainter::end(); \
+ }
+
+ QRectF boundingRect(const QRectF &rect, int flags, const QString &text);
+ QRect boundingRect(const QRect &rect, int flags, const QString &text);
+ QRect boundingRect(int x, int y, int w, int h, int flags, const QString &text);
+ QRectF boundingRect(const QRectF &rect, const QString &text, const QTextOption &o = QTextOption());
+
+ TQRect boundingRect(const QRect &rect, int flags, const QString &text, int len);
+ TQRect boundingRect(int x, int y, int w, int h, int flags, const QString &text, int len);
+
+ void drawText(const QPointF &p, const QString &s);
+ void drawText(const QPoint &p, const QString &s);
+ void drawText(int x, int y, const QString &s);
+ void drawText(const QPointF &p, const QString &str, int tf, int justificationPadding);
+ void drawText(const QRectF &r, int flags, const QString &text, QRectF *br=0);
+ void drawText(const QRect &r, int flags, const QString &text, QRect *br=0);
+ void drawText(int x, int y, int w, int h, int flags, const QString &text, QRect *br=0);
+ void drawText(const QRectF &r, const QString &text, const QTextOption &o = QTextOption());
+
+ void drawText( int x, int y, const TQString &s, int len = -1, TextDirection dir = Auto );
+ void drawText( const TQPoint &p, const TQString &s, int len = -1, TextDirection dir = Auto );
+ void drawText( int x, int y, const TQString &s, int pos, int len, TextDirection dir = Auto );
+ void drawText( const TQPoint &p, const TQString &s, int pos, int len, TextDirection dir = Auto );
+
+ void drawText(int x, int y, const QString &s, int pos, int len);
+ void drawText(const QPoint &p, const QString &s, int pos, int len);
+ void drawText(int x, int y, const QString &s, int len);
+ void drawText(const QPoint &p, const QString &s, int len);
+ void drawText(const QRect &r, int flags, const QString &str, int len, QRect *br=0);
+ void drawText(int x, int y, int w, int h, int flags, const QString &text, int len, QRect *br=0);
+
+ void map(int x, int y, int *rx, int *ry) const;
+ void map( int, int, int, int, int *, int *, int *, int * ) const;
+ TQPoint xForm(const QPoint &) const; // map virtual -> deviceb
+ TQRect xForm(const QRect &) const;
+// TQPolygon xForm(const QPolygon &) const;
+// TQPolygon xForm(const QPolygon &, int index, int npoints) const;
+ TQPoint xFormDev(const QPoint &) const; // map device -> virtual
+ TQRect xFormDev(const QRect &) const;
+// TQPolygon xFormDev(const QPolygon &) const;
+// TQPolygon xFormDev(const QPolygon &, int index, int npoints) const;
+ qreal translationX() const;
+ qreal translationY() const;
+
+ void resetXForm();
+
+ // [FIXME] The drawWinFocusRect methods below probably need tweaking to exactly match the old Qt3 behaviour
+ void drawWinFocusRect( int x, int y, int w, int h );
+ void drawWinFocusRect( int x, int y, int w, int h, const TQColor &bgColor );
+ void drawWinFocusRect( const TQRect &tqr );
+ void drawWinFocusRect( const TQRect &tqr, const TQColor &bgColor );
+
+// inline const TQWMatrix &tqworldMatrix() const { return (*(static_cast<const TQWMatrix*>(&worldMatrix()))); }
+ const TQWMatrix &tqworldMatrix() const;
+
+ inline TQPaintDevice *tqdevice() const { return static_cast<TQPaintDevice*>(device()); }
+
+ TQRegion clipRegion( CoordinateMode cm = CoordDevice ) const;
+
+ void setClipRegion( const QRegion &qr, CoordinateMode cm = CoordDevice );
+
+ void setBackgroundColor(const QColor &color);
+ const QColor &backgroundColor() const;
+
+ void setClipRect(const QRectF &qrf, Qt::ClipOperation op = Qt::ReplaceClip);
+ void setClipRect(const QRect &qr, Qt::ClipOperation op = Qt::ReplaceClip);
+ void setClipRect( const TQRect &qr, CoordinateMode cm = CoordDevice );
+ void setClipRect( int x, int y, int w, int h, CoordinateMode cm = CoordDevice );
+
+ inline double m11() const { return deviceTransform().m11(); }
+ inline double m12() const { return deviceTransform().m12(); }
+ inline double m21() const { return deviceTransform().m21(); }
+ inline double m22() const { return deviceTransform().m22(); }
+ inline double dx() const { return deviceTransform().dx(); }
+ inline double dy() const { return deviceTransform().dy(); }
+ inline double im11() const { return deviceTransform().inverted().m11(); }
+ inline double im12() const { return deviceTransform().inverted().m12(); }
+ inline double im21() const { return deviceTransform().inverted().m21(); }
+ inline double im22() const { return deviceTransform().inverted().m22(); }
+ inline double idx() const { return deviceTransform().inverted().dx(); }
+ inline double idy() const { return deviceTransform().inverted().dy(); }
+
+ void moveTo( int x, int y );
+ void moveTo( const TQPoint & );
+ void lineTo( int x, int y );
+ void lineTo( const TQPoint & );
+
+ void tqdrawTextItem( int x, int y, const TQTextItem &ti, int textflags = 0 );
+ void tqdrawTextItem( const TQPoint& p, const TQTextItem &ti, int textflags = 0 );
+
+ static void redirect(QPaintDevice *pdev, QPaintDevice *replacement);
+ static TQPaintDevice *redirect(QPaintDevice *pdev);
+
+ TQt::RasterOp rasterOp() const;
+ void setRasterOp( TQt::RasterOp );
+
+ bool tqbegin( QPaintDevice *pdev, bool unclipped = FALSE );
+ bool tqbegin( QPaintDevice *pdev, const QWidget *init, bool unclipped = FALSE );
+
+ inline void tqdrawPolyline(const QPolygon &pa, int index, int npoints = -1) { drawPolyline(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints); }
+ inline void tqdrawPolygon(const QPolygon &pa, bool winding, int index = 0, int npoints = -1) { drawPolygon(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints, winding ? Qt::WindingFill : Qt::OddEvenFill); }
+ inline void tqdrawPolygon(const QPolygonF &polygon, bool winding, int index = 0, int npoints = -1) { drawPolygon(polygon.constData() + index, npoints == -1 ? polygon.size() - index : npoints, winding ? Qt::WindingFill : Qt::OddEvenFill); }
+ inline void tqdrawConvexPolygon(const QPolygonF &polygon, int index, int npoints = -1) { drawConvexPolygon(polygon.constData() + index, npoints == -1 ? polygon.size() - index : npoints); }
+ inline void tqdrawConvexPolygon(const QPolygon &pa, int index, int npoints = -1) { drawConvexPolygon(pa.constData() + index, npoints == -1 ? pa.size() - index : npoints); }
+// static inline void redirect(QPaintDevice *pdev, QPaintDevice *replacement) { setRedirected(pdev, replacement); }
+// static inline TQPaintDevice *redirect(QPaintDevice *pdev) { return const_cast<QPaintDevice*>(redirected(pdev)); }
+ void setWorldXForm(bool enabled);
+ bool hasWorldXForm() const;
+// inline void resetXForm() { resetTransform(); }
+ void setViewXForm(bool enabled);
+ bool hasViewXForm() const;
+
+ // [FIXME]
+ static void initialize();
+ static void cleanup();
+
+ bool has_qwidget;
+ mutable QWidget* qwidget_ptr;
+
+private:
+ QRect adjustedRectangle(const QRect &r);
+ int rectSubtraction() const;
+ uchar rop;
+ enum { IsActive=0x01, ExtDev=0x02, IsStartingUp=0x04, NoCache=0x08,
+ VxF=0x10, WxF=0x20, ClipOn=0x40, SafePolygon=0x80, MonoDev=0x100,
+ DirtyFont=0x200, DirtyPen=0x400, DirtyBrush=0x800,
+ RGBColor=0x1000, FontMet=0x2000, FontInf=0x4000, CtorBegin=0x8000,
+ UsePrivateCx = 0x10000, VolatileDC = 0x20000, TQt2Compat = 0x40000 };
+// uint flags;
+// bool testf( uint b ) const { return (flags&b)!=0; }
+ bool testf( uint b ) const;
+ void drawWinFocusRect( int x, int y, int w, int h, bool xorPaint, const QColor &penColor );
+ void fix_neg_rect( int *x, int *y, int *w, int *h );
+
+ TQPoint current_penpos;
+
+ Q_DISABLE_COPY(TQPainter)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#else // USE_QT4
+
+class TQGfx;
+class TQTextCodec;
+class TQTextParag;
+class TQPaintDevice;
+class TQTextItem;
+#if defined( TQ_WS_MAC )
+class TQMacSavedPortInfo;
+#endif
+class TQPainterPrivate;
+
+#if defined(TQ_WS_TQWS)
+class TQScreen;
+#endif
+
+class TQ_EXPORT TQPainter : public TQt
+{
+public:
+ enum CoordinateMode { CoordDevice, CoordPainter };
+
+ TQPainter();
+ TQPainter( const TQPaintDevice *, bool unclipped = FALSE );
+ TQPainter( const TQPaintDevice *, const TQWidget *, bool unclipped = FALSE );
+ ~TQPainter();
+
+ bool begin( const TQPaintDevice *, bool unclipped = FALSE );
+ bool begin( const TQPaintDevice *, const TQWidget *, bool unclipped = FALSE );
+ bool end();
+ TQPaintDevice *tqdevice() const;
+
+#ifdef TQ_WS_TQWS
+ TQGfx * internalGfx();
+#ifdef TQT_TQWS_EXPERIMENTAL_SCREENPAINTER
+ bool begin(TQScreen *screen);
+#endif
+#endif
+
+ static void redirect( TQPaintDevice *pdev, TQPaintDevice *tqreplacement );
+ static TQPaintDevice *redirect( TQPaintDevice *pdev );
+
+ bool isActive() const;
+
+ void flush( const TQRegion &region, CoordinateMode cm = CoordDevice );
+ void flush();
+ void save();
+ void restore();
+
+ // Drawing tools
+
+ TQFontMetrics fontMetrics() const;
+ TQFontInfo fontInfo() const;
+
+ const TQFont &font() const;
+ void setFont( const TQFont & );
+ const TQPen &pen() const;
+ void setPen( const TQPen & );
+ void setPen( PenStyle );
+ void setPen( const TQColor & );
+ const TQBrush &brush() const;
+ void setBrush( const TQBrush & );
+ void setBrush( BrushStyle );
+ void setBrush( const TQColor & );
+ TQPoint pos() const;
+
+ // Drawing attributes/modes
+
+ const TQColor &backgroundColor() const;
+ void setBackgroundColor( const TQColor & );
+ BGMode backgroundMode() const;
+ void setBackgroundMode( BGMode );
+ RasterOp rasterOp() const;
+ void setRasterOp( RasterOp );
+ const TQPoint &brushOrigin() const;
+ void setBrushOrigin( int x, int y );
+ void setBrushOrigin( const TQPoint & );
+
+ // Scaling and transformations
+
+// PaintUnit unit() const; // get set painter unit
+// void setUnit( PaintUnit ); // NOT IMPLEMENTED!!!
+
+ bool hasViewXForm() const;
+ bool hasWorldXForm() const;
+
+#ifndef TQT_NO_TRANSFORMATIONS
+ void setViewXForm( bool ); // set xform on/off
+ TQRect window() const; // get window
+ void setWindow( const TQRect & ); // set window
+ void setWindow( int x, int y, int w, int h );
+ TQRect viewport() const; // get viewport
+ void setViewport( const TQRect & ); // set viewport
+ void setViewport( int x, int y, int w, int h );
+
+ void setWorldXForm( bool ); // set world xform on/off
+ const TQWMatrix &tqworldMatrix() const; // get/set world xform matrix
+ void setWorldMatrix( const TQWMatrix &, bool combine=FALSE );
+
+ void saveWorldMatrix();
+ void restoreWorldMatrix();
+
+ void scale( double sx, double sy );
+ void shear( double sh, double sv );
+ void rotate( double a );
+#endif
+ void translate( double dx, double dy );
+ void resetXForm();
+ double translationX() const;
+ double translationY() const;
+
+ TQPoint xForm( const TQPoint & ) const; // map virtual -> tqdevice
+ TQRect xForm( const TQRect & ) const;
+ TQPointArray xForm( const TQPointArray & ) const;
+ TQPointArray xForm( const TQPointArray &, int index, int npoints ) const;
+ TQPoint xFormDev( const TQPoint & ) const; // map tqdevice -> virtual
+ TQRect xFormDev( const TQRect & ) const;
+ TQPointArray xFormDev( const TQPointArray & ) const;
+ TQPointArray xFormDev( const TQPointArray &, int index, int npoints ) const;
+
+ // Clipping
+
+ void setClipping( bool ); // set clipping on/off
+ bool hasClipping() const;
+ TQRegion clipRegion( CoordinateMode = CoordDevice ) const;
+ void setClipRect( const TQRect &, CoordinateMode = CoordDevice ); // set clip rectangle
+ void setClipRect( int x, int y, int w, int h, CoordinateMode = CoordDevice );
+ void setClipRegion( const TQRegion &, CoordinateMode = CoordDevice );// set clip region
+
+ // Graphics drawing functions
+
+ void drawPoint( int x, int y );
+ void drawPoint( const TQPoint & );
+ void drawPoints( const TQPointArray& a,
+ int index=0, int npoints=-1 );
+ void moveTo( int x, int y );
+ void moveTo( const TQPoint & );
+ void lineTo( int x, int y );
+ void lineTo( const TQPoint & );
+ void drawLine( int x1, int y1, int x2, int y2 );
+ void drawLine( const TQPoint &, const TQPoint & );
+ void drawRect( int x, int y, int w, int h );
+ void drawRect( const TQRect & );
+ void drawWinFocusRect( int x, int y, int w, int h );
+ void drawWinFocusRect( int x, int y, int w, int h,
+ const TQColor &bgColor );
+ void drawWinFocusRect( const TQRect & );
+ void drawWinFocusRect( const TQRect &,
+ const TQColor &bgColor );
+ void drawRoundRect( int x, int y, int w, int h, int = 25, int = 25 );
+ void drawRoundRect( const TQRect &, int = 25, int = 25 );
+ void drawEllipse( int x, int y, int w, int h );
+ void drawEllipse( const TQRect & );
+ void drawArc( int x, int y, int w, int h, int a, int alen );
+ void drawArc( const TQRect &, int a, int alen );
+ void drawPie( int x, int y, int w, int h, int a, int alen );
+ void drawPie( const TQRect &, int a, int alen );
+ void drawChord( int x, int y, int w, int h, int a, int alen );
+ void drawChord( const TQRect &, int a, int alen );
+ void drawLineSegments( const TQPointArray &,
+ int index=0, int nlines=-1 );
+ void drawPolyline( const TQPointArray &,
+ int index=0, int npoints=-1 );
+ void drawPolygon( const TQPointArray &, bool winding=FALSE,
+ int index=0, int npoints=-1 );
+ void drawConvexPolygon( const TQPointArray &,
+ int index=0, int npoints=-1 );
+#ifndef TQT_NO_BEZIER
+ void drawCubicBezier( const TQPointArray &, int index=0 );
+#endif
+ void drawPixmap( int x, int y, const TQPixmap &,
+ int sx=0, int sy=0, int sw=-1, int sh=-1 );
+ void drawPixmap( const TQPoint &, const TQPixmap &,
+ const TQRect &sr );
+ void drawPixmap( const TQPoint &, const TQPixmap & );
+ void drawPixmap( const TQRect &, const TQPixmap & );
+ void drawImage( int x, int y, const TQImage &,
+ int sx = 0, int sy = 0, int sw = -1, int sh = -1,
+ int conversionFlags = 0 );
+ void drawImage( const TQPoint &, const TQImage &,
+ const TQRect &sr, int conversionFlags = 0 );
+ void drawImage( const TQPoint &, const TQImage &,
+ int conversion_flags = 0 );
+ void drawImage( const TQRect &, const TQImage & );
+ void drawTiledPixmap( int x, int y, int w, int h, const TQPixmap &,
+ int sx=0, int sy=0 );
+ void drawTiledPixmap( const TQRect &, const TQPixmap &,
+ const TQPoint & );
+ void drawTiledPixmap( const TQRect &, const TQPixmap & );
+#ifndef TQT_NO_PICTURE
+ void drawPicture( const TQPicture & );
+ void drawPicture( int x, int y, const TQPicture & );
+ void drawPicture( const TQPoint &, const TQPicture & );
+#endif
+
+ void fillRect( int x, int y, int w, int h, const TQBrush & );
+ void fillRect( const TQRect &, const TQBrush & );
+ void eraseRect( int x, int y, int w, int h );
+ void eraseRect( const TQRect & );
+
+ // Text drawing functions
+
+ enum TextDirection {
+ Auto,
+ RTL,
+ LTR
+ };
+
+ void drawText( int x, int y, const TQString &, int len = -1, TextDirection dir = Auto );
+ void drawText( const TQPoint &, const TQString &, int len = -1, TextDirection dir = Auto );
+
+ void drawText( int x, int y, const TQString &, int pos, int len, TextDirection dir = Auto );
+ void drawText( const TQPoint &p, const TQString &, int pos, int len, TextDirection dir = Auto );
+
+ void drawText( int x, int y, int w, int h, int flags,
+ const TQString&, int len = -1, TQRect *br=0,
+ TQTextParag **intern=0 );
+ void drawText( const TQRect &, int flags,
+ const TQString&, int len = -1, TQRect *br=0,
+ TQTextParag **intern=0 );
+
+ void tqdrawTextItem( int x, int y, const TQTextItem &ti, int textflags = 0 );
+ void tqdrawTextItem( const TQPoint& p, const TQTextItem &ti, int textflags = 0 );
+
+ TQRect boundingRect( int x, int y, int w, int h, int flags,
+ const TQString&, int len = -1, TQTextParag **intern=0 );
+ TQRect boundingRect( const TQRect &, int flags,
+ const TQString&, int len = -1, TQTextParag **intern=0 );
+
+ int tabStops() const;
+ void setTabStops( int );
+ int *tabArray() const;
+ void setTabArray( int * );
+
+ // Other functions
+
+#if defined(TQ_WS_WIN)
+ HDC handle() const;
+#elif defined(TQ_WS_X11) || defined(TQ_WS_MAC)
+ HANDLE handle() const;
+#endif
+
+
+ static void initialize();
+ static void cleanup();
+
+private:
+ void init();
+ void destroy();
+ void updateFont();
+ void updatePen();
+ void updateBrush();
+#ifndef TQT_NO_TRANSFORMATIONS
+ void updateXForm();
+ void updateInvXForm();
+#endif
+ void map( int, int, int *rx, int *ry ) const;
+ void map( int, int, int, int, int *, int *, int *, int * ) const;
+ void mapInv( int, int, int *, int * ) const;
+ void mapInv( int, int, int, int, int *, int *, int *, int * ) const;
+ void drawPolyInternal( const TQPointArray &, bool close=TRUE );
+ void drawWinFocusRect( int x, int y, int w, int h, bool xorPaint,
+ const TQColor &penColor );
+
+ enum { IsActive=0x01, ExtDev=0x02, IsStartingUp=0x04, NoCache=0x08,
+ VxF=0x10, WxF=0x20, ClipOn=0x40, SafePolygon=0x80, MonoDev=0x100,
+ DirtyFont=0x200, DirtyPen=0x400, DirtyBrush=0x800,
+ RGBColor=0x1000, FontMet=0x2000, FontInf=0x4000, CtorBegin=0x8000,
+ UsePrivateCx = 0x10000, VolatileDC = 0x20000, TQt2Compat = 0x40000 };
+ uint flags;
+ bool testf( uint b ) const { return (flags&b)!=0; }
+ void setf( uint b ) { flags |= b; }
+ void setf( uint b, bool v );
+ void clearf( uint b ) { flags &= (uint)(~b); }
+ void fix_neg_rect( int *x, int *y, int *w, int *h );
+
+ TQPainterPrivate *d;
+ TQPaintDevice *pdev;
+ TQColor bg_col;
+ uchar bg_mode;
+ uchar rop;
+ uchar pu;
+ TQPoint bro;
+ TQFont cfont;
+ TQFont *pfont; // font used for metrics (might be different for printers)
+ TQPen cpen;
+ TQBrush cbrush;
+ TQRegion crgn;
+ int tabstops;
+ int *tabarray;
+ int tabarraylen;
+ bool block_ext; // for temporary blocking of external tqdevices
+
+ // Transformations
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQCOORD wx, wy, ww, wh;
+ TQCOORD vx, vy, vw, vh;
+ TQWMatrix wxmat;
+
+ // Cached composition (and inverse) of transformations
+ TQWMatrix xmat;
+ TQWMatrix ixmat;
+
+
+
+ double m11() const { return xmat.m11(); }
+ double m12() const { return xmat.m12(); }
+ double m21() const { return xmat.m21(); }
+ double m22() const { return xmat.m22(); }
+ double dx() const { return xmat.dx(); }
+ double dy() const { return xmat.dy(); }
+ double im11() const { return ixmat.m11(); }
+ double im12() const { return ixmat.m12(); }
+ double im21() const { return ixmat.m21(); }
+ double im22() const { return ixmat.m22(); }
+ double idx() const { return ixmat.dx(); }
+ double idy() const { return ixmat.dy(); }
+
+ int txop;
+ bool txinv;
+
+#else
+ // even without transformations we still have translations
+ int xlatex;
+ int xlatey;
+#endif
+
+ void *penRef; // pen cache ref
+ void *brushRef; // brush cache ref
+ void *ps_stack;
+ void *wm_stack;
+ void killPStack();
+
+protected:
+#ifdef TQ_OS_TEMP
+ TQPoint internalCurrentPos;
+ uint old_pix; // ### All win platforms in 4.0
+#endif
+#if defined(TQ_WS_WIN)
+ friend class TQFontEngineWin;
+ friend class TQFontEngineBox;
+ TQT_WIN_PAINTER_MEMBERS
+#elif defined(TQ_WS_X11)
+ friend class TQFontEngineXLFD;
+ friend class TQFontEngineXft;
+ friend class TQFontEngineBox;
+ Display *dpy; // current display
+ int scrn; // current screen
+ TQt::HANDLE hd; // handle to drawable
+ TQt::HANDLE rendhd; // handle to Xft draw
+ GC gc; // graphics context (standard)
+ GC gc_brush; // graphics contect for brush
+ TQPoint curPt; // current point
+ uint clip_serial; // clipping serial number
+#elif defined(TQ_WS_MAC)
+ TQt::HANDLE hd; // handle to drawable
+ void initPaintDevice(bool force=FALSE, TQPoint *off=NULL, TQRegion *rgn=NULL);
+ friend const TQRegion &qt_mac_update_painter(TQPainter *, bool);
+ friend class TQFontEngineMac;
+ friend class TQMacPainter;
+#elif defined(TQ_WS_TQWS)
+ friend class TQFontEngine;
+ TQGfx * gfx;
+ friend void qwsUpdateActivePainters();
+#endif
+ friend class TQFontMetrics;
+ friend class TQFontInfo;
+ friend class TQTextLayout;
+ friend void qt_format_text( const TQFont &, const TQRect &r,
+ int tf, const TQString& str, int len, TQRect *brect,
+ int tabstops, int* tabarray, int tabarraylen,
+ TQTextParag **internal, TQPainter* painter );
+ friend void qt_draw_background( TQPainter *p, int x, int y, int w, int h );
+ friend void qt_draw_transformed_rect( TQPainter *p, int x, int y, int w, int h, bool fill );
+ friend class TQPrinter;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQPainter( const TQPainter & );
+ TQPainter &operator=( const TQPainter & );
+#endif
+
+ enum TransformationCodes {
+ TxNone = 0, // transformation codes
+ TxTranslate = 1, // copy in qpainter_*.cpp
+ TxScale = 2,
+ TxRotShear = 3
+ };
+};
+
+
+/*****************************************************************************
+ TQPainter member functions
+ *****************************************************************************/
+
+inline TQPaintDevice *TQPainter::tqdevice() const
+{
+ return pdev;
+}
+
+inline bool TQPainter::isActive() const
+{
+ return testf(IsActive);
+}
+
+inline const TQFont &TQPainter::font() const
+{
+ return cfont;
+}
+
+inline const TQPen &TQPainter::pen() const
+{
+ return cpen;
+}
+
+inline const TQBrush &TQPainter::brush() const
+{
+ return cbrush;
+}
+
+/*
+inline PaintUnit TQPainter::unit() const
+{
+ return (PaintUnit)pu;
+}
+*/
+
+inline const TQColor &TQPainter::backgroundColor() const
+{
+ return bg_col;
+}
+
+inline TQt::BGMode TQPainter::backgroundMode() const
+{
+ return (BGMode)bg_mode;
+}
+
+inline TQt::RasterOp TQPainter::rasterOp() const
+{
+ return (RasterOp)rop;
+}
+
+inline const TQPoint &TQPainter::brushOrigin() const
+{
+ return bro;
+}
+
+inline bool TQPainter::hasViewXForm() const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ return testf(VxF);
+#else
+ return xlatex || xlatey;
+#endif
+}
+
+inline bool TQPainter::hasWorldXForm() const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ return testf(WxF);
+#else
+ return xlatex || xlatey;
+#endif
+}
+
+inline double TQPainter::translationX() const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ return tqworldMatrix().dx();
+#else
+ return xlatex;
+#endif
+}
+
+inline double TQPainter::translationY() const
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ return tqworldMatrix().dy();
+#else
+ return xlatey;
+#endif
+}
+
+
+inline bool TQPainter::hasClipping() const
+{
+ return testf(ClipOn);
+}
+
+inline int TQPainter::tabStops() const
+{
+ return tabstops;
+}
+
+inline int *TQPainter::tabArray() const
+{
+ return tabarray;
+}
+
+#if defined(TQ_WS_WIN)
+inline HDC TQPainter::handle() const
+{
+ return hdc;
+}
+#elif defined(TQ_WS_X11) || defined(TQ_WS_MAC)
+inline TQt::HANDLE TQPainter::handle() const
+{
+ return hd;
+}
+#endif
+
+inline void TQPainter::setBrushOrigin( const TQPoint &p )
+{
+ setBrushOrigin( p.x(), p.y() );
+}
+
+#ifndef TQT_NO_TRANSFORMATIONS
+inline void TQPainter::setWindow( const TQRect &r )
+{
+ setWindow( r.x(), r.y(), r.width(), r.height() );
+}
+
+inline void TQPainter::setViewport( const TQRect &r )
+{
+ setViewport( r.x(), r.y(), r.width(), r.height() );
+}
+#endif
+
+inline void TQPainter::setClipRect( int x, int y, int w, int h, CoordinateMode m )
+{
+ setClipRect( TQRect(x,y,w,h), m );
+}
+
+inline void TQPainter::drawPoint( const TQPoint &p )
+{
+ drawPoint( p.x(), p.y() );
+}
+
+inline void TQPainter::moveTo( const TQPoint &p )
+{
+ moveTo( p.x(), p.y() );
+}
+
+inline void TQPainter::lineTo( const TQPoint &p )
+{
+ lineTo( p.x(), p.y() );
+}
+
+inline void TQPainter::drawLine( const TQPoint &p1, const TQPoint &p2 )
+{
+ drawLine( p1.x(), p1.y(), p2.x(), p2.y() );
+}
+
+inline void TQPainter::drawRect( const TQRect &r )
+{
+ drawRect( r.x(), r.y(), r.width(), r.height() );
+}
+
+inline void TQPainter::drawWinFocusRect( const TQRect &r )
+{
+ drawWinFocusRect( r.x(), r.y(), r.width(), r.height() );
+}
+
+inline void TQPainter::drawWinFocusRect( const TQRect &r,const TQColor &penColor )
+{
+ drawWinFocusRect( r.x(), r.y(), r.width(), r.height(), penColor );
+}
+
+inline void TQPainter::drawRoundRect( const TQRect &r, int xRnd, int yRnd )
+{
+ drawRoundRect( r.x(), r.y(), r.width(), r.height(), xRnd, yRnd );
+}
+
+inline void TQPainter::drawEllipse( const TQRect &r )
+{
+ drawEllipse( r.x(), r.y(), r.width(), r.height() );
+}
+
+inline void TQPainter::drawArc( const TQRect &r, int a, int alen )
+{
+ drawArc( r.x(), r.y(), r.width(), r.height(), a, alen );
+}
+
+inline void TQPainter::drawPie( const TQRect &r, int a, int alen )
+{
+ drawPie( r.x(), r.y(), r.width(), r.height(), a, alen );
+}
+
+inline void TQPainter::drawChord( const TQRect &r, int a, int alen )
+{
+ drawChord( r.x(), r.y(), r.width(), r.height(), a, alen );
+}
+
+inline void TQPainter::drawPixmap( const TQPoint &p, const TQPixmap &pm,
+ const TQRect &sr )
+{
+ drawPixmap( p.x(), p.y(), pm, sr.x(), sr.y(), sr.width(), sr.height() );
+}
+
+inline void TQPainter::drawImage( const TQPoint &p, const TQImage &pm,
+ const TQRect &sr, int conversionFlags )
+{
+ drawImage( p.x(), p.y(), pm,
+ sr.x(), sr.y(), sr.width(), sr.height(), conversionFlags );
+}
+
+inline void TQPainter::drawTiledPixmap( const TQRect &r, const TQPixmap &pm,
+ const TQPoint &sp )
+{
+ drawTiledPixmap( r.x(), r.y(), r.width(), r.height(), pm, sp.x(), sp.y() );
+}
+
+inline void TQPainter::drawTiledPixmap( const TQRect &r, const TQPixmap &pm )
+{
+ drawTiledPixmap( r.x(), r.y(), r.width(), r.height(), pm, 0, 0 );
+}
+
+inline void TQPainter::fillRect( const TQRect &r, const TQBrush &brush )
+{
+ fillRect( r.x(), r.y(), r.width(), r.height(), brush );
+}
+
+inline void TQPainter::eraseRect( int x, int y, int w, int h )
+{
+ fillRect( x, y, w, h, backgroundColor() );
+}
+
+inline void TQPainter::eraseRect( const TQRect &r )
+{
+ fillRect( r.x(), r.y(), r.width(), r.height(), backgroundColor() );
+}
+
+inline void TQPainter::drawText( const TQPoint &p, const TQString &s, int len, TextDirection dir )
+{
+ drawText( p.x(), p.y(), s, 0, len, dir );
+}
+
+inline void TQPainter::drawText( const TQPoint &p, const TQString &s, int pos, int len, TextDirection dir )
+{
+ drawText( p.x(), p.y(), s, pos, len, dir );
+}
+
+inline void TQPainter::drawText( int x, int y, int w, int h, int tf,
+ const TQString& str, int len, TQRect *br, TQTextParag **i )
+{
+ TQRect r(x, y, w, h);
+ drawText( r, tf, str, len, br, i );
+}
+
+inline void TQPainter::tqdrawTextItem( const TQPoint& p, const TQTextItem &ti, int textflags )
+{
+ tqdrawTextItem( p.x(), p.y(), ti, textflags );
+}
+
+inline TQRect TQPainter::boundingRect( int x, int y, int w, int h, int tf,
+ const TQString& str, int len, TQTextParag **i )
+{
+ TQRect r(x, y, w, h);
+ return boundingRect( r, tf, str, len, i );
+}
+
+#if defined(TQ_WS_TQWS)
+inline TQGfx * TQPainter::internalGfx()
+{
+ return gfx;
+}
+#endif
+
+#endif // USE_QT4
+
+#endif // TQPAINTER_H
diff --git a/tqtinterface/qt4/src/kernel/tqpainter_p.h b/tqtinterface/qt4/src/kernel/tqpainter_p.h
new file mode 100644
index 0000000..85dedc0
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpainter_p.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Definition of some TQt private functions.
+**
+** Created : 000909
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPAINTER_P_H
+#define TQPAINTER_P_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qpainter.cpp and qfont.cpp. This header file may change
+// from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#endif // TQT_H
+
+extern void qt_format_text( const TQFont& f, const TQRect &r,
+ int tf, const TQString& str, int len, TQRect *brect,
+ int tabstops, int* tabarray, int tabarraylen,
+ TQTextParag **internal, TQPainter* painter );
+
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqpainter_x11.cpp b/tqtinterface/qt4/src/kernel/tqpainter_x11.cpp
new file mode 100644
index 0000000..ac788d4
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpainter_x11.cpp
@@ -0,0 +1,3348 @@
+/****************************************************************************
+**
+** Implementation of TQPainter class for X11
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+#ifdef USE_QT4
+#include <Qt/qtextstream.h>
+#endif // USE_QT4
+
+#include "tqfont.h"
+#include "tqpainter.h"
+#include "tqwidget.h"
+#include "tqbitmap.h"
+#include "tqpixmapcache.h"
+#include "tqtextcodec.h"
+#include "tqpaintdevicemetrics.h"
+
+#include "tqt_x11_p.h"
+
+#include "tqtextlayout_p.h"
+#include "tqfontdata_p.h"
+#include "tqfontengine_p.h"
+#include "tqtextengine_p.h"
+
+#include <math.h>
+
+#ifdef USE_QT4
+
+/*! \internal
+ Draws the text item \a ti at position \a (x, y ).
+
+ This method ignores the painters background mode and
+ color. drawText and qt_format_text have to do it themselves, as
+ only they know the extents of the complete string.
+
+ It ignores the font set on the painter as the text item has one of its own.
+
+ The underline and strikeout parameters of the text items font are
+ ignored as well. You'll need to pass in the correct flags to get
+ underlining and strikeout.
+*/
+void TQPainter::tqdrawTextItem( int x, int y, const TQTextItem &ti, int textFlags )
+{
+ ti.tqt_tqdrawTextItem( const_cast<TQPainter*>(this), x, y, ti, textFlags );
+}
+
+/*!
+ Sets the \link TQt::RasterOp raster operation \endlink to \a r.
+ The default is \c CopyROP.
+
+ \sa rasterOp() TQt::RasterOp
+*/
+
+void TQPainter::setRasterOp( TQt::RasterOp r )
+{
+ if ( !isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::setRasterOp: Call begin() first" );
+#endif
+ return;
+ }
+ if ( (uint)r > TQt::LastROP ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPainter::setRasterOp: Invalid ROP code" );
+#endif
+ return;
+ }
+ rop = r;
+
+// [FIXME]
+// This needs to be implemented for Qt4
+// See http://lists.trolltech.com/qt-interest/2007-05/thread00975-0.html
+// printf("[WARNING] TQPainter::setRasterOp( TQt::RasterOp r ) unimplemented [Was attempting to use raster operation %d\n\r", rop);
+
+// An attempt to work around this on X11 only
+// See http://doc.qt.nokia.com/latest/qpainter.html#CompositionMode-enum
+
+ QPainter::CompositionMode cm;
+ switch (rop) {
+ case CopyROP:
+ cm=QPainter::CompositionMode_SourceOver;
+ break;
+ case OrROP:
+ cm=QPainter::RasterOp_SourceOrDestination;
+ break;
+ case XorROP:
+ cm=QPainter::RasterOp_SourceXorDestination;
+ break;
+ case NotAndROP:
+ cm=QPainter::RasterOp_NotSourceAndDestination;
+ break;
+// case EraseROP:
+// cm=QPainter::RasterOp_NotSourceAndDestination;
+// break;
+ case NotCopyROP:
+ cm=QPainter::RasterOp_NotSource;
+ break;
+ case NotOrROP:
+ printf("[WARNING] TQPainter::setRasterOp( TQt::RasterOp r ) unimplemented [Was attempting to use raster operation %d\n\r", rop);
+ return;
+ break;
+ case NotXorROP:
+ cm=QPainter::RasterOp_NotSourceXorDestination;
+ break;
+ case AndROP:
+ cm=QPainter::RasterOp_SourceAndDestination;
+ break;
+// case NotEraseROP:
+// cm=QPainter::RasterOp_SourceAndDestination;
+// break;
+ case NotROP:
+ cm=QPainter::RasterOp_SourceAndNotDestination; // [WARNING] This may not be a correct substitute for NotROP!
+ break;
+ case ClearROP:
+ cm=QPainter::CompositionMode_Clear;
+ break;
+ case SetROP:
+ printf("[WARNING] TQPainter::setRasterOp( TQt::RasterOp r ) unimplemented [Was attempting to use raster operation %d\n\r", rop);
+ return;
+ break;
+ case NopROP:
+ cm=QPainter::CompositionMode_Destination;
+ break;
+ case AndNotROP:
+ cm=QPainter::RasterOp_SourceAndNotDestination;
+ break;
+ case OrNotROP:
+ printf("[WARNING] TQPainter::setRasterOp( TQt::RasterOp r ) unimplemented [Was attempting to use raster operation %d\n\r", rop);
+ return;
+ break;
+ case NandROP:
+ cm=QPainter::RasterOp_NotSourceOrNotDestination;
+ break;
+ case NorROP:
+ cm=QPainter::RasterOp_NotSourceAndNotDestination;
+ break;
+ }
+
+ setCompositionMode(cm);
+
+// if ( testf(ExtDev) ) {
+// TQPDevCmdParam param[1];
+// param[0].ival = r;
+// if ( !pdev->cmd( TQPaintDevice::PdcSetROP, this, param ) || !hd )
+// return;
+// }
+// if ( penRef )
+// updatePen(); // get non-cached pen GC
+// if ( brushRef )
+// updateBrush(); // get non-cached brush GC
+// XSetFunction( dpy, gc, ropCodes[rop] );
+// XSetFunction( dpy, gc_brush, ropCodes[rop] );
+}
+
+/*!
+ \internal
+*/
+
+void TQPainter::drawWinFocusRect( int x, int y, int w, int h, bool xorPaint, const QColor &bgColor )
+{
+ if ( !isActive() /*|| txop == TxRotShear*/ )
+ return;
+ static char winfocus_line[] = { 1, 1 };
+
+ TQPen old_pen = pen();
+ RasterOp old_rop = (RasterOp)rasterOp();
+
+ if ( xorPaint ) {
+ if ( TQColor::numBitPlanes() <= 8 )
+ setPen( color1 );
+ else
+ setPen( white );
+ setRasterOp( XorROP );
+ } else {
+ if ( tqGray( bgColor.rgb() ) < 128 )
+ setPen( white );
+ else
+ setPen( black );
+ }
+
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+// TQPDevCmdParam param[1];
+// TQRect r( x, y, w, h );
+// param[0].rect = &r;
+// if ( !pdev->cmd( TQPaintDevice::PdcDrawRect, this, param ) || !hd) {
+// setRasterOp( old_rop );
+// setPen( old_pen );
+// return;
+// }
+ printf("[FIXME] TQPainter::drawWinFocusRect not yet supported on external paint devices\n\r");
+ }
+ map( x, y, w, h, &x, &y, &w, &h );
+ }
+// if ( w <= 0 || h <= 0 ) {
+// if ( w == 0 || h == 0 )
+// return;
+// fix_neg_rect( &x, &y, &w, &h );
+// }
+
+// XSetDashes( dpy, gc, 0, winfocus_line, 2 );
+// XSetLineAttributes( dpy, gc, 1, LineOnOffDash, CapButt, JoinMiter );
+// XDrawRectangle( dpy, hd, gc, x, y, w-1, h-1 );
+// XSetLineAttributes( dpy, gc, 0, LineSolid, CapButt, JoinMiter );
+
+ printf("[WARNING] TQPainter::drawWinFocusRect may not draw the correct rectangle in all cases [due to shift from Xorg to Qt painting]\n\r");
+// drawRect( x, y, w-1, h-1 );
+ drawRect( x, y, w, h );
+
+ setRasterOp( old_rop );
+ setPen( old_pen );
+}
+
+#else // USE_QT4
+
+// paintevent magic to provide Windows semantics on X11
+static TQRegion* paintEventClipRegion = 0;
+static TQPaintDevice* paintEventDevice = 0;
+
+void qt_set_paintevent_clipping( TQPaintDevice* dev, const TQRegion& region)
+{
+ if ( !paintEventClipRegion )
+ paintEventClipRegion = new TQRegion( region );
+ else
+ *paintEventClipRegion = region;
+ paintEventDevice = dev;
+}
+
+void qt_clear_paintevent_clipping()
+{
+ delete paintEventClipRegion;
+ paintEventClipRegion = 0;
+ paintEventDevice = 0;
+}
+
+class TQWFlagWidget : public TQWidget
+{
+public:
+ void setWState( WFlags f ) { TQWidget::setWState(f); }
+ void clearWState( WFlags f ) { TQWidget::clearWState(f); }
+ void setWFlags( WFlags f ) { TQWidget::setWFlags(f); }
+ void clearWFlags( WFlags f ) { TQWidget::clearWFlags(f); }
+};
+
+void qt_erase_region( TQWidget* w, const TQRegion& region)
+{
+ TQRegion reg = region;
+
+ if ( TQPainter::redirect(w) || (!w->isTopLevel() && w->backgroundPixmap()
+ && w->backgroundOrigin() != TQWidget::WidgetOrigin) ) {
+ TQPoint offset = w->backgroundOffset();
+ int ox = offset.x();
+ int oy = offset.y();
+
+ bool unclipped = w->testWFlags( TQt::WPaintUnclipped );
+ if ( unclipped )
+ ((TQWFlagWidget*)w)->clearWFlags( TQt::WPaintUnclipped );
+ TQPainter p( w );
+ p.setClipRegion( region ); // automatically includes paintEventDevice if required
+ if ( w->backgroundPixmap() )
+ p.drawTiledPixmap( 0, 0, w->width(), w->height(),
+ *w->backgroundPixmap(), ox, oy );
+ else
+ p.fillRect( w->rect(), w->eraseColor() );
+ if ( unclipped )
+ ((TQWFlagWidget*)w)->setWFlags( TQt::WPaintUnclipped );
+ return;
+ }
+
+ if ( w == paintEventDevice && paintEventClipRegion )
+ reg = paintEventClipRegion->intersect( reg );
+
+ TQMemArray<TQRect> r = reg.rects();
+ for (uint i=0; i<r.size(); i++) {
+ const TQRect& rr = r[(int)i];
+ XClearArea( w->x11Display(), w->winId(),
+ rr.x(), rr.y(), rr.width(), rr.height(), False );
+ }
+}
+
+void qt_erase_rect( TQWidget* w, const TQRect& r)
+{
+ if ( TQPainter::redirect(w) || w == paintEventDevice
+ || w->backgroundOrigin() != TQWidget::WidgetOrigin )
+ qt_erase_region( w, r );
+ else
+ XClearArea( w->x11Display(), w->winId(), r.x(), r.y(), r.width(), r.height(), False );
+
+}
+
+#ifdef TQT_NO_XFTFREETYPE
+static const TQt::HANDLE rendhd = 0;
+#endif
+
+// hack, so we don't have to make TQRegion::clipRectangles() public or include
+// X11 headers in tqregion.h
+inline void *qt_getClipRects( const TQRegion &r, int &num )
+{
+ return r.clipRectangles( num );
+}
+
+static inline void x11SetClipRegion(Display *dpy, GC gc, GC gc2, TQt::HANDLE draw, const TQRegion &r)
+{
+ int num;
+ XRectangle *rects = (XRectangle *)qt_getClipRects( r, num );
+
+ if (gc)
+ XSetClipRectangles( dpy, gc, 0, 0, rects, num, YXBanded );
+ if (gc2)
+ XSetClipRectangles( dpy, gc2, 0, 0, rects, num, YXBanded );
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (draw)
+ XftDrawSetClipRectangles((XftDraw *) draw, 0, 0, rects, num);
+#else
+ TQ_UNUSED(draw);
+#endif // TQT_NO_XFTFREETYPE
+}
+
+static inline void x11ClearClipRegion(Display *dpy, GC gc, GC gc2, TQt::HANDLE draw)
+{
+ if (gc)
+ XSetClipMask(dpy, gc, None);
+ if (gc2)
+ XSetClipMask(dpy, gc2, None);
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (draw) {
+# ifdef TQT_XFT2
+ XftDrawSetClip((XftDraw *) draw, None);
+# else
+ // stupid Xft1
+ Picture pict = XftDrawPicture((XftDraw *) draw);
+ XRenderPictureAttributes pattr;
+ pattr.clip_mask = None;
+ XRenderChangePicture(dpy, pict, CPClipMask, &pattr);
+# endif // TQT_XFT2
+ }
+#else
+ TQ_UNUSED(draw);
+#endif // TQT_NO_XFTFREETYPE
+}
+
+
+/*****************************************************************************
+ Trigonometric function for TQPainter
+
+ We have implemented simple sine and cosine function that are called from
+ TQPainter::drawPie() and TQPainter::drawChord() when drawing the outline of
+ pies and chords.
+ These functions are slower and less accurate than math.h sin() and cos(),
+ but with still around 1/70000th sec. execution time (on a 486DX2-66) and
+ 8 digits accuracy, it should not be the bottleneck in drawing these tqshapes.
+ The advantage is that you don't have to link in the math library.
+ *****************************************************************************/
+
+const double TQ_PI = 3.14159265358979323846; // pi
+const double TQ_2PI = 6.28318530717958647693; // 2*pi
+const double TQ_PI2 = 1.57079632679489661923; // pi/2
+
+
+#if defined(TQ_CC_GNU) && defined(TQ_OS_AIX)
+// AIX 4.2 gcc 2.7.2.3 gets internal error.
+static int tqRoundAIX( double d )
+{
+ return tqRound(d);
+}
+#define tqRound tqRoundAIX
+#endif
+
+
+#if defined(TQ_CC_GNU) && defined(__i386__)
+
+inline double qcos( double a )
+{
+ double r;
+ __asm__ (
+ "fcos"
+ : "=t" (r) : "0" (a) );
+ return(r);
+}
+
+inline double qsin( double a )
+{
+ double r;
+ __asm__ (
+ "fsin"
+ : "=t" (r) : "0" (a) );
+ return(r);
+}
+
+double qsincos( double a, bool calcCos=FALSE )
+{
+ return calcCos ? qcos(a) : qsin(a);
+}
+
+#else
+
+double qsincos( double a, bool calcCos=FALSE )
+{
+ if ( calcCos ) // calculate cosine
+ a -= TQ_PI2;
+ if ( a >= TQ_2PI || a <= -TQ_2PI ) { // fix range: -2*pi < a < 2*pi
+ int m = (int)(a/TQ_2PI);
+ a -= TQ_2PI*m;
+ }
+ if ( a < 0.0 ) // 0 <= a < 2*pi
+ a += TQ_2PI;
+ int sign = a > TQ_PI ? -1 : 1;
+ if ( a >= TQ_PI )
+ a = TQ_2PI - a;
+ if ( a >= TQ_PI2 )
+ a = TQ_PI - a;
+ if ( calcCos )
+ sign = -sign;
+ double a2 = a*a; // here: 0 <= a < pi/4
+ double a3 = a2*a; // make taylor sin sum
+ double a5 = a3*a2;
+ double a7 = a5*a2;
+ double a9 = a7*a2;
+ double a11 = a9*a2;
+ return (a-a3/6+a5/120-a7/5040+a9/362880-a11/39916800)*sign;
+}
+
+inline double qsin( double a ) { return qsincos(a, FALSE); }
+inline double qcos( double a ) { return qsincos(a, TRUE); }
+
+#endif
+
+
+/*****************************************************************************
+ TQPainter internal GC (Graphics Context) allocator.
+
+ The GC allocator offers two functions; alloc_gc() and free_gc() that
+ reuse GC objects instead of calling XCreateGC() and XFreeGC(), which
+ are a whole lot slower.
+ *****************************************************************************/
+
+struct TQGC
+{
+ GC gc;
+ char in_use;
+ bool mono;
+ int scrn;
+};
+
+const int gc_array_size = 256;
+static TQGC gc_array[gc_array_size]; // array of GCs
+static bool gc_array_init = FALSE;
+
+
+static void init_gc_array()
+{
+ if ( !gc_array_init ) {
+ memset( gc_array, 0, gc_array_size*sizeof(TQGC) );
+ gc_array_init = TRUE;
+ }
+}
+
+static void cleanup_gc_array( Display *dpy )
+{
+ register TQGC *p = gc_array;
+ int i = gc_array_size;
+ if ( gc_array_init ) {
+ while ( i-- ) {
+ if ( p->gc ) // destroy GC
+ XFreeGC( dpy, p->gc );
+ p++;
+ }
+ gc_array_init = FALSE;
+ }
+}
+
+// #define DONT_USE_GC_ARRAY
+
+static GC alloc_gc( Display *dpy, int scrn, Drawable hd, bool monochrome=FALSE,
+ bool privateGC = FALSE )
+{
+#if defined(DONT_USE_GC_ARRAY)
+ privateGC = TRUE; // will be slower
+#endif
+ if ( privateGC ) {
+ GC gc = XCreateGC( dpy, hd, 0, 0 );
+ XSetGraphicsExposures( dpy, gc, False );
+ return gc;
+ }
+ register TQGC *p = gc_array;
+ int i = gc_array_size;
+ if ( !gc_array_init ) // not initialized
+ init_gc_array();
+ while ( i-- ) {
+ if ( !p->gc ) { // create GC (once)
+ p->gc = XCreateGC( dpy, hd, 0, 0 );
+ p->scrn = scrn;
+ XSetGraphicsExposures( dpy, p->gc, False );
+ p->in_use = FALSE;
+ p->mono = monochrome;
+ }
+ if ( !p->in_use && p->mono == monochrome && p->scrn == scrn ) {
+ p->in_use = TRUE; // available/compatible GC
+ return p->gc;
+ }
+ p++;
+ }
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQPainter: Internal error; no available GC" );
+#endif
+ GC gc = XCreateGC( dpy, hd, 0, 0 );
+ XSetGraphicsExposures( dpy, gc, False );
+ return gc;
+}
+
+static void free_gc( Display *dpy, GC gc, bool privateGC = FALSE )
+{
+#if defined(DONT_USE_GC_ARRAY)
+ privateGC = TRUE; // will be slower
+#endif
+ if ( privateGC ) {
+ TQ_ASSERT( dpy != 0 );
+ XFreeGC( dpy, gc );
+ return;
+ }
+ register TQGC *p = gc_array;
+ int i = gc_array_size;
+ if ( gc_array_init ) {
+ while ( i-- ) {
+ if ( p->gc == gc ) {
+ p->in_use = FALSE; // set available
+ XSetClipMask( dpy, gc, None ); // make it reusable
+ XSetFunction( dpy, gc, GXcopy );
+ XSetFillStyle( dpy, gc, FillSolid );
+ XSetTSOrigin( dpy, gc, 0, 0 );
+ return;
+ }
+ p++;
+ }
+ }
+
+ // not found in gc_array
+ XFreeGC(dpy, gc);
+}
+
+
+/*****************************************************************************
+ TQPainter internal GC (Graphics Context) cache for solid pens and
+ brushes.
+
+ The GC cache makes a significant contribution to speeding up
+ drawing. Setting new pen and brush colors will make the painter
+ look for another GC with the same color instead of changing the
+ color value of the GC currently in use. The cache structure is
+ optimized for fast lookup. Only solid line pens with line width 0
+ and solid brushes are cached.
+
+ In addition, stored GCs may have an implicit clipping region
+ set. This prevents any drawing outside paint events. Both
+ updatePen() and updateBrush() keep track of the validity of this
+ clipping region by storing the clip_serial number in the cache.
+
+*****************************************************************************/
+
+struct TQGCC // cached GC
+{
+ GC gc;
+ uint pix;
+ int count;
+ int hits;
+ uint clip_serial;
+ int scrn;
+};
+
+const int gc_cache_size = 29; // multiply by 4
+static TQGCC *gc_cache_buf;
+static TQGCC *gc_cache[4*gc_cache_size];
+static bool gc_cache_init = FALSE;
+static uint gc_cache_clip_serial = 0;
+
+
+static void init_gc_cache()
+{
+ if ( !gc_cache_init ) {
+ gc_cache_init = TRUE;
+ gc_cache_clip_serial = 0;
+ TQGCC *g = gc_cache_buf = new TQGCC[4*gc_cache_size];
+ memset( g, 0, 4*gc_cache_size*sizeof(TQGCC) );
+ for ( int i=0; i<4*gc_cache_size; i++ )
+ gc_cache[i] = g++;
+ }
+}
+
+
+// #define GC_CACHE_STAT
+#if defined(GC_CACHE_STAT)
+#include "tqtextstream.h"
+#include "tqbuffer.h"
+
+static int g_numhits = 0;
+static int g_numcreates = 0;
+static int g_numfaults = 0;
+#endif
+
+
+static void cleanup_gc_cache()
+{
+ if ( !gc_cache_init )
+ return;
+#if defined(GC_CACHE_STAT)
+ qDebug( "Number of cache hits = %d", g_numhits );
+ qDebug( "Number of cache creates = %d", g_numcreates );
+ qDebug( "Number of cache faults = %d", g_numfaults );
+ for ( int i=0; i<gc_cache_size; i++ ) {
+ TQCString str;
+ TQBuffer buf( str );
+ buf.open(IO_ReadWrite);
+ TQTextStream s(&buf);
+ s << i << ": ";
+ for ( int j=0; j<4; j++ ) {
+ TQGCC *g = gc_cache[i*4+j];
+ s << (g->gc ? 'X' : '-') << ',' << g->hits << ','
+ << g->count << '\t';
+ }
+ s << '\0';
+ qDebug( str );
+ buf.close();
+ }
+#endif
+ delete [] gc_cache_buf;
+ gc_cache_init = FALSE;
+}
+
+
+static bool obtain_gc( void **ref, GC *gc, uint pix, Display *dpy, int scrn,
+ TQt::HANDLE hd, uint painter_clip_serial )
+{
+ if ( !gc_cache_init )
+ init_gc_cache();
+
+ int k = (pix % gc_cache_size) * 4;
+ TQGCC *g = gc_cache[k];
+ TQGCC *prev = 0;
+
+#define NOMATCH (g->gc && (g->pix != pix || g->scrn != scrn || \
+ (g->clip_serial > 0 && g->clip_serial != painter_clip_serial)))
+
+ if ( NOMATCH ) {
+ prev = g;
+ g = gc_cache[++k];
+ if ( NOMATCH ) {
+ prev = g;
+ g = gc_cache[++k];
+ if ( NOMATCH ) {
+ prev = g;
+ g = gc_cache[++k];
+ if ( NOMATCH ) {
+ if ( g->count == 0 && g->scrn == scrn) { // steal this GC
+ g->pix = pix;
+ g->count = 1;
+ g->hits = 1;
+ g->clip_serial = 0;
+ XSetForeground( dpy, g->gc, pix );
+ XSetClipMask(dpy, g->gc, None);
+ gc_cache[k] = prev;
+ gc_cache[k-1] = g;
+ *ref = (void *)g;
+ *gc = g->gc;
+ return TRUE;
+ } else { // all GCs in use
+#if defined(GC_CACHE_STAT)
+ g_numfaults++;
+#endif
+ *ref = 0;
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+
+#undef NOMATCH
+
+ *ref = (void *)g;
+
+ if ( g->gc ) { // reuse existing GC
+#if defined(GC_CACHE_STAT)
+ g_numhits++;
+#endif
+ *gc = g->gc;
+ g->count++;
+ g->hits++;
+ if ( prev && g->hits > prev->hits ) { // maintain LRU order
+ gc_cache[k] = prev;
+ gc_cache[k-1] = g;
+ }
+ return TRUE;
+ } else { // create new GC
+#if defined(GC_CACHE_STAT)
+ g_numcreates++;
+#endif
+ g->gc = alloc_gc( dpy, scrn, hd, FALSE );
+ g->scrn = scrn;
+ g->pix = pix;
+ g->count = 1;
+ g->hits = 1;
+ g->clip_serial = 0;
+ *gc = g->gc;
+ return FALSE;
+ }
+}
+
+static inline void release_gc( void *ref )
+{
+ ((TQGCC*)ref)->count--;
+}
+
+/*****************************************************************************
+ TQPainter member functions
+ *****************************************************************************/
+
+/*!
+ \internal
+
+ Internal function that initializes the painter.
+*/
+
+void TQPainter::initialize()
+{
+ init_gc_array();
+ init_gc_cache();
+}
+
+/*!
+ \internal
+
+ Internal function that cleans up the painter.
+*/
+
+void TQPainter::cleanup()
+{
+ cleanup_gc_cache();
+ cleanup_gc_array( TQPaintDevice::x11AppDisplay() );
+ TQPointArray::cleanBuffers();
+}
+
+/*!
+ \internal
+
+ Internal function that destroys up the painter.
+*/
+
+void TQPainter::destroy()
+{
+
+}
+
+void TQPainter::init()
+{
+ d = 0;
+ flags = IsStartingUp;
+ bg_col = white; // default background color
+ bg_mode = TransparentMode; // default background mode
+ rop = CopyROP; // default ROP
+ tabstops = 0; // default tabbing
+ tabarray = 0;
+ tabarraylen = 0;
+ ps_stack = 0;
+ wm_stack = 0;
+ gc = gc_brush = 0;
+ pdev = 0;
+ dpy = 0;
+ txop = txinv = 0;
+ penRef = brushRef = 0;
+ clip_serial = 0;
+ pfont = 0;
+ block_ext = FALSE;
+}
+
+
+/*!
+ \fn const TQFont &TQPainter::font() const
+
+ Returns the currently set painter font.
+
+ \sa setFont(), TQFont
+*/
+
+/*!
+ Sets the painter's font to \a font.
+
+ This font is used by subsequent drawText() functions. The text
+ color is the same as the pen color.
+
+ \sa font(), drawText()
+*/
+
+void TQPainter::setFont( const TQFont &font )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setFont: Will be reset by begin()" );
+#endif
+ if ( cfont.d != font.d ) {
+ cfont = font;
+ cfont.x11SetScreen( scrn );
+ setf(DirtyFont);
+ }
+}
+
+
+void TQPainter::updateFont()
+{
+ if (!isActive())
+ return;
+
+ clearf(DirtyFont);
+ if ( testf(ExtDev) ) {
+ if (pdev->devType() == TQInternal::Printer) {
+ if ( pfont ) delete pfont;
+ pfont = new TQFont( cfont.d, pdev );
+ }
+ TQPDevCmdParam param[1];
+ param[0].font = &cfont;
+ if ( !pdev->cmd( TQPaintDevice::PdcSetFont, this, param ) || !hd )
+ return;
+ }
+ setf(NoCache);
+ if ( penRef )
+ updatePen(); // force a non-cached GC
+}
+
+
+void TQPainter::updatePen()
+{
+ if (!isActive())
+ return;
+
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ param[0].pen = &cpen;
+ if ( !pdev->cmd( TQPaintDevice::PdcSetPen, this, param ) || !hd )
+ return;
+ }
+
+ int ps = cpen.style();
+ bool cacheIt = !testf(ClipOn|MonoDev|NoCache) &&
+ (ps == NoPen || ps == SolidLine) &&
+ cpen.width() == 0 && rop == CopyROP;
+
+ bool obtained = FALSE;
+ bool internclipok = hasClipping();
+ if ( cacheIt ) {
+ if ( gc ) {
+ if ( penRef )
+ release_gc( penRef );
+ else
+ free_gc( dpy, gc );
+ }
+ obtained = obtain_gc(&penRef, &gc, cpen.color().pixel(scrn), dpy, scrn,
+ hd, clip_serial);
+ if ( !obtained && !penRef )
+ gc = alloc_gc( dpy, scrn, hd, FALSE );
+ } else {
+ if ( gc ) {
+ if ( penRef ) {
+ release_gc( penRef );
+ penRef = 0;
+ gc = alloc_gc( dpy, scrn, hd, testf(MonoDev) );
+ } else {
+ internclipok = TRUE;
+ }
+ } else {
+ gc = alloc_gc( dpy, scrn, hd, testf(MonoDev), testf(UsePrivateCx) );
+ }
+ }
+
+ if ( !internclipok ) {
+ if ( pdev == paintEventDevice && paintEventClipRegion ) {
+ if ( penRef &&((TQGCC*)penRef)->clip_serial < gc_cache_clip_serial ) {
+ x11SetClipRegion( dpy, gc, 0, rendhd, *paintEventClipRegion );
+ ((TQGCC*)penRef)->clip_serial = gc_cache_clip_serial;
+ } else if ( !penRef ) {
+ x11SetClipRegion( dpy, gc, 0, rendhd, *paintEventClipRegion );
+ }
+ } else if (penRef && ((TQGCC*)penRef)->clip_serial ) {
+ x11ClearClipRegion(dpy, gc, 0, rendhd);
+ ((TQGCC*)penRef)->clip_serial = 0;
+ }
+ }
+
+ if ( obtained )
+ return;
+
+ char dashes[10]; // custom pen dashes
+ int dash_len = 0; // length of dash list
+ int s = LineSolid;
+ int cp = CapButt;
+ int jn = JoinMiter;
+
+ /*
+ We are emulating Windows here. Windows treats cpen.width() == 1
+ (or 0) as a very special case. The fudge variable unifies this
+ case with the general case.
+ */
+ int dot = cpen.width(); // width of a dot
+ int fudge = 1;
+ bool allow_zero_lw = TRUE;
+ if ( dot <= 1 ) {
+ dot = 3;
+ fudge = 2;
+ }
+
+ switch( ps ) {
+ case NoPen:
+ case SolidLine:
+ s = LineSolid;
+ break;
+ case DashLine:
+ dashes[0] = fudge * 3 * dot;
+ dashes[1] = fudge * dot;
+ dash_len = 2;
+ allow_zero_lw = FALSE;
+ break;
+ case DotLine:
+ dashes[0] = dot;
+ dashes[1] = dot;
+ dash_len = 2;
+ allow_zero_lw = FALSE;
+ break;
+ case DashDotLine:
+ dashes[0] = 3 * dot;
+ dashes[1] = fudge * dot;
+ dashes[2] = dot;
+ dashes[3] = fudge * dot;
+ dash_len = 4;
+ allow_zero_lw = FALSE;
+ break;
+ case DashDotDotLine:
+ dashes[0] = 3 * dot;
+ dashes[1] = dot;
+ dashes[2] = dot;
+ dashes[3] = dot;
+ dashes[4] = dot;
+ dashes[5] = dot;
+ dash_len = 6;
+ allow_zero_lw = FALSE;
+ }
+ TQ_ASSERT( dash_len <= (int) sizeof(dashes) );
+
+ switch ( cpen.capStyle() ) {
+ case SquareCap:
+ cp = CapProjecting;
+ break;
+ case RoundCap:
+ cp = CapRound;
+ break;
+ case FlatCap:
+ default:
+ cp = CapButt;
+ break;
+ }
+ switch ( cpen.joinStyle() ) {
+ case BevelJoin:
+ jn = JoinBevel;
+ break;
+ case RoundJoin:
+ jn = JoinRound;
+ break;
+ case MiterJoin:
+ default:
+ jn = JoinMiter;
+ break;
+ }
+
+ XSetForeground( dpy, gc, cpen.color().pixel(scrn) );
+ XSetBackground( dpy, gc, bg_col.pixel(scrn) );
+
+ if ( dash_len ) { // make dash list
+ XSetDashes( dpy, gc, 0, dashes, dash_len );
+ s = bg_mode == TransparentMode ? LineOnOffDash : LineDoubleDash;
+ }
+ XSetLineAttributes( dpy, gc,
+ (! allow_zero_lw && cpen.width() == 0) ? 1 : cpen.width(),
+ s, cp, jn );
+}
+
+
+void TQPainter::updateBrush()
+{
+ if (!isActive())
+ return;
+
+ static const uchar dense1_pat[] = { 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff, 0xff };
+ static const uchar dense2_pat[] = { 0x77, 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff };
+ static const uchar dense3_pat[] = { 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55, 0xee };
+ static const uchar dense4_pat[] = { 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa };
+ static const uchar dense5_pat[] = { 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa, 0x11 };
+ static const uchar dense6_pat[] = { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 };
+ static const uchar dense7_pat[] = { 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00 };
+ static const uchar hor_pat[] = { // horizontal pattern
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ static const uchar ver_pat[] = { // vertical pattern
+ 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
+ 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
+ 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
+ 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
+ 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
+ 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20 };
+ static const uchar cross_pat[] = { // cross pattern
+ 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0xff, 0xff, 0xff,
+ 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
+ 0x08, 0x82, 0x20, 0xff, 0xff, 0xff, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
+ 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0xff, 0xff, 0xff,
+ 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20,
+ 0x08, 0x82, 0x20, 0xff, 0xff, 0xff, 0x08, 0x82, 0x20, 0x08, 0x82, 0x20 };
+ static const uchar bdiag_pat[] = { // backward diagonal pattern
+ 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01,
+ 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04,
+ 0x02, 0x02, 0x01, 0x01, 0x80, 0x80, 0x40, 0x40 };
+ static const uchar fdiag_pat[] = { // forward diagonal pattern
+ 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40,
+ 0x80, 0x80, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10,
+ 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x01, 0x01 };
+ static const uchar dcross_pat[] = { // diagonal cross pattern
+ 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x14, 0x14, 0x22, 0x22, 0x41, 0x41,
+ 0x80, 0x80, 0x41, 0x41, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x14, 0x14,
+ 0x22, 0x22, 0x41, 0x41, 0x80, 0x80, 0x41, 0x41 };
+ static const uchar * const pat_tbl[] = {
+ dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
+ dense6_pat, dense7_pat,
+ hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
+
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ param[0].brush = &cbrush;
+ if ( !pdev->cmd( TQPaintDevice::PdcSetBrush, this, param ) || !hd )
+ return;
+ }
+
+ int bs = cbrush.style();
+ bool cacheIt = !testf(ClipOn|MonoDev|NoCache) &&
+ (bs == NoBrush || bs == SolidPattern) &&
+ bro.x() == 0 && bro.y() == 0 && rop == CopyROP;
+
+ bool obtained = FALSE;
+ bool internclipok = hasClipping();
+ if ( cacheIt ) {
+ if ( gc_brush ) {
+ if ( brushRef )
+ release_gc( brushRef );
+ else
+ free_gc( dpy, gc_brush );
+ }
+ obtained = obtain_gc(&brushRef, &gc_brush, cbrush.color().pixel(scrn), dpy,
+ scrn, hd, clip_serial);
+ if ( !obtained && !brushRef )
+ gc_brush = alloc_gc( dpy, scrn, hd, FALSE );
+ } else {
+ if ( gc_brush ) {
+ if ( brushRef ) {
+ release_gc( brushRef );
+ brushRef = 0;
+ gc_brush = alloc_gc( dpy, scrn, hd, testf(MonoDev) );
+ } else {
+ internclipok = TRUE;
+ }
+ } else {
+ gc_brush = alloc_gc( dpy, scrn, hd, testf(MonoDev), testf(UsePrivateCx));
+ }
+ }
+
+ if ( !internclipok ) {
+ if ( pdev == paintEventDevice && paintEventClipRegion ) {
+ if ( brushRef &&((TQGCC*)brushRef)->clip_serial < gc_cache_clip_serial ) {
+ x11SetClipRegion( dpy, gc_brush, 0, rendhd, *paintEventClipRegion );
+ ((TQGCC*)brushRef)->clip_serial = gc_cache_clip_serial;
+ } else if ( !brushRef ){
+ x11SetClipRegion( dpy, gc_brush, 0, rendhd, *paintEventClipRegion );
+ }
+ } else if (brushRef && ((TQGCC*)brushRef)->clip_serial ) {
+ x11ClearClipRegion(dpy, gc_brush, 0, rendhd);
+ ((TQGCC*)brushRef)->clip_serial = 0;
+ }
+ }
+
+ if ( obtained )
+ return;
+
+ const uchar *pat = 0; // pattern
+ int d = 0; // defalt pattern size: d*d
+ int s = FillSolid;
+ if ( bs >= Dense1Pattern && bs <= DiagCrossPattern ) {
+ pat = pat_tbl[ bs-Dense1Pattern ];
+ if ( bs <= Dense7Pattern )
+ d = 8;
+ else if ( bs <= CrossPattern )
+ d = 24;
+ else
+ d = 16;
+ }
+
+ XSetLineAttributes( dpy, gc_brush, 0, LineSolid, CapButt, JoinMiter );
+ XSetForeground( dpy, gc_brush, cbrush.color().pixel(scrn) );
+ XSetBackground( dpy, gc_brush, bg_col.pixel(scrn) );
+
+ if ( bs == CustomPattern || pat ) {
+ TQPixmap *pm;
+ if ( pat ) {
+ TQString key;
+ key.sprintf( "$qt-brush$%d", bs );
+ pm = TQPixmapCache::tqfind( key );
+ bool del = FALSE;
+ if ( !pm ) { // not already in pm dict
+ pm = new TQBitmap( d, d, pat, TRUE );
+ TQ_CHECK_PTR( pm );
+ del = !TQPixmapCache::insert( key, pm );
+ }
+ if ( cbrush.data->pixmap )
+ delete cbrush.data->pixmap;
+ cbrush.data->pixmap = new TQPixmap( *pm );
+ if (del) delete pm;
+ }
+ pm = cbrush.data->pixmap;
+ pm->x11SetScreen( scrn );
+ if ( pm->depth() == 1 ) {
+ XSetStipple( dpy, gc_brush, pm->handle() );
+ s = bg_mode == TransparentMode ? FillStippled : FillOpaqueStippled;
+ } else {
+ XSetTile( dpy, gc_brush, pm->handle() );
+ s = FillTiled;
+ }
+ }
+ XSetFillStyle( dpy, gc_brush, s );
+}
+
+
+/*!
+ Begins painting the paint tqdevice \a pd and returns TRUE if
+ successful; otherwise returns FALSE. If \a unclipped is TRUE, the
+ painting will not be clipped at the paint tqdevice's boundaries,
+ (although this is not supported by all platforms).
+
+ The errors that can occur are serious problems, such as these:
+
+ \code
+ p->begin( 0 ); // impossible - paint tqdevice cannot be 0
+
+ TQPixmap pm( 0, 0 );
+ p->begin( pm ); // impossible - pm.isNull();
+
+ p->begin( myWidget );
+ p2->begin( myWidget ); // impossible - only one painter at a time
+ \endcode
+
+ Note that most of the time, you can use one of the constructors
+ instead of begin(), and that end() is automatically done at
+ destruction.
+
+ \warning A paint tqdevice can only be painted by one painter at a
+ time.
+
+ \sa end(), flush()
+*/
+
+bool TQPainter::begin( const TQPaintDevice *pd, bool unclipped )
+{
+ if ( isActive() ) { // already active painting
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::begin: Painter is already active."
+ "\n\tYou must end() the painter before a second begin()" );
+#endif
+ return FALSE;
+ }
+ if ( pd == 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQPainter::begin: Paint tqdevice cannot be null" );
+#endif
+ return FALSE;
+ }
+
+ TQPixmap::x11SetDefaultScreen( pd->x11Screen() );
+
+ const TQWidget *copyFrom = 0;
+ pdev = redirect( (TQPaintDevice*)pd );
+ if ( pdev ) { // redirected paint tqdevice?
+ if ( pd->devType() == TQInternal::Widget )
+ copyFrom = (const TQWidget *)pd; // copy widget settings
+ } else {
+ pdev = (TQPaintDevice*)pd;
+ }
+
+ if ( pdev->isExtDev() && pdev->paintingActive() ) {
+ // somebody else is already painting
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::begin: Another TQPainter is already painting "
+ "this tqdevice;\n\tAn extended paint tqdevice can only be "
+ "painted by one TQPainter at a time." );
+#endif
+ return FALSE;
+ }
+
+ bool reinit = flags != IsStartingUp; // 2nd or 3rd etc. time called
+ flags = IsActive | DirtyFont; // init flags
+ int dt = pdev->devType(); // get the tqdevice type
+
+ if ( (pdev->devFlags & TQInternal::ExternalDevice) != 0 )
+ setf(ExtDev);
+ else if ( dt == TQInternal::Pixmap ) // tqdevice is a pixmap
+ ((TQPixmap*)pdev)->detach(); // will modify it
+
+ dpy = pdev->x11Display(); // get display variable
+ scrn = pdev->x11Screen(); // get screen variable
+ hd = pdev->handle(); // get handle to drawable
+ rendhd = pdev->rendhd;
+
+ if ( testf(ExtDev) ) { // external tqdevice
+ if ( !pdev->cmd( TQPaintDevice::PdcBegin, this, 0 ) ) {
+ // could not begin painting
+ if ( reinit )
+ clearf( IsActive | DirtyFont );
+ else
+ flags = IsStartingUp;
+ pdev = 0;
+ return FALSE;
+ }
+ if ( tabstops ) // update tabstops for tqdevice
+ setTabStops( tabstops );
+ if ( tabarray ) // update tabarray for tqdevice
+ setTabArray( tabarray );
+ }
+
+ if ( pdev->x11Depth() != pdev->x11AppDepth( scrn ) ) { // non-standard depth
+ setf(NoCache);
+ setf(UsePrivateCx);
+ }
+
+ pdev->painters++; // also tell paint tqdevice
+ bro = curPt = TQPoint( 0, 0 );
+ if ( reinit ) {
+ bg_mode = TransparentMode; // default background mode
+ rop = CopyROP; // default ROP
+ wxmat.reset(); // reset world xform matrix
+ xmat.reset();
+ ixmat.reset();
+ txop = txinv = 0;
+ if ( dt != TQInternal::Widget ) {
+ TQFont defaultFont; // default drawing tools
+ TQPen defaultPen;
+ TQBrush defaultBrush;
+ cfont = defaultFont; // set these drawing tools
+ cpen = defaultPen;
+ cbrush = defaultBrush;
+ bg_col = white; // default background color
+ }
+ }
+ wx = wy = vx = vy = 0; // default view origins
+
+ if ( dt == TQInternal::Widget ) { // tqdevice is a widget
+ TQWidget *w = (TQWidget*)pdev;
+ cfont = w->font(); // use widget font
+ cpen = TQPen( w->foregroundColor() ); // use widget fg color
+ if ( reinit ) {
+ TQBrush defaultBrush;
+ cbrush = defaultBrush;
+ }
+ bg_col = w->backgroundColor(); // use widget bg color
+ ww = vw = w->width(); // default view size
+ wh = vh = w->height();
+ if ( unclipped || w->testWFlags( WPaintUnclipped ) ) { // paint direct on tqdevice
+ setf( NoCache );
+ setf(UsePrivateCx);
+ updatePen();
+ updateBrush();
+ XSetSubwindowMode( dpy, gc, IncludeInferiors );
+ XSetSubwindowMode( dpy, gc_brush, IncludeInferiors );
+#ifndef TQT_NO_XFTFREETYPE
+ if (rendhd)
+ XftDrawSetSubwindowMode((XftDraw *) rendhd, IncludeInferiors);
+#endif
+ }
+ } else if ( dt == TQInternal::Pixmap ) { // tqdevice is a pixmap
+ TQPixmap *pm = (TQPixmap*)pdev;
+ if ( pm->isNull() ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQPainter::begin: Cannot paint null pixmap" );
+#endif
+ end();
+ return FALSE;
+ }
+ bool mono = pm->depth() == 1; // monochrome bitmap
+ if ( mono ) {
+ setf( MonoDev );
+ bg_col = color0;
+ cpen.setColor( color1 );
+ }
+ ww = vw = pm->width(); // default view size
+ wh = vh = pm->height();
+ } else if ( testf(ExtDev) ) { // external tqdevice
+ ww = vw = pdev->metric( TQPaintDeviceMetrics::PdmWidth );
+ wh = vh = pdev->metric( TQPaintDeviceMetrics::PdmHeight );
+ }
+ if ( ww == 0 )
+ ww = wh = vw = vh = 1024;
+ if ( copyFrom ) { // copy redirected widget
+ cfont = copyFrom->font();
+ cpen = TQPen( copyFrom->foregroundColor() );
+ bg_col = copyFrom->backgroundColor();
+ }
+ if ( testf(ExtDev) ) { // external tqdevice
+ setBackgroundColor( bg_col ); // default background color
+ setBackgroundMode( TransparentMode ); // default background mode
+ setRasterOp( CopyROP ); // default raster operation
+ }
+ clip_serial = gc_cache_clip_serial++;
+ updateBrush();
+ updatePen();
+ return TRUE;
+}
+
+/*!
+ Ends painting. Any resources used while painting are released.
+
+ Note that while you mostly don't need to call end(), the
+ destructor will do it, there is at least one common case when it
+ is needed, namely double buffering.
+
+ \code
+ TQPainter p( myPixmap, this )
+ // ...
+ p.end(); // stops drawing on myPixmap
+ p.begin( this );
+ p.drawPixmap( 0, 0, myPixmap );
+ \endcode
+
+ Since you can't draw a TQPixmap while it is being painted, it is
+ necessary to close the active painter.
+
+ \sa begin(), isActive()
+*/
+
+bool TQPainter::end() // end painting
+{
+ if ( !isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::end: Missing begin() or begin() failed" );
+#endif
+ return FALSE;
+ }
+ killPStack();
+
+ //#### This should not be necessary:
+ if ( pdev->devType() == TQInternal::Widget && // #####
+ ((TQWidget*)pdev)->testWFlags(WPaintUnclipped) ) {
+ if ( gc )
+ XSetSubwindowMode( dpy, gc, ClipByChildren );
+ if ( gc_brush )
+ XSetSubwindowMode( dpy, gc_brush, ClipByChildren );
+ }
+
+ if ( gc_brush ) { // restore brush gc
+ if ( brushRef ) {
+ release_gc( brushRef );
+ brushRef = 0;
+ } else {
+ free_gc( dpy, gc_brush, testf(UsePrivateCx) );
+ }
+ gc_brush = 0;
+
+ }
+ if ( gc ) { // restore pen gc
+ if ( penRef ) {
+ release_gc( penRef );
+ penRef = 0;
+ } else {
+ free_gc( dpy, gc, testf(UsePrivateCx) );
+ }
+ gc = 0;
+ }
+
+ if ( testf(ExtDev) )
+ pdev->cmd( TQPaintDevice::PdcEnd, this, 0 );
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (rendhd) {
+ // reset clipping/subwindow mode on our render picture
+ XftDrawSetClip((XftDraw *) rendhd, None);
+ XftDrawSetSubwindowMode((XftDraw *) rendhd, ClipByChildren);
+ }
+#endif // TQT_NO_XFTFREETYPE
+
+ if ( pfont ) {
+ delete pfont;
+ pfont = 0;
+ }
+
+ flags = 0;
+ pdev->painters--;
+ pdev = 0;
+ dpy = 0;
+ return TRUE;
+}
+
+/*!
+ Flushes any buffered drawing operations inside the region \a
+ region using clipping mode \a cm.
+
+ The flush may update the whole tqdevice if the platform does not
+ support flushing to a specified region.
+
+ \sa flush() CoordinateMode
+*/
+
+void TQPainter::flush(const TQRegion &, CoordinateMode)
+{
+ flush();
+}
+
+
+/*!
+ \overload
+
+ Flushes any buffered drawing operations.
+*/
+
+void TQPainter::flush()
+{
+ if ( isActive() && dpy )
+ XFlush( dpy );
+}
+
+
+/*!
+ Sets the background color of the painter to \a c.
+
+ The background color is the color that is filled in when drawing
+ opaque text, stippled lines and bitmaps. The background color has
+ no effect in transtqparent background mode (which is the default).
+
+ \sa backgroundColor() setBackgroundMode() BackgroundMode
+*/
+
+void TQPainter::setBackgroundColor( const TQColor &c )
+{
+ if ( !isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::setBackgroundColor: Call begin() first" );
+#endif
+ return;
+ }
+ bg_col = c;
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ param[0].color = &bg_col;
+ if ( !pdev->cmd( TQPaintDevice::PdcSetBkColor, this, param ) || !hd )
+ return;
+ }
+ if ( !penRef )
+ updatePen(); // update pen setting
+ if ( !brushRef )
+ updateBrush(); // update brush setting
+}
+
+/*!
+ Sets the background mode of the painter to \a m, which must be
+ either \c TransparentMode (the default) or \c OpaqueMode.
+
+ Transtqparent mode draws stippled lines and text without setting the
+ background pixels. Opaque mode fills these space with the current
+ background color.
+
+ Note that in order to draw a bitmap or pixmap transparently, you
+ must use TQPixmap::setMask().
+
+ \sa backgroundMode(), setBackgroundColor()
+*/
+
+void TQPainter::setBackgroundMode( BGMode m )
+{
+ if ( !isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::setBackgroundMode: Call begin() first" );
+#endif
+ return;
+ }
+ if ( m != TransparentMode && m != OpaqueMode ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPainter::setBackgroundMode: Invalid mode" );
+#endif
+ return;
+ }
+ bg_mode = m;
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ param[0].ival = m;
+ if ( !pdev->cmd( TQPaintDevice::PdcSetBkMode, this, param ) || !hd )
+ return;
+ }
+ if ( !penRef )
+ updatePen(); // update pen setting
+ if ( !brushRef )
+ updateBrush(); // update brush setting
+}
+
+static const short ropCodes[] = { // ROP translation table
+ GXcopy, // CopyROP
+ GXor, // OrROP
+ GXxor, // XorROP
+ GXandInverted, // NotAndROP EraseROP
+ GXcopyInverted, // NotCopyROP
+ GXorInverted, // NotOrROP
+ GXequiv, // NotXorROP
+ GXand, // AndROP
+ GXinvert, // NotROP
+ GXclear, // ClearROP
+ GXset, // SetROP
+ GXnoop, // NopROP
+ GXandReverse, // AndNotROP
+ GXorReverse, // OrNotROP
+ GXnand, // NandROP
+ GXnor // NorROP
+};
+
+
+/*!
+ Sets the \link TQt::RasterOp raster operation \endlink to \a r.
+ The default is \c CopyROP.
+
+ \sa rasterOp() TQt::RasterOp
+*/
+
+void TQPainter::setRasterOp( RasterOp r )
+{
+ if ( !isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::setRasterOp: Call begin() first" );
+#endif
+ return;
+ }
+ if ( (uint)r > LastROP ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPainter::setRasterOp: Invalid ROP code" );
+#endif
+ return;
+ }
+ rop = r;
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ param[0].ival = r;
+ if ( !pdev->cmd( TQPaintDevice::PdcSetROP, this, param ) || !hd )
+ return;
+ }
+ if ( penRef )
+ updatePen(); // get non-cached pen GC
+ if ( brushRef )
+ updateBrush(); // get non-cached brush GC
+ XSetFunction( dpy, gc, ropCodes[rop] );
+ XSetFunction( dpy, gc_brush, ropCodes[rop] );
+}
+
+// ### matthias - true?
+
+/*!
+ Sets the brush origin to \a (x, y).
+
+ The brush origin specifies the (0, 0) coordinate of the painter's
+ brush. This setting only applies to pattern brushes and pixmap
+ brushes.
+
+ \sa brushOrigin()
+*/
+
+void TQPainter::setBrushOrigin( int x, int y )
+{
+ if ( !isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::setBrushOrigin: Call begin() first" );
+#endif
+ return;
+ }
+ bro = TQPoint(x, y);
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ param[0].point = &bro;
+ if ( !pdev->cmd( TQPaintDevice::PdcSetBrushOrigin, this, param ) ||
+ !hd )
+ return;
+ }
+ if ( brushRef )
+ updateBrush(); // get non-cached brush GC
+ XSetTSOrigin( dpy, gc_brush, x, y );
+}
+
+
+/*!
+ Enables clipping if \a enable is TRUE, or disables clipping if \a
+ enable is FALSE.
+
+ \sa hasClipping(), setClipRect(), setClipRegion()
+*/
+
+void TQPainter::setClipping( bool enable )
+{
+ if ( !isActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPainter::setClipping: Will be reset by begin()" );
+#endif
+ return;
+ }
+
+ if ( enable == testf(ClipOn) )
+ return;
+
+ setf( ClipOn, enable );
+ if ( testf(ExtDev) ) {
+ if ( block_ext )
+ return;
+ TQPDevCmdParam param[1];
+ param[0].ival = enable;
+ if ( !pdev->cmd( TQPaintDevice::PdcSetClip, this, param ) || !hd )
+ return;
+ }
+ if ( enable ) {
+ TQRegion rgn = crgn;
+ if ( pdev == paintEventDevice && paintEventClipRegion )
+ rgn = rgn.intersect( *paintEventClipRegion );
+ if ( penRef )
+ updatePen();
+ if ( brushRef )
+ updateBrush();
+ x11SetClipRegion( dpy, gc, gc_brush, rendhd, rgn );
+ } else {
+ if ( pdev == paintEventDevice && paintEventClipRegion ) {
+ x11SetClipRegion( dpy, gc, gc_brush , rendhd, *paintEventClipRegion );
+ } else {
+ x11ClearClipRegion(dpy, gc, gc_brush, rendhd);
+ }
+ }
+}
+
+
+/*!
+ \overload
+
+ Sets the clip region to the rectangle \a r and enables clipping.
+ The clip mode is set to \a m.
+
+ \sa CoordinateMode
+*/
+
+void TQPainter::setClipRect( const TQRect &r, CoordinateMode m )
+{
+ setClipRegion( TQRegion( r ), m );
+}
+
+/*!
+ Sets the clip region to \a rgn and enables clipping. The clip mode
+ is set to \a m.
+
+ Note that the clip region is given in physical tqdevice coordinates
+ and \e not subject to any \link coordsys.html coordinate
+ transformation.\endlink
+
+ \sa setClipRect(), clipRegion(), setClipping() CoordinateMode
+*/
+
+void TQPainter::setClipRegion( const TQRegion &rgn, CoordinateMode m )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isActive() )
+ qWarning( "TQPainter::setClipRegion: Will be reset by begin()" );
+#endif
+ if ( m == CoordDevice )
+ crgn = rgn;
+ else
+ crgn = xmat * rgn;
+
+ if ( testf(ExtDev) ) {
+ if ( block_ext )
+ return;
+ TQPDevCmdParam param[2];
+ param[0].rgn = &rgn;
+ param[1].ival = m;
+ if ( !pdev->cmd( TQPaintDevice::PdcSetClipRegion, this, param ) )
+ return; // tqdevice cannot clip
+ }
+ clearf( ClipOn ); // be sure to update clip rgn
+ setClipping( TRUE );
+}
+
+
+/*!
+ \internal
+
+ Internal function for drawing a polygon.
+*/
+
+void TQPainter::drawPolyInternal( const TQPointArray &a, bool close )
+{
+ if ( a.size() < 2 )
+ return;
+
+ int x1, y1, x2, y2; // connect last to first point
+ a.point( a.size()-1, &x1, &y1 );
+ a.point( 0, &x2, &y2 );
+ bool do_close = close && !(x1 == x2 && y1 == y2);
+
+ if ( close && cbrush.style() != NoBrush ) { // draw filled polygon
+ XFillPolygon( dpy, hd, gc_brush, (XPoint*)a.shortPoints(), a.size(),
+ Nonconvex, CoordModeOrigin );
+ if ( cpen.style() == NoPen ) { // draw fake outline
+ XDrawLines( dpy, hd, gc_brush, (XPoint*)a.shortPoints(), a.size(),
+ CoordModeOrigin );
+ if ( do_close )
+ XDrawLine( dpy, hd, gc_brush, x1, y1, x2, y2 );
+ }
+ }
+ if ( cpen.style() != NoPen ) { // draw outline
+ XDrawLines( dpy, hd, gc, (XPoint*)a.shortPoints(), a.size(),
+ CoordModeOrigin);
+ if ( do_close )
+ XDrawLine( dpy, hd, gc, x1, y1, x2, y2 );
+ }
+}
+
+
+/*!
+ Draws/plots a single point at \a (x, y) using the current pen.
+
+ \sa TQPen
+*/
+
+void TQPainter::drawPoint( int x, int y )
+{
+ if ( !isActive() )
+ return;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ TQPoint p( x, y );
+ param[0].point = &p;
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawPoint, this, param ) ||
+ !hd )
+ return;
+ }
+ map( x, y, &x, &y );
+ }
+ if ( cpen.style() != NoPen )
+ XDrawPoint( dpy, hd, gc, x, y );
+}
+
+
+/*!
+ Draws/plots an array of points, \a a, using the current pen.
+
+ If \a index is non-zero (the default is zero) only points from \a
+ index are drawn. If \a npoints is negative (the default) the rest
+ of the points from \a index are drawn. If \a npoints is zero or
+ greater, \a npoints points are drawn.
+
+ \warning On X11, coordinates that do not fit into 16-bit signed
+ values are truncated. This limitation is expected to go away in
+ TQt 4.
+*/
+
+void TQPainter::drawPoints( const TQPointArray& a, int index, int npoints )
+{
+ if ( npoints < 0 )
+ npoints = a.size() - index;
+ if ( index + npoints > (int)a.size() )
+ npoints = a.size() - index;
+ if ( !isActive() || npoints < 1 || index < 0 )
+ return;
+ TQPointArray pa = a;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ for (int i=0; i<npoints; i++) {
+ TQPoint p( pa[index+i].x(), pa[index+i].y() );
+ param[0].point = &p;
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawPoint, this, param ))
+ return;
+ }
+ if ( !hd ) return;
+ }
+ if ( txop != TxNone ) {
+ pa = xForm( a, index, npoints );
+ if ( pa.size() != a.size() ) {
+ index = 0;
+ npoints = pa.size();
+ }
+ }
+ }
+ if ( cpen.style() != NoPen )
+ XDrawPoints( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, npoints )),
+ npoints, CoordModeOrigin );
+}
+
+
+/*! \obsolete
+ Sets the current pen position to \a (x, y)
+
+ \sa lineTo(), pos()
+*/
+
+void TQPainter::moveTo( int x, int y )
+{
+ if ( !isActive() )
+ return;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ TQPoint p( x, y );
+ param[0].point = &p;
+ if ( !pdev->cmd( TQPaintDevice::PdcMoveTo, this, param ) || !hd )
+ return;
+ }
+ }
+ curPt = TQPoint( x, y );
+}
+
+/*! \obsolete
+ Use drawLine() instead.
+
+ Draws a line from the current pen position to \a (x, y) and sets
+ \a (x, y) to be the new current pen position.
+
+ \sa TQPen moveTo(), drawLine(), pos()
+*/
+
+void TQPainter::lineTo( int x, int y )
+{
+ if ( !isActive() )
+ return;
+ int cx = curPt.x(), cy = curPt.y();
+ curPt = TQPoint( x, y );
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ TQPoint p( x, y );
+ param[0].point = &p;
+ if ( !pdev->cmd( TQPaintDevice::PdcLineTo, this, param ) || !hd )
+ return;
+ }
+ map( x, y, &x, &y );
+ map( cx, cy, &cx, &cy );
+ }
+ if ( cpen.style() != NoPen )
+ XDrawLine( dpy, hd, gc, cx, cy, x, y );
+}
+
+/*!
+ Draws a line from (\a x1, \a y1) to (\a x2, \a y2) and sets the
+ current pen position to (\a x2, \a y2).
+
+ \sa pen()
+*/
+
+void TQPainter::drawLine( int x1, int y1, int x2, int y2 )
+{
+ if ( !isActive() )
+ return;
+ curPt = TQPoint( x2, y2 );
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[2];
+ TQPoint p1(x1, y1), p2(x2, y2);
+ param[0].point = &p1;
+ param[1].point = &p2;
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawLine, this, param ) || !hd )
+ return;
+ }
+ map( x1, y1, &x1, &y1 );
+ map( x2, y2, &x2, &y2 );
+ }
+ if ( cpen.style() != NoPen )
+ XDrawLine( dpy, hd, gc, x1, y1, x2, y2 );
+}
+
+
+
+/*!
+ Draws a rectangle with upper left corner at \a (x, y) and with
+ width \a w and height \a h.
+
+ \sa TQPen, drawRoundRect()
+*/
+
+void TQPainter::drawRect( int x, int y, int w, int h )
+{
+ if ( !isActive() )
+ return;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ TQRect r( x, y, w, h );
+ param[0].rect = &r;
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawRect, this, param ) || !hd )
+ return;
+ }
+ if ( txop == TxRotShear ) { // rotate/shear polygon
+ TQPointArray pa = xmat.mapToPolygon( TQRect(x, y, w, h) );
+ pa.resize( 5 );
+ pa.setPoint( 4, pa.point( 0 ) );
+ drawPolyInternal( pa );
+ return;
+ }
+ map( x, y, w, h, &x, &y, &w, &h );
+ }
+ if ( w <= 0 || h <= 0 ) {
+ if ( w == 0 || h == 0 )
+ return;
+ fix_neg_rect( &x, &y, &w, &h );
+ }
+ if ( cbrush.style() != NoBrush ) {
+ if ( cpen.style() == NoPen ) {
+ XFillRectangle( dpy, hd, gc_brush, x, y, w, h );
+ return;
+ }
+ int lw = cpen.width();
+ int lw2 = (lw+1)/2;
+ if ( w > lw && h > lw )
+ XFillRectangle( dpy, hd, gc_brush, x+lw2, y+lw2, w-lw-1, h-lw-1 );
+ }
+ if ( cpen.style() != NoPen )
+ XDrawRectangle( dpy, hd, gc, x, y, w-1, h-1 );
+}
+
+/*!
+ \overload
+
+ Draws a Windows focus rectangle with upper left corner at (\a x,
+ \a y) and with width \a w and height \a h.
+
+ This function draws a stippled XOR rectangle that is used to
+ indicate keyboard focus (when TQApplication::style() is \c
+ WindowStyle).
+
+ \warning This function draws nothing if the coordinate system has
+ been \link rotate() rotated\endlink or \link shear()
+ sheared\endlink.
+
+ \sa drawRect(), TQApplication::style()
+*/
+
+void TQPainter::drawWinFocusRect( int x, int y, int w, int h )
+{
+ drawWinFocusRect( x, y, w, h, TRUE, color0 );
+}
+
+/*!
+ Draws a Windows focus rectangle with upper left corner at (\a x,
+ \a y) and with width \a w and height \a h using a pen color that
+ contrasts with \a bgColor.
+
+ This function draws a stippled rectangle (XOR is not used) that is
+ used to indicate keyboard focus (when the TQApplication::style() is
+ \c WindowStyle).
+
+ The pen color used to draw the rectangle is either white or black
+ depending on the color of \a bgColor (see TQColor::gray()).
+
+ \warning This function draws nothing if the coordinate system has
+ been \link rotate() rotated\endlink or \link shear()
+ sheared\endlink.
+
+ \sa drawRect(), TQApplication::style()
+*/
+
+void TQPainter::drawWinFocusRect( int x, int y, int w, int h,
+ const TQColor &bgColor )
+{
+ drawWinFocusRect( x, y, w, h, FALSE, bgColor );
+}
+
+
+/*!
+ \internal
+*/
+
+void TQPainter::drawWinFocusRect( int x, int y, int w, int h,
+ bool xorPaint, const TQColor &bgColor )
+{
+ if ( !isActive() || txop == TxRotShear )
+ return;
+ static char winfocus_line[] = { 1, 1 };
+
+ TQPen old_pen = cpen;
+ RasterOp old_rop = (RasterOp)rop;
+
+ if ( xorPaint ) {
+ if ( TQColor::numBitPlanes() <= 8 )
+ setPen( color1 );
+ else
+ setPen( white );
+ setRasterOp( XorROP );
+ } else {
+ if ( tqGray( bgColor.rgb() ) < 128 )
+ setPen( white );
+ else
+ setPen( black );
+ }
+
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ TQRect r( x, y, w, h );
+ param[0].rect = &r;
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawRect, this, param ) || !hd) {
+ setRasterOp( old_rop );
+ setPen( old_pen );
+ return;
+ }
+ }
+ map( x, y, w, h, &x, &y, &w, &h );
+ }
+ if ( w <= 0 || h <= 0 ) {
+ if ( w == 0 || h == 0 )
+ return;
+ fix_neg_rect( &x, &y, &w, &h );
+ }
+ XSetDashes( dpy, gc, 0, winfocus_line, 2 );
+ XSetLineAttributes( dpy, gc, 1, LineOnOffDash, CapButt, JoinMiter );
+
+ XDrawRectangle( dpy, hd, gc, x, y, w-1, h-1 );
+ XSetLineAttributes( dpy, gc, 0, LineSolid, CapButt, JoinMiter );
+ setRasterOp( old_rop );
+ setPen( old_pen );
+}
+
+
+/*!
+ Draws a rectangle with rounded corners at \a (x, y), with width \a
+ w and height \a h.
+
+ The \a xRnd and \a yRnd arguments specify how rounded the corners
+ should be. 0 is angled corners, 99 is maximum roundedness.
+
+ The width and height include all of the drawn lines.
+
+ \sa drawRect(), TQPen
+*/
+
+void TQPainter::drawRoundRect( int x, int y, int w, int h, int xRnd, int yRnd )
+{
+ if ( !isActive() )
+ return;
+ if ( xRnd <= 0 || yRnd <= 0 ) {
+ drawRect( x, y, w, h ); // draw normal rectangle
+ return;
+ }
+ if ( xRnd >= 100 ) // fix ranges
+ xRnd = 99;
+ if ( yRnd >= 100 )
+ yRnd = 99;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[3];
+ TQRect r( x, y, w, h );
+ param[0].rect = &r;
+ param[1].ival = xRnd;
+ param[2].ival = yRnd;
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawRoundRect, this, param ) ||
+ !hd )
+ return;
+ }
+ if ( txop == TxRotShear ) { // rotate/shear polygon
+ if ( w <= 0 || h <= 0 )
+ fix_neg_rect( &x, &y, &w, &h );
+ w--;
+ h--;
+ int rxx = w*xRnd/200;
+ int ryy = h*yRnd/200;
+ // were there overflows?
+ if ( rxx < 0 )
+ rxx = w/200*xRnd;
+ if ( ryy < 0 )
+ ryy = h/200*yRnd;
+ int rxx2 = 2*rxx;
+ int ryy2 = 2*ryy;
+ TQPointArray a[4];
+ a[0].makeArc( x, y, rxx2, ryy2, 1*16*90, 16*90, xmat );
+ a[1].makeArc( x, y+h-ryy2, rxx2, ryy2, 2*16*90, 16*90, xmat );
+ a[2].makeArc( x+w-rxx2, y+h-ryy2, rxx2, ryy2, 3*16*90, 16*90, xmat );
+ a[3].makeArc( x+w-rxx2, y, rxx2, ryy2, 0*16*90, 16*90, xmat );
+ // ### is there a better way to join TQPointArrays?
+ TQPointArray aa;
+ aa.resize( a[0].size() + a[1].size() + a[2].size() + a[3].size() );
+ uint j = 0;
+ for ( int k=0; k<4; k++ ) {
+ for ( uint i=0; i<a[k].size(); i++ ) {
+ aa.setPoint( j, a[k].point(i) );
+ j++;
+ }
+ }
+ drawPolyInternal( aa );
+ return;
+ }
+ map( x, y, w, h, &x, &y, &w, &h );
+ }
+ w--;
+ h--;
+ if ( w <= 0 || h <= 0 ) {
+ if ( w == 0 || h == 0 )
+ return;
+ fix_neg_rect( &x, &y, &w, &h );
+ }
+ int rx = (w*xRnd)/200;
+ int ry = (h*yRnd)/200;
+ int rx2 = 2*rx;
+ int ry2 = 2*ry;
+ if ( cbrush.style() != NoBrush ) { // draw filled round rect
+ int dp, ds;
+ if ( cpen.style() == NoPen ) {
+ dp = 0;
+ ds = 1;
+ }
+ else {
+ dp = 1;
+ ds = 0;
+ }
+#define SET_ARC(px, py, w, h, a1, a2) \
+ a->x=px; a->y=py; a->width=w; a->height=h; a->angle1=a1; a->angle2=a2; a++
+ XArc arcs[4];
+ XArc *a = arcs;
+ SET_ARC( x+w-rx2, y, rx2, ry2, 0, 90*64 );
+ SET_ARC( x, y, rx2, ry2, 90*64, 90*64 );
+ SET_ARC( x, y+h-ry2, rx2, ry2, 180*64, 90*64 );
+ SET_ARC( x+w-rx2, y+h-ry2, rx2, ry2, 270*64, 90*64 );
+ XFillArcs( dpy, hd, gc_brush, arcs, 4 );
+#undef SET_ARC
+#define SET_RCT(px, py, w, h) \
+ r->x=px; r->y=py; r->width=w; r->height=h; r++
+ XRectangle rects[3];
+ XRectangle *r = rects;
+ SET_RCT( x+rx, y+dp, w-rx2, ry );
+ SET_RCT( x+dp, y+ry, w+ds, h-ry2 );
+ SET_RCT( x+rx, y+h-ry, w-rx2, ry+ds );
+ XFillRectangles( dpy, hd, gc_brush, rects, 3 );
+#undef SET_RCT
+ }
+ if ( cpen.style() != NoPen ) { // draw outline
+#define SET_ARC(px, py, w, h, a1, a2) \
+ a->x=px; a->y=py; a->width=w; a->height=h; a->angle1=a1; a->angle2=a2; a++
+ XArc arcs[4];
+ XArc *a = arcs;
+ SET_ARC( x+w-rx2, y, rx2, ry2, 0, 90*64 );
+ SET_ARC( x, y, rx2, ry2, 90*64, 90*64 );
+ SET_ARC( x, y+h-ry2, rx2, ry2, 180*64, 90*64 );
+ SET_ARC( x+w-rx2, y+h-ry2, rx2, ry2, 270*64, 90*64 );
+ XDrawArcs( dpy, hd, gc, arcs, 4 );
+#undef SET_ARC
+#define SET_SEG(xp1, yp1, xp2, yp2) \
+ s->x1=xp1; s->y1=yp1; s->x2=xp2; s->y2=yp2; s++
+ XSegment segs[4];
+ XSegment *s = segs;
+ SET_SEG( x+rx, y, x+w-rx, y );
+ SET_SEG( x+rx, y+h, x+w-rx, y+h );
+ SET_SEG( x, y+ry, x, y+h-ry );
+ SET_SEG( x+w, y+ry, x+w, y+h-ry );
+ XDrawSegments( dpy, hd, gc, segs, 4 );
+#undef SET_SET
+ }
+}
+
+/*!
+ Draws an ellipse with center at \a (x + w/2, y + h/2) and size \a
+ (w, h).
+*/
+
+void TQPainter::drawEllipse( int x, int y, int w, int h )
+{
+ if ( !isActive() )
+ return;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ TQRect r( x, y, w, h );
+ param[0].rect = &r;
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawEllipse, this, param ) ||
+ !hd )
+ return;
+ }
+ if ( txop == TxRotShear ) { // rotate/shear polygon
+ TQPointArray a;
+ a.makeArc( x, y, w, h, 0, 360*16, xmat );
+ drawPolyInternal( a );
+ return;
+ }
+ map( x, y, w, h, &x, &y, &w, &h );
+ }
+ if ( w <= 0 || h <= 0 ) {
+ if ( w == 0 || h == 0 )
+ return;
+ fix_neg_rect( &x, &y, &w, &h );
+ }
+ if ( w == 1 && h == 1 ) {
+ XDrawPoint( dpy, hd, (cpen.style() == NoPen)?gc_brush:gc, x, y );
+ return;
+ }
+ w--;
+ h--;
+ if ( cbrush.style() != NoBrush ) { // draw filled ellipse
+ XFillArc( dpy, hd, gc_brush, x, y, w, h, 0, 360*64 );
+ if ( cpen.style() == NoPen ) {
+ XDrawArc( dpy, hd, gc_brush, x, y, w, h, 0, 360*64 );
+ return;
+ }
+ }
+ if ( cpen.style() != NoPen ) // draw outline
+ XDrawArc( dpy, hd, gc, x, y, w, h, 0, 360*64 );
+}
+
+
+/*!
+ Draws an arc defined by the rectangle \a (x, y, w, h), the start
+ angle \a a and the arc length \a alen.
+
+ The angles \a a and \a alen are 1/16th of a degree, i.e. a full
+ circle equals 5760 (16*360). Positive values of \a a and \a alen
+ mean counter-clockwise while negative values mean the clockwise
+ direction. Zero degrees is at the 3 o'clock position.
+
+ Example:
+ \code
+ TQPainter p( myWidget );
+ p.drawArc( 10,10, 70,100, 100*16, 160*16 ); // draws a "(" arc
+ \endcode
+
+ \sa drawPie(), drawChord()
+*/
+
+void TQPainter::drawArc( int x, int y, int w, int h, int a, int alen )
+{
+ if ( !isActive() )
+ return;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[3];
+ TQRect r( x, y, w, h );
+ param[0].rect = &r;
+ param[1].ival = a;
+ param[2].ival = alen;
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawArc, this, param ) ||
+ !hd )
+ return;
+ }
+ if ( txop == TxRotShear ) { // rotate/shear
+ TQPointArray pa;
+ pa.makeArc( x, y, w, h, a, alen, xmat ); // arc polyline
+ drawPolyInternal( pa, FALSE );
+ return;
+ }
+ map( x, y, w, h, &x, &y, &w, &h );
+ }
+ w--;
+ h--;
+ if ( w <= 0 || h <= 0 ) {
+ if ( w == 0 || h == 0 )
+ return;
+ fix_neg_rect( &x, &y, &w, &h );
+ }
+ if ( cpen.style() != NoPen )
+ XDrawArc( dpy, hd, gc, x, y, w, h, a*4, alen*4 );
+}
+
+
+/*!
+ Draws a pie defined by the rectangle \a (x, y, w, h), the start
+ angle \a a and the arc length \a alen.
+
+ The pie is filled with the current brush().
+
+ The angles \a a and \a alen are 1/16th of a degree, i.e. a full
+ circle equals 5760 (16*360). Positive values of \a a and \a alen
+ mean counter-clockwise while negative values mean the clockwise
+ direction. Zero degrees is at the 3 o'clock position.
+
+ \sa drawArc(), drawChord()
+*/
+
+void TQPainter::drawPie( int x, int y, int w, int h, int a, int alen )
+{
+ // Make sure "a" is 0..360*16, as otherwise a*4 may overflow 16 bits.
+ if ( a > (360*16) ) {
+ a = a % (360*16);
+ } else if ( a < 0 ) {
+ a = a % (360*16);
+ if ( a < 0 ) a += (360*16);
+ }
+
+ if ( !isActive() )
+ return;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[3];
+ TQRect r( x, y, w, h );
+ param[0].rect = &r;
+ param[1].ival = a;
+ param[2].ival = alen;
+ if ( !pdev->cmd( TQPaintDevice::PdcDrawPie, this, param ) || !hd )
+ return;
+ }
+ if ( txop == TxRotShear ) { // rotate/shear
+ TQPointArray pa;
+ pa.makeArc( x, y, w, h, a, alen, xmat ); // arc polyline
+ int n = pa.size();
+ int cx, cy;
+ xmat.map(x+w/2, y+h/2, &cx, &cy);
+ pa.resize( n+2 );
+ pa.setPoint( n, cx, cy ); // add legs
+ pa.setPoint( n+1, pa.at(0) );
+ drawPolyInternal( pa );
+ return;
+ }
+ map( x, y, w, h, &x, &y, &w, &h );
+ }
+ XSetArcMode( dpy, gc_brush, ArcPieSlice );
+ w--;
+ h--;
+ if ( w <= 0 || h <= 0 ) {
+ if ( w == 0 || h == 0 )
+ return;
+ fix_neg_rect( &x, &y, &w, &h );
+ }
+
+ GC g = gc;
+ bool nopen = cpen.style() == NoPen;
+
+ if ( cbrush.style() != NoBrush ) { // draw filled pie
+ XFillArc( dpy, hd, gc_brush, x, y, w, h, a*4, alen*4 );
+ if ( nopen ) {
+ g = gc_brush;
+ nopen = FALSE;
+ }
+ }
+ if ( !nopen ) { // draw pie outline
+ double w2 = 0.5*w; // with, height in ellipsis
+ double h2 = 0.5*h;
+ double xc = (double)x+w2;
+ double yc = (double)y+h2;
+ double ra1 = TQ_PI/2880.0*a; // convert a, alen to radians
+ double ra2 = ra1 + TQ_PI/2880.0*alen;
+ int xic = tqRound(xc);
+ int yic = tqRound(yc);
+ XDrawLine( dpy, hd, g, xic, yic,
+ tqRound(xc + qcos(ra1)*w2), tqRound(yc - qsin(ra1)*h2));
+ XDrawLine( dpy, hd, g, xic, yic,
+ tqRound(xc + qcos(ra2)*w2), tqRound(yc - qsin(ra2)*h2));
+ XDrawArc( dpy, hd, g, x, y, w, h, a*4, alen*4 );
+ }
+}
+
+
+/*!
+ Draws a chord defined by the rectangle \a (x, y, w, h), the start
+ angle \a a and the arc length \a alen.
+
+ The chord is filled with the current brush().
+
+ The angles \a a and \a alen are 1/16th of a degree, i.e. a full
+ circle equals 5760 (16*360). Positive values of \a a and \a alen
+ mean counter-clockwise while negative values mean the clockwise
+ direction. Zero degrees is at the 3 o'clock position.
+
+ \sa drawArc(), drawPie()
+*/
+
+void TQPainter::drawChord( int x, int y, int w, int h, int a, int alen )
+{
+ if ( !isActive() )
+ return;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[3];
+ TQRect r( x, y, w, h );
+ param[0].rect = &r;
+ param[1].ival = a;
+ param[2].ival = alen;
+ if ( !pdev->cmd(TQPaintDevice::PdcDrawChord, this, param) || !hd )
+ return;
+ }
+ if ( txop == TxRotShear ) { // rotate/shear
+ TQPointArray pa;
+ pa.makeArc( x, y, w-1, h-1, a, alen, xmat ); // arc polygon
+ int n = pa.size();
+ pa.resize( n+1 );
+ pa.setPoint( n, pa.at(0) ); // connect endpoints
+ drawPolyInternal( pa );
+ return;
+ }
+ map( x, y, w, h, &x, &y, &w, &h );
+ }
+ XSetArcMode( dpy, gc_brush, ArcChord );
+ w--;
+ h--;
+ if ( w <= 0 || h <= 0 ) {
+ if ( w == 0 || h == 0 )
+ return;
+ fix_neg_rect( &x, &y, &w, &h );
+ }
+
+ GC g = gc;
+ bool nopen = cpen.style() == NoPen;
+
+ if ( cbrush.style() != NoBrush ) { // draw filled chord
+ XFillArc( dpy, hd, gc_brush, x, y, w, h, a*4, alen*4 );
+ if ( nopen ) {
+ g = gc_brush;
+ nopen = FALSE;
+ }
+ }
+ if ( !nopen ) { // draw chord outline
+ double w2 = 0.5*w; // with, height in ellipsis
+ double h2 = 0.5*h;
+ double xc = (double)x+w2;
+ double yc = (double)y+h2;
+ double ra1 = TQ_PI/2880.0*a; // convert a, alen to radians
+ double ra2 = ra1 + TQ_PI/2880.0*alen;
+ XDrawLine( dpy, hd, g,
+ tqRound(xc + qcos(ra1)*w2), tqRound(yc - qsin(ra1)*h2),
+ tqRound(xc + qcos(ra2)*w2), tqRound(yc - qsin(ra2)*h2));
+ XDrawArc( dpy, hd, g, x, y, w, h, a*4, alen*4 );
+ }
+ XSetArcMode( dpy, gc_brush, ArcPieSlice );
+}
+
+
+/*!
+ Draws \a nlines separate lines from points defined in \a a,
+ starting at \a a[index] (\a index defaults to 0). If \a nlines is
+ -1 (the default) all points until the end of the array are used
+ (i.e. (a.size()-index)/2 lines are drawn).
+
+ Draws the 1st line from \a a[index] to \a a[index+1]. Draws the
+ 2nd line from \a a[index+2] to \a a[index+3] etc.
+
+ \warning On X11, coordinates that do not fit into 16-bit signed
+ values are truncated. This limitation is expected to go away in
+ TQt 4.
+
+ \sa drawPolyline(), drawPolygon(), TQPen
+*/
+
+void TQPainter::drawLineSegments( const TQPointArray &a, int index, int nlines )
+{
+ if ( nlines < 0 )
+ nlines = a.size()/2 - index/2;
+ if ( index + nlines*2 > (int)a.size() )
+ nlines = (a.size() - index)/2;
+ if ( !isActive() || nlines < 1 || index < 0 )
+ return;
+ TQPointArray pa = a;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ if ( 2*nlines != (int)pa.size() ) {
+ pa = TQPointArray( nlines*2 );
+ for ( int i=0; i<nlines*2; i++ )
+ pa.setPoint( i, a.point(index+i) );
+ index = 0;
+ }
+ TQPDevCmdParam param[1];
+ param[0].ptarr = (TQPointArray*)&pa;
+ if ( !pdev->cmd(TQPaintDevice::PdcDrawLineSegments, this, param) ||
+ !hd )
+ return;
+ }
+ if ( txop != TxNone ) {
+ pa = xForm( a, index, nlines*2 );
+ if ( pa.size() != a.size() ) {
+ index = 0;
+ nlines = pa.size()/2;
+ }
+ }
+ }
+ if ( cpen.style() != NoPen )
+ XDrawSegments( dpy, hd, gc,
+ (XSegment*)(pa.shortPoints( index, nlines*2 )), nlines );
+}
+
+
+/*!
+ Draws the polyline defined by the \a npoints points in \a a
+ starting at \a a[index]. (\a index defaults to 0.)
+
+ If \a npoints is -1 (the default) all points until the end of the
+ array are used (i.e. a.size()-index-1 line segments are drawn).
+
+ \warning On X11, coordinates that do not fit into 16-bit signed
+ values are truncated. This limitation is expected to go away in
+ TQt 4.
+
+ \sa drawLineSegments(), drawPolygon(), TQPen
+*/
+
+void TQPainter::drawPolyline( const TQPointArray &a, int index, int npoints )
+{
+ if ( npoints < 0 )
+ npoints = a.size() - index;
+ if ( index + npoints > (int)a.size() )
+ npoints = a.size() - index;
+ if ( !isActive() || npoints < 2 || index < 0 )
+ return;
+ TQPointArray pa = a;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ if ( npoints != (int)pa.size() ) {
+ pa = TQPointArray( npoints );
+ for ( int i=0; i<npoints; i++ )
+ pa.setPoint( i, a.point(index+i) );
+ index = 0;
+ }
+ TQPDevCmdParam param[1];
+ param[0].ptarr = (TQPointArray*)&pa;
+ if ( !pdev->cmd(TQPaintDevice::PdcDrawPolyline, this, param) || !hd )
+ return;
+ }
+ if ( txop != TxNone ) {
+ pa = xForm( pa, index, npoints );
+ if ( pa.size() != a.size() ) {
+ index = 0;
+ npoints = pa.size();
+ }
+ }
+ }
+ if ( cpen.style() != NoPen ) {
+ while(npoints>65535) {
+ XDrawLines( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, 65535 )),
+ 65535, CoordModeOrigin );
+ npoints-=65535;
+ index+=65535;
+ }
+ XDrawLines( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, npoints )),
+ npoints, CoordModeOrigin );
+ }
+}
+
+static int global_polygon_tqshape = Complex;
+
+/*!
+ Draws the polygon defined by the \a npoints points in \a a
+ starting at \a a[index]. (\a index defaults to 0.)
+
+ If \a npoints is -1 (the default) all points until the end of the
+ array are used (i.e. a.size()-index line segments define the
+ polygon).
+
+ The first point is always connected to the last point.
+
+ The polygon is filled with the current brush(). If \a winding is
+ TRUE, the polygon is filled using the winding fill algorithm. If
+ \a winding is FALSE, the polygon is filled using the even-odd
+ (alternative) fill algorithm.
+
+ \warning On X11, coordinates that do not fit into 16-bit signed
+ values are truncated. This limitation is expected to go away in
+ TQt 4.
+
+ \sa drawLineSegments(), drawPolyline(), TQPen
+*/
+
+void TQPainter::drawPolygon( const TQPointArray &a, bool winding,
+ int index, int npoints )
+{
+ if ( npoints < 0 )
+ npoints = a.size() - index;
+ if ( index + npoints > (int)a.size() )
+ npoints = a.size() - index;
+ if ( !isActive() || npoints < 2 || index < 0 )
+ return;
+ TQPointArray pa = a;
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ if ( npoints != (int)a.size() ) {
+ pa = TQPointArray( npoints );
+ for ( int i=0; i<npoints; i++ )
+ pa.setPoint( i, a.point(index+i) );
+ index = 0;
+ }
+ TQPDevCmdParam param[2];
+ param[0].ptarr = (TQPointArray*)&pa;
+ param[1].ival = winding;
+ if ( !pdev->cmd(TQPaintDevice::PdcDrawPolygon, this, param) || !hd )
+ return;
+ }
+ if ( txop != TxNone ) {
+ pa = xForm( a, index, npoints );
+ if ( pa.size() != a.size() ) {
+ index = 0;
+ npoints = pa.size();
+ }
+ }
+ }
+ if ( winding ) // set to winding fill rule
+ XSetFillRule( dpy, gc_brush, WindingRule );
+
+ if ( pa[index] != pa[index+npoints-1] ){ // close open pointarray
+ pa.detach();
+ pa.resize( index+npoints+1 );
+ pa.setPoint( index+npoints, pa[index] );
+ npoints++;
+ }
+
+ if ( cbrush.style() != NoBrush ) { // draw filled polygon
+ XFillPolygon( dpy, hd, gc_brush,
+ (XPoint*)(pa.shortPoints( index, npoints )),
+ npoints, global_polygon_tqshape, CoordModeOrigin );
+ }
+ if ( cpen.style() != NoPen ) { // draw outline
+ XDrawLines( dpy, hd, gc, (XPoint*)(pa.shortPoints( index, npoints )),
+ npoints, CoordModeOrigin );
+ }
+ if ( winding ) // set to normal fill rule
+ XSetFillRule( dpy, gc_brush, EvenOddRule );
+}
+
+/*!
+ Draws the convex polygon defined by the \a npoints points in \a pa
+ starting at \a pa[index] (\a index defaults to 0).
+
+ If the supplied polygon is not convex, the results are undefined.
+
+ On some platforms (e.g. X Window), this is faster than
+ drawPolygon().
+
+ \warning On X11, coordinates that do not fit into 16-bit signed
+ values are truncated. This limitation is expected to go away in
+ TQt 4.
+*/
+void TQPainter::drawConvexPolygon( const TQPointArray &pa,
+ int index, int npoints )
+{
+ global_polygon_tqshape = Convex;
+ drawPolygon(pa, FALSE, index, npoints);
+ global_polygon_tqshape = Complex;
+}
+
+
+
+/*!
+ Draws a cubic Bezier curve defined by the control points in \a a,
+ starting at \a a[index] (\a index defaults to 0).
+
+ Control points after \a a[index + 3] are ignored. Nothing happens
+ if there aren't enough control points.
+
+ \warning On X11, coordinates that do not fit into 16-bit signed
+ values are truncated. This limitation is expected to go away in
+ TQt 4.
+*/
+
+void TQPainter::drawCubicBezier( const TQPointArray &a, int index )
+{
+ if ( !isActive() )
+ return;
+ if ( a.size() - index < 4 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPainter::drawCubicBezier: Cubic Bezier needs 4 control "
+ "points" );
+#endif
+ return;
+ }
+ TQPointArray pa( a );
+ if ( index != 0 || a.size() > 4 ) {
+ pa = TQPointArray( 4 );
+ for ( int i=0; i<4; i++ )
+ pa.setPoint( i, a.point(index+i) );
+ }
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[1];
+ param[0].ptarr = (TQPointArray*)&pa;
+ if ( !pdev->cmd(TQPaintDevice::PdcDrawCubicBezier, this, param) ||
+ !hd )
+ return;
+ }
+ if ( txop != TxNone )
+ pa = xForm( pa );
+ }
+ if ( cpen.style() != NoPen ) {
+ pa = pa.cubicBezier();
+ XDrawLines( dpy, hd, gc, (XPoint*)pa.shortPoints(), pa.size(),
+ CoordModeOrigin );
+ }
+}
+
+
+/*!
+ Draws a pixmap at \a (x, y) by copying a part of \a pixmap into
+ the paint tqdevice.
+
+ \a (x, y) specifies the top-left point in the paint tqdevice that is
+ to be drawn onto. \a (sx, sy) specifies the top-left point in \a
+ pixmap that is to be drawn. The default is (0, 0).
+
+ \a (sw, sh) specifies the size of the pixmap that is to be drawn.
+ The default, (-1, -1), means all the way to the bottom right of
+ the pixmap.
+
+ Currently the tqmask of the pixmap or it's alpha channel are ignored
+ when painting on a TQPrinter.
+
+ \sa bitBlt(), TQPixmap::setMask()
+*/
+
+void TQPainter::drawPixmap( int x, int y, const TQPixmap &pixmap,
+ int sx, int sy, int sw, int sh )
+{
+ if ( !isActive() || pixmap.isNull() )
+ return;
+
+ // right/bottom
+ if ( sw < 0 )
+ sw = pixmap.width() - sx;
+ if ( sh < 0 )
+ sh = pixmap.height() - sy;
+
+ // Sanity-check clipping
+ if ( sx < 0 ) {
+ x -= sx;
+ sw += sx;
+ sx = 0;
+ }
+ if ( sw + sx > pixmap.width() )
+ sw = pixmap.width() - sx;
+ if ( sy < 0 ) {
+ y -= sy;
+ sh += sy;
+ sy = 0;
+ }
+ if ( sh + sy > pixmap.height() )
+ sh = pixmap.height() - sy;
+
+ if ( sw <= 0 || sh <= 0 )
+ return;
+
+ if ( pdev->x11Screen() != pixmap.x11Screen() ) {
+ TQPixmap* p = (TQPixmap*) &pixmap;
+ p->x11SetScreen( pdev->x11Screen() );
+ }
+
+ TQPixmap::x11SetDefaultScreen( pixmap.x11Screen() );
+
+ if ( testf(ExtDev|VxF|WxF) ) {
+ if ( testf(ExtDev) || txop == TxScale || txop == TxRotShear ) {
+ if ( sx != 0 || sy != 0 ||
+ sw != pixmap.width() || sh != pixmap.height() ) {
+ TQPixmap tmp( sw, sh, pixmap.depth() );
+ bitBlt( &tmp, 0, 0, &pixmap, sx, sy, sw, sh, CopyROP, TRUE );
+ if ( pixmap.tqmask() ) {
+ TQBitmap tqmask( sw, sh );
+ bitBlt( &tqmask, 0, 0, pixmap.tqmask(), sx, sy, sw, sh,
+ CopyROP, TRUE );
+ tmp.setMask( tqmask );
+ }
+ drawPixmap( x, y, tmp );
+ return;
+ }
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[2];
+ TQRect r(x, y, pixmap.width(), pixmap.height());
+ param[0].rect = &r;
+ param[1].pixmap = &pixmap;
+ if ( !pdev->cmd(TQPaintDevice::PdcDrawPixmap, this, param) || !hd )
+ return;
+ }
+ if ( txop == TxScale || txop == TxRotShear ) {
+ TQWMatrix mat( m11(), m12(),
+ m21(), m22(),
+ dx(), dy() );
+ mat = TQPixmap::trueMatrix( mat, sw, sh );
+ TQPixmap pm = pixmap.xForm( mat );
+ if ( !pm.tqmask() && txop == TxRotShear ) {
+ TQBitmap bm_clip( sw, sh, 1 );
+ bm_clip.fill( color1 );
+ pm.setMask( bm_clip.xForm(mat) );
+ }
+ map( x, y, &x, &y ); // compute position of pixmap
+ int dx, dy;
+ mat.map( 0, 0, &dx, &dy );
+ uint save_flags = flags;
+ flags = IsActive | (save_flags & ClipOn);
+ drawPixmap( x-dx, y-dy, pm );
+ flags = save_flags;
+ return;
+ }
+ }
+ map( x, y, &x, &y );
+ }
+
+ TQBitmap *tqmask = (TQBitmap *)pixmap.tqmask();
+ bool mono = pixmap.depth() == 1;
+
+ if ( tqmask && !hasClipping() && pdev != paintEventDevice ) {
+ if ( mono ) { // needs GCs pen color
+ bool selfmask = pixmap.data->selfmask;
+ if ( selfmask ) {
+ XSetFillStyle( dpy, gc, FillStippled );
+ XSetStipple( dpy, gc, pixmap.handle() );
+ } else {
+ XSetFillStyle( dpy, gc, FillOpaqueStippled );
+ XSetStipple( dpy, gc, pixmap.handle() );
+ XSetClipMask( dpy, gc, tqmask->handle() );
+ XSetClipOrigin( dpy, gc, x-sx, y-sy );
+ }
+ XSetTSOrigin( dpy, gc, x-sx, y-sy );
+ XFillRectangle( dpy, hd, gc, x, y, sw, sh );
+ XSetTSOrigin( dpy, gc, 0, 0 );
+ XSetFillStyle( dpy, gc, FillSolid );
+ if ( !selfmask ) {
+ if ( pdev == paintEventDevice && paintEventClipRegion ) {
+ x11SetClipRegion( dpy, gc, 0, rendhd, *paintEventClipRegion );
+ } else {
+ x11ClearClipRegion(dpy, gc, 0, rendhd);
+ }
+ }
+ } else {
+ bitBlt( pdev, x, y, &pixmap, sx, sy, sw, sh, (RasterOp)rop );
+ }
+ return;
+ }
+
+ TQRegion rgn = crgn;
+
+ if ( tqmask ) { // pixmap has clip tqmask
+ // Implies that clipping is on, either explicit or implicit
+ // Create a new tqmask that combines the tqmask with the clip region
+
+ if ( pdev == paintEventDevice && paintEventClipRegion ) {
+ if ( hasClipping() )
+ rgn = rgn.intersect( *paintEventClipRegion );
+ else
+ rgn = *paintEventClipRegion;
+ }
+
+ TQBitmap *comb = new TQBitmap( sw, sh );
+ comb->detach();
+ GC cgc = qt_xget_temp_gc( pixmap.x11Screen(), TRUE ); // get temporary mono GC
+ XSetForeground( dpy, cgc, 0 );
+ XFillRectangle( dpy, comb->handle(), cgc, 0, 0, sw, sh );
+ XSetBackground( dpy, cgc, 0 );
+ XSetForeground( dpy, cgc, 1 );
+ int num;
+ XRectangle *rects = (XRectangle *)qt_getClipRects( rgn, num );
+ XSetClipRectangles( dpy, cgc, -x, -y, rects, num, YXBanded );
+ XSetFillStyle( dpy, cgc, FillOpaqueStippled );
+ XSetStipple( dpy, cgc, tqmask->handle() );
+ XSetTSOrigin( dpy, cgc, -sx, -sy );
+ XFillRectangle( dpy, comb->handle(), cgc, 0, 0, sw, sh );
+ XSetTSOrigin( dpy, cgc, 0, 0 ); // restore cgc
+ XSetFillStyle( dpy, cgc, FillSolid );
+ XSetClipMask( dpy, cgc, None );
+ tqmask = comb; // it's deleted below
+
+ XSetClipMask( dpy, gc, tqmask->handle() );
+ XSetClipOrigin( dpy, gc, x, y );
+ }
+
+ if ( mono ) {
+ XSetBackground( dpy, gc, bg_col.pixel(scrn) );
+ XSetFillStyle( dpy, gc, FillOpaqueStippled );
+ XSetStipple( dpy, gc, pixmap.handle() );
+ XSetTSOrigin( dpy, gc, x-sx, y-sy );
+ XFillRectangle( dpy, hd, gc, x, y, sw, sh );
+ XSetTSOrigin( dpy, gc, 0, 0 );
+ XSetFillStyle( dpy, gc, FillSolid );
+ } else {
+#if !defined(TQT_NO_XFTFREETYPE) && !defined(TQT_NO_XRENDER)
+ Picture pict = rendhd ? XftDrawPicture((XftDraw *) rendhd) : None;
+ TQPixmap *alpha = pixmap.data->alphapm;
+
+ if ( pict && pixmap.x11RenderHandle() &&
+ alpha && alpha->x11RenderHandle()) {
+ XRenderComposite(dpy, PictOpOver, pixmap.x11RenderHandle(),
+ alpha->x11RenderHandle(), pict,
+ sx, sy, sx, sy, x, y, sw, sh);
+ } else
+#endif // !TQT_NO_XFTFREETYPE && !TQT_NO_XRENDER
+ {
+ XCopyArea( dpy, pixmap.handle(), hd, gc, sx, sy, sw, sh, x, y );
+ }
+ }
+
+ if ( tqmask ) { // restore clipping
+ XSetClipOrigin( dpy, gc, 0, 0 );
+ XSetRegion( dpy, gc, rgn.handle() );
+ delete tqmask; // delete comb, created above
+ }
+}
+
+
+/* Internal, used by drawTiledPixmap */
+
+static void drawTile( TQPainter *p, int x, int y, int w, int h,
+ const TQPixmap &pixmap, int xOffset, int yOffset )
+{
+ int yPos, xPos, drawH, drawW, yOff, xOff;
+ yPos = y;
+ yOff = yOffset;
+ while( yPos < y + h ) {
+ drawH = pixmap.height() - yOff; // Cropping first row
+ if ( yPos + drawH > y + h ) // Cropping last row
+ drawH = y + h - yPos;
+ xPos = x;
+ xOff = xOffset;
+ while( xPos < x + w ) {
+ drawW = pixmap.width() - xOff; // Cropping first column
+ if ( xPos + drawW > x + w ) // Cropping last column
+ drawW = x + w - xPos;
+ p->drawPixmap( xPos, yPos, pixmap, xOff, yOff, drawW, drawH );
+ xPos += drawW;
+ xOff = 0;
+ }
+ yPos += drawH;
+ yOff = 0;
+ }
+}
+
+#if 0 // see comment in drawTiledPixmap
+/* Internal, used by drawTiledPixmap */
+
+static void fillTile( TQPixmap *tile, const TQPixmap &pixmap )
+{
+ bitBlt( tile, 0, 0, &pixmap, 0, 0, -1, -1, TQt::CopyROP, TRUE );
+ int x = pixmap.width();
+ while ( x < tile->width() ) {
+ bitBlt( tile, x,0, tile, 0,0, x,pixmap.height(), TQt::CopyROP, TRUE );
+ x *= 2;
+ }
+ int y = pixmap.height();
+ while ( y < tile->height() ) {
+ bitBlt( tile, 0,y, tile, 0,0, tile->width(),y, TQt::CopyROP, TRUE );
+ y *= 2;
+ }
+}
+#endif
+
+/*!
+ Draws a tiled \a pixmap in the specified rectangle.
+
+ \a (x, y) specifies the top-left point in the paint tqdevice that is
+ to be drawn onto; with the width and height given by \a w and \a
+ h. \a (sx, sy) specifies the top-left point in \a pixmap that is
+ to be drawn. The default is (0, 0).
+
+ Calling drawTiledPixmap() is similar to calling drawPixmap()
+ several times to fill (tile) an area with a pixmap, but is
+ potentially much more efficient depending on the underlying window
+ system.
+
+ \sa drawPixmap()
+*/
+
+void TQPainter::drawTiledPixmap( int x, int y, int w, int h,
+ const TQPixmap &pixmap, int sx, int sy )
+{
+ int sw = pixmap.width();
+ int sh = pixmap.height();
+ if (!sw || !sh )
+ return;
+ if ( sx < 0 )
+ sx = sw - -sx % sw;
+ else
+ sx = sx % sw;
+ if ( sy < 0 )
+ sy = sh - -sy % sh;
+ else
+ sy = sy % sh;
+ /*
+ Requirements for optimizing tiled pixmaps:
+ - not an external tqdevice
+ - not scale or rotshear
+ - not mono pixmap
+ - no tqmask
+ */
+ TQBitmap *tqmask = (TQBitmap *)pixmap.tqmask();
+ if ( !testf(ExtDev) && txop <= TxTranslate && pixmap.depth() > 1 &&
+ tqmask == 0 ) {
+ if ( txop == TxTranslate )
+ map( x, y, &x, &y );
+
+#if !defined(TQT_NO_XFTFREETYPE) && !defined(TQT_NO_XRENDER)
+ Picture pict = rendhd ? XftDrawPicture((XftDraw *) rendhd) : None;
+ TQPixmap *alpha = pixmap.data->alphapm;
+
+ if (pict && pixmap.x11RenderHandle() && alpha && alpha->x11RenderHandle()) {
+ // this is essentially drawTile() from above, inlined for
+ // the XRenderComposite call
+ int yPos, xPos, drawH, drawW, yOff, xOff;
+ yPos = y;
+ yOff = sy;
+ while( yPos < y + h ) {
+ drawH = pixmap.height() - yOff; // Cropping first row
+ if ( yPos + drawH > y + h ) // Cropping last row
+ drawH = y + h - yPos;
+ xPos = x;
+ xOff = sx;
+ while( xPos < x + w ) {
+ drawW = pixmap.width() - xOff; // Cropping first column
+ if ( xPos + drawW > x + w ) // Cropping last column
+ drawW = x + w - xPos;
+ XRenderComposite(dpy, PictOpOver, pixmap.x11RenderHandle(),
+ alpha->x11RenderHandle(), pict,
+ xOff, yOff, xOff, yOff, xPos, yPos, drawW, drawH);
+ xPos += drawW;
+ xOff = 0;
+ }
+ yPos += drawH;
+ yOff = 0;
+ }
+ return;
+ }
+#endif // !TQT_NO_XFTFREETYPE && !TQT_NO_XRENDER
+
+ XSetTile( dpy, gc, pixmap.handle() );
+ XSetFillStyle( dpy, gc, FillTiled );
+ XSetTSOrigin( dpy, gc, x-sx, y-sy );
+ XFillRectangle( dpy, hd, gc, x, y, w, h );
+ XSetTSOrigin( dpy, gc, 0, 0 );
+ XSetFillStyle( dpy, gc, FillSolid );
+ return;
+ }
+
+#if 0
+ // maybe there'll be point in this again, but for the time all it
+ // does is make trouble for the postscript code.
+ if ( sw*sh < 8192 && sw*sh < 16*w*h ) {
+ int tw = sw;
+ int th = sh;
+ while( th * tw < 4096 && ( th < h || tw < w ) ) {
+ if ( h/th > w/tw )
+ th *= 2;
+ else
+ tw *= 2;
+ }
+ TQPixmap tile( tw, th, pixmap.depth(), TQPixmap::NormalOptim );
+ fillTile( &tile, pixmap );
+ if ( tqmask ) {
+ TQBitmap tiletqmask( tw, th, TQPixmap::NormalOptim );
+ fillTile( &tiletqmask, *tqmask );
+ tile.setMask( tiletqmask );
+ }
+ drawTile( this, x, y, w, h, tile, sx, sy );
+ } else {
+ drawTile( this, x, y, w, h, pixmap, sx, sy );
+ }
+#else
+ // for now we'll just output the original and let the postscript
+ // code make what it can of it. qpicture will be unhappy.
+ drawTile( this, x, y, w, h, pixmap, sx, sy );
+#endif
+}
+
+#if 0
+//
+// Generate a string that describes a transformed bitmap. This string is used
+// to insert and tqfind bitmaps in the global pixmap cache.
+//
+
+static TQString gen_text_bitmap_key( const TQWMatrix &m, const TQFont &font,
+ const TQString &str, int pos, int len )
+{
+ TQString fk = font.key();
+ int sz = 4*2 + len*2 + fk.length()*2 + sizeof(double)*6;
+ TQByteArray buf(sz);
+ uchar *p = (uchar *)buf.data();
+ *((double*)p)=m.m11(); p+=sizeof(double);
+ *((double*)p)=m.m12(); p+=sizeof(double);
+ *((double*)p)=m.m21(); p+=sizeof(double);
+ *((double*)p)=m.m22(); p+=sizeof(double);
+ *((double*)p)=m.dx(); p+=sizeof(double);
+ *((double*)p)=m.dy(); p+=sizeof(double);
+ TQChar h1( '$' );
+ TQChar h2( 'q' );
+ TQChar h3( 't' );
+ TQChar h4( '$' );
+ *((TQChar*)p)=h1; p+=2;
+ *((TQChar*)p)=h2; p+=2;
+ *((TQChar*)p)=h3; p+=2;
+ *((TQChar*)p)=h4; p+=2;
+ memcpy( (char*)p, (char*)(str.tqunicode()+pos), len*2 ); p += len*2;
+ memcpy( (char*)p, (char*)fk.tqunicode(), fk.length()*2 ); p += fk.length()*2;
+ return TQString( (TQChar*)buf.data(), buf.size()/2 );
+}
+
+static TQBitmap *get_text_bitmap( const TQString &key )
+{
+ return (TQBitmap*)TQPixmapCache::tqfind( key );
+}
+
+static void ins_text_bitmap( const TQString &key, TQBitmap *bm )
+{
+ if ( !TQPixmapCache::insert(key, bm) ) // cannot insert pixmap
+ delete bm;
+}
+#endif
+
+void qt_draw_transformed_rect( TQPainter *p, int x, int y, int w, int h, bool fill )
+{
+ XPoint points[5];
+ int xp = x, yp = y;
+ p->map( xp, yp, &xp, &yp );
+ points[0].x = xp;
+ points[0].y = yp;
+ xp = x + w; yp = y;
+ p->map( xp, yp, &xp, &yp );
+ points[1].x = xp;
+ points[1].y = yp;
+ xp = x + w; yp = y + h;
+ p->map( xp, yp, &xp, &yp );
+ points[2].x = xp;
+ points[2].y = yp;
+ xp = x; yp = y + h;
+ p->map( xp, yp, &xp, &yp );
+ points[3].x = xp;
+ points[3].y = yp;
+ points[4] = points[0];
+
+ if ( fill )
+ XFillPolygon( p->dpy, p->hd, p->gc, points, 4, Convex, CoordModeOrigin );
+ else
+ XDrawLines( p->dpy, p->hd, p->gc, points, 5, CoordModeOrigin );
+}
+
+void qt_draw_background( TQPainter *p, int x, int y, int w, int h )
+{
+ if (p->testf(TQPainter::ExtDev)) {
+ if (p->pdev->devType() == TQInternal::Printer)
+ p->fillRect(x, y, w, h, p->bg_col);
+ return;
+ }
+ XSetForeground( p->dpy, p->gc, p->bg_col.pixel(p->scrn) );
+ qt_draw_transformed_rect( p, x, y, w, h, TRUE);
+ XSetForeground( p->dpy, p->gc, p->cpen.color().pixel(p->scrn) );
+}
+
+/*!
+ Draws at most \a len characters of the string \a str at position
+ \a (x, y).
+
+ \a (x, y) is the base line position. Note that the meaning of \a y
+ is not the same for the two drawText() varieties.
+*/
+void TQPainter::drawText( int x, int y, const TQString &str, int len, TQPainter::TextDirection dir )
+{
+ drawText( x, y, str, 0, len, dir );
+}
+
+/*!
+ Draws at most \a len characters starting at position \a pos from the
+ string \a str to position \a (x, y).
+
+ \a (x, y) is the base line position. Note that the meaning of \a y
+ is not the same for the two drawText() varieties.
+*/
+void TQPainter::drawText( int x, int y, const TQString &str, int pos, int len, TQPainter::TextDirection dir )
+{
+ if ( !isActive() )
+ return;
+ if (len < 0)
+ len = str.length() - pos;
+ if ( len <= 0 || pos >= (int)str.length() ) // empty string
+ return;
+ if ( pos + len > (int)str.length() )
+ len = str.length() - pos;
+
+ if ( testf(DirtyFont) ) {
+ updateFont();
+ }
+
+ if ( testf(ExtDev) && pdev->devType() != TQInternal::Printer ) {
+ TQPDevCmdParam param[3];
+ TQPoint p(x, y);
+ TQString string = str.mid( pos, len );
+ param[0].point = &p;
+ param[1].str = &string;
+ param[2].ival = TQFont::Latin;
+ if ( !pdev->cmd(TQPaintDevice::PdcDrawText2, this, param) || !hd )
+ return;
+ }
+
+ bool simple = (dir == TQPainter::Auto) && str.simpleText();
+ // we can't take the complete string here as we would otherwise
+ // get quadratic behaviour when drawing long strings in parts.
+ // we do however need some chars around the part we paint to get arabic shaping correct.
+ // ### maybe possible to remove after cursor restrictions work in TQRT
+ int start;
+ int end;
+ if ( simple ) {
+ start = pos;
+ end = pos+len;
+ } else {
+ start = TQMAX( 0, pos - 8 );
+ end = TQMIN( (int)str.length(), pos + len + 8 );
+ }
+ TQConstString cstr( str.tqunicode() + start, end - start );
+ pos -= start;
+
+ TQTextEngine engine( cstr.string(), pfont ? pfont->d : cfont.d );
+ TQTextLayout tqlayout( &engine );
+
+ // this is actually what beginLayout does. Inlined here, so we can
+ // avoid the bidi algorithm if we don't need it.
+ engine.itemize( simple ? TQTextEngine::NoBidi|TQTextEngine::SingleLine : TQTextEngine::Full|TQTextEngine::SingleLine );
+ engine.currentItem = 0;
+ engine.firstItemInLine = -1;
+
+ if ( dir != Auto ) {
+ int level = dir == RTL ? 1 : 0;
+ for ( int i = engine.items.size(); i >= 0; i-- )
+ engine.items[i].analysis.bidiLevel = level;
+ }
+
+ if ( !simple ) {
+ tqlayout.setBoundary( pos );
+ tqlayout.setBoundary( pos + len );
+ }
+
+ // small hack to force skipping of unneeded items
+ start = 0;
+ while ( engine.items[start].position < pos )
+ ++start;
+ engine.currentItem = start;
+ tqlayout.beginLine( 0xfffffff );
+ end = start;
+ while ( !tqlayout.atEnd() && tqlayout.currentItem().from() < pos + len ) {
+ tqlayout.addCurrentItem();
+ end++;
+ }
+ TQFontMetrics fm(fontMetrics());
+ int ascent = fm.ascent(), descent = fm.descent();
+ int left, right;
+ tqlayout.endLine( 0, 0, TQt::SingleLine|TQt::AlignLeft, &ascent, &descent, &left, &right );
+
+ // do _not_ call endLayout() here, as it would clean up the tqshaped items and we would do shaping another time
+ // for painting.
+
+ int textFlags = 0;
+ if ( cfont.d->underline ) textFlags |= TQt::Underline;
+ if ( cfont.d->overline ) textFlags |= TQt::Overline;
+ if ( cfont.d->strikeOut ) textFlags |= TQt::StrikeOut;
+
+ if ( bg_mode == OpaqueMode )
+ qt_draw_background( this, x, y-ascent, right-left, ascent+descent+1);
+
+ for ( int i = start; i < end; i++ ) {
+ TQTextItem ti;
+ ti.item = i;
+ ti.engine = &engine;
+
+ tqdrawTextItem( x, y - ascent, ti, textFlags );
+ }
+ tqlayout.d = 0;
+}
+
+
+/*! \internal
+ Draws the text item \a ti at position \a (x, y ).
+
+ This method ignores the painters background mode and
+ color. drawText and qt_format_text have to do it themselves, as
+ only they know the extents of the complete string.
+
+ It ignores the font set on the painter as the text item has one of its own.
+
+ The underline and strikeout parameters of the text items font are
+ ignored aswell. You'll need to pass in the correct flags to get
+ underlining and strikeout.
+*/
+void TQPainter::tqdrawTextItem( int x, int y, const TQTextItem &ti, int textFlags )
+{
+ if ( testf(ExtDev) ) {
+ TQPDevCmdParam param[2];
+ TQPoint p(x, y);
+ param[0].point = &p;
+ param[1].textItem = &ti;
+ bool retval = pdev->cmd(TQPaintDevice::PdcDrawTextItem, this, param);
+ if ( !retval || !hd )
+ return;
+ }
+
+ TQTextEngine *engine = ti.engine;
+ TQScriptItem *si = &engine->items[ti.item];
+
+ engine->tqshape( ti.item );
+ TQFontEngine *fe = si->fontEngine;
+ assert( fe != 0 );
+
+ x += si->x;
+ y += si->y;
+
+ fe->draw( this, x, y, engine, si, textFlags );
+}
+
+#if TQT_VERSION >= 0x040000
+#error "remove current position and associated methods"
+#endif
+/*!
+ \obsolete
+ Returns the current position of the pen.
+
+ \sa moveTo()
+ */
+TQPoint TQPainter::pos() const
+{
+ return curPt;
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqpalette.cpp b/tqtinterface/qt4/src/kernel/tqpalette.cpp
new file mode 100644
index 0000000..2e9e49e
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpalette.cpp
@@ -0,0 +1,1348 @@
+/****************************************************************************
+**
+** Implementation of TQColorGroup and TQPalette classes
+**
+** Created : 950323
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <tqtglobaldefines.h>
+// Nasty, nasty horrid HACK to get access to QPalette's private members
+// This is TERRIBLE and I wish there was a way around it
+// This is a good example of the new, broken & irritating Qt4 API,
+// and the corresponding loss in functionality versus Qt3.
+// See also tqrect.cpp
+#define private protected
+#include <Qt/qpalette.h>
+#undef private
+
+#include "tqpalette.h"
+
+#ifndef TQT_NO_PALETTE
+#include "tqdatastream.h"
+#include "tqcleanuphandler.h"
+
+#ifdef USE_QT4
+
+#include <Qt/qvariant.h>
+
+/*!
+ Constructs a palette with the specified \a active, \a disabled and
+ \a inactive color groups.
+*/
+TQPalette::TQPalette(const TQColorGroup &active, const TQColorGroup &disabled, const TQColorGroup &inactive) : QPalette()
+{
+ Q_ASSERT(TQPalette::NColorRoles == TQPalette::ToolTipText + 1);
+ tqsetColorGroup(Active, active);
+ tqsetColorGroup(Disabled, disabled);
+ tqsetColorGroup(Inactive, inactive);
+}
+
+TQColorGroup TQPalette::createColorGroup(ColorGroup cr) const
+{
+ TQColorGroup ret(*this);
+ ret.setCurrentColorGroup(cr);
+ return ret;
+}
+
+void TQPalette::tqsetColorGroup(ColorGroup cg, const TQColorGroup &g)
+{
+ setColorGroup(cg, g.brush(WindowText), g.brush(Button), g.brush(Light),
+ g.brush(Dark), g.brush(Mid), g.brush(Text), g.brush(BrightText),
+ g.brush(Base), g.brush(AlternateBase), g.brush(Window),
+ g.brush(Midlight), g.brush(ButtonText), g.brush(Shadow),
+ g.brush(Highlight), g.brush(HighlightedText), g.brush(Link),
+ g.brush(LinkVisited), g.brush(ToolTipBase), g.brush(ToolTipText));
+}
+
+bool TQColorGroup::operator==(const TQColorGroup &other) const
+{
+ if (isCopyOf(other))
+ return true;
+ for (int role = 0; role < int(NColorRoles); role++) {
+ if (brush(currentColorGroup(), (QPalette::ColorRole)role) != other.brush((QPalette::ColorGroup)(other.currentColorGroup()), (QPalette::ColorRole)role))
+ return false;
+ }
+ return true;
+}
+
+/*!
+ Returns the color group as a QVariant
+*/
+// TQColorGroup::operator QVariant() const
+// {
+// return QVariant(QVariant::ColorGroup, this);
+// }
+
+/*!\internal*/
+TQPalette::ColorRole TQPalette::foregroundRoleFromMode( TQt::BackgroundMode mode )
+{
+ switch (mode) {
+ case TQt::PaletteButton:
+ return TQColorGroup::ButtonText;
+ case TQt::PaletteBase:
+ return TQColorGroup::Text;
+ case TQt::PaletteDark:
+ case TQt::PaletteShadow:
+ return TQColorGroup::Light;
+ case TQt::PaletteHighlight:
+ return TQColorGroup::HighlightedText;
+ case TQt::PaletteBackground:
+ default:
+ return TQColorGroup::Foreground;
+ }
+}
+
+/*!\internal*/
+TQPalette::ColorRole TQPalette::backgroundRoleFromMode( TQt::BackgroundMode mode)
+{
+ switch (mode) {
+ case TQt::PaletteForeground:
+ return TQColorGroup::Foreground;
+ case TQt::PaletteButton:
+ return TQColorGroup::Button;
+ case TQt::PaletteLight:
+ return TQColorGroup::Light;
+ case TQt::PaletteMidlight:
+ return TQColorGroup::Midlight;
+ case TQt::PaletteDark:
+ return TQColorGroup::Dark;
+ case TQt::PaletteMid:
+ return TQColorGroup::Mid;
+ case TQt::PaletteText:
+ return TQColorGroup::Text;
+ case TQt::PaletteBrightText:
+ return TQColorGroup::BrightText;
+ case TQt::PaletteButtonText:
+ return TQColorGroup::ButtonText;
+ case TQt::PaletteBase:
+ return TQColorGroup::Base;
+ case TQt::PaletteShadow:
+ return TQColorGroup::Shadow;
+ case TQt::PaletteHighlight:
+ return TQColorGroup::Highlight;
+ case TQt::PaletteHighlightedText:
+ return TQColorGroup::HighlightedText;
+ case TQt::PaletteLink:
+ return TQColorGroup::Link;
+ case TQt::PaletteLinkVisited:
+ return TQColorGroup::LinkVisited;
+ case TQt::PaletteBackground:
+ default:
+ return TQColorGroup::Background;
+ }
+}
+
+#else // USE_QT4
+
+/*****************************************************************************
+ TQColorGroup member functions
+ *****************************************************************************/
+
+/*!
+ \class TQColorGroup tqpalette.h
+ \brief The TQColorGroup class tqcontains a group of widget colors.
+
+ \ingroup appearance
+ \ingroup graphics
+ \ingroup images
+
+ A color group tqcontains a group of colors used by widgets for
+ drawing themselves. We recommend that widgets use color group
+ roles such as "foreground" and "base" rather than literal colors
+ like "red" or "turquoise". The color roles are enumerated and
+ defined in the \l ColorRole documentation.
+
+ The most common use of TQColorGroup is like this:
+
+ \code
+ TQPainter p;
+ ...
+ p.setPen( tqcolorGroup().foreground() );
+ p.drawLine( ... )
+ \endcode
+
+ It is also possible to modify color groups or create new color
+ groups from scratch.
+
+ The color group class can be created using three different
+ constructors or by modifying one supplied by TQt. The default
+ constructor creates an all-black color group, which can then be
+ modified using set functions; there's also a constructor for
+ specifying all the color group colors. And there is also a copy
+ constructor.
+
+ We strongly recommend using a system-supplied color group and
+ modifying that as necessary.
+
+ You modify a color group by calling the access functions
+ setColor() and setBrush(), depending on whether you want a pure
+ color or a pixmap pattern.
+
+ There are also corresponding color() and brush() getters, and a
+ commonly used convenience function to get each ColorRole:
+ background(), foreground(), base(), etc.
+
+ \sa TQColor TQPalette TQWidget::tqcolorGroup()
+*/
+
+
+/*!
+ \enum TQColorGroup::ColorRole
+
+ The ColorRole enum defines the different symbolic color roles used
+ in current GUIs.
+
+ The central roles are:
+
+ \value Background general background color.
+
+ \value Foreground general foreground color.
+
+ \value Base used as background color for text entry widgets, for example;
+ usually white or another light color.
+
+ \value Text the foreground color used with \c Base. Usually this
+ is the same as the \c Foreground, in which case it must provide good
+ contrast with \c Background and \c Base.
+
+ \value Button general button background color in which buttons need a
+ background different from \c Background, as in the Macintosh style.
+
+ \value ButtonText a foreground color used with the \c Button color.
+
+ There are some color roles used mostly for 3D bevel and shadow
+ effects:
+
+ \value Light lighter than \c Button color.
+
+ \value Midlight between \c Button and \c Light.
+
+ \value Dark darker than \c Button.
+
+ \value Mid between \c Button and \c Dark.
+
+ \value Shadow a very dark color.
+ By default, the shadow color is \c TQt::black.
+
+ All of these are normally derived from \c Background and used in
+ ways that depend on that relationship. For example, buttons depend
+ on it to make the bevels look attractive, and Motif scroll bars
+ depend on \c Mid to be slightly different from \c Background.
+
+ Selected (marked) items have two roles:
+
+ \value Highlight a color to indicate a selected item or the
+ current item. By default, the highlight color is \c TQt::darkBlue.
+
+ \value HighlightedText a text color that contrasts with \c Highlight.
+ By default, the highlighted text color is \c TQt::white.
+
+ Finally, there is a special role for text that needs to be
+ drawn where \c Text or \c Foreground would give poor contrast,
+ such as on pressed push buttons:
+
+ \value BrightText a text color that is very different from \c
+ Foreground and contrasts well with e.g. \c Dark.
+
+ \value Link a text color used for unvisited hyperlinks.
+ By default, the link color is \c TQt::blue.
+
+ \value LinkVisited a text color used for already visited hyperlinks.
+ By default, the linkvisited color is \c TQt::magenta.
+
+ \value NColorRoles Internal.
+
+ Note that text colors can be used for things other than just
+ words; text colors are \e usually used for text, but it's quite
+ common to use the text color roles for lines, icons, etc.
+
+ This image shows most of the color roles in use:
+ \img palette.png Color Roles
+*/
+
+
+class TQColorGroupPrivate : public TQShared
+{
+public:
+ TQBrush br[TQColorGroup::NColorRoles];
+ TQColorGroupPrivate* detach() {
+ if ( count > 1 ) {
+ deref();
+ TQColorGroupPrivate* d = new TQColorGroupPrivate;
+ for (int i=0; i<TQColorGroup::NColorRoles; i++)
+ d->br[i] = br[i];
+ return d;
+ }
+ return this;
+ }
+};
+
+/*!
+ Constructs a color group with all colors set to black.
+*/
+
+TQColorGroup::TQColorGroup()
+{
+ static TQColorGroupPrivate* defColorGroupData = 0;
+ if ( !defColorGroupData ) {
+ static TQSharedCleanupHandler<TQColorGroupPrivate> defColorGroupCleanup;
+ defColorGroupData = new TQColorGroupPrivate;
+ defColorGroupCleanup.set( &defColorGroupData );
+ }
+ d = defColorGroupData;
+ br = d->br;
+ d->ref();
+}
+
+/*!
+ Constructs a color group that is an independent copy of \a other.
+*/
+TQColorGroup::TQColorGroup( const TQColorGroup& other )
+{
+ d = other.d;
+ d->ref();
+ br = d->br;
+}
+
+/*!
+ Copies the colors of \a other to this color group.
+*/
+TQColorGroup& TQColorGroup::operator =(const TQColorGroup& other)
+{
+ if ( d != other.d ) {
+ if ( d->deref() )
+ delete d;
+ d = other.d;
+ br = d->br;
+ d->ref();
+ }
+ return *this;
+}
+
+static TQColor qt_mix_colors( TQColor a, TQColor b)
+{
+ return TQColor( (a.red() + b.red()) / 2, (a.green() + b.green()) / 2, (a.blue() + b.blue()) / 2 );
+}
+
+
+/*!
+ Constructs a color group. You can pass either brushes, pixmaps or
+ plain colors for \a foreground, \a button, \a light, \a dark, \a
+ mid, \a text, \a bright_text, \a base and \a background.
+
+ \sa TQBrush
+*/
+ TQColorGroup::TQColorGroup( const TQBrush &foreground, const TQBrush &button,
+ const TQBrush &light, const TQBrush &dark,
+ const TQBrush &mid, const TQBrush &text,
+ const TQBrush &bright_text, const TQBrush &base,
+ const TQBrush &background)
+{
+ d = new TQColorGroupPrivate;
+ br = d->br;
+ br[Foreground] = foreground;
+ br[Button] = button;
+ br[Light] = light;
+ br[Dark] = dark;
+ br[Mid] = mid;
+ br[Text] = text;
+ br[BrightText] = bright_text;
+ br[ButtonText] = text;
+ br[Base] = base;
+ br[Background] = background;
+ br[Midlight] = qt_mix_colors( br[Button].color(), br[Light].color() );
+ br[Shadow] = TQt::black;
+ br[Highlight] = TQt::darkBlue;
+ br[HighlightedText] = TQt::white;
+ br[Link] = TQt::blue;
+ br[LinkVisited] = TQt::magenta;
+}
+
+
+/*!\obsolete
+
+ Constructs a color group with the specified colors. The button
+ color will be set to the background color.
+*/
+
+TQColorGroup::TQColorGroup( const TQColor &foreground, const TQColor &background,
+ const TQColor &light, const TQColor &dark,
+ const TQColor &mid,
+ const TQColor &text, const TQColor &base )
+{
+ d = new TQColorGroupPrivate;
+ br = d->br;
+ br[Foreground] = TQBrush(foreground);
+ br[Button] = TQBrush(background);
+ br[Light] = TQBrush(light);
+ br[Dark] = TQBrush(dark);
+ br[Mid] = TQBrush(mid);
+ br[Text] = TQBrush(text);
+ br[BrightText] = br[Light];
+ br[ButtonText] = br[Text];
+ br[Base] = TQBrush(base);
+ br[Background] = TQBrush(background);
+ br[Midlight] = qt_mix_colors( br[Button].color(), br[Light].color() );
+ br[Shadow] = TQt::black;
+ br[Highlight] = TQt::darkBlue;
+ br[HighlightedText] = TQt::white;
+ br[Link] = TQt::blue;
+ br[LinkVisited] = TQt::magenta;
+}
+
+/*!
+ Destroys the color group.
+*/
+
+TQColorGroup::~TQColorGroup()
+{
+ if ( d->deref() )
+ delete d;
+}
+
+/*!
+ Returns the color that has been set for color role \a r.
+
+ \sa brush() ColorRole
+ */
+const TQColor &TQColorGroup::color( ColorRole r ) const
+{
+ return br[r].color();
+}
+
+/*!
+ Returns the brush that has been set for color role \a r.
+
+ \sa color() setBrush() ColorRole
+*/
+const TQBrush &TQColorGroup::brush( ColorRole r ) const
+{
+ return br[r];
+}
+
+/*!
+ Sets the brush used for color role \a r to a solid color \a c.
+
+ \sa brush() setColor() ColorRole
+*/
+void TQColorGroup::setColor( ColorRole r, const TQColor &c )
+{
+ setBrush( r, TQBrush(c) );
+}
+
+/*!
+ Sets the brush used for color role \a r to \a b.
+
+ \sa brush() setColor() ColorRole
+*/
+void TQColorGroup::setBrush( ColorRole r, const TQBrush &b )
+{
+ d = d->detach();
+ br = d->br;
+ br[r] = b;
+}
+
+
+/*!
+ \fn const TQColor & TQColorGroup::foreground() const
+
+ Returns the foreground color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::button() const
+
+ Returns the button color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::light() const
+
+ Returns the light color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor& TQColorGroup::midlight() const
+
+ Returns the midlight color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::dark() const
+
+ Returns the dark color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::mid() const
+
+ Returns the mid color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::text() const
+
+ Returns the text foreground color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::brightText() const
+
+ Returns the bright text foreground color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::buttonText() const
+
+ Returns the button text foreground color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::base() const
+
+ Returns the base color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::background() const
+
+ Returns the background color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::shadow() const
+
+ Returns the shadow color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::highlight() const
+
+ Returns the highlight color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::highlightedText() const
+
+ Returns the highlighted text color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::link() const
+
+ Returns the unvisited link text color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn const TQColor & TQColorGroup::linkVisited() const
+
+ Returns the visited link text color of the color group.
+
+ \sa ColorRole
+*/
+
+/*!
+ \fn bool TQColorGroup::operator!=( const TQColorGroup &g ) const
+
+ Returns TRUE if this color group is different from \a g; otherwise
+ returns FALSE.
+
+ \sa operator!=()
+*/
+
+/*!
+ Returns TRUE if this color group is equal to \a g; otherwise
+ returns FALSE.
+
+ \sa operator==()
+*/
+
+bool TQColorGroup::operator==( const TQColorGroup &g ) const
+{
+ if ( d == g.d )
+ return TRUE;
+ for( int r = 0 ; r < NColorRoles ; r++ )
+ if ( br[r] != g.br[r] )
+ return FALSE;
+ return TRUE;
+}
+
+/*****************************************************************************
+ TQPalette member functions
+ *****************************************************************************/
+
+/*!
+ \class TQPalette tqpalette.h
+
+ \brief The TQPalette class tqcontains color groups for each widget state.
+
+ \ingroup appearance
+ \ingroup shared
+ \ingroup graphics
+ \ingroup images
+ \mainclass
+
+ A palette consists of three color groups: \e active, \e disabled,
+ and \e inactive. All widgets contain a palette, and all widgets in
+ TQt use their palette to draw themselves. This makes the user
+ interface easily configurable and easier to keep consistent.
+
+ If you create a new widget we strongly recommend that you use the
+ colors in the palette rather than hard-coding specific colors.
+
+ The color groups:
+ \list
+ \i The active() group is used for the window that has keyboard focus.
+ \i The inactive() group is used for other windows.
+ \i The disabled() group is used for widgets (not windows) that are
+ disabled for some reason.
+ \endlist
+
+ Both active and inactive windows can contain disabled widgets.
+ (Disabled widgets are often called \e inaccessible or \e{grayed
+ out}.)
+
+ In Motif style, active() and inactive() look the same. In Windows
+ 2000 style and Macintosh Platinum style, the two styles look
+ slightly different.
+
+ There are setActive(), setInactive(), and setDisabled() functions
+ to modify the palette. (TQt also supports a normal() group; this is
+ an obsolete alias for active(), supported for backwards
+ compatibility.)
+
+ Colors and brushes can be set for particular roles in any of a
+ palette's color groups with setColor() and setBrush().
+
+ You can copy a palette using the copy constructor and test to see
+ if two palettes are \e identical using isCopyOf().
+
+ \sa TQApplication::setPalette(), TQWidget::setPalette(), TQColorGroup, TQColor
+*/
+
+/*!
+ \enum TQPalette::ColorGroup
+
+ \value Disabled
+ \value Active
+ \value Inactive
+ \value NColorGroups
+ \value Normal synonym for Active
+*/
+
+/*!
+ \obsolete
+
+ \fn const TQColorGroup &TQPalette::normal() const
+
+ Returns the active color group. Use active() instead.
+
+ \sa setActive() active()
+*/
+
+/*!
+ \obsolete
+
+ \fn void TQPalette::setNormal( const TQColorGroup & cg )
+
+ Sets the active color group to \a cg. Use setActive() instead.
+
+ \sa setActive() active()
+*/
+
+
+static int palette_count = 1;
+
+/*!
+ Constructs a palette that consists of color groups with only black
+ colors.
+*/
+
+TQPalette::TQPalette()
+{
+ static TQPalData *defPalData = 0;
+ if ( !defPalData ) { // create common palette data
+ defPalData = new TQPalData; // for the default palette
+ static TQSharedCleanupHandler<TQPalData> defPalCleanup;
+ defPalCleanup.set( &defPalData );
+ defPalData->ser_no = palette_count++;
+ }
+ data = defPalData;
+ data->ref();
+}
+
+/*!\obsolete
+ Constructs a palette from the \a button color. The other colors are
+ automatically calculated, based on this color. Background will be
+ the button color as well.
+*/
+
+TQPalette::TQPalette( const TQColor &button )
+{
+ data = new TQPalData;
+ TQ_CHECK_PTR( data );
+ data->ser_no = palette_count++;
+ TQColor bg = button, btn = button, fg, base, disfg;
+ int h, s, v;
+ bg.hsv( &h, &s, &v );
+ if ( v > 128 ) { // light background
+ fg = TQt::black;
+ base = TQt::white;
+ disfg = TQt::darkGray;
+ } else { // dark background
+ fg = TQt::white;
+ base = TQt::black;
+ disfg = TQt::darkGray;
+ }
+ data->active = TQColorGroup( fg, btn, btn.light(150), btn.dark(),
+ btn.dark(150), fg, TQt::white, base, bg );
+ data->disabled = TQColorGroup( disfg, btn, btn.light(150), btn.dark(),
+ btn.dark(150), disfg, TQt::white, base, bg );
+ data->inactive = data->active;
+}
+
+/*!
+ Constructs a palette from a \a button color and a \a background.
+ The other colors are automatically calculated, based on these
+ colors.
+*/
+
+TQPalette::TQPalette( const TQColor &button, const TQColor &background )
+{
+ data = new TQPalData;
+ TQ_CHECK_PTR( data );
+ data->ser_no = palette_count++;
+ TQColor bg = background, btn = button, fg, base, disfg;
+ int h, s, v;
+ bg.hsv( &h, &s, &v );
+ if ( v > 128 ) { // light background
+ fg = TQt::black;
+ base = TQt::white;
+ disfg = TQt::darkGray;
+ } else { // dark background
+ fg = TQt::white;
+ base = TQt::black;
+ disfg = TQt::darkGray;
+ }
+ data->active = TQColorGroup( fg, btn, btn.light(150), btn.dark(),
+ btn.dark(150), fg, TQt::white, base, bg );
+ data->disabled = TQColorGroup( disfg, btn, btn.light(150), btn.dark(),
+ btn.dark(150), disfg, TQt::white, base, bg );
+ data->inactive = data->active;
+}
+
+/*!
+ Constructs a palette that consists of the three color groups \a
+ active, \a disabled and \a inactive. See the \link #details
+ Detailed Description\endlink for definitions of the color groups
+ and \l TQColorGroup::ColorRole for definitions of each color role
+ in the three groups.
+
+ \sa TQColorGroup TQColorGroup::ColorRole TQPalette
+*/
+
+TQPalette::TQPalette( const TQColorGroup &active, const TQColorGroup &disabled,
+ const TQColorGroup &inactive )
+{
+ data = new TQPalData;
+ TQ_CHECK_PTR( data );
+ data->ser_no = palette_count++;
+ data->active = active;
+ data->disabled = disabled;
+ data->inactive = inactive;
+}
+
+/*!
+ Constructs a copy of \a p.
+
+ This constructor is fast (it uses copy-on-write).
+*/
+
+TQPalette::TQPalette( const TQPalette &p )
+{
+ data = p.data;
+ data->ref();
+}
+
+/*!
+ Destroys the palette.
+*/
+
+TQPalette::~TQPalette()
+{
+ if ( data->deref() )
+ delete data;
+}
+
+/*!
+ Assigns \a p to this palette and returns a reference to this
+ palette.
+
+ This is fast (it uses copy-on-write).
+
+ \sa copy()
+*/
+
+TQPalette &TQPalette::operator=( const TQPalette &p )
+{
+ p.data->ref();
+ if ( data->deref() )
+ delete data;
+ data = p.data;
+ return *this;
+}
+
+
+/*!
+ Returns the color in color group \a gr, used for color role \a r.
+
+ \sa brush() setColor() TQColorGroup::ColorRole
+*/
+const TQColor &TQPalette::color( ColorGroup gr, TQColorGroup::ColorRole r ) const
+{
+ return directBrush( gr, r ).color();
+}
+
+/*!
+ Returns the brush in color group \a gr, used for color role \a r.
+
+ \sa color() setBrush() TQColorGroup::ColorRole
+*/
+const TQBrush &TQPalette::brush( ColorGroup gr, TQColorGroup::ColorRole r ) const
+{
+ return directBrush( gr, r );
+}
+
+/*!
+ Sets the brush in color group \a gr, used for color role \a r, to
+ the solid color \a c.
+
+ \sa setBrush() color() TQColorGroup::ColorRole
+*/
+void TQPalette::setColor( ColorGroup gr, TQColorGroup::ColorRole r,
+ const TQColor &c)
+{
+ setBrush( gr, r, TQBrush(c) );
+}
+
+/*!
+ Sets the brush in color group \a gr, used for color role \a r, to
+ \a b.
+
+ \sa brush() setColor() TQColorGroup::ColorRole
+*/
+void TQPalette::setBrush( ColorGroup gr, TQColorGroup::ColorRole r,
+ const TQBrush &b)
+{
+ detach();
+ data->ser_no = palette_count++;
+ directSetBrush( gr, r, b);
+}
+
+/*!
+ \overload
+
+ Sets the brush color used for color role \a r to color \a c in all
+ three color groups.
+
+ \sa color() setBrush() TQColorGroup::ColorRole
+*/
+void TQPalette::setColor( TQColorGroup::ColorRole r, const TQColor &c )
+{
+ setBrush( r, TQBrush(c) );
+}
+
+/*!
+ \overload
+
+ Sets the brush in for color role \a r in all three color groups to
+ \a b.
+
+ \sa brush() setColor() TQColorGroup::ColorRole active() inactive() disabled()
+*/
+void TQPalette::setBrush( TQColorGroup::ColorRole r, const TQBrush &b )
+{
+ detach();
+ data->ser_no = palette_count++;
+ directSetBrush( Active, r, b );
+ directSetBrush( Disabled, r, b );
+ directSetBrush( Inactive, r, b );
+}
+
+
+/*!
+ Returns a deep copy of this palette.
+
+ \warning This is slower than the copy constructor and assignment
+ operator and offers no benefits.
+*/
+
+TQPalette TQPalette::copy() const
+{
+ TQPalette p( data->active, data->disabled, data->inactive );
+ return p;
+}
+
+
+/*!
+ Detaches this palette from any other TQPalette objects with which
+ it might implicitly share TQColorGroup objects. In essence, does
+ the copying part of copy-on-write.
+
+ Calling this should generally not be necessary; TQPalette calls it
+ itself when necessary.
+*/
+
+void TQPalette::detach()
+{
+ if ( data->count != 1 )
+ *this = copy();
+}
+
+/*!
+ \fn const TQColorGroup & TQPalette::disabled() const
+
+ Returns the disabled color group of this palette.
+
+ \sa TQColorGroup, setDisabled(), active(), inactive()
+*/
+
+/*!
+ Sets the \c Disabled color group to \a g.
+
+ \sa disabled() setActive() setInactive()
+*/
+
+void TQPalette::setDisabled( const TQColorGroup &g )
+{
+ detach();
+ data->ser_no = palette_count++;
+ data->disabled = g;
+}
+
+/*!
+ \fn const TQColorGroup & TQPalette::active() const
+
+ Returns the active color group of this palette.
+
+ \sa TQColorGroup, setActive(), inactive(), disabled()
+*/
+
+/*!
+ Sets the \c Active color group to \a g.
+
+ \sa active() setDisabled() setInactive() TQColorGroup
+*/
+
+void TQPalette::setActive( const TQColorGroup &g )
+{
+ detach();
+ data->ser_no = palette_count++;
+ data->active = g;
+}
+
+/*!
+ \fn const TQColorGroup & TQPalette::inactive() const
+
+ Returns the inactive color group of this palette.
+
+ \sa TQColorGroup, setInactive(), active(), disabled()
+*/
+
+/*!
+ Sets the \c Inactive color group to \a g.
+
+ \sa active() setDisabled() setActive() TQColorGroup
+*/
+
+void TQPalette::setInactive( const TQColorGroup &g )
+{
+ detach();
+ data->ser_no = palette_count++;
+ data->inactive = g;
+}
+
+
+/*!
+ \fn bool TQPalette::operator!=( const TQPalette &p ) const
+
+ Returns TRUE (slowly) if this palette is different from \a p;
+ otherwise returns FALSE (usually quickly).
+*/
+
+/*!
+ Returns TRUE (usually quickly) if this palette is equal to \a p;
+ otherwise returns FALSE (slowly).
+*/
+
+bool TQPalette::operator==( const TQPalette &p ) const
+{
+ return data->active == p.data->active &&
+ data->disabled == p.data->disabled &&
+ data->inactive == p.data->inactive;
+}
+
+
+/*!
+ \fn int TQPalette::serialNumber() const
+
+ Returns a number that uniquely identifies this TQPalette object.
+ The serial number is intended for caching. Its value may not be
+ used for anything other than equality testing.
+
+ Note that TQPalette uses copy-on-write, and the serial number
+ changes during the lazy copy operation (detach()), not during a
+ shallow copy (copy constructor or assignment).
+
+ \sa TQPixmap TQPixmapCache TQCache
+*/
+
+
+/*****************************************************************************
+ TQColorGroup/TQPalette stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQColorGroup
+
+ Writes color group, \a g to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQColorGroup &g )
+{
+ if ( s.version() == 1 ) {
+ // TQt 1.x
+ s << g.foreground()
+ << g.background()
+ << g.light()
+ << g.dark()
+ << g.mid()
+ << g.text()
+ << g.base();
+ } else {
+ int max = TQColorGroup::NColorRoles;
+ if ( s.version() <= 3) // TQt 2.x
+ max = 14;
+
+ for( int r = 0 ; r < max ; r++ )
+ s << g.brush( (TQColorGroup::ColorRole)r);
+ }
+ return s;
+}
+
+/*!
+ \related TQColorGroup
+
+ Reads a color group from the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQColorGroup &g )
+{
+ if ( s.version() == 1 ) {
+ // TQt 1.x
+ TQColor fg, bg, light, dark, mid, text, base;
+ s >> fg >> bg >> light >> dark >> mid >> text >> base;
+ TQPalette p( bg );
+ TQColorGroup n( p.active() );
+ n.setColor( TQColorGroup::Foreground, fg );
+ n.setColor( TQColorGroup::Light, light );
+ n.setColor( TQColorGroup::Dark, dark );
+ n.setColor( TQColorGroup::Mid, mid );
+ n.setColor( TQColorGroup::Text, text );
+ n.setColor( TQColorGroup::Base, base );
+ g = n;
+ } else {
+ int max = TQColorGroup::NColorRoles;
+ if (s.version() <= 3) // TQt 2.x
+ max = 14;
+
+ TQBrush tmp;
+ for( int r = 0 ; r < max; r++ ) {
+ s >> tmp;
+ g.setBrush( (TQColorGroup::ColorRole)r, tmp);
+ }
+ }
+ return s;
+}
+
+
+/*!
+ \relates TQPalette
+
+ Writes the palette, \a p to the stream \a s and returns a
+ reference to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQPalette &p )
+{
+ return s << p.active()
+ << p.disabled()
+ << p.inactive();
+}
+
+
+static void readV1ColorGroup( TQDataStream &s, TQColorGroup &g,
+ TQPalette::ColorGroup r )
+{
+ TQColor fg, bg, light, dark, mid, text, base;
+ s >> fg >> bg >> light >> dark >> mid >> text >> base;
+ TQPalette p( bg );
+ TQColorGroup n;
+ switch ( r ) {
+ case TQPalette::Disabled:
+ n = p.disabled();
+ break;
+ case TQPalette::Inactive:
+ n = p.inactive();
+ break;
+ default:
+ n = p.active();
+ break;
+ }
+ n.setColor( TQColorGroup::Foreground, fg );
+ n.setColor( TQColorGroup::Light, light );
+ n.setColor( TQColorGroup::Dark, dark );
+ n.setColor( TQColorGroup::Mid, mid );
+ n.setColor( TQColorGroup::Text, text );
+ n.setColor( TQColorGroup::Base, base );
+ g = n;
+}
+
+
+/*!
+ \relates TQPalette
+
+ Reads a palette from the stream, \a s into the palette \a p, and
+ returns a reference to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQPalette &p )
+{
+ TQColorGroup active, disabled, inactive;
+ if ( s.version() == 1 ) {
+ readV1ColorGroup( s, active, TQPalette::Active );
+ readV1ColorGroup( s, disabled, TQPalette::Disabled );
+ readV1ColorGroup( s, inactive, TQPalette::Inactive );
+ } else {
+ s >> active >> disabled >> inactive;
+ }
+ TQPalette newpal( active, disabled, inactive );
+ p = newpal;
+ return s;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*!
+ Returns TRUE if this palette and \a p are copies of each other,
+ i.e. one of them was created as a copy of the other and neither
+ was subsequently modified; otherwise returns FALSE. This is much
+ stricter than equality.
+
+ \sa operator=() operator==()
+*/
+
+bool TQPalette::isCopyOf( const TQPalette & p )
+{
+ return data && data == p.data;
+}
+
+const TQBrush &TQPalette::directBrush( ColorGroup gr, TQColorGroup::ColorRole r ) const
+{
+ if ( (uint)gr > (uint)TQPalette::NColorGroups ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPalette::directBrush: tqcolorGroup(%i) out of range", gr );
+#endif
+ return data->active.br[TQColorGroup::Foreground];
+ }
+ if ( (uint)r >= (uint)TQColorGroup::NColorRoles ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPalette::directBrush: colorRole(%i) out of range", r );
+#endif
+ return data->active.br[TQColorGroup::Foreground];
+ }
+ switch( gr ) {
+ case Active:
+ return data->active.br[r];
+ //break;
+ case Disabled:
+ return data->disabled.br[r];
+ //break;
+ case Inactive:
+ return data->inactive.br[r];
+ //break;
+ default:
+ break;
+ }
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPalette::directBrush: tqcolorGroup(%i) internal error", gr );
+#endif
+ return data->active.br[TQColorGroup::Foreground]; // Satisfy compiler
+}
+
+void TQPalette::directSetBrush( ColorGroup gr, TQColorGroup::ColorRole r, const TQBrush& b)
+{
+ if ( (uint)gr > (uint)TQPalette::NColorGroups ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPalette::directBrush: tqcolorGroup(%i) out of range", gr );
+#endif
+ return;
+ }
+ if ( (uint)r >= (uint)TQColorGroup::NColorRoles ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPalette::directBrush: colorRole(%i) out of range", r );
+#endif
+ return;
+ }
+ switch( gr ) {
+ case Active:
+ data->active.setBrush(r,b);
+ break;
+ case Disabled:
+ data->disabled.setBrush(r,b);
+ break;
+ case Inactive:
+ data->inactive.setBrush(r,b);
+ break;
+ default:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPalette::directBrush: tqcolorGroup(%i) internal error", gr );
+#endif
+ break;
+ }
+}
+
+
+/*!\internal*/
+TQColorGroup::ColorRole TQPalette::foregroundRoleFromMode( TQt::BackgroundMode mode )
+{
+ switch (mode) {
+ case TQt::PaletteButton:
+ return TQColorGroup::ButtonText;
+ case TQt::PaletteBase:
+ return TQColorGroup::Text;
+ case TQt::PaletteDark:
+ case TQt::PaletteShadow:
+ return TQColorGroup::Light;
+ case TQt::PaletteHighlight:
+ return TQColorGroup::HighlightedText;
+ case TQt::PaletteBackground:
+ default:
+ return TQColorGroup::Foreground;
+ }
+}
+
+/*!\internal*/
+TQColorGroup::ColorRole TQPalette::backgroundRoleFromMode( TQt::BackgroundMode mode)
+{
+ switch (mode) {
+ case TQt::PaletteForeground:
+ return TQColorGroup::Foreground;
+ case TQt::PaletteButton:
+ return TQColorGroup::Button;
+ case TQt::PaletteLight:
+ return TQColorGroup::Light;
+ case TQt::PaletteMidlight:
+ return TQColorGroup::Midlight;
+ case TQt::PaletteDark:
+ return TQColorGroup::Dark;
+ case TQt::PaletteMid:
+ return TQColorGroup::Mid;
+ case TQt::PaletteText:
+ return TQColorGroup::Text;
+ case TQt::PaletteBrightText:
+ return TQColorGroup::BrightText;
+ case TQt::PaletteButtonText:
+ return TQColorGroup::ButtonText;
+ case TQt::PaletteBase:
+ return TQColorGroup::Base;
+ case TQt::PaletteShadow:
+ return TQColorGroup::Shadow;
+ case TQt::PaletteHighlight:
+ return TQColorGroup::Highlight;
+ case TQt::PaletteHighlightedText:
+ return TQColorGroup::HighlightedText;
+ case TQt::PaletteLink:
+ return TQColorGroup::Link;
+ case TQt::PaletteLinkVisited:
+ return TQColorGroup::LinkVisited;
+ case TQt::PaletteBackground:
+ default:
+ return TQColorGroup::Background;
+ }
+}
+
+#endif // USE_QT4
+
+#endif // TQT_NO_PALETTE \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqpalette.h b/tqtinterface/qt4/src/kernel/tqpalette.h
new file mode 100644
index 0000000..19bf08a
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpalette.h
@@ -0,0 +1,295 @@
+/****************************************************************************
+**
+** Definition of TQColorGroup and TQPalette classes
+**
+** Created : 950323
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPALETTE_H
+#define TQPALETTE_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqcolor.h"
+#include "tqshared.h"
+#include "tqbrush.h" // TQColor->TQBrush conversion
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qpalette.h>
+
+#endif // USE_QT4
+
+#ifndef TQT_NO_PALETTE
+
+#ifdef USE_QT4
+
+class Q_GUI_EXPORT TQPalette : public QPalette, virtual public TQt
+{
+public:
+ TQPalette() : QPalette() {}
+ TQPalette( const QColor &button ) : QPalette( button ) {}
+ TQPalette( const QColor &button, const QColor &background ) : QPalette( button, background ) {}
+ TQPalette( const TQColorGroup &active, const TQColorGroup &disabled, const TQColorGroup &inactive );
+ TQPalette( const QPalette &pa ) : QPalette( pa ) {}
+ TQPalette(const QBrush &windowText, const QBrush &button, const QBrush &light, const QBrush &dark, const QBrush &mid, const QBrush &text, const QBrush &bright_text, const QBrush &base, const QBrush &window) : QPalette( windowText, button, light, dark, mid, text, bright_text, base, window ) {}
+ TQPalette(const QColor &windowText, const QColor &window, const QColor &light, const QColor &dark, const QColor &mid, const QColor &text, const QColor &base) : QPalette( windowText, window, light, dark, mid, text, base ) {}
+
+ TQColorGroup normal() const;
+ inline void setNormal(const TQColorGroup &cg) { tqsetColorGroup(Active, cg); }
+
+ TQColorGroup active() const;
+ TQColorGroup disabled() const;
+ TQColorGroup inactive() const;
+// inline void setActive(const TQColorGroup &cg) { tqsetColorGroup(Active, cg); }
+// inline void setDisabled(const TQColorGroup &cg) { tqsetColorGroup(Disabled, cg); }
+// inline void setInactive(const TQColorGroup &cg) { tqsetColorGroup(Inactive, cg); }
+
+ static ColorRole foregroundRoleFromMode( TQt::BackgroundMode mode );
+ static ColorRole backgroundRoleFromMode( TQt::BackgroundMode mode );
+
+// inline QPalette copy() const { QPalette p = *this; p.detach(); return p; }
+
+ inline void setActive(const TQColorGroup &cg) { tqsetColorGroup(Active, cg); }
+ inline void setDisabled(const TQColorGroup &cg) { tqsetColorGroup(Disabled, cg); }
+ inline void setInactive(const TQColorGroup &cg) { tqsetColorGroup(Inactive, cg); }
+
+private:
+ friend class TQColorGroup;
+ void tqsetColorGroup(ColorGroup, const TQColorGroup &);
+ TQColorGroup createColorGroup(ColorGroup) const;
+
+public:
+ // Interoperability
+ static const TQPalette& convertFromQPaletteh( QPalette& qp );
+};
+
+// Interoperability
+inline static const TQPalette& convertFromQPalette( const QPalette& qp ) {
+ return (*static_cast<const TQPalette*>(&qp));
+}
+
+class Q_GUI_EXPORT TQColorGroup : public TQPalette
+{
+public:
+ inline TQColorGroup() : TQPalette() {}
+ inline TQColorGroup(const QBrush &foreground, const QBrush &button, const QBrush &light,
+ const QBrush &dark, const QBrush &mid, const QBrush &text,
+ const QBrush &bright_text, const QBrush &base, const QBrush &background)
+ : TQPalette(foreground, button, light, dark, mid, text, bright_text, base, background)
+ {}
+ inline TQColorGroup(const QColor &foreground, const QColor &background, const QColor &light,
+ const QColor &dark, const QColor &mid, const QColor &text, const QColor &base)
+ : TQPalette(foreground, background, light, dark, mid, text, base) {}
+ inline TQColorGroup(const TQColorGroup &cg) : TQPalette(cg) {}
+ inline TQColorGroup(const QPalette &pal) : TQPalette(pal) {}
+ bool operator==(const TQColorGroup &other) const;
+ inline bool operator!=(const TQColorGroup &other) const { return !(operator==(other)); }
+// operator QVariant() const;
+
+ inline const TQColor &foreground() const { return TQT_TQCOLOR_OBJECT(color(WindowText)); }
+ inline const TQColor &button() const { return TQT_TQCOLOR_OBJECT(color(Button)); }
+ inline const TQColor &light() const { return TQT_TQCOLOR_OBJECT(color(Light)); }
+ inline const TQColor &dark() const { return TQT_TQCOLOR_OBJECT(color(Dark)); }
+ inline const TQColor &mid() const { return TQT_TQCOLOR_OBJECT(color(Mid)); }
+ inline const TQColor &text() const { return TQT_TQCOLOR_OBJECT(color(Text)); }
+ inline const TQColor &base() const { return TQT_TQCOLOR_OBJECT(color(Base)); }
+ inline const TQColor &background() const { return TQT_TQCOLOR_OBJECT(color(Window)); }
+ inline const TQColor &midlight() const { return TQT_TQCOLOR_OBJECT(color(Midlight)); }
+ inline const TQColor &brightText() const { return TQT_TQCOLOR_OBJECT(color(BrightText)); }
+ inline const TQColor &buttonText() const { return TQT_TQCOLOR_OBJECT(color(ButtonText)); }
+ inline const TQColor &shadow() const { return TQT_TQCOLOR_OBJECT(color(Shadow)); }
+ inline const TQColor &highlight() const { return TQT_TQCOLOR_OBJECT(color(Highlight)); }
+ inline const TQColor &highlightedText() const { return TQT_TQCOLOR_OBJECT(color(HighlightedText)); }
+ inline const TQColor &link() const { return TQT_TQCOLOR_OBJECT(color(Link)); }
+ inline const TQColor &linkVisited() const { return TQT_TQCOLOR_OBJECT(color(LinkVisited)); }
+
+ inline const TQBrush &tqbrush( ColorRole cr ) const { return TQT_TQBRUSH_OBJECT(TQPalette::brush(cr)); }
+};
+
+// #ifndef QT_NO_DATASTREAM
+// QDataStream &operator<<(QDataStream &ds, const TQColorGroup &cg);
+// QDataStream &operator>>(QDataStream &ds, TQColorGroup &cg);
+// #endif
+
+inline TQColorGroup TQPalette::inactive() const { return createColorGroup(Inactive); }
+inline TQColorGroup TQPalette::disabled() const { return createColorGroup(Disabled); }
+inline TQColorGroup TQPalette::active() const { return createColorGroup(Active); }
+inline TQColorGroup TQPalette::normal() const { return createColorGroup(Active); }
+
+#else // USE_QT4
+
+class TQColorGroupPrivate;
+
+class TQ_EXPORT TQColorGroup
+{
+public:
+ TQColorGroup();
+ TQColorGroup( const TQColor &foreground, const TQColor &button,
+ const TQColor &light, const TQColor &dark, const TQColor &mid,
+ const TQColor &text, const TQColor &base );
+ TQColorGroup( const TQBrush &foreground, const TQBrush &button,
+ const TQBrush &light, const TQBrush &dark, const TQBrush &mid,
+ const TQBrush &text, const TQBrush &bright_text,
+ const TQBrush &base, const TQBrush &background);
+ TQColorGroup( const TQColorGroup & );
+
+ ~TQColorGroup();
+
+ TQColorGroup& operator =(const TQColorGroup&);
+
+ // Do not change the order, the serialization format depends on it
+ enum ColorRole { Foreground, Button, Light, Midlight, Dark, Mid,
+ Text, BrightText, ButtonText, Base, Background, Shadow,
+ Highlight, HighlightedText, Link, LinkVisited,
+ NColorRoles };
+
+ const TQColor &color( ColorRole ) const;
+ const TQBrush &brush( ColorRole ) const;
+ void setColor( ColorRole, const TQColor & );
+ void setBrush( ColorRole, const TQBrush & );
+
+ const TQColor &foreground() const { return br[Foreground].color(); }
+ const TQColor &button() const { return br[Button].color(); }
+ const TQColor &light() const { return br[Light].color(); }
+ const TQColor &dark() const { return br[Dark].color(); }
+ const TQColor &mid() const { return br[Mid].color(); }
+ const TQColor &text() const { return br[Text].color(); }
+ const TQColor &base() const { return br[Base].color(); }
+ const TQColor &background() const { return br[Background].color(); }
+
+ const TQColor &midlight() const { return br[Midlight].color(); }
+ const TQColor &brightText() const { return br[BrightText].color(); }
+ const TQColor &buttonText() const { return br[ButtonText].color(); }
+ const TQColor &shadow() const { return br[Shadow].color(); }
+ const TQColor &highlight() const { return br[Highlight].color(); }
+ const TQColor &highlightedText() const{return br[HighlightedText].color(); }
+ const TQColor &link() const { return br[Link].color(); }
+ const TQColor &linkVisited() const { return br[LinkVisited].color(); }
+
+ bool operator==( const TQColorGroup &g ) const;
+ bool operator!=( const TQColorGroup &g ) const
+ { return !(operator==(g)); }
+
+private:
+ TQBrush *br;
+ TQColorGroupPrivate * d;
+
+ friend class TQPalette;
+};
+
+
+class TQ_EXPORT TQPalette
+{
+public:
+ TQPalette();
+ TQPalette( const TQColor &button );
+ TQPalette( const TQColor &button, const TQColor &background );
+ TQPalette( const TQColorGroup &active, const TQColorGroup &disabled,
+ const TQColorGroup &inactive );
+ TQPalette( const TQPalette & );
+ ~TQPalette();
+ TQPalette &operator=( const TQPalette & );
+
+ enum ColorGroup { Disabled, Active, Inactive, NColorGroups, Normal=Active };
+
+ const TQColor &color( ColorGroup, TQColorGroup::ColorRole ) const;
+ const TQBrush &brush( ColorGroup, TQColorGroup::ColorRole ) const;
+ void setColor( ColorGroup, TQColorGroup::ColorRole, const TQColor & );
+ void setBrush( ColorGroup, TQColorGroup::ColorRole, const TQBrush & );
+
+ void setColor( TQColorGroup::ColorRole, const TQColor & );
+ void setBrush( TQColorGroup::ColorRole, const TQBrush & );
+
+ TQPalette copy() const;
+
+ const TQColorGroup &active() const { return data->active; }
+ const TQColorGroup &disabled() const { return data->disabled; }
+ const TQColorGroup &inactive() const { return data->inactive; }
+#ifndef TQT_NO_COMPAT
+ const TQColorGroup &normal() const { return active(); }
+#endif
+
+ void setActive( const TQColorGroup & );
+ void setDisabled( const TQColorGroup & );
+ void setInactive( const TQColorGroup & );
+#ifndef TQT_NO_COMPAT
+ void setNormal( const TQColorGroup & cg ) { setActive(cg); }
+#endif
+
+ bool operator==( const TQPalette &p ) const;
+ bool operator!=( const TQPalette &p ) const
+ { return !(operator==(p)); }
+ bool isCopyOf( const TQPalette & );
+
+ int serialNumber() const { return data->ser_no; }
+
+
+ static TQColorGroup::ColorRole foregroundRoleFromMode( TQt::BackgroundMode mode );
+ static TQColorGroup::ColorRole backgroundRoleFromMode( TQt::BackgroundMode mode);
+
+private:
+ void detach();
+ const TQBrush &directBrush( ColorGroup, TQColorGroup::ColorRole ) const;
+ void directSetBrush( ColorGroup, TQColorGroup::ColorRole, const TQBrush& );
+
+ struct TQPalData : public TQShared {
+ TQColorGroup disabled;
+ TQColorGroup active;
+ int ser_no;
+ TQColorGroup inactive;
+ } *data;
+};
+
+
+/*****************************************************************************
+ TQColorGroup/TQPalette stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQColorGroup & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQColorGroup & );
+
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPalette & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPalette & );
+#endif // TQT_NO_DATASTREAM
+
+#endif // TQT_NO_PALETTE
+#endif // USE_QT4
+#endif // TQPALETTE_H
diff --git a/tqtinterface/qt4/src/kernel/tqpen.h b/tqtinterface/qt4/src/kernel/tqpen.h
new file mode 100644
index 0000000..c6d4d75
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpen.h
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Definition of TQPen class
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPEN_H
+#define TQPEN_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqcolor.h"
+#include "tqshared.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qpen.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQPen: public QPen, virtual public TQt
+{
+public:
+ TQPen() : QPen() {}
+ TQPen( Qt::PenStyle ps ) : QPen( ps ) {}
+ TQPen( const QColor &color, uint width=0, Qt::PenStyle style=Qt::SolidLine ) : QPen( color, width, style ) {}
+ TQPen( const QColor &color, uint width, TQt::PenStyle style ) : QPen( color, width, (Qt::PenStyle)style ) {}
+ TQPen( const QColor &cl, uint w, Qt::PenStyle s, Qt::PenCapStyle c, Qt::PenJoinStyle j) : QPen( cl, w, s, c, j ) {}
+ TQPen( const QPen &p ) : QPen( p ) {}
+
+ inline void tqsetStyle( TQt::PenStyle tqps ) { setStyle((Qt::PenStyle)tqps); }
+ inline void tqsetCapStyle( TQt::PenCapStyle tqps ) { setCapStyle((Qt::PenCapStyle)tqps); }
+ inline void tqsetJoinStyle( TQt::PenJoinStyle tqps ) { setJoinStyle((Qt::PenJoinStyle)tqps); }
+
+ using QPen::operator=;
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQPen: public TQt
+{
+public:
+ TQPen();
+ TQPen( PenStyle );
+ TQPen( const TQColor &color, uint width=0, PenStyle style=SolidLine );
+ TQPen( const TQColor &cl, uint w, PenStyle s, PenCapStyle c, PenJoinStyle j);
+ TQPen( const TQPen & );
+ ~TQPen();
+ TQPen &operator=( const TQPen & );
+
+ PenStyle style() const { return data->style; }
+ void setStyle( PenStyle );
+ uint width() const { return data->width; }
+ void setWidth( uint );
+ const TQColor &color() const { return data->color; }
+ void setColor( const TQColor & );
+ PenCapStyle capStyle() const;
+ void setCapStyle( PenCapStyle );
+ PenJoinStyle joinStyle() const;
+ void setJoinStyle( PenJoinStyle );
+
+ bool operator==( const TQPen &p ) const;
+ bool operator!=( const TQPen &p ) const
+ { return !(operator==(p)); }
+
+private:
+ friend class TQPainter;
+#ifdef TQ_WS_WIN
+ friend class TQFontEngineWin;
+#endif
+
+ TQPen copy() const;
+ void detach();
+ void init( const TQColor &, uint, uint );
+ struct TQPenData : public TQShared { // pen data
+ PenStyle style;
+ uint width;
+ TQColor color;
+ TQ_UINT16 linest;
+ } *data;
+};
+
+
+/*****************************************************************************
+ TQPen stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPen & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPen & );
+#endif
+
+#endif // USE_QT4
+
+#endif // TQPEN_H
diff --git a/tqtinterface/qt4/src/kernel/tqpicture.cpp b/tqtinterface/qt4/src/kernel/tqpicture.cpp
new file mode 100644
index 0000000..c9c5c0e
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpicture.cpp
@@ -0,0 +1,1235 @@
+/****************************************************************************
+**
+** Implementation of TQPicture class
+**
+** Created : 940802
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpicture.h"
+
+#ifndef TQT_NO_PICTURE
+
+#include "tqpainter.h"
+#include "tqpixmap.h"
+#include "tqimage.h"
+#include "tqfile.h"
+#include "tqdatastream.h"
+#include "tqpaintdevicemetrics.h"
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+#ifndef TQT_NO_SVG
+#include "private/tqsvgdevice_p.h"
+#endif
+
+/*!
+ \class TQPicture tqpicture.h
+ \brief The TQPicture class is a paint tqdevice that records and
+ replays TQPainter commands.
+
+ \ingroup graphics
+ \ingroup images
+ \ingroup shared
+
+ A picture serializes painter commands to an IO tqdevice in a
+ platform-independent format. For example, a picture created under
+ Windows can be read on a Sun SPARC.
+
+ Pictures are called meta-files on some platforms.
+
+ TQt pictures use a proprietary binary format. Unlike native picture
+ (meta-file) formats on many window systems, TQt pictures have no
+ limitations regarding their contents. Everything that can be
+ painted can also be stored in a picture, e.g. fonts, pixmaps,
+ regions, transformed graphics, etc.
+
+ TQPicture is an \link shclass.html implicitly shared\endlink class.
+
+ Example of how to record a picture:
+ \code
+ TQPicture pic;
+ TQPainter p;
+ p.begin( &pic ); // paint in picture
+ p.drawEllipse( 10,20, 80,70 ); // draw an ellipse
+ p.end(); // painting done
+ pic.save( "drawing.pic" ); // save picture
+ \endcode
+
+ Example of how to replay a picture:
+ \code
+ TQPicture pic;
+ pic.load( "drawing.pic" ); // load picture
+ TQPainter p;
+ p.begin( &myWidget ); // paint in myWidget
+ p.drawPicture( pic ); // draw the picture
+ p.end(); // painting done
+ \endcode
+
+ Pictures can also be drawn using play(). Some basic data about a
+ picture is available, for example, size(), isNull() and
+ boundingRect().
+
+*/
+
+
+static const char *mfhdr_tag = "TQPIC"; // header tag
+static const TQ_UINT16 mfhdr_maj = 5; // major version #
+static const TQ_UINT16 mfhdr_min = 0; // minor version #
+
+
+/*!
+ Constructs an empty picture.
+
+ The \a formatVersion parameter may be used to \e create a TQPicture
+ that can be read by applications that are compiled with earlier
+ versions of TQt.
+ \list
+ \i \a formatVersion == 1 is binary compatible with TQt 1.x and later.
+ \i \a formatVersion == 2 is binary compatible with TQt 2.0.x and later.
+ \i \a formatVersion == 3 is binary compatible with TQt 2.1.x and later.
+ \i \a formatVersion == 4 is binary compatible with TQt 3.0.x and later.
+ \i \a formatVersion == 5 is binary compatible with TQt 3.1.
+ \endlist
+
+ Note that the default formatVersion is -1 which signifies the
+ current release, i.e. for TQt 3.1 a formatVersion of 5 is the same
+ as the default formatVersion of -1.
+
+ Reading pictures generated by earlier versions of TQt is supported
+ and needs no special coding; the format is automatically detected.
+*/
+
+TQPicture::TQPicture( int formatVersion )
+ : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice )
+ // set tqdevice type
+{
+ d = new TQPicturePrivate;
+
+#if defined(TQT_CHECK_RANGE)
+ if ( formatVersion == 0 )
+ qWarning( "TQPicture: invalid format version 0" );
+#endif
+
+ // still accept the 0 default from before TQt 3.0.
+ if ( formatVersion > 0 && formatVersion != (int)mfhdr_maj ) {
+ d->formatMajor = formatVersion;
+ d->formatMinor = 0;
+ d->formatOk = FALSE;
+ }
+ else {
+ d->resetFormat();
+ }
+}
+
+/*!
+ Constructs a \link shclass.html shallow copy\endlink of \a pic.
+*/
+
+TQPicture::TQPicture( const TQPicture &pic )
+ : TQPaintDevice( TQInternal::Picture | TQInternal::ExternalDevice )
+{
+ d = pic.d;
+ d->ref();
+}
+
+/*!
+ Destroys the picture.
+*/
+TQPicture::~TQPicture()
+{
+ if ( d->deref() )
+ delete d;
+}
+
+
+/*!
+ \fn bool TQPicture::isNull() const
+
+ Returns TRUE if the picture tqcontains no data; otherwise returns
+ FALSE.
+*/
+
+/*!
+ \fn uint TQPicture::size() const
+
+ Returns the size of the picture data.
+
+ \sa data()
+*/
+
+/*!
+ \fn const char* TQPicture::data() const
+
+ Returns a pointer to the picture data. The pointer is only valid
+ until the next non-const function is called on this picture. The
+ returned pointer is 0 if the picture tqcontains no data.
+
+ \sa size(), isNull()
+*/
+
+/*!
+ Sets the picture data directly from \a data and \a size. This
+ function copies the input data.
+
+ \sa data(), size()
+*/
+
+void TQPicture::setData( const char* data, uint size )
+{
+ detach();
+ TQByteArray a( size );
+ memcpy( a.data(), data, size );
+ d->pictb.setBuffer( a ); // set byte array in buffer
+ d->resetFormat(); // we'll have to check
+}
+
+
+/*!
+ Loads a picture from the file specified by \a fileName and returns
+ TRUE if successful; otherwise returns FALSE.
+
+ By default, the file will be interpreted as being in the native
+ TQPicture format. Specifying the \a format string is optional and
+ is only needed for importing picture data stored in a different
+ format.
+
+ Currently, the only external format supported is the \link
+ http://www.w3.org/Graphics/SVG/ W3C SVG \endlink format which
+ requires the \link xml.html TQt XML module \endlink. The
+ corresponding \a format string is "svg".
+
+ \sa save()
+*/
+
+bool TQPicture::load( const TQString &fileName, const char *format )
+{
+ TQFile f( fileName );
+ if ( !f.open(IO_ReadOnly) )
+ return FALSE;
+ return load( &f, format );
+}
+
+/*!
+ \overload
+
+ \a dev is the tqdevice to use for loading.
+*/
+
+bool TQPicture::load( TQIODevice *dev, const char *format )
+{
+#ifndef TQT_NO_SVG
+ if ( qstrcmp( format, "svg" ) == 0 ) {
+ TQSvgDevice svg;
+ if ( !svg.load( dev ) )
+ return FALSE;
+ TQPainter p( this );
+ bool b = svg.play( &p );
+ d->brect = svg.boundingRect();
+ return b;
+ }
+#endif
+ if ( format ) {
+ qWarning( "TQPicture::load: No such picture format: %s", format );
+ return FALSE;
+ }
+
+ detach();
+ TQByteArray a = dev->readAll();
+ d->pictb.setBuffer( a ); // set byte array in buffer
+ return d->checkFormat();
+}
+
+/*!
+ Saves a picture to the file specified by \a fileName and returns
+ TRUE if successful; otherwise returns FALSE.
+
+ Specifying the file \a format string is optional. It's not
+ recommended unless you intend to export the picture data for
+ use by a third party reader. By default the data will be saved in
+ the native TQPicture file format.
+
+ Currently, the only external format supported is the \link
+ http://www.w3.org/Graphics/SVG/ W3C SVG \endlink format which
+ requires the \link xml.html TQt XML module \endlink. The
+ corresponding \a format string is "svg".
+
+ \sa load()
+*/
+
+bool TQPicture::save( const TQString &fileName, const char *format )
+{
+ if ( paintingActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPicture::save: still being painted on. "
+ "Call TQPainter::end() first" );
+#endif
+ return FALSE;
+ }
+
+#ifndef TQT_NO_SVG
+ // identical to TQIODevice* code below but the file name
+ // makes a difference when it comes to saving pixmaps
+ if ( qstricmp( format, "svg" ) == 0 ) {
+ TQSvgDevice svg;
+ TQPainter p( &svg );
+ if ( !play( &p ) )
+ return FALSE;
+ svg.setBoundingRect( boundingRect() );
+ return svg.save( fileName );
+ }
+#endif
+
+ TQFile f( fileName );
+ if ( !f.open(IO_WriteOnly) )
+ return FALSE;
+ return save( &f, format );
+}
+
+/*!
+ \overload
+
+ \a dev is the tqdevice to use for saving.
+*/
+
+bool TQPicture::save( TQIODevice *dev, const char *format )
+{
+ if ( paintingActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPicture::save: still being painted on. "
+ "Call TQPainter::end() first" );
+#endif
+ return FALSE;
+ }
+
+#ifndef TQT_NO_SVG
+ if ( qstricmp( format, "svg" ) == 0 ) {
+ TQSvgDevice svg;
+ TQPainter p( &svg );
+ if ( !play( &p ) )
+ return FALSE;
+ svg.setBoundingRect( boundingRect() );
+ return svg.save( dev );
+ }
+#endif
+ if ( format ) {
+ qWarning( "TQPicture::save: No such picture format: %s", format );
+ return FALSE;
+ }
+
+ dev->writeBlock( d->pictb.buffer().data(), d->pictb.buffer().size() );
+ return TRUE;
+}
+
+/*!
+ Returns the picture's bounding rectangle or an invalid rectangle
+ if the picture tqcontains no data.
+*/
+
+TQRect TQPicture::boundingRect() const
+{
+ if ( !d->formatOk )
+ d->checkFormat();
+ return d->brect;
+}
+
+/*!
+ Sets the picture's bounding rectangle to \a r. The automatically
+ calculated value is overriden.
+*/
+
+void TQPicture::setBoundingRect( const TQRect &r )
+{
+ if ( !d->formatOk )
+ d->checkFormat();
+ d->brect = r;
+}
+
+/*!
+ Replays the picture using \a painter, and returns TRUE if
+ successful; otherwise returns FALSE.
+
+ This function does exactly the same as TQPainter::drawPicture()
+ with (x, y) = (0, 0).
+*/
+
+bool TQPicture::play( TQPainter *painter )
+{
+ if ( d->pictb.size() == 0 ) // nothing recorded
+ return TRUE;
+
+ if ( !d->formatOk && !d->checkFormat() )
+ return FALSE;
+
+ d->pictb.open( IO_ReadOnly ); // open buffer tqdevice
+ TQDataStream s;
+ s.setDevice( &d->pictb ); // attach data stream to buffer
+ s.tqdevice()->at( 10 ); // go directly to the data
+ s.setVersion( d->formatMajor == 4 ? 3 : d->formatMajor );
+
+ TQ_UINT8 c, clen;
+ TQ_UINT32 nrecords;
+ s >> c >> clen;
+ TQ_ASSERT( c == PdcBegin );
+ // bounding rect was introduced in ver 4. Read in checkFormat().
+ if ( d->formatMajor >= 4 ) {
+ TQ_INT32 dummy;
+ s >> dummy >> dummy >> dummy >> dummy;
+ }
+ s >> nrecords;
+ if ( !exec( painter, s, nrecords ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPicture::play: Format error" );
+#endif
+ d->pictb.close();
+ return FALSE;
+ }
+ d->pictb.close();
+ return TRUE; // no end-command
+}
+
+
+/*!
+ \internal
+ Iterates over the internal picture data and draws the picture using
+ \a painter.
+*/
+
+bool TQPicture::exec( TQPainter *painter, TQDataStream &s, int nrecords )
+{
+#if defined(TQT_DEBUG)
+ int strm_pos;
+#endif
+ TQ_UINT8 c; // command id
+ TQ_UINT8 tiny_len; // 8-bit length descriptor
+ TQ_INT32 len; // 32-bit length descriptor
+ TQ_INT16 i_16, i1_16, i2_16; // parameters...
+ TQ_INT8 i_8;
+ TQ_UINT32 ul;
+ TQCString str1;
+ TQString str;
+ TQPoint p, p1, p2;
+ TQRect r;
+ TQPointArray a;
+ TQColor color;
+ TQFont font;
+ TQPen pen;
+ TQBrush brush;
+ TQRegion rgn;
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix matrix;
+#endif
+
+ while ( nrecords-- && !s.eof() ) {
+ s >> c; // read cmd
+ s >> tiny_len; // read param length
+ if ( tiny_len == 255 ) // longer than 254 bytes
+ s >> len;
+ else
+ len = tiny_len;
+#if defined(TQT_DEBUG)
+ strm_pos = s.tqdevice()->at();
+#endif
+ switch ( c ) { // exec cmd
+ case PdcNOP:
+ break;
+ case PdcDrawPoint:
+ s >> p;
+ painter->drawPoint( p );
+ break;
+ case PdcMoveTo:
+ s >> p;
+ painter->moveTo( p );
+ break;
+ case PdcLineTo:
+ s >> p;
+ painter->lineTo( p );
+ break;
+ case PdcDrawLine:
+ s >> p1 >> p2;
+ painter->drawLine( p1, p2 );
+ break;
+ case PdcDrawRect:
+ s >> r;
+ painter->drawRect( r );
+ break;
+ case PdcDrawRoundRect:
+ s >> r >> i1_16 >> i2_16;
+ painter->drawRoundRect( r, i1_16, i2_16 );
+ break;
+ case PdcDrawEllipse:
+ s >> r;
+ painter->drawEllipse( r );
+ break;
+ case PdcDrawArc:
+ s >> r >> i1_16 >> i2_16;
+ painter->drawArc( r, i1_16, i2_16 );
+ break;
+ case PdcDrawPie:
+ s >> r >> i1_16 >> i2_16;
+ painter->drawPie( r, i1_16, i2_16 );
+ break;
+ case PdcDrawChord:
+ s >> r >> i1_16 >> i2_16;
+ painter->drawChord( r, i1_16, i2_16 );
+ break;
+ case PdcDrawLineSegments:
+ s >> a;
+ painter->drawLineSegments( a );
+ break;
+ case PdcDrawPolyline:
+ s >> a;
+ painter->drawPolyline( a );
+ break;
+ case PdcDrawPolygon:
+ s >> a >> i_8;
+ painter->drawPolygon( a, i_8 );
+ break;
+ case PdcDrawCubicBezier:
+ s >> a;
+#ifndef TQT_NO_BEZIER
+ painter->drawCubicBezier( a );
+#endif
+ break;
+ case PdcDrawText:
+ s >> p >> str1;
+ painter->drawText( p, str1 );
+ break;
+ case PdcDrawTextFormatted:
+ s >> r >> i_16 >> str1;
+ painter->drawText( r, i_16, str1 );
+ break;
+ case PdcDrawText2:
+ s >> p >> str;
+ painter->drawText( p, str );
+ break;
+ case PdcDrawText2Formatted:
+ s >> r >> i_16 >> str;
+ painter->drawText( r, i_16, str );
+ break;
+ case PdcDrawPixmap: {
+ TQPixmap pixmap;
+ if ( d->formatMajor < 4 ) {
+ s >> p >> pixmap;
+ painter->drawPixmap( p, pixmap );
+ } else {
+ s >> r >> pixmap;
+ painter->drawPixmap( r, pixmap );
+ }
+ }
+ break;
+ case PdcDrawImage: {
+ TQImage image;
+ if ( d->formatMajor < 4 ) {
+ s >> p >> image;
+ painter->drawImage( p, image );
+ } else {
+ s >> r >> image;
+ painter->drawImage( r, image );
+ }
+ }
+ break;
+ case PdcBegin:
+ s >> ul; // number of records
+ if ( !exec( painter, s, ul ) )
+ return FALSE;
+ break;
+ case PdcEnd:
+ if ( nrecords == 0 )
+ return TRUE;
+ break;
+ case PdcSave:
+ painter->save();
+ break;
+ case PdcRestore:
+ painter->restore();
+ break;
+ case PdcSetBkColor:
+ s >> color;
+ painter->setBackgroundColor( color );
+ break;
+ case PdcSetBkMode:
+ s >> i_8;
+ painter->setBackgroundMode( (TQt::BGMode)i_8 );
+ break;
+ case PdcSetROP:
+ s >> i_8;
+ painter->setRasterOp( (TQt::RasterOp)i_8 );
+ break;
+ case PdcSetBrushOrigin:
+ s >> p;
+ painter->setBrushOrigin( p );
+ break;
+ case PdcSetFont:
+ s >> font;
+ painter->setFont( font );
+ break;
+ case PdcSetPen:
+ s >> pen;
+ painter->setPen( pen );
+ break;
+ case PdcSetBrush:
+ s >> brush;
+ painter->setBrush( brush );
+ break;
+ case PdcSetTabStops:
+ s >> i_16;
+ painter->setTabStops( i_16 );
+ break;
+ case PdcSetTabArray:
+ s >> i_16;
+ if ( i_16 == 0 ) {
+ painter->setTabArray( 0 );
+ } else {
+ int *ta = new int[i_16];
+ TQ_CHECK_PTR( ta );
+ for ( int i=0; i<i_16; i++ ) {
+ s >> i1_16;
+ ta[i] = i1_16;
+ }
+ painter->setTabArray( ta );
+ delete [] ta;
+ }
+ break;
+ case PdcSetVXform:
+ s >> i_8;
+#ifndef TQT_NO_TRANSFORMATIONS
+ painter->setViewXForm( i_8 );
+#endif
+ break;
+ case PdcSetWindow:
+ s >> r;
+#ifndef TQT_NO_TRANSFORMATIONS
+ painter->setWindow( r );
+#endif
+ break;
+ case PdcSetViewport:
+ s >> r;
+#ifndef TQT_NO_TRANSFORMATIONS
+ painter->setViewport( r );
+#endif
+ break;
+ case PdcSetWXform:
+ s >> i_8;
+#ifndef TQT_NO_TRANSFORMATIONS
+ painter->setWorldXForm( i_8 );
+#endif
+ break;
+ case PdcSetWMatrix:
+#ifndef TQT_NO_TRANSFORMATIONS // #### fix me!
+ s >> matrix >> i_8;
+ painter->setWorldMatrix( matrix, i_8 );
+#endif
+ break;
+#ifndef TQT_NO_TRANSFORMATIONS
+ case PdcSaveWMatrix:
+ painter->saveWorldMatrix();
+ break;
+ case PdcRestoreWMatrix:
+ painter->restoreWorldMatrix();
+ break;
+#endif
+ case PdcSetClip:
+ s >> i_8;
+ painter->setClipping( i_8 );
+ break;
+ case PdcSetClipRegion:
+ s >> rgn >> i_8;
+ painter->setClipRegion( rgn, (TQPainter::CoordinateMode)i_8 );
+ break;
+ default:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPicture::play: Invalid command %d", c );
+#endif
+ if ( len ) // skip unknown command
+ s.tqdevice()->at( s.tqdevice()->at()+len );
+ }
+#if defined(TQT_DEBUG)
+ //qDebug( "tqdevice->at(): %i, strm_pos: %i len: %i", s.tqdevice()->at(), strm_pos, len );
+ TQ_ASSERT( TQ_INT32(s.tqdevice()->at() - strm_pos) == len );
+#endif
+ }
+ return FALSE;
+}
+
+
+/*!
+ \internal
+ Records painter commands and stores them in the pictb buffer.
+*/
+
+bool TQPicture::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
+{
+ detach();
+ return d->cmd( c, pt, p );
+}
+
+/*!
+ \internal
+ Implementation of the function forwarded above to the internal data struct.
+*/
+
+bool TQPicture::TQPicturePrivate::cmd( int c, TQPainter *pt, TQPDevCmdParam *p )
+{
+ TQDataStream s;
+ s.setDevice( &pictb );
+ // when moving up to 4 the TQDataStream version remained at 3
+ s.setVersion( formatMajor != 4 ? formatMajor : 3 );
+ if ( c == PdcBegin ) { // begin; write header
+ TQByteArray empty( 0 );
+ pictb.setBuffer( empty ); // reset byte array in buffer
+ pictb.open( IO_WriteOnly );
+ s.writeRawBytes( mfhdr_tag, 4 );
+ s << (TQ_UINT16)0 << (TQ_UINT16)formatMajor << (TQ_UINT16)formatMinor;
+ s << (TQ_UINT8)c << (TQ_UINT8)sizeof(TQ_INT32);
+ brect = TQRect();
+ if ( formatMajor >= 4 ) {
+ s << (TQ_INT32)brect.left() << (TQ_INT32)brect.top()
+ << (TQ_INT32)brect.width() << (TQ_INT32)brect.height();
+ }
+ trecs = 0;
+ s << (TQ_UINT32)trecs; // total number of records
+ formatOk = FALSE;
+ return TRUE;
+ } else if ( c == PdcEnd ) { // end; calc checksum and close
+ trecs++;
+ s << (TQ_UINT8)c << (TQ_UINT8)0;
+ TQByteArray buf = pictb.buffer();
+ int cs_start = sizeof(TQ_UINT32); // pos of checksum word
+ int data_start = cs_start + sizeof(TQ_UINT16);
+ int brect_start = data_start + 2*sizeof(TQ_INT16) + 2*sizeof(TQ_UINT8);
+ int pos = pictb.at();
+ pictb.at( brect_start );
+ if ( formatMajor >= 4 ) { // bounding rectangle
+ s << (TQ_INT32)brect.left() << (TQ_INT32)brect.top()
+ << (TQ_INT32)brect.width() << (TQ_INT32)brect.height();
+ }
+ s << (TQ_UINT32)trecs; // write number of records
+ pictb.at( cs_start );
+ TQ_UINT16 cs = (TQ_UINT16)qChecksum( buf.data()+data_start, pos-data_start );
+ s << cs; // write checksum
+ pictb.close();
+ return TRUE;
+ }
+ trecs++;
+ s << (TQ_UINT8)c; // write cmd to stream
+ s << (TQ_UINT8)0; // write dummy length info
+ int pos = (int)pictb.at(); // save position
+ TQRect br; // bounding rect addition
+ bool corr = FALSE; // correction for pen width
+
+ switch ( c ) {
+ case PdcDrawPoint:
+ case PdcMoveTo:
+ case PdcLineTo:
+ case PdcSetBrushOrigin:
+ s << *p[0].point;
+ br = TQRect( *p[0].point, TQSize( 1, 1 ) );
+ corr = TRUE;
+ break;
+ case PdcDrawLine:
+ s << *p[0].point << *p[1].point;
+ br = TQRect( *p[0].point, *p[1].point ).normalize();
+ corr = TRUE;
+ break;
+ case PdcDrawRect:
+ case PdcDrawEllipse:
+ s << *p[0].rect;
+ br = *p[0].rect;
+ corr = TRUE;
+ break;
+ case PdcDrawRoundRect:
+ case PdcDrawArc:
+ case PdcDrawPie:
+ case PdcDrawChord:
+ s << *p[0].rect << (TQ_INT16)p[1].ival << (TQ_INT16)p[2].ival;
+ br = *p[0].rect;
+ corr = TRUE;
+ break;
+ case PdcDrawLineSegments:
+ case PdcDrawPolyline:
+ s << *p[0].ptarr;
+ br = p[0].ptarr->boundingRect();
+ corr = TRUE;
+ break;
+#ifndef TQT_NO_BEZIER
+ case PdcDrawCubicBezier:
+ s << *p[0].ptarr;
+ br = p[0].ptarr->cubicBezier().boundingRect();
+ corr = TRUE;
+ break;
+#endif
+ case PdcDrawPolygon:
+ s << *p[0].ptarr << (TQ_INT8)p[1].ival;
+ br = p[0].ptarr->boundingRect();
+ corr = TRUE;
+ break;
+ case PdcDrawText2:
+ if ( formatMajor == 1 ) {
+ pictb.at( pos - 2 );
+ s << (TQ_UINT8)PdcDrawText << (TQ_UINT8)0;
+ TQCString str1( (*p[1].str).latin1() );
+ s << *p[0].point << str1;
+ }
+ else {
+ s << *p[0].point << *p[1].str;
+ }
+ br = pt->fontMetrics().boundingRect( *p[1].str );
+ br.moveBy( p[0].point->x(), p[0].point->y() );
+ break;
+ case PdcDrawText2Formatted:
+ if ( formatMajor == 1 ) {
+ pictb.at( pos - 2 );
+ s << (TQ_UINT8)PdcDrawTextFormatted << (TQ_UINT8)0;
+ TQCString str1( (*p[2].str).latin1() );
+ s << *p[0].rect << (TQ_INT16)p[1].ival << str1;
+ }
+ else {
+ s << *p[0].rect << (TQ_INT16)p[1].ival << *p[2].str;
+ }
+ br = *p[0].rect;
+ break;
+ case PdcDrawPixmap:
+ if ( formatMajor < 4 ) {
+ s << *p[0].point;
+ s << *p[1].pixmap;
+ br = TQRect( *p[0].point, p[1].pixmap->size() );
+ } else {
+ s << *p[0].rect;
+ s << *p[1].pixmap;
+ br = *p[0].rect;
+ }
+ break;
+ case PdcDrawImage:
+ if ( formatMajor < 4 ) {
+ TQPoint pt( p[0].point->x(), p[0].point->y() );
+ s << pt;
+ s << *p[1].image;
+ br = TQRect( *p[0].point, p[1].image->size() );
+ } else {
+ s << *p[0].rect;
+ s << *p[1].image;
+ br = *p[0].rect;
+ }
+ break;
+ case PdcSave:
+ case PdcRestore:
+ break;
+ case PdcSetBkColor:
+ s << *p[0].color;
+ break;
+ case PdcSetBkMode:
+ case PdcSetROP:
+ s << (TQ_INT8)p[0].ival;
+ break;
+ case PdcSetFont: {
+ TQFont fnt = *p[0].font;
+ if (fnt.pointSize() > 0)
+ // we have to store pixels to get correct replay.
+ // the resolution is 72 dpi, so points == pixels
+ fnt.setPixelSize(TQFontInfo(fnt).pixelSize());
+ s << fnt;
+ }
+ break;
+ case PdcSetPen:
+ s << *p[0].pen;
+ break;
+ case PdcSetBrush:
+ s << *p[0].brush;
+ break;
+ case PdcSetTabStops:
+ s << (TQ_INT16)p[0].ival;
+ break;
+ case PdcSetTabArray:
+ s << (TQ_INT16)p[0].ival;
+ if ( p[0].ival ) {
+ int *ta = p[1].ivec;
+ for ( int i=0; i<p[0].ival; i++ )
+ s << (TQ_INT16)ta[i];
+ }
+ break;
+ case PdcSetUnit:
+ case PdcSetVXform:
+ case PdcSetWXform:
+ case PdcSetClip:
+ s << (TQ_INT8)p[0].ival;
+ break;
+#ifndef TQT_NO_TRANSFORMATIONS
+ case PdcSetWindow:
+ case PdcSetViewport:
+ s << *p[0].rect;
+ break;
+ case PdcSetWMatrix:
+ s << *p[0].matrix << (TQ_INT8)p[1].ival;
+ break;
+#endif
+ case PdcSetClipRegion:
+ s << *p[0].rgn;
+ s << (TQ_INT8)p[1].ival;
+ break;
+#if defined(TQT_CHECK_RANGE)
+ default:
+ qWarning( "TQPicture::cmd: Command %d not recognized", c );
+#endif
+ }
+ int newpos = (int)pictb.at(); // new position
+ int length = newpos - pos;
+ if ( length < 255 ) { // write 8-bit length
+ pictb.at(pos - 1); // position to right index
+ s << (TQ_UINT8)length;
+ } else { // write 32-bit length
+ s << (TQ_UINT32)0; // extend the buffer
+ pictb.at(pos - 1); // position to right index
+ s << (TQ_UINT8)255; // indicate 32-bit length
+ char *p = pictb.buffer().data();
+ memmove( p+pos+4, p+pos, length ); // make room for 4 byte
+ s << (TQ_UINT32)length;
+ newpos += 4;
+ }
+ pictb.at( newpos ); // set to new position
+
+ if ( br.isValid() ) {
+ if ( corr ) { // widen bounding rect
+ int w2 = pt->pen().width() / 2;
+ br.setCoords( br.left() - w2, br.top() - w2,
+ br.right() + w2, br.bottom() + w2 );
+ }
+#ifndef TQT_NO_TRANSFORMATIONS
+ br = pt->tqworldMatrix().map( br );
+#endif
+ if ( pt->hasClipping() ) {
+ TQRect cr = pt->clipRegion().boundingRect();
+ br &= cr;
+ }
+ if ( br.isValid() )
+ brect |= br; // merge with existing rect
+ }
+
+ return TRUE;
+}
+
+
+/*!
+ Internal implementation of the virtual TQPaintDevice::metric()
+ function.
+
+ Use the TQPaintDeviceMetrics class instead.
+
+ A picture has the following hard-coded values: dpi=72,
+ numcolors=16777216 and depth=24.
+
+ \a m is the metric to get.
+*/
+
+int TQPicture::metric( int m ) const
+{
+ int val;
+ switch ( m ) {
+ // ### hard coded dpi and color depth values !
+ case TQPaintDeviceMetrics::PdmWidth:
+ val = d->brect.width();
+ break;
+ case TQPaintDeviceMetrics::PdmHeight:
+ val = d->brect.height();
+ break;
+ case TQPaintDeviceMetrics::PdmWidthMM:
+ val = int(25.4/72.0*d->brect.width());
+ break;
+ case TQPaintDeviceMetrics::PdmHeightMM:
+ val = int(25.4/72.0*d->brect.height());
+ break;
+ case TQPaintDeviceMetrics::PdmDpiX:
+ case TQPaintDeviceMetrics::PdmPhysicalDpiX:
+ val = 72;
+ break;
+ case TQPaintDeviceMetrics::PdmDpiY:
+ case TQPaintDeviceMetrics::PdmPhysicalDpiY:
+ val = 72;
+ break;
+ case TQPaintDeviceMetrics::PdmNumColors:
+ val = 16777216;
+ break;
+ case TQPaintDeviceMetrics::PdmDepth:
+ val = 24;
+ break;
+ default:
+ val = 0;
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPicture::metric: Invalid metric command" );
+#endif
+ }
+ return val;
+}
+
+/*!
+ Detaches from shared picture data and makes sure that this picture
+ is the only one referring to the data.
+
+ If multiple pictures share common data, this picture makes a copy
+ of the data and detaches itself from the sharing mechanism.
+ Nothing is done if there is just a single reference.
+*/
+
+void TQPicture::detach()
+{
+ if ( d->count != 1 )
+ *this = copy();
+}
+
+/*!
+ Returns a \link shclass.html deep copy\endlink of the picture.
+*/
+
+TQPicture TQPicture::copy() const
+{
+ TQPicture p;
+ TQByteArray a( size() );
+ memcpy( a.data(), data(), size() );
+ p.d->pictb.setBuffer( a ); // set byte array in buffer
+ if ( d->pictb.isOpen() ) { // copy buffer state
+ p.d->pictb.open( d->pictb.mode() );
+ p.d->pictb.at( d->pictb.at() );
+ }
+ p.d->trecs = d->trecs;
+ p.d->formatOk = d->formatOk;
+ p.d->formatMinor = d->formatMajor;
+ p.d->brect = boundingRect();
+ return p;
+}
+
+/*****************************************************************************
+ TQPainter member functions
+ *****************************************************************************/
+
+/*!
+ Replays the picture \a pic translated by (\a x, \a y).
+
+ This function does exactly the same as TQPicture::play() when
+ called with (\a x, \a y) = (0, 0).
+*/
+
+void TQPainter::drawPicture( int x, int y, const TQPicture &pic )
+{
+ save();
+ translate( x, y );
+ ((TQPicture*)&pic)->play( (TQPainter*)this );
+ restore();
+}
+
+/*!
+ \overload void TQPainter::drawPicture( const TQPoint &p, const TQPicture &pic )
+
+ Draws picture \a pic at point \a p.
+*/
+
+void TQPainter::drawPicture( const TQPoint &p, const TQPicture &pic )
+{
+ drawPicture( p.x(), p.y(), pic );
+}
+
+/*!
+ \obsolete
+
+ Use one of the other TQPainter::drawPicture() functions with a (0, 0)
+ offset instead.
+*/
+
+void TQPainter::drawPicture( const TQPicture &pic )
+{
+ drawPicture( 0, 0, pic );
+}
+
+/*!
+ Assigns a \link shclass.html shallow copy\endlink of \a p to this
+ picture and returns a reference to this picture.
+*/
+
+TQPicture& TQPicture::operator= (const TQPicture& p)
+{
+ p.d->ref(); // avoid 'x = x'
+ if ( d->deref() )
+ delete d;
+ d = p.d;
+ return *this;
+}
+
+
+/*!
+ \internal
+
+ Sets formatOk to FALSE and resets the format version numbers to default
+*/
+
+void TQPicture::TQPicturePrivate::resetFormat()
+{
+ formatOk = FALSE;
+ formatMajor = mfhdr_maj;
+ formatMinor = mfhdr_min;
+}
+
+/*!
+ \internal
+
+ Checks data integrity and format version number. Set formatOk to TRUE
+ on success, to FALSE otherwise. Returns the resulting formatOk value.
+*/
+
+bool TQPicture::TQPicturePrivate::checkFormat()
+{
+ resetFormat();
+
+ // can't check anything in an empty buffer
+ if ( pictb.size() == 0 )
+ return FALSE;
+
+ pictb.open( IO_ReadOnly ); // open buffer tqdevice
+ TQDataStream s;
+ s.setDevice( &pictb ); // attach data stream to buffer
+
+ char mf_id[4]; // picture header tag
+ s.readRawBytes( mf_id, 4 ); // read actual tag
+ if ( memcmp(mf_id, mfhdr_tag, 4) != 0 ) { // wrong header id
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPicture::checkFormat: Incorrect header" );
+#endif
+ pictb.close();
+ return FALSE;
+ }
+
+ int cs_start = sizeof(TQ_UINT32); // pos of checksum word
+ int data_start = cs_start + sizeof(TQ_UINT16);
+ TQ_UINT16 cs,ccs;
+ TQByteArray buf = pictb.buffer(); // pointer to data
+ s >> cs; // read checksum
+ ccs = qChecksum( buf.data() + data_start, buf.size() - data_start );
+ if ( ccs != cs ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPicture::checkFormat: Invalid checksum %x, %x expected",
+ ccs, cs );
+#endif
+ pictb.close();
+ return FALSE;
+ }
+
+ TQ_UINT16 major, minor;
+ s >> major >> minor; // read version number
+ if ( major > mfhdr_maj ) { // new, incompatible version
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPicture::checkFormat: Incompatible version %d.%d",
+ major, minor);
+#endif
+ pictb.close();
+ return FALSE;
+ }
+ s.setVersion( major != 4 ? major : 3 );
+
+ TQ_UINT8 c, clen;
+ s >> c >> clen;
+ if ( c == PdcBegin ) {
+ if ( !( major >= 1 && major <= 3 )) {
+ TQ_INT32 l, t, w, h;
+ s >> l >> t >> w >> h;
+ brect = TQRect( l, t, w, h );
+ }
+ } else {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPicture::checkFormat: Format error" );
+#endif
+ pictb.close();
+ return FALSE;
+ }
+ pictb.close();
+
+ formatOk = TRUE; // picture seems to be ok
+ formatMajor = major;
+ formatMinor = minor;
+ return TRUE;
+}
+
+/*****************************************************************************
+ TQPicture stream functions
+ *****************************************************************************/
+
+/*!
+ \relates TQPicture
+
+ Writes picture \a r to the stream \a s and returns a reference to
+ the stream.
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQPicture &r )
+{
+ TQ_UINT32 size = r.d->pictb.buffer().size();
+ s << size;
+ // null picture ?
+ if ( size == 0 )
+ return s;
+ // just write the whole buffer to the stream
+ return s.writeRawBytes ( r.d->pictb.buffer().data(),
+ r.d->pictb.buffer().size() );
+}
+
+/*!
+ \relates TQPicture
+
+ Reads a picture from the stream \a s into picture \a r and returns
+ a reference to the stream.
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQPicture &r )
+{
+ TQDataStream sr;
+
+ // "init"; this code is similar to the beginning of TQPicture::cmd()
+ sr.setDevice( &r.d->pictb );
+ sr.setVersion( r.d->formatMajor );
+ TQ_UINT32 len;
+ s >> len;
+ TQByteArray data( len );
+ if ( len > 0 )
+ s.readRawBytes( data.data(), len );
+
+ r.d->pictb.setBuffer( data );
+ r.d->resetFormat();
+
+ return s;
+}
+
+#endif // USE_QT4
+
+#endif // TQT_NO_PICTURE
+
diff --git a/tqtinterface/qt4/src/kernel/tqpicture.h b/tqtinterface/qt4/src/kernel/tqpicture.h
new file mode 100644
index 0000000..6dfc9cd
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpicture.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Definition of TQPicture class
+**
+** Created : 940729
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPICTURE_H
+#define TQPICTURE_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqpaintdevice.h"
+#include "tqbuffer.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_PICTURE
+
+#ifdef USE_QT4
+
+#include <Qt/qpicture.h>
+
+class TQ_EXPORT TQPicture : public QPicture, virtual public TQt
+{
+public:
+ TQPicture( int formatVersion = -1 ) : QPicture( formatVersion ) {}
+ TQPicture( const TQPicture &tqp ) : QPicture( tqp ) {}
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQPicture : public TQPaintDevice // picture class
+{
+public:
+ TQPicture( int formatVersion = -1 );
+ TQPicture( const TQPicture & );
+ ~TQPicture();
+
+ bool isNull() const;
+
+ uint size() const;
+ const char* data() const;
+ virtual void setData( const char* data, uint size );
+
+ bool play( TQPainter * );
+
+ bool load( TQIODevice *dev, const char *format = 0 );
+ bool load( const TQString &fileName, const char *format = 0 );
+ bool save( TQIODevice *dev, const char *format = 0 );
+ bool save( const TQString &fileName, const char *format = 0 );
+
+ TQRect boundingRect() const;
+ void setBoundingRect( const TQRect &r );
+
+ TQPicture& operator= (const TQPicture&);
+
+ friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPicture & );
+ friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPicture & );
+
+protected:
+ bool cmd( int, TQPainter *, TQPDevCmdParam * );
+ int metric( int ) const;
+ void detach();
+ TQPicture copy() const;
+
+private:
+ bool exec( TQPainter *, TQDataStream &, int );
+
+ struct TQPicturePrivate : public TQShared {
+ bool cmd( int, TQPainter *, TQPDevCmdParam * );
+ bool checkFormat();
+ void resetFormat();
+
+ TQBuffer pictb;
+ int trecs;
+ bool formatOk;
+ int formatMajor;
+ int formatMinor;
+ TQRect brect;
+ } *d;
+};
+
+
+inline bool TQPicture::isNull() const
+{
+ return d->pictb.buffer().isNull();
+}
+
+inline uint TQPicture::size() const
+{
+ return d->pictb.buffer().size();
+}
+
+inline const char* TQPicture::data() const
+{
+ return d->pictb.buffer().data();
+}
+
+/*****************************************************************************
+ TQPicture stream functions
+ *****************************************************************************/
+
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPicture & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPicture & );
+
+#endif // USE_QT4
+
+#endif // TQT_NO_PICTURE
+
+#endif // TQPICTURE_H
diff --git a/tqtinterface/qt4/src/kernel/tqpixmap.cpp b/tqtinterface/qt4/src/kernel/tqpixmap.cpp
new file mode 100644
index 0000000..f47fb38
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpixmap.cpp
@@ -0,0 +1,1882 @@
+/****************************************************************************
+**
+** Implementation of TQPixmap class
+**
+** Created : 950301
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpixmap.h"
+
+#include "tqbitmap.h"
+#include "tqimage.h"
+#include "tqwidget.h"
+#include "tqpainter.h"
+#include "tqdatastream.h"
+#include "tqbuffer.h"
+#include "tqobjectlist.h"
+#include "tqapplication.h"
+#include <private/tqinternal_p.h>
+#include "tqmime.h"
+#include "tqdragobject.h"
+#include "tqfile.h"
+
+#ifdef USE_QT4
+
+#include <Qt/qpaintengine.h>
+#include "tqbitmap.h"
+
+#define VERIFY_TQPIXMAP_OBJECT_FUNCTION(x) \
+if (!dynamic_cast<const TQPixmap*>(static_cast<const QPixmap*>(this))) { \
+ printf("[WARNING] An attempt was made to access the TQPixmap::tqmask method from an object not of type TQPixmap [possibly QPixmap]\n\r\tThis may indicate creation and subsequent [illegal] downcasting of a QPixmap object to a TQPixmap object within your application\n\r\tNo pixmap was returned\n\r"); \
+ return x; \
+}
+
+TQPixmap::TQPixmap() : QPixmap(), tqt_tqbitmap_ptr(0) {
+}
+
+TQPixmap::TQPixmap( const QImage& image ) : QPixmap( QPixmap::fromImage(image) ), tqt_tqbitmap_ptr(0) {
+}
+
+// [FIXME] Set depth correctly (in Qt4 is that even possible/wise?)
+TQPixmap::TQPixmap( int w, int h, int depth, Optimization o ) : QPixmap( w, h ), tqt_tqbitmap_ptr(0) {
+ TQ_UNUSED(o);
+ TQ_UNUSED(depth);
+}
+
+// [FIXME] Set depth correctly (in Qt4 is that even possible/wise?)
+TQPixmap::TQPixmap( const QSize &s, int depth, Optimization o ) : QPixmap( s ), tqt_tqbitmap_ptr(0) {
+ TQ_UNUSED(o);
+ TQ_UNUSED(depth);
+}
+
+#ifndef TQT_NO_IMAGEIO
+TQPixmap::TQPixmap( const QString& fileName, const char *format, TQPixmap::ColorMode mode ) : QPixmap( fileName, format ), tqt_tqbitmap_ptr(0) {
+ TQ_UNUSED(mode);
+}
+
+TQPixmap::TQPixmap( const QString& fileName, const char *format, int conversion_flags ) : QPixmap( fileName, format, (Qt::ImageConversionFlags)conversion_flags), tqt_tqbitmap_ptr(0) {
+}
+
+TQPixmap::TQPixmap( const char *xpm[] ) : QPixmap( xpm ), tqt_tqbitmap_ptr(0) {
+}
+
+TQPixmap::TQPixmap( const QByteArray &data ) : QPixmap( data ), tqt_tqbitmap_ptr(0) {
+}
+#endif
+TQPixmap::TQPixmap( const TQPixmap &p ) : QPixmap( p ), tqt_tqbitmap_ptr(0) {
+}
+
+TQPixmap::TQPixmap( const QPixmap p ) : QPixmap( p ), tqt_tqbitmap_ptr(0) {
+}
+
+TQPixmap::~TQPixmap() {
+ // HACK
+ // Make absolutely sure that this is a TQPixmap object!
+ VERIFY_TQPIXMAP_OBJECT_FUNCTION( )
+// printf("[WARNING] Memory leak likely at TQPixmap destruction [tqt_tqbitmap_ptr was %p]\n\r", (void*)tqt_tqbitmap_ptr); fflush(stdout); // [FIXME] [CRITICAL] [MEMORY LEAK]
+ if (tqt_tqbitmap_ptr) delete tqt_tqbitmap_ptr;
+}
+
+bool TQPixmap::selfMask() const {
+ return false;
+}
+
+bool TQPixmap::convertFromImage(const QImage &img, Qt::ImageConversionFlags flags) {
+ *this = fromImage(img, flags);
+ return true;
+}
+
+bool TQPixmap::convertFromImage(const QImage &img, int flags) {
+ return QPixmap::convertFromImage(img, (Qt::ImageConversionFlag)flags);
+}
+
+void TQPixmap::setOptimization( TQPixmap::Optimization ) {
+}
+
+void TQPixmap::setDefaultOptimization( TQPixmap::Optimization ) {
+}
+
+void TQPixmap::resize(const QSize s) {
+ resize_helper(s);
+}
+
+void TQPixmap::resize(int width, int height) {
+ resize_helper(QSize(width, height));
+}
+
+void *TQPixmap::x11AppVisual( void ) {
+ return x11AppVisual(-1);
+}
+
+void *TQPixmap::x11AppVisual( int screen ) {
+ return QX11Info::appVisual(screen);
+}
+
+int TQPixmap::x11AppCells( void ) {
+ return x11AppCells(-1);
+}
+
+int TQPixmap::x11AppCells( int screen ) {
+ return QX11Info::appCells(screen);
+}
+
+int TQPixmap::x11AppDepth( void ) {
+ return x11AppDepth(-1);
+}
+
+int TQPixmap::x11AppDepth( int screen ) {
+ return QX11Info::appDepth(screen);
+}
+
+Display *TQPixmap::x11AppDisplay( void ) {
+ return QX11Info::display();
+}
+
+int TQPixmap::x11AppScreen( void ) {
+ return QX11Info::appScreen();
+}
+
+bool TQPixmap::x11AppDefaultVisual( void ) {
+ return x11AppDefaultVisual(-1);
+}
+
+bool TQPixmap::x11AppDefaultVisual( int screen ) {
+ return QX11Info::appDefaultVisual(screen);
+}
+
+TQt::HANDLE TQPixmap::x11AppColormap( void ) {
+ return x11AppColormap(-1);
+}
+
+TQt::HANDLE TQPixmap::x11AppColormap( int screen ) {
+ return QX11Info::appColormap(screen);
+}
+
+bool TQPixmap::x11AppDefaultColormap( void ) {
+ return x11AppDefaultColormap(-1);
+}
+
+bool TQPixmap::x11AppDefaultColormap( int screen ) {
+ return QX11Info::appDefaultColormap(screen);
+}
+
+TQt::HANDLE TQPixmap::x11AppRootWindow( void ) {
+ return x11AppRootWindow(-1);
+}
+
+TQt::HANDLE TQPixmap::x11AppRootWindow( int screen ) {
+ return QX11Info::appRootWindow(screen);
+}
+
+const TQBitmap *TQPixmap::tqmask() const {
+ // HACK
+ // Make absolutely sure that this is a TQPixmap object!
+ VERIFY_TQPIXMAP_OBJECT_FUNCTION(0)
+
+ const QBitmap& ptrRef = mask();
+ if (ptrRef.isNull() == true) {
+ return 0;
+ }
+ if (tqt_tqbitmap_ptr) {
+ delete tqt_tqbitmap_ptr;
+ }
+ tqt_tqbitmap_ptr = new TQBitmap(ptrRef);
+ return tqt_tqbitmap_ptr;
+}
+
+void TQPixmap::resize_helper(const QSize s)
+{
+ int w = s.width();
+ int h = s.height();
+
+ if (w < 1 || h < 1) {
+ *this = TQPixmap();
+ return;
+ }
+
+ if (size() == s)
+ return;
+
+ TQPixmap pm(QSize(w, h));
+ if (!isNull()) {
+ // Copy old pixmap
+ if (hasAlphaChannel())
+ pm.fill(Qt::transparent);
+ QPainter p(&pm);
+ p.drawPixmap(0, 0, *this, 0, 0, qMin(width(), w), qMin(height(), h));
+ p.end();
+ }
+
+ // Mask too....
+ if (!mask().isNull()) {
+ TQBitmap m = mask();
+ if (m.size() != QSize(w,h)) {
+ TQBitmap pmr(QSize(w, h));
+ pmr.fill(Qt::color0);
+ QPainter pr(&pmr);
+ pr.setBrush(Qt::color1);
+ pr.drawPixmap(0, 0, m, 0, 0, qMin(m.width(), w), qMin(m.height(), h));
+ pr.end();
+ pm.setMask(pmr);
+ }
+ else {
+ pm.setMask(m);
+ }
+ }
+
+ // [FIXME]
+ // Note that the Xorg pixmap and/or gc (if any) is not created via the above process
+ // Therefore resize is more of a copy operation than a true resize
+ #warning TQPixmap::resize() partially implemented
+
+ *this = pm;
+}
+
+TQImage TQPixmap::convertToImage() const {
+ return TQImage(toImage());
+}
+
+TQPixmap::operator TQImage() const {
+ return TQImage(toImage());
+}
+
+TQPixmap TQPixmap::xForm(const QMatrix &matrix) const {
+ return TQPixmap(transformed(QTransform(matrix)));
+}
+
+void copyBlt(QPixmap *dst, int dx, int dy,
+ const QPixmap *src, int sx, int sy, int sw, int sh)
+{
+ Q_ASSERT_X(dst, "::copyBlt", "Destination pixmap must be non-null");
+ Q_ASSERT_X(src, "::copyBlt", "Source pixmap must be non-null");
+
+ if (src->hasAlphaChannel()) {
+ if (dst->paintEngine()->hasFeature(QPaintEngine::PorterDuff)) {
+ QPainter p(dst);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.drawPixmap(dx, dy, *src, sx, sy, sw, sh);
+ } else {
+ QImage image = dst->toImage().convertToFormat(QImage::Format_ARGB32_Premultiplied);
+ QPainter p(&image);
+ p.setCompositionMode(QPainter::CompositionMode_Source);
+ p.drawPixmap(dx, dy, *src, sx, sy, sw, sh);
+ p.end();
+ *dst = QPixmap::fromImage(image);
+ }
+ } else {
+ QPainter p(dst);
+ p.drawPixmap(dx, dy, *src, sx, sy, sw, sh);
+ }
+
+}
+
+extern const Q_GUI_EXPORT QX11Info *qt_x11Info(const QPaintDevice *pd); // Defined in tqpaintdevice_x11.cpp
+
+Display *TQPixmap::x11Display() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->display();
+ return QX11Info::display();
+}
+
+int TQPixmap::x11Screen() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->screen();
+ return QX11Info::appScreen();
+}
+
+void *TQPixmap::x11Visual() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->visual();
+ return QX11Info::appVisual();
+}
+
+int TQPixmap::x11Depth() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->depth();
+ return QX11Info::appDepth();
+}
+
+int TQPixmap::x11Cells() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->cells();
+ return QX11Info::appCells();
+}
+
+Qt::HANDLE TQPixmap::x11Colormap() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->colormap();
+ return QX11Info::appColormap();
+}
+
+bool TQPixmap::x11DefaultColormap() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->defaultColormap();
+ return QX11Info::appDefaultColormap();
+}
+
+bool TQPixmap::x11DefaultVisual() const
+{
+ const QX11Info *info = qt_x11Info(this);
+ if (info)
+ return info->defaultVisual();
+ return QX11Info::appDefaultVisual();
+}
+
+void TQPixmap::x11SetAppDpiX(int dpi, int screen)
+{
+ QX11Info::setAppDpiX(dpi, screen);
+}
+
+void TQPixmap::x11SetAppDpiY(int dpi, int screen)
+{
+ QX11Info::setAppDpiY(dpi, screen);
+}
+
+int TQPixmap::x11AppDpiX(int screen)
+{
+ return QX11Info::appDpiX(screen);
+}
+
+int TQPixmap::x11AppDpiY(int screen)
+{
+ return QX11Info::appDpiY(screen);
+}
+
+/*! Convenience function. Gets the data associated with the absolute
+ name \a abs_name from the default mime source factory and decodes it
+ to a pixmap.
+
+ \sa TQMimeSourceFactory, TQImage::fromMimeSource(), TQImageDrag::decode()
+*/
+
+#ifndef TQT_NO_MIME
+TQPixmap TQPixmap::fromMimeSource( const TQString &abs_name )
+{
+ const TQMimeSource *m = TQT_TQMIMESOURCE_CONST(TQMimeSourceFactory::defaultFactory()->data( abs_name ));
+ if ( !m ) {
+ if ( TQFile::exists( abs_name ) )
+ return TQPixmap( abs_name );
+#if defined(TQT_CHECK_STATE)
+ if ( !abs_name.isEmpty() )
+ qWarning( "TQPixmap::fromMimeSource: Cannot find pixmap \"%s\" in the mime source factory",
+ abs_name.latin1() );
+#endif
+ return TQPixmap();
+ }
+ TQPixmap pix;
+ TQImageDrag::decode( m, pix );
+ return pix;
+}
+#endif
+
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+TQBitmap TQPixmap::createHeuristicMask( bool clipTight ) const {
+ return TQBitmap(QPixmap::createHeuristicMask(clipTight));
+}
+#endif
+
+#else // USE_QT4
+
+/*!
+ \class TQPixmap tqpixmap.h
+ \brief The TQPixmap class is an off-screen, pixel-based paint tqdevice.
+
+ \ingroup graphics
+ \ingroup images
+ \ingroup shared
+ \mainclass
+
+ TQPixmap is one of the two classes TQt provides for dealing with
+ images; the other is TQImage. TQPixmap is designed and optimized
+ for drawing; TQImage is designed and optimized for I/O and for
+ direct pixel access/manipulation. There are (slow) functions to
+ convert between TQImage and TQPixmap: convertToImage() and
+ convertFromImage().
+
+ One common use of the TQPixmap class is to enable smooth updating
+ of widgets. Whenever something complex needs to be drawn, you can
+ use a pixmap to obtain flicker-free drawing, like this:
+
+ \list 1
+ \i Create a pixmap with the same size as the widget.
+ \i Fill the pixmap with the widget background color.
+ \i Paint the pixmap.
+ \i bitBlt() the pixmap contents onto the widget.
+ \endlist
+
+ Pixel data in a pixmap is internal and is managed by the
+ underlying window system. Pixels can be accessed only through
+ TQPainter functions, through bitBlt(), and by converting the
+ TQPixmap to a TQImage.
+
+ You can easily display a TQPixmap on the screen using
+ TQLabel::setPixmap(). For example, all the TQButton subclasses
+ support pixmap use.
+
+ The TQPixmap class uses \link shclass.html copy-on-write\endlink,
+ so it is practical to pass TQPixmap objects by value.
+
+ You can retrieve the width(), height(), depth() and size() of a
+ pixmap. The enclosing rectangle is given by rect(). Pixmaps can be
+ filled with fill() and resized with resize(). You can create and
+ set a tqmask with createHeuristicMask() and setMask(). Use
+ selfMask() to see if the pixmap is identical to its tqmask.
+
+ In addition to loading a pixmap from file using load() you can
+ also loadFromData(). You can control optimization with
+ setOptimization() and obtain a transformed version of the pixmap
+ using xForm()
+
+ Note regarding Windows 95 and 98: on Windows 9x the system crashes
+ if you create more than about 1000 pixmaps, independent of the
+ size of the pixmaps or installed RAM. Windows NT-systems (including
+ 2000, XP and following versions) do not have the same limitation,
+ but depending on the graphics equipment the system will fail to
+ allocate pixmap objects at some point (due to system running out of
+ GDI resources).
+
+ TQt tries to work around the resource limitation. If you set the
+ pixmap optimization to \c TQPixmap::MemoryOptim and the width of
+ your pixmap is less than or equal to 128 pixels, TQt stores the
+ pixmap in a way that is very memory-efficient when there are many
+ pixmaps.
+
+ If your application uses dozens or hundreds of pixmaps (for
+ example on tool bar buttons and in popup menus), and you plan to
+ run it on Windows 95 or Windows 98, we recommend using code like
+ this:
+
+ \code
+ TQPixmap::setDefaultOptimization( TQPixmap::MemoryOptim );
+ while ( ... ) {
+ // load tool bar pixmaps etc.
+ TQPixmap *pixmap = new TQPixmap(fileName);
+ }
+ TQPixmap::setDefaultOptimization( TQPixmap::NormalOptim );
+ \endcode
+
+ In general it is recommended to make as much use of TQPixmap's
+ implicit sharing and the TQPixmapCache as possible.
+
+ \sa TQBitmap, TQImage, TQImageIO, \link shclass.html Shared Classes\endlink
+*/
+
+/*!
+ \enum TQPixmap::ColorMode
+
+ This enum type defines the color modes that exist for converting
+ TQImage objects to TQPixmap.
+
+ \value Auto Select \c Color or \c Mono on a case-by-case basis.
+ \value Color Always create colored pixmaps.
+ \value Mono Always create bitmaps.
+*/
+
+/*!
+ \enum TQPixmap::Optimization
+
+ TQPixmap has the choice of optimizing for speed or memory in a few
+ places; the best choice varies from pixmap to pixmap but can
+ generally be derived heuristically. This enum type defines a
+ number of optimization modes that you can set for any pixmap to
+ tweak the speed/memory tradeoffs:
+
+ \value DefaultOptim Whatever TQPixmap::defaultOptimization()
+ returns. A pixmap with this optimization will have whatever
+ the current default optimization is. If the default
+ optimization is changed using setDefaultOptimization(), then
+ this will not effect any pixmaps that have already been
+ created.
+
+ \value NoOptim No optimization (currently the same as \c
+ MemoryOptim).
+
+ \value MemoryOptim Optimize for minimal memory use on Windows
+ 9x and X11 systems.
+
+ \value NormalOptim Optimize for typical usage. Often uses more
+ memory than \c MemoryOptim, and is often faster.
+
+ \value BestOptim Optimize for pixmaps that are drawn very often
+ and where performance is critical. Generally uses more memory
+ than \c NormalOptim and may provide a little more speed.
+
+ We recommend using \c DefaultOptim.
+
+*/
+
+
+TQPixmap::Optimization TQPixmap::defOptim = TQPixmap::NormalOptim;
+
+
+/*!
+ \internal
+ Private constructor which takes the bitmap flag, the optimization.and a screen.
+*/
+
+TQPixmap::TQPixmap( int w, int h, int depth, bool bitmap,
+ Optimization optimization )
+ : TQPaintDevice( TQInternal::Pixmap )
+{
+ init( w, h, depth, bitmap, optimization );
+}
+
+
+/*!
+ Constructs a null pixmap.
+
+ \sa isNull()
+*/
+
+TQPixmap::TQPixmap()
+ : TQPaintDevice( TQInternal::Pixmap )
+{
+ init( 0, 0, 0, FALSE, defOptim );
+}
+
+/*!
+ Constructs a pixmap from the TQImage \a image.
+
+ \sa convertFromImage()
+*/
+
+TQPixmap::TQPixmap( const TQImage& image )
+ : TQPaintDevice( TQInternal::Pixmap )
+{
+ init( 0, 0, 0, FALSE, defOptim );
+ convertFromImage( image );
+}
+
+/*!
+ Constructs a pixmap with \a w width, \a h height and \a depth bits
+ per pixel. The pixmap is optimized in accordance with the \a
+ optimization value.
+
+ The contents of the pixmap is uninitialized.
+
+ The \a depth can be either 1 (monochrome) or the depth of the
+ current video mode. If \a depth is negative, then the hardware
+ depth of the current video mode will be used.
+
+ If either \a w or \a h is zero, a null pixmap is constructed.
+
+ \sa isNull() TQPixmap::Optimization
+*/
+
+TQPixmap::TQPixmap( int w, int h, int depth, Optimization optimization )
+ : TQPaintDevice( TQInternal::Pixmap )
+{
+ init( w, h, depth, FALSE, optimization );
+}
+
+/*!
+ \overload TQPixmap::TQPixmap( const TQSize &size, int depth, Optimization optimization )
+
+ Constructs a pixmap of size \a size, \a depth bits per pixel,
+ optimized in accordance with the \a optimization value.
+*/
+
+TQPixmap::TQPixmap( const TQSize &size, int depth, Optimization optimization )
+ : TQPaintDevice( TQInternal::Pixmap )
+{
+ init( size.width(), size.height(), depth, FALSE, optimization );
+}
+
+#ifndef TQT_NO_IMAGEIO
+/*!
+ Constructs a pixmap from the file \a fileName. If the file does
+ not exist or is of an unknown format, the pixmap becomes a null
+ pixmap.
+
+ The \a fileName, \a format and \a conversion_flags parameters are
+ passed on to load(). This means that the data in \a fileName is
+ not compiled into the binary. If \a fileName tqcontains a relative
+ path (e.g. the filename only) the relevant file must be found
+ relative to the runtime working directory.
+
+ If the image needs to be modified to fit in a lower-resolution
+ result (e.g. converting from 32-bit to 8-bit), use the \a
+ conversion_flags to specify how you'd prefer this to happen.
+
+ \sa TQt::ImageConversionFlags isNull(), load(), loadFromData(), save(), imageFormat()
+*/
+
+TQPixmap::TQPixmap( const TQString& fileName, const char *format,
+ int conversion_flags )
+ : TQPaintDevice( TQInternal::Pixmap )
+{
+ init( 0, 0, 0, FALSE, defOptim );
+ load( fileName, format, conversion_flags );
+}
+
+/*!
+ Constructs a pixmap from the file \a fileName. If the file does
+ not exist or is of an unknown format, the pixmap becomes a null
+ pixmap.
+
+ The \a fileName, \a format and \a mode parameters are passed on to
+ load(). This means that the data in \a fileName is not compiled
+ into the binary. If \a fileName tqcontains a relative path (e.g. the
+ filename only) the relevant file must be found relative to the
+ runtime working directory.
+
+ \sa TQPixmap::ColorMode isNull(), load(), loadFromData(), save(), imageFormat()
+*/
+
+TQPixmap::TQPixmap( const TQString& fileName, const char *format, ColorMode mode )
+ : TQPaintDevice( TQInternal::Pixmap )
+{
+ init( 0, 0, 0, FALSE, defOptim );
+ load( fileName, format, mode );
+}
+
+/*!
+ Constructs a pixmap from \a xpm, which must be a valid XPM image.
+
+ Errors are silently ignored.
+
+ Note that it's possible to squeeze the XPM variable a little bit
+ by using an unusual declaration:
+
+ \code
+ static const char * const start_xpm[]={
+ "16 15 8 1",
+ "a c #cec6bd",
+ ....
+ \endcode
+
+ The extra \c const makes the entire definition read-only, which is
+ slightly more efficient (for example, when the code is in a shared
+ library) and ROMable when the application is to be stored in ROM.
+
+ In order to use that sort of declaration you must cast the
+ variable back to \c{const char **} when you create the TQPixmap.
+*/
+
+TQPixmap::TQPixmap( const char *xpm[] )
+ : TQPaintDevice( TQInternal::Pixmap )
+{
+ init( 0, 0, 0, FALSE, defOptim );
+ TQImage image( xpm );
+ if ( !image.isNull() )
+ convertFromImage( image );
+}
+
+/*!
+ Constructs a pixmaps by loading from \a img_data. The data can be
+ in any image format supported by TQt.
+
+ \sa loadFromData()
+*/
+
+TQPixmap::TQPixmap( const TQByteArray & img_data )
+ : TQPaintDevice( TQInternal::Pixmap )
+{
+ init( 0, 0, 0, FALSE, defOptim );
+ loadFromData( img_data );
+}
+#endif //TQT_NO_IMAGEIO
+
+/*!
+ Constructs a pixmap that is a copy of \a pixmap.
+*/
+
+TQPixmap::TQPixmap( const TQPixmap &pixmap )
+ : TQPaintDevice( TQInternal::Pixmap )
+{
+ if ( pixmap.paintingActive() ) { // make a deep copy
+ data = 0;
+ operator=( pixmap.copy() );
+ } else {
+ data = pixmap.data;
+ data->ref();
+ devFlags = pixmap.devFlags; // copy TQPaintDevice flags
+#if defined(TQ_WS_WIN)
+ hdc = pixmap.hdc; // copy Windows tqdevice context
+#elif defined(TQ_WS_X11)
+ hd = pixmap.hd; // copy X11 drawable
+ rendhd = pixmap.rendhd;
+ copyX11Data( &pixmap ); // copy x11Data
+#elif defined(TQ_WS_MAC)
+ hd = pixmap.hd;
+#endif
+ }
+}
+
+
+/*!
+ Destroys the pixmap.
+*/
+
+TQPixmap::~TQPixmap()
+{
+ deref();
+}
+
+/*! Convenience function. Gets the data associated with the absolute
+ name \a abs_name from the default mime source factory and decodes it
+ to a pixmap.
+
+ \sa TQMimeSourceFactory, TQImage::fromMimeSource(), TQImageDrag::decode()
+*/
+
+#ifndef TQT_NO_MIME
+TQPixmap TQPixmap::fromMimeSource( const TQString &abs_name )
+{
+ const TQMimeSource *m = TQMimeSourceFactory::defaultFactory()->data( abs_name );
+ if ( !m ) {
+ if ( TQFile::exists( abs_name ) )
+ return TQPixmap( abs_name );
+#if defined(TQT_CHECK_STATE)
+ if ( !abs_name.isEmpty() )
+ qWarning( "TQPixmap::fromMimeSource: Cannot find pixmap \"%s\" in the mime source factory",
+ abs_name.latin1() );
+#endif
+ return TQPixmap();
+ }
+ TQPixmap pix;
+ TQImageDrag::decode( m, pix );
+ return pix;
+}
+#endif
+
+/*!
+ Returns a \link shclass.html deep copy\endlink of the pixmap using
+ the bitBlt() function to copy the pixels.
+
+ \sa operator=()
+*/
+
+TQPixmap TQPixmap::copy( bool ignoreMask ) const
+{
+#if defined(TQ_WS_X11)
+ int old = x11SetDefaultScreen( x11Screen() );
+#endif // TQ_WS_X11
+
+ TQPixmap pm( data->w, data->h, data->d, data->bitmap, data->optim );
+
+ if ( !pm.isNull() ) { // copy the bitmap
+#if defined(TQ_WS_X11)
+ pm.cloneX11Data( this );
+#endif // TQ_WS_X11
+
+ if ( ignoreMask )
+ bitBlt( &pm, 0, 0, this, 0, 0, data->w, data->h, TQt::CopyROP, TRUE );
+ else
+ copyBlt( &pm, 0, 0, this, 0, 0, data->w, data->h );
+ }
+
+#if defined(TQ_WS_X11)
+ x11SetDefaultScreen( old );
+#endif // TQ_WS_X11
+
+ return pm;
+}
+
+
+/*!
+ Assigns the pixmap \a pixmap to this pixmap and returns a
+ reference to this pixmap.
+*/
+
+TQPixmap &TQPixmap::operator=( const TQPixmap &pixmap )
+{
+ if ( paintingActive() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQPixmap::operator=: Cannot assign to pixmap during painting");
+#endif
+ return *this;
+ }
+ pixmap.data->ref(); // avoid 'x = x'
+ deref();
+ if ( pixmap.paintingActive() ) { // make a deep copy
+ init( pixmap.width(), pixmap.height(), pixmap.depth(),
+ pixmap.data->bitmap, pixmap.data->optim );
+ data->uninit = FALSE;
+ if ( !isNull() )
+ copyBlt( this, 0, 0, &pixmap, 0, 0, pixmap.width(), pixmap.height() );
+ pixmap.data->deref();
+ } else {
+ data = pixmap.data;
+ devFlags = pixmap.devFlags; // copy TQPaintDevice flags
+#if defined(TQ_WS_WIN)
+ hdc = pixmap.hdc;
+#elif defined(TQ_WS_X11)
+ hd = pixmap.hd; // copy TQPaintDevice drawable
+ rendhd = pixmap.rendhd;
+ copyX11Data( &pixmap ); // copy x11Data
+#elif defined(TQ_WS_MACX) || defined(TQ_OS_MAC9)
+ hd = pixmap.hd;
+#endif
+ }
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Converts the image \a image to a pixmap that is assigned to this
+ pixmap. Returns a reference to the pixmap.
+
+ \sa convertFromImage().
+*/
+
+TQPixmap &TQPixmap::operator=( const TQImage &image )
+{
+ convertFromImage( image );
+ return *this;
+}
+
+
+/*!
+ \fn bool TQPixmap::isTQBitmap() const
+
+ Returns TRUE if this is a TQBitmap; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQPixmap::isNull() const
+
+ Returns TRUE if this is a null pixmap; otherwise returns FALSE.
+
+ A null pixmap has zero width, zero height and no contents. You
+ cannot draw in a null pixmap or bitBlt() anything to it.
+
+ Resizing an existing pixmap to (0, 0) makes a pixmap into a null
+ pixmap.
+
+ \sa resize()
+*/
+
+/*!
+ \fn int TQPixmap::width() const
+
+ Returns the width of the pixmap.
+
+ \sa height(), size(), rect()
+*/
+
+/*!
+ \fn int TQPixmap::height() const
+
+ Returns the height of the pixmap.
+
+ \sa width(), size(), rect()
+*/
+
+/*!
+ \fn TQSize TQPixmap::size() const
+
+ Returns the size of the pixmap.
+
+ \sa width(), height(), rect()
+*/
+
+/*!
+ \fn TQRect TQPixmap::rect() const
+
+ Returns the enclosing rectangle (0,0,width(),height()) of the pixmap.
+
+ \sa width(), height(), size()
+*/
+
+/*!
+ \fn int TQPixmap::depth() const
+
+ Returns the depth of the pixmap.
+
+ The pixmap depth is also called bits per pixel (bpp) or bit planes
+ of a pixmap. A null pixmap has depth 0.
+
+ \sa defaultDepth(), isNull(), TQImage::convertDepth()
+*/
+
+
+/*!
+ \overload void TQPixmap::fill( const TQWidget *widget, const TQPoint &ofs )
+
+ Fills the pixmap with the \a widget's background color or pixmap.
+ If the background is empty, nothing is done.
+
+ The \a ofs point is an offset in the widget.
+
+ The point \a ofs is a point in the widget's coordinate system. The
+ pixmap's top-left pixel will be mapped to the point \a ofs in the
+ widget. This is significant if the widget has a background pixmap;
+ otherwise the pixmap will simply be filled with the background
+ color of the widget.
+
+ Example:
+ \code
+ void CuteWidget::paintEvent( TQPaintEvent *e )
+ {
+ TQRect ur = e->rect(); // rectangle to update
+ TQPixmap pix( ur.size() ); // Pixmap for double-buffering
+ pix.fill( this, ur.topLeft() ); // fill with widget background
+
+ TQPainter p( &pix );
+ p.translate( -ur.x(), -ur.y() ); // use widget coordinate system
+ // when drawing on pixmap
+ // ... draw on pixmap ...
+
+ p.end();
+
+ bitBlt( this, ur.topLeft(), &pix );
+ }
+ \endcode
+*/
+
+/*!
+ \overload void TQPixmap::fill( const TQWidget *widget, int xofs, int yofs )
+
+ Fills the pixmap with the \a widget's background color or pixmap.
+ If the background is empty, nothing is done. \a xofs, \a yofs is
+ an offset in the widget.
+*/
+
+void TQPixmap::fill( const TQWidget *widget, int xofs, int yofs )
+{
+ const TQPixmap* bgpm = widget->backgroundPixmap();
+ fill( widget->backgroundColor() );
+ if ( bgpm ) {
+ if ( !bgpm->isNull() ) {
+ TQPoint ofs = widget->backgroundOffset();
+ xofs += ofs.x();
+ yofs += ofs.y();
+
+ TQPainter p;
+ p.begin( this );
+ p.setPen( NoPen );
+ p.drawTiledPixmap( 0, 0, width(), height(), *widget->backgroundPixmap(), xofs, yofs );
+ p.end();
+ }
+ }
+}
+
+
+/*!
+ \overload void TQPixmap::resize( const TQSize &size )
+
+ Resizes the pixmap to size \a size.
+*/
+
+/*!
+ Resizes the pixmap to \a w width and \a h height. If either \a w
+ or \a h is 0, the pixmap becomes a null pixmap.
+
+ If both \a w and \a h are greater than 0, a valid pixmap is
+ created. New pixels will be uninitialized (random) if the pixmap
+ is expanded.
+*/
+
+void TQPixmap::resize( int w, int h )
+{
+ if ( w < 1 || h < 1 ) { // becomes null
+ TQPixmap pm( 0, 0, 0, data->bitmap, data->optim );
+ *this = pm;
+ return;
+ }
+ int d;
+ if ( depth() > 0 )
+ d = depth();
+ else
+ d = isTQBitmap() ? 1 : -1;
+ // Create new pixmap
+ TQPixmap pm( w, h, d, data->bitmap, data->optim );
+#ifdef TQ_WS_X11
+ pm.x11SetScreen( x11Screen() );
+#endif // TQ_WS_X11
+ if ( !data->uninit && !isNull() ) // has existing pixmap
+ bitBlt( &pm, 0, 0, this, 0, 0, // copy old pixmap
+ TQMIN(width(), w),
+ TQMIN(height(),h), CopyROP, TRUE );
+#if defined(TQ_WS_MAC)
+ if(data->alphapm) {
+ data->alphapm->resize(w, h);
+ } else
+#elif defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)
+ if (data->alphapm)
+ qWarning("TQPixmap::resize: TODO: resize alpha data");
+ else
+#endif // TQ_WS_X11
+ if ( data->tqmask ) { // resize tqmask as well
+ if ( data->selfmask ) { // preserve self-tqmask
+ pm.setMask( *((TQBitmap*)&pm) );
+ } else { // independent tqmask
+ TQBitmap m = *data->tqmask;
+ m.resize( w, h );
+ pm.setMask( m );
+ }
+ }
+ *this = pm;
+}
+
+
+/*!
+ \fn const TQBitmap *TQPixmap::tqmask() const
+
+ Returns the tqmask bitmap, or 0 if no tqmask has been set.
+
+ \sa setMask(), TQBitmap, hasAlpha()
+*/
+
+/*!
+ Sets a tqmask bitmap.
+
+ The \a newtqmask bitmap defines the clip tqmask for this pixmap. Every
+ pixel in \a newtqmask corresponds to a pixel in this pixmap. Pixel
+ value 1 means opaque and pixel value 0 means transtqparent. The tqmask
+ must have the same size as this pixmap.
+
+ \warning Setting the tqmask on a pixmap will cause any alpha channel
+ data to be cleared. For example:
+ \code
+ TQPixmap alpha( "image-with-alpha.png" );
+ TQPixmap alphacopy = alpha;
+ alphacopy.setMask( *alphacopy.tqmask() );
+ \endcode
+ Now, alpha and alphacopy are visually different.
+
+ Setting a \link isNull() null\endlink tqmask resets the tqmask.
+
+ \sa tqmask(), createHeuristicMask(), TQBitmap
+*/
+
+void TQPixmap::setMask( const TQBitmap &newtqmask )
+{
+ const TQPixmap *tmp = &newtqmask; // dec cxx bug
+ if ( (data == tmp->data) ||
+ ( newtqmask.handle() && newtqmask.handle() == handle() ) ) {
+ TQPixmap m = tmp->copy( TRUE );
+ setMask( *((TQBitmap*)&m) );
+ data->selfmask = TRUE; // tqmask == pixmap
+ return;
+ }
+
+ if ( newtqmask.isNull() ) { // reset the tqmask
+ if (data->tqmask) {
+ detach();
+ data->selfmask = FALSE;
+
+ delete data->tqmask;
+ data->tqmask = 0;
+ }
+ return;
+ }
+
+ detach();
+ data->selfmask = FALSE;
+
+ if ( newtqmask.width() != width() || newtqmask.height() != height() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPixmap::setMask: The pixmap and the tqmask must have "
+ "the same size" );
+#endif
+ return;
+ }
+#if defined(TQ_WS_MAC) || (defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE))
+ // when setting the tqmask, we get rid of the alpha channel completely
+ delete data->alphapm;
+ data->alphapm = 0;
+#endif // TQ_WS_X11 && !TQT_NO_XFTFREETYPE
+
+ delete data->tqmask;
+ TQBitmap* newmaskcopy;
+ if ( newtqmask.tqmask() )
+ newmaskcopy = (TQBitmap*)new TQPixmap( tmp->copy( TRUE ) );
+ else
+ newmaskcopy = new TQBitmap( newtqmask );
+#ifdef TQ_WS_X11
+ newmaskcopy->x11SetScreen( x11Screen() );
+#endif
+ data->tqmask = newmaskcopy;
+}
+
+
+/*!
+ \fn bool TQPixmap::selfMask() const
+
+ Returns TRUE if the pixmap's tqmask is identical to the pixmap
+ itself; otherwise returns FALSE.
+
+ \sa tqmask()
+*/
+
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+/*!
+ Creates and returns a heuristic tqmask for this pixmap. It works by
+ selecting a color from one of the corners and then chipping away
+ pixels of that color, starting at all the edges.
+
+ The tqmask may not be perfect but it should be reasonable, so you
+ can do things such as the following:
+ \code
+ pm->setMask( pm->createHeuristicMask() );
+ \endcode
+
+ This function is slow because it involves transformation to a
+ TQImage, non-trivial computations and a transformation back to a
+ TQBitmap.
+
+ If \a clipTight is TRUE the tqmask is just large enough to cover the
+ pixels; otherwise, the tqmask is larger than the data pixels.
+
+ \sa TQImage::createHeuristicMask()
+*/
+
+TQBitmap TQPixmap::createHeuristicMask( bool clipTight ) const
+{
+ TQBitmap m;
+ m.convertFromImage( convertToImage().createHeuristicMask(clipTight) );
+ return m;
+}
+#endif
+#ifndef TQT_NO_IMAGEIO
+/*!
+ Returns a string that specifies the image format of the file \a
+ fileName, or 0 if the file cannot be read or if the format cannot
+ be recognized.
+
+ The TQImageIO documentation lists the supported image formats.
+
+ \sa load(), save()
+*/
+
+const char* TQPixmap::imageFormat( const TQString &fileName )
+{
+ return TQImageIO::imageFormat(fileName);
+}
+
+/*!
+ Loads a pixmap from the file \a fileName at runtime. Returns TRUE
+ if successful; otherwise returns FALSE.
+
+ If \a format is specified, the loader attempts to read the pixmap
+ using the specified format. If \a format is not specified
+ (default), the loader reads a few bytes from the header to guess
+ the file's format.
+
+ See the convertFromImage() documentation for a description of the
+ \a conversion_flags argument.
+
+ The TQImageIO documentation lists the supported image formats and
+ explains how to add extra formats.
+
+ \sa loadFromData(), save(), imageFormat(), TQImage::load(),
+ TQImageIO
+*/
+
+bool TQPixmap::load( const TQString &fileName, const char *format,
+ int conversion_flags )
+{
+ TQImageIO io( fileName, format );
+ bool result = io.read();
+ if ( result ) {
+ detach(); // ###hanord: Why detach here, convertFromImage does it
+ result = convertFromImage( io.image(), conversion_flags );
+ }
+ return result;
+}
+
+/*!
+ \overload
+
+ Loads a pixmap from the file \a fileName at runtime.
+
+ If \a format is specified, the loader attempts to read the pixmap
+ using the specified format. If \a format is not specified
+ (default), the loader reads a few bytes from the header to guess
+ the file's format.
+
+ The \a mode is used to specify the color mode of the pixmap.
+
+ \sa TQPixmap::ColorMode
+*/
+
+bool TQPixmap::load( const TQString &fileName, const char *format,
+ ColorMode mode )
+{
+ int conversion_flags = 0;
+ switch (mode) {
+ case Color:
+ conversion_flags |= ColorOnly;
+ break;
+ case Mono:
+ conversion_flags |= MonoOnly;
+ break;
+ default:
+ break;// Nothing.
+ }
+ return load( fileName, format, conversion_flags );
+}
+#endif //TQT_NO_IMAGEIO
+
+/*!
+ \overload
+
+ Converts \a image and sets this pixmap using color mode \a mode.
+ Returns TRUE if successful; otherwise returns FALSE.
+
+ \sa TQPixmap::ColorMode
+*/
+
+bool TQPixmap::convertFromImage( const TQImage &image, ColorMode mode )
+{
+ if ( image.isNull() ) {
+ // convert null image to null pixmap
+ *this = TQPixmap();
+ return TRUE;
+ }
+
+ int conversion_flags = 0;
+ switch (mode) {
+ case Color:
+ conversion_flags |= ColorOnly;
+ break;
+ case Mono:
+ conversion_flags |= MonoOnly;
+ break;
+ default:
+ break;// Nothing.
+ }
+ return convertFromImage( image, conversion_flags );
+}
+
+#ifndef TQT_NO_IMAGEIO
+/*!
+ Loads a pixmap from the binary data in \a buf (\a len bytes).
+ Returns TRUE if successful; otherwise returns FALSE.
+
+ If \a format is specified, the loader attempts to read the pixmap
+ using the specified format. If \a format is not specified
+ (default), the loader reads a few bytes from the header to guess
+ the file's format.
+
+ See the convertFromImage() documentation for a description of the
+ \a conversion_flags argument.
+
+ The TQImageIO documentation lists the supported image formats and
+ explains how to add extra formats.
+
+ \sa load(), save(), imageFormat(), TQImage::loadFromData(),
+ TQImageIO
+*/
+
+bool TQPixmap::loadFromData( const uchar *buf, uint len, const char *format,
+ int conversion_flags )
+{
+ TQByteArray a;
+ a.setRawData( (char *)buf, len );
+ TQBuffer b( a );
+ b.open( IO_ReadOnly );
+ TQImageIO io( &b, format );
+ bool result = io.read();
+ b.close();
+ a.resetRawData( (char *)buf, len );
+ if ( result ) {
+ detach();
+ result = convertFromImage( io.image(), conversion_flags );
+ }
+ return result;
+}
+
+/*!
+ \overload
+
+ Loads a pixmap from the binary data in \a buf (\a len bytes) using
+ color mode \a mode. Returns TRUE if successful; otherwise returns
+ FALSE.
+
+ If \a format is specified, the loader attempts to read the pixmap
+ using the specified format. If \a format is not specified
+ (default), the loader reads a few bytes from the header to guess
+ the file's format.
+
+ \sa TQPixmap::ColorMode
+*/
+
+bool TQPixmap::loadFromData( const uchar *buf, uint len, const char *format,
+ ColorMode mode )
+{
+ int conversion_flags = 0;
+ switch (mode) {
+ case Color:
+ conversion_flags |= ColorOnly;
+ break;
+ case Mono:
+ conversion_flags |= MonoOnly;
+ break;
+ default:
+ break;// Nothing.
+ }
+ return loadFromData( buf, len, format, conversion_flags );
+}
+
+/*!
+ \overload
+*/
+
+bool TQPixmap::loadFromData( const TQByteArray &buf, const char *format,
+ int conversion_flags )
+{
+ return loadFromData( (const uchar *)(buf.data()), buf.size(),
+ format, conversion_flags );
+}
+
+
+/*!
+ Saves the pixmap to the file \a fileName using the image file
+ format \a format and a quality factor \a quality. \a quality must
+ be in the range [0,100] or -1. Specify 0 to obtain small
+ compressed files, 100 for large uncompressed files, and -1 to use
+ the default settings. Returns TRUE if successful; otherwise
+ returns FALSE.
+
+ \sa load(), loadFromData(), imageFormat(), TQImage::save(),
+ TQImageIO
+*/
+
+bool TQPixmap::save( const TQString &fileName, const char *format, int quality ) const
+{
+ if ( isNull() )
+ return FALSE; // nothing to save
+ TQImageIO io( fileName, format );
+ return doImageIO( &io, quality );
+}
+
+/*!
+ \overload
+
+ This function writes a TQPixmap to the TQIODevice, \a tqdevice. This
+ can be used, for example, to save a pixmap directly into a
+ TQByteArray:
+ \code
+ TQPixmap pixmap;
+ TQByteArray ba;
+ TQBuffer buffer( ba );
+ buffer.open( IO_WriteOnly );
+ pixmap.save( &buffer, "PNG" ); // writes pixmap into ba in PNG format
+ \endcode
+*/
+
+bool TQPixmap::save( TQIODevice* tqdevice, const char* format, int quality ) const
+{
+ if ( isNull() )
+ return FALSE; // nothing to save
+ TQImageIO io( tqdevice, format );
+ return doImageIO( &io, quality );
+}
+
+/*! \internal
+*/
+
+bool TQPixmap::doImageIO( TQImageIO* io, int quality ) const
+{
+ if ( !io )
+ return FALSE;
+ io->setImage( convertToImage() );
+#if defined(TQT_CHECK_RANGE)
+ if ( quality > 100 || quality < -1 )
+ qWarning( "TQPixmap::save: quality out of range [-1,100]" );
+#endif
+ if ( quality >= 0 )
+ io->setQuality( TQMIN(quality,100) );
+ return io->write();
+}
+
+#endif //TQT_NO_IMAGEIO
+
+/*!
+ \fn int TQPixmap::serialNumber() const
+
+ Returns a number that uniquely identifies the contents of this
+ TQPixmap object. This means that multiple TQPixmap objects can have
+ the same serial number as long as they refer to the same contents.
+
+ An example of where this is useful is for caching TQPixmaps.
+
+ \sa TQPixmapCache
+*/
+
+
+/*!
+ Returns the default pixmap optimization setting.
+
+ \sa setDefaultOptimization(), setOptimization(), optimization()
+*/
+
+TQPixmap::Optimization TQPixmap::defaultOptimization()
+{
+ return defOptim;
+}
+
+/*!
+ Sets the default pixmap optimization.
+
+ All \e new pixmaps that are created will use this default
+ optimization. You may also set optimization for individual pixmaps
+ using the setOptimization() function.
+
+ The initial default \a optimization setting is \c TQPixmap::Normal.
+
+ \sa defaultOptimization(), setOptimization(), optimization()
+*/
+
+void TQPixmap::setDefaultOptimization( Optimization optimization )
+{
+ if ( optimization != DefaultOptim )
+ defOptim = optimization;
+}
+
+
+// helper for next function.
+static TQPixmap grabChildWidgets( TQWidget * w )
+{
+ TQPixmap res( w->width(), w->height() );
+ if ( res.isNull() && w->width() )
+ return res;
+ res.fill( w, TQPoint( 0, 0 ) );
+ TQPaintDevice *oldRedirect = TQPainter::redirect( w );
+ TQPainter::redirect( w, &res );
+ bool dblbfr = TQSharedDoubleBuffer::isDisabled();
+ TQSharedDoubleBuffer::setDisabled( TRUE );
+ TQPaintEvent e( w->rect(), FALSE );
+ TQApplication::sendEvent( w, &e );
+ TQSharedDoubleBuffer::setDisabled( dblbfr );
+ TQPainter::redirect( w, oldRedirect );
+
+ if ( !w->childrenListObject().isEmpty() ) {
+ TQPainter p( &res );
+ TQObjectListIt it( w->childrenListObject() );
+ TQObject * child;
+ while( (child=it.current()) != 0 ) {
+ ++it;
+ if ( child->isWidgetType() &&
+ !((TQWidget *)child)->isHidden() &&
+ !((TQWidget *)child)->isTopLevel() &&
+ ((TQWidget *)child)->tqgeometry().intersects( w->rect() ) ) {
+ // those conditions aren't quite right, it's possible
+ // to have a grandchild completely outside its
+ // grandtqparent, but partially inside its tqparent. no
+ // point in optimizing for that.
+
+ // make sure to evaluate pos() first - who knows what
+ // the paint event(s) inside grabChildWidgets() will do.
+ TQPoint childpos = ((TQWidget *)child)->pos();
+ TQPixmap cpm = grabChildWidgets( (TQWidget *)child );
+ if ( cpm.isNull() ) {
+ // Some child pixmap failed - abort and reset
+ res.resize( 0, 0 );
+ break;
+ }
+ p.drawPixmap( childpos, cpm);
+ }
+ }
+ }
+ return res;
+}
+
+
+/*!
+ Creates a pixmap and paints \a widget in it.
+
+ If the \a widget has any tqchildren, then they are also painted in
+ the appropriate positions.
+
+ If you specify \a x, \a y, \a w or \a h, only the rectangle you
+ specify is painted. The defaults are 0, 0 (top-left corner) and
+ -1,-1 (which means the entire widget).
+
+ (If \a w is negative, the function copies everything to the right
+ border of the window. If \a h is negative, the function copies
+ everything to the bottom of the window.)
+
+ If \a widget is 0, or if the rectangle defined by \a x, \a y, the
+ modified \a w and the modified \a h does not overlap the \a
+ {widget}->rect(), this function will return a null TQPixmap.
+
+ This function actually asks \a widget to paint itself (and its
+ tqchildren to paint themselves). TQPixmap::grabWindow() grabs pixels
+ off the screen, which is a bit faster and picks up \e exactly
+ what's on-screen. This function works by calling paintEvent() with
+ painter redirection turned on. If there are overlaying windows,
+ grabWindow() will see them, but not this function.
+
+ If there is overlap, it returns a pixmap of the size you want,
+ containing a rendering of \a widget. If the rectangle you ask for
+ is a superset of \a widget, the areas outside \a widget are
+ covered with the widget's background.
+
+ If an error occurs when trying to grab the widget, such as the
+ size of the widget being too large to fit in memory, an isNull()
+ pixmap is returned.
+
+ \sa grabWindow() TQPainter::redirect() TQWidget::paintEvent()
+*/
+
+TQPixmap TQPixmap::grabWidget( TQWidget * widget, int x, int y, int w, int h )
+{
+ TQPixmap res;
+ if ( !widget )
+ return res;
+
+ if ( w < 0 )
+ w = widget->width() - x;
+ if ( h < 0 )
+ h = widget->height() - y;
+
+ TQRect wr( x, y, w, h );
+ if ( wr == widget->rect() )
+ return grabChildWidgets( widget );
+ if ( !wr.intersects( widget->rect() ) )
+ return res;
+
+ res.resize( w, h );
+ if( res.isNull() )
+ return res;
+ res.fill( widget, TQPoint( w,h ) );
+ TQPixmap tmp( grabChildWidgets( widget ) );
+ if( tmp.isNull() )
+ return tmp;
+ ::bitBlt( &res, 0, 0, &tmp, x, y, w, h );
+ return res;
+}
+
+/*!
+ Returns the actual matrix used for transforming a pixmap with \a w
+ width and \a h height and matrix \a matrix.
+
+ When transforming a pixmap with xForm(), the transformation matrix
+ is internally adjusted to compensate for unwanted translation,
+ i.e. xForm() returns the smallest pixmap containing all
+ transformed points of the original pixmap.
+
+ This function returns the modified matrix, which maps points
+ correctly from the original pixmap into the new pixmap.
+
+ \sa xForm(), TQWMatrix
+*/
+#ifndef TQT_NO_PIXMAP_TRANSFORMATION
+TQWMatrix TQPixmap::trueMatrix( const TQWMatrix &matrix, int w, int h )
+{
+ const double dt = (double)0.;
+ double x1,y1, x2,y2, x3,y3, x4,y4; // get corners
+ double xx = (double)w;
+ double yy = (double)h;
+
+ TQWMatrix mat( matrix.m11(), matrix.m12(), matrix.m21(), matrix.m22(), 0., 0. );
+
+ mat.map( dt, dt, &x1, &y1 );
+ mat.map( xx, dt, &x2, &y2 );
+ mat.map( xx, yy, &x3, &y3 );
+ mat.map( dt, yy, &x4, &y4 );
+
+ double ymin = y1; // lowest y value
+ if ( y2 < ymin ) ymin = y2;
+ if ( y3 < ymin ) ymin = y3;
+ if ( y4 < ymin ) ymin = y4;
+ double xmin = x1; // lowest x value
+ if ( x2 < xmin ) xmin = x2;
+ if ( x3 < xmin ) xmin = x3;
+ if ( x4 < xmin ) xmin = x4;
+
+ double ymax = y1; // lowest y value
+ if ( y2 > ymax ) ymax = y2;
+ if ( y3 > ymax ) ymax = y3;
+ if ( y4 > ymax ) ymax = y4;
+ double xmax = x1; // lowest x value
+ if ( x2 > xmax ) xmax = x2;
+ if ( x3 > xmax ) xmax = x3;
+ if ( x4 > xmax ) xmax = x4;
+
+ if ( xmax-xmin > 1.0 )
+ xmin -= xmin/(xmax-xmin);
+ if ( ymax-ymin > 1.0 )
+ ymin -= ymin/(ymax-ymin);
+
+ mat.setMatrix( matrix.m11(), matrix.m12(), matrix.m21(), matrix.m22(), -xmin, -ymin );
+ return mat;
+}
+#endif // TQT_NO_WMATRIX
+
+
+
+
+
+/*****************************************************************************
+ TQPixmap stream functions
+ *****************************************************************************/
+#if !defined(TQT_NO_DATASTREAM) && !defined(TQT_NO_IMAGEIO)
+/*!
+ \relates TQPixmap
+
+ Writes the pixmap \a pixmap to the stream \a s as a PNG image.
+
+ Note that writing the stream to a file will not produce a valid image file.
+
+ \sa TQPixmap::save()
+ \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQPixmap &pixmap )
+{
+ s << pixmap.convertToImage();
+ return s;
+}
+
+/*!
+ \relates TQPixmap
+
+ Reads a pixmap from the stream \a s into the pixmap \a pixmap.
+
+ \sa TQPixmap::load()
+ \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQPixmap &pixmap )
+{
+ TQImage img;
+ s >> img;
+ pixmap.convertFromImage( img );
+ return s;
+}
+
+#endif //TQT_NO_DATASTREAM
+
+
+
+
+/*****************************************************************************
+ TQPixmap (and TQImage) helper functions
+ *****************************************************************************/
+/*
+ This internal function tqcontains the common (i.e. platform independent) code
+ to do a transformation of pixel data. It is used by TQPixmap::xForm() and by
+ TQImage::xForm().
+
+ \a trueMat is the true transformation matrix (see TQPixmap::trueMatrix()) and
+ \a xoffset is an offset to the matrix.
+
+ \a msbfirst specifies for 1bpp images, if the MSB or LSB comes first and \a
+ depth specifies the colordepth of the data.
+
+ \a dptr is a pointer to the destination data, \a dbpl specifies the bits per
+ line for the destination data, \a p_inc is the offset that we advance for
+ every scanline and \a dHeight is the height of the destination image.
+
+ \a sprt is the pointer to the source data, \a sbpl specifies the bits per
+ line of the source data, \a sWidth and \a sHeight are the width and height of
+ the source data.
+*/
+#ifndef TQT_NO_PIXMAP_TRANSFORMATION
+#undef IWX_MSB
+#define IWX_MSB(b) if ( trigx < maxws && trigy < maxhs ) { \
+ if ( *(sptr+sbpl*(trigy>>16)+(trigx>>19)) & \
+ (1 << (7-((trigx>>16)&7))) ) \
+ *dptr |= b; \
+ } \
+ trigx += m11; \
+ trigy += m12;
+ // END OF MACRO
+#undef IWX_LSB
+#define IWX_LSB(b) if ( trigx < maxws && trigy < maxhs ) { \
+ if ( *(sptr+sbpl*(trigy>>16)+(trigx>>19)) & \
+ (1 << ((trigx>>16)&7)) ) \
+ *dptr |= b; \
+ } \
+ trigx += m11; \
+ trigy += m12;
+ // END OF MACRO
+#undef IWX_PIX
+#define IWX_PIX(b) if ( trigx < maxws && trigy < maxhs ) { \
+ if ( (*(sptr+sbpl*(trigy>>16)+(trigx>>19)) & \
+ (1 << (7-((trigx>>16)&7)))) == 0 ) \
+ *dptr &= ~b; \
+ } \
+ trigx += m11; \
+ trigy += m12;
+ // END OF MACRO
+bool qt_xForm_helper( const TQWMatrix &trueMat, int xoffset,
+ int type, int depth,
+ uchar *dptr, int dbpl, int p_inc, int dHeight,
+ uchar *sptr, int sbpl, int sWidth, int sHeight
+ )
+{
+ int m11 = int(trueMat.m11()*65536.0 + 1.);
+ int m12 = int(trueMat.m12()*65536.0 + 1.);
+ int m21 = int(trueMat.m21()*65536.0 + 1.);
+ int m22 = int(trueMat.m22()*65536.0 + 1.);
+ int dx = tqRound(trueMat.dx() *65536.0);
+ int dy = tqRound(trueMat.dy() *65536.0);
+
+ int m21ydx = dx + (xoffset<<16);
+ int m22ydy = dy;
+ uint trigx;
+ uint trigy;
+ uint maxws = sWidth<<16;
+ uint maxhs = sHeight<<16;
+
+ for ( int y=0; y<dHeight; y++ ) { // for each target scanline
+ trigx = m21ydx;
+ trigy = m22ydy;
+ uchar *maxp = dptr + dbpl;
+ if ( depth != 1 ) {
+ switch ( depth ) {
+ case 8: // 8 bpp transform
+ while ( dptr < maxp ) {
+ if ( trigx < maxws && trigy < maxhs )
+ *dptr = *(sptr+sbpl*(trigy>>16)+(trigx>>16));
+ trigx += m11;
+ trigy += m12;
+ dptr++;
+ }
+ break;
+
+ case 16: // 16 bpp transform
+ while ( dptr < maxp ) {
+ if ( trigx < maxws && trigy < maxhs )
+ *((ushort*)dptr) = *((ushort *)(sptr+sbpl*(trigy>>16) +
+ ((trigx>>16)<<1)));
+ trigx += m11;
+ trigy += m12;
+ dptr++;
+ dptr++;
+ }
+ break;
+
+ case 24: { // 24 bpp transform
+ uchar *p2;
+ while ( dptr < maxp ) {
+ if ( trigx < maxws && trigy < maxhs ) {
+ p2 = sptr+sbpl*(trigy>>16) + ((trigx>>16)*3);
+ dptr[0] = p2[0];
+ dptr[1] = p2[1];
+ dptr[2] = p2[2];
+ }
+ trigx += m11;
+ trigy += m12;
+ dptr += 3;
+ }
+ }
+ break;
+
+ case 32: // 32 bpp transform
+ while ( dptr < maxp ) {
+ if ( trigx < maxws && trigy < maxhs )
+ *((uint*)dptr) = *((uint *)(sptr+sbpl*(trigy>>16) +
+ ((trigx>>16)<<2)));
+ trigx += m11;
+ trigy += m12;
+ dptr += 4;
+ }
+ break;
+
+ default: {
+ return FALSE;
+ }
+ }
+ } else {
+ switch ( type ) {
+ case TQT_XFORM_TYPE_MSBFIRST:
+ while ( dptr < maxp ) {
+ IWX_MSB(128);
+ IWX_MSB(64);
+ IWX_MSB(32);
+ IWX_MSB(16);
+ IWX_MSB(8);
+ IWX_MSB(4);
+ IWX_MSB(2);
+ IWX_MSB(1);
+ dptr++;
+ }
+ break;
+ case TQT_XFORM_TYPE_LSBFIRST:
+ while ( dptr < maxp ) {
+ IWX_LSB(1);
+ IWX_LSB(2);
+ IWX_LSB(4);
+ IWX_LSB(8);
+ IWX_LSB(16);
+ IWX_LSB(32);
+ IWX_LSB(64);
+ IWX_LSB(128);
+ dptr++;
+ }
+ break;
+# if defined(TQ_WS_WIN)
+ case TQT_XFORM_TYPE_WINDOWSPIXMAP:
+ while ( dptr < maxp ) {
+ IWX_PIX(128);
+ IWX_PIX(64);
+ IWX_PIX(32);
+ IWX_PIX(16);
+ IWX_PIX(8);
+ IWX_PIX(4);
+ IWX_PIX(2);
+ IWX_PIX(1);
+ dptr++;
+ }
+ break;
+# endif
+ }
+ }
+ m21ydx += m21;
+ m22ydy += m22;
+ dptr += p_inc;
+ }
+ return TRUE;
+}
+#undef IWX_MSB
+#undef IWX_LSB
+#undef IWX_PIX
+#endif // TQT_NO_PIXMAP_TRANSFORMATION
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqpixmap.h b/tqtinterface/qt4/src/kernel/tqpixmap.h
new file mode 100644
index 0000000..13a0a2c
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpixmap.h
@@ -0,0 +1,496 @@
+/****************************************************************************
+**
+** Definition of TQPixmap class
+**
+** Created : 940501
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPIXMAP_H
+#define TQPIXMAP_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqpaintdevice.h"
+#include "tqcolor.h" // char*->TQColor conversion
+#include "tqstring.h" // char*->TQString conversion
+#include "tqnamespace.h"
+#endif // TQT_H
+
+class TQGfx;
+class TQPixmapPrivate;
+
+#if defined(TQ_WS_WIN)
+// Internal pixmap memory optimization class for Windows 9x
+class TQMultiCellPixmap;
+#endif
+
+#ifdef USE_QT4
+
+#include <Qt/qpixmap.h>
+#include <Qt/qbitmap.h>
+
+class TQBitmap;
+
+// #include "tqimage.h"
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQPixmap : public QPixmap, virtual public TQt
+{
+public:
+ enum ColorMode { Auto, Color, Mono };
+ enum Optimization { DefaultOptim, NoOptim, MemoryOptim=NoOptim, NormalOptim, BestOptim };
+
+ TQPixmap();
+ TQPixmap( const QImage& image );
+ TQPixmap( int w, int h, int depth = -1, Optimization o=DefaultOptim );
+ TQPixmap( const QSize &s, int depth = -1, Optimization o=DefaultOptim );
+#ifndef TQT_NO_IMAGEIO
+ TQPixmap( const QString& fileName, const char *format=0, ColorMode mode=Auto );
+ TQPixmap( const QString& fileName, const char *format, int conversion_flags );
+ TQPixmap( const char *xpm[] );
+ TQPixmap( const QByteArray &data );
+#endif
+ TQPixmap( const TQPixmap &p );
+ TQPixmap( const QPixmap p );
+ virtual ~TQPixmap();
+
+#ifndef TQT_NO_MIME
+ static TQPixmap fromMimeSource( const TQString& abs_name );
+#endif
+
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+ TQBitmap createHeuristicMask( bool clipTight = TRUE ) const;
+#endif
+
+ const TQBitmap *tqmask() const;
+ TQImage convertToImage() const;
+ bool selfMask() const;
+
+// inline QImage convertToImage() const { return toImage(); }
+// bool convertFromImage(const QImage &, ColorMode mode); // Needs some code in the cpp file...
+ bool convertFromImage(const QImage &img, Qt::ImageConversionFlags flags = Qt::AutoColor);
+ bool convertFromImage(const QImage &img, int flags);
+
+ operator TQImage() const;
+// inline operator TQImage() const { return toImage(); }
+ TQPixmap xForm(const QMatrix &matrix) const;
+
+ // These four functions no longer have any purpose
+// inline Optimization optimization() const {}
+ void setOptimization( Optimization );
+// inline static Optimization defaultOptimization() {}
+ static void setDefaultOptimization( Optimization );
+
+private:
+ void resize_helper(const QSize s);
+public:
+ void resize(const QSize s);
+ void resize(int width, int height);
+
+ // From TQQPaintDevice
+public:
+ static void *x11AppVisual( void );
+ static void *x11AppVisual( int screen );
+ static int x11AppCells( void );
+ static int x11AppCells( int screen );
+ static int x11AppDepth( void );
+ static int x11AppDepth( int screen );
+ static Display *x11AppDisplay( void );
+ static int x11AppScreen( void );
+ static bool x11AppDefaultVisual( void );
+ static bool x11AppDefaultVisual( int screen );
+ static TQt::HANDLE x11AppColormap( void );
+ static TQt::HANDLE x11AppColormap( int screen );
+ static bool x11AppDefaultColormap( void );
+ static bool x11AppDefaultColormap( int screen );
+ static TQt::HANDLE x11AppRootWindow( void );
+ static TQt::HANDLE x11AppRootWindow( int screen );
+
+#if defined(TQ_WS_X11)
+ Display *x11Display() const;
+ int x11Screen() const;
+ int x11Depth() const;
+ int x11Cells() const;
+ Qt::HANDLE x11Colormap() const;
+ bool x11DefaultColormap() const;
+ void *x11Visual() const;
+ bool x11DefaultVisual() const;
+
+ static int x11AppDpiX(int screen = -1);
+ static int x11AppDpiY(int screen = -1);
+ static void x11SetAppDpiX(int, int);
+ static void x11SetAppDpiY(int, int);
+#endif
+
+ // Windows: get tqdevice context
+ // X-Windows: get drawable
+#if defined(TQ_WS_WIN)
+// virtual HDC handle() const;
+#elif defined(TQ_WS_X11)
+ virtual TQt::HANDLE handle() const;
+ virtual TQt::HANDLE x11RenderHandle() const;
+#elif defined(TQ_WS_MAC)
+// virtual TQt::HANDLE handle() const;
+#elif defined(TQ_WS_TQWS)
+// virtual TQt::HANDLE handle() const;
+#endif
+
+private:
+ mutable TQBitmap* tqt_tqbitmap_ptr;
+
+public:
+ // Interoperability
+ static const TQPixmap& convertFromQPixmap( QPixmap& qpm );
+};
+
+// Interoperability
+inline static const TQPixmap& convertFromQPixmap( const QPixmap& qpm ) {
+ return (*static_cast<const TQPixmap*>(&qpm));
+}
+
+void copyBlt(QPixmap *dst, int dx, int dy, const QPixmap *src, int sx=0, int sy=0, int sw=-1, int sh=-1);
+
+#ifndef TQT_NO_PIXMAP_TRANSFORMATION
+# define TQT_XFORM_TYPE_MSBFIRST 0
+# define TQT_XFORM_TYPE_LSBFIRST 1
+# if defined(TQ_WS_WIN)
+# define TQT_XFORM_TYPE_WINDOWSPIXMAP 2
+# endif
+#endif
+
+#else // USE_QT4
+
+class TQ_EXPORT TQPixmap : public TQPaintDevice, public TQt
+{
+public:
+ enum ColorMode { Auto, Color, Mono };
+ enum Optimization { DefaultOptim, NoOptim, MemoryOptim=NoOptim,
+ NormalOptim, BestOptim };
+
+ TQPixmap();
+ TQPixmap( const TQImage& image );
+ TQPixmap( int w, int h, int depth = -1, Optimization = DefaultOptim );
+ TQPixmap( const TQSize &, int depth = -1, Optimization = DefaultOptim );
+#ifndef TQT_NO_IMAGEIO
+ TQPixmap( const TQString& fileName, const char *format=0,
+ ColorMode mode=Auto );
+ TQPixmap( const TQString& fileName, const char *format,
+ int conversion_flags );
+ TQPixmap( const char *xpm[] ); // ### in 4.0, 'const char * const xpm[]'?
+ TQPixmap( const TQByteArray &data );
+#endif
+ TQPixmap( const TQPixmap & );
+ ~TQPixmap();
+
+ TQPixmap &operator=( const TQPixmap & );
+ TQPixmap &operator=( const TQImage & );
+
+ bool isNull() const;
+
+ int width() const { return data->w; }
+ int height() const { return data->h; }
+ TQSize size() const { return TQSize(data->w,data->h); }
+ TQRect rect() const { return TQRect(0,0,data->w,data->h); }
+ int depth() const { return data->d; }
+ static int defaultDepth();
+
+ void fill( const TQColor &fillColor = TQt::white );
+ void fill( const TQWidget *, int xofs, int yofs );
+ void fill( const TQWidget *, const TQPoint &ofs );
+ void resize( int width, int height );
+ void resize( const TQSize & );
+
+ const TQBitmap *tqmask() const;
+ void setMask( const TQBitmap & );
+ bool selfMask() const;
+ bool hasAlpha() const;
+ bool hasAlphaChannel() const;
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+ TQBitmap createHeuristicMask( bool clipTight = TRUE ) const;
+#endif
+#ifndef TQT_NO_MIME
+ static TQPixmap fromMimeSource( const TQString& abs_name );
+#endif
+ static TQPixmap grabWindow( WId, int x=0, int y=0, int w=-1, int h=-1 );
+ static TQPixmap grabWidget( TQWidget * widget,
+ int x=0, int y=0, int w=-1, int h=-1 );
+
+#ifndef TQT_NO_PIXMAP_TRANSFORMATION
+ TQPixmap xForm( const TQWMatrix & ) const;
+ static TQWMatrix trueMatrix( const TQWMatrix &, int w, int h );
+#endif
+
+ TQImage convertToImage() const;
+ bool convertFromImage( const TQImage &, ColorMode mode=Auto );
+ bool convertFromImage( const TQImage &, int conversion_flags );
+#ifndef TQT_NO_IMAGEIO
+ static const char* imageFormat( const TQString &fileName );
+ bool load( const TQString& fileName, const char *format=0,
+ ColorMode mode=Auto );
+ bool load( const TQString& fileName, const char *format,
+ int conversion_flags );
+ bool loadFromData( const uchar *buf, uint len,
+ const char* format=0,
+ ColorMode mode=Auto );
+ bool loadFromData( const uchar *buf, uint len,
+ const char* format,
+ int conversion_flags );
+ bool loadFromData( const TQByteArray &data,
+ const char* format=0,
+ int conversion_flags=0 );
+ bool save( const TQString& fileName, const char* format, int quality = -1 ) const;
+ bool save( TQIODevice* tqdevice, const char* format, int quality = -1 ) const;
+#endif
+
+#if defined(TQ_WS_WIN)
+ HBITMAP hbm() const;
+#endif
+
+ int serialNumber() const;
+
+ Optimization optimization() const;
+ void setOptimization( Optimization );
+ static Optimization defaultOptimization();
+ static void setDefaultOptimization( Optimization );
+
+ virtual void detach();
+
+ bool isTQBitmap() const;
+
+#if defined(TQ_WS_WIN)
+ // These functions are internal and used by Windows 9x only
+ bool isMultiCellPixmap() const;
+ HDC multiCellHandle() const;
+ HBITMAP multiCellBitmap() const;
+ int multiCellOffset() const;
+ int allocCell();
+ void freeCell( bool = FALSE );
+#endif
+
+#if defined(TQ_WS_TQWS)
+ virtual TQGfx * graphicsContext(bool clip_tqchildren=TRUE) const;
+ virtual unsigned char * scanLine(int) const;
+ virtual int bytesPerLine() const;
+ TQRgb * clut() const;
+ int numCols() const;
+#elif defined(TQ_WS_X11)
+ static int x11SetDefaultScreen( int screen );
+ void x11SetScreen( int screen );
+#endif
+
+#ifndef TQ_TQDOC
+ TQ_DUMMY_COMPARISON_OPERATOR(TQPixmap)
+#endif
+
+protected:
+ TQPixmap( int w, int h, const uchar *data, bool isXbitmap );
+ int metric( int ) const;
+
+#if defined(TQ_WS_WIN)
+ struct TQMCPI { // mem optim for win9x
+ TQMultiCellPixmap *mcp;
+ int offset;
+ };
+#endif
+
+ struct TQPixmapData : public TQShared { // internal pixmap data
+ TQCOORD w, h;
+ short d;
+ uint uninit : 1;
+ uint bitmap : 1;
+ uint selfmask : 1;
+#if defined(TQ_WS_WIN)
+ uint mcp : 1;
+#endif
+ int ser_no;
+ TQBitmap *tqmask;
+#if defined(TQ_WS_WIN)
+ TQPixmap *maskpm;
+ union {
+ HBITMAP hbm; // if mcp == FALSE
+ TQMCPI *mcpi; // if mcp == TRUE
+ } hbm_or_mcpi;
+ uchar *realAlphaBits;
+#ifdef TQ_OS_TEMP
+ uchar* ppvBits; // Pointer to DIBSection bits
+#endif
+#elif defined(TQ_WS_X11)
+ void *ximage;
+ void *maskgc;
+ TQPixmap *alphapm;
+#elif defined(TQ_WS_MAC)
+ ColorTable *clut;
+ TQPixmap *alphapm;
+#elif defined(TQ_WS_TQWS)
+ int id; // ### should use TQPaintDevice::hd, since it is there
+ TQRgb * clut;
+ int numcols;
+ int rw;
+ int rh;
+ bool hasAlpha;
+#endif
+ Optimization optim;
+#if defined(TQ_WS_WIN)
+ HBITMAP old_hbm;
+#endif
+ } *data;
+private:
+#ifndef TQT_NO_IMAGEIO
+ bool doImageIO( TQImageIO* io, int quality ) const;
+#endif
+ TQPixmap( int w, int h, int depth, bool, Optimization );
+ void init( int, int, int, bool, Optimization );
+ void deref();
+ TQPixmap copy( bool ignoreMask = FALSE ) const;
+#if defined(TQ_WS_WIN)
+ void initAlphaPixmap( uchar *bytes, int length, struct tagBITMAPINFO *bmi );
+ void convertToAlphaPixmap( bool initAlpha=TRUE );
+ static void bitBltAlphaPixmap( TQPixmap *dst, int dx, int dy,
+ const TQPixmap *src, int sx, int sy,
+ int sw, int sh, bool useDstAlpha );
+#endif
+ static Optimization defOptim;
+ friend TQ_EXPORT void bitBlt( TQPaintDevice *, int, int,
+ const TQPaintDevice *,
+ int, int, int, int, RasterOp, bool );
+ friend TQ_EXPORT void bitBlt( TQPaintDevice *, int, int,
+ const TQImage* src,
+ int, int, int, int, int conversion_flags );
+ friend TQ_EXPORT void copyBlt( TQPixmap *dst, int dx, int dy,
+ const TQPixmap *src, int sx, int sy,
+ int sw, int sh );
+
+#if defined(TQ_WS_MAC)
+ friend void unclippedScaledBitBlt(TQPaintDevice *, int, int, int, int,
+ const TQPaintDevice *, int, int, int, int,
+ TQt::RasterOp, bool, bool);
+#endif
+
+ friend class TQBitmap;
+ friend class TQPaintDevice;
+ friend class TQPainter;
+ friend class TQGLWidget;
+};
+
+
+inline bool TQPixmap::isNull() const
+{
+ return data->w == 0;
+}
+
+inline void TQPixmap::fill( const TQWidget *w, const TQPoint &ofs )
+{
+ fill( w, ofs.x(), ofs.y() );
+}
+
+inline void TQPixmap::resize( const TQSize &s )
+{
+ resize( s.width(), s.height() );
+}
+
+inline const TQBitmap *TQPixmap::tqmask() const
+{
+ return data->tqmask;
+}
+
+inline bool TQPixmap::selfMask() const
+{
+ return data->selfmask;
+}
+
+#if defined(TQ_WS_WIN)
+inline HBITMAP TQPixmap::hbm() const
+{
+ return data->mcp ? 0 : data->hbm_or_mcpi.hbm;
+}
+#endif
+
+inline int TQPixmap::serialNumber() const
+{
+ return data->ser_no;
+}
+
+inline TQPixmap::Optimization TQPixmap::optimization() const
+{
+ return data->optim;
+}
+
+inline bool TQPixmap::isTQBitmap() const
+{
+ return data->bitmap;
+}
+
+#if defined(TQ_WS_WIN)
+inline bool TQPixmap::isMultiCellPixmap() const
+{
+ return data->mcp;
+}
+#endif
+
+
+/*****************************************************************************
+ TQPixmap stream functions
+ *****************************************************************************/
+
+#if !defined(TQT_NO_DATASTREAM) && !defined(TQT_NO_IMAGEIO)
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPixmap & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPixmap & );
+#endif
+
+/*****************************************************************************
+ TQPixmap (and TQImage) helper functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_PIXMAP_TRANSFORMATION
+# define TQT_XFORM_TYPE_MSBFIRST 0
+# define TQT_XFORM_TYPE_LSBFIRST 1
+# if defined(TQ_WS_WIN)
+# define TQT_XFORM_TYPE_WINDOWSPIXMAP 2
+# endif
+bool qt_xForm_helper( const TQWMatrix&, int, int, int, uchar*, int, int, int, uchar*, int, int, int );
+#endif
+
+TQ_EXPORT void copyBlt( TQPixmap *dst, int dx, int dy,
+ const TQPixmap *src, int sx = 0, int sy = 0,
+ int sw = -1, int sh = -1 );
+
+#endif // USE_QT4
+
+#endif // TQPIXMAP_H
diff --git a/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp b/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp
new file mode 100644
index 0000000..974f23c
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpixmap_x11.cpp
@@ -0,0 +1,2155 @@
+/****************************************************************************
+**
+** Implementation of TQPixmap class for X11
+**
+** Created : 940501
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// NOT REVISED
+
+// Uncomment the next line to enable the MIT Shared Memory extension
+//
+// WARNING: This has some problems:
+//
+// 1. Consumes a 800x600 pixmap
+// 2. TQt does not handle the ShmCompletion message, so you will
+// get strange effects if you xForm() repeatedly.
+//
+// #define TQT_MITSHM
+
+#if defined(TQ_OS_WIN32) && defined(TQT_MITSHM)
+#undef TQT_MITSHM
+#endif
+
+#include "tqplatformdefs.h"
+
+#include "tqbitmap.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqimage.h"
+#include "tqwmatrix.h"
+#include "tqapplication.h"
+#include "tqt_x11_p.h"
+
+#include <stdlib.h>
+
+#if defined(TQ_CC_MIPS)
+# define for if(0){}else for
+#endif
+
+#ifdef USE_QT4
+
+/*!
+ Returns the window system handle of the paint tqdevice, for
+ low-level access. Using this function is not portable.
+
+ The HANDLE type varies with platform; see \c tqpaintdevice.h and
+ \c tqwindowdefs.h for details.
+
+ \sa x11Display()
+*/
+TQt::HANDLE TQPixmap::handle() const
+{
+ return QPixmap::handle();
+}
+
+/*!
+ Returns the window system handle of the paint tqdevice for XRender
+ support. Use of this function is not portable. This function will
+ return 0 if XRender support is not compiled into TQt, if the
+ XRender extension is not supported on the X11 display, or if the
+ handle could not be created.
+*/
+TQt::HANDLE TQPixmap::x11RenderHandle() const
+{
+// #ifndef TQT_NO_XFTFREETYPE
+// return rendhd ? XftDrawPicture( (XftDraw *) rendhd ) : 0;
+// #else
+// return 0;
+// #endif // TQT_NO_XFTFREETYPE
+
+ // [FIXME]
+ printf("[WARNING] TQPixmap::x11RenderHandle() const unimplemented\n\r");
+ return 0;
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQPixmap::TQPixmapData
+ \brief The TQPixmap::TQPixmapData class is an internal class.
+ \internal
+*/
+
+
+// For thread-safety:
+// image->data does not belong to X11, so we must free it ourselves.
+
+inline static void qSafeXDestroyImage( XImage *x )
+{
+ if ( x->data ) {
+ free( x->data );
+ x->data = 0;
+ }
+ XDestroyImage( x );
+}
+
+
+/*****************************************************************************
+ MIT Shared Memory Extension support: makes xForm noticeably (~20%) faster.
+ *****************************************************************************/
+
+#if defined(TQT_MITSHM)
+
+static bool xshminit = FALSE;
+static XShmSegmentInfo xshminfo;
+static XImage *xshmimg = 0;
+static Pixmap xshmpm = 0;
+
+static void qt_cleanup_mitshm()
+{
+ if ( xshmimg == 0 )
+ return;
+ Display *dpy = TQPaintDevice::x11AppDisplay();
+ if ( xshmpm ) {
+ XFreePixmap( dpy, xshmpm );
+ xshmpm = 0;
+ }
+ XShmDetach( dpy, &xshminfo ); xshmimg->data = 0;
+ qSafeXDestroyImage( xshmimg ); xshmimg = 0;
+ shmdt( xshminfo.shmaddr );
+ shmctl( xshminfo.shmid, IPC_RMID, 0 );
+}
+
+
+static bool qt_create_mitshm_buffer( const TQPaintDevice* dev, int w, int h )
+{
+ static int major, minor;
+ static Bool pixmaps_ok;
+ Display *dpy = dev->x11Display();
+ int dd = dev->x11Depth();
+ Visual *vis = (Visual*)dev->x11Visual();
+
+ if ( xshminit ) {
+ qt_cleanup_mitshm();
+ } else {
+ if ( !XShmQueryVersion(dpy, &major, &minor, &pixmaps_ok) )
+ return FALSE; // MIT Shm not supported
+ qAddPostRoutine( qt_cleanup_mitshm );
+ xshminit = TRUE;
+ }
+
+ xshmimg = XShmCreateImage( dpy, vis, dd, ZPixmap, 0, &xshminfo, w, h );
+ if ( !xshmimg )
+ return FALSE;
+
+ bool ok;
+ xshminfo.shmid = shmget( IPC_PRIVATE,
+ xshmimg->bytes_per_line * xshmimg->height,
+ IPC_CREAT | 0777 );
+ ok = xshminfo.shmid != -1;
+ if ( ok ) {
+ xshmimg->data = (char*)shmat( xshminfo.shmid, 0, 0 );
+ xshminfo.shmaddr = xshmimg->data;
+ ok = ( xshminfo.shmaddr != (char*)-1 );
+ }
+ xshminfo.readOnly = FALSE;
+ if ( ok )
+ ok = XShmAttach( dpy, &xshminfo );
+ if ( !ok ) {
+ qSafeXDestroyImage( xshmimg );
+ xshmimg = 0;
+ if ( xshminfo.shmaddr )
+ shmdt( xshminfo.shmaddr );
+ if ( xshminfo.shmid != -1 )
+ shmctl( xshminfo.shmid, IPC_RMID, 0 );
+ return FALSE;
+ }
+ if ( pixmaps_ok )
+ xshmpm = XShmCreatePixmap( dpy, DefaultRootWindow(dpy), xshmimg->data,
+ &xshminfo, w, h, dd );
+
+ return TRUE;
+}
+
+#else
+
+// If extern, need a dummy.
+//
+// static bool qt_create_mitshm_buffer( TQPaintDevice*, int, int )
+// {
+// return FALSE;
+// }
+
+#endif // TQT_MITSHM
+
+
+/*****************************************************************************
+ Internal functions
+ *****************************************************************************/
+
+extern const uchar *qt_get_bitflip_array(); // defined in qimage.cpp
+
+static uchar *flip_bits( const uchar *bits, int len )
+{
+ register const uchar *p = bits;
+ const uchar *end = p + len;
+ uchar *newdata = new uchar[len];
+ uchar *b = newdata;
+ const uchar *f = qt_get_bitflip_array();
+ while ( p < end )
+ *b++ = f[*p++];
+ return newdata;
+}
+
+// Returns position of highest bit set or -1 if none
+static int highest_bit( uint v )
+{
+ int i;
+ uint b = (uint)1 << 31;
+ for ( i=31; ((b & v) == 0) && i>=0; i-- )
+ b >>= 1;
+ return i;
+}
+
+// Returns position of lowest set bit in 'v' as an integer (0-31), or -1
+static int lowest_bit( uint v )
+{
+ int i;
+ ulong lb;
+ lb = 1;
+ for (i=0; ((v & lb) == 0) && i<32; i++, lb<<=1);
+ return i==32 ? -1 : i;
+}
+
+// Counts the number of bits set in 'v'
+static uint n_bits( uint v )
+{
+ int i = 0;
+ while ( v ) {
+ v = v & (v - 1);
+ i++;
+ }
+ return i;
+}
+
+static uint *red_scale_table = 0;
+static uint *green_scale_table = 0;
+static uint *blue_scale_table = 0;
+
+static void cleanup_scale_tables()
+{
+ delete[] red_scale_table;
+ delete[] green_scale_table;
+ delete[] blue_scale_table;
+}
+
+/*
+ Could do smart bitshifting, but the "obvious" algorithm only works for
+ nBits >= 4. This is more robust.
+*/
+static void build_scale_table( uint **table, uint nBits )
+{
+ if ( nBits > 7 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "build_scale_table: internal error, nBits = %i", nBits );
+#endif
+ return;
+ }
+ if (!*table) {
+ static bool firstTable = TRUE;
+ if ( firstTable ) {
+ qAddPostRoutine( cleanup_scale_tables );
+ firstTable = FALSE;
+ }
+ *table = new uint[256];
+ }
+ int maxVal = (1 << nBits) - 1;
+ int valShift = 8 - nBits;
+ int i;
+ for( i = 0 ; i < maxVal + 1 ; i++ )
+ (*table)[i << valShift] = i*255/maxVal;
+}
+
+static int defaultScreen = -1;
+
+extern bool qt_use_xrender; // defined in qapplication_x11.cpp
+extern bool qt_has_xft; // defined in qfont_x11.cpp
+
+#ifndef TQT_NO_XFTFREETYPE
+#ifndef TQT_XFT2
+// Xft1 doesn't have XftDrawCreateAlpha, so we fake it in qtaddons_x11.cpp
+extern "C" XftDraw *XftDrawCreateAlpha( Display *, TQt::HANDLE, int );
+#endif // TQT_XFT2
+#endif // TQT_NO_XFTFREETYPE
+
+/*****************************************************************************
+ TQPixmap member functions
+ *****************************************************************************/
+
+/*!
+ \internal
+ Initializes the pixmap data.
+*/
+
+void TQPixmap::init( int w, int h, int d, bool bitmap, Optimization optim )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( tqApp->type() == TQApplication::Tty ) {
+ qWarning( "TQPixmap: Cannot create a TQPixmap when no GUI "
+ "is being used" );
+ }
+#endif
+
+ static int serial = 0;
+
+ if ( defaultScreen >= 0 && defaultScreen != x11Screen() ) {
+ TQPaintDeviceX11Data* xd = getX11Data( TRUE );
+ xd->x_screen = defaultScreen;
+ xd->x_depth = TQPaintDevice::x11AppDepth( xd->x_screen );
+ xd->x_cells = TQPaintDevice::x11AppCells( xd->x_screen );
+ xd->x_colormap = TQPaintDevice::x11AppColormap( xd->x_screen );
+ xd->x_defcolormap = TQPaintDevice::x11AppDefaultColormap( xd->x_screen );
+ xd->x_visual = TQPaintDevice::x11AppVisual( xd->x_screen );
+ xd->x_defvisual = TQPaintDevice::x11AppDefaultVisual( xd->x_screen );
+ setX11Data( xd );
+ }
+
+ int dd = x11Depth();
+
+ if ( d != -1 )
+ dd = d;
+
+ if ( optim == DefaultOptim ) // use default optimization
+ optim = defOptim;
+
+ data = new TQPixmapData;
+ TQ_CHECK_PTR( data );
+
+ memset( data, 0, sizeof(TQPixmapData) );
+ data->count = 1;
+ data->uninit = TRUE;
+ data->bitmap = bitmap;
+ data->ser_no = ++serial;
+ data->optim = optim;
+
+ bool make_null = w == 0 || h == 0; // create null pixmap
+ if ( d == 1 ) // monocrome pixmap
+ data->d = 1;
+ else if ( d < 0 || d == dd ) // def depth pixmap
+ data->d = dd;
+ if ( make_null || w < 0 || h < 0 || data->d == 0 ) {
+ hd = 0;
+ rendhd = 0;
+#if defined(TQT_CHECK_RANGE)
+ if ( !make_null )
+ qWarning( "TQPixmap: Invalid pixmap parameters" );
+#endif
+ return;
+ }
+ data->w = w;
+ data->h = h;
+ hd = (HANDLE)XCreatePixmap( x11Display(), RootWindow(x11Display(), x11Screen() ),
+ w, h, data->d );
+
+#ifndef TQT_NO_XFTFREETYPE
+ if ( qt_has_xft ) {
+ if ( data->d == 1 ) {
+ rendhd = (HANDLE) XftDrawCreateBitmap( x11Display(), hd );
+ } else {
+ rendhd = (HANDLE) XftDrawCreate( x11Display(), hd,
+ (Visual *) x11Visual(),
+ x11Colormap() );
+ }
+ }
+#endif // TQT_NO_XFTFREETYPE
+
+}
+
+
+void TQPixmap::deref()
+{
+ if ( data && data->deref() ) { // last reference lost
+ delete data->tqmask;
+ delete data->alphapm;
+ if ( data->ximage )
+ qSafeXDestroyImage( (XImage*)data->ximage );
+ if ( data->maskgc )
+ XFreeGC( x11Display(), (GC)data->maskgc );
+ if ( tqApp && hd) {
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (rendhd) {
+ XftDrawDestroy( (XftDraw *) rendhd );
+ rendhd = 0;
+ }
+#endif // TQT_NO_XFTFREETYPE
+
+ XFreePixmap( x11Display(), hd );
+ hd = 0;
+ }
+ delete data;
+ }
+}
+
+
+/*!
+ Constructs a monochrome pixmap, with width \a w and height \a h,
+ that is initialized with the data in \a bits. The \a isXbitmap
+ indicates whether the data is an X bitmap and defaults to FALSE.
+ This constructor is protected and used by the TQBitmap class.
+*/
+
+TQPixmap::TQPixmap( int w, int h, const uchar *bits, bool isXbitmap)
+ : TQPaintDevice( TQInternal::Pixmap )
+{ // for bitmaps only
+ init( 0, 0, 0, FALSE, defOptim );
+ if ( w <= 0 || h <= 0 ) // create null pixmap
+ return;
+
+ data->uninit = FALSE;
+ data->w = w;
+ data->h = h;
+ data->d = 1;
+ uchar *flipped_bits;
+ if ( isXbitmap ) {
+ flipped_bits = 0;
+ } else { // not X bitmap -> flip bits
+ flipped_bits = flip_bits( bits, ((w+7)/8)*h );
+ bits = flipped_bits;
+ }
+ hd = (HANDLE)XCreateBitmapFromData( x11Display(),
+ RootWindow(x11Display(), x11Screen() ),
+ (char *)bits, w, h );
+
+#ifndef TQT_NO_XFTFREETYPE
+ if ( qt_has_xft )
+ rendhd = (HANDLE) XftDrawCreateBitmap (x11Display (), hd);
+#endif // TQT_NO_XFTFREETYPE
+
+ if ( flipped_bits ) // Avoid purify complaint
+ delete [] flipped_bits;
+}
+
+
+/*!
+ This is a special-purpose function that detaches the pixmap from
+ shared pixmap data.
+
+ A pixmap is automatically detached by TQt whenever its contents is
+ about to change. This is done in all TQPixmap member functions
+ that modify the pixmap (fill(), resize(), convertFromImage(),
+ load(), etc.), in bitBlt() for the destination pixmap and in
+ TQPainter::begin() on a pixmap.
+
+ It is possible to modify a pixmap without letting TQt know. You can
+ first obtain the system-dependent handle() and then call
+ system-specific functions (for instance, BitBlt under Windows)
+ that modify the pixmap contents. In such cases, you can call
+ detach() to cut the pixmap loose from other pixmaps that share
+ data with this one.
+
+ detach() returns immediately if there is just a single reference
+ or if the pixmap has not been initialized yet.
+*/
+
+void TQPixmap::detach()
+{
+ if ( data->count != 1 )
+ *this = copy();
+ data->uninit = FALSE;
+
+ // reset cached data
+ if ( data->ximage ) {
+ qSafeXDestroyImage( (XImage*)data->ximage );
+ data->ximage = 0;
+ }
+ if ( data->maskgc ) {
+ XFreeGC( x11Display(), (GC)data->maskgc );
+ data->maskgc = 0;
+ }
+}
+
+
+/*!
+ Returns the default pixmap depth, i.e. the depth a pixmap gets if
+ -1 is specified.
+
+ \sa depth()
+*/
+
+int TQPixmap::defaultDepth()
+{
+ return x11AppDepth();
+}
+
+
+/*!
+ \fn TQPixmap::Optimization TQPixmap::optimization() const
+
+ Returns the optimization setting for this pixmap.
+
+ The default optimization setting is \c TQPixmap::NormalOptim. You
+ can change this setting in two ways:
+ \list
+ \i Call setDefaultOptimization() to set the default optimization
+ for all new pixmaps.
+ \i Call setOptimization() to set the optimization for individual
+ pixmaps.
+ \endlist
+
+ \sa setOptimization(), setDefaultOptimization(), defaultOptimization()
+*/
+
+/*!
+ Sets pixmap drawing optimization for this pixmap.
+
+ The \a optimization setting affects pixmap operations, in
+ particular drawing of transtqparent pixmaps (bitBlt() a pixmap with
+ a tqmask set) and pixmap transformations (the xForm() function).
+
+ Pixmap optimization involves keeping intermediate results in a
+ cache buffer and using the cache to speed up bitBlt() and xForm().
+ The cost is more memory consumption, up to twice as much as an
+ unoptimized pixmap.
+
+ Use the setDefaultOptimization() to change the default
+ optimization for all new pixmaps.
+
+ \sa optimization(), setDefaultOptimization(), defaultOptimization()
+*/
+
+void TQPixmap::setOptimization( Optimization optimization )
+{
+ if ( optimization == data->optim )
+ return;
+ detach();
+ data->optim = optimization == DefaultOptim ?
+ defOptim : optimization;
+ if ( data->optim == MemoryOptim && data->ximage ) {
+ qSafeXDestroyImage( (XImage*)data->ximage );
+ data->ximage = 0;
+ }
+}
+
+
+/*!
+ Fills the pixmap with the color \a fillColor.
+*/
+
+void TQPixmap::fill( const TQColor &fillColor )
+{
+ if ( isNull() )
+ return;
+ detach(); // detach other references
+ GC gc = qt_xget_temp_gc( x11Screen(), depth()==1 );
+ XSetForeground( x11Display(), gc, fillColor.pixel(x11Screen()) );
+ XFillRectangle( x11Display(), hd, gc, 0, 0, width(), height() );
+}
+
+
+/*!
+ Internal implementation of the virtual TQPaintDevice::metric() function.
+
+ Use the TQPaintDeviceMetrics class instead.
+
+ \a m is the metric to get.
+*/
+
+int TQPixmap::metric( int m ) const
+{
+ int val;
+ if ( m == TQPaintDeviceMetrics::PdmWidth )
+ val = width();
+ else if ( m == TQPaintDeviceMetrics::PdmHeight ) {
+ val = height();
+ } else {
+ Display *dpy = x11Display();
+ int scr = x11Screen();
+ switch ( m ) {
+ case TQPaintDeviceMetrics::PdmDpiX:
+ case TQPaintDeviceMetrics::PdmPhysicalDpiX:
+ val = TQPaintDevice::x11AppDpiX( scr );
+ break;
+ case TQPaintDeviceMetrics::PdmDpiY:
+ case TQPaintDeviceMetrics::PdmPhysicalDpiY:
+ val = TQPaintDevice::x11AppDpiY( scr );
+ break;
+ case TQPaintDeviceMetrics::PdmWidthMM:
+ val = (DisplayWidthMM(dpy,scr)*width())/
+ DisplayWidth(dpy,scr);
+ break;
+ case TQPaintDeviceMetrics::PdmHeightMM:
+ val = (DisplayHeightMM(dpy,scr)*height())/
+ DisplayHeight(dpy,scr);
+ break;
+ case TQPaintDeviceMetrics::PdmNumColors:
+ val = 1 << depth();
+ break;
+ case TQPaintDeviceMetrics::PdmDepth:
+ val = depth();
+ break;
+ default:
+ val = 0;
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPixmap::metric: Invalid metric command" );
+#endif
+ }
+ }
+ return val;
+}
+
+/*!
+ Converts the pixmap to a TQImage. Returns a null image if it fails.
+
+ If the pixmap has 1-bit depth, the returned image will also be 1
+ bit deep. If the pixmap has 2- to 8-bit depth, the returned image
+ has 8-bit depth. If the pixmap has greater than 8-bit depth, the
+ returned image has 32-bit depth.
+
+ Note that for the moment, alpha masks on monochrome images are
+ ignored.
+
+ \sa convertFromImage()
+*/
+
+TQImage TQPixmap::convertToImage() const
+{
+ TQImage image;
+ if ( isNull() )
+ return image; // null image
+
+ int w = width();
+ int h = height();
+ int d = depth();
+ bool mono = d == 1;
+ Visual *visual = (Visual *)x11Visual();
+ bool trucol = (visual->c_class == TrueColor || visual->c_class == DirectColor) && !mono && d > 8;
+
+ if ( d > 1 && d <= 8 ) // set to nearest valid depth
+ d = 8; // 2..8 ==> 8
+ // we could run into the situation where d == 8 AND trucol is true, which can
+ // cause problems when converting to and from images. in this case, always treat
+ // the depth as 32... from Klaus Schmidinger and qt-bugs/arc-15/31333.
+ if ( d > 8 || trucol )
+ d = 32; // > 8 ==> 32
+
+ XImage *xi = (XImage *)data->ximage; // any cached ximage?
+ if ( !xi ) // fetch data from X server
+ xi = XGetImage( x11Display(), hd, 0, 0, w, h, AllPlanes,
+ mono ? XYPixmap : ZPixmap );
+ TQ_CHECK_PTR( xi );
+ if (!xi)
+ return image; // null image
+
+ TQImage::Endian bitOrder = TQImage::IgnoreEndian;
+ if ( mono ) {
+ bitOrder = xi->bitmap_bit_order == LSBFirst ?
+ TQImage::LittleEndian : TQImage::BigEndian;
+ }
+ image.create( w, h, d, 0, bitOrder );
+ if ( image.isNull() ) // could not create image
+ return image;
+
+ const TQPixmap* msk = tqmask();
+ const TQPixmap *alf = data->alphapm;
+
+ TQImage alpha;
+ if (alf) {
+ XImage *axi = XGetImage(x11Display(), alf->hd, 0, 0, w, h, AllPlanes, ZPixmap);
+
+ if (axi) {
+ image.setAlphaBuffer( TRUE );
+ alpha.create(w, h, 8);
+
+ // copy each scanline
+ char *src = axi->data;
+ int bpl = TQMIN(alpha.bytesPerLine(), axi->bytes_per_line);
+ for (int y = 0; y < h; y++ ) {
+ memcpy( alpha.scanLine(y), src, bpl );
+ src += axi->bytes_per_line;
+ }
+
+ qSafeXDestroyImage( axi );
+ }
+ } else if (msk) {
+ image.setAlphaBuffer( TRUE );
+ alpha = msk->convertToImage();
+ }
+ bool ale = alpha.bitOrder() == TQImage::LittleEndian;
+
+ if ( trucol ) { // truecolor
+ const uint red_mask = (uint)visual->red_mask;
+ const uint green_mask = (uint)visual->green_mask;
+ const uint blue_mask = (uint)visual->blue_mask;
+ const int red_shift = highest_bit( red_mask ) - 7;
+ const int green_shift = highest_bit( green_mask ) - 7;
+ const int blue_shift = highest_bit( blue_mask ) - 7;
+
+ const uint red_bits = n_bits( red_mask );
+ const uint green_bits = n_bits( green_mask );
+ const uint blue_bits = n_bits( blue_mask );
+
+ static uint red_table_bits = 0;
+ static uint green_table_bits = 0;
+ static uint blue_table_bits = 0;
+
+ if ( red_bits < 8 && red_table_bits != red_bits) {
+ build_scale_table( &red_scale_table, red_bits );
+ red_table_bits = red_bits;
+ }
+ if ( blue_bits < 8 && blue_table_bits != blue_bits) {
+ build_scale_table( &blue_scale_table, blue_bits );
+ blue_table_bits = blue_bits;
+ }
+ if ( green_bits < 8 && green_table_bits != green_bits) {
+ build_scale_table( &green_scale_table, green_bits );
+ green_table_bits = green_bits;
+ }
+
+ int r, g, b;
+
+ TQRgb *dst;
+ uchar *src;
+ uint pixel;
+ int bppc = xi->bits_per_pixel;
+
+ if ( bppc > 8 && xi->byte_order == LSBFirst )
+ bppc++;
+
+ for ( int y=0; y<h; y++ ) {
+ uchar* asrc = alf || msk ? alpha.scanLine( y ) : 0;
+ dst = (TQRgb *)image.scanLine( y );
+ src = (uchar *)xi->data + xi->bytes_per_line*y;
+ for ( int x=0; x<w; x++ ) {
+ switch ( bppc ) {
+ case 8:
+ pixel = *src++;
+ break;
+ case 16: // 16 bit MSB
+ pixel = src[1] | (ushort)src[0] << 8;
+ src += 2;
+ break;
+ case 17: // 16 bit LSB
+ pixel = src[0] | (ushort)src[1] << 8;
+ src += 2;
+ break;
+ case 24: // 24 bit MSB
+ pixel = src[2] | (ushort)src[1] << 8 |
+ (uint)src[0] << 16;
+ src += 3;
+ break;
+ case 25: // 24 bit LSB
+ pixel = src[0] | (ushort)src[1] << 8 |
+ (uint)src[2] << 16;
+ src += 3;
+ break;
+ case 32: // 32 bit MSB
+ pixel = src[3] | (ushort)src[2] << 8 |
+ (uint)src[1] << 16 | (uint)src[0] << 24;
+ src += 4;
+ break;
+ case 33: // 32 bit LSB
+ pixel = src[0] | (ushort)src[1] << 8 |
+ (uint)src[2] << 16 | (uint)src[3] << 24;
+ src += 4;
+ break;
+ default: // should not really happen
+ x = w; // leave loop
+ y = h;
+ pixel = 0; // eliminate compiler warning
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPixmap::convertToImage: Invalid depth %d",
+ bppc );
+#endif
+ }
+ if ( red_shift > 0 )
+ r = (pixel & red_mask) >> red_shift;
+ else
+ r = (pixel & red_mask) << -red_shift;
+ if ( green_shift > 0 )
+ g = (pixel & green_mask) >> green_shift;
+ else
+ g = (pixel & green_mask) << -green_shift;
+ if ( blue_shift > 0 )
+ b = (pixel & blue_mask) >> blue_shift;
+ else
+ b = (pixel & blue_mask) << -blue_shift;
+
+ if ( red_bits < 8 )
+ r = red_scale_table[r];
+ if ( green_bits < 8 )
+ g = green_scale_table[g];
+ if ( blue_bits < 8 )
+ b = blue_scale_table[b];
+
+ if (alf) {
+ *dst++ = tqRgba(r, g, b, asrc[x]);
+ } else if (msk) {
+ if ( ale ) {
+ *dst++ = (asrc[x >> 3] & (1 << (x & 7)))
+ ? tqRgba(r, g, b, 0xff) : tqRgba(r, g, b, 0x00);
+ } else {
+ *dst++ = (asrc[x >> 3] & (1 << (7 -(x & 7))))
+ ? tqRgba(r, g, b, 0xff) : tqRgba(r, g, b, 0x00);
+ }
+ } else {
+ *dst++ = tqRgb(r, g, b);
+ }
+ }
+ }
+ } else if ( xi->bits_per_pixel == d ) { // compatible depth
+ char *xidata = xi->data; // copy each scanline
+ int bpl = TQMIN(image.bytesPerLine(),xi->bytes_per_line);
+ for ( int y=0; y<h; y++ ) {
+ memcpy( image.scanLine(y), xidata, bpl );
+ xidata += xi->bytes_per_line;
+ }
+ } else {
+ /* Typically 2 or 4 bits display depth */
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPixmap::convertToImage: Display not supported (bpp=%d)",
+ xi->bits_per_pixel );
+#endif
+ image.reset();
+ return image;
+ }
+
+ if ( mono ) { // bitmap
+ image.setNumColors( 2 );
+ image.setColor( 0, tqRgb(255,255,255) );
+ image.setColor( 1, tqRgb(0,0,0) );
+ } else if ( !trucol ) { // pixmap with colormap
+ register uchar *p;
+ uchar *end;
+ uchar use[256]; // pixel-in-use table
+ uchar pix[256]; // pixel translation table
+ int ncols, i, bpl;
+ memset( use, 0, 256 );
+ memset( pix, 0, 256 );
+ bpl = image.bytesPerLine();
+
+ if (msk) { // which pixels are used?
+ for ( i=0; i<h; i++ ) {
+ uchar* asrc = alpha.scanLine( i );
+ p = image.scanLine( i );
+ for ( int x = 0; x < w; x++ ) {
+ if ( ale ) {
+ if (asrc[x >> 3] & (1 << (x & 7)))
+ use[*p] = 1;
+ } else {
+ if (asrc[x >> 3] & (1 << (7 -(x & 7))))
+ use[*p] = 1;
+ }
+ ++p;
+ }
+ }
+ } else {
+ for ( i=0; i<h; i++ ) {
+ p = image.scanLine( i );
+ end = p + bpl;
+ while ( p < end )
+ use[*p++] = 1;
+ }
+ }
+ ncols = 0;
+ for ( i=0; i<256; i++ ) { // build translation table
+ if ( use[i] )
+ pix[i] = ncols++;
+ }
+ for ( i=0; i<h; i++ ) { // translate pixels
+ p = image.scanLine( i );
+ end = p + bpl;
+ while ( p < end ) {
+ *p = pix[*p];
+ p++;
+ }
+ }
+
+ Colormap cmap = x11Colormap();
+ int ncells = x11Cells();
+ XColor *carr = new XColor[ncells];
+ for ( i=0; i<ncells; i++ )
+ carr[i].pixel = i;
+ // Get default colormap
+ XQueryColors( x11Display(), cmap, carr, ncells );
+
+ if (msk) {
+ int trans;
+ if (ncols < 256) {
+ trans = ncols++;
+ image.setNumColors( ncols ); // create color table
+ image.setColor( trans, 0x00000000 );
+ } else {
+ image.setNumColors( ncols ); // create color table
+ // oh dear... no spare "transtqparent" pixel.
+ // use first pixel in image (as good as any).
+ trans = image.scanLine( i )[0];
+ }
+ for ( i=0; i<h; i++ ) {
+ uchar* asrc = alpha.scanLine( i );
+ p = image.scanLine( i );
+ for ( int x = 0; x < w; x++ ) {
+ if ( ale ) {
+ if (!(asrc[x >> 3] & (1 << (x & 7))))
+ *p = trans;
+ } else {
+ if (!(asrc[x >> 3] & (1 << (7 -(x & 7)))))
+ *p = trans;
+ }
+ ++p;
+ }
+ }
+ } else {
+ image.setNumColors( ncols ); // create color table
+ }
+ int j = 0;
+ for ( i=0; i<256; i++ ) { // translate pixels
+ if ( use[i] ) {
+ image.setColor( j++,
+ ( msk ? 0xff000000 : 0 )
+ | tqRgb( (carr[i].red >> 8) & 255,
+ (carr[i].green >> 8) & 255,
+ (carr[i].blue >> 8) & 255 ) );
+ }
+ }
+
+ delete [] carr;
+ }
+ if ( data->optim != BestOptim ) { // throw away image data
+ qSafeXDestroyImage( xi );
+ ((TQPixmap*)this)->data->ximage = 0;
+ } else // keep ximage data
+ ((TQPixmap*)this)->data->ximage = xi;
+
+ return image;
+}
+
+
+/*!
+ Converts image \a img and sets this pixmap. Returns TRUE if
+ successful; otherwise returns FALSE.
+
+ The \a conversion_flags argument is a bitwise-OR of the
+ \l{TQt::ImageConversionFlags}. Passing 0 for \a conversion_flags
+ sets all the default options.
+
+ Note that even though a TQPixmap with depth 1 behaves much like a
+ TQBitmap, isTQBitmap() returns FALSE.
+
+ If a pixmap with depth 1 is painted with color0 and color1 and
+ converted to an image, the pixels painted with color0 will produce
+ pixel index 0 in the image and those painted with color1 will
+ produce pixel index 1.
+
+ \sa convertToImage(), isTQBitmap(), TQImage::convertDepth(),
+ defaultDepth(), TQImage::hasAlphaBuffer()
+*/
+
+bool TQPixmap::convertFromImage( const TQImage &img, int conversion_flags )
+{
+ if ( img.isNull() ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQPixmap::convertFromImage: Cannot convert a null image" );
+#endif
+ return FALSE;
+ }
+ detach(); // detach other references
+ TQImage image = img;
+ const uint w = image.width();
+ const uint h = image.height();
+ int d = image.depth();
+ const int dd = x11Depth();
+ bool force_mono = (dd == 1 || isTQBitmap() ||
+ (conversion_flags & ColorMode_Mask)==MonoOnly );
+
+ if ( w >= 32768 || h >= 32768 )
+ return FALSE;
+
+ // get rid of the tqmask
+ delete data->tqmask;
+ data->tqmask = 0;
+
+ // get rid of alpha pixmap
+ delete data->alphapm;
+ data->alphapm = 0;
+
+ // must be monochrome
+ if ( force_mono ) {
+ if ( d != 1 ) {
+ // dither
+ image = image.convertDepth( 1, conversion_flags );
+ d = 1;
+ }
+ } else { // can be both
+ bool conv8 = FALSE;
+ if ( d > 8 && dd <= 8 ) { // convert to 8 bit
+ if ( (conversion_flags & DitherMode_Mask) == AutoDither )
+ conversion_flags = (conversion_flags & ~DitherMode_Mask)
+ | PreferDither;
+ conv8 = TRUE;
+ } else if ( (conversion_flags & ColorMode_Mask) == ColorOnly ) {
+ conv8 = d == 1; // native depth wanted
+ } else if ( d == 1 ) {
+ if ( image.numColors() == 2 ) {
+ TQRgb c0 = image.color(0); // Auto: convert to best
+ TQRgb c1 = image.color(1);
+ conv8 = TQMIN(c0,c1) != tqRgb(0,0,0) || TQMAX(c0,c1) != tqRgb(255,255,255);
+ } else {
+ // eg. 1-color monochrome images (they do exist).
+ conv8 = TRUE;
+ }
+ }
+ if ( conv8 ) {
+ image = image.convertDepth( 8, conversion_flags );
+ d = 8;
+ }
+ }
+
+ if ( d == 1 ) { // 1 bit pixmap (bitmap)
+ if ( hd ) { // delete old X pixmap
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (rendhd) {
+ XftDrawDestroy( (XftDraw *) rendhd );
+ rendhd = 0;
+ }
+#endif // TQT_NO_XFTFREETYPE
+
+ XFreePixmap( x11Display(), hd );
+ }
+
+ // make sure image.color(0) == color0 (white) and image.color(1) == color1 (black)
+ if (image.color(0) == TQt::black.rgb() && image.color(1) == TQt::white.rgb()) {
+ image.invertPixels();
+ image.setColor(0, TQt::white.rgb());
+ image.setColor(1, TQt::black.rgb());
+ }
+
+ char *bits;
+ uchar *tmp_bits;
+ int bpl = (w+7)/8;
+ int ibpl = image.bytesPerLine();
+ if ( image.bitOrder() == TQImage::BigEndian || bpl != ibpl ) {
+ tmp_bits = new uchar[bpl*h];
+ TQ_CHECK_PTR( tmp_bits );
+ bits = (char *)tmp_bits;
+ uchar *p, *b, *end;
+ uint y, count;
+ if ( image.bitOrder() == TQImage::BigEndian ) {
+ const uchar *f = qt_get_bitflip_array();
+ b = tmp_bits;
+ for ( y=0; y<h; y++ ) {
+ p = image.scanLine( y );
+ end = p + bpl;
+ count = bpl;
+ while ( count > 4 ) {
+ *b++ = f[*p++];
+ *b++ = f[*p++];
+ *b++ = f[*p++];
+ *b++ = f[*p++];
+ count -= 4;
+ }
+ while ( p < end )
+ *b++ = f[*p++];
+ }
+ } else { // just copy
+ b = tmp_bits;
+ p = image.scanLine( 0 );
+ for ( y=0; y<h; y++ ) {
+ memcpy( b, p, bpl );
+ b += bpl;
+ p += ibpl;
+ }
+ }
+ } else {
+ bits = (char *)image.bits();
+ tmp_bits = 0;
+ }
+ hd = (HANDLE)XCreateBitmapFromData( x11Display(),
+ RootWindow(x11Display(), x11Screen() ),
+ bits, w, h );
+
+#ifndef TQT_NO_XFTFREETYPE
+ if ( qt_has_xft )
+ rendhd = (HANDLE) XftDrawCreateBitmap( x11Display(), hd );
+#endif // TQT_NO_XFTFREETYPE
+
+ if ( tmp_bits ) // Avoid purify complaint
+ delete [] tmp_bits;
+ data->w = w; data->h = h; data->d = 1;
+
+ if ( image.hasAlphaBuffer() ) {
+ TQBitmap m;
+ m = image.createAlphaMask( conversion_flags );
+ setMask( m );
+ }
+ return TRUE;
+ }
+
+ Display *dpy = x11Display();
+ Visual *visual = (Visual *)x11Visual();
+ XImage *xi = 0;
+ bool trucol = (visual->c_class == TrueColor || visual->c_class == DirectColor);
+ int nbytes = image.numBytes();
+ uchar *newbits= 0;
+
+ if ( trucol ) { // truecolor display
+ TQRgb pix[256]; // pixel translation table
+ const bool d8 = d == 8;
+ const uint red_mask = (uint)visual->red_mask;
+ const uint green_mask = (uint)visual->green_mask;
+ const uint blue_mask = (uint)visual->blue_mask;
+ const int red_shift = highest_bit( red_mask ) - 7;
+ const int green_shift = highest_bit( green_mask ) - 7;
+ const int blue_shift = highest_bit( blue_mask ) - 7;
+ const uint rbits = highest_bit(red_mask) - lowest_bit(red_mask) + 1;
+ const uint gbits = highest_bit(green_mask) - lowest_bit(green_mask) + 1;
+ const uint bbits = highest_bit(blue_mask) - lowest_bit(blue_mask) + 1;
+
+ if ( d8 ) { // setup pixel translation
+ TQRgb *ctable = image.colorTable();
+ for ( int i=0; i<image.numColors(); i++ ) {
+ int r = tqRed (ctable[i]);
+ int g = tqGreen(ctable[i]);
+ int b = tqBlue (ctable[i]);
+ r = red_shift > 0 ? r << red_shift : r >> -red_shift;
+ g = green_shift > 0 ? g << green_shift : g >> -green_shift;
+ b = blue_shift > 0 ? b << blue_shift : b >> -blue_shift;
+ pix[i] = (b & blue_mask) | (g & green_mask) | (r & red_mask)
+ | ~(blue_mask | green_mask | red_mask);
+ }
+ }
+
+ xi = XCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0 );
+ TQ_CHECK_PTR( xi );
+ if (!xi)
+ return false;
+ newbits = (uchar *)malloc( xi->bytes_per_line*h );
+ TQ_CHECK_PTR( newbits );
+ if ( !newbits ) // no memory
+ return FALSE;
+ int bppc = xi->bits_per_pixel;
+
+ if ( bppc > 8 && xi->byte_order == LSBFirst )
+ bppc++;
+
+ bool contig_bits = n_bits(red_mask) == rbits &&
+ n_bits(green_mask) == gbits &&
+ n_bits(blue_mask) == bbits;
+ bool dither_tc =
+ // Want it?
+ (conversion_flags & Dither_Mask) != ThresholdDither &&
+ (conversion_flags & DitherMode_Mask) != AvoidDither &&
+ // Need it?
+ bppc < 24 && !d8 &&
+ // Can do it? (Contiguous bits?)
+ contig_bits;
+
+ static bool init=FALSE;
+ static int D[16][16];
+ if ( dither_tc && !init ) {
+ // I also contributed this code to XV - WWA.
+ /*
+ The dither matrix, D, is obtained with this formula:
+
+ D2 = [ 0 2 ]
+ [ 3 1 ]
+
+
+ D2*n = [ 4*Dn 4*Dn+2*Un ]
+ [ 4*Dn+3*Un 4*Dn+1*Un ]
+ */
+ int n,i,j;
+ init=1;
+
+ /* Set D2 */
+ D[0][0]=0;
+ D[1][0]=2;
+ D[0][1]=3;
+ D[1][1]=1;
+
+ /* Expand using recursive definition given above */
+ for (n=2; n<16; n*=2) {
+ for (i=0; i<n; i++) {
+ for (j=0; j<n; j++) {
+ D[i][j]*=4;
+ D[i+n][j]=D[i][j]+2;
+ D[i][j+n]=D[i][j]+3;
+ D[i+n][j+n]=D[i][j]+1;
+ }
+ }
+ }
+ init=TRUE;
+ }
+
+ for ( uint y=0; y<h; y++ ) {
+ uchar* src = image.scanLine( y );
+ uchar* dst = newbits + xi->bytes_per_line*y;
+ TQRgb* p = (TQRgb *)src;
+
+#define GET_RGB \
+ int r = tqRed ( *p ); \
+ int g = tqGreen( *p ); \
+ int b = tqBlue ( *p++ ); \
+ r = red_shift > 0 \
+ ? r << red_shift : r >> -red_shift; \
+ g = green_shift > 0 \
+ ? g << green_shift : g >> -green_shift; \
+ b = blue_shift > 0 \
+ ? b << blue_shift : b >> -blue_shift;
+
+#define GET_PIXEL \
+ int pixel; \
+ if ( d8 ) pixel = pix[*src++]; \
+ else { \
+ GET_RGB \
+ pixel = (b & blue_mask)|(g & green_mask) | (r & red_mask) \
+ | ~(blue_mask | green_mask | red_mask); \
+ }
+
+#define GET_PIXEL_DITHER_TC \
+ int r = tqRed ( *p ); \
+ int g = tqGreen( *p ); \
+ int b = tqBlue ( *p++ ); \
+ const int thres = D[x%16][y%16]; \
+ if ( r <= (255-(1<<(8-rbits))) && ((r<<rbits) & 255) \
+ > thres) \
+ r += (1<<(8-rbits)); \
+ if ( g <= (255-(1<<(8-gbits))) && ((g<<gbits) & 255) \
+ > thres) \
+ g += (1<<(8-gbits)); \
+ if ( b <= (255-(1<<(8-bbits))) && ((b<<bbits) & 255) \
+ > thres) \
+ b += (1<<(8-bbits)); \
+ r = red_shift > 0 \
+ ? r << red_shift : r >> -red_shift; \
+ g = green_shift > 0 \
+ ? g << green_shift : g >> -green_shift; \
+ b = blue_shift > 0 \
+ ? b << blue_shift : b >> -blue_shift; \
+ int pixel = (b & blue_mask)|(g & green_mask) | (r & red_mask);
+
+ if ( dither_tc ) {
+ uint x;
+ switch ( bppc ) {
+ case 16: // 16 bit MSB
+ for ( x=0; x<w; x++ ) {
+ GET_PIXEL_DITHER_TC
+ *dst++ = (pixel >> 8);
+ *dst++ = pixel;
+ }
+ break;
+ case 17: // 16 bit LSB
+ for ( x=0; x<w; x++ ) {
+ GET_PIXEL_DITHER_TC
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ }
+ break;
+ default:
+ qFatal("Logic error");
+ }
+ } else {
+ uint x;
+ switch ( bppc ) {
+ case 8: // 8 bit
+ for ( x=0; x<w; x++ ) {
+ int pixel = pix[*src++];
+ *dst++ = pixel;
+ }
+ break;
+ case 16: // 16 bit MSB
+ for ( x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = (pixel >> 8);
+ *dst++ = pixel;
+ }
+ break;
+ case 17: // 16 bit LSB
+ for ( x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ }
+ break;
+ case 24: // 24 bit MSB
+ for ( x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = pixel >> 16;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel;
+ }
+ break;
+ case 25: // 24 bit LSB
+ for ( x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel >> 16;
+ }
+ break;
+ case 32: // 32 bit MSB
+ for ( x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = pixel >> 24;
+ *dst++ = pixel >> 16;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel;
+ }
+ break;
+ case 33: // 32 bit LSB
+ for ( x=0; x<w; x++ ) {
+ GET_PIXEL
+ *dst++ = pixel;
+ *dst++ = pixel >> 8;
+ *dst++ = pixel >> 16;
+ *dst++ = pixel >> 24;
+ }
+ break;
+ default:
+ qFatal("Logic error 2");
+ }
+ }
+ }
+ xi->data = (char *)newbits;
+ }
+
+ if ( d == 8 && !trucol ) { // 8 bit pixmap
+ int pop[256]; // pixel popularity
+
+ if ( image.numColors() == 0 )
+ image.setNumColors( 1 );
+
+ memset( pop, 0, sizeof(int)*256 ); // reset popularity array
+ uint i;
+ for ( i=0; i<h; i++ ) { // for each scanline...
+ uchar* p = image.scanLine( i );
+ uchar *end = p + w;
+ while ( p < end ) // compute popularity
+ pop[*p++]++;
+ }
+
+ newbits = (uchar *)malloc( nbytes ); // copy image into newbits
+ TQ_CHECK_PTR( newbits );
+ if ( !newbits ) // no memory
+ return FALSE;
+ uchar* p = newbits;
+ memcpy( p, image.bits(), nbytes ); // copy image data into newbits
+
+ /*
+ * The code below picks the most important colors. It is based on the
+ * diversity algorithm, implemented in XV 3.10. XV is (C) by John Bradley.
+ */
+
+ struct PIX { // pixel sort element
+ uchar r,g,b,n; // color + pad
+ int use; // popularity
+ int index; // index in colormap
+ int mindist;
+ };
+ int ncols = 0;
+ for ( i=0; i< (uint) image.numColors(); i++ ) { // compute number of colors
+ if ( pop[i] > 0 )
+ ncols++;
+ }
+ for ( i=image.numColors(); i<256; i++ ) // ignore out-of-range pixels
+ pop[i] = 0;
+
+ // works since we make sure above to have at least
+ // one color in the image
+ if ( ncols == 0 )
+ ncols = 1;
+
+ PIX pixarr[256]; // pixel array
+ PIX pixarr_sorted[256]; // pixel array (sorted)
+ memset( pixarr, 0, ncols*sizeof(PIX) );
+ PIX *px = &pixarr[0];
+ int maxpop = 0;
+ int maxpix = 0;
+ TQ_CHECK_PTR( pixarr );
+ uint j = 0;
+ TQRgb* ctable = image.colorTable();
+ for ( i=0; i<256; i++ ) { // init pixel array
+ if ( pop[i] > 0 ) {
+ px->r = tqRed ( ctable[i] );
+ px->g = tqGreen( ctable[i] );
+ px->b = tqBlue ( ctable[i] );
+ px->n = 0;
+ px->use = pop[i];
+ if ( pop[i] > maxpop ) { // select most popular entry
+ maxpop = pop[i];
+ maxpix = j;
+ }
+ px->index = i;
+ px->mindist = 1000000;
+ px++;
+ j++;
+ }
+ }
+ pixarr_sorted[0] = pixarr[maxpix];
+ pixarr[maxpix].use = 0;
+
+ for ( i=1; i< (uint) ncols; i++ ) { // sort pixels
+ int minpix = -1, mindist = -1;
+ px = &pixarr_sorted[i-1];
+ int r = px->r;
+ int g = px->g;
+ int b = px->b;
+ int dist;
+ if ( (i & 1) || i<10 ) { // sort on max distance
+ for ( int j=0; j<ncols; j++ ) {
+ px = &pixarr[j];
+ if ( px->use ) {
+ dist = (px->r - r)*(px->r - r) +
+ (px->g - g)*(px->g - g) +
+ (px->b - b)*(px->b - b);
+ if ( px->mindist > dist )
+ px->mindist = dist;
+ if ( px->mindist > mindist ) {
+ mindist = px->mindist;
+ minpix = j;
+ }
+ }
+ }
+ } else { // sort on max popularity
+ for ( int j=0; j<ncols; j++ ) {
+ px = &pixarr[j];
+ if ( px->use ) {
+ dist = (px->r - r)*(px->r - r) +
+ (px->g - g)*(px->g - g) +
+ (px->b - b)*(px->b - b);
+ if ( px->mindist > dist )
+ px->mindist = dist;
+ if ( px->use > mindist ) {
+ mindist = px->use;
+ minpix = j;
+ }
+ }
+ }
+ }
+ pixarr_sorted[i] = pixarr[minpix];
+ pixarr[minpix].use = 0;
+ }
+
+ uint pix[256]; // pixel translation table
+ px = &pixarr_sorted[0];
+ for ( i=0; i< (uint) ncols; i++ ) { // allocate colors
+ TQColor c( px->r, px->g, px->b );
+ pix[px->index] = c.pixel(x11Screen());
+ px++;
+ }
+
+ p = newbits;
+ for ( i=0; i< (uint) nbytes; i++ ) { // translate pixels
+ *p = pix[*p];
+ p++;
+ }
+ }
+
+ if ( !xi ) { // X image not created
+ xi = XCreateImage( dpy, visual, dd, ZPixmap, 0, 0, w, h, 32, 0 );
+ if ( xi->bits_per_pixel == 16 ) { // convert 8 bpp ==> 16 bpp
+ ushort *p2;
+ int p2inc = xi->bytes_per_line/sizeof(ushort);
+ ushort *newerbits = (ushort *)malloc( xi->bytes_per_line * h );
+ TQ_CHECK_PTR( newerbits );
+ if ( !newerbits ) // no memory
+ return FALSE;
+ uchar* p = newbits;
+ for ( uint y=0; y<h; y++ ) { // OOPS: Do right byte order!!
+ p2 = newerbits + p2inc*y;
+ for ( uint x=0; x<w; x++ )
+ *p2++ = *p++;
+ }
+ free( newbits );
+ newbits = (uchar *)newerbits;
+ } else if ( xi->bits_per_pixel != 8 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPixmap::convertFromImage: Display not supported "
+ "(bpp=%d)", xi->bits_per_pixel );
+#endif
+ }
+ xi->data = (char *)newbits;
+ }
+
+ if ( hd && (width() != (int)w || height() != (int)h || this->depth() != dd) ) {
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (rendhd) {
+ XftDrawDestroy( (XftDraw *) rendhd );
+ rendhd = 0;
+ }
+#endif // TQT_NO_XFTFREETYPE
+
+ XFreePixmap( dpy, hd ); // don't reuse old pixmap
+ hd = 0;
+ }
+ if ( !hd ) { // create new pixmap
+ hd = (HANDLE)XCreatePixmap( x11Display(),
+ RootWindow(x11Display(), x11Screen() ),
+ w, h, dd );
+
+#ifndef TQT_NO_XFTFREETYPE
+ if ( qt_has_xft ) {
+ if ( data->d == 1 ) {
+ rendhd = (HANDLE) XftDrawCreateBitmap( x11Display (), hd );
+ } else {
+ rendhd = (HANDLE) XftDrawCreate( x11Display (), hd,
+ (Visual *) x11Visual(), x11Colormap() );
+ }
+ }
+#endif // TQT_NO_XFTFREETYPE
+
+ }
+
+ XPutImage( dpy, hd, qt_xget_readonly_gc( x11Screen(), FALSE ),
+ xi, 0, 0, 0, 0, w, h );
+
+ if ( data->optim != BestOptim ) { // throw away image
+ qSafeXDestroyImage( xi );
+ data->ximage = 0;
+ } else { // keep ximage that we created
+ data->ximage = xi;
+ }
+ data->w = w;
+ data->h = h;
+ data->d = dd;
+
+ if ( image.hasAlphaBuffer() ) {
+ TQBitmap m;
+ m = image.createAlphaMask( conversion_flags );
+ setMask( m );
+
+#ifndef TQT_NO_XFTFREETYPE
+ // does this image have an alphamap (and not just a 1bpp tqmask)?
+ bool alphamap = image.depth() == 32;
+ if (image.depth() == 8) {
+ const TQRgb * const rgb = image.colorTable();
+ for (int i = 0, count = image.numColors(); i < count; ++i) {
+ const int alpha = tqAlpha(rgb[i]);
+ if (alpha != 0 && alpha != 0xff) {
+ alphamap = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (qt_use_xrender && qt_has_xft && alphamap) {
+ data->alphapm = new TQPixmap; // create a null pixmap
+
+ // setup pixmap data
+ data->alphapm->data->w = w;
+ data->alphapm->data->h = h;
+ data->alphapm->data->d = 8;
+
+ // create 8bpp pixmap and render picture
+ data->alphapm->hd =
+ XCreatePixmap(x11Display(), RootWindow(x11Display(), x11Screen()),
+ w, h, 8);
+
+ data->alphapm->rendhd =
+ (HANDLE) XftDrawCreateAlpha( x11Display(), data->alphapm->hd, 8 );
+
+ XImage *axi = XCreateImage(x11Display(), (Visual *) x11Visual(),
+ 8, ZPixmap, 0, 0, w, h, 8, 0);
+
+ if (axi) {
+ // the data is deleted by qSafeXDestroyImage
+ axi->data = (char *) malloc(h * axi->bytes_per_line);
+ TQ_CHECK_PTR( axi->data );
+ char *aptr = axi->data;
+
+ if (image.depth() == 32) {
+ const int *iptr = (const int *) image.bits();
+ int max = w * h;
+ while (max--)
+ *aptr++ = *iptr++ >> 24; // squirt
+ } else if (image.depth() == 8) {
+ const TQRgb * const rgb = image.colorTable();
+ for (uint y = 0; y < h; ++y) {
+ const uchar *iptr = image.scanLine(y);
+ for (uint x = 0; x < w; ++x)
+ *aptr++ = tqAlpha(rgb[*iptr++]);
+ }
+ }
+
+ GC gc = XCreateGC(x11Display(), data->alphapm->hd, 0, 0);
+ XPutImage(dpy, data->alphapm->hd, gc, axi, 0, 0, 0, 0, w, h);
+ XFreeGC(x11Display(), gc);
+ qSafeXDestroyImage(axi);
+ }
+ }
+#endif // TQT_NO_XFTFREETYPE
+ }
+
+ return TRUE;
+}
+
+
+/*!
+ Grabs the contents of the window \a window and makes a pixmap out
+ of it. Returns the pixmap.
+
+ The arguments \a (x, y) specify the offset in the window, whereas
+ \a (w, h) specify the width and height of the area to be copied.
+
+ If \a w is negative, the function copies everything to the right
+ border of the window. If \a h is negative, the function copies
+ everything to the bottom of the window.
+
+ Note that grabWindow() grabs pixels from the screen, not from the
+ window. If there is another window partially or entirely over the
+ one you grab, you get pixels from the overlying window, too.
+
+ Note also that the mouse cursor is generally not grabbed.
+
+ The reason we use a window identifier and not a TQWidget is to
+ enable grabbing of windows that are not part of the application,
+ window system frames, and so on.
+
+ \warning Grabbing an area outside the screen is not safe in
+ general. This depends on the underlying window system.
+
+ \warning X11 only: If \a window is not the same depth as the root
+ window and another window partially or entirely obscures the one
+ you grab, you will \e not get pixels from the overlying window.
+ The contests of the obscured areas in the pixmap are undefined and
+ uninitialized.
+
+ \sa grabWidget()
+*/
+
+TQPixmap TQPixmap::grabWindow( WId window, int x, int y, int w, int h )
+{
+ if ( w == 0 || h == 0 )
+ return TQPixmap();
+
+ Display *dpy = x11AppDisplay();
+ XWindowAttributes window_attr;
+ if ( ! XGetWindowAttributes( dpy, window, &window_attr ) )
+ return TQPixmap();
+
+ if ( w < 0 )
+ w = window_attr.width - x;
+ if ( h < 0 )
+ h = window_attr.height - y;
+
+ // determine the screen
+ int scr;
+ for ( scr = 0; scr < ScreenCount( dpy ); ++scr ) {
+ if ( window_attr.root == RootWindow( dpy, scr ) ) // found it
+ break;
+ }
+ if ( scr >= ScreenCount( dpy ) ) // sanity check
+ return TQPixmap();
+
+
+ // get the depth of the root window
+ XWindowAttributes root_attr;
+ if ( ! XGetWindowAttributes( dpy, window_attr.root, &root_attr ) )
+ return TQPixmap();
+
+ if ( window_attr.depth == root_attr.depth ) {
+ // if the depth of the specified window and the root window are the
+ // same, grab pixels from the root window (so that we get the any
+ // overlapping windows and window manager frames)
+
+ // map x and y to the root window
+ WId unused;
+ if ( ! XTranslateCoordinates( dpy, window, window_attr.root, x, y,
+ &x, &y, &unused ) )
+ return TQPixmap();
+
+ window = window_attr.root;
+ }
+
+ TQPixmap pm( w, h );
+ pm.data->uninit = FALSE;
+ pm.x11SetScreen( scr );
+
+ GC gc = qt_xget_temp_gc( scr, FALSE );
+ XSetSubwindowMode( dpy, gc, IncludeInferiors );
+ XCopyArea( dpy, window, pm.handle(), gc, x, y, w, h, 0, 0 );
+ XSetSubwindowMode( dpy, gc, ClipByChildren );
+
+ return pm;
+}
+
+/*!
+ Returns a copy of the pixmap that is transformed using \a matrix.
+ The original pixmap is not changed.
+
+ The transformation \a matrix is internally adjusted to compensate
+ for unwanted translation, i.e. xForm() returns the smallest image
+ that tqcontains all the transformed points of the original image.
+
+ This function is slow because it involves transformation to a
+ TQImage, non-trivial computations and a transformation back to a
+ TQPixmap.
+
+ \sa trueMatrix(), TQWMatrix, TQPainter::setWorldMatrix() TQImage::xForm()
+*/
+
+TQPixmap TQPixmap::xForm( const TQWMatrix &matrix ) const
+{
+ uint w = 0;
+ uint h = 0; // size of target pixmap
+ uint ws, hs; // size of source pixmap
+ uchar *dptr; // data in target pixmap
+ uint dbpl, dbytes; // bytes per line/bytes total
+ uchar *sptr; // data in original pixmap
+ int sbpl; // bytes per line in original
+ int bpp; // bits per pixel
+ bool depth1 = depth() == 1;
+ Display *dpy = x11Display();
+
+ if ( isNull() ) // this is a null pixmap
+ return copy();
+
+ ws = width();
+ hs = height();
+
+ TQWMatrix mat( matrix.m11(), matrix.m12(), matrix.m21(), matrix.m22(), 0., 0. );
+
+ double scaledWidth;
+ double scaledHeight;
+
+ if ( matrix.m12() == 0.0F && matrix.m21() == 0.0F ) {
+ if ( matrix.m11() == 1.0F && matrix.m22() == 1.0F )
+ return *this; // identity matrix
+ scaledHeight = matrix.m22()*hs;
+ scaledWidth = matrix.m11()*ws;
+ h = TQABS( tqRound( scaledHeight ) );
+ w = TQABS( tqRound( scaledWidth ) );
+ } else { // rotation or shearing
+ TQPointArray a( TQRect(0,0,ws+1,hs+1) );
+ a = mat.map( a );
+ TQRect r = a.boundingRect().normalize();
+ w = r.width()-1;
+ h = r.height()-1;
+ scaledWidth = w;
+ scaledHeight = h;
+ }
+
+ mat = trueMatrix( mat, ws, hs ); // true matrix
+
+
+ bool invertible;
+ mat = mat.invert( &invertible ); // invert matrix
+
+ if ( h == 0 || w == 0 || !invertible
+ || TQABS(scaledWidth) >= 32768 || TQABS(scaledHeight) >= 32768 ) { // error, return null pixmap
+ TQPixmap pm;
+ pm.data->bitmap = data->bitmap;
+ return pm;
+ }
+
+#if defined(TQT_MITSHM)
+ static bool try_once = TRUE;
+ if (try_once) {
+ try_once = FALSE;
+ if ( !xshminit )
+ qt_create_mitshm_buffer( this, 800, 600 );
+ }
+
+ bool use_mitshm = xshmimg && !depth1 &&
+ xshmimg->width >= w && xshmimg->height >= h;
+#endif
+ XImage *xi = (XImage*)data->ximage; // any cached ximage?
+ if ( !xi )
+ xi = XGetImage( x11Display(), handle(), 0, 0, ws, hs, AllPlanes,
+ depth1 ? XYPixmap : ZPixmap );
+
+ if ( !xi ) { // error, return null pixmap
+ TQPixmap pm;
+ pm.data->bitmap = data->bitmap;
+ pm.data->alphapm = data->alphapm;
+ return pm;
+ }
+
+ sbpl = xi->bytes_per_line;
+ sptr = (uchar *)xi->data;
+ bpp = xi->bits_per_pixel;
+
+ if ( depth1 )
+ dbpl = (w+7)/8;
+ else
+ dbpl = ((w*bpp+31)/32)*4;
+ dbytes = dbpl*h;
+
+#if defined(TQT_MITSHM)
+ if ( use_mitshm ) {
+ dptr = (uchar *)xshmimg->data;
+ uchar fillbyte = bpp == 8 ? white.pixel() : 0xff;
+ for ( int y=0; y<h; y++ )
+ memset( dptr + y*xshmimg->bytes_per_line, fillbyte, dbpl );
+ } else {
+#endif
+ dptr = (uchar *)malloc( dbytes ); // create buffer for bits
+ TQ_CHECK_PTR( dptr );
+ if ( depth1 ) // fill with zeros
+ memset( dptr, 0, dbytes );
+ else if ( bpp == 8 ) // fill with background color
+ memset( dptr, TQt::white.pixel( x11Screen() ), dbytes );
+ else
+ memset( dptr, 0xff, dbytes );
+#if defined(TQT_MITSHM)
+ }
+#endif
+
+ // #define TQT_DEBUG_XIMAGE
+#if defined(TQT_DEBUG_XIMAGE)
+ qDebug( "----IMAGE--INFO--------------" );
+ qDebug( "width............. %d", xi->width );
+ qDebug( "height............ %d", xi->height );
+ qDebug( "xoffset........... %d", xi->xoffset );
+ qDebug( "format............ %d", xi->format );
+ qDebug( "byte order........ %d", xi->byte_order );
+ qDebug( "bitmap unit....... %d", xi->bitmap_unit );
+ qDebug( "bitmap bit order.. %d", xi->bitmap_bit_order );
+ qDebug( "depth............. %d", xi->depth );
+ qDebug( "bytes per line.... %d", xi->bytes_per_line );
+ qDebug( "bits per pixel.... %d", xi->bits_per_pixel );
+#endif
+
+ int type;
+ if ( xi->bitmap_bit_order == MSBFirst )
+ type = TQT_XFORM_TYPE_MSBFIRST;
+ else
+ type = TQT_XFORM_TYPE_LSBFIRST;
+ int xbpl, p_inc;
+ if ( depth1 ) {
+ xbpl = (w+7)/8;
+ p_inc = dbpl - xbpl;
+ } else {
+ xbpl = (w*bpp)/8;
+ p_inc = dbpl - xbpl;
+#if defined(TQT_MITSHM)
+ if ( use_mitshm )
+ p_inc = xshmimg->bytes_per_line - xbpl;
+#endif
+ }
+
+ if ( !qt_xForm_helper( mat, xi->xoffset, type, bpp, dptr, xbpl, p_inc, h, sptr, sbpl, ws, hs ) ){
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPixmap::xForm: display not supported (bpp=%d)",bpp);
+#endif
+ TQPixmap pm;
+ return pm;
+ }
+
+ if ( data->optim == NoOptim ) { // throw away ximage
+ qSafeXDestroyImage( xi );
+ data->ximage = 0;
+ } else { // keep ximage that we fetched
+ data->ximage = xi;
+ }
+
+ if ( depth1 ) { // mono bitmap
+ TQPixmap pm( w, h, dptr, TQImage::systemBitOrder() != TQImage::BigEndian );
+ pm.data->bitmap = data->bitmap;
+ free( dptr );
+ if ( data->tqmask ) {
+ if ( data->selfmask ) // pixmap == tqmask
+ pm.setMask( *((TQBitmap*)(&pm)) );
+ else
+ pm.setMask( data->tqmask->xForm(matrix) );
+ }
+ return pm;
+ } else { // color pixmap
+ GC gc = qt_xget_readonly_gc( x11Screen(), FALSE );
+ TQPixmap pm( w, h );
+ pm.data->uninit = FALSE;
+ pm.x11SetScreen( x11Screen() );
+#if defined(TQT_MITSHM)
+ if ( use_mitshm ) {
+ XCopyArea( dpy, xshmpm, pm.handle(), gc, 0, 0, w, h, 0, 0 );
+ } else {
+#endif
+ xi = XCreateImage( dpy, (Visual *)x11Visual(), x11Depth(),
+ ZPixmap, 0, (char *)dptr, w, h, 32, 0 );
+ XPutImage( dpy, pm.handle(), gc, xi, 0, 0, 0, 0, w, h);
+ qSafeXDestroyImage( xi );
+#if defined(TQT_MITSHM)
+ }
+#endif
+
+ if ( data->tqmask ) // xform tqmask, too
+ pm.setMask( data->tqmask->xForm(matrix) );
+
+#ifndef TQT_NO_XFTFREETYPE
+ if ( qt_use_xrender && qt_has_xft && data->alphapm ) { // xform the alpha channel
+ XImage *axi = 0;
+ if ((axi = XGetImage(x11Display(), data->alphapm->handle(),
+ 0, 0, ws, hs, AllPlanes, ZPixmap))) {
+ sbpl = axi->bytes_per_line;
+ sptr = (uchar *) axi->data;
+ bpp = axi->bits_per_pixel;
+ dbytes = dbpl * h;
+ dptr = (uchar *) malloc(dbytes);
+ TQ_CHECK_PTR( dptr );
+ memset(dptr, 0, dbytes);
+ if ( axi->bitmap_bit_order == MSBFirst )
+ type = TQT_XFORM_TYPE_MSBFIRST;
+ else
+ type = TQT_XFORM_TYPE_LSBFIRST;
+
+ if (qt_xForm_helper( mat, axi->xoffset, type, bpp, dptr, w,
+ 0, h, sptr, sbpl, ws, hs )) {
+ delete pm.data->alphapm;
+ pm.data->alphapm = new TQPixmap; // create a null pixmap
+
+ // setup pixmap data
+ pm.data->alphapm->data->w = w;
+ pm.data->alphapm->data->h = h;
+ pm.data->alphapm->data->d = 8;
+
+ // create 8bpp pixmap and render picture
+ pm.data->alphapm->hd =
+ XCreatePixmap(x11Display(),
+ RootWindow(x11Display(), x11Screen()),
+ w, h, 8);
+
+ pm.data->alphapm->rendhd =
+ (HANDLE) XftDrawCreateAlpha( x11Display(),
+ pm.data->alphapm->hd, 8 );
+
+ XImage *axi2 = XCreateImage(x11Display(), (Visual *) x11Visual(),
+ 8, ZPixmap, 0, (char *)dptr, w, h, 8, 0);
+
+ if (axi2) {
+ // the data is deleted by qSafeXDestroyImage
+ GC gc = XCreateGC(x11Display(), pm.data->alphapm->hd, 0, 0);
+ XPutImage(dpy, pm.data->alphapm->hd, gc, axi2, 0, 0, 0, 0, w, h);
+ XFreeGC(x11Display(), gc);
+ qSafeXDestroyImage(axi2);
+ }
+ }
+ qSafeXDestroyImage(axi);
+ }
+ }
+#endif // TQT_NO_XFTFREETYPE
+
+ return pm;
+ }
+}
+
+
+/*!
+ \internal
+*/
+int TQPixmap::x11SetDefaultScreen( int screen )
+{
+ int old = defaultScreen;
+ defaultScreen = screen;
+ return old;
+}
+
+/*!
+ \internal
+*/
+void TQPixmap::x11SetScreen( int screen )
+{
+ if ( screen < 0 )
+ screen = x11AppScreen();
+
+ if ( screen == x11Screen() )
+ return; // nothing to do
+
+ if ( isNull() ) {
+ TQPaintDeviceX11Data* xd = getX11Data( TRUE );
+ xd->x_screen = screen;
+ xd->x_depth = TQPaintDevice::x11AppDepth( screen );
+ xd->x_cells = TQPaintDevice::x11AppCells( screen );
+ xd->x_colormap = TQPaintDevice::x11AppColormap( screen );
+ xd->x_defcolormap = TQPaintDevice::x11AppDefaultColormap( screen );
+ xd->x_visual = TQPaintDevice::x11AppVisual( screen );
+ xd->x_defvisual = TQPaintDevice::x11AppDefaultVisual( screen );
+ setX11Data( xd );
+ return;
+ }
+#if 0
+ qDebug("TQPixmap::x11SetScreen for %p from %d to %d. Size is %d/%d", data, x11Screen(), screen, width(), height() );
+#endif
+
+ TQImage img = convertToImage();
+ resize(0,0);
+ TQPaintDeviceX11Data* xd = getX11Data( TRUE );
+ xd->x_screen = screen;
+ xd->x_depth = TQPaintDevice::x11AppDepth( screen );
+ xd->x_cells = TQPaintDevice::x11AppCells( screen );
+ xd->x_colormap = TQPaintDevice::x11AppColormap( screen );
+ xd->x_defcolormap = TQPaintDevice::x11AppDefaultColormap( screen );
+ xd->x_visual = TQPaintDevice::x11AppVisual( screen );
+ xd->x_defvisual = TQPaintDevice::x11AppDefaultVisual( screen );
+ setX11Data( xd );
+ convertFromImage( img );
+}
+
+/*!
+ Returns TRUE this pixmap has an alpha channel or a tqmask.
+
+ \sa hasAlphaChannel() tqmask()
+*/
+bool TQPixmap::hasAlpha() const
+{
+ return data->alphapm || data->tqmask;
+}
+
+/*!
+ Returns TRUE if the pixmap has an alpha channel; otherwise it
+ returns FALSE.
+
+ NOTE: If the pixmap has a tqmask but not alpha channel, this
+ function returns FALSE.
+
+ \sa hasAlpha() tqmask()
+*/
+bool TQPixmap::hasAlphaChannel() const
+{
+ return data->alphapm != 0;
+}
+
+/*!
+ \relates TQPixmap
+
+ Copies a block of pixels from \a src to \a dst. The alpha channel
+ and tqmask data (if any) is also copied from \a src. NOTE: \a src
+ is \e not alpha blended or masked when copied to \a dst. Use
+ bitBlt() or TQPainter::drawPixmap() to perform alpha blending or
+ masked drawing.
+
+ \a sx, \a sy is the top-left pixel in \a src (0, 0 by default), \a
+ dx, \a dy is the top-left position in \a dst and \a sw, \sh is the
+ size of the copied block (all of \a src by default).
+
+ If \a src, \a dst, \a sw or \a sh is 0 (zero), copyBlt() does
+ nothing. If \a sw or \a sh is negative, copyBlt() copies starting
+ at \a sx (and respectively, \a sy) and ending at the right edge
+ (and respectively, the bottom edge) of \a src.
+
+ copyBlt() does nothing if \a src and \a dst have different depths.
+*/
+TQ_EXPORT void copyBlt( TQPixmap *dst, int dx, int dy,
+ const TQPixmap *src, int sx, int sy, int sw, int sh )
+{
+ if ( ! dst || ! src || sw == 0 || sh == 0 || dst->depth() != src->depth() ) {
+#ifdef TQT_CHECK_NULL
+ TQ_ASSERT( dst != 0 );
+ TQ_ASSERT( src != 0 );
+#endif
+ return;
+ }
+
+ // copy pixel data
+ bitBlt( dst, dx, dy, src, sx, sy, sw, sh, TQt::CopyROP, TRUE );
+
+ // copy tqmask data
+ if ( src->data->tqmask ) {
+ if ( ! dst->data->tqmask ) {
+ dst->data->tqmask = new TQBitmap( dst->width(), dst->height() );
+
+ // new masks are fully opaque by default
+ dst->data->tqmask->fill( TQt::color1 );
+ }
+
+ bitBlt( dst->data->tqmask, dx, dy,
+ src->data->tqmask, sx, sy, sw, sh, TQt::CopyROP, TRUE );
+ }
+
+#ifndef TQT_NO_XFTFREETYPE
+ // copy alpha data
+ extern bool qt_use_xrender; // from qapplication_x11.cpp
+ if ( ! qt_use_xrender || ! src->data->alphapm )
+ return;
+
+ if ( sw < 0 )
+ sw = src->width() - sx;
+ else
+ sw = TQMIN( src->width()-sx, sw );
+ sw = TQMIN( dst->width()-dx, sw );
+
+ if ( sh < 0 )
+ sh = src->height() - sy ;
+ else
+ sh = TQMIN( src->height()-sy, sh );
+ sh = TQMIN( dst->height()-dy, sh );
+
+ if ( sw <= 0 || sh <= 0 )
+ return;
+
+ // create an alpha pixmap for dst if it doesn't exist
+ bool do_init = FALSE;
+ if ( ! dst->data->alphapm ) {
+ dst->data->alphapm = new TQPixmap;
+
+ // setup pixmap d
+ dst->data->alphapm->data->w = dst->width();
+ dst->data->alphapm->data->h = dst->height();
+ dst->data->alphapm->data->d = 8;
+
+ // create 8bpp pixmap and render picture
+ dst->data->alphapm->hd =
+ XCreatePixmap(dst->x11Display(),
+ RootWindow(dst->x11Display(), dst->x11Screen()),
+ dst->width(), dst->height(), 8);
+
+ // new alpha pixmaps should be fully opaque by default
+ do_init = TRUE;
+
+ dst->data->alphapm->rendhd =
+ (TQt::HANDLE) XftDrawCreateAlpha( dst->x11Display(),
+ dst->data->alphapm->hd, 8 );
+ }
+
+ GC gc = XCreateGC(dst->x11Display(), dst->data->alphapm->hd, 0, 0);
+
+ if ( do_init ) {
+ // the alphapm was just created, make it fully opaque
+ XSetForeground( dst->x11Display(), gc, 255 );
+ XSetBackground( dst->x11Display(), gc, 255 );
+ XFillRectangle( dst->x11Display(), dst->data->alphapm->hd, gc,
+ 0, 0, dst->data->alphapm->data->w,
+ dst->data->alphapm->data->h );
+ }
+
+ XCopyArea(dst->x11Display(), src->data->alphapm->hd, dst->data->alphapm->hd, gc,
+ sx, sy, sw, sh, dx, dy);
+ XFreeGC(dst->x11Display(), gc);
+#endif // TQT_NO_XFTFREETYPE
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqpixmapcache.cpp b/tqtinterface/qt4/src/kernel/tqpixmapcache.cpp
new file mode 100644
index 0000000..6724d82
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpixmapcache.cpp
@@ -0,0 +1,336 @@
+/****************************************************************************
+**
+** Implementation of TQPixmapCache class
+**
+** Created : 950504
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpixmapcache.h"
+#include "tqcache.h"
+#include "tqobject.h"
+#include "tqcleanuphandler.h"
+
+
+// REVISED: paul
+/*!
+ \class TQPixmapCache tqpixmapcache.h
+
+ \brief The TQPixmapCache class provides an application-global cache for
+ pixmaps.
+
+ \ingroup environment
+ \ingroup graphics
+ \ingroup images
+
+ This class is a tool for optimized drawing with TQPixmap. You can
+ use it to store temporary pixmaps that are expensive to generate
+ without using more storage space than cacheLimit(). Use insert()
+ to insert pixmaps, tqfind() to tqfind them and clear() to empty the
+ cache.
+
+ For example, TQRadioButton has a non-trivial visual representation
+ so we don't want to regenerate a pixmap whenever a radio button is
+ displayed or changes state. In the function
+ TQRadioButton::drawButton(), we do not draw the radio button
+ directly. Instead, we first check the global pixmap cache for a
+ pixmap with the key "$qt_radio_nnn_", where \c nnn is a numerical
+ value that specifies the the radio button state. If a pixmap is
+ found, we bitBlt() it onto the widget and return. Otherwise, we
+ create a new pixmap, draw the radio button in the pixmap, and
+ finally insert the pixmap in the global pixmap cache, using the
+ key above. The bitBlt() is ten times faster than drawing the
+ radio button. All radio buttons in the program share the cached
+ pixmap since TQPixmapCache is application-global.
+
+ TQPixmapCache tqcontains no member data, only static functions to
+ access the global pixmap cache. It creates an internal TQCache for
+ caching the pixmaps.
+
+ The cache associates a pixmap with a string (key). If two pixmaps
+ are inserted into the cache using equal keys, then the last pixmap
+ will hide the first pixmap. The TQDict and TQCache classes do
+ exactly the same.
+
+ The cache becomes full when the total size of all pixmaps in the
+ cache exceeds cacheLimit(). The initial cache limit is 1024 KByte
+ (1 MByte); it is changed with setCacheLimit(). A pixmap takes
+ roughly width*height*depth/8 bytes of memory.
+
+ See the \l TQCache documentation for more details about the cache
+ mechanism.
+*/
+
+
+static const int cache_size = 149; // size of internal hash array
+#ifdef TQ_WS_MAC9
+static int cache_limit = 256; // 256 KB cache limit
+#else
+static int cache_limit = 1024; // 1024 KB cache limit
+#endif
+
+class TQPMCache: public TQObject, public TQCache<TQPixmap>
+{
+public:
+ TQPMCache():
+ TQObject( 0, "global pixmap cache" ),
+ TQCache<TQPixmap>( cache_limit * 1024, cache_size ),
+ id( 0 ), ps( 0 ), t( FALSE )
+ {
+ setAutoDelete( TRUE );
+ }
+ ~TQPMCache() {}
+ void timerEvent( TQTimerEvent * );
+ bool insert( const TQString& k, const TQPixmap *d, int c, int p = 0 );
+private:
+ int id;
+ int ps;
+ bool t;
+};
+
+
+/*
+ This is supposed to cut the cache size down by about 80-90% in a
+ minute once the application becomes idle, to let any inserted pixmap
+ remain in the cache for some time before it becomes a candidate for
+ cleaning-up, and to not cut down the size of the cache while the
+ cache is in active use.
+
+ When the last pixmap has been deleted from the cache, kill the
+ timer so TQt won't keep the CPU from going into sleep mode.
+*/
+
+void TQPMCache::timerEvent( TQTimerEvent * )
+{
+ int mc = maxCost();
+ bool nt = totalCost() == ps;
+ setMaxCost( nt ? totalCost() * 3 / 4 : totalCost() -1 );
+ setMaxCost( mc );
+ ps = totalCost();
+
+ if ( !count() ) {
+ killTimer( id );
+ id = 0;
+ } else if ( nt != t ) {
+ killTimer( id );
+ id = startTimer( nt ? 10000 : 30000 );
+ t = nt;
+ }
+}
+
+bool TQPMCache::insert( const TQString& k, const TQPixmap *d, int c, int p )
+{
+ bool r = TQCache<TQPixmap>::insert( k, d, c, p );
+ if ( r && !id ) {
+ id = startTimer( 30000 );
+ t = FALSE;
+ }
+ return r;
+}
+
+static TQPMCache *pm_cache = 0; // global pixmap cache
+
+static TQSingleCleanupHandler<TQPMCache> qpm_cleanup_cache;
+
+/*!
+ Returns the pixmap associated with the \a key in the cache, or
+ null if there is no such pixmap.
+
+ \warning If valid, you should copy the pixmap immediately (this is
+ fast). Subsequent insertions into the cache could cause the
+ pointer to become invalid. For this reason, we recommend you use
+ tqfind(const TQString&, TQPixmap&) instead.
+
+ Example:
+ \code
+ TQPixmap* pp;
+ TQPixmap p;
+ if ( (pp=TQPixmapCache::tqfind("my_big_image", pm)) ) {
+ p = *pp;
+ } else {
+ p.load("bigimage.png");
+ TQPixmapCache::insert("my_big_image", new TQPixmap(p));
+ }
+ painter->drawPixmap(0, 0, p);
+ \endcode
+*/
+
+TQPixmap *TQPixmapCache::tqfind( const TQString &key )
+{
+ return pm_cache ? pm_cache->tqfind(key) : 0;
+}
+
+
+/*!
+ \overload
+
+ Looks for a cached pixmap associated with the \a key in the cache.
+ If a pixmap is found, the function sets \a pm to that pixmap and
+ returns TRUE; otherwise leaves \a pm alone and returns FALSE.
+
+ Example:
+ \code
+ TQPixmap p;
+ if ( !TQPixmapCache::tqfind("my_big_image", pm) ) {
+ pm.load("bigimage.png");
+ TQPixmapCache::insert("my_big_image", pm);
+ }
+ painter->drawPixmap(0, 0, p);
+ \endcode
+*/
+
+bool TQPixmapCache::tqfind( const TQString &key, TQPixmap& pm )
+{
+ TQPixmap* p = pm_cache ? pm_cache->tqfind(key) : 0;
+ if ( p ) pm = *p;
+ return !!p;
+}
+
+
+/*!
+ \obsolete
+ Inserts the pixmap \a pm associated with \a key into the cache.
+ Returns TRUE if successful, or FALSE if the pixmap is too big for the cache.
+
+ <strong>
+ Note: \a pm must be allocated on the heap (using \c new).
+
+ If this function returns FALSE, you must delete \a pm yourself.
+
+ If this function returns TRUE, do not use \a pm afterwards or
+ keep references to it because any other insertions into the cache,
+ whether from anywhere in the application or within TQt itself, could cause
+ the pixmap to be discarded from the cache and the pointer to
+ become invalid.
+
+ Due to these dangers, we strongly recommend that you use
+ insert(const TQString&, const TQPixmap&) instead.
+ </strong>
+*/
+
+bool TQPixmapCache::insert( const TQString &key, TQPixmap *pm )
+{
+ if ( !pm_cache ) { // create pixmap cache
+ pm_cache = new TQPMCache;
+ TQ_CHECK_PTR( pm_cache );
+ qpm_cleanup_cache.set( &pm_cache );
+ }
+ return pm_cache->insert( key, pm, pm->width()*pm->height()*pm->depth()/8 );
+}
+
+/*!
+ Inserts a copy of the pixmap \a pm associated with the \a key into
+ the cache.
+
+ All pixmaps inserted by the TQt library have a key starting with
+ "$qt", so your own pixmap keys should never begin "$qt".
+
+ When a pixmap is inserted and the cache is about to exceed its
+ limit, it removes pixmaps until there is enough room for the
+ pixmap to be inserted.
+
+ The oldest pixmaps (least recently accessed in the cache) are
+ deleted when more space is needed.
+
+ \sa setCacheLimit().
+*/
+
+bool TQPixmapCache::insert( const TQString &key, const TQPixmap& pm )
+{
+ if ( !pm_cache ) { // create pixmap cache
+ pm_cache = new TQPMCache;
+ TQ_CHECK_PTR( pm_cache );
+ qpm_cleanup_cache.set( &pm_cache );
+ }
+ TQPixmap *p = new TQPixmap(pm);
+ bool rt = pm_cache->insert( key, p, p->width()*p->height()*p->depth()/8 );
+ if ( !rt )
+ delete p;
+
+ return rt;
+}
+
+/*!
+ Returns the cache limit (in kilobytes).
+
+ The default setting is 1024 kilobytes.
+
+ \sa setCacheLimit().
+*/
+
+int TQPixmapCache::cacheLimit()
+{
+ return cache_limit;
+}
+
+/*!
+ Sets the cache limit to \a n kilobytes.
+
+ The default setting is 1024 kilobytes.
+
+ \sa cacheLimit()
+*/
+
+void TQPixmapCache::setCacheLimit( int n )
+{
+#ifdef TQ_WS_MAC9
+ if(n > 256)
+ qWarning("TQPixmapCache::setCacheLimit: Setting cache limits high is harmfull to mac9's health");
+#endif
+ cache_limit = n;
+ if ( pm_cache )
+ pm_cache->setMaxCost( 1024*cache_limit );
+}
+
+
+/*!
+ Removes the pixmap associated with \a key from the cache.
+*/
+void TQPixmapCache::remove( const TQString &key )
+{
+ if ( pm_cache )
+ pm_cache->remove( key );
+}
+
+
+/*!
+ Removes all pixmaps from the cache.
+*/
+
+void TQPixmapCache::clear()
+{
+ if ( pm_cache )
+ pm_cache->clear();
+}
diff --git a/tqtinterface/qt4/src/kernel/tqpixmapcache.h b/tqtinterface/qt4/src/kernel/tqpixmapcache.h
new file mode 100644
index 0000000..ba543ac
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpixmapcache.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Definition of TQPixmapCache class
+**
+** Created : 950501
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPIXMAPCACHE_H
+#define TQPIXMAPCACHE_H
+
+#ifndef TQT_H
+#include "tqpixmap.h"
+#endif // TQT_H
+
+
+class TQ_EXPORT TQPixmapCache // global pixmap cache
+{
+public:
+ static int cacheLimit();
+ static void setCacheLimit( int );
+ static TQPixmap *tqfind( const TQString &key );
+ static bool tqfind( const TQString &key, TQPixmap& );
+ static bool insert( const TQString &key, TQPixmap * );
+ static bool insert( const TQString &key, const TQPixmap& );
+ static void remove( const TQString &key );
+ static void clear();
+};
+
+
+#endif // TQPIXMAPCACHE_H
diff --git a/tqtinterface/qt4/src/kernel/tqpngio.cpp b/tqtinterface/qt4/src/kernel/tqpngio.cpp
new file mode 100644
index 0000000..7c8cf1d
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpngio.cpp
@@ -0,0 +1,1250 @@
+/****************************************************************************
+**
+** Implementation of PNG TQImage IOHandler
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpngio.h"
+
+#ifndef TQT_NO_IMAGEIO_PNG
+
+#include "tqasyncimageio.h"
+#include "tqiodevice.h"
+
+#include <png.h>
+
+
+#ifdef TQ_OS_TEMP
+#define CALLBACK_CALL_TYPE __cdecl
+#else
+#define CALLBACK_CALL_TYPE
+#endif
+
+
+/*
+ All PNG files load to the minimal TQImage equivalent.
+
+ All TQImage formats output to reasonably efficient PNG equivalents.
+ Never to grayscale.
+*/
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static
+void CALLBACK_CALL_TYPE iod_read_fn(png_structp png_ptr, png_bytep data, png_size_t length)
+{
+ TQImageIO* iio = (TQImageIO*)png_get_io_ptr(png_ptr);
+ TQIODevice* in = iio->ioDevice();
+
+ while (length) {
+ int nr = in->readBlock((char*)data, length);
+ if (nr <= 0) {
+ png_error(png_ptr, "Read Error");
+ return;
+ }
+ length -= nr;
+ }
+}
+
+
+static
+void CALLBACK_CALL_TYPE qpiw_write_fn( png_structp png_ptr, png_bytep data, png_size_t length )
+{
+ TQPNGImageWriter* qpiw = (TQPNGImageWriter*)png_get_io_ptr( png_ptr );
+ TQIODevice* out = qpiw->tqdevice();
+
+ uint nr = out->writeBlock( (char*)data, length );
+ if ( nr != length ) {
+ png_error( png_ptr, "Write Error" );
+ return;
+ }
+}
+
+
+static
+void CALLBACK_CALL_TYPE qpiw_flush_fn( png_structp png_ptr )
+{
+ TQPNGImageWriter* qpiw = (TQPNGImageWriter*)png_get_io_ptr( png_ptr );
+ TQIODevice* out = qpiw->tqdevice();
+
+ out->flush();
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+static
+void setup_qt( TQImage& image, png_structp png_ptr, png_infop info_ptr, float screen_gamma=0.0 )
+{
+ if ( screen_gamma != 0.0 && png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA) ) {
+ double file_gamma;
+ png_get_gAMA(png_ptr, info_ptr, &file_gamma);
+ png_set_gamma( png_ptr, screen_gamma, file_gamma );
+ }
+
+ png_uint_32 width;
+ png_uint_32 height;
+ int bit_depth;
+ int color_type;
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+ 0, 0, 0);
+
+ if ( color_type == PNG_COLOR_TYPE_GRAY ) {
+ // Black & White or 8-bit grayscale
+ if ( bit_depth == 1 && info_ptr->channels == 1 ) {
+ png_set_invert_mono( png_ptr );
+ png_read_update_info( png_ptr, info_ptr );
+ if (!image.create( width, height, 1, 2, TQImage::BigEndian ))
+ return;
+ image.setColor( 1, tqRgb(0,0,0) );
+ image.setColor( 0, tqRgb(255,255,255) );
+ } else if (bit_depth == 16 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ png_set_expand(png_ptr);
+ png_set_strip_16(png_ptr);
+ png_set_gray_to_rgb(png_ptr);
+
+ if (!image.create(width, height, 32))
+ return;
+ image.setAlphaBuffer(TRUE);
+
+ if (TQImage::systemByteOrder() == TQImage::BigEndian)
+ png_set_swap_alpha(png_ptr);
+
+ png_read_update_info(png_ptr, info_ptr);
+ } else {
+ if ( bit_depth == 16 )
+ png_set_strip_16(png_ptr);
+ else if ( bit_depth < 8 )
+ png_set_packing(png_ptr);
+ int ncols = bit_depth < 8 ? 1 << bit_depth : 256;
+ png_read_update_info(png_ptr, info_ptr);
+ if (!image.create(width, height, 8, ncols))
+ return;
+ for (int i=0; i<ncols; i++) {
+ int c = i*255/(ncols-1);
+ image.setColor( i, tqRgba(c,c,c,0xff) );
+ }
+ if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ) {
+ const int g = info_ptr->trans_values.gray;
+ if (g < ncols) {
+ image.setAlphaBuffer(TRUE);
+ image.setColor(g, image.color(g) & TQRGB_MASK);
+ }
+ }
+ }
+ } else if ( color_type == PNG_COLOR_TYPE_PALETTE
+ && png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE)
+ && info_ptr->num_palette <= 256 )
+ {
+ // 1-bit and 8-bit color
+ if ( bit_depth != 1 )
+ png_set_packing( png_ptr );
+ png_read_update_info( png_ptr, info_ptr );
+ png_get_IHDR(png_ptr, info_ptr,
+ &width, &height, &bit_depth, &color_type, 0, 0, 0);
+ if (!image.create(width, height, bit_depth, info_ptr->num_palette,
+ TQImage::BigEndian))
+ return;
+ int i = 0;
+ if ( png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) ) {
+ image.setAlphaBuffer( TRUE );
+ while ( i < info_ptr->num_trans ) {
+ image.setColor(i, tqRgba(
+ info_ptr->palette[i].red,
+ info_ptr->palette[i].green,
+ info_ptr->palette[i].blue,
+ info_ptr->trans[i]
+ )
+ );
+ i++;
+ }
+ }
+ while ( i < info_ptr->num_palette ) {
+ image.setColor(i, tqRgba(
+ info_ptr->palette[i].red,
+ info_ptr->palette[i].green,
+ info_ptr->palette[i].blue,
+ 0xff
+ )
+ );
+ i++;
+ }
+ } else {
+ // 32-bit
+ if ( bit_depth == 16 )
+ png_set_strip_16(png_ptr);
+
+ png_set_expand(png_ptr);
+
+ if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA )
+ png_set_gray_to_rgb(png_ptr);
+
+ if (!image.create(width, height, 32))
+ return;
+
+ // Only add filler if no alpha, or we can get 5 channel data.
+ if (!(color_type & PNG_COLOR_MASK_ALPHA)
+ && !png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ png_set_filler(png_ptr, 0xff,
+ TQImage::systemByteOrder() == TQImage::BigEndian ?
+ PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
+ // We want 4 bytes, but it isn't an alpha channel
+ } else {
+ image.setAlphaBuffer(TRUE);
+ }
+
+ if ( TQImage::systemByteOrder() == TQImage::BigEndian ) {
+ png_set_swap_alpha(png_ptr);
+ }
+
+ png_read_update_info(png_ptr, info_ptr);
+ }
+
+ // TQt==ARGB==Big(ARGB)==Little(BGRA)
+ if ( TQImage::systemByteOrder() == TQImage::LittleEndian ) {
+ png_set_bgr(png_ptr);
+ }
+}
+
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+static void CALLBACK_CALL_TYPE qt_png_warning(png_structp /*png_ptr*/, png_const_charp message)
+{
+ qWarning("libpng warning: %s", message);
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+static
+void read_png_image(TQImageIO* iio)
+{
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_infop end_info;
+ png_bytep* row_pointers;
+
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,0,0,0);
+ if (!png_ptr) {
+ iio->setqStatus(-1);
+ return;
+ }
+
+ png_set_error_fn(png_ptr, 0, 0, qt_png_warning);
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ png_destroy_read_struct(&png_ptr, 0, 0);
+ iio->setqStatus(-2);
+ return;
+ }
+
+ end_info = png_create_info_struct(png_ptr);
+ if (!end_info) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, 0);
+ iio->setqStatus(-3);
+ return;
+ }
+
+ if (setjmp(png_ptr->jmpbuf)) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ iio->setqStatus(-4);
+ return;
+ }
+
+ png_set_read_fn(png_ptr, (void*)iio, iod_read_fn);
+ png_read_info(png_ptr, info_ptr);
+
+ TQImage image;
+ setup_qt(image, png_ptr, info_ptr, iio->gamma());
+ if (image.isNull()) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+ iio->setqStatus(-5);
+ return;
+ }
+
+ png_uint_32 width;
+ png_uint_32 height;
+ int bit_depth;
+ int color_type;
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+ 0, 0, 0);
+
+#if 0 // Jump tables in Qt4 can't be used this way
+ uchar** jt = image.jumpTable();
+ row_pointers=new png_bytep[height];
+
+ for (uint y=0; y<height; y++) {
+ row_pointers[y]=jt[y];
+ }
+#else
+ row_pointers=new png_bytep[height];
+
+ for (uint y=0; y<height; y++) {
+ row_pointers[y]=image.scanLine(y);
+ }
+#endif
+
+ png_read_image(png_ptr, row_pointers);
+
+#if 0 // libpng takes care of this.
+png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)
+ if (image.depth()==32 && png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) {
+ TQRgb trans = 0xFF000000 | tqRgb(
+ (info_ptr->trans_values.red << 8 >> bit_depth)&0xff,
+ (info_ptr->trans_values.green << 8 >> bit_depth)&0xff,
+ (info_ptr->trans_values.blue << 8 >> bit_depth)&0xff);
+ for (uint y=0; y<height; y++) {
+ for (uint x=0; x<info_ptr->width; x++) {
+ if (((uint**)jt)[y][x] == trans) {
+ ((uint**)jt)[y][x] &= 0x00FFFFFF;
+ } else {
+ }
+ }
+ }
+ }
+#endif
+
+ image.setDotsPerMeterX(png_get_x_pixels_per_meter(png_ptr,info_ptr));
+ image.setDotsPerMeterY(png_get_y_pixels_per_meter(png_ptr,info_ptr));
+
+#ifndef TQT_NO_IMAGE_TEXT
+ png_textp text_ptr;
+ int num_text=0;
+ png_get_text(png_ptr,info_ptr,&text_ptr,&num_text);
+ while (num_text--) {
+ image.setText(text_ptr->key,0,text_ptr->text);
+ text_ptr++;
+ }
+#endif
+
+ delete [] row_pointers;
+
+ if ( image.hasAlphaBuffer() ) {
+ // Many PNG files lie (eg. from PhotoShop). Fortunately this loop will
+ // usually be quick to find those that tell the truth.
+ TQRgb* c;
+ int n;
+ if (image.depth()==32) {
+ c = (TQRgb*)image.bits();
+ n = image.bytesPerLine() * image.height() / 4;
+ } else {
+ c = image.tqcolorTable();
+ n = image.numColors();
+ }
+ while ( n-- && tqAlpha(*c++)==0xff )
+ ;
+ if ( n<0 ) // LIAR!
+ image.setAlphaBuffer(FALSE);
+ }
+
+ iio->setImage(image);
+
+ png_read_end(png_ptr, end_info);
+ png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
+
+ iio->setqStatus(0);
+}
+
+TQPNGImageWriter::TQPNGImageWriter(TQIODevice* iod) :
+ dev(iod),
+ frames_written(0),
+ disposal(Unspecified),
+ looping(-1),
+ ms_delay(-1),
+ gamma(0.0)
+{
+}
+
+TQPNGImageWriter::~TQPNGImageWriter()
+{
+}
+
+void TQPNGImageWriter::setDisposalMethod(DisposalMethod dm)
+{
+ disposal = dm;
+}
+
+void TQPNGImageWriter::setLooping(int loops)
+{
+ looping = loops;
+}
+
+void TQPNGImageWriter::setFrameDelay(int msecs)
+{
+ ms_delay = msecs;
+}
+
+void TQPNGImageWriter::setGamma(float g)
+{
+ gamma = g;
+}
+
+
+#ifndef TQT_NO_IMAGE_TEXT
+static void set_text(const TQImage& image, png_structp png_ptr, png_infop info_ptr, bool short_not_long)
+{
+ TQValueList<TQImageTextKeyLang> keys = image.tqtextList();
+ if ( keys.count() ) {
+ png_textp text_ptr = new png_text[keys.count()];
+ int i=0;
+ for (TQValueList<TQImageTextKeyLang>::Iterator it=keys.begin();
+ it != keys.end(); ++it)
+ {
+ TQString t = image.text(*it);
+ if ( (t.length() <= 200) == short_not_long ) {
+ if ( t.length() < 40 )
+ text_ptr[i].compression = PNG_TEXT_COMPRESSION_NONE;
+ else
+ text_ptr[i].compression = PNG_TEXT_COMPRESSION_zTXt;
+ text_ptr[i].key = (png_charp)(*it).key.data();
+ text_ptr[i].text = (png_charp)t.latin1();
+ //text_ptr[i].text = qstrdup(t.latin1());
+ i++;
+ }
+ }
+ png_set_text(png_ptr, info_ptr, text_ptr, i);
+ //for (int j=0; j<i; j++)
+ //free(text_ptr[i].text);
+ delete [] text_ptr;
+ }
+}
+#endif
+
+bool TQPNGImageWriter::writeImage(const TQImage& image, int off_x, int off_y)
+{
+ return writeImage(image, -1, off_x, off_y);
+}
+
+bool TQPNGImageWriter::writeImage(const TQImage& image, int quality_in, int off_x_in, int off_y_in)
+{
+ TQPoint offset = image.offset();
+ int off_x = off_x_in + offset.x();
+ int off_y = off_y_in + offset.y();
+
+ png_structp png_ptr;
+ png_infop info_ptr;
+ png_bytep* row_pointers;
+
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,0,0,0);
+ if (!png_ptr) {
+ return FALSE;
+ }
+
+ png_set_error_fn(png_ptr, 0, 0, qt_png_warning);
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ png_destroy_write_struct(&png_ptr, 0);
+ return FALSE;
+ }
+
+ if (setjmp(png_ptr->jmpbuf)) {
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+ return FALSE;
+ }
+
+ int quality = quality_in;
+ if (quality >= 0) {
+ if (quality > 9) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "PNG: Quality %d out of range", quality );
+#endif
+ quality = 9;
+ }
+ png_set_compression_level(png_ptr, quality);
+ }
+
+ if (gamma != 0.0) {
+ png_set_gAMA(png_ptr, info_ptr, 1.0/gamma);
+ }
+
+ png_set_write_fn(png_ptr, (void*)this, qpiw_write_fn, qpiw_flush_fn);
+
+ info_ptr->channels =
+ (image.depth() == 32)
+ ? (image.hasAlphaBuffer() ? 4 : 3)
+ : 1;
+
+ png_set_IHDR(png_ptr, info_ptr, image.width(), image.height(),
+ image.depth() == 1 ? 1 : 8 /* per channel */,
+ image.depth() == 32
+ ? image.hasAlphaBuffer()
+ ? PNG_COLOR_TYPE_RGB_ALPHA
+ : PNG_COLOR_TYPE_RGB
+ : PNG_COLOR_TYPE_PALETTE, 0, 0, 0);
+
+
+ //png_set_sBIT(png_ptr, info_ptr, 8);
+ info_ptr->sig_bit.red = 8;
+ info_ptr->sig_bit.green = 8;
+ info_ptr->sig_bit.blue = 8;
+
+ if (image.depth() == 1 && image.bitOrder() == TQImage::LittleEndian)
+ png_set_packswap(png_ptr);
+
+ png_colorp palette = 0;
+ png_bytep copy_trans = 0;
+ if (image.numColors()) {
+ // Paletted
+ int num_palette = image.numColors();
+ palette = new png_color[num_palette];
+ png_set_PLTE(png_ptr, info_ptr, palette, num_palette);
+ int* trans = new int[num_palette];
+ int num_trans = 0;
+ for (int i=0; i<num_palette; i++) {
+ TQRgb rgb=image.color(i);
+ info_ptr->palette[i].red = tqRed(rgb);
+ info_ptr->palette[i].green = tqGreen(rgb);
+ info_ptr->palette[i].blue = tqBlue(rgb);
+ if (image.hasAlphaBuffer()) {
+ trans[i] = rgb >> 24;
+ if (trans[i] < 255) {
+ num_trans = i+1;
+ }
+ }
+ }
+ if (num_trans) {
+ copy_trans = new png_byte[num_trans];
+ for (int i=0; i<num_trans; i++)
+ copy_trans[i] = trans[i];
+ png_set_tRNS(png_ptr, info_ptr, copy_trans, num_trans, 0);
+ }
+ delete [] trans;
+ }
+
+ if ( image.hasAlphaBuffer() ) {
+ info_ptr->sig_bit.alpha = 8;
+ }
+
+ // Swap ARGB to RGBA (normal PNG format) before saving on
+ // BigEndian machines
+ if ( TQImage::systemByteOrder() == TQImage::BigEndian ) {
+ png_set_swap_alpha(png_ptr);
+ }
+
+ // TQt==ARGB==Big(ARGB)==Little(BGRA)
+ if ( TQImage::systemByteOrder() == TQImage::LittleEndian ) {
+ png_set_bgr(png_ptr);
+ }
+
+ if (off_x || off_y) {
+ png_set_oFFs(png_ptr, info_ptr, off_x, off_y, PNG_OFFSET_PIXEL);
+ }
+
+ if ( frames_written > 0 )
+ png_set_sig_bytes(png_ptr, 8);
+
+ if ( image.dotsPerMeterX() > 0 || image.dotsPerMeterY() > 0 ) {
+ png_set_pHYs(png_ptr, info_ptr,
+ image.dotsPerMeterX(), image.dotsPerMeterY(),
+ PNG_RESOLUTION_METER);
+ }
+
+#ifndef TQT_NO_IMAGE_TEXT
+ // Write short texts early.
+ set_text(image,png_ptr,info_ptr,TRUE);
+#endif
+
+ png_write_info(png_ptr, info_ptr);
+
+#ifndef TQT_NO_IMAGE_TEXT
+ // Write long texts later.
+ set_text(image,png_ptr,info_ptr,FALSE);
+#endif
+
+ if ( image.depth() != 1 )
+ png_set_packing(png_ptr);
+
+ if ( image.depth() == 32 && !image.hasAlphaBuffer() )
+ png_set_filler(png_ptr, 0,
+ TQImage::systemByteOrder() == TQImage::BigEndian ?
+ PNG_FILLER_BEFORE : PNG_FILLER_AFTER);
+
+ if ( looping >= 0 && frames_written == 0 ) {
+ uchar data[13] = "NETSCAPE2.0";
+ // 0123456789aBC
+ data[0xB] = looping%0x100;
+ data[0xC] = looping/0x100;
+ png_write_chunk(png_ptr, (png_byte*)"gIFx", data, 13);
+ }
+ if ( ms_delay >= 0 || disposal!=Unspecified ) {
+ uchar data[4];
+ data[0] = disposal;
+ data[1] = 0;
+ data[2] = (ms_delay/10)/0x100; // hundredths
+ data[3] = (ms_delay/10)%0x100;
+ png_write_chunk(png_ptr, (png_byte*)"gIFg", data, 4);
+ }
+
+ png_uint_32 width;
+ png_uint_32 height;
+ int bit_depth;
+ int color_type;
+ png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
+ 0, 0, 0);
+
+ uchar** jt = const_cast<TQImage*>(&image)->jumpTable();
+ row_pointers=new png_bytep[height];
+ uint y;
+ for (y=0; y<height; y++) {
+ row_pointers[y]=jt[y];
+ }
+ png_write_image(png_ptr, row_pointers);
+ delete [] row_pointers;
+
+ png_write_end(png_ptr, info_ptr);
+ frames_written++;
+
+ if ( palette )
+ delete [] palette;
+ if ( copy_trans )
+ delete [] copy_trans;
+
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ return TRUE;
+}
+
+static
+void write_png_image(TQImageIO* iio)
+{
+ TQPNGImageWriter writer(iio->ioDevice());
+ int quality = iio->quality();
+ if ( quality >= 0 ) {
+ quality = TQMIN( quality, 100 );
+ quality = (100-quality) * 9 / 91; // map [0,100] -> [9,0]
+ }
+ writer.setGamma(iio->gamma());
+ bool ok = writer.writeImage( iio->image(), quality );
+ iio->setqStatus( ok ? 0 : -1 );
+}
+
+/*!
+ \class TQPNGImagePacker tqpngio.h
+ \brief The TQPNGImagePacker class creates well-compressed PNG animations.
+
+ \ingroup images
+ \ingroup graphics
+
+ By using transparency, TQPNGImagePacker allows you to build a PNG
+ image from a sequence of TQImages.
+
+ Images are added using packImage().
+*/
+
+
+/*!
+ Creates an image packer that writes PNG data to IO tqdevice \a iod
+ using a \a storage_depth bit encoding (use 8 or 32, depending on
+ the desired quality and compression requirements).
+
+ If the image needs to be modified to fit in a lower-resolution
+ result (e.g. converting from 32-bit to 8-bit), use the \a
+ conversionflags to specify how you'd prefer this to happen.
+
+ \sa TQt::ImageConversionFlags
+*/
+TQPNGImagePacker::TQPNGImagePacker(TQIODevice* iod, int storage_depth,
+ int conversionflags) :
+ TQPNGImageWriter(iod),
+ depth(storage_depth),
+ convflags(conversionflags),
+ alignx(1)
+{
+}
+
+/*!
+ Aligns pixel differences to \a x pixels. For example, using 8 can
+ improve playback on certain hardware. Normally the default of
+ 1-pixel tqalignment (i.e. no tqalignment) gives better compression and
+ performance.
+*/
+void TQPNGImagePacker::setPixelAlignment(int x)
+{
+ alignx = x;
+}
+
+/*!
+ Adds the image \a img to the PNG animation, analyzing the
+ differences between this and the previous image to improve
+ compression.
+*/
+bool TQPNGImagePacker::packImage(const TQImage& img)
+{
+ TQImage image = img.convertDepth(32);
+ if ( previous.isNull() ) {
+ // First image
+ writeImage(image.convertDepth(depth,(Qt::ImageConversionFlag)convflags));
+ } else {
+ bool done;
+ int minx, maxx, miny, maxy;
+ int w = image.width();
+ int h = image.height();
+
+ TQRgb** jt = (TQRgb**)image.jumpTable();
+ TQRgb** pjt = (TQRgb**)previous.jumpTable();
+
+ // Find left edge of change
+ done = FALSE;
+ for (minx = 0; minx < w && !done; minx++) {
+ for (int ty = 0; ty < h; ty++) {
+ if ( jt[ty][minx] != pjt[ty][minx] ) {
+ done = TRUE;
+ break;
+ }
+ }
+ }
+ minx--;
+
+ // Find right edge of change
+ done = FALSE;
+ for (maxx = w-1; maxx >= 0 && !done; maxx--) {
+ for (int ty = 0; ty < h; ty++) {
+ if ( jt[ty][maxx] != pjt[ty][maxx] ) {
+ done = TRUE;
+ break;
+ }
+ }
+ }
+ maxx++;
+
+ // Find top edge of change
+ done = FALSE;
+ for (miny = 0; miny < h && !done; miny++) {
+ for (int tx = 0; tx < w; tx++) {
+ if ( jt[miny][tx] != pjt[miny][tx] ) {
+ done = TRUE;
+ break;
+ }
+ }
+ }
+ miny--;
+
+ // Find right edge of change
+ done = FALSE;
+ for (maxy = h-1; maxy >= 0 && !done; maxy--) {
+ for (int tx = 0; tx < w; tx++) {
+ if ( jt[maxy][tx] != pjt[maxy][tx] ) {
+ done = TRUE;
+ break;
+ }
+ }
+ }
+ maxy++;
+
+ if ( minx > maxx ) minx=maxx=0;
+ if ( miny > maxy ) miny=maxy=0;
+
+ if ( alignx > 1 ) {
+ minx -= minx % alignx;
+ maxx = maxx - maxx % alignx + alignx - 1;
+ }
+
+ int dw = maxx-minx+1;
+ int dh = maxy-miny+1;
+
+ TQImage diff(dw, dh, 32);
+
+ diff.setAlphaBuffer(TRUE);
+ int x, y;
+ if ( alignx < 1 )
+ alignx = 1;
+ for (y = 0; y < dh; y++) {
+ TQRgb* li = (TQRgb*)image.scanLine(y+miny)+minx;
+ TQRgb* lp = (TQRgb*)previous.scanLine(y+miny)+minx;
+ TQRgb* ld = (TQRgb*)diff.scanLine(y);
+ if ( alignx ) {
+ for (x = 0; x < dw; x+=alignx) {
+ int i;
+ for (i=0; i<alignx; i++) {
+ if ( li[x+i] != lp[x+i] )
+ break;
+ }
+ if ( i == alignx ) {
+ // All the same
+ for (i=0; i<alignx; i++) {
+ ld[x+i] = tqRgba(0,0,0,0);
+ }
+ } else {
+ // Some different
+ for (i=0; i<alignx; i++) {
+ ld[x+i] = 0xff000000 | li[x+i];
+ }
+ }
+ }
+ } else {
+ for (x = 0; x < dw; x++) {
+ if ( li[x] != lp[x] )
+ ld[x] = 0xff000000 | li[x];
+ else
+ ld[x] = tqRgba(0,0,0,0);
+ }
+ }
+ }
+
+ diff = diff.convertDepth(depth,(Qt::ImageConversionFlag)convflags);
+ if ( !writeImage(diff, minx, miny) )
+ return FALSE;
+ }
+ previous = image;
+ return TRUE;
+}
+
+
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+
+class TQPNGFormat : public TQImageFormat {
+public:
+ TQPNGFormat();
+ virtual ~TQPNGFormat();
+
+ int decode(TQImage& img, TQImageConsumer* consumer,
+ const uchar* buffer, int length);
+
+ void info(png_structp png_ptr, png_infop info);
+ void row(png_structp png_ptr, png_bytep new_row,
+ png_uint_32 row_num, int pass);
+ void end(png_structp png_ptr, png_infop info);
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+ int user_chunk(png_structp png_ptr,
+ png_bytep data, png_uint_32 length);
+#endif
+
+private:
+ // Animation-level information
+ enum { MovieStart, FrameStart, Inside, End } state;
+ int first_frame;
+ int base_offx;
+ int base_offy;
+
+ // Image-level information
+ png_structp png_ptr;
+ png_infop info_ptr;
+
+ // Temporary locals during single data-chunk processing
+ TQImageConsumer* consumer;
+ TQImage* image;
+ int unused_data;
+};
+
+class TQPNGFormatType : public TQImageFormatType
+{
+ TQImageFormat* decoderFor(const uchar* buffer, int length);
+ const char* formatName() const;
+};
+
+
+/*
+ \class TQPNGFormat tqpngio.h
+ \brief The TQPNGFormat class provides an incremental image decoder for PNG
+ image format.
+
+ \ingroup images
+ \ingroup graphics
+
+ This subclass of TQImageFormat decodes PNG format images,
+ including animated PNGs.
+
+ Animated PNG images are standard PNG images. The PNG standard
+ defines two extension chunks that are useful for animations:
+
+ \list
+ \i gIFg - GIF-like Graphic Control Extension.
+ This includes frame disposal, user input flag (we ignore this),
+ and inter-frame delay.
+ \i gIFx - GIF-like Application Extension.
+ This is multi-purpose, but we just use the Netscape extension
+ which specifies looping.
+ \endlist
+
+ The subimages usually contain a offset chunk (oFFs) but need not.
+
+ The first image defines the "screen" size. Any subsequent image that
+ doesn't fit is clipped.
+*/
+/* ###TODO: decide on this point. gIFg gives disposal types, so it can be done.
+ All images paste (\e not composite, just place all-channel copying)
+ over the previous image to produce a subsequent frame.
+*/
+
+/*
+ \class TQPNGFormatType tqasyncimageio.h
+ \brief The TQPNGFormatType class provides an incremental image decoder
+ for PNG image format.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup io
+
+ This subclass of TQImageFormatType recognizes PNG format images, creating
+ a TQPNGFormat when required. An instance of this class is created
+ automatically before any other factories, so you should have no need for
+ such objects.
+*/
+
+TQImageFormat* TQPNGFormatType::decoderFor(
+ const uchar* buffer, int length)
+{
+ if (length < 8) return 0;
+ if (buffer[0]==137
+ && buffer[1]=='P'
+ && buffer[2]=='N'
+ && buffer[3]=='G'
+ && buffer[4]==13
+ && buffer[5]==10
+ && buffer[6]==26
+ && buffer[7]==10)
+ return new TQPNGFormat;
+ return 0;
+}
+
+const char* TQPNGFormatType::formatName() const
+{
+ return "PNG";
+}
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+static void
+CALLBACK_CALL_TYPE info_callback(png_structp png_ptr, png_infop info)
+{
+ TQPNGFormat* that = (TQPNGFormat*)png_get_progressive_ptr(png_ptr);
+ that->info(png_ptr,info);
+}
+
+static void
+CALLBACK_CALL_TYPE row_callback(png_structp png_ptr, png_bytep new_row,
+ png_uint_32 row_num, int pass)
+{
+ TQPNGFormat* that = (TQPNGFormat*)png_get_progressive_ptr(png_ptr);
+ that->row(png_ptr,new_row,row_num,pass);
+}
+
+static void
+CALLBACK_CALL_TYPE end_callback(png_structp png_ptr, png_infop info)
+{
+ TQPNGFormat* that = (TQPNGFormat*)png_get_progressive_ptr(png_ptr);
+ that->end(png_ptr,info);
+}
+
+#if 0
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+static int
+CALLBACK_CALL_TYPE user_chunk_callback(png_structp png_ptr,
+ png_unknown_chunkp chunk)
+{
+ TQPNGFormat* that = (TQPNGFormat*)png_get_progressive_ptr(png_ptr);
+ return that->user_chunk(png_ptr,chunk->data,chunk->size);
+}
+#endif
+#endif
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+/*!
+ Constructs a TQPNGFormat object.
+*/
+TQPNGFormat::TQPNGFormat()
+{
+ state = MovieStart;
+ first_frame = 1;
+ base_offx = 0;
+ base_offy = 0;
+ png_ptr = 0;
+ info_ptr = 0;
+}
+
+
+/*!
+ Destroys a TQPNGFormat object.
+*/
+TQPNGFormat::~TQPNGFormat()
+{
+ if ( png_ptr )
+ png_destroy_read_struct(&png_ptr, &info_ptr, 0);
+}
+
+
+/*!
+ This function decodes some data into image changes.
+
+ Returns the number of bytes consumed.
+*/
+int TQPNGFormat::decode(TQImage& img, TQImageConsumer* cons,
+ const uchar* buffer, int length)
+{
+ consumer = cons;
+ image = &img;
+
+ if ( state != Inside ) {
+ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
+ if (!png_ptr) {
+ info_ptr = 0;
+ image = 0;
+ return -1;
+ }
+
+ png_set_error_fn(png_ptr, 0, 0, qt_png_warning);
+ png_set_compression_level(png_ptr, 9);
+
+ info_ptr = png_create_info_struct(png_ptr);
+ if (!info_ptr) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, 0);
+ image = 0;
+ return -1;
+ }
+
+ if (setjmp((png_ptr)->jmpbuf)) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, 0);
+ image = 0;
+ return -1;
+ }
+
+ png_set_progressive_read_fn(png_ptr, (void *)this,
+ info_callback, row_callback, end_callback);
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+ // Can't do this yet. libpng has a crash bug with unknown (user) chunks.
+ // Warwick has sent them a patch.
+ // png_set_read_user_chunk_fn(png_ptr, 0, user_chunk_callback);
+ // png_set_keep_unknown_chunks(png_ptr, 2/*HANDLE_CHUNK_IF_SAFE*/, 0, 0);
+#endif
+
+ if ( state != MovieStart && *buffer != 0211 ) {
+ // Good, no signature - the preferred way to concat PNG images.
+ // Skip them.
+ png_set_sig_bytes(png_ptr, 8);
+ }
+
+ state = Inside;
+ }
+
+ if ( !png_ptr ) return 0;
+
+ if (setjmp(png_ptr->jmpbuf)) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, 0);
+ image = 0;
+ state = MovieStart;
+ return -1;
+ }
+ unused_data = 0;
+ png_process_data(png_ptr, info_ptr, (png_bytep)buffer, length);
+ int l = length - unused_data;
+
+ // TODO: send incremental stuff to consumer (optional)
+
+ if ( state != Inside ) {
+ if ( png_ptr )
+ png_destroy_read_struct(&png_ptr, &info_ptr, 0);
+ }
+
+ image = 0;
+ return l;
+}
+
+void TQPNGFormat::info(png_structp png, png_infop)
+{
+ png_set_interlace_handling(png);
+ setup_qt(*image, png, info_ptr);
+}
+
+void TQPNGFormat::row(png_structp png, png_bytep new_row,
+ png_uint_32 row_num, int)
+{
+ uchar* old_row = image->scanLine(row_num);
+ png_progressive_combine_row(png, old_row, new_row);
+}
+
+
+void TQPNGFormat::end(png_structp png, png_infop info)
+{
+ int offx = png_get_x_offset_pixels(png,info) - base_offx;
+ int offy = png_get_y_offset_pixels(png,info) - base_offy;
+ if ( first_frame ) {
+ base_offx = offx;
+ base_offy = offy;
+ first_frame = 0;
+ }
+ image->setOffset(TQPoint(offx,offy));
+ image->setDotsPerMeterX(png_get_x_pixels_per_meter(png,info));
+ image->setDotsPerMeterY(png_get_y_pixels_per_meter(png,info));
+#ifndef TQT_NO_IMAGE_TEXT
+ png_textp text_ptr;
+ int num_text=0;
+ png_get_text(png,info,&text_ptr,&num_text);
+ while (num_text--) {
+ image->setText(text_ptr->key,0,text_ptr->text);
+ text_ptr++;
+ }
+#endif
+ TQRect r(0,0,image->width(),image->height());
+ consumer->frameDone(TQPoint(offx,offy),r);
+ consumer->end();
+ state = FrameStart;
+ unused_data = (int)png->buffer_size; // Since libpng doesn't tell us
+}
+
+#ifdef PNG_USER_CHUNKS_SUPPORTED
+
+/*
+#ifndef TQT_NO_IMAGE_TEXT
+static bool skip(png_uint_32& max, png_bytep& data)
+{
+ while (*data) {
+ if ( !max ) return FALSE;
+ max--;
+ data++;
+ }
+ if ( !max ) return FALSE;
+ max--;
+ data++; // skip to after NUL
+ return TRUE;
+}
+#endif
+*/
+
+int TQPNGFormat::user_chunk(png_structp png,
+ png_bytep data, png_uint_32 length)
+{
+#if 0 // NOT SUPPORTED: experimental PNG animation.
+ // qDebug("Got %ld-byte %s chunk", length, png->chunk_name);
+ if ( 0==qstrcmp((char*)png->chunk_name, "gIFg")
+ && length == 4 ) {
+
+ //TQPNGImageWriter::DisposalMethod disposal =
+ // (TQPNGImageWriter::DisposalMethod)data[0];
+ // ### TODO: use the disposal method
+ int ms_delay = ((data[2] << 8) | data[3])*10;
+ consumer->setFramePeriod(ms_delay);
+ return 1;
+ } else if ( 0==qstrcmp((char*)png->chunk_name, "gIFx")
+ && length == 13 ) {
+ if ( tqstrncmp((char*)data,"NETSCAPE2.0",11)==0 ) {
+ int looping = (data[0xC]<<8)|data[0xB];
+ consumer->setLooping(looping);
+ return 1;
+ }
+ }
+#else
+ TQ_UNUSED( png )
+ TQ_UNUSED( data )
+ TQ_UNUSED( length )
+#endif
+
+#ifndef TQT_NO_IMAGE_TEXT
+ /*
+
+ libpng now supports this chunk.
+
+
+ if ( 0==qstrcmp((char*)png->chunk_name, "iTXt") && length>=6 ) {
+ const char* keyword = (const char*)data;
+ if ( !skip(length,data) ) return 0;
+ if ( length >= 4 ) {
+ char compression_flag = *data++;
+ char compression_method = *data++;
+ if ( compression_flag == compression_method ) {
+ // fool the compiler into thinking they're used
+ }
+ const char* lang = (const char*)data;
+ if ( !skip(length,data) ) return 0;
+ // const char* keyword_utf8 = (const char*)data;
+ if ( !skip(length,data) ) return 0;
+ const char* text_utf8 = (const char*)data;
+ if ( !skip(length,data) ) return 0;
+ TQString text = TQString::fromUtf8(text_utf8);
+ image->setText(keyword,lang[0] ? lang : 0,text);
+ return 1;
+ }
+ }
+ */
+#endif
+
+ return 0;
+}
+#endif
+
+
+static TQPNGFormatType* globalPngFormatTypeObject = 0;
+
+#endif // TQT_NO_ASYNC_IMAGE_IO
+
+static bool done = FALSE;
+void qCleanupPngIO()
+{
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+ if ( globalPngFormatTypeObject ) {
+ delete globalPngFormatTypeObject;
+ globalPngFormatTypeObject = 0;
+ }
+#endif
+ done = FALSE;
+}
+
+void qInitPngIO()
+{
+ if ( !done ) {
+ done = TRUE;
+ TQImageIO::defineIOHandler( "PNG", "^.PNG\r", 0, read_png_image,
+ write_png_image);
+#ifndef TQT_NO_ASYNC_IMAGE_IO
+ globalPngFormatTypeObject = new TQPNGFormatType;
+#endif
+ qAddPostRoutine( qCleanupPngIO );
+ }
+}
+
+void qt_zlib_compression_hack()
+{
+ compress(0,0,0,0);
+ uncompress(0,0,0,0);
+}
+
+#endif // TQT_NO_IMAGEIO_PNG
diff --git a/tqtinterface/qt4/src/kernel/tqpngio.h b/tqtinterface/qt4/src/kernel/tqpngio.h
new file mode 100644
index 0000000..43e669f
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpngio.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Definition of PNG TQImage IOHandler
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPNGIO_H
+#define TQPNGIO_H
+
+#ifndef TQT_H
+#include "tqimage.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_IMAGEIO_PNG
+
+void qInitPngIO();
+
+class TQIODevice;
+
+#ifndef TQ_PNGEXPORT
+#if !defined(TQT_PLUGIN)
+#define TQ_PNGEXPORT TQ_EXPORT
+#else
+#define TQ_PNGEXPORT
+#endif
+#endif
+
+class TQ_PNGEXPORT TQPNGImageWriter {
+public:
+ TQPNGImageWriter(TQIODevice*);
+ ~TQPNGImageWriter();
+
+ enum DisposalMethod { Unspecified, NoDisposal, RestoreBackground, RestoreImage };
+ void setDisposalMethod(DisposalMethod);
+ void setLooping(int loops=0); // 0 == infinity
+ void setFrameDelay(int msecs);
+ void setGamma(float);
+
+ bool writeImage(const TQImage& img, int x, int y);
+ bool writeImage(const TQImage& img, int quality, int x, int y);
+ bool writeImage(const TQImage& img)
+ { return writeImage(img, 0, 0); }
+ bool writeImage(const TQImage& img, int quality)
+ { return writeImage(img, quality, 0, 0); }
+
+ TQIODevice* tqdevice() { return dev; }
+
+private:
+ TQIODevice* dev;
+ int frames_written;
+ DisposalMethod disposal;
+ int looping;
+ int ms_delay;
+ float gamma;
+};
+
+class TQ_PNGEXPORT TQPNGImagePacker : public TQPNGImageWriter {
+public:
+ TQPNGImagePacker(TQIODevice*, int depth, int convflags);
+
+ void setPixelAlignment(int x);
+ bool packImage(const TQImage& img);
+
+private:
+ TQImage previous;
+ int depth;
+ int convflags;
+ int alignx;
+};
+
+#endif // TQT_NO_IMAGEIO_PNG
+
+#endif // TQPNGIO_H
diff --git a/tqtinterface/qt4/src/kernel/tqpoint.cpp b/tqtinterface/qt4/src/kernel/tqpoint.cpp
new file mode 100644
index 0000000..cf8422e
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpoint.cpp
@@ -0,0 +1,448 @@
+/****************************************************************************
+**
+** Implementation of TQPoint class
+**
+** Created : 931028
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpoint.h"
+#include "tqdatastream.h"
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \class TQPoint tqpoint.h
+ \brief The TQPoint class defines a point in the plane.
+
+ \ingroup images
+ \ingroup graphics
+ \mainclass
+
+ A point is specified by an x coordinate and a y coordinate.
+
+ The coordinate type is \c TQCOORD (a 32-bit integer). The minimum
+ value of \c TQCOORD is \c TQCOORD_MIN (-2147483648) and the maximum
+ value is \c TQCOORD_MAX (2147483647).
+
+ The coordinates are accessed by the functions x() and y(); they
+ can be set by setX() and setY() or by the reference functions rx()
+ and ry().
+
+ Given a point \e p, the following statements are all equivalent:
+ \code
+ p.setX( p.x() + 1 );
+ p += TQPoint( 1, 0 );
+ p.rx()++;
+ \endcode
+
+ A TQPoint can also be used as a vector. Addition and subtraction
+ of TQPoints are defined as for vectors (each component is added
+ separately). You can divide or multiply a TQPoint by an \c int or a
+ \c double. The function manhattanLength() gives an inexpensive
+ approximation of the length of the TQPoint interpreted as a vector.
+
+ Example:
+ \code
+ //TQPoint oldPos is defined somewhere else
+ MyWidget::mouseMoveEvent( TQMouseEvent *e )
+ {
+ TQPoint vector = e->pos() - oldPos;
+ if ( vector.manhattanLength() > 3 )
+ ... //mouse has moved more than 3 pixels since oldPos
+ }
+ \endcode
+
+ TQPoints can be compared for equality or inequality, and they can
+ be written to and read from a TQStream.
+
+ \sa TQPointArray TQSize, TQRect
+*/
+
+
+/*****************************************************************************
+ TQPoint member functions
+ *****************************************************************************/
+
+/*!
+ \fn TQPoint::TQPoint()
+
+ Constructs a point with coordinates (0, 0) (isNull() returns TRUE).
+*/
+
+/*!
+ \fn TQPoint::TQPoint( int xpos, int ypos )
+
+ Constructs a point with x value \a xpos and y value \a ypos.
+*/
+
+/*!
+ \fn bool TQPoint::isNull() const
+
+ Returns TRUE if both the x value and the y value are 0; otherwise
+ returns FALSE.
+*/
+
+/*!
+ \fn int TQPoint::x() const
+
+ Returns the x coordinate of the point.
+
+ \sa setX() y()
+*/
+
+/*!
+ \fn int TQPoint::y() const
+
+ Returns the y coordinate of the point.
+
+ \sa setY() x()
+*/
+
+/*!
+ \fn void TQPoint::setX( int x )
+
+ Sets the x coordinate of the point to \a x.
+
+ \sa x() setY()
+*/
+
+/*!
+ \fn void TQPoint::setY( int y )
+
+ Sets the y coordinate of the point to \a y.
+
+ \sa y() setX()
+*/
+
+
+/*!
+ \fn TQCOORD &TQPoint::rx()
+
+ Returns a reference to the x coordinate of the point.
+
+ Using a reference makes it possible to directly manipulate x.
+
+ Example:
+ \code
+ TQPoint p( 1, 2 );
+ p.rx()--; // p becomes (0, 2)
+ \endcode
+
+ \sa ry()
+*/
+
+/*!
+ \fn TQCOORD &TQPoint::ry()
+
+ Returns a reference to the y coordinate of the point.
+
+ Using a reference makes it possible to directly manipulate y.
+
+ Example:
+ \code
+ TQPoint p( 1, 2 );
+ p.ry()++; // p becomes (1, 3)
+ \endcode
+
+ \sa rx()
+*/
+
+
+/*!
+ \fn TQPoint &TQPoint::operator+=( const TQPoint &p )
+
+ Adds point \a p to this point and returns a reference to this
+ point.
+
+ Example:
+ \code
+ TQPoint p( 3, 7 );
+ TQPoint q( -1, 4 );
+ p += q; // p becomes (2,11)
+ \endcode
+*/
+
+/*!
+ \fn TQPoint &TQPoint::operator-=( const TQPoint &p )
+
+ Subtracts point \a p from this point and returns a reference to
+ this point.
+
+ Example:
+ \code
+ TQPoint p( 3, 7 );
+ TQPoint q( -1, 4 );
+ p -= q; // p becomes (4,3)
+ \endcode
+*/
+
+/*!
+ \fn TQPoint &TQPoint::operator*=( int c )
+
+ Multiplies this point's x and y by \a c, and returns a reference
+ to this point.
+
+ Example:
+ \code
+ TQPoint p( -1, 4 );
+ p *= 2; // p becomes (-2,8)
+ \endcode
+*/
+
+/*!
+ \overload TQPoint &TQPoint::operator*=( double c )
+
+ Multiplies this point's x and y by \a c, and returns a reference
+ to this point.
+
+ Example:
+ \code
+ TQPoint p( -1, 4 );
+ p *= 2.5; // p becomes (-3,10)
+ \endcode
+
+ Note that the result is truncated because points are held as
+ integers.
+*/
+
+
+/*!
+ \fn bool operator==( const TQPoint &p1, const TQPoint &p2 )
+
+ \relates TQPoint
+
+ Returns TRUE if \a p1 and \a p2 are equal; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool operator!=( const TQPoint &p1, const TQPoint &p2 )
+
+ \relates TQPoint
+
+ Returns TRUE if \a p1 and \a p2 are not equal; otherwise returns FALSE.
+*/
+
+/*!
+ \fn const TQPoint operator+( const TQPoint &p1, const TQPoint &p2 )
+
+ \relates TQPoint
+
+ Returns the sum of \a p1 and \a p2; each component is added separately.
+*/
+
+/*!
+ \fn const TQPoint operator-( const TQPoint &p1, const TQPoint &p2 )
+
+ \relates TQPoint
+
+ Returns \a p2 subtracted from \a p1; each component is subtracted
+ separately.
+*/
+
+/*!
+ \fn const TQPoint operator*( const TQPoint &p, int c )
+
+ \relates TQPoint
+
+ Returns the TQPoint formed by multiplying both components of \a p
+ by \a c.
+*/
+
+/*!
+ \overload const TQPoint operator*( int c, const TQPoint &p )
+
+ \relates TQPoint
+
+ Returns the TQPoint formed by multiplying both components of \a p
+ by \a c.
+*/
+
+/*!
+ \overload const TQPoint operator*( const TQPoint &p, double c )
+
+ \relates TQPoint
+
+ Returns the TQPoint formed by multiplying both components of \a p
+ by \a c.
+
+ Note that the result is truncated because points are held as
+ integers.
+*/
+
+/*!
+ \overload const TQPoint operator*( double c, const TQPoint &p )
+
+ \relates TQPoint
+
+ Returns the TQPoint formed by multiplying both components of \a p
+ by \a c.
+
+ Note that the result is truncated because points are held as
+ integers.
+*/
+
+/*!
+ \overload const TQPoint operator-( const TQPoint &p )
+
+ \relates TQPoint
+
+ Returns the TQPoint formed by changing the sign of both components
+ of \a p, equivalent to \c{TQPoint(0,0) - p}.
+*/
+
+/*!
+ \fn TQPoint &TQPoint::operator/=( int c )
+
+ Divides both x and y by \a c, and returns a reference to this
+ point.
+
+ Example:
+ \code
+ TQPoint p( -2, 8 );
+ p /= 2; // p becomes (-1,4)
+ \endcode
+*/
+
+/*!
+ \overload TQPoint &TQPoint::operator/=( double c )
+
+ Divides both x and y by \a c, and returns a reference to this
+ point.
+
+ Example:
+ \code
+ TQPoint p( -3, 10 );
+ p /= 2.5; // p becomes (-1,4)
+ \endcode
+
+ Note that the result is truncated because points are held as
+ integers.
+*/
+
+/*!
+ \fn const TQPoint operator/( const TQPoint &p, int c )
+
+ \relates TQPoint
+
+ Returns the TQPoint formed by dividing both components of \a p by
+ \a c.
+*/
+
+/*!
+ \overload const TQPoint operator/( const TQPoint &p, double c )
+
+ \relates TQPoint
+
+ Returns the TQPoint formed by dividing both components of \a p
+ by \a c.
+
+ Note that the result is truncated because points are held as
+ integers.
+*/
+
+
+void TQPoint::warningDivByZero()
+{
+#if defined(TQT_CHECK_MATH)
+ qWarning( "TQPoint: Division by zero error" );
+#endif
+}
+
+
+/*****************************************************************************
+ TQPoint stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQPoint
+
+ Writes point \a p to the stream \a s and returns a reference to
+ the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQPoint &p )
+{
+ if ( s.version() == 1 )
+ s << (TQ_INT16)p.x() << (TQ_INT16)p.y();
+ else
+ s << (TQ_INT32)p.x() << (TQ_INT32)p.y();
+ return s;
+}
+
+/*!
+ \relates TQPoint
+
+ Reads a TQPoint from the stream \a s into point \a p and returns a
+ reference to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQPoint &p )
+{
+ if ( s.version() == 1 ) {
+ TQ_INT16 x, y;
+ s >> x; p.rx() = x;
+ s >> y; p.ry() = y;
+ }
+ else {
+ TQ_INT32 x, y;
+ s >> x; p.rx() = x;
+ s >> y; p.ry() = y;
+ }
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+/*!
+ Returns the sum of the absolute values of x() and y(),
+ traditionally known as the "Manhattan length" of the vector from
+ the origin to the point. The tradition arises because such
+ distances apply to travelers who can only travel on a rectangular
+ grid, like the streets of Manhattan.
+
+ This is a useful, and quick to calculate, approximation to the
+ true length: sqrt(pow(x(),2)+pow(y(),2)).
+*/
+int TQPoint::manhattanLength() const
+{
+ return TQABS(x())+TQABS(y());
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqpoint.h b/tqtinterface/qt4/src/kernel/tqpoint.h
new file mode 100644
index 0000000..dc9a5bb
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpoint.h
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** Definition of TQPoint class
+**
+** Created : 931028
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPOINT_H
+#define TQPOINT_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qrect.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQPoint : public QPoint, virtual public TQt
+{
+public:
+ TQPoint() : QPoint() {}
+ TQPoint( int xpos, int ypos ) : QPoint(xpos, ypos) {}
+
+ // Interoperability
+ TQPoint(QPoint a) {
+ setX(a.x());
+ setY(a.y());
+ }
+
+ // Interoperability
+ static const TQPoint& convertFromQPoint( QPoint& qp );
+};
+
+// Interoperability
+inline static const TQPoint& convertFromQPoint( const QPoint& qp ) {
+ return (*static_cast<const TQPoint*>(&qp));
+}
+
+#else // USE_QT4
+
+class TQ_EXPORT TQPoint
+{
+public:
+ TQPoint();
+ TQPoint( int xpos, int ypos );
+
+ bool isNull() const;
+
+ int x() const;
+ int y() const;
+ void setX( int x );
+ void setY( int y );
+
+ int manhattanLength() const;
+
+ TQCOORD &rx();
+ TQCOORD &ry();
+
+ TQPoint &operator+=( const TQPoint &p );
+ TQPoint &operator-=( const TQPoint &p );
+ TQPoint &operator*=( int c );
+ TQPoint &operator*=( double c );
+ TQPoint &operator/=( int c );
+ TQPoint &operator/=( double c );
+
+ friend inline bool operator==( const TQPoint &, const TQPoint & );
+ friend inline bool operator!=( const TQPoint &, const TQPoint & );
+ friend inline const TQPoint operator+( const TQPoint &, const TQPoint & );
+ friend inline const TQPoint operator-( const TQPoint &, const TQPoint & );
+ friend inline const TQPoint operator*( const TQPoint &, int );
+ friend inline const TQPoint operator*( int, const TQPoint & );
+ friend inline const TQPoint operator*( const TQPoint &, double );
+ friend inline const TQPoint operator*( double, const TQPoint & );
+ friend inline const TQPoint operator-( const TQPoint & );
+ friend inline const TQPoint operator/( const TQPoint &, int );
+ friend inline const TQPoint operator/( const TQPoint &, double );
+
+private:
+ static void warningDivByZero();
+
+#if defined(TQ_OS_MAC)
+ TQCOORD yp;
+ TQCOORD xp;
+#else
+ TQCOORD xp;
+ TQCOORD yp;
+#endif
+};
+
+
+/*****************************************************************************
+ TQPoint stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPoint & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPoint & );
+#endif
+
+/*****************************************************************************
+ TQPoint inline functions
+ *****************************************************************************/
+
+inline TQPoint::TQPoint()
+{ xp=0; yp=0; }
+
+inline TQPoint::TQPoint( int xpos, int ypos )
+{ xp=(TQCOORD)xpos; yp=(TQCOORD)ypos; }
+
+inline bool TQPoint::isNull() const
+{ return xp == 0 && yp == 0; }
+
+inline int TQPoint::x() const
+{ return xp; }
+
+inline int TQPoint::y() const
+{ return yp; }
+
+inline void TQPoint::setX( int x )
+{ xp = (TQCOORD)x; }
+
+inline void TQPoint::setY( int y )
+{ yp = (TQCOORD)y; }
+
+inline TQCOORD &TQPoint::rx()
+{ return xp; }
+
+inline TQCOORD &TQPoint::ry()
+{ return yp; }
+
+inline TQPoint &TQPoint::operator+=( const TQPoint &p )
+{ xp+=p.xp; yp+=p.yp; return *this; }
+
+inline TQPoint &TQPoint::operator-=( const TQPoint &p )
+{ xp-=p.xp; yp-=p.yp; return *this; }
+
+inline TQPoint &TQPoint::operator*=( int c )
+{ xp*=(TQCOORD)c; yp*=(TQCOORD)c; return *this; }
+
+inline TQPoint &TQPoint::operator*=( double c )
+{ xp=(TQCOORD)(xp*c); yp=(TQCOORD)(yp*c); return *this; }
+
+inline bool operator==( const TQPoint &p1, const TQPoint &p2 )
+{ return p1.xp == p2.xp && p1.yp == p2.yp; }
+
+inline bool operator!=( const TQPoint &p1, const TQPoint &p2 )
+{ return p1.xp != p2.xp || p1.yp != p2.yp; }
+
+inline const TQPoint operator+( const TQPoint &p1, const TQPoint &p2 )
+{ return TQPoint(p1.xp+p2.xp, p1.yp+p2.yp); }
+
+inline const TQPoint operator-( const TQPoint &p1, const TQPoint &p2 )
+{ return TQPoint(p1.xp-p2.xp, p1.yp-p2.yp); }
+
+inline const TQPoint operator*( const TQPoint &p, int c )
+{ return TQPoint(p.xp*c, p.yp*c); }
+
+inline const TQPoint operator*( int c, const TQPoint &p )
+{ return TQPoint(p.xp*c, p.yp*c); }
+
+inline const TQPoint operator*( const TQPoint &p, double c )
+{ return TQPoint((TQCOORD)(p.xp*c), (TQCOORD)(p.yp*c)); }
+
+inline const TQPoint operator*( double c, const TQPoint &p )
+{ return TQPoint((TQCOORD)(p.xp*c), (TQCOORD)(p.yp*c)); }
+
+inline const TQPoint operator-( const TQPoint &p )
+{ return TQPoint(-p.xp, -p.yp); }
+
+inline TQPoint &TQPoint::operator/=( int c )
+{
+#if defined(TQT_CHECK_MATH)
+ if ( c == 0 )
+ warningDivByZero();
+#endif
+ xp/=(TQCOORD)c;
+ yp/=(TQCOORD)c;
+ return *this;
+}
+
+inline TQPoint &TQPoint::operator/=( double c )
+{
+#if defined(TQT_CHECK_MATH)
+ if ( c == 0.0 )
+ warningDivByZero();
+#endif
+ xp=(TQCOORD)(xp/c);
+ yp=(TQCOORD)(yp/c);
+ return *this;
+}
+
+inline const TQPoint operator/( const TQPoint &p, int c )
+{
+#if defined(TQT_CHECK_MATH)
+ if ( c == 0 )
+ TQPoint::warningDivByZero();
+#endif
+ return TQPoint(p.xp/c, p.yp/c);
+}
+
+inline const TQPoint operator/( const TQPoint &p, double c )
+{
+#if defined(TQT_CHECK_MATH)
+ if ( c == 0.0 )
+ TQPoint::warningDivByZero();
+#endif
+ return TQPoint((TQCOORD)(p.xp/c), (TQCOORD)(p.yp/c));
+}
+
+#endif // USE_QT4
+
+#define TQ_DEFINED_TQPOINT
+#include "tqwinexport.h"
+#endif // TQPOINT_H
diff --git a/tqtinterface/qt4/src/kernel/tqpointarray.cpp b/tqtinterface/qt4/src/kernel/tqpointarray.cpp
new file mode 100644
index 0000000..f5d0016
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpointarray.cpp
@@ -0,0 +1,1311 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqpointarray.h"
+#include "private/qt4_qbezier_p.h"
+
+// Normally declared in private/qpainterpath_p.h
+void Q_GUI_EXPORT qt_find_ellipse_coords(const QRectF &r, qreal angle, qreal length, QPointF* startPoint, QPointF *endPoint);
+
+#include <Qt/qpainterpath.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class TQPointArray
+ The TQPointArray class provides an array of points.
+
+ \compat
+
+ TQPointArray is a QPolygon subclass that provides functions
+ to make it more source compatible with the \c QPointArray class
+ in Qt 3.
+
+ In Qt 4, we recommend that you use QPainterPath for representing
+ arcs, ellipses, and Bezier curves, rather than QPolygon.
+*/
+
+/*!
+ Sets the points of the array to those describing an arc of an
+ ellipse with size, width \a w by height \a h, and position (\a x,
+ \a y), starting from angle \a a1 and spanning by angle \a a2. The
+ resulting array has sufficient resolution for pixel accuracy (see
+ the overloaded function which takes an additional QMatrix
+ parameter).
+
+ Angles are specified in 16ths of a degree, i.e. a full circle
+ equals 5760 (16*360). Positive values mean counter-clockwise,
+ whereas negative values mean the clockwise direction. Zero degrees
+ is at the 3 o'clock position.
+*/
+#ifndef QT_NO_WMATRIX
+void TQPointArray::makeArc(int x, int y, int w, int h, int a1, int a2)
+{
+ QRectF r(x, y, w, h);
+ QPointF startPoint;
+ qt_find_ellipse_coords(r, a1 / 16.0, a2 / 16.0, &startPoint, 0);
+
+ QPainterPath path(startPoint);
+ path.arcTo(r, a1 / 16.0, a2 / 16.0);
+
+ if (path.isEmpty())
+ *this = TQPointArray();
+ else
+ *this = path.toSubpathPolygons().at(0).toPolygon();
+}
+#endif
+
+#ifndef QT_NO_TRANSFORMATIONS
+/*!
+ \overload
+
+ Sets the points of the array to those describing an arc of an
+ ellipse with width \a w and height \a h and position (\a x, \a y),
+ starting from angle \a a1, and spanning angle by \a a2, and
+ transformed by the matrix \a xf. The resulting array has
+ sufficient resolution for pixel accuracy.
+
+ Angles are specified in 16ths of a degree, i.e. a full circle
+ equals 5760 (16 * 360). Positive values mean counter-clockwise,
+ whereas negative values mean the clockwise direction. Zero
+ degrees is at the 3 o'clock position.
+*/
+void TQPointArray::makeArc(int x, int y, int w, int h, int a1, int a2, const QMatrix &xf)
+{
+ QRectF r(x, y, w, h);
+ QPointF startPoint;
+ qt_find_ellipse_coords(r, a1 / 16.0, a2 / 16.0, &startPoint, 0);
+
+ QPainterPath path(startPoint);
+ path.arcTo(r, a1 / 16.0, a2 / 16.0);
+ path = path * xf;
+ if (path.isEmpty())
+ *this = TQPointArray();
+ else
+ *this = path.toSubpathPolygons().at(0).toPolygon();
+}
+
+#endif // QT_NO_TRANSFORMATIONS
+
+/*!
+ \fn TQPointArray::TQPointArray()
+
+ Constructs an empty TQPointArray.
+*/
+
+/*!
+ \fn TQPointArray::TQPointArray(const QRect &r, bool closed)
+
+ Constructs a point array from the rectangle \a r.
+
+ If \a closed is false, then the point array just contains the
+ following four points of the rectangle ordered clockwise. The
+ bottom-right point is located at (r.x() + r.width(), r.y() +
+ r.height()).
+*/
+
+/*!
+ \fn TQPointArray::TQPointArray(const QPolygon& other)
+
+ Constructs a copy of \a other.
+*/
+
+/*!
+ \fn TQPointArray TQPointArray::copy() const
+
+ Returns a copy of this TQPointArray.
+*/
+
+/*!
+ \fn bool TQPointArray::isNull()
+
+ Returns isEmpty(). Use isEmpty() instead.
+*/
+
+/*!
+ Sets the points of the array to those describing an ellipse with
+ size, width \a w by height \a h, and position (\a x, \a y).
+
+ The returned array has sufficient resolution for use as pixels.
+*/
+void TQPointArray::makeEllipse(int x, int y, int w, int h)
+{
+ QPainterPath path;
+ path.addEllipse(x, y, w, h);
+ *this = path.toSubpathPolygons().at(0).toPolygon();
+}
+
+#ifndef QT_NO_BEZIER
+
+/*!
+ Returns the Bezier points for the four control points in this
+ array.
+*/
+TQPointArray TQPointArray::cubicBezier() const
+{
+ if (size() != 4) {
+ qWarning( "TQPointArray::bezier: The array must have 4 control points" );
+ return QPolygon();
+ }
+ QPolygonF polygon = QBezier::fromPoints(at(0), at(1), at(2), at(3)).toPolygon();
+ return polygon.toPolygon();
+}
+#endif //QT_NO_BEZIER
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of TQPointArray class
+**
+** Created : 940213
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpointarray.h"
+#include "tqrect.h"
+#include "tqdatastream.h"
+#include "tqwmatrix.h"
+#include <stdarg.h>
+
+const double TQ_PI = 3.14159265358979323846; // pi // one more useful comment
+
+
+/*!
+ \class TQPointArray tqpointarray.h
+ \brief The TQPointArray class provides an array of points.
+
+ \ingroup images
+ \ingroup graphics
+ \ingroup shared
+
+ A TQPointArray is an array of TQPoint objects. In addition to the
+ functions provided by TQMemArray, TQPointArray provides some
+ point-specific functions.
+
+ For convenient reading and writing of the point data use
+ setPoints(), putPoints(), point(), and setPoint().
+
+ For tqgeometry operations use boundingRect() and translate(). There
+ is also the TQWMatrix::map() function for more general
+ transformations of TQPointArrays. You can also create arcs and
+ ellipses with makeArc() and makeEllipse().
+
+ Among others, TQPointArray is used by TQPainter::drawLineSegments(),
+ TQPainter::drawPolyline(), TQPainter::drawPolygon() and
+ TQPainter::drawCubicBezier().
+
+ Note that because this class is a TQMemArray, copying an array and
+ modifying the copy modifies the original as well, i.e. a shallow
+ copy. If you need a deep copy use copy() or detach(), for example:
+
+ \code
+ void drawGiraffe( const TQPointArray & r, TQPainter * p )
+ {
+ TQPointArray tmp = r;
+ tmp.detach();
+ // some code that modifies tmp
+ p->drawPoints( tmp );
+ }
+ \endcode
+
+ If you forget the tmp.detach(), the const array will be modified.
+
+ \sa TQPainter TQWMatrix TQMemArray
+*/
+
+
+/*****************************************************************************
+ TQPointArray member functions
+ *****************************************************************************/
+
+/*!
+ \fn TQPointArray::TQPointArray()
+
+ Constructs a null point array.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn TQPointArray::TQPointArray( int size )
+
+ Constructs a point array with room for \a size points. Makes a
+ null array if \a size == 0.
+
+ \sa resize(), isNull()
+*/
+
+/*!
+ \fn TQPointArray::TQPointArray( const TQPointArray &a )
+
+ Constructs a shallow copy of the point array \a a.
+
+ \sa copy() detach()
+*/
+
+/*!
+ Constructs a point array from the rectangle \a r.
+
+ If \a closed is FALSE, then the point array just tqcontains the
+ following four points in the listed order: r.topLeft(),
+ r.topRight(), r.bottomRight() and r.bottomLeft().
+
+ If \a closed is TRUE, then a fifth point is set to r.topLeft().
+*/
+
+TQPointArray::TQPointArray( const TQRect &r, bool closed )
+{
+ setPoints( 4, r.left(), r.top(),
+ r.right(), r.top(),
+ r.right(), r.bottom(),
+ r.left(), r.bottom() );
+ if ( closed ) {
+ resize( 5 );
+ setPoint( 4, r.left(), r.top() );
+ }
+}
+
+/*!
+ \internal
+ Constructs a point array with \a nPoints points, taken from the
+ \a points array.
+
+ Equivalent to setPoints(nPoints, points).
+*/
+
+TQPointArray::TQPointArray( int nPoints, const TQCOORD *points )
+{
+ setPoints( nPoints, points );
+}
+
+
+/*!
+ \fn TQPointArray::~TQPointArray()
+
+ Destroys the point array.
+*/
+
+
+/*!
+ \fn TQPointArray &TQPointArray::operator=( const TQPointArray &a )
+
+ Assigns a shallow copy of \a a to this point array and returns a
+ reference to this point array.
+
+ Equivalent to assign(a).
+
+ \sa copy() detach()
+*/
+
+/*!
+ \fn TQPointArray TQPointArray::copy() const
+
+ Creates a deep copy of the array.
+
+ \sa detach()
+*/
+
+
+
+/*!
+ Translates all points in the array by \a (dx, dy).
+*/
+
+void TQPointArray::translate( int dx, int dy )
+{
+ register TQPoint *p = data();
+ register int i = size();
+ TQPoint pt( dx, dy );
+ while ( i-- ) {
+ *p += pt;
+ p++;
+ }
+}
+
+
+/*!
+ Reads the coordinates of the point at position \a index within the
+ array and writes them into \a *x and \a *y.
+*/
+
+void TQPointArray::point( uint index, int *x, int *y ) const
+{
+ TQPoint p = TQMemArray<TQPoint>::at( index );
+ if ( x )
+ *x = (int)p.x();
+ if ( y )
+ *y = (int)p.y();
+}
+
+/*!
+ \overload
+
+ Returns the point at position \a index within the array.
+*/
+
+TQPoint TQPointArray::point( uint index ) const
+{ // #### index out of bounds
+ return TQMemArray<TQPoint>::at( index );
+}
+
+/*!
+ \fn void TQPointArray::setPoint( uint i, const TQPoint &p )
+
+ \overload
+
+ Sets the point at array index \a i to \a p.
+*/
+
+/*!
+ Sets the point at position \a index in the array to \a (x, y).
+*/
+
+void TQPointArray::setPoint( uint index, int x, int y )
+{ // #### index out of bounds
+ TQMemArray<TQPoint>::at( index ) = TQPoint( x, y );
+}
+
+/*!
+ \internal
+ Resizes the array to \a nPoints and sets the points in the array to
+ the values taken from \a points.
+
+ Returns TRUE if successful, or FALSE if the array could not be
+ resized (normally due to lack of memory).
+
+ The example code creates an array with two points (1,2) and (3,4):
+ \code
+ static TQCOORD points[] = { 1,2, 3,4 };
+ TQPointArray a;
+ a.setPoints( 2, points );
+ \endcode
+
+ \sa resize(), putPoints()
+*/
+
+bool TQPointArray::setPoints( int nPoints, const TQCOORD *points )
+{
+ if ( !resize(nPoints) )
+ return FALSE;
+ int i = 0;
+ while ( nPoints-- ) { // make array of points
+ setPoint( i++, *points, *(points+1) );
+ points++;
+ points++;
+ }
+ return TRUE;
+}
+
+/*!
+ \overload
+
+ Resizes the array to \a nPoints and sets the points in the array
+ to the values taken from the variable argument list.
+
+ Returns TRUE if successful, or FALSE if the array could not be
+ resized (typically due to lack of memory).
+
+ The example code creates an array with two points (1,2) and (3,4):
+
+ \code
+ TQPointArray a;
+ a.setPoints( 2, 1,2, 3,4 );
+ \endcode
+
+ The points are given as a sequence of integers, starting with \a
+ firstx then \a firsty, and so on.
+
+ \sa resize(), putPoints()
+*/
+
+bool TQPointArray::setPoints( int nPoints, int firstx, int firsty, ... )
+{
+ va_list ap;
+ if ( !resize(nPoints) )
+ return FALSE;
+ setPoint( 0, firstx, firsty ); // set first point
+ int i = 1, x, y;
+ nPoints--;
+ va_start( ap, firsty );
+ while ( nPoints-- ) {
+ x = va_arg( ap, int );
+ y = va_arg( ap, int );
+ setPoint( i++, x, y );
+ }
+ va_end( ap );
+ return TRUE;
+}
+
+/*! \overload
+ \internal
+ Copies \a nPoints points from the \a points coord array into
+ this point array, and resizes the point array if
+ \c{index+nPoints} exceeds the size of the array.
+
+ Returns TRUE if successful, or FALSE if the array could not be
+ resized (typically due to lack of memory).
+
+*/
+
+bool TQPointArray::putPoints( int index, int nPoints, const TQCOORD *points )
+{
+ if ( index + nPoints > (int)size() ) { // extend array
+ if ( !resize( index + nPoints ) )
+ return FALSE;
+ }
+ int i = index;
+ while ( nPoints-- ) { // make array of points
+ setPoint( i++, *points, *(points+1) );
+ points++;
+ points++;
+ }
+ return TRUE;
+}
+
+/*!
+ Copies \a nPoints points from the variable argument list into this
+ point array from position \a index, and resizes the point array if
+ \c{index+nPoints} exceeds the size of the array.
+
+ Returns TRUE if successful, or FALSE if the array could not be
+ resized (typically due to lack of memory).
+
+ The example code creates an array with three points (4,5), (6,7)
+ and (8,9), by expanding the array from 1 to 3 points:
+
+ \code
+ TQPointArray a( 1 );
+ a[0] = TQPoint( 4, 5 );
+ a.putPoints( 1, 2, 6,7, 8,9 ); // index == 1, points == 2
+ \endcode
+
+ This has the same result, but here putPoints overwrites rather
+ than extends:
+ \code
+ TQPointArray a( 3 );
+ a.putPoints( 0, 3, 4,5, 0,0, 8,9 );
+ a.putPoints( 1, 1, 6,7 );
+ \endcode
+
+ The points are given as a sequence of integers, starting with \a
+ firstx then \a firsty, and so on.
+
+ \sa resize()
+*/
+
+bool TQPointArray::putPoints( int index, int nPoints, int firstx, int firsty,
+ ... )
+{
+ va_list ap;
+ if ( index + nPoints > (int)size() ) { // extend array
+ if ( !resize(index + nPoints) )
+ return FALSE;
+ }
+ if ( nPoints <= 0 )
+ return TRUE;
+ setPoint( index, firstx, firsty ); // set first point
+ int i = index + 1, x, y;
+ nPoints--;
+ va_start( ap, firsty );
+ while ( nPoints-- ) {
+ x = va_arg( ap, int );
+ y = va_arg( ap, int );
+ setPoint( i++, x, y );
+ }
+ va_end( ap );
+ return TRUE;
+}
+
+
+/*!
+ \overload
+
+ This version of the function copies \a nPoints from \a from into
+ this array, starting at \a index in this array and \a fromIndex in
+ \a from. \a fromIndex is 0 by default.
+
+ \code
+ TQPointArray a;
+ a.putPoints( 0, 3, 1,2, 0,0, 5,6 );
+ // a is now the three-point array ( 1,2, 0,0, 5,6 );
+ TQPointArray b;
+ b.putPoints( 0, 3, 4,4, 5,5, 6,6 );
+ // b is now ( 4,4, 5,5, 6,6 );
+ a.putPoints( 2, 3, b );
+ // a is now ( 1,2, 0,0, 4,4, 5,5, 6,6 );
+ \endcode
+*/
+
+bool TQPointArray::putPoints( int index, int nPoints,
+ const TQPointArray & from, int fromIndex )
+{
+ if ( index + nPoints > (int)size() ) { // extend array
+ if ( !resize(index + nPoints) )
+ return FALSE;
+ }
+ if ( nPoints <= 0 )
+ return TRUE;
+ int n = 0;
+ while( n < nPoints ) {
+ setPoint( index+n, from[fromIndex+n] );
+ n++;
+ }
+ return TRUE;
+}
+
+
+/*!
+ Returns the bounding rectangle of the points in the array, or
+ TQRect(0,0,0,0) if the array is empty.
+*/
+
+TQRect TQPointArray::boundingRect() const
+{
+ if ( isEmpty() )
+ return TQRect( 0, 0, 0, 0 ); // null rectangle
+ register TQPoint *pd = data();
+ int minx, maxx, miny, maxy;
+ minx = maxx = pd->x();
+ miny = maxy = pd->y();
+ pd++;
+ for ( int i=1; i<(int)size(); i++ ) { // tqfind min+max x and y
+ if ( pd->x() < minx )
+ minx = pd->x();
+ else if ( pd->x() > maxx )
+ maxx = pd->x();
+ if ( pd->y() < miny )
+ miny = pd->y();
+ else if ( pd->y() > maxy )
+ maxy = pd->y();
+ pd++;
+ }
+ return TQRect( TQPoint(minx,miny), TQPoint(maxx,maxy) );
+}
+
+
+static inline int fix_angle( int a )
+{
+ if ( a > 16*360 )
+ a %= 16*360;
+ else if ( a < -16*360 ) {
+ a = -( (-a) % (16*360) );
+ }
+ return a;
+}
+
+/*!
+ Sets the points of the array to those describing an arc of an
+ ellipse with size, width \a w by height \a h, and position (\a x,
+ \a y), starting from angle \a a1 and spanning by angle \a a2. The
+ resulting array has sufficient resolution for pixel accuracy (see
+ the overloaded function which takes an additional TQWMatrix
+ parameter).
+
+ Angles are specified in 16ths of a degree, i.e. a full circle
+ equals 5760 (16*360). Positive values mean counter-clockwise,
+ whereas negative values mean the clockwise direction. Zero degrees
+ is at the 3 o'clock position.
+
+ See the \link qcanvasellipse.html#anglediagram angle diagram\endlink.
+*/
+
+void TQPointArray::makeArc( int x, int y, int w, int h, int a1, int a2 )
+{
+#if !defined(TQT_OLD_MAKEELLIPSE) && !defined(TQT_NO_TRANSFORMATIONS)
+ TQWMatrix unit;
+ makeArc(x,y,w,h,a1,a2,unit);
+#else
+ a1 = fix_angle( a1 );
+ if ( a1 < 0 )
+ a1 += 16*360;
+ a2 = fix_angle( a2 );
+ int a3 = a2 > 0 ? a2 : -a2; // abs angle
+ makeEllipse( x, y, w, h );
+ int npts = a3*size()/(16*360); // # points in arc array
+ TQPointArray a(npts);
+ int i = a1*size()/(16*360);
+ int j = 0;
+ if ( a2 > 0 ) {
+ while ( npts-- ) {
+ if ( i >= (int)size() ) // wrap index
+ i = 0;
+ a.TQMemArray<TQPoint>::at( j++ ) = TQMemArray<TQPoint>::at( i++ );
+ }
+ } else {
+ while ( npts-- ) {
+ if ( i < 0 ) // wrap index
+ i = (int)size()-1;
+ a.TQMemArray<TQPoint>::at( j++ ) = TQMemArray<TQPoint>::at( i-- );
+ }
+ }
+ *this = a;
+ return;
+#endif
+}
+
+#ifndef TQT_NO_TRANSFORMATIONS
+// Based upon:
+// parelarc.c from Graphics Gems III
+// VanAken / Simar, "A Parametric Elliptical Arc Algorithm"
+//
+static void
+qtr_elips(TQPointArray& a, int off, double dxP, double dyP, double dxQ, double dyQ, double dxK, double dyK, int m)
+{
+#define PIV2 102944 /* fixed point PI/2 */
+#define TWOPI 411775 /* fixed point 2*PI */
+#define HALF 32768 /* fixed point 1/2 */
+
+ int xP, yP, xQ, yQ, xK, yK;
+ xP = int(dxP * 65536.0); yP = int(dyP * 65536.0);
+ xQ = int(dxQ * 65536.0); yQ = int(dyQ * 65536.0);
+ xK = int(dxK * 65536.0); yK = int(dyK * 65536.0);
+
+ int i;
+ int vx, ux, vy, uy, xJ, yJ;
+
+ vx = xK - xQ; /* displacements from center */
+ ux = xK - xP;
+ vy = yK - yQ;
+ uy = yK - yP;
+ xJ = xP - vx + HALF; /* center of ellipse J */
+ yJ = yP - vy + HALF;
+
+ int r;
+ ux -= (r = ux >> (2*m + 3)); /* cancel 2nd-order error */
+ ux -= (r >>= (2*m + 4)); /* cancel 4th-order error */
+ ux -= r >> (2*m + 3); /* cancel 6th-order error */
+ ux += vx >> (m + 1); /* cancel 1st-order error */
+ uy -= (r = uy >> (2*m + 3)); /* cancel 2nd-order error */
+ uy -= (r >>= (2*m + 4)); /* cancel 4th-order error */
+ uy -= r >> (2*m + 3); /* cancel 6th-order error */
+ uy += vy >> (m + 1); /* cancel 1st-order error */
+
+ const int qn = a.size()/4;
+ for (i = 0; i < qn; i++) {
+ a[off+i] = TQPoint((xJ + vx) >> 16, (yJ + vy) >> 16);
+ ux -= vx >> m;
+ vx += ux >> m;
+ uy -= vy >> m;
+ vy += uy >> m;
+ }
+
+#undef PIV2
+#undef TWOPI
+#undef HALF
+}
+
+
+/*!
+ \overload
+
+ Sets the points of the array to those describing an arc of an
+ ellipse with width \a w and height \a h and position (\a x, \a y),
+ starting from angle \a a1, and spanning angle by \a a2, and
+ transformed by the matrix \a xf. The resulting array has
+ sufficient resolution for pixel accuracy.
+
+ Angles are specified in 16ths of a degree, i.e. a full circle
+ equals 5760 (16*360). Positive values mean counter-clockwise,
+ whereas negative values mean the clockwise direction. Zero degrees
+ is at the 3 o'clock position.
+
+ See the \link qcanvasellipse.html#anglediagram angle diagram\endlink.
+*/
+void TQPointArray::makeArc( int x, int y, int w, int h,
+ int a1, int a2,
+ const TQWMatrix& xf )
+{
+#define PIV2 102944 /* fixed point PI/2 */
+ if ( --w < 0 || --h < 0 || !a2 ) {
+ resize( 0 );
+ return;
+ }
+
+ bool rev = a2 < 0;
+ if ( rev ) {
+ a1 += a2;
+ a2 = -a2;
+ }
+ a1 = fix_angle( a1 );
+ if ( a1 < 0 )
+ a1 += 16*360;
+ a2 = fix_angle( a2 );
+
+ bool arc = a1 != 0 || a2 != 360*16 || rev;
+
+ double xP, yP, xQ, yQ, xK, yK;
+
+ xf.map(x+w, y+h/2.0, &xP, &yP);
+ xf.map(x+w/2.0, y, &xQ, &yQ);
+ xf.map(x+w, y, &xK, &yK);
+
+ int m = 3;
+ int max;
+ int q = int(TQMAX(TQABS(xP-xQ),TQABS(yP-yQ)));
+ if ( arc )
+ q *= 2;
+ do {
+ m++;
+ max = 4*(1 + (PIV2 >> (16 - m)) );
+ } while (max < q && m < 16); // 16 limits memory usage on HUGE arcs
+
+ double inc = 1.0/(1<<m);
+
+ const int qn = (PIV2 >> (16 - m));
+ resize(qn*4);
+
+ qtr_elips(*this, 0, xP, yP, xQ, yQ, xK, yK, m);
+ xP = xQ; yP = yQ;
+ xf.map(x, y+h/2.0, &xQ, &yQ);
+ xf.map(x, y, &xK, &yK);
+ qtr_elips(*this, qn, xP, yP, xQ, yQ, xK, yK, m);
+ xP = xQ; yP = yQ;
+ xf.map(x+w/2.0, y+h, &xQ, &yQ);
+ xf.map(x, y+h, &xK, &yK);
+ qtr_elips(*this, qn*2, xP, yP, xQ, yQ, xK, yK, m);
+ xP = xQ; yP = yQ;
+ xf.map(x+w, y+h/2.0, &xQ, &yQ);
+ xf.map(x+w, y+h, &xK, &yK);
+ qtr_elips(*this, qn*3, xP, yP, xQ, yQ, xK, yK, m);
+
+ int n = size();
+
+ if ( arc ) {
+ double da1 = double(a1)*TQ_PI / (360*8);
+ double da3 = double(a2+a1)*TQ_PI / (360*8);
+ int i = int(da1/inc+0.5);
+ int l = int(da3/inc+0.5);
+ int k = (l-i)+1;
+ TQPointArray r(k);
+ int j = 0;
+
+ if ( rev ) {
+ while ( k-- )
+ r[j++] = at((i+k)%n);
+ } else {
+ while ( j < k ) {
+ r[j] = at((i+j)%n);
+ j++;
+ }
+ }
+ *this = r;
+ }
+#undef PIV2
+}
+
+#endif // TQT_NO_TRANSFORMATIONS
+
+/*!
+ Sets the points of the array to those describing an ellipse with
+ size, width \a w by height \a h, and position (\a x, \a y).
+
+ The returned array has sufficient resolution for use as pixels.
+*/
+void TQPointArray::makeEllipse( int x, int y, int w, int h )
+{ // midpoint, 1/4 ellipse
+#if !defined(TQT_OLD_MAKEELLIPSE) && !defined(TQT_NO_TRANSFORMATIONS)
+ TQWMatrix unit;
+ makeArc(x,y,w,h,0,360*16,unit);
+ return;
+#else
+ if ( w <= 0 || h <= 0 ) {
+ if ( w == 0 || h == 0 ) {
+ resize( 0 );
+ return;
+ }
+ if ( w < 0 ) { // negative width
+ w = -w;
+ x -= w;
+ }
+ if ( h < 0 ) { // negative height
+ h = -h;
+ y -= h;
+ }
+ }
+ int s = (w+h+2)/2; // max size of xx,yy array
+ int *px = new int[s]; // 1/4th of ellipse
+ int *py = new int[s];
+ int xx, yy, i=0;
+ double d1, d2;
+ double a2=(w/2)*(w/2), b2=(h/2)*(h/2);
+ xx = 0;
+ yy = int(h/2);
+ d1 = b2 - a2*(h/2) + 0.25*a2;
+ px[i] = xx;
+ py[i] = yy;
+ i++;
+ while ( a2*(yy-0.5) > b2*(xx+0.5) ) { // region 1
+ if ( d1 < 0 ) {
+ d1 = d1 + b2*(3.0+2*xx);
+ xx++;
+ } else {
+ d1 = d1 + b2*(3.0+2*xx) + 2.0*a2*(1-yy);
+ xx++;
+ yy--;
+ }
+ px[i] = xx;
+ py[i] = yy;
+ i++;
+ }
+ d2 = b2*(xx+0.5)*(xx+0.5) + a2*(yy-1)*(yy-1) - a2*b2;
+ while ( yy > 0 ) { // region 2
+ if ( d2 < 0 ) {
+ d2 = d2 + 2.0*b2*(xx+1) + a2*(3-2*yy);
+ xx++;
+ yy--;
+ } else {
+ d2 = d2 + a2*(3-2*yy);
+ yy--;
+ }
+ px[i] = xx;
+ py[i] = yy;
+ i++;
+ }
+ s = i;
+ resize( 4*s ); // make full point array
+ x += w/2;
+ y += h/2;
+ for ( i=0; i<s; i++ ) { // mirror
+ xx = px[i];
+ yy = py[i];
+ setPoint( s-i-1, x+xx, y-yy );
+ setPoint( s+i, x-xx, y-yy );
+ setPoint( 3*s-i-1, x-xx, y+yy );
+ setPoint( 3*s+i, x+xx, y+yy );
+ }
+ delete[] px;
+ delete[] py;
+#endif
+}
+
+#ifndef TQT_NO_BEZIER
+// Work functions for TQPointArray::cubicBezier()
+static
+void split(const double *p, double *l, double *r)
+{
+ double tmpx;
+ double tmpy;
+
+ l[0] = p[0];
+ l[1] = p[1];
+ r[6] = p[6];
+ r[7] = p[7];
+
+ l[2] = (p[0]+ p[2])/2;
+ l[3] = (p[1]+ p[3])/2;
+ tmpx = (p[2]+ p[4])/2;
+ tmpy = (p[3]+ p[5])/2;
+ r[4] = (p[4]+ p[6])/2;
+ r[5] = (p[5]+ p[7])/2;
+
+ l[4] = (l[2]+ tmpx)/2;
+ l[5] = (l[3]+ tmpy)/2;
+ r[2] = (tmpx + r[4])/2;
+ r[3] = (tmpy + r[5])/2;
+
+ l[6] = (l[4]+ r[2])/2;
+ l[7] = (l[5]+ r[3])/2;
+ r[0] = l[6];
+ r[1] = l[7];
+}
+
+// Based on:
+//
+// A Fast 2D Point-On-Line Test
+// by Alan Paeth
+// from "Graphics Gems", Academic Press, 1990
+static
+int pnt_on_line( const int* p, const int* q, const int* t )
+{
+/*
+ * given a line through P:(px,py) Q:(qx,qy) and T:(tx,ty)
+ * return 0 if T is not on the line through <--P--Q-->
+ * 1 if T is on the open ray ending at P: <--P
+ * 2 if T is on the closed interior along: P--Q
+ * 3 if T is on the open ray beginning at Q: Q-->
+ *
+ * Example: consider the line P = (3,2), Q = (17,7). A plot
+ * of the test points T(x,y) (with 0 mapped onto '.') yields:
+ *
+ * 8| . . . . . . . . . . . . . . . . . 3 3
+ * Y 7| . . . . . . . . . . . . . . 2 2 Q 3 3 Q = 2
+ * 6| . . . . . . . . . . . 2 2 2 2 2 . . .
+ * a 5| . . . . . . . . 2 2 2 2 2 2 . . . . .
+ * x 4| . . . . . 2 2 2 2 2 2 . . . . . . . .
+ * i 3| . . . 2 2 2 2 2 . . . . . . . . . . .
+ * s 2| 1 1 P 2 2 . . . . . . . . . . . . . . P = 2
+ * 1| 1 1 . . . . . . . . . . . . . . . . .
+ * +--------------------------------------
+ * 1 2 3 4 5 X-axis 10 15 19
+ *
+ * Point-Line distance is normalized with the Infinity Norm
+ * avoiding square-root code and tightening the test vs the
+ * Manhattan Norm. All math is done on the field of integers.
+ * The latter tqreplaces the initial ">= MAX(...)" test with
+ * "> (ABS(qx-px) + ABS(qy-py))" loosening both inequality
+ * and norm, yielding a broader target line for selection.
+ * The tightest test is employed here for best discrimination
+ * in merging collinear (to grid coordinates) vertex chains
+ * into a larger, spanning vectors within the Lemming editor.
+ */
+
+ // if all points are coincident, return condition 2 (on line)
+ if(q[0]==p[0] && q[1]==p[1] && q[0]==t[0] && q[1]==t[1]) {
+ return 2;
+ }
+
+ if ( TQABS((q[1]-p[1])*(t[0]-p[0])-(t[1]-p[1])*(q[0]-p[0])) >=
+ (TQMAX(TQABS(q[0]-p[0]), TQABS(q[1]-p[1])))) return 0;
+
+ if (((q[0]<p[0])&&(p[0]<t[0])) || ((q[1]<p[1])&&(p[1]<t[1])))
+ return 1 ;
+ if (((t[0]<p[0])&&(p[0]<q[0])) || ((t[1]<p[1])&&(p[1]<q[1])))
+ return 1 ;
+ if (((p[0]<q[0])&&(q[0]<t[0])) || ((p[1]<q[1])&&(q[1]<t[1])))
+ return 3 ;
+ if (((t[0]<q[0])&&(q[0]<p[0])) || ((t[1]<q[1])&&(q[1]<p[1])))
+ return 3 ;
+
+ return 2 ;
+}
+static
+void polygonizeTQBezier( double* acc, int& accsize, const double ctrl[],
+ int maxsize )
+{
+ if ( accsize > maxsize / 2 )
+ {
+ // This never happens in practice.
+
+ if ( accsize >= maxsize-4 )
+ return;
+ // Running out of space - approximate by a line.
+ acc[accsize++] = ctrl[0];
+ acc[accsize++] = ctrl[1];
+ acc[accsize++] = ctrl[6];
+ acc[accsize++] = ctrl[7];
+ return;
+ }
+
+ //intersects:
+ double l[8];
+ double r[8];
+ split( ctrl, l, r);
+
+ // convert to integers for line condition check
+ int c0[2]; c0[0] = int(ctrl[0]); c0[1] = int(ctrl[1]);
+ int c1[2]; c1[0] = int(ctrl[2]); c1[1] = int(ctrl[3]);
+ int c2[2]; c2[0] = int(ctrl[4]); c2[1] = int(ctrl[5]);
+ int c3[2]; c3[0] = int(ctrl[6]); c3[1] = int(ctrl[7]);
+
+ // #### Duplication needed?
+ if ( TQABS(c1[0]-c0[0]) <= 1 && TQABS(c1[1]-c0[1]) <= 1
+ && TQABS(c2[0]-c0[0]) <= 1 && TQABS(c2[1]-c0[1]) <= 1
+ && TQABS(c3[0]-c1[0]) <= 1 && TQABS(c3[1]-c0[1]) <= 1 )
+ {
+ // Approximate by one line.
+ // Dont need to write last pt as it is the same as first pt
+ // on the next segment
+ acc[accsize++] = l[0];
+ acc[accsize++] = l[1];
+ return;
+ }
+
+ if ( ( pnt_on_line( c0, c3, c1 ) == 2 && pnt_on_line( c0, c3, c2 ) == 2 )
+ || ( TQABS(c1[0]-c0[0]) <= 1 && TQABS(c1[1]-c0[1]) <= 1
+ && TQABS(c2[0]-c0[0]) <= 1 && TQABS(c2[1]-c0[1]) <= 1
+ && TQABS(c3[0]-c1[0]) <= 1 && TQABS(c3[1]-c0[1]) <= 1 ) )
+ {
+ // Approximate by one line.
+ // Dont need to write last pt as it is the same as first pt
+ // on the next segment
+ acc[accsize++] = l[0];
+ acc[accsize++] = l[1];
+ return;
+ }
+
+ // Too big and too curved - recusively subdivide.
+ polygonizeTQBezier( acc, accsize, l, maxsize );
+ polygonizeTQBezier( acc, accsize, r, maxsize );
+}
+
+/*!
+ Returns the Bezier points for the four control points in this
+ array.
+*/
+
+TQPointArray TQPointArray::cubicBezier() const
+{
+#ifdef USE_SIMPLE_TQBEZIER_CODE
+ if ( size() != 4 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPointArray::bezier: The array must have 4 control points" );
+#endif
+ TQPointArray p;
+ return p;
+ }
+
+ int v;
+ float xvec[4];
+ float yvec[4];
+ for ( v=0; v<4; v++ ) { // store all x,y in xvec,yvec
+ int x, y;
+ point( v, &x, &y );
+ xvec[v] = (float)x;
+ yvec[v] = (float)y;
+ }
+
+ TQRect r = boundingRect();
+ int m = TQMAX(r.width(),r.height())/2;
+ m = TQMIN(m,30); // m = number of result points
+ if ( m < 2 ) // at least two points
+ m = 2;
+ TQPointArray p( m ); // p = Bezier point array
+ register TQPointData *pd = p.data();
+
+ float x0 = xvec[0], y0 = yvec[0];
+ float dt = 1.0F/m;
+ float cx = 3.0F * (xvec[1] - x0);
+ float bx = 3.0F * (xvec[2] - xvec[1]) - cx;
+ float ax = xvec[3] - (x0 + cx + bx);
+ float cy = 3.0F * (yvec[1] - y0);
+ float by = 3.0F * (yvec[2] - yvec[1]) - cy;
+ float ay = yvec[3] - (y0 + cy + by);
+ float t = dt;
+
+ pd->rx() = (TQCOORD)xvec[0];
+ pd->ry() = (TQCOORD)yvec[0];
+ pd++;
+ m -= 2;
+
+ while ( m-- ) {
+ pd->rx() = (TQCOORD)tqRound( ((ax * t + bx) * t + cx) * t + x0 );
+ pd->ry() = (TQCOORD)tqRound( ((ay * t + by) * t + cy) * t + y0 );
+ pd++;
+ t += dt;
+ }
+
+ pd->rx() = (TQCOORD)xvec[3];
+ pd->ry() = (TQCOORD)yvec[3];
+
+ return p;
+#else
+
+ if ( size() != 4 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPointArray::bezier: The array must have 4 control points" );
+#endif
+ TQPointArray pa;
+ return pa;
+ } else {
+ TQRect r = boundingRect();
+ int m = 4+2*TQMAX(r.width(),r.height());
+ double *p = new double[m];
+ double ctrl[8];
+ int i;
+ for (i=0; i<4; i++) {
+ ctrl[i*2] = at(i).x();
+ ctrl[i*2+1] = at(i).y();
+ }
+ int len=0;
+ polygonizeTQBezier( p, len, ctrl, m );
+ TQPointArray pa((len/2)+1); // one extra point for last point on line
+ int j=0;
+ for (i=0; j<len; i++) {
+ int x = tqRound(p[j++]);
+ int y = tqRound(p[j++]);
+ pa[i] = TQPoint(x,y);
+ }
+ // add last pt on the line, which will be at the last control pt
+ pa[(int)pa.size()-1] = at(3);
+ delete[] p;
+
+ return pa;
+ }
+
+#endif
+}
+#endif //TQT_NO_BEZIER
+
+/*****************************************************************************
+ TQPointArray stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQPointArray
+
+ Writes the point array, \a a to the stream \a s and returns a
+ reference to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQPointArray &a )
+{
+ register uint i;
+ uint len = a.size();
+ s << len; // write size of array
+ for ( i=0; i<len; i++ ) // write each point
+ s << a.point( i );
+ return s;
+}
+
+/*!
+ \relates TQPointArray
+
+ Reads a point array, \a a from the stream \a s and returns a
+ reference to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQPointArray &a )
+{
+ register uint i;
+ uint len;
+ s >> len; // read size of array
+ if ( !a.resize( len ) ) // no memory
+ return s;
+ TQPoint p;
+ for ( i=0; i<len; i++ ) { // read each point
+ s >> p;
+ a.setPoint( i, p );
+ }
+ return s;
+}
+#endif //TQT_NO_DATASTREAM
+
+
+
+struct TQShortPoint { // Binary compatible with XPoint
+ short x, y;
+};
+
+uint TQPointArray::splen = 0;
+void* TQPointArray::sp = 0; // Really a TQShortPoint*
+
+/*!
+ \internal
+
+ Converts the point coords to short (16bit) size, compatible with
+ X11's XPoint structure. The pointer returned points to a static
+ array, so its contents will be overwritten the next time this
+ function is called.
+*/
+
+void* TQPointArray::shortPoints( int index, int nPoints ) const
+{
+
+ if ( isNull() || !nPoints )
+ return 0;
+ TQPoint* p = data();
+ p += index;
+ uint i = nPoints < 0 ? size() : nPoints;
+ if ( splen < i ) {
+ if ( sp )
+ delete[] ((TQShortPoint*)sp);
+ sp = new TQShortPoint[i];
+ splen = i;
+ }
+ TQShortPoint* ps = (TQShortPoint*)sp;
+ while ( i-- ) {
+ ps->x = (short)p->x();
+ ps->y = (short)p->y();
+ p++;
+ ps++;
+ }
+ return sp;
+}
+
+
+/*!
+ \internal
+
+ Deallocates the internal buffer used by shortPoints().
+*/
+
+void TQPointArray::cleanBuffers()
+{
+ if ( sp )
+ delete[] ((TQShortPoint*)sp);
+ sp = 0;
+ splen = 0;
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqpointarray.h b/tqtinterface/qt4/src/kernel/tqpointarray.h
new file mode 100644
index 0000000..41a31f9
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpointarray.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Definition of TQPointArray class
+**
+** Created : 940213
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPOINTARRAY_H
+#define TQPOINTARRAY_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqmemarray.h"
+#include "tqpoint.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qpolygon.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3SupportLight)
+
+class Q_COMPAT_EXPORT TQPointArray : public QPolygon, virtual public TQt
+{
+public:
+ inline TQPointArray() : QPolygon() {}
+ inline TQPointArray(const QRect &r, bool closed=false) : QPolygon(r, closed) {}
+ inline TQPointArray(const QPolygon& a) : QPolygon(a) {}
+ inline TQPointArray( int nPoints, const TQCOORD *points ) : QPolygon() { setPoints( nPoints, points ); }
+
+ inline TQPointArray copy() const { return *this; }
+ inline bool isNull() { return isEmpty(); }
+ void makeEllipse(int x, int y, int w, int h);
+#ifndef QT_NO_WMATRIX
+ void makeArc(int x, int y, int w, int h, int a1, int a2);
+ void makeArc(int x, int y, int w, int h, int a1, int a2, const QMatrix &matrix);
+#endif
+ TQPointArray cubicBezier() const;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#else // USE_QT4
+
+#if defined(TQ_TEMPLATEDLL)
+//TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMemArray<TQPoint>;
+#endif
+
+class TQ_EXPORT TQPointArray : public TQMemArray<TQPoint>
+{
+public:
+ TQPointArray() {}
+ ~TQPointArray() {}
+ TQPointArray( int size ) : TQMemArray<TQPoint>( size ) {}
+ TQPointArray( const TQPointArray &a ) : TQMemArray<TQPoint>( a ) {}
+ TQPointArray( const TQRect &r, bool closed=FALSE );
+ TQPointArray( int nPoints, const TQCOORD *points );
+
+ TQPointArray &operator=( const TQPointArray &a )
+ { return (TQPointArray&)assign( a ); }
+
+ TQPointArray copy() const
+ { TQPointArray tmp; return *((TQPointArray*)&tmp.duplicate(*this)); }
+
+ void translate( int dx, int dy );
+ TQRect boundingRect() const;
+
+ void point( uint i, int *x, int *y ) const;
+ TQPoint point( uint i ) const;
+ void setPoint( uint i, int x, int y );
+ void setPoint( uint i, const TQPoint &p );
+ bool setPoints( int nPoints, const TQCOORD *points );
+ bool setPoints( int nPoints, int firstx, int firsty, ... );
+ bool putPoints( int index, int nPoints, const TQCOORD *points );
+ bool putPoints( int index, int nPoints, int firstx, int firsty, ... );
+ bool putPoints( int index, int nPoints,
+ const TQPointArray & from, int fromIndex=0 );
+
+ void makeArc( int x, int y, int w, int h, int a1, int a2 );
+ void makeEllipse( int x, int y, int w, int h );
+ void makeArc( int x, int y, int w, int h, int a1, int a2,
+ const TQWMatrix& );
+#ifndef TQT_NO_BEZIER
+ TQPointArray cubicBezier() const;
+#endif
+ void* shortPoints( int index = 0, int nPoints = -1 ) const;
+ static void cleanBuffers();
+
+protected:
+ static uint splen;
+ static void* sp;
+};
+
+
+/*****************************************************************************
+ TQPointArray stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQPointArray & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQPointArray & );
+#endif
+
+/*****************************************************************************
+ Misc. TQPointArray functions
+ *****************************************************************************/
+
+inline void TQPointArray::setPoint( uint i, const TQPoint &p )
+{
+ setPoint( i, p.x(), p.y() );
+}
+
+#endif // USE_QT4
+
+#endif // TQPOINTARRAY_H
diff --git a/tqtinterface/qt4/src/kernel/tqpolygonscanner.cpp b/tqtinterface/qt4/src/kernel/tqpolygonscanner.cpp
new file mode 100644
index 0000000..78e35ab
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpolygonscanner.cpp
@@ -0,0 +1,937 @@
+/****************************************************************************
+**
+** Implementation of TQPolygonScanner class
+**
+** Created : 000120
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpolygonscanner.h"
+#include "tqpointarray.h"
+#include <stdlib.h>
+
+
+// Based on Xserver code miFillGeneralPoly...
+/*
+ *
+ * Written by Brian Kelleher; Oct. 1985
+ *
+ * Routine to fill a polygon. Two fill rules are
+ * supported: frWINDING and frEVENODD.
+ *
+ * See fillpoly.h for a complete description of the algorithm.
+ */
+
+/*
+ * These are the data structures needed to scan
+ * convert regions. Two different scan conversion
+ * methods are available -- the even-odd method, and
+ * the winding number method.
+ * The even-odd rule states that a point is inside
+ * the polygon if a ray drawn from that point in any
+ * direction will pass through an odd number of
+ * path segments.
+ * By the winding number rule, a point is decided
+ * to be inside the polygon if a ray drawn from that
+ * point in any direction passes through a different
+ * number of clockwise and counterclockwise path
+ * segments.
+ *
+ * These data structures are adapted somewhat from
+ * the algorithm in (Foley/Van Dam) for scan converting
+ * polygons.
+ * The basic algorithm is to start at the top (smallest y)
+ * of the polygon, stepping down to the bottom of
+ * the polygon by incrementing the y coordinate. We
+ * keep a list of edges which the current scanline crosses,
+ * sorted by x. This list is called the Active Edge Table (AET)
+ * As we change the y-coordinate, we update each entry in
+ * in the active edge table to reflect the edges new xcoord.
+ * This list must be sorted at each scanline in case
+ * two edges intersect.
+ * We also keep a data structure known as the Edge Table (ET),
+ * which keeps track of all the edges which the current
+ * scanline has not yet reached. The ET is basically a
+ * list of ScanLineList structures containing a list of
+ * edges which are entered at a given scanline. There is one
+ * ScanLineList per scanline at which an edge is entered.
+ * When we enter a new edge, we move it from the ET to the AET.
+ *
+ * From the AET, we can implement the even-odd rule as in
+ * (Foley/Van Dam).
+ * The winding number rule is a little trickier. We also
+ * keep the EdgeTableEntries in the AET linked by the
+ * nextWETE (winding EdgeTableEntry) link. This allows
+ * the edges to be linked just as before for updating
+ * purposes, but only uses the edges linked by the nextWETE
+ * link as edges representing spans of the polygon to
+ * drawn (as with the even-odd rule).
+ */
+
+/* $XConsortium: miscanfill.h,v 1.5 94/04/17 20:27:50 dpw Exp $ */
+/*
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+
+
+/*
+ * scanfill.h
+ *
+ * Written by Brian Kelleher; Jan 1985
+ *
+ * This file tqcontains a few macros to help track
+ * the edge of a filled object. The object is assumed
+ * to be filled in scanline order, and thus the
+ * algorithm used is an extension of Bresenham's line
+ * drawing algorithm which assumes that y is always the
+ * major axis.
+ * Since these pieces of code are the same for any filled tqshape,
+ * it is more convenient to gather the library in one
+ * place, but since these pieces of code are also in
+ * the inner loops of output primitives, procedure call
+ * overhead is out of the question.
+ * See the author for a derivation if needed.
+ */
+
+/*
+ * In scan converting polygons, we want to choose those pixels
+ * which are inside the polygon. Thus, we add .5 to the starting
+ * x coordinate for both left and right edges. Now we choose the
+ * first pixel which is inside the pgon for the left edge and the
+ * first pixel which is outside the pgon for the right edge.
+ * Draw the left pixel, but not the right.
+ *
+ * How to add .5 to the starting x coordinate:
+ * If the edge is moving to the right, then subtract dy from the
+ * error term from the general form of the algorithm.
+ * If the edge is moving to the left, then add dy to the error term.
+ *
+ * The reason for the difference between edges moving to the left
+ * and edges moving to the right is simple: If an edge is moving
+ * to the right, then we want the algorithm to flip immediately.
+ * If it is moving to the left, then we don't want it to flip until
+ * we traverse an entire pixel.
+ */
+#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \
+ int dx; /* local storage */ \
+\
+ /* \
+ * if the edge is horizontal, then it is ignored \
+ * and assumed not to be processed. Otherwise, do this stuff. \
+ */ \
+ if ((dy) != 0) { \
+ xStart = (x1); \
+ dx = (x2) - xStart; \
+ if (dx < 0) { \
+ m = dx / (dy); \
+ m1 = m - 1; \
+ incr1 = -2 * dx + 2 * (dy) * m1; \
+ incr2 = -2 * dx + 2 * (dy) * m; \
+ d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
+ } else { \
+ m = dx / (dy); \
+ m1 = m + 1; \
+ incr1 = 2 * dx - 2 * (dy) * m1; \
+ incr2 = 2 * dx - 2 * (dy) * m; \
+ d = -2 * m * (dy) + 2 * dx; \
+ } \
+ } \
+}
+
+#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \
+ if (m1 > 0) { \
+ if (d > 0) { \
+ minval += m1; \
+ d += incr1; \
+ } \
+ else { \
+ minval += m; \
+ d += incr2; \
+ } \
+ } else {\
+ if (d >= 0) { \
+ minval += m1; \
+ d += incr1; \
+ } \
+ else { \
+ minval += m; \
+ d += incr2; \
+ } \
+ } \
+}
+
+
+/*
+ * This structure tqcontains all of the information needed
+ * to run the bresenham algorithm.
+ * The variables may be hardcoded into the declarations
+ * instead of using this structure to make use of
+ * register declarations.
+ */
+typedef struct {
+ int minor; /* minor axis */
+ int d; /* decision variable */
+ int m, m1; /* slope and slope+1 */
+ int incr1, incr2; /* error increments */
+} BRESINFO;
+
+
+#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
+ BRESINITPGON(dmaj, min1, min2, bres.minor, bres.d, \
+ bres.m, bres.m1, bres.incr1, bres.incr2)
+
+#define BRESINCRPGONSTRUCT(bres) \
+ BRESINCRPGON(bres.d, bres.minor, bres.m, bres.m1, bres.incr1, bres.incr2)
+
+
+typedef struct _EdgeTableEntry {
+ int ymax; /* ycoord at which we exit this edge. */
+ BRESINFO bres; /* Bresenham info to run the edge */
+ struct _EdgeTableEntry *next; /* next in the list */
+ struct _EdgeTableEntry *back; /* for insertion sort */
+ struct _EdgeTableEntry *nextWETE; /* for winding num rule */
+ int ClockWise; /* flag for winding number rule */
+} EdgeTableEntry;
+
+
+typedef struct _ScanLineList{
+ int scanline; /* the scanline represented */
+ EdgeTableEntry *edgelist; /* header node */
+ struct _ScanLineList *next; /* next in the list */
+} ScanLineList;
+
+
+typedef struct {
+ int ymax; /* ymax for the polygon */
+ int ymin; /* ymin for the polygon */
+ ScanLineList scanlines; /* header node */
+} EdgeTable;
+
+
+/*
+ * Here is a struct to help with storage allocation
+ * so we can allocate a big chunk at a time, and then take
+ * pieces from this heap when we need to.
+ */
+#define SLLSPERBLOCK 25
+
+typedef struct _ScanLineListBlock {
+ ScanLineList SLLs[SLLSPERBLOCK];
+ struct _ScanLineListBlock *next;
+} ScanLineListBlock;
+
+/*
+ * number of points to buffer before sending them off
+ * to scanlines() : Must be an even number
+ */
+#define NUMPTSTOBUFFER 200
+
+/*
+ *
+ * a few macros for the inner loops of the fill code where
+ * performance considerations don't allow a procedure call.
+ *
+ * Evaluate the given edge at the given scanline.
+ * If the edge has expired, then we leave it and fix up
+ * the active edge table; otherwise, we increment the
+ * x value to be ready for the next scanline.
+ * The winding number rule is in effect, so we must notify
+ * the caller when the edge has been removed so he
+ * can reorder the Winding Active Edge Table.
+ */
+#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
+ if (pAET->ymax == y) { /* leaving this edge */ \
+ pPrevAET->next = pAET->next; \
+ pAET = pPrevAET->next; \
+ fixWAET = 1; \
+ if (pAET) \
+ pAET->back = pPrevAET; \
+ } \
+ else { \
+ BRESINCRPGONSTRUCT(pAET->bres); \
+ pPrevAET = pAET; \
+ pAET = pAET->next; \
+ } \
+}
+
+
+/*
+ * Evaluate the given edge at the given scanline.
+ * If the edge has expired, then we leave it and fix up
+ * the active edge table; otherwise, we increment the
+ * x value to be ready for the next scanline.
+ * The even-odd rule is in effect.
+ */
+#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
+ if (pAET->ymax == y) { /* leaving this edge */ \
+ pPrevAET->next = pAET->next; \
+ pAET = pPrevAET->next; \
+ if (pAET) \
+ pAET->back = pPrevAET; \
+ } \
+ else { \
+ BRESINCRPGONSTRUCT(pAET->bres) \
+ pPrevAET = pAET; \
+ pAET = pAET->next; \
+ } \
+}
+
+/***********************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSETQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+******************************************************************/
+
+#define MAXINT 0x7fffffff
+#define MININT -MAXINT
+
+/*
+ * fillUtils.c
+ *
+ * Written by Brian Kelleher; Oct. 1985
+ *
+ * This module tqcontains all of the utility functions
+ * needed to scan convert a polygon.
+ *
+ */
+/*
+ * InsertEdgeInET
+ *
+ * Insert the given edge into the edge table.
+ * First we must tqfind the correct bucket in the
+ * Edge table, then tqfind the right slot in the
+ * bucket. Finally, we can insert it.
+ *
+ */
+static bool
+miInsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE,
+ int scanline, ScanLineListBlock **SLLBlock, int *iSLLBlock)
+{
+ register EdgeTableEntry *start, *prev;
+ register ScanLineList *pSLL, *pPrevSLL;
+ ScanLineListBlock *tmpSLLBlock;
+
+ /*
+ * tqfind the right bucket to put the edge into
+ */
+ pPrevSLL = &ET->scanlines;
+ pSLL = pPrevSLL->next;
+ while (pSLL && (pSLL->scanline < scanline))
+ {
+ pPrevSLL = pSLL;
+ pSLL = pSLL->next;
+ }
+
+ /*
+ * reassign pSLL (pointer to ScanLineList) if necessary
+ */
+ if ((!pSLL) || (pSLL->scanline > scanline))
+ {
+ if (*iSLLBlock > SLLSPERBLOCK-1)
+ {
+ tmpSLLBlock =
+ (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock));
+ if (!tmpSLLBlock)
+ return FALSE;
+ (*SLLBlock)->next = tmpSLLBlock;
+ tmpSLLBlock->next = 0;
+ *SLLBlock = tmpSLLBlock;
+ *iSLLBlock = 0;
+ }
+ pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
+
+ pSLL->next = pPrevSLL->next;
+ pSLL->edgelist = 0;
+ pPrevSLL->next = pSLL;
+ }
+ pSLL->scanline = scanline;
+
+ /*
+ * now insert the edge in the right bucket
+ */
+ prev = 0;
+ start = pSLL->edgelist;
+ while (start && (start->bres.minor < ETE->bres.minor))
+ {
+ prev = start;
+ start = start->next;
+ }
+ ETE->next = start;
+
+ if (prev)
+ prev->next = ETE;
+ else
+ pSLL->edgelist = ETE;
+ return TRUE;
+}
+
+/*
+ * CreateEdgeTable
+ *
+ * This routine creates the edge table for
+ * scan converting polygons.
+ * The Edge Table (ET) looks like:
+ *
+ * EdgeTable
+ * --------
+ * | ymax | ScanLineLists
+ * |scanline|-->------------>-------------->...
+ * -------- |scanline| |scanline|
+ * |edgelist| |edgelist|
+ * --------- ---------
+ * | |
+ * | |
+ * V V
+ * list of ETEs list of ETEs
+ *
+ * where ETE is an EdgeTableEntry data structure,
+ * and there is one ScanLineList per scanline at
+ * which an edge is initially entered.
+ *
+ */
+
+typedef struct {
+#if defined(TQ_OS_MAC)
+ int y, x;
+#else
+ int x, y;
+#endif
+
+} DDXPointRec, *DDXPointPtr;
+
+/*
+ * Clean up our act.
+ */
+static void
+miFreeStorage(ScanLineListBlock *pSLLBlock)
+{
+ register ScanLineListBlock *tmpSLLBlock;
+
+ while (pSLLBlock)
+ {
+ tmpSLLBlock = pSLLBlock->next;
+ free(pSLLBlock);
+ pSLLBlock = tmpSLLBlock;
+ }
+}
+
+static bool
+miCreateETandAET(int count, DDXPointPtr pts, EdgeTable *ET,
+ EdgeTableEntry *AET, EdgeTableEntry *pETEs, ScanLineListBlock *pSLLBlock)
+{
+ register DDXPointPtr top, bottom;
+ register DDXPointPtr PrevPt, CurrPt;
+ int iSLLBlock = 0;
+
+ int dy;
+
+ if (count < 2) return TRUE;
+
+ /*
+ * initialize the Active Edge Table
+ */
+ AET->next = 0;
+ AET->back = 0;
+ AET->nextWETE = 0;
+ AET->bres.minor = MININT;
+
+ /*
+ * initialize the Edge Table.
+ */
+ ET->scanlines.next = 0;
+ ET->ymax = MININT;
+ ET->ymin = MAXINT;
+ pSLLBlock->next = 0;
+
+ PrevPt = &pts[count-1];
+
+ /*
+ * for each vertex in the array of points.
+ * In this loop we are dealing with two vertices at
+ * a time -- these make up one edge of the polygon.
+ */
+ while (count--)
+ {
+ CurrPt = pts++;
+
+ /*
+ * tqfind out which point is above and which is below.
+ */
+ if (PrevPt->y > CurrPt->y)
+ {
+ bottom = PrevPt, top = CurrPt;
+ pETEs->ClockWise = 0;
+ }
+ else
+ {
+ bottom = CurrPt, top = PrevPt;
+ pETEs->ClockWise = 1;
+ }
+
+ /*
+ * don't add horizontal edges to the Edge table.
+ */
+ if (bottom->y != top->y)
+ {
+ pETEs->ymax = bottom->y-1; /* -1 so we don't get last scanline */
+
+ /*
+ * initialize integer edge algorithm
+ */
+ dy = bottom->y - top->y;
+ BRESINITPGONSTRUCT(dy, top->x, bottom->x, pETEs->bres)
+
+ if (!miInsertEdgeInET(ET, pETEs, top->y, &pSLLBlock, &iSLLBlock))
+ {
+ miFreeStorage(pSLLBlock->next);
+ return FALSE;
+ }
+
+ ET->ymax = TQMAX(ET->ymax, PrevPt->y);
+ ET->ymin = TQMIN(ET->ymin, PrevPt->y);
+ pETEs++;
+ }
+
+ PrevPt = CurrPt;
+ }
+ return TRUE;
+}
+
+/*
+ * loadAET
+ *
+ * This routine moves EdgeTableEntries from the
+ * EdgeTable into the Active Edge Table,
+ * leaving them sorted by smaller x coordinate.
+ *
+ */
+
+static void
+miloadAET(EdgeTableEntry *AET, EdgeTableEntry *ETEs)
+{
+ register EdgeTableEntry *pPrevAET;
+ register EdgeTableEntry *tmp;
+
+ pPrevAET = AET;
+ AET = AET->next;
+ while (ETEs)
+ {
+ while (AET && (AET->bres.minor < ETEs->bres.minor))
+ {
+ pPrevAET = AET;
+ AET = AET->next;
+ }
+ tmp = ETEs->next;
+ ETEs->next = AET;
+ if (AET)
+ AET->back = ETEs;
+ ETEs->back = pPrevAET;
+ pPrevAET->next = ETEs;
+ pPrevAET = ETEs;
+
+ ETEs = tmp;
+ }
+}
+
+/*
+ * computeWAET
+ *
+ * This routine links the AET by the
+ * nextWETE (winding EdgeTableEntry) link for
+ * use by the winding number rule. The final
+ * Active Edge Table (AET) might look something
+ * like:
+ *
+ * AET
+ * ---------- --------- ---------
+ * |ymax | |ymax | |ymax |
+ * | ... | |... | |... |
+ * |next |->|next |->|next |->...
+ * |nextWETE| |nextWETE| |nextWETE|
+ * --------- --------- ^--------
+ * | | |
+ * V-------------------> V---> ...
+ *
+ */
+static void
+micomputeWAET(EdgeTableEntry *AET)
+{
+ register EdgeTableEntry *pWETE;
+ register int inside = 1;
+ register int isInside = 0;
+
+ AET->nextWETE = 0;
+ pWETE = AET;
+ AET = AET->next;
+ while (AET)
+ {
+ if (AET->ClockWise)
+ isInside++;
+ else
+ isInside--;
+
+ if ((!inside && !isInside) ||
+ ( inside && isInside))
+ {
+ pWETE->nextWETE = AET;
+ pWETE = AET;
+ inside = !inside;
+ }
+ AET = AET->next;
+ }
+ pWETE->nextWETE = 0;
+}
+
+/*
+ * InsertionSort
+ *
+ * Just a simple insertion sort using
+ * pointers and back pointers to sort the Active
+ * Edge Table.
+ *
+ */
+
+static int
+miInsertionSort(EdgeTableEntry *AET)
+{
+ register EdgeTableEntry *pETEchase;
+ register EdgeTableEntry *pETEinsert;
+ register EdgeTableEntry *pETEchaseBackTMP;
+ register int changed = 0;
+
+ AET = AET->next;
+ while (AET)
+ {
+ pETEinsert = AET;
+ pETEchase = AET;
+ while (pETEchase->back->bres.minor > AET->bres.minor)
+ pETEchase = pETEchase->back;
+
+ AET = AET->next;
+ if (pETEchase != pETEinsert)
+ {
+ pETEchaseBackTMP = pETEchase->back;
+ pETEinsert->back->next = AET;
+ if (AET)
+ AET->back = pETEinsert->back;
+ pETEinsert->next = pETEchase;
+ pETEchase->back->next = pETEinsert;
+ pETEchase->back = pETEinsert;
+ pETEinsert->back = pETEchaseBackTMP;
+ changed = 1;
+ }
+ }
+ return(changed);
+}
+
+/*!
+ \overload
+*/
+void TQPolygonScanner::scan(const TQPointArray& pa, bool winding, int index, int npoints)
+{
+ scan( pa, winding, index, npoints, TRUE );
+}
+
+/*!
+ \overload
+
+ If \a stitchable is FALSE, the right and bottom edges of the
+ polygon are included. This causes adjacent polygons to overlap.
+*/
+void TQPolygonScanner::scan(const TQPointArray& pa, bool winding, int index, int npoints, bool stitchable)
+{
+ scan( pa, winding, index, npoints,
+ stitchable ? Edge(Left+Top) : Edge(Left+Right+Top+Bottom) );
+}
+
+/*!
+ Calls processSpans() for all scanlines of the polygon defined by
+ \a npoints starting at \a index in \a pa.
+
+ If \a winding is TRUE, the Winding algorithm rather than the
+ Odd-Even rule is used.
+
+ The \a edges is any bitwise combination of:
+ \list
+ \i \c TQPolygonScanner::Left
+ \i \c TQPolygonScanner::Right
+ \i \c TQPolygonScanner::Top
+ \i \c TQPolygonScanner::Bottom
+ \endlist
+ \a edges determines which edges are included.
+
+ \warning The edges feature does not work properly.
+
+*/
+void TQPolygonScanner::scan( const TQPointArray& pa, bool winding, int index, int npoints, Edge edges )
+{
+
+
+ DDXPointPtr ptsIn = (DDXPointPtr)pa.data();
+ ptsIn += index;
+ register EdgeTableEntry *pAET; /* the Active Edge Table */
+ register int y; /* the current scanline */
+ register int nPts = 0; /* number of pts in buffer */
+ register EdgeTableEntry *pWETE; /* Winding Edge Table */
+ register ScanLineList *pSLL; /* Current ScanLineList */
+ register DDXPointPtr ptsOut; /* ptr to output buffers */
+ int *width;
+ DDXPointRec FirstPoint[NUMPTSTOBUFFER]; /* the output buffers */
+ int FirstWidth[NUMPTSTOBUFFER];
+ EdgeTableEntry *pPrevAET; /* previous AET entry */
+ EdgeTable ET; /* Edge Table header node */
+ EdgeTableEntry AET; /* Active ET header node */
+ EdgeTableEntry *pETEs; /* Edge Table Entries buff */
+ ScanLineListBlock SLLBlock; /* header for ScanLineList */
+ int fixWAET = 0;
+ int edge_l = (edges & Left) ? 1 : 0;
+ int edge_r = (edges & Right) ? 1 : 0;
+ int edge_t = 1; //#### (edges & Top) ? 1 : 0;
+ int edge_b = (edges & Bottom) ? 1 : 0;
+
+ if (npoints == -1)
+ npoints = pa.size();
+
+ if (npoints < 3)
+ return;
+
+ if(!(pETEs = (EdgeTableEntry *)
+ malloc(sizeof(EdgeTableEntry) * npoints)))
+ return;
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ if (!miCreateETandAET(npoints, ptsIn, &ET, &AET, pETEs, &SLLBlock))
+ {
+ free(pETEs);
+ return;
+ }
+ pSLL = ET.scanlines.next;
+
+ if (!winding)
+ {
+ /*
+ * for each scanline
+ */
+ for (y = ET.ymin+1-edge_t; y < ET.ymax+edge_b; y++)
+ {
+ /*
+ * Add a new edge to the active edge table when we
+ * get to the next edge.
+ */
+ if (pSLL && y == pSLL->scanline)
+ {
+ miloadAET(&AET, pSLL->edgelist);
+ pSLL = pSLL->next;
+ }
+ pPrevAET = &AET;
+ pAET = AET.next;
+
+ /*
+ * for each active edge
+ */
+ while (pAET)
+ {
+ ptsOut->x = pAET->bres.minor + 1 - edge_l;
+ ptsOut++->y = y;
+ *width++ = pAET->next->bres.minor - pAET->bres.minor
+ - 1 + edge_l + edge_r;
+ nPts++;
+
+ /*
+ * send out the buffer when its full
+ */
+ if (nPts == NUMPTSTOBUFFER)
+ {
+ processSpans( nPts, (TQPoint*)FirstPoint, FirstWidth );
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ nPts = 0;
+ }
+ EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
+ EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
+ }
+ miInsertionSort(&AET);
+ }
+ }
+ else /* default to WindingNumber */
+ {
+ /*
+ * for each scanline
+ */
+ for (y = ET.ymin+1-edge_t; y < ET.ymax+edge_b; y++)
+ {
+ /*
+ * Add a new edge to the active edge table when we
+ * get to the next edge.
+ */
+ if (pSLL && y == pSLL->scanline)
+ {
+ miloadAET(&AET, pSLL->edgelist);
+ micomputeWAET(&AET);
+ pSLL = pSLL->next;
+ }
+ pPrevAET = &AET;
+ pAET = AET.next;
+ pWETE = pAET;
+
+ /*
+ * for each active edge
+ */
+ while (pAET)
+ {
+ /*
+ * if the next edge in the active edge table is
+ * also the next edge in the winding active edge
+ * table.
+ */
+ if (pWETE == pAET)
+ {
+ ptsOut->x = pAET->bres.minor + 1 - edge_l;
+ ptsOut++->y = y;
+ *width++ = pAET->nextWETE->bres.minor - pAET->bres.minor - 1 + edge_l + edge_r;
+ nPts++;
+
+ /*
+ * send out the buffer
+ */
+ if (nPts == NUMPTSTOBUFFER)
+ {
+ processSpans( nPts, (TQPoint*)FirstPoint, FirstWidth );
+ ptsOut = FirstPoint;
+ width = FirstWidth;
+ nPts = 0;
+ }
+
+ pWETE = pWETE->nextWETE;
+ while (pWETE != pAET) {
+ EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
+ }
+ pWETE = pWETE->nextWETE;
+ }
+ EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
+ }
+
+ /*
+ * reevaluate the Winding active edge table if we
+ * just had to resort it or if we just exited an edge.
+ */
+ if (miInsertionSort(&AET) || fixWAET)
+ {
+ micomputeWAET(&AET);
+ fixWAET = 0;
+ }
+ }
+ }
+
+ /*
+ * Get any spans that we missed by buffering
+ */
+
+
+ processSpans( nPts, (TQPoint*)FirstPoint, FirstWidth );
+ free(pETEs);
+ miFreeStorage(SLLBlock.next);
+}
+/***** END OF X11-based CODE *****/
+
+
diff --git a/tqtinterface/qt4/src/kernel/tqpolygonscanner.h b/tqtinterface/qt4/src/kernel/tqpolygonscanner.h
new file mode 100644
index 0000000..433504e
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpolygonscanner.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Definition of TQPolygonScanner class
+**
+** Created : 000120
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPOLYGONSCANNER_H
+#define TQPOLYGONSCANNER_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+class TQPointArray;
+class TQPoint;
+
+class TQ_EXPORT TQPolygonScanner {
+public:
+ // BIC: fix for 3.0
+ void scan( const TQPointArray& pa, bool winding, int index=0, int npoints=-1 );
+ void scan( const TQPointArray& pa, bool winding, int index, int npoints, bool stitchable );
+ enum Edge { Left=1, Right=2, Top=4, Bottom=8 };
+ void scan( const TQPointArray& pa, bool winding, int index, int npoints, Edge edges );
+ virtual void processSpans( int n, TQPoint* point, int* width )=0;
+};
+
+#endif // TQPOLYGONSCANNER_H
diff --git a/tqtinterface/qt4/src/kernel/tqprinter.cpp b/tqtinterface/qt4/src/kernel/tqprinter.cpp
new file mode 100644
index 0000000..31c5c19
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqprinter.cpp
@@ -0,0 +1,1198 @@
+/**********************************************************************
+**
+** Implementation of TQPrinter class
+**
+** Created : 941003
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <tqtglobaldefines.h>
+// Nasty, nasty horrid HACK to get access to QPrinter's private members
+// This is TERRIBLE and I wish there was a way around it
+// This is a good example of the new, broken & irritating Qt4 API,
+// and the corresponding loss in functionality versus Qt3.
+// See also tqrect.cpp
+#define private protected
+#include <Qt/qprinter.h>
+#undef private
+
+#include "tqprinter.h"
+#include "tqprinter_p.h"
+
+#ifndef TQT_NO_PRINTER
+
+#ifdef USE_QT4
+
+#include "tqprintdialog.h"
+#include "private/qt4_qprinter_p.h"
+
+#ifdef Q_WS_MAC
+bool qt_compat_QPrinter_pageSetup(QPrinter *p, QWidget *parent)
+{
+ QPageSetupDialog psd(p, parent);
+ return psd.exec() != 0;
+}
+#endif // Q_WS_MAC
+
+bool qt_compat_QPrinter_printSetup(QPrinter *printer, QWidget *parent)
+{
+ TQPrintDialog dlg(TQT_TQPRINTER(printer), TQT_TQWIDGET(parent));
+ return dlg.exec() != 0;
+}
+
+#ifdef Q_WS_MAC
+/*!
+ Executes a page setup dialog so that the user can configure the type of
+ page used for printing. Returns true if the contents of the dialog are
+ accepted; returns false if the dialog is canceled.
+*/
+bool TQPrinter::pageSetup(QWidget *parent)
+{
+ return qt_compat_QPrinter_pageSetup(this, parent);
+}
+
+/*!
+ Executes a print setup dialog so that the user can configure the printing
+ process. Returns true if the contents of the dialog are accepted; returns
+ false if the dialog is canceled.
+*/
+bool TQPrinter::printSetup(QWidget *parent)
+{
+ return qt_compat_QPrinter_printSetup(this, parent);
+}
+#endif // Q_WS_MAC
+
+/*!
+ Use QPrintDialog instead.
+
+ \oldcode
+ if (printer->setup(parent))
+ ...
+ \newcode
+ QPrintDialog dialog(printer, parent);
+ if (dialog.exec())
+ ...
+ \endcode
+*/
+bool TQPrinter::setup(QWidget *parent)
+{
+ return qt_compat_QPrinter_printSetup(this, parent)
+#ifdef Q_WS_MAC
+ && qt_compat_QPrinter_pageSetup(this, parent);
+#endif
+ ;
+}
+
+/*!
+ Use QPrintDialog::minPage() instead.
+*/
+int TQPrinter::minPage() const
+{
+ return d_ptr->minPage;
+}
+
+/*!
+ Use QPrintDialog::maxPage() instead.
+*/
+int TQPrinter::maxPage() const
+{
+ return d_ptr->maxPage;
+}
+
+/*!
+ Use QPrintDialog::setMinMax() instead.
+*/
+void TQPrinter::setMinMax( int minPage, int maxPage )
+{
+ Q_ASSERT_X(minPage <= maxPage, "QPrinter::setMinMax",
+ "'min' must be less than or equal to 'max'");
+ d_ptr->minPage = minPage;
+ d_ptr->maxPage = maxPage;
+ d_ptr->options |= QPrintDialog::PrintPageRange;
+}
+
+/*!
+ Use QPrintDialog::setOption(QPrintDialog::PrintCollateCopies)
+ or QPrintDialog::setOptions(QPrintDialog::options()
+ & ~QPrintDialog::PrintCollateCopies) instead, depending on \a
+ enable.
+*/
+void TQPrinter::setCollateCopiesEnabled(bool enable)
+{
+ if (enable)
+ d_ptr->options |= QPrintDialog::PrintCollateCopies;
+ else
+ d_ptr->options &= ~QPrintDialog::PrintCollateCopies;
+}
+
+/*!
+ Returns true if the printer is set up to collate copies of printed documents;
+ otherwise returns false.
+
+ Use QPrintDialog::isOptionEnabled(QPrintDialog::PrintCollateCopies)
+ instead.
+
+ \sa collateCopies()
+*/
+bool TQPrinter::collateCopiesEnabled() const
+{
+ return (d_ptr->options & QPrintDialog::PrintCollateCopies);
+}
+
+/*!
+ Use QPrintDialog instead.
+*/
+void TQPrinter::setOptionEnabled( PrinterOption option, bool enable )
+{
+ if (enable)
+ d_ptr->options |= QPrintDialog::PrintDialogOption(1 << option);
+ else
+ d_ptr->options &= ~QPrintDialog::PrintDialogOption(1 << option);
+}
+
+/*!
+ Use QPrintDialog instead.
+*/
+bool TQPrinter::isOptionEnabled( PrinterOption option ) const
+{
+ return (d_ptr->options & QPrintDialog::PrintDialogOption(option));
+}
+
+/*!
+ \fn void QPrinter::setOutputToFile(bool enable)
+
+ Specifies whether the output should be written to a file or sent
+ directly to the printer.
+
+ Will output to a file if \a enable is true, or will output
+ directly to the printer if \a enable is false.
+
+ \sa outputToFile(), setOutputFileName()
+*/
+void TQPrinter::setOutputToFile(bool f)
+{
+ if (f) {
+ if (outputFileName().isEmpty())
+ setOutputFileName(QLatin1String("untitled_printer_document"));
+ } else {
+ setOutputFileName(QString());
+ }
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQPrinter tqprinter.h
+ \brief The TQPrinter class is a paint tqdevice that paints on a printer.
+
+ \ingroup images
+ \ingroup graphics
+ \mainclass
+
+ On Windows it uses the built-in printer drivers. On X11 it
+ generates postscript and sends that to lpr, lp, or another print
+ command.
+
+ TQPrinter is used in much the same way as TQWidget and TQPixmap are
+ used. The big difference is that you must keep track of the pages.
+
+ TQPrinter supports a number of settable parameters, most of which
+ can be changed by the end user when the application calls
+ TQPrinter::setup().
+
+ The most important parameters are:
+ \list
+ \i setOrientation() tells TQPrinter which page orientation to use (virtual).
+ \i setPageSize() tells TQPrinter what page size to expect from the
+ printer.
+ \i setResolution() tells TQPrinter what resolution you wish the
+ printer to provide (in dpi).
+ \i setFullPage() tells TQPrinter whether you want to deal with the
+ full page or just with the part the printer can draw on. The
+ default is FALSE, so that by default you should be able to paint
+ on (0,0). If TRUE the origin of the coordinate system will be in
+ the top left corner of the paper and most probably the printer
+ will not be able to paint something there due to it's physical
+ margins.
+ \i setNumCopies() tells TQPrinter how many copies of the document
+ it should print.
+ \i setMinMax() tells TQPrinter and TQPrintDialog what the allowed
+ range for fromPage() and toPage() are.
+ \endlist
+
+ Except where noted, you can only call the set functions before
+ setup(), or between TQPainter::end() and setup(). (Some may take
+ effect between setup() and begin(), or between begin() and end(),
+ but that's strictly undocumented and such behaviour may differ
+ depending on platform.)
+
+ There are also some settings that the user sets (through the
+ printer dialog) and that applications are expected to obey:
+
+ \list
+
+ \i pageOrder() tells the application program whether to print
+ first-page-first or last-page-first.
+
+ \i colorMode() tells the application program whether to print in
+ color or grayscale. (If you print in color and the printer does
+ not support color, TQt will try to approximate. The document may
+ take longer to print, but the quality should not be made visibly
+ poorer.)
+
+ \i fromPage() and toPage() indicate what pages the application
+ program should print.
+
+ \i paperSource() tells the application progam which paper source
+ to print from.
+
+ \endlist
+
+ You can of course call these functions to establish defaults
+ before you ask the user through TQPrinter::setup().
+
+ Once you start printing, calling newPage() is essential. You will
+ probably also need to look at the TQPaintDeviceMetrics for the
+ printer (see the \link simple-application.html#printersimple print
+ function\endlink in the Application walk-through). In previous versions,
+ paint tqdevice metrics were valid only after the TQPrinter has been set
+ up, i.e. after setup() has returned successfully. This is no longer
+ the case and paint tqdevice metrics can be requested safely before set up.
+
+ If you want to abort the print job, abort() will try its best to
+ stop printing. It may cancel the entire job or just some of it.
+
+ \omit Need a function to setup() without a dialog (i.e. use defaults).
+ \endomit
+
+ The TrueType font embedding for TQt's postscript driver uses code
+ by David Chappell of Trinity College Computing Center.
+
+ \legalese
+
+ Copyright 1995, Trinity College Computing Center.
+ Written by David Chappell.
+
+ Permission to use, copy, modify, and distribute this software and
+ its documentation for any purpose and without fee is hereby
+ granted, provided that the above copyright notice appear in all
+ copies and that both that copyright notice and this permission
+ notice appear in supporting documentation. This software is
+ provided "as is" without express or implied warranty.
+
+ TrueType font support. These functions allow PPR to generate
+ PostScript fonts from Microsoft compatible TrueType font files.
+
+ The functions in this file do most of the work to convert a
+ TrueType font to a type 3 PostScript font.
+
+ Most of the material in this file is derived from a program called
+ "ttf2ps" which L. S. Ng posted to the usenet news group
+ "comp.sources.postscript". The author did not provide a copyright
+ notice or indicate any restrictions on use.
+
+ Last revised 11 July 1995.
+
+*/
+
+/*!
+ \enum TQPrinter::PrinterMode
+
+ This enum describes the mode the printer should work in. It
+ basically presets a certain resolution and working mode.
+
+ \value ScreenResolution Sets the resolution of the print tqdevice to
+ the screen resolution. This has the big advantage that the results
+ obtained when painting on the printer will match more or less
+ exactly the visible output on the screen. It is the easiest to
+ use, as font metrics on the screen and on the printer are the
+ same. This is the default value. ScreenResolution will produce a
+ lower quality output than HighResolution and should only be used
+ for drafts.
+
+ \value PrinterResolution Use the physical resolution of the
+ printer on Windows. On Unix, set the postscript resolution to 72
+ dpi.
+
+ \value HighResolution Use printer resolution on windows, set the
+ resolution of the postscript driver to 600dpi.
+
+ \value Compatible Almost the same as PrinterResolution, but keeps
+ some peculiarities of the TQt 2.x printer driver. This is useful
+ for applications ported from TQt 2.x to TQt 3.x.
+*/
+
+/*!
+ \enum TQPrinter::Orientation
+
+ This enum type (not to be confused with Orientation) is used
+ to specify each page's orientation.
+
+ \value Portrait the page's height is greater than its width (the
+ default).
+
+ \value Landscape the page's width is greater than its height.
+
+ This type interacts with \l TQPrinter::PageSize and
+ TQPrinter::setFullPage() to determine the final size of the page
+ available to the application.
+*/
+
+
+/*!
+ \enum TQPrinter::PageSize
+
+ This enum type specifies what paper size TQPrinter should use.
+ TQPrinter does not check that the paper size is available; it just
+ uses this information, together with TQPrinter::Orientation and
+ TQPrinter::setFullPage(), to determine the printable area (see
+ TQPaintDeviceMetrics).
+
+ The defined sizes (with setFullPage(TRUE)) are:
+
+ \value A0 841 x 1189 mm This value is not supported on windows.
+ \value A1 594 x 841 mm This value is not supported on windows.
+ \value A2 420 x 594 mm
+ \value A3 297 x 420 mm
+ \value A4 210 x 297 mm, 8.26 x 11.7 inches
+ \value A5 148 x 210 mm
+ \value A6 105 x 148 mm
+ \value A7 74 x 105 mm
+ \value A8 52 x 74 mm
+ \value A9 37 x 52 mm
+ \value B0 1030 x 1456 mm
+ \value B1 728 x 1030 mm
+ \value B10 32 x 45 mm
+ \value B2 515 x 728 mm
+ \value B3 364 x 515 mm
+ \value B4 257 x 364 mm
+ \value B5 182 x 257 mm, 7.17 x 10.13 inches
+ \value B6 128 x 182 mm
+ \value B7 91 x 128 mm
+ \value B8 64 x 91 mm
+ \value B9 45 x 64 mm
+ \value C5E 163 x 229 mm
+ \value Comm10E 105 x 241 mm, US Common #10 Envelope
+ \value DLE 110 x 220 mm
+ \value Executive 7.5 x 10 inches, 191 x 254 mm
+ \value Folio 210 x 330 mm
+ \value Ledger 432 x 279 mm
+ \value Legal 8.5 x 14 inches, 216 x 356 mm
+ \value Letter 8.5 x 11 inches, 216 x 279 mm
+ \value Tabloid 279 x 432 mm
+ \value Custom
+ \value NPageSize (internal)
+
+ With setFullPage(FALSE) (the default), the metrics will be a bit
+ smaller; how much depends on the printer in use.
+*/
+
+
+/*!
+ \enum TQPrinter::PageOrder
+
+ This enum type is used by TQPrinter to tell the application program
+ how to print.
+
+ \value FirstPageFirst the lowest-numbered page should be printed
+ first.
+
+ \value LastPageFirst the highest-numbered page should be printed
+ first.
+*/
+
+/*!
+ \enum TQPrinter::ColorMode
+
+ This enum type is used to indicate whether TQPrinter should print
+ in color or not.
+
+ \value Color print in color if available, otherwise in grayscale.
+
+ \value GrayScale print in grayscale, even on color printers.
+ Might be a little faster than \c Color. This is the default.
+*/
+
+/*!
+ \enum TQPrinter::PaperSource
+
+ This enum type specifies what paper source TQPrinter is to use.
+ TQPrinter does not check that the paper source is available; it
+ just uses this information to try and set the paper source.
+ Whether it will set the paper source depends on whether the
+ printer has that particular source.
+
+ Note: this is currently only implemented for Windows.
+
+ \value OnlyOne
+ \value Lower
+ \value Middle
+ \value Manual
+ \value Envelope
+ \value EnvelopeManual
+ \value Auto
+ \value Tractor
+ \value SmallFormat
+ \value LargeFormat
+ \value LargeCapacity
+ \value Cassette
+ \value FormSource
+*/
+
+/*!
+ \enum TQPrinter::PrintRange
+
+ This enum is used to specify which print range the application
+ should use to print.
+
+ \value AllPages All pages should be printed
+ \value Selection Only the selection should be printed.
+ \value PageRange From page, to page option.
+
+ \sa setPrintRange(), printRange()
+*/
+
+/*!
+ \enum TQPrinter::PrinterOption
+
+ This enum describes various printer options that appear in the
+ printer setup dialog. It is used to enable and disable these
+ options in the setup dialog.
+
+ \value PrintToFile Describes if print to file should be enabled.
+ \value PrintSelection Describes if printing selections should be enabled.
+ \value PrintPageRange Describes if printing page ranges (from, to) should
+ be enabled
+
+ \sa setOptionEnabled(), isOptionEnabled()
+*/
+
+
+/*!
+ \fn TQString TQPrinter::printerName() const
+
+ Returns the printer name. This value is initially set to the name
+ of the default printer.
+
+ \sa setPrinterName()
+*/
+
+/*!
+ \fn bool TQPrinter::outputToFile() const
+
+ Returns TRUE if the output should be written to a file, or FALSE
+ if the output should be sent directly to the printer. The default
+ setting is FALSE.
+
+ This function is currently only supported under X11 and Mac OS X.
+
+ \sa setOutputToFile(), setOutputFileName()
+*/
+
+/*!
+ Specifies whether the output should be written to a file or sent
+ directly to the printer.
+
+ Will output to a file if \a enable is TRUE, or will output
+ directly to the printer if \a enable is FALSE.
+
+ This function is currently only supported under X11 and Mac OS X.
+
+ \sa outputToFile(), setOutputFileName()
+*/
+
+void TQPrinter::setOutputToFile( bool enable )
+{
+ if ( state != 0 ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPrinter::setOutputToFile: Cannot do this during printing" );
+#endif
+ return;
+ }
+ output_file = enable;
+}
+
+
+/*!
+ \fn TQString TQPrinter::outputFileName() const
+
+ Returns the name of the output file. There is no default file
+ name.
+
+ \sa setOutputFileName(), setOutputToFile()
+*/
+
+/*!
+ Sets the name of the output file to \a fileName.
+
+ Setting a null or empty name (0 or "") disables output to a file,
+ i.e. calls setOutputToFile(FALSE). Setting a non-empty name
+ enables output to a file, i.e. calls setOutputToFile(TRUE).
+
+ This function is currently only supported under X11.
+
+ \sa outputFileName(), setOutputToFile()
+*/
+
+void TQPrinter::setOutputFileName( const TQString &fileName )
+{
+ if ( state != 0 ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQPrinter::setOutputFileName: Cannot do this during printing");
+#endif
+ return;
+ }
+ output_filename = fileName;
+ output_file = !output_filename.isEmpty();
+}
+
+
+/*!
+ \fn TQString TQPrinter::printProgram() const
+
+ Returns the name of the program that sends the print output to the
+ printer.
+
+ The default is to return a null string; meaning that TQPrinter will
+ try to be smart in a system-dependent way. On X11 only, you can
+ set it to something different to use a specific print program.
+
+ On Windows, this function returns the name of the printer tqdevice
+ driver.
+
+ \sa setPrintProgram() setPrinterSelectionOption()
+*/
+
+/*!
+ Sets the name of the program that should do the print job to \a
+ printProg.
+
+ On X11, this function sets the program to call with the PostScript
+ output. On other platforms, it has no effect.
+
+ \sa printProgram()
+*/
+
+void TQPrinter::setPrintProgram( const TQString &printProg )
+{
+ print_prog = printProg;
+}
+
+
+/*!
+ \fn TQString TQPrinter::docName() const
+
+ Returns the document name.
+
+ \sa setDocName()
+*/
+
+/*!
+ Sets the document name to \a name.
+*/
+
+void TQPrinter::setDocName( const TQString &name )
+{
+ if ( state != 0 ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPrinter::setDocName: Cannot do this during printing" );
+#endif
+ return;
+ }
+ doc_name = name;
+}
+
+
+/*!
+ \fn TQString TQPrinter::creator() const
+
+ Returns the name of the application that created the document.
+
+ \sa setCreator()
+*/
+
+/*!
+ Sets the name of the application that created the document to \a
+ creator.
+
+ This function is only applicable to the X11 version of TQt. If no
+ creator name is specified, the creator will be set to "TQt"
+ followed by some version number.
+
+ \sa creator()
+*/
+
+void TQPrinter::setCreator( const TQString &creator )
+{
+ creator_name = creator;
+}
+
+
+/*!
+ \fn Orientation TQPrinter::orientation() const
+
+ Returns the orientation setting. The default value is \c
+ TQPrinter::Portrait.
+
+ \sa setOrientation()
+*/
+
+/*!
+ Sets the print orientation to \a orientation.
+
+ The orientation can be either \c TQPrinter::Portrait or \c
+ TQPrinter::Landscape.
+
+ The printer driver reads this setting and prints using the
+ specified orientation. On Windows this setting won't take effect
+ until the printer dialog is shown (using TQPrinter::setup()).
+
+ Windows only! This option can be changed while printing and will
+ take effect from the next call to newPage()
+
+ \sa orientation()
+*/
+
+void TQPrinter::setOrientation( Orientation orientation )
+{
+ orient = orientation;
+#if defined(TQ_WS_WIN)
+ reinit();
+#endif
+}
+
+
+/*!
+ \fn PageSize TQPrinter::pageSize() const
+
+ Returns the printer page size. The default value is system-dependent.
+
+ \sa setPageSize()
+*/
+
+
+/*!
+ Sets the printer page size to \a newPageSize if that size is
+ supported. The result if undefined if \a newPageSize is not
+ supported.
+
+ The default page size is system-dependent.
+
+ This function is useful mostly for setting a default value that
+ the user can override in the print dialog when you call setup().
+
+ \sa pageSize() PageSize setFullPage() setResolution()
+*/
+
+void TQPrinter::setPageSize( PageSize newPageSize )
+{
+ if ( newPageSize > NPageSize ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQPrinter::SetPageSize: illegal page size %d", newPageSize );
+#endif
+ return;
+ }
+ page_size = newPageSize;
+#if defined(TQ_WS_WIN)
+ reinit();
+#endif
+}
+
+/*!
+ Sets the page order to \a newPageOrder.
+
+ The page order can be \c TQPrinter::FirstPageFirst or \c
+ TQPrinter::LastPageFirst. The application programmer is responsible
+ for reading the page order and printing accordingly.
+
+ This function is useful mostly for setting a default value that
+ the user can override in the print dialog when you call setup().
+
+ \bug This value is not kept in sync with the Windows or Mac OS X printer
+ dialogs.
+*/
+
+void TQPrinter::setPageOrder( PageOrder newPageOrder )
+{
+ page_order = newPageOrder;
+#if defined(TQ_WS_WIN)
+ reinit();
+#endif
+}
+
+
+/*!
+ Returns the current page order.
+
+ The default page order is \c FirstPageFirst.
+
+ \bug This value is not kept in sync with the Windows or Mac OS X printer
+ dialogs.
+*/
+
+TQPrinter::PageOrder TQPrinter::pageOrder() const
+{
+ return page_order;
+}
+
+
+/*!
+ Sets the printer's color mode to \a newColorMode, which can be
+ either \c Color or \c GrayScale (the default).
+
+ \sa colorMode()
+*/
+
+void TQPrinter::setColorMode( ColorMode newColorMode )
+{
+ color_mode = newColorMode;
+#if defined(TQ_WS_WIN)
+ reinit();
+#endif
+}
+
+
+/*!
+ Returns the current color mode. The default color mode is \c
+ Color.
+
+ \sa setColorMode()
+*/
+
+TQPrinter::ColorMode TQPrinter::colorMode() const
+{
+ return color_mode;
+}
+
+
+/*!
+ \fn int TQPrinter::fromPage() const
+
+ Returns the from-page setting. The default value is 0.
+
+ If fromPage() and toPage() both return 0 this signifies 'print the
+ whole document'.
+
+ The programmer is responsible for reading this setting and
+ printing accordingly.
+
+ \sa setFromTo(), toPage()
+*/
+
+/*!
+ \fn int TQPrinter::toPage() const
+
+ Returns the to-page setting. The default value is 0.
+
+ If fromPage() and toPage() both return 0 this signifies 'print the
+ whole document'.
+
+ The programmer is responsible for reading this setting and
+ printing accordingly.
+
+ \sa setFromTo(), fromPage()
+*/
+
+/*!
+ Sets the from-page and to-page settings to \a fromPage and \a
+ toPage respectively.
+
+ The from-page and to-page settings specify what pages to print.
+
+ If fromPage() and toPage() both return 0 this signifies 'print the
+ whole document'.
+
+ This function is useful mostly to set a default value that the
+ user can override in the print dialog when you call setup().
+
+ \sa fromPage(), toPage(), setMinMax(), setup()
+*/
+
+void TQPrinter::setFromTo( int fromPage, int toPage )
+{
+ if ( state != 0 ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPrinter::setFromTo: Cannot do this during printing" );
+#endif
+ return;
+ }
+ from_pg = fromPage;
+ to_pg = toPage;
+}
+
+
+/*!
+ \fn int TQPrinter::minPage() const
+
+ Returns the min-page setting, i.e. the lowest page number a user
+ is allowed to choose. The default value is 0.
+
+ \sa maxPage(), setMinMax() setFromTo()
+*/
+
+/*!
+ \fn int TQPrinter::maxPage() const
+
+ Returns the max-page setting. A user can't choose a higher page
+ number than maxPage() when they select a print range. The default
+ value is 0.
+
+ \sa minPage(), setMinMax() setFromTo()
+*/
+
+/*!
+ Sets the min-page and max-page settings to \a minPage and \a
+ maxPage respectively.
+
+ The min-page and max-page restrict the from-page and to-page
+ settings. When the printer setup dialog appears, the user cannot
+ select a from page or a to page that are outside the range
+ specified by min and max pages.
+
+ \sa minPage(), maxPage(), setFromTo(), setup()
+*/
+
+void TQPrinter::setMinMax( int minPage, int maxPage )
+{
+ min_pg = minPage;
+ max_pg = maxPage;
+ if ( from_pg == 0 || from_pg < minPage )
+ from_pg = minPage;
+ if ( to_pg == 0 || to_pg > maxPage )
+ to_pg = maxPage;
+}
+
+
+/*!
+ \fn int TQPrinter::numCopies() const
+
+ Returns the number of copies to be printed. The default value is 1.
+
+ This value will return the number of times the application is
+ required to print in order to match the number specified in the
+ printer setup dialog. This has been done since some printer
+ drivers are not capable of buffering up the copies and the
+ application in those cases have to make an explicit call to the
+ print code for each copy.
+
+ \sa setNumCopies()
+*/
+
+/*!
+ \fn bool TQPrinter::collateCopiesEnabled() const
+
+ \internal
+
+ Returns TRUE if the application should provide the user with the
+ option of choosing a collated printout; otherwise returns FALSE.
+
+ Collation means that each page is printed in order, i.e. print the
+ first page, then the second page, then the third page and so on, and
+ then repeat this sequence for as many copies as have been requested.
+ If you don't collate you get several copies of the first page, then
+ several copies of the second page, then several copies of the third
+ page, and so on.
+
+ \sa setCollateCopiesEnabled() setCollateCopies() collateCopies()
+*/
+
+/*!
+ \fn void TQPrinter::setCollateCopiesEnabled(bool enable)
+
+ \internal
+
+ If \a enable is TRUE (the default) the user is given the choice of
+ whether to print out multiple copies collated in the print dialog.
+ If \a enable is FALSE, then collateCopies() will be ignored.
+
+ Collation means that each page is printed in order, i.e. print the
+ first page, then the second page, then the third page and so on, and
+ then repeat this sequence for as many copies as have been requested.
+ If you don't collate you get several copies of the first page, then
+ several copies of the second page, then several copies of the third
+ page, and so on.
+
+ \sa collateCopiesEnabled() setCollateCopies() collateCopies()
+*/
+
+/*!
+ \fn bool TQPrinter::collateCopies() const
+
+ \internal
+
+ Returns TRUE if collation is turned on when multiple copies is selected.
+ Returns FALSE if it is turned off when multiple copies is selected.
+
+ \sa collateCopiesEnabled() setCollateCopiesEnabled() setCollateCopies()
+*/
+
+/*!
+ \internal
+
+ Sets the default value for collation checkbox when the print dialog appears.
+ If \a on is TRUE, it will enable setCollateCopiesEnabled().
+ The default value is FALSE. This value will be changed by what the
+ user presses in the print dialog.
+
+ \sa collateCopiesEnabled() setCollateCopiesEnabled() collateCopies()
+*/
+
+void TQPrinter::setCollateCopies(bool on)
+{
+ if (!collateCopiesEnabled() && on)
+ setCollateCopiesEnabled(on);
+ usercolcopies = on;
+}
+
+/*!
+ Sets the number of copies to be printed to \a numCopies.
+
+ The printer driver reads this setting and prints the specified
+ number of copies.
+
+ \sa numCopies(), setup()
+*/
+
+void TQPrinter::setNumCopies( int numCopies )
+{
+ ncopies = numCopies;
+#if defined(TQ_WS_WIN)
+ reinit();
+#endif
+}
+
+
+/*!
+ Returns the printer options selection string. This is useful only
+ if the print command has been explicitly set.
+
+ The default value (a null string) implies that the printer should
+ be selected in a system-dependent manner.
+
+ Any other value implies that the given value should be used.
+
+ \sa setPrinterSelectionOption()
+*/
+
+TQString TQPrinter::printerSelectionOption() const
+{
+ return option_string;
+}
+
+
+/*!
+ Sets the printer to use \a option to select the printer. \a option
+ is null by default (which implies that TQt should be smart enough
+ to guess correctly), but it can be set to other values to use a
+ specific printer selection option.
+
+ If the printer selection option is changed while the printer is
+ active, the current print job may or may not be affected.
+
+ \sa printerSelectionOption()
+*/
+
+void TQPrinter::setPrinterSelectionOption( const TQString & option )
+{
+ option_string = option;
+}
+
+
+/*!
+ Sets TQPrinter to have the origin of the coordinate system at the
+ top-left corner of the paper if \a fp is TRUE, or where it thinks
+ the top-left corner of the printable area is if \a fp is FALSE.
+
+ The default is FALSE. You can (probably) print on (0,0), and
+ TQPaintDeviceMetrics will report something smaller than the size
+ indicated by PageSize. (Note that TQPrinter may be wrong on Unix
+ systems - it does not have perfect knowledge of the physical
+ printer.)
+
+ If you set \a fp to TRUE, TQPaintDeviceMetrics will report the
+ exact same size as indicated by \c PageSize, but you cannot print
+ on all of that - you must take care of the output margins
+ yourself.
+
+ \sa PageSize setPageSize() TQPaintDeviceMetrics fullPage()
+*/
+
+void TQPrinter::setFullPage( bool fp )
+{
+ to_edge = fp;
+}
+
+
+/*!
+ Returns TRUE if the origin of the printer's coordinate system is
+ at the corner of the sheet and FALSE if it is at the edge of the
+ printable area.
+
+ See setFullPage() for details and caveats.
+
+ \sa setFullPage() PageSize TQPaintDeviceMetrics
+*/
+
+bool TQPrinter::fullPage() const
+{
+ return to_edge;
+}
+
+
+/*!
+ Requests that the printer prints at \a dpi or as near to \a dpi as
+ possible.
+
+ This setting affects the coordinate system as returned by, for
+ example, TQPaintDeviceMetrics and TQPainter::viewport().
+
+ The value depends on the \c PrintingMode used in the TQPrinter
+ constructor. By default, the dpi value of the screen is used.
+
+ This function must be called before setup() to have an effect on
+ all platforms.
+
+ \sa resolution() setPageSize()
+*/
+
+void TQPrinter::setResolution( int dpi )
+{
+ res = dpi;
+ res_set = TRUE;
+}
+
+
+/*!
+ Returns the current assumed resolution of the printer, as set by
+ setResolution() or by the printer subsystem.
+
+ \sa setResolution()
+*/
+
+int TQPrinter::resolution() const
+{
+ return res;
+}
+
+/*!
+ Sets the paper source setting to \a source.
+
+ Windows only! This option can be changed while printing and will
+ take effect from the next call to newPage()
+
+ \sa paperSource()
+*/
+
+void TQPrinter::setPaperSource( PaperSource source )
+{
+ paper_source = source;
+#if defined(TQ_WS_WIN)
+ reinit();
+#endif
+}
+
+/*!
+ Returns the currently set paper source of the printer.
+
+ \sa setPaperSource()
+*/
+
+TQPrinter::PaperSource TQPrinter::paperSource() const
+{
+ return paper_source;
+}
+
+/*!
+ Sets the default selected page range to be used when the print setup
+ dialog is opened to \a range. If the PageRange specified by \a range is
+ currently disabled the function does nothing.
+
+ \sa printRange()
+*/
+void TQPrinter::setPrintRange( PrintRange range )
+{
+ if( range != AllPages )
+ if( range == Selection
+ && !isOptionEnabled( PrintSelection ) )
+ setOptionEnabled( PrintSelection, TRUE );
+ else if( range == PageRange
+ && !isOptionEnabled( PrintPageRange ) )
+ setOptionEnabled( PrintPageRange, TRUE );
+ d->printRange = range;
+}
+
+/*!
+ Returns the PageRange of the TQPrinter. After the print setup dialog
+ has been opened, this function returns the value selected by the user.
+
+ \sa setPrintRange()
+*/
+TQPrinter::PrintRange TQPrinter::printRange() const
+{
+ return d->printRange;
+}
+
+/*!
+ Enables the printer option with the identifier \a option if \a
+ enable is TRUE, and disables option \a option if \a enable is FALSE.
+
+ \sa isOptionEnabled()
+*/
+void TQPrinter::setOptionEnabled( PrinterOption option, bool enable )
+{
+ if( enable ) {
+ d->printerOptions |= ( 1 << option );
+ if( ( option == PrintPageRange ) && min_pg==0 && max_pg==0 )
+ max_pg = 9999;
+ } else {
+ d->printerOptions &= ( ~( 1 << option ) );
+ }
+}
+
+/*!
+ Returns TRUE if the printer option with identifier \a option is enabled;
+ otherwise returns FALSE.
+
+ \sa setOptionEnabled()
+ */
+bool TQPrinter::isOptionEnabled( PrinterOption option )
+{
+ return d->printerOptions & ( 1 << option );
+}
+
+#endif // USE_QT4
+
+#endif // TQT_NO_PRINTER
+
diff --git a/tqtinterface/qt4/src/kernel/tqprinter.h b/tqtinterface/qt4/src/kernel/tqprinter.h
new file mode 100755
index 0000000..a719a95
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqprinter.h
@@ -0,0 +1,335 @@
+/**********************************************************************
+**
+** Definition of TQPrinter class
+**
+** Created : 940927
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPRINTER_H
+#define TQPRINTER_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqpaintdevice.h"
+#include "tqstring.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_PRINTER
+
+#ifdef USE_QT4
+
+#include <Qt/qprinter.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQPrinter : public QPrinter//, virtual public TQt
+{
+public:
+ enum PrinterOption { PrintToFile, PrintSelection, PrintPageRange };
+
+ TQPrinter( PrinterMode mode = ScreenResolution ) : QPrinter( mode ) {}
+
+#ifdef Q_WS_MAC
+ bool pageSetup(QWidget *parent = 0);
+ bool printSetup(QWidget *parent = 0);
+#endif
+
+ bool setup(QWidget *parent = 0);
+
+ void setMinMax(int minPage, int maxPage);
+ int minPage() const;
+ int maxPage() const;
+
+ void setCollateCopiesEnabled(bool);
+ bool collateCopiesEnabled() const;
+
+ void setOptionEnabled(PrinterOption, bool enable);
+ bool isOptionEnabled(PrinterOption) const;
+
+ inline TQSize margins() const { printf("[WARNING] TQPrinter::margins unimplemented\n\r"); }
+ inline void margins(uint *top, uint *left, uint *bottom, uint *right) const { printf("[WARNING] TQPrinter::margins unimplemented\n\r"); }
+
+ inline bool aborted() { return printerState() == Aborted; }
+
+ void setOutputToFile(bool);
+ inline bool outputToFile() const { return !outputFileName().isEmpty(); }
+
+protected:
+ bool cmd( int, TQPainter *, TQPDevCmdParam * );
+ inline int metric( int a ) const { return metric((QPaintDevice::PaintDeviceMetric)a); }
+ inline void setMargins( uint top, uint left, uint bottom, uint right ) { printf("[WARNING] TQPrinter::setMargins unimplemented\n\r"); }
+};
+
+#else // USE_QT4
+
+#if defined(B0)
+#undef B0 // Terminal hang-up. We assume that you do not want that.
+#endif
+
+class TQPrinterPrivate;
+
+class TQ_EXPORT TQPrinter : public TQPaintDevice
+{
+public:
+ enum PrinterMode { ScreenResolution, PrinterResolution, HighResolution, Compatible };
+
+ TQPrinter( PrinterMode mode = ScreenResolution );
+ ~TQPrinter();
+
+ enum Orientation { Portrait, Landscape };
+
+ enum PageSize { A4, B5, Letter, Legal, Executive,
+ A0, A1, A2, A3, A5, A6, A7, A8, A9, B0, B1,
+ B10, B2, B3, B4, B6, B7, B8, B9, C5E, Comm10E,
+ DLE, Folio, Ledger, Tabloid, Custom, NPageSize = Custom };
+
+ enum PageOrder { FirstPageFirst, LastPageFirst };
+
+ enum ColorMode { GrayScale, Color };
+
+ enum PaperSource { OnlyOne, Lower, Middle, Manual, Envelope,
+ EnvelopeManual, Auto, Tractor, SmallFormat,
+ LargeFormat, LargeCapacity, Cassette, FormSource };
+
+ enum PrintRange { AllPages,
+ Selection,
+ PageRange };
+
+ enum PrinterOption { PrintToFile,
+ PrintSelection,
+ PrintPageRange };
+
+ TQString printerName() const;
+ virtual void setPrinterName( const TQString &);
+ bool outputToFile() const;
+ virtual void setOutputToFile( bool );
+ TQString outputFileName()const;
+ virtual void setOutputFileName( const TQString &);
+
+ TQString printProgram() const;
+ virtual void setPrintProgram( const TQString &);
+
+ TQString printerSelectionOption() const;
+ virtual void setPrinterSelectionOption( const TQString & );
+
+ TQString docName() const;
+ virtual void setDocName( const TQString &);
+ TQString creator() const;
+ virtual void setCreator( const TQString &);
+
+ Orientation orientation() const;
+ virtual void setOrientation( Orientation );
+ PageSize pageSize() const;
+ virtual void setPageSize( PageSize );
+#ifdef TQ_WS_WIN
+ void setWinPageSize( short winPageSize );
+ short winPageSize() const;
+#endif
+#ifdef TQ_WS_MAC
+ bool printSetup();
+ bool pageSetup();
+#endif
+ virtual void setPageOrder( PageOrder );
+ PageOrder pageOrder() const;
+
+ void setResolution( int );
+ int resolution() const;
+
+ virtual void setColorMode( ColorMode );
+ ColorMode colorMode() const;
+
+ virtual void setFullPage( bool );
+ bool fullPage() const;
+ TQSize margins() const;
+ void setMargins( uint top, uint left, uint bottom, uint right );
+ void margins( uint *top, uint *left, uint *bottom, uint *right ) const;
+
+ int fromPage() const;
+ int toPage() const;
+ virtual void setFromTo( int fromPage, int toPage );
+ int minPage() const;
+ int maxPage() const;
+ virtual void setMinMax( int minPage, int maxPage );
+ int numCopies() const;
+ virtual void setNumCopies( int );
+
+ bool collateCopiesEnabled() const;
+ void setCollateCopiesEnabled(bool );
+
+ bool collateCopies() const;
+ void setCollateCopies( bool );
+
+ PrintRange printRange() const;
+ void setPrintRange( PrintRange range );
+
+ bool newPage();
+ bool abort();
+ bool aborted() const;
+
+ bool setup( TQWidget *tqparent = 0 );
+
+ PaperSource paperSource() const;
+ virtual void setPaperSource( PaperSource );
+
+ void setOptionEnabled( PrinterOption, bool enable );
+ bool isOptionEnabled( PrinterOption );
+
+protected:
+ bool cmd( int, TQPainter *, TQPDevCmdParam * );
+ int metric( int ) const;
+
+#if defined(TQ_WS_WIN)
+ virtual void setActive();
+ virtual void setIdle();
+#endif
+
+private:
+#if defined(TQ_WS_X11) || defined(TQ_WS_TQWS)
+ TQPaintDevice *pdrv;
+ int pid;
+#endif
+#if defined(TQ_WS_MAC)
+ friend class TQPrinterPrivate;
+ PMPageFormat pformat;
+ PMPrintSettings psettings;
+ PMPrintSession psession;
+ bool prepare(PMPrintSettings *);
+ bool prepare(PMPageFormat *);
+ void interpret(PMPrintSettings *);
+ void interpret(PMPageFormat *);
+#endif
+#if defined(TQ_WS_WIN)
+ void readPdlg( void* );
+ void readPdlgA( void* );
+ void writeDevmode( TQt::HANDLE );
+ void writeDevmodeA( TQt::HANDLE );
+ void reinit();
+
+ bool viewOffsetDone;
+ TQPainter* painter;
+ TQt::HANDLE hdevmode;
+ TQt::HANDLE hdevnames;
+#endif
+
+ int state;
+ TQString printer_name;
+ TQString option_string;
+ TQString output_filename;
+ bool output_file;
+ TQString print_prog;
+ TQString doc_name;
+ TQString creator_name;
+
+ PageSize page_size;
+ PaperSource paper_source;
+ PageOrder page_order;
+ ColorMode color_mode;
+ Orientation orient;
+ uint to_edge : 1;
+ uint appcolcopies : 1;
+ uint usercolcopies : 1;
+ uint res_set : 1;
+ short from_pg, to_pg;
+ short min_pg, max_pg;
+ short ncopies;
+ int res;
+ TQPrinterPrivate *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQPrinter( const TQPrinter & );
+ TQPrinter &operator=( const TQPrinter & );
+#endif
+};
+
+
+inline TQString TQPrinter::printerName() const
+{ return printer_name; }
+
+inline bool TQPrinter::outputToFile() const
+{ return output_file; }
+
+inline TQString TQPrinter::outputFileName() const
+{ return output_filename; }
+
+inline TQString TQPrinter::printProgram() const
+{ return print_prog; }
+
+inline TQString TQPrinter::docName() const
+{ return doc_name; }
+
+inline TQString TQPrinter::creator() const
+{ return creator_name; }
+
+inline TQPrinter::PageSize TQPrinter::pageSize() const
+{ return page_size; }
+
+inline TQPrinter::Orientation TQPrinter::orientation() const
+{ return orient; }
+
+inline int TQPrinter::fromPage() const
+{ return from_pg; }
+
+inline int TQPrinter::toPage() const
+{ return to_pg; }
+
+inline int TQPrinter::minPage() const
+{ return min_pg; }
+
+inline int TQPrinter::maxPage() const
+{ return max_pg; }
+
+inline int TQPrinter::numCopies() const
+{ return ncopies; }
+
+inline bool TQPrinter::collateCopiesEnabled() const
+{ return appcolcopies; }
+
+inline void TQPrinter::setCollateCopiesEnabled(bool v)
+{ appcolcopies = v; }
+
+inline bool TQPrinter::collateCopies() const
+{ return usercolcopies; }
+
+#endif // USE_QT4
+
+#endif // TQT_NO_PRINTER
+
+#endif // TQPRINTER_H
diff --git a/tqtinterface/qt4/src/kernel/tqprinter_p.h b/tqtinterface/qt4/src/kernel/tqprinter_p.h
new file mode 100644
index 0000000..4638252
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqprinter_p.h
@@ -0,0 +1,59 @@
+/**********************************************************************
+**
+** Definition of TQPrinter class
+**
+** Created : 940927
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPRINTER_P_H
+#define TQPRINTER_P_H
+#ifndef TQT_NO_PRINTER
+
+#ifndef TQT_H
+#include <tqshared.h>
+#include <tqstring.h>
+#include <tqsize.h>
+#endif // TQT_H
+
+class TQPrinterPrivate
+{
+public:
+ TQ_UINT32 printerOptions;
+ TQPrinter::PrintRange printRange;
+};
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqprinter_unix.cpp b/tqtinterface/qt4/src/kernel/tqprinter_unix.cpp
new file mode 100644
index 0000000..f9ff932
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqprinter_unix.cpp
@@ -0,0 +1,853 @@
+/****************************************************************************
+**
+** Implementation of TQPrinter class for Unix
+**
+** Created : 950810
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// POSIX Large File Support redefines open -> open64
+static inline int qt_open(const char *pathname, int flags, mode_t mode)
+{ return ::open(pathname, flags, mode); }
+#if defined(open)
+# undef open
+#endif
+
+#include "tqprinter.h"
+
+#ifndef TQT_NO_PRINTER
+
+#include "tqpaintdevicemetrics.h"
+#include "tqpsprinter_p.h"
+#include "tqprintdialog.h"
+#include "tqapplication.h"
+#include "tqprinter_p.h"
+
+#include <unistd.h> // For ::sleep()
+#include <stdlib.h>
+
+#ifdef USE_QT4
+
+/*!
+ \internal
+ Handles painter commands to the printer.
+*/
+
+bool TQPrinter::cmd( int c, TQPainter *paint, TQPDevCmdParam *p )
+{
+ #warning FIXME [TQPrinter::cmd]
+ // [FIXME]
+ printf("[WARNING] TQPrinter::cmd unimplemented\n\r");
+
+// if ( c == PdcBegin ) {
+// if ( state == PST_IDLE ) {
+// if ( output_file ) {
+// int fd = 0;
+// fd = qt_open( output_filename.local8Bit(),
+// O_CREAT | O_NOCTTY | O_TRUNC | O_WRONLY,
+// 0666 );
+// if ( fd >= 0 ) {
+// pdrv = new TQPSPrinter( this, fd );
+// state = PST_ACTIVE;
+// }
+// } else {
+// TQString pr;
+// if ( printer_name )
+// pr = printer_name;
+// TQApplication::flushX();
+// int fds[2];
+// if ( pipe( fds ) != 0 ) {
+// qWarning( "TQPSPrinter: could not open pipe to print" );
+// state = PST_ERROR;
+// return FALSE;
+// }
+//
+// // ### shouldn't we use TQProcess here????
+// #if 0 && defined(TQ_OS_OS2EMX)
+// // this code is still not used, and maybe it's not
+// // usable either, any more. if you want to use it,
+// // you may need to fix it first.
+//
+// // old comment:
+//
+// // this code is usable but not in use. spawn() is
+// // preferable to fork()/exec() for very large
+// // programs. if fork()/exec() is a problem and you
+// // use OS/2, remove '0 && ' from the #if.
+// int tmp;
+// tmp = dup(0);
+// dup2( fds[0], 0 );
+// ::close( fds[0] );
+// fcntl(tmp, F_SETFD, FD_CLOEXEC);
+// fcntl(fds[1], F_SETFD, FD_CLOEXEC);
+// if ( option_string )
+// pr.prepend( option_string );
+// else
+// pr.prepend( "-P" ); // ###
+// if ( spawnlp(P_NOWAIT,print_prog.data(), print_prog.data(),
+// pr.data(), output->name(), 0) == -1 ) {
+// ; // couldn't exec, ignored
+// }
+// dup2( tmp, 0 );
+// ::close( tmp );
+// pdrv = new TQPSPrinter( this, fds[1] );
+// state = PST_ACTIVE;
+// #else
+// pid = fork();
+// if ( pid == 0 ) { // child process
+// // if possible, exit quickly, so the actual lp/lpr
+// // becomes a child of init, and ::waitpid() is
+// // guaranteed not to wait.
+// if ( fork() > 0 ) {
+// closeAllOpenFds();
+//
+// // try to tqreplace this process with "true" - this prevents
+// // global destructors from being called (that could possibly
+// // do wrong things to the tqparent process)
+// (void)execlp("true", "true", (char *)0);
+// (void)execl("/bin/true", "true", (char *)0);
+// (void)execl("/usr/bin/true", "true", (char *)0);
+// ::exit( 0 );
+// }
+// dup2( fds[0], 0 );
+//
+// closeAllOpenFds();
+//
+// if ( print_prog ) {
+// if ( option_string )
+// pr.prepend( option_string );
+// else
+// pr.prepend( TQString::tqfromLatin1( "-P" ) );
+// (void)execlp( print_prog.ascii(), print_prog.ascii(),
+// pr.ascii(), (char *)0 );
+// } else {
+// // if no print program has been specified, be smart
+// // about the option string too.
+// TQStringList lprhack;
+// TQStringList lphack;
+// TQString media;
+// if ( pr || option_string ) {
+// if ( option_string ) {
+// lprhack = TQStringList::split(TQChar(' '), option_string);
+// lphack = lprhack;
+// } else {
+// lprhack.append( TQString::tqfromLatin1( "-P" ) );
+// lphack.append( TQString::tqfromLatin1( "-d" ) );
+// }
+// lprhack.append(pr);
+// lphack.append(pr);
+// }
+// char ** lpargs = new char *[lphack.size()+6];
+// lpargs[0] = "lp";
+// uint i;
+// for (i = 0; i < lphack.size(); ++i)
+// lpargs[i+1] = (char *)lphack[i].ascii();
+// #ifndef TQ_OS_OSF
+// if (psToStr[page_size]) {
+// lpargs[++i] = "-o";
+// lpargs[++i] = (char *)psToStr[page_size];
+// lpargs[++i] = "-o";
+// media = "media=";
+// media += psToStr[page_size];
+// lpargs[++i] = (char *)media.ascii();
+// }
+// #endif
+// lpargs[++i] = 0;
+// char **lprargs = new char *[lprhack.size()+1];
+// lprargs[0] = "lpr";
+// for (uint x = 0; x < lprhack.size(); ++x)
+// lprargs[x+1] = (char *)lprhack[x].ascii();
+// lprargs[lprhack.size() + 1] = 0;
+// (void)execvp( "lp", lpargs );
+// (void)execvp( "lpr", lprargs );
+// (void)execv( "/bin/lp", lpargs);
+// (void)execv( "/bin/lpr", lprargs);
+// (void)execv( "/usr/bin/lp", lpargs);
+// (void)execv( "/usr/bin/lpr", lprargs);
+// }
+// // if we couldn't exec anything, close the fd,
+// // wait for a second so the tqparent process (the
+// // child of the GUI process) has exited. then
+// // exit.
+// ::close( 0 );
+// (void)::sleep( 1 );
+// ::exit( 0 );
+// } else { // tqparent process
+// ::close( fds[0] );
+// pdrv = new TQPSPrinter( this, fds[1] );
+// state = PST_ACTIVE;
+// }
+// #endif // else part of TQ_OS_OS2EMX
+// }
+// if ( state == PST_ACTIVE && pdrv )
+// return ((TQPSPrinter*)pdrv)->cmd( c, paint, p );
+// } else {
+// // ignore it? I don't know
+// }
+// } else {
+// bool r = FALSE;
+// if ( state == PST_ACTIVE && pdrv ) {
+// r = ((TQPSPrinter*)pdrv)->cmd( c, paint, p );
+// if ( c == PdcEnd ) {
+// state = PST_IDLE;
+// delete pdrv;
+// pdrv = 0;
+// if ( pid ) {
+// (void)::waitpid( pid, 0, 0 );
+// pid = 0;
+// }
+// }
+// } else if ( state == PST_ABORTED && c == PdcEnd )
+// state = PST_IDLE;
+// return r;
+// }
+// return TRUE;
+}
+
+#else // USE_QT4
+
+// NOT REVISED
+
+
+class TQPrinterUnixPrivate : public TQPrinterPrivate
+{
+public:
+ bool marginsSpecified;
+ uint topMargin;
+ uint leftMargin;
+ uint bottomMargin;
+ uint rightMargin;
+};
+
+#define D ( (TQPrinterUnixPrivate*) d )
+
+/*****************************************************************************
+ TQPrinter member functions
+ *****************************************************************************/
+
+// TQPrinter states
+
+#define PST_IDLE 0
+#define PST_ACTIVE 1
+#define PST_ERROR 2
+#define PST_ABORTED 3
+
+// Default values for TQPrinter members
+
+struct PrinterDefaults {
+ TQString printerName;
+ bool outputToFile;
+ TQString outputFileName;
+ TQPrinter::Orientation orientation;
+ TQPrinter::PageSize pageSize;
+ TQPrinter::PageOrder pageOrder;
+ TQPrinter::ColorMode colorMode;
+ int numCopies;
+};
+
+static PrinterDefaults * globalPrinterDefaults = 0;
+
+/*!
+ Constructs a printer paint tqdevice with mode \a m.
+
+ \sa TQPrinter::PrinterMode
+*/
+
+TQPrinter::TQPrinter( PrinterMode m )
+ : TQPaintDevice( TQInternal::Printer | TQInternal::ExternalDevice )
+{
+ pdrv = 0;
+ pid = 0;
+ orient = Portrait;
+ page_size = A4;
+ page_order = FirstPageFirst;
+ color_mode = GrayScale;
+ ncopies = 1;
+ printer_name = getenv("PRINTER");
+ from_pg = to_pg = min_pg = max_pg = 0;
+ state = PST_IDLE;
+ output_file = FALSE;
+ to_edge = FALSE;
+ paper_source = OnlyOne;
+ switch ( m ) {
+ case ScreenResolution:
+#ifdef TQ_WS_TQWS
+ res = 72;
+#else
+ res = TQPaintDevice::x11AppDpiY();
+#endif
+ break;
+ case Compatible:
+ case PrinterResolution:
+ res = 72;
+ break;
+ case HighResolution:
+ res = 600;
+ }
+
+ d = new TQPrinterUnixPrivate;
+ D->marginsSpecified = FALSE;
+ d->printerOptions = 0;
+ setOptionEnabled( PrintToFile, TRUE );
+ setOptionEnabled( PrintPageRange, TRUE );
+ setPrintRange( AllPages );
+}
+
+/*!
+ Destroys the printer paint tqdevice and cleans up.
+*/
+
+TQPrinter::~TQPrinter()
+{
+ delete pdrv;
+ if ( pid ) {
+ (void)::kill( pid, 6 );
+ (void)::wait( 0 );
+ pid = 0;
+ }
+ delete d;
+}
+
+
+/*!
+ Advances to a new page on the printer. Returns TRUE if successful;
+ otherwise returns FALSE.
+*/
+
+bool TQPrinter::newPage()
+{
+ if ( state == PST_ACTIVE && pdrv )
+ return ((TQPSPrinter*)pdrv)->cmd( TQPSPrinter::NewPage, 0, 0 );
+ return FALSE;
+}
+
+
+/*!
+ Aborts the print job. Returns TRUE if successful; otherwise
+ returns FALSE.
+
+ \sa aborted()
+*/
+
+bool TQPrinter::abort()
+{
+ if ( state == PST_ACTIVE && pdrv ) {
+ ((TQPSPrinter*)pdrv)->cmd( TQPSPrinter::AbortPrinting, 0, 0 );
+ state = PST_ABORTED;
+ if ( pid ) {
+ (void)::kill( pid, 6 );
+ (void)::wait( 0 );
+ pid = 0;
+ }
+ }
+ return state == PST_ABORTED;
+}
+
+/*!
+ Returns TRUE if the print job was aborted; otherwise returns
+ FALSE.
+
+ \sa abort()
+*/
+
+bool TQPrinter::aborted() const
+{
+ return state == PST_ABORTED;
+}
+
+/*!
+ Sets the printer name to \a name.
+
+ The default printer will be used if no printer name is set.
+
+ Under X11, the \c PRINTER environment variable defines the default
+ printer. Under any other window system, the window system defines
+ the default printer.
+
+ \sa printerName()
+*/
+
+void TQPrinter::setPrinterName( const TQString &name )
+{
+ if ( state != 0 ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQPrinter::setPrinterName: Cannot do this during printing" );
+#endif
+ return;
+ }
+ printer_name = name;
+}
+
+static void deleteGlobalPrinterDefaults()
+{
+ delete globalPrinterDefaults;
+ globalPrinterDefaults = 0;
+}
+
+/*!
+ Opens a printer setup dialog, with tqparent \a tqparent, and asks the
+ user to specify which printer they wish to use and what settings
+ it should have.
+
+ Returns TRUE if the user pressed "OK" to print, or FALSE if the
+ user canceled the operation.
+*/
+
+bool TQPrinter::setup( TQWidget * tqparent )
+{
+#ifndef TQT_NO_PRINTDIALOG
+ bool result = TQPrintDialog::getPrinterSetup( this, tqparent );
+#else
+ bool result = FALSE;
+#endif
+ if ( result ) {
+ if ( !globalPrinterDefaults ) {
+ globalPrinterDefaults = new PrinterDefaults;
+ qAddPostRoutine( deleteGlobalPrinterDefaults );
+ }
+ globalPrinterDefaults->printerName = printerName();
+ globalPrinterDefaults->outputToFile = outputToFile();
+ globalPrinterDefaults->outputFileName = outputFileName();
+ globalPrinterDefaults->orientation = orientation();
+ globalPrinterDefaults->pageSize = pageSize();
+ globalPrinterDefaults->pageOrder = pageOrder();
+ globalPrinterDefaults->colorMode = colorMode();
+ }
+ return result;
+}
+
+static void closeAllOpenFds()
+{
+ // hack time... getting the maximum number of open
+ // files, if possible. if not we assume it's the
+ // larger of 256 and the fd we got
+ int i;
+#if defined(TQ_OS_OS2EMX)
+ LONG req_count = 0;
+ ULONG rc, handle_count;
+ rc = DosSetRelMaxFH (&req_count, &handle_count);
+ /* if (rc != NO_ERROR) ... */
+ i = (int)handle_count;
+#elif defined(_SC_OPEN_MAX)
+ i = (int)sysconf( _SC_OPEN_MAX );
+#elif defined(_POSIX_OPEN_MAX)
+ i = (int)_POSIX_OPEN_MAX;
+#elif defined(OPEN_MAX)
+ i = (int)OPEN_MAX;
+#else
+ i = TQMAX( 256, fds[0] );
+#endif // TQ_OS_OS2EMX // ways-to-set i
+ while( --i > 0 )
+ ::close( i );
+}
+
+
+
+static const char * const psToStr[TQPrinter::NPageSize+1] =
+{ "A4", "B5", "Letter", "Legal", "Executive",
+ "A0", "A1", "A2", "A3", "A5", "A6", "A7", "A8", "A9", "B0", "B1",
+ "B10", "B2", "B3", "B4", "B6", "B7", "B8", "B9", "C5E", "Comm10E",
+ "DLE", "Folio", "Ledger", "Tabloid", 0
+};
+
+
+/*!
+ \internal
+ Handles painter commands to the printer.
+*/
+
+bool TQPrinter::cmd( int c, TQPainter *paint, TQPDevCmdParam *p )
+{
+ if ( c == PdcBegin ) {
+ if ( state == PST_IDLE ) {
+ if ( output_file ) {
+ int fd = 0;
+ fd = qt_open( output_filename.local8Bit(),
+ O_CREAT | O_NOCTTY | O_TRUNC | O_WRONLY,
+ 0666 );
+ if ( fd >= 0 ) {
+ pdrv = new TQPSPrinter( this, fd );
+ state = PST_ACTIVE;
+ }
+ } else {
+ TQString pr;
+ if ( printer_name )
+ pr = printer_name;
+ TQApplication::flushX();
+ int fds[2];
+ if ( pipe( fds ) != 0 ) {
+ qWarning( "TQPSPrinter: could not open pipe to print" );
+ state = PST_ERROR;
+ return FALSE;
+ }
+
+// ### shouldn't we use TQProcess here????
+#if 0 && defined(TQ_OS_OS2EMX)
+ // this code is still not used, and maybe it's not
+ // usable either, any more. if you want to use it,
+ // you may need to fix it first.
+
+ // old comment:
+
+ // this code is usable but not in use. spawn() is
+ // preferable to fork()/exec() for very large
+ // programs. if fork()/exec() is a problem and you
+ // use OS/2, remove '0 && ' from the #if.
+ int tmp;
+ tmp = dup(0);
+ dup2( fds[0], 0 );
+ ::close( fds[0] );
+ fcntl(tmp, F_SETFD, FD_CLOEXEC);
+ fcntl(fds[1], F_SETFD, FD_CLOEXEC);
+ if ( option_string )
+ pr.prepend( option_string );
+ else
+ pr.prepend( "-P" ); // ###
+ if ( spawnlp(P_NOWAIT,print_prog.data(), print_prog.data(),
+ pr.data(), output->name(), 0) == -1 ) {
+ ; // couldn't exec, ignored
+ }
+ dup2( tmp, 0 );
+ ::close( tmp );
+ pdrv = new TQPSPrinter( this, fds[1] );
+ state = PST_ACTIVE;
+#else
+ pid = fork();
+ if ( pid == 0 ) { // child process
+ // if possible, exit quickly, so the actual lp/lpr
+ // becomes a child of init, and ::waitpid() is
+ // guaranteed not to wait.
+ if ( fork() > 0 ) {
+ closeAllOpenFds();
+
+ // try to tqreplace this process with "true" - this prevents
+ // global destructors from being called (that could possibly
+ // do wrong things to the tqparent process)
+ (void)execlp("true", "true", (char *)0);
+ (void)execl("/bin/true", "true", (char *)0);
+ (void)execl("/usr/bin/true", "true", (char *)0);
+ ::exit( 0 );
+ }
+ dup2( fds[0], 0 );
+
+ closeAllOpenFds();
+
+ if ( print_prog ) {
+ if ( option_string )
+ pr.prepend( option_string );
+ else
+ pr.prepend( TQString::tqfromLatin1( "-P" ) );
+ (void)execlp( print_prog.ascii(), print_prog.ascii(),
+ pr.ascii(), (char *)0 );
+ } else {
+ // if no print program has been specified, be smart
+ // about the option string too.
+ TQStringList lprhack;
+ TQStringList lphack;
+ TQString media;
+ if ( pr || option_string ) {
+ if ( option_string ) {
+ lprhack = TQStringList::split(TQChar(' '), option_string);
+ lphack = lprhack;
+ } else {
+ lprhack.append( TQString::tqfromLatin1( "-P" ) );
+ lphack.append( TQString::tqfromLatin1( "-d" ) );
+ }
+ lprhack.append(pr);
+ lphack.append(pr);
+ }
+ char ** lpargs = new char *[lphack.size()+6];
+ lpargs[0] = "lp";
+ uint i;
+ for (i = 0; i < lphack.size(); ++i)
+ lpargs[i+1] = (char *)lphack[i].ascii();
+#ifndef TQ_OS_OSF
+ if (psToStr[page_size]) {
+ lpargs[++i] = "-o";
+ lpargs[++i] = (char *)psToStr[page_size];
+ lpargs[++i] = "-o";
+ media = "media=";
+ media += psToStr[page_size];
+ lpargs[++i] = (char *)media.ascii();
+ }
+#endif
+ lpargs[++i] = 0;
+ char **lprargs = new char *[lprhack.size()+1];
+ lprargs[0] = "lpr";
+ for (uint x = 0; x < lprhack.size(); ++x)
+ lprargs[x+1] = (char *)lprhack[x].ascii();
+ lprargs[lprhack.size() + 1] = 0;
+ (void)execvp( "lp", lpargs );
+ (void)execvp( "lpr", lprargs );
+ (void)execv( "/bin/lp", lpargs);
+ (void)execv( "/bin/lpr", lprargs);
+ (void)execv( "/usr/bin/lp", lpargs);
+ (void)execv( "/usr/bin/lpr", lprargs);
+ }
+ // if we couldn't exec anything, close the fd,
+ // wait for a second so the tqparent process (the
+ // child of the GUI process) has exited. then
+ // exit.
+ ::close( 0 );
+ (void)::sleep( 1 );
+ ::exit( 0 );
+ } else { // tqparent process
+ ::close( fds[0] );
+ pdrv = new TQPSPrinter( this, fds[1] );
+ state = PST_ACTIVE;
+ }
+#endif // else part of TQ_OS_OS2EMX
+ }
+ if ( state == PST_ACTIVE && pdrv )
+ return ((TQPSPrinter*)pdrv)->cmd( c, paint, p );
+ } else {
+ // ignore it? I don't know
+ }
+ } else {
+ bool r = FALSE;
+ if ( state == PST_ACTIVE && pdrv ) {
+ r = ((TQPSPrinter*)pdrv)->cmd( c, paint, p );
+ if ( c == PdcEnd ) {
+ state = PST_IDLE;
+ delete pdrv;
+ pdrv = 0;
+ if ( pid ) {
+ (void)::waitpid( pid, 0, 0 );
+ pid = 0;
+ }
+ }
+ } else if ( state == PST_ABORTED && c == PdcEnd )
+ state = PST_IDLE;
+ return r;
+ }
+ return TRUE;
+}
+
+
+#define MM(n) int((n * 720 + 127) / 254)
+#define IN(n) int(n * 72)
+
+struct PaperSize {
+ int width, height;
+};
+
+static const PaperSize paperSizes[TQPrinter::NPageSize] =
+{
+ { MM(210), MM(297) }, // A4
+ { MM(176), MM(250) }, // B5
+ { IN(8.5), IN(11) }, // Letter
+ { IN(8.5), IN(14) }, // Legal
+ { IN(7.5), IN(10) }, // Executive
+ { MM(841), MM(1189) }, // A0
+ { MM(594), MM(841) }, // A1
+ { MM(420), MM(594) }, // A2
+ { MM(297), MM(420) }, // A3
+ { MM(148), MM(210) }, // A5
+ { MM(105), MM(148) }, // A6
+ { MM(74), MM(105)}, // A7
+ { MM(52), MM(74) }, // A8
+ { MM(37), MM(52) }, // A9
+ { MM(1000), MM(1414) }, // B0
+ { MM(707), MM(1000) }, // B1
+ { MM(31), MM(44) }, // B10
+ { MM(500), MM(707) }, // B2
+ { MM(353), MM(500) }, // B3
+ { MM(250), MM(353) }, // B4
+ { MM(125), MM(176) }, // B6
+ { MM(88), MM(125) }, // B7
+ { MM(62), MM(88) }, // B8
+ { MM(44), MM(62) }, // B9
+ { MM(162), MM(229) }, // C5E
+ { IN(4.125), IN(9.5) }, // Comm10E
+ { MM(110), MM(220) }, // DLE
+ { IN(8.5), IN(13) }, // Folio
+ { IN(17), IN(11) }, // Ledger
+ { IN(11), IN(17) } // Tabloid
+};
+
+/*!
+ Internal implementation of the virtual TQPaintDevice::metric() function.
+
+ Use the TQPaintDeviceMetrics class instead.
+
+ \internal
+ Hard coded return values for PostScript under X.
+*/
+
+int TQPrinter::metric( int m ) const
+{
+ int val;
+ PageSize s = pageSize();
+#if defined(TQT_CHECK_RANGE)
+ TQ_ASSERT( (uint)s < (uint)NPageSize );
+#endif
+ switch ( m ) {
+ case TQPaintDeviceMetrics::PdmWidth:
+ val = orient == Portrait ? paperSizes[s].width : paperSizes[s].height;
+ if ( res != 72 )
+ val = (val * res + 36) / 72;
+ if ( !fullPage() ) {
+ if ( D->marginsSpecified )
+ val -= D->leftMargin + D->rightMargin;
+ else
+ val -= 2*margins().width();
+ }
+ break;
+ case TQPaintDeviceMetrics::PdmHeight:
+ val = orient == Portrait ? paperSizes[s].height : paperSizes[s].width;
+ if ( res != 72 )
+ val = (val * res + 36) / 72;
+ if ( !fullPage() ) {
+ if ( D->marginsSpecified )
+ val -= D->topMargin + D->bottomMargin;
+ else
+ val -= 2*margins().height();
+ }
+ break;
+ case TQPaintDeviceMetrics::PdmDpiX:
+ val = res;
+ break;
+ case TQPaintDeviceMetrics::PdmDpiY:
+ val = res;
+ break;
+ case TQPaintDeviceMetrics::PdmPhysicalDpiX:
+ case TQPaintDeviceMetrics::PdmPhysicalDpiY:
+ val = 72;
+ break;
+ case TQPaintDeviceMetrics::PdmWidthMM:
+ // double rounding error here. hooray.
+ val = metric( TQPaintDeviceMetrics::PdmWidth );
+ val = (val * 254 + 5*res) / (10*res);
+ break;
+ case TQPaintDeviceMetrics::PdmHeightMM:
+ val = metric( TQPaintDeviceMetrics::PdmHeight );
+ val = (val * 254 + 5*res) / (10*res);
+ break;
+ case TQPaintDeviceMetrics::PdmNumColors:
+ val = 16777216;
+ break;
+ case TQPaintDeviceMetrics::PdmDepth:
+ val = 24;
+ break;
+ default:
+ val = 0;
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQPixmap::metric: Invalid metric command" );
+#endif
+ }
+ return val;
+}
+
+
+/*!
+ Returns the width of the left margin and the height of the top
+ margin of the printer. On Unix, this is a best-effort guess, not
+ based on perfect knowledge.
+
+ If you have called setFullPage( TRUE ), margins().width() may be
+ treated as the smallest sane left margin you can use, and
+ margins().height() as the smallest sane top margin you can
+ use.
+
+ If you have called setFullPage( FALSE ) (this is the default),
+ margins() is automatically subtracted from the pageSize() by
+ TQPrinter.
+
+ \sa setFullPage() TQPaintDeviceMetrics PageSize
+*/
+TQSize TQPrinter::margins() const
+{
+ if ( D->marginsSpecified )
+ return TQSize( D->leftMargin, D->topMargin );
+
+ if (orient == Portrait)
+ return TQSize( res/2, res/3 );
+
+ return TQSize( res/3, res/2 );
+}
+
+/*!
+ \overload
+
+ Sets \a top, \a left, \a bottom and \a right to the margins of the
+ printer. On Unix, this is a best-effort guess, not based on
+ perfect knowledge.
+
+ If you have called setFullPage( TRUE ), the four values specify
+ the smallest sane margins you can use.
+
+ If you have called setFullPage( FALSE ) (this is the default),
+ the margins are automatically subtracted from the pageSize() by
+ TQPrinter.
+
+ \sa setFullPage() TQPaintDeviceMetrics PageSize
+*/
+void TQPrinter::margins( uint *top, uint *left, uint *bottom, uint *right ) const
+{
+ if ( !D->marginsSpecified ) {
+ int x = orient == Portrait ? res/2 : res/3;
+ int y = orient == Portrait ? res/3 : res/2;
+ *top = *bottom = y;
+ *left = *right = x;
+ } else {
+ *top = D->topMargin;
+ *left = D->leftMargin;
+ *bottom = D->bottomMargin;
+ *right = D->rightMargin;
+ }
+}
+
+/*!
+ Sets the printer margins to the sizes specified in \a top, \a left,
+ \a bottom and \a right.
+
+ This function currently only has an effect on Unix systems.
+
+ \sa margins()
+*/
+void TQPrinter::setMargins( uint top, uint left, uint bottom, uint right )
+{
+ D->topMargin = top;
+ D->leftMargin = left;
+ D->bottomMargin = bottom;
+ D->rightMargin = right;
+ D->marginsSpecified = TRUE;
+}
+
+#endif // USE_QT4
+
+#endif \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqprocess.cpp b/tqtinterface/qt4/src/kernel/tqprocess.cpp
new file mode 100644
index 0000000..a809996
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqprocess.cpp
@@ -0,0 +1,806 @@
+/****************************************************************************
+**
+** Implementation of TQProcess class
+**
+** Created : 20000905
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "tqprocess.h"
+
+#ifndef TQT_NO_PROCESS
+
+#include "tqapplication.h"
+#include "private/tqinternal_p.h"
+
+
+//#define TQT_TQPROCESS_DEBUG
+
+
+/*!
+ \class TQProcess tqprocess.h
+
+ \brief The TQProcess class is used to start external programs and
+ to communicate with them.
+
+ \ingroup io
+ \ingroup misc
+ \mainclass
+
+ You can write to the started program's standard input, and can
+ read the program's standard output and standard error. You can
+ pass command line arguments to the program either in the
+ constructor or with setArguments() or addArgument(). The program's
+ working directory can be set with setWorkingDirectory(). If you
+ need to set up environment variables pass them to the start() or
+ launch() functions (see below). The processExited() signal is
+ emitted if the program exits. The program's exit status is
+ available from exitqStatus(), although you could simply call
+ normalExit() to see if the program terminated normally.
+
+ There are two different ways to start a process. If you just want
+ to run a program, optionally passing data to its standard input at
+ the beginning, use one of the launch() functions. If you want full
+ control of the program's standard input (especially if you don't
+ know all the data you want to send to standard input at the
+ beginning), use the start() function.
+
+ If you use start() you can write to the program's standard input
+ using writeToStdin() and you can close the standard input with
+ closeStdin(). The wroteToStdin() signal is emitted if the data
+ sent to standard input has been written. You can read from the
+ program's standard output using readStdout() or readLineStdout().
+ These functions return an empty TQByteArray if there is no data to
+ read. The readyReadStdout() signal is emitted when there is data
+ available to be read from standard output. Standard error has a
+ set of functions that correspond to the standard output functions,
+ i.e. readStderr(), readLineStderr() and readyReadStderr().
+
+ If you use one of the launch() functions the data you pass will be
+ sent to the program's standard input which will be closed once all
+ the data has been written. You should \e not use writeToStdin() or
+ closeStdin() if you use launch(). If you need to send data to the
+ program's standard input after it has started running use start()
+ instead of launch().
+
+ Both start() and launch() can accept a string list of strings each
+ of which has the format, key=value, where the keys are the names
+ of environment variables.
+
+ You can test to see if a program is running with isRunning(). The
+ program's process identifier is available from
+ processIdentifier(). If you want to terminate a running program
+ use tryTerminate(), but note that the program may ignore this. If
+ you \e really want to terminate the program, without it having any
+ chance to clean up, you can use kill().
+
+ As an example, suppose we want to start the \c uic command (a TQt
+ command line tool used with \e{TQt Designer}) and perform some
+ operations on the output (the \c uic outputs the code it generates
+ to standard output by default). Suppose further that we want to
+ run the program on the file "small_dialog.ui" with the command
+ line options "-tr i18n". On the command line we would write:
+ \code
+ uic -tr i18n small_dialog.ui
+ \endcode
+
+ \quotefile process/process.cpp
+
+ A code snippet for this with the TQProcess class might look like
+ this:
+
+ \skipto UicManager::UicManager()
+ \printline UicManager::UicManager()
+ \printline {
+ \skipto proc = new TQProcess( this );
+ \printline proc = new TQProcess( this );
+ \skipto proc->addArgument( "uic" );
+ \printuntil this, TQT_SLOT(readFromStdout()) );
+ \skipto if ( !proc->start() ) {
+ \printuntil // error handling
+ \skipto }
+ \printline }
+ \printline }
+
+ \skipto void UicManager::readFromStdout()
+ \printuntil // Bear in mind that the data might be output in chunks.
+ \skipto }
+ \printline }
+
+ Although you may need quotes for a file named on the command line
+ (e.g. if it tqcontains spaces) you shouldn't use extra quotes for
+ arguments passed to addArgument() or setArguments().
+
+ The readyReadStdout() signal is emitted when there is new data on
+ standard output. This happens asynchronously: you don't know if
+ more data will arrive later.
+
+ In the above example you could connect the processExited() signal
+ to the slot UicManager::readFromStdout() instead. If you do so,
+ you will be certain that all the data is available when the slot
+ is called. On the other hand, you must wait until the process has
+ finished before doing any processing.
+
+ Note that if you are expecting a lot of output from the process,
+ you may hit platform-dependent limits to the pipe buffer size. The
+ solution is to make sure you connect to the output, e.g. the
+ readyReadStdout() and readyReadStderr() Q_SIGNALS and read the data
+ as soon as it becomes available.
+
+ Please note that TQProcess does not emulate a shell. This means that
+ TQProcess does not do any expansion of arguments: a '*' is passed as a '*'
+ to the program and is \e not tqreplaced by all the files, a '$HOME' is also
+ passed literally and is \e not tqreplaced by the environment variable HOME
+ and the special characters for IO redirection ('>', '|', etc.) are also
+ passed literally and do \e not have the special meaning as they have in a
+ shell.
+
+ Also note that TQProcess does not emulate a terminal. This means that
+ certain programs which need direct terminal control, do not work as
+ expected with TQProcess. Such programs include console email programs (like
+ pine and mutt) but also programs which require the user to enter a password
+ (like su and ssh).
+
+ \section1 Notes for Windows users
+
+ Some Windows commands, for example, \c dir, are not provided by
+ separate applications, but by the command interpreter.
+ If you attempt to use TQProcess to execute these commands directly
+ it won't work. One possible solution is to execute the command
+ interpreter itself (\c cmd.exe on some Windows systems), and ask
+ the interpreter to execute the desired command.
+
+ Under Windows there are certain problems starting 16-bit applications
+ and capturing their output. Microsoft recommends using an intermediate
+ application to start 16-bit applications.
+
+ \sa TQSocket
+*/
+
+/*!
+ \enum TQProcess::Communication
+
+ This enum type defines the communication channels connected to the
+ process.
+
+ \value Stdin Data can be written to the process's standard input.
+
+ \value Stdout Data can be read from the process's standard
+ output.
+
+ \value Stderr Data can be read from the process's standard error.
+
+ \value DupStderr Both the process's standard error output \e and
+ its standard output are written to its standard output. (Like
+ Unix's dup2().) This means that nothing is sent to the standard
+ error output. This is especially useful if your application
+ requires that the output on standard output and on standard error
+ must be read in the same order that they are produced. This is a
+ flag, so to activate it you must pass \c{Stdout|Stderr|DupStderr},
+ or \c{Stdin|Stdout|Stderr|DupStderr} if you want to provide input,
+ to the setCommunication() call.
+
+ \sa setCommunication() communication()
+*/
+
+/*!
+ Constructs a TQProcess object. The \a tqparent and \a name parameters
+ are passed to the TQObject constructor.
+
+ \sa setArguments() addArgument() start()
+*/
+TQProcess::TQProcess( TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
+ wroteToStdinConnected( FALSE ),
+ readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
+ comms( Stdin|Stdout|Stderr )
+{
+ init();
+}
+
+/*!
+ Constructs a TQProcess with \a arg0 as the command to be executed.
+ The \a tqparent and \a name parameters are passed to the TQObject
+ constructor.
+
+ The process is not started. You must call start() or launch() to
+ start the process.
+
+ \sa setArguments() addArgument() start()
+*/
+TQProcess::TQProcess( const TQString& arg0, TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
+ wroteToStdinConnected( FALSE ),
+ readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
+ comms( Stdin|Stdout|Stderr )
+{
+ init();
+ addArgument( arg0 );
+}
+
+/*!
+ Constructs a TQProcess with \a args as the arguments of the
+ process. The first element in the list is the command to be
+ executed. The other elements in the list are the arguments to this
+ command. The \a tqparent and \a name parameters are passed to the
+ TQObject constructor.
+
+ The process is not started. You must call start() or launch() to
+ start the process.
+
+ \sa setArguments() addArgument() start()
+*/
+TQProcess::TQProcess( const TQStringList& args, TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name ), ioRedirection( FALSE ), notifyOnExit( FALSE ),
+ wroteToStdinConnected( FALSE ),
+ readStdoutCalled( FALSE ), readStderrCalled( FALSE ),
+ comms( Stdin|Stdout|Stderr )
+{
+ init();
+ setArguments( args );
+}
+
+
+/*!
+ Returns the list of arguments that are set for the process.
+ Arguments can be specified with the constructor or with the
+ functions setArguments() and addArgument().
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myProcess.arguments();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa setArguments() addArgument()
+*/
+TQStringList TQProcess::arguments() const
+{
+ return _arguments;
+}
+
+/*!
+ Clears the list of arguments that are set for the process.
+
+ \sa setArguments() addArgument()
+*/
+void TQProcess::clearArguments()
+{
+ _arguments.clear();
+}
+
+/*!
+ Sets \a args as the arguments for the process. The first element
+ in the list is the command to be executed. The other elements in
+ the list are the arguments to the command. Any previous arguments
+ are deleted.
+
+ TQProcess does not perform argument substitutions; for example, if you
+ specify "*" or "$DISPLAY", these values are passed to the process
+ literally. If you want to have the same behavior as the shell
+ provides, you must do the substitutions yourself; i.e. instead of
+ specifying a "*" you must specify the list of all the filenames in
+ the current directory, and instead of "$DISPLAY" you must specify
+ the value of the environment variable \c DISPLAY.
+
+ Note for Windows users. The standard Windows shells, e.g. \c
+ command.com and \c cmd.exe, do not perform file globbing, i.e.
+ they do not convert a "*" on the command line into a list of files
+ in the current directory. For this reason most Windows
+ applications implement their own file globbing, and as a result of
+ this, specifying an argument of "*" for a Windows application is
+ likely to result in the application performing a file glob and
+ ending up with a list of filenames.
+
+ \sa arguments() addArgument()
+*/
+void TQProcess::setArguments( const TQStringList& args )
+{
+ _arguments = args;
+}
+
+/*!
+ Adds \a arg to the end of the list of arguments.
+
+ The first element in the list of arguments is the command to be
+ executed; the following elements are the command's arguments.
+
+ \sa arguments() setArguments()
+*/
+void TQProcess::addArgument( const TQString& arg )
+{
+ _arguments.append( arg );
+}
+
+#ifndef TQT_NO_DIR
+/*!
+ Returns the working directory that was set with
+ setWorkingDirectory(), or the current directory if none has been
+ explicitly set.
+
+ \sa setWorkingDirectory() TQDir::current()
+*/
+TQDir TQProcess::workingDirectory() const
+{
+ return workingDir;
+}
+
+/*!
+ Sets \a dir as the working directory for processes. This does not
+ affect running processes; only processes that are started
+ afterwards are affected.
+
+ Setting the working directory is especially useful for processes
+ that try to access files with relative paths.
+
+ \sa workingDirectory() start()
+*/
+void TQProcess::setWorkingDirectory( const TQDir& dir )
+{
+ workingDir = dir;
+}
+#endif //TQT_NO_DIR
+
+/*!
+ Returns the communication required with the process, i.e. some
+ combination of the \c Communication flags.
+
+ \sa setCommunication()
+*/
+int TQProcess::communication() const
+{
+ return comms;
+}
+
+/*!
+ Sets \a commFlags as the communication required with the process.
+
+ \a commFlags is a bitwise OR of the flags defined by the \c
+ Communication enum.
+
+ The default is \c{Stdin|Stdout|Stderr}.
+
+ \sa communication()
+*/
+void TQProcess::setCommunication( int commFlags )
+{
+ comms = commFlags;
+}
+
+/*!
+ Returns TRUE if the process has exited normally; otherwise returns
+ FALSE. This implies that this function returns FALSE if the
+ process is still running.
+
+ \sa isRunning() exitqStatus() processExited()
+*/
+bool TQProcess::normalExit() const
+{
+ // isRunning() has the side effect that it determines the exit status!
+ if ( isRunning() )
+ return FALSE;
+ else
+ return exitNormal;
+}
+
+/*!
+ Returns the exit status of the process or 0 if the process is
+ still running. This function returns immediately and does not wait
+ until the process is finished.
+
+ If normalExit() is FALSE (e.g. if the program was killed or
+ crashed), this function returns 0, so you should check the return
+ value of normalExit() before relying on this value.
+
+ \sa normalExit() processExited()
+*/
+int TQProcess::exitqStatus() const
+{
+ // isRunning() has the side effect that it determines the exit status!
+ if ( isRunning() )
+ return 0;
+ else
+ return exitStat;
+}
+
+
+/*!
+ Reads the data that the process has written to standard output.
+ When new data is written to standard output, the class emits the
+ signal readyReadStdout().
+
+ If there is no data to read, this function returns a TQByteArray of
+ size 0: it does not wait until there is something to read.
+
+ \sa readyReadStdout() readLineStdout() readStderr() writeToStdin()
+*/
+TQByteArray TQProcess::readStdout()
+{
+ if ( readStdoutCalled ) {
+ return TQByteArray();
+ }
+ readStdoutCalled = TRUE;
+ TQMembuf *buf = membufStdout();
+ readStdoutCalled = FALSE;
+
+ return buf->readAll();
+}
+
+/*!
+ Reads the data that the process has written to standard error.
+ When new data is written to standard error, the class emits the
+ signal readyReadStderr().
+
+ If there is no data to read, this function returns a TQByteArray of
+ size 0: it does not wait until there is something to read.
+
+ \sa readyReadStderr() readLineStderr() readStdout() writeToStdin()
+*/
+TQByteArray TQProcess::readStderr()
+{
+ if ( readStderrCalled ) {
+ return TQByteArray();
+ }
+ readStderrCalled = TRUE;
+ TQMembuf *buf = membufStderr();
+ readStderrCalled = FALSE;
+
+ return buf->readAll();
+}
+
+/*!
+ Reads a line of text from standard output, excluding any trailing
+ newline or carriage return characters, and returns it. Returns
+ TQString::null if canReadLineStdout() returns FALSE.
+
+ By default, the text is interpreted to be in Latin-1 encoding. If you need
+ other codecs, you can set a different codec with
+ TQTextCodec::setCodecForCStrings().
+
+ \sa canReadLineStdout() readyReadStdout() readStdout() readLineStderr()
+*/
+TQString TQProcess::readLineStdout()
+{
+ TQByteArray a( 256 );
+ TQMembuf *buf = membufStdout();
+ if ( !buf->scanNewline( &a ) ) {
+ if ( !canReadLineStdout() )
+ return TQString::null;
+
+ if ( !buf->scanNewline( &a ) )
+ return TQString( buf->readAll() );
+ }
+
+ uint size = a.size();
+ buf->consumeBytes( size, 0 );
+
+ // get rid of terminating \n or \r\n
+ if ( size>0 && a.at( size - 1 ) == '\n' ) {
+ if ( size>1 && a.at( size - 2 ) == '\r' )
+ a[ size - 2 ] = '\0';
+ else
+ a[ size - 1 ] = '\0';
+ }
+ return TQString( a );
+}
+
+/*!
+ Reads a line of text from standard error, excluding any trailing
+ newline or carriage return characters and returns it. Returns
+ TQString::null if canReadLineStderr() returns FALSE.
+
+ By default, the text is interpreted to be in Latin-1 encoding. If you need
+ other codecs, you can set a different codec with
+ TQTextCodec::setCodecForCStrings().
+
+ \sa canReadLineStderr() readyReadStderr() readStderr() readLineStdout()
+*/
+TQString TQProcess::readLineStderr()
+{
+ TQByteArray a( 256 );
+ TQMembuf *buf = membufStderr();
+ if ( !buf->scanNewline( &a ) ) {
+ if ( !canReadLineStderr() )
+ return TQString::null;
+
+ if ( !buf->scanNewline( &a ) )
+ return TQString( buf->readAll() );
+ }
+
+ uint size = a.size();
+ buf->consumeBytes( size, 0 );
+
+ // get rid of terminating \n or \r\n
+ if ( size>0 && a.at( size - 1 ) == '\n' ) {
+ if ( size>1 && a.at( size - 2 ) == '\r' )
+ a[ size - 2 ] = '\0';
+ else
+ a[ size - 1 ] = '\0';
+ }
+ return TQString( a );
+}
+
+/*!
+ \fn void TQProcess::launchFinished()
+
+ This signal is emitted when the process was started with launch().
+ If the start was successful, this signal is emitted after all the
+ data has been written to standard input. If the start failed, then
+ this signal is emitted immediately.
+
+ This signal is especially useful if you want to know when you can
+ safely delete the TQProcess object when you are not interested in
+ reading from standard output or standard error.
+
+ \sa launch() TQObject::deleteLater()
+*/
+
+/*!
+ Runs the process and writes the data \a buf to the process's
+ standard input. If all the data is written to standard input,
+ standard input is closed. The command is searched for in the path
+ for executable programs; you can also use an absolute path in the
+ command itself.
+
+ If \a env is null, then the process is started with the same
+ environment as the starting process. If \a env is non-null, then
+ the values in the string list are interpreted as environment
+ setttings of the form \c {key=value} and the process is started
+ with these environment settings. For convenience, there is a small
+ exception to this rule under Unix: if \a env does not contain any
+ settings for the environment variable \c LD_LIBRARY_PATH, then
+ this variable is inherited from the starting process.
+
+ Returns TRUE if the process could be started; otherwise returns
+ FALSE.
+
+ Note that you should not use the Q_SLOTS writeToStdin() and
+ closeStdin() on processes started with launch(), since the result
+ is not well-defined. If you need these Q_SLOTS, use start() instead.
+
+ The process may or may not read the \a buf data sent to its
+ standard input.
+
+ You can call this function even when a process that was started
+ with this instance is still running. Be aware that if you do this
+ the standard input of the process that was launched first will be
+ closed, with any pending data being deleted, and the process will
+ be left to run out of your control. Similarly, if the process
+ could not be started the standard input will be closed and the
+ pending data deleted. (On operating systems that have zombie
+ processes, TQt will also wait() on the old process.)
+
+ The object emits the signal launchFinished() when this function
+ call is finished. If the start was successful, this signal is
+ emitted after all the data has been written to standard input. If
+ the start failed, then this signal is emitted immediately.
+
+ \sa start() launchFinished();
+*/
+bool TQProcess::launch( const TQByteArray& buf, TQStringList *env )
+{
+ if ( start( env ) ) {
+ if ( !buf.isEmpty() ) {
+ connect( this, TQT_SIGNAL(wroteToStdin()),
+ this, TQT_SLOT(closeStdinLaunch()) );
+ writeToStdin( buf );
+ } else {
+ closeStdin();
+ emit launchFinished();
+ }
+ return TRUE;
+ } else {
+ emit launchFinished();
+ return FALSE;
+ }
+}
+
+/*!
+ \overload
+
+ The data \a buf is written to standard input with writeToStdin()
+ using the TQString::local8Bit() representation of the strings.
+*/
+bool TQProcess::launch( const TQString& buf, TQStringList *env )
+{
+ if ( start( env ) ) {
+ if ( !buf.isEmpty() ) {
+ connect( this, TQT_SIGNAL(wroteToStdin()),
+ this, TQT_SLOT(closeStdinLaunch()) );
+ writeToStdin( buf );
+ } else {
+ closeStdin();
+ emit launchFinished();
+ }
+ return TRUE;
+ } else {
+ emit launchFinished();
+ return FALSE;
+ }
+}
+
+/*
+ This private slot is used by the launch() functions to close standard input.
+*/
+void TQProcess::closeStdinLaunch()
+{
+ disconnect( this, TQT_SIGNAL(wroteToStdin()),
+ this, TQT_SLOT(closeStdinLaunch()) );
+ closeStdin();
+ emit launchFinished();
+}
+
+
+/*!
+ \fn void TQProcess::readyReadStdout()
+
+ This signal is emitted when the process has written data to
+ standard output. You can read the data with readStdout().
+
+ Note that this signal is only emitted when there is new data and
+ not when there is old, but unread data. In the slot connected to
+ this signal, you should always read everything that is available
+ at that moment to make sure that you don't lose any data.
+
+ \sa readStdout() readLineStdout() readyReadStderr()
+*/
+
+/*!
+ \fn void TQProcess::readyReadStderr()
+
+ This signal is emitted when the process has written data to
+ standard error. You can read the data with readStderr().
+
+ Note that this signal is only emitted when there is new data and
+ not when there is old, but unread data. In the slot connected to
+ this signal, you should always read everything that is available
+ at that moment to make sure that you don't lose any data.
+
+ \sa readStderr() readLineStderr() readyReadStdout()
+*/
+
+/*!
+ \fn void TQProcess::processExited()
+
+ This signal is emitted when the process has exited.
+
+ \sa isRunning() normalExit() exitqStatus() start() launch()
+*/
+
+/*!
+ \fn void TQProcess::wroteToStdin()
+
+ This signal is emitted if the data sent to standard input (via
+ writeToStdin()) was actually written to the process. This does not
+ imply that the process really read the data, since this class only
+ detects when it was able to write the data to the operating
+ system. But it is now safe to close standard input without losing
+ pending data.
+
+ \sa writeToStdin() closeStdin()
+*/
+
+
+/*!
+ \overload
+
+ The string \a buf is handled as text using the
+ TQString::local8Bit() representation.
+*/
+void TQProcess::writeToStdin( const TQString& buf )
+{
+ TQByteArray tmp = buf.local8Bit();
+ tmp.resize( tqstrlen( tmp.data() ) );
+ writeToStdin( tmp );
+}
+
+
+/*
+ * Under Windows the implementation is not so nice: it is not that easy to
+ * detect when one of the Q_SIGNALS should be emitted; therefore there are some
+ * timers that query the information.
+ * To keep it a little efficient, use the timers only when they are needed.
+ * They are needed, if you are interested in the Q_SIGNALS. So use
+ * connectNotify() and disconnectNotify() to keep track of your interest.
+ */
+/*! \reimp
+*/
+void TQProcess::connectNotify( const char * signal )
+{
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::connectNotify(): signal %s has been connected", signal );
+#endif
+ if ( !ioRedirection )
+ if ( qstrcmp( signal, TQT_SIGNAL(readyReadStdout()) )==0 ||
+ qstrcmp( signal, TQT_SIGNAL(readyReadStderr()) )==0
+ ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::connectNotify(): set ioRedirection to TRUE" );
+#endif
+ setIoRedirection( TRUE );
+ return;
+ }
+ if ( !notifyOnExit && qstrcmp( signal, TQT_SIGNAL(processExited()) )==0 ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::connectNotify(): set notifyOnExit to TRUE" );
+#endif
+ setNotifyOnExit( TRUE );
+ return;
+ }
+ if ( !wroteToStdinConnected && qstrcmp( signal, TQT_SIGNAL(wroteToStdin()) )==0 ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::connectNotify(): set wroteToStdinConnected to TRUE" );
+#endif
+ setWroteStdinConnected( TRUE );
+ return;
+ }
+}
+
+/*! \reimp
+*/
+void TQProcess::disconnectNotify( const char * )
+{
+ if ( ioRedirection &&
+ tqreceivers( TQT_SIGNAL(readyReadStdout()) ) ==0 &&
+ tqreceivers( TQT_SIGNAL(readyReadStderr()) ) ==0
+ ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::disconnectNotify(): set ioRedirection to FALSE" );
+#endif
+ setIoRedirection( FALSE );
+ }
+ if ( notifyOnExit && tqreceivers( TQT_SIGNAL(processExited()) ) == 0 ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::disconnectNotify(): set notifyOnExit to FALSE" );
+#endif
+ setNotifyOnExit( FALSE );
+ }
+ if ( wroteToStdinConnected && tqreceivers( TQT_SIGNAL(wroteToStdin()) ) == 0 ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::disconnectNotify(): set wroteToStdinConnected to FALSE" );
+#endif
+ setWroteStdinConnected( FALSE );
+ }
+}
+
+#endif // TQT_NO_PROCESS
diff --git a/tqtinterface/qt4/src/kernel/tqprocess.h b/tqtinterface/qt4/src/kernel/tqprocess.h
new file mode 100644
index 0000000..ad00b30
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqprocess.h
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Implementation of TQProcess class
+**
+** Created : 20000905
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPROCESS_H
+#define TQPROCESS_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqstringlist.h"
+#include "tqdir.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_PROCESS
+
+class TQProcessPrivate;
+class TQMembuf;
+
+
+class TQ_EXPORT TQProcess : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQProcess( TQObject *tqparent=0, const char *name=0 );
+ TQProcess( const TQString& arg0, TQObject *tqparent=0, const char *name=0 );
+ TQProcess( const TQStringList& args, TQObject *tqparent=0, const char *name=0 );
+ ~TQProcess();
+
+ // set and get the arguments and working directory
+ TQStringList arguments() const;
+ void clearArguments();
+ virtual void setArguments( const TQStringList& args );
+ virtual void addArgument( const TQString& arg );
+#ifndef TQT_NO_DIR
+ TQDir workingDirectory() const;
+ virtual void setWorkingDirectory( const TQDir& dir );
+#endif
+
+ // set and get the comms wanted
+ enum Communication { Stdin=0x01, Stdout=0x02, Stderr=0x04, DupStderr=0x08 };
+ void setCommunication( int c );
+ int communication() const;
+
+ // start the execution
+ virtual bool start( TQStringList *env=0 );
+ virtual bool launch( const TQString& buf, TQStringList *env=0 );
+ virtual bool launch( const TQByteArray& buf, TQStringList *env=0 );
+
+ // inquire the status
+ bool isRunning() const;
+ bool normalExit() const;
+ int exitqStatus() const;
+
+ // reading
+ virtual TQByteArray readStdout();
+ virtual TQByteArray readStderr();
+ bool canReadLineStdout() const;
+ bool canReadLineStderr() const;
+ virtual TQString readLineStdout();
+ virtual TQString readLineStderr();
+
+ // get platform dependent process information
+#if defined(TQ_OS_WIN32)
+ typedef void* PID;
+#else
+ typedef TQ_LONG PID;
+#endif
+ PID processIdentifier();
+
+ void flushStdin();
+
+Q_SIGNALS:
+ void readyReadStdout();
+ void readyReadStderr();
+ void processExited();
+ void wroteToStdin();
+ void launchFinished();
+
+public Q_SLOTS:
+ // end the execution
+ void tryTerminate() const;
+ void kill() const;
+
+ // input
+ virtual void writeToStdin( const TQByteArray& buf );
+ virtual void writeToStdin( const TQString& buf );
+ virtual void closeStdin();
+
+protected: // ### or private?
+ void connectNotify( const char * signal );
+ void disconnectNotify( const char * signal );
+private:
+ void setIoRedirection( bool value );
+ void setNotifyOnExit( bool value );
+ void setWroteStdinConnected( bool value );
+
+ void init();
+ void reset();
+#if defined(TQ_OS_WIN32)
+ uint readStddev( HANDLE dev, char *buf, uint bytes );
+#endif
+ TQMembuf* membufStdout();
+ TQMembuf* membufStderr();
+
+private Q_SLOTS:
+ void socketRead( int fd );
+ void socketWrite( int fd );
+ void timeout();
+ void closeStdinLaunch();
+
+private:
+ TQProcessPrivate *d;
+#ifndef TQT_NO_DIR
+ TQDir workingDir;
+#endif
+ TQStringList _arguments;
+
+ int exitStat; // exit status
+ bool exitNormal; // normal exit?
+ bool ioRedirection; // automatically set be (dis)connectNotify
+ bool notifyOnExit; // automatically set be (dis)connectNotify
+ bool wroteToStdinConnected; // automatically set be (dis)connectNotify
+
+ bool readStdoutCalled;
+ bool readStderrCalled;
+ int comms;
+
+ friend class TQProcessPrivate;
+#if defined(TQ_OS_UNIX)
+ friend class TQProcessManager;
+ friend class TQProc;
+#endif
+
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQProcess( const TQProcess & );
+ TQProcess &operator=( const TQProcess & );
+#endif
+};
+
+#endif // TQT_NO_PROCESS
+
+#endif // TQPROCESS_H
diff --git a/tqtinterface/qt4/src/kernel/tqprocess_unix.cpp b/tqtinterface/qt4/src/kernel/tqprocess_unix.cpp
new file mode 100644
index 0000000..0895ae2
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqprocess_unix.cpp
@@ -0,0 +1,1410 @@
+/****************************************************************************
+**
+** Implementation of TQProcess class for Unix
+**
+** Created : 20000905
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
+#if defined(connect)
+#undef connect
+#endif
+
+#include "tqprocess.h"
+
+#ifndef TQT_NO_PROCESS
+
+#include "tqapplication.h"
+#include "tqptrqueue.h"
+#include "tqptrlist.h"
+#include "tqsocketnotifier.h"
+#include "tqtimer.h"
+#include "tqcleanuphandler.h"
+#include "tqregexp.h"
+#include "private/tqinternal_p.h"
+
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#ifdef __MIPSEL__
+# ifndef SOCK_DGRAM
+# define SOCK_DGRAM 1
+# endif
+# ifndef SOCK_STREAM
+# define SOCK_STREAM 2
+# endif
+#endif
+
+//#define TQT_TQPROCESS_DEBUG
+
+
+#ifdef TQ_C_CALLBACKS
+extern "C" {
+#endif // TQ_C_CALLBACKS
+
+ TQT_SIGNAL_RETTYPE qt_C_sigchldHnd(TQT_SIGNAL_ARGS);
+
+#ifdef TQ_C_CALLBACKS
+}
+#endif // TQ_C_CALLBACKS
+
+
+class TQProc;
+class TQProcessManager;
+class TQProcessPrivate
+{
+public:
+ TQProcessPrivate();
+ ~TQProcessPrivate();
+
+ void closeOpenSocketsForChild();
+ void newProc( pid_t pid, TQProcess *process );
+
+ TQMembuf bufStdout;
+ TQMembuf bufStderr;
+
+ TQPtrQueue<TQByteArray> stdinBuf;
+
+ TQSocketNotifier *notifierStdin;
+ TQSocketNotifier *notifierStdout;
+ TQSocketNotifier *notifierStderr;
+
+ ssize_t stdinBufRead;
+ TQProc *proc;
+
+ bool exitValuesCalculated;
+ bool socketReadCalled;
+
+ static TQProcessManager *procManager;
+};
+
+
+/***********************************************************************
+ *
+ * TQProc
+ *
+ **********************************************************************/
+/*
+ The class TQProcess does not necessarily map exactly to the running
+ child processes: if the process is finished, the TQProcess class may still be
+ there; furthermore a user can use TQProcess to start more than one process.
+
+ The helper-class TQProc has the semantics that one instance of this class maps
+ directly to a running child process.
+*/
+class TQProc
+{
+public:
+ TQProc( pid_t p, TQProcess *proc=0 ) : pid(p), process(proc)
+ {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProc: Constructor for pid %d and TQProcess %p", pid, process );
+#endif
+ socketStdin = 0;
+ socketStdout = 0;
+ socketStderr = 0;
+ }
+ ~TQProc()
+ {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProc: Destructor for pid %d and TQProcess %p", pid, process );
+#endif
+ if ( process ) {
+ if ( process->d->notifierStdin )
+ process->d->notifierStdin->setEnabled( FALSE );
+ if ( process->d->notifierStdout )
+ process->d->notifierStdout->setEnabled( FALSE );
+ if ( process->d->notifierStderr )
+ process->d->notifierStderr->setEnabled( FALSE );
+ process->d->proc = 0;
+ }
+ if( socketStdin )
+ ::close( socketStdin );
+ if( socketStdout )
+ ::close( socketStdout );
+ if( socketStderr )
+ ::close( socketStderr );
+ }
+
+ pid_t pid;
+ int socketStdin;
+ int socketStdout;
+ int socketStderr;
+ TQProcess *process;
+};
+
+/***********************************************************************
+ *
+ * TQProcessManager
+ *
+ **********************************************************************/
+class TQProcessManager : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQProcessManager();
+ ~TQProcessManager();
+
+ void append( TQProc *p );
+ void remove( TQProc *p );
+
+ void cleanup();
+
+public Q_SLOTS:
+ void removeMe();
+ void sigchldHnd( int );
+
+public:
+ struct sigaction oldactChld;
+ struct sigaction oldactPipe;
+ TQPtrList<TQProc> *procList;
+ int sigchldFd[2];
+
+private:
+ TQSocketNotifier *sn;
+};
+
+static void qprocess_cleanup()
+{
+ delete TQProcessPrivate::procManager;
+ TQProcessPrivate::procManager = 0;
+}
+
+#ifdef TQ_OS_TQNX6
+#define BAILOUT close(tmpSocket);close(socketFD[1]);return -1;
+int qnx6SocketPairReplacement (int socketFD[2]) {
+ int tmpSocket;
+ tmpSocket = socket (AF_INET, SOCK_STREAM, 0);
+ if (tmpSocket == -1)
+ return -1;
+ socketFD[1] = socket(AF_INET, SOCK_STREAM, 0);
+ if (socketFD[1] == -1) { BAILOUT };
+
+ sockaddr_in ipAddr;
+ memset(&ipAddr, 0, sizeof(ipAddr));
+ ipAddr.sin_family = AF_INET;
+ ipAddr.sin_addr.s_addr = INADDR_ANY;
+
+ int socketOptions = 1;
+ setsockopt(tmpSocket, SOL_SOCKET, SO_REUSEADDR, &socketOptions, sizeof(int));
+
+ bool found = FALSE;
+ for (int socketIP = 2000; (socketIP < 2500) && !(found); socketIP++) {
+ ipAddr.sin_port = htons(socketIP);
+ if (bind(tmpSocket, (struct sockaddr *)&ipAddr, sizeof(ipAddr)))
+ found = TRUE;
+ }
+
+ if (listen(tmpSocket, 5)) { BAILOUT };
+
+ // Select non-blocking mode
+ int originalFlags = fcntl(socketFD[1], F_GETFL, 0);
+ fcntl(socketFD[1], F_SETFL, originalFlags | O_NONBLOCK);
+
+ // Request connection
+ if (connect(socketFD[1], (struct sockaddr*)&ipAddr, sizeof(ipAddr)))
+ if (errno != EINPROGRESS) { BAILOUT };
+
+ // Accept connection
+ socketFD[0] = accept(tmpSocket, (struct sockaddr *)NULL, (size_t *)NULL);
+ if(socketFD[0] == -1) { BAILOUT };
+
+ // We're done
+ close(tmpSocket);
+
+ // Restore original flags , ie return to blocking
+ fcntl(socketFD[1], F_SETFL, originalFlags);
+ return 0;
+}
+#undef BAILOUT
+#endif
+
+TQProcessManager::TQProcessManager() : sn(0)
+{
+ procList = new TQPtrList<TQProc>;
+ procList->setAutoDelete( TRUE );
+
+ // The SIGCHLD handler writes to a socket to tell the manager that
+ // something happened. This is done to get the processing in sync with the
+ // event reporting.
+#ifndef TQ_OS_TQNX6
+ if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, sigchldFd ) ) {
+#else
+ if ( qnx6SocketPairReplacement (sigchldFd) ) {
+#endif
+ sigchldFd[0] = 0;
+ sigchldFd[1] = 0;
+ } else {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager: install socket notifier (%d)", sigchldFd[1] );
+#endif
+ sn = new TQSocketNotifier( sigchldFd[1],
+ TQSocketNotifier::Read, this );
+ connect( sn, TQT_SIGNAL(activated(int)),
+ this, TQT_SLOT(sigchldHnd(int)) );
+ sn->setEnabled( TRUE );
+ }
+
+ // install a SIGCHLD handler and ignore SIGPIPE
+ struct sigaction act;
+
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager: install a SIGCHLD handler" );
+#endif
+ act.sa_handler = qt_C_sigchldHnd;
+ sigemptyset( &(act.sa_mask) );
+ sigaddset( &(act.sa_mask), SIGCHLD );
+ act.sa_flags = SA_NOCLDSTOP;
+#if defined(SA_RESTART)
+ act.sa_flags |= SA_RESTART;
+#endif
+ if ( sigaction( SIGCHLD, &act, &oldactChld ) != 0 )
+ qWarning( "Error installing SIGCHLD handler" );
+
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager: install a SIGPIPE handler (SIG_IGN)" );
+#endif
+ act.sa_handler = TQT_SIGNAL_IGNORE;
+ sigemptyset( &(act.sa_mask) );
+ sigaddset( &(act.sa_mask), SIGPIPE );
+ act.sa_flags = 0;
+ if ( sigaction( SIGPIPE, &act, &oldactPipe ) != 0 )
+ qWarning( "Error installing SIGPIPE handler" );
+}
+
+TQProcessManager::~TQProcessManager()
+{
+ delete procList;
+
+ if ( sigchldFd[0] != 0 )
+ ::close( sigchldFd[0] );
+ if ( sigchldFd[1] != 0 )
+ ::close( sigchldFd[1] );
+
+ // restore SIGCHLD handler
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager: restore old sigchild handler" );
+#endif
+ if ( sigaction( SIGCHLD, &oldactChld, 0 ) != 0 )
+ qWarning( "Error restoring SIGCHLD handler" );
+
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager: restore old sigpipe handler" );
+#endif
+ if ( sigaction( SIGPIPE, &oldactPipe, 0 ) != 0 )
+ qWarning( "Error restoring SIGPIPE handler" );
+}
+
+void TQProcessManager::append( TQProc *p )
+{
+ procList->append( p );
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager: append process (procList.count(): %d)", procList->count() );
+#endif
+}
+
+void TQProcessManager::remove( TQProc *p )
+{
+ procList->remove( p );
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager: remove process (procList.count(): %d)", procList->count() );
+#endif
+ cleanup();
+}
+
+void TQProcessManager::cleanup()
+{
+ if ( procList->count() == 0 ) {
+ TQTimer::singleShot( 0, this, TQT_SLOT(removeMe()) );
+ }
+}
+
+void TQProcessManager::removeMe()
+{
+ if ( procList->count() == 0 ) {
+ qRemovePostRoutine(qprocess_cleanup);
+ TQProcessPrivate::procManager = 0;
+ delete this;
+ }
+}
+
+void TQProcessManager::sigchldHnd( int fd )
+{
+ // Disable the socket notifier to make sure that this function is not
+ // called recursively -- this can happen, if you enter the event loop in
+ // the slot connected to the processExited() signal (e.g. by showing a
+ // modal dialog) and there are more than one process which exited in the
+ // meantime.
+ if ( sn ) {
+ if ( !sn->isEnabled() )
+ return;
+ sn->setEnabled( FALSE );
+ }
+
+ char tmp;
+ ::read( fd, &tmp, sizeof(tmp) );
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager::sigchldHnd()" );
+#endif
+ TQProc *proc;
+ TQProcess *process;
+ bool removeProc;
+ proc = procList->first();
+ while ( proc != 0 ) {
+ removeProc = FALSE;
+ process = proc->process;
+ if ( process != 0 ) {
+ if ( !process->isRunning() ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager::sigchldHnd() (PID: %d): process exited (TQProcess available)", proc->pid );
+#endif
+ /*
+ Apparently, there is not consistency among different
+ operating systems on how to use FIONREAD.
+
+ FreeBSD, Linux and Solaris all expect the 3rd
+ argument to ioctl() to be an int, which is normally
+ 32-bit even on 64-bit machines.
+
+ IRIX, on the other hand, expects a size_t, which is
+ 64-bit on 64-bit machines.
+
+ So, the solution is to use size_t initialized to
+ zero to make sure all bits are set to zero,
+ preventing underflow with the FreeBSD/Linux/Solaris
+ ioctls.
+ */
+ size_t nbytes = 0;
+ // read pending data
+ if ( proc->socketStdout && ::ioctl(proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on stdout", proc->pid, nbytes );
+#endif
+ process->socketRead( proc->socketStdout );
+ }
+ nbytes = 0;
+ if ( proc->socketStderr && ::ioctl(proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager::sigchldHnd() (PID: %d): reading %d bytes of pending data on stderr", proc->pid, nbytes );
+#endif
+ process->socketRead( proc->socketStderr );
+ }
+ // close filedescriptors if open, and disable the
+ // socket notifiers
+ if ( proc->socketStdout ) {
+ ::close( proc->socketStdout );
+ proc->socketStdout = 0;
+ if (process->d->notifierStdout)
+ process->d->notifierStdout->setEnabled(FALSE);
+ }
+ if ( proc->socketStderr ) {
+ ::close( proc->socketStderr );
+ proc->socketStderr = 0;
+ if (process->d->notifierStderr)
+ process->d->notifierStderr->setEnabled(FALSE);
+ }
+
+ if ( process->notifyOnExit )
+ emit process->processExited();
+
+ removeProc = TRUE;
+ }
+ } else {
+ int status;
+ if ( ::waitpid( proc->pid, &status, WNOHANG ) == proc->pid ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessManager::sigchldHnd() (PID: %d): process exited (TQProcess not available)", proc->pid );
+#endif
+ removeProc = TRUE;
+ }
+ }
+ if ( removeProc ) {
+ TQProc *oldproc = proc;
+ proc = procList->next();
+ remove( oldproc );
+ } else {
+ proc = procList->next();
+ }
+ }
+ if ( sn )
+ sn->setEnabled( TRUE );
+}
+
+#include "tqprocess_unix.tqmoc"
+
+
+/***********************************************************************
+ *
+ * TQProcessPrivate
+ *
+ **********************************************************************/
+TQProcessManager *TQProcessPrivate::procManager = 0;
+
+TQProcessPrivate::TQProcessPrivate()
+{
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessPrivate: Constructor" );
+#endif
+ stdinBufRead = 0;
+
+ notifierStdin = 0;
+ notifierStdout = 0;
+ notifierStderr = 0;
+
+ exitValuesCalculated = FALSE;
+ socketReadCalled = FALSE;
+
+ proc = 0;
+}
+
+TQProcessPrivate::~TQProcessPrivate()
+{
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcessPrivate: Destructor" );
+#endif
+
+ if ( proc != 0 ) {
+ if ( proc->socketStdin != 0 ) {
+ ::close( proc->socketStdin );
+ proc->socketStdin = 0;
+ }
+ proc->process = 0;
+ }
+
+ while ( !stdinBuf.isEmpty() ) {
+ delete stdinBuf.dequeue();
+ }
+ delete notifierStdin;
+ delete notifierStdout;
+ delete notifierStderr;
+}
+
+/*
+ Closes all open sockets in the child process that are not needed by the child
+ process. Otherwise one child may have an open socket on standard input, etc.
+ of another child.
+*/
+void TQProcessPrivate::closeOpenSocketsForChild()
+{
+ if ( procManager != 0 ) {
+ if ( procManager->sigchldFd[0] != 0 )
+ ::close( procManager->sigchldFd[0] );
+ if ( procManager->sigchldFd[1] != 0 )
+ ::close( procManager->sigchldFd[1] );
+
+ // close also the sockets from other TQProcess instances
+ for ( TQProc *p=procManager->procList->first(); p!=0; p=procManager->procList->next() ) {
+ ::close( p->socketStdin );
+ ::close( p->socketStdout );
+ ::close( p->socketStderr );
+ }
+ }
+}
+
+void TQProcessPrivate::newProc( pid_t pid, TQProcess *process )
+{
+ proc = new TQProc( pid, process );
+ if ( procManager == 0 ) {
+ procManager = new TQProcessManager;
+ qAddPostRoutine(qprocess_cleanup);
+ }
+ // the TQProcessManager takes care of deleting the TQProc instances
+ procManager->append( proc );
+}
+
+/***********************************************************************
+ *
+ * sigchld handler callback
+ *
+ **********************************************************************/
+TQT_SIGNAL_RETTYPE qt_C_sigchldHnd( TQT_SIGNAL_ARGS )
+{
+ if ( TQProcessPrivate::procManager == 0 )
+ return;
+ if ( TQProcessPrivate::procManager->sigchldFd[0] == 0 )
+ return;
+
+ char a = 1;
+ ::write( TQProcessPrivate::procManager->sigchldFd[0], &a, sizeof(a) );
+}
+
+
+/***********************************************************************
+ *
+ * TQProcess
+ *
+ **********************************************************************/
+/*
+ This private class does basic initialization.
+*/
+void TQProcess::init()
+{
+ d = new TQProcessPrivate();
+ exitStat = 0;
+ exitNormal = FALSE;
+}
+
+/*
+ This private class resets the process variables, etc. so that it can be used
+ for another process to start.
+*/
+void TQProcess::reset()
+{
+ delete d;
+ d = new TQProcessPrivate();
+ exitStat = 0;
+ exitNormal = FALSE;
+ d->bufStdout.clear();
+ d->bufStderr.clear();
+}
+
+TQMembuf* TQProcess::membufStdout()
+{
+ if ( d->proc && d->proc->socketStdout ) {
+ /*
+ Apparently, there is not consistency among different
+ operating systems on how to use FIONREAD.
+
+ FreeBSD, Linux and Solaris all expect the 3rd argument to
+ ioctl() to be an int, which is normally 32-bit even on
+ 64-bit machines.
+
+ IRIX, on the other hand, expects a size_t, which is 64-bit
+ on 64-bit machines.
+
+ So, the solution is to use size_t initialized to zero to
+ make sure all bits are set to zero, preventing underflow
+ with the FreeBSD/Linux/Solaris ioctls.
+ */
+ size_t nbytes = 0;
+ if ( ::ioctl(d->proc->socketStdout, FIONREAD, (char*)&nbytes)==0 && nbytes>0 )
+ socketRead( d->proc->socketStdout );
+ }
+ return &d->bufStdout;
+}
+
+TQMembuf* TQProcess::membufStderr()
+{
+ if ( d->proc && d->proc->socketStderr ) {
+ /*
+ Apparently, there is not consistency among different
+ operating systems on how to use FIONREAD.
+
+ FreeBSD, Linux and Solaris all expect the 3rd argument to
+ ioctl() to be an int, which is normally 32-bit even on
+ 64-bit machines.
+
+ IRIX, on the other hand, expects a size_t, which is 64-bit
+ on 64-bit machines.
+
+ So, the solution is to use size_t initialized to zero to
+ make sure all bits are set to zero, preventing underflow
+ with the FreeBSD/Linux/Solaris ioctls.
+ */
+ size_t nbytes = 0;
+ if ( ::ioctl(d->proc->socketStderr, FIONREAD, (char*)&nbytes)==0 && nbytes>0 )
+ socketRead( d->proc->socketStderr );
+ }
+ return &d->bufStderr;
+}
+
+/*!
+ Destroys the instance.
+
+ If the process is running, it is <b>not</b> terminated! The
+ standard input, standard output and standard error of the process
+ are closed.
+
+ You can connect the destroyed() signal to the kill() slot, if you
+ want the process to be terminated automatically when the instance
+ is destroyed.
+
+ \sa tryTerminate() kill()
+*/
+TQProcess::~TQProcess()
+{
+ delete d;
+}
+
+/*!
+ Tries to run a process for the command and arguments that were
+ specified with setArguments(), addArgument() or that were
+ specified in the constructor. The command is searched for in the
+ path for executable programs; you can also use an absolute path in
+ the command itself.
+
+ If \a env is null, then the process is started with the same
+ environment as the starting process. If \a env is non-null, then
+ the values in the stringlist are interpreted as environment
+ setttings of the form \c {key=value} and the process is started in
+ these environment settings. For convenience, there is a small
+ exception to this rule: under Unix, if \a env does not contain any
+ settings for the environment variable \c LD_LIBRARY_PATH, then
+ this variable is inherited from the starting process; under
+ Windows the same applies for the environment variable \c PATH.
+
+ Returns TRUE if the process could be started; otherwise returns
+ FALSE.
+
+ You can write data to the process's standard input with
+ writeToStdin(). You can close standard input with closeStdin() and
+ you can terminate the process with tryTerminate(), or with kill().
+
+ You can call this function even if you've used this instance to
+ create a another process which is still running. In such cases,
+ TQProcess closes the old process's standard input and deletes
+ pending data, i.e., you lose all control over the old process, but
+ the old process is not terminated. This applies also if the
+ process could not be started. (On operating systems that have
+ zombie processes, TQt will also wait() on the old process.)
+
+ \sa launch() closeStdin()
+*/
+bool TQProcess::start( TQStringList *env )
+{
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::start()" );
+#endif
+ reset();
+
+ int sStdin[2];
+ int sStdout[2];
+ int sStderr[2];
+
+ // open sockets for piping
+#ifndef TQ_OS_TQNX6
+ if ( (comms & Stdin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdin ) == -1 ) {
+#else
+ if ( (comms & Stdin) && qnx6SocketPairReplacement(sStdin) == -1 ) {
+#endif
+ return FALSE;
+ }
+#ifndef TQ_OS_TQNX6
+ if ( (comms & Stderr) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStderr ) == -1 ) {
+#else
+ if ( (comms & Stderr) && qnx6SocketPairReplacement(sStderr) == -1 ) {
+#endif
+ if ( comms & Stdin ) {
+ ::close( sStdin[0] );
+ ::close( sStdin[1] );
+ }
+ return FALSE;
+ }
+#ifndef TQ_OS_TQNX6
+ if ( (comms & Stdout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdout ) == -1 ) {
+#else
+ if ( (comms & Stdout) && qnx6SocketPairReplacement(sStdout) == -1 ) {
+#endif
+ if ( comms & Stdin ) {
+ ::close( sStdin[0] );
+ ::close( sStdin[1] );
+ }
+ if ( comms & Stderr ) {
+ ::close( sStderr[0] );
+ ::close( sStderr[1] );
+ }
+ return FALSE;
+ }
+
+ // the following pipe is only used to determine if the process could be
+ // started
+ int fd[2];
+ if ( pipe( fd ) < 0 ) {
+ // non critical error, go on
+ fd[0] = 0;
+ fd[1] = 0;
+ }
+
+ // construct the arguments for exec
+ TQCString *arglistQ = new TQCString[ _arguments.count() + 1 ];
+ const char** arglist = new const char*[ _arguments.count() + 1 ];
+ int i = 0;
+ for ( TQStringList::Iterator it = _arguments.begin(); it != _arguments.end(); ++it ) {
+ arglistQ[i] = (*it).local8Bit();
+ arglist[i] = arglistQ[i];
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::start(): arg %d = %s", i, arglist[i] );
+#endif
+ i++;
+ }
+#ifdef TQ_OS_MACX
+ if(i) {
+ TQCString arg_bundle = arglistQ[0];
+ TQFileInfo fi(arg_bundle);
+ if(fi.exists() && fi.isDir() && arg_bundle.right(4) == ".app") {
+ TQCString exe = arg_bundle;
+ int lslash = exe.tqfindRev('/');
+ if(lslash != -1)
+ exe = exe.mid(lslash+1);
+ exe = TQCString(arg_bundle + "/Contents/MacOS/" + exe);
+ exe = exe.left(exe.length() - 4); //chop off the .app
+ if(TQFile::exists(exe)) {
+ arglistQ[0] = exe;
+ arglist[0] = arglistQ[0];
+ }
+ }
+ }
+#endif
+ arglist[i] = 0;
+
+ // Must make sure signal handlers are installed before exec'ing
+ // in case the process exits quickly.
+ if ( d->procManager == 0 ) {
+ d->procManager = new TQProcessManager;
+ qAddPostRoutine(qprocess_cleanup);
+ }
+
+ // fork and exec
+ TQApplication::flushX();
+ pid_t pid = fork();
+ if ( pid == 0 ) {
+ // child
+ d->closeOpenSocketsForChild();
+ if ( comms & Stdin ) {
+ ::close( sStdin[1] );
+ ::dup2( sStdin[0], STDIN_FILENO );
+ }
+ if ( comms & Stdout ) {
+ ::close( sStdout[0] );
+ ::dup2( sStdout[1], STDOUT_FILENO );
+ }
+ if ( comms & Stderr ) {
+ ::close( sStderr[0] );
+ ::dup2( sStderr[1], STDERR_FILENO );
+ }
+ if ( comms & DupStderr ) {
+ ::dup2( STDOUT_FILENO, STDERR_FILENO );
+ }
+#ifndef TQT_NO_DIR
+ ::chdir( workingDir.absPath().latin1() );
+#endif
+ if ( fd[0] )
+ ::close( fd[0] );
+ if ( fd[1] )
+ ::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows sucess
+
+ if ( env == 0 ) { // inherit environment and start process
+#ifndef TQ_OS_TQNX4
+ ::execvp( arglist[0], (char*const*)arglist ); // ### cast not nice
+#else
+ ::execvp( arglist[0], (char const*const*)arglist ); // ### cast not nice
+#endif
+ } else { // start process with environment settins as specified in env
+ // construct the environment for exec
+ int numEntries = env->count();
+#if defined(TQ_OS_MACX)
+ TQString ld_library_path("DYLD_LIBRARY_PATH");
+#else
+ TQString ld_library_path("LD_LIBRARY_PATH");
+#endif
+ bool setLibraryPath =
+ env->grep( TQRegExp( "^" + ld_library_path + "=" ) ).empty() &&
+ getenv( ld_library_path ) != 0;
+ if ( setLibraryPath )
+ numEntries++;
+ TQCString *envlistQ = new TQCString[ numEntries + 1 ];
+ const char** envlist = new const char*[ numEntries + 1 ];
+ int i = 0;
+ if ( setLibraryPath ) {
+ envlistQ[i] = TQT_TQSTRING(TQString( ld_library_path + "=%1" ).arg( getenv( ld_library_path ) )).local8Bit();
+ envlist[i] = envlistQ[i];
+ i++;
+ }
+ for ( TQStringList::Iterator it = env->begin(); it != env->end(); ++it ) {
+ envlistQ[i] = (*it).local8Bit();
+ envlist[i] = envlistQ[i];
+ i++;
+ }
+ envlist[i] = 0;
+
+ // look for the executable in the search path
+ if ( _arguments.count()>0 && getenv("PATH")!=0 ) {
+ TQString command = _arguments[0];
+ if ( !command.tqcontains( '/' ) ) {
+ TQStringList pathList = TQStringList::split( ':', getenv( "PATH" ) );
+ for (TQStringList::Iterator it = pathList.begin(); it != pathList.end(); ++it ) {
+ TQString dir = *it;
+#if defined(TQ_OS_MACX) //look in a bundle
+ if(!TQFile::exists(dir + "/" + command) && TQFile::exists(dir + "/" + command + ".app"))
+ dir += "/" + command + ".app/Contents/MacOS";
+#endif
+#ifndef TQT_NO_DIR
+ TQFileInfo fileInfo( dir, command );
+#else
+ TQFileInfo fileInfo( dir + "/" + command );
+#endif
+ if ( fileInfo.isExecutable() ) {
+#if defined(TQ_OS_MACX)
+ arglistQ[0] = fileInfo.absFilePath().local8Bit();
+#else
+ arglistQ[0] = fileInfo.filePath().local8Bit();
+#endif
+ arglist[0] = arglistQ[0];
+ break;
+ }
+ }
+ }
+ }
+#ifndef TQ_OS_TQNX4
+ ::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice
+#else
+ ::execve( arglist[0], (char const*const*)arglist,(char const*const*)envlist ); // ### casts not nice
+#endif
+ }
+ if ( fd[1] ) {
+ char buf = 0;
+ ::write( fd[1], &buf, 1 );
+ ::close( fd[1] );
+ }
+ ::_exit( -1 );
+ } else if ( pid == -1 ) {
+ // error forking
+ goto error;
+ }
+
+ // test if exec was successful
+ if ( fd[1] )
+ ::close( fd[1] );
+ if ( fd[0] ) {
+ char buf;
+ for ( ;; ) {
+ int n = ::read( fd[0], &buf, 1 );
+ if ( n==1 ) {
+ // socket was not closed => error
+ if ( ::waitpid( pid, 0, WNOHANG ) != pid ) {
+ // The wait did not succeed yet, so try again when we get
+ // the sigchild (to avoid zombies).
+ d->newProc( pid, 0 );
+ }
+ d->proc = 0;
+ goto error;
+ } else if ( n==-1 ) {
+ if ( errno==EAGAIN || errno==EINTR )
+ // try it again
+ continue;
+ }
+ break;
+ }
+ ::close( fd[0] );
+ }
+
+ d->newProc( pid, this );
+
+ if ( comms & Stdin ) {
+ ::close( sStdin[0] );
+ d->proc->socketStdin = sStdin[1];
+
+ // Select non-blocking mode
+ int originalFlags = fcntl(d->proc->socketStdin, F_GETFL, 0);
+ fcntl(d->proc->socketStdin, F_SETFL, originalFlags | O_NONBLOCK);
+
+ d->notifierStdin = new TQSocketNotifier( sStdin[1], TQSocketNotifier::Write );
+ connect( d->notifierStdin, TQT_SIGNAL(activated(int)),
+ this, TQT_SLOT(socketWrite(int)) );
+ // setup notifiers for the sockets
+ if ( !d->stdinBuf.isEmpty() ) {
+ d->notifierStdin->setEnabled( TRUE );
+ }
+ }
+ if ( comms & Stdout ) {
+ ::close( sStdout[1] );
+ d->proc->socketStdout = sStdout[0];
+ d->notifierStdout = new TQSocketNotifier( sStdout[0], TQSocketNotifier::Read );
+ connect( d->notifierStdout, TQT_SIGNAL(activated(int)),
+ this, TQT_SLOT(socketRead(int)) );
+ if ( ioRedirection )
+ d->notifierStdout->setEnabled( TRUE );
+ }
+ if ( comms & Stderr ) {
+ ::close( sStderr[1] );
+ d->proc->socketStderr = sStderr[0];
+ d->notifierStderr = new TQSocketNotifier( sStderr[0], TQSocketNotifier::Read );
+ connect( d->notifierStderr, TQT_SIGNAL(activated(int)),
+ this, TQT_SLOT(socketRead(int)) );
+ if ( ioRedirection )
+ d->notifierStderr->setEnabled( TRUE );
+ }
+
+ // cleanup and return
+ delete[] arglistQ;
+ delete[] arglist;
+ return TRUE;
+
+error:
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::start(): error starting process" );
+#endif
+ if ( d->procManager )
+ d->procManager->cleanup();
+ if ( comms & Stdin ) {
+ ::close( sStdin[1] );
+ ::close( sStdin[0] );
+ }
+ if ( comms & Stdout ) {
+ ::close( sStdout[0] );
+ ::close( sStdout[1] );
+ }
+ if ( comms & Stderr ) {
+ ::close( sStderr[0] );
+ ::close( sStderr[1] );
+ }
+ ::close( fd[0] );
+ ::close( fd[1] );
+ delete[] arglistQ;
+ delete[] arglist;
+ return FALSE;
+}
+
+
+/*!
+ Asks the process to terminate. Processes can ignore this if they
+ wish. If you want to be certain that the process really
+ terminates, you can use kill() instead.
+
+ The slot returns immediately: it does not wait until the process
+ has finished. When the process terminates, the processExited()
+ signal is emitted.
+
+ \sa kill() processExited()
+*/
+void TQProcess::tryTerminate() const
+{
+ if ( d->proc != 0 )
+ ::kill( d->proc->pid, SIGTERM );
+}
+
+/*!
+ Terminates the process. This is not a safe way to end a process
+ since the process will not be able to do any cleanup.
+ tryTerminate() is safer, but processes can ignore a
+ tryTerminate().
+
+ The nice way to end a process and to be sure that it is finished,
+ is to do something like this:
+ \code
+ process->tryTerminate();
+ TQTimer::singleShot( 5000, process, TQT_SLOT( kill() ) );
+ \endcode
+
+ This tries to terminate the process the nice way. If the process
+ is still running after 5 seconds, it terminates the process the
+ hard way. The timeout should be chosen depending on the time the
+ process needs to do all its cleanup: use a higher value if the
+ process is likely to do a lot of computation or I/O on cleanup.
+
+ The slot returns immediately: it does not wait until the process
+ has finished. When the process terminates, the processExited()
+ signal is emitted.
+
+ \sa tryTerminate() processExited()
+*/
+void TQProcess::kill() const
+{
+ if ( d->proc != 0 )
+ ::kill( d->proc->pid, SIGKILL );
+}
+
+/*!
+ Returns TRUE if the process is running; otherwise returns FALSE.
+
+ \sa normalExit() exitqStatus() processExited()
+*/
+bool TQProcess::isRunning() const
+{
+ if ( d->exitValuesCalculated ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::isRunning(): FALSE (already computed)" );
+#endif
+ return FALSE;
+ }
+ if ( d->proc == 0 )
+ return FALSE;
+ int status;
+ if ( ::waitpid( d->proc->pid, &status, WNOHANG ) == d->proc->pid ) {
+ // compute the exit values
+ TQProcess *that = (TQProcess*)this; // mutable
+ that->exitNormal = WIFEXITED( status ) != 0;
+ if ( exitNormal ) {
+ that->exitStat = (char)WEXITSTATUS( status );
+ }
+ d->exitValuesCalculated = TRUE;
+
+ // On heavy processing, the socket notifier for the sigchild might not
+ // have found time to fire yet.
+ if ( d->procManager && d->procManager->sigchldFd[1] < FD_SETSIZE ) {
+ fd_set fds;
+ struct timeval tv;
+ FD_ZERO( &fds );
+ FD_SET( d->procManager->sigchldFd[1], &fds );
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ if ( ::select( d->procManager->sigchldFd[1]+1, &fds, 0, 0, &tv ) > 0 )
+ d->procManager->sigchldHnd( d->procManager->sigchldFd[1] );
+ }
+
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::isRunning() (PID: %d): FALSE", d->proc->pid );
+#endif
+ return FALSE;
+ }
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::isRunning() (PID: %d): TRUE", d->proc->pid );
+#endif
+ return TRUE;
+}
+
+/*!
+ Returns TRUE if it's possible to read an entire line of text from
+ standard output at this time; otherwise returns FALSE.
+
+ \sa readLineStdout() canReadLineStderr()
+*/
+bool TQProcess::canReadLineStdout() const
+{
+ if ( !d->proc || !d->proc->socketStdout )
+ return d->bufStdout.size() != 0;
+
+ TQProcess *that = (TQProcess*)this;
+ return that->membufStdout()->scanNewline( 0 );
+}
+
+/*!
+ Returns TRUE if it's possible to read an entire line of text from
+ standard error at this time; otherwise returns FALSE.
+
+ \sa readLineStderr() canReadLineStdout()
+*/
+bool TQProcess::canReadLineStderr() const
+{
+ if ( !d->proc || !d->proc->socketStderr )
+ return d->bufStderr.size() != 0;
+
+ TQProcess *that = (TQProcess*)this;
+ return that->membufStderr()->scanNewline( 0 );
+}
+
+/*!
+ Writes the data \a buf to the process's standard input. The
+ process may or may not read this data.
+
+ This function always returns immediately. The data you
+ pass to writeToStdin() is copied into an internal memory buffer in
+ TQProcess, and when control goes back to the event loop, TQProcess will
+ starting transferring data from this buffer to the running process. �
+ Sometimes the data will be transferred in several payloads, depending on
+ how much data is read at a time by the process itself. When TQProcess has
+ transferred all the data from its memory buffer to the running process, it
+ emits wroteToStdin().
+
+ Note that some operating systems use a buffer to transfer
+ the data. As a result, wroteToStdin() may be emitted before the
+ running process has actually read all the data.
+
+ \sa wroteToStdin() closeStdin() readStdout() readStderr()
+*/
+void TQProcess::writeToStdin( const TQByteArray& buf )
+{
+#if defined(TQT_TQPROCESS_DEBUG)
+// qDebug( "TQProcess::writeToStdin(): write to stdin (%d)", d->socketStdin );
+#endif
+ d->stdinBuf.enqueue( new TQByteArray(buf) );
+ if ( d->notifierStdin != 0 )
+ d->notifierStdin->setEnabled( TRUE );
+}
+
+
+/*!
+ Closes the process's standard input.
+
+ This function also deletes any pending data that has not been
+ written to standard input.
+
+ \sa wroteToStdin()
+*/
+void TQProcess::closeStdin()
+{
+ if ( d->proc == 0 )
+ return;
+ if ( d->proc->socketStdin !=0 ) {
+ while ( !d->stdinBuf.isEmpty() ) {
+ delete d->stdinBuf.dequeue();
+ }
+ delete d->notifierStdin;
+ d->notifierStdin = 0;
+ if ( ::close( d->proc->socketStdin ) != 0 ) {
+ qWarning( "Could not close stdin of child process" );
+ }
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::closeStdin(): stdin (%d) closed", d->proc->socketStdin );
+#endif
+ d->proc->socketStdin = 0;
+ }
+}
+
+
+/*
+ This private slot is called when the process has outputted data to either
+ standard output or standard error.
+*/
+void TQProcess::socketRead( int fd )
+{
+ if ( d->socketReadCalled ) {
+ // the Q_SLOTS that are connected to the readyRead...() Q_SIGNALS might
+ // trigger a recursive call of socketRead(). Avoid this since you get a
+ // blocking read otherwise.
+ return;
+ }
+
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::socketRead(): %d", fd );
+#endif
+ if ( fd == 0 )
+ return;
+ if ( !d->proc )
+ return;
+ TQMembuf *buffer = 0;
+ int n;
+ if ( fd == d->proc->socketStdout ) {
+ buffer = &d->bufStdout;
+ } else if ( fd == d->proc->socketStderr ) {
+ buffer = &d->bufStderr;
+ } else {
+ // this case should never happen, but just to be safe
+ return;
+ }
+#if defined(TQT_TQPROCESS_DEBUG)
+ uint oldSize = buffer->size();
+#endif
+
+ // try to read data first (if it fails, the filedescriptor was closed)
+ const int basize = 4096;
+ TQByteArray *ba = new TQByteArray( basize );
+ n = ::read( fd, ba->data(), basize );
+ if ( n > 0 ) {
+ ba->resize( n );
+ buffer->append( ba );
+ ba = 0;
+ } else {
+ delete ba;
+ ba = 0;
+ }
+ // eof or error?
+ if ( n == 0 || n == -1 ) {
+ if ( fd == d->proc->socketStdout ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::socketRead(): stdout (%d) closed", fd );
+#endif
+ d->notifierStdout->setEnabled( FALSE );
+ delete d->notifierStdout;
+ d->notifierStdout = 0;
+ ::close( d->proc->socketStdout );
+ d->proc->socketStdout = 0;
+ return;
+ } else if ( fd == d->proc->socketStderr ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::socketRead(): stderr (%d) closed", fd );
+#endif
+ d->notifierStderr->setEnabled( FALSE );
+ delete d->notifierStderr;
+ d->notifierStderr = 0;
+ ::close( d->proc->socketStderr );
+ d->proc->socketStderr = 0;
+ return;
+ }
+ }
+
+ if ( fd < FD_SETSIZE ) {
+ fd_set fds;
+ struct timeval tv;
+ FD_ZERO( &fds );
+ FD_SET( fd, &fds );
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ while ( ::select( fd+1, &fds, 0, 0, &tv ) > 0 ) {
+ // prepare for the next round
+ FD_ZERO( &fds );
+ FD_SET( fd, &fds );
+ // read data
+ ba = new TQByteArray( basize );
+ n = ::read( fd, ba->data(), basize );
+ if ( n > 0 ) {
+ ba->resize( n );
+ buffer->append( ba );
+ ba = 0;
+ } else {
+ delete ba;
+ ba = 0;
+ break;
+ }
+ }
+ }
+
+ d->socketReadCalled = TRUE;
+ if ( fd == d->proc->socketStdout ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::socketRead(): %d bytes read from stdout (%d)",
+ buffer->size()-oldSize, fd );
+#endif
+ emit readyReadStdout();
+ } else if ( fd == d->proc->socketStderr ) {
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::socketRead(): %d bytes read from stderr (%d)",
+ buffer->size()-oldSize, fd );
+#endif
+ emit readyReadStderr();
+ }
+ d->socketReadCalled = FALSE;
+}
+
+
+/*
+ This private slot is called when the process tries to read data from standard
+ input.
+*/
+void TQProcess::socketWrite( int fd )
+{
+ while ( fd == d->proc->socketStdin && d->proc->socketStdin != 0 ) {
+ if ( d->stdinBuf.isEmpty() ) {
+ d->notifierStdin->setEnabled( FALSE );
+ return;
+ }
+ ssize_t ret = ::write( fd,
+ d->stdinBuf.head()->data() + d->stdinBufRead,
+ d->stdinBuf.head()->size() - d->stdinBufRead );
+#if defined(TQT_TQPROCESS_DEBUG)
+ qDebug( "TQProcess::socketWrite(): wrote %d bytes to stdin (%d)", ret, fd );
+#endif
+ if ( ret == -1 )
+ return;
+ d->stdinBufRead += ret;
+ if ( d->stdinBufRead == (ssize_t)d->stdinBuf.head()->size() ) {
+ d->stdinBufRead = 0;
+ delete d->stdinBuf.dequeue();
+ if ( wroteToStdinConnected && d->stdinBuf.isEmpty() )
+ emit wroteToStdin();
+ }
+ }
+}
+
+/*!
+ \internal
+ Flushes standard input. This is useful if you want to use TQProcess in a
+ synchronous manner.
+
+ This function should probably go into the public API.
+*/
+void TQProcess::flushStdin()
+{
+ if (d->proc)
+ socketWrite(d->proc->socketStdin);
+}
+
+/*
+ This private slot is only used under Windows (but tqmoc does not know about #if
+ defined()).
+*/
+void TQProcess::timeout()
+{
+}
+
+
+/*
+ This private function is used by connectNotify() and disconnectNotify() to
+ change the value of ioRedirection (and related behaviour)
+*/
+void TQProcess::setIoRedirection( bool value )
+{
+ ioRedirection = value;
+ if ( ioRedirection ) {
+ if ( d->notifierStdout )
+ d->notifierStdout->setEnabled( TRUE );
+ if ( d->notifierStderr )
+ d->notifierStderr->setEnabled( TRUE );
+ } else {
+ if ( d->notifierStdout )
+ d->notifierStdout->setEnabled( FALSE );
+ if ( d->notifierStderr )
+ d->notifierStderr->setEnabled( FALSE );
+ }
+}
+
+/*
+ This private function is used by connectNotify() and
+ disconnectNotify() to change the value of notifyOnExit (and related
+ behaviour)
+*/
+void TQProcess::setNotifyOnExit( bool value )
+{
+ notifyOnExit = value;
+}
+
+/*
+ This private function is used by connectNotify() and disconnectNotify() to
+ change the value of wroteToStdinConnected (and related behaviour)
+*/
+void TQProcess::setWroteStdinConnected( bool value )
+{
+ wroteToStdinConnected = value;
+}
+
+/*! \enum TQProcess::PID
+ \internal
+*/
+/*!
+ Returns platform dependent information about the process. This can
+ be used together with platform specific system calls.
+
+ Under Unix the return value is the PID of the process, or -1 if no
+ process belongs to this object.
+
+ Under Windows it is a pointer to the \c PROCESS_INFORMATION
+ struct, or 0 if no process is belongs to this object.
+
+ Use of this function's return value is likely to be non-portable.
+*/
+TQProcess::PID TQProcess::processIdentifier()
+{
+ if ( d->proc == 0 )
+ return -1;
+ return d->proc->pid;
+}
+
+#endif // TQT_NO_PROCESS
diff --git a/tqtinterface/qt4/src/kernel/tqpsprinter.cpp b/tqtinterface/qt4/src/kernel/tqpsprinter.cpp
new file mode 100644
index 0000000..18227cf
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpsprinter.cpp
@@ -0,0 +1,6595 @@
+/**********************************************************************
+**
+** Implementation of TQPSPrinter class
+**
+** Created : 941003
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// POSIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+#include "tqpsprinter_p.h"
+
+#ifdef USE_QT4
+
+static bool qt_gen_epsf = FALSE;
+
+TQ_EXPORT void qt_generate_epsf( bool b )
+{
+ qt_gen_epsf = b;
+}
+
+#else // USE_QT4
+
+#ifndef TQT_NO_PRINTER
+
+#undef TQ_PRINTER_USE_TYPE42
+
+#include "tqpainter.h"
+#include "tqapplication.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqimage.h"
+#include "tqdatetime.h"
+#include "tqstring.h"
+#include "tqdict.h"
+#include "tqmemarray.h"
+#include "tqfile.h"
+#include "tqbuffer.h"
+#include "tqintdict.h"
+#include "tqtextcodec.h"
+#include "tqsettings.h"
+#include "tqmap.h"
+#include "tqfontdatabase.h"
+#include "tqregexp.h"
+#include "tqbitmap.h"
+#include <private/tqunicodetables_p.h>
+
+#if defined(TQ_OS_WIN32)
+#include <io.h>
+#ifdef TQ_PRINTER_USE_TYPE42
+#include <stdlib.h>
+#endif
+#else
+#include <unistd.h>
+#include <stdlib.h>
+#endif
+
+#ifdef TQ_WS_X11
+#include "tqt_x11_p.h"
+#ifdef None
+#undef None
+#endif
+#ifdef GrayScale
+#undef GrayScale
+#endif
+#endif
+
+#if defined( TQ_WS_X11 ) || defined (TQ_WS_TQWS)
+#include "tqfontdata_p.h"
+#include "tqfontengine_p.h"
+#include "tqtextlayout_p.h"
+#include "tqtextengine_p.h"
+extern bool qt_has_xft;
+#endif
+
+static bool qt_gen_epsf = FALSE;
+static bool embedFonts = TRUE;
+
+TQ_EXPORT void qt_generate_epsf( bool b )
+{
+ qt_gen_epsf = b;
+}
+
+static const char *const ps_header =
+"/d/def load def/D{bind d}bind d/d2{dup dup}D/B{0 d2}D/W{255 d2}D/ED{exch d}D\n"
+"/D0{0 ED}D/LT{lineto}D/MT{moveto}D/S{stroke}D/F{setfont}D/SW{setlinewidth}D\n"
+"/CP{closepath}D/RL{rlineto}D/NP{newpath}D/CM{currentmatrix}D/SM{setmatrix}D\n"
+"/TR{translate}D/SD{setdash}D/SC{aload pop setrgbcolor}D/CR{currentfile read\n"
+"pop}D/i{index}D/bs{bitshift}D/scs{setcolorspace}D/DB{dict dup begin}D/DE{end\n"
+"d}D/ie{ifelse}D/sp{astore pop}D/BSt 0 d/LWi 1 d/PSt 1 d/Cx 0 d/Cy 0 d/WFi\n"
+"false d/OMo false d/BCol[1 1 1]d/PCol[0 0 0]d/BkCol[1 1 1]d/BDArr[0.94 0.88\n"
+"0.63 0.50 0.37 0.12 0.06]d/defM matrix d/nS 0 d/GPS{PSt 1 ge PSt 5 le and{{\n"
+"LArr PSt 1 sub 2 mul get}{LArr PSt 2 mul 1 sub get}ie}{[]}ie}D/QS{PSt 0 ne{\n"
+"gsave LWi SW true GPS 0 SD S OMo PSt 1 ne and{BkCol SC false GPS dup 0 get\n"
+"SD S}if grestore}if}D/r28{{CR dup 32 gt{exit}if pop}loop 3{CR}repeat 0 4{7\n"
+"bs exch dup 128 gt{84 sub}if 42 sub 127 and add}repeat}D/rA 0 d/rL 0 d/rB{rL\n"
+"0 eq{/rA r28 d/rL 28 d}if dup rL gt{rA exch rL sub rL exch/rA 0 d/rL 0 d rB\n"
+"exch bs add}{dup rA 16#fffffff 3 -1 roll bs not and exch dup rL exch sub/rL\n"
+"ED neg rA exch bs/rA ED}ie}D/uc{/rL 0 d 0{dup 2 i length ge{exit}if 1 rB 1\n"
+"eq{3 rB dup 3 ge{1 add dup rB 1 i 5 ge{1 i 6 ge{1 i 7 ge{1 i 8 ge{128 add}if\n"
+"64 add}if 32 add}if 16 add}if 3 add exch pop}if 3 add exch 10 rB 1 add{dup 3\n"
+"i lt{dup}{2 i}ie 4 i 3 i 3 i sub 2 i getinterval 5 i 4 i 3 -1 roll\n"
+"putinterval dup 4 -1 roll add 3 1 roll 4 -1 roll exch sub dup 0 eq{exit}if 3\n"
+"1 roll}loop pop pop}{3 rB 1 add{2 copy 8 rB put 1 add}repeat}ie}loop pop}D\n"
+"/sl D0/TQCIgray D0/TQCIcolor D0/TQCIindex D0/TQCI{/colorimage where{pop false 3\n"
+"colorimage}{exec/TQCIcolor ED/TQCIgray TQCIcolor length 3 idiv string d 0 1\n"
+"TQCIcolor length 3 idiv 1 sub{/TQCIindex ED/x TQCIindex 3 mul d TQCIgray\n"
+"TQCIindex TQCIcolor x get 0.30 mul TQCIcolor x 1 add get 0.59 mul TQCIcolor x 2\n"
+"add get 0.11 mul add add cvi put}for TQCIgray image}ie}D/di{gsave TR 1 i 1 eq\n"
+"{false eq{pop true 3 1 roll 4 i 4 i false 4 i 4 i imagetqmask BkCol SC\n"
+"imagetqmask}{pop false 3 1 roll imagetqmask}ie}{dup false ne{/languagelevel\n"
+"where{pop languagelevel 3 ge}{false}ie}{false}ie{/ma ED 8 eq{/dc[0 1]d\n"
+"/DeviceGray}{/dc[0 1 0 1 0 1]d/DeviceRGB}ie scs/im ED/mt ED/h ED/w ED/id 7\n"
+"DB/ImageType 1 d/Width w d/Height h d/ImageMatrix mt d/DataSource im d\n"
+"/BitsPerComponent 8 d/Decode dc d DE/md 7 DB/ImageType 1 d/Width w d/Height\n"
+"h d/ImageMatrix mt d/DataSource ma d/BitsPerComponent 1 d/Decode[0 1]d DE 4\n"
+"DB/ImageType 3 d/DataDict id d/MaskDict md d/InterleaveType 3 d end image}{\n"
+"pop 8 4 1 roll 8 eq{image}{TQCI}ie}ie}ie grestore}d/BF{gsave BSt 1 eq{BCol SC\n"
+"WFi{fill}{eofill}ie}if BSt 2 ge BSt 8 le and{BDArr BSt 2 sub get/sc ED BCol{\n"
+"1. exch sub sc mul 1. exch sub}forall 3 array astore SC WFi{fill}{eofill}ie}\n"
+"if BSt 9 ge BSt 14 le and{WFi{clip}{eoclip}ie defM SM pathbbox 3 i 3 i TR 4\n"
+"2 roll 3 2 roll exch sub/h ED sub/w ED OMo{NP 0 0 MT 0 h RL w 0 RL 0 h neg\n"
+"RL CP BkCol SC fill}if BCol SC 0.3 SW NP BSt 9 eq BSt 11 eq or{0 4 h{dup 0\n"
+"exch MT w exch LT}for}if BSt 10 eq BSt 11 eq or{0 4 w{dup 0 MT h LT}for}if\n"
+"BSt 12 eq BSt 14 eq or{w h gt{0 6 w h add{dup 0 MT h sub h LT}for}{0 6 w h\n"
+"add{dup 0 exch MT w sub w exch LT}for}ie}if BSt 13 eq BSt 14 eq or{w h gt{0\n"
+"6 w h add{dup h MT h sub 0 LT}for}{0 6 w h add{dup w exch MT w sub 0 exch LT\n"
+"}for}ie}if S}if BSt 24 eq{}if grestore}D/mat matrix d/ang1 D0/ang2 D0/w D0/h\n"
+"D0/x D0/y D0/ARC{/ang2 ED/ang1 ED/h ED/w ED/y ED/x ED mat CM pop x w 2 div\n"
+"add y h 2 div add TR 1 h w div neg scale ang2 0 ge{0 0 w 2 div ang1 ang1\n"
+"ang2 add arc}{0 0 w 2 div ang1 ang1 ang2 add arcn}ie mat SM}D/C D0/P{NP MT\n"
+"0.5 0.5 rmoveto 0 -1 RL -1 0 RL 0 1 RL CP fill}D/M{/Cy ED/Cx ED}D/L{NP Cx Cy\n"
+"MT/Cy ED/Cx ED Cx Cy LT QS}D/DL{NP MT LT QS}D/HL{1 i DL}D/VL{2 i exch DL}D/R\n"
+"{/h ED/w ED/y ED/x ED NP x y MT 0 h RL w 0 RL 0 h neg RL CP BF QS}D/ACR{/h\n"
+"ED/w ED/y ED/x ED x y MT 0 h RL w 0 RL 0 h neg RL CP}D/xr D0/yr D0/rx D0/ry\n"
+"D0/rx2 D0/ry2 D0/RR{/yr ED/xr ED/h ED/w ED/y ED/x ED xr 0 le yr 0 le or{x y\n"
+"w h R}{xr 100 ge yr 100 ge or{x y w h E}{/rx xr w mul 200 div d/ry yr h mul\n"
+"200 div d/rx2 rx 2 mul d/ry2 ry 2 mul d NP x rx add y MT x y rx2 ry2 180 -90\n"
+"x y h add ry2 sub rx2 ry2 270 -90 x w add rx2 sub y h add ry2 sub rx2 ry2 0\n"
+"-90 x w add rx2 sub y rx2 ry2 90 -90 ARC ARC ARC ARC CP BF QS}ie}ie}D/E{/h\n"
+"ED/w ED/y ED/x ED mat CM pop x w 2 div add y h 2 div add TR 1 h w div scale\n"
+"NP 0 0 w 2 div 0 360 arc mat SM BF QS}D/A{16 div exch 16 div exch NP ARC QS}\n"
+"D/PIE{/ang2 ED/ang1 ED/h ED/w ED/y ED/x ED NP x w 2 div add y h 2 div add MT\n"
+"x y w h ang1 16 div ang2 16 div ARC CP BF QS}D/CH{16 div exch 16 div exch NP\n"
+"ARC CP BF QS}D/BZ{curveto QS}D/CRGB{255 div 3 1 roll 255 div 3 1 roll 255\n"
+"div 3 1 roll}D/BC{CRGB BkCol sp}D/BR{CRGB BCol sp/BSt ED}D/WB{1 W BR}D/NB{0\n"
+"B BR}D/PE{setlinejoin setlinecap CRGB PCol sp/LWi ED/PSt ED LWi 0 eq{0.25\n"
+"/LWi ED}if PCol SC}D/P1{1 0 5 2 roll 0 0 PE}D/ST{defM SM concat}D/MF{true\n"
+"exch true exch{exch pop exch pop dup 0 get dup tqfindfont dup/FontName get 3\n"
+"-1 roll eq{exit}if}forall exch dup 1 get/fxscale ED 2 get/fslant ED exch\n"
+"/fencoding ED[fxscale 0 fslant 1 0 0]makefont fencoding false eq{}{dup\n"
+"maxlength dict begin{1 i/FID ne{def}{pop pop}ifelse}forall/Encoding\n"
+"fencoding d currentdict end}ie definefont pop}D/MFEmb{tqfindfont dup length\n"
+"dict begin{1 i/FID ne{d}{pop pop}ifelse}forall/Encoding ED currentdict end\n"
+"definefont pop}D/DF{tqfindfont/fs 3 -1 roll d[fs 0 0 fs -1 mul 0 0]makefont d}\n"
+"D/ty 0 d/Y{/ty ED}D/Tl{gsave SW NP 1 i exch MT 1 i 0 RL S grestore}D/XYT{ty\n"
+"MT/xyshow where{pop pop xyshow}{exch pop 1 i dup length 2 div exch\n"
+"stringwidth pop 3 -1 roll exch sub exch div exch 0 exch ashow}ie}D/AT{ty MT\n"
+"1 i dup length 2 div exch stringwidth pop 3 -1 roll exch sub exch div exch 0\n"
+"exch ashow}D/QI{/C save d pageinit/Cx 0 d/Cy 0 d/OMo false d}D/QP{C restore\n"
+"showpage}D/SPD{/setpagetqdevice where{1 DB 3 1 roll d end setpagetqdevice}{pop\n"
+"pop}ie}D/SV{BSt LWi PSt Cx Cy WFi OMo BCol PCol BkCol/nS nS 1 add d gsave}D\n"
+"/RS{nS 0 gt{grestore/BkCol ED/PCol ED/BCol ED/OMo ED/WFi ED/Cy ED/Cx ED/PSt\n"
+"ED/LWi ED/BSt ED/nS nS 1 sub d}if}D/CLSTART{/clipTmp matrix CM d defM SM NP}\n"
+"D/CLEND{clip NP clipTmp SM}D/CLO{grestore gsave defM SM}D\n";
+
+// the next table is derived from a list provided by Adobe on its web
+// server: http://partners.adobe.com/asn/developer/typeforum/glyphlist.txt
+
+// the start of the header comment:
+//
+// Name: Adobe Glyph List
+// Table version: 1.2
+// Date: 22 Oct 1998
+//
+// Description:
+//
+// The Adobe Glyph List (AGL) list relates Unicode values (UVs) to glyph
+// names, and should be used only as described in the document "Unicode and
+// Glyph Names," at
+// http://partners.adobe.com:80/asn/developer/type/tqunicodegn.html
+//
+// IMPORTANT NOTE:
+// the list tqcontains glyphs in the private use area of tqunicode. These should get removed when regenerating the glyphlist.
+// also 0 shout be mapped to .notdef
+static const struct {
+ TQ_UINT16 u;
+ const char * g;
+} tqunicodetoglyph[] = {
+ // grep '^[0-9A-F][0-9A-F][0-9A-F][0-9A-F];' < /tmp/glyphlist.txt | sed -e 's/;/, "/' -e 's-;-" }, // -' -e 's/^/ { 0x/' | sort
+ { 0x0000, ".notdef" },
+ { 0x0020, "space" }, // SPACE
+ { 0x0021, "exclam" }, // EXCLAMATION MARK
+ { 0x0022, "quotedbl" }, // TQUOTATION MARK
+ { 0x0023, "numbersign" }, // NUMBER SIGN
+ { 0x0024, "dollar" }, // DOLLAR SIGN
+ { 0x0025, "percent" }, // PERCENT SIGN
+ { 0x0026, "ampersand" }, // AMPERSAND
+ { 0x0027, "quotesingle" }, // APOSTROPHE
+ { 0x0028, "parenleft" }, // LEFT PARENTHESIS
+ { 0x0029, "parenright" }, // RIGHT PARENTHESIS
+ { 0x002A, "asterisk" }, // ASTERISK
+ { 0x002B, "plus" }, // PLUS SIGN
+ { 0x002C, "comma" }, // COMMA
+ { 0x002D, "hyphen" }, // HYPHEN-MINUS
+ { 0x002E, "period" }, // FULL STOP
+ { 0x002F, "slash" }, // SOLIDUS
+ { 0x0030, "zero" }, // DIGIT ZERO
+ { 0x0031, "one" }, // DIGIT ONE
+ { 0x0032, "two" }, // DIGIT TWO
+ { 0x0033, "three" }, // DIGIT THREE
+ { 0x0034, "four" }, // DIGIT FOUR
+ { 0x0035, "five" }, // DIGIT FIVE
+ { 0x0036, "six" }, // DIGIT SIX
+ { 0x0037, "seven" }, // DIGIT SEVEN
+ { 0x0038, "eight" }, // DIGIT EIGHT
+ { 0x0039, "nine" }, // DIGIT NINE
+ { 0x003A, "colon" }, // COLON
+ { 0x003B, "semicolon" }, // SEMICOLON
+ { 0x003C, "less" }, // LESS-THAN SIGN
+ { 0x003D, "equal" }, // ETQUALS SIGN
+ { 0x003E, "greater" }, // GREATER-THAN SIGN
+ { 0x003F, "question" }, // TQUESTION MARK
+ { 0x0040, "at" }, // COMMERCIAL AT
+ { 0x0041, "A" }, // LATIN CAPITAL LETTER A
+ { 0x0042, "B" }, // LATIN CAPITAL LETTER B
+ { 0x0043, "C" }, // LATIN CAPITAL LETTER C
+ { 0x0044, "D" }, // LATIN CAPITAL LETTER D
+ { 0x0045, "E" }, // LATIN CAPITAL LETTER E
+ { 0x0046, "F" }, // LATIN CAPITAL LETTER F
+ { 0x0047, "G" }, // LATIN CAPITAL LETTER G
+ { 0x0048, "H" }, // LATIN CAPITAL LETTER H
+ { 0x0049, "I" }, // LATIN CAPITAL LETTER I
+ { 0x004A, "J" }, // LATIN CAPITAL LETTER J
+ { 0x004B, "K" }, // LATIN CAPITAL LETTER K
+ { 0x004C, "L" }, // LATIN CAPITAL LETTER L
+ { 0x004D, "M" }, // LATIN CAPITAL LETTER M
+ { 0x004E, "N" }, // LATIN CAPITAL LETTER N
+ { 0x004F, "O" }, // LATIN CAPITAL LETTER O
+ { 0x0050, "P" }, // LATIN CAPITAL LETTER P
+ { 0x0051, "Q" }, // LATIN CAPITAL LETTER Q
+ { 0x0052, "R" }, // LATIN CAPITAL LETTER R
+ { 0x0053, "S" }, // LATIN CAPITAL LETTER S
+ { 0x0054, "T" }, // LATIN CAPITAL LETTER T
+ { 0x0055, "U" }, // LATIN CAPITAL LETTER U
+ { 0x0056, "V" }, // LATIN CAPITAL LETTER V
+ { 0x0057, "W" }, // LATIN CAPITAL LETTER W
+ { 0x0058, "X" }, // LATIN CAPITAL LETTER X
+ { 0x0059, "Y" }, // LATIN CAPITAL LETTER Y
+ { 0x005A, "Z" }, // LATIN CAPITAL LETTER Z
+ { 0x005B, "bracketleft" }, // LEFT STQUARE BRACKET
+ { 0x005C, "backslash" }, // REVERSE SOLIDUS
+ { 0x005D, "bracketright" }, // RIGHT STQUARE BRACKET
+ { 0x005E, "asciicircum" }, // CIRCUMFLEX ACCENT
+ { 0x005F, "underscore" }, // LOW LINE
+ { 0x0060, "grave" }, // GRAVE ACCENT
+ { 0x0061, "a" }, // LATIN SMALL LETTER A
+ { 0x0062, "b" }, // LATIN SMALL LETTER B
+ { 0x0063, "c" }, // LATIN SMALL LETTER C
+ { 0x0064, "d" }, // LATIN SMALL LETTER D
+ { 0x0065, "e" }, // LATIN SMALL LETTER E
+ { 0x0066, "f" }, // LATIN SMALL LETTER F
+ { 0x0067, "g" }, // LATIN SMALL LETTER G
+ { 0x0068, "h" }, // LATIN SMALL LETTER H
+ { 0x0069, "i" }, // LATIN SMALL LETTER I
+ { 0x006A, "j" }, // LATIN SMALL LETTER J
+ { 0x006B, "k" }, // LATIN SMALL LETTER K
+ { 0x006C, "l" }, // LATIN SMALL LETTER L
+ { 0x006D, "m" }, // LATIN SMALL LETTER M
+ { 0x006E, "n" }, // LATIN SMALL LETTER N
+ { 0x006F, "o" }, // LATIN SMALL LETTER O
+ { 0x0070, "p" }, // LATIN SMALL LETTER P
+ { 0x0071, "q" }, // LATIN SMALL LETTER Q
+ { 0x0072, "r" }, // LATIN SMALL LETTER R
+ { 0x0073, "s" }, // LATIN SMALL LETTER S
+ { 0x0074, "t" }, // LATIN SMALL LETTER T
+ { 0x0075, "u" }, // LATIN SMALL LETTER U
+ { 0x0076, "v" }, // LATIN SMALL LETTER V
+ { 0x0077, "w" }, // LATIN SMALL LETTER W
+ { 0x0078, "x" }, // LATIN SMALL LETTER X
+ { 0x0079, "y" }, // LATIN SMALL LETTER Y
+ { 0x007A, "z" }, // LATIN SMALL LETTER Z
+ { 0x007B, "braceleft" }, // LEFT CURLY BRACKET
+ { 0x007C, "bar" }, // VERTICAL LINE
+ { 0x007D, "braceright" }, // RIGHT CURLY BRACKET
+ { 0x007E, "asciitilde" }, // TILDE
+ { 0x00A0, "space" }, // NO-BREAK SPACE;Duplicate
+ { 0x00A1, "exclamdown" }, // INVERTED EXCLAMATION MARK
+ { 0x00A2, "cent" }, // CENT SIGN
+ { 0x00A3, "sterling" }, // POUND SIGN
+ { 0x00A4, "currency" }, // CURRENCY SIGN
+ { 0x00A5, "yen" }, // YEN SIGN
+ { 0x00A6, "brokenbar" }, // BROKEN BAR
+ { 0x00A7, "section" }, // SECTION SIGN
+ { 0x00A8, "dieresis" }, // DIAERESIS
+ { 0x00A9, "copyright" }, // COPYRIGHT SIGN
+ { 0x00AA, "ordfeminine" }, // FEMININE ORDINAL INDICATOR
+ { 0x00AB, "guillemotleft" }, // LEFT-POINTING DOUBLE ANGLE TQUOTATION MARK
+ { 0x00AC, "logicalnot" }, // NOT SIGN
+ { 0x00AD, "hyphen" }, // SOFT HYPHEN;Duplicate
+ { 0x00AE, "registered" }, // REGISTERED SIGN
+ { 0x00AF, "macron" }, // MACRON
+ { 0x00B0, "degree" }, // DEGREE SIGN
+ { 0x00B1, "plusminus" }, // PLUS-MINUS SIGN
+ { 0x00B2, "twosuperior" }, // SUPERSCRIPT TWO
+ { 0x00B3, "threesuperior" }, // SUPERSCRIPT THREE
+ { 0x00B4, "acute" }, // ACUTE ACCENT
+ { 0x00B5, "mu" }, // MICRO SIGN
+ { 0x00B6, "paragraph" }, // PILCROW SIGN
+ { 0x00B7, "periodcentered" }, // MIDDLE DOT
+ { 0x00B8, "cedilla" }, // CEDILLA
+ { 0x00B9, "onesuperior" }, // SUPERSCRIPT ONE
+ { 0x00BA, "ordmasculine" }, // MASCULINE ORDINAL INDICATOR
+ { 0x00BB, "guillemotright" }, // RIGHT-POINTING DOUBLE ANGLE TQUOTATION MARK
+ { 0x00BC, "onequarter" }, // VULGAR FRACTION ONE TQUARTER
+ { 0x00BD, "onehalf" }, // VULGAR FRACTION ONE HALF
+ { 0x00BE, "threequarters" }, // VULGAR FRACTION THREE TQUARTERS
+ { 0x00BF, "questiondown" }, // INVERTED TQUESTION MARK
+ { 0x00C0, "Agrave" }, // LATIN CAPITAL LETTER A WITH GRAVE
+ { 0x00C1, "Aacute" }, // LATIN CAPITAL LETTER A WITH ACUTE
+ { 0x00C2, "Acircumflex" }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+ { 0x00C3, "Atilde" }, // LATIN CAPITAL LETTER A WITH TILDE
+ { 0x00C4, "Adieresis" }, // LATIN CAPITAL LETTER A WITH DIAERESIS
+ { 0x00C5, "Aring" }, // LATIN CAPITAL LETTER A WITH RING ABOVE
+ { 0x00C6, "AE" }, // LATIN CAPITAL LETTER AE
+ { 0x00C7, "Ccedilla" }, // LATIN CAPITAL LETTER C WITH CEDILLA
+ { 0x00C8, "Egrave" }, // LATIN CAPITAL LETTER E WITH GRAVE
+ { 0x00C9, "Eacute" }, // LATIN CAPITAL LETTER E WITH ACUTE
+ { 0x00CA, "Ecircumflex" }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+ { 0x00CB, "Edieresis" }, // LATIN CAPITAL LETTER E WITH DIAERESIS
+ { 0x00CC, "Igrave" }, // LATIN CAPITAL LETTER I WITH GRAVE
+ { 0x00CD, "Iacute" }, // LATIN CAPITAL LETTER I WITH ACUTE
+ { 0x00CE, "Icircumflex" }, // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+ { 0x00CF, "Idieresis" }, // LATIN CAPITAL LETTER I WITH DIAERESIS
+ { 0x00D0, "Eth" }, // LATIN CAPITAL LETTER ETH
+ { 0x00D1, "Ntilde" }, // LATIN CAPITAL LETTER N WITH TILDE
+ { 0x00D2, "Ograve" }, // LATIN CAPITAL LETTER O WITH GRAVE
+ { 0x00D3, "Oacute" }, // LATIN CAPITAL LETTER O WITH ACUTE
+ { 0x00D4, "Ocircumflex" }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+ { 0x00D5, "Otilde" }, // LATIN CAPITAL LETTER O WITH TILDE
+ { 0x00D6, "Odieresis" }, // LATIN CAPITAL LETTER O WITH DIAERESIS
+ { 0x00D7, "multiply" }, // MULTIPLICATION SIGN
+ { 0x00D8, "Oslash" }, // LATIN CAPITAL LETTER O WITH STROKE
+ { 0x00D9, "Ugrave" }, // LATIN CAPITAL LETTER U WITH GRAVE
+ { 0x00DA, "Uacute" }, // LATIN CAPITAL LETTER U WITH ACUTE
+ { 0x00DB, "Ucircumflex" }, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+ { 0x00DC, "Udieresis" }, // LATIN CAPITAL LETTER U WITH DIAERESIS
+ { 0x00DD, "Yacute" }, // LATIN CAPITAL LETTER Y WITH ACUTE
+ { 0x00DE, "Thorn" }, // LATIN CAPITAL LETTER THORN
+ { 0x00DF, "germandbls" }, // LATIN SMALL LETTER SHARP S
+ { 0x00E0, "agrave" }, // LATIN SMALL LETTER A WITH GRAVE
+ { 0x00E1, "aacute" }, // LATIN SMALL LETTER A WITH ACUTE
+ { 0x00E2, "acircumflex" }, // LATIN SMALL LETTER A WITH CIRCUMFLEX
+ { 0x00E3, "atilde" }, // LATIN SMALL LETTER A WITH TILDE
+ { 0x00E4, "adieresis" }, // LATIN SMALL LETTER A WITH DIAERESIS
+ { 0x00E5, "aring" }, // LATIN SMALL LETTER A WITH RING ABOVE
+ { 0x00E6, "ae" }, // LATIN SMALL LETTER AE
+ { 0x00E7, "ccedilla" }, // LATIN SMALL LETTER C WITH CEDILLA
+ { 0x00E8, "egrave" }, // LATIN SMALL LETTER E WITH GRAVE
+ { 0x00E9, "eacute" }, // LATIN SMALL LETTER E WITH ACUTE
+ { 0x00EA, "ecircumflex" }, // LATIN SMALL LETTER E WITH CIRCUMFLEX
+ { 0x00EB, "edieresis" }, // LATIN SMALL LETTER E WITH DIAERESIS
+ { 0x00EC, "igrave" }, // LATIN SMALL LETTER I WITH GRAVE
+ { 0x00ED, "iacute" }, // LATIN SMALL LETTER I WITH ACUTE
+ { 0x00EE, "icircumflex" }, // LATIN SMALL LETTER I WITH CIRCUMFLEX
+ { 0x00EF, "idieresis" }, // LATIN SMALL LETTER I WITH DIAERESIS
+ { 0x00F0, "eth" }, // LATIN SMALL LETTER ETH
+ { 0x00F1, "ntilde" }, // LATIN SMALL LETTER N WITH TILDE
+ { 0x00F2, "ograve" }, // LATIN SMALL LETTER O WITH GRAVE
+ { 0x00F3, "oacute" }, // LATIN SMALL LETTER O WITH ACUTE
+ { 0x00F4, "ocircumflex" }, // LATIN SMALL LETTER O WITH CIRCUMFLEX
+ { 0x00F5, "otilde" }, // LATIN SMALL LETTER O WITH TILDE
+ { 0x00F6, "odieresis" }, // LATIN SMALL LETTER O WITH DIAERESIS
+ { 0x00F7, "divide" }, // DIVISION SIGN
+ { 0x00F8, "oslash" }, // LATIN SMALL LETTER O WITH STROKE
+ { 0x00F9, "ugrave" }, // LATIN SMALL LETTER U WITH GRAVE
+ { 0x00FA, "uacute" }, // LATIN SMALL LETTER U WITH ACUTE
+ { 0x00FB, "ucircumflex" }, // LATIN SMALL LETTER U WITH CIRCUMFLEX
+ { 0x00FC, "udieresis" }, // LATIN SMALL LETTER U WITH DIAERESIS
+ { 0x00FD, "yacute" }, // LATIN SMALL LETTER Y WITH ACUTE
+ { 0x00FE, "thorn" }, // LATIN SMALL LETTER THORN
+ { 0x00FF, "ydieresis" }, // LATIN SMALL LETTER Y WITH DIAERESIS
+ { 0x0100, "Amacron" }, // LATIN CAPITAL LETTER A WITH MACRON
+ { 0x0101, "amacron" }, // LATIN SMALL LETTER A WITH MACRON
+ { 0x0102, "Abreve" }, // LATIN CAPITAL LETTER A WITH BREVE
+ { 0x0103, "abreve" }, // LATIN SMALL LETTER A WITH BREVE
+ { 0x0104, "Aogonek" }, // LATIN CAPITAL LETTER A WITH OGONEK
+ { 0x0105, "aogonek" }, // LATIN SMALL LETTER A WITH OGONEK
+ { 0x0106, "Cacute" }, // LATIN CAPITAL LETTER C WITH ACUTE
+ { 0x0107, "cacute" }, // LATIN SMALL LETTER C WITH ACUTE
+ { 0x0108, "Ccircumflex" }, // LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+ { 0x0109, "ccircumflex" }, // LATIN SMALL LETTER C WITH CIRCUMFLEX
+ { 0x010A, "Cdotaccent" }, // LATIN CAPITAL LETTER C WITH DOT ABOVE
+ { 0x010B, "cdotaccent" }, // LATIN SMALL LETTER C WITH DOT ABOVE
+ { 0x010C, "Ccaron" }, // LATIN CAPITAL LETTER C WITH CARON
+ { 0x010D, "ccaron" }, // LATIN SMALL LETTER C WITH CARON
+ { 0x010E, "Dcaron" }, // LATIN CAPITAL LETTER D WITH CARON
+ { 0x010F, "dcaron" }, // LATIN SMALL LETTER D WITH CARON
+ { 0x0110, "Dcroat" }, // LATIN CAPITAL LETTER D WITH STROKE
+ { 0x0111, "dcroat" }, // LATIN SMALL LETTER D WITH STROKE
+ { 0x0112, "Emacron" }, // LATIN CAPITAL LETTER E WITH MACRON
+ { 0x0113, "emacron" }, // LATIN SMALL LETTER E WITH MACRON
+ { 0x0114, "Ebreve" }, // LATIN CAPITAL LETTER E WITH BREVE
+ { 0x0115, "ebreve" }, // LATIN SMALL LETTER E WITH BREVE
+ { 0x0116, "Edotaccent" }, // LATIN CAPITAL LETTER E WITH DOT ABOVE
+ { 0x0117, "edotaccent" }, // LATIN SMALL LETTER E WITH DOT ABOVE
+ { 0x0118, "Eogonek" }, // LATIN CAPITAL LETTER E WITH OGONEK
+ { 0x0119, "eogonek" }, // LATIN SMALL LETTER E WITH OGONEK
+ { 0x011A, "Ecaron" }, // LATIN CAPITAL LETTER E WITH CARON
+ { 0x011B, "ecaron" }, // LATIN SMALL LETTER E WITH CARON
+ { 0x011C, "Gcircumflex" }, // LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+ { 0x011D, "gcircumflex" }, // LATIN SMALL LETTER G WITH CIRCUMFLEX
+ { 0x011E, "Gbreve" }, // LATIN CAPITAL LETTER G WITH BREVE
+ { 0x011F, "gbreve" }, // LATIN SMALL LETTER G WITH BREVE
+ { 0x0120, "Gdotaccent" }, // LATIN CAPITAL LETTER G WITH DOT ABOVE
+ { 0x0121, "gdotaccent" }, // LATIN SMALL LETTER G WITH DOT ABOVE
+ { 0x0122, "Gcommaaccent" }, // LATIN CAPITAL LETTER G WITH CEDILLA
+ { 0x0123, "gcommaaccent" }, // LATIN SMALL LETTER G WITH CEDILLA
+ { 0x0124, "Hcircumflex" }, // LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+ { 0x0125, "hcircumflex" }, // LATIN SMALL LETTER H WITH CIRCUMFLEX
+ { 0x0126, "Hbar" }, // LATIN CAPITAL LETTER H WITH STROKE
+ { 0x0127, "hbar" }, // LATIN SMALL LETTER H WITH STROKE
+ { 0x0128, "Itilde" }, // LATIN CAPITAL LETTER I WITH TILDE
+ { 0x0129, "itilde" }, // LATIN SMALL LETTER I WITH TILDE
+ { 0x012A, "Imacron" }, // LATIN CAPITAL LETTER I WITH MACRON
+ { 0x012B, "imacron" }, // LATIN SMALL LETTER I WITH MACRON
+ { 0x012C, "Ibreve" }, // LATIN CAPITAL LETTER I WITH BREVE
+ { 0x012D, "ibreve" }, // LATIN SMALL LETTER I WITH BREVE
+ { 0x012E, "Iogonek" }, // LATIN CAPITAL LETTER I WITH OGONEK
+ { 0x012F, "iogonek" }, // LATIN SMALL LETTER I WITH OGONEK
+ { 0x0130, "Idotaccent" }, // LATIN CAPITAL LETTER I WITH DOT ABOVE
+ { 0x0131, "dotlessi" }, // LATIN SMALL LETTER DOTLESS I
+ { 0x0132, "IJ" }, // LATIN CAPITAL LIGATURE IJ
+ { 0x0133, "ij" }, // LATIN SMALL LIGATURE IJ
+ { 0x0134, "Jcircumflex" }, // LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+ { 0x0135, "jcircumflex" }, // LATIN SMALL LETTER J WITH CIRCUMFLEX
+ { 0x0136, "Kcommaaccent" }, // LATIN CAPITAL LETTER K WITH CEDILLA
+ { 0x0137, "kcommaaccent" }, // LATIN SMALL LETTER K WITH CEDILLA
+ { 0x0138, "kgreenlandic" }, // LATIN SMALL LETTER KRA
+ { 0x0139, "Lacute" }, // LATIN CAPITAL LETTER L WITH ACUTE
+ { 0x013A, "lacute" }, // LATIN SMALL LETTER L WITH ACUTE
+ { 0x013B, "Lcommaaccent" }, // LATIN CAPITAL LETTER L WITH CEDILLA
+ { 0x013C, "lcommaaccent" }, // LATIN SMALL LETTER L WITH CEDILLA
+ { 0x013D, "Lcaron" }, // LATIN CAPITAL LETTER L WITH CARON
+ { 0x013E, "lcaron" }, // LATIN SMALL LETTER L WITH CARON
+ { 0x013F, "Ldot" }, // LATIN CAPITAL LETTER L WITH MIDDLE DOT
+ { 0x0140, "ldot" }, // LATIN SMALL LETTER L WITH MIDDLE DOT
+ { 0x0141, "Lslash" }, // LATIN CAPITAL LETTER L WITH STROKE
+ { 0x0142, "lslash" }, // LATIN SMALL LETTER L WITH STROKE
+ { 0x0143, "Nacute" }, // LATIN CAPITAL LETTER N WITH ACUTE
+ { 0x0144, "nacute" }, // LATIN SMALL LETTER N WITH ACUTE
+ { 0x0145, "Ncommaaccent" }, // LATIN CAPITAL LETTER N WITH CEDILLA
+ { 0x0146, "ncommaaccent" }, // LATIN SMALL LETTER N WITH CEDILLA
+ { 0x0147, "Ncaron" }, // LATIN CAPITAL LETTER N WITH CARON
+ { 0x0148, "ncaron" }, // LATIN SMALL LETTER N WITH CARON
+ { 0x0149, "napostrophe" }, // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+ { 0x014A, "Eng" }, // LATIN CAPITAL LETTER ENG
+ { 0x014B, "eng" }, // LATIN SMALL LETTER ENG
+ { 0x014C, "Omacron" }, // LATIN CAPITAL LETTER O WITH MACRON
+ { 0x014D, "omacron" }, // LATIN SMALL LETTER O WITH MACRON
+ { 0x014E, "Obreve" }, // LATIN CAPITAL LETTER O WITH BREVE
+ { 0x014F, "obreve" }, // LATIN SMALL LETTER O WITH BREVE
+ { 0x0150, "Ohungarumlaut" }, // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+ { 0x0151, "ohungarumlaut" }, // LATIN SMALL LETTER O WITH DOUBLE ACUTE
+ { 0x0152, "OE" }, // LATIN CAPITAL LIGATURE OE
+ { 0x0153, "oe" }, // LATIN SMALL LIGATURE OE
+ { 0x0154, "Racute" }, // LATIN CAPITAL LETTER R WITH ACUTE
+ { 0x0155, "racute" }, // LATIN SMALL LETTER R WITH ACUTE
+ { 0x0156, "Rcommaaccent" }, // LATIN CAPITAL LETTER R WITH CEDILLA
+ { 0x0157, "rcommaaccent" }, // LATIN SMALL LETTER R WITH CEDILLA
+ { 0x0158, "Rcaron" }, // LATIN CAPITAL LETTER R WITH CARON
+ { 0x0159, "rcaron" }, // LATIN SMALL LETTER R WITH CARON
+ { 0x015A, "Sacute" }, // LATIN CAPITAL LETTER S WITH ACUTE
+ { 0x015B, "sacute" }, // LATIN SMALL LETTER S WITH ACUTE
+ { 0x015C, "Scircumflex" }, // LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+ { 0x015D, "scircumflex" }, // LATIN SMALL LETTER S WITH CIRCUMFLEX
+ { 0x015E, "Scedilla" }, // LATIN CAPITAL LETTER S WITH CEDILLA
+ { 0x015F, "scedilla" }, // LATIN SMALL LETTER S WITH CEDILLA
+ { 0x0160, "Scaron" }, // LATIN CAPITAL LETTER S WITH CARON
+ { 0x0161, "scaron" }, // LATIN SMALL LETTER S WITH CARON
+ { 0x0162, "Tcommaaccent" }, // LATIN CAPITAL LETTER T WITH CEDILLA
+ { 0x0163, "tcommaaccent" }, // LATIN SMALL LETTER T WITH CEDILLA
+ { 0x0164, "Tcaron" }, // LATIN CAPITAL LETTER T WITH CARON
+ { 0x0165, "tcaron" }, // LATIN SMALL LETTER T WITH CARON
+ { 0x0166, "Tbar" }, // LATIN CAPITAL LETTER T WITH STROKE
+ { 0x0167, "tbar" }, // LATIN SMALL LETTER T WITH STROKE
+ { 0x0168, "Utilde" }, // LATIN CAPITAL LETTER U WITH TILDE
+ { 0x0169, "utilde" }, // LATIN SMALL LETTER U WITH TILDE
+ { 0x016A, "Umacron" }, // LATIN CAPITAL LETTER U WITH MACRON
+ { 0x016B, "umacron" }, // LATIN SMALL LETTER U WITH MACRON
+ { 0x016C, "Ubreve" }, // LATIN CAPITAL LETTER U WITH BREVE
+ { 0x016D, "ubreve" }, // LATIN SMALL LETTER U WITH BREVE
+ { 0x016E, "Uring" }, // LATIN CAPITAL LETTER U WITH RING ABOVE
+ { 0x016F, "uring" }, // LATIN SMALL LETTER U WITH RING ABOVE
+ { 0x0170, "Uhungarumlaut" }, // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+ { 0x0171, "uhungarumlaut" }, // LATIN SMALL LETTER U WITH DOUBLE ACUTE
+ { 0x0172, "Uogonek" }, // LATIN CAPITAL LETTER U WITH OGONEK
+ { 0x0173, "uogonek" }, // LATIN SMALL LETTER U WITH OGONEK
+ { 0x0174, "Wcircumflex" }, // LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+ { 0x0175, "wcircumflex" }, // LATIN SMALL LETTER W WITH CIRCUMFLEX
+ { 0x0176, "Ycircumflex" }, // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+ { 0x0177, "ycircumflex" }, // LATIN SMALL LETTER Y WITH CIRCUMFLEX
+ { 0x0178, "Ydieresis" }, // LATIN CAPITAL LETTER Y WITH DIAERESIS
+ { 0x0179, "Zacute" }, // LATIN CAPITAL LETTER Z WITH ACUTE
+ { 0x017A, "zacute" }, // LATIN SMALL LETTER Z WITH ACUTE
+ { 0x017B, "Zdotaccent" }, // LATIN CAPITAL LETTER Z WITH DOT ABOVE
+ { 0x017C, "zdotaccent" }, // LATIN SMALL LETTER Z WITH DOT ABOVE
+ { 0x017D, "Zcaron" }, // LATIN CAPITAL LETTER Z WITH CARON
+ { 0x017E, "zcaron" }, // LATIN SMALL LETTER Z WITH CARON
+ { 0x017F, "longs" }, // LATIN SMALL LETTER LONG S
+ { 0x0192, "florin" }, // LATIN SMALL LETTER F WITH HOOK
+ { 0x01A0, "Ohorn" }, // LATIN CAPITAL LETTER O WITH HORN
+ { 0x01A1, "ohorn" }, // LATIN SMALL LETTER O WITH HORN
+ { 0x01AF, "Uhorn" }, // LATIN CAPITAL LETTER U WITH HORN
+ { 0x01B0, "uhorn" }, // LATIN SMALL LETTER U WITH HORN
+ { 0x01E6, "Gcaron" }, // LATIN CAPITAL LETTER G WITH CARON
+ { 0x01E7, "gcaron" }, // LATIN SMALL LETTER G WITH CARON
+ { 0x01FA, "Aringacute" }, // LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
+ { 0x01FB, "aringacute" }, // LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE
+ { 0x01FC, "AEacute" }, // LATIN CAPITAL LETTER AE WITH ACUTE
+ { 0x01FD, "aeacute" }, // LATIN SMALL LETTER AE WITH ACUTE
+ { 0x01FE, "Oslashacute" }, // LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
+ { 0x01FF, "oslashacute" }, // LATIN SMALL LETTER O WITH STROKE AND ACUTE
+ { 0x0218, "Scommaaccent" }, // LATIN CAPITAL LETTER S WITH COMMA BELOW
+ { 0x0219, "scommaaccent" }, // LATIN SMALL LETTER S WITH COMMA BELOW
+ { 0x021A, "Tcommaaccent" }, // LATIN CAPITAL LETTER T WITH COMMA BELOW;Duplicate
+ { 0x021B, "tcommaaccent" }, // LATIN SMALL LETTER T WITH COMMA BELOW;Duplicate
+ { 0x02BC, "afii57929" }, // MODIFIER LETTER APOSTROPHE
+ { 0x02BD, "afii64937" }, // MODIFIER LETTER REVERSED COMMA
+ { 0x02C6, "circumflex" }, // MODIFIER LETTER CIRCUMFLEX ACCENT
+ { 0x02C7, "caron" }, // CARON
+ { 0x02C9, "macron" }, // MODIFIER LETTER MACRON;Duplicate
+ { 0x02D8, "breve" }, // BREVE
+ { 0x02D9, "dotaccent" }, // DOT ABOVE
+ { 0x02DA, "ring" }, // RING ABOVE
+ { 0x02DB, "ogonek" }, // OGONEK
+ { 0x02DC, "tilde" }, // SMALL TILDE
+ { 0x02DD, "hungarumlaut" }, // DOUBLE ACUTE ACCENT
+ { 0x0300, "gravecomb" }, // COMBINING GRAVE ACCENT
+ { 0x0301, "acutecomb" }, // COMBINING ACUTE ACCENT
+ { 0x0303, "tildecomb" }, // COMBINING TILDE
+ { 0x0309, "hookabovecomb" }, // COMBINING HOOK ABOVE
+ { 0x0323, "dotbelowcomb" }, // COMBINING DOT BELOW
+ { 0x0384, "tonos" }, // GREEK TONOS
+ { 0x0385, "dieresistonos" }, // GREEK DIALYTIKA TONOS
+ { 0x0386, "Alphatonos" }, // GREEK CAPITAL LETTER ALPHA WITH TONOS
+ { 0x0387, "anoteleia" }, // GREEK ANO TELEIA
+ { 0x0388, "Epsilontonos" }, // GREEK CAPITAL LETTER EPSILON WITH TONOS
+ { 0x0389, "Etatonos" }, // GREEK CAPITAL LETTER ETA WITH TONOS
+ { 0x038A, "Iotatonos" }, // GREEK CAPITAL LETTER IOTA WITH TONOS
+ { 0x038C, "Omicrontonos" }, // GREEK CAPITAL LETTER OMICRON WITH TONOS
+ { 0x038E, "Upsilontonos" }, // GREEK CAPITAL LETTER UPSILON WITH TONOS
+ { 0x038F, "Omegatonos" }, // GREEK CAPITAL LETTER OMEGA WITH TONOS
+ { 0x0390, "iotadieresistonos" }, // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+ { 0x0391, "Alpha" }, // GREEK CAPITAL LETTER ALPHA
+ { 0x0392, "Beta" }, // GREEK CAPITAL LETTER BETA
+ { 0x0393, "Gamma" }, // GREEK CAPITAL LETTER GAMMA
+ { 0x0394, "Delta" }, // GREEK CAPITAL LETTER DELTA;Duplicate
+ { 0x0395, "Epsilon" }, // GREEK CAPITAL LETTER EPSILON
+ { 0x0396, "Zeta" }, // GREEK CAPITAL LETTER ZETA
+ { 0x0397, "Eta" }, // GREEK CAPITAL LETTER ETA
+ { 0x0398, "Theta" }, // GREEK CAPITAL LETTER THETA
+ { 0x0399, "Iota" }, // GREEK CAPITAL LETTER IOTA
+ { 0x039A, "Kappa" }, // GREEK CAPITAL LETTER KAPPA
+ { 0x039B, "Lambda" }, // GREEK CAPITAL LETTER LAMDA
+ { 0x039C, "Mu" }, // GREEK CAPITAL LETTER MU
+ { 0x039D, "Nu" }, // GREEK CAPITAL LETTER NU
+ { 0x039E, "Xi" }, // GREEK CAPITAL LETTER XI
+ { 0x039F, "Omicron" }, // GREEK CAPITAL LETTER OMICRON
+ { 0x03A0, "Pi" }, // GREEK CAPITAL LETTER PI
+ { 0x03A1, "Rho" }, // GREEK CAPITAL LETTER RHO
+ { 0x03A3, "Sigma" }, // GREEK CAPITAL LETTER SIGMA
+ { 0x03A4, "Tau" }, // GREEK CAPITAL LETTER TAU
+ { 0x03A5, "Upsilon" }, // GREEK CAPITAL LETTER UPSILON
+ { 0x03A6, "Phi" }, // GREEK CAPITAL LETTER PHI
+ { 0x03A7, "Chi" }, // GREEK CAPITAL LETTER CHI
+ { 0x03A8, "Psi" }, // GREEK CAPITAL LETTER PSI
+ { 0x03A9, "Omega" }, // GREEK CAPITAL LETTER OMEGA;Duplicate
+ { 0x03AA, "Iotadieresis" }, // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+ { 0x03AB, "Upsilondieresis" }, // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+ { 0x03AC, "alphatonos" }, // GREEK SMALL LETTER ALPHA WITH TONOS
+ { 0x03AD, "epsilontonos" }, // GREEK SMALL LETTER EPSILON WITH TONOS
+ { 0x03AE, "etatonos" }, // GREEK SMALL LETTER ETA WITH TONOS
+ { 0x03AF, "iotatonos" }, // GREEK SMALL LETTER IOTA WITH TONOS
+ { 0x03B0, "upsilondieresistonos" }, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+ { 0x03B1, "alpha" }, // GREEK SMALL LETTER ALPHA
+ { 0x03B2, "beta" }, // GREEK SMALL LETTER BETA
+ { 0x03B3, "gamma" }, // GREEK SMALL LETTER GAMMA
+ { 0x03B4, "delta" }, // GREEK SMALL LETTER DELTA
+ { 0x03B5, "epsilon" }, // GREEK SMALL LETTER EPSILON
+ { 0x03B6, "zeta" }, // GREEK SMALL LETTER ZETA
+ { 0x03B7, "eta" }, // GREEK SMALL LETTER ETA
+ { 0x03B8, "theta" }, // GREEK SMALL LETTER THETA
+ { 0x03B9, "iota" }, // GREEK SMALL LETTER IOTA
+ { 0x03BA, "kappa" }, // GREEK SMALL LETTER KAPPA
+ { 0x03BB, "lambda" }, // GREEK SMALL LETTER LAMDA
+ { 0x03BC, "mu" }, // GREEK SMALL LETTER MU;Duplicate
+ { 0x03BD, "nu" }, // GREEK SMALL LETTER NU
+ { 0x03BE, "xi" }, // GREEK SMALL LETTER XI
+ { 0x03BF, "omicron" }, // GREEK SMALL LETTER OMICRON
+ { 0x03C0, "pi" }, // GREEK SMALL LETTER PI
+ { 0x03C1, "rho" }, // GREEK SMALL LETTER RHO
+ { 0x03C2, "sigma1" }, // GREEK SMALL LETTER FINAL SIGMA
+ { 0x03C3, "sigma" }, // GREEK SMALL LETTER SIGMA
+ { 0x03C4, "tau" }, // GREEK SMALL LETTER TAU
+ { 0x03C5, "upsilon" }, // GREEK SMALL LETTER UPSILON
+ { 0x03C6, "phi" }, // GREEK SMALL LETTER PHI
+ { 0x03C7, "chi" }, // GREEK SMALL LETTER CHI
+ { 0x03C8, "psi" }, // GREEK SMALL LETTER PSI
+ { 0x03C9, "omega" }, // GREEK SMALL LETTER OMEGA
+ { 0x03CA, "iotadieresis" }, // GREEK SMALL LETTER IOTA WITH DIALYTIKA
+ { 0x03CB, "upsilondieresis" }, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+ { 0x03CC, "omicrontonos" }, // GREEK SMALL LETTER OMICRON WITH TONOS
+ { 0x03CD, "upsilontonos" }, // GREEK SMALL LETTER UPSILON WITH TONOS
+ { 0x03CE, "omegatonos" }, // GREEK SMALL LETTER OMEGA WITH TONOS
+ { 0x03D1, "theta1" }, // GREEK THETA SYMBOL
+ { 0x03D2, "Upsilon1" }, // GREEK UPSILON WITH HOOK SYMBOL
+ { 0x03D5, "phi1" }, // GREEK PHI SYMBOL
+ { 0x03D6, "omega1" }, // GREEK PI SYMBOL
+ { 0x0401, "afii10023" }, // CYRILLIC CAPITAL LETTER IO
+ { 0x0402, "afii10051" }, // CYRILLIC CAPITAL LETTER DJE
+ { 0x0403, "afii10052" }, // CYRILLIC CAPITAL LETTER GJE
+ { 0x0404, "afii10053" }, // CYRILLIC CAPITAL LETTER UKRAINIAN IE
+ { 0x0405, "afii10054" }, // CYRILLIC CAPITAL LETTER DZE
+ { 0x0406, "afii10055" }, // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+ { 0x0407, "afii10056" }, // CYRILLIC CAPITAL LETTER YI
+ { 0x0408, "afii10057" }, // CYRILLIC CAPITAL LETTER JE
+ { 0x0409, "afii10058" }, // CYRILLIC CAPITAL LETTER LJE
+ { 0x040A, "afii10059" }, // CYRILLIC CAPITAL LETTER NJE
+ { 0x040B, "afii10060" }, // CYRILLIC CAPITAL LETTER TSHE
+ { 0x040C, "afii10061" }, // CYRILLIC CAPITAL LETTER KJE
+ { 0x040E, "afii10062" }, // CYRILLIC CAPITAL LETTER SHORT U
+ { 0x040F, "afii10145" }, // CYRILLIC CAPITAL LETTER DZHE
+ { 0x0410, "afii10017" }, // CYRILLIC CAPITAL LETTER A
+ { 0x0411, "afii10018" }, // CYRILLIC CAPITAL LETTER BE
+ { 0x0412, "afii10019" }, // CYRILLIC CAPITAL LETTER VE
+ { 0x0413, "afii10020" }, // CYRILLIC CAPITAL LETTER GHE
+ { 0x0414, "afii10021" }, // CYRILLIC CAPITAL LETTER DE
+ { 0x0415, "afii10022" }, // CYRILLIC CAPITAL LETTER IE
+ { 0x0416, "afii10024" }, // CYRILLIC CAPITAL LETTER ZHE
+ { 0x0417, "afii10025" }, // CYRILLIC CAPITAL LETTER ZE
+ { 0x0418, "afii10026" }, // CYRILLIC CAPITAL LETTER I
+ { 0x0419, "afii10027" }, // CYRILLIC CAPITAL LETTER SHORT I
+ { 0x041A, "afii10028" }, // CYRILLIC CAPITAL LETTER KA
+ { 0x041B, "afii10029" }, // CYRILLIC CAPITAL LETTER EL
+ { 0x041C, "afii10030" }, // CYRILLIC CAPITAL LETTER EM
+ { 0x041D, "afii10031" }, // CYRILLIC CAPITAL LETTER EN
+ { 0x041E, "afii10032" }, // CYRILLIC CAPITAL LETTER O
+ { 0x041F, "afii10033" }, // CYRILLIC CAPITAL LETTER PE
+ { 0x0420, "afii10034" }, // CYRILLIC CAPITAL LETTER ER
+ { 0x0421, "afii10035" }, // CYRILLIC CAPITAL LETTER ES
+ { 0x0422, "afii10036" }, // CYRILLIC CAPITAL LETTER TE
+ { 0x0423, "afii10037" }, // CYRILLIC CAPITAL LETTER U
+ { 0x0424, "afii10038" }, // CYRILLIC CAPITAL LETTER EF
+ { 0x0425, "afii10039" }, // CYRILLIC CAPITAL LETTER HA
+ { 0x0426, "afii10040" }, // CYRILLIC CAPITAL LETTER TSE
+ { 0x0427, "afii10041" }, // CYRILLIC CAPITAL LETTER CHE
+ { 0x0428, "afii10042" }, // CYRILLIC CAPITAL LETTER SHA
+ { 0x0429, "afii10043" }, // CYRILLIC CAPITAL LETTER SHCHA
+ { 0x042A, "afii10044" }, // CYRILLIC CAPITAL LETTER HARD SIGN
+ { 0x042B, "afii10045" }, // CYRILLIC CAPITAL LETTER YERU
+ { 0x042C, "afii10046" }, // CYRILLIC CAPITAL LETTER SOFT SIGN
+ { 0x042D, "afii10047" }, // CYRILLIC CAPITAL LETTER E
+ { 0x042E, "afii10048" }, // CYRILLIC CAPITAL LETTER YU
+ { 0x042F, "afii10049" }, // CYRILLIC CAPITAL LETTER YA
+ { 0x0430, "afii10065" }, // CYRILLIC SMALL LETTER A
+ { 0x0431, "afii10066" }, // CYRILLIC SMALL LETTER BE
+ { 0x0432, "afii10067" }, // CYRILLIC SMALL LETTER VE
+ { 0x0433, "afii10068" }, // CYRILLIC SMALL LETTER GHE
+ { 0x0434, "afii10069" }, // CYRILLIC SMALL LETTER DE
+ { 0x0435, "afii10070" }, // CYRILLIC SMALL LETTER IE
+ { 0x0436, "afii10072" }, // CYRILLIC SMALL LETTER ZHE
+ { 0x0437, "afii10073" }, // CYRILLIC SMALL LETTER ZE
+ { 0x0438, "afii10074" }, // CYRILLIC SMALL LETTER I
+ { 0x0439, "afii10075" }, // CYRILLIC SMALL LETTER SHORT I
+ { 0x043A, "afii10076" }, // CYRILLIC SMALL LETTER KA
+ { 0x043B, "afii10077" }, // CYRILLIC SMALL LETTER EL
+ { 0x043C, "afii10078" }, // CYRILLIC SMALL LETTER EM
+ { 0x043D, "afii10079" }, // CYRILLIC SMALL LETTER EN
+ { 0x043E, "afii10080" }, // CYRILLIC SMALL LETTER O
+ { 0x043F, "afii10081" }, // CYRILLIC SMALL LETTER PE
+ { 0x0440, "afii10082" }, // CYRILLIC SMALL LETTER ER
+ { 0x0441, "afii10083" }, // CYRILLIC SMALL LETTER ES
+ { 0x0442, "afii10084" }, // CYRILLIC SMALL LETTER TE
+ { 0x0443, "afii10085" }, // CYRILLIC SMALL LETTER U
+ { 0x0444, "afii10086" }, // CYRILLIC SMALL LETTER EF
+ { 0x0445, "afii10087" }, // CYRILLIC SMALL LETTER HA
+ { 0x0446, "afii10088" }, // CYRILLIC SMALL LETTER TSE
+ { 0x0447, "afii10089" }, // CYRILLIC SMALL LETTER CHE
+ { 0x0448, "afii10090" }, // CYRILLIC SMALL LETTER SHA
+ { 0x0449, "afii10091" }, // CYRILLIC SMALL LETTER SHCHA
+ { 0x044A, "afii10092" }, // CYRILLIC SMALL LETTER HARD SIGN
+ { 0x044B, "afii10093" }, // CYRILLIC SMALL LETTER YERU
+ { 0x044C, "afii10094" }, // CYRILLIC SMALL LETTER SOFT SIGN
+ { 0x044D, "afii10095" }, // CYRILLIC SMALL LETTER E
+ { 0x044E, "afii10096" }, // CYRILLIC SMALL LETTER YU
+ { 0x044F, "afii10097" }, // CYRILLIC SMALL LETTER YA
+ { 0x0451, "afii10071" }, // CYRILLIC SMALL LETTER IO
+ { 0x0452, "afii10099" }, // CYRILLIC SMALL LETTER DJE
+ { 0x0453, "afii10100" }, // CYRILLIC SMALL LETTER GJE
+ { 0x0454, "afii10101" }, // CYRILLIC SMALL LETTER UKRAINIAN IE
+ { 0x0455, "afii10102" }, // CYRILLIC SMALL LETTER DZE
+ { 0x0456, "afii10103" }, // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+ { 0x0457, "afii10104" }, // CYRILLIC SMALL LETTER YI
+ { 0x0458, "afii10105" }, // CYRILLIC SMALL LETTER JE
+ { 0x0459, "afii10106" }, // CYRILLIC SMALL LETTER LJE
+ { 0x045A, "afii10107" }, // CYRILLIC SMALL LETTER NJE
+ { 0x045B, "afii10108" }, // CYRILLIC SMALL LETTER TSHE
+ { 0x045C, "afii10109" }, // CYRILLIC SMALL LETTER KJE
+ { 0x045E, "afii10110" }, // CYRILLIC SMALL LETTER SHORT U
+ { 0x045F, "afii10193" }, // CYRILLIC SMALL LETTER DZHE
+ { 0x0462, "afii10146" }, // CYRILLIC CAPITAL LETTER YAT
+ { 0x0463, "afii10194" }, // CYRILLIC SMALL LETTER YAT
+ { 0x0472, "afii10147" }, // CYRILLIC CAPITAL LETTER FITA
+ { 0x0473, "afii10195" }, // CYRILLIC SMALL LETTER FITA
+ { 0x0474, "afii10148" }, // CYRILLIC CAPITAL LETTER IZHITSA
+ { 0x0475, "afii10196" }, // CYRILLIC SMALL LETTER IZHITSA
+ { 0x0490, "afii10050" }, // CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+ { 0x0491, "afii10098" }, // CYRILLIC SMALL LETTER GHE WITH UPTURN
+ { 0x04D9, "afii10846" }, // CYRILLIC SMALL LETTER SCHWA
+ { 0x05B0, "afii57799" }, // HEBREW POINT SHEVA
+ { 0x05B1, "afii57801" }, // HEBREW POINT HATAF SEGOL
+ { 0x05B2, "afii57800" }, // HEBREW POINT HATAF PATAH
+ { 0x05B3, "afii57802" }, // HEBREW POINT HATAF TQAMATS
+ { 0x05B4, "afii57793" }, // HEBREW POINT HIRIQ
+ { 0x05B5, "afii57794" }, // HEBREW POINT TSERE
+ { 0x05B6, "afii57795" }, // HEBREW POINT SEGOL
+ { 0x05B7, "afii57798" }, // HEBREW POINT PATAH
+ { 0x05B8, "afii57797" }, // HEBREW POINT TQAMATS
+ { 0x05B9, "afii57806" }, // HEBREW POINT HOLAM
+ { 0x05BB, "afii57796" }, // HEBREW POINT TQUBUTS
+ { 0x05BC, "afii57807" }, // HEBREW POINT DAGESH OR MAPIQ
+ { 0x05BD, "afii57839" }, // HEBREW POINT METEG
+ { 0x05BE, "afii57645" }, // HEBREW PUNCTUATION MATQAF
+ { 0x05BF, "afii57841" }, // HEBREW POINT RAFE
+ { 0x05C0, "afii57842" }, // HEBREW PUNCTUATION PASEQ
+ { 0x05C1, "afii57804" }, // HEBREW POINT SHIN DOT
+ { 0x05C2, "afii57803" }, // HEBREW POINT SIN DOT
+ { 0x05C3, "afii57658" }, // HEBREW PUNCTUATION SOF PASUQ
+ { 0x05D0, "afii57664" }, // HEBREW LETTER ALEF
+ { 0x05D1, "afii57665" }, // HEBREW LETTER BET
+ { 0x05D2, "afii57666" }, // HEBREW LETTER GIMEL
+ { 0x05D3, "afii57667" }, // HEBREW LETTER DALET
+ { 0x05D4, "afii57668" }, // HEBREW LETTER HE
+ { 0x05D5, "afii57669" }, // HEBREW LETTER VAV
+ { 0x05D6, "afii57670" }, // HEBREW LETTER ZAYIN
+ { 0x05D7, "afii57671" }, // HEBREW LETTER HET
+ { 0x05D8, "afii57672" }, // HEBREW LETTER TET
+ { 0x05D9, "afii57673" }, // HEBREW LETTER YOD
+ { 0x05DA, "afii57674" }, // HEBREW LETTER FINAL KAF
+ { 0x05DB, "afii57675" }, // HEBREW LETTER KAF
+ { 0x05DC, "afii57676" }, // HEBREW LETTER LAMED
+ { 0x05DD, "afii57677" }, // HEBREW LETTER FINAL MEM
+ { 0x05DE, "afii57678" }, // HEBREW LETTER MEM
+ { 0x05DF, "afii57679" }, // HEBREW LETTER FINAL NUN
+ { 0x05E0, "afii57680" }, // HEBREW LETTER NUN
+ { 0x05E1, "afii57681" }, // HEBREW LETTER SAMEKH
+ { 0x05E2, "afii57682" }, // HEBREW LETTER AYIN
+ { 0x05E3, "afii57683" }, // HEBREW LETTER FINAL PE
+ { 0x05E4, "afii57684" }, // HEBREW LETTER PE
+ { 0x05E5, "afii57685" }, // HEBREW LETTER FINAL TSADI
+ { 0x05E6, "afii57686" }, // HEBREW LETTER TSADI
+ { 0x05E7, "afii57687" }, // HEBREW LETTER TQOF
+ { 0x05E8, "afii57688" }, // HEBREW LETTER RESH
+ { 0x05E9, "afii57689" }, // HEBREW LETTER SHIN
+ { 0x05EA, "afii57690" }, // HEBREW LETTER TAV
+ { 0x05F0, "afii57716" }, // HEBREW LIGATURE YIDDISH DOUBLE VAV
+ { 0x05F1, "afii57717" }, // HEBREW LIGATURE YIDDISH VAV YOD
+ { 0x05F2, "afii57718" }, // HEBREW LIGATURE YIDDISH DOUBLE YOD
+ { 0x060C, "afii57388" }, // ARABIC COMMA
+ { 0x061B, "afii57403" }, // ARABIC SEMICOLON
+ { 0x061F, "afii57407" }, // ARABIC TQUESTION MARK
+ { 0x0621, "afii57409" }, // ARABIC LETTER HAMZA
+ { 0x0622, "afii57410" }, // ARABIC LETTER ALEF WITH MADDA ABOVE
+ { 0x0623, "afii57411" }, // ARABIC LETTER ALEF WITH HAMZA ABOVE
+ { 0x0624, "afii57412" }, // ARABIC LETTER WAW WITH HAMZA ABOVE
+ { 0x0625, "afii57413" }, // ARABIC LETTER ALEF WITH HAMZA BELOW
+ { 0x0626, "afii57414" }, // ARABIC LETTER YEH WITH HAMZA ABOVE
+ { 0x0627, "afii57415" }, // ARABIC LETTER ALEF
+ { 0x0628, "afii57416" }, // ARABIC LETTER BEH
+ { 0x0629, "afii57417" }, // ARABIC LETTER TEH MARBUTA
+ { 0x062A, "afii57418" }, // ARABIC LETTER TEH
+ { 0x062B, "afii57419" }, // ARABIC LETTER THEH
+ { 0x062C, "afii57420" }, // ARABIC LETTER JEEM
+ { 0x062D, "afii57421" }, // ARABIC LETTER HAH
+ { 0x062E, "afii57422" }, // ARABIC LETTER KHAH
+ { 0x062F, "afii57423" }, // ARABIC LETTER DAL
+ { 0x0630, "afii57424" }, // ARABIC LETTER THAL
+ { 0x0631, "afii57425" }, // ARABIC LETTER REH
+ { 0x0632, "afii57426" }, // ARABIC LETTER ZAIN
+ { 0x0633, "afii57427" }, // ARABIC LETTER SEEN
+ { 0x0634, "afii57428" }, // ARABIC LETTER SHEEN
+ { 0x0635, "afii57429" }, // ARABIC LETTER SAD
+ { 0x0636, "afii57430" }, // ARABIC LETTER DAD
+ { 0x0637, "afii57431" }, // ARABIC LETTER TAH
+ { 0x0638, "afii57432" }, // ARABIC LETTER ZAH
+ { 0x0639, "afii57433" }, // ARABIC LETTER AIN
+ { 0x063A, "afii57434" }, // ARABIC LETTER GHAIN
+ { 0x0640, "afii57440" }, // ARABIC TATWEEL
+ { 0x0641, "afii57441" }, // ARABIC LETTER FEH
+ { 0x0642, "afii57442" }, // ARABIC LETTER TQAF
+ { 0x0643, "afii57443" }, // ARABIC LETTER KAF
+ { 0x0644, "afii57444" }, // ARABIC LETTER LAM
+ { 0x0645, "afii57445" }, // ARABIC LETTER MEEM
+ { 0x0646, "afii57446" }, // ARABIC LETTER NOON
+ { 0x0647, "afii57470" }, // ARABIC LETTER HEH
+ { 0x0648, "afii57448" }, // ARABIC LETTER WAW
+ { 0x0649, "afii57449" }, // ARABIC LETTER ALEF MAKSURA
+ { 0x064A, "afii57450" }, // ARABIC LETTER YEH
+ { 0x064B, "afii57451" }, // ARABIC FATHATAN
+ { 0x064C, "afii57452" }, // ARABIC DAMMATAN
+ { 0x064D, "afii57453" }, // ARABIC KASRATAN
+ { 0x064E, "afii57454" }, // ARABIC FATHA
+ { 0x064F, "afii57455" }, // ARABIC DAMMA
+ { 0x0650, "afii57456" }, // ARABIC KASRA
+ { 0x0651, "afii57457" }, // ARABIC SHADDA
+ { 0x0652, "afii57458" }, // ARABIC SUKUN
+ { 0x0660, "afii57392" }, // ARABIC-INDIC DIGIT ZERO
+ { 0x0661, "afii57393" }, // ARABIC-INDIC DIGIT ONE
+ { 0x0662, "afii57394" }, // ARABIC-INDIC DIGIT TWO
+ { 0x0663, "afii57395" }, // ARABIC-INDIC DIGIT THREE
+ { 0x0664, "afii57396" }, // ARABIC-INDIC DIGIT FOUR
+ { 0x0665, "afii57397" }, // ARABIC-INDIC DIGIT FIVE
+ { 0x0666, "afii57398" }, // ARABIC-INDIC DIGIT SIX
+ { 0x0667, "afii57399" }, // ARABIC-INDIC DIGIT SEVEN
+ { 0x0668, "afii57400" }, // ARABIC-INDIC DIGIT EIGHT
+ { 0x0669, "afii57401" }, // ARABIC-INDIC DIGIT NINE
+ { 0x066A, "afii57381" }, // ARABIC PERCENT SIGN
+ { 0x066D, "afii63167" }, // ARABIC FIVE POINTED STAR
+ { 0x0679, "afii57511" }, // ARABIC LETTER TTEH
+ { 0x067E, "afii57506" }, // ARABIC LETTER PEH
+ { 0x0686, "afii57507" }, // ARABIC LETTER TCHEH
+ { 0x0688, "afii57512" }, // ARABIC LETTER DDAL
+ { 0x0691, "afii57513" }, // ARABIC LETTER RREH
+ { 0x0698, "afii57508" }, // ARABIC LETTER JEH
+ { 0x06A4, "afii57505" }, // ARABIC LETTER VEH
+ { 0x06AF, "afii57509" }, // ARABIC LETTER GAF
+ { 0x06BA, "afii57514" }, // ARABIC LETTER NOON GHUNNA
+ { 0x06D2, "afii57519" }, // ARABIC LETTER YEH BARREE
+ { 0x06D5, "afii57534" }, // ARABIC LETTER AE
+ { 0x1E80, "Wgrave" }, // LATIN CAPITAL LETTER W WITH GRAVE
+ { 0x1E81, "wgrave" }, // LATIN SMALL LETTER W WITH GRAVE
+ { 0x1E82, "Wacute" }, // LATIN CAPITAL LETTER W WITH ACUTE
+ { 0x1E83, "wacute" }, // LATIN SMALL LETTER W WITH ACUTE
+ { 0x1E84, "Wdieresis" }, // LATIN CAPITAL LETTER W WITH DIAERESIS
+ { 0x1E85, "wdieresis" }, // LATIN SMALL LETTER W WITH DIAERESIS
+ { 0x1EF2, "Ygrave" }, // LATIN CAPITAL LETTER Y WITH GRAVE
+ { 0x1EF3, "ygrave" }, // LATIN SMALL LETTER Y WITH GRAVE
+ { 0x200C, "afii61664" }, // ZERO WIDTH NON-JOINER
+ { 0x200D, "afii301" }, // ZERO WIDTH JOINER
+ { 0x200E, "afii299" }, // LEFT-TO-RIGHT MARK
+ { 0x200F, "afii300" }, // RIGHT-TO-LEFT MARK
+ { 0x2012, "figuredash" }, // FIGURE DASH
+ { 0x2013, "endash" }, // EN DASH
+ { 0x2014, "emdash" }, // EM DASH
+ { 0x2015, "afii00208" }, // HORIZONTAL BAR
+ { 0x2017, "underscoredbl" }, // DOUBLE LOW LINE
+ { 0x2018, "quoteleft" }, // LEFT SINGLE TQUOTATION MARK
+ { 0x2019, "quoteright" }, // RIGHT SINGLE TQUOTATION MARK
+ { 0x201A, "quotesinglbase" }, // SINGLE LOW-9 TQUOTATION MARK
+ { 0x201B, "quotereversed" }, // SINGLE HIGH-REVERSED-9 TQUOTATION MARK
+ { 0x201C, "quotedblleft" }, // LEFT DOUBLE TQUOTATION MARK
+ { 0x201D, "quotedblright" }, // RIGHT DOUBLE TQUOTATION MARK
+ { 0x201E, "quotedblbase" }, // DOUBLE LOW-9 TQUOTATION MARK
+ { 0x2020, "dagger" }, // DAGGER
+ { 0x2021, "daggerdbl" }, // DOUBLE DAGGER
+ { 0x2022, "bullet" }, // BULLET
+ { 0x2024, "onedotenleader" }, // ONE DOT LEADER
+ { 0x2025, "twodotenleader" }, // TWO DOT LEADER
+ { 0x2026, "ellipsis" }, // HORIZONTAL ELLIPSIS
+ { 0x202C, "afii61573" }, // POP DIRECTIONAL FORMATTING
+ { 0x202D, "afii61574" }, // LEFT-TO-RIGHT OVERRIDE
+ { 0x202E, "afii61575" }, // RIGHT-TO-LEFT OVERRIDE
+ { 0x2030, "perthousand" }, // PER MILLE SIGN
+ { 0x2032, "minute" }, // PRIME
+ { 0x2033, "second" }, // DOUBLE PRIME
+ { 0x2039, "guilsinglleft" }, // SINGLE LEFT-POINTING ANGLE TQUOTATION MARK
+ { 0x203A, "guilsinglright" }, // SINGLE RIGHT-POINTING ANGLE TQUOTATION MARK
+ { 0x203C, "exclamdbl" }, // DOUBLE EXCLAMATION MARK
+ { 0x2044, "fraction" }, // FRACTION SLASH
+ { 0x2070, "zerosuperior" }, // SUPERSCRIPT ZERO
+ { 0x2074, "foursuperior" }, // SUPERSCRIPT FOUR
+ { 0x2075, "fivesuperior" }, // SUPERSCRIPT FIVE
+ { 0x2076, "sixsuperior" }, // SUPERSCRIPT SIX
+ { 0x2077, "sevensuperior" }, // SUPERSCRIPT SEVEN
+ { 0x2078, "eightsuperior" }, // SUPERSCRIPT EIGHT
+ { 0x2079, "ninesuperior" }, // SUPERSCRIPT NINE
+ { 0x207D, "parenleftsuperior" }, // SUPERSCRIPT LEFT PARENTHESIS
+ { 0x207E, "parenrightsuperior" }, // SUPERSCRIPT RIGHT PARENTHESIS
+ { 0x207F, "nsuperior" }, // SUPERSCRIPT LATIN SMALL LETTER N
+ { 0x2080, "zeroinferior" }, // SUBSCRIPT ZERO
+ { 0x2081, "oneinferior" }, // SUBSCRIPT ONE
+ { 0x2082, "twoinferior" }, // SUBSCRIPT TWO
+ { 0x2083, "threeinferior" }, // SUBSCRIPT THREE
+ { 0x2084, "fourinferior" }, // SUBSCRIPT FOUR
+ { 0x2085, "fiveinferior" }, // SUBSCRIPT FIVE
+ { 0x2086, "sixinferior" }, // SUBSCRIPT SIX
+ { 0x2087, "seveninferior" }, // SUBSCRIPT SEVEN
+ { 0x2088, "eightinferior" }, // SUBSCRIPT EIGHT
+ { 0x2089, "nineinferior" }, // SUBSCRIPT NINE
+ { 0x208D, "parenleftinferior" }, // SUBSCRIPT LEFT PARENTHESIS
+ { 0x208E, "parenrightinferior" }, // SUBSCRIPT RIGHT PARENTHESIS
+ { 0x20A1, "colonmonetary" }, // COLON SIGN
+ { 0x20A3, "franc" }, // FRENCH FRANC SIGN
+ { 0x20A4, "lira" }, // LIRA SIGN
+ { 0x20A7, "peseta" }, // PESETA SIGN
+ { 0x20AA, "afii57636" }, // NEW SHETQEL SIGN
+ { 0x20AB, "dong" }, // DONG SIGN
+ { 0x20AC, "Euro" }, // EURO SIGN
+ { 0x2105, "afii61248" }, // CARE OF
+ { 0x2111, "Ifraktur" }, // BLACK-LETTER CAPITAL I
+ { 0x2113, "afii61289" }, // SCRIPT SMALL L
+ { 0x2116, "afii61352" }, // NUMERO SIGN
+ { 0x2118, "weierstrass" }, // SCRIPT CAPITAL P
+ { 0x211C, "Rfraktur" }, // BLACK-LETTER CAPITAL R
+ { 0x211E, "prescription" }, // PRESCRIPTION TAKE
+ { 0x2122, "trademark" }, // TRADE MARK SIGN
+ { 0x2126, "Omega" }, // OHM SIGN
+ { 0x212E, "estimated" }, // ESTIMATED SYMBOL
+ { 0x2135, "aleph" }, // ALEF SYMBOL
+ { 0x2153, "onethird" }, // VULGAR FRACTION ONE THIRD
+ { 0x2154, "twothirds" }, // VULGAR FRACTION TWO THIRDS
+ { 0x215B, "oneeighth" }, // VULGAR FRACTION ONE EIGHTH
+ { 0x215C, "threeeighths" }, // VULGAR FRACTION THREE EIGHTHS
+ { 0x215D, "fiveeighths" }, // VULGAR FRACTION FIVE EIGHTHS
+ { 0x215E, "seveneighths" }, // VULGAR FRACTION SEVEN EIGHTHS
+ { 0x2190, "arrowleft" }, // LEFTWARDS ARROW
+ { 0x2191, "arrowup" }, // UPWARDS ARROW
+ { 0x2192, "arrowright" }, // RIGHTWARDS ARROW
+ { 0x2193, "arrowdown" }, // DOWNWARDS ARROW
+ { 0x2194, "arrowboth" }, // LEFT RIGHT ARROW
+ { 0x2195, "arrowupdn" }, // UP DOWN ARROW
+ { 0x21A8, "arrowupdnbse" }, // UP DOWN ARROW WITH BASE
+ { 0x21B5, "carriagereturn" }, // DOWNWARDS ARROW WITH CORNER LEFTWARDS
+ { 0x21D0, "arrowdblleft" }, // LEFTWARDS DOUBLE ARROW
+ { 0x21D1, "arrowdblup" }, // UPWARDS DOUBLE ARROW
+ { 0x21D2, "arrowdblright" }, // RIGHTWARDS DOUBLE ARROW
+ { 0x21D3, "arrowdbldown" }, // DOWNWARDS DOUBLE ARROW
+ { 0x21D4, "arrowdblboth" }, // LEFT RIGHT DOUBLE ARROW
+ { 0x2200, "universal" }, // FOR ALL
+ { 0x2202, "partialdiff" }, // PARTIAL DIFFERENTIAL
+ { 0x2203, "existential" }, // THERE EXISTS
+ { 0x2205, "emptyset" }, // EMPTY SET
+ { 0x2206, "Delta" }, // INCREMENT
+ { 0x2207, "gradient" }, // NABLA
+ { 0x2208, "element" }, // ELEMENT OF
+ { 0x2209, "notelement" }, // NOT AN ELEMENT OF
+ { 0x220B, "suchthat" }, // CONTAINS AS MEMBER
+ { 0x220F, "product" }, // N-ARY PRODUCT
+ { 0x2211, "summation" }, // N-ARY SUMMATION
+ { 0x2212, "minus" }, // MINUS SIGN
+ { 0x2215, "fraction" }, // DIVISION SLASH;Duplicate
+ { 0x2217, "asteriskmath" }, // ASTERISK OPERATOR
+ { 0x2219, "periodcentered" }, // BULLET OPERATOR;Duplicate
+ { 0x221A, "radical" }, // STQUARE ROOT
+ { 0x221D, "proportional" }, // PROPORTIONAL TO
+ { 0x221E, "infinity" }, // INFINITY
+ { 0x221F, "orthogonal" }, // RIGHT ANGLE
+ { 0x2220, "angle" }, // ANGLE
+ { 0x2227, "logicaland" }, // LOGICAL AND
+ { 0x2228, "logicalor" }, // LOGICAL OR
+ { 0x2229, "intersection" }, // INTERSECTION
+ { 0x222A, "union" }, // UNION
+ { 0x222B, "integral" }, // INTEGRAL
+ { 0x2234, "therefore" }, // THEREFORE
+ { 0x223C, "similar" }, // TILDE OPERATOR
+ { 0x2245, "congruent" }, // APPROXIMATELY ETQUAL TO
+ { 0x2248, "approxequal" }, // ALMOST ETQUAL TO
+ { 0x2260, "notequal" }, // NOT ETQUAL TO
+ { 0x2261, "equivalence" }, // IDENTICAL TO
+ { 0x2264, "lessequal" }, // LESS-THAN OR ETQUAL TO
+ { 0x2265, "greaterequal" }, // GREATER-THAN OR ETQUAL TO
+ { 0x2282, "propersubset" }, // SUBSET OF
+ { 0x2283, "propersuperset" }, // SUPERSET OF
+ { 0x2284, "notsubset" }, // NOT A SUBSET OF
+ { 0x2286, "reflexsubset" }, // SUBSET OF OR ETQUAL TO
+ { 0x2287, "reflexsuperset" }, // SUPERSET OF OR ETQUAL TO
+ { 0x2295, "circleplus" }, // CIRCLED PLUS
+ { 0x2297, "circlemultiply" }, // CIRCLED TIMES
+ { 0x22A5, "perpendicular" }, // UP TACK
+ { 0x22C5, "dotmath" }, // DOT OPERATOR
+ { 0x2302, "house" }, // HOUSE
+ { 0x2310, "revlogicalnot" }, // REVERSED NOT SIGN
+ { 0x2320, "integraltp" }, // TOP HALF INTEGRAL
+ { 0x2321, "integralbt" }, // BOTTOM HALF INTEGRAL
+ { 0x2329, "angleleft" }, // LEFT-POINTING ANGLE BRACKET
+ { 0x232A, "angleright" }, // RIGHT-POINTING ANGLE BRACKET
+ { 0x2500, "SF100000" }, // BOX DRAWINGS LIGHT HORIZONTAL
+ { 0x2502, "SF110000" }, // BOX DRAWINGS LIGHT VERTICAL
+ { 0x250C, "SF010000" }, // BOX DRAWINGS LIGHT DOWN AND RIGHT
+ { 0x2510, "SF030000" }, // BOX DRAWINGS LIGHT DOWN AND LEFT
+ { 0x2514, "SF020000" }, // BOX DRAWINGS LIGHT UP AND RIGHT
+ { 0x2518, "SF040000" }, // BOX DRAWINGS LIGHT UP AND LEFT
+ { 0x251C, "SF080000" }, // BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+ { 0x2524, "SF090000" }, // BOX DRAWINGS LIGHT VERTICAL AND LEFT
+ { 0x252C, "SF060000" }, // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+ { 0x2534, "SF070000" }, // BOX DRAWINGS LIGHT UP AND HORIZONTAL
+ { 0x253C, "SF050000" }, // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+ { 0x2550, "SF430000" }, // BOX DRAWINGS DOUBLE HORIZONTAL
+ { 0x2551, "SF240000" }, // BOX DRAWINGS DOUBLE VERTICAL
+ { 0x2552, "SF510000" }, // BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+ { 0x2553, "SF520000" }, // BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+ { 0x2554, "SF390000" }, // BOX DRAWINGS DOUBLE DOWN AND RIGHT
+ { 0x2555, "SF220000" }, // BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+ { 0x2556, "SF210000" }, // BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+ { 0x2557, "SF250000" }, // BOX DRAWINGS DOUBLE DOWN AND LEFT
+ { 0x2558, "SF500000" }, // BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+ { 0x2559, "SF490000" }, // BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+ { 0x255A, "SF380000" }, // BOX DRAWINGS DOUBLE UP AND RIGHT
+ { 0x255B, "SF280000" }, // BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+ { 0x255C, "SF270000" }, // BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+ { 0x255D, "SF260000" }, // BOX DRAWINGS DOUBLE UP AND LEFT
+ { 0x255E, "SF360000" }, // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+ { 0x255F, "SF370000" }, // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+ { 0x2560, "SF420000" }, // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+ { 0x2561, "SF190000" }, // BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+ { 0x2562, "SF200000" }, // BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+ { 0x2563, "SF230000" }, // BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+ { 0x2564, "SF470000" }, // BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+ { 0x2565, "SF480000" }, // BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+ { 0x2566, "SF410000" }, // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+ { 0x2567, "SF450000" }, // BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+ { 0x2568, "SF460000" }, // BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+ { 0x2569, "SF400000" }, // BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+ { 0x256A, "SF540000" }, // BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+ { 0x256B, "SF530000" }, // BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+ { 0x256C, "SF440000" }, // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+ { 0x2580, "upblock" }, // UPPER HALF BLOCK
+ { 0x2584, "dnblock" }, // LOWER HALF BLOCK
+ { 0x2588, "block" }, // FULL BLOCK
+ { 0x258C, "lfblock" }, // LEFT HALF BLOCK
+ { 0x2590, "rtblock" }, // RIGHT HALF BLOCK
+ { 0x2591, "ltshade" }, // LIGHT SHADE
+ { 0x2592, "shade" }, // MEDIUM SHADE
+ { 0x2593, "dkshade" }, // DARK SHADE
+ { 0x25A0, "filledbox" }, // BLACK STQUARE
+ { 0x25A1, "H22073" }, // WHITE STQUARE
+ { 0x25AA, "H18543" }, // BLACK SMALL STQUARE
+ { 0x25AB, "H18551" }, // WHITE SMALL STQUARE
+ { 0x25AC, "filledrect" }, // BLACK RECTANGLE
+ { 0x25B2, "triagup" }, // BLACK UP-POINTING TRIANGLE
+ { 0x25BA, "triagrt" }, // BLACK RIGHT-POINTING POINTER
+ { 0x25BC, "triagdn" }, // BLACK DOWN-POINTING TRIANGLE
+ { 0x25C4, "triaglf" }, // BLACK LEFT-POINTING POINTER
+ { 0x25CA, "lozenge" }, // LOZENGE
+ { 0x25CB, "circle" }, // WHITE CIRCLE
+ { 0x25CF, "H18533" }, // BLACK CIRCLE
+ { 0x25D8, "invbullet" }, // INVERSE BULLET
+ { 0x25D9, "invcircle" }, // INVERSE WHITE CIRCLE
+ { 0x25E6, "openbullet" }, // WHITE BULLET
+ { 0x263A, "smileface" }, // WHITE SMILING FACE
+ { 0x263B, "invsmileface" }, // BLACK SMILING FACE
+ { 0x263C, "sun" }, // WHITE SUN WITH RAYS
+ { 0x2640, "female" }, // FEMALE SIGN
+ { 0x2642, "male" }, // MALE SIGN
+ { 0x2660, "spade" }, // BLACK SPADE SUIT
+ { 0x2663, "club" }, // BLACK CLUB SUIT
+ { 0x2665, "heart" }, // BLACK HEART SUIT
+ { 0x2666, "diamond" }, // BLACK DIAMOND SUIT
+ { 0x266A, "musicalnote" }, // EIGHTH NOTE
+ { 0x266B, "musicalnotedbl" }, // BEAMED EIGHTH NOTES
+ // The names below are in the PU area of Unicode, but needed to get a correct mapping of the symbol font
+ { 0xF6D9, "copyrightserif" },
+ { 0xF6DA, "registerserif" },
+ { 0xF6DB, "trademarkserif" },
+ { 0xF8E5, "radicalex" },
+ { 0xF8E6, "arrowvertex" },
+ { 0xF8E7, "arrowhorizex" },
+ { 0xF8E8, "registersans" },
+ { 0xF8E9, "copyrightsans" },
+ { 0xF8EA, "trademarksans" },
+ { 0xF8EB, "parenlefttp" },
+ { 0xF8EC, "parenleftex" },
+ { 0xF8ED, "parenleftbt" },
+ { 0xF8EE, "bracketlefttp" },
+ { 0xF8EF, "bracketleftex" },
+ { 0xF8F0, "bracketleftbt" },
+ { 0xF8F1, "bracelefttp" },
+ { 0xF8F2, "braceleftmid" },
+ { 0xF8F3, "braceleftbt" },
+ { 0xF8F4, "braceex" },
+ { 0xF8F5, "integralex" },
+ { 0xF8F6, "parenrighttp" },
+ { 0xF8F7, "parenrightex" },
+ { 0xF8F8, "parenrightbt" },
+ { 0xF8F9, "bracketrighttp" },
+ { 0xF8FA, "bracketrightex" },
+ { 0xF8FB, "bracketrightbt" },
+ { 0xF8FC, "bracerighttp" },
+ { 0xF8FD, "bracerightmid" },
+ { 0xF8FE, "bracerightbt" },
+ // End of extensions needed for symbols
+ { 0xFB00, "ff" }, // LATIN SMALL LIGATURE FF
+ { 0xFB01, "fi" }, // LATIN SMALL LIGATURE FI
+ { 0xFB02, "fl" }, // LATIN SMALL LIGATURE FL
+ { 0xFB03, "ffi" }, // LATIN SMALL LIGATURE FFI
+ { 0xFB04, "ffl" }, // LATIN SMALL LIGATURE FFL
+ { 0xFB1F, "afii57705" }, // HEBREW LIGATURE YIDDISH YOD YOD PATAH
+ { 0xFB2A, "afii57694" }, // HEBREW LETTER SHIN WITH SHIN DOT
+ { 0xFB2B, "afii57695" }, // HEBREW LETTER SHIN WITH SIN DOT
+ { 0xFB35, "afii57723" }, // HEBREW LETTER VAV WITH DAGESH
+ { 0xFB4B, "afii57700" }, // HEBREW LETTER VAV WITH HOLAM
+ // end of stuff from glyphlist.txt
+ { 0xFFFF, 0 }
+};
+
+// ---------------------------------------------------------------------
+// postscript font substitution dictionary. We assume every postscript printer has at least
+// Helvetica, Times, Courier and Symbol
+
+struct psfont {
+ const char *psname;
+ float slant;
+ float xscale;
+};
+
+static const psfont Arial[] = {
+ {"Arial", 0, 84.04 },
+ { "Arial-Italic", 0, 84.04 },
+ { "Arial-Bold", 0, 88.65 },
+ { "Arial-BoldItalic", 0, 88.65 }
+};
+
+static const psfont AvantGarde[] = {
+ { "AvantGarde-Book", 0, 87.43 },
+ { "AvantGarde-BookOblique", 0, 88.09 },
+ { "AvantGarde-Demi", 0, 88.09 },
+ { "AvantGarde-DemiOblique", 0, 87.43 },
+};
+
+static const psfont Bookman [] = {
+ { "Bookman-Light", 0, 93.78 },
+ { "Bookman-LightItalic", 0, 91.42 },
+ { "Bookman-Demi", 0, 99.86 },
+ { "Bookman-DemiItalic", 0, 101.54 }
+};
+
+static const psfont Charter [] = {
+ { "CharterBT-Roman", 0, 84.04 },
+ { "CharterBT-Italic", 0.0, 81.92 },
+ { "CharterBT-Bold", 0, 88.99 },
+ { "CharterBT-BoldItalic", 0.0, 88.20 }
+};
+
+static const psfont Courier [] = {
+ { "Courier", 0, 100. },
+ { "Courier-Oblique", 0, 100. },
+ { "Courier-Bold", 0, 100. },
+ { "Courier-BoldOblique", 0, 100. }
+};
+
+static const psfont Garamond [] = {
+ { "Garamond-Antiqua", 0, 78.13 },
+ { "Garamond-Kursiv", 0, 78.13 },
+ { "Garamond-Halbfett", 0, 78.13 },
+ { "Garamond-KursivHalbfett", 0, 78.13 }
+};
+
+static const psfont GillSans [] = { // ### some estimated value for xstretch
+ { "GillSans", 0, 82 },
+ { "GillSans-Italic", 0, 82 },
+ { "GillSans-Bold", 0, 82 },
+ { "GillSans-BoldItalic", 0, 82 }
+};
+
+static const psfont Helvetica [] = {
+ { "Helvetica", 0, 84.04 },
+ { "Helvetica-Oblique", 0, 84.04 },
+ { "Helvetica-Bold", 0, 88.65 },
+ { "Helvetica-BoldOblique", 0, 88.65 }
+};
+
+static const psfont Letter [] = {
+ { "LetterGothic", 0, 83.32 },
+ { "LetterGothic-Italic", 0, 83.32 },
+ { "LetterGothic-Bold", 0, 83.32 },
+ { "LetterGothic-Bold", 0.2, 83.32 }
+};
+
+static const psfont LucidaSans [] = {
+ { "LucidaSans", 0, 94.36 },
+ { "LucidaSans-Oblique", 0, 94.36 },
+ { "LucidaSans-Demi", 0, 98.10 },
+ { "LucidaSans-DemiOblique", 0, 98.08 }
+};
+
+static const psfont LucidaSansTT [] = {
+ { "LucidaSans-Typewriter", 0, 100.50 },
+ { "LucidaSans-TypewriterOblique", 0, 100.50 },
+ { "LucidaSans-TypewriterBold", 0, 100.50 },
+ { "LucidaSans-TypewriterBoldOblique", 0, 100.50 }
+};
+
+static const psfont LucidaBright [] = {
+ { "LucidaBright", 0, 93.45 },
+ { "LucidaBright-Italic", 0, 91.98 },
+ { "LucidaBright-Demi", 0, 96.22 },
+ { "LucidaBright-DemiItalic", 0, 96.98 }
+};
+
+static const psfont Palatino [] = {
+ { "Palatino-Roman", 0, 82.45 },
+ { "Palatino-Italic", 0, 76.56 },
+ { "Palatino-Bold", 0, 83.49 },
+ { "Palatino-BoldItalic", 0, 81.51 }
+};
+
+static const psfont Symbol [] = {
+ { "Symbol", 0, 82.56 },
+ { "Symbol", 0.2, 82.56 },
+ { "Symbol", 0, 82.56 },
+ { "Symbol", 0.2, 82.56 }
+};
+
+static const psfont Tahoma [] = {
+ { "Tahoma", 0, 83.45 },
+ { "Tahoma", 0.2, 83.45 },
+ { "Tahoma-Bold", 0, 95.59 },
+ { "Tahoma-Bold", 0.2, 95.59 }
+};
+
+static const psfont Times [] = {
+ { "Times-Roman", 0, 82.45 },
+ { "Times-Italic", 0, 82.45 },
+ { "Times-Bold", 0, 82.45 },
+ { "Times-BoldItalic", 0, 82.45 }
+};
+
+static const psfont Verdana [] = {
+ { "Verdana", 0, 96.06 },
+ { "Verdana-Italic", 0, 96.06 },
+ { "Verdana-Bold", 0, 107.12 },
+ { "Verdana-BoldItalic", 0, 107.10 }
+};
+
+static const psfont Utopia [] = { // ###
+ { "Utopia-Regular", 0, 84.70 },
+ { "Utopia-Regular", 0.2, 84.70 },
+ { "Utopia-Bold", 0, 88.01 },
+ { "Utopia-Bold", 0.2, 88.01 }
+};
+
+static const psfont * const SansSerifReplacements[] = {
+ Helvetica, 0
+ };
+static const psfont * const SerifReplacements[] = {
+ Times, 0
+ };
+static const psfont * const FixedReplacements[] = {
+ Courier, 0
+ };
+static const psfont * const TahomaReplacements[] = {
+ Verdana, AvantGarde, Helvetica, 0
+ };
+static const psfont * const VerdanaReplacements[] = {
+ Tahoma, AvantGarde, Helvetica, 0
+ };
+
+static const struct {
+ const char * input; // spaces are stripped in here, and everything lowercase
+ const psfont * ps;
+ const psfont *const * tqreplacements;
+} postscriptFonts [] = {
+ { "arial", Arial, SansSerifReplacements },
+ { "arialmt", Arial, SansSerifReplacements },
+ { "arialtqunicodems", Arial, SansSerifReplacements },
+ { "avantgarde", AvantGarde, SansSerifReplacements },
+ { "bookman", Bookman, SerifReplacements },
+ { "charter", Charter, SansSerifReplacements },
+ { "bitstreamcharter", Charter, SansSerifReplacements },
+ { "bitstreamcyberbit", Times, SerifReplacements }, // ###
+ { "courier", Courier, 0 },
+ { "couriernew", Courier, 0 },
+ { "fixed", Courier, 0 },
+ { "garamond", Garamond, SerifReplacements },
+ { "gillsans", GillSans, SansSerifReplacements },
+ { "helvetica", Helvetica, 0 },
+ { "letter", Letter, FixedReplacements },
+ { "lucida", LucidaSans, SansSerifReplacements },
+ { "lucidasans", LucidaSans, SansSerifReplacements },
+ { "lucidabright", LucidaBright, SerifReplacements },
+ { "lucidasanstypewriter", LucidaSansTT, FixedReplacements },
+ { "luciduxsans", LucidaSans, SansSerifReplacements },
+ { "luciduxserif", LucidaBright, SerifReplacements },
+ { "luciduxmono", LucidaSansTT, FixedReplacements },
+ { "palatino", Palatino, SerifReplacements },
+ { "symbol", Symbol, 0 },
+ { "tahoma", Tahoma, TahomaReplacements },
+ { "terminal", Courier, 0 },
+ { "times", Times, 0 },
+ { "timesnewroman", Times, 0 },
+ { "verdana", Verdana, VerdanaReplacements },
+ { "utopia", Utopia, SerifReplacements },
+ { 0, 0, 0 }
+};
+
+
+// ------------------------------End of static data ----------------------------------
+
+// make sure DSC comments are not longer than 255 chars per line.
+static TQString wrapDSC( const TQString &str )
+{
+ TQString dsc = str.simplifyWhiteSpace();
+ const uint wrapAt = 254;
+ TQString wrapped;
+ if ( dsc.length() < wrapAt )
+ wrapped = dsc;
+ else {
+ wrapped = dsc.left( wrapAt );
+ TQString tmp = dsc.mid( wrapAt );
+ while ( tmp.length() > wrapAt-3 ) {
+ wrapped += "\n%%+" + tmp.left( wrapAt-3 );
+ tmp = tmp.mid( wrapAt-3 );
+ }
+ wrapped += "\n%%+" + tmp;
+ }
+ return wrapped + "\n";
+}
+
+static TQString toString( const float num )
+{
+ return TQString::number( num, 'f', 3 );
+}
+
+// ----------------------------- Internal class declarations -----------------------------
+
+class TQPSPrinterFontPrivate;
+
+class TQPSPrinterPrivate {
+public:
+ TQPSPrinterPrivate( TQPrinter *prt, int filedes );
+ ~TQPSPrinterPrivate();
+
+ void matrixSetup( TQPainter * );
+ void clippingSetup( TQPainter * );
+ void setClippingOff( TQPainter * );
+ void orientationSetup();
+ void resetDrawingTools( TQPainter * );
+ void emitHeader( bool finished );
+ void setFont( const TQFont &, int script );
+ void drawImage( TQPainter *, float x, float y, float w, float h, const TQImage &img, const TQImage &tqmask );
+ void initPage( TQPainter *paint );
+ void flushPage( bool last = FALSE );
+
+ TQPrinter *printer;
+ int pageCount;
+ bool dirtyMatrix;
+ bool dirtyNewPage;
+ bool epsf;
+ TQString fontsUsed;
+
+ // outstream is the stream the build up pages are copied to. It points to buffer
+ // at the start, and is reset to use the outDevice after emitHeader has been called.
+ TQTextStream outStream;
+
+ // stores the descriptions of the first pages. outStream operates on this buffer
+ // until we call emitHeader
+ TQBuffer *buffer;
+ int pagesInBuffer;
+
+ // the tqdevice the output is in the end streamed to.
+ TQIODevice * outDevice;
+ int fd;
+
+ // buffer for the current page. Needed becaus we might have page fonts.
+ TQBuffer *pageBuffer;
+ TQTextStream pageStream;
+
+ TQDict<TQString> headerFontNames;
+ TQDict<TQString> pageFontNames;
+ TQDict<TQPSPrinterFontPrivate> fonts;
+ TQPSPrinterFontPrivate *currentFontFile;
+ int headerFontNumber;
+ int pageFontNumber;
+ TQBuffer * fontBuffer;
+ TQTextStream fontStream;
+ bool dirtyClipping;
+ bool firstClipOnPage;
+ TQRect boundingBox;
+ TQImage * savedImage;
+ TQPen cpen;
+ TQBrush cbrush;
+ bool dirtypen;
+ bool dirtybrush;
+ TQColor bkColor;
+ bool dirtyBkColor;
+ TQt::BGMode bkMode;
+ bool dirtyBkMode;
+#ifndef TQT_NO_TEXTCODEC
+ TQTextCodec * currentFontCodec;
+#endif
+ TQString currentFont;
+ TQFontMetrics fm;
+ int textY;
+ TQFont currentUsed;
+ int scriptUsed;
+ TQFont currentSet;
+ float scale;
+
+ TQStringList fontpath;
+};
+
+
+class TQPSPrinterFontPrivate {
+public:
+ TQPSPrinterFontPrivate();
+ virtual ~TQPSPrinterFontPrivate() {}
+ virtual TQString postScriptFontName() { return psname; }
+ virtual TQString defineFont( TQTextStream &stream, const TQString &ps, const TQFont &f, const TQString &key,
+ TQPSPrinterPrivate *d );
+ virtual void download(TQTextStream& s, bool global);
+ virtual void drawText( TQTextStream &stream, const TQPoint &p, TQTextEngine *engine, int item,
+ const TQString &text, TQPSPrinterPrivate *d, TQPainter *paint);
+ virtual unsigned short mapUnicode( unsigned short tqunicode );
+ void downloadMapping( TQTextStream &s, bool global );
+ TQString glyphName( unsigned short glyphindex, bool *glyphSet = 0 );
+ virtual void restore();
+
+ virtual unsigned short tqunicode_for_glyph(int glyphindex) { return glyphindex; }
+ virtual unsigned short glyph_for_tqunicode(unsigned short tqunicode) { return tqunicode; }
+ unsigned short insertIntoSubset( unsigned short tqunicode );
+ virtual bool embedded() { return FALSE; }
+
+ bool operator == ( const TQPSPrinterFontPrivate &other ) {
+ return other.psname == psname;
+ }
+ inline void setSymbol() { symbol = TRUE; }
+
+protected:
+ TQString psname;
+ TQStringList tqreplacementList;
+
+ TQMap<unsigned short, unsigned short> subset; // tqunicode subset in the global font
+ TQMap<unsigned short, unsigned short> page_subset; // subset added in this page
+ int subsetCount;
+ int pageSubsetCount;
+ bool global_dict;
+ bool downloaded;
+ bool symbol;
+};
+
+// ------------------- end of class declarations ---------------------------
+
+// --------------------------------------------------------------
+// beginning of font related methods
+// --------------------------------------------------------------
+
+
+static int getPsFontType( const TQFontEngine *fe )
+{
+ int weight = fe->fontDef.weight;
+ bool italic = fe->fontDef.italic;
+
+ int type = 0; // used to look up in the psname array
+ // get the right modification, or build something
+ if ( weight > TQFont::Normal && italic )
+ type = 3;
+ else if ( weight > TQFont::Normal )
+ type = 2;
+ else if ( italic )
+ type = 1;
+ return type;
+}
+
+static int addPsFontNameExtension( const TQFontEngine *fe, TQString &ps, const psfont *psf = 0 )
+{
+ int type = getPsFontType( fe );
+
+ if ( psf ) {
+ ps = TQString::tqfromLatin1( psf[type].psname );
+ } else {
+ switch ( type ) {
+ case 1:
+ ps.append( TQString::tqfromLatin1("-Italic") );
+ break;
+ case 2:
+ ps.append( TQString::tqfromLatin1("-Bold") );
+ break;
+ case 3:
+ ps.append( TQString::tqfromLatin1("-BoldItalic") );
+ break;
+ case 0:
+ default:
+ break;
+ }
+ }
+ return type;
+}
+
+static TQString makePSFontName( const TQFontEngine *fe, int *listpos = 0, int *ftype = 0 )
+{
+ TQString ps;
+ int i;
+
+ TQString family = fe->fontDef.family.lower();
+
+ // try to make a "good" postscript name
+ ps = family.simplifyWhiteSpace();
+ i = 0;
+ while( (unsigned int)i < ps.length() ) {
+ if ( i != 0 && ps[i] == '[') {
+ if ( ps[i-1] == ' ' )
+ ps.truncate (i-1);
+ else
+ ps.truncate (i);
+ break;
+ }
+ if ( i == 0 || ps[i-1] == ' ' ) {
+ ps[i] = ps[i].upper();
+ if ( i )
+ ps.remove( i-1, 1 );
+ else
+ i++;
+ } else {
+ i++;
+ }
+ }
+
+ if ( ps.isEmpty() )
+ ps = "Helvetica";
+
+ // see if the table has a better name
+ i = 0;
+ TQString lowerName = ps.lower();
+ while( postscriptFonts[i].input &&
+ postscriptFonts[i].input != lowerName )
+ i++;
+ const psfont *psf = postscriptFonts[i].ps;
+
+ int type = addPsFontNameExtension( fe, ps, psf );
+
+ if ( listpos )
+ *listpos = i;
+ if ( ftype )
+ *ftype = type;
+ return ps;
+}
+
+static void appendReplacements( TQStringList &list, const psfont * const * tqreplacements, int type, float xscale = 100. )
+{
+ // iterate through the tqreplacement fonts
+ while ( *tqreplacements ) {
+ const psfont *psf = *tqreplacements;
+ TQString ps = "[ /" + TQString::tqfromLatin1( psf[type].psname ) + " " +
+ toString( xscale / psf[type].xscale ) + " " +
+ toString( psf[type].slant ) + " ]";
+ list.append( ps );
+ ++tqreplacements;
+ }
+}
+
+static TQStringList makePSFontNameList( const TQFontEngine *fe, const TQString &psname = TQString::null, bool useNameForLookup = FALSE )
+{
+ int i;
+ int type;
+ TQStringList list;
+ TQString ps = psname;
+
+ if ( !ps.isEmpty() && !useNameForLookup ) {
+ TQString best = "[ /" + ps + " 1.0 0.0 ]";
+ list.append( best );
+ }
+
+ ps = makePSFontName( fe, &i, &type );
+
+ const psfont *psf = postscriptFonts[i].ps;
+ const psfont * const * tqreplacements = postscriptFonts[i].tqreplacements;
+ float xscale = 100;
+ if ( psf ) {
+ // xscale for the "right" font is always 1. We scale the tqreplacements...
+ xscale = psf->xscale;
+ ps = "[ /" + TQString::tqfromLatin1( psf[type].psname ) + " 1.0 " +
+ toString( psf[type].slant ) + " ]";
+ } else {
+ ps = "[ /" + ps + " 1.0 0.0 ]";
+ // only add default tqreplacement fonts in case this font was unknown.
+ if ( fe->fontDef.fixedPitch ) {
+ tqreplacements = FixedReplacements;
+ } else {
+ tqreplacements = SansSerifReplacements;
+ // 100 is courier, but most fonts are not as wide as courier. Using 100
+ // here would make letters overlap for some fonts. This value is empirical.
+ xscale = 83;
+ }
+ }
+ list.append( ps );
+
+ if ( tqreplacements )
+ appendReplacements( list, tqreplacements, type, xscale);
+ return list;
+}
+
+static void emitPSFontNameList( TQTextStream &s, const TQString &psname, const TQStringList &list )
+{
+ s << "/" << psname << "List [\n";
+ s << list.join("\n ");
+ s << "\n] d\n";
+}
+
+static inline float pointSize( const TQFont &f, float scale )
+{
+ float psize;
+ if ( f.pointSize() != -1 )
+ psize = f.pointSize()/scale;
+ else
+ psize = f.pixelSize();
+ return psize;
+}
+
+
+// ========================== FONT CLASSES ===============
+
+
+TQPSPrinterFontPrivate::TQPSPrinterFontPrivate()
+{
+ global_dict = FALSE;
+ downloaded = FALSE;
+ symbol = FALSE;
+ // map 0 to .notdef
+ subset.insert( 0, 0 );
+ subsetCount = 1;
+ pageSubsetCount = 0;
+}
+
+unsigned short TQPSPrinterFontPrivate::insertIntoSubset( unsigned short u )
+{
+ unsigned short retval = 0;
+ if ( subset.tqfind(u) == subset.end() ) {
+ if ( !downloaded ) { // we need to add to the page subset
+ subset.insert( u, subsetCount ); // mark it as used
+ //printf("GLOBAL SUBSET ADDED %04x = %04x\n",u, subsetCount);
+ retval = subsetCount;
+ subsetCount++;
+ } else if ( page_subset.tqfind(u) == page_subset.end() ) {
+ page_subset.insert( u, pageSubsetCount ); // mark it as used
+ //printf("PAGE SUBSET ADDED %04x = %04x\n",u, pageSubsetCount);
+ retval = pageSubsetCount + (subsetCount/256 + 1) * 256;
+ pageSubsetCount++;
+ }
+ } else {
+ qWarning("TQPSPrinterFont::internal error");
+ }
+ return retval;
+}
+
+void TQPSPrinterFontPrivate::restore()
+{
+ page_subset.clear();
+ pageSubsetCount = 0;
+ //qDebug("restore for font %s\n",psname.latin1());
+}
+
+static inline const char *toHex( uchar u )
+{
+ static char hexVal[3];
+ int i = 1;
+ while ( i >= 0 ) {
+ ushort hex = (u & 0x000f);
+ if ( hex < 0x0a )
+ hexVal[i] = '0'+hex;
+ else
+ hexVal[i] = 'A'+(hex-0x0a);
+ u = u >> 4;
+ i--;
+ }
+ hexVal[2] = '\0';
+ return hexVal;
+}
+
+static inline const char *toHex( ushort u )
+{
+ static char hexVal[5];
+ int i = 3;
+ while ( i >= 0 ) {
+ ushort hex = (u & 0x000f);
+ if ( hex < 0x0a )
+ hexVal[i] = '0'+hex;
+ else
+ hexVal[i] = 'A'+(hex-0x0a);
+ u = u >> 4;
+ i--;
+ }
+ hexVal[4] = '\0';
+ return hexVal;
+}
+
+static inline const char * toInt( int i )
+{
+ static char intVal[20];
+ intVal[19] = 0;
+ int pos = 19;
+ if ( i == 0 ) {
+ intVal[--pos] = '0';
+ } else {
+ bool neg = FALSE;
+ if ( i < 0 ) {
+ neg = TRUE;
+ i = -i;
+ }
+ while ( i ) {
+ int dec = i%10;
+ intVal[--pos] = '0'+dec;
+ i /= 10;
+ }
+ if ( neg )
+ intVal[--pos] = '-';
+ }
+ return intVal+pos;
+}
+
+void TQPSPrinterFontPrivate::drawText( TQTextStream &stream, const TQPoint &p, TQTextEngine *engine, int item,
+ const TQString &text, TQPSPrinterPrivate *d, TQPainter *paint)
+{
+ int len = engine->length( item );
+ TQScriptItem &si = engine->items[item];
+
+ int x = p.x() + si.x;
+ int y = p.y() + si.y;
+ if ( y != d->textY || d->textY == 0 )
+ stream << y << " Y";
+ d->textY = y;
+
+ stream << "<";
+ if ( si.analysis.bidiLevel % 2 ) {
+ for ( int i = len-1; i >=0; i-- )
+ stream << toHex( mapUnicode(text.tqunicode()[i].tqunicode()) );
+ } else {
+ for ( int i = 0; i < len; i++ )
+ stream << toHex( mapUnicode(text.tqunicode()[i].tqunicode()) );
+ }
+ stream << ">";
+
+ stream << si.width << " " << x;
+
+ if ( paint->font().underline() )
+ stream << ' ' << y + d->fm.underlinePos() + d->fm.lineWidth()
+ << " " << d->fm.lineWidth() << " Tl";
+ if ( paint->font().strikeOut() )
+ stream << ' ' << y + d->fm.strikeOutPos()
+ << " " << d->fm.lineWidth() << " Tl";
+ stream << " AT\n";
+
+}
+
+
+TQString TQPSPrinterFontPrivate::defineFont( TQTextStream &stream, const TQString &ps, const TQFont &f, const TQString &key,
+ TQPSPrinterPrivate *d )
+{
+ TQString fontName;
+ fontName.sprintf( "/%s-Uni", ps.latin1());
+
+ if ( d->buffer ) {
+ ++d->headerFontNumber;
+ d->fontStream << "/F" << d->headerFontNumber << " "
+ << pointSize( f, d->scale ) << fontName << " DF\n";
+ fontName.sprintf( "F%d", d->headerFontNumber );
+ d->headerFontNames.insert( key, new TQString( fontName ) );
+ } else {
+ ++d->pageFontNumber;
+ stream << "/F" << d->pageFontNumber << " "
+ << pointSize( f, d->scale ) << fontName << " DF\n";
+ fontName.sprintf( "F%d", d->pageFontNumber );
+ d->pageFontNames.insert( key, new TQString( fontName ) );
+ }
+ return fontName;
+}
+
+unsigned short TQPSPrinterFontPrivate::mapUnicode( unsigned short tqunicode )
+{
+ TQMap<unsigned short, unsigned short>::iterator res;
+ res = subset.tqfind( tqunicode );
+ unsigned short offset = 0;
+ bool found = FALSE;
+ if ( res != subset.end() ) {
+ found = TRUE;
+ } else {
+ if ( downloaded ) {
+ res = page_subset.tqfind( tqunicode );
+ offset = (subsetCount/256 + 1) * 256;
+ if ( res != page_subset.end() )
+ found = TRUE;
+ }
+ }
+ if ( !found ) {
+ return insertIntoSubset( tqunicode );
+ }
+ //qDebug("mapping tqunicode %x to %x", tqunicode, offset+*res);
+ return offset + *res;
+}
+
+// This map is used for symbol fonts to get the correct glyph names for the latin range
+static const unsigned short symbol_map[0x100] = {
+ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
+ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
+ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
+ 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
+ 0x0020, 0x0021, 0x2200, 0x0023, 0x2203, 0x0025, 0x0026, 0x220b,
+ 0x0028, 0x0029, 0x2217, 0x002b, 0x002c, 0x2212, 0x002e, 0x002f,
+ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
+ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
+
+ 0x2245, 0x0391, 0x0392, 0x03a7, 0x0394, 0x0395, 0x03a6, 0x0393,
+ 0x0397, 0x0399, 0x03d1, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f,
+ 0x03a0, 0x0398, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03c2, 0x03a9,
+ 0x039e, 0x03a8, 0x0396, 0x005b, 0x2234, 0x005d, 0x22a5, 0x005f,
+ 0xf8e5, 0x03b1, 0x03b2, 0x03c7, 0x03b4, 0x03b5, 0x03c6, 0x03b3,
+ 0x03b7, 0x03b9, 0x03d5, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03bf,
+ 0x03c0, 0x03b8, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03d6, 0x03c9,
+ 0x03be, 0x03c8, 0x03b6, 0x007b, 0x007c, 0x007d, 0x223c, 0x007f,
+
+ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
+ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
+ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
+ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
+ 0x20ac, 0x03d2, 0x2023, 0x2264, 0x2044, 0x221e, 0x0192, 0x2263,
+ 0x2666, 0x2665, 0x2660, 0x2194, 0x2190, 0x2191, 0x2192, 0x2193,
+ 0x00b0, 0x00b1, 0x2033, 0x2265, 0x00d7, 0x221d, 0x2202, 0x2022,
+ 0x00f7, 0x2260, 0x2261, 0x2248, 0x2026, 0xf8e6, 0xf8e7, 0x21b5,
+
+ 0x2135, 0x2111, 0x211c, 0x2118, 0x2297, 0x2295, 0x2205, 0x2229,
+ 0x222a, 0x2283, 0x2287, 0x2284, 0x2282, 0x2286, 0x2208, 0x2209,
+ 0x2220, 0x2207, 0xf6da, 0xf6d9, 0xf6db, 0x220f, 0x221a, 0x22c5,
+ 0x00ac, 0x2227, 0x2228, 0x21d4, 0x21d0, 0x21d1, 0x21d2, 0x21d3,
+ 0x25ca, 0x2329, 0xf8e8, 0xf8e9, 0xf8ea, 0x2211, 0xf8eb, 0xf8ec,
+ 0xf8ed, 0xf8ee, 0xf8ef, 0xf8f0, 0xf8f1, 0xf8f2, 0xf8f3, 0xf8f4,
+ 0x0000, 0x232a, 0x222b, 0x2320, 0xf8f5, 0x2321, 0xf8f6, 0xf8f7,
+ 0xf8f8, 0xf8f9, 0xf8fa, 0xf8fb, 0xf8fc, 0xf8fd, 0xf8fe, 0x0000,
+};
+
+TQString TQPSPrinterFontPrivate::glyphName( unsigned short glyphindex, bool *glyphSet )
+{
+ TQString glyphname;
+ int l = 0;
+ unsigned short tqunicode = tqunicode_for_glyph( glyphindex );
+ if (symbol && tqunicode < 0x100) {
+ // map from latin1 to symbol
+ tqunicode = symbol_map[tqunicode];
+ }
+ if ( !tqunicode && glyphindex ) {
+ glyphname = "gl";
+ glyphname += toHex( glyphindex );
+ } else {
+ while( tqunicodetoglyph[l].u < tqunicode )
+ l++;
+ if ( tqunicodetoglyph[l].u == tqunicode ) {
+ glyphname = tqunicodetoglyph[l].g;
+ if ( glyphSet ) {
+ int other = 0;
+ switch ( tqunicode ) {
+ // some glyph names are duplicate in postscript. Make sure we give the
+ // duplicate a different name to avoid infinite recursion
+ case 0x0394:
+ other = 0x2206;
+ break;
+ case 0x03a9:
+ other = 0x2126;
+ break;
+ case 0x0162:
+ other = 0x021a;
+ break;
+ case 0x2215:
+ other = 0x2044;
+ break;
+ case 0x00ad:
+ other = 0x002d;
+ break;
+ case 0x02c9:
+ other = 0x00af;
+ break;
+ case 0x03bc:
+ other = 0x00b5;
+ break;
+ case 0x2219:
+ other = 0x00b7;
+ break;
+ case 0x00a0:
+ other = 0x0020;
+ break;
+ case 0x0163:
+ other = 0x021b;
+ break;
+ default:
+ break;
+ }
+ if ( other ) {
+ int oglyph = glyph_for_tqunicode( other );
+ if( oglyph && oglyph != glyphindex && glyphSet[oglyph] ) {
+ glyphname = "uni";
+ glyphname += toHex( tqunicode );
+ }
+ }
+ }
+ } else {
+ glyphname = "uni";
+ glyphname += toHex( tqunicode );
+ }
+ }
+ return glyphname;
+}
+
+void TQPSPrinterFontPrivate::download(TQTextStream &s, bool global)
+{
+ //printf("defining mapping for printer font %s\n",psname.latin1());
+ downloadMapping( s, global );
+}
+
+void TQPSPrinterFontPrivate::downloadMapping( TQTextStream &s, bool global )
+{
+ uchar rangeOffset = 0;
+ uchar numRanges = (uchar)(subsetCount/256 + 1);
+ uchar range;
+ TQMap<unsigned short, unsigned short> *subsetDict = &subset;
+ if ( !global ) {
+ rangeOffset = numRanges;
+ numRanges = pageSubsetCount/256 + 1;
+ subsetDict = &page_subset;
+ }
+ // build up inverse table
+ unsigned short *inverse = new unsigned short[numRanges * 256];
+ memset( inverse, 0, numRanges * 256 * sizeof( unsigned short ) );
+
+ TQMap<unsigned short, unsigned short>::iterator it;
+ for ( it = subsetDict->begin(); it != subsetDict->end(); ++it) {
+ const unsigned short &mapped = *it;
+ inverse[mapped] = it.key();
+ }
+
+ TQString vector;
+ TQString glyphname;
+
+ for (range=0; range < numRanges; range++) {
+ //printf("outputing range %04x\n",range*256);
+ vector = "%% Font Page ";
+ vector += toHex((uchar)(range + rangeOffset));
+ vector += "\n/";
+ vector += psname;
+ vector += "-ENC-";
+ vector += toHex((uchar)(range + rangeOffset));
+ vector += " [\n";
+
+ TQString line;
+ for(int k=0; k<256; k++ ) {
+ int c = range*256 + k;
+ unsigned short glyph = inverse[c];
+ glyphname = glyphName( glyph );
+ if ( line.length() + glyphname.length() > 76 ) {
+ vector += line;
+ vector += "\n";
+ line = "";
+ }
+ line += "/" + glyphname;
+ }
+ vector += line;
+ vector += "] def\n";
+ s << vector;
+ }
+
+ delete [] inverse;
+
+ // DEFINE BASE FONTS
+
+ for (range=0; range < numRanges; range++) {
+ s << "/";
+ s << psname;
+ s << "-Uni-";
+ s << toHex((uchar)(range + rangeOffset));
+ s << " ";
+ s << psname;
+ s << "-ENC-";
+ s << toHex((uchar)(range + rangeOffset));
+ if ( embedded() && embedFonts ) {
+ s << " /";
+ s << psname;
+ s << " MFEmb\n";
+ } else {
+ s << " " << psname << "List";
+ s << " MF\n";
+ }
+ }
+
+ // === write header ===
+ // int VMMin;
+ // int VMMax;
+
+ s << wrapDSC( "%%BeginFont: " + psname )
+ << "%!PS-AdobeFont-1.0 Composite Font\n"
+ << wrapDSC( "%%FontName: " + psname + "-Uni" )
+ << "%%Creator: Composite font created by TQt\n";
+
+ /* Start the dictionary which will eventually */
+ /* become the font. */
+ s << "25 dict begin\n"; // need to verify. Sivan
+
+ s << "/FontName /";
+ s << psname;
+ s << "-Uni";
+ s << " def\n";
+ s << "/PaintType 0 def\n";
+
+ // This is concatenated with the base fonts, so it should perform
+ // no transformation. Sivan
+ s << "/FontMatrix[1 0 0 1 0 0]def\n";
+
+ s << "/FontType ";
+ s << 0;
+ s << " def\n";
+
+ // now come composite font structures
+ // FMapTypes:
+ // 2: 8/8, 8 bits select the font, 8 the glyph
+
+ s << "/FMapType 2 def\n";
+
+ // The encoding in a composite font is used for indirection.
+ // Every char is split into a font-number and a character-selector.
+ // PostScript prints glyph number character-selector from the font
+ // FDepVector[ Encoding[ font-number ] ].
+
+ s << "/Encoding [";
+ for (range=0; range < rangeOffset + numRanges; range++) {
+ if (range % 16 == 0)
+ s << "\n";
+ else
+ s << " ";
+ s << range;
+ }
+ s << "]def\n";
+
+ // Descendent fonts
+
+ s << "/FDepVector [\n";
+ for (range=0; range < rangeOffset + numRanges; range++) {
+ s << "/";
+ s << psname;
+ s << "-Uni-";
+ s << toHex( range );
+ s << " tqfindfont\n";
+ }
+ s << "]def\n";
+
+ // === trailer ===
+
+ s << "FontName currentdict end definefont pop\n";
+ s << "%%EndFont\n";
+}
+
+
+// ================== TTF ====================
+
+typedef TQ_UINT8 BYTE;
+typedef TQ_UINT16 USHORT;
+typedef TQ_UINT16 uFWord;
+typedef TQ_INT16 SHORT;
+typedef TQ_INT16 FWord;
+typedef TQ_UINT32 ULONG;
+typedef TQ_INT32 FIXED;
+
+typedef struct {
+ TQ_INT16 whole;
+ TQ_UINT16 fraction;
+} Fixed; // 16.16 bit fixed-point number
+
+static float f2dot14( ushort s )
+{
+ float f = ((float)( s & 0x3fff ))/ 16384.;
+ f += (s & 0x8000) ? ( (s & 0x4000) ? -1 : -2 ) : ( (s & 0x4000) ? 1 : 0 );
+ return f;
+}
+
+typedef struct {
+ int* epts_ctr; /* array of contour endpoints */
+ int num_pts, num_ctr; /* number of points, number of coutours */
+ FWord* xcoor, *ycoor; /* arrays of x and y coordinates */
+ BYTE* tt_flags; /* array of TrueType flags */
+ double* area_ctr;
+ char* check_ctr;
+ int* ctrset; /* in contour index followed by out contour index */
+} charproc_data;
+
+
+class TQPSPrinterFontTTF
+ : public TQPSPrinterFontPrivate {
+public:
+ TQPSPrinterFontTTF(const TQFontEngine *f, TQByteArray& data);
+ virtual void download(TQTextStream& s, bool global);
+ virtual void drawText( TQTextStream &stream, const TQPoint &p, TQTextEngine *engine, int item,
+ const TQString &text, TQPSPrinterPrivate *d, TQPainter *paint);
+ // virtual ~TQPSPrinterFontTTF();
+
+ virtual bool embedded() { return TRUE; }
+private:
+ TQByteArray data;
+ TQMemArray<ushort> uni2glyph; // to speed up lookups
+ TQMemArray<ushort> glyph2uni; // to speed up lookups
+ bool defective; // if we can't process this file
+
+ BYTE* getTable(const char *);
+ void uni2glyphSetup();
+ unsigned short tqunicode_for_glyph(int glyphindex);
+ unsigned short glyph_for_tqunicode(unsigned short tqunicode);
+ int topost(FWord x) { return (int)( ((int)(x) * 1000 + HUPM) / unitsPerEm ); }
+
+#ifdef TQ_PRINTER_USE_TYPE42
+ void sfnts_pputBYTE(BYTE n,TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string);
+ void sfnts_pputUSHORT(USHORT n,TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string);
+ void sfnts_pputULONG(ULONG n,TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string);
+ void sfnts_end_string(TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string);
+ void sfnts_new_table(ULONG length,TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string);
+ void sfnts_glyf_table(ULONG oldoffset,
+ ULONG correct_total_length,
+ TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string);
+ void download_sfnts(TQTextStream& s);
+#endif
+
+ void subsetGlyph(int charindex,bool* glyphset);
+
+ void charproc(int charindex, TQTextStream& s, bool *glyphSet);
+ BYTE* charprocFindGlyphData(int charindex);
+ void charprocComposite(BYTE *glyph, TQTextStream& s, bool *glyphSet);
+ void charprocLoad(BYTE *glyph, charproc_data* cd);
+
+ int target_type; /* 42 or 3 */
+
+ int numTables; /* number of tables present */
+ TQString PostName; /* Font's PostScript name */
+ TQString FullName; /* Font's full name */
+ TQString FamilyName; /* Font's family name */
+ TQString Style; /* Font's style string */
+ TQString Copyright; /* Font's copyright string */
+ TQString Version; /* Font's version string */
+ TQString Trademark; /* Font's trademark string */
+ int llx,lly,urx,ury; /* bounding box */
+
+ Fixed TTVersion; /* Truetype version number from offset table */
+ Fixed MfrRevision; /* Revision number of this font */
+
+ BYTE *offset_table; /* Offset table in memory */
+ BYTE *post_table; /* 'post' table in memory */
+
+ BYTE *loca_table; /* 'loca' table in memory */
+ BYTE *glyf_table; /* 'glyf' table in memory */
+ BYTE *hmtx_table; /* 'hmtx' table in memory */
+
+ USHORT numberOfHMetrics;
+ int unitsPerEm; /* unitsPerEm converted to int */
+ int HUPM; /* half of above */
+
+ int numGlyphs; /* from 'post' table */
+
+ int indexToLocFormat; /* short or long offsets */
+
+};
+
+
+static ULONG getULONG(BYTE *p)
+{
+ int x;
+ ULONG val=0;
+
+ for(x=0; x<4; x++) {
+ val *= 0x100;
+ val += p[x];
+ }
+
+ return val;
+}
+
+static USHORT getUSHORT(BYTE *p)
+{
+ int x;
+ USHORT val=0;
+
+ for(x=0; x<2; x++) {
+ val *= 0x100;
+ val += p[x];
+ }
+
+ return val;
+}
+
+static Fixed getFixed(BYTE *s)
+{
+ Fixed val={0,0};
+
+ val.whole = ((s[0] * 256) + s[1]);
+ val.fraction = ((s[2] * 256) + s[3]);
+
+ return val;
+}
+
+static FWord getFWord(BYTE* s) { return (FWord) getUSHORT(s); }
+static uFWord getuFWord(BYTE* s) { return (uFWord) getUSHORT(s); }
+static SHORT getSHORT(BYTE* s) { return (SHORT) getUSHORT(s); }
+
+#if 0
+static const char * const Apple_CharStrings[]={
+ ".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign",
+ "dollar","percent","ampersand","quotesingle","parenleft","parenright",
+ "asterisk","plus", "comma","hyphen","period","slash","zero","one","two",
+ "three","four","five","six","seven","eight","nine","colon","semicolon",
+ "less","equal","greater","question","at","A","B","C","D","E","F","G","H","I",
+ "J","K", "L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
+ "bracketleft","backslash","bracketright","asciicircum","underscore","grave",
+ "a","b","c","d","e","f","g","h","i","j","k", "l","m","n","o","p","q","r","s",
+ "t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde",
+ "Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis",
+ "aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla",
+ "eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex",
+ "idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde",
+ "uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent",
+ "sterling","section","bullet","paragraph","germandbls","registered",
+ "copyright","trademark","acute","dieresis","notequal","AE","Oslash",
+ "infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff",
+ "summation","product","pi","integral","ordfeminine","ordmasculine","Omega",
+ "ae","oslash","questiondown","exclamdown","logicalnot","radical","florin",
+ "approxequal","Delta","guillemotleft","guillemotright","ellipsis",
+ "nobreakspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash",
+ "quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge",
+ "ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright",
+ "fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase",
+ "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave",
+ "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple",
+ "Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde",
+ "macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron",
+ "Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth",
+ "Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior",
+ "twosuperior","threesuperior","onehalf","onequarter","threequarters","franc",
+ "Gbreve","gbreve","Idot","Scedilla","scedilla","Cacute","cacute","Ccaron",
+ "ccaron","dmacron","markingspace","capslock","shift","propeller","enter",
+ "markingtabrtol","markingtabltor","control","markingdeleteltor",
+ "markingdeletertol","option","escape","parbreakltor","parbreakrtol",
+ "newpage","checkmark","linebreakltor","linebreakrtol","markingnobreakspace",
+ "diamond","appleoutline"};
+#endif
+
+// #define DEBUG_TRUETYPE
+
+TQPSPrinterFontTTF::TQPSPrinterFontTTF(const TQFontEngine *f, TQByteArray& d)
+{
+ data = d;
+ defective = FALSE;
+
+ BYTE *ptr;
+
+ target_type = 3; // will work on any printer
+ //target_type = 42; // works with gs, faster, better quality
+
+#ifdef TQ_PRINTER_USE_TYPE42
+ char* environment_preference = getenv("TQT_TTFTOPS");
+ if (environment_preference) {
+ if (TQString(environment_preference) == "42")
+ target_type = 42;
+ else if (TQString(environment_preference) == "3")
+ target_type = 3;
+ else
+ qWarning("The value of TQT_TTFTOPS must be 42 or 3");
+ }
+#endif
+ offset_table = (unsigned char*) data.data(); /* first 12 bytes */
+
+ /* Determine how many directory entries there are. */
+ numTables = getUSHORT( offset_table + 4 );
+
+ /* Extract information from the "Offset" table. */
+ TTVersion = getFixed( offset_table );
+
+ /* Load the "head" table and extract information from it. */
+ ptr = getTable("head");
+ if ( !ptr ) {
+ defective = TRUE;
+ return;
+ }
+ MfrRevision = getFixed( ptr + 4 ); /* font revision number */
+ unitsPerEm = getUSHORT( ptr + 18 );
+ HUPM = unitsPerEm / 2;
+#ifdef DEBUG_TRUETYPE
+ printf("unitsPerEm=%d",(int)unitsPerEm);
+#endif
+ llx = topost( getFWord( ptr + 36 ) ); /* bounding box info */
+ lly = topost( getFWord( ptr + 38 ) );
+ urx = topost( getFWord( ptr + 40 ) );
+ ury = topost( getFWord( ptr + 42 ) );
+ indexToLocFormat = getSHORT( ptr + 50 ); /* size of 'loca' data */
+ if(indexToLocFormat != 0 && indexToLocFormat != 1) {
+ qWarning("TrueType font is unusable because indexToLocFormat != 0");
+ defective = TRUE;
+ return;
+ }
+ if( getSHORT(ptr+52) != 0 ) {
+ qWarning("TrueType font is unusable because glyphDataFormat != 0");
+ defective = TRUE;
+ return;
+ }
+
+ // === Load information from the "name" table ===
+
+ /* Set default values to avoid future references to */
+ /* undefined pointers. */
+
+ psname = FullName = FamilyName = Version = Style = "unknown";
+ Copyright = "No copyright notice";
+ Trademark = "No trademark notice";
+
+ BYTE* table_ptr = getTable("name"); /* pointer to table */
+ if ( !table_ptr ) {
+ defective = TRUE;
+ qDebug("couldn't tqfind name table" );
+ return;
+ }
+ int numrecords = getUSHORT( table_ptr + 2 ); /* number of names */
+ char* strings = (char *)table_ptr + getUSHORT( table_ptr + 4 ); /* start of string storage */
+
+ BYTE* ptr2 = table_ptr + 6;
+ for(int x=0; x < numrecords; x++,ptr2+=12) {
+ int platform = getUSHORT(ptr2);
+ //int encoding = getUSHORT(ptr2+2);
+ //int language = getUSHORT(ptr2+4);
+ int nameid = getUSHORT(ptr2+6);
+ int length = getUSHORT(ptr2+8);
+ int offset = getUSHORT(ptr2+10);
+
+ if( platform == 1 && nameid == 0 )
+ Copyright.setLatin1(strings+offset,length);
+
+ if( platform == 1 && nameid == 1 )
+ FamilyName.setLatin1(strings+offset,length);
+
+ if( platform == 1 && nameid == 2 )
+ Style.setLatin1(strings+offset,length);
+
+ if( platform == 1 && nameid == 4 )
+ FullName.setLatin1(strings+offset,length);
+
+ if( platform == 1 && nameid == 5 )
+ Version.setLatin1(strings+offset,length);
+
+ if( platform == 1 && nameid == 6 )
+ psname.setLatin1(strings+offset,length);
+
+ if( platform == 1 && nameid == 7 )
+ Trademark.setLatin1(strings+offset,length);
+
+ }
+ psname.tqreplace(' ', '-');
+ psname.tqreplace("/", "");
+ if (psname.isEmpty())
+ psname = makePSFontName(f);
+
+ //read_cmap(font);
+
+ /* We need to have the PostScript table around. */
+
+ post_table = getTable("post");
+#if 0
+ if ( post_table ) {
+ Fixed post_format = getFixed( post_table );
+
+ if( post_format.whole != 2 || post_format.fraction != 0 ) {
+ qWarning("TrueType font does not have a format 2.0 'post' table");
+ qWarning("post format is %d.%d",post_format.whole,post_format.fraction);
+ // Sivan Feb 2001: no longer defective.
+ // defective = TRUE;
+ }
+ }
+#endif
+ BYTE *maxp = getTable("maxp");
+ if ( !maxp ) {
+ defective = TRUE;
+ qDebug("no maxp table in font");
+ return;
+ }
+ numGlyphs = getUSHORT( maxp + 4 );
+// qDebug("number of glyphs is %d", numGlyphs);
+ tqreplacementList = makePSFontNameList( f, psname );
+ uni2glyphSetup();
+}
+
+
+void TQPSPrinterFontTTF::drawText( TQTextStream &stream, const TQPoint &p, TQTextEngine *engine, int item,
+ const TQString &text, TQPSPrinterPrivate *d, TQPainter *paint)
+{
+ // we draw glyphs here to get correct shaping of arabic and indic
+ TQScriptItem &si = engine->items[item];
+ engine->tqshape( item );
+ int len = si.num_glyphs;
+
+ int x = p.x() + si.x;
+ int y = p.y() + si.y;
+ if ( y != d->textY || d->textY == 0 )
+ stream << y << " Y";
+ d->textY = y;
+
+ TQCString xyarray;
+ int xo = 0;
+ int yo = 0;
+
+ glyph_t *glyphs = engine->glyphs( &si );
+ advance_t *advances = engine->advances( &si );
+ qoffset_t *offsets = engine->offsets( &si );
+#ifdef TQ_WS_X11
+ int type = si.fontEngine->type();
+ bool glyphIndices = (type == TQFontEngine::Xft);
+ // This helps us get arabic for XLFD fonts working. In that case we have a Unicode
+ // cmap (== 0), and the glyphs array tqcontains the tqshaped string.
+ bool useGlyphAsUnicode = (type == TQFontEngine::XLFD && si.fontEngine->cmap() == 0);
+#else // TQ_WS_TQWS
+ const bool glyphIndices = FALSE;
+ const bool useGlyphAsUnicode = TRUE;
+#endif
+ stream << "<";
+ if ( si.analysis.bidiLevel % 2 ) {
+ for ( int i = len-1; i >=0; i-- ) {
+ // map tqunicode is not really the correct name, as we map glyphs, but we also download glyphs, so this works
+ unsigned short glyph;
+ if (glyphIndices)
+ glyph = glyphs[i];
+ else
+ glyph = glyph_for_tqunicode(useGlyphAsUnicode ? glyphs[i] : text.tqunicode()[i].tqunicode());
+ stream << toHex(mapUnicode(glyph));
+ if ( i != len-1 ) {
+ xyarray += toInt( xo + offsets[i].x + advances[i+1] );
+ xyarray += " ";
+ xyarray += toInt( yo + offsets[i].y );
+ xyarray += " ";
+ xo = -offsets[i].x;
+ yo = -offsets[i].y;
+ }
+ }
+ } else {
+ for ( int i = 0; i < len; i++ ) {
+ // map tqunicode is not really the correct name, as we map glyphs, but we also download glyphs, so this works
+ unsigned short glyph;
+ if (glyphIndices)
+ glyph = glyphs[i];
+ else
+ glyph = glyph_for_tqunicode(useGlyphAsUnicode ? glyphs[i] : text.tqunicode()[i].tqunicode());
+ stream << toHex(mapUnicode(glyph));
+ if ( i ) {
+ xyarray += toInt( xo + offsets[i].x + advances[i-1] );
+ xyarray += " ";
+ xyarray += toInt( yo + offsets[i].y );
+ xyarray += " ";
+ xo = -offsets[i].x;
+ yo = -offsets[i].y;
+ }
+ }
+ }
+ stream << ">";
+
+ stream << "[" << xyarray << "0 0]";
+ stream << si.width << " " << x;
+
+ if ( paint->font().underline() )
+ stream << ' ' << y + d->fm.underlinePos() + d->fm.lineWidth()
+ << " " << d->fm.lineWidth() << " Tl";
+ if ( paint->font().strikeOut() )
+ stream << ' ' << y + d->fm.strikeOutPos()
+ << " " << d->fm.lineWidth() << " Tl";
+ stream << " XYT\n";
+
+}
+
+
+void TQPSPrinterFontTTF::download(TQTextStream& s,bool global)
+{
+ emitPSFontNameList( s, psname, tqreplacementList);
+ if ( !embedFonts ) {
+ downloadMapping(s, global);
+ return;
+ }
+
+ //qDebug("downloading ttf font %s", psname.latin1() );
+ //qDebug("target type=%d", target_type);
+ global_dict = global;
+ TQMap<unsigned short, unsigned short> *subsetDict = &subset;
+ if ( !global )
+ subsetDict = &page_subset;
+
+ downloaded = TRUE;
+
+ if (defective) {
+ s << "% Font ";
+ s << FullName;
+ s << " cannot be downloaded\n";
+ return;
+ }
+
+ // === write header ===
+ int VMMin;
+ int VMMax;
+
+ s << wrapDSC( "%%BeginFont: " + FullName );
+ if( target_type == 42 ) {
+ s << "%!PS-TrueTypeFont-"
+ << TTVersion.whole
+ << "."
+ << TTVersion.fraction
+ << "-"
+ << MfrRevision.whole
+ << "."
+ << MfrRevision.fraction
+ << "\n";
+ } else {
+ /* If it is not a Type 42 font, we will use a different format. */
+ s << "%!PS-Adobe-3.0 Resource-Font\n";
+ } /* See RBIIp 641 */
+
+ if( Copyright != (char*)NULL ) {
+ s << wrapDSC( "%%Copyright: " + Copyright );
+ }
+
+ if( target_type == 42 )
+ s << "%%Creator: Converted from TrueType to type 42 by TQt\n";
+ else
+ s << "%%Creator: Converted from TrueType by TQt\n";
+
+ /* If VM usage information is available, print it. */
+ if( target_type == 42 && post_table)
+ {
+ VMMin = (int)getULONG( post_table + 16 );
+ VMMax = (int)getULONG( post_table + 20 );
+ if( VMMin > 0 && VMMax > 0 )
+ s << "%%VMUsage: " << VMMin << " " << VMMax << "\n";
+ }
+
+ /* Start the dictionary which will eventually */
+ /* become the font. */
+ if( target_type != 3 ) {
+ s << "15 dict begin\n";
+ } else {
+ s << "25 dict begin\n";
+
+ /* Type 3 fonts will need some subroutines here. */
+ s << "/_d{bind def}bind def\n";
+ s << "/_m{moveto}_d\n";
+ s << "/_l{lineto}_d\n";
+ s << "/_cl{closepath eofill}_d\n";
+ s << "/_c{curveto}_d\n";
+ s << "/_sc{7 -1 roll{setcachetqdevice}{pop pop pop pop pop pop}ifelse}_d\n";
+ s << "/_e{exec}_d\n";
+ }
+
+ s << "/FontName /";
+ s << psname;
+ s << " def\n";
+ s << "/PaintType 0 def\n";
+
+ if(target_type == 42)
+ s << "/FontMatrix[1 0 0 1 0 0]def\n";
+ else
+ s << "/FontMatrix[.001 0 0 .001 0 0]def\n";
+
+ s << "/FontBBox[";
+ s<< llx;
+ s << " ";
+ s<< lly;
+ s << " ";
+ s<< urx;
+ s << " ";
+ s<< ury;
+ s << "]def\n";
+
+ s << "/FontType ";
+ s<< target_type;
+ s << " def\n";
+
+ // === write encoding ===
+
+ s << "/Encoding StandardEncoding def\n";
+
+ // === write fontinfo dict ===
+
+ /* We create a sub dictionary named "FontInfo" where we */
+ /* store information which though it is not used by the */
+ /* interpreter, is useful to some programs which will */
+ /* be printing with the font. */
+ s << "/FontInfo 10 dict dup begin\n";
+
+ /* These names come from the TrueType font's "name" table. */
+ s << "/FamilyName (";
+ s << FamilyName;
+ s << ") def\n";
+
+ s << "/FullName (";
+ s << FullName;
+ s << ") def\n";
+
+ s << "/Notice (";
+ s << Copyright;
+ s << " ";
+ s << Trademark;
+ s << ") def\n";
+
+ /* This information is not quite correct. */
+ s << "/Weight (";
+ s << Style;
+ s << ") def\n";
+
+ /* Some fonts have this as "version". */
+ s << "/Version (";
+ s << Version;
+ s << ") def\n";
+
+ /* Some information from the "post" table. */
+ if ( post_table ) {
+ Fixed ItalicAngle = getFixed( post_table + 4 );
+ s << "/ItalicAngle ";
+ s << ItalicAngle.whole;
+ s << ".";
+ s << ItalicAngle.fraction;
+ s << " def\n";
+
+ s << "/isFixedPitch ";
+ s << (getULONG( post_table + 12 ) ? "true" : "false" );
+ s << " def\n";
+
+ s << "/UnderlinePosition ";
+ s << (int)getFWord( post_table + 8 );
+ s << " def\n";
+
+ s << "/UnderlineThickness ";
+ s << (int)getFWord( post_table + 10 );
+ s << " def\n";
+ }
+ s << "end readonly def\n";
+
+#ifdef TQ_PRINTER_USE_TYPE42
+ /* If we are generating a type 42 font, */
+ /* emmit the sfnts array. */
+ if( target_type == 42 )
+ download_sfnts(s);
+#endif
+ /* If we are generating a Type 3 font, we will need to */
+ /* have the 'loca' and 'glyf' tables arround while */
+ /* we are generating the CharStrings. */
+ if(target_type == 3)
+ {
+ BYTE *ptr; /* We need only one value */
+ ptr = getTable("hhea");
+ numberOfHMetrics = getUSHORT(ptr + 34);
+
+ loca_table = getTable("loca");
+ glyf_table = getTable("glyf");
+ hmtx_table = getTable("hmtx");
+ }
+
+ // === CharStrings array ===
+
+ // subsetting. We turn a char subset into a glyph subset
+ // and we mark as used the base glyphs of used composite glyphs.
+
+ bool glyphset[65536];
+ for(int c=0; c < 65536; c++)
+ glyphset[c] = FALSE;
+ glyphset[0] = TRUE; // always output .notdef
+
+ TQMap<unsigned short, unsigned short>::iterator it;
+ for( it = subsetDict->begin(); it != subsetDict->end(); ++it ) {
+ subsetGlyph( it.key(), glyphset );
+ }
+ int nGlyphs = numGlyphs;
+ if ( target_type == 3 ) {
+ nGlyphs = 0;;
+ for(int c=0; c < 65536; c++)
+ if ( glyphset[c] ) nGlyphs++;
+ }
+
+ s << "/CharStrings ";
+ s << nGlyphs;
+ s << " dict dup begin\n";
+
+ // Emmit one key-value pair for each glyph.
+ for(int x=0; x < 65536; x++) {
+ if(target_type == 42) {
+ s << "/";
+ s << glyphName( x );
+ s << " ";
+ s << x;
+ s << " def\n";
+ } else { /* type 3 */
+ if (!glyphset[x]) continue;
+
+ //qDebug("emitting charproc for glyph %d, name=%s", x, glyphName(x).latin1() );
+ s << "/";
+ s << glyphName( x, glyphset );
+ s << "{";
+ charproc(x,s, glyphset);
+ s << "}_d\n"; /* "} bind def" */
+ }
+ }
+
+ s << "end readonly def\n";
+
+ // === trailer ===
+
+ /* If we are generating a type 3 font, we need to provide */
+ /* a BuildGlyph and BuildChar proceedures. */
+ if( target_type == 3 ) {
+ s << "\n";
+
+ s << "/BuildGlyph\n";
+ s << " {exch begin\n"; /* start font dictionary */
+ s << " CharStrings exch\n";
+ s << " 2 copy known not{pop /.notdef}if\n";
+ s << " true 3 1 roll get exec\n";
+ s << " end}_d\n";
+
+ s << "\n";
+
+ /* This proceedure is for compatiblity with */
+ /* level 1 interpreters. */
+ s << "/BuildChar {\n";
+ s << " 1 index /Encoding get exch get\n";
+ s << " 1 index /BuildGlyph get exec\n";
+ s << "}_d\n";
+
+ s << "\n";
+
+ }
+
+ /* If we are generating a type 42 font, we need to check to see */
+ /* if this PostScript interpreter understands type 42 fonts. If */
+ /* it doesn't, we will hope that the Apple TrueType rasterizer */
+ /* has been loaded and we will adjust the font accordingly. */
+ /* I found out how to do this by examining a TrueType font */
+ /* generated by a Macintosh. That is where the TrueType interpreter */
+ /* setup instructions and part of BuildGlyph came from. */
+ else if( target_type == 42 ) {
+ s << "\n";
+
+ /* If we have no "resourcestatus" command, or FontType 42 */
+ /* is unknown, leave "true" on the stack. */
+ s << "systemdict/resourcestatus known\n";
+ s << " {42 /FontType resourcestatus\n";
+ s << " {pop pop false}{true}ifelse}\n";
+ s << " {true}ifelse\n";
+
+ /* If true, execute code to produce an error message if */
+ /* we can't tqfind Apple's TrueDict in VM. */
+ s << "{/TrueDict where{pop}{(%%[ Error: no TrueType rasterizer ]%%)= flush}ifelse\n";
+
+ /* Since we are expected to use Apple's TrueDict TrueType */
+ /* reasterizer, change the font type to 3. */
+ s << "/FontType 3 def\n";
+
+ /* Define a string to hold the state of the Apple */
+ /* TrueType interpreter. */
+ s << " /TrueState 271 string def\n";
+
+ /* It looks like we get information about the resolution */
+ /* of the printer and store it in the TrueState string. */
+ s << " TrueDict begin sfnts save\n";
+ s << " 72 0 matrix defaultmatrix dtransform dup\n";
+ s << " mul exch dup mul add sqrt cvi 0 72 matrix\n";
+ s << " defaultmatrix dtransform dup mul exch dup\n";
+ s << " mul add sqrt cvi 3 -1 roll restore\n";
+ s << " TrueState initer end\n";
+
+ /* This BuildGlyph procedure will look the name up in the */
+ /* CharStrings array, and then check to see if what it gets */
+ /* is a procedure. If it is, it executes it, otherwise, it */
+ /* lets the TrueType rasterizer loose on it. */
+
+ /* When this proceedure is executed the stack tqcontains */
+ /* the font dictionary and the character name. We */
+ /* exchange arguments and move the dictionary to the */
+ /* dictionary stack. */
+ s << " /BuildGlyph{exch begin\n";
+ /* stack: charname */
+
+ /* Put two copies of CharStrings on the stack and consume */
+ /* one testing to see if the charname is defined in it, */
+ /* leave the answer on the stack. */
+ s << " CharStrings dup 2 index known\n";
+ /* stack: charname CharStrings bool */
+
+ /* Exchange the CharStrings dictionary and the charname, */
+ /* but if the answer was false, tqreplace the character name */
+ /* with ".notdef". */
+ s << " {exch}{exch pop /.notdef}ifelse\n";
+ /* stack: CharStrings charname */
+
+ /* Get the value from the CharStrings dictionary and see */
+ /* if it is executable. */
+ s << " get dup xcheck\n";
+ /* stack: CharStrings_entry */
+
+ /* If is a proceedure. Execute according to RBIIp 277-278. */
+ s << " {currentdict systemdict begin begin exec end end}\n";
+
+ /* Is a TrueType character index, let the rasterizer at it. */
+ s << " {TrueDict begin /bander load cvlit exch TrueState render end}\n";
+
+ s << " ifelse\n";
+
+ /* Pop the font's dictionary off the stack. */
+ s << " end}bind def\n";
+
+ /* This is the level 1 compatibility BuildChar procedure. */
+ /* See RBIIp 281. */
+ s << " /BuildChar{\n";
+ s << " 1 index /Encoding get exch get\n";
+ s << " 1 index /BuildGlyph get exec\n";
+ s << " }bind def\n";
+
+ /* Here we close the condition which is true */
+ /* if the printer has no built-in TrueType */
+ /* rasterizer. */
+ s << "}if\n";
+ s << "\n";
+ } /* end of if Type 42 not understood. */
+
+ s << "FontName currentdict end definefont pop\n";
+
+ downloadMapping(s, global);
+ s << "%%EndFont\n";
+}
+
+BYTE* TQPSPrinterFontTTF::getTable(const char* name)
+{
+ BYTE *ptr;
+ int x;
+
+ /* We must search the table directory. */
+ ptr = offset_table + 12;
+ x=0;
+ while (x != numTables) {
+ if( strncmp((const char *)ptr,name,4) == 0 ) {
+ ULONG offset;
+ //ULONG length;
+ BYTE *table;
+
+ offset = getULONG( ptr + 8 );
+ //length = getULONG( ptr + 12 );
+
+ table = offset_table + offset;
+ return table;
+ }
+
+ x++;
+ ptr += 16;
+ }
+
+ return 0;
+}
+
+void TQPSPrinterFontTTF::uni2glyphSetup()
+{
+ uni2glyph.resize(65536);
+ int i;
+ for (i=0; i<65536; i++) uni2glyph[i] = 0x0000;
+ glyph2uni.resize(65536);
+ for (i=0; i<65536; i++) glyph2uni[i] = 0x0000;
+
+ unsigned char* cmap = getTable("cmap");
+ int pos = 0;
+
+ //USHORT version = getUSHORT(cmap + pos);
+ pos += 2;
+ USHORT nmaps = getUSHORT(cmap + pos); pos += 2;
+
+ //fprintf(stderr,"cmap version %d (should be 0), %d maps\n",version,nmaps);
+
+ ULONG offset = 0;
+ int map = -1;
+ bool symbol = TRUE;
+ for (i=0; i<nmaps; i++) {
+ USHORT platform = getUSHORT(cmap+pos); pos+=2;
+ USHORT encoding = getUSHORT(cmap+pos); pos+=2;
+ offset = getULONG( cmap+pos); pos+=4;
+ //fprintf(stderr,"[%d] plat %d enc %d\n",i,platform,encoding);
+ if (platform == 3 && encoding == 1) {
+ map = i;
+ symbol = FALSE;
+ break; // tqunicode
+ }
+ if (platform == 3 && encoding == 0) {
+ // symbol, continue looking
+ map = i;
+ }
+ }
+ if (map==nmaps) {
+ qWarning("Font does not have tqunicode encoding\n");
+ return; // no tqunicode encoding!
+ }
+
+ pos = 8*map;
+ //fprintf(stderr,"Doing Unicode encoding\n");
+
+ pos = offset;
+ USHORT format = getUSHORT(cmap+pos); pos+=2;
+ //fprintf(stderr,"Unicode cmap format %d\n",format);
+
+ if (format != 4) {
+ //qWarning("Unicode cmap format is not 4");
+ return;
+ }
+
+ pos += 2; // length
+ pos += 2; // version
+ USHORT segcount = getUSHORT(cmap+pos) / 2; pos+=2;
+
+ //fprintf(stderr,"Unicode cmap seg count %d\n",segcount);
+
+ // skip search data
+ pos += 2;
+ pos += 2;
+ pos += 2;
+
+ unsigned char* endcode = cmap + offset + 14;
+ unsigned char* startcode = cmap + offset + 16 + 2*segcount;
+ unsigned char* iddelta = cmap + offset + 16 + 4*segcount;
+ unsigned char* idrangeoff = cmap + offset + 16 + 6*segcount;
+ //unsigned char* glyphid = cmap + offset + 16 + 8*segcount;
+ for (i=0; i<segcount; i++) {
+ USHORT endcode_i = getUSHORT(endcode +2*i);
+ USHORT startcode_i = getUSHORT(startcode +2*i);
+ SHORT iddelta_i = getSHORT(iddelta +2*i);
+ USHORT idrangeoff_i = getUSHORT(idrangeoff+2*i);
+
+// fprintf(stderr,"[%d] %04x-%04x (%x %x)\n",
+// i,startcode_i,endcode_i,iddelta_i,idrangeoff_i);
+ if (endcode_i == 0xffff) break; // last dummy segment
+
+ if (idrangeoff_i == 0) {
+ for (USHORT c = startcode_i; c <= endcode_i; c++) {
+ USHORT g = c + iddelta_i; // glyph index
+ if ( g != 0 ) {
+ uni2glyph[g] = c;
+ glyph2uni[c] = g;
+ }
+ }
+ } else {
+ for (USHORT c = startcode_i; c <= endcode_i; c++) {
+ USHORT g = getUSHORT(idrangeoff+2*i
+ + 2*(c - startcode_i)
+ + idrangeoff_i);
+ if ( g != 0 ) {
+ uni2glyph[g] = c;
+ glyph2uni[c] = g;
+ }
+ }
+ }
+ }
+ if (symbol && glyph2uni[0x40] == 0 && glyph2uni[0xf040] != 0) {
+ // map 0xf000-0xf0ff into latin1 range.
+ for (int i = 0; i < 0x100; ++i) {
+ if (!glyph2uni[i])
+ glyph2uni[i] = glyph2uni[i+0xf000];
+
+ }
+ }
+}
+
+USHORT TQPSPrinterFontTTF::tqunicode_for_glyph(int glyphindex)
+{
+ return uni2glyph[glyphindex];
+}
+
+USHORT TQPSPrinterFontTTF::glyph_for_tqunicode(unsigned short tqunicode)
+{
+ return glyph2uni[tqunicode];
+}
+
+#ifdef TQ_PRINTER_USE_TYPE42
+// ****************** SNFTS ROUTINES *******
+
+/*-------------------------------------------------------------------
+** sfnts routines
+** These routines generate the PostScript "sfnts" array which
+** tqcontains one or more strings which contain a reduced version
+** of the TrueType font.
+**
+** A number of functions are required to accomplish this rather
+** complicated task.
+-------------------------------------------------------------------*/
+
+// Write a BYTE as a hexadecimal value as part of the sfnts array.
+
+void TQPSPrinterFontTTF::sfnts_pputBYTE(BYTE n,TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string)
+{
+ static const char hexdigits[]="0123456789ABCDEF";
+
+ if(!in_string) {
+ s << "<";
+ string_len = 0;
+ line_len++;
+ in_string = TRUE;
+ }
+
+ s << hexdigits[ n / 16 ] ;
+ s << hexdigits[ n % 16 ] ;
+ string_len++;
+ line_len+=2;
+
+ if(line_len > 70) {
+ s << "\n";
+ line_len=0;
+ }
+}
+
+// Write a USHORT as a hexadecimal value as part of the sfnts array.
+
+void TQPSPrinterFontTTF::sfnts_pputUSHORT(USHORT n,TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string)
+{
+ sfnts_pputBYTE(n / 256,s, string_len, line_len, in_string);
+ sfnts_pputBYTE(n % 256,s, string_len, line_len, in_string);
+}
+
+
+// Write a ULONG as part of the sfnts array.
+
+void TQPSPrinterFontTTF::sfnts_pputULONG(ULONG n,TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string)
+{
+ int x1 = n % 256; n /= 256;
+ int x2 = n % 256; n /= 256;
+ int x3 = n % 256; n /= 256;
+
+ sfnts_pputBYTE(n,s , string_len, line_len, in_string);
+ sfnts_pputBYTE(x3,s, string_len, line_len, in_string);
+ sfnts_pputBYTE(x2,s, string_len, line_len, in_string);
+ sfnts_pputBYTE(x1,s, string_len, line_len, in_string);
+}
+
+/*
+** This is called whenever it is
+** necessary to end a string in the sfnts array.
+**
+** (The array must be broken into strings which are
+** no longer than 64K characters.)
+*/
+void TQPSPrinterFontTTF::sfnts_end_string(TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string)
+{
+ if(in_string) {
+ string_len=0; /* fool sfnts_pputBYTE() */
+
+ // s << "\n% dummy byte:\n";
+
+ // extra byte for pre-2013 compatibility
+ sfnts_pputBYTE(0, s, string_len, line_len, in_string);
+
+ s << ">";
+ line_len++;
+ }
+
+ in_string=FALSE;
+}
+
+/*
+** This is called at the start of each new table.
+** The argement is the length in bytes of the table
+** which will follow. If the new table will not fit
+** in the current string, a new one is started.
+*/
+void TQPSPrinterFontTTF::sfnts_new_table(ULONG length,TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string)
+{
+ if( (string_len + length) > 65528 )
+ sfnts_end_string(s, string_len, line_len, in_string);
+}
+
+/*
+** We may have to break up the 'glyf' table. That is the reason
+** why we provide this special routine to copy it into the sfnts
+** array.
+*/
+void TQPSPrinterFontTTF::sfnts_glyf_table(ULONG oldoffset,
+ ULONG correct_total_length,
+ TQTextStream& s,
+ int& string_len, int& line_len, bool& in_string)
+
+{
+ int x;
+ ULONG off;
+ ULONG length;
+ int c;
+ ULONG total=0; /* running total of bytes written to table */
+
+ loca_table = getTable("loca");
+
+ int font_off = oldoffset;
+
+ /* Copy the glyphs one by one */
+ for(x=0; x < numGlyphs; x++) {
+ /* Read the glyph offset from the index-to-location table. */
+ if(indexToLocFormat == 0) {
+ off = getUSHORT( loca_table + (x * 2) );
+ off *= 2;
+ length = getUSHORT( loca_table + ((x+1) * 2) );
+ length *= 2;
+ length -= off;
+ } else {
+ off = getULONG( loca_table + (x * 4) );
+ length = getULONG( loca_table + ((x+1) * 4) );
+ length -= off;
+ }
+
+ // fprintf(stderr,"glyph length=%d",(int)length);
+
+ /* Start new string if necessary. */
+ sfnts_new_table( (int)length, s, string_len, line_len, in_string );
+
+ /*
+ ** Make sure the glyph is padded out to a
+ ** two byte boundary.
+ */
+ if( length % 2 ) {
+ qWarning("TrueType font tqcontains a 'glyf' table without 2 byte padding");
+ defective = TRUE;
+ return;
+ }
+
+ /* Copy the bytes of the glyph. */
+ while( length-- ) {
+ c = offset_table[ font_off ];
+ font_off++;
+
+ sfnts_pputBYTE(c, s, string_len, line_len, in_string);
+ total++; /* add to running total */
+ }
+ }
+
+ /* Pad out to full length from table directory */
+ while( total < correct_total_length ) {
+ sfnts_pputBYTE(0, s, string_len, line_len, in_string);
+ total++;
+ }
+
+ /* Look for unexplainable descrepancies between sizes */
+ if( total != correct_total_length ) {
+ qWarning("TQPSPrinterFontTTF::sfnts_glyf_table: total != correct_total_length");
+ defective = TRUE;
+ return;
+ }
+}
+
+/*
+** Here is the routine which ties it all together.
+**
+** Create the array called "sfnts" which
+** holds the actual TrueType data.
+*/
+
+void TQPSPrinterFontTTF::download_sfnts(TQTextStream& s)
+{
+ // tables worth including in a type 42 font
+ char *table_names[]= {
+ "cvt ",
+ "fpgm",
+ "glyf",
+ "head",
+ "hhea",
+ "hmtx",
+ "loca",
+ "maxp",
+ "prep"
+ };
+
+ struct { /* The location of each of */
+ ULONG oldoffset; /* the above tables. */
+ ULONG newoffset;
+ ULONG length;
+ ULONG checksum;
+ } tables[9];
+
+ int c; /* Input character. */
+ int diff;
+ int count; /* How many `important' tables did we tqfind? */
+
+ BYTE* ptr = offset_table + 12; // original table directory
+ ULONG nextoffset=0;
+ count=0;
+
+ /*
+ ** Find the tables we want and store there vital
+ ** statistics in tables[].
+ */
+ for(int x=0; x < 9; x++ ) {
+ do {
+ diff = strncmp( (char*)ptr, table_names[x], 4 );
+
+ if( diff > 0 ) { /* If we are past it. */
+ tables[x].length = 0;
+ diff = 0;
+ }
+ else if( diff < 0 ) { /* If we haven't hit it yet. */
+ ptr += 16;
+ }
+ else if( diff == 0 ) { /* Here it is! */
+ tables[x].newoffset = nextoffset;
+ tables[x].checksum = getULONG( ptr + 4 );
+ tables[x].oldoffset = getULONG( ptr + 8 );
+ tables[x].length = getULONG( ptr + 12 );
+ nextoffset += ( ((tables[x].length + 3) / 4) * 4 );
+ count++;
+ ptr += 16;
+ }
+ } while(diff != 0);
+ } /* end of for loop which passes over the table directory */
+
+ /* Begin the sfnts array. */
+
+ s << "/sfnts[<";
+
+ bool in_string=TRUE;
+ int string_len=0;
+ int line_len=8;
+
+ /* Generate the offset table header */
+ /* Start by copying the TrueType version number. */
+ ptr = offset_table;
+ for(int x=0; x < 4; x++)
+ sfnts_pputBYTE( *(ptr++) , s, string_len, line_len, in_string );
+
+ /* Now, generate those silly numTables numbers. */
+ sfnts_pputUSHORT(count,s, string_len, line_len, in_string); /* number of tables */
+ if( count == 9 ) {
+ sfnts_pputUSHORT(7,s, string_len, line_len, in_string); /* searchRange */
+ sfnts_pputUSHORT(3,s, string_len, line_len, in_string); /* entrySelector */
+ sfnts_pputUSHORT(81,s, string_len, line_len, in_string); /* rangeShift */
+ }
+ else {
+ qWarning("Fewer than 9 tables selected");
+ }
+
+ /* Now, emmit the table directory. */
+ for(int x=0; x < 9; x++) {
+ if( tables[x].length == 0 ) /* Skip missing tables */
+ continue;
+
+ /* Name */
+ sfnts_pputBYTE( table_names[x][0], s, string_len, line_len, in_string);
+ sfnts_pputBYTE( table_names[x][1], s, string_len, line_len, in_string);
+ sfnts_pputBYTE( table_names[x][2], s, string_len, line_len, in_string);
+ sfnts_pputBYTE( table_names[x][3], s, string_len, line_len, in_string);
+
+ /* Checksum */
+ sfnts_pputULONG( tables[x].checksum, s, string_len, line_len, in_string );
+
+ /* Offset */
+ sfnts_pputULONG( tables[x].newoffset + 12 + (count * 16), s,
+ string_len, line_len, in_string );
+
+ /* Length */
+ sfnts_pputULONG( tables[x].length, s,
+ string_len, line_len, in_string );
+ }
+
+ /* Now, send the tables */
+ for(int x=0; x < 9; x++) {
+ if( tables[x].length == 0 ) /* skip tables that aren't there */
+ continue;
+
+ /* 'glyf' table gets special treatment */
+ if( strcmp(table_names[x],"glyf")==0 ) {
+ sfnts_glyf_table(tables[x].oldoffset,tables[x].length, s,
+ string_len, line_len, in_string);
+ } else { // other tables should not exceed 64K (not always true; Sivan)
+ if( tables[x].length > 65535 ) {
+ qWarning("TrueType font has a table which is too long");
+ defective = TRUE;
+ return;
+ }
+
+ /* Start new string if necessary. */
+ sfnts_new_table(tables[x].length, s,
+ string_len, line_len, in_string);
+
+ int font_off = tables[x].oldoffset;
+ /* Copy the bytes of the table. */
+ for( int y=0; y < (int)tables[x].length; y++ ) {
+ c = offset_table[ font_off ];
+ font_off++;
+
+ sfnts_pputBYTE(c, s, string_len, line_len, in_string);
+ }
+ }
+
+ /* Padd it out to a four byte boundary. */
+ int y=tables[x].length;
+ while( (y % 4) != 0 ) {
+ sfnts_pputBYTE(0, s, string_len, line_len, in_string);
+ y++;
+ }
+
+ } /* End of loop for all tables */
+
+ /* Close the array. */
+ sfnts_end_string(s, string_len, line_len, in_string);
+ s << "]def\n";
+}
+#endif
+
+// ****************** Type 3 CharProcs *******
+
+/*
+** This routine is used to break the character
+** procedure up into a number of smaller
+** procedures. This is necessary so as not to
+** overflow the stack on certain level 1 interpreters.
+**
+** Prepare to push another item onto the stack,
+** starting a new proceedure if necessary.
+**
+** Not all the stack depth calculations in this routine
+** are perfectly accurate, but they do the job.
+*/
+static int stack_depth = 0;
+static void stack(int num_pts, int newnew, TQTextStream& s)
+{
+ if( num_pts > 25 ) { /* Only do something of we will */
+ /* have a log of points. */
+ if(stack_depth == 0) {
+ s << "{";
+ stack_depth=1;
+ }
+
+ stack_depth += newnew; /* Account for what we propose to add */
+
+ if(stack_depth > 100) {
+ s << "}_e{";
+ stack_depth = 3 + newnew; /* A rough estimate */
+ }
+ }
+}
+
+static void stack_end(TQTextStream& s) /* called at end */
+{
+ if(stack_depth) {
+ s << "}_e";
+ stack_depth=0;
+ }
+}
+
+// postscript drawing commands
+
+static void PSMoveto(FWord x, FWord y, TQTextStream& ts)
+{
+ ts << x;
+ ts << " ";
+ ts << y;
+ ts << " _m\n";
+}
+
+static void PSLineto(FWord x, FWord y, TQTextStream& ts)
+{
+ ts << x;
+ ts << " ";
+ ts << y;
+ ts << " _l\n";
+}
+
+/* Emmit a PostScript "curveto" command. */
+static void PSCurveto(FWord* xcoor, FWord* ycoor,
+ FWord x, FWord y, int s, int t, TQTextStream& ts)
+{
+ int N, i;
+ double sx[3], sy[3], cx[4], cy[4];
+
+ N = t-s+2;
+ for(i=0; i<N-1; i++) {
+ sx[0] = i==0?xcoor[s-1]:(xcoor[i+s]+xcoor[i+s-1])/2;
+ sy[0] = i==0?ycoor[s-1]:(ycoor[i+s]+ycoor[i+s-1])/2;
+ sx[1] = xcoor[s+i];
+ sy[1] = ycoor[s+i];
+ sx[2] = i==N-2?x:(xcoor[s+i]+xcoor[s+i+1])/2;
+ sy[2] = i==N-2?y:(ycoor[s+i]+ycoor[s+i+1])/2;
+ cx[3] = sx[2];
+ cy[3] = sy[2];
+ cx[1] = (2*sx[1]+sx[0])/3;
+ cy[1] = (2*sy[1]+sy[0])/3;
+ cx[2] = (sx[2]+2*sx[1])/3;
+ cy[2] = (sy[2]+2*sy[1])/3;
+
+ ts << (int)cx[1];
+ ts << " ";
+ ts << (int)cy[1];
+ ts << " ";
+ ts << (int)cx[2];
+ ts << " ";
+ ts << (int)cy[2];
+ ts << " ";
+ ts << (int)cx[3];
+ ts << " ";
+ ts << (int)cy[3];
+ ts << " _c\n";
+ }
+}
+
+/* The PostScript bounding box. */
+/* Variables to hold the character data. */
+
+//void load_char(struct TTFONT *font, BYTE *glyph);
+//void clear_data();
+
+//void PSMoveto(FWord x, FWord y, TQTextStream& ts);
+//void PSLineto(FWord x, FWord y, TQTextStream& ts);
+//void PSCurveto(FWord x, FWord y, int s, int t, TQTextStream& ts);
+
+//double area(FWord *x, FWord *y, int n);
+//int nextinctr(int co, int ci);
+//int nextoutctr(int co);
+//int nearout(int ci);
+//double intest(int co, int ci);
+#define sqr(x) ((x)*(x))
+
+#define NOMOREINCTR -1
+#define NOMOREOUTCTR -1
+
+/*
+** Find the area of a contour?
+*/
+static double area(FWord *x, FWord *y, int n)
+{
+ int i;
+ double sum;
+
+ sum=x[n-1]*y[0]-y[n-1]*x[0];
+ for (i=0; i<=n-2; i++) sum += x[i]*y[i+1] - y[i]*x[i+1];
+ return sum;
+}
+
+static int nextoutctr(int /*co*/, charproc_data* cd)
+{
+ int j;
+
+ for(j=0; j<cd->num_ctr; j++)
+ if (cd->check_ctr[j]==0 && cd->area_ctr[j] < 0) {
+ cd->check_ctr[j]=1;
+ return j;
+ }
+
+ return NOMOREOUTCTR;
+} /* end of nextoutctr() */
+
+static int nextinctr(int co, int /*ci*/, charproc_data* cd)
+{
+ int j;
+
+ for(j=0; j<cd->num_ctr; j++)
+ if (cd->ctrset[2*j+1]==co)
+ if (cd->check_ctr[ cd->ctrset[2*j] ]==0) {
+ cd->check_ctr[ cd->ctrset[2*j] ]=1;
+ return cd->ctrset[2*j];
+ }
+
+ return NOMOREINCTR;
+}
+
+static double intest( int co, int ci, charproc_data *cd )
+{
+ int i, j, start, end;
+ double r1, r2;
+ FWord xi[3], yi[3];
+
+ j = start = ( co == 0 ) ? 0 : ( cd->epts_ctr[co - 1] + 1 );
+ end = cd->epts_ctr[co];
+ i = ( ci == 0 ) ? 0 : ( cd->epts_ctr[ci - 1] + 1 );
+ xi[0] = cd->xcoor[i];
+ yi[0] = cd->ycoor[i];
+ r1 = sqr( cd->xcoor[start] - xi[0] ) + sqr( cd->ycoor[start] - yi[0] );
+
+ for ( i = start; i <= end; i++ ) {
+ r2 = sqr( cd->xcoor[i] - xi[0] ) + sqr( cd->ycoor[i] - yi[0] );
+ if ( r2 < r1 ) {
+ r1 = r2;
+ j = i;
+ }
+ }
+ if ( j == start ) {
+ xi[1] = cd->xcoor[end];
+ yi[1] = cd->ycoor[end];
+ } else {
+ xi[1] = cd->xcoor[j - 1];
+ yi[1] = cd->ycoor[j - 1];
+ }
+ if ( j == end ) {
+ xi[2] = cd->xcoor[start];
+ yi[2] = cd->ycoor[start];
+ } else {
+ xi[2] = cd->xcoor[j + 1];
+ yi[2] = cd->ycoor[j + 1];
+ }
+ return area( xi, yi, 3 );
+}
+
+/*
+** tqfind the nearest out contour to a specified in contour.
+*/
+static int nearout(int ci, charproc_data* cd)
+{
+ int k = 0; /* !!! is this right? */
+ int co;
+ double a, a1=0;
+
+ for (co=0; co < cd->num_ctr; co++) {
+ if(cd->area_ctr[co] < 0) {
+ a=intest(co,ci, cd);
+ if (a<0 && a1==0) {
+ k=co;
+ a1=a;
+ }
+ if(a<0 && a1!=0 && a>a1) {
+ k=co;
+ a1=a;
+ }
+ }
+ }
+
+ return k;
+} /* end of nearout() */
+
+
+/*
+** We call this routine to emmit the PostScript code
+** for the character we have loaded with load_char().
+*/
+static void PSConvert(TQTextStream& s, charproc_data* cd)
+{
+ int i,j,k,fst,start_offpt;
+ int end_offpt=0;
+
+ cd->area_ctr = new double[cd->num_ctr];
+ memset(cd->area_ctr, 0, (cd->num_ctr*sizeof(double)));
+
+ cd->check_ctr = new char[cd->num_ctr];
+ memset(cd->check_ctr, 0, (cd->num_ctr*sizeof(char)));
+
+ cd->ctrset = new int[2*(cd->num_ctr)];
+ memset(cd->ctrset, 0, (cd->num_ctr*2*sizeof(int)));
+
+ cd->check_ctr[0]=1;
+ cd->area_ctr[0]=area(cd->xcoor, cd->ycoor, cd->epts_ctr[0]+1);
+
+ for (i=1; i<cd->num_ctr; i++)
+ cd->area_ctr[i]=area(cd->xcoor+cd->epts_ctr[i-1]+1,
+ cd->ycoor+cd->epts_ctr[i-1]+1,
+ cd->epts_ctr[i]-cd->epts_ctr[i-1]);
+
+ for (i=0; i<cd->num_ctr; i++) {
+ if (cd->area_ctr[i]>0) {
+ cd->ctrset[2*i]=i;
+ cd->ctrset[2*i+1]=nearout(i,cd);
+ } else {
+ cd->ctrset[2*i]=-1;
+ cd->ctrset[2*i+1]=-1;
+ }
+ }
+
+ /* Step thru the coutours. */
+ /* I believe that a contour is a detatched */
+ /* set of curves and lines. */
+ i=j=k=0;
+ while (i < cd->num_ctr ) {
+ fst = j = (k==0) ? 0 : (cd->epts_ctr[k-1]+1);
+
+ /* Move to the first point on the contour. */
+ stack(cd->num_pts,3,s);
+ PSMoveto(cd->xcoor[j],cd->ycoor[j],s);
+ start_offpt = 0; /* No off curve points yet. */
+
+ /* Step thru the remaining points of this contour. */
+ for(j++; j <= cd->epts_ctr[k]; j++) {
+ if (!(cd->tt_flags[j]&1)) { /* Off curve */
+ if (!start_offpt)
+ { start_offpt = end_offpt = j; }
+ else
+ end_offpt++;
+ } else { /* On Curve */
+ if (start_offpt) {
+ stack(cd->num_pts,7,s);
+ PSCurveto(cd->xcoor,cd->ycoor,
+ cd->xcoor[j],cd->ycoor[j],
+ start_offpt,end_offpt,s);
+ start_offpt = 0;
+ } else {
+ stack(cd->num_pts,3,s);
+ PSLineto(cd->xcoor[j], cd->ycoor[j],s);
+ }
+ }
+ }
+
+ /* Do the final curve or line */
+ /* of this coutour. */
+ if (start_offpt) {
+ stack(cd->num_pts,7,s);
+ PSCurveto(cd->xcoor,cd->ycoor,
+ cd->xcoor[fst],cd->ycoor[fst],
+ start_offpt,end_offpt,s);
+ } else {
+ stack(cd->num_pts,3,s);
+ PSLineto(cd->xcoor[fst],cd->ycoor[fst],s);
+ }
+
+ k=nextinctr(i,k,cd);
+
+ if (k==NOMOREINCTR)
+ i=k=nextoutctr(i,cd);
+
+ if (i==NOMOREOUTCTR)
+ break;
+ }
+
+ /* Now, we can fill the whole thing. */
+ stack(cd->num_pts,1,s);
+ s << "_cl"; /* "closepath eofill" */
+
+ /* Free our work arrays. */
+ delete [] cd->area_ctr;
+ delete [] cd->check_ctr;
+ delete [] cd->ctrset;
+}
+
+
+/*
+** Load the simple glyph data pointed to by glyph.
+** The pointer "glyph" should point 10 bytes into
+** the glyph data.
+*/
+void TQPSPrinterFontTTF::charprocLoad(BYTE *glyph, charproc_data* cd)
+{
+ int x;
+ BYTE c, ct;
+
+ /* Read the contour endpoints list. */
+ cd->epts_ctr = new int[cd->num_ctr];
+ //cd->epts_ctr = (int *)myalloc(cd->num_ctr,sizeof(int));
+ for (x = 0; x < cd->num_ctr; x++) {
+ cd->epts_ctr[x] = getUSHORT(glyph);
+ glyph += 2;
+ }
+
+ /* From the endpoint of the last contour, we can */
+ /* determine the number of points. */
+ cd->num_pts = cd->epts_ctr[cd->num_ctr-1]+1;
+#ifdef DEBUG_TRUETYPE
+ fprintf(stderr,"num_pts=%d\n",cd->num_pts);
+#endif
+
+ /* Skip the instructions. */
+ x = getUSHORT(glyph);
+ glyph += 2;
+ glyph += x;
+
+ /* Allocate space to hold the data. */
+ //cd->tt_flags = (BYTE *)myalloc(num_pts,sizeof(BYTE));
+ //cd->xcoor = (FWord *)myalloc(num_pts,sizeof(FWord));
+ //cd->ycoor = (FWord *)myalloc(num_pts,sizeof(FWord));
+ cd->tt_flags = new BYTE[cd->num_pts];
+ cd->xcoor = new FWord[cd->num_pts];
+ cd->ycoor = new FWord[cd->num_pts];
+
+ /* Read the flags array, uncompressing it as we go. */
+ /* There is danger of overflow here. */
+ for (x = 0; x < cd->num_pts; ) {
+ cd->tt_flags[x++] = c = *(glyph++);
+
+ if (c&8) { /* If next byte is repeat count, */
+ ct = *(glyph++);
+
+ if( (x + ct) > cd->num_pts ) {
+ qWarning("Fatal Error in TT flags");
+ return;
+ }
+
+ while (ct--)
+ cd->tt_flags[x++] = c;
+ }
+ }
+
+ /* Read the x coordinates */
+ for (x = 0; x < cd->num_pts; x++) {
+ if (cd->tt_flags[x] & 2) { /* one byte value with */
+ /* external sign */
+ c = *(glyph++);
+ cd->xcoor[x] = (cd->tt_flags[x] & 0x10) ? c : (-1 * (int)c);
+ } else if(cd->tt_flags[x] & 0x10) { /* repeat last */
+ cd->xcoor[x] = 0;
+ } else { /* two byte signed value */
+ cd->xcoor[x] = getFWord(glyph);
+ glyph+=2;
+ }
+ }
+
+ /* Read the y coordinates */
+ for(x = 0; x < cd->num_pts; x++) {
+ if (cd->tt_flags[x] & 4) { /* one byte value with */
+ /* external sign */
+ c = *(glyph++);
+ cd->ycoor[x] = (cd->tt_flags[x] & 0x20) ? c : (-1 * (int)c);
+ } else if (cd->tt_flags[x] & 0x20) { /* repeat last value */
+ cd->ycoor[x] = 0;
+ } else { /* two byte signed value */
+ cd->ycoor[x] = getUSHORT(glyph);
+ glyph+=2;
+ }
+ }
+
+ /* Convert delta values to absolute values. */
+ for(x = 1; x < cd->num_pts; x++) {
+ cd->xcoor[x] += cd->xcoor[x-1];
+ cd->ycoor[x] += cd->ycoor[x-1];
+ }
+
+ for(x=0; x < cd->num_pts; x++) {
+ cd->xcoor[x] = topost(cd->xcoor[x]);
+ cd->ycoor[x] = topost(cd->ycoor[x]);
+ }
+}
+
+#define ARG_1_AND_2_ARE_WORDS 1
+#define ARGS_ARE_XY_VALUES 2
+#define ROUND_XY_TO_GRID 4
+#define WE_HAVE_A_SCALE 8
+/* RESERVED 16 */
+#define MORE_COMPONENTS 32
+#define WE_HAVE_AN_X_AND_Y_SCALE 64
+#define WE_HAVE_A_TWO_BY_TWO 128
+#define WE_HAVE_INSTRUCTIONS 256
+#define USE_MY_METRICS 512
+
+void TQPSPrinterFontTTF::subsetGlyph(int charindex,bool* glyphset)
+{
+ USHORT flags;
+ USHORT glyphIndex;
+ charproc_data cd;
+
+ glyphset[charindex] = TRUE;
+ //printf("subsetting %s ==> ",glyphName(charindex).latin1());
+
+ /* Get a pointer to the data. */
+ BYTE* glyph = charprocFindGlyphData( charindex );
+
+ /* If the character is blank, it has no bounding box, */
+ /* otherwise read the bounding box. */
+ if( glyph == (BYTE*)NULL ) {
+ cd.num_ctr=0;
+ } else {
+ cd.num_ctr = getSHORT(glyph);
+ /* Advance the pointer past bounding box. */
+ glyph += 10;
+ }
+
+ if( cd.num_ctr < 0 ) { // composite
+ /* Once around this loop for each component. */
+ do {
+ flags = getUSHORT(glyph); /* read the flags word */
+ glyph += 2;
+ glyphIndex = getUSHORT(glyph); /* read the glyphindex word */
+ glyph += 2;
+
+ glyphset[ glyphIndex ] = TRUE;
+ subsetGlyph( glyphIndex, glyphset );
+ //printf("subset tqcontains: %d %s ",glyphIndex, glyphName(glyphIndex).latin1());
+
+ if(flags & ARG_1_AND_2_ARE_WORDS) {
+ glyph += 2;
+ glyph += 2;
+ } else {
+ glyph += 1;
+ glyph += 1;
+ }
+
+ if(flags & WE_HAVE_A_SCALE) {
+ glyph += 2;
+ } else if(flags & WE_HAVE_AN_X_AND_Y_SCALE) {
+ glyph += 2;
+ glyph += 2;
+ } else if(flags & WE_HAVE_A_TWO_BY_TWO) {
+ glyph += 2;
+ glyph += 2;
+ glyph += 2;
+ glyph += 2;
+ } else {
+ }
+ } while(flags & MORE_COMPONENTS);
+ }
+ //printf("\n");
+}
+
+
+/*
+** Emmit PostScript code for a composite character.
+*/
+void TQPSPrinterFontTTF::charprocComposite(BYTE *glyph, TQTextStream& s, bool *glyphSet)
+{
+ USHORT flags;
+ USHORT glyphIndex;
+ int arg1;
+ int arg2;
+ float xscale = 1;
+ float yscale = 1;
+#ifdef DEBUG_TRUETYPE
+ float scale01 = 0;
+ float scale10 = 0;
+#endif
+
+ /* Once around this loop for each component. */
+ do {
+ flags = getUSHORT(glyph); /* read the flags word */
+ glyph += 2;
+
+ glyphIndex = getUSHORT(glyph); /* read the glyphindex word */
+ glyph += 2;
+
+ if(flags & ARG_1_AND_2_ARE_WORDS) {
+ /* The tt spec. seems to say these are signed. */
+ arg1 = getSHORT(glyph);
+ glyph += 2;
+ arg2 = getSHORT(glyph);
+ glyph += 2;
+ } else { /* The tt spec. does not clearly indicate */
+ /* whether these values are signed or not. */
+ arg1 = (char)*(glyph++);
+ arg2 = (char)*(glyph++);
+ }
+
+ if(flags & WE_HAVE_A_SCALE) {
+ xscale = yscale = f2dot14( getUSHORT(glyph) );
+ glyph += 2;
+ } else if(flags & WE_HAVE_AN_X_AND_Y_SCALE) {
+ xscale = f2dot14( getUSHORT(glyph) );
+ glyph += 2;
+ yscale = f2dot14( getUSHORT(glyph) );
+ glyph += 2;
+ } else if(flags & WE_HAVE_A_TWO_BY_TWO) {
+ xscale = f2dot14( getUSHORT(glyph) );
+ glyph += 2;
+#ifdef DEBUG_TRUETYPE
+ scale01 = f2dot14( getUSHORT(glyph) );
+#endif
+ glyph += 2;
+#ifdef DEBUG_TRUETYPE
+ scale10 = f2dot14( getUSHORT(glyph) );
+#endif
+ glyph += 2;
+ yscale = f2dot14( getUSHORT(glyph) );
+ glyph += 2;
+ }
+
+ /* Debugging */
+#ifdef DEBUG_TRUETYPE
+ s << "% flags=" << flags << ", arg1=" << arg1 << ", arg2=" << arg2 << ", xscale=" << xscale << ", yscale=" << yscale <<
+ ", scale01=" << scale01 << ", scale10=" << scale10 << endl;
+#endif
+
+
+ if ( (flags & ARGS_ARE_XY_VALUES) != ARGS_ARE_XY_VALUES ) {
+ s << "% unimplemented shift, arg1=" << arg1;
+ s << ", arg2=" << arg2 << "\n";
+ arg1 = arg2 = 0;
+ }
+
+ /* If we have an (X,Y) shif and it is non-zero, */
+ /* translate the coordinate system. */
+ if ( flags & (WE_HAVE_A_TWO_BY_TWO|WE_HAVE_AN_X_AND_Y_SCALE) ) {
+#if 0
+ // code similar to this would be needed for two_by_two
+ s << "gsave [ " << xscale << " " << scale01 << " " << scale10 << " "
+ << yscale << " " << topost(arg1) << " " << topost(arg2) << "] SM\n";
+#endif
+ if ( flags & WE_HAVE_A_TWO_BY_TWO )
+ s << "% Two by two transformation, unimplemented\n";
+ s << "gsave " << topost(arg1);
+ s << " " << topost(arg2);
+ s << " translate\n";
+ s << xscale << " " << yscale << " scale\n";
+ } else if ( flags & ARGS_ARE_XY_VALUES && ( arg1 != 0 || arg2 != 0 ) ) {
+ s << "gsave " << topost(arg1);
+ s << " " << topost(arg2);
+ s << " translate\n";
+ }
+
+ /* Invoke the CharStrings procedure to print the component. */
+ s << "false CharStrings /";
+ s << glyphName( glyphIndex, glyphSet );
+ s << " get exec\n";
+
+ // printf("false CharStrings /%s get exec\n",
+ //ttfont_CharStrings_getname(font,glyphIndex));
+
+ /* If we translated the coordinate system, */
+ /* put it back the way it was. */
+ if( (flags & ARGS_ARE_XY_VALUES && (arg1 != 0 || arg2 != 0) ) ||
+ ( flags & (WE_HAVE_A_TWO_BY_TWO|WE_HAVE_AN_X_AND_Y_SCALE) ) ) {
+ s << "grestore ";
+ }
+ } while (flags & MORE_COMPONENTS);
+}
+
+/*
+** Return a pointer to a specific glyph's data.
+*/
+BYTE* TQPSPrinterFontTTF::charprocFindGlyphData(int charindex)
+{
+ ULONG off;
+ ULONG length;
+
+ /* Read the glyph offset from the index to location table. */
+ if(indexToLocFormat == 0) {
+ off = getUSHORT( loca_table + (charindex * 2) );
+ off *= 2;
+ length = getUSHORT( loca_table + ((charindex+1) * 2) );
+ length *= 2;
+ length -= off;
+ } else {
+ off = getULONG( loca_table + (charindex * 4) );
+ length = getULONG( loca_table + ((charindex+1) * 4) );
+ length -= off;
+ }
+
+ if(length > 0)
+ return glyf_table + off;
+ else
+ return (BYTE*)NULL;
+}
+
+void TQPSPrinterFontTTF::charproc(int charindex, TQTextStream& s, bool *glyphSet )
+{
+ int llx,lly,urx,ury;
+ int advance_width;
+ charproc_data cd;
+
+#ifdef DEBUG_TRUETYPE
+ s << "% tt_type3_charproc for ";
+ s << charindex;
+ s << "\n";
+#endif
+
+ /* Get a pointer to the data. */
+ BYTE* glyph = charprocFindGlyphData( charindex );
+
+ /* If the character is blank, it has no bounding box, */
+ /* otherwise read the bounding box. */
+ if( glyph == (BYTE*)NULL ) {
+ llx=lly=urx=ury=0; /* A blank char has an all zero BoundingBox */
+ cd.num_ctr=0; /* Set this for later if()s */
+ } else {
+ /* Read the number of contours. */
+ cd.num_ctr = getSHORT(glyph);
+
+ /* Read PostScript bounding box. */
+ llx = getFWord(glyph + 2);
+ lly = getFWord(glyph + 4);
+ urx = getFWord(glyph + 6);
+ ury = getFWord(glyph + 8);
+
+ /* Advance the pointer. */
+ glyph += 10;
+ }
+
+ /* If it is a simple character, load its data. */
+ if (cd.num_ctr > 0)
+ charprocLoad(glyph, &cd);
+ else
+ cd.num_pts=0;
+
+ /* Consult the horizontal metrics table to determine */
+ /* the character width. */
+ if( charindex < numberOfHMetrics )
+ advance_width = getuFWord( hmtx_table + (charindex * 4) );
+ else
+ advance_width = getuFWord( hmtx_table + ((numberOfHMetrics-1) * 4) );
+
+ /* Execute setcachetqdevice in order to inform the font machinery */
+ /* of the character bounding box and advance width. */
+ stack(cd.num_pts,7,s);
+ s << topost(advance_width);
+ s << " 0 ";
+ s << topost(llx);
+ s << " ";
+ s << topost(lly);
+ s << " ";
+ s << topost(urx);
+ s << " ";
+ s << topost(ury);
+ s << " _sc\n";
+
+ /* If it is a simple glyph, convert it, */
+ /* otherwise, close the stack business. */
+ if( cd.num_ctr > 0 ) { // simple
+ PSConvert(s,&cd);
+ delete [] cd.tt_flags;
+ delete [] cd.xcoor;
+ delete [] cd.ycoor;
+ delete [] cd.epts_ctr;
+ } else if( cd.num_ctr < 0 ) { // composite
+ charprocComposite(glyph,s, glyphSet);
+ }
+
+ stack_end(s);
+} /* end of tt_type3_charproc() */
+
+
+// ================== PFA ====================
+
+class TQPSPrinterFontPFA
+ : public TQPSPrinterFontPrivate {
+public:
+ TQPSPrinterFontPFA(const TQFontEngine *f, TQByteArray& data);
+ virtual void download(TQTextStream& s, bool global);
+ virtual bool embedded() { return TRUE; }
+private:
+ TQByteArray data;
+};
+
+TQPSPrinterFontPFA::TQPSPrinterFontPFA(const TQFontEngine *f, TQByteArray& d)
+{
+ data = d;
+
+ int pos = 0;
+ char* p = data.data();
+ TQString fontname;
+
+ if (p[ pos ] != '%' || p[ pos+1 ] != '!') { // PFA marker
+ qWarning("invalid pfa file");
+ return;
+ }
+
+ char* fontnameptr = strstr(p+pos,"/FontName");
+ if (fontnameptr == NULL)
+ return;
+
+ fontnameptr += strlen("/FontName") + 1;
+ while (*fontnameptr == ' ' || *fontnameptr == '/') fontnameptr++;
+ int l=0;
+ while (fontnameptr[l] != ' ') l++;
+
+ psname = TQString::tqfromLatin1(fontnameptr,l);
+ tqreplacementList = makePSFontNameList( f, psname );
+}
+
+void TQPSPrinterFontPFA::download(TQTextStream& s, bool global)
+{
+ emitPSFontNameList( s, psname, tqreplacementList);
+
+ if ( !embedFonts ) {
+ downloadMapping(s, global);
+ return;
+ }
+
+ //qDebug("downloading pfa font %s", psname.latin1() );
+ char* p = data.data();
+
+ s << "% Font resource\n";
+ for (int i=0; i < (int)data.size(); i++) s << p[i];
+ s << "% End of font resource\n";
+ downloadMapping( s, global );
+}
+
+// ================== PFB ====================
+
+class TQPSPrinterFontPFB
+ : public TQPSPrinterFontPrivate {
+public:
+ TQPSPrinterFontPFB(const TQFontEngine *f, TQByteArray& data);
+ virtual void download(TQTextStream& s, bool global);
+ virtual bool embedded() { return TRUE; }
+private:
+ TQByteArray data;
+};
+
+TQPSPrinterFontPFB::TQPSPrinterFontPFB(const TQFontEngine *f, TQByteArray& d)
+{
+ data = d;
+
+ int pos = 0;
+ int len;
+ // int typ;
+ unsigned char* p = (unsigned char*) data.data();
+ TQString fontname;
+
+ if (p[ pos ] != 0x80) { // PFB marker
+ qWarning("pfb file does not start with 0x80");
+ return;
+ }
+ pos++;
+ // typ = p[ pos ]; // 1=ascii 2=binary 3=done
+ pos++;
+ len = p[ pos ]; pos++;
+ len |= (p[ pos ] << 8) ; pos++;
+ len |= (p[ pos ] << 16); pos++;
+ len |= (p[ pos ] << 24); pos++;
+
+ //printf("font block type %d len %d\n",typ,len);
+
+ char* fontnameptr = strstr((char*)p+pos,"/FontName");
+ if (fontnameptr == NULL)
+ return;
+
+ fontnameptr += strlen("/FontName") + 1;
+ while (*fontnameptr == ' ' || *fontnameptr == '/') fontnameptr++;
+ int l=0;
+ while (fontnameptr[l] != ' ') l++;
+
+ psname = TQString::tqfromLatin1(fontnameptr,l);
+ tqreplacementList = makePSFontNameList( f, psname );
+}
+
+void TQPSPrinterFontPFB::download(TQTextStream& s, bool global)
+{
+ emitPSFontNameList( s, psname, tqreplacementList);
+
+ if ( !embedFonts ) {
+ downloadMapping(s, global);
+ return;
+ }
+
+ //qDebug("downloading pfb font %s", psname.latin1() );
+ unsigned char* p = (unsigned char*) data.data();
+ int pos;
+ int len;
+ int typ;
+
+ int hexcol = 0;
+ int line_length = 64;
+
+ s << "% Font resource\n";
+
+ pos = 0;
+ typ = -1;
+ while (typ != 3) { // not end of file
+ if (p[ pos ] != 0x80) // PFB marker
+ return; // pfb file does not start with 0x80
+ pos++;
+ typ = p[ pos ]; // 1=ascii 2=binary 3=done
+ pos++;
+
+ if (typ == 3) break;
+
+ len = p[ pos ]; pos++;
+ len |= (p[ pos ] << 8) ; pos++;
+ len |= (p[ pos ] << 16); pos++;
+ len |= (p[ pos ] << 24); pos++;
+
+ //qDebug("font block type %d len %d",typ,len);
+
+ int end = pos + len;
+ if (typ==1) {
+ while (pos < end) {
+ if (hexcol > 0) {
+ s << "\n";
+ hexcol = 0;
+ }
+ //qWarning(TQString::tqfromLatin1((char*)(p+pos),1));
+ if (p[pos] == '\r' || p[pos] == '\n') {
+ s << "\n";
+ while (pos < end && (p[pos] == '\r' || p[pos] == '\n'))
+ pos++;
+ } else {
+ s << TQString::tqfromLatin1((char*)(p+pos),1);
+ pos++;
+ }
+ }
+ }
+ if (typ==2) {
+ static const char *hexchar = "0123456789abcdef";
+ while (pos < end) {
+ /* trim hexadecimal lines to line_length columns */
+ if (hexcol >= line_length) {
+ s << "\n";
+ hexcol = 0;
+ }
+ s << TQString::tqfromLatin1(hexchar+((p[pos] >> 4) & 0xf),1)
+ << TQString::tqfromLatin1(hexchar+((p[pos] ) & 0xf),1);
+ pos++;
+ hexcol += 2;
+ }
+ }
+ }
+ s << "% End of font resource\n";
+ downloadMapping( s, global );
+}
+
+// ================== AFontFileNotFound ============
+
+
+
+class TQPSPrinterFontNotFound
+ : public TQPSPrinterFontPrivate {
+public:
+ TQPSPrinterFontNotFound(const TQFontEngine* f);
+ virtual void download(TQTextStream& s, bool global);
+private:
+ TQByteArray data;
+};
+
+TQPSPrinterFontNotFound::TQPSPrinterFontNotFound(const TQFontEngine* f)
+{
+ psname = makePSFontName( f );
+ tqreplacementList = makePSFontNameList( f );
+}
+
+void TQPSPrinterFontNotFound::download(TQTextStream& s, bool)
+{
+ //qDebug("downloading not found font %s", psname.latin1() );
+ emitPSFontNameList( s, psname, tqreplacementList );
+ s << "% No embeddable font for ";
+ s << psname;
+ s << " found\n";
+ TQPSPrinterFontPrivate::download(s, TRUE);
+}
+
+#ifndef TQT_NO_TEXTCODEC
+// =================== A font file for asian ============
+
+class TQPSPrinterFontAsian
+ : public TQPSPrinterFontPrivate {
+public:
+ TQPSPrinterFontAsian()
+ : TQPSPrinterFontPrivate(), codec( 0 ) {}
+ void download(TQTextStream& s, bool global);
+ TQString defineFont( TQTextStream &stream, const TQString &ps, const TQFont &f, const TQString &key,
+ TQPSPrinterPrivate *d );
+ void drawText( TQTextStream &stream, const TQPoint &p, TQTextEngine *engine, int item,
+ const TQString &text, TQPSPrinterPrivate *d, TQPainter *paint );
+
+ TQString makePSFontName( const TQFontEngine *f, int type ) const;
+ virtual TQString extension() const = 0;
+
+ TQTextCodec *codec;
+};
+
+TQString TQPSPrinterFontAsian::makePSFontName( const TQFontEngine *f, int type ) const
+{
+ TQString ps;
+ int i;
+
+ TQString family = f->fontDef.family.lower();
+
+ // try to make a "good" postscript name
+ ps = family.simplifyWhiteSpace();
+ i = 0;
+ while( (unsigned int)i < ps.length() ) {
+ if ( i != 0 && ps[i] == '[') {
+ if ( ps[i-1] == ' ' )
+ ps.truncate (i-1);
+ else
+ ps.truncate (i);
+ break;
+ }
+ if ( i == 0 || ps[i-1] == ' ' ) {
+ ps[i] = ps[i].upper();
+ if ( i )
+ ps.remove( i-1, 1 );
+ else
+ i++;
+ } else {
+ i++;
+ }
+ }
+
+ switch ( type ) {
+ case 1:
+ ps.append( TQString::tqfromLatin1("-Italic") );
+ break;
+ case 2:
+ ps.append( TQString::tqfromLatin1("-Bold") );
+ break;
+ case 3:
+ ps.append( TQString::tqfromLatin1("-BoldItalic") );
+ break;
+ case 0:
+ default:
+ break;
+ }
+
+ ps += extension();
+
+ return ps;
+}
+
+
+TQString TQPSPrinterFontAsian::defineFont( TQTextStream &stream, const TQString &ps, const TQFont &f,
+ const TQString &key, TQPSPrinterPrivate *d)
+{
+ TQString fontName;
+ TQString fontName2;
+
+ TQString *tmp = d->headerFontNames.tqfind( ps );
+
+ if ( d->buffer ) {
+ if ( tmp ) {
+ fontName = *tmp;
+ } else {
+ fontName.sprintf( "F%d", ++d->headerFontNumber );
+ d->fontStream << "/" << fontName << " false " << ps << "List MF\n";
+ d->headerFontNames.insert( ps, new TQString( fontName ) );
+ }
+ fontName2.sprintf( "F%d", ++d->headerFontNumber );
+ d->fontStream << "/" << fontName2 << " "
+ << pointSize( f, d->scale ) << "/" << fontName << " DF\n";
+ d->headerFontNames.insert( key, new TQString( fontName2 ) );
+ } else {
+ if ( tmp ) {
+ fontName = *tmp;
+ } else {
+ fontName.sprintf( "F%d", ++d->pageFontNumber );
+ stream << "/" << fontName << " false " << ps << "List MF\n";
+ d->pageFontNames.insert( ps, new TQString( fontName ) );
+ }
+ fontName2.sprintf( "F%d", ++d->pageFontNumber );
+ stream << "/" << fontName2 << " "
+ << pointSize( f, d->scale ) << "/" << fontName << " DF\n";
+ d->pageFontNames.insert( key, new TQString( fontName2 ) );
+ }
+ return fontName2;
+}
+
+
+void TQPSPrinterFontAsian::download(TQTextStream& s, bool)
+{
+ //qDebug("downloading asian font %s", psname.latin1() );
+ s << "% Asian postscript font requested. Using "
+ << psname << endl;
+ emitPSFontNameList( s, psname, tqreplacementList );
+}
+
+void TQPSPrinterFontAsian::drawText( TQTextStream &stream, const TQPoint &p, TQTextEngine *engine, int item,
+ const TQString &text, TQPSPrinterPrivate *d, TQPainter *paint)
+{
+ int len = engine->length( item );
+ TQScriptItem &si = engine->items[item];
+
+ int x = p.x() + si.x;
+ int y = p.y() + si.y;
+ if ( y != d->textY || d->textY == 0 )
+ stream << y << " Y";
+ d->textY = y;
+
+ TQString mdf;
+ if ( paint->font().underline() )
+ mdf += " " + TQString().setNum( y + d->fm.underlinePos() + d->fm.lineWidth() ) +
+ " " + toString( d->fm.lineWidth() ) + " Tl";
+ if ( paint->font().strikeOut() )
+ mdf += " " + TQString().setNum( y + d->fm.strikeOutPos() ) +
+ " " + toString( d->fm.lineWidth() ) + " Tl";
+ TQCString mb;
+ TQCString out;
+ TQString dummy( TQChar(0x20) );
+
+ if ( si.analysis.bidiLevel % 2 ) {
+ for ( int i = len-1; i >= 0; i-- ) {
+ TQChar ch = text.tqunicode()[i];
+ if ( !ch.row() ) {
+ ; // ignore, we should never get here anyway
+ } else {
+ if ( codec ) {
+ dummy[0] = ch;
+ mb = codec->fromUnicode( dummy );
+ } else
+ mb = " ";
+
+ for ( unsigned int j = 0; j < mb.length (); j++ ) {
+ if ( mb.at(j) == '(' || mb.at(j) == ')' || mb.at(j) == '\\' )
+ out += "\\";
+ out += mb.at(j);
+ }
+ }
+ }
+ } else {
+ for ( int i = 0; i < len; i++ ) {
+ TQChar ch = text.tqunicode()[i];
+ if ( !ch.row() ) {
+ ; // ignore, we should never get here anyway
+ } else {
+ if ( codec ) {
+ dummy[0] = ch;
+ mb = codec->fromUnicode( dummy );
+ } else
+ mb = " ";
+
+ for ( unsigned int j = 0; j < mb.length (); j++ ) {
+ if ( mb.at(j) == '(' || mb.at(j) == ')' || mb.at(j) == '\\' )
+ out += "\\";
+ out += mb.at(j);
+ }
+ }
+ }
+ }
+ stream << "(" << out << ")" << si.width << " " << x << mdf << " AT\n";
+}
+
+// ----------- Japanese --------------
+
+static const psfont Japanese1 [] = {
+ { "Ryumin-Light-H", 0, 100. },
+ { "Ryumin-Light-H", 0.2, 100. },
+ { "GothicBBB-Medium-H", 0, 100. },
+ { "GothicBBB-Medium-H", 0.2, 100. }
+};
+
+static const psfont Japanese1a [] = {
+ { "GothicBBB-Medium-H", 0, 100. },
+ { "GothicBBB-Medium-H", 0.2, 100. },
+ { "Ryumin-Light-H", 0, 100. },
+ { "Ryumin-Light-H", 0.2, 100. }
+};
+
+static const psfont Japanese2 [] = {
+ { "GothicBBB-Medium-H", 0, 100. },
+ { "GothicBBB-Medium-H", 0.2, 100. },
+ { "GothicBBB-Medium-H", 0, 100. },
+ { "GothicBBB-Medium-H", 0.2, 100. }
+};
+
+static const psfont Japanese2a [] = {
+ { "Ryumin-Light-H", 0, 100. },
+ { "Ryumin-Light-H", 0.2, 100. },
+ { "Ryumin-Light-H", 0, 100. },
+ { "Ryumin-Light-H", 0.2, 100. }
+};
+
+
+// Wadalab fonts
+
+static const psfont WadaMin [] = {
+ { "WadaMin-Regular-H", 0, 100. },
+ { "WadaMin-Regular-H", 0.2, 100. },
+ { "WadaMin-Bold-H", 0, 100. },
+ { "WadaMin-Bold-H", 0.2, 100. }
+};
+
+static const psfont WadaGo [] = {
+ { "WadaMaruGo-Regular-H", 0, 100. },
+ { "WadaMaruGo-Regular-H", 0.2, 100. },
+ { "WadaGo-Bold-H", 0, 100. },
+ { "WadaGo-Bold-H", 0.2, 100. }
+};
+
+// Adobe Wadalab
+
+static const psfont WadaGoAdobe [] = {
+ { "WadaMaruGo-RegularH-Hojo-H", 0, 100. },
+ { "WadaMaruGo-RegularH-Hojo-H", 0.2, 100. },
+ { "WadaMaruGo-RegularH-Hojo-H", 0, 100. },
+ { "WadaMaruGo-RegularH-Hojo-H", 0.2, 100. },
+};
+static const psfont WadaMinAdobe [] = {
+ { "WadaMin-RegularH-Hojo-H", 0, 100. },
+ { "WadaMin-RegularH-Hojo-H", 0.2, 100. },
+ { "WadaMin-RegularH-Hojo-H", 0, 100. },
+ { "WadaMin-RegularH-Hojo-H", 0.2, 100. },
+};
+
+
+static const psfont * const Japanese1Replacements[] = {
+ Japanese1, Japanese1a, WadaMin, WadaGo, WadaMinAdobe, WadaGoAdobe, 0
+};
+static const psfont * const Japanese2Replacements[] = {
+ Japanese2, Japanese2a, WadaMin, WadaGo, WadaMinAdobe, WadaGoAdobe, 0
+};
+
+class TQPSPrinterFontJapanese
+ : public TQPSPrinterFontAsian {
+public:
+ TQPSPrinterFontJapanese(const TQFontEngine* f);
+ virtual TQString extension() const;
+};
+
+TQPSPrinterFontJapanese::TQPSPrinterFontJapanese(const TQFontEngine* f)
+{
+ codec = TQTextCodec::codecForMib( 63 ); // jisx0208.1983-0
+
+ int type = getPsFontType( f );
+ psname = makePSFontName( f, type );
+ TQString best = "[ /" + psname + " 1.0 0.0 ]";
+ tqreplacementList.append( best );
+
+ const psfont *const *tqreplacements = ( psname.tqcontains( "Helvetica" ) ? Japanese2Replacements : Japanese1Replacements );
+ appendReplacements( tqreplacementList, tqreplacements, type );
+}
+
+TQString TQPSPrinterFontJapanese::extension() const
+{
+ return "-H";
+}
+
+// ----------- Korean --------------
+
+// sans serif
+static const psfont SMGothic [] = {
+ { "SMGothic-Medium-KSC-EUC-H", 0, 100. },
+ { "SMGothic-Medium-KSC-EUC-H", 0.2, 100. },
+ { "SMGothic-DemiBold-KSC-EUC-H", 0, 100. },
+ { "SMGothic-DemiBold-KSC-EUC-H", 0.2, 100. }
+};
+
+// serif
+#if 0 // ### this is never used?
+static const psfont SMMyungjo [] = {
+ { "SMMyungjo-Light-KSC-EUC-H", 0, 100. },
+ { "SMMyungjo-Light-KSC-EUC-H", 0.2, 100. },
+ { "SMMyungjo-Bold-KSC-EUC-H", 0, 100. },
+ { "SMMyungjo-Bold-KSC-EUC-H", 0.2, 100. }
+};
+#endif
+
+static const psfont MKai [] = {
+ { "MingMT-Light-KSC-EUC-H", 0, 100. },
+ { "MingMT-Light-KSC-EUC-H", 0.2, 100. },
+ { "MKai-Medium-KSC-EUC-H", 0, 100. },
+ { "MKai-Medium-KSC-EUC-H", 0.2, 100. },
+};
+
+
+static const psfont Munhwa [] = {
+ { "Munhwa-Regular-KSC-EUC-H", 0, 100. },
+ { "Munhwa-Regular-KSC-EUC-H", 0.2, 100. },
+ { "Munhwa-Bold-KSC-EUC-H", 0, 100. },
+ { "Munhwa-Bold-KSC-EUC-H", 0.2, 100. }
+};
+
+static const psfont MunhwaGothic [] = {
+ { "MunhwaGothic-Regular-KSC-EUC-H", 0, 100. },
+ { "MunhwaGothic-Regular-KSC-EUC-H", 0.2, 100. },
+ { "MunhwaGothic-Bold-KSC-EUC-H", 0, 100. },
+ { "MunhwaGothic-Bold-KSC-EUC-H", 0.2, 100. }
+};
+
+static const psfont MunhwaGungSeo [] = {
+ { "MunhwaGungSeo-Light-KSC-EUC-H", 0, 100. },
+ { "MunhwaGungSeo-Light-KSC-EUC-H", 0.2, 100. },
+ { "MunhwaGungSeo-Bold-KSC-EUC-H", 0, 100. },
+ { "MunhwaGungSeo-Bold-KSC-EUC-H", 0.2, 100. }
+};
+
+static const psfont MunhwaGungSeoHeulim [] = {
+ { "MunhwaGungSeoHeulim-Light-KSC-EUC-H", 0, 100. },
+ { "MunhwaGungSeoHeulim-Light-KSC-EUC-H", 0.2, 100. },
+ { "MunhwaGungSeoHeulim-Bold-KSC-EUC-H", 0, 100. },
+ { "MunhwaGungSeoHeulim-Bold-KSC-EUC-H", 0.2, 100. }
+};
+
+static const psfont MunhwaHoonMin [] = {
+ { "MunhwaHoonMin-Regular-KSC-EUC-H", 0, 100. },
+ { "MunhwaHoonMin-Regular-KSC-EUC-H", 0.2, 100. },
+ { "MunhwaHoonMin-Regular-KSC-EUC-H", 0, 100. },
+ { "MunhwaHoonMin-Regular-KSC-EUC-H", 0.2, 100. }
+};
+
+static const psfont BaekmukGulim [] = {
+ { "Baekmuk-Gulim-KSC-EUC-H", 0, 100. },
+ { "Baekmuk-Gulim-KSC-EUC-H", 0.2, 100. },
+ { "Baekmuk-Gulim-KSC-EUC-H", 0, 100. },
+ { "Baekmuk-Gulim-KSC-EUC-H", 0.2, 100. }
+};
+
+static const psfont * const KoreanReplacements[] = {
+ BaekmukGulim, SMGothic, Munhwa, MunhwaGothic, MKai, MunhwaGungSeo,
+ MunhwaGungSeoHeulim, MunhwaHoonMin, Helvetica, 0
+};
+
+class TQPSPrinterFontKorean
+ : public TQPSPrinterFontAsian {
+public:
+ TQPSPrinterFontKorean(const TQFontEngine* f);
+ TQString extension() const;
+};
+
+TQPSPrinterFontKorean::TQPSPrinterFontKorean(const TQFontEngine* f)
+{
+ codec = TQTextCodec::codecForMib( 38 ); // eucKR
+ int type = getPsFontType( f );
+ psname = makePSFontName( f, type );
+ TQString best = "[ /" + psname + " 1.0 0.0 ]";
+ tqreplacementList.append( best );
+ appendReplacements( tqreplacementList, KoreanReplacements, type );
+}
+
+TQString TQPSPrinterFontKorean::extension() const
+{
+ return "-KSC-EUC-H";
+}
+// ----------- traditional chinese ------------
+
+// Arphic Public License Big5 TrueType fonts (on Debian and CLE and others)
+static const psfont ShanHeiSun [] = {
+ { "ShanHeiSun-Light-ETen-B5-H", 0, 100. },
+ { "ShanHeiSun-Light-ETen-B5-H", 0.2, 100. },
+ { "ShanHeiSun-Light-ETen-B5-H", 0, 100. },
+ { "ShanHeiSun-Light-ETen-B5-H", 0.2, 100. },
+};
+static const psfont ZenKai [] = {
+ { "ZenKai-Medium-ETen-B5-H", 0, 100. },
+ { "ZenKai-Medium-Italic-ETen-B5-H", 0.2, 100. },
+ { "ZenKai-Medium-Bold-ETen-B5-H", 0, 100. },
+ { "ZenKai-Medium-BoldItalic-ETen-B5-H", 0.2, 100. },
+};
+
+// Fonts on Turbolinux
+static const psfont SongB5 [] = {
+ { "B5-MSung-Light-ETen-B5-H", 0, 100. },
+ { "B5-MSung-Italic-ETen-B5-H", 0, 100. },
+ { "B5-MSung-Bold-ETen-B5-H", 0, 100. },
+ { "B5-MSung-BoldItalic-ETen-B5-H", 0, 100. },
+};
+static const psfont KaiB5 [] = {
+ { "B5-MKai-Medium-ETen-B5-H", 0, 100. },
+ { "B5-MKai-Italic-ETen-B5-H", 0, 100. },
+ { "B5-MKai-Bold-ETen-B5-H", 0, 100. },
+ { "B5-MKai-BoldItalic-ETen-B5-H", 0, 100. },
+};
+static const psfont HeiB5 [] = {
+ { "B5-MHei-Medium-ETen-B5-H", 0, 100. },
+ { "B5-MHei-Italic-ETen-B5-H", 0, 100. },
+ { "B5-MHei-Bold-ETen-B5-H", 0, 100. },
+ { "B5-MHei-BoldItalic-ETen-B5-H", 0, 100. },
+};
+static const psfont FangSongB5 [] = {
+ { "B5-CFangSong-Light-ETen-B5-H", 0, 100. },
+ { "B5-CFangSong-Italic-ETen-B5-H", 0, 100. },
+ { "B5-CFangSong-Bold-ETen-B5-H", 0, 100. },
+ { "B5-CFangSong-BoldItalic-ETen-B5-H", 0, 100. },
+};
+
+// Arphic fonts on Thiz Linux
+static const psfont LinGothic [] = {
+ { "LinGothic-Light-ETen-B5-H", 0, 100. },
+ { "LinGothic-Light-Italic-ETen-B5-H", 0.2, 100. },
+ { "LinGothic-Light-Bold-ETen-B5-H", 0, 100. },
+ { "LinGothic-Light-BoldItalic-ETen-B5-H", 0.2, 100. },
+};
+static const psfont YenRound [] = {
+ { "YenRound-Light-ETen-B5-H", 0, 100. },
+ { "YenRound-Light-Italic-ETen-B5-H", 0.2, 100. },
+ { "YenRound-Light-Bold-ETen-B5-H", 0, 100. },
+ { "YenRound-Light-BoldItalic-ETen-B5-H", 0.2, 100. },
+};
+
+// Dr. Wang Hann-Tzong's GPL'ed Big5 TrueType fonts
+#if 0 // ### this is never used?
+static const psfont HtWFangSong [] = {
+ { "HtW-FSong-Light-ETen-B5-H", 0, 100. },
+ { "HtW-FSong-Light-Italic-ETen-B5-H", 0.2, 100. },
+ { "HtW-FSong-Light-Bold-ETen-B5-H", 0, 100. },
+ { "HtW-FSong-Light-BoldItalic-ETen-B5-H", 0.2, 100. },
+};
+#endif
+
+static const psfont MingB5 [] = {
+ { "Ming-Light-ETen-B5-H", 0, 100. },
+ { "Ming-Light-Italic-ETen-B5-H", 0.2, 100. },
+ { "Ming-Light-Bold-ETen-B5-H", 0, 100. },
+ { "Ming-Light-BoldItalic-ETen-B5-H", 0.2, 100. },
+};
+
+// Microsoft's Ming/Sung font?
+static const psfont MSung [] = {
+ { "MSung-Light-ETenms-B5-H", 0, 100. },
+ { "MSung-Light-ETenms-B5-H", 0.2, 100. },
+ { "MSung-Light-ETenms-B5-H", 0, 100. },
+ { "MSung-Light-ETenms-B5-H", 0.2, 100. },
+};
+// "Standard Sung/Ming" font by Taiwan Ministry of Education
+static const psfont MOESung [] = {
+ { "MOESung-Regular-B5-H", 0, 100. },
+ { "MOESung-Regular-B5-H", 0.2, 100. },
+ { "MOESung-Regular-B5-H", 0, 100. },
+ { "MOESung-Regular-B5-H", 0.2, 100. },
+};
+
+static const psfont MOEKai [] = {
+ { "MOEKai-Regular-B5-H", 0, 100. },
+ { "MOEKai-Regular-B5-H", 0.2, 100. },
+ { "MOEKai-Regular-B5-H", 0, 100. },
+ { "MOEKai-Regular-B5-H", 0.2, 100. },
+};
+
+static const psfont * const TraditionalReplacements[] = {
+ MOESung, SongB5, ShanHeiSun, MingB5, MSung, FangSongB5, KaiB5, ZenKai, HeiB5,
+ LinGothic, YenRound, MOEKai, Helvetica, 0
+ };
+
+#if 0 // ### these are never used?
+static const psfont * const SongB5Replacements[] = {
+ SongB5, ShanHeiSun, MingB5, MSung, MOESung, Helvetica, 0
+ };
+
+static const psfont * const FangSongB5Replacements[] = {
+ FangSongB5, HtWFangSong, Courier, 0
+ };
+static const psfont * const KaiB5Replacements[] = {
+ KaiB5, ZenKai, Times, 0
+ };
+static const psfont * const HeiB5Replacements[] = {
+ HeiB5, LinGothic, YenRound, LucidaSans, 0
+ };
+static const psfont * const YuanB5Replacements[] = {
+ YenRound, LinGothic, HeiB5, LucidaSans, 0
+ };
+#endif
+
+
+class TQPSPrinterFontTraditionalChinese
+ : public TQPSPrinterFontAsian {
+public:
+ TQPSPrinterFontTraditionalChinese(const TQFontEngine* f);
+ TQString extension() const;
+};
+
+TQPSPrinterFontTraditionalChinese::TQPSPrinterFontTraditionalChinese(const TQFontEngine* f)
+{
+ codec = TQTextCodec::codecForMib( 2026 ); // Big5-0
+ int type = getPsFontType( f );
+ psname = makePSFontName( f, type );
+ TQString best = "[ /" + psname + " 1.0 0.0 ]";
+ tqreplacementList.append( best );
+ appendReplacements( tqreplacementList, TraditionalReplacements, type );
+}
+
+TQString TQPSPrinterFontTraditionalChinese::extension() const
+{
+ return "-ETen-B5-H";
+}
+
+// ----------- simplified chinese ------------
+
+#if 0
+// GB18030 fonts on XteamLinux (?)
+static const psfont SimplifiedGBK2K [] = {
+ { "MSung-Light-GBK2K-H", 0, 100. },
+ { "MSung-Light-GBK2K-H", 0.2, 100. },
+ { "MKai-Medium-GBK2K-H", 0, 100. },
+ { "MKai-Medium-GBK2K-H", 0.2, 100. },
+};
+#endif
+
+// GB18030 fonts on Turbolinux
+static const psfont SongGBK2K [] = {
+ { "MSung-Light-GBK2K-H", 0, 100. },
+ { "MSung-Italic-GBK2K-H", 0, 100. },
+ { "MSung-Bold-GBK2K-H", 0, 100. },
+ { "MSung-BoldItalic-GBK2K-H", 0, 100. },
+};
+static const psfont KaiGBK2K [] = {
+ { "MKai-Medium-GBK2K-H", 0, 100. },
+ { "MKai-Italic-GBK2K-H", 0, 100. },
+ { "MKai-Bold-GBK2K-H", 0, 100. },
+ { "MKai-BoldItalic-GBK2K-H", 0, 100. },
+};
+static const psfont HeiGBK2K [] = {
+ { "MHei-Medium-GBK2K-H", 0, 100. },
+ { "MHei-Italic-GBK2K-H", 0, 100. },
+ { "MHei-Bold-GBK2K-H", 0, 100. },
+ { "MHei-BoldItalic-GBK2K-H", 0, 100. },
+};
+static const psfont FangSongGBK2K [] = {
+ { "CFangSong-Light-GBK2K-H", 0, 100. },
+ { "CFangSong-Italic-GBK2K-H", 0, 100. },
+ { "CFangSong-Bold-GBK2K-H", 0, 100. },
+ { "CFangSong-BoldItalic-GBK2K-H", 0, 100. },
+};
+
+static const psfont Simplified [] = {
+ { "MSung-Light-GBK-EUC-H", 0, 100. },
+ { "MSung-Light-GBK-EUC-H", 0.2, 100. },
+ { "MKai-Medium-GBK-EUC-H", 0, 100. },
+ { "MKai-Medium-GBK-EUC-H", 0.2, 100. },
+};
+
+static const psfont MSungGBK [] = {
+ { "MSung-Light-GBK-EUC-H", 0, 100. },
+ { "MSung-Light-GBK-EUC-H", 0.2, 100. },
+ { "MSung-Light-GBK-EUC-H", 0, 100. },
+ { "MSung-Light-GBK-EUC-H", 0.2, 100. },
+};
+
+static const psfont FangSong [] = {
+ { "CFangSong-Light-GBK-EUC-H", 0, 100. },
+ { "CFangSong-Light-GBK-EUC-H", 0.2, 100. },
+ { "CFangSong-Light-GBK-EUC-H", 0, 100. },
+ { "CFangSong-Light-GBK-EUC-H", 0.2, 100. },
+};
+
+// Arphic Public License GB2312 TrueType fonts (on Debian and CLE and others)
+static const psfont BousungEG [] = {
+ { "BousungEG-Light-GB-GB-EUC-H", 0, 100. },
+ { "BousungEG-Light-GB-GB-EUC-H", 0.2, 100. },
+ { "BousungEG-Light-GB-Bold-GB-EUC-H", 0, 100. },
+ { "BousungEG-Light-GB-Bold-GB-EUC-H", 0.2, 100. },
+};
+static const psfont GBZenKai [] = {
+ { "GBZenKai-Medium-GB-GB-EUC-H", 0, 100. },
+ { "GBZenKai-Medium-GB-GB-EUC-H", 0.2, 100. },
+ { "GBZenKai-Medium-GB-Bold-GB-EUC-H", 0, 100. },
+ { "GBZenKai-Medium-GB-Bold-GB-EUC-H", 0.2, 100. },
+};
+
+static const psfont * const SimplifiedReplacements[] = {
+ SongGBK2K, FangSongGBK2K, KaiGBK2K, HeiGBK2K,
+ Simplified, MSungGBK, FangSong, BousungEG, GBZenKai, Helvetica, 0
+ };
+#if 0
+static const psfont * const SongGBK2KReplacements[] = {
+ SongGBK2K, MSungGBK, BousungEG, Helvetica, 0
+ };
+#endif
+static const psfont * const FangSongGBK2KReplacements[] = {
+ FangSongGBK2K, FangSong, Courier, 0
+ };
+static const psfont * const KaiGBK2KReplacements[] = {
+ KaiGBK2K, GBZenKai, Times, 0
+ };
+static const psfont * const HeiGBK2KReplacements[] = {
+ HeiGBK2K, LucidaSans, 0
+ };
+
+class TQPSPrinterFontSimplifiedChinese
+ : public TQPSPrinterFontAsian {
+public:
+ TQPSPrinterFontSimplifiedChinese(const TQFontEngine* f);
+ TQString extension() const;
+};
+
+TQPSPrinterFontSimplifiedChinese::TQPSPrinterFontSimplifiedChinese(const TQFontEngine* f)
+{
+ codec = TQTextCodec::codecForMib( 114 ); // GB18030
+ int type = getPsFontType( f );
+ TQString family = f->fontDef.family.lower();
+ if( family.tqcontains("kai",FALSE) ) {
+ psname = KaiGBK2K[type].psname;
+ appendReplacements( tqreplacementList, KaiGBK2KReplacements, type );
+ } else if( family.tqcontains("fangsong",FALSE) ) {
+ psname = FangSongGBK2K[type].psname;
+ appendReplacements( tqreplacementList, FangSongGBK2KReplacements, type );
+ } else if( family.tqcontains("hei",FALSE) ) {
+ psname = HeiGBK2K[type].psname;
+ appendReplacements( tqreplacementList, HeiGBK2KReplacements, type );
+ } else {
+ psname = SongGBK2K[type].psname;
+ appendReplacements( tqreplacementList, SimplifiedReplacements, type );
+ }
+ //qDebug("simplified chinese: fontname is %s, psname=%s", f.family().latin1(), psname.latin1() );
+}
+
+TQString TQPSPrinterFontSimplifiedChinese::extension() const
+{
+ return "-GBK2K-H";
+}
+
+#endif
+
+
+// ================== TQPSPrinterFont ====================
+
+class TQPSPrinterFont {
+public:
+ TQPSPrinterFont(const TQFont& f, int script, TQPSPrinterPrivate *priv);
+ ~TQPSPrinterFont();
+ TQString postScriptFontName() { return p->postScriptFontName(); }
+ TQString defineFont( TQTextStream &stream, const TQString &ps, const TQFont &f, const TQString &key,
+ TQPSPrinterPrivate *d )
+ { return p->defineFont( stream, ps, f, key, d ); }
+ void download(TQTextStream& s, bool global) { p->download(s, global); }
+ TQPSPrinterFontPrivate *handle() { return p; }
+ TQString xfontname;
+private:
+ TQByteArray data;
+ TQPSPrinterFontPrivate* p;
+};
+
+TQPSPrinterFont::~TQPSPrinterFont()
+{
+ // the dict in TQFontPrivate does deletion for us.
+ // delete p;
+}
+
+
+TQPSPrinterFont::TQPSPrinterFont(const TQFont &f, int script, TQPSPrinterPrivate *priv)
+ : p(0)
+{
+ TQString fontfilename;
+ TQString fontname;
+
+ enum { NONE, PFB, PFA, TTF } type = NONE;
+
+ TQFontEngine *engine = f.d->engineForScript( (TQFont::Script) script );
+ // ### implement similar code for TQWS and WIN
+ xfontname = makePSFontName( engine );
+
+#if defined( TQ_WS_X11 )
+ bool xlfd = FALSE;
+ //qDebug("engine = %p name=%s, script=%d", engine, engine ? engine->name() : "(null)", script);
+
+#ifndef TQT_NO_XFTFREETYPE
+ if ( qt_has_xft && engine && engine->type() == TQFontEngine::Xft ) {
+ XftPattern *pattern = static_cast<TQFontEngineXft *>( engine )->pattern();
+ char *filename = 0;
+ XftPatternGetString (pattern, XFT_FILE, 0, &filename);
+ //qDebug("filename for font is '%s'", filename);
+ if ( filename ) {
+ fontfilename = TQString::fromLocal8Bit( filename );
+ xfontname = fontfilename;
+ }
+ } else
+#endif
+ {
+ TQString rawName;
+ if ( engine && engine != (TQFontEngine *)-1 )
+ rawName = engine->name();
+ int index = rawName.tqfind('-');
+ if (index == 0) {
+ // this is an XLFD font name
+ for (int i=0; i < 6; i++) {
+ index = rawName.tqfind('-',index+1);
+ }
+ xfontname = rawName.mid(0,index);
+ if ( xfontname.endsWith( "*" ) )
+ xfontname.truncate( xfontname.length() - 1 );
+ xlfd = TRUE;
+ }
+ }
+#endif // TQ_WS_X11
+#ifndef TQT_NO_TEXTCODEC
+ // map some scripts to something more useful
+ if ( script == TQFont::Han ) {
+ TQTextCodec *lc = TQTextCodec::codecForLocale();
+ switch( lc->mibEnum() ) {
+ case 36: // KS C 5601
+ case 38: // EUC KR
+ script = TQFont::Hangul;
+ break;
+
+ case 57: // gb2312.1980-0
+ case 113: // GBK
+ case -113: // gbk-0
+ case 114: // GB18030
+ case -114: // gb18030-0
+ case 2025: // GB2312
+ case 2026: // Big5
+ case -2026: // Big5-HKSCS
+ case 2101: // big5-0, big5.eten-0
+ case -2101: // big5hkscs-0, hkscs-1
+ break;
+
+ case 16: // JIS7
+ case 17: // SJIS
+ case 18: // EUC JP
+ case 63: // JIS X 0208
+ default:
+ script = TQFont::Hiragana;
+ break;
+ }
+ } else if ( script == TQFont::Katakana )
+ script = TQFont::Hiragana;
+ else if ( script == TQFont::Bopomofo )
+ script = TQFont::Han;
+#endif
+
+ TQString searchname = xfontname;
+#if defined(TQ_WS_X11)
+ // we need an extension here due to the fact that we use different
+ // fonts for different scripts
+ if ( xlfd && script >= TQFont::Han && script <= TQFont::Bopomofo )
+ xfontname += "/" + toString( script );
+#endif
+
+ //qDebug("looking for font %s in dict", xfontname.latin1() );
+ p = priv->fonts.tqfind(xfontname);
+ if ( p )
+ return;
+
+#if defined(TQ_WS_X11)
+ if ( xlfd ) {
+
+ for (TQStringList::Iterator it=priv->fontpath.begin(); it!=priv->fontpath.end() && fontfilename.isEmpty(); ++it) {
+ if ((*it).left(1) != "/") continue; // not a path name, a font server
+ TQString fontmapname;
+ int num = 0;
+ // search font.dir and font.scale for the right file
+ while ( num < 2 ) {
+ if ( num == 0 )
+ fontmapname = (*it) + "/fonts.scale";
+ else
+ fontmapname = (*it) + "/fonts.dir";
+ //qWarning(fontmapname);
+ TQFile fontmap(fontmapname);
+ if (fontmap.open(IO_ReadOnly)) {
+ while (!fontmap.atEnd()) {
+ TQString mapping;
+ fontmap.readLine(mapping,512);
+ // fold to lower (since X folds to lowercase)
+ //qWarning(xfontname);
+ //qWarning(mapping);
+ if (mapping.lower().tqcontains(searchname.lower())) {
+ int index = mapping.tqfind(' ',0);
+ TQString ffn = mapping.mid(0,index);
+ // remove the most common bitmap formats
+ if( !ffn.tqcontains( ".pcf" ) && !ffn.tqcontains( ".bdf" ) &&
+ !ffn.tqcontains( ".spd" ) && !ffn.tqcontains( ".phont" ) ) {
+ fontfilename = (*it) + TQString("/") + ffn;
+ if ( TQFile::exists(fontfilename) ) {
+ //qDebug("found font file %s", fontfilename.latin1());
+ break;
+ } else // unset fontfilename
+ fontfilename = TQString();
+ }
+ }
+ }
+ fontmap.close();
+ }
+ num++;
+ }
+ }
+ }
+#endif
+
+ //qDebug("font=%s, fontname=%s, file=%s, p=%p", f.family().latin1(), xfontname.latin1(), fontfilename.latin1(), p);
+
+ // memory mapping would be better here
+ if (fontfilename.length() > 0) { // maybe there is no file name
+ TQFile fontfile(fontfilename);
+ if ( fontfile.exists() ) {
+ //printf("font name %s size = %d\n",fontfilename.latin1(),fontfile.size());
+ data = TQByteArray( fontfile.size() );
+
+ fontfile.open(IO_Raw | IO_ReadOnly);
+ fontfile.readBlock(data.data(), fontfile.size());
+ fontfile.close();
+ }
+ }
+
+ if (!data.isNull() && data.size() > 0) {
+ unsigned char* d = (unsigned char *)data.data();
+ if (d[0] == 0x80 && d[1] == 0x01 && d[6] == '%' && d[7] == '!')
+ type = PFB;
+ else if (d[0] == '%' && d[1] == '!' && d[2] == 'P' && d[3] == 'S')
+ type = PFA;
+ else if (d[0]==0x00 && d[1]==0x01 && d[2]==0x00 && d[3]==0x00)
+ type = TTF;
+ else
+ type = NONE;
+ } else
+ type = NONE;
+
+ //qDebug("font is of type %d", type );
+ switch (type) {
+ case TTF :
+ p = new TQPSPrinterFontTTF(engine, data);
+ break;
+ case PFB:
+ p = new TQPSPrinterFontPFB(engine, data);
+ break;
+ case PFA:
+ p = new TQPSPrinterFontPFA(engine, data);
+ break;
+ case NONE:
+ default:
+
+#ifndef TQT_NO_TEXTCODEC
+
+ if ( script == TQFont::Hiragana )
+ p = new TQPSPrinterFontJapanese( engine );
+ else if ( script == TQFont::Hangul )
+ p = new TQPSPrinterFontKorean( engine );
+ else if ( script == TQFont::Han ) {
+ TQTextCodec *lc = TQTextCodec::codecForLocale();
+ switch( lc->mibEnum() ) {
+ case 2025: // GB2312
+ case 57: // gb2312.1980-0
+ case 113: // GBK
+ case -113: // gbk-0
+ case 114: // GB18030
+ case -114: // gb18030-0
+ p = new TQPSPrinterFontSimplifiedChinese( engine );
+ break;
+ case 2026: // Big5
+ case -2026: // big5-0, big5.eten-0
+ case 2101: // Big5-HKSCS
+ case -2101: // big5hkscs-0, hkscs-1
+ p = new TQPSPrinterFontTraditionalChinese( engine );
+ break;
+ default:
+ p = new TQPSPrinterFontJapanese( engine );
+ }
+ } else
+#endif
+ //qDebug("didnt tqfind font for %s", xfontname.latin1());
+ p = new TQPSPrinterFontNotFound( engine );
+ break;
+ }
+
+ if (p->postScriptFontName() == "Symbol")
+ p->setSymbol();
+
+ // this is needed to make sure we don't get the same postscriptname twice
+ TQDictIterator<TQPSPrinterFontPrivate> it( priv->fonts );
+ for( it.toFirst(); it.current(); ++it ) {
+ if ( *(*it) == *p ) {
+// qWarning("Post script driver: font already in dict");
+ delete p;
+ p = *it;
+ return;
+ }
+ }
+
+ //qDebug("inserting font %s in dict psname=%s", xfontname.latin1(), p->postScriptFontName().latin1() );
+ priv->fonts.insert( xfontname, p );
+}
+
+// ================= END OF PS FONT METHODS ============
+
+
+TQPSPrinterPrivate::TQPSPrinterPrivate( TQPrinter *prt, int filedes )
+ : buffer( 0 ), outDevice( 0 ), fd( filedes ), pageBuffer( 0 ), fonts(27, FALSE), fontBuffer(0), savedImage( 0 ),
+ dirtypen( FALSE ), dirtybrush( FALSE ), dirtyBkColor( FALSE ), bkMode( TQt::TransparentMode ), dirtyBkMode( FALSE ),
+#ifndef TQT_NO_TEXTCODEC
+ currentFontCodec( 0 ),
+#endif
+ fm( TQFont() ), textY( 0 )
+{
+ printer = prt;
+ headerFontNames.setAutoDelete( TRUE );
+ pageFontNames.setAutoDelete( TRUE );
+ fonts.setAutoDelete( TRUE );
+ currentFontFile = 0;
+ scale = 1.;
+ scriptUsed = -1;
+
+#ifdef TQ_WS_X11
+ // append qsettings fontpath
+ TQSettings settings;
+ embedFonts = settings.readBoolEntry( "/qt/embedFonts", TRUE );
+
+ int npaths;
+ char** font_path;
+ font_path = XGetFontPath( qt_xdisplay(), &npaths);
+ bool xfsconfig_read = FALSE;
+ for (int i=0; i<npaths; i++) {
+ // If we're using xfs, append font paths from /etc/X11/fs/config
+ // can't hurt, and chances are we'll get all fonts that way.
+ if (((font_path[i])[0] != '/') && !xfsconfig_read) {
+ // We're using xfs -> read its config
+ bool finished = FALSE;
+ TQFile f("/etc/X11/fs/config");
+ if ( !f.exists() )
+ f.setName("/usr/X11R6/lib/X11/fs/config");
+ if ( !f.exists() )
+ f.setName("/usr/X11/lib/X11/fs/config");
+ if ( f.exists() ) {
+ f.open(IO_ReadOnly);
+ while(f.status()==IO_Ok && !finished) {
+ TQString fs;
+ f.readLine(fs, 1024);
+ fs=fs.stripWhiteSpace();
+ if (fs.left(9)=="catalogue" && fs.tqcontains('=')) {
+ fs=fs.mid(fs.tqfind('=')+1).stripWhiteSpace();
+ bool end = FALSE;
+ while( f.status()==IO_Ok && !end ) {
+ if ( fs[int(fs.length())-1] == ',' )
+ fs = fs.left(fs.length()-1);
+ else
+ end = TRUE;
+ if (fs[0] != '#' && !fs.tqcontains(":unscaled"))
+ fontpath += fs;
+ f.readLine(fs, 1024);
+ fs=fs.stripWhiteSpace();
+ }
+ finished = TRUE;
+ }
+ }
+ f.close();
+ }
+ xfsconfig_read = TRUE;
+ } else if(!strstr(font_path[i], ":unscaled")) {
+ // Fonts paths marked :unscaled are always bitmapped fonts
+ // -> we can as well ignore them now and save time
+ fontpath += font_path[i];
+ }
+ }
+ XFreeFontPath(font_path);
+
+ // append qsettings fontpath
+ TQStringList fp = settings.readListEntry( "/qt/fontPath", ':' );
+ if ( !fp.isEmpty() )
+ fontpath += fp;
+#else
+ embedFonts = FALSE;
+#endif
+}
+
+TQPSPrinterPrivate::~TQPSPrinterPrivate()
+{
+ delete pageBuffer;
+}
+
+void TQPSPrinterPrivate::setFont( const TQFont & fnt, int script )
+{
+ TQFont f = fnt;
+ if ( f.rawMode() ) {
+ TQFont fnt( TQString::tqfromLatin1("Helvetica"), 12 );
+ setFont( fnt, TQFont::Unicode );
+ return;
+ }
+ if ( f.pointSize() == 0 ) {
+#if defined(CHECK_RANGE)
+ qWarning( "TQPrinter: Cannot set a font with zero point size." );
+#endif
+ f.setPointSize(TQApplication::font().pointSize());
+ if ( f.pointSize() == 0 )
+ f.setPointSize( 11 );
+ }
+
+ TQPSPrinterFont ff( f, script, this );
+ TQString ps = ff.postScriptFontName();
+
+ TQString s = ps;
+ s.append( ' ' );
+ s.prepend( ' ' );
+
+ TQString key = ff.xfontname;
+
+ if ( f.pointSize() != -1 )
+ key += " " + toString( f.pointSize() );
+ else
+ key += " px" + toString( f.pixelSize() );
+ TQString * tmp;
+ if ( !buffer )
+ tmp = pageFontNames.tqfind( key );
+ else
+ tmp = headerFontNames.tqfind( key );
+
+ TQString fontName;
+ if ( tmp )
+ fontName = *tmp;
+
+ if ( fontName.isEmpty() ) {
+ fontName = ff.defineFont( pageStream, ps, f, key, this );
+ }
+ pageStream << fontName << " F\n";
+
+ ps.append( ' ' );
+ ps.prepend( ' ' );
+ if ( !fontsUsed.tqcontains( ps ) )
+ fontsUsed += ps;
+
+#ifndef TQT_NO_TEXTCODEC
+ TQTextCodec * codec = 0;
+// ###
+// #ifndef TQT_NO_TEXTCODEC
+// i = 0;
+// do {
+// if ( tqunicodevalues[i].cs == f.charSet() )
+// codec = TQTextCodec::codecForMib( tqunicodevalues[i++].mib );
+// } while( codec == 0 && tqunicodevalues[i++].cs != tqunicodevalues_LAST );
+// #endif
+ currentFontCodec = codec;
+#endif
+ currentFont = fontName;
+ currentFontFile = ff.handle();
+ scriptUsed = script;
+}
+
+
+static void ps_r7( TQTextStream& stream, const char * s, int l )
+{
+ int i = 0;
+ uchar line[79];
+ int col = 0;
+
+ while( i < l ) {
+ line[col++] = s[i++];
+ if ( col >= 76 ) {
+ line[col++] = '\n';
+ line[col++] = '\0';
+ stream << (const char *)line;
+ col = 0;
+ }
+ }
+ if ( col > 0 ) {
+ while( (col&3) != 0 )
+ line[col++] = '%'; // use a comment as padding
+ line[col++] = '\n';
+ line[col++] = '\0';
+ stream << (const char *)line;
+ }
+}
+
+
+static const int quoteSize = 3; // 1-8 pixels
+static const int maxQuoteLength = 4+16+32+64+128+256; // magic extended quote
+static const int quoteReach = 10; // ... 1-1024 pixels back
+static const int tableSize = 1024; // 2 ** quoteReach;
+static const int numAttempts = 128;
+
+static const int hashSize = 71;
+
+static const int None = INT_MAX;
+
+/* puts the lowest numBits of data into the out array starting at postion (byte/bit).
+ Adjusts byte and bit to point ot the next position.
+
+ Need to make sure the out array is long enough before calling the method.
+*/
+static void emitBits( char *out, int & byte, int & bit,
+ int numBits, uint data )
+{
+ int b = 0;
+ uint d = data;
+ while( b < numBits ) {
+ if ( bit == 0 )
+ out[byte] = 0;
+ if ( d & 1 )
+ out[byte] = (uchar)out[byte] | ( 1 << bit );
+ d = d >> 1;
+ b++;
+ bit++;
+ if ( bit > 6 ) {
+ bit = 0;
+ byte++;
+ }
+ }
+}
+
+//#define DEBUG_COMPRESS
+#ifdef DEBUG_COMPRESS
+#include <tqdatetime.h>
+#endif
+
+static TQByteArray compress( const TQImage & image, bool gray ) {
+#ifdef DEBUG_COMPRESS
+ TQTime t;
+ t.start();
+ int sizeUncompressed[11];
+ for( int i = 0; i < 11; i++ )
+ sizeUncompressed[i] = 0;
+ int sizeCompressed[11];
+ for( int i = 0; i < 11; i++ )
+ sizeCompressed[i] = 0;
+#endif
+
+ int width = image.width();
+ int height = image.height();
+ int depth = image.depth();
+ int size = width*height;
+
+ int pastPixel[tableSize];
+ int mostRecentPixel[hashSize];
+ if ( depth == 1 )
+ size = (width+7)/8*height;
+ else if ( !gray )
+ size = size*3;
+
+ unsigned char *pixel = new unsigned char[size+1];
+ int i = 0;
+ if ( depth == 1 ) {
+ TQImage::Endian bitOrder = image.bitOrder();
+ memset( pixel, 0xff, size );
+ for( int y=0; y < height; y++ ) {
+ uchar * s = image.scanLine( y );
+ for( int x=0; x < width; x++ ) {
+ // need to copy bit for bit...
+ bool b = ( bitOrder == TQImage::LittleEndian ) ?
+ (*(s + (x >> 3)) >> (x & 7)) & 1 :
+ (*(s + (x >> 3)) << (x & 7)) & 0x80 ;
+ if ( b )
+ pixel[i >> 3] ^= (0x80 >> ( i & 7 ));
+ i++;
+ }
+ // we need to align to 8 bit here
+ i = (i+7) & 0xffffff8;
+ }
+ } else if ( depth == 8 ) {
+ for( int y=0; y < height; y++ ) {
+ uchar * s = image.scanLine( y );
+ for( int x=0; x < width; x++ ) {
+ TQRgb rgb = image.color( s[x] );
+ if ( gray ) {
+ pixel[i] = (unsigned char) tqGray( rgb );
+ i++;
+ } else {
+ pixel[i] = (unsigned char) tqRed( rgb );
+ pixel[i+1] = (unsigned char) tqGreen( rgb );
+ pixel[i+2] = (unsigned char) tqBlue( rgb );
+ i += 3;
+ }
+ }
+ }
+ } else {
+ bool alpha = image.hasAlphaBuffer();
+ for( int y=0; y < height; y++ ) {
+ TQRgb * s = (TQRgb*)(image.scanLine( y ));
+ for( int x=0; x < width; x++ ) {
+ TQRgb rgb = (*s++);
+ if ( alpha && tqAlpha( rgb ) < 0x40 ) // 25% alpha, convert to white -
+ rgb = tqRgb( 0xff, 0xff, 0xff );
+ if ( gray ) {
+ pixel[i] = (unsigned char) tqGray( rgb );
+ i++;
+ } else {
+ pixel[i] = (unsigned char) tqRed( rgb );
+ pixel[i+1] = (unsigned char) tqGreen( rgb );
+ pixel[i+2] = (unsigned char) tqBlue( rgb );
+ i += 3;
+ }
+ }
+ }
+ }
+
+ pixel[size] = 0;
+
+ /* this compression function emits blocks of data, where each
+ block is an unquoted series of pixels, or a quote from earlier
+ pixels. if the six-letter string "banana" were a six-pixel
+ image, it might be unquoted "ban" followed by a 3-pixel quote
+ from -2. note that the final "a" is then copied from the
+ second "a", which is copied from the first "a" in the same copy
+ operation.
+
+ the scanning for quotable blocks uses a cobol-like loop and a
+ hash table: we know how many pixels we need to quote, hash the
+ first and last pixel we need, and then go backwards in time
+ looking for some spot where those pixels of those two colours
+ occur at the right distance from each other.
+
+ when we tqfind a spot, we'll try a string-compare of all the
+ intervening pixels. we only do a maximum of 128 both-ends
+ compares or 64 full-string compares. it's more important to be
+ fast than get the ultimate in compression.
+
+ The format of the compressed stream is as follows:
+ // 2 bits step size for search and backreference ( 1 or 3 )
+ 1 bit compressed or uncompressed block follows
+
+ uncompressed block:
+ 3 bits size of block in bytes
+ size*8 bits data
+
+ compressed block:
+ 3 bits compression header
+ 0-2 size of block is 1-3 bytes
+ 3-7 size of block is bigger, 4-8 additional bits specifying size follow
+ 0/4-8 additional size fields
+ 10 location of backreference
+ */
+
+ for( i=0; i < hashSize; i++ )
+ mostRecentPixel[i] = None;
+ int index = 0;
+ int emittedUntil = 0;
+ char *out = (char *)malloc( 256 * sizeof( char ) );
+ int outLen = 256;
+ int outOffset = 0;
+ int outBit = 0;
+
+ /* we process pixels serially, emitting as necessary/possible. */
+ while( index <= size ) {
+ int bestCandidate = None;
+ int bestLength = 0;
+ i = index % tableSize;
+ int h = pixel[index] % hashSize;
+ int start, end;
+ start = end = pastPixel[i] = mostRecentPixel[h];
+ mostRecentPixel[h] = index;
+ /* if our first candidate quote is unusable, or we don't need
+ to quote because we've already emitted something for this
+ pixel, just skip. */
+ if ( start < index - tableSize || index >= size ||
+ emittedUntil > index)
+ start = end = None;
+ int attempts = 0;
+ /* scan for suitable quote candidates: not too far back, and
+ if we've found one that's as big as it can get, don't look
+ for more */
+ while( start != None && end != None &&
+ bestLength < maxQuoteLength &&
+ start >= index - tableSize &&
+ end >= index - tableSize + bestLength ) {
+ /* scan backwards, looking for something good enough to
+ try a (slow) string comparison. we maintain indexes to
+ the start and the end of the quote candidate here */
+ while( start != None && end != None &&
+ ( pixel[start] != pixel[index] ||
+ pixel[end] != pixel[index+bestLength] ) ) {
+ if ( attempts++ > numAttempts ) {
+ start = None;
+ } else if ( pixel[end] % hashSize ==
+ pixel[index+bestLength] % hashSize ) {
+ /* we move the area along the end index' chain */
+ end = pastPixel[end%tableSize];
+ start = end - bestLength;
+ } else if ( pixel[start] % hashSize ==
+ pixel[index] % hashSize ) {
+ /* ... or along the start index' chain */
+ start = pastPixel[start%tableSize];
+ end = start + bestLength;
+ } else {
+#if 0
+ /* this should never happen: both the start and
+ the end pointers ran off their tracks. */
+ qDebug( "oops! %06x %06x %06x %06x %5d %5d %5d %d",
+ pixel[start], pixel[end],
+ pixel[index], pixel[index+bestLength],
+ start, end, index, bestLength );
+#endif
+ /* but if it should happen, no problem. we'll just
+ say we found nothing, and the compression will
+ be a bit worse. */
+ start = None;
+ }
+ /* if we've moved either index too far to use the
+ quote candidate, let's just give up here. there's
+ also a guard against "start" insanity. */
+ if ( start < index - tableSize || start < 0 || start >= index )
+ start = None;
+ if ( end < index - tableSize + bestLength || end < bestLength )
+ end = None;
+ }
+ /* ok, now start and end point to an area of suitable
+ length whose first and last points match, or one/both
+ is/are set to None. */
+ if ( start != None && end != None ) {
+ /* slow string compare... */
+ int length = 0;
+ while( length < maxQuoteLength &&
+ index+length < size &&
+ pixel[start+length] == pixel[index+length] )
+ length++;
+ /* if we've found something that overlaps the index
+ point, maybe we can move the quote point back? if
+ we're copying 10 pixels from 8 pixels back (an
+ overlap of 2), that'll be faster than copying from
+ 4 pixels back (an overlap of 6). */
+ if ( start + length > index && length > 0 ) {
+ int d = index-start;
+ int equal = TRUE;
+ while( equal && start + length > index &&
+ start > d && start-d >= index-tableSize ) {
+ int i = 0;
+ while( equal && i < d ) {
+ if( pixel[start+i] != pixel[start+i-d] )
+ equal = FALSE;
+ i++;
+ }
+ if ( equal )
+ start -= d;
+ }
+ }
+ /* if what we have is longer than the best previous
+ candidate, we'll use this one. */
+ if ( length > bestLength ) {
+ attempts = 0;
+ bestCandidate = start;
+ bestLength = length;
+ if ( length < maxQuoteLength && index + length < size )
+ end = mostRecentPixel[pixel[index+length]%hashSize];
+ } else {
+ /* and if it ins't, we'll try some more. but we'll
+ count each string compare extra, since they're
+ so expensive. */
+ attempts += 2;
+ if ( attempts > numAttempts ) {
+ start = None;
+ } else if ( pastPixel[start%tableSize] + bestLength <
+ pastPixel[end%tableSize] ) {
+ start = pastPixel[start%tableSize];
+ end = start + bestLength;
+ } else {
+ end = pastPixel[end%tableSize];
+ start = end - bestLength;
+ }
+ }
+ /* again, if we can't make use of the current quote
+ candidate, we don't try any more */
+ if ( start < index - tableSize || start < 0 || start > size+1 )
+ start = None;
+ if ( end < index - tableSize + bestLength || end < 0 || end > size+1 )
+ end = None;
+ }
+ }
+ /* backreferences to 1 byte of data are actually more costly than
+ emitting the data directly, 2 bytes don't save much. */
+ if ( bestCandidate != None && bestLength < 3 )
+ bestCandidate = None;
+ /* at this point, bestCandidate is a candidate of bestLength
+ length, or else it's None. if we have such a candidate, or
+ we're at the end, we have to emit all unquoted data. */
+ if ( index == size || bestCandidate != None ) {
+ /* we need a double loop, because there's a maximum length
+ on the "unquoted data" section. */
+ while( emittedUntil < index ) {
+#ifdef DEBUG_COMPRESS
+ int x = 0;
+ int bl = emittedUntil - index;
+ while ( (bl /= 2) )
+ x++;
+ if ( x > 10 ) x = 10;
+ sizeUncompressed[x]++;
+#endif
+ int l = TQMIN( 8, index - emittedUntil );
+ if ( outOffset + l + 2 >= outLen ) {
+ outLen *= 2;
+ out = (char *) realloc( out, outLen );
+ }
+ emitBits( out, outOffset, outBit,
+ 1, 0 );
+ emitBits( out, outOffset, outBit,
+ quoteSize, l-1 );
+ while( l-- ) {
+ emitBits( out, outOffset, outBit,
+ 8, pixel[emittedUntil] );
+ emittedUntil++;
+ }
+ }
+ }
+ /* if we have some quoted data to output, do it. */
+ if ( bestCandidate != None ) {
+#ifdef DEBUG_COMPRESS
+ int x = 0;
+ int bl = bestLength;
+ while ( (bl /= 2) )
+ x++;
+ if ( x > 10 ) x = 10;
+ sizeCompressed[x]++;
+#endif
+ if ( outOffset + 4 >= outLen ) {
+ outLen *= 2;
+ out = (char *) realloc( out, outLen );
+ }
+ emitBits( out, outOffset, outBit,
+ 1, 1 );
+ int l = bestLength - 3;
+ const struct off_len {
+ int off;
+ int bits;
+ } ol_table [] = {
+ /* Warning: if you change the table here, change /uc in the PS code! */
+ { 3, 0/*dummy*/ },
+ { 16, 4 },
+ { 32, 5 },
+ { 64, 6 },
+ { 128, 7 },
+ { /*256*/ 0xfffffff, 8 },
+ };
+
+ if ( l < ol_table[0].off ) {
+ emitBits( out, outOffset, outBit,
+ quoteSize, l );
+ } else {
+ const off_len *ol = ol_table;
+ l -= ol->off;
+ ol++;
+ while ( l >= ol->off ) {
+ l -= ol->off;
+ ol++;
+ }
+ emitBits( out, outOffset, outBit,
+ quoteSize, ol->bits-1 );
+ emitBits( out, outOffset, outBit,
+ ol->bits, l );
+ }
+ emitBits( out, outOffset, outBit,
+ quoteReach, index - bestCandidate - 1 );
+ emittedUntil += bestLength;
+ }
+ index++;
+ }
+ /* we've output all the data; time to clean up and finish off the
+ last characters. */
+ if ( outBit )
+ outOffset++;
+ i = 0;
+ /* we have to make sure the data is encoded in a stylish way :) */
+ while( i < outOffset ) {
+ uchar c = out[i];
+ c += 42;
+ if ( c > 'Z' && ( c != 't' || i == 0 || out[i-1] != 'Q' ) )
+ c += 84;
+ out[i] = c;
+ i++;
+ }
+ TQByteArray outarr;
+ outarr.duplicate( out, outOffset );
+ free( out );
+ delete [] pixel;
+
+#ifdef DEBUG_COMPRESS
+ qDebug( "------------- image compression statistics ----------------" );
+ qDebug(" compression time %d", t.elapsed() );
+ qDebug( "Size dist of uncompressed blocks:" );
+ qDebug( "\t%d\t%d\t%d\t%d\t%d\t%d\n", sizeUncompressed[0], sizeUncompressed[1],
+ sizeUncompressed[2], sizeUncompressed[3], sizeUncompressed[4], sizeUncompressed[5]);
+ qDebug( "\t%d\t%d\t%d\t%d\t%d\n", sizeUncompressed[6], sizeUncompressed[7],
+ sizeUncompressed[8], sizeUncompressed[9], sizeUncompressed[10] );
+ qDebug( "Size dist of compressed blocks:" );
+ qDebug( "\t%d\t%d\t%d\t%d\t%d\t%d\n", sizeCompressed[0], sizeCompressed[1],
+ sizeCompressed[2], sizeCompressed[3], sizeCompressed[4], sizeCompressed[5]);
+ qDebug( "\t%d\t%d\t%d\t%d\t%d\n", sizeCompressed[6], sizeCompressed[7],
+ sizeCompressed[8], sizeCompressed[9], sizeCompressed[10] );
+ qDebug( "===> total compression ratio %d/%d = %f", outOffset, size, (float)outOffset/(float)size );
+ qDebug( "-----------------------------------------------------------" );
+#endif
+
+ return outarr;
+}
+
+#undef XCOORD
+#undef YCOORD
+#undef WIDTH
+#undef HEIGHT
+#undef POINT
+#undef RECT
+#undef INT_ARG
+
+#define XCOORD(x) (float)(x)
+#define YCOORD(y) (float)(y)
+#define WIDTH(w) (float)(w)
+#define HEIGHT(h) (float)(h)
+
+#define POINT(index) XCOORD(p[index].point->x()) << ' ' << \
+ YCOORD(p[index].point->y()) << ' '
+#define RECT(index) XCOORD(p[index].rect->normalize().x()) << ' ' << \
+ YCOORD(p[index].rect->normalize().y()) << ' ' << \
+ WIDTH (p[index].rect->normalize().width()) << ' ' << \
+ HEIGHT(p[index].rect->normalize().height()) << ' '
+#define INT_ARG(index) p[index].ival << ' '
+
+static char returnbuffer[13];
+static const char * color( const TQColor &c, TQPrinter * printer )
+{
+ if ( c == TQt::black )
+ qstrcpy( returnbuffer, "B " );
+ else if ( c == TQt::white )
+ qstrcpy( returnbuffer, "W " );
+ else if ( c.red() == c.green() && c.red() == c.blue() )
+ sprintf( returnbuffer, "%d d2 ", c.red() );
+ else if ( printer->colorMode() == TQPrinter::GrayScale )
+ sprintf( returnbuffer, "%d d2 ",
+ tqGray( c.red(), c.green(),c.blue() ) );
+ else
+ sprintf( returnbuffer, "%d %d %d ",
+ c.red(), c.green(), c.blue() );
+ return returnbuffer;
+}
+
+
+static const char * psCap( TQt::PenCapStyle p )
+{
+ if ( p == TQt::SquareCap )
+ return "2 ";
+ else if ( p == TQt::RoundCap )
+ return "1 ";
+ return "0 ";
+}
+
+
+static const char * psJoin( TQt::PenJoinStyle p ) {
+ if ( p == TQt::BevelJoin )
+ return "2 ";
+ else if ( p == TQt::RoundJoin )
+ return "1 ";
+ return "0 ";
+}
+
+
+
+void TQPSPrinterPrivate::drawImage( TQPainter *paint, float x, float y, float w, float h,
+ const TQImage &img, const TQImage &tqmask )
+{
+ if ( !w || !h || img.isNull() ) return;
+
+ int width = img.width();
+ int height = img.height();
+ float scaleX = (float)width/w;
+ float scaleY = (float)height/h;
+
+ bool gray = (printer->colorMode() == TQPrinter::GrayScale) ||
+ img.allGray();
+ int splitSize = 21830 * (gray ? 3 : 1 );
+ if ( width * height > splitSize ) { // 65535/3, tolerance for broken printers
+ int images, subheight;
+ images = ( width * height + splitSize - 1 ) / splitSize;
+ subheight = ( height + images-1 ) / images;
+ while ( subheight * width > splitSize ) {
+ images++;
+ subheight = ( height + images-1 ) / images;
+ }
+ int suby = 0;
+ while( suby < height ) {
+ drawImage(paint, x, y + suby/scaleY, w, TQMIN( subheight, height-suby )/scaleY,
+ img.copy( 0, suby, width, TQMIN( subheight, height-suby ) ),
+ tqmask.isNull() ? tqmask : tqmask.copy( 0, suby, width, TQMIN( subheight, height-suby ) ));
+ suby += subheight;
+ }
+ } else {
+ TQByteArray out;
+ int size = 0;
+ const char *bits;
+
+ if ( !tqmask.isNull() ) {
+ out = ::compress( tqmask, TRUE );
+ size = (width+7)/8*height;
+ pageStream << "/tqmask " << size << " string uc\n";
+ ps_r7( pageStream, out, out.size() );
+ pageStream << "d\n";
+ }
+ if ( img.depth() == 1 ) {
+ size = (width+7)/8*height;
+ bits = "1 ";
+ } else if ( gray ) {
+ size = width*height;
+ bits = "8 ";
+ } else {
+ size = width*height*3;
+ bits = "24 ";
+ }
+
+ out = ::compress( img, gray );
+ pageStream << "/sl " << size << " string uc\n";
+ ps_r7( pageStream, out, out.size() );
+ pageStream << "d\n"
+ << width << ' ' << height << "[" << scaleX << " 0 0 " << scaleY << " 0 0]sl "
+ << bits << (!tqmask.isNull() ? "tqmask " : "false ")
+ << x << ' ' << y << " di\n";
+ }
+}
+
+
+void TQPSPrinterPrivate::matrixSetup( TQPainter *paint )
+{
+#ifndef TQT_NO_TRANSFORMATIONS
+ TQWMatrix tmp;
+ if ( paint->hasViewXForm() ) {
+ TQRect viewport = paint->viewport();
+ TQRect window = paint->window();
+ tmp.translate( viewport.x(), viewport.y() );
+ tmp.scale( 1.0 * viewport.width() / window.width(),
+ 1.0 * viewport.height() / window.height() );
+ tmp.translate( -window.x(), -window.y() );
+ }
+ if ( paint->hasWorldXForm() ) {
+ tmp = paint->tqworldMatrix() * tmp;
+ }
+ pageStream << "["
+ << tmp.m11() << ' ' << tmp.m12() << ' '
+ << tmp.m21() << ' ' << tmp.m22() << ' '
+ << tmp.dx() << ' ' << tmp.dy()
+ << "]ST\n";
+#else
+ TQPoint p(0,0);
+ p = paint->xForm(p);
+ pageStream << "["
+ << 0 << ' ' << 0 << ' '
+ << 0 << ' ' << 0 << ' '
+ << p.x() << ' ' << p.y()
+ << "]ST\n";
+#endif
+ dirtyMatrix = FALSE;
+}
+
+void TQPSPrinterPrivate::orientationSetup()
+{
+ if ( printer->orientation() == TQPrinter::Landscape )
+ pageStream << "TQLS\n";
+}
+
+
+void TQPSPrinterPrivate::emitHeader( bool finished )
+{
+ TQString title = printer->docName();
+ TQString creator = printer->creator();
+ if ( !creator ) // default creator
+ creator = TQString::tqfromLatin1("TQt " TQT_VERSION_STR);
+ outDevice = new TQFile();
+ (void)((TQFile *)outDevice)->open( IO_WriteOnly, fd );
+ outStream.setDevice( outDevice );
+ outStream << "%!PS-Adobe-1.0";
+ TQPaintDeviceMetrics m( printer );
+ scale = 72. / ((float) m.logicalDpiY());
+ uint mtop, mleft, mbottom, mright;
+ printer->margins( &mtop, &mleft, &mbottom, &mright );
+ int width = m.width();
+ int height = m.height();
+ bool fullPage = printer->fullPage();
+ if ( finished && pageCount == 1 && printer->numCopies() == 1 &&
+ ( ( printer->fullPage() && qt_gen_epsf ) ||
+ ( printer->outputToFile() && printer->outputFileName().endsWith( ".eps" ) ) )
+ ) {
+ if ( !boundingBox.isValid() )
+ boundingBox.setRect( 0, 0, width, height );
+ if ( printer->orientation() == TQPrinter::Landscape ) {
+ if ( !fullPage )
+ boundingBox.moveBy( -mleft, -mtop );
+ outStream << " EPSF-3.0\n%%BoundingBox: "
+ << (int)(m.height() - boundingBox.bottom())*scale << " " // llx
+ << (int)(m.width() - boundingBox.right())*scale - 1 << " " // lly
+ << (int)(m.height() - boundingBox.top())*scale + 1 << " " // urx
+ << (int)(m.width() - boundingBox.left())*scale; // ury
+ } else {
+ if ( !fullPage )
+ boundingBox.moveBy( mleft, -mtop );
+ outStream << " EPSF-3.0\n%%BoundingBox: "
+ << (int)(boundingBox.left())*scale << " "
+ << (int)(m.height() - boundingBox.bottom())*scale - 1 << " "
+ << (int)(boundingBox.right())*scale + 1 << " "
+ << (int)(m.height() - boundingBox.top())*scale;
+ }
+ } else {
+ int w = width + (fullPage ? 0 : mleft + mright);
+ int h = height + (fullPage ? 0 : mtop + mbottom);
+ w = (int)(w*scale);
+ h = (int)(h*scale);
+ // set a bounding box according to the DSC
+ if ( printer->orientation() == TQPrinter::Landscape )
+ outStream << "\n%%BoundingBox: 0 0 " << h << " " << w;
+ else
+ outStream << "\n%%BoundingBox: 0 0 " << w << " " << h;
+ }
+ outStream << "\n" << wrapDSC( "%%Creator: " + creator );
+ if ( !!title )
+ outStream << wrapDSC( "%%Title: " + title );
+ outStream << "%%CreationDate: " << TQDateTime::tqcurrentDateTime().toString();
+ outStream << "\n%%Orientation: ";
+ if ( printer->orientation() == TQPrinter::Landscape )
+ outStream << "Landscape";
+ else
+ outStream << "Portrait";
+ if ( finished )
+ outStream << "\n%%Pages: " << pageCount << "\n"
+ << wrapDSC( "%%DocumentFonts: " + fontsUsed );
+ else
+ outStream << "%%Pages: (atend)"
+ << "\n%%DocumentFonts: (atend)";
+ outStream << "\n%%EndComments\n";
+
+ outStream << "%%BeginProlog\n";
+ const char * const prologLicense = "% Prolog copyright 1994-2006 Trolltech. "
+ "You may copy this prolog in any way\n"
+ "% that is directly related to this "
+ "document. For other use of this prolog,\n"
+ "% see your licensing agreement for TQt.\n";
+ outStream << prologLicense << ps_header << "\n";
+
+ // we have to do this here, as scaling can affect this.
+ TQString lineStyles = "/LArr[" // Pen styles:
+ " [] []" // solid line
+ " [ w s ] [ s w ]" // dash line
+ " [ s s ] [ s s ]" // dot line
+ " [ m s s s ] [ s m s s ]" // dash dot line
+ " [ m s s s s ] [ s m s s s s ]" // dash dot dot line
+ " ] d\n";
+ lineStyles.tqreplace( TQRegExp( "w" ), toString( 10./scale ) );
+ lineStyles.tqreplace( TQRegExp( "m" ), toString( 5./scale ) );
+ lineStyles.tqreplace( TQRegExp( "s" ), toString( 3./scale ) );
+
+ outStream << lineStyles;
+
+ outStream << "/pageinit {\n";
+ if ( !printer->fullPage() ) {
+ if ( printer->orientation() == TQPrinter::Portrait )
+ outStream << mleft*scale << " "
+ << mbottom*scale << " translate\n";
+ else
+ outStream << mtop*scale << " "
+ << mleft*scale << " translate\n";
+ }
+ if ( printer->orientation() == TQPrinter::Portrait ) {
+ outStream << "% " << m.widthMM() << "*" << m.heightMM()
+ << "mm (portrait)\n0 " << height*scale
+ << " translate " << scale << " -" << scale << " scale/defM matrix CM d } d\n";
+ } else {
+ outStream << "% " << m.heightMM() << "*" << m.widthMM()
+ << " mm (landscape)\n 90 rotate " << scale << " -" << scale << " scale/defM matrix CM d } d\n";
+ }
+ outStream << "%%EndProlog\n";
+
+
+ outStream << "%%BeginSetup\n";
+ if ( printer->numCopies() > 1 ) {
+ outStream << "/#copies " << printer->numCopies() << " def\n";
+ outStream << "/NumCopies " << printer->numCopies() << " SPD\n";
+ outStream << "/Collate " << (printer->collateCopies() ? "true" : "false") << " SPD\n";
+ }
+ if ( fontBuffer->buffer().size() ) {
+ if ( pageCount == 1 || finished )
+ outStream << "% Fonts and encodings used\n";
+ else
+ outStream << "% Fonts and encodings used on pages 1-"
+ << pageCount << "\n";
+ TQDictIterator<TQPSPrinterFontPrivate> it(fonts);
+ while (it.current()) {
+ it.current()->download(outStream,TRUE); // true means its global
+ ++it;
+ }
+ outStream.writeRawBytes( fontBuffer->buffer().data(),
+ fontBuffer->buffer().size() );
+ }
+ outStream << "%%EndSetup\n";
+
+ outStream.writeRawBytes( buffer->buffer().data(),
+ buffer->buffer().size() );
+
+ delete buffer;
+ buffer = 0;
+ fontStream.unsetDevice();
+ delete fontBuffer;
+ fontBuffer = 0;
+}
+
+
+/* Called whenever a restore has been done. Currently done at the top of a
+ new page and whenever clipping is turned off. */
+void TQPSPrinterPrivate::resetDrawingTools( TQPainter *paint )
+{
+ TQPen defaultPen; // default drawing tools
+ TQBrush defaultBrush;
+
+ TQColor c = paint->backgroundColor();
+ if ( c != TQt::white )
+ pageStream << color( c, printer ) << "BC\n";
+
+ if ( paint->backgroundMode() != TQt::TransparentMode )
+ pageStream << "/OMo true d\n";
+
+ //currentUsed = currentSet;
+ //setFont( currentSet );
+ currentFontFile = 0;
+
+ TQBrush b = paint->brush();
+ if ( b != defaultBrush ) {
+ if ( b == TQt::CustomPattern ) {
+#if defined(CHECK_RANGE)
+ qWarning( "TQPrinter: Pixmap brush not supported" );
+#endif
+ } else {
+ cbrush = b;
+ }
+ }
+
+ dirtypen = TRUE;
+ dirtybrush = TRUE;
+
+ if ( paint->hasViewXForm() || paint->hasWorldXForm() )
+ matrixSetup( paint );
+}
+
+
+static void putRect( TQTextStream &stream, const TQRect &r )
+{
+ stream << r.x() << " "
+ << r.y() << " "
+ << r.width() << " "
+ << r.height() << " ";
+}
+
+
+void TQPSPrinterPrivate::setClippingOff( TQPainter *paint )
+{
+ pageStream << "CLO\n"; // clipping off, includes a restore
+ resetDrawingTools( paint ); // so drawing tools must be reset
+}
+
+
+void TQPSPrinterPrivate::clippingSetup( TQPainter *paint )
+{
+ if ( paint->hasClipping() ) {
+ if ( !firstClipOnPage )
+ setClippingOff( paint );
+ const TQRegion rgn = paint->clipRegion();
+ TQMemArray<TQRect> rects = rgn.rects();
+ int i;
+ pageStream<< "CLSTART\n"; // start clipping
+ for( i = 0 ; i < (int)rects.size() ; i++ ) {
+ putRect( pageStream, rects[i] );
+ pageStream << "ACR\n"; // add clip rect
+ if ( pageCount == 1 )
+ boundingBox = boundingBox.unite( rects[i] );
+ }
+ pageStream << "CLEND\n"; // end clipping
+ firstClipOnPage = FALSE;
+ } else {
+ if ( !firstClipOnPage ) // no need to turn off if first on page
+ setClippingOff( paint );
+ // if we're painting without clipping, the bounding box must
+ // be everything. NOTE: this assumes that this function is
+ // only ever called when something is to be painted.
+ TQPaintDeviceMetrics m( printer );
+ if ( !boundingBox.isValid() )
+ boundingBox.setRect( 0, 0, m.width(), m.height() );
+ }
+ dirtyClipping = FALSE;
+}
+
+void TQPSPrinterPrivate::initPage(TQPainter *paint)
+{
+
+ // a restore undefines all the fonts that have been defined
+ // inside the scope (normally within pages) and all the glyphs that
+ // have been added in the scope.
+
+ TQDictIterator<TQPSPrinterFontPrivate> it(fonts);
+ while (it.current()) {
+ it.current()->restore();
+ ++it;
+ }
+ if ( !buffer ) {
+ pageFontNames.clear();
+ }
+
+ pageStream.unsetDevice();
+ if ( pageBuffer )
+ delete pageBuffer;
+ pageBuffer = new TQBuffer();
+ pageBuffer->open( IO_WriteOnly );
+ pageStream.setEncoding( TQTextStream::Latin1 );
+ pageStream.setDevice( pageBuffer );
+ delete savedImage;
+ savedImage = 0;
+ textY = 0;
+ dirtyClipping = TRUE;
+ firstClipOnPage = TRUE;
+
+
+ resetDrawingTools( paint );
+ dirtyNewPage = FALSE;
+ pageFontNumber = headerFontNumber;
+}
+
+void TQPSPrinterPrivate::flushPage( bool last )
+{
+ if ( last && !pageBuffer )
+ return;
+ bool pageFonts = ( buffer == 0 );
+ if ( buffer &&
+// ( last || pagesInBuffer++ > -1 ||
+// ( pagesInBuffer > 4 && buffer->size() > 262144 ) ) )
+#ifdef TQ_WS_TQWS
+ (last || buffer->size() > 2000000) // embedded is usually limited in memory
+#else
+ (last || buffer->size() > 50000000)
+#endif
+ ) {
+// qDebug("emiting header at page %d", pageCount );
+ emitHeader( last );
+ }
+ outStream << "%%Page: "
+ << pageCount << ' ' << pageCount << endl
+ << "%%BeginPageSetup\n"
+ << "QI\n";
+ if (!dirtyNewPage) {
+ if ( pageFonts ) {
+ //qDebug("page fonts for page %d", pageCount);
+ // we have already downloaded the header. Maybe we have page fonts here
+ TQDictIterator<TQPSPrinterFontPrivate> it(fonts);
+ while (it.current()) {
+ it.current()->download( outStream, FALSE ); // FALSE means its for the page only
+ ++it;
+ }
+ }
+ outStream << "%%EndPageSetup\n";
+ if ( pageBuffer )
+ outStream.writeRawBytes( pageBuffer->buffer().data(),
+ pageBuffer->buffer().size() );
+ }
+ outStream << "\nQP\n";
+ pageCount++;
+}
+
+// ================ PSPrinter class ========================
+
+TQPSPrinter::TQPSPrinter( TQPrinter *prt, int fd )
+ : TQPaintDevice( TQInternal::Printer | TQInternal::ExternalDevice )
+{
+ d = new TQPSPrinterPrivate( prt, fd );
+}
+
+
+TQPSPrinter::~TQPSPrinter()
+{
+ if ( d->fd >= 0 )
+#if defined(_OS_WIN32_)
+ ::_close( d->fd );
+#else
+ ::close( d->fd );
+#endif
+ delete d;
+}
+
+
+
+static void ignoreSigPipe(bool b)
+{
+ static struct sigaction *users_sigpipe_handler = 0;
+
+ if (b) {
+ if (users_sigpipe_handler != 0)
+ return; // already ignoring sigpipe
+
+ users_sigpipe_handler = new struct sigaction;
+ struct sigaction tmp_sigpipe_handler;
+ tmp_sigpipe_handler.sa_handler = SIG_IGN;
+ sigemptyset(&tmp_sigpipe_handler.sa_mask);
+ tmp_sigpipe_handler.sa_flags = 0;
+
+ if (sigaction(SIGPIPE, &tmp_sigpipe_handler, users_sigpipe_handler) == -1) {
+ delete users_sigpipe_handler;
+ users_sigpipe_handler = 0;
+ }
+ }
+ else {
+ if (users_sigpipe_handler == 0)
+ return; // not ignoring sigpipe
+
+ if (sigaction(SIGPIPE, users_sigpipe_handler, 0) == -1)
+ qWarning("TQPSPrinter: could not restore SIGPIPE handler");
+
+ delete users_sigpipe_handler;
+ users_sigpipe_handler = 0;
+ }
+}
+
+bool TQPSPrinter::cmd( int c , TQPainter *paint, TQPDevCmdParam *p )
+{
+ if ( c == PdcBegin ) { // start painting
+ d->pagesInBuffer = 0;
+ d->buffer = new TQBuffer();
+ d->buffer->open( IO_WriteOnly );
+ d->outStream.setEncoding( TQTextStream::Latin1 );
+ d->outStream.setDevice( d->buffer );
+ d->fontBuffer = new TQBuffer();
+ d->fontBuffer->open( IO_WriteOnly );
+ d->fontStream.setEncoding( TQTextStream::Latin1 );
+ d->fontStream.setDevice( d->fontBuffer );
+ d->headerFontNumber = 0;
+ d->pageCount = 1; // initialize state
+ d->dirtyMatrix = TRUE;
+ d->dirtyClipping = TRUE;
+ d->dirtyNewPage = TRUE;
+ d->firstClipOnPage = TRUE;
+ d->boundingBox = TQRect( 0, 0, -1, -1 );
+ d->fontsUsed = TQString::tqfromLatin1("");
+
+ TQPaintDeviceMetrics m( d->printer );
+ d->scale = 72. / ((float) m.logicalDpiY());
+
+ return TRUE;
+ }
+
+ if ( c == PdcEnd ) { // painting done
+ bool pageCountAtEnd = (d->buffer != 0);
+
+ // we're writing to lp/lpr through a pipe, we don't want to crash with SIGPIPE
+ // if lp/lpr dies
+ ignoreSigPipe(TRUE);
+ d->flushPage( TRUE );
+ d->outStream << "%%Trailer\n";
+ if ( pageCountAtEnd )
+ d->outStream << "%%Pages: " << d->pageCount - 1 << "\n" <<
+ wrapDSC( "%%DocumentFonts: " + d->fontsUsed );
+ d->outStream << "%%EOF\n";
+ ignoreSigPipe(FALSE);
+
+ d->outStream.unsetDevice();
+ if ( d->outDevice )
+ d->outDevice->close();
+ if ( d->fd >= 0 )
+ ::close( d->fd );
+ d->fd = -1;
+ delete d->outDevice;
+ d->outDevice = 0;
+ }
+
+ if ( c >= PdcDrawFirst && c <= PdcDrawLast ) {
+ if ( !paint )
+ return FALSE; // sanity
+ if ( d->dirtyNewPage )
+ d->initPage( paint );
+ if ( d->dirtyMatrix )
+ d->matrixSetup( paint );
+ if ( d->dirtyClipping ) // Must be after matrixSetup and initPage
+ d->clippingSetup( paint );
+ if ( d->dirtypen ) {
+ // we special-case for narrow solid lines with the default
+ // cap and join styles
+ if ( d->cpen.style() == TQt::SolidLine && d->cpen.width() == 0 &&
+ d->cpen.capStyle() == TQt::FlatCap &&
+ d->cpen.joinStyle() == TQt::MiterJoin )
+ d->pageStream << color( d->cpen.color(), d->printer ) << "P1\n";
+ else
+ d->pageStream << (int)d->cpen.style() << ' ' << d->cpen.width()
+ << ' ' << color( d->cpen.color(), d->printer )
+ << psCap( d->cpen.capStyle() )
+ << psJoin( d->cpen.joinStyle() ) << "PE\n";
+ d->dirtypen = FALSE;
+ }
+ if ( d->dirtybrush ) {
+ // we special-case for nobrush and solid white, since
+ // those are the two most common brushes
+ if ( d->cbrush.style() == TQt::NoBrush )
+ d->pageStream << "NB\n";
+ else if ( d->cbrush.style() == TQt::SolidPattern &&
+ d->cbrush.color() == TQt::white )
+ d->pageStream << "WB\n";
+ else
+ d->pageStream << (int)d->cbrush.style() << ' '
+ << color( d->cbrush.color(), d->printer ) << "BR\n";
+ d->dirtybrush = FALSE;
+ }
+ if ( d->dirtyBkColor ) {
+ d->pageStream << color( d->bkColor, d->printer ) << "BC\n";
+ d->dirtyBkColor = FALSE;
+ }
+ if ( d->dirtyBkMode ) {
+ if ( d->bkMode == TQt::TransparentMode )
+ d->pageStream << "/OMo false d\n";
+ else
+ d->pageStream << "/OMo true d\n";
+ d->dirtyBkMode = FALSE;
+ }
+ }
+
+ switch( c ) {
+ case PdcDrawPoint:
+ d->pageStream << POINT(0) << "P\n";
+ break;
+ case PdcMoveTo:
+ d->pageStream << POINT(0) << "M\n";
+ break;
+ case PdcLineTo:
+ d->pageStream << POINT(0) << "L\n";
+ break;
+ case PdcDrawLine:
+ if ( p[0].point->y() == p[1].point->y() )
+ d->pageStream << POINT(1) << p[0].point->x() << " HL\n";
+ else if ( p[0].point->x() == p[1].point->x() )
+ d->pageStream << POINT(1) << p[0].point->y() << " VL\n";
+ else
+ d->pageStream << POINT(1) << POINT(0) << "DL\n";
+ break;
+ case PdcDrawRect:
+ d->pageStream << RECT(0) << "R\n";
+ break;
+ case PdcDrawRoundRect:
+ d->pageStream << RECT(0) << INT_ARG(1) << INT_ARG(2) << "RR\n";
+ break;
+ case PdcDrawEllipse:
+ d->pageStream << RECT(0) << "E\n";
+ break;
+ case PdcDrawArc:
+ d->pageStream << RECT(0) << INT_ARG(1) << INT_ARG(2) << "A\n";
+ break;
+ case PdcDrawPie:
+ d->pageStream << RECT(0) << INT_ARG(1) << INT_ARG(2) << "PIE\n";
+ break;
+ case PdcDrawChord:
+ d->pageStream << RECT(0) << INT_ARG(1) << INT_ARG(2) << "CH\n";
+ break;
+ case PdcDrawLineSegments:
+ if ( p[0].ptarr->size() > 0 ) {
+ TQPointArray a = *p[0].ptarr;
+ TQPoint pt;
+ d->pageStream << "NP\n";
+ for ( int i=0; i<(int)a.size(); i+=2 ) {
+ pt = a.point( i );
+ d->pageStream << XCOORD(pt.x()) << ' '
+ << YCOORD(pt.y()) << " MT\n";
+ pt = a.point( i+1 );
+ d->pageStream << XCOORD(pt.x()) << ' '
+ << YCOORD(pt.y()) << " LT\n";
+ }
+ d->pageStream << "QS\n";
+ }
+ break;
+ case PdcDrawPolyline:
+ if ( p[0].ptarr->size() > 1 ) {
+ TQPointArray a = *p[0].ptarr;
+ TQPoint pt = a.point( 0 );
+ d->pageStream << "NP\n"
+ << XCOORD(pt.x()) << ' ' << YCOORD(pt.y()) << " MT\n";
+ for ( int i=1; i<(int)a.size(); i++ ) {
+ pt = a.point( i );
+ d->pageStream << XCOORD(pt.x()) << ' '
+ << YCOORD(pt.y()) << " LT\n";
+ }
+ d->pageStream << "QS\n";
+ }
+ break;
+ case PdcDrawPolygon:
+ if ( p[0].ptarr->size() > 2 ) {
+ TQPointArray a = *p[0].ptarr;
+ if ( p[1].ival )
+ d->pageStream << "/WFi true d\n";
+ TQPoint pt = a.point(0);
+ d->pageStream << "NP\n";
+ d->pageStream << XCOORD(pt.x()) << ' '
+ << YCOORD(pt.y()) << " MT\n";
+ for( int i=1; i<(int)a.size(); i++) {
+ pt = a.point( i );
+ d->pageStream << XCOORD(pt.x()) << ' '
+ << YCOORD(pt.y()) << " LT\n";
+ }
+ d->pageStream << "CP BF QS\n";
+ if ( p[1].ival )
+ d->pageStream << "/WFi false d\n";
+ }
+ break;
+ case PdcDrawCubicBezier:
+ if ( p[0].ptarr->size() == 4 ) {
+ d->pageStream << "NP\n";
+ TQPointArray a = *p[0].ptarr;
+ d->pageStream << XCOORD(a[0].x()) << ' '
+ << YCOORD(a[0].y()) << " MT ";
+ for ( int i=1; i<4; i++ ) {
+ d->pageStream << XCOORD(a[i].x()) << ' '
+ << YCOORD(a[i].y()) << ' ';
+ }
+ d->pageStream << "BZ\n";
+ }
+ break;
+ case PdcDrawText2:
+ // we use tqdrawTextItem instead
+ return TRUE;
+ case PdcDrawText2Formatted:
+ return TRUE;
+ case PdcDrawTextItem: {
+ const TQTextItem *ti = p[1].textItem;
+ TQScriptItem &si = ti->engine->items[ti->item];
+ int len = ti->engine->length( ti->item );
+ if ( si.isSpace || si.isObject )
+ return FALSE;
+
+ if ( d->currentSet != d->currentUsed || d->scriptUsed != si.analysis.script || !d->currentFontFile ) {
+ d->currentUsed = d->currentSet;
+ d->setFont( d->currentSet, si.analysis.script );
+ }
+ if( d->currentFontFile ) // better not crash in case somethig goes wrong.
+ d->currentFontFile->drawText( d->pageStream, *p[0].point, ti->engine, ti->item,
+ ti->engine->string.mid( si.position, len ), d, paint);
+ return FALSE;
+ }
+ case PdcDrawPixmap: {
+ if ( p[1].pixmap->isNull() )
+ break;
+ TQRect r = *p[0].rect;
+ TQImage img;
+ img = *(p[1].pixmap);
+ TQImage tqmask;
+ if ( p[1].pixmap->tqmask() )
+ tqmask = *(p[1].pixmap->tqmask());
+ d->drawImage(paint, r.x(), r.y(), r.width(), r.height(), img, tqmask);
+ break;
+ }
+ case PdcDrawImage: {
+ if ( p[1].image->isNull() )
+ break;
+ TQRect r = *(p[0].rect);
+ TQImage img = *(p[1].image);
+ TQImage tqmask;
+#ifndef TQT_NO_IMAGE_DITHER_TO_1
+ if ( img.hasAlphaBuffer() )
+ tqmask = img.createAlphaMask();
+#endif
+ d->drawImage(paint, r.x(), r.y(), r.width(), r.height(), img, tqmask);
+ break;
+ }
+ case PdcSetBkColor:
+ {
+ if ( d->bkColor != *(p[0].color) ) {
+ d->bkColor = *(p[0].color);
+ d->dirtyBkColor = TRUE;
+ }
+ break;
+ }
+ case PdcSetBkMode:
+ {
+ if ( d->bkMode != p[0].ival ) {
+ d->bkMode = (TQt::BGMode) p[0].ival;
+ d->dirtyBkMode = TRUE;
+ }
+ break;
+ }
+ case PdcSetROP:
+#if defined(CHECK_RANGE)
+ if ( p[0].ival != TQt::CopyROP )
+ qWarning( "TQPrinter: Raster operation setting not supported" );
+#endif
+ break;
+ case PdcSetBrushOrigin:
+ break;
+ case PdcSetFont:
+ d->currentSet = *(p[0].font);
+ d->fm = paint->fontMetrics();
+ // turn these off - they confuse the 'avoid font change' logic
+ d->currentSet.setUnderline( FALSE );
+ d->currentSet.setStrikeOut( FALSE );
+ break;
+ case PdcSetPen:
+ if ( d->cpen != *(p[0].pen) ) {
+ d->dirtypen = TRUE;
+ d->cpen = *(p[0].pen);
+ }
+ break;
+ case PdcSetBrush:
+ if ( p[0].brush->style() == TQt::CustomPattern ) {
+#if defined(CHECK_RANGE)
+ qWarning( "TQPrinter: Pixmap brush not supported" );
+#endif
+ return FALSE;
+ }
+ if ( d->cbrush != *(p[0].brush) ) {
+ d->dirtybrush = TRUE;
+ d->cbrush = *(p[0].brush);
+ }
+ break;
+ case PdcSetTabStops:
+ case PdcSetTabArray:
+ return FALSE;
+ case PdcSetUnit:
+ break;
+ case PdcSetVXform:
+ case PdcSetWindow:
+ case PdcSetViewport:
+ case PdcSetWXform:
+ case PdcSetWMatrix:
+ case PdcRestoreWMatrix:
+ d->dirtyMatrix = TRUE;
+ break;
+ case PdcSetClip:
+ d->dirtyClipping = TRUE;
+ break;
+ case PdcSetClipRegion:
+ d->dirtyClipping = TRUE;
+ break;
+ case NewPage:
+ // we're writing to lp/lpr through a pipe, we don't want to crash with SIGPIPE
+ // if lp/lpr dies
+ ignoreSigPipe(TRUE);
+ d->flushPage();
+ ignoreSigPipe(FALSE);
+
+ d->dirtyNewPage = TRUE;
+ break;
+ case AbortPrinting:
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+#endif // TQT_NO_PRINTER
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqpsprinter_p.h b/tqtinterface/qt4/src/kernel/tqpsprinter_p.h
new file mode 100644
index 0000000..878d9d3
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqpsprinter_p.h
@@ -0,0 +1,98 @@
+/**********************************************************************
+**
+** Definition of internal TQPSPrinter class.
+** TQPSPrinter implements PostScript (tm) output via TQPrinter.
+**
+** Created : 940927
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPSPRINTER_P_H
+#define TQPSPRINTER_P_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qpsprinter.cpp and qprinter_x11.cpp.
+// This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+//
+
+
+#ifndef TQT_H
+#include "tqprinter.h"
+#include "tqtextstream.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_PRINTER
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+class TQPSPrinterPrivate;
+
+class TQ_EXPORT TQPSPrinter : public TQPaintDevice
+{
+private:
+ // TQPrinter uses these
+ TQPSPrinter( TQPrinter *, int );
+ ~TQPSPrinter();
+
+ bool cmd ( int, TQPainter *, TQPDevCmdParam * );
+
+ enum { NewPage = 100, AbortPrinting };
+
+ friend class TQPrinter;
+private:
+ // not used by TQPrinter
+ TQPSPrinterPrivate *d;
+
+ // Disabled copy constructor and operator=
+ TQPSPrinter( const TQPSPrinter & );
+ TQPSPrinter &operator=( const TQPSPrinter & );
+};
+
+#endif // USE_QT4
+
+#endif // TQT_NO_PRINTER
+
+#endif // TQPSPRINTER_P_H
diff --git a/tqtinterface/qt4/src/kernel/tqrect.cpp b/tqtinterface/qt4/src/kernel/tqrect.cpp
new file mode 100644
index 0000000..aa16303
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqrect.cpp
@@ -0,0 +1,1010 @@
+/****************************************************************************
+**
+** Implementation of TQRect class
+**
+** Created : 931028
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <tqtglobaldefines.h>
+// Nasty, nasty horrid HACK to get access to QRect's private members
+// This is TERRIBLE and I wish there was a way around it
+// This is a good example of the new, broken & irritating Qt4 API,
+// and the corresponding loss in functionality versus Qt3.
+#define private protected
+#include <Qt/qrect.h>
+#undef private
+
+#define TQRECT_C
+#include "tqrect.h"
+#include "tqdatastream.h"
+
+#ifdef USE_QT4
+
+int &TQRect::rLeft() { return x1; }
+int &TQRect::rTop() { return y1; }
+int &TQRect::rRight() { return x2; }
+int &TQRect::rBottom() { return y2; }
+
+/*!
+ Extracts the rectangle parameters as the position \a *x, \a *y and
+ width \a *w and height \a *h.
+
+ \sa setRect(), coords()
+*/
+
+void TQRect::rect( int *x, int *y, int *w, int *h ) const
+{
+ *x = x1;
+ *y = y1;
+ *w = x2-x1+1;
+ *h = y2-y1+1;
+}
+
+/*!
+ Extracts the rectangle parameters as the top-left point \a *xp1,
+ \a *yp1 and the bottom-right point \a *xp2, \a *yp2.
+
+ \sa setCoords(), rect()
+*/
+
+void TQRect::coords( int *xp1, int *yp1, int *xp2, int *yp2 ) const
+{
+ *xp1 = x1;
+ *yp1 = y1;
+ *xp2 = x2;
+ *yp2 = y2;
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQRect
+ \brief The TQRect class defines a rectangle in the plane.
+
+ \ingroup images
+ \ingroup graphics
+ \mainclass
+
+ A rectangle is internally represented as an upper-left corner and
+ a bottom-right corner, but it is normally expressed as an
+ upper-left corner and a size.
+
+ The coordinate type is TQCOORD (defined in \c tqwindowdefs.h as \c
+ int). The minimum value of TQCOORD is TQCOORD_MIN (-2147483648) and
+ the maximum value is TQCOORD_MAX (2147483647).
+
+ Note that the size (width and height) of a rectangle might be
+ different from what you are used to. If the top-left corner and
+ the bottom-right corner are the same, the height and the width of
+ the rectangle will both be 1.
+
+ Generally, \e{width = right - left + 1} and \e{height = bottom -
+ top + 1}. We designed it this way to make it correspond to
+ rectangular spaces used by drawing functions in which the width
+ and height denote a number of pixels. For example, drawing a
+ rectangle with width and height 1 draws a single pixel.
+
+ The default coordinate system has origin (0, 0) in the top-left
+ corner. The positive direction of the y axis is down, and the
+ positive x axis is from left to right.
+
+ A TQRect can be constructed with a set of left, top, width and
+ height integers, from two TQPoints or from a TQPoint and a TQSize.
+ After creation the dimensions can be changed, e.g. with setLeft(),
+ setRight(), setTop() and setBottom(), or by setting sizes, e.g.
+ setWidth(), setHeight() and setSize(). The dimensions can also be
+ changed with the move functions, e.g. moveBy(), moveCenter(),
+ moveBottomRight(), etc. You can also add coordinates to a
+ rectangle with addCoords().
+
+ You can test to see if a TQRect tqcontains a specific point with
+ tqcontains(). You can also test to see if two TQRects intersect with
+ intersects() (see also intersect()). To get the bounding rectangle
+ of two TQRects use unite().
+
+ \sa TQPoint, TQSize
+*/
+
+
+/*****************************************************************************
+ TQRect member functions
+ *****************************************************************************/
+
+/*!
+ \fn TQRect::TQRect()
+
+ Constructs an invalid rectangle.
+*/
+
+/*!
+ Constructs a rectangle with \a topLeft as the top-left corner and
+ \a bottomRight as the bottom-right corner.
+*/
+
+TQRect::TQRect( const TQPoint &topLeft, const TQPoint &bottomRight )
+{
+ x1 = (TQCOORD)topLeft.x();
+ y1 = (TQCOORD)topLeft.y();
+ x2 = (TQCOORD)bottomRight.x();
+ y2 = (TQCOORD)bottomRight.y();
+}
+
+/*!
+ Constructs a rectangle with \a topLeft as the top-left corner and
+ \a size as the rectangle size.
+*/
+
+TQRect::TQRect( const TQPoint &topLeft, const TQSize &size )
+{
+ x1 = (TQCOORD)topLeft.x();
+ y1 = (TQCOORD)topLeft.y();
+ x2 = (TQCOORD)(x1+size.width()-1);
+ y2 = (TQCOORD)(y1+size.height()-1);
+}
+
+/*!
+ \fn TQRect::TQRect( int left, int top, int width, int height )
+
+ Constructs a rectangle with the \a top, \a left corner and \a
+ width and \a height.
+
+ Example (creates three identical rectangles):
+ \code
+ TQRect r1( TQPoint(100,200), TQPoint(110,215) );
+ TQRect r2( TQPoint(100,200), TQSize(11,16) );
+ TQRect r3( 100, 200, 11, 16 );
+ \endcode
+*/
+
+
+/*!
+ \fn bool TQRect::isNull() const
+
+ Returns TRUE if the rectangle is a null rectangle; otherwise
+ returns FALSE.
+
+ A null rectangle has both the width and the height set to 0, that
+ is right() == left() - 1 and bottom() == top() - 1.
+
+ Note that if right() == left() and bottom() == top(), then the
+ rectangle has width 1 and height 1.
+
+ A null rectangle is also empty.
+
+ A null rectangle is not valid.
+
+ \sa isEmpty(), isValid()
+*/
+
+/*!
+ \fn bool TQRect::isEmpty() const
+
+ Returns TRUE if the rectangle is empty; otherwise returns FALSE.
+
+ An empty rectangle has a left() \> right() or top() \> bottom().
+
+ An empty rectangle is not valid. \c{isEmpty() == !isValid()}
+
+ \sa isNull(), isValid(), normalize()
+*/
+
+/*!
+ \fn bool TQRect::isValid() const
+
+ Returns TRUE if the rectangle is valid; otherwise returns FALSE.
+
+ A valid rectangle has a left() \<= right() and top() \<= bottom().
+
+ Note that non-trivial operations like intersections are not defined
+ for invalid rectangles.
+
+ \c{isValid() == !isEmpty()}
+
+ \sa isNull(), isEmpty(), normalize()
+*/
+
+
+/*!
+ Returns a normalized rectangle, i.e. a rectangle that has a
+ non-negative width and height.
+
+ It swaps left and right if left() \> right(), and swaps top and
+ bottom if top() \> bottom().
+
+ \sa isValid()
+*/
+
+TQRect TQRect::normalize() const
+{
+ TQRect r;
+ if ( x2 < x1 ) { // swap bad x values
+ r.x1 = x2;
+ r.x2 = x1;
+ } else {
+ r.x1 = x1;
+ r.x2 = x2;
+ }
+ if ( y2 < y1 ) { // swap bad y values
+ r.y1 = y2;
+ r.y2 = y1;
+ } else {
+ r.y1 = y1;
+ r.y2 = y2;
+ }
+ return r;
+}
+
+
+/*!
+ \fn int TQRect::left() const
+
+ Returns the left coordinate of the rectangle. Identical to x().
+
+ \sa setLeft(), right(), topLeft(), bottomLeft()
+*/
+
+/*!
+ \fn int TQRect::top() const
+
+ Returns the top coordinate of the rectangle. Identical to y().
+
+ \sa setTop(), bottom(), topLeft(), topRight()
+*/
+
+/*!
+ \fn int TQRect::right() const
+
+ Returns the right coordinate of the rectangle.
+
+ \sa setRight(), left(), topRight(), bottomRight()
+*/
+
+/*!
+ \fn int TQRect::bottom() const
+
+ Returns the bottom coordinate of the rectangle.
+
+ \sa setBottom(), top(), bottomLeft(), bottomRight()
+*/
+
+/*!
+ \fn TQCOORD &TQRect::rLeft()
+
+ Returns a reference to the left coordinate of the rectangle.
+
+ \sa rTop(), rRight(), rBottom()
+*/
+
+/*!
+ \fn TQCOORD &TQRect::rTop()
+
+ Returns a reference to the top coordinate of the rectangle.
+
+ \sa rLeft(), rRight(), rBottom()
+*/
+
+/*!
+ \fn TQCOORD &TQRect::rRight()
+
+ Returns a reference to the right coordinate of the rectangle.
+
+ \sa rLeft(), rTop(), rBottom()
+*/
+
+/*!
+ \fn TQCOORD &TQRect::rBottom()
+
+ Returns a reference to the bottom coordinate of the rectangle.
+
+ \sa rLeft(), rTop(), rRight()
+*/
+
+/*!
+ \fn int TQRect::x() const
+
+ Returns the left coordinate of the rectangle. Identical to left().
+
+ \sa left(), y(), setX()
+*/
+
+/*!
+ \fn int TQRect::y() const
+
+ Returns the top coordinate of the rectangle. Identical to top().
+
+ \sa top(), x(), setY()
+*/
+
+/*!
+ \fn void TQRect::setLeft( int pos )
+
+ Sets the left edge of the rectangle to \a pos. May change the
+ width, but will never change the right edge of the rectangle.
+
+ Identical to setX().
+
+ \sa left(), setTop(), setWidth()
+*/
+
+/*!
+ \fn void TQRect::setTop( int pos )
+
+ Sets the top edge of the rectangle to \a pos. May change the
+ height, but will never change the bottom edge of the rectangle.
+
+ Identical to setY().
+
+ \sa top(), setBottom(), setHeight()
+*/
+
+/*!
+ \fn void TQRect::setRight( int pos )
+
+ Sets the right edge of the rectangle to \a pos. May change the
+ width, but will never change the left edge of the rectangle.
+
+ \sa right(), setLeft(), setWidth()
+*/
+
+/*!
+ \fn void TQRect::setBottom( int pos )
+
+ Sets the bottom edge of the rectangle to \a pos. May change the
+ height, but will never change the top edge of the rectangle.
+
+ \sa bottom(), setTop(), setHeight()
+*/
+
+/*!
+ \fn void TQRect::setX( int x )
+
+ Sets the x position of the rectangle (its left end) to \a x. May
+ change the width, but will never change the right edge of the
+ rectangle.
+
+ Identical to setLeft().
+
+ \sa x(), setY()
+*/
+
+/*!
+ \fn void TQRect::setY( int y )
+
+ Sets the y position of the rectangle (its top) to \a y. May change
+ the height, but will never change the bottom edge of the
+ rectangle.
+
+ Identical to setTop().
+
+ \sa y(), setX()
+*/
+
+/*!
+ Set the top-left corner of the rectangle to \a p. May change
+ the size, but will the never change the bottom-right corner of
+ the rectangle.
+
+ \sa topLeft(), moveTopLeft(), setBottomRight(), setTopRight(), setBottomLeft()
+*/
+void TQRect::setTopLeft( const TQPoint &p )
+{
+ setLeft( p.x() );
+ setTop( p.y() );
+}
+
+/*!
+ Set the bottom-right corner of the rectangle to \a p. May change
+ the size, but will the never change the top-left corner of
+ the rectangle.
+
+ \sa bottomRight(), moveBottomRight(), setTopLeft(), setTopRight(), setBottomLeft()
+*/
+void TQRect::setBottomRight( const TQPoint &p )
+{
+ setRight( p.x() );
+ setBottom( p.y() );
+}
+
+/*!
+ Set the top-right corner of the rectangle to \a p. May change
+ the size, but will the never change the bottom-left corner of
+ the rectangle.
+
+ \sa topRight(), moveTopRight(), setTopLeft(), setBottomRight(), setBottomLeft()
+*/
+void TQRect::setTopRight( const TQPoint &p )
+{
+ setRight( p.x() );
+ setTop( p.y() );
+}
+
+/*!
+ Set the bottom-left corner of the rectangle to \a p. May change
+ the size, but will the never change the top-right corner of
+ the rectangle.
+
+ \sa bottomLeft(), moveBottomLeft(), setTopLeft(), setBottomRight(), setTopRight()
+*/
+void TQRect::setBottomLeft( const TQPoint &p )
+{
+ setLeft( p.x() );
+ setBottom( p.y() );
+}
+
+/*!
+ \fn TQPoint TQRect::topLeft() const
+
+ Returns the top-left position of the rectangle.
+
+ \sa setTopLeft(), moveTopLeft(), bottomRight(), left(), top()
+*/
+
+/*!
+ \fn TQPoint TQRect::bottomRight() const
+
+ Returns the bottom-right position of the rectangle.
+
+ \sa setBottomRight(), moveBottomRight(), topLeft(), right(), bottom()
+*/
+
+/*!
+ \fn TQPoint TQRect::topRight() const
+
+ Returns the top-right position of the rectangle.
+
+ \sa setTopRight(), moveTopRight(), bottomLeft(), top(), right()
+*/
+
+/*!
+ \fn TQPoint TQRect::bottomLeft() const
+
+ Returns the bottom-left position of the rectangle.
+
+ \sa setBottomLeft(), moveBottomLeft(), topRight(), bottom(), left()
+*/
+
+/*!
+ \fn TQPoint TQRect::center() const
+
+ Returns the center point of the rectangle.
+
+ \sa moveCenter(), topLeft(), bottomRight(), topRight(), bottomLeft()
+*/
+
+
+/*!
+ Extracts the rectangle parameters as the position \a *x, \a *y and
+ width \a *w and height \a *h.
+
+ \sa setRect(), coords()
+*/
+
+void TQRect::rect( int *x, int *y, int *w, int *h ) const
+{
+ *x = x1;
+ *y = y1;
+ *w = x2-x1+1;
+ *h = y2-y1+1;
+}
+
+/*!
+ Extracts the rectangle parameters as the top-left point \a *xp1,
+ \a *yp1 and the bottom-right point \a *xp2, \a *yp2.
+
+ \sa setCoords(), rect()
+*/
+
+void TQRect::coords( int *xp1, int *yp1, int *xp2, int *yp2 ) const
+{
+ *xp1 = x1;
+ *yp1 = y1;
+ *xp2 = x2;
+ *yp2 = y2;
+}
+
+
+/*!
+ Sets the left position of the rectangle to \a pos, leaving the
+ size unchanged.
+
+ \sa left(), setLeft(), moveTop(), moveRight(), moveBottom()
+*/
+void TQRect::moveLeft( int pos )
+{
+ x2 += (TQCOORD)(pos - x1);
+ x1 = (TQCOORD)pos;
+}
+
+/*!
+ Sets the top position of the rectangle to \a pos, leaving the
+ size unchanged.
+
+ \sa top(), setTop(), moveLeft(), moveRight(), moveBottom()
+*/
+
+void TQRect::moveTop( int pos )
+{
+ y2 += (TQCOORD)(pos - y1);
+ y1 = (TQCOORD)pos;
+}
+
+/*!
+ Sets the right position of the rectangle to \a pos, leaving the
+ size unchanged.
+
+ \sa right(), setRight(), moveLeft(), moveTop(), moveBottom()
+*/
+
+void TQRect::moveRight( int pos )
+{
+ x1 += (TQCOORD)(pos - x2);
+ x2 = (TQCOORD)pos;
+}
+
+/*!
+ Sets the bottom position of the rectangle to \a pos, leaving the
+ size unchanged.
+
+ \sa bottom(), setBottom(), moveLeft(), moveTop(), moveRight()
+*/
+
+void TQRect::moveBottom( int pos )
+{
+ y1 += (TQCOORD)(pos - y2);
+ y2 = (TQCOORD)pos;
+}
+
+/*!
+ Sets the top-left position of the rectangle to \a p, leaving the
+ size unchanged.
+
+ \sa topLeft(), setTopLeft(), moveBottomRight(), moveTopRight(), moveBottomLeft()
+*/
+
+void TQRect::moveTopLeft( const TQPoint &p )
+{
+ moveLeft( p.x() );
+ moveTop( p.y() );
+}
+
+/*!
+ Sets the bottom-right position of the rectangle to \a p, leaving
+ the size unchanged.
+
+ \sa bottomRight(), setBottomRight(), moveTopLeft(), moveTopRight(), moveBottomLeft()
+*/
+
+void TQRect::moveBottomRight( const TQPoint &p )
+{
+ moveRight( p.x() );
+ moveBottom( p.y() );
+}
+
+/*!
+ Sets the top-right position of the rectangle to \a p, leaving the
+ size unchanged.
+
+ \sa topRight(), setTopRight(), moveTopLeft(), moveBottomRight(), moveBottomLeft()
+*/
+
+void TQRect::moveTopRight( const TQPoint &p )
+{
+ moveRight( p.x() );
+ moveTop( p.y() );
+}
+
+/*!
+ Sets the bottom-left position of the rectangle to \a p, leaving
+ the size unchanged.
+
+ \sa bottomLeft(), setBottomLeft(), moveTopLeft(), moveBottomRight(), moveTopRight()
+*/
+
+void TQRect::moveBottomLeft( const TQPoint &p )
+{
+ moveLeft( p.x() );
+ moveBottom( p.y() );
+}
+
+
+/*!
+ Sets the center point of the rectangle to \a p, leaving the size
+ unchanged.
+
+ \sa center(), moveTopLeft(), moveBottomRight(), moveTopRight(), moveBottomLeft()
+*/
+
+void TQRect::moveCenter( const TQPoint &p )
+{
+ TQCOORD w = x2 - x1;
+ TQCOORD h = y2 - y1;
+ x1 = (TQCOORD)(p.x() - w/2);
+ y1 = (TQCOORD)(p.y() - h/2);
+ x2 = x1 + w;
+ y2 = y1 + h;
+}
+
+
+/*!
+ Moves the rectangle \a dx along the x axis and \a dy along the y
+ axis, relative to the current position. Positive values move the
+ rectangle to the right and down.
+
+ \sa moveTopLeft()
+*/
+
+void TQRect::moveBy( int dx, int dy )
+{
+ x1 += (TQCOORD)dx;
+ y1 += (TQCOORD)dy;
+ x2 += (TQCOORD)dx;
+ y2 += (TQCOORD)dy;
+}
+
+/*!
+ Sets the coordinates of the rectangle's top-left corner to \a (x,
+ y), and its size to \a (w, h).
+
+ \sa rect(), setCoords()
+*/
+
+void TQRect::setRect( int x, int y, int w, int h )
+{
+ x1 = (TQCOORD)x;
+ y1 = (TQCOORD)y;
+ x2 = (TQCOORD)(x+w-1);
+ y2 = (TQCOORD)(y+h-1);
+}
+
+/*!
+ Sets the coordinates of the rectangle's top-left corner to \a
+ (xp1, yp1), and the coordinates of its bottom-right corner to \a
+ (xp2, yp2).
+
+ \sa coords(), setRect()
+*/
+
+void TQRect::setCoords( int xp1, int yp1, int xp2, int yp2 )
+{
+ x1 = (TQCOORD)xp1;
+ y1 = (TQCOORD)yp1;
+ x2 = (TQCOORD)xp2;
+ y2 = (TQCOORD)yp2;
+}
+
+/*!
+ Adds \a xp1, \a yp1, \a xp2 and \a yp2 respectively to the
+ existing coordinates of the rectangle.
+*/
+
+void TQRect::addCoords( int xp1, int yp1, int xp2, int yp2 )
+{
+ x1 += (TQCOORD)xp1;
+ y1 += (TQCOORD)yp1;
+ x2 += (TQCOORD)xp2;
+ y2 += (TQCOORD)yp2;
+}
+
+/*!
+ \fn TQSize TQRect::size() const
+
+ Returns the size of the rectangle.
+
+ \sa width(), height()
+*/
+
+/*!
+ \fn int TQRect::width() const
+
+ Returns the width of the rectangle. The width includes both the
+ left and right edges, i.e. width = right - left + 1.
+
+ \sa height(), size(), setHeight()
+*/
+
+/*!
+ \fn int TQRect::height() const
+
+ Returns the height of the rectangle. The height includes both the
+ top and bottom edges, i.e. height = bottom - top + 1.
+
+ \sa width(), size(), setHeight()
+*/
+
+/*!
+ Sets the width of the rectangle to \a w. The right edge is
+ changed, but not the left edge.
+
+ \sa width(), setLeft(), setRight(), setSize()
+*/
+
+void TQRect::setWidth( int w )
+{
+ x2 = (TQCOORD)(x1 + w - 1);
+}
+
+/*!
+ Sets the height of the rectangle to \a h. The top edge is not
+ moved, but the bottom edge may be moved.
+
+ \sa height(), setTop(), setBottom(), setSize()
+*/
+
+void TQRect::setHeight( int h )
+{
+ y2 = (TQCOORD)(y1 + h - 1);
+}
+
+/*!
+ Sets the size of the rectangle to \a s. The top-left corner is not
+ moved.
+
+ \sa size(), setWidth(), setHeight()
+*/
+
+void TQRect::setSize( const TQSize &s )
+{
+ x2 = (TQCOORD)(s.width() +x1-1);
+ y2 = (TQCOORD)(s.height()+y1-1);
+}
+
+/*!
+ Returns TRUE if the point \a p is inside or on the edge of the
+ rectangle; otherwise returns FALSE.
+
+ If \a proper is TRUE, this function returns TRUE only if \a p is
+ inside (not on the edge).
+*/
+
+bool TQRect::tqcontains( const TQPoint &p, bool proper ) const
+{
+ if ( proper )
+ return p.x() > x1 && p.x() < x2 &&
+ p.y() > y1 && p.y() < y2;
+ else
+ return p.x() >= x1 && p.x() <= x2 &&
+ p.y() >= y1 && p.y() <= y2;
+}
+
+/*!
+ \overload bool TQRect::tqcontains( int x, int y, bool proper ) const
+
+ Returns TRUE if the point \a x, \a y is inside this rectangle;
+ otherwise returns FALSE.
+
+ If \a proper is TRUE, this function returns TRUE only if the point
+ is entirely inside (not on the edge).
+*/
+
+/*!
+ \overload bool TQRect::tqcontains( int x, int y ) const
+
+ Returns TRUE if the point \a x, \a y is inside this rectangle;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \overload
+
+ Returns TRUE if the rectangle \a r is inside this rectangle;
+ otherwise returns FALSE.
+
+ If \a proper is TRUE, this function returns TRUE only if \a r is
+ entirely inside (not on the edge).
+
+ \sa unite(), intersect(), intersects()
+*/
+
+bool TQRect::tqcontains( const TQRect &r, bool proper ) const
+{
+ if ( proper )
+ return r.x1 > x1 && r.x2 < x2 && r.y1 > y1 && r.y2 < y2;
+ else
+ return r.x1 >= x1 && r.x2 <= x2 && r.y1 >= y1 && r.y2 <= y2;
+}
+
+/*!
+ Unites this rectangle with rectangle \a r.
+*/
+TQRect& TQRect::operator|=(const TQRect &r)
+{
+ *this = *this | r;
+ return *this;
+}
+
+/*!
+ Intersects this rectangle with rectangle \a r.
+*/
+TQRect& TQRect::operator&=(const TQRect &r)
+{
+ *this = *this & r;
+ return *this;
+}
+
+
+/*!
+ Returns the bounding rectangle of this rectangle and rectangle \a
+ r.
+
+ The bounding rectangle of a nonempty rectangle and an empty or
+ invalid rectangle is defined to be the nonempty rectangle.
+
+ \sa operator|=(), operator&(), intersects(), tqcontains()
+*/
+
+TQRect TQRect::operator|(const TQRect &r) const
+{
+ if ( isValid() ) {
+ if ( r.isValid() ) {
+ TQRect tmp;
+ tmp.setLeft( TQMIN( x1, r.x1 ) );
+ tmp.setRight( TQMAX( x2, r.x2 ) );
+ tmp.setTop( TQMIN( y1, r.y1 ) );
+ tmp.setBottom( TQMAX( y2, r.y2 ) );
+ return tmp;
+ } else {
+ return *this;
+ }
+ } else {
+ return r;
+ }
+}
+
+/*!
+ Returns the bounding rectangle of this rectangle and rectangle \a
+ r. \c{r.unite(s)} is equivalent to \c{r|s}.
+*/
+TQRect TQRect::unite( const TQRect &r ) const
+{
+ return *this | r;
+}
+
+
+/*!
+ Returns the intersection of this rectangle and rectangle \a r.
+
+ Returns an empty rectangle if there is no intersection.
+
+ \sa operator&=(), operator|(), isEmpty(), intersects(), tqcontains()
+*/
+
+TQRect TQRect::operator&( const TQRect &r ) const
+{
+ TQRect tmp;
+ tmp.x1 = TQMAX( x1, r.x1 );
+ tmp.x2 = TQMIN( x2, r.x2 );
+ tmp.y1 = TQMAX( y1, r.y1 );
+ tmp.y2 = TQMIN( y2, r.y2 );
+ return tmp;
+}
+
+/*!
+ Returns the intersection of this rectangle and rectangle \a r.
+ \c{r.intersect(s)} is equivalent to \c{r&s}.
+*/
+TQRect TQRect::intersect( const TQRect &r ) const
+{
+ return *this & r;
+}
+
+/*!
+ Returns TRUE if this rectangle intersects with rectangle \a r
+ (there is at least one pixel that is within both rectangles);
+ otherwise returns FALSE.
+
+ \sa intersect(), tqcontains()
+*/
+
+bool TQRect::intersects( const TQRect &r ) const
+{
+ return ( TQMAX( x1, r.x1 ) <= TQMIN( x2, r.x2 ) &&
+ TQMAX( y1, r.y1 ) <= TQMIN( y2, r.y2 ) );
+}
+
+
+/*!
+ \relates TQRect
+
+ Returns TRUE if \a r1 and \a r2 are equal; otherwise returns FALSE.
+*/
+
+bool operator==( const TQRect &r1, const TQRect &r2 )
+{
+ return r1.x1==r2.x1 && r1.x2==r2.x2 && r1.y1==r2.y1 && r1.y2==r2.y2;
+}
+
+/*!
+ \relates TQRect
+
+ Returns TRUE if \a r1 and \a r2 are different; otherwise returns FALSE.
+*/
+
+bool operator!=( const TQRect &r1, const TQRect &r2 )
+{
+ return r1.x1!=r2.x1 || r1.x2!=r2.x2 || r1.y1!=r2.y1 || r1.y2!=r2.y2;
+}
+
+
+/*****************************************************************************
+ TQRect stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQRect
+
+ Writes the TQRect, \a r, to the stream \a s, and returns a
+ reference to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQRect &r )
+{
+ if ( s.version() == 1 )
+ s << (TQ_INT16)r.left() << (TQ_INT16)r.top()
+ << (TQ_INT16)r.right() << (TQ_INT16)r.bottom();
+ else
+ s << (TQ_INT32)r.left() << (TQ_INT32)r.top()
+ << (TQ_INT32)r.right() << (TQ_INT32)r.bottom();
+ return s;
+}
+
+/*!
+ \relates TQRect
+
+ Reads a TQRect from the stream \a s into rect \a r and returns a
+ reference to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQRect &r )
+{
+ if ( s.version() == 1 ) {
+ TQ_INT16 x1, y1, x2, y2;
+ s >> x1; s >> y1; s >> x2; s >> y2;
+ r.setCoords( x1, y1, x2, y2 );
+ }
+ else {
+ TQ_INT32 x1, y1, x2, y2;
+ s >> x1; s >> y1; s >> x2; s >> y2;
+ r.setCoords( x1, y1, x2, y2 );
+ }
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqrect.h b/tqtinterface/qt4/src/kernel/tqrect.h
new file mode 100644
index 0000000..e208978
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqrect.h
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Definition of TQRect class
+**
+** Created : 931028
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQRECT_H
+#define TQRECT_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqsize.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qrect.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+
+class TQ_EXPORT TQRect : public QRect, virtual public TQt
+{
+public:
+ TQRect() : QRect(0, 0, -1, -1) {}
+ TQRect( const TQPoint &topleft, const TQPoint &bottomright ) : QRect(topleft, bottomright) {}
+ TQRect( const TQPoint &topleft, const TQSize &size ) : QRect(topleft, size) {}
+ TQRect( int left, int top, int width, int height ) : QRect(left, top, width, height) {}
+
+ void moveBy( int dx, int dy ) { translate(dx, dy); }
+
+ inline bool tqcontains( const TQPoint &p, bool proper=FALSE ) const { return contains(p, proper); }
+ inline bool tqcontains( int x, int y ) const { return contains(x, y); }
+ inline bool tqcontains( int x, int y, bool proper ) const { return contains(x, y, proper); }
+ inline bool tqcontains( const TQRect &r, bool proper=FALSE ) const { return contains(r, proper); }
+
+ inline void addCoords( int x1, int y1, int x2, int y2 ) { adjust(x1, y1, x2, y2); }
+
+ int &rLeft();
+ int &rTop();
+ int &rRight();
+ int &rBottom();
+
+ void rect( int *x, int *y, int *w, int *h ) const;
+ void coords( int *x1, int *y1, int *x2, int *y2 ) const;
+
+ TQRect normalize() const { return normalized(); }
+
+ // Interoperability
+ TQRect(QRect a) {
+ setLeft(a.left());
+ setTop(a.top());
+ setWidth(a.width());
+ setHeight(a.height());
+ }
+};
+
+#else // USE_QT4
+
+#if defined(topLeft)
+#error "Macro definition of topLeft conflicts with TQRect"
+// don't just silently undo people's defines: #undef topLeft
+#endif
+
+class TQ_EXPORT TQRect // rectangle class
+{
+public:
+ TQRect() { x1 = y1 = 0; x2 = y2 = -1; }
+ TQRect( const TQPoint &topleft, const TQPoint &bottomright );
+ TQRect( const TQPoint &topleft, const TQSize &size );
+ TQRect( int left, int top, int width, int height );
+
+ bool isNull() const;
+ bool isEmpty() const;
+ bool isValid() const;
+ TQRect normalize() const;
+
+ int left() const;
+ int top() const;
+ int right() const;
+ int bottom() const;
+
+ TQCOORD &rLeft();
+ TQCOORD &rTop();
+ TQCOORD &rRight();
+ TQCOORD &rBottom();
+
+ int x() const;
+ int y() const;
+ void setLeft( int pos );
+ void setTop( int pos );
+ void setRight( int pos );
+ void setBottom( int pos );
+ void setX( int x );
+ void setY( int y );
+
+ void setTopLeft( const TQPoint &p );
+ void setBottomRight( const TQPoint &p );
+ void setTopRight( const TQPoint &p );
+ void setBottomLeft( const TQPoint &p );
+
+ TQPoint topLeft() const;
+ TQPoint bottomRight() const;
+ TQPoint topRight() const;
+ TQPoint bottomLeft() const;
+ TQPoint center() const;
+
+ void rect( int *x, int *y, int *w, int *h ) const;
+ void coords( int *x1, int *y1, int *x2, int *y2 ) const;
+
+ void moveLeft( int pos );
+ void moveTop( int pos );
+ void moveRight( int pos );
+ void moveBottom( int pos );
+ void moveTopLeft( const TQPoint &p );
+ void moveBottomRight( const TQPoint &p );
+ void moveTopRight( const TQPoint &p );
+ void moveBottomLeft( const TQPoint &p );
+ void moveCenter( const TQPoint &p );
+ void moveBy( int dx, int dy );
+
+ void setRect( int x, int y, int w, int h );
+ void setCoords( int x1, int y1, int x2, int y2 );
+ void addCoords( int x1, int y1, int x2, int y2 );
+
+ TQSize size() const;
+ int width() const;
+ int height() const;
+ void setWidth( int w );
+ void setHeight( int h );
+ void setSize( const TQSize &s );
+
+ TQRect operator|(const TQRect &r) const;
+ TQRect operator&(const TQRect &r) const;
+ TQRect& operator|=(const TQRect &r);
+ TQRect& operator&=(const TQRect &r);
+
+ bool tqcontains( const TQPoint &p, bool proper=FALSE ) const;
+ bool tqcontains( int x, int y ) const; // inline methods, _don't_ merge these
+ bool tqcontains( int x, int y, bool proper ) const;
+ bool tqcontains( const TQRect &r, bool proper=FALSE ) const;
+ TQRect unite( const TQRect &r ) const;
+ TQRect intersect( const TQRect &r ) const;
+ bool intersects( const TQRect &r ) const;
+
+ friend TQ_EXPORT bool operator==( const TQRect &, const TQRect & );
+ friend TQ_EXPORT bool operator!=( const TQRect &, const TQRect & );
+
+private:
+#if defined(TQ_WS_X11) || defined(TQ_OS_TEMP)
+ friend void qt_setCoords( TQRect *r, int xp1, int yp1, int xp2, int yp2 );
+#endif
+#if defined(TQ_OS_MAC)
+ TQCOORD y1;
+ TQCOORD x1;
+ TQCOORD y2;
+ TQCOORD x2;
+#else
+ TQCOORD x1;
+ TQCOORD y1;
+ TQCOORD x2;
+ TQCOORD y2;
+#endif
+};
+
+TQ_EXPORT bool operator==( const TQRect &, const TQRect & );
+TQ_EXPORT bool operator!=( const TQRect &, const TQRect & );
+
+
+/*****************************************************************************
+ TQRect stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQRect & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQRect & );
+#endif
+
+/*****************************************************************************
+ TQRect inline member functions
+ *****************************************************************************/
+
+inline TQRect::TQRect( int left, int top, int width, int height )
+{
+ x1 = (TQCOORD)left;
+ y1 = (TQCOORD)top;
+ x2 = (TQCOORD)(left+width-1);
+ y2 = (TQCOORD)(top+height-1);
+}
+
+inline bool TQRect::isNull() const
+{ return x2 == x1-1 && y2 == y1-1; }
+
+inline bool TQRect::isEmpty() const
+{ return x1 > x2 || y1 > y2; }
+
+inline bool TQRect::isValid() const
+{ return x1 <= x2 && y1 <= y2; }
+
+inline int TQRect::left() const
+{ return x1; }
+
+inline int TQRect::top() const
+{ return y1; }
+
+inline int TQRect::right() const
+{ return x2; }
+
+inline int TQRect::bottom() const
+{ return y2; }
+
+inline TQCOORD &TQRect::rLeft()
+{ return x1; }
+
+inline TQCOORD & TQRect::rTop()
+{ return y1; }
+
+inline TQCOORD & TQRect::rRight()
+{ return x2; }
+
+inline TQCOORD & TQRect::rBottom()
+{ return y2; }
+
+inline int TQRect::x() const
+{ return x1; }
+
+inline int TQRect::y() const
+{ return y1; }
+
+inline void TQRect::setLeft( int pos )
+{ x1 = (TQCOORD)pos; }
+
+inline void TQRect::setTop( int pos )
+{ y1 = (TQCOORD)pos; }
+
+inline void TQRect::setRight( int pos )
+{ x2 = (TQCOORD)pos; }
+
+inline void TQRect::setBottom( int pos )
+{ y2 = (TQCOORD)pos; }
+
+inline void TQRect::setX( int x )
+{ x1 = (TQCOORD)x; }
+
+inline void TQRect::setY( int y )
+{ y1 = (TQCOORD)y; }
+
+inline TQPoint TQRect::topLeft() const
+{ return TQPoint(x1, y1); }
+
+inline TQPoint TQRect::bottomRight() const
+{ return TQPoint(x2, y2); }
+
+inline TQPoint TQRect::topRight() const
+{ return TQPoint(x2, y1); }
+
+inline TQPoint TQRect::bottomLeft() const
+{ return TQPoint(x1, y2); }
+
+inline TQPoint TQRect::center() const
+{ return TQPoint((x1+x2)/2, (y1+y2)/2); }
+
+inline int TQRect::width() const
+{ return x2 - x1 + 1; }
+
+inline int TQRect::height() const
+{ return y2 - y1 + 1; }
+
+inline TQSize TQRect::size() const
+{ return TQSize(x2-x1+1, y2-y1+1); }
+
+inline bool TQRect::tqcontains( int x, int y, bool proper ) const
+{
+ if ( proper )
+ return x > x1 && x < x2 &&
+ y > y1 && y < y2;
+ else
+ return x >= x1 && x <= x2 &&
+ y >= y1 && y <= y2;
+}
+
+inline bool TQRect::tqcontains( int x, int y ) const
+{
+ return x >= x1 && x <= x2 &&
+ y >= y1 && y <= y2;
+}
+
+#endif // USE_QT4
+
+#define TQ_DEFINED_TQRECT
+#include "tqwinexport.h"
+#endif // TQRECT_H
diff --git a/tqtinterface/qt4/src/kernel/tqregion.cpp b/tqtinterface/qt4/src/kernel/tqregion.cpp
new file mode 100644
index 0000000..58bf4eb
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqregion.cpp
@@ -0,0 +1,398 @@
+/****************************************************************************
+**
+** Implementation of TQRegion class
+**
+** Created : 950726
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqregion.h"
+#include "tqpointarray.h"
+#include "tqbuffer.h"
+#include "tqdatastream.h"
+
+#ifdef USE_QT4
+
+/*!
+ Use the constructor tha takes a Qt::FillRule as the second
+ argument instead.
+*/
+TQRegion::TQRegion(const QPolygon &pa, bool winding)
+{
+ new (this) QRegion(pa, winding ? Qt::WindingFill : Qt::OddEvenFill);
+}
+
+#else // USE_QT4
+
+// BEING REVISED: paul
+/*!
+ \class TQRegion tqregion.h
+ \brief The TQRegion class specifies a clip region for a painter.
+
+ \ingroup images
+ \ingroup graphics
+
+ TQRegion is used with TQPainter::setClipRegion() to limit the paint
+ area to what needs to be painted. There is also a
+ TQWidget::tqrepaint() that takes a TQRegion parameter. TQRegion is the
+ best tool for reducing flicker.
+
+ A region can be created from a rectangle, an ellipse, a polygon or
+ a bitmap. Complex regions may be created by combining simple
+ regions using unite(), intersect(), subtract() or eor() (exclusive
+ or). You can move a region using translate().
+
+ You can test whether a region isNull(), isEmpty() or if it
+ tqcontains() a TQPoint or TQRect. The bounding rectangle is given by
+ boundingRect().
+
+ The function rects() gives a decomposition of the region into
+ rectangles.
+
+ Example of using complex regions:
+ \code
+ void MyWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPainter p; // our painter
+ TQRegion r1( TQRect(100,100,200,80), // r1 = elliptic region
+ TQRegion::Ellipse );
+ TQRegion r2( TQRect(100,120,90,30) ); // r2 = rectangular region
+ TQRegion r3 = r1.intersect( r2 ); // r3 = intersection
+ p.begin( this ); // start painting widget
+ p.setClipRegion( r3 ); // set clip region
+ ... // paint clipped graphics
+ p.end(); // painting done
+ }
+ \endcode
+
+ TQRegion is an \link shclass.html implicitly shared\endlink class.
+
+ \warning Due to window system limitations, the whole coordinate
+ space for a region is limited to the points between -32767 and
+ 32767 on Mac OS X and Windows 95/98/ME.
+
+ \sa TQPainter::setClipRegion(), TQPainter::setClipRect()
+*/
+
+
+/*!
+ \enum TQRegion::RegionType
+
+ Specifies the tqshape of the region to be created.
+
+ \value Rectangle the region covers the entire rectangle.
+ \value Ellipse the region is an ellipse inside the rectangle.
+*/
+
+/*!
+ \fn Region TQRegion::handle() const
+
+ Returns the region's handle.
+*/
+
+/*****************************************************************************
+ TQRegion member functions
+ *****************************************************************************/
+
+/*!
+ Constructs a rectangular or elliptic region.
+
+ If \a t is \c Rectangle, the region is the filled rectangle (\a x,
+ \a y, \a w, \a h). If \a t is \c Ellipse, the region is the filled
+ ellipse with center at (\a x + \a w / 2, \a y + \a h / 2) and size
+ (\a w ,\a h ).
+*/
+TQRegion::TQRegion( int x, int y, int w, int h, RegionType t )
+{
+ TQRegion tmp(TQRect(x,y,w,h),t);
+ tmp.data->ref();
+ data = tmp.data;
+}
+
+/*!
+ Detaches from shared region data to make sure that this region is
+ the only one referring to the data.
+
+ \sa copy(), \link shclass.html shared classes\endlink
+*/
+
+void TQRegion::detach()
+{
+ if ( data->count != 1 )
+ *this = copy();
+}
+
+#ifndef TQT_NO_DATASTREAM
+/*
+ Executes region commands in the internal buffer and rebuilds the
+ original region.
+
+ We do this when we read a region from the data stream.
+
+ If \a ver is non-0, uses the format version \a ver on reading the
+ byte array.
+*/
+
+void TQRegion::exec( const TQByteArray &buffer, int ver )
+{
+ TQBuffer buf( buffer );
+ TQDataStream s( &buf );
+ if ( ver )
+ s.setVersion( ver );
+ buf.open( IO_ReadOnly );
+ TQRegion rgn;
+#if defined(TQT_CHECK_STATE)
+ int test_cnt = 0;
+#endif
+ while ( !s.eof() ) {
+ TQ_INT32 id;
+ if ( s.version() == 1 ) {
+ int id_int;
+ s >> id_int;
+ id = id_int;
+ } else {
+ s >> id;
+ }
+#if defined(TQT_CHECK_STATE)
+ if ( test_cnt > 0 && id != TQRGN_TRANSLATE )
+ qWarning( "TQRegion::exec: Internal error" );
+ test_cnt++;
+#endif
+ if ( id == TQRGN_SETRECT || id == TQRGN_SETELLIPSE ) {
+ TQRect r;
+ s >> r;
+ rgn = TQRegion( r, id == TQRGN_SETRECT ? Rectangle : Ellipse );
+ } else if ( id == TQRGN_SETPTARRAY_ALT || id == TQRGN_SETPTARRAY_WIND ) {
+ TQPointArray a;
+ s >> a;
+ rgn = TQRegion( a, id == TQRGN_SETPTARRAY_WIND );
+ } else if ( id == TQRGN_TRANSLATE ) {
+ TQPoint p;
+ s >> p;
+ rgn.translate( p.x(), p.y() );
+ } else if ( id >= TQRGN_OR && id <= TQRGN_XOR ) {
+ TQByteArray bop1, bop2;
+ TQRegion r1, r2;
+ s >> bop1; r1.exec( bop1 );
+ s >> bop2; r2.exec( bop2 );
+ switch ( id ) {
+ case TQRGN_OR:
+ rgn = r1.unite( r2 );
+ break;
+ case TQRGN_AND:
+ rgn = r1.intersect( r2 );
+ break;
+ case TQRGN_SUB:
+ rgn = r1.subtract( r2 );
+ break;
+ case TQRGN_XOR:
+ rgn = r1.eor( r2 );
+ break;
+ }
+ } else if ( id == TQRGN_RECTS ) {
+ // (This is the only form used in TQt 2.0)
+ TQ_UINT32 n;
+ s >> n;
+ TQRect r;
+ for ( int i=0; i<(int)n; i++ ) {
+ s >> r;
+ rgn = rgn.unite( TQRegion(r) );
+ }
+ }
+ }
+ buf.close();
+ *this = rgn;
+}
+
+
+/*****************************************************************************
+ TQRegion stream functions
+ *****************************************************************************/
+
+/*!
+ \relates TQRegion
+
+ Writes the region \a r to the stream \a s and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQRegion &r )
+{
+ TQMemArray<TQRect> a = r.rects();
+ if ( a.isEmpty() ) {
+ s << (TQ_UINT32)0;
+ } else {
+ if ( s.version() == 1 ) {
+ int i;
+ for ( i=(int)a.size()-1; i>0; i-- ) {
+ s << (TQ_UINT32)(12+i*24);
+ s << (int)TQRGN_OR;
+ }
+ for ( i=0; i<(int)a.size(); i++ ) {
+ s << (TQ_UINT32)(4+8) << (int)TQRGN_SETRECT << a[i];
+ }
+ }
+ else {
+ s << (TQ_UINT32)(4+4+16*a.size()); // 16: storage size of TQRect
+ s << (TQ_INT32)TQRGN_RECTS;
+ s << (TQ_UINT32)a.size();
+ for ( int i=0; i<(int)a.size(); i++ )
+ s << a[i];
+ }
+ }
+ return s;
+}
+
+/*!
+ \relates TQRegion
+
+ Reads a region from the stream \a s into \a r and returns a
+ reference to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQRegion &r )
+{
+ TQByteArray b;
+ s >> b;
+ r.exec( b, s.version() );
+ return s;
+}
+#endif //TQT_NO_DATASTREAM
+
+// These are not inline - they can be implemented better on some platforms
+// (eg. Windows at least provides 3-variable operations). For now, simple.
+
+
+/*!
+ Applies the unite() function to this region and \a r. \c r1|r2 is
+ equivalent to \c r1.unite(r2)
+
+ \sa unite(), operator+()
+*/
+const TQRegion TQRegion::operator|( const TQRegion &r ) const
+ { return unite(r); }
+
+/*!
+ Applies the unite() function to this region and \a r. \c r1+r2 is
+ equivalent to \c r1.unite(r2)
+
+ \sa unite(), operator|()
+*/
+const TQRegion TQRegion::operator+( const TQRegion &r ) const
+ { return unite(r); }
+
+/*!
+ Applies the intersect() function to this region and \a r. \c r1&r2
+ is equivalent to \c r1.intersect(r2)
+
+ \sa intersect()
+*/
+const TQRegion TQRegion::operator&( const TQRegion &r ) const
+ { return intersect(r); }
+
+/*!
+ Applies the subtract() function to this region and \a r. \c r1-r2
+ is equivalent to \c r1.subtract(r2)
+
+ \sa subtract()
+*/
+const TQRegion TQRegion::operator-( const TQRegion &r ) const
+ { return subtract(r); }
+
+/*!
+ Applies the eor() function to this region and \a r. \c r1^r2 is
+ equivalent to \c r1.eor(r2)
+
+ \sa eor()
+*/
+const TQRegion TQRegion::operator^( const TQRegion &r ) const
+ { return eor(r); }
+
+/*!
+ Applies the unite() function to this region and \a r and assigns
+ the result to this region. \c r1|=r2 is equivalent to \c
+ r1=r1.unite(r2)
+
+ \sa unite()
+*/
+TQRegion& TQRegion::operator|=( const TQRegion &r )
+ { return *this = *this | r; }
+
+/*!
+ Applies the unite() function to this region and \a r and assigns
+ the result to this region. \c r1+=r2 is equivalent to \c
+ r1=r1.unite(r2)
+
+ \sa intersect()
+*/
+TQRegion& TQRegion::operator+=( const TQRegion &r )
+ { return *this = *this + r; }
+
+/*!
+ Applies the intersect() function to this region and \a r and
+ assigns the result to this region. \c r1&=r2 is equivalent to \c
+ r1=r1.intersect(r2)
+
+ \sa intersect()
+*/
+TQRegion& TQRegion::operator&=( const TQRegion &r )
+ { return *this = *this & r; }
+
+/*!
+ Applies the subtract() function to this region and \a r and
+ assigns the result to this region. \c r1-=r2 is equivalent to \c
+ r1=r1.subtract(r2)
+
+ \sa subtract()
+*/
+TQRegion& TQRegion::operator-=( const TQRegion &r )
+ { return *this = *this - r; }
+
+/*!
+ Applies the eor() function to this region and \a r and
+ assigns the result to this region. \c r1^=r2 is equivalent to \c
+ r1=r1.eor(r2)
+
+ \sa eor()
+*/
+TQRegion& TQRegion::operator^=( const TQRegion &r )
+ { return *this = *this ^ r; }
+
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqregion.h b/tqtinterface/qt4/src/kernel/tqregion.h
new file mode 100644
index 0000000..179d33d
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqregion.h
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Definition of TQRegion class
+**
+** Created : 940514
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQREGION_H
+#define TQREGION_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqshared.h"
+#include "tqrect.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include "tqpointarray.h"
+#include <Qt/qregion.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQRegion : public QRegion, virtual public TQt
+{
+public:
+ TQRegion() : QRegion() {}
+ TQRegion( int x, int y, int w, int h, RegionType rt = Rectangle ) : QRegion( x, y, w, h, rt ) {}
+ TQRegion( const QRect &qr, RegionType rt = Rectangle ) : QRegion( qr, rt ) {}
+// TQRegion( const TQPointArray &qpa, bool winding=FALSE ) : QRegion( qpa, winding ) {}
+ TQRegion(const QPolygon &pa, bool winding);
+ TQRegion( const QRegion &qr ) : QRegion( qr ) {}
+ TQRegion( const QBitmap &qb ) : QRegion( qb ) {}
+
+ inline bool isNull() const { return isEmpty(); }
+
+ inline bool tqcontains( const QPoint &p ) const { return contains(p); }
+ inline bool tqcontains( const QRect &r ) const { return contains(r); }
+
+ inline TQMemArray<TQRect> tqrects() const {
+ QVector<QRect> qvr = rects();
+ TQMemArray<TQRect> tqma(qvr.size());
+
+ for (int i = 0; i < qvr.size(); i++) {
+ TQRect tr = qvr.at(i);
+ memcpy (&(tqma[i]), &tr, sizeof tqma[i]); // If this is not done we get a crash, because the assignment operator (=) expects the left hand argument to be a valid TQRect object (which it is not)
+ }
+ return tqma;
+ }
+
+ // Interoperability
+ static const TQRegion& convertFromQRegion( QRegion& qr );
+};
+
+// Interoperability
+inline static const TQRegion& convertFromQRegion( const QRegion& qr ) {
+ return (*static_cast<const TQRegion*>(&qr));
+}
+
+#else // USE_QT4
+
+#ifdef TQ_WS_X11
+struct TQRegionPrivate;
+#endif
+
+class TQ_EXPORT TQRegion
+{
+public:
+ enum RegionType { Rectangle, Ellipse };
+
+ TQRegion();
+ TQRegion( int x, int y, int w, int h, RegionType = Rectangle );
+ TQRegion( const TQRect &, RegionType = Rectangle );
+ TQRegion( const TQPointArray &, bool winding=FALSE );
+ TQRegion( const TQRegion & );
+ TQRegion( const TQBitmap & );
+ ~TQRegion();
+ TQRegion &operator=( const TQRegion & );
+
+ bool isNull() const;
+ bool isEmpty() const;
+
+ bool tqcontains( const TQPoint &p ) const;
+ bool tqcontains( const TQRect &r ) const;
+
+ void translate( int dx, int dy );
+
+ TQRegion unite( const TQRegion & ) const;
+ TQRegion intersect( const TQRegion &) const;
+ TQRegion subtract( const TQRegion & ) const;
+ TQRegion eor( const TQRegion & ) const;
+
+ TQRect boundingRect() const;
+ TQMemArray<TQRect> rects() const;
+ void setRects( const TQRect *, int );
+
+ const TQRegion operator|( const TQRegion & ) const;
+ const TQRegion operator+( const TQRegion & ) const;
+ const TQRegion operator&( const TQRegion & ) const;
+ const TQRegion operator-( const TQRegion & ) const;
+ const TQRegion operator^( const TQRegion & ) const;
+ TQRegion& operator|=( const TQRegion & );
+ TQRegion& operator+=( const TQRegion & );
+ TQRegion& operator&=( const TQRegion & );
+ TQRegion& operator-=( const TQRegion & );
+ TQRegion& operator^=( const TQRegion & );
+
+ bool operator==( const TQRegion & ) const;
+ bool operator!=( const TQRegion &r ) const
+ { return !(operator==(r)); }
+
+#if defined(TQ_WS_WIN)
+ HRGN handle() const { return data->rgn; }
+#elif defined(TQ_WS_X11)
+ Region handle() const { if(!data->rgn) updateX11Region(); return data->rgn; }
+#elif defined(TQ_WS_MAC)
+ RgnHandle handle(bool require_rgn=FALSE) const;
+#elif defined(TQ_WS_TQWS)
+ // TQGfx_TQWS needs this for region drawing
+ void * handle() const { return data->rgn; }
+#endif
+
+#ifndef TQT_NO_DATASTREAM
+ friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQRegion & );
+ friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQRegion & );
+#endif
+private:
+ TQRegion( bool );
+ TQRegion copy() const;
+ void detach();
+#if defined(TQ_WS_WIN)
+ TQRegion winCombine( const TQRegion &, int ) const;
+#endif
+#if defined(TQ_WS_X11)
+ void updateX11Region() const;
+ void *clipRectangles( int &num ) const;
+ friend void *qt_getClipRects( const TQRegion &, int & );
+#endif
+ void exec( const TQByteArray &, int ver = 0 );
+ struct TQRegionData : public TQShared {
+#if defined(TQ_WS_WIN)
+ HRGN rgn;
+#elif defined(TQ_WS_X11)
+ Region rgn;
+ void *xrectangles;
+ TQRegionPrivate *region;
+#elif defined(TQ_WS_MAC)
+ uint is_rect:1;
+ TQRect rect;
+ RgnHandle rgn;
+#elif defined(TQ_WS_TQWS)
+ void * rgn;
+#endif
+ bool is_null;
+ } *data;
+#if defined(TQ_WS_MAC)
+ friend struct qt_mac_rgn_data_cache;
+ friend TQRegionData *qt_mac_get_rgn_data();
+ friend void qt_mac_free_rgn_data(TQRegionData *);
+ void rectifyRegion();
+#elif defined(TQ_WS_WIN)
+ friend class TQETWidget;
+#endif
+
+};
+
+
+#define TQRGN_SETRECT 1 // region stream commands
+#define TQRGN_SETELLIPSE 2 // (these are internal)
+#define TQRGN_SETPTARRAY_ALT 3
+#define TQRGN_SETPTARRAY_WIND 4
+#define TQRGN_TRANSLATE 5
+#define TQRGN_OR 6
+#define TQRGN_AND 7
+#define TQRGN_SUB 8
+#define TQRGN_XOR 9
+#define TQRGN_RECTS 10
+
+
+/*****************************************************************************
+ TQRegion stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQRegion & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQRegion & );
+#endif
+
+#endif // USE_QT4
+
+#endif // TQREGION_H
diff --git a/tqtinterface/qt4/src/kernel/tqregion_x11.cpp b/tqtinterface/qt4/src/kernel/tqregion_x11.cpp
new file mode 100644
index 0000000..4e573c9
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqregion_x11.cpp
@@ -0,0 +1,2908 @@
+/****************************************************************************
+**
+** Implementation of TQRegion class for X11
+**
+** Created : 940729
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqregion.h"
+#include "tqpointarray.h"
+#include "tqbuffer.h"
+#include "tqimage.h"
+#include "tqbitmap.h"
+#include "tqt_x11_p.h"
+
+#include <stdlib.h>
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+// inline TQRect::setCoords
+inline void qt_setCoords( TQRect *r, int xp1, int yp1, int xp2, int yp2 )
+{
+#ifdef USE_QT4
+ r->setCoords((TQCOORD)xp1, (TQCOORD)yp1, (TQCOORD)xp2, (TQCOORD)yp2);
+#else // USE_QT4
+ r->x1 = (TQCOORD)xp1;
+ r->y1 = (TQCOORD)yp1;
+ r->x2 = (TQCOORD)xp2;
+ r->y2 = (TQCOORD)yp2;
+#endif // USE_QT4
+}
+
+/*
+ * clip region
+ */
+
+struct TQRegionPrivate {
+ int numRects;
+ TQMemArray<TQRect> rects;
+ TQRect extents;
+
+ TQRegionPrivate() { numRects = 0; }
+ TQRegionPrivate( const TQRect &r ) : rects(1) {
+ numRects = 1;
+ rects[0] = r;
+ extents = r;
+ }
+
+ TQRegionPrivate( const TQRegionPrivate &r ) {
+ rects = r.rects.copy();
+ numRects = r.numRects;
+ extents = r.extents;
+ }
+
+ TQRegionPrivate &operator=( const TQRegionPrivate &r ) {
+ rects = r.rects.copy();
+ numRects = r.numRects;
+ extents = r.extents;
+ return *this;
+ }
+
+};
+
+
+static void UnionRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, TQRegionPrivate *newReg);
+static void IntersectRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, register TQRegionPrivate *newReg);
+static void miRegionOp(register TQRegionPrivate *newReg, TQRegionPrivate *reg1, TQRegionPrivate *reg2,
+ void (*overlapFunc)(...),
+ void (*nonOverlap1Func)(...),
+ void (*nonOverlap2Func)(...));
+#define RectangleOut 0
+#define RectangleIn 1
+#define RectanglePart 2
+#define EvenOddRule 0
+#define WindingRule 1
+
+// START OF region.h extract
+/* $XConsortium: region.h,v 11.14 94/04/17 20:22:20 rws Exp $ */
+/************************************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSETQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+
+#ifndef _XREGION_H
+#define _XREGION_H
+
+#include <limits.h>
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+
+/* 1 if two BOXs overlap.
+ * 0 if two BOXs do not overlap.
+ * Remember, x2 and y2 are not in the region
+ */
+#define EXTENTCHECK(r1, r2) \
+ ((r1)->right() >= (r2)->left() && \
+ (r1)->left() <= (r2)->right() && \
+ (r1)->bottom() >= (r2)->top() && \
+ (r1)->top() <= (r2)->bottom())
+
+/*
+ * update region extents
+ */
+#define EXTENTS(r,idRect){\
+ if((r)->left() < (idRect)->extents.left())\
+ (idRect)->extents.setLeft( (r)->left() );\
+ if((r)->top() < (idRect)->extents.top())\
+ (idRect)->extents.setTop( (r)->top() );\
+ if((r)->right() > (idRect)->extents.right())\
+ (idRect)->extents.setRight( (r)->right() );\
+ if((r)->bottom() > (idRect)->extents.bottom())\
+ (idRect)->extents.setBottom( (r)->bottom() );\
+ }
+
+/*
+ * Check to see if there is enough memory in the present region.
+ */
+#define MEMCHECK(reg, rect, firstrect){\
+ if ((reg)->numRects >= (int)((reg)->rects.size()-1)){\
+ firstrect.resize(firstrect.size() * 2); \
+ (rect) = (firstrect).data() + (reg)->numRects;\
+ }\
+ }
+
+
+#define EMPTY_REGION(pReg) pReg->numRects = 0
+
+#define REGION_NOT_EMPTY(pReg) pReg->numRects
+
+/*
+ * number of points to buffer before sending them off
+ * to scanlines() : Must be an even number
+ */
+#define NUMPTSTOBUFFER 200
+
+/*
+ * used to allocate buffers for points and link
+ * the buffers together
+ */
+typedef struct _POINTBLOCK {
+ TQPoint pts[NUMPTSTOBUFFER];
+ struct _POINTBLOCK *next;
+} POINTBLOCK;
+
+#endif
+// END OF region.h extract
+
+// START OF Region.c extract
+/* $XConsortium: Region.c /main/30 1996/10/22 14:21:24 kaleb $ */
+/************************************************************************
+
+Copyright (c) 1987, 1988 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSETQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+/*
+ * The functions in this file implement the Region abstraction, similar to one
+ * used in the X11 sample server. A Region is simply an area, as the name
+ * implies, and is implemented as a "y-x-banded" array of rectangles. To
+ * explain: Each Region is made up of a certain number of rectangles sorted
+ * by y coordinate first, and then by x coordinate.
+ *
+ * Furthermore, the rectangles are banded such that every rectangle with a
+ * given upper-left y coordinate (y1) will have the same lower-right y
+ * coordinate (y2) and vice versa. If a rectangle has scanlines in a band, it
+ * will span the entire vertical distance of the band. This means that some
+ * areas that could be merged into a taller rectangle will be represented as
+ * several shorter rectangles to account for shorter rectangles to its left
+ * or right but within its "vertical scope".
+ *
+ * An added constraint on the rectangles is that they must cover as much
+ * horizontal area as possible. E.g. no two rectangles in a band are allowed
+ * to touch.
+ *
+ * Whenever possible, bands will be merged together to cover a greater vertical
+ * distance (and thus reduce the number of rectangles). Two bands can be merged
+ * only if the bottom of one touches the top of the other and they have
+ * rectangles in the same places (of the same width, of course). This maintains
+ * the y-x-banding that's so nice to have...
+ */
+/* $XFree86: xc/lib/X11/Region.c,v 1.1.1.2.2.2 1998/10/04 15:22:50 hohndel Exp $ */
+
+typedef void (*voidProcp)(...);
+
+
+static
+void UnionRectWithRegion(register const TQRect *rect, TQRegionPrivate *source, TQRegionPrivate *dest)
+{
+ TQRegionPrivate region;
+
+ if (!rect->width() || !rect->height())
+ return;
+ region.rects.resize(1);
+ region.numRects = 1;
+ region.rects[0] = *rect;
+ region.extents = *rect;
+
+ UnionRegion(&region, source, dest);
+ return;
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miSetExtents --
+ * Reset the extents of a region to what they should be. Called by
+ * miSubtract and miIntersect b/c they can't figure it out along the
+ * way or do so easily, as miUnion can.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The region's 'extents' structure is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+static void
+miSetExtents (TQRegionPrivate *pReg)
+{
+ register TQRect *pBox,
+ *pBoxEnd,
+ *pExtents;
+
+ if (pReg->numRects == 0)
+ {
+ qt_setCoords(&pReg->extents, 0, 0, 0, 0);
+ return;
+ }
+
+ pExtents = &pReg->extents;
+ pBox = pReg->rects.data();
+ pBoxEnd = &pBox[pReg->numRects - 1];
+
+ /*
+ * Since pBox is the first rectangle in the region, it must have the
+ * smallest y1 and since pBoxEnd is the last rectangle in the region,
+ * it must have the largest y2, because of banding. Initialize x1 and
+ * x2 from pBox and pBoxEnd, resp., as good things to initialize them
+ * to...
+ */
+ pExtents->setLeft( pBox->left() );
+ pExtents->setTop( pBox->top() );
+ pExtents->setRight( pBoxEnd->right() );
+ pExtents->setBottom( pBoxEnd->bottom() );
+
+ TQ_ASSERT(pExtents->top() <= pExtents->bottom());
+ while (pBox <= pBoxEnd)
+ {
+ if (pBox->left() < pExtents->left())
+ {
+ pExtents->setLeft( pBox->left() );
+ }
+ if (pBox->right() > pExtents->right())
+ {
+ pExtents->setRight( pBox->right() );
+ }
+ pBox++;
+ }
+ TQ_ASSERT(pExtents->left() <= pExtents->right());
+}
+
+
+/* TranslateRegion(pRegion, x, y)
+ translates in place
+ added by raymond
+*/
+
+static
+int
+OffsetRegion(register TQRegionPrivate *pRegion, register int x, register int y)
+{
+ register int nbox;
+ register TQRect *pbox;
+
+ pbox = pRegion->rects.data();
+ nbox = pRegion->numRects;
+
+ while(nbox--)
+ {
+ pbox->moveBy(x, y);
+ pbox++;
+ }
+ pRegion->extents.moveBy(x, y);
+ return 1;
+}
+
+/*======================================================================
+ * Region Intersection
+ *====================================================================*/
+/*-
+ *-----------------------------------------------------------------------
+ * miIntersectO --
+ * Handle an overlapping band for miIntersect.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Rectangles may be added to the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static void*/
+static
+int
+miIntersectO (register TQRegionPrivate *pReg, register TQRect *r1, TQRect *r1End,
+ register TQRect *r2, TQRect *r2End, int y1, int y2)
+{
+ register int x1;
+ register int x2;
+ register TQRect *pNextRect;
+
+ pNextRect = pReg->rects.data() + pReg->numRects;
+
+ while ((r1 != r1End) && (r2 != r2End))
+ {
+ x1 = TQMAX(r1->left(),r2->left());
+ x2 = TQMIN(r1->right(),r2->right());
+
+ /*
+ * If there's any overlap between the two rectangles, add that
+ * overlap to the new region.
+ * There's no need to check for subsumption because the only way
+ * such a need could arise is if some region has two rectangles
+ * right next to each other. Since that should never happen...
+ */
+ if (x1 <= x2)
+ {
+ TQ_ASSERT(y1<=y2);
+
+ MEMCHECK(pReg, pNextRect, pReg->rects)
+ qt_setCoords( pNextRect, x1, y1, x2, y2 );
+ pReg->numRects++;
+ pNextRect++;
+ }
+
+ /*
+ * Need to advance the pointers. Shift the one that extends
+ * to the right the least, since the other still has a chance to
+ * overlap with that region's next rectangle, if you see what I mean.
+ */
+ if (r1->right() < r2->right())
+ {
+ r1++;
+ }
+ else if (r2->right() < r1->right())
+ {
+ r2++;
+ }
+ else
+ {
+ r1++;
+ r2++;
+ }
+ }
+ return 0; /* lint */
+}
+
+static
+void
+IntersectRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, register TQRegionPrivate *newReg)
+{
+ /* check for trivial reject */
+ if ( (!(reg1->numRects)) || (!(reg2->numRects)) ||
+ (!EXTENTCHECK(&reg1->extents, &reg2->extents)))
+ newReg->numRects = 0;
+ else
+ miRegionOp (newReg, reg1, reg2,
+ (voidProcp) miIntersectO, (voidProcp) NULL, (voidProcp) NULL);
+
+ /*
+ * Can't alter newReg's extents before we call miRegionOp because
+ * it might be one of the source regions and miRegionOp depends
+ * on the extents of those regions being the same. Besides, this
+ * way there's no checking against rectangles that will be nuked
+ * due to coalescing, so we have to examine fewer rectangles.
+ */
+ miSetExtents(newReg);
+ return;
+}
+
+/*======================================================================
+ * Generic Region Operator
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * miCoalesce --
+ * Attempt to merge the boxes in the current band with those in the
+ * previous one. Used only by miRegionOp.
+ *
+ * Results:
+ * The new index for the previous band.
+ *
+ * Side Effects:
+ * If coalescing takes place:
+ * - rectangles in the previous band will have their y2 fields
+ * altered.
+ * - pReg->numRects will be decreased.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static int*/
+static
+int
+miCoalesce (register TQRegionPrivate *pReg, int prevStart, int curStart)
+ //Region pReg; /* Region to coalesce */
+ //prevStart; /* Index of start of previous band */
+ //curStart; /* Index of start of current band */
+{
+ register TQRect *pPrevBox; /* Current box in previous band */
+ register TQRect *pCurBox; /* Current box in current band */
+ register TQRect *pRegEnd; /* End of region */
+ int curNumRects; /* Number of rectangles in current
+ * band */
+ int prevNumRects; /* Number of rectangles in previous
+ * band */
+ int bandY1; /* Y1 coordinate for current band */
+
+ pRegEnd = pReg->rects.data() + pReg->numRects;
+
+ pPrevBox = pReg->rects.data() + prevStart;
+ prevNumRects = curStart - prevStart;
+
+ /*
+ * Figure out how many rectangles are in the current band. Have to do
+ * this because multiple bands could have been added in miRegionOp
+ * at the end when one region has been exhausted.
+ */
+ pCurBox = pReg->rects.data() + curStart;
+ bandY1 = pCurBox->top();
+ for (curNumRects = 0;
+ (pCurBox != pRegEnd) && (pCurBox->top() == bandY1);
+ curNumRects++)
+ {
+ pCurBox++;
+ }
+
+ if (pCurBox != pRegEnd)
+ {
+ /*
+ * If more than one band was added, we have to tqfind the start
+ * of the last band added so the next coalescing job can start
+ * at the right place... (given when multiple bands are added,
+ * this may be pointless -- see above).
+ */
+ pRegEnd--;
+ while ((pRegEnd-1)->top() == pRegEnd->top())
+ {
+ pRegEnd--;
+ }
+ curStart = pRegEnd - pReg->rects.data();
+ pRegEnd = pReg->rects.data() + pReg->numRects;
+ }
+
+ if ((curNumRects == prevNumRects) && (curNumRects != 0)) {
+ pCurBox -= curNumRects;
+ /*
+ * The bands may only be coalesced if the bottom of the previous
+ * matches the top scanline of the current.
+ */
+ if (pPrevBox->bottom() == pCurBox->top() - 1)
+ {
+ /*
+ * Make sure the bands have boxes in the same places. This
+ * assumes that boxes have been added in such a way that they
+ * cover the most area possible. I.e. two boxes in a band must
+ * have some horizontal space between them.
+ */
+ do
+ {
+ if ((pPrevBox->left() != pCurBox->left()) ||
+ (pPrevBox->right() != pCurBox->right()))
+ {
+ /*
+ * The bands don't line up so they can't be coalesced.
+ */
+ return (curStart);
+ }
+ pPrevBox++;
+ pCurBox++;
+ prevNumRects -= 1;
+ } while (prevNumRects != 0);
+
+ pReg->numRects -= curNumRects;
+ pCurBox -= curNumRects;
+ pPrevBox -= curNumRects;
+
+ /*
+ * The bands may be merged, so set the bottom y of each box
+ * in the previous band to that of the corresponding box in
+ * the current band.
+ */
+ do
+ {
+ pPrevBox->setBottom( pCurBox->bottom() );
+ pPrevBox++;
+ pCurBox++;
+ curNumRects -= 1;
+ } while (curNumRects != 0);
+
+ /*
+ * If only one band was added to the region, we have to backup
+ * curStart to the start of the previous band.
+ *
+ * If more than one band was added to the region, copy the
+ * other bands down. The assumption here is that the other bands
+ * came from the same region as the current one and no further
+ * coalescing can be done on them since it's all been done
+ * already... curStart is already in the right place.
+ */
+ if (pCurBox == pRegEnd)
+ {
+ curStart = prevStart;
+ }
+ else
+ {
+ do
+ {
+ *pPrevBox++ = *pCurBox++;
+ } while (pCurBox != pRegEnd);
+ }
+
+ }
+ }
+ return (curStart);
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miRegionOp --
+ * Apply an operation to two regions. Called by miUnion, miInverse,
+ * miSubtract, miIntersect...
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * The new region is overwritten.
+ *
+ * Notes:
+ * The idea behind this function is to view the two regions as sets.
+ * Together they cover a rectangle of area that this function divides
+ * into horizontal bands where points are covered only by one region
+ * or by both. For the first case, the nonOverlapFunc is called with
+ * each the band and the band's upper and lower extents. For the
+ * second, the overlapFunc is called to process the entire band. It
+ * is responsible for clipping the rectangles in the band, though
+ * this function provides the boundaries.
+ * At the end of each band, the new region is coalesced, if possible,
+ * to reduce the number of rectangles in the region.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static void*/
+static void
+miRegionOp(register TQRegionPrivate *newReg, TQRegionPrivate *reg1, TQRegionPrivate *reg2,
+ void (*overlapFunc)(...),
+ void (*nonOverlap1Func)(...),
+ void (*nonOverlap2Func)(...))
+ //register Region newReg; /* Place to store result */
+ //Region reg1; /* First region in operation */
+ //Region reg2; /* 2d region in operation */
+ //void (*overlapFunc)(); /* Function to call for over-
+ //* lapping bands */
+ //void (*nonOverlap1Func)(); /* Function to call for non-
+ //* overlapping bands in region
+ //* 1 */
+ //void (*nonOverlap2Func)(); /* Function to call for non-
+ //* overlapping bands in region
+ //* 2 */
+{
+ register TQRect *r1; /* Pointer into first region */
+ register TQRect *r2; /* Pointer into 2d region */
+ TQRect *r1End; /* End of 1st region */
+ TQRect *r2End; /* End of 2d region */
+ register int ybot; /* Bottom of intersection */
+ register int ytop; /* Top of intersection */
+ int prevBand; /* Index of start of
+ * previous band in newReg */
+ int curBand; /* Index of start of current
+ * band in newReg */
+ register TQRect *r1BandEnd; /* End of current band in r1 */
+ register TQRect *r2BandEnd; /* End of current band in r2 */
+ int top; /* Top of non-overlapping
+ * band */
+ int bot; /* Bottom of non-overlapping
+ * band */
+
+ /*
+ * Initialization:
+ * set r1, r2, r1End and r2End appropriately, preserve the important
+ * parts of the destination region until the end in case it's one of
+ * the two source regions, then mark the "new" region empty, allocating
+ * another array of rectangles for it to use.
+ */
+ r1 = reg1->rects.data();
+ r2 = reg2->rects.data();
+ r1End = r1 + reg1->numRects;
+ r2End = r2 + reg2->numRects;
+
+ TQMemArray<TQRect> oldRects = newReg->rects;
+
+ newReg->rects.detach();
+ EMPTY_REGION(newReg);
+
+ /*
+ * Allocate a reasonable number of rectangles for the new region. The idea
+ * is to allocate enough so the individual functions don't need to
+ * reallocate and copy the array, which is time consuming, yet we don't
+ * have to worry about using too much memory. I hope to be able to
+ * nuke the realloc() at the end of this function eventually.
+ */
+ newReg->rects.resize( TQMAX(reg1->numRects,reg2->numRects) * 2 );
+
+ /*
+ * Initialize ybot and ytop.
+ * In the upcoming loop, ybot and ytop serve different functions depending
+ * on whether the band being handled is an overlapping or non-overlapping
+ * band.
+ * In the case of a non-overlapping band (only one of the regions
+ * has points in the band), ybot is the bottom of the most recent
+ * intersection and thus clips the top of the rectangles in that band.
+ * ytop is the top of the next intersection between the two regions and
+ * serves to clip the bottom of the rectangles in the current band.
+ * For an overlapping band (where the two regions intersect), ytop clips
+ * the top of the rectangles of both regions and ybot clips the bottoms.
+ */
+ if (reg1->extents.top() < reg2->extents.top())
+ ybot = reg1->extents.top() - 1;
+ else
+ ybot = reg2->extents.top() - 1;
+
+ /*
+ * prevBand serves to mark the start of the previous band so rectangles
+ * can be coalesced into larger rectangles. qv. miCoalesce, above.
+ * In the beginning, there is no previous band, so prevBand == curBand
+ * (curBand is set later on, of course, but the first band will always
+ * start at index 0). prevBand and curBand must be indices because of
+ * the possible expansion, and resultant moving, of the new region's
+ * array of rectangles.
+ */
+ prevBand = 0;
+
+ do
+ {
+ curBand = newReg->numRects;
+
+ /*
+ * This algorithm proceeds one source-band (as opposed to a
+ * destination band, which is determined by where the two regions
+ * intersect) at a time. r1BandEnd and r2BandEnd serve to mark the
+ * rectangle after the last one in the current band for their
+ * respective regions.
+ */
+ r1BandEnd = r1;
+ while ((r1BandEnd != r1End) && (r1BandEnd->top() == r1->top()))
+ {
+ r1BandEnd++;
+ }
+
+ r2BandEnd = r2;
+ while ((r2BandEnd != r2End) && (r2BandEnd->top() == r2->top()))
+ {
+ r2BandEnd++;
+ }
+
+ /*
+ * First handle the band that doesn't intersect, if any.
+ *
+ * Note that attention is restricted to one band in the
+ * non-intersecting region at once, so if a region has n
+ * bands between the current position and the next place it overlaps
+ * the other, this entire loop will be passed through n times.
+ */
+ if (r1->top() < r2->top())
+ {
+ top = TQMAX(r1->top(),ybot+1);
+ bot = TQMIN(r1->bottom(),r2->top()-1);
+
+ if ((nonOverlap1Func != (voidProcp)NULL) && bot >= top)
+ {
+ (* nonOverlap1Func) (newReg, r1, r1BandEnd, top, bot);
+ }
+
+ ytop = r2->top();
+ }
+ else if (r2->top() < r1->top())
+ {
+ top = TQMAX(r2->top(),ybot+1);
+ bot = TQMIN(r2->bottom(),r1->top()-1);
+
+ if ((nonOverlap2Func != (voidProcp)NULL) && bot >= top)
+ {
+ (* nonOverlap2Func) (newReg, r2, r2BandEnd, top, bot);
+ }
+
+ ytop = r1->top();
+ }
+ else
+ {
+ ytop = r1->top();
+ }
+
+ /*
+ * If any rectangles got added to the region, try and coalesce them
+ * with rectangles from the previous band. Note we could just do
+ * this test in miCoalesce, but some machines incur a not
+ * inconsiderable cost for function calls, so...
+ */
+ if (newReg->numRects != curBand)
+ {
+ prevBand = miCoalesce (newReg, prevBand, curBand);
+ }
+
+ /*
+ * Now see if we've hit an intersecting band. The two bands only
+ * intersect if ybot >= ytop
+ */
+ ybot = TQMIN(r1->bottom(), r2->bottom());
+ curBand = newReg->numRects;
+ if (ybot >= ytop)
+ {
+ (* overlapFunc) (newReg, r1, r1BandEnd, r2, r2BandEnd, ytop, ybot);
+
+ }
+
+ if (newReg->numRects != curBand)
+ {
+ prevBand = miCoalesce (newReg, prevBand, curBand);
+ }
+
+ /*
+ * If we've finished with a band (y2 == ybot) we skip forward
+ * in the region to the next band.
+ */
+ if (r1->bottom() == ybot)
+ {
+ r1 = r1BandEnd;
+ }
+ if (r2->bottom() == ybot)
+ {
+ r2 = r2BandEnd;
+ }
+ } while ((r1 != r1End) && (r2 != r2End));
+
+ /*
+ * Deal with whichever region still has rectangles left.
+ */
+ curBand = newReg->numRects;
+ if (r1 != r1End)
+ {
+ if (nonOverlap1Func != (voidProcp)NULL)
+ {
+ do
+ {
+ r1BandEnd = r1;
+ while ((r1BandEnd < r1End) && (r1BandEnd->top() == r1->top()))
+ {
+ r1BandEnd++;
+ }
+ (* nonOverlap1Func) (newReg, r1, r1BandEnd,
+ TQMAX(r1->top(),ybot+1), r1->bottom());
+ r1 = r1BandEnd;
+ } while (r1 != r1End);
+ }
+ }
+ else if ((r2 != r2End) && (nonOverlap2Func != (voidProcp)NULL))
+ {
+ do
+ {
+ r2BandEnd = r2;
+ while ((r2BandEnd < r2End) && (r2BandEnd->top() == r2->top()))
+ {
+ r2BandEnd++;
+ }
+ (* nonOverlap2Func) (newReg, r2, r2BandEnd,
+ TQMAX(r2->top(),ybot+1), r2->bottom());
+ r2 = r2BandEnd;
+ } while (r2 != r2End);
+ }
+
+ if (newReg->numRects != curBand)
+ {
+ (void) miCoalesce (newReg, prevBand, curBand);
+ }
+
+ /*
+ * A bit of cleanup. To keep regions from growing without bound,
+ * we shrink the array of rectangles to match the new number of
+ * rectangles in the region. This never goes to 0, however...
+ *
+ * Only do this stuff if the number of rectangles allocated is more than
+ * twice the number of rectangles in the region (a simple optimization...).
+ */
+ if (newReg->numRects < (int)(newReg->rects.size() >> 1))
+ {
+ if (REGION_NOT_EMPTY(newReg))
+ {
+ newReg->rects.resize(newReg->numRects);
+ }
+ else
+ {
+ /*
+ * No point in doing the extra work involved in an realloc if
+ * the region is empty
+ */
+ newReg->rects.resize(1);
+ }
+ }
+ return;
+}
+
+
+/*======================================================================
+ * Region Union
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * miUnionNonO --
+ * Handle a non-overlapping band for the union operation. Just
+ * Adds the rectangles into the region. Doesn't have to check for
+ * subsumption or anything.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * pReg->numRects is incremented and the final rectangles overwritten
+ * with the rectangles we're passed.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static void*/
+static
+int
+miUnionNonO (register TQRegionPrivate *pReg, register TQRect * r,
+ TQRect * rEnd, register int y1, register int y2)
+{
+ register TQRect * pNextRect;
+
+ pNextRect = pReg->rects.data() + pReg->numRects;
+
+ TQ_ASSERT(y1 <= y2);
+
+ while (r != rEnd)
+ {
+ TQ_ASSERT(r->left() <= r->right());
+ MEMCHECK(pReg, pNextRect, pReg->rects)
+ qt_setCoords( pNextRect, r->left(), y1, r->right(), y2 );
+ pReg->numRects++;
+ pNextRect++;
+
+ r++;
+ }
+ return 0; /* lint */
+}
+
+
+/*-
+ *-----------------------------------------------------------------------
+ * miUnionO --
+ * Handle an overlapping band for the union operation. Picks the
+ * left-most rectangle each time and merges it into the region.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * Rectangles are overwritten in pReg->rects and pReg->numRects will
+ * be changed.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+/* static void*/
+static
+int
+miUnionO (register TQRegionPrivate *pReg, register TQRect *r1, TQRect *r1End,
+ register TQRect *r2, TQRect *r2End, register int y1, register int y2)
+{
+ register TQRect *pNextRect;
+
+ pNextRect = pReg->rects.data() + pReg->numRects;
+
+#define MERGERECT(r) \
+ if ((pReg->numRects != 0) && \
+ (pNextRect[-1].top() == y1) && \
+ (pNextRect[-1].bottom() == y2) && \
+ (pNextRect[-1].right() >= r->left()-1)) { \
+ if (pNextRect[-1].right() < r->right()) { \
+ pNextRect[-1].setRight( r->right() ); \
+ TQ_ASSERT(pNextRect[-1].left() <= pNextRect[-1].right()); \
+ } \
+ } else { \
+ MEMCHECK(pReg, pNextRect, pReg->rects) \
+ qt_setCoords( pNextRect, r->left(), y1, r->right(), y2 ); \
+ pReg->numRects++; \
+ pNextRect++; \
+ } \
+ r++;
+
+ TQ_ASSERT (y1<=y2);
+ while ((r1 != r1End) && (r2 != r2End)) {
+ if (r1->left() < r2->left()) {
+ MERGERECT(r1)
+ } else {
+ MERGERECT(r2)
+ }
+ }
+
+ if (r1 != r1End)
+ {
+ do
+ {
+ MERGERECT(r1)
+ } while (r1 != r1End);
+ }
+ else while (r2 != r2End)
+ {
+ MERGERECT(r2)
+ }
+ return 0; /* lint */
+}
+
+static void UnionRegion(TQRegionPrivate *reg1, TQRegionPrivate *reg2, TQRegionPrivate *newReg)
+{
+ /* checks all the simple cases */
+
+ /*
+ * Region 1 and 2 are the same or region 1 is empty
+ */
+ if ( (reg1 == reg2) || (!(reg1->numRects)) )
+ {
+ *newReg = *reg2;
+ return;
+ }
+
+ /*
+ * if nothing to union (region 2 empty)
+ */
+ if (!(reg2->numRects))
+ {
+ *newReg = *reg1;
+ return;
+ }
+
+ /*
+ * Region 1 completely subsumes region 2
+ */
+ if ((reg1->numRects == 1) &&
+ (reg1->extents.left() <= reg2->extents.left()) &&
+ (reg1->extents.top() <= reg2->extents.top()) &&
+ (reg1->extents.right() >= reg2->extents.right()) &&
+ (reg1->extents.bottom() >= reg2->extents.bottom()))
+ {
+ *newReg = *reg1;
+ return;
+ }
+
+ /*
+ * Region 2 completely subsumes region 1
+ */
+ if ((reg2->numRects == 1) &&
+ (reg2->extents.left() <= reg1->extents.left()) &&
+ (reg2->extents.top() <= reg1->extents.top()) &&
+ (reg2->extents.right() >= reg1->extents.right()) &&
+ (reg2->extents.bottom() >= reg1->extents.bottom()))
+ {
+ *newReg = *reg2;
+ return;
+ }
+
+ miRegionOp (newReg, reg1, reg2, (voidProcp) miUnionO,
+ (voidProcp) miUnionNonO, (voidProcp) miUnionNonO);
+
+ qt_setCoords( &newReg->extents,
+ TQMIN(reg1->extents.left(), reg2->extents.left()),
+ TQMIN(reg1->extents.top(), reg2->extents.top()),
+ TQMAX(reg1->extents.right(), reg2->extents.right()),
+ TQMAX(reg1->extents.bottom(), reg2->extents.bottom()) );
+
+ return;
+}
+
+/*======================================================================
+ * Region Subtraction
+ *====================================================================*/
+
+/*-
+ *-----------------------------------------------------------------------
+ * miSubtractNonO --
+ * Deal with non-overlapping band for subtraction. Any parts from
+ * region 2 we discard. Anything from region 1 we add to the region.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * pReg may be affected.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static void*/
+static
+int
+miSubtractNonO1 (register TQRegionPrivate *pReg, register TQRect *r,
+ TQRect *rEnd, register int y1, register int y2)
+{
+ register TQRect *pNextRect;
+
+ pNextRect = pReg->rects.data() + pReg->numRects;
+
+ TQ_ASSERT(y1<=y2);
+
+ while (r != rEnd)
+ {
+ TQ_ASSERT(r->left()<=r->right());
+ MEMCHECK(pReg, pNextRect, pReg->rects)
+ qt_setCoords( pNextRect, r->left(), y1, r->right(), y2 );
+ pReg->numRects++;
+ pNextRect++;
+
+ r++;
+ }
+ return 0; /* lint */
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miSubtractO --
+ * Overlapping band subtraction. x1 is the left-most point not yet
+ * checked.
+ *
+ * Results:
+ * None.
+ *
+ * Side Effects:
+ * pReg may have rectangles added to it.
+ *
+ *-----------------------------------------------------------------------
+ */
+/* static void*/
+static
+int
+miSubtractO (register TQRegionPrivate *pReg, register TQRect *r1, TQRect *r1End,
+ register TQRect *r2, TQRect *r2End, register int y1, register int y2)
+{
+ register TQRect *pNextRect;
+ register int x1;
+
+ x1 = r1->left();
+
+ TQ_ASSERT(y1<=y2);
+ pNextRect = pReg->rects.data() + pReg->numRects;
+
+ while ((r1 != r1End) && (r2 != r2End))
+ {
+ if (r2->right() < x1)
+ {
+ /*
+ * Subtrahend missed the boat: go to next subtrahend.
+ */
+ r2++;
+ }
+ else if (r2->left() <= x1)
+ {
+ /*
+ * Subtrahend precedes minuend: nuke left edge of minuend.
+ */
+ x1 = r2->right()+1;
+ if (x1 > r1->right())
+ {
+ /*
+ * Minuend completely covered: advance to next minuend and
+ * reset left fence to edge of new minuend.
+ */
+ r1++;
+ if (r1 != r1End)
+ x1 = r1->left();
+ }
+ else
+ {
+ /*
+ * Subtrahend now used up since it doesn't extend beyond
+ * minuend
+ */
+ r2++;
+ }
+ }
+ else if (r2->left() <= r1->right())
+ {
+ /*
+ * Left part of subtrahend covers part of minuend: add uncovered
+ * part of minuend to region and skip to next subtrahend.
+ */
+ TQ_ASSERT(x1<r2->left());
+ MEMCHECK(pReg, pNextRect, pReg->rects)
+ qt_setCoords( pNextRect, x1, y1, r2->left() - 1, y2 );
+ pReg->numRects++;
+ pNextRect++;
+
+ x1 = r2->right() + 1;
+ if (x1 > r1->right())
+ {
+ /*
+ * Minuend used up: advance to new...
+ */
+ r1++;
+ if (r1 != r1End)
+ x1 = r1->left();
+ }
+ else
+ {
+ /*
+ * Subtrahend used up
+ */
+ r2++;
+ }
+ }
+ else
+ {
+ /*
+ * Minuend used up: add any remaining piece before advancing.
+ */
+ if (r1->right() >= x1)
+ {
+ MEMCHECK(pReg, pNextRect, pReg->rects)
+ qt_setCoords( pNextRect, x1, y1, r1->right(), y2 );
+ pReg->numRects++;
+ pNextRect++;
+ }
+ r1++;
+ if ( r1 != r1End )
+ x1 = r1->left();
+ }
+ }
+
+ /*
+ * Add remaining minuend rectangles to region.
+ */
+ while (r1 != r1End)
+ {
+ TQ_ASSERT(x1<=r1->right());
+ MEMCHECK(pReg, pNextRect, pReg->rects)
+ qt_setCoords( pNextRect, x1, y1, r1->right(), y2 );
+ pReg->numRects++;
+ pNextRect++;
+
+ r1++;
+ if (r1 != r1End)
+ {
+ x1 = r1->left();
+ }
+ }
+ return 0; /* lint */
+}
+
+/*-
+ *-----------------------------------------------------------------------
+ * miSubtract --
+ * Subtract regS from regM and leave the result in regD.
+ * S stands for subtrahend, M for minuend and D for difference.
+ *
+ * Side Effects:
+ * regD is overwritten.
+ *
+ *-----------------------------------------------------------------------
+ */
+
+static void SubtractRegion(TQRegionPrivate *regM, TQRegionPrivate *regS, register TQRegionPrivate *regD)
+{
+ /* check for trivial reject */
+ if ( (!(regM->numRects)) || (!(regS->numRects)) ||
+ (!EXTENTCHECK(&regM->extents, &regS->extents)) )
+ {
+ *regD = *regM;
+ return;
+ }
+
+ miRegionOp (regD, regM, regS, (voidProcp) miSubtractO,
+ (voidProcp) miSubtractNonO1, (voidProcp) NULL);
+
+ /*
+ * Can't alter newReg's extents before we call miRegionOp because
+ * it might be one of the source regions and miRegionOp depends
+ * on the extents of those regions being the unaltered. Besides, this
+ * way there's no checking against rectangles that will be nuked
+ * due to coalescing, so we have to examine fewer rectangles.
+ */
+ miSetExtents (regD);
+}
+
+static void XorRegion( TQRegionPrivate *sra, TQRegionPrivate *srb, TQRegionPrivate *dr )
+{
+ TQRegionPrivate tra, trb;
+
+ SubtractRegion(sra,srb,&tra);
+ SubtractRegion(srb,sra,&trb);
+ UnionRegion(&tra,&trb,dr);
+}
+
+/*
+ * Check to see if two regions are equal
+ */
+static bool EqualRegion( TQRegionPrivate *r1, TQRegionPrivate *r2 )
+{
+ int i;
+
+ if( r1->numRects != r2->numRects ) return FALSE;
+ else if( r1->numRects == 0 ) return TRUE;
+ else if ( r1->extents.left() != r2->extents.left() ||
+ r1->extents.right() != r2->extents.right() ||
+ r1->extents.top() != r2->extents.top() ||
+ r1->extents.bottom() != r2->extents.bottom() )
+ return FALSE;
+ else {
+ TQRect *rr1 = r1->rects.data();
+ TQRect *rr2 = r2->rects.data();
+ for( i=0; i < r1->numRects; i++, rr1++, rr2++ ) {
+ if ( rr1->left() != rr2->left() ||
+ rr1->right() != rr2->right() ||
+ rr1->top() != rr2->top() ||
+ rr1->bottom() != rr2->bottom() )
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static bool PointInRegion( TQRegionPrivate *pRegion, int x, int y )
+{
+ int i;
+
+ if (pRegion->numRects == 0)
+ return FALSE;
+ if (!pRegion->extents.contains(x, y))
+ return FALSE;
+ for (i=0; i<pRegion->numRects; i++)
+ {
+ if (pRegion->rects[i].contains(x, y))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool RectInRegion(register TQRegionPrivate *region,
+ int rx, int ry, unsigned int rwidth, unsigned int rheight)
+{
+ register TQRect *pbox;
+ register TQRect *pboxEnd;
+ TQRect rect(rx, ry, rwidth, rheight);
+ register TQRect *prect = &rect;
+ int partIn, partOut;
+
+ /* this is (just) a useful optimization */
+ if ((region->numRects == 0) || !EXTENTCHECK(&region->extents, prect))
+ return(RectangleOut);
+
+ partOut = FALSE;
+ partIn = FALSE;
+
+ /* can stop when both partOut and partIn are TRUE, or we reach prect->y2 */
+ for (pbox = region->rects.data(), pboxEnd = pbox + region->numRects;
+ pbox < pboxEnd;
+ pbox++)
+ {
+
+ if (pbox->bottom() < ry)
+ continue; /* getting up to speed or skipping remainder of band */
+
+ if (pbox->top() > ry)
+ {
+ partOut = TRUE; /* missed part of rectangle above */
+ if (partIn || (pbox->top() > prect->bottom()))
+ break;
+ ry = pbox->top(); /* x guaranteed to be == prect->x1 */
+ }
+
+ if (pbox->right() < rx)
+ continue; /* not far enough over yet */
+
+ if (pbox->left() > rx)
+ {
+ partOut = TRUE; /* missed part of rectangle to left */
+ if (partIn)
+ break;
+ }
+
+ if (pbox->left() <= prect->right())
+ {
+ partIn = TRUE; /* definitely overlap */
+ if (partOut)
+ break;
+ }
+
+ if (pbox->right() >= prect->right())
+ {
+ ry = pbox->bottom() + 1; /* finished with this band */
+ if (ry > prect->bottom())
+ break;
+ rx = prect->left(); /* reset x out to left again */
+ } else
+ {
+ /*
+ * Because boxes in a band are maximal width, if the first box
+ * to overlap the rectangle doesn't completely cover it in that
+ * band, the rectangle must be partially out, since some of it
+ * will be uncovered in that band. partIn will have been set true
+ * by now...
+ */
+ break;
+ }
+
+ }
+
+ return(partIn ? ((ry <= prect->bottom()) ? RectanglePart : RectangleIn) :
+ RectangleOut);
+}
+// END OF Region.c extract
+// START OF poly.h extract
+/* $XConsortium: poly.h,v 1.4 94/04/17 20:22:19 rws Exp $ */
+/************************************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSETQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+
+/*
+ * This file tqcontains a few macros to help track
+ * the edge of a filled object. The object is assumed
+ * to be filled in scanline order, and thus the
+ * algorithm used is an extension of Bresenham's line
+ * drawing algorithm which assumes that y is always the
+ * major axis.
+ * Since these pieces of code are the same for any filled tqshape,
+ * it is more convenient to gather the library in one
+ * place, but since these pieces of code are also in
+ * the inner loops of output primitives, procedure call
+ * overhead is out of the question.
+ * See the author for a derivation if needed.
+ */
+
+
+/*
+ * In scan converting polygons, we want to choose those pixels
+ * which are inside the polygon. Thus, we add .5 to the starting
+ * x coordinate for both left and right edges. Now we choose the
+ * first pixel which is inside the pgon for the left edge and the
+ * first pixel which is outside the pgon for the right edge.
+ * Draw the left pixel, but not the right.
+ *
+ * How to add .5 to the starting x coordinate:
+ * If the edge is moving to the right, then subtract dy from the
+ * error term from the general form of the algorithm.
+ * If the edge is moving to the left, then add dy to the error term.
+ *
+ * The reason for the difference between edges moving to the left
+ * and edges moving to the right is simple: If an edge is moving
+ * to the right, then we want the algorithm to flip immediately.
+ * If it is moving to the left, then we don't want it to flip until
+ * we traverse an entire pixel.
+ */
+#define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \
+ int dx; /* local storage */ \
+\
+ /* \
+ * if the edge is horizontal, then it is ignored \
+ * and assumed not to be processed. Otherwise, do this stuff. \
+ */ \
+ if ((dy) != 0) { \
+ xStart = (x1); \
+ dx = (x2) - xStart; \
+ if (dx < 0) { \
+ m = dx / (dy); \
+ m1 = m - 1; \
+ incr1 = -2 * dx + 2 * (dy) * m1; \
+ incr2 = -2 * dx + 2 * (dy) * m; \
+ d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
+ } else { \
+ m = dx / (dy); \
+ m1 = m + 1; \
+ incr1 = 2 * dx - 2 * (dy) * m1; \
+ incr2 = 2 * dx - 2 * (dy) * m; \
+ d = -2 * m * (dy) + 2 * dx; \
+ } \
+ } \
+}
+
+#define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \
+ if (m1 > 0) { \
+ if (d > 0) { \
+ minval += m1; \
+ d += incr1; \
+ } \
+ else { \
+ minval += m; \
+ d += incr2; \
+ } \
+ } else {\
+ if (d >= 0) { \
+ minval += m1; \
+ d += incr1; \
+ } \
+ else { \
+ minval += m; \
+ d += incr2; \
+ } \
+ } \
+}
+
+
+/*
+ * This structure tqcontains all of the information needed
+ * to run the bresenham algorithm.
+ * The variables may be hardcoded into the declarations
+ * instead of using this structure to make use of
+ * register declarations.
+ */
+typedef struct {
+ int minor_axis; /* minor axis */
+ int d; /* decision variable */
+ int m, m1; /* slope and slope+1 */
+ int incr1, incr2; /* error increments */
+} BRESINFO;
+
+
+#define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
+ BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \
+ bres.m, bres.m1, bres.incr1, bres.incr2)
+
+#define BRESINCRPGONSTRUCT(bres) \
+ BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2)
+
+
+
+/*
+ * These are the data structures needed to scan
+ * convert regions. Two different scan conversion
+ * methods are available -- the even-odd method, and
+ * the winding number method.
+ * The even-odd rule states that a point is inside
+ * the polygon if a ray drawn from that point in any
+ * direction will pass through an odd number of
+ * path segments.
+ * By the winding number rule, a point is decided
+ * to be inside the polygon if a ray drawn from that
+ * point in any direction passes through a different
+ * number of clockwise and counter-clockwise path
+ * segments.
+ *
+ * These data structures are adapted somewhat from
+ * the algorithm in (Foley/Van Dam) for scan converting
+ * polygons.
+ * The basic algorithm is to start at the top (smallest y)
+ * of the polygon, stepping down to the bottom of
+ * the polygon by incrementing the y coordinate. We
+ * keep a list of edges which the current scanline crosses,
+ * sorted by x. This list is called the Active Edge Table (AET)
+ * As we change the y-coordinate, we update each entry in
+ * in the active edge table to reflect the edges new xcoord.
+ * This list must be sorted at each scanline in case
+ * two edges intersect.
+ * We also keep a data structure known as the Edge Table (ET),
+ * which keeps track of all the edges which the current
+ * scanline has not yet reached. The ET is basically a
+ * list of ScanLineList structures containing a list of
+ * edges which are entered at a given scanline. There is one
+ * ScanLineList per scanline at which an edge is entered.
+ * When we enter a new edge, we move it from the ET to the AET.
+ *
+ * From the AET, we can implement the even-odd rule as in
+ * (Foley/Van Dam).
+ * The winding number rule is a little trickier. We also
+ * keep the EdgeTableEntries in the AET linked by the
+ * nextWETE (winding EdgeTableEntry) link. This allows
+ * the edges to be linked just as before for updating
+ * purposes, but only uses the edges linked by the nextWETE
+ * link as edges representing spans of the polygon to
+ * drawn (as with the even-odd rule).
+ */
+
+/*
+ * for the winding number rule
+ */
+#define CLOCKWISE 1
+#define COUNTERCLOCKWISE -1
+
+typedef struct _EdgeTableEntry {
+ int ymax; /* ycoord at which we exit this edge. */
+ BRESINFO bres; /* Bresenham info to run the edge */
+ struct _EdgeTableEntry *next; /* next in the list */
+ struct _EdgeTableEntry *back; /* for insertion sort */
+ struct _EdgeTableEntry *nextWETE; /* for winding num rule */
+ int ClockWise; /* flag for winding number rule */
+} EdgeTableEntry;
+
+
+typedef struct _ScanLineList{
+ int scanline; /* the scanline represented */
+ EdgeTableEntry *edgelist; /* header node */
+ struct _ScanLineList *next; /* next in the list */
+} ScanLineList;
+
+
+typedef struct {
+ int ymax; /* ymax for the polygon */
+ int ymin; /* ymin for the polygon */
+ ScanLineList scanlines; /* header node */
+} EdgeTable;
+
+
+/*
+ * Here is a struct to help with storage allocation
+ * so we can allocate a big chunk at a time, and then take
+ * pieces from this heap when we need to.
+ */
+#define SLLSPERBLOCK 25
+
+typedef struct _ScanLineListBlock {
+ ScanLineList SLLs[SLLSPERBLOCK];
+ struct _ScanLineListBlock *next;
+} ScanLineListBlock;
+
+
+
+/*
+ *
+ * a few macros for the inner loops of the fill code where
+ * performance considerations don't allow a procedure call.
+ *
+ * Evaluate the given edge at the given scanline.
+ * If the edge has expired, then we leave it and fix up
+ * the active edge table; otherwise, we increment the
+ * x value to be ready for the next scanline.
+ * The winding number rule is in effect, so we must notify
+ * the caller when the edge has been removed so he
+ * can reorder the Winding Active Edge Table.
+ */
+#define EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) { \
+ if (pAET->ymax == y) { /* leaving this edge */ \
+ pPrevAET->next = pAET->next; \
+ pAET = pPrevAET->next; \
+ fixWAET = 1; \
+ if (pAET) \
+ pAET->back = pPrevAET; \
+ } \
+ else { \
+ BRESINCRPGONSTRUCT(pAET->bres) \
+ pPrevAET = pAET; \
+ pAET = pAET->next; \
+ } \
+}
+
+
+/*
+ * Evaluate the given edge at the given scanline.
+ * If the edge has expired, then we leave it and fix up
+ * the active edge table; otherwise, we increment the
+ * x value to be ready for the next scanline.
+ * The even-odd rule is in effect.
+ */
+#define EVALUATEEDGEEVENODD(pAET, pPrevAET, y) { \
+ if (pAET->ymax == y) { /* leaving this edge */ \
+ pPrevAET->next = pAET->next; \
+ pAET = pPrevAET->next; \
+ if (pAET) \
+ pAET->back = pPrevAET; \
+ } \
+ else { \
+ BRESINCRPGONSTRUCT(pAET->bres) \
+ pPrevAET = pAET; \
+ pAET = pAET->next; \
+ } \
+}
+// END OF poly.h extract
+// START OF PolyReg.c extract
+/* $XConsortium: PolyReg.c,v 11.23 94/11/17 21:59:37 converse Exp $ */
+/************************************************************************
+
+Copyright (c) 1987 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
+
+ All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Digital not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSETQUENTIAL DAMAGES OR
+ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+SOFTWARE.
+
+************************************************************************/
+/* $XFree86: xc/lib/X11/PolyReg.c,v 1.1.1.2.8.2 1998/10/04 15:22:49 hohndel Exp $ */
+
+#define LARGE_COORDINATE 1000000
+#define SMALL_COORDINATE -LARGE_COORDINATE
+
+/*
+ * InsertEdgeInET
+ *
+ * Insert the given edge into the edge table.
+ * First we must tqfind the correct bucket in the
+ * Edge table, then tqfind the right slot in the
+ * bucket. Finally, we can insert it.
+ *
+ */
+static void
+InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline,
+ ScanLineListBlock **SLLBlock, int *iSLLBlock)
+{
+ register EdgeTableEntry *start, *prev;
+ register ScanLineList *pSLL, *pPrevSLL;
+ ScanLineListBlock *tmpSLLBlock;
+
+ /*
+ * tqfind the right bucket to put the edge into
+ */
+ pPrevSLL = &ET->scanlines;
+ pSLL = pPrevSLL->next;
+ while (pSLL && (pSLL->scanline < scanline))
+ {
+ pPrevSLL = pSLL;
+ pSLL = pSLL->next;
+ }
+
+ /*
+ * reassign pSLL (pointer to ScanLineList) if necessary
+ */
+ if ((!pSLL) || (pSLL->scanline > scanline))
+ {
+ if (*iSLLBlock > SLLSPERBLOCK-1)
+ {
+ tmpSLLBlock =
+ (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock));
+ (*SLLBlock)->next = tmpSLLBlock;
+ tmpSLLBlock->next = (ScanLineListBlock *)NULL;
+ *SLLBlock = tmpSLLBlock;
+ *iSLLBlock = 0;
+ }
+ pSLL = &((*SLLBlock)->SLLs[(*iSLLBlock)++]);
+
+ pSLL->next = pPrevSLL->next;
+ pSLL->edgelist = (EdgeTableEntry *)NULL;
+ pPrevSLL->next = pSLL;
+ }
+ pSLL->scanline = scanline;
+
+ /*
+ * now insert the edge in the right bucket
+ */
+ prev = (EdgeTableEntry *)NULL;
+ start = pSLL->edgelist;
+ while (start && (start->bres.minor_axis < ETE->bres.minor_axis))
+ {
+ prev = start;
+ start = start->next;
+ }
+ ETE->next = start;
+
+ if (prev)
+ prev->next = ETE;
+ else
+ pSLL->edgelist = ETE;
+}
+
+/*
+ * CreateEdgeTable
+ *
+ * This routine creates the edge table for
+ * scan converting polygons.
+ * The Edge Table (ET) looks like:
+ *
+ * EdgeTable
+ * --------
+ * | ymax | ScanLineLists
+ * |scanline|-->------------>-------------->...
+ * -------- |scanline| |scanline|
+ * |edgelist| |edgelist|
+ * --------- ---------
+ * | |
+ * | |
+ * V V
+ * list of ETEs list of ETEs
+ *
+ * where ETE is an EdgeTableEntry data structure,
+ * and there is one ScanLineList per scanline at
+ * which an edge is initially entered.
+ *
+ */
+
+static void
+CreateETandAET(register int count, register TQPoint *pts,
+ EdgeTable *ET, EdgeTableEntry *AET, register EdgeTableEntry *pETEs,
+ ScanLineListBlock *pSLLBlock)
+{
+ register TQPoint *top, *bottom;
+ register TQPoint *PrevPt, *CurrPt;
+ int iSLLBlock = 0;
+ int dy;
+
+ if (count < 2) return;
+
+ /*
+ * initialize the Active Edge Table
+ */
+ AET->next = (EdgeTableEntry *)NULL;
+ AET->back = (EdgeTableEntry *)NULL;
+ AET->nextWETE = (EdgeTableEntry *)NULL;
+ AET->bres.minor_axis = SMALL_COORDINATE;
+
+ /*
+ * initialize the Edge Table.
+ */
+ ET->scanlines.next = (ScanLineList *)NULL;
+ ET->ymax = SMALL_COORDINATE;
+ ET->ymin = LARGE_COORDINATE;
+ pSLLBlock->next = (ScanLineListBlock *)NULL;
+
+ PrevPt = &pts[count-1];
+
+ /*
+ * for each vertex in the array of points.
+ * In this loop we are dealing with two vertices at
+ * a time -- these make up one edge of the polygon.
+ */
+ while (count--)
+ {
+ CurrPt = pts++;
+
+ /*
+ * tqfind out which point is above and which is below.
+ */
+ if (PrevPt->y() > CurrPt->y() )
+ {
+ bottom = PrevPt, top = CurrPt;
+ pETEs->ClockWise = 0;
+ }
+ else
+ {
+ bottom = CurrPt, top = PrevPt;
+ pETEs->ClockWise = 1;
+ }
+
+ /*
+ * don't add horizontal edges to the Edge table.
+ */
+ if ( bottom->y() != top->y() )
+ {
+ pETEs->ymax = bottom->y()-1; /* -1 so we don't get last scanline */
+
+ /*
+ * initialize integer edge algorithm
+ */
+ dy = bottom->y() - top->y();
+ BRESINITPGONSTRUCT(dy, top->x(), bottom->x(), pETEs->bres)
+
+ InsertEdgeInET(ET, pETEs, top->y(), &pSLLBlock, &iSLLBlock);
+
+ if (PrevPt->y() > ET->ymax)
+ ET->ymax = PrevPt->y();
+ if (PrevPt->y() < ET->ymin)
+ ET->ymin = PrevPt->y();
+ pETEs++;
+ }
+
+ PrevPt = CurrPt;
+ }
+}
+
+/*
+ * loadAET
+ *
+ * This routine moves EdgeTableEntries from the
+ * EdgeTable into the Active Edge Table,
+ * leaving them sorted by smaller x coordinate.
+ *
+ */
+
+static void
+loadAET(register EdgeTableEntry *AET, register EdgeTableEntry *ETEs)
+{
+ register EdgeTableEntry *pPrevAET;
+ register EdgeTableEntry *tmp;
+
+ pPrevAET = AET;
+ AET = AET->next;
+ while (ETEs)
+ {
+ while (AET && (AET->bres.minor_axis < ETEs->bres.minor_axis))
+ {
+ pPrevAET = AET;
+ AET = AET->next;
+ }
+ tmp = ETEs->next;
+ ETEs->next = AET;
+ if (AET)
+ AET->back = ETEs;
+ ETEs->back = pPrevAET;
+ pPrevAET->next = ETEs;
+ pPrevAET = ETEs;
+
+ ETEs = tmp;
+ }
+}
+
+/*
+ * computeWAET
+ *
+ * This routine links the AET by the
+ * nextWETE (winding EdgeTableEntry) link for
+ * use by the winding number rule. The final
+ * Active Edge Table (AET) might look something
+ * like:
+ *
+ * AET
+ * ---------- --------- ---------
+ * |ymax | |ymax | |ymax |
+ * | ... | |... | |... |
+ * |next |->|next |->|next |->...
+ * |nextWETE| |nextWETE| |nextWETE|
+ * --------- --------- ^--------
+ * | | |
+ * V-------------------> V---> ...
+ *
+ */
+static void
+computeWAET(register EdgeTableEntry *AET)
+{
+ register EdgeTableEntry *pWETE;
+ register int inside = 1;
+ register int isInside = 0;
+
+ AET->nextWETE = (EdgeTableEntry *)NULL;
+ pWETE = AET;
+ AET = AET->next;
+ while (AET)
+ {
+ if (AET->ClockWise)
+ isInside++;
+ else
+ isInside--;
+
+ if ((!inside && !isInside) ||
+ ( inside && isInside))
+ {
+ pWETE->nextWETE = AET;
+ pWETE = AET;
+ inside = !inside;
+ }
+ AET = AET->next;
+ }
+ pWETE->nextWETE = (EdgeTableEntry *)NULL;
+}
+
+/*
+ * InsertionSort
+ *
+ * Just a simple insertion sort using
+ * pointers and back pointers to sort the Active
+ * Edge Table.
+ *
+ */
+
+static int
+InsertionSort(register EdgeTableEntry *AET)
+{
+ register EdgeTableEntry *pETEchase;
+ register EdgeTableEntry *pETEinsert;
+ register EdgeTableEntry *pETEchaseBackTMP;
+ register int changed = 0;
+
+ AET = AET->next;
+ while (AET)
+ {
+ pETEinsert = AET;
+ pETEchase = AET;
+ while (pETEchase->back->bres.minor_axis > AET->bres.minor_axis)
+ pETEchase = pETEchase->back;
+
+ AET = AET->next;
+ if (pETEchase != pETEinsert)
+ {
+ pETEchaseBackTMP = pETEchase->back;
+ pETEinsert->back->next = AET;
+ if (AET)
+ AET->back = pETEinsert->back;
+ pETEinsert->next = pETEchase;
+ pETEchase->back->next = pETEinsert;
+ pETEchase->back = pETEinsert;
+ pETEinsert->back = pETEchaseBackTMP;
+ changed = 1;
+ }
+ }
+ return(changed);
+}
+
+/*
+ * Clean up our act.
+ */
+static void
+FreeStorage(register ScanLineListBlock *pSLLBlock)
+{
+ register ScanLineListBlock *tmpSLLBlock;
+
+ while (pSLLBlock)
+ {
+ tmpSLLBlock = pSLLBlock->next;
+ free((char *)pSLLBlock);
+ pSLLBlock = tmpSLLBlock;
+ }
+}
+
+/*
+ * Create an array of rectangles from a list of points.
+ * If indeed these things (POINTS, RECTS) are the same,
+ * then this proc is still needed, because it allocates
+ * storage for the array, which was allocated on the
+ * stack by the calling procedure.
+ *
+ */
+static int PtsToRegion(register int numFullPtBlocks, register int iCurPtBlock,
+ POINTBLOCK *FirstPtBlock, TQRegionPrivate *reg)
+{
+ register TQRect *rects;
+ register TQPoint *pts;
+ register POINTBLOCK *CurPtBlock;
+ register int i;
+ register TQRect *extents;
+ register int numRects;
+
+ extents = &reg->extents;
+
+ numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;
+
+ reg->rects.resize(numRects);
+
+ CurPtBlock = FirstPtBlock;
+ rects = reg->rects.data() - 1;
+ numRects = 0;
+ extents->setLeft( INT_MAX );
+ extents->setRight( INT_MIN );
+
+ for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) {
+ /* the loop uses 2 points per iteration */
+ i = NUMPTSTOBUFFER >> 1;
+ if (!numFullPtBlocks)
+ i = iCurPtBlock >> 1;
+ for (pts = CurPtBlock->pts; i--; pts += 2) {
+ if ( pts->x() == pts[1].x() )
+ continue;
+ if (numRects && pts->x() == rects->left() && pts->y() == rects->bottom() + 1 &&
+ pts[1].x() == rects->right() &&
+ (numRects == 1 || rects[-1].top() != rects->top()) &&
+ (i && pts[2].y() > pts[1].y() )) {
+ rects->setBottom( pts[1].y() );
+ continue;
+ }
+ numRects++;
+ rects++;
+ qt_setCoords( rects, pts->x(), pts->y(), pts[1].x() - 1, pts[1].y() );
+ if (rects->left() < extents->left())
+ extents->setLeft( rects->left() );
+ if (rects->right() > extents->right())
+ extents->setRight( rects->right() );
+ }
+ CurPtBlock = CurPtBlock->next;
+ }
+
+ if (numRects) {
+ extents->setTop( reg->rects[0].top() );
+ extents->setBottom( rects->bottom() );
+ } else {
+ qt_setCoords(extents, 0, 0, 0, 0);
+ }
+ reg->numRects = numRects;
+
+ return(TRUE);
+}
+
+/*
+ * polytoregion
+ *
+ * Scan converts a polygon by returning a run-length
+ * encoding of the resultant bitmap -- the run-length
+ * encoding is in the form of an array of rectangles.
+ */
+static TQRegionPrivate *PolygonRegion(TQPoint *Pts, int Count, int rule)
+ //Point *Pts; /* the pts */
+ //int Count; /* number of pts */
+ //int rule; /* winding rule */
+{
+ TQRegionPrivate *region;
+ register EdgeTableEntry *pAET; /* Active Edge Table */
+ register int y; /* current scanline */
+ register int iPts = 0; /* number of pts in buffer */
+ register EdgeTableEntry *pWETE; /* Winding Edge Table Entry*/
+ register ScanLineList *pSLL; /* current scanLineList */
+ register TQPoint *pts; /* output buffer */
+ EdgeTableEntry *pPrevAET; /* ptr to previous AET */
+ EdgeTable ET; /* header node for ET */
+ EdgeTableEntry AET; /* header node for AET */
+ EdgeTableEntry *pETEs; /* EdgeTableEntries pool */
+ ScanLineListBlock SLLBlock; /* header for scanlinelist */
+ int fixWAET = FALSE;
+ POINTBLOCK FirstPtBlock, *curPtBlock; /* PtBlock buffers */
+ POINTBLOCK *tmpPtBlock;
+ int numFullPtBlocks = 0;
+
+ if ( !(region = new TQRegionPrivate) )
+ return 0;
+
+ /* special case a rectangle */
+ pts = Pts;
+ if (((Count == 4) ||
+ ((Count == 5) && (pts[4].x() == pts[0].x() ) && (pts[4].y() == pts[0].y() ))) &&
+ (((pts[0].y() == pts[1].y()) &&
+ (pts[1].x() == pts[2].x()) &&
+ (pts[2].y() == pts[3].y()) &&
+ (pts[3].x() == pts[0].x())) ||
+ ((pts[0].x() == pts[1].x()) &&
+ (pts[1].y() == pts[2].y()) &&
+ (pts[2].x() == pts[3].x()) &&
+ (pts[3].y() == pts[0].y())))) {
+ region->extents.setLeft( TQMIN(pts[0].x(), pts[2].x()) );
+ region->extents.setTop( TQMIN(pts[0].y(), pts[2].y()) );
+ region->extents.setRight( TQMAX(pts[0].x(), pts[2].x()) );
+ region->extents.setBottom( TQMAX(pts[0].y(), pts[2].y()) );
+ if ((region->extents.left() <= region->extents.right()) &&
+ (region->extents.top() <= region->extents.bottom())) {
+ region->numRects = 1;
+ region->rects.resize(1);
+ region->rects[0] = region->extents;
+ }
+ return region;
+ }
+
+ if (! (pETEs = (EdgeTableEntry *)
+ malloc((unsigned) (sizeof(EdgeTableEntry) * Count))))
+ return 0;
+
+ pts = FirstPtBlock.pts;
+ CreateETandAET(Count, Pts, &ET, &AET, pETEs, &SLLBlock);
+ pSLL = ET.scanlines.next;
+ curPtBlock = &FirstPtBlock;
+
+ if (rule == EvenOddRule) {
+ /*
+ * for each scanline
+ */
+ for (y = ET.ymin; y < ET.ymax; y++) {
+ /*
+ * Add a new edge to the active edge table when we
+ * get to the next edge.
+ */
+ if (pSLL != NULL && y == pSLL->scanline) {
+ loadAET(&AET, pSLL->edgelist);
+ pSLL = pSLL->next;
+ }
+ pPrevAET = &AET;
+ pAET = AET.next;
+
+ /*
+ * for each active edge
+ */
+ while (pAET) {
+ pts->setX( pAET->bres.minor_axis ), pts->setY( y );
+ pts++, iPts++;
+
+ /*
+ * send out the buffer
+ */
+ if (iPts == NUMPTSTOBUFFER) {
+ tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK));
+ curPtBlock->next = tmpPtBlock;
+ curPtBlock = tmpPtBlock;
+ pts = curPtBlock->pts;
+ numFullPtBlocks++;
+ iPts = 0;
+ }
+ EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
+ }
+ (void) InsertionSort(&AET);
+ }
+ }
+ else {
+ /*
+ * for each scanline
+ */
+ for (y = ET.ymin; y < ET.ymax; y++) {
+ /*
+ * Add a new edge to the active edge table when we
+ * get to the next edge.
+ */
+ if (pSLL != NULL && y == pSLL->scanline) {
+ loadAET(&AET, pSLL->edgelist);
+ computeWAET(&AET);
+ pSLL = pSLL->next;
+ }
+ pPrevAET = &AET;
+ pAET = AET.next;
+ pWETE = pAET;
+
+ /*
+ * for each active edge
+ */
+ while (pAET) {
+ /*
+ * add to the buffer only those edges that
+ * are in the Winding active edge table.
+ */
+ if (pWETE == pAET) {
+ pts->setX( pAET->bres.minor_axis), pts->setY( y );
+ pts++, iPts++;
+
+ /*
+ * send out the buffer
+ */
+ if (iPts == NUMPTSTOBUFFER) {
+ tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK));
+ curPtBlock->next = tmpPtBlock;
+ curPtBlock = tmpPtBlock;
+ pts = curPtBlock->pts;
+ numFullPtBlocks++; iPts = 0;
+ }
+ pWETE = pWETE->nextWETE;
+ }
+ EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
+ }
+
+ /*
+ * recompute the winding active edge table if
+ * we just resorted or have exited an edge.
+ */
+ if (InsertionSort(&AET) || fixWAET) {
+ computeWAET(&AET);
+ fixWAET = FALSE;
+ }
+ }
+ }
+ FreeStorage(SLLBlock.next);
+ (void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
+ for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
+ tmpPtBlock = curPtBlock->next;
+ free((char *)curPtBlock);
+ curPtBlock = tmpPtBlock;
+ }
+ free((char *)pETEs);
+ return region;
+}
+// END OF PolyReg.c extract
+
+TQRegionPrivate *qt_bitmapToRegion(const TQBitmap& bitmap)
+{
+ TQImage image = bitmap.convertToImage();
+
+ TQRegionPrivate *region = new TQRegionPrivate;
+ TQRect xr;
+
+#define AddSpan \
+ { \
+ qt_setCoords( &xr, prev1, y, x-1, y ); \
+ UnionRectWithRegion( &xr, region, region ); \
+ }
+
+ const int zero=0;
+ bool little = image.bitOrder() == TQImage::LittleEndian;
+
+ int x, y;
+ for (y=0; y<image.height(); y++) {
+ uchar *line = image.scanLine(y);
+ int w = image.width();
+ uchar all=zero;
+ int prev1 = -1;
+ for (x=0; x<w; ) {
+ uchar byte = line[x/8];
+ if ( x>w-8 || byte!=all ) {
+ if ( little ) {
+ for ( int b=8; b>0 && x<w; b-- ) {
+ if ( !(byte&0x01) == !all ) {
+ // More of the same
+ } else {
+ // A change.
+ if ( all!=zero ) {
+ AddSpan
+ all = zero;
+ } else {
+ prev1 = x;
+ all = ~zero;
+ }
+ }
+ byte >>= 1;
+ x++;
+ }
+ } else {
+ for ( int b=8; b>0 && x<w; b-- ) {
+ if ( !(byte&0x80) == !all ) {
+ // More of the same
+ } else {
+ // A change.
+ if ( all!=zero ) {
+ AddSpan
+ all = zero;
+ } else {
+ prev1 = x;
+ all = ~zero;
+ }
+ }
+ byte <<= 1;
+ x++;
+ }
+ }
+ } else {
+ x+=8;
+ }
+ }
+ if ( all != zero ) {
+ AddSpan
+ }
+ }
+
+ return region;
+}
+
+// NOT REVISED
+
+static TQRegion *empty_region = 0;
+
+static void cleanup_empty_region()
+{
+ delete empty_region;
+ empty_region = 0;
+}
+
+
+/*!
+ Constructs a null region.
+
+ \sa isNull()
+*/
+
+TQRegion::TQRegion()
+{
+ if ( !empty_region ) { // avoid too many allocs
+ qAddPostRoutine( cleanup_empty_region );
+ empty_region = new TQRegion( TRUE );
+ TQ_CHECK_PTR( empty_region );
+ }
+ data = empty_region->data;
+ data->ref();
+}
+
+/*! \internal
+ Internal constructor that creates a null region.
+*/
+
+TQRegion::TQRegion( bool is_null )
+{
+ data = new TQRegionData;
+ TQ_CHECK_PTR( data );
+ data->region = new TQRegionPrivate;
+ data->is_null = is_null;
+ data->rgn = 0;
+ data->xrectangles = 0;
+}
+
+/*!
+ \overload
+
+ Create a region based on the rectange \a r with region type \a t.
+
+ If the rectangle is invalid a null region will be created.
+
+ \sa TQRegion::RegionType
+*/
+
+TQRegion::TQRegion( const TQRect &r, RegionType t )
+{
+ if ( r.isEmpty() ) {
+ if ( !empty_region ) { // avoid too many allocs
+ qAddPostRoutine( cleanup_empty_region );
+ empty_region = new TQRegion( TRUE );
+ TQ_CHECK_PTR( empty_region );
+ }
+ data = empty_region->data;
+ data->ref();
+ } else {
+ data = new TQRegionData;
+ TQ_CHECK_PTR( data );
+ data->is_null = FALSE;
+ data->rgn = 0;
+ data->xrectangles = 0;
+ if ( t == Rectangle ) { // rectangular region
+ data->region = new TQRegionPrivate( r );
+ } else if ( t == Ellipse ) { // elliptic region
+ TQPointArray a;
+ a.makeEllipse( r.x(), r.y(), r.width(), r.height() );
+ data->region = PolygonRegion( (TQPoint*)a.data(), a.size(),
+ EvenOddRule );
+ }
+ }
+}
+
+
+/*!
+ Constructs a polygon region from the point array \a a.
+
+ If \a winding is TRUE, the polygon region is filled using the
+ winding algorithm, otherwise the default even-odd fill algorithm
+ is used.
+
+ This constructor may create complex regions that will slow down
+ painting when used.
+*/
+
+TQRegion::TQRegion( const TQPointArray &a, bool winding )
+{
+ if (a.size() > 2) {
+ data = new TQRegionData;
+ TQ_CHECK_PTR( data );
+ data->is_null = FALSE;
+ data->rgn = 0;
+ data->xrectangles = 0;
+ data->region = PolygonRegion( (TQPoint*)a.data(), a.size(),
+ winding ? WindingRule : EvenOddRule );
+ } else {
+ if ( !empty_region ) {
+ qAddPostRoutine( cleanup_empty_region );
+ empty_region = new TQRegion( TRUE );
+ TQ_CHECK_PTR( empty_region );
+ }
+ data = empty_region->data;
+ data->ref();
+ }
+}
+
+
+/*!
+ Constructs a new region which is equal to region \a r.
+*/
+
+TQRegion::TQRegion( const TQRegion &r )
+{
+ data = r.data;
+ data->ref();
+}
+
+
+/*!
+ Constructs a region from the bitmap \a bm.
+
+ The resulting region consists of the pixels in bitmap \a bm that
+ are \c color1, as if each pixel was a 1 by 1 rectangle.
+
+ This constructor may create complex regions that will slow down
+ painting when used. Note that drawing masked pixmaps can be done
+ much faster using TQPixmap::setMask().
+*/
+TQRegion::TQRegion( const TQBitmap & bm )
+{
+ if ( bm.isNull() ) {
+ if ( !empty_region ) { // avoid too many allocs
+ qAddPostRoutine( cleanup_empty_region );
+ empty_region = new TQRegion( TRUE );
+ TQ_CHECK_PTR( empty_region );
+ }
+ data = empty_region->data;
+ data->ref();
+ } else {
+ data = new TQRegionData;
+ TQ_CHECK_PTR( data );
+ data->is_null = FALSE;
+ data->rgn = 0;
+ data->xrectangles = 0;
+ data->region = qt_bitmapToRegion(bm);
+ }
+}
+
+/*!
+ Destroys the region.
+*/
+
+TQRegion::~TQRegion()
+{
+ if ( data->deref() ) {
+ delete data->region;
+ if ( data->rgn )
+ XDestroyRegion( data->rgn );
+ if ( data->xrectangles )
+ free( data->xrectangles );
+ delete data;
+ }
+}
+
+
+/*!
+ Assigns \a r to this region and returns a reference to the region.
+*/
+
+TQRegion &TQRegion::operator=( const TQRegion &r )
+{
+ r.data->ref(); // beware of r = r
+ if ( data->deref() ) {
+ delete data->region;
+ if ( data->rgn )
+ XDestroyRegion( data->rgn );
+ if ( data->xrectangles )
+ free( data->xrectangles );
+ delete data;
+ }
+ data = r.data;
+ return *this;
+}
+
+
+/*!
+ Returns a \link shclass.html deep copy\endlink of the region.
+
+ \sa detach()
+*/
+
+TQRegion TQRegion::copy() const
+{
+ TQRegion r( data->is_null );
+ *r.data->region = *data->region;
+ return r;
+}
+
+/*!
+ Returns TRUE if the region is a null region; otherwise returns
+ FALSE.
+
+ A null region is a region that has not been initialized. A null
+ region is always empty.
+
+ \sa isEmpty()
+*/
+
+bool TQRegion::isNull() const
+{
+ return data->is_null;
+}
+
+
+/*!
+ Returns TRUE if the region is empty; otherwise returns FALSE. An
+ empty region is a region that tqcontains no points.
+
+ Example:
+ \code
+ TQRegion r1( 10, 10, 20, 20 );
+ TQRegion r2( 40, 40, 20, 20 );
+ TQRegion r3;
+ r1.isNull(); // FALSE
+ r1.isEmpty(); // FALSE
+ r3.isNull(); // TRUE
+ r3.isEmpty(); // TRUE
+ r3 = r1.intersect( r2 ); // r3 = intersection of r1 and r2
+ r3.isNull(); // FALSE
+ r3.isEmpty(); // TRUE
+ r3 = r1.unite( r2 ); // r3 = union of r1 and r2
+ r3.isNull(); // FALSE
+ r3.isEmpty(); // FALSE
+ \endcode
+
+ \sa isNull()
+*/
+
+bool TQRegion::isEmpty() const
+{
+ return data->is_null || ( data->region->numRects == 0 );
+}
+
+
+/*!
+ Returns TRUE if the region tqcontains the point \a p; otherwise
+ returns FALSE.
+*/
+
+bool TQRegion::tqcontains( const TQPoint &p ) const
+{
+ return PointInRegion( data->region, p.x(), p.y() );
+}
+
+/*!
+ \overload
+
+ Returns TRUE if the region overlaps the rectangle \a r; otherwise
+ returns FALSE.
+*/
+
+bool TQRegion::tqcontains( const TQRect &r ) const
+{
+ return RectInRegion( data->region, r.left(), r.top(),
+ r.width(), r.height() ) != RectangleOut;
+}
+
+
+/*!
+ Translates (moves) the region \a dx along the X axis and \a dy
+ along the Y axis.
+*/
+
+void TQRegion::translate( int dx, int dy )
+{
+ if ( empty_region && data == empty_region->data )
+ return;
+ detach();
+ OffsetRegion( data->region, dx, dy );
+ if ( data->xrectangles ) {
+ free( data->xrectangles );
+ data->xrectangles = 0;
+ }
+}
+
+
+/*!
+ Returns a region which is the union of this region and \a r.
+
+ \img runion.png Region Union
+
+ The figure shows the union of two elliptical regions.
+*/
+
+TQRegion TQRegion::unite( const TQRegion &r ) const
+{
+ TQRegion result( FALSE );
+ UnionRegion( data->region, r.data->region, result.data->region );
+ return result;
+}
+
+/*!
+ Returns a region which is the intersection of this region and \a r.
+
+ \img rintersect.png Region Intersection
+
+ The figure shows the intersection of two elliptical regions.
+*/
+
+TQRegion TQRegion::intersect( const TQRegion &r ) const
+{
+ TQRegion result( FALSE );
+ IntersectRegion( data->region, r.data->region, result.data->region );
+ return result;
+}
+
+/*!
+ Returns a region which is \a r subtracted from this region.
+
+ \img rsubtract.png Region Subtraction
+
+ The figure shows the result when the ellipse on the right is
+ subtracted from the ellipse on the left. (\c left-right )
+*/
+
+TQRegion TQRegion::subtract( const TQRegion &r ) const
+{
+ TQRegion result( FALSE );
+ SubtractRegion( data->region, r.data->region, result.data->region );
+ return result;
+}
+
+/*!
+ Returns a region which is the exclusive or (XOR) of this region
+ and \a r.
+
+ \img rxor.png Region XORed
+
+ The figure shows the exclusive or of two elliptical regions.
+*/
+
+TQRegion TQRegion::eor( const TQRegion &r ) const
+{
+ TQRegion result( FALSE );
+ XorRegion( data->region, r.data->region, result.data->region );
+ return result;
+}
+
+/*!
+ Returns the bounding rectangle of this region. An empty region
+ gives a rectangle that is TQRect::isNull().
+*/
+
+TQRect TQRegion::boundingRect() const
+{
+ return data->region->extents;
+}
+
+
+/*!
+ Returns an array of non-overlapping rectangles that make up the
+ region.
+
+ The union of all the rectangles is equal to the original region.
+*/
+
+TQMemArray<TQRect> TQRegion::rects() const
+{
+ TQMemArray<TQRect> rects;
+ rects.duplicate( data->region->rects, data->region->numRects );
+ return rects;
+}
+
+/*!
+ Sets the region to be the given set of rectangles. The rectangles
+ \e must be optimal Y-X sorted bands as follows:
+ <ul>
+ <li> The rectangles must not intersect
+ <li> All rectangles with a given top coordinate must have the same height.
+ <li> No two rectangles may abut horizontally (they should be combined
+ into a single wider rectangle in that case).
+ <li> The rectangles must be sorted ascendingly by Y as the major sort key
+ and X as the minor sort key.
+ </ul>
+ \internal
+ Only some platforms have that restriction (TQWS and X11).
+*/
+void TQRegion::setRects( const TQRect *rects, int num )
+{
+ *this = TQRegion( FALSE );
+ if ( !rects || (num == 1 && rects->isEmpty()) )
+ num = 0;
+
+ data->region->rects.duplicate( rects, num );
+ data->region->numRects = num;
+ if ( num == 0 ) {
+ data->region->extents = TQRect();
+ } else {
+ int left = INT_MAX, right = INT_MIN, top = INT_MAX, bottom = INT_MIN;
+ int i;
+ for ( i = 0; i < num; i++ ) {
+ left = TQMIN( rects[i].left(), left );
+ right = TQMAX( rects[i].right(), right );
+ top = TQMIN( rects[i].top(), top );
+ bottom = TQMAX( rects[i].bottom(), bottom );
+ }
+ data->region->extents = TQRect( TQPoint(left, top), TQPoint(right, bottom) );
+ }
+}
+
+/*!
+ Returns TRUE if the region is equal to \a r; otherwise returns
+ FALSE.
+*/
+
+bool TQRegion::operator==( const TQRegion &r ) const
+{
+ return data == r.data ?
+ TRUE : EqualRegion( data->region, r.data->region );
+}
+
+/*!
+ \fn bool TQRegion::operator!=( const TQRegion &r ) const
+
+ Returns TRUE if the region is different from \a r; otherwise
+ returns FALSE.
+*/
+
+/*
+ This is how X represents regions internally.
+*/
+
+struct BOX {
+ short x1, x2, y1, y2;
+};
+
+struct _XRegion {
+ long size;
+ long numRects;
+ BOX *rects;
+ BOX extents;
+};
+
+
+void TQRegion::updateX11Region() const
+{
+ data->rgn = XCreateRegion();
+
+ for( int i = 0; i < data->region->numRects; i++ ) {
+ XRectangle r;
+ const TQRect &rect = data->region->rects[i];
+ r.x = TQMAX( SHRT_MIN, rect.x() );
+ r.y = TQMAX( SHRT_MIN, rect.y() );
+ r.width = TQMIN( USHRT_MAX, rect.width() );
+ r.height = TQMIN( USHRT_MAX, rect.height() );
+ XUnionRectWithRegion( &r, data->rgn, data->rgn );
+ }
+}
+
+
+void *TQRegion::clipRectangles( int &num ) const
+{
+ if ( !data->xrectangles ) {
+ XRectangle *r = (XRectangle *) malloc( data->region->numRects * sizeof( XRectangle ) );
+ data->xrectangles = r;
+ for( int i = 0; i < data->region->numRects; i++ ) {
+ const TQRect &rect = data->region->rects[i];
+ r->x = TQMAX( SHRT_MIN, rect.x() );
+ r->y = TQMAX( SHRT_MIN, rect.y() );
+ r->width = TQMIN( USHRT_MAX, rect.width() );
+ r->height = TQMIN( USHRT_MAX, rect.height() );
+ r++;
+ }
+ }
+ num = data->region->numRects;
+ return data->xrectangles;
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqrichtext.cpp b/tqtinterface/qt4/src/kernel/tqrichtext.cpp
new file mode 100644
index 0000000..8b614d6
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqrichtext.cpp
@@ -0,0 +1,16615 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+// #if 0
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqrichtext_p.h"
+
+#ifndef QT_NO_RICHTEXT
+
+#include "Qt/qbitmap.h"
+#include "Qt/qapplication.h"
+#include "tqcleanuphandler.h"
+#include "Qt/qcursor.h"
+#include "Qt/qdatastream.h"
+#include "tqdragobject.h"
+#include "Qt/qdrawutil.h"
+#include "Qt/qfile.h"
+#include "Qt/qfileinfo.h"
+#include "Qt/qfont.h"
+#include "Qt/qimage.h"
+#include "Qt/qmap.h"
+#include "Qt/qmime.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqpainter.h"
+#include "tqstringlist.h"
+#include "Qt/qstyle.h"
+#include "Qt/qstyleoption.h"
+#include "tqstylesheet.h"
+#include "Qt/qtextstream.h"
+#include "private/qt4_qtextengine_p.h"
+// #include <private/qunicodetables_p.h>
+
+#include <stdlib.h>
+
+#if defined(Q_WS_X11)
+// #include "qx11info_x11.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+
+static TQTextCursor* richTextExportStart = 0;
+static TQTextCursor* richTextExportEnd = 0;
+
+class TQTextFormatCollection;
+
+const int border_tolerance = 2;
+
+#ifdef Q_WS_WIN
+QT_BEGIN_INCLUDE_NAMESPACE
+#include "qt_windows.h"
+QT_END_INCLUDE_NAMESPACE
+#endif
+
+static inline bool is_printer(TQPainter *p)
+{
+ if (!p || !p->device())
+ return false;
+ return p->device()->devType() == QInternal::Printer;
+}
+
+static inline int scale(int value, TQPainter *painter)
+{
+ if (is_printer(painter)) {
+ TQPaintDeviceMetrics metrics(painter->device());
+#if defined(Q_WS_X11)
+ value = value * metrics.logicalDpiY() /
+ QX11Info::appDpiY(painter->tqdevice()->x11Screen());
+#elif defined (Q_WS_WIN)
+ HDC hdc = GetDC(0);
+ int gdc = GetDeviceCaps(hdc, LOGPIXELSY);
+ if (gdc)
+ value = value * metrics.logicalDpiY() / gdc;
+ ReleaseDC(0, hdc);
+#elif defined (Q_WS_MAC)
+ value = value * metrics.logicalDpiY() / 75; // ##### FIXME
+#elif defined (Q_WS_QWS)
+ value = value * metrics.logicalDpiY() / 75;
+#endif
+ }
+ return value;
+}
+
+
+static inline bool isBreakable(TQTextString *string, int pos)
+{
+ if (string->at(pos).nobreak)
+ return false;
+ return (pos < string->length()-1 && string->at(pos+1).softBreak);
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+void TQTextCommandHistory::addCommand(TQTextCommand *cmd)
+{
+ if (current < history.count() - 1) {
+ QList<TQTextCommand *> commands;
+
+ for (int i = 0; i <= current; ++i)
+ commands.insert(i, history.takeFirst());
+
+ commands.append(cmd);
+ while (!history.isEmpty())
+ delete history.takeFirst();
+ history = commands;
+ } else {
+ history.append(cmd);
+ }
+
+ if (history.count() > steps)
+ delete history.takeFirst();
+ else
+ ++current;
+}
+
+TQTextCursor *TQTextCommandHistory::undo(TQTextCursor *c)
+{
+ if (current > -1) {
+ TQTextCursor *c2 = history.at(current)->unexecute(c);
+ --current;
+ return c2;
+ }
+ return 0;
+}
+
+TQTextCursor *TQTextCommandHistory::redo(TQTextCursor *c)
+{
+ if (current > -1) {
+ if (current < history.count() - 1) {
+ ++current;
+ return history.at(current)->execute(c);
+ }
+ } else {
+ if (history.count() > 0) {
+ ++current;
+ return history.at(current)->execute(c);
+ }
+ }
+ return 0;
+}
+
+bool TQTextCommandHistory::isUndoAvailable()
+{
+ return current > -1;
+}
+
+bool TQTextCommandHistory::isRedoAvailable()
+{
+ return (current > -1 && current < history.count() - 1) || (current == -1 && history.count() > 0);
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextDeleteCommand::TQTextDeleteCommand(TQTextDocument *dc, int i, int idx, const QVector<TQTextStringChar> &str,
+ const QByteArray& oldStyleInfo)
+ : TQTextCommand(dc), id(i), index(idx), parag(0), text(str), styleInformation(oldStyleInfo)
+{
+ for (int j = 0; j < (int)text.size(); ++j) {
+ if (text[j].format())
+ text[j].format()->addRef();
+ }
+}
+
+TQTextDeleteCommand::TQTextDeleteCommand(TQTextParagraph *p, int idx, const QVector<TQTextStringChar> &str)
+ : TQTextCommand(0), id(-1), index(idx), parag(p), text(str)
+{
+ for (int i = 0; i < (int)text.size(); ++i) {
+ if (text[i].format())
+ text[i].format()->addRef();
+ }
+}
+
+TQTextDeleteCommand::~TQTextDeleteCommand()
+{
+ for (int i = 0; i < (int)text.size(); ++i) {
+ if (text[i].format())
+ text[i].format()->removeRef();
+ }
+ text.resize(0);
+}
+
+TQTextCursor *TQTextDeleteCommand::execute(TQTextCursor *c)
+{
+ TQTextParagraph *s = doc ? doc->paragAt(id) : parag;
+ if (!s) {
+ qWarning("can't locate parag at %d, last parag: %d", id, doc->lastParagraph()->paragId());
+ return 0;
+ }
+
+ cursor.setParagraph(s);
+ cursor.setIndex(index);
+ int len = text.size();
+ if (c)
+ *c = cursor;
+ if (doc) {
+ doc->setSelectionStart(TQTextDocument::Temp, cursor);
+ for (int i = 0; i < len; ++i)
+ cursor.gotoNextLetter();
+ doc->setSelectionEnd(TQTextDocument::Temp, cursor);
+ doc->removeSelectedText(TQTextDocument::Temp, &cursor);
+ if (c)
+ *c = cursor;
+ } else {
+ s->remove(index, len);
+ }
+
+ return c;
+}
+
+TQTextCursor *TQTextDeleteCommand::unexecute(TQTextCursor *c)
+{
+ TQTextParagraph *s = doc ? doc->paragAt(id) : parag;
+ if (!s) {
+ qWarning("can't locate parag at %d, last parag: %d", id, doc->lastParagraph()->paragId());
+ return 0;
+ }
+
+ cursor.setParagraph(s);
+ cursor.setIndex(index);
+ TQString str = TQTextString::toString(text);
+ cursor.insert(str, true, &text);
+ if (c)
+ *c = cursor;
+ cursor.setParagraph(s);
+ cursor.setIndex(index);
+
+#ifndef QT_NO_DATASTREAM
+ if (!styleInformation.isEmpty()) {
+ QDataStream styleStream(&styleInformation, IO_ReadOnly);
+ int num;
+ styleStream >> num;
+ TQTextParagraph *p = s;
+ while (num-- && p) {
+ p->readStyleInformation(styleStream);
+ p = p->next();
+ }
+ }
+#endif
+ s = cursor.paragraph();
+ while (s) {
+ s->format();
+ s->setChanged(true);
+ if (s == c->paragraph())
+ break;
+ s = s->next();
+ }
+
+ return &cursor;
+}
+
+TQTextFormatCommand::TQTextFormatCommand(TQTextDocument *dc, int sid, int sidx, int eid, int eidx,
+ const QVector<TQTextStringChar> &old, TQTextFormat *f, int fl)
+ : TQTextCommand(dc), startId(sid), startIndex(sidx), endId(eid), endIndex(eidx), format(f), oldFormats(old), flags(fl)
+{
+ format = dc->formatCollection()->format(f);
+ for (int j = 0; j < (int)oldFormats.size(); ++j) {
+ if (oldFormats[j].format())
+ oldFormats[j].format()->addRef();
+ }
+}
+
+TQTextFormatCommand::~TQTextFormatCommand()
+{
+ format->removeRef();
+ for (int j = 0; j < (int)oldFormats.size(); ++j) {
+ if (oldFormats[j].format())
+ oldFormats[j].format()->removeRef();
+ }
+}
+
+TQTextCursor *TQTextFormatCommand::execute(TQTextCursor *c)
+{
+ TQTextParagraph *sp = doc->paragAt(startId);
+ TQTextParagraph *ep = doc->paragAt(endId);
+ if (!sp || !ep)
+ return c;
+
+ TQTextCursor start(doc);
+ start.setParagraph(sp);
+ start.setIndex(startIndex);
+ TQTextCursor end(doc);
+ end.setParagraph(ep);
+ end.setIndex(endIndex);
+
+ doc->setSelectionStart(TQTextDocument::Temp, start);
+ doc->setSelectionEnd(TQTextDocument::Temp, end);
+ doc->setFormat(TQTextDocument::Temp, format, flags);
+ doc->removeSelection(TQTextDocument::Temp);
+ if (endIndex == ep->length())
+ end.gotoLeft();
+ *c = end;
+ return c;
+}
+
+TQTextCursor *TQTextFormatCommand::unexecute(TQTextCursor *c)
+{
+ TQTextParagraph *sp = doc->paragAt(startId);
+ TQTextParagraph *ep = doc->paragAt(endId);
+ if (!sp || !ep)
+ return 0;
+
+ int idx = startIndex;
+ int fIndex = 0;
+ while ( fIndex < int(oldFormats.size()) ) {
+ if (oldFormats.at(fIndex).c == TQLatin1Char('\n')) {
+ if (idx > 0) {
+ if (idx < sp->length() && fIndex > 0)
+ sp->setFormat(idx, 1, oldFormats.at(fIndex - 1).format());
+ if (sp == ep)
+ break;
+ sp = sp->next();
+ idx = 0;
+ }
+ fIndex++;
+ }
+ if (oldFormats.at(fIndex).format())
+ sp->setFormat(idx, 1, oldFormats.at(fIndex).format());
+ idx++;
+ fIndex++;
+ if (fIndex >= (int)oldFormats.size())
+ break;
+ if (idx >= sp->length()) {
+ if (sp == ep)
+ break;
+ sp = sp->next();
+ idx = 0;
+ }
+ }
+
+ TQTextCursor end(doc);
+ end.setParagraph(ep);
+ end.setIndex(endIndex);
+ if (endIndex == ep->length())
+ end.gotoLeft();
+ *c = end;
+ return c;
+}
+
+TQTextStyleCommand::TQTextStyleCommand(TQTextDocument *dc, int fParag, int lParag, const QByteArray& beforeChange)
+ : TQTextCommand(dc), firstParag(fParag), lastParag(lParag), before(beforeChange)
+{
+ after = readStyleInformation( dc, fParag, lParag);
+}
+
+
+QByteArray TQTextStyleCommand::readStyleInformation( TQTextDocument* doc, int fParag, int lParag)
+{
+ QByteArray style;
+#ifndef QT_NO_DATASTREAM
+ TQTextParagraph *p = doc->paragAt(fParag);
+ if (!p)
+ return style;
+ QDataStream styleStream(&style, IO_WriteOnly);
+ int num = lParag - fParag + 1;
+ styleStream << num;
+ while (num -- && p) {
+ p->writeStyleInformation(styleStream);
+ p = p->next();
+ }
+#endif
+ return style;
+}
+
+void TQTextStyleCommand::writeStyleInformation( TQTextDocument* doc, int fParag, const QByteArray& style)
+{
+#ifndef QT_NO_DATASTREAM
+ TQTextParagraph *p = doc->paragAt(fParag);
+ if (!p)
+ return;
+ QByteArray copy = style;
+ QDataStream styleStream(&copy, IO_ReadOnly);
+ int num;
+ styleStream >> num;
+ while (num-- && p) {
+ p->readStyleInformation(styleStream);
+ p = p->next();
+ }
+#endif
+}
+
+TQTextCursor *TQTextStyleCommand::execute(TQTextCursor *c)
+{
+ writeStyleInformation(doc, firstParag, after);
+ return c;
+}
+
+TQTextCursor *TQTextStyleCommand::unexecute(TQTextCursor *c)
+{
+ writeStyleInformation(doc, firstParag, before);
+ return c;
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextCursor::TQTextCursor(TQTextDocument *dc)
+ : idx(0), tmpX(-1), ox(0), oy(0),
+ valid(true)
+{
+ para = dc ? dc->firstParagraph() : 0;
+}
+
+TQTextCursor::TQTextCursor(const TQTextCursor &c)
+{
+ ox = c.ox;
+ oy = c.oy;
+ idx = c.idx;
+ para = c.para;
+ tmpX = c.tmpX;
+ indices = c.indices;
+ paras = c.paras;
+ xOffsets = c.xOffsets;
+ yOffsets = c.yOffsets;
+ valid = c.valid;
+}
+
+TQTextCursor::~TQTextCursor()
+{
+}
+
+TQTextCursor &TQTextCursor::operator=(const TQTextCursor &c)
+{
+ ox = c.ox;
+ oy = c.oy;
+ idx = c.idx;
+ para = c.para;
+ tmpX = c.tmpX;
+ indices = c.indices;
+ paras = c.paras;
+ xOffsets = c.xOffsets;
+ yOffsets = c.yOffsets;
+ valid = c.valid;
+
+ return *this;
+}
+
+bool TQTextCursor::operator==(const TQTextCursor &c) const
+{
+ return para == c.para && idx == c.idx;
+}
+
+int TQTextCursor::totalOffsetX() const
+{
+ int xoff = ox;
+ for (QStack<int>::ConstIterator xit = xOffsets.begin(); xit != xOffsets.end(); ++xit)
+ xoff += *xit;
+ return xoff;
+}
+
+int TQTextCursor::totalOffsetY() const
+{
+ int yoff = oy;
+ for (QStack<int>::ConstIterator yit = yOffsets.begin(); yit != yOffsets.end(); ++yit)
+ yoff += *yit;
+ return yoff;
+}
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+void TQTextCursor::gotoIntoNested(const QPoint &globalPos)
+{
+ if (!para)
+ return;
+ Q_ASSERT(para->at(idx)->isCustom());
+ push();
+ ox = 0;
+ int bl, y;
+ para->lineHeightOfChar(idx, &bl, &y);
+ oy = y + para->rect().y();
+ ox = para->at(idx)->x;
+ TQTextDocument* doc = document();
+ para->at(idx)->customItem()->enterAt(this, doc, para, idx, ox, oy, globalPos-QPoint(ox,oy));
+}
+#endif
+
+void TQTextCursor::invalidateNested()
+{
+ if (nestedDepth()) {
+ QStack<TQTextParagraph*>::Iterator it = paras.begin();
+ QStack<int>::Iterator it2 = indices.begin();
+ for (; it != paras.end(); ++it, ++it2) {
+ if (*it == para)
+ continue;
+ (*it)->invalidate(0);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if ((*it)->at(*it2)->isCustom())
+ (*it)->at(*it2)->customItem()->invalidate();
+#endif
+ }
+ }
+}
+
+void TQTextCursor::insert(const QString &str, bool checkNewLine, QVector<TQTextStringChar> *formatting)
+{
+ tmpX = -1;
+ bool justInsert = true;
+ TQString s(str);
+#if defined(Q_WS_WIN)
+ if (checkNewLine) {
+ int i = 0;
+ while ((i = s.indexOf(TQLatin1Char('\r'), i)) != -1)
+ s.remove(i ,1);
+ }
+#endif
+ if (checkNewLine)
+ justInsert = s.indexOf(TQLatin1Char('\n')) == -1;
+ if (justInsert) { // we ignore new lines and insert all in the current para at the current index
+ para->insert(idx, s.unicode(), s.length());
+ if (formatting) {
+ for (int i = 0; i < (int)s.length(); ++i) {
+ if (formatting->at(i).format()) {
+ formatting->at(i).format()->addRef();
+ para->string()->setFormat(idx + i, formatting->at(i).format(), true);
+ }
+ }
+ }
+ idx += s.length();
+ } else { // we split at new lines
+ int start = -1;
+ int end;
+ int y = para->rect().y() + para->rect().height();
+ int lastIndex = 0;
+ do {
+ end = s.indexOf(TQLatin1Char('\n'), start + 1); // find line break
+ if (end == -1) // didn't find one, so end of line is end of string
+ end = s.length();
+ int len = (start == -1 ? end : end - start - 1);
+ if (len > 0) // insert the line
+ para->insert(idx, s.unicode() + start + 1, len);
+ else
+ para->invalidate(0);
+ if (formatting) { // set formats to the chars of the line
+ for (int i = 0; i < len; ++i) {
+ if (formatting->at(i + lastIndex).format()) {
+ formatting->at(i + lastIndex).format()->addRef();
+ para->string()->setFormat(i + idx, formatting->at(i + lastIndex).format(), true);
+ }
+ }
+ lastIndex += len;
+ }
+ start = end; // next start is at the end of this line
+ idx += len; // increase the index of the cursor to the end of the inserted text
+ if (s[end] == TQLatin1Char('\n')) { // if at the end was a line break, break the line
+ splitAndInsertEmptyParagraph(false, true);
+ para->setEndState(-1);
+ para->prev()->format(-1, false);
+ lastIndex++;
+ }
+
+ } while (end < (int)s.length());
+
+ para->format(-1, false);
+ int dy = para->rect().y() + para->rect().height() - y;
+ TQTextParagraph *p = para;
+ p->setParagId(p->prev() ? p->prev()->paragId() + 1 : 0);
+ p = p->next();
+ while (p) {
+ p->setParagId(p->prev()->paragId() + 1);
+ p->move(dy);
+ p->invalidate(0);
+ p->setEndState(-1);
+ p = p->next();
+ }
+ }
+
+ int h = para->rect().height();
+ para->format(-1, true);
+ if (h != para->rect().height())
+ invalidateNested();
+ else if (para->document() && para->document()->parent())
+ para->document()->nextDoubleBuffered = true;
+
+ fixCursorPosition();
+}
+
+void TQTextCursor::gotoLeft()
+{
+ if (para->string()->isRightToLeft())
+ gotoNextLetter();
+ else
+ gotoPreviousLetter();
+}
+
+void TQTextCursor::gotoPreviousLetter()
+{
+ tmpX = -1;
+
+ if (idx > 0) {
+ idx = para->string()->previousCursorPosition(idx);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ const TQTextStringChar *tsc = para->at(idx);
+ if (tsc && tsc->isCustom() && tsc->customItem()->isNested())
+ processNesting(EnterEnd);
+#endif
+ } else if (para->prev()) {
+ para = para->prev();
+ while (!para->isVisible() && para->prev())
+ para = para->prev();
+ idx = para->length() - 1;
+ } else if (nestedDepth()) {
+ pop();
+ processNesting(Prev);
+ if (idx == -1) {
+ pop();
+ if (idx > 0) {
+ idx = para->string()->previousCursorPosition(idx);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ const TQTextStringChar *tsc = para->at(idx);
+ if (tsc && tsc->isCustom() && tsc->customItem()->isNested())
+ processNesting(EnterEnd);
+#endif
+ } else if (para->prev()) {
+ para = para->prev();
+ idx = para->length() - 1;
+ }
+ }
+ }
+}
+
+void TQTextCursor::push()
+{
+ indices.push(idx);
+ paras.push(para);
+ xOffsets.push(ox);
+ yOffsets.push(oy);
+}
+
+void TQTextCursor::pop()
+{
+ if (indices.isEmpty())
+ return;
+ idx = indices.pop();
+ para = paras.pop();
+ ox = xOffsets.pop();
+ oy = yOffsets.pop();
+}
+
+void TQTextCursor::restoreState()
+{
+ while (!indices.isEmpty())
+ pop();
+}
+
+bool TQTextCursor::place(const QPoint &p, TQTextParagraph *s, bool link)
+{
+ QPoint pos(p);
+ TQRect r;
+ TQTextParagraph *str = s;
+ if (pos.y() < s->rect().y()) {
+ pos.setY(s->rect().y());
+#ifdef Q_WS_MAC
+ pos.setX(s->rect().x());
+#endif
+ }
+ while (s) {
+ r = s->rect();
+ r.setWidth(document() ? document()->width() : QWIDGETSIZE_MAX);
+ if (s->isVisible())
+ str = s;
+ if (pos.y() >= r.y() && pos.y() <= r.y() + r.height())
+ break;
+ if (!s->next()) {
+#ifdef Q_WS_MAC
+ pos.setX(s->rect().x() + s->rect().width());
+#endif
+ break;
+ }
+ s = s->next();
+ }
+
+ if (!s || !str)
+ return false;
+
+ s = str;
+
+ setParagraph(s);
+ int y = s->rect().y();
+ int lines = s->lines();
+ TQTextStringChar *chr = 0;
+ int index = 0;
+ int i = 0;
+ int cy = 0;
+ int ch = 0;
+ for (; i < lines; ++i) {
+ chr = s->lineStartOfLine(i, &index);
+ cy = s->lineY(i);
+ ch = s->lineHeight(i);
+ if (!chr)
+ return false;
+ if (pos.y() <= y + cy + ch)
+ break;
+ }
+ int nextLine;
+ if (i < lines - 1)
+ s->lineStartOfLine(i+1, &nextLine);
+ else
+ nextLine = s->length();
+ i = index;
+ int x = s->rect().x();
+ if (pos.x() < x)
+ pos.setX(x + 1);
+ int cw;
+ int curpos = s->length()-1;
+ int dist = 10000000;
+ bool inCustom = false;
+ while (i < nextLine) {
+ chr = s->at(i);
+ int cpos = x + chr->x;
+ cw = s->string()->width(i);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (chr->isCustom() && chr->customItem()->isNested()) {
+ if (pos.x() >= cpos && pos.x() <= cpos + cw &&
+ pos.y() >= y + cy && pos.y() <= y + cy + chr->height()) {
+ inCustom = true;
+ curpos = i;
+ break;
+ }
+ } else
+#endif
+ {
+ if(chr->rightToLeft)
+ cpos += cw;
+ int diff = cpos - pos.x();
+ bool dm = diff < 0 ? !chr->rightToLeft : chr->rightToLeft;
+ if ((QABS(diff) < dist || (dist == diff && dm == true)) && para->string()->validCursorPosition(i)) {
+ dist = QABS(diff);
+ if (!link || pos.x() >= x + chr->x)
+ curpos = i;
+ }
+ }
+ i++;
+ }
+ setIndex(curpos);
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (inCustom && para->document() && para->at(curpos)->isCustom() && para->at(curpos)->customItem()->isNested()) {
+ TQTextDocument *oldDoc = para->document();
+ gotoIntoNested(pos);
+ if (oldDoc == para->document())
+ return true;
+ QPoint p(pos.x() - offsetX(), pos.y() - offsetY());
+ if (!place(p, document()->firstParagraph(), link))
+ pop();
+ }
+#endif
+ return true;
+}
+
+bool TQTextCursor::processNesting(Operation op)
+{
+ if (!para->document())
+ return false;
+ TQTextDocument* doc = para->document();
+ push();
+ ox = para->at(idx)->x;
+ int bl, y;
+ para->lineHeightOfChar(idx, &bl, &y);
+ oy = y + para->rect().y();
+ bool ok = false;
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ switch (op) {
+ case EnterBegin:
+ ok = para->at(idx)->customItem()->enter(this, doc, para, idx, ox, oy);
+ break;
+ case EnterEnd:
+ ok = para->at(idx)->customItem()->enter(this, doc, para, idx, ox, oy, true);
+ break;
+ case Next:
+ ok = para->at(idx)->customItem()->next(this, doc, para, idx, ox, oy);
+ break;
+ case Prev:
+ ok = para->at(idx)->customItem()->prev(this, doc, para, idx, ox, oy);
+ break;
+ case Down:
+ ok = para->at(idx)->customItem()->down(this, doc, para, idx, ox, oy);
+ break;
+ case Up:
+ ok = para->at(idx)->customItem()->up(this, doc, para, idx, ox, oy);
+ break;
+ }
+ if (!ok)
+#endif
+ pop();
+ return ok;
+}
+
+void TQTextCursor::gotoRight()
+{
+ if (para->string()->isRightToLeft())
+ gotoPreviousLetter();
+ else
+ gotoNextLetter();
+}
+
+void TQTextCursor::gotoNextLetter()
+{
+ tmpX = -1;
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ const TQTextStringChar *tsc = para->at(idx);
+ if (tsc && tsc->isCustom() && tsc->customItem()->isNested()) {
+ if (processNesting(EnterBegin))
+ return;
+ }
+#endif
+
+ if (idx < para->length() - 1) {
+ idx = para->string()->nextCursorPosition(idx);
+ } else if (para->next()) {
+ para = para->next();
+ while (!para->isVisible() && para->next())
+ para = para->next();
+ idx = 0;
+ } else if (nestedDepth()) {
+ pop();
+ processNesting(Next);
+ if (idx == -1) {
+ pop();
+ if (idx < para->length() - 1) {
+ idx = para->string()->nextCursorPosition(idx);
+ } else if (para->next()) {
+ para = para->next();
+ idx = 0;
+ }
+ }
+ }
+}
+
+void TQTextCursor::gotoUp()
+{
+ int indexOfLineStart;
+ int line;
+ TQTextStringChar *c = para->lineStartOfChar(idx, &indexOfLineStart, &line);
+ if (!c)
+ return;
+
+ if (tmpX < 0)
+ tmpX = x();
+
+ if (indexOfLineStart == 0) {
+ if (!para->prev()) {
+ if (!nestedDepth())
+ return;
+ pop();
+ processNesting(Up);
+ if (idx == -1) {
+ pop();
+ if (!para->prev())
+ return;
+ idx = tmpX = 0;
+ } else {
+ tmpX = -1;
+ return;
+ }
+ }
+ TQTextParagraph *p = para->prev();
+ while (p && !p->isVisible())
+ p = p->prev();
+ if (p)
+ para = p;
+ int lastLine = para->lines() - 1;
+ if (!para->lineStartOfLine(lastLine, &indexOfLineStart))
+ return;
+ idx = indexOfLineStart;
+ while (idx < para->length()-1 && para->at(idx)->x < tmpX)
+ ++idx;
+ if (idx > indexOfLineStart &&
+ para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
+ --idx;
+ } else {
+ --line;
+ int oldIndexOfLineStart = indexOfLineStart;
+ if (!para->lineStartOfLine(line, &indexOfLineStart))
+ return;
+ idx = indexOfLineStart;
+ while (idx < oldIndexOfLineStart-1 && para->at(idx)->x < tmpX)
+ ++idx;
+ if (idx > indexOfLineStart &&
+ para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
+ --idx;
+ }
+ fixCursorPosition();
+}
+
+void TQTextCursor::gotoDown()
+{
+ int indexOfLineStart;
+ int line;
+ TQTextStringChar *c = para->lineStartOfChar(idx, &indexOfLineStart, &line);
+ if (!c)
+ return;
+
+ if (tmpX < 0)
+ tmpX = x();
+
+ if (line == para->lines() - 1) {
+ if (!para->next()) {
+ if (!nestedDepth())
+ return;
+ pop();
+ processNesting(Down);
+ if (idx == -1) {
+ pop();
+ if (!para->next())
+ return;
+ idx = tmpX = 0;
+ } else {
+ tmpX = -1;
+ return;
+ }
+ }
+ TQTextParagraph *s = para->next();
+ while (s && !s->isVisible())
+ s = s->next();
+ if (s)
+ para = s;
+ if (!para->lineStartOfLine(0, &indexOfLineStart))
+ return;
+ int end;
+ if (para->lines() == 1)
+ end = para->length();
+ else
+ para->lineStartOfLine(1, &end);
+
+ idx = indexOfLineStart;
+ while (idx < end-1 && para->at(idx)->x < tmpX)
+ ++idx;
+ if (idx > indexOfLineStart &&
+ para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
+ --idx;
+ } else {
+ ++line;
+ int end;
+ if (line == para->lines() - 1)
+ end = para->length();
+ else
+ para->lineStartOfLine(line + 1, &end);
+ if (!para->lineStartOfLine(line, &indexOfLineStart))
+ return;
+ idx = indexOfLineStart;
+ while (idx < end-1 && para->at(idx)->x < tmpX)
+ ++idx;
+ if (idx > indexOfLineStart &&
+ para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
+ --idx;
+ }
+ fixCursorPosition();
+}
+
+void TQTextCursor::gotoLineEnd()
+{
+ tmpX = -1;
+ int indexOfLineStart;
+ int line;
+ TQTextStringChar *c = para->lineStartOfChar(idx, &indexOfLineStart, &line);
+ if (!c)
+ return;
+
+ if (line == para->lines() - 1) {
+ idx = para->length() - 1;
+ } else {
+ c = para->lineStartOfLine(++line, &indexOfLineStart);
+ indexOfLineStart--;
+ idx = indexOfLineStart;
+ }
+}
+
+void TQTextCursor::gotoLineStart()
+{
+ tmpX = -1;
+ int indexOfLineStart;
+ int line;
+ TQTextStringChar *c = para->lineStartOfChar(idx, &indexOfLineStart, &line);
+ if (!c)
+ return;
+
+ idx = indexOfLineStart;
+}
+
+void TQTextCursor::gotoHome()
+{
+ if (topParagraph()->document())
+ gotoPosition(topParagraph()->document()->firstParagraph());
+ else
+ gotoLineStart();
+}
+
+void TQTextCursor::gotoEnd()
+{
+ if (topParagraph()->document() && topParagraph()->document()->lastParagraph()->isValid())
+ gotoPosition(topParagraph()->document()->lastParagraph(),
+ topParagraph()->document()->lastParagraph()->length() - 1);
+ else
+ gotoLineEnd();
+}
+
+void TQTextCursor::gotoPageUp(int visibleHeight)
+{
+ int targetY = globalY() - visibleHeight;
+ TQTextParagraph* old; int index;
+ do {
+ old = para; index = idx;
+ gotoUp();
+ } while ((old != para || index != idx) && globalY() > targetY);
+}
+
+void TQTextCursor::gotoPageDown(int visibleHeight)
+{
+ int targetY = globalY() + visibleHeight;
+ TQTextParagraph* old; int index;
+ do {
+ old = para; index = idx;
+ gotoDown();
+ } while ((old != para || index != idx) && globalY() < targetY);
+}
+
+void TQTextCursor::gotoWordRight()
+{
+ if (para->string()->isRightToLeft())
+ gotoPreviousWord();
+ else
+ gotoNextWord();
+}
+
+void TQTextCursor::gotoWordLeft()
+{
+ if (para->string()->isRightToLeft())
+ gotoNextWord();
+ else
+ gotoPreviousWord();
+}
+
+static bool is_seperator(const TQChar &c, bool onlySpace)
+{
+ if (onlySpace)
+ return c.isSpace();
+ return c.isSpace() ||
+ c == TQLatin1Char('\t') ||
+ c == TQLatin1Char('.') ||
+ c == TQLatin1Char(',') ||
+ c == TQLatin1Char(':') ||
+ c == TQLatin1Char(';') ||
+ c == TQLatin1Char('-') ||
+ c == TQLatin1Char('<') ||
+ c == TQLatin1Char('>') ||
+ c == TQLatin1Char('[') ||
+ c == TQLatin1Char(']') ||
+ c == TQLatin1Char('(') ||
+ c == TQLatin1Char(')') ||
+ c == TQLatin1Char('{') ||
+ c == TQLatin1Char('}');
+}
+
+void TQTextCursor::gotoPreviousWord(bool onlySpace)
+{
+ gotoPreviousLetter();
+ tmpX = -1;
+ TQTextString *s = para->string();
+ bool allowSame = false;
+ if (idx == ((int)s->length()-1))
+ return;
+ for (int i = idx; i >= 0; --i) {
+ if (is_seperator(s->at(i).c, onlySpace)) {
+ if (!allowSame)
+ continue;
+ idx = i + 1;
+ return;
+ }
+ if (!allowSame && !is_seperator(s->at(i).c, onlySpace))
+ allowSame = true;
+ }
+ idx = 0;
+}
+
+void TQTextCursor::gotoNextWord(bool onlySpace)
+{
+ tmpX = -1;
+ TQTextString *s = para->string();
+ bool allowSame = false;
+ for (int i = idx; i < (int)s->length(); ++i) {
+ if (!is_seperator(s->at(i).c, onlySpace)) {
+ if (!allowSame)
+ continue;
+ idx = i;
+ return;
+ }
+ if (!allowSame && is_seperator(s->at(i).c, onlySpace))
+ allowSame = true;
+
+ }
+
+ if (idx < ((int)s->length()-1)) {
+ gotoLineEnd();
+ } else if (para->next()) {
+ TQTextParagraph *p = para->next();
+ while (p && !p->isVisible())
+ p = p->next();
+ if (s) {
+ para = p;
+ idx = 0;
+ }
+ } else {
+ gotoLineEnd();
+ }
+}
+
+bool TQTextCursor::atParagStart()
+{
+ return idx == 0;
+}
+
+bool TQTextCursor::atParagEnd()
+{
+ return idx == para->length() - 1;
+}
+
+void TQTextCursor::splitAndInsertEmptyParagraph(bool ind, bool updateIds)
+{
+ if (!para->document())
+ return;
+ tmpX = -1;
+ TQTextFormat *f = 0;
+ if (para->document()->useFormatCollection()) {
+ f = para->at(idx)->format();
+ if (idx == para->length() - 1 && idx > 0)
+ f = para->at(idx - 1)->format();
+ if (f->isMisspelled()) {
+ f->removeRef();
+ f = para->document()->formatCollection()->format(f->font(), f->color());
+ }
+ }
+
+ if (atParagEnd()) {
+ TQTextParagraph *n = para->next();
+ TQTextParagraph *s = para->document()->createParagraph(para->document(), para, n, updateIds);
+ if (f)
+ s->setFormat(0, 1, f, true);
+ s->copyParagData(para);
+ if (ind) {
+ int oi, ni;
+ s->indent(&oi, &ni);
+ para = s;
+ idx = ni;
+ } else {
+ para = s;
+ idx = 0;
+ }
+ } else if (atParagStart()) {
+ TQTextParagraph *p = para->prev();
+ TQTextParagraph *s = para->document()->createParagraph(para->document(), p, para, updateIds);
+ if (f)
+ s->setFormat(0, 1, f, true);
+ s->copyParagData(para);
+ if (ind) {
+ s->indent();
+ s->format();
+ indent();
+ para->format();
+ }
+ } else {
+ TQString str = para->string()->toString().mid(idx, 0xFFFFFF);
+ TQTextParagraph *n = para->next();
+ TQTextParagraph *s = para->document()->createParagraph(para->document(), para, n, updateIds);
+ s->copyParagData(para);
+ s->remove(0, 1);
+ s->append(str, true);
+ for (int i = 0; i < str.length(); ++i) {
+ TQTextStringChar* tsc = para->at(idx + i);
+ s->setFormat(i, 1, tsc->format(), true);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (tsc->isCustom()) {
+ TQTextCustomItem * item = tsc->customItem();
+ s->at(i)->setCustomItem(item);
+ tsc->loseCustomItem();
+ }
+#endif
+ if (tsc->isAnchor())
+ s->at(i)->setAnchor(tsc->anchorName(),
+ tsc->anchorHref());
+ }
+ para->truncate(idx);
+ if (ind) {
+ int oi, ni;
+ s->indent(&oi, &ni);
+ para = s;
+ idx = ni;
+ } else {
+ para = s;
+ idx = 0;
+ }
+ }
+
+ invalidateNested();
+}
+
+bool TQTextCursor::remove()
+{
+ tmpX = -1;
+ if (!atParagEnd()) {
+ int next = para->string()->nextCursorPosition(idx);
+ para->remove(idx, next-idx);
+ int h = para->rect().height();
+ para->format(-1, true);
+ if (h != para->rect().height())
+ invalidateNested();
+ else if (para->document() && para->document()->parent())
+ para->document()->nextDoubleBuffered = true;
+ return false;
+ } else if (para->next()) {
+ para->join(para->next());
+ invalidateNested();
+ return true;
+ }
+ return false;
+}
+
+/* needed to implement backspace the correct way */
+bool TQTextCursor::removePreviousChar()
+{
+ tmpX = -1;
+ if (!atParagStart()) {
+ para->remove(idx-1, 1);
+ int h = para->rect().height();
+ idx--;
+ // shouldn't be needed, just to make sure.
+ fixCursorPosition();
+ para->format(-1, true);
+ if (h != para->rect().height())
+ invalidateNested();
+ else if (para->document() && para->document()->parent())
+ para->document()->nextDoubleBuffered = true;
+ return false;
+ } else if (para->prev()) {
+ para = para->prev();
+ para->join(para->next());
+ invalidateNested();
+ return true;
+ }
+ return false;
+}
+
+void TQTextCursor::indent()
+{
+ int oi = 0, ni = 0;
+ para->indent(&oi, &ni);
+ if (oi == ni)
+ return;
+
+ if (idx >= oi)
+ idx += ni - oi;
+ else
+ idx = ni;
+}
+
+void TQTextCursor::fixCursorPosition()
+{
+ // searches for the closest valid cursor position
+ if (para->string()->validCursorPosition(idx))
+ return;
+
+ int lineIdx;
+ TQTextStringChar *start = para->lineStartOfChar(idx, &lineIdx, 0);
+ int x = para->string()->at(idx).x;
+ int diff = QABS(start->x - x);
+ int best = lineIdx;
+
+ TQTextStringChar *c = start;
+ ++c;
+
+ TQTextStringChar *end = &para->string()->at(para->length()-1);
+ while (c <= end && !c->lineStart) {
+ int xp = c->x;
+ if (c->rightToLeft)
+ xp += para->string()->width(lineIdx + (c-start));
+ int ndiff = QABS(xp - x);
+ if (ndiff < diff && para->string()->validCursorPosition(lineIdx + (c-start))) {
+ diff = ndiff;
+ best = lineIdx + (c-start);
+ }
+ ++c;
+ }
+ idx = best;
+}
+
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextDocument::TQTextDocument(TQTextDocument *p)
+ : par(p), parentPar(0)
+#ifndef QT_NO_TEXTCUSTOMITEM
+ , tc(0)
+#endif
+ , tArray(0), tStopWidth(0)
+{
+ fCollection = par ? par->fCollection : new TQTextFormatCollection;
+ init();
+}
+
+void TQTextDocument::init()
+{
+ oTextValid = true;
+ mightHaveCustomItems = false;
+ if (par)
+ par->insertChild(this);
+ pProcessor = 0;
+ useFC = true;
+ pFormatter = 0;
+ indenter = 0;
+ fParag = 0;
+ txtFormat = TQt::AutoText;
+ preferRichText = false;
+ pages = false;
+ focusIndicator.parag = 0;
+ minw = 0;
+ wused = 0;
+ minwParag = curParag = 0;
+ align = TQt::AlignAuto;
+ nSelections = 1;
+
+ setStyleSheet(TQStyleSheet::defaultSheet());
+#ifndef QT_NO_MIME
+ factory_ = TQMimeSourceFactory::defaultFactory();
+#endif
+ contxt.clear();
+
+ underlLinks = par ? par->underlLinks : true;
+ backBrush = 0;
+ buf_pixmap = 0;
+ nextDoubleBuffered = false;
+
+ if (par)
+ withoutDoubleBuffer = par->withoutDoubleBuffer;
+ else
+ withoutDoubleBuffer = false;
+
+ lParag = fParag = createParagraph(this, 0, 0);
+
+ cx = 0;
+ cy = 2;
+ if (par)
+ cx = cy = 0;
+ cw = 600;
+ vw = 0;
+ flow_ = new TQTextFlow;
+ flow_->setWidth(cw);
+
+ leftmargin = rightmargin = 4;
+ scaleFontsFactor = 1;
+
+ commandHistory = new TQTextCommandHistory(100);
+ tStopWidth = formatCollection()->defaultFormat()->width(TQLatin1Char('x')) * 8;
+}
+
+TQTextDocument::~TQTextDocument()
+{
+ delete commandHistory;
+ if (par)
+ par->removeChild(this);
+ clear();
+ delete flow_;
+ if (!par) {
+ delete pFormatter;
+ delete fCollection;
+ }
+ delete pProcessor;
+ delete buf_pixmap;
+ delete indenter;
+ delete backBrush;
+ delete [] tArray;
+}
+
+void TQTextDocument::clear(bool createEmptyParag)
+{
+ while (fParag) {
+ TQTextParagraph *p = fParag->next();
+ delete fParag;
+ fParag = p;
+ }
+ if (flow_)
+ flow_->clear();
+ fParag = lParag = 0;
+ if (createEmptyParag)
+ fParag = lParag = createParagraph(this);
+ selections.clear();
+ oText.clear();
+ oTextValid = false;
+}
+
+int TQTextDocument::widthUsed() const
+{
+ return wused + 2*border_tolerance;
+}
+
+int TQTextDocument::height() const
+{
+ int h = 0;
+ if (lParag)
+ h = lParag->rect().top() + lParag->rect().height() + 1;
+ int fh = flow_->boundingRect().bottom();
+ return qMax(h, fh);
+}
+
+
+
+TQTextParagraph *TQTextDocument::createParagraph(TQTextDocument *dc, TQTextParagraph *pr, TQTextParagraph *nx, bool updateIds)
+{
+ return new TQTextParagraph(dc, pr, nx, updateIds);
+}
+
+bool TQTextDocument::setMinimumWidth(int needed, int used, TQTextParagraph *p)
+{
+ if (needed == -1) {
+ minw = 0;
+ wused = 0;
+ p = 0;
+ }
+ if (p == minwParag) {
+ if (minw > needed) {
+ TQTextParagraph *tp = fParag;
+ while (tp) {
+ if (tp != p && tp->minwidth > needed) {
+ needed = tp->minwidth;
+ minwParag = tp;
+ }
+ tp = tp->n;
+ }
+ }
+ minw = needed;
+ emit minimumWidthChanged(minw);
+ } else if (needed > minw) {
+ minw = needed;
+ minwParag = p;
+ emit minimumWidthChanged(minw);
+ }
+ wused = qMax(wused, used);
+ wused = qMax(wused, minw);
+ cw = qMax(minw, cw);
+ return true;
+}
+
+void TQTextDocument::setPlainText(const TQString &text)
+{
+ preferRichText = false;
+ clear();
+ oTextValid = true;
+ oText = text;
+
+ int lastNl = 0;
+ int nl = text.indexOf(TQLatin1Char('\n'));
+ if (nl == -1) {
+ lParag = createParagraph(this, lParag, 0);
+ if (!fParag)
+ fParag = lParag;
+ TQString s = text;
+ if (!s.isEmpty()) {
+ if (s[(int)s.length() - 1] == TQLatin1Char('\r'))
+ s.remove(s.length() - 1, 1);
+ lParag->append(s);
+ }
+ } else {
+ for (;;) {
+ lParag = createParagraph(this, lParag, 0);
+ if (!fParag)
+ fParag = lParag;
+ int l = nl - lastNl;
+ if (l > 0) {
+ if (text.unicode()[nl-1] == TQLatin1Char('\r'))
+ l--;
+ TQString cs = TQString::fromRawData(text.unicode()+lastNl, l);
+ lParag->append(cs);
+ }
+ if (nl == (int)text.length())
+ break;
+ lastNl = nl + 1;
+ nl = text.indexOf(TQLatin1Char('\n'), nl + 1);
+ if (nl == -1)
+ nl = text.length();
+ }
+ }
+ if (!lParag)
+ lParag = fParag = createParagraph(this, 0, 0);
+}
+
+struct TQTextDocumentTag {
+ TQTextDocumentTag(){}
+ TQTextDocumentTag(const TQString&n, const TQStyleSheetItem* s, const TQTextFormat& f)
+ :name(n),style(s), format(f), alignment(TQt::AlignAuto), direction(TQChar::DirON),liststyle(TQStyleSheetItem::ListDisc) {
+ wsm = TQStyleSheetItem::WhiteSpaceNormal;
+ }
+ TQString name;
+ const TQStyleSheetItem* style;
+ TQString anchorHref;
+ TQStyleSheetItem::WhiteSpaceMode wsm;
+ TQTextFormat format;
+ signed int alignment : 16;
+ signed int direction : 5;
+ TQStyleSheetItem::ListStyle liststyle;
+
+ TQTextDocumentTag( const TQTextDocumentTag& t) {
+ name = t.name;
+ style = t.style;
+ anchorHref = t.anchorHref;
+ wsm = t.wsm;
+ format = t.format;
+ alignment = t.alignment;
+ direction = t.direction;
+ liststyle = t.liststyle;
+ }
+ TQTextDocumentTag& operator=(const TQTextDocumentTag& t) {
+ name = t.name;
+ style = t.style;
+ anchorHref = t.anchorHref;
+ wsm = t.wsm;
+ format = t.format;
+ alignment = t.alignment;
+ direction = t.direction;
+ liststyle = t.liststyle;
+ return *this;
+ }
+
+ Q_DUMMY_COMPARISON_OPERATOR(TQTextDocumentTag)
+};
+
+
+#define NEWPAR \
+ do{ \
+ if (!hasNewPar) { \
+ if (!textEditMode && curpar && curpar->length()>1 \
+ && curpar->at(curpar->length()-2)->c == TQChar::LineSeparator) \
+ curpar->remove(curpar->length()-2, 1); \
+ curpar = createParagraph(this, curpar, curpar->next()); \
+ styles.append(vec); \
+ vec = 0; \
+ } \
+ hasNewPar = true; \
+ curpar->rtext = true; \
+ curpar->align = curtag.alignment; \
+ curpar->lstyle = curtag.liststyle; \
+ curpar->litem = (curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem); \
+ curpar->str->setDirection((TQChar::Direction)curtag.direction); \
+ space = true; \
+ tabExpansionColumn = 0; \
+ delete vec; \
+ vec = new QVector<TQStyleSheetItem *>(); \
+ for (QStack<TQTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it) \
+ vec->append(const_cast<TQStyleSheetItem *>((*it).style)); \
+ vec->append(const_cast<TQStyleSheetItem *>(curtag.style)); \
+ } while(false);
+
+
+void TQTextDocument::setRichText(const TQString &text, const TQString &context, const TQTextFormat *initialFormat)
+{
+ preferRichText = true;
+ if (!context.isEmpty())
+ setContext(context);
+ clear();
+ fParag = lParag = createParagraph(this);
+ oTextValid = true;
+ oText = text;
+ setRichTextInternal(text, 0, initialFormat);
+ fParag->rtext = true;
+}
+
+void TQTextDocument::setRichTextInternal(const TQString &text, TQTextCursor* cursor, const TQTextFormat *initialFormat)
+{
+ TQTextParagraph* curpar = lParag;
+ int pos = 0;
+ QStack<TQTextDocumentTag> tags;
+ if (!initialFormat)
+ initialFormat = formatCollection()->defaultFormat();
+ TQTextDocumentTag initag(TQLatin1String(""), sheet_->item(TQLatin1String("")), *initialFormat);
+ if (bodyText.isValid())
+ initag.format.setColor(bodyText);
+ TQTextDocumentTag curtag = initag;
+ bool space = true;
+ bool canMergeLi = false;
+
+ bool textEditMode = false;
+ int tabExpansionColumn = 0;
+
+ const TQChar* doc = static_cast<const TQChar*>(text.unicode());
+ int length = text.length();
+ bool hasNewPar = curpar->length() <= 1;
+ TQString anchorName;
+
+ // style sheet handling for margin and line spacing calculation below
+ TQTextParagraph* stylesPar = curpar;
+ QVector<TQStyleSheetItem *>* vec = 0;
+ QList< QVector<TQStyleSheetItem *> *> styles;
+
+ if (cursor) {
+ cursor->splitAndInsertEmptyParagraph();
+ TQTextCursor tmp = *cursor;
+ tmp.gotoPreviousLetter();
+ stylesPar = curpar = tmp.paragraph();
+ hasNewPar = true;
+ textEditMode = true;
+ } else {
+ NEWPAR;
+ }
+
+ // set rtext spacing to false for the initial paragraph.
+ curpar->rtext = false;
+
+ TQString wellKnownTags = TQLatin1String("br hr wsp table qt body meta title");
+
+ while (pos < length) {
+ if (hasPrefix(doc, length, pos, TQLatin1Char('<'))){
+ if (!hasPrefix(doc, length, pos+1, TQLatin1Char('/'))) {
+ // open tag
+ QMap<TQString, TQString> attr;
+ QMap<TQString, TQString>::Iterator it, end = attr.end();
+ bool emptyTag = false;
+ TQString tagname = parseOpenTag(doc, length, pos, attr, emptyTag);
+ if (tagname.isEmpty())
+ continue; // nothing we could do with this, probably parse error
+
+ const TQStyleSheetItem* nstyle = sheet_->item(tagname);
+
+ if (nstyle) {
+ // we might have to close some 'forgotten' tags
+ while (!nstyle->allowedInContext(curtag.style)) {
+ TQString msg;
+ msg.sprintf("QText Warning: Document not valid ('%s' not allowed in '%s' #%d)",
+ tagname.ascii(), curtag.style->name().ascii(), pos);
+ sheet_->error(msg);
+ if (tags.isEmpty())
+ break;
+ curtag = tags.pop();
+ }
+
+ /* special handling for p and li for HTML
+ compatibility. We do not want to embed blocks in
+ p, and we do not want new blocks inside non-empty
+ lis. Plus we want to merge empty lis sometimes. */
+ if(nstyle->displayMode() == TQStyleSheetItem::DisplayListItem) {
+ canMergeLi = true;
+ } else if (nstyle->displayMode() == TQStyleSheetItem::DisplayBlock) {
+ while (curtag.style->name() == TQLatin1String("p")) {
+ if (tags.isEmpty())
+ break;
+ curtag = tags.pop();
+ }
+
+ if (curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem) {
+ // we are in a li and a new block comes along
+ if (nstyle->name() == TQLatin1String("ul") || nstyle->name() == TQLatin1String("ol"))
+ hasNewPar = false; // we want an empty li (like most browsers)
+ if (!hasNewPar) {
+ /* do not add new blocks inside
+ non-empty lis */
+ while (curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem) {
+ if (tags.isEmpty())
+ break;
+ curtag = tags.pop();
+ }
+ } else if (canMergeLi) {
+ /* we have an empty li and a block
+ comes along, merge them */
+ nstyle = curtag.style;
+ }
+ canMergeLi = false;
+ }
+ }
+ }
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem* custom = 0;
+#else
+ bool custom = false;
+#endif
+
+ // some well-known tags, some have a nstyle, some not
+ if (wellKnownTags.contains(tagname)) {
+ if (tagname == TQLatin1String("br")) {
+ emptyTag = space = true;
+ int index = qMax(curpar->length(),1) - 1;
+ TQTextFormat format = curtag.format.makeTextFormat(nstyle, attr, scaleFontsFactor);
+ curpar->append(TQString(TQChar(TQChar::LineSeparator)));
+ curpar->setFormat(index, 1, &format);
+ hasNewPar = false;
+ } else if (tagname == TQLatin1String("hr")) {
+ emptyTag = space = true;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ custom = tag(sheet_, tagname, attr, contxt, *factory_ , emptyTag, this);
+#endif
+ } else if (tagname == TQLatin1String("table")) {
+ emptyTag = space = true;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ TQTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor);
+ curpar->setAlignment(curtag.alignment);
+ custom = parseTable(attr, format, doc, length, pos, curpar);
+#endif
+ } else if (tagname == TQLatin1String("qt") || tagname == TQLatin1String("body")) {
+ it = attr.find(TQLatin1String("bgcolor"));
+ if (it != end) {
+ TQBrush *b = new TQBrush(QColor(*it));
+ setPaper(b);
+ }
+ it = attr.find(TQLatin1String("background"));
+ if (it != end) {
+#ifndef QT_NO_MIME
+ TQImage img;
+ TQString bg = *it;
+ const QMimeSource* m = factory_->data(bg, contxt);
+ if (!m) {
+ qCritical("QRichText: no mimesource for %s",
+ QFile::encodeName(bg).data());
+ } else {
+ if (!TQImageDrag::decode(TQT_TQMIMESOURCE_CONST(m), img)) {
+ qCritical("TQTextImage: cannot decode %s",
+ QFile::encodeName(bg).data());
+ }
+ }
+ if (!img.isNull()) {
+ TQBrush *b = new TQBrush(QColor(), TQPixmap(img));
+ setPaper(b);
+ }
+#endif
+ }
+ it = attr.find(TQLatin1String("text"));
+ if (it != end) {
+ QColor c(*it);
+ initag.format.setColor(c);
+ curtag.format.setColor(c);
+ bodyText = c;
+ }
+ it = attr.find(TQLatin1String("link"));
+ if (it != end)
+ linkColor = QColor(*it);
+ it = attr.find(TQLatin1String("title"));
+ if (it != end)
+ attribs.insert(TQLatin1String("title"), *it);
+
+ if (textEditMode) {
+ it = attr.find(TQLatin1String("style"));
+ if (it != end) {
+ TQString a = *it;
+ int count = a.count(TQLatin1Char(';')) + 1;
+ for (int s = 0; s < count; s++) {
+ TQString style = a.section(TQLatin1Char(';'), s, s);
+ if (style.startsWith(TQLatin1String("font-size:")) && style.endsWith(TQLatin1String("pt"))) {
+ scaleFontsFactor = double(formatCollection()->defaultFormat()->fn.pointSize()) /
+ style.mid(10, style.length() - 12).toInt();
+ }
+ }
+ }
+ nstyle = 0; // ignore body in textEditMode
+ }
+ // end qt- and body-tag handling
+ } else if (tagname == TQLatin1String("meta")) {
+ if (attr[TQLatin1String("name")] == TQLatin1String("qrichtext") && attr[TQLatin1String("content")] == TQLatin1String("1"))
+ textEditMode = true;
+ } else if (tagname == TQLatin1String("title")) {
+ TQString title;
+ while (pos < length) {
+ if (hasPrefix(doc, length, pos, TQLatin1Char('<')) && hasPrefix(doc, length, pos+1, TQLatin1Char('/')) &&
+ parseCloseTag(doc, length, pos) == TQLatin1String("title"))
+ break;
+ title += doc[pos];
+ ++pos;
+ }
+ attribs.insert(TQLatin1String("title"), title);
+ }
+ } // end of well-known tag handling
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (!custom) // try generic custom item
+ custom = tag(sheet_, tagname, attr, contxt, *factory_ , emptyTag, this);
+#endif
+ if (!nstyle && !custom) // we have no clue what this tag could be, ignore it
+ continue;
+
+ if (custom) {
+#ifndef QT_NO_TEXTCUSTOMITEM
+ int index = qMax(curpar->length(),1) - 1;
+ TQTextFormat format = curtag.format.makeTextFormat(nstyle, attr, scaleFontsFactor);
+ curpar->append(TQString(TQLatin1Char('*')));
+ TQTextFormat* f = formatCollection()->format(&format);
+ curpar->setFormat(index, 1, f);
+ curpar->at(index)->setCustomItem(custom);
+ if (!curtag.anchorHref.isEmpty())
+ curpar->at(index)->setAnchor(TQString(), curtag.anchorHref);
+ if (!anchorName.isEmpty() ) {
+ curpar->at(index)->setAnchor(anchorName, curpar->at(index)->anchorHref());
+ anchorName.clear();
+ }
+ registerCustomItem(custom, curpar);
+ hasNewPar = false;
+#endif
+ } else if (!emptyTag) {
+ /* if we do nesting, push curtag on the stack,
+ otherwise reinint curag. */
+ if (curtag.style->name() != tagname || nstyle->selfNesting()) {
+ tags.push(curtag);
+ } else {
+ if (!tags.isEmpty())
+ curtag = tags.top();
+ else
+ curtag = initag;
+ }
+
+ curtag.name = tagname;
+ curtag.style = nstyle;
+ curtag.name = tagname;
+ curtag.style = nstyle;
+ if (nstyle->whiteSpaceMode() != TQStyleSheetItem::WhiteSpaceModeUndefined)
+ curtag.wsm = nstyle->whiteSpaceMode();
+
+ /* netscape compatibility: eat a newline and only a newline if a pre block starts */
+ if (curtag.wsm == TQStyleSheetItem::WhiteSpacePre &&
+ nstyle->displayMode() == TQStyleSheetItem::DisplayBlock)
+ eat(doc, length, pos, TQLatin1Char('\n'));
+
+ /* ignore whitespace for inline elements if there
+ was already one*/
+ if (!textEditMode &&
+ (curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal
+ || curtag.wsm == TQStyleSheetItem::WhiteSpaceNoWrap)
+ && (space || nstyle->displayMode() != TQStyleSheetItem::DisplayInline))
+ eatSpace(doc, length, pos);
+
+ curtag.format = curtag.format.makeTextFormat(nstyle, attr, scaleFontsFactor);
+ if (nstyle->isAnchor()) {
+ if (!anchorName.isEmpty())
+ anchorName += TQLatin1Char('#') + attr[TQLatin1String("name")];
+ else
+ anchorName = attr[TQLatin1String("name")];
+ curtag.anchorHref = attr[TQLatin1String("href")];
+ }
+
+ if (nstyle->alignment() != TQStyleSheetItem::Undefined)
+ curtag.alignment = nstyle->alignment();
+
+ if (nstyle->listStyle() != TQStyleSheetItem::ListStyleUndefined)
+ curtag.liststyle = nstyle->listStyle();
+
+ if (nstyle->displayMode() == TQStyleSheetItem::DisplayBlock
+ || nstyle->displayMode() == TQStyleSheetItem::DisplayListItem) {
+
+ if (nstyle->name() == TQLatin1String("ol") ||
+ nstyle->name() == TQLatin1String("ul") ||
+ nstyle->name() == TQLatin1String("li")) {
+ TQString type = attr[TQLatin1String("type")];
+ if (!type.isEmpty()) {
+ if (type == TQLatin1String("1")) {
+ curtag.liststyle = TQStyleSheetItem::ListDecimal;
+ } else if (type == TQLatin1String("a")) {
+ curtag.liststyle = TQStyleSheetItem::ListLowerAlpha;
+ } else if (type == TQLatin1String("A")) {
+ curtag.liststyle = TQStyleSheetItem::ListUpperAlpha;
+ } else {
+ type = type.toLower();
+ if (type == TQLatin1String("square"))
+ curtag.liststyle = TQStyleSheetItem::ListSquare;
+ else if (type == TQLatin1String("disc"))
+ curtag.liststyle = TQStyleSheetItem::ListDisc;
+ else if (type == TQLatin1String("circle"))
+ curtag.liststyle = TQStyleSheetItem::ListCircle;
+ }
+ }
+ }
+
+
+ /* Internally we treat ordered and bullet
+ lists the same for margin calculations. In
+ order to have fast pointer compares in the
+ xMargin() functions we restrict ourselves to
+ <ol>. Once we calculate the margins in the
+ parser rathern than later, the unelegance of
+ this approach goes awy
+ */
+ if (nstyle->name() == TQLatin1String("ul"))
+ curtag.style = sheet_->item(TQLatin1String("ol"));
+
+ it = attr.find(TQLatin1String("align"));
+ if (it != end) {
+ TQString align = (*it).toLower();
+ if (align == TQLatin1String("center"))
+ curtag.alignment = Qt::AlignCenter;
+ else if (align == TQLatin1String("right"))
+ curtag.alignment = Qt::AlignRight;
+ else if (align == TQLatin1String("justify"))
+ curtag.alignment = Qt::AlignJustify;
+ }
+ it = attr.find(TQLatin1String("dir"));
+ if (it != end) {
+ TQString dir = (*it).toLower();
+ if (dir == TQLatin1String("rtl"))
+ curtag.direction = TQChar::DirR;
+ else if (dir == TQLatin1String("ltr"))
+ curtag.direction = TQChar::DirL;
+ }
+
+ NEWPAR;
+
+ if (curtag.style && curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem) {
+ it = attr.find(TQLatin1String("value"));
+ if (it != end)
+ curpar->setListValue((*it).toInt());
+ }
+
+ it = attr.find(TQLatin1String("style"));
+ if (it != end) {
+ TQString a = *it;
+ bool ok = true;
+ int count = a.count(TQLatin1Char(';'))+1;
+ for (int s = 0; ok && s < count; s++) {
+ TQString style = a.section(TQLatin1Char(';'), s, s);
+ if (style.startsWith(TQLatin1String("margin-top:")) && style.endsWith(TQLatin1String("px")))
+ curpar->utm = 1+style.mid(11, style.length() - 13).toInt(&ok);
+ else if (style.startsWith(TQLatin1String("margin-bottom:")) && style.endsWith(TQLatin1String("px")))
+ curpar->ubm = 1+style.mid(14, style.length() - 16).toInt(&ok);
+ else if (style.startsWith(TQLatin1String("margin-left:")) && style.endsWith(TQLatin1String("px")))
+ curpar->ulm = 1+style.mid(12, style.length() - 14).toInt(&ok);
+ else if (style.startsWith(TQLatin1String("margin-right:")) && style.endsWith(TQLatin1String("px")))
+ curpar->urm = 1+style.mid(13, style.length() - 15).toInt(&ok);
+ else if (style.startsWith(TQLatin1String("text-indent:")) && style.endsWith(TQLatin1String("px")))
+ curpar->uflm = 1+style.mid(12, style.length() - 14).toInt(&ok);
+ }
+ if (!ok) // be pressmistic
+ curpar->utm = curpar->ubm = curpar->urm = curpar->ulm = 0;
+ }
+ } else if (nstyle->name() == TQLatin1String("html")) {
+ it = attr.find(TQLatin1String("dir"));
+ if (it != end) {
+ TQString dir = (*it).toLower();
+ if (dir == TQLatin1String("rtl"))
+ curtag.direction = TQChar::DirR;
+ else if (dir == TQLatin1String("ltr"))
+ curtag.direction = TQChar::DirL;
+ }
+ }
+ }
+ } else {
+ TQString tagname = parseCloseTag(doc, length, pos);
+ if (tagname.isEmpty())
+ continue; // nothing we could do with this, probably parse error
+ if (!sheet_->item(tagname)) // ignore unknown tags
+ continue;
+ if (tagname == TQLatin1String("li"))
+ continue;
+
+ // we close a block item. Since the text may continue, we need to have a new paragraph
+ bool needNewPar = curtag.style->displayMode() == TQStyleSheetItem::DisplayBlock
+ || curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem;
+
+
+ // html slopiness: handle unbalanched tag closing
+ while (curtag.name != tagname) {
+ TQString msg;
+ msg.sprintf("QText Warning: Document not valid ('%s' not closed before '%s' #%d)",
+ curtag.name.ascii(), tagname.ascii(), pos);
+ sheet_->error(msg);
+ if (tags.isEmpty())
+ break;
+ curtag = tags.pop();
+ }
+
+
+ // close the tag
+ if (!tags.isEmpty())
+ curtag = tags.pop();
+ else
+ curtag = initag;
+
+ if (needNewPar) {
+ if (textEditMode && (tagname == TQLatin1String("p") || tagname == TQLatin1String("div"))) // preserve empty paragraphs
+ hasNewPar = false;
+ NEWPAR;
+ }
+ }
+ } else {
+ // normal contents
+ TQString s;
+ TQChar c;
+ while (pos < length && !hasPrefix(doc, length, pos, TQLatin1Char('<'))){
+ if (textEditMode) {
+ // text edit mode: we handle all white space but ignore newlines
+ c = parseChar(doc, length, pos, TQStyleSheetItem::WhiteSpacePre);
+ if (c == TQChar::LineSeparator)
+ break;
+ } else {
+ int l = pos;
+ c = parseChar(doc, length, pos, curtag.wsm);
+
+ // in white space pre mode: treat any space as non breakable
+ // and expand tabs to eight character wide columns.
+ if (curtag.wsm == TQStyleSheetItem::WhiteSpacePre) {
+ if (c == TQLatin1Char('\t')) {
+ c = TQLatin1Char(' ');
+ while((++tabExpansionColumn)%8)
+ s += c;
+ }
+ if (c == TQChar::LineSeparator)
+ tabExpansionColumn = 0;
+ else
+ tabExpansionColumn++;
+
+ }
+ if (c == TQLatin1Char(' ') || c == TQChar::LineSeparator) {
+ /* avoid overlong paragraphs by forcing a new
+ paragraph after 4096 characters. This case can
+ occur when loading undiscovered plain text
+ documents in rich text mode. Instead of hanging
+ forever, we do the trick.
+ */
+ if (curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal && s.length() > 4096) do {
+ if (doc[l] == TQLatin1Char('\n')) {
+ hasNewPar = false; // for a new paragraph ...
+ NEWPAR;
+ hasNewPar = false; // ... and make it non-reusable
+ c = TQLatin1Char('\n'); // make sure we break below
+ break;
+ }
+ } while (++l < pos);
+ }
+ }
+
+ if (c == TQLatin1Char('\n'))
+ break; // break on newlines, pre delievers a TQChar::LineSeparator
+
+ bool c_isSpace = c.isSpace() && c.unicode() != 0x00a0U && !textEditMode;
+
+ if (curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal && c_isSpace && space)
+ continue;
+ if (c == TQLatin1Char('\r'))
+ continue;
+ space = c_isSpace;
+ s += c;
+ }
+ if (!s.isEmpty() && curtag.style->displayMode() != TQStyleSheetItem::DisplayNone) {
+ hasNewPar = false;
+ int index = qMax(curpar->length(),1) - 1;
+ curpar->append(s);
+ if (curtag.wsm != TQStyleSheetItem::WhiteSpaceNormal) {
+ TQTextString *str = curpar->string();
+ for (int i = index; i < index + s.length(); ++i)
+ str->at(i).nobreak = true;
+ }
+
+ TQTextFormat* f = formatCollection()->format(&curtag.format);
+ curpar->setFormat(index, s.length(), f, false); // do not use collection because we have done that already
+ f->ref += s.length() -1; // that what friends are for...
+ if (!curtag.anchorHref.isEmpty()) {
+ for (int i = 0; i < int(s.length()); i++)
+ curpar->at(index + i)->setAnchor(TQString(), curtag.anchorHref);
+ }
+ if (!anchorName.isEmpty() ) {
+ for (int i = 0; i < int(s.length()); i++)
+ curpar->at(index + i)->setAnchor(anchorName, curpar->at(index + i)->anchorHref());
+ anchorName.clear();
+ }
+ }
+ }
+ }
+
+ if (hasNewPar && curpar != fParag && !cursor && stylesPar != curpar) {
+ // cleanup unused last paragraphs
+ curpar = curpar->p;
+ delete curpar->n;
+ }
+
+ if (!anchorName.isEmpty() ) {
+ curpar->at(curpar->length() - 1)->setAnchor(anchorName, curpar->at(curpar->length() - 1)->anchorHref());
+ anchorName.clear();
+ }
+
+ setRichTextMarginsInternal(styles, stylesPar);
+
+ if (cursor) {
+ cursor->gotoPreviousLetter();
+ cursor->remove();
+ }
+ while (!styles.isEmpty())
+ delete styles.takeFirst();
+ delete vec;
+}
+
+void TQTextDocument::setRichTextMarginsInternal(QList< QVector<TQStyleSheetItem *> *>& styles, TQTextParagraph* stylesPar)
+{
+ // margin and line spacing calculation
+ // qDebug("setRichTextMarginsInternal: styles.size() = %d", styles.size());
+ QVector<TQStyleSheetItem *>* prevStyle = 0;
+ int stylesIndex = 0;
+ QVector<TQStyleSheetItem *>* curStyle = styles.size() ? styles.first() : 0;
+ QVector<TQStyleSheetItem *>* nextStyle =
+ (++stylesIndex) < styles.size() ? styles.at(stylesIndex) : 0;
+ while (stylesPar) {
+ if (!curStyle) {
+ stylesPar = stylesPar->next();
+ prevStyle = curStyle;
+ curStyle = nextStyle;
+ nextStyle = (++stylesIndex) < styles.size() ? styles.at(stylesIndex) : 0;
+ continue;
+ }
+
+ int i, mar;
+ TQStyleSheetItem* mainStyle = curStyle->size() ? (*curStyle)[curStyle->size()-1] : 0;
+ if (mainStyle && mainStyle->displayMode() == TQStyleSheetItem::DisplayListItem)
+ stylesPar->setListItem(true);
+ int numLists = 0;
+ for (i = 0; i < (int)curStyle->size(); ++i) {
+ if ((*curStyle)[i]->displayMode() == TQStyleSheetItem::DisplayBlock
+ && (*curStyle)[i]->listStyle() != TQStyleSheetItem::ListStyleUndefined)
+ numLists++;
+ }
+ stylesPar->ldepth = numLists;
+ if (stylesPar->next() && nextStyle) {
+ // also set the depth of the next paragraph, required for the margin calculation
+ numLists = 0;
+ for (i = 0; i < (int)nextStyle->size(); ++i) {
+ if ((*nextStyle)[i]->displayMode() == TQStyleSheetItem::DisplayBlock
+ && (*nextStyle)[i]->listStyle() != TQStyleSheetItem::ListStyleUndefined)
+ numLists++;
+ }
+ stylesPar->next()->ldepth = numLists;
+ }
+
+ // do the top margin
+ TQStyleSheetItem* item = mainStyle;
+ int m;
+ if (stylesPar->utm > 0) {
+ m = stylesPar->utm-1;
+ stylesPar->utm = 0;
+ } else {
+ m = qMax(0, item->margin(TQStyleSheetItem::MarginTop));
+ if (stylesPar->ldepth) {
+ if (item->displayMode() == TQStyleSheetItem::DisplayListItem)
+ m /= stylesPar->ldepth * stylesPar->ldepth;
+ else
+ m = 0;
+ }
+ }
+ for (i = (int)curStyle->size() - 2 ; i >= 0; --i) {
+ item = (*curStyle)[i];
+ if (prevStyle && i < (int) prevStyle->size() &&
+ ( item->displayMode() == TQStyleSheetItem::DisplayBlock &&
+ (*prevStyle)[i] == item))
+ break;
+ // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
+ if (item->listStyle() != TQStyleSheetItem::ListStyleUndefined &&
+ (( i> 0 && (*curStyle)[i-1] == item) || (*curStyle)[i+1] == item))
+ continue;
+ mar = qMax(0, item->margin(TQStyleSheetItem::MarginTop));
+ m = qMax(m, mar);
+ }
+ stylesPar->utm = m - stylesPar->topMargin();
+
+ // do the bottom margin
+ item = mainStyle;
+ if (stylesPar->ubm > 0) {
+ m = stylesPar->ubm-1;
+ stylesPar->ubm = 0;
+ } else {
+ m = qMax(0, item->margin(TQStyleSheetItem::MarginBottom));
+ if (stylesPar->ldepth) {
+ if (item->displayMode() == TQStyleSheetItem::DisplayListItem)
+ m /= stylesPar->ldepth * stylesPar->ldepth;
+ else
+ m = 0;
+ }
+ }
+ for (i = (int)curStyle->size() - 2 ; i >= 0; --i) {
+ item = (*curStyle)[i];
+ if (nextStyle && i < (int) nextStyle->size() &&
+ ( item->displayMode() == TQStyleSheetItem::DisplayBlock &&
+ (*nextStyle)[i] == item))
+ break;
+ // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
+ if (item->listStyle() != TQStyleSheetItem::ListStyleUndefined &&
+ (( i> 0 && (*curStyle)[i-1] == item) || (*curStyle)[i+1] == item))
+ continue;
+ mar = qMax(0, item->margin(TQStyleSheetItem::MarginBottom));
+ m = qMax(m, mar);
+ }
+ stylesPar->ubm = m - stylesPar->bottomMargin();
+
+ // do the left margin, simplyfied
+ item = mainStyle;
+ if (stylesPar->ulm > 0) {
+ m = stylesPar->ulm-1;
+ stylesPar->ulm = 0;
+ } else {
+ m = qMax(0, item->margin(TQStyleSheetItem::MarginLeft));
+ }
+ for (i = (int)curStyle->size() - 2 ; i >= 0; --i) {
+ item = (*curStyle)[i];
+ m += qMax(0, item->margin(TQStyleSheetItem::MarginLeft));
+ }
+ stylesPar->ulm = m - stylesPar->leftMargin();
+
+ // do the right margin, simplyfied
+ item = mainStyle;
+ if (stylesPar->urm > 0) {
+ m = stylesPar->urm-1;
+ stylesPar->urm = 0;
+ } else {
+ m = qMax(0, item->margin(TQStyleSheetItem::MarginRight));
+ }
+ for (i = (int)curStyle->size() - 2 ; i >= 0; --i) {
+ item = (*curStyle)[i];
+ m += qMax(0, item->margin(TQStyleSheetItem::MarginRight));
+ }
+ stylesPar->urm = m - stylesPar->rightMargin();
+
+ // do the first line margin, which really should be called text-indent
+ item = mainStyle;
+ if (stylesPar->uflm > 0) {
+ m = stylesPar->uflm-1;
+ stylesPar->uflm = 0;
+ } else {
+ m = qMax(0, item->margin(TQStyleSheetItem::MarginFirstLine));
+ }
+ for (i = (int)curStyle->size() - 2 ; i >= 0; --i) {
+ item = (*curStyle)[i];
+ mar = qMax(0, item->margin(TQStyleSheetItem::MarginFirstLine));
+ m = qMax(m, mar);
+ }
+ stylesPar->uflm =m - stylesPar->firstLineMargin();
+
+ // do the bogus line "spacing", which really is just an extra margin
+ item = mainStyle;
+ for (i = (int)curStyle->size() - 1 ; i >= 0; --i) {
+ item = (*curStyle)[i];
+ if (item->lineSpacing() != TQStyleSheetItem::Undefined) {
+ stylesPar->ulinespacing = item->lineSpacing();
+ if (formatCollection() &&
+ stylesPar->ulinespacing < formatCollection()->defaultFormat()->height())
+ stylesPar->ulinespacing += formatCollection()->defaultFormat()->height();
+ break;
+ }
+ }
+
+ stylesPar = stylesPar->next();
+ prevStyle = curStyle;
+ curStyle = nextStyle;
+ nextStyle = (++stylesIndex) < styles.size() ? styles.at(stylesIndex) : 0;
+ }
+}
+
+void TQTextDocument::setText(const TQString &text, const TQString &context)
+{
+ focusIndicator.parag = 0;
+ selections.clear();
+ if ((txtFormat == TQt::AutoText && TQStyleSheet::mightBeRichText(text))
+ || txtFormat == TQt::RichText)
+ setRichText(text, context);
+ else
+ setPlainText(text);
+}
+
+TQString TQTextDocument::plainText() const
+{
+ TQString buffer;
+ TQString s;
+ TQTextParagraph *p = fParag;
+ while (p) {
+ if (!p->mightHaveCustomItems) {
+ const TQTextString *ts = p->string(); // workaround VC++ and Borland
+ s = ts->toString(); // with false we don't fix spaces (nbsp)
+ } else {
+ for (int i = 0; i < p->length() - 1; ++i) {
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (p->at(i)->isCustom()) {
+ if (p->at(i)->customItem()->isNested()) {
+ s += TQLatin1String("\n");
+ TQTextTable *t = (TQTextTable*)p->at(i)->customItem();
+ QList<TQTextTableCell *> cells = t->tableCells();
+ for (int idx = 0; idx < cells.size(); ++idx) {
+ TQTextTableCell *c = cells.at(idx);
+ s += c->richText()->plainText() + TQLatin1String("\n");
+ }
+ s += TQLatin1String("\n");
+ }
+ } else
+#endif
+ {
+ s += p->at(i)->c;
+ }
+ }
+ }
+ s.remove(s.length() - 1, 1);
+ if (p->next())
+ s += TQLatin1String("\n");
+ buffer += s;
+ p = p->next();
+ }
+ return buffer;
+}
+
+static TQString align_to_string(int a)
+{
+ if (a & Qt::AlignRight)
+ return TQLatin1String(" align=\"right\"");
+ if (a & Qt::AlignHCenter)
+ return TQLatin1String(" align=\"center\"");
+ if (a & Qt::AlignJustify)
+ return TQLatin1String(" align=\"justify\"");
+ return TQString();
+}
+
+static TQString direction_to_string(int dir)
+{
+ if (dir != TQChar::DirON)
+ return (dir == TQChar::DirL? TQLatin1String(" dir=\"ltr\"") : TQLatin1String(" dir=\"rtl\""));
+ return TQString();
+}
+
+static TQString list_value_to_string(int v)
+{
+ if (v != -1)
+ return TQLatin1String(" listvalue=\"") + TQString::number(v) + TQLatin1Char('"');
+ return TQString();
+}
+
+static TQString list_style_to_string(int v)
+{
+ switch(v) {
+ case TQStyleSheetItem::ListDecimal: return TQLatin1String("\"1\"");
+ case TQStyleSheetItem::ListLowerAlpha: return TQLatin1String("\"a\"");
+ case TQStyleSheetItem::ListUpperAlpha: return TQLatin1String("\"A\"");
+ case TQStyleSheetItem::ListDisc: return TQLatin1String("\"disc\"");
+ case TQStyleSheetItem::ListSquare: return TQLatin1String("\"square\"");
+ case TQStyleSheetItem::ListCircle: return TQLatin1String("\"circle\"");
+ default:
+ return TQString();
+ }
+}
+
+static inline bool list_is_ordered(int v)
+{
+ return v == TQStyleSheetItem::ListDecimal ||
+ v == TQStyleSheetItem::ListLowerAlpha ||
+ v == TQStyleSheetItem::ListUpperAlpha;
+}
+
+
+static TQString margin_to_string(TQStyleSheetItem* style, int t, int b, int l, int r, int fl)
+{
+ TQString s;
+ if (l > 0)
+ s += TQString(s.size() ? TQLatin1String(";") : TQLatin1String("")) + TQLatin1String("margin-left:") +
+ TQString::number(l+qMax(0,style->margin(TQStyleSheetItem::MarginLeft))) + TQLatin1String("px");
+ if (r > 0)
+ s += TQString(s.size() ? TQLatin1String(";") : TQLatin1String("")) + TQLatin1String("margin-right:") +
+ TQString::number(r+qMax(0,style->margin(TQStyleSheetItem::MarginRight))) + TQLatin1String("px");
+ if (t > 0)
+ s += TQString(s.size() ? TQLatin1String(";") : TQLatin1String("")) + TQLatin1String("margin-top:") +
+ TQString::number(t+qMax(0,style->margin(TQStyleSheetItem::MarginTop))) + TQLatin1String("px");
+ if (b > 0)
+ s += TQString(s.size() ? TQLatin1String(";") : TQLatin1String("")) + TQLatin1String("margin-bottom:") +
+ TQString::number(b+qMax(0,style->margin(TQStyleSheetItem::MarginBottom))) + TQLatin1String("px");
+ if (fl > 0)
+ s += TQString(s.size() ? TQLatin1String(";") : TQLatin1String("")) + TQLatin1String("text-indent:") +
+ TQString::number(fl+qMax(0,style->margin(TQStyleSheetItem::MarginFirstLine))) + TQLatin1String("px");
+ if (s.size())
+ return TQLatin1String(" style=\"") + s + TQLatin1String("\"");
+ return TQString();
+}
+
+TQString TQTextDocument::richText() const
+{
+ TQString s = TQLatin1String("");
+ if (!par) {
+ s += TQLatin1String("<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:");
+ s += TQString::number(formatCollection()->defaultFormat()->font().pointSize());
+ s += TQLatin1String("pt;font-family:");
+ s += formatCollection()->defaultFormat()->font().family();
+ s += TQLatin1String("\">");
+ }
+ TQTextParagraph* p = fParag;
+
+ TQStyleSheetItem* item_p = styleSheet()->item(TQLatin1String("p"));
+ TQStyleSheetItem* item_div = styleSheet()->item(TQLatin1String("div"));
+ TQStyleSheetItem* item_ul = styleSheet()->item(TQLatin1String("ul"));
+ TQStyleSheetItem* item_ol = styleSheet()->item(TQLatin1String("ol"));
+ TQStyleSheetItem* item_li = styleSheet()->item(TQLatin1String("li"));
+ if (!item_p || !item_div || !item_ul || !item_ol || !item_li) {
+ qWarning("QTextEdit: cannot export HTML due to insufficient stylesheet (lack of p, div, ul, ol, or li)");
+ return TQString();
+ }
+ int pastListDepth = 0;
+ int listDepth = 0;
+#if 0
+ int futureListDepth = 0;
+#endif
+ QVector<int> listStyles(10);
+
+ while (p) {
+ listDepth = p->listDepth();
+ if (listDepth < pastListDepth) {
+ for (int i = pastListDepth; i > listDepth; i--)
+ s += list_is_ordered(listStyles[i]) ? TQLatin1String("</ol>") : TQLatin1String("</ul>");
+ s += TQLatin1Char('\n');
+ } else if (listDepth > pastListDepth) {
+ s += TQLatin1Char('\n');
+ listStyles.resize(qMax((int)listStyles.size(), listDepth+1));
+ TQString list_type;
+ listStyles[listDepth] = p->listStyle();
+ if (!list_is_ordered(p->listStyle()) || item_ol->listStyle() != p->listStyle())
+ list_type = TQLatin1String(" type=") + list_style_to_string(p->listStyle());
+ for (int i = pastListDepth; i < listDepth; i++) {
+ s += list_is_ordered(p->listStyle()) ? TQLatin1String("<ol") : TQLatin1String("<ul");
+ s += list_type + TQLatin1Char('>');
+ }
+ } else {
+ s += TQLatin1Char('\n');
+ }
+
+ TQString ps = p->richText();
+
+#if 0
+ // for the bottom margin we need to know whether we are at the end of a list
+ futureListDepth = 0;
+ if (listDepth > 0 && p->next())
+ futureListDepth = p->next()->listDepth();
+#endif
+
+ if (richTextExportStart && richTextExportStart->paragraph() ==p &&
+ richTextExportStart->index() == 0)
+ s += TQLatin1String("<!--StartFragment-->");
+
+ if (p->isListItem()) {
+ s += TQLatin1String("<li");
+ if (p->listStyle() != listStyles[listDepth])
+ s += TQLatin1String(" type=") + list_style_to_string(p->listStyle());
+ s += align_to_string(p->alignment());
+ s += margin_to_string(item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm);
+ s += list_value_to_string(p->listValue());
+ s += direction_to_string(p->direction());
+ s += TQLatin1Char('>');
+ s += ps;
+ s += TQLatin1String("</li>");
+ } else if (p->listDepth()) {
+ s += TQLatin1String("<div");
+ s += align_to_string(p->alignment());
+ s += margin_to_string(item_div, p->utm, p->ubm, p->ulm, p->urm, p->uflm);
+ s += direction_to_string(p->direction());
+ s += TQLatin1Char('>');
+ s += ps;
+ s += TQLatin1String("</div>");
+ } else {
+ // normal paragraph item
+ s += TQLatin1String("<p");
+ s += align_to_string(p->alignment());
+ s += margin_to_string(item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm);
+ s += direction_to_string(p->direction());
+ s += TQLatin1Char('>');
+ s += ps;
+ s += TQLatin1String("</p>");
+ }
+ pastListDepth = listDepth;
+ p = p->next();
+ }
+ while (listDepth > 0) {
+ s += list_is_ordered(listStyles[listDepth]) ? TQLatin1String("</ol>") : TQLatin1String("</ul>");
+ listDepth--;
+ }
+
+ if (!par)
+ s += TQLatin1String("\n</body></html>\n");
+
+ return s;
+}
+
+TQString TQTextDocument::text() const
+{
+ if ((txtFormat == TQt::AutoText && preferRichText) || txtFormat == TQt::RichText)
+ return richText();
+ return plainText();
+}
+
+TQString TQTextDocument::text(int parag) const
+{
+ TQTextParagraph *p = paragAt(parag);
+ if (!p)
+ return TQString();
+
+ if ((txtFormat == TQt::AutoText && preferRichText) || txtFormat == TQt::RichText)
+ return p->richText();
+ else
+ return p->string()->toString();
+}
+
+void TQTextDocument::invalidate()
+{
+ TQTextParagraph *s = fParag;
+ while (s) {
+ s->invalidate(0);
+ s = s->next();
+ }
+}
+
+void TQTextDocument::selectionStart(int id, int &paragId, int &index)
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
+ if (it == selections.end())
+ return;
+ TQTextDocumentSelection &sel = *it;
+ paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
+ index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
+}
+
+TQTextCursor TQTextDocument::selectionStartCursor(int id)
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
+ if (it == selections.end())
+ return TQTextCursor(this);
+ TQTextDocumentSelection &sel = *it;
+ if (sel.swapped)
+ return sel.endCursor;
+ return sel.startCursor;
+}
+
+TQTextCursor TQTextDocument::selectionEndCursor(int id)
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
+ if (it == selections.end())
+ return TQTextCursor(this);
+ TQTextDocumentSelection &sel = *it;
+ if (!sel.swapped)
+ return sel.endCursor;
+ return sel.startCursor;
+}
+
+void TQTextDocument::selectionEnd(int id, int &paragId, int &index)
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
+ if (it == selections.end())
+ return;
+ TQTextDocumentSelection &sel = *it;
+ paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
+ index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
+}
+
+void TQTextDocument::addSelection(int id)
+{
+ nSelections = qMax(nSelections, id + 1);
+}
+
+static void setSelectionEndHelper(int id, TQTextDocumentSelection &sel, TQTextCursor &start, TQTextCursor &end)
+{
+ TQTextCursor c1 = start;
+ TQTextCursor c2 = end;
+ if (sel.swapped) {
+ c1 = end;
+ c2 = start;
+ }
+
+ c1.paragraph()->removeSelection(id);
+ c2.paragraph()->removeSelection(id);
+ if (c1.paragraph() != c2.paragraph()) {
+ c1.paragraph()->setSelection(id, c1.index(), c1.paragraph()->length() - 1);
+ c2.paragraph()->setSelection(id, 0, c2.index());
+ } else {
+ c1.paragraph()->setSelection(id, qMin(c1.index(), c2.index()), qMax(c1.index(), c2.index()));
+ }
+
+ sel.startCursor = start;
+ sel.endCursor = end;
+ if (sel.startCursor.paragraph() == sel.endCursor.paragraph())
+ sel.swapped = sel.startCursor.index() > sel.endCursor.index();
+}
+
+bool TQTextDocument::setSelectionEnd(int id, const TQTextCursor &cursor)
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
+ if (it == selections.end())
+ return false;
+ TQTextDocumentSelection &sel = *it;
+
+ TQTextCursor start = sel.startCursor;
+ TQTextCursor end = cursor;
+
+ if (start == end) {
+ removeSelection(id);
+ setSelectionStart(id, cursor);
+ return true;
+ }
+
+ if (sel.endCursor.paragraph() == end.paragraph()) {
+ setSelectionEndHelper(id, sel, start, end);
+ return true;
+ }
+
+ bool inSelection = false;
+ TQTextCursor c(this);
+ TQTextCursor tmp = sel.startCursor;
+ if (sel.swapped)
+ tmp = sel.endCursor;
+ tmp.restoreState();
+ TQTextCursor tmp2 = cursor;
+ tmp2.restoreState();
+ c.setParagraph(tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph());
+ bool hadStart = false;
+ bool hadEnd = false;
+ bool hadStartParag = false;
+ bool hadEndParag = false;
+ bool hadOldStart = false;
+ bool hadOldEnd = false;
+ bool leftSelection = false;
+ sel.swapped = false;
+ for (;;) {
+ if (c == start)
+ hadStart = true;
+ if (c == end)
+ hadEnd = true;
+ if (c.paragraph() == start.paragraph())
+ hadStartParag = true;
+ if (c.paragraph() == end.paragraph())
+ hadEndParag = true;
+ if (c == sel.startCursor)
+ hadOldStart = true;
+ if (c == sel.endCursor)
+ hadOldEnd = true;
+
+ if (!sel.swapped &&
+ ((hadEnd && !hadStart)
+ || (hadEnd && hadStart && start.paragraph() == end.paragraph() && start.index() > end.index())))
+ sel.swapped = true;
+
+ if ((c == end && hadStartParag) || (c == start && hadEndParag)) {
+ TQTextCursor tmp = c;
+ tmp.restoreState();
+ if (tmp.paragraph() != c.paragraph()) {
+ int sstart = tmp.paragraph()->selectionStart(id);
+ tmp.paragraph()->removeSelection(id);
+ tmp.paragraph()->setSelection(id, sstart, tmp.index());
+ }
+ }
+
+ if (inSelection &&
+ ((c == end && hadStart) || (c == start && hadEnd)))
+ leftSelection = true;
+ else if (!leftSelection && !inSelection && (hadStart || hadEnd))
+ inSelection = true;
+
+ bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection(id) && c.atParagEnd();
+ c.paragraph()->removeSelection(id);
+ if (inSelection) {
+ if (c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph()) {
+ c.paragraph()->setSelection(id, qMin(start.index(), end.index()), qMax(start.index(), end.index()));
+ } else if (c.paragraph() == start.paragraph() && !hadEndParag) {
+ c.paragraph()->setSelection(id, start.index(), c.paragraph()->length() - 1);
+ } else if (c.paragraph() == end.paragraph() && !hadStartParag) {
+ c.paragraph()->setSelection(id, end.index(), c.paragraph()->length() - 1);
+ } else if (c.paragraph() == end.paragraph() && hadEndParag) {
+ c.paragraph()->setSelection(id, 0, end.index());
+ } else if (c.paragraph() == start.paragraph() && hadStartParag) {
+ c.paragraph()->setSelection(id, 0, start.index());
+ } else {
+ c.paragraph()->setSelection(id, 0, c.paragraph()->length() - 1);
+ }
+ }
+
+ if (leftSelection)
+ inSelection = false;
+
+ if (noSelectionAnymore)
+ break;
+ // *ugle*hack optimization
+ TQTextParagraph *p = c.paragraph();
+ if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph()) {
+ c.gotoNextLetter();
+ if (p == lastParagraph() && c.atParagEnd())
+ break;
+ } else {
+ if (p->document()->parent())
+ do {
+ c.gotoNextLetter();
+ } while (c.paragraph() == p);
+ else
+ c.setParagraph(p->next());
+ }
+ }
+
+ if (!sel.swapped)
+ sel.startCursor.paragraph()->setSelection(id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1);
+
+ sel.startCursor = start;
+ sel.endCursor = end;
+ if (sel.startCursor.paragraph() == sel.endCursor.paragraph())
+ sel.swapped = sel.startCursor.index() > sel.endCursor.index();
+
+ setSelectionEndHelper(id, sel, start, end);
+
+ return true;
+}
+
+void TQTextDocument::selectAll(int id)
+{
+ removeSelection(id);
+
+ TQTextDocumentSelection sel;
+ sel.swapped = false;
+ TQTextCursor c(this);
+
+ c.setParagraph(fParag);
+ c.setIndex(0);
+ sel.startCursor = c;
+
+ c.setParagraph(lParag);
+ c.setIndex(lParag->length() - 1);
+ sel.endCursor = c;
+
+ selections.insert(id, sel);
+
+ TQTextParagraph *p = fParag;
+ while (p) {
+ p->setSelection(id, 0, p->length() - 1);
+ p = p->next();
+ }
+
+ for (int idx = 0; idx < childList.size(); ++idx) {
+ TQTextDocument *dc = childList.at(idx);
+ dc->selectAll(id);
+ }
+}
+
+bool TQTextDocument::removeSelection(int id)
+{
+ if (!selections.contains(id))
+ return false;
+
+ TQTextDocumentSelection &sel = selections[id];
+
+ TQTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor;
+ TQTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor;
+ TQTextParagraph* p = 0;
+ while (start != end) {
+ if (p != start.paragraph()) {
+ p = start.paragraph();
+ p->removeSelection(id);
+ //### avoid endless loop by all means necessary, did somebody mention refactoring?
+ if (!parent() && p == lParag)
+ break;
+ }
+ start.gotoNextLetter();
+ }
+ p = start.paragraph();
+ p->removeSelection(id);
+ selections.remove(id);
+ return true;
+}
+
+TQString TQTextDocument::selectedText(int id, bool asRichText) const
+{
+ QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.find(id);
+ if (it == selections.end())
+ return TQString();
+
+ TQTextDocumentSelection sel = *it;
+
+
+ TQTextCursor c1 = sel.startCursor;
+ TQTextCursor c2 = sel.endCursor;
+ if (sel.swapped) {
+ c2 = sel.startCursor;
+ c1 = sel.endCursor;
+ }
+
+ /* 3.0.3 improvement: Make it possible to get a reasonable
+ selection inside a table. This approach is very conservative:
+ make sure that both cursors have the same depth level and point
+ to paragraphs within the same text document.
+
+ Meaning if you select text in two table cells, you will get the
+ entire table. This is still far better than the 3.0.2, where
+ you always got the entire table.
+
+ ### Fix this properly when refactoring
+ */
+ while (c2.nestedDepth() > c1.nestedDepth())
+ c2.oneUp();
+ while (c1.nestedDepth() > c2.nestedDepth())
+ c1.oneUp();
+ while (c1.nestedDepth() && c2.nestedDepth() &&
+ c1.paragraph()->document() != c2.paragraph()->document()) {
+ c1.oneUp();
+ c2.oneUp();
+ }
+ // do not trust sel_swapped with tables. Fix this properly when refactoring as well
+ if (c1.paragraph()->paragId() > c2.paragraph()->paragId() ||
+ (c1.paragraph() == c2.paragraph() && c1.index() > c2.index())) {
+ TQTextCursor tmp = c1;
+ c2 = c1;
+ c1 = tmp;
+ }
+
+ // end selection 3.0.3 improvement
+
+ if (asRichText && !parent()) {
+ richTextExportStart = &c1;
+ richTextExportEnd = &c2;
+
+ TQString sel = richText();
+ int from = sel.indexOf(TQLatin1String("<!--StartFragment-->"));
+ if (from >= 0) {
+ from += 20;
+ // find the previous span and move it into the start fragment before we clip it
+ TQString prevspan;
+ int pspan = sel.lastIndexOf(TQLatin1String("<span"), from-21);
+ if (pspan > sel.lastIndexOf(TQLatin1String("</span"), from-21)) {
+ int spanend = sel.indexOf(TQLatin1Char('>'), pspan);
+ prevspan = sel.mid(pspan, spanend - pspan + 1);
+ }
+ int to = sel.lastIndexOf(TQLatin1String("<!--EndFragment-->"));
+ if (from <= to)
+ sel = TQLatin1String("<!--StartFragment-->") + prevspan + sel.mid(from, to - from);
+ }
+ richTextExportStart = richTextExportEnd = 0;
+ return sel;
+ }
+
+ TQString s;
+ if (c1.paragraph() == c2.paragraph()) {
+ TQTextParagraph *p = c1.paragraph();
+ int end = c2.index();
+ if (p->at(qMax(0, end - 1))->isCustom())
+ ++end;
+ if (!p->mightHaveCustomItems) {
+ s += p->string()->toString().mid(c1.index(), end - c1.index());
+ } else {
+ for (int i = c1.index(); i < end; ++i) {
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (p->at(i)->isCustom()) {
+ if (p->at(i)->customItem()->isNested()) {
+ s += TQLatin1String("\n");
+ TQTextTable *t = (TQTextTable*)p->at(i)->customItem();
+ QList<TQTextTableCell *> cells = t->tableCells();
+ for (int idx = 0; idx < cells.size(); ++idx) {
+ TQTextTableCell *c = cells.at(idx);
+ s += c->richText()->plainText() + TQLatin1String("\n");
+ }
+ s += TQLatin1String("\n");
+ }
+ } else
+#endif
+ {
+ s += p->at(i)->c;
+ }
+ }
+ }
+ } else {
+ TQTextParagraph *p = c1.paragraph();
+ int start = c1.index();
+ while (p) {
+ int end = p == c2.paragraph() ? c2.index() : p->length() - 1;
+ if (p == c2.paragraph() && p->at(qMax(0, end - 1))->isCustom())
+ ++end;
+ if (!p->mightHaveCustomItems) {
+ s += p->string()->toString().mid(start, end - start);
+ if (p != c2.paragraph())
+ s += TQLatin1String("\n");
+ } else {
+ for (int i = start; i < end; ++i) {
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (p->at(i)->isCustom()) {
+ if (p->at(i)->customItem()->isNested()) {
+ s += TQLatin1String(TQLatin1String("\n"));
+ TQTextTable *t = (TQTextTable*)p->at(i)->customItem();
+ QList<TQTextTableCell *> cells = t->tableCells();
+ for (int idx = 0; idx < cells.size(); ++idx) {
+ TQTextTableCell *c = cells.at(idx);
+ s += c->richText()->plainText() + TQLatin1String("\n");
+ }
+ s += TQLatin1String("\n");
+ }
+ } else
+#endif
+ {
+ s += p->at(i)->c;
+ }
+ }
+ }
+ start = 0;
+ if (p == c2.paragraph())
+ break;
+ p = p->next();
+ }
+ }
+ // ### workaround for plain text export until we get proper
+ // mime types: turn unicode line seperators into the more
+ // widely understood \n. Makes copy and pasting code snipplets
+ // from within Assistent possible
+ TQChar* uc = (TQChar*) s.unicode();
+ for (int ii = 0; ii < s.length(); ii++) {
+ if (uc[(int)ii] == TQChar::LineSeparator)
+ uc[(int)ii] = TQLatin1Char('\n');
+ else if ( uc[(int)ii] == TQChar::Nbsp )
+ uc[(int)ii] = TQLatin1Char(' ');
+ }
+ return s;
+}
+
+void TQTextDocument::setFormat(int id, TQTextFormat *f, int flags)
+{
+ QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.constFind(id);
+ if (it == selections.constEnd())
+ return;
+
+ TQTextDocumentSelection sel = *it;
+
+ TQTextCursor c1 = sel.startCursor;
+ TQTextCursor c2 = sel.endCursor;
+ if (sel.swapped) {
+ c2 = sel.startCursor;
+ c1 = sel.endCursor;
+ }
+
+ c2.restoreState();
+ c1.restoreState();
+
+ if (c1.paragraph() == c2.paragraph()) {
+ c1.paragraph()->setFormat(c1.index(), c2.index() - c1.index(), f, true, flags);
+ return;
+ }
+
+ c1.paragraph()->setFormat(c1.index(), c1.paragraph()->length() - c1.index(), f, true, flags);
+ TQTextParagraph *p = c1.paragraph()->next();
+ while (p && p != c2.paragraph()) {
+ p->setFormat(0, p->length(), f, true, flags);
+ p = p->next();
+ }
+ c2.paragraph()->setFormat(0, c2.index(), f, true, flags);
+}
+
+void TQTextDocument::removeSelectedText(int id, TQTextCursor *cursor)
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
+ if (it == selections.end())
+ return;
+
+ TQTextDocumentSelection sel = *it;
+ TQTextCursor c1 = sel.startCursor;
+ TQTextCursor c2 = sel.endCursor;
+ if (sel.swapped) {
+ c2 = sel.startCursor;
+ c1 = sel.endCursor;
+ }
+
+ // ### no support for editing tables yet
+ if (c1.nestedDepth() || c2.nestedDepth())
+ return;
+
+ c2.restoreState();
+ c1.restoreState();
+
+ *cursor = c1;
+ removeSelection(id);
+
+ if (c1.paragraph() == c2.paragraph()) {
+ c1.paragraph()->remove(c1.index(), c2.index() - c1.index());
+ return;
+ }
+
+ if (c1.paragraph() == fParag && c1.index() == 0 &&
+ c2.paragraph() == lParag && c2.index() == lParag->length() - 1)
+ cursor->setValid(false);
+
+ bool didGoLeft = false;
+ if ( c1.index() == 0 && c1.paragraph() != fParag) {
+ cursor->gotoPreviousLetter();
+ didGoLeft = cursor->isValid();
+ }
+
+ c1.paragraph()->remove(c1.index(), c1.paragraph()->length() - 1 - c1.index());
+ TQTextParagraph *p = c1.paragraph()->next();
+ int dy = 0;
+ TQTextParagraph *tmp;
+ while (p && p != c2.paragraph()) {
+ tmp = p->next();
+ dy -= p->rect().height();
+ delete p;
+ p = tmp;
+ }
+ c2.paragraph()->remove(0, c2.index());
+ while (p) {
+ p->move(dy);
+ p->invalidate(0);
+ p->setEndState(-1);
+ p = p->next();
+ }
+
+
+ c1.paragraph()->join(c2.paragraph());
+
+ if (didGoLeft)
+ cursor->gotoNextLetter();
+}
+
+void TQTextDocument::indentSelection(int id)
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.find(id);
+ if (it == selections.end())
+ return;
+
+ TQTextDocumentSelection sel = *it;
+ TQTextParagraph *startParag = sel.startCursor.paragraph();
+ TQTextParagraph *endParag = sel.endCursor.paragraph();
+ if (sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId()) {
+ endParag = sel.startCursor.paragraph();
+ startParag = sel.endCursor.paragraph();
+ }
+
+ TQTextParagraph *p = startParag;
+ while (p && p != endParag) {
+ p->indent();
+ p = p->next();
+ }
+}
+
+void TQTextCommandHistory::clear()
+{
+ while (!history.isEmpty())
+ delete history.takeFirst();
+ current = -1;
+}
+
+void TQTextDocument::addCommand(TQTextCommand *cmd)
+{
+ commandHistory->addCommand(cmd);
+}
+
+TQTextCursor *TQTextDocument::undo(TQTextCursor *c)
+{
+ return commandHistory->undo(c);
+}
+
+TQTextCursor *TQTextDocument::redo(TQTextCursor *c)
+{
+ return commandHistory->redo(c);
+}
+
+bool TQTextDocument::find(TQTextCursor& cursor, const TQString &expr, bool cs, bool wo, bool forward)
+{
+ Qt::CaseSensitivity caseSensitive = cs ? Qt::CaseSensitive : Qt::CaseInsensitive;
+ removeSelection(Standard);
+ if (expr.isEmpty())
+ return false;
+ for (;;) {
+ TQString s = cursor.paragraph()->string()->toString();
+ int start = cursor.index();
+ for (;;) {
+ int res = forward
+ ? s.indexOf(expr, start, caseSensitive)
+ : s.lastIndexOf(expr, start, caseSensitive);
+ int end = res + expr.length();
+ if (res == -1 || (!forward && start <= res))
+ break;
+ if (!wo || ((res == 0 || !s[res-1].isLetterOrNumber())
+ && (end == (int)s.length() || !s[end].isLetterOrNumber()))) {
+ removeSelection(Standard);
+ cursor.setIndex(forward ? end : res);
+ setSelectionStart(Standard, cursor);
+ cursor.setIndex(forward ? res : end);
+ setSelectionEnd(Standard, cursor);
+ if (!forward)
+ cursor.setIndex(res);
+ return true;
+ }
+ start = res + (forward ? 1 : -1);
+ }
+ if (forward) {
+ if (cursor.paragraph() == lastParagraph() && cursor.atParagEnd())
+ break;
+ cursor.gotoNextLetter();
+ } else {
+ if (cursor.paragraph() == firstParagraph() && cursor.atParagStart())
+ break;
+ cursor.gotoPreviousLetter();
+ }
+ }
+ return false;
+}
+
+void TQTextDocument::setTextFormat(TQt::TextFormat f)
+{
+ txtFormat = f;
+ if (fParag == lParag && fParag->length() <= 1)
+ fParag->rtext = (f == TQt::RichText);
+}
+
+TQt::TextFormat TQTextDocument::textFormat() const
+{
+ return txtFormat;
+}
+
+bool TQTextDocument::inSelection(int selId, const QPoint &pos) const
+{
+ QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.find(selId);
+ if (it == selections.end())
+ return false;
+
+ TQTextDocumentSelection sel = *it;
+ TQTextParagraph *startParag = sel.startCursor.paragraph();
+ TQTextParagraph *endParag = sel.endCursor.paragraph();
+ if (sel.startCursor.paragraph() == sel.endCursor.paragraph() &&
+ sel.startCursor.paragraph()->selectionStart(selId) == sel.endCursor.paragraph()->selectionEnd(selId))
+ return false;
+ if (sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId()) {
+ endParag = sel.startCursor.paragraph();
+ startParag = sel.endCursor.paragraph();
+ }
+
+ TQTextParagraph *p = startParag;
+ while (p) {
+ if (p->rect().contains(pos)) {
+ bool inSel = false;
+ int selStart = p->selectionStart(selId);
+ int selEnd = p->selectionEnd(selId);
+ int y = 0;
+ int h = 0;
+ for (int i = 0; i < p->length(); ++i) {
+ if (i == selStart)
+ inSel = true;
+ if (i == selEnd)
+ break;
+ if (p->at(i)->lineStart) {
+ y = (*p->lineStarts.find(i))->y;
+ h = (*p->lineStarts.find(i))->h;
+ }
+ if (pos.y() - p->rect().y() >= y && pos.y() - p->rect().y() <= y + h) {
+ if (inSel && pos.x() >= p->at(i)->x &&
+ pos.x() <= p->at(i)->x + p->at(i)->format()->width(p->at(i)->c))
+ return true;
+ }
+ }
+ }
+ if (pos.y() < p->rect().y())
+ break;
+ if (p == endParag)
+ break;
+ p = p->next();
+ }
+
+ return false;
+}
+
+void TQTextDocument::doLayout(TQPainter *p, int w)
+{
+ minw = wused = 0;
+ if (!is_printer(p))
+ p = 0;
+ withoutDoubleBuffer = (p != 0);
+ TQPainter * oldPainter = TQTextFormat::painter();
+ TQTextFormat::setPainter(p);
+ tStopWidth = formatCollection()->defaultFormat()->width( TQLatin1Char('x') ) * 8;
+ flow_->setWidth(w);
+ cw = w;
+ vw = w;
+ TQTextParagraph *parag = fParag;
+ while (parag) {
+ parag->invalidate(0);
+ if (p)
+ parag->adjustToPainter(p);
+ parag->format();
+ parag = parag->next();
+ }
+ TQTextFormat::setPainter(oldPainter);
+}
+
+TQPixmap *TQTextDocument::bufferPixmap(const QSize &s)
+{
+ if (!buf_pixmap)
+ buf_pixmap = new TQPixmap(s.expandedTo(QSize(1,1)));
+ else if (buf_pixmap->size() != s)
+ buf_pixmap->resize(s.expandedTo(buf_pixmap->size()));
+ return buf_pixmap;
+}
+
+void TQTextDocument::draw(TQPainter *p, const TQRect &rect, const QPalette &pal,
+ const TQBrush *paper)
+{
+ if (!firstParagraph())
+ return;
+
+ if (paper) {
+ p->setBrushOrigin(-qIntCast(p->translationX()),
+ -qIntCast(p->translationY()));
+
+ p->fillRect(rect, *paper);
+ }
+
+ TQPainter * oldPainter = TQTextFormat::painter();
+ TQTextFormat::setPainter(p);
+
+ if (formatCollection()->defaultFormat()->color() != pal.text().color())
+ setDefaultFormat(formatCollection()->defaultFormat()->font(), pal.text().color());
+
+ TQTextParagraph *parag = firstParagraph();
+ while (parag) {
+ if (!parag->isValid())
+ parag->format();
+ int y = parag->rect().y();
+ TQRect pr(parag->rect());
+ pr.setX(0);
+ pr.setWidth(QWIDGETSIZE_MAX);
+ if (!rect.isNull() && !rect.intersects(pr)) {
+ parag = parag->next();
+ continue;
+ }
+ p->translate(0, y);
+ if (rect.isValid())
+ parag->paint(*p, pal, 0, false, rect.x(), rect.y(), rect.width(), rect.height());
+ else
+ parag->paint(*p, pal, 0, false);
+ p->translate(0, -y);
+ parag = parag->next();
+ if (!flow()->isEmpty())
+ flow()->drawFloatingItems(p, rect.x(), rect.y(), rect.width(), rect.height(), pal, false);
+ }
+ TQTextFormat::setPainter(oldPainter);
+}
+
+void TQTextDocument::drawParagraph(TQPainter *painter, TQTextParagraph *parag, int cx, int cy,
+ int cw, int ch,
+ TQPixmap *&/*doubleBuffer*/, const QPalette &pal,
+ bool drawCursor, TQTextCursor *cursor, bool resetChanged)
+{
+ if (resetChanged)
+ parag->setChanged(false);
+ TQRect ir(parag->rect());
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (!parag->tableCell())
+#endif
+ ir.setWidth(width());
+
+ painter->translate(ir.x(), ir.y());
+
+ if (!parag->document()->parent()) {
+ const QPoint oldOrigin = painter->brushOrigin();
+ painter->setBrushOrigin(-ir.topLeft());
+ painter->fillRect(TQRect(0, 0, ir.width(), ir.height()), parag->backgroundBrush(pal));
+ painter->setBrushOrigin(oldOrigin);
+ }
+
+ painter->translate(-(ir.x() - parag->rect().x()),
+ -(ir.y() - parag->rect().y()));
+ parag->paint(*painter, pal, drawCursor ? cursor : 0, true, cx, cy, cw, ch);
+
+ painter->translate(-ir.x(), -ir.y());
+
+ parag->document()->nextDoubleBuffered = false;
+}
+
+TQTextParagraph *TQTextDocument::draw(TQPainter *p, int cx, int cy, int cw, int ch,
+ const QPalette &pal, bool onlyChanged, bool drawCursor,
+ TQTextCursor *cursor, bool resetChanged)
+{
+ if (withoutDoubleBuffer || (par && par->withoutDoubleBuffer)) {
+ withoutDoubleBuffer = true;
+ TQRect r;
+ draw(p, r, pal);
+ return 0;
+ }
+ withoutDoubleBuffer = false;
+
+ if (!firstParagraph())
+ return 0;
+
+ TQPainter * oldPainter = TQTextFormat::painter();
+ TQTextFormat::setPainter(p);
+ if (formatCollection()->defaultFormat()->color() != pal.text().color())
+ setDefaultFormat(formatCollection()->defaultFormat()->font(), pal.text().color());
+
+ if (cx < 0 && cy < 0) {
+ cx = 0;
+ cy = 0;
+ cw = width();
+ ch = height();
+ }
+
+ TQTextParagraph *lastFormatted = 0;
+ TQTextParagraph *parag = firstParagraph();
+
+ TQPixmap *doubleBuffer = 0;
+
+ while (parag) {
+ lastFormatted = parag;
+ if (!parag->isValid())
+ parag->format();
+
+ TQRect pr = parag->rect();
+ pr.setWidth(parag->document()->width());
+ if (pr.y() > cy + ch)
+ goto floating;
+ TQRect clipr(cx, cy, cw, ch);
+ if (!pr.intersects(clipr) || (onlyChanged && !parag->hasChanged())) {
+ pr.setWidth(parag->document()->width());
+ parag = parag->next();
+ continue;
+ }
+
+ drawParagraph(p, parag, cx, cy, cw, ch, doubleBuffer, pal, drawCursor,
+ cursor, resetChanged);
+ parag = parag->next();
+ }
+
+ parag = lastParagraph();
+
+ floating:
+ if (parag->rect().y() + parag->rect().height() < parag->document()->height()) {
+ if (!parag->document()->parent()) {
+ TQRect fillRect = TQRect(0, parag->rect().y() + parag->rect().height(), parag->document()->width(),
+ parag->document()->height() - (parag->rect().y() + parag->rect().height()));
+ if (TQRect(cx, cy, cw, ch).intersects(fillRect))
+ p->fillRect(fillRect, pal.brush(QPalette::Base));
+ }
+ if (!flow()->isEmpty()) {
+ TQRect cr(cx, cy, cw, ch);
+ flow()->drawFloatingItems(p, cr.x(), cr.y(), cr.width(), cr.height(), pal, false);
+ }
+ }
+
+ if (buf_pixmap && buf_pixmap->height() > 300) {
+ delete buf_pixmap;
+ buf_pixmap = 0;
+ }
+
+ TQTextFormat::setPainter(oldPainter);
+ return lastFormatted;
+}
+
+/*
+ #### this function only sets the default font size in the format collection
+ */
+void TQTextDocument::setDefaultFormat(const QFont &font, const QColor &color)
+{
+ bool reformat = font != fCollection->defaultFormat()->font();
+ for (int idx = 0; idx < childList.size(); ++idx) {
+ TQTextDocument *dc = childList.at(idx);
+ dc->setDefaultFormat(font, color);
+ }
+ fCollection->updateDefaultFormat(font, color, sheet_);
+
+ if (!reformat)
+ return;
+ tStopWidth = formatCollection()->defaultFormat()->width(TQLatin1Char('x')) * 8;
+
+ // invalidate paragraphs and custom items
+ TQTextParagraph *p = fParag;
+ while (p) {
+ p->invalidate(0);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ for (int i = 0; i < p->length() - 1; ++i)
+ if (p->at(i)->isCustom())
+ p->at(i)->customItem()->invalidate();
+#endif
+ p = p->next();
+ }
+}
+
+
+/*!
+ \preliminary
+
+ Generates an internal object for the tag called \a name, given the
+ attributes \a attr, and using additional information provided by
+ the mime source factory \a factory.
+
+ \a context is the optional context of the document, i.e. the path
+ to look for relative links. This becomes important if the text
+ contains relative references, for example within image tags.
+ QSimpleRichText always uses the default mime source factory (see
+ \l{TQMimeSourceFactory::defaultFactory()}) to resolve these
+ references. The context will then be used to calculate the
+ absolute path. See TQMimeSourceFactory::makeAbsolute() for details.
+
+ \a emptyTag and \a doc are for internal use only.
+
+ This function should not be used in application code.
+*/
+#ifndef QT_NO_TEXTCUSTOMITEM
+TQTextCustomItem* TQTextDocument::tag(TQStyleSheet *sheet, const TQString& name,
+ const QMap<TQString, TQString> &attr,
+ const TQString& context,
+ const TQMimeSourceFactory& factory,
+ bool /*emptyTag */, TQTextDocument *doc)
+{
+ const TQStyleSheetItem* style = sheet->item(name);
+ // first some known tags
+ if (!style)
+ return 0;
+ if (style->name() == TQLatin1String("img"))
+ return new TQTextImage(doc, attr, context, (TQMimeSourceFactory&)factory);
+ if (style->name() == TQLatin1String("hr"))
+ return new TQTextHorizontalLine(doc, attr, context, (TQMimeSourceFactory&)factory );
+ return 0;
+}
+#endif
+
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+void TQTextDocument::registerCustomItem(TQTextCustomItem *i, TQTextParagraph *p)
+{
+ if (i && i->placement() != TQTextCustomItem::PlaceInline) {
+ flow_->registerFloatingItem(i);
+ p->registerFloatingItem(i);
+ i->setParagraph(p);
+ }
+ p->mightHaveCustomItems = mightHaveCustomItems = true;
+}
+
+void TQTextDocument::unregisterCustomItem(TQTextCustomItem *i, TQTextParagraph *p)
+{
+ p->unregisterFloatingItem(i);
+ i->setParagraph(0);
+ flow_->unregisterFloatingItem(i);
+}
+#endif
+
+bool TQTextDocument::hasFocusParagraph() const
+{
+ return !!focusIndicator.parag;
+}
+
+TQString TQTextDocument::focusHref() const
+{
+ return focusIndicator.href;
+}
+
+TQString TQTextDocument::focusName() const
+{
+ return focusIndicator.name;
+}
+
+bool TQTextDocument::focusNextPrevChild(bool next)
+{
+ if (!focusIndicator.parag) {
+ if (next) {
+ focusIndicator.parag = fParag;
+ focusIndicator.start = 0;
+ focusIndicator.len = 0;
+ } else {
+ focusIndicator.parag = lParag;
+ focusIndicator.start = lParag->length();
+ focusIndicator.len = 0;
+ }
+ } else {
+ focusIndicator.parag->setChanged(true);
+ }
+ focusIndicator.href.clear();
+ focusIndicator.name.clear();
+
+ if (next) {
+ TQTextParagraph *p = focusIndicator.parag;
+ int index = focusIndicator.start + focusIndicator.len;
+ while (p) {
+ for (int i = index; i < p->length(); ++i) {
+ if (p->at(i)->isAnchor()) {
+ p->setChanged(true);
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = p->at(i)->anchorHref();
+ focusIndicator.name = p->at(i)->anchorName();
+ while (i < p->length()) {
+ if (!p->at(i)->isAnchor())
+ return true;
+ focusIndicator.len++;
+ i++;
+ }
+#ifndef QT_NO_TEXTCUSTOMITEM
+ } else if (p->at(i)->isCustom()) {
+ if (p->at(i)->customItem()->isNested()) {
+ TQTextTable *t = (TQTextTable*)p->at(i)->customItem();
+ QList<TQTextTableCell *> cells = t->tableCells();
+ // first try to continue
+ int idx;
+ bool resetCells = true;
+ for (idx = 0; idx < cells.size(); ++idx) {
+ TQTextTableCell *c = cells.at(idx);
+ if (c->richText()->hasFocusParagraph()) {
+ if (c->richText()->focusNextPrevChild(next)) {
+ p->setChanged(true);
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = c->richText()->focusHref();
+ focusIndicator.name = c->richText()->focusName();
+ return true;
+ } else {
+ resetCells = false;
+ ++idx;
+ break;
+ }
+ }
+ }
+ // now really try
+ if (resetCells)
+ idx = 0;
+ for (; idx < cells.size(); ++idx) {
+ TQTextTableCell *c = cells.at(idx);
+ if (c->richText()->focusNextPrevChild(next)) {
+ p->setChanged(true);
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = c->richText()->focusHref();
+ focusIndicator.name = c->richText()->focusName();
+ return true;
+ }
+ }
+ }
+#endif
+ }
+ }
+ index = 0;
+ p = p->next();
+ }
+ } else {
+ TQTextParagraph *p = focusIndicator.parag;
+ int index = focusIndicator.start - 1;
+ if (focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1)
+ index++;
+ while (p) {
+ for (int i = index; i >= 0; --i) {
+ if (p->at(i)->isAnchor()) {
+ p->setChanged(true);
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = p->at(i)->anchorHref();
+ focusIndicator.name = p->at(i)->anchorName();
+ while (i >= -1) {
+ if (i < 0 || !p->at(i)->isAnchor()) {
+ focusIndicator.start++;
+ return true;
+ }
+ if (i < 0)
+ break;
+ focusIndicator.len++;
+ focusIndicator.start--;
+ i--;
+ }
+#ifndef QT_NO_TEXTCUSTOMITEM
+ } else if (p->at(i)->isCustom()) {
+ if (p->at(i)->customItem()->isNested()) {
+ TQTextTable *t = (TQTextTable*)p->at(i)->customItem();
+ QList<TQTextTableCell *> cells = t->tableCells();
+ // first try to continue
+ int idx;
+ bool resetCells = true;
+ for (idx = cells.size()-1; idx >= 0; --idx) {
+ TQTextTableCell *c = cells.at(idx);
+ if (c->richText()->hasFocusParagraph()) {
+ if (c->richText()->focusNextPrevChild(next)) {
+ p->setChanged(true);
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = c->richText()->focusHref();
+ focusIndicator.name = c->richText()->focusName();
+ return true;
+ } else {
+ resetCells = false;
+ --idx;
+ break;
+ }
+ }
+ }
+ // now really try
+ if (resetCells)
+ idx = cells.size()-1;
+ for (; idx >= 0; --idx) {
+ TQTextTableCell *c = cells.at(idx);
+ if (c->richText()->focusNextPrevChild(next)) {
+ p->setChanged(true);
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = c->richText()->focusHref();
+ focusIndicator.name = c->richText()->focusName();
+ return true;
+ }
+ }
+ }
+#endif
+ }
+ }
+ p = p->prev();
+ if (p)
+ index = p->length() - 1;
+ }
+ }
+
+ focusIndicator.parag = 0;
+
+ return false;
+}
+
+int TQTextDocument::length() const
+{
+ int l = -1;
+ TQTextParagraph *p = fParag;
+ while (p) {
+ l += p->length();
+ p = p->next();
+ }
+ return qMax(0,l);
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+int TQTextFormat::width(const TQChar &c) const
+{
+ if (c.unicode() == 0xad) // soft hyphen
+ return 0;
+ if (!pntr || !pntr->isActive()) {
+ if (c == TQLatin1Char('\t'))
+ return fm.width(TQLatin1Char(' '));
+ if (ha == AlignNormal) {
+ int w;
+ if (c.row())
+ w = fm.width(c);
+ else
+ w = widths[c.unicode()];
+ if (w == 0 && !c.row()) {
+ w = fm.width(c);
+ ((TQTextFormat*)this)->widths[c.unicode()] = w;
+ }
+ return w;
+ } else {
+ QFont f(fn);
+ if (usePixelSizes)
+ f.setPixelSize((f.pixelSize() * 2) / 3);
+ else
+ f.setPointSize((f.pointSize() * 2) / 3);
+ QFontMetrics fm_(f);
+ return fm_.width(c);
+ }
+ }
+
+ QFont f(fn);
+ if (ha != AlignNormal) {
+ if (usePixelSizes)
+ f.setPixelSize((f.pixelSize() * 2) / 3);
+ else
+ f.setPointSize((f.pointSize() * 2) / 3);
+ }
+ applyFont(f);
+
+ return pntr_fm->width(c);
+}
+
+int TQTextFormat::width(const TQString &str, int pos) const
+{
+ int w = 0;
+ if (str.unicode()[pos].unicode() == 0xad)
+ return w;
+ if (!pntr || !pntr->isActive()) {
+ if (ha == AlignNormal) {
+ w = fm.charWidth(str, pos);
+ } else {
+ QFont f(fn);
+ if (usePixelSizes)
+ f.setPixelSize((f.pixelSize() * 2) / 3);
+ else
+ f.setPointSize((f.pointSize() * 2) / 3);
+ QFontMetrics fm_(f);
+ w = fm_.charWidth(str, pos);
+ }
+ } else {
+ QFont f(fn);
+ if (ha != AlignNormal) {
+ if (usePixelSizes)
+ f.setPixelSize((f.pixelSize() * 2) / 3);
+ else
+ f.setPointSize((f.pointSize() * 2) / 3);
+ }
+ applyFont(f);
+ w = pntr_fm->charWidth(str, pos);
+ }
+ return w;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextString::TQTextString()
+{
+ bidiDirty = true;
+ bidi = false;
+ rightToLeft = false;
+ dir = TQChar::DirON;
+}
+
+TQTextString::TQTextString(const TQTextString &s)
+{
+ bidiDirty = true;
+ bidi = s.bidi;
+ rightToLeft = s.rightToLeft;
+ dir = s.dir;
+ data = s.data;
+ data.detach();
+ for (int i = 0; i < (int)data.size(); ++i) {
+ TQTextFormat *f = data[i].format();
+ if (f)
+ f->addRef();
+ }
+}
+
+void TQTextString::insert(int index, const QString &s, TQTextFormat *f)
+{
+ insert(index, s.unicode(), s.length(), f);
+}
+
+void TQTextString::insert(int index, const QChar *unicode, int len, TQTextFormat *f)
+{
+ int os = data.size();
+ data.resize(data.size() + len);
+ if (index < os) {
+ memmove(data.data() + index + len, data.data() + index,
+ sizeof(TQTextStringChar) * (os - index));
+ }
+ TQTextStringChar *ch = data.data() + index;
+ for (int i = 0; i < len; ++i) {
+ ch->x = 0;
+ ch->lineStart = 0;
+ ch->nobreak = false;
+ ch->type = TQTextStringChar::Regular;
+ ch->p.format = f;
+ ch->rightToLeft = 0;
+ ch->c = unicode[i];
+ ++ch;
+ }
+ bidiDirty = true;
+}
+
+TQTextString::~TQTextString()
+{
+ clear();
+}
+
+void TQTextString::insert(int index, TQTextStringChar *c, bool doAddRefFormat )
+{
+ int os = data.size();
+ data.resize(data.size() + 1);
+ if (index < os) {
+ memmove(data.data() + index + 1, data.data() + index,
+ sizeof(TQTextStringChar) * (os - index));
+ }
+ TQTextStringChar &ch = data[(int)index];
+ ch.c = c->c;
+ ch.x = 0;
+ ch.lineStart = 0;
+ ch.rightToLeft = 0;
+ ch.p.format = 0;
+ ch.type = TQTextStringChar::Regular;
+ ch.nobreak = false;
+ if (doAddRefFormat && c->format())
+ c->format()->addRef();
+ ch.setFormat(c->format());
+ bidiDirty = true;
+}
+
+int TQTextString::appendParagraphs( TQTextParagraph *start, TQTextParagraph *end )
+{
+ int paragCount = 0;
+ int newLength = data.size();
+ for (TQTextParagraph *p = start; p != end; p = p->next()) {
+ newLength += p->length();
+ ++paragCount;
+ }
+
+ const int oldLength = data.size();
+ data.resize(newLength);
+
+ TQTextStringChar *d = &data[oldLength];
+ for (TQTextParagraph *p = start; p != end; p = p->next()) {
+ const TQTextStringChar * const src = p->at(0);
+ int i = 0;
+ for (; i < p->length() - 1; ++i) {
+ d[i].c = src[i].c;
+ d[i].x = 0;
+ d[i].lineStart = 0;
+ d[i].rightToLeft = 0;
+ d[i].type = TQTextStringChar::Regular;
+ d[i].nobreak = false;
+ d[i].p.format = src[i].format();
+ if (d[i].p.format)
+ d[i].p.format->addRef();
+ }
+ d[i].x = 0;
+ d[i].lineStart = 0;
+ d[i].nobreak = false;
+ d[i].type = TQTextStringChar::Regular;
+ d[i].p.format = 0;
+ d[i].rightToLeft = 0;
+ d[i].c = TQLatin1Char('\n');
+ d += p->length();
+ }
+
+ bidiDirty = true;
+ return paragCount;
+}
+
+void TQTextString::truncate(int index)
+{
+ index = qMax(index, 0);
+ index = qMin(index, (int)data.size() - 1);
+ if (index < (int)data.size()) {
+ for (int i = index + 1; i < (int)data.size(); ++i) {
+ TQTextStringChar &ch = data[i];
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (!(ch.type == TQTextStringChar::Regular)) {
+ delete ch.customItem();
+ if (ch.p.custom->format)
+ ch.p.custom->format->removeRef();
+ delete ch.p.custom;
+ ch.p.custom = 0;
+ } else
+#endif
+ if (ch.format()) {
+ ch.format()->removeRef();
+ }
+ }
+ }
+ data.resize(index);
+ bidiDirty = true;
+}
+
+void TQTextString::remove(int index, int len)
+{
+ for (int i = index; i < (int)data.size() && i - index < len; ++i) {
+ TQTextStringChar &ch = data[i];
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (!(ch.type == TQTextStringChar::Regular)) {
+ delete ch.customItem();
+ if (ch.p.custom->format)
+ ch.p.custom->format->removeRef();
+ delete ch.p.custom;
+ ch.p.custom = 0;
+ } else
+#endif
+ if (ch.format()) {
+ ch.format()->removeRef();
+ }
+ }
+ memmove(data.data() + index, data.data() + index + len,
+ sizeof(TQTextStringChar) * (data.size() - index - len));
+ data.resize(data.size() - len);
+ bidiDirty = true;
+}
+
+void TQTextString::clear()
+{
+ for (int i = 0; i < (int)data.count(); ++i) {
+ TQTextStringChar &ch = data[i];
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (!(ch.type == TQTextStringChar::Regular)) {
+ if (ch.customItem() && ch.customItem()->placement() == TQTextCustomItem::PlaceInline)
+ delete ch.customItem();
+ if (ch.p.custom->format)
+ ch.p.custom->format->removeRef();
+ delete ch.p.custom;
+ ch.p.custom = 0;
+ } else
+#endif
+ if (ch.format()) {
+ ch.format()->removeRef();
+ }
+ }
+ data.resize(0);
+ bidiDirty = true;
+}
+
+void TQTextString::setFormat(int index, TQTextFormat *f, bool useCollection)
+{
+ TQTextStringChar &ch = data[index];
+ if (useCollection && ch.format())
+ ch.format()->removeRef();
+ ch.setFormat(f);
+}
+
+void TQTextString::checkBidi() const
+{
+ // ############ fix BIDI handling
+ TQTextString *that = (TQTextString *)this;
+ that->bidiDirty = false;
+ int length = data.size();
+ if (!length) {
+ that->bidi = rightToLeft;
+ that->rightToLeft = (dir == TQChar::DirR);
+ return;
+ }
+
+ if (dir == TQChar::DirR) {
+ that->rightToLeft = true;
+ } else if (dir == TQChar::DirL) {
+ that->rightToLeft = false;
+ } else {
+ that->rightToLeft = (QApplication::layoutDirection() == Qt::RightToLeft);
+ }
+
+ const TQTextStringChar *start = data.data();
+ const TQTextStringChar *end = start + length;
+
+ ((TQTextString *)this)->stringCache = toString(data);
+
+ // determines the properties we need for layouting
+ QTextEngine textEngine;
+ textEngine.text = toString();
+ textEngine.option.setTextDirection(rightToLeft ? Qt::RightToLeft : Qt::LeftToRight);
+ textEngine.itemize();
+ const HB_CharAttributes *ca = textEngine.attributes() + length-1;
+ TQTextStringChar *ch = (TQTextStringChar *)end - 1;
+ QScriptItem *item = &textEngine.layoutData->items[textEngine.layoutData->items.size()-1];
+ unsigned char bidiLevel = item->analysis.bidiLevel;
+ that->bidi = (bidiLevel || rightToLeft);
+ int pos = length-1;
+ while (ch >= start) {
+ if (item->position > pos) {
+ --item;
+ Q_ASSERT(item >= &textEngine.layoutData->items[0]);
+ bidiLevel = item->analysis.bidiLevel;
+ if (bidiLevel)
+ that->bidi = true;
+ }
+ ch->softBreak = ca->lineBreakType >= HB_Break;
+ ch->whiteSpace = ca->whiteSpace;
+ ch->charStop = ca->charStop;
+ ch->bidiLevel = bidiLevel;
+ ch->rightToLeft = (bidiLevel%2);
+ --ch;
+ --ca;
+ --pos;
+ }
+}
+
+void TQTextDocument::setStyleSheet(TQStyleSheet *s)
+{
+ if (!s)
+ return;
+ sheet_ = s;
+ list_tm = list_bm = par_tm = par_bm = 12;
+ list_lm = 40;
+ li_tm = li_bm = 0;
+ TQStyleSheetItem* item = s->item(TQLatin1String("ol"));
+ if (item) {
+ list_tm = qMax(0,item->margin(TQStyleSheetItem::MarginTop));
+ list_bm = qMax(0,item->margin(TQStyleSheetItem::MarginBottom));
+ list_lm = qMax(0,item->margin(TQStyleSheetItem::MarginLeft));
+ }
+ if ((item = s->item(TQLatin1String("li")))) {
+ li_tm = qMax(0,item->margin(TQStyleSheetItem::MarginTop));
+ li_bm = qMax(0,item->margin(TQStyleSheetItem::MarginBottom));
+ }
+ if ((item = s->item(TQLatin1String("p")))) {
+ par_tm = qMax(0,item->margin(TQStyleSheetItem::MarginTop));
+ par_bm = qMax(0,item->margin(TQStyleSheetItem::MarginBottom));
+ }
+}
+
+void TQTextDocument::setUnderlineLinks(bool b) {
+ underlLinks = b;
+ for (int idx = 0; idx < childList.size(); ++idx) {
+ TQTextDocument *dc = childList.at(idx);
+ dc->setUnderlineLinks(b);
+ }
+}
+
+void TQTextStringChar::setFormat(TQTextFormat *f)
+{
+ if (type == Regular) {
+ p.format = f;
+ } else {
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (!p.custom) {
+ p.custom = new CustomData;
+ p.custom->custom = 0;
+ }
+ p.custom->format = f;
+#endif
+ }
+}
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+void TQTextStringChar::setCustomItem(TQTextCustomItem *i)
+{
+ if (type == Regular) {
+ TQTextFormat *f = format();
+ p.custom = new CustomData;
+ p.custom->format = f;
+ } else {
+ delete p.custom->custom;
+ }
+ p.custom->custom = i;
+ type = (type == Anchor ? CustomAnchor : Custom);
+}
+
+void TQTextStringChar::loseCustomItem()
+{
+ if (type == Custom) {
+ TQTextFormat *f = p.custom->format;
+ p.custom->custom = 0;
+ delete p.custom;
+ type = Regular;
+ p.format = f;
+ } else if (type == CustomAnchor) {
+ p.custom->custom = 0;
+ type = Anchor;
+ }
+}
+
+#endif
+
+TQString TQTextStringChar::anchorName() const
+{
+ if (type == Regular)
+ return TQString();
+ else
+ return p.custom->anchorName;
+}
+
+TQString TQTextStringChar::anchorHref() const
+{
+ if (type == Regular)
+ return TQString();
+ else
+ return p.custom->anchorHref;
+}
+
+void TQTextStringChar::setAnchor(const TQString& name, const TQString& href)
+{
+ if (type == Regular) {
+ TQTextFormat *f = format();
+ p.custom = new CustomData;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ p.custom->custom = 0;
+#endif
+ p.custom->format = f;
+ type = Anchor;
+ } else if (type == Custom) {
+ type = CustomAnchor;
+ }
+ p.custom->anchorName = name;
+ p.custom->anchorHref = href;
+}
+
+
+int TQTextString::width(int idx) const
+{
+ int w = 0;
+ TQTextStringChar *c = &at(idx);
+ if (!c->charStop || c->c.unicode() == 0xad || c->c.unicode() == 0x2028)
+ return 0;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if(c->isCustom()) {
+ if(c->customItem()->placement() == TQTextCustomItem::PlaceInline)
+ w = c->customItem()->width;
+ } else
+#endif
+ {
+ int r = c->c.row();
+ if(r < 0x06
+#ifndef Q_WS_WIN
+ // Uniscribe's handling of Asian makes the condition below fail.
+ || (r > 0x1f && !(r > 0xd7 && r < 0xe0))
+#endif
+ ) {
+ w = c->format()->width(c->c);
+ } else {
+ // complex text. We need some hacks to get the right metric here
+ w = c->format()->width(toString(), idx);
+ }
+ }
+ return w;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextParagraph::TQTextParagraph(TQTextDocument *dc, TQTextParagraph *pr, TQTextParagraph *nx, bool updateIds)
+ : p(pr), n(nx), docOrPseudo(dc),
+ changed(false), firstFormat(true), firstPProcess(true), needPreProcess(false), fullWidth(true),
+ lastInFrame(false), visible(true), breakable(true), movedDown(false),
+ mightHaveCustomItems(false), hasdoc(dc != 0), litem(false), rtext(false),
+ align(0), lstyle(TQStyleSheetItem::ListDisc), invalid(0), mSelections(0),
+#ifndef QT_NO_TEXTCUSTOMITEM
+ mFloatingItems(0),
+#endif
+ utm(0), ubm(0), ulm(0), urm(0), uflm(0), ulinespacing(0),
+ tabStopWidth(0), minwidth(0), tArray(0), eData(0), ldepth(0)
+{
+ lstyle = TQStyleSheetItem::ListDisc;
+ if (!hasdoc)
+ docOrPseudo = new TQTextParagraphPseudoDocument;
+ bgcol = 0;
+ list_val = -1;
+ paintdevice = 0;
+ TQTextFormat* defFormat = formatCollection()->defaultFormat();
+ if (!hasdoc) {
+ tabStopWidth = defFormat->width(TQLatin1Char('x')) * 8;
+ pseudoDocument()->commandHistory = new TQTextCommandHistory(100);
+ }
+
+ if (p)
+ p->n = this;
+ if (n)
+ n->p = this;
+
+ if (!p && hasdoc)
+ document()->setFirstParagraph(this);
+ if (!n && hasdoc)
+ document()->setLastParagraph(this);
+
+ state = -1;
+
+ if (p)
+ id = p->id + 1;
+ else
+ id = 0;
+ if (n && updateIds) {
+ TQTextParagraph *s = n;
+ while (s) {
+ s->id = s->p->id + 1;
+ s->invalidateStyleCache();
+ s = s->n;
+ }
+ }
+
+ str = new TQTextString();
+ const TQChar ch(TQLatin1Char(' '));
+ str->insert(0, &ch, 1, formatCollection()->defaultFormat());
+}
+
+TQTextParagraph::~TQTextParagraph()
+{
+ delete str;
+ if (hasdoc) {
+ register TQTextDocument *doc = document();
+ if (this == doc->minwParag) {
+ doc->minwParag = 0;
+ doc->minw = 0;
+ }
+ if (this == doc->curParag)
+ doc->curParag = 0;
+ } else {
+ delete pseudoDocument();
+ }
+ delete [] tArray;
+ delete eData;
+ QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin();
+ for (; it != lineStarts.end(); ++it)
+ delete *it;
+ if (mSelections)
+ delete mSelections;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (mFloatingItems)
+ delete mFloatingItems;
+#endif
+ if (p)
+ p->setNext(n);
+ if (n)
+ n->setPrev(p);
+ delete bgcol;
+}
+
+void TQTextParagraph::setNext(TQTextParagraph *s)
+{
+ n = s;
+ if (!n && hasdoc)
+ document()->setLastParagraph(this);
+}
+
+void TQTextParagraph::setPrev(TQTextParagraph *s)
+{
+ p = s;
+ if (!p && hasdoc)
+ document()->setFirstParagraph(this);
+}
+
+void TQTextParagraph::invalidate(int chr)
+{
+ if (invalid < 0)
+ invalid = chr;
+ else
+ invalid = qMin(invalid, chr);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (mFloatingItems) {
+ for (int idx = 0; idx < mFloatingItems->size(); ++idx) {
+ TQTextCustomItem *i = mFloatingItems->at(idx);
+ i->ypos = -1;
+ }
+ }
+#endif
+ invalidateStyleCache();
+}
+
+void TQTextParagraph::invalidateStyleCache()
+{
+ if (list_val < 0)
+ list_val = -1;
+}
+
+
+void TQTextParagraph::insert(int index, const QString &s)
+{
+ insert(index, s.unicode(), s.length());
+}
+
+void TQTextParagraph::insert(int index, const QChar *unicode, int len)
+{
+ if (hasdoc && !document()->useFormatCollection() && document()->preProcessor())
+ str->insert(index, unicode, len,
+ document()->preProcessor()->format(TQTextPreProcessor::Standard));
+ else
+ str->insert(index, unicode, len, formatCollection()->defaultFormat());
+ invalidate(index);
+ needPreProcess = true;
+}
+
+void TQTextParagraph::truncate(int index)
+{
+ str->truncate(index);
+ insert(length(), TQLatin1String(" "));
+ needPreProcess = true;
+}
+
+void TQTextParagraph::remove(int index, int len)
+{
+ if (index + len - str->length() > 0)
+ return;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ for (int i = index; i < index + len; ++i) {
+ TQTextStringChar *c = at(i);
+ if (hasdoc && c->isCustom()) {
+ document()->unregisterCustomItem(c->customItem(), this);
+ }
+ }
+#endif
+ str->remove(index, len);
+ invalidate(0);
+ needPreProcess = true;
+}
+
+void TQTextParagraph::join(TQTextParagraph *s)
+{
+ int oh = r.height() + s->r.height();
+ n = s->n;
+ if (n)
+ n->p = this;
+ else if (hasdoc)
+ document()->setLastParagraph(this);
+
+ int start = str->length();
+ if (length() > 0 && at(length() - 1)->c == TQLatin1Char(' ')) {
+ remove(length() - 1, 1);
+ --start;
+ }
+ append(s->str->toString(), true);
+
+ for (int i = 0; i < s->length(); ++i) {
+ if (!hasdoc || document()->useFormatCollection()) {
+ s->str->at(i).format()->addRef();
+ str->setFormat(i + start, s->str->at(i).format(), true);
+ }
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (s->str->at(i).isCustom()) {
+ TQTextCustomItem * item = s->str->at(i).customItem();
+ str->at(i + start).setCustomItem(item);
+ s->str->at(i).loseCustomItem();
+ if (hasdoc) {
+ document()->unregisterCustomItem(item, s);
+ document()->registerCustomItem(item, this);
+ }
+ }
+ if (s->str->at(i).isAnchor()) {
+ str->at(i + start).setAnchor(s->str->at(i).anchorName(),
+ s->str->at(i).anchorHref());
+ }
+#endif
+ }
+
+ if (!extraData() && s->extraData()) {
+ setExtraData(s->extraData());
+ s->setExtraData(0);
+ } else if (extraData() && s->extraData()) {
+ extraData()->join(s->extraData());
+ }
+ delete s;
+ invalidate(0);
+ r.setHeight(oh);
+ needPreProcess = true;
+ if (n) {
+ TQTextParagraph *s = n;
+ s->invalidate(0);
+ while (s) {
+ s->id = s->p->id + 1;
+ s->state = -1;
+ s->needPreProcess = true;
+ s->changed = true;
+ s->invalidateStyleCache();
+ s = s->n;
+ }
+ }
+ format();
+ state = -1;
+}
+
+void TQTextParagraph::move(int &dy)
+{
+ if (dy == 0)
+ return;
+ changed = true;
+ r.moveBy(0, dy);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (mFloatingItems) {
+ for (int idx = 0; idx < mFloatingItems->size(); ++idx) {
+ TQTextCustomItem *i = mFloatingItems->at(idx);
+ i->ypos += dy;
+ }
+ }
+#endif
+ if (p)
+ p->lastInFrame = true;
+
+ // do page breaks if required
+ if (hasdoc && document()->isPageBreakEnabled()) {
+ int shift;
+ if ((shift = document()->formatter()->formatVertically( document(), this))) {
+ if (p)
+ p->setChanged(true);
+ dy += shift;
+ }
+ }
+}
+
+void TQTextParagraph::format(int start, bool doMove)
+{
+ if (!str || str->length() == 0 || !formatter())
+ return;
+
+ if (hasdoc &&
+ document()->preProcessor() &&
+ (needPreProcess || state == -1))
+ document()->preProcessor()->process(document(), this, invalid <= 0 ? 0 : invalid);
+ needPreProcess = false;
+
+ if (invalid == -1)
+ return;
+
+ r.moveTopLeft(QPoint(documentX(), p ? p->r.y() + p->r.height() : documentY()));
+ if (p)
+ p->lastInFrame = false;
+
+ movedDown = false;
+ bool formattedAgain = false;
+
+ formatAgain:
+
+ r.setWidth(documentWidth());
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (hasdoc && mFloatingItems) {
+ for (int idx = 0; idx < mFloatingItems->size(); ++idx) {
+ TQTextCustomItem *i = mFloatingItems->at(idx);
+ i->ypos = r.y();
+ if (i->placement() == TQTextCustomItem::PlaceRight) {
+ i->xpos = r.x() + r.width() - i->width;
+ }
+ }
+ }
+#endif
+ QMap<int, QTextLineStart*> oldLineStarts = lineStarts;
+ lineStarts.clear();
+ int y = formatter()->format(document(), this, start, oldLineStarts);
+
+
+ r.setWidth(qMax(r.width(), formatter()->minimumWidth()));
+
+
+ QMap<int, QTextLineStart*>::Iterator it = oldLineStarts.begin();
+
+ for (; it != oldLineStarts.end(); ++it)
+ delete *it;
+
+ if (!hasdoc) { // qt_format_text bounding rect handling
+ it = lineStarts.begin();
+ int usedw = 0;
+ for (; it != lineStarts.end(); ++it)
+ usedw = qMax(usedw, (*it)->w);
+ if (r.width() <= 0) {
+ // if the user specifies an invalid rect, this means that the
+ // bounding box should grow to the width that the text actually
+ // needs
+ r.setWidth(usedw);
+ } else {
+ r.setWidth(qMin(usedw, r.width()));
+ }
+ }
+
+ if (y != r.height())
+ r.setHeight(y);
+
+ if (!visible) {
+ r.setHeight(0);
+ } else {
+ int minw = minwidth = formatter()->minimumWidth();
+ int wused = formatter()->widthUsed();
+ wused = qMax(minw, wused);
+ if (hasdoc) {
+ document()->setMinimumWidth(minw, wused, this);
+ } else {
+ pseudoDocument()->minw = qMax(pseudoDocument()->minw, minw);
+ pseudoDocument()->wused = qMax(pseudoDocument()->wused, wused);
+ }
+ }
+
+ // do page breaks if required
+ if (hasdoc && document()->isPageBreakEnabled()) {
+ int shift = document()->formatter()->formatVertically(document(), this);
+ if (shift && !formattedAgain) {
+ formattedAgain = true;
+ goto formatAgain;
+ }
+ }
+
+ if (n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y()) {
+ int dy = (r.y() + r.height()) - n->r.y();
+ TQTextParagraph *s = n;
+ bool makeInvalid = p && p->lastInFrame;
+ while (s && dy) {
+ if (!s->isFullWidth())
+ makeInvalid = true;
+ if (makeInvalid)
+ s->invalidate(0);
+ s->move(dy);
+ if (s->lastInFrame)
+ makeInvalid = true;
+ s = s->n;
+ }
+ }
+
+ firstFormat = false;
+ changed = true;
+ invalid = -1;
+ //##### string()->setTextChanged(false);
+}
+
+int TQTextParagraph::lineHeightOfChar(int i, int *bl, int *y) const
+{
+ if (!isValid())
+ ((TQTextParagraph*)this)->format();
+
+ QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end();
+ --it;
+ for (;;) {
+ if (i >= it.key()) {
+ if (bl)
+ *bl = (*it)->baseLine;
+ if (y)
+ *y = (*it)->y;
+ return (*it)->h;
+ }
+ if (it == lineStarts.begin())
+ break;
+ --it;
+ }
+
+ qWarning("TQTextParagraph::lineHeightOfChar: couldn't find lh for %d", i);
+ return 15;
+}
+
+TQTextStringChar *TQTextParagraph::lineStartOfChar(int i, int *index, int *line) const
+{
+ if (!isValid())
+ ((TQTextParagraph*)this)->format();
+
+ int l = (int)lineStarts.count() - 1;
+ QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.end();
+ --it;
+ for (;;) {
+ if (i >= it.key()) {
+ if (index)
+ *index = it.key();
+ if (line)
+ *line = l;
+ return &str->at(it.key());
+ }
+ if (it == lineStarts.begin())
+ break;
+ --it;
+ --l;
+ }
+
+ qWarning("TQTextParagraph::lineStartOfChar: couldn't find %d", i);
+ return 0;
+}
+
+int TQTextParagraph::lines() const
+{
+ if (!isValid())
+ ((TQTextParagraph*)this)->format();
+
+ return (int)lineStarts.count();
+}
+
+TQTextStringChar *TQTextParagraph::lineStartOfLine(int line, int *index) const
+{
+ if (!isValid())
+ ((TQTextParagraph*)this)->format();
+
+ if (line >= 0 && line < (int)lineStarts.count()) {
+ QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while (line-- > 0)
+ ++it;
+ int i = it.key();
+ if (index)
+ *index = i;
+ return &str->at(i);
+ }
+
+ qWarning("TQTextParagraph::lineStartOfLine: couldn't find %d", line);
+ return 0;
+}
+
+int TQTextParagraph::leftGap() const
+{
+ if (!isValid())
+ ((TQTextParagraph*)this)->format();
+
+ if (str->length() == 0)
+ return 0;
+
+ int line = 0;
+ int x = str->length() ? str->at(0).x : 0; /* set x to x of first char */
+ if (str->isBidi()) {
+ for (int i = 1; i < str->length()-1; ++i)
+ x = qMin(x, str->at(i).x);
+ return x;
+ }
+
+ QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while (line < (int)lineStarts.count()) {
+ int i = it.key(); /* char index */
+ x = qMin(x, str->at(i).x);
+ ++it;
+ ++line;
+ }
+ return x;
+}
+
+void TQTextParagraph::setFormat(int index, int len, TQTextFormat *f, bool useCollection, int flags)
+{
+ if (!f)
+ return;
+ if (index < 0)
+ index = 0;
+ if (index > str->length() - 1)
+ index = str->length() - 1;
+ if (index + len >= str->length())
+ len = str->length() - index;
+
+ TQTextFormatCollection *fc = 0;
+ if (useCollection)
+ fc = formatCollection();
+ TQTextFormat *of;
+ for (int i = 0; i < len; ++i) {
+ of = str->at(i + index).format();
+ if (!changed && (!of || f->key() != of->key()))
+ changed = true;
+ if (invalid == -1 &&
+ (f->font().family() != of->font().family() ||
+ f->font().pointSize() != of->font().pointSize() ||
+ f->font().weight() != of->font().weight() ||
+ f->font().italic() != of->font().italic() ||
+ f->vAlign() != of->vAlign())) {
+ invalidate(0);
+ }
+ if (flags == -1 || flags == TQTextFormat::Format || !fc) {
+ if (fc)
+ f = fc->format(f);
+ str->setFormat(i + index, f, useCollection);
+ } else {
+ TQTextFormat *fm = fc->format(of, f, flags);
+ str->setFormat(i + index, fm, useCollection);
+ }
+ }
+}
+
+void TQTextParagraph::indent(int *oldIndent, int *newIndent)
+{
+ if (!hasdoc || !document()->indent() || isListItem()) {
+ if (oldIndent)
+ *oldIndent = 0;
+ if (newIndent)
+ *newIndent = 0;
+ if (oldIndent && newIndent)
+ *newIndent = *oldIndent;
+ return;
+ }
+ document()->indent()->indent(document(), this, oldIndent, newIndent);
+}
+
+void TQTextParagraph::paint(TQPainter &painter, const QPalette &pal, TQTextCursor *cursor,
+ bool drawSelections, int clipx, int clipy, int clipw, int cliph)
+{
+ if (!visible)
+ return;
+ int i, y, h, baseLine, xstart, xend = 0;
+ i = y =h = baseLine = 0;
+ TQRect cursorRect;
+ drawSelections &= (mSelections != 0);
+ // macintosh full-width selection style
+ bool fullWidthStyle = QApplication::style()->styleHint(QStyle::SH_RichText_FullWidthSelection);
+ int fullSelectionWidth = 0;
+ if (drawSelections && fullWidthStyle)
+ fullSelectionWidth = (hasdoc ? document()->width() : r.width());
+
+ TQString qstr = str->toString();
+ qstr.detach();
+ // ### workaround so that \n are not drawn, actually this should
+ // be fixed in QFont somewhere (under Windows you get ugly boxes
+ // otherwise)
+ TQChar* uc = (TQChar*) qstr.unicode();
+ for (int ii = 0; ii < qstr.length(); ii++)
+ if (uc[(int)ii]== TQLatin1Char(TQLatin1Char('\n')) || uc[(int)ii] == TQLatin1Char('\t'))
+ uc[(int)ii] = 0x20;
+
+ int line = -1;
+ int paintStart = 0;
+ TQTextStringChar *chr = 0;
+ TQTextStringChar *nextchr = at(0);
+ for (i = 0; i < length(); i++) {
+ chr = nextchr;
+ if (i < length()-1)
+ nextchr = at(i+1);
+
+ // we flush at end of document
+ bool flush = (i == length()-1);
+ bool ignoreSoftHyphen = false;
+ if (!flush) {
+ // we flush at end of line
+ flush |= nextchr->lineStart;
+ // we flush on format changes
+ flush |= (nextchr->format() != chr->format());
+ // we flush on link changes
+ flush |= (nextchr->isLink() != chr->isLink());
+ // we flush on start of run
+ flush |= (nextchr->bidiLevel != chr->bidiLevel);
+ // we flush on bidi changes
+ flush |= (nextchr->rightToLeft != chr->rightToLeft);
+ // we flush before and after tabs
+ flush |= (chr->c == TQLatin1Char('\t') || nextchr->c == TQLatin1Char('\t'));
+ // we flush on soft hyphens
+ if (chr->c.unicode() == 0xad) {
+ flush = true;
+ if (!nextchr->lineStart)
+ ignoreSoftHyphen = true;
+ }
+ // we flush on custom items
+ flush |= chr->isCustom();
+ // we flush before custom items
+ flush |= nextchr->isCustom();
+ // when painting justified, we flush on spaces
+ if ((alignment() & Qt::AlignJustify) == Qt::AlignJustify)
+ flush |= chr->whiteSpace;
+ }
+
+ // init a new line
+ if (chr->lineStart) {
+ ++line;
+ paintStart = i;
+ lineInfo(line, y, h, baseLine);
+ if (clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph) { // outside clip area, leave
+ break;
+ }
+
+ // if this is the first line and we are a list item, draw the the bullet label
+ if (line == 0 && isListItem()) {
+ int x = chr->x;
+ if (str->isBidi()) {
+ if (str->isRightToLeft()) {
+ x = chr->x + str->width(0);
+ for (int k = 1; k < length(); ++k) {
+ if (str->at(k).lineStart)
+ break;
+ x = qMax(x, str->at(k).x + str->width(k));
+ }
+ } else {
+ x = chr->x;
+ for (int k = 1; k < length(); ++k) {
+ if (str->at(k).lineStart)
+ break;
+ x = qMin(x, str->at(k).x);
+ }
+ }
+ }
+ drawLabel(&painter, x, y, 0, 0, baseLine, pal);
+ }
+ }
+
+ // check for cursor mark
+ if (cursor && this == cursor->paragraph() && i == cursor->index()) {
+ TQTextStringChar *c = i == 0 ? chr : chr - 1;
+ cursorRect.setRect(cursor->x() , y + baseLine - c->format()->ascent(),
+ 1, c->format()->height());
+ }
+
+ if (flush) { // something changed, draw what we have so far
+ if (chr->rightToLeft) {
+ xstart = chr->x;
+ xend = at(paintStart)->x + str->width(paintStart);
+ } else {
+ xstart = at(paintStart)->x;
+ xend = chr->x;
+ if (i < length() - 1) {
+ if (!str->at(i + 1).lineStart &&
+ str->at(i + 1).rightToLeft == chr->rightToLeft)
+ xend = str->at(i + 1).x;
+ else
+ xend += str->width(i);
+ }
+ }
+
+ if ((clipx == -1 || clipw <= 0 || (xend >= clipx && xstart <= clipx + clipw)) &&
+ (clipy == -1 || clipy < y+r.y()+h)) {
+ if (!chr->isCustom())
+ drawString(painter, qstr, paintStart, i - paintStart + (ignoreSoftHyphen ? 0 : 1), xstart, y,
+ baseLine, xend-xstart, h, drawSelections, fullSelectionWidth,
+ chr, pal, chr->rightToLeft);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ else if (chr->customItem()->placement() == TQTextCustomItem::PlaceInline) {
+ bool inSelection = false;
+ if (drawSelections) {
+ QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->constFind(TQTextDocument::Standard);
+ inSelection = (it != mSelections->constEnd() && (*it).start <= i && (*it).end > i);
+ }
+ chr->customItem()->draw(&painter, chr->x, y,
+ clipx == -1 ? clipx : (clipx - r.x()),
+ clipy == -1 ? clipy : (clipy - r.y()),
+ clipw, cliph, pal, inSelection);
+ }
+#endif
+ }
+ paintStart = i+1;
+ }
+
+ }
+
+ // time to draw the cursor
+ const int cursor_extent = 4;
+ if (!cursorRect.isNull() && cursor &&
+ ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw))) {
+ painter.fillRect(cursorRect, pal.color(QPalette::Text));
+ painter.save();
+ if (string()->isBidi()) {
+ if (at(cursor->index())->rightToLeft) {
+ painter.setPen(Qt::black);
+ painter.drawLine(cursorRect.x(), cursorRect.y(), cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2);
+ painter.drawLine(cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2);
+ } else {
+ painter.setPen(Qt::black);
+ painter.drawLine(cursorRect.x(), cursorRect.y(), cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2);
+ painter.drawLine(cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2);
+ }
+ }
+ painter.restore();
+ }
+}
+
+//#define BIDI_DEBUG
+
+void TQTextParagraph::setColorForSelection(QColor &color, TQPainter &painter,
+ const QPalette &pal, int selection)
+{
+ if (selection < 0)
+ return;
+ color = (hasdoc && selection != TQTextDocument::Standard) ?
+ document()->selectionColor(selection) :
+ pal.color(QPalette::Highlight);
+ QColor text = (hasdoc && document()->hasSelectionTextColor(selection)) ? document()->selectionTextColor(selection) : pal.color(QPalette::HighlightedText);
+ if (text.isValid())
+ painter.setPen(text);
+}
+
+void TQTextParagraph::drawString(TQPainter &painter, const TQString &str, int start, int len,
+ int xstart, int y, int baseLine, int w, int h,
+ bool drawSelections, int fullSelectionWidth,
+ TQTextStringChar *formatChar, const QPalette& pal,
+ bool rightToLeft)
+{
+ bool plainText = hasdoc ? document()->textFormat() == TQt::PlainText : false;
+ TQTextFormat* format = formatChar->format();
+
+ int textFlags = int(rightToLeft ? Qt::TextForceRightToLeft : Qt::TextForceLeftToRight);
+
+ if (!plainText || (hasdoc && format->color() != document()->formatCollection()->defaultFormat()->color()))
+ painter.setPen(QPen(format->color()));
+ else
+ painter.setPen(pal.text().color());
+ painter.setFont(format->font());
+
+ if (hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty()) {
+ if (format->useLinkColor())
+ painter.setPen(document()->linkColor.isValid() ? document()->linkColor :
+ pal.link().color());
+ if (document()->underlineLinks()) {
+ QFont fn = format->font();
+ fn.setUnderline(true);
+ painter.setFont(fn);
+ }
+ }
+
+ int real_length = len;
+ if (len && !rightToLeft && start + len == length()) // don't draw the last character (trailing space)
+ len--;
+ if (len && str.unicode()[start+len-1] == TQChar::LineSeparator)
+ len--;
+
+
+ TQTextFormat::VerticalAlignment vAlign = format->vAlign();
+ if (vAlign != TQTextFormat::AlignNormal) {
+ // sub or superscript
+ QFont f(painter.font());
+ if (format->fontSizesInPixels())
+ f.setPixelSize((f.pixelSize() * 2) / 3);
+ else
+ f.setPointSize((f.pointSize() * 2) / 3);
+ painter.setFont(f);
+ int h = painter.fontMetrics().height();
+ baseLine += (vAlign == TQTextFormat::AlignSubScript) ? h/6 : -h/2;
+ }
+
+ bool allSelected = false;
+ if (drawSelections) {
+ QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->constFind(TQTextDocument::Standard);
+ allSelected = (it != mSelections->constEnd() && (*it).start <= start && (*it).end >= start+len);
+ }
+ if (!allSelected)
+ painter.drawText(QPointF(xstart, y + baseLine), str.mid(start, len), textFlags, /*justificationPadding*/0);
+
+#ifdef BIDI_DEBUG
+ painter.save();
+ painter.setPen (Qt::red);
+ painter.drawLine(xstart, y, xstart, y + baseLine);
+ painter.drawLine(xstart, y + baseLine/2, xstart + 10, y + baseLine/2);
+ int w = 0;
+ int i = 0;
+ while(i < len)
+ w += painter.fontMetrics().charWidth(str, start + i++);
+ painter.setPen (Qt::blue);
+ painter.drawLine(xstart + w - 1, y, xstart + w - 1, y + baseLine);
+ painter.drawLine(xstart + w - 1, y + baseLine/2, xstart + w - 1 - 10, y + baseLine/2);
+ painter.restore();
+#endif
+
+ // check if we are in a selection and draw it
+ if (drawSelections) {
+ QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->constEnd();
+ while (it != mSelections->constBegin()) {
+ --it;
+ int selStart = (*it).start;
+ int selEnd = (*it).end;
+ int tmpw = w;
+
+ selStart = qMax(selStart, start);
+ int real_selEnd = qMin(selEnd, start+real_length);
+ selEnd = qMin(selEnd, start+len);
+ bool extendRight = false;
+ bool extendLeft = false;
+ bool selWrap = (real_selEnd == length()-1 && n && n->hasSelection(it.key()));
+ if (selWrap
+ || ((real_selEnd < this->str->length()) && this->str->at(real_selEnd).lineStart)) {
+ extendRight = (fullSelectionWidth != 0);
+ if (!extendRight && !rightToLeft)
+ tmpw += painter.fontMetrics().width(TQLatin1Char(' '));
+ }
+ if (fullSelectionWidth && (selStart == 0 || this->str->at(selStart).lineStart)) {
+ extendLeft = true;
+ }
+ if (this->str->isRightToLeft() != rightToLeft)
+ extendLeft = extendRight = false;
+
+ if (this->str->isRightToLeft()) {
+ bool tmp = extendLeft;
+ extendLeft = extendRight;
+ extendRight = tmp;
+ }
+
+ if (selStart < real_selEnd ||
+ (selWrap && fullSelectionWidth && extendRight &&
+ // don't draw the standard selection on a printer=
+ (it.key() != TQTextDocument::Standard || !is_printer(&painter)))) {
+ int selection = it.key();
+ QColor color;
+ setColorForSelection(color, painter, pal, selection);
+ if (selStart != start || selEnd != start + len || selWrap) {
+ // have to clip
+ painter.save();
+ int cs, ce;
+ if (rightToLeft) {
+ cs = (selEnd != start + len) ?
+ this->str->at(this->str->previousCursorPosition(selEnd)).x : xstart;
+ ce = (selStart != start) ?
+ this->str->at(this->str->previousCursorPosition(selStart)).x : xstart+tmpw;
+ } else {
+ cs = (selStart != start) ? this->str->at(selStart).x : xstart;
+ ce = (selEnd != start + len) ? this->str->at(selEnd).x : xstart+tmpw;
+ }
+ TQRect r(cs, y, ce-cs, h);
+ if (extendLeft)
+ r.setLeft(0);
+ if (extendRight)
+ r.setRight(fullSelectionWidth);
+ QRegion reg(r);
+ if (painter.hasClipping())
+ reg &= painter.clipRegion();
+ painter.setClipRegion(reg);
+ }
+ int xleft = xstart;
+ if (extendLeft) {
+ tmpw += xstart;
+ xleft = 0;
+ }
+ if (extendRight)
+ tmpw = fullSelectionWidth - xleft;
+ if(color.isValid())
+ painter.fillRect(xleft, y, tmpw, h, color);
+ painter.drawText(QPointF(xstart, y + baseLine), str.mid(start, len), textFlags, /*justificationPadding*/0);
+ if (selStart != start || selEnd != start + len || selWrap)
+ painter.restore();
+ }
+ }
+ }
+
+ if (format->isMisspelled()) {
+ painter.save();
+ painter.setPen(QPen(Qt::red, 1, Qt::DotLine));
+ painter.drawLine(xstart, y + baseLine + 1, xstart + w, y + baseLine + 1);
+ painter.restore();
+ }
+
+ if (hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() &&
+ document()->focusIndicator.parag == this &&
+ ((document()->focusIndicator.start >= start &&
+ document()->focusIndicator.start + document()->focusIndicator.len <= start + len)
+ || (document()->focusIndicator.start <= start &&
+ document()->focusIndicator.start + document()->focusIndicator.len >= start + len))) {
+ QStyleOptionFocusRect opt;
+ opt.rect.setRect(xstart, y, w, h);
+#ifndef Q_WS_WIN
+ opt.state = QStyle::State_None;
+#else
+ // force drawing a focus rect but only on windows because it's
+ // configurable by the user in windows settings (see
+ // SH_UnderlineShortcut style hint) and we want to override
+ // this settings.
+ opt.state = QStyle::State_KeyboardFocusChange;
+#endif
+ opt.palette = pal;
+ QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, &painter);
+ }
+}
+
+void TQTextParagraph::drawLabel(TQPainter* p, int x, int y, int w, int h, int base,
+ const QPalette& pal)
+{
+ TQRect r (x, y, w, h);
+ TQStyleSheetItem::ListStyle s = listStyle();
+
+ p->save();
+ TQTextFormat *format = at(0)->format();
+ if (format) {
+ p->setPen(format->color());
+ p->setFont(format->font());
+ }
+ QFontMetrics fm(p->fontMetrics());
+ int size = fm.lineSpacing() / 3;
+
+ bool rtl = str->isRightToLeft();
+
+ switch (s) {
+ case TQStyleSheetItem::ListDecimal:
+ case TQStyleSheetItem::ListLowerAlpha:
+ case TQStyleSheetItem::ListUpperAlpha:
+ {
+ if (list_val == -1) { // uninitialised list value, calcluate the right one
+ int depth = listDepth();
+ list_val--;
+ // ### evil, square and expensive. This needs to be done when formatting, not when painting
+ TQTextParagraph* s = prev();
+ int depth_s;
+ while (s && (depth_s = s->listDepth()) >= depth) {
+ if (depth_s == depth && s->isListItem())
+ list_val--;
+ s = s->prev();
+ }
+ }
+
+ int n = list_val;
+ if (n < -1)
+ n = -n - 1;
+ TQString l;
+ switch (s) {
+ case TQStyleSheetItem::ListLowerAlpha:
+ if (n < 27) {
+ l = TQLatin1Char(('a' + (char) (n-1)));
+ break;
+ }
+ case TQStyleSheetItem::ListUpperAlpha:
+ if (n < 27) {
+ l = TQLatin1Char(('A' + (char) (n-1)));
+ break;
+ }
+ break;
+ default: //TQStyleSheetItem::ListDecimal:
+ l.setNum(n);
+ break;
+ }
+ if (rtl)
+ l.prepend(TQLatin1String(" ."));
+ else
+ l += TQString::fromLatin1(". ");
+ int x = (rtl ? r.left() : r.right() - fm.width(l));
+ p->drawText(x, r.top() + base, l);
+ }
+ break;
+ case TQStyleSheetItem::ListSquare:
+ {
+ int x = rtl ? r.left() + size : r.right() - size*2;
+ TQRect er(x, r.top() + fm.height() / 2 - size / 2, size, size);
+ p->fillRect(er , pal.brush(QPalette::Text));
+ }
+ break;
+ case TQStyleSheetItem::ListCircle:
+ {
+ int x = rtl ? r.left() + size : r.right() - size*2;
+ TQRect er(x, r.top() + fm.height() / 2 - size / 2, size, size);
+ p->drawEllipse(er);
+ }
+ break;
+ case TQStyleSheetItem::ListDisc:
+ default:
+ {
+ p->setBrush(pal.brush(QPalette::Text));
+ int x = rtl ? r.left() + size : r.right() - size*2;
+ TQRect er(x, r.top() + fm.height() / 2 - size / 2, size, size);
+ p->drawEllipse(er);
+ p->setBrush(Qt::NoBrush);
+ }
+ break;
+ }
+
+ p->restore();
+}
+
+#ifndef QT_NO_DATASTREAM
+void TQTextParagraph::readStyleInformation(QDataStream &stream)
+{
+ int int_align, int_lstyle;
+ uchar uchar_litem, uchar_rtext, uchar_dir;
+ stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm
+ >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir;
+ align = int_align; lstyle = (TQStyleSheetItem::ListStyle) int_lstyle;
+ litem = uchar_litem; rtext = uchar_rtext; str->setDirection((TQChar::Direction)uchar_dir);
+ TQTextParagraph* s = prev() ? prev() : this;
+ while (s) {
+ s->invalidate(0);
+ s = s->next();
+ }
+}
+
+void TQTextParagraph::writeStyleInformation(QDataStream& stream) const
+{
+ stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction();
+}
+#endif
+
+
+void TQTextParagraph::setListItem(bool li)
+{
+ if ((bool)litem == li)
+ return;
+ litem = li;
+ changed = true;
+ TQTextParagraph* s = prev() ? prev() : this;
+ while (s) {
+ s->invalidate(0);
+ s = s->next();
+ }
+}
+
+void TQTextParagraph::setListDepth(int depth) {
+ if (!hasdoc || depth == ldepth)
+ return;
+ ldepth = depth;
+ TQTextParagraph* s = prev() ? prev() : this;
+ while (s) {
+ s->invalidate(0);
+ s = s->next();
+ }
+}
+
+int *TQTextParagraph::tabArray() const
+{
+ int *ta = tArray;
+ if (!ta && hasdoc)
+ ta = document()->tabArray();
+ return ta;
+}
+
+int TQTextParagraph::nextTab(int, int x)
+{
+ int *ta = tArray;
+ if (hasdoc) {
+ if (!ta)
+ ta = document()->tabArray();
+ tabStopWidth = document()->tabStopWidth();
+ }
+ if (ta) {
+ int i = 0;
+ while (ta[i]) {
+ if (ta[i] >= x)
+ return tArray[i];
+ ++i;
+ }
+ return tArray[0];
+ } else {
+ int n;
+ if (tabStopWidth != 0)
+ n = x / tabStopWidth;
+ else
+ return x;
+ return tabStopWidth * (n + 1);
+ }
+}
+
+void TQTextParagraph::adjustToPainter(TQPainter *p)
+{
+#ifndef QT_NO_TEXTCUSTOMITEM
+ for (int i = 0; i < length(); ++i) {
+ if (at(i)->isCustom())
+ at(i)->customItem()->adjustToPainter(p);
+ }
+#endif
+}
+
+TQTextFormatCollection *TQTextParagraph::formatCollection() const
+{
+ if (hasdoc)
+ return document()->formatCollection();
+ TQTextFormatCollection* fc = &pseudoDocument()->collection;
+ if (paintdevice != fc->paintDevice())
+ fc->setPaintDevice(paintdevice);
+ return fc;
+}
+
+TQString TQTextParagraph::richText() const
+{
+ TQString s;
+ TQTextStringChar *formatChar = 0;
+ TQString spaces;
+ bool doStart = richTextExportStart && richTextExportStart->paragraph() == this;
+ bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this;
+ int i;
+ TQString lastAnchorName;
+ for (i = 0; i < length()-1; ++i) {
+ if (doStart && i && richTextExportStart->index() == i)
+ s += TQLatin1String("<!--StartFragment-->");
+ if (doEnd && richTextExportEnd->index() == i)
+ s += TQLatin1String("<!--EndFragment-->");
+ TQTextStringChar *c = &str->at(i);
+ if (c->isAnchor() && !c->anchorName().isEmpty() && c->anchorName() != lastAnchorName) {
+ lastAnchorName = c->anchorName();
+ if (c->anchorName().contains(TQLatin1Char('#'))) {
+// TQStringList l = c->anchorName().split(TQLatin1Char('#'));
+ TQStringList l = TQStringList::split(TQLatin1Char('#'), c->anchorName());
+ for (TQStringList::ConstIterator it = l.constBegin(); it != l.constEnd(); ++it)
+ s += TQLatin1String("<a name=\"") + *it + TQLatin1String("\"></a>");
+ } else {
+ s += TQLatin1String("<a name=\"") + c->anchorName() + TQLatin1String("\"></a>");
+ }
+ }
+ if (!formatChar) {
+ s += c->format()->makeFormatChangeTags(formatCollection()->defaultFormat(),
+ 0, TQString(), c->anchorHref());
+ formatChar = c;
+ } else if ((formatChar->format()->key() != c->format()->key()) ||
+ (c->anchorHref() != formatChar->anchorHref())) {
+ s += c->format()->makeFormatChangeTags(formatCollection()->defaultFormat(),
+ formatChar->format() , formatChar->anchorHref(), c->anchorHref());
+ formatChar = c;
+ }
+ if (c->c == TQLatin1Char('<'))
+ s += TQLatin1String("&lt;");
+ else if (c->c == TQLatin1Char('>'))
+ s += TQLatin1String("&gt;");
+ else if (c->c == TQLatin1Char('&'))
+ s += TQLatin1String("&amp;");
+ else if (c->c == TQLatin1Char('\"'))
+ s += TQLatin1String("&quot;");
+#ifndef QT_NO_TEXTCUSTOMITEM
+ else if (c->isCustom())
+ s += c->customItem()->richText();
+#endif
+ else if (c->c == TQLatin1Char('\n') || c->c == TQChar::LineSeparator)
+ s += TQLatin1String("<br />"); // space on purpose for compatibility with Netscape, Lynx & Co.
+ else
+ s += c->c;
+ }
+ if (doEnd && richTextExportEnd->index() == i)
+ s += TQLatin1String("<!--EndFragment-->");
+ if (formatChar)
+ s += formatChar->format()->makeFormatEndTags(formatCollection()->defaultFormat(), formatChar->anchorHref());
+ return s;
+}
+
+void TQTextParagraph::addCommand(TQTextCommand *cmd)
+{
+ if (!hasdoc)
+ pseudoDocument()->commandHistory->addCommand(cmd);
+ else
+ document()->commands()->addCommand(cmd);
+}
+
+TQTextCursor *TQTextParagraph::undo(TQTextCursor *c)
+{
+ if (!hasdoc)
+ return pseudoDocument()->commandHistory->undo(c);
+ return document()->commands()->undo(c);
+}
+
+TQTextCursor *TQTextParagraph::redo(TQTextCursor *c)
+{
+ if (!hasdoc)
+ return pseudoDocument()->commandHistory->redo(c);
+ return document()->commands()->redo(c);
+}
+
+int TQTextParagraph::topMargin() const
+{
+ int m = 0;
+ if (rtext) {
+ m = isListItem() ? (document()->li_tm/qMax(1,listDepth()*listDepth())) :
+ (listDepth() ? 0 : document()->par_tm);
+ if (listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth()))
+ m = qMax<int>(m, document()->list_tm);
+ }
+ m += utm;
+ return scale(m, TQTextFormat::painter());
+}
+
+int TQTextParagraph::bottomMargin() const
+{
+ int m = 0;
+ if (rtext) {
+ m = isListItem() ? (document()->li_bm/qMax(1,listDepth()*listDepth())) :
+ (listDepth() ? 0 : document()->par_bm);
+ if (listDepth() == 1 &&( !next() || next()->listDepth() < listDepth()))
+ m = qMax<int>(m, document()->list_bm);
+ }
+ m += ubm;
+ return scale(m, TQTextFormat::painter());
+}
+
+int TQTextParagraph::leftMargin() const
+{
+ int m = ulm;
+ if (listDepth() && !string()->isRightToLeft())
+ m += listDepth() * document()->list_lm;
+ return scale(m, TQTextFormat::painter());
+}
+
+int TQTextParagraph::firstLineMargin() const
+{
+ int m = uflm;
+ return scale(m, TQTextFormat::painter());
+}
+
+int TQTextParagraph::rightMargin() const
+{
+ int m = urm;
+ if (listDepth() && string()->isRightToLeft())
+ m += listDepth() * document()->list_lm;
+ return scale(m, TQTextFormat::painter());
+}
+
+int TQTextParagraph::lineSpacing() const
+{
+ int l = ulinespacing;
+ l = scale(l, TQTextFormat::painter());
+ return l;
+}
+
+void TQTextParagraph::copyParagData(TQTextParagraph *parag)
+{
+ rtext = parag->rtext;
+ lstyle = parag->lstyle;
+ ldepth = parag->ldepth;
+ litem = parag->litem;
+ align = parag->align;
+ utm = parag->utm;
+ ubm = parag->ubm;
+ urm = parag->urm;
+ ulm = parag->ulm;
+ uflm = parag->uflm;
+ ulinespacing = parag->ulinespacing;
+ QColor *c = parag->backgroundColor();
+ if (c)
+ setBackgroundColor(*c);
+ str->setDirection(parag->str->direction());
+}
+
+void TQTextParagraph::show()
+{
+ if (visible || !hasdoc)
+ return;
+ visible = true;
+}
+
+void TQTextParagraph::hide()
+{
+ if (!visible || !hasdoc)
+ return;
+ visible = false;
+}
+
+void TQTextParagraph::setDirection(TQChar::Direction dir)
+{
+ if (str && str->direction() != dir) {
+ str->setDirection(dir);
+ invalidate(0);
+ }
+}
+
+TQChar::Direction TQTextParagraph::direction() const
+{
+ return (str ? str->direction() : TQChar::DirON);
+}
+
+void TQTextParagraph::setChanged(bool b, bool recursive)
+{
+ changed = b;
+ if (recursive) {
+ if (document() && document()->parentParagraph())
+ document()->parentParagraph()->setChanged(b, recursive);
+ }
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
+TQTextPreProcessor::TQTextPreProcessor()
+{
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextFormatter::TQTextFormatter()
+ : thisminw(0), thiswused(0), wrapEnabled(true), wrapColumn(-1), biw(false)
+{
+}
+
+QTextLineStart *TQTextFormatter::formatLine(TQTextParagraph *parag, TQTextString *string, QTextLineStart *line,
+ TQTextStringChar *startChar, TQTextStringChar *lastChar, int align, int space)
+{
+ if (lastChar < startChar)
+ return new QTextLineStart;
+#ifndef QT_NO_COMPLEXTEXT
+ if(string->isBidi())
+ return bidiReorderLine(parag, string, line, startChar, lastChar, align, space);
+#endif
+ int start = (startChar - &string->at(0));
+ int last = (lastChar - &string->at(0));
+
+ // ignore white space at the end of the line.
+ TQTextStringChar *ch = lastChar;
+ while (ch > startChar && ch->whiteSpace) {
+ space += ch->format()->width(TQLatin1Char(' '));
+ --ch;
+ }
+
+ if (space < 0)
+ space = 0;
+
+ // do alignment Auto == Left in this case
+ if (align & Qt::AlignHCenter || align & Qt::AlignRight) {
+ if (align & Qt::AlignHCenter)
+ space /= 2;
+ for (int j = start; j <= last; ++j)
+ string->at(j).x += space;
+ } else if (align & Qt::AlignJustify) {
+ int numSpaces = 0;
+ // End at "last-1", the last space ends up with a width of 0
+ for (int j = last-1; j >= start; --j) {
+ // Start at last tab, if any.
+ TQTextStringChar &ch = string->at(j);
+ if (ch.c == TQLatin1Char('\t')) {
+ start = j+1;
+ break;
+ }
+ if(ch.whiteSpace)
+ numSpaces++;
+ }
+ int toAdd = 0;
+ for (int k = start + 1; k <= last; ++k) {
+ TQTextStringChar &ch = string->at(k);
+ if(numSpaces && ch.whiteSpace) {
+ int s = space / numSpaces;
+ toAdd += s;
+ space -= s;
+ numSpaces--;
+ }
+ string->at(k).x += toAdd;
+ }
+ }
+
+ if (last >= 0 && last < string->length())
+ line->w = string->at(last).x + string->width(last);
+ else
+ line->w = 0;
+
+ return new QTextLineStart;
+}
+
+#ifndef QT_NO_COMPLEXTEXT
+
+#ifdef BIDI_DEBUG
+QT_BEGIN_INCLUDE_NAMESPACE
+#include <iostream>
+QT_END_INCLUDE_NAMESPACE
+#endif
+
+// collects one line of the paragraph and transforms it to visual order
+QTextLineStart *TQTextFormatter::bidiReorderLine(TQTextParagraph * /*parag*/, TQTextString *text, QTextLineStart *line,
+ TQTextStringChar *startChar, TQTextStringChar *lastChar, int align, int space)
+{
+ // ignore white space at the end of the line.
+ int endSpaces = 0;
+ while (lastChar > startChar && lastChar->whiteSpace) {
+ space += lastChar->format()->width(TQLatin1Char(' '));
+ --lastChar;
+ ++endSpaces;
+ }
+
+ int start = (startChar - &text->at(0));
+ int last = (lastChar - &text->at(0));
+
+ int length = lastChar - startChar + 1;
+
+
+ int x = startChar->x;
+
+ unsigned char _levels[256];
+ int _visual[256];
+
+ unsigned char *levels = _levels;
+ int *visual = _visual;
+
+ if (length > 255) {
+ levels = (unsigned char *)malloc(length*sizeof(unsigned char));
+ visual = (int *)malloc(length*sizeof(int));
+ }
+
+ //qDebug("bidiReorderLine: length=%d (%d-%d)", length, start, last);
+
+ TQTextStringChar *ch = startChar;
+ unsigned char *l = levels;
+ while (ch <= lastChar) {
+ //qDebug(" level: %d", ch->bidiLevel);
+ *(l++) = (ch++)->bidiLevel;
+ }
+
+ QTextEngine::bidiReorder(length, levels, visual);
+
+ // now construct the reordered string out of the runs...
+
+ int numSpaces = 0;
+ align = QStyle::visualAlignment(text->isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight, QFlag(align));
+
+ // This is not really correct, but as we can't make the scroll bar move to the left of the origin,
+ // this ensures all text can be scrolled to and read.
+ if (space < 0)
+ space = 0;
+
+ if (align & Qt::AlignHCenter)
+ x += space/2;
+ else if (align & Qt::AlignRight)
+ x += space;
+ else if (align & Qt::AlignJustify) {
+ // End at "last-1", the last space ends up with a width of 0
+ for (int j = last-1; j >= start; --j) {
+ // Start at last tab, if any.
+ TQTextStringChar &ch = text->at(j);
+ if (ch.c == TQLatin1Char('\t')) {
+ start = j+1;
+ break;
+ }
+ if(ch.whiteSpace)
+ numSpaces++;
+ }
+ }
+
+ int toAdd = 0;
+ int xorig = x;
+ TQTextStringChar *lc = startChar + visual[0];
+ for (int i = 0; i < length; i++) {
+ TQTextStringChar *ch = startChar + visual[i];
+ if (numSpaces && ch->whiteSpace) {
+ int s = space / numSpaces;
+ toAdd += s;
+ space -= s;
+ numSpaces--;
+ }
+
+ if (lc->format() != ch->format() && !ch->c.isSpace()
+ && lc->format()->font().italic() && !ch->format()->font().italic()) {
+ int rb = lc->format()->fontMetrics().rightBearing(lc->c);
+ if (rb < 0)
+ x -= rb;
+ }
+
+ ch->x = x + toAdd;
+ ch->rightToLeft = ch->bidiLevel % 2;
+ //qDebug("visual: %d (%p) placed at %d rightToLeft=%d", visual[i], ch, x +toAdd, ch->rightToLeft );
+ int ww = 0;
+ if (ch->c.unicode() >= 32 || ch->c == TQLatin1Char(TQLatin1Char('\t')) || ch->c == TQLatin1Char('\n') || ch->isCustom()) {
+ ww = text->width(start+visual[i]);
+ } else {
+ ww = ch->format()->width(TQLatin1Char(' '));
+ }
+ x += ww;
+ lc = ch;
+ }
+ x += toAdd;
+
+ while (endSpaces--) {
+ ++lastChar;
+ int sw = lastChar->format()->width(TQLatin1Char(' '));
+ if (text->isRightToLeft()) {
+ xorig -= sw;
+ lastChar->x = xorig;
+ ch->rightToLeft = true;
+ } else {
+ lastChar->x = x;
+ x += sw;
+ ch->rightToLeft = false;
+ }
+ }
+
+ line->w = x;
+
+ if (length > 255) {
+ free(levels);
+ free(visual);
+ }
+
+ return new QTextLineStart;
+}
+#endif
+
+
+void TQTextFormatter::insertLineStart(TQTextParagraph *parag, int index, QTextLineStart *ls)
+{
+ QMap<int, QTextLineStart*>::Iterator it;
+ if ((it = parag->lineStartList().find(index)) == parag->lineStartList().end()) {
+ parag->lineStartList().insert(index, ls);
+ } else {
+ delete *it;
+ parag->lineStartList().erase(it);
+ parag->lineStartList().insert(index, ls);
+ }
+}
+
+
+/* Standard pagebreak algorithm using TQTextFlow::adjustFlow. Returns
+ the shift of the paragraphs bottom line.
+ */
+int TQTextFormatter::formatVertically(TQTextDocument* doc, TQTextParagraph* parag)
+{
+ int oldHeight = parag->rect().height();
+ QMap<int, QTextLineStart*>& lineStarts = parag->lineStartList();
+ QMap<int, QTextLineStart*>::Iterator it = lineStarts.begin();
+ int h = parag->prev() ? qMax(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
+ for (; it != lineStarts.end() ; ++it ) {
+ QTextLineStart * ls = it.value();
+ ls->y = h;
+ TQTextStringChar *c = &parag->string()->at(it.key());
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (c && c->customItem() && c->customItem()->ownLine()) {
+ int h = c->customItem()->height;
+ c->customItem()->pageBreak(parag->rect().y() + ls->y + ls->baseLine - h, doc->flow());
+ int delta = c->customItem()->height - h;
+ ls->h += delta;
+ if (delta)
+ parag->setMovedDown(true);
+ } else
+#endif
+ {
+
+ int shift = doc->flow()->adjustFlow(parag->rect().y() + ls->y, ls->w, ls->h);
+ ls->y += shift;
+ if (shift)
+ parag->setMovedDown(true);
+ }
+ h = ls->y + ls->h;
+ }
+ int m = parag->bottomMargin();
+ if (!parag->next())
+ m = 0;
+ else
+ m = qMax(m, parag->next()->topMargin()) / 2;
+ h += m;
+ parag->setHeight(h);
+ return h - oldHeight;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextFormatterBreakInWords::TQTextFormatterBreakInWords()
+{
+}
+
+#define SPACE(s) s
+
+int TQTextFormatterBreakInWords::format(TQTextDocument *doc,TQTextParagraph *parag,
+ int start, const QMap<int, QTextLineStart*> &)
+{
+ // make sure bidi information is correct.
+ (void)parag->string()->isBidi();
+
+ TQTextStringChar *c = 0;
+ TQTextStringChar *firstChar = 0;
+ int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
+ int x = left + (doc ? parag->firstLineMargin() : 0);
+ int dw = parag->documentVisibleWidth() - (doc ? doc->rightMargin() : 0);
+ int y = parag->prev() ? qMax(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
+ int h = y;
+ int len = parag->length();
+ if (doc)
+ x = doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), x, 4);
+ int rm = parag->rightMargin();
+ int w = dw - (doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 4) : 0);
+ bool fullWidth = true;
+ int minw = 0;
+ int wused = 0;
+ bool wrapEnabled = isWrapEnabled(parag);
+
+ start = 0; //######### what is the point with start?! (Matthias)
+ if (start == 0)
+ c = &parag->string()->at(0);
+
+ int i = start;
+ QTextLineStart *lineStart = new QTextLineStart(y, y, 0);
+ insertLineStart(parag, 0, lineStart);
+
+ TQPainter *painter = TQTextFormat::painter();
+
+ int col = 0;
+ int ww = 0;
+ TQChar lastChr;
+ int tabBase = left < x ? left : x;
+ for (; i < len; ++i, ++col) {
+ if (c)
+ lastChr = c->c;
+ c = &parag->string()->at(i);
+ // ### the lines below should not be needed
+ if (painter)
+ c->format()->setPainter(painter);
+ if (i > 0) {
+ c->lineStart = 0;
+ } else {
+ c->lineStart = 1;
+ firstChar = c;
+ }
+ if (c->c.unicode() >= 32 || c->isCustom()) {
+ ww = parag->string()->width(i);
+ } else if (c->c == TQLatin1Char('\t')) {
+ int nx = parag->nextTab(i, x - tabBase) + tabBase;
+ if (nx < x)
+ ww = w - x;
+ else
+ ww = nx - x;
+ } else {
+ ww = c->format()->width(TQLatin1Char(' '));
+ }
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ if (c->isCustom() && c->customItem()->ownLine()) {
+ x = doc ? doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), left, 4) : left;
+ w = dw - (doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 4) : 0);
+ c->customItem()->resize(w - x);
+ w = dw;
+ y += h;
+ h = c->height();
+ lineStart = new QTextLineStart(y, h, h);
+ insertLineStart(parag, i, lineStart);
+ c->lineStart = 1;
+ firstChar = c;
+ x = 0xffffff;
+ continue;
+ }
+#endif
+
+ if (wrapEnabled &&
+ ((wrapAtColumn() == -1 && x + ww > w) ||
+ (wrapAtColumn() != -1 && col >= wrapAtColumn()))) {
+ x = doc ? parag->document()->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), left, 4) : left;
+ w = dw;
+ y += h;
+ h = c->height();
+ lineStart = formatLine(parag, parag->string(), lineStart, firstChar, c-1);
+ lineStart->y = y;
+ insertLineStart(parag, i, lineStart);
+ lineStart->baseLine = c->ascent();
+ lineStart->h = c->height();
+ c->lineStart = 1;
+ firstChar = c;
+ col = 0;
+ if (wrapAtColumn() != -1)
+ minw = qMax(minw, w);
+ } else if (lineStart) {
+ lineStart->baseLine = qMax(lineStart->baseLine, c->ascent());
+ h = qMax(h, c->height());
+ lineStart->h = h;
+ }
+
+ c->x = x;
+ x += ww;
+ wused = qMax(wused, x);
+ }
+
+ int m = parag->bottomMargin();
+ if (!parag->next())
+ m = 0;
+ else
+ m = qMax(m, parag->next()->topMargin()) / 2;
+ parag->setFullWidth(fullWidth);
+ y += h + m;
+ if (doc)
+ minw += doc->rightMargin();
+ if (!wrapEnabled)
+ minw = qMax(minw, wused);
+
+ thisminw = minw;
+ thiswused = wused;
+ return y;
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextFormatterBreakWords::TQTextFormatterBreakWords()
+{
+}
+
+#define DO_FLOW(lineStart) do{ if (doc && doc->isPageBreakEnabled()) { \
+ int yflow = lineStart->y + parag->rect().y();\
+ int shift = doc->flow()->adjustFlow(yflow, dw, lineStart->h); \
+ lineStart->y += shift;\
+ y += shift;\
+ }}while(false)
+
+int TQTextFormatterBreakWords::format(TQTextDocument *doc, TQTextParagraph *parag,
+ int start, const QMap<int, QTextLineStart*> &)
+{
+ // make sure bidi information is correct.
+ (void)parag->string()->isBidi();
+
+ TQTextStringChar *c = 0;
+ TQTextStringChar *firstChar = 0;
+ TQTextString *string = parag->string();
+ int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
+ int x = left + (doc ? parag->firstLineMargin() : 0);
+ int y = parag->prev() ? qMax(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
+ int h = y;
+ int len = parag->length();
+ if (doc)
+ x = doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), x, 0);
+ int dw = parag->documentVisibleWidth() - (doc ? (left != x ? 0 : doc->rightMargin()) : 0);
+
+ int curLeft = x;
+ int rm = parag->rightMargin();
+ int rdiff = doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 0) : 0;
+ int w = dw - rdiff;
+ bool fullWidth = true;
+ int marg = left + rdiff;
+ int minw = 0;
+ int wused = 0;
+ int tminw = marg;
+ int linespacing = doc ? parag->lineSpacing() : 0;
+ bool wrapEnabled = isWrapEnabled(parag);
+
+ start = 0;
+
+ int i = start;
+ QTextLineStart *lineStart = new QTextLineStart(y, y, 0);
+ insertLineStart(parag, 0, lineStart);
+ int lastBreak = -1;
+ int tmpBaseLine = 0, tmph = 0;
+ bool lastWasNonInlineCustom = false;
+
+ int align = parag->alignment();
+ if (align == TQt::AlignAuto && doc && doc->alignment() != TQt::AlignAuto)
+ align = doc->alignment();
+
+ align &= Qt::AlignHorizontal_Mask;
+
+ // ### hack. The last char in the paragraph is always invisible,
+ // ### and somehow sometimes has a wrong format. It changes
+ // ### between // layouting and printing. This corrects some
+ // ### layouting errors in BiDi mode due to this.
+ if (len > 1) {
+ c = &parag->string()->at(len - 1);
+ if (!c->isAnchor()) {
+ if (c->format())
+ c->format()->removeRef();
+ c->setFormat(string->at(len - 2).format());
+ if (c->format())
+ c->format()->addRef();
+ }
+ }
+
+ c = &parag->string()->at(0);
+
+ TQPainter *painter = TQTextFormat::painter();
+ int col = 0;
+ int ww = 0;
+ TQChar lastChr = c->c;
+ TQTextFormat *lastFormat = c->format();
+ int tabBase = left < x ? left : x;
+ for (; i < len; ++i, ++col) {
+ if (i) {
+ c = &parag->string()->at(i-1);
+ lastChr = c->c;
+ lastFormat = c->format();
+ }
+ bool lastWasOwnLineCustomItem = lastBreak == -2;
+ bool hadBreakableChar = lastBreak != -1;
+ bool lastWasHardBreak = lastChr == TQChar::LineSeparator;
+
+ // ### next line should not be needed
+ if (painter)
+ c->format()->setPainter(painter);
+ c = &string->at(i);
+
+ if (lastFormat != c->format() && !c->c.isSpace()
+ && lastFormat->font().italic() && !c->format()->font().italic()) {
+ int rb = lastFormat->fontMetrics().rightBearing(lastChr);
+ if (rb < 0)
+ x -= rb;
+ }
+
+ if ((i > 0 && (x > curLeft || ww == 0)) || lastWasNonInlineCustom) {
+ c->lineStart = 0;
+ } else {
+ c->lineStart = 1;
+ firstChar = c;
+ }
+
+ // ignore non spacing marks for column count.
+ if (col != 0 && TQChar::category(c->c.unicode()) == TQChar::Mark_NonSpacing)
+ --col;
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ lastWasNonInlineCustom = (c->isCustom() && c->customItem()->placement() != TQTextCustomItem::PlaceInline);
+#endif
+
+ if (c->c.unicode() >= 32 || c->isCustom()) {
+ ww = string->width(i);
+ } else if (c->c == TQLatin1Char('\t')) {
+ if (align == Qt::AlignRight || align == Qt::AlignCenter) {
+ // we can not (yet) do tabs
+ ww = c->format()->width(TQLatin1Char(' '));
+ } else {
+ int tabx = lastWasHardBreak ? (left + (doc ? parag->firstLineMargin() : 0)) : x;
+ int nx = parag->nextTab(i, tabx - tabBase) + tabBase;
+ if (nx < tabx) // strrrange...
+ ww = 0;
+ else
+ ww = nx - tabx;
+ }
+ } else {
+ ww = c->format()->width(TQLatin1Char(' '));
+ }
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem* ci = c->customItem();
+ if (c->isCustom() && ci->ownLine()) {
+ QTextLineStart *lineStart2 = formatLine(parag, string, lineStart, firstChar, c-1, align, SPACE(w - x - ww));
+ x = doc ? doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), left, 4) : left;
+ w = dw - (doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 4) : 0);
+ ci->resize(w - x);
+ if (ci->width < w - x) {
+ if (align & Qt::AlignHCenter)
+ x = (w - ci->width) / 2;
+ else if (align & Qt::AlignRight) {
+ x = w - ci->width;
+ }
+ }
+ c->x = x;
+ curLeft = x;
+ if (i == 0 || !isBreakable(string, i-1) ||
+ string->at(i - 1).lineStart == 0) {
+ y += qMax(h, qMax(tmph, linespacing));
+ tmph = c->height();
+ h = tmph;
+ lineStart = lineStart2;
+ lineStart->y = y;
+ insertLineStart(parag, i, lineStart);
+ c->lineStart = 1;
+ firstChar = c;
+ } else {
+ tmph = c->height();
+ h = tmph;
+ delete lineStart2;
+ }
+ lineStart->h = h;
+ lineStart->baseLine = h;
+ tmpBaseLine = lineStart->baseLine;
+ lastBreak = -2;
+ x = w;
+ minw = qMax(minw, tminw);
+
+ int tw = ci->minimumWidth() + (doc ? doc->leftMargin() : 0);
+ if (tw < QWIDGETSIZE_MAX)
+ tminw = tw;
+ else
+ tminw = marg;
+ wused = qMax(wused, ci->width);
+ continue;
+ } else if (c->isCustom() && ci->placement() != TQTextCustomItem::PlaceInline) {
+ int tw = ci->minimumWidth();
+ if (tw < QWIDGETSIZE_MAX)
+ minw = qMax(minw, tw);
+ }
+#endif
+ // we break if
+ // 1. the last character was a hard break (TQChar::LineSeparator) or
+ // 2. the last character was a own-line custom item (eg. table or ruler) or
+ // 3. wrapping was enabled, it was not a space and following
+ // condition is true: We either had a breakable character
+ // previously or we ar allowed to break in words and - either
+ // we break at w pixels and the current char would exceed that
+ // or - we break at a column and the current character would
+ // exceed that.
+ if (lastWasHardBreak || lastWasOwnLineCustomItem ||
+ (wrapEnabled &&
+ ((!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) &&
+ ((wrapAtColumn() == -1 && x + ww > w) ||
+ (wrapAtColumn() != -1 && col >= wrapAtColumn()))))
+ )
+ ) {
+ if (wrapAtColumn() != -1)
+ minw = qMax(minw, x + ww);
+ // if a break was forced (no breakable char, hard break or own line custom item), break immediately....
+ if (!hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem) {
+ if (lineStart) {
+ lineStart->baseLine = qMax(lineStart->baseLine, tmpBaseLine);
+ h = qMax(h, tmph);
+ lineStart->h = h;
+ DO_FLOW(lineStart);
+ }
+ lineStart = formatLine(parag, string, lineStart, firstChar, c-1, align, SPACE(w - x));
+ x = doc ? doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), left, 4) : left;
+ w = dw - (doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 4) : 0);
+ if (!doc && c->c == TQLatin1Char('\t')) { // qt_format_text tab handling
+ int nx = parag->nextTab(i, x - tabBase) + tabBase;
+ if (nx < x)
+ ww = w - x;
+ else
+ ww = nx - x;
+ }
+ curLeft = x;
+ y += qMax(h, linespacing);
+ tmph = c->height();
+ h = 0;
+ lineStart->y = y;
+ insertLineStart(parag, i, lineStart);
+ lineStart->baseLine = c->ascent();
+ lineStart->h = c->height();
+ c->lineStart = 1;
+ firstChar = c;
+ tmpBaseLine = lineStart->baseLine;
+ lastBreak = -1;
+ col = 0;
+ if (allowBreakInWords() || lastWasHardBreak) {
+ minw = qMax(minw, tminw);
+ tminw = marg + ww;
+ }
+ } else { // ... otherwise if we had a breakable char, break there
+ DO_FLOW(lineStart);
+ c->x = x;
+ i = lastBreak;
+ lineStart = formatLine(parag, string, lineStart, firstChar, parag->at(lastBreak),align, SPACE(w - string->at(i+1).x));
+ x = doc ? doc->flow()->adjustLMargin(y + parag->rect().y(), parag->rect().height(), left, 4) : left;
+ w = dw - (doc ? doc->flow()->adjustRMargin(y + parag->rect().y(), parag->rect().height(), rm, 4) : 0);
+ if (!doc && c->c == TQLatin1Char('\t')) { // qt_format_text tab handling
+ int nx = parag->nextTab(i, x - tabBase) + tabBase;
+ if (nx < x)
+ ww = w - x;
+ else
+ ww = nx - x;
+ }
+ curLeft = x;
+ y += qMax(h, linespacing);
+ tmph = c->height();
+ h = tmph;
+ lineStart->y = y;
+ insertLineStart(parag, i + 1, lineStart);
+ lineStart->baseLine = c->ascent();
+ lineStart->h = c->height();
+ c->lineStart = 1;
+ firstChar = c;
+ tmpBaseLine = lineStart->baseLine;
+ lastBreak = -1;
+ col = 0;
+ minw = qMax(minw, tminw);
+ tminw = marg;
+ continue;
+ }
+ } else if (lineStart && isBreakable(string, i)) {
+ if (len <= 2 || i < len - 1) {
+ tmpBaseLine = qMax(tmpBaseLine, c->ascent());
+ tmph = qMax(tmph, c->height());
+ }
+ minw = qMax(minw, tminw);
+
+ tminw = marg + ww;
+ lineStart->baseLine = qMax(lineStart->baseLine, tmpBaseLine);
+ h = qMax(h, tmph);
+ lineStart->h = h;
+ if (i < len - 2 || c->c != TQLatin1Char(' '))
+ lastBreak = i;
+ } else {
+ tminw += ww;
+ int cascent = c->ascent();
+ int cheight = c->height();
+ int belowBaseLine = qMax(tmph - tmpBaseLine, cheight-cascent);
+ tmpBaseLine = qMax(tmpBaseLine, cascent);
+ tmph = tmpBaseLine + belowBaseLine;
+ }
+
+ c->x = x;
+ x += ww;
+ wused = qMax(wused, x);
+ }
+
+ if (lineStart) {
+ lineStart->baseLine = qMax(lineStart->baseLine, tmpBaseLine);
+ h = qMax(h, tmph);
+ lineStart->h = h;
+ // last line in a paragraph is not justified
+ if (align & Qt::AlignJustify) {
+ align |= Qt::AlignLeft;
+ align &= ~(Qt::AlignJustify|Qt::AlignAbsolute);
+ }
+ DO_FLOW(lineStart);
+ lineStart = formatLine(parag, string, lineStart, firstChar, c, align, SPACE(w - x));
+ delete lineStart;
+ }
+
+ minw = qMax(minw, tminw);
+ if (doc)
+ minw += doc->rightMargin();
+
+ int m = parag->bottomMargin();
+ if (!parag->next())
+ m = 0;
+ else
+ m = qMax(m, parag->next()->topMargin()) / 2;
+ parag->setFullWidth(fullWidth);
+ y += qMax(h, linespacing) + m;
+
+ wused += rm;
+ if (!wrapEnabled || wrapAtColumn() != -1)
+ minw = qMax(minw, wused);
+
+ // This is the case where we are breaking wherever we darn well please
+ // in cases like that, the minw should not be the length of the entire
+ // word, because we necessarily want to show the word on the whole line.
+ // example: word wrap in iconview
+ if (allowBreakInWords() && minw > wused)
+ minw = wused;
+
+ thisminw = minw;
+ thiswused = wused;
+ return y;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextIndent::TQTextIndent()
+{
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextFormatCollection::TQTextFormatCollection()
+ : paintdevice(0)
+{
+ defFormat = new TQTextFormat(QApplication::font(),
+ QApplication::palette().color(QPalette::Active, QPalette::Text));
+ lastFormat = cres = 0;
+ cflags = -1;
+ cachedFormat = 0;
+}
+
+TQTextFormatCollection::~TQTextFormatCollection()
+{
+ QHash<TQString, TQTextFormat *>::ConstIterator it = cKey.constBegin();
+ while (it != cKey.constEnd()) {
+ delete it.value();
+ ++it;
+ }
+ delete defFormat;
+}
+
+void TQTextFormatCollection::setPaintDevice(QPaintDevice *pd)
+{
+ paintdevice = TQT_TQPAINTDEVICE(pd);
+
+#if defined(Q_WS_X11)
+ int scr = (paintdevice) ? paintdevice->x11Screen() : QX11Info::appScreen();
+
+ defFormat->fn.tqt_x11SetScreen(scr);
+ defFormat->update();
+
+ QHash<TQString, TQTextFormat *>::Iterator it = cKey.begin();
+ for (; it != cKey.end(); ++it) {
+ TQTextFormat *format = *it;
+ format->fn.tqt_x11SetScreen(scr);
+ format->update();
+ }
+#endif // Q_WS_X11
+}
+
+TQTextFormat *TQTextFormatCollection::format(TQTextFormat *f)
+{
+ if (f->parent() == this || f == defFormat) {
+ lastFormat = f;
+ lastFormat->addRef();
+ return lastFormat;
+ }
+
+ if (f == lastFormat || (lastFormat && f->key() == lastFormat->key())) {
+ lastFormat->addRef();
+ return lastFormat;
+ }
+
+ TQTextFormat *fm = cKey.value(f->key());
+ if (fm) {
+ lastFormat = fm;
+ lastFormat->addRef();
+ return lastFormat;
+ }
+
+ if (f->key() == defFormat->key())
+ return defFormat;
+
+ lastFormat = createFormat(*f);
+ lastFormat->collection = this;
+ cKey.insert(lastFormat->key(), lastFormat);
+ return lastFormat;
+}
+
+TQTextFormat *TQTextFormatCollection::format(TQTextFormat *of, TQTextFormat *nf, int flags)
+{
+ if (cres && kof == of->key() && knf == nf->key() && cflags == flags) {
+ cres->addRef();
+ return cres;
+ }
+
+ cres = createFormat(*of);
+ kof = of->key();
+ knf = nf->key();
+ cflags = flags;
+ if (flags & TQTextFormat::Bold)
+ cres->fn.setBold(nf->fn.bold());
+ if (flags & TQTextFormat::Italic)
+ cres->fn.setItalic(nf->fn.italic());
+ if (flags & TQTextFormat::Underline)
+ cres->fn.setUnderline(nf->fn.underline());
+ if (flags & TQTextFormat::StrikeOut)
+ cres->fn.setStrikeOut(nf->fn.strikeOut());
+ if (flags & TQTextFormat::Family)
+ cres->fn.setFamily(nf->fn.family());
+ if (flags & TQTextFormat::Size) {
+ if (of->usePixelSizes)
+ cres->fn.setPixelSize(nf->fn.pixelSize());
+ else
+ cres->fn.setPointSize(nf->fn.pointSize());
+ }
+ if (flags & TQTextFormat::Color)
+ cres->col = nf->col;
+ if (flags & TQTextFormat::Misspelled)
+ cres->missp = nf->missp;
+ if (flags & TQTextFormat::VAlign)
+ cres->ha = nf->ha;
+ cres->update();
+
+ TQTextFormat *fm = cKey.value(cres->key());
+ if (!fm) {
+ cres->collection = this;
+ cKey.insert(cres->key(), cres);
+ } else {
+ delete cres;
+ cres = fm;
+ cres->addRef();
+ }
+
+ return cres;
+}
+
+TQTextFormat *TQTextFormatCollection::format(const QFont &f, const QColor &c)
+{
+ if (cachedFormat && cfont == f && ccol == c) {
+ cachedFormat->addRef();
+ return cachedFormat;
+ }
+
+ TQString key = TQTextFormat::getKey(f, c, false, TQTextFormat::AlignNormal);
+ cachedFormat = cKey.value(key);
+ cfont = f;
+ ccol = c;
+
+ if (cachedFormat) {
+ cachedFormat->addRef();
+ return cachedFormat;
+ }
+
+ if (key == defFormat->key())
+ return defFormat;
+
+ cachedFormat = createFormat(f, c);
+ cachedFormat->collection = this;
+ cKey.insert(cachedFormat->key(), cachedFormat);
+ if (cachedFormat->key() != key)
+ qWarning("ASSERT: keys for format not identical: '%s '%s'", cachedFormat->key().latin1(), key.latin1());
+ return cachedFormat;
+}
+
+void TQTextFormatCollection::remove(TQTextFormat *f)
+{
+ if (lastFormat == f)
+ lastFormat = 0;
+ if (cres == f)
+ cres = 0;
+ if (cachedFormat == f)
+ cachedFormat = 0;
+ if (cKey.value(f->key()) == f)
+ delete cKey.take(f->key());
+}
+
+#define UPDATE(up, lo, rest) \
+ if (font.lo##rest() != defFormat->fn.lo##rest() && fm->fn.lo##rest() == defFormat->fn.lo##rest()) \
+ fm->fn.set##up##rest(font.lo##rest())
+
+void TQTextFormatCollection::updateDefaultFormat(const QFont &font, const QColor &color, TQStyleSheet *sheet)
+{
+ bool usePixels = font.pointSize() == -1;
+ bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() :
+ font.pointSize() != defFormat->fn.pointSize();
+ int base = usePixels ? font.pixelSize() : font.pointSize();
+ QHash<TQString, TQTextFormat *>::Iterator it = cKey.begin();
+ for (; it != cKey.end(); ++it) {
+ TQTextFormat *fm = *it;
+ UPDATE(F, f, amily);
+ UPDATE(W, w, eight);
+ UPDATE(B, b, old);
+ UPDATE(I, i, talic);
+ UPDATE(U, u, nderline);
+ if (changeSize) {
+ fm->stdSize = base;
+ fm->usePixelSizes = usePixels;
+ if (usePixels)
+ fm->fn.setPixelSize(fm->stdSize);
+ else
+ fm->fn.setPointSize(fm->stdSize);
+ sheet->scaleFont(fm->fn, fm->logicalFontSize);
+ }
+ if (color.isValid() && color != defFormat->col && fm->col == defFormat->col)
+ fm->col = color;
+ fm->update();
+ }
+
+ defFormat->fn = font;
+ defFormat->col = color;
+ defFormat->update();
+ defFormat->stdSize = base;
+ defFormat->usePixelSizes = usePixels;
+
+ updateKeys();
+}
+
+// the keys in cKey have changed, rebuild the hashtable
+void TQTextFormatCollection::updateKeys()
+{
+ if (cKey.isEmpty())
+ return;
+ TQTextFormat** formats = new TQTextFormat *[cKey.count() + 1];
+ TQTextFormat **f = formats;
+ for (QHash<TQString, TQTextFormat *>::Iterator it = cKey.begin(); it != cKey.end(); ++it, ++f)
+ *f = *it;
+ *f = 0;
+ cKey.clear();
+ for (f = formats; *f; f++)
+ cKey.insert((*f)->key(), *f);
+ delete [] formats;
+}
+
+
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+void TQTextFormat::setBold(bool b)
+{
+ if (b == fn.bold())
+ return;
+ fn.setBold(b);
+ update();
+}
+
+void TQTextFormat::setMisspelled(bool b)
+{
+ if (b == (bool)missp)
+ return;
+ missp = b;
+ update();
+}
+
+void TQTextFormat::setVAlign(VerticalAlignment a)
+{
+ if (a == ha)
+ return;
+ ha = a;
+ update();
+}
+
+void TQTextFormat::setItalic(bool b)
+{
+ if (b == fn.italic())
+ return;
+ fn.setItalic(b);
+ update();
+}
+
+void TQTextFormat::setUnderline(bool b)
+{
+ if (b == fn.underline())
+ return;
+ fn.setUnderline(b);
+ update();
+}
+
+void TQTextFormat::setStrikeOut(bool b)
+{
+ if (b == fn.strikeOut())
+ return;
+ fn.setStrikeOut(b);
+ update();
+}
+
+void TQTextFormat::setFamily(const TQString &f)
+{
+ if (f == fn.family())
+ return;
+ fn.setFamily(f);
+ update();
+}
+
+void TQTextFormat::setPointSize(int s)
+{
+ if (s == fn.pointSize())
+ return;
+ fn.setPointSize(s);
+ usePixelSizes = false;
+ update();
+}
+
+void TQTextFormat::setFont(const QFont &f)
+{
+ if (f == fn && !k.isEmpty())
+ return;
+ fn = f;
+ update();
+}
+
+void TQTextFormat::setColor(const QColor &c)
+{
+ if (c == col)
+ return;
+ col = c;
+ update();
+}
+
+TQString TQTextFormat::makeFormatChangeTags(TQTextFormat* defaultFormat, TQTextFormat *f,
+ const TQString& oldAnchorHref, const TQString& anchorHref ) const
+{
+ TQString tag;
+ if (f)
+ tag += f->makeFormatEndTags(defaultFormat, oldAnchorHref);
+
+ if (!anchorHref.isEmpty())
+ tag += TQLatin1String("<a href=\"") + anchorHref + TQLatin1String("\">");
+
+ if (font() != defaultFormat->font()
+ || vAlign() != defaultFormat->vAlign()
+ || color().rgb() != defaultFormat->color().rgb()) {
+ TQString s;
+ if (font().family() != defaultFormat->font().family())
+ s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("font-family:") + fn.family();
+ if (font().italic() && font().italic() != defaultFormat->font().italic())
+ s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("font-style:") + (font().italic() ? TQLatin1String("italic") : TQLatin1String("normal"));
+ if (font().pointSize() != defaultFormat->font().pointSize())
+ s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("font-size:") + TQString::number(fn.pointSize()) + TQLatin1String("pt");
+ if (font().weight() != defaultFormat->font().weight())
+ s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("font-weight:") + TQString::number(fn.weight() * 8);
+ TQString textDecoration;
+ bool none = false;
+ if ( font().underline() != defaultFormat->font().underline() ) {
+ if (font().underline())
+ textDecoration = TQLatin1String("underline");
+ else
+ none = true;
+ }
+ if ( font().overline() != defaultFormat->font().overline() ) {
+ if (font().overline())
+ textDecoration += TQLatin1String(" overline");
+ else
+ none = true;
+ }
+ if ( font().strikeOut() != defaultFormat->font().strikeOut() ) {
+ if (font().strikeOut())
+ textDecoration += TQLatin1String(" line-through");
+ else
+ none = true;
+ }
+ if (none && textDecoration.isEmpty())
+ textDecoration = TQLatin1String("none");
+ if (!textDecoration.isEmpty())
+ s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("text-decoration:") + textDecoration;
+ if (vAlign() != defaultFormat->vAlign()) {
+ s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("vertical-align:");
+ if (vAlign() == TQTextFormat::AlignSuperScript)
+ s += TQLatin1String("super");
+ else if (vAlign() == TQTextFormat::AlignSubScript)
+ s += TQLatin1String("sub");
+ else
+ s += TQLatin1String("normal");
+ }
+ if (color().rgb() != defaultFormat->color().rgb())
+ s += TQString(s.size()?TQLatin1String(";"):TQLatin1String("")) + TQLatin1String("color:") + col.name();
+ if (!s.isEmpty())
+ tag += TQLatin1String("<span style=\"") + s + TQLatin1String("\">");
+ }
+
+ return tag;
+}
+
+TQString TQTextFormat::makeFormatEndTags(TQTextFormat* defaultFormat, const TQString& anchorHref) const
+{
+ TQString tag;
+ if (font().family() != defaultFormat->font().family()
+ || font().pointSize() != defaultFormat->font().pointSize()
+ || font().weight() != defaultFormat->font().weight()
+ || font().italic() != defaultFormat->font().italic()
+ || font().underline() != defaultFormat->font().underline()
+ || font().strikeOut() != defaultFormat->font().strikeOut()
+ || vAlign() != defaultFormat->vAlign()
+ || color().rgb() != defaultFormat->color().rgb())
+ tag += TQLatin1String("</span>");
+ if (!anchorHref.isEmpty())
+ tag += TQLatin1String("</a>");
+ return tag;
+}
+
+TQTextFormat TQTextFormat::makeTextFormat(const TQStyleSheetItem *style, const QMap<TQString,TQString>& attr, double scaleFontsFactor) const
+{
+ TQTextFormat format(*this);
+ if (!style)
+ return format;
+
+ if (!style->isAnchor() && style->color().isValid()) {
+ // the style is not an anchor and defines a color.
+ // It might be used inside an anchor and it should
+ // override the link color.
+ format.linkColor = false;
+ }
+ switch (style->verticalAlignment()) {
+ case TQStyleSheetItem::VAlignBaseline:
+ format.setVAlign(TQTextFormat::AlignNormal);
+ break;
+ case TQStyleSheetItem::VAlignSuper:
+ format.setVAlign(TQTextFormat::AlignSuperScript);
+ break;
+ case TQStyleSheetItem::VAlignSub:
+ format.setVAlign(TQTextFormat::AlignSubScript);
+ break;
+ }
+
+ if (style->fontWeight() != TQStyleSheetItem::Undefined)
+ format.fn.setWeight(style->fontWeight());
+ if (style->fontSize() != TQStyleSheetItem::Undefined) {
+ format.fn.setPointSize(style->fontSize());
+ } else if (style->logicalFontSize() != TQStyleSheetItem::Undefined) {
+ format.logicalFontSize = style->logicalFontSize();
+ if (format.usePixelSizes)
+ format.fn.setPixelSize(format.stdSize);
+ else
+ format.fn.setPointSize(format.stdSize);
+ style->styleSheet()->scaleFont(format.fn, format.logicalFontSize);
+ } else if (style->logicalFontSizeStep()) {
+ format.logicalFontSize += style->logicalFontSizeStep();
+ if (format.usePixelSizes)
+ format.fn.setPixelSize(format.stdSize);
+ else
+ format.fn.setPointSize(format.stdSize);
+ style->styleSheet()->scaleFont(format.fn, format.logicalFontSize);
+ }
+ if (!style->fontFamily().isEmpty())
+ format.fn.setFamily(style->fontFamily());
+ if (style->color().isValid())
+ format.col = style->color();
+ if (style->definesFontItalic())
+ format.fn.setItalic(style->fontItalic());
+ if (style->definesFontUnderline())
+ format.fn.setUnderline(style->fontUnderline());
+ if (style->definesFontStrikeOut())
+ format.fn.setStrikeOut(style->fontStrikeOut());
+
+ QMap<TQString, TQString>::ConstIterator it, end = attr.end();
+
+ if (style->name() == TQLatin1String("font")) {
+ it = attr.find(TQLatin1String("color"));
+ if (it != end && ! (*it).isEmpty()){
+ format.col.setNamedColor(*it);
+ format.linkColor = false;
+ }
+ it = attr.find(TQLatin1String("face"));
+ if (it != end) {
+ TQString family = (*it).section(TQLatin1Char(','), 0, 0);
+ if (family.size())
+ format.fn.setFamily(family);
+ }
+ it = attr.find(TQLatin1String("size"));
+ if (it != end) {
+ TQString a = *it;
+ int n = a.toInt();
+ if (a[0] == TQLatin1Char('+') || a[0] == TQLatin1Char('-'))
+ n += 3;
+ format.logicalFontSize = n;
+ if (format.usePixelSizes)
+ format.fn.setPixelSize(format.stdSize);
+ else
+ format.fn.setPointSize(format.stdSize);
+ style->styleSheet()->scaleFont(format.fn, format.logicalFontSize);
+ }
+ }
+
+ it = attr.find(TQLatin1String("style"));
+ if (it != end) {
+ TQString a = *it;
+ int count = a.count(TQLatin1Char(';'))+1;
+ for (int s = 0; s < count; s++) {
+ TQString style = a.section(TQLatin1Char(';'), s, s);
+ if (style.startsWith(TQLatin1String("font-size:")) && style.endsWith(TQLatin1String("pt"))) {
+ format.logicalFontSize = 0;
+ int size = int(scaleFontsFactor * style.mid(10, style.length() - 12).toDouble());
+ format.setPointSize(size);
+ } else if (style.startsWith(TQLatin1String("font-style:"))) {
+ TQString s = style.mid(11).trimmed();
+ if (s == TQLatin1String("normal"))
+ format.fn.setItalic(false);
+ else if (s == TQLatin1String("italic") || s == TQLatin1String("oblique"))
+ format.fn.setItalic(true);
+ } else if (style.startsWith(TQLatin1String("font-weight:"))) {
+ TQString s = style.mid(12);
+ bool ok = true;
+ int n = s.toInt(&ok);
+ if (ok)
+ format.fn.setWeight(n/8);
+ } else if (style.startsWith(TQLatin1String("font-family:"))) {
+ TQString family = style.mid(12).section(TQLatin1Char(','),0,0);
+ family.replace(TQLatin1Char('\"'), TQLatin1Char(' '));
+ family.replace(TQLatin1Char('\''), TQLatin1Char(' '));
+ family = family.trimmed();
+ format.fn.setFamily(family);
+ } else if (style.startsWith(TQLatin1String("text-decoration:"))) {
+ TQString s = style.mid( 16 );
+ format.fn.setOverline(s.contains(TQLatin1String("overline")));
+ format.fn.setStrikeOut(s.contains(TQLatin1String("line-through")));
+ format.fn.setUnderline(s.contains(TQLatin1String("underline")));
+ } else if (style.startsWith(TQLatin1String("vertical-align:"))) {
+ TQString s = style.mid(15).trimmed();
+ if (s == TQLatin1String("sub"))
+ format.setVAlign(TQTextFormat::AlignSubScript);
+ else if (s == TQLatin1String("super"))
+ format.setVAlign(TQTextFormat::AlignSuperScript);
+ else
+ format.setVAlign(TQTextFormat::AlignNormal);
+ } else if (style.startsWith(TQLatin1String("color:"))) {
+ format.col.setNamedColor(style.mid(6));
+ format.linkColor = false;
+ }
+ }
+ }
+
+ format.update();
+ return format;
+}
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+
+struct TQPixmapInt
+{
+ TQPixmapInt() : ref(0) {}
+ TQPixmap pm;
+ int ref;
+ Q_DUMMY_COMPARISON_OPERATOR(TQPixmapInt)
+};
+
+static QMap<TQString, TQPixmapInt> *pixmap_map = 0;
+
+TQTextImage::TQTextImage(TQTextDocument *p, const QMap<TQString, TQString> &attr, const TQString& context,
+ TQMimeSourceFactory &factory)
+ : TQTextCustomItem(p)
+{
+ width = height = 0;
+
+ QMap<TQString, TQString>::ConstIterator it, end = attr.end();
+ it = attr.find(TQLatin1String("width"));
+ if (it != end)
+ width = (*it).toInt();
+ it = attr.find(TQLatin1String("height"));
+ if (it != end)
+ height = (*it).toInt();
+
+ reg = 0;
+ TQString imageName = attr[TQLatin1String("src")];
+
+ if (imageName.size() == 0)
+ imageName = attr[TQLatin1String("source")];
+
+ if (!imageName.isEmpty()) {
+ imgId = TQString::fromLatin1("%1,%2,%3,%4").arg(imageName).arg(width).arg(height).arg((quintptr)&factory);
+ if (!pixmap_map)
+ pixmap_map = new QMap<TQString, TQPixmapInt>;
+ if (pixmap_map->contains(imgId)) {
+ TQPixmapInt& pmi = pixmap_map->operator[](imgId);
+ pm = pmi.pm;
+ pmi.ref++;
+ width = pm.width();
+ height = pm.height();
+ } else {
+ TQImage img;
+ const QMimeSource* m =
+ factory.data(imageName, context);
+ if (!m) {
+ qCritical("TQTextImage: no mimesource for %s", imageName.latin1());
+ }
+ else {
+ if (!TQImageDrag::decode(TQT_TQMIMESOURCE_CONST(m), img)) {
+ qCritical("TQTextImage: cannot decode %s", imageName.latin1());
+ }
+ }
+
+ if (!img.isNull()) {
+ if (width == 0) {
+ width = img.width();
+ if (height != 0) {
+ width = img.width() * height / img.height();
+ }
+ }
+ if (height == 0) {
+ height = img.height();
+ if (width != img.width()) {
+ height = img.height() * width / img.width();
+ }
+ }
+ if (img.width() != width || img.height() != height){
+#ifndef QT_NO_IMAGE_SMOOTHSCALE
+ img = img.smoothScale(width, height);
+#endif
+ width = img.width();
+ height = img.height();
+ }
+ pm.convertFromImage(img);
+ }
+ if (!pm.isNull()) {
+ TQPixmapInt& pmi = pixmap_map->operator[](imgId);
+ pmi.pm = pm;
+ pmi.ref++;
+ }
+ }
+ if (pm.hasAlphaChannel()) {
+ QRegion mask(pm.mask());
+ QRegion all(0, 0, pm.width(), pm.height());
+ reg = new QRegion(all.subtracted(mask));
+ }
+ }
+
+ if (pm.isNull() && (width*height)==0)
+ width = height = 50;
+
+ place = PlaceInline;
+ if (attr[TQLatin1String("align")] == TQLatin1String("left"))
+ place = PlaceLeft;
+ else if (attr[TQLatin1String("align")] == TQLatin1String("right"))
+ place = PlaceRight;
+
+ tmpwidth = width;
+ tmpheight = height;
+
+ attributes = attr;
+}
+
+TQTextImage::~TQTextImage()
+{
+ if (pixmap_map && pixmap_map->contains(imgId)) {
+ TQPixmapInt& pmi = pixmap_map->operator[](imgId);
+ pmi.ref--;
+ if (!pmi.ref) {
+ pixmap_map->remove(imgId);
+ if (pixmap_map->isEmpty()) {
+ delete pixmap_map;
+ pixmap_map = 0;
+ }
+ }
+ }
+ delete reg;
+}
+
+TQString TQTextImage::richText() const
+{
+ TQString s;
+ s += TQLatin1String("<img ");
+ QMap<TQString, TQString>::ConstIterator it = attributes.begin();
+ for (; it != attributes.end(); ++it) {
+ s += it.key() + TQLatin1Char('=');
+ if ((*it).contains(TQLatin1Char(' ')))
+ s += TQLatin1Char('\"') + *it + TQLatin1String("\" ");
+ else
+ s += *it + TQLatin1Char(' ');
+ }
+ s += TQLatin1Char('>');
+ return s;
+}
+
+void TQTextImage::adjustToPainter(TQPainter* p)
+{
+ width = scale(tmpwidth, p);
+ height = scale(tmpheight, p);
+}
+
+#if !defined(Q_WS_X11)
+static TQPixmap *qrt_selection = 0;
+static TQSingleCleanupHandler<TQPixmap> qrt_cleanup_pixmap;
+static void qrt_createSelectionPixmap(const QPalette &pal)
+{
+ qrt_selection = new TQPixmap(2, 2);
+ qrt_cleanup_pixmap.set(&qrt_selection);
+ qrt_selection->fill(Qt::color0);
+ QBitmap m(2, 2);
+ m.fill(Qt::color1);
+ TQPainter p(&m);
+ p.setPen(Qt::color0);
+ for (int j = 0; j < 2; ++j) {
+ p.drawPoint(j % 2, j);
+ }
+ p.end();
+ qrt_selection->setMask(m);
+ qrt_selection->fill(pal.highlight().color());
+}
+#endif
+
+void TQTextImage::draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
+ const QPalette &pal, bool selected)
+{
+ if (placement() != PlaceInline) {
+ x = xpos;
+ y = ypos;
+ }
+
+ if (pm.isNull()) {
+ p->fillRect(x , y, width, height, pal.dark());
+ return;
+ }
+
+ if (is_printer(p)) {
+ p->drawPixmap(TQRect(x, y, width, height), pm);
+ return;
+ }
+
+ if (placement() != PlaceInline && !TQRect(xpos, ypos, width, height).intersects(TQRect(cx, cy, cw, ch)))
+ return;
+
+ if (placement() == PlaceInline)
+ p->drawPixmap(x , y, pm);
+ else
+ p->drawPixmap(cx , cy, pm, cx - x, cy - y, cw, ch);
+
+ if (selected && placement() == PlaceInline && is_printer(p)) {
+#if defined(Q_WS_X11)
+ p->fillRect(TQRect(QPoint(x, y), pm.size()), TQBrush(pal.Highlight,
+ Qt::Dense4Pattern));
+#else // in WIN32 Qt::Dense4Pattern doesn't work correctly (transparency problem), so work around it
+ if (!qrt_selection)
+ qrt_createSelectionPixmap(pal);
+ p->drawTiledPixmap(x, y, pm.width(), pm.height(), *qrt_selection);
+#endif
+ }
+}
+
+void TQTextHorizontalLine::adjustToPainter(TQPainter* p)
+{
+ height = scale(tmpheight, p);
+}
+
+
+TQTextHorizontalLine::TQTextHorizontalLine(TQTextDocument *p, const QMap<TQString, TQString> &attr,
+ const TQString &,
+ TQMimeSourceFactory &)
+ : TQTextCustomItem(p)
+{
+ height = tmpheight = 8;
+ QMap<TQString, TQString>::ConstIterator it, end = attr.end();
+ it = attr.find(TQLatin1String("color"));
+ if (it != end)
+ color = QColor(*it);
+ shade = attr.find(TQLatin1String("noshade")) == end;
+}
+
+TQTextHorizontalLine::~TQTextHorizontalLine()
+{
+}
+
+TQString TQTextHorizontalLine::richText() const
+{
+ return TQLatin1String("<hr>");
+}
+
+void TQTextHorizontalLine::draw(TQPainter* p, int x, int y, int , int , int , int ,
+ const QPalette& pal, bool selected)
+{
+ TQRect r(x, y, width, height);
+ if (is_printer(p) || !shade) {
+ QPen oldPen = p->pen();
+ if (!color.isValid())
+ p->setPen(QPen(pal.text().color(), is_printer(p) ? height/8 : qMax(2, height/4)));
+ else
+ p->setPen(QPen(color, is_printer(p) ? height/8 : qMax(2, height/4)));
+ p->drawLine(r.left()-1, y + height / 2, r.right() + 1, y + height / 2);
+ p->setPen(oldPen);
+ } else {
+ if (selected)
+ p->fillRect(r, pal.highlight());
+ QPalette pal2(pal);
+ if (color.isValid())
+ pal2.setColor(pal2.currentColorGroup(), QPalette::Dark, color);
+ qDrawShadeLine(p, r.left() - 1, y + height / 2, r.right() + 1, y + height / 2, pal2,
+ true, height / 8);
+ }
+}
+#endif //QT_NO_TEXTCUSTOMITEM
+
+/*****************************************************************/
+// Small set of utility functions to make the parser a bit simpler
+//
+
+bool TQTextDocument::hasPrefix(const TQChar* doc, int length, int pos, TQChar c)
+{
+ if (pos + 1 > length)
+ return false;
+ return doc[pos].toLower() == c.toLower();
+}
+
+bool TQTextDocument::hasPrefix(const TQChar* doc, int length, int pos, const TQString& s)
+{
+ if (pos + (int) s.length() > length)
+ return false;
+ for (int i = 0; i < (int)s.length(); i++) {
+ if (doc[pos + i].toLower() != s[i].toLower())
+ return false;
+ }
+ return true;
+}
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+static bool qt_is_cell_in_use(QList<TQTextTableCell *>& cells, int row, int col)
+{
+ for (int idx = 0; idx < cells.size(); ++idx) {
+ TQTextTableCell *c = cells.at(idx);
+ if (row >= c->row() && row < c->row() + c->rowspan()
+ && col >= c->column() && col < c->column() + c->colspan())
+ return true;
+ }
+ return false;
+}
+
+TQTextCustomItem* TQTextDocument::parseTable(const QMap<TQString, TQString> &attr, const TQTextFormat &fmt,
+ const TQChar* doc, int length, int& pos, TQTextParagraph *curpar)
+{
+
+ TQTextTable* table = new TQTextTable(this, attr);
+ int row = -1;
+ int col = -1;
+
+ TQString rowbgcolor;
+ TQString rowalign;
+ TQString tablebgcolor = attr[TQLatin1String("bgcolor")];
+
+ QList<TQTextTableCell *> multicells;
+
+ TQString tagname;
+ (void) eatSpace(doc, length, pos);
+ while (pos < length) {
+ if (hasPrefix(doc, length, pos, TQLatin1Char('<'))){
+ if (hasPrefix(doc, length, pos+1, TQLatin1Char('/'))) {
+ tagname = parseCloseTag(doc, length, pos);
+ if (tagname == TQLatin1String("table")) {
+ return table;
+ }
+ } else {
+ QMap<TQString, TQString> attr2;
+ bool emptyTag = false;
+ tagname = parseOpenTag(doc, length, pos, attr2, emptyTag);
+ if (tagname == TQLatin1String("tr")) {
+ rowbgcolor = attr2[TQLatin1String("bgcolor")];
+ rowalign = attr2[TQLatin1String("align")];
+ row++;
+ col = -1;
+ }
+ else if (tagname == TQLatin1String("td") || tagname == TQLatin1String("th")) {
+ col++;
+ while (qt_is_cell_in_use(multicells, row, col)) {
+ col++;
+ }
+
+ if (row >= 0 && col >= 0) {
+ const TQStyleSheetItem* s = sheet_->item(tagname);
+ if (!attr2.contains(TQLatin1String("bgcolor"))) {
+ if (!rowbgcolor.isEmpty())
+ attr2[TQLatin1String("bgcolor")] = rowbgcolor;
+ else if (!tablebgcolor.isEmpty())
+ attr2[TQLatin1String("bgcolor")] = tablebgcolor;
+ }
+ if (!attr2.contains(TQLatin1String("align"))) {
+ if (!rowalign.isEmpty())
+ attr2[TQLatin1String("align")] = rowalign;
+ }
+
+ // extract the cell contents
+ int end = pos;
+ while (end < length
+ && !hasPrefix(doc, length, end, TQLatin1String("</td"))
+ && !hasPrefix(doc, length, end, TQLatin1String("<td"))
+ && !hasPrefix(doc, length, end, TQLatin1String("</th"))
+ && !hasPrefix(doc, length, end, TQLatin1String("<th"))
+ && !hasPrefix(doc, length, end, TQLatin1String("<td"))
+ && !hasPrefix(doc, length, end, TQLatin1String("</tr"))
+ && !hasPrefix(doc, length, end, TQLatin1String("<tr"))
+ && !hasPrefix(doc, length, end, TQLatin1String("</table"))) {
+ if (hasPrefix(doc, length, end, TQLatin1String("<table"))) { // nested table
+ int nested = 1;
+ ++end;
+ while (end < length && nested != 0) {
+ if (hasPrefix(doc, length, end, TQLatin1String("</table")))
+ nested--;
+ if (hasPrefix(doc, length, end, TQLatin1String("<table")))
+ nested++;
+ end++;
+ }
+ }
+ end++;
+ }
+ TQTextTableCell* cell = new TQTextTableCell(table, row, col,
+ attr2, s, fmt.makeTextFormat(s, attr2, scaleFontsFactor),
+ contxt, *factory_, sheet_,
+ TQString::fromRawData(doc + pos, end - pos));
+ cell->richText()->parentPar = curpar;
+ if (cell->colspan() > 1 || cell->rowspan() > 1)
+ multicells.append(cell);
+ col += cell->colspan()-1;
+ pos = end;
+ }
+ }
+ }
+
+ } else {
+ ++pos;
+ }
+ }
+ return table;
+}
+#endif // QT_NO_TEXTCUSTOMITEM
+
+bool TQTextDocument::eatSpace(const TQChar* doc, int length, int& pos, bool includeNbsp)
+{
+ int old_pos = pos;
+ while (pos < length && doc[pos].isSpace() && (includeNbsp || (doc[pos] != TQChar(TQChar::nbsp))))
+ pos++;
+ return old_pos < pos;
+}
+
+bool TQTextDocument::eat(const TQChar* doc, int length, int& pos, TQChar c)
+{
+ bool ok = pos < length && doc[pos] == c;
+ if (ok)
+ pos++;
+ return ok;
+}
+/*****************************************************************/
+
+struct Entity {
+ const char * name;
+ Q_UINT16 code;
+};
+
+static const Entity entitylist [] = {
+ { "AElig", 0x00c6 },
+ { "Aacute", 0x00c1 },
+ { "Acirc", 0x00c2 },
+ { "Agrave", 0x00c0 },
+ { "Alpha", 0x0391 },
+ { "AMP", 38 },
+ { "Aring", 0x00c5 },
+ { "Atilde", 0x00c3 },
+ { "Auml", 0x00c4 },
+ { "Beta", 0x0392 },
+ { "Ccedil", 0x00c7 },
+ { "Chi", 0x03a7 },
+ { "Dagger", 0x2021 },
+ { "Delta", 0x0394 },
+ { "ETH", 0x00d0 },
+ { "Eacute", 0x00c9 },
+ { "Ecirc", 0x00ca },
+ { "Egrave", 0x00c8 },
+ { "Epsilon", 0x0395 },
+ { "Eta", 0x0397 },
+ { "Euml", 0x00cb },
+ { "Gamma", 0x0393 },
+ { "GT", 62 },
+ { "Iacute", 0x00cd },
+ { "Icirc", 0x00ce },
+ { "Igrave", 0x00cc },
+ { "Iota", 0x0399 },
+ { "Iuml", 0x00cf },
+ { "Kappa", 0x039a },
+ { "Lambda", 0x039b },
+ { "LT", 60 },
+ { "Mu", 0x039c },
+ { "Ntilde", 0x00d1 },
+ { "Nu", 0x039d },
+ { "OElig", 0x0152 },
+ { "Oacute", 0x00d3 },
+ { "Ocirc", 0x00d4 },
+ { "Ograve", 0x00d2 },
+ { "Omega", 0x03a9 },
+ { "Omicron", 0x039f },
+ { "Oslash", 0x00d8 },
+ { "Otilde", 0x00d5 },
+ { "Ouml", 0x00d6 },
+ { "Phi", 0x03a6 },
+ { "Pi", 0x03a0 },
+ { "Prime", 0x2033 },
+ { "Psi", 0x03a8 },
+ { "QUOT", 34 },
+ { "Rho", 0x03a1 },
+ { "Scaron", 0x0160 },
+ { "Sigma", 0x03a3 },
+ { "THORN", 0x00de },
+ { "Tau", 0x03a4 },
+ { "Theta", 0x0398 },
+ { "Uacute", 0x00da },
+ { "Ucirc", 0x00db },
+ { "Ugrave", 0x00d9 },
+ { "Upsilon", 0x03a5 },
+ { "Uuml", 0x00dc },
+ { "Xi", 0x039e },
+ { "Yacute", 0x00dd },
+ { "Yuml", 0x0178 },
+ { "Zeta", 0x0396 },
+ { "aacute", 0x00e1 },
+ { "acirc", 0x00e2 },
+ { "acute", 0x00b4 },
+ { "aelig", 0x00e6 },
+ { "agrave", 0x00e0 },
+ { "alefsym", 0x2135 },
+ { "alpha", 0x03b1 },
+ { "amp", 38 },
+ { "and", 0x22a5 },
+ { "ang", 0x2220 },
+ { "apos", 0x0027 },
+ { "aring", 0x00e5 },
+ { "asymp", 0x2248 },
+ { "atilde", 0x00e3 },
+ { "auml", 0x00e4 },
+ { "bdquo", 0x201e },
+ { "beta", 0x03b2 },
+ { "brvbar", 0x00a6 },
+ { "bull", 0x2022 },
+ { "cap", 0x2229 },
+ { "ccedil", 0x00e7 },
+ { "cedil", 0x00b8 },
+ { "cent", 0x00a2 },
+ { "chi", 0x03c7 },
+ { "circ", 0x02c6 },
+ { "clubs", 0x2663 },
+ { "cong", 0x2245 },
+ { "copy", 0x00a9 },
+ { "crarr", 0x21b5 },
+ { "cup", 0x222a },
+ { "cur" "ren", 0x00a4 },
+ { "dArr", 0x21d3 },
+ { "dagger", 0x2020 },
+ { "darr", 0x2193 },
+ { "deg", 0x00b0 },
+ { "delta", 0x03b4 },
+ { "diams", 0x2666 },
+ { "divide", 0x00f7 },
+ { "eacute", 0x00e9 },
+ { "ecirc", 0x00ea },
+ { "egrave", 0x00e8 },
+ { "empty", 0x2205 },
+ { "emsp", 0x2003 },
+ { "ensp", 0x2002 },
+ { "epsilon", 0x03b5 },
+ { "equiv", 0x2261 },
+ { "eta", 0x03b7 },
+ { "eth", 0x00f0 },
+ { "euml", 0x00eb },
+ { "euro", 0x20ac },
+ { "exist", 0x2203 },
+ { "fnof", 0x0192 },
+ { "forall", 0x2200 },
+ { "frac12", 0x00bd },
+ { "frac14", 0x00bc },
+ { "frac34", 0x00be },
+ { "frasl", 0x2044 },
+ { "gamma", 0x03b3 },
+ { "ge", 0x2265 },
+ { "gt", 62 },
+ { "hArr", 0x21d4 },
+ { "harr", 0x2194 },
+ { "hearts", 0x2665 },
+ { "hellip", 0x2026 },
+ { "iacute", 0x00ed },
+ { "icirc", 0x00ee },
+ { "iexcl", 0x00a1 },
+ { "igrave", 0x00ec },
+ { "image", 0x2111 },
+ { "infin", 0x221e },
+ { "int", 0x222b },
+ { "iota", 0x03b9 },
+ { "iquest", 0x00bf },
+ { "isin", 0x2208 },
+ { "iuml", 0x00ef },
+ { "kappa", 0x03ba },
+ { "lArr", 0x21d0 },
+ { "lambda", 0x03bb },
+ { "lang", 0x2329 },
+ { "laquo", 0x00ab },
+ { "larr", 0x2190 },
+ { "lceil", 0x2308 },
+ { "ldquo", 0x201c },
+ { "le", 0x2264 },
+ { "lfloor", 0x230a },
+ { "lowast", 0x2217 },
+ { "loz", 0x25ca },
+ { "lrm", 0x200e },
+ { "lsaquo", 0x2039 },
+ { "lsquo", 0x2018 },
+ { "lt", 60 },
+ { "macr", 0x00af },
+ { "mdash", 0x2014 },
+ { "micro", 0x00b5 },
+ { "middot", 0x00b7 },
+ { "minus", 0x2212 },
+ { "mu", 0x03bc },
+ { "nabla", 0x2207 },
+ { "nbsp", 0x00a0 },
+ { "ndash", 0x2013 },
+ { "ne", 0x2260 },
+ { "ni", 0x220b },
+ { "not", 0x00ac },
+ { "notin", 0x2209 },
+ { "nsub", 0x2284 },
+ { "ntilde", 0x00f1 },
+ { "nu", 0x03bd },
+ { "oacute", 0x00f3 },
+ { "ocirc", 0x00f4 },
+ { "oelig", 0x0153 },
+ { "ograve", 0x00f2 },
+ { "oline", 0x203e },
+ { "omega", 0x03c9 },
+ { "omicron", 0x03bf },
+ { "oplus", 0x2295 },
+ { "or", 0x22a6 },
+ { "ordf", 0x00aa },
+ { "ordm", 0x00ba },
+ { "oslash", 0x00f8 },
+ { "otilde", 0x00f5 },
+ { "otimes", 0x2297 },
+ { "ouml", 0x00f6 },
+ { "para", 0x00b6 },
+ { "part", 0x2202 },
+ { "percnt", 0x0025 },
+ { "permil", 0x2030 },
+ { "perp", 0x22a5 },
+ { "phi", 0x03c6 },
+ { "pi", 0x03c0 },
+ { "piv", 0x03d6 },
+ { "plusmn", 0x00b1 },
+ { "pound", 0x00a3 },
+ { "prime", 0x2032 },
+ { "prod", 0x220f },
+ { "prop", 0x221d },
+ { "psi", 0x03c8 },
+ { "quot", 34 },
+ { "rArr", 0x21d2 },
+ { "radic", 0x221a },
+ { "rang", 0x232a },
+ { "raquo", 0x00bb },
+ { "rarr", 0x2192 },
+ { "rceil", 0x2309 },
+ { "rdquo", 0x201d },
+ { "real", 0x211c },
+ { "reg", 0x00ae },
+ { "rfloor", 0x230b },
+ { "rho", 0x03c1 },
+ { "rlm", 0x200f },
+ { "rsaquo", 0x203a },
+ { "rsquo", 0x2019 },
+ { "sbquo", 0x201a },
+ { "scaron", 0x0161 },
+ { "sdot", 0x22c5 },
+ { "sect", 0x00a7 },
+ { "shy", 0x00ad },
+ { "sigma", 0x03c3 },
+ { "sigmaf", 0x03c2 },
+ { "sim", 0x223c },
+ { "spades", 0x2660 },
+ { "sub", 0x2282 },
+ { "sube", 0x2286 },
+ { "sum", 0x2211 },
+ { "sup1", 0x00b9 },
+ { "sup2", 0x00b2 },
+ { "sup3", 0x00b3 },
+ { "sup", 0x2283 },
+ { "supe", 0x2287 },
+ { "szlig", 0x00df },
+ { "tau", 0x03c4 },
+ { "there4", 0x2234 },
+ { "theta", 0x03b8 },
+ { "thetasym", 0x03d1 },
+ { "thinsp", 0x2009 },
+ { "thorn", 0x00fe },
+ { "tilde", 0x02dc },
+ { "times", 0x00d7 },
+ { "trade", 0x2122 },
+ { "uArr", 0x21d1 },
+ { "uacute", 0x00fa },
+ { "uarr", 0x2191 },
+ { "ucirc", 0x00fb },
+ { "ugrave", 0x00f9 },
+ { "uml", 0x00a8 },
+ { "upsih", 0x03d2 },
+ { "upsilon", 0x03c5 },
+ { "uuml", 0x00fc },
+ { "weierp", 0x2118 },
+ { "xi", 0x03be },
+ { "yacute", 0x00fd },
+ { "yen", 0x00a5 },
+ { "yuml", 0x00ff },
+ { "zeta", 0x03b6 },
+ { "zwj", 0x200d },
+ { "zwnj", 0x200c },
+ { "", 0x0000 }
+};
+
+
+
+
+
+static QMap<QByteArray, TQChar> *html_map = 0;
+static void qt_cleanup_html_map()
+{
+ delete html_map;
+ html_map = 0;
+}
+
+static QMap<QByteArray, TQChar> *htmlMap()
+{
+ if (!html_map) {
+ html_map = new QMap<QByteArray, TQChar>;
+ qAddPostRoutine(qt_cleanup_html_map);
+
+ const Entity *ent = entitylist;
+ while(ent->code) {
+ html_map->insert(QByteArray(ent->name), TQChar(ent->code));
+ ent++;
+ }
+ }
+ return html_map;
+}
+
+TQChar TQTextDocument::parseHTMLSpecialChar(const TQChar* doc, int length, int& pos)
+{
+ TQString s;
+ pos++;
+ int recoverpos = pos;
+ while (pos < length && doc[pos] != TQLatin1Char(';') && !doc[pos].isSpace() && pos < recoverpos + 8) {
+ s += doc[pos];
+ pos++;
+ }
+ if (doc[pos] != TQLatin1Char(';') && !doc[pos].isSpace()) {
+ pos = recoverpos;
+ return TQLatin1Char('&');
+ }
+ pos++;
+
+ if (s.length() > 1 && s[0] == TQLatin1Char('#')) {
+ int off = 1;
+ int base = 10;
+ if (s[1] == TQLatin1Char('x')) {
+ off = 2;
+ base = 16;
+ }
+ bool ok;
+ int num = s.mid(off).toInt(&ok, base);
+ if (num == 151) // ### hack for designer manual
+ return TQLatin1Char('-');
+ return num;
+ }
+
+ QMap<QByteArray, TQChar>::Iterator it = htmlMap()->find(s.toLatin1());
+ if (it != htmlMap()->end()) {
+ return *it;
+ }
+
+ pos = recoverpos;
+ return TQLatin1Char('&');
+}
+
+TQString TQTextDocument::parseWord(const TQChar* doc, int length, int& pos, bool lower)
+{
+ TQString s;
+
+ if (doc[pos] == TQLatin1Char('"')) {
+ pos++;
+ while (pos < length && doc[pos] != TQLatin1Char('"')) {
+ if (doc[pos] == TQLatin1Char('&')) {
+ s += parseHTMLSpecialChar(doc, length, pos);
+ } else {
+ s += doc[pos];
+ pos++;
+ }
+ }
+ eat(doc, length, pos, TQLatin1Char('"'));
+ } else if (doc[pos] == TQLatin1Char('\'')) {
+ pos++;
+ while (pos < length && doc[pos] != TQLatin1Char('\'')) {
+ s += doc[pos];
+ pos++;
+ }
+ eat(doc, length, pos, TQLatin1Char('\''));
+ } else {
+ static TQString term = TQString::fromLatin1("/>");
+ while (pos < length
+ && doc[pos] != TQLatin1Char('>')
+ && !hasPrefix(doc, length, pos, term)
+ && doc[pos] != TQLatin1Char('<')
+ && doc[pos] != TQLatin1Char('=')
+ && !doc[pos].isSpace())
+ {
+ if (doc[pos] == TQLatin1Char('&')) {
+ s += parseHTMLSpecialChar(doc, length, pos);
+ } else {
+ s += doc[pos];
+ pos++;
+ }
+ }
+ if (lower)
+ s = s.toLower();
+ }
+ return s;
+}
+
+TQChar TQTextDocument::parseChar(const TQChar* doc, int length, int& pos, TQStyleSheetItem::WhiteSpaceMode wsm)
+{
+ if (pos >= length)
+ return TQChar::null;
+
+ TQChar c = doc[pos++];
+
+ if (c == TQLatin1Char('<'))
+ return TQChar::null;
+
+ if (c.isSpace() && c != TQChar(TQChar::nbsp)) {
+ if (wsm == TQStyleSheetItem::WhiteSpacePre) {
+ if (c == TQLatin1Char('\n'))
+ return TQChar::LineSeparator;
+ else
+ return c;
+ } else { // non-pre mode: collapse whitespace except nbsp
+ while (pos< length &&
+ doc[pos].isSpace() && doc[pos] != TQChar(TQChar::nbsp))
+ pos++;
+ return TQLatin1Char(' ');
+ }
+ }
+ else if (c == TQLatin1Char('&'))
+ return parseHTMLSpecialChar(doc, length, --pos);
+ else
+ return c;
+}
+
+TQString TQTextDocument::parseOpenTag(const TQChar* doc, int length, int& pos,
+ QMap<TQString, TQString> &attr, bool& emptyTag)
+{
+ emptyTag = false;
+ pos++;
+ if (hasPrefix(doc, length, pos, TQLatin1Char('!'))) {
+ if (hasPrefix(doc, length, pos+1, TQLatin1String("--"))) {
+ pos += 3;
+ // eat comments
+ TQString pref = TQString::fromLatin1("-->");
+ while (!hasPrefix(doc, length, pos, pref) && pos < length)
+ pos++;
+ if (hasPrefix(doc, length, pos, pref)) {
+ pos += 3;
+ eatSpace(doc, length, pos, true);
+ }
+ emptyTag = true;
+ return TQString();
+ }
+ else {
+ // eat strange internal tags
+ while (!hasPrefix(doc, length, pos, TQLatin1Char('>')) && pos < length)
+ pos++;
+ if (hasPrefix(doc, length, pos, TQLatin1Char('>'))) {
+ pos++;
+ eatSpace(doc, length, pos, true);
+ }
+ return TQString();
+ }
+ }
+
+ TQString tag = parseWord(doc, length, pos);
+ eatSpace(doc, length, pos, true);
+ static TQString term = TQString::fromLatin1("/>");
+ static TQString s_TRUE = TQString::fromLatin1("TRUE");
+
+ while (doc[pos] != TQLatin1Char('>') && ! (emptyTag = hasPrefix(doc, length, pos, term))) {
+ TQString key = parseWord(doc, length, pos);
+ eatSpace(doc, length, pos, true);
+ if (key.isEmpty()) {
+ // error recovery
+ while (pos < length && doc[pos] != TQLatin1Char('>'))
+ pos++;
+ break;
+ }
+ TQString value;
+ if (hasPrefix(doc, length, pos, TQLatin1Char('='))){
+ pos++;
+ eatSpace(doc, length, pos);
+ value = parseWord(doc, length, pos, false);
+ }
+ else
+ value = s_TRUE;
+ attr.insert(key.toLower(), value);
+ eatSpace(doc, length, pos, true);
+ }
+
+ if (emptyTag) {
+ eat(doc, length, pos, TQLatin1Char('/'));
+ eat(doc, length, pos, TQLatin1Char('>'));
+ }
+ else
+ eat(doc, length, pos, TQLatin1Char('>'));
+
+ return tag;
+}
+
+TQString TQTextDocument::parseCloseTag(const TQChar* doc, int length, int& pos)
+{
+ pos++;
+ pos++;
+ TQString tag = parseWord(doc, length, pos);
+ eatSpace(doc, length, pos, true);
+ eat(doc, length, pos, TQLatin1Char('>'));
+ return tag;
+}
+
+TQTextFlow::TQTextFlow()
+{
+ w = pagesize = 0;
+}
+
+TQTextFlow::~TQTextFlow()
+{
+ clear();
+}
+
+void TQTextFlow::clear()
+{
+#ifndef QT_NO_TEXTCUSTOMITEM
+ while (!leftItems.isEmpty())
+ delete leftItems.takeFirst();
+ while (!rightItems.isEmpty())
+ delete rightItems.takeFirst();
+#endif
+}
+
+void TQTextFlow::setWidth(int width)
+{
+ w = width;
+}
+
+int TQTextFlow::adjustLMargin(int yp, int, int margin, int space)
+{
+#ifndef QT_NO_TEXTCUSTOMITEM
+ for (int idx = 0; idx < leftItems.size(); ++idx) {
+ TQTextCustomItem* item = leftItems.at(idx);
+ if (item->ypos == -1)
+ continue;
+ if (yp >= item->ypos && yp < item->ypos + item->height)
+ margin = qMax(margin, item->xpos + item->width + space);
+ }
+#endif
+ return margin;
+}
+
+int TQTextFlow::adjustRMargin(int yp, int, int margin, int space)
+{
+#ifndef QT_NO_TEXTCUSTOMITEM
+ for (int idx = 0; idx < rightItems.size(); ++idx) {
+ TQTextCustomItem* item = rightItems.at(idx);
+ if (item->ypos == -1)
+ continue;
+ if (yp >= item->ypos && yp < item->ypos + item->height)
+ margin = qMax(margin, w - item->xpos - space);
+ }
+#endif
+ return margin;
+}
+
+
+int TQTextFlow::adjustFlow(int y, int /*w*/, int h)
+{
+ if (pagesize > 0) { // check pages
+ int yinpage = y % pagesize;
+ if (yinpage <= border_tolerance)
+ return border_tolerance - yinpage;
+ else
+ if (yinpage + h > pagesize - border_tolerance)
+ return (pagesize - yinpage) + border_tolerance;
+ }
+ return 0;
+}
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+void TQTextFlow::unregisterFloatingItem(TQTextCustomItem* item)
+{
+ leftItems.removeAll(item);
+ rightItems.removeAll(item);
+}
+
+void TQTextFlow::registerFloatingItem(TQTextCustomItem* item)
+{
+ if (item->placement() == TQTextCustomItem::PlaceRight) {
+ if (!rightItems.contains(item))
+ rightItems.append(item);
+ } else if (item->placement() == TQTextCustomItem::PlaceLeft &&
+ !leftItems.contains(item)) {
+ leftItems.append(item);
+ }
+}
+#endif // QT_NO_TEXTCUSTOMITEM
+
+TQRect TQTextFlow::boundingRect() const
+{
+ TQRect br;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ for (int idx = 0; idx < leftItems.size(); ++idx) {
+ TQTextCustomItem* item = leftItems.at(idx);
+ br = br.united(item->geometry());
+ }
+ for (int idx = 0; idx < rightItems.size(); ++idx) {
+ TQTextCustomItem* item = rightItems.at(idx);
+ br = br.united(item->geometry());
+ }
+#endif
+ return br;
+}
+
+
+void TQTextFlow::drawFloatingItems(TQPainter* p, int cx, int cy, int cw, int ch,
+ const QPalette &pal, bool selected)
+{
+#ifndef QT_NO_TEXTCUSTOMITEM
+ for (int idx = 0; idx < leftItems.size(); ++idx) {
+ TQTextCustomItem* item = leftItems.at(idx);
+ if (item->xpos == -1 || item->ypos == -1)
+ continue;
+ item->draw(p, item->xpos, item->ypos, cx, cy, cw, ch, pal, selected);
+ }
+
+ for (int idx = 0; idx < rightItems.size(); ++idx) {
+ TQTextCustomItem* item = rightItems.at(idx);
+ if (item->xpos == -1 || item->ypos == -1)
+ continue;
+ item->draw(p, item->xpos, item->ypos, cx, cy, cw, ch, pal, selected);
+ }
+#endif
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+void TQTextCustomItem::pageBreak(int /*y*/ , TQTextFlow* /*flow*/)
+{
+}
+#endif
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+TQTextTable::TQTextTable(TQTextDocument *p, const QMap<TQString, TQString> & attr )
+ : TQTextCustomItem(p)
+{
+ cellspacing = 2;
+ cellpadding = 1;
+ border = innerborder = 0;
+
+ QMap<TQString, TQString>::ConstIterator it, end = attr.end();
+ it = attr.find(TQLatin1String("cellspacing"));
+ if (it != end)
+ cellspacing = (*it).toInt();
+ it = attr.find(TQLatin1String("cellpadding"));
+ if (it != end)
+ cellpadding = (*it).toInt();
+ it = attr.find(TQLatin1String("border"));
+ if (it != end) {
+ if (*it == TQLatin1String("TRUE"))
+ border = 1;
+ else
+ border = (*it).toInt();
+ }
+ us_b = border;
+
+ innerborder = us_ib = border ? 1 : 0;
+
+ if (border)
+ cellspacing += 2;
+
+ us_ib = innerborder;
+ us_cs = cellspacing;
+ us_cp = cellpadding;
+ outerborder = cellspacing + border;
+ us_ob = outerborder;
+ layout = new TQGridLayout(1, 1, cellspacing);
+
+ fixwidth = 0;
+ stretch = 0;
+ it = attr.find(TQLatin1String("width"));
+ if (it != end) {
+ bool b;
+ TQString s(*it);
+ int w = s.toInt(&b);
+ if (b) {
+ fixwidth = w;
+ } else {
+ s = s.trimmed();
+ if (s.length() > 1 && s[(int)s.length()-1] == TQLatin1Char('%'))
+ stretch = s.left(s.length()-1).toInt();
+ }
+ }
+ us_fixwidth = fixwidth;
+
+ place = PlaceInline;
+ if (attr[TQLatin1String("align")] == TQLatin1String("left"))
+ place = PlaceLeft;
+ else if (attr[TQLatin1String("align")] == TQLatin1String("right"))
+ place = PlaceRight;
+ cachewidth = 0;
+ attributes = attr;
+ pageBreakFor = -1;
+}
+
+TQTextTable::~TQTextTable()
+{
+ delete layout;
+}
+
+TQString TQTextTable::richText() const
+{
+ TQString s;
+ s = TQLatin1String("<table ");
+ QMap<TQString, TQString>::ConstIterator it = attributes.begin();
+ for (; it != attributes.end(); ++it)
+ s += it.key() + TQLatin1Char('=') + *it + TQLatin1Char(' ');
+ s += TQLatin1String(">\n");
+
+ int lastRow = -1;
+ bool needEnd = false;
+ for (int idx = 0; idx < cells.size(); ++idx) {
+ TQTextTableCell *cell = cells.at(idx);
+ if (lastRow != cell->row()) {
+ if (lastRow != -1)
+ s += TQLatin1String("</tr>\n");
+ s += TQLatin1String("<tr>");
+ lastRow = cell->row();
+ needEnd = true;
+ }
+ s += TQLatin1String("<td");
+ it = cell->attributes.constBegin();
+ for (; it != cell->attributes.constEnd(); ++it)
+ s += TQLatin1Char(' ') + it.key() + TQLatin1Char('=') + *it;
+ s += TQLatin1Char('>');
+ s += cell->richText()->richText();
+ s += TQLatin1String("</td>");
+ }
+ if (needEnd)
+ s += TQLatin1String("</tr>\n");
+ s += TQLatin1String("</table>\n");
+ return s;
+}
+
+void TQTextTable::adjustToPainter(TQPainter* p)
+{
+ cellspacing = scale(us_cs, p);
+ cellpadding = scale(us_cp, p);
+ border = scale(us_b , p);
+ innerborder = scale(us_ib, p);
+ outerborder = scale(us_ob ,p);
+ fixwidth = scale( us_fixwidth, p);
+ width = 0;
+ cachewidth = 0;
+ for (int idx = 0; idx < cells.size(); ++idx) {
+ TQTextTableCell *cell = cells.at(idx);
+ cell->adjustToPainter(p);
+ }
+}
+
+void TQTextTable::adjustCells(int y , int shift)
+{
+ bool enlarge = false;
+ for (int idx = 0; idx < cells.size(); ++idx) {
+ TQTextTableCell *cell = cells.at(idx);
+ TQRect r = cell->geometry();
+ if (y <= r.top()) {
+ r.moveBy(0, shift);
+ cell->setGeometry(r);
+ enlarge = true;
+ } else if (y <= r.bottom()) {
+ r.rBottom() += shift;
+ cell->setGeometry(r);
+ enlarge = true;
+ }
+ }
+ if (enlarge)
+ height += shift;
+}
+
+void TQTextTable::pageBreak(int yt, TQTextFlow* flow)
+{
+ if (flow->pageSize() <= 0)
+ return;
+ if (layout && pageBreakFor > 0 && pageBreakFor != yt) {
+ layout->invalidate();
+ int h = layout->heightForWidth(width-2*outerborder);
+ layout->setGeometry(TQRect(0, 0, width-2*outerborder, h) );
+ height = layout->geometry().height()+2*outerborder;
+ }
+ pageBreakFor = yt;
+ for (int idx = 0; idx < cells.size(); ++idx) {
+ TQTextTableCell *cell = cells.at(idx);
+ int y = yt + outerborder + cell->geometry().y();
+ int shift = flow->adjustFlow(y - cellspacing, width, cell->richText()->height() + 2*cellspacing);
+ adjustCells(y - outerborder - yt, shift);
+ }
+}
+
+
+void TQTextTable::draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
+ const QPalette &pal, bool selected)
+{
+ if (placement() != PlaceInline) {
+ x = xpos;
+ y = ypos;
+ }
+
+ for (int idx = 0; idx < cells.size(); ++idx) {
+ TQTextTableCell *cell = cells.at(idx);
+ if ((cx < 0 && cy < 0) ||
+ TQRect(cx, cy, cw, ch).intersects(TQRect(x + outerborder + cell->geometry().x(),
+ y + outerborder + cell->geometry().y(),
+ cell->geometry().width(),
+ cell->geometry().height()))) {
+ cell->draw(p, x+outerborder, y+outerborder, cx, cy, cw, ch, pal, selected);
+ if (border) {
+ TQRect r(x+outerborder+cell->geometry().x() - innerborder,
+ y+outerborder+cell->geometry().y() - innerborder,
+ cell->geometry().width() + 2 * innerborder,
+ cell->geometry().height() + 2 * innerborder);
+ if (is_printer(p)) {
+ QPen oldPen = p->pen();
+ TQRect r2 = r;
+ r2.adjust(innerborder/2, innerborder/2, -innerborder/2, -innerborder/2);
+ p->setPen(QPen(pal.text().color(), innerborder));
+ p->drawRect(r2);
+ p->setPen(oldPen);
+ } else {
+ int s = qMax(cellspacing-2*innerborder, 0);
+ if (s) {
+ p->fillRect(r.left()-s, r.top(), s+1, r.height(), pal.button());
+ p->fillRect(r.right(), r.top(), s+1, r.height(), pal.button());
+ p->fillRect(r.left()-s, r.top()-s, r.width()+2*s, s, pal.button());
+ p->fillRect(r.left()-s, r.bottom(), r.width()+2*s, s, pal.button());
+ }
+ qDrawShadePanel(p, r, pal, true, innerborder);
+ }
+ }
+ }
+ }
+ if (border) {
+ TQRect r (x, y, width, height);
+ if (is_printer(p)) {
+ TQRect r2 = r;
+ r2.adjust(border/2, border/2, -border/2, -border/2);
+ QPen oldPen = p->pen();
+ p->setPen(QPen(pal.text().color(), border));
+ p->drawRect(r2);
+ p->setPen(oldPen);
+ } else {
+ int s = border+qMax(cellspacing-2*innerborder, 0);
+ if (s) {
+ p->fillRect(r.left(), r.top(), s, r.height(), pal.button());
+ p->fillRect(r.right()-s, r.top(), s, r.height(), pal.button());
+ p->fillRect(r.left(), r.top(), r.width(), s, pal.button());
+ p->fillRect(r.left(), r.bottom()-s, r.width(), s, pal.button());
+ }
+ qDrawShadePanel(p, r, pal, false, border);
+ }
+ }
+
+}
+
+int TQTextTable::minimumWidth() const
+{
+ return qMax(fixwidth, ((layout ? layout->minimumSize().width() : 0) + 2 * outerborder));
+}
+
+void TQTextTable::resize(int nwidth)
+{
+ if (fixwidth && cachewidth != 0)
+ return;
+ if (nwidth == cachewidth)
+ return;
+
+
+ cachewidth = nwidth;
+ int w = nwidth;
+
+ format(w);
+
+ if (stretch)
+ nwidth = nwidth * stretch / 100;
+
+ width = nwidth;
+ layout->invalidate();
+ int shw = layout->sizeHint().width() + 2*outerborder;
+ int mw = layout->minimumSize().width() + 2*outerborder;
+ if (stretch)
+ width = qMax(mw, nwidth);
+ else
+ width = qMax(mw, qMin(nwidth, shw));
+
+ if (fixwidth)
+ width = fixwidth;
+
+ layout->invalidate();
+ mw = layout->minimumSize().width() + 2*outerborder;
+ width = qMax(width, mw);
+
+ int h = layout->heightForWidth(width-2*outerborder);
+ layout->setGeometry(TQRect(0, 0, width-2*outerborder, h) );
+ height = layout->geometry().height()+2*outerborder;
+}
+
+void TQTextTable::format(int w)
+{
+ for (int i = 0; i < (int)cells.count(); ++i) {
+ TQTextTableCell *cell = cells.at(i);
+ TQRect r = cell->geometry();
+ r.setWidth(w - 2*outerborder);
+ cell->setGeometry(r);
+ }
+}
+
+void TQTextTable::addCell(TQTextTableCell* cell)
+{
+ cells.append(cell);
+ layout->addMultiCell(cell, cell->row(), cell->row() + cell->rowspan()-1,
+ cell->column(), cell->column() + cell->colspan()-1);
+}
+
+bool TQTextTable::enter(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd)
+{
+ currCell.remove(c);
+ if (!atEnd)
+ return next(c, doc, parag, idx, ox, oy);
+ currCell.insert(c, cells.count());
+ return prev(c, doc, parag, idx, ox, oy);
+}
+
+bool TQTextTable::enterAt(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint &pos)
+{
+ currCell.remove(c);
+ int lastCell = -1;
+ int lastY = -1;
+ int i;
+ for (i = 0; i < (int)cells.count(); ++i) {
+ TQTextTableCell *cell = cells.at(i);
+ if (!cell)
+ continue;
+ TQRect r(cell->geometry().x(),
+ cell->geometry().y(),
+ cell->geometry().width() + 2 * innerborder + 2 * outerborder,
+ cell->geometry().height() + 2 * innerborder + 2 * outerborder);
+
+ if (r.left() <= pos.x() && r.right() >= pos.x()) {
+ if (cell->geometry().y() > lastY) {
+ lastCell = i;
+ lastY = cell->geometry().y();
+ }
+ if (r.top() <= pos.y() && r.bottom() >= pos.y()) {
+ currCell.insert(c, i);
+ break;
+ }
+ }
+ }
+ if (i == (int) cells.count())
+ return false; // no cell found
+
+ if (currCell.find(c) == currCell.end()) {
+ if (lastY != -1)
+ currCell.insert(c, lastCell);
+ else
+ return false;
+ }
+
+ TQTextTableCell *cell = cells.at(*currCell.find(c));
+ if (!cell)
+ return false;
+ doc = cell->richText();
+ parag = doc->firstParagraph();
+ idx = 0;
+ ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
+ oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
+ return true;
+}
+
+bool TQTextTable::next(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy)
+{
+ int cc = -1;
+ if (currCell.find(c) != currCell.end())
+ cc = *currCell.find(c);
+ if (cc > (int)cells.count() - 1 || cc < 0)
+ cc = -1;
+ currCell.remove(c);
+ currCell.insert(c, ++cc);
+ if (cc >= (int)cells.count()) {
+ currCell.insert(c, 0);
+ TQTextCustomItem::next(c, doc, parag, idx, ox, oy);
+ TQTextTableCell *cell = cells.first();
+ if (!cell)
+ return false;
+ doc = cell->richText();
+ idx = -1;
+ return true;
+ }
+
+ if (currCell.find(c) == currCell.end())
+ return false;
+ TQTextTableCell *cell = cells.at(*currCell.find(c));
+ if (!cell)
+ return false;
+ doc = cell->richText();
+ parag = doc->firstParagraph();
+ idx = 0;
+ ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
+ oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
+ return true;
+}
+
+bool TQTextTable::prev(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy)
+{
+ int cc = -1;
+ if (currCell.find(c) != currCell.end())
+ cc = *currCell.find(c);
+ if (cc > (int)cells.count() - 1 || cc < 0)
+ cc = cells.count();
+ currCell.remove(c);
+ currCell.insert(c, --cc);
+ if (cc < 0) {
+ currCell.insert(c, 0);
+ TQTextCustomItem::prev(c, doc, parag, idx, ox, oy);
+ TQTextTableCell *cell = cells.first();
+ if (!cell)
+ return false;
+ doc = cell->richText();
+ idx = -1;
+ return true;
+ }
+
+ if (currCell.find(c) == currCell.end())
+ return false;
+ TQTextTableCell *cell = cells.at(*currCell.find(c));
+ if (!cell)
+ return false;
+ doc = cell->richText();
+ parag = doc->lastParagraph();
+ idx = parag->length() - 1;
+ ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
+ oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
+ return true;
+}
+
+bool TQTextTable::down(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy)
+{
+ if (currCell.find(c) == currCell.end())
+ return false;
+ TQTextTableCell *cell = cells.at(*currCell.find(c));
+ if (cell->row_ == layout->numRows() - 1) {
+ currCell.insert(c, 0);
+ TQTextCustomItem::down(c, doc, parag, idx, ox, oy);
+ TQTextTableCell *cell = cells.first();
+ if (!cell)
+ return false;
+ doc = cell->richText();
+ idx = -1;
+ return true;
+ }
+
+ int oldRow = cell->row_;
+ int oldCol = cell->col_;
+ if (currCell.find(c) == currCell.end())
+ return false;
+ int cc = *currCell.find(c);
+ for (int i = cc; i < (int)cells.count(); ++i) {
+ cell = cells.at(i);
+ if (cell->row_ > oldRow && cell->col_ == oldCol) {
+ currCell.insert(c, i);
+ break;
+ }
+ }
+ doc = cell->richText();
+ if (!cell)
+ return false;
+ parag = doc->firstParagraph();
+ idx = 0;
+ ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
+ oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
+ return true;
+}
+
+bool TQTextTable::up(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy)
+{
+ if (currCell.find(c) == currCell.end())
+ return false;
+ TQTextTableCell *cell = cells.at(*currCell.find(c));
+ if (cell->row_ == 0) {
+ currCell.insert(c, 0);
+ TQTextCustomItem::up(c, doc, parag, idx, ox, oy);
+ TQTextTableCell *cell = cells.first();
+ if (!cell)
+ return false;
+ doc = cell->richText();
+ idx = -1;
+ return true;
+ }
+
+ int oldRow = cell->row_;
+ int oldCol = cell->col_;
+ if (currCell.find(c) == currCell.end())
+ return false;
+ int cc = *currCell.find(c);
+ for (int i = cc; i >= 0; --i) {
+ cell = cells.at(i);
+ if (cell->row_ < oldRow && cell->col_ == oldCol) {
+ currCell.insert(c, i);
+ break;
+ }
+ }
+ doc = cell->richText();
+ if (!cell)
+ return false;
+ parag = doc->lastParagraph();
+ idx = parag->length() - 1;
+ ox += cell->geometry().x() + cell->horizontalAlignmentOffset() + outerborder + parent->x();
+ oy += cell->geometry().y() + cell->verticalAlignmentOffset() + outerborder;
+ return true;
+}
+
+TQTextTableCell::TQTextTableCell(TQTextTable* table,
+ int row, int column,
+ const QMap<TQString, TQString> &attr,
+ const TQStyleSheetItem* style,
+ const TQTextFormat& fmt, const TQString& context,
+ TQMimeSourceFactory &factory, TQStyleSheet *sheet,
+ const TQString& doc)
+{
+ cached_width = -1;
+ cached_sizehint = -1;
+
+ maxw = QWIDGETSIZE_MAX;
+ minw = 0;
+
+ parent = table;
+ row_ = row;
+ col_ = column;
+ stretch_ = 0;
+ richtext = new TQTextDocument(table->parent);
+ richtext->formatCollection()->setPaintDevice(table->parent->formatCollection()->paintDevice());
+ richtext->bodyText = fmt.color();
+ richtext->setTableCell(this);
+
+ QMap<TQString,TQString>::ConstIterator it, end = attr.end();
+ int halign = style->alignment();
+ if (halign != TQStyleSheetItem::Undefined)
+ richtext->setAlignment(halign);
+ it = attr.find(TQLatin1String("align"));
+ if (it != end && ! (*it).isEmpty()) {
+ TQString a = (*it).toLower();
+ if (a == TQLatin1String("left"))
+ richtext->setAlignment(Qt::AlignLeft);
+ else if (a == TQLatin1String("center"))
+ richtext->setAlignment(Qt::AlignHCenter);
+ else if (a == TQLatin1String("right"))
+ richtext->setAlignment(Qt::AlignRight);
+ }
+ align = 0;
+ it = attr.find(TQLatin1String("valign"));
+ if (it != end && ! (*it).isEmpty()) {
+ TQString va = (*it).toLower();
+ if ( va == TQLatin1String("top") )
+ align |= Qt::AlignTop;
+ else if ( va == TQLatin1String("center") || va == TQLatin1String("middle") )
+ align |= Qt::AlignVCenter;
+ else if (va == TQLatin1String("bottom"))
+ align |= Qt::AlignBottom;
+ }
+ richtext->setFormatter(table->parent->formatter());
+ richtext->setUseFormatCollection(table->parent->useFormatCollection());
+ richtext->setMimeSourceFactory(&factory);
+ richtext->setStyleSheet(sheet);
+ richtext->setRichText(doc, context, &fmt);
+ rowspan_ = 1;
+ colspan_ = 1;
+
+ it = attr.find(TQLatin1String("colspan"));
+ if (it != end)
+ colspan_ = (*it).toInt();
+ it = attr.find(TQLatin1String("rowspan"));
+ if (it != end)
+ rowspan_ = (*it).toInt();
+
+ background = 0;
+ it = attr.find(TQLatin1String("bgcolor"));
+ if (it != end) {
+ background = new TQBrush(QColor(*it));
+ }
+
+ hasFixedWidth = false;
+ it = attr.find(TQLatin1String("width"));
+ if (it != end) {
+ bool b;
+ TQString s(*it);
+ int w = s.toInt(&b);
+ if (b) {
+ maxw = w;
+ minw = maxw;
+ hasFixedWidth = true;
+ } else {
+ s = s.trimmed();
+ if (s.length() > 1 && s[(int)s.length()-1] == TQLatin1Char('%'))
+ stretch_ = s.left(s.length()-1).toInt();
+ }
+ }
+
+ attributes = attr;
+
+ parent->addCell(this);
+}
+
+TQTextTableCell::~TQTextTableCell()
+{
+ delete background;
+ background = 0;
+ delete richtext;
+ richtext = 0;
+}
+
+TQSize TQTextTableCell::tqsizeHint() const
+{
+ int extra = 2 * (parent->innerborder + parent->cellpadding + border_tolerance);
+ int used = richtext->widthUsed() + extra;
+
+ if (stretch_) {
+ int w = parent->width * stretch_ / 100 - 2*parent->cellspacing - 2*parent->cellpadding;
+ return QSize(qMin(w, maxw), 0).expandedTo(minimumSize());
+ }
+
+ return QSize(used, 0).expandedTo(minimumSize());
+}
+
+TQSize TQTextTableCell::tqminimumSize() const
+{
+ int extra = 2 * (parent->innerborder + parent->cellpadding + border_tolerance);
+ return QSize(qMax(richtext->minimumWidth() + extra, minw), 0);
+}
+
+TQSize TQTextTableCell::tqmaximumSize() const
+{
+ return QSize(maxw, QWIDGETSIZE_MAX);
+}
+
+Qt::Orientations TQTextTableCell::expandingDirections() const
+{
+ return Qt::Horizontal | Qt::Vertical;
+}
+
+bool TQTextTableCell::isEmpty() const
+{
+ return false;
+}
+void TQTextTableCell::setGeometry(const TQRect& r)
+{
+ int extra = 2 * (parent->innerborder + parent->cellpadding);
+ if (r.width() != cached_width)
+ richtext->doLayout(TQTextFormat::painter(), r.width() - extra);
+ cached_width = r.width();
+ geom = r;
+}
+
+TQRect TQTextTableCell::tqgeometry() const
+{
+ return geom;
+}
+
+bool TQTextTableCell::hasHeightForWidth() const
+{
+ return true;
+}
+
+int TQTextTableCell::heightForWidth(int w) const
+{
+ int extra = 2 * (parent->innerborder + parent->cellpadding);
+ w = qMax(minw, w);
+
+ if (cached_width != w) {
+ TQTextTableCell* that = (TQTextTableCell*) this;
+ that->richtext->doLayout(TQTextFormat::painter(), w - extra);
+ that->cached_width = w;
+ }
+ return richtext->height() + extra;
+}
+
+void TQTextTableCell::adjustToPainter(TQPainter* p)
+{
+ TQTextParagraph *parag = richtext->firstParagraph();
+ while (parag) {
+ parag->adjustToPainter(p);
+ parag = parag->next();
+ }
+}
+
+int TQTextTableCell::horizontalAlignmentOffset() const
+{
+ return parent->cellpadding;
+}
+
+int TQTextTableCell::verticalAlignmentOffset() const
+{
+ if ((align & Qt::AlignVCenter) == Qt::AlignVCenter)
+ return (geom.height() - richtext->height()) / 2;
+ else if ((align & Qt::AlignBottom) == Qt::AlignBottom)
+ return geom.height() - parent->cellpadding - richtext->height() ;
+ return parent->cellpadding;
+}
+
+void TQTextTableCell::draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
+ const QPalette &pal, bool)
+{
+ if (cached_width != geom.width()) {
+ int extra = 2 * (parent->innerborder + parent->cellpadding);
+ richtext->doLayout(p, geom.width() - extra);
+ cached_width = geom.width();
+ }
+ QPalette pal2(pal);
+ if (background)
+ pal2.setBrush(QPalette::Base, *background);
+ else if (richtext->paper())
+ pal2.setBrush(QPalette::Base, *richtext->paper());
+
+ p->save();
+ p->translate(x + geom.x(), y + geom.y());
+ if (background)
+ p->fillRect(0, 0, geom.width(), geom.height(), *background);
+ else if (richtext->paper())
+ p->fillRect(0, 0, geom.width(), geom.height(), *richtext->paper());
+
+ p->translate(horizontalAlignmentOffset(), verticalAlignmentOffset());
+
+ QRegion r;
+ if (cx >= 0 && cy >= 0)
+ richtext->draw(p, cx - (x + horizontalAlignmentOffset() + geom.x()),
+ cy - (y + geom.y() + verticalAlignmentOffset()),
+ cw, ch, pal2, false, false, 0);
+ else
+ richtext->draw(p, -1, -1, -1, -1, pal2, false, false, 0);
+
+ p->restore();
+}
+#endif
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_RICHTEXT
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of the internal TQt classes dealing with rich text
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqrichtext_p.h"
+
+#ifndef TQT_NO_RICHTEXT
+
+
+#include "tqstringlist.h"
+#include "tqfont.h"
+#include "tqtextstream.h"
+#include "tqfile.h"
+#include "tqapplication.h"
+#include "tqmap.h"
+#include "tqfileinfo.h"
+#include "tqstylesheet.h"
+#include "tqmime.h"
+#include "tqimage.h"
+#include "tqdragobject.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqcursor.h"
+#include "tqptrstack.h"
+#include "tqptrdict.h"
+#include "tqstyle.h"
+#include "tqcleanuphandler.h"
+#include "tqtextengine_p.h"
+#include <private/tqunicodetables_p.h>
+
+#include <stdlib.h>
+
+static TQTextCursor* richTextExportStart = 0;
+static TQTextCursor* richTextExportEnd = 0;
+
+class TQTextFormatCollection;
+
+const int border_tolerance = 2;
+
+#ifdef TQ_WS_WIN
+#include "tqt_windows.h"
+#endif
+
+#define TQChar_linesep TQChar(0x2028U)
+
+static inline bool is_printer( TQPainter *p )
+{
+ if ( !p || !p->tqdevice() )
+ return FALSE;
+ return p->tqdevice()->devType() == TQInternal::Printer;
+}
+
+static inline int scale( int value, TQPainter *painter )
+{
+ if ( is_printer( painter ) ) {
+ TQPaintDeviceMetrics metrics( painter->tqdevice() );
+#if defined(TQ_WS_X11)
+ value = value * metrics.logicalDpiY() /
+ TQPaintDevice::x11AppDpiY( painter->tqdevice()->x11Screen() );
+#elif defined (TQ_WS_WIN)
+ HDC hdc = GetDC( 0 );
+ int gdc = GetDeviceCaps( hdc, LOGPIXELSY );
+ if ( gdc )
+ value = value * metrics.logicalDpiY() / gdc;
+ ReleaseDC( 0, hdc );
+#elif defined (TQ_WS_MAC)
+ value = value * metrics.logicalDpiY() / 75; // ##### FIXME
+#elif defined (TQ_WS_TQWS)
+ value = value * metrics.logicalDpiY() / 75;
+#endif
+ }
+ return value;
+}
+
+
+inline bool isBreakable( TQTextString *string, int pos )
+{
+ if (string->at(pos).nobreak)
+ return FALSE;
+ return (pos < string->length()-1 && string->at(pos+1).softBreak);
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+void TQTextCommandHistory::addCommand( TQTextCommand *cmd )
+{
+ if ( current < (int)history.count() - 1 ) {
+ TQPtrList<TQTextCommand> commands;
+ commands.setAutoDelete( FALSE );
+
+ for( int i = 0; i <= current; ++i ) {
+ commands.insert( i, history.at( 0 ) );
+ history.take( 0 );
+ }
+
+ commands.append( cmd );
+ history.clear();
+ history = commands;
+ history.setAutoDelete( TRUE );
+ } else {
+ history.append( cmd );
+ }
+
+ if ( (int)history.count() > steps )
+ history.removeFirst();
+ else
+ ++current;
+}
+
+TQTextCursor *TQTextCommandHistory::undo( TQTextCursor *c )
+{
+ if ( current > -1 ) {
+ TQTextCursor *c2 = history.at( current )->unexecute( c );
+ --current;
+ return c2;
+ }
+ return 0;
+}
+
+TQTextCursor *TQTextCommandHistory::redo( TQTextCursor *c )
+{
+ if ( current > -1 ) {
+ if ( current < (int)history.count() - 1 ) {
+ ++current;
+ return history.at( current )->execute( c );
+ }
+ } else {
+ if ( history.count() > 0 ) {
+ ++current;
+ return history.at( current )->execute( c );
+ }
+ }
+ return 0;
+}
+
+bool TQTextCommandHistory::isUndoAvailable()
+{
+ return current > -1;
+}
+
+bool TQTextCommandHistory::isRedoAvailable()
+{
+ return ((current > -1) && current < ((int)history.count() - 1)) || ((current == -1) && (history.count()) > 0);
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextDeleteCommand::TQTextDeleteCommand( TQTextDocument *d, int i, int idx, const TQMemArray<TQTextStringChar> &str,
+ const TQByteArray& oldStyleInfo )
+ : TQTextCommand( d ), id( i ), index( idx ), parag( 0 ), text( str ), styleInformation( oldStyleInfo )
+{
+ for ( int j = 0; j < (int)text.size(); ++j ) {
+ if ( text[ j ].format() )
+ text[ j ].format()->addRef();
+ }
+}
+
+TQTextDeleteCommand::TQTextDeleteCommand( TQTextParagraph *p, int idx, const TQMemArray<TQTextStringChar> &str )
+ : TQTextCommand( 0 ), id( -1 ), index( idx ), parag( p ), text( str )
+{
+ for ( int i = 0; i < (int)text.size(); ++i ) {
+ if ( text[ i ].format() )
+ text[ i ].format()->addRef();
+ }
+}
+
+TQTextDeleteCommand::~TQTextDeleteCommand()
+{
+ for ( int i = 0; i < (int)text.size(); ++i ) {
+ if ( text[ i ].format() )
+ text[ i ].format()->removeRef();
+ }
+ text.resize( 0 );
+}
+
+TQTextCursor *TQTextDeleteCommand::execute( TQTextCursor *c )
+{
+ TQTextParagraph *s = doc ? doc->paragAt( id ) : parag;
+ if ( !s ) {
+ qWarning( "can't locate parag at %d, last parag: %d", id, doc->lastParagraph()->paragId() );
+ return 0;
+ }
+
+ cursor.setParagraph( s );
+ cursor.setIndex( index );
+ int len = text.size();
+ if ( c )
+ *c = cursor;
+ if ( doc ) {
+ doc->setSelectionStart( TQTextDocument::Temp, cursor );
+ for ( int i = 0; i < len; ++i )
+ cursor.gotoNextLetter();
+ doc->setSelectionEnd( TQTextDocument::Temp, cursor );
+ doc->removeSelectedText( TQTextDocument::Temp, &cursor );
+ if ( c )
+ *c = cursor;
+ } else {
+ s->remove( index, len );
+ }
+
+ return c;
+}
+
+TQTextCursor *TQTextDeleteCommand::unexecute( TQTextCursor *c )
+{
+ TQTextParagraph *s = doc ? doc->paragAt( id ) : parag;
+ if ( !s ) {
+ qWarning( "can't locate parag at %d, last parag: %d", id, doc->lastParagraph()->paragId() );
+ return 0;
+ }
+
+ cursor.setParagraph( s );
+ cursor.setIndex( index );
+ TQString str = TQTextString::toString( text );
+ cursor.insert( str, TRUE, &text );
+ if ( c )
+ *c = cursor;
+ cursor.setParagraph( s );
+ cursor.setIndex( index );
+
+#ifndef TQT_NO_DATASTREAM
+ if ( !styleInformation.isEmpty() ) {
+ TQDataStream styleStream( styleInformation, IO_ReadOnly );
+ int num;
+ styleStream >> num;
+ TQTextParagraph *p = s;
+ while ( num-- && p ) {
+ p->readStyleInformation( styleStream );
+ p = p->next();
+ }
+ }
+#endif
+ s = cursor.paragraph();
+ while ( s ) {
+ s->format();
+ s->setChanged( TRUE );
+ if ( s == c->paragraph() )
+ break;
+ s = s->next();
+ }
+
+ return &cursor;
+}
+
+TQTextFormatCommand::TQTextFormatCommand( TQTextDocument *d, int sid, int sidx, int eid, int eidx,
+ const TQMemArray<TQTextStringChar> &old, TQTextFormat *f, int fl )
+ : TQTextCommand( d ), startId( sid ), startIndex( sidx ), endId( eid ), endIndex( eidx ), format( f ), oldFormats( old ), flags( fl )
+{
+ format = d->formatCollection()->format( f );
+ for ( int j = 0; j < (int)oldFormats.size(); ++j ) {
+ if ( oldFormats[ j ].format() )
+ oldFormats[ j ].format()->addRef();
+ }
+}
+
+TQTextFormatCommand::~TQTextFormatCommand()
+{
+ format->removeRef();
+ for ( int j = 0; j < (int)oldFormats.size(); ++j ) {
+ if ( oldFormats[ j ].format() )
+ oldFormats[ j ].format()->removeRef();
+ }
+}
+
+TQTextCursor *TQTextFormatCommand::execute( TQTextCursor *c )
+{
+ TQTextParagraph *sp = doc->paragAt( startId );
+ TQTextParagraph *ep = doc->paragAt( endId );
+ if ( !sp || !ep )
+ return c;
+
+ TQTextCursor start( doc );
+ start.setParagraph( sp );
+ start.setIndex( startIndex );
+ TQTextCursor end( doc );
+ end.setParagraph( ep );
+ end.setIndex( endIndex );
+
+ doc->setSelectionStart( TQTextDocument::Temp, start );
+ doc->setSelectionEnd( TQTextDocument::Temp, end );
+ doc->setFormat( TQTextDocument::Temp, format, flags );
+ doc->removeSelection( TQTextDocument::Temp );
+ if ( endIndex == ep->length() )
+ end.gotoLeft();
+ *c = end;
+ return c;
+}
+
+TQTextCursor *TQTextFormatCommand::unexecute( TQTextCursor *c )
+{
+ TQTextParagraph *sp = doc->paragAt( startId );
+ TQTextParagraph *ep = doc->paragAt( endId );
+ if ( !sp || !ep )
+ return 0;
+
+ int idx = startIndex;
+ int fIndex = 0;
+ while ( fIndex < int(oldFormats.size()) ) {
+ if ( oldFormats.at( fIndex ).c == '\n' ) {
+ if ( idx > 0 ) {
+ if ( idx < sp->length() && fIndex > 0 )
+ sp->setFormat( idx, 1, oldFormats.at( fIndex - 1 ).format() );
+ if ( sp == ep )
+ break;
+ sp = sp->next();
+ idx = 0;
+ }
+ fIndex++;
+ }
+ if ( oldFormats.at( fIndex ).format() )
+ sp->setFormat( idx, 1, oldFormats.at( fIndex ).format() );
+ idx++;
+ fIndex++;
+ if ( fIndex >= (int)oldFormats.size() )
+ break;
+ if ( idx >= sp->length() ) {
+ if ( sp == ep )
+ break;
+ sp = sp->next();
+ idx = 0;
+ }
+ }
+
+ TQTextCursor end( doc );
+ end.setParagraph( ep );
+ end.setIndex( endIndex );
+ if ( endIndex == ep->length() )
+ end.gotoLeft();
+ *c = end;
+ return c;
+}
+
+TQTextStyleCommand::TQTextStyleCommand( TQTextDocument *d, int fParag, int lParag, const TQByteArray& beforeChange )
+ : TQTextCommand( d ), firstParag( fParag ), lastParag( lParag ), before( beforeChange )
+{
+ after = readStyleInformation( d, fParag, lParag );
+}
+
+
+TQByteArray TQTextStyleCommand::readStyleInformation( TQTextDocument* doc, int fParag, int lParag )
+{
+ TQByteArray style;
+#ifndef TQT_NO_DATASTREAM
+ TQTextParagraph *p = doc->paragAt( fParag );
+ if ( !p )
+ return style;
+ TQDataStream styleStream( style, IO_WriteOnly );
+ int num = lParag - fParag + 1;
+ styleStream << num;
+ while ( num -- && p ) {
+ p->writeStyleInformation( styleStream );
+ p = p->next();
+ }
+#endif
+ return style;
+}
+
+void TQTextStyleCommand::writeStyleInformation( TQTextDocument* doc, int fParag, const TQByteArray& style )
+{
+#ifndef TQT_NO_DATASTREAM
+ TQTextParagraph *p = doc->paragAt( fParag );
+ if ( !p )
+ return;
+ TQDataStream styleStream( style, IO_ReadOnly );
+ int num;
+ styleStream >> num;
+ while ( num-- && p ) {
+ p->readStyleInformation( styleStream );
+ p = p->next();
+ }
+#endif
+}
+
+TQTextCursor *TQTextStyleCommand::execute( TQTextCursor *c )
+{
+ writeStyleInformation( doc, firstParag, after );
+ return c;
+}
+
+TQTextCursor *TQTextStyleCommand::unexecute( TQTextCursor *c )
+{
+ writeStyleInformation( doc, firstParag, before );
+ return c;
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextCursor::TQTextCursor( TQTextDocument *d )
+ : idx( 0 ), tmpX( -1 ), ox( 0 ), oy( 0 ),
+ valid( TRUE )
+{
+ para = d ? d->firstParagraph() : 0;
+}
+
+TQTextCursor::TQTextCursor( const TQTextCursor &c )
+{
+ ox = c.ox;
+ oy = c.oy;
+ idx = c.idx;
+ para = c.para;
+ tmpX = c.tmpX;
+ indices = c.indices;
+ paras = c.paras;
+ xOffsets = c.xOffsets;
+ yOffsets = c.yOffsets;
+ valid = c.valid;
+}
+
+TQTextCursor &TQTextCursor::operator=( const TQTextCursor &c )
+{
+ ox = c.ox;
+ oy = c.oy;
+ idx = c.idx;
+ para = c.para;
+ tmpX = c.tmpX;
+ indices = c.indices;
+ paras = c.paras;
+ xOffsets = c.xOffsets;
+ yOffsets = c.yOffsets;
+ valid = c.valid;
+
+ return *this;
+}
+
+bool TQTextCursor::operator==( const TQTextCursor &c ) const
+{
+ return para == c.para && idx == c.idx;
+}
+
+int TQTextCursor::totalOffsetX() const
+{
+ int xoff = ox;
+ for ( TQValueStack<int>::ConstIterator xit = xOffsets.begin(); xit != xOffsets.end(); ++xit )
+ xoff += *xit;
+ return xoff;
+}
+
+int TQTextCursor::totalOffsetY() const
+{
+ int yoff = oy;
+ for ( TQValueStack<int>::ConstIterator yit = yOffsets.begin(); yit != yOffsets.end(); ++yit )
+ yoff += *yit;
+ return yoff;
+}
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+void TQTextCursor::gotoIntoNested( const TQPoint &globalPos )
+{
+ if ( !para )
+ return;
+ TQ_ASSERT( para->at( idx )->isCustom() );
+ push();
+ ox = 0;
+ int bl, y;
+ para->lineHeightOfChar( idx, &bl, &y );
+ oy = y + para->rect().y();
+ ox = para->at( idx )->x;
+ TQTextDocument* doc = document();
+ para->at( idx )->customItem()->enterAt( this, doc, para, idx, ox, oy, globalPos-TQPoint(ox,oy) );
+}
+#endif
+
+void TQTextCursor::invalidateNested()
+{
+ if ( nestedDepth() ) {
+ TQValueStack<TQTextParagraph*>::Iterator it = paras.begin();
+ TQValueStack<int>::Iterator it2 = indices.begin();
+ for ( ; it != paras.end(); ++it, ++it2 ) {
+ if ( *it == para )
+ continue;
+ (*it)->tqinvalidate( 0 );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( (*it)->at( *it2 )->isCustom() )
+ (*it)->at( *it2 )->customItem()->tqinvalidate();
+#endif
+ }
+ }
+}
+
+void TQTextCursor::insert( const QString &str, bool checkNewLine, TQMemArray<TQTextStringChar> *formatting )
+{
+ tmpX = -1;
+ bool justInsert = TRUE;
+ TQString s( str );
+#if defined(TQ_WS_WIN)
+ if ( checkNewLine ) {
+ int i = 0;
+ while ( ( i = s.tqfind( '\r', i ) ) != -1 )
+ s.remove( i ,1 );
+ }
+#endif
+ if ( checkNewLine )
+ justInsert = s.tqfind( '\n' ) == -1;
+ if ( justInsert ) { // we ignore new lines and insert all in the current para at the current index
+ para->insert( idx, s.tqunicode(), s.length() );
+ if ( formatting ) {
+ for ( int i = 0; i < (int)s.length(); ++i ) {
+ if ( formatting->at( i ).format() ) {
+ formatting->at( i ).format()->addRef();
+ para->string()->setFormat( idx + i, formatting->at( i ).format(), TRUE );
+ }
+ }
+ }
+ idx += s.length();
+ } else { // we split at new lines
+ int start = -1;
+ int end;
+ int y = para->rect().y() + para->rect().height();
+ int lastIndex = 0;
+ do {
+ end = s.tqfind( '\n', start + 1 ); // tqfind line break
+ if ( end == -1 ) // didn't tqfind one, so end of line is end of string
+ end = s.length();
+ int len = (start == -1 ? end : end - start - 1);
+ if ( len > 0 ) // insert the line
+ para->insert( idx, s.tqunicode() + start + 1, len );
+ else
+ para->tqinvalidate( 0 );
+ if ( formatting ) { // set formats to the chars of the line
+ for ( int i = 0; i < len; ++i ) {
+ if ( formatting->at( i + lastIndex ).format() ) {
+ formatting->at( i + lastIndex ).format()->addRef();
+ para->string()->setFormat( i + idx, formatting->at( i + lastIndex ).format(), TRUE );
+ }
+ }
+ lastIndex += len;
+ }
+ start = end; // next start is at the end of this line
+ idx += len; // increase the index of the cursor to the end of the inserted text
+ if ( s[end] == '\n' ) { // if at the end was a line break, break the line
+ splitAndInsertEmptyParagraph( FALSE, TRUE );
+ para->setEndState( -1 );
+ para->prev()->format( -1, FALSE );
+ lastIndex++;
+ }
+
+ } while ( end < (int)s.length() );
+
+ para->format( -1, FALSE );
+ int dy = para->rect().y() + para->rect().height() - y;
+ TQTextParagraph *p = para;
+ p->setParagId( p->prev() ? p->prev()->paragId() + 1 : 0 );
+ p = p->next();
+ while ( p ) {
+ p->setParagId( p->prev()->paragId() + 1 );
+ p->move( dy );
+ p->tqinvalidate( 0 );
+ p->setEndState( -1 );
+ p = p->next();
+ }
+ }
+
+ int h = para->rect().height();
+ para->format( -1, TRUE );
+ if ( h != para->rect().height() )
+ invalidateNested();
+ else if ( para->document() && para->document()->tqparent() )
+ para->document()->nextDoubleBuffered = TRUE;
+
+ fixCursorPosition();
+}
+
+void TQTextCursor::gotoLeft()
+{
+ if ( para->string()->isRightToLeft() )
+ gotoNextLetter();
+ else
+ gotoPreviousLetter();
+}
+
+void TQTextCursor::gotoPreviousLetter()
+{
+ tmpX = -1;
+
+ if ( idx > 0 ) {
+ idx = para->string()->previousCursorPosition( idx );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ const TQTextStringChar *tsc = para->at( idx );
+ if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() )
+ processNesting( EnterEnd );
+#endif
+ } else if ( para->prev() ) {
+ para = para->prev();
+ while ( !para->isVisible() && para->prev() )
+ para = para->prev();
+ idx = para->length() - 1;
+ } else if ( nestedDepth() ) {
+ pop();
+ processNesting( Prev );
+ if ( idx == -1 ) {
+ pop();
+ if ( idx > 0 ) {
+ idx = para->string()->previousCursorPosition( idx );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ const TQTextStringChar *tsc = para->at( idx );
+ if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() )
+ processNesting( EnterEnd );
+#endif
+ } else if ( para->prev() ) {
+ para = para->prev();
+ idx = para->length() - 1;
+ }
+ }
+ }
+}
+
+void TQTextCursor::push()
+{
+ indices.push( idx );
+ paras.push( para );
+ xOffsets.push( ox );
+ yOffsets.push( oy );
+}
+
+void TQTextCursor::pop()
+{
+ if ( indices.isEmpty() )
+ return;
+ idx = indices.pop();
+ para = paras.pop();
+ ox = xOffsets.pop();
+ oy = yOffsets.pop();
+}
+
+void TQTextCursor::restoreState()
+{
+ while ( !indices.isEmpty() )
+ pop();
+}
+
+bool TQTextCursor::place( const TQPoint &p, TQTextParagraph *s, bool link )
+{
+ TQPoint pos( p );
+ TQRect r;
+ TQTextParagraph *str = s;
+ if ( pos.y() < s->rect().y() ) {
+ pos.setY( s->rect().y() );
+#ifdef TQ_WS_MACX
+ pos.setX( s->rect().x() );
+#endif
+ }
+ while ( s ) {
+ r = s->rect();
+ r.setWidth( document() ? document()->width() : TQWIDGETSIZE_MAX );
+ if ( s->isVisible() )
+ str = s;
+ if ( pos.y() >= r.y() && pos.y() <= r.y() + r.height() )
+ break;
+ if ( !s->next() ) {
+#ifdef TQ_WS_MACX
+ pos.setX( s->rect().x() + s->rect().width() );
+#endif
+ break;
+ }
+ s = s->next();
+ }
+
+ if ( !s || !str )
+ return FALSE;
+
+ s = str;
+
+ setParagraph( s );
+ int y = s->rect().y();
+ int lines = s->lines();
+ TQTextStringChar *chr = 0;
+ int index = 0;
+ int i = 0;
+ int cy = 0;
+ int ch = 0;
+ for ( ; i < lines; ++i ) {
+ chr = s->lineStartOfLine( i, &index );
+ cy = s->lineY( i );
+ ch = s->lineHeight( i );
+ if ( !chr )
+ return FALSE;
+ if ( pos.y() <= y + cy + ch )
+ break;
+ }
+ int nextLine;
+ if ( i < lines - 1 )
+ s->lineStartOfLine( i+1, &nextLine );
+ else
+ nextLine = s->length();
+ i = index;
+ int x = s->rect().x();
+ if ( pos.x() < x )
+ pos.setX( x + 1 );
+ int cw;
+ int curpos = s->length()-1;
+ int dist = 10000000;
+ bool inCustom = FALSE;
+ while ( i < nextLine ) {
+ chr = s->at(i);
+ int cpos = x + chr->x;
+ cw = s->string()->width( i );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( chr->isCustom() && chr->customItem()->isNested() ) {
+ if ( pos.x() >= cpos && pos.x() <= cpos + cw &&
+ pos.y() >= y + cy && pos.y() <= y + cy + chr->height() ) {
+ inCustom = TRUE;
+ curpos = i;
+ break;
+ }
+ } else
+#endif
+ {
+ if( chr->rightToLeft )
+ cpos += cw;
+ int d = cpos - pos.x();
+ bool dm = d < 0 ? !chr->rightToLeft : chr->rightToLeft;
+ if ( (TQABS( d ) < dist || (dist == d && dm == TRUE )) && para->string()->validCursorPosition( i ) ) {
+ dist = TQABS( d );
+ if ( !link || pos.x() >= x + chr->x )
+ curpos = i;
+ }
+ }
+ i++;
+ }
+ setIndex( curpos );
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( inCustom && para->document() && para->at( curpos )->isCustom() && para->at( curpos )->customItem()->isNested() ) {
+ TQTextDocument *oldDoc = para->document();
+ gotoIntoNested( pos );
+ if ( oldDoc == para->document() )
+ return TRUE;
+ TQPoint p( pos.x() - offsetX(), pos.y() - offsetY() );
+ if ( !place( p, document()->firstParagraph(), link ) )
+ pop();
+ }
+#endif
+ return TRUE;
+}
+
+bool TQTextCursor::processNesting( Operation op )
+{
+ if ( !para->document() )
+ return FALSE;
+ TQTextDocument* doc = para->document();
+ push();
+ ox = para->at( idx )->x;
+ int bl, y;
+ para->lineHeightOfChar( idx, &bl, &y );
+ oy = y + para->rect().y();
+ bool ok = FALSE;
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ switch ( op ) {
+ case EnterBegin:
+ ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy );
+ break;
+ case EnterEnd:
+ ok = para->at( idx )->customItem()->enter( this, doc, para, idx, ox, oy, TRUE );
+ break;
+ case Next:
+ ok = para->at( idx )->customItem()->next( this, doc, para, idx, ox, oy );
+ break;
+ case Prev:
+ ok = para->at( idx )->customItem()->prev( this, doc, para, idx, ox, oy );
+ break;
+ case Down:
+ ok = para->at( idx )->customItem()->down( this, doc, para, idx, ox, oy );
+ break;
+ case Up:
+ ok = para->at( idx )->customItem()->up( this, doc, para, idx, ox, oy );
+ break;
+ }
+ if ( !ok )
+#endif
+ pop();
+ return ok;
+}
+
+void TQTextCursor::gotoRight()
+{
+ if ( para->string()->isRightToLeft() )
+ gotoPreviousLetter();
+ else
+ gotoNextLetter();
+}
+
+void TQTextCursor::gotoNextLetter()
+{
+ tmpX = -1;
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ const TQTextStringChar *tsc = para->at( idx );
+ if ( tsc && tsc->isCustom() && tsc->customItem()->isNested() ) {
+ if ( processNesting( EnterBegin ) )
+ return;
+ }
+#endif
+
+ if ( idx < para->length() - 1 ) {
+ idx = para->string()->nextCursorPosition( idx );
+ } else if ( para->next() ) {
+ para = para->next();
+ while ( !para->isVisible() && para->next() )
+ para = para->next();
+ idx = 0;
+ } else if ( nestedDepth() ) {
+ pop();
+ processNesting( Next );
+ if ( idx == -1 ) {
+ pop();
+ if ( idx < para->length() - 1 ) {
+ idx = para->string()->nextCursorPosition( idx );
+ } else if ( para->next() ) {
+ para = para->next();
+ idx = 0;
+ }
+ }
+ }
+}
+
+void TQTextCursor::gotoUp()
+{
+ int indexOfLineStart;
+ int line;
+ TQTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
+ if ( !c )
+ return;
+
+ if (tmpX < 0)
+ tmpX = x();
+
+ if ( indexOfLineStart == 0 ) {
+ if ( !para->prev() ) {
+ if ( !nestedDepth() )
+ return;
+ pop();
+ processNesting( Up );
+ if ( idx == -1 ) {
+ pop();
+ if ( !para->prev() )
+ return;
+ idx = tmpX = 0;
+ } else {
+ tmpX = -1;
+ return;
+ }
+ }
+ TQTextParagraph *p = para->prev();
+ while ( p && !p->isVisible() )
+ p = p->prev();
+ if ( p )
+ para = p;
+ int lastLine = para->lines() - 1;
+ if ( !para->lineStartOfLine( lastLine, &indexOfLineStart ) )
+ return;
+ idx = indexOfLineStart;
+ while (idx < para->length()-1 && para->at(idx)->x < tmpX)
+ ++idx;
+ if (idx > indexOfLineStart &&
+ para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
+ --idx;
+ } else {
+ --line;
+ int oldIndexOfLineStart = indexOfLineStart;
+ if ( !para->lineStartOfLine( line, &indexOfLineStart ) )
+ return;
+ idx = indexOfLineStart;
+ while (idx < oldIndexOfLineStart-1 && para->at(idx)->x < tmpX)
+ ++idx;
+ if (idx > indexOfLineStart &&
+ para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
+ --idx;
+ }
+ fixCursorPosition();
+}
+
+void TQTextCursor::gotoDown()
+{
+ int indexOfLineStart;
+ int line;
+ TQTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
+ if ( !c )
+ return;
+
+ if (tmpX < 0)
+ tmpX = x();
+ if ( line == para->lines() - 1 ) {
+ if ( !para->next() ) {
+ if ( !nestedDepth() )
+ return;
+ pop();
+ processNesting( Down );
+ if ( idx == -1 ) {
+ pop();
+ if ( !para->next() )
+ return;
+ idx = tmpX = 0;
+ } else {
+ tmpX = -1;
+ return;
+ }
+ }
+ TQTextParagraph *s = para->next();
+ while ( s && !s->isVisible() )
+ s = s->next();
+ if ( s )
+ para = s;
+ if ( !para->lineStartOfLine( 0, &indexOfLineStart ) )
+ return;
+ int end;
+ if ( para->lines() == 1 )
+ end = para->length();
+ else
+ para->lineStartOfLine( 1, &end );
+
+ idx = indexOfLineStart;
+ while (idx < end-1 && para->at(idx)->x < tmpX)
+ ++idx;
+ if (idx > indexOfLineStart &&
+ para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
+ --idx;
+ } else {
+ ++line;
+ int end;
+ if ( line == para->lines() - 1 )
+ end = para->length();
+ else
+ para->lineStartOfLine( line + 1, &end );
+ if ( !para->lineStartOfLine( line, &indexOfLineStart ) )
+ return;
+ idx = indexOfLineStart;
+ while (idx < end-1 && para->at(idx)->x < tmpX)
+ ++idx;
+ if (idx > indexOfLineStart &&
+ para->at(idx)->x - tmpX > tmpX - para->at(idx-1)->x)
+ --idx;
+ }
+ fixCursorPosition();
+}
+
+void TQTextCursor::gotoLineEnd()
+{
+ tmpX = -1;
+ int indexOfLineStart;
+ int line;
+ TQTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
+ if ( !c )
+ return;
+
+ if ( line == para->lines() - 1 ) {
+ idx = para->length() - 1;
+ } else {
+ c = para->lineStartOfLine( ++line, &indexOfLineStart );
+ indexOfLineStart--;
+ idx = indexOfLineStart;
+ }
+}
+
+void TQTextCursor::gotoLineStart()
+{
+ tmpX = -1;
+ int indexOfLineStart;
+ int line;
+ TQTextStringChar *c = para->lineStartOfChar( idx, &indexOfLineStart, &line );
+ if ( !c )
+ return;
+
+ idx = indexOfLineStart;
+}
+
+void TQTextCursor::gotoHome()
+{
+ if ( topParagraph()->document() )
+ gotoPosition( topParagraph()->document()->firstParagraph() );
+ else
+ gotoLineStart();
+}
+
+void TQTextCursor::gotoEnd()
+{
+ if ( topParagraph()->document() && topParagraph()->document()->lastParagraph()->isValid() )
+ gotoPosition( topParagraph()->document()->lastParagraph(),
+ topParagraph()->document()->lastParagraph()->length() - 1);
+ else
+ gotoLineEnd();
+}
+
+void TQTextCursor::gotoPageUp( int visibleHeight )
+{
+ int targetY = globalY() - visibleHeight;
+ TQTextParagraph* old; int index;
+ do {
+ old = para; index = idx;
+ gotoUp();
+ } while ( (old != para || index != idx) && globalY() > targetY );
+}
+
+void TQTextCursor::gotoPageDown( int visibleHeight )
+{
+ int targetY = globalY() + visibleHeight;
+ TQTextParagraph* old; int index;
+ do {
+ old = para; index = idx;
+ gotoDown();
+ } while ( (old != para || index != idx) && globalY() < targetY );
+}
+
+void TQTextCursor::gotoWordRight()
+{
+ if ( para->string()->isRightToLeft() )
+ gotoPreviousWord();
+ else
+ gotoNextWord();
+}
+
+void TQTextCursor::gotoWordLeft()
+{
+ if ( para->string()->isRightToLeft() )
+ gotoNextWord();
+ else
+ gotoPreviousWord();
+}
+
+static bool is_seperator( const TQChar &c, bool onlySpace )
+{
+ if ( onlySpace )
+ return c.isSpace();
+ return c.isSpace() ||
+ c == '\t' ||
+ c == '.' ||
+ c == ',' ||
+ c == ':' ||
+ c == ';' ||
+ c == '-' ||
+ c == '<' ||
+ c == '>' ||
+ c == '[' ||
+ c == ']' ||
+ c == '(' ||
+ c == ')' ||
+ c == '{' ||
+ c == '}';
+}
+
+void TQTextCursor::gotoPreviousWord( bool onlySpace )
+{
+ gotoPreviousLetter();
+ tmpX = -1;
+ TQTextString *s = para->string();
+ bool allowSame = FALSE;
+ if ( idx == ((int)s->length()-1) )
+ return;
+ for ( int i = idx; i >= 0; --i ) {
+ if ( is_seperator( s->at( i ).c, onlySpace ) ) {
+ if ( !allowSame )
+ continue;
+ idx = i + 1;
+ return;
+ }
+ if ( !allowSame && !is_seperator( s->at( i ).c, onlySpace ) )
+ allowSame = TRUE;
+ }
+ idx = 0;
+}
+
+void TQTextCursor::gotoNextWord( bool onlySpace )
+{
+ tmpX = -1;
+ TQTextString *s = para->string();
+ bool allowSame = FALSE;
+ for ( int i = idx; i < (int)s->length(); ++i ) {
+ if ( !is_seperator( s->at( i ).c, onlySpace ) ) {
+ if ( !allowSame )
+ continue;
+ idx = i;
+ return;
+ }
+ if ( !allowSame && is_seperator( s->at( i ).c, onlySpace ) )
+ allowSame = TRUE;
+
+ }
+
+ if ( idx < ((int)s->length()-1) ) {
+ gotoLineEnd();
+ } else if ( para->next() ) {
+ TQTextParagraph *p = para->next();
+ while ( p && !p->isVisible() )
+ p = p->next();
+ if ( s ) {
+ para = p;
+ idx = 0;
+ }
+ } else {
+ gotoLineEnd();
+ }
+}
+
+bool TQTextCursor::atParagStart()
+{
+ return idx == 0;
+}
+
+bool TQTextCursor::atParagEnd()
+{
+ return idx == para->length() - 1;
+}
+
+void TQTextCursor::splitAndInsertEmptyParagraph( bool ind, bool updateIds )
+{
+ if ( !para->document() )
+ return;
+ tmpX = -1;
+ TQTextFormat *f = 0;
+ if ( para->document()->useFormatCollection() ) {
+ f = para->at( idx )->format();
+ if ( idx == para->length() - 1 && idx > 0 )
+ f = para->at( idx - 1 )->format();
+ if ( f->isMisspelled() ) {
+ f->removeRef();
+ f = para->document()->formatCollection()->format( f->font(), f->color() );
+ }
+ }
+
+ if ( atParagEnd() ) {
+ TQTextParagraph *n = para->next();
+ TQTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds );
+ if ( f )
+ s->setFormat( 0, 1, f, TRUE );
+ s->copyParagData( para );
+ if ( ind ) {
+ int oi, ni;
+ s->indent( &oi, &ni );
+ para = s;
+ idx = ni;
+ } else {
+ para = s;
+ idx = 0;
+ }
+ } else if ( atParagStart() ) {
+ TQTextParagraph *p = para->prev();
+ TQTextParagraph *s = para->document()->createParagraph( para->document(), p, para, updateIds );
+ if ( f )
+ s->setFormat( 0, 1, f, TRUE );
+ s->copyParagData( para );
+ if ( ind ) {
+ s->indent();
+ s->format();
+ indent();
+ para->format();
+ }
+ } else {
+ TQString str = para->string()->toString().mid( idx, 0xFFFFFF );
+ TQTextParagraph *n = para->next();
+ TQTextParagraph *s = para->document()->createParagraph( para->document(), para, n, updateIds );
+ s->copyParagData( para );
+ s->remove( 0, 1 );
+ s->append( str, TRUE );
+ for ( int i = 0; i < str.length(); ++i ) {
+ TQTextStringChar* tsc = para->at( idx + i );
+ s->setFormat( i, 1, tsc->format(), TRUE );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( tsc->isCustom() ) {
+ TQTextCustomItem * item = tsc->customItem();
+ s->at( i )->setCustomItem( item );
+ tsc->loseCustomItem();
+ }
+#endif
+ if ( tsc->isAnchor() )
+ s->at( i )->setAnchor( tsc->anchorName(),
+ tsc->anchorHref() );
+ }
+ para->truncate( idx );
+ if ( ind ) {
+ int oi, ni;
+ s->indent( &oi, &ni );
+ para = s;
+ idx = ni;
+ } else {
+ para = s;
+ idx = 0;
+ }
+ }
+
+ invalidateNested();
+}
+
+bool TQTextCursor::remove()
+{
+ tmpX = -1;
+ if ( !atParagEnd() ) {
+ int next = para->string()->nextCursorPosition( idx );
+ para->remove( idx, next-idx );
+ int h = para->rect().height();
+ para->format( -1, TRUE );
+ if ( h != para->rect().height() )
+ invalidateNested();
+ else if ( para->document() && para->document()->tqparent() )
+ para->document()->nextDoubleBuffered = TRUE;
+ return FALSE;
+ } else if ( para->next() ) {
+ para->join( para->next() );
+ invalidateNested();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* needed to implement backspace the correct way */
+bool TQTextCursor::removePreviousChar()
+{
+ tmpX = -1;
+ if ( !atParagStart() ) {
+ para->remove( idx-1, 1 );
+ int h = para->rect().height();
+ idx--;
+ // shouldn't be needed, just to make sure.
+ fixCursorPosition();
+ para->format( -1, TRUE );
+ if ( h != para->rect().height() )
+ invalidateNested();
+ else if ( para->document() && para->document()->tqparent() )
+ para->document()->nextDoubleBuffered = TRUE;
+ return FALSE;
+ } else if ( para->prev() ) {
+ para = para->prev();
+ para->join( para->next() );
+ invalidateNested();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void TQTextCursor::indent()
+{
+ int oi = 0, ni = 0;
+ para->indent( &oi, &ni );
+ if ( oi == ni )
+ return;
+
+ if ( idx >= oi )
+ idx += ni - oi;
+ else
+ idx = ni;
+}
+
+void TQTextCursor::fixCursorPosition()
+{
+ // searches for the closest valid cursor position
+ if ( para->string()->validCursorPosition( idx ) )
+ return;
+
+ int lineIdx;
+ TQTextStringChar *start = para->lineStartOfChar( idx, &lineIdx, 0 );
+ int x = para->string()->at( idx ).x;
+ int diff = TQABS(start->x - x);
+ int best = lineIdx;
+
+ TQTextStringChar *c = start;
+ ++c;
+
+ TQTextStringChar *end = &para->string()->at( para->length()-1 );
+ while ( c <= end && !c->lineStart ) {
+ int xp = c->x;
+ if ( c->rightToLeft )
+ xp += para->string()->width( lineIdx + (c-start) );
+ int ndiff = TQABS(xp - x);
+ if ( ndiff < diff && para->string()->validCursorPosition(lineIdx + (c-start)) ) {
+ diff = ndiff;
+ best = lineIdx + (c-start);
+ }
+ ++c;
+ }
+ idx = best;
+}
+
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextDocument::TQTextDocument( TQTextDocument *p )
+ : par( p ), parentPar( 0 )
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ , tc( 0 )
+#endif
+ , tArray( 0 ), tStopWidth( 0 )
+{
+ fCollection = par ? par->fCollection : new TQTextFormatCollection;
+ init();
+}
+
+void TQTextDocument::init()
+{
+ oTextValid = TRUE;
+ mightHaveCustomItems = FALSE;
+ if ( par )
+ par->insertChild( this );
+ pProcessor = 0;
+ useFC = TRUE;
+ pFormatter = 0;
+ indenter = 0;
+ fParag = 0;
+ txtFormat = TQt::AutoText;
+ preferRichText = FALSE;
+ pages = FALSE;
+ focusIndicator.parag = 0;
+ minw = 0;
+ wused = 0;
+ minwParag = curParag = 0;
+ align = TQt::AlignAuto;
+ nSelections = 1;
+
+ setStyleSheet( TQStyleSheet::defaultSheet() );
+#ifndef TQT_NO_MIME
+ factory_ = TQMimeSourceFactory::defaultFactory();
+#endif
+ contxt = TQString::null;
+
+ underlLinks = par ? par->underlLinks : TRUE;
+ backBrush = 0;
+ buf_pixmap = 0;
+ nextDoubleBuffered = FALSE;
+
+ if ( par )
+ withoutDoubleBuffer = par->withoutDoubleBuffer;
+ else
+ withoutDoubleBuffer = FALSE;
+
+ lParag = fParag = createParagraph( this, 0, 0 );
+
+ cx = 0;
+ cy = 2;
+ if ( par )
+ cx = cy = 0;
+ cw = 600;
+ vw = 0;
+ flow_ = new TQTextFlow;
+ flow_->setWidth( cw );
+
+ leftmargin = rightmargin = 4;
+ scaleFontsFactor = 1;
+
+
+ selectionColors[ Standard ] = TQApplication::palette().color( TQPalette::Active, TQColorGroup::Highlight );
+ selectionText[ Standard ] = TRUE;
+ selectionText[ IMSelectionText ] = TRUE;
+ selectionText[ IMCompositionText ] = FALSE;
+ commandHistory = new TQTextCommandHistory( 100 );
+ tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8;
+}
+
+TQTextDocument::~TQTextDocument()
+{
+ delete commandHistory;
+ if ( par )
+ par->removeChild( this );
+ clear();
+ delete flow_;
+ if ( !par ) {
+ delete pFormatter;
+ delete fCollection;
+ }
+ delete pProcessor;
+ delete buf_pixmap;
+ delete indenter;
+ delete backBrush;
+ delete [] tArray;
+}
+
+void TQTextDocument::clear( bool createEmptyParag )
+{
+ while ( fParag ) {
+ TQTextParagraph *p = fParag->next();
+ delete fParag;
+ fParag = p;
+ }
+ if ( flow_ )
+ flow_->clear();
+ fParag = lParag = 0;
+ if ( createEmptyParag )
+ fParag = lParag = createParagraph( this );
+ focusIndicator.parag = 0;
+ selections.clear();
+ oText = TQString::null;
+ oTextValid = FALSE;
+}
+
+int TQTextDocument::widthUsed() const
+{
+ return wused + 2*border_tolerance;
+}
+
+int TQTextDocument::height() const
+{
+ int h = 0;
+ if ( lParag )
+ h = lParag->rect().top() + lParag->rect().height() + 1;
+ int fh = flow_->boundingRect().bottom();
+ return TQMAX( h, fh );
+}
+
+
+
+TQTextParagraph *TQTextDocument::createParagraph( TQTextDocument *d, TQTextParagraph *pr, TQTextParagraph *nx, bool updateIds )
+{
+ return new TQTextParagraph( d, pr, nx, updateIds );
+}
+
+bool TQTextDocument::setMinimumWidth( int needed, int used, TQTextParagraph *p )
+{
+ if ( needed == -1 ) {
+ minw = 0;
+ wused = 0;
+ p = 0;
+ }
+ if ( p == minwParag ) {
+ if (minw > needed) {
+ TQTextParagraph *tp = fParag;
+ while (tp) {
+ if (tp != p && tp->minwidth > needed) {
+ needed = tp->minwidth;
+ minwParag = tp;
+ }
+ tp = tp->n;
+ }
+ }
+ minw = needed;
+ emit minimumWidthChanged( minw );
+ } else if ( needed > minw ) {
+ minw = needed;
+ minwParag = p;
+ emit minimumWidthChanged( minw );
+ }
+ wused = TQMAX( wused, used );
+ wused = TQMAX( wused, minw );
+ cw = TQMAX( minw, cw );
+ return TRUE;
+}
+
+void TQTextDocument::setPlainText( const TQString &text )
+{
+ preferRichText = FALSE;
+ clear();
+ oTextValid = TRUE;
+ oText = text;
+
+ int lastNl = 0;
+ int nl = text.tqfind( '\n' );
+ if ( nl == -1 ) {
+ lParag = createParagraph( this, lParag, 0 );
+ if ( !fParag )
+ fParag = lParag;
+ TQString s = text;
+ if ( !s.isEmpty() ) {
+ if ( s[ (int)s.length() - 1 ] == '\r' )
+ s.remove( s.length() - 1, 1 );
+ lParag->append( s );
+ }
+ } else {
+ for (;;) {
+ lParag = createParagraph( this, lParag, 0 );
+ if ( !fParag )
+ fParag = lParag;
+ int l = nl - lastNl;
+ if ( l > 0 ) {
+ if (text.tqunicode()[nl-1] == '\r')
+ l--;
+ TQConstString cs(text.tqunicode()+lastNl, l);
+ lParag->append( cs.string() );
+ }
+ if ( nl == (int)text.length() )
+ break;
+ lastNl = nl + 1;
+ nl = text.tqfind( '\n', nl + 1 );
+ if ( nl == -1 )
+ nl = text.length();
+ }
+ }
+ if ( !lParag )
+ lParag = fParag = createParagraph( this, 0, 0 );
+}
+
+struct TQ_EXPORT TQTextDocumentTag {
+ TQTextDocumentTag(){}
+ TQTextDocumentTag( const TQString&n, const TQStyleSheetItem* s, const TQTextFormat& f )
+ :name(n),style(s), format(f), tqalignment(TQt::AlignAuto), direction(TQChar::DirON),liststyle(TQStyleSheetItem::ListDisc) {
+ wsm = TQStyleSheetItem::WhiteSpaceNormal;
+ }
+ TQString name;
+ const TQStyleSheetItem* style;
+ TQString anchorHref;
+ TQStyleSheetItem::WhiteSpaceMode wsm;
+ TQTextFormat format;
+ int tqalignment : 16;
+ int direction : 5;
+ TQStyleSheetItem::ListStyle liststyle;
+
+ TQTextDocumentTag( const TQTextDocumentTag& t ) {
+ name = t.name;
+ style = t.style;
+ anchorHref = t.anchorHref;
+ wsm = t.wsm;
+ format = t.format;
+ tqalignment = t.tqalignment;
+ direction = t.direction;
+ liststyle = t.liststyle;
+ }
+ TQTextDocumentTag& operator=(const TQTextDocumentTag& t) {
+ name = t.name;
+ style = t.style;
+ anchorHref = t.anchorHref;
+ wsm = t.wsm;
+ format = t.format;
+ tqalignment = t.tqalignment;
+ direction = t.direction;
+ liststyle = t.liststyle;
+ return *this;
+ }
+
+ TQ_DUMMY_COMPARISON_OPERATOR(TQTextDocumentTag)
+};
+
+
+#define NEWPAR do{ if ( !hasNewPar) { \
+ if ( !textEditMode && curpar && curpar->length()>1 && curpar->at( curpar->length()-2)->c == TQChar_linesep ) \
+ curpar->remove( curpar->length()-2, 1 ); \
+ curpar = createParagraph( this, curpar, curpar->next() ); styles.append( vec ); vec = 0;} \
+ hasNewPar = TRUE; \
+ curpar->rtext = TRUE; \
+ curpar->align = curtag.tqalignment; \
+ curpar->lstyle = curtag.liststyle; \
+ curpar->litem = ( curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem ); \
+ curpar->str->setDirection( (TQChar::Direction)curtag.direction ); \
+ space = TRUE; \
+ tabExpansionColumn = 0; \
+ delete vec; vec = new TQPtrVector<TQStyleSheetItem>( (uint)tags.count() + 1); \
+ int i = 0; \
+ for ( TQValueStack<TQTextDocumentTag>::Iterator it = tags.begin(); it != tags.end(); ++it ) \
+ vec->insert( i++, (*it).style ); \
+ vec->insert( i, curtag.style ); \
+ }while(FALSE);
+
+
+void TQTextDocument::setRichText( const TQString &text, const TQString &context, const TQTextFormat *initialFormat )
+{
+ preferRichText = TRUE;
+ if ( !context.isEmpty() )
+ setContext( context );
+ clear();
+ fParag = lParag = createParagraph( this );
+ oTextValid = TRUE;
+ oText = text;
+ setRichTextInternal( text, 0, initialFormat );
+ fParag->rtext = TRUE;
+}
+
+void TQTextDocument::setRichTextInternal( const TQString &text, TQTextCursor* cursor, const TQTextFormat *initialFormat )
+{
+ TQTextParagraph* curpar = lParag;
+ int pos = 0;
+ TQValueStack<TQTextDocumentTag> tags;
+ if ( !initialFormat )
+ initialFormat = formatCollection()->defaultFormat();
+ TQTextDocumentTag initag( "", sheet_->item(""), *initialFormat );
+ if ( bodyText.isValid() )
+ initag.format.setColor( bodyText );
+ TQTextDocumentTag curtag = initag;
+ bool space = TRUE;
+ bool canMergeLi = FALSE;
+
+ bool textEditMode = FALSE;
+ int tabExpansionColumn = 0;
+
+ const TQChar* doc = text.tqunicode();
+ int length = text.length();
+ bool hasNewPar = curpar->length() <= 1;
+ TQString anchorName;
+
+ // style sheet handling for margin and line spacing calculation below
+ TQTextParagraph* stylesPar = curpar;
+ TQPtrVector<TQStyleSheetItem>* vec = 0;
+ TQPtrList< TQPtrVector<TQStyleSheetItem> > styles;
+ styles.setAutoDelete( TRUE );
+
+ if ( cursor ) {
+ cursor->splitAndInsertEmptyParagraph();
+ TQTextCursor tmp = *cursor;
+ tmp.gotoPreviousLetter();
+ stylesPar = curpar = tmp.paragraph();
+ hasNewPar = TRUE;
+ textEditMode = TRUE;
+ } else {
+ NEWPAR;
+ }
+
+ // set rtext spacing to FALSE for the initial paragraph.
+ curpar->rtext = FALSE;
+
+ TQString wellKnownTags = "br hr wsp table qt body meta title";
+
+ while ( pos < length ) {
+ if ( hasPrefix(doc, length, pos, '<' ) ){
+ if ( !hasPrefix( doc, length, pos+1, TQChar('/') ) ) {
+ // open tag
+ QMap<TQString, TQString> attr;
+ bool emptyTag = FALSE;
+ TQString tagname = parseOpenTag(doc, length, pos, attr, emptyTag);
+ if ( tagname.isEmpty() )
+ continue; // nothing we could do with this, probably parse error
+
+ const TQStyleSheetItem* nstyle = sheet_->item(tagname);
+
+ if ( nstyle ) {
+ // we might have to close some 'forgotten' tags
+ while ( !nstyle->allowedInContext( curtag.style ) ) {
+ TQString msg;
+ msg.sprintf( "TQText Warning: Document not valid ( '%s' not allowed in '%s' #%d)",
+ tagname.ascii(), curtag.style->name().ascii(), pos);
+ sheet_->error( msg );
+ if ( tags.isEmpty() )
+ break;
+ curtag = tags.pop();
+ }
+
+ /* special handling for p and li for HTML
+ compatibility. We do not want to embed blocks in
+ p, and we do not want new blocks inside non-empty
+ lis. Plus we want to merge empty lis sometimes. */
+ if( nstyle->displayMode() == TQStyleSheetItem::DisplayListItem ) {
+ canMergeLi = TRUE;
+ } else if ( nstyle->displayMode() == TQStyleSheetItem::DisplayBlock ) {
+ while ( curtag.style->name() == "p" ) {
+ if ( tags.isEmpty() )
+ break;
+ curtag = tags.pop();
+ }
+
+ if ( curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem ) {
+ // we are in a li and a new block comes along
+ if ( nstyle->name() == "ul" || nstyle->name() == "ol" )
+ hasNewPar = FALSE; // we want an empty li (like most browsers)
+ if ( !hasNewPar ) {
+ /* do not add new blocks inside
+ non-empty lis */
+ while ( curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem ) {
+ if ( tags.isEmpty() )
+ break;
+ curtag = tags.pop();
+ }
+ } else if ( canMergeLi ) {
+ /* we have an empty li and a block
+ comes along, merge them */
+ nstyle = curtag.style;
+ }
+ canMergeLi = FALSE;
+ }
+ }
+ }
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem* custom = 0;
+#else
+ bool custom = FALSE;
+#endif
+
+ // some well-known tags, some have a nstyle, some not
+ if ( wellKnownTags.tqfind( tagname ) != -1 ) {
+ if ( tagname == "br" ) {
+ emptyTag = space = TRUE;
+ int index = TQMAX( curpar->length(),1) - 1;
+ TQTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
+ curpar->append( TQChar_linesep );
+ curpar->setFormat( index, 1, &format );
+ hasNewPar = false;
+ } else if ( tagname == "hr" ) {
+ emptyTag = space = TRUE;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this );
+#endif
+ } else if ( tagname == "table" ) {
+ emptyTag = space = TRUE;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
+ curpar->tqsetAlignment( curtag.tqalignment );
+ custom = parseTable( attr, format, doc, length, pos, curpar );
+#endif
+ } else if ( tagname == "qt" || tagname == "body" ) {
+ if ( attr.tqcontains( "bgcolor" ) ) {
+ TQBrush *b = new TQBrush( TQColor( attr["bgcolor"] ) );
+ setPaper( b );
+ }
+ if ( attr.tqcontains( "background" ) ) {
+#ifndef TQT_NO_MIME
+ TQImage img;
+ TQString bg = attr["background"];
+ const TQMimeSource* m = factory_->data( bg, contxt );
+ if ( !m ) {
+ qWarning("TQRichText: no mimesource for %s", bg.latin1() );
+ } else {
+ if ( !TQImageDrag::decode( m, img ) ) {
+ qWarning("TQTextImage: cannot decode %s", bg.latin1() );
+ }
+ }
+ if ( !img.isNull() ) {
+ TQBrush *b = new TQBrush( TQColor(), TQPixmap( img ) );
+ setPaper( b );
+ }
+#endif
+ }
+ if ( attr.tqcontains( "text" ) ) {
+ TQColor c( attr["text"] );
+ initag.format.setColor( c );
+ curtag.format.setColor( c );
+ bodyText = c;
+ }
+ if ( attr.tqcontains( "link" ) )
+ linkColor = TQColor( attr["link"] );
+ if ( attr.tqcontains( "title" ) )
+ attribs.tqreplace( "title", attr["title"] );
+
+ if ( textEditMode ) {
+ if ( attr.tqcontains("style" ) ) {
+ TQString a = attr["style"];
+ for ( int s = 0; s < a.tqcontains(';')+1; s++ ) {
+ TQString style = a.section( ';', s, s );
+ if ( style.startsWith("font-size:" ) && style.endsWith("pt") ) {
+ scaleFontsFactor = double( formatCollection()->defaultFormat()->fn.pointSize() ) /
+ style.mid( 10, style.length() - 12 ).toInt();
+ }
+ }
+ }
+ nstyle = 0; // ignore body in textEditMode
+ }
+ // end qt- and body-tag handling
+ } else if ( tagname == "meta" ) {
+ if ( attr["name"] == "qrichtext" && attr["content"] == "1" )
+ textEditMode = TRUE;
+ } else if ( tagname == "title" ) {
+ TQString title;
+ while ( pos < length ) {
+ if ( hasPrefix( doc, length, pos, TQChar('<') ) && hasPrefix( doc, length, pos+1, TQChar('/') ) &&
+ parseCloseTag( doc, length, pos ) == "title" )
+ break;
+ title += doc[ pos ];
+ ++pos;
+ }
+ attribs.tqreplace( "title", title );
+ }
+ } // end of well-known tag handling
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( !custom ) // try generic custom item
+ custom = sheet_->tag( tagname, attr, contxt, *factory_ , emptyTag, this );
+#endif
+ if ( !nstyle && !custom ) // we have no clue what this tag could be, ignore it
+ continue;
+
+ if ( custom ) {
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ int index = TQMAX( curpar->length(),1) - 1;
+ TQTextFormat format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
+ curpar->append( TQChar('*') );
+ TQTextFormat* f = formatCollection()->format( &format );
+ curpar->setFormat( index, 1, f );
+ curpar->at( index )->setCustomItem( custom );
+ if ( !curtag.anchorHref.isEmpty() )
+ curpar->at(index)->setAnchor( TQString::null, curtag.anchorHref );
+ if ( !anchorName.isEmpty() ) {
+ curpar->at(index)->setAnchor( anchorName, curpar->at(index)->anchorHref() );
+ anchorName = TQString::null;
+ }
+ registerCustomItem( custom, curpar );
+ hasNewPar = FALSE;
+#endif
+ } else if ( !emptyTag ) {
+ /* if we do nesting, push curtag on the stack,
+ otherwise reinint curag. */
+ if ( curtag.style->name() != tagname || nstyle->selfNesting() ) {
+ tags.push( curtag );
+ } else {
+ if ( !tags.isEmpty() )
+ curtag = tags.top();
+ else
+ curtag = initag;
+ }
+
+ curtag.name = tagname;
+ curtag.style = nstyle;
+ curtag.name = tagname;
+ curtag.style = nstyle;
+ if ( nstyle->whiteSpaceMode() != TQStyleSheetItem::WhiteSpaceModeUndefined )
+ curtag.wsm = nstyle->whiteSpaceMode();
+
+ /* netscape compatibility: eat a newline and only a newline if a pre block starts */
+ if ( curtag.wsm == TQStyleSheetItem::WhiteSpacePre &&
+ nstyle->displayMode() == TQStyleSheetItem::DisplayBlock )
+ eat( doc, length, pos, '\n' );
+
+ /* ignore whitespace for inline elements if there
+ was already one*/
+ if ( !textEditMode &&
+ (curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal
+ || curtag.wsm == TQStyleSheetItem::WhiteSpaceNoWrap)
+ && ( space || nstyle->displayMode() != TQStyleSheetItem::DisplayInline ) )
+ eatSpace( doc, length, pos );
+
+ curtag.format = curtag.format.makeTextFormat( nstyle, attr, scaleFontsFactor );
+ if ( nstyle->isAnchor() ) {
+ if ( !anchorName.isEmpty() )
+ anchorName += "#" + attr["name"];
+ else
+ anchorName = attr["name"];
+ curtag.anchorHref = attr["href"];
+ }
+
+ if ( nstyle->tqalignment() != TQStyleSheetItem::Undefined )
+ curtag.tqalignment = nstyle->tqalignment();
+
+ if ( nstyle->listStyle() != TQStyleSheetItem::ListStyleUndefined )
+ curtag.liststyle = nstyle->listStyle();
+
+ if ( nstyle->displayMode() == TQStyleSheetItem::DisplayBlock
+ || nstyle->displayMode() == TQStyleSheetItem::DisplayListItem ) {
+
+ if ( nstyle->name() == "ol" || nstyle->name() == "ul" || nstyle->name() == "li") {
+ TQString type = attr["type"];
+ if ( !type.isEmpty() ) {
+ if ( type == "1" ) {
+ curtag.liststyle = TQStyleSheetItem::ListDecimal;
+ } else if ( type == "a" ) {
+ curtag.liststyle = TQStyleSheetItem::ListLowerAlpha;
+ } else if ( type == "A" ) {
+ curtag.liststyle = TQStyleSheetItem::ListUpperAlpha;
+ } else {
+ type = type.lower();
+ if ( type == "square" )
+ curtag.liststyle = TQStyleSheetItem::ListSquare;
+ else if ( type == "disc" )
+ curtag.liststyle = TQStyleSheetItem::ListDisc;
+ else if ( type == "circle" )
+ curtag.liststyle = TQStyleSheetItem::ListCircle;
+ }
+ }
+ }
+
+
+ /* Internally we treat ordered and bullet
+ lists the same for margin calculations. In
+ order to have fast pointer compares in the
+ xMargin() functions we restrict ourselves to
+ <ol>. Once we calculate the margins in the
+ parser rathern than later, the unelegance of
+ this approach goes awy
+ */
+ if ( nstyle->name() == "ul" )
+ curtag.style = sheet_->item( "ol" );
+
+ if ( attr.tqcontains( "align" ) ) {
+ TQString align = attr["align"].lower();
+ if ( align == "center" )
+ curtag.tqalignment = TQt::AlignCenter;
+ else if ( align == "right" )
+ curtag.tqalignment = TQt::AlignRight;
+ else if ( align == "justify" )
+ curtag.tqalignment = TQt::AlignJustify;
+ }
+ if ( attr.tqcontains( "dir" ) ) {
+ TQString dir = attr["dir"];
+ if ( dir == "rtl" )
+ curtag.direction = TQChar::DirR;
+ else if ( dir == "ltr" )
+ curtag.direction = TQChar::DirL;
+ }
+
+ NEWPAR;
+
+ if ( curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem ) {
+ if ( attr.tqcontains( "value " ) )
+ curpar->setListValue( attr["value"].toInt() );
+ }
+
+ if ( attr.tqcontains( "style" ) ) {
+ TQString a = attr["style"];
+ bool ok = TRUE;
+ for ( int s = 0; ok && s < a.tqcontains(';')+1; s++ ) {
+ TQString style = a.section( ';', s, s );
+ if ( style.startsWith("margin-top:" ) && style.endsWith("px") )
+ curpar->utm = 1+style.mid(11, style.length() - 13).toInt(&ok);
+ else if ( style.startsWith("margin-bottom:" ) && style.endsWith("px") )
+ curpar->ubm = 1+style.mid(14, style.length() - 16).toInt(&ok);
+ else if ( style.startsWith("margin-left:" ) && style.endsWith("px") )
+ curpar->ulm = 1+style.mid(12, style.length() - 14).toInt(&ok);
+ else if ( style.startsWith("margin-right:" ) && style.endsWith("px") )
+ curpar->urm = 1+style.mid(13, style.length() - 15).toInt(&ok);
+ else if ( style.startsWith("text-indent:" ) && style.endsWith("px") )
+ curpar->uflm = 1+style.mid(12, style.length() - 14).toInt(&ok);
+ }
+ if ( !ok ) // be pressmistic
+ curpar->utm = curpar->ubm = curpar->urm = curpar->ulm = 0;
+ }
+ }
+ }
+ } else {
+ TQString tagname = parseCloseTag( doc, length, pos );
+ if ( tagname.isEmpty() )
+ continue; // nothing we could do with this, probably parse error
+ if ( !sheet_->item( tagname ) ) // ignore unknown tags
+ continue;
+ if ( tagname == "li" )
+ continue;
+
+ // we close a block item. Since the text may continue, we need to have a new paragraph
+ bool needNewPar = curtag.style->displayMode() == TQStyleSheetItem::DisplayBlock
+ || curtag.style->displayMode() == TQStyleSheetItem::DisplayListItem;
+
+
+ // html slopiness: handle unbalanched tag closing
+ while ( curtag.name != tagname ) {
+ TQString msg;
+ msg.sprintf( "TQText Warning: Document not valid ( '%s' not closed before '%s' #%d)",
+ curtag.name.ascii(), tagname.ascii(), pos);
+ sheet_->error( msg );
+ if ( tags.isEmpty() )
+ break;
+ curtag = tags.pop();
+ }
+
+
+ // close the tag
+ if ( !tags.isEmpty() )
+ curtag = tags.pop();
+ else
+ curtag = initag;
+
+ if ( needNewPar ) {
+ if ( textEditMode && (tagname == "p" || tagname == "div" ) ) // preserve empty paragraphs
+ hasNewPar = FALSE;
+ NEWPAR;
+ }
+ }
+ } else {
+ // normal contents
+ TQString s;
+ TQChar c;
+ while ( pos < length && !hasPrefix(doc, length, pos, TQChar('<') ) ){
+ if ( textEditMode ) {
+ // text edit mode: we handle all white space but ignore newlines
+ c = parseChar( doc, length, pos, TQStyleSheetItem::WhiteSpacePre );
+ if ( c == TQChar_linesep )
+ break;
+ } else {
+ int l = pos;
+ c = parseChar( doc, length, pos, curtag.wsm );
+
+ // in white space pre mode: treat any space as non breakable
+ // and expand tabs to eight character wide columns.
+ if ( curtag.wsm == TQStyleSheetItem::WhiteSpacePre ) {
+ if ( c == '\t' ) {
+ c = ' ';
+ while( (++tabExpansionColumn)%8 )
+ s += c;
+ }
+ if ( c == TQChar_linesep )
+ tabExpansionColumn = 0;
+ else
+ tabExpansionColumn++;
+
+ }
+ if ( c == ' ' || c == TQChar_linesep ) {
+ /* avoid overlong paragraphs by forcing a new
+ paragraph after 4096 characters. This case can
+ occur when loading undiscovered plain text
+ documents in rich text mode. Instead of hanging
+ forever, we do the trick.
+ */
+ if ( curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal && s.length() > 4096 ) do {
+ if ( doc[l] == '\n' ) {
+ hasNewPar = FALSE; // for a new paragraph ...
+ NEWPAR;
+ hasNewPar = FALSE; // ... and make it non-reusable
+ c = '\n'; // make sure we break below
+ break;
+ }
+ } while ( ++l < pos );
+ }
+ }
+
+ if ( c == '\n' )
+ break; // break on newlines, pre delievers a TQChar_linesep
+
+ bool c_isSpace = c.isSpace() && c.tqunicode() != 0x00a0U && !textEditMode;
+
+ if ( curtag.wsm == TQStyleSheetItem::WhiteSpaceNormal && c_isSpace && space )
+ continue;
+ if ( c == '\r' )
+ continue;
+ space = c_isSpace;
+ s += c;
+ }
+ if ( !s.isEmpty() && curtag.style->displayMode() != TQStyleSheetItem::DisplayNone ) {
+ hasNewPar = FALSE;
+ int index = TQMAX( curpar->length(),1) - 1;
+ curpar->append( s );
+ if (curtag.wsm != TQStyleSheetItem::WhiteSpaceNormal) {
+ TQTextString *str = curpar->string();
+ for (int i = index; i < index + s.length(); ++i)
+ str->at(i).nobreak = TRUE;
+ }
+
+ TQTextFormat* f = formatCollection()->format( &curtag.format );
+ curpar->setFormat( index, s.length(), f, FALSE ); // do not use collection because we have done that already
+ f->ref += s.length() -1; // that what friends are for...
+ if ( !curtag.anchorHref.isEmpty() ) {
+ for ( int i = 0; i < int(s.length()); i++ )
+ curpar->at(index + i)->setAnchor( TQString::null, curtag.anchorHref );
+ }
+ if ( !anchorName.isEmpty() ) {
+ for ( int i = 0; i < int(s.length()); i++ )
+ curpar->at(index + i)->setAnchor( anchorName, curpar->at(index + i)->anchorHref() );
+ anchorName = TQString::null;
+ }
+ }
+ }
+ }
+
+ if ( hasNewPar && curpar != fParag && !cursor && stylesPar != curpar ) {
+ // cleanup unused last paragraphs
+ curpar = curpar->p;
+ delete curpar->n;
+ }
+
+ if ( !anchorName.isEmpty() ) {
+ curpar->at(curpar->length() - 1)->setAnchor( anchorName, curpar->at( curpar->length() - 1 )->anchorHref() );
+ anchorName = TQString::null;
+ }
+
+
+ setRichTextMarginsInternal( styles, stylesPar );
+
+ if ( cursor ) {
+ cursor->gotoPreviousLetter();
+ cursor->remove();
+ }
+ delete vec;
+}
+
+void TQTextDocument::setRichTextMarginsInternal( TQPtrList< TQPtrVector<TQStyleSheetItem> >& styles, TQTextParagraph* stylesPar )
+{
+ // margin and line spacing calculation
+ TQPtrVector<TQStyleSheetItem>* prevStyle = 0;
+ TQPtrVector<TQStyleSheetItem>* curStyle = styles.first();
+ TQPtrVector<TQStyleSheetItem>* nextStyle = styles.next();
+ while ( stylesPar ) {
+ if ( !curStyle ) {
+ stylesPar = stylesPar->next();
+ prevStyle = curStyle;
+ curStyle = nextStyle;
+ nextStyle = styles.next();
+ continue;
+ }
+
+ int i, mar;
+ TQStyleSheetItem* mainStyle = curStyle->size() ? (*curStyle)[curStyle->size()-1] : 0;
+ if ( mainStyle && mainStyle->displayMode() == TQStyleSheetItem::DisplayListItem )
+ stylesPar->setListItem( TRUE );
+ int numLists = 0;
+ for ( i = 0; i < (int)curStyle->size(); ++i ) {
+ if ( (*curStyle)[ i ]->displayMode() == TQStyleSheetItem::DisplayBlock
+ && (*curStyle)[ i ]->listStyle() != TQStyleSheetItem::ListStyleUndefined )
+ numLists++;
+ }
+ stylesPar->ldepth = numLists;
+ if ( stylesPar->next() && nextStyle ) {
+ // also set the depth of the next paragraph, required for the margin calculation
+ numLists = 0;
+ for ( i = 0; i < (int)nextStyle->size(); ++i ) {
+ if ( (*nextStyle)[ i ]->displayMode() == TQStyleSheetItem::DisplayBlock
+ && (*nextStyle)[ i ]->listStyle() != TQStyleSheetItem::ListStyleUndefined )
+ numLists++;
+ }
+ stylesPar->next()->ldepth = numLists;
+ }
+
+ // do the top margin
+ TQStyleSheetItem* item = mainStyle;
+ int m;
+ if (stylesPar->utm > 0 ) {
+ m = stylesPar->utm-1;
+ stylesPar->utm = 0;
+ } else {
+ m = TQMAX(0, item->margin( TQStyleSheetItem::MarginTop ) );
+ if ( stylesPar->ldepth ) {
+ if ( item->displayMode() == TQStyleSheetItem::DisplayListItem )
+ m /= stylesPar->ldepth * stylesPar->ldepth;
+ else
+ m = 0;
+ }
+ }
+ for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
+ item = (*curStyle)[ i ];
+ if ( prevStyle && i < (int) prevStyle->size() &&
+ ( item->displayMode() == TQStyleSheetItem::DisplayBlock &&
+ (*prevStyle)[ i ] == item ) )
+ break;
+ // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
+ if ( item->listStyle() != TQStyleSheetItem::ListStyleUndefined &&
+ ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) )
+ continue;
+ mar = TQMAX( 0, item->margin( TQStyleSheetItem::MarginTop ) );
+ m = TQMAX( m, mar );
+ }
+ stylesPar->utm = m - stylesPar->topMargin();
+
+ // do the bottom margin
+ item = mainStyle;
+ if (stylesPar->ubm > 0 ) {
+ m = stylesPar->ubm-1;
+ stylesPar->ubm = 0;
+ } else {
+ m = TQMAX(0, item->margin( TQStyleSheetItem::MarginBottom ) );
+ if ( stylesPar->ldepth ) {
+ if ( item->displayMode() == TQStyleSheetItem::DisplayListItem )
+ m /= stylesPar->ldepth * stylesPar->ldepth;
+ else
+ m = 0;
+ }
+ }
+ for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
+ item = (*curStyle)[ i ];
+ if ( nextStyle && i < (int) nextStyle->size() &&
+ ( item->displayMode() == TQStyleSheetItem::DisplayBlock &&
+ (*nextStyle)[ i ] == item ) )
+ break;
+ // emulate CSS2' standard 0 vertical margin for multiple ul or ol tags
+ if ( item->listStyle() != TQStyleSheetItem::ListStyleUndefined &&
+ ( ( i> 0 && (*curStyle)[ i-1 ] == item ) || (*curStyle)[i+1] == item ) )
+ continue;
+ mar = TQMAX(0, item->margin( TQStyleSheetItem::MarginBottom ) );
+ m = TQMAX( m, mar );
+ }
+ stylesPar->ubm = m - stylesPar->bottomMargin();
+
+ // do the left margin, simplyfied
+ item = mainStyle;
+ if (stylesPar->ulm > 0 ) {
+ m = stylesPar->ulm-1;
+ stylesPar->ulm = 0;
+ } else {
+ m = TQMAX( 0, item->margin( TQStyleSheetItem::MarginLeft ) );
+ }
+ for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
+ item = (*curStyle)[ i ];
+ m += TQMAX( 0, item->margin( TQStyleSheetItem::MarginLeft ) );
+ }
+ stylesPar->ulm = m - stylesPar->leftMargin();
+
+ // do the right margin, simplyfied
+ item = mainStyle;
+ if (stylesPar->urm > 0 ) {
+ m = stylesPar->urm-1;
+ stylesPar->urm = 0;
+ } else {
+ m = TQMAX( 0, item->margin( TQStyleSheetItem::MarginRight ) );
+ }
+ for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
+ item = (*curStyle)[ i ];
+ m += TQMAX( 0, item->margin( TQStyleSheetItem::MarginRight ) );
+ }
+ stylesPar->urm = m - stylesPar->rightMargin();
+
+ // do the first line margin, which really should be called text-indent
+ item = mainStyle;
+ if (stylesPar->uflm > 0 ) {
+ m = stylesPar->uflm-1;
+ stylesPar->uflm = 0;
+ } else {
+ m = TQMAX( 0, item->margin( TQStyleSheetItem::MarginFirstLine ) );
+ }
+ for ( i = (int)curStyle->size() - 2 ; i >= 0; --i ) {
+ item = (*curStyle)[ i ];
+ mar = TQMAX( 0, item->margin( TQStyleSheetItem::MarginFirstLine ) );
+ m = TQMAX( m, mar );
+ }
+ stylesPar->uflm =m - stylesPar->firstLineMargin();
+
+ // do the bogus line "spacing", which really is just an extra margin
+ item = mainStyle;
+ for ( i = (int)curStyle->size() - 1 ; i >= 0; --i ) {
+ item = (*curStyle)[ i ];
+ if ( item->lineSpacing() != TQStyleSheetItem::Undefined ) {
+ stylesPar->ulinespacing = item->lineSpacing();
+ if ( formatCollection() &&
+ stylesPar->ulinespacing < formatCollection()->defaultFormat()->height() )
+ stylesPar->ulinespacing += formatCollection()->defaultFormat()->height();
+ break;
+ }
+ }
+
+ stylesPar = stylesPar->next();
+ prevStyle = curStyle;
+ curStyle = nextStyle;
+ nextStyle = styles.next();
+ }
+}
+
+void TQTextDocument::setText( const TQString &text, const TQString &context )
+{
+ focusIndicator.parag = 0;
+ selections.clear();
+ if ( ((txtFormat == TQt::AutoText) && (TQStyleSheet::mightBeRichText( text ))) ||
+ (txtFormat == TQt::RichText) )
+ setRichText( text, context );
+ else
+ setPlainText( text );
+}
+
+TQString TQTextDocument::plainText() const
+{
+ TQString buffer;
+ TQString s;
+ TQTextParagraph *p = fParag;
+ while ( p ) {
+ if ( !p->mightHaveCustomItems ) {
+ const TQTextString *ts = p->string(); // workaround VC++ and Borland
+ s = ts->toString(); // with FALSE we don't fix spaces (nbsp)
+ } else {
+ for ( int i = 0; i < p->length() - 1; ++i ) {
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( p->at( i )->isCustom() ) {
+ if ( p->at( i )->customItem()->isNested() ) {
+ s += "\n";
+ TQTextTable *t = (TQTextTable*)p->at( i )->customItem();
+ TQPtrList<TQTextTableCell> cells = t->tableCells();
+ for ( TQTextTableCell *c = cells.first(); c; c = cells.next() )
+ s += c->richText()->plainText() + "\n";
+ s += "\n";
+ }
+ } else
+#endif
+ {
+ s += p->at( i )->c;
+ }
+ }
+ }
+ s.remove( s.length() - 1, 1 );
+ if ( p->next() )
+ s += "\n";
+ buffer += s;
+ p = p->next();
+ }
+ return buffer;
+}
+
+static TQString align_to_string( int a )
+{
+ if ( a & TQt::AlignRight )
+ return " align=\"right\"";
+ if ( a & TQt::AlignHCenter )
+ return " align=\"center\"";
+ if ( a & TQt::AlignJustify )
+ return " align=\"justify\"";
+ return TQString::null;
+}
+
+static TQString direction_to_string( int d )
+{
+ if ( d != TQChar::DirON )
+ return ( d == TQChar::DirL? " dir=\"ltr\"" : " dir=\"rtl\"" );
+ return TQString::null;
+}
+
+static TQString list_value_to_string( int v )
+{
+ if ( v != -1 )
+ return " listvalue=\"" + TQString::number( v ) + "\"";
+ return TQString::null;
+}
+
+static TQString list_style_to_string( int v )
+{
+ switch( v ) {
+ case TQStyleSheetItem::ListDecimal: return "\"1\"";
+ case TQStyleSheetItem::ListLowerAlpha: return "\"a\"";
+ case TQStyleSheetItem::ListUpperAlpha: return "\"A\"";
+ case TQStyleSheetItem::ListDisc: return "\"disc\"";
+ case TQStyleSheetItem::ListSquare: return "\"square\"";
+ case TQStyleSheetItem::ListCircle: return "\"circle\"";
+ default:
+ return TQString::null;
+ }
+}
+
+static inline bool list_is_ordered( int v )
+{
+ return v == TQStyleSheetItem::ListDecimal ||
+ v == TQStyleSheetItem::ListLowerAlpha ||
+ v == TQStyleSheetItem::ListUpperAlpha;
+}
+
+
+static TQString margin_to_string( TQStyleSheetItem* style, int t, int b, int l, int r, int fl )
+{
+ TQString s;
+ if ( l > 0 )
+ s += TQString(!!s?";":"") + "margin-left:" + TQString::number(l+TQMAX(0,style->margin(TQStyleSheetItem::MarginLeft))) + "px";
+ if ( r > 0 )
+ s += TQString(!!s?";":"") + "margin-right:" + TQString::number(r+TQMAX(0,style->margin(TQStyleSheetItem::MarginRight))) + "px";
+ if ( t > 0 )
+ s += TQString(!!s?";":"") + "margin-top:" + TQString::number(t+TQMAX(0,style->margin(TQStyleSheetItem::MarginTop))) + "px";
+ if ( b > 0 )
+ s += TQString(!!s?";":"") + "margin-bottom:" + TQString::number(b+TQMAX(0,style->margin(TQStyleSheetItem::MarginBottom))) + "px";
+ if ( fl > 0 )
+ s += TQString(!!s?";":"") + "text-indent:" + TQString::number(fl+TQMAX(0,style->margin(TQStyleSheetItem::MarginFirstLine))) + "px";
+ if ( !!s )
+ return " style=\"" + s + "\"";
+ return TQString::null;
+}
+
+TQString TQTextDocument::richText() const
+{
+ TQString s = "";
+ if ( !par ) {
+ s += "<html><head><meta name=\"qrichtext\" content=\"1\" /></head><body style=\"font-size:" ;
+ s += TQString::number( formatCollection()->defaultFormat()->font().pointSize() );
+ s += "pt;font-family:";
+ s += formatCollection()->defaultFormat()->font().family();
+ s +="\">";
+ }
+ TQTextParagraph* p = fParag;
+
+ TQStyleSheetItem* item_p = styleSheet()->item("p");
+ TQStyleSheetItem* item_div = styleSheet()->item("div");
+ TQStyleSheetItem* item_ul = styleSheet()->item("ul");
+ TQStyleSheetItem* item_ol = styleSheet()->item("ol");
+ TQStyleSheetItem* item_li = styleSheet()->item("li");
+ if ( !item_p || !item_div || !item_ul || !item_ol || !item_li ) {
+ qWarning( "TQTextEdit: cannot export HTML due to insufficient stylesheet (lack of p, div, ul, ol, or li)" );
+ return TQString::null;
+ }
+ int pastListDepth = 0;
+ int listDepth = 0;
+#if 0
+ int futureListDepth = 0;
+#endif
+ TQMemArray<int> listStyles(10);
+
+ while ( p ) {
+ listDepth = p->listDepth();
+ if ( listDepth < pastListDepth ) {
+ for ( int i = pastListDepth; i > listDepth; i-- )
+ s += list_is_ordered( listStyles[i] ) ? "</ol>" : "</ul>";
+ s += '\n';
+ } else if ( listDepth > pastListDepth ) {
+ s += '\n';
+ listStyles.resize( TQMAX( (int)listStyles.size(), listDepth+1 ) );
+ TQString list_type;
+ listStyles[listDepth] = p->listStyle();
+ if ( !list_is_ordered( p->listStyle() ) || item_ol->listStyle() != p->listStyle() )
+ list_type = " type=" + list_style_to_string( p->listStyle() );
+ for ( int i = pastListDepth; i < listDepth; i++ ) {
+ s += list_is_ordered( p->listStyle() ) ? "<ol" : "<ul" ;
+ s += list_type + ">";
+ }
+ } else {
+ s += '\n';
+ }
+
+ TQString ps = p->richText();
+
+#if 0
+ // for the bottom margin we need to know whether we are at the end of a list
+ futureListDepth = 0;
+ if ( listDepth > 0 && p->next() )
+ futureListDepth = p->next()->listDepth();
+#endif
+
+ if ( richTextExportStart && richTextExportStart->paragraph() ==p &&
+ richTextExportStart->index() == 0 )
+ s += "<!--StartFragment-->";
+
+ if ( p->isListItem() ) {
+ s += "<li";
+ if ( p->listStyle() != listStyles[listDepth] )
+ s += " type=" + list_style_to_string( p->listStyle() );
+ s +=align_to_string( p->tqalignment() );
+ s += margin_to_string( item_li, p->utm, p->ubm, p->ulm, p->urm, p->uflm );
+ s += list_value_to_string( p->listValue() );
+ s += direction_to_string( p->direction() );
+ s +=">";
+ s += ps;
+ s += "</li>";
+ } else if ( p->listDepth() ) {
+ s += "<div";
+ s += align_to_string( p->tqalignment() );
+ s += margin_to_string( item_div, p->utm, p->ubm, p->ulm, p->urm, p->uflm );
+ s +=direction_to_string( p->direction() );
+ s += ">";
+ s += ps;
+ s += "</div>";
+ } else {
+ // normal paragraph item
+ s += "<p";
+ s += align_to_string( p->tqalignment() );
+ s += margin_to_string( item_p, p->utm, p->ubm, p->ulm, p->urm, p->uflm );
+ s +=direction_to_string( p->direction() );
+ s += ">";
+ s += ps;
+ s += "</p>";
+ }
+ pastListDepth = listDepth;
+ p = p->next();
+ }
+ while ( listDepth > 0 ) {
+ s += list_is_ordered( listStyles[listDepth] ) ? "</ol>" : "</ul>";
+ listDepth--;
+ }
+
+ if ( !par )
+ s += "\n</body></html>\n";
+
+ return s;
+}
+
+TQString TQTextDocument::text() const
+{
+ if ( ((txtFormat == TQt::AutoText) && preferRichText) || (txtFormat == TQt::RichText) )
+ return richText();
+ return plainText();
+}
+
+TQString TQTextDocument::text( int parag ) const
+{
+ TQTextParagraph *p = paragAt( parag );
+ if ( !p )
+ return TQString::null;
+
+ if ( ((txtFormat == TQt::AutoText) && preferRichText) || (txtFormat == TQt::RichText) )
+ return p->richText();
+ else
+ return p->string()->toString();
+}
+
+void TQTextDocument::tqinvalidate()
+{
+ TQTextParagraph *s = fParag;
+ while ( s ) {
+ s->tqinvalidate( 0 );
+ s = s->next();
+ }
+}
+
+void TQTextDocument::selectionStart( int id, int &paragId, int &index )
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.tqfind( id );
+ if ( it == selections.end() )
+ return;
+ TQTextDocumentSelection &sel = *it;
+ paragId = !sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
+ index = !sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
+}
+
+TQTextCursor TQTextDocument::selectionStartCursor( int id)
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.tqfind( id );
+ if ( it == selections.end() )
+ return TQTextCursor( this );
+ TQTextDocumentSelection &sel = *it;
+ if ( sel.swapped )
+ return sel.endCursor;
+ return sel.startCursor;
+}
+
+TQTextCursor TQTextDocument::selectionEndCursor( int id)
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.tqfind( id );
+ if ( it == selections.end() )
+ return TQTextCursor( this );
+ TQTextDocumentSelection &sel = *it;
+ if ( !sel.swapped )
+ return sel.endCursor;
+ return sel.startCursor;
+}
+
+void TQTextDocument::selectionEnd( int id, int &paragId, int &index )
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.tqfind( id );
+ if ( it == selections.end() )
+ return;
+ TQTextDocumentSelection &sel = *it;
+ paragId = sel.swapped ? sel.startCursor.paragraph()->paragId() : sel.endCursor.paragraph()->paragId();
+ index = sel.swapped ? sel.startCursor.index() : sel.endCursor.index();
+}
+
+void TQTextDocument::addSelection( int id )
+{
+ nSelections = TQMAX( nSelections, id + 1 );
+}
+
+static void setSelectionEndHelper( int id, TQTextDocumentSelection &sel, TQTextCursor &start, TQTextCursor &end )
+{
+ TQTextCursor c1 = start;
+ TQTextCursor c2 = end;
+ if ( sel.swapped ) {
+ c1 = end;
+ c2 = start;
+ }
+
+ c1.paragraph()->removeSelection( id );
+ c2.paragraph()->removeSelection( id );
+ if ( c1.paragraph() != c2.paragraph() ) {
+ c1.paragraph()->setSelection( id, c1.index(), c1.paragraph()->length() - 1 );
+ c2.paragraph()->setSelection( id, 0, c2.index() );
+ } else {
+ c1.paragraph()->setSelection( id, TQMIN( c1.index(), c2.index() ), TQMAX( c1.index(), c2.index() ) );
+ }
+
+ sel.startCursor = start;
+ sel.endCursor = end;
+ if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() )
+ sel.swapped = sel.startCursor.index() > sel.endCursor.index();
+}
+
+bool TQTextDocument::setSelectionEnd( int id, const TQTextCursor &cursor )
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.tqfind( id );
+ if ( it == selections.end() )
+ return FALSE;
+ TQTextDocumentSelection &sel = *it;
+
+ TQTextCursor start = sel.startCursor;
+ TQTextCursor end = cursor;
+
+ if ( start == end ) {
+ removeSelection( id );
+ setSelectionStart( id, cursor );
+ return TRUE;
+ }
+
+ if ( sel.endCursor.paragraph() == end.paragraph() ) {
+ setSelectionEndHelper( id, sel, start, end );
+ return TRUE;
+ }
+
+ bool inSelection = FALSE;
+ TQTextCursor c( this );
+ TQTextCursor tmp = sel.startCursor;
+ if ( sel.swapped )
+ tmp = sel.endCursor;
+ tmp.restoreState();
+ TQTextCursor tmp2 = cursor;
+ tmp2.restoreState();
+ c.setParagraph( tmp.paragraph()->paragId() < tmp2.paragraph()->paragId() ? tmp.paragraph() : tmp2.paragraph() );
+ bool hadStart = FALSE;
+ bool hadEnd = FALSE;
+ bool hadStartParag = FALSE;
+ bool hadEndParag = FALSE;
+ bool hadOldStart = FALSE;
+ bool hadOldEnd = FALSE;
+ bool leftSelection = FALSE;
+ sel.swapped = FALSE;
+ for ( ;; ) {
+ if ( c == start )
+ hadStart = TRUE;
+ if ( c == end )
+ hadEnd = TRUE;
+ if ( c.paragraph() == start.paragraph() )
+ hadStartParag = TRUE;
+ if ( c.paragraph() == end.paragraph() )
+ hadEndParag = TRUE;
+ if ( c == sel.startCursor )
+ hadOldStart = TRUE;
+ if ( c == sel.endCursor )
+ hadOldEnd = TRUE;
+
+ if ( !sel.swapped &&
+ ( (hadEnd && !hadStart) ||
+ (hadEnd && hadStart && (start.paragraph() == end.paragraph()) && start.index() > end.index()) ) )
+ sel.swapped = TRUE;
+
+ if ( ((c == end) && hadStartParag) ||
+ ((c == start) && hadEndParag )) {
+ TQTextCursor tmp = c;
+ tmp.restoreState();
+ if ( tmp.paragraph() != c.paragraph() ) {
+ int sstart = tmp.paragraph()->selectionStart( id );
+ tmp.paragraph()->removeSelection( id );
+ tmp.paragraph()->setSelection( id, sstart, tmp.index() );
+ }
+ }
+
+ if ( inSelection &&
+ ( ((c == end) && hadStart) || ((c == start) && hadEnd) ) )
+ leftSelection = TRUE;
+ else if ( !leftSelection && !inSelection && ( hadStart || hadEnd ) )
+ inSelection = TRUE;
+
+ bool noSelectionAnymore = hadOldStart && hadOldEnd && leftSelection && !inSelection && !c.paragraph()->hasSelection( id ) && c.atParagEnd();
+ c.paragraph()->removeSelection( id );
+ if ( inSelection ) {
+ if ( c.paragraph() == start.paragraph() && start.paragraph() == end.paragraph() ) {
+ c.paragraph()->setSelection( id, TQMIN( start.index(), end.index() ), TQMAX( start.index(), end.index() ) );
+ } else if ( c.paragraph() == start.paragraph() && !hadEndParag ) {
+ c.paragraph()->setSelection( id, start.index(), c.paragraph()->length() - 1 );
+ } else if ( c.paragraph() == end.paragraph() && !hadStartParag ) {
+ c.paragraph()->setSelection( id, end.index(), c.paragraph()->length() - 1 );
+ } else if ( c.paragraph() == end.paragraph() && hadEndParag ) {
+ c.paragraph()->setSelection( id, 0, end.index() );
+ } else if ( c.paragraph() == start.paragraph() && hadStartParag ) {
+ c.paragraph()->setSelection( id, 0, start.index() );
+ } else {
+ c.paragraph()->setSelection( id, 0, c.paragraph()->length() - 1 );
+ }
+ }
+
+ if ( leftSelection )
+ inSelection = FALSE;
+
+ if ( noSelectionAnymore )
+ break;
+ // *ugle*hack optimization
+ TQTextParagraph *p = c.paragraph();
+ if ( p->mightHaveCustomItems || p == start.paragraph() || p == end.paragraph() || p == lastParagraph() ) {
+ c.gotoNextLetter();
+ if ( p == lastParagraph() && c.atParagEnd() )
+ break;
+ } else {
+ if ( p->document()->tqparent() )
+ do {
+ c.gotoNextLetter();
+ } while ( c.paragraph() == p );
+ else
+ c.setParagraph( p->next() );
+ }
+ }
+
+ if ( !sel.swapped )
+ sel.startCursor.paragraph()->setSelection( id, sel.startCursor.index(), sel.startCursor.paragraph()->length() - 1 );
+
+ sel.startCursor = start;
+ sel.endCursor = end;
+ if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() )
+ sel.swapped = sel.startCursor.index() > sel.endCursor.index();
+
+ setSelectionEndHelper( id, sel, start, end );
+
+ return TRUE;
+}
+
+void TQTextDocument::selectAll( int id )
+{
+ removeSelection( id );
+
+ TQTextDocumentSelection sel;
+ sel.swapped = FALSE;
+ TQTextCursor c( this );
+
+ c.setParagraph( fParag );
+ c.setIndex( 0 );
+ sel.startCursor = c;
+
+ c.setParagraph( lParag );
+ c.setIndex( lParag->length() - 1 );
+ sel.endCursor = c;
+
+ selections.insert( id, sel );
+
+ TQTextParagraph *p = fParag;
+ while ( p ) {
+ p->setSelection( id, 0, p->length() - 1 );
+ p = p->next();
+ }
+
+ for ( TQTextDocument *d = childList.first(); d; d = childList.next() )
+ d->selectAll( id );
+}
+
+bool TQTextDocument::removeSelection( int id )
+{
+ if ( !selections.tqcontains( id ) )
+ return FALSE;
+
+ TQTextDocumentSelection &sel = selections[ id ];
+
+ TQTextCursor start = sel.swapped ? sel.endCursor : sel.startCursor;
+ TQTextCursor end = sel.swapped ? sel.startCursor : sel.endCursor;
+ TQTextParagraph* p = 0;
+ while ( start != end ) {
+ if ( p != start.paragraph() ) {
+ p = start.paragraph();
+ p->removeSelection( id );
+ //### avoid endless loop by all means necessary, did somebody mention refactoring?
+ if ( !tqparent() && p == lParag )
+ break;
+ }
+ start.gotoNextLetter();
+ }
+ p = start.paragraph();
+ p->removeSelection( id );
+ selections.remove( id );
+ return TRUE;
+}
+
+TQString TQTextDocument::selectedText( int id, bool asRichText ) const
+{
+ QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.tqfind( id );
+ if ( it == selections.end() )
+ return TQString::null;
+
+ TQTextDocumentSelection sel = *it;
+
+
+ TQTextCursor c1 = sel.startCursor;
+ TQTextCursor c2 = sel.endCursor;
+ if ( sel.swapped ) {
+ c2 = sel.startCursor;
+ c1 = sel.endCursor;
+ }
+
+ /* 3.0.3 improvement: Make it possible to get a reasonable
+ selection inside a table. This approach is very conservative:
+ make sure that both cursors have the same depth level and point
+ to paragraphs within the same text document.
+
+ Meaning if you select text in two table cells, you will get the
+ entire table. This is still far better than the 3.0.2, where
+ you always got the entire table.
+
+ ### Fix this properly when refactoring
+ */
+ while ( c2.nestedDepth() > c1.nestedDepth() )
+ c2.oneUp();
+ while ( c1.nestedDepth() > c2.nestedDepth() )
+ c1.oneUp();
+ while ( c1.nestedDepth() && c2.nestedDepth() &&
+ c1.paragraph()->document() != c2.paragraph()->document() ) {
+ c1.oneUp();
+ c2.oneUp();
+ }
+ // do not trust sel_swapped with tables. Fix this properly when refactoring as well
+ if ( c1.paragraph()->paragId() > c2.paragraph()->paragId() ||
+ (c1.paragraph() == c2.paragraph() && c1.index() > c2.index() ) ) {
+ TQTextCursor tmp = c1;
+ c2 = c1;
+ c1 = tmp;
+ }
+
+ // end selection 3.0.3 improvement
+
+ if ( asRichText && !tqparent() ) {
+ richTextExportStart = &c1;
+ richTextExportEnd = &c2;
+
+ TQString sel = richText();
+ int from = sel.tqfind( "<!--StartFragment-->" );
+ if ( from >= 0 ) {
+ from += 20;
+ // tqfind the previous span and move it into the start fragment before we clip it
+ TQString prevspan;
+ int pspan = sel.tqfindRev( "<span", from-21 );
+ if ( pspan > sel.tqfindRev( "</span", from-21 ) ) {
+ int spanend = sel.tqfind( '>', pspan );
+ prevspan = sel.mid( pspan, spanend - pspan + 1 );
+ }
+ int to = sel.tqfindRev( "<!--EndFragment-->" );
+ if ( from <= to )
+ sel = "<!--StartFragment-->" + prevspan + sel.mid( from, to - from );
+ }
+ richTextExportStart = richTextExportEnd = 0;
+ return sel;
+ }
+
+ TQString s;
+ if ( c1.paragraph() == c2.paragraph() ) {
+ TQTextParagraph *p = c1.paragraph();
+ int end = c2.index();
+ if ( p->at( TQMAX( 0, end - 1 ) )->isCustom() )
+ ++end;
+ if ( !p->mightHaveCustomItems ) {
+ s += p->string()->toString().mid( c1.index(), end - c1.index() );
+ } else {
+ for ( int i = c1.index(); i < end; ++i ) {
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( p->at( i )->isCustom() ) {
+ if ( p->at( i )->customItem()->isNested() ) {
+ s += "\n";
+ TQTextTable *t = (TQTextTable*)p->at( i )->customItem();
+ TQPtrList<TQTextTableCell> cells = t->tableCells();
+ for ( TQTextTableCell *c = cells.first(); c; c = cells.next() )
+ s += c->richText()->plainText() + "\n";
+ s += "\n";
+ }
+ } else
+#endif
+ {
+ s += p->at( i )->c;
+ }
+ }
+ }
+ } else {
+ TQTextParagraph *p = c1.paragraph();
+ int start = c1.index();
+ while ( p ) {
+ int end = p == c2.paragraph() ? c2.index() : p->length() - 1;
+ if ( p == c2.paragraph() && p->at( TQMAX( 0, end - 1 ) )->isCustom() )
+ ++end;
+ if ( !p->mightHaveCustomItems ) {
+ s += p->string()->toString().mid( start, end - start );
+ if ( p != c2.paragraph() )
+ s += "\n";
+ } else {
+ for ( int i = start; i < end; ++i ) {
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( p->at( i )->isCustom() ) {
+ if ( p->at( i )->customItem()->isNested() ) {
+ s += "\n";
+ TQTextTable *t = (TQTextTable*)p->at( i )->customItem();
+ TQPtrList<TQTextTableCell> cells = t->tableCells();
+ for ( TQTextTableCell *c = cells.first(); c; c = cells.next() )
+ s += c->richText()->plainText() + "\n";
+ s += "\n";
+ }
+ } else
+#endif
+ {
+ s += p->at( i )->c;
+ }
+ }
+ }
+ start = 0;
+ if ( p == c2.paragraph() )
+ break;
+ p = p->next();
+ }
+ }
+ // ### workaround for plain text export until we get proper
+ // mime types: turn tqunicode line seperators into the more
+ // widely understood \n. Makes copy and pasting code snipplets
+ // from within Assistent possible
+ TQChar* uc = (TQChar*) s.tqunicode();
+ for ( int ii = 0; ii < s.length(); ii++ ) {
+ if ( uc[(int)ii] == TQChar_linesep )
+ uc[(int)ii] = TQChar('\n');
+ else if ( uc[(int)ii] == TQChar::nbsp )
+ uc[(int)ii] = TQChar(' ');
+ }
+ return s;
+}
+
+void TQTextDocument::setFormat( int id, TQTextFormat *f, int flags )
+{
+ QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.tqfind( id );
+ if ( it == selections.end() )
+ return;
+
+ TQTextDocumentSelection sel = *it;
+
+ TQTextCursor c1 = sel.startCursor;
+ TQTextCursor c2 = sel.endCursor;
+ if ( sel.swapped ) {
+ c2 = sel.startCursor;
+ c1 = sel.endCursor;
+ }
+
+ c2.restoreState();
+ c1.restoreState();
+
+ if ( c1.paragraph() == c2.paragraph() ) {
+ c1.paragraph()->setFormat( c1.index(), c2.index() - c1.index(), f, TRUE, flags );
+ return;
+ }
+
+ c1.paragraph()->setFormat( c1.index(), c1.paragraph()->length() - c1.index(), f, TRUE, flags );
+ TQTextParagraph *p = c1.paragraph()->next();
+ while ( p && p != c2.paragraph() ) {
+ p->setFormat( 0, p->length(), f, TRUE, flags );
+ p = p->next();
+ }
+ c2.paragraph()->setFormat( 0, c2.index(), f, TRUE, flags );
+}
+
+void TQTextDocument::removeSelectedText( int id, TQTextCursor *cursor )
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.tqfind( id );
+ if ( it == selections.end() )
+ return;
+
+ TQTextDocumentSelection sel = *it;
+ TQTextCursor c1 = sel.startCursor;
+ TQTextCursor c2 = sel.endCursor;
+ if ( sel.swapped ) {
+ c2 = sel.startCursor;
+ c1 = sel.endCursor;
+ }
+
+ // ### no support for editing tables yet
+ if ( c1.nestedDepth() || c2.nestedDepth() )
+ return;
+
+ c2.restoreState();
+ c1.restoreState();
+
+ *cursor = c1;
+ removeSelection( id );
+
+ if ( c1.paragraph() == c2.paragraph() ) {
+ c1.paragraph()->remove( c1.index(), c2.index() - c1.index() );
+ return;
+ }
+
+ if ( c1.paragraph() == fParag && c1.index() == 0 &&
+ c2.paragraph() == lParag && c2.index() == lParag->length() - 1 )
+ cursor->setValid( FALSE );
+
+ bool didGoLeft = FALSE;
+ if ( c1.index() == 0 && c1.paragraph() != fParag ) {
+ cursor->gotoPreviousLetter();
+ didGoLeft = cursor->isValid();
+ }
+
+ c1.paragraph()->remove( c1.index(), c1.paragraph()->length() - 1 - c1.index() );
+ TQTextParagraph *p = c1.paragraph()->next();
+ int dy = 0;
+ TQTextParagraph *tmp;
+ while ( p && p != c2.paragraph() ) {
+ tmp = p->next();
+ dy -= p->rect().height();
+ delete p;
+ p = tmp;
+ }
+ c2.paragraph()->remove( 0, c2.index() );
+ while ( p ) {
+ p->move( dy );
+ p->tqinvalidate( 0 );
+ p->setEndState( -1 );
+ p = p->next();
+ }
+
+
+ c1.paragraph()->join( c2.paragraph() );
+
+ if ( didGoLeft )
+ cursor->gotoNextLetter();
+}
+
+void TQTextDocument::indentSelection( int id )
+{
+ QMap<int, TQTextDocumentSelection>::Iterator it = selections.tqfind( id );
+ if ( it == selections.end() )
+ return;
+
+ TQTextDocumentSelection sel = *it;
+ TQTextParagraph *startParag = sel.startCursor.paragraph();
+ TQTextParagraph *endParag = sel.endCursor.paragraph();
+ if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) {
+ endParag = sel.startCursor.paragraph();
+ startParag = sel.endCursor.paragraph();
+ }
+
+ TQTextParagraph *p = startParag;
+ while ( p && p != endParag ) {
+ p->indent();
+ p = p->next();
+ }
+}
+
+void TQTextDocument::addCommand( TQTextCommand *cmd )
+{
+ commandHistory->addCommand( cmd );
+}
+
+TQTextCursor *TQTextDocument::undo( TQTextCursor *c )
+{
+ return commandHistory->undo( c );
+}
+
+TQTextCursor *TQTextDocument::redo( TQTextCursor *c )
+{
+ return commandHistory->redo( c );
+}
+
+bool TQTextDocument::tqfind( TQTextCursor& cursor, const TQString &expr, bool cs, bool wo, bool forward )
+{
+ removeSelection( Standard );
+ TQTextParagraph *p = 0;
+ if ( expr.isEmpty() )
+ return FALSE;
+ for (;;) {
+ if ( p != cursor.paragraph() ) {
+ p = cursor.paragraph();
+ TQString s = cursor.paragraph()->string()->toString();
+ int start = cursor.index();
+ for ( ;; ) {
+ int res = forward ? s.tqfind( expr, start, cs ) : s.tqfindRev( expr, start, cs );
+ int end = res + expr.length();
+ if ( res == -1 || ( !forward && start <= res ) )
+ break;
+ if ( !wo || ( ( res == 0 || s[ res - 1 ].isSpace() || s[ res - 1 ].isPunct() ) &&
+ ( end == (int)s.length() || s[ end ].isSpace() || s[ end ].isPunct() ) ) ) {
+ removeSelection( Standard );
+ cursor.setIndex( forward ? end : res );
+ setSelectionStart( Standard, cursor );
+ cursor.setIndex( forward ? res : end );
+ setSelectionEnd( Standard, cursor );
+ if ( !forward )
+ cursor.setIndex( res );
+ return TRUE;
+ }
+ start = res + (forward ? 1 : -1);
+ }
+ }
+ if ( forward ) {
+ if ( cursor.paragraph() == lastParagraph() && cursor.atParagEnd() )
+ break;
+ cursor.gotoNextLetter();
+ } else {
+ if ( cursor.paragraph() == firstParagraph() && cursor.atParagStart() )
+ break;
+ cursor.gotoPreviousLetter();
+ }
+ }
+ return FALSE;
+}
+
+void TQTextDocument::setTextFormat( TQt::TextFormat f )
+{
+ txtFormat = f;
+ if ( fParag == lParag && fParag->length() <= 1 )
+ fParag->rtext = ( f == TQt::RichText );
+}
+
+TQt::TextFormat TQTextDocument::textFormat() const
+{
+ return txtFormat;
+}
+
+bool TQTextDocument::inSelection( int selId, const TQPoint &pos ) const
+{
+ QMap<int, TQTextDocumentSelection>::ConstIterator it = selections.tqfind( selId );
+ if ( it == selections.end() )
+ return FALSE;
+
+ TQTextDocumentSelection sel = *it;
+ TQTextParagraph *startParag = sel.startCursor.paragraph();
+ TQTextParagraph *endParag = sel.endCursor.paragraph();
+ if ( sel.startCursor.paragraph() == sel.endCursor.paragraph() &&
+ sel.startCursor.paragraph()->selectionStart( selId ) == sel.endCursor.paragraph()->selectionEnd( selId ) )
+ return FALSE;
+ if ( sel.endCursor.paragraph()->paragId() < sel.startCursor.paragraph()->paragId() ) {
+ endParag = sel.startCursor.paragraph();
+ startParag = sel.endCursor.paragraph();
+ }
+
+ TQTextParagraph *p = startParag;
+ while ( p ) {
+ if ( p->rect().tqcontains( pos ) ) {
+ bool inSel = FALSE;
+ int selStart = p->selectionStart( selId );
+ int selEnd = p->selectionEnd( selId );
+ int y = 0;
+ int h = 0;
+ for ( int i = 0; i < p->length(); ++i ) {
+ if ( i == selStart )
+ inSel = TRUE;
+ if ( i == selEnd )
+ break;
+ if ( p->at( i )->lineStart ) {
+ y = (*p->lineStarts.tqfind( i ))->y;
+ h = (*p->lineStarts.tqfind( i ))->h;
+ }
+ if ( pos.y() - p->rect().y() >= y && pos.y() - p->rect().y() <= y + h ) {
+ if ( inSel && pos.x() >= p->at( i )->x &&
+ pos.x() <= p->at( i )->x + p->at( i )->format()->width( p->at( i )->c ) )
+ return TRUE;
+ }
+ }
+ }
+ if ( pos.y() < p->rect().y() )
+ break;
+ if ( p == endParag )
+ break;
+ p = p->next();
+ }
+
+ return FALSE;
+}
+
+void TQTextDocument::doLayout( TQPainter *p, int w )
+{
+ minw = wused = 0;
+ if ( !is_printer( p ) )
+ p = 0;
+ withoutDoubleBuffer = ( p != 0 );
+ TQPainter * oldPainter = TQTextFormat::painter();
+ TQTextFormat::setPainter( p );
+ tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8;
+ flow_->setWidth( w );
+ cw = w;
+ vw = w;
+ TQTextParagraph *parag = fParag;
+ while ( parag ) {
+ parag->tqinvalidate( 0 );
+ if ( p )
+ parag->adjustToPainter( p );
+ parag->format();
+ parag = parag->next();
+ }
+ TQTextFormat::setPainter( oldPainter );
+}
+
+TQPixmap *TQTextDocument::bufferPixmap( const TQSize &s )
+{
+ if ( !buf_pixmap )
+ buf_pixmap = new TQPixmap( s.expandedTo( TQSize(1,1) ) );
+ else if ( buf_pixmap->size() != s )
+ buf_pixmap->resize( s.expandedTo( buf_pixmap->size() ) );
+ return buf_pixmap;
+}
+
+void TQTextDocument::draw( TQPainter *p, const TQRect &rect, const TQColorGroup &cg, const TQBrush *paper )
+{
+ if ( !firstParagraph() )
+ return;
+
+ if ( paper ) {
+ p->setBrushOrigin( -int( p->translationX() ),
+ -int( p->translationY() ) );
+
+ p->fillRect( rect, *paper );
+ }
+
+ TQPainter * oldPainter = TQTextFormat::painter();
+ TQTextFormat::setPainter( p );
+
+ if ( formatCollection()->defaultFormat()->color() != cg.text() )
+ setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() );
+
+ TQTextParagraph *parag = firstParagraph();
+ while ( parag ) {
+ if ( !parag->isValid() )
+ parag->format();
+ int y = parag->rect().y();
+ TQRect pr( parag->rect() );
+ pr.setX( 0 );
+ pr.setWidth( TQWIDGETSIZE_MAX );
+ if ( !rect.isNull() && !rect.intersects( pr ) ) {
+ parag = parag->next();
+ continue;
+ }
+ p->translate( 0, y );
+ if ( rect.isValid() )
+ parag->paint( *p, cg, 0, FALSE, rect.x(), rect.y(), rect.width(), rect.height() );
+ else
+ parag->paint( *p, cg, 0, FALSE );
+ p->translate( 0, -y );
+ parag = parag->next();
+ if ( !flow()->isEmpty() )
+ flow()->drawFloatingItems( p, rect.x(), rect.y(), rect.width(), rect.height(), cg, FALSE );
+ }
+ TQTextFormat::setPainter(oldPainter);
+}
+
+void TQTextDocument::drawParagraph( TQPainter *p, TQTextParagraph *parag, int cx, int cy, int cw, int ch,
+ TQPixmap *&doubleBuffer, const TQColorGroup &cg,
+ bool drawCursor, TQTextCursor *cursor, bool resetChanged )
+{
+ TQPainter *painter = 0;
+ if ( resetChanged )
+ parag->setChanged( FALSE );
+ TQRect ir( parag->rect() );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if (!parag->tableCell())
+#endif
+ ir.setWidth(width());
+
+ bool uDoubleBuffer = useDoubleBuffer( parag, p );
+
+ if ( uDoubleBuffer ) {
+ painter = new TQPainter;
+ if ( cx >= 0 && cy >= 0 )
+ ir = ir.intersect( TQRect( cx, cy, cw, ch ) );
+ if ( !doubleBuffer ||
+ ir.width() > doubleBuffer->width() ||
+ ir.height() > doubleBuffer->height() ) {
+ doubleBuffer = bufferPixmap( ir.size() );
+ painter->begin( doubleBuffer );
+ } else {
+ painter->begin( doubleBuffer );
+ }
+ } else {
+ painter = p;
+ painter->translate( ir.x(), ir.y() );
+ }
+
+ painter->setBrushOrigin( -ir.x(), -ir.y() );
+
+ if ( uDoubleBuffer || is_printer( painter ) )
+ painter->fillRect( TQRect( 0, 0, ir.width(), ir.height() ), parag->backgroundBrush( cg ) );
+ else if ( cursor && cursor->paragraph() == parag )
+ painter->fillRect( TQRect( parag->at( cursor->index() )->x, 0, 2, ir.height() ),
+ parag->backgroundBrush( cg ) );
+
+ painter->translate( -( ir.x() - parag->rect().x() ),
+ -( ir.y() - parag->rect().y() ) );
+ parag->paint( *painter, cg, drawCursor ? cursor : 0, TRUE, cx, cy, cw, ch );
+
+ if ( uDoubleBuffer ) {
+ delete painter;
+ painter = 0;
+ p->drawPixmap( ir.topLeft(), *doubleBuffer, TQRect( TQPoint( 0, 0 ), ir.size() ) );
+ } else {
+ painter->translate( -ir.x(), -ir.y() );
+ }
+
+ parag->document()->nextDoubleBuffered = FALSE;
+}
+
+TQTextParagraph *TQTextDocument::draw( TQPainter *p, int cx, int cy, int cw, int ch, const TQColorGroup &cg,
+ bool onlyChanged, bool drawCursor, TQTextCursor *cursor, bool resetChanged )
+{
+ if ( withoutDoubleBuffer || (par && par->withoutDoubleBuffer) ) {
+ withoutDoubleBuffer = TRUE;
+ TQRect r;
+ draw( p, r, cg );
+ return 0;
+ }
+ withoutDoubleBuffer = FALSE;
+
+ if ( !firstParagraph() )
+ return 0;
+
+ TQPainter * oldPainter = TQTextFormat::painter();
+ TQTextFormat::setPainter( p );
+ if ( formatCollection()->defaultFormat()->color() != cg.text() )
+ setDefaultFormat( formatCollection()->defaultFormat()->font(), cg.text() );
+
+ if ( cx < 0 && cy < 0 ) {
+ cx = 0;
+ cy = 0;
+ cw = width();
+ ch = height();
+ }
+
+ TQTextParagraph *lastFormatted = 0;
+ TQTextParagraph *parag = firstParagraph();
+
+ TQPixmap *doubleBuffer = 0;
+
+ while ( parag ) {
+ lastFormatted = parag;
+ if ( !parag->isValid() )
+ parag->format();
+
+ TQRect pr = parag->rect();
+ pr.setWidth( parag->document()->width() );
+ if ( pr.y() > cy + ch )
+ goto floating;
+ TQRect clipr( cx, cy, cw, ch );
+ if ( !pr.intersects( clipr ) || ( onlyChanged && !parag->hasChanged() ) ) {
+ pr.setWidth( parag->document()->width() );
+ parag = parag->next();
+ continue;
+ }
+
+ drawParagraph( p, parag, cx, cy, cw, ch, doubleBuffer, cg, drawCursor, cursor, resetChanged );
+ parag = parag->next();
+ }
+
+ parag = lastParagraph();
+
+ floating:
+ if ( parag->rect().y() + parag->rect().height() < parag->document()->height() ) {
+ if ( !parag->document()->tqparent() ) {
+ TQRect fillRect = TQRect( 0, parag->rect().y() + parag->rect().height(), parag->document()->width(),
+ parag->document()->height() - ( parag->rect().y() + parag->rect().height() ) );
+ if ( TQRect( cx, cy, cw, ch ).intersects( fillRect ) )
+ p->fillRect( fillRect, cg.brush( TQColorGroup::Base ) );
+ }
+ if ( !flow()->isEmpty() ) {
+ TQRect cr( cx, cy, cw, ch );
+ flow()->drawFloatingItems( p, cr.x(), cr.y(), cr.width(), cr.height(), cg, FALSE );
+ }
+ }
+
+ if ( buf_pixmap && buf_pixmap->height() > 300 ) {
+ delete buf_pixmap;
+ buf_pixmap = 0;
+ }
+
+ TQTextFormat::setPainter(oldPainter);
+ return lastFormatted;
+}
+
+/*
+ #### this function only sets the default font size in the format collection
+ */
+void TQTextDocument::setDefaultFormat( const TQFont &font, const TQColor &color )
+{
+ bool reformat = font != fCollection->defaultFormat()->font();
+ for ( TQTextDocument *d = childList.first(); d; d = childList.next() )
+ d->setDefaultFormat( font, color );
+ fCollection->updateDefaultFormat( font, color, sheet_ );
+
+ if ( !reformat )
+ return;
+ tStopWidth = formatCollection()->defaultFormat()->width( 'x' ) * 8;
+
+ // tqinvalidate paragraphs and custom items
+ TQTextParagraph *p = fParag;
+ while ( p ) {
+ p->tqinvalidate( 0 );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ for ( int i = 0; i < p->length() - 1; ++i )
+ if ( p->at( i )->isCustom() )
+ p->at( i )->customItem()->tqinvalidate();
+#endif
+ p = p->next();
+ }
+}
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+void TQTextDocument::registerCustomItem( TQTextCustomItem *i, TQTextParagraph *p )
+{
+ if ( i && i->placement() != TQTextCustomItem::PlaceInline ) {
+ flow_->registerFloatingItem( i );
+ p->registerFloatingItem( i );
+ }
+ if (i) i->setParagraph( p );
+ p->mightHaveCustomItems = mightHaveCustomItems = TRUE;
+}
+
+void TQTextDocument::unregisterCustomItem( TQTextCustomItem *i, TQTextParagraph *p )
+{
+ p->unregisterFloatingItem( i );
+ i->setParagraph( 0 );
+ flow_->unregisterFloatingItem( i );
+}
+#endif
+
+bool TQTextDocument::hasFocusParagraph() const
+{
+ return !!focusIndicator.parag;
+}
+
+TQString TQTextDocument::focusHref() const
+{
+ return focusIndicator.href;
+}
+
+TQString TQTextDocument::focusName() const
+{
+ return focusIndicator.name;
+}
+
+bool TQTextDocument::focusNextPrevChild( bool next )
+{
+ if ( !focusIndicator.parag ) {
+ if ( next ) {
+ focusIndicator.parag = fParag;
+ focusIndicator.start = 0;
+ focusIndicator.len = 0;
+ } else {
+ focusIndicator.parag = lParag;
+ focusIndicator.start = lParag->length();
+ focusIndicator.len = 0;
+ }
+ } else {
+ focusIndicator.parag->setChanged( TRUE );
+ }
+ focusIndicator.href = TQString::null;
+ focusIndicator.name = TQString::null;
+
+ if ( next ) {
+ TQTextParagraph *p = focusIndicator.parag;
+ int index = focusIndicator.start + focusIndicator.len;
+ while ( p ) {
+ for ( int i = index; i < p->length(); ++i ) {
+ if ( p->at( i )->isAnchor() ) {
+ p->setChanged( TRUE );
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = p->at( i )->anchorHref();
+ focusIndicator.name = p->at( i )->anchorName();
+ while ( i < p->length() ) {
+ if ( !p->at( i )->isAnchor() )
+ return TRUE;
+ focusIndicator.len++;
+ i++;
+ }
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ } else if ( p->at( i )->isCustom() ) {
+ if ( p->at( i )->customItem()->isNested() ) {
+ TQTextTable *t = (TQTextTable*)p->at( i )->customItem();
+ TQPtrList<TQTextTableCell> cells = t->tableCells();
+ // first try to continue
+ TQTextTableCell *c;
+ bool resetCells = TRUE;
+ for ( c = cells.first(); c; c = cells.next() ) {
+ if ( c->richText()->hasFocusParagraph() ) {
+ if ( c->richText()->focusNextPrevChild( next ) ) {
+ p->setChanged( TRUE );
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = c->richText()->focusHref();
+ focusIndicator.name = c->richText()->focusName();
+ return TRUE;
+ } else {
+ resetCells = FALSE;
+ c = cells.next();
+ break;
+ }
+ }
+ }
+ // now really try
+ if ( resetCells )
+ c = cells.first();
+ for ( ; c; c = cells.next() ) {
+ if ( c->richText()->focusNextPrevChild( next ) ) {
+ p->setChanged( TRUE );
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = c->richText()->focusHref();
+ focusIndicator.name = c->richText()->focusName();
+ return TRUE;
+ }
+ }
+ }
+#endif
+ }
+ }
+ index = 0;
+ p = p->next();
+ }
+ } else {
+ TQTextParagraph *p = focusIndicator.parag;
+ int index = focusIndicator.start - 1;
+ if ( focusIndicator.len == 0 && index < focusIndicator.parag->length() - 1 )
+ index++;
+ while ( p ) {
+ for ( int i = index; i >= 0; --i ) {
+ if ( p->at( i )->isAnchor() ) {
+ p->setChanged( TRUE );
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = p->at( i )->anchorHref();
+ focusIndicator.name = p->at( i )->anchorName();
+ while ( i >= -1 ) {
+ if ( i < 0 || !p->at( i )->isAnchor() ) {
+ focusIndicator.start++;
+ return TRUE;
+ }
+ if ( i < 0 )
+ break;
+ focusIndicator.len++;
+ focusIndicator.start--;
+ i--;
+ }
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ } else if ( p->at( i )->isCustom() ) {
+ if ( p->at( i )->customItem()->isNested() ) {
+ TQTextTable *t = (TQTextTable*)p->at( i )->customItem();
+ TQPtrList<TQTextTableCell> cells = t->tableCells();
+ // first try to continue
+ TQTextTableCell *c;
+ bool resetCells = TRUE;
+ for ( c = cells.last(); c; c = cells.prev() ) {
+ if ( c->richText()->hasFocusParagraph() ) {
+ if ( c->richText()->focusNextPrevChild( next ) ) {
+ p->setChanged( TRUE );
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = c->richText()->focusHref();
+ focusIndicator.name = c->richText()->focusName();
+ return TRUE;
+ } else {
+ resetCells = FALSE;
+ c = cells.prev();
+ break;
+ }
+ }
+ if ( cells.at() == 0 )
+ break;
+ }
+ // now really try
+ if ( resetCells )
+ c = cells.last();
+ for ( ; c; c = cells.prev() ) {
+ if ( c->richText()->focusNextPrevChild( next ) ) {
+ p->setChanged( TRUE );
+ focusIndicator.parag = p;
+ focusIndicator.start = i;
+ focusIndicator.len = 0;
+ focusIndicator.href = c->richText()->focusHref();
+ focusIndicator.name = c->richText()->focusName();
+ return TRUE;
+ }
+ if ( cells.at() == 0 )
+ break;
+ }
+ }
+#endif
+ }
+ }
+ p = p->prev();
+ if ( p )
+ index = p->length() - 1;
+ }
+ }
+
+ focusIndicator.parag = 0;
+
+ return FALSE;
+}
+
+int TQTextDocument::length() const
+{
+ int l = -1;
+ TQTextParagraph *p = fParag;
+ while ( p ) {
+ l += p->length();
+ p = p->next();
+ }
+ return TQMAX(0,l);
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+int TQTextFormat::width( const TQChar &c ) const
+{
+ if ( c.tqunicode() == 0xad ) // soft hyphen
+ return 0;
+ if ( !pntr || !pntr->isActive() ) {
+ if ( c == '\t' )
+ return fm.width( ' ' );
+ if ( ha == AlignNormal ) {
+ int w;
+ if ( c.row() )
+ w = fm.width( c );
+ else
+ w = widths[ c.tqunicode() ];
+ if ( w == 0 && !c.row() ) {
+ w = fm.width( c );
+ ( (TQTextFormat*)this )->widths[ c.tqunicode() ] = w;
+ }
+ return w;
+ } else {
+ TQFont f( fn );
+ if ( usePixelSizes )
+ f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
+ else
+ f.setPointSize( ( f.pointSize() * 2 ) / 3 );
+ TQFontMetrics fm_( f );
+ return fm_.width( c );
+ }
+ }
+
+ TQFont f( fn );
+ if ( ha != AlignNormal ) {
+ if ( usePixelSizes )
+ f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
+ else
+ f.setPointSize( ( f.pointSize() * 2 ) / 3 );
+ }
+ applyFont( f );
+
+ return pntr_fm->width( c );
+}
+
+int TQTextFormat::width( const TQString &str, int pos ) const
+{
+ int w = 0;
+ if ( str.tqunicode()[ pos ].tqunicode() == 0xad )
+ return w;
+ if ( !pntr || !pntr->isActive() ) {
+ if ( ha == AlignNormal ) {
+ w = fm.charWidth( str, pos );
+ } else {
+ TQFont f( fn );
+ if ( usePixelSizes )
+ f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
+ else
+ f.setPointSize( ( f.pointSize() * 2 ) / 3 );
+ TQFontMetrics fm_( f );
+ w = fm_.charWidth( str, pos );
+ }
+ } else {
+ TQFont f( fn );
+ if ( ha != AlignNormal ) {
+ if ( usePixelSizes )
+ f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
+ else
+ f.setPointSize( ( f.pointSize() * 2 ) / 3 );
+ }
+ applyFont( f );
+ w = pntr_fm->charWidth( str, pos );
+ }
+ return w;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextString::TQTextString()
+{
+ bidiDirty = TRUE;
+ bidi = FALSE;
+ rightToLeft = FALSE;
+ dir = TQChar::DirON;
+}
+
+TQTextString::TQTextString( const TQTextString &s )
+{
+ bidiDirty = TRUE;
+ bidi = s.bidi;
+ rightToLeft = s.rightToLeft;
+ dir = s.dir;
+ data = s.data;
+ data.detach();
+ for ( int i = 0; i < (int)data.size(); ++i ) {
+ TQTextFormat *f = data[i].format();
+ if ( f )
+ f->addRef();
+ }
+}
+
+void TQTextString::insert( int index, const QString &s, TQTextFormat *f )
+{
+ insert( index, s.tqunicode(), s.length(), f );
+}
+
+void TQTextString::insert( int index, const QChar *tqunicode, int len, TQTextFormat *f )
+{
+ int os = data.size();
+ data.resize( data.size() + len, TQGArray::SpeedOptim );
+ if ( index < os ) {
+ memmove( data.data() + index + len, data.data() + index,
+ sizeof( TQTextStringChar ) * ( os - index ) );
+ }
+ TQTextStringChar *ch = data.data() + index;
+ for ( int i = 0; i < len; ++i ) {
+ ch->x = 0;
+ ch->lineStart = 0;
+ ch->d.format = 0;
+ ch->nobreak = FALSE;
+ ch->type = TQTextStringChar::Regular;
+ ch->d.format = f;
+ ch->rightToLeft = 0;
+ ch->c = tqunicode[i];
+ ++ch;
+ }
+ bidiDirty = TRUE;
+}
+
+TQTextString::~TQTextString()
+{
+ clear();
+}
+
+void TQTextString::insert( int index, TQTextStringChar *c, bool doAddRefFormat )
+{
+ int os = data.size();
+ data.resize( data.size() + 1, TQGArray::SpeedOptim );
+ if ( index < os ) {
+ memmove( data.data() + index + 1, data.data() + index,
+ sizeof( TQTextStringChar ) * ( os - index ) );
+ }
+ TQTextStringChar &ch = data[ (int)index ];
+ ch.c = c->c;
+ ch.x = 0;
+ ch.lineStart = 0;
+ ch.rightToLeft = 0;
+ ch.d.format = 0;
+ ch.type = TQTextStringChar::Regular;
+ ch.nobreak = FALSE;
+ if ( doAddRefFormat && c->format() )
+ c->format()->addRef();
+ ch.setFormat( c->format() );
+ bidiDirty = TRUE;
+}
+
+int TQTextString::appendParagraphs( TQTextParagraph *start, TQTextParagraph *end )
+{
+ int paragCount = 0;
+ int newLength = data.size();
+ TQTextParagraph *p = start;
+ for (; p != end; p = p->next()) {
+ newLength += p->length();
+ ++paragCount;
+ }
+
+ const int oldLength = data.size();
+ data.resize(newLength, TQGArray::SpeedOptim);
+
+ TQTextStringChar *d = &data[oldLength];
+ for (p = start; p != end; p = p->next()) {
+ const TQTextStringChar * const src = p->at(0);
+ int i = 0;
+ for (; i < p->length() - 1; ++i) {
+ d[i].c = src[i].c;
+ d[i].x = 0;
+ d[i].lineStart = 0;
+ d[i].rightToLeft = 0;
+ d[i].type = TQTextStringChar::Regular;
+ d[i].nobreak = FALSE;
+ d[i].d.format = src[i].format();
+ if (d[i].d.format)
+ d[i].d.format->addRef();
+ }
+ d[i].x = 0;
+ d[i].lineStart = 0;
+ d[i].nobreak = FALSE;
+ d[i].type = TQTextStringChar::Regular;
+ d[i].d.format = 0;
+ d[i].rightToLeft = 0;
+ d[i].c = '\n';
+ d += p->length();
+ }
+
+ bidiDirty = TRUE;
+ return paragCount;
+}
+
+void TQTextString::truncate( int index )
+{
+ index = TQMAX( index, 0 );
+ index = TQMIN( index, (int)data.size() - 1 );
+ if ( index < (int)data.size() ) {
+ for ( int i = index + 1; i < (int)data.size(); ++i ) {
+ TQTextStringChar &ch = data[ i ];
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( !(ch.type == TQTextStringChar::Regular) ) {
+ delete ch.customItem();
+ if ( ch.d.custom->format )
+ ch.d.custom->format->removeRef();
+ delete ch.d.custom;
+ ch.d.custom = 0;
+ } else
+#endif
+ if ( ch.format() ) {
+ ch.format()->removeRef();
+ }
+ }
+ }
+ data.truncate( index );
+ bidiDirty = TRUE;
+}
+
+void TQTextString::remove( int index, int len )
+{
+ for ( int i = index; i < (int)data.size() && i - index < len; ++i ) {
+ TQTextStringChar &ch = data[ i ];
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( !(ch.type == TQTextStringChar::Regular) ) {
+ delete ch.customItem();
+ if ( ch.d.custom->format )
+ ch.d.custom->format->removeRef();
+ delete ch.d.custom;
+ ch.d.custom = 0;
+ } else
+#endif
+ if ( ch.format() ) {
+ ch.format()->removeRef();
+ }
+ }
+ memmove( data.data() + index, data.data() + index + len,
+ sizeof( TQTextStringChar ) * ( data.size() - index - len ) );
+ data.resize( data.size() - len, TQGArray::SpeedOptim );
+ bidiDirty = TRUE;
+}
+
+void TQTextString::clear()
+{
+ for ( int i = 0; i < (int)data.count(); ++i ) {
+ TQTextStringChar &ch = data[ i ];
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( !(ch.type == TQTextStringChar::Regular) ) {
+ if ( ch.customItem() && ch.customItem()->placement() == TQTextCustomItem::PlaceInline )
+ delete ch.customItem();
+ if ( ch.d.custom->format )
+ ch.d.custom->format->removeRef();
+ delete ch.d.custom;
+ ch.d.custom = 0;
+ } else
+#endif
+ if ( ch.format() ) {
+ ch.format()->removeRef();
+ }
+ }
+ data.resize( 0 );
+ bidiDirty = TRUE;
+}
+
+void TQTextString::setFormat( int index, TQTextFormat *f, bool useCollection )
+{
+ TQTextStringChar &ch = data[ index ];
+ if ( useCollection && ch.format() )
+ ch.format()->removeRef();
+ ch.setFormat( f );
+}
+
+void TQTextString::checkBidi() const
+{
+ TQTextString *that = (TQTextString *)this;
+ that->bidiDirty = FALSE;
+ int length = data.size();
+ if ( !length ) {
+ that->bidi = FALSE;
+ that->rightToLeft = dir == TQChar::DirR;
+ return;
+ }
+ const TQTextStringChar *start = data.data();
+ const TQTextStringChar *end = start + length;
+
+ ((TQTextString *)this)->stringCache = toString(data);
+
+
+ // determines the properties we need for layouting
+ TQTextEngine textEngine( toString(), 0 );
+ textEngine.direction = (TQChar::Direction) dir;
+ textEngine.itemize(TQTextEngine::SingleLine);
+ const TQCharAttributes *ca = textEngine.attributes() + length-1;
+ TQTextStringChar *ch = (TQTextStringChar *)end - 1;
+ TQScriptItem *item = &textEngine.items[textEngine.items.size()-1];
+ unsigned char bidiLevel = item->analysis.bidiLevel;
+ if ( bidiLevel )
+ that->bidi = TRUE;
+ int pos = length-1;
+ while ( ch >= start ) {
+ if ( item->position > pos ) {
+ --item;
+ TQ_ASSERT( item >= &textEngine.items[0] );
+ TQ_ASSERT( item < &textEngine.items[textEngine.items.size()] );
+ bidiLevel = item->analysis.bidiLevel;
+ if ( bidiLevel )
+ that->bidi = TRUE;
+ }
+ ch->softBreak = ca->softBreak;
+ ch->whiteSpace = ca->whiteSpace;
+ ch->charStop = ca->charStop;
+ ch->wordStop = ca->wordStop;
+ ch->bidiLevel = bidiLevel;
+ ch->rightToLeft = (bidiLevel%2);
+ --ch;
+ --ca;
+ --pos;
+ }
+
+ if ( dir == TQChar::DirR ) {
+ that->bidi = TRUE;
+ that->rightToLeft = TRUE;
+ } else if ( dir == TQChar::DirL ) {
+ that->rightToLeft = FALSE;
+ } else {
+ that->rightToLeft = (textEngine.direction == TQChar::DirR);
+ }
+}
+
+void TQTextDocument::setStyleSheet( TQStyleSheet *s )
+{
+ if ( !s )
+ return;
+ sheet_ = s;
+ list_tm = list_bm = par_tm = par_bm = 12;
+ list_lm = 40;
+ li_tm = li_bm = 0;
+ TQStyleSheetItem* item = s->item( "ol" );
+ if ( item ) {
+ list_tm = TQMAX(0,item->margin( TQStyleSheetItem::MarginTop ));
+ list_bm = TQMAX(0,item->margin( TQStyleSheetItem::MarginBottom ));
+ list_lm = TQMAX(0,item->margin( TQStyleSheetItem::MarginLeft ));
+ }
+ if ( (item = s->item( "li" ) ) ) {
+ li_tm = TQMAX(0,item->margin( TQStyleSheetItem::MarginTop ));
+ li_bm = TQMAX(0,item->margin( TQStyleSheetItem::MarginBottom ));
+ }
+ if ( (item = s->item( "p" ) ) ) {
+ par_tm = TQMAX(0,item->margin( TQStyleSheetItem::MarginTop ));
+ par_bm = TQMAX(0,item->margin( TQStyleSheetItem::MarginBottom ));
+ }
+}
+
+void TQTextDocument::setUnderlineLinks( bool b ) {
+ underlLinks = b;
+ for ( TQTextDocument *d = childList.first(); d; d = childList.next() )
+ d->setUnderlineLinks( b );
+}
+
+void TQTextStringChar::setFormat( TQTextFormat *f )
+{
+ if ( type == Regular ) {
+ d.format = f;
+ } else {
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( !d.custom ) {
+ d.custom = new CustomData;
+ d.custom->custom = 0;
+ }
+ d.custom->format = f;
+#endif
+ }
+}
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+void TQTextStringChar::setCustomItem( TQTextCustomItem *i )
+{
+ if ( type == Regular ) {
+ TQTextFormat *f = format();
+ d.custom = new CustomData;
+ d.custom->format = f;
+ } else {
+ delete d.custom->custom;
+ }
+ d.custom->custom = i;
+ type = (type == Anchor ? CustomAnchor : Custom);
+}
+
+void TQTextStringChar::loseCustomItem()
+{
+ if ( type == Custom ) {
+ TQTextFormat *f = d.custom->format;
+ d.custom->custom = 0;
+ delete d.custom;
+ type = Regular;
+ d.format = f;
+ } else if ( type == CustomAnchor ) {
+ d.custom->custom = 0;
+ type = Anchor;
+ }
+}
+
+#endif
+
+TQString TQTextStringChar::anchorName() const
+{
+ if ( type == Regular )
+ return TQString::null;
+ else
+ return d.custom->anchorName;
+}
+
+TQString TQTextStringChar::anchorHref() const
+{
+ if ( type == Regular )
+ return TQString::null;
+ else
+ return d.custom->anchorHref;
+}
+
+void TQTextStringChar::setAnchor( const TQString& name, const TQString& href )
+{
+ if ( type == Regular ) {
+ TQTextFormat *f = format();
+ d.custom = new CustomData;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ d.custom->custom = 0;
+#endif
+ d.custom->format = f;
+ type = Anchor;
+ } else if ( type == Custom ) {
+ type = CustomAnchor;
+ }
+ d.custom->anchorName = name;
+ d.custom->anchorHref = href;
+}
+
+
+int TQTextString::width( int idx ) const
+{
+ int w = 0;
+ TQTextStringChar *c = &at( idx );
+ if ( !c->charStop || c->c.tqunicode() == 0xad || c->c.tqunicode() == 0x2028 )
+ return 0;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if( c->isCustom() ) {
+ if( c->customItem()->placement() == TQTextCustomItem::PlaceInline )
+ w = c->customItem()->width;
+ } else
+#endif
+ {
+ int r = c->c.row();
+ if(r < 0x06
+#ifndef TQ_WS_WIN
+ // Uniscribe's handling of Asian makes the condition below fail.
+ || (r > 0x1f && !(r > 0xd7 && r < 0xe0))
+#endif
+ ) {
+ w = c->format()->width( c->c );
+ } else {
+ w = c->format()->width(toString(), idx);
+ }
+ }
+ return w;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextParagraph::TQTextParagraph( TQTextDocument *d, TQTextParagraph *pr, TQTextParagraph *nx, bool updateIds )
+ : p( pr ), n( nx ), docOrPseudo( d ),
+ changed(FALSE), firstFormat(TRUE), firstPProcess(TRUE), needPreProcess(FALSE), fullWidth(TRUE),
+ lastInFrame(FALSE), visible(TRUE), breakable(TRUE), movedDown(FALSE),
+ mightHaveCustomItems(FALSE), hasdoc( d != 0 ), litem(FALSE), rtext(FALSE),
+ align( 0 ), lstyle( TQStyleSheetItem::ListDisc ), invalid( 0 ), mSelections( 0 ),
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ mFloatingItems( 0 ),
+#endif
+ utm( 0 ), ubm( 0 ), ulm( 0 ), urm( 0 ), uflm( 0 ), ulinespacing( 0 ),
+ tabStopWidth(0), minwidth(0), tArray(0), eData( 0 ), ldepth( 0 )
+{
+ lstyle = TQStyleSheetItem::ListDisc;
+ if ( !hasdoc )
+ docOrPseudo = new TQTextParagraphPseudoDocument;
+ bgcol = 0;
+ list_val = -1;
+ painttqdevice = 0;
+ TQTextFormat* defFormat = formatCollection()->defaultFormat();
+ if ( !hasdoc ) {
+ tabStopWidth = defFormat->width( 'x' ) * 8;
+ pseudoDocument()->commandHistory = new TQTextCommandHistory( 100 );
+ }
+
+ if ( p )
+ p->n = this;
+ if ( n )
+ n->p = this;
+
+ if ( !p && hasdoc )
+ document()->setFirstParagraph( this );
+ if ( !n && hasdoc )
+ document()->setLastParagraph( this );
+
+ state = -1;
+
+ if ( p )
+ id = p->id + 1;
+ else
+ id = 0;
+ if ( n && updateIds ) {
+ TQTextParagraph *s = n;
+ while ( s ) {
+ s->id = s->p->id + 1;
+ s->invalidateStyleCache();
+ s = s->n;
+ }
+ }
+
+ str = new TQTextString();
+ TQChar ch(' ');
+ str->insert( 0, &ch, 1, formatCollection()->defaultFormat() );
+}
+
+TQTextParagraph::~TQTextParagraph()
+{
+ delete str;
+ if ( hasdoc ) {
+ register TQTextDocument *doc = document();
+ if ( this == doc->minwParag ) {
+ doc->minwParag = 0;
+ doc->minw = 0;
+ }
+ if ( this == doc->curParag )
+ doc->curParag = 0;
+ } else {
+ delete pseudoDocument();
+ }
+ delete [] tArray;
+ delete eData;
+ QMap<int, TQTextLineStart*>::Iterator it = lineStarts.begin();
+ for ( ; it != lineStarts.end(); ++it )
+ delete *it;
+ if ( mSelections )
+ delete mSelections;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( mFloatingItems )
+ delete mFloatingItems;
+#endif
+ if ( p )
+ p->setNext( n );
+ if ( n )
+ n->setPrev( p );
+ delete bgcol;
+}
+
+void TQTextParagraph::setNext( TQTextParagraph *s )
+{
+ n = s;
+ if ( !n && hasdoc )
+ document()->setLastParagraph( this );
+}
+
+void TQTextParagraph::setPrev( TQTextParagraph *s )
+{
+ p = s;
+ if ( !p && hasdoc )
+ document()->setFirstParagraph( this );
+}
+
+void TQTextParagraph::tqinvalidate( int chr )
+{
+ if ( invalid < 0 )
+ invalid = chr;
+ else
+ invalid = TQMIN( invalid, chr );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( mFloatingItems ) {
+ for ( TQTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() )
+ i->ypos = -1;
+ }
+#endif
+ invalidateStyleCache();
+}
+
+void TQTextParagraph::invalidateStyleCache()
+{
+ if ( list_val < 0 )
+ list_val = -1;
+}
+
+
+void TQTextParagraph::insert( int index, const QString &s )
+{
+ insert( index, s.tqunicode(), s.length() );
+}
+
+void TQTextParagraph::insert( int index, const QChar *tqunicode, int len )
+{
+ if ( hasdoc && !document()->useFormatCollection() && document()->preProcessor() )
+ str->insert( index, tqunicode, len,
+ document()->preProcessor()->format( TQTextPreProcessor::Standard ) );
+ else
+ str->insert( index, tqunicode, len, formatCollection()->defaultFormat() );
+ tqinvalidate( index );
+ needPreProcess = TRUE;
+}
+
+void TQTextParagraph::truncate( int index )
+{
+ str->truncate( index );
+ insert( length(), " " );
+ needPreProcess = TRUE;
+}
+
+void TQTextParagraph::remove( int index, int len )
+{
+ if ( index + len - str->length() > 0 )
+ return;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ for ( int i = index; i < index + len; ++i ) {
+ TQTextStringChar *c = at( i );
+ if ( hasdoc && c->isCustom() ) {
+ document()->unregisterCustomItem( c->customItem(), this );
+ }
+ }
+#endif
+ str->remove( index, len );
+ tqinvalidate( 0 );
+ needPreProcess = TRUE;
+}
+
+void TQTextParagraph::join( TQTextParagraph *s )
+{
+ int oh = r.height() + s->r.height();
+ n = s->n;
+ if ( n )
+ n->p = this;
+ else if ( hasdoc )
+ document()->setLastParagraph( this );
+
+ int start = str->length();
+ if ( length() > 0 && at( length() - 1 )->c == ' ' ) {
+ remove( length() - 1, 1 );
+ --start;
+ }
+ append( s->str->toString(), TRUE );
+
+ for ( int i = 0; i < s->length(); ++i ) {
+ if ( !hasdoc || document()->useFormatCollection() ) {
+ s->str->at( i ).format()->addRef();
+ str->setFormat( i + start, s->str->at( i ).format(), TRUE );
+ }
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( s->str->at( i ).isCustom() ) {
+ TQTextCustomItem * item = s->str->at( i ).customItem();
+ str->at( i + start ).setCustomItem( item );
+ s->str->at( i ).loseCustomItem();
+ if ( hasdoc ) {
+ document()->unregisterCustomItem( item, s );
+ document()->registerCustomItem( item, this );
+ }
+ }
+ if ( s->str->at( i ).isAnchor() ) {
+ str->at( i + start ).setAnchor( s->str->at( i ).anchorName(),
+ s->str->at( i ).anchorHref() );
+ }
+#endif
+ }
+
+ if ( !extraData() && s->extraData() ) {
+ setExtraData( s->extraData() );
+ s->setExtraData( 0 );
+ } else if ( extraData() && s->extraData() ) {
+ extraData()->join( s->extraData() );
+ }
+ delete s;
+ tqinvalidate( 0 );
+ r.setHeight( oh );
+ needPreProcess = TRUE;
+ if ( n ) {
+ TQTextParagraph *s = n;
+ s->tqinvalidate( 0 );
+ while ( s ) {
+ s->id = s->p->id + 1;
+ s->state = -1;
+ s->needPreProcess = TRUE;
+ s->changed = TRUE;
+ s->invalidateStyleCache();
+ s = s->n;
+ }
+ }
+ format();
+ state = -1;
+}
+
+void TQTextParagraph::move( int &dy )
+{
+ if ( dy == 0 )
+ return;
+ changed = TRUE;
+ r.moveBy( 0, dy );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( mFloatingItems ) {
+ for ( TQTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() )
+ i->ypos += dy;
+ }
+#endif
+ if ( p )
+ p->lastInFrame = TRUE;
+
+ // do page breaks if required
+ if ( hasdoc && document()->isPageBreakEnabled() ) {
+ int shift;
+ if ( ( shift = document()->formatter()->formatVertically( document(), this ) ) ) {
+ if ( p )
+ p->setChanged( TRUE );
+ dy += shift;
+ }
+ }
+}
+
+void TQTextParagraph::format( int start, bool doMove )
+{
+ if ( !str || str->length() == 0 || !formatter() )
+ return;
+
+ if ( hasdoc &&
+ document()->preProcessor() &&
+ ( needPreProcess || state == -1 ) )
+ document()->preProcessor()->process( document(), this, invalid <= 0 ? 0 : invalid );
+ needPreProcess = FALSE;
+
+ if ( invalid == -1 )
+ return;
+
+ r.moveTopLeft( TQPoint( documentX(), p ? p->r.y() + p->r.height() : documentY() ) );
+ if ( p )
+ p->lastInFrame = FALSE;
+
+ movedDown = FALSE;
+ bool formattedAgain = FALSE;
+
+ formatAgain:
+
+ r.setWidth( documentWidth() );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( hasdoc && mFloatingItems ) {
+ for ( TQTextCustomItem *i = mFloatingItems->first(); i; i = mFloatingItems->next() ) {
+ i->ypos = r.y();
+ if ( i->placement() == TQTextCustomItem::PlaceRight ) {
+ i->xpos = r.x() + r.width() - i->width;
+ }
+ }
+ }
+#endif
+ QMap<int, TQTextLineStart*> oldLineStarts = lineStarts;
+ lineStarts.clear();
+ int y = formatter()->format( document(), this, start, oldLineStarts );
+
+
+ r.setWidth( TQMAX( r.width(), formatter()->minimumWidth() ) );
+
+
+ QMap<int, TQTextLineStart*>::Iterator it = oldLineStarts.begin();
+
+ for ( ; it != oldLineStarts.end(); ++it )
+ delete *it;
+
+ if ( !hasdoc ) { // qt_format_text bounding rect handling
+ it = lineStarts.begin();
+ int usedw = 0;
+ for ( ; it != lineStarts.end(); ++it )
+ usedw = TQMAX( usedw, (*it)->w );
+ if ( r.width() <= 0 ) {
+ // if the user specifies an invalid rect, this means that the
+ // bounding box should grow to the width that the text actually
+ // needs
+ r.setWidth( usedw );
+ } else {
+ r.setWidth( TQMIN( usedw, r.width() ) );
+ }
+ }
+
+ if ( y != r.height() )
+ r.setHeight( y );
+
+ if ( !visible ) {
+ r.setHeight( 0 );
+ } else {
+ int minw = minwidth = formatter()->minimumWidth();
+ int wused = formatter()->widthUsed();
+ wused = TQMAX( minw, wused );
+ if ( hasdoc ) {
+ document()->setMinimumWidth( minw, wused, this );
+ } else {
+ pseudoDocument()->minw = TQMAX( pseudoDocument()->minw, minw );
+ pseudoDocument()->wused = TQMAX( pseudoDocument()->wused, wused );
+ }
+ }
+
+ // do page breaks if required
+ if ( hasdoc && document()->isPageBreakEnabled() ) {
+ int shift = document()->formatter()->formatVertically( document(), this );
+ if ( shift && !formattedAgain ) {
+ formattedAgain = TRUE;
+ goto formatAgain;
+ }
+ }
+
+ if ( n && doMove && n->invalid == -1 && r.y() + r.height() != n->r.y() ) {
+ int dy = ( r.y() + r.height() ) - n->r.y();
+ TQTextParagraph *s = n;
+ bool makeInvalid = p && p->lastInFrame;
+ while ( s && dy ) {
+ if ( !s->isFullWidth() )
+ makeInvalid = TRUE;
+ if ( makeInvalid )
+ s->tqinvalidate( 0 );
+ s->move( dy );
+ if ( s->lastInFrame )
+ makeInvalid = TRUE;
+ s = s->n;
+ }
+ }
+
+ firstFormat = FALSE;
+ changed = TRUE;
+ invalid = -1;
+ //##### string()->setTextChanged( FALSE );
+}
+
+int TQTextParagraph::lineHeightOfChar( int i, int *bl, int *y ) const
+{
+ if ( !isValid() )
+ ( (TQTextParagraph*)this )->format();
+
+ QMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.end();
+ --it;
+ for ( ;; ) {
+ if ( i >= it.key() ) {
+ if ( bl )
+ *bl = ( *it )->baseLine;
+ if ( y )
+ *y = ( *it )->y;
+ return ( *it )->h;
+ }
+ if ( it == lineStarts.begin() )
+ break;
+ --it;
+ }
+
+ qWarning( "TQTextParagraph::lineHeightOfChar: couldn't tqfind lh for %d", i );
+ return 15;
+}
+
+TQTextStringChar *TQTextParagraph::lineStartOfChar( int i, int *index, int *line ) const
+{
+ if ( !isValid() )
+ ( (TQTextParagraph*)this )->format();
+
+ int l = (int)lineStarts.count() - 1;
+ QMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.end();
+ --it;
+ for ( ;; ) {
+ if ( i >= it.key() ) {
+ if ( index )
+ *index = it.key();
+ if ( line )
+ *line = l;
+ return &str->at( it.key() );
+ }
+ if ( it == lineStarts.begin() )
+ break;
+ --it;
+ --l;
+ }
+
+ qWarning( "TQTextParagraph::lineStartOfChar: couldn't tqfind %d", i );
+ return 0;
+}
+
+int TQTextParagraph::lines() const
+{
+ if ( !isValid() )
+ ( (TQTextParagraph*)this )->format();
+
+ return (int)lineStarts.count();
+}
+
+TQTextStringChar *TQTextParagraph::lineStartOfLine( int line, int *index ) const
+{
+ if ( !isValid() )
+ ( (TQTextParagraph*)this )->format();
+
+ if ( line >= 0 && line < (int)lineStarts.count() ) {
+ QMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while ( line-- > 0 )
+ ++it;
+ int i = it.key();
+ if ( index )
+ *index = i;
+ return &str->at( i );
+ }
+
+ qWarning( "TQTextParagraph::lineStartOfLine: couldn't tqfind %d", line );
+ return 0;
+}
+
+int TQTextParagraph::leftGap() const
+{
+ if ( !isValid() )
+ ( (TQTextParagraph*)this )->format();
+
+ if ( str->length() == 0)
+ return 0;
+
+ int line = 0;
+ int x = str->length() ? str->at(0).x : 0; /* set x to x of first char */
+ if ( str->isBidi() ) {
+ for ( int i = 1; i < str->length()-1; ++i )
+ x = TQMIN(x, str->at(i).x);
+ return x;
+ }
+
+ QMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while (line < (int)lineStarts.count()) {
+ int i = it.key(); /* char index */
+ x = TQMIN(x, str->at(i).x);
+ ++it;
+ ++line;
+ }
+ return x;
+}
+
+void TQTextParagraph::setFormat( int index, int len, TQTextFormat *f, bool useCollection, int flags )
+{
+ if ( !f )
+ return;
+ if ( index < 0 )
+ index = 0;
+ if ( index > str->length() - 1 )
+ index = str->length() - 1;
+ if ( index + len >= str->length() )
+ len = str->length() - index;
+
+ TQTextFormatCollection *fc = 0;
+ if ( useCollection )
+ fc = formatCollection();
+ TQTextFormat *of;
+ for ( int i = 0; i < len; ++i ) {
+ of = str->at( i + index ).format();
+ if ( !changed && ( !of || f->key() != of->key() ) )
+ changed = TRUE;
+ if ( invalid == -1 &&
+ ( f->font().family() != of->font().family() ||
+ f->font().pointSize() != of->font().pointSize() ||
+ f->font().weight() != of->font().weight() ||
+ f->font().italic() != of->font().italic() ||
+ f->vAlign() != of->vAlign() ) ) {
+ tqinvalidate( 0 );
+ }
+ if ( flags == -1 || flags == TQTextFormat::Format || !fc ) {
+ if ( fc )
+ f = fc->format( f );
+ str->setFormat( i + index, f, useCollection );
+ } else {
+ TQTextFormat *fm = fc->format( of, f, flags );
+ str->setFormat( i + index, fm, useCollection );
+ }
+ }
+}
+
+void TQTextParagraph::indent( int *oldIndent, int *newIndent )
+{
+ if ( !hasdoc || !document()->indent() || isListItem() ) {
+ if ( oldIndent )
+ *oldIndent = 0;
+ if ( newIndent )
+ *newIndent = 0;
+ if ( oldIndent && newIndent )
+ *newIndent = *oldIndent;
+ return;
+ }
+ document()->indent()->indent( document(), this, oldIndent, newIndent );
+}
+
+void TQTextParagraph::paint( TQPainter &painter, const TQColorGroup &cg, TQTextCursor *cursor, bool drawSelections,
+ int clipx, int clipy, int clipw, int cliph )
+{
+ if ( !visible )
+ return;
+ int i, y, h, baseLine, xstart, xend = 0;
+ i = y =h = baseLine = 0;
+ TQRect cursorRect;
+ drawSelections &= ( mSelections != 0 );
+ // macintosh full-width selection style
+ bool fullWidthStyle = TQApplication::tqstyle().tqstyleHint(TQStyle::SH_RichText_FullWidthSelection);
+ int fullSelectionWidth = 0;
+ if ( drawSelections && fullWidthStyle )
+ fullSelectionWidth = (hasdoc ? document()->width() : r.width());
+
+ TQString qstr = str->toString();
+ // detach string
+ qstr.setLength(qstr.length());
+ // ### workaround so that \n are not drawn, actually this should
+ // be fixed in TQFont somewhere (under Windows you get ugly boxes
+ // otherwise)
+ TQChar* uc = (TQChar*) qstr.tqunicode();
+ for ( int ii = 0; ii < qstr.length(); ii++ )
+ if ( uc[(int)ii]== '\n' || uc[(int)ii] == '\t' )
+ uc[(int)ii] = 0x20;
+
+ int line = -1;
+ int paintStart = 0;
+ TQTextStringChar *chr = 0;
+ TQTextStringChar *nextchr = at( 0 );
+ for ( i = 0; i < length(); i++ ) {
+ chr = nextchr;
+ if ( i < length()-1 )
+ nextchr = at( i+1 );
+
+ // we flush at end of document
+ bool flush = (i == length()-1);
+ bool ignoreSoftHyphen = FALSE;
+ if ( !flush ) {
+ // we flush at end of line
+ flush |= nextchr->lineStart;
+ // we flush on format changes
+ flush |= ( nextchr->format() != chr->format() );
+ // we flush on link changes
+ flush |= ( nextchr->isLink() != chr->isLink() );
+ // we flush on start of run
+ flush |= ( nextchr->bidiLevel != chr->bidiLevel );
+ // we flush on bidi changes
+ flush |= ( nextchr->rightToLeft != chr->rightToLeft );
+ // we flush before and after tabs
+ flush |= ( chr->c == '\t' || nextchr->c == '\t' );
+ // we flush on soft hypens
+ if (chr->c.tqunicode() == 0xad) {
+ flush = TRUE;
+ if (!nextchr->lineStart)
+ ignoreSoftHyphen = TRUE;
+ }
+ // we flush on custom items
+ flush |= chr->isCustom();
+ // we flush before custom items
+ flush |= nextchr->isCustom();
+ // when painting justified, we flush on spaces
+ if ((tqalignment() & TQt::AlignJustify) == TQt::AlignJustify )
+ flush |= chr->whiteSpace;
+ }
+
+ // init a new line
+ if ( chr->lineStart ) {
+ ++line;
+ paintStart = i;
+ lineInfo( line, y, h, baseLine );
+ if ( clipy != -1 && cliph != 0 && y + r.y() - h > clipy + cliph ) { // outside clip area, leave
+ break;
+ }
+
+ // if this is the first line and we are a list item, draw the the bullet label
+ if ( line == 0 && isListItem() ) {
+ int x = chr->x;
+ if (str->isBidi()) {
+ if (str->isRightToLeft()) {
+ x = chr->x + str->width(0);
+ for (int k = 1; k < length(); ++k) {
+ if (str->at(k).lineStart)
+ break;
+ x = TQMAX(x, str->at(k).x + str->width(k));
+ }
+ } else {
+ x = chr->x;
+ for (int k = 1; k < length(); ++k) {
+ if (str->at(k).lineStart)
+ break;
+ x = TQMIN(x, str->at(k).x);
+ }
+ }
+ }
+ drawLabel( &painter, x, y, 0, 0, baseLine, cg );
+ }
+ }
+
+ // check for cursor mark
+ if ( cursor && this == cursor->paragraph() && i == cursor->index() ) {
+ TQTextStringChar *c = i == 0 ? chr : chr - 1;
+ cursorRect.setRect( cursor->x() , y + baseLine - c->format()->ascent(),
+ 1, c->format()->height() );
+ }
+
+ if ( flush ) { // something changed, draw what we have so far
+ if ( chr->rightToLeft ) {
+ xstart = chr->x;
+ xend = at( paintStart )->x + str->width( paintStart );
+ } else {
+ xstart = at( paintStart )->x;
+ xend = chr->x;
+ if ( i < length() - 1 ) {
+ if ( !str->at( i + 1 ).lineStart &&
+ str->at( i + 1 ).rightToLeft == chr->rightToLeft )
+ xend = str->at( i + 1 ).x;
+ else
+ xend += str->width( i );
+ }
+ }
+
+ if ( (clipx == -1 || clipw <= 0 || (xend >= clipx && xstart <= clipx + clipw)) &&
+ ( clipy == -1 || clipy < y+r.y()+h ) ) {
+ if ( !chr->isCustom() )
+ drawString( painter, qstr, paintStart, i - paintStart + (ignoreSoftHyphen ? 0 : 1), xstart, y,
+ baseLine, xend-xstart, h, drawSelections, fullSelectionWidth,
+ chr, cg, chr->rightToLeft );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ else if ( chr->customItem()->placement() == TQTextCustomItem::PlaceInline ) {
+ bool inSelection = FALSE;
+ if (drawSelections) {
+ QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->tqfind( TQTextDocument::Standard );
+ inSelection = (it != mSelections->end() && (*it).start <= i && (*it).end > i);
+ }
+ chr->customItem()->draw( &painter, chr->x, y,
+ clipx == -1 ? clipx : (clipx - r.x()),
+ clipy == -1 ? clipy : (clipy - r.y()),
+ clipw, cliph, cg, inSelection );
+ }
+#endif
+ }
+ paintStart = i+1;
+ }
+
+ }
+
+ // time to draw the cursor
+ const int cursor_extent = 4;
+ if ( !cursorRect.isNull() && cursor &&
+ ((clipx == -1 || clipw == -1) || (cursorRect.right()+cursor_extent >= clipx && cursorRect.left()-cursor_extent <= clipx + clipw)) ) {
+ painter.fillRect( cursorRect, cg.color( TQColorGroup::Text ) );
+ painter.save();
+ if ( string()->isBidi() ) {
+ if ( at( cursor->index() )->rightToLeft ) {
+ painter.setPen( TQt::black );
+ painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
+ painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() - cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
+ } else {
+ painter.setPen( TQt::black );
+ painter.drawLine( cursorRect.x(), cursorRect.y(), cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
+ painter.drawLine( cursorRect.x(), cursorRect.y() + cursor_extent, cursorRect.x() + cursor_extent / 2, cursorRect.y() + cursor_extent / 2 );
+ }
+ }
+ painter.restore();
+ }
+}
+
+//#define BIDI_DEBUG
+
+void TQTextParagraph::setColorForSelection( TQColor &color, TQPainter &painter,
+ const TQColorGroup& cg, int selection )
+{
+ if (selection < 0)
+ return;
+ color = ( hasdoc && selection != TQTextDocument::Standard ) ?
+ document()->selectionColor( selection ) :
+ cg.color( TQColorGroup::Highlight );
+ if ( selection == TQTextDocument::IMCompositionText ) {
+#ifndef TQ_WS_MACX
+ int h1, s1, v1, h2, s2, v2;
+ TQT_TQCOLOR_OBJECT(cg.color( TQColorGroup::Base )).hsv( &h1, &s1, &v1 );
+ TQT_TQCOLOR_OBJECT(cg.color( TQColorGroup::Background )).hsv( &h2, &s2, &v2 );
+ color.setHsv( h1, s1, ( v1 + v2 ) / 2 );
+#else
+ color = TQt::lightGray;
+#endif
+ painter.setPen( cg.color( TQColorGroup::Text ) );
+ } else if ( selection == TQTextDocument::IMSelectionText ) {
+ color = cg.color( TQColorGroup::Dark );
+ painter.setPen( cg.color( TQColorGroup::BrightText ) );
+ } else if ( !hasdoc || document()->invertSelectionText( selection ) ) {
+ painter.setPen( cg.color( TQColorGroup::HighlightedText ) );
+ }
+}
+
+void TQTextParagraph::drawString( TQPainter &painter, const TQString &str, int start, int len, int xstart,
+ int y, int baseLine, int w, int h, bool drawSelections, int fullSelectionWidth,
+ TQTextStringChar *formatChar, const TQColorGroup& cg,
+ bool rightToLeft )
+{
+ bool plainText = hasdoc ? document()->textFormat() == TQt::PlainText : FALSE;
+ TQTextFormat* format = formatChar->format();
+
+ if ( !plainText || (hasdoc && (format->color() != document()->formatCollection()->defaultFormat()->color())) )
+ painter.setPen( TQPen( format->color() ) );
+ else
+ painter.setPen( cg.text() );
+ painter.setFont( format->font() );
+
+ if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() ) {
+ if ( format->useLinkColor() )
+ painter.setPen(document()->linkColor.isValid() ? document()->linkColor : cg.link());
+ if ( document()->underlineLinks() ) {
+ TQFont fn = format->font();
+ fn.setUnderline( TRUE );
+ painter.setFont( fn );
+ }
+ }
+
+ TQPainter::TextDirection dir = rightToLeft ? TQPainter::RTL : TQPainter::LTR;
+
+ int real_length = len;
+ if (len && dir != TQPainter::RTL && start + len == length() ) // don't draw the last character (trailing space)
+ len--;
+ if (len && str.tqunicode()[start+len-1] == TQChar_linesep)
+ len--;
+
+
+ TQTextFormat::VerticalAlignment vAlign = format->vAlign();
+ if ( vAlign != TQTextFormat::AlignNormal ) {
+ // sub or superscript
+ TQFont f( painter.font() );
+ if ( format->fontSizesInPixels() )
+ f.setPixelSize( ( f.pixelSize() * 2 ) / 3 );
+ else
+ f.setPointSize( ( f.pointSize() * 2 ) / 3 );
+ painter.setFont( f );
+ int h = painter.fontMetrics().height();
+ baseLine += (vAlign == TQTextFormat::AlignSubScript) ? h/6 : -h/2;
+ }
+
+ bool allSelected = FALSE;
+ if (drawSelections) {
+ QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->tqfind( TQTextDocument::Standard );
+ allSelected = (it != mSelections->end() && (*it).start <= start && (*it).end >= start+len);
+ }
+ if (!allSelected)
+ painter.drawText(xstart, y + baseLine, str, start, len, dir);
+
+#ifdef BIDI_DEBUG
+ painter.save();
+ painter.setPen ( TQt::red );
+ painter.drawLine( xstart, y, xstart, y + baseLine );
+ painter.drawLine( xstart, y + baseLine/2, xstart + 10, y + baseLine/2 );
+ int w = 0;
+ int i = 0;
+ while( i < len )
+ w += painter.fontMetrics().charWidth( str, start + i++ );
+ painter.setPen ( TQt::blue );
+ painter.drawLine( xstart + w - 1, y, xstart + w - 1, y + baseLine );
+ painter.drawLine( xstart + w - 1, y + baseLine/2, xstart + w - 1 - 10, y + baseLine/2 );
+ painter.restore();
+#endif
+
+ // check if we are in a selection and draw it
+ if (drawSelections) {
+ QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->end();
+ while ( it != mSelections->begin() ) {
+ --it;
+ int selStart = (*it).start;
+ int selEnd = (*it).end;
+ int tmpw = w;
+
+ selStart = TQMAX(selStart, start);
+ int real_selEnd = TQMIN(selEnd, start+real_length);
+ selEnd = TQMIN(selEnd, start+len);
+ bool extendRight = FALSE;
+ bool extendLeft = FALSE;
+ bool selWrap = (real_selEnd == length()-1 && n && n->hasSelection(it.key()));
+ if (selWrap || this->str->at(real_selEnd).lineStart) {
+ extendRight = (fullSelectionWidth != 0);
+ if (!extendRight && !rightToLeft)
+ tmpw += painter.fontMetrics().width(' ');
+ }
+ if (fullSelectionWidth && (selStart == 0 || this->str->at(selStart).lineStart)) {
+ extendLeft = TRUE;
+ }
+ if (this->str->isRightToLeft() != rightToLeft)
+ extendLeft = extendRight = FALSE;
+
+ if (this->str->isRightToLeft()) {
+ bool tmp = extendLeft;
+ extendLeft = extendRight;
+ extendRight = tmp;
+ }
+
+ if ((selStart < real_selEnd) ||
+ (selWrap && fullSelectionWidth && extendRight &&
+ // don't draw the standard selection on a printer=
+ ((it.key() != TQTextDocument::Standard) || (!is_printer( &painter))))) {
+ int selection = it.key();
+ TQColor color;
+ setColorForSelection( color, painter, cg, selection );
+ if (selStart != start || selEnd != start + len || selWrap) {
+ // have to clip
+ painter.save();
+ int cs, ce;
+ if (rightToLeft) {
+ cs = (selEnd != start + len) ?
+ this->str->at(this->str->previousCursorPosition(selEnd)).x : xstart;
+ ce = (selStart != start) ?
+ this->str->at(this->str->previousCursorPosition(selStart)).x : xstart+tmpw;
+ } else {
+ cs = (selStart != start) ? this->str->at(selStart).x : xstart;
+ ce = (selEnd != start + len) ? this->str->at(selEnd).x : xstart+tmpw;
+ }
+ TQRect r(cs, y, ce-cs, h);
+ if (extendLeft)
+ r.setLeft(0);
+ if (extendRight)
+ r.setRight(fullSelectionWidth);
+ TQRegion reg(r);
+ if ( painter.hasClipping() )
+ reg &= painter.clipRegion(TQPainter::CoordPainter);
+ painter.setClipRegion(reg, TQPainter::CoordPainter);
+ }
+ int xleft = xstart;
+ if ( extendLeft ) {
+ tmpw += xstart;
+ xleft = 0;
+ }
+ if ( extendRight )
+ tmpw = fullSelectionWidth - xleft;
+ painter.fillRect( xleft, y, tmpw, h, color );
+ painter.drawText( xstart, y + baseLine, str, start, len, dir );
+ if (selStart != start || selEnd != start + len || selWrap)
+ painter.restore();
+ }
+ }
+ }
+
+ if ( format->isMisspelled() ) {
+ painter.save();
+ painter.setPen( TQPen( TQt::red, 1, TQt::DotLine ) );
+ painter.drawLine( xstart, y + baseLine + 1, xstart + w, y + baseLine + 1 );
+ painter.restore();
+ }
+
+ if ( hasdoc && formatChar->isAnchor() && !formatChar->anchorHref().isEmpty() &&
+ document()->focusIndicator.parag == this &&
+ ( (document()->focusIndicator.start >= start &&
+ document()->focusIndicator.start + document()->focusIndicator.len <= start + len) ||
+ (document()->focusIndicator.start <= start &&
+ document()->focusIndicator.start + document()->focusIndicator.len >= start + len )) )
+ painter.drawWinFocusRect( TQRect( xstart, y, w, h ) );
+}
+
+void TQTextParagraph::drawLabel( TQPainter* p, int x, int y, int w, int h, int base, const TQColorGroup& cg )
+{
+ TQRect r ( x, y, w, h );
+ TQStyleSheetItem::ListStyle s = listStyle();
+
+ p->save();
+ TQTextFormat *format = at( 0 )->format();
+ if ( format ) {
+ p->setPen( format->color() );
+ p->setFont( format->font() );
+ }
+ TQFontMetrics fm( p->fontMetrics() );
+ int size = fm.lineSpacing() / 3;
+
+ bool rtl = str->isRightToLeft();
+
+ switch ( s ) {
+ case TQStyleSheetItem::ListDecimal:
+ case TQStyleSheetItem::ListLowerAlpha:
+ case TQStyleSheetItem::ListUpperAlpha:
+ {
+ if ( list_val == -1 ) { // uninitialised list value, calcluate the right one
+ int depth = listDepth();
+ list_val--;
+ // ### evil, square and expensive. This needs to be done when formatting, not when painting
+ TQTextParagraph* s = prev();
+ int depth_s;
+ while ( s && (depth_s = s->listDepth()) >= depth ) {
+ if ( depth_s == depth && s->isListItem() )
+ list_val--;
+ s = s->prev();
+ }
+ }
+
+ int n = list_val;
+ if ( n < -1 )
+ n = -n - 1;
+ TQString l;
+ switch ( s ) {
+ case TQStyleSheetItem::ListLowerAlpha:
+ if ( n < 27 ) {
+ l = TQChar( ('a' + (char) (n-1)));
+ break;
+ }
+ case TQStyleSheetItem::ListUpperAlpha:
+ if ( n < 27 ) {
+ l = TQChar( ('A' + (char) (n-1)));
+ break;
+ }
+ break;
+ default: //TQStyleSheetItem::ListDecimal:
+ l.setNum( n );
+ break;
+ }
+ if (rtl)
+ l.prepend(" .");
+ else
+ l += TQString::tqfromLatin1(". ");
+ int x = ( rtl ? r.left() : r.right() - fm.width(l));
+ p->drawText( x, r.top() + base, l );
+ }
+ break;
+ case TQStyleSheetItem::ListSquare:
+ {
+ int x = rtl ? r.left() + size : r.right() - size*2;
+ TQRect er( x, r.top() + fm.height() / 2 - size / 2, size, size );
+ p->fillRect( er , cg.brush( TQColorGroup::Text ) );
+ }
+ break;
+ case TQStyleSheetItem::ListCircle:
+ {
+ int x = rtl ? r.left() + size : r.right() - size*2;
+ TQRect er( x, r.top() + fm.height() / 2 - size / 2, size, size);
+ p->drawEllipse( er );
+ }
+ break;
+ case TQStyleSheetItem::ListDisc:
+ default:
+ {
+ p->setBrush( cg.brush( TQColorGroup::Text ));
+ int x = rtl ? r.left() + size : r.right() - size*2;
+ TQRect er( x, r.top() + fm.height() / 2 - size / 2, size, size);
+ p->drawEllipse( er );
+ p->setBrush( TQt::NoBrush );
+ }
+ break;
+ }
+
+ p->restore();
+}
+
+#ifndef TQT_NO_DATASTREAM
+void TQTextParagraph::readStyleInformation( TQDataStream& stream )
+{
+ int int_align, int_lstyle;
+ uchar uchar_litem, uchar_rtext, uchar_dir;
+ stream >> int_align >> int_lstyle >> utm >> ubm >> ulm >> urm >> uflm
+ >> ulinespacing >> ldepth >> uchar_litem >> uchar_rtext >> uchar_dir;
+ align = int_align; lstyle = (TQStyleSheetItem::ListStyle) int_lstyle;
+ litem = uchar_litem; rtext = uchar_rtext; str->setDirection( (TQChar::Direction)uchar_dir );
+ TQTextParagraph* s = prev() ? prev() : this;
+ while ( s ) {
+ s->tqinvalidate( 0 );
+ s = s->next();
+ }
+}
+
+void TQTextParagraph::writeStyleInformation( TQDataStream& stream ) const
+{
+ stream << (int) align << (int) lstyle << utm << ubm << ulm << urm << uflm << ulinespacing << ldepth << (uchar)litem << (uchar)rtext << (uchar)str->direction();
+}
+#endif
+
+
+void TQTextParagraph::setListItem( bool li )
+{
+ if ( (bool)litem == li )
+ return;
+ litem = li;
+ changed = TRUE;
+ TQTextParagraph* s = prev() ? prev() : this;
+ while ( s ) {
+ s->tqinvalidate( 0 );
+ s = s->next();
+ }
+}
+
+void TQTextParagraph::setListDepth( int depth ) {
+ if ( !hasdoc || depth == ldepth )
+ return;
+ ldepth = depth;
+ TQTextParagraph* s = prev() ? prev() : this;
+ while ( s ) {
+ s->tqinvalidate( 0 );
+ s = s->next();
+ }
+}
+
+int *TQTextParagraph::tabArray() const
+{
+ int *ta = tArray;
+ if ( !ta && hasdoc )
+ ta = document()->tabArray();
+ return ta;
+}
+
+int TQTextParagraph::nextTab( int, int x )
+{
+ int *ta = tArray;
+ if ( hasdoc ) {
+ if ( !ta )
+ ta = document()->tabArray();
+ tabStopWidth = document()->tabStopWidth();
+ }
+ if ( ta ) {
+ int i = 0;
+ while ( ta[ i ] ) {
+ if ( ta[ i ] >= x )
+ return tArray[ i ];
+ ++i;
+ }
+ return tArray[ 0 ];
+ } else {
+ int d;
+ if ( tabStopWidth != 0 )
+ d = x / tabStopWidth;
+ else
+ return x;
+ return tabStopWidth * ( d + 1 );
+ }
+}
+
+void TQTextParagraph::adjustToPainter( TQPainter *p )
+{
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ for ( int i = 0; i < length(); ++i ) {
+ if ( at( i )->isCustom() )
+ at( i )->customItem()->adjustToPainter( p );
+ }
+#endif
+}
+
+TQTextFormatCollection *TQTextParagraph::formatCollection() const
+{
+ if ( hasdoc )
+ return document()->formatCollection();
+ TQTextFormatCollection* fc = &pseudoDocument()->collection;
+ if ( painttqdevice != fc->paintDevice() )
+ fc->setPaintDevice( painttqdevice );
+ return fc;
+}
+
+TQString TQTextParagraph::richText() const
+{
+ TQString s;
+ TQTextStringChar *formatChar = 0;
+ TQString spaces;
+ bool doStart = richTextExportStart && richTextExportStart->paragraph() == this;
+ bool doEnd = richTextExportEnd && richTextExportEnd->paragraph() == this;
+ int i;
+ TQString lastAnchorName;
+ for ( i = 0; i < length()-1; ++i ) {
+ if ( doStart && i && richTextExportStart->index() == i )
+ s += "<!--StartFragment-->";
+ if ( doEnd && richTextExportEnd->index() == i )
+ s += "<!--EndFragment-->";
+ TQTextStringChar *c = &str->at( i );
+ if ( c->isAnchor() && !c->anchorName().isEmpty() && c->anchorName() != lastAnchorName ) {
+ lastAnchorName = c->anchorName();
+ if ( c->anchorName().tqcontains( '#' ) ) {
+ TQStringList l = TQStringList::split( '#', c->anchorName() );
+ for ( TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it )
+ s += "<a name=\"" + *it + "\"></a>";
+ } else {
+ s += "<a name=\"" + c->anchorName() + "\"></a>";
+ }
+ }
+ if ( !formatChar ) {
+ s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(),
+ 0, TQString::null, c->anchorHref() );
+ formatChar = c;
+ } else if ( ( formatChar->format()->key() != c->format()->key() ) ||
+ (c->anchorHref() != formatChar->anchorHref() ) ) {
+ s += c->format()->makeFormatChangeTags( formatCollection()->defaultFormat(),
+ formatChar->format() , formatChar->anchorHref(), c->anchorHref() );
+ formatChar = c;
+ }
+ if ( c->c == '<' )
+ s += "&lt;";
+ else if ( c->c == '>' )
+ s += "&gt;";
+ else if ( c->c =='&' )
+ s += "&amp;";
+ else if ( c->c =='\"' )
+ s += "&quot;";
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ else if ( c->isCustom() )
+ s += c->customItem()->richText();
+#endif
+ else if ( c->c == '\n' || c->c == TQChar_linesep )
+ s += "<br />"; // space on purpose for compatibility with Netscape, Lynx & Co.
+ else
+ s += c->c;
+ }
+ if ( doEnd && richTextExportEnd->index() == i )
+ s += "<!--EndFragment-->";
+ if ( formatChar )
+ s += formatChar->format()->makeFormatEndTags( formatCollection()->defaultFormat(), formatChar->anchorHref() );
+ return s;
+}
+
+void TQTextParagraph::addCommand( TQTextCommand *cmd )
+{
+ if ( !hasdoc )
+ pseudoDocument()->commandHistory->addCommand( cmd );
+ else
+ document()->commands()->addCommand( cmd );
+}
+
+TQTextCursor *TQTextParagraph::undo( TQTextCursor *c )
+{
+ if ( !hasdoc )
+ return pseudoDocument()->commandHistory->undo( c );
+ return document()->commands()->undo( c );
+}
+
+TQTextCursor *TQTextParagraph::redo( TQTextCursor *c )
+{
+ if ( !hasdoc )
+ return pseudoDocument()->commandHistory->redo( c );
+ return document()->commands()->redo( c );
+}
+
+int TQTextParagraph::topMargin() const
+{
+ int m = 0;
+ if ( rtext ) {
+ m = isListItem() ? (document()->li_tm/TQMAX(1,listDepth()*listDepth())) :
+ ( listDepth() ? 0 : document()->par_tm );
+ if ( listDepth() == 1 &&( !prev() || prev()->listDepth() < listDepth() ) )
+ m = TQMAX( m, document()->list_tm );
+ }
+ m += utm;
+ return scale( m, TQTextFormat::painter() );
+}
+
+int TQTextParagraph::bottomMargin() const
+{
+ int m = 0;
+ if ( rtext ) {
+ m = isListItem() ? (document()->li_bm/TQMAX(1,listDepth()*listDepth())) :
+ ( listDepth() ? 0 : document()->par_bm );
+ if ( listDepth() == 1 &&( !next() || next()->listDepth() < listDepth() ) )
+ m = TQMAX( m, document()->list_bm );
+ }
+ m += ubm;
+ return scale( m, TQTextFormat::painter() );
+}
+
+int TQTextParagraph::leftMargin() const
+{
+ int m = ulm;
+ if ( listDepth() && !string()->isRightToLeft() )
+ m += listDepth() * document()->list_lm;
+ return scale( m, TQTextFormat::painter() );
+}
+
+int TQTextParagraph::firstLineMargin() const
+{
+ int m = uflm;
+ return scale( m, TQTextFormat::painter() );
+}
+
+int TQTextParagraph::rightMargin() const
+{
+ int m = urm;
+ if ( listDepth() && string()->isRightToLeft() )
+ m += listDepth() * document()->list_lm;
+ return scale( m, TQTextFormat::painter() );
+}
+
+int TQTextParagraph::lineSpacing() const
+{
+ int l = ulinespacing;
+ l = scale( l, TQTextFormat::painter() );
+ return l;
+}
+
+void TQTextParagraph::copyParagData( TQTextParagraph *parag )
+{
+ rtext = parag->rtext;
+ lstyle = parag->lstyle;
+ ldepth = parag->ldepth;
+ litem = parag->litem;
+ align = parag->align;
+ utm = parag->utm;
+ ubm = parag->ubm;
+ urm = parag->urm;
+ ulm = parag->ulm;
+ uflm = parag->uflm;
+ ulinespacing = parag->ulinespacing;
+ TQColor *c = parag->backgroundColor();
+ if ( c )
+ setBackgroundColor( *c );
+ str->setDirection( parag->str->direction() );
+}
+
+void TQTextParagraph::show()
+{
+ if ( visible || !hasdoc )
+ return;
+ visible = TRUE;
+}
+
+void TQTextParagraph::hide()
+{
+ if ( !visible || !hasdoc )
+ return;
+ visible = FALSE;
+}
+
+void TQTextParagraph::setDirection( TQChar::Direction d )
+{
+ if ( str && str->direction() != d ) {
+ str->setDirection( d );
+ tqinvalidate( 0 );
+ }
+}
+
+TQChar::Direction TQTextParagraph::direction() const
+{
+ return (str ? str->direction() : TQChar::DirON );
+}
+
+void TQTextParagraph::setChanged( bool b, bool recursive )
+{
+ changed = b;
+ if ( recursive ) {
+ if ( document() && document()->parentParagraph() )
+ document()->parentParagraph()->setChanged( b, recursive );
+ }
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
+TQTextPreProcessor::TQTextPreProcessor()
+{
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextFormatter::TQTextFormatter()
+ : thisminw(0), thiswused(0), wrapEnabled( TRUE ), wrapColumn( -1 ), biw( FALSE )
+{
+}
+
+TQTextLineStart *TQTextFormatter::formatLine( TQTextParagraph *parag, TQTextString *string, TQTextLineStart *line,
+ TQTextStringChar *startChar, TQTextStringChar *lastChar, int align, int space )
+{
+ if ( lastChar < startChar )
+ return new TQTextLineStart;
+#ifndef TQT_NO_COMPLEXTEXT
+ if( string->isBidi() )
+ return bidiReorderLine( parag, string, line, startChar, lastChar, align, space );
+#endif
+ int start = (startChar - &string->at(0));
+ int last = (lastChar - &string->at(0) );
+
+ // ignore white space at the end of the line.
+ TQTextStringChar *ch = lastChar;
+ while ( ch > startChar && ch->whiteSpace ) {
+ space += ch->format()->width( ' ' );
+ --ch;
+ }
+
+ if (space < 0)
+ space = 0;
+
+ // do tqalignment Auto == Left in this case
+ if ( align & TQt::AlignHCenter || align & TQt::AlignRight ) {
+ if ( align & TQt::AlignHCenter )
+ space /= 2;
+ for ( int j = start; j <= last; ++j )
+ string->at( j ).x += space;
+ } else if ( align & TQt::AlignJustify ) {
+ int numSpaces = 0;
+ // End at "last-1", the last space ends up with a width of 0
+ for ( int j = last-1; j >= start; --j ) {
+ // Start at last tab, if any.
+ TQTextStringChar &ch = string->at( j );
+ if ( ch.c == '\t' ) {
+ start = j+1;
+ break;
+ }
+ if(ch.whiteSpace)
+ numSpaces++;
+ }
+ int toAdd = 0;
+ for ( int k = start + 1; k <= last; ++k ) {
+ TQTextStringChar &ch = string->at( k );
+ if( numSpaces && ch.whiteSpace ) {
+ int s = space / numSpaces;
+ toAdd += s;
+ space -= s;
+ numSpaces--;
+ }
+ string->at( k ).x += toAdd;
+ }
+ }
+
+ if ( last >= 0 && last < string->length() )
+ line->w = string->at( last ).x + string->width( last );
+ else
+ line->w = 0;
+
+ return new TQTextLineStart;
+}
+
+#ifndef TQT_NO_COMPLEXTEXT
+
+#ifdef BIDI_DEBUG
+#include <iostream>
+#endif
+
+// collects one line of the paragraph and transforms it to visual order
+TQTextLineStart *TQTextFormatter::bidiReorderLine( TQTextParagraph * /*parag*/, TQTextString *text, TQTextLineStart *line,
+ TQTextStringChar *startChar, TQTextStringChar *lastChar, int align, int space )
+{
+ // ignore white space at the end of the line.
+ int endSpaces = 0;
+ while ( lastChar > startChar && lastChar->whiteSpace ) {
+ space += lastChar->format()->width( ' ' );
+ --lastChar;
+ ++endSpaces;
+ }
+
+ int start = (startChar - &text->at(0));
+ int last = (lastChar - &text->at(0) );
+
+ int length = lastChar - startChar + 1;
+
+
+ int x = startChar->x;
+
+ unsigned char _levels[256];
+ int _visual[256];
+
+ unsigned char *levels = _levels;
+ int *visual = _visual;
+
+ if ( length > 255 ) {
+ levels = (unsigned char *)malloc( length*sizeof( unsigned char ) );
+ visual = (int *)malloc( length*sizeof( int ) );
+ }
+
+ //qDebug("bidiReorderLine: length=%d (%d-%d)", length, start, last );
+
+ TQTextStringChar *ch = startChar;
+ unsigned char *l = levels;
+ while ( ch <= lastChar ) {
+ //qDebug( " level: %d", ch->bidiLevel );
+ *(l++) = (ch++)->bidiLevel;
+ }
+
+ TQTextEngine::bidiReorder( length, levels, visual );
+
+ // now construct the reordered string out of the runs...
+
+ int numSpaces = 0;
+ // set the correct tqalignment. This is a bit messy....
+ if( align == TQt::AlignAuto ) {
+ // align according to directionality of the paragraph...
+ if ( text->isRightToLeft() )
+ align = TQt::AlignRight;
+ }
+
+ // This is not really correct, but as we can't make the scrollbar move to the left of the origin,
+ // this ensures all text can be scrolled to and read.
+ if (space < 0)
+ space = 0;
+
+ if ( align & TQt::AlignHCenter )
+ x += space/2;
+ else if ( align & TQt::AlignRight )
+ x += space;
+ else if ( align & TQt::AlignJustify ) {
+ // End at "last-1", the last space ends up with a width of 0
+ for ( int j = last-1; j >= start; --j ) {
+ // Start at last tab, if any.
+ TQTextStringChar &ch = text->at( j );
+ if ( ch.c == '\t' ) {
+ start = j+1;
+ break;
+ }
+ if(ch.whiteSpace)
+ numSpaces++;
+ }
+ }
+
+ int toAdd = 0;
+ int xorig = x;
+ TQTextStringChar *lc = startChar + visual[0];
+ for ( int i = 0; i < length; i++ ) {
+ TQTextStringChar *ch = startChar + visual[i];
+ if (numSpaces && ch->whiteSpace) {
+ int s = space / numSpaces;
+ toAdd += s;
+ space -= s;
+ numSpaces--;
+ }
+
+ if (lc->format() != ch->format() && !ch->c.isSpace()
+ && lc->format()->font().italic() && !ch->format()->font().italic()) {
+ int rb = lc->format()->fontMetrics().rightBearing(lc->c);
+ if (rb < 0)
+ x -= rb;
+ }
+
+ ch->x = x + toAdd;
+ ch->rightToLeft = ch->bidiLevel % 2;
+ //qDebug("visual: %d (%x) placed at %d rightToLeft=%d", visual[i], ch->c.tqunicode(), x +toAdd, ch->rightToLeft );
+ int ww = 0;
+ if ( ch->c.tqunicode() >= 32 || ch->c == '\t' || ch->c == '\n' || ch->isCustom() ) {
+ ww = text->width( start+visual[i] );
+ } else {
+ ww = ch->format()->width( ' ' );
+ }
+ x += ww;
+ lc = ch;
+ }
+ x += toAdd;
+
+ while ( endSpaces-- ) {
+ ++lastChar;
+ int sw = lastChar->format()->width( ' ' );
+ if ( text->isRightToLeft() ) {
+ xorig -= sw;
+ lastChar->x = xorig;
+ ch->rightToLeft = TRUE;
+ } else {
+ lastChar->x = x;
+ x += sw;
+ ch->rightToLeft = FALSE;
+ }
+ }
+
+ line->w = x;
+
+ if ( length > 255 ) {
+ free( levels );
+ free( visual );
+ }
+
+ return new TQTextLineStart;
+}
+#endif
+
+
+void TQTextFormatter::insertLineStart( TQTextParagraph *parag, int index, TQTextLineStart *ls )
+{
+ QMap<int, TQTextLineStart*>::Iterator it;
+ if ( ( it = parag->lineStartList().tqfind( index ) ) == parag->lineStartList().end() ) {
+ parag->lineStartList().insert( index, ls );
+ } else {
+ delete *it;
+ parag->lineStartList().remove( it );
+ parag->lineStartList().insert( index, ls );
+ }
+}
+
+
+/* Standard pagebreak algorithm using TQTextFlow::adjustFlow. Returns
+ the shift of the paragraphs bottom line.
+ */
+int TQTextFormatter::formatVertically( TQTextDocument* doc, TQTextParagraph* parag )
+{
+ int oldHeight = parag->rect().height();
+ QMap<int, TQTextLineStart*>& lineStarts = parag->lineStartList();
+ QMap<int, TQTextLineStart*>::Iterator it = lineStarts.begin();
+ int h = parag->prev() ? TQMAX(parag->prev()->bottomMargin(),parag->topMargin() ) / 2: 0;
+ for ( ; it != lineStarts.end() ; ++it ) {
+ TQTextLineStart * ls = it.data();
+ ls->y = h;
+ TQTextStringChar *c = &parag->string()->at(it.key());
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( c && c->customItem() && c->customItem()->ownLine() ) {
+ int h = c->customItem()->height;
+ c->customItem()->pageBreak( parag->rect().y() + ls->y + ls->baseLine - h, doc->flow() );
+ int delta = c->customItem()->height - h;
+ ls->h += delta;
+ if ( delta )
+ parag->setMovedDown( TRUE );
+ } else
+#endif
+ {
+
+ int shift = doc->flow()->adjustFlow( parag->rect().y() + ls->y, ls->w, ls->h );
+ ls->y += shift;
+ if ( shift )
+ parag->setMovedDown( TRUE );
+ }
+ h = ls->y + ls->h;
+ }
+ int m = parag->bottomMargin();
+ if ( !parag->next() )
+ m = 0;
+ else
+ m = TQMAX(m, parag->next()->topMargin() ) / 2;
+ h += m;
+ parag->setHeight( h );
+ return h - oldHeight;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextFormatterBreakInWords::TQTextFormatterBreakInWords()
+{
+}
+
+#define SPACE(s) s
+
+int TQTextFormatterBreakInWords::format( TQTextDocument *doc,TQTextParagraph *parag,
+ int start, const QMap<int, TQTextLineStart*> & )
+{
+ // make sure bidi information is correct.
+ (void )parag->string()->isBidi();
+
+ TQTextStringChar *c = 0;
+ TQTextStringChar *firstChar = 0;
+ int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
+ int x = left + ( doc ? parag->firstLineMargin() : 0 );
+ int dw = parag->documentVisibleWidth() - ( doc ? doc->rightMargin() : 0 );
+ int y = parag->prev() ? TQMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
+ int h = y;
+ int len = parag->length();
+ if ( doc )
+ x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 4 );
+ int rm = parag->rightMargin();
+ int w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
+ bool fullWidth = TRUE;
+ int minw = 0;
+ int wused = 0;
+ bool wrapEnabled = isWrapEnabled( parag );
+
+ start = 0; //######### what is the point with start?! (Matthias)
+ if ( start == 0 )
+ c = &parag->string()->at( 0 );
+
+ int i = start;
+ TQTextLineStart *lineStart = new TQTextLineStart( y, y, 0 );
+ insertLineStart( parag, 0, lineStart );
+
+ TQPainter *painter = TQTextFormat::painter();
+
+ int col = 0;
+ int ww = 0;
+ TQChar lastChr;
+ for ( ; i < len; ++i, ++col ) {
+ if ( c )
+ lastChr = c->c;
+ c = &parag->string()->at( i );
+ // ### the lines below should not be needed
+ if ( painter )
+ c->format()->setPainter( painter );
+ if ( i > 0 ) {
+ c->lineStart = 0;
+ } else {
+ c->lineStart = 1;
+ firstChar = c;
+ }
+ if ( c->c.tqunicode() >= 32 || c->isCustom() ) {
+ ww = parag->string()->width( i );
+ } else if ( c->c == '\t' ) {
+ int nx = parag->nextTab( i, x - left ) + left;
+ if ( nx < x )
+ ww = w - x;
+ else
+ ww = nx - x;
+ } else {
+ ww = c->format()->width( ' ' );
+ }
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ if ( c->isCustom() && c->customItem()->ownLine() ) {
+ x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
+ w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
+ c->customItem()->resize( w - x );
+ w = dw;
+ y += h;
+ h = c->height();
+ lineStart = new TQTextLineStart( y, h, h );
+ insertLineStart( parag, i, lineStart );
+ c->lineStart = 1;
+ firstChar = c;
+ x = 0xffffff;
+ continue;
+ }
+#endif
+
+ if ( wrapEnabled &&
+ ( ((wrapAtColumn() == -1) && (x + ww > w)) ||
+ ((wrapAtColumn() != -1) && (col >= wrapAtColumn())) ) ) {
+ x = doc ? parag->document()->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
+ w = dw;
+ y += h;
+ h = c->height();
+ lineStart = formatLine( parag, parag->string(), lineStart, firstChar, c-1 );
+ lineStart->y = y;
+ insertLineStart( parag, i, lineStart );
+ lineStart->baseLine = c->ascent();
+ lineStart->h = c->height();
+ c->lineStart = 1;
+ firstChar = c;
+ col = 0;
+ if ( wrapAtColumn() != -1 )
+ minw = TQMAX( minw, w );
+ } else if ( lineStart ) {
+ lineStart->baseLine = TQMAX( lineStart->baseLine, c->ascent() );
+ h = TQMAX( h, c->height() );
+ lineStart->h = h;
+ }
+
+ c->x = x;
+ x += ww;
+ wused = TQMAX( wused, x );
+ }
+
+ int m = parag->bottomMargin();
+ if ( !parag->next() )
+ m = 0;
+ else
+ m = TQMAX(m, parag->next()->topMargin() ) / 2;
+ parag->setFullWidth( fullWidth );
+ y += h + m;
+ if ( doc )
+ minw += doc->rightMargin();
+ if ( !wrapEnabled )
+ minw = TQMAX(minw, wused);
+
+ thisminw = minw;
+ thiswused = wused;
+ return y;
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextFormatterBreakWords::TQTextFormatterBreakWords()
+{
+}
+
+#define DO_FLOW( lineStart ) do{ if ( doc && doc->isPageBreakEnabled() ) { \
+ int yflow = lineStart->y + parag->rect().y();\
+ int shift = doc->flow()->adjustFlow( yflow, dw, lineStart->h ); \
+ lineStart->y += shift;\
+ y += shift;\
+ }}while(FALSE)
+
+int TQTextFormatterBreakWords::format( TQTextDocument *doc, TQTextParagraph *parag,
+ int start, const QMap<int, TQTextLineStart*> & )
+{
+ // make sure bidi information is correct.
+ (void )parag->string()->isBidi();
+
+ TQTextStringChar *c = 0;
+ TQTextStringChar *firstChar = 0;
+ TQTextString *string = parag->string();
+ int left = doc ? parag->leftMargin() + doc->leftMargin() : 0;
+ int x = left + ( doc ? parag->firstLineMargin() : 0 );
+ int y = parag->prev() ? TQMAX(parag->prev()->bottomMargin(),parag->topMargin()) / 2: 0;
+ int h = y;
+ int len = parag->length();
+ if ( doc )
+ x = doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), x, 0 );
+ int dw = parag->documentVisibleWidth() - ( doc ? ( left != x ? 0 : doc->rightMargin() ) : 0 );
+
+ int curLeft = x;
+ int rm = parag->rightMargin();
+ int rdiff = doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 0 ) : 0;
+ int w = dw - rdiff;
+ bool fullWidth = TRUE;
+ int marg = left + rdiff;
+ int minw = 0;
+ int wused = 0;
+ int tminw = marg;
+ int linespacing = doc ? parag->lineSpacing() : 0;
+ bool wrapEnabled = isWrapEnabled( parag );
+
+ start = 0;
+
+ int i = start;
+ TQTextLineStart *lineStart = new TQTextLineStart( y, y, 0 );
+ insertLineStart( parag, 0, lineStart );
+ int lastBreak = -1;
+ int tmpBaseLine = 0, tmph = 0;
+ bool lastWasNonInlineCustom = FALSE;
+
+ int align = parag->tqalignment();
+ if ( align == TQt::AlignAuto && doc && doc->tqalignment() != TQt::AlignAuto )
+ align = doc->tqalignment();
+
+ align &= TQt::AlignHorizontal_Mask;
+
+ // ### hack. The last char in the paragraph is always invisible,
+ // ### and somehow sometimes has a wrong format. It changes
+ // ### between // layouting and printing. This corrects some
+ // ### layouting errors in BiDi mode due to this.
+ if ( len > 1 ) {
+ c = &parag->string()->at(len - 1);
+ if (!c->isAnchor()) {
+ if (c->format())
+ c->format()->removeRef();
+ c->setFormat( string->at( len - 2 ).format() );
+ if (c->format())
+ c->format()->addRef();
+ }
+ }
+
+ c = &parag->string()->at( 0 );
+
+ TQPainter *painter = TQTextFormat::painter();
+ int col = 0;
+ int ww = 0;
+ TQChar lastChr = c->c;
+ TQTextFormat *lastFormat = c->format();
+ for ( ; i < len; ++i, ++col ) {
+ if ( i ) {
+ c = &parag->string()->at(i-1);
+ lastChr = c->c;
+ lastFormat = c->format();
+ }
+ bool lastWasOwnLineCustomItem = lastBreak == -2;
+ bool hadBreakableChar = lastBreak != -1;
+ bool lastWasHardBreak = lastChr == TQChar_linesep;
+
+ // ### next line should not be needed
+ if ( painter )
+ c->format()->setPainter( painter );
+ c = &string->at( i );
+
+ if (lastFormat != c->format() && !c->c.isSpace()
+ && lastFormat->font().italic() && !c->format()->font().italic()) {
+ int rb = lastFormat->fontMetrics().rightBearing(lastChr);
+ if (rb < 0)
+ x -= rb;
+ }
+
+ if ( ((i > 0) && (x > curLeft || ww == 0)) || lastWasNonInlineCustom ) {
+ c->lineStart = 0;
+ } else {
+ c->lineStart = 1;
+ firstChar = c;
+ }
+
+ // ignore non spacing marks for column count.
+ if (col != 0 && ::category(c->c) == TQChar::Mark_NonSpacing)
+ --col;
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ lastWasNonInlineCustom = ( c->isCustom() && c->customItem()->placement() != TQTextCustomItem::PlaceInline );
+#endif
+
+ if ( c->c.tqunicode() >= 32 || c->isCustom() ) {
+ ww = string->width( i );
+ } else if ( c->c == '\t' ) {
+ if ( align == TQt::AlignRight || align == TQt::AlignCenter ) {
+ // we can not (yet) do tabs
+ ww = c->format()->width(' ' );
+ } else {
+ int tabx = lastWasHardBreak ? (left + ( doc ? parag->firstLineMargin() : 0 )) : x;
+ int nx = parag->nextTab( i, tabx - left ) + left;
+ if ( nx < tabx ) // strrrange...
+ ww = 0;
+ else
+ ww = nx - tabx;
+ }
+ } else {
+ ww = c->format()->width( ' ' );
+ }
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem* ci = c->customItem();
+ if ( c->isCustom() && ci->ownLine() ) {
+ TQTextLineStart *lineStart2 = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x - ww) );
+ x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
+ w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
+ ci->resize(w - x);
+ if ( ci->width < w - x ) {
+ if ( align & TQt::AlignHCenter )
+ x = ( w - ci->width ) / 2;
+ else if ( align & TQt::AlignRight ) {
+ x = w - ci->width;
+ }
+ }
+ c->x = x;
+ curLeft = x;
+ if ( i == 0 || !isBreakable(string, i-1) ||
+ string->at( i - 1 ).lineStart == 0 ) {
+ y += TQMAX( h, TQMAX( tmph, linespacing ) );
+ tmph = c->height();
+ h = tmph;
+ lineStart = lineStart2;
+ lineStart->y = y;
+ insertLineStart( parag, i, lineStart );
+ c->lineStart = 1;
+ firstChar = c;
+ } else {
+ tmph = c->height();
+ h = tmph;
+ delete lineStart2;
+ }
+ lineStart->h = h;
+ lineStart->baseLine = h;
+ tmpBaseLine = lineStart->baseLine;
+ lastBreak = -2;
+ x = w;
+ minw = TQMAX( minw, tminw );
+
+ int tw = ci->minimumWidth() + ( doc ? doc->leftMargin() : 0 );
+ if ( tw < TQWIDGETSIZE_MAX )
+ tminw = tw;
+ else
+ tminw = marg;
+ wused = TQMAX( wused, ci->width );
+ continue;
+ } else if ( c->isCustom() && ci->placement() != TQTextCustomItem::PlaceInline ) {
+ int tw = ci->minimumWidth();
+ if ( tw < TQWIDGETSIZE_MAX )
+ minw = TQMAX( minw, tw );
+ }
+#endif
+ // we break if
+ // 1. the last character was a hard break (TQChar_linesep) or
+ // 2. the last charater was a own-line custom item (eg. table or ruler) or
+ // 3. wrapping was enabled, it was not a space and following
+ // condition is true: We either had a breakable character
+ // previously or we ar allowed to break in words and - either
+ // we break at w pixels and the current char would exceed that
+ // or - we break at a column and the current character would
+ // exceed that.
+ if ( lastWasHardBreak || lastWasOwnLineCustomItem ||
+ ( wrapEnabled &&
+ ( (!c->c.isSpace() && (hadBreakableChar || allowBreakInWords()) &&
+ ( (wrapAtColumn() == -1 && x + ww > w) ||
+ (wrapAtColumn() != -1 && col >= wrapAtColumn()) ) ) )
+ )
+ ) {
+ if ( wrapAtColumn() != -1 )
+ minw = TQMAX( minw, x + ww );
+ // if a break was forced (no breakable char, hard break or own line custom item), break immediately....
+ if ( !hadBreakableChar || lastWasHardBreak || lastWasOwnLineCustomItem ) {
+ if ( lineStart ) {
+ lineStart->baseLine = TQMAX( lineStart->baseLine, tmpBaseLine );
+ h = TQMAX( h, tmph );
+ lineStart->h = h;
+ DO_FLOW( lineStart );
+ }
+ lineStart = formatLine( parag, string, lineStart, firstChar, c-1, align, SPACE(w - x) );
+ x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
+ w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
+ if ( !doc && c->c == '\t' ) { // qt_format_text tab handling
+ int nx = parag->nextTab( i, x - left ) + left;
+ if ( nx < x )
+ ww = w - x;
+ else
+ ww = nx - x;
+ }
+ curLeft = x;
+ y += TQMAX( h, linespacing );
+ tmph = c->height();
+ h = 0;
+ lineStart->y = y;
+ insertLineStart( parag, i, lineStart );
+ lineStart->baseLine = c->ascent();
+ lineStart->h = c->height();
+ c->lineStart = 1;
+ firstChar = c;
+ tmpBaseLine = lineStart->baseLine;
+ lastBreak = -1;
+ col = 0;
+ if ( allowBreakInWords() || lastWasHardBreak ) {
+ minw = TQMAX(minw, tminw);
+ tminw = marg + ww;
+ }
+ } else { // ... otherwise if we had a breakable char, break there
+ DO_FLOW( lineStart );
+ c->x = x;
+ i = lastBreak;
+ lineStart = formatLine( parag, string, lineStart, firstChar, parag->at( lastBreak ),align, SPACE(w - string->at( i+1 ).x) );
+ x = doc ? doc->flow()->adjustLMargin( y + parag->rect().y(), parag->rect().height(), left, 4 ) : left;
+ w = dw - ( doc ? doc->flow()->adjustRMargin( y + parag->rect().y(), parag->rect().height(), rm, 4 ) : 0 );
+ if ( !doc && c->c == '\t' ) { // qt_format_text tab handling
+ int nx = parag->nextTab( i, x - left ) + left;
+ if ( nx < x )
+ ww = w - x;
+ else
+ ww = nx - x;
+ }
+ curLeft = x;
+ y += TQMAX( h, linespacing );
+ tmph = c->height();
+ h = tmph;
+ lineStart->y = y;
+ insertLineStart( parag, i + 1, lineStart );
+ lineStart->baseLine = c->ascent();
+ lineStart->h = c->height();
+ c->lineStart = 1;
+ firstChar = c;
+ tmpBaseLine = lineStart->baseLine;
+ lastBreak = -1;
+ col = 0;
+ minw = TQMAX(minw, tminw);
+ tminw = marg;
+ continue;
+ }
+ } else if (lineStart && isBreakable(string, i)) {
+ if ( len <= 2 || i < len - 1 ) {
+ tmpBaseLine = TQMAX( tmpBaseLine, c->ascent() );
+ tmph = TQMAX( tmph, c->height() );
+ }
+ minw = TQMAX( minw, tminw );
+
+ tminw = marg + ww;
+ lineStart->baseLine = TQMAX( lineStart->baseLine, tmpBaseLine );
+ h = TQMAX( h, tmph );
+ lineStart->h = h;
+ if ( i < len - 2 || c->c != ' ' )
+ lastBreak = i;
+ } else {
+ tminw += ww;
+ int cascent = c->ascent();
+ int cheight = c->height();
+ int belowBaseLine = TQMAX( tmph - tmpBaseLine, cheight-cascent );
+ tmpBaseLine = TQMAX( tmpBaseLine, cascent );
+ tmph = tmpBaseLine + belowBaseLine;
+ }
+
+ c->x = x;
+ x += ww;
+ wused = TQMAX( wused, x );
+ }
+
+ if ( lineStart ) {
+ lineStart->baseLine = TQMAX( lineStart->baseLine, tmpBaseLine );
+ h = TQMAX( h, tmph );
+ lineStart->h = h;
+ // last line in a paragraph is not justified
+ if ( align == TQt::AlignJustify )
+ align = TQt::AlignAuto;
+ DO_FLOW( lineStart );
+ lineStart = formatLine( parag, string, lineStart, firstChar, c, align, SPACE(w - x) );
+ delete lineStart;
+ }
+
+ minw = TQMAX( minw, tminw );
+ if ( doc )
+ minw += doc->rightMargin();
+
+ int m = parag->bottomMargin();
+ if ( !parag->next() )
+ m = 0;
+ else
+ m = TQMAX(m, parag->next()->topMargin() ) / 2;
+ parag->setFullWidth( fullWidth );
+ y += TQMAX( h, linespacing ) + m;
+
+ wused += rm;
+ if ( !wrapEnabled || wrapAtColumn() != -1 )
+ minw = TQMAX(minw, wused);
+
+ // This is the case where we are breaking wherever we darn well please
+ // in cases like that, the minw should not be the length of the entire
+ // word, because we necessarily want to show the word on the whole line.
+ // example: word wrap in iconview
+ if ( allowBreakInWords() && minw > wused )
+ minw = wused;
+
+ thisminw = minw;
+ thiswused = wused;
+ return y;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextIndent::TQTextIndent()
+{
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+TQTextFormatCollection::TQTextFormatCollection()
+ : cKey( 307 ), painttqdevice( 0 )
+{
+ defFormat = new TQTextFormat( TQApplication::font(),
+ TQApplication::palette().color( TQPalette::Active, TQColorGroup::Text ) );
+ lastFormat = cres = 0;
+ cflags = -1;
+ cKey.setAutoDelete( TRUE );
+ cachedFormat = 0;
+}
+
+TQTextFormatCollection::~TQTextFormatCollection()
+{
+ delete defFormat;
+}
+
+void TQTextFormatCollection::setPaintDevice( TQPaintDevice *pd )
+{
+ painttqdevice = pd;
+
+#if defined(TQ_WS_X11)
+ int scr = ( painttqdevice ) ? painttqdevice->x11Screen() : TQPaintDevice::x11AppScreen();
+
+ defFormat->fn.tqt_x11SetScreen( scr );
+ defFormat->update();
+
+ TQDictIterator<TQTextFormat> it( cKey );
+ TQTextFormat *format;
+ while ( ( format = it.current() ) != 0 ) {
+ ++it;
+ format->fn.tqt_x11SetScreen( scr );
+ format->update();
+ }
+#endif // TQ_WS_X11
+}
+
+TQTextFormat *TQTextFormatCollection::format( TQTextFormat *f )
+{
+ if ( f->tqparent() == this || f == defFormat ) {
+ lastFormat = f;
+ lastFormat->addRef();
+ return lastFormat;
+ }
+
+ if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) {
+ lastFormat->addRef();
+ return lastFormat;
+ }
+
+ TQTextFormat *fm = cKey.tqfind( f->key() );
+ if ( fm ) {
+ lastFormat = fm;
+ lastFormat->addRef();
+ return lastFormat;
+ }
+
+ if ( f->key() == defFormat->key() )
+ return defFormat;
+
+ lastFormat = createFormat( *f );
+ lastFormat->collection = this;
+ cKey.insert( lastFormat->key(), lastFormat );
+ return lastFormat;
+}
+
+TQTextFormat *TQTextFormatCollection::format( TQTextFormat *of, TQTextFormat *nf, int flags )
+{
+ if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) {
+ cres->addRef();
+ return cres;
+ }
+
+ cres = createFormat( *of );
+ kof = of->key();
+ knf = nf->key();
+ cflags = flags;
+ if ( flags & TQTextFormat::Bold )
+ cres->fn.setBold( nf->fn.bold() );
+ if ( flags & TQTextFormat::Italic )
+ cres->fn.setItalic( nf->fn.italic() );
+ if ( flags & TQTextFormat::Underline )
+ cres->fn.setUnderline( nf->fn.underline() );
+ if ( flags & TQTextFormat::StrikeOut )
+ cres->fn.setStrikeOut( nf->fn.strikeOut() );
+ if ( flags & TQTextFormat::Family )
+ cres->fn.setFamily( nf->fn.family() );
+ if ( flags & TQTextFormat::Size ) {
+ if ( of->usePixelSizes )
+ cres->fn.setPixelSize( nf->fn.pixelSize() );
+ else
+ cres->fn.setPointSize( nf->fn.pointSize() );
+ }
+ if ( flags & TQTextFormat::Color )
+ cres->col = nf->col;
+ if ( flags & TQTextFormat::Misspelled )
+ cres->missp = nf->missp;
+ if ( flags & TQTextFormat::VAlign )
+ cres->ha = nf->ha;
+ cres->update();
+
+ TQTextFormat *fm = cKey.tqfind( cres->key() );
+ if ( !fm ) {
+ cres->collection = this;
+ cKey.insert( cres->key(), cres );
+ } else {
+ delete cres;
+ cres = fm;
+ cres->addRef();
+ }
+
+ return cres;
+}
+
+TQTextFormat *TQTextFormatCollection::format( const TQFont &f, const TQColor &c )
+{
+ if ( cachedFormat && cfont == f && ccol == c ) {
+ cachedFormat->addRef();
+ return cachedFormat;
+ }
+
+ TQString key = TQTextFormat::getKey( f, c, FALSE, TQTextFormat::AlignNormal );
+ cachedFormat = cKey.tqfind( key );
+ cfont = f;
+ ccol = c;
+
+ if ( cachedFormat ) {
+ cachedFormat->addRef();
+ return cachedFormat;
+ }
+
+ if ( key == defFormat->key() )
+ return defFormat;
+
+ cachedFormat = createFormat( f, c );
+ cachedFormat->collection = this;
+ cKey.insert( cachedFormat->key(), cachedFormat );
+ if ( cachedFormat->key() != key )
+ qWarning("ASSERT: keys for format not identical: '%s '%s'", cachedFormat->key().latin1(), key.latin1() );
+ return cachedFormat;
+}
+
+void TQTextFormatCollection::remove( TQTextFormat *f )
+{
+ if ( lastFormat == f )
+ lastFormat = 0;
+ if ( cres == f )
+ cres = 0;
+ if ( cachedFormat == f )
+ cachedFormat = 0;
+ if (cKey.tqfind(f->key()) == f)
+ cKey.remove( f->key() );
+}
+
+#define UPDATE( up, lo, rest ) \
+ if ( font.lo##rest() != defFormat->fn.lo##rest() && fm->fn.lo##rest() == defFormat->fn.lo##rest() ) \
+ fm->fn.set##up##rest( font.lo##rest() )
+
+void TQTextFormatCollection::updateDefaultFormat( const TQFont &font, const TQColor &color, TQStyleSheet *sheet )
+{
+ TQDictIterator<TQTextFormat> it( cKey );
+ TQTextFormat *fm;
+ bool usePixels = font.pointSize() == -1;
+ bool changeSize = usePixels ? font.pixelSize() != defFormat->fn.pixelSize() :
+ font.pointSize() != defFormat->fn.pointSize();
+ int base = usePixels ? font.pixelSize() : font.pointSize();
+ while ( ( fm = it.current() ) ) {
+ ++it;
+ UPDATE( F, f, amily );
+ UPDATE( W, w, eight );
+ UPDATE( B, b, old );
+ UPDATE( I, i, talic );
+ UPDATE( U, u, nderline );
+ if ( changeSize ) {
+ fm->stdSize = base;
+ fm->usePixelSizes = usePixels;
+ if ( usePixels )
+ fm->fn.setPixelSize( fm->stdSize );
+ else
+ fm->fn.setPointSize( fm->stdSize );
+ sheet->scaleFont( fm->fn, fm->logicalFontSize );
+ }
+ if ( color.isValid() && color != defFormat->col && fm->col == defFormat->col )
+ fm->col = color;
+ fm->update();
+ }
+
+ defFormat->fn = font;
+ defFormat->col = color;
+ defFormat->update();
+ defFormat->stdSize = base;
+ defFormat->usePixelSizes = usePixels;
+
+ updateKeys();
+}
+
+// the keys in cKey have changed, rebuild the hashtable
+void TQTextFormatCollection::updateKeys()
+{
+ if ( cKey.isEmpty() )
+ return;
+ cKey.setAutoDelete( FALSE );
+ TQTextFormat** formats = new TQTextFormat*[ cKey.count() + 1 ];
+ TQTextFormat **f = formats;
+ TQDictIterator<TQTextFormat> it( cKey );
+ while ( ( *f = it.current() ) ) {
+ ++it;
+ ++f;
+ }
+ cKey.clear();
+ for ( f = formats; *f; f++ )
+ cKey.insert( (*f)->key(), *f );
+ cKey.setAutoDelete( TRUE );
+ delete [] formats;
+}
+
+
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+void TQTextFormat::setBold( bool b )
+{
+ if ( b == fn.bold() )
+ return;
+ fn.setBold( b );
+ update();
+}
+
+void TQTextFormat::setMisspelled( bool b )
+{
+ if ( b == (bool)missp )
+ return;
+ missp = b;
+ update();
+}
+
+void TQTextFormat::setVAlign( VerticalAlignment a )
+{
+ if ( a == ha )
+ return;
+ ha = a;
+ update();
+}
+
+void TQTextFormat::setItalic( bool b )
+{
+ if ( b == fn.italic() )
+ return;
+ fn.setItalic( b );
+ update();
+}
+
+void TQTextFormat::setUnderline( bool b )
+{
+ if ( b == fn.underline() )
+ return;
+ fn.setUnderline( b );
+ update();
+}
+
+void TQTextFormat::setStrikeOut( bool b )
+{
+ if ( b == fn.strikeOut() )
+ return;
+ fn.setStrikeOut( b );
+ update();
+}
+
+void TQTextFormat::setFamily( const TQString &f )
+{
+ if ( f == fn.family() )
+ return;
+ fn.setFamily( f );
+ update();
+}
+
+void TQTextFormat::setPointSize( int s )
+{
+ if ( s == fn.pointSize() )
+ return;
+ fn.setPointSize( s );
+ usePixelSizes = FALSE;
+ update();
+}
+
+void TQTextFormat::setFont( const TQFont &f )
+{
+ if ( f == fn && !k.isEmpty() )
+ return;
+ fn = f;
+ update();
+}
+
+void TQTextFormat::setColor( const TQColor &c )
+{
+ if ( c == col )
+ return;
+ col = c;
+ update();
+}
+
+TQString TQTextFormat::makeFormatChangeTags( TQTextFormat* defaultFormat, TQTextFormat *f,
+ const TQString& oldAnchorHref, const TQString& anchorHref ) const
+{
+ TQString tag;
+ if ( f )
+ tag += f->makeFormatEndTags( defaultFormat, oldAnchorHref );
+
+ if ( !anchorHref.isEmpty() )
+ tag += "<a href=\"" + anchorHref + "\">";
+
+ if ( font() != defaultFormat->font()
+ || vAlign() != defaultFormat->vAlign()
+ || color().rgb() != defaultFormat->color().rgb() ) {
+ TQString s;
+ if ( font().family() != defaultFormat->font().family() )
+ s += TQString(!!s?";":"") + "font-family:" + fn.family();
+ if ( font().italic() && font().italic() != defaultFormat->font().italic() )
+ s += TQString(!!s?";":"") + "font-style:" + (font().italic() ? "italic" : "normal");
+ if ( font().pointSize() != defaultFormat->font().pointSize() )
+ s += TQString(!!s?";":"") + "font-size:" + TQString::number( fn.pointSize() ) + "pt";
+ if ( font().weight() != defaultFormat->font().weight() )
+ s += TQString(!!s?";":"") + "font-weight:" + TQString::number( fn.weight() * 8 );
+ TQString textDecoration;
+ bool none = FALSE;
+ if ( font().underline() != defaultFormat->font().underline() ) {
+ if (font().underline())
+ textDecoration = "underline";
+ else
+ none = TRUE;
+ }
+ if ( font().overline() != defaultFormat->font().overline() ) {
+ if (font().overline())
+ textDecoration += " overline";
+ else
+ none = TRUE;
+ }
+ if ( font().strikeOut() != defaultFormat->font().strikeOut() ) {
+ if (font().strikeOut())
+ textDecoration += " line-through";
+ else
+ none = TRUE;
+ }
+ if (none && textDecoration.isEmpty())
+ textDecoration = "none";
+ if (!textDecoration.isEmpty())
+ s += TQString(!!s?";":"") + "text-decoration:" + textDecoration;
+ if ( vAlign() != defaultFormat->vAlign() ) {
+ s += TQString(!!s?";":"") + "vertical-align:";
+ if ( vAlign() == TQTextFormat::AlignSuperScript )
+ s += "super";
+ else if ( vAlign() == TQTextFormat::AlignSubScript )
+ s += "sub";
+ else
+ s += "normal";
+ }
+ if ( color().rgb() != defaultFormat->color().rgb() )
+ s += TQString(!!s?";":"") + "color:" + col.name();
+ if ( !s.isEmpty() )
+ tag += "<span style=\"" + s + "\">";
+ }
+
+ return tag;
+}
+
+TQString TQTextFormat::makeFormatEndTags( TQTextFormat* defaultFormat, const TQString& anchorHref ) const
+{
+ TQString tag;
+ if ( font().family() != defaultFormat->font().family()
+ || font().pointSize() != defaultFormat->font().pointSize()
+ || font().weight() != defaultFormat->font().weight()
+ || font().italic() != defaultFormat->font().italic()
+ || font().underline() != defaultFormat->font().underline()
+ || font().strikeOut() != defaultFormat->font().strikeOut()
+ || vAlign() != defaultFormat->vAlign()
+ || color().rgb() != defaultFormat->color().rgb() )
+ tag += "</span>";
+ if ( !anchorHref.isEmpty() )
+ tag += "</a>";
+ return tag;
+}
+
+TQTextFormat TQTextFormat::makeTextFormat( const TQStyleSheetItem *style, const QMap<TQString,TQString>& attr, double scaleFontsFactor ) const
+{
+ TQTextFormat format(*this);
+ if (!style )
+ return format;
+
+ if ( !style->isAnchor() && style->color().isValid() ) {
+ // the style is not an anchor and defines a color.
+ // It might be used inside an anchor and it should
+ // override the link color.
+ format.linkColor = FALSE;
+ }
+ switch ( style->verticalAlignment() ) {
+ case TQStyleSheetItem::VAlignBaseline:
+ format.setVAlign( TQTextFormat::AlignNormal );
+ break;
+ case TQStyleSheetItem::VAlignSuper:
+ format.setVAlign( TQTextFormat::AlignSuperScript );
+ break;
+ case TQStyleSheetItem::VAlignSub:
+ format.setVAlign( TQTextFormat::AlignSubScript );
+ break;
+ }
+
+ if ( style->fontWeight() != TQStyleSheetItem::Undefined )
+ format.fn.setWeight( style->fontWeight() );
+ if ( style->fontSize() != TQStyleSheetItem::Undefined ) {
+ format.fn.setPointSize( style->fontSize() );
+ } else if ( style->logicalFontSize() != TQStyleSheetItem::Undefined ) {
+ format.logicalFontSize = style->logicalFontSize();
+ if ( format.usePixelSizes )
+ format.fn.setPixelSize( format.stdSize );
+ else
+ format.fn.setPointSize( format.stdSize );
+ style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
+ } else if ( style->logicalFontSizeStep() ) {
+ format.logicalFontSize += style->logicalFontSizeStep();
+ if ( format.usePixelSizes )
+ format.fn.setPixelSize( format.stdSize );
+ else
+ format.fn.setPointSize( format.stdSize );
+ style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
+ }
+ if ( !style->fontFamily().isEmpty() )
+ format.fn.setFamily( style->fontFamily() );
+ if ( style->color().isValid() )
+ format.col = style->color();
+ if ( style->definesFontItalic() )
+ format.fn.setItalic( style->fontItalic() );
+ if ( style->definesFontUnderline() )
+ format.fn.setUnderline( style->fontUnderline() );
+ if ( style->definesFontStrikeOut() )
+ format.fn.setStrikeOut( style->fontStrikeOut() );
+
+
+ if ( style->name() == "font") {
+ if ( attr.tqcontains("color") ) {
+ TQString s = attr["color"];
+ if ( !s.isEmpty() ) {
+ format.col.setNamedColor( s );
+ format.linkColor = FALSE;
+ }
+ }
+ if ( attr.tqcontains("face") ) {
+ TQString a = attr["face"];
+ TQString family = a.section( ',', 0, 0 );
+ if ( !!family )
+ format.fn.setFamily( family );
+ }
+ if ( attr.tqcontains("size") ) {
+ TQString a = attr["size"];
+ int n = a.toInt();
+ if ( a[0] == '+' || a[0] == '-' )
+ n += 3;
+ format.logicalFontSize = n;
+ if ( format.usePixelSizes )
+ format.fn.setPixelSize( format.stdSize );
+ else
+ format.fn.setPointSize( format.stdSize );
+ style->styleSheet()->scaleFont( format.fn, format.logicalFontSize );
+ }
+ }
+ if ( attr.tqcontains("style" ) ) {
+ TQString a = attr["style"];
+ for ( int s = 0; s < a.tqcontains(';')+1; s++ ) {
+ TQString style = a.section( ';', s, s );
+ if ( style.startsWith("font-size:" ) && style.endsWith("pt") ) {
+ format.logicalFontSize = 0;
+ int size = int( scaleFontsFactor * style.mid( 10, style.length() - 12 ).toDouble() );
+ format.setPointSize( size );
+ } else if ( style.startsWith("font-style:" ) ) {
+ TQString s = TQT_TQSTRING(style.mid( 11 )).stripWhiteSpace();
+ if ( s == "normal" )
+ format.fn.setItalic( FALSE );
+ else if ( s == "italic" || s == "oblique" )
+ format.fn.setItalic( TRUE );
+ } else if ( style.startsWith("font-weight:" ) ) {
+ TQString s = style.mid( 12 );
+ bool ok = TRUE;
+ int n = s.toInt( &ok );
+ if ( ok )
+ format.fn.setWeight( n/8 );
+ } else if ( style.startsWith("font-family:" ) ) {
+ TQString family = style.mid(12).section(',',0,0);
+ family.tqreplace( '\"', ' ' );
+ family.tqreplace( '\'', ' ' );
+ family = family.stripWhiteSpace();
+ format.fn.setFamily( family );
+ } else if ( style.startsWith("text-decoration:" ) ) {
+ TQString s = style.mid( 16 );
+ format.fn.setOverline( s.tqfind("overline") != -1 );
+ format.fn.setStrikeOut( s.tqfind("line-through") != -1 );
+ format.fn.setUnderline( s.tqfind("underline") != -1 );
+ } else if ( style.startsWith("vertical-align:" ) ) {
+ TQString s = TQT_TQSTRING(style.mid( 15 )).stripWhiteSpace();
+ if ( s == "sub" )
+ format.setVAlign( TQTextFormat::AlignSubScript );
+ else if ( s == "super" )
+ format.setVAlign( TQTextFormat::AlignSuperScript );
+ else
+ format.setVAlign( TQTextFormat::AlignNormal );
+ } else if ( style.startsWith("color:" ) ) {
+ format.col.setNamedColor( style.mid(6) );
+ format.linkColor = FALSE;
+ }
+ }
+ }
+
+ format.update();
+ return format;
+}
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+
+struct TQPixmapInt
+{
+ TQPixmapInt() : ref( 0 ) {}
+ TQPixmap pm;
+ int ref;
+ TQ_DUMMY_COMPARISON_OPERATOR(TQPixmapInt)
+};
+
+static QMap<TQString, TQPixmapInt> *pixmap_map = 0;
+
+TQTextImage::TQTextImage( TQTextDocument *p, const QMap<TQString, TQString> &attr, const TQString& context,
+ TQMimeSourceFactory &factory )
+ : TQTextCustomItem( p )
+{
+ width = height = 0;
+ if ( attr.tqcontains("width") )
+ width = attr["width"].toInt();
+ if ( attr.tqcontains("height") )
+ height = attr["height"].toInt();
+
+ reg = 0;
+ TQString imageName = attr["src"];
+
+ if (!imageName)
+ imageName = attr["source"];
+
+ if ( !imageName.isEmpty() ) {
+ imgId = TQString( "%1,%2,%3,%4" ).arg( imageName ).arg( width ).arg( height ).arg( (ulong)&factory );
+ if ( !pixmap_map )
+ pixmap_map = new QMap<TQString, TQPixmapInt>;
+ if ( pixmap_map->tqcontains( imgId ) ) {
+ TQPixmapInt& pmi = pixmap_map->operator[](imgId);
+ pm = pmi.pm;
+ pmi.ref++;
+ width = pm.width();
+ height = pm.height();
+ } else {
+ TQImage img;
+ const TQMimeSource* m =
+ factory.data( imageName, context );
+ if ( !m ) {
+ qWarning("TQTextImage: no mimesource for %s", imageName.latin1() );
+ }
+ else {
+ if ( !TQImageDrag::decode( m, img ) ) {
+ qWarning("TQTextImage: cannot decode %s", imageName.latin1() );
+ }
+ }
+
+ if ( !img.isNull() ) {
+ if ( width == 0 ) {
+ width = img.width();
+ if ( height != 0 ) {
+ width = img.width() * height / img.height();
+ }
+ }
+ if ( height == 0 ) {
+ height = img.height();
+ if ( width != img.width() ) {
+ height = img.height() * width / img.width();
+ }
+ }
+ if ( img.width() != width || img.height() != height ){
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+ img = img.smoothScale(width, height);
+#endif
+ width = img.width();
+ height = img.height();
+ }
+ pm.convertFromImage( img );
+ }
+ if ( !pm.isNull() ) {
+ TQPixmapInt& pmi = pixmap_map->operator[](imgId);
+ pmi.pm = pm;
+ pmi.ref++;
+ }
+ }
+ if ( pm.tqmask() ) {
+ TQRegion tqmask( *pm.tqmask() );
+ TQRegion all( 0, 0, pm.width(), pm.height() );
+ reg = new TQRegion( all.subtract( tqmask ) );
+ }
+ }
+
+ if ( pm.isNull() && (width*height)==0 )
+ width = height = 50;
+
+ place = PlaceInline;
+ if ( attr["align"] == "left" )
+ place = PlaceLeft;
+ else if ( attr["align"] == "right" )
+ place = PlaceRight;
+
+ tmpwidth = width;
+ tmpheight = height;
+
+ attributes = attr;
+}
+
+TQTextImage::~TQTextImage()
+{
+ if ( pixmap_map && pixmap_map->tqcontains( imgId ) ) {
+ TQPixmapInt& pmi = pixmap_map->operator[](imgId);
+ pmi.ref--;
+ if ( !pmi.ref ) {
+ pixmap_map->remove( imgId );
+ if ( pixmap_map->isEmpty() ) {
+ delete pixmap_map;
+ pixmap_map = 0;
+ }
+ }
+ }
+ delete reg;
+}
+
+TQString TQTextImage::richText() const
+{
+ TQString s;
+ s += "<img ";
+ QMap<TQString, TQString>::ConstIterator it = attributes.begin();
+ for ( ; it != attributes.end(); ++it ) {
+ s += it.key() + "=";
+ if ( (*it).tqfind( ' ' ) != -1 )
+ s += "\"" + *it + "\"" + " ";
+ else
+ s += *it + " ";
+ }
+ s += ">";
+ return s;
+}
+
+void TQTextImage::adjustToPainter( TQPainter* p )
+{
+ width = scale( tmpwidth, p );
+ height = scale( tmpheight, p );
+}
+
+#if !defined(TQ_WS_X11)
+#include <tqbitmap.h>
+#include <tqcleanuphandler.h>
+static TQPixmap *qrt_selection = 0;
+static TQSingleCleanupHandler<TQPixmap> qrt_cleanup_pixmap;
+static void qrt_createSelectionPixmap( const TQColorGroup &cg )
+{
+ qrt_selection = new TQPixmap( 2, 2 );
+ qrt_cleanup_pixmap.set( &qrt_selection );
+ qrt_selection->fill( TQt::color0 );
+ TQBitmap m( 2, 2 );
+ m.fill( TQt::color1 );
+ TQPainter p( &m );
+ p.setPen( TQt::color0 );
+ for ( int j = 0; j < 2; ++j ) {
+ p.drawPoint( j % 2, j );
+ }
+ p.end();
+ qrt_selection->setMask( m );
+ qrt_selection->fill( cg.highlight() );
+}
+#endif
+
+void TQTextImage::draw( TQPainter* p, int x, int y, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected )
+{
+ if ( placement() != PlaceInline ) {
+ x = xpos;
+ y = ypos;
+ }
+
+ if ( pm.isNull() ) {
+ p->fillRect( x , y, width, height, cg.dark() );
+ return;
+ }
+
+ if ( is_printer( p ) ) {
+ p->drawPixmap( TQRect( x, y, width, height ), pm );
+ return;
+ }
+
+ if ( placement() != PlaceInline && !TQRect( xpos, ypos, width, height ).intersects( TQRect( cx, cy, cw, ch ) ) )
+ return;
+
+ if ( placement() == PlaceInline )
+ p->drawPixmap( x , y, pm );
+ else
+ p->drawPixmap( cx , cy, pm, cx - x, cy - y, cw, ch );
+
+ if ( selected && placement() == PlaceInline && is_printer( p ) ) {
+#if defined(TQ_WS_X11)
+ p->fillRect( TQRect( TQPoint( x, y ), pm.size() ), TQBrush( cg.highlight(), Qt::Dense4Pattern) );
+#else // in WIN32 Dense4Pattern doesn't work correctly (transparency problem), so work around it
+ if ( !qrt_selection )
+ qrt_createSelectionPixmap( cg );
+ p->drawTiledPixmap( x, y, pm.width(), pm.height(), *qrt_selection );
+#endif
+ }
+}
+
+void TQTextHorizontalLine::adjustToPainter( TQPainter* p )
+{
+ height = scale( tmpheight, p );
+}
+
+
+TQTextHorizontalLine::TQTextHorizontalLine( TQTextDocument *p, const QMap<TQString, TQString> &attr,
+ const TQString &,
+ TQMimeSourceFactory & )
+ : TQTextCustomItem( p )
+{
+ height = tmpheight = 8;
+ if ( attr.tqfind( "color" ) != attr.end() )
+ color = TQColor( *attr.tqfind( "color" ) );
+ shade = attr.tqfind( "noshade" ) == attr.end();
+}
+
+TQTextHorizontalLine::~TQTextHorizontalLine()
+{
+}
+
+TQString TQTextHorizontalLine::richText() const
+{
+ return "<hr>";
+}
+
+void TQTextHorizontalLine::draw( TQPainter* p, int x, int y, int , int , int , int , const TQColorGroup& cg, bool selected )
+{
+ TQRect r( x, y, width, height);
+ if ( is_printer( p ) || !shade ) {
+ TQPen oldPen = p->pen();
+ if ( !color.isValid() )
+ p->setPen( TQPen( cg.text(), is_printer( p ) ? height/8 : TQMAX( 2, height/4 ) ) );
+ else
+ p->setPen( TQPen( color, is_printer( p ) ? height/8 : TQMAX( 2, height/4 ) ) );
+ p->drawLine( r.left()-1, y + height / 2, r.right() + 1, y + height / 2 );
+ p->setPen( oldPen );
+ } else {
+ TQColorGroup g( cg );
+ if ( color.isValid() )
+ g.setColor( TQColorGroup::Dark, color );
+ if ( selected )
+ p->fillRect( r, g.highlight() );
+ qDrawShadeLine( p, r.left() - 1, y + height / 2, r.right() + 1, y + height / 2, g, TRUE, height / 8 );
+ }
+}
+#endif //TQT_NO_TEXTCUSTOMITEM
+
+/*****************************************************************/
+// Small set of utility functions to make the parser a bit simpler
+//
+
+bool TQTextDocument::hasPrefix(const TQChar* doc, int length, int pos, TQChar c)
+{
+ if ( pos + 1 > length )
+ return FALSE;
+ return doc[ pos ].lower() == c.lower();
+}
+
+bool TQTextDocument::hasPrefix( const TQChar* doc, int length, int pos, const TQString& s )
+{
+ if ( pos + (int) s.length() > length )
+ return FALSE;
+ for ( int i = 0; i < (int)s.length(); i++ ) {
+ if ( doc[ pos + i ].lower() != s[ i ].lower() )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+static bool qt_is_cell_in_use( TQPtrList<TQTextTableCell>& cells, int row, int col )
+{
+ for ( TQTextTableCell* c = cells.first(); c; c = cells.next() ) {
+ if ( row >= c->row() && row < c->row() + c->rowspan()
+ && col >= c->column() && col < c->column() + c->colspan() )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+TQTextCustomItem* TQTextDocument::parseTable( const QMap<TQString, TQString> &attr, const TQTextFormat &fmt,
+ const TQChar* doc, int length, int& pos, TQTextParagraph *curpar )
+{
+
+ TQTextTable* table = new TQTextTable( this, attr );
+ int row = -1;
+ int col = -1;
+
+ TQString rowbgcolor;
+ TQString rowalign;
+ TQString tablebgcolor = attr["bgcolor"];
+
+ TQPtrList<TQTextTableCell> multicells;
+
+ TQString tagname;
+ (void) eatSpace(doc, length, pos);
+ while ( pos < length) {
+ if (hasPrefix(doc, length, pos, TQChar('<')) ){
+ if (hasPrefix(doc, length, pos+1, TQChar('/'))) {
+ tagname = parseCloseTag( doc, length, pos );
+ if ( tagname == "table" ) {
+ return table;
+ }
+ } else {
+ QMap<TQString, TQString> attr2;
+ bool emptyTag = FALSE;
+ tagname = parseOpenTag( doc, length, pos, attr2, emptyTag );
+ if ( tagname == "tr" ) {
+ rowbgcolor = attr2["bgcolor"];
+ rowalign = attr2["align"];
+ row++;
+ col = -1;
+ }
+ else if ( tagname == "td" || tagname == "th" ) {
+ col++;
+ while ( qt_is_cell_in_use( multicells, row, col ) ) {
+ col++;
+ }
+
+ if ( row >= 0 && col >= 0 ) {
+ const TQStyleSheetItem* s = sheet_->item(tagname);
+ if ( !attr2.tqcontains("bgcolor") ) {
+ if (!rowbgcolor.isEmpty() )
+ attr2["bgcolor"] = rowbgcolor;
+ else if (!tablebgcolor.isEmpty() )
+ attr2["bgcolor"] = tablebgcolor;
+ }
+ if ( !attr2.tqcontains("align") ) {
+ if (!rowalign.isEmpty() )
+ attr2["align"] = rowalign;
+ }
+
+ // extract the cell contents
+ int end = pos;
+ while ( end < length
+ && !hasPrefix( doc, length, end, "</td")
+ && !hasPrefix( doc, length, end, "<td")
+ && !hasPrefix( doc, length, end, "</th")
+ && !hasPrefix( doc, length, end, "<th")
+ && !hasPrefix( doc, length, end, "<td")
+ && !hasPrefix( doc, length, end, "</tr")
+ && !hasPrefix( doc, length, end, "<tr")
+ && !hasPrefix( doc, length, end, "</table") ) {
+ if ( hasPrefix( doc, length, end, "<table" ) ) { // nested table
+ int nested = 1;
+ ++end;
+ while ( end < length && nested != 0 ) {
+ if ( hasPrefix( doc, length, end, "</table" ) )
+ nested--;
+ if ( hasPrefix( doc, length, end, "<table" ) )
+ nested++;
+ end++;
+ }
+ }
+ end++;
+ }
+ TQTextTableCell* cell = new TQTextTableCell( table, row, col,
+ attr2, s, fmt.makeTextFormat( s, attr2, scaleFontsFactor ),
+ contxt, *factory_, sheet_,
+ TQConstString( doc + pos, end - pos ).string() );
+ cell->richText()->parentPar = curpar;
+ if ( cell->colspan() > 1 || cell->rowspan() > 1 )
+ multicells.append( cell );
+ col += cell->colspan()-1;
+ pos = end;
+ }
+ }
+ }
+
+ } else {
+ ++pos;
+ }
+ }
+ return table;
+}
+#endif // TQT_NO_TEXTCUSTOMITEM
+
+bool TQTextDocument::eatSpace(const TQChar* doc, int length, int& pos, bool includeNbsp )
+{
+ int old_pos = pos;
+ while (pos < length && doc[pos].isSpace() && ( includeNbsp || (doc[pos] != TQChar::nbsp ) ) )
+ pos++;
+ return old_pos < pos;
+}
+
+bool TQTextDocument::eat(const TQChar* doc, int length, int& pos, TQChar c)
+{
+ bool ok = pos < length && doc[pos] == c;
+ if ( ok )
+ pos++;
+ return ok;
+}
+/*****************************************************************/
+
+struct Entity {
+ const char * name;
+ TQ_UINT16 code;
+};
+
+static const Entity entitylist [] = {
+ { "AElig", 0x00c6 },
+ { "Aacute", 0x00c1 },
+ { "Acirc", 0x00c2 },
+ { "Agrave", 0x00c0 },
+ { "Alpha", 0x0391 },
+ { "AMP", 38 },
+ { "Aring", 0x00c5 },
+ { "Atilde", 0x00c3 },
+ { "Auml", 0x00c4 },
+ { "Beta", 0x0392 },
+ { "Ccedil", 0x00c7 },
+ { "Chi", 0x03a7 },
+ { "Dagger", 0x2021 },
+ { "Delta", 0x0394 },
+ { "ETH", 0x00d0 },
+ { "Eacute", 0x00c9 },
+ { "Ecirc", 0x00ca },
+ { "Egrave", 0x00c8 },
+ { "Epsilon", 0x0395 },
+ { "Eta", 0x0397 },
+ { "Euml", 0x00cb },
+ { "Gamma", 0x0393 },
+ { "GT", 62 },
+ { "Iacute", 0x00cd },
+ { "Icirc", 0x00ce },
+ { "Igrave", 0x00cc },
+ { "Iota", 0x0399 },
+ { "Iuml", 0x00cf },
+ { "Kappa", 0x039a },
+ { "Lambda", 0x039b },
+ { "LT", 60 },
+ { "Mu", 0x039c },
+ { "Ntilde", 0x00d1 },
+ { "Nu", 0x039d },
+ { "OElig", 0x0152 },
+ { "Oacute", 0x00d3 },
+ { "Ocirc", 0x00d4 },
+ { "Ograve", 0x00d2 },
+ { "Omega", 0x03a9 },
+ { "Omicron", 0x039f },
+ { "Oslash", 0x00d8 },
+ { "Otilde", 0x00d5 },
+ { "Ouml", 0x00d6 },
+ { "Phi", 0x03a6 },
+ { "Pi", 0x03a0 },
+ { "Prime", 0x2033 },
+ { "Psi", 0x03a8 },
+ { "TQUOT", 34 },
+ { "Rho", 0x03a1 },
+ { "Scaron", 0x0160 },
+ { "Sigma", 0x03a3 },
+ { "THORN", 0x00de },
+ { "Tau", 0x03a4 },
+ { "Theta", 0x0398 },
+ { "Uacute", 0x00da },
+ { "Ucirc", 0x00db },
+ { "Ugrave", 0x00d9 },
+ { "Upsilon", 0x03a5 },
+ { "Uuml", 0x00dc },
+ { "Xi", 0x039e },
+ { "Yacute", 0x00dd },
+ { "Yuml", 0x0178 },
+ { "Zeta", 0x0396 },
+ { "aacute", 0x00e1 },
+ { "acirc", 0x00e2 },
+ { "acute", 0x00b4 },
+ { "aelig", 0x00e6 },
+ { "agrave", 0x00e0 },
+ { "alefsym", 0x2135 },
+ { "alpha", 0x03b1 },
+ { "amp", 38 },
+ { "and", 0x22a5 },
+ { "ang", 0x2220 },
+ { "apos", 0x0027 },
+ { "aring", 0x00e5 },
+ { "asymp", 0x2248 },
+ { "atilde", 0x00e3 },
+ { "auml", 0x00e4 },
+ { "bdquo", 0x201e },
+ { "beta", 0x03b2 },
+ { "brvbar", 0x00a6 },
+ { "bull", 0x2022 },
+ { "cap", 0x2229 },
+ { "ccedil", 0x00e7 },
+ { "cedil", 0x00b8 },
+ { "cent", 0x00a2 },
+ { "chi", 0x03c7 },
+ { "circ", 0x02c6 },
+ { "clubs", 0x2663 },
+ { "cong", 0x2245 },
+ { "copy", 0x00a9 },
+ { "crarr", 0x21b5 },
+ { "cup", 0x222a },
+ { "curren", 0x00a4 },
+ { "dArr", 0x21d3 },
+ { "dagger", 0x2020 },
+ { "darr", 0x2193 },
+ { "deg", 0x00b0 },
+ { "delta", 0x03b4 },
+ { "diams", 0x2666 },
+ { "divide", 0x00f7 },
+ { "eacute", 0x00e9 },
+ { "ecirc", 0x00ea },
+ { "egrave", 0x00e8 },
+ { "empty", 0x2205 },
+ { "emsp", 0x2003 },
+ { "ensp", 0x2002 },
+ { "epsilon", 0x03b5 },
+ { "equiv", 0x2261 },
+ { "eta", 0x03b7 },
+ { "eth", 0x00f0 },
+ { "euml", 0x00eb },
+ { "euro", 0x20ac },
+ { "exist", 0x2203 },
+ { "fnof", 0x0192 },
+ { "forall", 0x2200 },
+ { "frac12", 0x00bd },
+ { "frac14", 0x00bc },
+ { "frac34", 0x00be },
+ { "frasl", 0x2044 },
+ { "gamma", 0x03b3 },
+ { "ge", 0x2265 },
+ { "gt", 62 },
+ { "hArr", 0x21d4 },
+ { "harr", 0x2194 },
+ { "hearts", 0x2665 },
+ { "hellip", 0x2026 },
+ { "iacute", 0x00ed },
+ { "icirc", 0x00ee },
+ { "iexcl", 0x00a1 },
+ { "igrave", 0x00ec },
+ { "image", 0x2111 },
+ { "infin", 0x221e },
+ { "int", 0x222b },
+ { "iota", 0x03b9 },
+ { "iquest", 0x00bf },
+ { "isin", 0x2208 },
+ { "iuml", 0x00ef },
+ { "kappa", 0x03ba },
+ { "lArr", 0x21d0 },
+ { "lambda", 0x03bb },
+ { "lang", 0x2329 },
+ { "laquo", 0x00ab },
+ { "larr", 0x2190 },
+ { "lceil", 0x2308 },
+ { "ldquo", 0x201c },
+ { "le", 0x2264 },
+ { "lfloor", 0x230a },
+ { "lowast", 0x2217 },
+ { "loz", 0x25ca },
+ { "lrm", 0x200e },
+ { "lsaquo", 0x2039 },
+ { "lsquo", 0x2018 },
+ { "lt", 60 },
+ { "macr", 0x00af },
+ { "mdash", 0x2014 },
+ { "micro", 0x00b5 },
+ { "middot", 0x00b7 },
+ { "minus", 0x2212 },
+ { "mu", 0x03bc },
+ { "nabla", 0x2207 },
+ { "nbsp", 0x00a0 },
+ { "ndash", 0x2013 },
+ { "ne", 0x2260 },
+ { "ni", 0x220b },
+ { "not", 0x00ac },
+ { "notin", 0x2209 },
+ { "nsub", 0x2284 },
+ { "ntilde", 0x00f1 },
+ { "nu", 0x03bd },
+ { "oacute", 0x00f3 },
+ { "ocirc", 0x00f4 },
+ { "oelig", 0x0153 },
+ { "ograve", 0x00f2 },
+ { "oline", 0x203e },
+ { "omega", 0x03c9 },
+ { "omicron", 0x03bf },
+ { "oplus", 0x2295 },
+ { "or", 0x22a6 },
+ { "ordf", 0x00aa },
+ { "ordm", 0x00ba },
+ { "oslash", 0x00f8 },
+ { "otilde", 0x00f5 },
+ { "otimes", 0x2297 },
+ { "ouml", 0x00f6 },
+ { "para", 0x00b6 },
+ { "part", 0x2202 },
+ { "percnt", 0x0025 },
+ { "permil", 0x2030 },
+ { "perp", 0x22a5 },
+ { "phi", 0x03c6 },
+ { "pi", 0x03c0 },
+ { "piv", 0x03d6 },
+ { "plusmn", 0x00b1 },
+ { "pound", 0x00a3 },
+ { "prime", 0x2032 },
+ { "prod", 0x220f },
+ { "prop", 0x221d },
+ { "psi", 0x03c8 },
+ { "quot", 34 },
+ { "rArr", 0x21d2 },
+ { "radic", 0x221a },
+ { "rang", 0x232a },
+ { "raquo", 0x00bb },
+ { "rarr", 0x2192 },
+ { "rceil", 0x2309 },
+ { "rdquo", 0x201d },
+ { "real", 0x211c },
+ { "reg", 0x00ae },
+ { "rfloor", 0x230b },
+ { "rho", 0x03c1 },
+ { "rlm", 0x200f },
+ { "rsaquo", 0x203a },
+ { "rsquo", 0x2019 },
+ { "sbquo", 0x201a },
+ { "scaron", 0x0161 },
+ { "sdot", 0x22c5 },
+ { "sect", 0x00a7 },
+ { "shy", 0x00ad },
+ { "sigma", 0x03c3 },
+ { "sigmaf", 0x03c2 },
+ { "sim", 0x223c },
+ { "spades", 0x2660 },
+ { "sub", 0x2282 },
+ { "sube", 0x2286 },
+ { "sum", 0x2211 },
+ { "sup1", 0x00b9 },
+ { "sup2", 0x00b2 },
+ { "sup3", 0x00b3 },
+ { "sup", 0x2283 },
+ { "supe", 0x2287 },
+ { "szlig", 0x00df },
+ { "tau", 0x03c4 },
+ { "there4", 0x2234 },
+ { "theta", 0x03b8 },
+ { "thetasym", 0x03d1 },
+ { "thinsp", 0x2009 },
+ { "thorn", 0x00fe },
+ { "tilde", 0x02dc },
+ { "times", 0x00d7 },
+ { "trade", 0x2122 },
+ { "uArr", 0x21d1 },
+ { "uacute", 0x00fa },
+ { "uarr", 0x2191 },
+ { "ucirc", 0x00fb },
+ { "ugrave", 0x00f9 },
+ { "uml", 0x00a8 },
+ { "upsih", 0x03d2 },
+ { "upsilon", 0x03c5 },
+ { "uuml", 0x00fc },
+ { "weierp", 0x2118 },
+ { "xi", 0x03be },
+ { "yacute", 0x00fd },
+ { "yen", 0x00a5 },
+ { "yuml", 0x00ff },
+ { "zeta", 0x03b6 },
+ { "zwj", 0x200d },
+ { "zwnj", 0x200c },
+ { "", 0x0000 }
+};
+
+
+
+
+
+static QMap<TQString, TQChar> *html_map = 0;
+static void qt_cleanup_html_map()
+{
+ delete html_map;
+ html_map = 0;
+}
+
+static QMap<TQString, TQChar> *htmlMap()
+{
+ if ( !html_map ) {
+ html_map = new QMap<TQString, TQChar>;
+ qAddPostRoutine( qt_cleanup_html_map );
+
+ const Entity *ent = entitylist;
+ while( ent->code ) {
+ html_map->insert( ent->name, TQChar(ent->code) );
+ ent++;
+ }
+ }
+ return html_map;
+}
+
+TQChar TQTextDocument::parseHTMLSpecialChar(const TQChar* doc, int length, int& pos)
+{
+ TQString s;
+ pos++;
+ int recoverpos = pos;
+ while ( pos < length && doc[pos] != ';' && !doc[pos].isSpace() && pos < recoverpos + 8 ) {
+ s += doc[pos];
+ pos++;
+ }
+ if (doc[pos] != ';' && !doc[pos].isSpace() ) {
+ pos = recoverpos;
+ return '&';
+ }
+ pos++;
+
+ if ( s.length() > 1 && s[0] == '#') {
+ int off = 1;
+ int base = 10;
+ if (s[1] == 'x') {
+ off = 2;
+ base = 16;
+ }
+ bool ok;
+ int num = s.mid(off).toInt(&ok, base);
+ if ( num == 151 ) // ### hack for designer manual
+ return '-';
+ if (ok)
+ return num;
+ } else {
+ QMap<TQString, TQChar>::Iterator it = htmlMap()->tqfind(s);
+ if ( it != htmlMap()->end() ) {
+ return *it;
+ }
+ }
+
+ pos = recoverpos;
+ return '&';
+}
+
+TQString TQTextDocument::parseWord(const TQChar* doc, int length, int& pos, bool lower)
+{
+ TQString s;
+
+ if (doc[pos] == '"') {
+ pos++;
+ while ( pos < length && doc[pos] != '"' ) {
+ if ( doc[pos] == '&' ) {
+ s += parseHTMLSpecialChar( doc, length, pos );
+ } else {
+ s += doc[pos];
+ pos++;
+ }
+ }
+ eat(doc, length, pos, '"');
+ } else if (doc[pos] == '\'') {
+ pos++;
+ while ( pos < length && doc[pos] != '\'' ) {
+ s += doc[pos];
+ pos++;
+ }
+ eat(doc, length, pos, '\'');
+ } else {
+ static TQString term = TQString::tqfromLatin1("/>");
+ while ( pos < length
+ && doc[pos] != '>'
+ && !hasPrefix(doc, length, pos, term)
+ && doc[pos] != '<'
+ && doc[pos] != '='
+ && !doc[pos].isSpace() )
+ {
+ if ( doc[pos] == '&' ) {
+ s += parseHTMLSpecialChar( doc, length, pos );
+ } else {
+ s += doc[pos];
+ pos++;
+ }
+ }
+ if (lower)
+ s = s.lower();
+ }
+ return s;
+}
+
+TQChar TQTextDocument::parseChar(const TQChar* doc, int length, int& pos, TQStyleSheetItem::WhiteSpaceMode wsm )
+{
+ if ( pos >= length )
+ return TQChar::null;
+
+ TQChar c = doc[pos++];
+
+ if (c == '<' )
+ return TQChar::null;
+
+ if ( c.isSpace() && c != TQChar::nbsp ) {
+ if ( wsm == TQStyleSheetItem::WhiteSpacePre ) {
+ if ( c == '\n' )
+ return TQChar_linesep;
+ else
+ return c;
+ } else { // non-pre mode: collapse whitespace except nbsp
+ while ( pos< length &&
+ doc[pos].isSpace() && doc[pos] != TQChar::nbsp )
+ pos++;
+ return ' ';
+ }
+ }
+ else if ( c == '&' )
+ return parseHTMLSpecialChar( doc, length, --pos );
+ else
+ return c;
+}
+
+TQString TQTextDocument::parseOpenTag(const TQChar* doc, int length, int& pos,
+ QMap<TQString, TQString> &attr, bool& emptyTag)
+{
+ emptyTag = FALSE;
+ pos++;
+ if ( hasPrefix(doc, length, pos, '!') ) {
+ if ( hasPrefix( doc, length, pos+1, "--")) {
+ pos += 3;
+ // eat comments
+ TQString pref = TQString::tqfromLatin1("-->");
+ while ( !hasPrefix(doc, length, pos, pref ) && pos < length )
+ pos++;
+ if ( hasPrefix(doc, length, pos, pref ) ) {
+ pos += 3;
+ eatSpace(doc, length, pos, TRUE);
+ }
+ emptyTag = TRUE;
+ return TQString::null;
+ }
+ else {
+ // eat strange internal tags
+ while ( !hasPrefix(doc, length, pos, '>') && pos < length )
+ pos++;
+ if ( hasPrefix(doc, length, pos, '>') ) {
+ pos++;
+ eatSpace(doc, length, pos, TRUE);
+ }
+ return TQString::null;
+ }
+ }
+
+ TQString tag = parseWord(doc, length, pos );
+ eatSpace(doc, length, pos, TRUE);
+ static TQString term = TQString::tqfromLatin1("/>");
+ static TQString s_TRUE = TQString::tqfromLatin1("TRUE");
+
+ while (doc[pos] != '>' && ! (emptyTag = hasPrefix(doc, length, pos, term) )) {
+ TQString key = parseWord(doc, length, pos );
+ eatSpace(doc, length, pos, TRUE);
+ if ( key.isEmpty()) {
+ // error recovery
+ while ( pos < length && doc[pos] != '>' )
+ pos++;
+ break;
+ }
+ TQString value;
+ if (hasPrefix(doc, length, pos, '=') ){
+ pos++;
+ eatSpace(doc, length, pos);
+ value = parseWord(doc, length, pos, FALSE);
+ }
+ else
+ value = s_TRUE;
+ attr.insert(key.lower(), value );
+ eatSpace(doc, length, pos, TRUE);
+ }
+
+ if (emptyTag) {
+ eat(doc, length, pos, '/');
+ eat(doc, length, pos, '>');
+ }
+ else
+ eat(doc, length, pos, '>');
+
+ return tag;
+}
+
+TQString TQTextDocument::parseCloseTag( const TQChar* doc, int length, int& pos )
+{
+ pos++;
+ pos++;
+ TQString tag = parseWord(doc, length, pos );
+ eatSpace(doc, length, pos, TRUE);
+ eat(doc, length, pos, '>');
+ return tag;
+}
+
+TQTextFlow::TQTextFlow()
+{
+ w = pagesize = 0;
+}
+
+TQTextFlow::~TQTextFlow()
+{
+ clear();
+}
+
+void TQTextFlow::clear()
+{
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ leftItems.setAutoDelete( TRUE );
+ rightItems.setAutoDelete( TRUE );
+ leftItems.clear();
+ rightItems.clear();
+ leftItems.setAutoDelete( FALSE );
+ rightItems.setAutoDelete( FALSE );
+#endif
+}
+
+void TQTextFlow::setWidth( int width )
+{
+ w = width;
+}
+
+int TQTextFlow::adjustLMargin( int yp, int, int margin, int space )
+{
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ for ( TQTextCustomItem* item = leftItems.first(); item; item = leftItems.next() ) {
+ if ( item->ypos == -1 )
+ continue;
+ if ( yp >= item->ypos && yp < item->ypos + item->height )
+ margin = TQMAX( margin, item->xpos + item->width + space );
+ }
+#endif
+ return margin;
+}
+
+int TQTextFlow::adjustRMargin( int yp, int, int margin, int space )
+{
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ for ( TQTextCustomItem* item = rightItems.first(); item; item = rightItems.next() ) {
+ if ( item->ypos == -1 )
+ continue;
+ if ( yp >= item->ypos && yp < item->ypos + item->height )
+ margin = TQMAX( margin, w - item->xpos - space );
+ }
+#endif
+ return margin;
+}
+
+
+int TQTextFlow::adjustFlow( int y, int /*w*/, int h )
+{
+ if ( pagesize > 0 ) { // check pages
+ int yinpage = y % pagesize;
+ if ( yinpage <= border_tolerance )
+ return border_tolerance - yinpage;
+ else
+ if ( yinpage + h > pagesize - border_tolerance )
+ return ( pagesize - yinpage ) + border_tolerance;
+ }
+ return 0;
+}
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+void TQTextFlow::unregisterFloatingItem( TQTextCustomItem* item )
+{
+ leftItems.removeRef( item );
+ rightItems.removeRef( item );
+}
+
+void TQTextFlow::registerFloatingItem( TQTextCustomItem* item )
+{
+ if ( item->placement() == TQTextCustomItem::PlaceRight ) {
+ if ( !rightItems.tqcontains( item ) )
+ rightItems.append( item );
+ } else if ( item->placement() == TQTextCustomItem::PlaceLeft &&
+ !leftItems.tqcontains( item ) ) {
+ leftItems.append( item );
+ }
+}
+#endif // TQT_NO_TEXTCUSTOMITEM
+
+TQRect TQTextFlow::boundingRect() const
+{
+ TQRect br;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQPtrListIterator<TQTextCustomItem> l( leftItems );
+ while( l.current() ) {
+ br = br.unite( l.current()->tqgeometry() );
+ ++l;
+ }
+ TQPtrListIterator<TQTextCustomItem> r( rightItems );
+ while( r.current() ) {
+ br = br.unite( r.current()->tqgeometry() );
+ ++r;
+ }
+#endif
+ return br;
+}
+
+
+void TQTextFlow::drawFloatingItems( TQPainter* p, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected )
+{
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem *item;
+ for ( item = leftItems.first(); item; item = leftItems.next() ) {
+ if ( item->xpos == -1 || item->ypos == -1 )
+ continue;
+ item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected );
+ }
+
+ for ( item = rightItems.first(); item; item = rightItems.next() ) {
+ if ( item->xpos == -1 || item->ypos == -1 )
+ continue;
+ item->draw( p, item->xpos, item->ypos, cx, cy, cw, ch, cg, selected );
+ }
+#endif
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+void TQTextCustomItem::pageBreak( int /*y*/ , TQTextFlow* /*flow*/ )
+{
+}
+#endif
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+TQTextTable::TQTextTable( TQTextDocument *p, const QMap<TQString, TQString> & attr )
+ : TQTextCustomItem( p )
+{
+ cells.setAutoDelete( FALSE );
+ cellspacing = 2;
+ if ( attr.tqcontains("cellspacing") )
+ cellspacing = attr["cellspacing"].toInt();
+ cellpadding = 1;
+ if ( attr.tqcontains("cellpadding") )
+ cellpadding = attr["cellpadding"].toInt();
+ border = innerborder = 0;
+ if ( attr.tqcontains("border" ) ) {
+ TQString s( attr["border"] );
+ if ( s == "TRUE" )
+ border = 1;
+ else
+ border = attr["border"].toInt();
+ }
+ us_b = border;
+
+ innerborder = us_ib = border ? 1 : 0;
+
+ if ( border )
+ cellspacing += 2;
+
+ us_ib = innerborder;
+ us_cs = cellspacing;
+ us_cp = cellpadding;
+ outerborder = cellspacing + border;
+ us_ob = outerborder;
+ tqlayout = new TQGridLayout( 1, 1, cellspacing );
+
+ fixwidth = 0;
+ stretch = 0;
+ if ( attr.tqcontains("width") ) {
+ bool b;
+ TQString s( attr["width"] );
+ int w = s.toInt( &b );
+ if ( b ) {
+ fixwidth = w;
+ } else {
+ s = s.stripWhiteSpace();
+ if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' )
+ stretch = s.left( s.length()-1).toInt();
+ }
+ }
+ us_fixwidth = fixwidth;
+
+ place = PlaceInline;
+ if ( attr["align"] == "left" )
+ place = PlaceLeft;
+ else if ( attr["align"] == "right" )
+ place = PlaceRight;
+ cachewidth = 0;
+ attributes = attr;
+ pageBreakFor = -1;
+}
+
+TQTextTable::~TQTextTable()
+{
+ delete tqlayout;
+}
+
+TQString TQTextTable::richText() const
+{
+ TQString s;
+ s = "<table ";
+ QMap<TQString, TQString>::ConstIterator it = attributes.begin();
+ for ( ; it != attributes.end(); ++it )
+ s += it.key() + "=" + *it + " ";
+ s += ">\n";
+
+ int lastRow = -1;
+ bool needEnd = FALSE;
+ TQPtrListIterator<TQTextTableCell> it2( cells );
+ while ( it2.current() ) {
+ TQTextTableCell *cell = it2.current();
+ ++it2;
+ if ( lastRow != cell->row() ) {
+ if ( lastRow != -1 )
+ s += "</tr>\n";
+ s += "<tr>";
+ lastRow = cell->row();
+ needEnd = TRUE;
+ }
+ s += "<td";
+ it = cell->attributes.begin();
+ for ( ; it != cell->attributes.end(); ++it )
+ s += " " + it.key() + "=" + *it;
+ s += ">";
+ s += cell->richText()->richText();
+ s += "</td>";
+ }
+ if ( needEnd )
+ s += "</tr>\n";
+ s += "</table>\n";
+ return s;
+}
+
+void TQTextTable::setParagraph(TQTextParagraph *p)
+{
+ for ( TQTextTableCell* cell = cells.first(); cell; cell = cells.next() )
+ cell->richText()->parentPar = p;
+ TQTextCustomItem::setParagraph(p);
+}
+
+void TQTextTable::adjustToPainter( TQPainter* p )
+{
+ cellspacing = scale( us_cs, p );
+ cellpadding = scale( us_cp, p );
+ border = scale( us_b , p );
+ innerborder = scale( us_ib, p );
+ outerborder = scale( us_ob ,p );
+ fixwidth = scale( us_fixwidth, p);
+ width = 0;
+ cachewidth = 0;
+ for ( TQTextTableCell* cell = cells.first(); cell; cell = cells.next() )
+ cell->adjustToPainter( p );
+}
+
+void TQTextTable::adjustCells( int y , int shift )
+{
+ TQPtrListIterator<TQTextTableCell> it( cells );
+ TQTextTableCell* cell;
+ bool enlarge = FALSE;
+ while ( ( cell = it.current() ) ) {
+ ++it;
+ TQRect r = cell->tqgeometry();
+ if ( y <= r.top() ) {
+ r.moveBy(0, shift );
+ cell->setGeometry( r );
+ enlarge = TRUE;
+ } else if ( y <= r.bottom() ) {
+ r.rBottom() += shift;
+ cell->setGeometry( r );
+ enlarge = TRUE;
+ }
+ }
+ if ( enlarge )
+ height += shift;
+}
+
+void TQTextTable::pageBreak( int yt, TQTextFlow* flow )
+{
+ if ( flow->pageSize() <= 0 )
+ return;
+ if ( tqlayout && pageBreakFor > 0 && pageBreakFor != yt ) {
+ tqlayout->tqinvalidate();
+ int h = tqlayout->heightForWidth( width-2*outerborder );
+ tqlayout->setGeometry( TQRect(0, 0, width-2*outerborder, h) );
+ height = tqlayout->tqgeometry().height()+2*outerborder;
+ }
+ pageBreakFor = yt;
+ TQPtrListIterator<TQTextTableCell> it( cells );
+ TQTextTableCell* cell;
+ while ( ( cell = it.current() ) ) {
+ ++it;
+ int y = yt + outerborder + cell->tqgeometry().y();
+ int shift = flow->adjustFlow( y - cellspacing, width, cell->richText()->height() + 2*cellspacing );
+ adjustCells( y - outerborder - yt, shift );
+ }
+}
+
+
+void TQTextTable::draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected )
+{
+ if ( placement() != PlaceInline ) {
+ x = xpos;
+ y = ypos;
+ }
+
+ for (TQTextTableCell* cell = cells.first(); cell; cell = cells.next() ) {
+ if ( (cx < 0 && cy) < 0 ||
+ TQRect( cx, cy, cw, ch ).intersects( TQRect( x + outerborder + cell->tqgeometry().x(),
+ y + outerborder + cell->tqgeometry().y(),
+ cell->tqgeometry().width(), cell->tqgeometry().height() ) ) ) {
+ cell->draw( p, x+outerborder, y+outerborder, cx, cy, cw, ch, cg, selected );
+ if ( border ) {
+ TQRect r( x+outerborder+cell->tqgeometry().x() - innerborder,
+ y+outerborder+cell->tqgeometry().y() - innerborder,
+ cell->tqgeometry().width() + 2 * innerborder,
+ cell->tqgeometry().height() + 2 * innerborder );
+ if ( is_printer( p ) ) {
+ TQPen oldPen = p->pen();
+ TQRect r2 = r;
+ r2.addCoords( innerborder/2, innerborder/2, -innerborder/2, -innerborder/2 );
+ p->setPen( TQPen( cg.text(), innerborder ) );
+ p->drawRect( r2 );
+ p->setPen( oldPen );
+ } else {
+ int s = TQMAX( cellspacing-2*innerborder, 0);
+ if ( s ) {
+ p->fillRect( r.left()-s, r.top(), s+1, r.height(), cg.button() );
+ p->fillRect( r.right(), r.top(), s+1, r.height(), cg.button() );
+ p->fillRect( r.left()-s, r.top()-s, r.width()+2*s, s, cg.button() );
+ p->fillRect( r.left()-s, r.bottom(), r.width()+2*s, s, cg.button() );
+ }
+ qDrawShadePanel( p, r, cg, TRUE, innerborder );
+ }
+ }
+ }
+ }
+ if ( border ) {
+ TQRect r ( x, y, width, height );
+ if ( is_printer( p ) ) {
+ TQRect r2 = r;
+ r2.addCoords( border/2, border/2, -border/2, -border/2 );
+ TQPen oldPen = p->pen();
+ p->setPen( TQPen( cg.text(), border ) );
+ p->drawRect( r2 );
+ p->setPen( oldPen );
+ } else {
+ int s = border+TQMAX( cellspacing-2*innerborder, 0);
+ if ( s ) {
+ p->fillRect( r.left(), r.top(), s, r.height(), cg.button() );
+ p->fillRect( r.right()-s, r.top(), s, r.height(), cg.button() );
+ p->fillRect( r.left(), r.top(), r.width(), s, cg.button() );
+ p->fillRect( r.left(), r.bottom()-s, r.width(), s, cg.button() );
+ }
+ qDrawShadePanel( p, r, cg, FALSE, border );
+ }
+ }
+
+}
+
+int TQTextTable::minimumWidth() const
+{
+ return fixwidth ? fixwidth : ((tqlayout ? tqlayout->tqminimumSize().width() : 0) + 2 * outerborder);
+}
+
+void TQTextTable::resize( int nwidth )
+{
+ if ( fixwidth && cachewidth != 0 )
+ return;
+ if ( nwidth == cachewidth )
+ return;
+
+
+ cachewidth = nwidth;
+ int w = nwidth;
+
+ format( w );
+
+ if ( stretch )
+ nwidth = nwidth * stretch / 100;
+
+ width = nwidth;
+ tqlayout->tqinvalidate();
+ int shw = tqlayout->tqsizeHint().width() + 2*outerborder;
+ int mw = tqlayout->tqminimumSize().width() + 2*outerborder;
+ if ( stretch )
+ width = TQMAX( mw, nwidth );
+ else
+ width = TQMAX( mw, TQMIN( nwidth, shw ) );
+
+ if ( fixwidth )
+ width = fixwidth;
+
+ tqlayout->tqinvalidate();
+ mw = tqlayout->tqminimumSize().width() + 2*outerborder;
+ width = TQMAX( width, mw );
+
+ int h = tqlayout->heightForWidth( width-2*outerborder );
+ tqlayout->setGeometry( TQRect(0, 0, width-2*outerborder, h) );
+ height = tqlayout->tqgeometry().height()+2*outerborder;
+}
+
+void TQTextTable::format( int w )
+{
+ for ( int i = 0; i < (int)cells.count(); ++i ) {
+ TQTextTableCell *cell = cells.at( i );
+ TQRect r = cell->tqgeometry();
+ r.setWidth( w - 2*outerborder );
+ cell->setGeometry( r );
+ }
+}
+
+void TQTextTable::addCell( TQTextTableCell* cell )
+{
+ cells.append( cell );
+ tqlayout->addMultiCell( cell, cell->row(), cell->row() + cell->rowspan()-1,
+ cell->column(), cell->column() + cell->colspan()-1 );
+}
+
+bool TQTextTable::enter( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd )
+{
+ currCell.remove( c );
+ if ( !atEnd )
+ return next( c, doc, parag, idx, ox, oy );
+ currCell.insert( c, cells.count() );
+ return prev( c, doc, parag, idx, ox, oy );
+}
+
+bool TQTextTable::enterAt( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, const TQPoint &pos )
+{
+ currCell.remove( c );
+ int lastCell = -1;
+ int lastY = -1;
+ int i;
+ for ( i = 0; i < (int)cells.count(); ++i ) {
+ TQTextTableCell *cell = cells.at( i );
+ if ( !cell )
+ continue;
+ TQRect r( cell->tqgeometry().x(),
+ cell->tqgeometry().y(),
+ cell->tqgeometry().width() + 2 * innerborder + 2 * outerborder,
+ cell->tqgeometry().height() + 2 * innerborder + 2 * outerborder );
+
+ if ( r.left() <= pos.x() && r.right() >= pos.x() ) {
+ if ( cell->tqgeometry().y() > lastY ) {
+ lastCell = i;
+ lastY = cell->tqgeometry().y();
+ }
+ if ( r.top() <= pos.y() && r.bottom() >= pos.y() ) {
+ currCell.insert( c, i );
+ break;
+ }
+ }
+ }
+ if ( i == (int) cells.count() )
+ return FALSE; // no cell found
+
+ if ( currCell.tqfind( c ) == currCell.end() ) {
+ if ( lastY != -1 )
+ currCell.insert( c, lastCell );
+ else
+ return FALSE;
+ }
+
+ TQTextTableCell *cell = cells.at( *currCell.tqfind( c ) );
+ if ( !cell )
+ return FALSE;
+ doc = cell->richText();
+ parag = doc->firstParagraph();
+ idx = 0;
+ ox += cell->tqgeometry().x() + cell->horizontalAlignmentOffset() + outerborder + tqparent->x();
+ oy += cell->tqgeometry().y() + cell->verticalAlignmentOffset() + outerborder;
+ return TRUE;
+}
+
+bool TQTextTable::next( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy )
+{
+ int cc = -1;
+ if ( currCell.tqfind( c ) != currCell.end() )
+ cc = *currCell.tqfind( c );
+ if ( cc > (int)cells.count() - 1 || cc < 0 )
+ cc = -1;
+ currCell.remove( c );
+ currCell.insert( c, ++cc );
+ if ( cc >= (int)cells.count() ) {
+ currCell.insert( c, 0 );
+ TQTextCustomItem::next( c, doc, parag, idx, ox, oy );
+ TQTextTableCell *cell = cells.first();
+ if ( !cell )
+ return FALSE;
+ doc = cell->richText();
+ idx = -1;
+ return TRUE;
+ }
+
+ if ( currCell.tqfind( c ) == currCell.end() )
+ return FALSE;
+ TQTextTableCell *cell = cells.at( *currCell.tqfind( c ) );
+ if ( !cell )
+ return FALSE;
+ doc = cell->richText();
+ parag = doc->firstParagraph();
+ idx = 0;
+ ox += cell->tqgeometry().x() + cell->horizontalAlignmentOffset() + outerborder + tqparent->x();
+ oy += cell->tqgeometry().y() + cell->verticalAlignmentOffset() + outerborder;
+ return TRUE;
+}
+
+bool TQTextTable::prev( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy )
+{
+ int cc = -1;
+ if ( currCell.tqfind( c ) != currCell.end() )
+ cc = *currCell.tqfind( c );
+ if ( cc > (int)cells.count() - 1 || cc < 0 )
+ cc = cells.count();
+ currCell.remove( c );
+ currCell.insert( c, --cc );
+ if ( cc < 0 ) {
+ currCell.insert( c, 0 );
+ TQTextCustomItem::prev( c, doc, parag, idx, ox, oy );
+ TQTextTableCell *cell = cells.first();
+ if ( !cell )
+ return FALSE;
+ doc = cell->richText();
+ idx = -1;
+ return TRUE;
+ }
+
+ if ( currCell.tqfind( c ) == currCell.end() )
+ return FALSE;
+ TQTextTableCell *cell = cells.at( *currCell.tqfind( c ) );
+ if ( !cell )
+ return FALSE;
+ doc = cell->richText();
+ parag = doc->lastParagraph();
+ idx = parag->length() - 1;
+ ox += cell->tqgeometry().x() + cell->horizontalAlignmentOffset() + outerborder + tqparent->x();
+ oy += cell->tqgeometry().y() + cell->verticalAlignmentOffset() + outerborder;
+ return TRUE;
+}
+
+bool TQTextTable::down( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy )
+{
+ if ( currCell.tqfind( c ) == currCell.end() )
+ return FALSE;
+ TQTextTableCell *cell = cells.at( *currCell.tqfind( c ) );
+ if ( cell->row_ == tqlayout->numRows() - 1 ) {
+ currCell.insert( c, 0 );
+ TQTextCustomItem::down( c, doc, parag, idx, ox, oy );
+ TQTextTableCell *cell = cells.first();
+ if ( !cell )
+ return FALSE;
+ doc = cell->richText();
+ idx = -1;
+ return TRUE;
+ }
+
+ int oldRow = cell->row_;
+ int oldCol = cell->col_;
+ if ( currCell.tqfind( c ) == currCell.end() )
+ return FALSE;
+ int cc = *currCell.tqfind( c );
+ for ( int i = cc; i < (int)cells.count(); ++i ) {
+ cell = cells.at( i );
+ if ( cell->row_ > oldRow && cell->col_ == oldCol ) {
+ currCell.insert( c, i );
+ break;
+ }
+ }
+ doc = cell->richText();
+ if ( !cell )
+ return FALSE;
+ parag = doc->firstParagraph();
+ idx = 0;
+ ox += cell->tqgeometry().x() + cell->horizontalAlignmentOffset() + outerborder + tqparent->x();
+ oy += cell->tqgeometry().y() + cell->verticalAlignmentOffset() + outerborder;
+ return TRUE;
+}
+
+bool TQTextTable::up( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy )
+{
+ if ( currCell.tqfind( c ) == currCell.end() )
+ return FALSE;
+ TQTextTableCell *cell = cells.at( *currCell.tqfind( c ) );
+ if ( cell->row_ == 0 ) {
+ currCell.insert( c, 0 );
+ TQTextCustomItem::up( c, doc, parag, idx, ox, oy );
+ TQTextTableCell *cell = cells.first();
+ if ( !cell )
+ return FALSE;
+ doc = cell->richText();
+ idx = -1;
+ return TRUE;
+ }
+
+ int oldRow = cell->row_;
+ int oldCol = cell->col_;
+ if ( currCell.tqfind( c ) == currCell.end() )
+ return FALSE;
+ int cc = *currCell.tqfind( c );
+ for ( int i = cc; i >= 0; --i ) {
+ cell = cells.at( i );
+ if ( cell->row_ < oldRow && cell->col_ == oldCol ) {
+ currCell.insert( c, i );
+ break;
+ }
+ }
+ doc = cell->richText();
+ if ( !cell )
+ return FALSE;
+ parag = doc->lastParagraph();
+ idx = parag->length() - 1;
+ ox += cell->tqgeometry().x() + cell->horizontalAlignmentOffset() + outerborder + tqparent->x();
+ oy += cell->tqgeometry().y() + cell->verticalAlignmentOffset() + outerborder;
+ return TRUE;
+}
+
+TQTextTableCell::TQTextTableCell( TQTextTable* table,
+ int row, int column,
+ const QMap<TQString, TQString> &attr,
+ const TQStyleSheetItem* /*style*/, // ### use them
+ const TQTextFormat& fmt, const TQString& context,
+ TQMimeSourceFactory &factory, TQStyleSheet *sheet,
+ const TQString& doc)
+{
+ cached_width = -1;
+ cached_sizehint = -1;
+
+ maxw = TQWIDGETSIZE_MAX;
+ minw = 0;
+
+ tqparent = table;
+ row_ = row;
+ col_ = column;
+ stretch_ = 0;
+ richtext = new TQTextDocument( table->tqparent );
+ richtext->formatCollection()->setPaintDevice( table->tqparent->formatCollection()->paintDevice() );
+ richtext->bodyText = fmt.color();
+ richtext->setTableCell( this );
+ TQString a = *attr.tqfind( "align" );
+ if ( !a.isEmpty() ) {
+ a = a.lower();
+ if ( a == "left" )
+ richtext->tqsetAlignment( TQt::AlignLeft );
+ else if ( a == "center" )
+ richtext->tqsetAlignment( TQt::AlignHCenter );
+ else if ( a == "right" )
+ richtext->tqsetAlignment( TQt::AlignRight );
+ }
+ align = 0;
+ TQString va = *attr.tqfind( "valign" );
+ if ( !va.isEmpty() ) {
+ va = va.lower();
+ if ( va == "top" )
+ align |= TQt::AlignTop;
+ else if ( va == "center" || va == "middle" )
+ align |= TQt::AlignVCenter;
+ else if ( va == "bottom" )
+ align |= TQt::AlignBottom;
+ }
+ richtext->setFormatter( table->tqparent->formatter() );
+ richtext->setUseFormatCollection( table->tqparent->useFormatCollection() );
+ richtext->setMimeSourceFactory( &factory );
+ richtext->setStyleSheet( sheet );
+ richtext->setRichText( doc, context, &fmt );
+ rowspan_ = 1;
+ colspan_ = 1;
+ if ( attr.tqcontains("colspan") )
+ colspan_ = attr["colspan"].toInt();
+ if ( attr.tqcontains("rowspan") )
+ rowspan_ = attr["rowspan"].toInt();
+
+ background = 0;
+ if ( attr.tqcontains("bgcolor") ) {
+ background = new TQBrush(TQColor( attr["bgcolor"] ));
+ }
+
+
+ hasFixedWidth = FALSE;
+ if ( attr.tqcontains("width") ) {
+ bool b;
+ TQString s( attr["width"] );
+ int w = s.toInt( &b );
+ if ( b ) {
+ maxw = w;
+ minw = maxw;
+ hasFixedWidth = TRUE;
+ } else {
+ s = s.stripWhiteSpace();
+ if ( s.length() > 1 && s[ (int)s.length()-1 ] == '%' )
+ stretch_ = s.left( s.length()-1).toInt();
+ }
+ }
+
+ attributes = attr;
+
+ tqparent->addCell( this );
+}
+
+TQTextTableCell::~TQTextTableCell()
+{
+ delete background;
+ background = 0;
+ delete richtext;
+ richtext = 0;
+}
+
+TQSize TQTextTableCell::tqsizeHint() const
+{
+ int extra = 2 * ( tqparent->innerborder + tqparent->cellpadding + border_tolerance);
+ int used = richtext->widthUsed() + extra;
+
+ if (stretch_ ) {
+ int w = tqparent->width * stretch_ / 100 - 2*tqparent->cellspacing - 2*tqparent->cellpadding;
+ return TQSize( TQMIN( w, maxw ), 0 ).expandedTo( tqminimumSize() );
+ }
+
+ return TQSize( used, 0 ).expandedTo( tqminimumSize() );
+}
+
+TQSize TQTextTableCell::tqminimumSize() const
+{
+ int extra = 2 * ( tqparent->innerborder + tqparent->cellpadding + border_tolerance);
+ return TQSize( TQMAX( richtext->minimumWidth() + extra, minw), 0 );
+}
+
+TQSize TQTextTableCell::tqmaximumSize() const
+{
+ return TQSize( maxw, TQWIDGETSIZE_MAX );
+}
+
+TQ_SPExpandData TQTextTableCell::expandingDirections() const
+{
+ return (TQ_SPExpandData)TQSizePolicy::BothDirections;
+}
+
+bool TQTextTableCell::isEmpty() const
+{
+ return FALSE;
+}
+void TQTextTableCell::setGeometry( const TQRect& r )
+{
+ int extra = 2 * ( tqparent->innerborder + tqparent->cellpadding );
+ if ( r.width() != cached_width )
+ richtext->doLayout( TQTextFormat::painter(), r.width() - extra );
+ cached_width = r.width();
+ geom = r;
+}
+
+TQRect TQTextTableCell::tqgeometry() const
+{
+ return geom;
+}
+
+bool TQTextTableCell::hasHeightForWidth() const
+{
+ return TRUE;
+}
+
+int TQTextTableCell::heightForWidth( int w ) const
+{
+ int extra = 2 * ( tqparent->innerborder + tqparent->cellpadding );
+ w = TQMAX( minw, w );
+
+ if ( cached_width != w ) {
+ TQTextTableCell* that = (TQTextTableCell*) this;
+ that->richtext->doLayout( TQTextFormat::painter(), w - extra );
+ that->cached_width = w;
+ }
+ return richtext->height() + extra;
+}
+
+void TQTextTableCell::adjustToPainter( TQPainter* p )
+{
+ TQTextParagraph *parag = richtext->firstParagraph();
+ while ( parag ) {
+ parag->adjustToPainter( p );
+ parag = parag->next();
+ }
+}
+
+int TQTextTableCell::horizontalAlignmentOffset() const
+{
+ return tqparent->cellpadding;
+}
+
+int TQTextTableCell::verticalAlignmentOffset() const
+{
+ if ( (align & TQt::AlignVCenter ) == TQt::AlignVCenter )
+ return ( geom.height() - richtext->height() ) / 2;
+ else if ( ( align & TQt::AlignBottom ) == TQt::AlignBottom )
+ return geom.height() - tqparent->cellpadding - richtext->height() ;
+ return tqparent->cellpadding;
+}
+
+void TQTextTableCell::draw( TQPainter* p, int x, int y, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool )
+{
+ if ( cached_width != geom.width() ) {
+ int extra = 2 * ( tqparent->innerborder + tqparent->cellpadding );
+ richtext->doLayout( p, geom.width() - extra );
+ cached_width = geom.width();
+ }
+ TQColorGroup g( cg );
+ if ( background )
+ g.setBrush( TQColorGroup::Base, *background );
+ else if ( richtext->paper() )
+ g.setBrush( TQColorGroup::Base, *richtext->paper() );
+
+ p->save();
+ p->translate( x + geom.x(), y + geom.y() );
+ if ( background )
+ p->fillRect( 0, 0, geom.width(), geom.height(), *background );
+ else if ( richtext->paper() )
+ p->fillRect( 0, 0, geom.width(), geom.height(), *richtext->paper() );
+
+ p->translate( horizontalAlignmentOffset(), verticalAlignmentOffset() );
+
+ TQRegion r;
+ if ( cx >= 0 && cy >= 0 )
+ richtext->draw( p, cx - ( x + horizontalAlignmentOffset() + geom.x() ),
+ cy - ( y + geom.y() + verticalAlignmentOffset() ),
+ cw, ch, g, FALSE, FALSE, 0 );
+ else
+ richtext->draw( p, -1, -1, -1, -1, g, FALSE, FALSE, 0 );
+
+ p->restore();
+}
+#endif
+
+#endif //TQT_NO_RICHTEXT
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqrichtext_p.cpp b/tqtinterface/qt4/src/kernel/tqrichtext_p.cpp
new file mode 100644
index 0000000..d8504df
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqrichtext_p.cpp
@@ -0,0 +1,1283 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+// #if 0
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqrichtext_p.h"
+#include "tqpainter.h"
+
+#ifndef QT_NO_RICHTEXT
+
+QT_BEGIN_NAMESPACE
+
+TQTextCommand::~TQTextCommand() {}
+TQTextCommand::Commands TQTextCommand::type() const { return Invalid; }
+
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+TQTextCustomItem::~TQTextCustomItem() {}
+void TQTextCustomItem::adjustToPainter(TQPainter* p){ if (p) width = 0; }
+TQTextCustomItem::Placement TQTextCustomItem::placement() const { return PlaceInline; }
+
+bool TQTextCustomItem::ownLine() const { return false; }
+void TQTextCustomItem::resize(int nwidth){ width = nwidth; }
+void TQTextCustomItem::invalidate() {}
+
+bool TQTextCustomItem::isNested() const { return false; }
+int TQTextCustomItem::minimumWidth() const { return 0; }
+
+TQString TQTextCustomItem::richText() const { return TQString(); }
+
+bool TQTextCustomItem::enter(TQTextCursor *, TQTextDocument*&, TQTextParagraph *&, int &, int &, int &, bool)
+{
+ return true;
+}
+bool TQTextCustomItem::enterAt(TQTextCursor *, TQTextDocument *&, TQTextParagraph *&, int &, int &, int &, const QPoint &)
+{
+ return true;
+}
+bool TQTextCustomItem::next(TQTextCursor *, TQTextDocument *&, TQTextParagraph *&, int &, int &, int &)
+{
+ return true;
+}
+bool TQTextCustomItem::prev(TQTextCursor *, TQTextDocument *&, TQTextParagraph *&, int &, int &, int &)
+{
+ return true;
+}
+bool TQTextCustomItem::down(TQTextCursor *, TQTextDocument *&, TQTextParagraph *&, int &, int &, int &)
+{
+ return true;
+}
+bool TQTextCustomItem::up(TQTextCursor *, TQTextDocument *&, TQTextParagraph *&, int &, int &, int &)
+{
+ return true;
+}
+#endif // QT_NO_TEXTCUSTOMITEM
+
+void TQTextFlow::setPageSize(int ps) { pagesize = ps; }
+#ifndef QT_NO_TEXTCUSTOMITEM
+bool TQTextFlow::isEmpty() { return leftItems.isEmpty() && rightItems.isEmpty(); }
+#else
+bool TQTextFlow::isEmpty() { return true; }
+#endif
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+void TQTextTableCell::invalidate() { cached_width = -1; cached_sizehint = -1; }
+
+void TQTextTable::invalidate() { cachewidth = -1; }
+#endif
+
+TQTextParagraphData::~TQTextParagraphData() {}
+void TQTextParagraphData::join(TQTextParagraphData *) {}
+
+TQTextFormatter::~TQTextFormatter() {}
+void TQTextFormatter::setWrapEnabled(bool b) { wrapEnabled = b; }
+void TQTextFormatter::setWrapAtColumn(int c) { wrapColumn = c; }
+
+
+
+int TQTextCursor::x() const
+{
+ if (idx >= para->length())
+ return 0;
+ TQTextStringChar *c = para->at(idx);
+ int curx = c->x;
+ if (!c->rightToLeft &&
+ c->c.isSpace() &&
+ idx > 0 &&
+ para->at(idx - 1)->c != QLatin1Char('\t') &&
+ !c->lineStart &&
+ (para->alignment() & Qt::AlignJustify) == Qt::AlignJustify)
+ curx = para->at(idx - 1)->x + para->string()->width(idx - 1);
+ if (c->rightToLeft)
+ curx += para->string()->width(idx);
+ return curx;
+}
+
+int TQTextCursor::y() const
+{
+ int dummy, line;
+ para->lineStartOfChar(idx, &dummy, &line);
+ return para->lineY(line);
+}
+
+int TQTextCursor::globalX() const { return totalOffsetX() + para->rect().x() + x(); }
+int TQTextCursor::globalY() const { return totalOffsetY() + para->rect().y() + y(); }
+
+TQTextDocument *TQTextCursor::document() const
+{
+ return para ? para->document() : 0;
+}
+
+void TQTextCursor::gotoPosition(TQTextParagraph* p, int index)
+{
+ if (para && p != para) {
+ while (!indices.isEmpty() && para->document() != p->document())
+ pop();
+ Q_ASSERT(indices.isEmpty() || para->document() == p->document());
+ }
+ para = p;
+ if (index < 0 || index >= para->length()) {
+ qWarning("TQTextCursor::gotoParagraph Index: %d out of range", index);
+ if (index < 0 || para->length() == 0)
+ index = 0;
+ else
+ index = para->length() - 1;
+ }
+
+ tmpX = -1;
+ idx = index;
+ fixCursorPosition();
+}
+
+bool TQTextDocument::hasSelection(int id, bool visible) const
+{
+ return (selections.find(id) != selections.end() &&
+ (!visible ||
+ ((TQTextDocument*)this)->selectionStartCursor(id) !=
+ ((TQTextDocument*)this)->selectionEndCursor(id)));
+}
+
+void TQTextDocument::setSelectionStart(int id, const TQTextCursor &cursor)
+{
+ TQTextDocumentSelection sel;
+ sel.startCursor = cursor;
+ sel.endCursor = cursor;
+ sel.swapped = false;
+ selections[id] = sel;
+}
+
+TQTextParagraph *TQTextDocument::paragAt(int i) const
+{
+ TQTextParagraph* p = curParag;
+ if (!p || p->paragId() > i)
+ p = fParag;
+ while (p && p->paragId() != i)
+ p = p->next();
+ ((TQTextDocument*)this)->curParag = p;
+ return p;
+}
+
+
+TQTextFormat::~TQTextFormat()
+{
+}
+
+TQTextFormat::TQTextFormat()
+ : fm(QFontMetrics(fn)), linkColor(true), logicalFontSize(3), stdSize(qApp->font().pointSize())
+{
+ ref = 0;
+
+ usePixelSizes = false;
+ if (stdSize == -1) {
+ stdSize = qApp->font().pixelSize();
+ usePixelSizes = true;
+ }
+
+ missp = false;
+ ha = AlignNormal;
+ collection = 0;
+}
+
+TQTextFormat::TQTextFormat(const TQStyleSheetItem *style)
+ : fm(QFontMetrics(fn)), linkColor(true), logicalFontSize(3), stdSize(qApp->font().pointSize())
+{
+ ref = 0;
+
+ usePixelSizes = false;
+ if (stdSize == -1) {
+ stdSize = qApp->font().pixelSize();
+ usePixelSizes = true;
+ }
+
+ missp = false;
+ ha = AlignNormal;
+ collection = 0;
+ fn = QFont(style->fontFamily(),
+ style->fontSize(),
+ style->fontWeight(),
+ style->fontItalic());
+ fn.setUnderline(style->fontUnderline());
+ fn.setStrikeOut(style->fontStrikeOut());
+ col = style->color();
+ fm = QFontMetrics(fn);
+ leftBearing = fm.minLeftBearing();
+ rightBearing = fm.minRightBearing();
+ hei = fm.lineSpacing();
+ asc = fm.ascent() + (fm.leading()+1)/2;
+ dsc = fm.descent();
+ missp = false;
+ ha = AlignNormal;
+ memset(widths, 0, 256);
+ generateKey();
+ addRef();
+}
+
+TQTextFormat::TQTextFormat(const QFont &f, const QColor &c, TQTextFormatCollection *parent)
+ : fn(f), col(c), fm(QFontMetrics(f)), linkColor(true),
+ logicalFontSize(3), stdSize(f.pointSize())
+{
+ ref = 0;
+ usePixelSizes = false;
+ if (stdSize == -1) {
+ stdSize = f.pixelSize();
+ usePixelSizes = true;
+ }
+ collection = parent;
+ leftBearing = fm.minLeftBearing();
+ rightBearing = fm.minRightBearing();
+ hei = fm.lineSpacing();
+ asc = fm.ascent() + (fm.leading()+1)/2;
+ dsc = fm.descent();
+ missp = false;
+ ha = AlignNormal;
+ memset(widths, 0, 256);
+ generateKey();
+ addRef();
+}
+
+TQTextFormat::TQTextFormat(const TQTextFormat &f)
+ : fm(f.fm)
+{
+ ref = 0;
+ collection = 0;
+ fn = f.fn;
+ col = f.col;
+ leftBearing = f.leftBearing;
+ rightBearing = f.rightBearing;
+ memset(widths, 0, 256);
+ hei = f.hei;
+ asc = f.asc;
+ dsc = f.dsc;
+ stdSize = f.stdSize;
+ usePixelSizes = f.usePixelSizes;
+ logicalFontSize = f.logicalFontSize;
+ missp = f.missp;
+ ha = f.ha;
+ k = f.k;
+ linkColor = f.linkColor;
+ addRef();
+}
+
+TQTextFormat& TQTextFormat::operator=(const TQTextFormat &f)
+{
+ ref = 0;
+ collection = f.collection;
+ fn = f.fn;
+ col = f.col;
+ fm = f.fm;
+ leftBearing = f.leftBearing;
+ rightBearing = f.rightBearing;
+ memset(widths, 0, 256);
+ hei = f.hei;
+ asc = f.asc;
+ dsc = f.dsc;
+ stdSize = f.stdSize;
+ usePixelSizes = f.usePixelSizes;
+ logicalFontSize = f.logicalFontSize;
+ missp = f.missp;
+ ha = f.ha;
+ k = f.k;
+ linkColor = f.linkColor;
+ addRef();
+ return *this;
+}
+
+void TQTextFormat::update()
+{
+ fm = QFontMetrics(fn);
+ leftBearing = fm.minLeftBearing();
+ rightBearing = fm.minRightBearing();
+ hei = fm.lineSpacing();
+ asc = fm.ascent() + (fm.leading()+1)/2;
+ dsc = fm.descent();
+ memset(widths, 0, 256);
+ generateKey();
+}
+
+
+TQPainter* TQTextFormat::pntr = 0;
+QFontMetrics* TQTextFormat::pntr_fm = 0;
+int TQTextFormat::pntr_ldg=-1;
+int TQTextFormat::pntr_asc=-1;
+int TQTextFormat::pntr_hei=-1;
+int TQTextFormat::pntr_dsc=-1;
+
+void TQTextFormat::setPainter(TQPainter *p)
+{
+ pntr = p;
+}
+
+TQPainter* TQTextFormat::painter()
+{
+ return pntr;
+}
+
+void TQTextFormat::applyFont(const QFont &f)
+{
+ QFontMetrics fm(pntr->fontMetrics());
+ if (!pntr_fm || pntr->font() != f) {
+ pntr->setFont(f);
+ delete pntr_fm;
+ pntr_fm = new QFontMetrics(pntr->fontMetrics());
+ pntr_ldg = pntr_fm->leading();
+ pntr_asc = pntr_fm->ascent()+(pntr_ldg+1)/2;
+ pntr_hei = pntr_fm->lineSpacing();
+ pntr_dsc = -1;
+ }
+}
+
+int TQTextFormat::minLeftBearing() const
+{
+ if (!pntr || !pntr->isActive())
+ return leftBearing;
+ applyFont(fn);
+ return pntr_fm->minLeftBearing();
+}
+
+int TQTextFormat::minRightBearing() const
+{
+ if (!pntr || !pntr->isActive())
+ return rightBearing;
+ applyFont(fn);
+ return pntr_fm->minRightBearing();
+}
+
+int TQTextFormat::height() const
+{
+ if (!pntr || !pntr->isActive())
+ return hei;
+ applyFont(fn);
+ return pntr_hei;
+}
+
+int TQTextFormat::ascent() const
+{
+ if (!pntr || !pntr->isActive())
+ return asc;
+ applyFont(fn);
+ return pntr_asc;
+}
+
+int TQTextFormat::descent() const
+{
+ if (!pntr || !pntr->isActive())
+ return dsc;
+ applyFont(fn);
+ if (pntr_dsc < 0)
+ pntr_dsc = pntr_fm->descent();
+ return pntr_dsc;
+}
+
+int TQTextFormat::leading() const
+{
+ if (!pntr || !pntr->isActive())
+ return fm.leading();
+ applyFont(fn);
+ return pntr_ldg;
+}
+
+void TQTextFormat::generateKey()
+{
+ k = getKey(fn, col, isMisspelled(), vAlign());
+}
+
+TQString TQTextFormat::getKey(const QFont &fn, const QColor &col, bool misspelled, VerticalAlignment a)
+{
+ TQString k = fn.key();
+ k += QLatin1Char('/');
+ k += TQString::number((uint)col.rgb());
+ k += QLatin1Char('/');
+ k += TQString::number((int)misspelled);
+ k += QLatin1Char('/');
+ k += TQString::number((int)a);
+ return k;
+}
+
+TQString TQTextString::toString(const QVector<TQTextStringChar> &data)
+{
+ TQString s;
+ int l = data.size();
+ s.setUnicode(0, l);
+ const TQTextStringChar *c = data.data();
+ QChar *uc = (QChar *)s.unicode();
+ while (l--)
+ *(uc++) = (c++)->c;
+
+ return s;
+}
+
+void TQTextParagraph::setSelection(int id, int start, int end)
+{
+ QMap<int, TQTextParagraphSelection>::ConstIterator it = selections().constFind(id);
+ if (it != mSelections->constEnd()) {
+ if (start == (*it).start && end == (*it).end)
+ return;
+ }
+
+ TQTextParagraphSelection sel;
+ sel.start = start;
+ sel.end = end;
+ (*mSelections)[id] = sel;
+ setChanged(true, true);
+}
+
+void TQTextParagraph::removeSelection(int id)
+{
+ if (!hasSelection(id))
+ return;
+ if (mSelections)
+ mSelections->remove(id);
+ setChanged(true, true);
+}
+
+int TQTextParagraph::selectionStart(int id) const
+{
+ if (!mSelections)
+ return -1;
+ QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->constFind(id);
+ if (it == mSelections->constEnd())
+ return -1;
+ return (*it).start;
+}
+
+int TQTextParagraph::selectionEnd(int id) const
+{
+ if (!mSelections)
+ return -1;
+ QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->constFind(id);
+ if (it == mSelections->constEnd())
+ return -1;
+ return (*it).end;
+}
+
+bool TQTextParagraph::hasSelection(int id) const
+{
+ return mSelections ? mSelections->contains(id) : false;
+}
+
+bool TQTextParagraph::fullSelected(int id) const
+{
+ if (!mSelections)
+ return false;
+ QMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->constFind(id);
+ if (it == mSelections->constEnd())
+ return false;
+ return (*it).start == 0 && (*it).end == str->length() - 1;
+}
+
+int TQTextParagraph::lineY(int l) const
+{
+ if (l > (int)lineStarts.count() - 1) {
+ qWarning("TQTextParagraph::lineY: line %d out of range!", l);
+ return 0;
+ }
+
+ if (!isValid())
+ ((TQTextParagraph*)this)->format();
+
+ QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while (l-- > 0)
+ ++it;
+ return (*it)->y;
+}
+
+int TQTextParagraph::lineBaseLine(int l) const
+{
+ if (l > (int)lineStarts.count() - 1) {
+ qWarning("TQTextParagraph::lineBaseLine: line %d out of range!", l);
+ return 10;
+ }
+
+ if (!isValid())
+ ((TQTextParagraph*)this)->format();
+
+ QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while (l-- > 0)
+ ++it;
+ return (*it)->baseLine;
+}
+
+int TQTextParagraph::lineHeight(int l) const
+{
+ if (l > (int)lineStarts.count() - 1) {
+ qWarning("TQTextParagraph::lineHeight: line %d out of range!", l);
+ return 15;
+ }
+
+ if (!isValid())
+ ((TQTextParagraph*)this)->format();
+
+ QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while (l-- > 0)
+ ++it;
+ return (*it)->h;
+}
+
+void TQTextParagraph::lineInfo(int l, int &y, int &h, int &bl) const
+{
+ if (l > (int)lineStarts.count() - 1) {
+ qWarning("TQTextParagraph::lineInfo: line %d out of range!", l);
+ qDebug("%d %d", (int)lineStarts.count() - 1, l);
+ y = 0;
+ h = 15;
+ bl = 10;
+ return;
+ }
+
+ if (!isValid())
+ ((TQTextParagraph*)this)->format();
+
+ QMap<int, QTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while (l-- > 0)
+ ++it;
+ y = (*it)->y;
+ h = (*it)->h;
+ bl = (*it)->baseLine;
+}
+
+
+void TQTextParagraph::setAlignment(int a)
+{
+ if (a == (int)align)
+ return;
+ align = a;
+ invalidate(0);
+}
+
+TQTextFormatter *TQTextParagraph::formatter() const
+{
+ if (hasdoc)
+ return document()->formatter();
+ if (pseudoDocument()->pFormatter)
+ return pseudoDocument()->pFormatter;
+ return (((TQTextParagraph*)this)->pseudoDocument()->pFormatter = new TQTextFormatterBreakWords);
+}
+
+void TQTextParagraph::setTabArray(int *a)
+{
+ delete [] tArray;
+ tArray = a;
+}
+
+void TQTextParagraph::setTabStops(int tw)
+{
+ if (hasdoc)
+ document()->setTabStops(tw);
+ else
+ tabStopWidth = tw;
+}
+
+QMap<int, TQTextParagraphSelection> &TQTextParagraph::selections() const
+{
+ if (!mSelections)
+ ((TQTextParagraph *)this)->mSelections = new QMap<int, TQTextParagraphSelection>;
+ return *mSelections;
+}
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+QList<TQTextCustomItem *> &TQTextParagraph::floatingItems() const
+{
+ if (!mFloatingItems)
+ ((TQTextParagraph *)this)->mFloatingItems = new QList<TQTextCustomItem *>;
+ return *mFloatingItems;
+}
+#endif
+
+TQTextStringChar::~TQTextStringChar()
+{
+ if (format())
+ format()->removeRef();
+ if (type) // not Regular
+ delete p.custom;
+}
+
+TQTextParagraphPseudoDocument::TQTextParagraphPseudoDocument():pFormatter(0),commandHistory(0), minw(0),wused(0),collection(){}
+TQTextParagraphPseudoDocument::~TQTextParagraphPseudoDocument(){ delete pFormatter; delete commandHistory; }
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_RICHTEXT
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of the internal TQt classes dealing with rich text
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqrichtext_p.h"
+
+#ifndef TQT_NO_RICHTEXT
+
+TQTextCommand::~TQTextCommand() {}
+TQTextCommand::Commands TQTextCommand::type() const { return Invalid; }
+
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+TQTextCustomItem::~TQTextCustomItem() {}
+void TQTextCustomItem::adjustToPainter( TQPainter* p){ if ( p ) width = 0; }
+TQTextCustomItem::Placement TQTextCustomItem::placement() const { return PlaceInline; }
+
+bool TQTextCustomItem::ownLine() const { return FALSE; }
+void TQTextCustomItem::resize( int nwidth ){ width = nwidth; }
+void TQTextCustomItem::tqinvalidate() {}
+
+bool TQTextCustomItem::isNested() const { return FALSE; }
+int TQTextCustomItem::minimumWidth() const { return 0; }
+
+TQString TQTextCustomItem::richText() const { return TQString::null; }
+
+bool TQTextCustomItem::enter( TQTextCursor *, TQTextDocument*&, TQTextParagraph *&, int &, int &, int &, bool )
+{
+ return TRUE;
+}
+bool TQTextCustomItem::enterAt( TQTextCursor *, TQTextDocument *&, TQTextParagraph *&, int &, int &, int &, const TQPoint & )
+{
+ return TRUE;
+}
+bool TQTextCustomItem::next( TQTextCursor *, TQTextDocument *&, TQTextParagraph *&, int &, int &, int & )
+{
+ return TRUE;
+}
+bool TQTextCustomItem::prev( TQTextCursor *, TQTextDocument *&, TQTextParagraph *&, int &, int &, int & )
+{
+ return TRUE;
+}
+bool TQTextCustomItem::down( TQTextCursor *, TQTextDocument *&, TQTextParagraph *&, int &, int &, int & )
+{
+ return TRUE;
+}
+bool TQTextCustomItem::up( TQTextCursor *, TQTextDocument *&, TQTextParagraph *&, int &, int &, int & )
+{
+ return TRUE;
+}
+#endif // TQT_NO_TEXTCUSTOMITEM
+
+void TQTextFlow::setPageSize( int ps ) { pagesize = ps; }
+#ifndef TQT_NO_TEXTCUSTOMITEM
+bool TQTextFlow::isEmpty() { return leftItems.isEmpty() && rightItems.isEmpty(); }
+#else
+bool TQTextFlow::isEmpty() { return TRUE; }
+#endif
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+void TQTextTableCell::tqinvalidate() { cached_width = -1; cached_sizehint = -1; }
+
+void TQTextTable::tqinvalidate() { cachewidth = -1; }
+#endif
+
+TQTextParagraphData::~TQTextParagraphData() {}
+void TQTextParagraphData::join( TQTextParagraphData * ) {}
+
+TQTextFormatter::~TQTextFormatter() {}
+void TQTextFormatter::setWrapEnabled( bool b ) { wrapEnabled = b; }
+void TQTextFormatter::setWrapAtColumn( int c ) { wrapColumn = c; }
+
+
+
+int TQTextCursor::x() const
+{
+ if ( idx >= para->length() )
+ return 0;
+ TQTextStringChar *c = para->at( idx );
+ int curx = c->x;
+ if ( !c->rightToLeft &&
+ c->c.isSpace() &&
+ idx > 0 &&
+ para->at( idx - 1 )->c != '\t' &&
+ !c->lineStart &&
+ ( para->tqalignment() & TQt::AlignJustify ) == TQt::AlignJustify )
+ curx = para->at( idx - 1 )->x + para->string()->width( idx - 1 );
+ if ( c->rightToLeft )
+ curx += para->string()->width( idx );
+ return curx;
+}
+
+int TQTextCursor::y() const
+{
+ int dummy, line;
+ para->lineStartOfChar( idx, &dummy, &line );
+ return para->lineY( line );
+}
+
+int TQTextCursor::globalX() const { return totalOffsetX() + para->rect().x() + x(); }
+int TQTextCursor::globalY() const { return totalOffsetY() + para->rect().y() + y(); }
+
+TQTextDocument *TQTextCursor::document() const
+{
+ return para ? para->document() : 0;
+}
+
+void TQTextCursor::gotoPosition( TQTextParagraph* p, int index )
+{
+ if ( para && p != para ) {
+ while ( !indices.isEmpty() && para->document() != p->document() )
+ pop();
+ TQ_ASSERT( indices.isEmpty() || para->document() == p->document() );
+ }
+ para = p;
+ if ( index < 0 || index >= para->length() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQTextCursor::gotoParagraph Index: %d out of range", index );
+#endif
+ if ( index < 0 || para->length() == 0 )
+ index = 0;
+ else
+ index = para->length() - 1;
+ }
+
+ tmpX = -1;
+ idx = index;
+ fixCursorPosition();
+}
+
+bool TQTextDocument::hasSelection( int id, bool visible ) const
+{
+ return ( selections.tqfind( id ) != selections.end() &&
+ ( !visible ||
+ ( (TQTextDocument*)this )->selectionStartCursor( id ) !=
+ ( (TQTextDocument*)this )->selectionEndCursor( id ) ) );
+}
+
+void TQTextDocument::setSelectionStart( int id, const TQTextCursor &cursor )
+{
+ TQTextDocumentSelection sel;
+ sel.startCursor = cursor;
+ sel.endCursor = cursor;
+ sel.swapped = FALSE;
+ selections[ id ] = sel;
+}
+
+TQTextParagraph *TQTextDocument::paragAt( int i ) const
+{
+ TQTextParagraph* p = curParag;
+ if ( !p || p->paragId() > i )
+ p = fParag;
+ while ( p && p->paragId() != i )
+ p = p->next();
+ ((TQTextDocument*)this)->curParag = p;
+ return p;
+}
+
+
+TQTextFormat::~TQTextFormat()
+{
+}
+
+TQTextFormat::TQTextFormat()
+ : fm( TQFontMetrics( fn ) ), linkColor( TRUE ), logicalFontSize( 3 ), stdSize( tqApp->font().pointSize() )
+{
+ ref = 0;
+
+ usePixelSizes = FALSE;
+ if ( stdSize == -1 ) {
+ stdSize = tqApp->font().pixelSize();
+ usePixelSizes = TRUE;
+ }
+
+ missp = FALSE;
+ ha = AlignNormal;
+ collection = 0;
+}
+
+TQTextFormat::TQTextFormat( const TQStyleSheetItem *style )
+ : fm( TQFontMetrics( fn ) ), linkColor( TRUE ), logicalFontSize( 3 ), stdSize( tqApp->font().pointSize() )
+{
+ ref = 0;
+
+ usePixelSizes = FALSE;
+ if ( stdSize == -1 ) {
+ stdSize = tqApp->font().pixelSize();
+ usePixelSizes = TRUE;
+ }
+
+ missp = FALSE;
+ ha = AlignNormal;
+ collection = 0;
+ fn = TQFont( style->fontFamily(),
+ style->fontSize(),
+ style->fontWeight(),
+ style->fontItalic() );
+ fn.setUnderline( style->fontUnderline() );
+ fn.setStrikeOut( style->fontStrikeOut() );
+ col = style->color();
+ fm = TQFontMetrics( fn );
+ leftBearing = fm.minLeftBearing();
+ rightBearing = fm.minRightBearing();
+ hei = fm.lineSpacing();
+ asc = fm.ascent() + (fm.leading()+1)/2;
+ dsc = fm.descent();
+ missp = FALSE;
+ ha = AlignNormal;
+ memset( widths, 0, 256 );
+ generateKey();
+ addRef();
+}
+
+TQTextFormat::TQTextFormat( const TQFont &f, const TQColor &c, TQTextFormatCollection *tqparent )
+ : fn( f ), col( c ), fm( TQFontMetrics( f ) ), linkColor( TRUE ),
+ logicalFontSize( 3 ), stdSize( f.pointSize() )
+{
+ ref = 0;
+ usePixelSizes = FALSE;
+ if ( stdSize == -1 ) {
+ stdSize = f.pixelSize();
+ usePixelSizes = TRUE;
+ }
+ collection = tqparent;
+ leftBearing = fm.minLeftBearing();
+ rightBearing = fm.minRightBearing();
+ hei = fm.lineSpacing();
+ asc = fm.ascent() + (fm.leading()+1)/2;
+ dsc = fm.descent();
+ missp = FALSE;
+ ha = AlignNormal;
+ memset( widths, 0, 256 );
+ generateKey();
+ addRef();
+}
+
+TQTextFormat::TQTextFormat( const TQTextFormat &f )
+ : fm( f.fm )
+{
+ ref = 0;
+ collection = 0;
+ fn = f.fn;
+ col = f.col;
+ leftBearing = f.leftBearing;
+ rightBearing = f.rightBearing;
+ memset( widths, 0, 256 );
+ hei = f.hei;
+ asc = f.asc;
+ dsc = f.dsc;
+ stdSize = f.stdSize;
+ usePixelSizes = f.usePixelSizes;
+ logicalFontSize = f.logicalFontSize;
+ missp = f.missp;
+ ha = f.ha;
+ k = f.k;
+ linkColor = f.linkColor;
+ addRef();
+}
+
+TQTextFormat& TQTextFormat::operator=( const TQTextFormat &f )
+{
+ ref = 0;
+ collection = f.collection;
+ fn = f.fn;
+ col = f.col;
+ fm = f.fm;
+ leftBearing = f.leftBearing;
+ rightBearing = f.rightBearing;
+ memset( widths, 0, 256 );
+ hei = f.hei;
+ asc = f.asc;
+ dsc = f.dsc;
+ stdSize = f.stdSize;
+ usePixelSizes = f.usePixelSizes;
+ logicalFontSize = f.logicalFontSize;
+ missp = f.missp;
+ ha = f.ha;
+ k = f.k;
+ linkColor = f.linkColor;
+ addRef();
+ return *this;
+}
+
+void TQTextFormat::update()
+{
+ fm = TQFontMetrics( fn );
+ leftBearing = fm.minLeftBearing();
+ rightBearing = fm.minRightBearing();
+ hei = fm.lineSpacing();
+ asc = fm.ascent() + (fm.leading()+1)/2;
+ dsc = fm.descent();
+ memset( widths, 0, 256 );
+ generateKey();
+}
+
+
+TQPainter* TQTextFormat::pntr = 0;
+TQFontMetrics* TQTextFormat::pntr_fm = 0;
+int TQTextFormat::pntr_ldg=-1;
+int TQTextFormat::pntr_asc=-1;
+int TQTextFormat::pntr_hei=-1;
+int TQTextFormat::pntr_dsc=-1;
+
+void TQTextFormat::setPainter( TQPainter *p )
+{
+ pntr = p;
+}
+
+TQPainter* TQTextFormat::painter()
+{
+ return pntr;
+}
+
+void TQTextFormat::applyFont( const TQFont &f )
+{
+ TQFontMetrics fm( pntr->fontMetrics() );
+ if ( !pntr_fm
+// || pntr_fm->painter != pntr
+// || pntr_fm->d != fm.d
+ || !pntr->font().isCopyOf( f ) ) {
+ pntr->setFont( f );
+ delete pntr_fm;
+ pntr_fm = new TQFontMetrics( pntr->fontMetrics() );
+ pntr_ldg = pntr_fm->leading();
+ pntr_asc = pntr_fm->ascent()+(pntr_ldg+1)/2;
+ pntr_hei = pntr_fm->lineSpacing();
+ pntr_dsc = -1;
+ }
+}
+
+int TQTextFormat::minLeftBearing() const
+{
+ if ( !pntr || !pntr->isActive() )
+ return leftBearing;
+ applyFont( fn );
+ return pntr_fm->minLeftBearing();
+}
+
+int TQTextFormat::minRightBearing() const
+{
+ if ( !pntr || !pntr->isActive() )
+ return rightBearing;
+ applyFont( fn );
+ return pntr_fm->minRightBearing();
+}
+
+int TQTextFormat::height() const
+{
+ if ( !pntr || !pntr->isActive() )
+ return hei;
+ applyFont( fn );
+ return pntr_hei;
+}
+
+int TQTextFormat::ascent() const
+{
+ if ( !pntr || !pntr->isActive() )
+ return asc;
+ applyFont( fn );
+ return pntr_asc;
+}
+
+int TQTextFormat::descent() const
+{
+ if ( !pntr || !pntr->isActive() )
+ return dsc;
+ applyFont( fn );
+ if ( pntr_dsc < 0 )
+ pntr_dsc = pntr_fm->descent();
+ return pntr_dsc;
+}
+
+int TQTextFormat::leading() const
+{
+ if ( !pntr || !pntr->isActive() )
+ return fm.leading();
+ applyFont( fn );
+ return pntr_ldg;
+}
+
+void TQTextFormat::generateKey()
+{
+ k = getKey( fn, col, isMisspelled(), vAlign() );
+}
+
+TQString TQTextFormat::getKey( const TQFont &fn, const TQColor &col, bool misspelled, VerticalAlignment a )
+{
+ TQString k = fn.key();
+ k += '/';
+ k += TQString::number( (uint)col.rgb() );
+ k += '/';
+ k += TQString::number( (int)misspelled );
+ k += '/';
+ k += TQString::number( (int)a );
+ return k;
+}
+
+TQString TQTextString::toString( const TQMemArray<TQTextStringChar> &data )
+{
+ TQString s;
+ int l = data.size();
+ s.setUnicode( 0, l );
+ TQTextStringChar *c = data.data();
+ TQChar *uc = (TQChar *)s.tqunicode();
+ while ( l-- )
+ *(uc++) = (c++)->c;
+
+ return s;
+}
+
+void TQTextParagraph::setSelection( int id, int start, int end )
+{
+ TQMap<int, TQTextParagraphSelection>::ConstIterator it = selections().tqfind( id );
+ if ( it != mSelections->end() ) {
+ if ( start == ( *it ).start && end == ( *it ).end )
+ return;
+ }
+
+ TQTextParagraphSelection sel;
+ sel.start = start;
+ sel.end = end;
+ (*mSelections)[ id ] = sel;
+ setChanged( TRUE, TRUE );
+}
+
+void TQTextParagraph::removeSelection( int id )
+{
+ if ( !hasSelection( id ) )
+ return;
+ if ( mSelections )
+ mSelections->remove( id );
+ setChanged( TRUE, TRUE );
+}
+
+int TQTextParagraph::selectionStart( int id ) const
+{
+ if ( !mSelections )
+ return -1;
+ TQMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->tqfind( id );
+ if ( it == mSelections->end() )
+ return -1;
+ return ( *it ).start;
+}
+
+int TQTextParagraph::selectionEnd( int id ) const
+{
+ if ( !mSelections )
+ return -1;
+ TQMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->tqfind( id );
+ if ( it == mSelections->end() )
+ return -1;
+ return ( *it ).end;
+}
+
+bool TQTextParagraph::hasSelection( int id ) const
+{
+ return mSelections ? mSelections->tqcontains( id ) : FALSE;
+}
+
+bool TQTextParagraph::fullSelected( int id ) const
+{
+ if ( !mSelections )
+ return FALSE;
+ TQMap<int, TQTextParagraphSelection>::ConstIterator it = mSelections->tqfind( id );
+ if ( it == mSelections->end() )
+ return FALSE;
+ return ( *it ).start == 0 && ( *it ).end == str->length() - 1;
+}
+
+int TQTextParagraph::lineY( int l ) const
+{
+ if ( l > (int)lineStarts.count() - 1 ) {
+ qWarning( "TQTextParagraph::lineY: line %d out of range!", l );
+ return 0;
+ }
+
+ if ( !isValid() )
+ ( (TQTextParagraph*)this )->format();
+
+ TQMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while ( l-- > 0 )
+ ++it;
+ return ( *it )->y;
+}
+
+int TQTextParagraph::lineBaseLine( int l ) const
+{
+ if ( l > (int)lineStarts.count() - 1 ) {
+ qWarning( "TQTextParagraph::lineBaseLine: line %d out of range!", l );
+ return 10;
+ }
+
+ if ( !isValid() )
+ ( (TQTextParagraph*)this )->format();
+
+ TQMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while ( l-- > 0 )
+ ++it;
+ return ( *it )->baseLine;
+}
+
+int TQTextParagraph::lineHeight( int l ) const
+{
+ if ( l > (int)lineStarts.count() - 1 ) {
+ qWarning( "TQTextParagraph::lineHeight: line %d out of range!", l );
+ return 15;
+ }
+
+ if ( !isValid() )
+ ( (TQTextParagraph*)this )->format();
+
+ TQMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while ( l-- > 0 )
+ ++it;
+ return ( *it )->h;
+}
+
+void TQTextParagraph::lineInfo( int l, int &y, int &h, int &bl ) const
+{
+ if ( l > (int)lineStarts.count() - 1 ) {
+ qWarning( "TQTextParagraph::lineInfo: line %d out of range!", l );
+ qDebug( "%d %d", (int)lineStarts.count() - 1, l );
+ y = 0;
+ h = 15;
+ bl = 10;
+ return;
+ }
+
+ if ( !isValid() )
+ ( (TQTextParagraph*)this )->format();
+
+ TQMap<int, TQTextLineStart*>::ConstIterator it = lineStarts.begin();
+ while ( l-- > 0 )
+ ++it;
+ y = ( *it )->y;
+ h = ( *it )->h;
+ bl = ( *it )->baseLine;
+}
+
+
+void TQTextParagraph::tqsetAlignment( int a )
+{
+ if ( a == (int)align )
+ return;
+ align = a;
+ tqinvalidate( 0 );
+}
+
+TQTextFormatter *TQTextParagraph::formatter() const
+{
+ if ( hasdoc )
+ return document()->formatter();
+ if ( pseudoDocument()->pFormatter )
+ return pseudoDocument()->pFormatter;
+ return ( ( (TQTextParagraph*)this )->pseudoDocument()->pFormatter = new TQTextFormatterBreakWords );
+}
+
+void TQTextParagraph::setTabArray( int *a )
+{
+ delete [] tArray;
+ tArray = a;
+}
+
+void TQTextParagraph::setTabStops( int tw )
+{
+ if ( hasdoc )
+ document()->setTabStops( tw );
+ else
+ tabStopWidth = tw;
+}
+
+TQMap<int, TQTextParagraphSelection> &TQTextParagraph::selections() const
+{
+ if ( !mSelections )
+ ((TQTextParagraph *)this)->mSelections = new TQMap<int, TQTextParagraphSelection>;
+ return *mSelections;
+}
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+TQPtrList<TQTextCustomItem> &TQTextParagraph::floatingItems() const
+{
+ if ( !mFloatingItems )
+ ((TQTextParagraph *)this)->mFloatingItems = new TQPtrList<TQTextCustomItem>;
+ return *mFloatingItems;
+}
+#endif
+
+TQTextStringChar::~TQTextStringChar()
+{
+ if ( format() )
+ format()->removeRef();
+ if ( type ) // not Regular
+ delete d.custom;
+}
+
+TQTextParagraphPseudoDocument::TQTextParagraphPseudoDocument():pFormatter(0),commandHistory(0), minw(0),wused(0),collection(){}
+TQTextParagraphPseudoDocument::~TQTextParagraphPseudoDocument(){ delete pFormatter; delete commandHistory; }
+
+
+#endif //TQT_NO_RICHTEXT
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqrichtext_p.h b/tqtinterface/qt4/src/kernel/tqrichtext_p.h
new file mode 100644
index 0000000..b9cbd98
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqrichtext_p.h
@@ -0,0 +1,4300 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+// #if 0
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TQRICHTEXT_P_H
+#define TQRICHTEXT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of a number of Qt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtGui/qapplication.h"
+#include "QtGui/qcolor.h"
+#include "QtCore/qhash.h"
+#include "QtGui/qfont.h"
+#include "QtGui/qfontmetrics.h"
+#include "QtGui/qlayout.h"
+#include "QtCore/qmap.h"
+#include "QtCore/qvector.h"
+#include "QtCore/qstack.h"
+#include "QtCore/qlist.h"
+#include "QtCore/qobject.h"
+#include "QtGui/qpainter.h"
+#include "QtGui/qpixmap.h"
+#include "QtCore/qrect.h"
+#include "QtCore/qsize.h"
+#include "QtCore/qstring.h"
+#include "QtCore/qstringlist.h"
+#include "tqstylesheet.h"
+#include "tqmime.h"
+#include "tqpalette.h"
+#include "tqpixmap.h"
+#include "tqbrush.h"
+#include "tqlayout.h"
+
+#define TQLatin1String TQString
+#define TQLatin1Char TQChar
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_RICHTEXT
+
+class TQTextDocument;
+class TQTextString;
+class TQTextPreProcessor;
+class TQTextFormat;
+class TQTextCursor;
+class TQTextParagraph;
+class TQTextFormatter;
+class TQTextIndent;
+class TQTextFormatCollection;
+class TQStyleSheetItem;
+#ifndef QT_NO_TEXTCUSTOMITEM
+class TQTextCustomItem;
+#endif
+class TQTextFlow;
+struct QBidiContext;
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class Q_COMPAT_EXPORT TQTextStringChar
+{
+ friend class TQTextString;
+
+public:
+ // this is never called, initialize variables in TQTextString::insert()!!!
+ TQTextStringChar() : nobreak(false), lineStart(0), type(Regular) {p.format=0;}
+ ~TQTextStringChar();
+
+ struct CustomData
+ {
+ TQTextFormat *format;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem *custom;
+#endif
+ TQString anchorName;
+ TQString anchorHref;
+ };
+ enum Type { Regular=0, Custom=1, Anchor=2, CustomAnchor=3 };
+
+ TQChar c;
+ // this is the same struct as in qtextengine_p.h. Don't change!
+ uchar softBreak :1; // Potential linebreak point
+ uchar whiteSpace :1; // A unicode whitespace character, except NBSP, ZWNBSP
+ uchar charStop :1; // Valid cursor position (for left/right arrow)
+ uchar nobreak :1;
+
+ uchar lineStart : 1;
+ uchar /*Type*/ type : 2;
+ uchar bidiLevel :7;
+ uchar rightToLeft : 1;
+
+ int x;
+ union {
+ TQTextFormat* format;
+ CustomData* custom;
+ } p;
+
+
+ int height() const;
+ int ascent() const;
+ int descent() const;
+ bool isCustom() const { return (type & Custom) != 0; }
+ TQTextFormat *format() const;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem *customItem() const;
+#endif
+ void setFormat(TQTextFormat *f);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ void setCustomItem(TQTextCustomItem *i);
+#endif
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ void loseCustomItem();
+#endif
+
+
+ bool isAnchor() const { return (type & Anchor) != 0; }
+ bool isLink() const { return isAnchor() && p.custom->anchorHref.count(); }
+ TQString anchorName() const;
+ TQString anchorHref() const;
+ void setAnchor(const TQString& name, const TQString& href);
+
+ TQTextStringChar(const TQTextStringChar &) {
+ Q_ASSERT(false);
+ }
+private:
+ TQTextStringChar &operator=(const TQTextStringChar &) {
+ //abort();
+ return *this;
+ }
+ friend class TQTextParagraph;
+};
+
+Q_DECLARE_TYPEINFO(TQTextStringChar, Q_PRIMITIVE_TYPE);
+
+class Q_COMPAT_EXPORT TQTextString
+{
+public:
+
+ TQTextString();
+ TQTextString(const TQTextString &s);
+ virtual ~TQTextString();
+
+ static TQString toString(const QVector<TQTextStringChar> &data);
+ TQString toString() const;
+
+ inline TQTextStringChar &at(int i) const {
+ return const_cast<TQTextString *>(this)->data[i];
+ }
+ inline int length() const { return data.size(); }
+
+ int width(int idx) const;
+
+ void insert(int index, const QString &s, TQTextFormat *f);
+ void insert(int index, const QChar *unicode, int len, TQTextFormat *f);
+ void insert(int index, TQTextStringChar *c, bool doAddRefFormat = false);
+ void truncate(int index);
+ void remove(int index, int len);
+ void clear();
+
+ void setFormat(int index, TQTextFormat *f, bool useCollection);
+
+ void setBidi(bool b) { bidi = b; }
+ bool isBidi() const;
+ bool isRightToLeft() const;
+ TQChar::Direction direction() const;
+ void setDirection(TQChar::Direction dr) { dir = dr; bidiDirty = true; }
+
+ QVector<TQTextStringChar> rawData() const { return data; }
+
+ void operator=(const TQString &s) { clear(); insert(0, s, 0); }
+ void operator+=(const TQString &s) { insert(length(), s, 0); }
+ void prepend(const TQString &s) { insert(0, s, 0); }
+ int appendParagraphs( TQTextParagraph *start, TQTextParagraph *end );
+
+ // return next and previous valid cursor positions.
+ bool validCursorPosition(int idx);
+ int nextCursorPosition(int idx);
+ int previousCursorPosition(int idx);
+
+private:
+ void checkBidi() const;
+
+private:
+ QVector<TQTextStringChar> data;
+ TQString stringCache;
+ uint bidiDirty : 1;
+ uint bidi : 1; // true when the paragraph has right to left characters
+ uint rightToLeft : 1;
+ uint dir : 5;
+};
+
+inline bool TQTextString::isBidi() const
+{
+ if (bidiDirty)
+ checkBidi();
+ return bidi;
+}
+
+inline bool TQTextString::isRightToLeft() const
+{
+ if (bidiDirty)
+ checkBidi();
+ return rightToLeft;
+}
+
+inline TQString TQTextString::toString() const
+{
+ if (bidiDirty)
+ checkBidi();
+ return stringCache;
+}
+
+inline TQChar::Direction TQTextString::direction() const
+{
+ return rightToLeft ? TQChar::DirR : TQChar::DirL;
+}
+
+inline int TQTextString::nextCursorPosition(int next)
+{
+ if (bidiDirty)
+ checkBidi();
+
+ const TQTextStringChar *c = data.data();
+ int len = length();
+
+ if (next < len - 1) {
+ next++;
+ while (next < len - 1 && !c[next].charStop)
+ next++;
+ }
+ return next;
+}
+
+inline int TQTextString::previousCursorPosition(int prev)
+{
+ if (bidiDirty)
+ checkBidi();
+
+ const TQTextStringChar *c = data.data();
+
+ if (prev) {
+ prev--;
+ while (prev && !c[prev].charStop)
+ prev--;
+ }
+ return prev;
+}
+
+inline bool TQTextString::validCursorPosition(int idx)
+{
+ if (bidiDirty)
+ checkBidi();
+
+ return (at(idx).charStop);
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class Q_COMPAT_EXPORT TQTextCursor
+{
+public:
+ TQTextCursor(TQTextDocument * = 0);
+ TQTextCursor(const TQTextCursor &c);
+ TQTextCursor &operator=(const TQTextCursor &c);
+ virtual ~TQTextCursor();
+
+ bool operator==(const TQTextCursor &c) const;
+ bool operator!=(const TQTextCursor &c) const { return !(*this == c); }
+
+ inline TQTextParagraph *paragraph() const { return para; }
+
+ TQTextDocument *document() const;
+ int index() const;
+
+ void gotoPosition(TQTextParagraph* p, int index = 0);
+ void setIndex(int index) { gotoPosition(paragraph(), index); }
+ void setParagraph(TQTextParagraph*p) { gotoPosition(p, 0); }
+
+ void gotoLeft();
+ void gotoRight();
+ void gotoNextLetter();
+ void gotoPreviousLetter();
+ void gotoUp();
+ void gotoDown();
+ void gotoLineEnd();
+ void gotoLineStart();
+ void gotoHome();
+ void gotoEnd();
+ void gotoPageUp(int visibleHeight);
+ void gotoPageDown(int visibleHeight);
+ void gotoNextWord(bool onlySpace = false);
+ void gotoPreviousWord(bool onlySpace = false);
+ void gotoWordLeft();
+ void gotoWordRight();
+
+ void insert(const QString &s, bool checkNewLine, QVector<TQTextStringChar> *formatting = 0);
+ void splitAndInsertEmptyParagraph(bool ind = true, bool updateIds = true);
+ bool remove();
+ bool removePreviousChar();
+ void indent();
+
+ bool atParagStart();
+ bool atParagEnd();
+
+ int x() const; // x in current paragraph
+ int y() const; // y in current paragraph
+
+ int globalX() const;
+ int globalY() const;
+
+ TQTextParagraph *topParagraph() const { return paras.isEmpty() ? para : paras.first(); }
+ int offsetX() const { return ox; } // inner document offset
+ int offsetY() const { return oy; } // inner document offset
+ int totalOffsetX() const; // total document offset
+ int totalOffsetY() const; // total document offset
+
+ bool place(const QPoint &pos, TQTextParagraph *s) { return place(pos, s, false); }
+ bool place(const QPoint &pos, TQTextParagraph *s, bool link);
+ void restoreState();
+
+
+ int nestedDepth() const { return (int)indices.count(); } //### size_t/int cast
+ void oneUp() { if (!indices.isEmpty()) pop(); }
+ void setValid(bool b) { valid = b; }
+ bool isValid() const { return valid; }
+
+ void fixCursorPosition();
+private:
+ enum Operation { EnterBegin, EnterEnd, Next, Prev, Up, Down };
+
+ void push();
+ void pop();
+ bool processNesting(Operation op);
+ void invalidateNested();
+ void gotoIntoNested(const QPoint &globalPos);
+
+ TQTextParagraph *para;
+ int idx, tmpX;
+ int ox, oy;
+ QStack<int> indices;
+ QStack<TQTextParagraph*> paras;
+ QStack<int> xOffsets;
+ QStack<int> yOffsets;
+ uint valid : 1;
+
+};
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class Q_COMPAT_EXPORT TQTextCommand
+{
+public:
+ enum Commands { Invalid, Insert, Delete, Format, Style };
+
+ TQTextCommand(TQTextDocument *dc) : doc(dc), cursor(dc) {}
+ virtual ~TQTextCommand();
+
+ virtual Commands type() const;
+
+ virtual TQTextCursor *execute(TQTextCursor *c) = 0;
+ virtual TQTextCursor *unexecute(TQTextCursor *c) = 0;
+
+protected:
+ TQTextDocument *doc;
+ TQTextCursor cursor;
+
+};
+
+class Q_COMPAT_EXPORT TQTextCommandHistory
+{
+public:
+ TQTextCommandHistory(int s) : current(-1), steps(s) { }
+ virtual ~TQTextCommandHistory(); // ### why is it virtual?
+
+ void clear();
+
+ void addCommand(TQTextCommand *cmd);
+ TQTextCursor *undo(TQTextCursor *c);
+ TQTextCursor *redo(TQTextCursor *c);
+
+ bool isUndoAvailable();
+ bool isRedoAvailable();
+
+ void setUndoDepth(int depth) { steps = depth; }
+ int undoDepth() const { return steps; }
+
+ int historySize() const { return history.count(); }
+ int currentPosition() const { return current; }
+
+private:
+ QList<TQTextCommand *> history;
+ int current, steps;
+};
+
+inline TQTextCommandHistory::~TQTextCommandHistory()
+{
+ clear();
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+class Q_COMPAT_EXPORT TQTextCustomItem
+{
+public:
+ TQTextCustomItem(TQTextDocument *p)
+ : xpos(0), ypos(-1), width(-1), height(0), parent(p)
+ {}
+ virtual ~TQTextCustomItem();
+ virtual void draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
+ const QPalette &pal, bool selected) = 0;
+
+ virtual void adjustToPainter(TQPainter*);
+
+ enum Placement { PlaceInline = 0, PlaceLeft, PlaceRight };
+ virtual Placement placement() const;
+ bool placeInline() { return placement() == PlaceInline; }
+
+ virtual bool ownLine() const;
+ virtual void resize(int nwidth);
+ virtual void invalidate();
+ virtual int ascent() const { return height; }
+
+ virtual bool isNested() const;
+ virtual int minimumWidth() const;
+
+ virtual TQString richText() const;
+
+ int xpos; // used for floating items
+ int ypos; // used for floating items
+ int width;
+ int height;
+
+ TQRect geometry() const { return TQRect(xpos, ypos, width, height); }
+
+ virtual bool enter(TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd = false);
+ virtual bool enterAt(TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint &);
+ virtual bool next(TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy);
+ virtual bool prev(TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy);
+ virtual bool down(TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy);
+ virtual bool up(TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy);
+
+ void setParagraph(TQTextParagraph *p) { parag = p; }
+ TQTextParagraph *paragraph() const { return parag; }
+
+ TQTextDocument *parent;
+ TQTextParagraph *parag;
+
+ virtual void pageBreak(int y, TQTextFlow* flow);
+};
+#endif
+
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+class Q_COMPAT_EXPORT TQTextImage : public TQTextCustomItem
+{
+public:
+ TQTextImage(TQTextDocument *p, const QMap<TQString, TQString> &attr, const TQString& context,
+ TQMimeSourceFactory &factory);
+ virtual ~TQTextImage();
+
+ Placement placement() const { return place; }
+ void adjustToPainter(TQPainter*);
+ int minimumWidth() const { return width; }
+
+ TQString richText() const;
+
+ void draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
+ const QPalette &pal, bool selected);
+
+private:
+ QRegion* reg;
+ TQPixmap pm;
+ Placement place;
+ int tmpwidth, tmpheight;
+ QMap<TQString, TQString> attributes;
+ TQString imgId;
+
+};
+#endif
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+class Q_COMPAT_EXPORT TQTextHorizontalLine : public TQTextCustomItem
+{
+public:
+ TQTextHorizontalLine(TQTextDocument *p, const QMap<TQString, TQString> &attr, const TQString& context,
+ TQMimeSourceFactory &factory);
+ virtual ~TQTextHorizontalLine();
+
+ void adjustToPainter(TQPainter*);
+ void draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
+ const QPalette &pal, bool selected);
+ TQString richText() const;
+
+ bool ownLine() const { return true; }
+
+private:
+ int tmpheight;
+ QColor color;
+ bool shade;
+
+};
+#endif
+
+class Q_COMPAT_EXPORT TQTextFlow
+{
+ friend class TQTextDocument;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ friend class TQTextTableCell;
+#endif
+
+public:
+ TQTextFlow();
+ virtual ~TQTextFlow();
+
+ virtual void setWidth(int width);
+ int width() const;
+
+ virtual void setPageSize(int ps);
+ int pageSize() const { return pagesize; }
+
+ virtual int adjustLMargin(int yp, int h, int margin, int space);
+ virtual int adjustRMargin(int yp, int h, int margin, int space);
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ virtual void registerFloatingItem(TQTextCustomItem* item);
+ virtual void unregisterFloatingItem(TQTextCustomItem* item);
+#endif
+ virtual TQRect boundingRect() const;
+ virtual void drawFloatingItems(TQPainter* p, int cx, int cy, int cw, int ch,
+ const QPalette &pal, bool selected);
+
+ virtual int adjustFlow(int y, int w, int h); // adjusts y according to the defined pagesize. Returns the shift.
+
+ virtual bool isEmpty();
+
+ void clear();
+
+private:
+ int w;
+ int pagesize;
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ QList<TQTextCustomItem *> leftItems;
+ QList<TQTextCustomItem *> rightItems;
+#endif
+};
+
+inline int TQTextFlow::width() const { return w; }
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+class TQTextTable;
+
+class Q_COMPAT_EXPORT TQTextTableCell : public TQLayoutItem
+{
+ friend class TQTextTable;
+
+public:
+ TQTextTableCell(TQTextTable* table,
+ int row, int column,
+ const QMap<TQString, TQString> &attr,
+ const TQStyleSheetItem* style,
+ const TQTextFormat& fmt, const TQString& context,
+ TQMimeSourceFactory &factory, TQStyleSheet *sheet, const TQString& doc);
+ virtual ~TQTextTableCell();
+
+ TQSize tqsizeHint() const ;
+ TQSize tqminimumSize() const ;
+ TQSize tqmaximumSize() const ;
+ Qt::Orientations expandingDirections() const;
+ bool isEmpty() const;
+ void setGeometry(const TQRect&) ;
+ TQRect tqgeometry() const;
+
+ bool hasHeightForWidth() const;
+ int heightForWidth(int) const;
+
+ void adjustToPainter(TQPainter*);
+
+ int row() const { return row_; }
+ int column() const { return col_; }
+ int rowspan() const { return rowspan_; }
+ int colspan() const { return colspan_; }
+ int stretch() const { return stretch_; }
+
+ TQTextDocument* richText() const { return richtext; }
+ TQTextTable* table() const { return parent; }
+
+ void draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
+ const QPalette &cg, bool selected);
+
+ TQBrush *backGround() const { return background; }
+ virtual void invalidate();
+
+ int verticalAlignmentOffset() const;
+ int horizontalAlignmentOffset() const;
+
+ QLAYOUTITEM_REQUIRED_FUNCTIONS
+
+private:
+ TQRect geom;
+ TQTextTable* parent;
+ TQTextDocument* richtext;
+ int row_;
+ int col_;
+ int rowspan_;
+ int colspan_;
+ int stretch_;
+ int maxw;
+ int minw;
+ bool hasFixedWidth;
+ TQBrush *background;
+ int cached_width;
+ int cached_sizehint;
+ QMap<TQString, TQString> attributes;
+ int align;
+};
+#endif
+
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+class Q_COMPAT_EXPORT TQTextTable: public TQTextCustomItem
+{
+ friend class TQTextTableCell;
+
+public:
+ TQTextTable(TQTextDocument *p, const QMap<TQString, TQString> &attr);
+ virtual ~TQTextTable();
+
+ void adjustToPainter(TQPainter *p);
+ void pageBreak(int y, TQTextFlow* flow);
+ void draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
+ const QPalette &pal, bool selected);
+
+ bool noErase() const { return true; }
+ bool ownLine() const { return true; }
+ Placement placement() const { return place; }
+ bool isNested() const { return true; }
+ void resize(int nwidth);
+ virtual void invalidate();
+
+ virtual bool enter(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd = false);
+ virtual bool enterAt(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, const QPoint &pos);
+ virtual bool next(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy);
+ virtual bool prev(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy);
+ virtual bool down(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy);
+ virtual bool up(TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy);
+
+ TQString richText() const;
+
+ int minimumWidth() const;
+
+ QList<TQTextTableCell *> tableCells() const { return cells; }
+
+ TQPtrList<TQTextTableCell> tqtableCells() const {
+ TQPtrList<TQTextTableCell> tc;
+ tc.clear();
+ for (int i = 0; i < cells.size(); ++i) tc.append(cells.at(i));
+ return tc;
+ }
+
+ bool isStretching() const { return stretch; }
+
+private:
+ void format(int w);
+ void addCell(TQTextTableCell* cell);
+
+private:
+ TQGridLayout* layout;
+ QList<TQTextTableCell *> cells;
+ int cachewidth;
+ int fixwidth;
+ int cellpadding;
+ int cellspacing;
+ int border;
+ int outerborder;
+ int stretch;
+ int innerborder;
+ int us_cp, us_ib, us_b, us_ob, us_cs;
+ int us_fixwidth;
+ QMap<TQString, TQString> attributes;
+ QMap<TQTextCursor*, int> currCell;
+ Placement place;
+ void adjustCells(int y , int shift);
+ int pageBreakFor;
+};
+#endif
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+class TQTextTableCell;
+class TQTextParagraph;
+#endif
+
+struct Q_COMPAT_EXPORT TQTextDocumentSelection
+{
+ TQTextCursor startCursor, endCursor;
+ bool swapped;
+ Q_DUMMY_COMPARISON_OPERATOR(TQTextDocumentSelection)
+};
+
+class Q_COMPAT_EXPORT TQTextDocument : public TQT_BASE_OBJECT_NAME
+{
+ Q_OBJECT
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ friend class TQTextTableCell;
+#endif
+ friend class TQTextCursor;
+ friend class TQTextEdit;
+ friend class TQTextParagraph;
+
+public:
+
+ enum SelectionIds {
+ Standard = 0,
+ IMSelectionText = 31998,
+ IMCompositionText = 31999, // this must be higher!
+ Temp = 32000 // This selection must not be drawn, it's used e.g. by undo/redo to
+ // remove multiple lines with removeSelectedText()
+ };
+
+ TQTextDocument(TQTextDocument *p);
+ virtual ~TQTextDocument();
+
+ TQTextDocument *parent() const { return par; }
+ TQTextParagraph *parentParagraph() const { return parentPar; }
+
+ void setText(const TQString &text, const TQString &context);
+ QMap<TQString, TQString> attributes() const { return attribs; }
+ void setAttributes(const QMap<TQString, TQString> &attr) { attribs = attr; }
+
+ TQString text() const;
+ TQString text(int parag) const;
+ TQString originalText() const;
+
+ void setInvertSelectionText( int id, bool b );
+ bool invertSelectionText( int id ) const;
+
+ int x() const;
+ int y() const;
+ int width() const;
+ int widthUsed() const;
+ int visibleWidth() const;
+ int height() const;
+ void setWidth(int w);
+ int minimumWidth() const;
+ bool setMinimumWidth(int needed, int used = -1, TQTextParagraph *parag = 0);
+
+ void setY(int y);
+ int leftMargin() const;
+ void setLeftMargin(int lm);
+ int rightMargin() const;
+ void setRightMargin(int rm);
+
+ TQTextParagraph *firstParagraph() const;
+ TQTextParagraph *lastParagraph() const;
+ void setFirstParagraph(TQTextParagraph *p);
+ void setLastParagraph(TQTextParagraph *p);
+
+ void invalidate();
+ inline void tqinvalidate() { invalidate(); }
+
+ void setPreProcessor(TQTextPreProcessor *sh);
+ TQTextPreProcessor *preProcessor() const;
+
+ void setFormatter(TQTextFormatter *f);
+ TQTextFormatter *formatter() const;
+
+ void setIndent(TQTextIndent *i);
+ TQTextIndent *indent() const;
+
+ QColor selectionColor(int id) const;
+ QColor selectionTextColor(int id) const;
+ bool hasSelectionTextColor(int id) const;
+ void setSelectionColor(int id, const QColor &c);
+ void setSelectionTextColor(int id, const QColor &b);
+ bool hasSelection(int id, bool visible = false) const;
+ void setSelectionStart(int id, const TQTextCursor &cursor);
+ bool setSelectionEnd(int id, const TQTextCursor &cursor);
+ void selectAll(int id);
+ bool removeSelection(int id);
+ void selectionStart(int id, int &paragId, int &index);
+ TQTextCursor selectionStartCursor(int id);
+ TQTextCursor selectionEndCursor(int id);
+ void selectionEnd(int id, int &paragId, int &index);
+ void setFormat(int id, TQTextFormat *f, int flags);
+ int numSelections() const { return nSelections; }
+ void addSelection(int id);
+
+ TQString selectedText(int id, bool asRichText = false) const;
+ void removeSelectedText(int id, TQTextCursor *cursor);
+ void indentSelection(int id);
+
+ TQTextParagraph *paragAt(int i) const;
+
+ void addCommand(TQTextCommand *cmd);
+ TQTextCursor *undo(TQTextCursor *c = 0);
+ TQTextCursor *redo(TQTextCursor *c = 0);
+ TQTextCommandHistory *commands() const { return commandHistory; }
+
+ TQTextFormatCollection *formatCollection() const;
+
+ bool find(TQTextCursor &cursor, const TQString &expr, bool cs, bool wo, bool forward);
+ inline bool tqfind(TQTextCursor &cursor, const TQString &expr, bool cs, bool wo, bool forward) { return find(cursor, expr, cs, wo, forward); }
+
+ void setTextFormat(TQt::TextFormat f);
+ TQt::TextFormat textFormat() const;
+
+ bool inSelection(int selId, const QPoint &pos) const;
+
+ TQStyleSheet *styleSheet() const { return sheet_; }
+#ifndef QT_NO_MIME
+ TQMimeSourceFactory *mimeSourceFactory() const { return factory_; }
+#endif
+ TQString context() const { return contxt; }
+
+ void setStyleSheet(TQStyleSheet *s);
+ void setDefaultFormat(const QFont &font, const QColor &color);
+#ifndef QT_NO_MIME
+ void setMimeSourceFactory(TQMimeSourceFactory *f) { if (f) factory_ = f; }
+#endif
+ void setContext(const TQString &c) { if (!c.isEmpty()) contxt = c; }
+
+ void setUnderlineLinks(bool b);
+ bool underlineLinks() const { return underlLinks; }
+
+ void setPaper(TQBrush *brush) { if (backBrush) delete backBrush; backBrush = brush; }
+ TQBrush *paper() const { return backBrush; }
+
+ void doLayout(TQPainter *p, int w);
+ void draw(TQPainter *p, const TQRect& rect, const QPalette &pal, const TQBrush *paper = 0);
+
+ void drawParagraph(TQPainter *p, TQTextParagraph *parag, int cx, int cy, int cw, int ch,
+ TQPixmap *&doubleBuffer, const QPalette &pal,
+ bool drawCursor, TQTextCursor *cursor, bool resetChanged = true);
+ TQTextParagraph *draw(TQPainter *p, int cx, int cy, int cw, int ch, const QPalette &pal,
+ bool onlyChanged = false, bool drawCursor = false, TQTextCursor *cursor = 0,
+ bool resetChanged = true);
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ static TQTextCustomItem* tag(TQStyleSheet *sheet, const TQString& name,
+ const QMap<TQString, TQString> &attr,
+ const TQString& context,
+ const TQMimeSourceFactory& factory,
+ bool emptyTag, TQTextDocument *doc);
+#endif
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ void registerCustomItem(TQTextCustomItem *i, TQTextParagraph *p);
+ void unregisterCustomItem(TQTextCustomItem *i, TQTextParagraph *p);
+#endif
+
+ void setFlow(TQTextFlow *f);
+ void takeFlow();
+ TQTextFlow *flow() const { return flow_; }
+ bool isPageBreakEnabled() const { return pages; }
+ void setPageBreakEnabled(bool b) { pages = b; }
+
+ void setUseFormatCollection(bool b) { useFC = b; }
+ bool useFormatCollection() const { return useFC; }
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ TQTextTableCell *tableCell() const { return tc; }
+ void setTableCell(TQTextTableCell *c) { tc = c; }
+#endif
+
+ void setPlainText(const TQString &text);
+ void setRichText(const TQString &text, const TQString &context, const TQTextFormat *initialFormat = 0);
+ TQString richText() const;
+ TQString plainText() const;
+
+ bool focusNextPrevChild(bool next);
+
+ int alignment() const;
+ void setAlignment(int a);
+
+ int *tabArray() const;
+ int tabStopWidth() const;
+ void setTabArray(int *a);
+ void setTabStops(int tw);
+
+ void setUndoDepth(int depth) { commandHistory->setUndoDepth(depth); }
+ int undoDepth() const { return commandHistory->undoDepth(); }
+
+ int length() const;
+ void clear(bool createEmptyParag = false);
+
+ virtual TQTextParagraph *createParagraph(TQTextDocument *, TQTextParagraph *pr = 0, TQTextParagraph *nx = 0, bool updateIds = true);
+ void insertChild(TQTextDocument *dc) { childList.append(dc); }
+ void removeChild(TQTextDocument *dc) { childList.removeAll(dc); }
+ QList<TQTextDocument *> children() const { return childList; }
+
+ bool hasFocusParagraph() const;
+ TQString focusHref() const;
+ TQString focusName() const;
+
+ void invalidateOriginalText() { oTextValid = false; oText = TQLatin1String(""); }
+
+Q_SIGNALS:
+ void minimumWidthChanged(int);
+
+private:
+ Q_DISABLE_COPY(TQTextDocument)
+
+ void init();
+ TQPixmap *bufferPixmap(const QSize &s);
+ // HTML parser
+ bool hasPrefix(const TQChar* doc, int length, int pos, TQChar c);
+ bool hasPrefix(const TQChar* doc, int length, int pos, const TQString& s);
+#ifndef QT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem* parseTable(const QMap<TQString, TQString> &attr, const TQTextFormat &fmt,
+ const TQChar* doc, int length, int& pos, TQTextParagraph *curpar);
+#endif
+ bool eatSpace(const TQChar* doc, int length, int& pos, bool includeNbsp = false);
+ bool eat(const TQChar* doc, int length, int& pos, TQChar c);
+ TQString parseOpenTag(const TQChar* doc, int length, int& pos, QMap<TQString, TQString> &attr, bool& emptyTag);
+ TQString parseCloseTag(const TQChar* doc, int length, int& pos);
+ TQChar parseHTMLSpecialChar(const TQChar* doc, int length, int& pos);
+ TQString parseWord(const TQChar* doc, int length, int& pos, bool lower = true);
+ TQChar parseChar(const TQChar* doc, int length, int& pos, TQStyleSheetItem::WhiteSpaceMode wsm);
+ void setRichTextInternal(const TQString &text, TQTextCursor* cursor = 0, const TQTextFormat *initialFormat = 0);
+ void setRichTextMarginsInternal(QList< QVector<TQStyleSheetItem *> *>& styles, TQTextParagraph* stylesPar);
+
+ struct Q_COMPAT_EXPORT Focus {
+ TQTextParagraph *parag;
+ int start, len;
+ TQString href;
+ TQString name;
+ };
+
+ int cx, cy, cw, vw;
+ TQTextParagraph *fParag, *lParag;
+ TQTextPreProcessor *pProcessor;
+ struct SelectionColor {
+ QColor background;
+ QColor text;
+ };
+ QMap<int, SelectionColor> selectionColors;
+ QMap<int, TQTextDocumentSelection> selections;
+ TQTextCommandHistory *commandHistory;
+ TQTextFormatter *pFormatter;
+ TQTextIndent *indenter;
+ TQTextFormatCollection *fCollection;
+ TQt::TextFormat txtFormat;
+ uint preferRichText : 1;
+ uint pages : 1;
+ uint useFC : 1;
+ uint withoutDoubleBuffer : 1;
+ uint underlLinks : 1;
+ uint nextDoubleBuffered : 1;
+ uint oTextValid : 1;
+ uint mightHaveCustomItems : 1;
+ int align;
+ int nSelections;
+ TQTextFlow *flow_;
+ TQTextDocument *par;
+ TQTextParagraph *parentPar;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ TQTextTableCell *tc;
+#endif
+ TQBrush *backBrush;
+ TQPixmap *buf_pixmap;
+ Focus focusIndicator;
+ int minw;
+ int wused;
+ int leftmargin;
+ int rightmargin;
+ TQTextParagraph *minwParag, *curParag;
+ TQStyleSheet* sheet_;
+#ifndef QT_NO_MIME
+ TQMimeSourceFactory* factory_;
+#endif
+ TQString contxt;
+ QMap<TQString, TQString> attribs;
+ int *tArray;
+ int tStopWidth;
+ int uDepth;
+ TQString oText;
+ QList<TQTextDocument *> childList;
+ QColor linkColor, bodyText;
+ double scaleFontsFactor;
+
+ // TQt specific
+ TQMap<int, bool> selectionText;
+
+ short list_tm,list_bm, list_lm, li_tm, li_bm, par_tm, par_bm;
+};
+
+inline void TQTextDocument::setInvertSelectionText( int id, bool b )
+{
+// TQTextDocument *p = this;
+// while (p->par)
+// p = p->par;
+ selectionText[ id ] = b;
+}
+
+inline bool TQTextDocument::invertSelectionText( int id ) const
+{
+// TQTextDocument *p = this;
+// while (p->par)
+// p = p->par;
+ return selectionText[ id ];
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
+class Q_COMPAT_EXPORT TQTextDeleteCommand : public TQTextCommand
+{
+public:
+ TQTextDeleteCommand(TQTextDocument *dc, int i, int idx, const QVector<TQTextStringChar> &str,
+ const QByteArray& oldStyle);
+ TQTextDeleteCommand(TQTextParagraph *p, int idx, const QVector<TQTextStringChar> &str);
+ virtual ~TQTextDeleteCommand();
+
+ Commands type() const { return Delete; }
+ TQTextCursor *execute(TQTextCursor *c);
+ TQTextCursor *unexecute(TQTextCursor *c);
+
+protected:
+ int id, index;
+ TQTextParagraph *parag;
+ QVector<TQTextStringChar> text;
+ QByteArray styleInformation;
+
+};
+
+class Q_COMPAT_EXPORT TQTextInsertCommand : public TQTextDeleteCommand
+{
+public:
+ TQTextInsertCommand(TQTextDocument *dc, int i, int idx, const QVector<TQTextStringChar> &str,
+ const QByteArray& oldStyleInfo)
+ : TQTextDeleteCommand(dc, i, idx, str, oldStyleInfo) {}
+ TQTextInsertCommand(TQTextParagraph *p, int idx, const QVector<TQTextStringChar> &str)
+ : TQTextDeleteCommand(p, idx, str) {}
+ virtual ~TQTextInsertCommand() {}
+
+ Commands type() const { return Insert; }
+ TQTextCursor *execute(TQTextCursor *c) { return TQTextDeleteCommand::unexecute(c); }
+ TQTextCursor *unexecute(TQTextCursor *c) { return TQTextDeleteCommand::execute(c); }
+
+};
+
+class Q_COMPAT_EXPORT TQTextFormatCommand : public TQTextCommand
+{
+public:
+ TQTextFormatCommand(TQTextDocument *dc, int sid, int sidx, int eid, int eidx, const QVector<TQTextStringChar> &old, TQTextFormat *f, int fl);
+ virtual ~TQTextFormatCommand();
+
+ Commands type() const { return Format; }
+ TQTextCursor *execute(TQTextCursor *c);
+ TQTextCursor *unexecute(TQTextCursor *c);
+
+protected:
+ int startId, startIndex, endId, endIndex;
+ TQTextFormat *format;
+ QVector<TQTextStringChar> oldFormats;
+ int flags;
+
+};
+
+class Q_COMPAT_EXPORT TQTextStyleCommand : public TQTextCommand
+{
+public:
+ TQTextStyleCommand(TQTextDocument *dc, int fParag, int lParag, const QByteArray& beforeChange );
+ virtual ~TQTextStyleCommand() {}
+
+ Commands type() const { return Style; }
+ TQTextCursor *execute(TQTextCursor *c);
+ TQTextCursor *unexecute(TQTextCursor *c);
+
+ static QByteArray readStyleInformation( TQTextDocument* dc, int fParag, int lParag);
+ static void writeStyleInformation( TQTextDocument* dc, int fParag, const QByteArray& style);
+
+private:
+ int firstParag, lastParag;
+ QByteArray before;
+ QByteArray after;
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+struct Q_COMPAT_EXPORT TQTextParagraphSelection
+{
+ int start, end;
+ Q_DUMMY_COMPARISON_OPERATOR(TQTextParagraphSelection)
+};
+
+struct Q_COMPAT_EXPORT QTextLineStart
+{
+ QTextLineStart() : y(0), baseLine(0), h(0)
+ { }
+ QTextLineStart(int y_, int bl, int h_) : y(y_), baseLine(bl), h(h_),
+ w(0)
+ { }
+
+public:
+ int y, baseLine, h;
+ int w;
+};
+
+class Q_COMPAT_EXPORT TQTextParagraphData
+{
+public:
+ TQTextParagraphData() {}
+ virtual ~TQTextParagraphData();
+ virtual void join(TQTextParagraphData *);
+};
+
+class TQTextParagraphPseudoDocument;
+
+class TQSyntaxHighlighter;
+
+class Q_COMPAT_EXPORT TQTextParagraph
+{
+ friend class TQTextDocument;
+ friend class TQTextCursor;
+ friend class TQSyntaxHighlighter;
+
+public:
+ TQTextParagraph(TQTextDocument *dc, TQTextParagraph *pr = 0, TQTextParagraph *nx = 0, bool updateIds = true);
+ ~TQTextParagraph();
+
+ TQTextString *string() const;
+ TQTextStringChar *at(int i) const; // maybe remove later
+ int leftGap() const;
+ int length() const; // maybe remove later
+
+ void setListStyle(TQStyleSheetItem::ListStyle ls) { lstyle = ls; changed = true; }
+ TQStyleSheetItem::ListStyle listStyle() const { return (TQStyleSheetItem::ListStyle)lstyle; }
+ void setListItem(bool li);
+ bool isListItem() const { return litem; }
+ void setListValue(int v) { list_val = v; }
+ int listValue() const { return list_val > 0 ? list_val : -1; }
+
+ void setListDepth(int depth);
+ int listDepth() const { return ldepth; }
+
+// void setFormat(TQTextFormat *fm);
+// TQTextFormat *paragFormat() const;
+
+ inline TQTextDocument *document() const {
+ if (hasdoc) return (TQTextDocument*) docOrPseudo;
+ return 0;
+ }
+ TQTextParagraphPseudoDocument *pseudoDocument() const;
+
+ TQRect rect() const;
+ void setHeight(int h) { r.setHeight(h); }
+ void show();
+ void hide();
+ bool isVisible() const { return visible; }
+
+ TQTextParagraph *prev() const;
+ TQTextParagraph *next() const;
+ void setPrev(TQTextParagraph *s);
+ void setNext(TQTextParagraph *s);
+
+ void insert(int index, const QString &s);
+ void insert(int index, const QChar *unicode, int len);
+ void append(const TQString &s, bool reallyAtEnd = false);
+ void truncate(int index);
+ void remove(int index, int len);
+ void join(TQTextParagraph *s);
+
+ void invalidate(int chr);
+ inline void tqinvalidate(int chr) { invalidate(chr); }
+
+ void move(int &dy);
+ void format(int start = -1, bool doMove = true);
+
+ bool isValid() const;
+ bool hasChanged() const;
+ void setChanged(bool b, bool recursive = false);
+
+ int lineHeightOfChar(int i, int *bl = 0, int *y = 0) const;
+ TQTextStringChar *lineStartOfChar(int i, int *index = 0, int *line = 0) const;
+ int lines() const;
+ TQTextStringChar *lineStartOfLine(int line, int *index = 0) const;
+ int lineY(int l) const;
+ int lineBaseLine(int l) const;
+ int lineHeight(int l) const;
+ void lineInfo(int l, int &y, int &h, int &bl) const;
+
+ void setSelection(int id, int start, int end);
+ void removeSelection(int id);
+ int selectionStart(int id) const;
+ int selectionEnd(int id) const;
+ bool hasSelection(int id) const;
+ bool hasAnySelection() const;
+ bool fullSelected(int id) const;
+
+ void setEndState(int s);
+ int endState() const;
+
+ void setParagId(int i);
+ int paragId() const;
+
+ bool firstPreProcess() const;
+ void setFirstPreProcess(bool b);
+
+ void indent(int *oldIndent = 0, int *newIndent = 0);
+
+ void setExtraData(TQTextParagraphData *data);
+ TQTextParagraphData *extraData() const;
+
+ QMap<int, QTextLineStart*> &lineStartList();
+
+ void setFormat(int index, int len, TQTextFormat *f, bool useCollection = true, int flags = -1);
+
+ void setAlignment(int a);
+ inline void tqsetAlignment(int a) { setAlignment(a); }
+
+ int alignment() const;
+ inline int tqalignment() const { return alignment(); }
+
+ void paint(TQPainter &painter, const QPalette &pal, TQTextCursor *cursor = 0,
+ bool drawSelections = false, int clipx = -1, int clipy = -1,
+ int clipw = -1, int cliph = -1);
+
+ int topMargin() const;
+ int bottomMargin() const;
+ int leftMargin() const;
+ int firstLineMargin() const;
+ int rightMargin() const;
+ int lineSpacing() const;
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ void registerFloatingItem(TQTextCustomItem *i);
+ void unregisterFloatingItem(TQTextCustomItem *i);
+#endif
+
+ void setFullWidth(bool b) { fullWidth = b; }
+ bool isFullWidth() const { return fullWidth; }
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+ TQTextTableCell *tableCell() const;
+#endif
+
+ TQBrush *background() const;
+
+ int documentWidth() const;
+ int documentVisibleWidth() const;
+ int documentX() const;
+ int documentY() const;
+ TQTextFormatCollection *formatCollection() const;
+ TQTextFormatter *formatter() const;
+
+ int nextTab(int i, int x);
+ int *tabArray() const;
+ void setTabArray(int *a);
+ void setTabStops(int tw);
+
+ void adjustToPainter(TQPainter *p);
+
+ void setNewLinesAllowed(bool b);
+ bool isNewLinesAllowed() const;
+
+ TQString richText() const;
+
+ void addCommand(TQTextCommand *cmd);
+ TQTextCursor *undo(TQTextCursor *c = 0);
+ TQTextCursor *redo(TQTextCursor *c = 0);
+ TQTextCommandHistory *commands() const;
+ void copyParagData(TQTextParagraph *parag);
+
+ void setBreakable(bool b) { breakable = b; }
+ bool isBreakable() const { return breakable; }
+
+ void setBackgroundColor(const QColor &c);
+ QColor *backgroundColor() const { return bgcol; }
+ void clearBackgroundColor();
+
+ void setMovedDown(bool b) { movedDown = b; }
+ bool wasMovedDown() const { return movedDown; }
+
+ void setDirection(TQChar::Direction);
+ TQChar::Direction direction() const;
+ void setPaintDevice(TQPaintDevice *pd) { paintdevice = pd; }
+
+ void readStyleInformation(QDataStream& stream);
+ void writeStyleInformation(QDataStream& stream) const;
+
+protected:
+ void setColorForSelection(QColor &c, TQPainter &p, const QPalette &pal, int selection);
+ void drawLabel(TQPainter* p, int x, int y, int w, int h, int base, const QPalette &pal);
+ void drawString(TQPainter &painter, const TQString &str, int start, int len, int xstart,
+ int y, int baseLine, int w, int h, bool drawSelections, int fullSelectionWidth,
+ TQTextStringChar *formatChar, const QPalette &pal,
+ bool rightToLeft);
+
+private:
+ QMap<int, TQTextParagraphSelection> &selections() const;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ QList<TQTextCustomItem *> &floatingItems() const;
+#endif
+ inline TQBrush backgroundBrush(const QPalette &pal) {
+ if (bgcol)
+ return *bgcol;
+ return pal.brush(QPalette::Base);
+ }
+ void invalidateStyleCache();
+
+ QMap<int, QTextLineStart*> lineStarts;
+ TQRect r;
+ TQTextParagraph *p, *n;
+ void *docOrPseudo;
+ uint changed : 1;
+ uint firstFormat : 1;
+ uint firstPProcess : 1;
+ uint needPreProcess : 1;
+ uint fullWidth : 1;
+ uint lastInFrame : 1;
+ uint visible : 1;
+ uint breakable : 1;
+ uint movedDown : 1;
+ uint mightHaveCustomItems : 1;
+ uint hasdoc : 1;
+ uint litem : 1; // whether the paragraph is a list item
+ uint rtext : 1; // whether the paragraph needs rich text margin
+ signed int align : 5;
+ uint /*TQStyleSheetItem::ListStyle*/ lstyle : 4;
+ int invalid;
+ int state, id;
+ TQTextString *str;
+ QMap<int, TQTextParagraphSelection> *mSelections;
+#ifndef QT_NO_TEXTCUSTOMITEM
+ QList<TQTextCustomItem *> *mFloatingItems;
+#endif
+ short utm, ubm, ulm, urm, uflm, ulinespacing;
+ short tabStopWidth, minwidth;
+ int *tArray;
+ TQTextParagraphData *eData;
+ short list_val;
+ ushort ldepth;
+ QColor *bgcol;
+ TQPaintDevice *paintdevice;
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class Q_COMPAT_EXPORT TQTextFormatter
+{
+public:
+ TQTextFormatter();
+ virtual ~TQTextFormatter();
+
+ virtual int format(TQTextDocument *doc, TQTextParagraph *parag, int start, const QMap<int, QTextLineStart*> &oldLineStarts) = 0;
+ virtual int formatVertically(TQTextDocument* doc, TQTextParagraph* parag);
+
+ bool isWrapEnabled(TQTextParagraph *p) const { if (!wrapEnabled) return false; if (p && !p->isBreakable()) return false; return true;}
+ int wrapAtColumn() const { return wrapColumn;}
+ virtual void setWrapEnabled(bool b);
+ virtual void setWrapAtColumn(int c);
+ virtual void setAllowBreakInWords(bool b) { biw = b; }
+ bool allowBreakInWords() const { return biw; }
+
+ int minimumWidth() const { return thisminw; }
+ int widthUsed() const { return thiswused; }
+
+protected:
+ virtual QTextLineStart *formatLine(TQTextParagraph *parag, TQTextString *string, QTextLineStart *line, TQTextStringChar *start,
+ TQTextStringChar *last, int align = TQt::AlignAuto, int space = 0);
+#ifndef QT_NO_COMPLEXTEXT
+ virtual QTextLineStart *bidiReorderLine(TQTextParagraph *parag, TQTextString *string, QTextLineStart *line, TQTextStringChar *start,
+ TQTextStringChar *last, int align, int space);
+#endif
+ void insertLineStart(TQTextParagraph *parag, int index, QTextLineStart *ls);
+
+ int thisminw;
+ int thiswused;
+
+private:
+ bool wrapEnabled;
+ int wrapColumn;
+ bool biw;
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class Q_COMPAT_EXPORT TQTextFormatterBreakInWords : public TQTextFormatter
+{
+public:
+ TQTextFormatterBreakInWords();
+ virtual ~TQTextFormatterBreakInWords() {}
+
+ int format(TQTextDocument *doc, TQTextParagraph *parag, int start, const QMap<int, QTextLineStart*> &oldLineStarts);
+
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class Q_COMPAT_EXPORT TQTextFormatterBreakWords : public TQTextFormatter
+{
+public:
+ TQTextFormatterBreakWords();
+ virtual ~TQTextFormatterBreakWords() {}
+
+ int format(TQTextDocument *doc, TQTextParagraph *parag, int start, const QMap<int, QTextLineStart*> &oldLineStarts);
+
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class Q_COMPAT_EXPORT TQTextIndent
+{
+public:
+ TQTextIndent();
+ virtual ~TQTextIndent() {}
+
+ virtual void indent(TQTextDocument *doc, TQTextParagraph *parag, int *oldIndent = 0, int *newIndent = 0) = 0;
+
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class Q_COMPAT_EXPORT TQTextPreProcessor
+{
+public:
+ enum Ids {
+ Standard = 0
+ };
+
+ TQTextPreProcessor();
+ virtual ~TQTextPreProcessor() {}
+
+ virtual void process(TQTextDocument *doc, TQTextParagraph *, int, bool = true) = 0;
+ virtual TQTextFormat *format(int id) = 0;
+
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class Q_COMPAT_EXPORT TQTextFormat
+{
+ friend class TQTextFormatCollection;
+ friend class TQTextDocument;
+
+public:
+ enum Flags {
+ NoFlags,
+ Bold = 1,
+ Italic = 2,
+ Underline = 4,
+ Family = 8,
+ Size = 16,
+ Color = 32,
+ Misspelled = 64,
+ VAlign = 128,
+ StrikeOut= 256,
+ Font = Bold | Italic | Underline | Family | Size | StrikeOut,
+ Format = Font | Color | Misspelled | VAlign
+ };
+
+ enum VerticalAlignment { AlignNormal, AlignSuperScript, AlignSubScript };
+
+ TQTextFormat();
+ virtual ~TQTextFormat();
+
+ TQTextFormat(const TQStyleSheetItem *s);
+ TQTextFormat(const QFont &f, const QColor &c, TQTextFormatCollection *parent = 0);
+ TQTextFormat(const TQTextFormat &fm);
+ TQTextFormat makeTextFormat(const TQStyleSheetItem *style, const QMap<TQString,TQString>& attr, double scaleFontsFactor) const;
+ TQTextFormat& operator=(const TQTextFormat &fm);
+ QColor color() const;
+ QFont font() const;
+ QFontMetrics fontMetrics() const { return fm; }
+ bool isMisspelled() const;
+ VerticalAlignment vAlign() const;
+ int minLeftBearing() const;
+ int minRightBearing() const;
+ int width(const TQChar &c) const;
+ int width(const TQString &str, int pos) const;
+ int height() const;
+ int ascent() const;
+ int descent() const;
+ int leading() const;
+ bool useLinkColor() const;
+
+ void setBold(bool b);
+ void setItalic(bool b);
+ void setUnderline(bool b);
+ void setStrikeOut(bool b);
+ void setFamily(const TQString &f);
+ void setPointSize(int s);
+ void setFont(const QFont &f);
+ void setColor(const QColor &c);
+ void setMisspelled(bool b);
+ void setVAlign(VerticalAlignment a);
+
+ bool operator==(const TQTextFormat &f) const;
+ TQTextFormatCollection *parent() const;
+ const TQString &key() const;
+
+ static TQString getKey(const QFont &f, const QColor &c, bool misspelled, VerticalAlignment vAlign);
+
+ void addRef();
+ void removeRef();
+
+ TQString makeFormatChangeTags(TQTextFormat* defaultFormat, TQTextFormat *f, const TQString& oldAnchorHref, const TQString& anchorHref) const;
+ TQString makeFormatEndTags(TQTextFormat* defaultFormat, const TQString& anchorHref) const;
+
+ static void setPainter(TQPainter *p);
+ static TQPainter* painter();
+
+ bool fontSizesInPixels() { return usePixelSizes; }
+
+protected:
+ virtual void generateKey();
+
+private:
+ void update();
+ static void applyFont(const QFont &f);
+
+private:
+ TQFont fn;
+ QColor col;
+ QFontMetrics fm;
+ uint missp : 1;
+ uint linkColor : 1;
+ uint usePixelSizes : 1;
+ int leftBearing, rightBearing;
+ VerticalAlignment ha;
+ uchar widths[256];
+ int hei, asc, dsc;
+ TQTextFormatCollection *collection;
+ int ref;
+ TQString k;
+ int logicalFontSize;
+ int stdSize;
+ static TQPainter *pntr;
+ static QFontMetrics *pntr_fm;
+ static int pntr_asc;
+ static int pntr_hei;
+ static int pntr_ldg;
+ static int pntr_dsc;
+
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class Q_COMPAT_EXPORT TQTextFormatCollection
+{
+ friend class TQTextDocument;
+ friend class TQTextFormat;
+
+public:
+ TQTextFormatCollection();
+ virtual ~TQTextFormatCollection();
+
+ void setDefaultFormat(TQTextFormat *f);
+ TQTextFormat *defaultFormat() const;
+ virtual TQTextFormat *format(TQTextFormat *f);
+ virtual TQTextFormat *format(TQTextFormat *of, TQTextFormat *nf, int flags);
+ virtual TQTextFormat *format(const QFont &f, const QColor &c);
+ virtual void remove(TQTextFormat *f);
+ virtual TQTextFormat *createFormat(const TQTextFormat &f) { return new TQTextFormat(f); }
+ virtual TQTextFormat *createFormat(const QFont &f, const QColor &c) { return new TQTextFormat(f, c, this); }
+
+ void updateDefaultFormat(const QFont &font, const QColor &c, TQStyleSheet *sheet);
+
+ TQPaintDevice *paintDevice() const { return paintdevice; }
+ void setPaintDevice(QPaintDevice *);
+
+private:
+ void updateKeys();
+
+private:
+ TQTextFormat *defFormat, *lastFormat, *cachedFormat;
+ QHash<TQString, TQTextFormat *> cKey;
+ TQTextFormat *cres;
+ QFont cfont;
+ QColor ccol;
+ TQString kof, knf;
+ int cflags;
+
+ TQPaintDevice *paintdevice;
+};
+
+class Q_COMPAT_EXPORT TQTextParagraphPseudoDocument
+{
+public:
+ TQTextParagraphPseudoDocument();
+ ~TQTextParagraphPseudoDocument();
+ TQRect docRect;
+ TQTextFormatter *pFormatter;
+ TQTextCommandHistory *commandHistory;
+ int minw;
+ int wused;
+ TQTextFormatCollection collection;
+};
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+inline int TQTextParagraph::length() const
+{
+ return str->length();
+}
+
+inline TQRect TQTextParagraph::rect() const
+{
+ return r;
+}
+
+inline int TQTextCursor::index() const
+{
+ return idx;
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+inline int TQTextDocument::x() const
+{
+ return cx;
+}
+
+inline int TQTextDocument::y() const
+{
+ return cy;
+}
+
+inline int TQTextDocument::width() const
+{
+ return qMax(cw, flow_->width());
+}
+
+inline int TQTextDocument::visibleWidth() const
+{
+ return vw;
+}
+
+inline TQTextParagraph *TQTextDocument::firstParagraph() const
+{
+ return fParag;
+}
+
+inline TQTextParagraph *TQTextDocument::lastParagraph() const
+{
+ return lParag;
+}
+
+inline void TQTextDocument::setFirstParagraph(TQTextParagraph *p)
+{
+ fParag = p;
+}
+
+inline void TQTextDocument::setLastParagraph(TQTextParagraph *p)
+{
+ lParag = p;
+}
+
+inline void TQTextDocument::setWidth(int w)
+{
+ cw = qMax(w, minw);
+ flow_->setWidth(cw);
+ vw = w;
+}
+
+inline int TQTextDocument::minimumWidth() const
+{
+ return minw;
+}
+
+inline void TQTextDocument::setY(int y)
+{
+ cy = y;
+}
+
+inline int TQTextDocument::leftMargin() const
+{
+ return leftmargin;
+}
+
+inline void TQTextDocument::setLeftMargin(int lm)
+{
+ leftmargin = lm;
+}
+
+inline int TQTextDocument::rightMargin() const
+{
+ return rightmargin;
+}
+
+inline void TQTextDocument::setRightMargin(int rm)
+{
+ rightmargin = rm;
+}
+
+inline TQTextPreProcessor *TQTextDocument::preProcessor() const
+{
+ return pProcessor;
+}
+
+inline void TQTextDocument::setPreProcessor(TQTextPreProcessor * sh)
+{
+ pProcessor = sh;
+}
+
+inline void TQTextDocument::setFormatter(TQTextFormatter *f)
+{
+ delete pFormatter;
+ pFormatter = f;
+}
+
+inline TQTextFormatter *TQTextDocument::formatter() const
+{
+ return pFormatter;
+}
+
+inline void TQTextDocument::setIndent(TQTextIndent *i)
+{
+ indenter = i;
+}
+
+inline TQTextIndent *TQTextDocument::indent() const
+{
+ return indenter;
+}
+
+inline QColor TQTextDocument::selectionColor(int id) const
+{
+ const TQTextDocument *p = this;
+ while (p->par)
+ p = p->par;
+ return p->selectionColors[id].background;
+}
+
+inline QColor TQTextDocument::selectionTextColor(int id) const
+{
+ const TQTextDocument *p = this;
+ while (p->par)
+ p = p->par;
+ return p->selectionColors[id].text;
+}
+
+inline bool TQTextDocument::hasSelectionTextColor(int id) const
+{
+ const TQTextDocument *p = this;
+ while (p->par)
+ p = p->par;
+ return p->selectionColors.contains(id);
+}
+
+inline void TQTextDocument::setSelectionColor(int id, const QColor &c)
+{
+ TQTextDocument *p = this;
+ while (p->par)
+ p = p->par;
+ p->selectionColors[id].background = c;
+}
+
+inline void TQTextDocument::setSelectionTextColor(int id, const QColor &c)
+{
+ TQTextDocument *p = this;
+ while (p->par)
+ p = p->par;
+ p->selectionColors[id].text = c;
+}
+
+inline TQTextFormatCollection *TQTextDocument::formatCollection() const
+{
+ return fCollection;
+}
+
+inline int TQTextDocument::alignment() const
+{
+ return align;
+}
+
+inline void TQTextDocument::setAlignment(int a)
+{
+ align = a;
+}
+
+inline int *TQTextDocument::tabArray() const
+{
+ return tArray;
+}
+
+inline int TQTextDocument::tabStopWidth() const
+{
+ return tStopWidth;
+}
+
+inline void TQTextDocument::setTabArray(int *a)
+{
+ tArray = a;
+}
+
+inline void TQTextDocument::setTabStops(int tw)
+{
+ tStopWidth = tw;
+}
+
+inline TQString TQTextDocument::originalText() const
+{
+ if (oTextValid)
+ return oText;
+ return text();
+}
+
+inline void TQTextDocument::setFlow(TQTextFlow *f)
+{
+ if (flow_)
+ delete flow_;
+ flow_ = f;
+}
+
+inline void TQTextDocument::takeFlow()
+{
+ flow_ = 0;
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+inline QColor TQTextFormat::color() const
+{
+ return col;
+}
+
+inline QFont TQTextFormat::font() const
+{
+ return fn;
+}
+
+inline bool TQTextFormat::isMisspelled() const
+{
+ return missp;
+}
+
+inline TQTextFormat::VerticalAlignment TQTextFormat::vAlign() const
+{
+ return ha;
+}
+
+inline bool TQTextFormat::operator==(const TQTextFormat &f) const
+{
+ return k == f.k;
+}
+
+inline TQTextFormatCollection *TQTextFormat::parent() const
+{
+ return collection;
+}
+
+inline void TQTextFormat::addRef()
+{
+ ref++;
+}
+
+inline void TQTextFormat::removeRef()
+{
+ ref--;
+ if (!collection)
+ return;
+ if (this == collection->defFormat)
+ return;
+ if (ref == 0)
+ collection->remove(this);
+}
+
+inline const TQString &TQTextFormat::key() const
+{
+ return k;
+}
+
+inline bool TQTextFormat::useLinkColor() const
+{
+ return linkColor;
+}
+
+inline TQTextStringChar *TQTextParagraph::at(int i) const
+{
+ return &str->at(i);
+}
+
+inline bool TQTextParagraph::isValid() const
+{
+ return invalid == -1;
+}
+
+inline bool TQTextParagraph::hasChanged() const
+{
+ return changed;
+}
+
+inline void TQTextParagraph::setBackgroundColor(const QColor & c)
+{
+ delete bgcol;
+ bgcol = new QColor(c);
+ setChanged(true);
+}
+
+inline void TQTextParagraph::clearBackgroundColor()
+{
+ delete bgcol; bgcol = 0; setChanged(true);
+}
+
+inline void TQTextParagraph::append(const TQString &s, bool reallyAtEnd)
+{
+ if (reallyAtEnd) {
+ insert(str->length(), s);
+ } else {
+ int str_end = str->length() - 1;
+ insert(str_end > 0 ? str_end : 0, s);
+ }
+}
+
+inline TQTextParagraph *TQTextParagraph::prev() const
+{
+ return p;
+}
+
+inline TQTextParagraph *TQTextParagraph::next() const
+{
+ return n;
+}
+
+inline bool TQTextParagraph::hasAnySelection() const
+{
+ return mSelections ? !selections().isEmpty() : false;
+}
+
+inline void TQTextParagraph::setEndState(int s)
+{
+ if (s == state)
+ return;
+ state = s;
+}
+
+inline int TQTextParagraph::endState() const
+{
+ return state;
+}
+
+inline void TQTextParagraph::setParagId(int i)
+{
+ id = i;
+}
+
+inline int TQTextParagraph::paragId() const
+{
+ if (id == -1)
+ qWarning("invalid parag id!!!!!!!! (%p)", (void*)this);
+ return id;
+}
+
+inline bool TQTextParagraph::firstPreProcess() const
+{
+ return firstPProcess;
+}
+
+inline void TQTextParagraph::setFirstPreProcess(bool b)
+{
+ firstPProcess = b;
+}
+
+inline QMap<int, QTextLineStart*> &TQTextParagraph::lineStartList()
+{
+ return lineStarts;
+}
+
+inline TQTextString *TQTextParagraph::string() const
+{
+ return str;
+}
+
+inline TQTextParagraphPseudoDocument *TQTextParagraph::pseudoDocument() const
+{
+ if (hasdoc)
+ return 0;
+ return (TQTextParagraphPseudoDocument*) docOrPseudo;
+}
+
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+inline TQTextTableCell *TQTextParagraph::tableCell() const
+{
+ return hasdoc ? document()->tableCell () : 0;
+}
+#endif
+
+inline TQTextCommandHistory *TQTextParagraph::commands() const
+{
+ return hasdoc ? document()->commands() : pseudoDocument()->commandHistory;
+}
+
+
+inline int TQTextParagraph::alignment() const
+{
+ return align;
+}
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+inline void TQTextParagraph::registerFloatingItem(TQTextCustomItem *i)
+{
+ floatingItems().append(i);
+}
+
+inline void TQTextParagraph::unregisterFloatingItem(TQTextCustomItem *i)
+{
+ floatingItems().removeAll(i);
+}
+#endif
+
+inline TQBrush *TQTextParagraph::background() const
+{
+#ifndef QT_NO_TEXTCUSTOMITEM
+ return tableCell() ? tableCell()->backGround() : 0;
+#else
+ return 0;
+#endif
+}
+
+inline int TQTextParagraph::documentWidth() const
+{
+ return hasdoc ? document()->width() : pseudoDocument()->docRect.width();
+}
+
+inline int TQTextParagraph::documentVisibleWidth() const
+{
+ return hasdoc ? document()->visibleWidth() : pseudoDocument()->docRect.width();
+}
+
+inline int TQTextParagraph::documentX() const
+{
+ return hasdoc ? document()->x() : pseudoDocument()->docRect.x();
+}
+
+inline int TQTextParagraph::documentY() const
+{
+ return hasdoc ? document()->y() : pseudoDocument()->docRect.y();
+}
+
+inline void TQTextParagraph::setExtraData(TQTextParagraphData *data)
+{
+ eData = data;
+}
+
+inline TQTextParagraphData *TQTextParagraph::extraData() const
+{
+ return eData;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+inline void TQTextFormatCollection::setDefaultFormat(TQTextFormat *f)
+{
+ defFormat = f;
+}
+
+inline TQTextFormat *TQTextFormatCollection::defaultFormat() const
+{
+ return defFormat;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+inline TQTextFormat *TQTextStringChar::format() const
+{
+ return (type == Regular) ? p.format : p.custom->format;
+}
+
+
+#ifndef QT_NO_TEXTCUSTOMITEM
+inline TQTextCustomItem *TQTextStringChar::customItem() const
+{
+ return isCustom() ? p.custom->custom : 0;
+}
+#endif
+
+inline int TQTextStringChar::height() const
+{
+#ifndef QT_NO_TEXTCUSTOMITEM
+ return !isCustom() ? format()->height() : (customItem()->placement() == TQTextCustomItem::PlaceInline ? customItem()->height : 0);
+#else
+ return format()->height();
+#endif
+}
+
+inline int TQTextStringChar::ascent() const
+{
+#ifndef QT_NO_TEXTCUSTOMITEM
+ return !isCustom() ? format()->ascent() : (customItem()->placement() == TQTextCustomItem::PlaceInline ? customItem()->ascent() : 0);
+#else
+ return format()->ascent();
+#endif
+}
+
+inline int TQTextStringChar::descent() const
+{
+#ifndef QT_NO_TEXTCUSTOMITEM
+ return !isCustom() ? format()->descent() : 0;
+#else
+ return format()->descent();
+#endif
+}
+
+#endif // QT_NO_RICHTEXT
+
+QT_END_NAMESPACE
+
+#endif // TQRICHTEXT_P_H
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Definition of internal rich text classes
+**
+** Created : 990124
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQRICHTEXT_P_H
+#define TQRICHTEXT_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqptrlist.h"
+#include "tqrect.h"
+#include "tqfontmetrics.h"
+#include "tqintdict.h"
+#include "tqmap.h"
+#include "tqstringlist.h"
+#include "tqfont.h"
+#include "tqcolor.h"
+#include "tqsize.h"
+#include "tqvaluelist.h"
+#include "tqvaluestack.h"
+#include "tqobject.h"
+#include "tqdict.h"
+#include "tqpixmap.h"
+#include "tqstylesheet.h"
+#include "tqptrvector.h"
+#include "tqpainter.h"
+#include "tqlayout.h"
+#include "tqobject.h"
+#include "tqapplication.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_RICHTEXT
+
+class TQTextDocument;
+class TQTextString;
+class TQTextPreProcessor;
+class TQTextFormat;
+class TQTextCursor;
+class TQTextParagraph;
+class TQTextFormatter;
+class TQTextIndent;
+class TQTextFormatCollection;
+class TQStyleSheetItem;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+class TQTextCustomItem;
+#endif
+class TQTextFlow;
+struct TQBidiContext;
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class TQ_EXPORT TQTextStringChar
+{
+ friend class TQTextString;
+
+public:
+ // this is never called, initialize variables in TQTextString::insert()!!!
+ TQTextStringChar() : nobreak(FALSE), lineStart( 0 ), type( Regular ) {d.format=0;}
+ ~TQTextStringChar();
+
+ struct CustomData
+ {
+ TQTextFormat *format;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem *custom;
+#endif
+ TQString anchorName;
+ TQString anchorHref;
+ };
+ enum Type { Regular=0, Custom=1, Anchor=2, CustomAnchor=3 };
+
+ TQChar c;
+ // this is the same struct as in qtextengine_p.h. Don't change!
+ uchar softBreak :1; // Potential linebreak point
+ uchar whiteSpace :1; // A tqunicode whitespace character, except NBSP, ZWNBSP
+ uchar charStop :1; // Valid cursor position (for left/right arrow)
+ uchar wordStop :1; // Valid cursor position (for ctrl + left/right arrow)
+ uchar nobreak :1;
+
+ uchar lineStart : 1;
+ uchar /*Type*/ type : 2;
+ uchar bidiLevel :7;
+ uchar rightToLeft : 1;
+
+ int x;
+ union {
+ TQTextFormat* format;
+ CustomData* custom;
+ } d;
+
+
+ int height() const;
+ int ascent() const;
+ int descent() const;
+ bool isCustom() const { return (type & Custom) != 0; }
+ TQTextFormat *format() const;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem *customItem() const;
+#endif
+ void setFormat( TQTextFormat *f );
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ void setCustomItem( TQTextCustomItem *i );
+#endif
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ void loseCustomItem();
+#endif
+
+
+ bool isAnchor() const { return ( type & Anchor) != 0; }
+ bool isLink() const { return isAnchor() && !!d.custom->anchorHref; }
+ TQString anchorName() const;
+ TQString anchorHref() const;
+ void setAnchor( const TQString& name, const TQString& href );
+
+private:
+ TQTextStringChar &operator=( const TQTextStringChar & ) {
+ //abort();
+ return *this;
+ }
+ TQTextStringChar( const TQTextStringChar & ) {
+ }
+ friend class TQTextParagraph;
+};
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMemArray<TQTextStringChar>;
+// TQMOC_SKIP_END
+#endif
+
+class TQ_EXPORT TQTextString
+{
+public:
+
+ TQTextString();
+ TQTextString( const TQTextString &s );
+ virtual ~TQTextString();
+
+ static TQString toString( const TQMemArray<TQTextStringChar> &data );
+ TQString toString() const;
+
+ inline TQTextStringChar &at( int i ) const { return data[ i ]; }
+ inline int length() const { return data.size(); }
+
+ int width( int idx ) const;
+
+ void insert( int index, const QString &s, TQTextFormat *f );
+ void insert( int index, const QChar *tqunicode, int len, TQTextFormat *f );
+ void insert( int index, TQTextStringChar *c, bool doAddRefFormat = FALSE );
+ void truncate( int index );
+ void remove( int index, int len );
+ void clear();
+
+ void setFormat( int index, TQTextFormat *f, bool useCollection );
+
+ void setBidi( bool b ) { bidi = b; }
+ bool isBidi() const;
+ bool isRightToLeft() const;
+ TQChar::Direction direction() const;
+ void setDirection( TQChar::Direction d ) { dir = d; bidiDirty = TRUE; }
+
+ TQMemArray<TQTextStringChar> rawData() const { return data.copy(); }
+
+ void operator=( const TQString &s ) { clear(); insert( 0, s, 0 ); }
+ void operator+=( const TQString &s ) { insert( length(), s, 0 ); }
+ void prepend( const TQString &s ) { insert( 0, s, 0 ); }
+ int appendParagraphs( TQTextParagraph *start, TQTextParagraph *end );
+
+ // return next and previous valid cursor positions.
+ bool validCursorPosition( int idx );
+ int nextCursorPosition( int idx );
+ int previousCursorPosition( int idx );
+
+private:
+ void checkBidi() const;
+
+ TQMemArray<TQTextStringChar> data;
+ TQString stringCache;
+ uint bidiDirty : 1;
+ uint bidi : 1; // true when the paragraph has right to left characters
+ uint rightToLeft : 1;
+ uint dir : 5;
+};
+
+inline bool TQTextString::isBidi() const
+{
+ if ( bidiDirty )
+ checkBidi();
+ return bidi;
+}
+
+inline bool TQTextString::isRightToLeft() const
+{
+ if ( bidiDirty )
+ checkBidi();
+ return rightToLeft;
+}
+
+inline TQString TQTextString::toString() const
+{
+ if(bidiDirty)
+ checkBidi();
+ return stringCache;
+}
+
+inline TQChar::Direction TQTextString::direction() const
+{
+ return (TQChar::Direction) dir;
+}
+
+inline int TQTextString::nextCursorPosition( int next )
+{
+ if ( bidiDirty )
+ checkBidi();
+
+ const TQTextStringChar *c = data.data();
+ int len = length();
+
+ if ( next < len - 1 ) {
+ next++;
+ while ( next < len - 1 && !c[next].charStop )
+ next++;
+ }
+ return next;
+}
+
+inline int TQTextString::previousCursorPosition( int prev )
+{
+ if ( bidiDirty )
+ checkBidi();
+
+ const TQTextStringChar *c = data.data();
+
+ if ( prev ) {
+ prev--;
+ while ( prev && !c[prev].charStop )
+ prev--;
+ }
+ return prev;
+}
+
+inline bool TQTextString::validCursorPosition( int idx )
+{
+ if ( bidiDirty )
+ checkBidi();
+
+ return (at( idx ).charStop);
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueStack<int>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueStack<TQTextParagraph*>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueStack<bool>;
+// TQMOC_SKIP_END
+#endif
+
+class TQ_EXPORT TQTextCursor
+{
+public:
+ TQTextCursor( TQTextDocument *d = 0 );
+ TQTextCursor( const TQTextCursor &c );
+ TQTextCursor &operator=( const TQTextCursor &c );
+ virtual ~TQTextCursor() {}
+
+ bool operator==( const TQTextCursor &c ) const;
+ bool operator!=( const TQTextCursor &c ) const { return !(*this == c); }
+
+ inline TQTextParagraph *paragraph() const { return para; }
+
+ TQTextDocument *document() const;
+ int index() const;
+
+ void gotoPosition( TQTextParagraph* p, int index = 0);
+ void setIndex( int index ) { gotoPosition(paragraph(), index ); }
+ void setParagraph( TQTextParagraph*p ) { gotoPosition(p, 0 ); }
+
+ void gotoLeft();
+ void gotoRight();
+ void gotoNextLetter();
+ void gotoPreviousLetter();
+ void gotoUp();
+ void gotoDown();
+ void gotoLineEnd();
+ void gotoLineStart();
+ void gotoHome();
+ void gotoEnd();
+ void gotoPageUp( int visibleHeight );
+ void gotoPageDown( int visibleHeight );
+ void gotoNextWord( bool onlySpace = FALSE );
+ void gotoPreviousWord( bool onlySpace = FALSE );
+ void gotoWordLeft();
+ void gotoWordRight();
+
+ void insert( const QString &s, bool checkNewLine, TQMemArray<TQTextStringChar> *formatting = 0 );
+ void splitAndInsertEmptyParagraph( bool ind = TRUE, bool updateIds = TRUE );
+ bool remove();
+ bool removePreviousChar();
+ void indent();
+
+ bool atParagStart();
+ bool atParagEnd();
+
+ int x() const; // x in current paragraph
+ int y() const; // y in current paragraph
+
+ int globalX() const;
+ int globalY() const;
+
+ TQTextParagraph *topParagraph() const { return paras.isEmpty() ? para : paras.first(); }
+ int offsetX() const { return ox; } // inner document offset
+ int offsetY() const { return oy; } // inner document offset
+ int totalOffsetX() const; // total document offset
+ int totalOffsetY() const; // total document offset
+
+ bool place( const TQPoint &pos, TQTextParagraph *s ) { return place( pos, s, FALSE ); }
+ bool place( const TQPoint &pos, TQTextParagraph *s, bool link );
+ void restoreState();
+
+
+ int nestedDepth() const { return (int)indices.count(); } //### size_t/int cast
+ void oneUp() { if ( !indices.isEmpty() ) pop(); }
+ void setValid( bool b ) { valid = b; }
+ bool isValid() const { return valid; }
+
+ void fixCursorPosition();
+private:
+ enum Operation { EnterBegin, EnterEnd, Next, Prev, Up, Down };
+
+ void push();
+ void pop();
+ bool processNesting( Operation op );
+ void invalidateNested();
+ void gotoIntoNested( const TQPoint &globalPos );
+
+ TQTextParagraph *para;
+ int idx, tmpX;
+ int ox, oy;
+ TQValueStack<int> indices;
+ TQValueStack<TQTextParagraph*> paras;
+ TQValueStack<int> xOffsets;
+ TQValueStack<int> yOffsets;
+ uint valid : 1;
+
+};
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class TQ_EXPORT TQTextCommand
+{
+public:
+ enum Commands { Invalid, Insert, Delete, Format, Style };
+
+ TQTextCommand( TQTextDocument *d ) : doc( d ), cursor( d ) {}
+ virtual ~TQTextCommand();
+
+ virtual Commands type() const;
+
+ virtual TQTextCursor *execute( TQTextCursor *c ) = 0;
+ virtual TQTextCursor *unexecute( TQTextCursor *c ) = 0;
+
+protected:
+ TQTextDocument *doc;
+ TQTextCursor cursor;
+
+};
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrList<TQTextCommand>;
+// TQMOC_SKIP_END
+#endif
+
+class TQ_EXPORT TQTextCommandHistory
+{
+public:
+ TQTextCommandHistory( int s ) : current( -1 ), steps( s ) { history.setAutoDelete( TRUE ); }
+ virtual ~TQTextCommandHistory();
+
+ void clear() { history.clear(); current = -1; }
+
+ void addCommand( TQTextCommand *cmd );
+ TQTextCursor *undo( TQTextCursor *c );
+ TQTextCursor *redo( TQTextCursor *c );
+
+ bool isUndoAvailable();
+ bool isRedoAvailable();
+
+ void setUndoDepth( int d ) { steps = d; }
+ int undoDepth() const { return steps; }
+
+ int historySize() const { return history.count(); }
+ int currentPosition() const { return current; }
+
+private:
+ TQPtrList<TQTextCommand> history;
+ int current, steps;
+
+};
+
+inline TQTextCommandHistory::~TQTextCommandHistory()
+{
+ clear();
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+class TQ_EXPORT TQTextCustomItem
+{
+public:
+ TQTextCustomItem( TQTextDocument *p )
+ : xpos(0), ypos(-1), width(-1), height(0), tqparent( p )
+ {}
+ virtual ~TQTextCustomItem();
+ virtual void draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected ) = 0;
+
+ virtual void adjustToPainter( TQPainter* );
+
+ enum Placement { PlaceInline = 0, PlaceLeft, PlaceRight };
+ virtual Placement placement() const;
+ bool placeInline() { return placement() == PlaceInline; }
+
+ virtual bool ownLine() const;
+ virtual void resize( int nwidth );
+ virtual void tqinvalidate();
+ virtual int ascent() const { return height; }
+
+ virtual bool isNested() const;
+ virtual int minimumWidth() const;
+
+ virtual TQString richText() const;
+
+ int xpos; // used for floating items
+ int ypos; // used for floating items
+ int width;
+ int height;
+
+ TQRect tqgeometry() const { return TQRect( xpos, ypos, width, height ); }
+
+ virtual bool enter( TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd = FALSE );
+ virtual bool enterAt( TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, const TQPoint & );
+ virtual bool next( TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy );
+ virtual bool prev( TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy );
+ virtual bool down( TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy );
+ virtual bool up( TQTextCursor *, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy );
+
+ virtual void setParagraph( TQTextParagraph *p ) { parag = p; }
+ TQTextParagraph *paragraph() const { return parag; }
+
+ TQTextDocument *tqparent;
+ TQTextParagraph *parag;
+
+ virtual void pageBreak( int y, TQTextFlow* flow );
+};
+#endif
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+//TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<TQString, TQString>;
+// TQMOC_SKIP_END
+#endif
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+class TQ_EXPORT TQTextImage : public TQTextCustomItem
+{
+public:
+ TQTextImage( TQTextDocument *p, const QMap<TQString, TQString> &attr, const TQString& context,
+ TQMimeSourceFactory &factory );
+ virtual ~TQTextImage();
+
+ Placement placement() const { return place; }
+ void adjustToPainter( TQPainter* );
+ int minimumWidth() const { return width; }
+
+ TQString richText() const;
+
+ void draw( TQPainter* p, int x, int y, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected );
+
+private:
+ TQRegion* reg;
+ TQPixmap pm;
+ Placement place;
+ int tmpwidth, tmpheight;
+ TQMap<TQString, TQString> attributes;
+ TQString imgId;
+
+};
+#endif
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+class TQ_EXPORT TQTextHorizontalLine : public TQTextCustomItem
+{
+public:
+ TQTextHorizontalLine( TQTextDocument *p, const TQMap<TQString, TQString> &attr, const TQString& context,
+ TQMimeSourceFactory &factory );
+ virtual ~TQTextHorizontalLine();
+
+ void adjustToPainter( TQPainter* );
+ void draw(TQPainter* p, int x, int y, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected );
+ TQString richText() const;
+
+ bool ownLine() const { return TRUE; }
+
+private:
+ int tmpheight;
+ TQColor color;
+ bool shade;
+
+};
+#endif
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrList<TQTextCustomItem>;
+// TQMOC_SKIP_END
+#endif
+#endif
+
+class TQ_EXPORT TQTextFlow
+{
+ friend class TQTextDocument;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ friend class TQTextTableCell;
+#endif
+
+public:
+ TQTextFlow();
+ virtual ~TQTextFlow();
+
+ virtual void setWidth( int width );
+ int width() const;
+
+ virtual void setPageSize( int ps );
+ int pageSize() const { return pagesize; }
+
+ virtual int adjustLMargin( int yp, int h, int margin, int space );
+ virtual int adjustRMargin( int yp, int h, int margin, int space );
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ virtual void registerFloatingItem( TQTextCustomItem* item );
+ virtual void unregisterFloatingItem( TQTextCustomItem* item );
+#endif
+ virtual TQRect boundingRect() const;
+ virtual void drawFloatingItems(TQPainter* p, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected );
+
+ virtual int adjustFlow( int y, int w, int h ); // adjusts y according to the defined pagesize. Returns the shift.
+
+ virtual bool isEmpty();
+
+ void clear();
+
+private:
+ int w;
+ int pagesize;
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQPtrList<TQTextCustomItem> leftItems;
+ TQPtrList<TQTextCustomItem> rightItems;
+#endif
+};
+
+inline int TQTextFlow::width() const { return w; }
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+class TQTextTable;
+
+class TQ_EXPORT TQTextTableCell : public TQLayoutItem
+{
+ friend class TQTextTable;
+
+public:
+ TQTextTableCell( TQTextTable* table,
+ int row, int column,
+ const TQMap<TQString, TQString> &attr,
+ const TQStyleSheetItem* style,
+ const TQTextFormat& fmt, const TQString& context,
+ TQMimeSourceFactory &factory, TQStyleSheet *sheet, const TQString& doc );
+ virtual ~TQTextTableCell();
+
+ TQSize tqsizeHint() const ;
+ TQSize tqminimumSize() const ;
+ TQSize tqmaximumSize() const ;
+ TQ_SPExpandData expandingDirections() const;
+ bool isEmpty() const;
+ void setGeometry( const TQRect& ) ;
+ TQRect tqgeometry() const;
+
+ bool hasHeightForWidth() const;
+ int heightForWidth( int ) const;
+
+ void adjustToPainter( TQPainter* );
+
+ int row() const { return row_; }
+ int column() const { return col_; }
+ int rowspan() const { return rowspan_; }
+ int colspan() const { return colspan_; }
+ int stretch() const { return stretch_; }
+
+ TQTextDocument* richText() const { return richtext; }
+ TQTextTable* table() const { return tqparent; }
+
+ void draw( TQPainter* p, int x, int y, int cx, int cy, int cw, int ch, const TQColorGroup& cg, bool selected );
+
+ TQBrush *backGround() const { return background; }
+ virtual void tqinvalidate();
+
+ int verticalAlignmentOffset() const;
+ int horizontalAlignmentOffset() const;
+
+private:
+ TQRect geom;
+ TQTextTable* tqparent;
+ TQTextDocument* richtext;
+ int row_;
+ int col_;
+ int rowspan_;
+ int colspan_;
+ int stretch_;
+ int maxw;
+ int minw;
+ bool hasFixedWidth;
+ TQBrush *background;
+ int cached_width;
+ int cached_sizehint;
+ TQMap<TQString, TQString> attributes;
+ int align;
+};
+#endif
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrList<TQTextTableCell>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<TQTextCursor*, int>;
+// TQMOC_SKIP_END
+#endif
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+class TQ_EXPORT TQTextTable: public TQTextCustomItem
+{
+ friend class TQTextTableCell;
+
+public:
+ TQTextTable( TQTextDocument *p, const TQMap<TQString, TQString> &attr );
+ virtual ~TQTextTable();
+
+ void adjustToPainter( TQPainter *p );
+ void pageBreak( int y, TQTextFlow* flow );
+ void draw( TQPainter* p, int x, int y, int cx, int cy, int cw, int ch,
+ const TQColorGroup& cg, bool selected );
+
+ bool noErase() const { return TRUE; }
+ bool ownLine() const { return TRUE; }
+ Placement placement() const { return place; }
+ bool isNested() const { return TRUE; }
+ void resize( int nwidth );
+ virtual void tqinvalidate();
+
+ virtual bool enter( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, bool atEnd = FALSE );
+ virtual bool enterAt( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy, const TQPoint &pos );
+ virtual bool next( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy );
+ virtual bool prev( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy );
+ virtual bool down( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy );
+ virtual bool up( TQTextCursor *c, TQTextDocument *&doc, TQTextParagraph *&parag, int &idx, int &ox, int &oy );
+
+ TQString richText() const;
+
+ int minimumWidth() const;
+
+ TQPtrList<TQTextTableCell> tableCells() const { return cells; }
+
+ bool isStretching() const { return stretch; }
+ void setParagraph(TQTextParagraph *p);
+
+private:
+ void format( int w );
+ void addCell( TQTextTableCell* cell );
+
+private:
+ TQGridLayout* tqlayout;
+ TQPtrList<TQTextTableCell> cells;
+ int cachewidth;
+ int fixwidth;
+ int cellpadding;
+ int cellspacing;
+ int border;
+ int outerborder;
+ int stretch;
+ int innerborder;
+ int us_cp, us_ib, us_b, us_ob, us_cs;
+ int us_fixwidth;
+ TQMap<TQString, TQString> attributes;
+ TQMap<TQTextCursor*, int> currCell;
+ Placement place;
+ void adjustCells( int y , int shift );
+ int pageBreakFor;
+};
+#endif
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+class TQTextTableCell;
+class TQTextParagraph;
+#endif
+
+struct TQ_EXPORT TQTextDocumentSelection
+{
+ TQTextCursor startCursor, endCursor;
+ bool swapped;
+ TQ_DUMMY_COMPARISON_OPERATOR(TQTextDocumentSelection)
+};
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<int, TQColor>;
+//TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<int, bool>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<int, TQTextDocumentSelection>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrList<TQTextDocument>;
+// TQMOC_SKIP_END
+#endif
+
+class TQ_EXPORT TQTextDocument : public TQObject
+{
+ TQ_OBJECT
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ friend class TQTextTableCell;
+#endif
+ friend class TQTextCursor;
+ friend class TQTextEdit;
+ friend class TQTextParagraph;
+ friend class TQTextTable;
+
+public:
+ enum SelectionIds {
+ Standard = 0,
+ IMSelectionText = 31998,
+ IMCompositionText = 31999, // this must be higher!
+ Temp = 32000 // This selection must not be drawn, it's used e.g. by undo/redo to
+ // remove multiple lines with removeSelectedText()
+ };
+
+ TQTextDocument( TQTextDocument *p );
+ virtual ~TQTextDocument();
+
+ TQTextDocument *tqparent() const { return par; }
+ TQTextParagraph *parentParagraph() const { return parentPar; }
+
+ void setText( const TQString &text, const TQString &context );
+ TQMap<TQString, TQString> attributes() const { return attribs; }
+ void setAttributes( const TQMap<TQString, TQString> &attr ) { attribs = attr; }
+
+ TQString text() const;
+ TQString text( int parag ) const;
+ TQString originalText() const;
+
+ int x() const;
+ int y() const;
+ int width() const;
+ int widthUsed() const;
+ int visibleWidth() const;
+ int height() const;
+ void setWidth( int w );
+ int minimumWidth() const;
+ bool setMinimumWidth( int needed, int used = -1, TQTextParagraph *parag = 0 );
+
+ void setY( int y );
+ int leftMargin() const;
+ void setLeftMargin( int lm );
+ int rightMargin() const;
+ void setRightMargin( int rm );
+
+ TQTextParagraph *firstParagraph() const;
+ TQTextParagraph *lastParagraph() const;
+ void setFirstParagraph( TQTextParagraph *p );
+ void setLastParagraph( TQTextParagraph *p );
+
+ void tqinvalidate();
+
+ void setPreProcessor( TQTextPreProcessor *sh );
+ TQTextPreProcessor *preProcessor() const;
+
+ void setFormatter( TQTextFormatter *f );
+ TQTextFormatter *formatter() const;
+
+ void setIndent( TQTextIndent *i );
+ TQTextIndent *indent() const;
+
+ TQColor selectionColor( int id ) const;
+ bool invertSelectionText( int id ) const;
+ void setSelectionColor( int id, const TQColor &c );
+ void setInvertSelectionText( int id, bool b );
+ bool hasSelection( int id, bool visible = FALSE ) const;
+ void setSelectionStart( int id, const TQTextCursor &cursor );
+ bool setSelectionEnd( int id, const TQTextCursor &cursor );
+ void selectAll( int id );
+ bool removeSelection( int id );
+ void selectionStart( int id, int &paragId, int &index );
+ TQTextCursor selectionStartCursor( int id );
+ TQTextCursor selectionEndCursor( int id );
+ void selectionEnd( int id, int &paragId, int &index );
+ void setFormat( int id, TQTextFormat *f, int flags );
+ int numSelections() const { return nSelections; }
+ void addSelection( int id );
+
+ TQString selectedText( int id, bool asRichText = FALSE ) const;
+ void removeSelectedText( int id, TQTextCursor *cursor );
+ void indentSelection( int id );
+
+ TQTextParagraph *paragAt( int i ) const;
+
+ void addCommand( TQTextCommand *cmd );
+ TQTextCursor *undo( TQTextCursor *c = 0 );
+ TQTextCursor *redo( TQTextCursor *c = 0 );
+ TQTextCommandHistory *commands() const { return commandHistory; }
+
+ TQTextFormatCollection *formatCollection() const;
+
+ bool tqfind( TQTextCursor &cursor, const TQString &expr, bool cs, bool wo, bool forward);
+
+ void setTextFormat( TQt::TextFormat f );
+ TQt::TextFormat textFormat() const;
+
+ bool inSelection( int selId, const TQPoint &pos ) const;
+
+ TQStyleSheet *styleSheet() const { return sheet_; }
+#ifndef TQT_NO_MIME
+ TQMimeSourceFactory *mimeSourceFactory() const { return factory_; }
+#endif
+ TQString context() const { return contxt; }
+
+ void setStyleSheet( TQStyleSheet *s );
+ void setDefaultFormat( const TQFont &font, const TQColor &color );
+#ifndef TQT_NO_MIME
+ void setMimeSourceFactory( TQMimeSourceFactory *f ) { if ( f ) factory_ = f; }
+#endif
+ void setContext( const TQString &c ) { if ( !c.isEmpty() ) contxt = c; }
+
+ void setUnderlineLinks( bool b );
+ bool underlineLinks() const { return underlLinks; }
+
+ void setPaper( TQBrush *brush ) { if ( backBrush ) delete backBrush; backBrush = brush; }
+ TQBrush *paper() const { return backBrush; }
+
+ void doLayout( TQPainter *p, int w );
+ void draw( TQPainter *p, const TQRect& rect, const TQColorGroup &cg, const TQBrush *paper = 0 );
+ bool useDoubleBuffer( TQTextParagraph *parag, TQPainter *p );
+
+ void drawParagraph( TQPainter *p, TQTextParagraph *parag, int cx, int cy, int cw, int ch,
+ TQPixmap *&doubleBuffer, const TQColorGroup &cg,
+ bool drawCursor, TQTextCursor *cursor, bool resetChanged = TRUE );
+ TQTextParagraph *draw( TQPainter *p, int cx, int cy, int cw, int ch, const TQColorGroup &cg,
+ bool onlyChanged = FALSE, bool drawCursor = FALSE, TQTextCursor *cursor = 0,
+ bool resetChanged = TRUE );
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ void registerCustomItem( TQTextCustomItem *i, TQTextParagraph *p );
+ void unregisterCustomItem( TQTextCustomItem *i, TQTextParagraph *p );
+#endif
+
+ void setFlow( TQTextFlow *f );
+ void takeFlow();
+ TQTextFlow *flow() const { return flow_; }
+ bool isPageBreakEnabled() const { return pages; }
+ void setPageBreakEnabled( bool b ) { pages = b; }
+
+ void setUseFormatCollection( bool b ) { useFC = b; }
+ bool useFormatCollection() const { return useFC; }
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQTextTableCell *tableCell() const { return tc; }
+ void setTableCell( TQTextTableCell *c ) { tc = c; }
+#endif
+
+ void setPlainText( const TQString &text );
+ void setRichText( const TQString &text, const TQString &context, const TQTextFormat *initialFormat = 0 );
+ TQString richText() const;
+ TQString plainText() const;
+
+ bool focusNextPrevChild( bool next );
+
+ int tqalignment() const;
+ void tqsetAlignment( int a );
+
+ int *tabArray() const;
+ int tabStopWidth() const;
+ void setTabArray( int *a );
+ void setTabStops( int tw );
+
+ void setUndoDepth( int d ) { commandHistory->setUndoDepth( d ); }
+ int undoDepth() const { return commandHistory->undoDepth(); }
+
+ int length() const;
+ void clear( bool createEmptyParag = FALSE );
+
+ virtual TQTextParagraph *createParagraph( TQTextDocument *d, TQTextParagraph *pr = 0, TQTextParagraph *nx = 0, bool updateIds = TRUE );
+ void insertChild( TQObject *o ) { TQObject::insertChild( o ); }
+ void removeChild( TQObject *o ) { TQObject::removeChild( o ); }
+ void insertChild( TQTextDocument *d ) { childList.append( d ); }
+ void removeChild( TQTextDocument *d ) { childList.removeRef( d ); }
+ TQPtrList<TQTextDocument> childrenListObject() const { return childList; }
+
+ bool hasFocusParagraph() const;
+ TQString focusHref() const;
+ TQString focusName() const;
+
+ void invalidateOriginalText() { oTextValid = FALSE; oText = ""; }
+
+Q_SIGNALS:
+ void minimumWidthChanged( int );
+
+private:
+ void init();
+ TQPixmap *bufferPixmap( const TQSize &s );
+ // HTML parser
+ bool hasPrefix(const TQChar* doc, int length, int pos, TQChar c);
+ bool hasPrefix(const TQChar* doc, int length, int pos, const TQString& s);
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQTextCustomItem* parseTable( const TQMap<TQString, TQString> &attr, const TQTextFormat &fmt,
+ const TQChar* doc, int length, int& pos, TQTextParagraph *curpar );
+#endif
+ bool eatSpace(const TQChar* doc, int length, int& pos, bool includeNbsp = FALSE );
+ bool eat(const TQChar* doc, int length, int& pos, TQChar c);
+ TQString parseOpenTag(const TQChar* doc, int length, int& pos, TQMap<TQString, TQString> &attr, bool& emptyTag);
+ TQString parseCloseTag( const TQChar* doc, int length, int& pos );
+ TQChar parseHTMLSpecialChar(const TQChar* doc, int length, int& pos);
+ TQString parseWord(const TQChar* doc, int length, int& pos, bool lower = TRUE);
+ TQChar parseChar(const TQChar* doc, int length, int& pos, TQStyleSheetItem::WhiteSpaceMode wsm );
+ void setRichTextInternal( const TQString &text, TQTextCursor* cursor = 0, const TQTextFormat *initialFormat = 0 );
+ void setRichTextMarginsInternal( TQPtrList< TQPtrVector<TQStyleSheetItem> >& styles, TQTextParagraph* stylesPar );
+
+private:
+ struct TQ_EXPORT Focus {
+ TQTextParagraph *parag;
+ int start, len;
+ TQString href;
+ TQString name;
+ };
+
+ int cx, cy, cw, vw;
+ TQTextParagraph *fParag, *lParag;
+ TQTextPreProcessor *pProcessor;
+ TQMap<int, TQColor> selectionColors;
+ TQMap<int, TQTextDocumentSelection> selections;
+ TQMap<int, bool> selectionText;
+ TQTextCommandHistory *commandHistory;
+ TQTextFormatter *pFormatter;
+ TQTextIndent *indenter;
+ TQTextFormatCollection *fCollection;
+ TQt::TextFormat txtFormat;
+ uint preferRichText : 1;
+ uint pages : 1;
+ uint useFC : 1;
+ uint withoutDoubleBuffer : 1;
+ uint underlLinks : 1;
+ uint nextDoubleBuffered : 1;
+ uint oTextValid : 1;
+ uint mightHaveCustomItems : 1;
+ int align;
+ int nSelections;
+ TQTextFlow *flow_;
+ TQTextDocument *par;
+ TQTextParagraph *parentPar;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQTextTableCell *tc;
+#endif
+ TQBrush *backBrush;
+ TQPixmap *buf_pixmap;
+ Focus focusIndicator;
+ int minw;
+ int wused;
+ int leftmargin;
+ int rightmargin;
+ TQTextParagraph *minwParag, *curParag;
+ TQStyleSheet* sheet_;
+#ifndef TQT_NO_MIME
+ TQMimeSourceFactory* factory_;
+#endif
+ TQString contxt;
+ TQMap<TQString, TQString> attribs;
+ int *tArray;
+ int tStopWidth;
+ int uDepth;
+ TQString oText;
+ TQPtrList<TQTextDocument> childList;
+ TQColor linkColor, bodyText;
+ double scaleFontsFactor;
+
+ short list_tm,list_bm, list_lm, li_tm, li_bm, par_tm, par_bm;
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQTextDocument( const TQTextDocument & );
+ TQTextDocument &operator=( const TQTextDocument & );
+#endif
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+
+class TQ_EXPORT TQTextDeleteCommand : public TQTextCommand
+{
+public:
+ TQTextDeleteCommand( TQTextDocument *d, int i, int idx, const TQMemArray<TQTextStringChar> &str,
+ const TQByteArray& oldStyle );
+ TQTextDeleteCommand( TQTextParagraph *p, int idx, const TQMemArray<TQTextStringChar> &str );
+ virtual ~TQTextDeleteCommand();
+
+ Commands type() const { return Delete; }
+ TQTextCursor *execute( TQTextCursor *c );
+ TQTextCursor *unexecute( TQTextCursor *c );
+
+protected:
+ int id, index;
+ TQTextParagraph *parag;
+ TQMemArray<TQTextStringChar> text;
+ TQByteArray styleInformation;
+
+};
+
+class TQ_EXPORT TQTextInsertCommand : public TQTextDeleteCommand
+{
+public:
+ TQTextInsertCommand( TQTextDocument *d, int i, int idx, const TQMemArray<TQTextStringChar> &str,
+ const TQByteArray& oldStyleInfo )
+ : TQTextDeleteCommand( d, i, idx, str, oldStyleInfo ) {}
+ TQTextInsertCommand( TQTextParagraph *p, int idx, const TQMemArray<TQTextStringChar> &str )
+ : TQTextDeleteCommand( p, idx, str ) {}
+ virtual ~TQTextInsertCommand() {}
+
+ Commands type() const { return Insert; }
+ TQTextCursor *execute( TQTextCursor *c ) { return TQTextDeleteCommand::unexecute( c ); }
+ TQTextCursor *unexecute( TQTextCursor *c ) { return TQTextDeleteCommand::execute( c ); }
+
+};
+
+class TQ_EXPORT TQTextFormatCommand : public TQTextCommand
+{
+public:
+ TQTextFormatCommand( TQTextDocument *d, int sid, int sidx, int eid, int eidx, const TQMemArray<TQTextStringChar> &old, TQTextFormat *f, int fl );
+ virtual ~TQTextFormatCommand();
+
+ Commands type() const { return Format; }
+ TQTextCursor *execute( TQTextCursor *c );
+ TQTextCursor *unexecute( TQTextCursor *c );
+
+protected:
+ int startId, startIndex, endId, endIndex;
+ TQTextFormat *format;
+ TQMemArray<TQTextStringChar> oldFormats;
+ int flags;
+
+};
+
+class TQ_EXPORT TQTextStyleCommand : public TQTextCommand
+{
+public:
+ TQTextStyleCommand( TQTextDocument *d, int fParag, int lParag, const TQByteArray& beforeChange );
+ virtual ~TQTextStyleCommand() {}
+
+ Commands type() const { return Style; }
+ TQTextCursor *execute( TQTextCursor *c );
+ TQTextCursor *unexecute( TQTextCursor *c );
+
+ static TQByteArray readStyleInformation( TQTextDocument* d, int fParag, int lParag );
+ static void writeStyleInformation( TQTextDocument* d, int fParag, const TQByteArray& style );
+
+private:
+ int firstParag, lastParag;
+ TQByteArray before;
+ TQByteArray after;
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+struct TQ_EXPORT TQTextParagraphSelection
+{
+ TQTextParagraphSelection() : start(0), end(0) { }
+ int start, end;
+ TQ_DUMMY_COMPARISON_OPERATOR(TQTextParagraphSelection)
+};
+
+struct TQ_EXPORT TQTextLineStart
+{
+ TQTextLineStart() : y( 0 ), baseLine( 0 ), h( 0 )
+ { }
+ TQTextLineStart( int y_, int bl, int h_ ) : y( y_ ), baseLine( bl ), h( h_ ),
+ w( 0 )
+ { }
+
+public:
+ int y, baseLine, h;
+ int w;
+};
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<int, TQTextParagraphSelection>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<int, TQTextLineStart*>;
+// TQMOC_SKIP_END
+#endif
+
+class TQ_EXPORT TQTextParagraphData
+{
+public:
+ TQTextParagraphData() {}
+ virtual ~TQTextParagraphData();
+ virtual void join( TQTextParagraphData * );
+};
+
+class TQTextParagraphPseudoDocument;
+
+class TQSyntaxHighlighter;
+
+class TQ_EXPORT TQTextParagraph
+{
+ friend class TQTextDocument;
+ friend class TQTextCursor;
+ friend class TQSyntaxHighlighter;
+
+public:
+ TQTextParagraph( TQTextDocument *d, TQTextParagraph *pr = 0, TQTextParagraph *nx = 0, bool updateIds = TRUE );
+ ~TQTextParagraph();
+
+ TQTextString *string() const;
+ TQTextStringChar *at( int i ) const; // maybe remove later
+ int leftGap() const;
+ int length() const; // maybe remove later
+
+ void setListStyle( TQStyleSheetItem::ListStyle ls ) { lstyle = ls; changed = TRUE; }
+ TQStyleSheetItem::ListStyle listStyle() const { return (TQStyleSheetItem::ListStyle)lstyle; }
+ void setListItem( bool li );
+ bool isListItem() const { return litem; }
+ void setListValue( int v ) { list_val = v; }
+ int listValue() const { return list_val > 0 ? list_val : -1; }
+
+ void setListDepth( int depth );
+ int listDepth() const { return ldepth; }
+
+// void setFormat( TQTextFormat *fm );
+// TQTextFormat *paragFormat() const;
+
+ inline TQTextDocument *document() const {
+ if (hasdoc) return (TQTextDocument*) docOrPseudo;
+ return 0;
+ }
+ TQTextParagraphPseudoDocument *pseudoDocument() const;
+
+ TQRect rect() const;
+ void setHeight( int h ) { r.setHeight( h ); }
+ void show();
+ void hide();
+ bool isVisible() const { return visible; }
+
+ TQTextParagraph *prev() const;
+ TQTextParagraph *next() const;
+ void setPrev( TQTextParagraph *s );
+ void setNext( TQTextParagraph *s );
+
+ void insert( int index, const QString &s );
+ void insert( int index, const QChar *tqunicode, int len );
+ void append( const TQString &s, bool reallyAtEnd = FALSE );
+ void truncate( int index );
+ void remove( int index, int len );
+ void join( TQTextParagraph *s );
+
+ void tqinvalidate( int chr );
+
+ void move( int &dy );
+ void format( int start = -1, bool doMove = TRUE );
+
+ bool isValid() const;
+ bool hasChanged() const;
+ void setChanged( bool b, bool recursive = FALSE );
+
+ int lineHeightOfChar( int i, int *bl = 0, int *y = 0 ) const;
+ TQTextStringChar *lineStartOfChar( int i, int *index = 0, int *line = 0 ) const;
+ int lines() const;
+ TQTextStringChar *lineStartOfLine( int line, int *index = 0 ) const;
+ int lineY( int l ) const;
+ int lineBaseLine( int l ) const;
+ int lineHeight( int l ) const;
+ void lineInfo( int l, int &y, int &h, int &bl ) const;
+
+ void setSelection( int id, int start, int end );
+ void removeSelection( int id );
+ int selectionStart( int id ) const;
+ int selectionEnd( int id ) const;
+ bool hasSelection( int id ) const;
+ bool hasAnySelection() const;
+ bool fullSelected( int id ) const;
+
+ void setEndState( int s );
+ int endState() const;
+
+ void setParagId( int i );
+ int paragId() const;
+
+ bool firstPreProcess() const;
+ void setFirstPreProcess( bool b );
+
+ void indent( int *oldIndent = 0, int *newIndent = 0 );
+
+ void setExtraData( TQTextParagraphData *data );
+ TQTextParagraphData *extraData() const;
+
+ TQMap<int, TQTextLineStart*> &lineStartList();
+
+ void setFormat( int index, int len, TQTextFormat *f, bool useCollection = TRUE, int flags = -1 );
+
+ void tqsetAlignment( int a );
+ int tqalignment() const;
+
+ void paint( TQPainter &painter, const TQColorGroup &cg, TQTextCursor *cursor = 0, bool drawSelections = FALSE,
+ int clipx = -1, int clipy = -1, int clipw = -1, int cliph = -1 );
+
+ int topMargin() const;
+ int bottomMargin() const;
+ int leftMargin() const;
+ int firstLineMargin() const;
+ int rightMargin() const;
+ int lineSpacing() const;
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ void registerFloatingItem( TQTextCustomItem *i );
+ void unregisterFloatingItem( TQTextCustomItem *i );
+#endif
+
+ void setFullWidth( bool b ) { fullWidth = b; }
+ bool isFullWidth() const { return fullWidth; }
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQTextTableCell *tableCell() const;
+#endif
+
+ TQBrush *background() const;
+
+ int documentWidth() const;
+ int documentVisibleWidth() const;
+ int documentX() const;
+ int documentY() const;
+ TQTextFormatCollection *formatCollection() const;
+ TQTextFormatter *formatter() const;
+
+ int nextTab( int i, int x );
+ int *tabArray() const;
+ void setTabArray( int *a );
+ void setTabStops( int tw );
+
+ void adjustToPainter( TQPainter *p );
+
+ void setNewLinesAllowed( bool b );
+ bool isNewLinesAllowed() const;
+
+ TQString richText() const;
+
+ void addCommand( TQTextCommand *cmd );
+ TQTextCursor *undo( TQTextCursor *c = 0 );
+ TQTextCursor *redo( TQTextCursor *c = 0 );
+ TQTextCommandHistory *commands() const;
+ void copyParagData( TQTextParagraph *parag );
+
+ void setBreakable( bool b ) { breakable = b; }
+ bool isBreakable() const { return breakable; }
+
+ void setBackgroundColor( const TQColor &c );
+ TQColor *backgroundColor() const { return bgcol; }
+ void clearBackgroundColor();
+
+ void setMovedDown( bool b ) { movedDown = b; }
+ bool wasMovedDown() const { return movedDown; }
+
+ void setDirection( TQChar::Direction d );
+ TQChar::Direction direction() const;
+ void setPaintDevice( TQPaintDevice *pd ) { painttqdevice = pd; }
+
+ void readStyleInformation( TQDataStream& stream );
+ void writeStyleInformation( TQDataStream& stream ) const;
+
+protected:
+ void setColorForSelection( TQColor &c, TQPainter &p, const TQColorGroup& cg, int selection );
+ void drawLabel( TQPainter* p, int x, int y, int w, int h, int base, const TQColorGroup& cg );
+ void drawString( TQPainter &painter, const TQString &str, int start, int len, int xstart,
+ int y, int baseLine, int w, int h, bool drawSelections, int fullSelectionWidth,
+ TQTextStringChar *formatChar, const TQColorGroup& cg,
+ bool rightToLeft );
+
+private:
+ TQMap<int, TQTextParagraphSelection> &selections() const;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQPtrList<TQTextCustomItem> &floatingItems() const;
+#endif
+ TQBrush backgroundBrush( const TQColorGroup&cg ) { if ( bgcol ) return *bgcol; return cg.brush( TQColorGroup::Base ); }
+ void invalidateStyleCache();
+
+ TQMap<int, TQTextLineStart*> lineStarts;
+ TQRect r;
+ TQTextParagraph *p, *n;
+ void *docOrPseudo;
+ uint changed : 1;
+ uint firstFormat : 1;
+ uint firstPProcess : 1;
+ uint needPreProcess : 1;
+ uint fullWidth : 1;
+ uint lastInFrame : 1;
+ uint visible : 1;
+ uint breakable : 1;
+ uint movedDown : 1;
+ uint mightHaveCustomItems : 1;
+ uint hasdoc : 1;
+ uint litem : 1; // whether the paragraph is a list item
+ uint rtext : 1; // whether the paragraph needs rich text margin
+ int align : 4;
+ uint /*TQStyleSheetItem::ListStyle*/ lstyle : 4;
+ int invalid;
+ int state, id;
+ TQTextString *str;
+ TQMap<int, TQTextParagraphSelection> *mSelections;
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ TQPtrList<TQTextCustomItem> *mFloatingItems;
+#endif
+ short utm, ubm, ulm, urm, uflm, ulinespacing;
+ short tabStopWidth;
+ int minwidth;
+ int *tArray;
+ TQTextParagraphData *eData;
+ short list_val;
+ ushort ldepth;
+ TQColor *bgcol;
+ TQPaintDevice *painttqdevice;
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class TQ_EXPORT TQTextFormatter
+{
+public:
+ TQTextFormatter();
+ virtual ~TQTextFormatter();
+
+ virtual int format( TQTextDocument *doc, TQTextParagraph *parag, int start, const TQMap<int, TQTextLineStart*> &oldLineStarts ) = 0;
+ virtual int formatVertically( TQTextDocument* doc, TQTextParagraph* parag );
+
+ bool isWrapEnabled( TQTextParagraph *p ) const { if ( !wrapEnabled ) return FALSE; if ( p && !p->isBreakable() ) return FALSE; return TRUE;}
+ int wrapAtColumn() const { return wrapColumn;}
+ virtual void setWrapEnabled( bool b );
+ virtual void setWrapAtColumn( int c );
+ virtual void setAllowBreakInWords( bool b ) { biw = b; }
+ bool allowBreakInWords() const { return biw; }
+
+ int minimumWidth() const { return thisminw; }
+ int widthUsed() const { return thiswused; }
+
+protected:
+ virtual TQTextLineStart *formatLine( TQTextParagraph *parag, TQTextString *string, TQTextLineStart *line, TQTextStringChar *start,
+ TQTextStringChar *last, int align = TQt::AlignAuto, int space = 0 );
+#ifndef TQT_NO_COMPLEXTEXT
+ virtual TQTextLineStart *bidiReorderLine( TQTextParagraph *parag, TQTextString *string, TQTextLineStart *line, TQTextStringChar *start,
+ TQTextStringChar *last, int align, int space );
+#endif
+ void insertLineStart( TQTextParagraph *parag, int index, TQTextLineStart *ls );
+
+ int thisminw;
+ int thiswused;
+
+private:
+ bool wrapEnabled;
+ int wrapColumn;
+ bool biw;
+
+#ifdef HAVE_THAI_BREAKS
+ static TQCString *thaiCache;
+ static TQTextString *cachedString;
+ static ThBreakIterator *thaiIt;
+#endif
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class TQ_EXPORT TQTextFormatterBreakInWords : public TQTextFormatter
+{
+public:
+ TQTextFormatterBreakInWords();
+ virtual ~TQTextFormatterBreakInWords() {}
+
+ int format( TQTextDocument *doc, TQTextParagraph *parag, int start, const TQMap<int, TQTextLineStart*> &oldLineStarts );
+
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class TQ_EXPORT TQTextFormatterBreakWords : public TQTextFormatter
+{
+public:
+ TQTextFormatterBreakWords();
+ virtual ~TQTextFormatterBreakWords() {}
+
+ int format( TQTextDocument *doc, TQTextParagraph *parag, int start, const TQMap<int, TQTextLineStart*> &oldLineStarts );
+
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class TQ_EXPORT TQTextIndent
+{
+public:
+ TQTextIndent();
+ virtual ~TQTextIndent() {}
+
+ virtual void indent( TQTextDocument *doc, TQTextParagraph *parag, int *oldIndent = 0, int *newIndent = 0 ) = 0;
+
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class TQ_EXPORT TQTextPreProcessor
+{
+public:
+ enum Ids {
+ Standard = 0
+ };
+
+ TQTextPreProcessor();
+ virtual ~TQTextPreProcessor() {}
+
+ virtual void process( TQTextDocument *doc, TQTextParagraph *, int, bool = TRUE ) = 0;
+ virtual TQTextFormat *format( int id ) = 0;
+
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+class TQ_EXPORT TQTextFormat
+{
+ friend class TQTextFormatCollection;
+ friend class TQTextDocument;
+
+public:
+ enum Flags {
+ NoFlags,
+ Bold = 1,
+ Italic = 2,
+ Underline = 4,
+ Family = 8,
+ Size = 16,
+ Color = 32,
+ Misspelled = 64,
+ VAlign = 128,
+ StrikeOut= 256,
+ Font = Bold | Italic | Underline | Family | Size | StrikeOut,
+ Format = Font | Color | Misspelled | VAlign
+ };
+
+ enum VerticalAlignment { AlignNormal, AlignSuperScript, AlignSubScript };
+
+ TQTextFormat();
+ virtual ~TQTextFormat();
+
+ TQTextFormat( const TQStyleSheetItem *s );
+ TQTextFormat( const TQFont &f, const TQColor &c, TQTextFormatCollection *tqparent = 0 );
+ TQTextFormat( const TQTextFormat &fm );
+ TQTextFormat makeTextFormat( const TQStyleSheetItem *style, const TQMap<TQString,TQString>& attr, double scaleFontsFactor ) const;
+ TQTextFormat& operator=( const TQTextFormat &fm );
+ TQColor color() const;
+ TQFont font() const;
+ TQFontMetrics fontMetrics() const { return fm; }
+ bool isMisspelled() const;
+ VerticalAlignment vAlign() const;
+ int minLeftBearing() const;
+ int minRightBearing() const;
+ int width( const TQChar &c ) const;
+ int width( const TQString &str, int pos ) const;
+ int height() const;
+ int ascent() const;
+ int descent() const;
+ int leading() const;
+ bool useLinkColor() const;
+
+ void setBold( bool b );
+ void setItalic( bool b );
+ void setUnderline( bool b );
+ void setStrikeOut( bool b );
+ void setFamily( const TQString &f );
+ void setPointSize( int s );
+ void setFont( const TQFont &f );
+ void setColor( const TQColor &c );
+ void setMisspelled( bool b );
+ void setVAlign( VerticalAlignment a );
+
+ bool operator==( const TQTextFormat &f ) const;
+ TQTextFormatCollection *tqparent() const;
+ const TQString &key() const;
+
+ static TQString getKey( const TQFont &f, const TQColor &c, bool misspelled, VerticalAlignment vAlign );
+
+ void addRef();
+ void removeRef();
+
+ TQString makeFormatChangeTags( TQTextFormat* defaultFormat, TQTextFormat *f, const TQString& oldAnchorHref, const TQString& anchorHref ) const;
+ TQString makeFormatEndTags( TQTextFormat* defaultFormat, const TQString& anchorHref ) const;
+
+ static void setPainter( TQPainter *p );
+ static TQPainter* painter();
+
+ bool fontSizesInPixels() { return usePixelSizes; }
+
+protected:
+ virtual void generateKey();
+
+private:
+ void update();
+ static void applyFont( const TQFont &f );
+
+private:
+ TQFont fn;
+ TQColor col;
+ TQFontMetrics fm;
+ uint missp : 1;
+ uint linkColor : 1;
+ uint usePixelSizes : 1;
+ int leftBearing, rightBearing;
+ VerticalAlignment ha;
+ uchar widths[ 256 ];
+ int hei, asc, dsc;
+ TQTextFormatCollection *collection;
+ int ref;
+ TQString k;
+ int logicalFontSize;
+ int stdSize;
+ static TQPainter *pntr;
+ static TQFontMetrics *pntr_fm;
+ static int pntr_asc;
+ static int pntr_hei;
+ static int pntr_ldg;
+ static int pntr_dsc;
+
+};
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQDict<TQTextFormat>;
+// TQMOC_SKIP_END
+#endif
+
+class TQ_EXPORT TQTextFormatCollection
+{
+ friend class TQTextDocument;
+ friend class TQTextFormat;
+
+public:
+ TQTextFormatCollection();
+ virtual ~TQTextFormatCollection();
+
+ void setDefaultFormat( TQTextFormat *f );
+ TQTextFormat *defaultFormat() const;
+ virtual TQTextFormat *format( TQTextFormat *f );
+ virtual TQTextFormat *format( TQTextFormat *of, TQTextFormat *nf, int flags );
+ virtual TQTextFormat *format( const TQFont &f, const TQColor &c );
+ virtual void remove( TQTextFormat *f );
+ virtual TQTextFormat *createFormat( const TQTextFormat &f ) { return new TQTextFormat( f ); }
+ virtual TQTextFormat *createFormat( const TQFont &f, const TQColor &c ) { return new TQTextFormat( f, c, this ); }
+
+ void updateDefaultFormat( const TQFont &font, const TQColor &c, TQStyleSheet *sheet );
+
+ TQPaintDevice *paintDevice() const { return painttqdevice; }
+ void setPaintDevice( TQPaintDevice * );
+
+private:
+ void updateKeys();
+
+private:
+ TQTextFormat *defFormat, *lastFormat, *cachedFormat;
+ TQDict<TQTextFormat> cKey;
+ TQTextFormat *cres;
+ TQFont cfont;
+ TQColor ccol;
+ TQString kof, knf;
+ int cflags;
+
+ TQPaintDevice *painttqdevice;
+};
+
+class TQ_EXPORT TQTextParagraphPseudoDocument
+{
+public:
+ TQTextParagraphPseudoDocument();
+ ~TQTextParagraphPseudoDocument();
+ TQRect docRect;
+ TQTextFormatter *pFormatter;
+ TQTextCommandHistory *commandHistory;
+ int minw;
+ int wused;
+ TQTextFormatCollection collection;
+};
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+inline int TQTextParagraph::length() const
+{
+ return str->length();
+}
+
+inline TQRect TQTextParagraph::rect() const
+{
+ return r;
+}
+
+inline int TQTextCursor::index() const
+{
+ return idx;
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+inline int TQTextDocument::x() const
+{
+ return cx;
+}
+
+inline int TQTextDocument::y() const
+{
+ return cy;
+}
+
+inline int TQTextDocument::width() const
+{
+ return TQMAX( cw, flow_->width() );
+}
+
+inline int TQTextDocument::visibleWidth() const
+{
+ return vw;
+}
+
+inline TQTextParagraph *TQTextDocument::firstParagraph() const
+{
+ return fParag;
+}
+
+inline TQTextParagraph *TQTextDocument::lastParagraph() const
+{
+ return lParag;
+}
+
+inline void TQTextDocument::setFirstParagraph( TQTextParagraph *p )
+{
+ fParag = p;
+}
+
+inline void TQTextDocument::setLastParagraph( TQTextParagraph *p )
+{
+ lParag = p;
+}
+
+inline void TQTextDocument::setWidth( int w )
+{
+ cw = TQMAX( w, minw );
+ flow_->setWidth( cw );
+ vw = w;
+}
+
+inline int TQTextDocument::minimumWidth() const
+{
+ return minw;
+}
+
+inline void TQTextDocument::setY( int y )
+{
+ cy = y;
+}
+
+inline int TQTextDocument::leftMargin() const
+{
+ return leftmargin;
+}
+
+inline void TQTextDocument::setLeftMargin( int lm )
+{
+ leftmargin = lm;
+}
+
+inline int TQTextDocument::rightMargin() const
+{
+ return rightmargin;
+}
+
+inline void TQTextDocument::setRightMargin( int rm )
+{
+ rightmargin = rm;
+}
+
+inline TQTextPreProcessor *TQTextDocument::preProcessor() const
+{
+ return pProcessor;
+}
+
+inline void TQTextDocument::setPreProcessor( TQTextPreProcessor * sh )
+{
+ pProcessor = sh;
+}
+
+inline void TQTextDocument::setFormatter( TQTextFormatter *f )
+{
+ delete pFormatter;
+ pFormatter = f;
+}
+
+inline TQTextFormatter *TQTextDocument::formatter() const
+{
+ return pFormatter;
+}
+
+inline void TQTextDocument::setIndent( TQTextIndent *i )
+{
+ indenter = i;
+}
+
+inline TQTextIndent *TQTextDocument::indent() const
+{
+ return indenter;
+}
+
+inline TQColor TQTextDocument::selectionColor( int id ) const
+{
+ return selectionColors[ id ];
+}
+
+inline bool TQTextDocument::invertSelectionText( int id ) const
+{
+ return selectionText[ id ];
+}
+
+inline void TQTextDocument::setSelectionColor( int id, const TQColor &c )
+{
+ selectionColors[ id ] = c;
+}
+
+inline void TQTextDocument::setInvertSelectionText( int id, bool b )
+{
+ selectionText[ id ] = b;
+}
+
+inline TQTextFormatCollection *TQTextDocument::formatCollection() const
+{
+ return fCollection;
+}
+
+inline int TQTextDocument::tqalignment() const
+{
+ return align;
+}
+
+inline void TQTextDocument::tqsetAlignment( int a )
+{
+ align = a;
+}
+
+inline int *TQTextDocument::tabArray() const
+{
+ return tArray;
+}
+
+inline int TQTextDocument::tabStopWidth() const
+{
+ return tStopWidth;
+}
+
+inline void TQTextDocument::setTabArray( int *a )
+{
+ tArray = a;
+}
+
+inline void TQTextDocument::setTabStops( int tw )
+{
+ tStopWidth = tw;
+}
+
+inline TQString TQTextDocument::originalText() const
+{
+ if ( oTextValid )
+ return oText;
+ return text();
+}
+
+inline void TQTextDocument::setFlow( TQTextFlow *f )
+{
+ if ( flow_ )
+ delete flow_;
+ flow_ = f;
+}
+
+inline void TQTextDocument::takeFlow()
+{
+ flow_ = 0;
+}
+
+inline bool TQTextDocument::useDoubleBuffer( TQTextParagraph *parag, TQPainter *p )
+{
+ return ( !parag->document()->tqparent() || parag->document()->nextDoubleBuffered ) &&
+ ( !p || !p->tqdevice() || p->tqdevice()->devType() != TQInternal::Printer );
+}
+
+// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+inline TQColor TQTextFormat::color() const
+{
+ return col;
+}
+
+inline TQFont TQTextFormat::font() const
+{
+ return fn;
+}
+
+inline bool TQTextFormat::isMisspelled() const
+{
+ return missp;
+}
+
+inline TQTextFormat::VerticalAlignment TQTextFormat::vAlign() const
+{
+ return ha;
+}
+
+inline bool TQTextFormat::operator==( const TQTextFormat &f ) const
+{
+ return k == f.k;
+}
+
+inline TQTextFormatCollection *TQTextFormat::tqparent() const
+{
+ return collection;
+}
+
+inline void TQTextFormat::addRef()
+{
+ ref++;
+}
+
+inline void TQTextFormat::removeRef()
+{
+ ref--;
+ if ( !collection )
+ return;
+ if ( this == collection->defFormat )
+ return;
+ if ( ref == 0 )
+ collection->remove( this );
+}
+
+inline const TQString &TQTextFormat::key() const
+{
+ return k;
+}
+
+inline bool TQTextFormat::useLinkColor() const
+{
+ return linkColor;
+}
+
+inline TQTextStringChar *TQTextParagraph::at( int i ) const
+{
+ return &str->at( i );
+}
+
+inline bool TQTextParagraph::isValid() const
+{
+ return invalid == -1;
+}
+
+inline bool TQTextParagraph::hasChanged() const
+{
+ return changed;
+}
+
+inline void TQTextParagraph::setBackgroundColor( const TQColor & c )
+{
+ delete bgcol;
+ bgcol = new TQColor( c );
+ setChanged( TRUE );
+}
+
+inline void TQTextParagraph::clearBackgroundColor()
+{
+ delete bgcol; bgcol = 0; setChanged( TRUE );
+}
+
+inline void TQTextParagraph::append( const TQString &s, bool reallyAtEnd )
+{
+ if ( reallyAtEnd )
+ insert( str->length(), s );
+ else
+ insert( TQMAX( str->length() - 1, 0 ), s );
+}
+
+inline TQTextParagraph *TQTextParagraph::prev() const
+{
+ return p;
+}
+
+inline TQTextParagraph *TQTextParagraph::next() const
+{
+ return n;
+}
+
+inline bool TQTextParagraph::hasAnySelection() const
+{
+ return mSelections ? !selections().isEmpty() : FALSE;
+}
+
+inline void TQTextParagraph::setEndState( int s )
+{
+ if ( s == state )
+ return;
+ state = s;
+}
+
+inline int TQTextParagraph::endState() const
+{
+ return state;
+}
+
+inline void TQTextParagraph::setParagId( int i )
+{
+ id = i;
+}
+
+inline int TQTextParagraph::paragId() const
+{
+ if ( id == -1 )
+ qWarning( "invalid parag id!!!!!!!! (%p)", (void*)this );
+ return id;
+}
+
+inline bool TQTextParagraph::firstPreProcess() const
+{
+ return firstPProcess;
+}
+
+inline void TQTextParagraph::setFirstPreProcess( bool b )
+{
+ firstPProcess = b;
+}
+
+inline TQMap<int, TQTextLineStart*> &TQTextParagraph::lineStartList()
+{
+ return lineStarts;
+}
+
+inline TQTextString *TQTextParagraph::string() const
+{
+ return str;
+}
+
+inline TQTextParagraphPseudoDocument *TQTextParagraph::pseudoDocument() const
+{
+ if ( hasdoc )
+ return 0;
+ return (TQTextParagraphPseudoDocument*) docOrPseudo;
+}
+
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+inline TQTextTableCell *TQTextParagraph::tableCell() const
+{
+ return hasdoc ? document()->tableCell () : 0;
+}
+#endif
+
+inline TQTextCommandHistory *TQTextParagraph::commands() const
+{
+ return hasdoc ? document()->commands() : pseudoDocument()->commandHistory;
+}
+
+
+inline int TQTextParagraph::tqalignment() const
+{
+ return align;
+}
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+inline void TQTextParagraph::registerFloatingItem( TQTextCustomItem *i )
+{
+ floatingItems().append( i );
+}
+
+inline void TQTextParagraph::unregisterFloatingItem( TQTextCustomItem *i )
+{
+ floatingItems().removeRef( i );
+}
+#endif
+
+inline TQBrush *TQTextParagraph::background() const
+{
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ return tableCell() ? tableCell()->backGround() : 0;
+#else
+ return 0;
+#endif
+}
+
+inline int TQTextParagraph::documentWidth() const
+{
+ return hasdoc ? document()->width() : pseudoDocument()->docRect.width();
+}
+
+inline int TQTextParagraph::documentVisibleWidth() const
+{
+ return hasdoc ? document()->visibleWidth() : pseudoDocument()->docRect.width();
+}
+
+inline int TQTextParagraph::documentX() const
+{
+ return hasdoc ? document()->x() : pseudoDocument()->docRect.x();
+}
+
+inline int TQTextParagraph::documentY() const
+{
+ return hasdoc ? document()->y() : pseudoDocument()->docRect.y();
+}
+
+inline void TQTextParagraph::setExtraData( TQTextParagraphData *data )
+{
+ eData = data;
+}
+
+inline TQTextParagraphData *TQTextParagraph::extraData() const
+{
+ return eData;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+inline void TQTextFormatCollection::setDefaultFormat( TQTextFormat *f )
+{
+ defFormat = f;
+}
+
+inline TQTextFormat *TQTextFormatCollection::defaultFormat() const
+{
+ return defFormat;
+}
+
+// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+inline TQTextFormat *TQTextStringChar::format() const
+{
+ return (type == Regular) ? d.format : d.custom->format;
+}
+
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+inline TQTextCustomItem *TQTextStringChar::customItem() const
+{
+ return isCustom() ? d.custom->custom : 0;
+}
+#endif
+
+inline int TQTextStringChar::height() const
+{
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ return !isCustom() ? format()->height() : ( customItem()->placement() == TQTextCustomItem::PlaceInline ? customItem()->height : 0 );
+#else
+ return format()->height();
+#endif
+}
+
+inline int TQTextStringChar::ascent() const
+{
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ return !isCustom() ? format()->ascent() : ( customItem()->placement() == TQTextCustomItem::PlaceInline ? customItem()->ascent() : 0 );
+#else
+ return format()->ascent();
+#endif
+}
+
+inline int TQTextStringChar::descent() const
+{
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ return !isCustom() ? format()->descent() : 0;
+#else
+ return format()->descent();
+#endif
+}
+
+#endif //TQT_NO_RICHTEXT
+
+#endif
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqscriptengine.cpp b/tqtinterface/qt4/src/kernel/tqscriptengine.cpp
new file mode 100644
index 0000000..a45237f
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqscriptengine.cpp
@@ -0,0 +1,1630 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqscriptengine_p.h"
+
+#include "tqstring.h"
+#include "tqrect.h"
+#include "tqfont.h"
+#include <private/tqunicodetables_p.h>
+#include "tqtextengine_p.h"
+#include "tqfontengine_p.h"
+#include <stdlib.h>
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+#undef None
+#undef Pre
+#undef Above
+#undef Below
+
+const int Prealloc = 256;
+template<class T>
+class TQVarLengthArray
+{
+public:
+ inline explicit TQVarLengthArray(int size = 0);
+ inline ~TQVarLengthArray() {
+ if (ptr != reinterpret_cast<T *>(array))
+ free(ptr);
+ }
+
+ inline int size() const { return s; }
+ inline int count() const { return s; }
+ inline bool isEmpty() const { return (s == 0); }
+ inline void resize(int size);
+ inline void clear() { resize(0); }
+
+ inline int capacity() const { return a; }
+ inline void reserve(int size);
+
+ inline T &operator[](int idx) {
+ TQ_ASSERT(idx >= 0 && idx < s);
+ return ptr[idx];
+ }
+ inline const T &operator[](int idx) const {
+ TQ_ASSERT(idx >= 0 && idx < s);
+ return ptr[idx];
+ }
+
+ inline void append(const T &t) {
+ const int idx = s;
+ resize(idx + 1);
+ ptr[idx] = t;
+ }
+
+ inline T *data() { return ptr; }
+ inline const T *data() const { return ptr; }
+ inline const T * constData() const { return ptr; }
+
+private:
+ void realloc(int size, int alloc);
+
+ int a;
+ int s;
+ T *ptr;
+ TQ_UINT64 array[((Prealloc * sizeof(T)) / sizeof(TQ_UINT64)) + 1];
+};
+
+template <class T>
+TQ_INLINE_TEMPLATES TQVarLengthArray<T>::TQVarLengthArray(int asize)
+ : s(asize) {
+ if (s > Prealloc) {
+ ptr = reinterpret_cast<T *>(malloc(s * sizeof(T)));
+ a = s;
+ } else {
+ ptr = reinterpret_cast<T *>(array);
+ a = Prealloc;
+ }
+}
+
+
+// --------------------------------------------------------------------------------------------------------------------------------------------
+//
+// Basic processing
+//
+// --------------------------------------------------------------------------------------------------------------------------------------------
+
+static inline void positionCluster(TQShaperItem *item, int gfrom, int glast)
+{
+ int nmarks = glast - gfrom;
+ if (nmarks <= 0) {
+ qWarning("positionCluster: no marks to position!");
+ return;
+ }
+
+ TQFontEngine *f = item->font;
+
+ glyph_metrics_t baseInfo = f->boundingBox(item->glyphs[gfrom]);
+
+ if (item->script == TQFont::Hebrew)
+ // we need to attach below the baseline, because of the hebrew iud.
+ baseInfo.height = TQMAX(baseInfo.height, -baseInfo.y);
+
+ TQRect baseRect(baseInfo.x, baseInfo.y, baseInfo.width, baseInfo.height);
+
+// qDebug("---> positionCluster: cluster from %d to %d", gfrom, glast);
+// qDebug("baseInfo: %f/%f (%f/%f) off=%f/%f", baseInfo.x, baseInfo.y, baseInfo.width, baseInfo.height, baseInfo.xoff, baseInfo.yoff);
+
+ int size = (f->ascent()/10);
+ int offsetBase = (size - 4) / 4 + TQMIN(size, 4) + 1;
+// qDebug("offset = %f", offsetBase);
+
+ bool rightToLeft = item->flags & TQTextEngine::RightToLeft;
+
+ int i;
+ unsigned char lastCmb = 0;
+ TQRect attachmentRect;
+
+ for(i = 1; i <= nmarks; i++) {
+ glyph_t mark = item->glyphs[gfrom+i];
+ TQPoint p;
+ glyph_metrics_t markInfo = f->boundingBox(mark);
+ TQRect markRect(markInfo.x, markInfo.y, markInfo.width, markInfo.height);
+// qDebug("markInfo: %f/%f (%f/%f) off=%f/%f", markInfo.x, markInfo.y, markInfo.width, markInfo.height, markInfo.xoff, markInfo.yoff);
+
+ int offset = offsetBase;
+ unsigned char cmb = item->attributes[gfrom+i].combiningClass;
+
+ // ### maybe the whole position determination should move down to heuristicSetGlyphAttributes. Would save some
+ // bits in the glyphAttributes structure.
+ if (cmb < 200) {
+ // fixed position classes. We approximate by mapping to one of the others.
+ // currently I added only the ones for arabic, hebrew, lao and thai.
+
+ // for Lao and Thai marks with class 0, see below (heuristicSetGlyphAttributes)
+
+ // add a bit more offset to arabic, a bit hacky
+ if (cmb >= 27 && cmb <= 36 && offset < 3)
+ offset +=1;
+ // below
+ if ((cmb >= 10 && cmb <= 18) ||
+ cmb == 20 || cmb == 22 ||
+ cmb == 29 || cmb == 32)
+ cmb = TQChar::Combining_Below;
+ // above
+ else if (cmb == 23 || cmb == 27 || cmb == 28 ||
+ cmb == 30 || cmb == 31 || (cmb >= 33 && cmb <= 36))
+ cmb = TQChar::Combining_Above;
+ //below-right
+ else if (cmb == 9 || cmb == 103 || cmb == 118)
+ cmb = TQChar::Combining_BelowRight;
+ // above-right
+ else if (cmb == 24 || cmb == 107 || cmb == 122)
+ cmb = TQChar::Combining_AboveRight;
+ else if (cmb == 25)
+ cmb = TQChar::Combining_AboveLeft;
+ // fixed:
+ // 19 21
+
+ }
+
+ // combining marks of different class don't interact. Reset the rectangle.
+ if (cmb != lastCmb) {
+ //qDebug("resetting rect");
+ attachmentRect = baseRect;
+ }
+
+ switch(cmb) {
+ case TQChar::Combining_DoubleBelow:
+ // ### wrong in rtl context!
+ case TQChar::Combining_BelowLeft:
+ p += TQPoint(0, offset);
+ case TQChar::Combining_BelowLeftAttached:
+ p += attachmentRect.bottomLeft() - markRect.topLeft();
+ break;
+ case TQChar::Combining_Below:
+ p += TQPoint(0, offset);
+ case TQChar::Combining_BelowAttached:
+ p += attachmentRect.bottomLeft() - markRect.topLeft();
+ p += TQPoint((attachmentRect.width() - markRect.width())/2 , 0);
+ break;
+ case TQChar::Combining_BelowRight:
+ p += TQPoint(0, offset);
+ case TQChar::Combining_BelowRightAttached:
+ p += attachmentRect.bottomRight() - markRect.topRight();
+ break;
+ case TQChar::Combining_Left:
+ p += TQPoint(-offset, 0);
+ case TQChar::Combining_LeftAttached:
+ break;
+ case TQChar::Combining_Right:
+ p += TQPoint(offset, 0);
+ case TQChar::Combining_RightAttached:
+ break;
+ case TQChar::Combining_DoubleAbove:
+ // ### wrong in RTL context!
+ case TQChar::Combining_AboveLeft:
+ p += TQPoint(0, -offset);
+ case TQChar::Combining_AboveLeftAttached:
+ p += attachmentRect.topLeft() - markRect.bottomLeft();
+ break;
+ case TQChar::Combining_Above:
+ p += TQPoint(0, -offset);
+ case TQChar::Combining_AboveAttached:
+ p += attachmentRect.topLeft() - markRect.bottomLeft();
+ p += TQPoint((attachmentRect.width() - markRect.width())/2 , 0);
+ break;
+ case TQChar::Combining_AboveRight:
+ p += TQPoint(0, -offset);
+ case TQChar::Combining_AboveRightAttached:
+ p += attachmentRect.topRight() - markRect.bottomRight();
+ break;
+
+ case TQChar::Combining_IotaSubscript:
+ default:
+ break;
+ }
+// qDebug("char=%x combiningClass = %d offset=%d/%d", mark, cmb, p.x(), p.y());
+ markRect.moveBy(p.x(), p.y());
+ attachmentRect |= markRect;
+ lastCmb = cmb;
+ if (rightToLeft) {
+ item->offsets[gfrom+i].x = p.x();
+ item->offsets[gfrom+i].y = p.y();
+ } else {
+ item->offsets[gfrom+i].x = p.x() - baseInfo.xoff;
+ item->offsets[gfrom+i].y = p.y() - baseInfo.yoff;
+ }
+ item->advances[gfrom+i] = 0;
+ }
+ item->has_positioning = TRUE;
+}
+
+
+void qt_heuristicPosition(TQShaperItem *item)
+{
+ int cEnd = -1;
+ int i = item->num_glyphs;
+ while (i--) {
+ if (cEnd == -1 && item->attributes[i].mark) {
+ cEnd = i;
+ } else if (cEnd != -1 && !item->attributes[i].mark) {
+ positionCluster(item, i, cEnd);
+ cEnd = -1;
+ }
+ }
+}
+
+
+
+// set the glyph attributes heuristically. Assumes a 1 to 1 relationship between chars and glyphs
+// and no reordering.
+// also computes logClusters heuristically
+static void heuristicSetGlyphAttributes(TQShaperItem *item, const TQChar *uc, int length)
+{
+ // justification is missing here!!!!!
+
+ if ( item->num_glyphs != length )
+ qWarning("TQScriptEngine::heuristicSetGlyphAttributes: char length and num glyphs disagree" );
+
+ unsigned short *logClusters = item->log_clusters;
+
+ int i;
+ for (i = 0; i < length; ++i)
+ logClusters[i] = i;
+
+ // first char in a run is never (treated as) a mark
+ int cStart = 0;
+ item->attributes[0].mark = FALSE;
+ item->attributes[0].clusterStart = TRUE;
+ item->attributes[0].combiningClass = 0;
+ if (qIsZeroWidthChar(uc[0].tqunicode())) {
+ item->attributes[0].zeroWidth = TRUE;
+ item->advances[0] = 0;
+ item->has_positioning = TRUE;
+ } else {
+ item->attributes[0].zeroWidth = FALSE;
+ }
+
+ int lastCat = ::category(uc[0]);
+ for (i = 1; i < length; ++i) {
+ int cat = ::category(uc[i]);
+ if (qIsZeroWidthChar(uc[i].tqunicode())) {
+ item->attributes[i].mark = FALSE;
+ item->attributes[i].clusterStart = TRUE;
+ item->attributes[i].zeroWidth = TRUE;
+ item->attributes[i].combiningClass = 0;
+ cStart = i;
+ item->advances[i] = 0;
+ item->has_positioning = TRUE;
+ } else if (cat != TQChar::Mark_NonSpacing) {
+ item->attributes[i].mark = FALSE;
+ item->attributes[i].clusterStart = TRUE;
+ item->attributes[i].combiningClass = 0;
+ cStart = i;
+ } else {
+ int cmb = ::combiningClass(uc[i]);
+
+ if (cmb == 0) {
+ // Fix 0 combining classes
+ if ((uc[i].tqunicode() & 0xff00) == 0x0e00) {
+ // thai or lao
+ unsigned char col = uc[i].cell();
+ if (col == 0x31 ||
+ col == 0x34 ||
+ col == 0x35 ||
+ col == 0x36 ||
+ col == 0x37 ||
+ col == 0x47 ||
+ col == 0x4c ||
+ col == 0x4d ||
+ col == 0x4e) {
+ cmb = TQChar::Combining_AboveRight;
+ } else if (col == 0xb1 ||
+ col == 0xb4 ||
+ col == 0xb5 ||
+ col == 0xb6 ||
+ col == 0xb7 ||
+ col == 0xbb ||
+ col == 0xcc ||
+ col == 0xcd) {
+ cmb = TQChar::Combining_Above;
+ } else if (col == 0xbc) {
+ cmb = TQChar::Combining_Below;
+ }
+ }
+ }
+
+ item->attributes[i].mark = TRUE;
+ item->attributes[i].clusterStart = FALSE;
+ item->attributes[i].combiningClass = cmb;
+ logClusters[i] = cStart;
+ item->advances[i] = 0;
+ item->has_positioning = TRUE;
+ }
+
+ if (lastCat == TQChar::Separator_Space)
+ item->attributes[i-1].justification = GlyphAttributes::Space;
+ else if (cat != TQChar::Mark_NonSpacing)
+ item->attributes[i-1].justification = GlyphAttributes::Character;
+ else
+ item->attributes[i-1].justification = GlyphAttributes::NoJustification;
+
+ lastCat = cat;
+ }
+}
+
+static void heuristicSetGlyphAttributes(TQShaperItem *item)
+{
+ heuristicSetGlyphAttributes(item, item->string->tqunicode() + item->from, item->length);
+}
+
+
+static bool basic_tqshape(TQShaperItem *item)
+{
+ if (item->font->stringToCMap(item->string->tqunicode()+item->from, item->length, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+
+ heuristicSetGlyphAttributes(item);
+ qt_heuristicPosition(item);
+ return TRUE;
+}
+
+// --------------------------------------------------------------------------------------------------------------------------------------------
+//
+// Middle eastern languages
+//
+// --------------------------------------------------------------------------------------------------------------------------------------------
+
+// Uniscribe also defines dlig for Hebrew, but we leave this out for now, as it's mostly
+// ligatures one does not want in modern Hebrew (as lam-alef ligatures).
+enum {
+ CcmpProperty = 0x1
+};
+#if defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)
+static const TQOpenType::Features hebrew_features[] = {
+ { FT_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
+ {0, 0}
+};
+#endif
+/* Hebrew shaping. In the non opentype case we try to use the
+ presentation forms specified for Hebrew. Especially for the
+ ligatures with Dagesh this gives much better results than we could
+ achieve manually.
+*/
+static bool hebrew_tqshape(TQShaperItem *item)
+{
+ TQ_ASSERT(item->script == TQFont::Hebrew);
+
+#if defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)
+ TQOpenType *openType = item->font->openType();
+
+ if (openType && openType->supportsScript(item->script)) {
+ openType->selectScript(item->script, hebrew_features);
+
+ if (item->font->stringToCMap(item->string->tqunicode()+item->from, item->length, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+
+ heuristicSetGlyphAttributes(item);
+ openType->tqshape(item);
+ return openType->positionAndAdd(item);
+ }
+#endif
+
+ enum {
+ Dagesh = 0x5bc,
+ ShinDot = 0x5c1,
+ SinDot = 0x5c2,
+ Patah = 0x5b7,
+ Qamats = 0x5b8,
+ Holam = 0x5b9,
+ Rafe = 0x5bf
+ };
+ unsigned short chars[512];
+ TQChar *tqshapedChars = item->length > 256 ? (TQChar *)::malloc(2*item->length * sizeof(TQChar)) : (TQChar *)chars;
+
+ const TQChar *uc = item->string->tqunicode() + item->from;
+ unsigned short *logClusters = item->log_clusters;
+
+ *tqshapedChars = *uc;
+ logClusters[0] = 0;
+ int slen = 1;
+ int cluster_start = 0;
+ int i;
+ for (i = 1; i < item->length; ++i) {
+ ushort base = tqshapedChars[slen-1].tqunicode();
+ ushort tqshaped = 0;
+ bool invalid = FALSE;
+ if (uc[i].tqunicode() == Dagesh) {
+ if (base >= 0x5d0
+ && base <= 0x5ea
+ && base != 0x5d7
+ && base != 0x5dd
+ && base != 0x5df
+ && base != 0x5e2
+ && base != 0x5e5) {
+ tqshaped = base - 0x5d0 + 0xfb30;
+ } else if (base == 0xfb2a || base == 0xfb2b /* Shin with Shin or Sin dot */) {
+ tqshaped = base + 2;
+ } else {
+ invalid = TRUE;
+ }
+ } else if (uc[i].tqunicode() == ShinDot) {
+ if (base == 0x05e9)
+ tqshaped = 0xfb2a;
+ else if (base == 0xfb49)
+ tqshaped = 0xfb2c;
+ else
+ invalid = TRUE;
+ } else if (uc[i].tqunicode() == SinDot) {
+ if (base == 0x05e9)
+ tqshaped = 0xfb2b;
+ else if (base == 0xfb49)
+ tqshaped = 0xfb2d;
+ else
+ invalid = TRUE;
+ } else if (uc[i].tqunicode() == Patah) {
+ if (base == 0x5d0)
+ tqshaped = 0xfb2e;
+ } else if (uc[i].tqunicode() == Qamats) {
+ if (base == 0x5d0)
+ tqshaped = 0xfb2f;
+ } else if (uc[i].tqunicode() == Holam) {
+ if (base == 0x5d5)
+ tqshaped = 0xfb4b;
+ } else if (uc[i].tqunicode() == Rafe) {
+ if (base == 0x5d1)
+ tqshaped = 0xfb4c;
+ else if (base == 0x5db)
+ tqshaped = 0xfb4d;
+ else if (base == 0x5e4)
+ tqshaped = 0xfb4e;
+ }
+
+ if (invalid) {
+ tqshapedChars[slen] = 0x25cc;
+ item->attributes[slen].clusterStart = TRUE;
+ item->attributes[slen].mark = FALSE;
+ item->attributes[slen].combiningClass = 0;
+ cluster_start = slen;
+ ++slen;
+ }
+ if (tqshaped) {
+ if (item->font->canRender((TQChar *)&tqshaped, 1)) {
+ tqshapedChars[slen-1] = TQChar(tqshaped);
+ } else
+ tqshaped = 0;
+ }
+ if (!tqshaped) {
+ tqshapedChars[slen] = uc[i];
+ if (::category(uc[i]) != TQChar::Mark_NonSpacing) {
+ item->attributes[slen].clusterStart = TRUE;
+ item->attributes[slen].mark = FALSE;
+ item->attributes[slen].combiningClass = 0;
+ cluster_start = slen;
+ } else {
+ item->attributes[slen].clusterStart = FALSE;
+ item->attributes[slen].mark = TRUE;
+ item->attributes[slen].combiningClass = ::combiningClass(uc[i]);
+ }
+ ++slen;
+ }
+ logClusters[i] = cluster_start;
+ }
+
+ if (item->font->stringToCMap(tqshapedChars, slen, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+ for (i = 0; i < item->num_glyphs; ++i) {
+ if (item->attributes[i].mark)
+ item->advances[i] = 0;
+ }
+ qt_heuristicPosition(item);
+
+ if (item->length > 256)
+ ::free(tqshapedChars);
+ return TRUE;
+}
+
+// these groups correspond to the groups defined in the Unicode standard.
+// Some of these groups are equal whith regards to both joining and line breaking behaviour,
+// and thus have the same enum value
+//
+// I'm not sure the mapping of syriac to arabic enums is correct with regards to justification, but as
+// I couldn't tqfind any better document I'll hope for the best.
+enum ArabicGroup {
+ // NonJoining
+ ArabicNone,
+ ArabicSpace,
+ // Transtqparent
+ Transtqparent,
+ // Causing
+ Center,
+ Kashida,
+
+ // Arabic
+ // Dual
+ Beh,
+ Noon,
+ Meem = Noon,
+ Heh = Noon,
+ KnottedHeh = Noon,
+ HehGoal = Noon,
+ SwashKaf = Noon,
+ Yeh,
+ Hah,
+ Seen,
+ Sad = Seen,
+ Tah,
+ Kaf = Tah,
+ Gaf = Tah,
+ Lam = Tah,
+ Ain,
+ Feh = Ain,
+ Qaf = Ain,
+ // Right
+ Alef,
+ Waw,
+ Dal,
+ TehMarbuta = Dal,
+ Reh,
+ HamzaOnHehGoal,
+ YehWithTail = HamzaOnHehGoal,
+ YehBarre = HamzaOnHehGoal,
+
+ // Syriac
+ // Dual
+ Beth = Beh,
+ Gamal = Ain,
+ Heth = Noon,
+ Teth = Hah,
+ Yudh = Noon,
+ Kaph = Noon,
+ Lamadh = Lam,
+ Mim = Noon,
+ Nun = Noon,
+ Semakh = Noon,
+ FinalSemakh = Noon,
+ SyriacE = Ain,
+ Pe = Ain,
+ ReversedPe = Hah,
+ Qaph = Noon,
+ Shin = Noon,
+ Fe = Ain,
+
+ // Right
+ Alaph = Alef,
+ Dalath = Dal,
+ He = Dal,
+ SyriacWaw = Waw,
+ Zain = Alef,
+ YudhHe = Waw,
+ Sadhe = HamzaOnHehGoal,
+ Taw = Dal,
+
+ // Compiler bug? Otherwise ArabicGroupsEnd would be equal to Dal + 1.
+ Dummy = HamzaOnHehGoal,
+ ArabicGroupsEnd
+};
+
+static const unsigned char arabic_group[0x150] = {
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+ Transtqparent, Transtqparent, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+
+ ArabicNone, ArabicNone, Alef, Alef,
+ Waw, Alef, Yeh, Alef,
+ Beh, TehMarbuta, Beh, Beh,
+ Hah, Hah, Hah, Dal,
+
+ Dal, Reh, Reh, Seen,
+ Seen, Sad, Sad, Tah,
+ Tah, Ain, Ain, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+
+ // 0x640
+ Kashida, Feh, Qaf, Kaf,
+ Lam, Meem, Noon, Heh,
+ Waw, Yeh, Yeh, Transtqparent,
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+ Transtqparent, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, Beh, Qaf,
+
+ Transtqparent, Alef, Alef, Alef,
+ ArabicNone, Alef, Waw, Waw,
+ Yeh, Beh, Beh, Beh,
+ Beh, Beh, Beh, Beh,
+
+ // 0x680
+ Beh, Hah, Hah, Hah,
+ Hah, Hah, Hah, Hah,
+ Dal, Dal, Dal, Dal,
+ Dal, Dal, Dal, Dal,
+
+ Dal, Reh, Reh, Reh,
+ Reh, Reh, Reh, Reh,
+ Reh, Reh, Seen, Seen,
+ Seen, Sad, Sad, Tah,
+
+ Ain, Feh, Feh, Feh,
+ Feh, Feh, Feh, Qaf,
+ Qaf, Gaf, SwashKaf, Gaf,
+ Kaf, Kaf, Kaf, Gaf,
+
+ Gaf, Gaf, Gaf, Gaf,
+ Gaf, Lam, Lam, Lam,
+ Lam, Noon, Noon, Noon,
+ Noon, Noon, KnottedHeh, Hah,
+
+ // 0x6c0
+ TehMarbuta, HehGoal, HamzaOnHehGoal, HamzaOnHehGoal,
+ Waw, Waw, Waw, Waw,
+ Waw, Waw, Waw, Waw,
+ Yeh, YehWithTail, Yeh, Waw,
+
+ Yeh, Yeh, YehBarre, YehBarre,
+ ArabicNone, TehMarbuta, Transtqparent, Transtqparent,
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+ Transtqparent, ArabicNone, ArabicNone, Transtqparent,
+
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+ Transtqparent, ArabicNone, ArabicNone, Transtqparent,
+ Transtqparent, ArabicNone, Transtqparent, Transtqparent,
+ Transtqparent, Transtqparent, Dal, Reh,
+
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, Seen, Sad,
+ Ain, ArabicNone, ArabicNone, KnottedHeh,
+
+ // 0x700
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+ ArabicNone, ArabicNone, ArabicNone, ArabicNone,
+
+ Alaph, Transtqparent, Beth, Gamal,
+ Gamal, Dalath, Dalath, He,
+ SyriacWaw, Zain, Heth, Teth,
+ Teth, Yudh, YudhHe, Kaph,
+
+ Lamadh, Mim, Nun, Semakh,
+ FinalSemakh, SyriacE, Pe, ReversedPe,
+ Sadhe, Qaph, Dalath, Shin,
+ Taw, Beth, Gamal, Dalath,
+
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+ Transtqparent, Transtqparent, Transtqparent, Transtqparent,
+ Transtqparent, Transtqparent, Transtqparent, ArabicNone,
+ ArabicNone, Zain, Kaph, Fe,
+};
+
+static inline ArabicGroup arabicGroup(unsigned short uc)
+{
+ if (uc >= 0x0600 && uc < 0x750)
+ return (ArabicGroup) arabic_group[uc-0x600];
+ else if (uc == 0x200d)
+ return Center;
+ else if (::category(uc) == TQChar::Separator_Space)
+ return ArabicSpace;
+ else
+ return ArabicNone;
+}
+
+
+/*
+ Arabic shaping obeys a number of rules according to the joining classes (see Unicode book, section on
+ arabic).
+
+ Each tqunicode char has a joining class (right, dual (left&right), center (joincausing) or transtqparent).
+ transtqparent joining is not encoded in TQChar::joining(), but applies to all combining marks and format marks.
+
+ Right join-causing: dual + center
+ Left join-causing: dual + right + center
+
+ Rules are as follows (for a string already in visual order, as we have it here):
+
+ R1 Transtqparent characters do not affect joining behaviour.
+ R2 A right joining character, that has a right join-causing char on the right will get form XRight
+ (R3 A left joining character, that has a left join-causing char on the left will get form XLeft)
+ Note: the above rule is meaningless, as there are no pure left joining characters defined in Unicode
+ R4 A dual joining character, that has a left join-causing char on the left and a right join-causing char on
+ the right will get form XMedial
+ R5 A dual joining character, that has a right join causing char on the right, and no left join causing char on the left
+ will get form XRight
+ R6 A dual joining character, that has a left join causing char on the left, and no right join causing char on the right
+ will get form XLeft
+ R7 Otherwise the character will get form XIsolated
+
+ Additionally we have to do the minimal ligature support for lam-alef ligatures:
+
+ L1 Transtqparent characters do not affect ligature behaviour.
+ L2 Any sequence of Alef(XRight) + Lam(XMedial) will form the ligature Alef.Lam(XLeft)
+ L3 Any sequence of Alef(XRight) + Lam(XLeft) will form the ligature Alef.Lam(XIsolated)
+
+ The state table below handles rules R1-R7.
+*/
+
+enum Shape {
+ XIsolated,
+ XFinal,
+ XInitial,
+ XMedial,
+ // intermediate state
+ XCausing
+};
+
+
+enum Joining {
+ JNone,
+ JCausing,
+ JDual,
+ JRight,
+ JTranstqparent
+};
+
+
+static const Joining joining_for_group[ArabicGroupsEnd] = {
+ // NonJoining
+ JNone, // ArabicNone
+ JNone, // ArabicSpace
+ // Transtqparent
+ JTranstqparent, // Transtqparent
+ // Causing
+ JCausing, // Center
+ JCausing, // Kashida
+ // Dual
+ JDual, // Beh
+ JDual, // Noon
+ JDual, // Yeh
+ JDual, // Hah
+ JDual, // Seen
+ JDual, // Tah
+ JDual, // Ain
+ // Right
+ JRight, // Alef
+ JRight, // Waw
+ JRight, // Dal
+ JRight, // Reh
+ JRight // HamzaOnHehGoal
+};
+
+
+struct JoiningPair {
+ Shape form1;
+ Shape form2;
+};
+
+static const JoiningPair joining_table[5][4] =
+// None, Causing, Dual, Right
+{
+ { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XInitial }, { XIsolated, XIsolated } }, // XIsolated
+ { { XFinal, XIsolated }, { XFinal, XCausing }, { XFinal, XInitial }, { XFinal, XIsolated } }, // XFinal
+ { { XIsolated, XIsolated }, { XInitial, XCausing }, { XInitial, XMedial }, { XInitial, XFinal } }, // XInitial
+ { { XFinal, XIsolated }, { XMedial, XCausing }, { XMedial, XMedial }, { XMedial, XFinal } }, // XMedial
+ { { XIsolated, XIsolated }, { XIsolated, XCausing }, { XIsolated, XMedial }, { XIsolated, XFinal } }, // XCausing
+};
+
+
+/*
+According to http://www.microsoft.com/middleeast/Arabicdev/IE6/KBase.asp
+
+1. Find the priority of the connecting opportunities in each word
+2. Add expansion at the highest priority connection opportunity
+3. If more than one connection opportunity have the same highest value,
+ use the opportunity closest to the end of the word.
+
+Following is a chart that provides the priority for connection
+opportunities and where expansion occurs. The character group names
+are those in table 6.6 of the UNICODE 2.0 book.
+
+
+PrioritY Glyph Condition Kashida Location
+
+Arabic_Kashida User inserted Kashida The user entered a Kashida in a position. After the user
+ (Shift+j or Shift+[E with hat]) Thus, it is the highest priority to insert an inserted kashida
+ automatic kashida.
+
+Arabic_Seen Seen, Sad Connecting to the next character. After the character.
+ (Initial or medial form).
+
+Arabic_HaaDal Teh Marbutah, Haa, Dal Connecting to previous character. Before the final form
+ of these characters.
+
+Arabic_Alef Alef, Tah, Lam, Connecting to previous character. Before the final form
+ Kaf and Gaf of these characters.
+
+Arabic_BaRa Reh, Yeh Connected to medial Beh Before preceding medial Baa
+
+Arabic_Waw Waw, Ain, Qaf, Feh Connecting to previous character. Before the final form of
+ these characters.
+
+Arabic_Normal Other connecting Connecting to previous character. Before the final form
+ characters of these characters.
+
+
+
+This seems to imply that we have at most one kashida point per arabic word.
+
+*/
+
+struct TQArabicProperties {
+ unsigned char tqshape;
+ unsigned char justification;
+};
+
+
+static void getArabicProperties(const unsigned short *chars, int len, TQArabicProperties *properties)
+{
+// qDebug("arabicSyriacOpenTypeShape: properties:");
+ int lastPos = 0;
+ int lastGroup = ArabicNone;
+
+ ArabicGroup group = arabicGroup(chars[0]);
+ Joining j = joining_for_group[group];
+ Shape tqshape = joining_table[XIsolated][j].form2;
+ properties[0].justification = GlyphAttributes::NoJustification;
+
+ for (int i = 1; i < len; ++i) {
+ // #### fix handling for spaces and punktuation
+ properties[i].justification = GlyphAttributes::NoJustification;
+
+ group = arabicGroup(chars[i]);
+ j = joining_for_group[group];
+
+ if (j == JTranstqparent) {
+ properties[i].tqshape = XIsolated;
+ continue;
+ }
+
+ properties[lastPos].tqshape = joining_table[tqshape][j].form1;
+ tqshape = joining_table[tqshape][j].form2;
+
+ switch(lastGroup) {
+ case Seen:
+ if (properties[lastPos].tqshape == XInitial || properties[lastPos].tqshape == XMedial)
+ properties[i-1].justification = GlyphAttributes::Arabic_Seen;
+ break;
+ case Hah:
+ if (properties[lastPos].tqshape == XFinal)
+ properties[lastPos-1].justification = GlyphAttributes::Arabic_HaaDal;
+ break;
+ case Alef:
+ if (properties[lastPos].tqshape == XFinal)
+ properties[lastPos-1].justification = GlyphAttributes::Arabic_Alef;
+ break;
+ case Ain:
+ if (properties[lastPos].tqshape == XFinal)
+ properties[lastPos-1].justification = GlyphAttributes::Arabic_Waw;
+ break;
+ case Noon:
+ if (properties[lastPos].tqshape == XFinal)
+ properties[lastPos-1].justification = GlyphAttributes::Arabic_Normal;
+ break;
+ case ArabicNone:
+ break;
+
+ default:
+ TQ_ASSERT(FALSE);
+ }
+
+ lastGroup = ArabicNone;
+
+ switch(group) {
+ case ArabicNone:
+ case Transtqparent:
+ // ### Center should probably be treated as transtqparent when it comes to justification.
+ case Center:
+ break;
+ case ArabicSpace:
+ properties[i].justification = GlyphAttributes::Arabic_Space;
+ break;
+ case Kashida:
+ properties[i].justification = GlyphAttributes::Arabic_Kashida;
+ break;
+ case Seen:
+ lastGroup = Seen;
+ break;
+
+ case Hah:
+ case Dal:
+ lastGroup = Hah;
+ break;
+
+ case Alef:
+ case Tah:
+ lastGroup = Alef;
+ break;
+
+ case Yeh:
+ case Reh:
+ if (properties[lastPos].tqshape == XMedial && arabicGroup(chars[lastPos]) == Beh)
+ properties[lastPos-1].justification = GlyphAttributes::Arabic_BaRa;
+ break;
+
+ case Ain:
+ case Waw:
+ lastGroup = Ain;
+ break;
+
+ case Noon:
+ case Beh:
+ case HamzaOnHehGoal:
+ lastGroup = Noon;
+ break;
+ case ArabicGroupsEnd:
+ TQ_ASSERT(FALSE);
+ }
+
+ lastPos = i;
+ }
+ properties[lastPos].tqshape = joining_table[tqshape][JNone].form1;
+
+
+// for (int i = 0; i < len; ++i)
+// qDebug("arabic properties(%d): uc=%x tqshape=%d, justification=%d", i, chars[i], properties[i].tqshape, properties[i].justification);
+}
+
+
+
+
+
+
+// The tqunicode to tqunicode shaping codec.
+// does only presentation forms B at the moment, but that should be enough for
+// simple display
+static const ushort arabicUnicodeMapping[256][2] = {
+ // base of tqshaped forms, and number-1 of them (0 for non shaping,
+ // 1 for right binding and 3 for dual binding
+
+ // These are just the glyphs available in Unicode,
+ // some characters are in R class, but have no glyphs in Unicode.
+
+ { 0x0600, 0 }, // 0x0600
+ { 0x0601, 0 }, // 0x0601
+ { 0x0602, 0 }, // 0x0602
+ { 0x0603, 0 }, // 0x0603
+ { 0x0604, 0 }, // 0x0604
+ { 0x0605, 0 }, // 0x0605
+ { 0x0606, 0 }, // 0x0606
+ { 0x0607, 0 }, // 0x0607
+ { 0x0608, 0 }, // 0x0608
+ { 0x0609, 0 }, // 0x0609
+ { 0x060A, 0 }, // 0x060A
+ { 0x060B, 0 }, // 0x060B
+ { 0x060C, 0 }, // 0x060C
+ { 0x060D, 0 }, // 0x060D
+ { 0x060E, 0 }, // 0x060E
+ { 0x060F, 0 }, // 0x060F
+
+ { 0x0610, 0 }, // 0x0610
+ { 0x0611, 0 }, // 0x0611
+ { 0x0612, 0 }, // 0x0612
+ { 0x0613, 0 }, // 0x0613
+ { 0x0614, 0 }, // 0x0614
+ { 0x0615, 0 }, // 0x0615
+ { 0x0616, 0 }, // 0x0616
+ { 0x0617, 0 }, // 0x0617
+ { 0x0618, 0 }, // 0x0618
+ { 0x0619, 0 }, // 0x0619
+ { 0x061A, 0 }, // 0x061A
+ { 0x061B, 0 }, // 0x061B
+ { 0x061C, 0 }, // 0x061C
+ { 0x061D, 0 }, // 0x061D
+ { 0x061E, 0 }, // 0x061E
+ { 0x061F, 0 }, // 0x061F
+
+ { 0x0620, 0 }, // 0x0620
+ { 0xFE80, 0 }, // 0x0621 HAMZA
+ { 0xFE81, 1 }, // 0x0622 R ALEF WITH MADDA ABOVE
+ { 0xFE83, 1 }, // 0x0623 R ALEF WITH HAMZA ABOVE
+ { 0xFE85, 1 }, // 0x0624 R WAW WITH HAMZA ABOVE
+ { 0xFE87, 1 }, // 0x0625 R ALEF WITH HAMZA BELOW
+ { 0xFE89, 3 }, // 0x0626 D YEH WITH HAMZA ABOVE
+ { 0xFE8D, 1 }, // 0x0627 R ALEF
+ { 0xFE8F, 3 }, // 0x0628 D BEH
+ { 0xFE93, 1 }, // 0x0629 R TEH MARBUTA
+ { 0xFE95, 3 }, // 0x062A D TEH
+ { 0xFE99, 3 }, // 0x062B D THEH
+ { 0xFE9D, 3 }, // 0x062C D JEEM
+ { 0xFEA1, 3 }, // 0x062D D HAH
+ { 0xFEA5, 3 }, // 0x062E D KHAH
+ { 0xFEA9, 1 }, // 0x062F R DAL
+
+ { 0xFEAB, 1 }, // 0x0630 R THAL
+ { 0xFEAD, 1 }, // 0x0631 R REH
+ { 0xFEAF, 1 }, // 0x0632 R ZAIN
+ { 0xFEB1, 3 }, // 0x0633 D SEEN
+ { 0xFEB5, 3 }, // 0x0634 D SHEEN
+ { 0xFEB9, 3 }, // 0x0635 D SAD
+ { 0xFEBD, 3 }, // 0x0636 D DAD
+ { 0xFEC1, 3 }, // 0x0637 D TAH
+ { 0xFEC5, 3 }, // 0x0638 D ZAH
+ { 0xFEC9, 3 }, // 0x0639 D AIN
+ { 0xFECD, 3 }, // 0x063A D GHAIN
+ { 0x063B, 0 }, // 0x063B
+ { 0x063C, 0 }, // 0x063C
+ { 0x063D, 0 }, // 0x063D
+ { 0x063E, 0 }, // 0x063E
+ { 0x063F, 0 }, // 0x063F
+
+ { 0x0640, 0 }, // 0x0640 C TATWEEL // ### Join Causing, only one glyph
+ { 0xFED1, 3 }, // 0x0641 D FEH
+ { 0xFED5, 3 }, // 0x0642 D TQAF
+ { 0xFED9, 3 }, // 0x0643 D KAF
+ { 0xFEDD, 3 }, // 0x0644 D LAM
+ { 0xFEE1, 3 }, // 0x0645 D MEEM
+ { 0xFEE5, 3 }, // 0x0646 D NOON
+ { 0xFEE9, 3 }, // 0x0647 D HEH
+ { 0xFEED, 1 }, // 0x0648 R WAW
+ { 0x0649, 3 }, // 0x0649 ALEF MAKSURA // ### Dual, glyphs not consecutive, handle in code.
+ { 0xFEF1, 3 }, // 0x064A D YEH
+ { 0x064B, 0 }, // 0x064B
+ { 0x064C, 0 }, // 0x064C
+ { 0x064D, 0 }, // 0x064D
+ { 0x064E, 0 }, // 0x064E
+ { 0x064F, 0 }, // 0x064F
+
+ { 0x0650, 0 }, // 0x0650
+ { 0x0651, 0 }, // 0x0651
+ { 0x0652, 0 }, // 0x0652
+ { 0x0653, 0 }, // 0x0653
+ { 0x0654, 0 }, // 0x0654
+ { 0x0655, 0 }, // 0x0655
+ { 0x0656, 0 }, // 0x0656
+ { 0x0657, 0 }, // 0x0657
+ { 0x0658, 0 }, // 0x0658
+ { 0x0659, 0 }, // 0x0659
+ { 0x065A, 0 }, // 0x065A
+ { 0x065B, 0 }, // 0x065B
+ { 0x065C, 0 }, // 0x065C
+ { 0x065D, 0 }, // 0x065D
+ { 0x065E, 0 }, // 0x065E
+ { 0x065F, 0 }, // 0x065F
+
+ { 0x0660, 0 }, // 0x0660
+ { 0x0661, 0 }, // 0x0661
+ { 0x0662, 0 }, // 0x0662
+ { 0x0663, 0 }, // 0x0663
+ { 0x0664, 0 }, // 0x0664
+ { 0x0665, 0 }, // 0x0665
+ { 0x0666, 0 }, // 0x0666
+ { 0x0667, 0 }, // 0x0667
+ { 0x0668, 0 }, // 0x0668
+ { 0x0669, 0 }, // 0x0669
+ { 0x066A, 0 }, // 0x066A
+ { 0x066B, 0 }, // 0x066B
+ { 0x066C, 0 }, // 0x066C
+ { 0x066D, 0 }, // 0x066D
+ { 0x066E, 0 }, // 0x066E
+ { 0x066F, 0 }, // 0x066F
+
+ { 0x0670, 0 }, // 0x0670
+ { 0xFB50, 1 }, // 0x0671 R ALEF WASLA
+ { 0x0672, 0 }, // 0x0672
+ { 0x0673, 0 }, // 0x0673
+ { 0x0674, 0 }, // 0x0674
+ { 0x0675, 0 }, // 0x0675
+ { 0x0676, 0 }, // 0x0676
+ { 0x0677, 0 }, // 0x0677
+ { 0x0678, 0 }, // 0x0678
+ { 0xFB66, 3 }, // 0x0679 D TTEH
+ { 0xFB5E, 3 }, // 0x067A D TTEHEH
+ { 0xFB52, 3 }, // 0x067B D BEEH
+ { 0x067C, 0 }, // 0x067C
+ { 0x067D, 0 }, // 0x067D
+ { 0xFB56, 3 }, // 0x067E D PEH
+ { 0xFB62, 3 }, // 0x067F D TEHEH
+
+ { 0xFB5A, 3 }, // 0x0680 D BEHEH
+ { 0x0681, 0 }, // 0x0681
+ { 0x0682, 0 }, // 0x0682
+ { 0xFB76, 3 }, // 0x0683 D NYEH
+ { 0xFB72, 3 }, // 0x0684 D DYEH
+ { 0x0685, 0 }, // 0x0685
+ { 0xFB7A, 3 }, // 0x0686 D TCHEH
+ { 0xFB7E, 3 }, // 0x0687 D TCHEHEH
+ { 0xFB88, 1 }, // 0x0688 R DDAL
+ { 0x0689, 0 }, // 0x0689
+ { 0x068A, 0 }, // 0x068A
+ { 0x068B, 0 }, // 0x068B
+ { 0xFB84, 1 }, // 0x068C R DAHAL
+ { 0xFB82, 1 }, // 0x068D R DDAHAL
+ { 0xFB86, 1 }, // 0x068E R DUL
+ { 0x068F, 0 }, // 0x068F
+
+ { 0x0690, 0 }, // 0x0690
+ { 0xFB8C, 1 }, // 0x0691 R RREH
+ { 0x0692, 0 }, // 0x0692
+ { 0x0693, 0 }, // 0x0693
+ { 0x0694, 0 }, // 0x0694
+ { 0x0695, 0 }, // 0x0695
+ { 0x0696, 0 }, // 0x0696
+ { 0x0697, 0 }, // 0x0697
+ { 0xFB8A, 1 }, // 0x0698 R JEH
+ { 0x0699, 0 }, // 0x0699
+ { 0x069A, 0 }, // 0x069A
+ { 0x069B, 0 }, // 0x069B
+ { 0x069C, 0 }, // 0x069C
+ { 0x069D, 0 }, // 0x069D
+ { 0x069E, 0 }, // 0x069E
+ { 0x069F, 0 }, // 0x069F
+
+ { 0x06A0, 0 }, // 0x06A0
+ { 0x06A1, 0 }, // 0x06A1
+ { 0x06A2, 0 }, // 0x06A2
+ { 0x06A3, 0 }, // 0x06A3
+ { 0xFB6A, 3 }, // 0x06A4 D VEH
+ { 0x06A5, 0 }, // 0x06A5
+ { 0xFB6E, 3 }, // 0x06A6 D PEHEH
+ { 0x06A7, 0 }, // 0x06A7
+ { 0x06A8, 0 }, // 0x06A8
+ { 0xFB8E, 3 }, // 0x06A9 D KEHEH
+ { 0x06AA, 0 }, // 0x06AA
+ { 0x06AB, 0 }, // 0x06AB
+ { 0x06AC, 0 }, // 0x06AC
+ { 0xFBD3, 3 }, // 0x06AD D NG
+ { 0x06AE, 0 }, // 0x06AE
+ { 0xFB92, 3 }, // 0x06AF D GAF
+
+ { 0x06B0, 0 }, // 0x06B0
+ { 0xFB9A, 3 }, // 0x06B1 D NGOEH
+ { 0x06B2, 0 }, // 0x06B2
+ { 0xFB96, 3 }, // 0x06B3 D GUEH
+ { 0x06B4, 0 }, // 0x06B4
+ { 0x06B5, 0 }, // 0x06B5
+ { 0x06B6, 0 }, // 0x06B6
+ { 0x06B7, 0 }, // 0x06B7
+ { 0x06B8, 0 }, // 0x06B8
+ { 0x06B9, 0 }, // 0x06B9
+ { 0xFB9E, 1 }, // 0x06BA R NOON GHUNNA
+ { 0xFBA0, 3 }, // 0x06BB D RNOON
+ { 0x06BC, 0 }, // 0x06BC
+ { 0x06BD, 0 }, // 0x06BD
+ { 0xFBAA, 3 }, // 0x06BE D HEH DOACHASHMEE
+ { 0x06BF, 0 }, // 0x06BF
+
+ { 0xFBA4, 1 }, // 0x06C0 R HEH WITH YEH ABOVE
+ { 0xFBA6, 3 }, // 0x06C1 D HEH GOAL
+ { 0x06C2, 0 }, // 0x06C2
+ { 0x06C3, 0 }, // 0x06C3
+ { 0x06C4, 0 }, // 0x06C4
+ { 0xFBE0, 1 }, // 0x06C5 R KIRGHIZ OE
+ { 0xFBD9, 1 }, // 0x06C6 R OE
+ { 0xFBD7, 1 }, // 0x06C7 R U
+ { 0xFBDB, 1 }, // 0x06C8 R YU
+ { 0xFBE2, 1 }, // 0x06C9 R KIRGHIZ YU
+ { 0x06CA, 0 }, // 0x06CA
+ { 0xFBDE, 1 }, // 0x06CB R VE
+ { 0xFBFC, 3 }, // 0x06CC D FARSI YEH
+ { 0x06CD, 0 }, // 0x06CD
+ { 0x06CE, 0 }, // 0x06CE
+ { 0x06CF, 0 }, // 0x06CF
+
+ { 0xFBE4, 3 }, // 0x06D0 D E
+ { 0x06D1, 0 }, // 0x06D1
+ { 0xFBAE, 1 }, // 0x06D2 R YEH BARREE
+ { 0xFBB0, 1 }, // 0x06D3 R YEH BARREE WITH HAMZA ABOVE
+ { 0x06D4, 0 }, // 0x06D4
+ { 0x06D5, 0 }, // 0x06D5
+ { 0x06D6, 0 }, // 0x06D6
+ { 0x06D7, 0 }, // 0x06D7
+ { 0x06D8, 0 }, // 0x06D8
+ { 0x06D9, 0 }, // 0x06D9
+ { 0x06DA, 0 }, // 0x06DA
+ { 0x06DB, 0 }, // 0x06DB
+ { 0x06DC, 0 }, // 0x06DC
+ { 0x06DD, 0 }, // 0x06DD
+ { 0x06DE, 0 }, // 0x06DE
+ { 0x06DF, 0 }, // 0x06DF
+
+ { 0x06E0, 0 }, // 0x06E0
+ { 0x06E1, 0 }, // 0x06E1
+ { 0x06E2, 0 }, // 0x06E2
+ { 0x06E3, 0 }, // 0x06E3
+ { 0x06E4, 0 }, // 0x06E4
+ { 0x06E5, 0 }, // 0x06E5
+ { 0x06E6, 0 }, // 0x06E6
+ { 0x06E7, 0 }, // 0x06E7
+ { 0x06E8, 0 }, // 0x06E8
+ { 0x06E9, 0 }, // 0x06E9
+ { 0x06EA, 0 }, // 0x06EA
+ { 0x06EB, 0 }, // 0x06EB
+ { 0x06EC, 0 }, // 0x06EC
+ { 0x06ED, 0 }, // 0x06ED
+ { 0x06EE, 0 }, // 0x06EE
+ { 0x06EF, 0 }, // 0x06EF
+
+ { 0x06F0, 0 }, // 0x06F0
+ { 0x06F1, 0 }, // 0x06F1
+ { 0x06F2, 0 }, // 0x06F2
+ { 0x06F3, 0 }, // 0x06F3
+ { 0x06F4, 0 }, // 0x06F4
+ { 0x06F5, 0 }, // 0x06F5
+ { 0x06F6, 0 }, // 0x06F6
+ { 0x06F7, 0 }, // 0x06F7
+ { 0x06F8, 0 }, // 0x06F8
+ { 0x06F9, 0 }, // 0x06F9
+ { 0x06FA, 0 }, // 0x06FA
+ { 0x06FB, 0 }, // 0x06FB
+ { 0x06FC, 0 }, // 0x06FC
+ { 0x06FD, 0 }, // 0x06FD
+ { 0x06FE, 0 }, // 0x06FE
+ { 0x06FF, 0 } // 0x06FF
+};
+
+// the arabicUnicodeMapping does not work for U+0649 ALEF MAKSURA, this table does
+static const ushort alefMaksura[4] = {0xFEEF, 0xFEF0, 0xFBE8, 0xFBE9};
+
+// this is a bit tricky. Alef always binds to the right, so the second parameter descibing the tqshape
+// of the lam can be either initial of medial. So initial maps to the isolated form of the ligature,
+// medial to the final form
+static const ushort arabicUnicodeLamAlefMapping[6][4] = {
+ { 0xfffd, 0xfffd, 0xfef5, 0xfef6 }, // 0x622 R Alef with Madda above
+ { 0xfffd, 0xfffd, 0xfef7, 0xfef8 }, // 0x623 R Alef with Hamza above
+ { 0xfffd, 0xfffd, 0xfffd, 0xfffd }, // 0x624 // Just to fill the table ;-)
+ { 0xfffd, 0xfffd, 0xfef9, 0xfefa }, // 0x625 R Alef with Hamza below
+ { 0xfffd, 0xfffd, 0xfffd, 0xfffd }, // 0x626 // Just to fill the table ;-)
+ { 0xfffd, 0xfffd, 0xfefb, 0xfefc } // 0x627 R Alef
+};
+
+static inline int getShape(uchar cell, int tqshape)
+{
+ // the arabicUnicodeMapping does not work for U+0649 ALEF MAKSURA, handle this here
+ uint ch = (cell != 0x49)
+ ? (tqshape ? arabicUnicodeMapping[cell][0] + tqshape : 0x600+cell)
+ : alefMaksura[tqshape] ;
+ return ch;
+}
+
+
+/*
+ Two small helper functions for arabic shaping.
+*/
+static inline const TQChar prevChar(const TQString *str, int pos)
+{
+ //qDebug("leftChar: pos=%d", pos);
+ pos--;
+ const TQChar *ch = str->tqunicode() + pos;
+ while(pos > -1) {
+ if(::category(*ch) != TQChar::Mark_NonSpacing)
+ return *ch;
+ pos--;
+ ch--;
+ }
+ return TQChar::tqreplacement;
+}
+
+static inline const TQChar nextChar(const TQString *str, int pos)
+{
+ pos++;
+ int len = str->length();
+ const TQChar *ch = str->tqunicode() + pos;
+ while(pos < len) {
+ //qDebug("rightChar: %d isLetter=%d, joining=%d", pos, ch.isLetter(), ch.joining());
+ if(::category(*ch) != TQChar::Mark_NonSpacing)
+ return *ch;
+ // assume it's a transtqparent char, this might not be 100% correct
+ pos++;
+ ch++;
+ }
+ return TQChar::tqreplacement;
+}
+
+
+static void tqshapedString(const TQString *uc, int from, int len, TQChar *tqshapeBuffer, int *tqshapedLength,
+ bool reverse, GlyphAttributes *attributes, unsigned short *logClusters)
+{
+ TQ_ASSERT((int)uc->length() >= from + len);
+
+ if(len == 0) {
+ *tqshapedLength = 0;
+ return;
+ }
+
+ TQVarLengthArray<TQArabicProperties> props(len + 2);
+ TQArabicProperties *properties = props.data();
+ int f = from;
+ int l = len;
+ if (from > 0) {
+ --f;
+ ++l;
+ ++properties;
+ }
+ if (f + l < (int)uc->length()) {
+ ++l;
+ }
+ getArabicProperties((const unsigned short *)(uc->tqunicode()+f), l, props.data());
+
+ const TQChar *ch = uc->tqunicode() + from;
+ TQChar *data = tqshapeBuffer;
+ int clusterStart = 0;
+
+ for (int i = 0; i < len; i++) {
+ uchar r = ch->row();
+ int gpos = data - tqshapeBuffer;
+
+ if (r != 0x06) {
+ if (r == 0x20) {
+ uchar c = ch->cell();
+ if (c == 0x0c || c == 0x0d)
+ // remove ZWJ and ZWNJ
+ goto skip;
+ }
+ if (reverse)
+ *data = mirroredChar(*ch);
+ else
+ *data = *ch;
+ } else {
+ uchar c = ch->cell();
+ int pos = i + from;
+ int tqshape = properties[i].tqshape;
+// qDebug("mapping U+%x to tqshape %d glyph=0x%x", ch->tqunicode(), tqshape, getShape(c, tqshape));
+ // take care of lam-alef ligatures (lam right of alef)
+ ushort map;
+ switch (c) {
+ case 0x44: { // lam
+ const TQChar pch = nextChar(uc, pos);
+ if (pch.row() == 0x06) {
+ switch (pch.cell()) {
+ case 0x22:
+ case 0x23:
+ case 0x25:
+ case 0x27:
+// qDebug(" lam of lam-alef ligature");
+ map = arabicUnicodeLamAlefMapping[pch.cell() - 0x22][tqshape];
+ goto next;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+ case 0x22: // alef with madda
+ case 0x23: // alef with hamza above
+ case 0x25: // alef with hamza below
+ case 0x27: // alef
+ if (prevChar(uc, pos).tqunicode() == 0x0644) {
+ // have a lam alef ligature
+ //qDebug(" alef of lam-alef ligature");
+ goto skip;
+ }
+ default:
+ break;
+ }
+ map = getShape(c, tqshape);
+ next:
+ *data = map;
+ }
+ // ##### Fixme
+ //attributes[gpos].zeroWidth = zeroWidth;
+ if (::category(*ch) == TQChar::Mark_NonSpacing) {
+ attributes[gpos].mark = TRUE;
+// qDebug("glyph %d (char %d) is mark!", gpos, i);
+ } else {
+ attributes[gpos].mark = FALSE;
+ clusterStart = data - tqshapeBuffer;
+ }
+ attributes[gpos].clusterStart = !attributes[gpos].mark;
+ attributes[gpos].combiningClass = combiningClass(*ch);
+ attributes[gpos].justification = properties[i].justification;
+// qDebug("data[%d] = %x (from %x)", gpos, (uint)data->tqunicode(), ch->tqunicode());
+ data++;
+ skip:
+ ch++;
+ logClusters[i] = clusterStart;
+ }
+ *tqshapedLength = data - tqshapeBuffer;
+}
+
+#if defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)
+
+enum {
+ InitProperty = 0x2,
+ IsolProperty = 0x4,
+ FinaProperty = 0x8,
+ MediProperty = 0x10,
+ RligProperty = 0x20,
+ CaltProperty = 0x40,
+ LigaProperty = 0x80,
+ DligProperty = 0x100,
+ CswhProperty = 0x200,
+ MsetProperty = 0x400
+};
+
+static const TQOpenType::Features arabic_features[] = {
+ { FT_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
+ { FT_MAKE_TAG('i', 's', 'o', 'l'), IsolProperty },
+ { FT_MAKE_TAG('f', 'i', 'n', 'a'), FinaProperty },
+ { FT_MAKE_TAG('m', 'e', 'd', 'i'), MediProperty },
+ { FT_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
+ { FT_MAKE_TAG('r', 'l', 'i', 'g'), RligProperty },
+ { FT_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty },
+ { FT_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty },
+ { FT_MAKE_TAG('d', 'l', 'i', 'g'), DligProperty },
+ { FT_MAKE_TAG('c', 's', 'w', 'h'), CswhProperty },
+ // mset is used in old Win95 fonts that don't have a 'mark' positioning table.
+ { FT_MAKE_TAG('m', 's', 'e', 't'), MsetProperty },
+ {0, 0}
+};
+
+static const TQOpenType::Features syriac_features[] = {
+ { FT_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
+ { FT_MAKE_TAG('i', 's', 'o', 'l'), IsolProperty },
+ { FT_MAKE_TAG('f', 'i', 'n', 'a'), FinaProperty },
+ { FT_MAKE_TAG('f', 'i', 'n', '2'), FinaProperty },
+ { FT_MAKE_TAG('f', 'i', 'n', '3'), FinaProperty },
+ { FT_MAKE_TAG('m', 'e', 'd', 'i'), MediProperty },
+ { FT_MAKE_TAG('m', 'e', 'd', '2'), MediProperty },
+ { FT_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
+ { FT_MAKE_TAG('r', 'l', 'i', 'g'), RligProperty },
+ { FT_MAKE_TAG('c', 'a', 'l', 't'), CaltProperty },
+ { FT_MAKE_TAG('l', 'i', 'g', 'a'), LigaProperty },
+ { FT_MAKE_TAG('d', 'l', 'i', 'g'), DligProperty },
+ {0, 0}
+};
+
+static bool arabicSyriacOpenTypeShape(TQOpenType *openType, TQShaperItem *item, bool *ot_ok)
+{
+ *ot_ok = true;
+
+ openType->selectScript(item->script, item->script == TQFont::Arabic ? arabic_features : syriac_features);
+ int nglyphs = item->num_glyphs;
+ if (item->font->stringToCMap(item->string->tqunicode()+item->from, item->length, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+ heuristicSetGlyphAttributes(item);
+
+ unsigned short *logClusters = item->log_clusters;
+ const unsigned short *uc = (const unsigned short *)item->string->tqunicode() + item->from;
+
+ TQVarLengthArray<TQArabicProperties> props(item->length+2);
+ TQArabicProperties *properties = props.data();
+ int f = 0;
+ int l = item->length;
+ if (item->from > 0) {
+ --f;
+ ++l;
+ ++properties;
+ }
+ if (f + l < (int)item->string->length()) {
+ ++l;
+ }
+ getArabicProperties((const unsigned short *)(uc+f), l, props.data());
+
+ TQVarLengthArray<uint> apply(item->num_glyphs);
+
+
+ // Hack to remove ZWJ and ZWNJ from rendered output.
+ int j = 0;
+ for (int i = 0; i < item->num_glyphs; i++) {
+ if (uc[i] == 0x200c || uc[i] == 0x200d)
+ continue;
+ item->glyphs[j] = item->glyphs[i];
+ item->attributes[j] = item->attributes[i];
+ item->advances[j] = item->advances[i];
+ item->offsets[j] = item->offsets[i];
+ properties[j] = properties[i];
+ item->attributes[j].justification = properties[i].justification;
+ logClusters[i] = logClusters[j];
+ ++j;
+ }
+ item->num_glyphs = j;
+
+ for (int i = 0; i < item->num_glyphs; i++) {
+ apply[i] = 0;
+
+ if (properties[i].tqshape == XIsolated)
+ apply[i] |= MediProperty|FinaProperty|InitProperty;
+ else if (properties[i].tqshape == XMedial)
+ apply[i] |= IsolProperty|FinaProperty|InitProperty;
+ else if (properties[i].tqshape == XFinal)
+ apply[i] |= IsolProperty|MediProperty|InitProperty;
+ else if (properties[i].tqshape == XInitial)
+ apply[i] |= IsolProperty|MediProperty|FinaProperty;
+ }
+
+ if (!openType->tqshape(item, apply.data())) {
+ *ot_ok = false;
+ return false;
+ }
+ item->num_glyphs = nglyphs;
+ return openType->positionAndAdd(item);
+}
+
+#endif
+
+// #### stil missing: identify invalid character combinations
+static bool arabic_tqshape(TQShaperItem *item)
+{
+ TQ_ASSERT(item->script == TQFont::Arabic);
+
+#if defined(TQ_WS_X11) && !defined(TQT_NO_XFTFREETYPE)
+ TQOpenType *openType = item->font->openType();
+
+ if (openType && openType->supportsScript(TQFont::Arabic)) {
+ bool ot_ok;
+ if (arabicSyriacOpenTypeShape(openType, item, &ot_ok))
+ return true;
+ if (ot_ok)
+ return false;
+ // fall through to the non OT code
+ }
+#endif
+
+ TQVarLengthArray<ushort> tqshapedChars(item->length);
+
+ int slen;
+ tqshapedString(item->string, item->from, item->length, (TQChar *)tqshapedChars.data(), &slen,
+ item->flags & TQTextEngine::RightToLeft,
+ item->attributes, item->log_clusters);
+
+ if (item->font->stringToCMap((TQChar *)tqshapedChars.data(), slen, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+
+ for (int i = 0; i < slen; ++i)
+ if (item->attributes[i].mark)
+ item->advances[i] = 0;
+ qt_heuristicPosition(item);
+ return TRUE;
+}
+
+#if defined(TQ_WS_X11)
+# include "tqscriptengine_x11.cpp"
+#elif defined(TQ_WS_WIN)
+# include "tqscriptengine_win.cpp"
+#elif defined(TQ_WS_MAC)
+# include "tqscriptengine_mac.cpp"
+#elif defined(TQ_WS_TQWS)
+# include "tqscriptengine_qws.cpp"
+#endif
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqscriptengine_p.h b/tqtinterface/qt4/src/kernel/tqscriptengine_p.h
new file mode 100644
index 0000000..42698e9
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqscriptengine_p.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the $MODULE$ of the TQt Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+****************************************************************************/
+
+#ifndef TQSCRIPTENGINE_P_H
+#define TQSCRIPTENGINE_P_H
+
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "tqtextengine_p.h"
+
+class TQString;
+struct TQCharAttributes;
+
+struct TQShaperItem {
+ int script;
+ const TQString *string;
+ int from;
+ int length;
+ TQFontEngine *font;
+ glyph_t *glyphs;
+ advance_t *advances;
+ qoffset_t *offsets;
+ GlyphAttributes *attributes;
+ int num_glyphs; // in: available glyphs out: glyphs used/needed
+ unsigned short *log_clusters;
+ int flags;
+ bool has_positioning;
+};
+
+// return true if ok.
+typedef bool (*ShapeFunction)(TQShaperItem *item);
+typedef void (*AttributeFunction)(int script, const TQString &, int, int, TQCharAttributes *);
+
+struct q_scriptEngine {
+ ShapeFunction tqshape;
+ AttributeFunction charAttributes;
+};
+
+extern const q_scriptEngine scriptEngines[];
+
+#endif // USE_QT4
+
+#endif // TQSCRIPTENGINE_P_H
diff --git a/tqtinterface/qt4/src/kernel/tqscriptengine_x11.cpp b/tqtinterface/qt4/src/kernel/tqscriptengine_x11.cpp
new file mode 100644
index 0000000..3cd84d7
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqscriptengine_x11.cpp
@@ -0,0 +1,3752 @@
+/****************************************************************************
+**
+** Copyright (C) 2003-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// ------------------------------------------------------------------------------------------------------------------
+//
+// Continuation of middle eastern languages
+//
+// ------------------------------------------------------------------------------------------------------------------
+
+// #### stil missing: identify invalid character combinations
+static bool syriac_tqshape(TQShaperItem *item)
+{
+ TQ_ASSERT(item->script == TQFont::Syriac);
+
+#ifndef TQT_NO_XFTFREETYPE
+ TQOpenType *openType = item->font->openType();
+ if (openType && openType->supportsScript(TQFont::Syriac)) {
+ bool ot_ok;
+ if (arabicSyriacOpenTypeShape(openType, item, &ot_ok))
+ return true;
+ if (ot_ok)
+ return false;
+ // fall through to the non OT code
+ }
+#endif
+ return basic_tqshape(item);
+}
+
+
+static bool thaana_tqshape(TQShaperItem *item)
+{
+ TQ_ASSERT(item->script == TQFont::Thaana);
+
+#ifndef TQT_NO_XFTFREETYPE
+ TQOpenType *openType = item->font->openType();
+
+ if (openType && openType->supportsScript(item->script)) {
+ openType->selectScript(TQFont::Thaana);
+ if (item->font->stringToCMap(item->string->tqunicode()+item->from, item->length, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+ heuristicSetGlyphAttributes(item);
+ openType->tqshape(item);
+ return openType->positionAndAdd(item);
+ }
+#endif
+ return basic_tqshape(item);
+}
+
+// --------------------------------------------------------------------------------------------------------------------------------------------
+//
+// Indic languages
+//
+// --------------------------------------------------------------------------------------------------------------------------------------------
+
+enum Form {
+ Invalid = 0x0,
+ Unknown = Invalid,
+ Consonant,
+ Nukta,
+ Halant,
+ Matra,
+ VowelMark,
+ StressMark,
+ IndependentVowel,
+ LengthMark,
+ Control,
+ Other
+};
+
+static const unsigned char indicForms[0xe00-0x900] = {
+ // Devangari
+ Invalid, VowelMark, VowelMark, VowelMark,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Unknown, Unknown,
+ Nukta, Other, Matra, Matra,
+
+ Matra, Matra, Matra, Matra,
+ Matra, Matra, Matra, Matra,
+ Matra, Matra, Matra, Matra,
+ Matra, Halant, Unknown, Unknown,
+
+ Other, StressMark, StressMark, StressMark,
+ StressMark, Unknown, Unknown, Unknown,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ IndependentVowel, IndependentVowel, VowelMark, VowelMark,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Consonant,
+ Consonant, Consonant /* ??? */, Consonant, Consonant,
+
+ // Bengali
+ Invalid, VowelMark, VowelMark, VowelMark,
+ Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, Invalid, Invalid, IndependentVowel,
+
+ IndependentVowel, Invalid, Invalid, IndependentVowel,
+ IndependentVowel, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Invalid, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Invalid, Consonant, Invalid,
+ Invalid, Invalid, Consonant, Consonant,
+ Consonant, Consonant, Unknown, Unknown,
+ Nukta, Other, Matra, Matra,
+
+ Matra, Matra, Matra, Matra,
+ Matra, Invalid, Invalid, Matra,
+ Matra, Invalid, Invalid, Matra,
+ Matra, Halant, Consonant, Unknown,
+
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Invalid, VowelMark,
+ Invalid, Invalid, Invalid, Invalid,
+ Consonant, Consonant, Invalid, Consonant,
+
+ IndependentVowel, IndependentVowel, VowelMark, VowelMark,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ Consonant, Consonant, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ // Gurmukhi
+ Invalid, VowelMark, VowelMark, VowelMark,
+ Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
+ Invalid, Invalid, Invalid, IndependentVowel,
+
+ IndependentVowel, Invalid, Invalid, IndependentVowel,
+ IndependentVowel, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Invalid, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Invalid, Consonant, Consonant,
+ Invalid, Consonant, Consonant, Invalid,
+ Consonant, Consonant, Unknown, Unknown,
+ Nukta, Other, Matra, Matra,
+
+ Matra, Matra, Matra, Invalid,
+ Invalid, Invalid, Invalid, Matra,
+ Matra, Invalid, Invalid, Matra,
+ Matra, Halant, Unknown, Unknown,
+
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Unknown, Unknown, Unknown,
+ Invalid, Consonant, Consonant, Consonant,
+ Consonant, Invalid, Consonant, Invalid,
+
+ Other, Other, Invalid, Invalid,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ StressMark, StressMark, Consonant, Consonant,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ // Gujarati
+ Invalid, VowelMark, VowelMark, VowelMark,
+ Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, Invalid, IndependentVowel,
+
+ IndependentVowel, IndependentVowel, Invalid, IndependentVowel,
+ IndependentVowel, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Invalid, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Invalid, Consonant, Consonant,
+ Invalid, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Unknown, Unknown,
+ Nukta, Other, Matra, Matra,
+
+ Matra, Matra, Matra, Matra,
+ Matra, Matra, Invalid, Matra,
+ Matra, Matra, Invalid, Matra,
+ Matra, Halant, Unknown, Unknown,
+
+ Other, Unknown, Unknown, Unknown,
+ Unknown, Unknown, Unknown, Unknown,
+ Unknown, Unknown, Unknown, Unknown,
+ Unknown, Unknown, Unknown, Unknown,
+
+ IndependentVowel, IndependentVowel, VowelMark, VowelMark,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ // Oriya
+ Invalid, VowelMark, VowelMark, VowelMark,
+ Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, Invalid, Invalid, IndependentVowel,
+
+ IndependentVowel, Invalid, Invalid, IndependentVowel,
+ IndependentVowel, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Invalid, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Invalid, Consonant, Consonant,
+ Invalid, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Unknown, Unknown,
+ Nukta, Other, Matra, Matra,
+
+ Matra, Matra, Matra, Matra,
+ Invalid, Invalid, Invalid, Matra,
+ Matra, Invalid, Invalid, Matra,
+ Matra, Halant, Unknown, Unknown,
+
+ Other, Invalid, Invalid, Invalid,
+ Invalid, Unknown, LengthMark, LengthMark,
+ Invalid, Invalid, Invalid, Invalid,
+ Consonant, Consonant, Invalid, Consonant,
+
+ IndependentVowel, IndependentVowel, Invalid, Invalid,
+ Invalid, Invalid, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ Other, Consonant, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ //Tamil
+ Invalid, Invalid, VowelMark, Other,
+ Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
+ Invalid, Invalid, IndependentVowel, IndependentVowel,
+
+ IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
+ IndependentVowel, Consonant, Invalid, Invalid,
+ Invalid, Consonant, Consonant, Invalid,
+ Consonant, Invalid, Consonant, Consonant,
+
+ Invalid, Invalid, Invalid, Consonant,
+ Consonant, Invalid, Invalid, Invalid,
+ Consonant, Consonant, Consonant, Invalid,
+ Invalid, Invalid, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Unknown, Unknown,
+ Invalid, Invalid, Matra, Matra,
+
+ Matra, Matra, Matra, Invalid,
+ Invalid, Invalid, Matra, Matra,
+ Matra, Invalid, Matra, Matra,
+ Matra, Halant, Invalid, Invalid,
+
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Invalid, LengthMark,
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Invalid, Invalid,
+
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ // Telugu
+ Invalid, VowelMark, VowelMark, VowelMark,
+ Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
+
+ IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
+ IndependentVowel, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Invalid, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Invalid, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Unknown, Unknown,
+ Invalid, Invalid, Matra, Matra,
+
+ Matra, Matra, Matra, Matra,
+ Matra, Invalid, Matra, Matra,
+ Matra, Invalid, Matra, Matra,
+ Matra, Halant, Invalid, Invalid,
+
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, LengthMark, Matra, Invalid,
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Invalid, Invalid,
+
+ IndependentVowel, IndependentVowel, Invalid, Invalid,
+ Invalid, Invalid, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ // Kannada
+ Invalid, Invalid, VowelMark, VowelMark,
+ Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
+
+ IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
+ IndependentVowel, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Invalid, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Invalid, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Unknown, Unknown,
+ Nukta, Other, Matra, Matra,
+
+ Matra, Matra, Matra, Matra,
+ Matra, Invalid, Matra, Matra,
+ Matra, Invalid, Matra, Matra,
+ Matra, Halant, Invalid, Invalid,
+
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, LengthMark, LengthMark, Invalid,
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Consonant, Invalid,
+
+ IndependentVowel, IndependentVowel, VowelMark, VowelMark,
+ Invalid, Invalid, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ // Malayalam
+ Invalid, Invalid, VowelMark, VowelMark,
+ Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
+
+ IndependentVowel, Invalid, IndependentVowel, IndependentVowel,
+ IndependentVowel, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Invalid, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Unknown, Unknown,
+ Invalid, Invalid, Matra, Matra,
+
+ Matra, Matra, Matra, Matra,
+ Invalid, Invalid, Matra, Matra,
+ Matra, Invalid, Matra, Matra,
+ Matra, Halant, Invalid, Invalid,
+
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Invalid, LengthMark,
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Invalid, Invalid,
+
+ IndependentVowel, IndependentVowel, Invalid, Invalid,
+ Invalid, Invalid, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+
+ // Sinhala
+ Invalid, Invalid, VowelMark, VowelMark,
+ Invalid, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+
+ IndependentVowel, IndependentVowel, IndependentVowel, IndependentVowel,
+ IndependentVowel, IndependentVowel, IndependentVowel, Invalid,
+ Invalid, Invalid, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+
+ Consonant, Consonant, Invalid, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Consonant,
+ Invalid, Consonant, Invalid, Invalid,
+
+ Consonant, Consonant, Consonant, Consonant,
+ Consonant, Consonant, Consonant, Invalid,
+ Invalid, Invalid, Halant, Invalid,
+ Invalid, Invalid, Invalid, Matra,
+
+ Matra, Matra, Matra, Matra,
+ Matra, Invalid, Matra, Invalid,
+ Matra, Matra, Matra, Matra,
+ Matra, Matra, Matra, Matra,
+
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Invalid, Invalid,
+ Invalid, Invalid, Invalid, Invalid,
+
+ Invalid, Invalid, Matra, Matra,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+ Other, Other, Other, Other,
+};
+
+enum Position {
+ None,
+ Pre,
+ Above,
+ Below,
+ Post,
+ Split,
+ Base,
+ Reph,
+ Vattu,
+ Inherit
+};
+
+static const unsigned char indicPosition[0xe00-0x900] = {
+ // Devanagari
+ None, Above, Above, Post,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ Below, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, Post, Pre,
+
+ Post, Below, Below, Below,
+ Below, Above, Above, Above,
+ Above, Post, Post, Post,
+ Post, None, None, None,
+
+ None, Above, Below, Above,
+ Above, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, Below, Below,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ // Bengali
+ None, Above, Post, Post,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ Below, None, None, Post,
+
+ Below, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ Below, None, Post, Pre,
+
+ Post, Below, Below, Below,
+ Below, None, None, Pre,
+ Pre, None, None, Split,
+ Split, Below, None, None,
+
+ None, None, None, None,
+ None, None, None, Post,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, Below, Below,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ // Gurmukhi
+ None, Above, Above, Post,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, Post,
+
+ Below, None, None, None,
+ None, Below, None, None,
+ None, Below, None, None,
+ Below, None, Post, Pre,
+
+ Post, Below, Below, None,
+ None, None, None, Above,
+ Above, None, None, Above,
+ Above, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ Above, Above, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ // Gujarati
+ None, Above, Above, Post,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ Below, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, Post, Pre,
+
+ Post, Below, Below, Below,
+ Below, Above, None, Above,
+ Above, Post, None, Post,
+ Post, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, Below, Below,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ // Oriya
+ None, Above, Post, Post,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ Below, None, None, None,
+ Below, None, None, None,
+ Below, Below, Below, Post,
+
+ Below, None, Below, Below,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, Post, Above,
+
+ Post, Below, Below, Below,
+ None, None, None, Pre,
+ Split, None, None, Split,
+ Split, None, None, None,
+
+ None, None, None, None,
+ None, None, Above, Post,
+ None, None, None, None,
+ None, None, None, Post,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, Below, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ // Tamil
+ None, None, Above, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, Post, Post,
+
+ Above, Below, Below, None,
+ None, None, Pre, Pre,
+ Pre, None, Split, Split,
+ Split, Halant, None, None,
+
+ None, None, None, None,
+ None, None, None, Post,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ // Telugu
+ None, Post, Post, Post,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, Below, Below, Below,
+ Below, Below, Below, Below,
+ Below, Below, Below, Below,
+
+ Below, Below, Below, Below,
+ Below, Below, Below, Below,
+ Below, None, Below, Below,
+ Below, Below, Below, Below,
+
+ Below, None, Below, Below,
+ None, Below, Below, Below,
+ Below, Below, None, None,
+ None, None, Post, Above,
+
+ Above, Post, Post, Post,
+ Post, None, Above, Above,
+ Split, None, Post, Above,
+ Above, Halant, None, None,
+
+ None, None, None, None,
+ None, Above, Below, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ // Kannada
+ None, None, Post, Post,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, Below, Below, Below,
+ Below, Below, Below, Below,
+ Below, Below, Below, Below,
+
+ Below, Below, Below, Below,
+ Below, Below, Below, Below,
+ Below, Below, Below, Below,
+ Below, Below, Below, Below,
+
+ Below, None, Below, Below,
+ None, Below, Below, Below,
+ Below, Below, None, None,
+ None, None, Post, Above,
+
+ Split, Post, Post, Post,
+ Post, None, Above, Split,
+ Split, None, Split, Split,
+ Above, Halant, None, None,
+
+ None, None, None, None,
+ None, Post, Post, None,
+ None, None, None, None,
+ None, None, Below, None,
+
+ None, None, Below, Below,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ // Malayalam
+ None, None, Post, Post,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, Post,
+
+ Post, None, Below, None,
+ None, Post, None, None,
+ None, None, None, None,
+ None, None, Post, Post,
+
+ Post, Post, Post, Post,
+ None, None, Pre, Pre,
+ Pre, None, Split, Split,
+ Split, Halant, None, None,
+
+ None, None, None, None,
+ None, None, None, Post,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ // Sinhala
+ None, None, Post, Post,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, Post,
+
+ Post, Post, Above, Above,
+ Below, None, Below, None,
+ Post, Pre, Split, Pre,
+ Split, Split, Split, Post,
+
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None,
+
+ None, None, Post, Post,
+ None, None, None, None,
+ None, None, None, None,
+ None, None, None, None
+};
+
+static inline Form form(unsigned short uc) {
+ if (uc < 0x900 || uc > 0xdff) {
+ if (uc == 0x25cc)
+ return Consonant;
+ if (uc == 0x200c || uc == 0x200d)
+ return Control;
+ return Other;
+ }
+ return (Form)indicForms[uc-0x900];
+}
+
+static inline Position indic_position(unsigned short uc) {
+ if (uc < 0x900 || uc > 0xdff)
+ return None;
+ return (Position) indicPosition[uc-0x900];
+}
+
+
+enum IndicScriptProperties {
+ HasReph = 0x01,
+ HasSplit = 0x02
+};
+
+const uchar scriptProperties[10] = {
+ // Devanagari,
+ HasReph,
+ // Bengali,
+ HasReph|HasSplit,
+ // Gurmukhi,
+ 0,
+ // Gujarati,
+ HasReph,
+ // Oriya,
+ HasReph|HasSplit,
+ // Tamil,
+ HasSplit,
+ // Telugu,
+ HasSplit,
+ // Kannada,
+ HasSplit|HasReph,
+ // Malayalam,
+ HasSplit,
+ // Sinhala,
+ HasSplit
+};
+
+struct IndicOrdering {
+ Form form;
+ Position position;
+};
+
+static const IndicOrdering devanagari_order [] = {
+ { Consonant, Below },
+ { Matra, Below },
+ { VowelMark, Below },
+ { StressMark, Below },
+ { Matra, Above },
+ { Matra, Post },
+ { Consonant, Reph },
+ { VowelMark, Above },
+ { StressMark, Above },
+ { VowelMark, Post },
+ { (Form)0, None }
+};
+
+static const IndicOrdering bengali_order [] = {
+ { Consonant, Below },
+ { Matra, Below },
+ { Matra, Above },
+ { Consonant, Reph },
+ { VowelMark, Above },
+ { Consonant, Post },
+ { Matra, Post },
+ { VowelMark, Post },
+ { (Form)0, None }
+};
+
+static const IndicOrdering gurmukhi_order [] = {
+ { Consonant, Below },
+ { Matra, Below },
+ { Matra, Above },
+ { Consonant, Post },
+ { Matra, Post },
+ { VowelMark, Above },
+ { (Form)0, None }
+};
+
+static const IndicOrdering tamil_order [] = {
+ { Matra, Above },
+ { Matra, Post },
+ { VowelMark, Post },
+ { (Form)0, None }
+};
+
+static const IndicOrdering telugu_order [] = {
+ { Matra, Above },
+ { Matra, Below },
+ { Matra, Post },
+ { Consonant, Below },
+ { Consonant, Post },
+ { VowelMark, Post },
+ { (Form)0, None }
+};
+
+static const IndicOrdering kannada_order [] = {
+ { Matra, Above },
+ { Matra, Post },
+ { Consonant, Below },
+ { Consonant, Post },
+ { LengthMark, Post },
+ { Consonant, Reph },
+ { VowelMark, Post },
+ { (Form)0, None }
+};
+
+static const IndicOrdering malayalam_order [] = {
+ { Consonant, Below },
+ { Matra, Below },
+ { Consonant, Reph },
+ { Consonant, Post },
+ { Matra, Post },
+ { VowelMark, Post },
+ { (Form)0, None }
+};
+
+static const IndicOrdering sinhala_order [] = {
+ { Matra, Below },
+ { Matra, Above },
+ { Matra, Post },
+ { VowelMark, Post },
+ { (Form)0, None }
+};
+
+static const IndicOrdering * const indic_order[] = {
+ devanagari_order, // Devanagari
+ bengali_order, // Bengali
+ gurmukhi_order, // Gurmukhi
+ devanagari_order, // Gujarati
+ bengali_order, // Oriya
+ tamil_order, // Tamil
+ telugu_order, // Telugu
+ kannada_order, // Kannada
+ malayalam_order, // Malayalam
+ sinhala_order // Sinhala
+};
+
+
+
+// vowel matras that have to be split into two parts.
+static const unsigned short split_matras[] = {
+ // matra, split1, split2
+
+ // bengalis
+ 0x9cb, 0x9c7, 0x9be,
+ 0x9cc, 0x9c7, 0x9d7,
+ // oriya
+ 0xb48, 0xb47, 0xb56,
+ 0xb4b, 0xb47, 0xb3e,
+ 0xb4c, 0xb47, 0xb57,
+ // tamil
+ 0xbca, 0xbc6, 0xbbe,
+ 0xbcb, 0xbc7, 0xbbe,
+ 0xbcc, 0xbc6, 0xbd7,
+ // telugu
+ 0xc48, 0xc46, 0xc56,
+ // kannada
+ 0xcc0, 0xcbf, 0xcd5,
+ 0xcc7, 0xcc6, 0xcd5,
+ 0xcc8, 0xcc6, 0xcd6,
+ 0xcca, 0xcc6, 0xcc2,
+ 0xccb, 0xcca, 0xcd5,
+ // malayalam
+ 0xd4a, 0xd46, 0xd3e,
+ 0xd4b, 0xd47, 0xd3e,
+ 0xd4c, 0xd46, 0xd57,
+ // sinhala
+ 0xdda, 0xdd9, 0xdca,
+ 0xddc, 0xdd9, 0xdcf,
+ 0xddd, 0xddc, 0xdca,
+ 0xdde, 0xdd9, 0xddf,
+ 0xffff
+};
+
+static inline void splitMatra(unsigned short *reordered, int matra, int &len, int &base)
+{
+ unsigned short matra_uc = reordered[matra];
+ //qDebug("matra=%d, reordered[matra]=%x", matra, reordered[matra]);
+
+ const unsigned short *split = split_matras;
+ while (split[0] < matra_uc)
+ split += 3;
+
+ assert(*split == matra_uc);
+ ++split;
+
+ if (indic_position(*split) == Pre) {
+ reordered[matra] = split[1];
+ memmove(reordered + 1, reordered, len*sizeof(unsigned short));
+ reordered[0] = split[0];
+ base++;
+ } else {
+ memmove(reordered + matra + 1, reordered + matra, (len-matra)*sizeof(unsigned short));
+ reordered[matra] = split[0];
+ reordered[matra+1] = split[1];
+ }
+ len++;
+}
+
+enum IndicProperties {
+ // these two are already defined
+// CcmpProperty = 0x1,
+// InitProperty = 0x2,
+ NuktaProperty = 0x4,
+ AkhantProperty = 0x8,
+ RephProperty = 0x10,
+ PreFormProperty = 0x20,
+ BelowFormProperty = 0x40,
+ AboveFormProperty = 0x80,
+ HalfFormProperty = 0x100,
+ PostFormProperty = 0x200,
+ VattuProperty = 0x400,
+ PreSubstProperty = 0x800,
+ BelowSubstProperty = 0x1000,
+ AboveSubstProperty = 0x2000,
+ PostSubstProperty = 0x4000,
+ HalantProperty = 0x8000,
+ CligProperty = 0x10000
+};
+
+#ifndef TQT_NO_XFTFREETYPE
+static const TQOpenType::Features indic_features[] = {
+ { FT_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
+ { FT_MAKE_TAG('i', 'n', 'i', 't'), InitProperty },
+ { FT_MAKE_TAG('n', 'u', 'k', 't'), NuktaProperty },
+ { FT_MAKE_TAG('a', 'k', 'h', 'n'), AkhantProperty },
+ { FT_MAKE_TAG('r', 'p', 'h', 'f'), RephProperty },
+ { FT_MAKE_TAG('b', 'l', 'w', 'f'), BelowFormProperty },
+ { FT_MAKE_TAG('h', 'a', 'l', 'f'), HalfFormProperty },
+ { FT_MAKE_TAG('p', 's', 't', 'f'), PostFormProperty },
+ { FT_MAKE_TAG('v', 'a', 't', 'u'), VattuProperty },
+ { FT_MAKE_TAG('p', 'r', 'e', 's'), PreSubstProperty },
+ { FT_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
+ { FT_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
+ { FT_MAKE_TAG('p', 's', 't', 's'), PostSubstProperty },
+ { FT_MAKE_TAG('h', 'a', 'l', 'n'), HalantProperty },
+ { 0, 0 }
+};
+#endif
+
+// #define INDIC_DEBUG
+#ifdef INDIC_DEBUG
+#define IDEBUG qDebug
+#else
+#define IDEBUG if(0) qDebug
+#endif
+
+#ifdef INDIC_DEBUG
+static TQString propertiesToString(int properties)
+{
+ TQString res;
+ properties = ~properties;
+ if (properties & CcmpProperty)
+ res += "Ccmp ";
+ if (properties & InitProperty)
+ res += "Init ";
+ if (properties & NuktaProperty)
+ res += "Nukta ";
+ if (properties & AkhantProperty)
+ res += "Akhant ";
+ if (properties & RephProperty)
+ res += "Reph ";
+ if (properties & PreFormProperty)
+ res += "PreForm ";
+ if (properties & BelowFormProperty)
+ res += "BelowForm ";
+ if (properties & AboveFormProperty)
+ res += "AboveForm ";
+ if (properties & HalfFormProperty)
+ res += "HalfForm ";
+ if (properties & PostFormProperty)
+ res += "PostForm ";
+ if (properties & VattuProperty)
+ res += "Vattu ";
+ if (properties & PreSubstProperty)
+ res += "PreSubst ";
+ if (properties & BelowSubstProperty)
+ res += "BelowSubst ";
+ if (properties & AboveSubstProperty)
+ res += "AboveSubst ";
+ if (properties & PostSubstProperty)
+ res += "PostSubst ";
+ if (properties & HalantProperty)
+ res += "Halant ";
+ if (properties & CligProperty)
+ res += "Clig ";
+ return res;
+}
+#endif
+
+static bool indic_tqshape_syllable(TQOpenType *openType, TQShaperItem *item, bool invalid)
+{
+ TQ_UNUSED(openType)
+ int script = item->script;
+ TQ_ASSERT(script >= TQFont::Devanagari && script <= TQFont::Sinhala);
+ const unsigned short script_base = 0x0900 + 0x80*(script-TQFont::Devanagari);
+ const unsigned short ra = script_base + 0x30;
+ const unsigned short halant = script_base + 0x4d;
+ const unsigned short nukta = script_base + 0x3c;
+
+ int len = item->length;
+ IDEBUG(">>>>> indic tqshape: from=%d, len=%d invalid=%d", item->from, item->length, invalid);
+
+ if (item->num_glyphs < len+4) {
+ item->num_glyphs = len+4;
+ return FALSE;
+ }
+
+ TQVarLengthArray<unsigned short> reordered(len+4);
+ TQVarLengthArray<unsigned char> position(len+4);
+
+ unsigned char properties = scriptProperties[script-TQFont::Devanagari];
+
+ if (invalid) {
+ *reordered.data() = 0x25cc;
+ memcpy(reordered.data()+1, item->string->tqunicode() + item->from, len*sizeof(TQChar));
+ len++;
+ } else {
+ memcpy(reordered.data(), item->string->tqunicode() + item->from, len*sizeof(TQChar));
+ }
+ if (reordered[len-1] == 0x200c) // zero width non joiner
+ len--;
+
+ int i;
+ int base = 0;
+ int reph = -1;
+
+#ifdef INDIC_DEBUG
+ IDEBUG("original:");
+ for (i = 0; i < len; i++) {
+ IDEBUG(" %d: %4x", i, reordered[i]);
+ }
+#endif
+
+ if (len != 1) {
+ unsigned short *uc = reordered.data();
+ bool beginsWithRa = FALSE;
+
+ // Rule 1: tqfind base consonant
+ //
+ // The shaping engine tqfinds the base consonant of the
+ // syllable, using the following algorithm: starting from the
+ // end of the syllable, move backwards until a consonant is
+ // found that does not have a below-base or post-base form
+ // (post-base forms have to follow below-base forms), or
+ // arrive at the first consonant. The consonant stopped at
+ // will be the base.
+ //
+ // * If the syllable starts with Ra + H (in a script that has
+ // 'Reph'), Ra is excluded from candidates for base
+ // consonants.
+ //
+ // * In Kannada and Telugu, the base consonant cannot be
+ // farther than 3 consonants from the end of the syllable.
+ // #### tqreplace the HasReph property by testing if the feature exists in the font!
+ if (form(*uc) == Consonant || (script == TQFont::Bengali && form(*uc) == IndependentVowel)) {
+ beginsWithRa = (properties & HasReph) && ((len > 2) && *uc == ra && *(uc+1) == halant);
+
+ if (beginsWithRa && form(*(uc+2)) == Control)
+ beginsWithRa = FALSE;
+
+ base = (beginsWithRa ? 2 : 0);
+ IDEBUG(" length = %d, beginsWithRa = %d, base=%d", len, beginsWithRa, base);
+
+ int lastConsonant = 0;
+ int matra = -1;
+ // we remember:
+ // * the last consonant since we need it for rule 2
+ // * the matras position for rule 3 and 4
+
+ // figure out possible base glyphs
+ memset(position.data(), 0, len);
+ if (script == TQFont::Devanagari || script == TQFont::Gujarati) {
+ bool vattu = FALSE;
+ for (i = base; i < len; ++i) {
+ position[i] = form(uc[i]);
+ if (position[i] == Consonant) {
+ lastConsonant = i;
+ vattu = (!vattu && uc[i] == ra);
+ if (vattu) {
+ IDEBUG("excluding vattu glyph at %d from base candidates", i);
+ position[i] = Vattu;
+ }
+ } else if (position[i] == Matra) {
+ matra = i;
+ }
+ }
+ } else {
+ for (i = base; i < len; ++i) {
+ position[i] = form(uc[i]);
+ if (position[i] == Consonant)
+ lastConsonant = i;
+ else if (matra < 0 && position[i] == Matra)
+ matra = i;
+ }
+ }
+ int skipped = 0;
+ Position pos = Post;
+ for (i = len-1; i > base; i--) {
+ if (position[i] != Consonant && (position[i] != Control || script == TQFont::Kannada))
+ continue;
+
+ Position charPosition = indic_position(uc[i]);
+ if (pos == Post && charPosition == Post) {
+ pos = Post;
+ } else if ((pos == Post || pos == Below) && charPosition == Below) {
+ if (script == TQFont::Devanagari || script == TQFont::Gujarati)
+ base = i;
+ pos = Below;
+ } else {
+ base = i;
+ break;
+ }
+ if (skipped == 2 && (script == TQFont::Kannada || script == TQFont::Telugu)) {
+ base = i;
+ break;
+ }
+ ++skipped;
+ }
+
+ IDEBUG(" base consonant at %d skipped=%d, lastConsonant=%d", base, skipped, lastConsonant);
+
+ // Rule 2:
+ //
+ // If the base consonant is not the last one, Uniscribe
+ // moves the halant from the base consonant to the last
+ // one.
+ if (lastConsonant > base) {
+ int halantPos = 0;
+ if (uc[base+1] == halant)
+ halantPos = base + 1;
+ else if (uc[base+1] == nukta && uc[base+2] == halant)
+ halantPos = base + 2;
+ if (halantPos > 0) {
+ IDEBUG(" moving halant from %d to %d!", base+1, lastConsonant);
+ for (i = halantPos; i < lastConsonant; i++)
+ uc[i] = uc[i+1];
+ uc[lastConsonant] = halant;
+ }
+ }
+
+ // Rule 3:
+ //
+ // If the syllable starts with Ra + H, Uniscribe moves
+ // this combination so that it follows either:
+
+ // * the post-base 'matra' (if any) or the base consonant
+ // (in scripts that show similarity to Devanagari, i.e.,
+ // Devanagari, Gujarati, Bengali)
+ // * the base consonant (other scripts)
+ // * the end of the syllable (Kannada)
+
+ Position matra_position = None;
+ if (matra > 0)
+ matra_position = indic_position(uc[matra]);
+ IDEBUG(" matra at %d with form %d, base=%d", matra, matra_position, base);
+
+ if (beginsWithRa && base != 0) {
+ int toPos = base+1;
+ if (toPos < len && uc[toPos] == nukta)
+ toPos++;
+ if (toPos < len && uc[toPos] == halant)
+ toPos++;
+ if (toPos < len && uc[toPos] == 0x200d)
+ toPos++;
+ if (toPos < len-1 && uc[toPos] == ra && uc[toPos+1] == halant)
+ toPos += 2;
+ if (script == TQFont::Devanagari || script == TQFont::Gujarati || script == TQFont::Bengali) {
+ if (matra_position == Post || matra_position == Split) {
+ toPos = matra+1;
+ matra -= 2;
+ }
+ } else if (script == TQFont::Kannada) {
+ toPos = len;
+ matra -= 2;
+ }
+
+ IDEBUG("moving leading ra+halant to position %d", toPos);
+ for (i = 2; i < toPos; i++)
+ uc[i-2] = uc[i];
+ uc[toPos-2] = ra;
+ uc[toPos-1] = halant;
+ base -= 2;
+ if (properties & HasReph)
+ reph = toPos-2;
+ }
+
+ // Rule 4:
+
+ // Uniscribe splits two- or three-part matras into their
+ // parts. This splitting is a character-to-character
+ // operation).
+ //
+ // Uniscribe describes some moving operations for these
+ // matras here. For shaping however all pre matras need
+ // to be at the begining of the syllable, so we just move
+ // them there now.
+ if (matra_position == Split) {
+ splitMatra(uc, matra, len, base);
+ // Handle three-part matras (0xccb in Kannada)
+ matra_position = indic_position(uc[matra]);
+ if (matra_position == Split)
+ splitMatra(uc, matra, len, base);
+ } else if (matra_position == Pre) {
+ unsigned short m = uc[matra];
+ while (matra--)
+ uc[matra+1] = uc[matra];
+ uc[0] = m;
+ base++;
+ }
+ }
+
+ // Rule 5:
+ //
+ // Uniscribe classifies consonants and 'matra' parts as
+ // pre-base, above-base (Reph), below-base or post-base. This
+ // classification exists on the character code level and is
+ // language-dependent, not font-dependent.
+ for (i = 0; i < base; ++i)
+ position[i] = Pre;
+ position[base] = Base;
+ for (i = base+1; i < len; ++i) {
+ position[i] = indic_position(uc[i]);
+ // #### tqreplace by adjusting table
+ if (uc[i] == nukta || uc[i] == halant)
+ position[i] = Inherit;
+ }
+ if (reph > 0) {
+ // recalculate reph, it might have changed.
+ for (i = base+1; i < len; ++i)
+ if (uc[i] == ra)
+ reph = i;
+ position[reph] = Reph;
+ position[reph+1] = Inherit;
+ }
+
+ // all reordering happens now to the chars after the base
+ int fixed = base+1;
+ if (fixed < len && uc[fixed] == nukta)
+ fixed++;
+ if (fixed < len && uc[fixed] == halant)
+ fixed++;
+ if (fixed < len && uc[fixed] == 0x200d)
+ fixed++;
+
+#ifdef INDIC_DEBUG
+ for (i = fixed; i < len; ++i)
+ IDEBUG("position[%d] = %d, form=%d", i, position[i], form(uc[i]));
+#endif
+ // we continuosly position the matras and vowel marks and increase the fixed
+ // until we reached the end.
+ const IndicOrdering *finalOrder = indic_order[script-TQFont::Devanagari];
+
+ IDEBUG(" reordering pass:");
+ //IDEBUG(" base=%d fixed=%d", base, fixed);
+ int toMove = 0;
+ while (finalOrder[toMove].form && fixed < len-1) {
+ //IDEBUG(" fixed = %d, moving form %d with pos %d", fixed, finalOrder[toMove].form, finalOrder[toMove].position);
+ for (i = fixed; i < len; i++) {
+ if (form(uc[i]) == finalOrder[toMove].form &&
+ position[i] == finalOrder[toMove].position) {
+ // need to move this glyph
+ int to = fixed;
+ if (i < len-1 && position[i+1] == Inherit) {
+ IDEBUG(" moving two chars from %d to %d", i, to);
+ unsigned short ch = uc[i];
+ unsigned short ch2 = uc[i+1];
+ unsigned char pos = position[i];
+ for (int j = i+1; j > to+1; j--) {
+ uc[j] = uc[j-2];
+ position[j] = position[j-2];
+ }
+ uc[to] = ch;
+ uc[to+1] = ch2;
+ position[to] = pos;
+ position[to+1] = pos;
+ fixed += 2;
+ } else {
+ IDEBUG(" moving one char from %d to %d", i, to);
+ unsigned short ch = uc[i];
+ unsigned char pos = position[i];
+ for (int j = i; j > to; j--) {
+ uc[j] = uc[j-1];
+ position[j] = position[j-1];
+ }
+ uc[to] = ch;
+ position[to] = pos;
+ fixed++;
+ }
+ }
+ }
+ toMove++;
+ }
+
+ }
+
+ if (reph > 0) {
+ // recalculate reph, it might have changed.
+ for (i = base+1; i < len; ++i)
+ if (reordered[i] == ra)
+ reph = i;
+ }
+
+ if (item->font->stringToCMap((const TQChar *)reordered.data(), len, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+
+
+ IDEBUG(" base=%d, reph=%d", base, reph);
+ IDEBUG("reordered:");
+ for (i = 0; i < len; i++) {
+ item->attributes[i].mark = FALSE;
+ item->attributes[i].clusterStart = FALSE;
+ item->attributes[i].justification = 0;
+ item->attributes[i].zeroWidth = FALSE;
+ IDEBUG(" %d: %4x", i, reordered[i]);
+ }
+
+ // now we have the syllable in the right order, and can start running it through open type.
+
+ bool control = FALSE;
+ for (i = 0; i < len; ++i)
+ control |= (form(reordered[i]) == Control);
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (openType) {
+
+ // we need to keep track of where the base glyph is for some
+ // scripts and use the cluster feature for this. This
+ // also means we have to correct the logCluster output from
+ // the open type engine manually afterwards. for indic this
+ // is rather simple, as all chars just point to the first
+ // glyph in the syllable.
+ TQVarLengthArray<unsigned short> clusters(len);
+ TQVarLengthArray<unsigned int> properties(len);
+
+ for (i = 0; i < len; ++i)
+ clusters[i] = i;
+
+ // features we should always apply
+ for (i = 0; i < len; ++i)
+ properties[i] = ~(CcmpProperty
+ | NuktaProperty
+ | VattuProperty
+ | PreSubstProperty
+ | BelowSubstProperty
+ | AboveSubstProperty
+ | HalantProperty
+ | PositioningProperties);
+
+ // Ccmp always applies
+ // Init
+ if (item->from == 0
+ || !(item->string->tqunicode()[item->from-1].isLetter() || item->string->tqunicode()[item->from-1].isMark()))
+ properties[0] &= ~InitProperty;
+
+ // Nukta always applies
+ // Akhant
+ for (i = 0; i <= base; ++i)
+ properties[i] &= ~AkhantProperty;
+ // Reph
+ if (reph >= 0) {
+ properties[reph] &= ~RephProperty;
+ properties[reph+1] &= ~RephProperty;
+ }
+ // BelowForm
+ for (i = base+1; i < len; ++i)
+ properties[i] &= ~BelowFormProperty;
+
+ if (script == TQFont::Devanagari || script == TQFont::Gujarati) {
+ // vattu glyphs need this aswell
+ bool vattu = FALSE;
+ for (i = base-2; i > 1; --i) {
+ if (form(reordered[i]) == Consonant) {
+ vattu = (!vattu && reordered[i] == ra);
+ if (vattu) {
+ IDEBUG("forming vattu ligature at %d", i);
+ properties[i] &= ~BelowFormProperty;
+ properties[i+1] &= ~BelowFormProperty;
+ }
+ }
+ }
+ }
+ // HalfFormProperty
+ for (i = 0; i < base; ++i)
+ properties[i] &= ~HalfFormProperty;
+ if (control) {
+ for (i = 2; i < len; ++i) {
+ if (reordered[i] == 0x200d /* ZWJ */) {
+ properties[i-1] &= ~HalfFormProperty;
+ properties[i-2] &= ~HalfFormProperty;
+ } else if (reordered[i] == 0x200c /* ZWNJ */) {
+ properties[i-1] &= ~HalfFormProperty;
+ properties[i-2] &= ~HalfFormProperty;
+ }
+ }
+ }
+ // PostFormProperty
+ for (i = base+1; i < len; ++i)
+ properties[i] &= ~PostFormProperty;
+ // vattu always applies
+ // pres always applies
+ // blws always applies
+ // abvs always applies
+
+ // psts
+ // ### this looks slightly different from before, but I believe it's correct
+ if (reordered[len-1] != halant || base != len-2)
+ properties[base] &= ~PostSubstProperty;
+ for (i = base+1; i < len; ++i)
+ properties[i] &= ~PostSubstProperty;
+
+ // halant always applies
+
+#ifdef INDIC_DEBUG
+ {
+ IDEBUG("OT properties:");
+ for (int i = 0; i < len; ++i)
+ qDebug(" i: %s", ::propertiesToString(properties[i]).toLatin1().data());
+ }
+#endif
+
+ // initialize
+ item->log_clusters = clusters.data();
+ openType->tqshape(item, properties.data());
+
+ int newLen = openType->len();
+ OTL_GlyphItem otl_glyphs = openType->glyphs();
+
+ // move the left matra back to it's correct position in malayalam and tamil
+ if ((script == TQFont::Malayalam || script == TQFont::Tamil) && (form(reordered[0]) == Matra)) {
+// qDebug("reordering matra, len=%d", newLen);
+ // need to tqfind the base in the tqshaped string and move the matra there
+ int basePos = 0;
+ while (basePos < newLen && (int)otl_glyphs[basePos].cluster <= base)
+ basePos++;
+ --basePos;
+ if (basePos < newLen && basePos > 1) {
+// qDebug("moving prebase matra to position %d in syllable newlen=%d", basePos, newLen);
+ OTL_GlyphItemRec m = otl_glyphs[0];
+ --basePos;
+ for (i = 0; i < basePos; ++i)
+ otl_glyphs[i] = otl_glyphs[i+1];
+ otl_glyphs[basePos] = m;
+ }
+ }
+
+ if (!openType->positionAndAdd(item, FALSE))
+ return FALSE;
+
+ if (control) {
+ IDEBUG("found a control char in the syllable");
+ int i = 0, j = 0;
+ while (i < item->num_glyphs) {
+ if (form(reordered[otl_glyphs[i].cluster]) == Control) {
+ ++i;
+ if (i >= item->num_glyphs)
+ break;
+ }
+ item->glyphs[j] = item->glyphs[i];
+ ++i;
+ ++j;
+ }
+ item->num_glyphs = j;
+ }
+
+ }
+#endif
+
+ item->attributes[0].clusterStart = TRUE;
+ IDEBUG("<<<<<<");
+ return TRUE;
+}
+
+
+/* syllables are of the form:
+
+ (Consonant Nukta? Halant)* Consonant Matra? VowelMark? StressMark?
+ (Consonant Nukta? Halant)* Consonant Halant
+ IndependentVowel VowelMark? StressMark?
+
+ We return syllable boundaries on invalid combinations aswell
+*/
+static int indic_nextSyllableBoundary(int script, const TQString &s, int start, int end, bool *invalid)
+{
+ *invalid = FALSE;
+ IDEBUG("indic_nextSyllableBoundary: start=%d, end=%d", start, end);
+ const TQChar *uc = s.tqunicode()+start;
+
+ int pos = 0;
+ Form state = form(uc[pos].tqunicode());
+ IDEBUG("state[%d]=%d (uc=%4x)", pos, state, uc[pos].tqunicode());
+ pos++;
+
+ if (state != Consonant && state != IndependentVowel) {
+ if (state != Other)
+ *invalid = TRUE;
+ goto finish;
+ }
+
+ while (pos < end - start) {
+ Form newState = form(uc[pos].tqunicode());
+ IDEBUG("state[%d]=%d (uc=%4x)", pos, newState, uc[pos].tqunicode());
+ switch(newState) {
+ case Control:
+ newState = state;
+ if (state == Halant && uc[pos].tqunicode() == 0x200d /* ZWJ */)
+ break;
+ // the control character should be the last char in the item
+ ++pos;
+ goto finish;
+ case Consonant:
+ if (state == Halant && (script != TQFont::Sinhala || uc[pos-1].tqunicode() == 0x200d /* ZWJ */))
+ break;
+ goto finish;
+ case Halant:
+ if (state == Nukta || state == Consonant)
+ break;
+ // Bengali has a special exception allowing the combination Vowel_A/E + Halant + Ya
+ if (script == TQFont::Bengali && pos == 1 &&
+ (uc[0].tqunicode() == 0x0985 || uc[0].tqunicode() == 0x098f))
+ break;
+ goto finish;
+ case Nukta:
+ if (state == Consonant)
+ break;
+ goto finish;
+ case StressMark:
+ if (state == VowelMark)
+ break;
+ // fall through
+ case VowelMark:
+ if (state == Matra || state == IndependentVowel)
+ break;
+ // fall through
+ case Matra:
+ if (state == Consonant || state == Nukta)
+ break;
+ // ### not sure if this is correct. If it is, does it apply only to Bengali or should
+ // it work for all Indic languages?
+ // the combination Independent_A + Vowel Sign AA is allowed.
+ if (script == TQFont::Bengali && uc[pos].tqunicode() == 0x9be && uc[pos-1].tqunicode() == 0x985)
+ break;
+ if (script == TQFont::Tamil && state == Matra) {
+ if (uc[pos-1].tqunicode() == 0x0bc6 &&
+ (uc[pos].tqunicode() == 0xbbe || uc[pos].tqunicode() == 0xbd7))
+ break;
+ if (uc[pos-1].tqunicode() == 0x0bc7 && uc[pos].tqunicode() == 0xbbe)
+ break;
+ }
+ goto finish;
+
+ case LengthMark:
+ case IndependentVowel:
+ case Invalid:
+ case Other:
+ goto finish;
+ }
+ state = newState;
+ pos++;
+ }
+ finish:
+ return pos+start;
+}
+
+static bool indic_tqshape(TQShaperItem *item)
+{
+ TQ_ASSERT(item->script >= TQFont::Devanagari && item->script <= TQFont::Sinhala);
+
+#ifndef TQT_NO_XFTFREETYPE
+ TQOpenType *openType = item->font->openType();
+ if (openType)
+ openType->selectScript(item->script, indic_features);
+#else
+ TQOpenType *openType = 0;
+#endif
+ unsigned short *logClusters = item->log_clusters;
+
+ TQShaperItem syllable = *item;
+ int first_glyph = 0;
+
+ int sstart = item->from;
+ int end = sstart + item->length;
+ IDEBUG("indic_tqshape: from %d length %d", item->from, item->length);
+ while (sstart < end) {
+ bool invalid;
+ int send = indic_nextSyllableBoundary(item->script, *item->string, sstart, end, &invalid);
+ IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
+ invalid ? "TRUE" : "FALSE");
+ syllable.from = sstart;
+ syllable.length = send-sstart;
+ syllable.glyphs = item->glyphs + first_glyph;
+ syllable.offsets = item->offsets + first_glyph;
+ syllable.advances = item->advances + first_glyph;
+ syllable.attributes = item->attributes + first_glyph;
+ syllable.num_glyphs = item->num_glyphs - first_glyph;
+ if (!indic_tqshape_syllable(openType, &syllable, invalid)) {
+ IDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs);
+ item->num_glyphs += syllable.num_glyphs;
+ return FALSE;
+ }
+ item->has_positioning |= syllable.has_positioning;
+
+ // fix logcluster array
+ IDEBUG("syllable:");
+ int i;
+ for (i = first_glyph; i < first_glyph + syllable.num_glyphs; ++i)
+ IDEBUG(" %d -> glyph %x", i, item->glyphs[i]);
+ IDEBUG(" logclusters:");
+ for (i = sstart; i < send; ++i) {
+ IDEBUG(" %d -> glyph %d", i, first_glyph);
+ logClusters[i-item->from] = first_glyph;
+ }
+ sstart = send;
+ first_glyph += syllable.num_glyphs;
+ }
+ item->num_glyphs = first_glyph;
+ return TRUE;
+}
+
+
+static void indic_attributes(int script, const TQString &text, int from, int len, TQCharAttributes *attributes)
+{
+ int end = from + len;
+ const TQChar *uc = text.tqunicode() + from;
+ attributes += from;
+ int i = 0;
+ while (i < len) {
+ bool invalid;
+ int boundary = indic_nextSyllableBoundary(script, text, from+i, end, &invalid) - from;
+ attributes[i].charStop = TRUE;
+
+ if (boundary > len-1) boundary = len;
+ i++;
+ while (i < boundary) {
+ attributes[i].charStop = FALSE;
+ ++uc;
+ ++i;
+ }
+ assert(i == boundary);
+ }
+
+
+}
+
+
+// --------------------------------------------------------------------------------------------------------------------------------------------
+//
+// Thai and Lao
+//
+// --------------------------------------------------------------------------------------------------------------------------------------------
+
+#include <tqtextcodec.h>
+#include <tqlibrary.h>
+
+
+static void thaiWordBreaks(const TQChar *string, const int len, TQCharAttributes *attributes)
+{
+#ifndef TQT_NO_TEXTCODEC
+ typedef int (*th_brk_def)(const char*, int[], int);
+ static TQTextCodec *thaiCodec = TQTextCodec::codecForMib(2259);
+ static th_brk_def th_brk = 0;
+
+#ifndef TQT_NO_LIBRARY
+ /* load libthai dynamically */
+ if (!th_brk && thaiCodec) {
+ th_brk = (th_brk_def)TQLibrary::resolve("thai", "th_brk");
+ if (!th_brk)
+ thaiCodec = 0;
+ }
+#endif
+
+ if (!th_brk)
+ return;
+
+ TQCString cstr = thaiCodec->fromUnicode(TQConstString(string, len).string());
+
+ int brp[128];
+ int *break_positions = brp;
+ int numbreaks = th_brk(cstr.data(), break_positions, 128);
+ if (numbreaks > 128) {
+ break_positions = new int[numbreaks];
+ numbreaks = th_brk(cstr.data(),break_positions, numbreaks);
+ }
+
+ attributes[0].softBreak = TRUE;
+ int i;
+ for (i = 1; i < len; ++i)
+ attributes[i].softBreak = FALSE;
+
+ for (i = 0; i < numbreaks; ++i)
+ attributes[break_positions[i]].softBreak = TRUE;
+
+ if (break_positions != brp)
+ delete [] break_positions;
+#endif
+}
+
+
+static void thai_attributes( int script, const TQString &text, int from, int len, TQCharAttributes *attributes )
+{
+ TQ_UNUSED(script);
+ TQ_ASSERT(script == TQFont::Thai);
+ thaiWordBreaks(text.tqunicode() + from, len, attributes);
+}
+
+
+
+// --------------------------------------------------------------------------------------------------------------------------------------------
+//
+// Tibetan
+//
+// --------------------------------------------------------------------------------------------------------------------------------------------
+
+// tibetan syllables are of the form:
+// head position consonant
+// first sub-joined consonant
+// ....intermediate sub-joined consonants (if any)
+// last sub-joined consonant
+// sub-joined vowel (a-chung U+0F71)
+// standard or compound vowel sign (or 'virama' for devanagari transliteration)
+
+enum TibetanForm {
+ TibetanOther,
+ TibetanHeadConsonant,
+ TibetanSubjoinedConsonant,
+ TibetanSubjoinedVowel,
+ TibetanVowel
+};
+
+// this table starts at U+0f40
+static const unsigned char tibetanForm[0x80] = {
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+ TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant, TibetanHeadConsonant,
+ TibetanOther, TibetanOther, TibetanOther, TibetanOther,
+
+ TibetanOther, TibetanVowel, TibetanVowel, TibetanVowel,
+ TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
+ TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
+ TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
+
+ TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
+ TibetanVowel, TibetanVowel, TibetanVowel, TibetanVowel,
+ TibetanOther, TibetanOther, TibetanOther, TibetanOther,
+ TibetanOther, TibetanOther, TibetanOther, TibetanOther,
+
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+ TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant, TibetanSubjoinedConsonant,
+ TibetanSubjoinedConsonant, TibetanOther, TibetanOther, TibetanOther
+};
+
+
+static inline TibetanForm tibetan_form(const TQChar &c)
+{
+ return (TibetanForm)tibetanForm[c.tqunicode() - 0x0f40];
+}
+
+#ifndef TQT_NO_XFTFREETYPE
+static const TQOpenType::Features tibetan_features[] = {
+ { FT_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
+ { FT_MAKE_TAG('a', 'b', 'v', 's'), AboveSubstProperty },
+ { FT_MAKE_TAG('b', 'l', 'w', 's'), BelowSubstProperty },
+ {0, 0}
+};
+#endif
+
+static bool tibetan_tqshape_syllable(TQOpenType *openType, TQShaperItem *item, bool invalid)
+{
+ TQ_UNUSED(openType)
+ int len = item->length;
+
+ if (item->num_glyphs < item->length + 4) {
+ item->num_glyphs = item->length + 4;
+ return FALSE;
+ }
+
+ int i;
+ TQVarLengthArray<unsigned short> reordered(len+4);
+
+ const TQChar *str = item->string->tqunicode() + item->from;
+ if (invalid) {
+ *reordered.data() = 0x25cc;
+ memcpy(reordered.data()+1, str, len*sizeof(TQChar));
+ len++;
+ str = (TQChar *)reordered.data();
+ }
+
+ if (item->font->stringToCMap(str, len, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+
+ for (i = 0; i < item->length; i++) {
+ item->attributes[i].mark = FALSE;
+ item->attributes[i].clusterStart = FALSE;
+ item->attributes[i].justification = 0;
+ item->attributes[i].zeroWidth = FALSE;
+ IDEBUG(" %d: %4x", i, str[i].tqunicode());
+ }
+
+ // now we have the syllable in the right order, and can start running it through open type.
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (openType && openType->supportsScript(TQFont::Tibetan)) {
+ openType->selectScript(TQFont::Tibetan, tibetan_features);
+
+ openType->tqshape(item);
+ if (!openType->positionAndAdd(item, FALSE))
+ return FALSE;
+ }
+#endif
+
+ item->attributes[0].clusterStart = TRUE;
+ return TRUE;
+}
+
+
+static int tibetan_nextSyllableBoundary(const TQString &s, int start, int end, bool *invalid)
+{
+ const TQChar *uc = s.tqunicode() + start;
+
+ int pos = 0;
+ TibetanForm state = tibetan_form(*uc);
+
+// qDebug("state[%d]=%d (uc=%4x)", pos, state, uc[pos].tqunicode());
+ pos++;
+
+ if (state != TibetanHeadConsonant) {
+ if (state != TibetanOther)
+ *invalid = TRUE;
+ goto finish;
+ }
+
+ while (pos < end - start) {
+ TibetanForm newState = tibetan_form(uc[pos]);
+ switch(newState) {
+ case TibetanSubjoinedConsonant:
+ case TibetanSubjoinedVowel:
+ if (state != TibetanHeadConsonant &&
+ state != TibetanSubjoinedConsonant)
+ goto finish;
+ state = newState;
+ break;
+ case TibetanVowel:
+ if (state != TibetanHeadConsonant &&
+ state != TibetanSubjoinedConsonant &&
+ state != TibetanSubjoinedVowel)
+ goto finish;
+ break;
+ case TibetanOther:
+ case TibetanHeadConsonant:
+ goto finish;
+ }
+ pos++;
+ }
+
+finish:
+ *invalid = FALSE;
+ return start+pos;
+}
+
+static bool tibetan_tqshape(TQShaperItem *item)
+{
+ TQ_ASSERT(item->script == TQFont::Tibetan);
+
+#ifndef TQT_NO_XFTFREETYPE
+ TQOpenType *openType = item->font->openType();
+ if (openType && !openType->supportsScript(item->script))
+ openType = 0;
+#else
+ TQOpenType *openType = 0;
+#endif
+ unsigned short *logClusters = item->log_clusters;
+
+ TQShaperItem syllable = *item;
+ int first_glyph = 0;
+
+ int sstart = item->from;
+ int end = sstart + item->length;
+ while (sstart < end) {
+ bool invalid;
+ int send = tibetan_nextSyllableBoundary(*(item->string), sstart, end, &invalid);
+ IDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
+ invalid ? "TRUE" : "FALSE");
+ syllable.from = sstart;
+ syllable.length = send-sstart;
+ syllable.glyphs = item->glyphs + first_glyph;
+ syllable.offsets = item->offsets + first_glyph;
+ syllable.advances = item->advances + first_glyph;
+ syllable.attributes = item->attributes + first_glyph;
+ syllable.num_glyphs = item->num_glyphs - first_glyph;
+ if (!tibetan_tqshape_syllable(openType, &syllable, invalid)) {
+ item->num_glyphs += syllable.num_glyphs;
+ return FALSE;
+ }
+ item->has_positioning |= syllable.has_positioning;
+
+ // fix logcluster array
+ for (int i = sstart; i < send; ++i)
+ logClusters[i-item->from] = first_glyph;
+ sstart = send;
+ first_glyph += syllable.num_glyphs;
+ }
+ item->num_glyphs = first_glyph;
+ return TRUE;
+}
+
+static void tibetan_attributes(int script, const TQString &text, int from, int len, TQCharAttributes *attributes)
+{
+ TQ_UNUSED(script);
+
+ int end = from + len;
+ const TQChar *uc = text.tqunicode() + from;
+ attributes += from;
+ int i = 0;
+ while (i < len) {
+ bool invalid;
+ int boundary = tibetan_nextSyllableBoundary(text, from+i, end, &invalid) - from;
+
+ attributes[i].charStop = TRUE;
+
+ if (boundary > len-1) boundary = len;
+ i++;
+ while (i < boundary) {
+ attributes[i].charStop = FALSE;
+ ++uc;
+ ++i;
+ }
+ assert(i == boundary);
+ }
+}
+
+// --------------------------------------------------------------------------------------------------------------------------------------------
+//
+// Khmer
+//
+// --------------------------------------------------------------------------------------------------------------------------------------------
+
+
+// Vocabulary
+// Base -> A consonant or an independent vowel in its full (not subscript) form. It is the
+// center of the syllable, it can be surrounded by coeng (subscript) consonants, vowels,
+// split vowels, signs... but there is only one base in a syllable, it has to be coded as
+// the first character of the syllable.
+// split vowel --> vowel that has two parts placed separately (e.g. Before and after the consonant).
+// Khmer language has five of them. Khmer split vowels either have one part before the
+// base and one after the base or they have a part before the base and a part above the base.
+// The first part of all Khmer split vowels is the same character, identical to
+// the glyph of Khmer dependent vowel SRA EI
+// coeng --> modifier used in Khmer to construct coeng (subscript) consonants
+// Differently than indian languages, the coeng modifies the consonant that follows it,
+// not the one preceding it Each consonant has two forms, the base form and the subscript form
+// the base form is the normal one (using the consonants code-point), the subscript form is
+// displayed when the combination coeng + consonant is encountered.
+// Consonant of type 1 -> A consonant which has subscript for that only occupies space under a base consonant
+// Consonant of type 2.-> Its subscript form occupies space under and before the base (only one, RO)
+// Consonant of Type 3 -> Its subscript form occupies space under and after the base (KHO, CHHO, THHO, BA, YO, SA)
+// Consonant shifter -> Khmer has to series of consonants. The same dependent vowel has different sounds
+// if it is attached to a consonant of the first series or a consonant of the second series
+// Most consonants have an equivalent in the other series, but some of theme exist only in
+// one series (for example SA). If we want to use the consonant SA with a vowel sound that
+// can only be done with a vowel sound that corresponds to a vowel accompanying a consonant
+// of the other series, then we need to use a consonant shifter: TRIISAP or MUSIKATOAN
+// x17C9 y x17CA. TRIISAP changes a first series consonant to second series sound and
+// MUSIKATOAN a second series consonant to have a first series vowel sound.
+// Consonant shifter are both normally supercript marks, but, when they are followed by a
+// superscript, they change tqshape and take the form of subscript dependent vowel SRA U.
+// If they are in the same syllable as a coeng consonant, Unicode 3.0 says that they
+// should be typed before the coeng. Unicode 4.0 breaks the standard and says that it should
+// be placed after the coeng consonant.
+// Dependent vowel -> In khmer dependent vowels can be placed above, below, before or after the base
+// Each vowel has its own position. Only one vowel per syllable is allowed.
+// Signs -> Khmer has above signs and post signs. Only one above sign and/or one post sign are
+// Allowed in a syllable.
+//
+//
+// order is important here! This order must be the same that is found in each horizontal
+// line in the statetable for Khmer (see khmerStateTable) .
+//
+enum KhmerCharClassValues {
+ CC_RESERVED = 0,
+ CC_CONSONANT = 1, // Consonant of type 1 or independent vowel
+ CC_CONSONANT2 = 2, // Consonant of type 2
+ CC_CONSONANT3 = 3, // Consonant of type 3
+ CC_ZERO_WIDTH_NJ_MARK = 4, // Zero Width non joiner character (0x200C)
+ CC_CONSONANT_SHIFTER = 5,
+ CC_ROBAT = 6, // Khmer special diacritic accent -treated differently in state table
+ CC_COENG = 7, // Subscript consonant combining character
+ CC_DEPENDENT_VOWEL = 8,
+ CC_SIGN_ABOVE = 9,
+ CC_SIGN_AFTER = 10,
+ CC_ZERO_WIDTH_J_MARK = 11, // Zero width joiner character
+ CC_COUNT = 12 // This is the number of character classes
+};
+
+
+enum KhmerCharClassFlags {
+ CF_CLASS_MASK = 0x0000FFFF,
+
+ CF_CONSONANT = 0x01000000, // flag to speed up comparing
+ CF_SPLIT_VOWEL = 0x02000000, // flag for a split vowel -> the first part is added in front of the syllable
+ CF_DOTTED_CIRCLE = 0x04000000, // add a dotted circle if a character with this flag is the first in a syllable
+ CF_COENG = 0x08000000, // flag to speed up comparing
+ CF_SHIFTER = 0x10000000, // flag to speed up comparing
+ CF_ABOVE_VOWEL = 0x20000000, // flag to speed up comparing
+
+ // position flags
+ CF_POS_BEFORE = 0x00080000,
+ CF_POS_BELOW = 0x00040000,
+ CF_POS_ABOVE = 0x00020000,
+ CF_POS_AFTER = 0x00010000,
+ CF_POS_MASK = 0x000f0000
+};
+
+
+// Characters that get refered to by name
+enum KhmerChar {
+ C_SIGN_ZWNJ = 0x200C,
+ C_SIGN_ZWJ = 0x200D,
+ C_DOTTED_CIRCLE = 0x25CC,
+ C_RO = 0x179A,
+ C_VOWEL_AA = 0x17B6,
+ C_SIGN_NIKAHIT = 0x17C6,
+ C_VOWEL_E = 0x17C1,
+ C_COENG = 0x17D2
+};
+
+
+// simple classes, they are used in the statetable (in this file) to control the length of a syllable
+// they are also used to know where a character should be placed (location in reference to the base character)
+// and also to know if a character, when independently displayed, should be displayed with a dotted-circle to
+// indicate error in syllable construction
+//
+enum {
+ _xx = CC_RESERVED,
+ _sa = CC_SIGN_ABOVE | CF_DOTTED_CIRCLE | CF_POS_ABOVE,
+ _sp = CC_SIGN_AFTER | CF_DOTTED_CIRCLE| CF_POS_AFTER,
+ _c1 = CC_CONSONANT | CF_CONSONANT,
+ _c2 = CC_CONSONANT2 | CF_CONSONANT,
+ _c3 = CC_CONSONANT3 | CF_CONSONANT,
+ _rb = CC_ROBAT | CF_POS_ABOVE | CF_DOTTED_CIRCLE,
+ _cs = CC_CONSONANT_SHIFTER | CF_DOTTED_CIRCLE | CF_SHIFTER,
+ _dl = CC_DEPENDENT_VOWEL | CF_POS_BEFORE | CF_DOTTED_CIRCLE,
+ _db = CC_DEPENDENT_VOWEL | CF_POS_BELOW | CF_DOTTED_CIRCLE,
+ _da = CC_DEPENDENT_VOWEL | CF_POS_ABOVE | CF_DOTTED_CIRCLE | CF_ABOVE_VOWEL,
+ _dr = CC_DEPENDENT_VOWEL | CF_POS_AFTER | CF_DOTTED_CIRCLE,
+ _co = CC_COENG | CF_COENG | CF_DOTTED_CIRCLE,
+
+ // split vowel
+ _va = _da | CF_SPLIT_VOWEL,
+ _vr = _dr | CF_SPLIT_VOWEL
+};
+
+
+// Character class: a character class value
+// ORed with character class flags.
+//
+typedef unsigned long KhmerCharClass;
+
+
+// Character class tables
+// _xx character does not combine into syllable, such as numbers, puntuation marks, non-Khmer signs...
+// _sa Sign placed above the base
+// _sp Sign placed after the base
+// _c1 Consonant of type 1 or independent vowel (independent vowels behave as type 1 consonants)
+// _c2 Consonant of type 2 (only RO)
+// _c3 Consonant of type 3
+// _rb Khmer sign robat u17CC. combining mark for subscript consonants
+// _cd Consonant-shifter
+// _dl Dependent vowel placed before the base (left of the base)
+// _db Dependent vowel placed below the base
+// _da Dependent vowel placed above the base
+// _dr Dependent vowel placed behind the base (right of the base)
+// _co Khmer combining mark COENG u17D2, combines with the consonant or independent vowel following
+// it to create a subscript consonant or independent vowel
+// _va Khmer split vowel in wich the first part is before the base and the second one above the base
+// _vr Khmer split vowel in wich the first part is before the base and the second one behind (right of) the base
+//
+static const KhmerCharClass khmerCharClasses[] = {
+ _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c1, _c1, // 1780 - 178F
+ _c1, _c1, _c1, _c1, _c3, _c1, _c1, _c1, _c1, _c3, _c2, _c1, _c1, _c1, _c3, _c3, // 1790 - 179F
+ _c1, _c3, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, _c1, // 17A0 - 17AF
+ _c1, _c1, _c1, _c1, _dr, _dr, _dr, _da, _da, _da, _da, _db, _db, _db, _va, _vr, // 17B0 - 17BF
+ _vr, _dl, _dl, _dl, _vr, _vr, _sa, _sp, _sp, _cs, _cs, _sa, _rb, _sa, _sa, _sa, // 17C0 - 17CF
+ _sa, _sa, _co, _sa, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _xx, _sa, _xx, _xx // 17D0 - 17DF
+};
+
+// this enum must reflect the range of khmerCharClasses
+enum KhmerCharClassesRange {
+ KhmerFirstChar = 0x1780,
+ KhmerLastChar = 0x17df
+};
+
+// Below we define how a character in the input string is either in the khmerCharClasses table
+// (in which case we get its type back), a ZWJ or ZWNJ (two characters that may appear
+// within the syllable, but are not in the table) we also get their type back, or an unknown object
+// in which case we get _xx (CC_RESERVED) back
+//
+static inline KhmerCharClass getKhmerCharClass(const TQChar &uc)
+{
+ if (uc.tqunicode() == C_SIGN_ZWJ) {
+ return CC_ZERO_WIDTH_J_MARK;
+ }
+
+ if (uc.tqunicode() == C_SIGN_ZWNJ) {
+ return CC_ZERO_WIDTH_NJ_MARK;
+ }
+
+ if (uc.tqunicode() < KhmerFirstChar || uc.tqunicode() > KhmerLastChar) {
+ return CC_RESERVED;
+ }
+
+ return khmerCharClasses[uc.tqunicode() - KhmerFirstChar];
+}
+
+
+// The stateTable is used to calculate the end (the length) of a well
+// formed Khmer Syllable.
+//
+// Each horizontal line is ordered exactly the same way as the values in KhmerClassTable
+// CharClassValues. This coincidence of values allows the follow up of the table.
+//
+// Each line corresponds to a state, which does not necessarily need to be a type
+// of component... for example, state 2 is a base, with is always a first character
+// in the syllable, but the state could be produced a consonant of any type when
+// it is the first character that is analysed (in ground state).
+//
+// Differentiating 3 types of consonants is necessary in order to
+// forbid the use of certain combinations, such as having a second
+// coeng after a coeng RO,
+// The inexistent possibility of having a type 3 after another type 3 is permitted,
+// eliminating it would very much complicate the table, and it does not create typing
+// problems, as the case above.
+//
+// The table is quite complex, in order to limit the number of coeng consonants
+// to 2 (by means of the table).
+//
+// There a peculiarity, as far as Unicode is concerned:
+// - The consonant-shifter is considered in two possible different
+// locations, the one considered in Unicode 3.0 and the one considered in
+// Unicode 4.0. (there is a backwards compatibility problem in this standard).
+//
+//
+// xx independent character, such as a number, punctuation sign or non-khmer char
+//
+// c1 Khmer consonant of type 1 or an independent vowel
+// that is, a letter in which the subscript for is only under the
+// base, not taking any space to the right or to the left
+//
+// c2 Khmer consonant of type 2, the coeng form takes space under
+// and to the left of the base (only RO is of this type)
+//
+// c3 Khmer consonant of type 3. Its subscript form takes space under
+// and to the right of the base.
+//
+// cs Khmer consonant shifter
+//
+// rb Khmer robat
+//
+// co coeng character (u17D2)
+//
+// dv dependent vowel (including split vowels, they are treated in the same way).
+// even if dv is not defined above, the component that is really tested for is
+// KhmerClassTable::CC_DEPENDENT_VOWEL, which is common to all dependent vowels
+//
+// zwj Zero Width joiner
+//
+// zwnj Zero width non joiner
+//
+// sa above sign
+//
+// sp post sign
+//
+// there are lines with equal content but for an easier understanding
+// (and maybe change in the future) we did not join them
+//
+static const signed char khmerStateTable[][CC_COUNT] =
+{
+ // xx c1 c2 c3 zwnj cs rb co dv sa sp zwj
+ { 1, 2, 2, 2, 1, 1, 1, 6, 1, 1, 1, 2}, // 0 - ground state
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 1 - exit state (or sign to the right of the syllable)
+ {-1, -1, -1, -1, 3, 4, 5, 6, 16, 17, 1, -1}, // 2 - Base consonant
+ {-1, -1, -1, -1, -1, 4, -1, -1, 16, -1, -1, -1}, // 3 - First ZWNJ before a register shifter It can only be followed by a shifter or a vowel
+ {-1, -1, -1, -1, 15, -1, -1, 6, 16, 17, 1, 14}, // 4 - First register shifter
+ {-1, -1, -1, -1, -1, -1, -1, -1, 20, -1, 1, -1}, // 5 - Robat
+ {-1, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1}, // 6 - First Coeng
+ {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, // 7 - First consonant of type 1 after coeng
+ {-1, -1, -1, -1, 12, 13, -1, -1, 16, 17, 1, 14}, // 8 - First consonant of type 2 after coeng
+ {-1, -1, -1, -1, 12, 13, -1, 10, 16, 17, 1, 14}, // 9 - First consonant or type 3 after ceong
+ {-1, 11, 11, 11, -1, -1, -1, -1, -1, -1, -1, -1}, // 10 - Second Coeng (no register shifter before)
+ {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, // 11 - Second coeng consonant (or ind. vowel) no register shifter before
+ {-1, -1, -1, -1, -1, 13, -1, -1, 16, -1, -1, -1}, // 12 - Second ZWNJ before a register shifter
+ {-1, -1, -1, -1, 15, -1, -1, -1, 16, 17, 1, 14}, // 13 - Second register shifter
+ {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, // 14 - ZWJ before vowel
+ {-1, -1, -1, -1, -1, -1, -1, -1, 16, -1, -1, -1}, // 15 - ZWNJ before vowel
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 1, 18}, // 16 - dependent vowel
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 18}, // 17 - sign above
+ {-1, -1, -1, -1, -1, -1, -1, 19, -1, -1, -1, -1}, // 18 - ZWJ after vowel
+ {-1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1}, // 19 - Third coeng
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, // 20 - dependent vowel after a Robat
+};
+
+
+// #define KHMER_DEBUG
+#ifdef KHMER_DEBUG
+#define KHDEBUG qDebug
+#else
+#define KHDEBUG if(0) qDebug
+#endif
+
+// Given an input string of characters and a location in which to start looking
+// calculate, using the state table, which one is the last character of the syllable
+// that starts in the starting position.
+//
+static inline int khmer_nextSyllableBoundary(const TQString &s, int start, int end, bool *invalid)
+{
+ *invalid = FALSE;
+ const TQChar *uc = s.tqunicode() + start;
+ int state = 0;
+ int pos = start;
+
+ while (pos < end) {
+ KhmerCharClass charClass = getKhmerCharClass(*uc);
+ if (pos == start) {
+ *invalid = (charClass > 0) && ! (charClass & CF_CONSONANT);
+ }
+ state = khmerStateTable[state][charClass & CF_CLASS_MASK];
+
+ KHDEBUG("state[%d]=%d class=%8lx (uc=%4x)", pos - start, state,
+ charClass, uc->tqunicode() );
+
+ if (state < 0) {
+ break;
+ }
+ ++uc;
+ ++pos;
+ }
+ return pos;
+}
+
+
+#ifndef TQT_NO_XFTFREETYPE
+static const TQOpenType::Features khmer_features[] = {
+ { FT_MAKE_TAG( 'p', 'r', 'e', 'f' ), PreFormProperty },
+ { FT_MAKE_TAG( 'b', 'l', 'w', 'f' ), BelowFormProperty },
+ { FT_MAKE_TAG( 'a', 'b', 'v', 'f' ), AboveFormProperty },
+ { FT_MAKE_TAG( 'p', 's', 't', 'f' ), PostFormProperty },
+ { FT_MAKE_TAG( 'p', 'r', 'e', 's' ), PreSubstProperty },
+ { FT_MAKE_TAG( 'b', 'l', 'w', 's' ), BelowSubstProperty },
+ { FT_MAKE_TAG( 'a', 'b', 'v', 's' ), AboveSubstProperty },
+ { FT_MAKE_TAG( 'p', 's', 't', 's' ), PostSubstProperty },
+ { FT_MAKE_TAG( 'c', 'l', 'i', 'g' ), CligProperty },
+ { 0, 0 }
+};
+#endif
+
+
+static bool khmer_tqshape_syllable(TQOpenType *openType, TQShaperItem *item)
+{
+#ifndef TQT_NO_XFTFREETYPE
+ if (openType)
+ openType->selectScript(TQFont::Khmer, khmer_features);
+#endif
+ // according to the specs this is the max length one can get
+ // ### the real value should be smaller
+ assert(item->length < 13);
+
+ KHDEBUG("syllable from %d len %d, str='%s'", item->from, item->length,
+ item->string->mid(item->from, item->length).utf8().data());
+
+ int len = 0;
+ int syllableEnd = item->from + item->length;
+ unsigned short reordered[16];
+ unsigned char properties[16];
+ enum {
+ AboveForm = 0x01,
+ PreForm = 0x02,
+ PostForm = 0x04,
+ BelowForm = 0x08
+ };
+ memset(properties, 0, 16*sizeof(unsigned char));
+
+#ifdef KHMER_DEBUG
+ qDebug("original:");
+ for (int i = from; i < syllableEnd; i++) {
+ qDebug(" %d: %4x", i, string[i].tqunicode());
+ }
+#endif
+
+ // write a pre vowel or the pre part of a split vowel first
+ // and look out for coeng + ro. RO is the only vowel of type 2, and
+ // therefore the only one that requires saving space before the base.
+ //
+ int coengRo = -1; // There is no Coeng Ro, if found this value will change
+ int i;
+ for (i = item->from; i < syllableEnd; i += 1) {
+ KhmerCharClass charClass = getKhmerCharClass(item->string->at(i));
+
+ // if a split vowel, write the pre part. In Khmer the pre part
+ // is the same for all split vowels, same glyph as pre vowel C_VOWEL_E
+ if (charClass & CF_SPLIT_VOWEL) {
+ reordered[len] = C_VOWEL_E;
+ properties[len] = PreForm;
+ ++len;
+ break; // there can be only one vowel
+ }
+ // if a vowel with pos before write it out
+ if (charClass & CF_POS_BEFORE) {
+ reordered[len] = item->string->at(i).tqunicode();
+ properties[len] = PreForm;
+ ++len;
+ break; // there can be only one vowel
+ }
+ // look for coeng + ro and remember position
+ // works because coeng + ro is always in front of a vowel (if there is a vowel)
+ // and because CC_CONSONANT2 is enough to identify it, as it is the only consonant
+ // with this flag
+ if ( (charClass & CF_COENG) && (i + 1 < syllableEnd) &&
+ ( (getKhmerCharClass(item->string->at(i+1)) & CF_CLASS_MASK) == CC_CONSONANT2) ) {
+ coengRo = i;
+ }
+ }
+
+ // write coeng + ro if found
+ if (coengRo > -1) {
+ reordered[len] = C_COENG;
+ properties[len] = PreForm;
+ ++len;
+ reordered[len] = C_RO;
+ properties[len] = PreForm;
+ ++len;
+ }
+
+ // shall we add a dotted circle?
+ // If in the position in which the base should be (first char in the string) there is
+ // a character that has the Dotted circle flag (a character that cannot be a base)
+ // then write a dotted circle
+ if (getKhmerCharClass(item->string->at(item->from)) & CF_DOTTED_CIRCLE) {
+ reordered[len] = C_DOTTED_CIRCLE;
+ ++len;
+ }
+
+ // copy what is left to the output, skipping before vowels and
+ // coeng Ro if they are present
+ for (i = item->from; i < syllableEnd; i += 1) {
+ TQChar uc = item->string->at(i);
+ KhmerCharClass charClass = getKhmerCharClass(uc);
+
+ // skip a before vowel, it was already processed
+ if (charClass & CF_POS_BEFORE) {
+ continue;
+ }
+
+ // skip coeng + ro, it was already processed
+ if (i == coengRo) {
+ i += 1;
+ continue;
+ }
+
+ switch (charClass & CF_POS_MASK)
+ {
+ case CF_POS_ABOVE :
+ reordered[len] = uc.tqunicode();
+ properties[len] = AboveForm;
+ ++len;
+ break;
+
+ case CF_POS_AFTER :
+ reordered[len] = uc.tqunicode();
+ properties[len] = PostForm;
+ ++len;
+ break;
+
+ case CF_POS_BELOW :
+ reordered[len] = uc.tqunicode();
+ properties[len] = BelowForm;
+ ++len;
+ break;
+
+ default:
+ // assign the correct flags to a coeng consonant
+ // Consonants of type 3 are taged as Post forms and those type 1 as below forms
+ if ( (charClass & CF_COENG) && i + 1 < syllableEnd ) {
+ unsigned char property = (getKhmerCharClass(item->string->at(i+1)) & CF_CLASS_MASK) == CC_CONSONANT3 ?
+ PostForm : BelowForm;
+ reordered[len] = uc.tqunicode();
+ properties[len] = property;
+ ++len;
+ i += 1;
+ reordered[len] = item->string->at(i).tqunicode();
+ properties[len] = property;
+ ++len;
+ break;
+ }
+
+ // if a shifter is followed by an above vowel change the shifter to below form,
+ // an above vowel can have two possible positions i + 1 or i + 3
+ // (position i+1 corresponds to tqunicode 3, position i+3 to Unicode 4)
+ // and there is an extra rule for C_VOWEL_AA + C_SIGN_NIKAHIT also for two
+ // different positions, right after the shifter or after a vowel (Unicode 4)
+ if ( (charClass & CF_SHIFTER) && (i + 1 < syllableEnd) ) {
+ if (getKhmerCharClass(item->string->at(i+1)) & CF_ABOVE_VOWEL ) {
+ reordered[len] = uc.tqunicode();
+ properties[len] = BelowForm;
+ ++len;
+ break;
+ }
+ if (i + 2 < syllableEnd &&
+ (item->string->at(i+1).tqunicode() == C_VOWEL_AA) &&
+ (item->string->at(i+2).tqunicode() == C_SIGN_NIKAHIT) )
+ {
+ reordered[len] = uc.tqunicode();
+ properties[len] = BelowForm;
+ ++len;
+ break;
+ }
+ if (i + 3 < syllableEnd && (getKhmerCharClass(item->string->at(i+3)) & CF_ABOVE_VOWEL) ) {
+ reordered[len] = uc.tqunicode();
+ properties[len] = BelowForm;
+ ++len;
+ break;
+ }
+ if (i + 4 < syllableEnd &&
+ (item->string->at(i+3).tqunicode() == C_VOWEL_AA) &&
+ (item->string->at(i+4).tqunicode() == C_SIGN_NIKAHIT) )
+ {
+ reordered[len] = uc.tqunicode();
+ properties[len] = BelowForm;
+ ++len;
+ break;
+ }
+ }
+
+ // default - any other characters
+ reordered[len] = uc.tqunicode();
+ ++len;
+ break;
+ } // switch
+ } // for
+
+ if (item->font->stringToCMap((const TQChar *)reordered, len, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+
+ KHDEBUG("after shaping: len=%d", len);
+ for (i = 0; i < len; i++) {
+ item->attributes[i].mark = FALSE;
+ item->attributes[i].clusterStart = FALSE;
+ item->attributes[i].justification = 0;
+ item->attributes[i].zeroWidth = FALSE;
+ KHDEBUG(" %d: %4x property=%x", i, reordered[i], properties[i]);
+ }
+
+ // now we have the syllable in the right order, and can start running it through open type.
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (openType) {
+ unsigned short logClusters[16];
+ for (int i = 0; i < len; ++i)
+ logClusters[i] = i;
+
+ uint where[16];
+
+ for (int i = 0; i < len; ++i) {
+ where[i] = ~(PreSubstProperty
+ | BelowSubstProperty
+ | AboveSubstProperty
+ | PostSubstProperty
+ | CligProperty
+ | PositioningProperties);
+ if (properties[i] == PreForm)
+ where[i] &= ~PreFormProperty;
+ else if (properties[i] == BelowForm)
+ where[i] &= ~BelowFormProperty;
+ else if (properties[i] == AboveForm)
+ where[i] &= ~AboveFormProperty;
+ else if (properties[i] == PostForm)
+ where[i] &= ~PostFormProperty;
+ }
+
+ openType->tqshape(item, where);
+ if (!openType->positionAndAdd(item, FALSE))
+ return FALSE;
+ } else
+#endif
+ {
+ KHDEBUG("Not using openType");
+ TQ_UNUSED(openType);
+ }
+
+ item->attributes[0].clusterStart = TRUE;
+ return TRUE;
+}
+
+static bool khmer_tqshape(TQShaperItem *item)
+{
+ assert(item->script == TQFont::Khmer);
+
+#ifndef TQT_NO_XFTFREETYPE
+ TQOpenType *openType = item->font->openType();
+ if (openType && !openType->supportsScript(item->script))
+ openType = 0;
+#else
+ TQOpenType *openType = 0;
+#endif
+ unsigned short *logClusters = item->log_clusters;
+
+ TQShaperItem syllable = *item;
+ int first_glyph = 0;
+
+ int sstart = item->from;
+ int end = sstart + item->length;
+ KHDEBUG("khmer_tqshape: from %d length %d", item->from, item->length);
+ while (sstart < end) {
+ bool invalid;
+ int send = khmer_nextSyllableBoundary(*item->string, sstart, end, &invalid);
+ KHDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
+ invalid ? "TRUE" : "FALSE");
+ syllable.from = sstart;
+ syllable.length = send-sstart;
+ syllable.glyphs = item->glyphs + first_glyph;
+ syllable.offsets = item->offsets + first_glyph;
+ syllable.advances = item->advances + first_glyph;
+ syllable.attributes = item->attributes + first_glyph;
+ syllable.num_glyphs = item->num_glyphs - first_glyph;
+ if (!khmer_tqshape_syllable(openType, &syllable)) {
+ KHDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs);
+ item->num_glyphs += syllable.num_glyphs;
+ return FALSE;
+ }
+ item->has_positioning |= syllable.has_positioning;
+
+ // fix logcluster array
+ KHDEBUG("syllable:");
+ int i;
+ for (i = first_glyph; i < first_glyph + syllable.num_glyphs; ++i)
+ KHDEBUG(" %d -> glyph %x", i, item->glyphs[i]);
+ KHDEBUG(" logclusters:");
+ for (i = sstart; i < send; ++i) {
+ KHDEBUG(" %d -> glyph %d", i, first_glyph);
+ logClusters[i-item->from] = first_glyph;
+ }
+ sstart = send;
+ first_glyph += syllable.num_glyphs;
+ }
+ item->num_glyphs = first_glyph;
+ return TRUE;
+}
+
+static void khmer_attributes( int script, const TQString &text, int from, int len, TQCharAttributes *attributes )
+{
+ TQ_UNUSED(script);
+
+ int end = from + len;
+ const TQChar *uc = text.tqunicode() + from;
+ attributes += from;
+ int i = 0;
+ while ( i < len ) {
+ bool invalid;
+ int boundary = khmer_nextSyllableBoundary( text, from+i, end, &invalid ) - from;
+
+ attributes[i].charStop = TRUE;
+
+ if ( boundary > len-1 ) boundary = len;
+ i++;
+ while ( i < boundary ) {
+ attributes[i].charStop = FALSE;
+ ++uc;
+ ++i;
+ }
+ assert( i == boundary );
+ }
+}
+
+// --------------------------------------------------------------------------------------------------------------------------------------------
+//
+// Myanmar
+//
+// --------------------------------------------------------------------------------------------------------------------------------------------
+
+enum MymrCharClassValues
+{
+ Mymr_CC_RESERVED = 0,
+ Mymr_CC_CONSONANT = 1, /* Consonant of type 1, that has subscript form */
+ Mymr_CC_CONSONANT2 = 2, /* Consonant of type 2, that has no subscript form */
+ Mymr_CC_NGA = 3, /* Consonant NGA */
+ Mymr_CC_YA = 4, /* Consonant YA */
+ Mymr_CC_RA = 5, /* Consonant RA */
+ Mymr_CC_WA = 6, /* Consonant WA */
+ Mymr_CC_HA = 7, /* Consonant HA */
+ Mymr_CC_IND_VOWEL = 8, /* Independent vowel */
+ Mymr_CC_ZERO_WIDTH_NJ_MARK = 9, /* Zero Width non joiner character (0x200C) */
+ Mymr_CC_VIRAMA = 10, /* Subscript consonant combining character */
+ Mymr_CC_PRE_VOWEL = 11, /* Dependent vowel, prebase (Vowel e) */
+ Mymr_CC_BELOW_VOWEL = 12, /* Dependent vowel, prebase (Vowel u, uu) */
+ Mymr_CC_ABOVE_VOWEL = 13, /* Dependent vowel, prebase (Vowel i, ii, ai) */
+ Mymr_CC_POST_VOWEL = 14, /* Dependent vowel, prebase (Vowel aa) */
+ Mymr_CC_SIGN_ABOVE = 15,
+ Mymr_CC_SIGN_BELOW = 16,
+ Mymr_CC_SIGN_AFTER = 17,
+ Mymr_CC_ZERO_WIDTH_J_MARK = 18, /* Zero width joiner character */
+ Mymr_CC_COUNT = 19 /* This is the number of character classes */
+};
+
+enum MymrCharClassFlags
+{
+ Mymr_CF_CLASS_MASK = 0x0000FFFF,
+
+ Mymr_CF_CONSONANT = 0x01000000, /* flag to speed up comparing */
+ Mymr_CF_MEDIAL = 0x02000000, /* flag to speed up comparing */
+ Mymr_CF_IND_VOWEL = 0x04000000, /* flag to speed up comparing */
+ Mymr_CF_DEP_VOWEL = 0x08000000, /* flag to speed up comparing */
+ Mymr_CF_DOTTED_CIRCLE = 0x10000000, /* add a dotted circle if a character with this flag is the first in a syllable */
+ Mymr_CF_VIRAMA = 0x20000000, /* flag to speed up comparing */
+
+ /* position flags */
+ Mymr_CF_POS_BEFORE = 0x00080000,
+ Mymr_CF_POS_BELOW = 0x00040000,
+ Mymr_CF_POS_ABOVE = 0x00020000,
+ Mymr_CF_POS_AFTER = 0x00010000,
+ Mymr_CF_POS_MASK = 0x000f0000,
+
+ Mymr_CF_AFTER_KINZI = 0x00100000
+};
+
+/* Characters that get refrered to by name */
+enum MymrChar
+{
+ Mymr_C_SIGN_ZWNJ = 0x200C,
+ Mymr_C_SIGN_ZWJ = 0x200D,
+ Mymr_C_DOTTED_CIRCLE = 0x25CC,
+ Mymr_C_RA = 0x101B,
+ Mymr_C_YA = 0x101A,
+ Mymr_C_NGA = 0x1004,
+ Mymr_C_VOWEL_E = 0x1031,
+ Mymr_C_VIRAMA = 0x1039
+};
+
+enum
+{
+ Mymr_xx = Mymr_CC_RESERVED,
+ Mymr_c1 = Mymr_CC_CONSONANT | Mymr_CF_CONSONANT | Mymr_CF_POS_BELOW,
+ Mymr_c2 = Mymr_CC_CONSONANT2 | Mymr_CF_CONSONANT,
+ Mymr_ng = Mymr_CC_NGA | Mymr_CF_CONSONANT | Mymr_CF_POS_ABOVE,
+ Mymr_ya = Mymr_CC_YA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_AFTER | Mymr_CF_AFTER_KINZI,
+ Mymr_ra = Mymr_CC_RA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BEFORE,
+ Mymr_wa = Mymr_CC_WA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BELOW,
+ Mymr_ha = Mymr_CC_HA | Mymr_CF_CONSONANT | Mymr_CF_MEDIAL | Mymr_CF_POS_BELOW,
+ Mymr_id = Mymr_CC_IND_VOWEL | Mymr_CF_IND_VOWEL,
+ Mymr_vi = Mymr_CC_VIRAMA | Mymr_CF_VIRAMA | Mymr_CF_POS_ABOVE | Mymr_CF_DOTTED_CIRCLE,
+ Mymr_dl = Mymr_CC_PRE_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_BEFORE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
+ Mymr_db = Mymr_CC_BELOW_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_BELOW | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
+ Mymr_da = Mymr_CC_ABOVE_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_ABOVE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
+ Mymr_dr = Mymr_CC_POST_VOWEL | Mymr_CF_DEP_VOWEL | Mymr_CF_POS_AFTER | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI,
+ Mymr_sa = Mymr_CC_SIGN_ABOVE | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_POS_ABOVE | Mymr_CF_AFTER_KINZI,
+ Mymr_sb = Mymr_CC_SIGN_BELOW | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_POS_BELOW | Mymr_CF_AFTER_KINZI,
+ Mymr_sp = Mymr_CC_SIGN_AFTER | Mymr_CF_DOTTED_CIRCLE | Mymr_CF_AFTER_KINZI
+};
+
+
+typedef int MymrCharClass;
+
+
+static const MymrCharClass mymrCharClasses[] =
+{
+ Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_ng, Mymr_c1, Mymr_c1, Mymr_c1,
+ Mymr_c1, Mymr_c1, Mymr_c2, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, /* 1000 - 100F */
+ Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1, Mymr_c1,
+ Mymr_c1, Mymr_c1, Mymr_ya, Mymr_ra, Mymr_c1, Mymr_wa, Mymr_c1, Mymr_ha, /* 1010 - 101F */
+ Mymr_c2, Mymr_c2, Mymr_xx, Mymr_id, Mymr_id, Mymr_id, Mymr_id, Mymr_id,
+ Mymr_xx, Mymr_id, Mymr_id, Mymr_xx, Mymr_dr, Mymr_da, Mymr_da, Mymr_db, /* 1020 - 102F */
+ Mymr_db, Mymr_dl, Mymr_da, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_sa, Mymr_sb,
+ Mymr_sp, Mymr_vi, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1030 - 103F */
+ Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx,
+ Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1040 - 104F */
+ Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx,
+ Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, Mymr_xx, /* 1050 - 105F */
+};
+
+static MymrCharClass
+getMyanmarCharClass (const TQChar &ch)
+{
+ if (ch.tqunicode() == Mymr_C_SIGN_ZWJ)
+ return Mymr_CC_ZERO_WIDTH_J_MARK;
+
+ if (ch.tqunicode() == Mymr_C_SIGN_ZWNJ)
+ return Mymr_CC_ZERO_WIDTH_NJ_MARK;
+
+ if (ch.tqunicode() < 0x1000 || ch.tqunicode() > 0x105f)
+ return Mymr_CC_RESERVED;
+
+ return mymrCharClasses[ch.tqunicode() - 0x1000];
+}
+
+static const signed char mymrStateTable[][Mymr_CC_COUNT] =
+{
+// xx c1, c2 ng ya ra wa ha id zwnj vi dl db da dr sa sb sp zwj
+ { 1, 4, 4, 2, 4, 4, 4, 4, 24, 1, 27, 17, 18, 19, 20, 21, 1, 1, 4}, // 0 - ground state
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 1 - exit state (or sp to the right of the syllable)
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 17, 18, 19, 20, 21, -1, -1, 4}, // 2 - NGA
+ {-1, 4, 4, 4, 4, 4, 4, 4, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 3 - Virama after NGA
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 5, 17, 18, 19, 20, 21, 1, 1, -1}, // 4 - Base consonant
+ {-2, 6, -2, -2, 7, 8, 9, 10, -2, 23, -2, -2, -2, -2, -2, -2, -2, -2, -2}, // 5 - First virama
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 25, 17, 18, 19, 20, 21, -1, -1, -1}, // 6 - c1 after virama
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, // 7 - ya after virama
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, // 8 - ra after virama
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, -1, -1}, // 9 - wa after virama
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, // 10 - ha after virama
+ {-1, -1, -1, -1, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 11 - Virama after NGA+zwj
+ {-2, -2, -2, -2, -2, -2, 13, 14, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, // 12 - Second virama
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 15, 17, 18, 19, 20, 21, -1, -1, -1}, // 13 - wa after virama
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, // 14 - ha after virama
+ {-2, -2, -2, -2, -2, -2, -2, 16, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, // 15 - Third virama
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 17, 18, 19, 20, 21, -1, -1, -1}, // 16 - ha after virama
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 20, 21, 1, 1, -1}, // 17 - dl, Dependent vowel e
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, -1, 21, 1, 1, -1}, // 18 - db, Dependent vowel u,uu
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1}, // 19 - da, Dependent vowel i,ii,ai
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, 1, 1, -1}, // 20 - dr, Dependent vowel aa
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1}, // 21 - sa, Sign anusvara
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 22 - atha
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1}, // 23 - zwnj for atha
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1}, // 24 - Independent vowel
+ {-2, -2, -2, -2, 26, 26, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2}, // 25 - Virama after subscript consonant
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 17, 18, 19, 20, 21, -1, 1, -1}, // 26 - ra/ya after subscript consonant + virama
+ {-1, 6, -1, -1, 7, 8, 9, 10, -1, 23, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // 27 - Virama after ground state
+// exit state -2 is for invalid order of medials and combination of invalids
+// with virama where virama should treat as start of next syllable
+};
+
+
+
+// #define MYANMAR_DEBUG
+#ifdef MYANMAR_DEBUG
+#define MMDEBUG qDebug
+#else
+#define MMDEBUG if(0) qDebug
+#endif
+
+// Given an input string of characters and a location in which to start looking
+// calculate, using the state table, which one is the last character of the syllable
+// that starts in the starting position.
+//
+static inline int myanmar_nextSyllableBoundary(const TQString &s, int start, int end, bool *invalid)
+{
+ *invalid = FALSE;
+ const TQChar *uc = s.tqunicode() + start;
+ int state = 0;
+ int pos = start;
+
+ while (pos < end) {
+ MymrCharClass charClass = getMyanmarCharClass(*uc);
+ state = mymrStateTable[state][charClass & Mymr_CF_CLASS_MASK];
+ if (pos == start)
+ *invalid = charClass & Mymr_CF_DOTTED_CIRCLE;
+
+ MMDEBUG("state[%d]=%d class=%8x (uc=%4x)", pos - start, state, charClass, uc->tqunicode() );
+
+ if (state < 0) {
+ if (state < -1)
+ --pos;
+ break;
+ }
+ ++uc;
+ ++pos;
+ }
+ return pos;
+}
+
+
+#ifndef TQT_NO_XFTFREETYPE
+// ###### might have to change order of above and below forms and substitutions,
+// but according to Unicode below comes before above
+static const TQOpenType::Features myanmar_features[] = {
+ { FT_MAKE_TAG( 'p', 'r', 'e', 'f' ), PreFormProperty },
+ { FT_MAKE_TAG( 'b', 'l', 'w', 'f' ), BelowFormProperty },
+ { FT_MAKE_TAG( 'a', 'b', 'v', 'f' ), AboveFormProperty },
+ { FT_MAKE_TAG( 'p', 's', 't', 'f' ), PostFormProperty },
+ { FT_MAKE_TAG( 'p', 'r', 'e', 's' ), PreSubstProperty },
+ { FT_MAKE_TAG( 'b', 'l', 'w', 's' ), BelowSubstProperty },
+ { FT_MAKE_TAG( 'a', 'b', 'v', 's' ), AboveSubstProperty },
+ { FT_MAKE_TAG( 'p', 's', 't', 's' ), PostSubstProperty },
+ { FT_MAKE_TAG( 'r', 'l', 'i', 'g' ), CligProperty }, // Myanmar1 uses this instead of the other features
+ { 0, 0 }
+};
+#endif
+
+
+// Visual order before shaping should be:
+//
+// [Vowel Mark E]
+// [Virama + Medial Ra]
+// [Base]
+// [Virama + Consonant]
+// [Nga + Virama] (Kinzi) ### should probably come before post forms (medial ya)
+// [Vowels]
+// [Marks]
+//
+// This means that we can keep the logical order apart from having to
+// move the pre vowel, medial ra and kinzi
+
+static bool myanmar_tqshape_syllable(TQOpenType *openType, TQShaperItem *item, bool invalid)
+{
+#ifndef TQT_NO_XFTFREETYPE
+ if (openType)
+ openType->selectScript(TQFont::Myanmar, myanmar_features);
+#endif
+ // according to the table the max length of a syllable should be around 14 chars
+ assert(item->length < 32);
+
+ MMDEBUG("\nsyllable from %d len %d, str='%s'", item->from, item->length,
+ item->string->mid(item->from, item->length).utf8().data());
+
+ const TQChar *uc = item->string->tqunicode() + item->from;
+#ifdef MYANMAR_DEBUG
+ qDebug("original:");
+ for (int i = 0; i < item->length; i++) {
+ qDebug(" %d: %4x", i, uc[i].tqunicode());
+ }
+#endif
+ int vowel_e = -1;
+ int kinzi = -1;
+ int medial_ra = -1;
+ int base = -1;
+ int i;
+ for (i = 0; i < item->length; ++i) {
+ ushort chr = uc[i].tqunicode();
+
+ if (chr == Mymr_C_VOWEL_E) {
+ vowel_e = i;
+ continue;
+ }
+ if (i == 0
+ && chr == Mymr_C_NGA
+ && i + 2 < item->length
+ && uc[i+1].tqunicode() == Mymr_C_VIRAMA) {
+ int mc = getMyanmarCharClass(uc[i+2]);
+ //MMDEBUG("maybe kinzi: mc=%x", mc);
+ if ((mc & Mymr_CF_CONSONANT) == Mymr_CF_CONSONANT) {
+ kinzi = i;
+ continue;
+ }
+ }
+ if (base >= 0
+ && chr == Mymr_C_VIRAMA
+ && i + 1 < item->length
+ && uc[i+1].tqunicode() == Mymr_C_RA) {
+ medial_ra = i;
+ continue;
+ }
+ if (base < 0)
+ base = i;
+ }
+
+ MMDEBUG("\n base=%d, vowel_e=%d, kinzi=%d, medial_ra=%d", base, vowel_e, kinzi, medial_ra);
+ int len = 0;
+ unsigned short reordered[32];
+ unsigned char properties[32];
+ enum {
+ AboveForm = 0x01,
+ PreForm = 0x02,
+ PostForm = 0x04,
+ BelowForm = 0x08
+ };
+ memset(properties, 0, 32*sizeof(unsigned char));
+
+ // write vowel_e if found
+ if (vowel_e >= 0) {
+ reordered[0] = Mymr_C_VOWEL_E;
+ len = 1;
+ }
+ // write medial_ra
+ if (medial_ra >= 0) {
+ reordered[len] = Mymr_C_VIRAMA;
+ reordered[len+1] = Mymr_C_RA;
+ properties[len] = PreForm;
+ properties[len+1] = PreForm;
+ len += 2;
+ }
+
+ // shall we add a dotted circle?
+ // If in the position in which the base should be (first char in the string) there is
+ // a character that has the Dotted circle flag (a character that cannot be a base)
+ // then write a dotted circle
+ if (invalid) {
+ reordered[len] = C_DOTTED_CIRCLE;
+ ++len;
+ }
+
+ bool lastWasVirama = FALSE;
+ int basePos = -1;
+ // copy the rest of the syllable to the output, inserting the kinzi
+ // at the correct place
+ for (i = 0; i < item->length; ++i) {
+ if (i == vowel_e)
+ continue;
+ if (i == medial_ra || i == kinzi) {
+ ++i;
+ continue;
+ }
+
+ ushort chr = uc[i].tqunicode();
+ MymrCharClass cc = getMyanmarCharClass(uc[i]);
+ if (kinzi >= 0 && i > base && (cc & Mymr_CF_AFTER_KINZI)) {
+ reordered[len] = Mymr_C_NGA;
+ reordered[len+1] = Mymr_C_VIRAMA;
+ properties[len-1] = AboveForm;
+ properties[len] = AboveForm;
+ len += 2;
+ kinzi = -1;
+ }
+
+ if (lastWasVirama) {
+ int prop = 0;
+ switch(cc & Mymr_CF_POS_MASK) {
+ case Mymr_CF_POS_BEFORE:
+ prop = PreForm;
+ break;
+ case Mymr_CF_POS_BELOW:
+ prop = BelowForm;
+ break;
+ case Mymr_CF_POS_ABOVE:
+ prop = AboveForm;
+ break;
+ case Mymr_CF_POS_AFTER:
+ prop = PostForm;
+ break;
+ default:
+ break;
+ }
+ properties[len-1] = prop;
+ properties[len] = prop;
+ if(basePos >= 0 && basePos == len-2)
+ properties[len-2] = prop;
+ }
+ lastWasVirama = (chr == Mymr_C_VIRAMA);
+ if(i == base)
+ basePos = len;
+
+ if ((chr != Mymr_C_SIGN_ZWNJ && chr != Mymr_C_SIGN_ZWJ) || !len) {
+ reordered[len] = chr;
+ ++len;
+ }
+ }
+ if (kinzi >= 0) {
+ reordered[len] = Mymr_C_NGA;
+ reordered[len+1] = Mymr_C_VIRAMA;
+ properties[len] = AboveForm;
+ properties[len+1] = AboveForm;
+ len += 2;
+ }
+
+ if (item->font->stringToCMap((const TQChar *)reordered, len, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+
+ MMDEBUG("after shaping: len=%d", len);
+ for (i = 0; i < len; i++) {
+ item->attributes[i].mark = FALSE;
+ item->attributes[i].clusterStart = FALSE;
+ item->attributes[i].justification = 0;
+ item->attributes[i].zeroWidth = FALSE;
+ MMDEBUG(" %d: %4x property=%x", i, reordered[i], properties[i]);
+ }
+
+ // now we have the syllable in the right order, and can start running it through open type.
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (openType) {
+ unsigned short logClusters[32];
+ for (int i = 0; i < len; ++i)
+ logClusters[i] = i;
+
+ uint where[32];
+
+ for (int i = 0; i < len; ++i) {
+ where[i] = ~(PreSubstProperty
+ | BelowSubstProperty
+ | AboveSubstProperty
+ | PostSubstProperty
+ | CligProperty
+ | PositioningProperties);
+ if (properties[i] == PreForm)
+ where[i] &= ~PreFormProperty;
+ else if (properties[i] == BelowForm)
+ where[i] &= ~BelowFormProperty;
+ else if (properties[i] == AboveForm)
+ where[i] &= ~AboveFormProperty;
+ else if (properties[i] == PostForm)
+ where[i] &= ~PostFormProperty;
+ }
+
+ openType->tqshape(item, where);
+ if (!openType->positionAndAdd(item, FALSE))
+ return FALSE;
+ } else
+#endif
+ {
+ MMDEBUG("Not using openType");
+ TQ_UNUSED(openType);
+ }
+
+ item->attributes[0].clusterStart = TRUE;
+ return TRUE;
+}
+
+static bool myanmar_tqshape(TQShaperItem *item)
+{
+ assert(item->script == TQFont::Myanmar);
+
+#ifndef TQT_NO_XFTFREETYPE
+ TQOpenType *openType = item->font->openType();
+ if (openType && !openType->supportsScript(item->script))
+ openType = 0;
+#else
+ TQOpenType *openType = 0;
+#endif
+ unsigned short *logClusters = item->log_clusters;
+
+ TQShaperItem syllable = *item;
+ int first_glyph = 0;
+
+ int sstart = item->from;
+ int end = sstart + item->length;
+ MMDEBUG("myanmar_tqshape: from %d length %d", item->from, item->length);
+ while (sstart < end) {
+ bool invalid;
+ int send = myanmar_nextSyllableBoundary(*item->string, sstart, end, &invalid);
+ MMDEBUG("syllable from %d, length %d, invalid=%s", sstart, send-sstart,
+ invalid ? "TRUE" : "FALSE");
+ syllable.from = sstart;
+ syllable.length = send-sstart;
+ syllable.glyphs = item->glyphs + first_glyph;
+ syllable.offsets = item->offsets + first_glyph;
+ syllable.advances = item->advances + first_glyph;
+ syllable.attributes = item->attributes + first_glyph;
+ syllable.num_glyphs = item->num_glyphs - first_glyph;
+ if (!myanmar_tqshape_syllable(openType, &syllable, invalid)) {
+ MMDEBUG("syllable shaping failed, syllable requests %d glyphs", syllable.num_glyphs);
+ item->num_glyphs += syllable.num_glyphs;
+ return FALSE;
+ }
+ item->has_positioning |= syllable.has_positioning;
+
+ // fix logcluster array
+ MMDEBUG("syllable:");
+ int i;
+ for (i = first_glyph; i < first_glyph + syllable.num_glyphs; ++i)
+ MMDEBUG(" %d -> glyph %x", i, item->glyphs[i]);
+ MMDEBUG(" logclusters:");
+ for (i = sstart; i < send; ++i) {
+ MMDEBUG(" %d -> glyph %d", i, first_glyph);
+ logClusters[i-item->from] = first_glyph;
+ }
+ sstart = send;
+ first_glyph += syllable.num_glyphs;
+ }
+ item->num_glyphs = first_glyph;
+ return TRUE;
+}
+
+static void myanmar_attributes( int script, const TQString &text, int from, int len, TQCharAttributes *attributes )
+{
+ TQ_UNUSED(script);
+
+ int end = from + len;
+ const TQChar *uc = text.tqunicode() + from;
+ attributes += from;
+ int i = 0;
+ while ( i < len ) {
+ bool invalid;
+ int boundary = myanmar_nextSyllableBoundary( text, from+i, end, &invalid ) - from;
+
+ attributes[i].charStop = TRUE;
+ attributes[i].softBreak = TRUE;
+
+ if ( boundary > len-1 ) boundary = len;
+ i++;
+ while ( i < boundary ) {
+ attributes[i].charStop = FALSE;
+ attributes[i].softBreak = FALSE;
+ ++uc;
+ ++i;
+ }
+ assert( i == boundary );
+ }
+}
+
+// --------------------------------------------------------------------------------------------------------------------------------------------
+//
+// Hangul
+//
+// --------------------------------------------------------------------------------------------------------------------------------------------
+
+// Hangul is a syllable based script. Unicode reserves a large range
+// for precomposed hangul, where syllables are already precomposed to
+// their final glyph tqshape. In addition, a so called jamo range is
+// defined, that can be used to express old Hangul. Modern hangul
+// syllables can also be expressed as jamo, and should be composed
+// into syllables. The operation is rather simple and mathematical.
+
+// Every hangul jamo is classified as being either a Leading consonant
+// (L), and intermediat Vowel (V) or a trailing consonant (T). Modern
+// hangul syllables (the ones in the precomposed area can be of type
+// LV or LVT.
+//
+// Syllable breaks do _not_ occur between:
+//
+// L L, V or precomposed
+// V, LV V, T
+// LVT, T T
+//
+// A standard syllable is of the form L+V+T*. The above rules allow
+// nonstandard syllables L*V*T*. To transform them into standard
+// syllables fill characers L_f and V_f can be inserted.
+
+enum {
+ Hangul_SBase = 0xac00,
+ Hangul_LBase = 0x1100,
+ Hangul_VBase = 0x1161,
+ Hangul_TBase = 0x11a7,
+ Hangul_SCount = 11172,
+ Hangul_LCount = 19,
+ Hangul_VCount = 21,
+ Hangul_TCount = 28,
+ Hangul_NCount = 21*28
+};
+
+static inline bool hangul_isPrecomposed(unsigned short uc) {
+ return (uc >= Hangul_SBase && uc < Hangul_SBase + Hangul_SCount);
+}
+
+static inline bool hangul_isLV(unsigned short uc) {
+ return ((uc - Hangul_SBase) % Hangul_TCount == 0);
+}
+
+enum HangulType {
+ L,
+ V,
+ T,
+ LV,
+ LVT,
+ X
+};
+
+static inline HangulType hangul_type(unsigned short uc) {
+ if (uc > Hangul_SBase && uc < Hangul_SBase + Hangul_SCount)
+ return hangul_isLV(uc) ? LV : LVT;
+ if (uc < Hangul_LBase || uc > 0x11ff)
+ return X;
+ if (uc < Hangul_VBase)
+ return L;
+ if (uc < Hangul_TBase)
+ return V;
+ return T;
+}
+
+static int hangul_nextSyllableBoundary(const TQString &s, int start, int end)
+{
+ const TQChar *uc = s.tqunicode() + start;
+
+ HangulType state = hangul_type(uc->tqunicode());
+ int pos = 1;
+
+ while (pos < end - start) {
+ HangulType newState = hangul_type(uc[pos].tqunicode());
+ switch(newState) {
+ case X:
+ goto finish;
+ case L:
+ case V:
+ case T:
+ if (state > newState)
+ goto finish;
+ state = newState;
+ break;
+ case LV:
+ if (state > L)
+ goto finish;
+ state = V;
+ break;
+ case LVT:
+ if (state > L)
+ goto finish;
+ state = T;
+ }
+ ++pos;
+ }
+
+ finish:
+ return start+pos;
+}
+
+#ifndef TQT_NO_XFTFREETYPE
+static const TQOpenType::Features hangul_features [] = {
+ { FT_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty },
+ { FT_MAKE_TAG('l', 'j', 'm', 'o'), CcmpProperty },
+ { FT_MAKE_TAG('j', 'j', 'm', 'o'), CcmpProperty },
+ { FT_MAKE_TAG('t', 'j', 'm', 'o'), CcmpProperty },
+ { 0, 0 }
+};
+#endif
+
+static bool hangul_tqshape_syllable(TQOpenType *openType, TQShaperItem *item)
+{
+ TQ_UNUSED(openType)
+ const TQChar *ch = item->string->tqunicode() + item->from;
+
+ int i;
+ unsigned short composed = 0;
+ // see if we can compose the syllable into a modern hangul
+ if (item->length == 2) {
+ int LIndex = ch[0].tqunicode() - Hangul_LBase;
+ int VIndex = ch[1].tqunicode() - Hangul_VBase;
+ if (LIndex >= 0 && LIndex < Hangul_LCount &&
+ VIndex >= 0 && VIndex < Hangul_VCount)
+ composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + Hangul_SBase;
+ } else if (item->length == 3) {
+ int LIndex = ch[0].tqunicode() - Hangul_LBase;
+ int VIndex = ch[1].tqunicode() - Hangul_VBase;
+ int TIndex = ch[2].tqunicode() - Hangul_TBase;
+ if (LIndex >= 0 && LIndex < Hangul_LCount &&
+ VIndex >= 0 && VIndex < Hangul_VCount &&
+ TIndex >= 0 && TIndex < Hangul_TCount)
+ composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + TIndex + Hangul_SBase;
+ }
+
+
+ int len = item->length;
+ TQChar c(composed);
+
+ // ### icc says 'chars' is unused
+ // const TQChar *chars = ch;
+
+ // if we have a modern hangul use the composed form
+ if (composed) {
+ // chars = &c;
+ len = 1;
+ }
+
+ if (item->font->stringToCMap(ch, len, item->glyphs, item->advances,
+ &item->num_glyphs, item->flags & TQTextEngine::RightToLeft) != TQFontEngine::NoError)
+ return FALSE;
+ for (i = 0; i < len; i++) {
+ item->attributes[i].mark = FALSE;
+ item->attributes[i].clusterStart = FALSE;
+ item->attributes[i].justification = 0;
+ item->attributes[i].zeroWidth = FALSE;
+ IDEBUG(" %d: %4x", i, ch[i].tqunicode());
+ }
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (openType && !composed) {
+
+ TQVarLengthArray<unsigned short> logClusters(len);
+ for (i = 0; i < len; ++i)
+ logClusters[i] = i;
+ item->log_clusters = logClusters.data();
+
+ openType->tqshape(item);
+ if (!openType->positionAndAdd(item, FALSE))
+ return FALSE;
+
+ }
+#endif
+
+ item->attributes[0].clusterStart = TRUE;
+ return TRUE;
+}
+
+static bool hangul_tqshape(TQShaperItem *item)
+{
+ TQ_ASSERT(item->script == TQFont::Hangul);
+
+ const TQChar *uc = item->string->tqunicode() + item->from;
+
+ bool allPrecomposed = TRUE;
+ for (int i = 0; i < item->length; ++i) {
+ if (!hangul_isPrecomposed(uc[i].tqunicode())) {
+ allPrecomposed = FALSE;
+ break;
+ }
+ }
+
+ if (!allPrecomposed) {
+#ifndef TQT_NO_XFTFREETYPE
+ TQOpenType *openType = item->font->openType();
+ if (openType && !openType->supportsScript(item->script))
+ openType = 0;
+ if (openType)
+ openType->selectScript(TQFont::Hangul, hangul_features);
+#else
+ TQOpenType *openType = 0;
+#endif
+
+ unsigned short *logClusters = item->log_clusters;
+
+ TQShaperItem syllable = *item;
+ int first_glyph = 0;
+
+ int sstart = item->from;
+ int end = sstart + item->length;
+ while (sstart < end) {
+ int send = hangul_nextSyllableBoundary(*(item->string), sstart, end);
+
+ syllable.from = sstart;
+ syllable.length = send-sstart;
+ syllable.glyphs = item->glyphs + first_glyph;
+ syllable.offsets = item->offsets + first_glyph;
+ syllable.advances = item->advances + first_glyph;
+ syllable.attributes = item->attributes + first_glyph;
+ syllable.num_glyphs = item->num_glyphs - first_glyph;
+ if (!hangul_tqshape_syllable(openType, &syllable)) {
+ item->num_glyphs += syllable.num_glyphs;
+ return FALSE;
+ }
+ item->has_positioning |= syllable.has_positioning;
+ // fix logcluster array
+ for (int i = sstart; i < send; ++i)
+ logClusters[i-item->from] = first_glyph;
+ sstart = send;
+ first_glyph += syllable.num_glyphs;
+ }
+ item->num_glyphs = first_glyph;
+ return TRUE;
+ }
+
+ return basic_tqshape(item);
+}
+
+static void hangul_attributes(int script, const TQString &text, int from, int len, TQCharAttributes *attributes)
+{
+ TQ_UNUSED(script);
+
+ int end = from + len;
+ const TQChar *uc = text.tqunicode() + from;
+ attributes += from;
+ int i = 0;
+ while (i < len) {
+ int boundary = hangul_nextSyllableBoundary(text, from+i, end) - from;
+
+ attributes[i].charStop = TRUE;
+
+ if (boundary > len-1) boundary = len;
+ i++;
+ while (i < boundary) {
+ attributes[i].charStop = FALSE;
+ ++uc;
+ ++i;
+ }
+ assert(i == boundary);
+ }
+}
+
+// -----------------------------------------------------------------------------------------------
+//
+// The script engine jump table
+//
+// -----------------------------------------------------------------------------------------------
+
+const q_scriptEngine scriptEngines[] = {
+ // Latin,
+ { basic_tqshape, 0 },
+ // Greek,
+ { basic_tqshape, 0 },
+ // Cyrillic,
+ { basic_tqshape, 0 },
+ // Armenian,
+ { basic_tqshape, 0 },
+ // Georgian,
+ { basic_tqshape, 0 },
+ // Runic,
+ { basic_tqshape, 0 },
+ // Ogham,
+ { basic_tqshape, 0 },
+ // SpacingModifiers,
+ { basic_tqshape, 0 },
+ // CombiningMarks,
+ { basic_tqshape, 0 },
+
+ // // Middle Eastern Scripts
+ // Hebrew,
+ { hebrew_tqshape, 0 },
+ // Arabic,
+ { arabic_tqshape, 0 },
+ // Syriac,
+ { syriac_tqshape, 0 },
+ // Thaana,
+ { thaana_tqshape, 0 },
+
+ // // South and Southeast Asian Scripts
+ // Devanagari,
+ { indic_tqshape, indic_attributes },
+ // Bengali,
+ { indic_tqshape, indic_attributes },
+ // Gurmukhi,
+ { indic_tqshape, indic_attributes },
+ // Gujarati,
+ { indic_tqshape, indic_attributes },
+ // Oriya,
+ { indic_tqshape, indic_attributes },
+ // Tamil,
+ { indic_tqshape, indic_attributes },
+ // Telugu,
+ { indic_tqshape, indic_attributes },
+ // Kannada,
+ { indic_tqshape, indic_attributes },
+ // Malayalam,
+ { indic_tqshape, indic_attributes },
+ // Sinhala,
+ { indic_tqshape, indic_attributes },
+ // Thai,
+ { basic_tqshape, thai_attributes },
+ // Lao,
+ { basic_tqshape, thai_attributes },
+ // Tibetan,
+ { tibetan_tqshape, tibetan_attributes },
+ // Myanmar,
+ { myanmar_tqshape, myanmar_attributes },
+ // Khmer,
+ { khmer_tqshape, khmer_attributes },
+
+ // // East Asian Scripts
+ // Han,
+ { basic_tqshape, 0 },
+ // Hiragana,
+ { basic_tqshape, 0 },
+ // Katakana,
+ { basic_tqshape, 0 },
+ // Hangul,
+ { hangul_tqshape, hangul_attributes },
+ // Bopomofo,
+ { basic_tqshape, 0 },
+ // Yi,
+ { basic_tqshape, 0 },
+
+ // // Additional Scripts
+ // Ethiopic,
+ { basic_tqshape, 0 },
+ // Cherokee,
+ { basic_tqshape, 0 },
+ // CanadianAboriginal,
+ { basic_tqshape, 0 },
+ // Mongolian,
+ { basic_tqshape, 0 },
+
+ // // Symbols
+ // CurrencySymbols,
+ { basic_tqshape, 0 },
+ // LetterlikeSymbols,
+ { basic_tqshape, 0 },
+ // NumberForms,
+ { basic_tqshape, 0 },
+ // MathematicalOperators,
+ { basic_tqshape, 0 },
+ // TechnicalSymbols,
+ { basic_tqshape, 0 },
+ // GeometricSymbols,
+ { basic_tqshape, 0 },
+ // MiscellaneousSymbols,
+ { basic_tqshape, 0 },
+ // EnclosedAndSquare,
+ { basic_tqshape, 0 },
+ // Braille,
+ { basic_tqshape, 0 },
+
+ // Unicode,
+ { basic_tqshape, 0 },
+ //Tagalog,
+ { basic_tqshape, 0 },
+ //Hanunoo,
+ { basic_tqshape, 0 },
+ //Buhid,
+ { basic_tqshape, 0 },
+ //Tagbanwa,
+ { basic_tqshape, 0 },
+ // KatakanaHalfWidth
+ { basic_tqshape, 0 },
+ // Limbu
+ { basic_tqshape, 0 },
+ // TaiLe
+ { basic_tqshape, 0 }
+};
diff --git a/tqtinterface/qt4/src/kernel/tqsession.h b/tqtinterface/qt4/src/kernel/tqsession.h
new file mode 100644
index 0000000..6c7a800
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsession.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Definition of TQSession class
+**
+** Created : 990510
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSESSION_H
+#define TQSESSION_H
+
+#ifndef TQT_H
+#endif // TQT_H
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqsessionmanager.h b/tqtinterface/qt4/src/kernel/tqsessionmanager.h
new file mode 100644
index 0000000..d537270
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsessionmanager.h
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Definition of TQSessionManager class
+**
+** Created : 990510
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSESSIONMANAGER_H
+#define TQSESSIONMANAGER_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqwindowdefs.h"
+#include "tqstring.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+#include "tqapplication.h"
+// Nasty, nasty horrid HACK to get access to QSessionManager's private members
+// This is TERRIBLE and I wish there was a way around it
+// This is a good example of the new, broken & irritating Qt4 API,
+// and the corresponding loss in functionality versus Qt3.
+// See also tqrect.cpp
+#define private protected
+#include <Qt/qsessionmanager.h>
+#undef private
+#endif // USE_QT4
+
+#ifndef TQT_NO_SESSIONMANAGER
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQSessionManager : public QSessionManager, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQSessionManager( QApplication *app, QString id, QString key ) : QSessionManager( app, id, key ) {}
+
+ inline TQStringList restartCommand() const {
+ QStringList ql = QSessionManager::restartCommand();
+ TQStringList tqsl;
+ tqsl.clear();
+ for (int i = 0; i < ql.size(); ++i) tqsl.append(ql.at(i));
+ return tqsl;
+ }
+
+ inline TQStringList discardCommand() const {
+ QStringList ql = QSessionManager::discardCommand();
+ TQStringList tqsl;
+ tqsl.clear();
+ for (int i = 0; i < ql.size(); ++i) tqsl.append(ql.at(i));
+ return tqsl;
+ }
+
+ inline void setRestartCommand( const TQStringList& tqsl ) {
+ QStringList ql;
+ ql.clear();
+ for ( TQStringList::ConstIterator it = tqsl.begin(); it != tqsl.end(); ++it ) ql.append(*it);
+ QSessionManager::setRestartCommand(ql);
+ }
+
+ inline void setDiscardCommand( const TQStringList& tqsl ) {
+ QStringList ql;
+ ql.clear();
+ for ( TQStringList::ConstIterator it = tqsl.begin(); it != tqsl.end(); ++it ) ql.append(*it);
+ QSessionManager::setDiscardCommand(ql);
+ }
+
+ // Interoperability
+ static TQSessionManager& convertFromQSessionManager( QSessionManager& qsm );
+ static const TQSessionManager& convertFromQSessionManager( const QSessionManager& qsm );
+};
+
+// Interoperability
+inline static TQSessionManager& convertFromQSessionManager( QSessionManager& qsm ) {
+ return (*static_cast<TQSessionManager*>(&qsm));
+}
+inline static const TQSessionManager& convertFromQSessionManager( const QSessionManager& qsm ) {
+ return (*static_cast<const TQSessionManager*>(&qsm));
+}
+
+#else // USE_QT4
+
+class TQSessionManagerData;
+
+class TQ_EXPORT TQSessionManager : public TQObject
+{
+ TQ_OBJECT
+ TQSessionManager( TQApplication *app, TQString &id, TQString &key );
+ ~TQSessionManager();
+public:
+ TQString sessionId() const;
+ TQString sessionKey() const;
+#if defined(TQ_WS_X11) || defined(TQ_WS_MAC)
+ void* handle() const;
+#endif
+
+ bool allowsInteraction();
+ bool allowsErrorInteraction();
+ void release();
+
+ void cancel();
+
+ enum RestartHint {
+ RestartIfRunning,
+ RestartAnyway,
+ RestartImmediately,
+ RestartNever
+ };
+ void setRestartHint( RestartHint );
+ RestartHint restartHint() const;
+
+ void setRestartCommand( const TQStringList& );
+ TQStringList restartCommand() const;
+ void setDiscardCommand( const TQStringList& );
+ TQStringList discardCommand() const;
+
+ void setManagerProperty( const TQString& name, const TQString& value );
+ void setManagerProperty( const TQString& name, const TQStringList& value );
+
+ bool isPhase2() const;
+ void requestPhase2();
+
+private:
+ friend class TQApplication;
+ friend class TQBaseApplication;
+ TQSessionManagerData* d;
+};
+
+#endif // USE_QT4
+#endif // TQT_NO_SESSIONMANAGER
+#endif // TQSESSIONMANAGER_H
diff --git a/tqtinterface/qt4/src/kernel/tqsharedmemory_p.cpp b/tqtinterface/qt4/src/kernel/tqsharedmemory_p.cpp
new file mode 100644
index 0000000..20aa70b
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsharedmemory_p.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Provides a standardised interface to shared memory
+**
+** Created : 020124
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsharedmemory_p.h"
+
+#if !defined(TQT_TQWS_NO_SHM)
+
+#if defined(TQT_POSIX_TQSHM)
+#include <fcntl.h>
+#include <sys/mman.h>
+
+TQSharedMemory::TQSharedMemory (int size, TQString filename, char c )
+{
+ shmSize = size;
+ shmFile = filename;
+ character = c;
+ shmFile.append(c);
+}
+
+bool TQSharedMemory::create ()
+{
+ shmFD = shm_open (shmFile.latin1 (), O_RDWR | O_EXCL | O_CREAT, 0666);
+ if (shmFD == -1)
+ return FALSE;
+ else if (ftruncate (shmFD, shmSize) == -1)
+ {
+ close (shmFD);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void TQSharedMemory::destroy ()
+{
+ shm_unlink (shmFile.latin1 ());
+}
+
+bool TQSharedMemory::attach ()
+{
+ shmBase = mmap (0, shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, shmFD, 0);
+
+ if (shmBase == MAP_FAILED)
+ return FALSE;
+
+ close (shmFD);
+ return TRUE;
+}
+
+void TQSharedMemory::detach ()
+{
+ munmap (shmBase, shmSize);
+}
+
+void TQSharedMemory::setPermissions (mode_t mode)
+{
+ mprotect (shmBase, shmSize, mode); // Provide defines to make prot work properly
+}
+
+int TQSharedMemory::size()
+{
+ struct stat buf;
+ int rc = fstat (shmFD, &buf);
+ if (rc != -1)
+ return buf.st_size;
+ else
+ return rc;
+}
+
+#else // Assume SysV for backwards compat
+#include <sys/shm.h>
+
+TQSharedMemory::TQSharedMemory (int size, TQString filename, char c )
+{
+ shmSize = size;
+ shmFile = filename;
+ character = c;
+ key = ftok (shmFile.latin1 (), c);
+ idInitted = FALSE;
+ shmId = -1;
+}
+
+bool TQSharedMemory::create ()
+{
+ shmId = shmget (key, shmSize, IPC_CREAT | 0666);
+ if (shmId == -1)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+void TQSharedMemory::destroy ()
+{
+ if (shmId != -1) {
+ struct shmid_ds shm;
+ shmctl (shmId, IPC_RMID, &shm);
+ }
+}
+
+bool TQSharedMemory::attach ()
+{
+ if (shmId == -1)
+ shmId = shmget (key, shmSize, 0);
+
+ shmBase = shmat (shmId, 0, 0);
+ if ((int) shmBase == -1 || shmBase == 0)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+void TQSharedMemory::detach ()
+{
+ shmdt (shmBase);
+}
+
+void TQSharedMemory::setPermissions (mode_t mode)
+{
+ struct shmid_ds shm;
+ shmctl (shmId, IPC_STAT, &shm);
+ shm.shm_perm.mode = mode;
+ shmctl (shmId, IPC_SET, &shm);
+}
+
+int TQSharedMemory::size ()
+{
+ struct shmid_ds shm;
+ shmctl (shmId, IPC_STAT, &shm);
+ return shm.shm_segsz;
+}
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqsharedmemory_p.h b/tqtinterface/qt4/src/kernel/tqsharedmemory_p.h
new file mode 100644
index 0000000..55526b0
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsharedmemory_p.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Includes system files for shared memory
+**
+** Created : 020124
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSHAREDMEMORY_P_H
+#define TQSHAREDMEMORY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qapplication_qws.cpp and qgfxvnc_qws.cpp. This header file may
+// change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#if !defined (TQT_TQWS_NO_SHM)
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+
+class TQSharedMemory {
+public:
+ TQSharedMemory(){};
+ TQSharedMemory(int, TQString, char c = 'Q');
+ ~TQSharedMemory(){};
+
+ bool create();
+ void destroy();
+
+ bool attach();
+ void detach();
+
+ void setPermissions(mode_t mode);
+ int size();
+ void * base() { return shmBase; };
+
+private:
+ void *shmBase;
+ int shmSize;
+ TQString shmFile;
+ char character;
+#if defined(TQT_POSIX_TQSHM)
+ int shmFD;
+#else
+ int shmId;
+ key_t key;
+ int idInitted;
+#endif
+};
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqsignal.cpp b/tqtinterface/qt4/src/kernel/tqsignal.cpp
new file mode 100644
index 0000000..262164a
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsignal.cpp
@@ -0,0 +1,493 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqsignal.h"
+#include "Qt/qmetaobject.h"
+#include "Qt/qpointer.h"
+#include "tqcstring.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class TQSignal
+ \brief The TQSignal class can be used to send signals for classes
+ that don't inherit TQT_BASE_OBJECT_NAME.
+
+ \compat
+
+ If you want to send signals from a class that does not inherit
+ TQT_BASE_OBJECT_NAME, you can create an internal TQSignal object to emit the
+ signal. You must also provide a function that connects the signal
+ to an outside object slot. This is how we used to implement
+ signals in Qt 3's QMenuData class, which was not a TQT_BASE_OBJECT_NAME. In Qt
+ 4, menus contain actions, which are TQT_BASE_OBJECT_NAMEs.
+
+ In general, we recommend inheriting TQT_BASE_OBJECT_NAME instead. TQT_BASE_OBJECT_NAME
+ provides much more functionality.
+
+ You can set a single QVariant parameter for the signal with
+ setValue().
+
+ Note that TQT_BASE_OBJECT_NAME is a \e private base class of TQSignal, i.e. you
+ cannot call any TQT_BASE_OBJECT_NAME member functions from a TQSignal object.
+
+ Example:
+ \snippet doc/src/snippets/code/src_qt3support_tools_q3signal.cpp 0
+*/
+
+/*!
+ Constructs a signal object called \a name, with the parent object
+ \a parent. These arguments are passed directly to TQT_BASE_OBJECT_NAME.
+*/
+
+TQSignal::TQSignal(TQT_BASE_OBJECT_NAME *parent, const char *name)
+ : TQT_BASE_OBJECT_NAME(parent)
+{
+ setObjectName(QString::fromAscii(name));
+#ifndef QT_NO_VARIANT
+ val = 0;
+#endif
+}
+
+/*!
+ Destroys the signal. All connections are removed, as is the case
+ with all TQT_BASE_OBJECT_NAMEs.
+*/
+TQSignal::~TQSignal()
+{
+}
+#ifndef QT_NO_VARIANT
+// Returns true if it matches ".+(.*int.*"
+static inline bool intSignature(const char *member)
+{
+ TQCString s(member);
+ int p = s.tqfind('(');
+ return p > 0 && p < s.tqfindRev("int");
+}
+#endif
+/*!
+ Connects the signal to \a member in object \a receiver.
+ Returns true if the connection is successful.
+
+ \sa disconnect(), TQT_BASE_OBJECT_NAME::connect()
+*/
+
+bool TQSignal::connect(const TQT_BASE_OBJECT_NAME *receiver, const char *member)
+{
+#ifndef QT_NO_VARIANT
+ if (intSignature(member))
+#endif
+ return TQT_BASE_OBJECT_NAME::connect((TQT_BASE_OBJECT_NAME *)this, TQT_SIGNAL(intSignal(int)), receiver, member);
+#ifndef QT_NO_VARIANT
+ return TQT_BASE_OBJECT_NAME::connect((TQT_BASE_OBJECT_NAME *)this, TQT_SIGNAL(signal(QVariant)),
+ receiver, member);
+#endif
+}
+
+/*!
+ Disonnects the signal from \a member in object \a receiver.
+ Returns true if the connection existed and the disconnect
+ was successful.
+
+ \sa connect(), TQT_BASE_OBJECT_NAME::disconnect()
+*/
+
+bool TQSignal::disconnect(const TQT_BASE_OBJECT_NAME *receiver, const char *member)
+{
+ if (!member)
+ return TQT_BASE_OBJECT_NAME::disconnect((TQT_BASE_OBJECT_NAME *)this, 0, receiver, member);
+#ifndef QT_NO_VARIANT
+ if (intSignature(member))
+#endif
+ return TQT_BASE_OBJECT_NAME::disconnect((TQT_BASE_OBJECT_NAME *)this, TQT_SIGNAL(intSignal(int)), receiver, member);
+#ifndef QT_NO_VARIANT
+ return TQT_BASE_OBJECT_NAME::disconnect((TQT_BASE_OBJECT_NAME *)this, TQT_SIGNAL(signal(QVariant)),
+ receiver, member);
+#endif
+}
+
+
+/*!
+ \fn bool TQSignal::isBlocked() const
+ \obsolete
+ Returns true if the signal is blocked, or false if it is not blocked.
+
+ The signal is not blocked by default.
+
+ \sa block(), TQT_BASE_OBJECT_NAME::signalsBlocked()
+*/
+
+/*!
+ \fn void TQSignal::block(bool b)
+ \obsolete
+ Blocks the signal if \a b is true, or unblocks the signal if \a b is false.
+
+ An activated signal disappears into hyperspace if it is blocked.
+
+ \sa isBlocked(), activate(), TQT_BASE_OBJECT_NAME::blockSignals()
+*/
+
+
+/*!
+ \fn void TQSignal::activate()
+
+ Emits the signal. If the platform supports QVariant and a
+ parameter has been set with setValue(), this value is passed in
+ the signal.
+*/
+void TQSignal::activate()
+{
+#ifndef QT_NO_VARIANT
+ /* Create this TQGuardedPtr on this, if we get destroyed after the intSignal (but before the variant signal)
+ we cannot just emit the signal (because val has been destroyed already) */
+ QPointer<TQSignal> me = this;
+ if(me)
+ emit intSignal(val.toInt());
+ if(me)
+ emit signal(val);
+#else
+ emit intSignal(0);
+#endif
+}
+
+#ifndef QT_NO_VARIANT
+/*!
+ Sets the signal's parameter to \a value
+*/
+void TQSignal::setValue(const QVariant &value)
+{
+ val = value;
+}
+
+/*!
+ Returns the signal's parameter
+*/
+QVariant TQSignal::value() const
+{
+ return val;
+}
+/*! \fn void TQSignal::signal(const QVariant &)
+ \internal
+*/
+/*! \fn void TQSignal::intSignal(int)
+ \internal
+*/
+
+/*! \obsolete */
+void TQSignal::setParameter(int value)
+{
+ val = value;
+}
+
+/*! \obsolete */
+int TQSignal::parameter() const
+{
+ return val.toInt();
+}
+#endif //QT_NO_VARIANT
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of TQSignal class
+**
+** Created : 941201
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsignal.h"
+#include "tqmetaobject.h"
+#include "tqguardedptr.h"
+
+/*!
+ \class TQSignal tqsignal.h
+ \brief The TQSignal class can be used to send Q_SIGNALS for classes
+ that don't inherit TQObject.
+
+ \ingroup io
+ \ingroup misc
+
+ If you want to send Q_SIGNALS from a class that does not inherit
+ TQObject, you can create an internal TQSignal object to emit the
+ signal. You must also provide a function that connects the signal
+ to an outside object slot. This is how we have implemented
+ Q_SIGNALS in the TQMenuData class, which is not a TQObject.
+
+ In general, we recommend inheriting TQObject instead. TQObject
+ provides much more functionality.
+
+ You can set a single TQVariant parameter for the signal with
+ setValue().
+
+ Note that TQObject is a \e private base class of TQSignal, i.e. you
+ cannot call any TQObject member functions from a TQSignal object.
+
+ Example:
+ \code
+ #include <tqsignal.h>
+
+ class MyClass
+ {
+ public:
+ MyClass();
+ ~MyClass();
+
+ void doSomething();
+
+ void connect( TQObject *receiver, const char *member );
+
+ private:
+ TQSignal *sig;
+ };
+
+ MyClass::MyClass()
+ {
+ sig = new TQSignal;
+ }
+
+ MyClass::~MyClass()
+ {
+ delete sig;
+ }
+
+ void MyClass::doSomething()
+ {
+ // ... does something
+ sig->activate(); // emits the signal
+ }
+
+ void MyClass::connect( TQObject *receiver, const char *member )
+ {
+ sig->connect( receiver, member );
+ }
+ \endcode
+*/
+
+/*!
+ Constructs a signal object called \a name, with the tqparent object
+ \a tqparent. These arguments are passed directly to TQObject.
+*/
+
+TQSignal::TQSignal( TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name )
+{
+ isSignal = TRUE;
+#ifndef TQT_NO_VARIANT
+ val = 0;
+#endif
+}
+
+/*!
+ Destroys the signal. All connections are removed, as is the case
+ with all TQObjects.
+*/
+TQSignal::~TQSignal()
+{
+}
+#ifndef TQT_NO_VARIANT
+// Returns TRUE if it matches ".+(.*int.*"
+static inline bool intSignature( const char *member )
+{
+ TQCString s( member );
+ int p = s.tqfind( '(' );
+ return p > 0 && p < s.tqfindRev( "int" );
+}
+#endif
+/*!
+ Connects the signal to \a member in object \a receiver.
+
+ \sa disconnect(), TQObject::connect()
+*/
+
+bool TQSignal::connect( const TQT_BASE_OBJECT_NAME *receiver, const char *member )
+{
+#ifndef TQT_NO_VARIANT
+ if ( intSignature( member ) )
+#endif
+ return TQObject::connect( (TQT_BASE_OBJECT_NAME *)this, TQT_SIGNAL(intSignal(int)), receiver, member );
+#ifndef TQT_NO_VARIANT
+ return TQObject::connect( (TQT_BASE_OBJECT_NAME *)this, TQT_SIGNAL(signal(const TQVariant&)),
+ receiver, member );
+#endif
+}
+
+/*!
+ Disonnects the signal from \a member in object \a receiver.
+
+ \sa connect(), TQObject::disconnect()
+*/
+
+bool TQSignal::disconnect( const TQT_BASE_OBJECT_NAME *receiver, const char *member )
+{
+ if (!member)
+ return TQObject::disconnect( (TQT_BASE_OBJECT_NAME *)this, 0, receiver, member);
+#ifndef TQT_NO_VARIANT
+ if ( intSignature( member ) )
+#endif
+ return TQObject::disconnect( (TQT_BASE_OBJECT_NAME *)this, TQT_SIGNAL(intSignal(int)), receiver, member );
+#ifndef TQT_NO_VARIANT
+ return TQObject::disconnect( (TQT_BASE_OBJECT_NAME *)this, TQT_SIGNAL(signal(const TQVariant&)),
+ receiver, member );
+#endif
+}
+
+
+/*!
+ \fn bool TQSignal::isBlocked() const
+ \obsolete
+ Returns TRUE if the signal is blocked, or FALSE if it is not blocked.
+
+ The signal is not blocked by default.
+
+ \sa block(), TQObject::tqsignalsBlocked()
+*/
+
+/*!
+ \fn void TQSignal::block( bool b )
+ \obsolete
+ Blocks the signal if \a b is TRUE, or unblocks the signal if \a b is FALSE.
+
+ An activated signal disappears into hyperspace if it is blocked.
+
+ \sa isBlocked(), activate(), TQObject::blockSignals()
+*/
+
+
+/*!
+ \fn void TQSignal::activate()
+
+ Emits the signal. If the platform supports TQVariant and a
+ parameter has been set with setValue(), this value is passed in
+ the signal.
+*/
+void TQSignal::activate()
+{
+#ifndef TQT_NO_VARIANT
+ /* Create this TQGuardedPtr on this, if we get destroyed after the intSignal (but before the variant signal)
+ we cannot just emit the signal (because val has been destroyed already) */
+ TQGuardedPtr<TQSignal> me = this;
+ if( me )
+ emit intSignal( val.toInt() );
+ if( me )
+ emit signal( val );
+#else
+ emit intSignal(0);
+#endif
+}
+
+#ifndef TQT_NO_VARIANT
+/*!
+ Sets the signal's parameter to \a value
+*/
+void TQSignal::setValue( const TQVariant &value )
+{
+ val = value;
+}
+
+/*!
+ Returns the signal's parameter
+*/
+TQVariant TQSignal::value() const
+{
+ return val;
+}
+/*! \fn void TQSignal::signal( const TQVariant & )
+ \internal
+*/
+/*! \fn void TQSignal::intSignal( int )
+ \internal
+*/
+
+#ifndef TQT_NO_COMPAT
+/*! \obsolete */
+void TQSignal::setParameter( int value )
+{
+ val = value;
+}
+
+/*! \obsolete */
+int TQSignal::parameter() const
+{
+ return val.toInt();
+}
+#endif
+#endif //TQT_NO_VARIANT
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqsignal.h b/tqtinterface/qt4/src/kernel/tqsignal.h
new file mode 100644
index 0000000..72fd880
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsignal.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Definition of TQSignal class
+**
+** Created : 941201
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSIGNAL_H
+#define TQSIGNAL_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqvariant.h"
+#include "tqobject.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <QtCore/qvariant.h>
+#include <QtCore/qobject.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3SupportLight)
+
+class Q_COMPAT_EXPORT TQSignal : public TQT_BASE_OBJECT_NAME, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQSignal(TQT_BASE_OBJECT_NAME *parent=0, const char *name=0);
+ ~TQSignal();
+
+ bool connect(const TQT_BASE_OBJECT_NAME *receiver, const char *member);
+ bool disconnect(const TQT_BASE_OBJECT_NAME *receiver, const char *member=0);
+
+ void activate();
+
+ bool isBlocked() const { return TQT_BASE_OBJECT_NAME::signalsBlocked(); }
+ void block(bool b) { TQT_BASE_OBJECT_NAME::blockSignals(b); }
+#ifndef QT_NO_VARIANT
+ void setParameter(int value);
+ int parameter() const;
+#endif
+
+#ifndef QT_NO_VARIANT
+ void setValue(const QVariant &value);
+ QVariant value() const;
+#endif
+Q_SIGNALS:
+#ifndef QT_NO_VARIANT
+ void signal(const QVariant&);
+#endif
+ void intSignal(int);
+
+private:
+ Q_DISABLE_COPY(TQSignal)
+
+#ifndef QT_NO_VARIANT
+ QVariant val;
+#endif
+
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#else // USE_QT4
+
+class TQ_EXPORT TQSignal : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQSignal( TQObject *tqparent=0, const char *name=0 );
+ ~TQSignal();
+
+ bool connect( const TQT_BASE_OBJECT_NAME *receiver, const char *member );
+ bool disconnect( const TQT_BASE_OBJECT_NAME *receiver, const char *member=0 );
+
+ void activate();
+
+#ifndef TQT_NO_COMPAT
+ bool isBlocked() const { return TQObject::tqsignalsBlocked(); }
+ void block( bool b ) { TQObject::blockSignals( b ); }
+#ifndef TQT_NO_VARIANT
+ void setParameter( int value );
+ int parameter() const;
+#endif
+#endif
+
+#ifndef TQT_NO_VARIANT
+ void setValue( const TQVariant &value );
+ TQVariant value() const;
+#endif
+Q_SIGNALS:
+#ifndef TQT_NO_VARIANT
+ void signal( const TQVariant& );
+#endif
+ void intSignal( int );
+
+private:
+#ifndef TQT_NO_VARIANT
+ TQVariant val;
+#endif
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSignal( const TQSignal & );
+ TQSignal &operator=( const TQSignal & );
+#endif
+};
+
+#endif // USE_QT4
+
+#endif // TQSIGNAL_H
diff --git a/tqtinterface/qt4/src/kernel/tqsignalmapper.cpp b/tqtinterface/qt4/src/kernel/tqsignalmapper.cpp
new file mode 100644
index 0000000..8a99c54
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsignalmapper.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Implementation of TQSignalMapper class
+**
+** Created : 980503
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsignalmapper.h"
+#ifndef TQT_NO_SIGNALMAPPER
+#include "tqptrdict.h"
+
+struct TQSignalMapperRec {
+ TQSignalMapperRec()
+ {
+ has_int = 0;
+ str_id = TQString::null;
+ }
+
+ uint has_int:1;
+
+ int int_id;
+ TQString str_id;
+ // extendable to other types of identification
+};
+
+class TQSignalMapperData {
+public:
+ TQSignalMapperData()
+ {
+ dict.setAutoDelete( TRUE );
+ }
+
+ TQPtrDict<TQSignalMapperRec> dict;
+};
+
+/*!
+ \class TQSignalMapper tqsignalmapper.h
+ \brief The TQSignalMapper class bundles Q_SIGNALS from identifiable senders.
+
+ \ingroup io
+
+ This class collects a set of parameterless Q_SIGNALS, and re-emits
+ them with integer or string parameters corresponding to the object
+ that sent the signal.
+*/
+
+/*!
+ Constructs a TQSignalMapper called \a name, with tqparent \a tqparent.
+ Like all TQObjects, it will be deleted when the tqparent is deleted.
+*/
+TQSignalMapper::TQSignalMapper( TQObject* tqparent, const char* name ) :
+ TQObject( tqparent, name )
+{
+ d = new TQSignalMapperData;
+}
+
+/*!
+ Destroys the TQSignalMapper.
+*/
+TQSignalMapper::~TQSignalMapper()
+{
+ delete d;
+}
+
+/*!
+ Adds a mapping so that when map() is signaled from the given \a
+ sender, the signal mapped(\a identifier) is emitted.
+
+ There may be at most one integer identifier for each object.
+*/
+void TQSignalMapper::setMapping( const TQObject* sender, int identifier )
+{
+ TQSignalMapperRec* rec = getRec(sender);
+ rec->int_id = identifier;
+ rec->has_int = 1;
+}
+
+/*!
+ \overload
+
+ Adds a mapping so that when map() is signaled from the given \a
+ sender, the signal mapper(\a identifier) is emitted.
+
+ There may be at most one string identifier for each object, and it
+ may not be empty.
+*/
+void TQSignalMapper::setMapping( const TQObject* sender, const TQString &identifier )
+{
+ TQSignalMapperRec* rec = getRec(sender);
+ rec->str_id = identifier;
+}
+
+/*!
+ Removes all mappings for \a sender. This is done automatically
+ when mapped objects are destroyed.
+*/
+void TQSignalMapper::removeMappings( const TQObject* sender )
+{
+ d->dict.remove((void*)sender);
+}
+
+void TQSignalMapper::removeMapping()
+{
+ removeMappings(const_cast<const TQObject*>(static_cast<TQObject*>(sender())));
+}
+
+/*!
+ This slot emits Q_SIGNALS based on which object sends Q_SIGNALS to it.
+*/
+void TQSignalMapper::map()
+{
+ const TQObject* s = const_cast<const TQObject*>(static_cast<TQObject*>(sender()));
+ TQSignalMapperRec* rec = d->dict.tqfind( (void*)s );
+ if ( rec ) {
+ if ( rec->has_int )
+ emit mapped( rec->int_id );
+ if ( !rec->str_id.isEmpty() )
+ emit mapped( rec->str_id );
+ }
+}
+
+TQSignalMapperRec* TQSignalMapper::getRec( const TQObject* sender )
+{
+ TQSignalMapperRec* rec = d->dict.tqfind( (void*)sender );
+ if (!rec) {
+ rec = new TQSignalMapperRec;
+ d->dict.insert( (void*)sender, rec );
+ connect( sender, TQT_SIGNAL(destroyed()), this, TQT_SLOT(removeMapping()) );
+ }
+ return rec;
+}
+
+/*!
+ \fn void TQSignalMapper::mapped(int)
+
+ This signal is emitted when map() is signaled from an object that
+ has an integer mapping set.
+
+ \sa setMapping()
+*/
+
+/*!
+ \overload void TQSignalMapper::mapped(const TQString&)
+
+ This signal is emitted when map() is signaled from an object that
+ has a string mapping set.
+
+ \sa setMapping()
+*/
+#endif //TQT_NO_SIGNALMAPPER
diff --git a/tqtinterface/qt4/src/kernel/tqsignalmapper.h b/tqtinterface/qt4/src/kernel/tqsignalmapper.h
new file mode 100644
index 0000000..903dad2
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsignalmapper.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Definition of TQSignalMapper class
+**
+** Created : 980503
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSIGNALMAPPER_H
+#define TQSIGNALMAPPER_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+#ifndef TQT_NO_SIGNALMAPPER
+class TQSignalMapperData;
+struct TQSignalMapperRec;
+
+
+class TQ_EXPORT TQSignalMapper : public TQObject {
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQSignalMapper( TQObject* tqparent, const char* name=0 );
+ ~TQSignalMapper();
+
+ virtual void setMapping( const TQObject* sender, int identifier );
+ virtual void setMapping( const TQObject* sender, const TQString &identifier );
+ void removeMappings( const TQObject* sender );
+
+Q_SIGNALS:
+ void mapped(int);
+ void mapped(const TQString &);
+
+public Q_SLOTS:
+ void map();
+
+private:
+ TQSignalMapperData* d;
+ TQSignalMapperRec* getRec( const TQObject* );
+
+private Q_SLOTS:
+ void removeMapping();
+};
+
+#endif // TQT_NO_SIGNALMAPPER
+#endif // TQSIGNALMAPPER_H
diff --git a/tqtinterface/qt4/src/kernel/tqsignalslotimp.h b/tqtinterface/qt4/src/kernel/tqsignalslotimp.h
new file mode 100644
index 0000000..b16d453
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsignalslotimp.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Definition of signal/slot collections etc.
+**
+** Created : 980821
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSIGNALSLOTIMP_H
+#define TQSIGNALSLOTIMP_H
+
+#ifndef TQT_H
+#include "tqconnection.h"
+#include "tqptrlist.h"
+#include "tqptrvector.h"
+#endif // TQT_H
+
+class TQ_EXPORT TQConnectionList : public TQPtrList<TQConnection>
+{
+public:
+ TQConnectionList() : TQPtrList<TQConnection>() {}
+ TQConnectionList( const TQConnectionList &list ) : TQPtrList<TQConnection>(list) {}
+ ~TQConnectionList() { clear(); }
+ TQConnectionList &operator=(const TQConnectionList &list)
+ { return (TQConnectionList&)TQPtrList<TQConnection>::operator=(list); }
+};
+
+class TQ_EXPORT TQConnectionListIt : public TQPtrListIterator<TQConnection>
+{
+public:
+ TQConnectionListIt( const TQConnectionList &l ) : TQPtrListIterator<TQConnection>(l) {}
+ TQConnectionListIt &operator=(const TQConnectionListIt &i)
+ { return (TQConnectionListIt&)TQPtrListIterator<TQConnection>::operator=(i); }
+};
+
+#if defined(TQ_TEMPLATEDLL) && defined(TQ_CC_INTEL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrVector<TQConnectionList>;
+#define TQ_EXPORTED_TQPTRVECTORCONNECTTIONLIST_TEMPLATES
+// TQMOC_SKIP_END
+#endif
+
+class TQ_EXPORT TQSignalVec : public TQPtrVector<TQConnectionList>
+{
+public:
+ TQSignalVec(int size=17 )
+ : TQPtrVector<TQConnectionList>(size) {}
+ TQSignalVec( const TQSignalVec &dict )
+ : TQPtrVector<TQConnectionList>(dict) {}
+ ~TQSignalVec() { clear(); }
+ TQSignalVec &operator=(const TQSignalVec &dict)
+ { return (TQSignalVec&)TQPtrVector<TQConnectionList>::operator=(dict); }
+ TQConnectionList* at( uint index ) const {
+ return index >= size()? 0 : TQPtrVector<TQConnectionList>::at(index);
+ }
+ bool insert( uint index, const TQConnectionList* d ) {
+ if (index >= size() )
+ resize( 2*index + 1);
+ return TQPtrVector<TQConnectionList>::insert(index, d);
+ }
+};
+
+#define TQ_DEFINED_TQCONNECTION_LIST
+#include "tqwinexport.h"
+#endif // TQSIGNALSLOTIMP_H
diff --git a/tqtinterface/qt4/src/kernel/tqsimplerichtext.cpp b/tqtinterface/qt4/src/kernel/tqsimplerichtext.cpp
new file mode 100644
index 0000000..4721fd8
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsimplerichtext.cpp
@@ -0,0 +1,851 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqsimplerichtext.h"
+
+#ifndef QT_NO_RICHTEXT
+#include "tqrichtext_p.h"
+#include "tqapplication.h"
+
+QT_BEGIN_NAMESPACE
+
+class TQSimpleRichTextData
+{
+public:
+ TQTextDocument *doc;
+ QFont font;
+ int cachedWidth;
+ bool cachedWidthWithPainter;
+ void adjustSize();
+};
+
+// Pull this private function in from qglobal.cpp
+Q_CORE_EXPORT unsigned int qt_int_sqrt(unsigned int n);
+
+void TQSimpleRichTextData::adjustSize() {
+ QFontMetrics fm(font);
+ int mw = fm.width(QString(QLatin1Char('x'))) * 80;
+ int w = mw;
+ doc->doLayout(0,w);
+ if (doc->widthUsed() != 0) {
+ w = qt_int_sqrt(5 * doc->height() * doc->widthUsed() / 3);
+ doc->doLayout(0, qMin(w, mw));
+
+ if (w*3 < 5*doc->height()) {
+ w = qt_int_sqrt(2 * doc->height() * doc->widthUsed());
+ doc->doLayout(0,qMin(w, mw));
+ }
+ }
+ cachedWidth = doc->width();
+ cachedWidthWithPainter = false;
+}
+
+/*!
+ \class TQSimpleRichText
+ \brief The TQSimpleRichText class provides a small displayable piece of rich text.
+
+ \compat
+
+ This class encapsulates simple rich text usage in which a string
+ is interpreted as rich text and can be drawn. This is particularly
+ useful if you want to display some rich text in a custom widget. A
+ TQStyleSheet is needed to interpret the tags and format the rich
+ text. Qt provides a default HTML-like style sheet, but you may
+ define custom style sheets.
+
+ Once created, the rich text object can be queried for its width(),
+ height(), and the actual width used (see widthUsed()). Most
+ importantly, it can be drawn on any given QPainter with draw().
+ TQSimpleRichText can also be used to implement hypertext or active
+ text facilities by using anchorAt(). A hit test through inText()
+ makes it possible to use simple rich text for text objects in
+ editable drawing canvases.
+
+ Once constructed from a string the contents cannot be changed,
+ only resized. If the contents change, just throw the rich text
+ object away and make a new one with the new contents.
+
+ For large documents use QTextEdit or QTextBrowser. For very small
+ items of rich text you can use a QLabel.
+
+ If you are using TQSimpleRichText to print in high resolution you
+ should call setWidth(QPainter, int) so that the content will be
+ laid out properly on the page.
+*/
+
+/*!
+ Constructs a TQSimpleRichText from the rich text string \a text and
+ the font \a fnt.
+
+ The font is used as a basis for the text rendering. When using
+ rich text rendering on a widget \e w, you would normally specify
+ the widget's font, for example:
+
+ \snippet doc/src/snippets/code/src_qt3support_text_q3simplerichtext.cpp 0
+
+ \a context is the optional context of the rich text object. This
+ becomes important if \a text contains relative references, for
+ example within image tags. TQSimpleRichText always uses the default
+ mime source factory (see \l{TQMimeSourceFactory::defaultFactory()})
+ to resolve those references. The context will then be used to
+ calculate the absolute path. See
+ TQMimeSourceFactory::makeAbsolute() for details.
+
+ The \a sheet is an optional style sheet. If it is 0, the default
+ style sheet will be used (see \l{TQStyleSheet::defaultSheet()}).
+*/
+
+TQSimpleRichText::TQSimpleRichText(const QString& text, const QFont& fnt,
+ const QString& context, const TQStyleSheet* sheet)
+{
+ d = new TQSimpleRichTextData;
+ d->cachedWidth = -1;
+ d->cachedWidthWithPainter = false;
+ d->font = fnt;
+ d->doc = new TQTextDocument(0);
+ d->doc->setTextFormat(TQt::RichText);
+ d->doc->setLeftMargin(0);
+ d->doc->setRightMargin(0);
+ d->doc->setFormatter(new TQTextFormatterBreakWords);
+ d->doc->setStyleSheet((TQStyleSheet*)sheet);
+ d->doc->setDefaultFormat(fnt, QColor());
+ d->doc->setText(text, context);
+}
+
+
+/*!
+ Constructs a TQSimpleRichText from the rich text string \a text and
+ the font \a fnt.
+
+ This is a slightly more complex constructor for TQSimpleRichText
+ that takes an additional mime source factory \a factory, a page
+ break parameter \a pageBreak and a bool \a linkUnderline. \a
+ linkColor is only provided for compatibility, but has no effect,
+ as QPalette::link() color is used now.
+
+ \a context is the optional context of the rich text object. This
+ becomes important if \a text contains relative references, for
+ example within image tags. TQSimpleRichText always uses the default
+ mime source factory (see \l{TQMimeSourceFactory::defaultFactory()})
+ to resolve those references. The context will then be used to
+ calculate the absolute path. See
+ TQMimeSourceFactory::makeAbsolute() for details.
+
+ The \a sheet is an optional style sheet. If it is 0, the default
+ style sheet will be used (see \l{TQStyleSheet::defaultSheet()}).
+
+ This constructor is useful for creating a TQSimpleRichText object
+ suitable for printing. Set \a pageBreak to be the height of the
+ contents area of the pages.
+*/
+
+TQSimpleRichText::TQSimpleRichText(const QString& text, const QFont& fnt,
+ const QString& context, const TQStyleSheet* sheet,
+ const TQMimeSourceFactory* factory, int pageBreak,
+ const QColor& /*linkColor*/, bool linkUnderline)
+{
+ d = new TQSimpleRichTextData;
+ d->cachedWidth = -1;
+ d->cachedWidthWithPainter = false;
+ d->font = fnt;
+ d->doc = new TQTextDocument(0);
+ d->doc->setTextFormat(TQt::RichText);
+ d->doc->setFormatter(new TQTextFormatterBreakWords);
+ d->doc->setStyleSheet((TQStyleSheet*)sheet);
+ d->doc->setDefaultFormat(fnt, QColor());
+ d->doc->flow()->setPageSize(pageBreak);
+ d->doc->setPageBreakEnabled(true);
+#ifndef QT_NO_MIME
+ d->doc->setMimeSourceFactory((TQMimeSourceFactory*)factory);
+#endif
+ d->doc->setUnderlineLinks(linkUnderline);
+ d->doc->setText(text, context);
+}
+
+/*!
+ Destroys the rich text object, freeing memory.
+*/
+
+TQSimpleRichText::~TQSimpleRichText()
+{
+ delete d->doc;
+ delete d;
+}
+
+/*!
+ \overload
+
+ Sets the width of the rich text object to \a w pixels.
+
+ \sa height(), adjustSize()
+*/
+
+void TQSimpleRichText::setWidth(int w)
+{
+ if (w == d->cachedWidth && !d->cachedWidthWithPainter)
+ return;
+ d->doc->formatter()->setAllowBreakInWords(d->doc->isPageBreakEnabled());
+ d->cachedWidth = w;
+ d->cachedWidthWithPainter = false;
+ d->doc->doLayout(0, w);
+}
+
+/*!
+ Sets the width of the rich text object to \a w pixels,
+ recalculating the layout as if it were to be drawn with painter \a
+ p.
+
+ Passing a painter is useful when you intend drawing on devices
+ other than the screen, for example a QPrinter.
+
+ \sa height(), adjustSize()
+*/
+
+void TQSimpleRichText::setWidth(QPainter *p, int w)
+{
+ if (w == d->cachedWidth && d->cachedWidthWithPainter)
+ return;
+ d->doc->formatter()->setAllowBreakInWords(d->doc->isPageBreakEnabled() ||
+ (p && p->device() &&
+ p->device()->devType() == QInternal::Printer));
+ p->save();
+ d->cachedWidth = w;
+ d->cachedWidthWithPainter = true;
+ d->doc->doLayout(TQT_TQPAINTER(p), w);
+ p->restore();
+}
+
+/*!
+ Returns the set width of the rich text object in pixels.
+
+ \sa widthUsed()
+*/
+
+int TQSimpleRichText::width() const
+{
+ if (d->cachedWidth < 0)
+ d->adjustSize();
+ return d->doc->width();
+}
+
+/*!
+ Returns the width in pixels that is actually used by the rich text
+ object. This can be smaller or wider than the set width.
+
+ It may be wider, for example, if the text contains images or
+ non-breakable words that are already wider than the available
+ space. It's smaller when the object only consists of lines that do
+ not fill the width completely.
+
+ \sa width()
+*/
+
+int TQSimpleRichText::widthUsed() const
+{
+ if (d->cachedWidth < 0)
+ d->adjustSize();
+ return d->doc->widthUsed();
+}
+
+/*!
+ Returns the height of the rich text object in pixels.
+
+ \sa setWidth()
+*/
+
+int TQSimpleRichText::height() const
+{
+ if (d->cachedWidth < 0)
+ d->adjustSize();
+ return d->doc->height();
+}
+
+/*!
+ Adjusts the rich text object to a reasonable size.
+
+ \sa setWidth()
+*/
+
+void TQSimpleRichText::adjustSize()
+{
+ d->adjustSize();
+}
+
+/*!
+ Draws the formatted text with painter \a p, at position (\a x, \a
+ y), clipped to \a clipRect. The clipping rectangle is given in the
+ rich text object's coordinates translated by (\a x, \a y). Passing
+ an null rectangle results in no clipping. Colors from the color
+ group \a cg are used as needed, and if not 0, *\a{paper} is
+ used as the background brush.
+
+ Note that the display code is highly optimized to reduce flicker,
+ so passing a brush for \a paper is preferable to simply clearing
+ the area to be painted and then calling this without a brush.
+*/
+
+void TQSimpleRichText::draw(QPainter *p, int x, int y, const QRect& clipRect,
+ const TQColorGroup &cg, const QBrush* paper) const
+{
+ p->save();
+ if (d->cachedWidth < 0)
+ d->adjustSize();
+ TQRect r = clipRect;
+ if (!r.isNull())
+ r.moveBy(-x, -y);
+
+ if (paper)
+ d->doc->setPaper(new TQBrush(*paper));
+ QPalette pal2 = cg;
+ if (d->doc->paper())
+ pal2.setBrush(QPalette::Base, *d->doc->paper());
+
+ if (!clipRect.isNull())
+ p->setClipRect(clipRect);
+ p->translate(x, y);
+ d->doc->draw(TQT_TQPAINTER(p), r, pal2, TQT_TQBRUSH_CONST(paper));
+ p->translate(-x, -y);
+ p->restore();
+}
+
+
+/*! \fn void TQSimpleRichText::draw(QPainter *p, int x, int y, const QRegion& clipRegion,
+ const QColorGroup &cg, const QBrush* paper) const
+
+ Use the version with clipRect instead of this \a clipRegion version,
+ since this region version has problems with larger documents on some
+ platforms (on X11 regions internally are represented with 16-bit
+ coordinates).
+*/
+
+
+
+/*!
+ Returns the context of the rich text object. If no context has
+ been specified in the constructor, an empty string is returned. The
+ context is the path to use to look up relative links, such as
+ image tags and anchor references.
+*/
+
+TQString TQSimpleRichText::context() const
+{
+ return d->doc->context();
+}
+
+/*!
+ Returns the anchor at the requested position, \a pos. An empty
+ string is returned if no anchor is specified for this position.
+*/
+
+TQString TQSimpleRichText::anchorAt(const QPoint& pos) const
+{
+ if (d->cachedWidth < 0)
+ d->adjustSize();
+ TQTextCursor c(d->doc);
+ c.place(pos, d->doc->firstParagraph(), true);
+ return c.paragraph()->at(c.index())->anchorHref();
+}
+
+/*!
+ Returns true if \a pos is within a text line of the rich text
+ object; otherwise returns false.
+*/
+
+bool TQSimpleRichText::inText(const QPoint& pos) const
+{
+ if (d->cachedWidth < 0)
+ d->adjustSize();
+ if (pos.y() > d->doc->height())
+ return false;
+ TQTextCursor c(d->doc);
+ c.place(pos, d->doc->firstParagraph());
+ return c.totalOffsetX() + c.paragraph()->at(c.index())->x +
+ c.paragraph()->at(c.index())->format()->width(c.paragraph()->at(c.index())->c) > pos.x();
+}
+
+/*!
+ Sets the default font for the rich text object to \a f
+*/
+
+void TQSimpleRichText::setDefaultFont(const QFont &f)
+{
+ if (d->font == f)
+ return;
+ d->font = f;
+ d->cachedWidth = -1;
+ d->cachedWidthWithPainter = false;
+ d->doc->setDefaultFormat(f, QColor());
+ d->doc->setText(d->doc->originalText(), d->doc->context());
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_RICHTEXT
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of the TQSimpleRichText class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsimplerichtext.h"
+
+#ifndef TQT_NO_RICHTEXT
+#include "tqrichtext_p.h"
+#include "tqapplication.h"
+
+class TQSimpleRichTextData
+{
+public:
+ TQTextDocument *doc;
+ TQFont font;
+ int cachedWidth;
+ bool cachedWidthWithPainter;
+ void adjustSize(TQPainter *p = 0);
+};
+
+// Pull this private function in from qglobal.cpp
+extern unsigned int qt_int_sqrt( unsigned int n );
+
+void TQSimpleRichTextData::adjustSize(TQPainter *p) {
+ TQFontMetrics fm( font );
+ int mw = fm.width( 'x' ) * 80;
+ int w = mw;
+ doc->doLayout(p, w);
+ if ( doc->widthUsed() != 0 ) {
+ w = qt_int_sqrt( 5 * doc->height() * doc->widthUsed() / 3 );
+ doc->doLayout(p, TQMIN(w, mw));
+
+ if ( w*3 < 5*doc->height() ) {
+ w = qt_int_sqrt( 2 * doc->height() * doc->widthUsed() );
+ doc->doLayout(p, TQMIN(w, mw));
+ }
+ }
+ cachedWidth = doc->width();
+ cachedWidthWithPainter = FALSE;
+}
+
+/*!
+ \class TQSimpleRichText tqsimplerichtext.h
+ \brief The TQSimpleRichText class provides a small displayable piece of rich text.
+
+ \ingroup text
+ \mainclass
+
+ This class encapsulates simple rich text usage in which a string
+ is interpreted as rich text and can be drawn. This is particularly
+ useful if you want to display some rich text in a custom widget. A
+ TQStyleSheet is needed to interpret the tags and format the rich
+ text. TQt provides a default HTML-like style sheet, but you may
+ define custom style sheets.
+
+ Once created, the rich text object can be queried for its width(),
+ height(), and the actual width used (see widthUsed()). Most
+ importantly, it can be drawn on any given TQPainter with draw().
+ TQSimpleRichText can also be used to implement hypertext or active
+ text facilities by using anchorAt(). A hit test through inText()
+ makes it possible to use simple rich text for text objects in
+ editable drawing canvases.
+
+ Once constructed from a string the contents cannot be changed,
+ only resized. If the contents change, just throw the rich text
+ object away and make a new one with the new contents.
+
+ For large documents use TQTextEdit or TQTextBrowser. For very small
+ items of rich text you can use a TQLabel.
+
+ If you are using TQSimpleRichText to print in high resolution you
+ should call setWidth(TQPainter, int) so that the content will be
+ laid out properly on the page.
+*/
+
+/*!
+ Constructs a TQSimpleRichText from the rich text string \a text and
+ the font \a fnt.
+
+ The font is used as a basis for the text rendering. When using
+ rich text rendering on a widget \e w, you would normally specify
+ the widget's font, for example:
+
+ \code
+ TQSimpleRichText myrichtext( contents, mywidget->font() );
+ \endcode
+
+ \a context is the optional context of the rich text object. This
+ becomes important if \a text tqcontains relative references, for
+ example within image tags. TQSimpleRichText always uses the default
+ mime source factory (see \l{TQMimeSourceFactory::defaultFactory()})
+ to resolve those references. The context will then be used to
+ calculate the absolute path. See
+ TQMimeSourceFactory::makeAbsolute() for details.
+
+ The \a sheet is an optional style sheet. If it is 0, the default
+ style sheet will be used (see \l{TQStyleSheet::defaultSheet()}).
+*/
+
+TQSimpleRichText::TQSimpleRichText( const TQString& text, const TQFont& fnt,
+ const TQString& context, const TQStyleSheet* sheet )
+{
+ d = new TQSimpleRichTextData;
+ d->cachedWidth = -1;
+ d->cachedWidthWithPainter = FALSE;
+ d->font = fnt;
+ d->doc = new TQTextDocument( 0 );
+ d->doc->setTextFormat( TQt::RichText );
+ d->doc->setLeftMargin( 0 );
+ d->doc->setRightMargin( 0 );
+ d->doc->setFormatter( new TQTextFormatterBreakWords );
+ d->doc->setStyleSheet( (TQStyleSheet*)sheet );
+ d->doc->setDefaultFormat( fnt, TQColor() );
+ d->doc->setText( text, context );
+}
+
+
+/*!
+ Constructs a TQSimpleRichText from the rich text string \a text and
+ the font \a fnt.
+
+ This is a slightly more complex constructor for TQSimpleRichText
+ that takes an additional mime source factory \a factory, a page
+ break parameter \a pageBreak and a bool \a linkUnderline. \a
+ linkColor is only provided for compatibility, but has no effect,
+ as TQColorGroup's TQColorGroup::link() color is used now.
+
+ \a context is the optional context of the rich text object. This
+ becomes important if \a text tqcontains relative references, for
+ example within image tags. TQSimpleRichText always uses the default
+ mime source factory (see \l{TQMimeSourceFactory::defaultFactory()})
+ to resolve those references. The context will then be used to
+ calculate the absolute path. See
+ TQMimeSourceFactory::makeAbsolute() for details.
+
+ The \a sheet is an optional style sheet. If it is 0, the default
+ style sheet will be used (see \l{TQStyleSheet::defaultSheet()}).
+
+ This constructor is useful for creating a TQSimpleRichText object
+ suitable for printing. Set \a pageBreak to be the height of the
+ contents area of the pages.
+*/
+
+TQSimpleRichText::TQSimpleRichText( const TQString& text, const TQFont& fnt,
+ const TQString& context, const TQStyleSheet* sheet,
+ const TQMimeSourceFactory* factory, int pageBreak,
+ const TQColor& /*linkColor*/, bool linkUnderline )
+{
+ d = new TQSimpleRichTextData;
+ d->cachedWidth = -1;
+ d->cachedWidthWithPainter = FALSE;
+ d->font = fnt;
+ d->doc = new TQTextDocument( 0 );
+ d->doc->setTextFormat( TQt::RichText );
+ d->doc->setFormatter( new TQTextFormatterBreakWords );
+ d->doc->setStyleSheet( (TQStyleSheet*)sheet );
+ d->doc->setDefaultFormat( fnt, TQColor() );
+ d->doc->flow()->setPageSize( pageBreak );
+ d->doc->setPageBreakEnabled( TRUE );
+#ifndef TQT_NO_MIME
+ d->doc->setMimeSourceFactory( (TQMimeSourceFactory*)factory );
+#endif
+ d->doc->setUnderlineLinks( linkUnderline );
+ d->doc->setText( text, context );
+}
+
+/*!
+ Destroys the rich text object, freeing memory.
+*/
+
+TQSimpleRichText::~TQSimpleRichText()
+{
+ delete d->doc;
+ delete d;
+}
+
+/*!
+ \overload
+
+ Sets the width of the rich text object to \a w pixels.
+
+ \sa height(), adjustSize()
+*/
+
+void TQSimpleRichText::setWidth( int w )
+{
+ if ( w == d->cachedWidth && !d->cachedWidthWithPainter )
+ return;
+ d->doc->formatter()->setAllowBreakInWords( d->doc->isPageBreakEnabled() );
+ d->cachedWidth = w;
+ d->cachedWidthWithPainter = FALSE;
+ d->doc->doLayout( 0, w );
+}
+
+/*!
+ Sets the width of the rich text object to \a w pixels,
+ recalculating the tqlayout as if it were to be drawn with painter \a
+ p.
+
+ Passing a painter is useful when you intend drawing on tqdevices
+ other than the screen, for example a TQPrinter.
+
+ \sa height(), adjustSize()
+*/
+
+void TQSimpleRichText::setWidth( TQPainter *p, int w )
+{
+ if ( w == d->cachedWidth && d->cachedWidthWithPainter )
+ return;
+ d->doc->formatter()->setAllowBreakInWords( d->doc->isPageBreakEnabled() ||
+ (p && p->tqdevice() &&
+ (p->tqdevice()->devType() == TQInternal::Printer)) );
+ p->save();
+ d->cachedWidth = w;
+ d->cachedWidthWithPainter = TRUE;
+ d->doc->doLayout( p, w );
+ p->restore();
+}
+
+/*!
+ Returns the set width of the rich text object in pixels.
+
+ \sa widthUsed()
+*/
+
+int TQSimpleRichText::width() const
+{
+ if ( d->cachedWidth < 0 )
+ d->adjustSize();
+ return d->doc->width();
+}
+
+/*!
+ Returns the width in pixels that is actually used by the rich text
+ object. This can be smaller or wider than the set width.
+
+ It may be wider, for example, if the text tqcontains images or
+ non-breakable words that are already wider than the available
+ space. It's smaller when the object only consists of lines that do
+ not fill the width completely.
+
+ \sa width()
+*/
+
+int TQSimpleRichText::widthUsed() const
+{
+ if ( d->cachedWidth < 0 )
+ d->adjustSize();
+ return d->doc->widthUsed();
+}
+
+/*!
+ Returns the height of the rich text object in pixels.
+
+ \sa setWidth()
+*/
+
+int TQSimpleRichText::height() const
+{
+ if ( d->cachedWidth < 0 )
+ d->adjustSize();
+ return d->doc->height();
+}
+
+/*!
+ Adjusts the richt text object to a reasonable size.
+
+ \sa setWidth()
+*/
+
+void TQSimpleRichText::adjustSize()
+{
+ d->adjustSize();
+}
+
+/*!
+ Draws the formatted text with painter \a p, at position (\a x, \a
+ y), clipped to \a clipRect. The clipping rectangle is given in the
+ rich text object's coordinates translated by (\a x, \a y). Passing
+ an null rectangle results in no clipping. Colors from the color
+ group \a cg are used as needed, and if not 0, \a *paper is used as
+ the background brush.
+
+ Note that the display code is highly optimized to reduce flicker,
+ so passing a brush for \a paper is preferable to simply clearing
+ the area to be painted and then calling this without a brush.
+*/
+
+void TQSimpleRichText::draw( TQPainter *p, int x, int y, const QRect& clipRect,
+ const TQColorGroup& cg, const TQBrush* paper ) const
+{
+ p->save();
+ if ( d->cachedWidth < 0 )
+ d->adjustSize(p);
+
+ TQRect r = clipRect;
+ if ( !r.isNull() )
+ r.moveBy( -x, -y );
+
+ if ( paper )
+ d->doc->setPaper( new TQBrush( *paper ) );
+ TQColorGroup g = cg;
+ if ( d->doc->paper() )
+ g.setBrush( TQColorGroup::Base, *d->doc->paper() );
+
+ if ( !clipRect.isNull() )
+ p->setClipRect( clipRect, TQPainter::CoordPainter );
+ p->translate( x, y );
+ d->doc->draw( p, r, g, paper );
+ p->translate( -x, -y );
+ p->restore();
+}
+
+
+/*! \fn void TQSimpleRichText::draw( TQPainter *p, int x, int y, const TQRegion& clipRegion,
+ const TQColorGroup& cg, const TQBrush* paper ) const
+
+ \obsolete
+
+ Use the version with clipRect instead. The region version has
+ problems with larger documents on some platforms (on X11 regions
+ internally are represented with 16bit coordinates).
+*/
+
+
+
+/*!
+ Returns the context of the rich text object. If no context has
+ been specified in the constructor, a null string is returned. The
+ context is the path to use to look up relative links, such as
+ image tags and anchor references.
+*/
+
+TQString TQSimpleRichText::context() const
+{
+ return d->doc->context();
+}
+
+/*!
+ Returns the anchor at the requested position, \a pos. An empty
+ string is returned if no anchor is specified for this position.
+*/
+
+TQString TQSimpleRichText::anchorAt( const TQPoint& pos ) const
+{
+ if ( d->cachedWidth < 0 )
+ d->adjustSize();
+ TQTextCursor c( d->doc );
+ c.place( pos, d->doc->firstParagraph(), TRUE );
+ return c.paragraph()->at( c.index() )->anchorHref();
+}
+
+/*!
+ Returns TRUE if \a pos is within a text line of the rich text
+ object; otherwise returns FALSE.
+*/
+
+bool TQSimpleRichText::inText( const TQPoint& pos ) const
+{
+ if ( d->cachedWidth < 0 )
+ d->adjustSize();
+ if ( pos.y() > d->doc->height() )
+ return FALSE;
+ TQTextCursor c( d->doc );
+ c.place( pos, d->doc->firstParagraph() );
+ return c.totalOffsetX() + c.paragraph()->at( c.index() )->x +
+ c.paragraph()->at( c.index() )->format()->width( c.paragraph()->at( c.index() )->c ) > pos.x();
+}
+
+/*!
+ Sets the default font for the rich text object to \a f
+*/
+
+void TQSimpleRichText::setDefaultFont( const TQFont &f )
+{
+ if ( d->font == f )
+ return;
+ d->font = f;
+ d->cachedWidth = -1;
+ d->cachedWidthWithPainter = FALSE;
+ d->doc->setDefaultFormat( f, TQColor() );
+ d->doc->setText( d->doc->originalText(), d->doc->context() );
+}
+
+#endif //TQT_NO_RICHTEXT
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqsimplerichtext.h b/tqtinterface/qt4/src/kernel/tqsimplerichtext.h
new file mode 100644
index 0000000..2b29c53
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsimplerichtext.h
@@ -0,0 +1,234 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TQSIMPLERICHTEXT_H
+#define TQSIMPLERICHTEXT_H
+
+#include <QtCore/qnamespace.h>
+#include <QtCore/qstring.h>
+#include <QtGui/qregion.h>
+#include <QtGui/qcolor.h>
+
+#include "tqpalette.h"
+#include "tqpainter.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3SupportLight)
+
+#ifndef QT_NO_RICHTEXT
+
+class QPainter;
+class QWidget;
+class TQStyleSheet;
+class QBrush;
+class TQMimeSourceFactory;
+class TQSimpleRichTextData;
+
+class Q_COMPAT_EXPORT TQSimpleRichText
+{
+public:
+ TQSimpleRichText(const QString& text, const QFont& fnt,
+ const QString& context = QString(), const TQStyleSheet* sheet = 0);
+ TQSimpleRichText(const QString& text, const QFont& fnt,
+ const QString& context, const TQStyleSheet *sheet,
+ const TQMimeSourceFactory* factory, int pageBreak = -1,
+ const QColor& linkColor = Qt::blue, bool linkUnderline = true);
+ ~TQSimpleRichText();
+
+ void setWidth(int);
+ void setWidth(QPainter*, int);
+ void setDefaultFont(const QFont &f);
+ int width() const;
+ int widthUsed() const;
+ int height() const;
+ void adjustSize();
+
+ void draw(QPainter* p, int x, int y, const QRect& clipRect,
+ const TQColorGroup& cg, const QBrush* paper = 0) const;
+
+ void draw(QPainter* p, int x, int y, const QRegion& clipRegion,
+ const TQColorGroup& cg, const QBrush* paper = 0) const {
+ draw(p, x, y, clipRegion.boundingRect(), cg, paper);
+ }
+
+ TQString context() const;
+ TQString anchorAt(const QPoint& pos) const;
+
+ bool inText(const QPoint& pos) const;
+
+private:
+ Q_DISABLE_COPY(TQSimpleRichText)
+
+ TQSimpleRichTextData* d;
+};
+
+#endif // QT_NO_RICHTEXT
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // TQSIMPLERICHTEXT_H
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Definition of the TQSimpleRichText class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSIMPLERICHTEXT_H
+#define TQSIMPLERICHTEXT_H
+
+#ifndef TQT_H
+#include "tqnamespace.h"
+#include "tqstring.h"
+#include "tqregion.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_RICHTEXT
+
+class TQ_EXPORT TQSimpleRichText : public QSimpleRichText
+{
+public:
+ TQSimpleRichText( const QString& text, const QFont& fnt, const QString& context = TQString::null, const QStyleSheet* sheet = 0) : QSimpleRichText( text, fnt, context, sheet ) {}
+ TQSimpleRichText( const TQString& text, const TQFont& fnt, const TQString& context, const TQStyleSheet* sheet, const TQMimeSourceFactory* factory, int pageBreak = -1, const TQColor& linkColor = TQt::blue, bool linkUnderline = TRUE ) : QSimpleRichText( text, fnt, context, sheet, factory, pageBreak, linkColor, linkUnderline ) {}
+};
+
+#else // USE_QT4
+
+class TQPainter;
+class TQWidget;
+class TQStyleSheet;
+class TQBrush;
+class TQMimeSourceFactory;
+class TQSimpleRichTextData;
+
+class TQ_EXPORT TQSimpleRichText
+{
+public:
+ TQSimpleRichText( const TQString& text, const TQFont& fnt,
+ const TQString& context = TQString::null, const TQStyleSheet* sheet = 0);
+ TQSimpleRichText( const TQString& text, const TQFont& fnt,
+ const TQString& context, const TQStyleSheet* sheet,
+ const TQMimeSourceFactory* factory, int pageBreak = -1,
+ const TQColor& linkColor = TQt::blue, bool linkUnderline = TRUE );
+ ~TQSimpleRichText();
+
+ void setWidth( int );
+ void setWidth( TQPainter*, int );
+ void setDefaultFont( const TQFont &f );
+ int width() const;
+ int widthUsed() const;
+ int height() const;
+ void adjustSize();
+
+ void draw( TQPainter* p, int x, int y, const QRect& clipRect,
+ const TQColorGroup& cg, const TQBrush* paper = 0) const;
+
+ // obsolete
+ void draw( TQPainter* p, int x, int y, const TQRegion& clipRegion,
+ const TQColorGroup& cg, const TQBrush* paper = 0) const {
+ draw( p, x, y, clipRegion.boundingRect(), cg, paper );
+ }
+
+ TQString context() const;
+ TQString anchorAt( const TQPoint& pos ) const;
+
+ bool inText( const TQPoint& pos ) const;
+
+private:
+ TQSimpleRichTextData* d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSimpleRichText( const TQSimpleRichText & );
+ TQSimpleRichText &operator=( const TQSimpleRichText & );
+#endif
+};
+
+#endif // TQT_NO_RICHTEXT
+
+#endif // TQSIMPLERICHTEXT_H
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqsize.cpp b/tqtinterface/qt4/src/kernel/tqsize.cpp
new file mode 100644
index 0000000..e308f3c
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsize.cpp
@@ -0,0 +1,437 @@
+/****************************************************************************
+**
+** Implementation of TQSize class
+**
+** Created : 931028
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsize.h"
+#include "tqdatastream.h"
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \class TQSize
+ \brief The TQSize class defines the size of a two-dimensional object.
+
+ \ingroup images
+ \ingroup graphics
+
+ A size is specified by a width and a height.
+
+ The coordinate type is TQCOORD (defined in \c <tqwindowdefs.h> as \c int).
+ The minimum value of TQCOORD is TQCOORD_MIN (-2147483648) and the maximum
+ value is TQCOORD_MAX (2147483647).
+
+ The size can be set in the constructor and changed with setWidth()
+ and setHeight(), or using operator+=(), operator-=(), operator*=()
+ and operator/=(), etc. You can swap the width and height with
+ transpose(). You can get a size which holds the maximum height and
+ width of two sizes using expandedTo(), and the minimum height and
+ width of two sizes using boundedTo().
+
+
+ \sa TQPoint, TQRect
+*/
+
+
+/*****************************************************************************
+ TQSize member functions
+ *****************************************************************************/
+
+/*!
+ \fn TQSize::TQSize()
+ Constructs a size with invalid (negative) width and height.
+*/
+
+/*!
+ \fn TQSize::TQSize( int w, int h )
+ Constructs a size with width \a w and height \a h.
+*/
+
+/*!
+ \fn bool TQSize::isNull() const
+ Returns TRUE if the width is 0 and the height is 0; otherwise
+ returns FALSE.
+*/
+
+/*!
+ \fn bool TQSize::isEmpty() const
+ Returns TRUE if the width is less than or equal to 0, or the height is
+ less than or equal to 0; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQSize::isValid() const
+ Returns TRUE if the width is equal to or greater than 0 and the height is
+ equal to or greater than 0; otherwise returns FALSE.
+*/
+
+/*!
+ \fn int TQSize::width() const
+ Returns the width.
+ \sa height()
+*/
+
+/*!
+ \fn int TQSize::height() const
+ Returns the height.
+ \sa width()
+*/
+
+/*!
+ \fn void TQSize::setWidth( int w )
+ Sets the width to \a w.
+ \sa width(), setHeight()
+*/
+
+/*!
+ \fn void TQSize::setHeight( int h )
+ Sets the height to \a h.
+ \sa height(), setWidth()
+*/
+
+/*!
+ Swaps the values of width and height.
+*/
+
+void TQSize::transpose()
+{
+ TQCOORD tmp = wd;
+ wd = ht;
+ ht = tmp;
+}
+
+/*! \enum TQSize::ScaleMode
+
+ This enum type defines the different ways of scaling a size.
+
+ \img scaling.png
+
+ \value ScaleFree The size is scaled freely. The ratio is not preserved.
+ \value ScaleMin The size is scaled to a rectangle as large as possible
+ inside a given rectangle, preserving the aspect ratio.
+ \value ScaleMax The size is scaled to a rectangle as small as possible
+ outside a given rectangle, preserving the aspect ratio.
+
+ \sa TQSize::scale(), TQImage::scale(), TQImage::smoothScale()
+*/
+
+/*!
+ Scales the size to a rectangle of width \a w and height \a h according
+ to the ScaleMode \a mode.
+
+ \list
+ \i If \a mode is \c ScaleFree, the size is set to (\a w, \a h).
+ \i If \a mode is \c ScaleMin, the current size is scaled to a rectangle
+ as large as possible inside (\a w, \a h), preserving the aspect ratio.
+ \i If \a mode is \c ScaleMax, the current size is scaled to a rectangle
+ as small as possible outside (\a w, \a h), preserving the aspect ratio.
+ \endlist
+
+ Example:
+ \code
+ TQSize t1( 10, 12 );
+ t1.scale( 60, 60, TQSize::ScaleFree );
+ // t1 is (60, 60)
+
+ TQSize t2( 10, 12 );
+ t2.scale( 60, 60, TQSize::ScaleMin );
+ // t2 is (50, 60)
+
+ TQSize t3( 10, 12 );
+ t3.scale( 60, 60, TQSize::ScaleMax );
+ // t3 is (60, 72)
+ \endcode
+*/
+void TQSize::scale( int w, int h, ScaleMode mode )
+{
+ if ( mode == ScaleFree ) {
+ wd = (TQCOORD)w;
+ ht = (TQCOORD)h;
+ } else {
+ bool useHeight = TRUE;
+ int w0 = width();
+ int h0 = height();
+ int rw = h * w0 / h0;
+
+ if ( mode == ScaleMin ) {
+ useHeight = ( rw <= w );
+ } else { // mode == ScaleMax
+ useHeight = ( rw >= w );
+ }
+
+ if ( useHeight ) {
+ wd = (TQCOORD)rw;
+ ht = (TQCOORD)h;
+ } else {
+ wd = (TQCOORD)w;
+ ht = (TQCOORD)( w * h0 / w0 );
+ }
+ }
+}
+
+/*!
+ \overload
+
+ Equivalent to scale(\a{s}.width(), \a{s}.height(), \a mode).
+*/
+void TQSize::scale( const TQSize &s, ScaleMode mode )
+{
+ scale( s.width(), s.height(), mode );
+}
+
+/*!
+ \fn TQCOORD &TQSize::rwidth()
+ Returns a reference to the width.
+
+ Using a reference makes it possible to directly manipulate the width.
+
+ Example:
+ \code
+ TQSize s( 100, 10 );
+ s.rwidth() += 20; // s becomes (120,10)
+ \endcode
+
+ \sa rheight()
+*/
+
+/*!
+ \fn TQCOORD &TQSize::rheight()
+ Returns a reference to the height.
+
+ Using a reference makes it possible to directly manipulate the height.
+
+ Example:
+ \code
+ TQSize s( 100, 10 );
+ s.rheight() += 5; // s becomes (100,15)
+ \endcode
+
+ \sa rwidth()
+*/
+
+/*!
+ \fn TQSize &TQSize::operator+=( const TQSize &s )
+
+ Adds \a s to the size and returns a reference to this size.
+
+ Example:
+ \code
+ TQSize s( 3, 7 );
+ TQSize r( -1, 4 );
+ s += r; // s becomes (2,11)
+\endcode
+*/
+
+/*!
+ \fn TQSize &TQSize::operator-=( const TQSize &s )
+
+ Subtracts \a s from the size and returns a reference to this size.
+
+ Example:
+ \code
+ TQSize s( 3, 7 );
+ TQSize r( -1, 4 );
+ s -= r; // s becomes (4,3)
+ \endcode
+*/
+
+/*!
+ \fn TQSize &TQSize::operator*=( int c )
+ Multiplies both the width and height by \a c and returns a reference to
+ the size.
+*/
+
+/*!
+ \overload TQSize &TQSize::operator*=( double c )
+
+ Multiplies both the width and height by \a c and returns a reference to
+ the size.
+
+ Note that the result is truncated.
+*/
+
+/*!
+ \fn bool operator==( const TQSize &s1, const TQSize &s2 )
+ \relates TQSize
+ Returns TRUE if \a s1 and \a s2 are equal; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool operator!=( const TQSize &s1, const TQSize &s2 )
+ \relates TQSize
+ Returns TRUE if \a s1 and \a s2 are different; otherwise returns FALSE.
+*/
+
+/*!
+ \fn const TQSize operator+( const TQSize &s1, const TQSize &s2 )
+ \relates TQSize
+ Returns the sum of \a s1 and \a s2; each component is added separately.
+*/
+
+/*!
+ \fn const TQSize operator-( const TQSize &s1, const TQSize &s2 )
+ \relates TQSize
+ Returns \a s2 subtracted from \a s1; each component is
+ subtracted separately.
+*/
+
+/*!
+ \fn const TQSize operator*( const TQSize &s, int c )
+ \relates TQSize
+ Multiplies \a s by \a c and returns the result.
+*/
+
+/*!
+ \overload const TQSize operator*( int c, const TQSize &s )
+ \relates TQSize
+ Multiplies \a s by \a c and returns the result.
+*/
+
+/*!
+ \overload const TQSize operator*( const TQSize &s, double c )
+ \relates TQSize
+ Multiplies \a s by \a c and returns the result.
+*/
+
+/*!
+ \overload const TQSize operator*( double c, const TQSize &s )
+ \relates TQSize
+ Multiplies \a s by \a c and returns the result.
+*/
+
+/*!
+ \fn TQSize &TQSize::operator/=( int c )
+ Divides both the width and height by \a c and returns a reference to the
+ size.
+*/
+
+/*!
+ \fn TQSize &TQSize::operator/=( double c )
+ \overload
+ Divides both the width and height by \a c and returns a reference to the
+ size.
+
+ Note that the result is truncated.
+*/
+
+/*!
+ \fn const TQSize operator/( const TQSize &s, int c )
+ \relates TQSize
+ Divides \a s by \a c and returns the result.
+*/
+
+/*!
+ \fn const TQSize operator/( const TQSize &s, double c )
+ \relates TQSize
+ \overload
+ Divides \a s by \a c and returns the result.
+
+ Note that the result is truncated.
+*/
+
+/*!
+ \fn TQSize TQSize::expandedTo( const TQSize & otherSize ) const
+
+ Returns a size with the maximum width and height of this size and
+ \a otherSize.
+*/
+
+/*!
+ \fn TQSize TQSize::boundedTo( const TQSize & otherSize ) const
+
+ Returns a size with the minimum width and height of this size and
+ \a otherSize.
+*/
+
+
+void TQSize::warningDivByZero()
+{
+#if defined(TQT_CHECK_MATH)
+ qWarning( "TQSize: Division by zero error" );
+#endif
+}
+
+
+/*****************************************************************************
+ TQSize stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQSize
+ Writes the size \a sz to the stream \a s and returns a reference to
+ the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQSize &sz )
+{
+ if ( s.version() == 1 )
+ s << (TQ_INT16)sz.width() << (TQ_INT16)sz.height();
+ else
+ s << (TQ_INT32)sz.width() << (TQ_INT32)sz.height();
+ return s;
+}
+
+/*!
+ \relates TQSize
+ Reads the size from the stream \a s into size \a sz and returns a
+ reference to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQSize &sz )
+{
+ if ( s.version() == 1 ) {
+ TQ_INT16 w, h;
+ s >> w; sz.rwidth() = w;
+ s >> h; sz.rheight() = h;
+ }
+ else {
+ TQ_INT32 w, h;
+ s >> w; sz.rwidth() = w;
+ s >> h; sz.rheight() = h;
+ }
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqsize.h b/tqtinterface/qt4/src/kernel/tqsize.h
new file mode 100644
index 0000000..c74610b
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsize.h
@@ -0,0 +1,318 @@
+/****************************************************************************
+**
+** Definition of TQSize class
+**
+** Created : 931028
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSIZE_H
+#define TQSIZE_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqpoint.h" // ### change to tqwindowdefs.h?
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qsize.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQSize : public QSize, virtual public TQt
+{
+public:
+ // ### Move this enum to tqnamespace.h in TQt 4.0
+ enum ScaleMode {
+ ScaleFree,
+ ScaleMin,
+ ScaleMax
+ };
+
+ TQSize() : QSize() {}
+ TQSize( int w, int h ) : QSize(w, h) {}
+
+ // Interoperability
+ TQSize(QSize a) {
+ setWidth(a.width());
+ setHeight(a.height());
+ }
+
+ void tqscale( int w, int h, ScaleMode mode ) { scale(w, h, (Qt::AspectRatioMode)mode); }
+ void tqscale( const TQSize &s, ScaleMode mode ) { scale(s, (Qt::AspectRatioMode)mode); }
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQSize
+// ### Make TQSize inherit TQt in TQt 4.0
+{
+public:
+ // ### Move this enum to tqnamespace.h in TQt 4.0
+ enum ScaleMode {
+ ScaleFree,
+ ScaleMin,
+ ScaleMax
+ };
+
+ TQSize();
+ TQSize( int w, int h );
+
+// #ifdef USE_QT4
+//
+// // // Interoperability
+// // TQPtrList(const QList<type*>& l)
+// // {
+// // for (int i = 0; i < l.size(); ++i) append(l.at(i));
+// // }
+// //
+// // TQPtrList<type>& operator= (const QList<type*>& l)
+// // {
+// // this->clear();
+// // for (int i = 0; i < l.size(); ++i) append(l.at(i));
+// // return *this;
+// // }
+// //
+// // operator QList<type*>() const {
+// // QList<type*> list;
+// // for (typename TQPtrList<type>::const_iterator it = TQPtrList<type>::constBegin();
+// // it != TQPtrList<type>::constEnd(); ++it)
+// // list.append(*it);
+// // return list;
+// // }
+//
+// // Interoperability
+// TQSize(const QSize& a)
+// {
+// setWidth(a.width());
+// setHeight(a.height());
+// }
+//
+// // TQSize& operator= (const QSize& a)
+// // {
+// // this->setWidth(a.width());
+// // this->setHeight(a.height());
+// // return *this;
+// // }
+//
+// operator QSize() const {
+// QSize a;
+// a.setWidth(width());
+// a.setHeight(height());
+// return a;
+// }
+//
+// #endif // USE_QT4
+
+ bool isNull() const;
+ bool isEmpty() const;
+ bool isValid() const;
+
+ int width() const;
+ int height() const;
+ void setWidth( int w );
+ void setHeight( int h );
+ void transpose();
+
+ void scale( int w, int h, ScaleMode mode );
+ void scale( const TQSize &s, ScaleMode mode );
+
+ TQSize expandedTo( const TQSize & ) const;
+ TQSize boundedTo( const TQSize & ) const;
+
+ TQCOORD &rwidth();
+ TQCOORD &rheight();
+
+ TQSize &operator+=( const TQSize & );
+ TQSize &operator-=( const TQSize & );
+ TQSize &operator*=( int c );
+ TQSize &operator*=( double c );
+ TQSize &operator/=( int c );
+ TQSize &operator/=( double c );
+
+ friend inline bool operator==( const TQSize &, const TQSize & );
+ friend inline bool operator!=( const TQSize &, const TQSize & );
+ friend inline const TQSize operator+( const TQSize &, const TQSize & );
+ friend inline const TQSize operator-( const TQSize &, const TQSize & );
+ friend inline const TQSize operator*( const TQSize &, int );
+ friend inline const TQSize operator*( int, const TQSize & );
+ friend inline const TQSize operator*( const TQSize &, double );
+ friend inline const TQSize operator*( double, const TQSize & );
+ friend inline const TQSize operator/( const TQSize &, int );
+ friend inline const TQSize operator/( const TQSize &, double );
+
+private:
+ static void warningDivByZero();
+
+ TQCOORD wd;
+ TQCOORD ht;
+};
+
+/*****************************************************************************
+ TQSize stream functions
+ *****************************************************************************/
+
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQSize & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQSize & );
+
+
+/*****************************************************************************
+ TQSize inline functions
+ *****************************************************************************/
+
+inline TQSize::TQSize()
+{ wd = ht = -1; }
+
+inline TQSize::TQSize( int w, int h )
+{ wd=(TQCOORD)w; ht=(TQCOORD)h; }
+
+inline bool TQSize::isNull() const
+{ return wd==0 && ht==0; }
+
+inline bool TQSize::isEmpty() const
+{ return wd<1 || ht<1; }
+
+inline bool TQSize::isValid() const
+{ return wd>=0 && ht>=0; }
+
+inline int TQSize::width() const
+{ return wd; }
+
+inline int TQSize::height() const
+{ return ht; }
+
+inline void TQSize::setWidth( int w )
+{ wd=(TQCOORD)w; }
+
+inline void TQSize::setHeight( int h )
+{ ht=(TQCOORD)h; }
+
+inline TQCOORD &TQSize::rwidth()
+{ return wd; }
+
+inline TQCOORD &TQSize::rheight()
+{ return ht; }
+
+inline TQSize &TQSize::operator+=( const TQSize &s )
+{ wd+=s.wd; ht+=s.ht; return *this; }
+
+inline TQSize &TQSize::operator-=( const TQSize &s )
+{ wd-=s.wd; ht-=s.ht; return *this; }
+
+inline TQSize &TQSize::operator*=( int c )
+{ wd*=(TQCOORD)c; ht*=(TQCOORD)c; return *this; }
+
+inline TQSize &TQSize::operator*=( double c )
+{ wd=(TQCOORD)(wd*c); ht=(TQCOORD)(ht*c); return *this; }
+
+inline bool operator==( const TQSize &s1, const TQSize &s2 )
+{ return s1.wd == s2.wd && s1.ht == s2.ht; }
+
+inline bool operator!=( const TQSize &s1, const TQSize &s2 )
+{ return s1.wd != s2.wd || s1.ht != s2.ht; }
+
+inline const TQSize operator+( const TQSize & s1, const TQSize & s2 )
+{ return TQSize(s1.wd+s2.wd, s1.ht+s2.ht); }
+
+inline const TQSize operator-( const TQSize &s1, const TQSize &s2 )
+{ return TQSize(s1.wd-s2.wd, s1.ht-s2.ht); }
+
+inline const TQSize operator*( const TQSize &s, int c )
+{ return TQSize(s.wd*c, s.ht*c); }
+
+inline const TQSize operator*( int c, const TQSize &s )
+{ return TQSize(s.wd*c, s.ht*c); }
+
+inline const TQSize operator*( const TQSize &s, double c )
+{ return TQSize((TQCOORD)(s.wd*c), (TQCOORD)(s.ht*c)); }
+
+inline const TQSize operator*( double c, const TQSize &s )
+{ return TQSize((TQCOORD)(s.wd*c), (TQCOORD)(s.ht*c)); }
+
+inline TQSize &TQSize::operator/=( int c )
+{
+#if defined(TQT_CHECK_MATH)
+ if ( c == 0 )
+ warningDivByZero();
+#endif
+ wd/=(TQCOORD)c; ht/=(TQCOORD)c;
+ return *this;
+}
+
+inline TQSize &TQSize::operator/=( double c )
+{
+#if defined(TQT_CHECK_MATH)
+ if ( c == 0.0 )
+ warningDivByZero();
+#endif
+ wd=(TQCOORD)(wd/c); ht=(TQCOORD)(ht/c);
+ return *this;
+}
+
+inline const TQSize operator/( const TQSize &s, int c )
+{
+#if defined(TQT_CHECK_MATH)
+ if ( c == 0 )
+ TQSize::warningDivByZero();
+#endif
+ return TQSize(s.wd/c, s.ht/c);
+}
+
+inline const TQSize operator/( const TQSize &s, double c )
+{
+#if defined(TQT_CHECK_MATH)
+ if ( c == 0.0 )
+ TQSize::warningDivByZero();
+#endif
+ return TQSize((TQCOORD)(s.wd/c), (TQCOORD)(s.ht/c));
+}
+
+inline TQSize TQSize::expandedTo( const TQSize & otherSize ) const
+{
+ return TQSize( TQMAX(wd,otherSize.wd), TQMAX(ht,otherSize.ht) );
+}
+
+inline TQSize TQSize::boundedTo( const TQSize & otherSize ) const
+{
+ return TQSize( TQMIN(wd,otherSize.wd), TQMIN(ht,otherSize.ht) );
+}
+
+#endif // USE_QT4
+
+#endif // TQSIZE_H
diff --git a/tqtinterface/qt4/src/kernel/tqsizegrip.cpp b/tqtinterface/qt4/src/kernel/tqsizegrip.cpp
new file mode 100644
index 0000000..bcea2db
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsizegrip.cpp
@@ -0,0 +1,286 @@
+/****************************************************************************
+**
+** Implementation of TQSizeGrip class
+**
+** Created : 980119
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsizegrip.h"
+
+#ifndef TQT_NO_SIZEGRIP
+
+#include "tqpainter.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+
+#if defined(TQ_WS_X11)
+#include "tqt_x11_p.h"
+extern Atom qt_sizegrip; // defined in qapplication_x11.cpp
+#elif defined (TQ_WS_WIN )
+#include "tqobjectlist.h"
+#include "tqt_windows.h"
+#elif defined(TQ_WS_MAC)
+bool qt_mac_update_sizer(TQWidget *, int); //qwidget_mac.cpp
+#endif
+
+
+static TQWidget *qt_sizegrip_tqtopLevelWidget( TQWidget* w)
+{
+ TQWidget *p = w->parentWidget();
+ while ( !w->isTopLevel() && p && !p->inherits("TQWorkspace") ) {
+ w = p;
+ p = p->parentWidget();
+ }
+ return w;
+}
+
+static TQWidget* qt_sizegrip_workspace( TQWidget* w )
+{
+ while ( w && !w->inherits("TQWorkspace" ) ) {
+ if ( w->isTopLevel() )
+ return 0;
+ w = w->parentWidget();
+ }
+ return w;
+}
+
+
+/*!
+ \class TQSizeGrip tqsizegrip.h
+
+ \brief The TQSizeGrip class provides a corner-grip for resizing a top-level window.
+
+ \ingroup application
+ \ingroup basic
+ \ingroup appearance
+
+ This widget works like the standard Windows resize handle. In the
+ X11 version this resize handle generally works differently from
+ the one provided by the system; we hope to reduce this difference
+ in the future.
+
+ Put this widget anywhere in a widget tree and the user can use it
+ to resize the top-level window. Generally, this should be in the
+ lower right-hand corner. Note that TQStatusBar already uses this
+ widget, so if you have a status bar (e.g. you are using
+ TQMainWindow), then you don't need to use this widget explicitly.
+
+ <img src=qsizegrip-m.png> <img src=qsizegrip-w.png>
+
+ \sa TQStatusBar
+*/
+
+
+/*!
+ Constructs a resize corner called \a name, as a child widget of \a
+ tqparent.
+*/
+TQSizeGrip::TQSizeGrip( TQWidget * tqparent, const char* name )
+ : TQWidget( tqparent, name )
+{
+#ifndef TQT_NO_CURSOR
+#ifndef TQ_WS_MAC
+ if ( TQApplication::reverseLayout() )
+ setCursor( Qt::SizeBDiagCursor );
+ else
+ setCursor( Qt::SizeFDiagCursor );
+#endif
+#endif
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ) );
+#if defined(TQ_WS_X11)
+ if ( !qt_sizegrip_workspace( this ) ) {
+ WId id = winId();
+ XChangeProperty(qt_xdisplay(), tqtopLevelWidget()->winId(),
+ qt_sizegrip, XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)&id, 1);
+ }
+#endif
+ tlw = qt_sizegrip_tqtopLevelWidget( this );
+ if ( tlw )
+ tlw->installEventFilter( this );
+ installEventFilter( this ); //for binary compatibility fix in 4.0 with an event() ###
+}
+
+
+/*!
+ Destroys the size grip.
+*/
+TQSizeGrip::~TQSizeGrip()
+{
+#if defined(TQ_WS_X11)
+ if ( !TQApplication::closingDown() && parentWidget() ) {
+ WId id = None;
+ XChangeProperty(qt_xdisplay(), tqtopLevelWidget()->winId(),
+ qt_sizegrip, XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)&id, 1);
+ }
+#endif
+}
+
+/*!
+ Returns the size grip's size hint; this is a small size.
+*/
+TQSize TQSizeGrip::tqsizeHint() const
+{
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_SizeGrip, this, TQSize(13, 13)).
+ expandedTo(TQApplication::globalStrut()));
+}
+
+/*!
+ Paints the resize grip. Resize grips are usually rendered as small
+ diagonal textured lines in the lower-right corner. The event is in
+ \a e.
+*/
+void TQSizeGrip::paintEvent( TQPaintEvent *e )
+{
+ TQPainter painter( this );
+ painter.setClipRegion(e->region());
+ tqstyle().tqdrawPrimitive(TQStyle::PE_SizeGrip, &painter, rect(), tqcolorGroup());
+}
+
+/*!
+ Primes the resize operation. The event is in \a e.
+*/
+void TQSizeGrip::mousePressEvent( TQMouseEvent * e )
+{
+ p = e->globalPos();
+ s = qt_sizegrip_tqtopLevelWidget(this)->size();
+}
+
+
+/*!
+ Resizes the top-level widget containing this widget. The event is
+ in \a e.
+*/
+void TQSizeGrip::mouseMoveEvent( TQMouseEvent * e )
+{
+ if ( e->state() != Qt::LeftButton )
+ return;
+
+ TQWidget* tlw = qt_sizegrip_tqtopLevelWidget(this);
+ if ( tlw->testWState((WState)TQt::WState_ConfigPending) )
+ return;
+
+ TQPoint np( e->globalPos() );
+
+ TQWidget* ws = qt_sizegrip_workspace( this );
+ if ( ws ) {
+ TQPoint tmp( ws->mapFromGlobal( np ) );
+ if ( tmp.x() > ws->width() )
+ tmp.setX( ws->width() );
+ if ( tmp.y() > ws->height() )
+ tmp.setY( ws->height() );
+ np = ws->mapToGlobal( tmp );
+ }
+
+ int w;
+ int h = np.y() - p.y() + s.height();
+
+ if ( TQApplication::reverseLayout() )
+ w = s.width() - ( np.x() - p.x() );
+ else
+ w = np.x() - p.x() + s.width();
+
+ if ( w < 1 )
+ w = 1;
+ if ( h < 1 )
+ h = 1;
+ TQSize ms( tlw->tqminimumSizeHint() );
+ ms = ms.expandedTo( tqminimumSize() );
+ if ( w < ms.width() )
+ w = ms.width();
+ if ( h < ms.height() )
+ h = ms.height();
+
+ if (TQApplication::reverseLayout()) {
+ tlw->resize( w, h );
+ if (tlw->size() == TQSize(w,h))
+ tlw->move( tlw->x() + ( np.x()-p.x() ), tlw->y() );
+ } else {
+ tlw->resize( w, h );
+ }
+#ifdef TQ_WS_WIN
+ MSG msg;
+ while( PeekMessage( &msg, winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE ) )
+ ;
+#endif
+ TQApplication::syncX();
+
+ if ( TQApplication::reverseLayout() && tlw->size() == TQSize(w,h) ) {
+ s.rwidth() = tlw->size().width();
+ p.rx() = np.x();
+ }
+}
+
+/*! \reimp */
+bool TQSizeGrip::eventFilter( TQObject *o, TQEvent *e )
+{
+ if ( static_cast<TQT_BASE_OBJECT_NAME*>(o) == tlw ) {
+ switch ( e->type() ) {
+#ifndef TQ_WS_MAC
+ /* The size grip goes no where on Mac OS X when you maximize! --Sam */
+ case TQEvent::ShowMaximized:
+#endif
+ case TQEvent::ShowFullScreen:
+ hide();
+ break;
+ case TQEvent::ShowNormal:
+ show();
+ break;
+ default:
+ break;
+ }
+ } else if(static_cast<TQT_BASE_OBJECT_NAME*>(o) == this) {
+#if defined(TQ_WS_MAC)
+ switch(e->type()) {
+ case TQEvent::Hide:
+ case TQEvent::Show:
+ if(!TQApplication::closingDown() && parentWidget() && !qt_sizegrip_workspace(this)) {
+ if(TQWidget *w = qt_sizegrip_tqtopLevelWidget(this)) {
+ if(w->isTopLevel())
+ qt_mac_update_sizer(w, e->type() == TQEvent::Hide ? -1 : 1);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ #endif
+ }
+ return FALSE;
+}
+
+#endif //TQT_NO_SIZEGRIP
diff --git a/tqtinterface/qt4/src/kernel/tqsizegrip.h b/tqtinterface/qt4/src/kernel/tqsizegrip.h
new file mode 100644
index 0000000..fa893a2
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsizegrip.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Definition of TQSizeGrip class
+**
+** Created : 980316
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSIZEGRIP_H
+#define TQSIZEGRIP_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SIZEGRIP
+
+class TQ_EXPORT TQSizeGrip: public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQSizeGrip( TQWidget* tqparent, const char* name=0 );
+ ~TQSizeGrip();
+
+ TQSize tqsizeHint() const;
+
+protected:
+ void paintEvent( TQPaintEvent * );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+
+ bool eventFilter( TQObject *, TQEvent * );
+
+private:
+ TQPoint p;
+ TQSize s;
+ int d;
+ TQWidget *tlw;
+};
+
+#endif //TQT_NO_SIZEGRIP
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqsizepolicy.h b/tqtinterface/qt4/src/kernel/tqsizepolicy.h
new file mode 100644
index 0000000..29236a0
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsizepolicy.h
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Definition of the TQSizePolicy class
+**
+** Created : 980929
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSIZEPOLICY_H
+#define TQSIZEPOLICY_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qsizepolicy.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQSizePolicy : public QSizePolicy
+{
+public:
+ typedef Policy SizeType;
+ typedef Qt::Orientations ExpandData;
+ enum {
+ NoDirection = 0,
+ Horizontally = 1,
+ Vertically = 2,
+ BothDirections = Horizontally | Vertically
+ };
+
+ TQSizePolicy() : QSizePolicy() {}
+ TQSizePolicy( SizeType hor, SizeType ver, bool hfw = FALSE ) : QSizePolicy( hor, ver ) {
+ setHorizontalPolicy(hor);
+ setVerticalPolicy(ver);
+ setHeightForWidth(hfw);
+ }
+ TQSizePolicy( SizeType hor, SizeType ver, uchar hors, uchar vers, bool hfw = FALSE ) : QSizePolicy( hor, ver )
+ {
+ setHorizontalPolicy(hor);
+ setVerticalPolicy(ver);
+ setHorizontalStretch(hors);
+ setVerticalStretch(vers);
+ setHeightForWidth(hfw);
+ }
+
+ inline ExpandData expanding() const { return expandingDirections(); }
+ inline bool mayShrinkHorizontally() const { return horizontalPolicy() & QSizePolicy::ShrinkFlag; }
+ inline bool mayShrinkVertically() const { return verticalPolicy() & QSizePolicy::ShrinkFlag; }
+ inline bool mayGrowHorizontally() const { return QSizePolicy::horizontalPolicy() & QSizePolicy::GrowFlag; }
+ inline bool mayGrowVertically() const { return verticalPolicy() & QSizePolicy::GrowFlag; }
+
+ inline SizeType horData() const { return horizontalPolicy(); }
+ inline SizeType verData() const { return verticalPolicy(); }
+ inline void setHorData(Policy d) { setHorizontalPolicy(d); }
+ inline void setVerData(Policy d) { setVerticalPolicy(d); }
+
+ inline uint horStretch() const { return horizontalStretch(); }
+ inline uint verStretch() const { return verticalStretch(); }
+ inline void setHorStretch(uchar sf) { setHorizontalStretch(sf); }
+ inline void setVerStretch(uchar sf) { setVerticalStretch(sf); }
+
+ // Interoperability
+ static const TQSizePolicy& convertFromQSizePolicy( QSizePolicy& qs );
+};
+
+// Interoperability
+inline static const TQSizePolicy& convertFromQSizePolicy( const QSizePolicy& qs ) {
+ return (*static_cast<const TQSizePolicy*>(&qs));
+}
+
+#else // USE_QT4
+
+// Documentation is in qabstracttqlayout.cpp.
+
+class TQ_EXPORT TQSizePolicy
+{
+private:
+ enum SizePolicy_Internal { HSize = 6, HMask = 0x3f, VMask = HMask << HSize,
+ MayGrow = 1, ExpMask = 2, MayShrink = 4 };
+public:
+ enum SizeType { Fixed = 0,
+ Minimum = MayGrow,
+ Maximum = MayShrink,
+ Preferred = MayGrow | MayShrink,
+ MinimumExpanding = MayGrow | ExpMask,
+ Expanding = MayGrow | MayShrink | ExpMask,
+ Ignored = ExpMask /* magic value */ };
+
+ enum ExpandData { NoDirection = 0,
+ Horizontally = 1,
+ Vertically = 2,
+#ifndef TQT_NO_COMPAT
+ Horizontal = Horizontally,
+ Vertical = Vertically,
+#endif
+ BothDirections = Horizontally | Vertically };
+
+ TQSizePolicy() : data( 0 ) { }
+
+ TQSizePolicy( SizeType hor, SizeType ver, bool hfw = FALSE )
+ : data( hor | (ver<<HSize) | (hfw ? (TQ_UINT32)(1<<2*HSize) : 0) ) { }
+ TQSizePolicy( SizeType hor, SizeType ver, uchar hors, uchar vers, bool hfw = FALSE );
+
+ SizeType horData() const { return (SizeType)( data & HMask ); }
+ SizeType verData() const { return (SizeType)( (data & VMask) >> HSize ); }
+
+ bool mayShrinkHorizontally() const { return horData() & MayShrink || horData() == Ignored; }
+ bool mayShrinkVertically() const { return verData() & MayShrink || verData() == Ignored; }
+ bool mayGrowHorizontally() const { return horData() & MayGrow || horData() == Ignored; }
+ bool mayGrowVertically() const { return verData() & MayGrow || verData() == Ignored; }
+
+ ExpandData expanding() const
+ {
+ return (ExpandData)( (int)(verData() & ExpMask ? Vertically : 0) |
+ (int)(horData() & ExpMask ? Horizontally : 0) );
+ }
+
+ void setHorData( SizeType d ) { data = (TQ_UINT32)(data & ~HMask) | d; }
+ void setVerData( SizeType d ) { data = (TQ_UINT32)(data & ~(HMask << HSize)) |
+ (d << HSize); }
+
+ void setHeightForWidth( bool b ) { data = b ? (TQ_UINT32)( data | ( 1 << 2*HSize ) )
+ : (TQ_UINT32)( data & ~( 1 << 2*HSize ) ); }
+ bool hasHeightForWidth() const { return data & ( 1 << 2*HSize ); }
+
+ bool operator==( const TQSizePolicy& s ) const { return data == s.data; }
+ bool operator!=( const TQSizePolicy& s ) const { return data != s.data; }
+
+
+ uint horStretch() const { return data >> 24; }
+ uint verStretch() const { return (data >> 16) & 0xff; }
+ void setHorStretch( uchar sf ) { data = (data&0x00ffffff) | (uint(sf)<<24); }
+ void setVerStretch( uchar sf ) { data = (data&0xff00ffff) | (uint(sf)<<16); }
+ inline void transpose();
+
+private:
+ TQSizePolicy( int i ) : data( (TQ_UINT32)i ) { }
+
+ TQ_UINT32 data;
+};
+
+inline TQSizePolicy::TQSizePolicy( SizeType hor, SizeType ver, uchar hors, uchar vers, bool hfw )
+ : data( hor | (ver<<HSize) | (hfw ? (TQ_UINT32)(1<<2*HSize) : 0) ) {
+ setHorStretch( hors );
+ setVerStretch( vers );
+}
+
+inline void TQSizePolicy::transpose() {
+ *this = TQSizePolicy( verData(), horData(), verStretch(), horStretch(),
+ hasHeightForWidth() );
+}
+
+#endif // USE_QT4
+
+#endif // TQSIZEPOLICY_H
diff --git a/tqtinterface/qt4/src/kernel/tqsocketnotifier.cpp b/tqtinterface/qt4/src/kernel/tqsocketnotifier.cpp
new file mode 100644
index 0000000..9275de3
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsocketnotifier.cpp
@@ -0,0 +1,270 @@
+/****************************************************************************
+**
+** Implementation of TQSocketNotifier class
+**
+** Created : 951114
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsocketnotifier.h"
+#include "tqapplication.h"
+#include "tqevent.h"
+#include "tqeventloop.h"
+#include "tqplatformdefs.h"
+
+#if defined(TQ_OS_UNIX)
+#include <sys/types.h>
+#endif
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \class TQSocketNotifier tqsocketnotifier.h
+ \brief The TQSocketNotifier class provides support for socket callbacks.
+
+ \ingroup io
+
+ This class makes it possible to write asynchronous socket-based
+ code in TQt. Using synchronous socket operations blocks the
+ program, which is clearly not acceptable for an event-driven GUI
+ program.
+
+ Once you have opened a non-blocking socket (whether for TCP, UDP,
+ a UNIX-domain socket, or any other protocol family your operating
+ system supports), you can create a socket notifier to monitor the
+ socket. Then you connect the activated() signal to the slot you
+ want to be called when a socket event occurs.
+
+ Note for Windows users: the socket passed to TQSocketNotifier will
+ become non-blocking, even if it was created as a blocking socket.
+
+ There are three types of socket notifiers (read, write and
+ exception); you must specify one of these in the constructor.
+
+ The type specifies when the activated() signal is to be emitted:
+ \list 1
+ \i TQSocketNotifier::Read - There is data to be read (socket read event).
+ \i TQSocketNotifier::Write - Data can be written (socket write event).
+ \i TQSocketNofifier::Exception - An exception has occurred (socket
+ exception event). We recommend against using this.
+ \endlist
+
+ For example, if you need to monitor both reads and writes for the
+ same socket you must create two socket notifiers.
+
+ For read notifiers it makes little sense to connect the
+ activated() signal to more than one slot because the data can be
+ read from the socket only once.
+
+ Also observe that if you do not read all the available data when
+ the read notifier fires, it fires again and again.
+
+ For write notifiers, immediately disable the notifier after the
+ activated() signal has been received and you have sent the data to
+ be written on the socket. When you have more data to be written,
+ enable it again to get a new activated() signal. The exception is
+ if the socket data writing operation (send() or equivalent) fails
+ with a "would block" error, which means that some buffer is full
+ and you must wait before sending more data. In that case you do
+ not need to disable and re-enable the write notifier; it will fire
+ again as soon as the system allows more data to be sent.
+
+ The behavior of a write notifier that is left in enabled state
+ after having emitting the first activated() signal (and no "would
+ block" error has occurred) is undefined. Depending on the
+ operating system, it may fire on every pass of the event loop or
+ not at all.
+
+ If you need a time-out for your sockets you can use either \link
+ TQObject::startTimer() timer events\endlink or the TQTimer class.
+
+ Socket action is detected in the \link TQApplication::exec() main
+ event loop\endlink of TQt. The X11 version of TQt has a single UNIX
+ select() call that incorporates all socket notifiers and the X
+ socket.
+
+ Note that on XFree86 for OS/2, select() works only in the thread
+ in which main() is running; you should therefore use that thread
+ for GUI operations.
+
+ \sa TQSocket, TQServerSocket, TQSocketDevice, TQFile::handle()
+*/
+
+/*!
+ \enum TQSocketNotifier::Type
+
+ \value Read
+ \value Write
+ \value Exception
+*/
+
+
+/*!
+ Constructs a socket notifier called \a name, with the tqparent, \a
+ tqparent. It watches \a socket for \a type events, and enables it.
+
+ It is generally advisable to explicitly enable or disable the
+ socket notifier, especially for write notifiers.
+
+ \sa setEnabled(), isEnabled()
+*/
+
+TQSocketNotifier::TQSocketNotifier( int socket, Type type, TQObject *tqparent,
+ const char *name )
+ : TQObject( tqparent, name )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( socket < 0 )
+ qWarning( "TQSocketNotifier: Invalid socket specified" );
+# if defined(TQ_OS_UNIX)
+ if ( socket >= FD_SETSIZE )
+ qWarning( "TQSocketNotifier: Socket descriptor too large for select()" );
+# endif
+#endif
+ sockfd = socket;
+ sntype = type;
+ snenabled = TRUE;
+ TQApplication::eventLoop()->registerSocketNotifier( this );
+}
+
+/*!
+ Destroys the socket notifier.
+*/
+
+TQSocketNotifier::~TQSocketNotifier()
+{
+ setEnabled( FALSE );
+}
+
+
+/*!
+ \fn void TQSocketNotifier::activated( int socket )
+
+ This signal is emitted under certain conditions specified by the
+ notifier type():
+ \list 1
+ \i TQSocketNotifier::Read - There is data to be read (socket read event).
+ \i TQSocketNotifier::Write - Data can be written (socket write event).
+ \i TQSocketNofifier::Exception - An exception has occurred (socket
+ exception event).
+ \endlist
+
+ The \a socket argument is the \link socket() socket\endlink identifier.
+
+ \sa type(), socket()
+*/
+
+
+/*!
+ \fn int TQSocketNotifier::socket() const
+
+ Returns the socket identifier specified to the constructor.
+
+ \sa type()
+*/
+
+/*!
+ \fn Type TQSocketNotifier::type() const
+
+ Returns the socket event type specified to the constructor: \c
+ TQSocketNotifier::Read, \c TQSocketNotifier::Write, or \c
+ TQSocketNotifier::Exception.
+
+ \sa socket()
+*/
+
+
+/*!
+ \fn bool TQSocketNotifier::isEnabled() const
+
+ Returns TRUE if the notifier is enabled; otherwise returns FALSE.
+
+ \sa setEnabled()
+*/
+
+/*!
+ Enables the notifier if \a enable is TRUE or disables it if \a
+ enable is FALSE.
+
+ The notifier is enabled by default.
+
+ If the notifier is enabled, it emits the activated() signal
+ whenever a socket event corresponding to its \link type()
+ type\endlink occurs. If it is disabled, it ignores socket events
+ (the same effect as not creating the socket notifier).
+
+ Write notifiers should normally be disabled immediately after the
+ activated() signal has been emitted; see discussion of write
+ notifiers in the \link #details class description\endlink above.
+
+ \sa isEnabled(), activated()
+*/
+
+void TQSocketNotifier::setEnabled( bool enable )
+{
+ if ( sockfd < 0 )
+ return;
+ if ( snenabled == enable ) // no change
+ return;
+ snenabled = enable;
+
+ TQEventLoop *eventloop = TQApplication::eventLoop();
+ if ( ! eventloop ) // perhaps application is shutting down
+ return;
+
+ if ( snenabled )
+ eventloop->registerSocketNotifier( this );
+ else
+ eventloop->unregisterSocketNotifier( this );
+}
+
+
+/*!\reimp
+*/
+bool TQSocketNotifier::event( TQEvent *e )
+{
+ // Emits the activated() signal when a \c TQEvent::SockAct is
+ // received.
+ TQObject::event( e ); // will activate filters
+ if ( e->type() == TQEvent::SockAct ) {
+ emit activated( sockfd );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqsocketnotifier.h b/tqtinterface/qt4/src/kernel/tqsocketnotifier.h
new file mode 100644
index 0000000..404e9f7
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsocketnotifier.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Definition of TQSocketNotifier class
+**
+** Created : 951114
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSOCKETNOTIFIER_H
+#define TQSOCKETNOTIFIER_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qsocketnotifier.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQSocketNotifier : public QSocketNotifier
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQSocketNotifier( int socket, Type type, TQObject *tqparent=0, const char *name=0 ) : QSocketNotifier(socket, type, tqparent) { setObjectName(name); }
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQSocketNotifier : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ enum Type { Read, Write, Exception };
+
+ TQSocketNotifier( int socket, Type, TQObject *tqparent=0, const char *name=0 );
+ ~TQSocketNotifier();
+
+ int socket() const;
+ Type type() const;
+
+ bool isEnabled() const;
+ virtual void setEnabled( bool );
+
+Q_SIGNALS:
+ void activated( int socket );
+
+protected:
+ bool event( TQEvent * );
+
+private:
+ int sockfd;
+ Type sntype;
+ bool snenabled;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSocketNotifier( const TQSocketNotifier & );
+ TQSocketNotifier &operator=( const TQSocketNotifier & );
+#endif
+};
+
+
+inline int TQSocketNotifier::socket() const
+{ return sockfd; }
+
+inline TQSocketNotifier::Type TQSocketNotifier::type() const
+{ return sntype; }
+
+inline bool TQSocketNotifier::isEnabled() const
+{ return snenabled; }
+
+#endif // USE_QT4
+
+#endif // TQSOCKETNOTIFIER_H
diff --git a/tqtinterface/qt4/src/kernel/tqsound.cpp b/tqtinterface/qt4/src/kernel/tqsound.cpp
new file mode 100644
index 0000000..afb3871
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsound.cpp
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** Implementation of TQSound class and TQAuServer internal class
+**
+** Created : 000117
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsound.h"
+
+#ifndef TQT_NO_SOUND
+
+#include "tqptrlist.h"
+
+static TQPtrList<TQAuServer> *servers=0;
+
+TQAuServer::TQAuServer(TQObject* tqparent, const char* name) :
+ TQObject(tqparent,name)
+{
+ if ( !servers ) {
+ servers = new TQPtrList<TQAuServer>;
+ // ### add cleanup
+ }
+ servers->prepend(this);
+}
+
+TQAuServer::~TQAuServer()
+{
+ servers->remove(this);
+ if ( servers->count() == 0 ) {
+ delete servers;
+ servers = 0;
+ }
+}
+
+void TQAuServer::play(const TQString& filename)
+{
+ TQSound s(filename);
+ play(&s);
+}
+
+extern TQAuServer* qt_new_audio_server();
+
+static TQAuServer& server()
+{
+ if (!servers) qt_new_audio_server();
+ return *servers->first();
+}
+
+class TQSoundData {
+public:
+ TQSoundData(const TQString& fname) :
+ filename(fname), bucket(0), looprem(0), looptotal(1)
+ {
+ }
+
+ ~TQSoundData()
+ {
+ delete bucket;
+ }
+
+ TQString filename;
+ TQAuBucket* bucket;
+ int looprem;
+ int looptotal;
+};
+
+/*!
+ \class TQSound tqsound.h
+ \brief The TQSound class provides access to the platform audio facilities.
+
+ \ingroup multimedia
+ \mainclass
+
+ TQt provides the most commonly required audio operation in GUI
+ applications: asynchronously playing a sound file. This is most
+ easily accomplished with a single call:
+ \code
+ TQSound::play("mysounds/bells.wav");
+ \endcode
+
+ A second API is provided in which a TQSound object is created from
+ a sound file and is played later:
+ \code
+ TQSound bells("mysounds/bells.wav");
+
+ bells.play();
+ \endcode
+
+ Sounds played using the second model may use more memory but play
+ more immediately than sounds played using the first model,
+ depending on the underlying platform audio facilities.
+
+ On Microsoft Windows the underlying multimedia system is used;
+ only WAVE format sound files are supported.
+
+ On X11 the \link ftp://ftp.x.org/contrib/audio/nas/ Network Audio
+ System\endlink is used if available, otherwise all operations work
+ silently. NAS supports WAVE and AU files.
+
+ On Macintosh, ironically, we use QT (\link
+ http://quicktime.apple.com QuickTime\endlink) for sound, this
+ means all QuickTime formats are supported by TQt/Mac.
+
+ On TQt/Embedded, a built-in mixing sound server is used, which
+ accesses \c /dev/dsp directly. Only the WAVE format is supported.
+
+ The availability of sound can be tested with
+ TQSound::isAvailable().
+*/
+
+/*!
+ \fn static bool TQSound::available()
+
+ Returns TRUE if sound support is available; otherwise returns FALSE.
+*/
+
+/*!
+ Plays the sound in a file called \a filename.
+*/
+void TQSound::play(const TQString& filename)
+{
+ server().play(filename);
+}
+
+/*!
+ Constructs a TQSound that can quickly play the sound in a file
+ named \a filename.
+
+ This may use more memory than the static \c play function.
+
+ The \a tqparent and \a name arguments (default 0) are passed on to
+ the TQObject constructor.
+*/
+TQSound::TQSound(const TQString& filename, TQObject* tqparent, const char* name) :
+ TQObject(tqparent,name),
+ d(new TQSoundData(filename))
+{
+ server().init(this);
+}
+
+/*!
+ Destroys the sound object. If the sound is not finished playing stop() is called on it.
+
+ \sa stop() isFinished()
+*/
+TQSound::~TQSound()
+{
+ if ( !isFinished() )
+ stop();
+ delete d;
+}
+
+/*!
+ Returns TRUE if the sound has finished playing; otherwise returns FALSE.
+
+ \warning On Windows this function always returns TRUE for unlooped sounds.
+*/
+bool TQSound::isFinished() const
+{
+ return d->looprem == 0;
+}
+
+/*!
+ \overload
+
+ Starts the sound playing. The function returns immediately.
+ Depending on the platform audio facilities, other sounds may stop
+ or may be mixed with the new sound.
+
+ The sound can be played again at any time, possibly mixing or
+ replacing previous plays of the sound.
+*/
+void TQSound::play()
+{
+ d->looprem = d->looptotal;
+ server().play(this);
+}
+
+/*!
+ Returns the number of times the sound will play.
+*/
+int TQSound::loops() const
+{
+ return d->looptotal;
+}
+
+/*!
+ Returns the number of times the sound will loop. This value
+ decreases each time the sound loops.
+*/
+int TQSound::loopsRemaining() const
+{
+ return d->looprem;
+}
+
+/*!
+ Sets the sound to repeat \a l times when it is played. Passing the
+ value -1 will cause the sound to loop indefinitely.
+
+ \sa loops()
+*/
+void TQSound::setLoops(int l)
+{
+ d->looptotal = l;
+}
+
+/*!
+ Returns the filename associated with the sound.
+*/
+TQString TQSound::fileName() const
+{
+ return d->filename;
+}
+
+/*!
+ Stops the sound playing.
+
+ On Windows the current loop will finish if a sound is played
+ in a loop.
+
+ \sa play()
+*/
+void TQSound::stop()
+{
+ server().stop(this);
+}
+
+
+/*!
+ Returns TRUE if sound facilities exist on the platform; otherwise
+ returns FALSE. An application may choose either to notify the user
+ if sound is crucial to the application or to operate silently
+ without bothering the user.
+
+ If no sound is available, all TQSound operations work silently and
+ quickly.
+*/
+bool TQSound::isAvailable()
+{
+ return server().okay();
+}
+
+/*!
+ Sets the internal bucket record of sound \a s to \a b, deleting
+ any previous setting.
+*/
+void TQAuServer::setBucket(TQSound* s, TQAuBucket* b)
+{
+ delete s->d->bucket;
+ s->d->bucket = b;
+}
+
+/*!
+ Returns the internal bucket record of sound \a s.
+*/
+TQAuBucket* TQAuServer::bucket(TQSound* s)
+{
+ return s->d->bucket;
+}
+
+/*!
+ Decrements the TQSound::loopRemaining() value for sound \a s,
+ returning the result.
+*/
+int TQAuServer::decLoop(TQSound* s)
+{
+ if ( s->d->looprem > 0 )
+ --s->d->looprem;
+ return s->d->looprem;
+}
+
+/*!
+ Initializes the sound. The default implementation does nothing.
+*/
+void TQAuServer::init(TQSound*)
+{
+}
+
+TQAuBucket::~TQAuBucket()
+{
+}
+
+#endif // TQT_NO_SOUND
diff --git a/tqtinterface/qt4/src/kernel/tqsound.h b/tqtinterface/qt4/src/kernel/tqsound.h
new file mode 100644
index 0000000..a24a63f
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsound.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Definition of TQSound class and TQAuServer internal class
+**
+** Created : 000117
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+#ifndef TQSOUND_H
+#define TQSOUND_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SOUND
+
+class TQSoundData;
+
+class TQ_EXPORT TQSound : public TQObject {
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ static bool isAvailable();
+ static void play(const TQString& filename);
+
+ TQSound(const TQString& filename, TQObject* tqparent=0, const char* name=0);
+ ~TQSound();
+
+ /* Coming soon...
+ ?
+ TQSound(int hertz, Type type=Mono);
+ int play(const ushort* data, int samples);
+ bool full();
+ signal void notFull();
+ ?
+ */
+
+#ifndef TQT_NO_COMPAT
+ static bool available() { return isAvailable(); }
+#endif
+
+ int loops() const;
+ int loopsRemaining() const;
+ void setLoops(int);
+ TQString fileName() const;
+
+ bool isFinished() const;
+
+public Q_SLOTS:
+ void play();
+ void stop();
+
+private:
+ TQSoundData* d;
+ friend class TQAuServer;
+};
+
+
+/*
+ TQAuServer is an INTERNAL class. If you wish to provide support for
+ additional audio servers, you can make a subclass of TQAuServer to do
+ so, HOWEVER, your class may need to be re-engineered to some degree
+ with each new TQt release, including minor releases.
+
+ TQAuBucket is whatever you want.
+*/
+
+class TQAuBucket {
+public:
+ virtual ~TQAuBucket();
+};
+
+class TQAuServer : public TQObject {
+ TQ_OBJECT
+
+public:
+ TQAuServer(TQObject* tqparent, const char* name);
+ ~TQAuServer();
+
+ virtual void init(TQSound*);
+ virtual void play(const TQString& filename);
+ virtual void play(TQSound*)=0;
+ virtual void stop(TQSound*)=0;
+ virtual bool okay()=0;
+
+protected:
+ void setBucket(TQSound*, TQAuBucket*);
+ TQAuBucket* bucket(TQSound*);
+ int decLoop(TQSound*);
+};
+
+#endif // TQT_NO_SOUND
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqsound_x11.cpp b/tqtinterface/qt4/src/kernel/tqsound_x11.cpp
new file mode 100644
index 0000000..6ffe6e8
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqsound_x11.cpp
@@ -0,0 +1,284 @@
+/****************************************************************************
+**
+** Implementation of TQSound class and TQAuServer internal class
+**
+** Created : 000117
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#define TQT_CLEAN_NAMESPACE
+
+#include "tqsound.h"
+
+#ifndef TQT_NO_SOUND
+
+#include "tqptrdict.h"
+#include "tqsocketnotifier.h"
+#include "tqapplication.h"
+
+
+#ifdef TQT_NAS_SUPPORT
+
+#include <audio/audiolib.h>
+#include <audio/soundlib.h>
+
+static AuServer *nas=0;
+
+static AuBool eventPred(AuServer *, AuEvent *e, AuPointer p)
+{
+ if (e && (e->type == AuEventTypeElementNotify)) {
+ if (e->auelementnotify.flow == *((AuFlowID *)p))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+class TQAuBucketNAS : public TQAuBucket {
+public:
+ TQAuBucketNAS(AuBucketID b, AuFlowID f = 0) : id(b), flow(f), stopped(TRUE), numplaying(0) { }
+ ~TQAuBucketNAS()
+ {
+ if ( nas ) {
+ AuSync(nas, FALSE);
+ AuDestroyBucket(nas, id, NULL);
+
+ AuEvent ev;
+ while (AuScanEvents(nas, AuEventsQueuedAfterFlush, TRUE, eventPred, &flow, &ev))
+ ;
+ }
+ }
+
+ AuBucketID id;
+ AuFlowID flow;
+ bool stopped;
+ int numplaying;
+};
+
+class TQAuServerNAS : public TQAuServer {
+ Q_OBJECT
+ TQ_OBJECT
+
+ TQSocketNotifier* sn;
+
+public:
+ TQAuServerNAS(TQObject* tqparent);
+ ~TQAuServerNAS();
+
+ void init(TQSound*);
+ void play(const TQString& filename);
+ void play(TQSound*);
+ void stop(TQSound*);
+ bool okay();
+ void setDone(TQSound*);
+
+public Q_SLOTS:
+ void dataReceived();
+ void soundDestroyed(TQObject *o);
+
+private:
+ TQAuBucketNAS* bucket(TQSound* s)
+ {
+ return (TQAuBucketNAS*)TQAuServer::bucket(s);
+ }
+};
+
+TQAuServerNAS::TQAuServerNAS(TQObject* tqparent) :
+ TQAuServer(tqparent,"Network Audio System")
+{
+ nas = AuOpenServer(NULL, 0, NULL, 0, NULL, NULL);
+ if (nas) {
+ AuSetCloseDownMode(nas, AuCloseDownDestroy, NULL);
+ // Ask TQt for async messages...
+ sn=new TQSocketNotifier(AuServerConnectionNumber(nas),
+ TQSocketNotifier::Read);
+ TQObject::connect(sn, TQT_SIGNAL(activated(int)),
+ this, TQT_SLOT(dataReceived()));
+ } else {
+ sn = 0;
+ }
+}
+
+TQAuServerNAS::~TQAuServerNAS()
+{
+ if ( nas )
+ AuCloseServer( nas );
+ delete sn;
+ nas = 0;
+}
+
+static TQPtrDict<void> *inprogress=0;
+
+void TQAuServerNAS::soundDestroyed(TQObject *o)
+{
+ if (inprogress) {
+ TQSound *so = static_cast<TQSound *>(o);
+ while (inprogress->remove(so))
+ ; // Loop while remove returns TRUE
+ }
+}
+
+void TQAuServerNAS::play(const TQString& filename)
+{
+ if (nas) {
+ int iv=100;
+ AuFixedPoint volume=AuFixedPointFromFraction(iv,100);
+ AuSoundPlayFromFile(nas, filename, AuNone, volume, NULL, NULL, NULL, NULL, NULL, NULL);
+ AuFlush(nas);
+ dataReceived();
+ AuFlush(nas);
+ tqApp->flushX();
+ }
+}
+
+static void callback( AuServer*, AuEventHandlerRec*, AuEvent* e, AuPointer p)
+{
+ if ( inprogress->tqfind(p) && e ) {
+ if (e->type==AuEventTypeElementNotify &&
+ e->auelementnotify.kind==AuElementNotifyKindState) {
+ if ( e->auelementnotify.cur_state == AuStateStop )
+ ((TQAuServerNAS*)inprogress->tqfind(p))->setDone((TQSound*)p);
+ }
+ }
+}
+
+void TQAuServerNAS::setDone(TQSound* s)
+{
+ if (nas) {
+ decLoop(s);
+ if (s->loopsRemaining() && !bucket(s)->stopped) {
+ bucket(s)->stopped = TRUE;
+ play(s);
+ } else {
+ if (--(bucket(s)->numplaying) == 0)
+ bucket(s)->stopped = TRUE;
+ inprogress->remove(s);
+ }
+ }
+}
+
+void TQAuServerNAS::play(TQSound* s)
+{
+ if (nas) {
+ ++(bucket(s)->numplaying);
+ if (!bucket(s)->stopped) {
+ stop(s);
+ }
+
+ bucket(s)->stopped = FALSE;
+ if ( !inprogress )
+ inprogress = new TQPtrDict<void>;
+ inprogress->insert(s,(void*)this);
+ int iv=100;
+ AuFixedPoint volume=AuFixedPointFromFraction(iv,100);
+ TQAuBucketNAS *b = bucket(s);
+ AuSoundPlayFromBucket(nas, b->id, AuNone, volume,
+ callback, s, 0, &b->flow, NULL, NULL, NULL);
+ AuFlush(nas);
+ dataReceived();
+ AuFlush(nas);
+ tqApp->flushX();
+ }
+}
+
+void TQAuServerNAS::stop(TQSound* s)
+{
+ if (nas && !bucket(s)->stopped) {
+ bucket(s)->stopped = TRUE;
+ AuStopFlow(nas, bucket(s)->flow, NULL);
+ AuFlush(nas);
+ dataReceived();
+ AuFlush(nas);
+ tqApp->flushX();
+ }
+}
+
+void TQAuServerNAS::init(TQSound* s)
+{
+ connect(s, TQT_SIGNAL(destroyed(TQObject *)),
+ this, TQT_SLOT(soundDestroyed(TQObject *)));
+
+ if ( nas ) {
+ AuBucketID b_id =
+ AuSoundCreateBucketFromFile(nas, s->fileName(),
+ 0 /*AuAccessAllMasks*/, NULL, NULL);
+ setBucket(s, new TQAuBucketNAS(b_id));
+ }
+}
+
+bool TQAuServerNAS::okay()
+{
+ return !!nas;
+}
+
+void TQAuServerNAS::dataReceived()
+{
+ AuHandleEvents(nas);
+}
+
+#include "tqsound_x11.tqmoc"
+
+#endif
+
+
+class TQAuServerNull : public TQAuServer {
+public:
+ TQAuServerNull(TQObject* tqparent);
+
+ void play(const TQString&) { }
+ void play(TQSound*s) { while(decLoop(s) > 0) /* nothing */ ; }
+ void stop(TQSound*) { }
+ bool okay() { return FALSE; }
+};
+
+TQAuServerNull::TQAuServerNull(TQObject* tqparent) :
+ TQAuServer(tqparent,"Null Audio Server")
+{
+}
+
+
+TQAuServer* qt_new_audio_server()
+{
+#ifdef TQT_NAS_SUPPORT
+ TQAuServer* s=new TQAuServerNAS(TQT_TQOBJECT(tqApp));
+ if (s->okay()) {
+ return s;
+ } else {
+ delete s;
+ }
+#endif
+ return new TQAuServerNull(TQT_TQOBJECT(tqApp));
+}
+
+#endif // TQT_NO_SOUND
diff --git a/tqtinterface/qt4/src/kernel/tqstyle.cpp b/tqtinterface/qt4/src/kernel/tqstyle.cpp
new file mode 100644
index 0000000..ac14dcb
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqstyle.cpp
@@ -0,0 +1,2186 @@
+/****************************************************************************
+**
+** Implementation of TQStyle class
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqstyle.h"
+#ifndef TQT_NO_STYLE
+#include "tqapplication.h"
+#include "tqpainter.h"
+#include "tqbitmap.h"
+#include "tqpixmapcache.h"
+
+#include <limits.h>
+
+#ifdef USE_QT4
+
+// // Default implementations in case Qt4 style objects are being used
+// int TQStyle::tqpixelMetric( QStyle::PixelMetric metric, const TQWidget *widget ) const {
+// // return QStyle::pixelMetric(metric, 0, widget);
+// printf("[WARNING] TQStyle::tqpixelMetric( QStyle::PixelMetric metric, const TQWidget *widget ) const unimplemented\n\r");
+// return 0;
+// }
+//
+// // End default implementations
+
+bool TQStyle::isA( const char *classname ) const
+{
+ if (tqstrcmp(classname, metaObject()->className()) == 0) return true;
+ else {
+ TQString cn = metaObject()->className();
+ if (cn[0] == 'T')
+ cn = cn.remove(0,1);
+ return (tqstrcmp(classname, cn.ascii()) == 0);
+ }
+}
+
+bool TQStyle::inherits( const char *classname ) const {
+ if (QStyle::inherits(classname)) return true;
+ else {
+ TQString cn = classname;
+ if (cn[0] != 'T')
+ cn = cn.prepend('T');
+ return QStyle::inherits(cn.ascii());
+ }
+}
+
+//const char *TQStyle::name(const char *defaultName) const {
+// TQString s = objectName();
+// return s.isEmpty()?defaultName:s.latin1_helper();
+//}
+
+const char *TQStyle::tqname() const {
+ if (dynamic_cast<const TQStyle*>(static_cast<const QStyle*>(static_cast<const QObject*>(this)))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ printf("[WARNING] Attempted to call TQStyle::tqname() on an object without a constructed TQStyle object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+const char *TQStyle::name() const {
+ if (dynamic_cast<const TQStyle*>(static_cast<const QStyle*>(static_cast<const QObject*>(this)))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ printf("[WARNING] Attempted to call TQStyle::name() on an object without a constructed TQStyle object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+TQMetaObject *TQStyle::tqmetaObject() const {
+ return TQT_TQOBJECT_CONST(this)->tqmetaObject();
+}
+
+/*!
+ Returns the appropriate area (see below) within rectangle \a r in
+ which to draw the \a text or \a pixmap using painter \a p. If \a
+ len is -1 (the default) all the \a text is drawn; otherwise only
+ the first \a len characters of \a text are drawn. The text is
+ aligned in accordance with the tqalignment \a flags (see
+ \l{TQt::AlignmentFlags}). The \a enabled bool indicates whether or
+ not the item is enabled.
+
+ If \a r is larger than the area needed to render the \a text the
+ rectangle that is returned will be offset within \a r in
+ accordance with the tqalignment \a flags. For example if \a flags is
+ \c AlignCenter the returned rectangle will be centered within \a
+ r. If \a r is smaller than the area needed the rectangle that is
+ returned will be \e larger than \a r (the smallest rectangle large
+ enough to render the \a text or \a pixmap).
+
+ By default, if both the text and the pixmap are not null, the
+ pixmap is drawn and the text is ignored.
+*/
+TQRect TQStyle::tqitemRect( QPainter *p, const QRect &r,
+ int flags, bool enabled, const QPixmap *pixmap,
+ const QString& text, int len ) const
+{
+ TQRect result;
+ int x = r.x();
+ int y = r.y();
+ int w = r.width();
+ int h = r.height();
+ TQt::GUIStyle gs = (TQt::GUIStyle)tqstyleHint( SH_GUIStyle );
+
+ if ( pixmap ) {
+ if ( (flags & TQt::AlignVCenter) == TQt::AlignVCenter )
+ y += h/2 - pixmap->height()/2;
+ else if ( (flags & TQt::AlignBottom) == TQt::AlignBottom)
+ y += h - pixmap->height();
+ if ( (flags & TQt::AlignRight) == TQt::AlignRight )
+ x += w - pixmap->width();
+ else if ( (flags & TQt::AlignHCenter) == TQt::AlignHCenter )
+ x += w/2 - pixmap->width()/2;
+ else if ( (flags & TQt::AlignLeft) != TQt::AlignLeft && TQApplication::reverseLayout() )
+ x += w - pixmap->width();
+ result = TQRect(x, y, pixmap->width(), pixmap->height());
+ } else if ( !text.isNull() && p ) {
+ result = TQT_TQPAINTER(p)->boundingRect( x, y, w, h, flags, text, len );
+ if ( gs == TQt::WindowsStyle && !enabled ) {
+ result.setWidth(result.width()+1);
+ result.setHeight(result.height()+1);
+ }
+ } else {
+ result = TQRect(x, y, w, h);
+ }
+
+ return result;
+}
+
+/*!
+ Draws the \a text or \a pixmap in rectangle \a r using painter \a
+ p and color group \a g. The pen color is specified with \a
+ penColor. The \a enabled bool indicates whether or not the item is
+ enabled; when reimplementing this bool should influence how the
+ item is drawn. If \a len is -1 (the default) all the \a text is
+ drawn; otherwise only the first \a len characters of \a text are
+ drawn. The text is aligned and wrapped according to the tqalignment
+ \a flags (see \l{TQt::AlignmentFlags}).
+
+ By default, if both the text and the pixmap are not null, the
+ pixmap is drawn and the text is ignored.
+*/
+void TQStyle::drawItem( TQPainter *p, const TQRect &r,
+ int flags, const TQColorGroup &g, bool enabled,
+ const TQPixmap *pixmap, const TQString& text, int len,
+ const TQColor* penColor ) const
+{
+ int x = r.x();
+ int y = r.y();
+ int w = r.width();
+ int h = r.height();
+ TQt::GUIStyle gs = (TQt::GUIStyle)tqstyleHint( SH_GUIStyle );
+
+ p->setPen( penColor?*penColor:g.foreground() );
+ if ( pixmap ) {
+ TQPixmap pm( *pixmap );
+ bool clip = (flags & TQt::DontClip) == 0;
+ if ( clip ) {
+ if ( pm.width() < w && pm.height() < h ) {
+ clip = FALSE;
+ } else {
+ p->save();
+ TQRegion cr = TQRect(x, y, w, h);
+ if (p->hasClipping())
+ cr &= p->clipRegion(TQPainter::CoordPainter);
+ p->setClipRegion(cr);
+ }
+ }
+ if ( (flags & TQt::AlignVCenter) == TQt::AlignVCenter )
+ y += h/2 - pm.height()/2;
+ else if ( (flags & TQt::AlignBottom) == TQt::AlignBottom)
+ y += h - pm.height();
+ if ( (flags & TQt::AlignRight) == TQt::AlignRight )
+ x += w - pm.width();
+ else if ( (flags & TQt::AlignHCenter) == TQt::AlignHCenter )
+ x += w/2 - pm.width()/2;
+ else if ( ((flags & TQt::AlignLeft) != TQt::AlignLeft) && TQApplication::reverseLayout() ) // AlignAuto && rightToLeft
+ x += w - pm.width();
+
+ if ( !enabled ) {
+ if ( pm.tqmask() ) { // pixmap with a tqmask
+ if ( !pm.selfMask() ) { // tqmask is not pixmap itself
+ TQPixmap pmm( *pm.tqmask() );
+ pmm.setMask( *((TQBitmap *)&pmm) );
+ pm = pmm;
+ }
+ } else if ( pm.depth() == 1 ) { // monochrome pixmap, no tqmask
+ pm.setMask( *((TQBitmap *)&pm) );
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+ } else { // color pixmap, no tqmask
+ TQString k;
+ k.sprintf( "$qt-drawitem-%x", pm.serialNumber() );
+ TQPixmap *tqmask = TQPixmapCache::tqfind(k);
+ bool del=FALSE;
+ if ( !tqmask ) {
+ tqmask = new TQPixmap( pm.createHeuristicMask() );
+ tqmask->setMask( *((TQBitmap*)tqmask) );
+ del = !TQPixmapCache::insert( k, tqmask );
+ }
+ pm = *tqmask;
+ if (del) delete tqmask;
+#endif
+ }
+ if ( gs == TQt::WindowsStyle ) {
+ p->setPen( g.light() );
+ p->drawPixmap( x+1, y+1, pm );
+ p->setPen( g.text() );
+ }
+ }
+ p->drawPixmap( x, y, pm );
+ if ( clip )
+ p->restore();
+ } else if ( !text.isNull() ) {
+ if ( gs == TQt::WindowsStyle && !enabled ) {
+ p->setPen( g.light() );
+ p->drawText( x+1, y+1, w, h, flags, text, len );
+ p->setPen( g.text() );
+ }
+ p->drawText( x, y, w, h, flags, text, len );
+ }
+}
+
+/*!
+ Initializes the appearance of a widget.
+
+ This function is called for every widget at some point after it
+ has been fully created but just \e before it is shown the very
+ first time.
+
+ Reasonable actions in this function might be to call
+ TQWidget::setBackgroundMode() for the widget. An example of highly
+ unreasonable use would be setting the tqgeometry! Reimplementing
+ this function gives you a back-door through which you can change
+ the appearance of a widget. With TQt 3.0's style engine you will
+ rarely need to write your own polish(); instead reimplement
+ drawItem(), drawPrimitive(), etc.
+
+ The TQWidget::inherits() function may provide enough information to
+ allow class-specific customizations. But be careful not to
+ hard-code things too much because new TQStyle subclasses are
+ expected to work reasonably with all current and \e future
+ widgets.
+
+ \sa unPolish()
+*/
+void TQStyle::polish( TQWidget*)
+{
+}
+
+/*!
+ Undoes the initialization of a widget's appearance.
+
+ This function is the counterpart to polish. It is called for every
+ polished widget when the style is dynamically changed. The former
+ style has to unpolish its settings before the new style can polish
+ them again.
+
+ \sa polish()
+*/
+void TQStyle::unPolish( TQWidget*)
+{
+}
+
+/*!
+ \overload
+ Late initialization of the TQApplication object.
+
+ \sa unPolish()
+*/
+void TQStyle::polish( TQApplication*)
+{
+}
+
+/*!
+ \overload
+
+ Undoes the application polish.
+
+ \sa polish()
+*/
+void TQStyle::unPolish( TQApplication*)
+{
+}
+
+/*!
+ \overload
+
+ The style may have certain requirements for color palettes. In
+ this function it has the chance to change the palette according to
+ these requirements.
+
+ \sa TQPalette, TQApplication::setPalette()
+*/
+void TQStyle::polish( TQPalette&)
+{
+}
+
+#else // USE_QT4
+
+class TQStylePrivate
+{
+public:
+ TQStylePrivate()
+ {
+ }
+};
+
+/*!
+ \class TQStyleOption tqstyle.h
+ \brief The TQStyleOption class specifies optional parameters for TQStyle functions.
+ \ingroup appearance
+
+ Some TQStyle functions take an optional argument specifying extra
+ information that is required for a paritical primitive or control.
+ So that the TQStyle class can be extended, TQStyleOption is used to
+ provide a variable-argument for these options.
+
+ The TQStyleOption class has constructors for each type of optional
+ argument, and this set of constructors may be extended in future
+ TQt releases. There are also corresponding access functions that
+ return the optional arguments: these too may be extended.
+
+ For each constructor, you should refer to the documentation of the
+ TQStyle functions to see the meaning of the arguments.
+
+ When calling TQStyle functions from your own widgets, you must only
+ pass the default TQStyleOption or the argument that TQStyle is
+ documented to accept. For example, if the function expects
+ TQStyleOption(TQMenuItem *, int), passing TQStyleOption(TQMenuItem *)
+ leaves the optional integer argument uninitialized.
+
+ When subclassing TQStyle, you must similarly only expect the
+ default or documented arguments. The other arguments will have
+ uninitialized values.
+
+ If you make your own TQStyle subclasses and your own widgets, you
+ can make a subclass of TQStyleOption to pass additional arguments
+ to your TQStyle subclass. You will need to cast the "const
+ TQStyleOption&" argument to your subclass, so be sure your style
+ has been called from your widget.
+*/
+
+/*!
+ \enum TQStyleOption::StyleOptionDefault
+
+ This enum value can be passed as the optional argument to any
+ TQStyle function.
+
+ \value Default
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(StyleOptionDefault)
+
+ The default option. This can always be passed as the optional
+ argument to TQStyle functions.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(int)
+
+ Pass one integer, \a in1. For example, headerSection.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(int, int)
+
+ Pass two integers, \a in1 and \a in2. For example, linewidth and
+ midlinewidth.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(int, int, int, int)
+
+ Pass four integers, \a in1, \a in2, \a in3 and \a in4.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(TQMenuItem*)
+
+ Pass a menu item, \a m.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(TQMenuItem*, int)
+
+ Pass a menu item and an integer, \a m and \a in1.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(TQMenuItem*, int, int)
+
+ Pass a menu item and two integers, \a m, \a in1 and \a in2.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(const TQColor&)
+
+ Pass a color, \a c.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(TQTab*)
+
+ Pass a TQTab, \a t.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(TQListViewItem*)
+
+ Pass a TQListViewItem, \a i.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(TQt::ArrowType)
+
+ Pass an TQt::ArrowType, \a a.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption(TQCheckListItem* i)
+
+ Pass a TQCheckListItem, \a i.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption( const TQRect &r )
+
+ Pass a TQRect, \a r.
+*/
+
+/*!
+ \fn TQStyleOption::TQStyleOption( TQWidget *w )
+
+ Pass a TQWidget, \a w.
+*/
+
+/*!
+ \fn bool TQStyleOption::isDefault() const
+
+ Returns TRUE if the option was constructed with the default
+ constructor; otherwise returns FALSE.
+*/
+
+/*!
+ \fn int TQStyleOption::day() const
+
+ Returns the index of the day in the month if the appropriate
+ constructor was called; otherwise the return value is undefined.
+*/
+
+/*!
+ \fn int TQStyleOption::lineWidth() const
+
+ Returns the line width if the appropriate constructor was called;
+ otherwise the return value is undefined.
+*/
+
+/*!
+ \fn int TQStyleOption::midLineWidth() const
+
+ Returns the mid-line width if the appropriate constructor was
+ called; otherwise the return value is undefined.
+*/
+
+/*!
+ \fn int TQStyleOption::frameShape() const
+
+ Returns a TQFrame::Shape value if the appropriate constructor was
+ called; otherwise the return value is undefined.
+*/
+
+/*!
+ \fn int TQStyleOption::frameShadow() const
+
+ Returns a TQFrame::Shadow value if the appropriate constructor was
+ called; otherwise the return value is undefined.
+*/
+
+/*!
+ \fn TQMenuItem* TQStyleOption::menuItem() const
+
+ Returns a menu item if the appropriate constructor was called;
+ otherwise the return value is undefined.
+*/
+
+/*!
+ \fn int TQStyleOption::maxIconWidth() const
+
+ Returns the maximum width of the menu item check area if the
+ appropriate constructor was called; otherwise the return value is
+ undefined.
+*/
+
+/*!
+ \fn int TQStyleOption::tabWidth() const
+
+ Returns the tab indent width if the appropriate constructor was
+ called; otherwise the return value is undefined.
+*/
+
+/*!
+ \fn int TQStyleOption::headerSection() const
+
+ Returns the header section if the appropriate constructor was
+ called; otherwise the return value is undefined.
+*/
+
+/*!
+ \fn const TQColor& TQStyleOption::color() const
+
+ Returns a color if the appropriate constructor was called;
+ otherwise the return value is undefined.
+*/
+
+/*!
+ \fn TQTab* TQStyleOption::tab() const
+
+ Returns a TQTabBar tab if the appropriate constructor was called;
+ otherwise the return value is undefined.
+*/
+
+/*!
+ \fn TQListViewItem* TQStyleOption::listViewItem() const
+
+ Returns a TQListView item if the appropriate constructor was
+ called; otherwise the return value is undefined.
+*/
+
+/*!
+ \fn TQt::ArrowType TQStyleOption::arrowType() const
+
+ Returns an arrow type if the appropriate constructor was called;
+ otherwise the return value is undefined.
+*/
+
+/*!
+ \fn TQCheckListItem* TQStyleOption::checkListItem() const
+
+ Returns a check list item if the appropriate constructor was
+ called; otherwise the return value is undefined.
+*/
+
+/*!
+ \fn TQRect TQStyleOption::rect() const
+
+ Returns a rectangle if the appropriate constructor was called;
+ otherwise the return value is undefined.
+*/
+
+/*!
+ \fn TQWidget* TQStyleOption::widget() const
+
+ Returns a pointer to a widget if the appropriate constructor was called;
+ otherwise the return value is undefined.
+*/
+
+/*!
+ \class TQStyle tqstyle.h
+ \brief The TQStyle class specifies the look and feel of a GUI.
+ \ingroup appearance
+
+ A large number of GUI elements are common to many widgets. The
+ TQStyle class allows the look of these elements to be modified
+ across all widgets that use the TQStyle functions. It also
+ provides two feel options: Motif and Windows.
+
+ Although it is not possible to fully enumerate the look of
+ graphical elements and the feel of widgets in a GUI, TQStyle
+ provides a considerable amount of control and customisability.
+
+ In TQt 1.x the look and feel option for widgets was specified by a
+ single value: the GUIStyle. Starting with TQt 2.0, this notion was
+ expanded to allow the look to be specified by virtual drawing
+ functions.
+
+ Derived classes may reimplement some or all of the drawing
+ functions to modify the look of all widgets that use those
+ functions.
+
+ Languages written from right to left (such as Arabic and Hebrew)
+ usually also mirror the whole tqlayout of widgets. If you design a
+ style, you should take special care when drawing asymmetric
+ elements to make sure that they also look correct in a mirrored
+ tqlayout. You can start your application with \c -reverse to check
+ the mirrored tqlayout. Also notice, that for a reversed tqlayout, the
+ light usually comes from top right instead of top left.
+
+ The actual reverse tqlayout is performed automatically when
+ possible. However, for the sake of flexibility, the translation
+ cannot be performed everywhere. The documentation for each
+ function in the TQStyle API states whether the function
+ expects/returns logical or screen coordinates. Using logical
+ coordinates (in ComplexControls, for example) provides great
+ flexibility in controlling the look of a widget. Use tqvisualRect()
+ when necessary to translate logical coordinates into screen
+ coordinates for drawing.
+
+ In TQt versions prior to 3.0, if you wanted a low level route into
+ changing the appearance of a widget, you would reimplement
+ polish(). With the new 3.0 style engine the recommended approach
+ is to reimplement the draw functions, for example drawItem(),
+ drawPrimitive(), tqdrawControl(), tqdrawControlMask(),
+ tqdrawComplexControl() and tqdrawComplexControlMask(). Each of these
+ functions is called with a range of parameters that provide
+ information that you can use to determine how to draw them, e.g.
+ style flags, rectangle, color group, etc.
+
+ For information on changing elements of an existing style or
+ creating your own style see the \link customstyles.html Style
+ overview\endlink.
+
+ Styles can also be created as \link plugins-howto.html
+ plugins\endlink.
+*/
+
+/*!
+ \enum TQt::GUIStyle
+
+ \obsolete
+
+ \value WindowsStyle
+ \value MotifStyle
+ \value MacStyle
+ \value Win3Style
+ \value PMStyle
+*/
+
+/*!
+ \enum TQt::UIEffect
+
+ \value UI_General
+ \value UI_AnimateMenu
+ \value UI_FadeMenu
+ \value UI_AnimateCombo
+ \value UI_AnimateTooltip
+ \value UI_FadeTooltip
+ \value UI_AnimateToolBox Reserved
+*/
+
+/*!
+ Constructs a TQStyle.
+*/
+TQStyle::TQStyle()
+{
+ d = new TQStylePrivate;
+}
+
+/*!
+ Destroys the style and frees all allocated resources.
+*/
+TQStyle::~TQStyle()
+{
+ delete d;
+ d = 0;
+}
+
+/*
+ \fn GUIStyle TQStyle::guiStyle() const
+ \obsolete
+
+ Returns an indicator to the additional "feel" component of a
+ style. Current supported values are TQt::WindowsStyle and TQt::MotifStyle.
+*/
+
+
+
+/*!
+ Initializes the appearance of a widget.
+
+ This function is called for every widget at some point after it
+ has been fully created but just \e before it is shown the very
+ first time.
+
+ Reasonable actions in this function might be to call
+ TQWidget::setBackgroundMode() for the widget. An example of highly
+ unreasonable use would be setting the tqgeometry! Reimplementing
+ this function gives you a back-door through which you can change
+ the appearance of a widget. With TQt 3.0's style engine you will
+ rarely need to write your own polish(); instead reimplement
+ drawItem(), drawPrimitive(), etc.
+
+ The TQWidget::inherits() function may provide enough information to
+ allow class-specific customizations. But be careful not to
+ hard-code things too much because new TQStyle subclasses are
+ expected to work reasonably with all current and \e future
+ widgets.
+
+ \sa unPolish()
+*/
+void TQStyle::polish( TQWidget*)
+{
+}
+
+/*!
+ Undoes the initialization of a widget's appearance.
+
+ This function is the counterpart to polish. It is called for every
+ polished widget when the style is dynamically changed. The former
+ style has to unpolish its settings before the new style can polish
+ them again.
+
+ \sa polish()
+*/
+void TQStyle::unPolish( TQWidget*)
+{
+}
+
+
+/*!
+ \overload
+ Late initialization of the TQApplication object.
+
+ \sa unPolish()
+*/
+void TQStyle::polish( TQApplication*)
+{
+}
+
+/*!
+ \overload
+
+ Undoes the application polish.
+
+ \sa polish()
+*/
+void TQStyle::unPolish( TQApplication*)
+{
+}
+
+/*!
+ \overload
+
+ The style may have certain requirements for color palettes. In
+ this function it has the chance to change the palette according to
+ these requirements.
+
+ \sa TQPalette, TQApplication::setPalette()
+*/
+void TQStyle::polish( TQPalette&)
+{
+}
+
+/*!
+ Polishes the popup menu according to the GUI style. This usually
+ means setting the mouse tracking
+ (\l{TQPopupMenu::setMouseTracking()}) and whether the menu is
+ checkable by default (\l{TQPopupMenu::setCheckable()}).
+*/
+void TQStyle::polishPopupMenu( TQPopupMenu *)
+{
+}
+
+/*!
+ Returns the appropriate area (see below) within rectangle \a r in
+ which to draw the \a text or \a pixmap using painter \a p. If \a
+ len is -1 (the default) all the \a text is drawn; otherwise only
+ the first \a len characters of \a text are drawn. The text is
+ aligned in accordance with the tqalignment \a flags (see
+ \l{TQt::AlignmentFlags}). The \a enabled bool indicates whether or
+ not the item is enabled.
+
+ If \a r is larger than the area needed to render the \a text the
+ rectangle that is returned will be offset within \a r in
+ accordance with the tqalignment \a flags. For example if \a flags is
+ \c AlignCenter the returned rectangle will be centered within \a
+ r. If \a r is smaller than the area needed the rectangle that is
+ returned will be \e larger than \a r (the smallest rectangle large
+ enough to render the \a text or \a pixmap).
+
+ By default, if both the text and the pixmap are not null, the
+ pixmap is drawn and the text is ignored.
+*/
+TQRect TQStyle::tqitemRect( TQPainter *p, const TQRect &r,
+ int flags, bool enabled, const TQPixmap *pixmap,
+ const TQString& text, int len ) const
+{
+ TQRect result;
+ int x = r.x();
+ int y = r.y();
+ int w = r.width();
+ int h = r.height();
+ GUIStyle gs = (GUIStyle)tqstyleHint( SH_GUIStyle );
+
+ if ( pixmap ) {
+ if ( (flags & TQt::AlignVCenter) == TQt::AlignVCenter )
+ y += h/2 - pixmap->height()/2;
+ else if ( (flags & TQt::AlignBottom) == TQt::AlignBottom)
+ y += h - pixmap->height();
+ if ( (flags & TQt::AlignRight) == TQt::AlignRight )
+ x += w - pixmap->width();
+ else if ( (flags & TQt::AlignHCenter) == TQt::AlignHCenter )
+ x += w/2 - pixmap->width()/2;
+ else if ( (flags & TQt::AlignLeft) != TQt::AlignLeft && TQApplication::reverseLayout() )
+ x += w - pixmap->width();
+ result = TQRect(x, y, pixmap->width(), pixmap->height());
+ } else if ( !text.isNull() && p ) {
+ result = p->boundingRect( x, y, w, h, flags, text, len );
+ if ( gs == TQt::WindowsStyle && !enabled ) {
+ result.setWidth(result.width()+1);
+ result.setHeight(result.height()+1);
+ }
+ } else {
+ result = TQRect(x, y, w, h);
+ }
+
+ return result;
+}
+
+
+/*!
+ Draws the \a text or \a pixmap in rectangle \a r using painter \a
+ p and color group \a g. The pen color is specified with \a
+ penColor. The \a enabled bool indicates whether or not the item is
+ enabled; when reimplementing this bool should influence how the
+ item is drawn. If \a len is -1 (the default) all the \a text is
+ drawn; otherwise only the first \a len characters of \a text are
+ drawn. The text is aligned and wrapped according to the tqalignment
+ \a flags (see \l{TQt::AlignmentFlags}).
+
+ By default, if both the text and the pixmap are not null, the
+ pixmap is drawn and the text is ignored.
+*/
+void TQStyle::drawItem( TQPainter *p, const TQRect &r,
+ int flags, const TQColorGroup &g, bool enabled,
+ const TQPixmap *pixmap, const TQString& text, int len,
+ const TQColor* penColor ) const
+{
+ int x = r.x();
+ int y = r.y();
+ int w = r.width();
+ int h = r.height();
+ GUIStyle gs = (GUIStyle)tqstyleHint( SH_GUIStyle );
+
+ p->setPen( penColor?*penColor:g.foreground() );
+ if ( pixmap ) {
+ TQPixmap pm( *pixmap );
+ bool clip = (flags & TQt::DontClip) == 0;
+ if ( clip ) {
+ if ( pm.width() < w && pm.height() < h ) {
+ clip = FALSE;
+ } else {
+ p->save();
+ TQRegion cr = TQRect(x, y, w, h);
+ if (p->hasClipping())
+ cr &= p->clipRegion(TQPainter::CoordPainter);
+ p->setClipRegion(cr);
+ }
+ }
+ if ( (flags & TQt::AlignVCenter) == TQt::AlignVCenter )
+ y += h/2 - pm.height()/2;
+ else if ( (flags & TQt::AlignBottom) == TQt::AlignBottom)
+ y += h - pm.height();
+ if ( (flags & TQt::AlignRight) == TQt::AlignRight )
+ x += w - pm.width();
+ else if ( (flags & TQt::AlignHCenter) == TQt::AlignHCenter )
+ x += w/2 - pm.width()/2;
+ else if ( ((flags & TQt::AlignLeft) != TQt::AlignLeft) && TQApplication::reverseLayout() ) // AlignAuto && rightToLeft
+ x += w - pm.width();
+
+ if ( !enabled ) {
+ if ( pm.tqmask() ) { // pixmap with a tqmask
+ if ( !pm.selfMask() ) { // tqmask is not pixmap itself
+ TQPixmap pmm( *pm.tqmask() );
+ pmm.setMask( *((TQBitmap *)&pmm) );
+ pm = pmm;
+ }
+ } else if ( pm.depth() == 1 ) { // monochrome pixmap, no tqmask
+ pm.setMask( *((TQBitmap *)&pm) );
+#ifndef TQT_NO_IMAGE_HEURISTIC_MASK
+ } else { // color pixmap, no tqmask
+ TQString k;
+ k.sprintf( "$qt-drawitem-%x", pm.serialNumber() );
+ TQPixmap *tqmask = TQPixmapCache::tqfind(k);
+ bool del=FALSE;
+ if ( !tqmask ) {
+ tqmask = new TQPixmap( pm.createHeuristicMask() );
+ tqmask->setMask( *((TQBitmap*)tqmask) );
+ del = !TQPixmapCache::insert( k, tqmask );
+ }
+ pm = *tqmask;
+ if (del) delete tqmask;
+#endif
+ }
+ if ( gs == TQt::WindowsStyle ) {
+ p->setPen( g.light() );
+ p->drawPixmap( x+1, y+1, pm );
+ p->setPen( g.text() );
+ }
+ }
+ p->drawPixmap( x, y, pm );
+ if ( clip )
+ p->restore();
+ } else if ( !text.isNull() ) {
+ if ( gs == TQt::WindowsStyle && !enabled ) {
+ p->setPen( g.light() );
+ p->drawText( x+1, y+1, w, h, flags, text, len );
+ p->setPen( g.text() );
+ }
+ p->drawText( x, y, w, h, flags, text, len );
+ }
+}
+
+/*!
+ \enum TQStyle::PrimitiveElement
+
+ This enum represents the PrimitiveElements of a style. A
+ PrimitiveElement is a common GUI element, such as a checkbox
+ indicator or pushbutton bevel.
+
+ \value PE_ButtonCommand button used to initiate an action, for
+ example, a TQPushButton.
+ \value PE_ButtonDefault this button is the default button, e.g.
+ in a dialog.
+ \value PE_ButtonBevel generic button bevel.
+ \value PE_ButtonTool tool button, for example, a TQToolButton.
+ \value PE_ButtonDropDown drop down button, for example, a tool
+ button that displays a popup menu, for example, TQPopupMenu.
+
+
+ \value PE_FocusRect generic focus indicator.
+
+
+ \value PE_ArrowUp up arrow.
+ \value PE_ArrowDown down arrow.
+ \value PE_ArrowRight right arrow.
+ \value PE_ArrowLeft left arrow.
+
+
+ \value PE_SpinWidgetUp up symbol for a spin widget, for example a
+ TQSpinBox.
+ \value PE_SpinWidgetDown down symbol for a spin widget.
+ \value PE_SpinWidgetPlus increase symbol for a spin widget.
+ \value PE_SpinWidgetMinus decrease symbol for a spin widget.
+
+
+ \value PE_Indicator on/off indicator, for example, a TQCheckBox.
+ \value PE_IndicatorMask bitmap tqmask for an indicator.
+ \value PE_ExclusiveIndicator exclusive on/off indicator, for
+ example, a TQRadioButton.
+ \value PE_ExclusiveIndicatorMask bitmap tqmask for an exclusive indicator.
+
+
+ \value PE_DockWindowHandle tear off handle for dock windows and
+ toolbars, for example \l{TQDockWindow}s and \l{TQToolBar}s.
+ \value PE_DockWindowSeparator item separator for dock window and
+ toolbar contents.
+ \value PE_DockWindowResizeHandle resize handle for dock windows.
+
+ \value PE_Splitter splitter handle; see also TQSplitter.
+
+
+ \value PE_Panel generic panel frame; see also TQFrame.
+ \value PE_PanelPopup panel frame for popup windows/menus; see also
+ TQPopupMenu.
+ \value PE_PanelMenuBar panel frame for menu bars.
+ \value PE_PanelDockWindow panel frame for dock windows and toolbars.
+ \value PE_PanelTabWidget panel frame for tab widgets.
+ \value PE_PanelLineEdit panel frame for line edits.
+ \value PE_PanelGroupBox panel frame for group boxes.
+
+ \value PE_TabBarBase area below tabs in a tab widget, for example,
+ TQTab.
+
+
+ \value PE_HeaderSection section of a list or table header; see also
+ TQHeader.
+ \value PE_HeaderArrow arrow used to indicate sorting on a list or table
+ header
+ \value PE_tqStatusBarSection section of a status bar; see also
+ TQStatusBar.
+
+
+ \value PE_GroupBoxFrame frame around a group box; see also
+ TQGroupBox.
+ \value PE_WindowFrame frame around a MDI window or a docking window
+
+
+ \value PE_Separator generic separator.
+
+
+ \value PE_SizeGrip window resize handle; see also TQSizeGrip.
+
+
+ \value PE_CheckMark generic check mark; see also TQCheckBox.
+
+
+ \value PE_ScrollBarAddLine scrollbar line increase indicator
+ (i.e. scroll down); see also TQScrollBar.
+ \value PE_ScrollBarSubLine scrollbar line decrease indicator (i.e. scroll up).
+ \value PE_ScrollBarAddPage scolllbar page increase indicator (i.e. page down).
+ \value PE_ScrollBarSubPage scrollbar page decrease indicator (i.e. page up).
+ \value PE_ScrollBarSlider scrollbar slider
+ \value PE_ScrollBarFirst scrollbar first line indicator (i.e. home).
+ \value PE_ScrollBarLast scrollbar last line indicator (i.e. end).
+
+
+ \value PE_ProgressBarChunk section of a progress bar indicator; see
+ also TQProgressBar.
+
+ \value PE_CheckListController controller part of a listview item
+ \value PE_CheckListIndicator checkbox part of a listview item
+ \value PE_CheckListExclusiveIndicator radiobutton part of a listview item
+ \value PE_RubberBand rubber band used in such things as iconview
+
+ \value PE_CustomBase base value for custom PrimitiveElements.
+ All values above this are reserved for custom use. Custom
+ values must be greater than this value.
+
+ \sa drawPrimitive()
+*/
+/*! \enum TQStyle::SFlags
+ \internal
+*/
+/*! \enum TQStyle::SCFlags
+ \internal
+*/
+
+/*!
+ \enum TQStyle::StyleFlags
+
+ This enum represents flags for drawing PrimitiveElements. Not all
+ primitives use all of these flags. Note that these flags may mean
+ different things to different primitives. For an explanation of
+ the relationship between primitives and their flags, as well as
+ the different meanings of the flags, see the \link
+ customstyles.html Style overview\endlink.
+
+ \value Style_Default
+ \value Style_Enabled
+ \value Style_Raised
+ \value Style_Sunken
+ \value Style_Off
+ \value Style_NoChange
+ \value Style_On
+ \value Style_Down
+ \value Style_Horizontal
+ \value Style_HasFocus
+ \value Style_Top
+ \value Style_Bottom
+ \value Style_FocusAtBorder
+ \value Style_AutoRaise
+ \value Style_MouseOver
+ \value Style_Up
+ \value Style_Selected
+ \value Style_HasFocus
+ \value Style_Active
+ \value Style_ButtonDefault
+
+ \sa drawPrimitive()
+*/
+
+/*!
+ \fn void TQStyle::drawPrimitive( PrimitiveElement pe, TQPainter *p, const TQRect &r, const TQColorGroup &cg, SFlags flags, const TQStyleOption& opt) const
+
+ Draws the style PrimitiveElement \a pe using the painter \a p in
+ the area \a r. Colors are used from the color group \a cg.
+
+ The rect \a r should be in screen coordinates.
+
+ The \a flags argument is used to control how the PrimitiveElement
+ is drawn. Multiple flags can be OR'ed together.
+
+ For example, a pressed button would be drawn with the flags \c
+ Style_Enabled and \c Style_Down.
+
+ The \a opt argument can be used to control how various
+ PrimitiveElements are drawn. Note that \a opt may be the default
+ value even for PrimitiveElements that make use of extra options.
+ When \a opt is non-default, it is used as follows:
+
+ \table
+ \header \i PrimitiveElement \i Options \i Notes
+ \row \i \l PE_FocusRect
+ \i \l TQStyleOption ( const \l TQColor & bg )
+ \list
+ \i opt.\link TQStyleOption::color() color\endlink()
+ \endlist
+ \i \e bg is the background color on which the focus rect is being drawn.
+ \row \i12 \l PE_Panel
+ \i12 \l TQStyleOption ( int linewidth, int midlinewidth )
+ \list
+ \i opt.\link TQStyleOption::lineWidth() lineWidth\endlink()
+ \i opt.\link TQStyleOption::midLineWidth() midLineWidth\endlink()
+ \endlist
+ \i \e linewidth is the line width for drawing the panel.
+ \row \i \e midlinewidth is the mid-line width for drawing the panel.
+ \row \i12 \l PE_PanelPopup
+ \i12 \l TQStyleOption ( int linewidth, int midlinewidth )
+ \list
+ \i opt.\link TQStyleOption::lineWidth() lineWidth\endlink()
+ \i opt.\link TQStyleOption::midLineWidth() midLineWidth\endlink()
+ \endlist
+ \i \e linewidth is the line width for drawing the panel.
+ \row \i \e midlinewidth is the mid-line width for drawing the panel.
+ \row \i12 \l PE_PanelMenuBar
+ \i12 \l TQStyleOption ( int linewidth, int midlinewidth )
+ \list
+ \i opt.\link TQStyleOption::lineWidth() lineWidth\endlink()
+ \i opt.\link TQStyleOption::midLineWidth() midLineWidth\endlink()
+ \endlist
+ \i \e linewidth is the line width for drawing the panel.
+ \row \i \e midlinewidth is the mid-line width for drawing the panel.
+ \row \i12 \l PE_PanelDockWindow
+ \i12 \l TQStyleOption ( int linewidth, int midlinewidth )
+ \list
+ \i opt.\link TQStyleOption::lineWidth() lineWidth\endlink()
+ \i opt.\link TQStyleOption::midLineWidth() midLineWidth\endlink()
+ \endlist
+ \i \e linewidth is the line width for drawing the panel.
+ \row \i \e midlinewidth is the mid-line width for drawing the panel.
+ \row \i14 \l PE_GroupBoxFrame
+ \i14 \l TQStyleOption ( int linewidth, int midlinewidth, int tqshape, int shadow )
+ \list
+ \i opt.\link TQStyleOption::lineWidth() lineWidth\endlink()
+ \i opt.\link TQStyleOption::midLineWidth() midLineWidth\endlink()
+ \i opt.\link TQStyleOption::frameShape() frameShape\endlink()
+ \i opt.\link TQStyleOption::frameShadow() frameShadow\endlink()
+ \endlist
+ \i \e linewidth is the line width for the group box.
+ \row \i \e midlinewidth is the mid-line width for the group box.
+ \row \i \e tqshape is the \link TQFrame::frameShape frame tqshape \endlink
+ for the group box.
+ \row \i \e shadow is the \link TQFrame::frameShadow frame shadow \endlink
+ for the group box.
+ \endtable
+
+
+ For all other \link TQStyle::PrimitiveElement
+ PrimitiveElements\endlink, \a opt is unused.
+
+ \sa StyleFlags
+*/
+
+/*!
+ \enum TQStyle::ControlElement
+
+ This enum represents a ControlElement. A ControlElement is part of
+ a widget that performs some action or displays information to the
+ user.
+
+ \value CE_PushButton the bevel and default indicator of a TQPushButton.
+ \value CE_PushButtonLabel the label (iconset with text or pixmap)
+ of a TQPushButton.
+
+ \value CE_CheckBox the indicator of a TQCheckBox.
+ \value CE_CheckBoxLabel the label (text or pixmap) of a TQCheckBox.
+
+ \value CE_RadioButton the indicator of a TQRadioButton.
+ \value CE_RadioButtonLabel the label (text or pixmap) of a TQRadioButton.
+
+ \value CE_TabBarTab the tab within a TQTabBar (a TQTab).
+ \value CE_TabBarLabel the label within a TQTab.
+
+ \value CE_ProgressBarGroove the groove where the progress
+ indicator is drawn in a TQProgressBar.
+ \value CE_ProgressBarContents the progress indicator of a TQProgressBar.
+ \value CE_ProgressBarLabel the text label of a TQProgressBar.
+
+ \value CE_PopupMenuItem a menu item in a TQPopupMenu.
+ \value CE_PopupMenuScroller scrolling areas in a popumenu when the
+ style supports scrolling.
+ \value CE_PopupMenuHorizontalExtra extra frame area set aside with PM_PopupMenuFrameHorizontalExtra
+ \value CE_PopupMenuVerticalExtra extra frame area set aside with PM_PopupMenuFrameVerticalExtra
+
+ \value CE_MenuBarItem a menu item in a TQMenuBar.
+
+ \value CE_ToolButtonLabel a tool button's label.
+
+ \value CE_MenuBarEmptyArea the empty area of a TQMenuBar.
+ \value CE_DockWindowEmptyArea the empty area of a TQDockWindow.
+
+ \value CE_ToolBoxTab the toolbox's tab area
+ \value CE_HeaderLabel the header's label
+
+ \value CE_CustomBase base value for custom ControlElements. All values above
+ this are reserved for custom use. Therefore, custom values must be
+ greater than this value.
+
+ \sa tqdrawControl()
+*/
+
+/*!
+ \fn void TQStyle::tqdrawControl( ControlElement element, TQPainter *p, const TQWidget *widget, const TQRect &r, const TQColorGroup &cg, SFlags how, const TQStyleOption& opt) const
+
+ Draws the ControlElement \a element using the painter \a p in the
+ area \a r. Colors are used from the color group \a cg.
+
+ The rect \a r should be in screen coordinates.
+
+ The \a how argument is used to control how the ControlElement is
+ drawn. Multiple flags can be OR'ed together. See the table below
+ for an explanation of which flags are used with the various
+ ControlElements.
+
+ The \a widget argument is a pointer to a TQWidget or one of its
+ subclasses. The widget can be cast to the appropriate type based
+ on the value of \a element. The \a opt argument can be used to
+ pass extra information required when drawing the ControlElement.
+ Note that \a opt may be the default value even for ControlElements
+ that can make use of the extra options. See the table below for
+ the appropriate \a widget and \a opt usage:
+
+ \table
+ \header \i ControlElement<br>\& Widget Cast
+ \i Style Flags
+ \i Notes
+ \i Options
+ \i Notes
+
+ \row \i16 \l{CE_PushButton}(const \l TQPushButton *)
+
+ and
+
+ \l{CE_PushButtonLabel}(const \l TQPushButton *)
+ \i \l Style_Enabled \i Set if the button is enabled.
+ \i16 Unused.
+ \i16 &nbsp;
+ \row \i \l Style_HasFocus \i Set if the button has input focus.
+ \row \i \l Style_Raised \i Set if the button is not down, not on and not flat.
+ \row \i \l Style_On \i Set if the button is a toggle button and toggled on.
+ \row \i \l Style_Down \i Set if the button is down (i.e., the mouse button or
+ space bar is pressed on the button).
+ \row \i \l Style_ButtonDefault \i Set if the button is a default button.
+
+ \row \i16 \l{CE_CheckBox}(const \l TQCheckBox *)
+
+ and
+
+ \l{CE_CheckBoxLabel}(const \l TQCheckBox *)
+
+ \i \l Style_Enabled \i Set if the checkbox is enabled.
+ \i16 Unused.
+ \i16 &nbsp;
+ \row \i \l Style_HasFocus \i Set if the checkbox has input focus.
+ \row \i \l Style_On \i Set if the checkbox is checked.
+ \row \i \l Style_Off \i Set if the checkbox is not checked.
+ \row \i \l Style_NoChange \i Set if the checkbox is in the NoChange state.
+ \row \i \l Style_Down \i Set if the checkbox is down (i.e., the mouse button or
+ space bar is pressed on the button).
+
+ \row \i15 \l{CE_RadioButton}(const TQRadioButton *)
+
+ and
+
+ \l{CE_RadioButtonLabel}(const TQRadioButton *)
+ \i \l Style_Enabled \i Set if the radiobutton is enabled.
+ \i15 Unused.
+ \i15 &nbsp;
+ \row \i \l Style_HasFocus \i Set if the radiobutton has input focus.
+ \row \i \l Style_On \i Set if the radiobutton is checked.
+ \row \i \l Style_Off \i Set if the radiobutton is not checked.
+ \row \i \l Style_Down \i Set if the radiobutton is down (i.e., the mouse
+ button or space bar is pressed on the radiobutton).
+
+ \row \i12 \l{CE_TabBarTab}(const \l TQTabBar *)
+
+ and
+
+ \l{CE_TabBarLabel}(const \l TQTabBar *)
+
+ \i \l Style_Enabled \i Set if the tabbar and tab is enabled.
+ \i12 \l TQStyleOption ( \l TQTab *t )
+ \list
+ \i opt.\link TQStyleOption::tab() tab\endlink()
+ \endlist
+ \i12 \e t is the TQTab being drawn.
+ \row \i \l Style_Selected \i Set if the tab is the current tab.
+
+ \row \i12 \l{CE_ProgressBarGroove}(const TQProgressBar *)
+
+ and
+
+ \l{CE_ProgressBarContents}(const TQProgressBar *)
+
+ and
+
+ \l{CE_ProgressBarLabel}(const TQProgressBar *)
+
+ \i \l Style_Enabled \i Set if the progressbar is enabled.
+ \i12 Unused.
+ \i12 &nbsp;
+ \row \i \l Style_HasFocus \i Set if the progressbar has input focus.
+
+ \row \i13 \l{CE_PopupMenuItem}(const \l TQPopupMenu *)
+ \i \l Style_Enabled \i Set if the menuitem is enabled.
+ \i13 \l TQStyleOption ( TQMenuItem *mi, int tabwidth, int maxpmwidth )
+ \list
+ \i opt.\link TQStyleOption::menuItem() menuItem\endlink()
+ \i opt.\link TQStyleOption::tabWidth() tabWidth\endlink()
+ \i opt.\link TQStyleOption::maxIconWidth() maxIconWidth\endlink()
+ \endlist
+ \i \e mi is the menu item being drawn. TQMenuItem is currently an
+ internal class.
+ \row \i \l Style_Active \i Set if the menuitem is the current item.
+ \i \e tabwidth is the width of the tab column where key accelerators
+ are drawn.
+ \row \i \l Style_Down \i Set if the menuitem is down (i.e., the mouse button
+ or space bar is pressed).
+ \i \e maxpmwidth is the maximum width of the check column where
+ checkmarks and iconsets are drawn.
+
+ \row \i14 \l{CE_MenuBarItem}(const \l TQMenuBar *)
+ \i \l Style_Enabled \i Set if the menuitem is enabled
+ \i14 \l TQStyleOption ( TQMenuItem *mi )
+ \list
+ \i opt.\link TQStyleOption::menuItem() menuItem\endlink()
+ \endlist
+ \i14 \e mi is the menu item being drawn.
+ \row \i \l Style_Active \i Set if the menuitem is the current item.
+ \row \i \l Style_Down \i Set if the menuitem is down (i.e., a mouse button or
+ the space bar is pressed).
+ \row \i \l Style_HasFocus \i Set if the menubar has input focus.
+
+ \row \i17 \l{CE_ToolButtonLabel}(const \l TQToolButton *)
+ \i \l Style_Enabled \i Set if the toolbutton is enabled.
+ \i17 \l TQStyleOption ( \l ArrowType t )
+ \list
+ \i opt.\link TQStyleOption::arrowType() arrowType\endlink()
+ \endlist
+ \i17 When the tool button only tqcontains an arrow, \e t is the
+ arrow's type.
+ \row \i \l Style_HasFocus \i Set if the toolbutton has input focus.
+ \row \i \l Style_Down \i Set if the toolbutton is down (i.e., a
+ mouse button or the space is pressed).
+ \row \i \l Style_On \i Set if the toolbutton is a toggle button
+ and is toggled on.
+ \row \i \l Style_AutoRaise \i Set if the toolbutton has auto-raise enabled.
+ \row \i \l Style_MouseOver \i Set if the mouse pointer is over the toolbutton.
+ \row \i \l Style_Raised \i Set if the button is not down, not on and doesn't
+ contain the mouse when auto-raise is enabled.
+ \endtable
+
+ \sa ControlElement, StyleFlags
+*/
+
+/*!
+ \fn void TQStyle::tqdrawControlMask( ControlElement element, TQPainter *p, const TQWidget *widget, const TQRect &r, const TQStyleOption& opt) const
+
+ Draw a bittqmask for the ControlElement \a element using the painter
+ \a p in the area \a r. See tqdrawControl() for an explanation of the
+ use of the \a widget and \a opt arguments.
+
+ The rect \a r should be in screen coordinates.
+
+ \sa tqdrawControl(), ControlElement
+*/
+
+/*!
+ \enum TQStyle::SubRect
+
+ This enum represents a sub-area of a widget. Style implementations
+ would use these areas to draw the different parts of a widget.
+
+ \value SR_PushButtonContents area containing the label (iconset
+ with text or pixmap).
+ \value SR_PushButtonFocusRect area for the focus rect (usually
+ larger than the contents rect).
+
+ \value SR_CheckBoxIndicator area for the state indicator (e.g. check mark).
+ \value SR_CheckBoxContents area for the label (text or pixmap).
+ \value SR_CheckBoxFocusRect area for the focus indicator.
+
+
+ \value SR_RadioButtonIndicator area for the state indicator.
+ \value SR_RadioButtonContents area for the label.
+ \value SR_RadioButtonFocusRect area for the focus indicator.
+
+
+ \value SR_ComboBoxFocusRect area for the focus indicator.
+
+
+ \value SR_SliderFocusRect area for the focus indicator.
+
+
+ \value SR_DockWindowHandleRect area for the tear-off handle.
+
+
+ \value SR_ProgressBarGroove area for the groove.
+ \value SR_ProgressBarContents area for the progress indicator.
+ \value SR_ProgressBarLabel area for the text label.
+
+
+ \value SR_ToolButtonContents area for the tool button's label.
+
+ \value SR_DialogButtonAccept area for a dialog's accept button.
+ \value SR_DialogButtonReject area for a dialog's reject button.
+ \value SR_DialogButtonApply area for a dialog's apply button.
+ \value SR_DialogButtonHelp area for a dialog's help button.
+ \value SR_DialogButtonAll area for a dialog's all button.
+ \value SR_DialogButtonRetry area for a dialog's retry button.
+ \value SR_DialogButtonAbort area for a dialog's abort button.
+ \value SR_DialogButtonIgnore area for a dialog's ignore button.
+ \value SR_DialogButtonCustom area for a dialog's custom widget area (in button row).
+
+ \value SR_ToolBoxTabContents area for a toolbox tab's icon and label
+
+ \value SR_CustomBase base value for custom ControlElements. All values above
+ this are reserved for custom use. Therefore, custom values must be
+ greater than this value.
+
+ \sa subRect()
+*/
+
+/*!
+ \fn TQRect TQStyle::subRect( SubRect subrect, const TQWidget *widget ) const;
+
+ Returns the sub-area \a subrect for the \a widget in logical
+ coordinates.
+
+ The \a widget argument is a pointer to a TQWidget or one of its
+ subclasses. The widget can be cast to the appropriate type based
+ on the value of \a subrect. See the table below for the
+ appropriate \a widget casts:
+
+ \table
+ \header \i SubRect \i Widget Cast
+ \row \i \l SR_PushButtonContents \i (const \l TQPushButton *)
+ \row \i \l SR_PushButtonFocusRect \i (const \l TQPushButton *)
+ \row \i \l SR_CheckBoxIndicator \i (const \l TQCheckBox *)
+ \row \i \l SR_CheckBoxContents \i (const \l TQCheckBox *)
+ \row \i \l SR_CheckBoxFocusRect \i (const \l TQCheckBox *)
+ \row \i \l SR_RadioButtonIndicator \i (const \l TQRadioButton *)
+ \row \i \l SR_RadioButtonContents \i (const \l TQRadioButton *)
+ \row \i \l SR_RadioButtonFocusRect \i (const \l TQRadioButton *)
+ \row \i \l SR_ComboBoxFocusRect \i (const \l TQComboBox *)
+ \row \i \l SR_DockWindowHandleRect \i (const \l TQWidget *)
+ \row \i \l SR_ProgressBarGroove \i (const \l TQProgressBar *)
+ \row \i \l SR_ProgressBarContents \i (const \l TQProgressBar *)
+ \row \i \l SR_ProgressBarLabel \i (const \l TQProgressBar *)
+ \endtable
+
+ The tear-off handle (SR_DockWindowHandleRect) for TQDockWindow
+ is a private class. Use TQWidget::parentWidget() to access the
+ TQDockWindow:
+
+ \code
+ if ( !widget->parentWidget() )
+ return;
+ const TQDockWindow *dw = (const TQDockWindow *) widget->parentWidget();
+ \endcode
+
+ \sa SubRect
+*/
+
+/*!
+ \enum TQStyle::ComplexControl
+
+ This enum represents a ComplexControl. ComplexControls have
+ different behaviour depending upon where the user clicks on them
+ or which keys are pressed.
+
+ \value CC_SpinWidget
+ \value CC_ComboBox
+ \value CC_ScrollBar
+ \value CC_Slider
+ \value CC_ToolButton
+ \value CC_TitleBar
+ \value CC_ListView
+
+
+ \value CC_CustomBase base value for custom ControlElements. All
+ values above this are reserved for custom use. Therefore,
+ custom values must be greater than this value.
+
+ \sa SubControl tqdrawComplexControl()
+*/
+
+/*!
+ \enum TQStyle::SubControl
+
+ This enum represents a SubControl within a ComplexControl.
+
+ \value SC_None special value that matches no other SubControl.
+
+
+ \value SC_ScrollBarAddLine scrollbar add line (i.e. down/right
+ arrow); see also TQScrollbar.
+ \value SC_ScrollBarSubLine scrollbar sub line (i.e. up/left arrow).
+ \value SC_ScrollBarAddPage scrollbar add page (i.e. page down).
+ \value SC_ScrollBarSubPage scrollbar sub page (i.e. page up).
+ \value SC_ScrollBarFirst scrollbar first line (i.e. home).
+ \value SC_ScrollBarLast scrollbar last line (i.e. end).
+ \value SC_ScrollBarSlider scrollbar slider handle.
+ \value SC_ScrollBarGroove special subcontrol which tqcontains the
+ area in which the slider handle may move.
+
+
+ \value SC_SpinWidgetUp spinwidget up/increase; see also TQSpinBox.
+ \value SC_SpinWidgetDown spinwidget down/decrease.
+ \value SC_SpinWidgetFrame spinwidget frame.
+ \value SC_SpinWidgetEditField spinwidget edit field.
+ \value SC_SpinWidgetButtonField spinwidget button field.
+
+
+ \value SC_ComboBoxEditField combobox edit field; see also TQComboBox.
+ \value SC_ComboBoxArrow combobox arrow
+ \value SC_ComboBoxFrame combobox frame
+ \value SC_ComboBoxListBoxPopup combobox list box
+
+ \value SC_SliderGroove special subcontrol which tqcontains the area
+ in which the slider handle may move.
+ \value SC_SliderHandle slider handle.
+ \value SC_SliderTickmarks slider tickmarks.
+
+
+ \value SC_ToolButton tool button; see also TQToolbutton.
+ \value SC_ToolButtonMenu subcontrol for opening a popup menu in a
+ tool button; see also TQPopupMenu.
+
+
+ \value SC_TitleBarSysMenu system menu button (i.e. restore, close, etc.).
+ \value SC_TitleBarMinButton minimize button.
+ \value SC_TitleBarMaxButton maximize button.
+ \value SC_TitleBarCloseButton close button.
+ \value SC_TitleBarLabel window title label.
+ \value SC_TitleBarNormalButton normal (restore) button.
+ \value SC_TitleBarShadeButton shade button.
+ \value SC_TitleBarUnshadeButton unshade button.
+
+
+ \value SC_ListView the list view area.
+ \value SC_ListViewBranch (internal)
+ \value SC_ListViewExpand expand item (i.e. show/hide child items).
+
+
+ \value SC_All special value that matches all SubControls.
+
+
+ \sa ComplexControl
+*/
+
+/*!
+ \fn void TQStyle::tqdrawComplexControl( ComplexControl control, TQPainter *p, const TQWidget *widget, const TQRect &r, const TQColorGroup &cg, SFlags how, SCFlags sub, SCFlags subActive, const TQStyleOption& opt ) const
+
+ Draws the ComplexControl \a control using the painter \a p in the
+ area \a r. Colors are used from the color group \a cg. The \a sub
+ argument specifies which SubControls to draw. Multiple SubControls
+ can be OR'ed together. The \a subActive argument specifies which
+ SubControl is active.
+
+ The rect \a r should be in logical coordinates. Reimplementations
+ of this function should use tqvisualRect() to change the logical
+ coordinates into screen coordinates when using drawPrimitive() and
+ tqdrawControl().
+
+ The \a how argument is used to control how the ComplexControl is
+ drawn. Multiple flags can OR'ed together. See the table below for
+ an explanation of which flags are used with the various
+ ComplexControls.
+
+ The \a widget argument is a pointer to a TQWidget or one of its
+ subclasses. The widget can be cast to the appropriate type based
+ on the value of \a control. The \a opt argument can be used to
+ pass extra information required when drawing the ComplexControl.
+ Note that \a opt may be the default value even for ComplexControls
+ that can make use of the extra options. See the table below for
+ the appropriate \a widget and \a opt usage:
+
+ \table
+ \header \i ComplexControl<br>\& Widget Cast
+ \i Style Flags
+ \i Notes
+ \i Options
+ \i Notes
+
+ \row \i12 \l{CC_SpinWidget}(const TQSpinWidget *)
+ \i \l Style_Enabled \i Set if the spinwidget is enabled.
+ \i12 Unused.
+ \i12 &nbsp;
+ \row \i \l Style_HasFocus \i Set if the spinwidget has input focus.
+
+ \row \i12 \l{CC_ComboBox}(const \l TQComboBox *)
+ \i \l Style_Enabled \i Set if the combobox is enabled.
+ \i12 Unused.
+ \i12 &nbsp;
+ \row \i \l Style_HasFocus \i Set if the combobox has input focus.
+
+ \row \i12 \l{CC_ScrollBar}(const \l TQScrollBar *)
+ \i \l Style_Enabled \i Set if the scrollbar is enabled.
+ \i12 Unused.
+ \i12 &nbsp;
+ \row \i \l Style_HasFocus \i Set if the scrollbar has input focus.
+
+ \row \i12 \l{CC_Slider}(const \l TQSlider *)
+ \i \l Style_Enabled \i Set if the slider is enabled.
+ \i12 Unused.
+ \i12 &nbsp;
+
+ \row \i \l Style_HasFocus \i Set if the slider has input focus.
+
+ \row \i16 \l{CC_ToolButton}(const \l TQToolButton *)
+ \i \l Style_Enabled \i Set if the toolbutton is enabled.
+ \i16 \l TQStyleOption ( \l ArrowType t )
+ \list
+ \i opt.\link TQStyleOption::arrowType() arrowType\endlink()
+ \endlist
+ \i16 When the tool button only tqcontains an arrow, \e t is the
+ arrow's type.
+ \row \i \l Style_HasFocus \i Set if the toolbutton has input focus.
+ \row \i \l Style_Down \i Set if the toolbutton is down (ie. mouse
+ button or space pressed).
+ \row \i \l Style_On \i Set if the toolbutton is a toggle button
+ and is toggled on.
+ \row \i \l Style_AutoRaise \i Set if the toolbutton has auto-raise enabled.
+ \row \i \l Style_Raised \i Set if the button is not down, not on and doesn't
+ contain the mouse when auto-raise is enabled.
+
+ \row \i \l{CC_TitleBar}(const \l TQWidget *)
+ \i \l Style_Enabled \i Set if the titlebar is enabled.
+ \i Unused.
+ \i &nbsp;
+
+ \row \i \l{CC_ListView}(const \l TQListView *)
+ \i \l Style_Enabled \i Set if the titlebar is enabled.
+ \i \l TQStyleOption ( \l TQListViewItem *item )
+ \list
+ \i opt.\link TQStyleOption::listViewItem() listViewItem\endlink()
+ \endlist
+ \i \e item is the item that needs branches drawn
+ \endtable
+
+ \sa ComplexControl, SubControl
+*/
+
+/*!
+ \fn void TQStyle::tqdrawComplexControlMask( ComplexControl control, TQPainter *p, const TQWidget *widget, const TQRect &r, const TQStyleOption& opt) const
+
+ Draw a bittqmask for the ComplexControl \a control using the painter
+ \a p in the area \a r. See tqdrawComplexControl() for an explanation
+ of the use of the \a widget and \a opt arguments.
+
+ The rect \a r should be in logical coordinates. Reimplementations
+ of this function should use tqvisualRect() to change the logical
+ corrdinates into screen coordinates when using drawPrimitive() and
+ tqdrawControl().
+
+ \sa tqdrawComplexControl() ComplexControl
+*/
+
+/*!
+ \fn TQRect TQStyle::querySubControlMetrics( ComplexControl control, const TQWidget *widget, SubControl subcontrol, const TQStyleOption& opt = TQStyleOption::Default ) const;
+
+ Returns the rect for the SubControl \a subcontrol for \a widget in
+ logical coordinates.
+
+ The \a widget argument is a pointer to a TQWidget or one of its
+ subclasses. The widget can be cast to the appropriate type based
+ on the value of \a control. The \a opt argument can be used to
+ pass extra information required when drawing the ComplexControl.
+ Note that \a opt may be the default value even for ComplexControls
+ that can make use of the extra options. See tqdrawComplexControl()
+ for an explanation of the \a widget and \a opt arguments.
+
+ \sa tqdrawComplexControl(), ComplexControl, SubControl
+*/
+
+/*!
+ \fn SubControl TQStyle::querySubControl( ComplexControl control, const TQWidget *widget, const TQPoint &pos, const TQStyleOption& opt = TQStyleOption::Default ) const;
+
+ Returns the SubControl for \a widget at the point \a pos. The \a
+ widget argument is a pointer to a TQWidget or one of its
+ subclasses. The widget can be cast to the appropriate type based
+ on the value of \a control. The \a opt argument can be used to
+ pass extra information required when drawing the ComplexControl.
+ Note that \a opt may be the default value even for ComplexControls
+ that can make use of the extra options. See tqdrawComplexControl()
+ for an explanation of the \a widget and \a opt arguments.
+
+ Note that \a pos is passed in screen coordinates. When using
+ querySubControlMetrics() to check for hits and misses, use
+ tqvisualRect() to change the logical coordinates into screen
+ coordinates.
+
+ \sa tqdrawComplexControl(), ComplexControl, SubControl, querySubControlMetrics()
+*/
+
+/*!
+ \enum TQStyle::PixelMetric
+
+ This enum represents a PixelMetric. A PixelMetric is a style
+ dependent size represented as a single pixel value.
+
+ \value PM_ButtonMargin amount of whitespace between pushbutton
+ labels and the frame.
+ \value PM_ButtonDefaultIndicator width of the default-button indicator frame.
+ \value PM_MenuButtonIndicator width of the menu button indicator
+ proportional to the widget height.
+ \value PM_ButtonShiftHorizontal horizontal contents shift of a
+ button when the button is down.
+ \value PM_ButtonShiftVertical vertical contents shift of a button when the
+ button is down.
+
+ \value PM_DefaultFrameWidth default frame width, usually 2.
+ \value PM_SpinBoxFrameWidth frame width of a spin box.
+ \value PM_MDIFrameWidth frame width of an MDI window.
+ \value PM_MDIMinimizedWidth width of a minimized MSI window.
+
+ \value PM_MaximumDragDistance Some feels require the scrollbar or
+ other sliders to jump back to the original position when the
+ mouse pointer is too far away while dragging. A value of -1
+ disables this behavior.
+
+ \value PM_ScrollBarExtent width of a vertical scrollbar and the
+ height of a horizontal scrollbar.
+ \value PM_ScrollBarSliderMin the minimum height of a vertical
+ scrollbar's slider and the minimum width of a horiztonal
+ scrollbar slider.
+
+ \value PM_SliderThickness total slider thickness.
+ \value PM_SliderControlThickness thickness of the slider handle.
+ \value PM_SliderLength length of the slider.
+ \value PM_SliderTickmarkOffset the offset between the tickmarks
+ and the slider.
+ \value PM_SliderSpaceAvailable the available space for the slider to move.
+
+ \value PM_DockWindowSeparatorExtent width of a separator in a
+ horiztonal dock window and the height of a separator in a
+ vertical dock window.
+ \value PM_DockWindowHandleExtent width of the handle in a
+ horizontal dock window and the height of the handle in a
+ vertical dock window.
+ \value PM_DockWindowFrameWidth frame width of a dock window.
+
+ \value PM_MenuBarFrameWidth frame width of a menubar.
+
+ \value PM_MenuBarItemSpacing spacing between menubar items.
+ \value PM_ToolBarItemSpacing spacing between toolbar items.
+
+ \value PM_TabBarTabOverlap number of pixels the tabs should overlap.
+ \value PM_TabBarTabHSpace extra space added to the tab width.
+ \value PM_TabBarTabVSpace extra space added to the tab height.
+ \value PM_TabBarBaseHeight height of the area between the tab bar
+ and the tab pages.
+ \value PM_TabBarBaseOverlap number of pixels the tab bar overlaps
+ the tab bar base.
+ \value PM_TabBarScrollButtonWidth
+ \value PM_TabBarTabShiftHorizontal horizontal pixel shift when a
+ tab is selected.
+ \value PM_TabBarTabShiftVertical vertical pixel shift when a
+ tab is selected.
+
+ \value PM_ProgressBarChunkWidth width of a chunk in a progress bar indicator.
+
+ \value PM_SplitterWidth width of a splitter.
+
+ \value PM_TitleBarHeight height of the title bar.
+ \value PM_PopupMenuFrameHorizontalExtra additional border, e.g. for panels
+ \value PM_PopupMenuFrameVerticalExtra additional border, e.g. for panels
+
+ \value PM_IndicatorWidth width of a check box indicator.
+ \value PM_IndicatorHeight height of a checkbox indicator.
+ \value PM_ExclusiveIndicatorWidth width of a radio button indicator.
+ \value PM_ExclusiveIndicatorHeight height of a radio button indicator.
+
+ \value PM_PopupMenuScrollerHeight height of the scroller area in a popupmenu.
+ \value PM_PopupMenuScrollerHeight height of the scroller area in a popupmenu.
+ \value PM_CheckListButtonSize area (width/height) of the
+ checkbox/radiobutton in a TQCheckListItem
+ \value PM_CheckListControllerSize area (width/height) of the
+ controller in a TQCheckListItem
+
+ \value PM_DialogButtonsSeparator distance between buttons in a dialog buttons widget.
+ \value PM_DialogButtonsButtonWidth minimum width of a button in a dialog buttons widget.
+ \value PM_DialogButtonsButtonHeight minimum height of a button in a dialog buttons widget.
+
+ \value PM_HeaderMarkSize
+ \value PM_HeaderGripMargin
+ \value PM_HeaderMargin
+
+ \value PM_CustomBase base value for custom ControlElements. All
+ values above this are reserved for custom use. Therefore,
+ custom values must be greater than this value.
+
+
+ \sa tqpixelMetric()
+*/
+
+/*!
+ \fn int TQStyle::tqpixelMetric( PixelMetric metric, const TQWidget *widget = 0 ) const;
+
+ Returns the pixel metric for \a metric. The \a widget argument is
+ a pointer to a TQWidget or one of its subclasses. The widget can be
+ cast to the appropriate type based on the value of \a metric. Note
+ that \a widget may be zero even for PixelMetrics that can make use
+ of \a widget. See the table below for the appropriate \a widget
+ casts:
+
+ \table
+ \header \i PixelMetric \i Widget Cast
+ \row \i \l PM_SliderControlThickness \i (const \l TQSlider *)
+ \row \i \l PM_SliderLength \i (const \l TQSlider *)
+ \row \i \l PM_SliderTickmarkOffset \i (const \l TQSlider *)
+ \row \i \l PM_SliderSpaceAvailable \i (const \l TQSlider *)
+ \row \i \l PM_TabBarTabOverlap \i (const \l TQTabBar *)
+ \row \i \l PM_TabBarTabHSpace \i (const \l TQTabBar *)
+ \row \i \l PM_TabBarTabVSpace \i (const \l TQTabBar *)
+ \row \i \l PM_TabBarBaseHeight \i (const \l TQTabBar *)
+ \row \i \l PM_TabBarBaseOverlap \i (const \l TQTabBar *)
+ \endtable
+*/
+
+/*!
+ \enum TQStyle::ContentsType
+
+ This enum represents a ContentsType. It is used to calculate sizes
+ for the contents of various widgets.
+
+ \value CT_PushButton
+ \value CT_CheckBox
+ \value CT_RadioButton
+ \value CT_ToolButton
+ \value CT_ComboBox
+ \value CT_Splitter
+ \value CT_DockWindow
+ \value CT_ProgressBar
+ \value CT_PopupMenuItem
+ \value CT_TabBarTab
+ \value CT_Slider
+ \value CT_Header
+ \value CT_LineEdit
+ \value CT_MenuBar
+ \value CT_SpinBox
+ \value CT_SizeGrip
+ \value CT_TabWidget
+ \value CT_DialogButtons
+
+ \value CT_CustomBase base value for custom ControlElements. All
+ values above this are reserved for custom use. Custom values
+ must be greater than this value.
+
+ \sa sizeFromContents()
+*/
+
+/*!
+ \fn TQSize TQStyle::sizeFromContents( ContentsType contents, const TQWidget *widget, const TQSize &contentsSize, const TQStyleOption& opt = TQStyleOption::Default ) const;
+
+ Returns the size of \a widget based on the contents size \a
+ contentsSize.
+
+ The \a widget argument is a pointer to a TQWidget or one of its
+ subclasses. The widget can be cast to the appropriate type based
+ on the value of \a contents. The \a opt argument can be used to
+ pass extra information required when calculating the size. Note
+ that \a opt may be the default value even for ContentsTypes that
+ can make use of the extra options. See the table below for the
+ appropriate \a widget and \a opt usage:
+
+ \table
+ \header \i ContentsType \i Widget Cast \i Options \i Notes
+ \row \i \l CT_PushButton \i (const \l TQPushButton *) \i Unused. \i &nbsp;
+ \row \i \l CT_CheckBox \i (const \l TQCheckBox *) \i Unused. \i &nbsp;
+ \row \i \l CT_RadioButton \i (const \l TQRadioButton *) \i Unused. \i &nbsp;
+ \row \i \l CT_ToolButton \i (const \l TQToolButton *) \i Unused. \i &nbsp;
+ \row \i \l CT_ComboBox \i (const \l TQComboBox *) \i Unused. \i &nbsp;
+ \row \i \l CT_Splitter \i (const \l TQSplitter *) \i Unused. \i &nbsp;
+ \row \i \l CT_DockWindow \i (const \l TQDockWindow *) \i Unused. \i &nbsp;
+ \row \i \l CT_ProgressBar \i (const \l TQProgressBar *) \i Unused. \i &nbsp;
+ \row \i \l CT_PopupMenuItem \i (const TQPopupMenu *)
+ \i \l TQStyleOption ( TQMenuItem *mi )
+ \list
+ \i opt.\link TQStyleOption::menuItem() menuItem\endlink()
+ \endlist
+ \i \e mi is the menu item to use when calculating the size.
+ TQMenuItem is currently an internal class.
+ \endtable
+*/
+
+/*!
+ \enum TQStyle::StyleHint
+
+ This enum represents a StyleHint. A StyleHint is a general look
+ and/or feel hint.
+
+ \value SH_EtchDisabledText disabled text is "etched" like Windows.
+
+ \value SH_GUIStyle the GUI style to use.
+
+ \value SH_ScrollBar_BackgroundMode the background mode for a
+ TQScrollBar. Possible values are any of those in the \link
+ TQt::BackgroundMode BackgroundMode\endlink enum.
+
+ \value SH_ScrollBar_MiddleClickAbsolutePosition a boolean value.
+ If TRUE, middle clicking on a scrollbar causes the slider to
+ jump to that position. If FALSE, the middle clicking is
+ ignored.
+
+ \value SH_ScrollBar_LeftClickAbsolutePosition a boolean value.
+ If TRUE, left clicking on a scrollbar causes the slider to
+ jump to that position. If FALSE, the left clicking will
+ behave as appropriate for each control.
+
+ \value SH_ScrollBar_ScrollWhenPointerLeavesControl a boolean
+ value. If TRUE, when clicking a scrollbar SubControl, holding
+ the mouse button down and moving the pointer outside the
+ SubControl, the scrollbar continues to scroll. If FALSE, the
+ scollbar stops scrolling when the pointer leaves the
+ SubControl.
+
+ \value SH_TabBar_Alignment the tqalignment for tabs in a
+ TQTabWidget. Possible values are \c TQt::AlignLeft, \c
+ TQt::AlignCenter and \c TQt::AlignRight.
+
+ \value SH_Header_ArrowAlignment the placement of the sorting
+ indicator may appear in list or table headers. Possible values
+ are \c TQt::Left or \c TQt::Right.
+
+ \value SH_Slider_SnapToValue sliders snap to values while moving,
+ like Windows
+
+ \value SH_Slider_SloppyKeyEvents key presses handled in a sloppy
+ manner, i.e. left on a vertical slider subtracts a line.
+
+ \value SH_ProgressDialog_CenterCancelButton center button on
+ progress dialogs, like Motif, otherwise right aligned.
+
+ \value SH_ProgressDialog_TextLabelAlignment TQt::AlignmentFlags --
+ text label tqalignment in progress dialogs; Center on windows,
+ Auto|VCenter otherwise.
+
+ \value SH_PrintDialog_RightAlignButtons right align buttons in
+ the print dialog, like Windows.
+
+ \value SH_MainWindow_SpaceBelowMenuBar 1 or 2 pixel space between
+ the menubar and the dockarea, like Windows.
+
+ \value SH_FontDialog_SelectAssociatedText select the text in the
+ line edit, or when selecting an item from the listbox, or when
+ the line edit receives focus, like Windows.
+
+ \value SH_PopupMenu_AllowActiveAndDisabled allows disabled menu
+ items to be active.
+
+ \value SH_PopupMenu_SpaceActivatesItem pressing Space activates
+ the item, like Motif.
+
+ \value SH_PopupMenu_SubMenuPopupDelay the number of milliseconds
+ to wait before opening a submenu; 256 on windows, 96 on Motif.
+
+ \value SH_PopupMenu_Scrollable whether popupmenu's must support
+ scrolling.
+
+ \value SH_PopupMenu_SloppySubMenus whether popupmenu's must support
+ sloppy submenu; as implemented on Mac OS.
+
+ \value SH_ScrollView_FrameOnlyAroundContents whether scrollviews
+ draw their frame only around contents (like Motif), or around
+ contents, scrollbars and corner widgets (like Windows).
+
+ \value SH_MenuBar_AltKeyNavigation menubars items are navigable
+ by pressing Alt, followed by using the arrow keys to select
+ the desired item.
+
+ \value SH_ComboBox_ListMouseTracking mouse tracking in combobox
+ dropdown lists.
+
+ \value SH_PopupMenu_MouseTracking mouse tracking in popup menus.
+
+ \value SH_MenuBar_MouseTracking mouse tracking in menubars.
+
+ \value SH_ItemView_ChangeHighlightOnFocus gray out selected items
+ when losing focus.
+
+ \value SH_Widget_ShareActivation turn on sharing activation with
+ floating modeless dialogs.
+
+ \value SH_TabBar_SelectMouseType which type of mouse event should
+ cause a tab to be selected.
+
+ \value SH_ListViewExpand_SelectMouseType which type of mouse event should
+ cause a listview expansion to be selected.
+
+ \value SH_TabBar_PreferNoArrows whether a tabbar should suggest a size
+ to prevent scoll arrows.
+
+ \value SH_ComboBox_Popup allows popups as a combobox dropdown
+ menu.
+
+ \value SH_Workspace_FillSpaceOnMaximize the workspace should
+ maximize the client area.
+
+ \value SH_TitleBar_NoBorder the titlebar has no border
+
+ \value SH_ScrollBar_StopMouseOverSlider stops autorepeat when
+ slider reaches mouse
+
+ \value SH_BlinkCursorWhenTextSelected whether cursor should blink
+ when text is selected
+
+ \value SH_RichText_FullWidthSelection whether richtext selections
+ should extend the full width of the document.
+
+ \value SH_GroupBox_TextLabelVerticalAlignment how to vertically align a
+ groupbox's text label.
+
+ \value SH_GroupBox_TextLabelColor how to paint a groupbox's text label.
+
+ \value SH_DialogButtons_DefaultButton which buttons gets the
+ default status in a dialog's button widget.
+
+ \value SH_CustomBase base value for custom ControlElements. All
+ values above this are reserved for custom use. Therefore,
+ custom values must be greater than this value.
+
+ \value SH_ToolButton_Uses3D indicates whether TQToolButtons should
+ use a 3D frame when the mouse is over them
+
+ \value SH_ToolBox_SelectedPageTitleBold Boldness of the selected
+ page title in a TQToolBox.
+
+ \value SH_LineEdit_PasswordCharacter The TQChar Unicode character
+ to be used for passwords.
+
+ \value SH_Table_GridLineColor
+
+ \value SH_UnderlineAccelerator whether accelerators are underlined
+
+ \sa tqstyleHint()
+*/
+
+/*!
+ \fn int TQStyle::tqstyleHint( StyleHint stylehint, const TQWidget *widget = 0, const TQStyleOption &opt = TQStyleOption::Default, TQStyleHintReturn *returnData = 0 ) const;
+
+ Returns the style hint \a stylehint for \a widget. Currently, \a
+ widget, \a opt, and \a returnData are unused; they're included to
+ allow for future enhancements.
+
+ For an explanation of the return value see \l StyleHint.
+*/
+
+/*!
+ \enum TQStyle::StylePixmap
+
+ This enum represents a StylePixmap. A StylePixmap is a pixmap that
+ can follow some existing GUI style or guideline.
+
+
+ \value SP_TitleBarMinButton minimize button on titlebars. For
+ example, in a TQWorkspace.
+ \value SP_TitleBarMaxButton maximize button on titlebars.
+ \value SP_TitleBarCloseButton close button on titlebars.
+ \value SP_TitleBarNormalButton normal (restore) button on titlebars.
+ \value SP_TitleBarShadeButton shade button on titlebars.
+ \value SP_TitleBarUnshadeButton unshade button on titlebars.
+ \value SP_MessageBoxInformation the 'information' icon.
+ \value SP_MessageBoxWarning the 'warning' icon.
+ \value SP_MessageBoxCritical the 'critical' icon.
+ \value SP_MessageBoxQuestion the 'question' icon.
+
+
+ \value SP_DockWindowCloseButton close button on dock windows;
+ see also TQDockWindow.
+
+
+ \value SP_CustomBase base value for custom ControlElements. All
+ values above this are reserved for custom use. Therefore,
+ custom values must be greater than this value.
+
+ \sa stylePixmap()
+*/
+
+/*!
+ \fn TQPixmap TQStyle::stylePixmap( StylePixmap stylepixmap, const TQWidget *widget = 0, const TQStyleOption& opt = TQStyleOption::Default ) const;
+
+ Returns a pixmap for \a stylepixmap.
+
+ The \a opt argument can be used to pass extra information required
+ when drawing the ControlElement. Note that \a opt may be the
+ default value even for StylePixmaps that can make use of the extra
+ options. Currently, the \a opt argument is unused.
+
+ The \a widget argument is a pointer to a TQWidget or one of its
+ subclasses. The widget can be cast to the appropriate type based
+ on the value of \a stylepixmap. See the table below for the
+ appropriate \a widget casts:
+
+ \table
+ \header \i StylePixmap \i Widget Cast
+ \row \i \l SP_TitleBarMinButton \i (const \l TQWidget *)
+ \row \i \l SP_TitleBarMaxButton \i (const \l TQWidget *)
+ \row \i \l SP_TitleBarCloseButton \i (const \l TQWidget *)
+ \row \i \l SP_TitleBarNormalButton \i (const \l TQWidget *)
+ \row \i \l SP_TitleBarShadeButton \i (const \l TQWidget *)
+ \row \i \l SP_TitleBarUnshadeButton \i (const \l TQWidget *)
+ \row \i \l SP_DockWindowCloseButton \i (const \l TQDockWindow *)
+ \endtable
+
+ \sa StylePixmap
+*/
+
+/*!
+ \fn TQRect TQStyle::tqvisualRect( const TQRect &logical, const TQWidget *w );
+
+ Returns the rect \a logical in screen coordinates. The bounding
+ rect for widget \a w is used to perform the translation. This
+ function is provided to aid style implementors in supporting
+ right-to-left mode.
+
+ \sa TQApplication::reverseLayout()
+*/
+TQRect TQStyle::tqvisualRect( const TQRect &logical, const TQWidget *w )
+{
+ TQRect boundingRect = w->rect();
+ TQRect r = logical;
+ if ( TQApplication::reverseLayout() )
+ r.moveBy( 2*(boundingRect.right() - logical.right()) +
+ logical.width() - boundingRect.width(), 0 );
+ return r;
+}
+
+/*!
+ \overload TQRect TQStyle::tqvisualRect( const TQRect &logical, const TQRect &bounding );
+
+ Returns the rect \a logical in screen coordinates. The rect \a
+ bounding is used to perform the translation. This function is
+ provided to aid style implementors in supporting right-to-left
+ mode.
+
+ \sa TQApplication::reverseLayout()
+*/
+TQRect TQStyle::tqvisualRect( const TQRect &logical, const TQRect &boundingRect )
+{
+ TQRect r = logical;
+ if ( TQApplication::reverseLayout() )
+ r.moveBy( 2*(boundingRect.right() - logical.right()) +
+ logical.width() - boundingRect.width(), 0 );
+ return r;
+}
+
+/*!
+ \fn int TQStyle::defaultFrameWidth() const
+ \obsolete
+*/
+
+/*!
+ \fn void TQStyle::tabbarMetrics( const TQWidget *, int &, int &, int & ) const
+ \obsolete
+*/
+
+/*!
+ \fn TQSize TQStyle::scrollBarExtent() const
+ \obsolete
+*/
+
+#endif // USE_QT4
+
+#endif // TQT_NO_STYLE
diff --git a/tqtinterface/qt4/src/kernel/tqstyle.h b/tqtinterface/qt4/src/kernel/tqstyle.h
new file mode 100644
index 0000000..5d657d8
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqstyle.h
@@ -0,0 +1,1278 @@
+/****************************************************************************
+**
+** Definition of TQStyle class
+**
+** Created : 980616
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+#ifndef TQSTYLE_H
+#define TQSTYLE_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include "tqpainter.h"
+#include "tqpalette.h"
+#include "tqwidget.h"
+
+#include <Qt/qstyle.h>
+#include <Qt/qstyleoption.h>
+
+#include "tqtenuminheritance.h"
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+// HACK
+#define tqdrawPrimitiveBase tqdrawPrimitive
+
+// Remap changed values
+#define CT_DockWindow CT_Q3DockWindow
+#define CT_Header CT_Q3Header
+#define CT_PopupMenuItem CT_MenuItem
+
+// #define PE_SizeGrip CE_SizeGrip
+// #define PE_Splitter CE_Splitter
+// #define PE_RubberBand CE_RubberBand
+// #define PE_HeaderSection CE_HeaderSection
+#define PE_HeaderArrow PE_IndicatorHeaderArrow
+#define PE_FocusRect PE_FrameFocusRect
+#define PE_DockWindowResizeHandle PE_IndicatorDockWidgetResizeHandle
+#define PE_PanelGroupBox PE_FrameGroupBox
+#define PE_DockWindowHandle PE_IndicatorToolBarHandle
+#define PE_WindowFrame PE_FrameWindow
+#define PE_PanelTabWidget PE_FrameTabWidget
+#define PE_Panel PE_Frame
+#define PE_ButtonTool PE_PanelButtonTool
+#define PE_ButtonDropDown PE_IndicatorButtonDropDown
+#define PE_SpinWidgetPlus PE_IndicatorSpinPlus
+#define PE_SpinWidgetMinus PE_IndicatorSpinMinus
+#define PE_SpinWidgetUp PE_IndicatorSpinUp
+#define PE_SpinWidgetDown PE_IndicatorSpinDown
+#define PE_ButtonBevel PE_PanelButtonBevel
+#define PE_PanelDockWindow PE_FrameDockWindow
+#define PE_PanelPopup PE_FrameMenu
+#define PE_FrameDockWindow PE_FrameDockWidget
+#define PE_CheckMark PE_IndicatorMenuCheckMark
+#define PE_ButtonDefault PE_FrameDefaultButton
+#define PE_ArrowUp PE_IndicatorArrowUp
+#define PE_ArrowDown PE_IndicatorArrowDown
+#define PE_ArrowRight PE_IndicatorArrowRight
+#define PE_ArrowLeft PE_IndicatorArrowLeft
+// #define PE_ScrollBarSubLine CE_ScrollBarSubLine
+// #define PE_ScrollBarAddLine CE_ScrollBarAddLine
+// #define PE_ScrollBarSubPage CE_ScrollBarSubPage
+// #define PE_ScrollBarAddPage CE_ScrollBarAddPage
+// #define PE_ScrollBarFirst CE_ScrollBarFirst
+// #define PE_ScrollBarLast CE_ScrollBarLast
+// #define PE_ScrollBarSlider CE_ScrollBarSlider
+#define PE_Separator PE_Q3Separator
+#define PE_Indicator PE_IndicatorCheckBox
+#define PE_TabBarBase PE_FrameTabBarBase
+#define PE_StatusBarSection PE_FrameStatusBar
+#define PE_ProgressBarChunk PE_IndicatorProgressChunk
+#define PE_ButtonCommand PE_PanelButtonCommand
+#define PE_DockWindowSeparator PE_Q3DockWindowSeparator
+#define PE_CheckListController PE_Q3CheckListController
+#define PE_CheckListIndicator PE_Q3CheckListIndicator
+#define PE_CheckListExclusiveIndicator PE_Q3CheckListExclusiveIndicator
+
+class TQPopupMenu;
+class TQStylePrivate;
+class TQMenuItem;
+class TQTab;
+class TQListViewItem;
+class TQCheckListItem;
+
+// !!! [WARNING] !!!
+// THIS ENTIRE CLASS IS PRETTY MUCH COMPLETELY BROKEN
+// IT IS NOT INTERCHANGABLE WITH QSTYLEOPTION BY ANY STRETCH OF THE IMAGINATION
+// !!! [BEWARE] !!!
+// !!! [FIXME] !!!
+
+class TQStyleOption : public QStyleOption, virtual public TQt {
+public:
+ enum StyleOptionDefault { Default };
+
+ TQStyleOption(StyleOptionDefault=Default) : QStyleOption(), def(TRUE) {}
+ TQStyleOption(const QStyleOption &qso);
+
+// TQStyleOption(int in1) : QStyleOption( in1 ) {}
+// TQStyleOption(int in1, int in2) : QStyleOption( in1, in2 ) {}
+// TQStyleOption(int x, int y, int w, int h) : QStyleOption() { TQ_UNUSED(x); TQ_UNUSED(y); TQ_UNUSED(w); TQ_UNUSED(h);} // [FIXME] What are x, y, w, and h and what do they do? They are likely the visual bounding rectangle for the style element...origin at (x,y) with width w and height h
+
+ TQStyleOption(int in1) : QStyleOption(), def(FALSE), i1(in1) {}
+ TQStyleOption(int in1, int in2) : QStyleOption(), def(FALSE), i1(in1), i2(in2) {}
+ TQStyleOption(int in1, int in2, int in3, int in4) : QStyleOption(), def(FALSE), i1(in1), i2(in2), i3(in3), i4(in4) {}
+
+ TQStyleOption(TQMenuItem* m) : QStyleOption(), def(FALSE), mi(m) {}
+ TQStyleOption(TQMenuItem* m, int in1) : QStyleOption(), def(FALSE), mi(m), i1(in1) {}
+ TQStyleOption(TQMenuItem* m, int in1, int in2) : QStyleOption(), def(FALSE), mi(m), i1(in1), i2(in2) {}
+ TQStyleOption(const TQColor& c) : QStyleOption(), def(FALSE), cl(&c) {}
+ TQStyleOption(TQTab* t) : QStyleOption(), def(FALSE), tb(t) {}
+ TQStyleOption(TQListViewItem* i) : QStyleOption(), def(FALSE), li(i) {}
+ TQStyleOption(TQCheckListItem* i) : QStyleOption(), def(FALSE), cli(i) {}
+// TQStyleOption(TQt::ArrowType a) : QStyleOption( a ) {}
+// TQStyleOption(const TQRect& r) : QStyleOption( r ) {}
+ TQStyleOption(TQWidget *w) : QStyleOption(), def(FALSE), p1((void*)w) {}
+
+ // [FIXME] These are NOT YET PORTED to Qt4!!!
+ bool isDefault() const { return def; }
+ int day() const { return i1; }
+ int lineWidth() const { return i1; }
+ int midLineWidth() const { return i2; }
+ int frameShape() const { return i3; }
+ int frameShadow() const { return i4; }
+ int headerSection() const { return i1; }
+ TQMenuItem* menuItem() const { return mi; }
+ int maxIconWidth() const { return i1; }
+ int tabWidth() const { return i2; }
+ const TQColor& color() const { return *cl; }
+ TQTab* tab() const { return tb; }
+ TQCheckListItem* checkListItem() const { return cli; }
+ TQListViewItem* listViewItem() const { return li; }
+ TQt::ArrowType arrowType() const { return (TQt::ArrowType)i1; }
+ TQRect rect() const { return TQRect( i1, i2, i3, i4 ); }
+ TQWidget* widget() const { return (TQWidget*)p1; }
+
+private:
+ bool def;
+ TQTab* tb;
+ TQMenuItem* mi;
+ const TQColor* cl;
+ TQListViewItem* li;
+ int i1, i2, i3, i4;
+ TQCheckListItem* cli;
+ void *p1, *p2, *p3, *p4; // reserved
+ // (padded to 64 bytes on some architectures)
+};
+
+inline TQStyleOption::TQStyleOption(const QStyleOption& qso) {
+// i1 = qso.rect().x();
+// i2 = qso.rect().y();
+// i3 = qso.rect().width();
+// i4 = qso.rect().height();
+
+// switch (qso.type()) {
+// case QStyleOption::SO_MenuItem:
+//
+// break;
+// }
+
+ printf("[FIXME] TQt does not utilize any QStyleOption parameters during conversion to TQStyleOption\n\r");
+// qFatal("[ABORTING FOR DEBUGGING]");
+ //*this = TQStyleOption(*static_cast<const TQStyleOption*>(&qso));
+}
+
+// #define Style_Default State_None
+// #define Style_Enabled State_Enabled
+// #define Style_HasFocus State_HasFocus
+// #define Style_Up State_Raised
+// #define Style_Down State_Sunken
+// #define Style_On State_On
+// #define Style_Off State_Off
+// #define Style_Top State_Top
+// #define Style_Bottom State_Bottom
+// #define Style_NoChange State_NoChange
+// #define Style_MouseOver State_MouseOver
+// #define Style_Horizontal State_Horizontal
+// #define Style_Vertical State_Vertical
+// #define Style_Active State_Active
+// #define Style_Sunken State_Sunken
+// #define Style_Raised State_Raised
+// #define Style_Selected State_Selected
+// #define Style_AutoRaise State_AutoRaise
+// #define Style_FocusAtBorder State_FocusAtBorder
+// #define Style_ButtonDefault State_None /* [FIXME] Should be QStyleOptionButton::DefaultButton */
+
+#define SP_DockWindowCloseButton SP_DockWidgetCloseButton
+
+#define PM_DockWindowHandleExtent PM_DockWidgetHandleExtent
+#define PM_MenuBarFrameWidth PM_MenuBarPanelWidth
+#define PM_DockWindowFrameWidth PM_DockWidgetFrameWidth
+#define PM_PopupMenuFrameVerticalExtra PM_MenuVMargin
+#define PM_PopupMenuFrameHorizontalExtra PM_MenuHMargin
+#define PM_PopupMenuScrollerHeight PM_MenuScrollerHeight
+#define PM_DockWindowSeparatorExtent PM_DockWidgetSeparatorExtent
+
+#define CE_PopupMenuItem CE_MenuItem
+#define CE_PopupMenuVerticalExtra CE_MenuVMargin
+#define CE_PopupMenuHorizontalExtra CE_MenuHMargin
+#define CE_PopupMenuScroller CE_MenuScroller
+#define CE_TabBarLabel CE_TabBarTabLabel
+
+#define CC_ListView CC_Q3ListView
+
+#define SH_ListViewExpand_SelectMouseType SH_Q3ListViewExpand_SelectMouseType
+#define SH_PopupMenu_MouseTracking SH_Menu_MouseTracking
+#define SH_PopupMenu_Scrollable SH_Menu_Scrollable
+#define SH_PopupMenu_AllowActiveAndDisabled SH_Menu_AllowActiveAndDisabled
+#define SH_PopupMenu_SubMenuPopupDelay SH_Menu_SubMenuPopupDelay
+#define SH_PopupMenu_SpaceActivatesItem SH_Menu_SpaceActivatesItem
+#define SH_PopupMenu_SloppySubMenus SH_Menu_SloppySubMenus
+#define SH_ToolButton_Uses3D SH_ToolButtonStyle /* [FIXME] Verify that this is correct */
+
+// Use the TQt virtual functions, not the built in Qt ones...
+// This requires that the base virtual Qt functions be reimplemented so as to point to the TQt virtual functions instead as shown below.
+// This way, when Trinity overrides a TQt virtual function, the calling Qt code will blithely use the overriden TQt function instead.
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_01 inline void drawPrimitive(QStyle::PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w) const { TQ_UNUSED(opt); TQ_UNUSED(w); static_cast<const TQStyle*>(this)->tqdrawPrimitive(pe, static_cast<TQPainter*>(p), TQRect(), TQColorGroup()); }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_02 inline QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w) const { return static_cast<const TQStyle*>(this)->tqsizeFromContents( ct, static_cast<const TQWidget*>(w), contentsSize, TQT_TQSTYLEOPTION_OBJECT(*opt) ); }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_03 inline QRect itemTextRect(const QFontMetrics &fm, const QRect &r, int flags, bool enabled, const QString &text) const { TQ_UNUSED(fm); return static_cast<const TQStyle*>(this)->tqitemRect(NULL, r, flags, enabled, NULL, text); }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_04 inline QRect itemPixmapRect(const QRect &r, int flags, const QPixmap &pixmap) const { return static_cast<const TQStyle*>(this)->tqitemRect(NULL, r, flags, true, &pixmap, NULL); }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_05 inline void drawControl(QStyle::ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const { static_cast<const TQStyle*>(this)->tqdrawControl( element, static_cast<TQPainter*>(p), static_cast<const TQWidget*>(w), opt->rect, TQColorGroup() ); /* [FIXME] an empty (black) qcolorgroup is WRONG!*/ }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_06 inline int pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const { TQ_UNUSED(option); return static_cast<const TQStyle*>(this)->tqpixelMetric( metric, TQT_TQWIDGET_CONST(widget) ); }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_07 inline void drawComplexControl(QStyle::ComplexControl cc, const QStyleOptionComplex *opt, QPainter *p, const QWidget *widget) const { static_cast<const TQStyle*>(this)->tqdrawComplexControl( cc, static_cast<TQPainter*>(p), static_cast<const TQWidget*>(widget), opt->rect, TQColorGroup()); } /* [FIXME] an empty (black) qcolorgroup is WRONG! */
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_08 inline QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, const QWidget *widget) const { return static_cast<const TQStyle*>(this)->stylePixmap( standardPixmap, TQT_TQWIDGET_CONST(widget), TQT_TQSTYLEOPTION_OBJECT(*opt) ); }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_09 inline int styleHint(StyleHint stylehint, const QStyleOption *opt, const QWidget *widget, QStyleHintReturn* returnData) const { return static_cast<const TQStyle*>(this)->tqstyleHint( stylehint, TQT_TQWIDGET_CONST(widget), TQT_TQSTYLEOPTION_OBJECT(*opt), returnData ); }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_10 inline virtual QRect subElementRect(QStyle::SubElement r, const QStyleOption*, const QWidget *widget) const { return static_cast<const TQStyle*>(this)->subRect( (SubRect)r, static_cast<const TQWidget*>(widget) ); }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_11 inline virtual QStyle::SubControl hitTestComplexControl(QStyle::ComplexControl, const QStyleOptionComplex*, const QPoint&, const QWidget*) const { /* [FIXME] */ printf("[WARNING] virtual QStyle::SubControl hitTestComplexControl(QStyle::ComplexControl, const QStyleOptionComplex*, const QPoint&, const QWidget*) unimplemented\n\r"); }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_12 inline virtual QRect subControlRect(QStyle::ComplexControl r, const QStyleOptionComplex*, QStyle::SubControl, const QWidget* widget) const { return static_cast<const TQStyle*>(this)->subRect( (SubRect)r, static_cast<const TQWidget*>(widget) ); }
+
+#define TQT_TQSTYLE_QT4_INTERFACE_VFUNC_13 inline virtual QPixmap generatedIconPixmap(QIcon::Mode, const QPixmap&, const QStyleOption*) const { /* [FIXME] */ printf("[WARNING] virtual QPixmap generatedIconPixmap(QIcon::Mode, const QPixmap&, const QStyleOption*) unimplemented\n\r"); }
+
+//class TQStyleHintReturn; // not defined yet
+#define TQStyleHintReturn QStyleHintReturn
+
+class TQ_EXPORT TQStyle: public QStyle, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ typedef uint SFlags;
+
+// typedef State SFlags;
+ typedef StandardPixmap StylePixmap;
+
+ TQStyle() : QStyle() { TQT_TQOBJECT_REQUIRED_INITIALIZATION(tqparent) }
+
+ enum SH_NewTypes {
+ SH_GUIStyle = 0x00000100,
+ SH_ScrollBar_BackgroundMode,
+ SH_UnderlineAccelerator = SH_UnderlineShortcut
+ };
+
+ typedef TQTInheritEnum< SH_NewTypes, QStyle::StyleHint > TQ_StyleHint;
+
+ enum CE_NewTypes {
+ CE_DockWindowEmptyArea = 0xff000000
+ };
+
+ typedef TQTInheritEnum< CE_NewTypes, QStyle::ControlElement > TQ_ControlElement;
+
+ enum CC_NewTypes {
+ CC_SpinWidget = 0xff000000
+ };
+
+ typedef TQTInheritEnum< CC_NewTypes, QStyle::ComplexControl > TQ_ComplexControl;
+
+ enum PE_NewTypes {
+ PE_IndicatorMask = 0xff000000,
+ PE_ExclusiveIndicator = 0xff000001,
+ PE_ExclusiveIndicatorMask = 0xff000002,
+ PE_GroupBoxFrame = 0xff000003,
+
+ // NOTE: These need an interface to Qt4 such that Qt4 calls for CE_ScrollBar<xxx> are translated to the equivalent TQt PE_ScrollBar<xxx> calls
+ PE_ScrollBarAddLine = 0xff000004,
+ PE_ScrollBarSubLine = 0xff000005,
+ PE_ScrollBarAddPage = 0xff000006,
+ PE_ScrollBarSubPage = 0xff000007,
+ PE_ScrollBarSlider = 0xff000008,
+ PE_ScrollBarFirst = 0xff000009,
+ PE_ScrollBarLast = 0xff00000a,
+
+ // NOTE: Same as above...
+ PE_SizeGrip = 0xff00000b,
+ PE_Splitter = 0xff00000c,
+ PE_RubberBand = 0xff00000d,
+ PE_HeaderSection = 0xff00000e
+ };
+
+ typedef TQTInheritEnum< PE_NewTypes, QStyle::PrimitiveElement > TQ_PrimitiveElement;
+
+ // Note that StyleFlags is now StateFlags
+ enum StyleFlags {
+ Style_Default = QStyle::State_None,
+ Style_Enabled = QStyle::State_Enabled,
+ Style_HasFocus = QStyle::State_HasFocus,
+ Style_Up = QStyle::State_Raised,
+ Style_Down = QStyle::State_Sunken,
+ Style_On = QStyle::State_On,
+ Style_Off = QStyle::State_Off,
+ Style_Top = QStyle::State_Top,
+ Style_Bottom = QStyle::State_Bottom,
+ Style_NoChange = QStyle::State_NoChange,
+ Style_MouseOver = QStyle::State_MouseOver,
+ Style_Horizontal = QStyle::State_Horizontal,
+// Style_Vertical = QStyle::State_Vertical,
+ Style_Active = QStyle::State_Active,
+ Style_Sunken = QStyle::State_Sunken,
+ Style_Raised = QStyle::State_Raised,
+ Style_Selected = QStyle::State_Selected,
+ Style_AutoRaise = QStyle::State_AutoRaise,
+ Style_FocusAtBorder = QStyle::State_FocusAtBorder,
+ Style_ButtonDefault = QStyle::State_None /* [FIXME] Should be QStyleOptionButton::DefaultButton */
+ };
+
+ // Note that SubRect may not have an equivalent in Qt4--be careful!
+ enum SubRect {
+ SR_PushButtonContents,
+ SR_PushButtonFocusRect,
+
+ SR_CheckBoxIndicator,
+ SR_CheckBoxContents,
+ SR_CheckBoxFocusRect,
+
+ SR_RadioButtonIndicator,
+ SR_RadioButtonContents,
+ SR_RadioButtonFocusRect,
+
+ SR_ComboBoxFocusRect,
+
+ SR_SliderFocusRect,
+
+ SR_DockWindowHandleRect,
+
+ SR_ProgressBarGroove,
+ SR_ProgressBarContents,
+ SR_ProgressBarLabel,
+
+ SR_ToolButtonContents,
+
+ SR_DialogButtonAccept,
+ SR_DialogButtonReject,
+ SR_DialogButtonApply,
+ SR_DialogButtonHelp,
+ SR_DialogButtonAll,
+ SR_DialogButtonAbort,
+ SR_DialogButtonIgnore,
+ SR_DialogButtonRetry,
+ SR_DialogButtonCustom,
+
+ SR_ToolBoxTabContents,
+
+ // do not add any values below/greater than this
+ SR_CustomBase = 0xf0000000
+ };
+
+ // Note that SubControl may not have an equivalent in Qt4--be careful!
+ enum SubControl {
+ SC_None = 0x00000000,
+
+ SC_ScrollBarAddLine = 0x00000001,
+ SC_ScrollBarSubLine = 0x00000002,
+ SC_ScrollBarAddPage = 0x00000004,
+ SC_ScrollBarSubPage = 0x00000008,
+ SC_ScrollBarFirst = 0x00000010,
+ SC_ScrollBarLast = 0x00000020,
+ SC_ScrollBarSlider = 0x00000040,
+ SC_ScrollBarGroove = 0x00000080,
+
+ SC_SpinWidgetUp = 0x00000001,
+ SC_SpinWidgetDown = 0x00000002,
+ SC_SpinWidgetFrame = 0x00000004,
+ SC_SpinWidgetEditField = 0x00000008,
+ SC_SpinWidgetButtonField = 0x00000010,
+
+ SC_ComboBoxFrame = 0x00000001,
+ SC_ComboBoxEditField = 0x00000002,
+ SC_ComboBoxArrow = 0x00000004,
+ SC_ComboBoxListBoxPopup = 0x00000008,
+
+ SC_SliderGroove = 0x00000001,
+ SC_SliderHandle = 0x00000002,
+ SC_SliderTickmarks = 0x00000004,
+
+ SC_ToolButton = 0x00000001,
+ SC_ToolButtonMenu = 0x00000002,
+
+ SC_TitleBarLabel = 0x00000001,
+ SC_TitleBarSysMenu = 0x00000002,
+ SC_TitleBarMinButton = 0x00000004,
+ SC_TitleBarMaxButton = 0x00000008,
+ SC_TitleBarCloseButton = 0x00000010,
+ SC_TitleBarNormalButton = 0x00000020,
+ SC_TitleBarShadeButton = 0x00000040,
+ SC_TitleBarUnshadeButton = 0x00000080,
+
+ SC_ListView = 0x00000001,
+ SC_ListViewBranch = 0x00000002,
+ SC_ListViewExpand = 0x00000004,
+
+ SC_All = 0xffffffff
+ };
+ typedef uint SCFlags;
+
+ bool isA(const char *classname) const;
+ bool inherits( const char * ) const;
+
+ const char *tqname() const;
+ const char *name() const;
+// const char *name(const char *defaultName) const;
+
+ TQMetaObject *tqmetaObject() const;
+
+ // Compatibility functions
+ // For example, a TQt application may call tqdrawPrimitive with a ControlElement parameter
+ // TQt "knows" that the application should have called tqdrawControl instead, and translates accordingly.
+ inline void tqdrawPrimitive( TQ_ControlElement element, TQPainter *p, const TQRect &r, const TQColorGroup &cg, SFlags flags = Style_Default, const TQStyleOption &opt = TQStyleOption::Default ) const {
+ TQ_UNUSED(r);
+ TQ_UNUSED(cg);
+ TQ_UNUSED(flags);
+ drawControl((QStyle::ControlElement)(int)element, &opt, p, 0); // [FIXME] What should widget really be? I imagine 0 is *wrong*!!!
+ }
+ inline void tqdrawPrimitive( TQ_ComplexControl element, TQPainter *p, const TQRect &r, const TQColorGroup &cg, SFlags flags = Style_Default, const TQStyleOption &opt = TQStyleOption::Default ) const {
+ TQ_UNUSED(r);
+ TQ_UNUSED(cg);
+ TQ_UNUSED(flags);
+ drawComplexControl((QStyle::ComplexControl)(int)element, 0, p, 0); // [FIXME] What should widget and complexcontrol really be? I imagine 0 is *wrong*!!!
+ }
+ inline void tqdrawPrimitive( TQ_ControlElement element, TQPainter *p, const TQRect &r, const TQColorGroup &cg, int flags, const TQStyleOption &opt = TQStyleOption::Default ) const { tqdrawPrimitive( element, p, r, cg, (SFlags)flags, opt); }
+
+// inline void tqdrawPrimitive( TQ_PrimitiveElement pe, TQPainter *p, const TQRect &r, const TQColorGroup &cg, SFlags flags = Style_Default, const TQStyleOption &opt = TQStyleOption::Default ) const { tqdrawPrimitiveBase( pe, p, r, cg, flags, opt); }
+// inline void tqdrawPrimitive( TQ_PrimitiveElement pe, TQPainter *p, const TQRect &r, const TQColorGroup &cg, int flags, const TQStyleOption &opt = TQStyleOption::Default ) const { tqdrawPrimitive( pe, p, r, cg, (SFlags)flags, opt ); }
+ virtual void tqdrawPrimitive( TQ_PrimitiveElement pe, TQPainter *p, const TQRect &r, const TQColorGroup &cg, SFlags flags = Style_Default, const TQStyleOption &opt = TQStyleOption::Default ) const = 0;
+
+ inline static TQRect tqvisualRect( const TQRect &logical, const TQWidget *w ) { return visualRect(QApplication::layoutDirection(), w->rect(), logical); }
+ inline static TQRect tqvisualRect( const QRect &logical, const QRect &bounding ) { return visualRect(QApplication::layoutDirection(), bounding, logical); }
+
+// virtual void tqdrawPrimitiveBase( TQ_PrimitiveElement pe, TQPainter *p, const TQRect &r, const TQColorGroup &cg, SFlags flags = Style_Default, const TQStyleOption &opt = TQStyleOption::Default ) const = 0;
+ virtual TQSize tqsizeFromContents( ContentsType contents, const TQWidget *widget, const TQSize &contentsSize, const TQStyleOption& = TQStyleOption::Default ) const = 0;
+ virtual int tqstyleHint( TQ_StyleHint stylehint, const TQWidget *widget = 0, const TQStyleOption& = TQStyleOption::Default, TQStyleHintReturn* returnData = 0) const = 0;
+ virtual TQRect subRect( SubRect r, const TQWidget *widget ) const = 0; // There doesn't seem to be a Qt4 equivalent for this virtual function; should it just be left as-is here?
+ virtual TQRect tqitemRect( QPainter *p, const QRect &r, int flags, bool enabled, const QPixmap *pixmap, const QString &text, int len = -1 ) const;
+ virtual void tqdrawControlMask( TQ_ControlElement element, TQPainter *p, const TQWidget *widget, const TQRect &r, const TQStyleOption& = TQStyleOption::Default ) const = 0; // There doesn't seem to be a Qt4 equivalent for this virtual function; should it just be left as-is here?
+ virtual void tqdrawControl( TQ_ControlElement element, TQPainter *p, const TQWidget *widget, const TQRect &r, const TQColorGroup &cg, SFlags how = Style_Default, const TQStyleOption& = TQStyleOption::Default ) const = 0;
+ virtual int tqpixelMetric( PixelMetric metric, const TQWidget *widget = 0 ) const = 0;
+ virtual TQRect querySubControlMetrics( TQ_ComplexControl control, const TQWidget *widget, SubControl sc, const TQStyleOption& = TQStyleOption::Default ) const = 0; // There doesn't seem to be a Qt4 equivalent for this virtual function; should it just be left as-is here?
+ virtual void tqdrawComplexControl( TQ_ComplexControl control, TQPainter *p, const TQWidget *widget, const TQRect &r, const TQColorGroup &cg, SFlags how = Style_Default,
+#ifdef TQ_TQDOC
+ SCFlags sub = SC_All,
+#else
+ SCFlags sub = (uint)SC_All,
+#endif
+ SCFlags subActive = SC_None, const TQStyleOption& = TQStyleOption::Default ) const = 0;
+ virtual void tqdrawComplexControlMask( TQ_ComplexControl control, TQPainter *p, const TQWidget *widget, const TQRect &r, const TQStyleOption& = TQStyleOption::Default ) const = 0; // There doesn't seem to be a Qt4 equivalent for this virtual function; should it just be left as-is here?
+ virtual TQPixmap stylePixmap( StylePixmap stylepixmap, const TQWidget *widget = 0, const TQStyleOption& = TQStyleOption::Default ) const = 0;
+ virtual SubControl querySubControl( TQ_ComplexControl control, const TQWidget *widget, const TQPoint &pos, const TQStyleOption& = TQStyleOption::Default ) const = 0; // There doesn't seem to be a Qt4 equivalent for this virtual function; should it just be left as-is here?
+ virtual void polishPopupMenu( TQPopupMenu* ) = 0; // There doesn't seem to be a Qt4 equivalent for this virtual function; should it just be left as-is here?
+
+ // The Qt4 methods need to be here as well, otherwise they will be hidden by the method definitions above...
+// virtual void drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPainter *p, const QWidget *w = 0) const = 0;
+// virtual QSize sizeFromContents(ContentsType ct, const QStyleOption *opt, const QSize &contentsSize, const QWidget *w = 0) const = 0;
+
+ // These are implemented in the cpp file
+ virtual void drawItem( TQPainter *p, const TQRect &r, int flags, const TQColorGroup &g, bool enabled, const TQPixmap *pixmap, const TQString &text, int len = -1, const TQColor *penColor = 0 ) const;
+
+ // Compatibility
+ virtual void polish( TQWidget * );
+ virtual void unPolish( TQWidget * );
+ virtual void polish( TQApplication * );
+ virtual void unPolish( TQApplication * );
+ virtual void polish( TQPalette & );
+
+ // Feel free to look but please don't touch!
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_01
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_02
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_03
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_04
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_05
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_06
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_07
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_08
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_09
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_10
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_11
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_12
+ TQT_TQSTYLE_QT4_INTERFACE_VFUNC_13
+
+ // Old 2.x TQStyle API
+
+#ifndef TQT_NO_COMPAT
+ int defaultFrameWidth() const {
+ return tqpixelMetric( PM_DefaultFrameWidth );
+ }
+
+ void tabbarMetrics( const TQWidget* t, int& hf, int& vf, int& ov ) const {
+ hf = tqpixelMetric( PM_TabBarTabHSpace, t );
+ vf = tqpixelMetric( PM_TabBarTabVSpace, t );
+ ov = tqpixelMetric( PM_TabBarBaseOverlap, t );
+ }
+
+ TQSize scrollBarExtent() const {
+ return TQSize(tqpixelMetric(PM_ScrollBarExtent), tqpixelMetric(PM_ScrollBarExtent));
+ }
+#endif
+
+public Q_SLOTS:
+ void tqt_handle_qt_destroyed(QObject* obj) { emit destroyed(TQT_TQOBJECT(obj)); }
+
+Q_SIGNALS:
+ void destroyed( TQObject* obj );
+
+private:
+ mutable TQString static_object_name;
+};
+
+#else // USE_QT4
+
+#ifndef TQT_NO_STYLE
+
+class TQPopupMenu;
+class TQStylePrivate;
+class TQMenuItem;
+class TQTab;
+class TQListViewItem;
+class TQCheckListItem;
+
+class TQStyleOption {
+public:
+ enum StyleOptionDefault { Default };
+
+ TQStyleOption(StyleOptionDefault=Default) : def(TRUE) {}
+
+ // Note: we don't use default arguments since that is unnecessary
+ // initialization.
+ TQStyleOption(int in1) :
+ def(FALSE), i1(in1) {}
+ TQStyleOption(int in1, int in2) :
+ def(FALSE), i1(in1), i2(in2) {}
+ TQStyleOption(int in1, int in2, int in3, int in4) :
+ def(FALSE), i1(in1), i2(in2), i3(in3), i4(in4) {}
+ TQStyleOption(TQMenuItem* m) : def(FALSE), mi(m) {}
+ TQStyleOption(TQMenuItem* m, int in1) : def(FALSE), mi(m), i1(in1) {}
+ TQStyleOption(TQMenuItem* m, int in1, int in2) : def(FALSE), mi(m), i1(in1), i2(in2) {}
+ TQStyleOption(const TQColor& c) : def(FALSE), cl(&c) {}
+ TQStyleOption(TQTab* t) : def(FALSE), tb(t) {}
+ TQStyleOption(TQListViewItem* i) : def(FALSE), li(i) {}
+ TQStyleOption(TQCheckListItem* i) : def(FALSE), cli(i) {}
+ TQStyleOption(TQt::ArrowType a) : def(FALSE), i1((int)a) {}
+ TQStyleOption(const TQRect& r) : def(FALSE), i1(r.x()), i2(r.y()), i3(r.width()),i4(r.height()){}
+ TQStyleOption(TQWidget *w) : def(FALSE), p1((void*)w) {}
+
+ bool isDefault() const { return def; }
+
+ int day() const { return i1; }
+
+ int lineWidth() const { return i1; }
+ int midLineWidth() const { return i2; }
+ int frameShape() const { return i3; }
+ int frameShadow() const { return i4; }
+
+ int headerSection() const { return i1; }
+ TQMenuItem* menuItem() const { return mi; }
+ int maxIconWidth() const { return i1; }
+ int tabWidth() const { return i2; }
+
+ const TQColor& color() const { return *cl; }
+
+ TQTab* tab() const { return tb; }
+
+ TQCheckListItem* checkListItem() const { return cli; }
+ TQListViewItem* listViewItem() const { return li; }
+
+ TQt::ArrowType arrowType() const { return (TQt::ArrowType)i1; }
+ TQRect rect() const { return TQRect( i1, i2, i3, i4 ); }
+ TQWidget* widget() const { return (TQWidget*)p1; }
+
+private:
+ // NOTE: none of these components have constructors.
+ bool def;
+ bool b1,b2,b3; // reserved
+ TQMenuItem* mi;
+ TQTab* tb;
+ TQListViewItem* li;
+ const TQColor* cl;
+ int i1, i2, i3, i4;
+ int i5, i6; // reserved
+ TQCheckListItem* cli;
+ void *p1, *p2, *p3, *p4; // reserved
+ // (padded to 64 bytes on some architectures)
+};
+
+class TQStyleHintReturn; // not defined yet
+
+class TQ_EXPORT TQStyle: public TQObject
+{
+ TQ_OBJECT
+
+public:
+ TQStyle();
+ virtual ~TQStyle();
+
+ // New TQStyle API - most of these should probably be pure virtual
+
+ virtual void polish( TQWidget * );
+ virtual void unPolish( TQWidget * );
+
+ virtual void polish( TQApplication * );
+ virtual void unPolish( TQApplication * );
+
+ virtual void polish( TQPalette & );
+
+ virtual void polishPopupMenu( TQPopupMenu* ) = 0;
+
+ virtual TQRect tqitemRect( TQPainter *p, const TQRect &r,
+ int flags, bool enabled,
+ const TQPixmap *pixmap,
+ const TQString &text, int len = -1 ) const;
+
+ virtual void drawItem( TQPainter *p, const TQRect &r,
+ int flags, const TQColorGroup &g, bool enabled,
+ const TQPixmap *pixmap, const TQString &text,
+ int len = -1, const TQColor *penColor = 0 ) const;
+
+
+ enum PrimitiveElement {
+ PE_ButtonCommand,
+ PE_ButtonDefault,
+ PE_ButtonBevel,
+ PE_ButtonTool,
+ PE_ButtonDropDown,
+
+ PE_FocusRect,
+
+ PE_ArrowUp,
+ PE_ArrowDown,
+ PE_ArrowRight,
+ PE_ArrowLeft,
+
+ PE_SpinWidgetUp,
+ PE_SpinWidgetDown,
+ PE_SpinWidgetPlus,
+ PE_SpinWidgetMinus,
+
+ PE_Indicator,
+ PE_IndicatorMask,
+ PE_ExclusiveIndicator,
+ PE_ExclusiveIndicatorMask,
+
+ PE_DockWindowHandle,
+ PE_DockWindowSeparator,
+ PE_DockWindowResizeHandle,
+
+ PE_Splitter,
+
+ PE_Panel,
+ PE_PanelPopup,
+ PE_PanelMenuBar,
+ PE_PanelDockWindow,
+
+ PE_TabBarBase,
+
+ PE_HeaderSection,
+ PE_HeaderArrow,
+ PE_tqStatusBarSection,
+
+ PE_GroupBoxFrame,
+
+ PE_Separator,
+
+ PE_SizeGrip,
+
+ PE_CheckMark,
+
+ PE_ScrollBarAddLine,
+ PE_ScrollBarSubLine,
+ PE_ScrollBarAddPage,
+ PE_ScrollBarSubPage,
+ PE_ScrollBarSlider,
+ PE_ScrollBarFirst,
+ PE_ScrollBarLast,
+
+ PE_ProgressBarChunk,
+
+ PE_PanelLineEdit,
+ PE_PanelTabWidget,
+
+ PE_WindowFrame,
+
+ PE_CheckListController,
+ PE_CheckListIndicator,
+ PE_CheckListExclusiveIndicator,
+
+ PE_PanelGroupBox,
+ PE_RubberBand,
+
+ // do not add any values below/greater this
+ PE_CustomBase = 0xf000000
+ };
+
+ enum StyleFlags {
+ Style_Default = 0x00000000,
+ Style_Enabled = 0x00000001,
+ Style_Raised = 0x00000002,
+ Style_Sunken = 0x00000004,
+ Style_Off = 0x00000008,
+ Style_NoChange = 0x00000010,
+ Style_On = 0x00000020,
+ Style_Down = 0x00000040,
+ Style_Horizontal = 0x00000080,
+ Style_HasFocus = 0x00000100,
+ Style_Top = 0x00000200,
+ Style_Bottom = 0x00000400,
+ Style_FocusAtBorder = 0x00000800,
+ Style_AutoRaise = 0x00001000,
+ Style_MouseOver = 0x00002000,
+ Style_Up = 0x00004000,
+ Style_Selected = 0x00008000,
+ Style_Active = 0x00010000,
+ Style_ButtonDefault = 0x00020000
+ };
+ typedef uint SFlags;
+
+ virtual void drawPrimitive( PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const = 0;
+
+
+ enum ControlElement {
+ CE_PushButton,
+ CE_PushButtonLabel,
+
+ CE_CheckBox,
+ CE_CheckBoxLabel,
+
+ CE_RadioButton,
+ CE_RadioButtonLabel,
+
+ CE_TabBarTab,
+ CE_TabBarLabel,
+
+ CE_ProgressBarGroove,
+ CE_ProgressBarContents,
+ CE_ProgressBarLabel,
+
+ CE_PopupMenuItem,
+ CE_MenuBarItem,
+
+ CE_ToolButtonLabel,
+ CE_MenuBarEmptyArea,
+ CE_PopupMenuScroller,
+ CE_DockWindowEmptyArea,
+ CE_PopupMenuVerticalExtra,
+ CE_PopupMenuHorizontalExtra,
+
+ CE_ToolBoxTab,
+ CE_HeaderLabel,
+
+ // do not add any values below/greater than this
+ CE_CustomBase = 0xf0000000
+ };
+
+ virtual void tqdrawControl( ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const = 0;
+ virtual void tqdrawControlMask( ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQStyleOption& = TQStyleOption::Default ) const = 0;
+
+ enum SubRect {
+ SR_PushButtonContents,
+ SR_PushButtonFocusRect,
+
+ SR_CheckBoxIndicator,
+ SR_CheckBoxContents,
+ SR_CheckBoxFocusRect,
+
+ SR_RadioButtonIndicator,
+ SR_RadioButtonContents,
+ SR_RadioButtonFocusRect,
+
+ SR_ComboBoxFocusRect,
+
+ SR_SliderFocusRect,
+
+ SR_DockWindowHandleRect,
+
+ SR_ProgressBarGroove,
+ SR_ProgressBarContents,
+ SR_ProgressBarLabel,
+
+ SR_ToolButtonContents,
+
+ SR_DialogButtonAccept,
+ SR_DialogButtonReject,
+ SR_DialogButtonApply,
+ SR_DialogButtonHelp,
+ SR_DialogButtonAll,
+ SR_DialogButtonAbort,
+ SR_DialogButtonIgnore,
+ SR_DialogButtonRetry,
+ SR_DialogButtonCustom,
+
+ SR_ToolBoxTabContents,
+
+ // do not add any values below/greater than this
+ SR_CustomBase = 0xf0000000
+ };
+
+ virtual TQRect subRect( SubRect r, const TQWidget *widget ) const = 0;
+
+
+ enum ComplexControl{
+ CC_SpinWidget,
+ CC_ComboBox,
+ CC_ScrollBar,
+ CC_Slider,
+ CC_ToolButton,
+ CC_TitleBar,
+ CC_ListView,
+
+ // do not add any values below/greater than this
+ CC_CustomBase = 0xf0000000
+ };
+
+ enum SubControl {
+ SC_None = 0x00000000,
+
+ SC_ScrollBarAddLine = 0x00000001,
+ SC_ScrollBarSubLine = 0x00000002,
+ SC_ScrollBarAddPage = 0x00000004,
+ SC_ScrollBarSubPage = 0x00000008,
+ SC_ScrollBarFirst = 0x00000010,
+ SC_ScrollBarLast = 0x00000020,
+ SC_ScrollBarSlider = 0x00000040,
+ SC_ScrollBarGroove = 0x00000080,
+
+ SC_SpinWidgetUp = 0x00000001,
+ SC_SpinWidgetDown = 0x00000002,
+ SC_SpinWidgetFrame = 0x00000004,
+ SC_SpinWidgetEditField = 0x00000008,
+ SC_SpinWidgetButtonField = 0x00000010,
+
+ SC_ComboBoxFrame = 0x00000001,
+ SC_ComboBoxEditField = 0x00000002,
+ SC_ComboBoxArrow = 0x00000004,
+ SC_ComboBoxListBoxPopup = 0x00000008,
+
+ SC_SliderGroove = 0x00000001,
+ SC_SliderHandle = 0x00000002,
+ SC_SliderTickmarks = 0x00000004,
+
+ SC_ToolButton = 0x00000001,
+ SC_ToolButtonMenu = 0x00000002,
+
+ SC_TitleBarLabel = 0x00000001,
+ SC_TitleBarSysMenu = 0x00000002,
+ SC_TitleBarMinButton = 0x00000004,
+ SC_TitleBarMaxButton = 0x00000008,
+ SC_TitleBarCloseButton = 0x00000010,
+ SC_TitleBarNormalButton = 0x00000020,
+ SC_TitleBarShadeButton = 0x00000040,
+ SC_TitleBarUnshadeButton = 0x00000080,
+
+ SC_ListView = 0x00000001,
+ SC_ListViewBranch = 0x00000002,
+ SC_ListViewExpand = 0x00000004,
+
+ SC_All = 0xffffffff
+ };
+ typedef uint SCFlags;
+
+
+ virtual void tqdrawComplexControl( ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+#ifdef TQ_TQDOC
+ SCFlags sub = SC_All,
+#else
+ SCFlags sub = (uint)SC_All,
+#endif
+ SCFlags subActive = SC_None,
+ const TQStyleOption& = TQStyleOption::Default ) const = 0;
+ virtual void tqdrawComplexControlMask( ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQStyleOption& = TQStyleOption::Default ) const = 0;
+
+ virtual TQRect querySubControlMetrics( ComplexControl control,
+ const TQWidget *widget,
+ SubControl sc,
+ const TQStyleOption& = TQStyleOption::Default ) const = 0;
+ virtual SubControl querySubControl( ComplexControl control,
+ const TQWidget *widget,
+ const TQPoint &pos,
+ const TQStyleOption& = TQStyleOption::Default ) const = 0;
+
+
+ enum PixelMetric {
+ PM_ButtonMargin,
+ PM_ButtonDefaultIndicator,
+ PM_MenuButtonIndicator,
+ PM_ButtonShiftHorizontal,
+ PM_ButtonShiftVertical,
+
+ PM_DefaultFrameWidth,
+ PM_SpinBoxFrameWidth,
+
+ PM_MaximumDragDistance,
+
+ PM_ScrollBarExtent,
+ PM_ScrollBarSliderMin,
+
+ PM_SliderThickness, // total slider thickness
+ PM_SliderControlThickness, // thickness of the business part
+ PM_SliderLength, // total length of slider
+ PM_SliderTickmarkOffset, //
+ PM_SliderSpaceAvailable, // available space for slider to move
+
+ PM_DockWindowSeparatorExtent,
+ PM_DockWindowHandleExtent,
+ PM_DockWindowFrameWidth,
+
+ PM_MenuBarFrameWidth,
+
+ PM_TabBarTabOverlap,
+ PM_TabBarTabHSpace,
+ PM_TabBarTabVSpace,
+ PM_TabBarBaseHeight,
+ PM_TabBarBaseOverlap,
+
+ PM_ProgressBarChunkWidth,
+
+ PM_SplitterWidth,
+ PM_TitleBarHeight,
+
+ PM_IndicatorWidth,
+ PM_IndicatorHeight,
+ PM_ExclusiveIndicatorWidth,
+ PM_ExclusiveIndicatorHeight,
+ PM_PopupMenuScrollerHeight,
+ PM_CheckListButtonSize,
+ PM_CheckListControllerSize,
+ PM_PopupMenuFrameHorizontalExtra,
+ PM_PopupMenuFrameVerticalExtra,
+
+ PM_DialogButtonsSeparator,
+ PM_DialogButtonsButtonWidth,
+ PM_DialogButtonsButtonHeight,
+
+ PM_MDIFrameWidth,
+ PM_MDIMinimizedWidth,
+ PM_HeaderMargin,
+ PM_HeaderMarkSize,
+ PM_HeaderGripMargin,
+ PM_TabBarTabShiftHorizontal,
+ PM_TabBarTabShiftVertical,
+ PM_TabBarScrollButtonWidth,
+
+ PM_MenuBarItemSpacing,
+ PM_ToolBarItemSpacing,
+
+ // do not add any values below/greater than this
+ PM_CustomBase = 0xf0000000
+ };
+
+ virtual int tqpixelMetric( PixelMetric metric,
+ const TQWidget *widget = 0 ) const = 0;
+
+
+ enum ContentsType {
+ CT_PushButton,
+ CT_CheckBox,
+ CT_RadioButton,
+ CT_ToolButton,
+ CT_ComboBox,
+ CT_Splitter,
+ CT_DockWindow,
+ CT_ProgressBar,
+ CT_PopupMenuItem,
+ CT_TabBarTab,
+ CT_Slider,
+ CT_Header,
+ CT_LineEdit,
+ CT_MenuBar,
+ CT_SpinBox,
+ CT_SizeGrip,
+ CT_TabWidget,
+ CT_DialogButtons,
+
+ // do not add any values below/greater than this
+ CT_CustomBase = 0xf0000000
+ };
+
+ virtual TQSize sizeFromContents( ContentsType contents,
+ const TQWidget *widget,
+ const TQSize &contentsSize,
+ const TQStyleOption& = TQStyleOption::Default ) const = 0;
+
+ enum StyleHint {
+ // ...
+ // the general hints
+ // ...
+ // disabled text should be etched, ala Windows
+ SH_EtchDisabledText,
+
+ // the GUI style enum, argh!
+ SH_GUIStyle,
+
+ // ...
+ // widget specific hints
+ // ...
+ SH_ScrollBar_BackgroundMode,
+ SH_ScrollBar_MiddleClickAbsolutePosition,
+ SH_ScrollBar_ScrollWhenPointerLeavesControl,
+
+ // TQEvent::Type - which mouse event to select a tab
+ SH_TabBar_SelectMouseType,
+
+ SH_TabBar_Alignment,
+
+ SH_Header_ArrowAlignment,
+
+ // bool - sliders snap to values while moving, ala Windows
+ SH_Slider_SnapToValue,
+
+ // bool - key presses handled in a sloppy manner - ie. left on a vertical
+ // slider subtracts a line
+ SH_Slider_SloppyKeyEvents,
+
+ // bool - center button on progress dialogs, ala Motif, else right aligned
+ // perhaps this should be a TQt::Alignment value
+ SH_ProgressDialog_CenterCancelButton,
+
+ // TQt::AlignmentFlags - text label tqalignment in progress dialogs
+ // Center on windows, Auto|VCenter otherwize
+ SH_ProgressDialog_TextLabelAlignment,
+
+ // bool - right align buttons on print dialog, ala Windows
+ SH_PrintDialog_RightAlignButtons,
+
+ // bool - 1 or 2 pixel space between the menubar and the dockarea, ala Windows
+ // this *REALLY* needs a better name
+ SH_MainWindow_SpaceBelowMenuBar,
+
+ // bool - select the text in the line edit about the listbox when selecting
+ // an item from the listbox, or when the line edit receives focus, ala Windows
+ SH_FontDialog_SelectAssociatedText,
+
+ // bool - allows disabled menu items to be active
+ SH_PopupMenu_AllowActiveAndDisabled,
+
+ // bool - pressing space activates item, ala Motif
+ SH_PopupMenu_SpaceActivatesItem,
+
+ // int - number of milliseconds to wait before opening a submenu
+ // 256 on windows, 96 on motif
+ SH_PopupMenu_SubMenuPopupDelay,
+
+ // bool - should scrollviews draw their frame only around contents (ala Motif),
+ // or around contents, scrollbars and corner widgets (ala Windows) ?
+ SH_ScrollView_FrameOnlyAroundContents,
+
+ // bool - menubars items are navigatable by pressing alt, followed by using
+ // the arrow keys to select the desired item
+ SH_MenuBar_AltKeyNavigation,
+
+ // bool - mouse tracking in combobox dropdown lists
+ SH_ComboBox_ListMouseTracking,
+
+ // bool - mouse tracking in popupmenus
+ SH_PopupMenu_MouseTracking,
+
+ // bool - mouse tracking in menubars
+ SH_MenuBar_MouseTracking,
+
+ // bool - gray out selected items when loosing focus
+ SH_ItemView_ChangeHighlightOnFocus,
+
+ // bool - supports shared activation among modeless widgets
+ SH_Widget_ShareActivation,
+
+ // bool - workspace should just maximize the client area
+ SH_Workspace_FillSpaceOnMaximize,
+
+ // bool - supports popup menu comboboxes
+ SH_ComboBox_Popup,
+
+ // bool - titlebar has no border
+ SH_TitleBar_NoBorder,
+
+ // bool - stop scrollbar at mouse
+ SH_ScrollBar_StopMouseOverSlider,
+
+ //bool - blink cursort with selected text
+ SH_BlinkCursorWhenTextSelected,
+
+ //bool - richtext selections extend the full width of the docuemnt
+ SH_RichText_FullWidthSelection,
+
+ //bool - popupmenu supports scrolling instead of multicolumn mode
+ SH_PopupMenu_Scrollable,
+
+ // TQt::AlignmentFlags - text label vertical tqalignment in groupboxes
+ // Center on windows, Auto|VCenter otherwize
+ SH_GroupBox_TextLabelVerticalAlignment,
+
+ // TQt::TQRgb - text label color in groupboxes
+ SH_GroupBox_TextLabelColor,
+
+ // bool - popupmenu supports sloppy submenus
+ SH_PopupMenu_SloppySubMenus,
+
+ // TQt::TQRgb - table grid color
+ SH_Table_GridLineColor,
+
+ // TQChar - Unicode character for password char
+ SH_LineEdit_PasswordCharacter,
+
+ // TQDialogButtons::Button - default button
+ SH_DialogButtons_DefaultButton,
+
+ // TQToolBox - Boldness of the selected page title
+ SH_ToolBox_SelectedPageTitleBold,
+
+ //bool - if a tabbar prefers not to have scroller arrows
+ SH_TabBar_PreferNoArrows,
+
+ //bool - if left button should cause an absolute position
+ SH_ScrollBar_LeftClickAbsolutePosition,
+
+ // TQEvent::Type - which mouse event to select a list view expansion
+ SH_ListViewExpand_SelectMouseType,
+
+ //bool - if underline for accelerators
+ SH_UnderlineAccelerator,
+
+ // bool - TQToolButton - if tool buttons should use a 3D frame
+ // when the mouse is over the button
+ SH_ToolButton_Uses3D,
+
+ // do not add any values below/greater than this
+ SH_CustomBase = 0xf0000000
+ };
+
+ virtual int tqstyleHint( StyleHint stylehint,
+ const TQWidget *widget = 0,
+ const TQStyleOption& = TQStyleOption::Default,
+ TQStyleHintReturn* returnData = 0
+ ) const = 0;
+
+
+ enum StylePixmap {
+ SP_TitleBarMinButton,
+ SP_TitleBarMaxButton,
+ SP_TitleBarCloseButton,
+ SP_TitleBarNormalButton,
+ SP_TitleBarShadeButton,
+ SP_TitleBarUnshadeButton,
+ SP_DockWindowCloseButton,
+ SP_MessageBoxInformation,
+ SP_MessageBoxWarning,
+ SP_MessageBoxCritical,
+ SP_MessageBoxQuestion,
+
+ // do not add any values below/greater than this
+ SP_CustomBase = 0xf0000000
+ };
+
+ virtual TQPixmap stylePixmap( StylePixmap stylepixmap,
+ const TQWidget *widget = 0,
+ const TQStyleOption& = TQStyleOption::Default ) const = 0;
+
+
+ static TQRect tqvisualRect( const TQRect &logical, const TQWidget *w );
+
+ static TQRect tqvisualRect( const TQRect &logical, const TQRect &bounding );
+
+
+
+
+ // Old 2.x TQStyle API
+
+#ifndef TQT_NO_COMPAT
+ int defaultFrameWidth() const
+ {
+ return tqpixelMetric( PM_DefaultFrameWidth );
+ }
+ void tabbarMetrics( const TQWidget* t,
+ int& hf, int& vf, int& ov ) const
+ {
+ hf = tqpixelMetric( PM_TabBarTabHSpace, t );
+ vf = tqpixelMetric( PM_TabBarTabVSpace, t );
+ ov = tqpixelMetric( PM_TabBarBaseOverlap, t );
+ }
+ TQSize scrollBarExtent() const
+ {
+ return TQSize(tqpixelMetric(PM_ScrollBarExtent),
+ tqpixelMetric(PM_ScrollBarExtent));
+ }
+#endif
+
+
+private:
+ TQStylePrivate * d;
+
+#if defined(TQ_DISABLE_COPY)
+ TQStyle( const TQStyle & );
+ TQStyle& operator=( const TQStyle & );
+#endif
+};
+
+#endif // TQT_NO_STYLE
+#endif // TQSTYLE_H
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqstylesheet.cpp b/tqtinterface/qt4/src/kernel/tqstylesheet.cpp
new file mode 100644
index 0000000..25f6c0c
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqstylesheet.cpp
@@ -0,0 +1,1623 @@
+/****************************************************************************
+**
+** Implementation of the TQStyleSheet class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqstylesheet.h"
+
+#ifndef TQT_NO_RICHTEXT
+
+#include "private/tqrichtext_p.h"
+#include "tqlayout.h"
+#include "tqpainter.h"
+#include "tqcleanuphandler.h"
+
+#include <stdio.h>
+
+class TQStyleSheetItemData
+{
+public:
+ TQStyleSheetItem::DisplayMode disp;
+ int fontitalic;
+ int fontunderline;
+ int fontstrikeout;
+ int fontweight;
+ int fontsize;
+ int fontsizelog;
+ int fontsizestep;
+ int lineSpacing;
+ TQString fontfamily;
+ TQStyleSheetItem *parentstyle;
+ TQString stylename;
+ int ncolumns;
+ TQColor col;
+ bool anchor;
+ int align;
+ TQStyleSheetItem::VerticalAlignment valign;
+ int margin[5];
+ TQStyleSheetItem::ListStyle list;
+ TQStyleSheetItem::WhiteSpaceMode whitespacemode;
+ TQString contxt;
+ bool selfnest;
+ TQStyleSheet* sheet;
+};
+
+/*!
+ \class TQStyleSheetItem tqstylesheet.h
+ \brief The TQStyleSheetItem class provides an encapsulation of a set of text styles.
+
+ \ingroup text
+
+ A style sheet item consists of a name and a set of attributes that
+ specifiy its font, color, etc. When used in a \link TQStyleSheet
+ style sheet\endlink (see styleSheet()), items define the name() of
+ a rich text tag and the display property changes associated with
+ it.
+
+ The \link TQStyleSheetItem::DisplayMode display mode\endlink
+ attribute indicates whether the item is a block, an inline element
+ or a list element; see setDisplayMode(). The treatment of
+ whitespace is controlled by the \link
+ TQStyleSheetItem::WhiteSpaceMode white space mode\endlink; see
+ setWhiteSpaceMode(). An item's margins are set with setMargin(),
+ In the case of list items, the list style is set with
+ setListStyle(). An item may be a hypertext link anchor; see
+ setAnchor(). Other attributes are set with tqsetAlignment(),
+ setVerticalAlignment(), setFontFamily(), setFontSize(),
+ setFontWeight(), setFontItalic(), setFontUnderline(),
+ setFontStrikeOut and setColor().
+*/
+
+/*! \enum TQStyleSheetItem::AdditionalStyleValues
+ \internal
+*/
+
+/*!
+ \enum TQStyleSheetItem::WhiteSpaceMode
+
+ This enum defines the ways in which TQStyleSheet can treat
+ whitespace.
+
+ \value WhiteSpaceNormal any sequence of whitespace (including
+ line-breaks) is equivalent to a single space.
+
+ \value WhiteSpacePre whitespace must be output exactly as given
+ in the input.
+
+ \value WhiteSpaceNoWrap multiple spaces are collapsed as with
+ WhiteSpaceNormal, but no automatic line-breaks occur. To break
+ lines manually, use the \c{<br>} tag.
+
+*/
+
+/*!
+ \enum TQStyleSheetItem::Margin
+
+ \value MarginLeft left margin
+ \value MarginRight right margin
+ \value MarginTop top margin
+ \value MarginBottom bottom margin
+ \value MarginAll all margins (left, right, top and bottom)
+ \value MarginVertical top and bottom margins
+ \value MarginHorizontal left and right margins
+ \value MarginFirstLine margin (indentation) of the first line of
+ a paragarph (in addition to the MarginLeft of the paragraph)
+*/
+
+/*!
+ Constructs a new style called \a name for the stylesheet \a
+ tqparent.
+
+ All properties in TQStyleSheetItem are initially in the "do not
+ change" state, except \link TQStyleSheetItem::DisplayMode display
+ mode\endlink, which defaults to \c DisplayInline.
+*/
+TQStyleSheetItem::TQStyleSheetItem( TQStyleSheet* tqparent, const TQString& name )
+{
+ d = new TQStyleSheetItemData;
+ d->stylename = name.lower();
+ d->sheet = tqparent;
+ init();
+ if (tqparent)
+ tqparent->insert( this );
+}
+
+/*!
+ Copy constructor. Constructs a copy of \a other that is not bound
+ to any style sheet.
+*/
+TQStyleSheetItem::TQStyleSheetItem( const TQStyleSheetItem & other )
+{
+ d = new TQStyleSheetItemData;
+ *d = *other.d;
+}
+
+
+/*!
+ Destroys the style. Note that TQStyleSheetItem objects become
+ owned by TQStyleSheet when they are created.
+*/
+TQStyleSheetItem::~TQStyleSheetItem()
+{
+ delete d;
+}
+
+/*!
+ Assignment. Assings a copy of \a other that is not bound to any style sheet.
+ Unbounds first from previous style sheet.
+ */
+TQStyleSheetItem& TQStyleSheetItem::operator=( const TQStyleSheetItem& other )
+{
+ if ( &other == this )
+ return *this;
+ delete d;
+ d = new TQStyleSheetItemData;
+ *d = *other.d;
+ return *this;
+}
+
+/*!
+ Returns the style sheet this item is in.
+*/
+TQStyleSheet* TQStyleSheetItem::styleSheet()
+{
+ return d->sheet;
+}
+
+/*!
+ \overload
+
+ Returns the style sheet this item is in.
+*/
+const TQStyleSheet* TQStyleSheetItem::styleSheet() const
+{
+ return d->sheet;
+}
+
+/*!
+ \internal
+ Internal initialization
+ */
+void TQStyleSheetItem::init()
+{
+ d->disp = DisplayInline;
+
+ d->fontitalic = Undefined;
+ d->fontunderline = Undefined;
+ d->fontstrikeout = Undefined;
+ d->fontweight = Undefined;
+ d->fontsize = Undefined;
+ d->fontsizelog = Undefined;
+ d->fontsizestep = 0;
+ d->ncolumns = Undefined;
+ d->col = TQColor(); // !isValid()
+ d->anchor = FALSE;
+ d->align = Undefined;
+ d->valign = VAlignBaseline;
+ d->margin[0] = Undefined;
+ d->margin[1] = Undefined;
+ d->margin[2] = Undefined;
+ d->margin[3] = Undefined;
+ d->margin[4] = Undefined;
+ d->list = ListStyleUndefined;
+ d->whitespacemode = WhiteSpaceModeUndefined;
+ d->selfnest = TRUE;
+ d->lineSpacing = Undefined;
+}
+
+/*!
+ Returns the name of the style item.
+*/
+TQString TQStyleSheetItem::name() const
+{
+ return d->stylename;
+}
+
+/*!
+ Returns the \link TQStyleSheetItem::DisplayMode display
+ mode\endlink of the style.
+
+ \sa setDisplayMode()
+*/
+TQStyleSheetItem::DisplayMode TQStyleSheetItem::displayMode() const
+{
+ return d->disp;
+}
+
+/*!
+ \enum TQStyleSheetItem::DisplayMode
+
+ This enum type defines the way adjacent elements are displayed.
+
+ \value DisplayBlock elements are displayed as a rectangular block
+ (e.g. \c{<p>...</p>}).
+
+ \value DisplayInline elements are displayed in a horizontally
+ flowing sequence (e.g. \c{<em>...</em>}).
+
+ \value DisplayListItem elements are displayed in a vertical
+ sequence (e.g. \c{<li>...</li>}).
+
+ \value DisplayNone elements are not displayed at all.
+*/
+
+/*!
+ Sets the display mode of the style to \a m.
+
+ \sa displayMode()
+ */
+void TQStyleSheetItem::setDisplayMode(DisplayMode m)
+{
+ d->disp=m;
+}
+
+
+/*!
+ Returns the tqalignment of this style. Possible values are \c
+ AlignAuto, \c AlignLeft, \c AlignRight, \c AlignCenter or \c
+ AlignJustify.
+
+ \sa tqsetAlignment(), TQt::AlignmentFlags
+*/
+int TQStyleSheetItem::tqalignment() const
+{
+ return d->align;
+}
+
+/*!
+ Sets the tqalignment to \a f. This only makes sense for styles with
+ a \link TQStyleSheetItem::DisplayMode display mode\endlink of
+ DisplayBlock. Possible values are \c AlignAuto, \c AlignLeft,
+ \c AlignRight, \c AlignCenter or \c AlignJustify.
+
+ \sa tqalignment(), displayMode(), TQt::AlignmentFlags
+*/
+void TQStyleSheetItem::tqsetAlignment( int f )
+{
+ d->align = f;
+}
+
+
+/*!
+ Returns the vertical tqalignment of the style. Possible values are
+ \c VAlignBaseline, \c VAlignSub or \c VAlignSuper.
+
+ \sa setVerticalAlignment()
+*/
+TQStyleSheetItem::VerticalAlignment TQStyleSheetItem::verticalAlignment() const
+{
+ return d->valign;
+}
+
+/*!
+ \enum TQStyleSheetItem::VerticalAlignment
+
+ This enum type defines the way elements are aligned vertically.
+ This is only supported for text elements.
+
+ \value VAlignBaseline align the baseline of the element (or the
+ bottom, if the element doesn't have a baseline) with the
+ baseline of the tqparent
+
+ \value VAlignSub subscript the element
+
+ \value VAlignSuper superscript the element
+
+*/
+
+
+/*!
+ Sets the vertical tqalignment to \a valign. Possible values are
+ \c VAlignBaseline, \c VAlignSub or \c VAlignSuper.
+
+ The vertical tqalignment property is not inherited.
+
+ \sa verticalAlignment()
+*/
+void TQStyleSheetItem::setVerticalAlignment( VerticalAlignment valign )
+{
+ d->valign = valign;
+}
+
+
+/*!
+ Returns TRUE if the style sets an italic font; otherwise returns
+ FALSE.
+
+ \sa setFontItalic(), definesFontItalic()
+*/
+bool TQStyleSheetItem::fontItalic() const
+{
+ return d->fontitalic > 0;
+}
+
+/*!
+ If \a italic is TRUE sets italic for the style; otherwise sets
+ upright.
+
+ \sa fontItalic(), definesFontItalic()
+*/
+void TQStyleSheetItem::setFontItalic(bool italic)
+{
+ d->fontitalic = italic?1:0;
+}
+
+/*!
+ Returns TRUE if the style defines a font tqshape; otherwise returns
+ FALSE. A style does not define any tqshape until setFontItalic() is
+ called.
+
+ \sa setFontItalic(), fontItalic()
+*/
+bool TQStyleSheetItem::definesFontItalic() const
+{
+ return d->fontitalic != Undefined;
+}
+
+/*!
+ Returns TRUE if the style sets an underlined font; otherwise
+ returns FALSE.
+
+ \sa setFontUnderline(), definesFontUnderline()
+*/
+bool TQStyleSheetItem::fontUnderline() const
+{
+ return d->fontunderline > 0;
+}
+
+/*!
+ If \a underline is TRUE, sets underline for the style; otherwise
+ sets no underline.
+
+ \sa fontUnderline(), definesFontUnderline()
+*/
+void TQStyleSheetItem::setFontUnderline(bool underline)
+{
+ d->fontunderline = underline?1:0;
+}
+
+/*!
+ Returns TRUE if the style defines a setting for the underline
+ property of the font; otherwise returns FALSE. A style does not
+ define this until setFontUnderline() is called.
+
+ \sa setFontUnderline(), fontUnderline()
+*/
+bool TQStyleSheetItem::definesFontUnderline() const
+{
+ return d->fontunderline != Undefined;
+}
+
+
+/*!
+ Returns TRUE if the style sets a strike out font; otherwise
+ returns FALSE.
+
+ \sa setFontStrikeOut(), definesFontStrikeOut()
+*/
+bool TQStyleSheetItem::fontStrikeOut() const
+{
+ return d->fontstrikeout > 0;
+}
+
+/*!
+ If \a strikeOut is TRUE, sets strike out for the style; otherwise
+ sets no strike out.
+
+ \sa fontStrikeOut(), definesFontStrikeOut()
+*/
+void TQStyleSheetItem::setFontStrikeOut(bool strikeOut)
+{
+ d->fontstrikeout = strikeOut?1:0;
+}
+
+/*!
+ Returns TRUE if the style defines a setting for the strikeOut
+ property of the font; otherwise returns FALSE. A style does not
+ define this until setFontStrikeOut() is called.
+
+ \sa setFontStrikeOut(), fontStrikeOut()
+*/
+bool TQStyleSheetItem::definesFontStrikeOut() const
+{
+ return d->fontstrikeout != Undefined;
+}
+
+
+/*!
+ Returns the font weight setting of the style. This is either a
+ valid \c TQFont::Weight or the value \c TQStyleSheetItem::Undefined.
+
+ \sa setFontWeight(), TQFont
+*/
+int TQStyleSheetItem::fontWeight() const
+{
+ return d->fontweight;
+}
+
+/*!
+ Sets the font weight setting of the style to \a w. Valid values
+ are those defined by \c TQFont::Weight.
+
+ \sa TQFont, fontWeight()
+*/
+void TQStyleSheetItem::setFontWeight(int w)
+{
+ d->fontweight = w;
+}
+
+/*!
+ Returns the logical font size setting of the style. This is either
+ a valid size between 1 and 7 or \c TQStyleSheetItem::Undefined.
+
+ \sa setLogicalFontSize(), setLogicalFontSizeStep(), TQFont::pointSize(), TQFont::setPointSize()
+*/
+int TQStyleSheetItem::logicalFontSize() const
+{
+ return d->fontsizelog;
+}
+
+
+/*!
+ Sets the logical font size setting of the style to \a s. Valid
+ logical sizes are 1 to 7.
+
+ \sa logicalFontSize(), TQFont::pointSize(), TQFont::setPointSize()
+*/
+void TQStyleSheetItem::setLogicalFontSize(int s)
+{
+ d->fontsizelog = s;
+}
+
+/*!
+ Returns the logical font size step of this style.
+
+ The default is 0. Tags such as \c big define \c +1; \c small
+ defines \c -1.
+
+ \sa setLogicalFontSizeStep()
+*/
+int TQStyleSheetItem::logicalFontSizeStep() const
+{
+ return d->fontsizestep;
+}
+
+/*!
+ Sets the logical font size step of this style to \a s.
+
+ \sa logicalFontSizeStep()
+*/
+void TQStyleSheetItem::setLogicalFontSizeStep( int s )
+{
+ d->fontsizestep = s;
+}
+
+
+
+/*!
+ Sets the font size setting of the style to \a s points.
+
+ \sa fontSize(), TQFont::pointSize(), TQFont::setPointSize()
+*/
+void TQStyleSheetItem::setFontSize(int s)
+{
+ d->fontsize = s;
+}
+
+/*!
+ Returns the font size setting of the style. This is either a valid
+ point size or \c TQStyleSheetItem::Undefined.
+
+ \sa setFontSize(), TQFont::pointSize(), TQFont::setPointSize()
+*/
+int TQStyleSheetItem::fontSize() const
+{
+ return d->fontsize;
+}
+
+
+/*!
+ Returns the font family setting of the style. This is either a
+ valid font family or TQString::null if no family has been set.
+
+ \sa setFontFamily(), TQFont::family(), TQFont::setFamily()
+*/
+TQString TQStyleSheetItem::fontFamily() const
+{
+ return d->fontfamily;
+}
+
+/*!
+ Sets the font family setting of the style to \a fam.
+
+ \sa fontFamily(), TQFont::family(), TQFont::setFamily()
+*/
+void TQStyleSheetItem::setFontFamily( const TQString& fam)
+{
+ d->fontfamily = fam;
+}
+
+
+/*!\obsolete
+ Returns the number of columns for this style.
+
+ \sa setNumberOfColumns(), displayMode(), setDisplayMode()
+
+ */
+int TQStyleSheetItem::numberOfColumns() const
+{
+ return d->ncolumns;
+}
+
+
+/*!\obsolete
+ Sets the number of columns for this style. Elements in the style
+ are divided into columns.
+
+ This makes sense only if the style uses a block display mode
+ (see TQStyleSheetItem::DisplayMode).
+
+ \sa numberOfColumns()
+ */
+void TQStyleSheetItem::setNumberOfColumns(int ncols)
+{
+ if (ncols > 0)
+ d->ncolumns = ncols;
+}
+
+
+/*!
+ Returns the text color of this style or an invalid color if no
+ color has been set.
+
+ \sa setColor() TQColor::isValid()
+*/
+TQColor TQStyleSheetItem::color() const
+{
+ return d->col;
+}
+
+/*!
+ Sets the text color of this style to \a c.
+
+ \sa color()
+*/
+void TQStyleSheetItem::setColor( const TQColor &c)
+{
+ d->col = c;
+}
+
+/*!
+ Returns whether this style is an anchor.
+
+ \sa setAnchor()
+*/
+bool TQStyleSheetItem::isAnchor() const
+{
+ return d->anchor;
+}
+
+/*!
+ If \a anc is TRUE, sets this style to be an anchor (hypertext
+ link); otherwise sets it to not be an anchor. Elements in this
+ style link to other documents or anchors.
+
+ \sa isAnchor()
+*/
+void TQStyleSheetItem::setAnchor(bool anc)
+{
+ d->anchor = anc;
+}
+
+
+/*!
+ Returns the whitespace mode.
+
+ \sa setWhiteSpaceMode() WhiteSpaceMode
+*/
+TQStyleSheetItem::WhiteSpaceMode TQStyleSheetItem::whiteSpaceMode() const
+{
+ return d->whitespacemode;
+}
+
+/*!
+ Sets the whitespace mode to \a m.
+
+ \sa WhiteSpaceMode
+*/
+void TQStyleSheetItem::setWhiteSpaceMode(WhiteSpaceMode m)
+{
+ d->whitespacemode = m;
+}
+
+
+/*!
+ Returns the width of margin \a m in pixels.
+
+ The margin, \a m, can be \c MarginLeft, \c MarginRight, \c
+ MarginTop, \c MarginBottom, or \c MarginFirstLine.
+
+ \sa setMargin() Margin
+*/
+int TQStyleSheetItem::margin(Margin m) const
+{
+ if (m == MarginAll ) {
+ return d->margin[MarginLeft];
+ } else if (m == MarginVertical) {
+ return d->margin[MarginTop];
+ } else if (m == MarginHorizontal) {
+ return d->margin[MarginLeft];
+ } else {
+ return d->margin[m];
+ }
+}
+
+
+/*!
+ Sets the width of margin \a m to \a v pixels.
+
+ The margin, \a m, can be \c MarginLeft, \c MarginRight, \c
+ MarginTop, \c MarginBottom, \c MarginFirstLine, \c MarginAll,
+ \c MarginVertical or \c MarginHorizontal. The value \a v must
+ be >= 0.
+
+ \sa margin()
+*/
+void TQStyleSheetItem::setMargin(Margin m, int v)
+{
+ if (m == MarginAll) {
+ d->margin[MarginLeft] = v;
+ d->margin[MarginRight] = v;
+ d->margin[MarginTop] = v;
+ d->margin[MarginBottom] = v;
+ } else if (m == MarginVertical ) {
+ d->margin[MarginTop] = v;
+ d->margin[MarginBottom] = v;
+ } else if (m == MarginHorizontal ) {
+ d->margin[MarginLeft] = v;
+ d->margin[MarginRight] = v;
+ } else {
+ d->margin[m] = v;
+ }
+}
+
+
+/*!
+ Returns the list style of the style.
+
+ \sa setListStyle() ListStyle
+ */
+TQStyleSheetItem::ListStyle TQStyleSheetItem::listStyle() const
+{
+ return d->list;
+}
+
+/*!
+ \enum TQStyleSheetItem::ListStyle
+
+ This enum type defines how the items in a list are prefixed when
+ displayed.
+
+ \value ListDisc a filled circle (i.e. a bullet)
+ \value ListCircle an unfilled circle
+ \value ListSquare a filled square
+ \value ListDecimal an integer in base 10: \e 1, \e 2, \e 3, ...
+ \value ListLowerAlpha a lowercase letter: \e a, \e b, \e c, ...
+ \value ListUpperAlpha an uppercase letter: \e A, \e B, \e C, ...
+*/
+
+/*!
+ Sets the list style of the style to \a s.
+
+ This is used by nested elements that have a display mode of \c
+ DisplayListItem.
+
+ \sa listStyle() DisplayMode ListStyle
+*/
+void TQStyleSheetItem::setListStyle(ListStyle s)
+{
+ d->list=s;
+}
+
+
+/*!
+ Returns a space-separated list of names of styles that may contain
+ elements of this style. If nothing has been set, contexts()
+ returns an empty string, which indicates that this style can be
+ nested everywhere.
+
+ \sa setContexts()
+*/
+TQString TQStyleSheetItem::contexts() const
+{
+ return d->contxt;
+}
+
+/*!
+ Sets a space-separated list of names of styles that may contain
+ elements of this style. If \a c is empty, the style can be nested
+ everywhere.
+
+ \sa contexts()
+*/
+void TQStyleSheetItem::setContexts( const TQString& c)
+{
+ d->contxt = TQChar(' ') + c + TQChar(' ');
+}
+
+/*!
+ Returns TRUE if this style can be nested into an element of style
+ \a s; otherwise returns FALSE.
+
+ \sa contexts(), setContexts()
+*/
+bool TQStyleSheetItem::allowedInContext( const TQStyleSheetItem* s) const
+{
+ if ( d->contxt.isEmpty() )
+ return TRUE;
+ return d->contxt.tqfind( TQChar(' ')+s->name()+TQChar(' ')) != -1;
+}
+
+
+/*!
+ Returns TRUE if this style has self-nesting enabled; otherwise
+ returns FALSE.
+
+ \sa setSelfNesting()
+*/
+bool TQStyleSheetItem::selfNesting() const
+{
+ return d->selfnest;
+}
+
+/*!
+ Sets the self-nesting property for this style to \a nesting.
+
+ In order to support "dirty" HTML, paragraphs \c{<p>} and list
+ items \c{<li>} are not self-nesting. This means that starting a
+ new paragraph or list item automatically closes the previous one.
+
+ \sa selfNesting()
+*/
+void TQStyleSheetItem::setSelfNesting( bool nesting )
+{
+ d->selfnest = nesting;
+}
+
+/*!
+ \internal
+ Sets the linespacing to be at least \a ls pixels.
+
+ For compatibility with previous TQt releases, small values get
+ treated differently: If \a ls is smaller than the default font
+ line spacing in pixels at parse time, the resulting line spacing
+ is the sum of the default line spacing plus \a ls. We recommend
+ not relying on this behavior.
+*/
+
+void TQStyleSheetItem::setLineSpacing( int ls )
+{
+ d->lineSpacing = ls;
+}
+
+/*!
+ \obsolete
+
+ Returns the linespacing
+*/
+
+int TQStyleSheetItem::lineSpacing() const
+{
+ return d->lineSpacing;
+}
+
+//************************************************************************
+
+
+
+
+//************************************************************************
+
+
+/*!
+ \class TQStyleSheet tqstylesheet.h
+ \ingroup text
+ \brief The TQStyleSheet class is a collection of styles for rich text
+ rendering and a generator of tags.
+
+ \ingroup graphics
+ \ingroup helpsystem
+
+ By creating TQStyleSheetItem objects for a style sheet you build a
+ definition of a set of tags. This definition will be used by the
+ internal rich text rendering system to parse and display text
+ documents to which the style sheet applies. Rich text is normally
+ visualized in a TQTextEdit or a TQTextBrowser. However, TQLabel,
+ TQWhatsThis and TQMessageBox also support it, and other classes are
+ likely to follow. With TQSimpleRichText it is possible to use the
+ rich text renderer for custom widgets as well.
+
+ The default TQStyleSheet object has the following style bindings,
+ sorted by structuring bindings, anchors, character style bindings
+ (i.e. inline styles), special elements such as horizontal lines or
+ images, and other tags. In addition, rich text supports simple
+ HTML tables.
+
+ The structuring tags are
+ \table
+ \header \i Structuring tags \i Notes
+ \row \i \c{<qt>}...\c{</qt>}
+ \i A TQt rich text document. It understands the following
+ attributes:
+ \list
+ \i \c title -- The caption of the document. This attribute is
+ easily accessible with TQTextEdit::documentTitle().
+ \i \c type -- The type of the document. The default type is \c
+ page. It indicates that the document is displayed in a
+ page of its own. Another style is \c detail, which can be
+ used to explain certain expressions in more detail in a
+ few sentences. For \c detail, TQTextBrowser will then keep
+ the current page and display the new document in a small
+ popup similar to TQWhatsThis. Note that links will not work
+ in documents with \c{<qt type="detail">...</qt>}.
+ \i \c bgcolor -- The background color, for example \c
+ bgcolor="yellow" or \c bgcolor="#0000FF".
+ \i \c background -- The background pixmap, for example \c
+ background="granite.xpm". The pixmap name will be resolved
+ by a TQMimeSourceFactory().
+ \i \c text -- The default text color, for example \c text="red".
+ \i \c link -- The link color, for example \c link="green".
+ \endlist
+ \row \i \c{<h1>...</h1>}
+ \i A top-level heading.
+ \row \i \c{<h2>...</h2>}
+ \i A sublevel heading.
+ \row \i \c{<h3>...</h3>}
+ \i A sub-sublevel heading.
+ \row \i \c{<h4>...</h4>} \c{<h5>...</h5>}
+ \i Headings of lesser importance.
+ \row \i \c{<p>...</p>}
+ \i A left-aligned paragraph. Adjust the tqalignment with the \c
+ align attribute. Possible values are \c left, \c right and
+ \c center.
+ \row \i \c{<center>...}<br>\c{</center>}
+ \i A centered paragraph.
+ \row \i \c{<blockquote>...}<br>\c{</blockquote>}
+ \i An indented paragraph that is useful for quotes.
+ \row \i \c{<ul>...</ul>}
+ \i An unordered list. You can also pass a type argument to
+ define the bullet style. The default is \c type=disc;
+ other types are \c circle and \c square.
+ \row \i \c{<ol>...</ol>}
+ \i An ordered list. You can also pass a type argument to
+ define the enumeration label style. The default is \c
+ type="1"; other types are \c "a" and \c "A".
+ \row \i \c{<li>...</li>}
+ \i A list item. This tag can be used only within the context
+ of \c{<ol>} or \c{<ul>}.
+ \row \i \c{<dl>...</dl>}
+ \i A list of definitions, consisting of terms and descriptions.
+ \row \i \c{<dt>...</dt>}
+ \i A term in a list of definitions. This tag can be used only
+ in the context of \c{<dl>...</dl>}.
+ \row \i \c{<dd>...</dd>}
+ \i A description in a list of definitions. This tag can be
+ used only in the context of \c{<dl>...</dl>}.
+ \row \i \c{<pre>...</pre>}
+ \i For larger chunks of code. Whitespaces in the contents are
+ preserved. For small bits of code use the inline-style \c
+ code.
+ \row \i \c{<div>...</div>} and \c{<span>...</span>}
+ \i Block grouping elements. These are used to structure the
+ document, and are often used to provide hints about the
+ intended presentation of the document.
+ \endtable
+
+ Anchors and links are done with a single tag:
+ \table
+ \header \i Anchor tags \i Notes
+ \row \i \c{<a>...</a>}
+ \i An anchor or link.
+ \list
+ \i A link is created by using an \c href
+ attribute, for example
+ <br>\c{<a href="target.qml">Link Text</a>}. Links to
+ targets within a document are achieved in the same way
+ as for HTML, e.g.
+ <br>\c{<a href="target.qml#subtitle">Link Text</a>}.
+ \i A target is created by using a \c name
+ attribute, for example
+ <br>\c{<a name="subtitle"><h2>Sub Title</h2></a>}.
+ \endlist
+ \endtable
+
+ The default character style bindings are
+ \table
+ \header \i Style tags \i Notes
+ \row \i \c{<em>...</em>}
+ \i Emphasized. By default this is the same as \c{<i>...</i>}
+ (italic).
+ \row \i \c{<strong>...</strong>}
+ \i Strong. By default this is the same as \c{<b>...</b>}
+ (bold).
+ \row \i \c{<i>...</i>}
+ \i Italic font style.
+ \row \i \c{<b>...</b>}
+ \i Bold font style.
+ \row \i \c{<u>...</u>}
+ \i Underlined font style.
+ \row \i \c{<s>...</s>}
+ \i Strike out font style.
+ \row \i \c{<big>...</big>}
+ \i A larger font size.
+ \row \i \c{<small>...</small>}
+ \i A smaller font size.
+ \row \i \c{<sub>...</sub>}
+ \i Subscripted text
+ \row \i \c{<sup>...</sup>}
+ \i Superscripted text
+ \row \i \c{<code>...</code>}
+ \i Indicates code. By default this is the same as
+ \c{<tt>...</tt>} (typewriter). For larger chunks of code
+ use the block-tag \c{<}\c{pre>}.
+ \row \i \c{<tt>...</tt>}
+ \i Typewriter font style.
+ \row \i \c{<font>...</font>}
+ \i Customizes the font size, family and text color. The tag
+ understands the following attributes:
+ \list
+ \i \c color -- The text color, for example \c color="red" or
+ \c color="#FF0000".
+ \i \c size -- The logical size of the font. Logical sizes 1
+ to 7 are supported. The value may either be absolute
+ (for example, \c size=3) or relative (\c size=-2). In
+ the latter case the sizes are simply added.
+ \i \c face -- The family of the font, for example \c face=times.
+ \endlist
+ \endtable
+
+ Special elements are:
+ \table
+ \header \i Special tags \i Notes
+ \row \i \c{<img>}
+ \i An image. The image name for the mime source factory is
+ given in the source attribute, for example
+ \c{<img src="qt.xpm">} The image tag also understands the
+ attributes \c width and \c height that determine the size
+ of the image. If the pixmap does not fit the specified
+ size it will be scaled automatically (by using
+ TQImage::smoothScale()).
+ <br>
+ The \c align attribute determines where the image is
+ placed. By default, an image is placed inline just like a
+ normal character. Specify \c left or \c right to place the
+ image at the respective side.
+ \row \i \c{<hr>}
+ \i A horizontal line.
+ \row \i \c{<br>}
+ \i A line break.
+ \row \i \c{<nobr>...</nobr>}
+ \i No break. Prevents word wrap.
+ \endtable
+
+ In addition, rich text supports simple HTML tables. A table
+ consists of one or more rows each of which tqcontains one or more
+ cells. Cells are either data cells or header cells, depending on
+ their content. Cells which span rows and columns are supported.
+
+ \table
+ \header \i Table tags \i Notes
+ \row \i \c{<table>...</table>}
+ \i A table. Tables support the following attributes:
+ \list
+ \i \c bgcolor -- The background color.
+ \i \c width -- The table width. This is either an absolute
+ pixel width or a relative percentage of the table's
+ width, for example \c width=80%.
+ \i \c border -- The width of the table border. The default is
+ 0 (= no border).
+ \i \c cellspacing -- Additional space around the table cells.
+ The default is 2.
+ \i \c cellpadding -- Additional space around the contents of
+ table cells. The default is 1.
+ \endlist
+ \row \i \c{<tr>...</tr>}
+ \i A table row. This is only valid within a \c table. Rows
+ support the following attribute:
+ \list
+ \i \c bgcolor -- The background color.
+ \endlist
+ \row \i \c{<th>...</th>}
+ \i A table header cell. Similar to \c td, but defaults to
+ center tqalignment and a bold font.
+ \row \i \c{<td>...</td>}
+ \i A table data cell. This is only valid within a \c tr.
+ Cells support the following attributes:
+ \list
+ \i \c bgcolor -- The background color.
+ \i \c width -- The cell width. This is either an absolute
+ pixel width or a relative percentage of table's width,
+ for example \c width=50%.
+ \i \c colspan -- Specifies how many columns this cell spans.
+ The default is 1.
+ \i \c rowspan -- Specifies how many rows this cell spans. The
+ default is 1.
+ \i \c align -- Alignment; possible values are \c left, \c
+ right, and \c center. The default is \c left.
+ \i \c valign -- Vertical tqalignment; possible values are \c
+ top, \c middle, and \c bottom. The default is \c middle.
+ \endlist
+ \endtable
+*/
+
+/*!
+ Creates a style sheet called \a name, with tqparent \a tqparent. Like
+ any TQObject it will be deleted when its tqparent is destroyed (if
+ the child still exists).
+
+ By default the style sheet has the tag definitions defined above.
+*/
+TQStyleSheet::TQStyleSheet( TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name )
+{
+ init();
+}
+
+/*!
+ Destroys the style sheet. All styles inserted into the style sheet
+ will be deleted.
+*/
+TQStyleSheet::~TQStyleSheet()
+{
+}
+
+/*!
+ \internal
+ Initialized the style sheet to the basic TQt style.
+*/
+void TQStyleSheet::init()
+{
+ styles.setAutoDelete( TRUE );
+
+ nullstyle = new TQStyleSheetItem( this,
+ TQString::tqfromLatin1("") );
+
+ TQStyleSheetItem* style;
+
+ style = new TQStyleSheetItem( this, "qml" ); // compatibility
+ style->setDisplayMode( TQStyleSheetItem::DisplayBlock );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("qt") );
+ style->setDisplayMode( TQStyleSheetItem::DisplayBlock );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("a") );
+ style->setAnchor( TRUE );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("em") );
+ style->setFontItalic( TRUE );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("i") );
+ style->setFontItalic( TRUE );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("big") );
+ style->setLogicalFontSizeStep( 1 );
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("large") ); // compatibility
+ style->setLogicalFontSizeStep( 1 );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("small") );
+ style->setLogicalFontSizeStep( -1 );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("strong") );
+ style->setFontWeight( TQFont::Bold);
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("b") );
+ style->setFontWeight( TQFont::Bold);
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("h1") );
+ style->setFontWeight( TQFont::Bold);
+ style->setLogicalFontSize(6);
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style-> setMargin(TQStyleSheetItem::MarginTop, 18);
+ style-> setMargin(TQStyleSheetItem::MarginBottom, 12);
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("h2") );
+ style->setFontWeight( TQFont::Bold);
+ style->setLogicalFontSize(5);
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style-> setMargin(TQStyleSheetItem::MarginTop, 16);
+ style-> setMargin(TQStyleSheetItem::MarginBottom, 12);
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("h3") );
+ style->setFontWeight( TQFont::Bold);
+ style->setLogicalFontSize(4);
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style-> setMargin(TQStyleSheetItem::MarginTop, 14);
+ style-> setMargin(TQStyleSheetItem::MarginBottom, 12);
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("h4") );
+ style->setFontWeight( TQFont::Bold);
+ style->setLogicalFontSize(3);
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style-> setMargin(TQStyleSheetItem::MarginVertical, 12);
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("h5") );
+ style->setFontWeight( TQFont::Bold);
+ style->setLogicalFontSize(2);
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style-> setMargin(TQStyleSheetItem::MarginTop, 12);
+ style-> setMargin(TQStyleSheetItem::MarginBottom, 4);
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("p") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style-> setMargin(TQStyleSheetItem::MarginVertical, 12);
+ style->setSelfNesting( FALSE );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("center") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style->tqsetAlignment( Qt::AlignCenter );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("twocolumn") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style->setNumberOfColumns( 2 );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("multicol") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ (void) new TQStyleSheetItem( this, TQString::tqfromLatin1("font") );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("ul") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style->setListStyle( TQStyleSheetItem::ListDisc );
+ style-> setMargin(TQStyleSheetItem::MarginVertical, 12);
+ style->setMargin( TQStyleSheetItem::MarginLeft, 40 );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("ol") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style->setListStyle( TQStyleSheetItem::ListDecimal );
+ style-> setMargin(TQStyleSheetItem::MarginVertical, 12);
+ style->setMargin( TQStyleSheetItem::MarginLeft, 40 );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("li") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayListItem);
+ style->setSelfNesting( FALSE );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("code") );
+ style->setFontFamily( TQString::tqfromLatin1("Courier New,courier") );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("tt") );
+ style->setFontFamily( TQString::tqfromLatin1("Courier New,courier") );
+
+ new TQStyleSheetItem(this, TQString::tqfromLatin1("img"));
+ new TQStyleSheetItem(this, TQString::tqfromLatin1("br"));
+ new TQStyleSheetItem(this, TQString::tqfromLatin1("hr"));
+
+ style = new TQStyleSheetItem(this, TQString::tqfromLatin1("sub"));
+ style->setVerticalAlignment( TQStyleSheetItem::VAlignSub );
+ style = new TQStyleSheetItem(this, TQString::tqfromLatin1("sup"));
+ style->setVerticalAlignment( TQStyleSheetItem::VAlignSuper );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("pre") );
+ style->setFontFamily( TQString::tqfromLatin1("Courier New,courier") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style->setWhiteSpaceMode(TQStyleSheetItem::WhiteSpacePre);
+ style-> setMargin(TQStyleSheetItem::MarginVertical, 12);
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("blockquote") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style->setMargin(TQStyleSheetItem::MarginHorizontal, 40 );
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("head") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayNone);
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("body") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("div") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock) ;
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("span") );
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("dl") );
+ style-> setMargin(TQStyleSheetItem::MarginVertical, 8);
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("dt") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style->setContexts(TQString::tqfromLatin1("dl") );
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("dd") );
+ style->setDisplayMode(TQStyleSheetItem::DisplayBlock);
+ style->setMargin(TQStyleSheetItem::MarginLeft, 30);
+ style->setContexts(TQString::tqfromLatin1("dt dl") );
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("u") );
+ style->setFontUnderline( TRUE);
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("s") );
+ style->setFontStrikeOut( TRUE);
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("nobr") );
+ style->setWhiteSpaceMode( TQStyleSheetItem::WhiteSpaceNoWrap );
+
+ // compatibily with some minor 3.0.x TQt versions that had an
+ // undocumented <wsp> tag. ### Remove 3.1
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("wsp") );
+ style->setWhiteSpaceMode( TQStyleSheetItem::WhiteSpacePre );
+
+ // tables
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("table") );
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("tr") );
+ style->setContexts(TQString::tqfromLatin1("table"));
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("td") );
+ style->setContexts(TQString::tqfromLatin1("tr"));
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("th") );
+ style->setFontWeight( TQFont::Bold );
+ style->tqsetAlignment( TQt::AlignCenter );
+ style->setContexts(TQString::tqfromLatin1("tr"));
+
+ style = new TQStyleSheetItem( this, TQString::tqfromLatin1("html") );
+}
+
+
+
+static TQStyleSheet* defaultsheet = 0;
+static TQSingleCleanupHandler<TQStyleSheet> qt_cleanup_stylesheet;
+
+/*!
+ Returns the application-wide default style sheet. This style sheet
+ is used by rich text rendering classes such as TQSimpleRichText,
+ TQWhatsThis and TQMessageBox to define the rendering style and
+ available tags within rich text documents. It also serves as the
+ initial style sheet for the more complex render widgets, TQTextEdit
+ and TQTextBrowser.
+
+ \sa setDefaultSheet()
+*/
+TQStyleSheet* TQStyleSheet::defaultSheet()
+{
+ if (!defaultsheet) {
+ defaultsheet = new TQStyleSheet();
+ qt_cleanup_stylesheet.set( &defaultsheet );
+ }
+ return defaultsheet;
+}
+
+/*!
+ Sets the application-wide default style sheet to \a sheet,
+ deleting any style sheet previously set. The ownership is
+ transferred to TQStyleSheet.
+
+ \sa defaultSheet()
+*/
+void TQStyleSheet::setDefaultSheet( TQStyleSheet* sheet)
+{
+ if ( defaultsheet != sheet ) {
+ if ( defaultsheet )
+ qt_cleanup_stylesheet.reset();
+ delete defaultsheet;
+ }
+ defaultsheet = sheet;
+ if ( defaultsheet )
+ qt_cleanup_stylesheet.set( &defaultsheet );
+}
+
+/*!\internal
+ Inserts \a style. Any tags generated after this time will be
+ bound to this style. Note that \a style becomes owned by the
+ style sheet and will be deleted when the style sheet is destroyed.
+*/
+void TQStyleSheet::insert( TQStyleSheetItem* style )
+{
+ styles.insert(style->name(), style);
+}
+
+
+/*!
+ Returns the style called \a name or 0 if there is no such style.
+*/
+TQStyleSheetItem* TQStyleSheet::item( const TQString& name)
+{
+ if ( name.isNull() )
+ return 0;
+ return styles[name];
+}
+
+/*!
+ \overload
+
+ Returns the style called \a name or 0 if there is no such style
+ (const version)
+*/
+const TQStyleSheetItem* TQStyleSheet::item( const TQString& name) const
+{
+ if ( name.isNull() )
+ return 0;
+ return styles[name];
+}
+
+
+/*!
+ \preliminary
+
+ Generates an internal object for the tag called \a name, given the
+ attributes \a attr, and using additional information provided by
+ the mime source factory \a factory.
+
+ \a context is the optional context of the document, i.e. the path
+ to look for relative links. This becomes important if the text
+ tqcontains relative references, for example within image tags.
+ TQSimpleRichText always uses the default mime source factory (see
+ \l{TQMimeSourceFactory::defaultFactory()}) to resolve these
+ references. The context will then be used to calculate the
+ absolute path. See TQMimeSourceFactory::makeAbsolute() for details.
+
+ \a emptyTag and \a doc are for internal use only.
+
+ This function should not be used in application code.
+*/
+#ifndef TQT_NO_TEXTCUSTOMITEM
+TQTextCustomItem* TQStyleSheet::tag( const TQString& name,
+ const TQMap<TQString, TQString> &attr,
+ const TQString& context,
+ const TQMimeSourceFactory& factory,
+ bool /*emptyTag */, TQTextDocument *doc ) const
+{
+ const TQStyleSheetItem* style = item( name );
+ // first some known tags
+ if ( !style )
+ return 0;
+ if ( style->name() == "img" )
+ return new TQTextImage( doc, attr, context, (TQMimeSourceFactory&)factory );
+ if ( style->name() == "hr" )
+ return new TQTextHorizontalLine( doc, attr, context, (TQMimeSourceFactory&)factory );
+ return 0;
+}
+#endif
+
+
+/*! Auxiliary function. Converts the plain text string \a plain to a
+ rich text formatted paragraph while preserving most of its look.
+
+ \a mode defines the whitespace mode. Possible values are \c
+ TQStyleSheetItem::WhiteSpacePre (no wrapping, all whitespaces
+ preserved) and \c TQStyleSheetItem::WhiteSpaceNormal (wrapping,
+ simplified whitespaces).
+
+ \sa escape()
+*/
+TQString TQStyleSheet::convertFromPlainText( const TQString& plain, TQStyleSheetItem::WhiteSpaceMode mode )
+{
+ int col = 0;
+ TQString rich;
+ rich += "<p>";
+ for ( int i = 0; i < int(plain.length()); ++i ) {
+ if ( plain[i] == '\n' ){
+ int c = 1;
+ while ( i+1 < int(plain.length()) && plain[i+1] == '\n' ) {
+ i++;
+ c++;
+ }
+ if ( c == 1)
+ rich += "<br>\n";
+ else {
+ rich += "</p>\n";
+ while ( --c > 1 )
+ rich += "<br>\n";
+ rich += "<p>";
+ }
+ col = 0;
+ } else {
+ if ( mode == TQStyleSheetItem::WhiteSpacePre && plain[i] == '\t' ){
+ rich += 0x00a0U;
+ ++col;
+ while ( col % 8 ) {
+ rich += 0x00a0U;
+ ++col;
+ }
+ }
+ else if ( mode == TQStyleSheetItem::WhiteSpacePre && plain[i].isSpace() )
+ rich += 0x00a0U;
+ else if ( plain[i] == '<' )
+ rich +="&lt;";
+ else if ( plain[i] == '>' )
+ rich +="&gt;";
+ else if ( plain[i] == '&' )
+ rich +="&amp;";
+ else
+ rich += plain[i];
+ ++col;
+ }
+ }
+ if ( col != 0 )
+ rich += "</p>";
+ return rich;
+}
+
+/*!
+ Auxiliary function. Converts the plain text string \a plain to a
+ rich text formatted string with any HTML meta-characters escaped.
+
+ \sa convertFromPlainText()
+*/
+TQString TQStyleSheet::escape( const TQString& plain)
+{
+ TQString rich;
+ for ( int i = 0; i < int(plain.length()); ++i ) {
+ if ( plain[i] == '<' )
+ rich +="&lt;";
+ else if ( plain[i] == '>' )
+ rich +="&gt;";
+ else if ( plain[i] == '&' )
+ rich +="&amp;";
+ else
+ rich += plain[i];
+ }
+ return rich;
+}
+
+// Must doc this enum somewhere, and it is logically related to TQStyleSheet
+
+/*!
+ \enum TQt::TextFormat
+
+ This enum is used in widgets that can display both plain text and
+ rich text, e.g. TQLabel. It is used for deciding whether a text
+ string should be interpreted as one or the other. This is normally
+ done by passing one of the enum values to a setTextFormat()
+ function.
+
+ \value PlainText The text string is interpreted as a plain text
+ string.
+
+ \value RichText The text string is interpreted as a rich text
+ string using the current TQStyleSheet::defaultSheet().
+
+ \value AutoText The text string is interpreted as for \c RichText
+ if TQStyleSheet::mightBeRichText() returns TRUE, otherwise as
+ \c PlainText.
+
+ \value LogText A special, limited text format which is only used
+ by TQTextEdit in an optimized mode.
+*/
+
+/*!
+ Returns TRUE if the string \a text is likely to be rich text;
+ otherwise returns FALSE.
+
+ This function uses a fast and therefore simple heuristic. It
+ mainly checks whether there is something that looks like a tag
+ before the first line break. Although the result may be correct
+ for common cases, there is no guarantee.
+*/
+bool TQStyleSheet::mightBeRichText( const TQString& text)
+{
+ if ( text.isEmpty() )
+ return FALSE;
+ int start = 0;
+
+ while ( start < int(text.length()) && text[start].isSpace() )
+ ++start;
+ if ( TQT_TQSTRING(text.mid( start, 5 )).lower() == "<!doc" )
+ return TRUE;
+ int open = start;
+ while ( open < int(text.length()) && text[open] != '<'
+ && text[open] != '\n' ) {
+ if ( text[open] == '&' && text.mid(open+1,3) == "lt;" )
+ return TRUE; // support desperate attempt of user to see <...>
+ ++open;
+ }
+ if ( open < (int)text.length() && text[open] == '<' ) {
+ int close = text.tqfind('>', open);
+ if ( close > -1 ) {
+ TQString tag;
+ for (int i = open+1; i < close; ++i) {
+ if ( text[i].isDigit() || text[i].isLetter() )
+ tag += text[i];
+ else if ( !tag.isEmpty() && text[i].isSpace() )
+ break;
+ else if ( !text[i].isSpace() && (!tag.isEmpty() || text[i] != '!' ) )
+ return FALSE; // that's not a tag
+ }
+ return defaultSheet()->item( tag.lower() ) != 0;
+ }
+ }
+ return FALSE;
+}
+
+
+/*!
+ \fn void TQStyleSheet::error( const TQString& msg) const
+
+ This virtual function is called when an error occurs when
+ processing rich text. Reimplement it if you need to catch error
+ messages.
+
+ Errors might occur if some rich text strings contain tags that are
+ not understood by the stylesheet, if some tags are nested
+ incorrectly, or if tags are not closed properly.
+
+ \a msg is the error message.
+*/
+void TQStyleSheet::error( const TQString& ) const
+{
+}
+
+
+/*!
+ Scales the font \a font to the appropriate physical point size
+ corresponding to the logical font size \a logicalSize.
+
+ When calling this function, \a font has a point size corresponding
+ to the logical font size 3.
+
+ Logical font sizes range from 1 to 7, with 1 being the smallest.
+
+ \sa TQStyleSheetItem::logicalFontSize(), TQStyleSheetItem::logicalFontSizeStep(), TQFont::setPointSize()
+ */
+void TQStyleSheet::scaleFont( QFont& font, int logicalSize ) const
+{
+ if ( logicalSize < 1 )
+ logicalSize = 1;
+ if ( logicalSize > 7 )
+ logicalSize = 7;
+ int baseSize = font.pointSize();
+ bool pixel = FALSE;
+ if ( baseSize == -1 ) {
+ baseSize = font.pixelSize();
+ pixel = TRUE;
+ }
+ int s;
+ switch ( logicalSize ) {
+ case 1:
+ s = 7*baseSize/10;
+ break;
+ case 2:
+ s = (8 * baseSize) / 10;
+ break;
+ case 4:
+ s = (12 * baseSize) / 10;
+ break;
+ case 5:
+ s = (15 * baseSize) / 10;
+ break;
+ case 6:
+ s = 2 * baseSize;
+ break;
+ case 7:
+ s = (24 * baseSize) / 10;
+ break;
+ default:
+ s = baseSize;
+ }
+ if ( pixel )
+ font.setPixelSize( s );
+ else
+ font.setPointSize( s );
+}
+
+#endif // TQT_NO_RICHTEXT
diff --git a/tqtinterface/qt4/src/kernel/tqstylesheet.h b/tqtinterface/qt4/src/kernel/tqstylesheet.h
new file mode 100644
index 0000000..7f650be
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqstylesheet.h
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** Definition of the TQStyleSheet class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTYLESHEET_H
+#define TQSTYLESHEET_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqvaluelist.h"
+#include "tqptrvector.h"
+#include "tqdict.h"
+#include "tqobject.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_RICHTEXT
+
+class TQStyleSheet;
+class TQTextDocument;
+template<class Key, class T> class TQMap;
+class TQStyleSheetItemData;
+
+class TQ_EXPORT TQStyleSheetItem : public TQt
+{
+public:
+ TQStyleSheetItem( TQStyleSheet* tqparent, const TQString& name );
+ TQStyleSheetItem( const TQStyleSheetItem & );
+ ~TQStyleSheetItem();
+
+ TQStyleSheetItem& operator=( const TQStyleSheetItem& other );
+
+ TQString name() const;
+
+ TQStyleSheet* styleSheet();
+ const TQStyleSheet* styleSheet() const;
+
+ enum AdditionalStyleValues { Undefined = - 1};
+
+ enum DisplayMode {
+ DisplayBlock,
+ DisplayInline,
+ DisplayListItem,
+ DisplayNone
+#ifndef TQ_TQDOC
+ , DisplayModeUndefined = -1
+#endif
+ };
+
+ DisplayMode displayMode() const;
+ void setDisplayMode(DisplayMode m);
+
+ int tqalignment() const;
+ void tqsetAlignment( int f);
+
+ inline int alignment() const { return tqalignment(); }
+ inline void setAlignment( int f) { tqsetAlignment( f ); }
+
+ enum VerticalAlignment {
+ VAlignBaseline,
+ VAlignSub,
+ VAlignSuper
+ };
+
+ VerticalAlignment verticalAlignment() const;
+ void setVerticalAlignment( VerticalAlignment valign );
+
+ int fontWeight() const;
+ void setFontWeight(int w);
+
+ int logicalFontSize() const;
+ void setLogicalFontSize(int s);
+
+ int logicalFontSizeStep() const;
+ void setLogicalFontSizeStep( int s );
+
+ int fontSize() const;
+ void setFontSize(int s);
+
+ TQString fontFamily() const;
+ void setFontFamily( const TQString& );
+
+ int numberOfColumns() const;
+ void setNumberOfColumns(int ncols);
+
+ TQColor color() const;
+ void setColor( const TQColor &);
+
+ bool fontItalic() const;
+ void setFontItalic( bool );
+ bool definesFontItalic() const;
+
+ bool fontUnderline() const;
+ void setFontUnderline( bool );
+ bool definesFontUnderline() const;
+
+ bool fontStrikeOut() const;
+ void setFontStrikeOut( bool );
+ bool definesFontStrikeOut() const;
+
+ bool isAnchor() const;
+ void setAnchor(bool anc);
+
+ enum WhiteSpaceMode {
+ WhiteSpaceNormal,
+ WhiteSpacePre,
+ WhiteSpaceNoWrap
+#ifndef TQ_TQDOC
+ , WhiteSpaceModeUndefined = -1
+#endif
+ };
+ WhiteSpaceMode whiteSpaceMode() const;
+ void setWhiteSpaceMode(WhiteSpaceMode m);
+
+ enum Margin {
+ MarginLeft,
+ MarginRight,
+ MarginTop,
+ MarginBottom,
+ MarginFirstLine,
+ MarginAll,
+ MarginVertical,
+ MarginHorizontal
+#ifndef TQ_TQDOC
+ , MarginUndefined = -1
+#endif
+ };
+
+ int margin( Margin m) const;
+ void setMargin( Margin, int);
+
+ enum ListStyle {
+ ListDisc,
+ ListCircle,
+ ListSquare,
+ ListDecimal,
+ ListLowerAlpha,
+ ListUpperAlpha
+#ifndef TQ_TQDOC
+ , ListStyleUndefined = -1
+#endif
+ };
+
+ ListStyle listStyle() const;
+ void setListStyle( ListStyle );
+
+ TQString contexts() const;
+ void setContexts( const TQString& );
+ bool allowedInContext( const TQStyleSheetItem* ) const;
+
+ bool selfNesting() const;
+ void setSelfNesting( bool );
+
+ void setLineSpacing( int ls );
+ int lineSpacing() const;
+
+private:
+ void init();
+ TQStyleSheetItemData* d;
+};
+
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQDict<TQStyleSheetItem>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueList< TQPtrVector<TQStyleSheetItem> >;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrVector<TQStyleSheetItem>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueList<TQStyleSheetItem::ListStyle>;
+// TQMOC_SKIP_END
+#endif
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+class TQTextCustomItem;
+#endif
+
+class TQ_EXPORT TQStyleSheet : public TQObject
+{
+ TQ_OBJECT
+public:
+ TQStyleSheet( TQObject *tqparent=0, const char *name=0 );
+ virtual ~TQStyleSheet();
+
+ static TQStyleSheet* defaultSheet();
+ static void setDefaultSheet( TQStyleSheet* );
+
+
+ TQStyleSheetItem* item( const TQString& name);
+ const TQStyleSheetItem* item( const TQString& name) const;
+
+ void insert( TQStyleSheetItem* item);
+
+#ifndef TQT_NO_TEXTCUSTOMITEM
+ virtual TQTextCustomItem* tag( const TQString& name,
+ const TQMap<TQString, TQString> &attr,
+ const TQString& context,
+ const TQMimeSourceFactory& factory,
+ bool emptyTag, TQTextDocument *doc ) const;
+#endif
+ static TQString escape( const TQString& );
+ static TQString convertFromPlainText( const TQString&,
+ TQStyleSheetItem::WhiteSpaceMode mode = TQStyleSheetItem::WhiteSpacePre );
+ static bool mightBeRichText( const TQString& );
+
+ virtual void scaleFont( QFont& font, int logicalSize ) const;
+
+ virtual void error( const TQString& ) const;
+
+private:
+ void init();
+ TQDict<TQStyleSheetItem> styles;
+ TQStyleSheetItem* nullstyle;
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQStyleSheet( const TQStyleSheet & );
+ TQStyleSheet &operator=( const TQStyleSheet & );
+#endif
+};
+
+#endif // TQT_NO_RICHTEXT
+
+#endif // TQSTYLESHEET_H
diff --git a/tqtinterface/qt4/src/kernel/tqt.h b/tqtinterface/qt4/src/kernel/tqt.h
new file mode 100644
index 0000000..3e1fefa
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqt.h
@@ -0,0 +1,379 @@
+/****************************************************************************
+**
+** TQt GUI Toolkit
+**
+** This header file efficiently includes all TQt GUI Toolkit functionality.
+**
+** Generated : Mon Oct 13 13:07:29 CEST 2003
+
+**
+** Copyright (C) 1995-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the TQt GUI Toolkit.
+**
+*****************************************************************************/
+
+#define USE_QT4
+
+#ifdef __cplusplus
+
+#ifndef TQT_H
+#define TQT_H
+#undef QT_NO_TRANSLATION
+#undef TQT_NO_TRANSLATION
+#include "tqglobal.h"
+#include "tqfeatures.h"
+#include "tqshared.h"
+#include "tqptrcollection.h"
+#include "tqglist.h"
+#include "tqobjectdefs.h"
+#include "tqnamespace.h"
+#include "tqgarray.h"
+#include "tqmemarray.h"
+#include "tqcstring.h"
+#include "tqstring.h"
+#include "tqptrlist.h"
+#include "tqiodevice.h"
+#include "tqkeysequence.h"
+#include "tqwindowdefs.h"
+#include "tqgdict.h"
+#include "tqfont.h"
+#include "tqdatastream.h"
+#include "tqpair.h"
+#include "tqpoint.h"
+#include <stdio.h>
+#include "tqtextstream.h"
+#include "tqfontinfo.h"
+#include "tqsizepolicy.h"
+#include "tqtl.h"
+#include "tqsize.h"
+#include "tqrect.h"
+#include "tqbitarray.h"
+#include "tqregion.h"
+#include "tqsql.h"
+#include "tqstrlist.h"
+#include "tqvaluelist.h"
+#include "tqmap.h"
+#include "tqdatetime.h"
+#include "tqmime.h"
+#include "tqasciidict.h"
+#include "tqpaintdevice.h"
+#include "tqfontmetrics.h"
+#include "tqdict.h"
+#include "tqevent.h"
+#include "tqhostaddress.h"
+#include "tqstringlist.h"
+#include "tqcolor.h"
+#include <tqdom.h>
+#include "tqobject.h"
+#include <tqdrawutil.h>
+#include "tqbrush.h"
+#include "tqpalette.h"
+#include "tqwidget.h"
+#include "tqjpunicode.h"
+#include "tqtextcodec.h"
+#include "tqstyle.h"
+#include "tqframe.h"
+#include "tqfile.h"
+#include "tqfileinfo.h"
+#include "tqurlinfo.h"
+#include "tqwidgetlist.h"
+#include <tqcombobox.h>
+#include "tqgroupbox.h"
+#include "tqdialog.h"
+#include <tqdataview.h>
+#include "tqdockwindow.h"
+#include "tqcommonstyle.h"
+#include "tqnetworkprotocol.h"
+#include <tqeuckrcodec.h>
+#include <tqgb18030codec.h>
+#include "tqgcache.h"
+#include "tqpixmap.h"
+#include <tqgif.h>
+#include <tqglcolormap.h>
+#include <tqcache.h>
+#include <tqdropsite.h>
+#include "tqgplugin.h"
+#include <tqgrid.h>
+#include "tqrangecontrol.h"
+#include "tqbuttongroup.h"
+#include <tqdatetimeedit.h>
+#include "tqgvector.h"
+#include "tqhbox.h"
+#include <tqhbuttongroup.h>
+#include "tqiconset.h"
+#include <tqhgroupbox.h>
+#include "tqsocketnotifier.h"
+#include <tqeventloop.h>
+#include <tqhttp.h>
+#include <tqaction.h>
+#include "tqbuffer.h"
+#include "tqimage.h"
+#include <tqimageformatplugin.h>
+#include "tqlineedit.h"
+#include <tqintcache.h>
+#include "tqintdict.h"
+#include "tqmotifstyle.h"
+#include "tqpicture.h"
+#include <tqjiscodec.h>
+#include <tqeucjpcodec.h>
+#include <tqkeycode.h>
+#include <tqaccel.h>
+#include "tqlabel.h"
+#include "tqlayout.h"
+#include <tqlcdnumber.h>
+#include <tqlibrary.h>
+#include <tqinputdialog.h>
+#include "tqscrollbar.h"
+#include "tqscrollview.h"
+#include "tqdir.h"
+#include "tqwindowsstyle.h"
+#include "tqconnection.h"
+#include "tqbitmap.h"
+#include "tqvariant.h"
+#include "tqsignal.h"
+#include <tqmessagebox.h>
+#include "tqmetaobject.h"
+#include "tqheader.h"
+#include <tqmotifplusstyle.h>
+#include <tqcdestyle.h>
+#include <tqmovie.h>
+#include "tqptrvector.h"
+#include "tqmutex.h"
+#include "tqbutton.h"
+#include <tqnetwork.h>
+#include <tqftp.h>
+#include "tqguardedptr.h"
+#include <tqobjectcleanuphandler.h>
+#include "tqsqlfield.h"
+#include <tqobjectdict.h>
+#include <tqobjectlist.h>
+#include <tqcolordialog.h>
+#include <tqpaintdevicemetrics.h>
+#include "tqpointarray.h"
+#include "tqmenudata.h"
+#include <tqlistview.h>
+#include "tqpen.h"
+#include "tqdragobject.h"
+#include <tqiconview.h>
+#include <tqpixmapcache.h>
+#include <tqplatinumstyle.h>
+#include <tqpngio.h>
+#include <tqcursor.h>
+#include <tqerrormessage.h>
+#include <tqpolygonscanner.h>
+#include "tqpopupmenu.h"
+#include <tqprintdialog.h>
+#include <tqprinter.h>
+#include <tqprocess.h>
+#include "tqprogressbar.h"
+#include "tqsemimodal.h"
+#include <tqasciicache.h>
+#include "tqptrdict.h"
+#include <tqcleanuphandler.h>
+#include <tqptrqueue.h>
+#include <tqptrstack.h>
+#include "tqstylesheet.h"
+#include <tqpushbutton.h>
+#include <tqradiobutton.h>
+#include <tqdial.h>
+#include <tqdockarea.h>
+#include "tqregexp.h"
+#include <tqclipboard.h>
+#include <tqrtlcodec.h>
+#include <tqlistbox.h>
+#include <tqgridview.h>
+#include "tqsemaphore.h"
+#include <tqprogressdialog.h>
+#include "tqsocketdevice.h"
+#include <tqsessionmanager.h>
+#include <tqsettings.h>
+#include <tqsgistyle.h>
+#include <tqfontdialog.h>
+#include "tqtimer.h"
+#include <tqsignalmapper.h>
+#include <tqsignalslotimp.h>
+#include <tqsimplerichtext.h>
+#include "tqwmatrix.h"
+#include <tqsizegrip.h>
+#include <tqabstractlayout.h>
+#include <tqsjiscodec.h>
+#include <tqslider.h>
+#include <tqsocket.h>
+#include <tqserversocket.h>
+#include <tqdns.h>
+#include <tqsortedlist.h>
+#include <tqsound.h>
+#include <tqspinbox.h>
+#include <tqsplashscreen.h>
+#include <tqsplitter.h>
+#include "tqsqlerror.h"
+#include "tqeditorfactory.h"
+#include "tqsqlquery.h"
+#include "tqsqlrecord.h"
+#include <tqsqldriverplugin.h>
+#include "tqsqlindex.h"
+#include "tqsqlcursor.h"
+#include <tqsqldriver.h>
+#include <tqsqlform.h>
+#include "tqtable.h"
+#include <tqsqlpropertymap.h>
+#include <tqsqldatabase.h>
+#include <tqdatabrowser.h>
+#include <tqsqlresult.h>
+#include <tqsqlselectcursor.h>
+#include <tqstatusbar.h>
+#include <tqmenubar.h>
+#include <tqcanvas.h>
+#include "tqtranslator.h"
+#include <tqstrvec.h>
+#include <tqinterlacestyle.h>
+#include <tqstylefactory.h>
+#include <tqstyleplugin.h>
+#include "tqtextedit.h"
+#include <tqsyntaxhighlighter.h>
+#include <tqtabbar.h>
+#include <tqtabdialog.h>
+#include "tqsqleditorfactory.h"
+#include <tqtabwidget.h>
+#include <tqtextbrowser.h>
+#include <tqbig5codec.h>
+#include <tqtextcodecfactory.h>
+#include <tqtextcodecplugin.h>
+#include <tqmultilineedit.h>
+#include "tqtoolbar.h"
+#include <tqtextview.h>
+#include "tqwaitcondition.h"
+#include <tqasyncio.h>
+#include <tqfontdatabase.h>
+#include <tqmainwindow.h>
+#include <tqtoolbox.h>
+#include <tqtoolbutton.h>
+#include <tqtooltip.h>
+#include "tqdesktopwidget.h"
+#include <tqtsciicodec.h>
+#include "tqurl.h"
+#include "tqurloperator.h"
+#include <tqfiledialog.h>
+#include <tqutfcodec.h>
+#include <tquuid.h>
+#include <tqvalidator.h>
+#include <tqasyncimageio.h>
+#include <tqvaluestack.h>
+#include <tqvaluevector.h>
+#include <tqdatatable.h>
+#include <tqvbox.h>
+#include <tqvbuttongroup.h>
+#include <tqvfbhdr.h>
+#include <tqvgroupbox.h>
+#include <tqthread.h>
+#include <tqwhatsthis.h>
+#include <tqapplication.h>
+#include <tqwidgetintdict.h>
+#include <tqfocusdata.h>
+#include <tqwidgetplugin.h>
+#include <tqwidgetstack.h>
+#include <tqcheckbox.h>
+#include <tqcompactstyle.h>
+#include <tqwizard.h>
+#include <tqpainter.h>
+#include <tqworkspace.h>
+#include <tqlocalfs.h>
+#include <tqxml.h>
+
+#if defined( TQT_TQMOC_CPP ) || defined( TQT_H_CPP ) || defined( TQ_OS_MACX )
+#include <private/tqcom_p.h>
+#include <private/tqucom_p.h>
+#include "private/tqgfxdriverinterface_p.h"
+#include "private/tqcom_p.h"
+#include "private/tqimageformatinterface_p.h"
+#include "private/tqisciicodec_p.h"
+#include "private/tqkbddriverinterface_p.h"
+#include "private/tqlayoutengine_p.h"
+#include "private/tqcomlibrary_p.h"
+#include "private/tqmousedriverinterface_p.h"
+#include "private/tqeffects_p.h"
+#include "private/tqgpluginmanager_p.h"
+#include "private/tqinternal_p.h"
+#include "private/tqsqldriverinterface_p.h"
+#include "private/tqsqlmanager_p.h"
+#include "private/tqlock_p.h"
+#include "private/tqcomponentfactory_p.h"
+#include "private/tqstyleinterface_p.h"
+#include "private/tqrichtext_p.h"
+#include "private/tqsvgdevice_p.h"
+#include "private/tqfontcodecs_p.h"
+#include "private/tqtextcodecinterface_p.h"
+#include "private/tqpsprinter_p.h"
+#include "private/tqtitlebar_p.h"
+#include "private/tqucom_p.h"
+#include "private/tqucomextra_p.h"
+#include "private/tqpluginmanager_p.h"
+#include "private/tqdir_p.h"
+#include "private/tqsettings_p.h"
+#include "private/tqsqlextension_p.h"
+#include "private/tqdialogbuttons_p.h"
+#include "private/tqwidgetinterface_p.h"
+#include "private/tqwidgetresizehandler_p.h"
+#include "private/tqlibrary_p.h"
+#endif // Private headers
+
+
+#ifdef TQ_WS_MAC
+#include <tqaquastyle.h>
+#include <tqmacstyle_mac.h>
+#endif // TQ_WS_MAC
+
+#ifdef TQ_WS_WIN
+#include <tqwindowsxpstyle.h>
+#endif
+
+#ifdef TQ_WS_TQWS
+#include <private/tqtextengine_p.h>
+#include "tqfontmanager_qws.h"
+#include <tqfontfactorybdf_qws.h>
+#include <tqgfxvoodoodefs_qws.h>
+#include <tqgfxmatroxdefs_qws.h>
+#include <tqgfxdriverplugin_qws.h>
+#include <tqkbddriverfactory_qws.h>
+#include <tqkbddriverplugin_qws.h>
+#include <tqmousedriverfactory_qws.h>
+#include <tqmousedriverplugin_qws.h>
+#include <tqcopchannel_qws.h>
+#include <tqdirectpainter_qws.h>
+#include "tqmemorymanager_qws.h"
+#include <tqmouse_qws.h>
+#include <tqfontfactoryttf_qws.h>
+#ifndef TQ_OS_MAC
+# include <tqsoundqss_qws.h>
+#endif
+#include "tqgfx_qws.h"
+#include <tqgfxdriverfactory_qws.h>
+#include "tqwsdisplay_qws.h"
+#include "tqwssocket_qws.h"
+#include "tqwsdecoration_qws.h"
+#include "tqwsutils_qws.h"
+#include <tqwscursor_qws.h>
+#include "tqwsmanager_qws.h"
+#include "tqwsdefaultdecoration_qws.h"
+#include <tqgfxraster_qws.h>
+#include "tqwscommand_qws.h"
+#include <tqwshydrodecoration_qws.h>
+#include <tqwskde2decoration_qws.h>
+#include <tqwskdedecoration_qws.h>
+#include <tqwsbeosdecoration_qws.h>
+#include "tqwsproperty_qws.h"
+#include <tqwsregionmanager_qws.h>
+#include "tqwsevent_qws.h"
+#include <tqwindowsystem_qws.h>
+#include <tqwswindowsdecoration_qws.h>
+#endif // TQ_WS_TQWS
+
+
+#ifdef TQ_WS_WCE
+#include <tqpocketpcstyle_wce.h>
+#endif // TQ_WS_WCE
+
+#endif // TQT_H
+
+#endif // __cplusplus
diff --git a/tqtinterface/qt4/src/kernel/tqt_pch.h b/tqtinterface/qt4/src/kernel/tqt_pch.h
new file mode 100644
index 0000000..6693c8d
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqt_pch.h
@@ -0,0 +1,57 @@
+/*
+ * This is a precompiled header file for use in Xcode / Mac GCC /
+ * GCC >= 3.4 / VC to greatly speed the building of TQt. It may also be
+ * of use to people developing their own project, but it is probably
+ * better to define your own header. Use of this header is currently
+ * UNSUPPORTED.
+ */
+
+#if (defined(_WIN32) || defined(__NT__))
+# define TQT_UNDEF_MACROS_IN_PCH
+# define _WINSCARD_H_
+# define _POSIX_ /* Make sure PATH_MAX et al. are defined */
+# include <limits.h>
+# undef _POSIX_ /* Don't polute */
+#endif
+
+#if defined __cplusplus
+# if defined(__GNUC__)
+# ifndef TQT_NO_STL
+# include <ios>
+# undef _GLIBCPP_FULLY_COMPLIANT_HEADERS // Makes qlocale.cpp compile
+# endif
+# endif
+#include <tqmap.h> // I must be first!
+#include <private/tqucomextra_p.h> // All tqmoc genereated code has this include
+#include <tqapplication.h>
+#include <tqbitmap.h>
+#include <tqcursor.h>
+#include <tqdatetime.h>
+#include <tqglobal.h>
+#include <tqimage.h>
+#include <tqmetaobject.h> // All tqmoc genereated code has this include
+#include <tqobject.h>
+#include <tqpainter.h>
+#include <tqpixmap.h>
+#include <tqplatformdefs.h>
+#include <tqptrlist.h>
+#include <tqstring.h>
+#include <tqstringlist.h>
+#include <tqstyle.h>
+#include <tqtimer.h>
+#include <tqwidget.h>
+
+#include <limits.h>
+#include <stdlib.h>
+#if defined(__GNUC__)
+# ifndef TQT_NO_STL
+# define _GLIBCPP_FULLY_COMPLIANT_HEADERS
+# endif
+#endif
+#endif
+
+#if defined(TQT_UNDEF_MACROS_IN_PCH)
+# undef max /* These are defined in windef.h, but */
+# undef min /* we don't want them when building TQt */
+# undef _WINSCARD_H_
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqt_x11_p.h b/tqtinterface/qt4/src/kernel/tqt_x11_p.h
new file mode 100644
index 0000000..e08531d
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqt_x11_p.h
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Includes X11 system header files.
+**
+** Created : 981123
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQT_X11_H
+#define TQT_X11_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of q*_x11.cpp. This header file may change from version to version
+// without notice, or even be removed.
+//
+//
+
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#endif // TQT_H
+
+// the following is necessary to work around breakage in many versions
+// of XFree86's Xlib.h still in use
+// ### which versions?
+#if defined(_XLIB_H_) // crude hack, but...
+#error "cannot include <X11/Xlib.h> before this file"
+#endif
+#define XRegisterIMInstantiateCallback qt_XRegisterIMInstantiateCallback
+#define XUnregisterIMInstantiateCallback qt_XUnregisterIMInstantiateCallback
+#define XSetIMValues qt_XSetIMValues
+#include <X11/Xlib.h>
+#undef XRegisterIMInstantiateCallback
+#undef XUnregisterIMInstantiateCallback
+#undef XSetIMValues
+
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+
+
+//#define TQT_NO_SHAPE
+#ifdef TQT_NO_SHAPE
+#define XShapeCombineRegion(a,b,c,d,e,f,g)
+#define XShapeCombineMask(a,b,c,d,e,f,g)
+#else
+#include <X11/extensions/shape.h>
+#endif // TQT_NO_SHAPE
+
+
+// the wacom tablet (currently just the IRIX version)
+#if defined (TQT_TABLET_SUPPORT)
+# include <X11/extensions/XInput.h>
+#if defined (TQ_OS_IRIX)
+# include <wacom.h> // wacom driver defines for IRIX (quite handy)
+#endif
+#endif // TQT_TABLET_SUPPORT
+
+
+// #define TQT_NO_XINERAMA
+#ifndef TQT_NO_XINERAMA
+# if 0 // ### Xsun, but how to detect it?
+// Xinerama is only supported in Solaris 7 with patches 107648/108376 and
+// Solaris 8 or above which introduce the X11R6.4 Xserver.
+// To switch the Xinerama functionality on, you need to add the "+xinerama"
+// argument to the Xsun start line.
+// At least Solaris 7 and 8 are missing Xinerama system headers and function
+// declarations (bug 4284701).
+// The Xinerama API is not documented. In theory it could change but it
+// probably won't because Sun are using it in at least dtlogin (bug 4221829).
+extern "C" Bool XPanoramiXQueryExtension(
+ Display*,
+ int*,
+ int*
+);
+extern "C" tqStatus XPanoramiXQueryVersion(
+ Display*,
+ int*,
+ int*
+);
+extern "C" tqStatus XPanoramiXGetState(
+ Display*,
+ Drawable,
+ XPanoramiXInfo*
+);
+extern "C" tqStatus XPanoramiXGetScreenCount(
+ Display *,
+ Drawable,
+ XPanoramiXInfo*
+);
+extern "C" tqStatus XPanoramiXGetScreenSize(
+ Display*,
+ Drawable,
+ int,
+ XPanoramiXInfo*
+);
+# else // XFree86
+// XFree86 does not C++ify Xinerama (at least up to XFree86 4.0.3).
+extern "C" {
+# include <X11/extensions/Xinerama.h>
+}
+# endif
+#endif // TQT_NO_XINERAMA
+
+// #define TQT_NO_XRANDR
+#ifndef TQT_NO_XRANDR
+# include <X11/extensions/Xrandr.h>
+#endif // TQT_NO_XRANDR
+
+// #define TQT_NO_XRENDER
+#ifndef TQT_NO_XRENDER
+# include <X11/extensions/Xrender.h>
+// #define TQT_NO_XFTFREETYPE
+# ifndef TQT_NO_XFTFREETYPE
+// This hacks around the freetype poeple putting an #error into freetype.h in 2.1.7, making
+// it impossible to use an updated freetype with older Xft header files.
+# include <ft2build.h>
+# ifdef TQT_USE_XFT2_HEADER
+# include <X11/Xft/Xft2.h>
+# else
+# include <X11/Xft/Xft.h>
+# endif // TQT_USE_XFT2_HEADER
+# if defined(XFT_VERSION) && XFT_VERSION >= 20000
+# define TQT_XFT2
+# else
+# include <X11/Xft/XftFreetype.h>
+// Xft1 doesn't have these functions, so we implement them in qtaddons_x11.cpp
+extern "C" {
+ TQt::HANDLE XftDrawPicture( XftDraw * );
+ void XftDrawSetClipRectangles(XftDraw *, int, int, XRectangle *, int);
+ void XftDrawSetSubwindowMode(XftDraw *, int);
+}
+# endif // XFT_VERSION
+# endif // TQT_NO_XFTFREETYPE
+#else
+// make sure TQT_NO_XFTFREETYPE is defined if TQT_NO_XRENDER is defined
+# ifndef TQT_NO_XFTFREETYPE
+# define TQT_NO_XFTFREETYPE
+# endif
+#endif // TQT_NO_XRENDER
+
+
+#ifndef TQT_NO_XKB
+# include <X11/XKBlib.h>
+#endif // TQT_NO_XKB
+
+
+#if !defined(XlibSpecificationRelease)
+# define X11R4
+typedef char *XPointer;
+#else
+# undef X11R4
+#endif
+
+// #define TQT_NO_XIM
+#if defined(X11R4)
+// X11R4 does not have XIM
+#define TQT_NO_XIM
+#elif defined(TQ_OS_OSF) && (XlibSpecificationRelease < 6)
+// broken in Xlib up to OSF/1 3.2
+#define TQT_NO_XIM
+#elif defined(TQ_OS_AIX)
+// broken in Xlib up to what version of AIX?
+#define TQT_NO_XIM
+#elif defined(TQT_NO_DEBUG) && defined(TQ_OS_IRIX)
+// XmbLookupString broken on IRIX
+// XCreateIC broken when compiling -64 on IRIX 6.5.2
+#define TQT_NO_XIM
+#elif defined(TQ_OS_HPUX) && defined(__LP64__)
+// XCreateIC broken when compiling 64-bit ELF on HP-UX 11.0
+#define TQT_NO_XIM
+#elif defined(TQ_OS_SCO)
+// ### suggested by user...
+// ### #define TQT_NO_XIM
+#endif // TQT_NO_XIM
+
+
+/*
+ * Solaris patch 108652-47 and higher fixes crases in
+ * XRegisterIMInstantiateCallback, but the function doesn't seem to
+ * work.
+ *
+ * Instead, we disabled R6 input, and open the input method
+ * immediately at application start.
+ */
+#if !defined(TQT_NO_XIM) && (XlibSpecificationRelease >= 6) && \
+ !defined(TQ_OS_SOLARIS)
+#define USE_X11R6_XIM
+
+//######### XFree86 has wrong declarations for XRegisterIMInstantiateCallback
+//######### and XUnregisterIMInstantiateCallback in at least version 3.3.2.
+//######### Many old X11R6 header files lack XSetIMValues.
+//######### Therefore, we have to declare these functions ourselves.
+
+extern "C" Bool XRegisterIMInstantiateCallback(
+ Display*,
+ struct _XrmHashBucketRec*,
+ char*,
+ char*,
+ XIMProc, //XFree86 has XIDProc, which has to be wrong
+ XPointer
+);
+
+extern "C" Bool XUnregisterIMInstantiateCallback(
+ Display*,
+ struct _XrmHashBucketRec*,
+ char*,
+ char*,
+ XIMProc, //XFree86 has XIDProc, which has to be wrong
+ XPointer
+);
+
+extern "C" char *XSetIMValues( XIM /* im */, ... );
+
+#endif
+
+#ifndef TQT_NO_XIM
+// some platforms (eg. Solaris 2.51) don't have these defines in Xlib.h
+#ifndef XNResetState
+#define XNResetState "resetState"
+#endif
+#ifndef XIMPreserveState
+#define XIMPreserveState (1L<<1)
+#endif
+#endif
+
+
+#ifndef X11R4
+# include <X11/Xlocale.h>
+#endif // X11R4
+
+
+#ifdef TQT_MITSHM
+# include <X11/extensions/XShm.h>
+#endif // TQT_MITSHM
+
+
+#endif // TQT_X11_H
diff --git a/tqtinterface/qt4/src/kernel/tqtaddons_x11.cpp b/tqtinterface/qt4/src/kernel/tqtaddons_x11.cpp
new file mode 100644
index 0000000..4ad2199
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtaddons_x11.cpp
@@ -0,0 +1,144 @@
+/*
+ * $XFree86: xc/lib/Xft/xftname.c,v 1.10 2001/03/30 18:50:18 keithp Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSETQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "tqt_x11_p.h"
+
+#if !defined(TQT_NO_XFTFREETYPE) && !defined(TQT_XFT2)
+
+#include <X11/Xft/Xft.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+extern bool qt_use_xrender; // defined in qapplication_x11.cpp
+
+extern "C" {
+
+#define XFT_DRAW_N_SRC 2
+
+struct _XftDraw {
+ Display *dpy;
+ Drawable drawable;
+ Visual *visual;
+ Colormap colormap;
+ Region clip;
+ Bool core_set;
+ Bool render_set;
+ Bool render_able;
+ struct {
+ Picture pict;
+ struct {
+ Picture pict;
+ XRenderColor color;
+ } src[XFT_DRAW_N_SRC];
+ } render;
+ struct {
+ GC draw_gc;
+ unsigned long fg;
+ Font font;
+ } core;
+};
+
+Picture XftDrawPicture( XftDraw *draw )
+{
+ if ( ! draw ) return 0;
+ if ( ! draw->render_set ) {
+ // force the RENDER Picture to be created...
+ XftColor color;
+ color.color.red = color.color.green = color.color.blue = color.color.alpha =
+ color.pixel = 0;
+ XftDrawRect( draw, &color, -100, -100, 1, 1 );
+ }
+ return draw->render.pict;
+}
+
+XftDraw *XftDrawCreateAlpha( Display *display,
+ Pixmap pixmap,
+ int depth )
+{
+ // taken from Xft 1 sources, see copyright above
+ XftDraw *draw;
+
+ draw = (XftDraw *) malloc (sizeof (XftDraw));
+ if (!draw)
+ return 0;
+ draw->dpy = display;
+ draw->drawable = pixmap;
+ draw->visual = 0;
+ draw->colormap = 0;
+ draw->core_set = False;
+ draw->clip = 0;
+
+ // TQt addition - go ahead and create the render picture now
+ draw->render_set = True;
+ draw->render_able = False;
+
+ if ( qt_use_xrender ) {
+ draw->render_able = True;
+
+ XRenderPictFormat *format = 0;
+ XRenderPictFormat req;
+ unsigned long tqmask = PictFormatType | PictFormatDepth | PictFormatAlphaMask;
+ req.type = PictTypeDirect;
+ req.depth = depth;
+ req.direct.alphaMask = 0xff;
+ format = XRenderFindFormat(draw->dpy, tqmask, &req, 0);
+ if (format) {
+ draw->render.pict =
+ XRenderCreatePicture(draw->dpy, draw->drawable, format, 0, 0);
+ }
+
+ // to keep Xft from trying to free zero pixmaps/pictures, we need to create
+ // 2 more pictures (that are identical to draw->render.pict) :/
+ draw->render.src[0].pict =
+ XRenderCreatePicture( draw->dpy, draw->drawable, format, 0, 0 );
+ draw->render.src[1].pict =
+ XRenderCreatePicture( draw->dpy, draw->drawable, format, 0, 0 );
+ }
+
+ return draw;
+}
+
+void XftDrawSetClipRectangles(XftDraw *draw, int xoff, int yoff, XRectangle *rects, int count)
+{
+ if (!draw) return;
+
+ Picture pict = XftDrawPicture(draw);
+ XRenderSetPictureClipRectangles(draw->dpy, pict, xoff, yoff, rects, count);
+}
+
+void XftDrawSetSubwindowMode(XftDraw *draw, int mode)
+{
+ if (!draw) return;
+
+ Picture pict = XftDrawPicture(draw);
+ XRenderPictureAttributes pattr;
+ pattr.subwindow_mode = mode;
+ XRenderChangePicture(draw->dpy, pict, CPSubwindowMode, &pattr);
+}
+
+} // extern "C"
+
+#endif // !TQT_NO_XFTFREETYPE && !TQT_XFT2
diff --git a/tqtinterface/qt4/src/kernel/tqtextengine.cpp b/tqtinterface/qt4/src/kernel/tqtextengine.cpp
new file mode 100644
index 0000000..dd5d9d3
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtextengine.cpp
@@ -0,0 +1,1186 @@
+/****************************************************************************
+**
+** Text engine classes
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtextengine_p.h"
+
+#include "tqscriptengine_p.h"
+#include <tqfont.h>
+#include "tqfontdata_p.h"
+#include "tqfontengine_p.h"
+#include <tqstring.h>
+#include <private/tqunicodetables_p.h>
+#include <stdlib.h>
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+// -----------------------------------------------------------------------------------------------------
+//
+// The BiDi algorithm
+//
+// -----------------------------------------------------------------------------------------------------
+
+
+#define BIDI_DEBUG 0//2
+#if (BIDI_DEBUG >= 1)
+#include <iostream>
+using namespace std;
+
+static const char *directions[] = {
+ "DirL", "DirR", "DirEN", "DirES", "DirET", "DirAN", "DirCS", "DirB", "DirS", "DirWS", "DirON",
+ "DirLRE", "DirLRO", "DirAL", "DirRLE", "DirRLO", "DirPDF", "DirNSM", "DirBN"
+};
+
+#endif
+
+struct BiditqStatus {
+ BiditqStatus() {
+ eor = TQChar::DirON;
+ lastStrong = TQChar::DirON;
+ last = TQChar:: DirON;
+ dir = TQChar::DirON;
+ }
+ TQChar::Direction eor;
+ TQChar::Direction lastStrong;
+ TQChar::Direction last;
+ TQChar::Direction dir;
+};
+
+struct BidiControl {
+ struct Context {
+ unsigned char level : 6;
+ unsigned char override : 1;
+ unsigned char unused : 1;
+ };
+
+ inline BidiControl( bool rtl )
+ : cCtx( 0 ), singleLine( FALSE ) {
+ ctx[0].level = (rtl ? 1 : 0);
+ ctx[0].override = FALSE;
+ }
+
+ inline void embed( int level, bool override = FALSE ) {
+ if ( ctx[cCtx].level < 61 && cCtx < 61 ) {
+ (void) ++cCtx;
+ ctx[cCtx].level = level;
+ ctx[cCtx].override = override;
+ }
+ }
+ inline void pdf() {
+ if ( cCtx ) (void) --cCtx;
+ }
+
+ inline uchar level() const {
+ return ctx[cCtx].level;
+ }
+ inline bool override() const {
+ return ctx[cCtx].override;
+ }
+ inline TQChar::Direction basicDirection() {
+ return (ctx[0].level ? TQChar::DirR : TQChar:: DirL );
+ }
+ inline uchar baseLevel() {
+ return ctx[0].level;
+ }
+ inline TQChar::Direction direction() {
+ return ((ctx[cCtx].level%2) ? TQChar::DirR : TQChar:: DirL );
+ }
+
+ Context ctx[63];
+ unsigned int cCtx : 8;
+ bool singleLine : 8;
+};
+
+static TQChar::Direction basicDirection( const TQString &str )
+{
+ int len = str.length();
+ int pos = 0;
+ const TQChar *uc = str.tqunicode() + pos;
+ while( pos < len ) {
+ switch( direction( *uc ) )
+ {
+ case TQChar::DirL:
+ case TQChar::DirLRO:
+ case TQChar::DirLRE:
+ return TQChar::DirL;
+ case TQChar::DirR:
+ case TQChar::DirAL:
+ case TQChar::DirRLO:
+ case TQChar::DirRLE:
+ return TQChar::DirR;
+ default:
+ break;
+ }
+ ++pos;
+ ++uc;
+ }
+ return TQChar::DirL;
+}
+
+
+static void tqAppendItems(TQTextEngine *engine, int &start, int &stop, BidiControl &control, TQChar::Direction dir )
+{
+ TQScriptItemArray &items = engine->items;
+ const TQChar *text = engine->string.tqunicode();
+
+ if ( start > stop ) {
+ // #### the algorithm is currently not really safe against this. Still needs fixing.
+// qWarning( "Bidi: appendItems() internal error" );
+ return;
+ }
+
+ int level = control.level();
+
+ if(dir != TQChar::DirON && !control.override()) {
+ // add level of run (cases I1 & I2)
+ if( level % 2 ) {
+ if(dir == TQChar::DirL || dir == TQChar::DirAN || dir == TQChar::DirEN )
+ level++;
+ } else {
+ if( dir == TQChar::DirR )
+ level++;
+ else if( dir == TQChar::DirAN || dir == TQChar::DirEN )
+ level += 2;
+ }
+ }
+
+#if (BIDI_DEBUG >= 1)
+ qDebug("new run: dir=%s from %d, to %d level = %d\n", directions[dir], start, stop, level);
+#endif
+ TQFont::Script script = TQFont::NoScript;
+ TQScriptItem item;
+ item.position = start;
+ item.analysis.script = script;
+ item.analysis.bidiLevel = level;
+ item.analysis.override = control.override();
+ item.analysis.reserved = 0;
+
+ if ( control.singleLine ) {
+ for ( int i = start; i <= stop; i++ ) {
+
+ unsigned short uc = text[i].tqunicode();
+ TQFont::Script s = (TQFont::Script)scriptForChar( uc );
+ if (s == TQFont::UnknownScript || s == TQFont::CombiningMarks)
+ s = script;
+
+ if (s != script) {
+ item.analysis.script = s;
+ item.analysis.bidiLevel = level;
+ item.position = i;
+ items.append( item );
+ script = s;
+ }
+ }
+ } else {
+ for ( int i = start; i <= stop; i++ ) {
+
+ unsigned short uc = text[i].tqunicode();
+ TQFont::Script s = (TQFont::Script)scriptForChar( uc );
+ if (s == TQFont::UnknownScript || s == TQFont::CombiningMarks)
+ s = script;
+
+ TQChar::Category category = ::category( uc );
+ if ( uc == 0xfffcU || uc == 0x2028U ) {
+ item.analysis.bidiLevel = level % 2 ? level-1 : level;
+ item.analysis.script = TQFont::Latin;
+ item.isObject = TRUE;
+ s = TQFont::NoScript;
+ } else if ((uc >= 9 && uc <=13) ||
+ (category >= TQChar::Separator_Space && category <= TQChar::Separator_Paragraph)) {
+ item.analysis.script = TQFont::Latin;
+ item.isSpace = TRUE;
+ item.isTab = ( uc == '\t' );
+ item.analysis.bidiLevel = item.isTab ? control.baseLevel() : level;
+ s = TQFont::NoScript;
+ } else if ( s != script && (category != TQChar::Mark_NonSpacing || script == TQFont::NoScript)) {
+ item.analysis.script = s;
+ item.analysis.bidiLevel = level;
+ } else {
+ if (i - start < 32000)
+ continue;
+ start = i;
+ }
+
+ item.position = i;
+ items.append( item );
+ script = s;
+ item.isSpace = item.isTab = item.isObject = FALSE;
+ }
+ }
+ ++stop;
+ start = stop;
+}
+
+typedef void (* fAppendItems)(TQTextEngine *, int &start, int &stop, BidiControl &control, TQChar::Direction dir);
+static fAppendItems appendItems = tqAppendItems;
+
+// creates the next TQScript items.
+static void bidiItemize( TQTextEngine *engine, bool rightToLeft, int mode )
+{
+ BidiControl control( rightToLeft );
+ if ( mode & TQTextEngine::SingleLine )
+ control.singleLine = TRUE;
+
+ int sor = 0;
+ int eor = -1;
+
+ // ### should get rid of this!
+ bool first = TRUE;
+
+ int length = engine->string.length();
+
+ if ( !length )
+ return;
+
+ const TQChar *tqunicode = engine->string.tqunicode();
+ int current = 0;
+
+ TQChar::Direction dir = rightToLeft ? TQChar::DirR : TQChar::DirL;
+ BiditqStatus status;
+ TQChar::Direction sdir = direction( *tqunicode );
+ if ( sdir != TQChar::DirL && sdir != TQChar::DirR && sdir != TQChar::DirAL && sdir != TQChar::DirEN && sdir != TQChar::DirAN )
+ sdir = TQChar::DirON;
+ else
+ dir = TQChar::DirON;
+ status.eor = sdir;
+ status.lastStrong = rightToLeft ? TQChar::DirR : TQChar::DirL;
+ status.last = status.lastStrong;
+ status.dir = sdir;
+#if (BIDI_DEBUG >= 2)
+ qDebug("---- bidiReorder --- '%s'", engine->string.utf8().data());
+ qDebug("rightToLeft = %d", rightToLeft);
+#endif
+
+
+ while ( current <= length ) {
+
+ TQChar::Direction dirCurrent;
+ if ( current == (int)length )
+ dirCurrent = control.basicDirection();
+ else
+ dirCurrent = direction( tqunicode[current] );
+
+#if (BIDI_DEBUG >= 2)
+ cout << "pos=" << current << " dir=" << directions[dir]
+ << " current=" << directions[dirCurrent] << " last=" << directions[status.last]
+ << " eor=" << eor << "/" << directions[status.eor]
+ << " sor=" << sor << " lastStrong="
+ << directions[status.lastStrong]
+ << " level=" << (int)control.level() << endl;
+#endif
+
+ switch(dirCurrent) {
+
+ // embedding and overrides (X1-X9 in the BiDi specs)
+ case TQChar::DirRLE:
+ case TQChar::DirRLO:
+ case TQChar::DirLRE:
+ case TQChar::DirLRO:
+ {
+ bool rtl = (dirCurrent == TQChar::DirRLE || dirCurrent == TQChar::DirRLO );
+ bool override = (dirCurrent == TQChar::DirLRO || dirCurrent == TQChar::DirRLO );
+
+ uchar level = control.level();
+ if( (level%2 != 0) == rtl )
+ level += 2;
+ else
+ level++;
+ if(level < 61) {
+ eor = current-1;
+ appendItems(engine, sor, eor, control, dir);
+ eor = current;
+ control.embed( level, override );
+ TQChar::Direction edir = (rtl ? TQChar::DirR : TQChar::DirL );
+ dir = status.eor = edir;
+ status.lastStrong = edir;
+ }
+ break;
+ }
+ case TQChar::DirPDF:
+ {
+ if (dir != control.direction()) {
+ eor = current-1;
+ appendItems(engine, sor, eor, control, dir);
+ dir = control.direction();
+ }
+ eor = current;
+ appendItems(engine, sor, eor, control, dir);
+ dir = TQChar::DirON; status.eor = TQChar::DirON;
+ status.last = control.direction();
+ control.pdf();
+ if ( control.override() )
+ dir = control.direction();
+ else
+ dir = TQChar::DirON;
+ status.lastStrong = control.direction();
+ break;
+ }
+
+ // strong types
+ case TQChar::DirL:
+ if(dir == TQChar::DirON)
+ dir = TQChar::DirL;
+ switch(status.last)
+ {
+ case TQChar::DirL:
+ eor = current; status.eor = TQChar::DirL; break;
+ case TQChar::DirR:
+ case TQChar::DirAL:
+ case TQChar::DirEN:
+ case TQChar::DirAN:
+ if ( !first ) {
+ appendItems(engine, sor, eor, control, dir);
+ dir = eor < length ? direction( tqunicode[eor] ) : control.basicDirection();
+ status.eor = dir;
+ } else {
+ eor = current; status.eor = dir;
+ }
+ break;
+ case TQChar::DirES:
+ case TQChar::DirET:
+ case TQChar::DirCS:
+ case TQChar::DirBN:
+ case TQChar::DirB:
+ case TQChar::DirS:
+ case TQChar::DirWS:
+ case TQChar::DirON:
+ if(dir != TQChar::DirL) {
+ //last stuff takes embedding dir
+ if( control.direction() == TQChar::DirR ) {
+ if(status.eor != TQChar::DirR) {
+ // AN or EN
+ appendItems(engine, sor, eor, control, dir);
+ status.eor = TQChar::DirON;
+ dir = TQChar::DirR;
+ }
+ eor = current - 1;
+ appendItems(engine, sor, eor, control, dir);
+ dir = eor < length ? direction( tqunicode[eor] ) : control.basicDirection();
+ status.eor = dir;
+ } else {
+ if(status.eor != TQChar::DirL) {
+ appendItems(engine, sor, eor, control, dir);
+ status.eor = TQChar::DirON;
+ dir = TQChar::DirL;
+ } else {
+ eor = current; status.eor = TQChar::DirL; break;
+ }
+ }
+ } else {
+ eor = current; status.eor = TQChar::DirL;
+ }
+ default:
+ break;
+ }
+ status.lastStrong = TQChar::DirL;
+ break;
+ case TQChar::DirAL:
+ case TQChar::DirR:
+ if(dir == TQChar::DirON) dir = TQChar::DirR;
+ switch(status.last)
+ {
+ case TQChar::DirL:
+ case TQChar::DirEN:
+ case TQChar::DirAN:
+ if ( !first ) {
+ appendItems(engine, sor, eor, control, dir);
+ dir = TQChar::DirON; status.eor = TQChar::DirON;
+ break;
+ }
+ case TQChar::DirR:
+ case TQChar::DirAL:
+ eor = current; status.eor = TQChar::DirR; break;
+ case TQChar::DirES:
+ case TQChar::DirET:
+ case TQChar::DirCS:
+ case TQChar::DirBN:
+ case TQChar::DirB:
+ case TQChar::DirS:
+ case TQChar::DirWS:
+ case TQChar::DirON:
+ if( status.eor != TQChar::DirR && status.eor != TQChar::DirAL ) {
+ //last stuff takes embedding dir
+ if(control.direction() == TQChar::DirR
+ || status.lastStrong == TQChar::DirR || status.lastStrong == TQChar::DirAL) {
+ appendItems(engine, sor, eor, control, dir);
+ dir = TQChar::DirON; status.eor = TQChar::DirON;
+ dir = TQChar::DirR;
+ eor = current;
+ } else {
+ eor = current - 1;
+ appendItems(engine, sor, eor, control, dir);
+ dir = TQChar::DirON; status.eor = TQChar::DirON;
+ dir = TQChar::DirR;
+ }
+ } else {
+ eor = current; status.eor = TQChar::DirR;
+ }
+ default:
+ break;
+ }
+ status.lastStrong = dirCurrent;
+ break;
+
+ // weak types:
+
+ case TQChar::DirNSM:
+ if (eor == current-1)
+ eor = current;
+ break;
+ case TQChar::DirEN:
+ // if last strong was AL change EN to AN
+ if(status.lastStrong != TQChar::DirAL) {
+ if(dir == TQChar::DirON) {
+ if(status.lastStrong == TQChar::DirL)
+ dir = TQChar::DirL;
+ else
+ dir = TQChar::DirEN;
+ }
+ switch(status.last)
+ {
+ case TQChar::DirET:
+ if ( status.lastStrong == TQChar::DirR || status.lastStrong == TQChar::DirAL ) {
+ appendItems(engine, sor, eor, control, dir);
+ status.eor = TQChar::DirON;
+ dir = TQChar::DirAN;
+ }
+ // fall through
+ case TQChar::DirEN:
+ case TQChar::DirL:
+ eor = current;
+ status.eor = dirCurrent;
+ break;
+ case TQChar::DirR:
+ case TQChar::DirAL:
+ case TQChar::DirAN:
+ if ( !first )
+ appendItems(engine, sor, eor, control, dir);
+ status.eor = TQChar::DirEN;
+ dir = TQChar::DirAN; break;
+ case TQChar::DirES:
+ case TQChar::DirCS:
+ if(status.eor == TQChar::DirEN || dir == TQChar::DirAN) {
+ eor = current; break;
+ }
+ case TQChar::DirBN:
+ case TQChar::DirB:
+ case TQChar::DirS:
+ case TQChar::DirWS:
+ case TQChar::DirON:
+ if(status.eor == TQChar::DirR) {
+ // neutrals go to R
+ eor = current - 1;
+ appendItems(engine, sor, eor, control, dir);
+ dir = TQChar::DirON; status.eor = TQChar::DirEN;
+ dir = TQChar::DirAN;
+ }
+ else if( status.eor == TQChar::DirL ||
+ (status.eor == TQChar::DirEN && status.lastStrong == TQChar::DirL)) {
+ eor = current; status.eor = dirCurrent;
+ } else {
+ // numbers on both sides, neutrals get right to left direction
+ if(dir != TQChar::DirL) {
+ appendItems(engine, sor, eor, control, dir);
+ dir = TQChar::DirON; status.eor = TQChar::DirON;
+ eor = current - 1;
+ dir = TQChar::DirR;
+ appendItems(engine, sor, eor, control, dir);
+ dir = TQChar::DirON; status.eor = TQChar::DirON;
+ dir = TQChar::DirAN;
+ } else {
+ eor = current; status.eor = dirCurrent;
+ }
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ case TQChar::DirAN:
+ dirCurrent = TQChar::DirAN;
+ if(dir == TQChar::DirON) dir = TQChar::DirAN;
+ switch(status.last)
+ {
+ case TQChar::DirL:
+ case TQChar::DirAN:
+ eor = current; status.eor = TQChar::DirAN; break;
+ case TQChar::DirR:
+ case TQChar::DirAL:
+ case TQChar::DirEN:
+ if ( !first )
+ appendItems(engine, sor, eor, control, dir);
+ dir = TQChar::DirON; status.eor = TQChar::DirAN;
+ break;
+ case TQChar::DirCS:
+ if(status.eor == TQChar::DirAN) {
+ eor = current; break;
+ }
+ case TQChar::DirES:
+ case TQChar::DirET:
+ case TQChar::DirBN:
+ case TQChar::DirB:
+ case TQChar::DirS:
+ case TQChar::DirWS:
+ case TQChar::DirON:
+ if(status.eor == TQChar::DirR) {
+ // neutrals go to R
+ eor = current - 1;
+ appendItems(engine, sor, eor, control, dir);
+ status.eor = TQChar::DirAN;
+ dir = TQChar::DirAN;
+ } else if( status.eor == TQChar::DirL ||
+ (status.eor == TQChar::DirEN && status.lastStrong == TQChar::DirL)) {
+ eor = current; status.eor = dirCurrent;
+ } else {
+ // numbers on both sides, neutrals get right to left direction
+ if(dir != TQChar::DirL) {
+ appendItems(engine, sor, eor, control, dir);
+ status.eor = TQChar::DirON;
+ eor = current - 1;
+ dir = TQChar::DirR;
+ appendItems(engine, sor, eor, control, dir);
+ status.eor = TQChar::DirAN;
+ dir = TQChar::DirAN;
+ } else {
+ eor = current; status.eor = dirCurrent;
+ }
+ }
+ default:
+ break;
+ }
+ break;
+ case TQChar::DirES:
+ case TQChar::DirCS:
+ break;
+ case TQChar::DirET:
+ if(status.last == TQChar::DirEN) {
+ dirCurrent = TQChar::DirEN;
+ eor = current; status.eor = dirCurrent;
+ }
+ break;
+
+ // boundary neutrals should be ignored
+ case TQChar::DirBN:
+ break;
+ // neutrals
+ case TQChar::DirB:
+ // ### what do we do with newline and paragraph separators that come to here?
+ break;
+ case TQChar::DirS:
+ // ### implement rule L1
+ break;
+ case TQChar::DirWS:
+ case TQChar::DirON:
+ break;
+ default:
+ break;
+ }
+
+ //cout << " after: dir=" << // dir << " current=" << dirCurrent << " last=" << status.last << " eor=" << status.eor << " lastStrong=" << status.lastStrong << " embedding=" << control.direction() << endl;
+
+ if(current >= (int)length) break;
+
+ // set status.last as needed.
+ switch(dirCurrent) {
+ case TQChar::DirET:
+ case TQChar::DirES:
+ case TQChar::DirCS:
+ case TQChar::DirS:
+ case TQChar::DirWS:
+ case TQChar::DirON:
+ switch(status.last)
+ {
+ case TQChar::DirL:
+ case TQChar::DirR:
+ case TQChar::DirAL:
+ case TQChar::DirEN:
+ case TQChar::DirAN:
+ status.last = dirCurrent;
+ break;
+ default:
+ status.last = TQChar::DirON;
+ }
+ break;
+ case TQChar::DirNSM:
+ case TQChar::DirBN:
+ // ignore these
+ break;
+ case TQChar::DirLRO:
+ case TQChar::DirLRE:
+ status.last = TQChar::DirL;
+ break;
+ case TQChar::DirRLO:
+ case TQChar::DirRLE:
+ status.last = TQChar::DirR;
+ break;
+ case TQChar::DirEN:
+ if ( status.last == TQChar::DirL ) {
+ status.last = TQChar::DirL;
+ break;
+ }
+ // fall through
+ default:
+ status.last = dirCurrent;
+ }
+
+ first = FALSE;
+ ++current;
+ }
+
+#if (BIDI_DEBUG >= 1)
+ cout << "reached end of line current=" << current << ", eor=" << eor << endl;
+#endif
+ eor = current - 1; // remove dummy char
+
+ if ( sor <= eor )
+ appendItems(engine, sor, eor, control, dir);
+
+
+}
+
+void TQTextEngine::bidiReorder( int numItems, const TQ_UINT8 *levels, int *visualOrder )
+{
+
+ // first tqfind highest and lowest levels
+ uchar levelLow = 128;
+ uchar levelHigh = 0;
+ int i = 0;
+ while ( i < numItems ) {
+ //printf("level = %d\n", r->level);
+ if ( levels[i] > levelHigh )
+ levelHigh = levels[i];
+ if ( levels[i] < levelLow )
+ levelLow = levels[i];
+ i++;
+ }
+
+ // implements reordering of the line (L2 according to BiDi spec):
+ // L2. From the highest level found in the text to the lowest odd level on each line,
+ // reverse any contiguous sequence of characters that are at that level or higher.
+
+ // reversing is only done up to the lowest odd level
+ if(!(levelLow%2)) levelLow++;
+
+#if (BIDI_DEBUG >= 1)
+ cout << "reorderLine: lineLow = " << (uint)levelLow << ", lineHigh = " << (uint)levelHigh << endl;
+#endif
+
+ int count = numItems - 1;
+ for ( i = 0; i < numItems; i++ )
+ visualOrder[i] = i;
+
+ while(levelHigh >= levelLow) {
+ int i = 0;
+ while ( i < count ) {
+ while(i < count && levels[i] < levelHigh) i++;
+ int start = i;
+ while(i <= count && levels[i] >= levelHigh) i++;
+ int end = i-1;
+
+ if(start != end) {
+ //cout << "reversing from " << start << " to " << end << endl;
+ for(int j = 0; j < (end-start+1)/2; j++) {
+ int tmp = visualOrder[start+j];
+ visualOrder[start+j] = visualOrder[end-j];
+ visualOrder[end-j] = tmp;
+ }
+ }
+ i++;
+ }
+ levelHigh--;
+ }
+
+#if (BIDI_DEBUG >= 1)
+ cout << "visual order is:" << endl;
+ for ( i = 0; i < numItems; i++ )
+ cout << visualOrder[i] << endl;
+#endif
+}
+
+
+// -----------------------------------------------------------------------------------------------------
+//
+// The line break algorithm. See http://www.tqunicode.org/reports/tr14/tr14-13.html
+//
+// -----------------------------------------------------------------------------------------------------
+
+/* The Unicode algorithm does in our opinion allow line breaks at some
+ places they shouldn't be allowed. The following changes were thus
+ made in comparison to the Unicode reference:
+
+ CL->AL from Dbk to Ibk
+ CL->PR from Dbk to Ibk
+ EX->AL from Dbk to Ibk
+ IS->AL from Dbk to Ibk
+ PO->AL from Dbk to Ibk
+ SY->AL from Dbk to Ibk
+ SY->PO from Dbk to Ibk
+ SY->PR from Dbk to Ibk
+ SY->OP from Dbk to Ibk
+ Al->OP from Dbk to Ibk
+ AL->HY from Dbk to Ibk
+ AL->PR from Dbk to Ibk
+ AL->PO from Dbk to Ibk
+ PR->PR from Dbk to Ibk
+ PO->PO from Dbk to Ibk
+ PR->PO from Dbk to Ibk
+ PO->PR from Dbk to Ibk
+ HY->PO from Dbk to Ibk
+ HY->PR from Dbk to Ibk
+ HY->OP from Dbk to Ibk
+ PO->OP from Dbk to Ibk
+ NU->EX from Dbk to Ibk
+ NU->PR from Dbk to Ibk
+ PO->NU from Dbk to Ibk
+ EX->PO from Dbk to Ibk
+*/
+
+enum break_action {
+ Dbk, // Direct break
+ Ibk, // Indirect break; only allowed if space between the two chars
+ Pbk // Prohibited break; no break allowed even if space between chars
+};
+
+// The following line break classes are not treated by the table:
+// SA, BK, CR, LF, SG, CB, SP
+static const TQ_UINT8 breakTable[TQUnicodeTables::LineBreak_CM+1][TQUnicodeTables::LineBreak_CM+1] =
+{
+ // OP, CL, QU, GL, NS, EX, SY, IS, PR, PO, NU, AL, ID, IN, HY, BA, BB, B2, ZW, CM
+ { Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk, Pbk }, // OP
+ { Dbk, Pbk, Ibk, Pbk, Pbk, Pbk, Pbk, Pbk, Ibk, Ibk, Dbk, Ibk, Dbk, Dbk, Ibk, Ibk, Pbk, Pbk, Pbk, Pbk }, // CL
+ { Pbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Pbk, Pbk }, // QU
+ { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Pbk, Pbk }, // GL
+ { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // NS
+ { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // EX
+ { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // SY
+ { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // IS
+ { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }, // PR
+ { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // PO
+ { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }, // NU
+ { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk }, // AL
+ { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Ibk, Dbk, Dbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // ID
+ { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // IN
+ { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // HY
+ { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Dbk, Dbk, Pbk, Ibk }, // BA
+ { Ibk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Ibk, Pbk, Ibk }, // BB
+ { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Ibk, Ibk, Dbk, Pbk, Pbk, Ibk }, // B2
+ { Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Dbk, Pbk, Ibk }, // ZW
+ { Dbk, Pbk, Ibk, Pbk, Ibk, Pbk, Pbk, Pbk, Dbk, Ibk, Dbk, Dbk, Dbk, Ibk, Ibk, Ibk, Dbk, Dbk, Pbk, Pbk } // CM
+};
+
+// set the soft break flag at every possible line breaking point. This needs correct clustering information.
+static void calcLineBreaks(const TQString &str, TQCharAttributes *charAttributes)
+{
+ int len = str.length();
+ if (!len)
+ return;
+
+ const TQChar *uc = str.tqunicode();
+ int cls = lineBreakClass(*uc);
+ if (cls >= TQUnicodeTables::LineBreak_CM)
+ cls = TQUnicodeTables::LineBreak_ID;
+
+ charAttributes[0].softBreak = FALSE;
+ charAttributes[0].whiteSpace = (cls == TQUnicodeTables::LineBreak_SP);
+ charAttributes[0].charStop = TRUE;
+
+ for (int i = 1; i < len; ++i) {
+ int ncls = ::lineBreakClass(uc[i]);
+ int category = ::category(uc[i]);
+ if (category == TQChar::Mark_NonSpacing)
+ goto nsm;
+
+ if (category == TQChar::Other_Surrogate) {
+ // char stop only on first pair
+ if (uc[i].tqunicode() >= 0xd800 && uc[i].tqunicode() < 0xdc00 && i < len-1
+ && uc[i+1].tqunicode() >= 0xdc00 && uc[i+1].tqunicode() < 0xe000)
+ goto nsm;
+ // ### correctly handle second surrogate
+ }
+
+ if (ncls == TQUnicodeTables::LineBreak_SP) {
+ charAttributes[i].softBreak = FALSE;
+ charAttributes[i].whiteSpace = TRUE;
+ charAttributes[i].charStop = TRUE;
+ cls = ncls;
+ continue;
+ }
+
+
+ if (cls == TQUnicodeTables::LineBreak_SA && ncls == TQUnicodeTables::LineBreak_SA) {
+ // two complex chars (thai or lao), thai_attributes might override, but here
+ // we do a best guess
+ charAttributes[i].softBreak = TRUE;
+ charAttributes[i].whiteSpace = FALSE;
+ charAttributes[i].charStop = TRUE;
+ cls = ncls;
+ continue;
+ }
+ {
+ int tcls = ncls;
+ if (tcls >= TQUnicodeTables::LineBreak_SA)
+ tcls = TQUnicodeTables::LineBreak_ID;
+ if (cls >= TQUnicodeTables::LineBreak_SA)
+ cls = TQUnicodeTables::LineBreak_ID;
+
+ bool softBreak;
+ int brk = breakTable[cls][tcls];
+ if (brk == Ibk)
+ softBreak = (cls == TQUnicodeTables::LineBreak_SP);
+ else
+ softBreak = (brk == Dbk);
+// qDebug("char = %c %04x, cls=%d, ncls=%d, brk=%d soft=%d", uc[i].cell(), uc[i].tqunicode(), cls, ncls, brk, charAttributes[i].softBreak);
+ charAttributes[i].softBreak = softBreak;
+ charAttributes[i].whiteSpace = FALSE;
+ charAttributes[i].charStop = TRUE;
+ cls = ncls;
+ }
+ continue;
+ nsm:
+ charAttributes[i].softBreak = FALSE;
+ charAttributes[i].whiteSpace = FALSE;
+ charAttributes[i].charStop = FALSE;
+ }
+}
+
+#if defined( TQ_WS_X11 ) || defined ( TQ_WS_TQWS )
+# include "tqtextengine_unix.cpp"
+#elif defined( TQ_WS_WIN )
+# include "tqtextengine_win.cpp"
+#elif defined( TQ_WS_MAC )
+# include "tqtextengine_mac.cpp"
+#endif
+
+
+
+TQTextEngine::TQTextEngine( const TQString &str, TQFontPrivate *f )
+ : string( str ), fnt( f ), direction( TQChar::DirON ), haveCharAttributes( FALSE ), widthOnly( FALSE )
+{
+#ifdef TQ_WS_WIN
+ if ( !resolvedUsp10 )
+ resolveUsp10();
+#endif
+ if ( fnt ) fnt->ref();
+
+ num_glyphs = TQMAX( 16, str.length()*3/2 );
+ int space_charAttributes = (sizeof(TQCharAttributes)*str.length()+sizeof(void*)-1)/sizeof(void*);
+ int space_logClusters = (sizeof(unsigned short)*str.length()+sizeof(void*)-1)/sizeof(void*);
+ int space_glyphs = (sizeof(glyph_t)*num_glyphs+sizeof(void*)-1)/sizeof(void*);
+ int space_advances = (sizeof(advance_t)*num_glyphs+sizeof(void*)-1)/sizeof(void*);
+ int space_offsets = (sizeof(qoffset_t)*num_glyphs+sizeof(void*)-1)/sizeof(void*);
+ int space_glyphAttributes = (sizeof(GlyphAttributes)*num_glyphs+sizeof(void*)-1)/sizeof(void*);
+
+ allocated = space_charAttributes + space_glyphs + space_advances +
+ space_offsets + space_logClusters + space_glyphAttributes;
+ memory = (void **)::malloc( allocated*sizeof( void * ) );
+ memset( memory, 0, allocated*sizeof( void * ) );
+
+ void **m = memory;
+ m += space_charAttributes;
+ logClustersPtr = (unsigned short *) m;
+ m += space_logClusters;
+ glyphPtr = (glyph_t *) m;
+ m += space_glyphs;
+ advancePtr = (advance_t *) m;
+ m += space_advances;
+ offsetsPtr = (qoffset_t *) m;
+ m += space_offsets;
+ glyphAttributesPtr = (GlyphAttributes *) m;
+
+ used = 0;
+}
+
+TQTextEngine::~TQTextEngine()
+{
+ if ( fnt && fnt->deref())
+ delete fnt;
+ free( memory );
+ allocated = 0;
+}
+
+void TQTextEngine::reallocate( int totalGlyphs )
+{
+ int new_num_glyphs = totalGlyphs;
+ int space_charAttributes = (sizeof(TQCharAttributes)*string.length()+sizeof(void*)-1)/sizeof(void*);
+ int space_logClusters = (sizeof(unsigned short)*string.length()+sizeof(void*)-1)/sizeof(void*);
+ int space_glyphs = (sizeof(glyph_t)*new_num_glyphs+sizeof(void*)-1)/sizeof(void*);
+ int space_advances = (sizeof(advance_t)*new_num_glyphs+sizeof(void*)-1)/sizeof(void*);
+ int space_offsets = (sizeof(qoffset_t)*new_num_glyphs+sizeof(void*)-1)/sizeof(void*);
+ int space_glyphAttributes = (sizeof(GlyphAttributes)*new_num_glyphs+sizeof(void*)-1)/sizeof(void*);
+
+ int newAllocated = space_charAttributes + space_glyphs + space_advances +
+ space_offsets + space_logClusters + space_glyphAttributes;
+ void ** newMemory = (void **)::malloc( newAllocated*sizeof( void * ) );
+
+ void **nm = newMemory;
+ memcpy( nm, memory, string.length()*sizeof(TQCharAttributes) );
+ nm += space_charAttributes;
+ memcpy( nm, logClustersPtr, num_glyphs*sizeof(unsigned short) );
+ logClustersPtr = (unsigned short *) nm;
+ nm += space_logClusters;
+ memcpy( nm, glyphPtr, num_glyphs*sizeof(glyph_t) );
+ glyphPtr = (glyph_t *) nm;
+ nm += space_glyphs;
+ memcpy( nm, advancePtr, num_glyphs*sizeof(advance_t) );
+ advancePtr = (advance_t *) nm;
+ nm += space_advances;
+ memcpy( nm, offsetsPtr, num_glyphs*sizeof(qoffset_t) );
+ offsetsPtr = (qoffset_t *) nm;
+ nm += space_offsets;
+ memcpy( nm, glyphAttributesPtr, num_glyphs*sizeof(GlyphAttributes) );
+ glyphAttributesPtr = (GlyphAttributes *) nm;
+
+ free( memory );
+ memory = newMemory;
+ allocated = newAllocated;
+ num_glyphs = new_num_glyphs;
+}
+
+const TQCharAttributes *TQTextEngine::attributes()
+{
+ TQCharAttributes *charAttributes = (TQCharAttributes *) memory;
+ if ( haveCharAttributes )
+ return charAttributes;
+
+ if ( !items.d )
+ itemize();
+
+ ensureSpace(string.length());
+ charAttributes = (TQCharAttributes *) memory;
+ calcLineBreaks(string, charAttributes);
+
+ for ( int i = 0; i < items.size(); i++ ) {
+ TQScriptItem &si = items[i];
+#ifdef TQ_WS_WIN
+ int script = uspScriptForItem(this, i);
+#else
+ int script = si.analysis.script;
+#endif
+ TQ_ASSERT( script < TQFont::NScripts );
+ AttributeFunction attributes = scriptEngines[script].charAttributes;
+ if (!attributes)
+ continue;
+ int from = si.position;
+ int len = length( i );
+ attributes( script, string, from, len, charAttributes );
+ }
+
+ haveCharAttributes = TRUE;
+ return charAttributes;
+}
+
+void TQTextEngine::splitItem( int item, int pos )
+{
+ if ( pos <= 0 )
+ return;
+
+ // we have to ensure we get correct shaping for arabic and other
+ // complex languages so we have to call tqshape _before_ we split the item.
+ tqshape(item);
+
+ if ( items.d->size == items.d->alloc )
+ items.resize( items.d->size + 1 );
+
+ int numMove = items.d->size - item-1;
+ if ( numMove > 0 )
+ memmove( items.d->items + item+2, items.d->items +item+1, numMove*sizeof( TQScriptItem ) );
+ items.d->size++;
+ TQScriptItem &newItem = items.d->items[item+1];
+ TQScriptItem &oldItem = items.d->items[item];
+ newItem = oldItem;
+ items.d->items[item+1].position += pos;
+ if ( newItem.fontEngine )
+ newItem.fontEngine->ref();
+
+ if (oldItem.num_glyphs) {
+ // already tqshaped, break glyphs aswell
+ int breakGlyph = logClusters(&oldItem)[pos];
+
+ newItem.num_glyphs = oldItem.num_glyphs - breakGlyph;
+ oldItem.num_glyphs = breakGlyph;
+ newItem.glyph_data_offset = oldItem.glyph_data_offset + breakGlyph;
+
+ for (int i = 0; i < newItem.num_glyphs; i++)
+ logClusters(&newItem)[i] -= breakGlyph;
+
+ int w = 0;
+ const advance_t *a = advances(&oldItem);
+ for(int j = 0; j < breakGlyph; ++j)
+ w += *(a++);
+
+ newItem.width = oldItem.width - w;
+ oldItem.width = w;
+ }
+
+// qDebug("split at position %d itempos=%d", pos, item );
+}
+
+
+int TQTextEngine::width( int from, int len ) const
+{
+ int w = 0;
+
+// qDebug("TQTextEngine::width( from = %d, len = %d ), numItems=%d, strleng=%d", from, len, items.size(), string.length() );
+ for ( int i = 0; i < items.size(); i++ ) {
+ TQScriptItem *si = &items[i];
+ int pos = si->position;
+ int ilen = length( i );
+// qDebug("item %d: from %d len %d", i, pos, ilen );
+ if ( pos >= from + len )
+ break;
+ if ( pos + ilen > from ) {
+ if ( !si->num_glyphs )
+ tqshape( i );
+
+ advance_t *advances = this->advances( si );
+ unsigned short *logClusters = this->logClusters( si );
+
+// fprintf( stderr, " logclusters:" );
+// for ( int k = 0; k < ilen; k++ )
+// fprintf( stderr, " %d", logClusters[k] );
+// fprintf( stderr, "\n" );
+ // do the simple thing for now and give the first glyph in a cluster the full width, all other ones 0.
+ int charFrom = from - pos;
+ if ( charFrom < 0 )
+ charFrom = 0;
+ int glyphStart = logClusters[charFrom];
+ if ( charFrom > 0 && logClusters[charFrom-1] == glyphStart )
+ while ( charFrom < ilen && logClusters[charFrom] == glyphStart )
+ charFrom++;
+ if ( charFrom < ilen ) {
+ glyphStart = logClusters[charFrom];
+ int charEnd = from + len - 1 - pos;
+ if ( charEnd >= ilen )
+ charEnd = ilen-1;
+ int glyphEnd = logClusters[charEnd];
+ while ( charEnd < ilen && logClusters[charEnd] == glyphEnd )
+ charEnd++;
+ glyphEnd = (charEnd == ilen) ? si->num_glyphs : logClusters[charEnd];
+
+// qDebug("char: start=%d end=%d / glyph: start = %d, end = %d", charFrom, charEnd, glyphStart, glyphEnd );
+ for ( int i = glyphStart; i < glyphEnd; i++ )
+ w += advances[i];
+ }
+ }
+ }
+// qDebug(" --> w= %d ", w );
+ return w;
+}
+
+void TQTextEngine::itemize( int mode )
+{
+ if ( !items.d ) {
+ int size = 8;
+ items.d = (TQScriptItemArrayPrivate *)malloc( sizeof( TQScriptItemArrayPrivate ) +
+ sizeof( TQScriptItem ) * size );
+ items.d->alloc = size;
+ }
+ items.d->size = 0;
+ if ( string.length() == 0 )
+ return;
+
+ if ( !(mode & NoBidi) ) {
+ if ( direction == TQChar::DirON )
+ direction = basicDirection( string );
+ bidiItemize( this, direction == TQChar::DirR, mode );
+ } else {
+ BidiControl control( FALSE );
+ if ( mode & TQTextEngine::SingleLine )
+ control.singleLine = TRUE;
+ int start = 0;
+ int stop = string.length() - 1;
+ appendItems(this, start, stop, control, TQChar::DirL);
+ }
+ if ( (mode & WidthOnly) == WidthOnly )
+ widthOnly = TRUE;
+}
+
+glyph_metrics_t TQTextEngine::boundingBox( int from, int len ) const
+{
+ glyph_metrics_t gm;
+
+ for ( int i = 0; i < items.size(); i++ ) {
+ TQScriptItem *si = &items[i];
+ int pos = si->position;
+ int ilen = length( i );
+ if ( pos > from + len )
+ break;
+ if ( pos + len > from ) {
+ if ( !si->num_glyphs )
+ tqshape( i );
+ advance_t *advances = this->advances( si );
+ unsigned short *logClusters = this->logClusters( si );
+ glyph_t *glyphs = this->glyphs( si );
+ qoffset_t *offsets = this->offsets( si );
+
+ // do the simple thing for now and give the first glyph in a cluster the full width, all other ones 0.
+ int charFrom = from - pos;
+ if ( charFrom < 0 )
+ charFrom = 0;
+ int glyphStart = logClusters[charFrom];
+ if ( charFrom > 0 && logClusters[charFrom-1] == glyphStart )
+ while ( charFrom < ilen && logClusters[charFrom] == glyphStart )
+ charFrom++;
+ if ( charFrom < ilen ) {
+ glyphStart = logClusters[charFrom];
+ int charEnd = from + len - 1 - pos;
+ if ( charEnd >= ilen )
+ charEnd = ilen-1;
+ int glyphEnd = logClusters[charEnd];
+ while ( charEnd < ilen && logClusters[charEnd] == glyphEnd )
+ charEnd++;
+ glyphEnd = (charEnd == ilen) ? si->num_glyphs : logClusters[charEnd];
+ if ( glyphStart <= glyphEnd ) {
+ TQFontEngine *fe = si->fontEngine;
+ glyph_metrics_t m = fe->boundingBox( glyphs+glyphStart, advances+glyphStart,
+ offsets+glyphStart, glyphEnd-glyphStart );
+ gm.x = TQMIN( gm.x, m.x + gm.xoff );
+ gm.y = TQMIN( gm.y, m.y + gm.yoff );
+ gm.width = TQMAX( gm.width, m.width+gm.xoff );
+ gm.height = TQMAX( gm.height, m.height+gm.yoff );
+ gm.xoff += m.xoff;
+ gm.yoff += m.yoff;
+ }
+ }
+ }
+ }
+ return gm;
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqtextengine_p.h b/tqtinterface/qt4/src/kernel/tqtextengine_p.h
new file mode 100644
index 0000000..dcdbbba
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtextengine_p.h
@@ -0,0 +1,467 @@
+/****************************************************************************
+**
+** ???
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTEXTENGINE_P_H
+#define TQTEXTENGINE_P_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqstring.h"
+#include "tqnamespace.h"
+#include <private/tqfontdata_p.h>
+#endif // TQT_H
+
+#include <stdlib.h>
+#ifndef TQ_OS_TEMP
+#include <assert.h>
+#endif // TQ_OS_TEMP
+
+#ifdef USE_QT4
+
+// #include <private/qt4_qtextengine_p.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+// class TQTextEngine : public QTextEngine {
+// public:
+// TQTextEngine( const TQString &str, TQFontPrivate *f ) : QTextEngine(str, convertToQFont(f)) {}
+//
+// enum Mode {
+// Full = 0x00,
+// NoBidi = 0x01,
+// SingleLine = 0x02,
+// WidthOnly = 0x07
+// };
+//
+// enum Edge {
+// Leading,
+// Trailing
+// };
+// enum ShaperFlag {
+// RightToLeft = 0x0001,
+// Mirrored = 0x0001
+// };
+// //
+// // // Interoperability
+// // QFont convertToQFont( TQFontPrivate *f );
+// };
+//
+// // Interoperability
+// inline QFont convertToQFont( TQFontPrivate *f ) {
+// QFont qf;
+// // Copy over every single #!$% parameter from the TQFontPrivate object [FIXME]
+// QFont qft(qf, f->painttqdevice);
+// return qft;
+// }
+//
+// struct TQScriptAnalysis
+// {
+// unsigned short script : 7;
+// unsigned short bidiLevel : 6; // Unicode Bidi algorithm embedding level (0-61)
+// unsigned short override : 1; // Set when in LRO/RLO embedding
+// unsigned short reserved : 2;
+// bool operator == ( const TQScriptAnalysis &other ) {
+// return
+// script == other.script &&
+// bidiLevel == other.bidiLevel;
+// // ###
+// // && override == other.override;
+// }
+//
+// };
+//
+// class TQFontEngine;
+//
+// struct TQScriptItem
+// {
+// inline TQScriptItem() : position( 0 ), isSpace( FALSE ), isTab( FALSE ),
+// isObject( FALSE ), hasPositioning( FALSE ),
+// descent( -1 ), ascent( -1 ), width( -1 ),
+// x( 0 ), y( 0 ), num_glyphs( 0 ), glyph_data_offset( 0 ),
+// fontEngine( 0 ) { }
+// int position;
+// TQScriptAnalysis analysis;
+// unsigned short isSpace : 1;
+// unsigned short isTab : 1;
+// unsigned short isObject : 1;
+// unsigned short hasPositioning : 1;
+// unsigned short complex : 1; // Windows only
+// unsigned short private_use : 1; // Windows only
+// unsigned short reserved : 10;
+// short descent;
+// int ascent;
+// int width;
+// int x;
+// int y;
+// int num_glyphs;
+// int glyph_data_offset;
+// TQFontEngine *fontEngine;
+// };
+
+#else // USE_QT4
+
+class TQFontPrivate;
+class TQString;
+
+class TQOpenType;
+class TQPainter;
+
+// this uses the same coordinate system as TQt, but a different one to freetype and Xft.
+// * y is usually negative, and is equal to the ascent.
+// * negative yoff means the following stuff is drawn higher up.
+// the characters bounding rect is given by TQRect( x,y,width,height), it's advance by
+// xoo and yoff
+struct glyph_metrics_t
+{
+ inline glyph_metrics_t() {
+ x = 100000;
+ y = 100000;
+ width = 0;
+ height = 0;
+ xoff = 0;
+ yoff = 0;
+ }
+ inline glyph_metrics_t( int _x, int _y, int _width, int _height, int _xoff, int _yoff ) {
+ x = _x;
+ y = _y;
+ width = _width;
+ height = _height;
+ xoff = _xoff;
+ yoff = _yoff;
+ }
+ int x;
+ int y;
+ int width;
+ int height;
+ int xoff;
+ int yoff;
+};
+
+#if defined( TQ_WS_X11 ) || defined ( TQ_WS_TQWS )
+typedef unsigned short glyph_t;
+
+struct qoffset_t {
+ short x;
+ short y;
+};
+
+typedef int advance_t;
+
+struct TQScriptAnalysis
+{
+ unsigned short script : 7;
+ unsigned short bidiLevel : 6; // Unicode Bidi algorithm embedding level (0-61)
+ unsigned short override : 1; // Set when in LRO/RLO embedding
+ unsigned short reserved : 2;
+ bool operator == ( const TQScriptAnalysis &other ) {
+ return
+ script == other.script &&
+ bidiLevel == other.bidiLevel;
+ // ###
+// && override == other.override;
+ }
+
+};
+
+#elif defined( TQ_WS_MAC )
+
+typedef unsigned short glyph_t;
+
+struct qoffset_t {
+ short x;
+ short y;
+};
+
+typedef int advance_t;
+
+struct TQScriptAnalysis
+{
+ unsigned short script : 7;
+ unsigned short bidiLevel : 6; // Unicode Bidi algorithm embedding level (0-61)
+ unsigned short override : 1; // Set when in LRO/RLO embedding
+ unsigned short reserved : 2;
+ bool operator == ( const TQScriptAnalysis &other ) {
+ return
+ script == other.script &&
+ bidiLevel == other.bidiLevel;
+ // ###
+// && override == other.override;
+ }
+
+};
+
+#elif defined( TQ_WS_WIN )
+
+// do not change the definitions below unless you know what you are doing!
+// it is designed to be compatible with the types found in uniscribe.
+
+typedef unsigned short glyph_t;
+
+struct qoffset_t {
+ int x;
+ int y;
+};
+
+typedef int advance_t;
+
+struct TQScriptAnalysis {
+ unsigned short script :10;
+ unsigned short rtl :1;
+ unsigned short layoutRTL :1;
+ unsigned short linkBefore :1;
+ unsigned short linkAfter :1;
+ unsigned short logicalOrder :1;
+ unsigned short noGlyphIndex :1;
+ unsigned short bidiLevel :5;
+ unsigned short override :1;
+ unsigned short inhibitSymSwap :1;
+ unsigned short charShape :1;
+ unsigned short digitSubstitute :1;
+ unsigned short inhibitLigate :1;
+ unsigned short fDisplayZWG :1;
+ unsigned short arabicNumContext :1;
+ unsigned short gcpClusters :1;
+ unsigned short reserved :1;
+ unsigned short engineReserved :2;
+};
+
+inline bool operator == ( const TQScriptAnalysis &sa1, const TQScriptAnalysis &sa2 )
+{
+ return
+ sa1.script == sa2.script &&
+ sa1.bidiLevel == sa2.bidiLevel;
+ // ###
+// && override == other.override;
+}
+
+#endif
+
+// enum and struct are made to be compatible with Uniscribe, dont change unless you know what you're doing.
+struct GlyphAttributes {
+ // highest value means highest priority for justification. Justification is done by first inserting kashidas
+ // starting with the highest priority positions, then stretching spaces, afterwards extending inter char
+ // spacing, and last spacing between arabic words.
+ // NoJustification is for example set for arabic where no Kashida can be inserted or for diacritics.
+ enum Justification {
+ NoJustification= 0, // Justification can't be applied after this glyph
+ Arabic_Space = 1, // This glyph represents a space inside arabic text
+ Character = 2, // Inter-character justification point follows this glyph
+ Space = 4, // This glyph represents a blank outside an Arabic run
+ Arabic_Normal = 7, // Normal Middle-Of-Word glyph that connects to the right (begin)
+ Arabic_Waw = 8, // Next character is final form of Waw/Ain/Qaf/Fa
+ Arabic_BaRa = 9, // Next two chars are Ba + Ra/Ya/AlefMaksura
+ Arabic_Alef = 10, // Next character is final form of Alef/Tah/Lam/Kaf/Gaf
+ Arabic_HaaDal = 11, // Next character is final form of Haa/Dal/Taa Marbutah
+ Arabic_Seen = 12, // Initial or Medial form Of Seen/Sad
+ Arabic_Kashida = 13 // Kashida(U+640) in middle of word
+ };
+ unsigned short justification :4; // Justification class
+ unsigned short clusterStart :1; // First glyph of representation of cluster
+ unsigned short mark :1; // needs to be positioned around base char
+ unsigned short zeroWidth :1; // ZWJ, ZWNJ etc, with no width, currently used as "Don't print" for ZWSP
+ unsigned short reserved :1;
+ unsigned short combiningClass :8;
+};
+
+// also this is compatible to uniscribe. Do not change.
+struct TQCharAttributes {
+ uchar softBreak :1; // Potential linebreak point _before_ this character
+ uchar whiteSpace :1; // A tqunicode whitespace character, except NBSP, ZWNBSP
+ uchar charStop :1; // Valid cursor position (for left/right arrow)
+ uchar wordStop :1; // Valid cursor position (for ctrl + left/right arrow)
+ uchar invalid :1;
+ uchar reserved :3;
+};
+
+inline bool qIsZeroWidthChar(ushort uc)
+{
+ return (uc >= 0x200b && uc <= 0x200f /* ZW Space, ZWNJ, ZWJ, LRM and RLM */)
+ || (uc >= 0x2028 && uc <= 0x202f /* LS, PS, LRE, RLE, PDF, LRO, RLO, NNBSP */)
+ || (uc >= 0x206a && uc <= 0x206f /* ISS, ASS, IAFS, AFS, NADS, NODS */);
+}
+
+class TQFontEngine;
+
+struct TQScriptItem
+{
+ inline TQScriptItem() : position( 0 ), isSpace( FALSE ), isTab( FALSE ),
+ isObject( FALSE ), hasPositioning( FALSE ),
+ descent( -1 ), ascent( -1 ), width( -1 ),
+ x( 0 ), y( 0 ), num_glyphs( 0 ), glyph_data_offset( 0 ),
+ fontEngine( 0 ) { }
+ int position;
+ TQScriptAnalysis analysis;
+ unsigned short isSpace : 1;
+ unsigned short isTab : 1;
+ unsigned short isObject : 1;
+ unsigned short hasPositioning : 1;
+ unsigned short complex : 1; // Windows only
+ unsigned short private_use : 1; // Windows only
+ unsigned short reserved : 10;
+ short descent;
+ int ascent;
+ int width;
+ int x;
+ int y;
+ int num_glyphs;
+ int glyph_data_offset;
+ TQFontEngine *fontEngine;
+};
+
+struct TQScriptItemArrayPrivate
+{
+ unsigned int alloc;
+ unsigned int size;
+ TQScriptItem items[1];
+};
+
+class TQScriptItemArray
+{
+public:
+ TQScriptItemArray() : d( 0 ) {}
+ ~TQScriptItemArray();
+
+ inline TQScriptItem &operator[] (int i) const {return d->items[i]; }
+ inline void append( const TQScriptItem &item ) {
+ if ( d->size == d->alloc )
+ resize( d->size + 1 );
+ d->items[d->size] = item;
+ d->size++;
+ }
+ inline int size() const { return d ? d->size : 0; }
+
+ void resize( int s );
+ void clear();
+
+ TQScriptItemArrayPrivate *d;
+private:
+#ifdef TQ_DISABLE_COPY
+ TQScriptItemArray( const TQScriptItemArray & );
+ TQScriptItemArray &operator = ( const TQScriptItemArray & );
+#endif
+};
+
+class TQFontPrivate;
+
+class TQTextEngine {
+public:
+ TQTextEngine( const TQString &str, TQFontPrivate *f );
+ ~TQTextEngine();
+
+ enum Mode {
+ Full = 0x00,
+ NoBidi = 0x01,
+ SingleLine = 0x02,
+ WidthOnly = 0x07
+ };
+
+ void itemize( int mode = Full );
+
+ static void bidiReorder( int numRuns, const TQ_UINT8 *levels, int *visualOrder );
+
+ const TQCharAttributes *attributes();
+ void tqshape( int item ) const;
+
+ // ### we need something for justification
+
+ enum Edge {
+ Leading,
+ Trailing
+ };
+ enum ShaperFlag {
+ RightToLeft = 0x0001,
+ Mirrored = 0x0001
+ };
+
+ int width( int charFrom, int numChars ) const;
+ glyph_metrics_t boundingBox( int from, int len ) const;
+
+ TQScriptItemArray items;
+ TQString string;
+ TQFontPrivate *fnt;
+ int lineWidth;
+ int widthUsed;
+ int firstItemInLine;
+ int currentItem;
+ TQChar::Direction direction : 5;
+ unsigned int haveCharAttributes : 1;
+ unsigned int widthOnly : 1;
+ unsigned int reserved : 25;
+
+ int length( int item ) const {
+ const TQScriptItem &si = items[item];
+ int from = si.position;
+ item++;
+ return ( item < items.size() ? items[item].position : string.length() ) - from;
+ }
+ void splitItem( int item, int pos );
+
+ unsigned short *logClustersPtr;
+ glyph_t *glyphPtr;
+ advance_t *advancePtr;
+ qoffset_t *offsetsPtr;
+ GlyphAttributes *glyphAttributesPtr;
+
+ inline unsigned short *logClusters( const TQScriptItem *si ) const
+ { return logClustersPtr+si->position; }
+ inline glyph_t *glyphs( const TQScriptItem *si ) const
+ { return glyphPtr+si->glyph_data_offset; }
+ inline advance_t *advances( const TQScriptItem *si ) const
+ { return advancePtr+si->glyph_data_offset; }
+ inline qoffset_t *offsets( const TQScriptItem *si ) const
+ { return offsetsPtr+si->glyph_data_offset; }
+ inline GlyphAttributes *glyphAttributes( const TQScriptItem *si ) const
+ { return glyphAttributesPtr+si->glyph_data_offset; }
+
+ void reallocate( int totalGlyphs );
+ inline void ensureSpace( int nGlyphs ) const {
+ if ( num_glyphs - used < nGlyphs )
+ ((TQTextEngine *)this)->reallocate( ( (used + nGlyphs + 16) >> 4 ) << 4 );
+ }
+
+ int allocated;
+ void **memory;
+ int num_glyphs;
+ int used;
+};
+
+#endif
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqtextengine_unix.cpp b/tqtinterface/qt4/src/kernel/tqtextengine_unix.cpp
new file mode 100644
index 0000000..e503897
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtextengine_unix.cpp
@@ -0,0 +1,127 @@
+/****************************************************************************
+**
+** Text engine classes
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <assert.h>
+
+
+TQScriptItemArray::~TQScriptItemArray()
+{
+ clear();
+ free( d );
+}
+
+void TQScriptItemArray::clear()
+{
+ if ( d ) {
+ for ( unsigned int i = 0; i < d->size; i++ ) {
+ TQScriptItem &si = d->items[i];
+ if ( si.fontEngine )
+ si.fontEngine->deref();
+ }
+ d->size = 0;
+ }
+}
+
+void TQScriptItemArray::resize( int s )
+{
+ int alloc = (s + 8) >> 3 << 3;
+ d = (TQScriptItemArrayPrivate *)realloc( d, sizeof( TQScriptItemArrayPrivate ) +
+ sizeof( TQScriptItem ) * alloc );
+ d->alloc = alloc;
+}
+
+void TQTextEngine::tqshape( int item ) const
+{
+ assert( item < items.size() );
+ TQScriptItem &si = items[item];
+
+ if ( si.num_glyphs )
+ return;
+
+ TQFont::Script script = (TQFont::Script)si.analysis.script;
+ si.glyph_data_offset = used;
+
+ if ( !si.fontEngine )
+ si.fontEngine = fnt->engineForScript( script );
+ si.fontEngine->ref();
+
+ si.ascent = si.fontEngine->ascent();
+ si.descent = si.fontEngine->descent();
+ si.num_glyphs = 0;
+
+ if ( si.fontEngine && si.fontEngine != (TQFontEngine*)-1 ) {
+ TQShaperItem tqshaper_item;
+ tqshaper_item.script = si.analysis.script;
+ tqshaper_item.string = &string;
+ tqshaper_item.from = si.position;
+ tqshaper_item.length = length(item);
+ tqshaper_item.font = si.fontEngine;
+ tqshaper_item.num_glyphs = TQMAX(int(num_glyphs - used), tqshaper_item.length);
+ tqshaper_item.flags = si.analysis.bidiLevel % 2 ? RightToLeft : 0;
+ tqshaper_item.has_positioning = FALSE;
+
+ while (1) {
+// qDebug(" . num_glyphs=%d, used=%d, item.num_glyphs=%d", num_glyphs, used, tqshaper_item.num_glyphs);
+ ensureSpace(tqshaper_item.num_glyphs);
+ tqshaper_item.num_glyphs = num_glyphs - used;
+// qDebug(" .. num_glyphs=%d, used=%d, item.num_glyphs=%d", num_glyphs, used, tqshaper_item.num_glyphs);
+ tqshaper_item.glyphs = glyphs(&si);
+ tqshaper_item.advances = advances(&si);
+ tqshaper_item.offsets = offsets(&si);
+ tqshaper_item.attributes = glyphAttributes(&si);
+ tqshaper_item.log_clusters = logClusters(&si);
+ if (scriptEngines[tqshaper_item.script].tqshape(&tqshaper_item))
+ break;
+ }
+
+ si.num_glyphs = tqshaper_item.num_glyphs;
+ si.hasPositioning = tqshaper_item.has_positioning;
+ }
+ ((TQTextEngine *)this)->used += si.num_glyphs;
+
+ si.width = 0;
+ advance_t *advances = this->advances( &si );
+ advance_t *end = advances + si.num_glyphs;
+ while ( advances < end ) {
+// qDebug("advances[%d] = %d", advances - this->advances(&si), *advances);
+ si.width += *(advances++);
+ }
+
+ return;
+}
+
diff --git a/tqtinterface/qt4/src/kernel/tqtextlayout.cpp b/tqtinterface/qt4/src/kernel/tqtextlayout.cpp
new file mode 100644
index 0000000..1a007a8
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtextlayout.cpp
@@ -0,0 +1,818 @@
+/****************************************************************************
+**
+** ???
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <tqtglobaldefines.h>
+// Nasty, nasty horrid HACK to get access to QTextLine's private members
+// This is TERRIBLE and I wish there was a way around it
+// This is a good example of the new, broken & irritating Qt4 API,
+// and the corresponding loss in functionality versus Qt3.
+// See also tqrect.cpp
+#define private protected
+#include <Qt/qtextlayout.h>
+#undef private
+
+#include "tqtextlayout_p.h"
+#include "tqtextengine_p.h"
+
+#include <tqfont.h>
+#include <tqapplication.h>
+#include <tqpainter.h>
+
+#ifdef USE_QT4
+#include "private/qt4_qtextengine_p.h"
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+TQTextItem::TQTextItem(int line, QTextEngine *e) : QTextLine(line, e) {}
+
+// TQt internal functions
+// Do not modify unless you know what you are doing!
+QTextEngine* TQTextItem::tqt_textEngine() const {
+ return eng;
+}
+
+TQString TQTextItem::tqt_textString() const {
+ return eng->layoutData->string;
+}
+
+void TQTextItem::tqt_tqdrawTextItem( TQPainter* p, int x, int y, const TQTextItem &ti, int textFlags ) const {
+ // [FIXME] This needs serious help--it ignores the selected font, font size, etc.
+ #warning TQTextItem::tqt_tqdrawTextItem( TQPainter* p, int x, int y, const TQTextItem &ti, int textFlags ) unimplemented
+ printf("[WARNING] TQTextItem::tqt_tqdrawTextItem( TQPainter* p, int x, int y, const TQTextItem &ti, int textFlags ) partially implemented\n\r");
+
+ // Cheat!
+ TQString textToPaint = ti.tqt_textString();
+ p->save();
+ p->setFont(eng->font());
+ p->drawText( x, y, textToPaint, textToPaint.length());
+// p->drawText( x, y, TQString("BAD WOLF"), 8);
+ p->restore();
+}
+
+// End TQt internal functions
+
+// // [FIXME]
+TQTextItem TQTextLayout::nextItem() {
+ tqtl_currentItem++;
+
+ if ( tqtl_currentItem >= numItems() )
+ return TQTextItem();
+
+// d->tqshape( tqtl_currentItem );
+ return TQTextItem( tqtl_currentItem, d );
+}
+
+TQTextItem TQTextLayout::currentItem() {
+ if ( tqtl_currentItem >= numItems() )
+ return TQTextItem();
+
+// d->tqshape( tqtl_currentItem );
+ return TQTextItem( tqtl_currentItem, d );
+}
+
+bool TQTextItem::isRightToLeft() const
+{
+// if (textDirection() == Qt::RightToLeft) {
+// return true;
+// }
+// else {
+// return false;
+// }
+ printf("[WARNING] bool TQTextItem::isRightToLeft() const unimplemented\n\r");
+ return false;
+}
+
+bool TQTextItem::isObject() const
+{
+ printf("[WARNING] bool TQTextItem::isObject() const unimplemented\n\r");
+ return false;
+}
+
+bool TQTextItem::isSpace() const
+{
+ printf("[WARNING] bool TQTextItem::isSpace() const unimplemented\n\r");
+ return false;
+}
+
+bool TQTextItem::isTab() const
+{
+ printf("[WARNING] bool TQTextItem::isTab() const unimplemented\n\r");
+ return false;
+}
+
+int TQTextLayout::availableWidth() const
+{
+ return tqtl_lineWidth - tqtl_widthUsed;
+}
+
+int TQTextItem::from() const
+{
+// return engine->items[item].position;
+ return textStart();
+
+// printf("[WARNING] int TQTextItem::from() const unimplemented\n\r");
+// return 0;
+}
+
+int TQTextItem::length() const
+{
+// return engine->length(item);
+ return textLength();
+
+// printf("[WARNING] int TQTextItem::length() const unimplemented\n\r");
+// return 0;
+}
+
+void TQTextLayout::beginLine( int width ) {
+ tqtl_widthUsed = 0;
+ tqtl_lineWidth = width;
+ QTextLine line = createLine();
+ tqtl_currentItem = numItems() - 1;
+ line.setLineWidth(width);
+}
+
+bool TQTextLayout::atEnd() const
+{
+ return tqtl_currentItem >= numItems();
+}
+
+int TQTextLayout::widthUsed() {
+ return tqtl_widthUsed;
+}
+
+TQTextLayout::Result TQTextLayout::addCurrentItem() {
+ if (currentItem().isValid()) {
+ tqtl_widthUsed = currentItem().naturalTextWidth();
+ }
+ else {
+ tqtl_widthUsed = 0;
+ }
+ tqtl_currentItem++;
+ printf("[WARNING] TextLayout::Result TQTextLayout::addCurrentItem() partially implemented -- some of its functionality has been moved to beginLine()\n\r");
+ return Ok;
+// return (tqtl_widthUsed <= tqtl_lineWidth || (tqtl_currentItem < d->items.size() && d->items[tqtl_currentItem].isSpace)) ? Ok : LineFull;
+}
+
+TQTextLayout::Result TQTextLayout::endLine( int x, int y, int tqalignment, int *ascent, int *descent, int *lineLeft, int *lineRight )
+{
+// [FIXME] This crashes...
+// QTextLine line = itemAt(tqtl_currentItem);
+// line.setPosition(QPointF(x,y));
+// TQ_UNUSED(tqalignment);
+// TQ_UNUSED(ascent);
+// TQ_UNUSED(descent);
+// TQ_UNUSED(lineLeft);
+// TQ_UNUSED(lineRight);
+
+ TQ_UNUSED(x);
+ TQ_UNUSED(y);
+ TQ_UNUSED(tqalignment);
+ TQ_UNUSED(ascent);
+ TQ_UNUSED(descent);
+ TQ_UNUSED(lineLeft);
+ TQ_UNUSED(lineRight);
+ // tqtl_currentItem must be dealt with here as well
+ printf("[WARNING] TQTextLayout::Result TQTextLayout::endLine( int x, int y, int tqalignment, int *ascent, int *descent, int *lineLeft, int *lineRight ) unimplemented\n\r");
+ return Ok;
+}
+
+void TQTextLayout::setDirection(TQChar::Direction dir) {
+ printf("[WARNING] void TQTextLayout::setDirection(TQChar::Direction dir) unimplemented\n\r");
+}
+
+#else // USE_QT4
+
+TQRect TQTextItem::rect() const
+{
+ TQScriptItem& si = engine->items[item];
+ return TQRect( si.x, si.y, si.width, si.ascent+si.descent );
+}
+
+int TQTextItem::x() const
+{
+ return engine->items[item].x;
+}
+
+int TQTextItem::y() const
+{
+ return engine->items[item].y;
+}
+
+int TQTextItem::width() const
+{
+ return engine->items[item].width;
+}
+
+int TQTextItem::ascent() const
+{
+ return engine->items[item].ascent;
+}
+
+int TQTextItem::descent() const
+{
+ return engine->items[item].descent;
+}
+
+void TQTextItem::setWidth( int w )
+{
+ engine->items[item].width = w;
+}
+
+void TQTextItem::setAscent( int a )
+{
+ engine->items[item].ascent = a;
+}
+
+void TQTextItem::setDescent( int d )
+{
+ engine->items[item].descent = d;
+}
+
+int TQTextItem::from() const
+{
+ return engine->items[item].position;
+}
+
+int TQTextItem::length() const
+{
+ return engine->length(item);
+}
+
+
+int TQTextItem::cursorToX( int *cPos, Edge edge ) const
+{
+ int pos = *cPos;
+ TQScriptItem *si = &engine->items[item];
+
+ engine->tqshape( item );
+ advance_t *advances = engine->advances( si );
+ GlyphAttributes *glyphAttributes = engine->glyphAttributes( si );
+ unsigned short *logClusters = engine->logClusters( si );
+
+ int l = engine->length( item );
+ if ( pos > l )
+ pos = l;
+ if ( pos < 0 )
+ pos = 0;
+
+ int glyph_pos = pos == l ? si->num_glyphs : logClusters[pos];
+ if ( edge == Trailing ) {
+ // trailing edge is leading edge of next cluster
+ while ( glyph_pos < si->num_glyphs && !glyphAttributes[glyph_pos].clusterStart )
+ glyph_pos++;
+ }
+
+ int x = 0;
+ bool reverse = engine->items[item].analysis.bidiLevel % 2;
+
+ if ( reverse ) {
+ for ( int i = si->num_glyphs-1; i >= glyph_pos; i-- )
+ x += advances[i];
+ } else {
+ for ( int i = 0; i < glyph_pos; i++ )
+ x += advances[i];
+ }
+// qDebug("cursorToX: pos=%d, gpos=%d x=%d", pos, glyph_pos, x );
+ *cPos = pos;
+ return x;
+}
+
+int TQTextItem::xToCursor( int x, CursorPosition cpos ) const
+{
+ TQScriptItem *si = &engine->items[item];
+ engine->tqshape( item );
+ advance_t *advances = engine->advances( si );
+ unsigned short *logClusters = engine->logClusters( si );
+
+ int l = engine->length( item );
+ bool reverse = si->analysis.bidiLevel % 2;
+ if ( x < 0 )
+ return reverse ? l : 0;
+
+
+ if ( reverse ) {
+ int width = 0;
+ for ( int i = 0; i < si->num_glyphs; i++ ) {
+ width += advances[i];
+ }
+ x = -x + width;
+ }
+ int cp_before = 0;
+ int cp_after = 0;
+ int x_before = 0;
+ int x_after = 0;
+
+ int lastCluster = 0;
+ for ( int i = 1; i <= l; i++ ) {
+ int newCluster = i < l ? logClusters[i] : si->num_glyphs;
+ if ( newCluster != lastCluster ) {
+ // calculate cluster width
+ cp_before = cp_after;
+ x_before = x_after;
+ cp_after = i;
+ for ( int j = lastCluster; j < newCluster; j++ )
+ x_after += advances[j];
+ // qDebug("cluster boundary: lastCluster=%d, newCluster=%d, x_before=%d, x_after=%d",
+ // lastCluster, newCluster, x_before, x_after );
+ if ( x_after > x )
+ break;
+ lastCluster = newCluster;
+ }
+ }
+
+ bool before = ( cpos == OnCharacters || (x - x_before) < (x_after - x) );
+
+// qDebug("got cursor position for %d: %d/%d, x_ba=%d/%d using %d",
+// x, cp_before,cp_after, x_before, x_after, before ? cp_before : cp_after );
+
+ return before ? cp_before : cp_after;
+
+}
+
+
+bool TQTextItem::isRightToLeft() const
+{
+ return (engine->items[item].analysis.bidiLevel % 2);
+}
+
+bool TQTextItem::isObject() const
+{
+ return engine->items[item].isObject;
+}
+
+bool TQTextItem::isSpace() const
+{
+ return engine->items[item].isSpace;
+}
+
+bool TQTextItem::isTab() const
+{
+ return engine->items[item].isTab;
+}
+
+TQTextLayout::TQTextLayout()
+ :d(0) {}
+
+TQTextLayout::TQTextLayout( const TQString& string, TQPainter *p )
+{
+ TQFontPrivate *f = p ? ( p->pfont ? p->pfont->d : p->cfont.d ) : TQApplication::font().d;
+ d = new TQTextEngine( (string.isNull() ? (const TQString&)TQString::tqfromLatin1("") : string), f );
+}
+
+TQTextLayout::TQTextLayout( const TQString& string, const TQFont& fnt )
+{
+ d = new TQTextEngine( (string.isNull() ? (const TQString&)TQString::tqfromLatin1("") : string), fnt.d );
+}
+
+TQTextLayout::~TQTextLayout()
+{
+ delete d;
+}
+
+void TQTextLayout::setText( const TQString& string, const TQFont& fnt )
+{
+ delete d;
+ d = new TQTextEngine( (string.isNull() ? (const TQString&)TQString::tqfromLatin1("") : string), fnt.d );
+}
+
+/* add an additional item boundary eg. for style change */
+void TQTextLayout::setBoundary( int strPos )
+{
+ if ( strPos <= 0 || strPos >= (int)d->string.length() )
+ return;
+
+ int itemToSplit = 0;
+ while ( itemToSplit < d->items.size() && d->items[itemToSplit].position <= strPos )
+ itemToSplit++;
+ itemToSplit--;
+ if ( d->items[itemToSplit].position == strPos ) {
+ // already a split at the requested position
+ return;
+ }
+ d->splitItem( itemToSplit, strPos - d->items[itemToSplit].position );
+}
+
+
+int TQTextLayout::numItems() const
+{
+ return d->items.size();
+}
+
+TQTextItem TQTextLayout::itemAt( int i ) const
+{
+ return TQTextItem( i, d );
+}
+
+
+TQTextItem TQTextLayout::tqfindItem( int strPos ) const
+{
+ if ( strPos == 0 && d->items.size() )
+ return TQTextItem( 0, d );
+ // ## TODO use bsearch
+ for ( int i = d->items.size()-1; i >= 0; --i ) {
+ if ( d->items[i].position < strPos )
+ return TQTextItem( i, d );
+ }
+ return TQTextItem();
+}
+
+
+void TQTextLayout::beginLayout( TQTextLayout::LayoutMode m )
+{
+ d->items.clear();
+ TQTextEngine::Mode mode = TQTextEngine::Full;
+ if (m == NoBidi)
+ mode = TQTextEngine::NoBidi;
+ else if (m == SingleLine)
+ mode = TQTextEngine::SingleLine;
+ d->itemize( mode );
+ d->currentItem = 0;
+ d->firstItemInLine = -1;
+}
+
+void TQTextLayout::beginLine( int width )
+{
+ d->lineWidth = width;
+ d->widthUsed = 0;
+ d->firstItemInLine = -1;
+}
+
+bool TQTextLayout::atEnd() const
+{
+ return d->currentItem >= d->items.size();
+}
+
+TQTextItem TQTextLayout::nextItem()
+{
+ d->currentItem++;
+
+ if ( d->currentItem >= d->items.size() )
+ return TQTextItem();
+
+ d->tqshape( d->currentItem );
+ return TQTextItem( d->currentItem, d );
+}
+
+TQTextItem TQTextLayout::currentItem()
+{
+ if ( d->currentItem >= d->items.size() )
+ return TQTextItem();
+
+ d->tqshape( d->currentItem );
+ return TQTextItem( d->currentItem, d );
+}
+
+/* ## maybe also currentItem() */
+void TQTextLayout::setLineWidth( int newWidth )
+{
+ d->lineWidth = newWidth;
+}
+
+int TQTextLayout::lineWidth() const
+{
+ return d->lineWidth;
+}
+
+int TQTextLayout::widthUsed() const
+{
+ return d->widthUsed;
+}
+
+int TQTextLayout::availableWidth() const
+{
+ return d->lineWidth - d->widthUsed;
+}
+
+
+/* returns true if completely added */
+TQTextLayout::Result TQTextLayout::addCurrentItem()
+{
+ if ( d->firstItemInLine == -1 )
+ d->firstItemInLine = d->currentItem;
+ TQScriptItem &current = d->items[d->currentItem];
+ d->tqshape( d->currentItem );
+ d->widthUsed += current.width;
+// qDebug("trying to add item %d with width %d, remaining %d", d->currentItem, current.width, d->lineWidth-d->widthUsed );
+
+ d->currentItem++;
+
+ return (d->widthUsed <= d->lineWidth
+ || (d->currentItem < d->items.size() && d->items[d->currentItem].isSpace)) ? Ok : LineFull;
+}
+
+TQTextLayout::Result TQTextLayout::endLine( int x, int y, int tqalignment,
+ int *ascent, int *descent, int *lineLeft, int *lineRight )
+{
+ int available = d->lineWidth;
+ int numRuns = 0;
+ int numSpaceItems = 0;
+ TQ_UINT8 _levels[128];
+ int _visual[128];
+ TQ_UINT8 *levels = _levels;
+ int *visual = _visual;
+ int i;
+ TQTextLayout::Result result = LineEmpty;
+
+// qDebug("endLine x=%d, y=%d, first=%d, current=%d lw=%d wu=%d", x, y, d->firstItemInLine, d->currentItem, d->lineWidth, d->widthUsed );
+ int width_nobreak_found = d->widthUsed;
+ if ( d->firstItemInLine == -1 )
+ goto end;
+
+ if ( !(tqalignment & (TQt::SingleLine|TQt::IncludeTrailingSpaces))
+ && d->currentItem > d->firstItemInLine && d->items[d->currentItem-1].isSpace ) {
+ int i = d->currentItem-1;
+ while ( i > d->firstItemInLine && d->items[i].isSpace ) {
+ numSpaceItems++;
+ d->widthUsed -= d->items[i--].width;
+ }
+ }
+
+ if ( (tqalignment & (TQt::WordBreak|TQt::BreakAnywhere)) &&
+ d->widthUsed > d->lineWidth ) {
+ // tqfind linebreak
+
+ // even though we removed trailing spaces the line was too wide. We'll have to break at an earlier
+ // position. To not confuse the layouting below, reset the number of space items
+ numSpaceItems = 0;
+
+
+ bool breakany = tqalignment & TQt::BreakAnywhere;
+
+ const TQCharAttributes *attrs = d->attributes();
+ int w = 0;
+ int itemWidth = 0;
+ int breakItem = d->firstItemInLine;
+ int breakPosition = -1;
+#if 0
+ // we iterate backwards or forward depending on what we guess is closer
+ if ( d->widthUsed - d->lineWidth < d->lineWidth ) {
+ // backwards search should be faster
+
+ } else
+#endif
+ {
+ int tmpWidth = 0;
+ int swidth = 0;
+ // forward search is probably faster
+ for ( int i = d->firstItemInLine; i < d->currentItem; i++ ) {
+ const TQScriptItem *si = &d->items[i];
+ int length = d->length( i );
+ const TQCharAttributes *itemAttrs = attrs + si->position;
+
+ advance_t *advances = d->advances( si );
+ unsigned short *logClusters = d->logClusters( si );
+
+ int lastGlyph = 0;
+ int tmpItemWidth = 0;
+
+// qDebug("looking for break in item %d, isSpace=%d", i, si->isSpace );
+ if(si->isSpace && !(tqalignment & (TQt::SingleLine|TQt::IncludeTrailingSpaces))) {
+ swidth += si->width;
+ } else {
+ tmpWidth += swidth;
+ swidth = 0;
+ for ( int pos = 0; pos < length; pos++ ) {
+// qDebug("advance=%d, w=%d, tmpWidth=%d, softbreak=%d, whitespace=%d",
+// *advances, w, tmpWidth, itemAttrs->softBreak, itemAttrs->whiteSpace );
+ int glyph = logClusters[pos];
+ if ( lastGlyph != glyph ) {
+ while ( lastGlyph < glyph )
+ tmpItemWidth += advances[lastGlyph++];
+ if ( breakPosition != -1 && w + tmpWidth + tmpItemWidth > d->lineWidth ) {
+// qDebug("found break at w=%d, tmpWidth=%d, tmpItemWidth=%d", w, tmpWidth, tmpItemWidth);
+ d->widthUsed = w;
+ goto found;
+ }
+ }
+ if ( (itemAttrs->softBreak ||
+ ( breakany && itemAttrs->charStop ) ) &&
+ (i != d->firstItemInLine || pos != 0) ) {
+ if ( breakItem != i )
+ itemWidth = 0;
+ if (itemAttrs->softBreak)
+ breakany = FALSE;
+ breakItem = i;
+ breakPosition = pos;
+// qDebug("found possible break at item %d, position %d (absolute=%d), w=%d, tmpWidth=%d, tmpItemWidth=%d", breakItem, breakPosition, d->items[breakItem].position+breakPosition, w, tmpWidth, tmpItemWidth);
+ w += tmpWidth + tmpItemWidth;
+ itemWidth += tmpItemWidth;
+ tmpWidth = 0;
+ tmpItemWidth = 0;
+ }
+ itemAttrs++;
+ }
+ while ( lastGlyph < si->num_glyphs )
+ tmpItemWidth += advances[lastGlyph++];
+ tmpWidth += tmpItemWidth;
+ if ( w + tmpWidth > d->lineWidth ) {
+ d->widthUsed = w;
+ goto found;
+ }
+ }
+ }
+ }
+
+ found:
+ // no valid break point found
+ if ( breakPosition == -1 ) {
+ d->widthUsed = width_nobreak_found;
+ goto nobreak;
+ }
+
+// qDebug("linebreak at item %d, position %d, wu=%d", breakItem, breakPosition, d->widthUsed );
+ // split the line
+ if ( breakPosition > 0 ) {
+// int length = d->length( breakItem );
+
+// qDebug("splitting item, itemWidth=%d", itemWidth);
+ // not a full item, need to break
+ d->splitItem( breakItem, breakPosition );
+ d->currentItem = breakItem+1;
+ } else {
+ d->currentItem = breakItem;
+ }
+ }
+
+ result = Ok;
+
+ nobreak:
+ // position the objects in the line
+ available -= d->widthUsed;
+
+ numRuns = d->currentItem - d->firstItemInLine - numSpaceItems;
+ if ( numRuns > 127 ) {
+ levels = new TQ_UINT8[numRuns];
+ visual = new int[numRuns];
+ }
+
+// qDebug("reordering %d runs, numSpaceItems=%d", numRuns, numSpaceItems );
+ for ( i = 0; i < numRuns; i++ ) {
+ levels[i] = d->items[i+d->firstItemInLine].analysis.bidiLevel;
+// qDebug(" level = %d", d->items[i+d->firstItemInLine].analysis.bidiLevel );
+ }
+ d->bidiReorder( numRuns, levels, visual );
+
+ end:
+ // ### FIXME
+ if ( tqalignment & TQt::AlignJustify ) {
+ // #### justify items
+ tqalignment = TQt::AlignAuto;
+ }
+ if ( (tqalignment & TQt::AlignHorizontal_Mask) == TQt::AlignAuto )
+ tqalignment = TQt::AlignLeft;
+ if ( tqalignment & TQt::AlignRight )
+ x += available;
+ else if ( tqalignment & TQt::AlignHCenter )
+ x += available/2;
+
+
+ int asc = ascent ? *ascent : 0;
+ int desc = descent ? *descent : 0;
+
+ for ( i = 0; i < numRuns; i++ ) {
+ TQScriptItem &si = d->items[d->firstItemInLine+visual[i]];
+ asc = TQMAX( asc, si.ascent );
+ desc = TQMAX( desc, si.descent );
+ }
+
+ int left = x;
+ for ( i = 0; i < numRuns; i++ ) {
+ TQScriptItem &si = d->items[d->firstItemInLine+visual[i]];
+// qDebug("positioning item %d with width %d (from=%d/length=%d) at %d", d->firstItemInLine+visual[i], si.width, si.position,
+// d->length(d->firstItemInLine+visual[i]), x );
+ si.x = x;
+ si.y = y + asc;
+ x += si.width;
+ }
+ int right = x;
+
+ if ( numSpaceItems ) {
+ if ( d->items[d->firstItemInLine+numRuns].analysis.bidiLevel % 2 ) {
+ x = left;
+ for ( i = 0; i < numSpaceItems; i++ ) {
+ TQScriptItem &si = d->items[d->firstItemInLine + numRuns + i];
+ x -= si.width;
+ si.x = x;
+ si.y = y + asc;
+ }
+ } else {
+ for ( i = 0; i < numSpaceItems; i++ ) {
+ TQScriptItem &si = d->items[d->firstItemInLine + numRuns + i];
+ si.x = x;
+ si.y = y + asc;
+ x += si.width;
+ }
+ }
+ }
+
+ if ( lineLeft )
+ *lineLeft = left;
+ if ( lineRight )
+ *lineRight = right;
+ if ( ascent )
+ *ascent = asc;
+ if ( descent )
+ *descent = desc;
+
+ if (levels != _levels)
+ delete []levels;
+ if (visual != _visual)
+ delete []visual;
+
+ return result;
+}
+
+void TQTextLayout::endLayout()
+{
+ // nothing to do currently
+}
+
+
+int TQTextLayout::nextCursorPosition( int oldPos, CursorMode mode ) const
+{
+// qDebug("looking for next cursor pos for %d", oldPos );
+ const TQCharAttributes *attributes = d->attributes();
+ int len = d->string.length();
+ if ( oldPos >= len )
+ return oldPos;
+ oldPos++;
+ if ( mode == SkipCharacters ) {
+ while ( oldPos < len && !attributes[oldPos].charStop )
+ oldPos++;
+ } else {
+ while ( oldPos < len && !attributes[oldPos].wordStop && !attributes[oldPos-1].whiteSpace )
+ oldPos++;
+ }
+// qDebug(" -> %d", oldPos );
+ return oldPos;
+}
+
+int TQTextLayout::previousCursorPosition( int oldPos, CursorMode mode ) const
+{
+// qDebug("looking for previous cursor pos for %d", oldPos );
+ const TQCharAttributes *attributes = d->attributes();
+ if ( oldPos <= 0 )
+ return 0;
+ oldPos--;
+ if ( mode == SkipCharacters ) {
+ while ( oldPos && !attributes[oldPos].charStop )
+ oldPos--;
+ } else {
+ while ( oldPos && !attributes[oldPos].wordStop && !attributes[oldPos-1].whiteSpace )
+ oldPos--;
+ }
+// qDebug(" -> %d", oldPos );
+ return oldPos;
+}
+
+
+bool TQTextLayout::validCursorPosition( int pos ) const
+{
+ const TQCharAttributes *attributes = d->attributes();
+ if ( pos < 0 || pos > (int)d->string.length() )
+ return FALSE;
+ return attributes[pos].charStop;
+}
+
+void TQTextLayout::setDirection(TQChar::Direction dir)
+{
+ d->direction = dir;
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqtextlayout_p.h b/tqtinterface/qt4/src/kernel/tqtextlayout_p.h
new file mode 100644
index 0000000..049ede2
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtextlayout_p.h
@@ -0,0 +1,300 @@
+/****************************************************************************
+**
+** ???
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTEXTLAYOUT_P_H
+#define TQTEXTLAYOUT_P_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqnamespace.h"
+#include "tqrect.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include "tqfont.h"
+#include <Qt/qpaintengine.h>
+#include <Qt/qtextlayout.h>
+
+#endif // USE_QT4
+
+class TQTextEngine;
+class TQFont;
+
+// [FIXME]
+// Due to the absence of a font engine, we MUST inherit something from Qt4, as we therefore cannot directly implement the old QTextItem class!
+// [FIXME]
+
+#ifdef USE_QT4
+
+#define BetweenCharacters CursorBetweenCharacters
+#define OnCharacters CursorOnCharacter
+
+class TQ_EXPORT TQTextItem : public QTextLine, virtual public TQt
+{
+public:
+ TQTextItem() : QTextLine() {}
+
+ bool isRightToLeft() const;
+ bool isObject() const;
+ bool isSpace() const;
+ bool isTab() const;
+
+ int from() const;
+ int length() const;
+
+ inline TQRect tqrect() const { return TQRect(rect().left(), rect().top(), rect().width(), rect().height()); }
+
+private:
+ TQTextItem(int line, QTextEngine *e);
+ QTextEngine* tqt_textEngine() const;
+ TQString tqt_textString() const;
+ void tqt_tqdrawTextItem( TQPainter* p, int x, int y, const TQTextItem &ti, int textFlags ) const;
+ friend class TQTextLayout;
+ friend class TQPainter;
+
+public:
+ // Interoperability
+ static const TQTextItem& convertFromQTextLine( QTextLine& qtl );
+};
+
+// Interoperability
+inline static const TQTextItem& convertFromQTextLine( const QTextLine& qtl ) {
+ return (*static_cast<const TQTextItem*>(&qtl));
+}
+
+#else // USE_QT4
+
+class TQ_EXPORT TQTextItem
+{
+public:
+ inline TQTextItem() : item(0), engine(0) {}
+ inline bool isValid() const { return (bool)engine; }
+
+ TQRect rect() const;
+ int x() const;
+ int y() const;
+ int width() const;
+ int ascent() const;
+ int descent() const;
+
+ enum Edge {
+ Leading,
+ Trailing
+ };
+ enum CursorPosition {
+ BetweenCharacters,
+ OnCharacters
+ };
+
+ /* cPos gets set to the valid position */
+ int cursorToX( int *cPos, Edge edge = Leading ) const;
+ inline int cursorToX( int cPos, Edge edge = Leading ) const { return cursorToX( &cPos, edge ); }
+ int xToCursor( int x, CursorPosition = BetweenCharacters ) const;
+
+ bool isRightToLeft() const;
+ bool isObject() const;
+ bool isSpace() const;
+ bool isTab() const;
+
+ void setWidth( int w );
+ void setAscent( int a );
+ void setDescent( int d );
+
+ int from() const;
+ int length() const;
+
+private:
+ friend class TQTextLayout;
+ friend class TQPainter;
+ friend class TQPSPrinter;
+ TQTextItem( int i, TQTextEngine *e ) : item( i ), engine( e ) {}
+ int item;
+ TQTextEngine *engine;
+};
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQTextLayout : public QTextLayout, virtual public TQt
+{
+public:
+ TQTextLayout() : QTextLayout() {}
+ TQTextLayout( const QString& string, QPainter *p = 0 ) : QTextLayout(string, QFont(), p->device()) {}
+ TQTextLayout( const TQString& string, const TQFont& fnt ) : QTextLayout(string, convertFromQFont(fnt)) {}
+
+ enum LayoutMode {
+ NoBidi,
+ SingleLine,
+ MultiLine
+ };
+
+ enum LineBreakStrategy {
+ AtWordBoundaries,
+ AtCharBoundaries
+ };
+
+ enum Result {
+ Ok,
+ LineFull,
+ LineEmpty,
+ Error
+ };
+ Result addCurrentItem();
+ Result endLine( int x = 0, int y = 0, int tqalignment = TQt::AlignLeft, int *ascent = 0, int *descent = 0, int *left = 0, int *right = 0 );
+
+ int numItems() const { return lineCount(); }
+ TQTextItem itemAt( int i ) const { return convertFromQTextLine(lineAt(i)); }
+ TQTextItem tqfindItem( int strPos ) const { return convertFromQTextLine(lineForTextPosition(strPos)); }
+ bool atEnd() const;
+ TQTextItem nextItem();
+ TQTextItem currentItem();
+
+ inline void setLineWidth( int newWidth ) { tqtl_lineWidth = newWidth; currentItem().setLineWidth(newWidth); }
+ inline int lineWidth() { return tqtl_lineWidth; }
+ int widthUsed();
+ int availableWidth() const;
+
+ void beginLine( int width );
+
+ inline void beginLayout() { tqtl_currentItem = 0; return QTextLayout::beginLayout(); }
+ inline void beginLayout( LayoutMode m ) { TQ_UNUSED(m); tqtl_currentItem = 0; return QTextLayout::beginLayout(); }
+
+ inline void setText( const QString& string ) { QTextLayout::setText(string); }
+ inline void setText( const TQString& string, const TQFont& fnt ) { QTextLayout::setText(string); QTextLayout::setFont(fnt); }
+
+ void setDirection(TQChar::Direction);
+
+private:
+ int tqtl_currentItem;
+ int tqtl_widthUsed;
+ int tqtl_lineWidth;
+};
+
+#else // USE_QT4
+
+class TQPainter;
+
+class TQ_EXPORT TQTextLayout
+{
+public:
+ // does itemization
+ TQTextLayout();
+ TQTextLayout( const TQString& string, TQPainter * = 0 );
+ TQTextLayout( const TQString& string, const TQFont& fnt );
+ ~TQTextLayout();
+
+ void setText( const TQString& string, const TQFont& fnt );
+
+ enum LineBreakStrategy {
+ AtWordBoundaries,
+ AtCharBoundaries
+ };
+
+ /* add an additional item boundary eg. for style change */
+ void setBoundary( int strPos );
+
+ int numItems() const;
+ TQTextItem itemAt( int i ) const;
+ TQTextItem tqfindItem( int strPos ) const;
+
+ enum LayoutMode {
+ NoBidi,
+ SingleLine,
+ MultiLine
+ };
+ void beginLayout( LayoutMode m = MultiLine );
+ void beginLine( int width );
+
+ bool atEnd() const;
+ TQTextItem nextItem();
+ TQTextItem currentItem();
+ /* ## maybe also currentItem() */
+ void setLineWidth( int newWidth );
+ int lineWidth() const;
+ int widthUsed() const;
+ int availableWidth() const;
+
+ enum Result {
+ Ok,
+ LineFull,
+ LineEmpty,
+ Error
+ };
+ /* returns true if completely added */
+ Result addCurrentItem();
+
+ /* Note: if ascent and descent are used they must be initialized to the minimum ascent/descent
+ acceptable for the line. TQFontMetrics::ascent/descent() is usually the right choice */
+ Result endLine( int x = 0, int y = 0, int tqalignment = TQt::AlignLeft,
+ int *ascent = 0, int *descent = 0, int *left = 0, int *right = 0 );
+ void endLayout();
+
+ enum CursorMode {
+ SkipCharacters,
+ SkipWords
+ };
+ bool validCursorPosition( int pos ) const;
+ int nextCursorPosition( int oldPos, CursorMode mode = SkipCharacters ) const;
+ int previousCursorPosition( int oldPos, CursorMode mode = SkipCharacters ) const;
+
+ void setDirection(TQChar::Direction);
+private:
+ TQTextLayout( TQTextEngine *e ) : d( e ) {}
+ /* disable copy and assignment */
+ TQTextLayout( const TQTextLayout & ) {}
+ void operator = ( const TQTextLayout & ) {}
+
+ friend class TQTextItem;
+ friend class TQPainter;
+ friend class TQPSPrinter;
+ TQTextEngine *d;
+};
+
+
+/*
+ class TQPainter {
+ .....
+ void tqdrawTextItem( int x, int y, TQTextItem *item );
+ };
+*/
+
+#endif // USE_QT4
+
+#endif \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqtglobaldefines.h b/tqtinterface/qt4/src/kernel/tqtglobaldefines.h
new file mode 100644
index 0000000..7fc3168
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtglobaldefines.h
@@ -0,0 +1,502 @@
+#ifndef TQTGLOBALDEFINES_H
+#define TQTGLOBALDEFINES_H
+
+#include "tqtglobalsettings.h"
+
+// #ifdef USE_QT4
+// #define QT3_SUPPORT
+// #endif
+//
+#ifdef USE_QT4
+
+#include <Qt/qglobal.h>
+#include <Qt/qnamespace.h>
+#include <Qt/qobjectdefs.h>
+
+#ifdef QT_NO_TRANSLATION
+#define TQT_NO_TRANSLATION
+#endif // QT_NO_TRANSLATION
+
+#ifdef QT_THREAD_SUPPORT
+#define TQT_THREAD_SUPPORT
+#endif // QT_THREAD_SUPPORT
+
+// #define tqqt_cast qobject_cast
+
+// Mark certain Qt3 static variables squarely OFF LIMITS
+#define qt_x_time "Usage of the qt_x_time static variable is strongly deprecated in TQt, and is unavailable in TQt for Qt4. Use GET_QT_X_TIME/SET_QT_X_TIME instead"
+#define qt_x_user_time "Usage of the qt_x_time static variable is strongly deprecated in TQt, and is unavailable in TQt for Qt4. Use GET_QT_X_USER_TIME/SET_QT_X_USER_TIME instead"
+
+// #define TQT_TQOBJECT(x) (static_cast<TQObject*>(static_cast<TQT_BASE_OBJECT_NAME*>(x)))
+#define TQT_TQOBJECT(x) (convertFromTQT_BASE_OBJECT_NAMEPointer(x))
+#define TQT_TQWIDGET(x) TQWidget::tqt_ensure_valid_widget_painting(static_cast<TQWidget*>(static_cast<QWidget*>(static_cast<TQT_BASE_OBJECT_NAME*>(x))))
+#define TQT_TQSIZEPOLICY(x) (static_cast<TQSizePolicy*>(static_cast<QSizePolicy*>(x)))
+#define TQT_TQLAYOUT(x) (static_cast<TQLayout*>(static_cast<QLayout*>(x)))
+#define TQT_TQGRIDLAYOUT(x) (static_cast<TQGridLayout*>(static_cast<QGridLayout*>(x)))
+#define TQT_TQPAINTER(x) (static_cast<TQPainter*>(static_cast<QPainter*>(x)))
+#define TQT_TQPAINTDEVICE(x) (static_cast<TQPaintDevice*>(static_cast<QPaintDevice*>(x)))
+#define TQT_TQLAYOUTITEM(x) (static_cast<TQLayoutItem*>(static_cast<QLayoutItem*>(x)))
+#define TQT_TQIODEVICE(x) (static_cast<TQIODevice*>(static_cast<QIODevice*>(x)))
+#define TQT_TQCOLOR(x) (static_cast<TQColor*>(static_cast<QColor*>(x)))
+#define TQT_TQCHAR(x) TQChar(x)
+#define TQT_TQSTRING(x) TQString(x)
+#define TQT_TQPOINT(x) (static_cast<TQPoint*>(static_cast<QPoint*>(x)))
+#define TQT_TQBUFFER(x) (static_cast<TQBuffer*>(static_cast<QBuffer*>(x)))
+#define TQT_TQWMATRIX(x) (static_cast<TQWMatrix*>(static_cast<QMatrix*>(x)))
+#define TQT_TQFILE(x) (static_cast<TQFile*>(static_cast<QFile*>(x)))
+#define TQT_TQBYTEARRAY(x) (static_cast<TQByteArray*>(static_cast<QByteArray*>(x)))
+#define TQT_TQMIMESOURCE(x) (static_cast<TQMimeSource*>(static_cast<QMimeSource*>(x)))
+#define TQT_TQWEXTRA(x) (static_cast<TQWExtra*>(static_cast<QWExtra*>(x)))
+#define TQT_TQPIXMAP(x) (static_cast<TQPixmap*>(static_cast<QPixmap*>(x)))
+#define TQT_TQCLIPBOARD(x) (static_cast<TQClipboard*>(static_cast<QClipboard*>(x)))
+#define TQT_TQPRINTER(x) (static_cast<TQPrinter*>(static_cast<QPrinter*>(x)))
+#define TQT_TQVARIANT(x) (static_cast<TQVariant*>(static_cast<QVariant*>(x)))
+#define TQT_TQMETAOBJECT(x) (static_cast<TQMetaObject*>(static_cast<QMetaObject*>(x)))
+#define TQT_TQSTYLEOPTION(x) (static_cast<TQStyleOption*>(static_cast<TQStyleOption*>(x)))
+#define TQT_TQEVENT(x) (static_cast<TQEvent*>(static_cast<QEvent*>(x)))
+#define TQT_TQKEYEVENT(x) (static_cast<TQKeyEvent*>(static_cast<QKeyEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQMOVEEVENT(x) (static_cast<TQMoveEvent*>(static_cast<QMoveEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQSHOWEVENT(x) (static_cast<TQShowEvent*>(static_cast<QShowEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQMOUSEEVENT(x) (static_cast<TQMouseEvent*>(static_cast<QMouseEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQWHEELEVENT(x) (static_cast<TQWheelEvent*>(static_cast<QWheelEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQFOCUSEVENT(x) (static_cast<TQFocusEvent*>(static_cast<QFocusEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQPAINTEVENT(x) (static_cast<TQPaintEvent*>(static_cast<QPaintEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQCHILDEVENT(x) (static_cast<TQChildEvent*>(static_cast<QChildEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQCLOSEEVENT(x) (static_cast<TQCloseEvent*>(static_cast<QCloseEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQTIMEREVENT(x) (static_cast<TQTimerEvent*>(static_cast<QTimerEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQRESIZEEVENT(x) (static_cast<TQResizeEvent*>(static_cast<QResizeEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQTABLETEVENT(x) (static_cast<TQTabletEvent*>(static_cast<QTabletEvent*>(static_cast<QEvent*>(x))))
+#define TQT_TQCONTEXTMENUEVENT(x) (static_cast<TQContextMenuEvent*>(static_cast<QContextMenuEvent*>(static_cast<QEvent*>(x))))
+
+#define TQT_TQOBJECT_OBJECT(x) (convertFromTQT_BASE_OBJECT_NAME(x))
+#define TQT_TQSIZEPOLICY_OBJECT(x) (convertFromQSizePolicy(x))
+#define TQT_TQLAYOUT_OBJECT(x) (convertFromQLayout(x))
+#define TQT_TQCOLOR_OBJECT(x) (convertFromQColor(x))
+#define TQT_TQSTRING_OBJECT(x) (convertFromQString(x))
+#define TQT_TQSTRLIST_OBJECT(x) (convertFromQStrList(x))
+#define TQT_TQSTRINGLIST_OBJECT(x) (TQStringList::convertFromQStringList(x))
+#define TQT_TQWMATRIX_OBJECT(x) (convertFromQMatrix(x))
+#define TQT_TQRECT_OBJECT(x) TQRect(x)
+#define TQT_TQBYTEARRAY_OBJECT(x) (convertFromQByteArray(x))
+#define TQT_TQPIXMAP_OBJECT(x) (convertFromQPixmap(x))
+#define TQT_TQTIME_OBJECT(x) (TQTime::convertFromQTime(x))
+#define TQT_TQDATE_OBJECT(x) (TQDate::convertFromQDate(x))
+#define TQT_TQDATETIME_OBJECT(x) (TQDateTime::convertFromQDateTime(x))
+#define TQT_TQBRUSH_OBJECT(x) (convertFromQBrush(x))
+#define TQT_TQPALETTE_OBJECT(x) (convertFromQPalette(x))
+#define TQT_TQPOINT_OBJECT(x) (convertFromQPoint(x))
+#define TQT_TQREGION_OBJECT(x) (convertFromQRegion(x))
+#define TQT_TQIMAGE_OBJECT(x) (convertFromQImage(x))
+#define TQT_TQPAINTDEVICE_OBJECT(x) (convertFromQPaintDevice(x))
+#define TQT_TQVARIANT_OBJECT(x) (convertFromQVariant(x))
+#define TQT_TQIODEVICE_OBJECT(x) (convertFromQIODevice(x))
+#define TQT_TQSESSIONMANAGER_OBJECT(x) (convertFromQSessionManager(x))
+#define TQT_TQSTYLEOPTION_OBJECT(x) (TQStyleOption(x))
+
+// #define TQT_TQOBJECT_CONST(x) (static_cast<const TQObject*>(static_cast<const TQT_BASE_OBJECT_NAME*>(x)))
+#define TQT_TQOBJECT_CONST(x) (convertFromTQT_BASE_OBJECT_NAMEPointerConst(x))
+#define TQT_TQWIDGET_CONST(x) (static_cast<const TQWidget*>(static_cast<const QWidget*>(static_cast<const TQT_BASE_OBJECT_NAME*>(x))))
+#define TQT_TQMIMESOURCE_CONST(x) (static_cast<const TQMimeSource*>(static_cast<const QMimeSource*>(x)))
+#define TQT_TQPOINT_CONST(x) (static_cast<const TQPoint*>(static_cast<const QPoint*>(x)))
+#define TQT_TQBRUSH_CONST(x) (static_cast<const TQBrush*>(static_cast<const QBrush*>(x)))
+#define TQT_TQPIXMAP_CONST(x) (static_cast<const TQPixmap*>(static_cast<const QPixmap*>(x)))
+#define TQT_TQPAINTDEVICE_CONST(x) (static_cast<const TQPaintDevice*>(static_cast<const QPaintDevice*>(x)))
+#define TQT_TQCOLOR_CONST(x) (static_cast<const TQColor*>(static_cast<const QColor*>(x)))
+#define TQT_TQPRINTER_CONST(x) (static_cast<const TQPrinter*>(static_cast<const QPrinter*>(x)))
+#define TQT_TQIODEVICE_CONST(x) (static_cast<const TQIODevice*>(static_cast<const QIODevice*>(x)))
+#define TQT_TQVARIANT_CONST(x) (static_cast<const TQVariant*>(static_cast<const QVariant*>(x)))
+#define TQT_TQMETAOBJECT_CONST(x) (static_cast<const TQMetaObject*>(static_cast<const QMetaObject*>(x)))
+#define TQT_TQSTYLEOPTION_CONST(x) (static_cast<const TQStyleOption*>(static_cast<const TQStyleOption*>(x)))
+
+#define TQPOINT_OBJECT_NAME_STRING "TQPoint"
+#define TQBYTEARRAY_OBJECT_NAME_STRING "TQByteArray"
+#define TQPIXMAP_OBJECT_NAME_STRING "TQPixmap"
+#define TQSTRING_OBJECT_NAME_STRING "TQString"
+#define TQSTRINGLIST_OBJECT_NAME_STRING "TQStringList"
+#define TQLAYOUT_OBJECT_NAME_STRING "TQLayout"
+#define TQBOXLAYOUT_OBJECT_NAME_STRING "TQBoxLayout"
+#define TQHBOXLAYOUT_OBJECT_NAME_STRING "TQHBoxLayout"
+#define TQVBOXLAYOUT_OBJECT_NAME_STRING "TQVBoxLayout"
+#define TQGRIDLAYOUT_OBJECT_NAME_STRING "TQGridLayout"
+#define TQHBOX_OBJECT_NAME_STRING "TQHBox"
+#define TQVBOX_OBJECT_NAME_STRING "TQVBox"
+#define TQGRID_OBJECT_NAME_STRING "TQGrid"
+#define TQTABWIDGET_OBJECT_NAME_STRING "TQTabWidget"
+#define TQCHECKBOX_OBJECT_NAME_STRING "TQCheckBox"
+#define TQLINEEDIT_OBJECT_NAME_STRING "TQLineEdit"
+#define TQTEXTEDIT_OBJECT_NAME_STRING "TQTextEdit"
+#define TQOBJECT_OBJECT_NAME_STRING "TQObject"
+#define TQWIDGET_OBJECT_NAME_STRING "TQWidget"
+#define TQGLWIDGET_OBJECT_NAME_STRING "TQGLWidget"
+#define TQLABEL_OBJECT_NAME_STRING "TQLabel"
+#define TQTIMER_OBJECT_NAME_STRING "TQTimer"
+#define TQFRAME_OBJECT_NAME_STRING "TQFrame"
+#define TQACCEL_OBJECT_NAME_STRING "TQAccel"
+#define TQDIALOG_OBJECT_NAME_STRING "TQDialog"
+#define TQDIAL_OBJECT_NAME_STRING "TQDial"
+#define TQACTION_OBJECT_NAME_STRING "TQAction"
+#define TQACTIONGROUP_OBJECT_NAME_STRING "TQActionGroup"
+#define TQLCDNUMBER_OBJECT_NAME_STRING "TQLCDNumber"
+#define TQPROGRESSBAR_OBJECT_NAME_STRING "TQProgressBar"
+#define TQTABDIALOG_OBJECT_NAME_STRING "TQTabDialog"
+#define TQTABWIDGET_OBJECT_NAME_STRING "TQTabWidget"
+#define TQDOCKWINDOW_OBJECT_NAME_STRING "TQDockWindow"
+#define TQGROUPBOX_OBJECT_NAME_STRING "TQGroupBox"
+#define TQCOMBOBOX_OBJECT_NAME_STRING "TQComboBox"
+#define TQSPINBOX_OBJECT_NAME_STRING "TQSpinBox"
+#define TQSPINWIDGET_OBJECT_NAME_STRING "TQSpinWidget"
+#define TQLISTBOX_OBJECT_NAME_STRING "TQListBox"
+#define TQTOOLBOX_OBJECT_NAME_STRING "TQToolBox"
+#define TQTOOLBOXBUTTON_OBJECT_NAME_STRING "TQToolBoxButton"
+#define TQVGROUPBOX_OBJECT_NAME_STRING "TQVGroupBox"
+#define TQSPLITTER_OBJECT_NAME_STRING "TQSplitter"
+#define TQSPLITTERHANDLE_OBJECT_NAME_STRING "TQSplitterHandle"
+#define TQBUTTON_OBJECT_NAME_STRING "TQButton"
+#define TQGRIDVIEW_OBJECT_NAME_STRING "TQGridView"
+#define TQSLIDER_OBJECT_NAME_STRING "TQSlider"
+#define TQPUSHBUTTON_OBJECT_NAME_STRING "TQPushButton"
+#define TQTOOLBUTTON_OBJECT_NAME_STRING "TQToolButton"
+#define TQRADIOBUTTON_OBJECT_NAME_STRING "TQRadioButton"
+#define TQPOPUPMENU_OBJECT_NAME_STRING "TQPopupMenu"
+#define TQTOOLBAR_OBJECT_NAME_STRING "TQToolBar"
+#define TQMENUBAR_OBJECT_NAME_STRING "TQMenuBar"
+#define TQTABBAR_OBJECT_NAME_STRING "TQTabBar"
+#define TQLISTVIEW_OBJECT_NAME_STRING "TQListView"
+#define TQSCROLLBAR_OBJECT_NAME_STRING "TQScrollBar"
+#define TQSCROLLVIEW_OBJECT_NAME_STRING "TQScrollView"
+#define TQRANGECONTROL_OBJECT_NAME_STRING "TQRangeControl"
+#define TQCANVASITEM_OBJECT_NAME_STRING "TQCanvasItem"
+#define TQICONVIEW_OBJECT_NAME_STRING "TQIconView"
+#define TQMULTILINEEDIT_OBJECT_NAME_STRING "TQMultiLineEdit"
+#define TQINTVALIDATOR_OBJECT_NAME_STRING "TQIntValidator"
+#define TQDATEEDIT_OBJECT_NAME_STRING "TQDateEdit"
+#define TQTIMEEDIT_OBJECT_NAME_STRING "TQTimeEdit"
+#define TQDATETIMEEDIT_OBJECT_NAME_STRING "TQDateTimeEdit"
+#define TQHEADER_OBJECT_NAME_STRING "TQHeader"
+#define TQSIZEGRIP_OBJECT_NAME_STRING "TQSizeGrip"
+#define TQDOCKWINDOWHANDLE_OBJECT_NAME_STRING "TQDockWindowHandle"
+#define TQHIDEDOCK_OBJECT_NAME_STRING "TQHideDock"
+#define TQTABLE_OBJECT_NAME_STRING "TQTable"
+#define TQWIZARD_OBJECT_NAME_STRING "TQWizard"
+#define TQDATATABLE_OBJECT_NAME_STRING "TQDataTable"
+#define TQDATABROWSER_OBJECT_NAME_STRING "TQDataBrowser"
+#define TQDATAVIEW_OBJECT_NAME_STRING "TQDataView"
+#define TQMAINWINDOW_OBJECT_NAME_STRING "TQMainWindow"
+#define TQWIDGETSTACK_OBJECT_NAME_STRING "TQWidgetStack"
+#define TQBUTTONGROUP_OBJECT_NAME_STRING "TQButtonGroup"
+#define TQTEXTVIEW_OBJECT_NAME_STRING "TQTextView"
+#define TQTEXTBROWSER_OBJECT_NAME_STRING "TQTextBrowser"
+#define TQLAYOUTWIDGET_OBJECT_NAME_STRING "TQLayoutWidget"
+
+#define TQMOTIFPLUSSTYLE_OBJECT_NAME_STRING "TQMotifPlusStyle"
+
+// #define tqarrowCursor Qt::ArrowCursor
+// #define tqupArrowCursor Qt::UpArrowCursor
+// #define tqcrossCursor Qt::CrossCursor
+// #define tqwaitCursor Qt::WaitCursor
+// #define tqibeamCursor Qt::IBeamCursor
+// #define tqsizeVerCursor Qt::SizeVerCursor
+// #define tqsizeHorCursor Qt::SizeHorCursor
+// #define tqsizeBDiagCursor Qt::SizeBDiagCursor
+// #define tqsizeFDiagCursor Qt::SizeFDiagCursor
+// #define tqsizeAllCursor Qt::SizeAllCursor
+// #define tqblankCursor Qt::BlankCursor
+// #define tqsplitVCursor Qt::SplitVCursor
+// #define tqsplitHCursor Qt::SplitHCursor
+// #define tqpointingHandCursor Qt::PointingHandCursor
+// #define tqforbiddenCursor Qt::ForbiddenCursor
+// #define tqwhatsThisCursor Qt::WhatsThisCursor
+// #define tqbusyCursor Qt::BusyCursor
+
+#define tqarrowCursor TQt::arrowCursor
+#define tqupArrowCursor TQt::upArrowCursor
+#define tqcrossCursor TQt::crossCursor
+#define tqwaitCursor TQt::waitCursor
+#define tqibeamCursor TQt::ibeamCursor
+#define tqsizeVerCursor TQt::sizeVerCursor
+#define tqsizeHorCursor TQt::sizeHorCursor
+#define tqsizeBDiagCursor TQt::sizeBDiagCursor
+#define tqsizeFDiagCursor TQt::sizeFDiagCursor
+#define tqsizeAllCursor TQt::sizeAllCursor
+#define tqblankCursor TQt::blankCursor
+#define tqsplitVCursor TQt::splitVCursor
+#define tqsplitHCursor TQt::splitHCursor
+#define tqpointingHandCursor TQt::pointingHandCursor
+#define tqforbiddenCursor TQt::forbiddenCursor
+#define tqwhatsThisCursor TQt::whatsThisCursor
+#define tqbusyCursor TQt::busyCursor
+
+#define tqreadBlock readData
+#define tqwriteBlock writeData
+#define TQT_TQIO_LONG qint64
+#define TQT_TQIO_ULONG qint64
+#define TQ_WFlags WFlags
+
+#define SET_QT_X_TIME(x) QX11Info::setAppTime(x)
+#define GET_QT_X_TIME(x) QX11Info::appTime()
+#define SET_QT_X_USER_TIME(x) QX11Info::setAppUserTime(x)
+#define GET_QT_X_USER_TIME(x) QX11Info::appUserTime()
+
+// // [FIXME]
+// // This should try a dynamic cast first before resorting to conversion (which entails a create/copy/delete operation)
+// // Also, is simply overwriting the origin pointer enough to make this work in all cases???
+// template <class T, class U>
+// U* tqt_convert_object(T* orig)
+// {
+// T* orig_ptr = orig;
+// U* temp = new U();
+// *temp = *orig;
+// orig_ptr = temp;
+// delete orig;
+// return temp;
+// }
+//
+// #define TQT_TQPIXMAP(x) (tqt_convert_object<QPixmap, TQPixmap>(x))
+// #define TQT_TQPIXMAP_CONST(x) (tqt_convert_object<const QPixmap, const TQPixmap>(x))
+
+// [NOTE]
+// It is IMPOSSIBLE to downcast an abstract base class [ABC] to a derived type. Period. End of story.
+// Think of it this way...is it ever possible to instantiate an ABC on its own (e.g. with new)? No!
+// Therefore, it is also impossible to copy an ABC.
+// static_cast won't work because an ABC has a completely different structure than a non abstract class.
+// Specifically, you will get segmentation faults in typeinfo for the ABC at runtime.
+// This is probably due to the complete absence of the abstract method implementations in the static_casted object.
+// The only exception that I can think of MIGHT be if NO CHANGES are made to the abstracted methods,
+// including addition, modification, or removal of said methods. Don't bet the farm on this however!
+
+// #define TQT_TQLAYOUTITEM_CONST(x) (static_cast<const TQLayoutItem*>(static_cast<const QLayoutItem*>(x)))
+
+// // [FIXME]
+// // This should try a dynamic cast first before resorting to conversion (which entails a create/copy/delete operation)
+// // There is half a chance that this sort of nasty hackery is only required for abstract base classes, such as QStyle and QLayoutItem
+// // For other class types a simple static_cast *might* suffice. [???]
+// template <class T, class U>
+// U* tqt_convert_object(T* orig)
+// {
+// T* orig_ptr = orig;
+// U* temp = new U();
+// *temp = *orig;
+// orig_ptr = temp;
+// delete orig;
+// return temp;
+// }
+//
+// #define TQT_TQLAYOUTITEM_CONST(x) (tqt_convert_object<const QLayoutItem, const TQLayoutItem>(x))
+
+// TQT_BASE_OBJECT is here for equality operators, as pointers will only be considered equal if the top (base) classes are compared
+// This is because all widget/extension/etc. classes will have one and only one TQT_BASE_OBJECT class instance in memory
+// Thus casting both pointers to TQT_BASE_OBJECT and comparing will reveal if the objects being compared are truly the same
+// For TQT 3 TQObject is the real base class, while in TQt 4 QObject is the real base class
+#define TQT_BASE_OBJECT_NAME QObject
+#define TQT_BASE_OBJECT(x) (static_cast<TQT_BASE_OBJECT_NAME*>(x))
+#define TQT_BASE_OBJECT_CONST(x) (static_cast<const TQT_BASE_OBJECT_NAME*>(x))
+
+// This can be used to change any object name within TQt
+// x is a QString or TQString
+#define TQT_OBJECT_NAME_HANDLER(x) TQString(x)
+
+// Safe casts
+template <class T>
+T tqt_dynamic_cast(TQT_BASE_OBJECT_NAME* a) { return dynamic_cast<T>(a); }
+
+template <class T>
+T tqt_dynamic_cast(const TQT_BASE_OBJECT_NAME* a) { return dynamic_cast<T>(a); }
+
+// Interface defines
+#define QABS(n) qAbs(n)
+#define QMIN(x, y) qMin(x, y)
+#define QMAX(x, y) qMax(x, y)
+
+#define tqt_mo_access access()
+#define tqt_mo_ci_name name()
+#define tqt_mo_ci_value value()
+#define tqt_mo_ci_count count()
+#define tqt_mo_ci_items items()
+#define tqt_mo_ci_method method()
+
+// [FIXME] The underlying problem in uic creating the need for these defines should probably be fixed sometime in the future...
+// See object.cpp e.g. line 571
+#define setTqmaximumSize setMaximumSize
+#define setTqminimumSize setMinimumSize
+#define setTqalignment tqsetAlignment
+#define setTqgeometry setGeometry
+
+#define Q_UINT16 quint16
+
+#define ttqqt_cast( x ) tqqt_cast(TQT_TQOBJECT(x))
+
+// TQT for Qt3 compatibility defines
+#define tqred red
+#define tqgreen green
+#define tqblue blue
+#define tqcyan cyan
+#define tqmagenta magenta
+#define tqyellow yellow
+#define tqdarkRed darkRed
+#define tqdarkGreen darkGreen
+#define tqdarkBlue darkBlue
+#define tqdarkCyan darkCyan
+#define tqdarkMagenta darkMagenta
+#define tqdarkYellow darkYellow
+#define tqwhite white
+#define tqwhiteptr &TQt::white
+#define tqlightGray lightGray
+#define tqgray gray
+#define tqdarkGray darkGray
+#define tqblack black
+#define tqblackptr &TQt::black
+#define tqcolor0 color0
+#define tqcolor1 color1
+
+// #define tqaccess access
+// #define tqcolorTable colorTable
+#define TQSO_Default Default
+// #define tqqt_cast ::qt_cast
+#define TQ_Alignment Qt::Alignment
+#define TQ_Horizontal Horizontal
+#define TQ_Vertical Vertical
+#define TQImage_ScaleFree ScaleFree
+#define TQ_Key_Shift Key_Shift
+#define TQ_Key_Control Key_Control
+#define TQ_Key_Alt Key_Alt
+#define TQ_Key_Meta Key_Meta
+#define TQ_Key_Super_L Key_Super_L
+#define TQ_Key_Super_R Key_Super_R
+#define TQ_Key_Hyper_L Key_Hyper_L
+#define TQ_Key_Hyper_R Key_Hyper_R
+#define TQ_ButtonState TQt::ButtonState
+#define TQ_LeftButton Qt::LeftButton
+#define TQ_MidButton Qt::MidButton
+#define TQ_RightButton Qt::RightButton
+#define TQ_ShiftButton ShiftButton
+#define TQ_ControlButton ControlButton
+#define TQ_AltButton AltButton
+#define TQ_MetaButton MetaButton
+#define TQ_ScaleFree ScaleFree
+#define TQ_ScaleMin ScaleMin
+#define TQ_ScaleMax ScaleMax
+#define TQ_ScaleMode ScaleMode
+#define TQ_StrongFocus Qt::StrongFocus
+#define TQ_NoFocus Qt::NoFocus
+#define TQ_WheelFocus Qt::WheelFocus
+#define TQ_ClickFocus Qt::ClickFocus
+#define TQ_TabFocus Qt::TabFocus
+#define TQ_FocusPolicy Qt::FocusPolicy
+#define TQ_SPExpandData Qt::Orientations
+#define TQIODevice_OpenModeFlag QIODevice::OpenModeFlag
+#define TQ_OpenMode OpenMode
+#define TQ_SPVertically (Qt::Orientations) TQSizePolicy::Vertically
+#define TQ_SPHorizontally (Qt::Orientations) TQSizePolicy::Horizontally
+#define TQ_SPNoDirection (Qt::Orientations) TQSizePolicy::NoDirection
+
+// #define Orientation Qt::Orientation
+
+// #define SubRect SubElement
+// #define SR_PushButtonContents SE_PushButtonContents
+// #define SR_PushButtonFocusRect SE_PushButtonFocusRect
+// #define SR_CheckBoxIndicator SE_CheckBoxIndicator
+// #define SR_CheckBoxContents SE_CheckBoxContents
+// #define SR_CheckBoxFocusRect SE_CheckBoxFocusRect
+// #define SR_RadioButtonIndicator SE_RadioButtonIndicator
+// #define SR_RadioButtonContents SE_RadioButtonContents
+// #define SR_RadioButtonFocusRect SE_RadioButtonFocusRect
+// #define SR_ComboBoxFocusRect SE_ComboBoxFocusRect
+// #define SR_SliderFocusRect SE_SliderFocusRect
+// #define SR_DockWindowHandleRect SE_DockWindowHandleRect
+// #define SR_ProgressBarGroove SE_ProgressBarGroove
+// #define SR_ProgressBarContents SE_ProgressBarContents
+// #define SR_ProgressBarLabel SE_ProgressBarLabel
+// #define SR_ToolButtonContents SE_ToolButtonContents
+// #define SR_DialogButtonAccept SE_DialogButtonAccept
+// #define SR_DialogButtonReject SE_DialogButtonReject
+// #define SR_DialogButtonApply SE_DialogButtonApply
+// #define SR_DialogButtonHelp SE_DialogButtonHelp
+// #define SR_DialogButtonAll SE_DialogButtonAll
+// #define SR_DialogButtonAbort SE_DialogButtonAbort
+// #define SR_DialogButtonIgnore SE_DialogButtonIgnore
+// #define SR_DialogButtonRetry SE_DialogButtonRetry
+// #define SR_DialogButtonCustom SE_DialogButtonCustom
+// #define SR_ToolBoxTabContents SE_ToolBoxTabContents
+// #define SR_CustomBase SE_CustomBase
+//
+// #define StylePixmap StandardPixmap
+// // #define SP_TitleBarMinButton SC_TitleBarMinButton
+// // #define SP_TitleBarMaxButton SC_TitleBarMaxButton
+// // #define SP_TitleBarCloseButton SC_TitleBarCloseButton
+// // #define SP_TitleBarNormalButton SC_TitleBarNormalButton
+// // #define SP_TitleBarShadeButton SC_TitleBarShadeButton
+// // #define SP_TitleBarUnshadeButton SC_TitleBarUnshadeButton
+// #define SP_DockWindowCloseButton SP_DockWidgetCloseButton
+// // #define SP_MessageBoxInformation SC_MessageBoxInformation
+// // #define SP_MessageBoxWarning SC_MessageBoxWarning
+// // #define SP_MessageBoxCritical SC_MessageBoxCritical
+// // #define SP_MessageBoxQuestion SC_MessageBoxQuestion
+// // #define SP_CustomBase SC_CustomBase
+//
+// #define StyleFlags StateFlags
+// #define Style_Default QStyle::State_Default
+// #define Style_Enabled QStyle::State_Enabled
+// #define Style_Raised QStyle::State_Raised
+// #define Style_Sunken QStyle::State_Sunken
+// #define Style_Off QStyle::State_Off
+// #define Style_NoChange QStyle::State_NoChange
+// #define Style_On QStyle::State_On
+// #define Style_Down QStyle::State_DownArrow
+// #define Style_Horizontal QStyle::State_Horizontal
+// #define Style_HasFocus QStyle::State_HasFocus
+// #define Style_To QStyle::State_To
+// #define Style_Bottom QStyle::State_Bottom
+// #define Style_FocusAtBorder QStyle::State_FocusAtBorder
+// #define Style_AutoRaise QStyle::State_AutoRaise
+// #define Style_MouseOver QStyle::State_MouseOver
+// #define Style_Up QStyle::State_UpArrow
+// #define Style_Selected QStyle::State_Selected
+// #define Style_Active QStyle::State_Active
+// #define Style_ButtonDefault QStyle::State_ButtonDefault
+//
+// #define PE_ArrowDown PE_IndicatorArrowDown
+// #define PE_ArrowUp PE_IndicatorArrowUp
+// #define PE_ButtonTool PE_PanelButtonTool
+// #define PE_DockWindowHandle PE_IndicatorToolBarHandle
+// #define PE_DockWindowSeparator PE_Q3DockWindowSeparator
+// // Verify this one -------------v
+// #define PE_FocusRect PE_FrameFocusRect
+// #define PE_Panel PE_Frame
+// #define PE_RubberBand CE_RubberBand
+// #define PE_ScrollBarAddLine CE_ScrollBarAddLine
+// #define PE_ScrollBarAddPage CE_ScrollBarAddPage
+// #define PE_ScrollBarFirst CE_ScrollBarFirst
+// #define PE_ScrollBarLast CE_ScrollBarLast
+// #define PE_ScrollBarSlider CE_ScrollBarSlider
+// #define PE_ScrollBarSubLine CE_ScrollBarSubLine
+// #define PE_ScrollBarSubPage CE_ScrollBarSubPage
+//
+// #define SC_ListView SC_Q3ListView
+// #define SC_ListViewBranch SC_Q3ListViewBranch
+// #define SC_ListViewExpand SC_Q3ListViewExpand
+//
+// #define CC_ListView CC_Q3ListView
+//
+// #define WState Qt::WidgetAttribute
+// #define WState_Polished Qt::WA_WState_Polished
+// //#define WState_ForceHide Qt::WA_WState_ForceHide
+// #define WState_ForceHide Qt::WA_WState_Hidden
+//
+// #define SH_PopupMenu_Scrollable SH_Menu_Scrollable
+// #define SH_PopupMenu_SloppySubMenus SH_Menu_SloppySubMenus
+// #define SH_PopupMenu_SubMenuPopupDelay SH_Menu_SubMenuPopupDelay
+// #define SH_PopupMenu_AllowActiveAndDisabled SH_Menu_AllowActiveAndDisabled
+// #define SH_PopupMenu_MouseTracking SH_Menu_MouseTracking
+//
+// #define CE_PopupMenuScroller CE_MenuScroller
+//
+// #define PM_DockWindowHandleExtent PM_DockWidgetHandleExtent
+// #define PM_MenuBarFrameWidth PM_ToolBarFrameWidth
+// #define PM_DockWindowFrameWidth PM_DockWidgetFrameWidth
+// #define PM_PopupMenuScrollerHeight PM_MenuScrollerHeight
+//
+// // #define WFlags Qt::WindowFlags
+
+#endif // USE_QT4
+
+#endif // TQTGLOBALDEFINES_H
diff --git a/tqtinterface/qt4/src/kernel/tqtglobalsettings.h b/tqtinterface/qt4/src/kernel/tqtglobalsettings.h
new file mode 100644
index 0000000..45cf9ac
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtglobalsettings.h
@@ -0,0 +1,7 @@
+#ifndef TQTGLOBALSETTINGS_H
+#define TQTGLOBALSETTINGS_H
+
+//#define USE_QT3
+#define USE_QT4
+
+#endif // TQTGLOBALSETTINGS_H \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqthread.cpp b/tqtinterface/qt4/src/kernel/tqthread.cpp
new file mode 100644
index 0000000..34667fa
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqthread.cpp
@@ -0,0 +1,241 @@
+/****************************************************************************
+**
+** Cross-platform TQThread implementation.
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifdef TQT_THREAD_SUPPORT
+
+#include "tqplatformdefs.h"
+
+#include "tqthread.h"
+#include <private/tqthreadinstance_p.h>
+
+#ifndef TQT_H
+# include "tqapplication.h"
+#endif // TQT_H
+
+#if TQT_VERSION >= 0x040000
+# error "Remove TQThread::TQThread() and TQThread::start()."
+#endif
+
+
+/*!
+ \class TQThread tqthread.h
+ \threadsafe
+ \brief The TQThread class provides platform-independent threads.
+
+ \ingroup thread
+ \ingroup environment
+
+ A TQThread represents a separate thread of control within the
+ program; it shares data with all the other threads within the
+ process but executes independently in the way that a separate
+ program does on a multitasking operating system. Instead of
+ starting in main(), TQThreads begin executing in run(). You inherit
+ run() to include your code. For example:
+
+ \code
+ class MyThread : public TQThread {
+
+ public:
+
+ virtual void run();
+
+ };
+
+ void MyThread::run()
+ {
+ for( int count = 0; count < 20; count++ ) {
+ sleep( 1 );
+ qDebug( "Ping!" );
+ }
+ }
+
+ int main()
+ {
+ MyThread a;
+ MyThread b;
+ a.start();
+ b.start();
+ a.wait();
+ b.wait();
+ }
+ \endcode
+
+ This will start two threads, each of which writes Ping! 20 times
+ to the screen and exits. The wait() calls at the end of main() are
+ necessary because exiting main() ends the program, unceremoniously
+ killing all other threads. Each MyThread stops executing when it
+ reaches the end of MyThread::run(), just as an application does
+ when it leaves main().
+
+ \sa \link threads.html Thread Support in TQt\endlink.
+*/
+
+/*!
+ \enum TQThread::Priority
+
+ This enum type indicates how the operating system should schedule
+ newly created threads.
+
+ \value IdlePriority scheduled only when no other threads are
+ running.
+
+ \value LowestPriority scheduled less often than LowPriority.
+ \value LowPriority scheduled less often than NormalPriority.
+
+ \value NormalPriority the default priority of the operating
+ system.
+
+ \value HighPriority scheduled more often than NormalPriority.
+ \value HighestPriority scheduled more often then HighPriority.
+
+ \value TimeCriticalPriority scheduled as often as possible.
+
+ \value InheritPriority use the same priority as the creating
+ thread. This is the default.
+*/
+
+TQThread::TQThread()
+{
+ d = new TQThreadInstance;
+ d->init(0);
+}
+
+/*!
+ Constructs a new thread. The thread does not begin executing until
+ start() is called.
+
+ If \a stackSize is greater than zero, the maximum stack size is
+ set to \a stackSize bytes, otherwise the maximum stack size is
+ automatically determined by the operating system.
+
+ \warning Most operating systems place minimum and maximum limits
+ on thread stack sizes. The thread will fail to start if the stack
+ size is outside these limits.
+*/
+TQThread::TQThread( unsigned int stackSize )
+{
+ d = new TQThreadInstance;
+ d->init(stackSize);
+}
+
+/*!
+ TQThread destructor.
+
+ Note that deleting a TQThread object will not stop the execution of
+ the thread it represents. Deleting a running TQThread (i.e.
+ finished() returns FALSE) will probably result in a program crash.
+ You can wait() on a thread to make sure that it has finished.
+*/
+TQThread::~TQThread()
+{
+ TQMutexLocker locker( d->mutex() );
+ if ( d->running && !d->finished ) {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQThread object destroyed while thread is still running.");
+#endif
+
+ d->orphan = TRUE;
+ return;
+ }
+
+ d->deinit();
+ delete d;
+}
+
+/*!
+ This function terminates the execution of the thread. The thread
+ may or may not be terminated immediately, depending on the
+ operating system's scheduling policies. Use TQThread::wait()
+ after terminate() for synchronous termination.
+
+ When the thread is terminated, all threads waiting for the
+ the thread to finish will be woken up.
+
+ \warning This function is dangerous, and its use is discouraged.
+ The thread can be terminated at any point in its code path. Threads
+ can be terminated while modifying data. There is no chance for
+ the thread to cleanup after itself, unlock any held mutexes, etc.
+ In short, use this function only if \e absolutely necessary.
+*/
+void TQThread::terminate()
+{
+ TQMutexLocker locker( d->mutex() );
+ if ( d->finished || !d->running )
+ return;
+ d->terminate();
+}
+
+/*!
+ Returns TRUE if the thread is finished; otherwise returns FALSE.
+*/
+bool TQThread::finished() const
+{
+ TQMutexLocker locker( d->mutex() );
+ return d->finished;
+}
+
+/*!
+ Returns TRUE if the thread is running; otherwise returns FALSE.
+*/
+bool TQThread::running() const
+{
+ TQMutexLocker locker( d->mutex() );
+ return d->running;
+}
+
+/*!
+ \fn void TQThread::run()
+
+ This method is pure virtual, and must be implemented in derived
+ classes in order to do useful work. Returning from this method
+ will end the execution of the thread.
+
+ \sa wait()
+*/
+
+#ifndef TQT_NO_COMPAT
+/*! \obsolete
+ Use TQApplication::postEvent() instead.
+*/
+void TQThread::postEvent( TQObject * receiver, TQEvent * event )
+{
+ TQApplication::postEvent( receiver, event );
+}
+#endif
+
+#endif // TQT_THREAD_SUPPORT
diff --git a/tqtinterface/qt4/src/kernel/tqthread.h b/tqtinterface/qt4/src/kernel/tqthread.h
new file mode 100644
index 0000000..3d5c51e
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqthread.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Definition of TQThread class
+**
+** Created : 931107
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTHREAD_H
+#define TQTHREAD_H
+
+#if defined(TQT_THREAD_SUPPORT)
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#ifndef TQT_NO_COMPAT
+#include "tqmutex.h"
+#include "tqsemaphore.h"
+#include "tqwaitcondition.h"
+#endif // TQT_NO_COMPAT
+#endif // TQT_H
+
+#include <limits.h>
+
+class TQThreadInstance;
+
+class TQ_EXPORT TQThread : public TQt
+{
+public:
+ static TQt::HANDLE currentThread();
+
+#ifndef TQT_NO_COMPAT
+ static void postEvent( TQObject *,TQEvent * );
+#endif
+
+ static void initialize();
+ static void cleanup();
+
+ static void exit();
+
+#ifdef TQ_TQDOC
+ TQThread( unsigned int stackSize = 0 );
+#else
+ TQThread( unsigned int stackSize );
+ TQThread();
+#endif
+
+ virtual ~TQThread();
+
+ // default argument causes thread to block indefinately
+ bool wait( unsigned long time = ULONG_MAX );
+
+ enum Priority {
+ IdlePriority,
+
+ LowestPriority,
+ LowPriority,
+ NormalPriority,
+ HighPriority,
+ HighestPriority,
+
+ TimeCriticalPriority,
+
+ InheritPriority
+ };
+
+#ifdef TQ_TQDOC
+ void start( Priority = InheritPriority );
+#else
+ void start( Priority );
+ void start();
+#endif
+
+ void terminate();
+
+ bool finished() const;
+ bool running() const;
+
+protected:
+ virtual void run() = 0;
+
+ static void sleep( unsigned long );
+ static void msleep( unsigned long );
+ static void usleep( unsigned long );
+
+private:
+ TQThreadInstance * d;
+ friend class TQThreadInstance;
+
+#if defined(TQ_DISABLE_COPY)
+ TQThread( const TQThread & );
+ TQThread &operator=( const TQThread & );
+#endif // TQ_DISABLE_COPY
+};
+
+#endif // TQT_THREAD_SUPPORT
+
+#endif // TQTHREAD_H
diff --git a/tqtinterface/qt4/src/kernel/tqthread_unix.cpp b/tqtinterface/qt4/src/kernel/tqthread_unix.cpp
new file mode 100644
index 0000000..11a1a90
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqthread_unix.cpp
@@ -0,0 +1,474 @@
+/****************************************************************************
+**
+** TQThread class for Unix
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#if defined(TQT_THREAD_SUPPORT)
+
+#include "tqplatformdefs.h"
+
+typedef pthread_mutex_t TQ_MUTEX_T;
+
+#include "tqthread.h"
+#include <private/tqthreadinstance_p.h>
+#include <private/tqmutex_p.h>
+#include <private/tqmutexpool_p.h>
+#include <tqthreadstorage.h>
+
+#include <errno.h>
+#include <sched.h>
+
+
+static TQThreadInstance main_instance = {
+ 0, { 0, &main_instance }, 0, 0, 1, 0, PTHREAD_COND_INITIALIZER, 0
+};
+
+
+static TQMutexPool *qt_thread_mutexpool = 0;
+
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+typedef void*(*TQtThreadCallback)(void*);
+
+static pthread_once_t storage_key_once = PTHREAD_ONCE_INIT;
+static pthread_key_t storage_key;
+static void create_storage_key()
+{
+ pthread_key_create( &storage_key, NULL );
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+/**************************************************************************
+ ** TQThreadInstance
+ *************************************************************************/
+
+TQThreadInstance *TQThreadInstance::current()
+{
+ pthread_once( &storage_key_once, create_storage_key );
+ TQThreadInstance *ret = (TQThreadInstance *) pthread_getspecific( storage_key );
+ return ret;
+}
+
+void TQThreadInstance::init(unsigned int stackSize)
+{
+ stacksize = stackSize;
+ args[0] = args[1] = 0;
+ thread_storage = 0;
+ finished = FALSE;
+ running = FALSE;
+ orphan = FALSE;
+
+ pthread_cond_init(&thread_done, NULL);
+ thread_id = 0;
+
+ // threads have not been initialized yet, do it now
+ if (! qt_thread_mutexpool) TQThread::initialize();
+}
+
+void TQThreadInstance::deinit()
+{
+ pthread_cond_destroy(&thread_done);
+}
+
+void *TQThreadInstance::start( void *_arg )
+{
+ void **arg = (void **) _arg;
+
+ pthread_once( &storage_key_once, create_storage_key );
+ pthread_setspecific( storage_key, arg[1] );
+ pthread_cleanup_push( TQThreadInstance::finish, arg[1] );
+ pthread_testcancel();
+
+ ( (TQThread *) arg[0] )->run();
+
+ pthread_cleanup_pop( TRUE );
+ return 0;
+}
+
+void TQThreadInstance::finish( void * )
+{
+ TQThreadInstance *d = current();
+
+ if ( ! d ) {
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQThread: internal error: zero data for running thread." );
+#endif // TQT_CHECK_STATE
+ return;
+ }
+
+ TQMutexLocker locker( d->mutex() );
+ d->running = FALSE;
+ d->finished = TRUE;
+ d->args[0] = d->args[1] = 0;
+
+
+ TQThreadStorageData::finish( d->thread_storage );
+ d->thread_storage = 0;
+
+ d->thread_id = 0;
+ pthread_cond_broadcast(&d->thread_done);
+
+ if (d->orphan) {
+ d->deinit();
+ delete d;
+ }
+}
+
+TQMutex *TQThreadInstance::mutex() const
+{
+ return qt_thread_mutexpool ? qt_thread_mutexpool->get( (void *) this ) : 0;
+}
+
+void TQThreadInstance::terminate()
+{
+ if ( ! thread_id ) return;
+ pthread_cancel( thread_id );
+}
+
+
+/**************************************************************************
+ ** TQThread
+ *************************************************************************/
+
+/*!
+ This returns the thread handle of the currently executing thread.
+
+ \warning The handle returned by this function is used for internal
+ purposes and should \e not be used in any application code. On
+ Windows, the returned value is a pseudo handle for the current
+ thread, and it cannot be used for numerical comparison.
+*/
+TQt::HANDLE TQThread::currentThread()
+{
+ return (HANDLE) pthread_self();
+}
+
+/*! \internal
+ Initializes the TQThread system.
+*/
+void TQThread::initialize()
+{
+ if ( ! tqt_global_mutexpool )
+ tqt_global_mutexpool = new TQMutexPool( TRUE, 73 );
+ if ( ! qt_thread_mutexpool )
+ qt_thread_mutexpool = new TQMutexPool( FALSE, 127 );
+
+ pthread_once( &storage_key_once, create_storage_key );
+ pthread_setspecific( storage_key, &main_instance );
+}
+
+/*! \internal
+ Cleans up the TQThread system.
+*/
+void TQThread::cleanup()
+{
+ delete tqt_global_mutexpool;
+ delete qt_thread_mutexpool;
+ tqt_global_mutexpool = 0;
+ qt_thread_mutexpool = 0;
+
+ TQThreadInstance::finish(&main_instance);
+
+ pthread_once( &storage_key_once, create_storage_key );
+ pthread_setspecific( storage_key, 0 );
+}
+
+/*!
+ Ends the execution of the calling thread and wakes up any threads
+ waiting for its termination.
+*/
+void TQThread::exit()
+{
+ pthread_exit( 0 );
+}
+
+/* \internal
+ helper function to do thread sleeps, since usleep()/nanosleep()
+ aren't reliable enough (in terms of behavior and availability)
+*/
+static void thread_sleep( struct timespec *ti )
+{
+ pthread_mutex_t mtx;
+ pthread_cond_t cnd;
+
+ pthread_mutex_init(&mtx, 0);
+ pthread_cond_init(&cnd, 0);
+
+ pthread_mutex_lock( &mtx );
+ (void) pthread_cond_timedwait( &cnd, &mtx, ti );
+ pthread_mutex_unlock( &mtx );
+
+ pthread_cond_destroy( &cnd );
+ pthread_mutex_destroy( &mtx );
+}
+
+/*!
+ System independent sleep. This causes the current thread to sleep
+ for \a secs seconds.
+*/
+void TQThread::sleep( unsigned long secs )
+{
+ struct timeval tv;
+ gettimeofday( &tv, 0 );
+ struct timespec ti;
+ ti.tv_sec = tv.tv_sec + secs;
+ ti.tv_nsec = ( tv.tv_usec * 1000 );
+ thread_sleep( &ti );
+}
+
+/*!
+ System independent sleep. This causes the current thread to sleep
+ for \a msecs milliseconds
+*/
+void TQThread::msleep( unsigned long msecs )
+{
+ struct timeval tv;
+ gettimeofday( &tv, 0 );
+ struct timespec ti;
+
+ ti.tv_nsec = ( tv.tv_usec + ( msecs % 1000 ) * 1000 ) * 1000;
+ ti.tv_sec = tv.tv_sec + ( msecs / 1000 ) + ( ti.tv_nsec / 1000000000 );
+ ti.tv_nsec %= 1000000000;
+ thread_sleep( &ti );
+}
+
+/*!
+ System independent sleep. This causes the current thread to sleep
+ for \a usecs microseconds
+*/
+void TQThread::usleep( unsigned long usecs )
+{
+ struct timeval tv;
+ gettimeofday( &tv, 0 );
+ struct timespec ti;
+
+ ti.tv_nsec = ( tv.tv_usec + ( usecs % 1000000 ) ) * 1000;
+ ti.tv_sec = tv.tv_sec + ( usecs / 1000000 ) + ( ti.tv_nsec / 1000000000 );
+ ti.tv_nsec %= 1000000000;
+ thread_sleep( &ti );
+}
+
+/*!
+ Begins execution of the thread by calling run(), which should be
+ reimplemented in a TQThread subclass to contain your code. The
+ operating system will schedule the thread according to the \a
+ priority argument.
+
+ If you try to start a thread that is already running, this
+ function will wait until the the thread has finished and then
+ restart the thread.
+
+ \sa Priority
+*/
+void TQThread::start(Priority priority)
+{
+ TQMutexLocker locker( d->mutex() );
+
+ if ( d->running )
+ pthread_cond_wait(&d->thread_done, &locker.mutex()->d->handle);
+ d->running = TRUE;
+ d->finished = FALSE;
+
+ int ret;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+#if !defined(TQ_OS_OPENBSD) && defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING-0 >= 0)
+ switch (priority) {
+ case InheritPriority:
+ {
+ pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+ break;
+ }
+
+ default:
+ {
+ int sched_policy;
+ if (pthread_attr_getschedpolicy(&attr, &sched_policy) != 0) {
+ // failed to get the scheduling policy, don't bother
+ // setting the priority
+ qWarning("TQThread: cannot determine default scheduler policy");
+ break;
+ }
+
+ int prio_min = sched_get_priority_min(sched_policy);
+ int prio_max = sched_get_priority_max(sched_policy);
+ if (prio_min == -1 || prio_max == -1) {
+ // failed to get the scheduling parameters, don't
+ // bother setting the priority
+ qWarning("TQThread: cannot determine scheduler priority range");
+ break;
+ }
+
+ int prio;
+ switch (priority) {
+ case IdlePriority:
+ prio = prio_min;
+ break;
+
+ case HighestPriority:
+ prio = prio_max;
+ break;
+
+ default:
+ // crudely scale our priority enum values to the prio_min/prio_max
+ prio = (((prio_max - prio_min) / TimeCriticalPriority) *
+ priority) + prio_min;
+ prio = TQMAX(prio_min, TQMIN(prio_max, prio));
+ break;
+ }
+
+ sched_param sp;
+ sp.sched_priority = prio;
+
+ pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
+ pthread_attr_setschedparam(&attr, &sp);
+ break;
+ }
+ }
+#endif // _POSIX_THREAD_PRIORITY_SCHEDULING
+
+ if ( d->stacksize > 0 ) {
+#if defined(_POSIX_THREAD_ATTR_STACKSIZE) && (_POSIX_THREAD_ATTR_STACKSIZE-0 > 0)
+ ret = pthread_attr_setstacksize( &attr, d->stacksize );
+#else
+ ret = ENOSYS; // stack size not supported, automatically fail
+#endif // _POSIX_THREAD_ATTR_STACKSIZE
+
+ if ( ret ) {
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQThread::start: thread stack size error: %s", strerror( ret ) ) ;
+#endif // TQT_CHECK_STATE
+
+ // we failed to set the stacksize, and as the documentation states,
+ // the thread will fail to run...
+ d->running = FALSE;
+ d->finished = FALSE;
+ return;
+ }
+ }
+
+ d->args[0] = this;
+ d->args[1] = d;
+ ret = pthread_create( &d->thread_id, &attr, (TQtThreadCallback)TQThreadInstance::start, d->args );
+#if defined (TQ_OS_HPUX)
+ if (ret == EPERM) {
+ pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
+ ret = pthread_create(&d->thread_id, &attr, (TQtThreadCallback)TQThreadInstance::start, d->args);
+ }
+#endif
+ pthread_attr_destroy( &attr );
+
+ if ( ret ) {
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQThread::start: thread creation error: %s", strerror( ret ) );
+#endif // TQT_CHECK_STATE
+
+ d->running = FALSE;
+ d->finished = FALSE;
+ d->args[0] = d->args[1] = 0;
+ }
+}
+
+void TQThread::start()
+{
+ start(InheritPriority);
+}
+
+/*!
+ A thread calling this function will block until either of these
+ conditions is met:
+
+ \list
+ \i The thread associated with this TQThread object has finished
+ execution (i.e. when it returns from \l{run()}). This function
+ will return TRUE if the thread has finished. It also returns
+ TRUE if the thread has not been started yet.
+ \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
+ default), then the wait will never timeout (the thread must
+ return from \l{run()}). This function will return FALSE if the
+ wait timed out.
+ \endlist
+
+ This provides similar functionality to the POSIX \c pthread_join() function.
+*/
+bool TQThread::wait( unsigned long time )
+{
+ TQMutexLocker locker( d->mutex() );
+
+ if ( d->thread_id == pthread_self() ) {
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQThread::wait: thread tried to wait on itself" );
+#endif // TQT_CHECK_STATE
+
+ return FALSE;
+ }
+
+ if ( d->finished || ! d->running )
+ return TRUE;
+
+ int ret;
+ if (time != ULONG_MAX) {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+
+ timespec ti;
+ ti.tv_nsec = (tv.tv_usec + (time % 1000) * 1000) * 1000;
+ ti.tv_sec = tv.tv_sec + (time / 1000) + (ti.tv_nsec / 1000000000);
+ ti.tv_nsec %= 1000000000;
+
+ ret = pthread_cond_timedwait(&d->thread_done, &locker.mutex()->d->handle, &ti);
+ } else
+ ret = pthread_cond_wait(&d->thread_done, &locker.mutex()->d->handle);
+
+#ifdef TQT_CHECK_RANGE
+ if (ret && ret != ETIMEDOUT)
+ qWarning("Wait condition wait failure: %s",strerror(ret));
+#endif
+
+ return (ret == 0);
+}
+
+
+#endif // TQT_THREAD_SUPPORT
diff --git a/tqtinterface/qt4/src/kernel/tqtimer.cpp b/tqtinterface/qt4/src/kernel/tqtimer.cpp
new file mode 100644
index 0000000..d1a98e1
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtimer.cpp
@@ -0,0 +1,350 @@
+/****************************************************************************
+**
+** Implementation of TQTimer class
+**
+** Created : 931111
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtimer.h"
+#include "tqsignal.h"
+#include "tqobjectlist.h"
+
+#ifdef USE_QT4
+#include <Qt/qtimer.h>
+#endif // USE_QT4
+
+/*!
+ \class TQTimer tqtimer.h
+ \brief The TQTimer class provides timer Q_SIGNALS and single-shot timers.
+
+ \ingroup time
+ \ingroup events
+ \mainclass
+
+ It uses \link TQTimerEvent timer events\endlink internally to
+ provide a more versatile timer. TQTimer is very easy to use:
+ create a TQTimer, call start() to start it and connect its
+ timeout() to the appropriate Q_SLOTS. When the time is up it will
+ emit the timeout() signal.
+
+ Note that a TQTimer object is destroyed automatically when its
+ tqparent object is destroyed.
+
+ Example:
+ \code
+ TQTimer *timer = new TQTimer( myObject );
+ connect( timer, TQT_SIGNAL(timeout()), myObject, TQT_SLOT(timerDone()) );
+ timer->start( 2000, TRUE ); // 2 seconds single-shot timer
+ \endcode
+
+ You can also use the static singleShot() function to create a
+ single shot timer.
+
+ As a special case, a TQTimer with timeout 0 times out as soon as
+ all the events in the window system's event queue have been
+ processed.
+
+ This can be used to do heavy work while providing a snappy
+ user interface:
+ \code
+ TQTimer *t = new TQTimer( myObject );
+ connect( t, TQT_SIGNAL(timeout()), TQT_SLOT(processOneThing()) );
+ t->start( 0, FALSE );
+ \endcode
+
+ myObject->processOneThing() will be called repeatedly and should
+ return quickly (typically after processing one data item) so that
+ TQt can deliver events to widgets and stop the timer as soon as it
+ has done all its work. This is the traditional way of
+ implementing heavy work in GUI applications; multi-threading is
+ now becoming available on more and more platforms, and we expect
+ that null events will eventually be tqreplaced by threading.
+
+ Note that TQTimer's accuracy depends on the underlying operating
+ system and hardware. Most platforms support an accuracy of 20ms;
+ some provide more. If TQt is unable to deliver the requested
+ number of timer clicks, it will silently discard some.
+
+ An alternative to using TQTimer is to call TQObject::startTimer()
+ for your object and reimplement the TQObject::timerEvent() event
+ handler in your class (which must, of course, inherit TQObject).
+ The disadvantage is that timerEvent() does not support such
+ high-level features as single-shot timers or Q_SIGNALS.
+
+ Some operating systems limit the number of timers that may be
+ used; TQt tries to work around these limitations.
+*/
+
+
+static const int INV_TIMER = -1; // invalid timer id
+
+
+/*!
+ Constructs a timer called \a name, with the tqparent \a tqparent.
+
+ Note that the tqparent object's destructor will destroy this timer
+ object.
+*/
+
+TQTimer::TQTimer( TQT_BASE_OBJECT_NAME *tqparent, const char *name )
+ : TQObject( tqparent, name ), id(INV_TIMER), single(0), nulltimer(0)
+{
+}
+
+/*!
+ Destroys the timer.
+*/
+
+TQTimer::~TQTimer()
+{
+ if ( id != INV_TIMER ) // stop running timer
+ stop();
+}
+
+
+/*!
+ \fn void TQTimer::timeout()
+
+ This signal is emitted when the timer is activated.
+*/
+
+/*!
+ \fn bool TQTimer::isActive() const
+
+ Returns TRUE if the timer is running (pending); otherwise returns
+ FALSE.
+*/
+
+/*!
+ \fn int TQTimer::timerId() const
+
+ Returns the ID of the timer if the timer is running; otherwise returns
+ -1.
+*/
+
+
+/*!
+ Starts the timer with a \a msec milliseconds timeout, and returns
+ the ID of the timer, or zero when starting the timer failed.
+
+ If \a sshot is TRUE, the timer will be activated only once;
+ otherwise it will continue until it is stopped.
+
+ Any pending timer will be stopped.
+
+ \sa singleShot() stop(), changeInterval(), isActive()
+*/
+
+int TQTimer::start( int msec, bool sshot )
+{
+ if ( id >=0 && nulltimer && !msec && sshot )
+ return id;
+ if ( id != INV_TIMER ) // stop running timer
+ stop();
+ single = sshot;
+ nulltimer = ( !msec && sshot );
+ return id = startTimer( msec );
+}
+
+
+/*!
+ Changes the timeout interval to \a msec milliseconds.
+
+ If the timer signal is pending, it will be stopped and restarted;
+ otherwise it will be started.
+
+ \sa start(), isActive()
+*/
+
+void TQTimer::changeInterval( int msec )
+{
+ if ( id == INV_TIMER ) { // create new timer
+ start( msec );
+ } else {
+ killTimer( id ); // restart timer
+ id = startTimer( msec );
+ }
+}
+
+/*!
+ Stops the timer.
+
+ \sa start()
+*/
+
+void TQTimer::stop()
+{
+ if ( id != INV_TIMER ) {
+ killTimer( id );
+ id = INV_TIMER;
+ }
+}
+
+
+/*!
+ \reimp
+*/
+bool TQTimer::event( TQEvent *e )
+{
+ if ( e->type() != TQEvent::Timer ) // ignore all other events
+ return FALSE;
+ if ( single ) // stop single shot timer
+ stop();
+ emit timeout(); // emit timeout signal
+ return TRUE;
+}
+
+
+/*
+ The TQSingleShotTimer class is an internal class for implementing
+ TQTimer::singleShot(). It starts a timer and emits the signal
+ and kills itself when it gets the timeout.
+*/
+
+static TQObjectList *sst_list = 0; // list of single shot timers
+
+static void sst_cleanup()
+{
+ if ( sst_list ) {
+ sst_list->setAutoDelete( TRUE );
+ delete sst_list;
+ sst_list = 0;
+ }
+}
+
+static void sst_init()
+{
+ if ( !sst_list ) {
+ sst_list = new TQObjectList;
+ TQ_CHECK_PTR( sst_list );
+ qAddPostRoutine( sst_cleanup );
+ }
+}
+
+
+class TQSingleShotTimer : public TQObject
+{
+public:
+ ~TQSingleShotTimer();
+ bool start( int msec, TQT_BASE_OBJECT_NAME *r, const char * m );
+ bool isActive() const { return timerId > 0; }
+protected:
+ bool event( TQEvent * );
+private:
+ TQSignal signal;
+ int timerId;
+};
+
+extern int qStartTimer( int interval, TQObject *obj ); // implemented in qapp_xxx.cpp
+extern bool qKillTimer( int id );
+
+TQSingleShotTimer::~TQSingleShotTimer()
+{
+ if (timerId != 0) {
+ qKillTimer(timerId);
+ timerId = 0;
+ }
+}
+
+bool TQSingleShotTimer::start( int msec, TQT_BASE_OBJECT_NAME *r, const char *m )
+{
+ timerId = 0;
+ if ( signal.connect(TQT_TQOBJECT(r), m) )
+ timerId = qStartTimer( msec, TQT_TQOBJECT(this) );
+ return timerId != 0;
+}
+
+bool TQSingleShotTimer::event( TQEvent * )
+{
+ qKillTimer( timerId ); // no more timeouts
+ signal.activate(); // emit the signal
+ signal.disconnect( 0, 0 );
+ timerId = 0; // mark as inactive
+ return TRUE;
+}
+
+
+/*!
+ This static function calls a slot after a given time interval.
+
+ It is very convenient to use this function because you do not need
+ to bother with a \link TQObject::timerEvent() timerEvent\endlink or
+ to create a local TQTimer object.
+
+ Example:
+ \code
+ #include <tqapplication.h>
+ #include <tqtimer.h>
+
+ int main( int argc, char **argv )
+ {
+ TQApplication a( argc, argv );
+ TQTimer::singleShot( 10*60*1000, &a, TQT_SLOT(quit()) );
+ ... // create and show your widgets
+ return a.exec();
+ }
+ \endcode
+
+ This sample program automatically terminates after 10 minutes (i.e.
+ 600000 milliseconds).
+
+ The \a receiver is the receiving object and the \a member is the
+ slot. The time interval is \a msec.
+*/
+
+#ifdef USE_QT4
+void TQTimer::singleShot( int msec, TQT_BASE_OBJECT_NAME *receiver, const char *member )
+{
+ // Cheat!
+ QTimer::singleShot(msec, receiver, member);
+}
+#else // USE_QT4
+void TQTimer::singleShot( int msec, TQT_BASE_OBJECT_NAME *receiver, const char *member )
+{
+ if ( !sst_list )
+ sst_init();
+ // search the list for a free ss timer we could reuse
+ TQSingleShotTimer *sst = (TQSingleShotTimer*)sst_list->first();
+ while ( sst && sst->isActive() )
+ sst = (TQSingleShotTimer*)sst_list->next();
+ // create a new one if not successful
+ if ( !sst ) {
+ sst = new TQSingleShotTimer;
+ sst_list->append( sst );
+ }
+ sst->start(msec, receiver, member);
+}
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqtimer.h b/tqtinterface/qt4/src/kernel/tqtimer.h
new file mode 100644
index 0000000..1d2398a
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtimer.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Definition of TQTimer class
+**
+** Created : 931111
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTIMER_H
+#define TQTIMER_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+
+
+class TQ_EXPORT TQTimer : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQTimer( TQT_BASE_OBJECT_NAME *tqparent=0, const char *name=0 );
+ ~TQTimer();
+
+ bool isActive() const;
+
+ int start( int msec, bool sshot = FALSE );
+ void changeInterval( int msec );
+ void stop();
+
+ static void singleShot( int msec, TQT_BASE_OBJECT_NAME *receiver, const char *member );
+
+ int timerId() const { return id; }
+
+Q_SIGNALS:
+ void timeout();
+
+protected:
+ bool event( TQEvent * );
+
+private:
+ int id;
+ uint single : 1;
+ uint nulltimer : 1;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQTimer( const TQTimer & );
+ TQTimer &operator=( const TQTimer & );
+#endif
+};
+
+
+inline bool TQTimer::isActive() const
+{
+ return id >= 0;
+}
+
+
+#endif // TQTIMER_H
diff --git a/tqtinterface/qt4/src/kernel/tqtranslator.cpp b/tqtinterface/qt4/src/kernel/tqtranslator.cpp
new file mode 100644
index 0000000..ec0856b
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtranslator.cpp
@@ -0,0 +1,2438 @@
+/****************************************************************************
+**
+** Localization database support.
+**
+** Created : 980906
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// POSIX Large File Support redefines open -> open64
+static inline int qt_open(const char *pathname, int flags, mode_t mode)
+{ return ::open(pathname, flags, mode); }
+#if defined(open)
+# undef open
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+#include "tqtranslator.h"
+
+#ifndef TQT_NO_TRANSLATION
+
+#include "tqfileinfo.h"
+#include "tqwidgetlist.h"
+#include "tqintdict.h"
+#include "tqstring.h"
+#include "tqapplication.h"
+#include "tqfile.h"
+#include "tqbuffer.h"
+#include "tqdatastream.h"
+#include "tqmap.h"
+#include "tqtl.h"
+
+#if defined(TQ_OS_UNIX)
+#define TQT_USE_MMAP
+#endif
+
+// most of the headers below are already included in qplatformdefs.h
+// also this lacks Large File support but that's probably irrelevant
+#if defined(TQT_USE_MMAP)
+// for mmap
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <errno.h>
+// for htonl
+#include <netinet/in.h>
+#endif
+
+#include <stdlib.h>
+
+#ifdef USE_QT4
+
+// magic number for the file
+static const int MagicLength = 16;
+static const uchar magic[MagicLength] = {
+ 0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,
+ 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd
+};
+
+static bool match( const char* found, const char* target )
+{
+ // 0 means anything, "" means empty
+ return found == 0 || qstrcmp( found, target ) == 0;
+}
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+/*
+ Yes, unfortunately, we have code here that depends on endianness.
+ The candidate is big endian (it comes from a .qm file) whereas the
+ target endianness depends on the system TQt is running on.
+*/
+#ifdef TQ_OS_TEMP
+static int __cdecl cmp_uint32_little( const void* target, const void* candidate )
+#else
+static int cmp_uint32_little( const void* target, const void* candidate )
+#endif
+{
+ const uchar* t = (const uchar*) target;
+ const uchar* c = (const uchar*) candidate;
+ return t[3] != c[0] ? (int) t[3] - (int) c[0]
+ : t[2] != c[1] ? (int) t[2] - (int) c[1]
+ : t[1] != c[2] ? (int) t[1] - (int) c[2]
+ : (int) t[0] - (int) c[3];
+}
+
+#ifdef TQ_OS_TEMP
+static int __cdecl cmp_uint32_big( const void* target, const void* candidate )
+#else
+static int cmp_uint32_big( const void* target, const void* candidate )
+#endif
+{
+ const uchar* t = (const uchar*) target;
+ const uchar* c = (const uchar*) candidate;
+ return t[0] != c[0] ? (int) t[0] - (int) c[0]
+ : t[1] != c[1] ? (int) t[1] - (int) c[1]
+ : t[2] != c[2] ? (int) t[2] - (int) c[2]
+ : (int) t[3] - (int) c[3];
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+static int systemWordSize = 0;
+static bool systemBigEndian;
+
+static uint elfHash( const char * name )
+{
+ const uchar *k;
+ uint h = 0;
+ uint g;
+
+ if ( name ) {
+ k = (const uchar *) name;
+ while ( *k ) {
+ h = ( h << 4 ) + *k++;
+ if ( (g = (h & 0xf0000000)) != 0 )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ }
+ if ( !h )
+ h = 1;
+ return h;
+}
+
+extern bool qt_detectRTLLanguage();
+
+class TQTranslatorPrivate {
+public:
+ struct Offset {
+ Offset()
+ : h( 0 ), o( 0 ) { }
+ Offset( const TQTranslatorMessage& m, int offset )
+ : h( m.hash() ), o( offset ) { }
+
+ bool operator<( const Offset&k ) const {
+ return ( h != k.h ) ? h < k.h : o < k.o;
+ }
+ TQ_DUMMY_COMPARISON_OPERATOR(TQTranslatorPrivate::Offset)
+ uint h;
+ uint o;
+ };
+
+ enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69 };
+
+ TQTranslatorPrivate() :
+ unmapPointer( 0 ), unmapLength( 0 ),
+ messageArray( 0 ), offsetArray( 0 ), contextArray( 0 )
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ , messages( 0 )
+#endif
+ { }
+ // TQTranslator must finalize this before deallocating it
+
+ // for mmap'ed files, this is what needs to be unmapped.
+ char * unmapPointer;
+ unsigned int unmapLength;
+
+ // for squeezed but non-file data, this is what needs to be deleted
+ TQByteArray * messageArray;
+ TQByteArray * offsetArray;
+ TQByteArray * contextArray;
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ TQMap<TQTranslatorMessage, void *> * messages;
+#endif
+#ifdef TQ_WS_WIN
+ int oldPermissionLookup;
+#endif
+};
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+
+/*!
+ Returns a list of the messages in the translator. This function is
+ rather slow. Because it is seldom called, it's optimized for
+ simplicity and small size, rather than speed.
+
+ If you want to iterate over the list, you should iterate over a
+ copy, e.g.
+ \code
+ TQValueList<TQTranslatorMessage> list = myTranslator.messages();
+ TQValueList<TQTranslatorMessage>::Iterator it = list.begin();
+ while ( it != list.end() ) {
+ process_message( *it );
+ ++it;
+ }
+ \endcode
+*/
+
+TQValueList<TQTranslatorMessage> TQTranslator::messages() const
+{
+ if ( d->messages )
+ return d->messages->keys();
+
+ ((TQTranslator *) this)->unsqueeze();
+ TQValueList<TQTranslatorMessage> result = d->messages->keys();
+ delete d->messages;
+ d->messages = 0;
+ return result;
+}
+
+/*!
+ Saves this message file to \a filename, overwriting the previous
+ contents of \a filename. If \a mode is \c Everything (the
+ default), all the information is preserved. If \a mode is \c
+ Stripped, any information that is not necessary for tqfindMessage()
+ is stripped away.
+
+ \sa load()
+*/
+
+bool TQTranslator::save( const TQString & filename, SaveMode mode )
+{
+ TQFile f( filename );
+ if ( f.open( IO_WriteOnly ) ) {
+ squeeze( mode );
+
+ TQDataStream s( &f );
+ s.writeRawBytes( (const char *)magic, MagicLength );
+ TQ_UINT8 tag;
+
+ if ( d->offsetArray != 0 ) {
+ tag = (TQ_UINT8) TQTranslatorPrivate::Hashes;
+ TQ_UINT32 oas = (TQ_UINT32) d->offsetArray->size();
+ s << tag << oas;
+ s.writeRawBytes( d->offsetArray->data(), oas );
+ }
+ if ( d->messageArray != 0 ) {
+ tag = (TQ_UINT8) TQTranslatorPrivate::Messages;
+ TQ_UINT32 mas = (TQ_UINT32) d->messageArray->size();
+ s << tag << mas;
+ s.writeRawBytes( d->messageArray->data(), mas );
+ }
+ if ( d->contextArray != 0 ) {
+ tag = (TQ_UINT8) TQTranslatorPrivate::Contexts;
+ TQ_UINT32 cas = (TQ_UINT32) d->contextArray->size();
+ s << tag << cas;
+ s.writeRawBytes( d->contextArray->data(), cas );
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*!
+ Empties this translator of all contents.
+
+ This function works with stripped translator files.
+*/
+
+void TQTranslator::clear()
+{
+ if ( d->unmapPointer && d->unmapLength ) {
+#if defined(TQT_USE_MMAP)
+ munmap( d->unmapPointer, d->unmapLength );
+#else
+ delete [] d->unmapPointer;
+#endif
+ d->unmapPointer = 0;
+ d->unmapLength = 0;
+ }
+
+ if ( d->messageArray ) {
+ d->messageArray->resetRawData( d->messageArray->data(),
+ d->messageArray->size() );
+ delete d->messageArray;
+ d->messageArray = 0;
+ }
+ if ( d->offsetArray ) {
+ d->offsetArray->resetRawData( d->offsetArray->data(),
+ d->offsetArray->size() );
+ delete d->offsetArray;
+ d->offsetArray = 0;
+ }
+ if ( d->contextArray ) {
+ d->contextArray->resetRawData( d->contextArray->data(),
+ d->contextArray->size() );
+ delete d->contextArray;
+ d->contextArray = 0;
+ }
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ delete d->messages;
+ d->messages = 0;
+#endif
+
+ if ( tqApp ) {
+ tqApp->setReverseLayout( qt_detectRTLLanguage() );
+
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ TQWidgetListIt it( *list );
+ TQWidget *w;
+ while ( ( w=it.current() ) != 0 ) {
+ ++it;
+ if (!w->isDesktop())
+ tqApp->postEvent( w, new TQEvent( TQEvent::LanguageChange ) );
+ }
+ delete list;
+ }
+}
+
+/*!
+ Converts this message file to the compact format used to store
+ message files on disk.
+
+ You should never need to call this directly; save() and other
+ functions call it as necessary. \a mode is for internal use.
+
+ \sa save() unsqueeze()
+*/
+
+void TQTranslator::squeeze( SaveMode mode )
+{
+ if ( !d->messages ) {
+ if ( mode == Stripped )
+ unsqueeze();
+ else
+ return;
+ }
+
+ TQMap<TQTranslatorMessage, void *> * messages = d->messages;
+
+ d->messages = 0;
+ clear();
+
+ d->messageArray = new TQByteArray;
+ d->offsetArray = new TQByteArray;
+
+ TQMap<TQTranslatorPrivate::Offset, void *> offsets;
+
+ TQDataStream ms( *d->messageArray, IO_WriteOnly );
+ TQMap<TQTranslatorMessage, void *>::Iterator it = messages->begin(), next;
+ int cpPrev = 0, cpNext = 0;
+ for ( it = messages->begin(); it != messages->end(); ++it ) {
+ cpPrev = cpNext;
+ next = it;
+ ++next;
+ if ( next == messages->end() )
+ cpNext = 0;
+ else
+ cpNext = (int) it.key().commonPrefix( next.key() );
+ offsets.tqreplace( TQTranslatorPrivate::Offset(it.key(),
+ ms.tqdevice()->at()), (void*)0 );
+ it.key().write( ms, mode == Stripped,
+ (TQTranslatorMessage::Prefix) TQMAX(cpPrev, cpNext + 1) );
+ }
+
+ d->offsetArray->resize( 0 );
+ TQMap<TQTranslatorPrivate::Offset, void *>::Iterator offset;
+ offset = offsets.begin();
+ TQDataStream ds( *d->offsetArray, IO_WriteOnly );
+ while ( offset != offsets.end() ) {
+ TQTranslatorPrivate::Offset k = offset.key();
+ ++offset;
+ ds << (TQ_UINT32)k.h << (TQ_UINT32)k.o;
+ }
+
+ if ( mode == Stripped ) {
+ TQAsciiDict<int> contextSet( 1511 );
+ int baudelaire;
+
+ for ( it = messages->begin(); it != messages->end(); ++it )
+ contextSet.tqreplace( it.key().context(), &baudelaire );
+
+ TQ_UINT16 hTableSize;
+ if ( contextSet.count() < 200 )
+ hTableSize = ( contextSet.count() < 60 ) ? 151 : 503;
+ else if ( contextSet.count() < 2500 )
+ hTableSize = ( contextSet.count() < 750 ) ? 1511 : 5003;
+ else
+ hTableSize = 15013;
+
+ TQIntDict<char> hDict( hTableSize );
+ TQAsciiDictIterator<int> c = contextSet;
+ while ( c.current() != 0 ) {
+ hDict.insert( (long) (elfHash(c.currentKey()) % hTableSize),
+ c.currentKey() );
+ ++c;
+ }
+
+ /*
+ The contexts found in this translator are stored in a hash
+ table to provide fast lookup. The context array has the
+ following format:
+
+ TQ_UINT16 hTableSize;
+ TQ_UINT16 hTable[hTableSize];
+ TQ_UINT8 contextPool[...];
+
+ The context pool stores the contexts as Pascal strings:
+
+ TQ_UINT8 len;
+ TQ_UINT8 data[len];
+
+ Let's consider the look-up of context "FunnyDialog". A
+ hash value between 0 and hTableSize - 1 is computed, say h.
+ If hTable[h] is 0, "FunnyDialog" is not covered by this
+ translator. Else, we check in the contextPool at offset
+ 2 * hTable[h] to see if "FunnyDialog" is one of the
+ contexts stored there, until we tqfind it or we meet the
+ empty string.
+ */
+ d->contextArray = new TQByteArray;
+ d->contextArray->resize( 2 + (hTableSize << 1) );
+ TQDataStream t( *d->contextArray, IO_WriteOnly );
+ TQ_UINT16 *hTable = new TQ_UINT16[hTableSize];
+ memset( hTable, 0, hTableSize * sizeof(TQ_UINT16) );
+
+ t << hTableSize;
+ t.tqdevice()->at( 2 + (hTableSize << 1) );
+ t << (TQ_UINT16) 0; // the entry at offset 0 cannot be used
+ uint upto = 2;
+
+ for ( int i = 0; i < hTableSize; i++ ) {
+ const char *con = hDict.tqfind( i );
+ if ( con == 0 ) {
+ hTable[i] = 0;
+ } else {
+ hTable[i] = (TQ_UINT16) ( upto >> 1 );
+ do {
+ uint len = (uint) tqstrlen( con );
+ len = TQMIN( len, 255 );
+ t << (TQ_UINT8) len;
+ t.writeRawBytes( con, len );
+ upto += 1 + len;
+ hDict.remove( i );
+ } while ( (con = hDict.tqfind(i)) != 0 );
+ do {
+ t << (TQ_UINT8) 0; // empty string (at least one)
+ upto++;
+ } while ( (upto & 0x1) != 0 ); // offsets have to be even
+ }
+ }
+ t.tqdevice()->at( 2 );
+ for ( int j = 0; j < hTableSize; j++ )
+ t << hTable[j];
+ delete [] hTable;
+
+ if ( upto > 131072 ) {
+ qWarning( "TQTranslator::squeeze: Too many contexts" );
+ delete d->contextArray;
+ d->contextArray = 0;
+ }
+ }
+ delete messages;
+}
+
+
+/*!
+ Converts this message file into an easily modifiable data
+ structure, less compact than the format used in the files.
+
+ You should never need to call this function; it is called by
+ insert() and friends as necessary.
+
+ \sa squeeze()
+*/
+
+void TQTranslator::unsqueeze()
+{
+ if ( d->messages )
+ return;
+
+ d->messages = new TQMap<TQTranslatorMessage, void *>;
+ if ( !d->messageArray )
+ return;
+
+ TQDataStream s( *d->messageArray, IO_ReadOnly );
+ for ( ;; ) {
+ TQTranslatorMessage m( s );
+ if ( m.hash() == 0 )
+ break;
+ d->messages->insert( m, (void *) 0 );
+ }
+}
+
+/*!
+ Returns TRUE if this message file tqcontains a message with the key
+ (\a context, \a sourceText, \a comment); otherwise returns FALSE.
+
+ This function works with stripped translator files.
+
+ (This is is a one-liner that calls tqfindMessage().)
+*/
+
+bool TQTranslator::tqcontains( const char* context, const char* sourceText,
+ const char* comment ) const
+{
+ return !tqfindMessage( context, sourceText, comment ).translation().isNull();
+}
+
+/*!
+ Inserts \a message into this message file.
+
+ This function does \e not work with stripped translator files. It
+ may appear to, but that is not dependable.
+
+ \sa remove()
+*/
+
+void TQTranslator::insert( const TQTranslatorMessage& message )
+{
+ unsqueeze();
+ d->messages->remove( message ); // safer
+ d->messages->insert( message, (void *) 0 );
+}
+
+
+/*!
+ \fn void TQTranslator::insert( const char *, const char *, const TQString & )
+ \overload
+ \obsolete
+*/
+
+/*!
+ Removes \a message from this translator.
+
+ This function works with stripped translator files.
+
+ \sa insert()
+*/
+
+void TQTranslator::remove( const TQTranslatorMessage& message )
+{
+ unsqueeze();
+ d->messages->remove( message );
+}
+
+/*! Returns the TQTranslatorMessage for the key
+ (\a context, \a sourceText, \a comment). If none is found,
+ also tries (\a context, \a sourceText, "").
+*/
+
+#endif
+
+TQTranslatorMessage TQTranslator::tqfindMessage( const char* context,
+ const char* sourceText,
+ const char* comment ) const
+{
+ if ( context == 0 )
+ context = "";
+ if ( sourceText == 0 )
+ sourceText = "";
+ if ( comment == 0 )
+ comment = "";
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ if ( d->messages ) {
+ TQMap<TQTranslatorMessage, void *>::ConstIterator it;
+
+ it = d->messages->tqfind( TQTranslatorMessage(context, sourceText,
+ comment) );
+ if ( it != d->messages->end() )
+ return it.key();
+
+ if ( comment[0] ) {
+ it = d->messages->tqfind( TQTranslatorMessage(context, sourceText,
+ "") );
+ if ( it != d->messages->end() )
+ return it.key();
+ }
+ return TQTranslatorMessage();
+ }
+#endif
+
+ if ( !d->offsetArray )
+ return TQTranslatorMessage();
+
+ /*
+ Check if the context belongs to this TQTranslator. If many translators are
+ installed, this step is necessary.
+ */
+ if ( d->contextArray ) {
+ TQ_UINT16 hTableSize = 0;
+ TQDataStream t( *d->contextArray, IO_ReadOnly );
+ t >> hTableSize;
+ uint g = elfHash( context ) % hTableSize;
+ t.tqdevice()->at( 2 + (g << 1) );
+ TQ_UINT16 off;
+ t >> off;
+ if ( off == 0 )
+ return TQTranslatorMessage();
+ t.tqdevice()->at( 2 + (hTableSize << 1) + (off << 1) );
+
+ TQ_UINT8 len;
+ char con[256];
+ for ( ;; ) {
+ t >> len;
+ if ( len == 0 )
+ return TQTranslatorMessage();
+ t.readRawBytes( con, len );
+ con[len] = '\0';
+ if ( qstrcmp(con, context) == 0 )
+ break;
+ }
+ }
+
+ size_t numItems = d->offsetArray->size() / ( 2 * sizeof(TQ_UINT32) );
+ if ( !numItems )
+ return TQTranslatorMessage();
+
+ if ( systemWordSize == 0 )
+ qSysInfo( &systemWordSize, &systemBigEndian );
+
+ for ( ;; ) {
+ TQ_UINT32 h = elfHash( TQCString(sourceText) + comment );
+
+ char *r = (char *) bsearch( &h, d->offsetArray->data(), numItems,
+ 2 * sizeof(TQ_UINT32),
+ systemBigEndian ? cmp_uint32_big
+ : cmp_uint32_little );
+ if ( r != 0 ) {
+ // go back on equal key
+ while ( r != d->offsetArray->data() &&
+ cmp_uint32_big(r - 8, r) == 0 )
+ r -= 8;
+
+ TQDataStream s( *d->offsetArray, IO_ReadOnly );
+ s.tqdevice()->at( r - d->offsetArray->data() );
+
+ TQ_UINT32 rh, ro;
+ s >> rh >> ro;
+
+ TQDataStream ms( *d->messageArray, IO_ReadOnly );
+ while ( rh == h ) {
+ ms.tqdevice()->at( ro );
+ TQTranslatorMessage m( ms );
+ if ( match(m.context(), context)
+ && match(m.sourceText(), sourceText)
+ && match(m.comment(), comment) )
+ return m;
+ if ( s.atEnd() )
+ break;
+ s >> rh >> ro;
+ }
+ }
+ if ( !comment[0] )
+ break;
+ comment = "";
+ }
+ return TQTranslatorMessage();
+}
+
+// The functions below handle TQTranslatorMessage [USE_QT4]
+
+/*!
+ \class TQTranslatorMessage
+
+ \brief The TQTranslatorMessage class tqcontains a translator message and its
+ properties.
+
+ \ingroup i18n
+ \ingroup environment
+
+ This class is of no interest to most applications. It is useful
+ for translation tools such as \link linguist-manual.book TQt
+ Linguist\endlink. It is provided simply to make the API complete
+ and regular.
+
+ For a TQTranslator object, a lookup key is a triple (\e context, \e
+ {source text}, \e comment) that uniquely identifies a message. An
+ extended key is a quadruple (\e hash, \e context, \e {source
+ text}, \e comment), where \e hash is computed from the source text
+ and the comment. Unless you plan to read and write messages
+ yourself, you need not worry about the hash value.
+
+ TQTranslatorMessage stores this triple or quadruple and the relevant
+ translation if there is any.
+
+ \sa TQTranslator
+*/
+
+/*!
+ Constructs a translator message with the extended key (0, 0, 0, 0)
+ and TQString::null as translation.
+*/
+
+TQTranslatorMessage::TQTranslatorMessage()
+ : h( 0 ), cx( 0 ), st( 0 ), cm( 0 )
+{
+}
+
+
+/*!
+ Constructs an translator message with the extended key (\e h, \a
+ context, \a sourceText, \a comment), where \e h is computed from
+ \a sourceText and \a comment, and possibly with a \a translation.
+*/
+
+TQTranslatorMessage::TQTranslatorMessage( const char * context,
+ const char * sourceText,
+ const char * comment,
+ const TQString& translation )
+ : cx( context ), st( sourceText ), cm( comment ), tn( translation )
+{
+ // 0 means we don't know, "" means empty
+ if ( cx == (const char*)0 )
+ cx = "";
+ if ( st == (const char*)0 )
+ st = "";
+ if ( cm == (const char*)0 )
+ cm = "";
+ h = elfHash( st + cm );
+}
+
+
+/*!
+ Constructs a translator message read from the \a stream. The
+ resulting message may have any combination of content.
+
+ \sa TQTranslator::save()
+*/
+
+TQTranslatorMessage::TQTranslatorMessage( TQDataStream & stream )
+ : cx( 0 ), st( 0 ), cm( 0 )
+{
+ TQString str16;
+ char tag;
+ TQ_UINT8 obs1;
+
+ for ( ;; ) {
+ tag = 0;
+ if ( !stream.atEnd() )
+ stream.readRawBytes( &tag, 1 );
+ switch( (Tag)tag ) {
+ case Tag_End:
+ if ( h == 0 )
+ h = elfHash( st + cm );
+ return;
+ case Tag_SourceText16: // obsolete
+ stream >> str16;
+ st = str16.latin1();
+ break;
+ case Tag_Translation:
+ stream >> tn;
+ break;
+ case Tag_Context16: // obsolete
+ stream >> str16;
+ cx = str16.latin1();
+ break;
+ case Tag_Hash:
+ stream >> h;
+ break;
+ case Tag_SourceText:
+ stream >> st;
+ break;
+ case Tag_Context:
+ stream >> cx;
+ if ( cx == "" ) // for compatibility
+ cx = 0;
+ break;
+ case Tag_Comment:
+ stream >> cm;
+ break;
+ case Tag_Obsolete1: // obsolete
+ stream >> obs1;
+ break;
+ default:
+ h = 0;
+ st = 0;
+ cx = 0;
+ cm = 0;
+ tn = TQString::null;
+ return;
+ }
+ }
+}
+
+
+/*!
+ Constructs a copy of translator message \a m.
+*/
+
+TQTranslatorMessage::TQTranslatorMessage( const TQTranslatorMessage & m )
+ : cx( m.cx ), st( m.st ), cm( m.cm ), tn( m.tn )
+{
+ h = m.h;
+}
+
+
+/*!
+ Assigns message \a m to this translator message and returns a
+ reference to this translator message.
+*/
+
+TQTranslatorMessage & TQTranslatorMessage::operator=(
+ const TQTranslatorMessage & m )
+{
+ h = m.h;
+ cx = m.cx;
+ st = m.st;
+ cm = m.cm;
+ tn = m.tn;
+ return *this;
+}
+
+
+/*!
+ \fn uint TQTranslatorMessage::hash() const
+
+ Returns the hash value used internally to represent the lookup
+ key. This value is zero only if this translator message was
+ constructed from a stream containing invalid data.
+
+ The hashing function is unspecified, but it will remain unchanged
+ in future versions of TQt.
+*/
+
+/*!
+ \fn const char *TQTranslatorMessage::context() const
+
+ Returns the context for this message (e.g. "MyDialog").
+
+ \warning This may return 0 if the TQTranslator object is stripped
+ (compressed).
+*/
+
+/*!
+ \fn const char *TQTranslatorMessage::sourceText() const
+
+ Returns the source text of this message (e.g. "&Save").
+
+ \warning This may return 0 if the TQTranslator object is stripped
+ (compressed).
+*/
+
+/*!
+ \fn const char *TQTranslatorMessage::comment() const
+
+ Returns the comment for this message (e.g. "File|Save").
+
+ \warning This may return 0 if the TQTranslator object is stripped
+ (compressed).
+*/
+
+/*!
+ \fn void TQTranslatorMessage::setTranslation( const TQString & translation )
+
+ Sets the translation of the source text to \a translation.
+
+ \sa translation()
+*/
+
+/*!
+ \fn TQString TQTranslatorMessage::translation() const
+
+ Returns the translation of the source text (e.g., "&Sauvegarder").
+
+ \sa setTranslation()
+*/
+
+/*!
+ \enum TQTranslatorMessage::Prefix
+
+ Let (\e h, \e c, \e s, \e m) be the extended key. The possible
+ prefixes are
+
+ \value NoPrefix no prefix
+ \value Hash only (\e h)
+ \value HashContext only (\e h, \e c)
+ \value HashContextSourceText only (\e h, \e c, \e s)
+ \value HashContextSourceTextComment the whole extended key, (\e
+ h, \e c, \e s, \e m)
+
+ \sa write() commonPrefix()
+*/
+
+/*!
+ Writes this translator message to the \a stream. If \a strip is
+ FALSE (the default), all the information in the message is
+ written. If \a strip is TRUE, only the part of the extended key
+ specified by \a prefix is written with the translation (\c
+ HashContextSourceTextComment by default).
+
+ \sa commonPrefix()
+*/
+
+void TQTranslatorMessage::write( TQDataStream & stream, bool strip,
+ Prefix prefix ) const
+{
+ char tag;
+
+ tag = (char)Tag_Translation;
+ stream.writeRawBytes( &tag, 1 );
+ stream << tn;
+
+ bool mustWriteHash = TRUE;
+ if ( !strip )
+ prefix = HashContextSourceTextComment;
+
+ switch ( prefix ) {
+ case HashContextSourceTextComment:
+ tag = (char)Tag_Comment;
+ stream.writeRawBytes( &tag, 1 );
+ stream << cm;
+ // fall through
+ case HashContextSourceText:
+ tag = (char)Tag_SourceText;
+ stream.writeRawBytes( &tag, 1 );
+ stream << st;
+ // fall through
+ case HashContext:
+ tag = (char)Tag_Context;
+ stream.writeRawBytes( &tag, 1 );
+ stream << cx;
+ // fall through
+ default:
+ if ( mustWriteHash ) {
+ tag = (char)Tag_Hash;
+ stream.writeRawBytes( &tag, 1 );
+ stream << h;
+ }
+ }
+
+ tag = (char)Tag_End;
+ stream.writeRawBytes( &tag, 1 );
+}
+
+
+/*!
+ Returns the widest lookup prefix that is common to this translator
+ message and to message \a m.
+
+ For example, if the extended key is for this message is (71,
+ "PrintDialog", "Yes", "Print?") and that for \a m is (71,
+ "PrintDialog", "No", "Print?"), this function returns \c
+ HashContext.
+
+ \sa write()
+*/
+
+TQTranslatorMessage::Prefix TQTranslatorMessage::commonPrefix(
+ const TQTranslatorMessage& m ) const
+{
+ if ( h != m.h )
+ return NoPrefix;
+ if ( cx != m.cx )
+ return Hash;
+ if ( st != m.st )
+ return HashContext;
+ if ( cm != m.cm )
+ return HashContextSourceText;
+ return HashContextSourceTextComment;
+}
+
+
+/*!
+ Returns TRUE if the extended key of this object is equal to that of
+ \a m; otherwise returns FALSE.
+*/
+
+bool TQTranslatorMessage::operator==( const TQTranslatorMessage& m ) const
+{
+ return h == m.h && cx == m.cx && st == m.st && cm == m.cm;
+}
+
+
+/*!
+ \fn bool TQTranslatorMessage::operator!=( const TQTranslatorMessage& m ) const
+
+ Returns TRUE if the extended key of this object is different from
+ that of \a m; otherwise returns FALSE.
+*/
+
+
+/*!
+ Returns TRUE if the extended key of this object is
+ lexicographically before than that of \a m; otherwise returns
+ FALSE.
+*/
+
+bool TQTranslatorMessage::operator<( const TQTranslatorMessage& m ) const
+{
+ return h != m.h ? h < m.h
+ : ( cx != m.cx ? cx < m.cx
+ : (st != m.st ? st < m.st : cm < m.cm) );
+}
+
+
+/*!
+ \fn bool TQTranslatorMessage::operator<=( const TQTranslatorMessage& m ) const
+
+ Returns TRUE if the extended key of this object is
+ lexicographically before that of \a m or if they are equal;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQTranslatorMessage::operator>( const TQTranslatorMessage& m ) const
+
+ Returns TRUE if the extended key of this object is
+ lexicographically after that of \a m; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQTranslatorMessage::operator>=( const TQTranslatorMessage& m ) const
+
+ Returns TRUE if the extended key of this object is
+ lexicographically after that of \a m or if they are equal;
+ otherwise returns FALSE.
+*/
+
+#else // USE_QT4
+
+/*
+$ mcookie
+3cb86418caef9c95cd211cbf60a1bddd
+$
+*/
+
+// magic number for the file
+static const int MagicLength = 16;
+static const uchar magic[MagicLength] = {
+ 0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,
+ 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd
+};
+
+static bool match( const char* found, const char* target )
+{
+ // 0 means anything, "" means empty
+ return found == 0 || qstrcmp( found, target ) == 0;
+}
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+/*
+ Yes, unfortunately, we have code here that depends on endianness.
+ The candidate is big endian (it comes from a .qm file) whereas the
+ target endianness depends on the system TQt is running on.
+*/
+#ifdef TQ_OS_TEMP
+static int __cdecl cmp_uint32_little( const void* target, const void* candidate )
+#else
+static int cmp_uint32_little( const void* target, const void* candidate )
+#endif
+{
+ const uchar* t = (const uchar*) target;
+ const uchar* c = (const uchar*) candidate;
+ return t[3] != c[0] ? (int) t[3] - (int) c[0]
+ : t[2] != c[1] ? (int) t[2] - (int) c[1]
+ : t[1] != c[2] ? (int) t[1] - (int) c[2]
+ : (int) t[0] - (int) c[3];
+}
+
+#ifdef TQ_OS_TEMP
+static int __cdecl cmp_uint32_big( const void* target, const void* candidate )
+#else
+static int cmp_uint32_big( const void* target, const void* candidate )
+#endif
+{
+ const uchar* t = (const uchar*) target;
+ const uchar* c = (const uchar*) candidate;
+ return t[0] != c[0] ? (int) t[0] - (int) c[0]
+ : t[1] != c[1] ? (int) t[1] - (int) c[1]
+ : t[2] != c[2] ? (int) t[2] - (int) c[2]
+ : (int) t[3] - (int) c[3];
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+static int systemWordSize = 0;
+static bool systemBigEndian;
+
+static uint elfHash( const char * name )
+{
+ const uchar *k;
+ uint h = 0;
+ uint g;
+
+ if ( name ) {
+ k = (const uchar *) name;
+ while ( *k ) {
+ h = ( h << 4 ) + *k++;
+ if ( (g = (h & 0xf0000000)) != 0 )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ }
+ if ( !h )
+ h = 1;
+ return h;
+}
+
+extern bool qt_detectRTLLanguage();
+
+class TQTranslatorPrivate {
+public:
+ struct Offset {
+ Offset()
+ : h( 0 ), o( 0 ) { }
+ Offset( const TQTranslatorMessage& m, int offset )
+ : h( m.hash() ), o( offset ) { }
+
+ bool operator<( const Offset&k ) const {
+ return ( h != k.h ) ? h < k.h : o < k.o;
+ }
+ TQ_DUMMY_COMPARISON_OPERATOR(TQTranslatorPrivate::Offset)
+ uint h;
+ uint o;
+ };
+
+ enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69 };
+
+ TQTranslatorPrivate() :
+ unmapPointer( 0 ), unmapLength( 0 ),
+ messageArray( 0 ), offsetArray( 0 ), contextArray( 0 )
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ , messages( 0 )
+#endif
+ { }
+ // TQTranslator must finalize this before deallocating it
+
+ // for mmap'ed files, this is what needs to be unmapped.
+ char * unmapPointer;
+ unsigned int unmapLength;
+
+ // for squeezed but non-file data, this is what needs to be deleted
+ TQByteArray * messageArray;
+ TQByteArray * offsetArray;
+ TQByteArray * contextArray;
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ TQMap<TQTranslatorMessage, void *> * messages;
+#endif
+#ifdef TQ_WS_WIN
+ int oldPermissionLookup;
+#endif
+};
+
+
+/*!
+ \class TQTranslator
+
+ \brief The TQTranslator class provides internationalization support for text
+ output.
+
+ \ingroup i18n
+ \ingroup environment
+ \mainclass
+
+ An object of this class tqcontains a set of TQTranslatorMessage
+ objects, each of which specifies a translation from a source
+ language to a target language. TQTranslator provides functions to
+ look up translations, add new ones, remove them, load and save
+ them, etc.
+
+ The most common use of TQTranslator is to: load a translator file
+ created with \link linguist-manual.book TQt Linguist\endlink,
+ install it using TQApplication::installTranslator(), and use it via
+ TQObject::tr(). For example:
+
+ \code
+ int main( int argc, char ** argv )
+ {
+ TQApplication app( argc, argv );
+
+ TQTranslator translator( 0 );
+ translator.load( "french.qm", "." );
+ app.installTranslator( &translator );
+
+ MyWidget m;
+ app.setMainWidget( &m );
+ m.show();
+
+ return app.exec();
+ }
+ \endcode
+ Note that the translator must be created \e before the
+ application's main window.
+
+ Most applications will never need to do anything else with this
+ class. The other functions provided by this class are useful for
+ applications that work on translator files.
+
+ We call a translation a "messsage". For this reason, translation
+ files are sometimes referred to as "message files".
+
+ It is possible to lookup a translation using tqfindMessage() (as
+ tr() and TQApplication::translate() do) and tqcontains(), to insert a
+ new translation messsage using insert(), and to remove one using
+ remove().
+
+ Translation tools often need more information than the bare source
+ text and translation, for example, context information to help
+ the translator. But end-user programs that are using translations
+ usually only need lookup. To cater for these different needs,
+ TQTranslator can use stripped translator files that use the minimum
+ of memory and which support little more functionality than
+ tqfindMessage().
+
+ Thus, load() may not load enough information to make anything more
+ than tqfindMessage() work. save() has an argument indicating
+ whether to save just this minimum of information or to save
+ everything.
+
+ "Everything" means that for each translation item the following
+ information is kept:
+
+ \list
+ \i The \e {translated text} - the return value from tr().
+ \i The input key:
+ \list
+ \i The \e {source text} - usually the argument to tr().
+ \i The \e context - usually the class name for the tr() caller.
+ \i The \e comment - a comment that helps disambiguate different uses
+ of the same text in the same context.
+ \endlist
+ \endlist
+
+ The minimum for each item is just the information necessary for
+ tqfindMessage() to return the right text. This may include the
+ source, context and comment, but usually it is just a hash value
+ and the translated text.
+
+ For example, the "Cancel" in a dialog might have "Anuluj" when the
+ program runs in Polish (in this case the source text would be
+ "Cancel"). The context would (normally) be the dialog's class
+ name; there would normally be no comment, and the translated text
+ would be "Anuluj".
+
+ But it's not always so simple. The Spanish version of a printer
+ dialog with settings for two-sided printing and binding would
+ probably require both "Activado" and "Activada" as translations
+ for "Enabled". In this case the source text would be "Enabled" in
+ both cases, and the context would be the dialog's class name, but
+ the two items would have disambiguating comments such as
+ "two-sided printing" for one and "binding" for the other. The
+ comment enables the translator to choose the appropriate gender
+ for the Spanish version, and enables TQt to distinguish between
+ translations.
+
+ Note that when TQTranslator loads a stripped file, most functions
+ do not work. The functions that do work with stripped files are
+ explicitly documented as such.
+
+ \sa TQTranslatorMessage TQApplication::installTranslator()
+ TQApplication::removeTranslator() TQObject::tr() TQApplication::translate()
+*/
+
+/*!
+ \enum TQTranslator::SaveMode
+
+ This enum type defines how TQTranslator writes translation
+ files. There are two modes:
+
+ \value Everything files are saved with all available information
+ \value Stripped files are saved with just enough information for
+ end-user applications
+
+ Note that when TQTranslator loads a stripped file, most functions do
+ not work. The functions that do work with stripped files are
+ explicitly documented as such.
+*/
+
+#if defined(TQ_WS_WIN)
+extern int qt_ntfs_permission_lookup;
+#endif
+
+/*!
+ Constructs an empty message file object that is not connected to
+ any file. The object is called \a name with tqparent \a tqparent.
+*/
+
+TQTranslator::TQTranslator( TQObject * tqparent, const char * name )
+ : TQObject( tqparent, name )
+{
+ d = new TQTranslatorPrivate;
+#if defined(TQ_WS_WIN)
+ d->oldPermissionLookup = qt_ntfs_permission_lookup;
+#endif
+}
+
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQTranslator::~TQTranslator()
+{
+ if ( tqApp )
+ tqApp->removeTranslator( this );
+ clear();
+ delete d;
+}
+
+
+extern bool qt_detectRTLLanguage();
+
+/*!
+ Loads \a filename, which may be an absolute file name or relative
+ to \a directory. The previous contents of this translator object
+ is discarded. Returns TRUE if the file is loaded successfully;
+ otherwise returns FALSE.
+
+ If the full file name does not exist, other file names are tried
+ in the following order:
+
+ \list 1
+ \i File name with \a suffix appended (".qm" if the \a suffix is
+ TQString::null).
+ \i File name with text after a character in \a search_delimiters
+ stripped ("_." is the default for \a search_delimiters if it is
+ TQString::null).
+ \i File name stripped and \a suffix appended.
+ \i File name stripped further, etc.
+ \endlist
+
+ For example, an application running in the fr_CA locale
+ (French-speaking Canada) might call load("foo.fr_ca",
+ "/opt/foolib"). load() would then try to open the first existing
+ readable file from this list:
+
+ \list 1
+ \i /opt/foolib/foo.fr_ca
+ \i /opt/foolib/foo.fr_ca.qm
+ \i /opt/foolib/foo.fr
+ \i /opt/foolib/foo.fr.qm
+ \i /opt/foolib/foo
+ \i /opt/foolib/foo.qm
+ \endlist
+
+ \sa save()
+*/
+
+bool TQTranslator::load( const TQString & filename, const TQString & directory,
+ const TQString & search_delimiters,
+ const TQString & suffix )
+{
+ clear();
+
+ TQString prefix;
+
+ if ( filename[0] == '/'
+#ifdef TQ_WS_WIN
+ || (filename[0] && filename[1] == ':') || filename[0] == '\\'
+#endif
+ )
+ prefix = TQString::tqfromLatin1( "" );
+ else
+ prefix = directory;
+
+ if ( prefix.length() ) {
+ if ( prefix[int(prefix.length()-1)] != '/' )
+ prefix += TQChar( '/' );
+ }
+
+ TQString fname = filename;
+ TQString realname;
+ TQString delims;
+ delims = search_delimiters.isNull() ?
+ TQString::tqfromLatin1( "_." ) : search_delimiters;
+
+#if defined(TQ_WS_WIN)
+ qt_ntfs_permission_lookup--;
+#endif
+ for ( ;; ) {
+ TQFileInfo fi;
+
+ realname = prefix + fname;
+ fi.setFile( realname );
+ if ( fi.isReadable() )
+ break;
+
+ realname += suffix.isNull() ? TQString::tqfromLatin1( ".qm" ) : suffix;
+ fi.setFile( realname );
+ if ( fi.isReadable() )
+ break;
+
+ int rightmost = 0;
+ for ( int i = 0; i < (int)delims.length(); i++ ) {
+ int k = fname.tqfindRev( delims[i] );
+ if ( k > rightmost )
+ rightmost = k;
+ }
+
+ // no truncations? fail
+ if ( rightmost == 0 ) {
+#if defined(TQ_WS_WIN)
+ if (d->oldPermissionLookup != qt_ntfs_permission_lookup)
+ qt_ntfs_permission_lookup++;
+#endif
+ return FALSE;
+ }
+
+ fname.truncate( rightmost );
+ }
+#if defined(TQ_WS_WIN)
+ if (d->oldPermissionLookup != qt_ntfs_permission_lookup)
+ qt_ntfs_permission_lookup++;
+#endif
+
+ // realname is now the fully qualified name of a readable file.
+
+#if defined(TQT_USE_MMAP)
+
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+#ifndef MAP_FAILED
+#define MAP_FAILED -1
+#endif
+
+ int f;
+
+ f = qt_open( TQFile::encodeName(realname), O_RDONLY, 0666 );
+ if ( f < 0 ) {
+ // qDebug( "can't open %s: %s", realname.ascii(), strerror( errno ) );
+ return FALSE;
+ }
+
+ struct stat st;
+ if ( fstat( f, &st ) ) {
+ // qDebug( "can't stat %s: %s", realname.ascii(), strerror( errno ) );
+ return FALSE;
+ }
+ char * tmp;
+ tmp = (char*)mmap( 0, st.st_size, // any address, whole file
+ PROT_READ, // read-only memory
+ MAP_FILE | MAP_PRIVATE, // swap-backed map from file
+ f, 0 ); // from offset 0 of f
+ if ( !tmp || tmp == (char*)MAP_FAILED ) {
+ // qDebug( "can't mmap %s: %s", filename.ascii(), strerror( errno ) );
+ return FALSE;
+ }
+
+ ::close( f );
+
+ d->unmapPointer = tmp;
+ d->unmapLength = st.st_size;
+#else
+ TQFile f( realname );
+ if ( !f.exists() )
+ return FALSE;
+ d->unmapLength = f.size();
+ d->unmapPointer = new char[d->unmapLength];
+ bool ok = FALSE;
+ if ( f.open(IO_ReadOnly) ) {
+ ok = d->unmapLength ==
+ (uint)f.readBlock( d->unmapPointer, d->unmapLength );
+ f.close();
+ }
+ if ( !ok ) {
+ delete [] d->unmapPointer;
+ d->unmapPointer = 0;
+ return FALSE;
+ }
+#endif
+
+ return do_load( (const uchar *) d->unmapPointer, d->unmapLength );
+}
+
+/*!
+ \overload
+ \fn bool TQTranslator::load( const uchar *data, int len )
+
+ Loads the .qm file data \a data of length \a len into the
+ translator. Returns TRUE if the data is loaded successfully;
+ otherwise returns FALSE.
+
+ The data is not copied. The caller must be able to guarantee that \a data
+ will not be deleted or modified.
+*/
+
+bool TQTranslator::do_load( const uchar *data, int len )
+{
+ if ( len < MagicLength || memcmp( data, magic, MagicLength ) != 0 ) {
+ clear();
+ return FALSE;
+ }
+
+ TQByteArray array;
+ array.setRawData( (const char *) data, len );
+ TQDataStream s( array, IO_ReadOnly );
+ bool ok = TRUE;
+
+ s.tqdevice()->at( MagicLength );
+
+ TQ_UINT8 tag = 0;
+ TQ_UINT32 blockLen = 0;
+ s >> tag >> blockLen;
+ while ( tag && blockLen ) {
+ if ( (TQ_UINT32) s.tqdevice()->at() + blockLen > (TQ_UINT32) len ) {
+ ok = FALSE;
+ break;
+ }
+
+ if ( tag == TQTranslatorPrivate::Contexts && !d->contextArray ) {
+ d->contextArray = new TQByteArray;
+ d->contextArray->setRawData( array.data() + s.tqdevice()->at(),
+ blockLen );
+ } else if ( tag == TQTranslatorPrivate::Hashes && !d->offsetArray ) {
+ d->offsetArray = new TQByteArray;
+ d->offsetArray->setRawData( array.data() + s.tqdevice()->at(),
+ blockLen );
+ } else if ( tag == TQTranslatorPrivate::Messages && !d->messageArray ) {
+ d->messageArray = new TQByteArray;
+ d->messageArray->setRawData( array.data() + s.tqdevice()->at(),
+ blockLen );
+ }
+
+ if ( !s.tqdevice()->at(s.tqdevice()->at() + blockLen) ) {
+ ok = FALSE;
+ break;
+ }
+ tag = 0;
+ blockLen = 0;
+ if ( !s.atEnd() )
+ s >> tag >> blockLen;
+ }
+ array.resetRawData( (const char *) data, len );
+
+ if ( tqApp && tqApp->translators && tqApp->translators->tqcontains(this) )
+ tqApp->setReverseLayout( qt_detectRTLLanguage() );
+ return ok;
+}
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+
+/*!
+ Saves this message file to \a filename, overwriting the previous
+ contents of \a filename. If \a mode is \c Everything (the
+ default), all the information is preserved. If \a mode is \c
+ Stripped, any information that is not necessary for tqfindMessage()
+ is stripped away.
+
+ \sa load()
+*/
+
+bool TQTranslator::save( const TQString & filename, SaveMode mode )
+{
+ TQFile f( filename );
+ if ( f.open( IO_WriteOnly ) ) {
+ squeeze( mode );
+
+ TQDataStream s( &f );
+ s.writeRawBytes( (const char *)magic, MagicLength );
+ TQ_UINT8 tag;
+
+ if ( d->offsetArray != 0 ) {
+ tag = (TQ_UINT8) TQTranslatorPrivate::Hashes;
+ TQ_UINT32 oas = (TQ_UINT32) d->offsetArray->size();
+ s << tag << oas;
+ s.writeRawBytes( d->offsetArray->data(), oas );
+ }
+ if ( d->messageArray != 0 ) {
+ tag = (TQ_UINT8) TQTranslatorPrivate::Messages;
+ TQ_UINT32 mas = (TQ_UINT32) d->messageArray->size();
+ s << tag << mas;
+ s.writeRawBytes( d->messageArray->data(), mas );
+ }
+ if ( d->contextArray != 0 ) {
+ tag = (TQ_UINT8) TQTranslatorPrivate::Contexts;
+ TQ_UINT32 cas = (TQ_UINT32) d->contextArray->size();
+ s << tag << cas;
+ s.writeRawBytes( d->contextArray->data(), cas );
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#endif
+
+/*!
+ Empties this translator of all contents.
+
+ This function works with stripped translator files.
+*/
+
+void TQTranslator::clear()
+{
+ if ( d->unmapPointer && d->unmapLength ) {
+#if defined(TQT_USE_MMAP)
+ munmap( d->unmapPointer, d->unmapLength );
+#else
+ delete [] d->unmapPointer;
+#endif
+ d->unmapPointer = 0;
+ d->unmapLength = 0;
+ }
+
+ if ( d->messageArray ) {
+ d->messageArray->resetRawData( d->messageArray->data(),
+ d->messageArray->size() );
+ delete d->messageArray;
+ d->messageArray = 0;
+ }
+ if ( d->offsetArray ) {
+ d->offsetArray->resetRawData( d->offsetArray->data(),
+ d->offsetArray->size() );
+ delete d->offsetArray;
+ d->offsetArray = 0;
+ }
+ if ( d->contextArray ) {
+ d->contextArray->resetRawData( d->contextArray->data(),
+ d->contextArray->size() );
+ delete d->contextArray;
+ d->contextArray = 0;
+ }
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ delete d->messages;
+ d->messages = 0;
+#endif
+
+ if ( tqApp ) {
+ tqApp->setReverseLayout( qt_detectRTLLanguage() );
+
+ TQWidgetList *list = TQApplication::tqtopLevelWidgets();
+ TQWidgetListIt it( *list );
+ TQWidget *w;
+ while ( ( w=it.current() ) != 0 ) {
+ ++it;
+ if (!w->isDesktop())
+ tqApp->postEvent( w, new TQEvent( TQEvent::LanguageChange ) );
+ }
+ delete list;
+ }
+}
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+
+/*!
+ Converts this message file to the compact format used to store
+ message files on disk.
+
+ You should never need to call this directly; save() and other
+ functions call it as necessary. \a mode is for internal use.
+
+ \sa save() unsqueeze()
+*/
+
+void TQTranslator::squeeze( SaveMode mode )
+{
+ if ( !d->messages ) {
+ if ( mode == Stripped )
+ unsqueeze();
+ else
+ return;
+ }
+
+ TQMap<TQTranslatorMessage, void *> * messages = d->messages;
+
+ d->messages = 0;
+ clear();
+
+ d->messageArray = new TQByteArray;
+ d->offsetArray = new TQByteArray;
+
+ TQMap<TQTranslatorPrivate::Offset, void *> offsets;
+
+ TQDataStream ms( *d->messageArray, IO_WriteOnly );
+ TQMap<TQTranslatorMessage, void *>::Iterator it = messages->begin(), next;
+ int cpPrev = 0, cpNext = 0;
+ for ( it = messages->begin(); it != messages->end(); ++it ) {
+ cpPrev = cpNext;
+ next = it;
+ ++next;
+ if ( next == messages->end() )
+ cpNext = 0;
+ else
+ cpNext = (int) it.key().commonPrefix( next.key() );
+ offsets.tqreplace( TQTranslatorPrivate::Offset(it.key(),
+ ms.tqdevice()->at()), (void*)0 );
+ it.key().write( ms, mode == Stripped,
+ (TQTranslatorMessage::Prefix) TQMAX(cpPrev, cpNext + 1) );
+ }
+
+ d->offsetArray->resize( 0 );
+ TQMap<TQTranslatorPrivate::Offset, void *>::Iterator offset;
+ offset = offsets.begin();
+ TQDataStream ds( *d->offsetArray, IO_WriteOnly );
+ while ( offset != offsets.end() ) {
+ TQTranslatorPrivate::Offset k = offset.key();
+ ++offset;
+ ds << (TQ_UINT32)k.h << (TQ_UINT32)k.o;
+ }
+
+ if ( mode == Stripped ) {
+ TQAsciiDict<int> contextSet( 1511 );
+ int baudelaire;
+
+ for ( it = messages->begin(); it != messages->end(); ++it )
+ contextSet.tqreplace( it.key().context(), &baudelaire );
+
+ TQ_UINT16 hTableSize;
+ if ( contextSet.count() < 200 )
+ hTableSize = ( contextSet.count() < 60 ) ? 151 : 503;
+ else if ( contextSet.count() < 2500 )
+ hTableSize = ( contextSet.count() < 750 ) ? 1511 : 5003;
+ else
+ hTableSize = 15013;
+
+ TQIntDict<char> hDict( hTableSize );
+ TQAsciiDictIterator<int> c = contextSet;
+ while ( c.current() != 0 ) {
+ hDict.insert( (long) (elfHash(c.currentKey()) % hTableSize),
+ c.currentKey() );
+ ++c;
+ }
+
+ /*
+ The contexts found in this translator are stored in a hash
+ table to provide fast lookup. The context array has the
+ following format:
+
+ TQ_UINT16 hTableSize;
+ TQ_UINT16 hTable[hTableSize];
+ TQ_UINT8 contextPool[...];
+
+ The context pool stores the contexts as Pascal strings:
+
+ TQ_UINT8 len;
+ TQ_UINT8 data[len];
+
+ Let's consider the look-up of context "FunnyDialog". A
+ hash value between 0 and hTableSize - 1 is computed, say h.
+ If hTable[h] is 0, "FunnyDialog" is not covered by this
+ translator. Else, we check in the contextPool at offset
+ 2 * hTable[h] to see if "FunnyDialog" is one of the
+ contexts stored there, until we tqfind it or we meet the
+ empty string.
+ */
+ d->contextArray = new TQByteArray;
+ d->contextArray->resize( 2 + (hTableSize << 1) );
+ TQDataStream t( *d->contextArray, IO_WriteOnly );
+ TQ_UINT16 *hTable = new TQ_UINT16[hTableSize];
+ memset( hTable, 0, hTableSize * sizeof(TQ_UINT16) );
+
+ t << hTableSize;
+ t.tqdevice()->at( 2 + (hTableSize << 1) );
+ t << (TQ_UINT16) 0; // the entry at offset 0 cannot be used
+ uint upto = 2;
+
+ for ( int i = 0; i < hTableSize; i++ ) {
+ const char *con = hDict.tqfind( i );
+ if ( con == 0 ) {
+ hTable[i] = 0;
+ } else {
+ hTable[i] = (TQ_UINT16) ( upto >> 1 );
+ do {
+ uint len = (uint) tqstrlen( con );
+ len = TQMIN( len, 255 );
+ t << (TQ_UINT8) len;
+ t.writeRawBytes( con, len );
+ upto += 1 + len;
+ hDict.remove( i );
+ } while ( (con = hDict.tqfind(i)) != 0 );
+ do {
+ t << (TQ_UINT8) 0; // empty string (at least one)
+ upto++;
+ } while ( (upto & 0x1) != 0 ); // offsets have to be even
+ }
+ }
+ t.tqdevice()->at( 2 );
+ for ( int j = 0; j < hTableSize; j++ )
+ t << hTable[j];
+ delete [] hTable;
+
+ if ( upto > 131072 ) {
+ qWarning( "TQTranslator::squeeze: Too many contexts" );
+ delete d->contextArray;
+ d->contextArray = 0;
+ }
+ }
+ delete messages;
+}
+
+
+/*!
+ Converts this message file into an easily modifiable data
+ structure, less compact than the format used in the files.
+
+ You should never need to call this function; it is called by
+ insert() and friends as necessary.
+
+ \sa squeeze()
+*/
+
+void TQTranslator::unsqueeze()
+{
+ if ( d->messages )
+ return;
+
+ d->messages = new TQMap<TQTranslatorMessage, void *>;
+ if ( !d->messageArray )
+ return;
+
+ TQDataStream s( *d->messageArray, IO_ReadOnly );
+ for ( ;; ) {
+ TQTranslatorMessage m( s );
+ if ( m.hash() == 0 )
+ break;
+ d->messages->insert( m, (void *) 0 );
+ }
+}
+
+
+/*!
+ Returns TRUE if this message file tqcontains a message with the key
+ (\a context, \a sourceText, \a comment); otherwise returns FALSE.
+
+ This function works with stripped translator files.
+
+ (This is is a one-liner that calls tqfindMessage().)
+*/
+
+bool TQTranslator::tqcontains( const char* context, const char* sourceText,
+ const char* comment ) const
+{
+ return !tqfindMessage( context, sourceText, comment ).translation().isNull();
+}
+
+
+/*!
+ Inserts \a message into this message file.
+
+ This function does \e not work with stripped translator files. It
+ may appear to, but that is not dependable.
+
+ \sa remove()
+*/
+
+void TQTranslator::insert( const TQTranslatorMessage& message )
+{
+ unsqueeze();
+ d->messages->remove( message ); // safer
+ d->messages->insert( message, (void *) 0 );
+}
+
+
+/*!
+ \fn void TQTranslator::insert( const char *, const char *, const TQString & )
+ \overload
+ \obsolete
+*/
+
+/*!
+ Removes \a message from this translator.
+
+ This function works with stripped translator files.
+
+ \sa insert()
+*/
+
+void TQTranslator::remove( const TQTranslatorMessage& message )
+{
+ unsqueeze();
+ d->messages->remove( message );
+}
+
+
+/*!
+ \fn void TQTranslator::remove( const char *, const char * )
+ \overload
+ \obsolete
+
+ Removes the translation associated to the key (\a context, \a sourceText,
+ "") from this translator.
+*/
+#endif
+
+/*!
+ \fn TQString TQTranslator::tqfind( const char*, const char*, const char* ) const
+ \obsolete
+
+ Please use tqfindMessage() instead.
+
+ Returns the translation for the key (\a context, \a sourceText,
+ \a comment) or TQString::null if there is none in this translator.
+*/
+
+/*! Returns the TQTranslatorMessage for the key
+ (\a context, \a sourceText, \a comment). If none is found,
+ also tries (\a context, \a sourceText, "").
+*/
+
+TQTranslatorMessage TQTranslator::tqfindMessage( const char* context,
+ const char* sourceText,
+ const char* comment ) const
+{
+ if ( context == 0 )
+ context = "";
+ if ( sourceText == 0 )
+ sourceText = "";
+ if ( comment == 0 )
+ comment = "";
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ if ( d->messages ) {
+ TQMap<TQTranslatorMessage, void *>::ConstIterator it;
+
+ it = d->messages->tqfind( TQTranslatorMessage(context, sourceText,
+ comment) );
+ if ( it != d->messages->end() )
+ return it.key();
+
+ if ( comment[0] ) {
+ it = d->messages->tqfind( TQTranslatorMessage(context, sourceText,
+ "") );
+ if ( it != d->messages->end() )
+ return it.key();
+ }
+ return TQTranslatorMessage();
+ }
+#endif
+
+ if ( !d->offsetArray )
+ return TQTranslatorMessage();
+
+ /*
+ Check if the context belongs to this TQTranslator. If many translators are
+ installed, this step is necessary.
+ */
+ if ( d->contextArray ) {
+ TQ_UINT16 hTableSize = 0;
+ TQDataStream t( *d->contextArray, IO_ReadOnly );
+ t >> hTableSize;
+ uint g = elfHash( context ) % hTableSize;
+ t.tqdevice()->at( 2 + (g << 1) );
+ TQ_UINT16 off;
+ t >> off;
+ if ( off == 0 )
+ return TQTranslatorMessage();
+ t.tqdevice()->at( 2 + (hTableSize << 1) + (off << 1) );
+
+ TQ_UINT8 len;
+ char con[256];
+ for ( ;; ) {
+ t >> len;
+ if ( len == 0 )
+ return TQTranslatorMessage();
+ t.readRawBytes( con, len );
+ con[len] = '\0';
+ if ( qstrcmp(con, context) == 0 )
+ break;
+ }
+ }
+
+ size_t numItems = d->offsetArray->size() / ( 2 * sizeof(TQ_UINT32) );
+ if ( !numItems )
+ return TQTranslatorMessage();
+
+ if ( systemWordSize == 0 )
+ qSysInfo( &systemWordSize, &systemBigEndian );
+
+ for ( ;; ) {
+ TQ_UINT32 h = elfHash( TQCString(sourceText) + comment );
+
+ char *r = (char *) bsearch( &h, d->offsetArray->data(), numItems,
+ 2 * sizeof(TQ_UINT32),
+ systemBigEndian ? cmp_uint32_big
+ : cmp_uint32_little );
+ if ( r != 0 ) {
+ // go back on equal key
+ while ( r != d->offsetArray->data() &&
+ cmp_uint32_big(r - 8, r) == 0 )
+ r -= 8;
+
+ TQDataStream s( *d->offsetArray, IO_ReadOnly );
+ s.tqdevice()->at( r - d->offsetArray->data() );
+
+ TQ_UINT32 rh, ro;
+ s >> rh >> ro;
+
+ TQDataStream ms( *d->messageArray, IO_ReadOnly );
+ while ( rh == h ) {
+ ms.tqdevice()->at( ro );
+ TQTranslatorMessage m( ms );
+ if ( match(m.context(), context)
+ && match(m.sourceText(), sourceText)
+ && match(m.comment(), comment) )
+ return m;
+ if ( s.atEnd() )
+ break;
+ s >> rh >> ro;
+ }
+ }
+ if ( !comment[0] )
+ break;
+ comment = "";
+ }
+ return TQTranslatorMessage();
+}
+
+/*!
+ Returns TRUE if this translator is empty, otherwise returns FALSE.
+ This function works with stripped and unstripped translation files.
+*/
+bool TQTranslator::isEmpty() const
+{
+ return !( d->unmapPointer || d->unmapLength || d->messageArray ||
+ d->offsetArray || d->contextArray
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ || (d->messages && d->messages->count())
+#endif
+ );
+}
+
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+
+/*!
+ Returns a list of the messages in the translator. This function is
+ rather slow. Because it is seldom called, it's optimized for
+ simplicity and small size, rather than speed.
+
+ If you want to iterate over the list, you should iterate over a
+ copy, e.g.
+ \code
+ TQValueList<TQTranslatorMessage> list = myTranslator.messages();
+ TQValueList<TQTranslatorMessage>::Iterator it = list.begin();
+ while ( it != list.end() ) {
+ process_message( *it );
+ ++it;
+ }
+ \endcode
+*/
+
+TQValueList<TQTranslatorMessage> TQTranslator::messages() const
+{
+ if ( d->messages )
+ return d->messages->keys();
+
+ ((TQTranslator *) this)->unsqueeze();
+ TQValueList<TQTranslatorMessage> result = d->messages->keys();
+ delete d->messages;
+ d->messages = 0;
+ return result;
+}
+
+#endif
+
+/*!
+ \class TQTranslatorMessage
+
+ \brief The TQTranslatorMessage class tqcontains a translator message and its
+ properties.
+
+ \ingroup i18n
+ \ingroup environment
+
+ This class is of no interest to most applications. It is useful
+ for translation tools such as \link linguist-manual.book TQt
+ Linguist\endlink. It is provided simply to make the API complete
+ and regular.
+
+ For a TQTranslator object, a lookup key is a triple (\e context, \e
+ {source text}, \e comment) that uniquely identifies a message. An
+ extended key is a quadruple (\e hash, \e context, \e {source
+ text}, \e comment), where \e hash is computed from the source text
+ and the comment. Unless you plan to read and write messages
+ yourself, you need not worry about the hash value.
+
+ TQTranslatorMessage stores this triple or quadruple and the relevant
+ translation if there is any.
+
+ \sa TQTranslator
+*/
+
+/*!
+ Constructs a translator message with the extended key (0, 0, 0, 0)
+ and TQString::null as translation.
+*/
+
+TQTranslatorMessage::TQTranslatorMessage()
+ : h( 0 ), cx( 0 ), st( 0 ), cm( 0 )
+{
+}
+
+
+/*!
+ Constructs an translator message with the extended key (\e h, \a
+ context, \a sourceText, \a comment), where \e h is computed from
+ \a sourceText and \a comment, and possibly with a \a translation.
+*/
+
+TQTranslatorMessage::TQTranslatorMessage( const char * context,
+ const char * sourceText,
+ const char * comment,
+ const TQString& translation )
+ : cx( context ), st( sourceText ), cm( comment ), tn( translation )
+{
+ // 0 means we don't know, "" means empty
+ if ( cx == (const char*)0 )
+ cx = "";
+ if ( st == (const char*)0 )
+ st = "";
+ if ( cm == (const char*)0 )
+ cm = "";
+ h = elfHash( st + cm );
+}
+
+
+/*!
+ Constructs a translator message read from the \a stream. The
+ resulting message may have any combination of content.
+
+ \sa TQTranslator::save()
+*/
+
+TQTranslatorMessage::TQTranslatorMessage( TQDataStream & stream )
+ : cx( 0 ), st( 0 ), cm( 0 )
+{
+ TQString str16;
+ char tag;
+ TQ_UINT8 obs1;
+
+ for ( ;; ) {
+ tag = 0;
+ if ( !stream.atEnd() )
+ stream.readRawBytes( &tag, 1 );
+ switch( (Tag)tag ) {
+ case Tag_End:
+ if ( h == 0 )
+ h = elfHash( st + cm );
+ return;
+ case Tag_SourceText16: // obsolete
+ stream >> str16;
+ st = str16.latin1();
+ break;
+ case Tag_Translation:
+ stream >> tn;
+ break;
+ case Tag_Context16: // obsolete
+ stream >> str16;
+ cx = str16.latin1();
+ break;
+ case Tag_Hash:
+ stream >> h;
+ break;
+ case Tag_SourceText:
+ stream >> st;
+ break;
+ case Tag_Context:
+ stream >> cx;
+ if ( cx == "" ) // for compatibility
+ cx = 0;
+ break;
+ case Tag_Comment:
+ stream >> cm;
+ break;
+ case Tag_Obsolete1: // obsolete
+ stream >> obs1;
+ break;
+ default:
+ h = 0;
+ st = 0;
+ cx = 0;
+ cm = 0;
+ tn = TQString::null;
+ return;
+ }
+ }
+}
+
+
+/*!
+ Constructs a copy of translator message \a m.
+*/
+
+TQTranslatorMessage::TQTranslatorMessage( const TQTranslatorMessage & m )
+ : cx( m.cx ), st( m.st ), cm( m.cm ), tn( m.tn )
+{
+ h = m.h;
+}
+
+
+/*!
+ Assigns message \a m to this translator message and returns a
+ reference to this translator message.
+*/
+
+TQTranslatorMessage & TQTranslatorMessage::operator=(
+ const TQTranslatorMessage & m )
+{
+ h = m.h;
+ cx = m.cx;
+ st = m.st;
+ cm = m.cm;
+ tn = m.tn;
+ return *this;
+}
+
+
+/*!
+ \fn uint TQTranslatorMessage::hash() const
+
+ Returns the hash value used internally to represent the lookup
+ key. This value is zero only if this translator message was
+ constructed from a stream containing invalid data.
+
+ The hashing function is unspecified, but it will remain unchanged
+ in future versions of TQt.
+*/
+
+/*!
+ \fn const char *TQTranslatorMessage::context() const
+
+ Returns the context for this message (e.g. "MyDialog").
+
+ \warning This may return 0 if the TQTranslator object is stripped
+ (compressed).
+*/
+
+/*!
+ \fn const char *TQTranslatorMessage::sourceText() const
+
+ Returns the source text of this message (e.g. "&Save").
+
+ \warning This may return 0 if the TQTranslator object is stripped
+ (compressed).
+*/
+
+/*!
+ \fn const char *TQTranslatorMessage::comment() const
+
+ Returns the comment for this message (e.g. "File|Save").
+
+ \warning This may return 0 if the TQTranslator object is stripped
+ (compressed).
+*/
+
+/*!
+ \fn void TQTranslatorMessage::setTranslation( const TQString & translation )
+
+ Sets the translation of the source text to \a translation.
+
+ \sa translation()
+*/
+
+/*!
+ \fn TQString TQTranslatorMessage::translation() const
+
+ Returns the translation of the source text (e.g., "&Sauvegarder").
+
+ \sa setTranslation()
+*/
+
+/*!
+ \enum TQTranslatorMessage::Prefix
+
+ Let (\e h, \e c, \e s, \e m) be the extended key. The possible
+ prefixes are
+
+ \value NoPrefix no prefix
+ \value Hash only (\e h)
+ \value HashContext only (\e h, \e c)
+ \value HashContextSourceText only (\e h, \e c, \e s)
+ \value HashContextSourceTextComment the whole extended key, (\e
+ h, \e c, \e s, \e m)
+
+ \sa write() commonPrefix()
+*/
+
+/*!
+ Writes this translator message to the \a stream. If \a strip is
+ FALSE (the default), all the information in the message is
+ written. If \a strip is TRUE, only the part of the extended key
+ specified by \a prefix is written with the translation (\c
+ HashContextSourceTextComment by default).
+
+ \sa commonPrefix()
+*/
+
+void TQTranslatorMessage::write( TQDataStream & stream, bool strip,
+ Prefix prefix ) const
+{
+ char tag;
+
+ tag = (char)Tag_Translation;
+ stream.writeRawBytes( &tag, 1 );
+ stream << tn;
+
+ bool mustWriteHash = TRUE;
+ if ( !strip )
+ prefix = HashContextSourceTextComment;
+
+ switch ( prefix ) {
+ case HashContextSourceTextComment:
+ tag = (char)Tag_Comment;
+ stream.writeRawBytes( &tag, 1 );
+ stream << cm;
+ // fall through
+ case HashContextSourceText:
+ tag = (char)Tag_SourceText;
+ stream.writeRawBytes( &tag, 1 );
+ stream << st;
+ // fall through
+ case HashContext:
+ tag = (char)Tag_Context;
+ stream.writeRawBytes( &tag, 1 );
+ stream << cx;
+ // fall through
+ default:
+ if ( mustWriteHash ) {
+ tag = (char)Tag_Hash;
+ stream.writeRawBytes( &tag, 1 );
+ stream << h;
+ }
+ }
+
+ tag = (char)Tag_End;
+ stream.writeRawBytes( &tag, 1 );
+}
+
+
+/*!
+ Returns the widest lookup prefix that is common to this translator
+ message and to message \a m.
+
+ For example, if the extended key is for this message is (71,
+ "PrintDialog", "Yes", "Print?") and that for \a m is (71,
+ "PrintDialog", "No", "Print?"), this function returns \c
+ HashContext.
+
+ \sa write()
+*/
+
+TQTranslatorMessage::Prefix TQTranslatorMessage::commonPrefix(
+ const TQTranslatorMessage& m ) const
+{
+ if ( h != m.h )
+ return NoPrefix;
+ if ( cx != m.cx )
+ return Hash;
+ if ( st != m.st )
+ return HashContext;
+ if ( cm != m.cm )
+ return HashContextSourceText;
+ return HashContextSourceTextComment;
+}
+
+
+/*!
+ Returns TRUE if the extended key of this object is equal to that of
+ \a m; otherwise returns FALSE.
+*/
+
+bool TQTranslatorMessage::operator==( const TQTranslatorMessage& m ) const
+{
+ return h == m.h && cx == m.cx && st == m.st && cm == m.cm;
+}
+
+
+/*!
+ \fn bool TQTranslatorMessage::operator!=( const TQTranslatorMessage& m ) const
+
+ Returns TRUE if the extended key of this object is different from
+ that of \a m; otherwise returns FALSE.
+*/
+
+
+/*!
+ Returns TRUE if the extended key of this object is
+ lexicographically before than that of \a m; otherwise returns
+ FALSE.
+*/
+
+bool TQTranslatorMessage::operator<( const TQTranslatorMessage& m ) const
+{
+ return h != m.h ? h < m.h
+ : ( cx != m.cx ? cx < m.cx
+ : (st != m.st ? st < m.st : cm < m.cm) );
+}
+
+
+/*!
+ \fn bool TQTranslatorMessage::operator<=( const TQTranslatorMessage& m ) const
+
+ Returns TRUE if the extended key of this object is
+ lexicographically before that of \a m or if they are equal;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQTranslatorMessage::operator>( const TQTranslatorMessage& m ) const
+
+ Returns TRUE if the extended key of this object is
+ lexicographically after that of \a m; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQTranslatorMessage::operator>=( const TQTranslatorMessage& m ) const
+
+ Returns TRUE if the extended key of this object is
+ lexicographically after that of \a m or if they are equal;
+ otherwise returns FALSE.
+*/
+
+#endif // USE_QT4
+
+#endif // TQT_NO_TRANSLATION
diff --git a/tqtinterface/qt4/src/kernel/tqtranslator.h b/tqtinterface/qt4/src/kernel/tqtranslator.h
new file mode 100644
index 0000000..b42c983
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqtranslator.h
@@ -0,0 +1,281 @@
+/****************************************************************************
+**
+** Definition of the translator class
+**
+** Created : 980906
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+
+#ifndef TQTRANSLATOR_H
+#define TQTRANSLATOR_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqvaluelist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TRANSLATION
+
+#ifdef USE_QT4
+
+#undef QT_NO_TRANSLATION
+#include <Qt/qtranslator.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQTranslatorPrivate;
+
+class TQ_EXPORT TQTranslatorMessage
+{
+public:
+ TQTranslatorMessage();
+ TQTranslatorMessage( const char * context,
+ const char * sourceText,
+ const char * comment,
+ const TQString& translation = TQString::null );
+ TQTranslatorMessage( TQDataStream & );
+ TQTranslatorMessage( const TQTranslatorMessage & m );
+
+ TQTranslatorMessage & operator=( const TQTranslatorMessage & m );
+
+ uint hash() const { return h; }
+ const char *context() const { return cx; }
+ const char *sourceText() const { return st; }
+ const char *comment() const { return cm; }
+
+ void setTranslation( const TQString & translation ) { tn = translation; }
+ TQString translation() const { return tn; }
+
+ enum Prefix { NoPrefix, Hash, HashContext, HashContextSourceText,
+ HashContextSourceTextComment };
+ void write( TQDataStream & s, bool strip = FALSE,
+ Prefix prefix = HashContextSourceTextComment ) const;
+ Prefix commonPrefix( const TQTranslatorMessage& ) const;
+
+ bool operator==( const TQTranslatorMessage& m ) const;
+ bool operator!=( const TQTranslatorMessage& m ) const
+ { return !operator==( m ); }
+ bool operator<( const TQTranslatorMessage& m ) const;
+ bool operator<=( const TQTranslatorMessage& m ) const
+ { return !m.operator<( *this ); }
+ bool operator>( const TQTranslatorMessage& m ) const
+ { return m.operator<( *this ); }
+ bool operator>=( const TQTranslatorMessage& m ) const
+ { return !operator<( m ); }
+
+private:
+ uint h;
+ TQCString cx;
+ TQCString st;
+ TQCString cm;
+ TQString tn;
+
+ enum Tag { Tag_End = 1, Tag_SourceText16, Tag_Translation, Tag_Context16,
+ Tag_Hash, Tag_SourceText, Tag_Context, Tag_Comment,
+ Tag_Obsolete1 };
+};
+
+// TQTranslator is now a hybrid class that provides Qt4 compatible functionality for basic translations,
+// but also provides separate advanced level translation functions and methods via an independent TQTranslatorPrivate object.
+// Be aware that only the compatible functions can safely interface with Qt4/QApplication!!!
+//
+// See also tools/linguist/shared/translator.cpp for the inspiration behind this idea
+
+class TQ_EXPORT TQTranslator: public QTranslator, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQTranslator( TQObject * tqparent = 0, const char * name = 0 ) : QTranslator( tqparent ) { setObjectName(QString::fromAscii(name)); }
+
+ inline TQString find(const char *context, const char *sourceText, const char * comment = 0) const { return translate(context, sourceText, comment); }
+
+ // Everything below is part of the old API and is therefore incompatible with Qt4 functions which expect a pure QTranslator object or object pointer
+
+#ifndef TQT_NO_COMPAT
+ inline TQString tqfind( const char *context, const char *sourceText, const char * comment = 0 ) const { return tqfindMessage( context, sourceText, comment ).translation(); }
+#endif
+ virtual TQTranslatorMessage tqfindMessage( const char *, const char *, const char * = 0 ) const;
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ enum SaveMode { Everything, Stripped };
+
+ bool save( const TQString & filename, SaveMode mode = Everything );
+
+ void insert( const TQTranslatorMessage& );
+ inline void insert( const char *context, const char *sourceText, const TQString &translation ) { insert( TQTranslatorMessage(context, sourceText, "", translation) ); }
+ void remove( const TQTranslatorMessage& );
+ inline void remove( const char *context, const char *sourceText ) { remove( TQTranslatorMessage(context, sourceText, "") ); }
+
+ void squeeze( SaveMode = Everything );
+ void unsqueeze();
+
+ bool tqcontains( const char *, const char *, const char * comment = 0 ) const;
+
+ TQValueList<TQTranslatorMessage> messages() const;
+#endif
+
+ void clear();
+
+private:
+ TQTranslatorPrivate * d;
+};
+
+#else // USE_QT4
+
+class TQTranslatorPrivate;
+
+class TQ_EXPORT TQTranslatorMessage
+{
+public:
+ TQTranslatorMessage();
+ TQTranslatorMessage( const char * context,
+ const char * sourceText,
+ const char * comment,
+ const TQString& translation = TQString::null );
+ TQTranslatorMessage( TQDataStream & );
+ TQTranslatorMessage( const TQTranslatorMessage & m );
+
+ TQTranslatorMessage & operator=( const TQTranslatorMessage & m );
+
+ uint hash() const { return h; }
+ const char *context() const { return cx; }
+ const char *sourceText() const { return st; }
+ const char *comment() const { return cm; }
+
+ void setTranslation( const TQString & translation ) { tn = translation; }
+ TQString translation() const { return tn; }
+
+ enum Prefix { NoPrefix, Hash, HashContext, HashContextSourceText,
+ HashContextSourceTextComment };
+ void write( TQDataStream & s, bool strip = FALSE,
+ Prefix prefix = HashContextSourceTextComment ) const;
+ Prefix commonPrefix( const TQTranslatorMessage& ) const;
+
+ bool operator==( const TQTranslatorMessage& m ) const;
+ bool operator!=( const TQTranslatorMessage& m ) const
+ { return !operator==( m ); }
+ bool operator<( const TQTranslatorMessage& m ) const;
+ bool operator<=( const TQTranslatorMessage& m ) const
+ { return !m.operator<( *this ); }
+ bool operator>( const TQTranslatorMessage& m ) const
+ { return m.operator<( *this ); }
+ bool operator>=( const TQTranslatorMessage& m ) const
+ { return !operator<( m ); }
+
+private:
+ uint h;
+ TQCString cx;
+ TQCString st;
+ TQCString cm;
+ TQString tn;
+
+ enum Tag { Tag_End = 1, Tag_SourceText16, Tag_Translation, Tag_Context16,
+ Tag_Hash, Tag_SourceText, Tag_Context, Tag_Comment,
+ Tag_Obsolete1 };
+};
+
+
+class TQ_EXPORT TQTranslator: public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQTranslator( TQObject * tqparent = 0, const char * name = 0 );
+ ~TQTranslator();
+
+#ifndef TQT_NO_COMPAT
+ TQString tqfind( const char *context, const char *sourceText, const char * comment = 0 ) const {
+ return tqfindMessage( context, sourceText, comment ).translation();
+ }
+#endif
+ virtual TQTranslatorMessage tqfindMessage( const char *, const char *,
+ const char * = 0 ) const;
+
+ bool load( const TQString & filename,
+ const TQString & directory = TQString::null,
+ const TQString & search_delimiters = TQString::null,
+ const TQString & suffix = TQString::null );
+ bool load( const uchar *data, int len ) {
+ clear();
+ return do_load( data, len );
+ }
+
+ void clear();
+
+#ifndef TQT_NO_TRANSLATION_BUILDER
+ enum SaveMode { Everything, Stripped };
+
+ bool save( const TQString & filename, SaveMode mode = Everything );
+
+ void insert( const TQTranslatorMessage& );
+ void insert( const char *context, const char *sourceText, const TQString &translation ) {
+ insert( TQTranslatorMessage(context, sourceText, "", translation) );
+ }
+ void remove( const TQTranslatorMessage& );
+ void remove( const char *context, const char *sourceText ) {
+ remove( TQTranslatorMessage(context, sourceText, "") );
+ }
+ bool tqcontains( const char *, const char *, const char * comment = 0 ) const;
+
+ void squeeze( SaveMode = Everything );
+ void unsqueeze();
+
+ TQValueList<TQTranslatorMessage> messages() const;
+#endif
+
+ bool isEmpty() const;
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQTranslator( const TQTranslator & );
+ TQTranslator &operator=( const TQTranslator & );
+#endif
+
+ bool do_load( const uchar *data, int len );
+
+ TQTranslatorPrivate * d;
+};
+
+#endif // USE_QT4
+
+#endif // TQT_NO_TRANSLATION
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqucomextra.cpp b/tqtinterface/qt4/src/kernel/tqucomextra.cpp
new file mode 100644
index 0000000..b2f401b
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqucomextra.cpp
@@ -0,0 +1,177 @@
+/****************************************************************************
+**
+** Implementation of extra TQUcom classes
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqucomextra_p.h"
+#include <tqvariant.h>
+
+
+#ifndef TQT_NO_VARIANT
+// 6dc75d58-a1d9-4417-b591-d45c63a3a4ea
+const TQUuid TID_TQUType_TQVariant( 0x6dc75d58, 0xa1d9, 0x4417, 0xb5, 0x91, 0xd4, 0x5c, 0x63, 0xa3, 0xa4, 0xea );
+TQUType_TQVariant static_TQUType_TQVariant;
+
+const TQUuid *TQUType_TQVariant::uuid() const { return &TID_TQUType_TQVariant; }
+const char *TQUType_TQVariant::desc() const { return "TQVariant"; }
+
+void TQUType_TQVariant::set( TQUObject *o, const TQVariant& v )
+{
+ o->payload.ptr = new TQVariant( v );
+ o->type = this;
+}
+
+TQVariant &TQUType_TQVariant::get( TQUObject * o )
+{
+ return *(TQVariant*)o->payload.ptr;
+}
+
+bool TQUType_TQVariant::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( o->type, &static_TQUType_TQString )
+ || isEqual( o->type, &static_TQUType_int )
+ || isEqual( o->type, &static_TQUType_bool )
+ || isEqual( o->type, &static_TQUType_double )
+ || isEqual( o->type, &static_TQUType_charstar ) )
+ return TRUE;
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_TQVariant::canConvertTo( TQUObject * /*o*/, TQUType * /*t*/ )
+{
+ return FALSE;
+}
+
+bool TQUType_TQVariant::convertFrom( TQUObject *o, TQUType *t )
+{
+ TQVariant *var = 0;
+ if ( isEqual( o->type, &static_TQUType_TQString ) )
+ var = new TQVariant( static_TQUType_TQString.get( o ) );
+ else if ( isEqual( o->type, &static_TQUType_int ) )
+ var = new TQVariant( static_TQUType_int.get( o ) );
+ else if ( isEqual( o->type, &static_TQUType_bool ) )
+ var = new TQVariant( static_TQUType_bool.get( o ), 42 );
+ else if ( isEqual( o->type, &static_TQUType_double ) )
+ var = new TQVariant( static_TQUType_double.get( o ) );
+ else if ( isEqual( o->type, &static_TQUType_charstar ) )
+ var = new TQVariant( static_TQUType_charstar.get( o ) );
+ else
+ return t->convertTo( o, this );
+
+ o->type->clear( o );
+ o->payload.ptr = var;
+ o->type = this;
+ return TRUE;
+}
+
+bool TQUType_TQVariant::convertTo( TQUObject * /*o*/, TQUType * /*t*/ )
+{
+ return FALSE;
+}
+
+void TQUType_TQVariant::clear( TQUObject *o )
+{
+ delete (TQVariant*)o->payload.ptr;
+ o->payload.ptr = 0;
+}
+
+int TQUType_TQVariant::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_TQVariant::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+
+#endif
+
+const TQUuid TID_TQUType_varptr( 0x8d48b3a8, 0xbd7f, 0x11d5, 0x8d, 0x74, 0x00, 0xc0, 0xf0, 0x3b, 0xc0, 0xf3 );
+TQUType_varptr static_TQUType_varptr;
+const TQUuid *TQUType_varptr::uuid() const { return &TID_TQUType_varptr; }
+const char *TQUType_varptr::desc() const { return "varptr"; }
+
+void TQUType_varptr::set( TQUObject *o, const void* v )
+{
+ o->payload.ptr = (void*) v;
+ o->type = this;
+}
+
+bool TQUType_varptr::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_ptr ) )
+ return TRUE;
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_varptr::canConvertTo( TQUObject *, TQUType * t)
+{
+ return isEqual( t, &static_TQUType_ptr );
+}
+
+bool TQUType_varptr::convertFrom( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_ptr ) )
+ ;
+ else
+ return t->convertTo( o, this );
+
+ o->type = this;
+ return TRUE;
+}
+
+bool TQUType_varptr::convertTo( TQUObject *o, TQUType * t)
+{
+ if ( isEqual( t, &static_TQUType_ptr ) ) {
+ o->type = &static_TQUType_ptr;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int TQUType_varptr::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_varptr::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
diff --git a/tqtinterface/qt4/src/kernel/tqucomextra_p.h b/tqtinterface/qt4/src/kernel/tqucomextra_p.h
new file mode 100644
index 0000000..0862465
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqucomextra_p.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Definition of extra TQUcom classes
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQUCOMEXTRA_P_H
+#define TQUCOMEXTRA_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#include <private/tqucom_p.h>
+
+#if __GNUC__ - 0 > 3
+#pragma GCC system_header
+#endif
+
+class TQVariant;
+
+#ifndef TQT_NO_VARIANT
+// 6dc75d58-a1d9-4417-b591-d45c63a3a4ea
+extern const TQUuid TID_TQUType_TQVariant;
+
+struct TQ_EXPORT TQUType_TQVariant : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, const TQVariant & );
+ TQVariant &get( TQUObject * o );
+
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * );
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+};
+extern TQ_EXPORT TQUType_TQVariant static_TQUType_TQVariant;
+#endif //TQT_NO_VARIANT
+
+
+// {0x8d48b3a8, 0xbd7f, 0x11d5, 0x8d, 0x74, 0x00, 0xc0, 0xf0, 0x3b, 0xc0, 0xf3 }
+extern TQ_EXPORT const TQUuid TID_TQUType_varptr;
+struct TQ_EXPORT TQUType_varptr : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, const void* );
+ void* &get( TQUObject * o ) { return o->payload.ptr; }
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * ) {}
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+};
+extern TQ_EXPORT TQUType_varptr static_TQUType_varptr;
+
+
+#endif // TQUCOMEXTRA_P_H
+
diff --git a/tqtinterface/qt4/src/kernel/tqurl.cpp b/tqtinterface/qt4/src/kernel/tqurl.cpp
new file mode 100644
index 0000000..a355c4a
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqurl.cpp
@@ -0,0 +1,1345 @@
+/****************************************************************************
+**
+** Implementation of TQUrl class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqurl.h"
+
+#ifndef TQT_NO_URL
+
+#include "tqdir.h"
+
+#include <stdlib.h>
+
+class TQUrlPrivate
+{
+public:
+ TQString protocol;
+ TQString user;
+ TQString pass;
+ TQString host;
+ TQString path, cleanPath;
+ TQString refEncoded;
+ TQString queryEncoded;
+ bool isValid;
+ int port;
+ bool cleanPathDirty;
+};
+
+/*!
+ Replaces backslashes with slashes and removes multiple occurrences
+ of slashes or backslashes if \c allowMultiple is FALSE.
+*/
+
+static void slashify( TQString& s, bool allowMultiple = TRUE )
+{
+ bool justHadSlash = FALSE;
+ for ( int i = 0; i < (int)s.length(); i++ ) {
+ if ( !allowMultiple && justHadSlash &&
+ ( s[ i ] == '/' || s[ i ] == '\\' ) ) {
+ s.remove( i, 1 );
+ --i;
+ continue;
+ }
+ if ( s[ i ] == '\\' )
+ s[ i ] = '/';
+#if defined (TQ_WS_MAC9)
+ if ( s[ i ] == ':' && (i == (int)s.length()-1 || s[ i + 1 ] != '/' ) ) //mac colon's go away, unless after a protocol
+ s[ i ] = '/';
+#endif
+ if ( s[ i ] == '/' )
+ justHadSlash = TRUE;
+ else
+ justHadSlash = FALSE;
+ }
+}
+
+
+
+/*!
+ \class TQUrl tqurl.h
+
+ \brief The TQUrl class provides a URL parser and simplifies working with URLs.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \ingroup misc
+ \mainclass
+
+ \module network
+
+ The TQUrl class is provided for simple work with URLs. It can
+ parse, decode, encode, etc.
+
+ TQUrl works with the decoded path and encoded query in turn.
+
+ Example:
+
+ <tt>http://www.trolltech.com:80/cgi-bin/test%20me.pl?cmd=Hello%20you</tt>
+
+ \table
+ \header \i Function \i Returns
+ \row \i \l protocol() \i "http"
+ \row \i \l host() \i "www.trolltech.com"
+ \row \i \l port() \i 80
+ \row \i \l path() \i "/cgi-bin/test&nbsp;me.pl"
+ \row \i \l fileName() \i "test&nbsp;me.pl"
+ \row \i \l query() \i "cmd=Hello%20you"
+ \endtable
+
+ Example:
+
+ <tt>http://doc.trolltech.com/tqdockarea.html#lines</tt>
+
+ \table
+ \header \i Function \i Returns
+ \row \i \l protocol() \i "http"
+ \row \i \l host() \i "doc.trolltech.com"
+ \row \i \l fileName() \i "tqdockarea.html"
+ \row \i \l ref() \i "lines"
+ \endtable
+
+ The individual parts of a URL can be set with setProtocol(),
+ setHost(), setPort(), setPath(), setFileName(), setRef() and
+ setQuery(). A URL could contain, for example, an ftp address which
+ requires a user name and password; these can be set with setUser()
+ and setPassword().
+
+ Because path is always encoded internally you must not use "%00"
+ in the path, although this is okay (but not recommended) for the
+ query.
+
+ TQUrl is normally used like this:
+
+ \code
+ TQUrl url( "http://www.trolltech.com" );
+ // or
+ TQUrl url( "file:/home/myself/Mail", "Inbox" );
+ \endcode
+
+ You can then access and manipulate the various parts of the URL.
+
+ To make it easy to work with TQUrls and TQStrings, TQUrl implements
+ the necessary cast and assignment operators so you can do
+ following:
+
+ \code
+ TQUrl url( "http://www.trolltech.com" );
+ TQString s = url;
+ // or
+ TQString s( "http://www.trolltech.com" );
+ TQUrl url( s );
+ \endcode
+
+ Use the static functions, encode() and decode() to encode or
+ decode a URL in a string. (They operate on the string in-place.)
+ The isRelativeUrl() static function returns TRUE if the given
+ string is a relative URL.
+
+ If you want to use a URL to work on a hierarchical structure (e.g.
+ a local or remote filesystem), you might want to use the subclass
+ TQUrlOperator.
+
+ \sa TQUrlOperator
+*/
+
+
+/*!
+ Constructs an empty URL that is invalid.
+*/
+
+TQUrl::TQUrl()
+{
+ d = new TQUrlPrivate;
+ d->isValid = FALSE;
+ d->port = -1;
+ d->cleanPathDirty = TRUE;
+}
+
+/*!
+ Constructs a URL by parsing the string \a url.
+
+ If you pass a string like "/home/qt", the "file" protocol is
+ assumed.
+*/
+
+TQUrl::TQUrl( const TQString& url )
+{
+ d = new TQUrlPrivate;
+ d->protocol = "file";
+ d->port = -1;
+ parse( url );
+}
+
+/*!
+ Copy constructor. Copies the data of \a url.
+*/
+
+TQUrl::TQUrl( const TQUrl& url )
+{
+ d = new TQUrlPrivate;
+ *d = *url.d;
+}
+
+/*!
+ Returns TRUE if \a url is relative; otherwise returns FALSE.
+*/
+
+bool TQUrl::isRelativeUrl( const TQString &url )
+{
+ int colon = url.tqfind( ":" );
+ int slash = url.tqfind( "/" );
+
+ return ( slash != 0 && ( colon == -1 || ( slash != -1 && colon > slash ) ) );
+}
+
+/*!
+ Constructs an URL taking \a url as the base (context) and
+ \a relUrl as a relative URL to \a url. If \a relUrl is not relative,
+ \a relUrl is taken as the new URL.
+
+ For example, the path of
+ \code
+ TQUrl url( "ftp://ftp.trolltech.com/qt/source", "qt-2.1.0.tar.gz" );
+ \endcode
+ will be "/qt/srource/qt-2.1.0.tar.gz".
+
+ On the other hand,
+ \code
+ TQUrl url( "ftp://ftp.trolltech.com/qt/source", "/usr/local" );
+ \endcode
+ will result in a new URL, "ftp://ftp.trolltech.com/usr/local",
+ because "/usr/local" isn't relative.
+
+ Similarly,
+ \code
+ TQUrl url( "ftp://ftp.trolltech.com/qt/source", "file:/usr/local" );
+ \endcode
+ will result in a new URL, with "/usr/local" as the path
+ and "file" as the protocol.
+
+ Normally it is expected that the path of \a url points to a
+ directory, even if the path has no slash at the end. But if you
+ want the constructor to handle the last part of the path as a file
+ name if there is no slash at the end, and to let it be tqreplaced by
+ the file name of \a relUrl (if it tqcontains one), set \a checkSlash
+ to TRUE.
+*/
+
+TQUrl::TQUrl( const TQUrl& url, const TQString& relUrl, bool checkSlash )
+{
+ d = new TQUrlPrivate;
+ TQString rel = relUrl;
+ slashify( rel );
+
+ TQUrl urlTmp( url );
+ if ( !urlTmp.isValid() ) {
+ urlTmp.reset();
+ }
+ if ( isRelativeUrl( rel ) ) {
+ if ( rel[ 0 ] == '#' ) {
+ *this = urlTmp;
+ rel.remove( (uint)0, 1 );
+ decode( rel );
+ setRef( rel );
+ } else if ( rel[ 0 ] == '?' ) {
+ *this = urlTmp;
+ rel.remove( (uint)0, 1 );
+ setQuery( rel );
+ } else {
+ decode( rel );
+ *this = urlTmp;
+ setRef( TQString::null );
+ if ( checkSlash && d->cleanPath[(int)path().length()-1] != '/' ) {
+ if ( isRelativeUrl( path() ) )
+ setEncodedPathAndQuery( rel );
+ else
+ setFileName( rel );
+ } else {
+ TQString p = urlTmp.path();
+ if ( p.isEmpty() ) {
+ // allow URLs like "file:foo"
+ if ( !d->host.isEmpty() && !d->user.isEmpty() && !d->pass.isEmpty() )
+ p = "/";
+ }
+ if ( !p.isEmpty() && p.right(1)!="/" )
+ p += "/";
+ p += rel;
+ d->path = p;
+ d->cleanPathDirty = TRUE;
+ }
+ }
+ } else {
+ if ( rel[ 0 ] == TQChar( '/' ) ) {
+ *this = urlTmp;
+ setEncodedPathAndQuery( rel );
+ } else {
+ *this = rel;
+ }
+ }
+}
+
+/*!
+ Destructor.
+*/
+
+TQUrl::~TQUrl()
+{
+ delete d;
+ d = 0;
+}
+
+/*!
+ Returns the protocol of the URL. Typically, "file", "http", "ftp",
+ etc.
+
+ \sa setProtocol()
+*/
+
+TQString TQUrl::protocol() const
+{
+ return d->protocol;
+}
+
+/*!
+ Sets the protocol of the URL to \a protocol. Typically, "file",
+ "http", "ftp", etc.
+
+ \sa protocol()
+*/
+
+void TQUrl::setProtocol( const TQString& protocol )
+{
+ d->protocol = protocol;
+ if ( hasHost() )
+ d->isValid = TRUE;
+}
+
+/*!
+ Returns the username of the URL.
+
+ \sa setUser() setPassword()
+*/
+
+TQString TQUrl::user() const
+{
+ return d->user;
+}
+
+/*!
+ Sets the username of the URL to \a user.
+
+ \sa user() setPassword()
+*/
+
+void TQUrl::setUser( const TQString& user )
+{
+ d->user = user;
+}
+
+/*!
+ Returns TRUE if the URL tqcontains a username; otherwise returns
+ FALSE.
+
+ \sa setUser() setPassword()
+*/
+
+bool TQUrl::hasUser() const
+{
+ return !d->user.isEmpty();
+}
+
+/*!
+ Returns the password of the URL.
+
+ \warning Passwords passed in URLs are normally \e insecure; this
+ is due to the mechanism, not because of TQt.
+
+ \sa setPassword() setUser()
+*/
+
+TQString TQUrl::password() const
+{
+ return d->pass;
+}
+
+/*!
+ Sets the password of the URL to \a pass.
+
+ \warning Passwords passed in URLs are normally \e insecure; this
+ is due to the mechanism, not because of TQt.
+
+ \sa password() setUser()
+*/
+
+void TQUrl::setPassword( const TQString& pass )
+{
+ d->pass = pass;
+}
+
+/*!
+ Returns TRUE if the URL tqcontains a password; otherwise returns
+ FALSE.
+
+ \warning Passwords passed in URLs are normally \e insecure; this
+ is due to the mechanism, not because of TQt.
+
+ \sa setPassword() setUser()
+*/
+
+bool TQUrl::hasPassword() const
+{
+ return !d->pass.isEmpty();
+}
+
+/*!
+ Returns the hostname of the URL.
+
+ \sa setHost() hasHost()
+*/
+
+TQString TQUrl::host() const
+{
+ return d->host;
+}
+
+/*!
+ Sets the hostname of the URL to \a host.
+
+ \sa host() hasHost()
+*/
+
+void TQUrl::setHost( const TQString& host )
+{
+ d->host = host;
+ if ( !d->protocol.isNull() && d->protocol != "file" )
+ d->isValid = TRUE;
+}
+
+/*!
+ Returns TRUE if the URL tqcontains a hostname; otherwise returns
+ FALSE.
+
+ \sa setHost()
+*/
+
+bool TQUrl::hasHost() const
+{
+ return !d->host.isEmpty();
+}
+
+/*!
+ Returns the port of the URL or -1 if no port has been set.
+
+ \sa setPort()
+*/
+
+int TQUrl::port() const
+{
+ return d->port;
+}
+
+/*!
+ Sets the port of the URL to \a port.
+
+ \sa port()
+*/
+
+void TQUrl::setPort( int port )
+{
+ d->port = port;
+}
+
+/*!
+ Returns TRUE if the URL tqcontains a port; otherwise returns FALSE.
+
+ \sa setPort()
+*/
+
+bool TQUrl::hasPort() const
+{
+ return d->port >= 0;
+}
+
+/*!
+ Sets the path of the URL to \a path.
+
+ \sa path() hasPath()
+*/
+
+void TQUrl::setPath( const TQString& path )
+{
+ d->path = path;
+ slashify( d->path );
+ d->cleanPathDirty = TRUE;
+ d->isValid = TRUE;
+}
+
+/*!
+ Returns TRUE if the URL tqcontains a path; otherwise returns FALSE.
+
+ \sa path() setPath()
+*/
+
+bool TQUrl::hasPath() const
+{
+ return !d->path.isEmpty();
+}
+
+/*!
+ Sets the query of the URL to \a txt. \a txt must be encoded.
+
+ \sa query() encode()
+*/
+
+void TQUrl::setQuery( const TQString& txt )
+{
+ d->queryEncoded = txt;
+}
+
+/*!
+ Returns the (encoded) query of the URL.
+
+ \sa setQuery() decode()
+*/
+
+TQString TQUrl::query() const
+{
+ return d->queryEncoded;
+}
+
+/*!
+ Returns the (encoded) reference of the URL.
+
+ \sa setRef() hasRef() decode()
+*/
+
+TQString TQUrl::ref() const
+{
+ return d->refEncoded;
+}
+
+/*!
+ Sets the reference of the URL to \a txt. \a txt must be encoded.
+
+ \sa ref() hasRef() encode()
+*/
+
+void TQUrl::setRef( const TQString& txt )
+{
+ d->refEncoded = txt;
+}
+
+/*!
+ Returns TRUE if the URL has a reference; otherwise returns FALSE.
+
+ \sa setRef()
+*/
+
+bool TQUrl::hasRef() const
+{
+ return !d->refEncoded.isEmpty();
+}
+
+/*!
+ Returns TRUE if the URL is valid; otherwise returns FALSE. A URL
+ is invalid if it cannot be parsed, for example.
+*/
+
+bool TQUrl::isValid() const
+{
+ return d->isValid;
+}
+
+/*!
+ Resets all parts of the URL to their default values and
+ invalidates it.
+*/
+
+void TQUrl::reset()
+{
+ d->protocol = "file";
+ d->user = "";
+ d->pass = "";
+ d->host = "";
+ d->path = "";
+ d->queryEncoded = "";
+ d->refEncoded = "";
+ d->isValid = TRUE;
+ d->port = -1;
+ d->cleanPathDirty = TRUE;
+}
+
+/*!
+ Parses the \a url.
+*/
+
+bool TQUrl::parse( const TQString& url )
+{
+ TQString url_( url );
+ slashify( url_ );
+
+ if ( url_.isEmpty() ) {
+ d->isValid = FALSE;
+ return FALSE;
+ }
+
+ d->cleanPathDirty = TRUE;
+ d->isValid = TRUE;
+ TQString oldProtocol = d->protocol;
+ d->protocol = TQString::null;
+
+ const int Init = 0;
+ const int Protocol = 1;
+ const int Separator1= 2; // :
+ const int Separator2= 3; // :/
+ const int Separator3= 4; // :// or more slashes
+ const int User = 5;
+ const int Pass = 6;
+ const int Host = 7;
+ const int Path = 8;
+ const int Ref = 9;
+ const int Query = 10;
+ const int Port = 11;
+ const int Done = 12;
+
+ const int InputAlpha= 1;
+ const int InputDigit= 2;
+ const int InputSlash= 3;
+ const int InputColon= 4;
+ const int InputAt = 5;
+ const int InputHash = 6;
+ const int InputQuery= 7;
+
+ static uchar table[ 12 ][ 8 ] = {
+ /* None InputAlpha InputDigit InputSlash InputColon InputAt InputHash InputQuery */
+ { 0, Protocol, 0, Path, 0, 0, 0, 0, }, // Init
+ { 0, Protocol, Protocol, 0, Separator1, 0, 0, 0, }, // Protocol
+ { 0, Path, Path, Separator2, 0, 0, 0, 0, }, // Separator1
+ { 0, Path, Path, Separator3, 0, 0, 0, 0, }, // Separator2
+ { 0, User, User, Separator3, Pass, Host, 0, 0, }, // Separator3
+ { 0, User, User, User, Pass, Host, User, User, }, // User
+ { 0, Pass, Pass, Pass, Pass, Host, Pass, Pass, }, // Pass
+ { 0, Host, Host, Path, Port, Host, Ref, Query, }, // Host
+ { 0, Path, Path, Path, Path, Path, Ref, Query, }, // Path
+ { 0, Ref, Ref, Ref, Ref, Ref, Ref, Query, }, // Ref
+ { 0, Query, Query, Query, Query, Query, Query, Query, }, // Query
+ { 0, 0, Port, Path, 0, 0, 0, 0, } // Port
+ };
+
+ bool relPath = FALSE;
+
+ relPath = FALSE;
+ bool forceRel = FALSE;
+
+ // If ':' is at pos 1, we have only one letter
+ // before that separator => that's a drive letter!
+ if ( url_.length() >= 2 && url_[1] == ':' )
+ relPath = forceRel = TRUE;
+
+ int hasNoHost = -1;
+ int cs = url_.tqfind( ":/" );
+ if ( cs != -1 ) // if a protocol is there, tqfind out if there is a host or directly the path after it
+ hasNoHost = url_.tqfind( "///", cs );
+ table[ 4 ][ 1 ] = User;
+ table[ 4 ][ 2 ] = User;
+ if ( cs == -1 || forceRel ) { // we have a relative file
+ if ( url.tqfind( ':' ) == -1 || forceRel ) {
+ table[ 0 ][ 1 ] = Path;
+ // Filenames may also begin with a digit
+ table[ 0 ][ 2 ] = Path;
+ } else {
+ table[ 0 ][ 1 ] = Protocol;
+ }
+ relPath = TRUE;
+ } else { // some checking
+ table[ 0 ][ 1 ] = Protocol;
+
+ // tqfind the part between the protocol and the path as the meaning
+ // of that part is dependend on some chars
+ ++cs;
+ while ( url_[ cs ] == '/' )
+ ++cs;
+ int slash = url_.tqfind( "/", cs );
+ if ( slash == -1 )
+ slash = url_.length() - 1;
+ TQString tmp = url_.mid( cs, slash - cs + 1 );
+
+ if ( !tmp.isEmpty() ) { // if this part exists
+
+ // look for the @ in this part
+ int at = tmp.tqfind( "@" );
+ if ( at != -1 )
+ at += cs;
+ // we have no @, which means host[:port], so directly
+ // after the protocol the host starts, or if the protocol
+ // is file or there were more than 2 slashes, it�s the
+ // path
+ if ( at == -1 ) {
+ if ( url_.left( 4 ) == "file" || hasNoHost != -1 )
+ table[ 4 ][ 1 ] = Path;
+ else
+ table[ 4 ][ 1 ] = Host;
+ table[ 4 ][ 2 ] = table[ 4 ][ 1 ];
+ }
+ }
+ }
+
+ int state = Init; // parse state
+ int input; // input token
+
+ TQChar c = url_.at( 0 );
+ int i = 0;
+ TQString port;
+
+ for ( ;; ) {
+ switch ( c ) {
+ case '?':
+ input = InputQuery;
+ break;
+ case '#':
+ input = InputHash;
+ break;
+ case '@':
+ input = InputAt;
+ break;
+ case ':':
+ input = InputColon;
+ break;
+ case '/':
+ input = InputSlash;
+ break;
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9': case '0':
+ input = InputDigit;
+ break;
+ default:
+ input = InputAlpha;
+ }
+
+ state = table[ state ][ input ];
+
+ switch ( state ) {
+ case Protocol:
+ d->protocol += c;
+ break;
+ case User:
+ d->user += c;
+ break;
+ case Pass:
+ d->pass += c;
+ break;
+ case Host:
+ d->host += c;
+ break;
+ case Path:
+ d->path += c;
+ break;
+ case Ref:
+ d->refEncoded += c;
+ break;
+ case Query:
+ d->queryEncoded += c;
+ break;
+ case Port:
+ port += c;
+ break;
+ default:
+ break;
+ }
+
+ ++i;
+ if ( i > (int)url_.length() - 1 || state == Done || state == 0 )
+ break;
+ c = url_[ i ];
+
+ }
+
+ if ( !port.isEmpty() ) {
+ port.remove( (uint)0, 1 );
+ d->port = atoi( port.latin1() );
+ }
+
+ // error
+ if ( i < (int)url_.length() - 1 ) {
+ d->isValid = FALSE;
+ return FALSE;
+ }
+
+
+ if ( d->protocol.isEmpty() )
+ d->protocol = oldProtocol;
+
+ if ( d->path.isEmpty() )
+ d->path = "/";
+
+ // hack for windows
+ if ( d->path.length() == 2 && d->path[ 1 ] == ':' )
+ d->path += "/";
+
+ // #### do some corrections, should be done nicer too
+ if ( !d->pass.isEmpty() ) {
+ if ( d->pass[ 0 ] == ':' )
+ d->pass.remove( (uint)0, 1 );
+ decode( d->pass );
+ }
+ if ( !d->user.isEmpty() ) {
+ decode( d->user );
+ }
+ if ( !d->path.isEmpty() ) {
+ if ( d->path[ 0 ] == '@' || d->path[ 0 ] == ':' )
+ d->path.remove( (uint)0, 1 );
+ if ( d->path[ 0 ] != '/' && !relPath && d->path[ 1 ] != ':' )
+ d->path.prepend( "/" );
+ }
+ if ( !d->refEncoded.isEmpty() && d->refEncoded[ 0 ] == '#' )
+ d->refEncoded.remove( (uint)0, 1 );
+ if ( !d->queryEncoded.isEmpty() && d->queryEncoded[ 0 ] == '?' )
+ d->queryEncoded.remove( (uint)0, 1 );
+ if ( !d->host.isEmpty() && d->host[ 0 ] == '@' )
+ d->host.remove( (uint)0, 1 );
+
+#if defined(TQ_OS_WIN32)
+ // hack for windows file://machine/path syntax
+ if ( d->protocol == "file" ) {
+ if ( url.left( 7 ) == "file://" &&
+ d->path.length() > 1 && d->path[ 1 ] != ':' )
+ d->path.prepend( "/" );
+ }
+#endif
+
+ decode( d->path );
+ d->cleanPathDirty = TRUE;
+
+#if 0
+ qDebug( "URL: %s", url.latin1() );
+ qDebug( "protocol: %s", d->protocol.latin1() );
+ qDebug( "user: %s", d->user.latin1() );
+ qDebug( "pass: %s", d->pass.latin1() );
+ qDebug( "host: %s", d->host.latin1() );
+ qDebug( "path: %s", path().latin1() );
+ qDebug( "ref: %s", d->refEncoded.latin1() );
+ qDebug( "query: %s", d->queryEncoded.latin1() );
+ qDebug( "port: %d\n\n----------------------------\n\n", d->port );
+#endif
+
+ return TRUE;
+}
+
+/*!
+ \overload
+
+ Parses \a url and assigns the resulting data to this class.
+
+ If you pass a string like "/home/qt" the "file" protocol will be
+ assumed.
+*/
+
+TQUrl& TQUrl::operator=( const TQString& url )
+{
+ reset();
+ parse( url );
+
+ return *this;
+}
+
+/*!
+ Assigns the data of \a url to this class.
+*/
+
+TQUrl& TQUrl::operator=( const TQUrl& url )
+{
+ *d = *url.d;
+ return *this;
+}
+
+/*!
+ Compares this URL with \a url and returns TRUE if they are equal;
+ otherwise returns FALSE.
+*/
+
+bool TQUrl::operator==( const TQUrl& url ) const
+{
+ if ( !isValid() || !url.isValid() )
+ return FALSE;
+
+ if ( d->protocol == url.d->protocol &&
+ d->user == url.d->user &&
+ d->pass == url.d->pass &&
+ d->host == url.d->host &&
+ d->path == url.d->path &&
+ d->queryEncoded == url.d->queryEncoded &&
+ d->refEncoded == url.d->refEncoded &&
+ d->isValid == url.d->isValid &&
+ d->port == url.d->port )
+ return TRUE;
+
+ return FALSE;
+}
+
+/*!
+ \overload
+
+ Compares this URL with \a url. \a url is parsed first. Returns
+ TRUE if \a url is equal to this url; otherwise returns FALSE.
+*/
+
+bool TQUrl::operator==( const TQString& url ) const
+{
+ TQUrl u( url );
+ return ( *this == u );
+}
+
+/*!
+ Sets the file name of the URL to \a name. If this URL tqcontains a
+ fileName(), the original file name is tqreplaced by \a name.
+
+ See the documentation of fileName() for a more detailed discussion
+ of what is handled as file name and what is handled as a directory
+ path.
+
+ \sa fileName()
+*/
+
+void TQUrl::setFileName( const TQString& name )
+{
+ TQString fn( name );
+ slashify( fn );
+
+ while ( fn[ 0 ] == '/' )
+ fn.remove( (uint)0, 1 );
+
+ TQString p;
+ if ( path().isEmpty() ) {
+ p = "/";
+ } else {
+ p = path();
+ int slash = p.tqfindRev( TQChar( '/' ) );
+ if ( slash == -1 ) {
+ p = "/";
+ } else if ( p[ (int)p.length() - 1 ] != '/' ) {
+ p.truncate( slash + 1 );
+ }
+ }
+
+ p += fn;
+ if ( !d->queryEncoded.isEmpty() )
+ p += "?" + d->queryEncoded;
+ setEncodedPathAndQuery( p );
+}
+
+/*!
+ Returns the encoded path and query.
+
+ \sa decode()
+*/
+
+TQString TQUrl::encodedPathAndQuery()
+{
+ TQString p = path();
+ if ( p.isEmpty() )
+ p = "/";
+
+ encode( p );
+
+ if ( !d->queryEncoded.isEmpty() ) {
+ p += "?";
+ p += d->queryEncoded;
+ }
+
+ return p;
+}
+
+/*!
+ Parses \a pathAndQuery for a path and query and sets those values.
+ The whole string must be encoded.
+
+ \sa encode()
+*/
+
+void TQUrl::setEncodedPathAndQuery( const TQString& pathAndQuery )
+{
+ d->cleanPathDirty = TRUE;
+ int pos = pathAndQuery.tqfind( '?' );
+ if ( pos == -1 ) {
+ d->path = pathAndQuery;
+ d->queryEncoded = "";
+ } else {
+ d->path = pathAndQuery.left( pos );
+ d->queryEncoded = pathAndQuery.mid( pos + 1 );
+ }
+
+ decode( d->path );
+ d->cleanPathDirty = TRUE;
+}
+
+extern bool qt_resolve_symlinks; // defined in qapplication.cpp
+
+/*!
+ Returns the path of the URL. If \a correct is TRUE, the path is
+ cleaned (deals with too many or too few slashes, cleans things
+ like "/../..", etc). Otherwise path() returns exactly the path
+ that was parsed or set.
+
+ \sa setPath() hasPath()
+*/
+TQString TQUrl::path( bool correct ) const
+{
+ if ( !correct )
+ return d->path;
+
+ if ( d->cleanPathDirty ) {
+ bool check = TRUE;
+ if ( TQDir::isRelativePath( d->path ) ) {
+ d->cleanPath = d->path;
+ } else if ( isLocalFile() ) {
+#if defined(TQ_OS_WIN32)
+ // hack for stuff like \\machine\path and //machine/path on windows
+ if ( ( d->path.left( 1 ) == "/" || d->path.left( 1 ) == "\\" ) &&
+ d->path.length() > 1 ) {
+ d->cleanPath = d->path;
+ bool share = (d->cleanPath[0] == '\\' && d->cleanPath[1] == '\\') ||
+ (d->cleanPath[0] == '/' && d->cleanPath[1] == '/');
+ slashify( d->cleanPath, FALSE );
+ d->cleanPath = TQDir::cleanDirPath( d->cleanPath );
+ if ( share ) {
+ check = FALSE;
+ while (d->cleanPath.at(0) != '/' || d->cleanPath.at(1) != '/')
+ d->cleanPath.prepend("/");
+ }
+ }
+#endif
+ if ( check ) {
+ TQFileInfo fi( d->path );
+ if ( !fi.exists() )
+ d->cleanPath = d->path;
+ else if ( fi.isDir() ) {
+ TQString canPath = TQDir( d->path ).canonicalPath();
+ TQString dir;
+ if ( qt_resolve_symlinks && !canPath.isNull() )
+ dir = TQDir::cleanDirPath( canPath );
+ else
+ dir = TQDir::cleanDirPath( TQDir( d->path ).absPath() );
+ dir += "/";
+ if ( dir == "//" )
+ d->cleanPath = "/";
+ else
+ d->cleanPath = dir;
+ } else {
+ TQString p =
+ TQDir::cleanDirPath( (qt_resolve_symlinks ?
+ fi.dir().canonicalPath() :
+ fi.dir().absPath()) );
+ d->cleanPath = p + "/" + fi.fileName();
+ }
+ }
+ } else {
+ if ( d->path != "/" && d->path[ (int)d->path.length() - 1 ] == '/' )
+ d->cleanPath = TQDir::cleanDirPath( d->path ) + "/";
+ else
+ d->cleanPath = TQDir::cleanDirPath( d->path );
+ }
+
+ if ( check )
+ slashify( d->cleanPath, FALSE );
+ d->cleanPathDirty = FALSE;
+ }
+
+ return d->cleanPath;
+}
+
+/*!
+ Returns TRUE if the URL is a local file; otherwise returns FALSE.
+*/
+
+bool TQUrl::isLocalFile() const
+{
+ return d->protocol == "file";
+}
+
+/*!
+ Returns the file name of the URL. If the path of the URL doesn't
+ have a slash at the end, the part between the last slash and the
+ end of the path string is considered to be the file name. If the
+ path has a slash at the end, an empty string is returned here.
+
+ \sa setFileName()
+*/
+
+TQString TQUrl::fileName() const
+{
+ if ( d->path.isEmpty() || d->path.endsWith( "/" )
+#ifdef TQ_WS_WIN
+ || d->path.endsWith( "\\" )
+#endif
+ )
+ return TQString::null;
+
+ return TQFileInfo( d->path ).fileName();
+}
+
+/*!
+ Adds the path \a pa to the path of the URL.
+
+ \sa setPath() hasPath()
+*/
+
+void TQUrl::addPath( const TQString& pa )
+{
+ if ( pa.isEmpty() )
+ return;
+
+ TQString p( pa );
+ slashify( p );
+
+ if ( path().isEmpty() ) {
+ if ( p[ 0 ] != TQChar( '/' ) )
+ d->path = "/" + p;
+ else
+ d->path = p;
+ } else {
+ if ( p[ 0 ] != TQChar( '/' ) && d->path[ (int)d->path.length() - 1 ] != '/' )
+ d->path += "/" + p;
+ else
+ d->path += p;
+ }
+ d->cleanPathDirty = TRUE;
+}
+
+/*!
+ Returns the directory path of the URL. This is the part of the
+ path of the URL without the fileName(). See the documentation of
+ fileName() for a discussion of what is handled as file name and
+ what is handled as directory path.
+
+ \sa setPath() hasPath()
+*/
+
+TQString TQUrl::dirPath() const
+{
+ if ( path().isEmpty() )
+ return TQString::null;
+
+ TQString s = path();
+ int pos = s.tqfindRev( '/' );
+ if ( pos == -1 ) {
+ return TQString::tqfromLatin1(".");
+ } else {
+ if ( pos == 0 )
+ return TQString::tqfromLatin1( "/" );
+ return s.left( pos );
+ }
+}
+
+/*!
+ Encodes the \a url in-place into UTF-8. For example
+
+ \code
+ TQString url = http://www.trolltech.com
+ TQUrl::encode( url );
+ // url is now "http%3A//www%20trolltech%20com"
+ \endcode
+
+ \sa decode()
+*/
+
+void TQUrl::encode( TQString& url )
+{
+ if ( url.isEmpty() )
+ return;
+
+ TQCString curl = url.utf8();
+ int oldlen = curl.length();
+
+ const TQCString special( "+<>#@\"&%$:,;?={}|^~[]\'`\\ \n\t\r" );
+ TQString newUrl;
+ int newlen = 0;
+
+ for ( int i = 0; i < oldlen ;++i ) {
+ uchar inCh = (uchar)curl[ i ];
+
+ if ( inCh >= 128 || special.tqcontains(inCh) ) {
+ newUrl[ newlen++ ] = TQChar( '%' );
+
+ ushort c = inCh / 16;
+ c += c > 9 ? 'A' - 10 : '0';
+ newUrl[ newlen++ ] = c;
+
+ c = inCh % 16;
+ c += c > 9 ? 'A' - 10 : '0';
+ newUrl[ newlen++ ] = c;
+ } else {
+ newUrl[ newlen++ ] = inCh;
+ }
+ }
+
+ url = newUrl;
+}
+
+static uchar hex_to_int( uchar c )
+{
+ if ( c >= 'A' && c <= 'F' )
+ return c - 'A' + 10;
+ if ( c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ if ( c >= '0' && c <= '9')
+ return c - '0';
+ return 0;
+}
+
+/*!
+ Decodes the \a url in-place into UTF-8. For example
+
+ \code
+ TQString url = "http%3A//www%20trolltech%20com"
+ TQUrl::decode( url );
+ // url is now "http://www.trolltech.com"
+ \endcode
+
+ \sa encode()
+*/
+
+void TQUrl::decode( TQString& url )
+{
+ if ( url.isEmpty() )
+ return;
+
+ int newlen = 0;
+ TQCString curl = url.utf8();
+ int oldlen = curl.length();
+
+ TQCString newUrl(oldlen);
+
+ int i = 0;
+ while ( i < oldlen ) {
+ uchar c = (uchar)curl[ i++ ];
+ if ( c == '%' && i <= oldlen - 2 ) {
+ c = hex_to_int( (uchar)curl[ i ] ) * 16 + hex_to_int( (uchar)curl[ i + 1 ] );
+ i += 2;
+ }
+ newUrl [ newlen++ ] = c;
+ }
+ newUrl.truncate( newlen );
+
+ url = TQString::fromUtf8(newUrl.data());
+}
+
+
+/*!
+ Composes a string version of the URL and returns it. If \a
+ encodedPath is TRUE the path in the returned string is encoded. If
+ \a forcePrependProtocol is TRUE and \a encodedPath looks like a
+ local filename, the "file:/" protocol is also prepended.
+
+ \sa encode() decode()
+*/
+
+TQString TQUrl::toString( bool encodedPath, bool forcePrependProtocol ) const
+{
+ TQString res, p = path();
+ if ( encodedPath )
+ encode( p );
+
+ if ( isLocalFile() ) {
+ if ( forcePrependProtocol )
+ res = d->protocol + ":" + p;
+ else
+ res = p;
+ } else if ( d->protocol == "mailto" ) {
+ res = d->protocol + ":" + p;
+ } else {
+ res = d->protocol + "://";
+ if ( !d->user.isEmpty() || !d->pass.isEmpty() ) {
+ TQString tmp;
+ if ( !d->user.isEmpty() ) {
+ tmp = d->user;
+ encode( tmp );
+ res += tmp;
+ }
+ if ( !d->pass.isEmpty() ) {
+ tmp = d->pass;
+ encode( tmp );
+ res += ":" + tmp;
+ }
+ res += "@";
+ }
+ res += d->host;
+ if ( d->port != -1 )
+ res += ":" + TQString( "%1" ).arg( d->port );
+ if ( !p.isEmpty() ) {
+ if ( !d->host.isEmpty() && p[0]!='/' )
+ res += "/";
+ res += p;
+ }
+ }
+
+ if ( !d->refEncoded.isEmpty() )
+ res += "#" + d->refEncoded;
+ if ( !d->queryEncoded.isEmpty() )
+ res += "?" + d->queryEncoded;
+
+ return res;
+}
+
+/*!
+ Composes a string version of the URL and returns it.
+
+ \sa TQUrl::toString()
+*/
+
+TQUrl::operator TQString() const
+{
+ return toString();
+}
+
+/*!
+ Changes the directory to one directory up.
+
+ \sa setPath()
+*/
+
+bool TQUrl::cdUp()
+{
+ d->path += "/..";
+ d->cleanPathDirty = TRUE;
+ return TRUE;
+}
+
+#endif // TQT_NO_URL
diff --git a/tqtinterface/qt4/src/kernel/tqurl.h b/tqtinterface/qt4/src/kernel/tqurl.h
new file mode 100644
index 0000000..532633b
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqurl.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Definition of TQUrl class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQURL_H
+#define TQURL_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_URL
+
+class TQUrlPrivate;
+
+class TQ_EXPORT TQUrl
+{
+public:
+ TQUrl();
+ TQUrl( const TQString& url );
+ TQUrl( const TQUrl& url );
+ TQUrl( const TQUrl& url, const TQString& relUrl, bool checkSlash = FALSE );
+ virtual ~TQUrl();
+
+ TQString protocol() const;
+ virtual void setProtocol( const TQString& protocol );
+
+ TQString user() const;
+ virtual void setUser( const TQString& user );
+ bool hasUser() const;
+
+ TQString password() const;
+ virtual void setPassword( const TQString& pass );
+ bool hasPassword() const;
+
+ TQString host() const;
+ virtual void setHost( const TQString& user );
+ bool hasHost() const;
+
+ int port() const;
+ virtual void setPort( int port );
+ bool hasPort() const;
+
+ TQString path( bool correct = TRUE ) const;
+ virtual void setPath( const TQString& path );
+ bool hasPath() const;
+
+ virtual void setEncodedPathAndQuery( const TQString& enc );
+ TQString encodedPathAndQuery();
+
+ virtual void setQuery( const TQString& txt );
+ TQString query() const;
+
+ TQString ref() const;
+ virtual void setRef( const TQString& txt );
+ bool hasRef() const;
+
+ bool isValid() const;
+ bool isLocalFile() const;
+
+ virtual void addPath( const TQString& path );
+ virtual void setFileName( const TQString& txt );
+
+ TQString fileName() const;
+ TQString dirPath() const;
+
+ TQUrl& operator=( const TQUrl& url );
+ TQUrl& operator=( const TQString& url );
+
+ bool operator==( const TQUrl& url ) const;
+ bool operator==( const TQString& url ) const;
+
+ static void decode( TQString& url );
+ static void encode( TQString& url );
+
+ operator TQString() const;
+ virtual TQString toString( bool encodedPath = FALSE, bool forcePrependProtocol = TRUE ) const;
+
+ virtual bool cdUp();
+
+ static bool isRelativeUrl( const TQString &url );
+
+protected:
+ virtual void reset();
+ virtual bool parse( const TQString& url );
+
+private:
+ TQUrlPrivate *d;
+
+};
+
+#endif //TQT_NO_URL
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqurlinfo.cpp b/tqtinterface/qt4/src/kernel/tqurlinfo.cpp
new file mode 100644
index 0000000..60b9f15
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqurlinfo.cpp
@@ -0,0 +1,761 @@
+/****************************************************************************
+**
+** Implementation of TQUrlInfo class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqurlinfo.h"
+
+#ifndef TQT_NO_NETWORKPROTOCOL
+
+#include "tqurloperator.h"
+#include "tqdir.h"
+#include <limits.h>
+
+class TQUrlInfoPrivate
+{
+public:
+ TQUrlInfoPrivate() :
+ permissions(0),
+ size(0),
+ isDir(FALSE),
+ isFile(TRUE),
+ isSymLink(FALSE),
+ isWritable(TRUE),
+ isReadable(TRUE),
+ isExecutable(FALSE)
+ {}
+
+ TQString name;
+ int permissions;
+ TQString owner;
+ TQString group;
+#if defined(TQT_LARGEFILE_SUPPORT)
+ TQIODevice::Offset size;
+#else
+ uint size;
+#endif
+ TQDateTime lastModified;
+ TQDateTime lastRead;
+ bool isDir;
+ bool isFile;
+ bool isSymLink;
+ bool isWritable;
+ bool isReadable;
+ bool isExecutable;
+};
+
+
+/*!
+ \class TQUrlInfo tqurlinfo.h
+ \brief The TQUrlInfo class stores information about URLs.
+
+ \ingroup io
+ \ingroup misc
+
+ This class is just a container for storing information about URLs,
+ which is why all information must be passed in the constructor.
+
+ Unless you're reimplementing a network protocol you're unlikely to
+ create TQUrlInfo objects yourself, but you may receive TQUrlInfo
+ objects from functions, e.g. TQUrlOperator::info().
+
+ The information that can be retrieved includes name(),
+ permissions(), owner(), group(), size(), lastModified(),
+ lastRead(), isDir(), isFile(), isSymLink(), isWritable(),
+ isReadable() and isExecutable().
+*/
+
+/*!
+ \enum TQUrlInfo::PermissionSpec
+
+ This enum is used by the permissions() function to report the
+ permissions of a file.
+
+ \value ReadOwner The file is readable by the owner of the file.
+ \value WriteOwner The file is writable by the owner of the file.
+ \value ExeOwner The file is executable by the owner of the file.
+ \value ReadGroup The file is readable by the group.
+ \value WriteGroup The file is writable by the group.
+ \value ExeGroup The file is executable by the group.
+ \value ReadOther The file is readable by anyone.
+ \value WriteOther The file is writable by anyone.
+ \value ExeOther The file is executable by anyone.
+*/
+
+/*!
+ Constructs an invalid TQUrlInfo object with default values.
+
+ \sa isValid()
+*/
+
+TQUrlInfo::TQUrlInfo()
+{
+ d = 0;
+}
+
+/*!
+ Constructs a TQUrlInfo object with information about the file \a
+ file in the \a path. It tries to tqfind the information about the \a
+ file in the TQUrlOperator \a path.
+
+ If the information is not found, this constructor creates an
+ invalid TQUrlInfo, i.e. isValid() returns FALSE. You should always
+ check if the URL info is valid before relying on the return values
+ of any getter functions.
+
+ If \a file is empty, it defaults to the TQUrlOperator \a path, i.e.
+ to the directory.
+
+ \sa isValid() TQUrlOperator::info()
+*/
+
+TQUrlInfo::TQUrlInfo( const TQUrlOperator &path, const TQString &file )
+{
+ TQString file_ = file;
+ if ( file_.isEmpty() )
+ file_ = ".";
+
+ TQUrlInfo inf = path.info( file_ );
+ if ( inf.d ) {
+ d = new TQUrlInfoPrivate;
+ *d = *inf.d;
+ } else {
+ d = 0;
+ }
+}
+
+/*!
+ Copy constructor, copies \a ui to this URL info object.
+*/
+
+TQUrlInfo::TQUrlInfo( const TQUrlInfo &ui )
+{
+ if ( ui.d ) {
+ d = new TQUrlInfoPrivate;
+ *d = *ui.d;
+ } else {
+ d = 0;
+ }
+}
+
+/*!
+ Constructs a TQUrlInfo object by specifying all the URL's
+ information.
+
+ The information that is passed is the \a name, file \a
+ permissions, \a owner and \a group and the file's \a size. Also
+ passed is the \a lastModified date/time and the \a lastRead
+ date/time. Flags are also passed, specifically, \a isDir, \a
+ isFile, \a isSymLink, \a isWritable, \a isReadable and \a
+ isExecutable.
+*/
+
+#if defined(TQT_ABI_QT4)
+TQUrlInfo::TQUrlInfo( const TQString &name, int permissions, const TQString &owner,
+ const TQString &group, TQIODevice::Offset size, const TQDateTime &lastModified,
+ const TQDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
+ bool isWritable, bool isReadable, bool isExecutable )
+#else
+TQUrlInfo::TQUrlInfo( const TQString &name, int permissions, const TQString &owner,
+ const TQString &group, uint size, const TQDateTime &lastModified,
+ const TQDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
+ bool isWritable, bool isReadable, bool isExecutable )
+#endif
+{
+ d = new TQUrlInfoPrivate;
+ d->name = name;
+ d->permissions = permissions;
+ d->owner = owner;
+ d->group = group;
+ d->size = size;
+ d->lastModified = lastModified;
+ d->lastRead = lastRead;
+ d->isDir = isDir;
+ d->isFile = isFile;
+ d->isSymLink = isSymLink;
+ d->isWritable = isWritable;
+ d->isReadable = isReadable;
+ d->isExecutable = isExecutable;
+}
+
+
+/*!
+ Constructs a TQUrlInfo object by specifying all the URL's
+ information.
+
+ The information that is passed is the \a url, file \a
+ permissions, \a owner and \a group and the file's \a size. Also
+ passed is the \a lastModified date/time and the \a lastRead
+ date/time. Flags are also passed, specifically, \a isDir, \a
+ isFile, \a isSymLink, \a isWritable, \a isReadable and \a
+ isExecutable.
+*/
+
+#if defined(TQT_ABI_QT4)
+TQUrlInfo::TQUrlInfo( const TQUrl &url, int permissions, const TQString &owner,
+ const TQString &group, TQIODevice::Offset size, const TQDateTime &lastModified,
+ const TQDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
+ bool isWritable, bool isReadable, bool isExecutable )
+#else
+TQUrlInfo::TQUrlInfo( const TQUrl &url, int permissions, const TQString &owner,
+ const TQString &group, uint size, const TQDateTime &lastModified,
+ const TQDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
+ bool isWritable, bool isReadable, bool isExecutable )
+#endif
+{
+ d = new TQUrlInfoPrivate;
+ d->name = TQFileInfo( url.path() ).fileName();
+ d->permissions = permissions;
+ d->owner = owner;
+ d->group = group;
+ d->size = size;
+ d->lastModified = lastModified;
+ d->lastRead = lastRead;
+ d->isDir = isDir;
+ d->isFile = isFile;
+ d->isSymLink = isSymLink;
+ d->isWritable = isWritable;
+ d->isReadable = isReadable;
+ d->isExecutable = isExecutable;
+}
+
+
+/*!
+ Sets the name of the URL to \a name. The name is the full text,
+ for example, "http://doc.trolltech.com/tqurlinfo.html".
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+void TQUrlInfo::setName( const TQString &name )
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->name = name;
+}
+
+
+/*!
+ If \a b is TRUE then the URL is set to be a directory; if \b is
+ FALSE then the URL is set not to be a directory (which normally
+ means it is a file). (Note that a URL can refer to both a file and
+ a directory even though most file systems do not support this.)
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+void TQUrlInfo::setDir( bool b )
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->isDir = b;
+}
+
+
+/*!
+ If \a b is TRUE then the URL is set to be a file; if \b is FALSE
+ then the URL is set not to be a file (which normally means it is a
+ directory). (Note that a URL can refer to both a file and a
+ directory even though most file systems do not support this.)
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+void TQUrlInfo::setFile( bool b )
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->isFile = b;
+}
+
+
+/*!
+ Specifies that the URL refers to a symbolic link if \a b is TRUE
+ and that it does not if \a b is FALSE.
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+void TQUrlInfo::setSymLink( bool b )
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->isSymLink = b;
+}
+
+
+/*!
+ Specifies that the URL is writable if \a b is TRUE and not
+ writable if \a b is FALSE.
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+void TQUrlInfo::setWritable( bool b )
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->isWritable = b;
+}
+
+
+/*!
+ Specifies that the URL is readable if \a b is TRUE and not
+ readable if \a b is FALSE.
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+void TQUrlInfo::setReadable( bool b )
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->isReadable = b;
+}
+
+/*!
+ Specifies that the owner of the URL is called \a s.
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+void TQUrlInfo::setOwner( const TQString &s )
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->owner = s;
+}
+
+/*!
+ Specifies that the owning group of the URL is called \a s.
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+void TQUrlInfo::setGroup( const TQString &s )
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->group = s;
+}
+
+/*!
+ Specifies the \a size of the URL.
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+#if defined(TQT_ABI_QT4)
+void TQUrlInfo::setSize( TQIODevice::Offset size )
+#else
+void TQUrlInfo::setSize( uint size )
+#endif
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->size = size;
+}
+
+
+// ### reggie - what's the permission type? As in Unix?
+
+/*!
+ Specifies that the URL has access permisions, \a p.
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+void TQUrlInfo::setPermissions( int p )
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->permissions = p;
+}
+
+/*!
+ Specifies that the object the URL refers to was last modified at
+ \a dt.
+
+ If you call this function for an invalid URL info, this function
+ turns it into a valid one.
+
+ \sa isValid()
+*/
+
+void TQUrlInfo::setLastModified( const TQDateTime &dt )
+{
+ if ( !d )
+ d = new TQUrlInfoPrivate;
+ d->lastModified = dt;
+}
+
+/*!
+ Destroys the URL info object.
+
+ The TQUrlOperator object to which this URL referred (if any) is not
+ affected.
+*/
+
+TQUrlInfo::~TQUrlInfo()
+{
+ delete d;
+}
+
+/*!
+ Assigns the values of \a ui to this TQUrlInfo object.
+*/
+
+TQUrlInfo &TQUrlInfo::operator=( const TQUrlInfo &ui )
+{
+ if ( ui.d ) {
+ if ( !d )
+ d= new TQUrlInfoPrivate;
+ *d = *ui.d;
+ } else {
+ delete d;
+ d = 0;
+ }
+ return *this;
+}
+
+/*!
+ Returns the file name of the URL.
+
+ \sa isValid()
+*/
+
+TQString TQUrlInfo::name() const
+{
+ if ( !d )
+ return TQString::null;
+ return d->name;
+}
+
+/*!
+ Returns the permissions of the URL. You can use the \c PermissionSpec flags
+ to test for certain permissions.
+
+ \sa isValid()
+*/
+
+int TQUrlInfo::permissions() const
+{
+ if ( !d )
+ return 0;
+ return d->permissions;
+}
+
+/*!
+ Returns the owner of the URL.
+
+ \sa isValid()
+*/
+
+TQString TQUrlInfo::owner() const
+{
+ if ( !d )
+ return TQString::null;
+ return d->owner;
+}
+
+/*!
+ Returns the group of the URL.
+
+ \sa isValid()
+*/
+
+TQString TQUrlInfo::group() const
+{
+ if ( !d )
+ return TQString::null;
+ return d->group;
+}
+
+/*!
+ Returns the size of the URL.
+
+ \sa isValid()
+*/
+
+#if defined(TQT_ABI_QT4)
+TQIODevice::Offset TQUrlInfo::size() const
+#else
+uint TQUrlInfo::size() const
+#endif
+{
+ if ( !d )
+ return 0;
+#if defined(TQT_LARGEFILE_SUPPORT) && !defined(TQT_ABI_QT4)
+ return d->size > UINT_MAX ? UINT_MAX : (uint)d->size;
+#else
+ return d->size;
+#endif
+}
+
+/*!
+ Returns the last modification date of the URL.
+
+ \sa isValid()
+*/
+
+TQDateTime TQUrlInfo::lastModified() const
+{
+ if ( !d )
+ return TQDateTime();
+ return d->lastModified;
+}
+
+/*!
+ Returns the date when the URL was last read.
+
+ \sa isValid()
+*/
+
+TQDateTime TQUrlInfo::lastRead() const
+{
+ if ( !d )
+ return TQDateTime();
+ return d->lastRead;
+}
+
+/*!
+ Returns TRUE if the URL is a directory; otherwise returns FALSE.
+
+ \sa isValid()
+*/
+
+bool TQUrlInfo::isDir() const
+{
+ if ( !d )
+ return FALSE;
+ return d->isDir;
+}
+
+/*!
+ Returns TRUE if the URL is a file; otherwise returns FALSE.
+
+ \sa isValid()
+*/
+
+bool TQUrlInfo::isFile() const
+{
+ if ( !d )
+ return FALSE;
+ return d->isFile;
+}
+
+/*!
+ Returns TRUE if the URL is a symbolic link; otherwise returns FALSE.
+
+ \sa isValid()
+*/
+
+bool TQUrlInfo::isSymLink() const
+{
+ if ( !d )
+ return FALSE;
+ return d->isSymLink;
+}
+
+/*!
+ Returns TRUE if the URL is writable; otherwise returns FALSE.
+
+ \sa isValid()
+*/
+
+bool TQUrlInfo::isWritable() const
+{
+ if ( !d )
+ return FALSE;
+ return d->isWritable;
+}
+
+/*!
+ Returns TRUE if the URL is readable; otherwise returns FALSE.
+
+ \sa isValid()
+*/
+
+bool TQUrlInfo::isReadable() const
+{
+ if ( !d )
+ return FALSE;
+ return d->isReadable;
+}
+
+/*!
+ Returns TRUE if the URL is executable; otherwise returns FALSE.
+
+ \sa isValid()
+*/
+
+bool TQUrlInfo::isExecutable() const
+{
+ if ( !d )
+ return FALSE;
+ return d->isExecutable;
+}
+
+/*!
+ Returns TRUE if \a i1 is greater than \a i2; otherwise returns
+ FALSE. The objects are compared by the value, which is specified
+ by \a sortBy. This must be one of TQDir::Name, TQDir::Time or
+ TQDir::Size.
+*/
+
+bool TQUrlInfo::greaterThan( const TQUrlInfo &i1, const TQUrlInfo &i2,
+ int sortBy )
+{
+ switch ( sortBy ) {
+ case TQDir::Name:
+ return i1.name() > i2.name();
+ case TQDir::Time:
+ return i1.lastModified() > i2.lastModified();
+ case TQDir::Size:
+ return i1.size() > i2.size();
+ default:
+ return FALSE;
+ }
+}
+
+/*!
+ Returns TRUE if \a i1 is less than \a i2; otherwise returns FALSE.
+ The objects are compared by the value, which is specified by \a
+ sortBy. This must be one of TQDir::Name, TQDir::Time or TQDir::Size.
+*/
+
+bool TQUrlInfo::lessThan( const TQUrlInfo &i1, const TQUrlInfo &i2,
+ int sortBy )
+{
+ return !greaterThan( i1, i2, sortBy );
+}
+
+/*!
+ Returns TRUE if \a i1 equals to \a i2; otherwise returns FALSE.
+ The objects are compared by the value, which is specified by \a
+ sortBy. This must be one of TQDir::Name, TQDir::Time or TQDir::Size.
+*/
+
+bool TQUrlInfo::equal( const TQUrlInfo &i1, const TQUrlInfo &i2,
+ int sortBy )
+{
+ switch ( sortBy ) {
+ case TQDir::Name:
+ return i1.name() == i2.name();
+ case TQDir::Time:
+ return i1.lastModified() == i2.lastModified();
+ case TQDir::Size:
+ return i1.size() == i2.size();
+ default:
+ return FALSE;
+ }
+}
+
+/*!
+ Compares this TQUrlInfo with \a i and returns TRUE if they are
+ equal; otherwise returns FALSE.
+*/
+
+bool TQUrlInfo::operator==( const TQUrlInfo &i ) const
+{
+ if ( !d )
+ return i.d == 0;
+ if ( !i.d )
+ return FALSE;
+
+ return ( d->name == i.d->name &&
+ d->permissions == i.d->permissions &&
+ d->owner == i.d->owner &&
+ d->group == i.d->group &&
+ d->size == i.d->size &&
+ d->lastModified == i.d->lastModified &&
+ d->lastRead == i.d->lastRead &&
+ d->isDir == i.d->isDir &&
+ d->isFile == i.d->isFile &&
+ d->isSymLink == i.d->isSymLink &&
+ d->isWritable == i.d->isWritable &&
+ d->isReadable == i.d->isReadable &&
+ d->isExecutable == i.d->isExecutable );
+}
+
+/*!
+ Returns TRUE if the URL info is valid; otherwise returns FALSE.
+ Valid means that the TQUrlInfo tqcontains real information. For
+ example, a call to TQUrlOperator::info() might return a an invalid
+ TQUrlInfo, if no information about the requested entry is
+ available.
+
+ You should always check if the URL info is valid before relying on
+ the values.
+*/
+bool TQUrlInfo::isValid() const
+{
+ return d != 0;
+}
+
+#endif // TQT_NO_NETWORKPROTOCOL
diff --git a/tqtinterface/qt4/src/kernel/tqurlinfo.h b/tqtinterface/qt4/src/kernel/tqurlinfo.h
new file mode 100644
index 0000000..1954367
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqurlinfo.h
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** Definition of TQUrlInfo class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQURLINFO_H
+#define TQURLINFO_H
+
+#ifndef TQT_H
+#include "tqdatetime.h"
+#include "tqstring.h"
+#if defined(TQT_ABI_QT4)
+#include "tqiodevice.h"
+#endif
+#endif // TQT_H
+
+class TQUrlOperator;
+class TQUrl;
+class TQUrlInfoPrivate;
+
+class TQ_EXPORT TQUrlInfo
+{
+public:
+ enum PermissionSpec {
+ ReadOwner = 00400, WriteOwner = 00200, ExeOwner = 00100,
+ ReadGroup = 00040, WriteGroup = 00020, ExeGroup = 00010,
+ ReadOther = 00004, WriteOther = 00002, ExeOther = 00001 };
+
+ TQUrlInfo();
+ TQUrlInfo( const TQUrlOperator &path, const TQString &file );
+ TQUrlInfo( const TQUrlInfo &ui );
+#if (TQT_VERSION-0 >= 0x040000)
+#error "TQUrlInfo::TQUrlInfo() should accept TQIODevice::Offset instead of uint"
+#elif defined(TQT_ABI_QT4)
+ TQUrlInfo( const TQString &name, int permissions, const TQString &owner,
+ const TQString &group, TQIODevice::Offset size, const TQDateTime &lastModified,
+ const TQDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
+ bool isWritable, bool isReadable, bool isExecutable );
+ TQUrlInfo( const TQUrl &url, int permissions, const TQString &owner,
+ const TQString &group, TQIODevice::Offset size, const TQDateTime &lastModified,
+ const TQDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
+ bool isWritable, bool isReadable, bool isExecutable );
+#else
+ TQUrlInfo( const TQString &name, int permissions, const TQString &owner,
+ const TQString &group, uint size, const TQDateTime &lastModified,
+ const TQDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
+ bool isWritable, bool isReadable, bool isExecutable );
+ TQUrlInfo( const TQUrl &url, int permissions, const TQString &owner,
+ const TQString &group, uint size, const TQDateTime &lastModified,
+ const TQDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
+ bool isWritable, bool isReadable, bool isExecutable );
+#endif
+ TQUrlInfo &operator=( const TQUrlInfo &ui );
+ virtual ~TQUrlInfo();
+
+ virtual void setName( const TQString &name );
+ virtual void setDir( bool b );
+ virtual void setFile( bool b );
+ virtual void setSymLink( bool b );
+ virtual void setOwner( const TQString &s );
+ virtual void setGroup( const TQString &s );
+#if (TQT_VERSION-0 >= 0x040000)
+#error "TQUrlInfo::setSize() should accept TQIODevice::Offset instead of uint"
+#elif defined(TQT_ABI_QT4)
+ virtual void setSize( TQIODevice::Offset size );
+#else
+ virtual void setSize( uint size );
+#endif
+ virtual void setWritable( bool b );
+ virtual void setReadable( bool b );
+ virtual void setPermissions( int p );
+ virtual void setLastModified( const TQDateTime &dt );
+
+ bool isValid() const;
+
+ TQString name() const;
+ int permissions() const;
+ TQString owner() const;
+ TQString group() const;
+#if (TQT_VERSION-0 >= 0x040000)
+#error "TQUrlInfo::size() should return TQIODevice::Offset instead of uint"
+#elif defined(TQT_ABI_QT4)
+ TQIODevice::Offset size() const;
+#else
+ uint size() const;
+#endif
+ TQDateTime lastModified() const;
+ TQDateTime lastRead() const;
+ bool isDir() const;
+ bool isFile() const;
+ bool isSymLink() const;
+ bool isWritable() const;
+ bool isReadable() const;
+ bool isExecutable() const;
+
+ static bool greaterThan( const TQUrlInfo &i1, const TQUrlInfo &i2,
+ int sortBy );
+ static bool lessThan( const TQUrlInfo &i1, const TQUrlInfo &i2,
+ int sortBy );
+ static bool equal( const TQUrlInfo &i1, const TQUrlInfo &i2,
+ int sortBy );
+
+ bool operator==( const TQUrlInfo &i ) const;
+private:
+ TQUrlInfoPrivate *d;
+
+};
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqurloperator.cpp b/tqtinterface/qt4/src/kernel/tqurloperator.cpp
new file mode 100644
index 0000000..bae40bc
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqurloperator.cpp
@@ -0,0 +1,1226 @@
+/****************************************************************************
+**
+** Implementation of TQUrlOperator class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqurloperator.h"
+
+#ifndef TQT_NO_NETWORKPROTOCOL
+
+#include "tqurlinfo.h"
+#include "tqnetworkprotocol.h"
+#include "tqmap.h"
+#include "tqdir.h"
+#include "tqptrdict.h"
+#include "tqguardedptr.h"
+
+//#define TQURLOPERATOR_DEBUG
+
+class TQUrlOperatorPrivate
+{
+public:
+ TQUrlOperatorPrivate()
+ {
+ oldOps.setAutoDelete( FALSE );
+ networkProtocol = 0;
+ nameFilter = "*";
+ currPut = 0;
+ }
+
+ ~TQUrlOperatorPrivate()
+ {
+ delete networkProtocol;
+ while ( oldOps.first() ) {
+ oldOps.first()->free();
+ oldOps.removeFirst();
+ }
+ }
+
+ TQMap<TQString, TQUrlInfo> entryMap;
+ TQNetworkProtocol *networkProtocol;
+ TQString nameFilter;
+ TQDir dir;
+
+ // maps needed for copy/move operations
+ TQPtrDict<TQNetworkOperation> getOpPutOpMap;
+ TQPtrDict<TQNetworkProtocol> getOpPutProtMap;
+ TQPtrDict<TQNetworkProtocol> getOpGetProtMap;
+ TQPtrDict<TQNetworkOperation> getOpRemoveOpMap;
+ TQGuardedPtr<TQNetworkProtocol> currPut;
+ TQStringList waitingCopies;
+ TQString waitingCopiesDest;
+ bool waitingCopiesMove;
+ TQPtrList< TQNetworkOperation > oldOps;
+};
+
+/*!
+ \class TQUrlOperator tqurloperator.h
+
+ \brief The TQUrlOperator class provides common operations on URLs.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \ingroup misc
+ \mainclass
+
+ \module network
+
+ This class operates on hierarchical structures (such as
+ filesystems) using URLs. Its API facilitates all the common
+ operations:
+ \table
+ \header \i Operation \i Function
+ \row \i List files \i \l listChildren()
+ \row \i Make a directory \i \l mkdir()
+ \row \i Remove a file \i \l remove()
+ \row \i Rename a file \i \l rename()
+ \row \i Get a file \i \l get()
+ \row \i Put a file \i \l put()
+ \row \i Copy a file \i \l copy()
+ \endtable
+
+ You can obtain additional information about the URL with isDir()
+ and info(). If a directory is to be traversed using
+ listChildren(), a name filter can be set with setNameFilter().
+
+ A TQUrlOperator can be used like this, for example to download a
+ file (and assuming that the FTP protocol is \link
+ qInitNetworkProtocols() registered\endlink):
+ \code
+ TQUrlOperator *op = new TQUrlOperator();
+ op->copy( TQString("ftp://ftp.trolltech.com/qt/source/qt-2.1.0.tar.gz"),
+ "file:/tmp" );
+ \endcode
+
+ If you want to be notified about success/failure, progress, etc.,
+ you can connect to TQUrlOperator's Q_SIGNALS, e.g. to start(),
+ newChildren(), createdDirectory(), removed(), data(),
+ dataTransferProgress(), startedNextCopy(),
+ connectionStateChanged(), finished(), etc. A network operation can
+ be stopped with stop().
+
+ The class uses the functionality of registered network protocols
+ to perform these operations. Depending of the protocol of the URL,
+ it uses an appropriate network protocol class for the operations.
+ Each of the operation functions of TQUrlOperator creates a
+ TQNetworkOperation object that describes the operation and puts it
+ into the operation queue for the network protocol used. If no
+ suitable protocol could be found (because no implementation of the
+ necessary network protocol is registered), the URL operator emits
+ errors. Not every protocol supports every operation, but error
+ handling deals with this problem.
+
+ To register the available network protocols, use the
+ qInitNetworkProtocols() function. The protocols currently
+ supported are:
+ \list
+ \i \link TQFtp FTP\endlink,
+ \i \link TQHttp HTTP\endlink,
+ \i \link TQLocalFs local file system\endlink.
+ \endlist
+
+ For more information about the TQt Network Architecture see the
+ \link network.html TQt Network Documentation\endlink.
+
+ \sa TQNetworkProtocol, TQNetworkOperation
+*/
+
+/*!
+ \fn void TQUrlOperator::newChildren( const TQValueList<TQUrlInfo> &i, TQNetworkOperation *op )
+
+ This signal is emitted after listChildren() was called and new
+ tqchildren (i.e. files) have been read from a list of files. \a i
+ holds the information about the new files. \a op is a pointer
+ to the operation object which tqcontains all the information about
+ the operation, including the state.
+
+ \sa TQNetworkOperation, TQNetworkProtocol
+*/
+
+
+/*!
+ \fn void TQUrlOperator::finished( TQNetworkOperation *op )
+
+ This signal is emitted when an operation of some sort finishes,
+ whether with success or failure. \a op is a pointer to the
+ operation object, which tqcontains all the information, including
+ the state, of the operation which has been finished. Check the
+ state and error code of the operation object to see whether or not
+ the operation was successful.
+
+ \sa TQNetworkOperation, TQNetworkProtocol
+*/
+
+/*!
+ \fn void TQUrlOperator::start( TQNetworkOperation *op )
+
+ Some operations (such as listChildren()) emit this signal when
+ they start processing the operation. \a op is a pointer to the
+ operation object which tqcontains all the information about the
+ operation, including the state.
+
+ \sa TQNetworkOperation, TQNetworkProtocol
+*/
+
+/*!
+ \fn void TQUrlOperator::createdDirectory( const TQUrlInfo &i, TQNetworkOperation *op )
+
+ This signal is emitted when mkdir() succeeds and the directory has
+ been created. \a i holds the information about the new directory.
+
+ \a op is a pointer to the operation object, which tqcontains all the
+ information about the operation, including the state.
+ \c op->arg(0) holds the new directory's name.
+
+ \sa TQNetworkOperation, TQNetworkProtocol
+*/
+
+/*!
+ \fn void TQUrlOperator::removed( TQNetworkOperation *op )
+
+ This signal is emitted when remove() has been succesful and the
+ file has been removed.
+
+ \a op is a pointer to the operation object which tqcontains all the
+ information about the operation, including the state.
+ \c op->arg(0) holds the name of the file that was removed.
+
+ \sa TQNetworkOperation, TQNetworkProtocol
+*/
+
+/*!
+ \fn void TQUrlOperator::itemChanged( TQNetworkOperation *op )
+
+ This signal is emitted whenever a file which is a child of the URL
+ has been changed, for example by successfully calling rename().
+ \a op is a pointer to the operation object which tqcontains all the
+ information about the operation, including the state.
+ \c op->arg(0) holds the original file name and \c op->arg(1) holds
+ the new file name (if it was changed).
+
+ \sa TQNetworkOperation, TQNetworkProtocol
+*/
+
+/*!
+ \fn void TQUrlOperator::data( const TQByteArray &data, TQNetworkOperation *op )
+
+ This signal is emitted when new \a data has been received after calling
+ get() or put().
+ \a op is a pointer to the operation object which tqcontains all
+ the information about the operation, including the state.
+ \c op->arg(0) holds the name of the file whose data is retrieved
+ and op->rawArg(1) holds the (raw) data.
+
+ \sa TQNetworkOperation, TQNetworkProtocol
+*/
+
+/*!
+ \fn void TQUrlOperator::dataTransferProgress( int bytesDone, int bytesTotal, TQNetworkOperation *op )
+
+ This signal is emitted during data transfer (using put() or
+ get()). \a bytesDone specifies how many bytes of \a bytesTotal have
+ been transferred. More information about the operation is stored in
+ \a op, a pointer to the network operation that is processed.
+ \a bytesTotal may be -1, which means that the total number of bytes
+ is not known.
+
+ \sa TQNetworkOperation, TQNetworkProtocol
+*/
+
+/*!
+ \fn void TQUrlOperator::startedNextCopy( const TQPtrList<TQNetworkOperation> &lst )
+
+ This signal is emitted if copy() starts a new copy operation. \a
+ lst tqcontains all TQNetworkOperations related to this copy
+ operation.
+
+ \sa copy()
+*/
+
+/*!
+ \fn void TQUrlOperator::connectionStateChanged( int state, const TQString &data )
+
+ This signal is emitted whenever the URL operator's connection
+ state changes. \a state describes the new state, which is a
+ \l{TQNetworkProtocol::ConnectionState} value.
+
+ \a data is a string that describes the change of the connection.
+ This can be used to display a message to the user.
+*/
+
+/*!
+ Constructs a TQUrlOperator with an empty (i.e. invalid) URL.
+*/
+
+TQUrlOperator::TQUrlOperator()
+ : TQUrl()
+{
+#ifdef TQURLOPERATOR_DEBUG
+ qDebug( "TQUrlOperator: cstr 1" );
+#endif
+ d = new TQUrlOperatorPrivate;
+}
+
+/*!
+ Constructs a TQUrlOperator using \a url and parses this string.
+
+ If you pass strings like "/home/qt" the "file" protocol is
+ assumed.
+*/
+
+TQUrlOperator::TQUrlOperator( const TQString &url )
+ : TQUrl( url )
+{
+#ifdef TQURLOPERATOR_DEBUG
+ qDebug( "TQUrlOperator: cstr 2" );
+#endif
+ d = new TQUrlOperatorPrivate;
+ getNetworkProtocol();
+}
+
+/*!
+ Constructs a copy of \a url.
+*/
+
+TQUrlOperator::TQUrlOperator( const TQUrlOperator& url )
+ : TQObject(), TQUrl( url )
+{
+#ifdef TQURLOPERATOR_DEBUG
+ qDebug( "TQUrlOperator: cstr 3" );
+#endif
+ d = new TQUrlOperatorPrivate;
+ *d = *url.d;
+
+ d->networkProtocol = 0;
+ getNetworkProtocol();
+ d->nameFilter = "*";
+ d->currPut = 0;
+}
+
+/*!
+ Constructs a TQUrlOperator. The URL on which this TQUrlOperator
+ operates is constructed out of the arguments \a url, \a relUrl and
+ \a checkSlash: see the corresponding TQUrl constructor for an
+ explanation of these arguments.
+*/
+
+TQUrlOperator::TQUrlOperator( const TQUrlOperator& url, const TQString& relUrl, bool checkSlash )
+ : TQUrl( url, relUrl, checkSlash )
+{
+#ifdef TQURLOPERATOR_DEBUG
+ qDebug( "TQUrlOperator: cstr 4" );
+#endif
+ d = new TQUrlOperatorPrivate;
+ if ( relUrl == "." )
+ *d = *url.d;
+
+ d->networkProtocol = 0;
+ getNetworkProtocol();
+ d->currPut = 0;
+}
+
+/*!
+ Destructor.
+*/
+
+TQUrlOperator::~TQUrlOperator()
+{
+#ifdef TQURLOPERATOR_DEBUG
+ qDebug( "TQUrlOperator: dstr" );
+#endif
+ delete d;
+}
+
+/*!
+ This private function is used by the simple operation functions,
+ i.e. listChildren(), mkdir(), remove(), rename(), get() and put(),
+ to really start the operation. \a op is a pointer to the network
+ operation that should be started. Returns \a op on success;
+ otherwise returns 0.
+*/
+const TQNetworkOperation *TQUrlOperator::startOperation( TQNetworkOperation *op )
+{
+ if ( !d->networkProtocol )
+ getNetworkProtocol();
+
+ if ( d->networkProtocol && (d->networkProtocol->supportedOperations()&op->operation()) ) {
+ d->networkProtocol->addOperation( op );
+ if ( op->operation() == TQNetworkProtocol::OpListChildren )
+ clearEntries();
+ return op;
+ }
+
+ // error
+ TQString msg;
+ if ( !d->networkProtocol ) {
+ msg = tr( "The protocol `%1' is not supported" ).arg( protocol() );
+ } else {
+ switch ( op->operation() ) {
+ case TQNetworkProtocol::OpListChildren:
+ msg = tr( "The protocol `%1' does not support listing directories" ).arg( protocol() );
+ break;
+ case TQNetworkProtocol::OpMkDir:
+ msg = tr( "The protocol `%1' does not support creating new directories" ).arg( protocol() );
+ break;
+ case TQNetworkProtocol::OpRemove:
+ msg = tr( "The protocol `%1' does not support removing files or directories" ).arg( protocol() );
+ break;
+ case TQNetworkProtocol::OpRename:
+ msg = tr( "The protocol `%1' does not support renaming files or directories" ).arg( protocol() );
+ break;
+ case TQNetworkProtocol::OpGet:
+ msg = tr( "The protocol `%1' does not support getting files" ).arg( protocol() );
+ break;
+ case TQNetworkProtocol::OpPut:
+ msg = tr( "The protocol `%1' does not support putting files" ).arg( protocol() );
+ break;
+ default:
+ // this should never happen
+ break;
+ }
+ }
+ op->setState( TQNetworkProtocol::StFailed );
+ op->setProtocolDetail( msg );
+ op->setErrorCode( (int)TQNetworkProtocol::ErrUnsupported );
+ emit finished( op );
+ deleteOperation( op );
+ return 0;
+}
+
+/*!
+ Starts listing the tqchildren of this URL (e.g. the files in the
+ directory). The start() signal is emitted before the first entry
+ is listed and finished() is emitted after the last one. The
+ newChildren() signal is emitted for each list of new entries. If
+ an error occurs, the signal finished() is emitted, so be sure to
+ check the state of the network operation pointer.
+
+ Because the operation may not be executed immediately, a pointer
+ to the TQNetworkOperation object created by this function is
+ returned. This object tqcontains all the data about the operation
+ and is used to refer to this operation later (e.g. in the Q_SIGNALS
+ that are emitted by the TQUrlOperator). The return value can also
+ be 0 if the operation object couldn't be created.
+
+ The path of this TQUrlOperator must to point to a directory
+ (because the tqchildren of this directory will be listed), not to a
+ file.
+*/
+
+const TQNetworkOperation *TQUrlOperator::listChildren()
+{
+ if ( !checkValid() )
+ return 0;
+
+ TQNetworkOperation *res = new TQNetworkOperation( TQNetworkProtocol::OpListChildren, TQString::null, TQString::null, TQString::null );
+ return startOperation( res );
+}
+
+/*!
+ Tries to create a directory (child) with the name \a dirname. If
+ it is successful, a newChildren() signal with the new child is
+ emitted, and the createdDirectory() signal with the information
+ about the new child is also emitted. The finished() signal (with
+ success or failure) is emitted after the operation has been
+ processed, so check the state of the network operation object to
+ see whether or not the operation was successful.
+
+ Because the operation will not be executed immediately, a pointer
+ to the TQNetworkOperation object created by this function is
+ returned. This object tqcontains all the data about the operation
+ and is used to refer to this operation later (e.g. in the Q_SIGNALS
+ that are emitted by the TQUrlOperator). The return value can also
+ be 0 if the operation object couldn't be created.
+
+ The path of this TQUrlOperator must to point to a directory (not a
+ file) because the new directory will be created in this path.
+*/
+
+const TQNetworkOperation *TQUrlOperator::mkdir( const TQString &dirname )
+{
+ if ( !checkValid() )
+ return 0;
+
+ TQNetworkOperation *res = new TQNetworkOperation( TQNetworkProtocol::OpMkDir, dirname, TQString::null, TQString::null );
+ return startOperation( res );
+}
+
+/*!
+ Tries to remove the file (child) \a filename. If it succeeds the
+ removed() signal is emitted. finished() (with success or failure)
+ is also emitted after the operation has been processed, so check
+ the state of the network operation object to see whether or not
+ the operation was successful.
+
+ Because the operation will not be executed immediately, a pointer
+ to the TQNetworkOperation object created by this function is
+ returned. This object tqcontains all the data about the operation
+ and is used to refer to this operation later (e.g. in the Q_SIGNALS
+ that are emitted by the TQUrlOperator). The return value can also
+ be 0 if the operation object couldn't be created.
+
+ The path of this TQUrlOperator must point to a directory; because
+ if \a filename is relative, it will try to remove it in this
+ directory.
+*/
+
+const TQNetworkOperation *TQUrlOperator::remove( const TQString &filename )
+{
+ if ( !checkValid() )
+ return 0;
+
+ TQNetworkOperation *res = new TQNetworkOperation( TQNetworkProtocol::OpRemove, filename, TQString::null, TQString::null );
+ return startOperation( res );
+}
+
+/*!
+ Tries to rename the file (child) called \a oldname to \a newname.
+ If it succeeds, the itemChanged() signal is emitted. finished()
+ (with success or failure) is also emitted after the operation has
+ been processed, so check the state of the network operation object
+ to see whether or not the operation was successful.
+
+ Because the operation may not be executed immediately, a pointer
+ to the TQNetworkOperation object created by this function is
+ returned. This object tqcontains all the data about the operation
+ and is used to refer to this operation later (e.g. in the Q_SIGNALS
+ that are emitted by the TQUrlOperator). The return value can also
+ be 0 if the operation object couldn't be created.
+
+ This path of this TQUrlOperator must to point to a directory
+ because \a oldname and \a newname are handled relative to this
+ directory.
+*/
+
+const TQNetworkOperation *TQUrlOperator::rename( const TQString &oldname, const TQString &newname )
+{
+ if ( !checkValid() )
+ return 0;
+
+ TQNetworkOperation *res = new TQNetworkOperation( TQNetworkProtocol::OpRename, oldname, newname, TQString::null );
+ return startOperation( res );
+}
+
+/*!
+ Copies the file \a from to \a to. If \a move is TRUE, the file is
+ moved (copied and removed). \a from must point to a file and \a to
+ must point to a directory (into which \a from is copied) unless \a
+ toPath is set to FALSE. If \a toPath is set to FALSE then the \a
+ to variable is assumed to be the absolute file path (destination
+ file path + file name). The copying is done using the get() and
+ put() operations. If you want to be notified about the progress of
+ the operation, connect to the dataTransferProgress() signal. Bear
+ in mind that the get() and put() operations emit this signal
+ through the TQUrlOperator. The number of transferred bytes and the
+ total bytes that you receive as arguments in this signal do not
+ relate to the the whole copy operation; they relate first to the
+ get() and then to the put() operation. Always check what type of
+ operation the signal comes from; this is given in the signal's
+ last argument.
+
+ At the end, finished() (with success or failure) is emitted, so
+ check the state of the network operation object to see whether or
+ not the operation was successful.
+
+ Because a move or copy operation consists of multiple operations
+ (get(), put() and maybe remove()), this function doesn't return a
+ single TQNetworkOperation, but rather a list of them. They are in
+ the order: get(), put() and (if applicable) remove().
+
+ \sa get(), put()
+*/
+
+TQPtrList<TQNetworkOperation> TQUrlOperator::copy( const TQString &from, const TQString &to, bool move, bool toPath )
+{
+#ifdef TQURLOPERATOR_DEBUG
+ qDebug( "TQUrlOperator: copy %s %s %d", from.latin1(), to.latin1(), move );
+#endif
+
+ TQPtrList<TQNetworkOperation> ops;
+ ops.setAutoDelete( FALSE );
+
+ TQUrlOperator *uFrom = new TQUrlOperator( *this, from );
+ TQUrlOperator *uTo = new TQUrlOperator( to );
+
+ // prepare some string for later usage
+ TQString frm = *uFrom;
+ TQString file = uFrom->fileName();
+
+ if (frm == to + file)
+ return ops;
+
+ file.prepend( "/" );
+
+ // uFrom and uTo are deleted when the TQNetworkProtocol deletes itself via
+ // autodelete
+ uFrom->getNetworkProtocol();
+ uTo->getNetworkProtocol();
+ TQNetworkProtocol *gProt = uFrom->d->networkProtocol;
+ TQNetworkProtocol *pProt = uTo->d->networkProtocol;
+
+ uFrom->setPath( uFrom->dirPath() );
+
+ if ( gProt && (gProt->supportedOperations()&TQNetworkProtocol::OpGet) &&
+ pProt && (pProt->supportedOperations()&TQNetworkProtocol::OpPut) ) {
+
+ connect( gProt, TQT_SIGNAL( data(const TQByteArray&,TQNetworkOperation*) ),
+ this, TQT_SLOT( copyGotData(const TQByteArray&,TQNetworkOperation*) ) );
+ connect( gProt, TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ),
+ this, TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ) );
+ connect( gProt, TQT_SIGNAL( finished(TQNetworkOperation*) ),
+ this, TQT_SLOT( continueCopy(TQNetworkOperation*) ) );
+ connect( gProt, TQT_SIGNAL( finished(TQNetworkOperation*) ),
+ this, TQT_SIGNAL( finished(TQNetworkOperation*) ) );
+ connect( gProt, TQT_SIGNAL( connectionStateChanged(int,const TQString&) ),
+ this, TQT_SIGNAL( connectionStateChanged(int,const TQString&) ) );
+
+ connect( pProt, TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ),
+ this, TQT_SIGNAL( dataTransferProgress(int,int,TQNetworkOperation*) ) );
+ connect( pProt, TQT_SIGNAL( finished(TQNetworkOperation*) ),
+ this, TQT_SIGNAL( finished(TQNetworkOperation*) ) );
+ connect( pProt, TQT_SIGNAL( finished(TQNetworkOperation*) ),
+ this, TQT_SLOT( finishedCopy() ) );
+
+ TQNetworkOperation *opGet = new TQNetworkOperation( TQNetworkProtocol::OpGet, frm, TQString::null, TQString::null );
+ ops.append( opGet );
+ gProt->addOperation( opGet );
+
+
+ TQString toFile = to + file;
+ if (!toPath)
+ toFile = to;
+
+ TQNetworkOperation *opPut = new TQNetworkOperation( TQNetworkProtocol::OpPut, toFile, TQString::null, TQString::null );
+ ops.append( opPut );
+
+ d->getOpPutProtMap.insert( (void*)opGet, pProt );
+ d->getOpGetProtMap.insert( (void*)opGet, gProt );
+ d->getOpPutOpMap.insert( (void*)opGet, opPut );
+
+ if ( move && (gProt->supportedOperations()&TQNetworkProtocol::OpRemove) ) {
+ gProt->setAutoDelete( FALSE );
+
+ TQNetworkOperation *opRm = new TQNetworkOperation( TQNetworkProtocol::OpRemove, frm, TQString::null, TQString::null );
+ ops.append( opRm );
+ d->getOpRemoveOpMap.insert( (void*)opGet, opRm );
+ } else {
+ gProt->setAutoDelete( TRUE );
+ }
+#ifdef TQURLOPERATOR_DEBUG
+ qDebug( "TQUrlOperator: copy operation should start now..." );
+#endif
+ return ops;
+ } else {
+ TQString msg;
+ if ( !gProt ) {
+ msg = tr( "The protocol `%1' is not supported" ).arg( uFrom->protocol() );
+ } else if ( gProt->supportedOperations() & TQNetworkProtocol::OpGet ) {
+ msg = tr( "The protocol `%1' does not support copying or moving files or directories" ).arg( uFrom->protocol() );
+ } else if ( !pProt ) {
+ msg = tr( "The protocol `%1' is not supported" ).arg( uTo->protocol() );
+ } else {
+ msg = tr( "The protocol `%1' does not support copying or moving files or directories" ).arg( uTo->protocol() );
+ }
+ delete uFrom;
+ delete uTo;
+ TQNetworkOperation *res = new TQNetworkOperation( TQNetworkProtocol::OpGet, frm, to, TQString::null );
+ res->setState( TQNetworkProtocol::StFailed );
+ res->setProtocolDetail( msg );
+ res->setErrorCode( (int)TQNetworkProtocol::ErrUnsupported );
+ emit finished( res );
+ deleteOperation( res );
+ }
+
+ return ops;
+}
+
+/*!
+ \overload
+
+ Copies the \a files to the directory \a dest. If \a move is TRUE
+ the files are moved, not copied. \a dest must point to a
+ directory.
+
+ This function calls copy() for each entry in \a files in turn. You
+ don't get a result from this function; each time a new copy
+ begins, startedNextCopy() is emitted, with a list of
+ TQNetworkOperations that describe the new copy operation.
+*/
+
+void TQUrlOperator::copy( const TQStringList &files, const TQString &dest,
+ bool move )
+{
+ d->waitingCopies = files;
+ d->waitingCopiesDest = dest;
+ d->waitingCopiesMove = move;
+
+ finishedCopy();
+}
+
+/*!
+ Returns TRUE if the URL is a directory; otherwise returns FALSE.
+ This may not always work correctly, if the protocol of the URL is
+ something other than file (local filesystem). If you pass a bool
+ pointer as the \a ok argument, \a *ok is set to TRUE if the result
+ of this function is known to be correct, and to FALSE otherwise.
+*/
+
+bool TQUrlOperator::isDir( bool *ok )
+{
+ if ( ok )
+ *ok = TRUE;
+ if ( isLocalFile() ) {
+ if ( TQFileInfo( path() ).isDir() )
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ if ( d->entryMap.tqcontains( "." ) ) {
+ return d->entryMap[ "." ].isDir();
+ }
+ // #### can assume that we are a directory?
+ if ( ok )
+ *ok = FALSE;
+ return TRUE;
+}
+
+/*!
+ Tells the network protocol to get data from \a location or, if
+ this is TQString::null, to get data from the location to which this
+ URL points (see TQUrl::fileName() and TQUrl::encodedPathAndQuery()).
+ What happens then depends on the network protocol. The data()
+ signal is emitted when data comes in. Because it's unlikely that
+ all data will come in at once, it is common for multiple data()
+ Q_SIGNALS to be emitted. The dataTransferProgress() signal is
+ emitted while processing the operation. At the end, finished()
+ (with success or failure) is emitted, so check the state of the
+ network operation object to see whether or not the operation was
+ successful.
+
+ If \a location is TQString::null, the path of this TQUrlOperator
+ should point to a file when you use this operation. If \a location
+ is not empty, it can be a relative URL (a child of the path to
+ which the TQUrlOperator points) or an absolute URL.
+
+ For example, to get a web page you might do something like this:
+
+ \code
+ TQUrlOperator op( "http://www.whatever.org/cgi-bin/search.pl?cmd=Hello" );
+ op.get();
+ \endcode
+
+ For most other operations, the path of the TQUrlOperator must point
+ to a directory. If you want to download a file you could do the
+ following:
+
+ \code
+ TQUrlOperator op( "ftp://ftp.whatever.org/pub" );
+ // do some other stuff like op.listChildren() or op.mkdir( "new_dir" )
+ op.get( "a_file.txt" );
+ \endcode
+
+ This will get the data of ftp://ftp.whatever.org/pub/a_file.txt.
+
+ \e Never do anything like this:
+ \code
+ TQUrlOperator op( "http://www.whatever.org/cgi-bin" );
+ op.get( "search.pl?cmd=Hello" ); // WRONG!
+ \endcode
+
+ If \a location is not empty and relative it must not contain any
+ queries or references, just the name of a child. So if you need to
+ specify a query or reference, do it as shown in the first example
+ or specify the full URL (such as
+ http://www.whatever.org/cgi-bin/search.pl?cmd=Hello) as \a location.
+
+ \sa copy()
+*/
+
+const TQNetworkOperation *TQUrlOperator::get( const TQString &location )
+{
+ TQUrl u( *this );
+ if ( !location.isEmpty() )
+ u = TQUrl( *this, location );
+
+ if ( !u.isValid() )
+ return 0;
+
+ if ( !d->networkProtocol ) {
+ setProtocol( u.protocol() );
+ getNetworkProtocol();
+ }
+
+ TQNetworkOperation *res = new TQNetworkOperation( TQNetworkProtocol::OpGet, u, TQString::null, TQString::null );
+ return startOperation( res );
+}
+
+/*!
+ This function tells the network protocol to put \a data in \a
+ location. If \a location is empty (TQString::null), it puts the \a
+ data in the location to which the URL points. What happens depends
+ on the network protocol. Depending on the network protocol, some
+ data might come back after putting data, in which case the data()
+ signal is emitted. The dataTransferProgress() signal is emitted
+ during processing of the operation. At the end, finished() (with
+ success or failure) is emitted, so check the state of the network
+ operation object to see whether or not the operation was
+ successful.
+
+ If \a location is TQString::null, the path of this TQUrlOperator
+ should point to a file when you use this operation. If \a location
+ is not empty, it can be a relative (a child of the path to which
+ the TQUrlOperator points) or an absolute URL.
+
+ For putting some data to a file you can do the following:
+
+ \code
+ TQUrlOperator op( "ftp://ftp.whatever.com/home/me/filename.dat" );
+ op.put( data );
+ \endcode
+
+ For most other operations, the path of the TQUrlOperator must point
+ to a directory. If you want to upload data to a file you could do
+ the following:
+
+ \code
+ TQUrlOperator op( "ftp://ftp.whatever.com/home/me" );
+ // do some other stuff like op.listChildren() or op.mkdir( "new_dir" )
+ op.put( data, "filename.dat" );
+ \endcode
+
+ This will upload the data to ftp://ftp.whatever.com/home/me/filename.dat.
+
+ \sa copy()
+*/
+
+const TQNetworkOperation *TQUrlOperator::put( const TQByteArray &data, const TQString &location )
+{
+ TQUrl u( *this );
+ if ( !location.isEmpty() )
+ u = TQUrl( *this, location );
+
+ if ( !u.isValid() )
+ return 0;
+
+ if ( !d->networkProtocol ) {
+ setProtocol( u.protocol() );
+ getNetworkProtocol();
+ }
+
+ TQNetworkOperation *res = new TQNetworkOperation( TQNetworkProtocol::OpPut, u, TQString::null, TQString::null );
+ res->setRawArg( 1, data );
+ return startOperation( res );
+}
+
+/*!
+ Sets the name filter of the URL to \a nameFilter.
+
+ \sa TQDir::setNameFilter()
+*/
+
+void TQUrlOperator::setNameFilter( const TQString &nameFilter )
+{
+ d->nameFilter = nameFilter;
+}
+
+/*!
+ Returns the name filter of the URL.
+
+ \sa TQUrlOperator::setNameFilter() TQDir::nameFilter()
+*/
+
+TQString TQUrlOperator::nameFilter() const
+{
+ return d->nameFilter;
+}
+
+/*!
+ Clears the cache of tqchildren.
+*/
+
+void TQUrlOperator::clearEntries()
+{
+ d->entryMap.clear();
+}
+
+/*!
+ Adds an entry to the cache of tqchildren.
+*/
+
+void TQUrlOperator::addEntry( const TQValueList<TQUrlInfo> &i )
+{
+ TQValueList<TQUrlInfo>::ConstIterator it = i.begin();
+ for ( ; it != i.end(); ++it )
+ d->entryMap[ ( *it ).name().stripWhiteSpace() ] = *it;
+}
+
+/*!
+ Returns the URL information for the child \a entry, or returns an
+ empty TQUrlInfo object if there is no information available about
+ \a entry. Information about \a entry is only available after a successfully
+ finished listChildren() operation.
+*/
+
+TQUrlInfo TQUrlOperator::info( const TQString &entry ) const
+{
+ if ( d->entryMap.tqcontains( entry.stripWhiteSpace() ) ) {
+ return d->entryMap[ entry.stripWhiteSpace() ];
+ } else if ( entry == "." || entry == ".." ) {
+ // return a faked TQUrlInfo
+ TQUrlInfo inf;
+ inf.setName( entry );
+ inf.setDir( TRUE );
+ inf.setFile( FALSE );
+ inf.setSymLink( FALSE );
+ inf.setOwner( tr( "(unknown)" ) );
+ inf.setGroup( tr( "(unknown)" ) );
+ inf.setSize( 0 );
+ inf.setWritable( FALSE );
+ inf.setReadable( TRUE );
+ return inf;
+ }
+ return TQUrlInfo();
+}
+
+/*!
+ Finds a network protocol for the URL and deletes the old network protocol.
+*/
+
+void TQUrlOperator::getNetworkProtocol()
+{
+ delete d->networkProtocol;
+ TQNetworkProtocol *p = TQNetworkProtocol::getNetworkProtocol( protocol() );
+ if ( !p ) {
+ d->networkProtocol = 0;
+ return;
+ }
+
+ d->networkProtocol = (TQNetworkProtocol *)p;
+ d->networkProtocol->setUrl( this );
+ connect( d->networkProtocol, TQT_SIGNAL( itemChanged(TQNetworkOperation*) ),
+ this, TQT_SLOT( slotItemChanged(TQNetworkOperation*) ) );
+}
+
+/*!
+ Deletes the currently used network protocol.
+*/
+
+void TQUrlOperator::deleteNetworkProtocol()
+{
+ if (d->networkProtocol) {
+ d->networkProtocol->deleteLater();
+ d->networkProtocol = 0;
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQUrlOperator::setPath( const TQString& path )
+{
+ TQUrl::setPath( path );
+ if ( d->networkProtocol )
+ d->networkProtocol->setUrl( this );
+}
+
+/*!
+ \reimp
+*/
+
+void TQUrlOperator::reset()
+{
+ TQUrl::reset();
+ deleteNetworkProtocol();
+ d->nameFilter = "*";
+}
+
+/*!
+ \reimp
+*/
+
+bool TQUrlOperator::parse( const TQString &url )
+{
+ bool b = TQUrl::parse( url );
+ if ( !b ) {
+ return b;
+ }
+
+ getNetworkProtocol();
+
+ return b;
+}
+
+/*!
+ \reimp
+*/
+
+TQUrlOperator& TQUrlOperator::operator=( const TQUrlOperator &url )
+{
+ deleteNetworkProtocol();
+ TQUrl::operator=( url );
+
+ TQPtrDict<TQNetworkOperation> getOpPutOpMap = d->getOpPutOpMap;
+ TQPtrDict<TQNetworkProtocol> getOpPutProtMap = d->getOpPutProtMap;
+ TQPtrDict<TQNetworkProtocol> getOpGetProtMap = d->getOpGetProtMap;
+ TQPtrDict<TQNetworkOperation> getOpRemoveOpMap = d->getOpRemoveOpMap;
+
+ *d = *url.d;
+
+ d->oldOps.setAutoDelete( FALSE );
+ d->getOpPutOpMap = getOpPutOpMap;
+ d->getOpPutProtMap = getOpPutProtMap;
+ d->getOpGetProtMap = getOpGetProtMap;
+ d->getOpRemoveOpMap = getOpRemoveOpMap;
+
+ d->networkProtocol = 0;
+ getNetworkProtocol();
+ return *this;
+}
+
+/*!
+ \reimp
+*/
+
+TQUrlOperator& TQUrlOperator::operator=( const TQString &url )
+{
+ deleteNetworkProtocol();
+ TQUrl::operator=( url );
+ d->oldOps.setAutoDelete( FALSE );
+ getNetworkProtocol();
+ return *this;
+}
+
+/*!
+ \reimp
+*/
+
+bool TQUrlOperator::cdUp()
+{
+ bool b = TQUrl::cdUp();
+ if ( d->networkProtocol )
+ d->networkProtocol->setUrl( this );
+ return b;
+}
+
+/*!
+ \reimp
+*/
+
+bool TQUrlOperator::checkValid()
+{
+ // ######
+ if ( !isValid() ) {
+ //emit error( ErrValid, tr( "The entered URL is not valid!" ) );
+ return FALSE;
+ } else
+ return TRUE;
+}
+
+
+/*!
+ \internal
+*/
+
+void TQUrlOperator::copyGotData( const TQByteArray &data_, TQNetworkOperation *op )
+{
+#ifdef TQURLOPERATOR_DEBUG
+ qDebug( "TQUrlOperator: copyGotData: %d new bytes", data_.size() );
+#endif
+ TQNetworkOperation *put = d->getOpPutOpMap[ (void*)op ];
+ if ( put ) {
+ TQByteArray &s = put->raw( 1 );
+ int size = s.size();
+ s.resize( size + data_.size() );
+ memcpy( s.data() + size, data_.data(), data_.size() );
+ }
+ emit data( data_, op );
+}
+
+/*!
+ \internal
+*/
+
+void TQUrlOperator::continueCopy( TQNetworkOperation *op )
+{
+ if ( op->operation() != TQNetworkProtocol::OpGet )
+ return;
+ if ( op->state()!=TQNetworkProtocol::StDone && op->state()!=TQNetworkProtocol::StFailed ) {
+ return;
+ }
+
+#ifdef TQURLOPERATOR_DEBUG
+ if ( op->state() != TQNetworkProtocol::StFailed ) {
+ qDebug( "TQUrlOperator: continue copy (get finished, put will start)" );
+ }
+#endif
+
+ TQNetworkOperation *put = d->getOpPutOpMap[ (void*)op ];
+ TQNetworkProtocol *gProt = d->getOpGetProtMap[ (void*)op ];
+ TQNetworkProtocol *pProt = d->getOpPutProtMap[ (void*)op ];
+ TQNetworkOperation *rm = d->getOpRemoveOpMap[ (void*)op ];
+ d->getOpPutOpMap.take( op );
+ d->getOpGetProtMap.take( op );
+ d->getOpPutProtMap.take( op );
+ d->getOpRemoveOpMap.take( op );
+ if ( pProt )
+ pProt->setAutoDelete( TRUE );
+ if ( put && pProt ) {
+ if ( op->state() != TQNetworkProtocol::StFailed ) {
+ pProt->addOperation( put );
+ d->currPut = pProt;
+ } else {
+ deleteOperation( put );
+ }
+ }
+ if ( gProt ) {
+ gProt->setAutoDelete( TRUE );
+ }
+ if ( rm && gProt ) {
+ if ( op->state() != TQNetworkProtocol::StFailed ) {
+ gProt->addOperation( rm );
+ } else {
+ deleteOperation( rm );
+ }
+ }
+ disconnect( gProt, TQT_SIGNAL( data(const TQByteArray&,TQNetworkOperation*) ),
+ this, TQT_SLOT( copyGotData(const TQByteArray&,TQNetworkOperation*) ) );
+ disconnect( gProt, TQT_SIGNAL( finished(TQNetworkOperation*) ),
+ this, TQT_SLOT( continueCopy(TQNetworkOperation*) ) );
+}
+
+/*!
+ \internal
+*/
+
+void TQUrlOperator::finishedCopy()
+{
+#ifdef TQURLOPERATOR_DEBUG
+ qDebug( "TQUrlOperator: finished copy (finished putting)" );
+#endif
+
+ if ( d->waitingCopies.isEmpty() )
+ return;
+
+ TQString cp = d->waitingCopies.first();
+ d->waitingCopies.remove( cp );
+ TQPtrList<TQNetworkOperation> lst = copy( cp, d->waitingCopiesDest, d->waitingCopiesMove );
+ emit startedNextCopy( lst );
+}
+
+/*!
+ Stops the current network operation and removes all this
+ TQUrlOperator's waiting network operations.
+*/
+
+void TQUrlOperator::stop()
+{
+ d->getOpPutOpMap.clear();
+ d->getOpRemoveOpMap.clear();
+ d->getOpGetProtMap.setAutoDelete( TRUE );
+ d->getOpPutProtMap.setAutoDelete( TRUE );
+ TQPtrDictIterator<TQNetworkProtocol> it( d->getOpPutProtMap );
+ for ( ; it.current(); ++it )
+ it.current()->stop();
+ d->getOpPutProtMap.clear();
+ it = TQPtrDictIterator<TQNetworkProtocol>( d->getOpGetProtMap );
+ for ( ; it.current(); ++it )
+ it.current()->stop();
+ d->getOpGetProtMap.clear();
+ if ( d->currPut ) {
+ d->currPut->stop();
+ delete (TQNetworkProtocol *) d->currPut;
+ d->currPut = 0;
+ }
+ d->waitingCopies.clear();
+ if ( d->networkProtocol )
+ d->networkProtocol->stop();
+ getNetworkProtocol();
+}
+
+/*!
+ \internal
+*/
+
+void TQUrlOperator::deleteOperation( TQNetworkOperation *op )
+{
+ if ( op )
+ d->oldOps.append( op );
+}
+
+/*!
+ \internal
+ updates the entryMap after a network operation finished
+*/
+
+void TQUrlOperator::slotItemChanged( TQNetworkOperation *op )
+{
+ if ( !op )
+ return;
+
+ switch ( op->operation() ) {
+ case TQNetworkProtocol::OpRename :
+ {
+ if ( op->arg( 0 ) == op->arg( 1 ) )
+ return;
+
+ TQMap<TQString, TQUrlInfo>::iterator mi = d->entryMap.tqfind( op->arg( 0 ) );
+ if ( mi != d->entryMap.end() ) {
+ mi.data().setName( op->arg( 1 ) );
+ d->entryMap[ op->arg( 1 ) ] = mi.data();
+ d->entryMap.erase( mi );
+ }
+ break;
+ }
+ case TQNetworkProtocol::OpRemove :
+ {
+ TQMap<TQString, TQUrlInfo>::iterator mi = d->entryMap.tqfind( op->arg( 0 ) );
+ if ( mi != d->entryMap.end() )
+ d->entryMap.erase( mi );
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+
+#endif // TQT_NO_NETWORKPROTOCOL
diff --git a/tqtinterface/qt4/src/kernel/tqurloperator.h b/tqtinterface/qt4/src/kernel/tqurloperator.h
new file mode 100644
index 0000000..822c769
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqurloperator.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Definition of TQUrlOperator class
+**
+** Created : 950429
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQURLOPERATOR_H
+#define TQURLOPERATOR_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqurl.h"
+#include "tqptrlist.h"
+#include "tqnetworkprotocol.h"
+#include "tqstringlist.h" // TQString->TQStringList conversion
+#endif // TQT_H
+
+#ifndef TQT_NO_NETWORKPROTOCOL
+
+class TQUrlInfo;
+class TQUrlOperatorPrivate;
+
+class TQ_EXPORT TQUrlOperator : public TQObject, public TQUrl
+{
+ friend class TQNetworkProtocol;
+
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQUrlOperator();
+ TQUrlOperator( const TQString &urL );
+ TQUrlOperator( const TQUrlOperator& url );
+ TQUrlOperator( const TQUrlOperator& url, const TQString& relUrl, bool checkSlash = FALSE );
+ virtual ~TQUrlOperator();
+
+ virtual void setPath( const TQString& path );
+ virtual bool cdUp();
+
+ virtual const TQNetworkOperation *listChildren();
+ virtual const TQNetworkOperation *mkdir( const TQString &dirname );
+ virtual const TQNetworkOperation *remove( const TQString &filename );
+ virtual const TQNetworkOperation *rename( const TQString &oldname, const TQString &newname );
+ virtual const TQNetworkOperation *get( const TQString &location = TQString::null );
+ virtual const TQNetworkOperation *put( const TQByteArray &data, const TQString &location = TQString::null );
+ virtual TQPtrList<TQNetworkOperation> copy( const TQString &from, const TQString &to, bool move = FALSE, bool toPath = TRUE );
+ virtual void copy( const TQStringList &files, const TQString &dest, bool move = FALSE );
+ virtual bool isDir( bool *ok = 0 );
+
+ virtual void setNameFilter( const TQString &nameFilter );
+ TQString nameFilter() const;
+
+ virtual TQUrlInfo info( const TQString &entry ) const;
+
+ TQUrlOperator& operator=( const TQUrlOperator &url );
+ TQUrlOperator& operator=( const TQString &url );
+
+ virtual void stop();
+
+Q_SIGNALS:
+ void newChildren( const TQValueList<TQUrlInfo> &, TQNetworkOperation *res );
+ void finished( TQNetworkOperation *res );
+ void start( TQNetworkOperation *res );
+ void createdDirectory( const TQUrlInfo &, TQNetworkOperation *res );
+ void removed( TQNetworkOperation *res );
+ void itemChanged( TQNetworkOperation *res );
+ void data( const TQByteArray &, TQNetworkOperation *res );
+ void dataTransferProgress( int bytesDone, int bytesTotal, TQNetworkOperation *res );
+ void startedNextCopy( const TQPtrList<TQNetworkOperation> &lst );
+ void connectionStateChanged( int state, const TQString &data );
+
+protected:
+ void reset();
+ bool parse( const TQString& url );
+ virtual bool checkValid();
+ virtual void clearEntries();
+ void getNetworkProtocol();
+ void deleteNetworkProtocol();
+
+private Q_SLOTS:
+ const TQNetworkOperation *startOperation( TQNetworkOperation *op );
+ void copyGotData( const TQByteArray &data, TQNetworkOperation *op );
+ void continueCopy( TQNetworkOperation *op );
+ void finishedCopy();
+ void addEntry( const TQValueList<TQUrlInfo> &i );
+ void slotItemChanged( TQNetworkOperation *op );
+
+private:
+ void deleteOperation( TQNetworkOperation *op );
+
+ TQUrlOperatorPrivate *d;
+};
+
+#endif // TQT_NO_NETWORKPROTOCOL
+
+#endif // TQURLOPERATOR_H
diff --git a/tqtinterface/qt4/src/kernel/tqvariant.cpp b/tqtinterface/qt4/src/kernel/tqvariant.cpp
new file mode 100644
index 0000000..bd022e1
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqvariant.cpp
@@ -0,0 +1,4972 @@
+/****************************************************************************
+**
+** Implementation of TQVariant class
+**
+** Created : 990414
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <float.h>
+
+#include "tqvariant.h"
+#ifndef TQT_NO_VARIANT
+#include "tqstring.h"
+#include "tqcstring.h"
+#include "tqfont.h"
+#include "tqpixmap.h"
+#include "tqimage.h"
+#include "tqbrush.h"
+#include "tqpoint.h"
+#include "tqrect.h"
+#include "tqsize.h"
+#include "tqcolor.h"
+#include "tqpalette.h"
+#include "tqiconset.h"
+#include "tqdatastream.h"
+#include "tqregion.h"
+#include "tqpointarray.h"
+#include "tqbitmap.h"
+#include "tqcursor.h"
+#include "tqdatetime.h"
+#include "tqsizepolicy.h"
+#include "tqshared.h"
+#include "tqbitarray.h"
+#include "tqkeysequence.h"
+#include "tqpen.h"
+
+#ifdef USE_QT4
+
+#define IconSet Icon
+#define CString ByteArray
+#define PointArray Polygon
+#define ColorGroup 63
+
+/*!
+ Constructs a copy of the variant, \a p, passed as the argument to
+ this constructor. Usually this is a deep copy, but a shallow copy
+ is made if the stored data type is explicitly shared, as e.g.
+ TQImage is.
+*/
+TQVariant::TQVariant( const QVariant& p )
+ : QVariant(p)
+{
+// p.d.ref();
+// d = p.d;
+}
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ Reads the variant from the data stream, \a s.
+*/
+TQVariant::TQVariant( TQDataStream& s )
+{
+ s >> *this;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*!
+ Constructs a new variant with a string value, \a val.
+*/
+TQVariant::TQVariant( const TQString& val )
+ : QVariant(val)
+{
+// d.type = String;
+// d.data.ptr = new TQString( val );
+}
+
+/*!
+ Constructs a new variant with a C-string value, \a val.
+
+ If you want to modify the TQCString after you've passed it to this
+ constructor, we recommend passing a deep copy (see
+ TQCString::copy()).
+*/
+TQVariant::TQVariant( const TQCString& val )
+{
+ d.type = CString;
+ d.data.ptr = new TQCString( val );
+}
+
+/*!
+ Constructs a new variant with a C-string value of \a val if \a val
+ is non-null. The variant creates a deep copy of \a val.
+
+ If \a val is null, the resulting variant has type Invalid.
+*/
+TQVariant::TQVariant( const char* val )
+{
+ if ( val == 0 )
+ return;
+ d.type = CString;
+ d.data.ptr = new TQCString( val );
+}
+
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Constructs a new variant with a string list value, \a val.
+*/
+TQVariant::TQVariant( const TQStringList& val )
+{
+ d.type = StringList;
+ d.data.ptr = new TQStringList( val );
+ d.is_null = FALSE;
+}
+#endif // TQT_NO_STRINGLIST
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Constructs a new variant with a map of TQVariants, \a val.
+*/
+TQVariant::TQVariant( const TQMap<TQString,TQVariant>& val )
+{
+ d.type = Map;
+ d.data.ptr = new TQMap<TQString,TQVariant>( val );
+ d.is_null = FALSE;
+}
+#endif
+/*!
+ Constructs a new variant with a font value, \a val.
+*/
+TQVariant::TQVariant( const TQFont& val )
+{
+ d.type = Font;
+ d.data.ptr = new TQFont( val );
+ d.is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a pixmap value, \a val.
+*/
+TQVariant::TQVariant( const TQPixmap& val )
+{
+ d.type = Pixmap;
+ d.data.ptr = new TQPixmap( val );
+}
+
+
+/*!
+ Constructs a new variant with an image value, \a val.
+
+ Because TQImage is explicitly shared, you may need to pass a deep
+ copy to the variant using TQImage::copy(), e.g. if you intend
+ changing the image you've passed later on.
+*/
+TQVariant::TQVariant( const TQImage& val )
+{
+ d.type = Image;
+ d.data.ptr = new TQImage( val );
+}
+
+/*!
+ Constructs a new variant with a brush value, \a val.
+*/
+TQVariant::TQVariant( const TQBrush& val )
+{
+ d.type = Brush;
+ d.data.ptr = new TQBrush( val );
+ d.is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a point value, \a val.
+*/
+TQVariant::TQVariant( const TQPoint& val )
+{
+ d.type = Point;
+ d.data.ptr = new TQPoint( val );
+}
+
+/*!
+ Constructs a new variant with a rect value, \a val.
+*/
+TQVariant::TQVariant( const TQRect& val )
+{
+ d.type = Rect;
+ d.data.ptr = new TQRect( val );
+}
+
+/*!
+ Constructs a new variant with a size value, \a val.
+*/
+TQVariant::TQVariant( const TQSize& val )
+{
+ d.type = Size;
+ d.data.ptr = new TQSize( val );
+}
+
+/*!
+ Constructs a new variant with a color value, \a val.
+*/
+TQVariant::TQVariant( const TQColor& val )
+{
+ d.type = Color;
+ d.data.ptr = new TQColor( val );
+ d.is_null = FALSE;
+}
+
+#ifndef TQT_NO_PALETTE
+/*!
+ Constructs a new variant with a color palette value, \a val.
+*/
+TQVariant::TQVariant( const TQPalette& val )
+{
+ d.type = Palette;
+ d.data.ptr = new TQPalette( val );
+ d.is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a color group value, \a val.
+*/
+TQVariant::TQVariant( const TQColorGroup& val )
+{
+ d.type = ColorGroup;
+ d.data.ptr = new TQColorGroup( val );
+ d.is_null = FALSE;
+}
+#endif //TQT_NO_PALETTE
+#ifndef TQT_NO_ICONSET
+/*!
+ Constructs a new variant with an icon set value, \a val.
+*/
+TQVariant::TQVariant( const TQIconSet& val )
+{
+ d.type = IconSet;
+ d.data.ptr = new TQIconSet( val );
+}
+#endif //TQT_NO_ICONSET
+/*!
+ Constructs a new variant with a region value, \a val.
+*/
+TQVariant::TQVariant( const TQRegion& val )
+{
+ d.type = Region;
+ // ## Force a detach
+ d.data.ptr = new TQRegion( val );
+ ((TQRegion*)d.data.ptr)->translate( 0, 0 );
+}
+
+/*!
+ Constructs a new variant with a bitmap value, \a val.
+*/
+TQVariant::TQVariant( const TQBitmap& val )
+{
+ d.type = Bitmap;
+ d.data.ptr = new TQBitmap( val );
+}
+
+/*!
+ Constructs a new variant with a cursor value, \a val.
+*/
+TQVariant::TQVariant( const TQCursor& val )
+{
+ d.type = Cursor;
+ d.data.ptr = new TQCursor( val );
+ d.is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a point array value, \a val.
+
+ Because TQPointArray is explicitly shared, you may need to pass a
+ deep copy to the variant using TQPointArray::copy(), e.g. if you
+ intend changing the point array you've passed later on.
+*/
+TQVariant::TQVariant( const TQPointArray& val )
+{
+ d.type = PointArray;
+ d.data.ptr = new TQPointArray( val );
+}
+
+/*!
+ Constructs a new variant with a date value, \a val.
+*/
+TQVariant::TQVariant( const TQDate& val )
+{
+ d.type = Date;
+ d.data.ptr = new TQDate( val );
+}
+
+/*!
+ Constructs a new variant with a time value, \a val.
+*/
+TQVariant::TQVariant( const TQTime& val )
+{
+ d.type = Time;
+ d.data.ptr = new TQTime( val );
+}
+
+/*!
+ Constructs a new variant with a date/time value, \a val.
+*/
+TQVariant::TQVariant( const TQDateTime& val )
+{
+ d.type = DateTime;
+ d.data.ptr = new TQDateTime( val );
+}
+
+/*!
+ Constructs a new variant with a bytearray value, \a val.
+*/
+TQVariant::TQVariant( const TQByteArray& val )
+{
+ d.type = ByteArray;
+ d.data.ptr = new TQByteArray( val );
+}
+
+/*!
+ Constructs a new variant with a bitarray value, \a val.
+*/
+TQVariant::TQVariant( const TQBitArray& val )
+{
+ d.type = BitArray;
+ d.data.ptr = new TQBitArray( val );
+}
+
+#ifndef TQT_NO_ACCEL
+
+/*!
+ Constructs a new variant with a key sequence value, \a val.
+*/
+TQVariant::TQVariant( const TQKeySequence& val )
+{
+ d.type = KeySequence;
+ d.data.ptr = new TQKeySequence( val );
+ d.is_null = FALSE;
+}
+
+#endif
+
+/*!
+ Constructs a new variant with a pen value, \a val.
+*/
+TQVariant::TQVariant( const TQPen& val )
+{
+ d.type = Pen;
+ d.data.ptr = new TQPen( val );
+}
+
+#if 0
+
+/*!
+ Constructs a new variant with an integer value, \a val.
+*/
+TQVariant::TQVariant( int val )
+{
+ d = new Private;
+ d->typ = Int;
+ d->value.i = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with an unsigned integer value, \a val.
+*/
+TQVariant::TQVariant( uint val )
+{
+ d = new Private;
+ d->typ = UInt;
+ d->value.u = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a long long integer value, \a val.
+*/
+TQVariant::TQVariant( TQ_LLONG val )
+{
+ d = new Private;
+ d->typ = LongLong;
+ d->value.ll = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with an unsigned long long integer value, \a val.
+*/
+
+TQVariant::TQVariant( TQ_ULLONG val )
+{
+ d = new Private;
+ d->typ = ULongLong;
+ d->value.ull = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a boolean value, \a val. The integer
+ argument is a dummy, necessary for compatibility with some
+ compilers.
+*/
+TQVariant::TQVariant( bool val, int )
+{ // this is the comment that does NOT name said compiler.
+ d = new Private;
+ d->typ = Bool;
+ d->value.b = val;
+ d->is_null = FALSE;
+}
+
+
+/*!
+ Constructs a new variant with a floating point value, \a val.
+*/
+TQVariant::TQVariant( double val )
+{
+ d = new Private;
+ d->typ = Double;
+ d->value.d = val;
+ d->is_null = FALSE;
+}
+
+#endif
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Constructs a new variant with a list value, \a val.
+*/
+TQVariant::TQVariant( const TQValueList<TQVariant>& val )
+{
+ d.type = List;
+ d.data.ptr = new TQValueList<TQVariant>( val );
+ d.is_null = FALSE;
+}
+#endif
+
+/*!
+ Constructs a new variant with a size policy value, \a val.
+*/
+TQVariant::TQVariant( TQSizePolicy val )
+{
+// d = new Private;
+ d.type = SizePolicy;
+// d.value.ptr = new TQSizePolicy( val );
+ d.data.ptr = new TQSizePolicy( val );
+ d.is_null = FALSE;
+}
+
+/*!
+ Assigns the value of the variant \a variant to this variant.
+
+ This is a deep copy of the variant, but note that if the variant
+ holds an explicitly shared type such as TQImage, a shallow copy is
+ performed.
+
+ Directly taken from Qt4 qvariant.cpp
+*/
+// TQVariant& TQVariant::operator= ( const QVariant& variant )
+// {
+// // if (this == &variant)
+// // return *this;
+// //
+// // clear();
+// // if (variant.d.is_shared) {
+// // variant.d.data.shared->ref.ref();
+// // d = variant.d;
+// // } else if (variant.d.type > Char && variant.d.type < UserType) {
+// // d.type = variant.d.type;
+// // handler->construct(&d, variant.constData());
+// // d.is_null = variant.d.is_null;
+// // } else {
+// // d = variant.d;
+// // }
+// //
+// // return *this;
+//
+// return QVariant::operator=(variant);
+// }
+
+/*!
+ Returns the variant as a TQFont if the variant can be cast to Font;
+ otherwise returns the application's default font.
+
+ \sa asFont(), canCast()
+*/
+const TQFont TQVariant::toFont() const
+{
+ switch ( type() ) {
+// case CString:
+ case ByteArray:
+ case String:
+ {
+ TQFont fnt;
+ fnt.fromString( toString() );
+ return fnt;
+ }
+ case Font:
+ return *((TQFont*)d.data.ptr);
+ default:
+ return TQFont();
+ }
+}
+
+#define TQ_VARIANT_AS( f ) TQ##f& TQVariant::as##f() \
+{ \
+ bool b = isNull(); \
+ if ( d.type != f ) \
+ *this = TQVariant( to##f() ); \
+ else \
+ detach(); \
+ d.is_null = b; \
+ return *((TQ##f*)d.data.ptr); \
+}
+
+TQ_VARIANT_AS(String)
+TQ_VARIANT_AS(CString)
+#ifndef TQT_NO_STRINGLIST
+TQ_VARIANT_AS(StringList)
+#endif
+TQ_VARIANT_AS(Font)
+TQ_VARIANT_AS(Pixmap)
+TQ_VARIANT_AS(Image)
+TQ_VARIANT_AS(Brush)
+TQ_VARIANT_AS(Point)
+TQ_VARIANT_AS(Rect)
+TQ_VARIANT_AS(Size)
+TQ_VARIANT_AS(Color)
+#ifndef TQT_NO_PALETTE
+TQ_VARIANT_AS(Palette)
+TQ_VARIANT_AS(ColorGroup)
+#endif
+#ifndef TQT_NO_ICONSET
+TQ_VARIANT_AS(IconSet)
+#endif
+TQ_VARIANT_AS(PointArray)
+TQ_VARIANT_AS(Bitmap)
+TQ_VARIANT_AS(Region)
+TQ_VARIANT_AS(Cursor)
+TQ_VARIANT_AS(SizePolicy)
+TQ_VARIANT_AS(Date)
+TQ_VARIANT_AS(Time)
+TQ_VARIANT_AS(DateTime)
+TQ_VARIANT_AS(ByteArray)
+TQ_VARIANT_AS(BitArray)
+#ifndef TQT_NO_ACCEL
+TQ_VARIANT_AS(KeySequence)
+#endif
+TQ_VARIANT_AS(Pen)
+
+// #if 0
+
+/*!
+ Returns the variant's value as int reference.
+*/
+int& TQVariant::asInt()
+{
+ detach();
+ if ( d.type != Int ) {
+ int i = toInt();
+ bool b = isNull();
+// d.clear();
+ d.data.i = i;
+ d.type = Int;
+ d.is_null = b;
+ }
+ return d.data.i;
+}
+
+/*!
+ Returns the variant's value as unsigned int reference.
+*/
+uint& TQVariant::asUInt()
+{
+ detach();
+ if ( d.type != UInt ) {
+ uint u = toUInt();
+ bool b = isNull();
+// d.clear();
+ d.data.u = u;
+ d.type = UInt;
+ d.is_null = b;
+ }
+ return d.data.u;
+}
+
+/*!
+ Returns the variant's value as long long reference.
+*/
+TQ_LLONG& TQVariant::asLongLong()
+{
+ detach();
+ if ( d.type != LongLong ) {
+ TQ_LLONG ll = toLongLong();
+ bool b = isNull();
+// d.clear();
+ d.data.ll = ll;
+ d.type = LongLong;
+ d.is_null = b;
+ }
+ return d.data.ll;
+}
+
+/*!
+ Returns the variant's value as unsigned long long reference.
+*/
+TQ_ULLONG& TQVariant::asULongLong()
+{
+ detach();
+ if ( d.type != ULongLong ) {
+ TQ_ULLONG ull = toULongLong();
+ bool b = isNull();
+// d.clear();
+ d.data.ull = ull;
+ d.type = ULongLong;
+ d.is_null = b;
+ }
+ return d.data.ull;
+}
+
+/*!
+ Returns the variant's value as bool reference.
+*/
+bool& TQVariant::asBool()
+{
+ detach();
+ if ( d.type != Bool ) {
+ bool b = toBool();
+ bool nb = isNull();
+// d.clear();
+ d.data.b = b;
+ d.type = Bool;
+ d.is_null = nb;
+ }
+ return d.data.b;
+}
+
+/*!
+ Returns the variant's value as double reference.
+*/
+double& TQVariant::asDouble()
+{
+ detach();
+ if ( d.type != Double ) {
+ double dbl = toDouble();
+ bool b = isNull();
+// d.clear();
+ d.data.d = dbl;
+ d.type = Double;
+ d.is_null = b;
+ }
+ return d.data.d;
+}
+
+// #endif
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant's value as variant list reference.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQVariant> list = myVariant.asList();
+ TQValueList<TQVariant>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQValueList<TQVariant>& TQVariant::asList()
+{
+ bool b = isNull();
+ if ( d.type != List )
+ *this = TQVariant( toList() );
+ else
+ detach();
+ d.is_null = b;
+ return *((TQValueList<TQVariant>*)d.data.ptr);
+}
+
+/*!
+ Returns the variant's value as variant map reference.
+
+ Note that if you want to iterate over the map, you should iterate
+ over a copy, e.g.
+ \code
+ TQMap<TQString, TQVariant> map = myVariant.asMap();
+ TQMap<TQString, TQVariant>::Iterator it = map.begin();
+ while( it != map.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQMap<TQString, TQVariant>& TQVariant::asMap()
+{
+ bool b = isNull();
+ if ( d.type != Map )
+ *this = TQVariant( toMap() );
+ else
+ detach();
+ d.is_null = b;
+ return *((TQMap<TQString,TQVariant>*)d.data.ptr);
+}
+#endif
+
+/*!
+ Returns the variant as a TQString if the variant can be cast to
+ String, otherwise returns TQString::null.
+
+ \sa asString(), canCast()
+*/
+const TQString TQVariant::toString() const
+{
+// switch( d.type ) {
+// // case CString:
+// // return TQString::tqfromLatin1( toCString() );
+// case Int:
+// return TQString::number( toInt() );
+// case UInt:
+// return TQString::number( toUInt() );
+// case LongLong:
+// return TQString::number( toLongLong() );
+// case ULongLong:
+// return TQString::number( toULongLong() );
+// case Double:
+// return TQString::number( toDouble(), 'g', DBL_DIG );
+// #if !defined(TQT_NO_SPRINTF) && !defined(TQT_NO_DATESTRING)
+// case Date:
+// return toDate().toString( Qt::ISODate );
+// case Time:
+// return toTime().toString( Qt::ISODate );
+// case DateTime:
+// return toDateTime().toString( Qt::ISODate );
+// #endif
+// case Bool:
+// return toInt() ? "true" : "false";
+// #ifndef TQT_NO_ACCEL
+// case KeySequence:
+// return (TQString) *( (TQKeySequence*)d.data.ptr );
+// #endif
+// case ByteArray:
+// return TQString( *((TQByteArray*)d.data.ptr) );
+// case Font:
+// return toFont().toString();
+// case Color:
+// return toColor().name();
+// case String:
+// return *(static_cast<TQString*>(d.data.ptr));
+// default:
+// return TQString();
+// }
+
+// const QString& ref = QVariant::toString();
+// return *(static_cast<const TQString*>(&ref));
+ return TQString(QVariant::toString());
+}
+/*!
+ Returns the variant as a TQCString if the variant can be cast to a
+ CString; otherwise returns 0.
+
+ \sa asCString(), canCast()
+*/
+const TQCString TQVariant::toCString() const
+{
+ switch( d.type ) {
+ case CString: return *((TQCString*)d.data.ptr);
+ case String: return ((TQString*)d.data.ptr)->latin1();
+ default: {
+ if (!canCast(String))
+ return 0;
+ TQString c = toString();
+ return TQCString(c.latin1());
+ }
+ }
+}
+
+
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Returns the variant as a TQStringList if the variant has type()
+ StringList or List of a type that can be converted to TQString;
+ otherwise returns an empty list.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myVariant.toStringList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asStringList()
+*/
+const TQStringList TQVariant::toStringList() const
+{
+ switch ( d.type ) {
+ case StringList:
+ return *((TQStringList*)d.data.ptr);
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case List:
+ {
+ TQStringList lst;
+ TQValueList<TQVariant>::ConstIterator it = listBegin();
+ TQValueList<TQVariant>::ConstIterator end = listEnd();
+ while( it != end ) {
+ TQString tmp = (*it).toString();
+ ++it;
+ lst.append( tmp );
+ }
+ return lst;
+ }
+#endif
+ default:
+ return TQStringList();
+ }
+}
+#endif //TQT_NO_STRINGLIST
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant as a TQMap<TQString,TQVariant> if the variant has
+ type() Map; otherwise returns an empty map.
+
+ Note that if you want to iterate over the map, you should iterate
+ over a copy, e.g.
+ \code
+ TQMap<TQString, TQVariant> map = myVariant.toMap();
+ TQMap<TQString, TQVariant>::Iterator it = map.begin();
+ while( it != map.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asMap()
+*/
+const TQMap<TQString, TQVariant> TQVariant::toMap() const
+{
+ if ( d.type != Map )
+ return TQMap<TQString,TQVariant>();
+
+ return *((TQMap<TQString,TQVariant>*)d.data.ptr);
+}
+#endif
+
+/*!
+ Returns the variant as a TQPixmap if the variant has type() Pixmap;
+ otherwise returns a null pixmap.
+
+ \sa asPixmap()
+*/
+const TQPixmap TQVariant::toPixmap() const
+{
+ if ( d.type != Pixmap )
+ return TQPixmap();
+
+ return *((TQPixmap*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQImage if the variant has type() Image;
+ otherwise returns a null image.
+
+ \sa asImage()
+*/
+const TQImage TQVariant::toImage() const
+{
+ if ( d.type != Image )
+ return TQImage();
+
+ return *((TQImage*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQBrush if the variant has type() Brush;
+ otherwise returns a default brush (with all black colors).
+
+ \sa asBrush()
+*/
+const TQBrush TQVariant::toBrush() const
+{
+ if( d.type != Brush )
+ return TQBrush();
+
+ return *((TQBrush*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQPoint if the variant has type() Point;
+ otherwise returns a point (0, 0).
+
+ \sa asPoint()
+*/
+const TQPoint TQVariant::toPoint() const
+{
+ if ( d.type != Point )
+ return TQPoint();
+
+ return *((TQPoint*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQRect if the variant has type() Rect;
+ otherwise returns an empty rectangle.
+
+ \sa asRect()
+*/
+const TQRect TQVariant::toRect() const
+{
+ if ( d.type != Rect )
+ return TQRect();
+
+ return *((TQRect*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQSize if the variant has type() Size;
+ otherwise returns an invalid size.
+
+ \sa asSize()
+*/
+const TQSize TQVariant::toSize() const
+{
+ if ( d.type != Size )
+ return TQSize();
+
+ return *((TQSize*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQColor if the variant can be cast to Color;
+ otherwise returns an invalid color.
+
+ \sa asColor(), canCast()
+*/
+const TQColor TQVariant::toColor() const
+{
+ switch ( d.type ) {
+ case ByteArray:
+// case CString:
+ case String:
+ {
+ TQColor col;
+ col.setNamedColor( toString() );
+ return col;
+ }
+ case Color:
+ return *((TQColor*)d.data.ptr);
+ default:
+ return TQColor();
+ }
+}
+#ifndef TQT_NO_PALETTE
+/*!
+ Returns the variant as a TQPalette if the variant has type()
+ Palette; otherwise returns a completely black palette.
+
+ \sa asPalette()
+*/
+const TQPalette TQVariant::toPalette() const
+{
+ if ( d.type != Palette )
+ return TQPalette();
+
+ return *((TQPalette*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQColorGroup if the variant has type()
+ ColorGroup; otherwise returns a completely black color group.
+
+ \sa asColorGroup()
+*/
+const TQColorGroup TQVariant::toColorGroup() const
+{
+ if ( d.type != ColorGroup )
+ return TQColorGroup();
+
+ return *((TQColorGroup*)d.data.ptr);
+}
+#endif //TQT_NO_PALETTE
+#ifndef TQT_NO_ICONSET
+/*!
+ Returns the variant as a TQIconSet if the variant has type()
+ IconSet; otherwise returns an icon set of null pixmaps.
+
+ \sa asIconSet()
+*/
+const TQIconSet TQVariant::toIconSet() const
+{
+ if ( d.type != IconSet )
+ return TQIconSet();
+
+ return *((TQIconSet*)d.data.ptr);
+}
+#endif //TQT_NO_ICONSET
+/*!
+ Returns the variant as a TQPointArray if the variant has type()
+ PointArray; otherwise returns an empty TQPointArray.
+
+ \sa asPointArray()
+*/
+const TQPointArray TQVariant::toPointArray() const
+{
+ if ( d.type != PointArray )
+ return TQPointArray();
+
+ return *((TQPointArray*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQBitmap if the variant has type() Bitmap;
+ otherwise returns a null TQBitmap.
+
+ \sa asBitmap()
+*/
+const TQBitmap TQVariant::toBitmap() const
+{
+ if ( d.type != Bitmap )
+ return TQBitmap();
+
+ return *((TQBitmap*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQRegion if the variant has type() Region;
+ otherwise returns an empty TQRegion.
+
+ \sa asRegion()
+*/
+const TQRegion TQVariant::toRegion() const
+{
+ if ( d.type != Region )
+ return TQRegion();
+
+ return *((TQRegion*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQCursor if the variant has type() Cursor;
+ otherwise returns the default arrow cursor.
+
+ \sa asCursor()
+*/
+const TQCursor TQVariant::toCursor() const
+{
+#ifndef TQT_NO_CURSOR
+ if ( d.type != Cursor )
+ return TQCursor();
+#endif
+
+ return *((TQCursor*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQDate if the variant can be cast to Date;
+ otherwise returns an invalid date.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ date will be returned if the string cannot be parsed as a
+ Qt::ISODate format date.
+
+ \sa asDate(), canCast()
+*/
+const TQDate TQVariant::toDate() const
+{
+ switch ( d.type ) {
+ case Date:
+ return *((TQDate*)d.data.ptr);
+ case DateTime:
+ return TQT_TQDATE_OBJECT(((TQDateTime*)d.data.ptr)->date());
+#ifndef TQT_NO_DATESTRING
+ case String:
+ return TQT_TQDATE_OBJECT(TQDate::fromString( *((TQString*)d.data.ptr), Qt::ISODate ));
+// case CString:
+ case ByteArray:
+ return TQT_TQDATE_OBJECT(TQDate::fromString(toString(), Qt::ISODate));
+#endif
+ default:
+ return TQDate();
+ }
+}
+
+/*!
+ Returns the variant as a TQTime if the variant can be cast to Time;
+ otherwise returns an invalid date.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ time will be returned if the string cannot be parsed as a
+ Qt::ISODate format time.
+
+ \sa asTime()
+*/
+const TQTime TQVariant::toTime() const
+{
+ switch ( d.type ) {
+ case Time:
+ return *((TQTime*)d.data.ptr);
+ case DateTime:
+ return TQT_TQTIME_OBJECT(((TQDateTime*)d.data.ptr)->time());
+#ifndef TQT_NO_DATESTRING
+ case String:
+ return TQT_TQTIME_OBJECT(TQTime::fromString( *((TQString*)d.data.ptr), Qt::ISODate ));
+// case CString:
+ case ByteArray:
+ return TQT_TQTIME_OBJECT(TQTime::fromString(toString(), Qt::ISODate));
+#endif
+ default:
+ return TQTime();
+ }
+}
+
+/*!
+ Returns the variant as a TQDateTime if the variant can be cast to
+ DateTime; otherwise returns an invalid TQDateTime.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ TQDateTime will be returned if the string cannot be parsed as a
+ Qt::ISODate format date/time.
+
+ \sa asDateTime()
+*/
+const TQDateTime TQVariant::toDateTime() const
+{
+ switch ( d.type ) {
+ case DateTime:
+ return *((TQDateTime*)d.data.ptr);
+#ifndef TQT_NO_DATESTRING
+ case String:
+ return TQT_TQDATETIME_OBJECT(TQDateTime::fromString( *((TQString*)d.data.ptr), Qt::ISODate ));
+// case CString:
+ case ByteArray:
+ return TQT_TQDATETIME_OBJECT(TQDateTime::fromString(toString(), Qt::ISODate));
+#endif
+ case Date:
+ return TQDateTime( *((TQDate*)d.data.ptr) );
+ default:
+ return TQDateTime();
+ }
+}
+
+/*!
+ Returns the variant as a TQByteArray if the variant can be cast to
+ a ByteArray; otherwise returns an empty bytearray.
+
+ \sa asByteArray(), canCast()
+*/
+const TQByteArray TQVariant::toByteArray() const
+{
+ switch(d.type) {
+ case ByteArray: return *((TQByteArray*)d.data.ptr);
+// case CString: return *((TQByteArray*)d.data.ptr);
+ default: {
+ TQByteArray ret;
+ if (canCast(String)) {
+ TQString c = toString();
+ ret.duplicate(c.latin1(), c.length());
+ }
+ return ret;
+ }
+ }
+}
+
+/*!
+ Returns the variant as a TQBitArray if the variant has type()
+ BitArray; otherwise returns an empty bitarray.
+
+ \sa asBitArray()
+*/
+const TQBitArray TQVariant::toBitArray() const
+{
+ if ( d.type == BitArray )
+ return *((TQBitArray*)d.data.ptr);
+ return TQBitArray();
+}
+
+#ifndef TQT_NO_ACCEL
+
+/*!
+ Returns the variant as a TQKeySequence if the variant can be cast
+ to a KeySequence; otherwise returns an empty key sequence.
+
+ \sa asKeySequence(), canCast()
+*/
+const TQKeySequence TQVariant::toKeySequence() const
+{
+ switch ( d.type ) {
+ case KeySequence:
+ return *((TQKeySequence*)d.data.ptr);
+ case String:
+ case ByteArray:
+// case CString:
+ return TQKeySequence( toString() );
+ case Int:
+ case UInt:
+ case Double:
+ case ULongLong:
+ case LongLong:
+ return TQKeySequence( toInt() );
+ default:
+ return TQKeySequence();
+ }
+}
+
+#endif // TQT_NO_ACCEL
+
+/*!
+ Returns the variant as a TQPen if the variant has type()
+ Pen; otherwise returns an empty TQPen.
+
+ \sa asPen()
+*/
+const TQPen TQVariant::toPen() const
+{
+ if ( d.type != Pen )
+ return TQPen();
+
+ return *((TQPen*)d.data.ptr);
+}
+
+#if 0
+
+/*!
+ Returns the variant as an int if the variant can be cast to Int;
+ otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asInt(), canCast()
+*/
+int TQVariant::toInt( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( Int );
+
+ switch ( d.type ) {
+ case String:
+ return ((TQString*)d.data.ptr)->toInt( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d.data.ptr)->toInt( ok );
+ case Int:
+ return d.data.i;
+ case UInt:
+ return (int)d.data.u;
+ case LongLong:
+ return (int)d.data.ll;
+ case ULongLong:
+ return (int)d.data.ull;
+ case Double:
+ return (int)d.data.d;
+ case Bool:
+ return (int)d.data.b;
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ return (int) *( (TQKeySequence*)d.data.ptr );
+#endif
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as an unsigned int if the variant can be cast
+ to UInt; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an unsigned int; otherwise \a *ok is set to FALSE.
+
+ \sa asUInt(), canCast()
+*/
+uint TQVariant::toUInt( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( UInt );
+
+ switch( d.type ) {
+ case String:
+ return ((TQString*)d.data.ptr)->toUInt( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d.data.ptr)->toUInt( ok );
+ case Int:
+ return (uint)d.data.i;
+ case UInt:
+ return d.data.u;
+ case LongLong:
+ return (uint)d.data.ll;
+ case ULongLong:
+ return (uint)d.data.ull;
+ case Double:
+ return (uint)d.data.d;
+ case Bool:
+ return (uint)d.data.b;
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as a long long int if the variant can be cast
+ to LongLong; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asLongLong(), canCast()
+*/
+TQ_LLONG TQVariant::toLongLong( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( LongLong );
+
+ switch ( d.type ) {
+ case String:
+ return ((TQString*)d.data.ptr)->toLongLong( ok );
+ case CString:
+ case ByteArray:
+ return TQString(*(TQCString*)d.data.ptr).toLongLong(ok);
+ case Int:
+ return (TQ_LLONG)d.data.i;
+ case UInt:
+ return (TQ_LLONG)d.data.u;
+ case LongLong:
+ return d.data.ll;
+ case ULongLong:
+ return (TQ_LLONG)d.data.ull;
+ case Double:
+ return (TQ_LLONG)d.data.d;
+ case Bool:
+ return (TQ_LLONG)d.data.b;
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as as an unsigned long long int if the variant
+ can be cast to ULongLong; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asULongLong(), canCast()
+*/
+TQ_ULLONG TQVariant::toULongLong( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( ULongLong );
+
+ switch ( d.type ) {
+ case Int:
+ return (TQ_ULLONG)d.data.i;
+ case UInt:
+ return (TQ_ULLONG)d.data.u;
+ case LongLong:
+ return (TQ_ULLONG)d.data.ll;
+ case ULongLong:
+ return d.data.ull;
+ case Double:
+ return (TQ_ULLONG)d.data.d;
+ case Bool:
+ return (TQ_ULLONG)d.data.b;
+ case String:
+ return ((TQString*)d.data.ptr)->toULongLong( ok );
+ case CString:
+ case ByteArray:
+ return TQString(*(TQCString*)d.data.ptr).toULongLong(ok);
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as a bool if the variant can be cast to Bool;
+ otherWise returns FALSE.
+
+ Returns TRUE if the variant has a numeric type and its value is
+ non-zero, or if the variant has type String, ByteArray or CString
+ and its lower-case content is not empty, "0" or "false"; otherwise
+ returns FALSE.
+
+ \sa asBool(), canCast()
+*/
+bool TQVariant::toBool() const
+{
+ switch( d.type ) {
+ case Bool:
+ return d.data.b;
+ case Double:
+ return d.data.d != 0.0;
+ case Int:
+ return d.data.i != 0;
+ case UInt:
+ return d.data.u != 0;
+ case LongLong:
+ return d.data.ll != 0;
+ case ULongLong:
+ return d.data.ull != 0;
+ case String:
+ case CString:
+ case ByteArray:
+ {
+ TQString str = toString().lower();
+ return !(str == "0" || str == "false" || str.isEmpty() );
+ }
+ default:
+ return FALSE;
+ }
+}
+
+/*!
+ Returns the variant as a double if the variant can be cast to
+ Double; otherwise returns 0.0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to a double; otherwise \a *ok is set to FALSE.
+
+ \sa asDouble(), canCast()
+*/
+double TQVariant::toDouble( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( Double );
+
+ switch ( d.type ) {
+ case String:
+ return ((TQString*)d.data.ptr)->toDouble( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d.data.ptr)->toDouble( ok );
+ case Double:
+ return d.data.d;
+ case Int:
+ return (double)d.data.i;
+ case Bool:
+ return (double)d.data.b;
+ case UInt:
+ return (double)d.data.u;
+ case LongLong:
+ return (double)d.data.ll;
+ case ULongLong:
+#if defined(TQ_CC_MSVC) && !defined(TQ_CC_MSVC_NET)
+ return (double)(TQ_LLONG)d.data.ull;
+#else
+ return (double)d.data.ull;
+#endif
+ default:
+ return 0.0;
+ }
+}
+
+#endif
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant as a TQValueList<TQVariant> if the variant has
+ type() List or StringList; otherwise returns an empty list.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQVariant> list = myVariant.toList();
+ TQValueList<TQVariant>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asList()
+*/
+const TQValueList<TQVariant> TQVariant::toList() const
+{
+ if ( d.type == List )
+ return *((TQValueList<TQVariant>*)d.data.ptr);
+#ifndef TQT_NO_STRINGLIST
+ if ( d.type == StringList ) {
+ TQValueList<TQVariant> lst;
+ TQStringList::ConstIterator it = stringListBegin();
+ TQStringList::ConstIterator end = stringListEnd();
+ for( ; it != end; ++it )
+ lst.append( TQVariant( *it ) );
+ return lst;
+ }
+#endif //TQT_NO_STRINGLIST
+ return TQValueList<TQVariant>();
+}
+#endif
+
+/*!
+ Returns the variant as a TQSizePolicy if the variant has type()
+ SizePolicy; otherwise returns an undefined (but legal) size
+ policy.
+*/
+
+TQSizePolicy TQVariant::toSizePolicy() const
+{
+ if ( d.type == SizePolicy )
+ return *((TQSizePolicy*)d.data.ptr);
+
+ return TQSizePolicy();
+}
+
+#else // USE_QT4
+
+#ifndef DBL_DIG
+#define DBL_DIG 10
+#endif //DBL_DIG
+
+// Uncomment to test for memory leaks or to run qt/test/qvariant/main.cpp
+// #define TQVARIANT_DEBUG
+
+
+static bool isNumeric(TQVariant::Type type)
+{
+ return (type == TQVariant::Int || type == TQVariant::UInt
+ || type == TQVariant::Double || type == TQVariant::LongLong
+ || type == TQVariant::ULongLong || type == TQVariant::Bool);
+}
+
+
+#ifdef TQVARIANT_DEBUG
+int qv_count = 0;
+int get_qv_count() { return qv_count; }
+#endif
+
+TQVariant::Private::Private()
+{
+#ifdef TQVARIANT_DEBUG
+ qv_count++;
+#endif
+ typ = TQVariant::Invalid;
+ is_null = TRUE;
+}
+
+TQVariant::Private::Private( Private* d )
+{
+#ifdef TQVARIANT_DEBUG
+ qv_count++;
+#endif
+
+ switch( d->typ )
+ {
+ case TQVariant::Invalid:
+ break;
+ case TQVariant::Bitmap:
+ value.ptr = new TQBitmap( *((TQBitmap*)d->value.ptr) );
+ break;
+ case TQVariant::Region:
+ value.ptr = new TQRegion( *((TQRegion*)d->value.ptr) );
+ // ## Force a detach
+ // ((TQRegion*)value.ptr)->translate( 0, 0 );
+ break;
+ case TQVariant::PointArray:
+ // TQPointArray is explicit shared
+ value.ptr = new TQPointArray( *((TQPointArray*)d->value.ptr) );
+ break;
+ case TQVariant::String:
+ value.ptr = new TQString( *((TQString*)d->value.ptr) );
+ break;
+ case TQVariant::CString:
+ // TQCString is explicit shared
+ value.ptr = new TQCString( *((TQCString*)d->value.ptr) );
+ break;
+#ifndef TQT_NO_STRINGLIST
+ case TQVariant::StringList:
+ value.ptr = new TQStringList( *((TQStringList*)d->value.ptr) );
+ break;
+#endif //TQT_NO_STRINGLIST
+ case TQVariant::Font:
+ value.ptr = new TQFont( *((TQFont*)d->value.ptr) );
+ break;
+ case TQVariant::Pixmap:
+ value.ptr = new TQPixmap( *((TQPixmap*)d->value.ptr) );
+ break;
+ case TQVariant::Image:
+ // TQImage is explicit shared
+ value.ptr = new TQImage( *((TQImage*)d->value.ptr) );
+ break;
+ case TQVariant::Brush:
+ value.ptr = new TQBrush( *((TQBrush*)d->value.ptr) );
+ // ## Force a detach
+ // ((TQBrush*)value.ptr)->setColor( ((TQBrush*)value.ptr)->color() );
+ break;
+ case TQVariant::Point:
+ value.ptr = new TQPoint( *((TQPoint*)d->value.ptr) );
+ break;
+ case TQVariant::Rect:
+ value.ptr = new TQRect( *((TQRect*)d->value.ptr) );
+ break;
+ case TQVariant::Size:
+ value.ptr = new TQSize( *((TQSize*)d->value.ptr) );
+ break;
+ case TQVariant::Color:
+ value.ptr = new TQColor( *((TQColor*)d->value.ptr) );
+ break;
+#ifndef TQT_NO_PALETTE
+ case TQVariant::Palette:
+ value.ptr = new TQPalette( *((TQPalette*)d->value.ptr) );
+ break;
+ case TQVariant::ColorGroup:
+ value.ptr = new TQColorGroup( *((TQColorGroup*)d->value.ptr) );
+ break;
+#endif
+#ifndef TQT_NO_ICONSET
+ case TQVariant::IconSet:
+ value.ptr = new TQIconSet( *((TQIconSet*)d->value.ptr) );
+ break;
+#endif
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case TQVariant::Map:
+ value.ptr = new TQMap<TQString,TQVariant>( *((TQMap<TQString,TQVariant>*)d->value.ptr) );
+ break;
+ case TQVariant::List:
+ value.ptr = new TQValueList<TQVariant>( *((TQValueList<TQVariant>*)d->value.ptr) );
+ break;
+#endif
+ case TQVariant::Date:
+ value.ptr = new TQDate( *((TQDate*)d->value.ptr) );
+ break;
+ case TQVariant::Time:
+ value.ptr = new TQTime( *((TQTime*)d->value.ptr) );
+ break;
+ case TQVariant::DateTime:
+ value.ptr = new TQDateTime( *((TQDateTime*)d->value.ptr) );
+ break;
+ case TQVariant::ByteArray:
+ value.ptr = new TQByteArray( *((TQByteArray*)d->value.ptr) );
+ break;
+ case TQVariant::BitArray:
+ value.ptr = new TQBitArray( *((TQBitArray*)d->value.ptr) );
+ break;
+#ifndef TQT_NO_ACCEL
+ case TQVariant::KeySequence:
+ value.ptr = new TQKeySequence( *((TQKeySequence*)d->value.ptr) );
+ break;
+#endif
+ case TQVariant::Pen:
+ value.ptr = new TQPen( *((TQPen*)d->value.ptr) );
+ break;
+ case TQVariant::Int:
+ value.i = d->value.i;
+ break;
+ case TQVariant::UInt:
+ value.u = d->value.u;
+ break;
+ case TQVariant::LongLong:
+ value.ll = d->value.ll;
+ break;
+ case TQVariant::ULongLong:
+ value.ull = d->value.ull;
+ break;
+ case TQVariant::Bool:
+ value.b = d->value.b;
+ break;
+ case TQVariant::Double:
+ value.d = d->value.d;
+ break;
+ case TQVariant::SizePolicy:
+ value.ptr = new TQSizePolicy( *((TQSizePolicy*)d->value.ptr) );
+ break;
+ case TQVariant::Cursor:
+ value.ptr = new TQCursor( *((TQCursor*)d->value.ptr) );
+ break;
+ default:
+ TQ_ASSERT( 0 );
+ }
+
+ typ = d->typ;
+ is_null = d->is_null;
+}
+
+TQVariant::Private::~Private()
+{
+#ifdef TQVARIANT_DEBUG
+ qv_count--;
+#endif
+ clear();
+}
+
+void TQVariant::Private::clear()
+{
+ switch( typ )
+ {
+ case TQVariant::Bitmap:
+ delete (TQBitmap*)value.ptr;
+ break;
+ case TQVariant::Cursor:
+ delete (TQCursor*)value.ptr;
+ break;
+ case TQVariant::Region:
+ delete (TQRegion*)value.ptr;
+ break;
+ case TQVariant::PointArray:
+ delete (TQPointArray*)value.ptr;
+ break;
+ case TQVariant::String:
+ delete (TQString*)value.ptr;
+ break;
+ case TQVariant::CString:
+ delete (TQCString*)value.ptr;
+ break;
+#ifndef TQT_NO_STRINGLIST
+ case TQVariant::StringList:
+ delete (TQStringList*)value.ptr;
+ break;
+#endif //TQT_NO_STRINGLIST
+ case TQVariant::Font:
+ delete (TQFont*)value.ptr;
+ break;
+ case TQVariant::Pixmap:
+ delete (TQPixmap*)value.ptr;
+ break;
+ case TQVariant::Image:
+ delete (TQImage*)value.ptr;
+ break;
+ case TQVariant::Brush:
+ delete (TQBrush*)value.ptr;
+ break;
+ case TQVariant::Point:
+ delete (TQPoint*)value.ptr;
+ break;
+ case TQVariant::Rect:
+ delete (TQRect*)value.ptr;
+ break;
+ case TQVariant::Size:
+ delete (TQSize*)value.ptr;
+ break;
+ case TQVariant::Color:
+ delete (TQColor*)value.ptr;
+ break;
+#ifndef TQT_NO_PALETTE
+ case TQVariant::Palette:
+ delete (TQPalette*)value.ptr;
+ break;
+ case TQVariant::ColorGroup:
+ delete (TQColorGroup*)value.ptr;
+ break;
+#endif
+#ifndef TQT_NO_ICONSET
+ case TQVariant::IconSet:
+ delete (TQIconSet*)value.ptr;
+ break;
+#endif
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case TQVariant::Map:
+ delete (TQMap<TQString,TQVariant>*)value.ptr;
+ break;
+ case TQVariant::List:
+ delete (TQValueList<TQVariant>*)value.ptr;
+ break;
+#endif
+ case TQVariant::SizePolicy:
+ delete (TQSizePolicy*)value.ptr;
+ break;
+ case TQVariant::Date:
+ delete (TQDate*)value.ptr;
+ break;
+ case TQVariant::Time:
+ delete (TQTime*)value.ptr;
+ break;
+ case TQVariant::DateTime:
+ delete (TQDateTime*)value.ptr;
+ break;
+ case TQVariant::ByteArray:
+ delete (TQByteArray*)value.ptr;
+ break;
+ case TQVariant::BitArray:
+ delete (TQBitArray*)value.ptr;
+ break;
+#ifndef TQT_NO_ACCEL
+ case TQVariant::KeySequence:
+ delete (TQKeySequence*)value.ptr;
+ break;
+#endif
+ case TQVariant::Pen:
+ delete (TQPen*)value.ptr;
+ break;
+ case TQVariant::Invalid:
+ case TQVariant::Int:
+ case TQVariant::UInt:
+ case TQVariant::LongLong:
+ case TQVariant::ULongLong:
+ case TQVariant::Bool:
+ case TQVariant::Double:
+ break;
+ }
+
+ typ = TQVariant::Invalid;
+ is_null = TRUE;
+}
+
+/*!
+ \class TQVariant tqvariant.h
+ \brief The TQVariant class acts like a union for the most common TQt data types.
+
+ \ingroup objectmodel
+ \ingroup misc
+ \mainclass
+
+ Because C++ forbids unions from including types that have
+ non-default constructors or destructors, most interesting TQt
+ classes cannot be used in unions. Without TQVariant, this would be
+ a problem for TQObject::property() and for database work, etc.
+
+ A TQVariant object holds a single value of a single type() at a
+ time. (Some type()s are multi-valued, for example a string list.)
+ You can tqfind out what type, T, the variant holds, convert it to a
+ different type using one of the asT() functions, e.g. asSize(),
+ get its value using one of the toT() functions, e.g. toSize(), and
+ check whether the type can be converted to a particular type using
+ canCast().
+
+ The methods named toT() (for any supported T, see the \c Type
+ documentation for a list) are const. If you ask for the stored
+ type, they return a copy of the stored object. If you ask for a
+ type that can be generated from the stored type, toT() copies and
+ converts and leaves the object itself unchanged. If you ask for a
+ type that cannot be generated from the stored type, the result
+ depends on the type (see the function documentation for details).
+
+ Note that three data types supported by TQVariant are explicitly
+ shared, namely TQImage, TQPointArray, and TQCString, and in these
+ cases the toT() methods return a shallow copy. In almost all cases
+ you must make a deep copy of the returned values before modifying
+ them.
+
+ The asT() functions are not const. They do conversion like the
+ toT() methods, set the variant to hold the converted value, and
+ return a reference to the new contents of the variant.
+
+ Here is some example code to demonstrate the use of TQVariant:
+
+ \code
+ TQDataStream out(...);
+ TQVariant v(123); // The variant now tqcontains an int
+ int x = v.toInt(); // x = 123
+ out << v; // Writes a type tag and an int to out
+ v = TQVariant("hello"); // The variant now tqcontains a TQCString
+ v = TQVariant(tr("hello"));// The variant now tqcontains a TQString
+ int y = v.toInt(); // y = 0 since v cannot be converted to an int
+ TQString s = v.toString(); // s = tr("hello") (see TQObject::tr())
+ out << v; // Writes a type tag and a TQString to out
+ ...
+ TQDataStream in(...); // (opening the previously written stream)
+ in >> v; // Reads an Int variant
+ int z = v.toInt(); // z = 123
+ qDebug("Type is %s", // prints "Type is int"
+ v.typeName());
+ v.asInt() += 100; // The variant now hold the value 223.
+ v = TQVariant( TQStringList() );
+ v.asStringList().append( "Hello" );
+ \endcode
+
+ You can even store TQValueList<TQVariant>s and
+ TQMap<TQString,TQVariant>s in a variant, so you can easily construct
+ arbitrarily complex data structures of arbitrary types. This is
+ very powerful and versatile, but may prove less memory and speed
+ efficient than storing specific types in standard data structures.
+
+ TQVariant also supports the notion of NULL values, where you have a
+ defined type with no value set.
+ \code
+ TQVariant x, y( TQString() ), z( TQString("") );
+ x.asInt();
+ // x.isNull() == TRUE, y.isNull() == TRUE, z.isNull() == FALSE
+ \endcode
+
+ See the \link collection.html Collection Classes\endlink.
+*/
+
+/*!
+ \enum TQVariant::Type
+
+ This enum type defines the types of variable that a TQVariant can
+ contain.
+
+ \value Invalid no type
+ \value BitArray a TQBitArray
+ \value ByteArray a TQByteArray
+ \value Bitmap a TQBitmap
+ \value Bool a bool
+ \value Brush a TQBrush
+ \value Color a TQColor
+ \value ColorGroup a TQColorGroup
+ \value Cursor a TQCursor
+ \value Date a TQDate
+ \value DateTime a TQDateTime
+ \value Double a double
+ \value Font a TQFont
+ \value IconSet a TQIconSet
+ \value Image a TQImage
+ \value Int an int
+ \value KeySequence a TQKeySequence
+ \value List a TQValueList<TQVariant>
+ \value LongLong a long long
+ \value ULongLong an unsigned long long
+ \value Map a TQMap<TQString,TQVariant>
+ \value Palette a TQPalette
+ \value Pen a TQPen
+ \value Pixmap a TQPixmap
+ \value Point a TQPoint
+ \value PointArray a TQPointArray
+ \value Rect a TQRect
+ \value Region a TQRegion
+ \value Size a TQSize
+ \value SizePolicy a TQSizePolicy
+ \value String a TQString
+ \value CString a TQCString
+ \value StringList a TQStringList
+ \value Time a TQTime
+ \value UInt an unsigned int
+
+ Note that TQt's definition of bool depends on the compiler.
+ \c tqglobal.h has the system-dependent definition of bool.
+*/
+
+/*!
+ Constructs an invalid variant.
+*/
+TQVariant::TQVariant()
+{
+ d = new Private;
+}
+
+/*!
+ Destroys the TQVariant and the contained object.
+
+ Note that subclasses that reimplement clear() should reimplement
+ the destructor to call clear(). This destructor calls clear(), but
+ because it is the destructor, TQVariant::clear() is called rather
+ than a subclass's clear().
+*/
+TQVariant::~TQVariant()
+{
+ if ( d->deref() )
+ delete d;
+}
+
+/*!
+ Constructs a copy of the variant, \a p, passed as the argument to
+ this constructor. Usually this is a deep copy, but a shallow copy
+ is made if the stored data type is explicitly shared, as e.g.
+ TQImage is.
+*/
+TQVariant::TQVariant( const TQVariant& p )
+{
+ p.d->ref();
+ d = p.d;
+}
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ Reads the variant from the data stream, \a s.
+*/
+TQVariant::TQVariant( TQDataStream& s )
+{
+ d = new Private;
+ s >> *this;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*!
+ Constructs a new variant with a string value, \a val.
+*/
+TQVariant::TQVariant( const TQString& val )
+{
+ d = new Private;
+ d->typ = String;
+ d->value.ptr = new TQString( val );
+}
+
+/*!
+ Constructs a new variant with a C-string value, \a val.
+
+ If you want to modify the TQCString after you've passed it to this
+ constructor, we recommend passing a deep copy (see
+ TQCString::copy()).
+*/
+TQVariant::TQVariant( const TQCString& val )
+{
+ d = new Private;
+ d->typ = CString;
+ d->value.ptr = new TQCString( val );
+}
+
+/*!
+ Constructs a new variant with a C-string value of \a val if \a val
+ is non-null. The variant creates a deep copy of \a val.
+
+ If \a val is null, the resulting variant has type Invalid.
+*/
+TQVariant::TQVariant( const char* val )
+{
+ d = new Private;
+ if ( val == 0 )
+ return;
+ d->typ = CString;
+ d->value.ptr = new TQCString( val );
+}
+
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Constructs a new variant with a string list value, \a val.
+*/
+TQVariant::TQVariant( const TQStringList& val )
+{
+ d = new Private;
+ d->typ = StringList;
+ d->value.ptr = new TQStringList( val );
+ d->is_null = FALSE;
+}
+#endif // TQT_NO_STRINGLIST
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Constructs a new variant with a map of TQVariants, \a val.
+*/
+TQVariant::TQVariant( const TQMap<TQString,TQVariant>& val )
+{
+ d = new Private;
+ d->typ = Map;
+ d->value.ptr = new TQMap<TQString,TQVariant>( val );
+ d->is_null = FALSE;
+}
+#endif
+/*!
+ Constructs a new variant with a font value, \a val.
+*/
+TQVariant::TQVariant( const TQFont& val )
+{
+ d = new Private;
+ d->typ = Font;
+ d->value.ptr = new TQFont( val );
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a pixmap value, \a val.
+*/
+TQVariant::TQVariant( const TQPixmap& val )
+{
+ d = new Private;
+ d->typ = Pixmap;
+ d->value.ptr = new TQPixmap( val );
+}
+
+
+/*!
+ Constructs a new variant with an image value, \a val.
+
+ Because TQImage is explicitly shared, you may need to pass a deep
+ copy to the variant using TQImage::copy(), e.g. if you intend
+ changing the image you've passed later on.
+*/
+TQVariant::TQVariant( const TQImage& val )
+{
+ d = new Private;
+ d->typ = Image;
+ d->value.ptr = new TQImage( val );
+}
+
+/*!
+ Constructs a new variant with a brush value, \a val.
+*/
+TQVariant::TQVariant( const TQBrush& val )
+{
+ d = new Private;
+ d->typ = Brush;
+ d->value.ptr = new TQBrush( val );
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a point value, \a val.
+*/
+TQVariant::TQVariant( const TQPoint& val )
+{
+ d = new Private;
+ d->typ = Point;
+ d->value.ptr = new TQPoint( val );
+}
+
+/*!
+ Constructs a new variant with a rect value, \a val.
+*/
+TQVariant::TQVariant( const TQRect& val )
+{
+ d = new Private;
+ d->typ = Rect;
+ d->value.ptr = new TQRect( val );
+}
+
+/*!
+ Constructs a new variant with a size value, \a val.
+*/
+TQVariant::TQVariant( const TQSize& val )
+{
+ d = new Private;
+ d->typ = Size;
+ d->value.ptr = new TQSize( val );
+}
+
+/*!
+ Constructs a new variant with a color value, \a val.
+*/
+TQVariant::TQVariant( const TQColor& val )
+{
+ d = new Private;
+ d->typ = Color;
+ d->value.ptr = new TQColor( val );
+ d->is_null = FALSE;
+}
+
+#ifndef TQT_NO_PALETTE
+/*!
+ Constructs a new variant with a color palette value, \a val.
+*/
+TQVariant::TQVariant( const TQPalette& val )
+{
+ d = new Private;
+ d->typ = Palette;
+ d->value.ptr = new TQPalette( val );
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a color group value, \a val.
+*/
+TQVariant::TQVariant( const TQColorGroup& val )
+{
+ d = new Private;
+ d->typ = ColorGroup;
+ d->value.ptr = new TQColorGroup( val );
+ d->is_null = FALSE;
+}
+#endif //TQT_NO_PALETTE
+#ifndef TQT_NO_ICONSET
+/*!
+ Constructs a new variant with an icon set value, \a val.
+*/
+TQVariant::TQVariant( const TQIconSet& val )
+{
+ d = new Private;
+ d->typ = IconSet;
+ d->value.ptr = new TQIconSet( val );
+}
+#endif //TQT_NO_ICONSET
+/*!
+ Constructs a new variant with a region value, \a val.
+*/
+TQVariant::TQVariant( const TQRegion& val )
+{
+ d = new Private;
+ d->typ = Region;
+ // ## Force a detach
+ d->value.ptr = new TQRegion( val );
+ ((TQRegion*)d->value.ptr)->translate( 0, 0 );
+}
+
+/*!
+ Constructs a new variant with a bitmap value, \a val.
+*/
+TQVariant::TQVariant( const TQBitmap& val )
+{
+ d = new Private;
+ d->typ = Bitmap;
+ d->value.ptr = new TQBitmap( val );
+}
+
+/*!
+ Constructs a new variant with a cursor value, \a val.
+*/
+TQVariant::TQVariant( const TQCursor& val )
+{
+ d = new Private;
+ d->typ = Cursor;
+ d->value.ptr = new TQCursor( val );
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a point array value, \a val.
+
+ Because TQPointArray is explicitly shared, you may need to pass a
+ deep copy to the variant using TQPointArray::copy(), e.g. if you
+ intend changing the point array you've passed later on.
+*/
+TQVariant::TQVariant( const TQPointArray& val )
+{
+ d = new Private;
+ d->typ = PointArray;
+ d->value.ptr = new TQPointArray( val );
+}
+
+/*!
+ Constructs a new variant with a date value, \a val.
+*/
+TQVariant::TQVariant( const TQDate& val )
+{
+ d = new Private;
+ d->typ = Date;
+ d->value.ptr = new TQDate( val );
+}
+
+/*!
+ Constructs a new variant with a time value, \a val.
+*/
+TQVariant::TQVariant( const TQTime& val )
+{
+ d = new Private;
+ d->typ = Time;
+ d->value.ptr = new TQTime( val );
+}
+
+/*!
+ Constructs a new variant with a date/time value, \a val.
+*/
+TQVariant::TQVariant( const TQDateTime& val )
+{
+ d = new Private;
+ d->typ = DateTime;
+ d->value.ptr = new TQDateTime( val );
+}
+
+/*!
+ Constructs a new variant with a bytearray value, \a val.
+*/
+TQVariant::TQVariant( const TQByteArray& val )
+{
+ d = new Private;
+ d->typ = ByteArray;
+ d->value.ptr = new TQByteArray( val );
+}
+
+/*!
+ Constructs a new variant with a bitarray value, \a val.
+*/
+TQVariant::TQVariant( const TQBitArray& val )
+{
+ d = new Private;
+ d->typ = BitArray;
+ d->value.ptr = new TQBitArray( val );
+}
+
+#ifndef TQT_NO_ACCEL
+
+/*!
+ Constructs a new variant with a key sequence value, \a val.
+*/
+TQVariant::TQVariant( const TQKeySequence& val )
+{
+ d = new Private;
+ d->typ = KeySequence;
+ d->value.ptr = new TQKeySequence( val );
+ d->is_null = FALSE;
+}
+
+#endif
+
+/*!
+ Constructs a new variant with a pen value, \a val.
+*/
+TQVariant::TQVariant( const TQPen& val )
+{
+ d = new Private;
+ d->typ = Pen;
+ d->value.ptr = new TQPen( val );
+}
+
+/*!
+ Constructs a new variant with an integer value, \a val.
+*/
+TQVariant::TQVariant( int val )
+{
+ d = new Private;
+ d->typ = Int;
+ d->value.i = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with an unsigned integer value, \a val.
+*/
+TQVariant::TQVariant( uint val )
+{
+ d = new Private;
+ d->typ = UInt;
+ d->value.u = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a long long integer value, \a val.
+*/
+TQVariant::TQVariant( TQ_LLONG val )
+{
+ d = new Private;
+ d->typ = LongLong;
+ d->value.ll = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with an unsigned long long integer value, \a val.
+*/
+
+TQVariant::TQVariant( TQ_ULLONG val )
+{
+ d = new Private;
+ d->typ = ULongLong;
+ d->value.ull = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a boolean value, \a val. The integer
+ argument is a dummy, necessary for compatibility with some
+ compilers.
+*/
+TQVariant::TQVariant( bool val, int )
+{ // this is the comment that does NOT name said compiler.
+ d = new Private;
+ d->typ = Bool;
+ d->value.b = val;
+ d->is_null = FALSE;
+}
+
+
+/*!
+ Constructs a new variant with a floating point value, \a val.
+*/
+TQVariant::TQVariant( double val )
+{
+ d = new Private;
+ d->typ = Double;
+ d->value.d = val;
+ d->is_null = FALSE;
+}
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Constructs a new variant with a list value, \a val.
+*/
+TQVariant::TQVariant( const TQValueList<TQVariant>& val )
+{
+ d = new Private;
+ d->typ = List;
+ d->value.ptr = new TQValueList<TQVariant>( val );
+ d->is_null = FALSE;
+}
+#endif
+
+/*!
+ Constructs a new variant with a size policy value, \a val.
+*/
+TQVariant::TQVariant( TQSizePolicy val )
+{
+ d = new Private;
+ d->typ = SizePolicy;
+ d->value.ptr = new TQSizePolicy( val );
+ d->is_null = FALSE;
+}
+
+/*!
+ Assigns the value of the variant \a variant to this variant.
+
+ This is a deep copy of the variant, but note that if the variant
+ holds an explicitly shared type such as TQImage, a shallow copy is
+ performed.
+*/
+TQVariant& TQVariant::operator= ( const TQVariant& variant )
+{
+ TQVariant& other = (TQVariant&)variant;
+
+ other.d->ref();
+ if ( d->deref() )
+ delete d;
+
+ d = other.d;
+
+ return *this;
+}
+
+/*!
+ \internal
+*/
+void TQVariant::detach()
+{
+ if ( d->count == 1 )
+ return;
+
+ d->deref();
+ d = new Private( d );
+}
+
+/*!
+ Returns the name of the type stored in the variant. The returned
+ strings describe the C++ datatype used to store the data: for
+ example, "TQFont", "TQString", or "TQValueList<TQVariant>". An Invalid
+ variant returns 0.
+*/
+const char* TQVariant::typeName() const
+{
+ return typeToName( (Type) d->typ );
+}
+
+/*!
+ Convert this variant to type Invalid and free up any resources
+ used.
+*/
+void TQVariant::clear()
+{
+ if ( d->count > 1 )
+ {
+ d->deref();
+ d = new Private;
+ return;
+ }
+
+ d->clear();
+}
+
+/* Attention!
+
+ For dependency reasons, this table is duplicated in tqmoc.y. If you
+ change one, change both.
+
+ (Search for the word 'Attention' in tqmoc.y.)
+*/
+static const int ntypes = 35;
+static const char* const type_map[ntypes] =
+{
+ 0,
+ "TQMap<TQString,TQVariant>",
+ "TQValueList<TQVariant>",
+ "TQString",
+ "TQStringList",
+ "TQFont",
+ "TQPixmap",
+ "TQBrush",
+ "TQRect",
+ "TQSize",
+ "TQColor",
+ "TQPalette",
+ "TQColorGroup",
+ "TQIconSet",
+ "TQPoint",
+ "TQImage",
+ "int",
+ "uint",
+ "bool",
+ "double",
+ "TQCString",
+ "TQPointArray",
+ "TQRegion",
+ "TQBitmap",
+ "TQCursor",
+ "TQSizePolicy",
+ "TQDate",
+ "TQTime",
+ "TQDateTime",
+ "TQByteArray",
+ "TQBitArray",
+ "TQKeySequence",
+ "TQPen",
+ "TQ_LLONG",
+ "TQ_ULLONG"
+};
+
+
+/*!
+ Converts the enum representation of the storage type, \a typ, to
+ its string representation.
+*/
+const char* TQVariant::typeToName( Type typ )
+{
+ if ( typ >= ntypes )
+ return 0;
+ return type_map[typ];
+}
+
+
+/*!
+ Converts the string representation of the storage type given in \a
+ name, to its enum representation.
+
+ If the string representation cannot be converted to any enum
+ representation, the variant is set to \c Invalid.
+*/
+TQVariant::Type TQVariant::nameToType( const char* name )
+{
+ for ( int i = 0; i < ntypes; i++ ) {
+ if ( !qstrcmp( type_map[i], name ) )
+ return (Type) i;
+ }
+ return Invalid;
+}
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ Internal function for loading a variant from stream \a s. Use the
+ stream operators instead.
+
+ \internal
+*/
+void TQVariant::load( TQDataStream& s )
+{
+ clear();
+ TQ_UINT32 u;
+ s >> u;
+ Type t = (Type)u;
+
+ switch( t ) {
+ case Invalid:
+ {
+ // Since we wrote something, we should read something
+ TQString x;
+ s >> x;
+ d->typ = t;
+ d->is_null = TRUE;
+ }
+ break;
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case Map:
+ {
+ TQMap<TQString,TQVariant>* x = new TQMap<TQString,TQVariant>;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case List:
+ {
+ TQValueList<TQVariant>* x = new TQValueList<TQVariant>;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+#endif
+ case Cursor:
+ {
+#ifndef TQT_NO_CURSOR
+ TQCursor* x = new TQCursor;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+#endif
+ }
+ break;
+ case Bitmap:
+ {
+ TQBitmap* x = new TQBitmap;
+#ifndef TQT_NO_IMAGEIO
+ s >> *x;
+#endif
+ d->value.ptr = x;
+ }
+ break;
+ case Region:
+ {
+ TQRegion* x = new TQRegion;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case PointArray:
+ {
+ TQPointArray* x = new TQPointArray;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case String:
+ {
+ TQString* x = new TQString;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case CString:
+ {
+ TQCString* x = new TQCString;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+#ifndef TQT_NO_STRINGLIST
+ case StringList:
+ {
+ TQStringList* x = new TQStringList;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+#endif // TQT_NO_STRINGLIST
+ case Font:
+ {
+ TQFont* x = new TQFont;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case Pixmap:
+ {
+ TQPixmap* x = new TQPixmap;
+#ifndef TQT_NO_IMAGEIO
+ s >> *x;
+#endif
+ d->value.ptr = x;
+ }
+ break;
+ case Image:
+ {
+ TQImage* x = new TQImage;
+#ifndef TQT_NO_IMAGEIO
+ s >> *x;
+#endif
+ d->value.ptr = x;
+ }
+ break;
+ case Brush:
+ {
+ TQBrush* x = new TQBrush;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case Rect:
+ {
+ TQRect* x = new TQRect;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Point:
+ {
+ TQPoint* x = new TQPoint;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Size:
+ {
+ TQSize* x = new TQSize;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Color:
+ {
+ TQColor* x = new TQColor;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+#ifndef TQT_NO_PALETTE
+ case Palette:
+ {
+ TQPalette* x = new TQPalette;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case ColorGroup:
+ {
+ TQColorGroup* x = new TQColorGroup;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+#endif
+#ifndef TQT_NO_ICONSET
+ case IconSet:
+ {
+ TQPixmap x;
+ s >> x;
+ d->value.ptr = new TQIconSet( x );
+ }
+ break;
+#endif
+ case Int:
+ {
+ int x;
+ s >> x;
+ d->value.i = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case UInt:
+ {
+ uint x;
+ s >> x;
+ d->value.u = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case LongLong:
+ {
+ TQ_LLONG x;
+ s >> x;
+ d->value.ll = x;
+ }
+ break;
+ case ULongLong:
+ {
+ TQ_ULLONG x;
+ s >> x;
+ d->value.ull = x;
+ }
+ break;
+ case Bool:
+ {
+ TQ_INT8 x;
+ s >> x;
+ d->value.b = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case Double:
+ {
+ double x;
+ s >> x;
+ d->value.d = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case SizePolicy:
+ {
+ int h,v;
+ TQ_INT8 hfw;
+ s >> h >> v >> hfw;
+ d->value.ptr = new TQSizePolicy( (TQSizePolicy::SizeType)h,
+ (TQSizePolicy::SizeType)v,
+ (bool) hfw);
+ d->is_null = FALSE;
+ }
+ break;
+ case Date:
+ {
+ TQDate* x = new TQDate;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Time:
+ {
+ TQTime* x = new TQTime;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case DateTime:
+ {
+ TQDateTime* x = new TQDateTime;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case ByteArray:
+ {
+ TQByteArray* x = new TQByteArray;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case BitArray:
+ {
+ TQBitArray* x = new TQBitArray;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ {
+ TQKeySequence* x = new TQKeySequence;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+#endif // TQT_NO_ACCEL
+ case Pen:
+ {
+ TQPen* x = new TQPen;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+ }
+ d->typ = t;
+}
+
+/*!
+ Internal function for saving a variant to the stream \a s. Use the
+ stream operators instead.
+
+ \internal
+*/
+void TQVariant::save( TQDataStream& s ) const
+{
+ s << (TQ_UINT32)type();
+
+ switch( d->typ ) {
+ case Cursor:
+ s << *((TQCursor*)d->value.ptr);
+ break;
+ case Bitmap:
+#ifndef TQT_NO_IMAGEIO
+ s << *((TQBitmap*)d->value.ptr);
+#endif
+ break;
+ case PointArray:
+ s << *((TQPointArray*)d->value.ptr);
+ break;
+ case Region:
+ s << *((TQRegion*)d->value.ptr);
+ break;
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case List:
+ s << *((TQValueList<TQVariant>*)d->value.ptr);
+ break;
+ case Map:
+ s << *((TQMap<TQString,TQVariant>*)d->value.ptr);
+ break;
+#endif
+ case String:
+ s << *((TQString*)d->value.ptr);
+ break;
+ case CString:
+ s << *((TQCString*)d->value.ptr);
+ break;
+#ifndef TQT_NO_STRINGLIST
+ case StringList:
+ s << *((TQStringList*)d->value.ptr);
+ break;
+#endif
+ case Font:
+ s << *((TQFont*)d->value.ptr);
+ break;
+ case Pixmap:
+#ifndef TQT_NO_IMAGEIO
+ s << *((TQPixmap*)d->value.ptr);
+#endif
+ break;
+ case Image:
+#ifndef TQT_NO_IMAGEIO
+ s << *((TQImage*)d->value.ptr);
+#endif
+ break;
+ case Brush:
+ s << *((TQBrush*)d->value.ptr);
+ break;
+ case Point:
+ s << *((TQPoint*)d->value.ptr);
+ break;
+ case Rect:
+ s << *((TQRect*)d->value.ptr);
+ break;
+ case Size:
+ s << *((TQSize*)d->value.ptr);
+ break;
+ case Color:
+ s << *((TQColor*)d->value.ptr);
+ break;
+#ifndef TQT_NO_PALETTE
+ case Palette:
+ s << *((TQPalette*)d->value.ptr);
+ break;
+ case ColorGroup:
+ s << *((TQColorGroup*)d->value.ptr);
+ break;
+#endif
+#ifndef TQT_NO_ICONSET
+ case IconSet:
+ //### add stream operator to iconset
+ s << ((TQIconSet*)d->value.ptr)->pixmap();
+ break;
+#endif
+ case Int:
+ s << d->value.i;
+ break;
+ case UInt:
+ s << d->value.u;
+ break;
+ case LongLong:
+ s << d->value.ll;
+ break;
+ case ULongLong:
+ s << d->value.ull;
+ break;
+ case Bool:
+ s << (TQ_INT8)d->value.b;
+ break;
+ case Double:
+ s << d->value.d;
+ break;
+ case SizePolicy:
+ {
+ TQSizePolicy p = toSizePolicy();
+ s << (int) p.horData() << (int) p.verData()
+ << (TQ_INT8) p.hasHeightForWidth();
+ }
+ break;
+ case Date:
+ s << *((TQDate*)d->value.ptr);
+ break;
+ case Time:
+ s << *((TQTime*)d->value.ptr);
+ break;
+ case DateTime:
+ s << *((TQDateTime*)d->value.ptr);
+ break;
+ case ByteArray:
+ s << *((TQByteArray*)d->value.ptr);
+ break;
+ case BitArray:
+ s << *((TQBitArray*)d->value.ptr);
+ break;
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ s << *((TQKeySequence*)d->value.ptr);
+ break;
+#endif
+ case Pen:
+ s << *((TQPen*)d->value.ptr);
+ break;
+ case Invalid:
+ s << TQString(); // ### looks wrong.
+ break;
+ }
+}
+
+/*!
+ Reads a variant \a p from the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream
+ operators \endlink
+*/
+TQDataStream& operator>> ( TQDataStream& s, TQVariant& p )
+{
+ p.load( s );
+ return s;
+}
+
+/*!
+ Writes a variant \a p to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream
+ operators \endlink
+*/
+TQDataStream& operator<< ( TQDataStream& s, const TQVariant& p )
+{
+ p.save( s );
+ return s;
+}
+
+/*!
+ Reads a variant type \a p in enum representation from the stream \a s.
+*/
+TQDataStream& operator>> ( TQDataStream& s, TQVariant::Type& p )
+{
+ TQ_UINT32 u;
+ s >> u;
+ p = (TQVariant::Type) u;
+
+ return s;
+}
+
+/*!
+ Writes a variant type \a p to the stream \a s.
+*/
+TQDataStream& operator<< ( TQDataStream& s, const TQVariant::Type p )
+{
+ s << (TQ_UINT32)p;
+
+ return s;
+}
+
+#endif //TQT_NO_DATASTREAM
+
+/*!
+ \fn Type TQVariant::type() const
+
+ Returns the storage type of the value stored in the variant.
+ Usually it's best to test with canCast() whether the variant can
+ deliver the data type you are interested in.
+*/
+
+/*!
+ \fn bool TQVariant::isValid() const
+
+ Returns TRUE if the storage type of this variant is not
+ TQVariant::Invalid; otherwise returns FALSE.
+*/
+
+/*!
+ \fn TQValueListConstIterator<TQString> TQVariant::stringListBegin() const
+ \obsolete
+
+ Returns an iterator to the first string in the list if the
+ variant's type is StringList; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQValueListConstIterator<TQString> TQVariant::stringListEnd() const
+ \obsolete
+
+ Returns the end iterator for the list if the variant's type is
+ StringList; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQValueListConstIterator<TQVariant> TQVariant::listBegin() const
+ \obsolete
+
+ Returns an iterator to the first item in the list if the variant's
+ type is appropriate; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQValueListConstIterator<TQVariant> TQVariant::listEnd() const
+ \obsolete
+
+ Returns the end iterator for the list if the variant's type is
+ appropriate; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQMapConstIterator<TQString, TQVariant> TQVariant::mapBegin() const
+ \obsolete
+
+ Returns an iterator to the first item in the map, if the variant's
+ type is appropriate; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQMapConstIterator<TQString, TQVariant> TQVariant::mapEnd() const
+ \obsolete
+
+ Returns the end iterator for the map, if the variant's type is
+ appropriate; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQMapConstIterator<TQString, TQVariant> TQVariant::mapFind( const TQString& key ) const
+ \obsolete
+
+ Returns an iterator to the item in the map with \a key as key, if
+ the variant's type is appropriate and \a key is a valid key;
+ otherwise returns a null iterator.
+*/
+
+/*!
+ Returns the variant as a TQString if the variant can be cast to
+ String, otherwise returns TQString::null.
+
+ \sa asString(), canCast()
+*/
+const TQString TQVariant::toString() const
+{
+ switch( d->typ ) {
+ case CString:
+ return TQString::tqfromLatin1( toCString() );
+ case Int:
+ return TQString::number( toInt() );
+ case UInt:
+ return TQString::number( toUInt() );
+ case LongLong:
+ return TQString::number( toLongLong() );
+ case ULongLong:
+ return TQString::number( toULongLong() );
+ case Double:
+ return TQString::number( toDouble(), 'g', DBL_DIG );
+#if !defined(TQT_NO_SPRINTF) && !defined(TQT_NO_DATESTRING)
+ case Date:
+ return toDate().toString( TQt::ISODate );
+ case Time:
+ return toTime().toString( TQt::ISODate );
+ case DateTime:
+ return toDateTime().toString( TQt::ISODate );
+#endif
+ case Bool:
+ return toInt() ? "true" : "false";
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ return (TQString) *( (TQKeySequence*)d->value.ptr );
+#endif
+ case ByteArray:
+ return TQString( *((TQByteArray*)d->value.ptr) );
+ case Font:
+ return toFont().toString();
+ case Color:
+ return toColor().name();
+ case String:
+ return *((TQString*)d->value.ptr);
+ default:
+ return TQString::null;
+ }
+}
+/*!
+ Returns the variant as a TQCString if the variant can be cast to a
+ CString; otherwise returns 0.
+
+ \sa asCString(), canCast()
+*/
+const TQCString TQVariant::toCString() const
+{
+ switch( d->typ ) {
+ case CString: return *((TQCString*)d->value.ptr);
+ case String: return ((TQString*)d->value.ptr)->latin1();
+ default: {
+ if (!canCast(String))
+ return 0;
+ TQString c = toString();
+ return TQCString(c.latin1());
+ }
+ }
+}
+
+
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Returns the variant as a TQStringList if the variant has type()
+ StringList or List of a type that can be converted to TQString;
+ otherwise returns an empty list.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myVariant.toStringList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asStringList()
+*/
+const TQStringList TQVariant::toStringList() const
+{
+ switch ( d->typ ) {
+ case StringList:
+ return *((TQStringList*)d->value.ptr);
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case List:
+ {
+ TQStringList lst;
+ TQValueList<TQVariant>::ConstIterator it = listBegin();
+ TQValueList<TQVariant>::ConstIterator end = listEnd();
+ while( it != end ) {
+ TQString tmp = (*it).toString();
+ ++it;
+ lst.append( tmp );
+ }
+ return lst;
+ }
+#endif
+ default:
+ return TQStringList();
+ }
+}
+#endif //TQT_NO_STRINGLIST
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant as a TQMap<TQString,TQVariant> if the variant has
+ type() Map; otherwise returns an empty map.
+
+ Note that if you want to iterate over the map, you should iterate
+ over a copy, e.g.
+ \code
+ TQMap<TQString, TQVariant> map = myVariant.toMap();
+ TQMap<TQString, TQVariant>::Iterator it = map.begin();
+ while( it != map.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asMap()
+*/
+const TQMap<TQString, TQVariant> TQVariant::toMap() const
+{
+ if ( d->typ != Map )
+ return TQMap<TQString,TQVariant>();
+
+ return *((TQMap<TQString,TQVariant>*)d->value.ptr);
+}
+#endif
+/*!
+ Returns the variant as a TQFont if the variant can be cast to Font;
+ otherwise returns the application's default font.
+
+ \sa asFont(), canCast()
+*/
+const TQFont TQVariant::toFont() const
+{
+ switch ( d->typ ) {
+ case CString:
+ case ByteArray:
+ case String:
+ {
+ TQFont fnt;
+ fnt.fromString( toString() );
+ return fnt;
+ }
+ case Font:
+ return *((TQFont*)d->value.ptr);
+ default:
+ return TQFont();
+ }
+}
+
+/*!
+ Returns the variant as a TQPixmap if the variant has type() Pixmap;
+ otherwise returns a null pixmap.
+
+ \sa asPixmap()
+*/
+const TQPixmap TQVariant::toPixmap() const
+{
+ if ( d->typ != Pixmap )
+ return TQPixmap();
+
+ return *((TQPixmap*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQImage if the variant has type() Image;
+ otherwise returns a null image.
+
+ \sa asImage()
+*/
+const TQImage TQVariant::toImage() const
+{
+ if ( d->typ != Image )
+ return TQImage();
+
+ return *((TQImage*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQBrush if the variant has type() Brush;
+ otherwise returns a default brush (with all black colors).
+
+ \sa asBrush()
+*/
+const TQBrush TQVariant::toBrush() const
+{
+ if( d->typ != Brush )
+ return TQBrush();
+
+ return *((TQBrush*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQPoint if the variant has type() Point;
+ otherwise returns a point (0, 0).
+
+ \sa asPoint()
+*/
+const TQPoint TQVariant::toPoint() const
+{
+ if ( d->typ != Point )
+ return TQPoint();
+
+ return *((TQPoint*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQRect if the variant has type() Rect;
+ otherwise returns an empty rectangle.
+
+ \sa asRect()
+*/
+const TQRect TQVariant::toRect() const
+{
+ if ( d->typ != Rect )
+ return TQRect();
+
+ return *((TQRect*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQSize if the variant has type() Size;
+ otherwise returns an invalid size.
+
+ \sa asSize()
+*/
+const TQSize TQVariant::toSize() const
+{
+ if ( d->typ != Size )
+ return TQSize();
+
+ return *((TQSize*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQColor if the variant can be cast to Color;
+ otherwise returns an invalid color.
+
+ \sa asColor(), canCast()
+*/
+const TQColor TQVariant::toColor() const
+{
+ switch ( d->typ ) {
+ case ByteArray:
+ case CString:
+ case String:
+ {
+ TQColor col;
+ col.setNamedColor( toString() );
+ return col;
+ }
+ case Color:
+ return *((TQColor*)d->value.ptr);
+ default:
+ return TQColor();
+ }
+}
+#ifndef TQT_NO_PALETTE
+/*!
+ Returns the variant as a TQPalette if the variant has type()
+ Palette; otherwise returns a completely black palette.
+
+ \sa asPalette()
+*/
+const TQPalette TQVariant::toPalette() const
+{
+ if ( d->typ != Palette )
+ return TQPalette();
+
+ return *((TQPalette*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQColorGroup if the variant has type()
+ ColorGroup; otherwise returns a completely black color group.
+
+ \sa asColorGroup()
+*/
+const TQColorGroup TQVariant::toColorGroup() const
+{
+ if ( d->typ != ColorGroup )
+ return TQColorGroup();
+
+ return *((TQColorGroup*)d->value.ptr);
+}
+#endif //TQT_NO_PALETTE
+#ifndef TQT_NO_ICONSET
+/*!
+ Returns the variant as a TQIconSet if the variant has type()
+ IconSet; otherwise returns an icon set of null pixmaps.
+
+ \sa asIconSet()
+*/
+const TQIconSet TQVariant::toIconSet() const
+{
+ if ( d->typ != IconSet )
+ return TQIconSet();
+
+ return *((TQIconSet*)d->value.ptr);
+}
+#endif //TQT_NO_ICONSET
+/*!
+ Returns the variant as a TQPointArray if the variant has type()
+ PointArray; otherwise returns an empty TQPointArray.
+
+ \sa asPointArray()
+*/
+const TQPointArray TQVariant::toPointArray() const
+{
+ if ( d->typ != PointArray )
+ return TQPointArray();
+
+ return *((TQPointArray*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQBitmap if the variant has type() Bitmap;
+ otherwise returns a null TQBitmap.
+
+ \sa asBitmap()
+*/
+const TQBitmap TQVariant::toBitmap() const
+{
+ if ( d->typ != Bitmap )
+ return TQBitmap();
+
+ return *((TQBitmap*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQRegion if the variant has type() Region;
+ otherwise returns an empty TQRegion.
+
+ \sa asRegion()
+*/
+const TQRegion TQVariant::toRegion() const
+{
+ if ( d->typ != Region )
+ return TQRegion();
+
+ return *((TQRegion*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQCursor if the variant has type() Cursor;
+ otherwise returns the default arrow cursor.
+
+ \sa asCursor()
+*/
+const TQCursor TQVariant::toCursor() const
+{
+#ifndef TQT_NO_CURSOR
+ if ( d->typ != Cursor )
+ return TQCursor();
+#endif
+
+ return *((TQCursor*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQDate if the variant can be cast to Date;
+ otherwise returns an invalid date.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ date will be returned if the string cannot be parsed as a
+ TQt::ISODate format date.
+
+ \sa asDate(), canCast()
+*/
+const TQDate TQVariant::toDate() const
+{
+ switch ( d->typ ) {
+ case Date:
+ return *((TQDate*)d->value.ptr);
+ case DateTime:
+ return ((TQDateTime*)d->value.ptr)->date();
+#ifndef TQT_NO_DATESTRING
+ case String:
+ return TQDate::fromString( *((TQString*)d->value.ptr), TQt::ISODate );
+ case CString:
+ case ByteArray:
+ return TQDate::fromString(toString(), TQt::ISODate);
+#endif
+ default:
+ return TQDate();
+ }
+}
+
+/*!
+ Returns the variant as a TQTime if the variant can be cast to Time;
+ otherwise returns an invalid date.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ time will be returned if the string cannot be parsed as a
+ TQt::ISODate format time.
+
+ \sa asTime()
+*/
+const TQTime TQVariant::toTime() const
+{
+ switch ( d->typ ) {
+ case Time:
+ return *((TQTime*)d->value.ptr);
+ case DateTime:
+ return ((TQDateTime*)d->value.ptr)->time();
+#ifndef TQT_NO_DATESTRING
+ case String:
+ return TQTime::fromString( *((TQString*)d->value.ptr), TQt::ISODate );
+ case CString:
+ case ByteArray:
+ return TQTime::fromString(toString(), TQt::ISODate);
+#endif
+ default:
+ return TQTime();
+ }
+}
+
+/*!
+ Returns the variant as a TQDateTime if the variant can be cast to
+ DateTime; otherwise returns an invalid TQDateTime.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ TQDateTime will be returned if the string cannot be parsed as a
+ TQt::ISODate format date/time.
+
+ \sa asDateTime()
+*/
+const TQDateTime TQVariant::toDateTime() const
+{
+ switch ( d->typ ) {
+ case DateTime:
+ return *((TQDateTime*)d->value.ptr);
+#ifndef TQT_NO_DATESTRING
+ case String:
+ return TQDateTime::fromString( *((TQString*)d->value.ptr), TQt::ISODate );
+ case CString:
+ case ByteArray:
+ return TQDateTime::fromString(toString(), TQt::ISODate);
+#endif
+ case Date:
+ return TQDateTime( *((TQDate*)d->value.ptr) );
+ default:
+ return TQDateTime();
+ }
+}
+
+/*!
+ Returns the variant as a TQByteArray if the variant can be cast to
+ a ByteArray; otherwise returns an empty bytearray.
+
+ \sa asByteArray(), canCast()
+*/
+const TQByteArray TQVariant::toByteArray() const
+{
+ switch(d->typ) {
+ case ByteArray: return *((TQByteArray*)d->value.ptr);
+ case CString: return *((TQByteArray*)d->value.ptr);
+ default: {
+ TQByteArray ret;
+ if (canCast(String)) {
+ TQString c = toString();
+ ret.duplicate(c.latin1(), c.length());
+ }
+ return ret;
+ }
+ }
+}
+
+/*!
+ Returns the variant as a TQBitArray if the variant has type()
+ BitArray; otherwise returns an empty bitarray.
+
+ \sa asBitArray()
+*/
+const TQBitArray TQVariant::toBitArray() const
+{
+ if ( d->typ == BitArray )
+ return *((TQBitArray*)d->value.ptr);
+ return TQBitArray();
+}
+
+#ifndef TQT_NO_ACCEL
+
+/*!
+ Returns the variant as a TQKeySequence if the variant can be cast
+ to a KeySequence; otherwise returns an empty key sequence.
+
+ \sa asKeySequence(), canCast()
+*/
+const TQKeySequence TQVariant::toKeySequence() const
+{
+ switch ( d->typ ) {
+ case KeySequence:
+ return *((TQKeySequence*)d->value.ptr);
+ case String:
+ case ByteArray:
+ case CString:
+ return TQKeySequence( toString() );
+ case Int:
+ case UInt:
+ case Double:
+ case ULongLong:
+ case LongLong:
+ return TQKeySequence( toInt() );
+ default:
+ return TQKeySequence();
+ }
+}
+
+#endif // TQT_NO_ACCEL
+
+/*!
+ Returns the variant as a TQPen if the variant has type()
+ Pen; otherwise returns an empty TQPen.
+
+ \sa asPen()
+*/
+const TQPen TQVariant::toPen() const
+{
+ if ( d->typ != Pen )
+ return TQPen();
+
+ return *((TQPen*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as an int if the variant can be cast to Int;
+ otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asInt(), canCast()
+*/
+int TQVariant::toInt( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( Int );
+
+ switch ( d->typ ) {
+ case String:
+ return ((TQString*)d->value.ptr)->toInt( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d->value.ptr)->toInt( ok );
+ case Int:
+ return d->value.i;
+ case UInt:
+ return (int)d->value.u;
+ case LongLong:
+ return (int)d->value.ll;
+ case ULongLong:
+ return (int)d->value.ull;
+ case Double:
+ return (int)d->value.d;
+ case Bool:
+ return (int)d->value.b;
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ return (int) *( (TQKeySequence*)d->value.ptr );
+#endif
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as an unsigned int if the variant can be cast
+ to UInt; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an unsigned int; otherwise \a *ok is set to FALSE.
+
+ \sa asUInt(), canCast()
+*/
+uint TQVariant::toUInt( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( UInt );
+
+ switch( d->typ ) {
+ case String:
+ return ((TQString*)d->value.ptr)->toUInt( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d->value.ptr)->toUInt( ok );
+ case Int:
+ return (uint)d->value.i;
+ case UInt:
+ return d->value.u;
+ case LongLong:
+ return (uint)d->value.ll;
+ case ULongLong:
+ return (uint)d->value.ull;
+ case Double:
+ return (uint)d->value.d;
+ case Bool:
+ return (uint)d->value.b;
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as a long long int if the variant can be cast
+ to LongLong; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asLongLong(), canCast()
+*/
+TQ_LLONG TQVariant::toLongLong( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( LongLong );
+
+ switch ( d->typ ) {
+ case String:
+ return ((TQString*)d->value.ptr)->toLongLong( ok );
+ case CString:
+ case ByteArray:
+ return TQString(*(TQCString*)d->value.ptr).toLongLong(ok);
+ case Int:
+ return (TQ_LLONG)d->value.i;
+ case UInt:
+ return (TQ_LLONG)d->value.u;
+ case LongLong:
+ return d->value.ll;
+ case ULongLong:
+ return (TQ_LLONG)d->value.ull;
+ case Double:
+ return (TQ_LLONG)d->value.d;
+ case Bool:
+ return (TQ_LLONG)d->value.b;
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as as an unsigned long long int if the variant
+ can be cast to ULongLong; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asULongLong(), canCast()
+*/
+TQ_ULLONG TQVariant::toULongLong( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( ULongLong );
+
+ switch ( d->typ ) {
+ case Int:
+ return (TQ_ULLONG)d->value.i;
+ case UInt:
+ return (TQ_ULLONG)d->value.u;
+ case LongLong:
+ return (TQ_ULLONG)d->value.ll;
+ case ULongLong:
+ return d->value.ull;
+ case Double:
+ return (TQ_ULLONG)d->value.d;
+ case Bool:
+ return (TQ_ULLONG)d->value.b;
+ case String:
+ return ((TQString*)d->value.ptr)->toULongLong( ok );
+ case CString:
+ case ByteArray:
+ return TQString(*(TQCString*)d->value.ptr).toULongLong(ok);
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as a bool if the variant can be cast to Bool;
+ otherWise returns FALSE.
+
+ Returns TRUE if the variant has a numeric type and its value is
+ non-zero, or if the variant has type String, ByteArray or CString
+ and its lower-case content is not empty, "0" or "false"; otherwise
+ returns FALSE.
+
+ \sa asBool(), canCast()
+*/
+bool TQVariant::toBool() const
+{
+ switch( d->typ ) {
+ case Bool:
+ return d->value.b;
+ case Double:
+ return d->value.d != 0.0;
+ case Int:
+ return d->value.i != 0;
+ case UInt:
+ return d->value.u != 0;
+ case LongLong:
+ return d->value.ll != 0;
+ case ULongLong:
+ return d->value.ull != 0;
+ case String:
+ case CString:
+ case ByteArray:
+ {
+ TQString str = toString().lower();
+ return !(str == "0" || str == "false" || str.isEmpty() );
+ }
+ default:
+ return FALSE;
+ }
+}
+
+/*!
+ Returns the variant as a double if the variant can be cast to
+ Double; otherwise returns 0.0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to a double; otherwise \a *ok is set to FALSE.
+
+ \sa asDouble(), canCast()
+*/
+double TQVariant::toDouble( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( Double );
+
+ switch ( d->typ ) {
+ case String:
+ return ((TQString*)d->value.ptr)->toDouble( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d->value.ptr)->toDouble( ok );
+ case Double:
+ return d->value.d;
+ case Int:
+ return (double)d->value.i;
+ case Bool:
+ return (double)d->value.b;
+ case UInt:
+ return (double)d->value.u;
+ case LongLong:
+ return (double)d->value.ll;
+ case ULongLong:
+#if defined(TQ_CC_MSVC) && !defined(TQ_CC_MSVC_NET)
+ return (double)(TQ_LLONG)d->value.ull;
+#else
+ return (double)d->value.ull;
+#endif
+ default:
+ return 0.0;
+ }
+}
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant as a TQValueList<TQVariant> if the variant has
+ type() List or StringList; otherwise returns an empty list.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQVariant> list = myVariant.toList();
+ TQValueList<TQVariant>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asList()
+*/
+const TQValueList<TQVariant> TQVariant::toList() const
+{
+ if ( d->typ == List )
+ return *((TQValueList<TQVariant>*)d->value.ptr);
+#ifndef TQT_NO_STRINGLIST
+ if ( d->typ == StringList ) {
+ TQValueList<TQVariant> lst;
+ TQStringList::ConstIterator it = stringListBegin();
+ TQStringList::ConstIterator end = stringListEnd();
+ for( ; it != end; ++it )
+ lst.append( TQVariant( *it ) );
+ return lst;
+ }
+#endif //TQT_NO_STRINGLIST
+ return TQValueList<TQVariant>();
+}
+#endif
+
+/*!
+ Returns the variant as a TQSizePolicy if the variant has type()
+ SizePolicy; otherwise returns an undefined (but legal) size
+ policy.
+*/
+
+TQSizePolicy TQVariant::toSizePolicy() const
+{
+ if ( d->typ == SizePolicy )
+ return *((TQSizePolicy*)d->value.ptr);
+
+ return TQSizePolicy();
+}
+
+
+#define TQ_VARIANT_AS( f ) TQ##f& TQVariant::as##f() \
+{ \
+ bool b = isNull(); \
+ if ( d->typ != f ) \
+ *this = TQVariant( to##f() ); \
+ else \
+ detach(); \
+ d->is_null = b; \
+ return *((TQ##f*)d->value.ptr); \
+}
+
+TQ_VARIANT_AS(String)
+TQ_VARIANT_AS(CString)
+#ifndef TQT_NO_STRINGLIST
+TQ_VARIANT_AS(StringList)
+#endif
+TQ_VARIANT_AS(Font)
+TQ_VARIANT_AS(Pixmap)
+TQ_VARIANT_AS(Image)
+TQ_VARIANT_AS(Brush)
+TQ_VARIANT_AS(Point)
+TQ_VARIANT_AS(Rect)
+TQ_VARIANT_AS(Size)
+TQ_VARIANT_AS(Color)
+#ifndef TQT_NO_PALETTE
+TQ_VARIANT_AS(Palette)
+TQ_VARIANT_AS(ColorGroup)
+#endif
+#ifndef TQT_NO_ICONSET
+TQ_VARIANT_AS(IconSet)
+#endif
+TQ_VARIANT_AS(PointArray)
+TQ_VARIANT_AS(Bitmap)
+TQ_VARIANT_AS(Region)
+TQ_VARIANT_AS(Cursor)
+TQ_VARIANT_AS(SizePolicy)
+TQ_VARIANT_AS(Date)
+TQ_VARIANT_AS(Time)
+TQ_VARIANT_AS(DateTime)
+TQ_VARIANT_AS(ByteArray)
+TQ_VARIANT_AS(BitArray)
+#ifndef TQT_NO_ACCEL
+TQ_VARIANT_AS(KeySequence)
+#endif
+TQ_VARIANT_AS(Pen)
+
+/*!
+ \fn TQString& TQVariant::asString()
+
+ Tries to convert the variant to hold a string value. If that is
+ not possible the variant is set to an empty string.
+
+ Returns a reference to the stored string.
+
+ \sa toString()
+*/
+
+/*!
+ \fn TQCString& TQVariant::asCString()
+
+ Tries to convert the variant to hold a string value. If that is
+ not possible the variant is set to an empty string.
+
+ Returns a reference to the stored string.
+
+ \sa toCString()
+*/
+
+/*!
+ \fn TQStringList& TQVariant::asStringList()
+
+ Tries to convert the variant to hold a TQStringList value. If that
+ is not possible the variant is set to an empty string list.
+
+ Returns a reference to the stored string list.
+
+ Note that if you want to iterate over the list, you should
+ iterate over a copy, e.g.
+ \code
+ TQStringList list = myVariant.asStringList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa toStringList()
+*/
+
+/*!
+ \fn TQFont& TQVariant::asFont()
+
+ Tries to convert the variant to hold a TQFont. If that is not
+ possible the variant is set to the application's default font.
+
+ Returns a reference to the stored font.
+
+ \sa toFont()
+*/
+
+/*!
+ \fn TQPixmap& TQVariant::asPixmap()
+
+ Tries to convert the variant to hold a pixmap value. If that is
+ not possible the variant is set to a null pixmap.
+
+ Returns a reference to the stored pixmap.
+
+ \sa toPixmap()
+*/
+
+/*!
+ \fn TQImage& TQVariant::asImage()
+
+ Tries to convert the variant to hold an image value. If that is
+ not possible the variant is set to a null image.
+
+ Returns a reference to the stored image.
+
+ \sa toImage()
+*/
+
+/*!
+ \fn TQBrush& TQVariant::asBrush()
+
+ Tries to convert the variant to hold a brush value. If that is not
+ possible the variant is set to a default black brush.
+
+ Returns a reference to the stored brush.
+
+ \sa toBrush()
+*/
+
+/*!
+ \fn TQPoint& TQVariant::asPoint()
+
+ Tries to convert the variant to hold a point value. If that is not
+ possible the variant is set to a (0, 0) point.
+
+ Returns a reference to the stored point.
+
+ \sa toPoint()
+*/
+
+/*!
+ \fn TQRect& TQVariant::asRect()
+
+ Tries to convert the variant to hold a rectangle value. If that is
+ not possible the variant is set to an empty rectangle.
+
+ Returns a reference to the stored rectangle.
+
+ \sa toRect()
+*/
+
+/*!
+ \fn TQSize& TQVariant::asSize()
+
+ Tries to convert the variant to hold a TQSize value. If that is not
+ possible the variant is set to an invalid size.
+
+ Returns a reference to the stored size.
+
+ \sa toSize() TQSize::isValid()
+*/
+
+/*!
+ \fn TQSizePolicy& TQVariant::asSizePolicy()
+
+ Tries to convert the variant to hold a TQSizePolicy value. If that
+ fails, the variant is set to an arbitrary (valid) size policy.
+*/
+
+
+/*!
+ \fn TQColor& TQVariant::asColor()
+
+ Tries to convert the variant to hold a TQColor value. If that is
+ not possible the variant is set to an invalid color.
+
+ Returns a reference to the stored color.
+
+ \sa toColor() TQColor::isValid()
+*/
+
+/*!
+ \fn TQPalette& TQVariant::asPalette()
+
+ Tries to convert the variant to hold a TQPalette value. If that is
+ not possible the variant is set to a palette of black colors.
+
+ Returns a reference to the stored palette.
+
+ \sa toString()
+*/
+
+/*!
+ \fn TQColorGroup& TQVariant::asColorGroup()
+
+ Tries to convert the variant to hold a TQColorGroup value. If that
+ is not possible the variant is set to a color group of all black
+ colors.
+
+ Returns a reference to the stored color group.
+
+ \sa toColorGroup()
+*/
+
+/*!
+ \fn TQIconSet& TQVariant::asIconSet()
+
+ Tries to convert the variant to hold a TQIconSet value. If that is
+ not possible the variant is set to an empty iconset.
+
+ Returns a reference to the stored iconset.
+
+ \sa toIconSet()
+*/
+
+/*!
+ \fn TQPointArray& TQVariant::asPointArray()
+
+ Tries to convert the variant to hold a TQPointArray value. If that
+ is not possible the variant is set to an empty point array.
+
+ Returns a reference to the stored point array.
+
+ \sa toPointArray()
+*/
+
+/*!
+ \fn TQBitmap& TQVariant::asBitmap()
+
+ Tries to convert the variant to hold a bitmap value. If that is
+ not possible the variant is set to a null bitmap.
+
+ Returns a reference to the stored bitmap.
+
+ \sa toBitmap()
+*/
+
+/*!
+ \fn TQRegion& TQVariant::asRegion()
+
+ Tries to convert the variant to hold a TQRegion value. If that is
+ not possible the variant is set to a null region.
+
+ Returns a reference to the stored region.
+
+ \sa toRegion()
+*/
+
+/*!
+ \fn TQCursor& TQVariant::asCursor()
+
+ Tries to convert the variant to hold a TQCursor value. If that is
+ not possible the variant is set to a default arrow cursor.
+
+ Returns a reference to the stored cursor.
+
+ \sa toCursor()
+*/
+
+/*!
+ \fn TQDate& TQVariant::asDate()
+
+ Tries to convert the variant to hold a TQDate value. If that is not
+ possible then the variant is set to an invalid date.
+
+ Returns a reference to the stored date.
+
+ \sa toDate()
+*/
+
+/*!
+ \fn TQTime& TQVariant::asTime()
+
+ Tries to convert the variant to hold a TQTime value. If that is not
+ possible then the variant is set to an invalid time.
+
+ Returns a reference to the stored time.
+
+ \sa toTime()
+*/
+
+/*!
+ \fn TQDateTime& TQVariant::asDateTime()
+
+ Tries to convert the variant to hold a TQDateTime value. If that is
+ not possible then the variant is set to an invalid date/time.
+
+ Returns a reference to the stored date/time.
+
+ \sa toDateTime()
+*/
+
+/*!
+ \fn TQByteArray& TQVariant::asByteArray()
+
+ Tries to convert the variant to hold a TQByteArray value. If that
+ is not possible then the variant is set to an empty bytearray.
+
+ Returns a reference to the stored bytearray.
+
+ \sa toByteArray()
+*/
+
+/*!
+ \fn TQBitArray& TQVariant::asBitArray()
+
+ Tries to convert the variant to hold a TQBitArray value. If that is
+ not possible then the variant is set to an empty bitarray.
+
+ Returns a reference to the stored bitarray.
+
+ \sa toBitArray()
+*/
+
+/*!
+ \fn TQKeySequence& TQVariant::asKeySequence()
+
+ Tries to convert the variant to hold a TQKeySequence value. If that
+ is not possible then the variant is set to an empty key sequence.
+
+ Returns a reference to the stored key sequence.
+
+ \sa toKeySequence()
+*/
+
+/*! \fn TQPen& TQVariant::asPen()
+
+ Tries to convert the variant to hold a TQPen value. If that
+ is not possible then the variant is set to an empty pen.
+
+ Returns a reference to the stored pen.
+
+ \sa toPen()
+*/
+
+/*!
+ Returns the variant's value as int reference.
+*/
+int& TQVariant::asInt()
+{
+ detach();
+ if ( d->typ != Int ) {
+ int i = toInt();
+ bool b = isNull();
+ d->clear();
+ d->value.i = i;
+ d->typ = Int;
+ d->is_null = b;
+ }
+ return d->value.i;
+}
+
+/*!
+ Returns the variant's value as unsigned int reference.
+*/
+uint& TQVariant::asUInt()
+{
+ detach();
+ if ( d->typ != UInt ) {
+ uint u = toUInt();
+ bool b = isNull();
+ d->clear();
+ d->value.u = u;
+ d->typ = UInt;
+ d->is_null = b;
+ }
+ return d->value.u;
+}
+
+/*!
+ Returns the variant's value as long long reference.
+*/
+TQ_LLONG& TQVariant::asLongLong()
+{
+ detach();
+ if ( d->typ != LongLong ) {
+ TQ_LLONG ll = toLongLong();
+ bool b = isNull();
+ d->clear();
+ d->value.ll = ll;
+ d->typ = LongLong;
+ d->is_null = b;
+ }
+ return d->value.ll;
+}
+
+/*!
+ Returns the variant's value as unsigned long long reference.
+*/
+TQ_ULLONG& TQVariant::asULongLong()
+{
+ detach();
+ if ( d->typ != ULongLong ) {
+ TQ_ULLONG ull = toULongLong();
+ bool b = isNull();
+ d->clear();
+ d->value.ull = ull;
+ d->typ = ULongLong;
+ d->is_null = b;
+ }
+ return d->value.ull;
+}
+
+/*!
+ Returns the variant's value as bool reference.
+*/
+bool& TQVariant::asBool()
+{
+ detach();
+ if ( d->typ != Bool ) {
+ bool b = toBool();
+ bool nb = isNull();
+ d->clear();
+ d->value.b = b;
+ d->typ = Bool;
+ d->is_null = nb;
+ }
+ return d->value.b;
+}
+
+/*!
+ Returns the variant's value as double reference.
+*/
+double& TQVariant::asDouble()
+{
+ detach();
+ if ( d->typ != Double ) {
+ double dbl = toDouble();
+ bool b = isNull();
+ d->clear();
+ d->value.d = dbl;
+ d->typ = Double;
+ d->is_null = b;
+ }
+ return d->value.d;
+}
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant's value as variant list reference.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQVariant> list = myVariant.asList();
+ TQValueList<TQVariant>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQValueList<TQVariant>& TQVariant::asList()
+{
+ bool b = isNull();
+ if ( d->typ != List )
+ *this = TQVariant( toList() );
+ else
+ detach();
+ d->is_null = b;
+ return *((TQValueList<TQVariant>*)d->value.ptr);
+}
+
+/*!
+ Returns the variant's value as variant map reference.
+
+ Note that if you want to iterate over the map, you should iterate
+ over a copy, e.g.
+ \code
+ TQMap<TQString, TQVariant> map = myVariant.asMap();
+ TQMap<TQString, TQVariant>::Iterator it = map.begin();
+ while( it != map.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQMap<TQString, TQVariant>& TQVariant::asMap()
+{
+ bool b = isNull();
+ if ( d->typ != Map )
+ *this = TQVariant( toMap() );
+ else
+ detach();
+ d->is_null = b;
+ return *((TQMap<TQString,TQVariant>*)d->value.ptr);
+}
+#endif
+
+/*!
+ Returns TRUE if the variant's type can be cast to the requested
+ type, \a t. Such casting is done automatically when calling the
+ toInt(), toBool(), ... or asInt(), asBool(), ... methods.
+
+ The following casts are done automatically:
+ \table
+ \header \i Type \i Automatically Cast To
+ \row \i Bool \i Double, Int, UInt, LongLong, ULongLong, String, CString, ByteArray
+ \row \i Color \i String. CString. ByteArray
+ \row \i Date \i String, CString, ByteArray, DateTime
+ \row \i DateTime \i String, CString, ByteArray, Date, Time
+ \row \i Double \i String, CString, ByteArray, Int, Bool, UInt, LongLong, ULongLong
+ \row \i Font \i String, CString, ByteArray
+ \row \i Int \i String, CString, ByteArray, Double, Bool, UInt, LongLong, ULongLong, KeySequence
+ \row \i LongLong \i String, CString, ByteArray, Double, Bool, UInt, LongLong, ULongLong, KeySequence
+ \row \i ULongLong \i String, CString, ByteArray, Double, Bool, UInt, LongLong, ULongLong, KeySequence
+ \row \i List \i StringList (if the list tqcontains only strings or
+ something that can be cast to a string)
+ \row \i String \i CString, ByteArray, CString, Int, UInt, Bool, Double, Date,
+ Time, DateTime, KeySequence, Font, Color
+ \row \i CString \i String, ByteArray, Int, UInt, Bool, Double, Date, ULongLong, LongLong
+ \row \i ByteArray \i String, CString, Int, UInt, Bool, Double, Date, ULongLong, LongLong
+ \row \i StringList \i List
+ \row \i Time \i String
+ \row \i Int \i String, CString, ByteArray, Double, Bool, UInt, LongLong, ULongLong, KeySequence
+ \row \i KeySequence \i String, CString, ByteArray, Int, UInt, LongLong, ULongLong
+ \endtable
+*/
+bool TQVariant::canCast( Type t ) const
+{
+ if ( Type( d->typ ) == t )
+ return TRUE;
+
+ switch ( t ) {
+ case Bool:
+ case Double:
+ if (d->typ == KeySequence)
+ break;
+ case Int:
+ case UInt:
+ case LongLong:
+ case ULongLong:
+ switch(d->typ) {
+ case Bool:
+ case ByteArray:
+ case CString:
+ case Double:
+ case Int:
+ case KeySequence:
+ case LongLong:
+ case String:
+ case UInt:
+ case ULongLong:
+ return TRUE;
+ default: break;
+ }
+ break;
+
+ case CString:
+ case ByteArray:
+ case String:
+ switch(d->typ) {
+ case Bool:
+ case ByteArray:
+ case CString:
+ case Color:
+ case Date:
+ case DateTime:
+ case Double:
+ case Font:
+ case Int:
+ case KeySequence:
+ case LongLong:
+ case String:
+ case Time:
+ case UInt:
+ case ULongLong:
+ return TRUE;
+ default: break;
+ }
+ break;
+
+ case Time:
+ if (d->typ == Date)
+ break;
+ case Date:
+ case DateTime:
+ switch(d->typ) {
+ case ByteArray:
+ case CString:
+ case Date:
+ case DateTime:
+ case String:
+ return TRUE;
+ default: break;
+ }
+ break;
+
+ case KeySequence:
+ switch(d->typ) {
+ case ByteArray:
+ case CString:
+ case Int:
+ case UInt:
+ case LongLong:
+ case ULongLong:
+ case Double:
+ case String:
+ return TRUE;
+ default: break;
+ }
+ break;
+
+ case Font:
+ case Color:
+ switch(d->typ) {
+ case ByteArray:
+ case CString:
+ case String:
+ return TRUE;
+ default: break;
+ }
+ break;
+
+#ifndef TQT_NO_STRINGLIST
+ case List:
+ return d->typ == StringList;
+#endif
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case StringList:
+ if ( d->typ == List ) {
+ TQValueList<TQVariant>::ConstIterator it = listBegin();
+ TQValueList<TQVariant>::ConstIterator end = listEnd();
+ for( ; it != end; ++it ) {
+ if ( !(*it).canCast( String ) )
+ return FALSE;
+ }
+ return TRUE;
+ }
+#endif
+ case Invalid:
+ case Map:
+ case Pixmap:
+ case Brush:
+ case Rect:
+ case Size:
+ case Palette:
+ case ColorGroup:
+ case IconSet:
+ case Point:
+ case Image:
+ case PointArray:
+ case Region:
+ case Bitmap:
+ case Cursor:
+ case SizePolicy:
+ case BitArray:
+ case Pen:
+ break;
+ }
+ return FALSE;
+}
+
+/*!
+ Casts the variant to the requested type. If the cast cannot be
+ done, the variant is set to the default value of the requested
+ type (e.g. an empty string if the requested type \a t is
+ TQVariant::String, an empty point array if the requested type \a t
+ is TQVariant::PointArray, etc). Returns TRUE if the current type of
+ the variant was successfully cast; otherwise returns FALSE.
+
+ \sa canCast()
+*/
+
+bool TQVariant::cast( Type t )
+{
+ switch ( t ) {
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case TQVariant::Map:
+ asMap();
+ break;
+ case TQVariant::List:
+ asList();
+ break;
+#endif
+ case TQVariant::String:
+ asString();
+ break;
+#ifndef TQT_NO_STRINGLIST
+ case TQVariant::StringList:
+ asStringList();
+ break;
+#endif
+ case TQVariant::Font:
+ asFont();
+ break;
+ case TQVariant::Pixmap:
+ asPixmap();
+ break;
+ case TQVariant::Brush:
+ asBrush();
+ break;
+ case TQVariant::Rect:
+ asRect();
+ break;
+ case TQVariant::Size:
+ asSize();
+ break;
+ case TQVariant::Color:
+ asColor();
+ break;
+#ifndef TQT_NO_PALETTE
+ case TQVariant::Palette:
+ asPalette();
+ break;
+ case TQVariant::ColorGroup:
+ asColorGroup();
+ break;
+#endif
+#ifndef TQT_NO_ICONSET
+ case TQVariant::IconSet:
+ asIconSet();
+ break;
+#endif
+ case TQVariant::Point:
+ asPoint();
+ break;
+ case TQVariant::Image:
+ asImage();
+ break;
+ case TQVariant::Int:
+ asInt();
+ break;
+ case TQVariant::UInt:
+ asUInt();
+ break;
+ case TQVariant::Bool:
+ asBool();
+ break;
+ case TQVariant::Double:
+ asDouble();
+ break;
+ case TQVariant::CString:
+ asCString();
+ break;
+ case TQVariant::PointArray:
+ asPointArray();
+ break;
+ case TQVariant::Region:
+ asRegion();
+ break;
+ case TQVariant::Bitmap:
+ asBitmap();
+ break;
+ case TQVariant::Cursor:
+ asCursor();
+ break;
+ case TQVariant::SizePolicy:
+ asSizePolicy();
+ break;
+ case TQVariant::Date:
+ asDate();
+ break;
+ case TQVariant::Time:
+ asTime();
+ break;
+ case TQVariant::DateTime:
+ asDateTime();
+ break;
+ case TQVariant::ByteArray:
+ asByteArray();
+ break;
+ case TQVariant::BitArray:
+ asBitArray();
+ break;
+#ifndef TQT_NO_ACCEL
+ case TQVariant::KeySequence:
+ asKeySequence();
+ break;
+#endif
+ case TQVariant::Pen:
+ asPen();
+ break;
+ case TQVariant::LongLong:
+ asLongLong();
+ break;
+ case TQVariant::ULongLong:
+ asULongLong();
+ break;
+ default:
+ case TQVariant::Invalid:
+ (*this) = TQVariant();
+ }
+ return canCast( t );
+}
+
+/*!
+ Compares this TQVariant with \a v and returns TRUE if they are
+ equal; otherwise returns FALSE.
+*/
+
+bool TQVariant::operator==( const TQVariant &v ) const
+{
+ if (isNumeric(v.type()) && canCast(v.type())) {
+ bool ok;
+ switch(v.type()) {
+ case Bool:
+ return toBool() == v.toBool();
+ case Int:
+ {
+ int val = toInt(&ok);
+ return (ok && val == v.toInt());
+ }
+ case UInt:
+ {
+ uint val = toUInt(&ok);
+ return (ok && val == v.toUInt());
+ }
+
+ case Double:
+ {
+ double val = toDouble(&ok);
+ return (ok && val == v.toDouble());
+ }
+
+ case LongLong:
+ {
+ TQ_LLONG val = toLongLong(&ok);
+ return (ok && val == v.toLongLong());
+ }
+
+ case ULongLong:
+ {
+ TQ_ULLONG val = toULongLong(&ok);
+ return (ok && val == v.toULongLong());
+ }
+
+ default:
+ TQ_ASSERT(FALSE);
+ }
+ }
+
+ if (!v.canCast(d->typ)) {
+ return FALSE;
+ }
+
+ switch( d->typ ) {
+ case Cursor:
+#ifndef TQT_NO_CURSOR
+ return v.toCursor().tqshape() == toCursor().tqshape();
+#endif
+ case Bitmap:
+ return v.toBitmap().serialNumber() == toBitmap().serialNumber();
+ case PointArray:
+ return v.toPointArray() == toPointArray();
+ case Region:
+ return v.toRegion() == toRegion();
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case List:
+ return v.toList() == toList();
+ case Map: {
+ if ( v.toMap().count() != toMap().count() )
+ return FALSE;
+ TQMap<TQString, TQVariant>::ConstIterator it = v.toMap().begin();
+ TQMap<TQString, TQVariant>::ConstIterator it2 = toMap().begin();
+ while ( it != v.toMap().end() ) {
+ if ( *it != *it2 )
+ return FALSE;
+ ++it;
+ ++it2;
+ }
+ return TRUE;
+ }
+#endif
+ case String:
+ return v.toString() == toString();
+ case CString:
+ return v.toCString() == toCString();
+#ifndef TQT_NO_STRINGLIST
+ case StringList:
+ return v.toStringList() == toStringList();
+#endif
+ case Font:
+ return v.toFont() == toFont();
+ case Pixmap:
+ return v.toPixmap().serialNumber() == toPixmap().serialNumber();
+ case Image:
+ return v.toImage() == toImage();
+ case Brush:
+ return v.toBrush() == toBrush();
+ case Point:
+ return v.toPoint() == toPoint();
+ case Rect:
+ return v.toRect() == toRect();
+ case Size:
+ return v.toSize() == toSize();
+ case Color:
+ return v.toColor() == toColor();
+#ifndef TQT_NO_PALETTE
+ case Palette:
+ return v.toPalette() == toPalette();
+ case ColorGroup:
+ return v.toColorGroup() == toColorGroup();
+#endif
+#ifndef TQT_NO_ICONSET
+ case IconSet:
+ return v.toIconSet().pixmap().serialNumber()
+ == toIconSet().pixmap().serialNumber();
+#endif
+ case Int:
+ return v.toInt() == toInt();
+ case UInt:
+ return v.toUInt() == toUInt();
+ case LongLong:
+ return v.toLongLong() == toLongLong();
+ case ULongLong:
+ return v.toULongLong() == toULongLong();
+ case Bool:
+ return v.toBool() == toBool();
+ case Double:
+ return v.toDouble() == toDouble();
+ case SizePolicy:
+ return v.toSizePolicy() == toSizePolicy();
+ case Date:
+ return v.toDate() == toDate();
+ case Time:
+ return v.toTime() == toTime();
+ case DateTime:
+ return v.toDateTime() == toDateTime();
+ case ByteArray:
+ return v.toByteArray() == toByteArray();
+ case BitArray:
+ return v.toBitArray() == toBitArray();
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ return v.toKeySequence() == toKeySequence();
+#endif
+ case Pen:
+ return v.toPen() == toPen();
+ case Invalid:
+ break;
+ }
+ return FALSE;
+}
+
+/*!
+ Compares this TQVariant with \a v and returns TRUE if they are not
+ equal; otherwise returns FALSE.
+*/
+
+bool TQVariant::operator!=( const TQVariant &v ) const
+{
+ return !( v == *this );
+}
+
+
+/*! \internal
+
+ Reads or sets the variant type and ptr
+ */
+void* TQVariant::rawAccess( void* ptr, Type typ, bool deepCopy )
+{
+ if ( ptr ) {
+ clear();
+ d->typ = typ;
+ d->value.ptr = ptr;
+ d->is_null = FALSE;
+ if ( deepCopy ) {
+ TQVariant::Private* p = new Private( d );
+ d->typ = Invalid;
+ delete d;
+ d = p;
+ }
+ }
+
+ if ( !deepCopy )
+ return d->value.ptr;
+ TQVariant::Private* p = new Private( d );
+ void *ret = (void*)p->value.ptr;
+ p->typ = Invalid;
+ delete p;
+ return ret;
+}
+
+/*!
+ Returns TRUE if this is a NULL variant, FALSE otherwise.
+*/
+bool TQVariant::isNull() const
+{
+ switch( d->typ )
+ {
+ case TQVariant::Bitmap:
+ return ((TQBitmap*) d->value.ptr)->isNull();
+ case TQVariant::Region:
+ return ((TQRegion*) d->value.ptr)->isNull();
+ case TQVariant::PointArray:
+ return ((TQPointArray*) d->value.ptr)->isNull();
+ case TQVariant::String:
+ return ((TQString*) d->value.ptr)->isNull();
+ case TQVariant::CString:
+ return ((TQCString*) d->value.ptr)->isNull();
+ case TQVariant::Pixmap:
+ return ((TQPixmap*) d->value.ptr)->isNull();
+ case TQVariant::Image:
+ return ((TQImage*) d->value.ptr)->isNull();
+ case TQVariant::Point:
+ return ((TQPoint*) d->value.ptr)->isNull();
+ case TQVariant::Rect:
+ return ((TQRect*) d->value.ptr)->isNull();
+ case TQVariant::Size:
+ return ((TQSize*) d->value.ptr)->isNull();
+#ifndef TQT_NO_ICONSET
+ case TQVariant::IconSet:
+ return ((TQIconSet*) d->value.ptr)->isNull();
+#endif
+ case TQVariant::Date:
+ return ((TQDate*) d->value.ptr)->isNull();
+ case TQVariant::Time:
+ return ((TQTime*) d->value.ptr)->isNull();
+ case TQVariant::DateTime:
+ return ((TQDateTime*) d->value.ptr)->isNull();
+ case TQVariant::ByteArray:
+ return ((TQByteArray*) d->value.ptr)->isNull();
+ case TQVariant::BitArray:
+ return ((TQBitArray*) d->value.ptr)->isNull();
+ case TQVariant::Cursor:
+#ifndef TQT_NO_STRINGLIST
+ case TQVariant::StringList:
+#endif //TQT_NO_STRINGLIST
+ case TQVariant::Font:
+ case TQVariant::Brush:
+ case TQVariant::Color:
+#ifndef TQT_NO_PALETTE
+ case TQVariant::Palette:
+ case TQVariant::ColorGroup:
+#endif
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case TQVariant::Map:
+ case TQVariant::List:
+#endif
+ case TQVariant::SizePolicy:
+#ifndef TQT_NO_ACCEL
+ case TQVariant::KeySequence:
+#endif
+ case TQVariant::Pen:
+ case TQVariant::Invalid:
+ case TQVariant::Int:
+ case TQVariant::UInt:
+ case TQVariant::LongLong:
+ case TQVariant::ULongLong:
+ case TQVariant::Bool:
+ case TQVariant::Double:
+ break;
+ }
+ return d->is_null;
+}
+#endif //TQT_NO_VARIANT
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqvariant.cpp.new b/tqtinterface/qt4/src/kernel/tqvariant.cpp.new
new file mode 100644
index 0000000..22c05b3
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqvariant.cpp.new
@@ -0,0 +1,4858 @@
+/****************************************************************************
+**
+** Implementation of TQVariant class
+**
+** Created : 990414
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <float.h>
+
+#include "tqvariant.h"
+#ifndef TQT_NO_VARIANT
+#include "tqstring.h"
+#include "tqcstring.h"
+#include "tqfont.h"
+#include "tqpixmap.h"
+#include "tqimage.h"
+#include "tqbrush.h"
+#include "tqpoint.h"
+#include "tqrect.h"
+#include "tqsize.h"
+#include "tqcolor.h"
+#include "tqpalette.h"
+#include "tqiconset.h"
+#include "tqdatastream.h"
+#include "tqregion.h"
+#include "tqpointarray.h"
+#include "tqbitmap.h"
+#include "tqcursor.h"
+#include "tqdatetime.h"
+#include "tqsizepolicy.h"
+#include "tqshared.h"
+#include "tqbitarray.h"
+#include "tqkeysequence.h"
+#include "tqpen.h"
+
+#ifdef USE_QT4
+
+#define IconSet Icon
+#define CString ByteArray
+#define PointArray Polygon
+#define ColorGroup 63
+
+/*!
+ Constructs a copy of the variant, \a p, passed as the argument to
+ this constructor. Usually this is a deep copy, but a shallow copy
+ is made if the stored data type is explicitly shared, as e.g.
+ TQImage is.
+*/
+TQVariant::TQVariant( const TQVariant& p )
+ : QVariant(p)
+{
+// p.d.ref();
+ d = p.d;
+}
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ Reads the variant from the data stream, \a s.
+*/
+TQVariant::TQVariant( TQDataStream& s )
+{
+ s >> *this;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*!
+ Constructs a new variant with a string value, \a val.
+*/
+TQVariant::TQVariant( const TQString& val )
+{
+ d.type = String;
+ d.data.ptr = new TQString( val );
+}
+
+/*!
+ Constructs a new variant with a C-string value, \a val.
+
+ If you want to modify the TQCString after you've passed it to this
+ constructor, we recommend passing a deep copy (see
+ TQCString::copy()).
+*/
+TQVariant::TQVariant( const TQCString& val )
+{
+ d.type = CString;
+ d.data.ptr = new TQCString( val );
+}
+
+/*!
+ Constructs a new variant with a C-string value of \a val if \a val
+ is non-null. The variant creates a deep copy of \a val.
+
+ If \a val is null, the resulting variant has type Invalid.
+*/
+TQVariant::TQVariant( const char* val )
+{
+ if ( val == 0 )
+ return;
+ d.type = CString;
+ d.data.ptr = new TQCString( val );
+}
+
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Constructs a new variant with a string list value, \a val.
+*/
+TQVariant::TQVariant( const TQStringList& val )
+{
+ d.type = StringList;
+ d.data.ptr = new TQStringList( val );
+ d.is_null = FALSE;
+}
+#endif // TQT_NO_STRINGLIST
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Constructs a new variant with a map of TQVariants, \a val.
+*/
+TQVariant::TQVariant( const TQMap<TQString,TQVariant>& val )
+{
+ d.type = Map;
+ d.data.ptr = new TQMap<TQString,TQVariant>( val );
+ d.is_null = FALSE;
+}
+#endif
+/*!
+ Constructs a new variant with a font value, \a val.
+*/
+TQVariant::TQVariant( const TQFont& val )
+{
+ d.type = Font;
+ d.data.ptr = new TQFont( val );
+ d.is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a pixmap value, \a val.
+*/
+TQVariant::TQVariant( const TQPixmap& val )
+{
+ d.type = Pixmap;
+ d.data.ptr = new TQPixmap( val );
+}
+
+
+/*!
+ Constructs a new variant with an image value, \a val.
+
+ Because TQImage is explicitly shared, you may need to pass a deep
+ copy to the variant using TQImage::copy(), e.g. if you intend
+ changing the image you've passed later on.
+*/
+TQVariant::TQVariant( const TQImage& val )
+{
+ d.type = Image;
+ d.data.ptr = new TQImage( val );
+}
+
+/*!
+ Constructs a new variant with a brush value, \a val.
+*/
+TQVariant::TQVariant( const TQBrush& val )
+{
+ d.type = Brush;
+ d.data.ptr = new TQBrush( val );
+ d.is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a point value, \a val.
+*/
+TQVariant::TQVariant( const TQPoint& val )
+{
+ d.type = Point;
+ d.data.ptr = new TQPoint( val );
+}
+
+/*!
+ Constructs a new variant with a rect value, \a val.
+*/
+TQVariant::TQVariant( const TQRect& val )
+{
+ d.type = Rect;
+ d.data.ptr = new TQRect( val );
+}
+
+/*!
+ Constructs a new variant with a size value, \a val.
+*/
+TQVariant::TQVariant( const TQSize& val )
+{
+ d.type = Size;
+ d.data.ptr = new TQSize( val );
+}
+
+/*!
+ Constructs a new variant with a color value, \a val.
+*/
+TQVariant::TQVariant( const TQColor& val )
+{
+ d.type = Color;
+ d.data.ptr = new TQColor( val );
+ d.is_null = FALSE;
+}
+
+#ifndef TQT_NO_PALETTE
+/*!
+ Constructs a new variant with a color palette value, \a val.
+*/
+TQVariant::TQVariant( const TQPalette& val )
+{
+ d.type = Palette;
+ d.data.ptr = new TQPalette( val );
+ d.is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a color group value, \a val.
+*/
+TQVariant::TQVariant( const TQColorGroup& val )
+{
+ d.type = ColorGroup;
+ d.data.ptr = new TQColorGroup( val );
+ d.is_null = FALSE;
+}
+#endif //TQT_NO_PALETTE
+#ifndef TQT_NO_ICONSET
+/*!
+ Constructs a new variant with an icon set value, \a val.
+*/
+TQVariant::TQVariant( const TQIconSet& val )
+{
+ d.type = IconSet;
+ d.data.ptr = new TQIconSet( val );
+}
+#endif //TQT_NO_ICONSET
+/*!
+ Constructs a new variant with a region value, \a val.
+*/
+TQVariant::TQVariant( const TQRegion& val )
+{
+ d.type = Region;
+ // ## Force a detach
+ d.data.ptr = new TQRegion( val );
+ ((TQRegion*)d.data.ptr)->translate( 0, 0 );
+}
+
+/*!
+ Constructs a new variant with a bitmap value, \a val.
+*/
+TQVariant::TQVariant( const TQBitmap& val )
+{
+ d.type = Bitmap;
+ d.data.ptr = new TQBitmap( val );
+}
+
+/*!
+ Constructs a new variant with a cursor value, \a val.
+*/
+TQVariant::TQVariant( const TQCursor& val )
+{
+ d.type = Cursor;
+ d.data.ptr = new TQCursor( val );
+ d.is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a point array value, \a val.
+
+ Because TQPointArray is explicitly shared, you may need to pass a
+ deep copy to the variant using TQPointArray::copy(), e.g. if you
+ intend changing the point array you've passed later on.
+*/
+TQVariant::TQVariant( const TQPointArray& val )
+{
+ d.type = PointArray;
+ d.data.ptr = new TQPointArray( val );
+}
+
+/*!
+ Constructs a new variant with a date value, \a val.
+*/
+TQVariant::TQVariant( const TQDate& val )
+{
+ d.type = Date;
+ d.data.ptr = new TQDate( val );
+}
+
+/*!
+ Constructs a new variant with a time value, \a val.
+*/
+TQVariant::TQVariant( const TQTime& val )
+{
+ d.type = Time;
+ d.data.ptr = new TQTime( val );
+}
+
+/*!
+ Constructs a new variant with a date/time value, \a val.
+*/
+TQVariant::TQVariant( const TQDateTime& val )
+{
+ d.type = DateTime;
+ d.data.ptr = new TQDateTime( val );
+}
+
+/*!
+ Constructs a new variant with a bytearray value, \a val.
+*/
+TQVariant::TQVariant( const TQByteArray& val )
+{
+ d.type = ByteArray;
+ d.data.ptr = new TQByteArray( val );
+}
+
+/*!
+ Constructs a new variant with a bitarray value, \a val.
+*/
+TQVariant::TQVariant( const TQBitArray& val )
+{
+ d.type = BitArray;
+ d.data.ptr = new TQBitArray( val );
+}
+
+#ifndef TQT_NO_ACCEL
+
+/*!
+ Constructs a new variant with a key sequence value, \a val.
+*/
+TQVariant::TQVariant( const TQKeySequence& val )
+{
+ d.type = KeySequence;
+ d.data.ptr = new TQKeySequence( val );
+ d.is_null = FALSE;
+}
+
+#endif
+
+/*!
+ Constructs a new variant with a pen value, \a val.
+*/
+TQVariant::TQVariant( const TQPen& val )
+{
+ d.type = Pen;
+ d.data.ptr = new TQPen( val );
+}
+
+#if 0
+
+/*!
+ Constructs a new variant with an integer value, \a val.
+*/
+TQVariant::TQVariant( int val )
+{
+ d = new Private;
+ d->typ = Int;
+ d->value.i = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with an unsigned integer value, \a val.
+*/
+TQVariant::TQVariant( uint val )
+{
+ d = new Private;
+ d->typ = UInt;
+ d->value.u = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a long long integer value, \a val.
+*/
+TQVariant::TQVariant( TQ_LLONG val )
+{
+ d = new Private;
+ d->typ = LongLong;
+ d->value.ll = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with an unsigned long long integer value, \a val.
+*/
+
+TQVariant::TQVariant( TQ_ULLONG val )
+{
+ d = new Private;
+ d->typ = ULongLong;
+ d->value.ull = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a boolean value, \a val. The integer
+ argument is a dummy, necessary for compatibility with some
+ compilers.
+*/
+TQVariant::TQVariant( bool val, int )
+{ // this is the comment that does NOT name said compiler.
+ d = new Private;
+ d->typ = Bool;
+ d->value.b = val;
+ d->is_null = FALSE;
+}
+
+
+/*!
+ Constructs a new variant with a floating point value, \a val.
+*/
+TQVariant::TQVariant( double val )
+{
+ d = new Private;
+ d->typ = Double;
+ d->value.d = val;
+ d->is_null = FALSE;
+}
+
+#endif
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Constructs a new variant with a list value, \a val.
+*/
+TQVariant::TQVariant( const TQValueList<TQVariant>& val )
+{
+ d.type = List;
+ d.data.ptr = new TQValueList<TQVariant>( val );
+ d.is_null = FALSE;
+}
+#endif
+
+/*!
+ Constructs a new variant with a size policy value, \a val.
+*/
+TQVariant::TQVariant( TQSizePolicy val )
+{
+// d = new Private;
+ d.type = SizePolicy;
+// d.value.ptr = new TQSizePolicy( val );
+ d.data.ptr = new TQSizePolicy( val );
+ d.is_null = FALSE;
+}
+
+/*!
+ Assigns the value of the variant \a variant to this variant.
+
+ This is a deep copy of the variant, but note that if the variant
+ holds an explicitly shared type such as TQImage, a shallow copy is
+ performed.
+*/
+// TQVariant& TQVariant::operator= ( const TQVariant& variant )
+// {
+// TQVariant& other = (TQVariant&)variant;
+//
+// other.d->ref();
+// if ( d->deref() )
+// delete d;
+//
+// d = other.d;
+//
+// return *this;
+// }
+
+/*!
+ Returns the variant as a TQFont if the variant can be cast to Font;
+ otherwise returns the application's default font.
+
+ \sa asFont(), canCast()
+*/
+const TQFont TQVariant::toFont() const
+{
+ switch ( type() ) {
+// case CString:
+ case ByteArray:
+ case String:
+ {
+ TQFont fnt;
+ fnt.fromString( toString() );
+ return fnt;
+ }
+ case Font:
+ return *((TQFont*)d.data.ptr);
+ default:
+ return TQFont();
+ }
+}
+
+#define TQ_VARIANT_AS( f ) TQ##f& TQVariant::as##f() \
+{ \
+ bool b = isNull(); \
+ if ( d.type != f ) \
+ *this = TQVariant( to##f() ); \
+ else \
+ detach(); \
+ d.is_null = b; \
+ return *((TQ##f*)d.data.ptr); \
+}
+
+TQ_VARIANT_AS(String)
+TQ_VARIANT_AS(CString)
+#ifndef TQT_NO_STRINGLIST
+TQ_VARIANT_AS(StringList)
+#endif
+TQ_VARIANT_AS(Font)
+TQ_VARIANT_AS(Pixmap)
+TQ_VARIANT_AS(Image)
+TQ_VARIANT_AS(Brush)
+TQ_VARIANT_AS(Point)
+TQ_VARIANT_AS(Rect)
+TQ_VARIANT_AS(Size)
+TQ_VARIANT_AS(Color)
+#ifndef TQT_NO_PALETTE
+TQ_VARIANT_AS(Palette)
+TQ_VARIANT_AS(ColorGroup)
+#endif
+#ifndef TQT_NO_ICONSET
+TQ_VARIANT_AS(IconSet)
+#endif
+TQ_VARIANT_AS(PointArray)
+TQ_VARIANT_AS(Bitmap)
+TQ_VARIANT_AS(Region)
+TQ_VARIANT_AS(Cursor)
+TQ_VARIANT_AS(SizePolicy)
+TQ_VARIANT_AS(Date)
+TQ_VARIANT_AS(Time)
+TQ_VARIANT_AS(DateTime)
+TQ_VARIANT_AS(ByteArray)
+TQ_VARIANT_AS(BitArray)
+#ifndef TQT_NO_ACCEL
+TQ_VARIANT_AS(KeySequence)
+#endif
+TQ_VARIANT_AS(Pen)
+
+// #if 0
+
+/*!
+ Returns the variant's value as int reference.
+*/
+int& TQVariant::asInt()
+{
+ detach();
+ if ( d.type != Int ) {
+ int i = toInt();
+ bool b = isNull();
+// d.clear();
+ d.data.i = i;
+ d.type = Int;
+ d.is_null = b;
+ }
+ return d.data.i;
+}
+
+/*!
+ Returns the variant's value as unsigned int reference.
+*/
+uint& TQVariant::asUInt()
+{
+ detach();
+ if ( d.type != UInt ) {
+ uint u = toUInt();
+ bool b = isNull();
+// d.clear();
+ d.data.u = u;
+ d.type = UInt;
+ d.is_null = b;
+ }
+ return d.data.u;
+}
+
+/*!
+ Returns the variant's value as long long reference.
+*/
+TQ_LLONG& TQVariant::asLongLong()
+{
+ detach();
+ if ( d.type != LongLong ) {
+ TQ_LLONG ll = toLongLong();
+ bool b = isNull();
+// d.clear();
+ d.data.ll = ll;
+ d.type = LongLong;
+ d.is_null = b;
+ }
+ return d.data.ll;
+}
+
+/*!
+ Returns the variant's value as unsigned long long reference.
+*/
+TQ_ULLONG& TQVariant::asULongLong()
+{
+ detach();
+ if ( d.type != ULongLong ) {
+ TQ_ULLONG ull = toULongLong();
+ bool b = isNull();
+// d.clear();
+ d.data.ull = ull;
+ d.type = ULongLong;
+ d.is_null = b;
+ }
+ return d.data.ull;
+}
+
+/*!
+ Returns the variant's value as bool reference.
+*/
+bool& TQVariant::asBool()
+{
+ detach();
+ if ( d.type != Bool ) {
+ bool b = toBool();
+ bool nb = isNull();
+// d.clear();
+ d.data.b = b;
+ d.type = Bool;
+ d.is_null = nb;
+ }
+ return d.data.b;
+}
+
+/*!
+ Returns the variant's value as double reference.
+*/
+double& TQVariant::asDouble()
+{
+ detach();
+ if ( d.type != Double ) {
+ double dbl = toDouble();
+ bool b = isNull();
+// d.clear();
+ d.data.d = dbl;
+ d.type = Double;
+ d.is_null = b;
+ }
+ return d.data.d;
+}
+
+// #endif
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant's value as variant list reference.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQVariant> list = myVariant.asList();
+ TQValueList<TQVariant>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQValueList<TQVariant>& TQVariant::asList()
+{
+ bool b = isNull();
+ if ( d.type != List )
+ *this = TQVariant( toList() );
+ else
+ detach();
+ d.is_null = b;
+ return *((TQValueList<TQVariant>*)d.data.ptr);
+}
+
+/*!
+ Returns the variant's value as variant map reference.
+
+ Note that if you want to iterate over the map, you should iterate
+ over a copy, e.g.
+ \code
+ TQMap<TQString, TQVariant> map = myVariant.asMap();
+ TQMap<TQString, TQVariant>::Iterator it = map.begin();
+ while( it != map.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQMap<TQString, TQVariant>& TQVariant::asMap()
+{
+ bool b = isNull();
+ if ( d.type != Map )
+ *this = TQVariant( toMap() );
+ else
+ detach();
+ d.is_null = b;
+ return *((TQMap<TQString,TQVariant>*)d.data.ptr);
+}
+#endif
+
+/*!
+ Returns the variant as a TQString if the variant can be cast to
+ String, otherwise returns TQString::null.
+
+ \sa asString(), canCast()
+*/
+const TQString TQVariant::toString() const
+{
+ return TQT_TQSTRING_OBJECT(QVariant::toString());
+}
+/*!
+ Returns the variant as a TQCString if the variant can be cast to a
+ CString; otherwise returns 0.
+
+ \sa asCString(), canCast()
+*/
+const TQCString TQVariant::toCString() const
+{
+ switch( d.type ) {
+ case CString: return *((TQCString*)d.data.ptr);
+ case String: return ((TQString*)d.data.ptr)->latin1();
+ default: {
+ if (!canCast(String))
+ return 0;
+ TQString c = toString();
+ return TQCString(c.latin1());
+ }
+ }
+}
+
+
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Returns the variant as a TQStringList if the variant has type()
+ StringList or List of a type that can be converted to TQString;
+ otherwise returns an empty list.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myVariant.toStringList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asStringList()
+*/
+const TQStringList TQVariant::toStringList() const
+{
+ switch ( d.type ) {
+ case StringList:
+ return *((TQStringList*)d.data.ptr);
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case List:
+ {
+ TQStringList lst;
+ TQValueList<TQVariant>::ConstIterator it = listBegin();
+ TQValueList<TQVariant>::ConstIterator end = listEnd();
+ while( it != end ) {
+ TQString tmp = (*it).toString();
+ ++it;
+ lst.append( tmp );
+ }
+ return lst;
+ }
+#endif
+ default:
+ return TQStringList();
+ }
+}
+#endif //TQT_NO_STRINGLIST
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant as a TQMap<TQString,TQVariant> if the variant has
+ type() Map; otherwise returns an empty map.
+
+ Note that if you want to iterate over the map, you should iterate
+ over a copy, e.g.
+ \code
+ TQMap<TQString, TQVariant> map = myVariant.toMap();
+ TQMap<TQString, TQVariant>::Iterator it = map.begin();
+ while( it != map.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asMap()
+*/
+const TQMap<TQString, TQVariant> TQVariant::toMap() const
+{
+ if ( d.type != Map )
+ return TQMap<TQString,TQVariant>();
+
+ return *((TQMap<TQString,TQVariant>*)d.data.ptr);
+}
+#endif
+
+/*!
+ Returns the variant as a TQPixmap if the variant has type() Pixmap;
+ otherwise returns a null pixmap.
+
+ \sa asPixmap()
+*/
+const TQPixmap TQVariant::toPixmap() const
+{
+ if ( d.type != Pixmap )
+ return TQPixmap();
+
+ return *((TQPixmap*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQImage if the variant has type() Image;
+ otherwise returns a null image.
+
+ \sa asImage()
+*/
+const TQImage TQVariant::toImage() const
+{
+ if ( d.type != Image )
+ return TQImage();
+
+ return *((TQImage*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQBrush if the variant has type() Brush;
+ otherwise returns a default brush (with all black colors).
+
+ \sa asBrush()
+*/
+const TQBrush TQVariant::toBrush() const
+{
+ if( d.type != Brush )
+ return TQBrush();
+
+ return *((TQBrush*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQPoint if the variant has type() Point;
+ otherwise returns a point (0, 0).
+
+ \sa asPoint()
+*/
+const TQPoint TQVariant::toPoint() const
+{
+ return QVariant::toPoint();
+}
+
+/*!
+ Returns the variant as a TQRect if the variant has type() Rect;
+ otherwise returns an empty rectangle.
+
+ \sa asRect()
+*/
+const TQRect TQVariant::toRect() const
+{
+ if ( d.type != Rect )
+ return TQRect();
+
+ return *((TQRect*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQSize if the variant has type() Size;
+ otherwise returns an invalid size.
+
+ \sa asSize()
+*/
+const TQSize TQVariant::toSize() const
+{
+ return QVariant::toSize();
+}
+
+/*!
+ Returns the variant as a TQColor if the variant can be cast to Color;
+ otherwise returns an invalid color.
+
+ \sa asColor(), canCast()
+*/
+const TQColor TQVariant::toColor() const
+{
+ switch ( d.type ) {
+ case ByteArray:
+// case CString:
+ case String:
+ {
+ TQColor col;
+ col.setNamedColor( toString() );
+ return col;
+ }
+ case Color:
+ return *((TQColor*)d.data.ptr);
+ default:
+ return TQColor();
+ }
+}
+#ifndef TQT_NO_PALETTE
+/*!
+ Returns the variant as a TQPalette if the variant has type()
+ Palette; otherwise returns a completely black palette.
+
+ \sa asPalette()
+*/
+const TQPalette TQVariant::toPalette() const
+{
+ if ( d.type != Palette )
+ return TQPalette();
+
+ return *((TQPalette*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQColorGroup if the variant has type()
+ ColorGroup; otherwise returns a completely black color group.
+
+ \sa asColorGroup()
+*/
+const TQColorGroup TQVariant::toColorGroup() const
+{
+ if ( d.type != ColorGroup )
+ return TQColorGroup();
+
+ return *((TQColorGroup*)d.data.ptr);
+}
+#endif //TQT_NO_PALETTE
+#ifndef TQT_NO_ICONSET
+/*!
+ Returns the variant as a TQIconSet if the variant has type()
+ IconSet; otherwise returns an icon set of null pixmaps.
+
+ \sa asIconSet()
+*/
+const TQIconSet TQVariant::toIconSet() const
+{
+ if ( d.type != IconSet )
+ return TQIconSet();
+
+ return *((TQIconSet*)d.data.ptr);
+}
+#endif //TQT_NO_ICONSET
+/*!
+ Returns the variant as a TQPointArray if the variant has type()
+ PointArray; otherwise returns an empty TQPointArray.
+
+ \sa asPointArray()
+*/
+const TQPointArray TQVariant::toPointArray() const
+{
+ if ( d.type != PointArray )
+ return TQPointArray();
+
+ return *((TQPointArray*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQBitmap if the variant has type() Bitmap;
+ otherwise returns a null TQBitmap.
+
+ \sa asBitmap()
+*/
+const TQBitmap TQVariant::toBitmap() const
+{
+ if ( d.type != Bitmap )
+ return TQBitmap();
+
+ return *((TQBitmap*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQRegion if the variant has type() Region;
+ otherwise returns an empty TQRegion.
+
+ \sa asRegion()
+*/
+const TQRegion TQVariant::toRegion() const
+{
+ if ( d.type != Region )
+ return TQRegion();
+
+ return *((TQRegion*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQCursor if the variant has type() Cursor;
+ otherwise returns the default arrow cursor.
+
+ \sa asCursor()
+*/
+const TQCursor TQVariant::toCursor() const
+{
+#ifndef TQT_NO_CURSOR
+ if ( d.type != Cursor )
+ return TQCursor();
+#endif
+
+ return *((TQCursor*)d.data.ptr);
+}
+
+/*!
+ Returns the variant as a TQDate if the variant can be cast to Date;
+ otherwise returns an invalid date.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ date will be returned if the string cannot be parsed as a
+ Qt::ISODate format date.
+
+ \sa asDate(), canCast()
+*/
+const TQDate TQVariant::toDate() const
+{
+ return TQT_TQDATE_OBJECT(QVariant::toDate());
+}
+
+/*!
+ Returns the variant as a TQTime if the variant can be cast to Time;
+ otherwise returns an invalid date.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ time will be returned if the string cannot be parsed as a
+ Qt::ISODate format time.
+
+ \sa asTime()
+*/
+const TQTime TQVariant::toTime() const
+{
+ return TQT_TQTIME_OBJECT(QVariant::toTime());
+}
+
+/*!
+ Returns the variant as a TQDateTime if the variant can be cast to
+ DateTime; otherwise returns an invalid TQDateTime.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ TQDateTime will be returned if the string cannot be parsed as a
+ Qt::ISODate format date/time.
+
+ \sa asDateTime()
+*/
+const TQDateTime TQVariant::toDateTime() const
+{
+ return TQT_TQDATETIME_OBJECT(QVariant::toDateTime());
+}
+
+/*!
+ Returns the variant as a TQByteArray if the variant can be cast to
+ a ByteArray; otherwise returns an empty bytearray.
+
+ \sa asByteArray(), canCast()
+*/
+const TQByteArray TQVariant::toByteArray() const
+{
+ return TQT_TQBYTEARRAY_OBJECT(QVariant::toByteArray());
+}
+
+/*!
+ Returns the variant as a TQBitArray if the variant has type()
+ BitArray; otherwise returns an empty bitarray.
+
+ \sa asBitArray()
+*/
+const TQBitArray TQVariant::toBitArray() const
+{
+ return QVariant::toBitArray();
+}
+
+#ifndef TQT_NO_ACCEL
+
+/*!
+ Returns the variant as a TQKeySequence if the variant can be cast
+ to a KeySequence; otherwise returns an empty key sequence.
+
+ \sa asKeySequence(), canCast()
+*/
+const TQKeySequence TQVariant::toKeySequence() const
+{
+ switch ( d.type ) {
+ case KeySequence:
+ return *((TQKeySequence*)d.data.ptr);
+ case String:
+ case ByteArray:
+// case CString:
+ return TQKeySequence( toString() );
+ case Int:
+ case UInt:
+ case Double:
+ case ULongLong:
+ case LongLong:
+ return TQKeySequence( toInt() );
+ default:
+ return TQKeySequence();
+ }
+}
+
+#endif // TQT_NO_ACCEL
+
+/*!
+ Returns the variant as a TQPen if the variant has type()
+ Pen; otherwise returns an empty TQPen.
+
+ \sa asPen()
+*/
+const TQPen TQVariant::toPen() const
+{
+ if ( d.type != Pen )
+ return TQPen();
+
+ return *((TQPen*)d.data.ptr);
+}
+
+#if 0
+
+/*!
+ Returns the variant as an int if the variant can be cast to Int;
+ otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asInt(), canCast()
+*/
+int TQVariant::toInt( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( Int );
+
+ switch ( d.type ) {
+ case String:
+ return ((TQString*)d.data.ptr)->toInt( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d.data.ptr)->toInt( ok );
+ case Int:
+ return d.data.i;
+ case UInt:
+ return (int)d.data.u;
+ case LongLong:
+ return (int)d.data.ll;
+ case ULongLong:
+ return (int)d.data.ull;
+ case Double:
+ return (int)d.data.d;
+ case Bool:
+ return (int)d.data.b;
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ return (int) *( (TQKeySequence*)d.data.ptr );
+#endif
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as an unsigned int if the variant can be cast
+ to UInt; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an unsigned int; otherwise \a *ok is set to FALSE.
+
+ \sa asUInt(), canCast()
+*/
+uint TQVariant::toUInt( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( UInt );
+
+ switch( d.type ) {
+ case String:
+ return ((TQString*)d.data.ptr)->toUInt( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d.data.ptr)->toUInt( ok );
+ case Int:
+ return (uint)d.data.i;
+ case UInt:
+ return d.data.u;
+ case LongLong:
+ return (uint)d.data.ll;
+ case ULongLong:
+ return (uint)d.data.ull;
+ case Double:
+ return (uint)d.data.d;
+ case Bool:
+ return (uint)d.data.b;
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as a long long int if the variant can be cast
+ to LongLong; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asLongLong(), canCast()
+*/
+TQ_LLONG TQVariant::toLongLong( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( LongLong );
+
+ switch ( d.type ) {
+ case String:
+ return ((TQString*)d.data.ptr)->toLongLong( ok );
+ case CString:
+ case ByteArray:
+ return TQString(*(TQCString*)d.data.ptr).toLongLong(ok);
+ case Int:
+ return (TQ_LLONG)d.data.i;
+ case UInt:
+ return (TQ_LLONG)d.data.u;
+ case LongLong:
+ return d.data.ll;
+ case ULongLong:
+ return (TQ_LLONG)d.data.ull;
+ case Double:
+ return (TQ_LLONG)d.data.d;
+ case Bool:
+ return (TQ_LLONG)d.data.b;
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as as an unsigned long long int if the variant
+ can be cast to ULongLong; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asULongLong(), canCast()
+*/
+TQ_ULLONG TQVariant::toULongLong( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( ULongLong );
+
+ switch ( d.type ) {
+ case Int:
+ return (TQ_ULLONG)d.data.i;
+ case UInt:
+ return (TQ_ULLONG)d.data.u;
+ case LongLong:
+ return (TQ_ULLONG)d.data.ll;
+ case ULongLong:
+ return d.data.ull;
+ case Double:
+ return (TQ_ULLONG)d.data.d;
+ case Bool:
+ return (TQ_ULLONG)d.data.b;
+ case String:
+ return ((TQString*)d.data.ptr)->toULongLong( ok );
+ case CString:
+ case ByteArray:
+ return TQString(*(TQCString*)d.data.ptr).toULongLong(ok);
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as a bool if the variant can be cast to Bool;
+ otherWise returns FALSE.
+
+ Returns TRUE if the variant has a numeric type and its value is
+ non-zero, or if the variant has type String, ByteArray or CString
+ and its lower-case content is not empty, "0" or "false"; otherwise
+ returns FALSE.
+
+ \sa asBool(), canCast()
+*/
+bool TQVariant::toBool() const
+{
+ switch( d.type ) {
+ case Bool:
+ return d.data.b;
+ case Double:
+ return d.data.d != 0.0;
+ case Int:
+ return d.data.i != 0;
+ case UInt:
+ return d.data.u != 0;
+ case LongLong:
+ return d.data.ll != 0;
+ case ULongLong:
+ return d.data.ull != 0;
+ case String:
+ case CString:
+ case ByteArray:
+ {
+ TQString str = toString().lower();
+ return !(str == "0" || str == "false" || str.isEmpty() );
+ }
+ default:
+ return FALSE;
+ }
+}
+
+/*!
+ Returns the variant as a double if the variant can be cast to
+ Double; otherwise returns 0.0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to a double; otherwise \a *ok is set to FALSE.
+
+ \sa asDouble(), canCast()
+*/
+double TQVariant::toDouble( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( Double );
+
+ switch ( d.type ) {
+ case String:
+ return ((TQString*)d.data.ptr)->toDouble( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d.data.ptr)->toDouble( ok );
+ case Double:
+ return d.data.d;
+ case Int:
+ return (double)d.data.i;
+ case Bool:
+ return (double)d.data.b;
+ case UInt:
+ return (double)d.data.u;
+ case LongLong:
+ return (double)d.data.ll;
+ case ULongLong:
+#if defined(TQ_CC_MSVC) && !defined(TQ_CC_MSVC_NET)
+ return (double)(TQ_LLONG)d.data.ull;
+#else
+ return (double)d.data.ull;
+#endif
+ default:
+ return 0.0;
+ }
+}
+
+#endif
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant as a TQValueList<TQVariant> if the variant has
+ type() List or StringList; otherwise returns an empty list.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQVariant> list = myVariant.toList();
+ TQValueList<TQVariant>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asList()
+*/
+const TQValueList<TQVariant> TQVariant::toList() const
+{
+ if ( d.type == List )
+ return *((TQValueList<TQVariant>*)d.data.ptr);
+#ifndef TQT_NO_STRINGLIST
+ if ( d.type == StringList ) {
+ TQValueList<TQVariant> lst;
+ TQStringList::ConstIterator it = stringListBegin();
+ TQStringList::ConstIterator end = stringListEnd();
+ for( ; it != end; ++it )
+ lst.append( TQVariant( *it ) );
+ return lst;
+ }
+#endif //TQT_NO_STRINGLIST
+ return TQValueList<TQVariant>();
+}
+#endif
+
+/*!
+ Returns the variant as a TQSizePolicy if the variant has type()
+ SizePolicy; otherwise returns an undefined (but legal) size
+ policy.
+*/
+
+TQSizePolicy TQVariant::toSizePolicy() const
+{
+ if ( d.type == SizePolicy )
+ return *((TQSizePolicy*)d.data.ptr);
+
+ return TQSizePolicy();
+}
+
+#else // USE_QT4
+
+#ifndef DBL_DIG
+#define DBL_DIG 10
+#endif //DBL_DIG
+
+// Uncomment to test for memory leaks or to run qt/test/qvariant/main.cpp
+// #define TQVARIANT_DEBUG
+
+
+static bool isNumeric(TQVariant::Type type)
+{
+ return (type == TQVariant::Int || type == TQVariant::UInt
+ || type == TQVariant::Double || type == TQVariant::LongLong
+ || type == TQVariant::ULongLong || type == TQVariant::Bool);
+}
+
+
+#ifdef TQVARIANT_DEBUG
+int qv_count = 0;
+int get_qv_count() { return qv_count; }
+#endif
+
+TQVariant::Private::Private()
+{
+#ifdef TQVARIANT_DEBUG
+ qv_count++;
+#endif
+ typ = TQVariant::Invalid;
+ is_null = TRUE;
+}
+
+TQVariant::Private::Private( Private* d )
+{
+#ifdef TQVARIANT_DEBUG
+ qv_count++;
+#endif
+
+ switch( d->typ )
+ {
+ case TQVariant::Invalid:
+ break;
+ case TQVariant::Bitmap:
+ value.ptr = new TQBitmap( *((TQBitmap*)d->value.ptr) );
+ break;
+ case TQVariant::Region:
+ value.ptr = new TQRegion( *((TQRegion*)d->value.ptr) );
+ // ## Force a detach
+ // ((TQRegion*)value.ptr)->translate( 0, 0 );
+ break;
+ case TQVariant::PointArray:
+ // TQPointArray is explicit shared
+ value.ptr = new TQPointArray( *((TQPointArray*)d->value.ptr) );
+ break;
+ case TQVariant::String:
+ value.ptr = new TQString( *((TQString*)d->value.ptr) );
+ break;
+ case TQVariant::CString:
+ // TQCString is explicit shared
+ value.ptr = new TQCString( *((TQCString*)d->value.ptr) );
+ break;
+#ifndef TQT_NO_STRINGLIST
+ case TQVariant::StringList:
+ value.ptr = new TQStringList( *((TQStringList*)d->value.ptr) );
+ break;
+#endif //TQT_NO_STRINGLIST
+ case TQVariant::Font:
+ value.ptr = new TQFont( *((TQFont*)d->value.ptr) );
+ break;
+ case TQVariant::Pixmap:
+ value.ptr = new TQPixmap( *((TQPixmap*)d->value.ptr) );
+ break;
+ case TQVariant::Image:
+ // TQImage is explicit shared
+ value.ptr = new TQImage( *((TQImage*)d->value.ptr) );
+ break;
+ case TQVariant::Brush:
+ value.ptr = new TQBrush( *((TQBrush*)d->value.ptr) );
+ // ## Force a detach
+ // ((TQBrush*)value.ptr)->setColor( ((TQBrush*)value.ptr)->color() );
+ break;
+ case TQVariant::Point:
+ value.ptr = new TQPoint( *((TQPoint*)d->value.ptr) );
+ break;
+ case TQVariant::Rect:
+ value.ptr = new TQRect( *((TQRect*)d->value.ptr) );
+ break;
+ case TQVariant::Size:
+ value.ptr = new TQSize( *((TQSize*)d->value.ptr) );
+ break;
+ case TQVariant::Color:
+ value.ptr = new TQColor( *((TQColor*)d->value.ptr) );
+ break;
+#ifndef TQT_NO_PALETTE
+ case TQVariant::Palette:
+ value.ptr = new TQPalette( *((TQPalette*)d->value.ptr) );
+ break;
+ case TQVariant::ColorGroup:
+ value.ptr = new TQColorGroup( *((TQColorGroup*)d->value.ptr) );
+ break;
+#endif
+#ifndef TQT_NO_ICONSET
+ case TQVariant::IconSet:
+ value.ptr = new TQIconSet( *((TQIconSet*)d->value.ptr) );
+ break;
+#endif
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case TQVariant::Map:
+ value.ptr = new TQMap<TQString,TQVariant>( *((TQMap<TQString,TQVariant>*)d->value.ptr) );
+ break;
+ case TQVariant::List:
+ value.ptr = new TQValueList<TQVariant>( *((TQValueList<TQVariant>*)d->value.ptr) );
+ break;
+#endif
+ case TQVariant::Date:
+ value.ptr = new TQDate( *((TQDate*)d->value.ptr) );
+ break;
+ case TQVariant::Time:
+ value.ptr = new TQTime( *((TQTime*)d->value.ptr) );
+ break;
+ case TQVariant::DateTime:
+ value.ptr = new TQDateTime( *((TQDateTime*)d->value.ptr) );
+ break;
+ case TQVariant::ByteArray:
+ value.ptr = new TQByteArray( *((TQByteArray*)d->value.ptr) );
+ break;
+ case TQVariant::BitArray:
+ value.ptr = new TQBitArray( *((TQBitArray*)d->value.ptr) );
+ break;
+#ifndef TQT_NO_ACCEL
+ case TQVariant::KeySequence:
+ value.ptr = new TQKeySequence( *((TQKeySequence*)d->value.ptr) );
+ break;
+#endif
+ case TQVariant::Pen:
+ value.ptr = new TQPen( *((TQPen*)d->value.ptr) );
+ break;
+ case TQVariant::Int:
+ value.i = d->value.i;
+ break;
+ case TQVariant::UInt:
+ value.u = d->value.u;
+ break;
+ case TQVariant::LongLong:
+ value.ll = d->value.ll;
+ break;
+ case TQVariant::ULongLong:
+ value.ull = d->value.ull;
+ break;
+ case TQVariant::Bool:
+ value.b = d->value.b;
+ break;
+ case TQVariant::Double:
+ value.d = d->value.d;
+ break;
+ case TQVariant::SizePolicy:
+ value.ptr = new TQSizePolicy( *((TQSizePolicy*)d->value.ptr) );
+ break;
+ case TQVariant::Cursor:
+ value.ptr = new TQCursor( *((TQCursor*)d->value.ptr) );
+ break;
+ default:
+ TQ_ASSERT( 0 );
+ }
+
+ typ = d->typ;
+ is_null = d->is_null;
+}
+
+TQVariant::Private::~Private()
+{
+#ifdef TQVARIANT_DEBUG
+ qv_count--;
+#endif
+ clear();
+}
+
+void TQVariant::Private::clear()
+{
+ switch( typ )
+ {
+ case TQVariant::Bitmap:
+ delete (TQBitmap*)value.ptr;
+ break;
+ case TQVariant::Cursor:
+ delete (TQCursor*)value.ptr;
+ break;
+ case TQVariant::Region:
+ delete (TQRegion*)value.ptr;
+ break;
+ case TQVariant::PointArray:
+ delete (TQPointArray*)value.ptr;
+ break;
+ case TQVariant::String:
+ delete (TQString*)value.ptr;
+ break;
+ case TQVariant::CString:
+ delete (TQCString*)value.ptr;
+ break;
+#ifndef TQT_NO_STRINGLIST
+ case TQVariant::StringList:
+ delete (TQStringList*)value.ptr;
+ break;
+#endif //TQT_NO_STRINGLIST
+ case TQVariant::Font:
+ delete (TQFont*)value.ptr;
+ break;
+ case TQVariant::Pixmap:
+ delete (TQPixmap*)value.ptr;
+ break;
+ case TQVariant::Image:
+ delete (TQImage*)value.ptr;
+ break;
+ case TQVariant::Brush:
+ delete (TQBrush*)value.ptr;
+ break;
+ case TQVariant::Point:
+ delete (TQPoint*)value.ptr;
+ break;
+ case TQVariant::Rect:
+ delete (TQRect*)value.ptr;
+ break;
+ case TQVariant::Size:
+ delete (TQSize*)value.ptr;
+ break;
+ case TQVariant::Color:
+ delete (TQColor*)value.ptr;
+ break;
+#ifndef TQT_NO_PALETTE
+ case TQVariant::Palette:
+ delete (TQPalette*)value.ptr;
+ break;
+ case TQVariant::ColorGroup:
+ delete (TQColorGroup*)value.ptr;
+ break;
+#endif
+#ifndef TQT_NO_ICONSET
+ case TQVariant::IconSet:
+ delete (TQIconSet*)value.ptr;
+ break;
+#endif
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case TQVariant::Map:
+ delete (TQMap<TQString,TQVariant>*)value.ptr;
+ break;
+ case TQVariant::List:
+ delete (TQValueList<TQVariant>*)value.ptr;
+ break;
+#endif
+ case TQVariant::SizePolicy:
+ delete (TQSizePolicy*)value.ptr;
+ break;
+ case TQVariant::Date:
+ delete (TQDate*)value.ptr;
+ break;
+ case TQVariant::Time:
+ delete (TQTime*)value.ptr;
+ break;
+ case TQVariant::DateTime:
+ delete (TQDateTime*)value.ptr;
+ break;
+ case TQVariant::ByteArray:
+ delete (TQByteArray*)value.ptr;
+ break;
+ case TQVariant::BitArray:
+ delete (TQBitArray*)value.ptr;
+ break;
+#ifndef TQT_NO_ACCEL
+ case TQVariant::KeySequence:
+ delete (TQKeySequence*)value.ptr;
+ break;
+#endif
+ case TQVariant::Pen:
+ delete (TQPen*)value.ptr;
+ break;
+ case TQVariant::Invalid:
+ case TQVariant::Int:
+ case TQVariant::UInt:
+ case TQVariant::LongLong:
+ case TQVariant::ULongLong:
+ case TQVariant::Bool:
+ case TQVariant::Double:
+ break;
+ }
+
+ typ = TQVariant::Invalid;
+ is_null = TRUE;
+}
+
+/*!
+ \class TQVariant tqvariant.h
+ \brief The TQVariant class acts like a union for the most common TQt data types.
+
+ \ingroup objectmodel
+ \ingroup misc
+ \mainclass
+
+ Because C++ forbids unions from including types that have
+ non-default constructors or destructors, most interesting TQt
+ classes cannot be used in unions. Without TQVariant, this would be
+ a problem for TQObject::property() and for database work, etc.
+
+ A TQVariant object holds a single value of a single type() at a
+ time. (Some type()s are multi-valued, for example a string list.)
+ You can tqfind out what type, T, the variant holds, convert it to a
+ different type using one of the asT() functions, e.g. asSize(),
+ get its value using one of the toT() functions, e.g. toSize(), and
+ check whether the type can be converted to a particular type using
+ canCast().
+
+ The methods named toT() (for any supported T, see the \c Type
+ documentation for a list) are const. If you ask for the stored
+ type, they return a copy of the stored object. If you ask for a
+ type that can be generated from the stored type, toT() copies and
+ converts and leaves the object itself unchanged. If you ask for a
+ type that cannot be generated from the stored type, the result
+ depends on the type (see the function documentation for details).
+
+ Note that three data types supported by TQVariant are explicitly
+ shared, namely TQImage, TQPointArray, and TQCString, and in these
+ cases the toT() methods return a shallow copy. In almost all cases
+ you must make a deep copy of the returned values before modifying
+ them.
+
+ The asT() functions are not const. They do conversion like the
+ toT() methods, set the variant to hold the converted value, and
+ return a reference to the new contents of the variant.
+
+ Here is some example code to demonstrate the use of TQVariant:
+
+ \code
+ TQDataStream out(...);
+ TQVariant v(123); // The variant now tqcontains an int
+ int x = v.toInt(); // x = 123
+ out << v; // Writes a type tag and an int to out
+ v = TQVariant("hello"); // The variant now tqcontains a TQCString
+ v = TQVariant(tr("hello"));// The variant now tqcontains a TQString
+ int y = v.toInt(); // y = 0 since v cannot be converted to an int
+ TQString s = v.toString(); // s = tr("hello") (see TQObject::tr())
+ out << v; // Writes a type tag and a TQString to out
+ ...
+ TQDataStream in(...); // (opening the previously written stream)
+ in >> v; // Reads an Int variant
+ int z = v.toInt(); // z = 123
+ qDebug("Type is %s", // prints "Type is int"
+ v.typeName());
+ v.asInt() += 100; // The variant now hold the value 223.
+ v = TQVariant( TQStringList() );
+ v.asStringList().append( "Hello" );
+ \endcode
+
+ You can even store TQValueList<TQVariant>s and
+ TQMap<TQString,TQVariant>s in a variant, so you can easily construct
+ arbitrarily complex data structures of arbitrary types. This is
+ very powerful and versatile, but may prove less memory and speed
+ efficient than storing specific types in standard data structures.
+
+ TQVariant also supports the notion of NULL values, where you have a
+ defined type with no value set.
+ \code
+ TQVariant x, y( TQString() ), z( TQString("") );
+ x.asInt();
+ // x.isNull() == TRUE, y.isNull() == TRUE, z.isNull() == FALSE
+ \endcode
+
+ See the \link collection.html Collection Classes\endlink.
+*/
+
+/*!
+ \enum TQVariant::Type
+
+ This enum type defines the types of variable that a TQVariant can
+ contain.
+
+ \value Invalid no type
+ \value BitArray a TQBitArray
+ \value ByteArray a TQByteArray
+ \value Bitmap a TQBitmap
+ \value Bool a bool
+ \value Brush a TQBrush
+ \value Color a TQColor
+ \value ColorGroup a TQColorGroup
+ \value Cursor a TQCursor
+ \value Date a TQDate
+ \value DateTime a TQDateTime
+ \value Double a double
+ \value Font a TQFont
+ \value IconSet a TQIconSet
+ \value Image a TQImage
+ \value Int an int
+ \value KeySequence a TQKeySequence
+ \value List a TQValueList<TQVariant>
+ \value LongLong a long long
+ \value ULongLong an unsigned long long
+ \value Map a TQMap<TQString,TQVariant>
+ \value Palette a TQPalette
+ \value Pen a TQPen
+ \value Pixmap a TQPixmap
+ \value Point a TQPoint
+ \value PointArray a TQPointArray
+ \value Rect a TQRect
+ \value Region a TQRegion
+ \value Size a TQSize
+ \value SizePolicy a TQSizePolicy
+ \value String a TQString
+ \value CString a TQCString
+ \value StringList a TQStringList
+ \value Time a TQTime
+ \value UInt an unsigned int
+
+ Note that TQt's definition of bool depends on the compiler.
+ \c tqglobal.h has the system-dependent definition of bool.
+*/
+
+/*!
+ Constructs an invalid variant.
+*/
+TQVariant::TQVariant()
+{
+ d = new Private;
+}
+
+/*!
+ Destroys the TQVariant and the contained object.
+
+ Note that subclasses that reimplement clear() should reimplement
+ the destructor to call clear(). This destructor calls clear(), but
+ because it is the destructor, TQVariant::clear() is called rather
+ than a subclass's clear().
+*/
+TQVariant::~TQVariant()
+{
+ if ( d->deref() )
+ delete d;
+}
+
+/*!
+ Constructs a copy of the variant, \a p, passed as the argument to
+ this constructor. Usually this is a deep copy, but a shallow copy
+ is made if the stored data type is explicitly shared, as e.g.
+ TQImage is.
+*/
+TQVariant::TQVariant( const TQVariant& p )
+{
+ p.d->ref();
+ d = p.d;
+}
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ Reads the variant from the data stream, \a s.
+*/
+TQVariant::TQVariant( TQDataStream& s )
+{
+ d = new Private;
+ s >> *this;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*!
+ Constructs a new variant with a string value, \a val.
+*/
+TQVariant::TQVariant( const TQString& val )
+{
+ d = new Private;
+ d->typ = String;
+ d->value.ptr = new TQString( val );
+}
+
+/*!
+ Constructs a new variant with a C-string value, \a val.
+
+ If you want to modify the TQCString after you've passed it to this
+ constructor, we recommend passing a deep copy (see
+ TQCString::copy()).
+*/
+TQVariant::TQVariant( const TQCString& val )
+{
+ d = new Private;
+ d->typ = CString;
+ d->value.ptr = new TQCString( val );
+}
+
+/*!
+ Constructs a new variant with a C-string value of \a val if \a val
+ is non-null. The variant creates a deep copy of \a val.
+
+ If \a val is null, the resulting variant has type Invalid.
+*/
+TQVariant::TQVariant( const char* val )
+{
+ d = new Private;
+ if ( val == 0 )
+ return;
+ d->typ = CString;
+ d->value.ptr = new TQCString( val );
+}
+
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Constructs a new variant with a string list value, \a val.
+*/
+TQVariant::TQVariant( const TQStringList& val )
+{
+ d = new Private;
+ d->typ = StringList;
+ d->value.ptr = new TQStringList( val );
+ d->is_null = FALSE;
+}
+#endif // TQT_NO_STRINGLIST
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Constructs a new variant with a map of TQVariants, \a val.
+*/
+TQVariant::TQVariant( const TQMap<TQString,TQVariant>& val )
+{
+ d = new Private;
+ d->typ = Map;
+ d->value.ptr = new TQMap<TQString,TQVariant>( val );
+ d->is_null = FALSE;
+}
+#endif
+/*!
+ Constructs a new variant with a font value, \a val.
+*/
+TQVariant::TQVariant( const TQFont& val )
+{
+ d = new Private;
+ d->typ = Font;
+ d->value.ptr = new TQFont( val );
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a pixmap value, \a val.
+*/
+TQVariant::TQVariant( const TQPixmap& val )
+{
+ d = new Private;
+ d->typ = Pixmap;
+ d->value.ptr = new TQPixmap( val );
+}
+
+
+/*!
+ Constructs a new variant with an image value, \a val.
+
+ Because TQImage is explicitly shared, you may need to pass a deep
+ copy to the variant using TQImage::copy(), e.g. if you intend
+ changing the image you've passed later on.
+*/
+TQVariant::TQVariant( const TQImage& val )
+{
+ d = new Private;
+ d->typ = Image;
+ d->value.ptr = new TQImage( val );
+}
+
+/*!
+ Constructs a new variant with a brush value, \a val.
+*/
+TQVariant::TQVariant( const TQBrush& val )
+{
+ d = new Private;
+ d->typ = Brush;
+ d->value.ptr = new TQBrush( val );
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a point value, \a val.
+*/
+TQVariant::TQVariant( const TQPoint& val )
+{
+ d = new Private;
+ d->typ = Point;
+ d->value.ptr = new TQPoint( val );
+}
+
+/*!
+ Constructs a new variant with a rect value, \a val.
+*/
+TQVariant::TQVariant( const TQRect& val )
+{
+ d = new Private;
+ d->typ = Rect;
+ d->value.ptr = new TQRect( val );
+}
+
+/*!
+ Constructs a new variant with a size value, \a val.
+*/
+TQVariant::TQVariant( const TQSize& val )
+{
+ d = new Private;
+ d->typ = Size;
+ d->value.ptr = new TQSize( val );
+}
+
+/*!
+ Constructs a new variant with a color value, \a val.
+*/
+TQVariant::TQVariant( const TQColor& val )
+{
+ d = new Private;
+ d->typ = Color;
+ d->value.ptr = new TQColor( val );
+ d->is_null = FALSE;
+}
+
+#ifndef TQT_NO_PALETTE
+/*!
+ Constructs a new variant with a color palette value, \a val.
+*/
+TQVariant::TQVariant( const TQPalette& val )
+{
+ d = new Private;
+ d->typ = Palette;
+ d->value.ptr = new TQPalette( val );
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a color group value, \a val.
+*/
+TQVariant::TQVariant( const TQColorGroup& val )
+{
+ d = new Private;
+ d->typ = ColorGroup;
+ d->value.ptr = new TQColorGroup( val );
+ d->is_null = FALSE;
+}
+#endif //TQT_NO_PALETTE
+#ifndef TQT_NO_ICONSET
+/*!
+ Constructs a new variant with an icon set value, \a val.
+*/
+TQVariant::TQVariant( const TQIconSet& val )
+{
+ d = new Private;
+ d->typ = IconSet;
+ d->value.ptr = new TQIconSet( val );
+}
+#endif //TQT_NO_ICONSET
+/*!
+ Constructs a new variant with a region value, \a val.
+*/
+TQVariant::TQVariant( const TQRegion& val )
+{
+ d = new Private;
+ d->typ = Region;
+ // ## Force a detach
+ d->value.ptr = new TQRegion( val );
+ ((TQRegion*)d->value.ptr)->translate( 0, 0 );
+}
+
+/*!
+ Constructs a new variant with a bitmap value, \a val.
+*/
+TQVariant::TQVariant( const TQBitmap& val )
+{
+ d = new Private;
+ d->typ = Bitmap;
+ d->value.ptr = new TQBitmap( val );
+}
+
+/*!
+ Constructs a new variant with a cursor value, \a val.
+*/
+TQVariant::TQVariant( const TQCursor& val )
+{
+ d = new Private;
+ d->typ = Cursor;
+ d->value.ptr = new TQCursor( val );
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a point array value, \a val.
+
+ Because TQPointArray is explicitly shared, you may need to pass a
+ deep copy to the variant using TQPointArray::copy(), e.g. if you
+ intend changing the point array you've passed later on.
+*/
+TQVariant::TQVariant( const TQPointArray& val )
+{
+ d = new Private;
+ d->typ = PointArray;
+ d->value.ptr = new TQPointArray( val );
+}
+
+/*!
+ Constructs a new variant with a date value, \a val.
+*/
+TQVariant::TQVariant( const TQDate& val )
+{
+ d = new Private;
+ d->typ = Date;
+ d->value.ptr = new TQDate( val );
+}
+
+/*!
+ Constructs a new variant with a time value, \a val.
+*/
+TQVariant::TQVariant( const TQTime& val )
+{
+ d = new Private;
+ d->typ = Time;
+ d->value.ptr = new TQTime( val );
+}
+
+/*!
+ Constructs a new variant with a date/time value, \a val.
+*/
+TQVariant::TQVariant( const TQDateTime& val )
+{
+ d = new Private;
+ d->typ = DateTime;
+ d->value.ptr = new TQDateTime( val );
+}
+
+/*!
+ Constructs a new variant with a bytearray value, \a val.
+*/
+TQVariant::TQVariant( const TQByteArray& val )
+{
+ d = new Private;
+ d->typ = ByteArray;
+ d->value.ptr = new TQByteArray( val );
+}
+
+/*!
+ Constructs a new variant with a bitarray value, \a val.
+*/
+TQVariant::TQVariant( const TQBitArray& val )
+{
+ d = new Private;
+ d->typ = BitArray;
+ d->value.ptr = new TQBitArray( val );
+}
+
+#ifndef TQT_NO_ACCEL
+
+/*!
+ Constructs a new variant with a key sequence value, \a val.
+*/
+TQVariant::TQVariant( const TQKeySequence& val )
+{
+ d = new Private;
+ d->typ = KeySequence;
+ d->value.ptr = new TQKeySequence( val );
+ d->is_null = FALSE;
+}
+
+#endif
+
+/*!
+ Constructs a new variant with a pen value, \a val.
+*/
+TQVariant::TQVariant( const TQPen& val )
+{
+ d = new Private;
+ d->typ = Pen;
+ d->value.ptr = new TQPen( val );
+}
+
+/*!
+ Constructs a new variant with an integer value, \a val.
+*/
+TQVariant::TQVariant( int val )
+{
+ d = new Private;
+ d->typ = Int;
+ d->value.i = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with an unsigned integer value, \a val.
+*/
+TQVariant::TQVariant( uint val )
+{
+ d = new Private;
+ d->typ = UInt;
+ d->value.u = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a long long integer value, \a val.
+*/
+TQVariant::TQVariant( TQ_LLONG val )
+{
+ d = new Private;
+ d->typ = LongLong;
+ d->value.ll = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with an unsigned long long integer value, \a val.
+*/
+
+TQVariant::TQVariant( TQ_ULLONG val )
+{
+ d = new Private;
+ d->typ = ULongLong;
+ d->value.ull = val;
+ d->is_null = FALSE;
+}
+
+/*!
+ Constructs a new variant with a boolean value, \a val. The integer
+ argument is a dummy, necessary for compatibility with some
+ compilers.
+*/
+TQVariant::TQVariant( bool val, int )
+{ // this is the comment that does NOT name said compiler.
+ d = new Private;
+ d->typ = Bool;
+ d->value.b = val;
+ d->is_null = FALSE;
+}
+
+
+/*!
+ Constructs a new variant with a floating point value, \a val.
+*/
+TQVariant::TQVariant( double val )
+{
+ d = new Private;
+ d->typ = Double;
+ d->value.d = val;
+ d->is_null = FALSE;
+}
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Constructs a new variant with a list value, \a val.
+*/
+TQVariant::TQVariant( const TQValueList<TQVariant>& val )
+{
+ d = new Private;
+ d->typ = List;
+ d->value.ptr = new TQValueList<TQVariant>( val );
+ d->is_null = FALSE;
+}
+#endif
+
+/*!
+ Constructs a new variant with a size policy value, \a val.
+*/
+TQVariant::TQVariant( TQSizePolicy val )
+{
+ d = new Private;
+ d->typ = SizePolicy;
+ d->value.ptr = new TQSizePolicy( val );
+ d->is_null = FALSE;
+}
+
+/*!
+ Assigns the value of the variant \a variant to this variant.
+
+ This is a deep copy of the variant, but note that if the variant
+ holds an explicitly shared type such as TQImage, a shallow copy is
+ performed.
+*/
+TQVariant& TQVariant::operator= ( const TQVariant& variant )
+{
+ TQVariant& other = (TQVariant&)variant;
+
+ other.d->ref();
+ if ( d->deref() )
+ delete d;
+
+ d = other.d;
+
+ return *this;
+}
+
+/*!
+ \internal
+*/
+void TQVariant::detach()
+{
+ if ( d->count == 1 )
+ return;
+
+ d->deref();
+ d = new Private( d );
+}
+
+/*!
+ Returns the name of the type stored in the variant. The returned
+ strings describe the C++ datatype used to store the data: for
+ example, "TQFont", "TQString", or "TQValueList<TQVariant>". An Invalid
+ variant returns 0.
+*/
+const char* TQVariant::typeName() const
+{
+ return typeToName( (Type) d->typ );
+}
+
+/*!
+ Convert this variant to type Invalid and free up any resources
+ used.
+*/
+void TQVariant::clear()
+{
+ if ( d->count > 1 )
+ {
+ d->deref();
+ d = new Private;
+ return;
+ }
+
+ d->clear();
+}
+
+/* Attention!
+
+ For dependency reasons, this table is duplicated in tqmoc.y. If you
+ change one, change both.
+
+ (Search for the word 'Attention' in tqmoc.y.)
+*/
+static const int ntypes = 35;
+static const char* const type_map[ntypes] =
+{
+ 0,
+ "TQMap<TQString,TQVariant>",
+ "TQValueList<TQVariant>",
+ "TQString",
+ "TQStringList",
+ "TQFont",
+ "TQPixmap",
+ "TQBrush",
+ "TQRect",
+ "TQSize",
+ "TQColor",
+ "TQPalette",
+ "TQColorGroup",
+ "TQIconSet",
+ "TQPoint",
+ "TQImage",
+ "int",
+ "uint",
+ "bool",
+ "double",
+ "TQCString",
+ "TQPointArray",
+ "TQRegion",
+ "TQBitmap",
+ "TQCursor",
+ "TQSizePolicy",
+ "TQDate",
+ "TQTime",
+ "TQDateTime",
+ "TQByteArray",
+ "TQBitArray",
+ "TQKeySequence",
+ "TQPen",
+ "TQ_LLONG",
+ "TQ_ULLONG"
+};
+
+
+/*!
+ Converts the enum representation of the storage type, \a typ, to
+ its string representation.
+*/
+const char* TQVariant::typeToName( Type typ )
+{
+ if ( typ >= ntypes )
+ return 0;
+ return type_map[typ];
+}
+
+
+/*!
+ Converts the string representation of the storage type given in \a
+ name, to its enum representation.
+
+ If the string representation cannot be converted to any enum
+ representation, the variant is set to \c Invalid.
+*/
+TQVariant::Type TQVariant::nameToType( const char* name )
+{
+ for ( int i = 0; i < ntypes; i++ ) {
+ if ( !qstrcmp( type_map[i], name ) )
+ return (Type) i;
+ }
+ return Invalid;
+}
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ Internal function for loading a variant from stream \a s. Use the
+ stream operators instead.
+
+ \internal
+*/
+void TQVariant::load( TQDataStream& s )
+{
+ clear();
+ TQ_UINT32 u;
+ s >> u;
+ Type t = (Type)u;
+
+ switch( t ) {
+ case Invalid:
+ {
+ // Since we wrote something, we should read something
+ TQString x;
+ s >> x;
+ d->typ = t;
+ d->is_null = TRUE;
+ }
+ break;
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case Map:
+ {
+ TQMap<TQString,TQVariant>* x = new TQMap<TQString,TQVariant>;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case List:
+ {
+ TQValueList<TQVariant>* x = new TQValueList<TQVariant>;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+#endif
+ case Cursor:
+ {
+#ifndef TQT_NO_CURSOR
+ TQCursor* x = new TQCursor;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+#endif
+ }
+ break;
+ case Bitmap:
+ {
+ TQBitmap* x = new TQBitmap;
+#ifndef TQT_NO_IMAGEIO
+ s >> *x;
+#endif
+ d->value.ptr = x;
+ }
+ break;
+ case Region:
+ {
+ TQRegion* x = new TQRegion;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case PointArray:
+ {
+ TQPointArray* x = new TQPointArray;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case String:
+ {
+ TQString* x = new TQString;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case CString:
+ {
+ TQCString* x = new TQCString;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+#ifndef TQT_NO_STRINGLIST
+ case StringList:
+ {
+ TQStringList* x = new TQStringList;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+#endif // TQT_NO_STRINGLIST
+ case Font:
+ {
+ TQFont* x = new TQFont;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case Pixmap:
+ {
+ TQPixmap* x = new TQPixmap;
+#ifndef TQT_NO_IMAGEIO
+ s >> *x;
+#endif
+ d->value.ptr = x;
+ }
+ break;
+ case Image:
+ {
+ TQImage* x = new TQImage;
+#ifndef TQT_NO_IMAGEIO
+ s >> *x;
+#endif
+ d->value.ptr = x;
+ }
+ break;
+ case Brush:
+ {
+ TQBrush* x = new TQBrush;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case Rect:
+ {
+ TQRect* x = new TQRect;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Point:
+ {
+ TQPoint* x = new TQPoint;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Size:
+ {
+ TQSize* x = new TQSize;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Color:
+ {
+ TQColor* x = new TQColor;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+#ifndef TQT_NO_PALETTE
+ case Palette:
+ {
+ TQPalette* x = new TQPalette;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case ColorGroup:
+ {
+ TQColorGroup* x = new TQColorGroup;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+#endif
+#ifndef TQT_NO_ICONSET
+ case IconSet:
+ {
+ TQPixmap x;
+ s >> x;
+ d->value.ptr = new TQIconSet( x );
+ }
+ break;
+#endif
+ case Int:
+ {
+ int x;
+ s >> x;
+ d->value.i = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case UInt:
+ {
+ uint x;
+ s >> x;
+ d->value.u = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case LongLong:
+ {
+ TQ_LLONG x;
+ s >> x;
+ d->value.ll = x;
+ }
+ break;
+ case ULongLong:
+ {
+ TQ_ULLONG x;
+ s >> x;
+ d->value.ull = x;
+ }
+ break;
+ case Bool:
+ {
+ TQ_INT8 x;
+ s >> x;
+ d->value.b = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case Double:
+ {
+ double x;
+ s >> x;
+ d->value.d = x;
+ d->is_null = FALSE;
+ }
+ break;
+ case SizePolicy:
+ {
+ int h,v;
+ TQ_INT8 hfw;
+ s >> h >> v >> hfw;
+ d->value.ptr = new TQSizePolicy( (TQSizePolicy::SizeType)h,
+ (TQSizePolicy::SizeType)v,
+ (bool) hfw);
+ d->is_null = FALSE;
+ }
+ break;
+ case Date:
+ {
+ TQDate* x = new TQDate;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case Time:
+ {
+ TQTime* x = new TQTime;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case DateTime:
+ {
+ TQDateTime* x = new TQDateTime;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case ByteArray:
+ {
+ TQByteArray* x = new TQByteArray;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+ case BitArray:
+ {
+ TQBitArray* x = new TQBitArray;
+ s >> *x;
+ d->value.ptr = x;
+ }
+ break;
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ {
+ TQKeySequence* x = new TQKeySequence;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+#endif // TQT_NO_ACCEL
+ case Pen:
+ {
+ TQPen* x = new TQPen;
+ s >> *x;
+ d->value.ptr = x;
+ d->is_null = FALSE;
+ }
+ break;
+ }
+ d->typ = t;
+}
+
+/*!
+ Internal function for saving a variant to the stream \a s. Use the
+ stream operators instead.
+
+ \internal
+*/
+void TQVariant::save( TQDataStream& s ) const
+{
+ s << (TQ_UINT32)type();
+
+ switch( d->typ ) {
+ case Cursor:
+ s << *((TQCursor*)d->value.ptr);
+ break;
+ case Bitmap:
+#ifndef TQT_NO_IMAGEIO
+ s << *((TQBitmap*)d->value.ptr);
+#endif
+ break;
+ case PointArray:
+ s << *((TQPointArray*)d->value.ptr);
+ break;
+ case Region:
+ s << *((TQRegion*)d->value.ptr);
+ break;
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case List:
+ s << *((TQValueList<TQVariant>*)d->value.ptr);
+ break;
+ case Map:
+ s << *((TQMap<TQString,TQVariant>*)d->value.ptr);
+ break;
+#endif
+ case String:
+ s << *((TQString*)d->value.ptr);
+ break;
+ case CString:
+ s << *((TQCString*)d->value.ptr);
+ break;
+#ifndef TQT_NO_STRINGLIST
+ case StringList:
+ s << *((TQStringList*)d->value.ptr);
+ break;
+#endif
+ case Font:
+ s << *((TQFont*)d->value.ptr);
+ break;
+ case Pixmap:
+#ifndef TQT_NO_IMAGEIO
+ s << *((TQPixmap*)d->value.ptr);
+#endif
+ break;
+ case Image:
+#ifndef TQT_NO_IMAGEIO
+ s << *((TQImage*)d->value.ptr);
+#endif
+ break;
+ case Brush:
+ s << *((TQBrush*)d->value.ptr);
+ break;
+ case Point:
+ s << *((TQPoint*)d->value.ptr);
+ break;
+ case Rect:
+ s << *((TQRect*)d->value.ptr);
+ break;
+ case Size:
+ s << *((TQSize*)d->value.ptr);
+ break;
+ case Color:
+ s << *((TQColor*)d->value.ptr);
+ break;
+#ifndef TQT_NO_PALETTE
+ case Palette:
+ s << *((TQPalette*)d->value.ptr);
+ break;
+ case ColorGroup:
+ s << *((TQColorGroup*)d->value.ptr);
+ break;
+#endif
+#ifndef TQT_NO_ICONSET
+ case IconSet:
+ //### add stream operator to iconset
+ s << ((TQIconSet*)d->value.ptr)->pixmap();
+ break;
+#endif
+ case Int:
+ s << d->value.i;
+ break;
+ case UInt:
+ s << d->value.u;
+ break;
+ case LongLong:
+ s << d->value.ll;
+ break;
+ case ULongLong:
+ s << d->value.ull;
+ break;
+ case Bool:
+ s << (TQ_INT8)d->value.b;
+ break;
+ case Double:
+ s << d->value.d;
+ break;
+ case SizePolicy:
+ {
+ TQSizePolicy p = toSizePolicy();
+ s << (int) p.horData() << (int) p.verData()
+ << (TQ_INT8) p.hasHeightForWidth();
+ }
+ break;
+ case Date:
+ s << *((TQDate*)d->value.ptr);
+ break;
+ case Time:
+ s << *((TQTime*)d->value.ptr);
+ break;
+ case DateTime:
+ s << *((TQDateTime*)d->value.ptr);
+ break;
+ case ByteArray:
+ s << *((TQByteArray*)d->value.ptr);
+ break;
+ case BitArray:
+ s << *((TQBitArray*)d->value.ptr);
+ break;
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ s << *((TQKeySequence*)d->value.ptr);
+ break;
+#endif
+ case Pen:
+ s << *((TQPen*)d->value.ptr);
+ break;
+ case Invalid:
+ s << TQString(); // ### looks wrong.
+ break;
+ }
+}
+
+/*!
+ Reads a variant \a p from the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream
+ operators \endlink
+*/
+TQDataStream& operator>> ( TQDataStream& s, TQVariant& p )
+{
+ p.load( s );
+ return s;
+}
+
+/*!
+ Writes a variant \a p to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream
+ operators \endlink
+*/
+TQDataStream& operator<< ( TQDataStream& s, const TQVariant& p )
+{
+ p.save( s );
+ return s;
+}
+
+/*!
+ Reads a variant type \a p in enum representation from the stream \a s.
+*/
+TQDataStream& operator>> ( TQDataStream& s, TQVariant::Type& p )
+{
+ TQ_UINT32 u;
+ s >> u;
+ p = (TQVariant::Type) u;
+
+ return s;
+}
+
+/*!
+ Writes a variant type \a p to the stream \a s.
+*/
+TQDataStream& operator<< ( TQDataStream& s, const TQVariant::Type p )
+{
+ s << (TQ_UINT32)p;
+
+ return s;
+}
+
+#endif //TQT_NO_DATASTREAM
+
+/*!
+ \fn Type TQVariant::type() const
+
+ Returns the storage type of the value stored in the variant.
+ Usually it's best to test with canCast() whether the variant can
+ deliver the data type you are interested in.
+*/
+
+/*!
+ \fn bool TQVariant::isValid() const
+
+ Returns TRUE if the storage type of this variant is not
+ TQVariant::Invalid; otherwise returns FALSE.
+*/
+
+/*!
+ \fn TQValueListConstIterator<TQString> TQVariant::stringListBegin() const
+ \obsolete
+
+ Returns an iterator to the first string in the list if the
+ variant's type is StringList; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQValueListConstIterator<TQString> TQVariant::stringListEnd() const
+ \obsolete
+
+ Returns the end iterator for the list if the variant's type is
+ StringList; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQValueListConstIterator<TQVariant> TQVariant::listBegin() const
+ \obsolete
+
+ Returns an iterator to the first item in the list if the variant's
+ type is appropriate; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQValueListConstIterator<TQVariant> TQVariant::listEnd() const
+ \obsolete
+
+ Returns the end iterator for the list if the variant's type is
+ appropriate; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQMapConstIterator<TQString, TQVariant> TQVariant::mapBegin() const
+ \obsolete
+
+ Returns an iterator to the first item in the map, if the variant's
+ type is appropriate; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQMapConstIterator<TQString, TQVariant> TQVariant::mapEnd() const
+ \obsolete
+
+ Returns the end iterator for the map, if the variant's type is
+ appropriate; otherwise returns a null iterator.
+*/
+
+/*!
+ \fn TQMapConstIterator<TQString, TQVariant> TQVariant::mapFind( const TQString& key ) const
+ \obsolete
+
+ Returns an iterator to the item in the map with \a key as key, if
+ the variant's type is appropriate and \a key is a valid key;
+ otherwise returns a null iterator.
+*/
+
+/*!
+ Returns the variant as a TQString if the variant can be cast to
+ String, otherwise returns TQString::null.
+
+ \sa asString(), canCast()
+*/
+const TQString TQVariant::toString() const
+{
+ switch( d->typ ) {
+ case CString:
+ return TQString::tqfromLatin1( toCString() );
+ case Int:
+ return TQString::number( toInt() );
+ case UInt:
+ return TQString::number( toUInt() );
+ case LongLong:
+ return TQString::number( toLongLong() );
+ case ULongLong:
+ return TQString::number( toULongLong() );
+ case Double:
+ return TQString::number( toDouble(), 'g', DBL_DIG );
+#if !defined(TQT_NO_SPRINTF) && !defined(TQT_NO_DATESTRING)
+ case Date:
+ return toDate().toString( TQt::ISODate );
+ case Time:
+ return toTime().toString( TQt::ISODate );
+ case DateTime:
+ return toDateTime().toString( TQt::ISODate );
+#endif
+ case Bool:
+ return toInt() ? "true" : "false";
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ return (TQString) *( (TQKeySequence*)d->value.ptr );
+#endif
+ case ByteArray:
+ return TQString( *((TQByteArray*)d->value.ptr) );
+ case Font:
+ return toFont().toString();
+ case Color:
+ return toColor().name();
+ case String:
+ return *((TQString*)d->value.ptr);
+ default:
+ return TQString::null;
+ }
+}
+/*!
+ Returns the variant as a TQCString if the variant can be cast to a
+ CString; otherwise returns 0.
+
+ \sa asCString(), canCast()
+*/
+const TQCString TQVariant::toCString() const
+{
+ switch( d->typ ) {
+ case CString: return *((TQCString*)d->value.ptr);
+ case String: return ((TQString*)d->value.ptr)->latin1();
+ default: {
+ if (!canCast(String))
+ return 0;
+ TQString c = toString();
+ return TQCString(c.latin1());
+ }
+ }
+}
+
+
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Returns the variant as a TQStringList if the variant has type()
+ StringList or List of a type that can be converted to TQString;
+ otherwise returns an empty list.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myVariant.toStringList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asStringList()
+*/
+const TQStringList TQVariant::toStringList() const
+{
+ switch ( d->typ ) {
+ case StringList:
+ return *((TQStringList*)d->value.ptr);
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case List:
+ {
+ TQStringList lst;
+ TQValueList<TQVariant>::ConstIterator it = listBegin();
+ TQValueList<TQVariant>::ConstIterator end = listEnd();
+ while( it != end ) {
+ TQString tmp = (*it).toString();
+ ++it;
+ lst.append( tmp );
+ }
+ return lst;
+ }
+#endif
+ default:
+ return TQStringList();
+ }
+}
+#endif //TQT_NO_STRINGLIST
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant as a TQMap<TQString,TQVariant> if the variant has
+ type() Map; otherwise returns an empty map.
+
+ Note that if you want to iterate over the map, you should iterate
+ over a copy, e.g.
+ \code
+ TQMap<TQString, TQVariant> map = myVariant.toMap();
+ TQMap<TQString, TQVariant>::Iterator it = map.begin();
+ while( it != map.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asMap()
+*/
+const TQMap<TQString, TQVariant> TQVariant::toMap() const
+{
+ if ( d->typ != Map )
+ return TQMap<TQString,TQVariant>();
+
+ return *((TQMap<TQString,TQVariant>*)d->value.ptr);
+}
+#endif
+/*!
+ Returns the variant as a TQFont if the variant can be cast to Font;
+ otherwise returns the application's default font.
+
+ \sa asFont(), canCast()
+*/
+const TQFont TQVariant::toFont() const
+{
+ switch ( d->typ ) {
+ case CString:
+ case ByteArray:
+ case String:
+ {
+ TQFont fnt;
+ fnt.fromString( toString() );
+ return fnt;
+ }
+ case Font:
+ return *((TQFont*)d->value.ptr);
+ default:
+ return TQFont();
+ }
+}
+
+/*!
+ Returns the variant as a TQPixmap if the variant has type() Pixmap;
+ otherwise returns a null pixmap.
+
+ \sa asPixmap()
+*/
+const TQPixmap TQVariant::toPixmap() const
+{
+ if ( d->typ != Pixmap )
+ return TQPixmap();
+
+ return *((TQPixmap*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQImage if the variant has type() Image;
+ otherwise returns a null image.
+
+ \sa asImage()
+*/
+const TQImage TQVariant::toImage() const
+{
+ if ( d->typ != Image )
+ return TQImage();
+
+ return *((TQImage*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQBrush if the variant has type() Brush;
+ otherwise returns a default brush (with all black colors).
+
+ \sa asBrush()
+*/
+const TQBrush TQVariant::toBrush() const
+{
+ if( d->typ != Brush )
+ return TQBrush();
+
+ return *((TQBrush*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQPoint if the variant has type() Point;
+ otherwise returns a point (0, 0).
+
+ \sa asPoint()
+*/
+const TQPoint TQVariant::toPoint() const
+{
+ if ( d->typ != Point )
+ return TQPoint();
+
+ return *((TQPoint*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQRect if the variant has type() Rect;
+ otherwise returns an empty rectangle.
+
+ \sa asRect()
+*/
+const TQRect TQVariant::toRect() const
+{
+ if ( d->typ != Rect )
+ return TQRect();
+
+ return *((TQRect*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQSize if the variant has type() Size;
+ otherwise returns an invalid size.
+
+ \sa asSize()
+*/
+const TQSize TQVariant::toSize() const
+{
+ if ( d->typ != Size )
+ return TQSize();
+
+ return *((TQSize*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQColor if the variant can be cast to Color;
+ otherwise returns an invalid color.
+
+ \sa asColor(), canCast()
+*/
+const TQColor TQVariant::toColor() const
+{
+ switch ( d->typ ) {
+ case ByteArray:
+ case CString:
+ case String:
+ {
+ TQColor col;
+ col.setNamedColor( toString() );
+ return col;
+ }
+ case Color:
+ return *((TQColor*)d->value.ptr);
+ default:
+ return TQColor();
+ }
+}
+#ifndef TQT_NO_PALETTE
+/*!
+ Returns the variant as a TQPalette if the variant has type()
+ Palette; otherwise returns a completely black palette.
+
+ \sa asPalette()
+*/
+const TQPalette TQVariant::toPalette() const
+{
+ if ( d->typ != Palette )
+ return TQPalette();
+
+ return *((TQPalette*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQColorGroup if the variant has type()
+ ColorGroup; otherwise returns a completely black color group.
+
+ \sa asColorGroup()
+*/
+const TQColorGroup TQVariant::toColorGroup() const
+{
+ if ( d->typ != ColorGroup )
+ return TQColorGroup();
+
+ return *((TQColorGroup*)d->value.ptr);
+}
+#endif //TQT_NO_PALETTE
+#ifndef TQT_NO_ICONSET
+/*!
+ Returns the variant as a TQIconSet if the variant has type()
+ IconSet; otherwise returns an icon set of null pixmaps.
+
+ \sa asIconSet()
+*/
+const TQIconSet TQVariant::toIconSet() const
+{
+ if ( d->typ != IconSet )
+ return TQIconSet();
+
+ return *((TQIconSet*)d->value.ptr);
+}
+#endif //TQT_NO_ICONSET
+/*!
+ Returns the variant as a TQPointArray if the variant has type()
+ PointArray; otherwise returns an empty TQPointArray.
+
+ \sa asPointArray()
+*/
+const TQPointArray TQVariant::toPointArray() const
+{
+ if ( d->typ != PointArray )
+ return TQPointArray();
+
+ return *((TQPointArray*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQBitmap if the variant has type() Bitmap;
+ otherwise returns a null TQBitmap.
+
+ \sa asBitmap()
+*/
+const TQBitmap TQVariant::toBitmap() const
+{
+ if ( d->typ != Bitmap )
+ return TQBitmap();
+
+ return *((TQBitmap*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQRegion if the variant has type() Region;
+ otherwise returns an empty TQRegion.
+
+ \sa asRegion()
+*/
+const TQRegion TQVariant::toRegion() const
+{
+ if ( d->typ != Region )
+ return TQRegion();
+
+ return *((TQRegion*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQCursor if the variant has type() Cursor;
+ otherwise returns the default arrow cursor.
+
+ \sa asCursor()
+*/
+const TQCursor TQVariant::toCursor() const
+{
+#ifndef TQT_NO_CURSOR
+ if ( d->typ != Cursor )
+ return TQCursor();
+#endif
+
+ return *((TQCursor*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as a TQDate if the variant can be cast to Date;
+ otherwise returns an invalid date.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ date will be returned if the string cannot be parsed as a
+ TQt::ISODate format date.
+
+ \sa asDate(), canCast()
+*/
+const TQDate TQVariant::toDate() const
+{
+ switch ( d->typ ) {
+ case Date:
+ return *((TQDate*)d->value.ptr);
+ case DateTime:
+ return ((TQDateTime*)d->value.ptr)->date();
+#ifndef TQT_NO_DATESTRING
+ case String:
+ return TQDate::fromString( *((TQString*)d->value.ptr), TQt::ISODate );
+ case CString:
+ case ByteArray:
+ return TQDate::fromString(toString(), TQt::ISODate);
+#endif
+ default:
+ return TQDate();
+ }
+}
+
+/*!
+ Returns the variant as a TQTime if the variant can be cast to Time;
+ otherwise returns an invalid date.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ time will be returned if the string cannot be parsed as a
+ TQt::ISODate format time.
+
+ \sa asTime()
+*/
+const TQTime TQVariant::toTime() const
+{
+ switch ( d->typ ) {
+ case Time:
+ return *((TQTime*)d->value.ptr);
+ case DateTime:
+ return ((TQDateTime*)d->value.ptr)->time();
+#ifndef TQT_NO_DATESTRING
+ case String:
+ return TQTime::fromString( *((TQString*)d->value.ptr), TQt::ISODate );
+ case CString:
+ case ByteArray:
+ return TQTime::fromString(toString(), TQt::ISODate);
+#endif
+ default:
+ return TQTime();
+ }
+}
+
+/*!
+ Returns the variant as a TQDateTime if the variant can be cast to
+ DateTime; otherwise returns an invalid TQDateTime.
+
+ Note that if the type() is String, CString or ByteArray an invalid
+ TQDateTime will be returned if the string cannot be parsed as a
+ TQt::ISODate format date/time.
+
+ \sa asDateTime()
+*/
+const TQDateTime TQVariant::toDateTime() const
+{
+ switch ( d->typ ) {
+ case DateTime:
+ return *((TQDateTime*)d->value.ptr);
+#ifndef TQT_NO_DATESTRING
+ case String:
+ return TQDateTime::fromString( *((TQString*)d->value.ptr), TQt::ISODate );
+ case CString:
+ case ByteArray:
+ return TQDateTime::fromString(toString(), TQt::ISODate);
+#endif
+ case Date:
+ return TQDateTime( *((TQDate*)d->value.ptr) );
+ default:
+ return TQDateTime();
+ }
+}
+
+/*!
+ Returns the variant as a TQByteArray if the variant can be cast to
+ a ByteArray; otherwise returns an empty bytearray.
+
+ \sa asByteArray(), canCast()
+*/
+const TQByteArray TQVariant::toByteArray() const
+{
+ switch(d->typ) {
+ case ByteArray: return *((TQByteArray*)d->value.ptr);
+ case CString: return *((TQByteArray*)d->value.ptr);
+ default: {
+ TQByteArray ret;
+ if (canCast(String)) {
+ TQString c = toString();
+ ret.duplicate(c.latin1(), c.length());
+ }
+ return ret;
+ }
+ }
+}
+
+/*!
+ Returns the variant as a TQBitArray if the variant has type()
+ BitArray; otherwise returns an empty bitarray.
+
+ \sa asBitArray()
+*/
+const TQBitArray TQVariant::toBitArray() const
+{
+ if ( d->typ == BitArray )
+ return *((TQBitArray*)d->value.ptr);
+ return TQBitArray();
+}
+
+#ifndef TQT_NO_ACCEL
+
+/*!
+ Returns the variant as a TQKeySequence if the variant can be cast
+ to a KeySequence; otherwise returns an empty key sequence.
+
+ \sa asKeySequence(), canCast()
+*/
+const TQKeySequence TQVariant::toKeySequence() const
+{
+ switch ( d->typ ) {
+ case KeySequence:
+ return *((TQKeySequence*)d->value.ptr);
+ case String:
+ case ByteArray:
+ case CString:
+ return TQKeySequence( toString() );
+ case Int:
+ case UInt:
+ case Double:
+ case ULongLong:
+ case LongLong:
+ return TQKeySequence( toInt() );
+ default:
+ return TQKeySequence();
+ }
+}
+
+#endif // TQT_NO_ACCEL
+
+/*!
+ Returns the variant as a TQPen if the variant has type()
+ Pen; otherwise returns an empty TQPen.
+
+ \sa asPen()
+*/
+const TQPen TQVariant::toPen() const
+{
+ if ( d->typ != Pen )
+ return TQPen();
+
+ return *((TQPen*)d->value.ptr);
+}
+
+/*!
+ Returns the variant as an int if the variant can be cast to Int;
+ otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asInt(), canCast()
+*/
+int TQVariant::toInt( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( Int );
+
+ switch ( d->typ ) {
+ case String:
+ return ((TQString*)d->value.ptr)->toInt( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d->value.ptr)->toInt( ok );
+ case Int:
+ return d->value.i;
+ case UInt:
+ return (int)d->value.u;
+ case LongLong:
+ return (int)d->value.ll;
+ case ULongLong:
+ return (int)d->value.ull;
+ case Double:
+ return (int)d->value.d;
+ case Bool:
+ return (int)d->value.b;
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ return (int) *( (TQKeySequence*)d->value.ptr );
+#endif
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as an unsigned int if the variant can be cast
+ to UInt; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an unsigned int; otherwise \a *ok is set to FALSE.
+
+ \sa asUInt(), canCast()
+*/
+uint TQVariant::toUInt( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( UInt );
+
+ switch( d->typ ) {
+ case String:
+ return ((TQString*)d->value.ptr)->toUInt( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d->value.ptr)->toUInt( ok );
+ case Int:
+ return (uint)d->value.i;
+ case UInt:
+ return d->value.u;
+ case LongLong:
+ return (uint)d->value.ll;
+ case ULongLong:
+ return (uint)d->value.ull;
+ case Double:
+ return (uint)d->value.d;
+ case Bool:
+ return (uint)d->value.b;
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as a long long int if the variant can be cast
+ to LongLong; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asLongLong(), canCast()
+*/
+TQ_LLONG TQVariant::toLongLong( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( LongLong );
+
+ switch ( d->typ ) {
+ case String:
+ return ((TQString*)d->value.ptr)->toLongLong( ok );
+ case CString:
+ case ByteArray:
+ return TQString(*(TQCString*)d->value.ptr).toLongLong(ok);
+ case Int:
+ return (TQ_LLONG)d->value.i;
+ case UInt:
+ return (TQ_LLONG)d->value.u;
+ case LongLong:
+ return d->value.ll;
+ case ULongLong:
+ return (TQ_LLONG)d->value.ull;
+ case Double:
+ return (TQ_LLONG)d->value.d;
+ case Bool:
+ return (TQ_LLONG)d->value.b;
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as as an unsigned long long int if the variant
+ can be cast to ULongLong; otherwise returns 0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to an int; otherwise \a *ok is set to FALSE.
+
+ \sa asULongLong(), canCast()
+*/
+TQ_ULLONG TQVariant::toULongLong( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( ULongLong );
+
+ switch ( d->typ ) {
+ case Int:
+ return (TQ_ULLONG)d->value.i;
+ case UInt:
+ return (TQ_ULLONG)d->value.u;
+ case LongLong:
+ return (TQ_ULLONG)d->value.ll;
+ case ULongLong:
+ return d->value.ull;
+ case Double:
+ return (TQ_ULLONG)d->value.d;
+ case Bool:
+ return (TQ_ULLONG)d->value.b;
+ case String:
+ return ((TQString*)d->value.ptr)->toULongLong( ok );
+ case CString:
+ case ByteArray:
+ return TQString(*(TQCString*)d->value.ptr).toULongLong(ok);
+ default:
+ return 0;
+ }
+}
+
+/*!
+ Returns the variant as a bool if the variant can be cast to Bool;
+ otherWise returns FALSE.
+
+ Returns TRUE if the variant has a numeric type and its value is
+ non-zero, or if the variant has type String, ByteArray or CString
+ and its lower-case content is not empty, "0" or "false"; otherwise
+ returns FALSE.
+
+ \sa asBool(), canCast()
+*/
+bool TQVariant::toBool() const
+{
+ switch( d->typ ) {
+ case Bool:
+ return d->value.b;
+ case Double:
+ return d->value.d != 0.0;
+ case Int:
+ return d->value.i != 0;
+ case UInt:
+ return d->value.u != 0;
+ case LongLong:
+ return d->value.ll != 0;
+ case ULongLong:
+ return d->value.ull != 0;
+ case String:
+ case CString:
+ case ByteArray:
+ {
+ TQString str = toString().lower();
+ return !(str == "0" || str == "false" || str.isEmpty() );
+ }
+ default:
+ return FALSE;
+ }
+}
+
+/*!
+ Returns the variant as a double if the variant can be cast to
+ Double; otherwise returns 0.0.
+
+ If \a ok is non-null: \a *ok is set to TRUE if the value could be
+ converted to a double; otherwise \a *ok is set to FALSE.
+
+ \sa asDouble(), canCast()
+*/
+double TQVariant::toDouble( bool * ok ) const
+{
+ if ( ok )
+ *ok = canCast( Double );
+
+ switch ( d->typ ) {
+ case String:
+ return ((TQString*)d->value.ptr)->toDouble( ok );
+ case CString:
+ case ByteArray:
+ return ((TQCString*)d->value.ptr)->toDouble( ok );
+ case Double:
+ return d->value.d;
+ case Int:
+ return (double)d->value.i;
+ case Bool:
+ return (double)d->value.b;
+ case UInt:
+ return (double)d->value.u;
+ case LongLong:
+ return (double)d->value.ll;
+ case ULongLong:
+#if defined(TQ_CC_MSVC) && !defined(TQ_CC_MSVC_NET)
+ return (double)(TQ_LLONG)d->value.ull;
+#else
+ return (double)d->value.ull;
+#endif
+ default:
+ return 0.0;
+ }
+}
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant as a TQValueList<TQVariant> if the variant has
+ type() List or StringList; otherwise returns an empty list.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQVariant> list = myVariant.toList();
+ TQValueList<TQVariant>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa asList()
+*/
+const TQValueList<TQVariant> TQVariant::toList() const
+{
+ if ( d->typ == List )
+ return *((TQValueList<TQVariant>*)d->value.ptr);
+#ifndef TQT_NO_STRINGLIST
+ if ( d->typ == StringList ) {
+ TQValueList<TQVariant> lst;
+ TQStringList::ConstIterator it = stringListBegin();
+ TQStringList::ConstIterator end = stringListEnd();
+ for( ; it != end; ++it )
+ lst.append( TQVariant( *it ) );
+ return lst;
+ }
+#endif //TQT_NO_STRINGLIST
+ return TQValueList<TQVariant>();
+}
+#endif
+
+/*!
+ Returns the variant as a TQSizePolicy if the variant has type()
+ SizePolicy; otherwise returns an undefined (but legal) size
+ policy.
+*/
+
+TQSizePolicy TQVariant::toSizePolicy() const
+{
+ if ( d->typ == SizePolicy )
+ return *((TQSizePolicy*)d->value.ptr);
+
+ return TQSizePolicy();
+}
+
+
+#define TQ_VARIANT_AS( f ) TQ##f& TQVariant::as##f() \
+{ \
+ bool b = isNull(); \
+ if ( d->typ != f ) \
+ *this = TQVariant( to##f() ); \
+ else \
+ detach(); \
+ d->is_null = b; \
+ return *((TQ##f*)d->value.ptr); \
+}
+
+TQ_VARIANT_AS(String)
+TQ_VARIANT_AS(CString)
+#ifndef TQT_NO_STRINGLIST
+TQ_VARIANT_AS(StringList)
+#endif
+TQ_VARIANT_AS(Font)
+TQ_VARIANT_AS(Pixmap)
+TQ_VARIANT_AS(Image)
+TQ_VARIANT_AS(Brush)
+TQ_VARIANT_AS(Point)
+TQ_VARIANT_AS(Rect)
+TQ_VARIANT_AS(Size)
+TQ_VARIANT_AS(Color)
+#ifndef TQT_NO_PALETTE
+TQ_VARIANT_AS(Palette)
+TQ_VARIANT_AS(ColorGroup)
+#endif
+#ifndef TQT_NO_ICONSET
+TQ_VARIANT_AS(IconSet)
+#endif
+TQ_VARIANT_AS(PointArray)
+TQ_VARIANT_AS(Bitmap)
+TQ_VARIANT_AS(Region)
+TQ_VARIANT_AS(Cursor)
+TQ_VARIANT_AS(SizePolicy)
+TQ_VARIANT_AS(Date)
+TQ_VARIANT_AS(Time)
+TQ_VARIANT_AS(DateTime)
+TQ_VARIANT_AS(ByteArray)
+TQ_VARIANT_AS(BitArray)
+#ifndef TQT_NO_ACCEL
+TQ_VARIANT_AS(KeySequence)
+#endif
+TQ_VARIANT_AS(Pen)
+
+/*!
+ \fn TQString& TQVariant::asString()
+
+ Tries to convert the variant to hold a string value. If that is
+ not possible the variant is set to an empty string.
+
+ Returns a reference to the stored string.
+
+ \sa toString()
+*/
+
+/*!
+ \fn TQCString& TQVariant::asCString()
+
+ Tries to convert the variant to hold a string value. If that is
+ not possible the variant is set to an empty string.
+
+ Returns a reference to the stored string.
+
+ \sa toCString()
+*/
+
+/*!
+ \fn TQStringList& TQVariant::asStringList()
+
+ Tries to convert the variant to hold a TQStringList value. If that
+ is not possible the variant is set to an empty string list.
+
+ Returns a reference to the stored string list.
+
+ Note that if you want to iterate over the list, you should
+ iterate over a copy, e.g.
+ \code
+ TQStringList list = myVariant.asStringList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa toStringList()
+*/
+
+/*!
+ \fn TQFont& TQVariant::asFont()
+
+ Tries to convert the variant to hold a TQFont. If that is not
+ possible the variant is set to the application's default font.
+
+ Returns a reference to the stored font.
+
+ \sa toFont()
+*/
+
+/*!
+ \fn TQPixmap& TQVariant::asPixmap()
+
+ Tries to convert the variant to hold a pixmap value. If that is
+ not possible the variant is set to a null pixmap.
+
+ Returns a reference to the stored pixmap.
+
+ \sa toPixmap()
+*/
+
+/*!
+ \fn TQImage& TQVariant::asImage()
+
+ Tries to convert the variant to hold an image value. If that is
+ not possible the variant is set to a null image.
+
+ Returns a reference to the stored image.
+
+ \sa toImage()
+*/
+
+/*!
+ \fn TQBrush& TQVariant::asBrush()
+
+ Tries to convert the variant to hold a brush value. If that is not
+ possible the variant is set to a default black brush.
+
+ Returns a reference to the stored brush.
+
+ \sa toBrush()
+*/
+
+/*!
+ \fn TQPoint& TQVariant::asPoint()
+
+ Tries to convert the variant to hold a point value. If that is not
+ possible the variant is set to a (0, 0) point.
+
+ Returns a reference to the stored point.
+
+ \sa toPoint()
+*/
+
+/*!
+ \fn TQRect& TQVariant::asRect()
+
+ Tries to convert the variant to hold a rectangle value. If that is
+ not possible the variant is set to an empty rectangle.
+
+ Returns a reference to the stored rectangle.
+
+ \sa toRect()
+*/
+
+/*!
+ \fn TQSize& TQVariant::asSize()
+
+ Tries to convert the variant to hold a TQSize value. If that is not
+ possible the variant is set to an invalid size.
+
+ Returns a reference to the stored size.
+
+ \sa toSize() TQSize::isValid()
+*/
+
+/*!
+ \fn TQSizePolicy& TQVariant::asSizePolicy()
+
+ Tries to convert the variant to hold a TQSizePolicy value. If that
+ fails, the variant is set to an arbitrary (valid) size policy.
+*/
+
+
+/*!
+ \fn TQColor& TQVariant::asColor()
+
+ Tries to convert the variant to hold a TQColor value. If that is
+ not possible the variant is set to an invalid color.
+
+ Returns a reference to the stored color.
+
+ \sa toColor() TQColor::isValid()
+*/
+
+/*!
+ \fn TQPalette& TQVariant::asPalette()
+
+ Tries to convert the variant to hold a TQPalette value. If that is
+ not possible the variant is set to a palette of black colors.
+
+ Returns a reference to the stored palette.
+
+ \sa toString()
+*/
+
+/*!
+ \fn TQColorGroup& TQVariant::asColorGroup()
+
+ Tries to convert the variant to hold a TQColorGroup value. If that
+ is not possible the variant is set to a color group of all black
+ colors.
+
+ Returns a reference to the stored color group.
+
+ \sa toColorGroup()
+*/
+
+/*!
+ \fn TQIconSet& TQVariant::asIconSet()
+
+ Tries to convert the variant to hold a TQIconSet value. If that is
+ not possible the variant is set to an empty iconset.
+
+ Returns a reference to the stored iconset.
+
+ \sa toIconSet()
+*/
+
+/*!
+ \fn TQPointArray& TQVariant::asPointArray()
+
+ Tries to convert the variant to hold a TQPointArray value. If that
+ is not possible the variant is set to an empty point array.
+
+ Returns a reference to the stored point array.
+
+ \sa toPointArray()
+*/
+
+/*!
+ \fn TQBitmap& TQVariant::asBitmap()
+
+ Tries to convert the variant to hold a bitmap value. If that is
+ not possible the variant is set to a null bitmap.
+
+ Returns a reference to the stored bitmap.
+
+ \sa toBitmap()
+*/
+
+/*!
+ \fn TQRegion& TQVariant::asRegion()
+
+ Tries to convert the variant to hold a TQRegion value. If that is
+ not possible the variant is set to a null region.
+
+ Returns a reference to the stored region.
+
+ \sa toRegion()
+*/
+
+/*!
+ \fn TQCursor& TQVariant::asCursor()
+
+ Tries to convert the variant to hold a TQCursor value. If that is
+ not possible the variant is set to a default arrow cursor.
+
+ Returns a reference to the stored cursor.
+
+ \sa toCursor()
+*/
+
+/*!
+ \fn TQDate& TQVariant::asDate()
+
+ Tries to convert the variant to hold a TQDate value. If that is not
+ possible then the variant is set to an invalid date.
+
+ Returns a reference to the stored date.
+
+ \sa toDate()
+*/
+
+/*!
+ \fn TQTime& TQVariant::asTime()
+
+ Tries to convert the variant to hold a TQTime value. If that is not
+ possible then the variant is set to an invalid time.
+
+ Returns a reference to the stored time.
+
+ \sa toTime()
+*/
+
+/*!
+ \fn TQDateTime& TQVariant::asDateTime()
+
+ Tries to convert the variant to hold a TQDateTime value. If that is
+ not possible then the variant is set to an invalid date/time.
+
+ Returns a reference to the stored date/time.
+
+ \sa toDateTime()
+*/
+
+/*!
+ \fn TQByteArray& TQVariant::asByteArray()
+
+ Tries to convert the variant to hold a TQByteArray value. If that
+ is not possible then the variant is set to an empty bytearray.
+
+ Returns a reference to the stored bytearray.
+
+ \sa toByteArray()
+*/
+
+/*!
+ \fn TQBitArray& TQVariant::asBitArray()
+
+ Tries to convert the variant to hold a TQBitArray value. If that is
+ not possible then the variant is set to an empty bitarray.
+
+ Returns a reference to the stored bitarray.
+
+ \sa toBitArray()
+*/
+
+/*!
+ \fn TQKeySequence& TQVariant::asKeySequence()
+
+ Tries to convert the variant to hold a TQKeySequence value. If that
+ is not possible then the variant is set to an empty key sequence.
+
+ Returns a reference to the stored key sequence.
+
+ \sa toKeySequence()
+*/
+
+/*! \fn TQPen& TQVariant::asPen()
+
+ Tries to convert the variant to hold a TQPen value. If that
+ is not possible then the variant is set to an empty pen.
+
+ Returns a reference to the stored pen.
+
+ \sa toPen()
+*/
+
+/*!
+ Returns the variant's value as int reference.
+*/
+int& TQVariant::asInt()
+{
+ detach();
+ if ( d->typ != Int ) {
+ int i = toInt();
+ bool b = isNull();
+ d->clear();
+ d->value.i = i;
+ d->typ = Int;
+ d->is_null = b;
+ }
+ return d->value.i;
+}
+
+/*!
+ Returns the variant's value as unsigned int reference.
+*/
+uint& TQVariant::asUInt()
+{
+ detach();
+ if ( d->typ != UInt ) {
+ uint u = toUInt();
+ bool b = isNull();
+ d->clear();
+ d->value.u = u;
+ d->typ = UInt;
+ d->is_null = b;
+ }
+ return d->value.u;
+}
+
+/*!
+ Returns the variant's value as long long reference.
+*/
+TQ_LLONG& TQVariant::asLongLong()
+{
+ detach();
+ if ( d->typ != LongLong ) {
+ TQ_LLONG ll = toLongLong();
+ bool b = isNull();
+ d->clear();
+ d->value.ll = ll;
+ d->typ = LongLong;
+ d->is_null = b;
+ }
+ return d->value.ll;
+}
+
+/*!
+ Returns the variant's value as unsigned long long reference.
+*/
+TQ_ULLONG& TQVariant::asULongLong()
+{
+ detach();
+ if ( d->typ != ULongLong ) {
+ TQ_ULLONG ull = toULongLong();
+ bool b = isNull();
+ d->clear();
+ d->value.ull = ull;
+ d->typ = ULongLong;
+ d->is_null = b;
+ }
+ return d->value.ull;
+}
+
+/*!
+ Returns the variant's value as bool reference.
+*/
+bool& TQVariant::asBool()
+{
+ detach();
+ if ( d->typ != Bool ) {
+ bool b = toBool();
+ bool nb = isNull();
+ d->clear();
+ d->value.b = b;
+ d->typ = Bool;
+ d->is_null = nb;
+ }
+ return d->value.b;
+}
+
+/*!
+ Returns the variant's value as double reference.
+*/
+double& TQVariant::asDouble()
+{
+ detach();
+ if ( d->typ != Double ) {
+ double dbl = toDouble();
+ bool b = isNull();
+ d->clear();
+ d->value.d = dbl;
+ d->typ = Double;
+ d->is_null = b;
+ }
+ return d->value.d;
+}
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+/*!
+ Returns the variant's value as variant list reference.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQVariant> list = myVariant.asList();
+ TQValueList<TQVariant>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQValueList<TQVariant>& TQVariant::asList()
+{
+ bool b = isNull();
+ if ( d->typ != List )
+ *this = TQVariant( toList() );
+ else
+ detach();
+ d->is_null = b;
+ return *((TQValueList<TQVariant>*)d->value.ptr);
+}
+
+/*!
+ Returns the variant's value as variant map reference.
+
+ Note that if you want to iterate over the map, you should iterate
+ over a copy, e.g.
+ \code
+ TQMap<TQString, TQVariant> map = myVariant.asMap();
+ TQMap<TQString, TQVariant>::Iterator it = map.begin();
+ while( it != map.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQMap<TQString, TQVariant>& TQVariant::asMap()
+{
+ bool b = isNull();
+ if ( d->typ != Map )
+ *this = TQVariant( toMap() );
+ else
+ detach();
+ d->is_null = b;
+ return *((TQMap<TQString,TQVariant>*)d->value.ptr);
+}
+#endif
+
+/*!
+ Returns TRUE if the variant's type can be cast to the requested
+ type, \a t. Such casting is done automatically when calling the
+ toInt(), toBool(), ... or asInt(), asBool(), ... methods.
+
+ The following casts are done automatically:
+ \table
+ \header \i Type \i Automatically Cast To
+ \row \i Bool \i Double, Int, UInt, LongLong, ULongLong, String, CString, ByteArray
+ \row \i Color \i String. CString. ByteArray
+ \row \i Date \i String, CString, ByteArray, DateTime
+ \row \i DateTime \i String, CString, ByteArray, Date, Time
+ \row \i Double \i String, CString, ByteArray, Int, Bool, UInt, LongLong, ULongLong
+ \row \i Font \i String, CString, ByteArray
+ \row \i Int \i String, CString, ByteArray, Double, Bool, UInt, LongLong, ULongLong, KeySequence
+ \row \i LongLong \i String, CString, ByteArray, Double, Bool, UInt, LongLong, ULongLong, KeySequence
+ \row \i ULongLong \i String, CString, ByteArray, Double, Bool, UInt, LongLong, ULongLong, KeySequence
+ \row \i List \i StringList (if the list tqcontains only strings or
+ something that can be cast to a string)
+ \row \i String \i CString, ByteArray, CString, Int, UInt, Bool, Double, Date,
+ Time, DateTime, KeySequence, Font, Color
+ \row \i CString \i String, ByteArray, Int, UInt, Bool, Double, Date, ULongLong, LongLong
+ \row \i ByteArray \i String, CString, Int, UInt, Bool, Double, Date, ULongLong, LongLong
+ \row \i StringList \i List
+ \row \i Time \i String
+ \row \i Int \i String, CString, ByteArray, Double, Bool, UInt, LongLong, ULongLong, KeySequence
+ \row \i KeySequence \i String, CString, ByteArray, Int, UInt, LongLong, ULongLong
+ \endtable
+*/
+bool TQVariant::canCast( Type t ) const
+{
+ if ( Type( d->typ ) == t )
+ return TRUE;
+
+ switch ( t ) {
+ case Bool:
+ case Double:
+ if (d->typ == KeySequence)
+ break;
+ case Int:
+ case UInt:
+ case LongLong:
+ case ULongLong:
+ switch(d->typ) {
+ case Bool:
+ case ByteArray:
+ case CString:
+ case Double:
+ case Int:
+ case KeySequence:
+ case LongLong:
+ case String:
+ case UInt:
+ case ULongLong:
+ return TRUE;
+ default: break;
+ }
+ break;
+
+ case CString:
+ case ByteArray:
+ case String:
+ switch(d->typ) {
+ case Bool:
+ case ByteArray:
+ case CString:
+ case Color:
+ case Date:
+ case DateTime:
+ case Double:
+ case Font:
+ case Int:
+ case KeySequence:
+ case LongLong:
+ case String:
+ case Time:
+ case UInt:
+ case ULongLong:
+ return TRUE;
+ default: break;
+ }
+ break;
+
+ case Time:
+ if (d->typ == Date)
+ break;
+ case Date:
+ case DateTime:
+ switch(d->typ) {
+ case ByteArray:
+ case CString:
+ case Date:
+ case DateTime:
+ case String:
+ return TRUE;
+ default: break;
+ }
+ break;
+
+ case KeySequence:
+ switch(d->typ) {
+ case ByteArray:
+ case CString:
+ case Int:
+ case UInt:
+ case LongLong:
+ case ULongLong:
+ case Double:
+ case String:
+ return TRUE;
+ default: break;
+ }
+ break;
+
+ case Font:
+ case Color:
+ switch(d->typ) {
+ case ByteArray:
+ case CString:
+ case String:
+ return TRUE;
+ default: break;
+ }
+ break;
+
+#ifndef TQT_NO_STRINGLIST
+ case List:
+ return d->typ == StringList;
+#endif
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case StringList:
+ if ( d->typ == List ) {
+ TQValueList<TQVariant>::ConstIterator it = listBegin();
+ TQValueList<TQVariant>::ConstIterator end = listEnd();
+ for( ; it != end; ++it ) {
+ if ( !(*it).canCast( String ) )
+ return FALSE;
+ }
+ return TRUE;
+ }
+#endif
+ case Invalid:
+ case Map:
+ case Pixmap:
+ case Brush:
+ case Rect:
+ case Size:
+ case Palette:
+ case ColorGroup:
+ case IconSet:
+ case Point:
+ case Image:
+ case PointArray:
+ case Region:
+ case Bitmap:
+ case Cursor:
+ case SizePolicy:
+ case BitArray:
+ case Pen:
+ break;
+ }
+ return FALSE;
+}
+
+/*!
+ Casts the variant to the requested type. If the cast cannot be
+ done, the variant is set to the default value of the requested
+ type (e.g. an empty string if the requested type \a t is
+ TQVariant::String, an empty point array if the requested type \a t
+ is TQVariant::PointArray, etc). Returns TRUE if the current type of
+ the variant was successfully cast; otherwise returns FALSE.
+
+ \sa canCast()
+*/
+
+bool TQVariant::cast( Type t )
+{
+ switch ( t ) {
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case TQVariant::Map:
+ asMap();
+ break;
+ case TQVariant::List:
+ asList();
+ break;
+#endif
+ case TQVariant::String:
+ asString();
+ break;
+#ifndef TQT_NO_STRINGLIST
+ case TQVariant::StringList:
+ asStringList();
+ break;
+#endif
+ case TQVariant::Font:
+ asFont();
+ break;
+ case TQVariant::Pixmap:
+ asPixmap();
+ break;
+ case TQVariant::Brush:
+ asBrush();
+ break;
+ case TQVariant::Rect:
+ asRect();
+ break;
+ case TQVariant::Size:
+ asSize();
+ break;
+ case TQVariant::Color:
+ asColor();
+ break;
+#ifndef TQT_NO_PALETTE
+ case TQVariant::Palette:
+ asPalette();
+ break;
+ case TQVariant::ColorGroup:
+ asColorGroup();
+ break;
+#endif
+#ifndef TQT_NO_ICONSET
+ case TQVariant::IconSet:
+ asIconSet();
+ break;
+#endif
+ case TQVariant::Point:
+ asPoint();
+ break;
+ case TQVariant::Image:
+ asImage();
+ break;
+ case TQVariant::Int:
+ asInt();
+ break;
+ case TQVariant::UInt:
+ asUInt();
+ break;
+ case TQVariant::Bool:
+ asBool();
+ break;
+ case TQVariant::Double:
+ asDouble();
+ break;
+ case TQVariant::CString:
+ asCString();
+ break;
+ case TQVariant::PointArray:
+ asPointArray();
+ break;
+ case TQVariant::Region:
+ asRegion();
+ break;
+ case TQVariant::Bitmap:
+ asBitmap();
+ break;
+ case TQVariant::Cursor:
+ asCursor();
+ break;
+ case TQVariant::SizePolicy:
+ asSizePolicy();
+ break;
+ case TQVariant::Date:
+ asDate();
+ break;
+ case TQVariant::Time:
+ asTime();
+ break;
+ case TQVariant::DateTime:
+ asDateTime();
+ break;
+ case TQVariant::ByteArray:
+ asByteArray();
+ break;
+ case TQVariant::BitArray:
+ asBitArray();
+ break;
+#ifndef TQT_NO_ACCEL
+ case TQVariant::KeySequence:
+ asKeySequence();
+ break;
+#endif
+ case TQVariant::Pen:
+ asPen();
+ break;
+ case TQVariant::LongLong:
+ asLongLong();
+ break;
+ case TQVariant::ULongLong:
+ asULongLong();
+ break;
+ default:
+ case TQVariant::Invalid:
+ (*this) = TQVariant();
+ }
+ return canCast( t );
+}
+
+/*!
+ Compares this TQVariant with \a v and returns TRUE if they are
+ equal; otherwise returns FALSE.
+*/
+
+bool TQVariant::operator==( const TQVariant &v ) const
+{
+ if (isNumeric(v.type()) && canCast(v.type())) {
+ bool ok;
+ switch(v.type()) {
+ case Bool:
+ return toBool() == v.toBool();
+ case Int:
+ {
+ int val = toInt(&ok);
+ return (ok && val == v.toInt());
+ }
+ case UInt:
+ {
+ uint val = toUInt(&ok);
+ return (ok && val == v.toUInt());
+ }
+
+ case Double:
+ {
+ double val = toDouble(&ok);
+ return (ok && val == v.toDouble());
+ }
+
+ case LongLong:
+ {
+ TQ_LLONG val = toLongLong(&ok);
+ return (ok && val == v.toLongLong());
+ }
+
+ case ULongLong:
+ {
+ TQ_ULLONG val = toULongLong(&ok);
+ return (ok && val == v.toULongLong());
+ }
+
+ default:
+ TQ_ASSERT(FALSE);
+ }
+ }
+
+ if (!v.canCast(d->typ)) {
+ return FALSE;
+ }
+
+ switch( d->typ ) {
+ case Cursor:
+#ifndef TQT_NO_CURSOR
+ return v.toCursor().tqshape() == toCursor().tqshape();
+#endif
+ case Bitmap:
+ return v.toBitmap().serialNumber() == toBitmap().serialNumber();
+ case PointArray:
+ return v.toPointArray() == toPointArray();
+ case Region:
+ return v.toRegion() == toRegion();
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case List:
+ return v.toList() == toList();
+ case Map: {
+ if ( v.toMap().count() != toMap().count() )
+ return FALSE;
+ TQMap<TQString, TQVariant>::ConstIterator it = v.toMap().begin();
+ TQMap<TQString, TQVariant>::ConstIterator it2 = toMap().begin();
+ while ( it != v.toMap().end() ) {
+ if ( *it != *it2 )
+ return FALSE;
+ ++it;
+ ++it2;
+ }
+ return TRUE;
+ }
+#endif
+ case String:
+ return v.toString() == toString();
+ case CString:
+ return v.toCString() == toCString();
+#ifndef TQT_NO_STRINGLIST
+ case StringList:
+ return v.toStringList() == toStringList();
+#endif
+ case Font:
+ return v.toFont() == toFont();
+ case Pixmap:
+ return v.toPixmap().serialNumber() == toPixmap().serialNumber();
+ case Image:
+ return v.toImage() == toImage();
+ case Brush:
+ return v.toBrush() == toBrush();
+ case Point:
+ return v.toPoint() == toPoint();
+ case Rect:
+ return v.toRect() == toRect();
+ case Size:
+ return v.toSize() == toSize();
+ case Color:
+ return v.toColor() == toColor();
+#ifndef TQT_NO_PALETTE
+ case Palette:
+ return v.toPalette() == toPalette();
+ case ColorGroup:
+ return v.toColorGroup() == toColorGroup();
+#endif
+#ifndef TQT_NO_ICONSET
+ case IconSet:
+ return v.toIconSet().pixmap().serialNumber()
+ == toIconSet().pixmap().serialNumber();
+#endif
+ case Int:
+ return v.toInt() == toInt();
+ case UInt:
+ return v.toUInt() == toUInt();
+ case LongLong:
+ return v.toLongLong() == toLongLong();
+ case ULongLong:
+ return v.toULongLong() == toULongLong();
+ case Bool:
+ return v.toBool() == toBool();
+ case Double:
+ return v.toDouble() == toDouble();
+ case SizePolicy:
+ return v.toSizePolicy() == toSizePolicy();
+ case Date:
+ return v.toDate() == toDate();
+ case Time:
+ return v.toTime() == toTime();
+ case DateTime:
+ return v.toDateTime() == toDateTime();
+ case ByteArray:
+ return v.toByteArray() == toByteArray();
+ case BitArray:
+ return v.toBitArray() == toBitArray();
+#ifndef TQT_NO_ACCEL
+ case KeySequence:
+ return v.toKeySequence() == toKeySequence();
+#endif
+ case Pen:
+ return v.toPen() == toPen();
+ case Invalid:
+ break;
+ }
+ return FALSE;
+}
+
+/*!
+ Compares this TQVariant with \a v and returns TRUE if they are not
+ equal; otherwise returns FALSE.
+*/
+
+bool TQVariant::operator!=( const TQVariant &v ) const
+{
+ return !( v == *this );
+}
+
+
+/*! \internal
+
+ Reads or sets the variant type and ptr
+ */
+void* TQVariant::rawAccess( void* ptr, Type typ, bool deepCopy )
+{
+ if ( ptr ) {
+ clear();
+ d->typ = typ;
+ d->value.ptr = ptr;
+ d->is_null = FALSE;
+ if ( deepCopy ) {
+ TQVariant::Private* p = new Private( d );
+ d->typ = Invalid;
+ delete d;
+ d = p;
+ }
+ }
+
+ if ( !deepCopy )
+ return d->value.ptr;
+ TQVariant::Private* p = new Private( d );
+ void *ret = (void*)p->value.ptr;
+ p->typ = Invalid;
+ delete p;
+ return ret;
+}
+
+/*!
+ Returns TRUE if this is a NULL variant, FALSE otherwise.
+*/
+bool TQVariant::isNull() const
+{
+ switch( d->typ )
+ {
+ case TQVariant::Bitmap:
+ return ((TQBitmap*) d->value.ptr)->isNull();
+ case TQVariant::Region:
+ return ((TQRegion*) d->value.ptr)->isNull();
+ case TQVariant::PointArray:
+ return ((TQPointArray*) d->value.ptr)->isNull();
+ case TQVariant::String:
+ return ((TQString*) d->value.ptr)->isNull();
+ case TQVariant::CString:
+ return ((TQCString*) d->value.ptr)->isNull();
+ case TQVariant::Pixmap:
+ return ((TQPixmap*) d->value.ptr)->isNull();
+ case TQVariant::Image:
+ return ((TQImage*) d->value.ptr)->isNull();
+ case TQVariant::Point:
+ return ((TQPoint*) d->value.ptr)->isNull();
+ case TQVariant::Rect:
+ return ((TQRect*) d->value.ptr)->isNull();
+ case TQVariant::Size:
+ return ((TQSize*) d->value.ptr)->isNull();
+#ifndef TQT_NO_ICONSET
+ case TQVariant::IconSet:
+ return ((TQIconSet*) d->value.ptr)->isNull();
+#endif
+ case TQVariant::Date:
+ return ((TQDate*) d->value.ptr)->isNull();
+ case TQVariant::Time:
+ return ((TQTime*) d->value.ptr)->isNull();
+ case TQVariant::DateTime:
+ return ((TQDateTime*) d->value.ptr)->isNull();
+ case TQVariant::ByteArray:
+ return ((TQByteArray*) d->value.ptr)->isNull();
+ case TQVariant::BitArray:
+ return ((TQBitArray*) d->value.ptr)->isNull();
+ case TQVariant::Cursor:
+#ifndef TQT_NO_STRINGLIST
+ case TQVariant::StringList:
+#endif //TQT_NO_STRINGLIST
+ case TQVariant::Font:
+ case TQVariant::Brush:
+ case TQVariant::Color:
+#ifndef TQT_NO_PALETTE
+ case TQVariant::Palette:
+ case TQVariant::ColorGroup:
+#endif
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ case TQVariant::Map:
+ case TQVariant::List:
+#endif
+ case TQVariant::SizePolicy:
+#ifndef TQT_NO_ACCEL
+ case TQVariant::KeySequence:
+#endif
+ case TQVariant::Pen:
+ case TQVariant::Invalid:
+ case TQVariant::Int:
+ case TQVariant::UInt:
+ case TQVariant::LongLong:
+ case TQVariant::ULongLong:
+ case TQVariant::Bool:
+ case TQVariant::Double:
+ break;
+ }
+ return d->is_null;
+}
+#endif //TQT_NO_VARIANT
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/kernel/tqvariant.h b/tqtinterface/qt4/src/kernel/tqvariant.h
new file mode 100644
index 0000000..5fb5e65
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqvariant.h
@@ -0,0 +1,642 @@
+/****************************************************************************
+**
+** Definition of TQVariant class
+**
+** Created : 990414
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQVARIANT_H
+#define TQVARIANT_H
+
+#include "tqtglobaldefines.h"
+#include "tqnamespace.h"
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include "tqvaluelist.h"
+#include "tqstringlist.h"
+#include "tqmap.h"
+#include <Qt/qvariant.h>
+
+#endif // USE_QT4
+
+#ifndef TQT_NO_VARIANT
+class TQString;
+class TQCString;
+class TQFont;
+class TQPixmap;
+class TQBrush;
+class TQRect;
+class TQPoint;
+class TQImage;
+class TQSize;
+class TQColor;
+class TQPalette;
+class TQColorGroup;
+class TQIconSet;
+class TQDataStream;
+class TQPointArray;
+class TQRegion;
+class TQBitmap;
+class TQCursor;
+class TQStringList;
+class TQSizePolicy;
+class TQDate;
+class TQTime;
+class TQDateTime;
+class TQBitArray;
+class TQKeySequence;
+class TQPen;
+// Some headers rejected after TQVariant declaration for GCC 2.7.* compatibility
+class TQVariant;
+#ifndef TQT_NO_TEMPLATE_VARIANT
+template <class T> class TQValueList;
+template <class T> class TQValueListConstIterator;
+template <class T> class TQValueListNode;
+template <class Key, class T> class TQMap;
+template <class Key, class T> class TQMapConstIterator;
+#endif
+
+#ifdef USE_QT4
+
+#include "tqtenuminheritance.h"
+
+class TQ_EXPORT TQVariant : public QVariant, virtual public TQt
+{
+public:
+ // [FIXME] Should these line up with a Qt4 structure?
+ // Also, make sure they don't collide with QVariant::Type!
+ enum TQV_NewTypes {
+ CString = (QVariant::Type)150,
+ ColorGroup = (QVariant::Type)151,
+ IconSet = (QVariant::Type)152,
+ PointArray = (QVariant::Type)153
+ };
+// typedef TQTInheritEnum< TQV_NewTypes, QVariant::Type > Type;
+ typedef TQTInheritEnum< TQV_NewTypes, QVariant::Type > TQType;
+
+ TQVariant() : QVariant() {}
+ TQVariant( const QVariant &s );
+#ifndef TQT_NO_DATASTREAM
+ TQVariant( TQDataStream &s );
+#endif
+ TQVariant( const TQString &s );
+ TQVariant( const TQCString &s );
+ TQVariant( const char *s );
+#ifndef TQT_NO_STRINGLIST
+ TQVariant( const TQStringList &s );
+#endif
+ TQVariant( const TQFont &s );
+ TQVariant( const TQPixmap &s );
+ TQVariant( const TQImage &s );
+ TQVariant( const TQBrush &s );
+ TQVariant( const TQPoint &s );
+ TQVariant( const TQRect &s );
+ TQVariant( const TQSize &s );
+ TQVariant( const TQColor &s );
+ TQVariant( const TQPalette &s );
+ TQVariant( const TQColorGroup &s );
+ TQVariant( const TQIconSet &s );
+ TQVariant( const TQPointArray &s );
+ TQVariant( const TQRegion &s );
+ TQVariant( const TQBitmap &s );
+ TQVariant( const TQCursor &s );
+ TQVariant( const TQDate &s );
+ TQVariant( const TQTime &s );
+ TQVariant( const TQDateTime &s );
+ TQVariant( const TQByteArray &s );
+ TQVariant( const TQBitArray &s );
+#ifndef TQT_NO_ACCEL
+ TQVariant( const TQKeySequence &s );
+#endif
+ TQVariant( const TQPen &s );
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ TQVariant( const TQValueList<TQVariant>&s );
+ TQVariant( const TQMap<TQString,TQVariant>&s );
+#endif
+ TQVariant( int s ) : QVariant( s ) {}
+ TQVariant( uint s ) : QVariant( s ) {}
+ TQVariant( TQ_LLONG s ) : QVariant( s ) {}
+ TQVariant( TQ_ULLONG s ) : QVariant( s ) {}
+// TQVariant( bool s, int t ) : QVariant( s, t ) {}
+ TQVariant( bool s, int t ) : QVariant( s ) { TQ_UNUSED(t); }
+ TQVariant( double s ) : QVariant( s ) {}
+ TQVariant( TQSizePolicy s );
+
+ const TQFont toFont() const;
+
+ inline bool canCast(Type t) const { return canConvert(t); }
+ inline bool cast(Type t) { return convert(t); }
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ TQValueListConstIterator<TQString> stringListBegin() const;
+ TQValueListConstIterator<TQString> stringListEnd() const;
+ TQValueListConstIterator<TQVariant> listBegin() const;
+ TQValueListConstIterator<TQVariant> listEnd() const;
+ TQMapConstIterator<TQString,TQVariant> mapBegin() const;
+ TQMapConstIterator<TQString,TQVariant> mapEnd() const;
+ TQMapConstIterator<TQString,TQVariant> mapFind( const TQString& ) const;
+#endif
+
+ TQString& asString();
+ TQCString& asCString();
+#ifndef TQT_NO_STRINGLIST
+ TQStringList& asStringList();
+#endif
+ TQFont& asFont();
+ TQPixmap& asPixmap();
+ TQImage& asImage();
+ TQBrush& asBrush();
+ TQPoint& asPoint();
+ TQRect& asRect();
+ TQSize& asSize();
+ TQColor& asColor();
+ TQPalette& asPalette();
+ TQColorGroup& asColorGroup();
+ TQIconSet& asIconSet();
+ TQPointArray& asPointArray();
+ TQBitmap& asBitmap();
+ TQRegion& asRegion();
+ TQCursor& asCursor();
+ TQDate& asDate();
+ TQTime& asTime();
+ TQDateTime& asDateTime();
+ TQByteArray& asByteArray();
+ TQBitArray& asBitArray();
+#ifndef TQT_NO_ACCEL
+ TQKeySequence& asKeySequence();
+#endif
+ TQPen& asPen();
+ int& asInt();
+ uint& asUInt();
+ TQ_LLONG& asLongLong();
+ TQ_ULLONG& asULongLong();
+ bool& asBool();
+ double& asDouble();
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ TQValueList<TQVariant>& asList();
+ TQMap<TQString,TQVariant>& asMap();
+#endif
+ TQSizePolicy& asSizePolicy();
+
+ const TQString toString() const;
+ const TQCString toCString() const;
+#ifndef TQT_NO_STRINGLIST
+ const TQStringList toStringList() const;
+#endif
+// const TQFont toFont() const;
+ const TQPixmap toPixmap() const;
+ const TQImage toImage() const;
+ const TQBrush toBrush() const;
+ const TQPoint toPoint() const;
+ const TQRect toRect() const;
+ const TQSize toSize() const;
+ const TQColor toColor() const;
+ const TQPalette toPalette() const;
+ const TQColorGroup toColorGroup() const;
+ const TQIconSet toIconSet() const;
+ const TQPointArray toPointArray() const;
+ const TQBitmap toBitmap() const;
+ const TQRegion toRegion() const;
+ const TQCursor toCursor() const;
+ const TQDate toDate() const;
+ const TQTime toTime() const;
+ const TQDateTime toDateTime() const;
+ const TQByteArray toByteArray() const;
+ const TQBitArray toBitArray() const;
+#ifndef TQT_NO_ACCEL
+ const TQKeySequence toKeySequence() const;
+#endif
+ const TQPen toPen() const;
+// int toInt( bool * ok=0 ) const;
+// uint toUInt( bool * ok=0 ) const;
+// TQ_LLONG toLongLong( bool * ok=0 ) const;
+// TQ_ULLONG toULongLong( bool * ok=0 ) const;
+// bool toBool() const;
+// double toDouble( bool * ok=0 ) const;
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ const TQValueList<TQVariant> toList() const;
+ const TQMap<TQString,TQVariant> toMap() const;
+#endif
+ TQSizePolicy toSizePolicy() const;
+
+// using QVariant::operator=;
+// TQVariant& operator= ( const QVariant& );
+// inline TQVariant& operator= ( const QVariant&v ) {
+// QVariant& ref = QVariant::operator=(v);
+// return static_cast<TQVariant*>(&ref);
+// }
+
+public:
+ // Interoperability
+ static const TQVariant& convertFromQVariant( QVariant& qvr );
+};
+
+// Interoperability
+inline static const TQVariant& convertFromQVariant( const QVariant& qvr ) {
+ return (*static_cast<const TQVariant*>(&qvr));
+}
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+inline TQValueListConstIterator<TQString> TQVariant::stringListBegin() const
+{
+ if ( d.type != StringList )
+ return TQValueListConstIterator<TQString>();
+ return ((const TQStringList*)d.data.ptr)->begin();
+}
+
+inline TQValueListConstIterator<TQString> TQVariant::stringListEnd() const
+{
+ if ( d.type != StringList )
+ return TQValueListConstIterator<TQString>();
+ return ((const TQStringList*)d.data.ptr)->end();
+}
+
+inline TQValueListConstIterator<TQVariant> TQVariant::listBegin() const
+{
+ if ( d.type != List )
+ return TQValueListConstIterator<TQVariant>();
+ return ((const TQValueList<TQVariant>*)d.data.ptr)->begin();
+}
+
+inline TQValueListConstIterator<TQVariant> TQVariant::listEnd() const
+{
+ if ( d.type != List )
+ return TQValueListConstIterator<TQVariant>();
+ return ((const TQValueList<TQVariant>*)d.data.ptr)->end();
+}
+
+inline TQMapConstIterator<TQString,TQVariant> TQVariant::mapBegin() const
+{
+ if ( d.type != Map )
+ return TQMapConstIterator<TQString,TQVariant>();
+ return ((const TQMap<TQString,TQVariant>*)d.data.ptr)->begin();
+}
+
+inline TQMapConstIterator<TQString,TQVariant> TQVariant::mapEnd() const
+{
+ if ( d.type != Map )
+ return TQMapConstIterator<TQString,TQVariant>();
+ return ((const TQMap<TQString,TQVariant>*)d.data.ptr)->end();
+}
+
+inline TQMapConstIterator<TQString,TQVariant> TQVariant::mapFind( const TQString& key ) const
+{
+ if ( d.type != Map )
+ return TQMapConstIterator<TQString,TQVariant>();
+ return ((const TQMap<TQString,TQVariant>*)d.data.ptr)->tqfind( key );
+}
+#endif
+
+#else // USE_QT4
+
+class TQ_EXPORT TQVariant
+{
+public:
+ enum Type {
+ Invalid,
+ Map,
+ List,
+ String,
+ StringList,
+ Font,
+ Pixmap,
+ Brush,
+ Rect,
+ Size,
+ Color,
+ Palette,
+ ColorGroup,
+ IconSet,
+ Point,
+ Image,
+ Int,
+ UInt,
+ Bool,
+ Double,
+ CString,
+ PointArray,
+ Region,
+ Bitmap,
+ Cursor,
+ SizePolicy,
+ Date,
+ Time,
+ DateTime,
+ ByteArray,
+ BitArray,
+ KeySequence,
+ Pen,
+ LongLong,
+ ULongLong
+ };
+
+ TQVariant();
+ ~TQVariant();
+ TQVariant( const TQVariant& );
+#ifndef TQT_NO_DATASTREAM
+ TQVariant( TQDataStream& s );
+#endif
+ TQVariant( const TQString& );
+ TQVariant( const TQCString& );
+ TQVariant( const char* );
+#ifndef TQT_NO_STRINGLIST
+ TQVariant( const TQStringList& );
+#endif
+ TQVariant( const TQFont& );
+ TQVariant( const TQPixmap& );
+ TQVariant( const TQImage& );
+ TQVariant( const TQBrush& );
+ TQVariant( const TQPoint& );
+ TQVariant( const TQRect& );
+ TQVariant( const TQSize& );
+ TQVariant( const TQColor& );
+ TQVariant( const TQPalette& );
+ TQVariant( const TQColorGroup& );
+ TQVariant( const TQIconSet& );
+ TQVariant( const TQPointArray& );
+ TQVariant( const TQRegion& );
+ TQVariant( const TQBitmap& );
+ TQVariant( const TQCursor& );
+ TQVariant( const TQDate& );
+ TQVariant( const TQTime& );
+ TQVariant( const TQDateTime& );
+ TQVariant( const TQByteArray& );
+ TQVariant( const TQBitArray& );
+#ifndef TQT_NO_ACCEL
+ TQVariant( const TQKeySequence& );
+#endif
+ TQVariant( const TQPen& );
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ TQVariant( const TQValueList<TQVariant>& );
+ TQVariant( const TQMap<TQString,TQVariant>& );
+#endif
+ TQVariant( int );
+ TQVariant( uint );
+ TQVariant( TQ_LLONG );
+ TQVariant( TQ_ULLONG );
+ // ### Problems on some compilers ?
+ TQVariant( bool, int );
+ TQVariant( double );
+ TQVariant( TQSizePolicy );
+
+ TQVariant& operator= ( const TQVariant& );
+ bool operator==( const TQVariant& ) const;
+ bool operator!=( const TQVariant& ) const;
+
+ Type type() const;
+ const char* typeName() const;
+
+ bool canCast( Type ) const;
+ bool cast( Type );
+
+ bool isValid() const;
+ bool isNull() const;
+
+ void clear();
+
+ const TQString toString() const;
+ const TQCString toCString() const;
+#ifndef TQT_NO_STRINGLIST
+ const TQStringList toStringList() const;
+#endif
+ const TQFont toFont() const;
+ const TQPixmap toPixmap() const;
+ const TQImage toImage() const;
+ const TQBrush toBrush() const;
+ const TQPoint toPoint() const;
+ const TQRect toRect() const;
+ const TQSize toSize() const;
+ const TQColor toColor() const;
+ const TQPalette toPalette() const;
+ const TQColorGroup toColorGroup() const;
+ const TQIconSet toIconSet() const;
+ const TQPointArray toPointArray() const;
+ const TQBitmap toBitmap() const;
+ const TQRegion toRegion() const;
+ const TQCursor toCursor() const;
+ const TQDate toDate() const;
+ const TQTime toTime() const;
+ const TQDateTime toDateTime() const;
+ const TQByteArray toByteArray() const;
+ const TQBitArray toBitArray() const;
+#ifndef TQT_NO_ACCEL
+ const TQKeySequence toKeySequence() const;
+#endif
+ const TQPen toPen() const;
+ int toInt( bool * ok=0 ) const;
+ uint toUInt( bool * ok=0 ) const;
+ TQ_LLONG toLongLong( bool * ok=0 ) const;
+ TQ_ULLONG toULongLong( bool * ok=0 ) const;
+ bool toBool() const;
+ double toDouble( bool * ok=0 ) const;
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ const TQValueList<TQVariant> toList() const;
+ const TQMap<TQString,TQVariant> toMap() const;
+#endif
+ TQSizePolicy toSizePolicy() const;
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ TQValueListConstIterator<TQString> stringListBegin() const;
+ TQValueListConstIterator<TQString> stringListEnd() const;
+ TQValueListConstIterator<TQVariant> listBegin() const;
+ TQValueListConstIterator<TQVariant> listEnd() const;
+ TQMapConstIterator<TQString,TQVariant> mapBegin() const;
+ TQMapConstIterator<TQString,TQVariant> mapEnd() const;
+ TQMapConstIterator<TQString,TQVariant> mapFind( const TQString& ) const;
+#endif
+ TQString& asString();
+ TQCString& asCString();
+#ifndef TQT_NO_STRINGLIST
+ TQStringList& asStringList();
+#endif
+ TQFont& asFont();
+ TQPixmap& asPixmap();
+ TQImage& asImage();
+ TQBrush& asBrush();
+ TQPoint& asPoint();
+ TQRect& asRect();
+ TQSize& asSize();
+ TQColor& asColor();
+ TQPalette& asPalette();
+ TQColorGroup& asColorGroup();
+ TQIconSet& asIconSet();
+ TQPointArray& asPointArray();
+ TQBitmap& asBitmap();
+ TQRegion& asRegion();
+ TQCursor& asCursor();
+ TQDate& asDate();
+ TQTime& asTime();
+ TQDateTime& asDateTime();
+ TQByteArray& asByteArray();
+ TQBitArray& asBitArray();
+#ifndef TQT_NO_ACCEL
+ TQKeySequence& asKeySequence();
+#endif
+ TQPen& asPen();
+ int& asInt();
+ uint& asUInt();
+ TQ_LLONG& asLongLong();
+ TQ_ULLONG& asULongLong();
+ bool& asBool();
+ double& asDouble();
+#ifndef TQT_NO_TEMPLATE_VARIANT
+ TQValueList<TQVariant>& asList();
+ TQMap<TQString,TQVariant>& asMap();
+#endif
+ TQSizePolicy& asSizePolicy();
+
+#ifndef TQT_NO_DATASTREAM
+ void load( TQDataStream& );
+ void save( TQDataStream& ) const;
+#endif
+ static const char* typeToName( Type typ );
+ static Type nameToType( const char* name );
+
+private:
+ void detach();
+
+ class Private : public TQShared
+ {
+ public:
+ Private();
+ Private( Private* );
+ ~Private();
+
+ void clear();
+
+ Type typ;
+ union
+ {
+ uint u;
+ int i;
+ TQ_LLONG ll;
+ TQ_ULLONG ull;
+ bool b;
+ double d;
+ void *ptr;
+ } value;
+ uint is_null : 1; // ## 4.0 merge with typ
+ };
+
+ Private* d;
+
+public:
+ void* rawAccess( void* ptr = 0, Type typ = Invalid, bool deepCopy = FALSE );
+};
+
+// down here for GCC 2.7.* compatibility
+#ifndef TQT_H
+#include "tqvaluelist.h"
+#include "tqstringlist.h"
+#include "tqmap.h"
+#endif // TQT_H
+
+inline TQVariant::Type TQVariant::type() const
+{
+ return d->typ;
+}
+
+inline bool TQVariant::isValid() const
+{
+ return (d->typ != Invalid);
+}
+
+#ifndef TQT_NO_TEMPLATE_VARIANT
+inline TQValueListConstIterator<TQString> TQVariant::stringListBegin() const
+{
+ if ( d->typ != StringList )
+ return TQValueListConstIterator<TQString>();
+ return ((const TQStringList*)d->value.ptr)->begin();
+}
+
+inline TQValueListConstIterator<TQString> TQVariant::stringListEnd() const
+{
+ if ( d->typ != StringList )
+ return TQValueListConstIterator<TQString>();
+ return ((const TQStringList*)d->value.ptr)->end();
+}
+
+inline TQValueListConstIterator<TQVariant> TQVariant::listBegin() const
+{
+ if ( d->typ != List )
+ return TQValueListConstIterator<TQVariant>();
+ return ((const TQValueList<TQVariant>*)d->value.ptr)->begin();
+}
+
+inline TQValueListConstIterator<TQVariant> TQVariant::listEnd() const
+{
+ if ( d->typ != List )
+ return TQValueListConstIterator<TQVariant>();
+ return ((const TQValueList<TQVariant>*)d->value.ptr)->end();
+}
+
+inline TQMapConstIterator<TQString,TQVariant> TQVariant::mapBegin() const
+{
+ if ( d->typ != Map )
+ return TQMapConstIterator<TQString,TQVariant>();
+ return ((const TQMap<TQString,TQVariant>*)d->value.ptr)->begin();
+}
+
+inline TQMapConstIterator<TQString,TQVariant> TQVariant::mapEnd() const
+{
+ if ( d->typ != Map )
+ return TQMapConstIterator<TQString,TQVariant>();
+ return ((const TQMap<TQString,TQVariant>*)d->value.ptr)->end();
+}
+
+inline TQMapConstIterator<TQString,TQVariant> TQVariant::mapFind( const TQString& key ) const
+{
+ if ( d->typ != Map )
+ return TQMapConstIterator<TQString,TQVariant>();
+ return ((const TQMap<TQString,TQVariant>*)d->value.ptr)->tqfind( key );
+}
+#endif
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream& operator>> ( TQDataStream& s, TQVariant& p );
+TQ_EXPORT TQDataStream& operator<< ( TQDataStream& s, const TQVariant& p );
+TQ_EXPORT TQDataStream& operator>> ( TQDataStream& s, TQVariant::Type& p );
+TQ_EXPORT TQDataStream& operator<< ( TQDataStream& s, const TQVariant::Type p );
+#endif
+
+#endif // TQT_NO_VARIANT
+#endif // USE_QT4
+#endif // TQVARIANT_H
diff --git a/tqtinterface/qt4/src/kernel/tqvfbhdr.h b/tqtinterface/qt4/src/kernel/tqvfbhdr.h
new file mode 100644
index 0000000..138a356
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqvfbhdr.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** TQt/Embedded virtual framebuffer
+**
+** Created : 20000605
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQVFBHDR_H
+#define TQVFBHDR_H
+
+#ifndef TQT_H
+#include "tqcolor.h"
+#include "tqrect.h"
+#endif // TQT_H
+
+#define TQT_VFB_MOUSE_PIPE "/tmp/.qtvfb_mouse-%1"
+#define TQT_VFB_KEYBOARD_PIPE "/tmp/.qtvfb_keyboard-%1"
+
+struct TQVFbHeader
+{
+ int width;
+ int height;
+ int depth;
+ int linestep;
+ int dataoffset;
+ TQRect update;
+ bool dirty;
+ int numcols;
+ TQRgb clut[256];
+};
+
+struct TQVFbKeyData
+{
+ unsigned int tqunicode;
+ unsigned int modifiers;
+ bool press;
+ bool repeat;
+};
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqwidget.cpp b/tqtinterface/qt4/src/kernel/tqwidget.cpp
new file mode 100644
index 0000000..3bfdd86
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwidget.cpp
@@ -0,0 +1,8728 @@
+/****************************************************************************
+**
+** Implementation of TQWidget class
+**
+** Created : 931031
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+
+#include "tqobjectlist.h"
+#include "tqwidget.h"
+#include "tqwidgetlist.h"
+#include "tqwidgetintdict.h"
+#include "tqptrdict.h"
+#include "tqfocusdata.h"
+#include "tqcursor.h"
+#include "tqpixmap.h"
+#include "tqapplication.h"
+#include "tqapplication_p.h"
+#include "tqbrush.h"
+#include "tqlayout.h"
+#include "tqstylefactory.h"
+#include "tqcleanuphandler.h"
+#include "tqstyle.h"
+#include "tqmetaobject.h"
+#include "tqguardedptr.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+#if defined(TQ_WS_WIN)
+#include "tqt_windows.h"
+#include "tqinputcontext_p.h"
+#endif
+#if defined(TQ_WS_TQWS)
+#include "tqwsmanager_qws.h"
+#endif
+#include "tqfontdata_p.h"
+
+#ifdef USE_QT4
+
+TQObject* convertFromTQT_BASE_OBJECT_NAMEPointer( TQT_BASE_OBJECT_NAME* x ) {
+ return static_cast<TQObject*>(static_cast<TQT_BASE_OBJECT_NAME*>(x));
+}
+
+const TQObject* convertFromTQT_BASE_OBJECT_NAMEPointerConst( const TQT_BASE_OBJECT_NAME* x ) {
+ return static_cast<const TQObject*>(static_cast<const TQT_BASE_OBJECT_NAME*>(x));
+}
+
+void TQWidget::reparent(QWidget *parent, const QPoint &p, bool showIt) {
+ setParent(parent, windowFlags() & ~Qt::WindowType_Mask);
+ setGeometry(p.x(),p.y(),width(),height());
+ if (showIt) show();
+}
+
+bool TQWidget::close(bool alsoDelete) {
+ QPointer<QWidget> that = this;
+ bool accepted = QWidget::close();
+ if (alsoDelete && accepted && that)
+ deleteLater();
+ return accepted;
+}
+
+// void TQWidget::showEvent(QShowEvent *e) {
+// // if (!testAttribute(Qt::WA_Resized) && (isWindow() || !layout())) // Logic taken from Qt4 qwidget.cpp tqsetVisible...
+// // if (!testAttribute(Qt::WA_Resized))
+// // if (!isVisible())
+// // adjustSize(); // NOTE: Qt4 does not allow adjustSize to be overridden, therefore it must be called here
+// if (isVisible()) {
+// // setAttribute(Qt::WA_Resized, TRUE); //not a user resize
+// if (tqt_internal_show_called_event == FALSE) show(); // NOTE: Qt4 does not allow show to be overridden, therefore it must be called here
+// // if ( !isTopLevel() && parentWidget() ) QApplication::postEvent( parentWidget(), new TQEvent( TQEvent::LayoutHint) ); // Needed for layouts to work
+// tqt_internal_show_called_event = FALSE;
+// }
+// showEvent(static_cast<TQShowEvent*>(e));
+// }
+
+uint TQWidget::windowState() const {
+ return (uint)(QWidget::windowState());
+}
+
+void TQWidget::setWindowState(uint newstate) {
+ QWidget::setWindowState((Qt::WindowStates)newstate);
+}
+
+void TQWidget::showEvent(QShowEvent *e) {
+ if (isVisible()) {
+ // Spontaneous event
+ if (tqt_internal_show_called_event == FALSE) show(); // NOTE: Qt4 does not allow show to be overridden, therefore it must be called here
+ showEvent(static_cast<TQShowEvent*>(e));
+ }
+ else {
+ // Non-spontaneous event
+ showEvent(static_cast<TQShowEvent*>(e));
+ if (tqt_internal_show_called_event == FALSE) show(); // NOTE: Qt4 does not allow show to be overridden, therefore it must be called here
+ }
+ tqt_internal_show_called_event = FALSE;
+}
+
+void TQWidget::hideEvent(QHideEvent *e) {
+ hideEvent(static_cast<TQHideEvent*>(e));
+ if ( !isTopLevel() && parentWidget() ) QApplication::postEvent( parentWidget(), new TQEvent( TQEvent::LayoutHint) ); // Needed for layouts to work
+}
+
+void TQWidget::show() {
+ if ( testWState(WState_Visible) )
+ return;
+ tqt_internal_show_called_event = TRUE;
+ if ( !isTopLevel() && parentWidget() )
+ QApplication::postEvent( parentWidget(), new TQEvent( TQEvent::LayoutHint) ); // Needed for layouts to work
+ if (parentWidget()) {
+ if ( !isTopLevel() && !parentWidget()->isVisible() ) {
+ // return;
+ }
+ }
+ else {
+ QApplication::sendPostedEvents( this, TQEvent::ChildInserted );
+ if ( parentWidget() )
+ QApplication::sendPostedEvents( parentWidget(), TQEvent::ChildInserted );
+ // Required for Mac, not sure whether we should always do that [this? see tqwidget.cpp ::show() for Qt3.3]
+ if( isTopLevel() )
+ QApplication::sendPostedEvents(0, TQEvent::LayoutHint);
+ }
+ QWidget::show();
+}
+
+TQWidget* TQWidget::tqt_ensure_valid_widget_painting(TQWidget* w) {
+ if (w) w->setAttribute(Qt::WA_PaintOutsidePaintEvent, TRUE);
+ return w;
+}
+
+void TQWidget::showWindow() {
+ printf("[FIXME] TQWidget::showWindow unimplemented\n\r");
+}
+
+void TQWidget::hideWindow() {
+ printf("[FIXME] TQWidget::hideWindow unimplemented\n\r");
+}
+
+void TQWidget::timerEvent(QTimerEvent *e) {
+ timerEvent(static_cast<TQTimerEvent*>(e));
+}
+
+void TQWidget::childEvent(QChildEvent *e) {
+ TQT_TQOBJECT_CHILDEVENT_CONDITIONAL childEvent(static_cast<TQChildEvent*>(e));
+}
+
+void TQWidget::customEvent(QEvent *e) {
+ customEvent(static_cast<TQCustomEvent*>(e));
+}
+
+void TQWidget::tqrepaint() {
+ repaint();
+}
+
+void TQWidget::setFocus() {
+ setFocus(Qt::OtherFocusReason);
+}
+
+void TQWidget::polish() {
+ QApplication::sendPostedEvents( this, TQEvent::ChildInserted );
+ ensurePolished();
+}
+
+void TQWidget::mousePressEvent(QMouseEvent *e) {
+ TQT_TQWIDGET_FIX_BROKEN_POPUP_MOUSE_FOCUS mousePressEvent(static_cast<TQMouseEvent*>(e));
+}
+
+void TQWidget::mouseReleaseEvent(QMouseEvent *e) {
+ TQT_TQWIDGET_FIX_BROKEN_POPUP_MOUSE_FOCUS mouseReleaseEvent(static_cast<TQMouseEvent*>(e));
+}
+
+void TQWidget::mouseDoubleClickEvent(QMouseEvent *e) {
+ TQT_TQWIDGET_FIX_BROKEN_POPUP_MOUSE_FOCUS mouseDoubleClickEvent(static_cast<TQMouseEvent*>(e));
+}
+
+void TQWidget::mouseMoveEvent(QMouseEvent *e) {
+ TQT_TQWIDGET_FIX_BROKEN_POPUP_MOUSE_FOCUS mouseMoveEvent(static_cast<TQMouseEvent*>(e));
+}
+
+void TQWidget::createTLSysExtra( void ) {
+ printf("[TQT UNIMPLEMENTED CALL] createTLSysExtra()\n\r");
+}
+
+void TQWidget::destroyInputContext( void ) {
+ printf("[TQT UNIMPLEMENTED CALL] destroyInputContext()\n\r");
+}
+
+TQWidget::TQWidget( QWidget* tqparent, const char* name, WFlags f ) : QWidget( tqparent, (Qt::WindowFlags)(f&(~WTQtFlagMask)) ), TQtUpperWidgetFlags((WFlags)0) {
+ TQtUpperWidgetFlags = f & WTQtFlagMask;
+ TQT_TQWIDGET_REQUIRED_INITIALIZATION
+ static_cast<QWidget*>(this)->setObjectName(QString::fromAscii(name));
+ TQT_TQOBJECT_REQUIRED_INITIALIZATION(tqparent)
+}
+
+void TQWidget::setActiveWindow( void ) {
+ activateWindow();
+}
+
+Display * TQWidget::x11Display( void ) {
+ return this->x11Info().display();
+}
+
+int TQWidget::x11Screen( void ) {
+ return this->x11Info().screen();
+}
+
+TQWidget * TQWidget::parentWidget( bool sameWindow ) const {
+ TQ_UNUSED(sameWindow);
+ return static_cast<TQWidget*>(parentWidget());
+}
+
+TQCString TQWidget::normalizeSignalSlot( const char *signalSlot ) {
+ return TQObject::normalizeSignalSlot(signalSlot);
+}
+
+TQMetaObject *TQWidget::tqmetaObject() const {
+ return TQT_TQOBJECT_CONST(this)->tqmetaObject();
+}
+
+TQWidget * TQWidget::tqfind( WId w ) {
+ return static_cast<TQWidget*>(find(w));
+}
+
+bool TQWidget::isShown() const {
+ return !isHidden();
+}
+
+TQWidget *TQWidget::tqchildAt( int x, int y, bool includeThis ) const {
+ TQ_UNUSED(includeThis);
+ return static_cast<TQWidget*>(childAt(x, y));
+}
+
+TQWidget *TQWidget::tqchildAt( const TQPoint &p, bool includeThis ) const {
+ TQ_UNUSED(includeThis);
+ return static_cast<TQWidget*>(childAt(p));
+}
+
+TQWidget *TQWidget::tqtopLevelWidget() const {
+ return static_cast<TQWidget*>(topLevelWidget());
+}
+
+TQWExtra *TQWidget::extraData() {
+ return extra;
+}
+
+TQTLWExtra *TQWidget::topData() {
+ createTLExtra();
+ return extra->topextra;
+}
+
+void TQWidget::setName(const char *aName) {
+ TQT_TQOBJECT(this)->setName(aName);
+}
+
+TQWidget *TQWidget::parentWidget( bool sameWindow ) {
+ TQ_UNUSED(sameWindow);
+ return static_cast<TQWidget*>(this->parent());
+}
+
+bool TQWidget::isDialog() const {
+ return (windowType() == Qt::Dialog);
+}
+
+TQObject *TQWidget::child( const char *objName, const char *inheritsClass, bool recursiveSearch ) {
+ return TQT_TQOBJECT(this)->child( objName, inheritsClass, recursiveSearch );
+}
+
+const TQRect TQWidget::tqgeometry() const {
+ return TQT_TQRECT_OBJECT(geometry());
+}
+
+QSize TQWidget::sizeHint() const {
+ return tqsizeHint();
+}
+
+QSize TQWidget::minimumSizeHint() const {
+ return tqminimumSizeHint();
+}
+
+TQSize TQWidget::tqminimumSize() const {
+ return QWidget::minimumSize();
+}
+
+TQSize TQWidget::tqmaximumSize() const {
+ return QWidget::maximumSize();
+}
+
+TQColorGroup TQWidget::tqcolorGroup() const {
+ return TQColorGroup(palette());
+}
+
+void TQWidget::iconify() {
+ showMinimized();
+}
+
+void TQWidget::constPolish() const {
+ ensurePolished();
+}
+
+bool TQWidget::hasMouse() const {
+ return testAttribute(Qt::WA_UnderMouse);
+}
+
+bool TQWidget::ownCursor() const {
+ return testAttribute(Qt::WA_SetCursor);
+}
+
+bool TQWidget::ownFont() const {
+ return testAttribute(Qt::WA_SetFont);
+}
+
+const TQPixmap *TQWidget::backgroundPixmap() const {
+ return erasePixmap();
+}
+
+void TQWidget::tqsetSizePolicy(QSizePolicy qsp) {
+ setSizePolicy(qsp);
+}
+
+void TQWidget::tqsetSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical) {
+ setSizePolicy(horizontal, vertical);
+}
+
+void TQWidget::tqsetSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver, bool hfw) {
+ QSizePolicy sp(hor, ver);
+ sp.setHeightForWidth(hfw);
+ setSizePolicy(sp);
+}
+
+void TQWidget::setInputMethodEnabled(bool b) {
+ setAttribute(Qt::WA_InputMethodEnabled, b);
+}
+
+bool TQWidget::isInputMethodEnabled() const {
+ return testAttribute(Qt::WA_InputMethodEnabled);
+}
+
+bool TQWidget::isPopup() const {
+ return windowType() == Qt::Popup;
+}
+
+TQString TQWidget::caption() const {
+ return windowTitle();
+}
+
+void TQWidget::setCaption(const QString &c) {
+ setWindowTitle(c);
+}
+
+TQRect TQWidget::tqchildrenRect() const {
+ return childrenRect();
+}
+
+TQRegion TQWidget::tqchildrenRegion() const {
+ return childrenRegion();
+}
+
+void TQWidget::unsetFont() {
+ setFont(QFont());
+}
+
+bool TQWidget::ownPalette() const {
+ return testAttribute(Qt::WA_SetPalette);
+}
+
+void TQWidget::unsetPalette() {
+ setPalette(QPalette());
+}
+
+const TQPalette &TQWidget::tqpalette() const {
+ return TQT_TQPALETTE_OBJECT(palette());
+}
+
+bool TQWidget::isUpdatesEnabled() const {
+ return updatesEnabled();
+}
+
+void TQWidget::tqrepaint(int x, int y, int w, int h) {
+ return repaint(x, y, w, h);
+}
+
+void TQWidget::tqrepaint(const QRect &r) {
+ return repaint(r);
+}
+
+void TQWidget::tqrepaint(const QRegion &r) {
+ return repaint(r);
+}
+
+void TQWidget::tqrepaint(bool eraseme) {
+ if (eraseme) erase();
+ repaint();
+}
+
+void TQWidget::tqrepaint(int x, int y, int w, int h, bool) {
+ repaint(x,y,w,h);
+}
+
+void TQWidget::tqrepaint(const QRect &r, bool) {
+ repaint(r);
+}
+
+void TQWidget::tqrepaint(const QRegion &rgn, bool) {
+ repaint(rgn);
+}
+
+TQSizePolicy TQWidget::tqsizePolicy() const {
+ return TQT_TQSIZEPOLICY_OBJECT(sizePolicy());
+}
+
+TQPoint TQWidget::backgroundOffset() const {
+ return TQPoint();
+}
+
+bool TQWidget::tqsignalsBlocked() const {
+ return signalsBlocked();
+}
+
+TQObjectList *TQWidget::queryList( const char *inheritsClass, const char *objName, bool regexpMatch, bool recursiveSearch ) const {
+ return TQT_TQOBJECT_CONST(this)->queryList(inheritsClass, objName, regexpMatch, recursiveSearch);
+}
+
+TQWidget *TQWidget::tqfocusWidget() const {
+ return TQT_TQWIDGET(focusWidget());
+}
+
+void TQWidget::setBackgroundOrigin(BackgroundOrigin) {
+}
+
+TQWidget::BackgroundOrigin TQWidget::backgroundOrigin() const {
+ return WindowOrigin;
+}
+
+void TQWidget::setIconText(const QString &it) {
+ setWindowIconText(it);
+}
+
+void TQWidget::insertChild( TQObject *object ) {
+ TQT_TQOBJECT(this)->insertChild(object);
+}
+
+void TQWidget::removeChild( TQObject *object ) {
+ TQT_TQOBJECT(this)->removeChild(object);
+}
+
+bool TQWidget::close() {
+ return QWidget::close();
+}
+
+void TQWidget::setFocus(Qt::FocusReason reason) {
+ return QWidget::setFocus(reason);
+}
+
+void TQWidget::setBackgroundMode( TQt::BackgroundMode tqbm ) {
+ setBackgroundMode(tqbm, TQt::PaletteBackground);
+}
+
+const QColor &TQWidget::paletteForegroundColor() const {
+ return palette().color(foregroundRole());
+}
+
+void TQWidget::setPaletteForegroundColor(const QColor &c) {
+ QPalette p = palette();
+ p.setColor(foregroundRole(), c);
+ setPalette(p);
+}
+
+const QColor &TQWidget::paletteBackgroundColor() const {
+ return palette().color(backgroundRole());
+}
+
+void TQWidget::setPaletteBackgroundColor(const QColor &c) {
+ QPalette p = palette();
+ p.setColor(backgroundRole(), c);
+ setPalette(p);
+}
+
+const TQPixmap *TQWidget::paletteBackgroundPixmap() const {
+ QPalette p = palette();
+ const QPixmap& pm = p.brush(backgroundRole()).texture();
+ if (pm.isNull())
+ return 0;
+ return TQT_TQPIXMAP_CONST(&pm);
+}
+
+void TQWidget::setPaletteBackgroundPixmap(const QPixmap &pm) {
+ QPalette p = palette();
+ p.setBrush(backgroundRole(), QBrush(pm));
+ setPalette(p);
+}
+
+const TQColor &TQWidget::backgroundColor() const {
+ return TQT_TQCOLOR_OBJECT(palette().color(backgroundRole()));
+}
+
+void TQWidget::setBackgroundColor(const QColor &c) {
+ QPalette p = palette();
+ p.setColor(backgroundRole(), c);
+ setPalette(p);
+}
+
+const TQColor &TQWidget::eraseColor() const {
+ return TQT_TQCOLOR_OBJECT(palette().color(backgroundRole()));
+}
+
+void TQWidget::setEraseColor(const QColor &c) {
+ QPalette p = palette();
+ p.setColor(backgroundRole(), c);
+ setPalette(p);
+}
+
+const TQPixmap *TQWidget::erasePixmap() const {
+ QPalette p = palette();
+ const QPixmap& pm = p.brush(backgroundRole()).texture();
+ if (pm.isNull())
+ return 0;
+ return TQT_TQPIXMAP_CONST(&pm);
+}
+
+void TQWidget::setErasePixmap(const QPixmap &pm) {
+ QPalette p = palette();
+ p.setBrush(backgroundRole(), QBrush(pm));
+ setPalette(p);
+}
+
+const TQColor &TQWidget::foregroundColor() const {
+ return TQT_TQCOLOR_OBJECT(palette().color(foregroundRole()));
+}
+
+void TQWidget::erase() {
+ erase_helper(0, 0, QWidget::width(), QWidget::height());
+}
+
+void TQWidget::erase(int x, int y, int w, int h) {
+ erase_helper(x, y, w, h);
+}
+
+void TQWidget::erase(const QRect &r) {
+ erase_helper(r.x(), r.y(), r.width(), r.height());
+}
+
+const char *TQWidget::name(const char *defaultName) const {
+ TQString s = objectName();
+ return s.isEmpty()?defaultName:s.latin1_helper();
+}
+
+void TQWidget::tqsetPalette( const TQPalette &p, bool ) {
+ setPalette( p );
+}
+
+bool TQWidget::isDesktop() const {
+ return testWFlags(WType_Desktop);
+}
+
+bool TQWidget::isFocusEnabled() const {
+ return focusPolicy() != Qt::NoFocus;
+}
+
+// Qt4 handler interface
+bool TQWidget::eventFilter( QObject *q, QEvent *e ) {
+ return eventFilter(static_cast<TQObject*>(q), static_cast<TQEvent*>(e));
+}
+
+bool TQWidget::event( QEvent *e ) {
+ return event(static_cast<TQEvent*>(e));
+}
+
+#ifndef QT_NO_WHEELEVENT
+void TQWidget::wheelEvent(QWheelEvent *e) {
+ wheelEvent(static_cast<TQWheelEvent*>(e));
+}
+#endif
+
+void TQWidget::keyPressEvent(QKeyEvent *e) {
+ keyPressEvent(static_cast<TQKeyEvent*>(e));
+}
+
+void TQWidget::keyReleaseEvent(QKeyEvent *e) {
+ keyReleaseEvent(static_cast<TQKeyEvent*>(e));
+}
+
+void TQWidget::focusInEvent(QFocusEvent *e) {
+ focusInEvent(static_cast<TQFocusEvent*>(e));
+}
+
+void TQWidget::focusOutEvent(QFocusEvent *e) {
+ focusOutEvent(static_cast<TQFocusEvent*>(e));
+}
+
+void TQWidget::enterEvent(QEvent *e) {
+ enterEvent(static_cast<TQEvent*>(e));
+}
+
+void TQWidget::leaveEvent(QEvent *e) {
+ leaveEvent(static_cast<TQEvent*>(e));
+}
+
+void TQWidget::paintEvent(QPaintEvent *e) {
+ paintEvent(static_cast<TQPaintEvent*>(e));
+}
+
+void TQWidget::moveEvent(QMoveEvent *e) {
+ moveEvent(static_cast<TQMoveEvent*>(e));
+}
+
+void TQWidget::resizeEvent(QResizeEvent *e) {
+ resizeEvent(static_cast<TQResizeEvent*>(e));
+}
+
+void TQWidget::closeEvent(QCloseEvent *e) {
+ closeEvent(static_cast<TQCloseEvent*>(e));
+}
+
+#ifndef QT_NO_CONTEXTMENU
+void TQWidget::contextMenuEvent(QContextMenuEvent *e) {
+ contextMenuEvent(static_cast<TQContextMenuEvent*>(e));
+}
+#endif
+
+#ifndef QT_NO_TABLETEVENT
+void TQWidget::tabletEvent(QTabletEvent *e) {
+ tabletEvent(static_cast<TQTabletEvent*>(e));
+}
+#endif
+
+TQConnectionList *TQWidget::tqreceivers( const char* signal ) const {
+ return TQT_TQOBJECT_CONST(this)->tqreceivers(signal);
+}
+
+TQConnectionList *TQWidget::tqreceivers( int signal ) const {
+ return TQT_TQOBJECT_CONST(this)->tqreceivers(signal);
+}
+
+void TQWidget::activate_signal( int signal ) {
+ TQT_TQOBJECT(this)->activate_signal(signal);
+}
+
+void TQWidget::activate_signal( TQConnectionList *clist, TQUObject *o ) {
+ TQT_TQOBJECT(this)->activate_signal(clist, o);
+}
+
+void TQWidget::tqt_handle_qt_destroyed(QObject* obj) {
+ emit destroyed(TQT_TQOBJECT(obj));
+}
+
+bool TQWidget::isVisibleToTLW() const {
+ return isVisible();
+}
+
+/*!
+ \property TQWidget::backgroundBrush
+ \brief the widget's background brush
+
+ The background brush depends on a widget's palette and its
+ background mode.
+
+ \sa backgroundColor(), backgroundPixmap(), eraseColor(), palette,
+ TQApplication::setPalette()
+*/
+const TQBrush& TQWidget::backgroundBrush() const
+{
+ static TQBrush noBrush;
+#ifndef TQT_NO_PALETTE
+ TQt::BackgroundMode mode = extra ? (TQt::BackgroundMode) extra->bg_mode_visual : TQt::PaletteBackground;
+ switch( mode ) {
+ case TQt::FixedColor:
+ case TQt::FixedPixmap :
+ case TQt::NoBackground:
+ case TQt::X11ParentRelative:
+ return noBrush;
+ default:
+ TQColorGroup::ColorRole role = TQPalette::backgroundRoleFromMode( mode );
+ return tqcolorGroup().tqbrush( role );
+ }
+#else
+ return noBrush;
+#endif
+}
+
+/*!
+ \internal
+ Creates the widget extra data.
+*/
+
+// [FIXME] Fix the commented out lines
+
+void TQWidget::createExtra()
+{
+ if ( !extra ) { // if not exists
+ extra = new TQWExtra;
+ TQ_CHECK_PTR( extra );
+ extra->minw = extra->minh = 0;
+ extra->maxw = extra->maxh = TQWIDGETSIZE_MAX;
+ extra->bg_pix = 0;
+ extra->focus_proxy = 0;
+#ifndef TQT_NO_CURSOR
+ extra->curs = 0;
+#endif
+ extra->topextra = 0;
+ extra->bg_mode = TQt::PaletteBackground;
+ extra->bg_mode_visual = TQt::PaletteBackground;
+// extra->bg_origin = TQt::WidgetOrigin;
+#ifndef TQT_NO_STYLE
+ extra->style = 0;
+#endif
+ extra->size_policy = TQSizePolicy( TQSizePolicy::Preferred,
+ TQSizePolicy::Preferred );
+// createSysExtra();
+ }
+}
+
+
+/*!
+ \internal
+ Deletes the widget extra data.
+*/
+
+// [FIXME] Fix the commented out lines
+
+void TQWidget::deleteExtra()
+{
+ if ( extra ) { // if exists
+ delete extra->bg_pix;
+#ifndef TQT_NO_CURSOR
+ delete extra->curs;
+#endif
+// deleteSysExtra();
+ if ( extra->topextra ) {
+// deleteTLSysExtra();
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ delete extra->topextra->icon;
+#endif
+// delete extra->topextra->focusData;
+#if defined(TQ_WS_TQWS) && !defined(TQT_NO_TQWS_MANAGER)
+ delete extra->topextra->qwsManager;
+#endif
+ delete extra->topextra;
+ }
+ delete extra;
+ // extra->xic destroyed in TQWidget::destroy()
+ extra = 0;
+ }
+}
+
+void TQWidget::setBackgroundPixmap(const QPixmap &pm) {
+ // Is this object really a TQWidget (or based on a TQWidget)? If so use the internal virtual function instead...
+ if (inherits("TQObject") == TRUE) {
+ tqsetBackgroundPixmap(pm);
+ }
+ else {
+ QPalette p = palette();
+ p.setBrush(backgroundRole(), QBrush(pm));
+ setPalette(p);
+ }
+}
+
+void TQWidget::tqsetBackgroundPixmap(const QPixmap &pm) {
+ QPalette p = palette();
+ p.setBrush(backgroundRole(), QBrush(pm));
+ setPalette(p);
+}
+
+void TQWidget::setWFlags( WFlags flags ) {
+ if (this->inherits("TQWidget"))
+ TQtUpperWidgetFlags = TQtUpperWidgetFlags | (flags & WTQtFlagMask);
+ overrideWindowFlags((Qt::WindowFlags) (windowFlags() | (flags&(~WTQtFlagMask))));
+ if (this->inherits("TQWidget"))
+ processUpperWidgetFlags();
+}
+
+void TQWidget::clearWFlags( WFlags flags ) {
+ unsigned long long upperflags = 0ULL;
+ if (this->inherits("TQWidget"))
+ upperflags = TQtUpperWidgetFlags;
+ unsigned long long oldFlags = windowFlags() | upperflags;
+ unsigned long long newFlags = (oldFlags &= (~flags));
+ if ( ((newFlags & (WType_Dialog & (~WType_TopLevel))) != 0)
+ || ((newFlags & (WType_Popup & (~WType_TopLevel))) != 0)
+ || ((newFlags & (WType_Desktop & (~WType_TopLevel))) != 0))
+ newFlags = newFlags | WType_TopLevel;
+ overrideWindowFlags((Qt::WindowFlags)(newFlags&(~WTQtFlagMask)));
+ if (this->inherits("TQWidget"))
+ processUpperWidgetFlags();
+}
+
+WFlags TQWidget::getWFlags() const {
+ unsigned long long upperflags = 0ULL;
+ if (this->inherits("TQWidget"))
+ upperflags = TQtUpperWidgetFlags;
+ return windowFlags() | upperflags;
+}
+
+WFlags TQWidget::testWFlags( WFlags f ) const {
+ unsigned long long upperflags = 0ULL;
+ if (this->inherits("TQWidget"))
+ upperflags = TQtUpperWidgetFlags;
+ return ((windowFlags() | upperflags) & f);
+}
+
+void TQWidget::reparent(QWidget *parent, WFlags f, const QPoint &p, bool showIt) {
+ if (this->inherits("TQWidget")) {
+ TQtUpperWidgetFlags = f & WTQtFlagMask;
+ processUpperWidgetFlags();
+ }
+ setParent(parent, (Qt::WindowFlags)(f&(~WTQtFlagMask)));
+ setGeometry(p.x(),p.y(),width(),height());
+ if (showIt) show();
+}
+
+void TQWidget::processUpperWidgetFlags() {
+ unsigned long long flags = TQtUpperWidgetFlags&WTQtFlagMask;
+
+ // Process each extended TQt window flag that was defined in tqnamespace.h
+ if (flags & WNoAutoErase)
+ setAutoFillBackground(false);
+ else
+ setAutoFillBackground(true);
+
+ if (flags & WMouseNoMask)
+ setAttribute(Qt::WA_MouseNoMask, true);
+ else
+ setAttribute(Qt::WA_MouseNoMask, false);
+
+ if ((flags & WPaintOnScreen) || (flags & WPaintUnclipped))
+ setAttribute(Qt::WA_PaintOnScreen, true);
+ else
+ setAttribute(Qt::WA_PaintOnScreen, false);
+
+ if (flags & WPaintUnclipped)
+ setAttribute(Qt::WA_PaintUnclipped, true);
+ else
+ setAttribute(Qt::WA_PaintUnclipped, false);
+}
+
+void TQWidget::setDefaultWidgetFlags() {
+ TQtUpperWidgetFlags = TQtUpperWidgetFlags | WPaintOnScreen;
+}
+
+/*!
+ Enables key event compression, if \a compress is TRUE, and
+ disables it if \a compress is FALSE.
+
+ Key compression is off by default (except for TQLineEdit and
+ TQTextEdit), so widgets receive one key press event for each key
+ press (or more, since autorepeat is usually on). If you turn it on
+ and your program doesn't keep up with key input, TQt may try to
+ compress key events so that more than one character can be
+ processed in each event.
+
+ For example, a word processor widget might receive 2, 3 or more
+ characters in each TQKeyEvent::text(), if the tqlayout recalculation
+ takes too long for the CPU.
+
+ If a widget supports multiple character tqunicode input, it is
+ always safe to turn the compression on.
+
+ TQt performs key event compression only for printable characters.
+ Modifier keys, cursor movement keys, function keys and
+ miscellaneous action keys (e.g. Escape, Enter, Backspace,
+ PrintScreen) will stop key event compression, even if there are
+ more compressible key events available.
+
+ Not all platforms support this compression, in which case turning
+ it on will have no effect.
+
+ \sa TQKeyEvent::text();
+*/
+
+void TQWidget::setKeyCompression(bool compress)
+{
+ if ( compress )
+ setWState( TQt::WState_CompressKeys );
+ else
+ clearWState( TQt::WState_CompressKeys );
+}
+
+/*!
+ Returns the focus data for this widget's top-level widget.
+
+ Focus data always belongs to the top-level widget. The focus data
+ list tqcontains all the widgets in this top-level widget that can
+ accept focus, in tab order. An iterator points to the current
+ focus widget (tqfocusWidget() returns a pointer to this widget).
+
+ This information is useful for implementing advanced versions of
+ focusNextPrevChild().
+*/
+TQFocusData * TQWidget::focusData()
+{
+ return focusData( TRUE );
+}
+
+/*!
+ \internal
+
+ Internal function which lets us ask for the focus data, creating
+ it if it doesn't exist and \a create is TRUE.
+*/
+TQFocusData * TQWidget::focusData( bool create )
+{
+ TQWidget * tlw = tqtopLevelWidget();
+ TQWExtra * ed = tlw->extraData();
+ if ( !ed || !ed->topextra ) {
+ if ( !create )
+ return 0;
+ tlw->createTLExtra();
+ ed = tlw->extraData();
+ }
+ if ( create && !ed->topextra->focusData )
+ ed->topextra->focusData = new TQFocusData;
+
+ return ed->topextra->focusData;
+
+ // [FIXME] What does this do and how can I do it in Qt4?
+ printf("[WARNING] TQWidget::focusData( bool create ) unimplemented\n\r");
+ return 0;
+}
+
+void TQWidget::createTLExtra()
+{
+ if ( !extra )
+ createExtra();
+ if ( !extra->topextra ) {
+ TQTLWExtra* x = extra->topextra = new TQTLWExtra;
+#if defined( TQ_WS_WIN ) || defined( TQ_WS_MAC )
+ x->opacity = 255;
+#endif
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ x->icon = 0;
+#endif
+ x->focusData = 0;
+ x->fleft = x->fright = x->ftop = x->fbottom = 0;
+ x->incw = x->inch = 0;
+ x->basew = x->baseh = 0;
+ x->normalGeometry = TQRect(0,0,-1,-1);
+#if defined(TQ_WS_X11)
+ x->embedded = 0;
+ x->parentWinId = 0;
+ x->spont_unmapped = 0;
+ x->dnd = 0;
+ x->uspos = 0;
+ x->ussize = 0;
+#endif
+ x->savedFlags = 0;
+#if defined(TQ_WS_TQWS) && !defined(TQT_NO_TQWS_MANAGER)
+ x->decor_allocated_region = TQRegion();
+ x->qwsManager = 0;
+#endif
+ createTLSysExtra();
+ }
+}
+
+/*!
+ \property TQWidget::autoMask
+ \brief whether the auto tqmask feature is enabled for the widget
+
+ Transtqparent widgets use a tqmask to define their visible region.
+ TQWidget has some built-in support to make the task of
+ recalculating the tqmask easier. When setting auto tqmask to TRUE,
+ updateMask() will be called whenever the widget is resized or
+ changes its focus state. Note that you must reimplement
+ updateMask() (which should include a call to setMask()) or nothing
+ will happen.
+
+ Note: when you re-implement resizeEvent(), focusInEvent() or
+ focusOutEvent() in your custom widgets and still want to ensure
+ that the auto tqmask calculation works, you should add:
+
+ \code
+ if ( autoMask() )
+ updateMask();
+ \endcode
+
+ at the end of your event handlers. This is true for all member
+ functions that change the appearance of the widget in a way that
+ requires a recalculation of the tqmask.
+
+ While being a technically appealing concept, masks have a big
+ drawback: when using complex masks that cannot be expressed easily
+ with relatively simple regions, they can be very slow on some
+ window systems. The classic example is a transtqparent label. The
+ complex tqshape of its contents makes it necessary to represent its
+ tqmask by a bitmap, which consumes both memory and time. If all you
+ want is to blend the background of several neighboring widgets
+ together seamlessly, you will probably want to use
+ setBackgroundOrigin() rather than a tqmask.
+
+ \sa autoMask() updateMask() setMask() clearMask() setBackgroundOrigin()
+*/
+
+// [FIXME]
+// Verify that (WState)TQt::WState_AutoMask is a valid window state in Qt4, or at least
+// does not conflict with any Qt4 window states (i.e. can live alone without stomping on anything!)
+
+bool TQWidget::autoMask() const
+{
+ return testWState((WState)TQt::WState_AutoMask);
+}
+
+void TQWidget::setAutoMask( bool enable )
+{
+ if ( enable == autoMask() )
+ return;
+
+ if ( enable ) {
+ setWState((WState)TQt::WState_AutoMask);
+ updateMask();
+ } else {
+ clearWState((WState)TQt::WState_AutoMask);
+ clearMask();
+ }
+}
+
+void TQWidget::setFocus(TQFocusEvent::Reason reason)
+{
+ setFocus((Qt::FocusReason)reason);
+}
+
+TQObject *TQWidget::tqparent() const {
+ return TQT_TQOBJECT(parent());
+}
+
+// const TQObjectList *TQWidget::childrenListObject() const {
+// QObjectList qlr;
+// TQObjectList* tqt_tqobject_list = new TQObjectList();
+// qlr = this->children();
+// tqt_tqobject_list->clear();
+// for (int i = 0; i < qlr.size(); ++i) {
+// tqt_tqobject_list->append(static_cast<TQObject*>(qlr.at(i)));
+// }
+// return tqt_tqobject_list;
+// }
+
+TQObjectList TQWidget::childrenListObject() {
+ QObjectList qlr;
+ TQObjectList tqt_tqobject_list;
+ qlr = this->children();
+ tqt_tqobject_list.clear();
+ for (int i = 0; i < qlr.size(); ++i) {
+ tqt_tqobject_list.append(static_cast<TQObject*>(qlr.at(i)));
+ }
+ return tqt_tqobject_list;
+}
+
+const TQObjectList TQWidget::childrenListObject() const {
+ QObjectList qlr;
+ TQObjectList tqt_tqobject_list;
+ qlr = this->children();
+ tqt_tqobject_list.clear();
+ for (int i = 0; i < qlr.size(); ++i) {
+ tqt_tqobject_list.append(static_cast<TQObject*>(qlr.at(i)));
+ }
+ return tqt_tqobject_list;
+}
+
+const char *TQWidget::tqname() const {
+ if (dynamic_cast<const TQWidget*>(static_cast<const QWidget*>(static_cast<const QObject*>(this)))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ printf("[WARNING] Attempted to call TQWidget::tqname() on an object without a constructed TQWidget object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+const char *TQWidget::name() const {
+ if (dynamic_cast<const TQWidget*>(static_cast<const QWidget*>(static_cast<const QObject*>(this)))) {
+ static_object_name = TQT_OBJECT_NAME_HANDLER(objectName());
+ return static_object_name.ascii();
+ }
+ else {
+ printf("[WARNING] Attempted to call TQWidget::name() on an object without a constructed TQWidget object or base object. Returning \"\"\n\r");
+ return "";
+ }
+}
+
+TQLayout *TQWidget::tqlayout() const {
+ return TQT_TQLAYOUT(QWidget::layout());
+}
+
+/*!
+ Clear the rectangle at point (\a x, \a y) of width \a w and height
+ \a h.
+
+ \warning This is best done in a paintEvent().
+*/
+void TQWidget::erase_helper(int x, int y, int w, int h)
+{
+// if (testAttribute(Qt::WA_NoSystemBackground) || testAttribute(Qt::WA_UpdatesDisabled) || !testAttribute(Qt::WA_WState_Visible))
+// return;
+ if (w < 0)
+// w = data->crect.width() - x;
+ w = QWidget::x() - x;
+ if (h < 0)
+// h = data->crect.height() - y;
+ h = QWidget::y() - y;
+ if (w != 0 && h != 0) {
+// if (paintingActive()) {
+ if (paintingActive() && paintEngine()->isActive()) {
+ QPainter* p = paintEngine()->painter();
+ if (p) {
+ printf("[WARNING] A painter was aready active when TQWidget::erase(...) was called. Attempting to use existing painter for erasure...\n\r");
+ p->eraseRect(QRect(x, y, w, h));
+ }
+ else {
+ printf("[WARNING] A painter was aready active when TQWidget::erase(...) was called. Attempted to use existing painter for erasure but that FAILED!\n\r");
+ }
+ }
+ else {
+ QPainter p(this);
+ p.eraseRect(QRect(x, y, w, h));
+ }
+ }
+}
+
+/*!
+ \overload
+
+ Clear the given region, \a rgn.
+
+ Drawing may only take place in a QPaintEvent. Overload
+ paintEvent() to do your erasing and call update() to schedule a
+ replaint whenever necessary. See also QPainter.
+*/
+void TQWidget::erase(const QRegion& rgn)
+{
+ if (testAttribute(Qt::WA_NoSystemBackground) || testAttribute(Qt::WA_UpdatesDisabled) || !testAttribute(Qt::WA_WState_Visible))
+ return;
+
+ QPainter p(this);
+ p.setClipRegion(rgn);
+ p.eraseRect(rgn.boundingRect());
+}
+
+/*!
+ Returns the color role used for painting the widget's background.
+
+ Use QPalette(backgroundRole(()) instead.
+*/
+TQt::BackgroundMode TQWidget::backgroundMode() const
+{
+ if (testAttribute(Qt::WA_NoSystemBackground))
+ return TQt::NoBackground;
+ switch(backgroundRole()) {
+ case QPalette::WindowText:
+ return TQt::PaletteForeground;
+ case QPalette::Button:
+ return TQt::PaletteButton;
+ case QPalette::Light:
+ return TQt::PaletteLight;
+ case QPalette::Midlight:
+ return TQt::PaletteMidlight;
+ case QPalette::Dark:
+ return TQt::PaletteDark;
+ case QPalette::Mid:
+ return TQt::PaletteMid;
+ case QPalette::Text:
+ return TQt::PaletteText;
+ case QPalette::BrightText:
+ return TQt::PaletteBrightText;
+ case QPalette::Base:
+ return TQt::PaletteBase;
+ case QPalette::Window:
+ return TQt::PaletteBackground;
+ case QPalette::Shadow:
+ return TQt::PaletteShadow;
+ case QPalette::Highlight:
+ return TQt::PaletteHighlight;
+ case QPalette::HighlightedText:
+ return TQt::PaletteHighlightedText;
+ case QPalette::ButtonText:
+ return TQt::PaletteButtonText;
+ case QPalette::Link:
+ return TQt::PaletteLink;
+ case QPalette::LinkVisited:
+ return TQt::PaletteLinkVisited;
+ default:
+ break;
+ }
+ return TQt::NoBackground;
+}
+
+/*!
+ \fn void QWidget::setBackgroundMode(Qt::BackgroundMode
+ widgetBackground, Qt::BackgroundMode paletteBackground)
+
+ Sets the color role used for painting the widget's background to
+ background mode \a widgetBackground. The \a paletteBackground mode
+ parameter is ignored.
+*/
+void TQWidget::setBackgroundMode(TQt::BackgroundMode m, TQt::BackgroundMode)
+{
+ if(m == TQt::NoBackground) {
+ setAttribute(Qt::WA_NoSystemBackground, true);
+ return;
+ }
+ setAttribute(Qt::WA_NoSystemBackground, false);
+ setForegroundRole(QPalette::NoRole);
+ QPalette::ColorRole role = backgroundRole();
+ switch(m) {
+ case TQt::FixedColor:
+ case TQt::FixedPixmap:
+ break;
+ case TQt::PaletteForeground:
+ role = QPalette::WindowText;
+ break;
+ case TQt::PaletteButton:
+ role = QPalette::Button;
+ break;
+ case TQt::PaletteLight:
+ role = QPalette::Light;
+ break;
+ case TQt::PaletteMidlight:
+ role = QPalette::Midlight;
+ break;
+ case TQt::PaletteDark:
+ role = QPalette::Dark;
+ break;
+ case TQt::PaletteMid:
+ role = QPalette::Mid;
+ break;
+ case TQt::PaletteText:
+ role = QPalette::Text;
+ break;
+ case TQt::PaletteBrightText:
+ role = QPalette::BrightText;
+ break;
+ case TQt::PaletteBase:
+ role = QPalette::Base;
+ break;
+ case TQt::PaletteBackground:
+ role = QPalette::Window;
+ break;
+ case TQt::PaletteShadow:
+ role = QPalette::Shadow;
+ break;
+ case TQt::PaletteHighlight:
+ role = QPalette::Highlight;
+ break;
+ case TQt::PaletteHighlightedText:
+ role = QPalette::HighlightedText;
+ break;
+ case TQt::PaletteButtonText:
+ role = QPalette::ButtonText;
+ break;
+ case TQt::PaletteLink:
+ role = QPalette::Link;
+ break;
+ case TQt::PaletteLinkVisited:
+ role = QPalette::LinkVisited;
+ break;
+ case TQt::X11ParentRelative:
+ role = QPalette::NoRole;
+ setForegroundRole(role);
+ default:
+ break;
+ }
+ setBackgroundRole(role);
+}
+/*
+TQRect TQWidget::tqeffectiveRectFor(const QRect &rect) const
+{
+// #ifndef QT_NO_GRAPHICSEFFECT
+// if (graphicsEffect() && graphicsEffect()->isEnabled())
+// return graphicsEffect()->boundingRectFor(rect).toAlignedRect();
+// #endif //QT_NO_GRAPHICSEFFECT
+ return rect;
+}*/
+
+/*
+ Returns the widget's clipping rectangle.
+*/
+TQRect TQWidget::tqclipRect() const
+{
+// Q_Q(const QWidget);
+ const QWidget * w = this;
+ if (!w->isVisible())
+ return QRect();
+// QRect r = tqeffectiveRectFor(this->rect()); // [FIXME]
+ QRect r = this->rect();
+ int ox = 0;
+ int oy = 0;
+ while (w
+ && w->isVisible()
+ && !w->isWindow()
+ && w->parentWidget()) {
+ ox -= w->x();
+ oy -= w->y();
+ w = w->parentWidget();
+ r &= QRect(ox, oy, w->width(), w->height());
+ }
+ return r;
+}
+
+/*!
+ Use visibleRegion() instead.
+*/
+TQRect TQWidget::visibleRect() const
+{
+ return tqclipRect();
+}
+
+/*!
+ Returns the unobscured region where paint events can occur.
+
+ For visible widgets, this is an approximation of the area not
+ covered by other widgets; otherwise, this is an empty region.
+
+ The tqrepaint() function calls this function if necessary, so in
+ general you do not need to call it.
+
+*/
+TQRegion TQWidget::clipRegion() const
+{
+ return visibleRect();
+}
+
+void TQWidget::setIcon(const QPixmap &i)
+{
+ setWindowIcon(i);
+}
+
+/*!
+ \property TQWidget::customWhatsThis
+ \brief whether the widget wants to handle What's This help manually
+
+ The default implementation of customWhatsThis() returns FALSE,
+ which means the widget will not receive any events in Whats This
+ mode.
+
+ The widget may leave What's This mode by calling
+ TQWhatsThis::leaveWhatsThisMode(), with or without actually
+ displaying any help text.
+
+ You can also reimplement customWhatsThis() if your widget is a
+ "passive interactor" supposed to work under all circumstances.
+ Simply don't call TQWhatsThis::leaveWhatsThisMode() in that case.
+
+ \sa TQWhatsThis::inWhatsThisMode() TQWhatsThis::leaveWhatsThisMode()
+*/
+bool TQWidget::customWhatsThis() const
+{
+ return FALSE;
+}
+
+const TQPixmap *TQWidget::icon() const {
+ const_cast<TQWidget*>(this)->setProperty("TQT_WIDGET_ICON", TQPixmap(windowIcon().pixmap(QSize(14, 14)))); // [FIXME] Is there any way around hardcoding these sizes??
+ const QPixmap& ptrRef = property("TQT_WIDGET_ICON").value<QPixmap>();
+ return TQT_TQPIXMAP_CONST(&ptrRef);
+}
+
+const TQPixmap TQWidget::iconPixmap() const {
+ return TQPixmap(windowIcon().pixmap(QSize(14, 14))); // [FIXME] Is there any way around hardcoding these sizes??
+}
+
+/*!
+ This function can be reimplemented in a subclass to support
+ transtqparent widgets. It should be called whenever a widget changes
+ state in a way that means that the tqshape tqmask must be recalculated.
+
+ \sa setAutoMask(), updateMask(), setMask(), clearMask()
+*/
+void TQWidget::updateMask()
+{
+}
+
+/*!
+ Returns the GUI style for this widget
+
+ \sa TQWidget::setStyle(), TQApplication::setStyle(), TQApplication::style()
+*/
+
+TQStyle& TQWidget::tqstyle() const
+{
+// if ( extra && extra->style )
+// return *extra->style;
+ TQStyle &ret = tqApp->tqstyle();
+ return ret;
+}
+
+/*!
+ Sets the widget's GUI style to \a style. Ownership of the style
+ object is not transferred.
+
+ If no style is set, the widget uses the application's style,
+ TQApplication::style() instead.
+
+ Setting a widget's style has no effect on existing or future child
+ widgets.
+
+ \warning This function is particularly useful for demonstration
+ purposes, where you want to show TQt's styling capabilities. Real
+ applications should avoid it and use one consistent GUI style
+ instead.
+
+ \sa style(), TQStyle, TQApplication::style(), TQApplication::setStyle()
+*/
+
+void TQWidget::setStyle( TQStyle *style )
+{
+ QWidget::setStyle(style);
+}
+
+/*!
+ \overload
+
+ Sets the widget's GUI style to \a style using the TQStyleFactory.
+*/
+TQStyle* TQWidget::setStyle( const TQString &style )
+{
+ TQStyle *s = TQStyleFactory::create( style );
+ setStyle( s );
+ return s;
+}
+
+/*!
+ \property TQWidget::tqsizeHint
+ \brief the recommended size for the widget
+
+ If the value of this property is an invalid size, no size is
+ recommended.
+
+ The default implementation of tqsizeHint() returns an invalid size
+ if there is no tqlayout for this widget, and returns the tqlayout's
+ preferred size otherwise.
+
+ \sa TQSize::isValid(), tqminimumSizeHint(), sizePolicy(),
+ setMinimumSize(), updateGeometry()
+*/
+
+TQSize TQWidget::tqsizeHint() const
+{
+#ifndef TQT_NO_LAYOUT
+ if ( tqlayout() )
+ return tqlayout()->totalSizeHint();
+#endif
+ return TQSize( -1, -1 );
+}
+
+/*!
+ \property TQWidget::tqminimumSizeHint
+ \brief the recommended minimum size for the widget
+
+ If the value of this property is an invalid size, no minimum size
+ is recommended.
+
+ The default implementation of tqminimumSizeHint() returns an invalid
+ size if there is no tqlayout for this widget, and returns the
+ tqlayout's minimum size otherwise. Most built-in widgets reimplement
+ tqminimumSizeHint().
+
+ \l TQLayout will never resize a widget to a size smaller than
+ tqminimumSizeHint.
+
+ \sa TQSize::isValid(), resize(), setMinimumSize(), sizePolicy()
+*/
+TQSize TQWidget::tqminimumSizeHint() const
+{
+#ifndef TQT_NO_LAYOUT
+ if ( tqlayout() )
+ return tqlayout()->totalMinimumSize();
+#endif
+ return TQSize( -1, -1 );
+}
+
+/*!
+ \property TQWidget::updatesEnabled
+ \brief whether updates are enabled
+
+ Calling update() and tqrepaint() has no effect if updates are
+ disabled. Paint events from the window system are processed
+ normally even if updates are disabled.
+
+ setUpdatesEnabled() is normally used to disable updates for a
+ short period of time, for instance to avoid screen flicker during
+ large changes.
+
+ Example:
+ \code
+ setUpdatesEnabled( FALSE );
+ bigVisualChanges();
+ setUpdatesEnabled( TRUE );
+ tqrepaint();
+ \endcode
+
+ \sa update(), tqrepaint(), paintEvent()
+*/
+void TQWidget::tqsetUpdatesEnabled( bool enable )
+{
+// if ( enable )
+// clearWState( WState_BlockUpdates );
+// else
+// setWState( WState_BlockUpdates );
+
+ // Borrowed from Qt4
+ if (enable && !isWindow() && parentWidget() && !parentWidget()->updatesEnabled())
+ return; // nothing we can do
+
+ if (enable != testAttribute(Qt::WA_UpdatesDisabled))
+ return; // nothing to do
+
+ setAttribute(Qt::WA_UpdatesDisabled, !enable);
+// if (enable)
+// update();
+
+ Qt::WidgetAttribute attribute = enable ? Qt::WA_ForceUpdatesDisabled : Qt::WA_UpdatesDisabled;
+ for (int i = 0; i < children().size(); ++i) {
+ TQWidget *w = TQT_TQWIDGET(qobject_cast<QWidget *>(children().at(i)));
+ if (w && !w->isWindow() && !w->testAttribute(attribute))
+ w->tqsetUpdatesEnabled(enable);
+ }
+}
+
+// USE_QT4
+
+// PRIVATE API FROM QT4
+// THIS MAY HAVE TO BE SYNCED WITH QT4 ON OCCASION
+/*!
+ \internal
+ \class QWidgetBackingStoreTracker
+ \brief Class which allows tracking of which widgets are using a given backing store
+
+ QWidgetBackingStoreTracker is a thin wrapper around a QWidgetBackingStore pointer,
+ which maintains a list of the QWidgets which are currently using the backing
+ store. This list is modified via the registerWidget and unregisterWidget functions.
+ */
+
+QWidgetBackingStoreTracker::QWidgetBackingStoreTracker()
+ : m_ptr(0)
+{
+
+}
+
+QWidgetBackingStoreTracker::~QWidgetBackingStoreTracker()
+{
+ delete m_ptr;
+}
+
+#if 0
+
+/*!
+ \internal
+ Destroy the contained QWidgetBackingStore, if not null, and clear the list of
+ widgets using the backing store, then create a new QWidgetBackingStore, providing
+ the QWidget.
+ */
+void QWidgetBackingStoreTracker::create(QWidget *widget)
+{
+ destroy();
+ m_ptr = new QWidgetBackingStore(widget);
+}
+
+/*!
+ \internal
+ Destroy the contained QWidgetBackingStore, if not null, and clear the list of
+ widgets using the backing store.
+ */
+void QWidgetBackingStoreTracker::destroy()
+{
+ delete m_ptr;
+ m_ptr = 0;
+ m_widgets.clear();
+}
+
+/*!
+ \internal
+ Add the widget to the list of widgets currently using the backing store.
+ If the widget was already in the list, this function is a no-op.
+ */
+void QWidgetBackingStoreTracker::registerWidget(QWidget *w)
+{
+ Q_ASSERT(m_ptr);
+ Q_ASSERT(w->internalWinId());
+ Q_ASSERT(qt_widget_private(w)->maybeBackingStore() == m_ptr);
+ m_widgets.insert(w);
+}
+
+/*!
+ \internal
+ Remove the widget from the list of widgets currently using the backing store.
+ If the widget was in the list, and removing it causes the list to be empty,
+ the backing store is deleted.
+ If the widget was not in the list, this function is a no-op.
+ */
+void QWidgetBackingStoreTracker::unregisterWidget(QWidget *w)
+{
+ if (m_widgets.remove(w) && m_widgets.isEmpty()) {
+ delete m_ptr;
+ m_ptr = 0;
+ }
+}
+
+#endif
+
+// END PRIVATE API
+
+// TQMetaObject *TQWidget::tqstaticMetaObject() {
+// return const_cast<TQMetaObject*>(static_cast<const TQMetaObject*>(&TQT_BASE_OBJECT_NAME::staticMetaObject));
+// }
+
+/*!
+ This is the main event handler; it handles event \a e. You can
+ reimplement this function in a subclass, but we recommend using
+ one of the specialized event handlers instead.
+
+ The main event handler first passes an event through all \link
+ TQObject::installEventFilter() event filters\endlink that have been
+ installed. If none of the filters intercept the event, it calls
+ one of the specialized event handlers.
+
+ Key press and release events are treated differently from other
+ events. event() checks for Tab and Shift+Tab and tries to move the
+ focus appropriately. If there is no widget to move the focus to
+ (or the key press is not Tab or Shift+Tab), event() calls
+ keyPressEvent().
+
+ This function returns TRUE if it is able to pass the event over to
+ someone (i.e. someone wanted the event); otherwise returns FALSE.
+
+ \sa closeEvent(), focusInEvent(), focusOutEvent(), enterEvent(),
+ keyPressEvent(), keyReleaseEvent(), leaveEvent(),
+ mouseDoubleClickEvent(), mouseMoveEvent(), mousePressEvent(),
+ mouseReleaseEvent(), moveEvent(), paintEvent(), resizeEvent(),
+ TQObject::event(), TQObject::timerEvent()
+*/
+
+bool TQWidget::event( TQEvent *e )
+{
+ switch ( e->type() ) {
+// case TQEvent::MouseMove:
+// mouseMoveEvent( (TQMouseEvent*)e );
+// if ( ! ((TQMouseEvent*)e)->isAccepted() )
+// return FALSE;
+// break;
+//
+// case TQEvent::MouseButtonPress:
+// resetInputContext();
+// mousePressEvent( (TQMouseEvent*)e );
+// if ( ! ((TQMouseEvent*)e)->isAccepted() )
+// return FALSE;
+// break;
+//
+// case TQEvent::MouseButtonRelease:
+// mouseReleaseEvent( (TQMouseEvent*)e );
+// if ( ! ((TQMouseEvent*)e)->isAccepted() )
+// return FALSE;
+// break;
+//
+// case TQEvent::MouseButtonDblClick:
+// mouseDoubleClickEvent( (TQMouseEvent*)e );
+// if ( ! ((TQMouseEvent*)e)->isAccepted() )
+// return FALSE;
+// break;
+// #ifndef TQT_NO_WHEELEVENT
+// case TQEvent::Wheel:
+// wheelEvent( (TQWheelEvent*)e );
+// if ( ! ((TQWheelEvent*)e)->isAccepted() )
+// return FALSE;
+// break;
+// #endif
+// // case TQEvent::TabletMove:
+// // case TQEvent::TabletPress:
+// // case TQEvent::TabletRelease:
+// // tabletEvent( (TQTabletEvent*)e );
+// // if ( ! ((TQTabletEvent*)e)->isAccepted() )
+// // return FALSE;
+// // break;
+// // case TQEvent::Accel:
+// // ((TQKeyEvent*)e)->ignore();
+// // return FALSE;
+// case TQEvent::KeyPress: {
+// TQKeyEvent *k = (TQKeyEvent *)e;
+// bool res = FALSE;
+// if ( !(k->state() & ControlButton || k->state() & TQt::AltButton) ) {
+// if ( k->key() == Qt::Key_Backtab ||
+// (k->key() == Qt::Key_Tab &&
+// (k->state() & ShiftButton)) ) {
+// res = focusNextPrevChild( FALSE );
+//
+// } else if ( k->key() == Qt::Key_Tab ) {
+// res = focusNextPrevChild( TRUE );
+// }
+// if ( res )
+// break;
+// }
+// keyPressEvent( k );
+// if ( !k->isAccepted() )
+// return FALSE;
+// }
+// break;
+//
+// case TQEvent::KeyRelease:
+// keyReleaseEvent( (TQKeyEvent*)e );
+// if ( ! ((TQKeyEvent*)e)->isAccepted() )
+// return FALSE;
+// break;
+// //
+// // case TQEvent::IMStart: {
+// // TQIMEvent *i = (TQIMEvent *) e;
+// // imStartEvent(i);
+// // if (! i->isAccepted())
+// // return FALSE;
+// // }
+// // break;
+// //
+// // case TQEvent::IMCompose: {
+// // TQIMEvent *i = (TQIMEvent *) e;
+// // imComposeEvent(i);
+// // if (! i->isAccepted())
+// // return FALSE;
+// // }
+// // break;
+// //
+// // case TQEvent::IMEnd: {
+// // TQIMEvent *i = (TQIMEvent *) e;
+// // imEndEvent(i);
+// // if (! i->isAccepted())
+// // return FALSE;
+// // }
+// // break;
+// //
+// // case TQEvent::FocusIn:
+// // focusInEvent( (TQFocusEvent*)e );
+// // setFontSys();
+// // break;
+//
+// case TQEvent::FocusOut:
+// focusOutEvent( (TQFocusEvent*)e );
+// break;
+//
+// case TQEvent::Enter:
+// enterEvent( e );
+// break;
+//
+// case TQEvent::Leave:
+// leaveEvent( e );
+// break;
+//
+// case TQEvent::Paint:
+// // At this point the event has to be delivered, regardless
+// // whether the widget isVisible() or not because it
+// // already went through the filters
+// paintEvent( (TQPaintEvent*)e );
+// break;
+//
+// case TQEvent::Move:
+// moveEvent( (TQMoveEvent*)e );
+// break;
+//
+// case TQEvent::Resize:
+// resizeEvent( (TQResizeEvent*)e );
+// break;
+//
+// case TQEvent::Close: {
+// TQCloseEvent *c = (TQCloseEvent *)e;
+// closeEvent( c );
+// if ( !c->isAccepted() )
+// return FALSE;
+// }
+// break;
+// //
+// // case TQEvent::ContextMenu: {
+// // TQContextMenuEvent *c = (TQContextMenuEvent *)e;
+// // contextMenuEvent( c );
+// // if ( !c->isAccepted() )
+// // return FALSE;
+// // }
+// // break;
+// //
+// // #ifndef TQT_NO_DRAGANDDROP
+// // case TQEvent::Drop:
+// // dropEvent( (TQDropEvent*) e);
+// // break;
+// //
+// // case TQEvent::DragEnter:
+// // dragEnterEvent( (TQDragEnterEvent*) e);
+// // break;
+// //
+// // case TQEvent::DragMove:
+// // dragMoveEvent( (TQDragMoveEvent*) e);
+// // break;
+// //
+// // case TQEvent::DragLeave:
+// // dragLeaveEvent( (TQDragLeaveEvent*) e);
+// // break;
+// // #endif
+// //
+// case TQEvent::Show:
+// showEvent( (TQShowEvent*) e);
+// break;
+//
+// case TQEvent::Hide:
+// hideEvent( (TQHideEvent*) e);
+// break;
+//
+// // case TQEvent::ShowWindowRequest:
+// // if ( isShown() )
+// // showWindow();
+// // break;
+// //
+// // case TQEvent::ParentFontChange:
+// // if ( isTopLevel() )
+// // break;
+// // // fall through
+// // case TQEvent::ApplicationFontChange:
+// // if ( own_font )
+// // setFont( fnt.resolve( qt_naturalWidgetFont( this ) ) );
+// // else
+// // unsetFont();
+// // break;
+// //
+// // #ifndef TQT_NO_PALETTE
+// // case TQEvent::ParentPaletteChange:
+// // if ( isTopLevel() )
+// // break;
+// // // fall through
+// // case TQEvent::ApplicationPaletteChange:
+// // if ( !own_palette && !isDesktop() )
+// // unsetPalette();
+// // # if defined(TQ_WS_TQWS) && !defined (TQT_NO_TQWS_MANAGER)
+// // if ( isTopLevel() && topData()->qwsManager ) {
+// // TQRegion r( topData()->qwsManager->region() );
+// // TQApplication::postEvent(topData()->qwsManager, new TQPaintEvent(r, FALSE) );
+// // }
+// // # endif
+// // break;
+// // #endif
+// //
+// case TQEvent::WindowActivate:
+// case TQEvent::WindowDeactivate:
+// windowActivationChange( e->type() != TQEvent::WindowActivate );
+// if ( childrenListObject() ) {
+// TQObjectListIt it( *childrenListObject() );
+// TQObject *o;
+// while( ( o = it.current() ) != 0 ) {
+// ++it;
+// if ( o->isWidgetType() &&
+// ((TQWidget*)o)->isVisible() &&
+// !((TQWidget*)o)->isTopLevel() )
+// TQApplication::sendEvent( o, e );
+// }
+// }
+// break;
+// //
+// // case TQEvent::LanguageChange:
+// // case TQEvent::LocaleChange:
+// // if ( childrenListObject() ) {
+// // TQObjectListIt it( *childrenListObject() );
+// // TQObject *o;
+// // while( ( o = it.current() ) != 0 ) {
+// // ++it;
+// // TQApplication::sendEvent( o, e );
+// // }
+// // }
+// // if ( e->type() == TQEvent::LanguageChange ) {
+// // int index = tqmetaObject()->tqfindSlot( "languageChange()", TRUE );
+// // if ( index >= 0 )
+// // qt_invoke( index, 0 );
+// // }
+// // update();
+// // break;
+// // #ifndef TQT_NO_LAYOUT
+// // case TQEvent::LayoutDirectionChange:
+// // if ( tqlayout() ) {
+// // tqlayout()->activate();
+// // } else {
+// // TQObjectList* llist = queryList( "TQLayout", 0, TRUE, TRUE );
+// // TQObjectListIt lit( *llist );
+// // TQLayout *lay;
+// // while ( ( lay = (TQLayout*)lit.current() ) != 0 ) {
+// // ++lit;
+// // lay->activate();
+// // }
+// // delete llist;
+// // }
+// // update();
+// // break;
+// // #endif
+// //
+ case TQEvent::WindowStateChange:
+ {
+ if (tqt_internal_ignore_next_windowstatechange_event == FALSE) {
+ TQEvent::Type type;
+ if (isMinimized())
+ type = TQEvent::ShowMinimized;
+ else if (isFullScreen())
+ type = TQEvent::ShowFullScreen;
+ else if (isMaximized())
+ type = TQEvent::ShowMaximized;
+ else
+ type = TQEvent::ShowNormal;
+ TQApplication::postEvent(this, new TQEvent(type));
+ }
+ else {
+ tqt_internal_ignore_next_windowstatechange_event = FALSE;
+ }
+ break;
+ }
+
+// case TQEvent::WindowBlocked:
+// case TQEvent::WindowUnblocked:
+// if ( childrenListObject() ) {
+// TQObjectListIt it( *childrenListObject() );
+// TQObject *o;
+// while( ( o = it.current() ) != 0 ) {
+// ++it;
+// TQWidget *w = ::tqqt_cast<TQWidget*>(o);
+// if (w && !w->testWFlags(TQt::WShowModal))
+// TQApplication::sendEvent( o, e );
+// }
+// }
+// break;
+
+ case TQEvent::ChildInserted:
+// case TQEvent::ChildRemoved: // Causes a recursion loop if uncommented
+ childEvent( (TQChildEvent*)e );
+ return TRUE;
+
+ default:
+ if ( TQT_TQOBJECT(this)->TQObject::event( e ) )
+ return TRUE;
+ return QWidget::event(e);
+ }
+
+ return TRUE;
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse move events for the widget.
+
+ If mouse tracking is switched off, mouse move events only occur if
+ a mouse button is pressed while the mouse is being moved. If mouse
+ tracking is switched on, mouse move events occur even if no mouse
+ button is pressed.
+
+ TQMouseEvent::pos() reports the position of the mouse cursor,
+ relative to this widget. For press and release events, the
+ position is usually the same as the position of the last mouse
+ move event, but it might be different if the user's hand shakes.
+ This is a feature of the underlying window system, not TQt.
+
+ \sa setMouseTracking(), mousePressEvent(), mouseReleaseEvent(),
+ mouseDoubleClickEvent(), event(), TQMouseEvent
+*/
+
+void TQWidget::mouseMoveEvent( TQMouseEvent * e)
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse press events for the widget.
+
+ If you create new widgets in the mousePressEvent() the
+ mouseReleaseEvent() may not end up where you expect, depending on
+ the underlying window system (or X11 window manager), the widgets'
+ location and maybe more.
+
+ The default implementation implements the closing of popup widgets
+ when you click outside the window. For other widget types it does
+ nothing.
+
+ \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
+ mouseMoveEvent(), event(), TQMouseEvent
+*/
+
+void TQWidget::mousePressEvent( TQMouseEvent *e )
+{
+ e->ignore();
+ if ( isPopup() ) {
+ e->accept();
+ TQWidget* w;
+ while ( (w = TQT_TQWIDGET(tqApp->activePopupWidget()) ) && w != this ){
+ w->close();
+ if (tqApp->activePopupWidget() == w) // widget does not want to dissappear
+ w->hide(); // hide at least
+ }
+ if (!TQT_TQRECT_OBJECT(rect()).tqcontains(e->pos()) ){
+ close();
+ }
+ }
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse release events for the widget.
+
+ \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
+ mouseMoveEvent(), event(), TQMouseEvent
+*/
+
+void TQWidget::mouseReleaseEvent( TQMouseEvent * e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse double click events for the widget.
+
+ The default implementation generates a normal mouse press event.
+
+ Note that the widgets gets a mousePressEvent() and a
+ mouseReleaseEvent() before the mouseDoubleClickEvent().
+
+ \sa mousePressEvent(), mouseReleaseEvent() mouseMoveEvent(),
+ event(), TQMouseEvent
+*/
+
+void TQWidget::mouseDoubleClickEvent( TQMouseEvent *e )
+{
+ mousePressEvent( e ); // try mouse press event
+}
+
+#ifndef TQT_NO_WHEELEVENT
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive wheel events for the widget.
+
+ If you reimplement this handler, it is very important that you
+ \link TQWheelEvent ignore()\endlink the event if you do not handle
+ it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa TQWheelEvent::ignore(), TQWheelEvent::accept(), event(),
+ TQWheelEvent
+*/
+
+void TQWidget::wheelEvent( TQWheelEvent *e )
+{
+ e->ignore();
+}
+#endif
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive tablet events for the widget.
+
+ If you reimplement this handler, it is very important that you
+ \link TQTabletEvent ignore()\endlink the event if you do not handle
+ it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa TQTabletEvent::ignore(), TQTabletEvent::accept(), event(),
+ TQTabletEvent
+*/
+
+void TQWidget::tabletEvent( TQTabletEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive key press events for the widget.
+
+ A widget must call setFocusPolicy() to accept focus initially and
+ have focus in order to receive a key press event.
+
+ If you reimplement this handler, it is very important that you
+ explicitly \link TQKeyEvent::ignore() ignore\endlink the event
+ if you do not understand it, so that the widget's tqparent can
+ interpret it; otherwise, the event will be implicitly accepted.
+ Although top-level widgets are able to choose whether to accept
+ or ignore unknown events because they have no tqparent widgets that
+ could otherwise handle them, it is good practice to explicitly
+ ignore events to make widgets as reusable as possible.
+
+ The default implementation closes popup widgets if the user
+ presses <b>Esc</b>. Otherwise the event is ignored.
+
+ \sa keyReleaseEvent(), TQKeyEvent::ignore(), setFocusPolicy(),
+ focusInEvent(), focusOutEvent(), event(), TQKeyEvent
+*/
+
+void TQWidget::keyPressEvent( TQKeyEvent *e )
+{
+ if ( isPopup() && e->key() == Key_Escape ) {
+ e->accept();
+ close();
+ } else {
+ e->ignore();
+ }
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive key release events for the widget.
+
+ A widget must \link setFocusPolicy() accept focus\endlink
+ initially and \link hasFocus() have focus\endlink in order to
+ receive a key release event.
+
+ If you reimplement this handler, it is very important that you
+ \link TQKeyEvent ignore()\endlink the release if you do not
+ understand it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa keyPressEvent(), TQKeyEvent::ignore(), setFocusPolicy(),
+ focusInEvent(), focusOutEvent(), event(), TQKeyEvent
+*/
+
+void TQWidget::keyReleaseEvent( TQKeyEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ keyboard focus events (focus received) for the widget.
+
+ A widget normally must setFocusPolicy() to something other than
+ \c NoFocus in order to receive focus events. (Note that the
+ application programmer can call setFocus() on any widget, even
+ those that do not normally accept focus.)
+
+ The default implementation updates the widget (except for toplevel
+ widgets that do not specify a focusPolicy() ). It also calls
+ setMicroFocusHint(), hinting any system-specific input tools about
+ the focus of the user's attention.
+
+ \sa focusOutEvent(), setFocusPolicy(), keyPressEvent(),
+ keyReleaseEvent(), event(), TQFocusEvent
+*/
+
+void TQWidget::focusInEvent( TQFocusEvent * )
+{
+ if ( focusPolicy() != Qt::NoFocus || !isTopLevel() ) {
+ update();
+ if ( testWState(TQt::WState_AutoMask) )
+ updateMask();
+ setMicroFocusHint(width()/2, 0, 1, height(), FALSE);
+ }
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ keyboard focus events (focus lost) for the widget.
+
+ A widget normally must setFocusPolicy() to something other than
+ \c NoFocus in order to receive focus events. (Note that the
+ application programmer can call setFocus() on any widget, even
+ those that do not normally accept focus.)
+
+ The default implementation updates the widget (except for toplevel
+ widgets that do not specify a focusPolicy() ). It also calls
+ setMicroFocusHint(), hinting any system-specific input tools about
+ the focus of the user's attention.
+
+ \sa focusInEvent(), setFocusPolicy(), keyPressEvent(),
+ keyReleaseEvent(), event(), TQFocusEvent
+*/
+
+void TQWidget::focusOutEvent( TQFocusEvent * )
+{
+ if ( focusPolicy() != Qt::NoFocus || !isTopLevel() ){
+ update();
+ if ( testWState(TQt::WState_AutoMask) )
+ updateMask();
+ }
+}
+
+/*!
+ \property TQWidget::microFocusHint
+ \brief the currently set micro focus hint for this widget.
+
+ See the documentation of setMicroFocusHint() for more information.
+*/
+TQRect TQWidget::microFocusHint() const
+{
+ if ( !extra )
+ return TQRect(width()/2, 0, 1, height() );
+ else if ( extra->micro_focus_hint.isEmpty() )
+ return TQRect(width()/2, 0, 1, height() );
+ else
+ return extra->micro_focus_hint;
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget enter events.
+
+ An event is sent to the widget when the mouse cursor enters the
+ widget.
+
+ \sa leaveEvent(), mouseMoveEvent(), event()
+*/
+
+void TQWidget::enterEvent( TQEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget leave events.
+
+ A leave event is sent to the widget when the mouse cursor leaves
+ the widget.
+
+ \sa enterEvent(), mouseMoveEvent(), event()
+*/
+
+void TQWidget::leaveEvent( TQEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ paint events.
+
+ A paint event is a request to tqrepaint all or part of the widget.
+ It can happen as a result of tqrepaint() or update(), or because the
+ widget was obscured and has now been uncovered, or for many other
+ reasons.
+
+ Many widgets can simply tqrepaint their entire surface when asked
+ to, but some slow widgets need to optimize by painting only the
+ requested region: TQPaintEvent::region(). This speed optimization
+ does not change the result, as painting is clipped to that region
+ during event processing. TQListView and TQCanvas do this, for
+ example.
+
+ TQt also tries to speed up painting by merging multiple paint
+ events into one. When update() is called several times or the
+ window system sends several paint events, TQt merges these events
+ into one event with a larger region (see TQRegion::unite()).
+ tqrepaint() does not permit this optimization, so we suggest using
+ update() when possible.
+
+ When the paint event occurs, the update region has normally been
+ erased, so that you're painting on the widget's background. There
+ are a couple of exceptions and TQPaintEvent::erased() tells you
+ whether the widget has been erased or not.
+
+ The background can be set using setBackgroundMode(),
+ setPaletteBackgroundColor() or setBackgroundPixmap(). The
+ documentation for setBackgroundMode() elaborates on the
+ background; we recommend reading it.
+
+ \sa event(), tqrepaint(), update(), TQPainter, TQPixmap, TQPaintEvent
+*/
+
+void TQWidget::paintEvent( TQPaintEvent *e )
+{
+// // At least let Qt4 get a shot at painting it
+// QWidget::paintEvent(e);
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget move events. When the widget receives this event, it is
+ already at the new position.
+
+ The old position is accessible through TQMoveEvent::oldPos().
+
+ \sa resizeEvent(), event(), move(), TQMoveEvent
+*/
+
+void TQWidget::moveEvent( TQMoveEvent * )
+{
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget resize events. When resizeEvent() is called, the widget
+ already has its new tqgeometry. The old size is accessible through
+ TQResizeEvent::oldSize().
+
+ The widget will be erased and receive a paint event immediately
+ after processing the resize event. No drawing need be (or should
+ be) done inside this handler.
+
+ Widgets that have been created with the \c WNoAutoErase flag
+ will not be erased. Nevertheless, they will receive a paint event
+ for their entire area afterwards. Again, no drawing needs to be
+ done inside this handler.
+
+ The default implementation calls updateMask() if the widget has
+ \link TQWidget::setAutoMask() automatic masking\endlink enabled.
+
+ \sa moveEvent(), event(), resize(), TQResizeEvent, paintEvent()
+*/
+
+void TQWidget::resizeEvent( TQResizeEvent * )
+{
+ if ( testWState(TQt::WState_AutoMask) )
+ updateMask();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive widget close events.
+
+ The default implementation calls e->accept(), which hides this
+ widget. See the \l TQCloseEvent documentation for more details.
+
+ \sa event(), hide(), close(), TQCloseEvent
+*/
+
+void TQWidget::closeEvent( TQCloseEvent *e )
+{
+ e->accept();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive widget context menu events.
+
+ The default implementation calls e->ignore(), which rejects the
+ context event. See the \l TQContextMenuEvent documentation for
+ more details.
+
+ \sa event(), TQContextMenuEvent
+*/
+
+void TQWidget::contextMenuEvent( TQContextMenuEvent *e )
+{
+ e->ignore();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user begins entering text using an Input Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQWidget::imStartEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user has entered some text using an Input Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQWidget::imComposeEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user has finished inputting text via an Input
+ Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQWidget::imEndEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse enters this widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragEnterEvent
+*/
+void TQWidget::dragEnterEvent( TQDragEnterEvent * )
+{
+}
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse enters this widget, and whenever it moves within the widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragMoveEvent
+*/
+void TQWidget::dragMoveEvent( TQDragMoveEvent * )
+{
+}
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse leaves this widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragLeaveEvent
+*/
+void TQWidget::dragLeaveEvent( TQDragLeaveEvent * )
+{
+}
+
+/*!
+ This event handler is called when the drag is dropped on this
+ widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDropEvent
+*/
+void TQWidget::dropEvent( TQDropEvent * )
+{
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget show events.
+
+ Non-spontaneous show events are sent to widgets immediately before
+ they are shown. The spontaneous show events of top-level widgets
+ are delivered afterwards.
+
+ \sa event(), TQShowEvent
+*/
+void TQWidget::showEvent( TQShowEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget hide events.
+
+ Hide events are sent to widgets immediately after they have been
+ hidden.
+
+ \sa event(), TQHideEvent
+*/
+void TQWidget::hideEvent( TQHideEvent * )
+{
+}
+
+/*
+ \fn TQWidget::x11Event( MSG * )
+
+ This special event handler can be reimplemented in a subclass to
+ receive native X11 events.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by TQt, return TRUE. If you return FALSE, this
+ native event is passed back to TQt, which translates the event into
+ a TQt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa TQApplication::x11EventFilter()
+*/
+
+
+#if defined(TQ_WS_MAC)
+
+/*!
+ This special event handler can be reimplemented in a subclass to
+ receive native Macintosh events.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by TQt, return TRUE. If you return FALSE, this
+ native event is passed back to TQt, which translates the event into
+ a TQt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa TQApplication::macEventFilter()
+*/
+
+bool TQWidget::macEvent( MSG * )
+{
+ return FALSE;
+}
+
+#endif
+#if defined(TQ_WS_WIN)
+
+/*!
+ This special event handler can be reimplemented in a subclass to
+ receive native Windows events.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by TQt, return TRUE. If you return FALSE, this
+ native event is passed back to TQt, which translates the event into
+ a TQt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa TQApplication::winEventFilter()
+*/
+bool TQWidget::winEvent( MSG * )
+{
+ return FALSE;
+}
+
+#endif
+#if defined(TQ_WS_X11)
+
+/*!
+ This special event handler can be reimplemented in a subclass to
+ receive native X11 events.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by TQt, return TRUE. If you return FALSE, this
+ native event is passed back to TQt, which translates the event into
+ a TQt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa TQApplication::x11EventFilter()
+*/
+bool TQWidget::x11Event( XEvent * )
+{
+ return FALSE;
+}
+
+#endif
+#if defined(TQ_WS_TQWS)
+
+/*!
+ This special event handler can be reimplemented in a subclass to
+ receive native TQt/Embedded events.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by TQt, return TRUE. If you return FALSE, this
+ native event is passed back to TQt, which translates the event into
+ a TQt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa TQApplication::qwsEventFilter()
+*/
+bool TQWidget::qwsEvent( TQWSEvent * )
+{
+ return FALSE;
+}
+
+#endif
+
+void TQWidget::timerEvent( TQTimerEvent * )
+{
+}
+
+void TQWidget::childEvent( TQChildEvent * )
+{
+}
+
+void TQWidget::customEvent( TQCustomEvent * )
+{
+}
+
+bool TQWidget::eventFilter( TQObject * /* watched */, TQEvent * /* e */ )
+{
+ return FALSE;
+}
+
+int TQWidget::x11Depth() const {
+ const QX11Info *info = &x11Info();
+ if (info)
+ return info->depth();
+ return QX11Info::appDepth();
+}
+
+/*!
+ Adjusts the size of the widget to fit the contents.
+
+ Uses tqsizeHint() if valid (i.e if the size hint's width and height
+ are \>= 0), otherwise sets the size to the tqchildren rectangle (the
+ union of all child widget geometries).
+
+ \sa tqsizeHint(), tqchildrenRect()
+*/
+
+void TQWidget::adjustSize()
+{
+ TQApplication::sendPostedEvents( 0, TQEvent::ChildInserted );
+ TQApplication::sendPostedEvents( 0, TQEvent::LayoutHint );
+ if ( !testWState(WState_Polished) )
+ polish();
+ TQSize s = tqsizeHint();
+
+ if ( isTopLevel() ) {
+
+#if defined(TQ_WS_X11)
+ TQRect screen = TQApplication::desktop()->screenGeometry( x11Screen() );
+#else // all others
+ TQRect screen = TQApplication::desktop()->screenGeometry( pos() );
+#endif
+
+#ifndef TQT_NO_LAYOUT
+ if ( tqlayout() ) {
+ if ( tqlayout()->hasHeightForWidth() ) {
+ s = s.boundedTo( screen.size() );
+ s.setHeight( tqlayout()->totalHeightForWidth( s.width() ) );
+ }
+ } else
+#endif
+ {
+ if ( sizePolicy().hasHeightForWidth() ) {
+ s = s.boundedTo( screen.size() );
+ s.setHeight( heightForWidth( s.width() ) );
+ }
+ }
+ }
+ if ( s.isValid() ) {
+ resize( s );
+ return;
+ }
+ TQRect r = tqchildrenRect(); // get tqchildren rectangle
+ if ( r.isNull() ) // probably no widgets
+ return;
+ resize( r.width() + 2 * r.x(), r.height() + 2 * r.y() );
+}
+
+bool TQWidget::isA( const char *classname ) const
+{
+ if (tqstrcmp(classname, metaObject()->className()) == 0) return true;
+ else {
+ TQString cn = metaObject()->className();
+ if (cn[0] == 'T')
+ cn = cn.remove(0,1);
+ return (tqstrcmp(classname, cn.ascii()) == 0);
+ }
+}
+
+bool TQWidget::inherits( const char *classname ) const {
+ if (QWidget::inherits(classname)) return true;
+ else {
+ TQString cn = classname;
+ if (cn[0] != 'T')
+ cn = cn.prepend('T');
+ return QWidget::inherits(cn.ascii());
+ }
+}
+
+void TQWidget::setWState( uint state ) {
+ if (state == TQt::WState_OwnSizePolicy) setAttribute(Qt::WA_WState_OwnSizePolicy, true);
+ else if (state == TQt::WState_BlockUpdates) setAttribute(Qt::WA_ForceUpdatesDisabled, true);
+ else {
+ tqt_internal_ignore_next_windowstatechange_event = TRUE;
+ overrideWindowState((Qt::WindowState) (windowState() | state));
+ }
+}
+
+void TQWidget::clearWState( uint flags ) {
+ if (flags == TQt::WState_OwnSizePolicy)
+ setAttribute(Qt::WA_WState_OwnSizePolicy, false);
+ else if (flags == TQt::WState_BlockUpdates)
+ setAttribute(Qt::WA_ForceUpdatesDisabled, false);
+ else {
+ tqt_internal_ignore_next_windowstatechange_event = TRUE;
+ overrideWindowState((QWidget::windowState() &= (Qt::WindowState)(~flags)));
+ }
+}
+
+WState TQWidget::getWState() const {
+ return QWidget::windowState();
+}
+
+WState TQWidget::testWState( WState s ) const {
+ if (s == TQt::WState_OwnSizePolicy)
+ return (WState)(testAttribute(Qt::WA_WState_OwnSizePolicy) ? TQt::WState_OwnSizePolicy : 0);
+ else if (s == TQt::WState_BlockUpdates)
+ return (WState)(testAttribute(Qt::WA_ForceUpdatesDisabled) ? TQt::WState_BlockUpdates : 0);
+ else
+ return (QWidget::windowState() & s);
+}
+
+WState TQWidget::testWState( TQt::WidgetState s ) const {
+ if (s == TQt::WState_OwnSizePolicy)
+ return (WState)(testAttribute(Qt::WA_WState_OwnSizePolicy) ? TQt::WState_OwnSizePolicy : 0);
+ else if (s == TQt::WState_BlockUpdates)
+ return (WState)(testAttribute(Qt::WA_ForceUpdatesDisabled) ? TQt::WState_BlockUpdates : 0);
+ else
+ return (QWidget::windowState() & s);
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQWidget tqwidget.h
+ \brief The TQWidget class is the base class of all user interface objects.
+
+ \ingroup abstractwidgets
+ \mainclass
+
+ The widget is the atom of the user interface: it receives mouse,
+ keyboard and other events from the window system, and paints a
+ representation of itself on the screen. Every widget is
+ rectangular, and they are sorted in a Z-order. A widget is
+ clipped by its tqparent and by the widgets in front of it.
+
+ A widget that isn't embedded in a tqparent widget is called a
+ top-level widget. Usually, top-level widgets are windows with a
+ frame and a title bar (although it is also possible to create
+ top-level widgets without such decoration if suitable widget flags
+ are used). In TQt, TQMainWindow and the various subclasses of
+ TQDialog are the most common top-level windows.
+
+ A widget without a tqparent widget is always a top-level widget.
+
+ Non-top-level widgets are child widgets. These are child windows
+ in their tqparent widgets. You cannot usually distinguish a child
+ widget from its tqparent visually. Most other widgets in TQt are
+ useful only as child widgets. (It is possible to make, say, a
+ button into a top-level widget, but most people prefer to put
+ their buttons inside other widgets, e.g. TQDialog.)
+
+ If you want to use a TQWidget to hold child widgets you will
+ probably want to add a tqlayout to the tqparent TQWidget. (See \link
+ tqlayout.html Layouts\endlink.)
+
+ TQWidget has many member functions, but some of them have little
+ direct functionality: for example, TQWidget has a font property,
+ but never uses this itself. There are many subclasses which
+ provide real functionality, such as TQPushButton, TQListBox and
+ TQTabDialog, etc.
+
+ \section1 Groups of functions:
+
+ \table
+ \header \i Context \i Functions
+
+ \row \i Window functions \i
+ show(),
+ hide(),
+ raise(),
+ lower(),
+ close().
+
+ \row \i Top level windows \i
+ caption(),
+ setCaption(),
+ icon(),
+ setIcon(),
+ iconText(),
+ setIconText(),
+ isActiveWindow(),
+ setActiveWindow(),
+ showMinimized().
+ showMaximized(),
+ showFullScreen(),
+ showNormal().
+
+ \row \i Window contents \i
+ update(),
+ tqrepaint(),
+ erase(),
+ scroll(),
+ updateMask().
+
+ \row \i Geometry \i
+ pos(),
+ size(),
+ rect(),
+ x(),
+ y(),
+ width(),
+ height(),
+ sizePolicy(),
+ tqsetSizePolicy(),
+ tqsizeHint(),
+ updateGeometry(),
+ tqlayout(),
+ move(),
+ resize(),
+ setGeometry(),
+ frameGeometry(),
+ tqgeometry(),
+ tqchildrenRect(),
+ adjustSize(),
+ mapFromGlobal(),
+ mapFromParent()
+ mapToGlobal(),
+ mapToParent(),
+ tqmaximumSize(),
+ tqminimumSize(),
+ sizeIncrement(),
+ setMaximumSize(),
+ setMinimumSize(),
+ setSizeIncrement(),
+ setBaseSize(),
+ setFixedSize()
+
+ \row \i Mode \i
+ isVisible(),
+ isVisibleTo(),
+ isMinimized(),
+ isDesktop(),
+ isEnabled(),
+ isEnabledTo(),
+ isModal(),
+ isPopup(),
+ isTopLevel(),
+ setEnabled(),
+ hasMouseTracking(),
+ setMouseTracking(),
+ isUpdatesEnabled(),
+ setUpdatesEnabled(),
+ clipRegion().
+
+ \row \i Look and feel \i
+ style(),
+ setStyle(),
+ cursor(),
+ setCursor()
+ font(),
+ setFont(),
+ palette(),
+ setPalette(),
+ backgroundMode(),
+ setBackgroundMode(),
+ tqcolorGroup(),
+ fontMetrics(),
+ fontInfo().
+
+ \row \i Keyboard focus<br>functions \i
+ isFocusEnabled(),
+ setFocusPolicy(),
+ focusPolicy(),
+ hasFocus(),
+ setFocus(),
+ clearFocus(),
+ setTabOrder(),
+ setFocusProxy().
+
+ \row \i Mouse and<br>keyboard grabbing \i
+ grabMouse(),
+ releaseMouse(),
+ grabKeyboard(),
+ releaseKeyboard(),
+ mouseGrabber(),
+ keyboardGrabber().
+
+ \row \i Event handlers \i
+ event(),
+ mousePressEvent(),
+ mouseReleaseEvent(),
+ mouseDoubleClickEvent(),
+ mouseMoveEvent(),
+ keyPressEvent(),
+ keyReleaseEvent(),
+ focusInEvent(),
+ focusOutEvent(),
+ wheelEvent(),
+ enterEvent(),
+ leaveEvent(),
+ paintEvent(),
+ moveEvent(),
+ resizeEvent(),
+ closeEvent(),
+ dragEnterEvent(),
+ dragMoveEvent(),
+ dragLeaveEvent(),
+ dropEvent(),
+ childEvent(),
+ showEvent(),
+ hideEvent(),
+ customEvent().
+
+ \row \i Change handlers \i
+ enabledChange(),
+ fontChange(),
+ paletteChange(),
+ styleChange(),
+ windowActivationChange().
+
+ \row \i System functions \i
+ parentWidget(),
+ tqtopLevelWidget(),
+ reparent(),
+ polish(),
+ winId(),
+ tqfind(),
+ metric().
+
+ \row \i What's this help \i
+ customWhatsThis()
+
+ \row \i Internal kernel<br>functions \i
+ focusNextPrevChild(),
+ wmapper(),
+ clearWFlags(),
+ getWFlags(),
+ setWFlags(),
+ testWFlags().
+
+ \endtable
+
+ Every widget's constructor accepts two or three standard arguments:
+ \list 1
+ \i \c{TQWidget *tqparent = 0} is the tqparent of the new widget.
+ If it is 0 (the default), the new widget will be a top-level window.
+ If not, it will be a child of \e tqparent, and be constrained by \e
+ tqparent's tqgeometry (unless you specify \c WType_TopLevel as
+ widget flag).
+ \i \c{const char *name = 0} is the widget name of the new
+ widget. You can access it using name(). The widget name is little
+ used by programmers but is quite useful with GUI builders such as
+ \e{TQt Designer} (you can name a widget in \e{TQt Designer}, and
+ connect() to it using the name in your code). The dumpObjectTree()
+ debugging function also uses it.
+ \i \c{WFlags f = 0} (where available) sets the widget flags; the
+ default is suitable for almost all widgets, but to get, for
+ example, a top-level widget without a window system frame, you
+ must use special flags.
+ \endlist
+
+ The tictac/tictac.cpp example program is good example of a simple
+ widget. It tqcontains a few event handlers (as all widgets must), a
+ few custom routines that are specific to it (as all useful widgets
+ do), and has a few tqchildren and connections. Everything it does
+ is done in response to an event: this is by far the most common way
+ to design GUI applications.
+
+ You will need to supply the content for your widgets yourself, but
+ here is a brief run-down of the events, starting with the most common
+ ones:
+
+ \list
+
+ \i paintEvent() - called whenever the widget needs to be
+ repainted. Every widget which displays output must implement it,
+ and it is wise \e not to paint on the screen outside
+ paintEvent().
+
+ \i resizeEvent() - called when the widget has been resized.
+
+ \i mousePressEvent() - called when a mouse button is pressed.
+ There are six mouse-related events, but the mouse press and mouse
+ release events are by far the most important. A widget receives
+ mouse press events when the mouse is inside it, or when it has
+ grabbed the mouse using grabMouse().
+
+ \i mouseReleaseEvent() - called when a mouse button is released.
+ A widget receives mouse release events when it has received the
+ corresponding mouse press event. This means that if the user
+ presses the mouse inside \e your widget, then drags the mouse to
+ somewhere else, then releases, \e your widget receives the release
+ event. There is one exception: if a popup menu appears while the
+ mouse button is held down, this popup immediately steals the mouse
+ events.
+
+ \i mouseDoubleClickEvent() - not quite as obvious as it might seem.
+ If the user double-clicks, the widget receives a mouse press event
+ (perhaps a mouse move event or two if they don't hold the mouse
+ quite steady), a mouse release event and finally this event. It is
+ \e{not possible} to distinguish a click from a double click until you've
+ seen whether the second click arrives. (This is one reason why most GUI
+ books recommend that double clicks be an extension of single clicks,
+ rather than trigger a different action.)
+
+ \endlist
+
+ If your widget only tqcontains child widgets, you probably do not need to
+ implement any event handlers. If you want to detect a mouse click in
+ a child widget call the child's hasMouse() function inside the
+ tqparent widget's mousePressEvent().
+
+ Widgets that accept keyboard input need to reimplement a few more
+ event handlers:
+
+ \list
+
+ \i keyPressEvent() - called whenever a key is pressed, and again
+ when a key has been held down long enough for it to auto-repeat.
+ Note that the Tab and Shift+Tab keys are only passed to the widget
+ if they are not used by the focus-change mechanisms. To force those
+ keys to be processed by your widget, you must reimplement
+ TQWidget::event().
+
+ \i focusInEvent() - called when the widget gains keyboard focus
+ (assuming you have called setFocusPolicy()). Well written widgets
+ indicate that they own the keyboard focus in a clear but discreet
+ way.
+
+ \i focusOutEvent() - called when the widget loses keyboard focus.
+
+ \endlist
+
+ Some widgets will also need to reimplement some of the less common
+ event handlers:
+
+ \list
+
+ \i mouseMoveEvent() - called whenever the mouse moves while a
+ button is held down. This is useful for, for example, dragging. If
+ you call setMouseTracking(TRUE), you get mouse move events even
+ when no buttons are held down. (Note that applications which make
+ use of mouse tracking are often not very useful on low-bandwidth X
+ connections.) (See also the \link dnd.html drag and drop\endlink
+ information.)
+
+ \i keyReleaseEvent() - called whenever a key is released, and also
+ while it is held down if the key is auto-repeating. In that case
+ the widget receives a key release event and immediately a key press
+ event for every repeat. Note that the Tab and Shift+Tab keys are
+ only passed to the widget if they are not used by the focus-change
+ mechanisms. To force those keys to be processed by your widget, you
+ must reimplement TQWidget::event().
+
+ \i wheelEvent() -- called whenever the user turns the mouse wheel
+ while the widget has the focus.
+
+ \i enterEvent() - called when the mouse enters the widget's screen
+ space. (This excludes screen space owned by any tqchildren of the
+ widget.)
+
+ \i leaveEvent() - called when the mouse leaves the widget's screen
+ space.
+
+ \i moveEvent() - called when the widget has been moved relative to its
+ tqparent.
+
+ \i closeEvent() - called when the user closes the widget (or when
+ close() is called).
+
+ \endlist
+
+ There are also some rather obscure events. They are listed in
+ \c tqevent.h and you need to reimplement event() to handle them.
+ The default implementation of event() handles Tab and Shift+Tab
+ (to move the keyboard focus), and passes on most other events to
+ one of the more specialized handlers above.
+
+ When implementing a widget, there are a few more things to
+ consider.
+
+ \list
+
+ \i In the constructor, be sure to set up your member variables
+ early on, before there's any chance that you might receive an event.
+
+ \i It is almost always useful to reimplement tqsizeHint() and to set
+ the correct size policy with tqsetSizePolicy(), so users of your class
+ can set up tqlayout management more easily. A size policy lets you
+ supply good defaults for the tqlayout management handling, so that
+ other widgets can contain and manage yours easily. tqsizeHint()
+ indicates a "good" size for the widget.
+
+ \i If your widget is a top-level window, setCaption() and setIcon() set
+ the title bar and icon respectively.
+
+ \endlist
+
+ \sa TQEvent, TQPainter, TQGridLayout, TQBoxLayout
+*/
+
+
+/*****************************************************************************
+ Internal TQWidgetMapper class
+
+ The purpose of this class is to map widget identifiers to TQWidget objects.
+ All TQWidget objects register themselves in the TQWidgetMapper when they
+ get an identifier. Widgets unregister themselves when they change ident-
+ ifier or when they are destroyed. A widget identifier is really a window
+ handle.
+
+ The widget mapper is created and destroyed by the main application routines
+ in the file qapp_xxx.cpp.
+ *****************************************************************************/
+
+#if defined(TQ_WS_TQWS) || defined(TQ_OS_TEMP)
+static const int WDictSize = 163; // plenty for small tqdevices
+#else
+static const int WDictSize = 1123; // plenty for 5 big complex windows
+#endif
+
+class TQWidgetMapper : public TQWidgetIntDict
+{ // maps ids -> widgets
+public:
+ TQWidgetMapper();
+ ~TQWidgetMapper();
+ TQWidget *tqfind( WId id ); // tqfind widget
+ void insert( const TQWidget * ); // insert widget
+ bool remove( WId id ); // remove widget
+private:
+ WId cur_id;
+ TQWidget *cur_widget;
+};
+
+TQWidgetMapper *TQWidget::wmapper() = 0; // app global widget mapper
+
+
+TQWidgetMapper::TQWidgetMapper() : TQWidgetIntDict(WDictSize)
+{
+ cur_id = 0;
+ cur_widget = 0;
+}
+
+TQWidgetMapper::~TQWidgetMapper()
+{
+ clear();
+}
+
+inline TQWidget *TQWidgetMapper::tqfind( WId id )
+{
+ if ( id != cur_id ) { // need to lookup
+ cur_widget = TQWidgetIntDict::tqfind((long)id);
+ if ( cur_widget )
+ cur_id = id;
+ else
+ cur_id = 0;
+ }
+ return cur_widget;
+}
+
+inline void TQWidgetMapper::insert( const TQWidget *widget )
+{
+ TQWidgetIntDict::insert((long)widget->winId(),widget);
+}
+
+inline bool TQWidgetMapper::remove( WId id )
+{
+ if ( cur_id == id ) { // reset current widget
+ cur_id = 0;
+ cur_widget = 0;
+ }
+ return TQWidgetIntDict::remove((long)id);
+}
+
+
+/*****************************************************************************
+ TQWidget utility functions
+ *****************************************************************************/
+
+static TQFont qt_naturalWidgetFont( TQWidget* w ) {
+ TQFont naturalfont = TQApplication::font( w );
+ if ( ! w->isTopLevel() ) {
+ if ( ! naturalfont.isCopyOf( TQApplication::font() ) )
+ naturalfont = naturalfont.resolve( w->parentWidget()->font() );
+ else
+ naturalfont = w->parentWidget()->font();
+ }
+ return naturalfont;
+}
+
+#ifndef TQT_NO_PALETTE
+static TQPalette qt_naturalWidgetPalette( TQWidget* w ) {
+ TQPalette naturalpalette = TQApplication::palette( w );
+ if ( !w->isTopLevel() && naturalpalette.isCopyOf( TQApplication::palette() ) )
+ naturalpalette = w->parentWidget()->palette();
+ return naturalpalette;
+}
+#endif
+
+TQSize qt_naturalWidgetSize( TQWidget *w ) {
+ TQSize s = w->tqsizeHint();
+ TQ_SPExpandData exp;
+#ifndef TQT_NO_LAYOUT
+ if ( w->tqlayout() ) {
+ if ( w->tqlayout()->hasHeightForWidth() )
+ s.setHeight( w->tqlayout()->totalHeightForWidth( s.width() ) );
+ exp = w->tqlayout()->expandingDirections();
+ } else
+#endif
+ {
+ if ( w->sizePolicy().hasHeightForWidth() )
+ s.setHeight( w->heightForWidth( s.width() ) );
+ exp = w->sizePolicy().expandingDirections();
+ }
+ if ( exp & TQSizePolicy::Horizontally )
+ s.setWidth( TQMAX( s.width(), 200 ) );
+ if ( exp & TQSizePolicy::Vertically )
+ s.setHeight( TQMAX( s.height(), 150 ) );
+#if defined(TQ_WS_X11)
+ TQRect screen = TQApplication::desktop()->screenGeometry( w->x11Screen() );
+#else // all others
+ TQRect screen = TQApplication::desktop()->screenGeometry( w->pos() );
+#endif
+ s.setWidth( TQMIN( s.width(), screen.width()*2/3 ) );
+ s.setHeight( TQMIN( s.height(), screen.height()*2/3 ) );
+ return s;
+}
+
+/*****************************************************************************
+ TQWidget member functions
+ *****************************************************************************/
+
+/*
+ Widget state flags:
+ \list
+ \i WState_Created The widget has a valid winId().
+ \i WState_Disabled The widget does not receive any mouse or keyboard
+ events.
+ \i WState_ForceDisabled The widget is explicitly disabled, i.e. it
+ will remain disabled even when all its ancestors are set to the enabled
+ state. This implies WState_Disabled.
+ \i WState_Visible The widget is currently visible.
+ \i WState_ForceHide The widget is explicitly hidden, i.e. it won't
+ become visible unless you call show() on it. WState_ForceHide
+ implies !WState_Visible.
+ \i WState_OwnCursor A cursor has been set for this widget.
+ \i WState_MouseTracking Mouse tracking is enabled.
+ \i WState_CompressKeys Compress keyboard events.
+ \i WState_BlockUpdates Repaints and updates are disabled.
+ \i WState_InPaintEvent Currently processing a paint event.
+ \i WState_Reparented The widget has been reparented.
+ \i WState_ConfigPending A configuration (resize/move) event is pending.
+ \i WState_Resized The widget has been resized.
+ \i WState_AutoMask The widget has an automatic tqmask, see setAutoMask().
+ \i WState_Polished The widget has been "polished" (i.e. late
+ initialization) by a TQStyle.
+ \i WState_DND The widget supports drag and drop, see setAcceptDrops().
+ \i WState_Exposed the widget was finally exposed (X11 only,
+ helps avoid paint event doubling).
+ \i WState_HasMouse The widget is under the mouse cursor.
+ \endlist
+*/
+
+/*! \enum TQt::WFlags
+ \internal */
+/*! \enum TQt::WState
+ \internal */
+
+/*!
+ \enum TQt::WidgetFlags
+
+ \keyword widget flag
+
+ This enum type is used to specify various window-system properties
+ for the widget. They are fairly unusual but necessary in a few
+ cases. Some of these flags depend on whether the underlying window
+ manager supports them. (See the \link toplevel-example.html
+ toplevel example\endlink for an explanation and example of their
+ use.)
+
+ The main types are
+
+ \value WType_TopLevel indicates that this widget is a top-level
+ widget, usually with a window-system frame and so on.
+
+ \value WType_Dialog indicates that this widget is a top-level
+ window that should be decorated as a dialog (i.e. typically no
+ maximize or minimize buttons in the title bar). If you want to use
+ it as a modal dialog it should be launched from another window, or
+ have a tqparent and this flag should be combined with \c WShowModal.
+ If you make it modal, the dialog will prevent other top-level
+ windows in the application from getting any input. \c WType_Dialog
+ implies \c WType_TopLevel. We refer to a top-level window that has
+ a tqparent as a \e secondary window. (See also \c WGroupLeader.)
+
+ \value WType_Popup indicates that this widget is a popup
+ top-level window, i.e. that it is modal, but has a window system
+ frame appropriate for popup menus. \c WType_Popup implies
+ WType_TopLevel.
+
+ \value WType_Desktop indicates that this widget is the desktop.
+ See also \c WPaintDesktop below. \c WType_Desktop implies \c
+ WType_TopLevel.
+
+ There are also a number of flags which you can use to customize
+ the appearance of top-level windows. These have no effect on other
+ windows:
+
+ \value WStyle_Customize indicates that the \c WStyle_* flags
+ should be used to build the window instead of the default flags.
+
+ \value WStyle_NormalBorder gives the window a normal border.
+ This cannot be combined with \c WStyle_DialogBorder or \c
+ WStyle_NoBorder.
+
+ \value WStyle_DialogBorder gives the window a thin dialog border.
+ This cannot be combined with \c WStyle_NormalBorder or \c
+ WStyle_NoBorder.
+
+ \value WStyle_NoBorder produces a borderless window. Note that
+ the user cannot move or resize a borderless window via the window
+ system. This cannot be combined with \c WStyle_NormalBorder or \c
+ WStyle_DialogBorder. On Windows, the flag works fine. On X11, the
+ result of the flag is dependent on the window manager and its
+ ability to understand MOTIF and/or NETWM hints: most existing
+ modern window managers can handle this. With \c WX11BypassWM, you
+ can bypass the window manager completely. This results in a
+ borderless window that is not managed at all (i.e. no keyboard
+ input unless you call setActiveWindow() manually).
+
+ \value WStyle_NoBorderEx this value is obsolete. It has the same
+ effect as using \c WStyle_NoBorder.
+
+ \value WStyle_Title gives the window a title bar.
+
+ \value WStyle_SysMenu adds a window system menu.
+
+ \value WStyle_Minimize adds a minimize button. Note that on
+ Windows this has to be combined with \c WStyle_SysMenu for it to
+ work.
+
+ \value WStyle_Maximize adds a maximize button. Note that on
+ Windows this has to be combined with \c WStyle_SysMenu for it to work.
+
+ \value WStyle_MinMax is equal to \c
+ WStyle_Minimize|WStyle_Maximize. Note that on Windows this has to
+ be combined with \c WStyle_SysMenu to work.
+
+ \value WStyle_ContextHelp adds a context help button to dialogs.
+
+ \value WStyle_Tool makes the window a tool window. A tool window
+ is often a small window with a smaller than usual title bar and
+ decoration, typically used for collections of tool buttons. It
+ there is a tqparent, the tool window will always be kept on top of
+ it. If there isn't a tqparent, you may consider passing \c
+ WStyle_StaysOnTop as well. If the window system supports it, a
+ tool window can be decorated with a somewhat lighter frame. It can
+ also be combined with \c WStyle_NoBorder.
+
+ \value WStyle_StaysOnTop informs the window system that the
+ window should stay on top of all other windows. Note that on some
+ window managers on X11 you also have to pass \c WX11BypassWM for
+ this flag to work correctly.
+
+ \value WStyle_Dialog indicates that the window is a logical
+ subwindow of its tqparent (i.e. a dialog). The window will not get
+ its own taskbar entry and will be kept on top of its tqparent by the
+ window system. Usually it will also be minimized when the tqparent
+ is minimized. If not customized, the window is decorated with a
+ slightly simpler title bar. This is the flag TQDialog uses.
+
+ \value WStyle_Splash indicates that the window is a splash screen.
+ On X11, we try to follow NETWM standard for a splash screen window if the
+ window manager supports is otherwise it is equivalent to \c WX11BypassWM. On
+ other platforms, it is equivalent to \c WStyle_NoBorder \c | \c WMacNoSheet \c |
+ \c WStyle_Tool \c | \c WWinOwnDC
+
+ Modifier flags:
+
+ \value WDestructiveClose makes TQt delete this widget when the
+ widget has accepted closeEvent(), or when the widget tried to
+ ignore closeEvent() but could not.
+
+ \value WPaintDesktop gives this widget paint events for the
+ desktop.
+
+ \value WPaintUnclipped makes all painters operating on this
+ widget unclipped. Children of this widget or other widgets in
+ front of it do not clip the area the painter can paint on.
+
+ \value WPaintClever indicates that TQt should \e not try to
+ optimize repainting for the widget, but instead pass on window
+ system tqrepaint events directly. (This tends to produce more events
+ and smaller tqrepaint regions.)
+
+ \value WMouseNoMask indicates that even if the widget has a tqmask,
+ it wants mouse events for its entire rectangle.
+
+ \value WStaticContents indicates that the widget contents are
+ north-west aligned and static. On resize, such a widget will
+ receive paint events only for the newly visible part of itself.
+
+ \value WNoAutoErase indicates that the widget paints all its
+ pixels. Updating, resizing, scrolling and focus changes should
+ therefore not erase the widget. This allows smart-repainting to
+ avoid flicker.
+
+ \value WResizeNoErase this value is obsolete; use WNoAutoErase instead.
+ \value WRepaintNoErase this value is obsolete; use WNoAutoErase instead.
+ \value WGroupLeader makes this window a group leader. A group
+ leader should \e not have a tqparent (i.e. it should be a top-level
+ window). Any decendant windows (direct or indirect) of a group
+ leader are in its group; other windows are not. If you show a
+ secondary window from the group (i.e. show a window whose top-most
+ tqparent is a group leader), that window will be modal with respect
+ to the other windows in the group, but modeless with respect to
+ windows in other groups.
+
+ Miscellaneous flags
+
+ \value WShowModal see WType_Dialog
+
+ Internal flags.
+
+ \value WNoMousePropagation
+ \value WStaticContents
+ \value WStyle_Reserved
+ \value WSubWindow
+ \value WType_Modal
+ \value WWinOwnDC
+ \value WX11BypassWM
+ \value WMacNoSheet
+ \value WMacDrawer
+ \value WStyle_Mask
+ \value WType_Mask
+
+*/
+
+/*!
+ \enum TQt::WidgetState
+
+ Internal flags.
+
+ \value WState_Created
+ \value WState_Disabled
+ \value WState_Visible
+ \value WState_ForceHide
+ \value WState_OwnCursor
+ \value WState_MouseTracking
+ \value WState_CompressKeys
+ \value WState_BlockUpdates
+ \value WState_InPaintEvent
+ \value WState_Reparented
+ \value WState_ConfigPending
+ \value WState_Resized
+ \value WState_AutoMask
+ \value WState_Polished
+ \value WState_DND
+ \value WState_Reserved0 \e internal
+ \value WState_CreatedHidden
+ \value WState_Maximized
+ \value WState_Minimized
+ \value WState_ForceDisabled
+ \value WState_Exposed
+ \value WState_HasMouse
+ \value WState_CreatedHidden
+ \value WState_OwnSizePolicy
+ \value WState_FullScreen
+*/
+
+
+/*!
+ \enum TQt::WindowState
+
+ \keyword window state
+
+ This enum type is used to specify the current state of a top-level
+ window.
+
+ The states are
+
+ \value WindowNoState The window has no state set (in normal state).
+ \value WindowMinimized The window is minimized (i.e. iconified).
+ \value WindowMaximized The window is maximized with a frame around it.
+ \value WindowFullScreen The window fills the entire screen without any frame around it.
+ \value WindowActive The window is the active window, i.e. it has keyboard focus.
+
+*/
+
+/*!
+ Constructs a widget which is a child of \a tqparent, with the name
+ \a name and widget flags set to \a f.
+
+ If \a tqparent is 0, the new widget becomes a top-level window. If
+ \a tqparent is another widget, this widget becomes a child window
+ inside \a tqparent. The new widget is deleted when its \a tqparent is
+ deleted.
+
+ The \a name is sent to the TQObject constructor.
+
+ The widget flags argument, \a f, is normally 0, but it can be set
+ to customize the window frame of a top-level widget (i.e. \a
+ tqparent must be 0). To customize the frame, set the \c
+ WStyle_Customize flag OR'ed with any of the \l TQt::WidgetFlags.
+
+ If you add a child widget to an already visible widget you must
+ explicitly show the child to make it visible.
+
+ Note that the X11 version of TQt may not be able to deliver all
+ combinations of style flags on all systems. This is because on
+ X11, TQt can only ask the window manager, and the window manager
+ can override the application's settings. On Windows, TQt can set
+ whatever flags you want.
+
+ Example:
+ \code
+ TQLabel *splashScreen = new TQLabel( 0, "mySplashScreen",
+ WStyle_Customize | WStyle_Splash );
+ \endcode
+*/
+
+TQWidget::TQWidget( TQWidget *tqparent, const char *name, WFlags f )
+ : TQObject( tqparent, name ), TQPaintDevice( TQInternal::Widget )
+{
+#if defined(TQT_CHECK_STATE) && !defined(TQ_WS_WIN)
+ if ( tqApp->type() == TQApplication::Tty ) {
+ qWarning( "TQWidget: Cannot create a TQWidget when no GUI "
+ "is being used" );
+ }
+#endif
+
+ fstrut_dirty = 1;
+
+ isWidget = TRUE; // is a widget
+ winid = 0; // default attributes
+ widget_state = 0;
+ widget_flags = f;
+ focus_policy = 0;
+ own_font = 0;
+ own_palette = 0;
+ sizehint_forced = 0;
+ is_closing = 0;
+ in_show = 0;
+ in_show_maximized = 0;
+ im_enabled = FALSE;
+#ifndef TQT_NO_LAYOUT
+ lay_out = 0;
+#endif
+ extra = 0; // no extra widget info
+#ifndef TQT_NO_PALETTE
+ bg_col = pal.active().background(); // default background color
+#endif
+ create(); // platform-dependent init
+#ifndef TQT_NO_PALETTE
+ pal = isTopLevel() ? TQApplication::palette() : parentWidget()->palette();
+#endif
+ if ( ! isTopLevel() )
+ fnt = parentWidget()->font();
+#if defined(TQ_WS_X11)
+ fnt.x11SetScreen( x11Screen() );
+#endif // TQ_WS_X11
+
+ if ( !isDesktop() )
+ setBackgroundFromMode(); //### parts of this are done in create but not all (see reparent(...) )
+ // make sure move/resize events are sent to all widgets
+ TQApplication::postEvent( this, new TQMoveEvent( crect.topLeft(),
+ crect.topLeft() ) );
+ TQApplication::postEvent( this, new TQResizeEvent(crect.size(),
+ crect.size()) );
+ if ( isTopLevel() ) {
+ setWState( WState_ForceHide | WState_CreatedHidden );
+ TQFocusData *fd = focusData( TRUE );
+ if ( fd->tqfocusWidgets.tqfindRef(this) < 0 )
+ fd->tqfocusWidgets.append( this );
+ } else {
+ // propagate enabled state
+ if ( !parentWidget()->isEnabled() )
+ setWState( WState_Disabled );
+ // new widgets do not show up in already visible parents
+ if ( parentWidget()->isVisible() )
+ setWState( WState_ForceHide | WState_CreatedHidden );
+ }
+ if ( ++instanceCounter > maxInstances )
+ maxInstances = instanceCounter;
+}
+
+/*!
+ Destroys the widget.
+
+ All this widget's tqchildren are deleted first. The application
+ exits if this widget is the main widget.
+*/
+
+TQWidget::~TQWidget()
+{
+#if defined (TQT_CHECK_STATE)
+ if ( paintingActive() )
+ qWarning( "%s (%s): deleted while being painted", className(), name() );
+#endif
+
+ // Remove myself and all tqchildren from the can-take-focus list
+ TQFocusData *f = focusData( FALSE );
+ if ( f ) {
+ TQPtrListIterator<TQWidget> it(f->tqfocusWidgets);
+ TQWidget *w;
+ while ( (w = it.current()) ) {
+ ++it;
+ TQWidget * p = w;
+ while( p && p != this )
+ p = p->parentWidget();
+ if ( p ) // my descendant
+ f->tqfocusWidgets.removeRef( w );
+ }
+ }
+ --instanceCounter;
+
+ if ( TQApplication::main_widget == this ) { // reset main widget
+ TQApplication::main_widget = 0;
+ if (tqApp)
+ tqApp->quit();
+ }
+
+ if ( hasFocus() )
+ clearFocus();
+
+ if ( isTopLevel() && isShown() && winId() )
+ hide();
+
+ // A tqparent widget must destroy all its tqchildren before destroying itself
+ if ( childObjects ) { // delete tqchildren objects
+ TQObjectListIt it(*childObjects);
+ TQObject *obj;
+ while ( (obj=it.current()) ) {
+ ++it;
+ obj->parentObj = 0;
+ childObjects->removeRef( obj );
+ delete obj;
+ }
+ delete childObjects;
+ childObjects = 0;
+ }
+
+ TQApplication::removePostedEvents( this );
+
+ destroy(); // platform-dependent cleanup
+ if ( extra )
+ deleteExtra();
+}
+
+int TQWidget::instanceCounter = 0; // Current number of widget instances
+int TQWidget::maxInstances = 0; // Maximum number of widget instances
+
+/*!
+ \internal
+ Creates the global widget mapper.
+ The widget mapper converts window handles to widget pointers.
+ \sa destroyMapper()
+*/
+
+void TQWidget::createMapper()
+{
+ mapper = new TQWidgetMapper;
+ TQ_CHECK_PTR( mapper );
+}
+
+/*!
+ \internal
+ Destroys the global widget mapper.
+ \sa createMapper()
+*/
+
+void TQWidget::destroyMapper()
+{
+ if ( !mapper ) // already gone
+ return;
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)mapper) );
+ TQWidgetMapper * myMapper = mapper;
+ mapper = 0;
+ register TQWidget *w;
+ while ( (w=it.current()) ) { // remove parents widgets
+ ++it;
+ if ( !w->parentObj ) // widget is a tqparent
+ w->destroy( TRUE, TRUE );
+ }
+ delete myMapper;
+}
+
+
+static TQWidgetList *wListInternal( TQWidgetMapper *mapper, bool onlyTopLevel )
+{
+ TQWidgetList *list = new TQWidgetList;
+ TQ_CHECK_PTR( list );
+ if ( mapper ) {
+ TQWidget *w;
+ TQWidgetIntDictIt it( *((TQWidgetIntDict*)mapper) );
+ while ( (w=it.current()) ) {
+ ++it;
+ if ( !onlyTopLevel || w->isTopLevel() )
+ list->append( w );
+ }
+ }
+ return list;
+}
+
+/*!
+ \internal
+ Returns a list of all widgets.
+ \sa tlwList(), TQApplication::allWidgets()
+*/
+
+TQWidgetList *TQWidget::wList()
+{
+ return wListInternal( mapper, FALSE );
+}
+
+/*!
+ \internal
+ Returns a list of all top level widgets.
+ \sa wList(), TQApplication::tqtopLevelWidgets()
+*/
+
+TQWidgetList *TQWidget::tlwList()
+{
+ return wListInternal( mapper, TRUE );
+}
+
+
+void TQWidget::setWinId( WId id ) // set widget identifier
+{
+ if ( !mapper ) // mapper destroyed
+ return;
+ if ( winid )
+ mapper->remove( winid );
+ winid = id;
+#if defined(TQ_WS_X11)
+ hd = id; // X11: hd == ident
+#endif
+ if ( id )
+ mapper->insert( this );
+}
+
+
+/*!
+ \internal
+ Returns a pointer to the block of extra widget data.
+*/
+
+TQWExtra *TQWidget::extraData()
+{
+ return extra;
+}
+
+
+/*!
+ \internal
+ Returns a pointer to the block of extra top level widget data.
+
+ This data is guaranteed to exist for top level widgets.
+*/
+
+TQTLWExtra *TQWidget::topData()
+{
+ createTLExtra();
+ return extra->topextra;
+}
+
+
+void TQWidget::createTLExtra()
+{
+ if ( !extra )
+ createExtra();
+ if ( !extra->topextra ) {
+ TQTLWExtra* x = extra->topextra = new TQTLWExtra;
+#if defined( TQ_WS_WIN ) || defined( TQ_WS_MAC )
+ x->opacity = 255;
+#endif
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ x->icon = 0;
+#endif
+ x->focusData = 0;
+ x->fleft = x->fright = x->ftop = x->fbottom = 0;
+ x->incw = x->inch = 0;
+ x->basew = x->baseh = 0;
+ x->normalGeometry = TQRect(0,0,-1,-1);
+#if defined(TQ_WS_X11)
+ x->embedded = 0;
+ x->parentWinId = 0;
+ x->spont_unmapped = 0;
+ x->dnd = 0;
+ x->uspos = 0;
+ x->ussize = 0;
+#endif
+ x->savedFlags = 0;
+#if defined(TQ_WS_TQWS) && !defined(TQT_NO_TQWS_MANAGER)
+ x->decor_allocated_region = TQRegion();
+ x->qwsManager = 0;
+#endif
+ createTLSysExtra();
+ }
+}
+
+/*!
+ \internal
+ Creates the widget extra data.
+*/
+
+void TQWidget::createExtra()
+{
+ if ( !extra ) { // if not exists
+ extra = new TQWExtra;
+ TQ_CHECK_PTR( extra );
+ extra->minw = extra->minh = 0;
+ extra->maxw = extra->maxh = TQWIDGETSIZE_MAX;
+ extra->bg_pix = 0;
+ extra->focus_proxy = 0;
+#ifndef TQT_NO_CURSOR
+ extra->curs = 0;
+#endif
+ extra->topextra = 0;
+ extra->bg_mode = PaletteBackground;
+ extra->bg_mode_visual = PaletteBackground;
+ extra->bg_origin = WidgetOrigin;
+#ifndef TQT_NO_STYLE
+ extra->style = 0;
+#endif
+ extra->size_policy = TQSizePolicy( TQSizePolicy::Preferred,
+ TQSizePolicy::Preferred );
+ createSysExtra();
+ }
+}
+
+
+/*!
+ \internal
+ Deletes the widget extra data.
+*/
+
+void TQWidget::deleteExtra()
+{
+ if ( extra ) { // if exists
+ delete extra->bg_pix;
+#ifndef TQT_NO_CURSOR
+ delete extra->curs;
+#endif
+ deleteSysExtra();
+ if ( extra->topextra ) {
+ deleteTLSysExtra();
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ delete extra->topextra->icon;
+#endif
+ delete extra->topextra->focusData;
+#if defined(TQ_WS_TQWS) && !defined(TQT_NO_TQWS_MANAGER)
+ delete extra->topextra->qwsManager;
+#endif
+ delete extra->topextra;
+ }
+ delete extra;
+ // extra->xic destroyed in TQWidget::destroy()
+ extra = 0;
+ }
+}
+
+
+/*!
+ \internal
+ This function is called when a widget is hidden or destroyed.
+ It resets some application global pointers that should only refer active,
+ visible widgets.
+*/
+
+void TQWidget::deactivateWidgetCleanup()
+{
+ // If this was the active application window, reset it
+ if ( this == TQApplication::active_window )
+ tqApp->setActiveWindow( 0 );
+ // If the is the active mouse press widget, reset it
+#ifdef TQ_WS_MAC
+ extern TQGuardedPtr<TQWidget> qt_button_down;
+#else
+ extern TQWidget *qt_button_down;
+#endif
+ if ( this == (TQWidget *)qt_button_down )
+ qt_button_down = 0;
+}
+
+
+/*!
+ Returns a pointer to the widget with window identifer/handle \a
+ id.
+
+ The window identifier type depends on the underlying window
+ system, see \c tqwindowdefs.h for the actual definition. If there
+ is no widget with this identifier, 0 is returned.
+*/
+
+TQWidget *TQWidget::tqfind( WId id )
+{
+ return mapper ? mapper->tqfind( id ) : 0;
+}
+
+/*!
+ \fn TQWidgetMapper *TQWidget::wmapper()
+ \internal
+ Returns a pointer to the widget mapper.
+
+ The widget mapper is an internal dictionary that is used to map from
+ window identifiers/handles to widget pointers.
+ \sa tqfind(), id()
+*/
+
+/*!
+ \fn WFlags TQWidget::getWFlags() const
+
+ Returns the widget flags for this this widget.
+
+ Widget flags are a combination of \l{TQt::WidgetFlags}.
+
+ \sa testWFlags(), setWFlags(), clearWFlags()
+*/
+
+/*!
+ \fn void TQWidget::setWFlags( WFlags f )
+
+ Sets the widget flags \a f.
+
+ Widget flags are a combination of \l{TQt::WidgetFlags}.
+
+ \sa testWFlags(), getWFlags(), clearWFlags()
+*/
+
+/*!
+ \fn void TQWidget::clearWFlags( WFlags f )
+
+ Clears the widget flags \a f.
+
+ Widget flags are a combination of \l{TQt::WidgetFlags}.
+
+ \sa testWFlags(), getWFlags(), setWFlags()
+*/
+
+
+
+/*!
+ \fn WId TQWidget::winId() const
+
+ Returns the window system identifier of the widget.
+
+ Portable in principle, but if you use it you are probably about to
+ do something non-portable. Be careful.
+
+ \sa tqfind()
+*/
+
+#ifndef TQT_NO_STYLE
+/*!
+ Returns the GUI style for this widget
+
+ \sa TQWidget::setStyle(), TQApplication::setStyle(), TQApplication::style()
+*/
+
+TQStyle& TQWidget::style() const
+{
+ if ( extra && extra->style )
+ return *extra->style;
+ TQStyle &ret = tqApp->style();
+ return ret;
+}
+
+/*!
+ Sets the widget's GUI style to \a style. Ownership of the style
+ object is not transferred.
+
+ If no style is set, the widget uses the application's style,
+ TQApplication::style() instead.
+
+ Setting a widget's style has no effect on existing or future child
+ widgets.
+
+ \warning This function is particularly useful for demonstration
+ purposes, where you want to show TQt's styling capabilities. Real
+ applications should avoid it and use one consistent GUI style
+ instead.
+
+ \sa style(), TQStyle, TQApplication::style(), TQApplication::setStyle()
+*/
+
+void TQWidget::setStyle( TQStyle *style )
+{
+ TQStyle& old = TQWidget::style();
+ createExtra();
+ extra->style = style;
+ if ( !testWFlags(WType_Desktop) // (except desktop)
+ && testWState(WState_Polished)) { // (and have been polished)
+ old.unPolish( this );
+ TQWidget::style().polish( this );
+ }
+ styleChange( old );
+}
+
+/*!
+ \overload
+
+ Sets the widget's GUI style to \a style using the TQStyleFactory.
+*/
+TQStyle* TQWidget::setStyle( const TQString &style )
+{
+ TQStyle *s = TQStyleFactory::create( style );
+ setStyle( s );
+ return s;
+}
+
+/*!
+ This virtual function is called when the style of the widgets
+ changes. \a oldStyle is the previous GUI style; you can get the
+ new style from style().
+
+ Reimplement this function if your widget needs to know when its
+ GUI style changes. You will almost certainly need to update the
+ widget using update().
+
+ The default implementation updates the widget including its
+ tqgeometry.
+
+ \sa TQApplication::setStyle(), style(), update(), updateGeometry()
+*/
+
+void TQWidget::styleChange( TQStyle& /* oldStyle */ )
+{
+ update();
+ updateGeometry();
+}
+
+#endif
+
+/*!
+ \property TQWidget::isTopLevel
+ \brief whether the widget is a top-level widget
+
+ A top-level widget is a widget which usually has a frame and a
+ \link TQWidget::caption caption (title)\endlink. \link
+ TQWidget::isPopup() Popup\endlink and \link TQWidget::isDesktop()
+ desktop\endlink widgets are also top-level widgets.
+
+ A top-level widget can have a \link TQWidget::parentWidget() tqparent
+ widget\endlink. It will then be grouped with its tqparent and deleted
+ when the tqparent is deleted, minimized when the tqparent is minimized
+ etc. If supported by the window manager, it will also have a
+ common taskbar entry with its tqparent.
+
+ TQDialog and TQMainWindow widgets are by default top-level, even if
+ a tqparent widget is specified in the constructor. This behavior is
+ specified by the \c WType_TopLevel widget flag.
+
+ \sa tqtopLevelWidget(), isDialog(), isModal(), isPopup(), isDesktop(), parentWidget()
+*/
+
+/*!
+ \property TQWidget::isDialog
+ \brief whether the widget is a dialog widget
+
+ A dialog widget is a secondary top-level widget, i.e. a top-level
+ widget with a tqparent.
+
+ \sa isTopLevel(), TQDialog
+*/
+
+/*!
+ \property TQWidget::isPopup
+ \brief whether the widget is a popup widget
+
+ A popup widget is created by specifying the widget flag \c
+ WType_Popup to the widget constructor. A popup widget is also a
+ top-level widget.
+
+ \sa isTopLevel()
+*/
+
+/*!
+ \property TQWidget::isDesktop
+ \brief whether the widget is a desktop widget, i.e. represents the desktop
+
+ A desktop widget is also a top-level widget.
+
+ \sa isTopLevel(), TQApplication::desktop()
+*/
+
+/*!
+ \property TQWidget::isModal
+ \brief whether the widget is a modal widget
+
+ This property only makes sense for top-level widgets. A modal
+ widget prevents widgets in all other top-level widgets from
+ getting any input.
+
+ \sa isTopLevel(), isDialog(), TQDialog
+*/
+
+/*!
+ \property TQWidget::underMouse
+ \brief whether the widget is under the mouse cursor
+
+ This value is not updated properly during drag and drop
+ operations.
+
+ \sa TQEvent::Enter, TQEvent::Leave
+*/
+
+/*!
+ \property TQWidget::minimized
+ \brief whether this widget is minimized (iconified)
+
+ This property is only relevant for top-level widgets.
+
+ \sa showMinimized(), visible, show(), hide(), showNormal(), maximized
+*/
+bool TQWidget::isMinimized() const
+{ return testWState(WState_Minimized); }
+
+/*!
+ Shows the widget minimized, as an icon.
+
+ Calling this function only affects \link isTopLevel() top-level
+ widgets\endlink.
+
+ \sa showNormal(), showMaximized(), show(), hide(), isVisible(),
+ isMinimized()
+*/
+void TQWidget::showMinimized()
+{
+ bool isMin = isMinimized();
+ if (isMin && isVisible()) return;
+
+ if (!isMin)
+ setWindowState((windowState() & ~WindowActive) | WindowMinimized);
+ show();
+ if (!isTopLevel())
+ TQApplication::sendPostedEvents(this, TQEvent::ShowMinimized);
+}
+
+/*!
+ \property TQWidget::maximized
+ \brief whether this widget is maximized
+
+ This property is only relevant for top-level widgets.
+
+ Note that due to limitations in some window-systems, this does not
+ always report the expected results (e.g. if the user on X11
+ maximizes the window via the window manager, TQt has no way of
+ distinguishing this from any other resize). This is expected to
+ improve as window manager protocols evolve.
+
+ \sa windowState(), showMaximized(), visible, show(), hide(), showNormal(), minimized
+*/
+bool TQWidget::isMaximized() const
+{ return testWState(WState_Maximized); }
+
+
+
+/*! Returns the current window state. The window state is a OR'ed
+ combination of TQt::WindowState: \c WindowMinimized, \c
+ WindowMaximized, \c WindowFullScreen and \c WindowActive.
+
+ \sa TQt::WindowState setWindowState()
+ */
+uint TQWidget::windowState() const
+{
+ uint state = 0;
+ if (testWState(WState_Minimized))
+ state |= WindowMinimized;
+ if (testWState(WState_Maximized))
+ state |= WindowMaximized;
+ if (testWState(WState_FullScreen))
+ state |= WindowFullScreen;
+ if (isActiveWindow())
+ state |= WindowActive;
+ return state;
+}
+
+/*!
+ \fn void TQWidget::setWindowState(uint windowState)
+
+ Sets the window state to \a windowState. The window state is a OR'ed
+ combination of TQt::WindowState: \c WindowMinimized, \c
+ WindowMaximized, \c WindowFullScreen and \c WindowActive.
+
+ If the window is not visible (i.e. isVisible() returns FALSE), the
+ window state will take effect when show() is called. For visible
+ windows, the change is immediate. For example, to toggle between
+ full-screen and mormal mode, use the following code:
+
+ \code
+ w->setWindowState(w->windowState() ^ WindowFullScreen);
+ \endcode
+
+ In order to restore and activate a minimized window (while
+ preserving its maximized and/or full-screen state), use the following:
+
+ \code
+ w->setWindowState(w->windowState() & ~WindowMinimized | WindowActive);
+ \endcode
+
+ Note: On some window systems \c WindowActive is not immediate, and may be
+ ignored in certain cases.
+
+ \sa TQt::WindowState windowState()
+*/
+
+/*!
+ \property TQWidget::fullScreen
+ \brief whether the widget is full screen
+
+ \sa windowState(), minimized, maximized
+*/
+bool TQWidget::isFullScreen() const
+{ return testWState(WState_FullScreen); }
+
+/*!
+ Shows the widget in full-screen mode.
+
+ Calling this function only affects top-level widgets.
+
+ To return from full-screen mode, call showNormal().
+
+ Full-screen mode works fine under Windows, but has certain
+ problems under X. These problems are due to limitations of the
+ ICCCM protocol that specifies the communication between X11
+ clients and the window manager. ICCCM simply does not understand
+ the concept of non-decorated full-screen windows. Therefore, the
+ best we can do is to request a borderless window and place and
+ resize it to fill the entire screen. Depending on the window
+ manager, this may or may not work. The borderless window is
+ requested using MOTIF hints, which are at least partially
+ supported by virtually all modern window managers.
+
+ An alternative would be to bypass the window manager entirely and
+ create a window with the WX11BypassWM flag. This has other severe
+ problems though, like totally broken keyboard focus and very
+ strange effects on desktop changes or when the user raises other
+ windows.
+
+ X11 window managers that follow modern post-ICCCM specifications
+ support full-screen mode properly.
+
+ \sa showNormal(), showMaximized(), show(), hide(), isVisible()
+*/
+void TQWidget::showFullScreen()
+{
+ bool isFull = isFullScreen();
+ if (isFull && isVisible())
+ return;
+
+ if (!isFull)
+ setWindowState(windowState() | WindowFullScreen);
+ show();
+ if (!isTopLevel())
+ TQApplication::sendPostedEvents(this, TQEvent::ShowFullScreen);
+ setActiveWindow();
+}
+
+/*!
+ Shows the widget maximized.
+
+ Calling this function only affects \link isTopLevel() top-level
+ widgets\endlink.
+
+ On X11, this function may not work properly with certain window
+ managers. See the \link tqgeometry.html Window Geometry
+ documentation\endlink for an explanation.
+
+ \sa setWindowState(), showNormal(), showMinimized(), show(), hide(), isVisible()
+*/
+void TQWidget::showMaximized()
+{
+ if (isMaximized() && isVisible() && !isMinimized())
+ return;
+
+ setWindowState((windowState() & ~WindowMinimized) | WindowMaximized);
+ show();
+ if (!isTopLevel())
+ TQApplication::sendPostedEvents(this, TQEvent::ShowMaximized);
+}
+
+/*!
+ Restores the widget after it has been maximized or minimized.
+
+ Calling this function only affects \link isTopLevel() top-level
+ widgets\endlink.
+
+ \sa setWindowState(), showMinimized(), showMaximized(), show(), hide(), isVisible()
+*/
+void TQWidget::showNormal()
+{
+ setWindowState(WindowNoState);
+ show();
+ if (!isTopLevel())
+ TQApplication::sendPostedEvents(this, TQEvent::ShowNormal);
+}
+
+/*!
+ Returns TRUE if this widget would become enabled if \a ancestor is
+ enabled; otherwise returns FALSE.
+
+ This is the case if neither the widget itself nor every tqparent up
+ to but excluding \a ancestor has been explicitly disabled.
+
+ isEnabledTo(0) is equivalent to isEnabled().
+
+ \sa setEnabled() enabled
+*/
+
+bool TQWidget::isEnabledTo( TQWidget* ancestor ) const
+{
+ const TQWidget * w = this;
+ while ( w && !w->testWState(WState_ForceDisabled)
+ && !w->isTopLevel()
+ && w->parentWidget()
+ && w->parentWidget() != ancestor )
+ w = w->parentWidget();
+ return !w->testWState( WState_ForceDisabled );
+}
+
+
+/*!
+ \fn bool TQWidget::isEnabledToTLW() const
+ \obsolete
+
+ This function is deprecated. It is equivalent to isEnabled()
+*/
+
+/*!
+ \property TQWidget::enabled
+ \brief whether the widget is enabled
+
+ An enabled widget receives keyboard and mouse events; a disabled
+ widget does not. In fact, an enabled widget only receives keyboard
+ events when it is in focus.
+
+ Some widgets display themselves differently when they are
+ disabled. For example a button might draw its label grayed out. If
+ your widget needs to know when it becomes enabled or disabled, you
+ can reimplement the enabledChange() function.
+
+ Disabling a widget implicitly disables all its tqchildren. Enabling
+ respectively enables all child widgets unless they have been
+ explicitly disabled.
+
+ \sa isEnabled(), isEnabledTo(), TQKeyEvent, TQMouseEvent, enabledChange()
+*/
+void TQWidget::setEnabled( bool enable )
+{
+ if ( enable )
+ clearWState( WState_ForceDisabled );
+ else
+ setWState( WState_ForceDisabled );
+
+ if ( !isTopLevel() && parentWidget() &&
+ !parentWidget()->isEnabled() && enable )
+ return; // nothing we can do
+
+ if ( enable ) {
+ if ( testWState(WState_Disabled) ) {
+ clearWState( WState_Disabled );
+ setBackgroundFromMode();
+ enabledChange( !enable );
+ if ( childrenListObject() ) {
+ TQObjectListIt it( *childrenListObject() );
+ TQWidget *w;
+ while( (w = (TQWidget *)it.current()) != 0 ) {
+ ++it;
+ if ( w->isWidgetType() &&
+ !w->testWState( WState_ForceDisabled ) )
+ w->setEnabled( TRUE );
+ }
+ }
+ }
+ } else {
+ if ( !testWState(WState_Disabled) ) {
+ if (tqfocusWidget() == this) {
+ bool parentIsEnabled = (!parentWidget() || parentWidget()->isEnabled());
+ if (!parentIsEnabled || !focusNextPrevChild(TRUE))
+ clearFocus();
+ }
+ setWState( WState_Disabled );
+ setBackgroundFromMode();
+ enabledChange( !enable );
+ if ( childrenListObject() ) {
+ TQObjectListIt it( *childrenListObject() );
+ TQWidget *w;
+ while( (w = (TQWidget *)it.current()) != 0 ) {
+ ++it;
+ if ( w->isWidgetType() && w->isEnabled() ) {
+ w->setEnabled( FALSE );
+ w->clearWState( WState_ForceDisabled );
+ }
+ }
+ }
+ }
+ }
+#if defined(TQ_WS_X11)
+ if ( testWState( WState_OwnCursor ) ) {
+ // enforce the windows behavior of clearing the cursor on
+ // disabled widgets
+
+ extern void qt_x11_enforce_cursor( TQWidget * w ); // defined in qwidget_x11.cpp
+ qt_x11_enforce_cursor( this );
+ }
+#endif
+#ifdef TQ_WS_WIN
+ TQInputContext::enable( this, im_enabled & !((bool)testWState(WState_Disabled)) );
+#endif
+}
+
+/*!
+ Disables widget input events if \a disable is TRUE; otherwise
+ enables input events.
+
+ See the \l enabled documentation for more information.
+
+ \sa isEnabledTo(), TQKeyEvent, TQMouseEvent, enabledChange()
+*/
+void TQWidget::setDisabled( bool disable )
+{
+ setEnabled( !disable );
+}
+
+/*!
+ \fn void TQWidget::enabledChange( bool oldEnabled )
+
+ This virtual function is called from setEnabled(). \a oldEnabled
+ is the previous setting; you can get the new setting from
+ isEnabled().
+
+ Reimplement this function if your widget needs to know when it
+ becomes enabled or disabled. You will almost certainly need to
+ update the widget using update().
+
+ The default implementation repaints the visible part of the
+ widget.
+
+ \sa setEnabled(), isEnabled(), tqrepaint(), update(), clipRegion()
+*/
+
+void TQWidget::enabledChange( bool )
+{
+ update();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+}
+
+/*!
+ \fn void TQWidget::windowActivationChange( bool oldActive )
+
+ This virtual function is called for a widget when its window is
+ activated or deactivated by the window system. \a oldActive is the
+ previous state; you can get the new setting from isActiveWindow().
+
+ Reimplement this function if your widget needs to know when its
+ window becomes activated or deactivated.
+
+ The default implementation updates the visible part of the widget
+ if the inactive and the active colorgroup are different for colors
+ other than the highlight and link colors.
+
+ \sa setActiveWindow(), isActiveWindow(), update(), palette()
+*/
+
+void TQWidget::windowActivationChange( bool )
+{
+#ifndef TQT_NO_PALETTE
+ if ( !isVisible() )
+ return;
+
+ const TQColorGroup &acg = palette().active();
+ const TQColorGroup &icg = palette().inactive();
+
+ if ( acg != icg ) {
+ BackgroundMode bm = backgroundMode();
+ TQColorGroup::ColorRole role = TQPalette::backgroundRoleFromMode(bm);
+ if ( bm > NoBackground && acg.brush(role) != icg.brush(role) )
+ setBackgroundFromMode();
+ else if ( acg.background() == icg.background() &&
+ acg.base() == icg.base() &&
+ acg.text() == icg.text() &&
+ acg.foreground() == icg.foreground() &&
+ acg.button() == icg.button() &&
+ acg.buttonText() == icg.buttonText() &&
+ acg.brightText() == icg.brightText() &&
+ acg.dark() == icg.dark() &&
+ acg.light() == icg.light() &&
+ acg.mid() == icg.mid() &&
+ acg.midlight() == icg.midlight() &&
+ acg.shadow() == icg.shadow() )
+ return;
+ update();
+ }
+#endif
+}
+
+/*!
+ \property TQWidget::frameGeometry
+ \brief tqgeometry of the widget relative to its tqparent including any
+ window frame
+
+ See the \link tqgeometry.html Window Geometry documentation\endlink
+ for an overview of tqgeometry issues with top-level widgets.
+
+ \sa tqgeometry() x() y() pos()
+*/
+TQRect TQWidget::frameGeometry() const
+{
+ if (isTopLevel() && ! isPopup()) {
+ if (fstrut_dirty)
+ updateFrameStrut();
+ TQWidget *that = (TQWidget *) this;
+ TQTLWExtra *top = that->topData();
+ return TQRect(crect.x() - top->fleft,
+ crect.y() - top->ftop,
+ crect.width() + top->fleft + top->fright,
+ crect.height() + top->ftop + top->fbottom);
+ }
+ return crect;
+}
+
+/*! \property TQWidget::x
+ \brief the x coordinate of the widget relative to its tqparent including
+ any window frame
+
+ See the \link tqgeometry.html Window Geometry documentation\endlink
+ for an overview of top-level widget tqgeometry.
+
+ \sa frameGeometry, y, pos
+*/
+int TQWidget::x() const
+{
+ if (isTopLevel() && ! isPopup()) {
+ if (fstrut_dirty)
+ updateFrameStrut();
+ TQWidget *that = (TQWidget *) this;
+ return crect.x() - that->topData()->fleft;
+ }
+ return crect.x();
+}
+
+/*!
+ \property TQWidget::y
+ \brief the y coordinate of the widget relative to its tqparent and
+ including any window frame
+
+ See the \link tqgeometry.html Window Geometry documentation\endlink
+ for an overview of top-level widget tqgeometry.
+
+ \sa frameGeometry, x, pos
+*/
+int TQWidget::y() const
+{
+ if (isTopLevel() && ! isPopup()) {
+ if (fstrut_dirty)
+ updateFrameStrut();
+ TQWidget *that = (TQWidget *) this;
+ return crect.y() - that->topData()->ftop;
+ }
+ return crect.y();
+}
+
+/*!
+ \property TQWidget::pos
+ \brief the position of the widget within its tqparent widget
+
+ If the widget is a top-level widget, the position is that of the
+ widget on the desktop, including its frame.
+
+ When changing the position, the widget, if visible, receives a
+ move event (moveEvent()) immediately. If the widget is not
+ currently visible, it is guaranteed to receive an event before it
+ is shown.
+
+ move() is virtual, and all other overloaded move() implementations
+ in TQt call it.
+
+ \warning Calling move() or setGeometry() inside moveEvent() can
+ lead to infinite recursion.
+
+ See the \link tqgeometry.html Window Geometry documentation\endlink
+ for an overview of top-level widget tqgeometry.
+
+ \sa frameGeometry, size x(), y()
+*/
+TQPoint TQWidget::pos() const
+{
+ if (isTopLevel() && ! isPopup()) {
+ if (fstrut_dirty)
+ updateFrameStrut();
+ TQWidget *that = (TQWidget *) this;
+ TQTLWExtra *top = that->topData();
+ return TQPoint(crect.x() - top->fleft, crect.y() - top->ftop);
+ }
+ return crect.topLeft();
+}
+
+/*!
+ \property TQWidget::tqgeometry
+ \brief the tqgeometry of the widget relative to its tqparent and
+ excluding the window frame
+
+ When changing the tqgeometry, the widget, if visible, receives a
+ move event (moveEvent()) and/or a resize event (resizeEvent())
+ immediately. If the widget is not currently visible, it is
+ guaranteed to receive appropriate events before it is shown.
+
+ The size component is adjusted if it lies outside the range
+ defined by tqminimumSize() and tqmaximumSize().
+
+ setGeometry() is virtual, and all other overloaded setGeometry()
+ implementations in TQt call it.
+
+ \warning Calling setGeometry() inside resizeEvent() or moveEvent()
+ can lead to infinite recursion.
+
+ See the \link tqgeometry.html Window Geometry documentation\endlink
+ for an overview of top-level widget tqgeometry.
+
+ \sa frameGeometry(), rect(), move(), resize(), moveEvent(),
+ resizeEvent(), tqminimumSize(), tqmaximumSize()
+*/
+
+/*!
+ \property TQWidget::size
+ \brief the size of the widget excluding any window frame
+
+ When resizing, the widget, if visible, receives a resize event
+ (resizeEvent()) immediately. If the widget is not currently
+ visible, it is guaranteed to receive an event before it is shown.
+
+ The size is adjusted if it lies outside the range defined by
+ tqminimumSize() and tqmaximumSize(). Furthermore, the size is always
+ at least TQSize(1, 1). For toplevel widgets, the minimum size
+ might be larger, depending on the window manager.
+
+ If you want a top-level window to have a fixed size, call
+ setResizeMode( TQLayout::FreeResize ) on its tqlayout.
+
+ resize() is virtual, and all other overloaded resize()
+ implementations in TQt call it.
+
+ \warning Calling resize() or setGeometry() inside resizeEvent() can
+ lead to infinite recursion.
+
+ \sa pos, tqgeometry, tqminimumSize, tqmaximumSize, resizeEvent()
+*/
+
+/*!
+ \property TQWidget::width
+ \brief the width of the widget excluding any window frame
+
+ See the \link tqgeometry.html Window Geometry documentation\endlink
+ for an overview of top-level widget tqgeometry.
+
+ \sa tqgeometry, height, size
+*/
+
+/*!
+ \property TQWidget::height
+ \brief the height of the widget excluding any window frame
+
+ See the \link tqgeometry.html Window Geometry documentation\endlink
+ for an overview of top-level widget tqgeometry.
+
+ \sa tqgeometry, width, size
+*/
+
+/*!
+ \property TQWidget::rect
+ \brief the internal tqgeometry of the widget excluding any window
+ frame
+
+ The rect property equals TQRect(0, 0, width(), height()).
+
+ See the \link tqgeometry.html Window Geometry documentation\endlink
+ for an overview of top-level widget tqgeometry.
+
+ \sa size
+*/
+
+/*!
+ \property TQWidget::tqchildrenRect
+ \brief the bounding rectangle of the widget's tqchildren
+
+ Hidden tqchildren are excluded.
+
+ \sa tqchildrenRegion() tqgeometry()
+*/
+
+TQRect TQWidget::tqchildrenRect() const
+{
+ TQRect r( 0, 0, 0, 0 );
+ if ( !childrenListObject() )
+ return r;
+ TQObjectListIt it( *childrenListObject() );
+ TQObject *obj;
+ while ( (obj = it.current()) ) {
+ ++it;
+ if ( obj->isWidgetType() && !((TQWidget*)obj)->isHidden() && !((TQWidget*)obj)->isTopLevel())
+ r = r.unite( ((TQWidget*)obj)->tqgeometry() );
+ }
+ return r;
+}
+
+/*!
+ \property TQWidget::tqchildrenRegion
+ \brief the combined region occupied by the widget's tqchildren
+
+ Hidden tqchildren are excluded.
+
+ \sa tqchildrenRect() tqgeometry()
+*/
+
+TQRegion TQWidget::tqchildrenRegion() const
+{
+ TQRegion r;
+ if ( !childrenListObject() )
+ return r;
+ TQObjectListIt it( *childrenListObject() ); // iterate over all tqchildren
+ TQObject *obj;
+ while ( (obj=it.current()) ) {
+ ++it;
+ if ( obj->isWidgetType() && !((TQWidget*)obj)->isHidden() && !((TQWidget*)obj)->isTopLevel())
+ r = r.unite( ((TQWidget*)obj)->tqgeometry() );
+ }
+ return r;
+}
+
+
+/*!
+ \property TQWidget::tqminimumSize
+ \brief the widget's minimum size
+
+ The widget cannot be resized to a smaller size than the minimum
+ widget size. The widget's size is forced to the minimum size if
+ the current size is smaller.
+
+ If you use a tqlayout inside the widget, the minimum size will be
+ set by the tqlayout and not by setMinimumSize(), unless you set the
+ tqlayout's resize mode to TQLayout::FreeResize.
+
+ \sa minimumWidth, minimumHeight, tqmaximumSize, sizeIncrement
+ TQLayout::setResizeMode()
+*/
+
+TQSize TQWidget::tqminimumSize() const
+{
+ return extra ? TQSize( extra->minw, extra->minh ) : TQSize( 0, 0 );
+}
+
+/*!
+ \property TQWidget::tqmaximumSize
+ \brief the widget's maximum size
+
+ The widget cannot be resized to a larger size than the maximum
+ widget size.
+
+ \sa maximumWidth(), maximumHeight(), setMaximumSize(),
+ tqminimumSize(), sizeIncrement()
+*/
+
+TQSize TQWidget::tqmaximumSize() const
+{
+ return extra ? TQSize( extra->maxw, extra->maxh )
+ : TQSize( TQWIDGETSIZE_MAX, TQWIDGETSIZE_MAX );
+}
+
+
+/*!
+ \property TQWidget::minimumWidth
+ \brief the widget's minimum width
+
+ This property corresponds to tqminimumSize().width().
+
+ \sa tqminimumSize, minimumHeight
+*/
+
+/*!
+ \property TQWidget::minimumHeight
+ \brief the widget's minimum height
+
+ This property corresponds to tqminimumSize().height().
+
+ \sa tqminimumSize, minimumWidth
+*/
+
+/*!
+ \property TQWidget::maximumWidth
+ \brief the widget's maximum width
+
+ This property corresponds to tqmaximumSize().width().
+
+ \sa tqmaximumSize, maximumHeight
+*/
+
+/*!
+ \property TQWidget::maximumHeight
+ \brief the widget's maximum height
+
+ This property corresponds to tqmaximumSize().height().
+
+ \sa tqmaximumSize, maximumWidth
+*/
+
+/*!
+ \property TQWidget::sizeIncrement
+ \brief the size increment of the widget
+
+ When the user resizes the window, the size will move in steps of
+ sizeIncrement().width() pixels horizontally and
+ sizeIncrement.height() pixels vertically, with baseSize() as the
+ basis. Preferred widget sizes are for non-negative integers \e i
+ and \e j:
+ \code
+ width = baseSize().width() + i * sizeIncrement().width();
+ height = baseSize().height() + j * sizeIncrement().height();
+ \endcode
+
+ Note that while you can set the size increment for all widgets, it
+ only affects top-level widgets.
+
+ \warning The size increment has no effect under Windows, and may
+ be disregarded by the window manager on X.
+
+ \sa size, tqminimumSize, tqmaximumSize
+*/
+TQSize TQWidget::sizeIncrement() const
+{
+ return ( extra && extra->topextra )
+ ? TQSize( extra->topextra->incw, extra->topextra->inch )
+ : TQSize( 0, 0 );
+}
+
+/*!
+ \property TQWidget::baseSize
+ \brief the base size of the widget
+
+ The base size is used to calculate a proper widget size if the
+ widget defines sizeIncrement().
+
+ \sa setSizeIncrement()
+*/
+
+TQSize TQWidget::baseSize() const
+{
+ return ( extra != 0 && extra->topextra != 0 )
+ ? TQSize( extra->topextra->basew, extra->topextra->baseh )
+ : TQSize( 0, 0 );
+}
+
+/*!
+ Sets both the minimum and maximum sizes of the widget to \a s,
+ thereby preventing it from ever growing or shrinking.
+
+ \sa setMaximumSize() setMinimumSize()
+*/
+
+void TQWidget::setFixedSize( const TQSize & s)
+{
+ setMinimumSize( s );
+ setMaximumSize( s );
+ resize( s );
+}
+
+
+/*!
+ \overload void TQWidget::setFixedSize( int w, int h )
+
+ Sets the width of the widget to \a w and the height to \a h.
+*/
+
+void TQWidget::setFixedSize( int w, int h )
+{
+ setMinimumSize( w, h );
+ setMaximumSize( w, h );
+ resize( w, h );
+}
+
+void TQWidget::setMinimumWidth( int w )
+{
+ setMinimumSize( w, tqminimumSize().height() );
+}
+
+void TQWidget::setMinimumHeight( int h )
+{
+ setMinimumSize( tqminimumSize().width(), h );
+}
+
+void TQWidget::setMaximumWidth( int w )
+{
+ setMaximumSize( w, tqmaximumSize().height() );
+}
+
+void TQWidget::setMaximumHeight( int h )
+{
+ setMaximumSize( tqmaximumSize().width(), h );
+}
+
+/*!
+ Sets both the minimum and maximum width of the widget to \a w
+ without changing the heights. Provided for convenience.
+
+ \sa tqsizeHint() tqminimumSize() tqmaximumSize() setFixedSize()
+*/
+
+void TQWidget::setFixedWidth( int w )
+{
+ setMinimumSize( w, tqminimumSize().height() );
+ setMaximumSize( w, tqmaximumSize().height() );
+}
+
+
+/*!
+ Sets both the minimum and maximum heights of the widget to \a h
+ without changing the widths. Provided for convenience.
+
+ \sa tqsizeHint() tqminimumSize() tqmaximumSize() setFixedSize()
+*/
+
+void TQWidget::setFixedHeight( int h )
+{
+ setMinimumSize( tqminimumSize().width(), h );
+ setMaximumSize( tqmaximumSize().width(), h );
+}
+
+
+/*!
+ Translates the widget coordinate \a pos to the coordinate system
+ of \a tqparent. The \a tqparent must not be 0 and must be a tqparent
+ of the calling widget.
+
+ \sa mapFrom() mapToParent() mapToGlobal() hasMouse()
+*/
+
+TQPoint TQWidget::mapTo( TQWidget * tqparent, const TQPoint & pos ) const
+{
+ TQPoint p = pos;
+ if ( tqparent ) {
+ const TQWidget * w = this;
+ while ( w != tqparent ) {
+ p = w->mapToParent( p );
+ w = w->parentWidget();
+ }
+ }
+ return p;
+}
+
+
+/*!
+ Translates the widget coordinate \a pos from the coordinate system
+ of \a tqparent to this widget's coordinate system. The \a tqparent
+ must not be 0 and must be a tqparent of the calling widget.
+
+ \sa mapTo() mapFromParent() mapFromGlobal() hasMouse()
+*/
+
+TQPoint TQWidget::mapFrom( TQWidget * tqparent, const TQPoint & pos ) const
+{
+ TQPoint p( pos );
+ if ( tqparent ) {
+ const TQWidget * w = this;
+ while ( w != tqparent ) {
+ p = w->mapFromParent( p );
+ w = w->parentWidget();
+ }
+ }
+ return p;
+}
+
+
+/*!
+ Translates the widget coordinate \a pos to a coordinate in the
+ tqparent widget.
+
+ Same as mapToGlobal() if the widget has no tqparent.
+
+ \sa mapFromParent() mapTo() mapToGlobal() hasMouse()
+*/
+
+TQPoint TQWidget::mapToParent( const TQPoint &pos ) const
+{
+ return pos + crect.topLeft();
+}
+
+/*!
+ Translates the tqparent widget coordinate \a pos to widget
+ coordinates.
+
+ Same as mapFromGlobal() if the widget has no tqparent.
+
+ \sa mapToParent() mapFrom() mapFromGlobal() hasMouse()
+*/
+
+TQPoint TQWidget::mapFromParent( const TQPoint &pos ) const
+{
+ return pos - crect.topLeft();
+}
+
+
+/*!
+ Returns the top-level widget for this widget, i.e. the next
+ ancestor widget that has (or could have) a window-system frame.
+
+ If the widget is a top-level, the widget itself is returned.
+
+ Typical usage is changing the window caption:
+
+ \code
+ aWidget->tqtopLevelWidget()->setCaption( "New Caption" );
+ \endcode
+
+ \sa isTopLevel()
+*/
+
+TQWidget *TQWidget::tqtopLevelWidget() const
+{
+ TQWidget *w = (TQWidget *)this;
+ TQWidget *p = w->parentWidget();
+ while ( !w->testWFlags(WType_TopLevel) && p ) {
+ w = p;
+ p = p->parentWidget();
+ }
+ return w;
+}
+
+
+/*!
+ \property TQWidget::paletteForegroundColor
+ \brief the foreground color of the widget
+
+ setPaletteForegroundColor() is a convenience function that creates
+ and sets a modified TQPalette with setPalette(). The palette is
+ modified according to the widget's \e {background mode}. For
+ example, if the background mode is \c PaletteButton the palette entry
+ \c TQColorGroup::ButtonText is set to color.
+
+ \sa setPalette() TQApplication::setPalette() backgroundMode()
+ foregroundColor() setBackgroundMode() setEraseColor()
+*/
+const TQColor &TQWidget::paletteForegroundColor() const
+{
+#ifndef TQT_NO_PALETTE
+ BackgroundMode mode = extra ? (BackgroundMode) extra->bg_mode_visual : PaletteBackground;
+ return tqcolorGroup().color( TQPalette::foregroundRoleFromMode(mode) );
+#else
+ return TQt::black;
+#endif
+}
+
+void TQWidget::setPaletteForegroundColor( const TQColor & color )
+{
+#ifndef TQT_NO_PALETTE
+ BackgroundMode mode = extra ? (BackgroundMode) extra->bg_mode_visual : PaletteBackground;
+ TQPalette pal = palette();
+ TQColorGroup::ColorRole role = TQPalette::foregroundRoleFromMode( mode );
+ pal.setColor( TQPalette::Active, role, color );
+ pal.setColor( TQPalette::Inactive, role, color );
+ pal.setColor( TQPalette::Disabled, role, color );
+ setPalette( pal );
+#endif
+}
+
+
+/*!
+ Same as paletteForegroundColor()
+ */
+const TQColor &TQWidget::foregroundColor() const
+{
+ return paletteForegroundColor();
+}
+
+
+/*!
+ \fn const TQColor& TQWidget::eraseColor() const
+
+ Returns the erase color of the widget.
+
+ \sa setEraseColor() setErasePixmap() backgroundColor()
+*/
+
+/*!
+ Sets the erase color of the widget to \a color.
+
+ The erase color is the color the widget is to be cleared to before
+ paintEvent() is called. If there is an erase pixmap (set using
+ setErasePixmap()), then this property has an indeterminate value.
+
+ \sa erasePixmap(), backgroundColor(), backgroundMode(), palette()
+*/
+void TQWidget::setEraseColor( const TQColor & color )
+{
+ setBackgroundModeDirect( FixedColor );
+ setBackgroundColorDirect( color );
+ update();
+}
+
+/*!
+ Returns the widget's erase pixmap.
+
+ \sa setErasePixmap() eraseColor()
+*/
+const TQPixmap *TQWidget::erasePixmap() const
+{
+ return ( extra && extra->bg_pix ) ? extra->bg_pix : 0;
+}
+
+/*!
+ Sets the widget's erase pixmap to \a pixmap.
+
+ This pixmap is used to clear the widget before paintEvent() is
+ called.
+*/
+void TQWidget::setErasePixmap( const TQPixmap &pixmap )
+{
+ // This function is called with a null pixmap by setBackgroundEmpty().
+ setBackgroundPixmapDirect( pixmap );
+ setBackgroundModeDirect( FixedPixmap );
+ update();
+}
+
+void TQWidget::setBackgroundFromMode()
+{
+#ifndef TQT_NO_PALETTE
+ TQColorGroup::ColorRole r = TQColorGroup::Background;
+ if ( extra ) {
+ int i = (BackgroundMode)extra->bg_mode;
+ if ( i == FixedColor || i == FixedPixmap || i == NoBackground ) {
+ // Mode is for fixed color, not one based on palette,
+ // so nothing to do.
+ return;
+ }
+ switch( i ) {
+ case PaletteForeground:
+ r = TQColorGroup::Foreground;
+ break;
+ case PaletteButton:
+ r = TQColorGroup::Button;
+ break;
+ case PaletteLight:
+ r = TQColorGroup::Light;
+ break;
+ case PaletteMidlight:
+ r = TQColorGroup::Midlight;
+ break;
+ case PaletteDark:
+ r = TQColorGroup::Dark;
+ break;
+ case PaletteMid:
+ r = TQColorGroup::Mid;
+ break;
+ case PaletteText:
+ r = TQColorGroup::Text;
+ break;
+ case PaletteBrightText:
+ r = TQColorGroup::BrightText;
+ break;
+ case PaletteBase:
+ r = TQColorGroup::Base;
+ break;
+ case PaletteBackground:
+ r = TQColorGroup::Background;
+ break;
+ case PaletteShadow:
+ r = TQColorGroup::Shadow;
+ break;
+ case PaletteHighlight:
+ r = TQColorGroup::Highlight;
+ break;
+ case PaletteHighlightedText:
+ r = TQColorGroup::HighlightedText;
+ break;
+ case PaletteButtonText:
+ r = TQColorGroup::ButtonText;
+ break;
+ case X11ParentRelative:
+#if defined(TQ_WS_X11)
+ setBackgroundX11Relative();
+#endif
+ return;
+ }
+ }
+ const TQColorGroup &cg = tqcolorGroup();
+ TQPixmap * p = cg.brush( r ).pixmap();
+ if ( p )
+ setBackgroundPixmapDirect( *p );
+ else
+ setBackgroundColorDirect( cg.color( r ) );
+#endif
+}
+
+/*!
+ \enum TQt::BackgroundMode
+
+ This enum describes how the background of a widget changes, as the
+ widget's palette changes.
+
+ The background is what the widget tqcontains when \link
+ TQWidget::paintEvent() paintEvent()\endlink is called. To minimize
+ flicker, this should be the most common color or pixmap in the
+ widget. For \c PaletteBackground, use tqcolorGroup().brush( \c
+ TQColorGroup::Background ), and so on.
+
+ \value PaletteForeground
+ \value PaletteBackground
+ \value PaletteButton
+ \value PaletteLight
+ \value PaletteMidlight
+ \value PaletteDark
+ \value PaletteMid
+ \value PaletteText
+ \value PaletteBrightText
+ \value PaletteButtonText
+ \value PaletteBase
+ \value PaletteShadow
+ \value PaletteHighlight
+ \value PaletteHighlightedText
+ \value PaletteLink
+ \value PaletteLinkVisited
+ \value X11ParentRelative (internal use only)
+
+ The final three values have special meaning:
+
+ \value NoBackground the widget is not cleared before paintEvent().
+ If the widget's paint event always draws on all the pixels, using
+ this mode can be both fast and flicker-free.
+ \value FixedColor the widget is cleared to a fixed color, normally
+ different from all the ones in the palette(). Set using \link
+ TQWidget::setPaletteBackgroundColor()
+ setPaletteBackgroundColor()\endlink.
+ \value FixedPixmap the widget is cleared to a fixed pixmap,
+ normally different from all the ones in the palette(). Set using
+ \link TQWidget::setPaletteBackgroundPixmap()
+ setPaletteBackgroundPixmap()\endlink.
+
+ Although \c FixedColor and \c FixedPixmap are sometimes just
+ right, if you use them, make sure that you test your application
+ when the desktop color scheme has been changed. (On X11, a quick
+ way to test this is e.g. "./myapp -bg paleblue". On Windows, you
+ must use the control panel.)
+
+ \sa TQWidget::setBackgroundMode() TQWidget::backgroundMode()
+ TQWidget::setBackgroundPixmap() TQWidget::setPaletteBackgroundColor()
+*/
+
+/*!
+ \property TQWidget::backgroundMode
+ \brief the color role used for painting the background of the widget
+
+ setPaletteBackgroundColor() reads this property to determine which
+ entry of the \link TQWidget::palette palette\endlink to set.
+
+ For most widgets the default suffices (\c PaletteBackground,
+ typically gray), but some need to use \c PaletteBase (the
+ background color for text output, typically white) or another
+ role.
+
+ TQListBox, which is "sunken" and uses the base color to contrast
+ with its environment, does this in its constructor:
+
+ \code
+ setBackgroundMode( PaletteBase );
+ \endcode
+
+ You will never need to set the background mode of a built-in
+ widget in TQt, but you might consider setting it in your custom
+ widgets, so that setPaletteBackgroundColor() works as expected.
+
+ Note that two of the BackgroundMode values make no sense for
+ setBackgroundMode(), namely \c FixedPixmap and \c FixedColor. You
+ must call setBackgroundPixmap() and setPaletteBackgroundColor()
+ instead.
+*/
+TQt::BackgroundMode TQWidget::backgroundMode() const
+{
+ return extra ? (BackgroundMode) extra->bg_mode : PaletteBackground;
+}
+
+void TQWidget::setBackgroundMode( BackgroundMode m )
+{
+ setBackgroundMode( m, m );
+ if ( (widget_state & (WState_Visible|WState_BlockUpdates)) ==
+ WState_Visible )
+ update();
+}
+
+
+/*!
+ \overload
+
+ Sets the widget's own background mode to \a m and the visual
+ background mode to \a visual. The visual background mode is used
+ with the designable properties \c backgroundColor, \c
+ foregroundColor and \c backgroundPixmap.
+
+ For complex controls, the logical background mode sometimes
+ differs from a widget's own background mode. A spinbox for example
+ has \c PaletteBackground as background mode (typically dark gray),
+ while it's embedded lineedit control uses \c PaletteBase
+ (typically white). Since the lineedit covers most of the visual
+ area of a spinbox, it defines \c PaletteBase to be its \a visual
+ background mode. Changing the \c backgroundColor property thus
+ changes the lineedit control's background, which is exactly what
+ the user expects in \e{TQt Designer}.
+*/
+void TQWidget::setBackgroundMode( BackgroundMode m, BackgroundMode visual )
+{
+ if ( m == NoBackground ) {
+ setBackgroundEmpty();
+ } else if ( m == FixedColor || m == FixedPixmap ) {
+#if defined(TQT_DEBUG)
+ qWarning( "TQWidget::setBackgroundMode: FixedColor or FixedPixmap makes"
+ " no sense" );
+#endif
+ return;
+ }
+ setBackgroundModeDirect(m);
+ if ( m != visual && !extra )
+ createExtra();
+ if ( extra )
+ extra->bg_mode_visual = visual;
+}
+
+
+/*!
+ \internal
+*/
+void TQWidget::setBackgroundModeDirect( BackgroundMode m )
+{
+ if ( m == PaletteBackground && !extra )
+ return;
+
+ createExtra();
+ if ( (BackgroundMode)extra->bg_mode != m ) {
+ extra->bg_mode = m;
+ extra->bg_mode_visual = m;
+ setBackgroundFromMode();
+ }
+}
+
+/*!
+ \property TQWidget::paletteBackgroundColor
+ \brief the background color of the widget
+
+ The palette background color is usually set implicitly by
+ setBackgroundMode(), although it can also be set explicitly by
+ setPaletteBackgroundColor(). setPaletteBackgroundColor() is a
+ convenience function that creates and sets a modified TQPalette
+ with setPalette(). The palette is modified according to the
+ widget's background mode. For example, if the background mode is
+ \c PaletteButton the color used for the palette's \c
+ TQColorGroup::Button color entry is set.
+
+ If there is a background pixmap (set using
+ setPaletteBackgroundPixmap()), then the return value of this
+ function is indeterminate.
+
+ \sa paletteBackgroundPixmap, paletteForegroundColor, palette, tqcolorGroup()
+*/
+const TQColor & TQWidget::paletteBackgroundColor() const
+{
+#ifndef TQT_NO_PALETTE
+ BackgroundMode mode = extra ? (BackgroundMode) extra->bg_mode_visual : PaletteBackground;
+ switch( mode ) {
+ case FixedColor:
+ case FixedPixmap :
+ case NoBackground:
+ case X11ParentRelative:
+ return eraseColor();
+ default:
+ TQColorGroup::ColorRole role = TQPalette::backgroundRoleFromMode( mode );
+ return tqcolorGroup().color( role );
+ }
+#else
+ return eraseColor();
+#endif
+}
+
+void TQWidget::setPaletteBackgroundColor( const TQColor &color )
+{
+#ifndef TQT_NO_PALETTE
+ BackgroundMode mode = extra ? (BackgroundMode) extra->bg_mode_visual : PaletteBackground;
+ switch( mode ) {
+ case FixedColor:
+ case FixedPixmap :
+ case NoBackground:
+ case X11ParentRelative:
+ setEraseColor( color );
+ break;
+ default:
+ TQPalette pal = palette();
+ TQColorGroup::ColorRole role = TQPalette::backgroundRoleFromMode( mode );
+ pal.setColor( TQPalette::Active, role, color );
+ pal.setColor( TQPalette::Inactive, role, color );
+ pal.setColor( TQPalette::Disabled, role, color );
+ setPalette( pal );
+ break;
+ }
+#else
+ setEraseColor( color );
+#endif
+}
+
+
+/*!
+ \property TQWidget::paletteBackgroundPixmap
+ \brief the background pixmap of the widget
+
+ The palette background pixmap is usually set implicitly by
+ setBackgroundMode(), although it can also be set explicitly by
+ setPaletteBackgroundPixmap(). setPaletteBackgroundPixmap() is a
+ convenience function that creates and sets a modified TQPalette
+ with setPalette(). The palette is modified according to the
+ widget's background mode. For example, if the background mode is
+ \c PaletteButton the pixmap used for the palette's
+ \c TQColorGroup::Button color entry is set.
+
+ If there is a plain background color (set using
+ setPaletteBackgroundColor()), then this function returns 0.
+
+ \sa paletteBackgroundColor, paletteForegroundColor, palette, tqcolorGroup()
+*/
+const TQPixmap *TQWidget::paletteBackgroundPixmap() const
+{
+#ifndef TQT_NO_PALETTE
+ BackgroundMode mode = extra ? (BackgroundMode) extra->bg_mode_visual : PaletteBackground;
+ switch( mode ) {
+ case FixedColor:
+ case FixedPixmap :
+ case NoBackground:
+ case X11ParentRelative:
+ return erasePixmap();
+ default:
+ TQColorGroup::ColorRole role = TQPalette::backgroundRoleFromMode( mode );
+ return palette().brush( TQPalette::Active, role ).pixmap();
+ }
+#else
+ return erasePixmap();
+#endif
+}
+
+void TQWidget::setPaletteBackgroundPixmap( const TQPixmap &pixmap )
+{
+#ifndef TQT_NO_PALETTE
+ BackgroundMode mode = extra ? (BackgroundMode) extra->bg_mode_visual : PaletteBackground;
+ switch( mode ) {
+ case FixedColor:
+ case FixedPixmap :
+ case NoBackground:
+ case X11ParentRelative:
+ setErasePixmap( pixmap );
+ break;
+ default:
+ TQPalette pal = palette();
+ TQColorGroup::ColorRole role = TQPalette::backgroundRoleFromMode( mode );
+ pal.setBrush( TQPalette::Active, role, TQBrush( pal.color( TQPalette::Active, role ), pixmap ) );
+ pal.setBrush( TQPalette::Inactive, role, TQBrush( pal.color( TQPalette::Inactive, role ), pixmap ) );
+ pal.setBrush( TQPalette::Disabled, role, TQBrush( pal.color( TQPalette::Disabled, role ), pixmap ) );
+ setPalette( pal );
+ break;
+ }
+#else
+ setErasePixmap( pixmap );
+#endif
+}
+
+
+/*!
+ \property TQWidget::backgroundBrush
+ \brief the widget's background brush
+
+ The background brush depends on a widget's palette and its
+ background mode.
+
+ \sa backgroundColor(), backgroundPixmap(), eraseColor(), palette,
+ TQApplication::setPalette()
+*/
+const TQBrush& TQWidget::backgroundBrush() const
+{
+ static TQBrush noBrush;
+#ifndef TQT_NO_PALETTE
+ BackgroundMode mode = extra ? (BackgroundMode) extra->bg_mode_visual : PaletteBackground;
+ switch( mode ) {
+ case FixedColor:
+ case FixedPixmap :
+ case NoBackground:
+ case X11ParentRelative:
+ return noBrush;
+ default:
+ TQColorGroup::ColorRole role = TQPalette::backgroundRoleFromMode( mode );
+ return tqcolorGroup().brush( role );
+ }
+#else
+ return noBrush;
+#endif
+}
+
+
+/*!
+ \property TQWidget::tqcolorGroup
+ \brief the current color group of the widget palette
+
+ The color group is determined by the state of the widget. A
+ disabled widget has the TQPalette::disabled() color group, a widget
+ with keyboard focus has the TQPalette::active() color group, and an
+ inactive widget has the TQPalette::inactive() color group.
+
+ \sa palette
+*/
+#ifndef TQT_NO_PALETTE
+const TQColorGroup &TQWidget::tqcolorGroup() const
+{
+ if ( !isEnabled() )
+ return palette().disabled();
+ else if ( !isVisible() || isActiveWindow() )
+ return palette().active();
+ else
+ return palette().inactive();
+}
+#endif
+
+/*!
+ \property TQWidget::palette
+ \brief the widget's palette
+
+ As long as no special palette has been set, or after unsetPalette()
+ has been called, this is either a special palette for the widget
+ class, the tqparent's palette or (if this widget is a top level
+ widget), the default application palette.
+
+ Instead of defining an entirely new palette, you can also use the
+ \link TQWidget::paletteBackgroundColor paletteBackgroundColor\endlink,
+ \link TQWidget::paletteBackgroundPixmap paletteBackgroundPixmap\endlink and
+ \link TQWidget::paletteForegroundColor paletteForegroundColor\endlink
+ convenience properties to change a widget's
+ background and foreground appearance only.
+
+ \sa ownPalette, tqcolorGroup(), TQApplication::palette()
+*/
+
+#ifndef TQT_NO_PALETTE
+void TQWidget::setPalette( const TQPalette &palette )
+{
+ own_palette = TRUE;
+ if ( pal == palette )
+ return;
+ TQPalette old = pal;
+ pal = palette;
+ setBackgroundFromMode();
+ TQEvent ev( TQEvent::PaletteChange );
+ TQApplication::sendEvent( this, &ev );
+ if ( childrenListObject() ) {
+ TQEvent e( TQEvent::ParentPaletteChange );
+ TQObjectListIt it( *childrenListObject() );
+ TQWidget *w;
+ while( (w=(TQWidget *)it.current()) != 0 ) {
+ ++it;
+ if ( w->isWidgetType() )
+ TQApplication::sendEvent( w, &e );
+ }
+ }
+ paletteChange( old );
+ update();
+}
+
+void TQWidget::unsetPalette()
+{
+ // reset the palette
+ setPalette( qt_naturalWidgetPalette( this ) );
+ own_palette = FALSE;
+}
+
+/*!
+ \fn void TQWidget::setPalette( const TQPalette&, bool )
+ \obsolete
+
+ Use setPalette( const TQPalette& p ) instead.
+*/
+
+/*!
+ \fn void TQWidget::paletteChange( const TQPalette &oldPalette )
+
+ This virtual function is called from setPalette(). \a oldPalette
+ is the previous palette; you can get the new palette from
+ palette().
+
+ Reimplement this function if your widget needs to know when its
+ palette changes.
+
+ \sa setPalette(), palette()
+*/
+
+void TQWidget::paletteChange( const TQPalette & )
+{
+}
+#endif // TQT_NO_PALETTE
+
+/*!
+ \property TQWidget::font
+ \brief the font currently set for the widget
+
+ The fontInfo() function reports the actual font that is being used
+ by the widget.
+
+ As long as no special font has been set, or after unsetFont() is
+ called, this is either a special font for the widget class, the
+ tqparent's font or (if this widget is a top level widget), the
+ default application font.
+
+ This code fragment sets a 12 point helvetica bold font:
+ \code
+ TQFont f( "Helvetica", 12, TQFont::Bold );
+ setFont( f );
+ \endcode
+
+ In addition to setting the font, setFont() informs all tqchildren
+ about the change.
+
+ \sa fontChange() fontInfo() fontMetrics() ownFont()
+*/
+void TQWidget::setFont( const TQFont &font )
+{
+ own_font = TRUE;
+ if ( fnt == font && fnt.d->tqmask == font.d->tqmask )
+ return;
+ TQFont old = fnt;
+ fnt = font.resolve( qt_naturalWidgetFont( this ) );
+#if defined(TQ_WS_X11)
+ // make sure the font set on this widget is associated with the correct screen
+ fnt.x11SetScreen( x11Screen() );
+#endif
+ if ( childrenListObject() ) {
+ TQEvent e( TQEvent::ParentFontChange );
+ TQObjectListIt it( *childrenListObject() );
+ TQWidget *w;
+ while( (w=(TQWidget *)it.current()) != 0 ) {
+ ++it;
+ if ( w->isWidgetType() )
+ TQApplication::sendEvent( w, &e );
+ }
+ }
+ if ( hasFocus() )
+ setFontSys();
+ fontChange( old );
+}
+
+void TQWidget::unsetFont()
+{
+ // reset the font
+ setFont( qt_naturalWidgetFont( this ) );
+ own_font = FALSE;
+}
+
+/*!
+ \fn void TQWidget::setFont( const TQFont&, bool )
+ \obsolete
+
+ Use setFont(const TQFont& font) instead.
+*/
+
+/*!
+ \fn void TQWidget::fontChange( const TQFont &oldFont )
+
+ This virtual function is called from setFont(). \a oldFont is the
+ previous font; you can get the new font from font().
+
+ Reimplement this function if your widget needs to know when its
+ font changes. You will almost certainly need to update the widget
+ using update().
+
+ The default implementation updates the widget including its
+ tqgeometry.
+
+ \sa setFont(), font(), update(), updateGeometry()
+*/
+
+void TQWidget::fontChange( const TQFont & )
+{
+ update();
+ updateGeometry();
+}
+
+
+/*!
+ \fn TQFontMetrics TQWidget::fontMetrics() const
+
+ Returns the font metrics for the widget's current font.
+ Equivalent to TQFontMetrics(widget->font()).
+
+ \sa font(), fontInfo(), setFont()
+*/
+
+/*!
+ \fn TQFontInfo TQWidget::fontInfo() const
+
+ Returns the font info for the widget's current font.
+ Equivalent to TQFontInto(widget->font()).
+
+ \sa font(), fontMetrics(), setFont()
+*/
+
+
+/*!
+ \property TQWidget::cursor
+ \brief the cursor tqshape for this widget
+
+ The mouse cursor will assume this tqshape when it's over this
+ widget. See the \link TQt::tqCursorShape list of predefined cursor
+ objects\endlink for a range of useful tqshapes.
+
+ An editor widget might use an I-beam cursor:
+ \code
+ setCursor( IbeamCursor );
+ \endcode
+
+ If no cursor has been set, or after a call to unsetCursor(), the
+ tqparent's cursor is used. The function unsetCursor() has no effect
+ on top-level widgets.
+
+ \sa TQApplication::setOverrideCursor()
+*/
+
+#ifndef TQT_NO_CURSOR
+const TQCursor &TQWidget::cursor() const
+{
+ if ( testWState(WState_OwnCursor) )
+ return (extra && extra->curs)
+ ? *extra->curs
+ : arrowCursor;
+ else
+ return (isTopLevel() || !parentWidget()) ? arrowCursor : parentWidget()->cursor();
+}
+#endif
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+/*!
+ \property TQWidget::caption
+ \brief the window caption (title)
+
+ This property only makes sense for top-level widgets. If no
+ caption has been set, the caption is TQString::null.
+
+ \sa icon() iconText()
+*/
+TQString TQWidget::caption() const
+{
+ return extra && extra->topextra
+ ? extra->topextra->caption
+ : TQString::null;
+}
+
+/*!
+ \property TQWidget::icon
+ \brief the widget's icon
+
+ This property only makes sense for top-level widgets. If no icon
+ has been set, icon() returns 0.
+
+ \sa iconText, caption,
+ \link appicon.html Setting the Application Icon\endlink
+*/
+const TQPixmap *TQWidget::icon() const
+{
+ return ( extra && extra->topextra ) ? extra->topextra->icon : 0;
+}
+
+/*!
+ \property TQWidget::iconText
+ \brief the widget's icon text
+
+ This property only makes sense for top-level widgets. If no icon
+ text has been set, this functions returns TQString::null.
+
+ \sa icon, caption
+*/
+
+TQString TQWidget::iconText() const
+{
+ return ( extra && extra->topextra ) ? extra->topextra->iconText
+ : TQString::null;
+}
+#endif //TQT_NO_WIDGET_TOPEXTRA
+
+/*!
+ \property TQWidget::mouseTracking
+ \brief whether mouse tracking is enabled for the widget
+
+ If mouse tracking is disabled (the default), the widget only
+ receives mouse move events when at least one mouse button is
+ pressed while the mouse is being moved.
+
+ If mouse tracking is enabled, the widget receives mouse move
+ events even if no buttons are pressed.
+
+ \sa mouseMoveEvent(), TQApplication::setGlobalMouseTracking()
+*/
+
+
+/*!
+ Sets the widget's focus proxy to widget \a w. If \a w is 0, the
+ function resets this widget to have no focus proxy.
+
+ Some widgets, such as TQComboBox, can "have focus", but create a
+ child widget to actually handle the focus. TQComboBox, for example,
+ creates a TQLineEdit which handles the focus.
+
+ setFocusProxy() sets the widget which will actually get focus when
+ "this widget" gets it. If there is a focus proxy, focusPolicy(),
+ setFocusPolicy(), setFocus() and hasFocus() all operate on the
+ focus proxy.
+
+ \sa focusProxy()
+*/
+
+void TQWidget::setFocusProxy( TQWidget * w )
+{
+ if ( !w && !extra )
+ return;
+
+ for ( TQWidget* fp = w; fp; fp = fp->focusProxy() ) {
+ if ( fp == this ) {
+#if defined (TQT_CHECK_STATE)
+ qWarning( "%s (%s): already in focus proxy chain", className(), name() );
+#endif
+ return;
+ }
+ }
+
+ createExtra();
+
+ if ( extra->focus_proxy ) {
+ disconnect( extra->focus_proxy, TQT_SIGNAL(destroyed()),
+ this, TQT_SLOT(focusProxyDestroyed()) );
+ extra->focus_proxy = 0;
+ }
+
+ if ( w ) {
+ setFocusPolicy( w->focusPolicy() );
+ connect( w, TQT_SIGNAL(destroyed()),
+ this, TQT_SLOT(focusProxyDestroyed()) );
+ }
+ extra->focus_proxy = w;
+}
+
+
+/*!
+ Returns the focus proxy, or 0 if there is no focus proxy.
+
+ \sa setFocusProxy()
+*/
+
+TQWidget * TQWidget::focusProxy() const
+{
+ return extra ? extra->focus_proxy : 0;
+}
+
+
+/*!
+ \internal
+
+ Internal slot used to clean up if the focus proxy is destroyed.
+
+ \sa setFocusProxy()
+*/
+
+void TQWidget::focusProxyDestroyed()
+{
+ if ( extra )
+ extra->focus_proxy = 0;
+ setFocusPolicy( NoFocus );
+}
+
+/*!
+ \property TQWidget::focus
+ \brief whether this widget (or its focus proxy) has the keyboard
+ input focus
+
+ Effectively equivalent to \c {tqApp->tqfocusWidget() == this}.
+
+ \sa setFocus(), clearFocus(), setFocusPolicy(), TQApplication::tqfocusWidget()
+*/
+bool TQWidget::hasFocus() const
+{
+ const TQWidget* w = this;
+ while ( w->focusProxy() )
+ w = w->focusProxy();
+ return tqApp->tqfocusWidget() == w;
+}
+
+/*!
+ Gives the keyboard input focus to this widget (or its focus
+ proxy) if this widget or one of its parents is the \link
+ isActiveWindow() active window\endlink.
+
+ First, a focus out event is sent to the focus widget (if any) to
+ tell it that it is about to lose the focus. Then a focus in event
+ is sent to this widget to tell it that it just received the focus.
+ (Nothing happens if the focus in and focus out widgets are the
+ same.)
+
+ setFocus() gives focus to a widget regardless of its focus policy,
+ but does not clear any keyboard grab (see grabKeyboard()).
+
+ Be aware that if the widget is hidden, it will not accept focus.
+
+ \warning If you call setFocus() in a function which may itself be
+ called from focusOutEvent() or focusInEvent(), you may get an
+ infinite recursion.
+
+ \sa hasFocus() clearFocus() focusInEvent() focusOutEvent()
+ setFocusPolicy() TQApplication::tqfocusWidget() grabKeyboard()
+ grabMouse()
+*/
+
+void TQWidget::setFocus()
+{
+ if ( !isEnabled() )
+ return;
+
+ if ( focusProxy() ) {
+ focusProxy()->setFocus();
+ return;
+ }
+
+ TQFocusData * f = focusData( TRUE );
+ if ( f->it.current() == this && tqApp->tqfocusWidget() == this
+#if defined(TQ_WS_WIN)
+ && GetFocus() == winId()
+#endif
+ )
+ return;
+
+ f->it.toFirst();
+ while ( f->it.current() != this && !f->it.atLast() )
+ ++f->it;
+ // at this point, the iterator should point to 'this'. if it
+ // does not, 'this' must not be in the list - an error, but
+ // perhaps possible. fix it.
+ if ( f->it.current() != this ) {
+ f->tqfocusWidgets.append( this );
+ f->it.toLast();
+ }
+
+ if ( isActiveWindow() ) {
+ TQWidget * prev = tqApp->focus_widget;
+ if ( prev ) {
+ if ( prev != this )
+ prev->resetInputContext();
+ }
+#if defined(TQ_WS_WIN)
+ else {
+ TQInputContext::endComposition();
+ }
+#endif
+ tqApp->focus_widget = this;
+#if defined(TQ_WS_X11)
+ focusInputContext();
+#endif
+
+#if defined(TQ_WS_WIN)
+ if ( !tqtopLevelWidget()->isPopup() )
+ SetFocus( winId() );
+ else {
+#endif
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::Focus );
+#endif
+#if defined(TQ_WS_WIN)
+ }
+#endif
+
+ if ( prev != this ) {
+ if ( prev ) {
+ TQFocusEvent out( TQEvent::FocusOut );
+ TQApplication::sendEvent( prev, &out );
+ }
+
+ if ( tqApp->focus_widget == this ) {
+ TQFocusEvent in( TQEvent::FocusIn );
+ TQApplication::sendEvent( this, &in );
+ }
+ }
+ }
+}
+
+/*!
+ Takes keyboard input focus from the widget.
+
+ If the widget has active focus, a \link focusOutEvent() focus out
+ event\endlink is sent to this widget to tell it that it is about
+ to lose the focus.
+
+ This widget must enable focus setting in order to get the keyboard
+ input focus, i.e. it must call setFocusPolicy().
+
+ \sa hasFocus(), setFocus(), focusInEvent(), focusOutEvent(),
+ setFocusPolicy(), TQApplication::tqfocusWidget()
+*/
+
+void TQWidget::clearFocus()
+{
+ if ( focusProxy() ) {
+ focusProxy()->clearFocus();
+ return;
+ } else if ( hasFocus() ) {
+ resetInputContext();
+ TQWidget* w = tqApp->tqfocusWidget();
+ // clear active focus
+ tqApp->focus_widget = 0;
+ TQFocusEvent out( TQEvent::FocusOut );
+ TQApplication::sendEvent( w, &out );
+#if defined(TQ_WS_WIN)
+ if ( !isPopup() && GetFocus() == winId() )
+ SetFocus( 0 );
+ else {
+#endif
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::Focus );
+#endif
+#if defined(TQ_WS_WIN)
+ }
+#endif
+ }
+}
+
+
+/*!
+ Finds a new widget to give the keyboard focus to, as appropriate
+ for Tab and Shift+Tab, and returns TRUE if is can tqfind a new
+ widget and FALSE if it can't,
+
+ If \a next is TRUE, this function searches "forwards", if \a next
+ is FALSE, it searches "backwards".
+
+ Sometimes, you will want to reimplement this function. For
+ example, a web browser might reimplement it to move its "current
+ active link" forwards or backwards, and call
+ TQWidget::focusNextPrevChild() only when it reaches the last or
+ first link on the "page".
+
+ Child widgets call focusNextPrevChild() on their tqparent widgets,
+ but only the top-level widget decides where to redirect focus. By
+ overriding this method for an object, you thus gain control of
+ focus traversal for all child widgets.
+
+ \warning TQScrollView uses it own logic for this function, which
+ does the right thing in most cases. But if you are using a
+ TQScrollView and want complete control of the focus chain you'll
+ need to override TQScrollView::focusNextPrevChild() and your
+ top-level widgets' focusNextPrevChild() functions.
+
+ \sa focusData()
+*/
+
+bool TQWidget::focusNextPrevChild( bool next )
+{
+ TQWidget* p = parentWidget();
+ if ( !isTopLevel() && p )
+ return p->focusNextPrevChild(next);
+
+ TQFocusData *f = focusData( TRUE );
+
+ TQWidget *startingPoint = f->it.current();
+ TQWidget *candidate = 0;
+ TQWidget *w = next ? f->tqfocusWidgets.last() : f->tqfocusWidgets.first();
+ extern bool qt_tab_all_widgets;
+ uint focus_flag = qt_tab_all_widgets ? TabFocus : StrongFocus;
+ do {
+ if ( w && w != startingPoint &&
+ ( ( w->focusPolicy() & focus_flag ) == focus_flag )
+ && !w->focusProxy() && w->isVisibleTo(this) && w->isEnabled())
+ candidate = w;
+ w = next ? f->tqfocusWidgets.prev() : f->tqfocusWidgets.next();
+ } while( w && !(candidate && w==startingPoint) );
+
+ if ( !candidate )
+ return FALSE;
+
+ candidate->setFocus();
+ return TRUE;
+}
+
+/*!
+ Returns the focus widget in this widget's window. This is not the
+ same as TQApplication::tqfocusWidget(), which returns the focus
+ widget in the currently active window.
+*/
+
+TQWidget *TQWidget::tqfocusWidget() const
+{
+ TQWidget *that = (TQWidget *)this; // mutable
+ TQFocusData *f = that->focusData( FALSE );
+ if ( f && f->tqfocusWidgets.count() && f->it.current() == 0 )
+ f->it.toFirst();
+ return ( f && f->it.current() ) ? f->it.current() : 0;
+}
+
+
+/*!
+ Returns the focus data for this widget's top-level widget.
+
+ Focus data always belongs to the top-level widget. The focus data
+ list tqcontains all the widgets in this top-level widget that can
+ accept focus, in tab order. An iterator points to the current
+ focus widget (tqfocusWidget() returns a pointer to this widget).
+
+ This information is useful for implementing advanced versions of
+ focusNextPrevChild().
+*/
+TQFocusData * TQWidget::focusData()
+{
+ return focusData( TRUE );
+}
+
+/*!
+ \internal
+
+ Internal function which lets us ask for the focus data, creating
+ it if it doesn't exist and \a create is TRUE.
+*/
+TQFocusData * TQWidget::focusData( bool create )
+{
+ TQWidget * tlw = tqtopLevelWidget();
+ TQWExtra * ed = tlw->extraData();
+ if ( !ed || !ed->topextra ) {
+ if ( !create )
+ return 0;
+ tlw->createTLExtra();
+ ed = tlw->extraData();
+ }
+ if ( create && !ed->topextra->focusData )
+ ed->topextra->focusData = new TQFocusData;
+
+ return ed->topextra->focusData;
+}
+
+/*!
+ \property TQWidget::inputMethodEnabled
+ \brief enables or disables the use of input methods for this widget.
+
+ Most Widgets (as eg. buttons) that do not handle text input should have
+ the input method disabled if they have focus. This is the default.
+
+ If a widget handles text input it should set this property to TRUE.
+*/
+
+void TQWidget::setInputMethodEnabled( bool b )
+{
+ im_enabled = b;
+#ifdef TQ_WS_WIN
+ TQInputContext::enable( this, im_enabled & !((bool)testWState(WState_Disabled)) );
+#endif
+}
+
+
+/*!
+ Enables key event compression, if \a compress is TRUE, and
+ disables it if \a compress is FALSE.
+
+ Key compression is off by default (except for TQLineEdit and
+ TQTextEdit), so widgets receive one key press event for each key
+ press (or more, since autorepeat is usually on). If you turn it on
+ and your program doesn't keep up with key input, TQt may try to
+ compress key events so that more than one character can be
+ processed in each event.
+
+ For example, a word processor widget might receive 2, 3 or more
+ characters in each TQKeyEvent::text(), if the tqlayout recalculation
+ takes too long for the CPU.
+
+ If a widget supports multiple character tqunicode input, it is
+ always safe to turn the compression on.
+
+ TQt performs key event compression only for printable characters.
+ Modifier keys, cursor movement keys, function keys and
+ miscellaneous action keys (e.g. Escape, Enter, Backspace,
+ PrintScreen) will stop key event compression, even if there are
+ more compressible key events available.
+
+ Not all platforms support this compression, in which case turning
+ it on will have no effect.
+
+ \sa TQKeyEvent::text();
+*/
+
+void TQWidget::setKeyCompression(bool compress)
+{
+ if ( compress )
+ setWState( WState_CompressKeys );
+ else
+ clearWState( WState_CompressKeys );
+}
+
+/*!
+ \property TQWidget::isActiveWindow
+ \brief whether this widget is the active window
+
+ The active window is the window that tqcontains the widget
+ that has keyboard focus.
+
+ When popup windows are visible, this property is TRUE for both the
+ active window \e and for the popup.
+
+ \sa setActiveWindow(), TQApplication::activeWindow()
+*/
+bool TQWidget::isActiveWindow() const
+{
+ TQWidget *tlw = tqtopLevelWidget();
+ if(testWFlags(WSubWindow) && parentWidget())
+ tlw = parentWidget()->tqtopLevelWidget();
+ if(tlw == tqApp->activeWindow() || ( isVisible() && tlw->isPopup() ))
+ return TRUE;
+#ifndef TQT_NO_STYLE
+ if(style().tqstyleHint(TQStyle::SH_Widget_ShareActivation, this )) {
+ if((tlw->isDialog() || (tlw->testWFlags(TQt::WStyle_Tool) && !tlw->isPopup())) &&
+ !tlw->testWFlags(TQt::WShowModal) &&
+ (!tlw->parentWidget() || tlw->parentWidget()->isActiveWindow()))
+ return TRUE;
+ TQWidget *w = tqApp->activeWindow();
+ if( !testWFlags(WSubWindow) && w && w->testWFlags(WSubWindow) &&
+ w->parentWidget()->tqtopLevelWidget() == tlw)
+ return TRUE;
+ while(w && (tlw->isDialog() || tlw->testWFlags(TQt::WStyle_Tool)) &&
+ !w->testWFlags(TQt::WShowModal) && w->parentWidget()) {
+ w = w->parentWidget()->tqtopLevelWidget();
+ if( w == tlw )
+ return TRUE;
+ }
+ }
+#endif
+#if defined(TQ_WS_WIN32)
+ HWND tqparent = tlw->winId();
+ HWND toptqparent = GetActiveWindow();
+ while ( tqparent ) {
+ tqparent = ::GetParent( tqparent );
+ if ( tqparent && tqparent == toptqparent )
+ return TRUE;
+ }
+#endif
+
+ return FALSE;
+}
+
+/*!
+ Moves the \a second widget around the ring of focus widgets so
+ that keyboard focus moves from the \a first widget to the \a
+ second widget when the Tab key is pressed.
+
+ Note that since the tab order of the \a second widget is changed,
+ you should order a chain like this:
+
+ \code
+ setTabOrder( a, b ); // a to b
+ setTabOrder( b, c ); // a to b to c
+ setTabOrder( c, d ); // a to b to c to d
+ \endcode
+
+ \e not like this:
+
+ \code
+ setTabOrder( c, d ); // c to d WRONG
+ setTabOrder( a, b ); // a to b AND c to d
+ setTabOrder( b, c ); // a to b to c, but not c to d
+ \endcode
+
+ If \a first or \a second has a focus proxy, setTabOrder()
+ correctly substitutes the proxy.
+
+ \sa setFocusPolicy(), setFocusProxy()
+*/
+void TQWidget::setTabOrder( TQWidget* first, TQWidget *second )
+{
+ if ( !first || !second ||
+ first->focusPolicy() == NoFocus || second->focusPolicy() == NoFocus )
+ return;
+
+ // If first is redirected, set first to the last child of first
+ // that can take keyboard focus so that second is inserted after
+ // that last child, and the focus order within first is (more
+ // likely to be) preserved.
+ if ( first->focusProxy() ) {
+ TQObjectList *l = first->queryList( "TQWidget" );
+ if ( l && l->count() ) {
+ TQObjectListIt it(*l);
+ it.toLast();
+ while (it.current()) {
+ if (((TQWidget*)it.current())->tqtopLevelWidget() == first->tqtopLevelWidget()) {
+ first = (TQWidget*)it.current();
+ if (first->focusPolicy() != NoFocus)
+ break;
+ }
+ --it;
+ }
+ }
+ delete l;
+ }
+ while ( first->focusProxy() )
+ first = first->focusProxy();
+ while ( second->focusProxy() )
+ second = second->focusProxy();
+
+ TQFocusData *f = first->focusData( TRUE );
+ bool focusThere = (f->it.current() == second );
+ f->tqfocusWidgets.removeRef( second );
+ if ( f->tqfocusWidgets.tqfindRef( first ) >= 0 )
+ f->tqfocusWidgets.insert( f->tqfocusWidgets.at() + 1, second );
+ else
+ f->tqfocusWidgets.append( second );
+ if ( focusThere ) { // reset iterator so tab will work appropriately
+ f->it.toFirst();
+ while( f->it.current() && f->it.current() != second )
+ ++f->it;
+ }
+}
+
+/*!\internal
+
+ Moves the relevant subwidgets of this widget from the \a oldtlw's
+ tab chain to that of the new tqparent, if there's anything to move and
+ we're really moving
+
+ This function is called from TQWidget::reparent() *after* the widget
+ has been reparented.
+
+ \sa reparent()
+*/
+
+void TQWidget::reparentFocusWidgets( TQWidget * oldtlw )
+{
+ if ( oldtlw == tqtopLevelWidget() )
+ return; // nothing to do
+
+ TQFocusData * from = oldtlw ? oldtlw->topData()->focusData : 0;
+ TQFocusData * to;
+ to = focusData();
+
+ if ( from ) {
+ from->tqfocusWidgets.first();
+ do {
+ TQWidget * pw = from->tqfocusWidgets.current();
+ while( pw && pw != this )
+ pw = pw->parentWidget();
+ if ( pw == this ) {
+ TQWidget * w = from->tqfocusWidgets.take();
+ if ( w == from->it.current() )
+ // probably best to clear keyboard focus, or
+ // the user might become rather confused
+ w->clearFocus();
+ if ( !isTopLevel() )
+ to->tqfocusWidgets.append( w );
+ } else {
+ from->tqfocusWidgets.next();
+ }
+ } while( from->tqfocusWidgets.current() );
+ }
+
+ if ( to->tqfocusWidgets.tqfindRef(this) < 0 )
+ to->tqfocusWidgets.append( this );
+
+ if ( !isTopLevel() && extra && extra->topextra && extra->topextra->focusData ) {
+ // this widget is no longer a top-level widget, so get rid
+ // of old focus data
+ delete extra->topextra->focusData;
+ extra->topextra->focusData = 0;
+ }
+}
+
+/*!
+ \fn void TQWidget::recreate( TQWidget *tqparent, WFlags f, const TQPoint & p, bool showIt )
+
+ \obsolete
+
+ This method is provided to aid porting from TQt 1.0 to 2.0. It has
+ been renamed reparent() in TQt 2.0.
+*/
+
+/*!
+ \property TQWidget::frameSize
+ \brief the size of the widget including any window frame
+*/
+TQSize TQWidget::frameSize() const
+{
+ if ( isTopLevel() && !isPopup() ) {
+ if ( fstrut_dirty )
+ updateFrameStrut();
+ TQWidget *that = (TQWidget *) this;
+ TQTLWExtra *top = that->topData();
+ return TQSize( crect.width() + top->fleft + top->fright,
+ crect.height() + top->ftop + top->fbottom );
+ }
+ return crect.size();
+}
+
+/*!
+ \internal
+
+ Recursive function that updates \a widget and all its tqchildren,
+ if they have some tqparent background origin.
+*/
+static void qt_update_bg_recursive( TQWidget *widget )
+{
+ if ( !widget || widget->isHidden() || widget->backgroundOrigin() == TQWidget::WidgetOrigin || !widget->backgroundPixmap() )
+ return;
+
+ const TQObjectList *lst = widget->childrenListObject();
+
+ if ( lst ) {
+ TQObjectListIterator it( *lst );
+ TQWidget *widget;
+ while ( (widget = (TQWidget*)it.current()) ) {
+ ++it;
+ if ( widget->isWidgetType() && !widget->isHidden() && !widget->isTopLevel() && !widget->testWFlags(TQt::WSubWindow) )
+ qt_update_bg_recursive( widget );
+ }
+ }
+ TQApplication::postEvent( widget, new TQPaintEvent( widget->clipRegion(), !widget->testWFlags(TQt::WRepaintNoErase) ) );
+}
+
+/*!
+ \overload
+
+ This corresponds to move( TQPoint(\a x, \a y) ).
+*/
+
+void TQWidget::move( int x, int y )
+{
+ TQPoint oldp(pos());
+ internalSetGeometry( x + tqgeometry().x() - TQWidget::x(),
+ y + tqgeometry().y() - TQWidget::y(),
+ width(), height(), TRUE );
+ if ( isVisible() && oldp != pos() )
+ qt_update_bg_recursive( this );
+}
+
+/*!
+ \overload
+
+ This corresponds to resize( TQSize(\a w, \a h) ).
+*/
+void TQWidget::resize( int w, int h )
+{
+ internalSetGeometry( tqgeometry().x(), tqgeometry().y(), w, h, FALSE );
+ setWState( WState_Resized );
+}
+
+/*!
+ \overload
+
+ This corresponds to setGeometry( TQRect(\a x, \a y, \a w, \a h) ).
+*/
+void TQWidget::setGeometry( int x, int y, int w, int h )
+{
+ TQPoint oldp( pos( ));
+ internalSetGeometry( x, y, w, h, TRUE );
+ setWState( WState_Resized );
+ if ( isVisible() && oldp != pos() )
+ qt_update_bg_recursive( this );
+}
+
+/*!
+ \property TQWidget::focusEnabled
+ \brief whether the widget accepts keyboard focus
+
+ Keyboard focus is initially disabled (i.e. focusPolicy() ==
+ \c TQWidget::NoFocus).
+
+ You must enable keyboard focus for a widget if it processes
+ keyboard events. This is normally done from the widget's
+ constructor. For instance, the TQLineEdit constructor calls
+ setFocusPolicy(TQWidget::StrongFocus).
+
+ \sa setFocusPolicy(), focusInEvent(), focusOutEvent(), keyPressEvent(),
+ keyReleaseEvent(), isEnabled()
+*/
+
+/*!
+ \enum TQWidget::FocusPolicy
+
+ This enum type defines the various policies a widget can have with
+ respect to acquiring keyboard focus.
+
+ \value TabFocus the widget accepts focus by tabbing.
+ \value ClickFocus the widget accepts focus by clicking.
+ \value StrongFocus the widget accepts focus by both tabbing
+ and clicking. On Mac OS X this will also
+ be indicate that the widget accepts tab focus
+ when in 'Text/List focus mode'.
+ \value WheelFocus like StrongFocus plus the widget accepts
+ focus by using the mouse wheel.
+ \value NoFocus the widget does not accept focus.
+
+*/
+
+/*!
+ \property TQWidget::focusPolicy
+ \brief the way the widget accepts keyboard focus
+
+ The policy is \c TQWidget::TabFocus if the widget accepts keyboard
+ focus by tabbing, \c TQWidget::ClickFocus if the widget accepts
+ focus by clicking, \c TQWidget::StrongFocus if it accepts both, and
+ \c TQWidget::NoFocus (the default) if it does not accept focus at
+ all.
+
+ You must enable keyboard focus for a widget if it processes
+ keyboard events. This is normally done from the widget's
+ constructor. For instance, the TQLineEdit constructor calls
+ setFocusPolicy(TQWidget::StrongFocus).
+
+ \sa focusEnabled, focusInEvent(), focusOutEvent(), keyPressEvent(),
+ keyReleaseEvent(), enabled
+*/
+
+void TQWidget::setFocusPolicy( FocusPolicy policy )
+{
+ if ( focusProxy() )
+ focusProxy()->setFocusPolicy( policy );
+ if ( policy != NoFocus ) {
+ TQFocusData * f = focusData( TRUE );
+ if ( f->tqfocusWidgets.tqfindRef( this ) < 0 )
+ f->tqfocusWidgets.append( this );
+ }
+ focus_policy = (uint) policy;
+}
+
+/*!
+ \property TQWidget::updatesEnabled
+ \brief whether updates are enabled
+
+ Calling update() and tqrepaint() has no effect if updates are
+ disabled. Paint events from the window system are processed
+ normally even if updates are disabled.
+
+ setUpdatesEnabled() is normally used to disable updates for a
+ short period of time, for instance to avoid screen flicker during
+ large changes.
+
+ Example:
+ \code
+ setUpdatesEnabled( FALSE );
+ bigVisualChanges();
+ setUpdatesEnabled( TRUE );
+ tqrepaint();
+ \endcode
+
+ \sa update(), tqrepaint(), paintEvent()
+*/
+void TQWidget::setUpdatesEnabled( bool enable )
+{
+ if ( enable )
+ clearWState( WState_BlockUpdates );
+ else
+ setWState( WState_BlockUpdates );
+}
+
+/*!
+ Shows the widget and its child widgets.
+
+ If its size or position has changed, TQt guarantees that a widget
+ gets move and resize events just before it is shown.
+
+ You almost never have to reimplement this function. If you need to
+ change some settings before a widget is shown, use showEvent()
+ instead. If you need to do some delayed initialization use
+ polish().
+
+ \sa showEvent(), hide(), showMinimized(), showMaximized(),
+ showNormal(), isVisible(), polish()
+*/
+
+void TQWidget::show()
+{
+ if ( testWState(WState_Visible) )
+ return;
+
+ bool wasHidden = isHidden();
+ bool postLayoutHint = !isTopLevel() && wasHidden;
+ clearWState( WState_ForceHide | WState_CreatedHidden );
+
+ if ( !isTopLevel() && !parentWidget()->isVisible() ) {
+ // we should become visible, but one of our ancestors is
+ // explicitly hidden. Since we cleared the ForceHide flag, our
+ // immediate tqparent will call show() on us again during its
+ // own processing of show().
+ if ( wasHidden ) {
+ TQEvent showToParentEvent( TQEvent::ShowToParent );
+ TQApplication::sendEvent( this, &showToParentEvent );
+ }
+ if ( postLayoutHint )
+ TQApplication::postEvent( parentWidget(),
+ new TQEvent(TQEvent::LayoutHint) );
+ return;
+ }
+
+ in_show = TRUE; // set qws recursion watch
+
+ TQApplication::sendPostedEvents( this, TQEvent::ChildInserted );
+
+ uint state = isTopLevel() ? windowState() : 0;
+#ifndef TQ_OS_TEMP
+ if ( isTopLevel() && !testWState( WState_Resized ) ) {
+ // do this before sending the posted resize events. Otherwise
+ // the tqlayout would catch the resize event and may expand the
+ // minimum size.
+ TQSize s = qt_naturalWidgetSize( this );
+ if ( !s.isEmpty() )
+ resize( s );
+ }
+#endif // TQ_OS_TEMP
+
+ TQApplication::sendPostedEvents( this, TQEvent::Move );
+ TQApplication::sendPostedEvents( this, TQEvent::Resize );
+
+ // the resizing and layouting might have changed the window state
+ if (isTopLevel() && windowState() != state)
+ setWindowState(state);
+
+ setWState( WState_Visible );
+
+ if ( parentWidget() )
+ TQApplication::sendPostedEvents( parentWidget(),
+ TQEvent::ChildInserted );
+
+ if ( extra ) {
+ int w = crect.width();
+ int h = crect.height();
+ if ( w < extra->minw || h < extra->minh ||
+ w > extra->maxw || h > extra->maxh ) {
+ w = TQMAX( extra->minw, TQMIN( w, extra->maxw ));
+ h = TQMAX( extra->minh, TQMIN( h, extra->maxh ));
+ resize( w, h ); // deferred resize
+ }
+ }
+
+ if ( testWFlags(WStyle_Tool) || isPopup() ) {
+ raise();
+ } else if ( testWFlags(WType_TopLevel) ) {
+ while ( TQApplication::activePopupWidget() ) {
+ if ( !TQApplication::activePopupWidget()->close() )
+ break;
+ }
+ }
+
+ if ( !testWState(WState_Polished) )
+ polish();
+
+ showChildren( FALSE );
+
+ if ( postLayoutHint )
+ TQApplication::postEvent( parentWidget(),
+ new TQEvent(TQEvent::LayoutHint) );
+
+ // Required for Mac, not sure whether we should always do that
+ if( isTopLevel() )
+ TQApplication::sendPostedEvents(0, TQEvent::LayoutHint);
+
+ // On Windows, show the popup now so that our own focus handling
+ // stores the correct old focus widget even if it's stolen in the showevent
+#if defined(TQ_WS_WIN)
+ if ( testWFlags(WType_Popup) )
+ tqApp->openPopup( this );
+#endif
+
+ TQShowEvent showEvent;
+ TQApplication::sendEvent( this, &showEvent );
+
+ if ( testWFlags(WShowModal) ) {
+ // qt_enter_modal *before* show, otherwise the initial
+ // stacking might be wrong
+ qt_enter_modal( this );
+ }
+
+ // do not show the window directly, but post a show-window request
+ // to reduce flicker with widgets in layouts
+ if ( postLayoutHint )
+ TQApplication::postEvent( this, new TQEvent( TQEvent::ShowWindowRequest ) );
+ else
+ showWindow();
+
+#if !defined(TQ_WS_WIN)
+ if ( testWFlags(WType_Popup) )
+ tqApp->openPopup( this );
+#endif
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ObjectShow );
+#endif
+
+ in_show = FALSE; // reset qws recursion watch
+}
+
+/*! \fn void TQWidget::iconify()
+ \obsolete
+*/
+
+/*!
+ Hides the widget.
+
+ You almost never have to reimplement this function. If you need to
+ do something after a widget is hidden, use hideEvent() instead.
+
+ \sa hideEvent(), isHidden(), show(), showMinimized(), isVisible(), close()
+*/
+
+void TQWidget::hide()
+{
+ clearWState( WState_CreatedHidden );
+ if ( testWState(WState_ForceHide) )
+ return;
+
+ setWState( WState_ForceHide );
+
+ if ( testWFlags(WType_Popup) )
+ tqApp->closePopup( this );
+
+ // Move test modal here. Otherwise, a modal dialog could get
+ // destroyed and we lose all access to its tqparent because we haven't
+ // left modality. (Eg. modal Progress Dialog)
+ if ( testWFlags(WShowModal) )
+ qt_leave_modal( this );
+
+#if defined(TQ_WS_WIN)
+ if ( isTopLevel() && !isPopup() && parentWidget() && isActiveWindow() )
+ parentWidget()->setActiveWindow(); // Activate tqparent
+#endif
+
+ hideWindow();
+
+ if ( testWState(WState_Visible) ) {
+ clearWState( WState_Visible );
+
+ // next bit tries to move the focus if the focus widget is now
+ // hidden.
+ if ( tqApp && tqApp->tqfocusWidget() == this )
+ focusNextPrevChild( TRUE );
+ TQHideEvent hideEvent;
+ TQApplication::sendEvent( this, &hideEvent );
+ hideChildren( FALSE );
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ObjectHide );
+#endif
+ } else {
+ TQEvent hideToParentEvent( TQEvent::HideToParent );
+ TQApplication::sendEvent( this, &hideToParentEvent );
+ }
+
+ // post tqlayout hint for non toplevels. The tqparent widget check is
+ // necessary since the function is called in the destructor
+ if ( !isTopLevel() && parentWidget() )
+ TQApplication::postEvent( parentWidget(),
+ new TQEvent( TQEvent::LayoutHint) );
+}
+
+void TQWidget::setShown( bool show )
+{
+ if ( show )
+ this->show();
+ else
+ hide();
+}
+
+void TQWidget::setHidden( bool hide )
+{
+ if ( hide )
+ this->hide();
+ else
+ show();
+}
+
+void TQWidget::showChildren( bool spontaneous )
+{
+ if ( childrenListObject() ) {
+ TQObjectListIt it(*childrenListObject());
+ register TQObject *object;
+ TQWidget *widget;
+ while ( it ) {
+ object = it.current();
+ ++it;
+ if ( object->isWidgetType() ) {
+ widget = (TQWidget*)object;
+ if ( !widget->isTopLevel() && widget->isShown() ) {
+ if ( spontaneous ) {
+ widget->showChildren( spontaneous );
+ TQShowEvent e;
+ TQApplication::sendSpontaneousEvent( widget, &e );
+ } else {
+ widget->show();
+ }
+ }
+ }
+ }
+ }
+}
+
+void TQWidget::hideChildren( bool spontaneous )
+{
+ if ( childrenListObject() ) {
+ TQObjectListIt it(*childrenListObject());
+ register TQObject *object;
+ TQWidget *widget;
+ while ( it ) {
+ object = it.current();
+ ++it;
+ if ( object->isWidgetType() ) {
+ widget = (TQWidget*)object;
+ if ( !widget->isTopLevel() && widget->isShown() ) {
+ if ( !spontaneous )
+ widget->clearWState( WState_Visible );
+ widget->hideChildren( spontaneous );
+ TQHideEvent e;
+ if ( spontaneous )
+ TQApplication::sendSpontaneousEvent( widget, &e );
+ else
+ TQApplication::sendEvent( widget, &e );
+ }
+ }
+ }
+ }
+}
+
+
+/*!
+ Delayed initialization of a widget.
+
+ This function will be called \e after a widget has been fully
+ created and \e before it is shown the very first time.
+
+ Polishing is useful for final initialization which depends on
+ having an instantiated widget. This is something a constructor
+ cannot guarantee since the initialization of the subclasses might
+ not be finished.
+
+ After this function, the widget has a proper font and palette and
+ TQApplication::polish() has been called.
+
+ Remember to call TQWidget's implementation first when reimplementing this
+ function to ensure that your program does not end up in infinite recursion.
+
+ \sa constPolish(), TQApplication::polish()
+*/
+
+void TQWidget::polish()
+{
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( isTopLevel() ) {
+ const TQPixmap *pm = icon();
+ if ( !pm || pm->isNull() ) {
+ TQWidget *mw = (TQWidget *)tqparent();
+ pm = mw ? mw->icon() : 0;
+ if ( pm && !pm->isNull() )
+ setIcon( *pm );
+ else {
+ mw = mw ? mw->tqtopLevelWidget() : 0;
+ pm = mw ? mw->icon() : 0;
+ if ( pm && !pm->isNull() )
+ setIcon( *pm );
+ else {
+ mw = tqApp ? tqApp->mainWidget() : 0;
+ pm = mw ? mw->icon() : 0;
+ if ( pm && !pm->isNull() )
+ setIcon( *pm );
+ }
+ }
+ }
+ }
+#endif
+ if ( !testWState(WState_Polished) ) {
+ if ( ! own_font &&
+ ! TQApplication::font( this ).isCopyOf( TQApplication::font() ) )
+ unsetFont();
+#ifndef TQT_NO_PALETTE
+ if ( ! own_palette &&
+ ! TQApplication::palette( this ).isCopyOf( TQApplication::palette() ) )
+ unsetPalette();
+#endif
+ setWState(WState_Polished);
+ tqApp->polish( this );
+ TQApplication::sendPostedEvents( this, TQEvent::ChildInserted );
+ }
+}
+
+
+/*!
+ \fn void TQWidget::constPolish() const
+
+ Ensures that the widget is properly initialized by calling
+ polish().
+
+ Call constPolish() from functions like tqsizeHint() that depends on
+ the widget being initialized, and that may be called before
+ show().
+
+ \warning Do not call constPolish() on a widget from inside that
+ widget's constructor.
+
+ \sa polish()
+*/
+
+/*!
+ \overload
+
+ Closes this widget. Returns TRUE if the widget was closed;
+ otherwise returns FALSE.
+
+ If \a alsoDelete is TRUE or the widget has the \c
+ WDestructiveClose widget flag, the widget is also deleted. The
+ widget can prevent itself from being closed by rejecting the
+ \l TQCloseEvent it gets. A close events is delivered to the widget
+ no matter if the widget is visible or not.
+
+ The TQApplication::lastWindowClosed() signal is emitted when the
+ last visible top level widget is closed.
+
+ Note that closing the \l TQApplication::mainWidget() terminates the
+ application.
+
+ \sa closeEvent(), TQCloseEvent, hide(), TQApplication::quit(),
+ TQApplication::setMainWidget(), TQApplication::lastWindowClosed()
+*/
+
+bool TQWidget::close( bool alsoDelete )
+{
+ if ( is_closing )
+ return TRUE;
+ is_closing = 1;
+ WId id = winId();
+ bool isMain = tqApp->mainWidget() == this;
+ bool checkLastWindowClosed = isTopLevel() && !isPopup();
+ bool deleted = FALSE;
+ TQCloseEvent e;
+ TQApplication::sendEvent( this, &e );
+ deleted = !TQWidget::tqfind(id);
+ if ( !deleted && !e.isAccepted() ) {
+ is_closing = 0;
+ return FALSE;
+ }
+ if ( !deleted && !isHidden() )
+ hide();
+ if ( checkLastWindowClosed
+ && tqApp->tqreceivers(TQT_SIGNAL(lastWindowClosed())) ) {
+ /* if there is no non-withdrawn top level window left (except
+ the desktop, popups, or dialogs with parents), we emit the
+ lastWindowClosed signal */
+ TQWidgetList *list = tqApp->tqtopLevelWidgets();
+ TQWidget *widget = list->first();
+ while ( widget ) {
+ if ( !widget->isHidden()
+ && !widget->isDesktop()
+ && !widget->isPopup()
+ && (!widget->isDialog() || !widget->parentWidget()))
+ break;
+ widget = list->next();
+ }
+ delete list;
+ if ( widget == 0 )
+ emit tqApp->lastWindowClosed();
+ }
+ if ( isMain )
+ tqApp->quit();
+ if ( deleted )
+ return TRUE;
+ is_closing = 0;
+ if ( alsoDelete )
+ delete this;
+ else if ( testWFlags(WDestructiveClose) ) {
+ clearWFlags(WDestructiveClose);
+ deleteLater();
+ }
+ return TRUE;
+}
+
+
+/*!
+ \fn bool TQWidget::close()
+
+ Closes this widget. Returns TRUE if the widget was closed;
+ otherwise returns FALSE.
+
+ First it sends the widget a TQCloseEvent. The widget is \link
+ hide() hidden\endlink if it \link TQCloseEvent::accept()
+ accepts\endlink the close event. The default implementation of
+ TQWidget::closeEvent() accepts the close event.
+
+ The \l TQApplication::lastWindowClosed() signal is emitted when the
+ last visible top level widget is closed.
+
+*/
+
+/*!
+ \property TQWidget::visible
+ \brief whether the widget is visible
+
+ Calling show() sets the widget to visible status if all its tqparent
+ widgets up to the top-level widget are visible. If an ancestor is
+ not visible, the widget won't become visible until all its
+ ancestors are shown.
+
+ Calling hide() hides a widget explicitly. An explicitly hidden
+ widget will never become visible, even if all its ancestors become
+ visible, unless you show it.
+
+ A widget receives show and hide events when its visibility status
+ changes. Between a hide and a show event, there is no need to
+ waste CPU cycles preparing or displaying information to the user.
+ A video application, for example, might simply stop generating new
+ frames.
+
+ A widget that happens to be obscured by other windows on the
+ screen is considered to be visible. The same applies to iconified
+ top-level widgets and windows that exist on another virtual
+ desktop (on platforms that support this concept). A widget
+ receives spontaneous show and hide events when its mapping status
+ is changed by the window system, e.g. a spontaneous hide event
+ when the user minimizes the window, and a spontaneous show event
+ when the window is restored again.
+
+ \sa show(), hide(), isHidden(), isVisibleTo(), isMinimized(),
+ showEvent(), hideEvent()
+*/
+
+
+/*!
+ Returns TRUE if this widget would become visible if \a ancestor is
+ shown; otherwise returns FALSE.
+
+ The TRUE case occurs if neither the widget itself nor any tqparent
+ up to but excluding \a ancestor has been explicitly hidden.
+
+ This function will still return TRUE if the widget is obscured by
+ other windows on the screen, but could be physically visible if it
+ or they were to be moved.
+
+ isVisibleTo(0) is identical to isVisible().
+
+ \sa show() hide() isVisible()
+*/
+
+bool TQWidget::isVisibleTo(TQWidget* ancestor) const
+{
+ if ( !ancestor )
+ return isVisible();
+ const TQWidget * w = this;
+ while ( w
+ && w->isShown()
+ && !w->isTopLevel()
+ && w->parentWidget()
+ && w->parentWidget() != ancestor )
+ w = w->parentWidget();
+ return w->isShown();
+}
+
+
+/*!
+ \fn bool TQWidget::isVisibleToTLW() const
+ \obsolete
+
+ This function is deprecated. It is equivalent to isVisible()
+*/
+
+/*!
+ \property TQWidget::hidden
+ \brief whether the widget is explicitly hidden
+
+ If FALSE, the widget is visible or would become visible if all its
+ ancestors became visible.
+
+ \sa hide(), show(), isVisible(), isVisibleTo(), shown
+*/
+
+/*!
+ \property TQWidget::shown
+ \brief whether the widget is shown
+
+ If TRUE, the widget is visible or would become visible if all its
+ ancestors became visible.
+
+ \sa hide(), show(), isVisible(), isVisibleTo(), hidden
+*/
+
+/*!
+ \property TQWidget::visibleRect
+ \brief the visible rectangle
+
+ \obsolete
+
+ No longer necessary, you can simply call tqrepaint(). If you do not
+ need the rectangle for tqrepaint(), use clipRegion() instead.
+*/
+TQRect TQWidget::visibleRect() const
+{
+ TQRect r = rect();
+ const TQWidget * w = this;
+ int ox = 0;
+ int oy = 0;
+ while ( w
+ && w->isVisible()
+ && !w->isTopLevel()
+ && w->parentWidget() ) {
+ ox -= w->x();
+ oy -= w->y();
+ w = w->parentWidget();
+ r = r.intersect( TQRect( ox, oy, w->width(), w->height() ) );
+ }
+ if ( !w->isVisible() )
+ return TQRect();
+ return r;
+}
+
+/*!
+ Returns the unobscured region where paint events can occur.
+
+ For visible widgets, this is an approximation of the area not
+ covered by other widgets; otherwise, this is an empty region.
+
+ The tqrepaint() function calls this function if necessary, so in
+ general you do not need to call it.
+
+*/
+TQRegion TQWidget::clipRegion() const
+{
+ return visibleRect();
+}
+
+
+/*!
+ Adjusts the size of the widget to fit the contents.
+
+ Uses tqsizeHint() if valid (i.e if the size hint's width and height
+ are \>= 0), otherwise sets the size to the tqchildren rectangle (the
+ union of all child widget geometries).
+
+ \sa tqsizeHint(), tqchildrenRect()
+*/
+
+void TQWidget::adjustSize()
+{
+ TQApplication::sendPostedEvents( 0, TQEvent::ChildInserted );
+ TQApplication::sendPostedEvents( 0, TQEvent::LayoutHint );
+ if ( !testWState(WState_Polished) )
+ polish();
+ TQSize s = tqsizeHint();
+
+ if ( isTopLevel() ) {
+
+#if defined(TQ_WS_X11)
+ TQRect screen = TQApplication::desktop()->screenGeometry( x11Screen() );
+#else // all others
+ TQRect screen = TQApplication::desktop()->screenGeometry( pos() );
+#endif
+
+#ifndef TQT_NO_LAYOUT
+ if ( tqlayout() ) {
+ if ( tqlayout()->hasHeightForWidth() ) {
+ s = s.boundedTo( screen.size() );
+ s.setHeight( tqlayout()->totalHeightForWidth( s.width() ) );
+ }
+ } else
+#endif
+ {
+ if ( sizePolicy().hasHeightForWidth() ) {
+ s = s.boundedTo( screen.size() );
+ s.setHeight( heightForWidth( s.width() ) );
+ }
+ }
+ }
+ if ( s.isValid() ) {
+ resize( s );
+ return;
+ }
+ TQRect r = tqchildrenRect(); // get tqchildren rectangle
+ if ( r.isNull() ) // probably no widgets
+ return;
+ resize( r.width() + 2 * r.x(), r.height() + 2 * r.y() );
+}
+
+
+/*!
+ \property TQWidget::tqsizeHint
+ \brief the recommended size for the widget
+
+ If the value of this property is an invalid size, no size is
+ recommended.
+
+ The default implementation of tqsizeHint() returns an invalid size
+ if there is no tqlayout for this widget, and returns the tqlayout's
+ preferred size otherwise.
+
+ \sa TQSize::isValid(), tqminimumSizeHint(), sizePolicy(),
+ setMinimumSize(), updateGeometry()
+*/
+
+TQSize TQWidget::tqsizeHint() const
+{
+#ifndef TQT_NO_LAYOUT
+ if ( tqlayout() )
+ return tqlayout()->totalSizeHint();
+#endif
+ return TQSize( -1, -1 );
+}
+
+/*!
+ \property TQWidget::tqminimumSizeHint
+ \brief the recommended minimum size for the widget
+
+ If the value of this property is an invalid size, no minimum size
+ is recommended.
+
+ The default implementation of tqminimumSizeHint() returns an invalid
+ size if there is no tqlayout for this widget, and returns the
+ tqlayout's minimum size otherwise. Most built-in widgets reimplement
+ tqminimumSizeHint().
+
+ \l TQLayout will never resize a widget to a size smaller than
+ tqminimumSizeHint.
+
+ \sa TQSize::isValid(), resize(), setMinimumSize(), sizePolicy()
+*/
+TQSize TQWidget::tqminimumSizeHint() const
+{
+#ifndef TQT_NO_LAYOUT
+ if ( tqlayout() )
+ return tqlayout()->totalMinimumSize();
+#endif
+ return TQSize( -1, -1 );
+}
+
+
+/*!
+ \fn TQWidget *TQWidget::parentWidget( bool sameWindow ) const
+
+ Returns the tqparent of this widget, or 0 if it does not have any
+ tqparent widget. If \a sameWindow is TRUE and the widget is top
+ level returns 0; otherwise returns the widget's tqparent.
+*/
+
+/*!
+ \fn WFlags TQWidget::testWFlags( WFlags f ) const
+
+ Returns the bitwise AND of the widget flags and \a f.
+
+ Widget flags are a combination of \l{TQt::WidgetFlags}.
+
+ If you want to test for the presence of multiple flags (or
+ composite flags such as \c WStyle_Splash), test the
+ return value for equality against the argument. For example:
+
+ \code
+ int flags = WStyle_Tool | WStyle_NoBorder;
+ if ( testWFlags(flags) )
+ ... // WStyle_Tool or WStyle_NoBorder or both are set
+ if ( testWFlags(flags) == flags )
+ ... // both WStyle_Tool and WStyle_NoBorder are set
+ \endcode
+
+ \sa getWFlags(), setWFlags(), clearWFlags()
+*/
+
+/*!
+ \fn WState TQWidget::testWState( WState s ) const
+ \internal
+
+ Returns the bitwise AND of the widget states and \a s.
+*/
+
+/*!
+ \fn uint TQWidget::getWState() const
+
+ \internal
+
+ Returns the current widget state.
+*/
+/*!
+ \fn void TQWidget::clearWState( uint n )
+
+ \internal
+
+ Clears the widgets states \a n.
+*/
+/*!
+ \fn void TQWidget::setWState( uint n )
+
+ \internal
+
+ Sets the widgets states \a n.
+*/
+
+
+
+/*****************************************************************************
+ TQWidget event handling
+ *****************************************************************************/
+
+/*!
+ This is the main event handler; it handles event \a e. You can
+ reimplement this function in a subclass, but we recommend using
+ one of the specialized event handlers instead.
+
+ The main event handler first passes an event through all \link
+ TQObject::installEventFilter() event filters\endlink that have been
+ installed. If none of the filters intercept the event, it calls
+ one of the specialized event handlers.
+
+ Key press and release events are treated differently from other
+ events. event() checks for Tab and Shift+Tab and tries to move the
+ focus appropriately. If there is no widget to move the focus to
+ (or the key press is not Tab or Shift+Tab), event() calls
+ keyPressEvent().
+
+ This function returns TRUE if it is able to pass the event over to
+ someone (i.e. someone wanted the event); otherwise returns FALSE.
+
+ \sa closeEvent(), focusInEvent(), focusOutEvent(), enterEvent(),
+ keyPressEvent(), keyReleaseEvent(), leaveEvent(),
+ mouseDoubleClickEvent(), mouseMoveEvent(), mousePressEvent(),
+ mouseReleaseEvent(), moveEvent(), paintEvent(), resizeEvent(),
+ TQObject::event(), TQObject::timerEvent()
+*/
+
+bool TQWidget::event( TQEvent *e )
+{
+ if ( TQObject::event( e ) )
+ return TRUE;
+
+ switch ( e->type() ) {
+ case TQEvent::MouseMove:
+ mouseMoveEvent( (TQMouseEvent*)e );
+ if ( ! ((TQMouseEvent*)e)->isAccepted() )
+ return FALSE;
+ break;
+
+ case TQEvent::MouseButtonPress:
+ resetInputContext();
+ mousePressEvent( (TQMouseEvent*)e );
+ if ( ! ((TQMouseEvent*)e)->isAccepted() )
+ return FALSE;
+ break;
+
+ case TQEvent::MouseButtonRelease:
+ mouseReleaseEvent( (TQMouseEvent*)e );
+ if ( ! ((TQMouseEvent*)e)->isAccepted() )
+ return FALSE;
+ break;
+
+ case TQEvent::MouseButtonDblClick:
+ mouseDoubleClickEvent( (TQMouseEvent*)e );
+ if ( ! ((TQMouseEvent*)e)->isAccepted() )
+ return FALSE;
+ break;
+#ifndef TQT_NO_WHEELEVENT
+ case TQEvent::Wheel:
+ wheelEvent( (TQWheelEvent*)e );
+ if ( ! ((TQWheelEvent*)e)->isAccepted() )
+ return FALSE;
+ break;
+#endif
+ case TQEvent::TabletMove:
+ case TQEvent::TabletPress:
+ case TQEvent::TabletRelease:
+ tabletEvent( (TQTabletEvent*)e );
+ if ( ! ((TQTabletEvent*)e)->isAccepted() )
+ return FALSE;
+ break;
+ case TQEvent::Accel:
+ ((TQKeyEvent*)e)->ignore();
+ return FALSE;
+ case TQEvent::KeyPress: {
+ TQKeyEvent *k = (TQKeyEvent *)e;
+ bool res = FALSE;
+ if ( !(k->state() & ControlButton || k->state() & AltButton) ) {
+ if ( k->key() == Key_Backtab ||
+ (k->key() == Key_Tab &&
+ (k->state() & ShiftButton)) ) {
+ TQFocusEvent::setReason( TQFocusEvent::Backtab );
+ res = focusNextPrevChild( FALSE );
+ TQFocusEvent::resetReason();
+
+ } else if ( k->key() == Key_Tab ) {
+ TQFocusEvent::setReason( TQFocusEvent::Tab );
+ res = focusNextPrevChild( TRUE );
+ TQFocusEvent::resetReason();
+ }
+ if ( res )
+ break;
+ }
+ keyPressEvent( k );
+ if ( !k->isAccepted() )
+ return FALSE;
+ }
+ break;
+
+ case TQEvent::KeyRelease:
+ keyReleaseEvent( (TQKeyEvent*)e );
+ if ( ! ((TQKeyEvent*)e)->isAccepted() )
+ return FALSE;
+ break;
+
+ case TQEvent::IMStart: {
+ TQIMEvent *i = (TQIMEvent *) e;
+ imStartEvent(i);
+ if (! i->isAccepted())
+ return FALSE;
+ }
+ break;
+
+ case TQEvent::IMCompose: {
+ TQIMEvent *i = (TQIMEvent *) e;
+ imComposeEvent(i);
+ if (! i->isAccepted())
+ return FALSE;
+ }
+ break;
+
+ case TQEvent::IMEnd: {
+ TQIMEvent *i = (TQIMEvent *) e;
+ imEndEvent(i);
+ if (! i->isAccepted())
+ return FALSE;
+ }
+ break;
+
+ case TQEvent::FocusIn:
+ focusInEvent( (TQFocusEvent*)e );
+ setFontSys();
+ break;
+
+ case TQEvent::FocusOut:
+ focusOutEvent( (TQFocusEvent*)e );
+ break;
+
+ case TQEvent::Enter:
+ enterEvent( e );
+ break;
+
+ case TQEvent::Leave:
+ leaveEvent( e );
+ break;
+
+ case TQEvent::Paint:
+ // At this point the event has to be delivered, regardless
+ // whether the widget isVisible() or not because it
+ // already went through the filters
+ paintEvent( (TQPaintEvent*)e );
+ break;
+
+ case TQEvent::Move:
+ moveEvent( (TQMoveEvent*)e );
+ break;
+
+ case TQEvent::Resize:
+ resizeEvent( (TQResizeEvent*)e );
+ break;
+
+ case TQEvent::Close: {
+ TQCloseEvent *c = (TQCloseEvent *)e;
+ closeEvent( c );
+ if ( !c->isAccepted() )
+ return FALSE;
+ }
+ break;
+
+ case TQEvent::ContextMenu: {
+ TQContextMenuEvent *c = (TQContextMenuEvent *)e;
+ contextMenuEvent( c );
+ if ( !c->isAccepted() )
+ return FALSE;
+ }
+ break;
+
+#ifndef TQT_NO_DRAGANDDROP
+ case TQEvent::Drop:
+ dropEvent( (TQDropEvent*) e);
+ break;
+
+ case TQEvent::DragEnter:
+ dragEnterEvent( (TQDragEnterEvent*) e);
+ break;
+
+ case TQEvent::DragMove:
+ dragMoveEvent( (TQDragMoveEvent*) e);
+ break;
+
+ case TQEvent::DragLeave:
+ dragLeaveEvent( (TQDragLeaveEvent*) e);
+ break;
+#endif
+
+ case TQEvent::Show:
+ showEvent( (TQShowEvent*) e);
+ break;
+
+ case TQEvent::Hide:
+ hideEvent( (TQHideEvent*) e);
+ break;
+
+ case TQEvent::ShowWindowRequest:
+ if ( isShown() )
+ showWindow();
+ break;
+
+ case TQEvent::ParentFontChange:
+ if ( isTopLevel() )
+ break;
+ // fall through
+ case TQEvent::ApplicationFontChange:
+ if ( own_font )
+ setFont( fnt.resolve( qt_naturalWidgetFont( this ) ) );
+ else
+ unsetFont();
+ break;
+
+#ifndef TQT_NO_PALETTE
+ case TQEvent::ParentPaletteChange:
+ if ( isTopLevel() )
+ break;
+ // fall through
+ case TQEvent::ApplicationPaletteChange:
+ if ( !own_palette && !isDesktop() )
+ unsetPalette();
+# if defined(TQ_WS_TQWS) && !defined (TQT_NO_TQWS_MANAGER)
+ if ( isTopLevel() && topData()->qwsManager ) {
+ TQRegion r( topData()->qwsManager->region() );
+ TQApplication::postEvent(topData()->qwsManager, new TQPaintEvent(r, FALSE) );
+ }
+# endif
+ break;
+#endif
+
+ case TQEvent::WindowActivate:
+ case TQEvent::WindowDeactivate:
+ windowActivationChange( e->type() != TQEvent::WindowActivate );
+ if ( childrenListObject() ) {
+ TQObjectListIt it( *childrenListObject() );
+ TQObject *o;
+ while( ( o = it.current() ) != 0 ) {
+ ++it;
+ if ( o->isWidgetType() &&
+ ((TQWidget*)o)->isVisible() &&
+ !((TQWidget*)o)->isTopLevel() )
+ TQApplication::sendEvent( o, e );
+ }
+ }
+ break;
+
+ case TQEvent::LanguageChange:
+ case TQEvent::LocaleChange:
+ if ( childrenListObject() ) {
+ TQObjectListIt it( *childrenListObject() );
+ TQObject *o;
+ while( ( o = it.current() ) != 0 ) {
+ ++it;
+ TQApplication::sendEvent( o, e );
+ }
+ }
+ if ( e->type() == TQEvent::LanguageChange ) {
+ int index = tqmetaObject()->tqfindSlot( "languageChange()", TRUE );
+ if ( index >= 0 )
+ qt_invoke( index, 0 );
+ }
+ update();
+ break;
+#ifndef TQT_NO_LAYOUT
+ case TQEvent::LayoutDirectionChange:
+ if ( tqlayout() ) {
+ tqlayout()->activate();
+ } else {
+ TQObjectList* llist = queryList( "TQLayout", 0, TRUE, TRUE );
+ TQObjectListIt lit( *llist );
+ TQLayout *lay;
+ while ( ( lay = (TQLayout*)lit.current() ) != 0 ) {
+ ++lit;
+ lay->activate();
+ }
+ delete llist;
+ }
+ update();
+ break;
+#endif
+
+ case TQEvent::WindowStateChange:
+ {
+ TQEvent::Type type;
+ if (isMinimized())
+ type = TQEvent::ShowMinimized;
+ else if (isFullScreen())
+ type = TQEvent::ShowFullScreen;
+ else if (isMaximized())
+ type = TQEvent::ShowMaximized;
+ else
+ type = TQEvent::ShowNormal;
+
+ TQApplication::postEvent(this, new TQEvent(type));
+ break;
+ }
+
+ case TQEvent::WindowBlocked:
+ case TQEvent::WindowUnblocked:
+ if ( childrenListObject() ) {
+ TQObjectListIt it( *childrenListObject() );
+ TQObject *o;
+ while( ( o = it.current() ) != 0 ) {
+ ++it;
+ TQWidget *w = ::tqqt_cast<TQWidget*>(o);
+ if (w && !w->testWFlags(TQt::WShowModal))
+ TQApplication::sendEvent( o, e );
+ }
+ }
+ break;
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse move events for the widget.
+
+ If mouse tracking is switched off, mouse move events only occur if
+ a mouse button is pressed while the mouse is being moved. If mouse
+ tracking is switched on, mouse move events occur even if no mouse
+ button is pressed.
+
+ TQMouseEvent::pos() reports the position of the mouse cursor,
+ relative to this widget. For press and release events, the
+ position is usually the same as the position of the last mouse
+ move event, but it might be different if the user's hand shakes.
+ This is a feature of the underlying window system, not TQt.
+
+ \sa setMouseTracking(), mousePressEvent(), mouseReleaseEvent(),
+ mouseDoubleClickEvent(), event(), TQMouseEvent
+*/
+
+void TQWidget::mouseMoveEvent( TQMouseEvent * e)
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse press events for the widget.
+
+ If you create new widgets in the mousePressEvent() the
+ mouseReleaseEvent() may not end up where you expect, depending on
+ the underlying window system (or X11 window manager), the widgets'
+ location and maybe more.
+
+ The default implementation implements the closing of popup widgets
+ when you click outside the window. For other widget types it does
+ nothing.
+
+ \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
+ mouseMoveEvent(), event(), TQMouseEvent
+*/
+
+void TQWidget::mousePressEvent( TQMouseEvent *e )
+{
+ e->ignore();
+ if ( isPopup() ) {
+ e->accept();
+ TQWidget* w;
+ while ( (w = tqApp->activePopupWidget() ) && w != this ){
+ w->close();
+ if (tqApp->activePopupWidget() == w) // widget does not want to dissappear
+ w->hide(); // hide at least
+ }
+ if (!rect().tqcontains(e->pos()) ){
+ close();
+ }
+ }
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse release events for the widget.
+
+ \sa mouseReleaseEvent(), mouseDoubleClickEvent(),
+ mouseMoveEvent(), event(), TQMouseEvent
+*/
+
+void TQWidget::mouseReleaseEvent( TQMouseEvent * e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive mouse double click events for the widget.
+
+ The default implementation generates a normal mouse press event.
+
+ Note that the widgets gets a mousePressEvent() and a
+ mouseReleaseEvent() before the mouseDoubleClickEvent().
+
+ \sa mousePressEvent(), mouseReleaseEvent() mouseMoveEvent(),
+ event(), TQMouseEvent
+*/
+
+void TQWidget::mouseDoubleClickEvent( TQMouseEvent *e )
+{
+ mousePressEvent( e ); // try mouse press event
+}
+
+#ifndef TQT_NO_WHEELEVENT
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive wheel events for the widget.
+
+ If you reimplement this handler, it is very important that you
+ \link TQWheelEvent ignore()\endlink the event if you do not handle
+ it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa TQWheelEvent::ignore(), TQWheelEvent::accept(), event(),
+ TQWheelEvent
+*/
+
+void TQWidget::wheelEvent( TQWheelEvent *e )
+{
+ e->ignore();
+}
+#endif
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive tablet events for the widget.
+
+ If you reimplement this handler, it is very important that you
+ \link TQTabletEvent ignore()\endlink the event if you do not handle
+ it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa TQTabletEvent::ignore(), TQTabletEvent::accept(), event(),
+ TQTabletEvent
+*/
+
+void TQWidget::tabletEvent( TQTabletEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive key press events for the widget.
+
+ A widget must call setFocusPolicy() to accept focus initially and
+ have focus in order to receive a key press event.
+
+ If you reimplement this handler, it is very important that you
+ explicitly \link TQKeyEvent::ignore() ignore\endlink the event
+ if you do not understand it, so that the widget's tqparent can
+ interpret it; otherwise, the event will be implicitly accepted.
+ Although top-level widgets are able to choose whether to accept
+ or ignore unknown events because they have no tqparent widgets that
+ could otherwise handle them, it is good practice to explicitly
+ ignore events to make widgets as reusable as possible.
+
+ The default implementation closes popup widgets if the user
+ presses <b>Esc</b>. Otherwise the event is ignored.
+
+ \sa keyReleaseEvent(), TQKeyEvent::ignore(), setFocusPolicy(),
+ focusInEvent(), focusOutEvent(), event(), TQKeyEvent
+*/
+
+void TQWidget::keyPressEvent( TQKeyEvent *e )
+{
+ if ( isPopup() && e->key() == Key_Escape ) {
+ e->accept();
+ close();
+ } else {
+ e->ignore();
+ }
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive key release events for the widget.
+
+ A widget must \link setFocusPolicy() accept focus\endlink
+ initially and \link hasFocus() have focus\endlink in order to
+ receive a key release event.
+
+ If you reimplement this handler, it is very important that you
+ \link TQKeyEvent ignore()\endlink the release if you do not
+ understand it, so that the widget's tqparent can interpret it.
+
+ The default implementation ignores the event.
+
+ \sa keyPressEvent(), TQKeyEvent::ignore(), setFocusPolicy(),
+ focusInEvent(), focusOutEvent(), event(), TQKeyEvent
+*/
+
+void TQWidget::keyReleaseEvent( TQKeyEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ keyboard focus events (focus received) for the widget.
+
+ A widget normally must setFocusPolicy() to something other than
+ \c NoFocus in order to receive focus events. (Note that the
+ application programmer can call setFocus() on any widget, even
+ those that do not normally accept focus.)
+
+ The default implementation updates the widget (except for toplevel
+ widgets that do not specify a focusPolicy() ). It also calls
+ setMicroFocusHint(), hinting any system-specific input tools about
+ the focus of the user's attention.
+
+ \sa focusOutEvent(), setFocusPolicy(), keyPressEvent(),
+ keyReleaseEvent(), event(), TQFocusEvent
+*/
+
+void TQWidget::focusInEvent( TQFocusEvent * )
+{
+ if ( focusPolicy() != NoFocus || !isTopLevel() ) {
+ update();
+ if ( testWState(WState_AutoMask) )
+ updateMask();
+ setMicroFocusHint(width()/2, 0, 1, height(), FALSE);
+ }
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ keyboard focus events (focus lost) for the widget.
+
+ A widget normally must setFocusPolicy() to something other than
+ \c NoFocus in order to receive focus events. (Note that the
+ application programmer can call setFocus() on any widget, even
+ those that do not normally accept focus.)
+
+ The default implementation updates the widget (except for toplevel
+ widgets that do not specify a focusPolicy() ). It also calls
+ setMicroFocusHint(), hinting any system-specific input tools about
+ the focus of the user's attention.
+
+ \sa focusInEvent(), setFocusPolicy(), keyPressEvent(),
+ keyReleaseEvent(), event(), TQFocusEvent
+*/
+
+void TQWidget::focusOutEvent( TQFocusEvent * )
+{
+ if ( focusPolicy() != NoFocus || !isTopLevel() ){
+ update();
+ if ( testWState(WState_AutoMask) )
+ updateMask();
+ }
+}
+
+/*!
+ \property TQWidget::microFocusHint
+ \brief the currently set micro focus hint for this widget.
+
+ See the documentation of setMicroFocusHint() for more information.
+*/
+TQRect TQWidget::microFocusHint() const
+{
+ if ( !extra )
+ return TQRect(width()/2, 0, 1, height() );
+ else if ( extra->micro_focus_hint.isEmpty() )
+ return TQRect(width()/2, 0, 1, height() );
+ else
+ return extra->micro_focus_hint;
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget enter events.
+
+ An event is sent to the widget when the mouse cursor enters the
+ widget.
+
+ \sa leaveEvent(), mouseMoveEvent(), event()
+*/
+
+void TQWidget::enterEvent( TQEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget leave events.
+
+ A leave event is sent to the widget when the mouse cursor leaves
+ the widget.
+
+ \sa enterEvent(), mouseMoveEvent(), event()
+*/
+
+void TQWidget::leaveEvent( TQEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ paint events.
+
+ A paint event is a request to tqrepaint all or part of the widget.
+ It can happen as a result of tqrepaint() or update(), or because the
+ widget was obscured and has now been uncovered, or for many other
+ reasons.
+
+ Many widgets can simply tqrepaint their entire surface when asked
+ to, but some slow widgets need to optimize by painting only the
+ requested region: TQPaintEvent::region(). This speed optimization
+ does not change the result, as painting is clipped to that region
+ during event processing. TQListView and TQCanvas do this, for
+ example.
+
+ TQt also tries to speed up painting by merging multiple paint
+ events into one. When update() is called several times or the
+ window system sends several paint events, TQt merges these events
+ into one event with a larger region (see TQRegion::unite()).
+ tqrepaint() does not permit this optimization, so we suggest using
+ update() when possible.
+
+ When the paint event occurs, the update region has normally been
+ erased, so that you're painting on the widget's background. There
+ are a couple of exceptions and TQPaintEvent::erased() tells you
+ whether the widget has been erased or not.
+
+ The background can be set using setBackgroundMode(),
+ setPaletteBackgroundColor() or setBackgroundPixmap(). The
+ documentation for setBackgroundMode() elaborates on the
+ background; we recommend reading it.
+
+ \sa event(), tqrepaint(), update(), TQPainter, TQPixmap, TQPaintEvent
+*/
+
+void TQWidget::paintEvent( TQPaintEvent * )
+{
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget move events. When the widget receives this event, it is
+ already at the new position.
+
+ The old position is accessible through TQMoveEvent::oldPos().
+
+ \sa resizeEvent(), event(), move(), TQMoveEvent
+*/
+
+void TQWidget::moveEvent( TQMoveEvent * )
+{
+}
+
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget resize events. When resizeEvent() is called, the widget
+ already has its new tqgeometry. The old size is accessible through
+ TQResizeEvent::oldSize().
+
+ The widget will be erased and receive a paint event immediately
+ after processing the resize event. No drawing need be (or should
+ be) done inside this handler.
+
+ Widgets that have been created with the \c WNoAutoErase flag
+ will not be erased. Nevertheless, they will receive a paint event
+ for their entire area afterwards. Again, no drawing needs to be
+ done inside this handler.
+
+ The default implementation calls updateMask() if the widget has
+ \link TQWidget::setAutoMask() automatic masking\endlink enabled.
+
+ \sa moveEvent(), event(), resize(), TQResizeEvent, paintEvent()
+*/
+
+void TQWidget::resizeEvent( TQResizeEvent * )
+{
+ if ( testWState(WState_AutoMask) )
+ updateMask();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive widget close events.
+
+ The default implementation calls e->accept(), which hides this
+ widget. See the \l TQCloseEvent documentation for more details.
+
+ \sa event(), hide(), close(), TQCloseEvent
+*/
+
+void TQWidget::closeEvent( TQCloseEvent *e )
+{
+ e->accept();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive widget context menu events.
+
+ The default implementation calls e->ignore(), which rejects the
+ context event. See the \l TQContextMenuEvent documentation for
+ more details.
+
+ \sa event(), TQContextMenuEvent
+*/
+
+void TQWidget::contextMenuEvent( TQContextMenuEvent *e )
+{
+ e->ignore();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user begins entering text using an Input Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQWidget::imStartEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user has entered some text using an Input Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQWidget::imComposeEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+
+/*!
+ This event handler, for event \a e, can be reimplemented in a
+ subclass to receive Input Method composition events. This handler
+ is called when the user has finished inputting text via an Input
+ Method.
+
+ The default implementation calls e->ignore(), which rejects the
+ Input Method event. See the \l TQIMEvent documentation for more
+ details.
+
+ \sa event(), TQIMEvent
+*/
+void TQWidget::imEndEvent( TQIMEvent *e )
+{
+ e->ignore();
+}
+
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse enters this widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragEnterEvent
+*/
+void TQWidget::dragEnterEvent( TQDragEnterEvent * )
+{
+}
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse enters this widget, and whenever it moves within the widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragMoveEvent
+*/
+void TQWidget::dragMoveEvent( TQDragMoveEvent * )
+{
+}
+
+/*!
+ This event handler is called when a drag is in progress and the
+ mouse leaves this widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDragLeaveEvent
+*/
+void TQWidget::dragLeaveEvent( TQDragLeaveEvent * )
+{
+}
+
+/*!
+ This event handler is called when the drag is dropped on this
+ widget.
+
+ See the \link dnd.html Drag-and-drop documentation\endlink for an
+ overview of how to provide drag-and-drop in your application.
+
+ \sa TQTextDrag, TQImageDrag, TQDropEvent
+*/
+void TQWidget::dropEvent( TQDropEvent * )
+{
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget show events.
+
+ Non-spontaneous show events are sent to widgets immediately before
+ they are shown. The spontaneous show events of top-level widgets
+ are delivered afterwards.
+
+ \sa event(), TQShowEvent
+*/
+void TQWidget::showEvent( TQShowEvent * )
+{
+}
+
+/*!
+ This event handler can be reimplemented in a subclass to receive
+ widget hide events.
+
+ Hide events are sent to widgets immediately after they have been
+ hidden.
+
+ \sa event(), TQHideEvent
+*/
+void TQWidget::hideEvent( TQHideEvent * )
+{
+}
+
+/*
+ \fn TQWidget::x11Event( MSG * )
+
+ This special event handler can be reimplemented in a subclass to
+ receive native X11 events.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by TQt, return TRUE. If you return FALSE, this
+ native event is passed back to TQt, which translates the event into
+ a TQt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa TQApplication::x11EventFilter()
+*/
+
+
+#if defined(TQ_WS_MAC)
+
+/*!
+ This special event handler can be reimplemented in a subclass to
+ receive native Macintosh events.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by TQt, return TRUE. If you return FALSE, this
+ native event is passed back to TQt, which translates the event into
+ a TQt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa TQApplication::macEventFilter()
+*/
+
+bool TQWidget::macEvent( MSG * )
+{
+ return FALSE;
+}
+
+#endif
+#if defined(TQ_WS_WIN)
+
+/*!
+ This special event handler can be reimplemented in a subclass to
+ receive native Windows events.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by TQt, return TRUE. If you return FALSE, this
+ native event is passed back to TQt, which translates the event into
+ a TQt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa TQApplication::winEventFilter()
+*/
+bool TQWidget::winEvent( MSG * )
+{
+ return FALSE;
+}
+
+#endif
+#if defined(TQ_WS_X11)
+
+/*!
+ This special event handler can be reimplemented in a subclass to
+ receive native X11 events.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by TQt, return TRUE. If you return FALSE, this
+ native event is passed back to TQt, which translates the event into
+ a TQt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa TQApplication::x11EventFilter()
+*/
+bool TQWidget::x11Event( XEvent * )
+{
+ return FALSE;
+}
+
+#endif
+#if defined(TQ_WS_TQWS)
+
+/*!
+ This special event handler can be reimplemented in a subclass to
+ receive native TQt/Embedded events.
+
+ In your reimplementation of this function, if you want to stop the
+ event being handled by TQt, return TRUE. If you return FALSE, this
+ native event is passed back to TQt, which translates the event into
+ a TQt event and sends it to the widget.
+
+ \warning This function is not portable.
+
+ \sa TQApplication::qwsEventFilter()
+*/
+bool TQWidget::qwsEvent( TQWSEvent * )
+{
+ return FALSE;
+}
+
+#endif
+
+/*!
+ \property TQWidget::autoMask
+ \brief whether the auto tqmask feature is enabled for the widget
+
+ Transtqparent widgets use a tqmask to define their visible region.
+ TQWidget has some built-in support to make the task of
+ recalculating the tqmask easier. When setting auto tqmask to TRUE,
+ updateMask() will be called whenever the widget is resized or
+ changes its focus state. Note that you must reimplement
+ updateMask() (which should include a call to setMask()) or nothing
+ will happen.
+
+ Note: when you re-implement resizeEvent(), focusInEvent() or
+ focusOutEvent() in your custom widgets and still want to ensure
+ that the auto tqmask calculation works, you should add:
+
+ \code
+ if ( autoMask() )
+ updateMask();
+ \endcode
+
+ at the end of your event handlers. This is true for all member
+ functions that change the appearance of the widget in a way that
+ requires a recalculation of the tqmask.
+
+ While being a technically appealing concept, masks have a big
+ drawback: when using complex masks that cannot be expressed easily
+ with relatively simple regions, they can be very slow on some
+ window systems. The classic example is a transtqparent label. The
+ complex tqshape of its contents makes it necessary to represent its
+ tqmask by a bitmap, which consumes both memory and time. If all you
+ want is to blend the background of several neighboring widgets
+ together seamlessly, you will probably want to use
+ setBackgroundOrigin() rather than a tqmask.
+
+ \sa autoMask() updateMask() setMask() clearMask() setBackgroundOrigin()
+*/
+
+bool TQWidget::autoMask() const
+{
+ return testWState(WState_AutoMask);
+}
+
+void TQWidget::setAutoMask( bool enable )
+{
+ if ( enable == autoMask() )
+ return;
+
+ if ( enable ) {
+ setWState(WState_AutoMask);
+ updateMask();
+ } else {
+ clearWState(WState_AutoMask);
+ clearMask();
+ }
+}
+
+/*!
+ \enum TQWidget::BackgroundOrigin
+
+ This enum defines the origin used to draw a widget's background
+ pixmap.
+
+ The pixmap is drawn using the:
+ \value WidgetOrigin widget's coordinate system.
+ \value ParentOrigin tqparent's coordinate system.
+ \value WindowOrigin top-level window's coordinate system.
+ \value AncestorOrigin same origin as the tqparent uses.
+*/
+
+/*!
+ \property TQWidget::backgroundOrigin
+ \brief the origin of the widget's background
+
+ The origin is either WidgetOrigin (the default), ParentOrigin,
+ WindowOrigin or AncestorOrigin.
+
+ This only makes a difference if the widget has a background
+ pixmap, in which case positioning matters. Using \c WindowOrigin
+ for several neighboring widgets makes the background blend
+ together seamlessly. \c AncestorOrigin allows blending backgrounds
+ seamlessly when an ancestor of the widget has an origin other than
+ \c WindowOrigin.
+
+ \sa backgroundPixmap(), setBackgroundMode()
+*/
+TQWidget::BackgroundOrigin TQWidget::backgroundOrigin() const
+{
+ return extra ? (BackgroundOrigin)extra->bg_origin : WidgetOrigin;
+}
+
+void TQWidget::setBackgroundOrigin( BackgroundOrigin origin )
+{
+ if ( origin == backgroundOrigin() )
+ return;
+ createExtra();
+ extra->bg_origin = origin;
+ update();
+}
+
+/*!
+ This function can be reimplemented in a subclass to support
+ transtqparent widgets. It should be called whenever a widget changes
+ state in a way that means that the tqshape tqmask must be recalculated.
+
+ \sa setAutoMask(), updateMask(), setMask(), clearMask()
+*/
+void TQWidget::updateMask()
+{
+}
+
+/*!
+ \internal
+ Returns the offset of the widget from the backgroundOrigin.
+
+ \sa setBackgroundMode(), backgroundMode(),
+*/
+TQPoint TQWidget::backgroundOffset() const
+{
+ if (!isTopLevel()) {
+ switch(backgroundOrigin()) {
+ case WidgetOrigin:
+ break;
+ case ParentOrigin:
+ return pos();
+ case WindowOrigin:
+ {
+ const TQWidget *topl = this;
+ while(topl && !topl->isTopLevel() && !topl->testWFlags(TQt::WSubWindow))
+ topl = topl->parentWidget(TRUE);
+ return mapTo((TQWidget *)topl, TQPoint(0, 0) );
+ }
+ case AncestorOrigin:
+ {
+ const TQWidget *topl = this;
+ bool ancestorIsWindowOrigin = FALSE;
+ while(topl && !topl->isTopLevel() && !topl->testWFlags(TQt::WSubWindow))
+ {
+ if (!ancestorIsWindowOrigin) {
+ if (topl->backgroundOrigin() == TQWidget::WidgetOrigin)
+ break;
+ if (topl->backgroundOrigin() == TQWidget::ParentOrigin)
+ {
+ topl = topl->parentWidget(TRUE);
+ break;
+ }
+ if (topl->backgroundOrigin() == TQWidget::WindowOrigin)
+ ancestorIsWindowOrigin = TRUE;
+ }
+ topl = topl->parentWidget(TRUE);
+ }
+
+ return mapTo((TQWidget *) topl, TQPoint(0,0) );
+ }
+ }
+ }
+ // fall back
+ return TQPoint(0,0);
+}
+
+/*!
+ \fn TQLayout* TQWidget::tqlayout () const
+
+ Returns the tqlayout engine that manages the tqgeometry of this
+ widget's tqchildren.
+
+ If the widget does not have a tqlayout, tqlayout() returns 0.
+
+ \sa sizePolicy()
+*/
+
+
+/* Sets this widget to use tqlayout \a l to manage the tqgeometry of its
+ tqchildren.
+
+ If the widget already had a tqlayout, the old tqlayout is
+ forgotten. (Note that it is not deleted.)
+
+ \sa tqlayout() TQLayout sizePolicy()
+*/
+#ifndef TQT_NO_LAYOUT
+void TQWidget::setLayout( TQLayout *l )
+{
+ lay_out = l;
+}
+#endif
+
+/*!
+ \property TQWidget::sizePolicy
+ \brief the default tqlayout behavior of the widget
+
+ If there is a TQLayout that manages this widget's tqchildren, the
+ size policy specified by that tqlayout is used. If there is no such
+ TQLayout, the result of this function is used.
+
+ The default policy is Preferred/Preferred, which means that the
+ widget can be freely resized, but prefers to be the size
+ tqsizeHint() returns. Button-like widgets set the size policy to
+ specify that they may stretch horizontally, but are fixed
+ vertically. The same applies to lineedit controls (such as
+ TQLineEdit, TQSpinBox or an editable TQComboBox) and other
+ horizontally orientated widgets (such as TQProgressBar).
+ TQToolButton's are normally square, so they allow growth in both
+ directions. Widgets that support different directions (such as
+ TQSlider, TQScrollBar or TQHeader) specify stretching in the
+ respective direction only. Widgets that can provide scrollbars
+ (usually subclasses of TQScrollView) tend to specify that they can
+ use additional space, and that they can make do with less than
+ tqsizeHint().
+
+ \sa tqsizeHint() TQLayout TQSizePolicy updateGeometry()
+*/
+TQSizePolicy TQWidget::sizePolicy() const
+{
+ return extra ? extra->size_policy
+ : TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred );
+}
+
+void TQWidget::tqsetSizePolicy( TQSizePolicy policy )
+{
+ setWState( WState_OwnSizePolicy );
+ if ( policy == sizePolicy() )
+ return;
+ createExtra();
+ extra->size_policy = policy;
+ updateGeometry();
+}
+
+/*!
+ \overload void TQWidget::tqsetSizePolicy( TQSizePolicy::SizeType hor, TQSizePolicy::SizeType ver, bool hfw )
+
+ Sets the size policy of the widget to \a hor, \a ver and \a hfw
+ (height for width).
+
+ \sa TQSizePolicy::TQSizePolicy()
+*/
+
+/*!
+ Returns the preferred height for this widget, given the width \a
+ w. The default implementation returns 0, indicating that the
+ preferred height does not depend on the width.
+
+ \warning Does not look at the widget's tqlayout.
+*/
+
+int TQWidget::heightForWidth( int w ) const
+{
+ (void)w;
+ return 0;
+}
+
+/*!
+ \property TQWidget::customWhatsThis
+ \brief whether the widget wants to handle What's This help manually
+
+ The default implementation of customWhatsThis() returns FALSE,
+ which means the widget will not receive any events in Whats This
+ mode.
+
+ The widget may leave What's This mode by calling
+ TQWhatsThis::leaveWhatsThisMode(), with or without actually
+ displaying any help text.
+
+ You can also reimplement customWhatsThis() if your widget is a
+ "passive interactor" supposed to work under all circumstances.
+ Simply don't call TQWhatsThis::leaveWhatsThisMode() in that case.
+
+ \sa TQWhatsThis::inWhatsThisMode() TQWhatsThis::leaveWhatsThisMode()
+*/
+bool TQWidget::customWhatsThis() const
+{
+ return FALSE;
+}
+
+/*!
+ Returns the visible child widget at pixel position \a (x, y) in
+ the widget's own coordinate system.
+
+ If \a includeThis is TRUE, and there is no child visible at \a (x,
+ y), the widget itself is returned.
+*/
+TQWidget *TQWidget::tqchildAt( int x, int y, bool includeThis ) const
+{
+ if ( !rect().tqcontains( x, y ) )
+ return 0;
+ if ( childrenListObject() ) {
+ TQObjectListIt it( *childrenListObject() );
+ it.toLast();
+ TQWidget *w, *t;
+ while( (w=(TQWidget *)it.current()) != 0 ) {
+ --it;
+ if ( w->isWidgetType() && !w->isTopLevel() && !w->isHidden() ) {
+ if ( ( t = w->tqchildAt( x - w->x(), y - w->y(), TRUE ) ) )
+ return t;
+ }
+ }
+ }
+ if ( includeThis )
+ return (TQWidget*)this;
+ return 0;
+}
+
+/*!
+ \overload
+
+ Returns the visible child widget at point \a p in the widget's own
+ coordinate system.
+
+ If \a includeThis is TRUE, and there is no child visible at \a p,
+ the widget itself is returned.
+
+*/
+TQWidget *TQWidget::tqchildAt( const TQPoint & p, bool includeThis ) const
+{
+ return tqchildAt( p.x(), p.y(), includeThis );
+}
+
+
+/*!
+ Notifies the tqlayout system that this widget has changed and may
+ need to change tqgeometry.
+
+ Call this function if the tqsizeHint() or sizePolicy() have changed.
+
+ For explicitly hidden widgets, updateGeometry() is a no-op. The
+ tqlayout system will be notified as soon as the widget is shown.
+*/
+
+void TQWidget::updateGeometry()
+{
+ if ( !isTopLevel() && isShown() )
+ TQApplication::postEvent( parentWidget(),
+ new TQEvent( TQEvent::LayoutHint ) );
+}
+
+
+/*!
+ Reparents the widget. The widget gets a new \a tqparent, new widget
+ flags (\a f, but as usual, use 0) at a new position in its new
+ tqparent (\a p).
+
+ If \a showIt is TRUE, show() is called once the widget has been
+ reparented.
+
+ If the new tqparent widget is in a different top-level widget, the
+ reparented widget and its tqchildren are appended to the end of the
+ \link setFocusPolicy() tab chain \endlink of the new tqparent
+ widget, in the same internal order as before. If one of the moved
+ widgets had keyboard focus, reparent() calls clearFocus() for that
+ widget.
+
+ If the new tqparent widget is in the same top-level widget as the
+ old tqparent, reparent doesn't change the tab order or keyboard
+ focus.
+
+ \warning It is extremely unlikely that you will ever need this
+ function. If you have a widget that changes its content
+ dynamically, it is far easier to use \l TQWidgetStack or \l
+ TQWizard.
+
+ \sa getWFlags()
+*/
+
+void TQWidget::reparent( TQWidget *tqparent, WFlags f, const TQPoint &p,
+ bool showIt )
+{
+ reparentSys( tqparent, f, p, showIt );
+ TQEvent e( TQEvent::Retqparent );
+ TQApplication::sendEvent( this, &e );
+ if (!own_font)
+ unsetFont();
+ else
+ setFont( fnt.resolve( qt_naturalWidgetFont( this ) ) );
+#ifndef TQT_NO_PALETTE
+ if (!own_palette)
+ unsetPalette();
+#endif
+}
+
+/*!
+ \overload
+
+ A convenience version of reparent that does not take widget flags
+ as argument.
+
+ Calls reparent(\a tqparent, getWFlags() \& ~\l WType_Mask, \a p, \a
+ showIt).
+*/
+void TQWidget::reparent( TQWidget *tqparent, const TQPoint & p,
+ bool showIt )
+{
+ reparent( tqparent, getWFlags() & ~WType_Mask, p, showIt );
+}
+
+/*!
+ \property TQWidget::ownCursor
+ \brief whether the widget uses its own cursor
+
+ If FALSE, the widget uses its tqparent widget's cursor.
+
+ \sa cursor
+*/
+
+/*!
+ \property TQWidget::ownFont
+ \brief whether the widget uses its own font
+
+ If FALSE, the widget uses its tqparent widget's font.
+
+ \sa font
+*/
+
+/*!
+ \property TQWidget::ownPalette
+ \brief whether the widget uses its own palette
+
+ If FALSE, the widget uses its tqparent widget's palette.
+
+ \sa palette
+*/
+
+
+void TQWidget::tqrepaint( bool erase )
+{
+ tqrepaint( visibleRect(), erase );
+}
+
+
+
+
+/*!\obsolete Use paletteBackgroundColor() or eraseColor() instead. */
+const TQColor & TQWidget::backgroundColor() const { return eraseColor(); }
+/*!\obsolete Use setPaletteBackgroundColor() or setEraseColor() instead. */
+void TQWidget::setBackgroundColor( const TQColor &c ) { setEraseColor( c ); }
+/*!\obsolete Use paletteBackgroundPixmap() or erasePixmap() instead. */
+const TQPixmap *TQWidget::backgroundPixmap() const { return erasePixmap(); }
+/*!\obsolete Use setPaletteBackgroundPixmap() or setErasePixmap() instead. */
+void TQWidget::setBackgroundPixmap( const TQPixmap &pm ) { setErasePixmap( pm ); }
+
+
+// documentation in qdesktopwidget_win.cpp
+void TQDesktopWidget::insertChild( TQObject *obj )
+{
+ if ( obj->isWidgetType() )
+ return;
+ TQWidget::insertChild( obj );
+}
+
+/*!
+ \property TQWidget::windowOpacity
+
+ \brief The level of opacity for the window.
+
+ The valid range of opacity is from 1.0 (completely opaque) to
+ 0.0 (completely transtqparent).
+
+ By default the value of this property is 1.0.
+
+ This feature is only present on Mac OS X and Windows 2000 and up.
+
+ \warning Changing this property from opaque to transtqparent might issue a
+ paint event that needs to be processed before the window is displayed
+ correctly. This affects mainly the use of TQPixmap::grabWindow(). Also note
+ that semi-transtqparent windows update and resize significantely slower than
+ opaque windows.
+*/
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqwidget.h b/tqtinterface/qt4/src/kernel/tqwidget.h
new file mode 100644
index 0000000..c027464
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwidget.h
@@ -0,0 +1,1547 @@
+/****************************************************************************
+**
+** Definition of TQWidget class
+**
+** Created : 931029
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWIDGET_H
+#define TQWIDGET_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqobject.h"
+#include "tqpaintdevice.h"
+#include "tqpalette.h"
+#include "tqfont.h"
+#include "tqfontmetrics.h"
+#include "tqfontinfo.h"
+#include "tqsizepolicy.h"
+#include "tqbitmap.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+#ifndef TQFONTENGINE_P_H
+
+#include <Qt/qwidget.h>
+#include <private/qt4_qwidget_p.h>
+
+#endif // TQFONTENGINE_P_H
+#endif // USE_QT4
+
+class TQLayout;
+
+#ifdef USE_QT4
+
+// FIXME
+// Neither TQTLWExtra nor TQWExtra are fully Qt4 compatible!
+
+class TQFocusData;
+
+// typedef struct QTLWExtra TQTLWExtra;
+
+struct TQTLWExtra : public QTLWExtra, virtual public TQt
+{
+ TQFocusData *focusData; // focus data (for TLW)
+ ulong fleft, fright, ftop, fbottom;
+ uint uspos : 1; // User defined position
+ uint ussize : 1; // User defined size
+
+#if defined(TQ_WS_X11)
+ WId parentWinId; // tqparent window Id (valid after reparenting)
+#endif
+};
+
+// typedef struct QWExtra TQWExtra;
+
+struct TQWExtra : public QWExtra, virtual public TQt
+{
+ TQRect micro_focus_hint; // micro focus hint
+ TQPixmap *bg_pix; // background pixmap
+ char bg_mode; // background mode
+ char bg_mode_visual; // visual background mode
+ uint bg_origin : 2;
+ TQSizePolicy size_policy;
+ TQTLWExtra *topextra; // only useful for TLWs // WARNING: This is overriding the Qt4 builtin topextra with unknown consequences.....
+};
+
+#else // USE_QT4
+
+struct TQWExtra;
+struct TQTLWExtra;
+
+#endif // USE_QT4
+
+class TQFocusData;
+class TQCursor;
+class TQWSRegionManager;
+class TQStyle;
+
+#ifdef USE_QT4
+
+#include <Qt/qx11info_x11.h>
+#include <private/qt4_qwidget_p.h>
+
+typedef unsigned long long WFlags;
+typedef QFlags<Qt::WindowState> WState;
+
+// #define WType_Desktop Qt::Desktop
+//
+// #define Key_Escape Qt::Key_Escape
+// #define ShiftButton Qt::ShiftModifier
+// #define ControlButton Qt::ControlModifier
+//
+// #define WStyle_Customize 0
+// #define WType_Popup Qt::Popup
+// #define WX11BypassWM Qt::X11BypassWindowManagerHint
+
+// #define TQWIDGETSIZE_MAX 32767
+#define TQWIDGETSIZE_MAX QWIDGETSIZE_MAX
+
+#define TQT_TQWIDGET_INDEPENDENT_REQUIRED_INITIALIZATION \
+ setAttribute(Qt::WA_PaintOutsidePaintEvent, TRUE); \
+ setAutoFillBackground(true);
+
+#define TQT_TQWIDGET_REQUIRED_INITIALIZATION \
+ extra = 0; \
+ tqt_internal_ignore_next_windowstatechange_event = FALSE; \
+ tqt_internal_show_called_event = FALSE; \
+ if (testWFlags(WType_Popup) && testWFlags(WType_Dialog)) \
+ clearWFlags((WType_Dialog & (~WType_TopLevel))); \
+ TQT_TQWIDGET_INDEPENDENT_REQUIRED_INITIALIZATION \
+ setDefaultWidgetFlags(); \
+ processUpperWidgetFlags();
+
+#define TQT_TQWIDGET_FIX_BROKEN_POPUP_MOUSE_FOCUS \
+ bool new_receiver_found = FALSE; \
+ QWidget *popup = qApp->activePopupWidget(); \
+ QWidget *newreceiver = this; \
+ QPoint gpos = mapToGlobal(e->pos()); \
+ QPoint npos = newreceiver->mapFromGlobal(gpos); \
+ if (popup) { \
+ while (!TQT_TQRECT_OBJECT(newreceiver->rect()).tqcontains(npos)) { \
+ new_receiver_found = TRUE; \
+ newreceiver = tqwidget_parent_popup_menu(newreceiver); \
+ if (newreceiver) { \
+ npos = newreceiver->mapFromGlobal(gpos); \
+ } \
+ else { \
+ break; \
+ } \
+ } \
+ if ((newreceiver) && (new_receiver_found)) { \
+ if (TQT_TQRECT_OBJECT(newreceiver->rect()).tqcontains(npos)) { \
+ if (tqwidget_is_popup_menu(newreceiver)) { \
+ npos = newreceiver->mapFromGlobal(gpos); \
+ QMouseEvent fixedevent(e->type(), npos, e->globalPos(), e->button(), e->buttons(), e->modifiers()); \
+ QApplication::sendEvent(newreceiver, &fixedevent); \
+ e->accept(); \
+ } \
+ } \
+ } \
+ } \
+ if (!((newreceiver) && (new_receiver_found)))
+
+extern bool tqwidget_is_popup_menu(QWidget*);
+extern QWidget* tqwidget_parent_popup_menu(QWidget*);
+
+// class TQ_EXPORT TQWidget : public TQObject, public QWidget
+class TQ_EXPORT TQWidget : public QWidget, virtual public TQt
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQObject *tqparent() const;
+ TQObjectList childrenListObject();
+ const TQObjectList childrenListObject() const;
+
+public:
+// enum FocusPolicy {
+// NoFocus = 0,
+// TabFocus = 0x1,
+// ClickFocus = 0x2,
+// StrongFocus = TabFocus | ClickFocus | 0x8,
+// WheelFocus = StrongFocus | 0x4
+// };
+
+ enum BackgroundOrigin { WidgetOrigin, ParentOrigin, WindowOrigin, AncestorOrigin };
+
+// TQWidget methods
+public:
+ TQWidget( QWidget* tqparent=0, const char* name=0, WFlags f=0 );
+
+ void setWState( uint state );
+ void clearWState( uint flags );
+ WState getWState() const;
+ WState testWState( WState s ) const;
+ WState testWState( TQt::WidgetState s ) const;
+
+ void setWFlags( WFlags flags );
+ void clearWFlags( WFlags flags );
+ WFlags getWFlags() const;
+ WFlags testWFlags( WFlags f ) const;
+
+ uint windowState() const;
+ void setWindowState(uint windowState);
+
+ void setActiveWindow( void );
+ Display * x11Display( void );
+ int x11Depth() const;
+ int x11Screen( void );
+ TQWidget * parentWidget( bool sameWindow = FALSE ) const;
+ static TQCString normalizeSignalSlot( const char *signalSlot );
+ TQMetaObject *tqmetaObject() const;
+ static TQWidget * tqfind( WId w );
+ bool isShown() const;
+ TQWidget *tqchildAt( int x, int y, bool includeThis = FALSE ) const;
+ TQWidget *tqchildAt( const TQPoint &p, bool includeThis = FALSE ) const;
+ TQWidget *tqtopLevelWidget() const;
+ bool isA(const char *classname) const;
+ bool inherits( const char * ) const;
+// virtual bool close( bool alsoDelete ) { TQ_UNUSED(alsoDelete); return QWidget::close(); }
+// TQWExtra *extraData() { return TQT_TQWEXTRA(qt_widget_private(this)->extraData()); }
+ TQWExtra *extraData();
+// TQTLWExtra *topData() { return qt_widget_private(this)->topData(); }
+ TQTLWExtra *topData();
+ void setName(const char *aName);
+ TQWidget *parentWidget( bool sameWindow = FALSE );
+ bool isDialog() const;
+ TQObject *child( const char *objName, const char *inheritsClass = 0, bool recursiveSearch = TRUE );
+ const TQRect tqgeometry() const;
+ TQLayout *tqlayout() const;
+ virtual TQSize tqsizeHint() const;
+ virtual TQSize tqminimumSizeHint() const;
+ virtual QSize sizeHint() const;
+ virtual QSize minimumSizeHint() const;
+ TQSize tqminimumSize() const;
+ TQSize tqmaximumSize() const;
+ TQColorGroup tqcolorGroup() const;
+ TQStyle &tqstyle() const;
+ void reparent(QWidget *parent, WFlags f, const QPoint &p, bool showIt=false);
+ void reparent(QWidget *parent, const QPoint &p, bool showIt=false);
+ void iconify();
+ void constPolish() const;
+ bool hasMouse() const;
+#ifndef QT_NO_CURSOR
+ bool ownCursor() const;
+#endif
+ bool ownFont() const;
+ void setBackgroundPixmap(const QPixmap &pm);
+ virtual void tqsetBackgroundPixmap(const QPixmap &pm);
+ const TQPixmap *backgroundPixmap() const;
+ void tqsetSizePolicy(QSizePolicy qsp);
+ void tqsetSizePolicy(QSizePolicy::Policy horizontal, QSizePolicy::Policy vertical);
+ void tqsetSizePolicy(QSizePolicy::Policy hor, QSizePolicy::Policy ver, bool hfw);
+ void setInputMethodEnabled(bool b);
+ bool isInputMethodEnabled() const;
+ bool isPopup() const;
+ TQString caption() const;
+ void setCaption(const QString &c);
+ TQRect tqchildrenRect() const;
+ TQRegion tqchildrenRegion() const;
+ void unsetFont();
+ bool ownPalette() const;
+ void unsetPalette();
+ const TQPalette &tqpalette() const;
+ bool isUpdatesEnabled() const;
+ void tqrepaint(int x, int y, int w, int h);
+ void tqrepaint(const QRect &r);
+ void tqrepaint(const QRegion &r);
+ void tqrepaint(bool eraseme);
+ void tqrepaint(int x, int y, int w, int h, bool);
+ void tqrepaint(const QRect &r, bool);
+ void tqrepaint(const QRegion &rgn, bool);
+ TQSizePolicy tqsizePolicy() const;
+ TQPoint backgroundOffset() const;
+ bool tqsignalsBlocked() const;
+ TQObjectList *queryList( const char *inheritsClass = 0, const char *objName = 0, bool regexpMatch = TRUE, bool recursiveSearch = TRUE ) const;
+ TQWidget *tqfocusWidget() const;
+ void setBackgroundOrigin(BackgroundOrigin);
+ BackgroundOrigin backgroundOrigin() const;
+ void setIconText(const QString &it);
+ void insertChild( TQObject *object );
+ void removeChild( TQObject *object );
+
+ bool close();
+ bool close(bool alsoDelete);
+
+ void setFocus(Qt::FocusReason reason);
+ void setFocus(TQFocusEvent::Reason reason);
+
+ TQt::BackgroundMode backgroundMode() const;
+ /*virtual*/ void setBackgroundMode( TQt::BackgroundMode tqbm );
+ void setBackgroundMode(TQt::BackgroundMode, TQt::BackgroundMode);
+ const QColor &paletteForegroundColor() const;
+ void setPaletteForegroundColor(const QColor &c);
+ const QColor &paletteBackgroundColor() const;
+ /*virtual*/ void setPaletteBackgroundColor(const QColor &c);
+ const TQPixmap *paletteBackgroundPixmap() const;
+ /*virtual*/ void setPaletteBackgroundPixmap(const QPixmap &pm);
+ const TQColor &backgroundColor() const;
+ /*virtual*/ void setBackgroundColor(const QColor &c);
+ const TQColor &eraseColor() const;
+ /*virtual*/ void setEraseColor(const QColor &c);
+ const TQPixmap *erasePixmap() const;
+ /*virtual*/ void setErasePixmap(const QPixmap &pm);
+ const TQColor &foregroundColor() const;
+
+ virtual void setAutoMask(bool);
+ bool autoMask() const;
+ virtual void updateMask();
+
+ void erase();
+ void erase(int x, int y, int w, int h);
+ void erase(const QRect &r);
+ void erase(const QRegion &r);
+
+ void drawText( int x, int y, const TQString &);
+ void drawText( const TQPoint &, const TQString &);
+
+ const TQBrush& backgroundBrush() const;
+ void setIcon(const QPixmap &i);
+ const TQPixmap *icon() const;
+ const TQPixmap iconPixmap() const;
+
+ const char *tqname() const;
+ const char *name() const;
+ const char *name(const char *defaultName) const;
+
+ bool isVisibleToTLW() const; // obsolete
+ static TQWidget* tqt_ensure_valid_widget_painting(TQWidget* w);
+
+ void setMask( const QBitmap );
+ void setMask( const QRegion );
+
+#ifndef TQT_NO_STYLE
+ void setStyle( TQStyle * );
+ TQStyle* setStyle( const TQString& );
+#endif
+
+#ifndef TQT_NO_PALETTE
+ void tqsetPalette( const TQPalette &p, bool );
+#endif
+
+// static TQWidgetMapper *wmapper( void ) { return QWidgetPrivate::mapper; }
+
+// TQWExtra *extraData();
+// TQTLWExtra *topData();
+// TQFocusData *focusData();
+
+ bool isDesktop() const;
+
+ void createTLSysExtra( void );
+ void destroyInputContext( void );
+
+ void createExtra();
+ void deleteExtra();
+
+ bool isFocusEnabled() const;
+
+// TQRect tqeffectiveRectFor(const QRect &rect);
+ TQRect tqclipRect() const;
+ TQRect visibleRect() const;
+ TQRegion clipRegion() const;
+
+ virtual bool customWhatsThis() const;
+
+ virtual void setKeyCompression(bool);
+ TQRect microFocusHint() const;
+ virtual void setMicroFocusHint(int x, int y, int w, int h, bool text=TRUE, TQFont *f = 0);
+
+// // Interoperability
+// TQWidget* operator= (QWidget* a)
+// {
+// return static_cast<TQWidget*>(a);
+// }
+
+ operator TQObject*() const { return TQT_TQOBJECT(const_cast<TQWidget*>(this)); } // This implicit pointer converter doesn't work for some reason
+
+public:
+ // TQt handler
+ virtual bool eventFilter( TQObject *, TQEvent * );
+
+ // Qt4 handler interface
+ virtual bool eventFilter( QObject *q, QEvent *e );
+ bool event( QEvent *e );
+
+protected:
+ inline bool checkConnectArgs(const char *signal, const TQT_BASE_OBJECT_NAME *name, const char *member) { return TQT_TQOBJECT(this)->checkConnectArgs(signal, name, member); }
+
+// TQt event handlers
+protected:
+ TQFocusData *focusData();
+// virtual bool event( QEvent *e ); // NOTE: All event handlers that can be subclassed must be declared here, and
+ // declared virtual, so that run time dynamic call resolution will occur
+ virtual bool event( TQEvent *e );
+ virtual void mousePressEvent( TQMouseEvent * );
+ virtual void mouseReleaseEvent( TQMouseEvent * );
+ virtual void mouseDoubleClickEvent( TQMouseEvent * );
+ virtual void mouseMoveEvent( TQMouseEvent * );
+#ifndef TQT_NO_WHEELEVENT
+ virtual void wheelEvent( TQWheelEvent * );
+#endif
+ virtual void keyPressEvent( TQKeyEvent * );
+ virtual void keyReleaseEvent( TQKeyEvent * );
+ virtual void focusInEvent( TQFocusEvent * );
+ virtual void focusOutEvent( TQFocusEvent * );
+ virtual void enterEvent( TQEvent * );
+ virtual void leaveEvent( TQEvent * );
+ virtual void paintEvent( TQPaintEvent * );
+ virtual void moveEvent( TQMoveEvent * );
+ virtual void resizeEvent( TQResizeEvent * );
+ virtual void closeEvent( TQCloseEvent * );
+ virtual void contextMenuEvent( TQContextMenuEvent * );
+ virtual void imStartEvent( TQIMEvent * );
+ virtual void imComposeEvent( TQIMEvent * );
+ virtual void imEndEvent( TQIMEvent * );
+ virtual void tabletEvent( TQTabletEvent * );
+
+#ifndef TQT_NO_DRAGANDDROP
+ virtual void dragEnterEvent( TQDragEnterEvent * );
+ virtual void dragMoveEvent( TQDragMoveEvent * );
+ virtual void dragLeaveEvent( TQDragLeaveEvent * );
+ virtual void dropEvent( TQDropEvent * );
+#endif
+
+ virtual void showEvent( TQShowEvent * );
+ virtual void hideEvent( TQHideEvent * );
+
+#if defined(TQ_WS_MAC)
+ virtual bool macEvent( MSG * );
+#endif
+#if defined(TQ_WS_WIN)
+ virtual bool winEvent( MSG * );
+#endif
+#if defined(TQ_WS_X11)
+ virtual bool x11Event( XEvent * );
+#endif
+#if defined(TQ_WS_TQWS)
+ virtual bool qwsEvent( TQWSEvent * );
+#endif
+
+// Qt4 event handler interface
+protected:
+ virtual void mousePressEvent(QMouseEvent *e);
+ virtual void mouseReleaseEvent(QMouseEvent *e);
+ virtual void mouseDoubleClickEvent(QMouseEvent *e);
+ virtual void mouseMoveEvent(QMouseEvent *e);
+#ifndef QT_NO_WHEELEVENT
+ virtual void wheelEvent(QWheelEvent *e);
+#endif
+ virtual void keyPressEvent(QKeyEvent *e);
+ virtual void keyReleaseEvent(QKeyEvent *e);
+ virtual void focusInEvent(QFocusEvent *e);
+ virtual void focusOutEvent(QFocusEvent *e);
+ virtual void enterEvent(QEvent *e);
+ virtual void leaveEvent(QEvent *e);
+ virtual void paintEvent(QPaintEvent *e);
+ virtual void moveEvent(QMoveEvent *e);
+ virtual void resizeEvent(QResizeEvent *e);
+ virtual void closeEvent(QCloseEvent *e);
+#ifndef QT_NO_CONTEXTMENU
+ virtual void contextMenuEvent(QContextMenuEvent *e);
+#endif
+#ifndef QT_NO_TABLETEVENT
+ virtual void tabletEvent(QTabletEvent *e);
+#endif
+#ifndef QT_NO_ACTION
+// inline virtual void actionEvent(QActionEvent *e) { actionEvent(static_cast<TQActionEvent*>(e)); }
+#endif
+
+// #ifndef QT_NO_DRAGANDDROP
+// inline virtual void dragEnterEvent(QDragEnterEvent *e) { dragEnterEvent(static_cast<TQDragEnterEvent*>(e)); }
+// inline virtual void dragMoveEvent(QDragMoveEvent *e) { dragMoveEvent(static_cast<TQDragMoveEvent*>(e)); }
+// inline virtual void dragLeaveEvent(QDragLeaveEvent *e) { dragLeaveEvent(static_cast<TQDragLeaveEvent*>(e)); }
+// inline virtual void dropEvent(QDropEvent *e) { dropEvent(static_cast<TQDropEvent*>(e)); }
+// #endif
+
+ virtual void showEvent(QShowEvent *e);
+ virtual void hideEvent(QHideEvent *e);
+
+// #if defined(Q_WS_MAC)
+// inline virtual bool macEvent(EventHandlerCallRef e, EventRef r);
+// #endif
+// #if defined(Q_WS_WIN)
+// inline virtual bool winEvent(MSG *message, long *result);
+// #endif
+// #if defined(Q_WS_X11)
+// inline virtual bool x11Event(XEvent *e)
+// #endif
+// #if defined(Q_WS_QWS)
+// inline virtual bool qwsEvent(QWSEvent *e);
+// #endif
+
+// TQt event handlers
+protected:
+ virtual void timerEvent( TQTimerEvent * );
+ virtual void childEvent( TQChildEvent * );
+ virtual void customEvent( TQCustomEvent * );
+
+// Qt4 event handler interface
+protected:
+ virtual void timerEvent(QTimerEvent *e);
+ virtual void childEvent(QChildEvent *e);
+ virtual void customEvent(QEvent *e);
+
+private:
+ mutable TQStyle* tqt_internal_stylePointer;
+ void erase_helper(int x, int y, int w, int h);
+ TQWExtra *extra;
+ TQFocusData *focusData( bool create );
+ void createTLExtra();
+ bool tqt_internal_show_called_event;
+ mutable bool tqt_internal_ignore_next_windowstatechange_event;
+ mutable TQString static_object_name;
+
+ void showWindow();
+ void hideWindow();
+
+ WFlags TQtUpperWidgetFlags;
+ void processUpperWidgetFlags();
+ void setDefaultWidgetFlags();
+
+ friend class TQObject;
+
+public Q_SLOTS:
+ virtual void tqsetUpdatesEnabled( bool enable );
+ void tqrepaint();
+ virtual void setFocus();
+ virtual void show();
+ virtual void adjustSize();
+// inline virtual void adjustSize() {
+// QApplication::sendPostedEvents( 0, TQEvent::ChildInserted );
+// QWidget::adjustSize();
+// }
+ virtual void polish();
+// inline virtual void setGeometry( int x, int y, int w, int h ) { return QWidget::setGeometry(x, y, w, h); }
+// inline virtual void setGeometry( const TQRect &r ) { return QWidget::setGeometry(r); }
+
+// protected:
+ TQConnectionList *tqreceivers( const char* signal ) const;
+ TQConnectionList *tqreceivers( int signal ) const;
+//
+ void activate_signal( int signal );
+// void activate_signal( int signal, int second ) { TQT_TQOBJECT(this)->activate_signal(signal, second); }
+// void activate_signal( int signal, double second ) { TQT_TQOBJECT(this)->activate_signal(signal, second); }
+// void activate_signal( int signal, TQString second ) { TQT_TQOBJECT(this)->activate_signal(signal, second); }
+// void activate_signal_bool( int signal, bool second ) { TQT_TQOBJECT(this)->activate_signal(signal, second); }
+ void activate_signal( TQConnectionList *clist, TQUObject *o );
+
+ void tqt_handle_qt_destroyed(QObject* obj);
+
+Q_SIGNALS:
+ void destroyed( TQObject* obj );
+};
+
+inline void TQWidget::drawText( const TQPoint &p, const TQString &s )
+{ drawText( p.x(), p.y(), s ); }
+
+#else // USE_QT4
+
+class TQ_EXPORT TQWidget : public TQObject, public TQPaintDevice
+{
+ TQ_OBJECT
+ TQ_ENUMS( BackgroundMode FocusPolicy BackgroundOrigin )
+ Q_PROPERTY( bool isTopLevel READ isTopLevel )
+ Q_PROPERTY( bool isDialog READ isDialog )
+ Q_PROPERTY( bool isModal READ isModal )
+ Q_PROPERTY( bool isPopup READ isPopup )
+ Q_PROPERTY( bool isDesktop READ isDesktop )
+ Q_PROPERTY( bool enabled READ isEnabled WRITE setEnabled )
+ Q_PROPERTY( TQRect tqgeometry READ tqgeometry WRITE setGeometry )
+ Q_PROPERTY( TQRect frameGeometry READ frameGeometry )
+ Q_PROPERTY( int x READ x )
+ Q_PROPERTY( int y READ y )
+ Q_PROPERTY( TQPoint pos READ pos WRITE move DESIGNABLE false STORED false )
+ Q_PROPERTY( TQSize frameSize READ frameSize )
+ Q_PROPERTY( TQSize size READ size WRITE resize DESIGNABLE false STORED false )
+ Q_PROPERTY( int width READ width )
+ Q_PROPERTY( int height READ height )
+ Q_PROPERTY( TQRect rect READ rect )
+ Q_PROPERTY( TQRect tqchildrenRect READ tqchildrenRect )
+ Q_PROPERTY( TQRegion tqchildrenRegion READ tqchildrenRegion )
+ Q_PROPERTY( TQSizePolicy sizePolicy READ sizePolicy WRITE tqsetSizePolicy )
+ Q_PROPERTY( TQSize tqminimumSize READ tqminimumSize WRITE setMinimumSize )
+ Q_PROPERTY( TQSize tqmaximumSize READ tqmaximumSize WRITE setMaximumSize )
+ Q_PROPERTY( int minimumWidth READ minimumWidth WRITE setMinimumWidth STORED false DESIGNABLE false )
+ Q_PROPERTY( int minimumHeight READ minimumHeight WRITE setMinimumHeight STORED false DESIGNABLE false )
+ Q_PROPERTY( int maximumWidth READ maximumWidth WRITE setMaximumWidth STORED false DESIGNABLE false )
+ Q_PROPERTY( int maximumHeight READ maximumHeight WRITE setMaximumHeight STORED false DESIGNABLE false )
+ Q_PROPERTY( TQSize sizeIncrement READ sizeIncrement WRITE setSizeIncrement )
+ Q_PROPERTY( TQSize baseSize READ baseSize WRITE setBaseSize )
+ Q_PROPERTY( BackgroundMode backgroundMode READ backgroundMode WRITE setBackgroundMode DESIGNABLE false )
+ Q_PROPERTY( TQColor paletteForegroundColor READ paletteForegroundColor WRITE setPaletteForegroundColor RESET unsetPalette )
+ Q_PROPERTY( TQColor paletteBackgroundColor READ paletteBackgroundColor WRITE setPaletteBackgroundColor RESET unsetPalette )
+ Q_PROPERTY( TQPixmap paletteBackgroundPixmap READ paletteBackgroundPixmap WRITE setPaletteBackgroundPixmap RESET unsetPalette )
+ Q_PROPERTY( TQBrush backgroundBrush READ backgroundBrush )
+ Q_PROPERTY( TQColorGroup tqcolorGroup READ tqcolorGroup )
+ Q_PROPERTY( TQPalette palette READ palette WRITE setPalette RESET unsetPalette STORED ownPalette )
+ Q_PROPERTY( BackgroundOrigin backgroundOrigin READ backgroundOrigin WRITE setBackgroundOrigin )
+ Q_PROPERTY( bool ownPalette READ ownPalette )
+ Q_PROPERTY( TQFont font READ font WRITE setFont RESET unsetFont STORED ownFont )
+ Q_PROPERTY( bool ownFont READ ownFont )
+#ifndef TQT_NO_CURSOR
+ Q_PROPERTY( TQCursor cursor READ cursor WRITE setCursor RESET unsetCursor STORED ownCursor )
+ Q_PROPERTY( bool ownCursor READ ownCursor )
+#endif
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ Q_PROPERTY( TQString caption READ caption WRITE setCaption )
+ Q_PROPERTY( TQPixmap icon READ icon WRITE setIcon )
+ Q_PROPERTY( TQString iconText READ iconText WRITE setIconText )
+#endif
+ Q_PROPERTY( bool mouseTracking READ hasMouseTracking WRITE setMouseTracking )
+ Q_PROPERTY( bool underMouse READ hasMouse )
+ Q_PROPERTY( bool isActiveWindow READ isActiveWindow )
+ Q_PROPERTY( bool focusEnabled READ isFocusEnabled )
+ Q_PROPERTY( FocusPolicy focusPolicy READ focusPolicy WRITE setFocusPolicy )
+ Q_PROPERTY( bool focus READ hasFocus )
+ Q_PROPERTY( bool updatesEnabled READ isUpdatesEnabled WRITE setUpdatesEnabled DESIGNABLE false )
+ Q_PROPERTY( bool visible READ isVisible )
+ Q_PROPERTY( TQRect visibleRect READ visibleRect ) // obsolete
+ Q_PROPERTY( bool hidden READ isHidden WRITE setHidden DESIGNABLE false SCRIPTABLE false )
+ Q_PROPERTY( bool shown READ isShown WRITE setShown DESIGNABLE false SCRIPTABLE false )
+ Q_PROPERTY( bool minimized READ isMinimized )
+ Q_PROPERTY( bool maximized READ isMaximized )
+ Q_PROPERTY( bool fullScreen READ isFullScreen )
+ Q_PROPERTY( TQSize tqsizeHint READ tqsizeHint )
+ Q_PROPERTY( TQSize tqminimumSizeHint READ tqminimumSizeHint )
+ Q_PROPERTY( TQRect microFocusHint READ microFocusHint )
+ Q_PROPERTY( bool acceptDrops READ acceptDrops WRITE setAcceptDrops )
+ Q_PROPERTY( bool autoMask READ autoMask WRITE setAutoMask DESIGNABLE false SCRIPTABLE false )
+ Q_PROPERTY( bool customWhatsThis READ customWhatsThis )
+ Q_PROPERTY( bool inputMethodEnabled READ isInputMethodEnabled WRITE setInputMethodEnabled DESIGNABLE false SCRIPTABLE false )
+ Q_PROPERTY( double windowOpacity READ windowOpacity WRITE setWindowOpacity DESIGNABLE false )
+
+public:
+ TQ_EXPLICIT TQWidget( TQWidget* tqparent=0, const char* name=0, WFlags f=0 );
+ ~TQWidget();
+
+ WId winId() const;
+ void setName( const char *name );
+#ifndef TQT_NO_STYLE
+ // GUI style setting
+
+ TQStyle &style() const;
+ void setStyle( TQStyle * );
+ TQStyle* setStyle( const TQString& );
+#endif
+ // Widget types and states
+
+ bool isTopLevel() const;
+ bool isDialog() const;
+ bool isPopup() const;
+ bool isDesktop() const;
+ bool isModal() const;
+
+ bool isEnabled() const;
+ bool isEnabledTo(TQWidget*) const;
+ bool isEnabledToTLW() const;
+
+public Q_SLOTS:
+ virtual void setEnabled( bool );
+ void setDisabled( bool );
+
+ // Widget coordinates
+
+public:
+ TQRect frameGeometry() const;
+ const TQRect &tqgeometry() const;
+ int x() const;
+ int y() const;
+ TQPoint pos() const;
+ TQSize frameSize() const;
+ TQSize size() const;
+ int width() const;
+ int height() const;
+ TQRect rect() const;
+ TQRect tqchildrenRect() const;
+ TQRegion tqchildrenRegion() const;
+
+ TQSize tqminimumSize() const;
+ TQSize tqmaximumSize() const;
+ int minimumWidth() const;
+ int minimumHeight() const;
+ int maximumWidth() const;
+ int maximumHeight() const;
+ void setMinimumSize( const TQSize & );
+ virtual void setMinimumSize( int minw, int minh );
+ void setMaximumSize( const TQSize & );
+ virtual void setMaximumSize( int maxw, int maxh );
+ void setMinimumWidth( int minw );
+ void setMinimumHeight( int minh );
+ void setMaximumWidth( int maxw );
+ void setMaximumHeight( int maxh );
+
+ TQSize sizeIncrement() const;
+ void setSizeIncrement( const TQSize & );
+ virtual void setSizeIncrement( int w, int h );
+ TQSize baseSize() const;
+ void setBaseSize( const TQSize & );
+ void setBaseSize( int basew, int baseh );
+
+ void setFixedSize( const TQSize & );
+ void setFixedSize( int w, int h );
+ void setFixedWidth( int w );
+ void setFixedHeight( int h );
+
+ // Widget coordinate mapping
+
+ TQPoint mapToGlobal( const TQPoint & ) const;
+ TQPoint mapFromGlobal( const TQPoint & ) const;
+ TQPoint mapToParent( const TQPoint & ) const;
+ TQPoint mapFromParent( const TQPoint & ) const;
+ TQPoint mapTo( TQWidget *, const TQPoint & ) const;
+ TQPoint mapFrom( TQWidget *, const TQPoint & ) const;
+
+ TQWidget *tqtopLevelWidget() const;
+
+ // Widget attribute functions
+
+ BackgroundMode backgroundMode() const;
+ virtual void setBackgroundMode( BackgroundMode );
+ void setBackgroundMode( BackgroundMode, BackgroundMode );
+
+ const TQColor & foregroundColor() const;
+
+ const TQColor & eraseColor() const;
+ virtual void setEraseColor( const TQColor & );
+
+ const TQPixmap * erasePixmap() const;
+ virtual void setErasePixmap( const TQPixmap & );
+
+#ifndef TQT_NO_PALETTE
+ const TQColorGroup & tqcolorGroup() const;
+ const TQPalette & palette() const;
+ bool ownPalette() const;
+ virtual void setPalette( const TQPalette & );
+ void unsetPalette();
+#endif
+
+ const TQColor & paletteForegroundColor() const;
+ void setPaletteForegroundColor( const TQColor & );
+
+ const TQColor & paletteBackgroundColor() const;
+ virtual void setPaletteBackgroundColor( const TQColor & );
+
+ const TQPixmap * paletteBackgroundPixmap() const;
+ virtual void setPaletteBackgroundPixmap( const TQPixmap & );
+
+ const TQBrush& backgroundBrush() const;
+
+ TQFont font() const;
+ bool ownFont() const;
+ virtual void setFont( const TQFont & );
+ void unsetFont();
+ TQFontMetrics fontMetrics() const;
+ TQFontInfo fontInfo() const;
+
+#ifndef TQT_NO_CURSOR
+ const TQCursor &cursor() const;
+ bool ownCursor() const;
+ virtual void setCursor( const TQCursor & );
+ virtual void unsetCursor();
+#endif
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ TQString caption() const;
+ const TQPixmap *icon() const;
+ TQString iconText() const;
+#endif
+ bool hasMouseTracking() const;
+ bool hasMouse() const;
+
+ virtual void setMask( const TQBitmap & );
+ virtual void setMask( const TQRegion & );
+ void clearMask();
+
+ const TQColor & backgroundColor() const; // obsolete, use eraseColor()
+ virtual void setBackgroundColor( const TQColor & ); // obsolete, use setEraseColor()
+ const TQPixmap * backgroundPixmap() const; // obsolete, use erasePixmap()
+ virtual void setBackgroundPixmap( const TQPixmap & ); // obsolete, use setErasePixmap()
+
+public Q_SLOTS:
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ virtual void setCaption( const TQString &);
+ virtual void setIcon( const TQPixmap & );
+ virtual void setIconText( const TQString &);
+#endif
+ virtual void setMouseTracking( bool enable );
+
+ // Keyboard input focus functions
+
+ virtual void setFocus();
+ void clearFocus();
+
+public:
+ enum FocusPolicy {
+ NoFocus = 0,
+ TabFocus = 0x1,
+ ClickFocus = 0x2,
+ StrongFocus = TabFocus | ClickFocus | 0x8,
+ WheelFocus = StrongFocus | 0x4
+ };
+
+ bool isActiveWindow() const;
+ virtual void setActiveWindow();
+ bool isFocusEnabled() const;
+
+ FocusPolicy focusPolicy() const;
+ virtual void setFocusPolicy( FocusPolicy );
+ bool hasFocus() const;
+ static void setTabOrder( TQWidget *, TQWidget * );
+ virtual void setFocusProxy( TQWidget * );
+ TQWidget * focusProxy() const;
+
+ void setInputMethodEnabled( bool b );
+ bool isInputMethodEnabled() const;
+ // Grab functions
+
+ void grabMouse();
+#ifndef TQT_NO_CURSOR
+ void grabMouse( const TQCursor & );
+#endif
+ void releaseMouse();
+ void grabKeyboard();
+ void releaseKeyboard();
+ static TQWidget * mouseGrabber();
+ static TQWidget * keyboardGrabber();
+
+ // Update/refresh functions
+
+ bool isUpdatesEnabled() const;
+
+#if 0 //def TQ_WS_TQWS
+ void repaintUnclipped( const TQRegion &, bool erase = TRUE );
+#endif
+public Q_SLOTS:
+ virtual void setUpdatesEnabled( bool enable );
+ void update();
+ void update( int x, int y, int w, int h );
+ void update( const TQRect& );
+ void tqrepaint();
+ void tqrepaint( bool erase );
+ void tqrepaint( int x, int y, int w, int h, bool erase=TRUE );
+ void tqrepaint( const TQRect &, bool erase = TRUE );
+ void tqrepaint( const TQRegion &, bool erase = TRUE );
+
+ // Widget management functions
+
+ virtual void show();
+ virtual void hide();
+ void setShown( bool show );
+ void setHidden( bool hide );
+#ifndef TQT_NO_COMPAT
+ void iconify() { showMinimized(); }
+#endif
+ virtual void showMinimized();
+ virtual void showMaximized();
+ void showFullScreen();
+ virtual void showNormal();
+ virtual void polish();
+ void constPolish() const;
+ bool close();
+
+ void raise();
+ void lower();
+ void stackUnder( TQWidget* );
+ virtual void move( int x, int y );
+ void move( const TQPoint & );
+ virtual void resize( int w, int h );
+ void resize( const TQSize & );
+ virtual void setGeometry( int x, int y, int w, int h );
+ virtual void setGeometry( const TQRect & ); // ### make non virtual in TQt 4?
+
+public:
+ virtual bool close( bool alsoDelete );
+ bool isVisible() const;
+ bool isVisibleTo(TQWidget*) const;
+ bool isVisibleToTLW() const; // obsolete
+ TQRect visibleRect() const; // obsolete
+ bool isHidden() const;
+ bool isShown() const;
+ bool isMinimized() const;
+ bool isMaximized() const;
+ bool isFullScreen() const;
+
+ uint windowState() const;
+ void setWindowState(uint windowState);
+
+ virtual TQSize tqsizeHint() const;
+ virtual TQSize tqminimumSizeHint() const;
+ virtual TQSizePolicy sizePolicy() const;
+ virtual void tqsetSizePolicy( TQSizePolicy );
+ void tqsetSizePolicy( TQSizePolicy::SizeType hor, TQSizePolicy::SizeType ver, bool hfw = FALSE );
+ virtual int heightForWidth(int) const;
+
+ TQRegion clipRegion() const;
+
+// ### move together with other Q_SLOTS in TQt 4.0
+public Q_SLOTS:
+ virtual void adjustSize();
+
+public:
+#ifndef TQT_NO_LAYOUT
+ TQLayout * tqlayout() const { return lay_out; }
+#endif
+ void updateGeometry();
+ virtual void reparent( TQWidget *tqparent, WFlags, const TQPoint &,
+ bool showIt=FALSE );
+ void reparent( TQWidget *tqparent, const TQPoint &,
+ bool showIt=FALSE );
+#ifndef TQT_NO_COMPAT
+ void recreate( TQWidget *tqparent, WFlags f, const TQPoint & p,
+ bool showIt=FALSE ) { reparent(tqparent,f,p,showIt); }
+#endif
+
+ void erase();
+ void erase( int x, int y, int w, int h );
+ void erase( const TQRect & );
+ void erase( const TQRegion & );
+ void scroll( int dx, int dy );
+ void scroll( int dx, int dy, const TQRect& );
+
+ void drawText( int x, int y, const TQString &);
+ void drawText( const TQPoint &, const TQString &);
+
+ // Misc. functions
+
+ TQWidget * tqfocusWidget() const;
+ TQRect microFocusHint() const;
+
+ // drag and drop
+
+ bool acceptDrops() const;
+ virtual void setAcceptDrops( bool on );
+
+ // transparency and pseudo transparency
+
+ virtual void setAutoMask(bool);
+ bool autoMask() const;
+
+ enum BackgroundOrigin { WidgetOrigin, ParentOrigin, WindowOrigin, AncestorOrigin };
+
+ virtual void setBackgroundOrigin( BackgroundOrigin );
+ BackgroundOrigin backgroundOrigin() const;
+ TQPoint backgroundOffset() const;
+
+ // whats this help
+ virtual bool customWhatsThis() const;
+
+ TQWidget * parentWidget( bool sameWindow = FALSE ) const;
+ WState testWState( WState s ) const;
+ WFlags testWFlags( WFlags f ) const;
+ static TQWidget * tqfind( WId );
+ static TQWidgetMapper *wmapper();
+
+ TQWidget *tqchildAt( int x, int y, bool includeThis = FALSE ) const;
+ TQWidget *tqchildAt( const TQPoint &, bool includeThis = FALSE ) const;
+
+#if defined(TQ_WS_TQWS)
+ virtual TQGfx * graphicsContext(bool clip_tqchildren=TRUE) const;
+#endif
+#if defined(TQ_WS_MAC)
+ TQRegion clippedRegion(bool do_tqchildren=TRUE);
+ uint clippedSerial(bool do_tqchildren=TRUE);
+#ifndef TQMAC_NO_TQUARTZ
+ CGContextRef macCGContext(bool clipped=TRUE) const;
+#endif
+#endif
+
+ void setWindowOpacity(double level);
+ double windowOpacity() const;
+
+protected:
+ // Event handlers
+ virtual bool event( TQEvent * );
+ virtual void mousePressEvent( TQMouseEvent * );
+ virtual void mouseReleaseEvent( TQMouseEvent * );
+ virtual void mouseDoubleClickEvent( TQMouseEvent * );
+ virtual void mouseMoveEvent( TQMouseEvent * );
+#ifndef TQT_NO_WHEELEVENT
+ virtual void wheelEvent( TQWheelEvent * );
+#endif
+ virtual void keyPressEvent( TQKeyEvent * );
+ virtual void keyReleaseEvent( TQKeyEvent * );
+ virtual void focusInEvent( TQFocusEvent * );
+ virtual void focusOutEvent( TQFocusEvent * );
+ virtual void enterEvent( TQEvent * );
+ virtual void leaveEvent( TQEvent * );
+ virtual void paintEvent( TQPaintEvent * );
+ virtual void moveEvent( TQMoveEvent * );
+ virtual void resizeEvent( TQResizeEvent * );
+ virtual void closeEvent( TQCloseEvent * );
+ virtual void contextMenuEvent( TQContextMenuEvent * );
+ virtual void imStartEvent( TQIMEvent * );
+ virtual void imComposeEvent( TQIMEvent * );
+ virtual void imEndEvent( TQIMEvent * );
+ virtual void tabletEvent( TQTabletEvent * );
+
+#ifndef TQT_NO_DRAGANDDROP
+ virtual void dragEnterEvent( TQDragEnterEvent * );
+ virtual void dragMoveEvent( TQDragMoveEvent * );
+ virtual void dragLeaveEvent( TQDragLeaveEvent * );
+ virtual void dropEvent( TQDropEvent * );
+#endif
+
+ virtual void showEvent( TQShowEvent * );
+ virtual void hideEvent( TQHideEvent * );
+
+#if defined(TQ_WS_MAC)
+ virtual bool macEvent( MSG * );
+#endif
+#if defined(TQ_WS_WIN)
+ virtual bool winEvent( MSG * );
+#endif
+#if defined(TQ_WS_X11)
+ virtual bool x11Event( XEvent * );
+#endif
+#if defined(TQ_WS_TQWS)
+ virtual bool qwsEvent( TQWSEvent * );
+ virtual unsigned char *scanLine( int ) const;
+ virtual int bytesPerLine() const;
+#endif
+
+ virtual void updateMask();
+
+ // Misc. protected functions
+
+#ifndef TQT_NO_STYLE
+ virtual void styleChange( TQStyle& );
+#endif
+ virtual void enabledChange( bool oldEnabled );
+#ifndef TQT_NO_PALETTE
+ virtual void paletteChange( const TQPalette & );
+#endif
+ virtual void fontChange( const TQFont & );
+ virtual void windowActivationChange( bool oldActive );
+
+ int metric( int ) const;
+
+ void resetInputContext();
+
+ virtual void create( WId = 0, bool initializeWindow = TRUE,
+ bool destroyOldWindow = TRUE );
+ virtual void destroy( bool destroyWindow = TRUE,
+ bool destroySubWindows = TRUE );
+ uint getWState() const;
+ virtual void setWState( uint );
+ void clearWState( uint n );
+ WFlags getWFlags() const;
+ virtual void setWFlags( WFlags );
+ void clearWFlags( WFlags n );
+
+ virtual bool focusNextPrevChild( bool next );
+
+ TQWExtra *extraData();
+ TQTLWExtra *topData();
+ TQFocusData *focusData();
+
+ virtual void setKeyCompression(bool);
+ virtual void setMicroFocusHint(int x, int y, int w, int h, bool text=TRUE, TQFont *f = 0);
+
+#if defined(TQ_WS_MAC)
+ void dirtyClippedRegion(bool);
+ bool isClippedRegionDirty();
+ virtual void setRegionDirty(bool);
+ virtual void macWidgetChangedWindow();
+#endif
+
+private Q_SLOTS:
+ void focusProxyDestroyed();
+
+private:
+ void setFontSys( TQFont *f = 0 );
+#if defined(TQ_WS_X11)
+ void createInputContext();
+ void destroyInputContext();
+ void focusInputContext();
+ void checkChildrenDnd();
+#elif defined(TQ_WS_MAC)
+ uint own_id : 1, macDropEnabled : 1;
+ EventHandlerRef window_event;
+ //mac event functions
+ void propagateUpdates(bool update_rgn=TRUE);
+ void update( const TQRegion& );
+ //friends, way too many - fix this immediately!
+ friend void qt_clean_root_win();
+ friend bool qt_recreate_root_win();
+ friend TQPoint posInWindow(TQWidget *);
+ friend bool qt_mac_update_sizer(TQWidget *, int);
+ friend TQWidget *qt_recursive_match(TQWidget *widg, int x, int y);
+ friend bool qt_paint_childrenListObject(TQWidget *,TQRegion &, uchar ops);
+ friend TQMAC_PASCAL OStqStatus qt_window_event(EventHandlerCallRef er, EventRef event, void *);
+ friend void qt_event_request_updates(TQWidget *, const TQRegion &, bool subtract);
+ friend bool qt_window_rgn(WId, short, RgnHandle, bool);
+ friend class TQDragManager;
+#endif
+
+#ifndef TQT_NO_LAYOUT
+ void setLayout( TQLayout *l );
+#endif
+ void setWinId( WId );
+ void showWindow();
+ void hideWindow();
+ void showChildren( bool spontaneous );
+ void hideChildren( bool spontaneous );
+ void reparentSys( TQWidget *tqparent, WFlags, const TQPoint &, bool showIt);
+ void createTLExtra();
+ void createExtra();
+ void deleteExtra();
+ void createSysExtra();
+ void deleteSysExtra();
+ void createTLSysExtra();
+ void deleteTLSysExtra();
+ void deactivateWidgetCleanup();
+ void internalSetGeometry( int, int, int, int, bool );
+ void reparentFocusWidgets( TQWidget * );
+ TQFocusData *focusData( bool create );
+ void setBackgroundFromMode();
+ void setBackgroundColorDirect( const TQColor & );
+ void setBackgroundPixmapDirect( const TQPixmap & );
+ void setBackgroundModeDirect( BackgroundMode );
+ void setBackgroundEmpty();
+ void updateFrameStrut() const;
+#if defined(TQ_WS_X11)
+ void setBackgroundX11Relative();
+#endif
+
+ WId winid;
+ uint widget_state;
+ uint widget_flags;
+ uint focus_policy : 4;
+ uint own_font :1;
+ uint own_palette :1;
+ uint sizehint_forced :1;
+ uint is_closing :1;
+ uint in_show : 1;
+ uint in_show_maximized : 1;
+ uint fstrut_dirty : 1;
+ uint im_enabled : 1;
+ TQRect crect;
+ TQColor bg_col;
+#ifndef TQT_NO_PALETTE
+ TQPalette pal;
+#endif
+ TQFont fnt;
+#ifndef TQT_NO_LAYOUT
+ TQLayout *lay_out;
+#endif
+ TQWExtra *extra;
+#if defined(TQ_WS_TQWS)
+ TQRegion req_region; // Requested region
+ mutable TQRegion paintable_region; // Paintable region
+ mutable bool paintable_region_dirty;// needs to be recalculated
+ mutable TQRegion alloc_region; // Allocated region
+ mutable bool alloc_region_dirty; // needs to be recalculated
+ mutable int overlapping_tqchildren; // Handle overlapping tqchildren
+
+ int alloc_region_index;
+ int alloc_region_revision;
+
+ void updateOverlappingChildren() const;
+ void setChildrenAllocatedDirty();
+ void setChildrenAllocatedDirty( const TQRegion &r, const TQWidget *dirty=0 );
+ bool isAllocatedRegionDirty() const;
+ void updateRequestedRegion( const TQPoint &gpos );
+ TQRegion requestedRegion() const;
+ TQRegion allocatedRegion() const;
+ TQRegion paintableRegion() const;
+
+ void updateGraphicsContext( TQGfx *qgfx_qws, bool clip_tqchildren ) const;
+#ifndef TQT_NO_CURSOR
+ void updateCursor( const TQRegion &r ) const;
+#endif
+
+ // used to accumulate dirty region when tqchildren moved/resized.
+ TQRegion dirtyChildren;
+ bool isSettingGeometry;
+ friend class TQWSManager;
+#endif
+ static int instanceCounter; // Current number of widget instances
+ static int maxInstances; // Maximum number of widget instances
+
+ static void createMapper();
+ static void destroyMapper();
+ static TQWidgetList *wList();
+ static TQWidgetList *tlwList();
+ static TQWidgetMapper *mapper;
+ friend class TQApplication;
+ friend class TQBaseApplication;
+ friend class TQPainter;
+ friend class TQFontMetrics;
+ friend class TQFontInfo;
+ friend class TQETWidget;
+ friend class TQLayout;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQWidget( const TQWidget & );
+ TQWidget &operator=( const TQWidget & );
+#endif
+
+public: // obsolete functions to dissappear or to become inline in 3.0
+#ifndef TQT_NO_PALETTE
+ void setPalette( const TQPalette &p, bool ) { setPalette( p ); }
+#endif
+ void setFont( const TQFont &f, bool ) { setFont( f ); }
+};
+
+
+inline TQt::WState TQWidget::testWState( WState s ) const
+{ return (widget_state & s); }
+
+inline TQt::WFlags TQWidget::testWFlags( WFlags f ) const
+{ return (widget_flags & f); }
+
+
+inline WId TQWidget::winId() const
+{ return winid; }
+
+inline bool TQWidget::isTopLevel() const
+{ return testWFlags(WType_TopLevel); }
+
+inline bool TQWidget::isDialog() const
+{ return testWFlags(WType_Dialog); }
+
+inline bool TQWidget::isPopup() const
+{ return testWFlags(WType_Popup); }
+
+inline bool TQWidget::isDesktop() const
+{ return testWFlags(WType_Desktop); }
+
+inline bool TQWidget::isEnabled() const
+{ return !testWState(WState_Disabled); }
+
+inline bool TQWidget::isModal() const
+{ return testWFlags(WShowModal); }
+
+inline bool TQWidget::isEnabledToTLW() const
+{ return isEnabled(); }
+
+inline const TQRect &TQWidget::tqgeometry() const
+{ return crect; }
+
+inline TQSize TQWidget::size() const
+{ return crect.size(); }
+
+inline int TQWidget::width() const
+{ return crect.width(); }
+
+inline int TQWidget::height() const
+{ return crect.height(); }
+
+inline TQRect TQWidget::rect() const
+{ return TQRect(0,0,crect.width(),crect.height()); }
+
+inline int TQWidget::minimumWidth() const
+{ return tqminimumSize().width(); }
+
+inline int TQWidget::minimumHeight() const
+{ return tqminimumSize().height(); }
+
+inline int TQWidget::maximumWidth() const
+{ return tqmaximumSize().width(); }
+
+inline int TQWidget::maximumHeight() const
+{ return tqmaximumSize().height(); }
+
+inline void TQWidget::setMinimumSize( const TQSize &s )
+{ setMinimumSize(s.width(),s.height()); }
+
+inline void TQWidget::setMaximumSize( const TQSize &s )
+{ setMaximumSize(s.width(),s.height()); }
+
+inline void TQWidget::setSizeIncrement( const TQSize &s )
+{ setSizeIncrement(s.width(),s.height()); }
+
+inline void TQWidget::setBaseSize( const TQSize &s )
+{ setBaseSize(s.width(),s.height()); }
+
+inline const TQColor &TQWidget::eraseColor() const
+{ return bg_col; }
+
+#ifndef TQT_NO_PALETTE
+inline const TQPalette &TQWidget::palette() const
+{ return pal; }
+#endif
+
+inline TQFont TQWidget::font() const
+{ return fnt; }
+
+inline TQFontMetrics TQWidget::fontMetrics() const
+{ return TQFontMetrics(font()); }
+
+inline TQFontInfo TQWidget::fontInfo() const
+{ return TQFontInfo(font()); }
+
+inline bool TQWidget::hasMouseTracking() const
+{ return testWState(WState_MouseTracking); }
+
+inline bool TQWidget::hasMouse() const
+{ return testWState(WState_HasMouse); }
+
+inline bool TQWidget::isFocusEnabled() const
+{ return (FocusPolicy)focus_policy != NoFocus; }
+
+inline TQWidget::FocusPolicy TQWidget::focusPolicy() const
+{ return (FocusPolicy)focus_policy; }
+
+inline bool TQWidget::isUpdatesEnabled() const
+{ return !testWState(WState_BlockUpdates); }
+
+inline void TQWidget::update( const TQRect &r )
+{ update( r.x(), r.y(), r.width(), r.height() ); }
+
+inline void TQWidget::tqrepaint()
+{ tqrepaint( TRUE ); }
+
+inline void TQWidget::tqrepaint( const TQRect &r, bool erase )
+{ tqrepaint( r.x(), r.y(), r.width(), r.height(), erase ); }
+
+inline void TQWidget::erase()
+{ erase( 0, 0, crect.width(), crect.height() ); }
+
+inline void TQWidget::erase( const TQRect &r )
+{ erase( r.x(), r.y(), r.width(), r.height() ); }
+
+inline bool TQWidget::close()
+{ return close( FALSE ); }
+
+inline bool TQWidget::isVisible() const
+{ return testWState(WState_Visible); }
+
+inline bool TQWidget::isVisibleToTLW() const // obsolete
+{ return isVisible(); }
+
+inline bool TQWidget::isHidden() const
+{ return testWState(WState_ForceHide); }
+
+inline bool TQWidget::isShown() const
+{ return !testWState(WState_ForceHide); }
+
+inline void TQWidget::move( const TQPoint &p )
+{ move( p.x(), p.y() ); }
+
+inline void TQWidget::resize( const TQSize &s )
+{ resize( s.width(), s.height()); }
+
+inline void TQWidget::setGeometry( const TQRect &r )
+{ setGeometry( r.left(), r.top(), r.width(), r.height() ); }
+
+inline void TQWidget::drawText( const TQPoint &p, const TQString &s )
+{ drawText( p.x(), p.y(), s ); }
+
+inline TQWidget *TQWidget::parentWidget( bool sameWindow ) const
+{
+ if ( sameWindow )
+ return isTopLevel() ? 0 : (TQWidget *)TQObject::tqparent();
+ return (TQWidget *)TQObject::tqparent();
+}
+
+inline TQWidgetMapper *TQWidget::wmapper()
+{ return mapper; }
+
+inline uint TQWidget::getWState() const
+{ return widget_state; }
+
+inline void TQWidget::setWState( uint f )
+{ widget_state |= f; }
+
+inline void TQWidget::clearWState( uint f )
+{ widget_state &= ~f; }
+
+inline TQt::WFlags TQWidget::getWFlags() const
+{ return widget_flags; }
+
+inline void TQWidget::setWFlags( WFlags f )
+{ widget_flags |= f; }
+
+inline void TQWidget::clearWFlags( WFlags f )
+{ widget_flags &= ~f; }
+
+inline void TQWidget::constPolish() const
+{
+ if ( !testWState(WState_Polished) ) {
+ TQWidget* that = (TQWidget*) this;
+ that->polish();
+ that->setWState(WState_Polished); // be on the safe side...
+ }
+}
+#ifndef TQT_NO_CURSOR
+inline bool TQWidget::ownCursor() const
+{
+ return testWState( WState_OwnCursor );
+}
+#endif
+inline bool TQWidget::ownFont() const
+{
+ return own_font;
+}
+#ifndef TQT_NO_PALETTE
+inline bool TQWidget::ownPalette() const
+{
+ return own_palette;
+}
+#endif
+
+inline void TQWidget::tqsetSizePolicy( TQSizePolicy::SizeType hor, TQSizePolicy::SizeType ver, bool hfw )
+{
+ tqsetSizePolicy( TQSizePolicy( hor, ver, hfw) );
+}
+
+inline bool TQWidget::isInputMethodEnabled() const
+{
+ return (bool)im_enabled;
+}
+
+// Extra TQWidget data
+// - to minimize memory usage for members that are seldom used.
+// - top-level widgets have extra extra data to reduce cost further
+
+class TQFocusData;
+class TQWSManager;
+#if defined(TQ_WS_WIN)
+class TQOleDropTarget;
+#endif
+#if defined(TQ_WS_MAC)
+class TQMacDndExtra;
+#endif
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+struct TQ_EXPORT TQTLWExtra {
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ TQString caption; // widget caption
+ TQString iconText; // widget icon text
+ TQPixmap *icon; // widget icon
+#endif
+ TQFocusData *focusData; // focus data (for TLW)
+ short incw, inch; // size increments
+ // frame strut
+ ulong fleft, fright, ftop, fbottom;
+ uint unused : 8; // not used at this point...
+#if defined( TQ_WS_WIN ) || defined( TQ_WS_MAC )
+ uint opacity : 8; // Stores opacity level on Windows/Mac OS X.
+#endif
+ uint savedFlags; // Save widgetflags while showing fullscreen
+ short basew, baseh; // base sizes
+#if defined(TQ_WS_X11)
+ WId parentWinId; // tqparent window Id (valid after reparenting)
+ uint embedded : 1; // window is embedded in another TQt application
+ uint spont_unmapped: 1; // window was spontaneously unmapped
+ uint reserved: 1; // reserved
+ uint dnd : 1; // DND properties installed
+ uint uspos : 1; // User defined position
+ uint ussize : 1; // User defined size
+ void *xic; // XIM Input Context
+#endif
+#if defined(TQ_WS_MAC)
+ WindowGroupRef group;
+ uint is_moved: 1;
+ uint resizer : 4;
+#endif
+#if defined(TQ_WS_TQWS) && !defined ( TQT_NO_TQWS_MANAGER )
+ TQRegion decor_allocated_region; // decoration allocated region
+ TQWSManager *qwsManager;
+#endif
+#if defined(TQ_WS_WIN)
+ HICON winIcon; // internal Windows icon
+#endif
+ TQRect normalGeometry; // used by showMin/maximized/FullScreen
+#ifdef TQ_WS_WIN
+ uint style, exstyle;
+#endif
+};
+
+
+#define TQWIDGETSIZE_MAX 32767
+
+// dear user: you can see this struct, but it is internal. do not touch.
+
+struct TQ_EXPORT TQWExtra {
+ TQ_INT16 minw, minh; // minimum size
+ TQ_INT16 maxw, maxh; // maximum size
+ TQPixmap *bg_pix; // background pixmap
+ TQWidget *focus_proxy;
+#ifndef TQT_NO_CURSOR
+ TQCursor *curs;
+#endif
+ TQTLWExtra *topextra; // only useful for TLWs
+#if defined(TQ_WS_WIN)
+ TQOleDropTarget *dropTarget; // drop target
+#endif
+#if defined(TQ_WS_X11)
+ WId xDndProxy; // XDND forwarding to embedded windows
+#endif
+#if defined(TQ_WS_MAC)
+ TQRegion clip_saved, clip_sibs, clip_tqchildren;
+ TQMacDndExtra *macDndExtra;
+ TQRegion dirty_area;
+ uint clip_dirty : 1, clip_serial : 15;
+ uint child_dirty : 1, child_serial : 15;
+#ifndef TQMAC_NO_TQUARTZ
+ uint ctx_tqchildren_clipped:1;
+#endif // TQMAC_NO_TQUARTZ
+ uint has_dirty_area:1;
+#endif // TQ_WS_MAC
+ uint bg_origin : 2;
+#if defined(TQ_WS_X11)
+ uint tqchildren_use_dnd : 1;
+ uint compress_events : 1;
+#endif
+#if defined(TQ_WS_TQWS) || defined(TQ_WS_MAC)
+ TQRegion tqmask; // widget tqmask
+#endif
+ char bg_mode; // background mode
+ char bg_mode_visual; // visual background mode
+#ifndef TQT_NO_STYLE
+ TQStyle* style;
+#endif
+ TQRect micro_focus_hint; // micro focus hint
+ TQSizePolicy size_policy;
+};
+
+#endif // USE_QT4
+
+#define TQ_DEFINED_TQWIDGET
+#include "tqwinexport.h"
+
+#endif // TQWIDGET_H
diff --git a/tqtinterface/qt4/src/kernel/tqwidget_p.h b/tqtinterface/qt4/src/kernel/tqwidget_p.h
new file mode 100644
index 0000000..0450ac0
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwidget_p.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Definition of some TQt private functions.
+**
+** Created : 000903
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWIDGET_P_H
+#define TQWIDGET_P_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qapplication_*.cpp, qwidget*.cpp and qfiledialog.cpp. This header
+// file may change from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#endif // TQT_H
+
+#if defined (TQ_WS_X11) || defined (TQ_WS_TQWS)
+extern int qt_widget_tlw_gravity;
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqwidget_x11.cpp b/tqtinterface/qt4/src/kernel/tqwidget_x11.cpp
new file mode 100644
index 0000000..f8c605a
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwidget_x11.cpp
@@ -0,0 +1,2980 @@
+/****************************************************************************
+**
+** Implementation of TQWidget and TQWindow classes for X11
+**
+** Created : 931031
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqapplication.h"
+#include "tqapplication_p.h"
+#include "tqnamespace.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqpainter.h"
+#include "tqbitmap.h"
+#include "tqobjectlist.h"
+#include "tqlayout.h"
+#include "tqtextcodec.h"
+#include "tqdatetime.h"
+#include "tqcursor.h"
+#include "tqt_x11_p.h"
+#include <stdlib.h>
+
+#ifdef USE_QT4
+
+// defined in qapplication_x11.cpp
+extern Atom qt_wm_state;
+extern Atom qt_wm_change_state;
+extern Atom qt_wm_delete_window;
+extern Atom qt_wm_take_focus;
+extern Atom qt_wm_client_leader;
+extern Atom qt_window_role;
+extern Atom qt_sm_client_id;
+extern Atom qt_utf8_string;
+extern Atom qt_net_wm_context_help;
+extern Atom qt_net_wm_ping;
+extern Atom qt_xa_motif_wm_hints;
+extern Atom qt_net_wm_name;
+extern Atom qt_net_wm_icon_name;
+extern Atom qt_net_wm_state;
+extern Atom qt_net_wm_state_modal;
+extern Atom qt_net_wm_state_max_v;
+extern Atom qt_net_wm_state_max_h;
+extern Atom qt_net_wm_state_fullscreen;
+extern Atom qt_net_wm_state_above;
+extern Atom qt_net_wm_state_stays_on_top;
+extern Atom qt_net_wm_window_type;
+extern Atom qt_net_wm_window_type_normal;
+extern Atom qt_net_wm_window_type_dialog;
+extern Atom qt_net_wm_window_type_toolbar;
+extern Atom qt_net_wm_window_type_menu;
+extern Atom qt_net_wm_window_type_utility;
+extern Atom qt_net_wm_window_type_splash;
+extern Atom qt_net_wm_window_type_override;
+extern Atom qt_net_wm_pid;
+extern Atom qt_net_wm_user_time;
+extern Atom qt_enlightenment_desktop;
+extern Atom qt_net_virtual_roots;
+extern bool qt_broken_wm;
+
+// defined in qapplication_x11.cpp
+extern bool qt_net_supports(Atom);
+extern unsigned long *qt_net_virtual_root_list;
+
+TQ_EXPORT void qt_wait_for_window_manager( TQWidget* w )
+{
+ TQApplication::flushX();
+ XEvent ev;
+ TQTime t;
+ t.start();
+ while ( !XCheckTypedWindowEvent( w->x11Display(), w->winId(), ReparentNotify, &ev ) ) {
+ if ( XCheckTypedWindowEvent( w->x11Display(), w->winId(), MapNotify, &ev ) )
+ break;
+ if ( t.elapsed() > 500 )
+ return; // give up, no event available
+ tqApp->syncX(); // non-busy wait
+ }
+ tqApp->x11ProcessEvent( &ev );
+ if ( XCheckTypedWindowEvent( w->x11Display(), w->winId(), ConfigureNotify, &ev ) )
+ tqApp->x11ProcessEvent( &ev );
+}
+
+static void qt_net_change_wm_state(const TQWidget* w, bool set, Atom one, Atom two = 0)
+{
+ if (w->isShown()) {
+ // managed by WM
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = qt_net_wm_state;
+ e.xclient.display = const_cast<TQWidget*>(w)->x11Display();
+ e.xclient.window = w->winId();
+ e.xclient.format = 32;
+ e.xclient.data.l[ 0 ] = set ? 1 : 0;
+ e.xclient.data.l[ 1 ] = one;
+ e.xclient.data.l[ 2 ] = two;
+ e.xclient.data.l[ 3 ] = 0;
+ e.xclient.data.l[ 4 ] = 0;
+ XSendEvent(const_cast<TQWidget*>(w)->x11Display(), RootWindow(const_cast<TQWidget*>(w)->x11Display(), const_cast<TQWidget*>(w)->x11Screen()),
+ False, (SubstructureNotifyMask|SubstructureRedirectMask), &e);
+ } else {
+ Atom ret;
+ int format = 0, status;
+ unsigned char *data = 0;
+ unsigned long nitems = 0, after = 0;
+ Atom *old_states = 0;
+ status = XGetWindowProperty(const_cast<TQWidget*>(w)->x11Display(), w->winId(),
+ qt_net_wm_state, 0, 1024, False,
+ XA_ATOM, &ret, &format, &nitems,
+ &after, &data);
+ if (status == Success && ret == XA_ATOM && format == 32 && nitems > 0)
+ old_states = (Atom *) data;
+ else
+ nitems = 0;
+
+ Atom *new_states = new Atom[nitems + 2];
+ int i, j = 0;
+ for (i = 0; i < (int)nitems; ++i) {
+ if (old_states[i] && old_states[i] != one && old_states[i] != two)
+ new_states[j++] = old_states[i];
+ }
+
+ if (set) {
+ if (one) new_states[j++] = one;
+ if (two) new_states[j++] = two;
+ }
+
+ if (j)
+ XChangeProperty(const_cast<TQWidget*>(w)->x11Display(), w->winId(), qt_net_wm_state, XA_ATOM, 32,
+ PropModeReplace, (uchar *) new_states, j);
+ else
+ XDeleteProperty(const_cast<TQWidget*>(w)->x11Display(), w->winId(), qt_net_wm_state);
+
+ delete [] new_states;
+ if (data) XFree(data);
+ }
+}
+
+void TQWidget::setMask( const QRegion region )
+{
+ QWidget::setMask(region);
+}
+
+void TQWidget::setMask( const QBitmap bitmap )
+{
+ // Work around a bug in Qt4.x (including Qt4.7) where setting any pixel in either
+ // the bottom row or rightmost column of a QBitmap to Qt::color0 (i.e., transparent)
+ // will cause the entire mask to beome opaque
+ TQBitmap fixedBitmap = bitmap;
+ fixedBitmap.resize(bitmap.width()+1, bitmap.height()+1);
+ TQPainter fixerUpper(&fixedBitmap);
+ fixerUpper.setBrush(Qt::color1);
+ fixerUpper.setBackgroundMode(Qt::TransparentMode);
+ fixerUpper.drawLine(0, fixedBitmap.height()-1, fixedBitmap.width()-1, fixedBitmap.height()-1);
+ fixerUpper.drawLine(fixedBitmap.width()-1, 0, fixedBitmap.width()-1, fixedBitmap.height()-1);
+ fixerUpper.end();
+ QWidget::setMask(fixedBitmap.mask());
+}
+
+/*!
+ When a widget gets focus, it should call setMicroFocusHint() with
+ some appropriate position and size, \a x, \a y, \a width and \a
+ height. This has no \e visual effect, it just provides hints to
+ any system-specific input handling tools.
+
+ The \a text argument should be TRUE if this is a position for text
+ input.
+
+ In the Windows version of TQt, this method sets the system caret,
+ which is used for user Accessibility focus handling. If \a text
+ is TRUE, it also sets the IME composition window in Far East Asian
+ language input systems.
+
+ In the X11 version of TQt, if \a text is TRUE, this method sets the
+ XIM "spot" point for complex language input handling.
+
+ The font \a f is a rendering hint to the currently active input method.
+ If \a f is 0 the widget's font is used.
+
+ \sa microFocusHint()
+*/
+void TQWidget::setMicroFocusHint(int x, int y, int width, int height,
+ bool text, TQFont *f )
+{
+// #ifndef TQT_NO_XIM
+// if ( text ) {
+// TQWidget* tlw = tqtopLevelWidget();
+// TQTLWExtra *topdata = tlw->topData();
+//
+// // trigger input context creation if it hasn't happened already
+// createInputContext();
+// TQInputContext *qic = (TQInputContext *) topdata->xic;
+//
+// if ( qt_xim && qic ) {
+// TQPoint p( x, y );
+// TQPoint p2 = mapTo( tqtopLevelWidget(), TQPoint( 0, 0 ) );
+// p = mapTo( tqtopLevelWidget(), p);
+// qic->setXFontSet( f ? *f : fnt );
+// qic->setComposePosition(p.x(), p.y() + height);
+// qic->setComposeArea(p2.x(), p2.y(), this->width(), this->height());
+// }
+// }
+// #endif
+
+ if ( TQRect( x, y, width, height ) != microFocusHint() ) {
+ createExtra();
+ extraData()->micro_focus_hint.setRect( x, y, width, height );
+ }
+}
+
+// void TQWidget::createInputContext()
+// {
+// TQWidget *tlw = tqtopLevelWidget();
+// TQTLWExtra *topdata = tlw->topData();
+//
+// #ifndef TQT_NO_XIM
+// if (qt_xim) {
+// if (! topdata->xic) {
+// TQInputContext *qic = new TQInputContext(tlw);
+// topdata->xic = (void *) qic;
+// }
+// } else
+// #endif // TQT_NO_XIM
+// {
+// // qDebug("TQWidget::createInputContext: no xim");
+// topdata->xic = 0;
+// }
+// }
+
+/*!
+ \overload void TQWidget::drawText( const TQPoint &pos, const TQString& str )
+
+ Draws the string \a str at position \a pos.
+*/
+
+/*!
+ Draws the string \a str at position \a(x, y).
+
+ The \a y position is the base line position of the text. The text
+ is drawn using the default font and the default foreground color.
+
+ This function is provided for convenience. You will generally get
+ more flexible results and often higher speed by using a a \link
+ TQPainter painter\endlink instead.
+
+ \sa setFont(), foregroundColor(), TQPainter::drawText()
+*/
+
+void TQWidget::drawText( int x, int y, const TQString &str )
+{
+ if ( testWState(WState_Visible) ) {
+ TQPainter paint;
+ paint.begin( this );
+ paint.drawText( x, y, str );
+ paint.end();
+ }
+}
+
+#else // USE_QT4
+
+// NOT REVISED
+
+// defined in qapplication_x11.cpp
+extern Window qt_x11_wm_client_leader;
+extern void qt_x11_create_wm_client_leader();
+
+// defined in qapplication_x11.cpp
+void qt_insert_sip( TQWidget*, int, int );
+int qt_sip_count( TQWidget* );
+bool qt_wstate_iconified( WId );
+void qt_updated_rootinfo();
+
+#ifndef TQT_NO_XIM
+#include "tqinputcontext_p.h"
+
+extern XIM qt_xim;
+extern XIMStyle qt_xim_style;
+#endif
+
+// Paint event clipping magic
+extern void qt_set_paintevent_clipping( TQPaintDevice* dev, const TQRegion& region);
+extern void qt_clear_paintevent_clipping();
+
+extern bool qt_dnd_enable( TQWidget* w, bool on );
+extern bool qt_nograb();
+
+// defined in qapplication_x11.cpp
+extern void qt_deferred_map_add( TQWidget* );
+extern void qt_deferred_map_take( TQWidget* );
+extern bool qt_deferred_map_tqcontains(TQWidget *);
+
+static TQWidget *mouseGrb = 0;
+static TQWidget *keyboardGrb = 0;
+
+// defined in qfont_x11.cpp
+extern bool qt_has_xft;
+
+int qt_x11_create_desktop_on_screen = -1;
+
+/*****************************************************************************
+ TQWidget member functions
+ *****************************************************************************/
+
+// defined in qapplication_x11.cpp
+extern Atom qt_wm_state;
+extern Atom qt_wm_change_state;
+extern Atom qt_wm_delete_window;
+extern Atom qt_wm_take_focus;
+extern Atom qt_wm_client_leader;
+extern Atom qt_window_role;
+extern Atom qt_sm_client_id;
+extern Atom qt_utf8_string;
+extern Atom qt_net_wm_context_help;
+extern Atom qt_net_wm_ping;
+extern Atom qt_xa_motif_wm_hints;
+extern Atom qt_net_wm_name;
+extern Atom qt_net_wm_icon_name;
+extern Atom qt_net_wm_state;
+extern Atom qt_net_wm_state_modal;
+extern Atom qt_net_wm_state_max_v;
+extern Atom qt_net_wm_state_max_h;
+extern Atom qt_net_wm_state_fullscreen;
+extern Atom qt_net_wm_state_above;
+extern Atom qt_net_wm_state_stays_on_top;
+extern Atom qt_net_wm_window_type;
+extern Atom qt_net_wm_window_type_normal;
+extern Atom qt_net_wm_window_type_dialog;
+extern Atom qt_net_wm_window_type_toolbar;
+extern Atom qt_net_wm_window_type_menu;
+extern Atom qt_net_wm_window_type_utility;
+extern Atom qt_net_wm_window_type_splash;
+extern Atom qt_net_wm_window_type_override;
+extern Atom qt_net_wm_pid;
+extern Atom qt_net_wm_user_time;
+extern Atom qt_enlightenment_desktop;
+extern Atom qt_net_virtual_roots;
+extern bool qt_broken_wm;
+
+// defined in qapplication_x11.cpp
+extern bool qt_net_supports(Atom);
+extern unsigned long *qt_net_virtual_root_list;
+
+#if defined (TQT_TABLET_SUPPORT)
+extern XDevice *devStylus;
+extern XDevice *devEraser;
+extern XEventClass event_list_stylus[7];
+extern XEventClass event_list_eraser[7];
+extern int qt_curr_events_stylus;
+extern int qt_curr_events_eraser;
+#endif
+
+const uint stdWidgetEventMask = // X event tqmask
+ (uint)(
+ KeyPressMask | KeyReleaseMask |
+ ButtonPressMask | ButtonReleaseMask |
+ KeymapStateMask |
+ ButtonMotionMask |
+ EnterWindowMask | LeaveWindowMask |
+ FocusChangeMask |
+ ExposureMask |
+ PropertyChangeMask |
+ StructureNotifyMask
+ );
+
+const uint stdDesktopEventMask = // X event tqmask
+ (uint)(
+ KeymapStateMask |
+ EnterWindowMask | LeaveWindowMask |
+ PropertyChangeMask
+ );
+
+
+/*
+ The qt_ functions below are implemented in qwidgetcreate_x11.cpp.
+*/
+
+Window qt_XCreateWindow( const TQWidget *creator,
+ Display *display, Window tqparent,
+ int x, int y, uint w, uint h,
+ int borderwidth, int depth,
+ uint windowclass, Visual *visual,
+ ulong valuetqmask, XSetWindowAttributes *attributes );
+Window qt_XCreateSimpleWindow( const TQWidget *creator,
+ Display *display, Window tqparent,
+ int x, int y, uint w, uint h, int borderwidth,
+ ulong border, ulong background );
+void qt_XDestroyWindow( const TQWidget *destroyer,
+ Display *display, Window window );
+
+TQ_EXPORT void qt_x11_enforce_cursor( TQWidget * w )
+{
+ if ( w->testWState( TQt::WState_OwnCursor ) ) {
+ TQCursor * oc = TQApplication::overrideCursor();
+ if ( oc ) {
+ XDefineCursor( w->x11Display(), w->winId(), oc->handle() );
+ } else if ( w->isEnabled() ) {
+ XDefineCursor( w->x11Display(), w->winId(), w->cursor().handle() );
+ } else {
+ // enforce the windows behavior of clearing the cursor on
+ // disabled widgets
+ XDefineCursor( w->x11Display(), w->winId(), None );
+ }
+ } else {
+ XDefineCursor( w->x11Display(), w->winId(), None );
+ }
+}
+
+TQ_EXPORT void qt_wait_for_window_manager( TQWidget* w )
+{
+ TQApplication::flushX();
+ XEvent ev;
+ TQTime t;
+ t.start();
+ while ( !XCheckTypedWindowEvent( w->x11Display(), w->winId(), ReparentNotify, &ev ) ) {
+ if ( XCheckTypedWindowEvent( w->x11Display(), w->winId(), MapNotify, &ev ) )
+ break;
+ if ( t.elapsed() > 500 )
+ return; // give up, no event available
+ tqApp->syncX(); // non-busy wait
+ }
+ tqApp->x11ProcessEvent( &ev );
+ if ( XCheckTypedWindowEvent( w->x11Display(), w->winId(), ConfigureNotify, &ev ) )
+ tqApp->x11ProcessEvent( &ev );
+}
+
+static void qt_net_change_wm_state(const TQWidget* w, bool set, Atom one, Atom two = 0)
+{
+ if (w->isShown()) {
+ // managed by WM
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = qt_net_wm_state;
+ e.xclient.display = w->x11Display();
+ e.xclient.window = w->winId();
+ e.xclient.format = 32;
+ e.xclient.data.l[ 0 ] = set ? 1 : 0;
+ e.xclient.data.l[ 1 ] = one;
+ e.xclient.data.l[ 2 ] = two;
+ e.xclient.data.l[ 3 ] = 0;
+ e.xclient.data.l[ 4 ] = 0;
+ XSendEvent(w->x11Display(), RootWindow(w->x11Display(), w->x11Screen()),
+ False, (SubstructureNotifyMask|SubstructureRedirectMask), &e);
+ } else {
+ Atom ret;
+ int format = 0, status;
+ unsigned char *data = 0;
+ unsigned long nitems = 0, after = 0;
+ Atom *old_states = 0;
+ status = XGetWindowProperty(w->x11Display(), w->winId(),
+ qt_net_wm_state, 0, 1024, False,
+ XA_ATOM, &ret, &format, &nitems,
+ &after, &data);
+ if (status == Success && ret == XA_ATOM && format == 32 && nitems > 0)
+ old_states = (Atom *) data;
+ else
+ nitems = 0;
+
+ Atom *new_states = new Atom[nitems + 2];
+ int i, j = 0;
+ for (i = 0; i < (int)nitems; ++i) {
+ if (old_states[i] && old_states[i] != one && old_states[i] != two)
+ new_states[j++] = old_states[i];
+ }
+
+ if (set) {
+ if (one) new_states[j++] = one;
+ if (two) new_states[j++] = two;
+ }
+
+ if (j)
+ XChangeProperty(w->x11Display(), w->winId(), qt_net_wm_state, XA_ATOM, 32,
+ PropModeReplace, (uchar *) new_states, j);
+ else
+ XDeleteProperty(w->x11Display(), w->winId(), qt_net_wm_state);
+
+ delete [] new_states;
+ if (data) XFree(data);
+ }
+}
+
+/*!
+ Creates a new widget window if \a window is 0, otherwise sets the
+ widget's window to \a window.
+
+ Initializes the window (sets the tqgeometry etc.) if \a
+ initializeWindow is TRUE. If \a initializeWindow is FALSE, no
+ initialization is performed. This parameter only makes sense if \a
+ window is a valid window.
+
+ Destroys the old window if \a destroyOldWindow is TRUE. If \a
+ destroyOldWindow is FALSE, you are responsible for destroying the
+ window yourself (using platform native code).
+
+ The TQWidget constructor calls create(0,TRUE,TRUE) to create a
+ window for this widget.
+*/
+
+void TQWidget::create( WId window, bool initializeWindow, bool destroyOldWindow)
+{
+ if ( testWState(WState_Created) && window == 0 )
+ return;
+
+ // set created flag
+ setWState( WState_Created );
+
+ bool popup = testWFlags(WType_Popup);
+ bool dialog = testWFlags(WType_Dialog);
+ bool desktop = testWFlags(WType_Desktop);
+
+ // top-level widget
+ if ( !parentWidget() || parentWidget()->isDesktop() )
+ setWFlags( WType_TopLevel );
+
+ // these are top-level, too
+ if ( dialog || popup || desktop || testWFlags(WStyle_Splash))
+ setWFlags( WType_TopLevel );
+
+ // a popup stays on top
+ if ( popup )
+ setWFlags(WStyle_StaysOnTop);
+
+ bool topLevel = testWFlags(WType_TopLevel);
+ Window parentw, destroyw = 0;
+ WId id;
+
+ // always initialize
+ if ( !window )
+ initializeWindow = TRUE;
+
+ if ( desktop &&
+ qt_x11_create_desktop_on_screen >= 0 &&
+ qt_x11_create_desktop_on_screen != x11Screen() ) {
+ // desktop on a certain screen other than the default requested
+ TQPaintDeviceX11Data* xd = getX11Data( TRUE );
+ xd->x_screen = qt_x11_create_desktop_on_screen;
+ xd->x_depth = TQPaintDevice::x11AppDepth( xd->x_screen );
+ xd->x_cells = TQPaintDevice::x11AppCells( xd->x_screen );
+ xd->x_colormap = TQPaintDevice::x11AppColormap( xd->x_screen );
+ xd->x_defcolormap = TQPaintDevice::x11AppDefaultColormap( xd->x_screen );
+ xd->x_visual = TQPaintDevice::x11AppVisual( xd->x_screen );
+ xd->x_defvisual = TQPaintDevice::x11AppDefaultVisual( xd->x_screen );
+ setX11Data( xd );
+ } else if ( parentWidget() && parentWidget()->x11Screen() != x11Screen() ) {
+ // if we have a tqparent widget, move to its screen if necessary
+ TQPaintDeviceX11Data* xd = getX11Data( TRUE );
+ xd->x_screen = parentWidget()->x11Screen();
+ xd->x_depth = TQPaintDevice::x11AppDepth( xd->x_screen );
+ xd->x_cells = TQPaintDevice::x11AppCells( xd->x_screen );
+ xd->x_colormap = TQPaintDevice::x11AppColormap( xd->x_screen );
+ xd->x_defcolormap = TQPaintDevice::x11AppDefaultColormap( xd->x_screen );
+ xd->x_visual = TQPaintDevice::x11AppVisual( xd->x_screen );
+ xd->x_defvisual = TQPaintDevice::x11AppDefaultVisual( xd->x_screen );
+ setX11Data( xd );
+ }
+
+ //get display, screen number, root window and desktop tqgeometry for
+ //the current screen
+ Display *dpy = x11Display();
+ int scr = x11Screen();
+ Window root_win = RootWindow( dpy, scr );
+ int sw = DisplayWidth(dpy,scr);
+ int sh = DisplayHeight(dpy,scr);
+
+ if ( desktop ) { // desktop widget
+ dialog = popup = FALSE; // force these flags off
+ crect.setRect( 0, 0, sw, sh );
+ } else if ( topLevel ) { // calc pos/size from screen
+ crect.setRect( sw/4, 3*sh/10, sw/2, 4*sh/10 );
+ } else { // child widget
+ crect.setRect( 0, 0, 100, 30 );
+ }
+
+ parentw = topLevel ? root_win : parentWidget()->winId();
+
+ XSetWindowAttributes wsa;
+
+ if ( window ) { // override the old window
+ if ( destroyOldWindow )
+ destroyw = winid;
+ id = window;
+ setWinId( window );
+ XWindowAttributes a;
+ XGetWindowAttributes( dpy, window, &a );
+ crect.setRect( a.x, a.y, a.width, a.height );
+
+ if ( a.map_state == IsUnmapped )
+ clearWState( WState_Visible );
+ else
+ setWState( WState_Visible );
+
+ TQPaintDeviceX11Data* xd = getX11Data( TRUE );
+
+ // tqfind which screen the window is on...
+ xd->x_screen = TQPaintDevice::x11AppScreen(); // by default, use the default :)
+ int i;
+ for ( i = 0; i < ScreenCount( dpy ); i++ ) {
+ if ( RootWindow( dpy, i ) == a.root ) {
+ xd->x_screen = i;
+ break;
+ }
+ }
+
+ xd->x_depth = a.depth;
+ xd->x_cells = DisplayCells( dpy, xd->x_screen );
+ xd->x_visual = a.visual;
+ xd->x_defvisual = ( XVisualIDFromVisual( a.visual ) ==
+ XVisualIDFromVisual( (Visual*)x11AppVisual(x11Screen()) ) );
+ xd->x_colormap = a.colormap;
+ xd->x_defcolormap = ( a.colormap == x11AppColormap( x11Screen() ) );
+ setX11Data( xd );
+ } else if ( desktop ) { // desktop widget
+ id = (WId)parentw; // id = root window
+ TQWidget *otherDesktop = tqfind( id ); // is there another desktop?
+ if ( otherDesktop && otherDesktop->testWFlags(WPaintDesktop) ) {
+ otherDesktop->setWinId( 0 ); // remove id from widget mapper
+ setWinId( id ); // make sure otherDesktop is
+ otherDesktop->setWinId( id ); // found first
+ } else {
+ setWinId( id );
+ }
+ } else {
+ if ( x11DefaultVisual() && x11DefaultColormap() ) {
+ id = (WId)qt_XCreateSimpleWindow( this, dpy, parentw,
+ crect.left(), crect.top(),
+ crect.width(), crect.height(),
+ 0,
+ black.pixel(x11Screen()),
+ bg_col.pixel(x11Screen()) );
+ } else {
+ wsa.background_pixel = bg_col.pixel(x11Screen());
+ wsa.border_pixel = black.pixel(x11Screen());
+ wsa.colormap = (Colormap)x11Colormap();
+ id = (WId)qt_XCreateWindow( this, dpy, parentw,
+ crect.left(), crect.top(),
+ crect.width(), crect.height(),
+ 0, x11Depth(), InputOutput,
+ (Visual*)x11Visual(),
+ CWBackPixel|CWBorderPixel|CWColormap,
+ &wsa );
+ }
+
+ setWinId( id ); // set widget id/handle + hd
+ }
+
+#ifndef TQT_NO_XFTFREETYPE
+ if (rendhd) {
+ XftDrawDestroy( (XftDraw *) rendhd );
+ rendhd = 0;
+ }
+
+ if ( qt_has_xft )
+ rendhd = (HANDLE) XftDrawCreate( dpy, id, (Visual *) x11Visual(),
+ x11Colormap() );
+#endif // TQT_NO_XFTFREETYPE
+
+ // NET window types
+ long net_wintypes[7] = { 0, 0, 0, 0, 0, 0, 0 };
+ int curr_wintype = 0;
+
+ // NET window states
+ long net_winstates[6] = { 0, 0, 0, 0, 0, 0 };
+ int curr_winstate = 0;
+
+ struct {
+ ulong flags, functions, decorations;
+ long input_mode;
+ ulong status;
+ } mwmhints;
+
+ mwmhints.flags = mwmhints.functions = 0L;
+ mwmhints.decorations = (1L << 0); // MWM_DECOR_ALL
+ mwmhints.input_mode = 0L;
+ mwmhints.status = 0L;
+
+ if (topLevel && ! (desktop || popup)) {
+ ulong wsa_mask = 0;
+
+ if ( testWFlags(WStyle_Splash) ) {
+ if (qt_net_supports(qt_net_wm_window_type_splash)) {
+ clearWFlags( WX11BypassWM );
+ net_wintypes[curr_wintype++] = qt_net_wm_window_type_splash;
+ } else {
+ setWFlags( WX11BypassWM | WStyle_Tool | WStyle_NoBorder );
+ }
+ }
+ if (testWFlags(WStyle_Customize)) {
+ mwmhints.decorations = 0L;
+ mwmhints.flags |= (1L << 1); // MWM_HINTS_DECORATIONS
+
+ if ( testWFlags( WStyle_NoBorder ) ) {
+ // override netwm type - quick and easy for KDE noborder
+ net_wintypes[curr_wintype++] = qt_net_wm_window_type_override;
+ } else {
+ if ( testWFlags( WStyle_NormalBorder | WStyle_DialogBorder ) ) {
+ mwmhints.decorations |= (1L << 1); // MWM_DECOR_BORDER
+ mwmhints.decorations |= (1L << 2); // MWM_DECOR_RESIZEH
+ }
+
+ if ( testWFlags( WStyle_Title ) )
+ mwmhints.decorations |= (1L << 3); // MWM_DECOR_TITLE
+
+ if ( testWFlags( WStyle_SysMenu ) )
+ mwmhints.decorations |= (1L << 4); // MWM_DECOR_MENU
+
+ if ( testWFlags( WStyle_Minimize ) )
+ mwmhints.decorations |= (1L << 5); // MWM_DECOR_MINIMIZE
+
+ if ( testWFlags( WStyle_Maximize ) )
+ mwmhints.decorations |= (1L << 6); // MWM_DECOR_MAXIMIZE
+ }
+
+ if (testWFlags(WStyle_Tool)) {
+ wsa.save_under = True;
+ wsa_mask |= CWSaveUnder;
+ }
+ } else if (testWFlags(WType_Dialog)) {
+ setWFlags(WStyle_NormalBorder | WStyle_Title |
+ WStyle_SysMenu | WStyle_ContextHelp);
+ } else {
+ setWFlags(WStyle_NormalBorder | WStyle_Title |
+ WStyle_MinMax | WStyle_SysMenu);
+
+ // maximized netwm state
+ if (testWFlags(WState_Maximized)) {
+ net_winstates[curr_winstate++] = qt_net_wm_state_max_v;
+ net_winstates[curr_winstate++] = qt_net_wm_state_max_h;
+ }
+ }
+
+ // ### need a better way to do this
+ if (inherits("TQPopupMenu")) {
+ // menu netwm type
+ net_wintypes[curr_wintype++] = qt_net_wm_window_type_menu;
+ } else if (inherits("TQToolBar")) {
+ // toolbar netwm type
+ net_wintypes[curr_wintype++] = qt_net_wm_window_type_toolbar;
+ } else if (testWFlags(WStyle_Customize) && testWFlags(WStyle_Tool)) {
+ // utility netwm type
+ net_wintypes[curr_wintype++] = qt_net_wm_window_type_utility;
+ }
+
+ if (dialog) // dialog netwm type
+ net_wintypes[curr_wintype++] = qt_net_wm_window_type_dialog;
+ // normal netwm type - default
+ net_wintypes[curr_wintype++] = qt_net_wm_window_type_normal;
+
+ // stays on top
+ if (testWFlags(WStyle_StaysOnTop)) {
+ net_winstates[curr_winstate++] = qt_net_wm_state_above;
+ net_winstates[curr_winstate++] = qt_net_wm_state_stays_on_top;
+ }
+
+ if (testWFlags(WShowModal)) {
+ mwmhints.input_mode = 3L; // MWM_INPUT_FULL_APPLICATION_MODAL
+ mwmhints.flags |= (1L << 2); // MWM_HINTS_INPUT_MODE
+
+ net_winstates[curr_winstate++] = qt_net_wm_state_modal;
+ }
+
+ if ( testWFlags( WX11BypassWM ) ) {
+ wsa.override_redirect = True;
+ wsa_mask |= CWOverrideRedirect;
+ }
+
+ if ( wsa_mask && initializeWindow )
+ XChangeWindowAttributes( dpy, id, wsa_mask, &wsa );
+ } else {
+ if (! testWFlags(WStyle_Customize))
+ setWFlags(WStyle_NormalBorder | WStyle_Title |
+ WStyle_MinMax | WStyle_SysMenu);
+ }
+
+
+ if ( !initializeWindow ) {
+ // do no initialization
+ } else if ( popup ) { // popup widget
+ wsa.override_redirect = True;
+ wsa.save_under = True;
+ XChangeWindowAttributes( dpy, id, CWOverrideRedirect | CWSaveUnder,
+ &wsa );
+ } else if ( topLevel && !desktop ) { // top-level widget
+ TQWidget *p = parentWidget(); // real tqparent
+ if (p)
+ p = p->tqtopLevelWidget();
+
+ if (dialog || testWFlags(WStyle_DialogBorder) || testWFlags(WStyle_Tool)) {
+ if ( p )
+ XSetTransientForHint( dpy, id, p->winId() );
+ else // application-modal
+ XSetTransientForHint( dpy, id, root_win );
+ }
+
+ // tqfind the real client leader, i.e. a toplevel without tqparent
+ while ( p && p->parentWidget())
+ p = p->parentWidget()->tqtopLevelWidget();
+
+ XSizeHints size_hints;
+ size_hints.flags = USSize | PSize | PWinGravity;
+ size_hints.x = crect.left();
+ size_hints.y = crect.top();
+ size_hints.width = crect.width();
+ size_hints.height = crect.height();
+ size_hints.win_gravity =
+ TQApplication::reverseLayout() ? NorthEastGravity : NorthWestGravity;
+
+ XWMHints wm_hints; // window manager hints
+ wm_hints.input = True;
+ wm_hints.initial_state = NormalState;
+ wm_hints.flags = InputHint | StateHint;
+ if ( !qt_x11_wm_client_leader )
+ qt_x11_create_wm_client_leader();
+
+ wm_hints.window_group = qt_x11_wm_client_leader;
+ wm_hints.flags |= WindowGroupHint;
+
+ XClassHint class_hint;
+ class_hint.res_name = (char *) tqAppName(); // application name
+ class_hint.res_class = (char *) tqAppClass(); // application class
+
+ XSetWMProperties( dpy, id, 0, 0, 0, 0, &size_hints, &wm_hints, &class_hint );
+
+ XResizeWindow( dpy, id, crect.width(), crect.height() );
+ XStoreName( dpy, id, tqAppName() );
+ Atom protocols[4];
+ int n = 0;
+ protocols[n++] = qt_wm_delete_window; // support del window protocol
+ protocols[n++] = qt_wm_take_focus; // support take focus window protocol
+ protocols[n++] = qt_net_wm_ping; // support _NET_WM_PING protocol
+ if ( testWFlags( WStyle_ContextHelp ) )
+ protocols[n++] = qt_net_wm_context_help;
+ XSetWMProtocols( dpy, id, protocols, n );
+
+ // set mwm hints
+ if ( mwmhints.flags != 0l )
+ XChangeProperty(dpy, id, qt_xa_motif_wm_hints, qt_xa_motif_wm_hints, 32,
+ PropModeReplace, (unsigned char *) &mwmhints, 5);
+ else
+ XDeleteProperty(dpy, id, qt_xa_motif_wm_hints);
+
+ // set _NET_WM_WINDOW_TYPE
+ if (curr_wintype > 0)
+ XChangeProperty(dpy, id, qt_net_wm_window_type, XA_ATOM, 32, PropModeReplace,
+ (unsigned char *) net_wintypes, curr_wintype);
+ else
+ XDeleteProperty(dpy, id, qt_net_wm_window_type);
+
+ // set _NET_WM_WINDOW_STATE
+ if (curr_winstate > 0)
+ XChangeProperty(dpy, id, qt_net_wm_state, XA_ATOM, 32, PropModeReplace,
+ (unsigned char *) net_winstates, curr_winstate);
+ else
+ XDeleteProperty(dpy, id, qt_net_wm_state);
+
+ // set _NET_WM_PID
+ long curr_pid = getpid();
+ XChangeProperty(dpy, id, qt_net_wm_pid, XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) &curr_pid, 1);
+
+ // when we create a toplevel widget, the frame strut should be dirty
+ fstrut_dirty = 1;
+
+ // declare the widget's object name as window role
+ XChangeProperty( dpy, id,
+ qt_window_role, XA_STRING, 8, PropModeReplace,
+ (unsigned char *)name(), tqstrlen( name() ) );
+
+ // set client leader property
+ XChangeProperty( dpy, id, qt_wm_client_leader,
+ XA_WINDOW, 32, PropModeReplace,
+ (unsigned char *)&qt_x11_wm_client_leader, 1 );
+ } else {
+ // non-toplevel widgets don't have a frame, so no need to
+ // update the strut
+ fstrut_dirty = 0;
+ }
+
+ if ( initializeWindow ) {
+ // don't erase when resizing
+ wsa.bit_gravity =
+ TQApplication::reverseLayout() ? NorthEastGravity : NorthWestGravity;
+ XChangeWindowAttributes( dpy, id, CWBitGravity, &wsa );
+ }
+
+ setWState( WState_MouseTracking );
+ setMouseTracking( FALSE ); // also sets event tqmask
+ if ( desktop ) {
+ setWState( WState_Visible );
+ } else if ( topLevel ) { // set X cursor
+ setWState( WState_OwnCursor );
+ if ( initializeWindow )
+ qt_x11_enforce_cursor( this );
+ }
+
+ if ( destroyw )
+ qt_XDestroyWindow( this, dpy, destroyw );
+}
+
+
+/*!
+ Frees up window system resources. Destroys the widget window if \a
+ destroyWindow is TRUE.
+
+ destroy() calls itself recursively for all the child widgets,
+ passing \a destroySubWindows for the \a destroyWindow parameter.
+ To have more control over destruction of subwidgets, destroy
+ subwidgets selectively first.
+
+ This function is usually called from the TQWidget destructor.
+*/
+
+void TQWidget::destroy( bool destroyWindow, bool destroySubWindows )
+{
+ deactivateWidgetCleanup();
+ if ( testWState(WState_Created) ) {
+ clearWState( WState_Created );
+ if ( childrenListObject() ) {
+ TQObjectListIt it(*childrenListObject());
+ register TQObject *obj;
+ while ( (obj=it.current()) ) { // destroy all widget tqchildren
+ ++it;
+ if ( obj->isWidgetType() )
+ ((TQWidget*)obj)->destroy(destroySubWindows,
+ destroySubWindows);
+ }
+ }
+ if ( mouseGrb == this )
+ releaseMouse();
+ if ( keyboardGrb == this )
+ releaseKeyboard();
+ if ( isTopLevel() )
+ qt_deferred_map_take( this );
+ if ( testWFlags(WShowModal) ) // just be sure we leave modal
+ qt_leave_modal( this );
+ else if ( testWFlags(WType_Popup) )
+ tqApp->closePopup( this );
+
+#ifndef TQT_NO_XFTFREETYPE
+ if ( rendhd) {
+ if ( destroyWindow )
+ XftDrawDestroy( (XftDraw *) rendhd );
+ else
+ free( (void*) rendhd );
+ rendhd = 0;
+ }
+#endif // TQT_NO_XFTFREETYPE
+
+ if ( testWFlags(WType_Desktop) ) {
+ if ( acceptDrops() )
+ qt_dnd_enable( this, FALSE );
+ } else {
+ if ( destroyWindow )
+ qt_XDestroyWindow( this, x11Display(), winid );
+ }
+ setWinId( 0 );
+
+ extern void qPRCleanup( TQWidget *widget ); // from qapplication_x11.cpp
+ if ( testWState(WState_Reparented) )
+ qPRCleanup(this);
+ }
+}
+
+void TQWidget::reparentSys( TQWidget *tqparent, WFlags f, const TQPoint &p, bool showIt )
+{
+ extern void qPRCreate( const TQWidget *, Window );
+
+ Display *dpy = x11Display();
+ TQCursor oldcurs;
+ bool setcurs = testWState(WState_OwnCursor);
+ if ( setcurs ) {
+ oldcurs = cursor();
+ unsetCursor();
+ }
+
+ // dnd unregister (we will register again below)
+ bool accept_drops = acceptDrops();
+ setAcceptDrops( FALSE );
+
+ // clear mouse tracking, re-enabled below
+ bool mouse_tracking = hasMouseTracking();
+ clearWState(WState_MouseTracking);
+
+ TQWidget* oldtlw = tqtopLevelWidget();
+ TQWidget *oldtqparent = parentWidget();
+ WId old_winid = winid;
+ if ( testWFlags(WType_Desktop) )
+ old_winid = 0;
+ setWinId( 0 );
+
+ // hide and reparent our own window away. Otherwise we might get
+ // destroyed when emitting the child remove event below. See TQWorkspace.
+ XUnmapWindow( x11Display(), old_winid );
+ XReparentWindow( x11Display(), old_winid,
+ RootWindow( x11Display(), x11Screen() ), 0, 0 );
+
+ if ( isTopLevel() ) {
+ // input contexts are associated with toplevel widgets, so we need
+ // destroy the context here. if we are reparenting back to toplevel,
+ // then we will have another context created, otherwise we will
+ // use our new toplevel's context
+ destroyInputContext();
+ }
+
+ if ( isTopLevel() || !tqparent ) // we are toplevel, or reparenting to toplevel
+ topData()->parentWinId = 0;
+
+ if ( tqparent != parentObj ) {
+ if ( parentObj ) // remove from tqparent
+ parentObj->removeChild( this );
+ if ( tqparent ) // insert into new tqparent
+ tqparent->insertChild( this );
+ }
+ bool enable = isEnabled(); // remember status
+ FocusPolicy fp = focusPolicy();
+ TQSize s = size();
+ TQPixmap *bgp = (TQPixmap *)backgroundPixmap();
+ TQColor bgc = bg_col; // save colors
+ TQString capt= caption();
+ widget_flags = f;
+ clearWState( WState_Created | WState_Visible | WState_ForceHide );
+ create();
+ if ( isTopLevel() || (!tqparent || tqparent->isVisible() ) )
+ setWState( WState_ForceHide ); // new widgets do not show up in already visible parents
+
+ const TQObjectList *chlist = childrenListObject();
+ if ( chlist ) { // reparent tqchildren
+ TQObjectList childList(*chlist);
+ TQObjectListIt it(childList); // iterate over copy
+ TQObject *obj;
+ while ( (obj=it.current()) ) {
+ if ( obj->isWidgetType() ) {
+ TQWidget *w = (TQWidget *)obj;
+ if ( !w->isTopLevel() ) {
+ XReparentWindow( x11Display(), w->winId(), winId(),
+ w->tqgeometry().x(), w->tqgeometry().y() );
+ } else if ( w->isPopup()
+ || w->testWFlags(WStyle_DialogBorder)
+ || w->testWFlags(WType_Dialog)
+ || w->testWFlags(WStyle_Tool) ) {
+ /*
+ when reparenting toplevel windows with toplevel-transient tqchildren,
+ we need to make sure that the window manager gets the updated
+ WM_TRANSIENT_FOR information... unfortunately, some window managers
+ don't handle changing WM_TRANSIENT_FOR before the toplevel window is
+ visible, so we unmap and remap all toplevel-transient tqchildren *after*
+ the toplevel tqparent has been mapped. thankfully, this is easy in TQt :)
+ */
+ XUnmapWindow(w->x11Display(), w->winId());
+ XSetTransientForHint(w->x11Display(), w->winId(), winId());
+ TQApplication::postEvent(w, new TQEvent(TQEvent::ShowWindowRequest));
+ }
+ }
+ ++it;
+ }
+ }
+ qPRCreate( this, old_winid );
+ if ( bgp )
+ XSetWindowBackgroundPixmap( dpy, winid, bgp->handle() );
+ else
+ XSetWindowBackground( dpy, winid, bgc.pixel(x11Screen()) );
+
+ if (isTopLevel()) {
+ // preserve maximized/fullscreen flags and the normal tqgeometry
+ uint save_state = widget_state & (WState_Maximized | WState_FullScreen);
+ const TQRect r = topData()->normalGeometry;
+ setGeometry(p.x(), p.y(), s.width(), s.height());
+ widget_state |= save_state;
+ topData()->normalGeometry = r;
+ } else {
+ setGeometry(p.x(), p.y(), s.width(), s.height());
+ }
+
+ setEnabled( enable );
+ setFocusPolicy( fp );
+ if ( !capt.isNull() ) {
+ extra->topextra->caption = TQString::null;
+ setCaption( capt );
+ }
+ if ( showIt )
+ show();
+ if ( old_winid )
+ qt_XDestroyWindow( this, dpy, old_winid );
+ if ( setcurs )
+ setCursor(oldcurs);
+
+ reparentFocusWidgets( oldtlw );
+
+ // re-register dnd
+ if (oldtqparent)
+ oldtqparent->checkChildrenDnd();
+
+ if ( accept_drops )
+ setAcceptDrops( TRUE );
+ else {
+ checkChildrenDnd();
+ topData()->dnd = 0;
+ qt_dnd_enable(this, (extra && extra->tqchildren_use_dnd));
+ }
+
+ // re-enable mouse tracking
+ if (mouse_tracking)
+ setMouseTracking(mouse_tracking);
+}
+
+
+/*!
+ Translates the widget coordinate \a pos to global screen
+ coordinates. For example, \c{mapToGlobal(TQPoint(0,0))} would give
+ the global coordinates of the top-left pixel of the widget.
+
+ \sa mapFromGlobal() mapTo() mapToParent()
+*/
+
+TQPoint TQWidget::mapToGlobal( const TQPoint &pos ) const
+{
+ int x, y;
+ Window child;
+ XTranslateCoordinates( x11Display(), winId(),
+ TQApplication::desktop()->screen(x11Screen())->winId(),
+ pos.x(), pos.y(), &x, &y, &child );
+ return TQPoint( x, y );
+}
+
+/*!
+ Translates the global screen coordinate \a pos to widget
+ coordinates.
+
+ \sa mapToGlobal() mapFrom() mapFromParent()
+*/
+
+TQPoint TQWidget::mapFromGlobal( const TQPoint &pos ) const
+{
+ int x, y;
+ Window child;
+ XTranslateCoordinates( x11Display(),
+ TQApplication::desktop()->screen(x11Screen())->winId(),
+ winId(), pos.x(), pos.y(), &x, &y, &child );
+ return TQPoint( x, y );
+}
+
+/*!
+ When a widget gets focus, it should call setMicroFocusHint() with
+ some appropriate position and size, \a x, \a y, \a width and \a
+ height. This has no \e visual effect, it just provides hints to
+ any system-specific input handling tools.
+
+ The \a text argument should be TRUE if this is a position for text
+ input.
+
+ In the Windows version of TQt, this method sets the system caret,
+ which is used for user Accessibility focus handling. If \a text
+ is TRUE, it also sets the IME composition window in Far East Asian
+ language input systems.
+
+ In the X11 version of TQt, if \a text is TRUE, this method sets the
+ XIM "spot" point for complex language input handling.
+
+ The font \a f is a rendering hint to the currently active input method.
+ If \a f is 0 the widget's font is used.
+
+ \sa microFocusHint()
+*/
+void TQWidget::setMicroFocusHint(int x, int y, int width, int height,
+ bool text, TQFont *f )
+{
+#ifndef TQT_NO_XIM
+ if ( text ) {
+ TQWidget* tlw = tqtopLevelWidget();
+ TQTLWExtra *topdata = tlw->topData();
+
+ // trigger input context creation if it hasn't happened already
+ createInputContext();
+ TQInputContext *qic = (TQInputContext *) topdata->xic;
+
+ if ( qt_xim && qic ) {
+ TQPoint p( x, y );
+ TQPoint p2 = mapTo( tqtopLevelWidget(), TQPoint( 0, 0 ) );
+ p = mapTo( tqtopLevelWidget(), p);
+ qic->setXFontSet( f ? *f : fnt );
+ qic->setComposePosition(p.x(), p.y() + height);
+ qic->setComposeArea(p2.x(), p2.y(), this->width(), this->height());
+ }
+ }
+#endif
+
+ if ( TQRect( x, y, width, height ) != microFocusHint() ) {
+ createExtra();
+ extraData()->micro_focus_hint.setRect( x, y, width, height );
+ }
+}
+
+
+void TQWidget::setFontSys( TQFont * )
+{
+ // Nothing
+}
+
+
+void TQWidget::setBackgroundColorDirect( const TQColor &color )
+{
+ bg_col = color;
+ if ( extra && extra->bg_pix ) { // kill the background pixmap
+ delete extra->bg_pix;
+ extra->bg_pix = 0;
+ }
+ XSetWindowBackground( x11Display(), winId(), bg_col.pixel(x11Screen()) );
+}
+
+static int allow_null_pixmaps = 0;
+
+
+void TQWidget::setBackgroundPixmapDirect( const TQPixmap &pixmap )
+{
+ TQPixmap old;
+ if ( extra && extra->bg_pix )
+ old = *extra->bg_pix;
+ if ( !allow_null_pixmaps && pixmap.isNull() ) {
+ XSetWindowBackground( x11Display(), winId(), bg_col.pixel(x11Screen()) );
+ if ( extra && extra->bg_pix ) {
+ delete extra->bg_pix;
+ extra->bg_pix = 0;
+ }
+ } else {
+ TQPixmap pm = pixmap;
+ if (!pm.isNull()) {
+ if ( pm.depth() == 1 && TQPixmap::defaultDepth() > 1 ) {
+ pm = TQPixmap( pixmap.size() );
+ bitBlt( &pm, 0, 0, &pixmap, 0, 0, pm.width(), pm.height() );
+ }
+ }
+ if ( extra && extra->bg_pix )
+ delete extra->bg_pix;
+ else
+ createExtra();
+ extra->bg_pix = new TQPixmap( pm );
+ TQ_CHECK_PTR( extra->bg_pix );
+ extra->bg_pix->x11SetScreen( x11Screen() );
+ XSetWindowBackgroundPixmap( x11Display(), winId(), extra->bg_pix->handle() );
+ if ( testWFlags(WType_Desktop) ) // save rootinfo later
+ qt_updated_rootinfo();
+ }
+}
+
+
+/*!
+ Sets the window-system background of the widget to nothing.
+
+ Note that "nothing" is actually a pixmap that isNull(), thus you
+ can check for an empty background by checking backgroundPixmap().
+
+ \sa setBackgroundPixmap(), setBackgroundColor()
+*/
+void TQWidget::setBackgroundEmpty()
+{
+ allow_null_pixmaps++;
+ setErasePixmap(TQPixmap());
+ allow_null_pixmaps--;
+}
+
+
+void TQWidget::setBackgroundX11Relative()
+{
+ XSetWindowBackgroundPixmap( x11Display(), winId(), ParentRelative );
+}
+
+void TQWidget::setCursor( const TQCursor &cursor )
+{
+ if ( cursor.handle() != arrowCursor.handle()
+ || (extra && extra->curs) ) {
+ createExtra();
+ delete extra->curs;
+ extra->curs = new TQCursor(cursor);
+ }
+ setWState( WState_OwnCursor );
+ qt_x11_enforce_cursor( this );
+ XFlush( x11Display() );
+}
+
+void TQWidget::unsetCursor()
+{
+ if ( extra ) {
+ delete extra->curs;
+ extra->curs = 0;
+ }
+ if ( !isTopLevel() )
+ clearWState( WState_OwnCursor );
+ qt_x11_enforce_cursor( this );
+ XFlush( x11Display() );
+}
+
+static XTextProperty*
+qstring_to_xtp( const TQString& s )
+{
+ static XTextProperty tp = { 0, 0, 0, 0 };
+ static bool free_prop = TRUE; // we can't free tp.value in case it references
+ // the data of the static TQCString below.
+ if ( tp.value ) {
+ if ( free_prop )
+ XFree( tp.value );
+ tp.value = 0;
+ free_prop = TRUE;
+ }
+
+ static const TQTextCodec* mapper = TQTextCodec::codecForLocale();
+ int errCode = 0;
+ if ( mapper ) {
+ TQCString mapped = mapper->fromUnicode(s);
+ char* tl[2];
+ tl[0] = mapped.data();
+ tl[1] = 0;
+ errCode = XmbTextListToTextProperty( TQPaintDevice::x11AppDisplay(),
+ tl, 1, XStdICCTextStyle, &tp );
+#if defined(TQT_DEBUG)
+ if ( errCode < 0 )
+ qDebug( "qstring_to_xtp result code %d", errCode );
+#endif
+ }
+ if ( !mapper || errCode < 0 ) {
+ static TQCString qcs;
+ qcs = s.ascii();
+ tp.value = (uchar*)qcs.data();
+ tp.encoding = XA_STRING;
+ tp.format = 8;
+ tp.nitems = qcs.length();
+ free_prop = FALSE;
+ }
+
+ // ### If we knew WM could understand tqunicode, we could use
+ // ### a much simpler, cheaper encoding...
+ /*
+ tp.value = (XChar2b*)s.tqunicode();
+ tp.encoding = XA_UNICODE; // wish
+ tp.format = 16;
+ tp.nitems = s.length();
+ */
+
+ return &tp;
+}
+
+void TQWidget::setCaption( const TQString &caption )
+{
+ if ( TQWidget::caption() == caption )
+ return;
+
+ topData()->caption = caption;
+ XSetWMName( x11Display(), winId(), qstring_to_xtp(caption) );
+
+ TQCString net_wm_name = caption.utf8();
+ XChangeProperty(x11Display(), winId(), qt_net_wm_name, qt_utf8_string, 8,
+ PropModeReplace, (unsigned char *)net_wm_name.data(),
+ net_wm_name.length());
+
+ TQEvent e( TQEvent::CaptionChange );
+ TQApplication::sendEvent( this, &e );
+}
+
+void TQWidget::setIcon( const TQPixmap &pixmap )
+{
+ if ( extra && extra->topextra ) {
+ delete extra->topextra->icon;
+ extra->topextra->icon = 0;
+ } else {
+ createTLExtra();
+ }
+ Pixmap icon_pixmap = 0;
+ Pixmap mask_pixmap = 0;
+ if ( !pixmap.isNull() ) {
+ TQPixmap* pm = new TQPixmap( pixmap );
+ extra->topextra->icon = pm;
+ if ( !pm->tqmask() )
+ pm->setMask( pm->createHeuristicMask() ); // may do detach()
+ icon_pixmap = pm->handle();
+ if ( pm->tqmask() )
+ mask_pixmap = pm->tqmask()->handle();
+ }
+ XWMHints *h = XGetWMHints( x11Display(), winId() );
+ XWMHints wm_hints;
+ bool got_hints = h != 0;
+ if ( !got_hints ) {
+ h = &wm_hints;
+ h->flags = 0;
+ }
+ h->icon_pixmap = icon_pixmap;
+ h->icon_mask = mask_pixmap;
+ h->flags |= IconPixmapHint | IconMaskHint;
+ XSetWMHints( x11Display(), winId(), h );
+ if ( got_hints )
+ XFree( (char *)h );
+ TQEvent e( TQEvent::IconChange );
+ TQApplication::sendEvent( this, &e );
+}
+
+void TQWidget::setIconText( const TQString &iconText )
+{
+ if (TQWidget::iconText() == iconText)
+ return;
+
+ topData()->iconText = iconText;
+ XSetWMIconName( x11Display(), winId(), qstring_to_xtp(iconText) );
+
+ TQCString net_wm_icon_name = iconText.utf8();
+ XChangeProperty(x11Display(), winId(), qt_net_wm_icon_name, qt_utf8_string, 8, PropModeReplace,
+ (unsigned char *) net_wm_icon_name.data(), net_wm_icon_name.length());
+}
+
+void TQWidget::setMouseTracking( bool enable )
+{
+ bool gmt = TQApplication::hasGlobalMouseTracking();
+ if ( !enable == !testWState(WState_MouseTracking) && !gmt )
+ return;
+ uint m = (enable || gmt) ? (uint)PointerMotionMask : 0;
+ if ( enable )
+ setWState( WState_MouseTracking );
+ else
+ clearWState( WState_MouseTracking );
+ if ( testWFlags(WType_Desktop) ) { // desktop widget?
+ TQWidget* main_desktop = tqfind( winId() );
+ if ( main_desktop->testWFlags(WPaintDesktop) )
+ XSelectInput( x11Display(), winId(),
+ stdDesktopEventMask | ExposureMask );
+ else
+ XSelectInput( x11Display(), winId(), stdDesktopEventMask );
+ } else {
+ XSelectInput( x11Display(), winId(),
+ m | stdWidgetEventMask );
+#if defined (TQT_TABLET_SUPPORT)
+ if ( devStylus != NULL ) {
+ XSelectExtensionEvent( x11Display(), winId(), event_list_stylus,
+ qt_curr_events_stylus );
+ }
+ if ( devEraser != NULL ) {
+ XSelectExtensionEvent( x11Display(), winId(), event_list_eraser,
+ qt_curr_events_eraser );
+ }
+#endif
+ }
+}
+
+
+/*!
+ Grabs the mouse input.
+
+ This widget receives all mouse events until releaseMouse() is
+ called; other widgets get no mouse events at all. Keyboard
+ events are not affected. Use grabKeyboard() if you want to grab
+ that.
+
+ \warning Bugs in mouse-grabbing applications very often lock the
+ terminal. Use this function with extreme caution, and consider
+ using the \c -nograb command line option while debugging.
+
+ It is almost never necessary to grab the mouse when using TQt, as
+ TQt grabs and releases it sensibly. In particular, TQt grabs the
+ mouse when a mouse button is pressed and keeps it until the last
+ button is released.
+
+ Note that only visible widgets can grab mouse input. If
+ isVisible() returns FALSE for a widget, that widget cannot call
+ grabMouse().
+
+ \sa releaseMouse() grabKeyboard() releaseKeyboard() grabKeyboard()
+ tqfocusWidget()
+*/
+
+void TQWidget::grabMouse()
+{
+ if ( isVisible() && !qt_nograb() ) {
+ if ( mouseGrb )
+ mouseGrb->releaseMouse();
+#if defined(TQT_CHECK_STATE)
+ int status =
+#endif
+ XGrabPointer( x11Display(), winId(), False,
+ (uint)( ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | EnterWindowMask |
+ LeaveWindowMask ),
+ GrabModeAsync, GrabModeAsync,
+ None, None, GET_QT_X_TIME() );
+#if defined(TQT_CHECK_STATE)
+ if ( status ) {
+ const char *s =
+ status == GrabNotViewable ? "\"GrabNotViewable\"" :
+ status == AlreadyGrabbed ? "\"AlreadyGrabbed\"" :
+ status == GrabFrozen ? "\"GrabFrozen\"" :
+ status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
+ "<?>";
+ qWarning( "Grabbing the mouse failed with %s", s );
+ }
+#endif
+ mouseGrb = this;
+ }
+}
+
+/*!
+ \overload
+
+ Grabs the mouse input and changes the cursor tqshape.
+
+ The cursor will assume tqshape \a cursor (for as long as the mouse
+ focus is grabbed) and this widget will be the only one to receive
+ mouse events until releaseMouse() is called().
+
+ \warning Grabbing the mouse might lock the terminal.
+
+ \sa releaseMouse(), grabKeyboard(), releaseKeyboard(), setCursor()
+*/
+
+void TQWidget::grabMouse( const TQCursor &cursor )
+{
+ if ( !qt_nograb() ) {
+ if ( mouseGrb )
+ mouseGrb->releaseMouse();
+#if defined(TQT_CHECK_STATE)
+ int status =
+#endif
+ XGrabPointer( x11Display(), winId(), False,
+ (uint)(ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | EnterWindowMask | LeaveWindowMask),
+ GrabModeAsync, GrabModeAsync,
+ None, cursor.handle(), GET_QT_X_TIME() );
+#if defined(TQT_CHECK_STATE)
+ if ( status ) {
+ const char *s =
+ status == GrabNotViewable ? "\"GrabNotViewable\"" :
+ status == AlreadyGrabbed ? "\"AlreadyGrabbed\"" :
+ status == GrabFrozen ? "\"GrabFrozen\"" :
+ status == GrabInvalidTime ? "\"GrabInvalidTime\"" :
+ "<?>";
+ qWarning( "Grabbing the mouse failed with %s", s );
+ }
+#endif
+ mouseGrb = this;
+ }
+}
+
+/*!
+ Releases the mouse grab.
+
+ \sa grabMouse(), grabKeyboard(), releaseKeyboard()
+*/
+
+void TQWidget::releaseMouse()
+{
+ if ( !qt_nograb() && mouseGrb == this ) {
+ XUngrabPointer( x11Display(), GET_QT_X_TIME() );
+ XFlush( x11Display() );
+ mouseGrb = 0;
+ }
+}
+
+/*!
+ Grabs the keyboard input.
+
+ This widget reveives all keyboard events until releaseKeyboard()
+ is called; other widgets get no keyboard events at all. Mouse
+ events are not affected. Use grabMouse() if you want to grab that.
+
+ The focus widget is not affected, except that it doesn't receive
+ any keyboard events. setFocus() moves the focus as usual, but the
+ new focus widget receives keyboard events only after
+ releaseKeyboard() is called.
+
+ If a different widget is currently grabbing keyboard input, that
+ widget's grab is released first.
+
+ \sa releaseKeyboard() grabMouse() releaseMouse() tqfocusWidget()
+*/
+
+void TQWidget::grabKeyboard()
+{
+ if ( !qt_nograb() ) {
+ if ( keyboardGrb )
+ keyboardGrb->releaseKeyboard();
+ XGrabKeyboard( x11Display(), winid, False, GrabModeAsync, GrabModeAsync,
+ GET_QT_X_TIME() );
+ keyboardGrb = this;
+ }
+}
+
+/*!
+ Releases the keyboard grab.
+
+ \sa grabKeyboard(), grabMouse(), releaseMouse()
+*/
+
+void TQWidget::releaseKeyboard()
+{
+ if ( !qt_nograb() && keyboardGrb == this ) {
+ XUngrabKeyboard( x11Display(), GET_QT_X_TIME() );
+ keyboardGrb = 0;
+ }
+}
+
+
+/*!
+ Returns the widget that is currently grabbing the mouse input.
+
+ If no widget in this application is currently grabbing the mouse,
+ 0 is returned.
+
+ \sa grabMouse(), keyboardGrabber()
+*/
+
+TQWidget *TQWidget::mouseGrabber()
+{
+ return mouseGrb;
+}
+
+/*!
+ Returns the widget that is currently grabbing the keyboard input.
+
+ If no widget in this application is currently grabbing the
+ keyboard, 0 is returned.
+
+ \sa grabMouse(), mouseGrabber()
+*/
+
+TQWidget *TQWidget::keyboardGrabber()
+{
+ return keyboardGrb;
+}
+
+/*!
+ Sets the top-level widget containing this widget to be the active
+ window.
+
+ An active window is a visible top-level window that has the
+ keyboard input focus.
+
+ This function performs the same operation as clicking the mouse on
+ the title bar of a top-level window. On X11, the result depends on
+ the Window Manager. If you want to ensure that the window is
+ stacked on top as well you should also call raise(). Note that the
+ window must be visible, otherwise setActiveWindow() has no effect.
+
+ On Windows, if you are calling this when the application is not
+ currently the active one then it will not make it the active
+ window. It will flash the task bar entry blue to indicate that
+ the window has done something. This is because Microsoft do not
+ allow an application to interrupt what the user is currently doing
+ in another application.
+
+ \sa isActiveWindow(), tqtopLevelWidget(), show()
+*/
+
+void TQWidget::setActiveWindow()
+{
+ TQWidget *tlw = tqtopLevelWidget();
+ if ( tlw->isVisible() && !tlw->topData()->embedded && !qt_deferred_map_tqcontains(tlw) ) {
+ XSetInputFocus( x11Display(), tlw->winId(), RevertToNone, GET_QT_X_TIME());
+ focusInputContext();
+ }
+}
+
+
+/*!
+ Updates the widget unless updates are disabled or the widget is
+ hidden.
+
+ This function does not cause an immediate tqrepaint; instead it
+ schedules a paint event for processing when TQt returns to the main
+ event loop. This permits TQt to optimize for more speed and less
+ flicker than a call to tqrepaint() does.
+
+ Calling update() several times normally results in just one
+ paintEvent() call.
+
+ TQt normally erases the widget's area before the paintEvent() call.
+ If the \c WRepaintNoErase widget flag is set, the widget is
+ responsible for painting all its pixels itself.
+
+ \sa tqrepaint(), paintEvent(), setUpdatesEnabled(), erase(),
+ setWFlags()
+*/
+
+void TQWidget::update()
+{
+ if ( (widget_state & (WState_Visible|WState_BlockUpdates)) ==
+ WState_Visible )
+ TQApplication::postEvent( this, new TQPaintEvent( clipRegion(), !testWFlags(WRepaintNoErase) ) );
+}
+
+/*!
+ \overload
+
+ Updates a rectangle (\a x, \a y, \a w, \a h) inside the widget
+ unless updates are disabled or the widget is hidden.
+
+ This function does not cause an immediate tqrepaint; instead it
+ schedules a paint event for processing when TQt returns to the main
+ event loop. This permits TQt to optimize for more speed and less
+ flicker and a call to tqrepaint() does.
+
+ Calling update() several times normally results in just one
+ paintEvent() call.
+
+ If \a w is negative, it is tqreplaced with \c{width() - x}. If \a h
+ is negative, it is tqreplaced width \c{height() - y}.
+
+ TQt normally erases the specified area before the paintEvent()
+ call. If the \c WRepaintNoErase widget flag is set, the widget is
+ responsible for painting all its pixels itself.
+
+ \sa tqrepaint(), paintEvent(), setUpdatesEnabled(), erase()
+*/
+
+void TQWidget::update( int x, int y, int w, int h )
+{
+ if ( w && h &&
+ (widget_state & (WState_Visible|WState_BlockUpdates)) == WState_Visible ) {
+ if ( w < 0 )
+ w = crect.width() - x;
+ if ( h < 0 )
+ h = crect.height() - y;
+ if ( w != 0 && h != 0 )
+ TQApplication::postEvent( this,
+ new TQPaintEvent( clipRegion().intersect(TQRect(x,y,w,h)),
+ !testWFlags( WRepaintNoErase ) ) );
+ }
+}
+
+/*!
+ \overload void TQWidget::update( const TQRect &r )
+
+ Updates a rectangle \a r inside the widget unless updates are
+ disabled or the widget is hidden.
+
+ This function does not cause an immediate tqrepaint; instead it
+ schedules a paint event for processing when TQt returns to the main
+ event loop. This permits TQt to optimize for more speed and less
+ flicker and a call to tqrepaint() does.
+
+ Calling update() several times normally results in just one
+ paintEvent() call.
+*/
+
+/*!
+ \overload void TQWidget::tqrepaint( bool erase )
+
+ This version repaints the entire widget.
+*/
+
+/*!
+ \overload void TQWidget::tqrepaint()
+
+ This version erases and repaints the entire widget.
+*/
+
+/*!
+ Repaints the widget directly by calling paintEvent() immediately,
+ unless updates are disabled or the widget is hidden.
+
+ If \a erase is TRUE, TQt erases the area \a (x, y, w, h) before the
+ paintEvent() call.
+
+ If \a w is negative, it is tqreplaced with \c{width() - x}, and if
+ \a h is negative, it is tqreplaced width \c{height() - y}.
+
+ We suggest only using tqrepaint() if you need an immediate tqrepaint,
+ for example during animation. In almost all circumstances update()
+ is better, as it permits TQt to optimize for speed and minimize
+ flicker.
+
+ \warning If you call tqrepaint() in a function which may itself be
+ called from paintEvent(), you may get infinite recursion. The
+ update() function never causes recursion.
+
+ \sa update(), paintEvent(), setUpdatesEnabled(), erase()
+*/
+
+void TQWidget::tqrepaint( int x, int y, int w, int h, bool erase )
+{
+ if ( (widget_state & (WState_Visible|WState_BlockUpdates)) == WState_Visible ) {
+ if ( x > crect.width() || y > crect.height() )
+ return;
+ if ( w < 0 )
+ w = crect.width() - x;
+ if ( h < 0 )
+ h = crect.height() - y;
+ TQRect r(x,y,w,h);
+ if ( r.isEmpty() )
+ return; // nothing to do
+ TQPaintEvent e( r, erase );
+ if ( r != rect() )
+ qt_set_paintevent_clipping( this, r );
+ if ( erase && w != 0 && h != 0 ) {
+ if ( backgroundOrigin() == WidgetOrigin )
+ XClearArea( x11Display(), winId(), x, y, w, h, False );
+ else
+ this->erase( x, y, w, h);
+ }
+ TQApplication::sendEvent( this, &e );
+ qt_clear_paintevent_clipping();
+ }
+}
+
+/*!
+ \overload
+
+ Repaints the widget directly by calling paintEvent() directly,
+ unless updates are disabled or the widget is hidden.
+
+ Erases the widget region \a reg if \a erase is TRUE.
+
+ Only use tqrepaint if your widget needs to be repainted immediately,
+ for example when doing some animation. In all other cases, use
+ update(). Calling update() many times in a row will generate a
+ single paint event.
+
+ \warning If you call tqrepaint() in a function which may itself be
+ called from paintEvent(), you may get infinite recursion. The
+ update() function never causes recursion.
+
+ \sa update(), paintEvent(), setUpdatesEnabled(), erase()
+*/
+
+void TQWidget::tqrepaint( const TQRegion& reg, bool erase )
+{
+ if ( (widget_state & (WState_Visible|WState_BlockUpdates)) == WState_Visible ) {
+ TQPaintEvent e( reg, erase );
+ qt_set_paintevent_clipping( this, reg );
+ if ( erase )
+ this->erase(reg);
+ TQApplication::sendEvent( this, &e );
+ qt_clear_paintevent_clipping();
+ }
+}
+
+/*!
+ \overload void TQWidget::tqrepaint( const TQRect &r, bool erase )
+
+ Repaints the widget directly by calling paintEvent() directly,
+ unless updates are disabled or the widget is hidden.
+
+ Erases the widget region \a r if \a erase is TRUE.
+*/
+
+void TQWidget::setWindowState(uint newstate)
+{
+ bool needShow = FALSE;
+ uint oldstate = windowState();
+ if (isTopLevel()) {
+ TQTLWExtra *top = topData();
+
+ if ((oldstate & WindowMaximized) != (newstate & WindowMaximized)) {
+ if (qt_net_supports(qt_net_wm_state_max_h) && qt_net_supports(qt_net_wm_state_max_v)) {
+ qt_net_change_wm_state(this, (newstate & WindowMaximized),
+ qt_net_wm_state_max_h, qt_net_wm_state_max_v);
+ } else if (! (newstate & WindowFullScreen)) {
+ if (newstate & WindowMaximized) {
+ // save original tqgeometry
+ const TQRect normalGeometry = tqgeometry();
+
+ if (isVisible()) {
+ updateFrameStrut();
+ const TQRect maxRect = TQApplication::desktop()->availableGeometry(this);
+ const TQRect r = top->normalGeometry;
+ setGeometry(maxRect.x() + top->fleft,
+ maxRect.y() + top->ftop,
+ maxRect.width() - top->fleft - top->fright,
+ maxRect.height() - top->ftop - top->fbottom);
+ top->normalGeometry = r;
+ }
+
+ if (top->normalGeometry.width() < 0)
+ top->normalGeometry = normalGeometry;
+ } else {
+ // restore original tqgeometry
+ setGeometry(top->normalGeometry);
+ }
+ }
+ }
+
+ if ((oldstate & WindowFullScreen) != (newstate & WindowFullScreen)) {
+ if (qt_net_supports(qt_net_wm_state_fullscreen)) {
+ qt_net_change_wm_state(this, (newstate & WindowFullScreen),
+ qt_net_wm_state_fullscreen);
+ } else {
+ needShow = isVisible();
+
+ if (newstate & WindowFullScreen) {
+ const TQRect normalGeometry = TQRect(pos(), size());
+
+ top->savedFlags = getWFlags();
+ reparent(0, WType_TopLevel | WStyle_Customize | WStyle_NoBorder |
+ // preserve some widget flags
+ (getWFlags() & 0xffff0000),
+ mapToGlobal(TQPoint(0, 0)));
+ const TQRect r = top->normalGeometry;
+ setGeometry(tqApp->desktop()->screenGeometry(this));
+ top->normalGeometry = r;
+
+ if ( top->normalGeometry.width() < 0 )
+ top->normalGeometry = normalGeometry;
+ } else {
+ reparent( 0, top->savedFlags, mapToGlobal(TQPoint(0, 0)) );
+
+ if (newstate & WindowMaximized) {
+ // from fullscreen to maximized
+ updateFrameStrut();
+ const TQRect maxRect = TQApplication::desktop()->availableGeometry(this);
+ const TQRect r = top->normalGeometry;
+ setGeometry(maxRect.x() + top->fleft,
+ maxRect.y() + top->ftop,
+ maxRect.width() - top->fleft - top->fright,
+ maxRect.height() - top->ftop - top->fbottom);
+ top->normalGeometry = r;
+ } else {
+ // restore original tqgeometry
+ setGeometry(top->normalGeometry);
+ }
+ }
+ }
+ }
+
+ if ((oldstate & WindowMinimized) != (newstate & WindowMinimized)) {
+ if (isVisible()) {
+ if (newstate & WindowMinimized) {
+ XEvent e;
+ e.xclient.type = ClientMessage;
+ e.xclient.message_type = qt_wm_change_state;
+ e.xclient.display = x11Display();
+ e.xclient.window = winid;
+ e.xclient.format = 32;
+ e.xclient.data.l[0] = IconicState;
+ e.xclient.data.l[1] = 0;
+ e.xclient.data.l[2] = 0;
+ e.xclient.data.l[3] = 0;
+ e.xclient.data.l[4] = 0;
+ XSendEvent(x11Display(), RootWindow(x11Display(), x11Screen()),
+ False, (SubstructureNotifyMask|SubstructureRedirectMask), &e);
+ } else {
+ XMapWindow(x11Display(), winId());
+ }
+ }
+
+ needShow = FALSE;
+ }
+ }
+
+ widget_state &= ~(WState_Minimized | WState_Maximized | WState_FullScreen);
+ if (newstate & WindowMinimized)
+ widget_state |= WState_Minimized;
+ if (newstate & WindowMaximized)
+ widget_state |= WState_Maximized;
+ if (newstate & WindowFullScreen)
+ widget_state |= WState_FullScreen;
+
+ if (needShow)
+ show();
+
+ if (newstate & WindowActive)
+ setActiveWindow();
+
+ TQEvent e(TQEvent::WindowStateChange);
+ TQApplication::sendEvent(this, &e);
+}
+
+/*!
+ \internal
+ Platform-specific part of TQWidget::show().
+*/
+
+void TQWidget::showWindow()
+{
+ if ( isTopLevel() ) {
+ XWMHints *h = XGetWMHints( x11Display(), winId() );
+ XWMHints wm_hints;
+ bool got_hints = h != 0;
+ if ( !got_hints ) {
+ h = &wm_hints;
+ h->flags = 0;
+ }
+ h->initial_state = testWState(WState_Minimized) ? IconicState : NormalState;
+ h->flags |= StateHint;
+ XSetWMHints( x11Display(), winId(), h );
+ if ( got_hints )
+ XFree( (char *)h );
+
+ if (GET_QT_X_USER_TIME() != CurrentTime) {
+ Time my_tqx_user_time = GET_QT_X_USER_TIME();
+ XChangeProperty(x11Display(), winId(), qt_net_wm_user_time, XA_CARDINAL,
+ 32, PropModeReplace, (unsigned char *) &my_tqx_user_time, 1);
+ SET_QT_X_USER_TIME(my_tqx_user_time);
+ }
+
+ if (!topData()->embedded &&
+ topData()->parentWinId &&
+ topData()->parentWinId != TQPaintDevice::x11AppRootWindow(x11Screen()) &&
+ !isMinimized() ) {
+ qt_deferred_map_add( this );
+ return;
+ }
+
+ if (isMaximized() && !isFullScreen()
+ && !(qt_net_supports(qt_net_wm_state_max_h)
+ && qt_net_supports(qt_net_wm_state_max_v))) {
+ XMapWindow( x11Display(), winId() );
+ qt_wait_for_window_manager(this);
+
+ // if the wm was not smart enough to adjust our size, do that manually
+ updateFrameStrut();
+ TQRect maxRect = TQApplication::desktop()->availableGeometry(this);
+
+ TQTLWExtra *top = topData();
+ TQRect normalRect = top->normalGeometry;
+
+ setGeometry(maxRect.x() + top->fleft,
+ maxRect.y() + top->ftop,
+ maxRect.width() - top->fleft - top->fright,
+ maxRect.height() - top->ftop - top->fbottom);
+
+ // restore the original normalGeometry
+ top->normalGeometry = normalRect;
+ // internalSetGeometry() clears the maximized flag... make sure we set it back
+ setWState(WState_Maximized);
+
+ return;
+ }
+
+ if (isFullScreen() && !qt_net_supports(qt_net_wm_state_fullscreen)) {
+ XMapWindow(x11Display(), winId());
+ qt_wait_for_window_manager(this);
+ return;
+ }
+ }
+ XMapWindow( x11Display(), winId() );
+}
+
+
+/*!
+ \internal
+ Platform-specific part of TQWidget::hide().
+*/
+
+void TQWidget::hideWindow()
+{
+ clearWState( WState_Exposed );
+ deactivateWidgetCleanup();
+ if ( isTopLevel() ) {
+ qt_deferred_map_take( this );
+ if ( winId() ) // in nsplugin, may be 0
+ XWithdrawWindow( x11Display(), winId(), x11Screen() );
+
+ TQTLWExtra *top = topData();
+ crect.moveTopLeft( TQPoint(crect.x() - top->fleft, crect.y() - top->ftop ) );
+
+ // zero the frame strut and mark it dirty
+ top->fleft = top->fright = top->ftop = top->fbottom = 0;
+ fstrut_dirty = TRUE;
+
+ XFlush( x11Display() );
+ } else {
+ if ( winId() ) // in nsplugin, may be 0
+ XUnmapWindow( x11Display(), winId() );
+ }
+}
+
+/*!
+ Raises this widget to the top of the tqparent widget's stack.
+
+ After this call the widget will be visually in front of any
+ overlapping sibling widgets.
+
+ \sa lower(), stackUnder()
+*/
+
+void TQWidget::raise()
+{
+ TQWidget *p = parentWidget();
+ if ( p && p->childObjects && p->childObjects->tqfindRef(this) >= 0 )
+ p->childObjects->append( p->childObjects->take() );
+ XRaiseWindow( x11Display(), winId() );
+}
+
+/*!
+ Lowers the widget to the bottom of the tqparent widget's stack.
+
+ After this call the widget will be visually behind (and therefore
+ obscured by) any overlapping sibling widgets.
+
+ \sa raise(), stackUnder()
+*/
+
+void TQWidget::lower()
+{
+ TQWidget *p = parentWidget();
+ if ( p && p->childObjects && p->childObjects->tqfindRef(this) >= 0 )
+ p->childObjects->insert( 0, p->childObjects->take() );
+ XLowerWindow( x11Display(), winId() );
+}
+
+
+/*!
+ Places the widget under \a w in the tqparent widget's stack.
+
+ To make this work, the widget itself and \a w must be siblings.
+
+ \sa raise(), lower()
+*/
+void TQWidget::stackUnder( TQWidget* w)
+{
+ TQWidget *p = parentWidget();
+ if ( !w || isTopLevel() || p != w->parentWidget() || this == w )
+ return;
+ if ( p && p->childObjects && p->childObjects->tqfindRef(w) >= 0 && p->childObjects->tqfindRef(this) >= 0 ) {
+ p->childObjects->take();
+ p->childObjects->insert( p->childObjects->tqfindRef(w), this );
+ }
+ Window stack[2];
+ stack[0] = w->winId();;
+ stack[1] = winId();
+ XRestackWindows( x11Display(), stack, 2 );
+}
+
+
+
+/*
+ The global variable qt_widget_tlw_gravity defines the window gravity of
+ the next top level window to be created. We do this when setting the
+ main widget's tqgeometry and the "-tqgeometry" command line option tqcontains
+ a negative position.
+*/
+
+int qt_widget_tlw_gravity = NorthWestGravity;
+
+static void do_size_hints( TQWidget* widget, TQWExtra *x )
+{
+ XSizeHints s;
+ s.flags = 0;
+ if ( x ) {
+ s.x = widget->x();
+ s.y = widget->y();
+ s.width = widget->width();
+ s.height = widget->height();
+ if ( x->minw > 0 || x->minh > 0 ) { // add minimum size hints
+ s.flags |= PMinSize;
+ s.min_width = x->minw;
+ s.min_height = x->minh;
+ }
+ if ( x->maxw < TQWIDGETSIZE_MAX || x->maxh < TQWIDGETSIZE_MAX ) {
+ s.flags |= PMaxSize; // add maximum size hints
+ s.max_width = x->maxw;
+ s.max_height = x->maxh;
+ }
+ if ( x->topextra &&
+ (x->topextra->incw > 0 || x->topextra->inch > 0) )
+ { // add resize increment hints
+ s.flags |= PResizeInc | PBaseSize;
+ s.width_inc = x->topextra->incw;
+ s.height_inc = x->topextra->inch;
+ s.base_width = x->topextra->basew;
+ s.base_height = x->topextra->baseh;
+ }
+
+ if ( x->topextra && x->topextra->uspos) {
+ s.flags |= USPosition;
+ s.flags |= PPosition;
+ }
+ if ( x->topextra && x->topextra->ussize) {
+ s.flags |= USSize;
+ s.flags |= PSize;
+ }
+ }
+ s.flags |= PWinGravity;
+ s.win_gravity = qt_widget_tlw_gravity; // usually NorthWest
+ // reset in case it was set
+ qt_widget_tlw_gravity =
+ TQApplication::reverseLayout() ? NorthEastGravity : NorthWestGravity;
+ XSetWMNormalHints( widget->x11Display(), widget->winId(), &s );
+}
+
+
+void TQWidget::internalSetGeometry( int x, int y, int w, int h, bool isMove )
+{
+ Display *dpy = x11Display();
+
+ if ( testWFlags(WType_Desktop) )
+ return;
+ if (isTopLevel()) {
+ if (!qt_net_supports(qt_net_wm_state_max_h)
+ && !qt_net_supports(qt_net_wm_state_max_v))
+ clearWState(WState_Maximized);
+ if (!qt_net_supports(qt_net_wm_state_fullscreen))
+ clearWState(WState_FullScreen);
+ topData()->normalGeometry = TQRect(0, 0, -1, -1);
+ } else {
+ // for TQWorkspace
+ clearWState(WState_Maximized);
+ clearWState(WState_FullScreen);
+ }
+ if ( extra ) { // any size restrictions?
+ w = TQMIN(w,extra->maxw);
+ h = TQMIN(h,extra->maxh);
+ w = TQMAX(w,extra->minw);
+ h = TQMAX(h,extra->minh);
+ }
+ if ( w < 1 ) // invalid size
+ w = 1;
+ if ( h < 1 )
+ h = 1;
+ TQPoint oldPos( pos() );
+ TQSize oldSize( size() );
+ TQRect oldGeom( crect );
+ TQRect r( x, y, w, h );
+
+ // We only care about stuff that changes the tqgeometry, or may
+ // cause the window manager to change its state
+ if ( !isTopLevel() && oldGeom == r )
+ return;
+
+ crect = r;
+ bool isResize = size() != oldSize;
+
+ if ( isTopLevel() ) {
+ if ( isMove )
+ topData()->uspos = 1;
+ if ( isResize )
+ topData()->ussize = 1;
+ do_size_hints( this, extra );
+ }
+
+ if ( isMove ) {
+ if (! qt_broken_wm)
+ // pos() is right according to ICCCM 4.1.5
+ XMoveResizeWindow( dpy, winid, pos().x(), pos().y(), w, h );
+ else
+ // work around 4Dwm's incompliance with ICCCM 4.1.5
+ XMoveResizeWindow( dpy, winid, x, y, w, h );
+ } else if ( isResize )
+ XResizeWindow( dpy, winid, w, h );
+
+ if ( isVisible() ) {
+ if ( isMove && pos() != oldPos ) {
+ if ( ! qt_broken_wm ) {
+ // pos() is right according to ICCCM 4.1.5
+ TQMoveEvent e( pos(), oldPos );
+ TQApplication::sendEvent( this, &e );
+ } else {
+ // work around 4Dwm's incompliance with ICCCM 4.1.5
+ TQMoveEvent e( crect.topLeft(), oldGeom.topLeft() );
+ TQApplication::sendEvent( this, &e );
+ }
+ }
+ if ( isResize ) {
+
+ // set config pending only on resize, see qapplication_x11.cpp, translateConfigEvent()
+ setWState( WState_ConfigPending );
+
+ TQResizeEvent e( size(), oldSize );
+ TQApplication::sendEvent( this, &e );
+ }
+ } else {
+ if ( isMove && pos() != oldPos ) {
+ if ( ! qt_broken_wm )
+ // pos() is right according to ICCCM 4.1.5
+ TQApplication::postEvent( this, new TQMoveEvent( pos(), oldPos ) );
+ else
+ // work around 4Dwm's incompliance with ICCCM 4.1.5
+ TQApplication::postEvent( this, new TQMoveEvent( crect.topLeft(),
+ oldGeom.topLeft() ) );
+ }
+ if ( isResize )
+ TQApplication::postEvent( this,
+ new TQResizeEvent( size(), oldSize ) );
+ }
+}
+
+
+/*!
+ \overload
+
+ This function corresponds to setMinimumSize( TQSize(minw, minh) ).
+ Sets the minimum width to \a minw and the minimum height to \a
+ minh.
+*/
+
+void TQWidget::setMinimumSize( int minw, int minh )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( minw < 0 || minh < 0 )
+ qWarning("TQWidget::setMinimumSize: The smallest allowed size is (0,0)");
+#endif
+ createExtra();
+ if ( extra->minw == minw && extra->minh == minh )
+ return;
+ extra->minw = minw;
+ extra->minh = minh;
+ if ( minw > width() || minh > height() ) {
+ bool resized = testWState( WState_Resized );
+ resize( TQMAX(minw,width()), TQMAX(minh,height()) );
+ if ( !resized )
+ clearWState( WState_Resized ); // not a user resize
+ }
+ if ( testWFlags(WType_TopLevel) )
+ do_size_hints( this, extra );
+ updateGeometry();
+}
+
+/*!
+ \overload
+
+ This function corresponds to setMaximumSize( TQSize(\a maxw, \a
+ maxh) ). Sets the maximum width to \a maxw and the maximum height
+ to \a maxh.
+*/
+void TQWidget::setMaximumSize( int maxw, int maxh )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( maxw > TQWIDGETSIZE_MAX || maxh > TQWIDGETSIZE_MAX ) {
+ qWarning("TQWidget::setMaximumSize: (%s/%s) "
+ "The largest allowed size is (%d,%d)",
+ name( "unnamed" ), className(), TQWIDGETSIZE_MAX,
+ TQWIDGETSIZE_MAX );
+ maxw = TQMIN( maxw, TQWIDGETSIZE_MAX );
+ maxh = TQMIN( maxh, TQWIDGETSIZE_MAX );
+ }
+ if ( maxw < 0 || maxh < 0 ) {
+ qWarning("TQWidget::setMaximumSize: (%s/%s) Negative sizes (%d,%d) "
+ "are not possible",
+ name( "unnamed" ), className(), maxw, maxh );
+ maxw = TQMAX( maxw, 0 );
+ maxh = TQMAX( maxh, 0 );
+ }
+#endif
+ createExtra();
+ if ( extra->maxw == maxw && extra->maxh == maxh )
+ return;
+ extra->maxw = maxw;
+ extra->maxh = maxh;
+ if ( maxw < width() || maxh < height() ) {
+ bool resized = testWState( WState_Resized );
+ resize( TQMIN(maxw,width()), TQMIN(maxh,height()) );
+ if ( !resized )
+ clearWState( WState_Resized ); // not a user resize
+ }
+ if ( testWFlags(WType_TopLevel) )
+ do_size_hints( this, extra );
+ updateGeometry();
+}
+
+/*!
+ \overload
+
+ Sets the x (width) size increment to \a w and the y (height) size
+ increment to \a h.
+*/
+void TQWidget::setSizeIncrement( int w, int h )
+{
+ TQTLWExtra* x = topData();
+ if ( x->incw == w && x->inch == h )
+ return;
+ x->incw = w;
+ x->inch = h;
+ if ( testWFlags(WType_TopLevel) )
+ do_size_hints( this, extra );
+}
+
+/*!
+ \overload
+
+ This corresponds to setBaseSize( TQSize(\a basew, \a baseh) ). Sets
+ the widgets base size to width \a basew and height \a baseh.
+*/
+void TQWidget::setBaseSize( int basew, int baseh )
+{
+ createTLExtra();
+ TQTLWExtra* x = topData();
+ if ( x->basew == basew && x->baseh == baseh )
+ return;
+ x->basew = basew;
+ x->baseh = baseh;
+ if ( testWFlags(WType_TopLevel) )
+ do_size_hints( this, extra );
+}
+
+/*!
+ \overload void TQWidget::erase()
+
+ This version erases the entire widget.
+*/
+
+/*!
+ \overload void TQWidget::erase( const TQRect &r )
+
+ Erases the specified area \a r in the widget without generating a
+ \link paintEvent() paint event\endlink.
+*/
+
+/*!
+ Erases the specified area \a (x, y, w, h) in the widget without
+ generating a \link paintEvent() paint event\endlink.
+
+ If \a w is negative, it is tqreplaced with \c{width() - x}. If \a h
+ is negative, it is tqreplaced width \c{height() - y}.
+
+ Child widgets are not affected.
+
+ \sa tqrepaint()
+*/
+
+void TQWidget::erase( int x, int y, int w, int h )
+{
+ extern void qt_erase_rect( TQWidget*, const TQRect& ); // in qpainer_x11.cpp
+ if ( w < 0 )
+ w = crect.width() - x;
+ if ( h < 0 )
+ h = crect.height() - y;
+ if ( w != 0 && h != 0 )
+ qt_erase_rect( this, TQRect(x, y, w, h ) );
+}
+
+/*!
+ \overload
+
+ Erases the area defined by \a reg, without generating a \link
+ paintEvent() paint event\endlink.
+
+ Child widgets are not affected.
+*/
+
+void TQWidget::erase( const TQRegion& reg )
+{
+ extern void qt_erase_region( TQWidget*, const TQRegion& ); // in qpainer_x11.cpp
+ qt_erase_region( this, reg );
+}
+
+/*!
+ Scrolls the widget including its tqchildren \a dx pixels to the
+ right and \a dy downwards. Both \a dx and \a dy may be negative.
+
+ After scrolling, scroll() sends a paint event for the the part
+ that is read but not written. For example, when scrolling 10
+ pixels rightwards, the leftmost ten pixels of the widget need
+ repainting. The paint event may be delivered immediately or later,
+ depending on some heuristics (note that you might have to force
+ processing of paint events using TQApplication::sendPostedEvents()
+ when using scroll() and move() in combination).
+
+ \sa TQScrollView erase() bitBlt()
+*/
+
+void TQWidget::scroll( int dx, int dy )
+{
+ scroll( dx, dy, TQRect() );
+}
+
+/*!
+ \overload
+
+ This version only scrolls \a r and does not move the tqchildren of
+ the widget.
+
+ If \a r is empty or invalid, the result is undefined.
+
+ \sa TQScrollView erase() bitBlt()
+*/
+void TQWidget::scroll( int dx, int dy, const TQRect& r )
+{
+ if ( testWState( WState_BlockUpdates ) && !childrenListObject() )
+ return;
+ bool valid_rect = r.isValid();
+ bool just_update = TQABS( dx ) > width() || TQABS( dy ) > height();
+ if ( just_update )
+ update();
+ TQRect sr = valid_rect?r:clipRegion().boundingRect();
+ int x1, y1, x2, y2, w=sr.width(), h=sr.height();
+ if ( dx > 0 ) {
+ x1 = sr.x();
+ x2 = x1+dx;
+ w -= dx;
+ } else {
+ x2 = sr.x();
+ x1 = x2-dx;
+ w += dx;
+ }
+ if ( dy > 0 ) {
+ y1 = sr.y();
+ y2 = y1+dy;
+ h -= dy;
+ } else {
+ y2 = sr.y();
+ y1 = y2-dy;
+ h += dy;
+ }
+
+ if ( dx == 0 && dy == 0 )
+ return;
+
+ Display *dpy = x11Display();
+ GC gc = qt_xget_readonly_gc( x11Screen(), FALSE );
+ // Want expose events
+ if ( w > 0 && h > 0 && !just_update ) {
+ XSetGraphicsExposures( dpy, gc, True );
+ XCopyArea( dpy, winId(), winId(), gc, x1, y1, w, h, x2, y2);
+ XSetGraphicsExposures( dpy, gc, False );
+ }
+
+ if ( !valid_rect && childrenListObject() ) { // scroll tqchildren
+ TQPoint pd( dx, dy );
+ TQObjectListIt it(*childrenListObject());
+ register TQObject *object;
+ while ( it ) { // move all tqchildren
+ object = it.current();
+ if ( object->isWidgetType() ) {
+ TQWidget *w = (TQWidget *)object;
+ w->move( w->pos() + pd );
+ }
+ ++it;
+ }
+ }
+
+ if ( just_update )
+ return;
+
+ // Don't let the server be bogged-down with tqrepaint events
+ bool repaint_immediately = qt_sip_count( this ) < 3;
+
+ if ( dx ) {
+ int x = x2 == sr.x() ? sr.x()+w : sr.x();
+ if ( repaint_immediately )
+ tqrepaint( x, sr.y(), TQABS(dx), sr.height(), !testWFlags(WRepaintNoErase) );
+ else
+ XClearArea( dpy, winid, x, sr.y(), TQABS(dx), sr.height(), True );
+ }
+ if ( dy ) {
+ int y = y2 == sr.y() ? sr.y()+h : sr.y();
+ if ( repaint_immediately )
+ tqrepaint( sr.x(), y, sr.width(), TQABS(dy), !testWFlags(WRepaintNoErase) );
+ else
+ XClearArea( dpy, winid, sr.x(), y, sr.width(), TQABS(dy), True );
+ }
+
+ qt_insert_sip( this, dx, dy ); // #### ignores r
+}
+
+
+/*!
+ \overload void TQWidget::drawText( const TQPoint &pos, const TQString& str )
+
+ Draws the string \a str at position \a pos.
+*/
+
+/*!
+ Draws the string \a str at position \a(x, y).
+
+ The \a y position is the base line position of the text. The text
+ is drawn using the default font and the default foreground color.
+
+ This function is provided for convenience. You will generally get
+ more flexible results and often higher speed by using a a \link
+ TQPainter painter\endlink instead.
+
+ \sa setFont(), foregroundColor(), TQPainter::drawText()
+*/
+
+void TQWidget::drawText( int x, int y, const TQString &str )
+{
+ if ( testWState(WState_Visible) ) {
+ TQPainter paint;
+ paint.begin( this );
+ paint.drawText( x, y, str );
+ paint.end();
+ }
+}
+
+
+/*!
+ Internal implementation of the virtual TQPaintDevice::metric()
+ function.
+
+ Use the TQPaintDeviceMetrics class instead.
+
+ \a m is the metric to get.
+*/
+
+int TQWidget::metric( int m ) const
+{
+ int val;
+ if ( m == TQPaintDeviceMetrics::PdmWidth ) {
+ val = crect.width();
+ } else if ( m == TQPaintDeviceMetrics::PdmHeight ) {
+ val = crect.height();
+ } else {
+ Display *dpy = x11Display();
+ int scr = x11Screen();
+ switch ( m ) {
+ case TQPaintDeviceMetrics::PdmDpiX:
+ case TQPaintDeviceMetrics::PdmPhysicalDpiX:
+ val = TQPaintDevice::x11AppDpiX( scr );
+ break;
+ case TQPaintDeviceMetrics::PdmDpiY:
+ case TQPaintDeviceMetrics::PdmPhysicalDpiY:
+ val = TQPaintDevice::x11AppDpiY( scr );
+ break;
+ case TQPaintDeviceMetrics::PdmWidthMM:
+ val = (DisplayWidthMM(dpy,scr)*crect.width())/
+ DisplayWidth(dpy,scr);
+ break;
+ case TQPaintDeviceMetrics::PdmHeightMM:
+ val = (DisplayHeightMM(dpy,scr)*crect.height())/
+ DisplayHeight(dpy,scr);
+ break;
+ case TQPaintDeviceMetrics::PdmNumColors:
+ val = x11Cells();
+ break;
+ case TQPaintDeviceMetrics::PdmDepth:
+ val = x11Depth();
+ break;
+ default:
+ val = 0;
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQWidget::metric: Invalid metric command" );
+#endif
+ }
+ }
+ return val;
+}
+
+void TQWidget::createSysExtra()
+{
+ extra->xDndProxy = 0;
+ extra->tqchildren_use_dnd = FALSE;
+ extra->compress_events = TRUE;
+}
+
+void TQWidget::deleteSysExtra()
+{
+}
+
+void TQWidget::createTLSysExtra()
+{
+ // created lazily
+ extra->topextra->xic = 0;
+}
+
+void TQWidget::deleteTLSysExtra()
+{
+ destroyInputContext();
+}
+
+/*
+ examine the tqchildren of our tqparent up the tree and set the
+ tqchildren_use_dnd extra data appropriately... this is used to keep DND enabled
+ for widgets that are reparented and don't have DND enabled, BUT *DO* have
+ tqchildren (or tqchildren of tqchildren ...) with DND enabled...
+*/
+void TQWidget::checkChildrenDnd()
+{
+ TQWidget *widget = this;
+ const TQObjectList *tqchildren;
+ const TQObject *object;
+ const TQWidget *child;
+ while (widget && ! widget->isDesktop()) {
+ // note: this isn't done for the desktop widget
+
+ bool tqchildren_use_dnd = FALSE;
+ tqchildren = widget->childrenListObject();
+ if ( tqchildren ) {
+ TQObjectListIt it(*tqchildren);
+ while ( (object = it.current()) ) {
+ ++it;
+ if ( object->isWidgetType() ) {
+ child = (const TQWidget *) object;
+ tqchildren_use_dnd = (tqchildren_use_dnd ||
+ child->acceptDrops() ||
+ (child->extra &&
+ child->extra->tqchildren_use_dnd));
+ }
+ }
+ }
+
+ widget->createExtra();
+ widget->extra->tqchildren_use_dnd = tqchildren_use_dnd;
+
+ widget = widget->parentWidget();
+ }
+}
+
+/*!
+ \property TQWidget::acceptDrops
+ \brief whether drop events are enabled for this widget
+
+ Setting this property to TRUE announces to the system that this
+ widget \e may be able to accept drop events.
+
+ If the widget is the desktop (TQWidget::isDesktop()), this may
+ fail if another application is using the desktop; you can call
+ acceptDrops() to test if this occurs.
+
+ \warning
+ Do not modify this property in a Drag&Drop event handler.
+*/
+bool TQWidget::acceptDrops() const
+{
+ return testWState( WState_DND );
+}
+
+void TQWidget::setAcceptDrops( bool on )
+{
+ if ( testWState(WState_DND) != on ) {
+ if ( qt_dnd_enable( this, on ) ) {
+ if ( on )
+ setWState( WState_DND );
+ else
+ clearWState( WState_DND );
+ }
+
+ checkChildrenDnd();
+ }
+}
+
+/*!
+ \overload
+
+ Causes only the parts of the widget which overlap \a region to be
+ visible. If the region includes pixels outside the rect() of the
+ widget, window system controls in that area may or may not be
+ visible, depending on the platform.
+
+ Note that this effect can be slow if the region is particularly
+ complex.
+
+ \sa setMask(), clearMask()
+*/
+
+void TQWidget::setMask( const TQRegion& region )
+{
+ XShapeCombineRegion( x11Display(), winId(), ShapeBounding, 0, 0,
+ region.handle(), ShapeSet );
+}
+
+/*!
+ Causes only the pixels of the widget for which \a bitmap has a
+ corresponding 1 bit to be visible. Use TQt::color0 to draw
+ transtqparent regions and TQt::color1 to draw opaque regions of the
+ bitmap.
+
+ If the region includes pixels outside the rect() of the widget,
+ window system controls in that area may or may not be visible,
+ depending on the platform.
+
+ Note that this effect can be slow if the region is particularly
+ complex.
+
+ See \c examples/tux for an example of masking for transparency.
+
+ \sa setMask(), clearMask()
+*/
+
+void TQWidget::setMask( const TQBitmap &bitmap )
+{
+ TQBitmap bm = bitmap;
+ if ( bm.x11Screen() != x11Screen() )
+ bm.x11SetScreen( x11Screen() );
+ XShapeCombineMask( x11Display(), winId(), ShapeBounding, 0, 0,
+ bm.handle(), ShapeSet );
+}
+
+/*!
+ Removes any tqmask set by setMask().
+
+ \sa setMask()
+*/
+
+void TQWidget::clearMask()
+{
+ XShapeCombineMask( x11Display(), winId(), ShapeBounding, 0, 0,
+ None, ShapeSet );
+}
+
+/*!\reimp
+ */
+void TQWidget::setName( const char *name )
+{
+ TQObject::setName( name );
+ if ( isTopLevel() ) {
+ XChangeProperty( x11Display(), winId(),
+ qt_window_role, XA_STRING, 8, PropModeReplace,
+ (unsigned char *)name, tqstrlen( name ) );
+ }
+}
+
+
+/*!
+ \internal
+
+ Computes the frame rectangle when needed. This is an internal function, you
+ should never call this.
+*/
+
+void TQWidget::updateFrameStrut() const
+{
+ TQWidget *that = (TQWidget *) this;
+
+ if (! isVisible() || isDesktop()) {
+ that->fstrut_dirty = (! isVisible());
+ return;
+ }
+
+ Atom type_ret;
+ Window l = winId(), w = winId(), p, r; // target window, it's tqparent, root
+ Window *c;
+ int i_unused;
+ unsigned int nc;
+ unsigned char *data_ret;
+ unsigned long l_unused;
+
+ while (XQueryTree(TQPaintDevice::x11AppDisplay(), w, &r, &p, &c, &nc)) {
+ if (c && nc > 0)
+ XFree(c);
+
+ if (! p) {
+ qWarning("TQWidget::updateFrameStrut(): ERROR - no tqparent");
+ return;
+ }
+
+ // if the tqparent window is the root window, an Enlightenment virtual root or
+ // a NET WM virtual root window, stop here
+ data_ret = 0;
+ if (p == r ||
+ (XGetWindowProperty(TQPaintDevice::x11AppDisplay(), p,
+ qt_enlightenment_desktop, 0, 1, False, XA_CARDINAL,
+ &type_ret, &i_unused, &l_unused, &l_unused,
+ &data_ret) == Success &&
+ type_ret == XA_CARDINAL)) {
+ if (data_ret)
+ XFree(data_ret);
+
+ break;
+ } else if (qt_net_supports(qt_net_virtual_roots) && qt_net_virtual_root_list) {
+ int i = 0;
+ while (qt_net_virtual_root_list[i] != 0) {
+ if (qt_net_virtual_root_list[i++] == p)
+ break;
+ }
+ }
+
+ l = w;
+ w = p;
+ }
+
+ // we have our window
+ int transx, transy;
+ XWindowAttributes wattr;
+ if (XTranslateCoordinates(TQPaintDevice::x11AppDisplay(), l, w,
+ 0, 0, &transx, &transy, &p) &&
+ XGetWindowAttributes(TQPaintDevice::x11AppDisplay(), w, &wattr)) {
+ TQTLWExtra *top = that->topData();
+ top->fleft = transx;
+ top->ftop = transy;
+ top->fright = wattr.width - crect.width() - top->fleft;
+ top->fbottom = wattr.height - crect.height() - top->ftop;
+
+ // add the border_width for the window managers frame... some window managers
+ // do not use a border_width of zero for their frames, and if we the left and
+ // top strut, we ensure that pos() is absolutely correct. frameGeometry()
+ // will still be incorrect though... perhaps i should have foffset as well, to
+ // indicate the frame offset (equal to the border_width on X).
+ // - Brad
+ top->fleft += wattr.border_width;
+ top->fright += wattr.border_width;
+ top->ftop += wattr.border_width;
+ top->fbottom += wattr.border_width;
+ }
+
+ that->fstrut_dirty = 0;
+}
+
+
+void TQWidget::createInputContext()
+{
+ TQWidget *tlw = tqtopLevelWidget();
+ TQTLWExtra *topdata = tlw->topData();
+
+#ifndef TQT_NO_XIM
+ if (qt_xim) {
+ if (! topdata->xic) {
+ TQInputContext *qic = new TQInputContext(tlw);
+ topdata->xic = (void *) qic;
+ }
+ } else
+#endif // TQT_NO_XIM
+ {
+ // qDebug("TQWidget::createInputContext: no xim");
+ topdata->xic = 0;
+ }
+}
+
+
+void TQWidget::destroyInputContext()
+{
+#ifndef TQT_NO_XIM
+ TQInputContext *qic = (TQInputContext *) extra->topextra->xic;
+ delete qic;
+#endif // TQT_NO_XIM
+ extra->topextra->xic = 0;
+}
+
+
+/*!
+ This function is called when the user finishes input composition,
+ e.g. changes focus to another widget, moves the cursor, etc.
+*/
+void TQWidget::resetInputContext()
+{
+#ifndef TQT_NO_XIM
+ if ((qt_xim_style & XIMPreeditCallbacks) && hasFocus()) {
+ TQWidget *tlw = tqtopLevelWidget();
+ TQTLWExtra *topdata = tlw->topData();
+
+ // trigger input context creation if it hasn't happened already
+ createInputContext();
+
+ if (topdata->xic) {
+ TQInputContext *qic = (TQInputContext *) topdata->xic;
+ qic->reset();
+ }
+ }
+#endif // TQT_NO_XIM
+}
+
+
+void TQWidget::focusInputContext()
+{
+#ifndef TQT_NO_XIM
+ TQWidget *tlw = tqtopLevelWidget();
+ if (!tlw->isPopup() || isInputMethodEnabled()) {
+ TQTLWExtra *topdata = tlw->topData();
+
+ // trigger input context creation if it hasn't happened already
+ createInputContext();
+
+ if (topdata->xic) {
+ TQInputContext *qic = (TQInputContext *) topdata->xic;
+ qic->setFocus();
+ }
+ }
+#endif // TQT_NO_XIM
+}
+
+void TQWidget::setWindowOpacity(double)
+{
+}
+
+double TQWidget::windowOpacity() const
+{
+ return 1.0;
+}
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/kernel/tqwidgetcreate_x11.cpp b/tqtinterface/qt4/src/kernel/tqwidgetcreate_x11.cpp
new file mode 100644
index 0000000..574374d
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwidgetcreate_x11.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Implementation of TQt calls to X11
+**
+** Created : 970529
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwidget.h"
+#include "tqt_x11_p.h"
+
+
+/*
+ Internal TQt functions to create X windows. We have put them in
+ separate functions to allow the programmer to reimplement them by
+ custom versions.
+*/
+
+Window qt_XCreateWindow( const TQWidget*, Display *display, Window tqparent,
+ int x, int y, uint w, uint h,
+ int borderwidth, int depth,
+ uint windowclass, Visual *visual,
+ ulong valuetqmask, XSetWindowAttributes *attributes )
+{
+ return XCreateWindow( display, tqparent, x, y, w, h, borderwidth, depth,
+ windowclass, visual, valuetqmask, attributes );
+}
+
+
+Window qt_XCreateSimpleWindow( const TQWidget*, Display *display, Window tqparent,
+ int x, int y, uint w, uint h, int borderwidth,
+ ulong border, ulong background )
+{
+ return XCreateSimpleWindow( display, tqparent, x, y, w, h, borderwidth,
+ border, background );
+}
+
+
+void qt_XDestroyWindow( const TQWidget*, Display *display, Window window )
+{
+ XDestroyWindow( display, window );
+}
diff --git a/tqtinterface/qt4/src/kernel/tqwidgetintdict.h b/tqtinterface/qt4/src/kernel/tqwidgetintdict.h
new file mode 100644
index 0000000..751c950
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwidgetintdict.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Definition of TQWidgetIntDict
+**
+** Created : 950116
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWIDGETINTDICT_H
+#define TQWIDGETINTDICT_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqintdict.h"
+#endif // TQT_H
+
+
+#if defined(TQ_TEMPLATEDLL)
+//TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQIntDict<TQWidget>;
+//TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQIntDictIterator<TQWidget>;
+#endif
+
+
+class TQ_EXPORT TQWidgetIntDict : public TQIntDict<TQWidget>
+{
+public:
+ TQWidgetIntDict(int size=17) : TQIntDict<TQWidget>(size) {}
+ TQWidgetIntDict( const TQWidgetIntDict &dict ) : TQIntDict<TQWidget>(dict) {}
+ ~TQWidgetIntDict() { clear(); }
+ TQWidgetIntDict &operator=(const TQWidgetIntDict &dict)
+ { return (TQWidgetIntDict&)TQIntDict<TQWidget>::operator=(dict); }
+};
+
+class TQ_EXPORT TQWidgetIntDictIt : public TQIntDictIterator<TQWidget>
+{
+public:
+ TQWidgetIntDictIt( const TQWidgetIntDict &d ) : TQIntDictIterator<TQWidget>(d) {}
+ TQWidgetIntDictIt &operator=(const TQWidgetIntDictIt &i)
+ { return (TQWidgetIntDictIt&)TQIntDictIterator<TQWidget>::operator=(i); }
+};
+
+
+#endif
diff --git a/tqtinterface/qt4/src/kernel/tqwidgetlist.h b/tqtinterface/qt4/src/kernel/tqwidgetlist.h
new file mode 100644
index 0000000..19505a8
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwidgetlist.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Definition of TQWidgetList
+**
+** Created : 950116
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWIDGETLIST_H
+#define TQWIDGETLIST_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqptrlist.h"
+#endif // TQT_H
+
+class TQ_EXPORT TQWidgetList : public TQPtrList<TQWidget>
+{
+public:
+ TQWidgetList() : TQPtrList<TQWidget>() {}
+ TQWidgetList( const TQWidgetList &list ) : TQPtrList<TQWidget>(list) {}
+ ~TQWidgetList() { clear(); }
+ TQWidgetList &operator=(const TQWidgetList &list)
+ { return (TQWidgetList&)TQPtrList<TQWidget>::operator=(list); }
+};
+
+class TQ_EXPORT TQWidgetListIt : public TQPtrListIterator<TQWidget>
+{
+public:
+ TQWidgetListIt( const TQWidgetList &l ) : TQPtrListIterator<TQWidget>(l) {}
+ TQWidgetListIt &operator=(const TQWidgetListIt &i)
+ { return (TQWidgetListIt&)TQPtrListIterator<TQWidget>::operator=(i); }
+};
+
+#endif // TQWIDGETLIST_H
diff --git a/tqtinterface/qt4/src/kernel/tqwindow.cpp b/tqtinterface/qt4/src/kernel/tqwindow.cpp
new file mode 100644
index 0000000..d41de4b
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwindow.cpp
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** Implementation of TQWindow class
+**
+** Created : 931211
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
diff --git a/tqtinterface/qt4/src/kernel/tqwindow.h b/tqtinterface/qt4/src/kernel/tqwindow.h
new file mode 100644
index 0000000..8ed306a
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwindow.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Definition of TQWindow class
+**
+** Created : 931112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWINDOW_H
+#define TQWINDOW_H
+
+#error "TQWindow has gone away"
+
+#endif // TQWINDOW_H
diff --git a/tqtinterface/qt4/src/kernel/tqwindowdefs.h b/tqtinterface/qt4/src/kernel/tqwindowdefs.h
new file mode 100644
index 0000000..e6218f3
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwindowdefs.h
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Definition of general window system dependent functions, types and
+** constants
+**
+** Created : 931029
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWINDOWDEFS_H
+#define TQWINDOWDEFS_H
+
+#ifndef TQT_H
+#include "tqobjectdefs.h"
+#include "tqstring.h"
+#include "tqnamespace.h"
+#endif // TQT_H
+
+// Class forward definitions
+
+class TQPaintDevice;
+class TQPaintDeviceMetrics;
+class TQWidget;
+class TQWidgetMapper;
+class TQDialog;
+class TQColor;
+class TQColorGroup;
+class TQPalette;
+class TQCursor;
+class TQPoint;
+class TQSize;
+class TQRect;
+class TQPointArray;
+class TQPainter;
+class TQRegion;
+class TQFont;
+class TQFontMetrics;
+class TQFontInfo;
+class TQPen;
+class TQBrush;
+class TQWMatrix;
+class TQPixmap;
+class TQBitmap;
+class TQMovie;
+class TQImage;
+class TQImageIO;
+class TQPicture;
+class TQPrinter;
+class TQAccel;
+class TQTimer;
+class TQTime;
+class TQClipboard;
+
+
+// Widget list (defined in tqwidgetlist.h)
+
+class TQWidgetList;
+class TQWidgetListIt;
+
+
+// Window system dependent definitions
+
+#if defined(TQ_WS_MAC)
+#if TQT_MACOSX_VERSION < 0x1020
+typedef struct OpaqueEventLoopTimerRef* EventLoopTimerRef;
+typedef struct OpaqueMenuHandle *MenuRef;
+#else
+typedef struct __EventLoopTimer* EventLoopTimerRef;
+typedef struct OpaqueMenuRef* MenuRef;
+#endif
+
+#ifndef TQ_WS_MACX
+typedef struct CGContext *CGContextRef;
+#endif
+typedef struct OpaqueWindowGroupRef *WindowGroupRef;
+typedef struct OpaqueGrafPtr *CGrafPtr;
+typedef struct OpaquePMPrintSession *PMPrintSession;
+typedef struct OpaquePMPrintSettings *PMPrintSettings;
+typedef struct OpaquePMPageFormat *PMPageFormat;
+typedef struct Point Point;
+typedef struct OpaqueEventHandlerRef* EventHandlerRef;
+typedef struct OpaqueEventHandlerCallRef* EventHandlerCallRef;
+typedef struct OpaqueEventRef* EventRef;
+typedef long int OStqStatus;
+typedef struct OpaqueScrapRef *ScrapRef;
+typedef struct OpaqueRgnHandle *RgnHandle;
+typedef struct OpaqueWindowPtr *WindowPtr;
+typedef WindowPtr WindowRef;
+typedef struct OpaqueGrafPtr *GWorldPtr;
+typedef GWorldPtr GrafPtr;
+typedef struct GDevice **GDHandle;
+typedef struct ColorTable ColorTable;
+typedef struct BitMap BitMap;
+typedef struct EventRecord EventRecord;
+typedef void * MSG;
+typedef int WId;
+typedef struct AEDesc AppleEvent;
+
+#endif // TQ_WS_MAC
+
+#if defined(TQ_WS_WIN)
+#include "tqwindowdefs_win.h"
+#endif // TQ_WS_WIN
+
+
+#if defined(TQ_OS_TEMP)
+#include "tqwinfunctions_wce.h"
+#endif // TQ_OS_TEMP
+
+#if defined(TQ_WS_X11)
+
+typedef struct _XDisplay Display;
+typedef union _XEvent XEvent;
+typedef struct _XGC *GC;
+typedef struct _XRegion *Region;
+typedef unsigned long WId;
+
+TQ_EXPORT Display *qt_xdisplay();
+TQ_EXPORT int qt_xscreen();
+TQ_EXPORT WId qt_xrootwin(); // ### REMOVE 4.0
+TQ_EXPORT WId qt_xrootwin( int scrn ); // ### 4.0 add default arg of -1
+TQ_EXPORT GC qt_xget_readonly_gc( int scrn, bool monochrome );
+TQ_EXPORT GC qt_xget_temp_gc( int scrn, bool monochrome );
+
+TQ_EXPORT const char *tqAppClass(); // get application class
+
+#endif // TQ_WS_X11
+
+#if defined(TQ_WS_TQWS)
+
+typedef unsigned long WId;
+struct TQWSEvent;
+class TQGfx;
+
+#endif // TQ_WS_TQWS
+
+class TQApplication;
+
+#if defined(NEEDS_TQMAIN)
+#define main qMain
+#endif
+
+// Global platform-independent types and functions
+
+typedef TQ_INT32 TQCOORD; // coordinate type
+const TQCOORD TQCOORD_MAX = 2147483647;
+const TQCOORD TQCOORD_MIN = -TQCOORD_MAX - 1;
+
+typedef unsigned int TQRgb; // RGB triplet
+
+TQ_EXPORT const char *tqAppName(); // get application name
+
+// Misc functions
+
+typedef void (*TQtCleanUpFunction)();
+TQ_EXPORT void qAddPostRoutine( TQtCleanUpFunction );
+TQ_EXPORT void qRemovePostRoutine( TQtCleanUpFunction );
+
+#if !defined(TQT_CLEAN_NAMESPACE)
+// source compatibility with TQt 2.x
+typedef TQtCleanUpFunction TQ_CleanUpFunction;
+#endif
+
+
+#endif // TQWINDOWDEFS_H
diff --git a/tqtinterface/qt4/src/kernel/tqwmatrix.cpp b/tqtinterface/qt4/src/kernel/tqwmatrix.cpp
new file mode 100644
index 0000000..ffa0388
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwmatrix.cpp
@@ -0,0 +1,1204 @@
+/****************************************************************************
+**
+** Implementation of TQWMatrix class
+**
+** Created : 941020
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwmatrix.h"
+#include "tqdatastream.h"
+#include "tqregion.h"
+#if defined(TQ_WS_X11)
+double qsincos( double, bool calcCos ); // defined in qpainter_x11.cpp
+#else
+#include <math.h>
+#endif
+
+#include <limits.h>
+
+#ifndef TQT_NO_WMATRIX
+
+#ifdef USE_QT4
+
+// some defines to inline some code
+#define MAPDOUBLE( x, y, nx, ny ) \
+{ \
+ double fx = x; \
+ double fy = y; \
+ nx = m11()*fx + m21()*fy + dx(); \
+ ny = m12()*fx + m22()*fy + dy(); \
+}
+
+#define MAPINT( x, y, nx, ny ) \
+{ \
+ double fx = x; \
+ double fy = y; \
+ nx = tqRound(m11()*fx + m21()*fy + dx()); \
+ ny = tqRound(m12()*fx + m22()*fy + dy()); \
+}
+
+struct TQWMDoublePoint {
+ double x;
+ double y;
+};
+
+bool qt_old_transformations = TRUE;
+
+// TQWMatrix TQWMatrix::invert(bool *invertible=0) {
+// return convertFromQMatrix(inverted(invertible));
+// }
+
+/*!
+ Sets the transformation mode that TQWMatrix and painter
+ transformations use to \a m.
+
+ \sa TQWMatrix::TransformationMode
+*/
+void TQWMatrix::setTransformationMode( TQWMatrix::TransformationMode m )
+{
+ printf("[WARNING] TQWMatrix::setTransformationMode has no effect!\n\r");
+
+ if ( m == TQWMatrix::Points )
+ qt_old_transformations = TRUE;
+ else
+ qt_old_transformations = FALSE;
+}
+
+
+/*!
+ Returns the current transformation mode.
+
+ \sa TQWMatrix::TransformationMode
+*/
+TQWMatrix::TransformationMode TQWMatrix::transformationMode()
+{
+ return (qt_old_transformations ? TQWMatrix::Points : TQWMatrix::Areas );
+}
+
+/*!
+ \internal
+*/
+TQPointArray TQWMatrix::operator *( const TQPointArray &a ) const
+{
+ if( qt_old_transformations ) {
+ TQPointArray result = a.copy();
+ int x, y;
+ for ( int i=0; i<(int)result.size(); i++ ) {
+ result.point( i, &x, &y );
+ MAPINT( x, y, x, y );
+ result.setPoint( i, x, y );
+ }
+ return result;
+ } else {
+ int size = a.size();
+ int i;
+ TQMemArray<TQWMDoublePoint> p( size );
+ const TQPoint *da = TQT_TQPOINT_CONST(a.data());
+ TQWMDoublePoint *dp = p.data();
+ double xmin = INT_MAX;
+ double ymin = xmin;
+ double xmax = INT_MIN;
+ double ymax = xmax;
+ int xminp = 0;
+ int yminp = 0;
+ for( i = 0; i < size; i++ ) {
+ dp[i].x = da[i].x();
+ dp[i].y = da[i].y();
+ if ( dp[i].x < xmin ) {
+ xmin = dp[i].x;
+ xminp = i;
+ }
+ if ( dp[i].y < ymin ) {
+ ymin = dp[i].y;
+ yminp = i;
+ }
+ xmax = TQMAX( xmax, dp[i].x );
+ ymax = TQMAX( ymax, dp[i].y );
+ }
+ double w = TQMAX( xmax - xmin, 1 );
+ double h = TQMAX( ymax - ymin, 1 );
+ for( i = 0; i < size; i++ ) {
+ dp[i].x += (dp[i].x - xmin)/w;
+ dp[i].y += (dp[i].y - ymin)/h;
+ MAPDOUBLE( dp[i].x, dp[i].y, dp[i].x, dp[i].y );
+ }
+
+ // now apply correction back for transformed values...
+ xmin = INT_MAX;
+ ymin = xmin;
+ xmax = INT_MIN;
+ ymax = xmax;
+ for( i = 0; i < size; i++ ) {
+ xmin = TQMIN( xmin, dp[i].x );
+ ymin = TQMIN( ymin, dp[i].y );
+ xmax = TQMAX( xmax, dp[i].x );
+ ymax = TQMAX( ymax, dp[i].y );
+ }
+ w = TQMAX( xmax - xmin, 1 );
+ h = TQMAX( ymax - ymin, 1 );
+
+ TQPointArray result( size );
+ TQPoint *dr = TQT_TQPOINT(result.data());
+ for( i = 0; i < size; i++ ) {
+ dr[i].setX( tqRound( dp[i].x - (dp[i].x - dp[xminp].x)/w ) );
+ dr[i].setY( tqRound( dp[i].y - (dp[i].y - dp[yminp].y)/h ) );
+ }
+ return result;
+ }
+}
+
+/*!
+ Returns the result of multiplying this matrix by matrix \a m.
+*/
+
+TQWMatrix &TQWMatrix::operator*=( const TQWMatrix &m )
+{
+ double tm11 = m11()*m.m11() + m12()*m.m21();
+ double tm12 = m11()*m.m12() + m12()*m.m22();
+ double tm21 = m21()*m.m11() + m22()*m.m21();
+ double tm22 = m21()*m.m12() + m22()*m.m22();
+
+ double tdx = dx()*m.m11() + dy()*m.m21() + m.dx();
+ double tdy = dx()*m.m12() + dy()*m.m22() + m.dy();
+
+ *this = TQWMatrix(tm11, tm12, tm21, tm22, tdx, tdy);
+
+ return *this;
+}
+
+/*!
+ \overload
+ \relates TQWMatrix
+ Returns the product of \a m1 * \a m2.
+
+ Note that matrix multiplication is not commutative, i.e. a*b !=
+ b*a.
+*/
+
+TQWMatrix operator*( const TQWMatrix &m1, const TQWMatrix &m2 )
+{
+ TQWMatrix result = m1;
+ result *= m2;
+ return result;
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQWMatrix tqwmatrix.h
+ \brief The TQWMatrix class specifies 2D transformations of a
+ coordinate system.
+
+ \ingroup graphics
+ \ingroup images
+
+ The standard coordinate system of a \link TQPaintDevice paint
+ tqdevice\endlink has the origin located at the top-left position. X
+ values increase to the right; Y values increase downward.
+
+ This coordinate system is the default for the TQPainter, which
+ renders graphics in a paint tqdevice. A user-defined coordinate
+ system can be specified by setting a TQWMatrix for the painter.
+
+ Example:
+ \code
+ MyWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPainter p; // our painter
+ TQWMatrix m; // our transformation matrix
+ m.rotate( 22.5 ); // rotated coordinate system
+ p.begin( this ); // start painting
+ p.setWorldMatrix( m ); // use rotated coordinate system
+ p.drawText( 30,20, "detator" ); // draw rotated text at 30,20
+ p.end(); // painting done
+ }
+ \endcode
+
+ A matrix specifies how to translate, scale, shear or rotate the
+ graphics; the actual transformation is performed by the drawing
+ routines in TQPainter and by TQPixmap::xForm().
+
+ The TQWMatrix class tqcontains a 3x3 matrix of the form:
+ <table align=center border=1 cellpadding=1 cellspacing=0>
+ <tr align=center><td>m11</td><td>m12</td><td>&nbsp;0 </td></tr>
+ <tr align=center><td>m21</td><td>m22</td><td>&nbsp;0 </td></tr>
+ <tr align=center><td>dx</td> <td>dy</td> <td>&nbsp;1 </td></tr>
+ </table>
+
+ A matrix transforms a point in the plane to another point:
+ \code
+ x' = m11*x + m21*y + dx
+ y' = m22*y + m12*x + dy
+ \endcode
+
+ The point \e (x, y) is the original point, and \e (x', y') is the
+ transformed point. \e (x', y') can be transformed back to \e (x,
+ y) by performing the same operation on the \link
+ TQWMatrix::invert() inverted matrix\endlink.
+
+ The elements \e dx and \e dy specify horizontal and vertical
+ translation. The elements \e m11 and \e m22 specify horizontal and
+ vertical scaling. The elements \e m12 and \e m21 specify
+ horizontal and vertical shearing.
+
+ The identity matrix has \e m11 and \e m22 set to 1; all others are
+ set to 0. This matrix maps a point to itself.
+
+ Translation is the simplest transformation. Setting \e dx and \e
+ dy will move the coordinate system \e dx units along the X axis
+ and \e dy units along the Y axis.
+
+ Scaling can be done by setting \e m11 and \e m22. For example,
+ setting \e m11 to 2 and \e m22 to 1.5 will double the height and
+ increase the width by 50%.
+
+ Shearing is controlled by \e m12 and \e m21. Setting these
+ elements to values different from zero will twist the coordinate
+ system.
+
+ Rotation is achieved by carefully setting both the shearing
+ factors and the scaling factors. The TQWMatrix also has a function
+ that sets \link rotate() rotation \endlink directly.
+
+ TQWMatrix lets you combine transformations like this:
+ \code
+ TQWMatrix m; // identity matrix
+ m.translate(10, -20); // first translate (10,-20)
+ m.rotate(25); // then rotate 25 degrees
+ m.scale(1.2, 0.7); // finally scale it
+ \endcode
+
+ Here's the same example using basic matrix operations:
+ \code
+ double a = pi/180 * 25; // convert 25 to radians
+ double sina = sin(a);
+ double cosa = cos(a);
+ TQWMatrix m1(1, 0, 0, 1, 10, -20); // translation matrix
+ TQWMatrix m2( cosa, sina, // rotation matrix
+ -sina, cosa, 0, 0 );
+ TQWMatrix m3(1.2, 0, 0, 0.7, 0, 0); // scaling matrix
+ TQWMatrix m;
+ m = m3 * m2 * m1; // combine all transformations
+ \endcode
+
+ \l TQPainter has functions to translate, scale, shear and rotate the
+ coordinate system without using a TQWMatrix. Although these
+ functions are very convenient, it can be more efficient to build a
+ TQWMatrix and call TQPainter::setWorldMatrix() if you want to perform
+ more than a single transform operation.
+
+ \sa TQPainter::setWorldMatrix(), TQPixmap::xForm()
+*/
+
+bool qt_old_transformations = TRUE;
+
+/*!
+ \enum TQWMatrix::TransformationMode
+
+ \keyword transformation matrix
+
+ TQWMatrix offers two transformation modes. Calculations can either
+ be done in terms of points (Points mode, the default), or in
+ terms of area (Area mode).
+
+ In Points mode the transformation is applied to the points that
+ mark out the tqshape's bounding line. In Areas mode the
+ transformation is applied in such a way that the area of the
+ contained region is correctly transformed under the matrix.
+
+ \value Points transformations are applied to the tqshape's points.
+ \value Areas transformations are applied (e.g. to the width and
+ height) so that the area is transformed.
+
+ Example:
+
+ Suppose we have a rectangle,
+ \c{TQRect( 10, 20, 30, 40 )} and a transformation matrix
+ \c{TQWMatrix( 2, 0, 0, 2, 0, 0 )} to double the rectangle's size.
+
+ In Points mode, the matrix will transform the top-left (10,20) and
+ the bottom-right (39,59) points producing a rectangle with its
+ top-left point at (20,40) and its bottom-right point at (78,118),
+ i.e. with a width of 59 and a height of 79.
+
+ In Areas mode, the matrix will transform the top-left point in
+ the same way as in Points mode to (20/40), and double the width
+ and height, so the bottom-right will become (69,99), i.e. a width
+ of 60 and a height of 80.
+
+ Because integer arithmetic is used (for speed), rounding
+ differences mean that the modes will produce slightly different
+ results given the same tqshape and the same transformation,
+ especially when scaling up. This also means that some operations
+ are not commutative.
+
+ Under Points mode, \c{matrix * ( region1 | region2 )} is not equal to
+ \c{matrix * region1 | matrix * region2}. Under Area mode, \c{matrix *
+ (pointarray[i])} is not neccesarily equal to
+ \c{(matrix * pointarry)[i]}.
+
+ \img xform.png Comparison of Points and Areas TransformationModes
+*/
+
+/*!
+ Sets the transformation mode that TQWMatrix and painter
+ transformations use to \a m.
+
+ \sa TQWMatrix::TransformationMode
+*/
+void TQWMatrix::setTransformationMode( TQWMatrix::TransformationMode m )
+{
+ if ( m == TQWMatrix::Points )
+ qt_old_transformations = TRUE;
+ else
+ qt_old_transformations = FALSE;
+}
+
+
+/*!
+ Returns the current transformation mode.
+
+ \sa TQWMatrix::TransformationMode
+*/
+TQWMatrix::TransformationMode TQWMatrix::transformationMode()
+{
+ return (qt_old_transformations ? TQWMatrix::Points : TQWMatrix::Areas );
+}
+
+
+// some defines to inline some code
+#define MAPDOUBLE( x, y, nx, ny ) \
+{ \
+ double fx = x; \
+ double fy = y; \
+ nx = _m11*fx + _m21*fy + _dx; \
+ ny = _m12*fx + _m22*fy + _dy; \
+}
+
+#define MAPINT( x, y, nx, ny ) \
+{ \
+ double fx = x; \
+ double fy = y; \
+ nx = tqRound(_m11*fx + _m21*fy + _dx); \
+ ny = tqRound(_m12*fx + _m22*fy + _dy); \
+}
+
+/*****************************************************************************
+ TQWMatrix member functions
+ *****************************************************************************/
+
+/*!
+ Constructs an identity matrix. All elements are set to zero except
+ \e m11 and \e m22 (scaling), which are set to 1.
+*/
+
+TQWMatrix::TQWMatrix()
+{
+ _m11 = _m22 = 1.0;
+ _m12 = _m21 = _dx = _dy = 0.0;
+}
+
+/*!
+ Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a
+ m22, \a dx and \a dy.
+*/
+
+TQWMatrix::TQWMatrix( double m11, double m12, double m21, double m22,
+ double dx, double dy )
+{
+ _m11 = m11; _m12 = m12;
+ _m21 = m21; _m22 = m22;
+ _dx = dx; _dy = dy;
+}
+
+
+/*!
+ Sets the matrix elements to the specified values, \a m11, \a m12,
+ \a m21, \a m22, \a dx and \a dy.
+*/
+
+void TQWMatrix::setMatrix( double m11, double m12, double m21, double m22,
+ double dx, double dy )
+{
+ _m11 = m11; _m12 = m12;
+ _m21 = m21; _m22 = m22;
+ _dx = dx; _dy = dy;
+}
+
+
+/*!
+ \fn double TQWMatrix::m11() const
+
+ Returns the X scaling factor.
+*/
+
+/*!
+ \fn double TQWMatrix::m12() const
+
+ Returns the vertical shearing factor.
+*/
+
+/*!
+ \fn double TQWMatrix::m21() const
+
+ Returns the horizontal shearing factor.
+*/
+
+/*!
+ \fn double TQWMatrix::m22() const
+
+ Returns the Y scaling factor.
+*/
+
+/*!
+ \fn double TQWMatrix::dx() const
+
+ Returns the horizontal translation.
+*/
+
+/*!
+ \fn double TQWMatrix::dy() const
+
+ Returns the vertical translation.
+*/
+
+
+/*!
+ \overload
+
+ Transforms ( \a x, \a y ) to ( \a *tx, \a *ty ) using the
+ following formulae:
+
+ \code
+ *tx = m11*x + m21*y + dx
+ *ty = m22*y + m12*x + dy
+ \endcode
+*/
+
+void TQWMatrix::map( double x, double y, double *tx, double *ty ) const
+{
+ MAPDOUBLE( x, y, *tx, *ty );
+}
+
+/*!
+ Transforms ( \a x, \a y ) to ( \a *tx, \a *ty ) using the formulae:
+
+ \code
+ *tx = m11*x + m21*y + dx (rounded to the nearest integer)
+ *ty = m22*y + m12*x + dy (rounded to the nearest integer)
+ \endcode
+*/
+
+void TQWMatrix::map( int x, int y, int *tx, int *ty ) const
+{
+ MAPINT( x, y, *tx, *ty );
+}
+
+/*!
+ \fn TQPoint TQWMatrix::map( const TQPoint &p ) const
+
+ \overload
+
+ Transforms \a p to using the formulae:
+
+ \code
+ retx = m11*px + m21*py + dx (rounded to the nearest integer)
+ rety = m22*py + m12*px + dy (rounded to the nearest integer)
+ \endcode
+*/
+
+/*!
+ \fn TQRect TQWMatrix::map( const TQRect &r ) const
+
+ \obsolete
+
+ Please use \l TQWMatrix::mapRect() instead.
+
+ Note that this method does return the bounding rectangle of the \a r, when
+ shearing or rotations are used.
+*/
+
+/*!
+ \fn TQPointArray TQWMatrix::map( const TQPointArray &a ) const
+
+ \overload
+
+ Returns the point array \a a transformed by calling map for each point.
+*/
+
+
+/*!
+ \fn TQRegion TQWMatrix::map( const TQRegion &r ) const
+
+ \overload
+
+ Transforms the region \a r.
+
+ Calling this method can be rather expensive, if rotations or
+ shearing are used.
+*/
+
+/*!
+ \fn TQRegion TQWMatrix::mapToRegion( const TQRect &rect ) const
+
+ Returns the transformed rectangle \a rect.
+
+ A rectangle which has been rotated or sheared may result in a
+ non-rectangular region being returned.
+
+ Calling this method can be expensive, if rotations or shearing are
+ used. If you just need to know the bounding rectangle of the
+ returned region, use mapRect() which is a lot faster than this
+ function.
+
+ \sa TQWMatrix::mapRect()
+*/
+
+
+/*!
+ Returns the transformed rectangle \a rect.
+
+ The bounding rectangle is returned if rotation or shearing has
+ been specified.
+
+ If you need to know the exact region \a rect maps to use \l
+ operator*().
+
+ \sa operator*()
+*/
+
+TQRect TQWMatrix::mapRect( const TQRect &rect ) const
+{
+ TQRect result;
+ if( qt_old_transformations ) {
+ if ( _m12 == 0.0F && _m21 == 0.0F ) {
+ result = TQRect( map(rect.topLeft()), map(rect.bottomRight()) ).normalize();
+ } else {
+ TQPointArray a( rect );
+ a = map( a );
+ result = a.boundingRect();
+ }
+ } else {
+ if ( _m12 == 0.0F && _m21 == 0.0F ) {
+ int x = tqRound( _m11*rect.x() + _dx );
+ int y = tqRound( _m22*rect.y() + _dy );
+ int w = tqRound( _m11*rect.width() );
+ int h = tqRound( _m22*rect.height() );
+ if ( w < 0 ) {
+ w = -w;
+ x -= w-1;
+ }
+ if ( h < 0 ) {
+ h = -h;
+ y -= h-1;
+ }
+ result = TQRect( x, y, w, h );
+ } else {
+
+ // see mapToPolygon for explanations of the algorithm.
+ double x0, y0;
+ double x, y;
+ MAPDOUBLE( rect.left(), rect.top(), x0, y0 );
+ double xmin = x0;
+ double ymin = y0;
+ double xmax = x0;
+ double ymax = y0;
+ MAPDOUBLE( rect.right() + 1, rect.top(), x, y );
+ xmin = TQMIN( xmin, x );
+ ymin = TQMIN( ymin, y );
+ xmax = TQMAX( xmax, x );
+ ymax = TQMAX( ymax, y );
+ MAPDOUBLE( rect.right() + 1, rect.bottom() + 1, x, y );
+ xmin = TQMIN( xmin, x );
+ ymin = TQMIN( ymin, y );
+ xmax = TQMAX( xmax, x );
+ ymax = TQMAX( ymax, y );
+ MAPDOUBLE( rect.left(), rect.bottom() + 1, x, y );
+ xmin = TQMIN( xmin, x );
+ ymin = TQMIN( ymin, y );
+ xmax = TQMAX( xmax, x );
+ ymax = TQMAX( ymax, y );
+ double w = xmax - xmin;
+ double h = ymax - ymin;
+ xmin -= ( xmin - x0 ) / w;
+ ymin -= ( ymin - y0 ) / h;
+ xmax -= ( xmax - x0 ) / w;
+ ymax -= ( ymax - y0 ) / h;
+ result = TQRect( tqRound(xmin), tqRound(ymin), tqRound(xmax)-tqRound(xmin)+1, tqRound(ymax)-tqRound(ymin)+1 );
+ }
+ }
+ return result;
+}
+
+
+/*!
+ \internal
+*/
+TQPoint TQWMatrix::operator *( const TQPoint &p ) const
+{
+ double fx = p.x();
+ double fy = p.y();
+ return TQPoint( tqRound(_m11*fx + _m21*fy + _dx),
+ tqRound(_m12*fx + _m22*fy + _dy) );
+}
+
+
+struct TQWMDoublePoint {
+ double x;
+ double y;
+};
+
+/*!
+ \internal
+*/
+TQPointArray TQWMatrix::operator *( const TQPointArray &a ) const
+{
+ if( qt_old_transformations ) {
+ TQPointArray result = a.copy();
+ int x, y;
+ for ( int i=0; i<(int)result.size(); i++ ) {
+ result.point( i, &x, &y );
+ MAPINT( x, y, x, y );
+ result.setPoint( i, x, y );
+ }
+ return result;
+ } else {
+ int size = a.size();
+ int i;
+ TQMemArray<TQWMDoublePoint> p( size );
+ TQPoint *da = a.data();
+ TQWMDoublePoint *dp = p.data();
+ double xmin = INT_MAX;
+ double ymin = xmin;
+ double xmax = INT_MIN;
+ double ymax = xmax;
+ int xminp = 0;
+ int yminp = 0;
+ for( i = 0; i < size; i++ ) {
+ dp[i].x = da[i].x();
+ dp[i].y = da[i].y();
+ if ( dp[i].x < xmin ) {
+ xmin = dp[i].x;
+ xminp = i;
+ }
+ if ( dp[i].y < ymin ) {
+ ymin = dp[i].y;
+ yminp = i;
+ }
+ xmax = TQMAX( xmax, dp[i].x );
+ ymax = TQMAX( ymax, dp[i].y );
+ }
+ double w = TQMAX( xmax - xmin, 1 );
+ double h = TQMAX( ymax - ymin, 1 );
+ for( i = 0; i < size; i++ ) {
+ dp[i].x += (dp[i].x - xmin)/w;
+ dp[i].y += (dp[i].y - ymin)/h;
+ MAPDOUBLE( dp[i].x, dp[i].y, dp[i].x, dp[i].y );
+ }
+
+ // now apply correction back for transformed values...
+ xmin = INT_MAX;
+ ymin = xmin;
+ xmax = INT_MIN;
+ ymax = xmax;
+ for( i = 0; i < size; i++ ) {
+ xmin = TQMIN( xmin, dp[i].x );
+ ymin = TQMIN( ymin, dp[i].y );
+ xmax = TQMAX( xmax, dp[i].x );
+ ymax = TQMAX( ymax, dp[i].y );
+ }
+ w = TQMAX( xmax - xmin, 1 );
+ h = TQMAX( ymax - ymin, 1 );
+
+ TQPointArray result( size );
+ TQPoint *dr = result.data();
+ for( i = 0; i < size; i++ ) {
+ dr[i].setX( tqRound( dp[i].x - (dp[i].x - dp[xminp].x)/w ) );
+ dr[i].setY( tqRound( dp[i].y - (dp[i].y - dp[yminp].y)/h ) );
+ }
+ return result;
+ }
+}
+
+/*!
+\internal
+*/
+TQRegion TQWMatrix::operator * (const TQRect &rect ) const
+{
+ TQRegion result;
+ if ( isIdentity() ) {
+ result = rect;
+ } else if ( _m12 == 0.0F && _m21 == 0.0F ) {
+ if( qt_old_transformations ) {
+ result = TQRect( map(rect.topLeft()), map(rect.bottomRight()) ).normalize();
+ } else {
+ int x = tqRound( _m11*rect.x() + _dx );
+ int y = tqRound( _m22*rect.y() + _dy );
+ int w = tqRound( _m11*rect.width() );
+ int h = tqRound( _m22*rect.height() );
+ if ( w < 0 ) {
+ w = -w;
+ x -= w - 1;
+ }
+ if ( h < 0 ) {
+ h = -h;
+ y -= h - 1;
+ }
+ result = TQRect( x, y, w, h );
+ }
+ } else {
+ result = TQRegion( mapToPolygon( rect ) );
+ }
+ return result;
+
+}
+
+/*!
+ Returns the transformed rectangle \a rect as a polygon.
+
+ Polygons and rectangles behave slightly differently
+ when transformed (due to integer rounding), so
+ \c{matrix.map( TQPointArray( rect ) )} is not always the same as
+ \c{matrix.mapToPolygon( rect )}.
+*/
+TQPointArray TQWMatrix::mapToPolygon( const TQRect &rect ) const
+{
+ TQPointArray a( 4 );
+ if ( qt_old_transformations ) {
+ a = TQPointArray( rect );
+ return operator *( a );
+ }
+ double x[4], y[4];
+ if ( _m12 == 0.0F && _m21 == 0.0F ) {
+ x[0] = tqRound( _m11*rect.x() + _dx );
+ y[0] = tqRound( _m22*rect.y() + _dy );
+ double w = tqRound( _m11*rect.width() );
+ double h = tqRound( _m22*rect.height() );
+ if ( w < 0 ) {
+ w = -w;
+ x[0] -= w - 1.;
+ }
+ if ( h < 0 ) {
+ h = -h;
+ y[0] -= h - 1.;
+ }
+ x[1] = x[0]+w-1;
+ x[2] = x[1];
+ x[3] = x[0];
+ y[1] = y[0];
+ y[2] = y[0]+h-1;
+ y[3] = y[2];
+ } else {
+ MAPINT( rect.left(), rect.top(), x[0], y[0] );
+ MAPINT( rect.right() + 1, rect.top(), x[1], y[1] );
+ MAPINT( rect.right() + 1, rect.bottom() + 1, x[2], y[2] );
+ MAPINT( rect.left(), rect.bottom() + 1, x[3], y[3] );
+
+ /*
+ Including rectangles as we have are evil.
+
+ We now have a rectangle that is one pixel to wide and one to
+ high. the tranformed position of the top-left corner is
+ correct. All other points need some adjustments.
+
+ Doing this mathematically exact would force us to calculate some square roots,
+ something we don't want for the sake of speed.
+
+ Instead we use an approximation, that converts to the correct
+ answer when m12 -> 0 and m21 -> 0, and accept smaller
+ errors in the general transformation case.
+
+ The solution is to calculate the width and height of the
+ bounding rect, and scale the points 1/2/3 by (xp-x0)/xw pixel direction
+ to point 0.
+ */
+
+ double xmin = x[0];
+ double ymin = y[0];
+ double xmax = x[0];
+ double ymax = y[0];
+ int i;
+ for( i = 1; i< 4; i++ ) {
+ xmin = TQMIN( xmin, x[i] );
+ ymin = TQMIN( ymin, y[i] );
+ xmax = TQMAX( xmax, x[i] );
+ ymax = TQMAX( ymax, y[i] );
+ }
+ double w = xmax - xmin;
+ double h = ymax - ymin;
+
+ for( i = 1; i < 4; i++ ) {
+ x[i] -= (x[i] - x[0])/w;
+ y[i] -= (y[i] - y[0])/h;
+ }
+ }
+#if 0
+ int i;
+ for( i = 0; i< 4; i++ )
+ qDebug("coords(%d) = (%f/%f) (%d/%d)", i, x[i], y[i], tqRound(x[i]), tqRound(y[i]) );
+ qDebug( "width=%f, height=%f", sqrt( (x[1]-x[0])*(x[1]-x[0]) + (y[1]-y[0])*(y[1]-y[0]) ),
+ sqrt( (x[0]-x[3])*(x[0]-x[3]) + (y[0]-y[3])*(y[0]-y[3]) ) );
+#endif
+ // all coordinates are correctly, tranform to a pointarray
+ // (rounding to the next integer)
+ a.setPoints( 4, tqRound( x[0] ), tqRound( y[0] ),
+ tqRound( x[1] ), tqRound( y[1] ),
+ tqRound( x[2] ), tqRound( y[2] ),
+ tqRound( x[3] ), tqRound( y[3] ) );
+ return a;
+}
+
+/*!
+\internal
+*/
+TQRegion TQWMatrix::operator * (const TQRegion &r ) const
+{
+ if ( isIdentity() )
+ return r;
+ TQMemArray<TQRect> rects = r.rects();
+ TQRegion result;
+ register TQRect *rect = rects.data();
+ register int i = rects.size();
+ if ( _m12 == 0.0F && _m21 == 0.0F && _m11 > 1.0F && _m22 > 1.0F ) {
+ // simple case, no rotation
+ while ( i ) {
+ int x = tqRound( _m11*rect->x() + _dx );
+ int y = tqRound( _m22*rect->y() + _dy );
+ int w = tqRound( _m11*rect->width() );
+ int h = tqRound( _m22*rect->height() );
+ if ( w < 0 ) {
+ w = -w;
+ x -= w-1;
+ }
+ if ( h < 0 ) {
+ h = -h;
+ y -= h-1;
+ }
+ *rect = TQRect( x, y, w, h );
+ rect++;
+ i--;
+ }
+ result.setRects( rects.data(), rects.size() );
+ } else {
+ while ( i ) {
+ result |= operator *( *rect );
+ rect++;
+ i--;
+ }
+ }
+ return result;
+}
+
+/*!
+ Resets the matrix to an identity matrix.
+
+ All elements are set to zero, except \e m11 and \e m22 (scaling)
+ which are set to 1.
+
+ \sa isIdentity()
+*/
+
+void TQWMatrix::reset()
+{
+ _m11 = _m22 = 1.0;
+ _m12 = _m21 = _dx = _dy = 0.0;
+}
+
+/*!
+ Returns TRUE if the matrix is the identity matrix; otherwise returns FALSE.
+
+ \sa reset()
+*/
+bool TQWMatrix::isIdentity() const
+{
+ return _m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0
+ && _dx == 0.0 && _dy == 0.0;
+}
+
+/*!
+ Moves the coordinate system \a dx along the X-axis and \a dy along
+ the Y-axis.
+
+ Returns a reference to the matrix.
+
+ \sa scale(), shear(), rotate()
+*/
+
+TQWMatrix &TQWMatrix::translate( double dx, double dy )
+{
+ _dx += dx*_m11 + dy*_m21;
+ _dy += dy*_m22 + dx*_m12;
+ return *this;
+}
+
+/*!
+ Scales the coordinate system unit by \a sx horizontally and \a sy
+ vertically.
+
+ Returns a reference to the matrix.
+
+ \sa translate(), shear(), rotate()
+*/
+
+TQWMatrix &TQWMatrix::scale( double sx, double sy )
+{
+ _m11 *= sx;
+ _m12 *= sx;
+ _m21 *= sy;
+ _m22 *= sy;
+ return *this;
+}
+
+/*!
+ Shears the coordinate system by \a sh horizontally and \a sv
+ vertically.
+
+ Returns a reference to the matrix.
+
+ \sa translate(), scale(), rotate()
+*/
+
+TQWMatrix &TQWMatrix::shear( double sh, double sv )
+{
+ double tm11 = sv*_m21;
+ double tm12 = sv*_m22;
+ double tm21 = sh*_m11;
+ double tm22 = sh*_m12;
+ _m11 += tm11;
+ _m12 += tm12;
+ _m21 += tm21;
+ _m22 += tm22;
+ return *this;
+}
+
+const double deg2rad = 0.017453292519943295769; // pi/180
+
+/*!
+ Rotates the coordinate system \a a degrees counterclockwise.
+
+ Returns a reference to the matrix.
+
+ \sa translate(), scale(), shear()
+*/
+
+TQWMatrix &TQWMatrix::rotate( double a )
+{
+ double b = deg2rad*a; // convert to radians
+#if defined(TQ_WS_X11)
+ double sina = qsincos(b,FALSE); // fast and convenient
+ double cosa = qsincos(b,TRUE);
+#else
+ double sina = sin(b);
+ double cosa = cos(b);
+#endif
+ double tm11 = cosa*_m11 + sina*_m21;
+ double tm12 = cosa*_m12 + sina*_m22;
+ double tm21 = -sina*_m11 + cosa*_m21;
+ double tm22 = -sina*_m12 + cosa*_m22;
+ _m11 = tm11; _m12 = tm12;
+ _m21 = tm21; _m22 = tm22;
+ return *this;
+}
+
+/*!
+ \fn bool TQWMatrix::isInvertible() const
+
+ Returns TRUE if the matrix is invertible; otherwise returns FALSE.
+
+ \sa invert()
+*/
+
+/*!
+ \fn double TQWMatrix::det() const
+
+ Returns the matrix's determinant.
+*/
+
+
+/*!
+ Returns the inverted matrix.
+
+ If the matrix is singular (not invertible), the identity matrix is
+ returned.
+
+ If \a invertible is not 0: the value of \a *invertible is set
+ to TRUE if the matrix is invertible; otherwise \a *invertible is
+ set to FALSE.
+
+ \sa isInvertible()
+*/
+
+TQWMatrix TQWMatrix::invert( bool *invertible ) const
+{
+ double determinant = det();
+ if ( determinant == 0.0 ) {
+ if ( invertible )
+ *invertible = FALSE; // singular matrix
+ TQWMatrix defaultMatrix;
+ return defaultMatrix;
+ }
+ else { // invertible matrix
+ if ( invertible )
+ *invertible = TRUE;
+ double dinv = 1.0/determinant;
+ TQWMatrix imatrix( (_m22*dinv), (-_m12*dinv),
+ (-_m21*dinv), ( _m11*dinv),
+ ((_m21*_dy - _m22*_dx)*dinv),
+ ((_m12*_dx - _m11*_dy)*dinv) );
+ return imatrix;
+ }
+}
+
+
+/*!
+ Returns TRUE if this matrix is equal to \a m; otherwise returns FALSE.
+*/
+
+bool TQWMatrix::operator==( const TQWMatrix &m ) const
+{
+ return _m11 == m._m11 &&
+ _m12 == m._m12 &&
+ _m21 == m._m21 &&
+ _m22 == m._m22 &&
+ _dx == m._dx &&
+ _dy == m._dy;
+}
+
+/*!
+ Returns TRUE if this matrix is not equal to \a m; otherwise returns FALSE.
+*/
+
+bool TQWMatrix::operator!=( const TQWMatrix &m ) const
+{
+ return _m11 != m._m11 ||
+ _m12 != m._m12 ||
+ _m21 != m._m21 ||
+ _m22 != m._m22 ||
+ _dx != m._dx ||
+ _dy != m._dy;
+}
+
+/*!
+ Returns the result of multiplying this matrix by matrix \a m.
+*/
+
+TQWMatrix &TQWMatrix::operator*=( const TQWMatrix &m )
+{
+ double tm11 = _m11*m._m11 + _m12*m._m21;
+ double tm12 = _m11*m._m12 + _m12*m._m22;
+ double tm21 = _m21*m._m11 + _m22*m._m21;
+ double tm22 = _m21*m._m12 + _m22*m._m22;
+
+ double tdx = _dx*m._m11 + _dy*m._m21 + m._dx;
+ double tdy = _dx*m._m12 + _dy*m._m22 + m._dy;
+
+ _m11 = tm11; _m12 = tm12;
+ _m21 = tm21; _m22 = tm22;
+ _dx = tdx; _dy = tdy;
+ return *this;
+}
+
+/*!
+ \overload
+ \relates TQWMatrix
+ Returns the product of \a m1 * \a m2.
+
+ Note that matrix multiplication is not commutative, i.e. a*b !=
+ b*a.
+*/
+
+TQWMatrix operator*( const TQWMatrix &m1, const TQWMatrix &m2 )
+{
+ TQWMatrix result = m1;
+ result *= m2;
+ return result;
+}
+
+/*****************************************************************************
+ TQWMatrix stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQWMatrix
+
+ Writes the matrix \a m to the stream \a s and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQWMatrix &m )
+{
+ if ( s.version() == 1 )
+ s << (float)m.m11() << (float)m.m12() << (float)m.m21()
+ << (float)m.m22() << (float)m.dx() << (float)m.dy();
+ else
+ s << m.m11() << m.m12() << m.m21() << m.m22()
+ << m.dx() << m.dy();
+ return s;
+}
+
+/*!
+ \relates TQWMatrix
+
+ Reads the matrix \a m from the stream \a s and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQWMatrix &m )
+{
+ if ( s.version() == 1 ) {
+ float m11, m12, m21, m22, dx, dy;
+ s >> m11; s >> m12; s >> m21; s >> m22;
+ s >> dx; s >> dy;
+ m.setMatrix( m11, m12, m21, m22, dx, dy );
+ }
+ else {
+ double m11, m12, m21, m22, dx, dy;
+ s >> m11; s >> m12; s >> m21; s >> m22;
+ s >> dx; s >> dy;
+ m.setMatrix( m11, m12, m21, m22, dx, dy );
+ }
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+#endif // USE_QT4
+
+#endif // TQT_NO_WMATRIX
+
diff --git a/tqtinterface/qt4/src/kernel/tqwmatrix.cpp~ b/tqtinterface/qt4/src/kernel/tqwmatrix.cpp~
new file mode 100644
index 0000000..f95b660
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwmatrix.cpp~
@@ -0,0 +1,1204 @@
+/****************************************************************************
+**
+** Implementation of TQWMatrix class
+**
+** Created : 941020
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwmatrix.h"
+#include "tqdatastream.h"
+#include "tqregion.h"
+#if defined(TQ_WS_X11)
+double qsincos( double, bool calcCos ); // defined in qpainter_x11.cpp
+#else
+#include <math.h>
+#endif
+
+#include <limits.h>
+
+#ifndef TQT_NO_WMATRIX
+
+#ifdef USE_QT4
+
+// some defines to inline some code
+#define MAPDOUBLE( x, y, nx, ny ) \
+{ \
+ double fx = x; \
+ double fy = y; \
+ nx = m11()*fx + m21()*fy + dx(); \
+ ny = m12()*fx + m22()*fy + dy(); \
+}
+
+#define MAPINT( x, y, nx, ny ) \
+{ \
+ double fx = x; \
+ double fy = y; \
+ nx = tqRound(m11()*fx + m21()*fy + dx()); \
+ ny = tqRound(m12()*fx + m22()*fy + dy()); \
+}
+
+struct TQWMDoublePoint {
+ double x;
+ double y;
+};
+
+bool qt_old_transformations = TRUE;
+
+// TQWMatrix TQWMatrix::invert(bool *invertible=0) {
+// return convertFromQMatrix(inverted(invertible));
+// }
+
+/*!
+ Sets the transformation mode that TQWMatrix and painter
+ transformations use to \a m.
+
+ \sa TQWMatrix::TransformationMode
+*/
+void TQWMatrix::setTransformationMode( TQWMatrix::TransformationMode m )
+{
+ printf("[WARNING] TQWMatrix::setTransformationMode has no effect!\n\r");
+
+ if ( m == TQWMatrix::Points )
+ qt_old_transformations = TRUE;
+ else
+ qt_old_transformations = FALSE;
+}
+
+
+/*!
+ Returns the current transformation mode.
+
+ \sa TQWMatrix::TransformationMode
+*/
+TQWMatrix::TransformationMode TQWMatrix::transformationMode()
+{
+ return (qt_old_transformations ? TQWMatrix::Points : TQWMatrix::Areas );
+}
+
+/*!
+ \internal
+*/
+TQPointArray TQWMatrix::operator *( const TQPointArray &a ) const
+{
+ if( qt_old_transformations ) {
+ TQPointArray result = a.copy();
+ int x, y;
+ for ( int i=0; i<(int)result.size(); i++ ) {
+ result.point( i, &x, &y );
+ MAPINT( x, y, x, y );
+ result.setPoint( i, x, y );
+ }
+ return result;
+ } else {
+ int size = a.size();
+ int i;
+ TQMemArray<TQWMDoublePoint> p( size );
+ TQPoint *da = TQT_TQPOINT_CONST(a.data());
+ TQWMDoublePoint *dp = p.data();
+ double xmin = INT_MAX;
+ double ymin = xmin;
+ double xmax = INT_MIN;
+ double ymax = xmax;
+ int xminp = 0;
+ int yminp = 0;
+ for( i = 0; i < size; i++ ) {
+ dp[i].x = da[i].x();
+ dp[i].y = da[i].y();
+ if ( dp[i].x < xmin ) {
+ xmin = dp[i].x;
+ xminp = i;
+ }
+ if ( dp[i].y < ymin ) {
+ ymin = dp[i].y;
+ yminp = i;
+ }
+ xmax = TQMAX( xmax, dp[i].x );
+ ymax = TQMAX( ymax, dp[i].y );
+ }
+ double w = TQMAX( xmax - xmin, 1 );
+ double h = TQMAX( ymax - ymin, 1 );
+ for( i = 0; i < size; i++ ) {
+ dp[i].x += (dp[i].x - xmin)/w;
+ dp[i].y += (dp[i].y - ymin)/h;
+ MAPDOUBLE( dp[i].x, dp[i].y, dp[i].x, dp[i].y );
+ }
+
+ // now apply correction back for transformed values...
+ xmin = INT_MAX;
+ ymin = xmin;
+ xmax = INT_MIN;
+ ymax = xmax;
+ for( i = 0; i < size; i++ ) {
+ xmin = TQMIN( xmin, dp[i].x );
+ ymin = TQMIN( ymin, dp[i].y );
+ xmax = TQMAX( xmax, dp[i].x );
+ ymax = TQMAX( ymax, dp[i].y );
+ }
+ w = TQMAX( xmax - xmin, 1 );
+ h = TQMAX( ymax - ymin, 1 );
+
+ TQPointArray result( size );
+ TQPoint *dr = TQT_TQPOINT(result.data());
+ for( i = 0; i < size; i++ ) {
+ dr[i].setX( tqRound( dp[i].x - (dp[i].x - dp[xminp].x)/w ) );
+ dr[i].setY( tqRound( dp[i].y - (dp[i].y - dp[yminp].y)/h ) );
+ }
+ return result;
+ }
+}
+
+/*!
+ Returns the result of multiplying this matrix by matrix \a m.
+*/
+
+TQWMatrix &TQWMatrix::operator*=( const TQWMatrix &m )
+{
+ double tm11 = m11()*m.m11() + m12()*m.m21();
+ double tm12 = m11()*m.m12() + m12()*m.m22();
+ double tm21 = m21()*m.m11() + m22()*m.m21();
+ double tm22 = m21()*m.m12() + m22()*m.m22();
+
+ double tdx = dx()*m.m11() + dy()*m.m21() + m.dx();
+ double tdy = dx()*m.m12() + dy()*m.m22() + m.dy();
+
+ *this = TQWMatrix(tm11, tm12, tm21, tm22, tdx, tdy);
+
+ return *this;
+}
+
+/*!
+ \overload
+ \relates TQWMatrix
+ Returns the product of \a m1 * \a m2.
+
+ Note that matrix multiplication is not commutative, i.e. a*b !=
+ b*a.
+*/
+
+TQWMatrix operator*( const TQWMatrix &m1, const TQWMatrix &m2 )
+{
+ TQWMatrix result = m1;
+ result *= m2;
+ return result;
+}
+
+#else // USE_QT4
+
+/*!
+ \class TQWMatrix tqwmatrix.h
+ \brief The TQWMatrix class specifies 2D transformations of a
+ coordinate system.
+
+ \ingroup graphics
+ \ingroup images
+
+ The standard coordinate system of a \link TQPaintDevice paint
+ tqdevice\endlink has the origin located at the top-left position. X
+ values increase to the right; Y values increase downward.
+
+ This coordinate system is the default for the TQPainter, which
+ renders graphics in a paint tqdevice. A user-defined coordinate
+ system can be specified by setting a TQWMatrix for the painter.
+
+ Example:
+ \code
+ MyWidget::paintEvent( TQPaintEvent * )
+ {
+ TQPainter p; // our painter
+ TQWMatrix m; // our transformation matrix
+ m.rotate( 22.5 ); // rotated coordinate system
+ p.begin( this ); // start painting
+ p.setWorldMatrix( m ); // use rotated coordinate system
+ p.drawText( 30,20, "detator" ); // draw rotated text at 30,20
+ p.end(); // painting done
+ }
+ \endcode
+
+ A matrix specifies how to translate, scale, shear or rotate the
+ graphics; the actual transformation is performed by the drawing
+ routines in TQPainter and by TQPixmap::xForm().
+
+ The TQWMatrix class tqcontains a 3x3 matrix of the form:
+ <table align=center border=1 cellpadding=1 cellspacing=0>
+ <tr align=center><td>m11</td><td>m12</td><td>&nbsp;0 </td></tr>
+ <tr align=center><td>m21</td><td>m22</td><td>&nbsp;0 </td></tr>
+ <tr align=center><td>dx</td> <td>dy</td> <td>&nbsp;1 </td></tr>
+ </table>
+
+ A matrix transforms a point in the plane to another point:
+ \code
+ x' = m11*x + m21*y + dx
+ y' = m22*y + m12*x + dy
+ \endcode
+
+ The point \e (x, y) is the original point, and \e (x', y') is the
+ transformed point. \e (x', y') can be transformed back to \e (x,
+ y) by performing the same operation on the \link
+ TQWMatrix::invert() inverted matrix\endlink.
+
+ The elements \e dx and \e dy specify horizontal and vertical
+ translation. The elements \e m11 and \e m22 specify horizontal and
+ vertical scaling. The elements \e m12 and \e m21 specify
+ horizontal and vertical shearing.
+
+ The identity matrix has \e m11 and \e m22 set to 1; all others are
+ set to 0. This matrix maps a point to itself.
+
+ Translation is the simplest transformation. Setting \e dx and \e
+ dy will move the coordinate system \e dx units along the X axis
+ and \e dy units along the Y axis.
+
+ Scaling can be done by setting \e m11 and \e m22. For example,
+ setting \e m11 to 2 and \e m22 to 1.5 will double the height and
+ increase the width by 50%.
+
+ Shearing is controlled by \e m12 and \e m21. Setting these
+ elements to values different from zero will twist the coordinate
+ system.
+
+ Rotation is achieved by carefully setting both the shearing
+ factors and the scaling factors. The TQWMatrix also has a function
+ that sets \link rotate() rotation \endlink directly.
+
+ TQWMatrix lets you combine transformations like this:
+ \code
+ TQWMatrix m; // identity matrix
+ m.translate(10, -20); // first translate (10,-20)
+ m.rotate(25); // then rotate 25 degrees
+ m.scale(1.2, 0.7); // finally scale it
+ \endcode
+
+ Here's the same example using basic matrix operations:
+ \code
+ double a = pi/180 * 25; // convert 25 to radians
+ double sina = sin(a);
+ double cosa = cos(a);
+ TQWMatrix m1(1, 0, 0, 1, 10, -20); // translation matrix
+ TQWMatrix m2( cosa, sina, // rotation matrix
+ -sina, cosa, 0, 0 );
+ TQWMatrix m3(1.2, 0, 0, 0.7, 0, 0); // scaling matrix
+ TQWMatrix m;
+ m = m3 * m2 * m1; // combine all transformations
+ \endcode
+
+ \l TQPainter has functions to translate, scale, shear and rotate the
+ coordinate system without using a TQWMatrix. Although these
+ functions are very convenient, it can be more efficient to build a
+ TQWMatrix and call TQPainter::setWorldMatrix() if you want to perform
+ more than a single transform operation.
+
+ \sa TQPainter::setWorldMatrix(), TQPixmap::xForm()
+*/
+
+bool qt_old_transformations = TRUE;
+
+/*!
+ \enum TQWMatrix::TransformationMode
+
+ \keyword transformation matrix
+
+ TQWMatrix offers two transformation modes. Calculations can either
+ be done in terms of points (Points mode, the default), or in
+ terms of area (Area mode).
+
+ In Points mode the transformation is applied to the points that
+ mark out the tqshape's bounding line. In Areas mode the
+ transformation is applied in such a way that the area of the
+ contained region is correctly transformed under the matrix.
+
+ \value Points transformations are applied to the tqshape's points.
+ \value Areas transformations are applied (e.g. to the width and
+ height) so that the area is transformed.
+
+ Example:
+
+ Suppose we have a rectangle,
+ \c{TQRect( 10, 20, 30, 40 )} and a transformation matrix
+ \c{TQWMatrix( 2, 0, 0, 2, 0, 0 )} to double the rectangle's size.
+
+ In Points mode, the matrix will transform the top-left (10,20) and
+ the bottom-right (39,59) points producing a rectangle with its
+ top-left point at (20,40) and its bottom-right point at (78,118),
+ i.e. with a width of 59 and a height of 79.
+
+ In Areas mode, the matrix will transform the top-left point in
+ the same way as in Points mode to (20/40), and double the width
+ and height, so the bottom-right will become (69,99), i.e. a width
+ of 60 and a height of 80.
+
+ Because integer arithmetic is used (for speed), rounding
+ differences mean that the modes will produce slightly different
+ results given the same tqshape and the same transformation,
+ especially when scaling up. This also means that some operations
+ are not commutative.
+
+ Under Points mode, \c{matrix * ( region1 | region2 )} is not equal to
+ \c{matrix * region1 | matrix * region2}. Under Area mode, \c{matrix *
+ (pointarray[i])} is not neccesarily equal to
+ \c{(matrix * pointarry)[i]}.
+
+ \img xform.png Comparison of Points and Areas TransformationModes
+*/
+
+/*!
+ Sets the transformation mode that TQWMatrix and painter
+ transformations use to \a m.
+
+ \sa TQWMatrix::TransformationMode
+*/
+void TQWMatrix::setTransformationMode( TQWMatrix::TransformationMode m )
+{
+ if ( m == TQWMatrix::Points )
+ qt_old_transformations = TRUE;
+ else
+ qt_old_transformations = FALSE;
+}
+
+
+/*!
+ Returns the current transformation mode.
+
+ \sa TQWMatrix::TransformationMode
+*/
+TQWMatrix::TransformationMode TQWMatrix::transformationMode()
+{
+ return (qt_old_transformations ? TQWMatrix::Points : TQWMatrix::Areas );
+}
+
+
+// some defines to inline some code
+#define MAPDOUBLE( x, y, nx, ny ) \
+{ \
+ double fx = x; \
+ double fy = y; \
+ nx = _m11*fx + _m21*fy + _dx; \
+ ny = _m12*fx + _m22*fy + _dy; \
+}
+
+#define MAPINT( x, y, nx, ny ) \
+{ \
+ double fx = x; \
+ double fy = y; \
+ nx = tqRound(_m11*fx + _m21*fy + _dx); \
+ ny = tqRound(_m12*fx + _m22*fy + _dy); \
+}
+
+/*****************************************************************************
+ TQWMatrix member functions
+ *****************************************************************************/
+
+/*!
+ Constructs an identity matrix. All elements are set to zero except
+ \e m11 and \e m22 (scaling), which are set to 1.
+*/
+
+TQWMatrix::TQWMatrix()
+{
+ _m11 = _m22 = 1.0;
+ _m12 = _m21 = _dx = _dy = 0.0;
+}
+
+/*!
+ Constructs a matrix with the elements, \a m11, \a m12, \a m21, \a
+ m22, \a dx and \a dy.
+*/
+
+TQWMatrix::TQWMatrix( double m11, double m12, double m21, double m22,
+ double dx, double dy )
+{
+ _m11 = m11; _m12 = m12;
+ _m21 = m21; _m22 = m22;
+ _dx = dx; _dy = dy;
+}
+
+
+/*!
+ Sets the matrix elements to the specified values, \a m11, \a m12,
+ \a m21, \a m22, \a dx and \a dy.
+*/
+
+void TQWMatrix::setMatrix( double m11, double m12, double m21, double m22,
+ double dx, double dy )
+{
+ _m11 = m11; _m12 = m12;
+ _m21 = m21; _m22 = m22;
+ _dx = dx; _dy = dy;
+}
+
+
+/*!
+ \fn double TQWMatrix::m11() const
+
+ Returns the X scaling factor.
+*/
+
+/*!
+ \fn double TQWMatrix::m12() const
+
+ Returns the vertical shearing factor.
+*/
+
+/*!
+ \fn double TQWMatrix::m21() const
+
+ Returns the horizontal shearing factor.
+*/
+
+/*!
+ \fn double TQWMatrix::m22() const
+
+ Returns the Y scaling factor.
+*/
+
+/*!
+ \fn double TQWMatrix::dx() const
+
+ Returns the horizontal translation.
+*/
+
+/*!
+ \fn double TQWMatrix::dy() const
+
+ Returns the vertical translation.
+*/
+
+
+/*!
+ \overload
+
+ Transforms ( \a x, \a y ) to ( \a *tx, \a *ty ) using the
+ following formulae:
+
+ \code
+ *tx = m11*x + m21*y + dx
+ *ty = m22*y + m12*x + dy
+ \endcode
+*/
+
+void TQWMatrix::map( double x, double y, double *tx, double *ty ) const
+{
+ MAPDOUBLE( x, y, *tx, *ty );
+}
+
+/*!
+ Transforms ( \a x, \a y ) to ( \a *tx, \a *ty ) using the formulae:
+
+ \code
+ *tx = m11*x + m21*y + dx (rounded to the nearest integer)
+ *ty = m22*y + m12*x + dy (rounded to the nearest integer)
+ \endcode
+*/
+
+void TQWMatrix::map( int x, int y, int *tx, int *ty ) const
+{
+ MAPINT( x, y, *tx, *ty );
+}
+
+/*!
+ \fn TQPoint TQWMatrix::map( const TQPoint &p ) const
+
+ \overload
+
+ Transforms \a p to using the formulae:
+
+ \code
+ retx = m11*px + m21*py + dx (rounded to the nearest integer)
+ rety = m22*py + m12*px + dy (rounded to the nearest integer)
+ \endcode
+*/
+
+/*!
+ \fn TQRect TQWMatrix::map( const TQRect &r ) const
+
+ \obsolete
+
+ Please use \l TQWMatrix::mapRect() instead.
+
+ Note that this method does return the bounding rectangle of the \a r, when
+ shearing or rotations are used.
+*/
+
+/*!
+ \fn TQPointArray TQWMatrix::map( const TQPointArray &a ) const
+
+ \overload
+
+ Returns the point array \a a transformed by calling map for each point.
+*/
+
+
+/*!
+ \fn TQRegion TQWMatrix::map( const TQRegion &r ) const
+
+ \overload
+
+ Transforms the region \a r.
+
+ Calling this method can be rather expensive, if rotations or
+ shearing are used.
+*/
+
+/*!
+ \fn TQRegion TQWMatrix::mapToRegion( const TQRect &rect ) const
+
+ Returns the transformed rectangle \a rect.
+
+ A rectangle which has been rotated or sheared may result in a
+ non-rectangular region being returned.
+
+ Calling this method can be expensive, if rotations or shearing are
+ used. If you just need to know the bounding rectangle of the
+ returned region, use mapRect() which is a lot faster than this
+ function.
+
+ \sa TQWMatrix::mapRect()
+*/
+
+
+/*!
+ Returns the transformed rectangle \a rect.
+
+ The bounding rectangle is returned if rotation or shearing has
+ been specified.
+
+ If you need to know the exact region \a rect maps to use \l
+ operator*().
+
+ \sa operator*()
+*/
+
+TQRect TQWMatrix::mapRect( const TQRect &rect ) const
+{
+ TQRect result;
+ if( qt_old_transformations ) {
+ if ( _m12 == 0.0F && _m21 == 0.0F ) {
+ result = TQRect( map(rect.topLeft()), map(rect.bottomRight()) ).normalize();
+ } else {
+ TQPointArray a( rect );
+ a = map( a );
+ result = a.boundingRect();
+ }
+ } else {
+ if ( _m12 == 0.0F && _m21 == 0.0F ) {
+ int x = tqRound( _m11*rect.x() + _dx );
+ int y = tqRound( _m22*rect.y() + _dy );
+ int w = tqRound( _m11*rect.width() );
+ int h = tqRound( _m22*rect.height() );
+ if ( w < 0 ) {
+ w = -w;
+ x -= w-1;
+ }
+ if ( h < 0 ) {
+ h = -h;
+ y -= h-1;
+ }
+ result = TQRect( x, y, w, h );
+ } else {
+
+ // see mapToPolygon for explanations of the algorithm.
+ double x0, y0;
+ double x, y;
+ MAPDOUBLE( rect.left(), rect.top(), x0, y0 );
+ double xmin = x0;
+ double ymin = y0;
+ double xmax = x0;
+ double ymax = y0;
+ MAPDOUBLE( rect.right() + 1, rect.top(), x, y );
+ xmin = TQMIN( xmin, x );
+ ymin = TQMIN( ymin, y );
+ xmax = TQMAX( xmax, x );
+ ymax = TQMAX( ymax, y );
+ MAPDOUBLE( rect.right() + 1, rect.bottom() + 1, x, y );
+ xmin = TQMIN( xmin, x );
+ ymin = TQMIN( ymin, y );
+ xmax = TQMAX( xmax, x );
+ ymax = TQMAX( ymax, y );
+ MAPDOUBLE( rect.left(), rect.bottom() + 1, x, y );
+ xmin = TQMIN( xmin, x );
+ ymin = TQMIN( ymin, y );
+ xmax = TQMAX( xmax, x );
+ ymax = TQMAX( ymax, y );
+ double w = xmax - xmin;
+ double h = ymax - ymin;
+ xmin -= ( xmin - x0 ) / w;
+ ymin -= ( ymin - y0 ) / h;
+ xmax -= ( xmax - x0 ) / w;
+ ymax -= ( ymax - y0 ) / h;
+ result = TQRect( tqRound(xmin), tqRound(ymin), tqRound(xmax)-tqRound(xmin)+1, tqRound(ymax)-tqRound(ymin)+1 );
+ }
+ }
+ return result;
+}
+
+
+/*!
+ \internal
+*/
+TQPoint TQWMatrix::operator *( const TQPoint &p ) const
+{
+ double fx = p.x();
+ double fy = p.y();
+ return TQPoint( tqRound(_m11*fx + _m21*fy + _dx),
+ tqRound(_m12*fx + _m22*fy + _dy) );
+}
+
+
+struct TQWMDoublePoint {
+ double x;
+ double y;
+};
+
+/*!
+ \internal
+*/
+TQPointArray TQWMatrix::operator *( const TQPointArray &a ) const
+{
+ if( qt_old_transformations ) {
+ TQPointArray result = a.copy();
+ int x, y;
+ for ( int i=0; i<(int)result.size(); i++ ) {
+ result.point( i, &x, &y );
+ MAPINT( x, y, x, y );
+ result.setPoint( i, x, y );
+ }
+ return result;
+ } else {
+ int size = a.size();
+ int i;
+ TQMemArray<TQWMDoublePoint> p( size );
+ TQPoint *da = a.data();
+ TQWMDoublePoint *dp = p.data();
+ double xmin = INT_MAX;
+ double ymin = xmin;
+ double xmax = INT_MIN;
+ double ymax = xmax;
+ int xminp = 0;
+ int yminp = 0;
+ for( i = 0; i < size; i++ ) {
+ dp[i].x = da[i].x();
+ dp[i].y = da[i].y();
+ if ( dp[i].x < xmin ) {
+ xmin = dp[i].x;
+ xminp = i;
+ }
+ if ( dp[i].y < ymin ) {
+ ymin = dp[i].y;
+ yminp = i;
+ }
+ xmax = TQMAX( xmax, dp[i].x );
+ ymax = TQMAX( ymax, dp[i].y );
+ }
+ double w = TQMAX( xmax - xmin, 1 );
+ double h = TQMAX( ymax - ymin, 1 );
+ for( i = 0; i < size; i++ ) {
+ dp[i].x += (dp[i].x - xmin)/w;
+ dp[i].y += (dp[i].y - ymin)/h;
+ MAPDOUBLE( dp[i].x, dp[i].y, dp[i].x, dp[i].y );
+ }
+
+ // now apply correction back for transformed values...
+ xmin = INT_MAX;
+ ymin = xmin;
+ xmax = INT_MIN;
+ ymax = xmax;
+ for( i = 0; i < size; i++ ) {
+ xmin = TQMIN( xmin, dp[i].x );
+ ymin = TQMIN( ymin, dp[i].y );
+ xmax = TQMAX( xmax, dp[i].x );
+ ymax = TQMAX( ymax, dp[i].y );
+ }
+ w = TQMAX( xmax - xmin, 1 );
+ h = TQMAX( ymax - ymin, 1 );
+
+ TQPointArray result( size );
+ TQPoint *dr = result.data();
+ for( i = 0; i < size; i++ ) {
+ dr[i].setX( tqRound( dp[i].x - (dp[i].x - dp[xminp].x)/w ) );
+ dr[i].setY( tqRound( dp[i].y - (dp[i].y - dp[yminp].y)/h ) );
+ }
+ return result;
+ }
+}
+
+/*!
+\internal
+*/
+TQRegion TQWMatrix::operator * (const TQRect &rect ) const
+{
+ TQRegion result;
+ if ( isIdentity() ) {
+ result = rect;
+ } else if ( _m12 == 0.0F && _m21 == 0.0F ) {
+ if( qt_old_transformations ) {
+ result = TQRect( map(rect.topLeft()), map(rect.bottomRight()) ).normalize();
+ } else {
+ int x = tqRound( _m11*rect.x() + _dx );
+ int y = tqRound( _m22*rect.y() + _dy );
+ int w = tqRound( _m11*rect.width() );
+ int h = tqRound( _m22*rect.height() );
+ if ( w < 0 ) {
+ w = -w;
+ x -= w - 1;
+ }
+ if ( h < 0 ) {
+ h = -h;
+ y -= h - 1;
+ }
+ result = TQRect( x, y, w, h );
+ }
+ } else {
+ result = TQRegion( mapToPolygon( rect ) );
+ }
+ return result;
+
+}
+
+/*!
+ Returns the transformed rectangle \a rect as a polygon.
+
+ Polygons and rectangles behave slightly differently
+ when transformed (due to integer rounding), so
+ \c{matrix.map( TQPointArray( rect ) )} is not always the same as
+ \c{matrix.mapToPolygon( rect )}.
+*/
+TQPointArray TQWMatrix::mapToPolygon( const TQRect &rect ) const
+{
+ TQPointArray a( 4 );
+ if ( qt_old_transformations ) {
+ a = TQPointArray( rect );
+ return operator *( a );
+ }
+ double x[4], y[4];
+ if ( _m12 == 0.0F && _m21 == 0.0F ) {
+ x[0] = tqRound( _m11*rect.x() + _dx );
+ y[0] = tqRound( _m22*rect.y() + _dy );
+ double w = tqRound( _m11*rect.width() );
+ double h = tqRound( _m22*rect.height() );
+ if ( w < 0 ) {
+ w = -w;
+ x[0] -= w - 1.;
+ }
+ if ( h < 0 ) {
+ h = -h;
+ y[0] -= h - 1.;
+ }
+ x[1] = x[0]+w-1;
+ x[2] = x[1];
+ x[3] = x[0];
+ y[1] = y[0];
+ y[2] = y[0]+h-1;
+ y[3] = y[2];
+ } else {
+ MAPINT( rect.left(), rect.top(), x[0], y[0] );
+ MAPINT( rect.right() + 1, rect.top(), x[1], y[1] );
+ MAPINT( rect.right() + 1, rect.bottom() + 1, x[2], y[2] );
+ MAPINT( rect.left(), rect.bottom() + 1, x[3], y[3] );
+
+ /*
+ Including rectangles as we have are evil.
+
+ We now have a rectangle that is one pixel to wide and one to
+ high. the tranformed position of the top-left corner is
+ correct. All other points need some adjustments.
+
+ Doing this mathematically exact would force us to calculate some square roots,
+ something we don't want for the sake of speed.
+
+ Instead we use an approximation, that converts to the correct
+ answer when m12 -> 0 and m21 -> 0, and accept smaller
+ errors in the general transformation case.
+
+ The solution is to calculate the width and height of the
+ bounding rect, and scale the points 1/2/3 by (xp-x0)/xw pixel direction
+ to point 0.
+ */
+
+ double xmin = x[0];
+ double ymin = y[0];
+ double xmax = x[0];
+ double ymax = y[0];
+ int i;
+ for( i = 1; i< 4; i++ ) {
+ xmin = TQMIN( xmin, x[i] );
+ ymin = TQMIN( ymin, y[i] );
+ xmax = TQMAX( xmax, x[i] );
+ ymax = TQMAX( ymax, y[i] );
+ }
+ double w = xmax - xmin;
+ double h = ymax - ymin;
+
+ for( i = 1; i < 4; i++ ) {
+ x[i] -= (x[i] - x[0])/w;
+ y[i] -= (y[i] - y[0])/h;
+ }
+ }
+#if 0
+ int i;
+ for( i = 0; i< 4; i++ )
+ qDebug("coords(%d) = (%f/%f) (%d/%d)", i, x[i], y[i], tqRound(x[i]), tqRound(y[i]) );
+ qDebug( "width=%f, height=%f", sqrt( (x[1]-x[0])*(x[1]-x[0]) + (y[1]-y[0])*(y[1]-y[0]) ),
+ sqrt( (x[0]-x[3])*(x[0]-x[3]) + (y[0]-y[3])*(y[0]-y[3]) ) );
+#endif
+ // all coordinates are correctly, tranform to a pointarray
+ // (rounding to the next integer)
+ a.setPoints( 4, tqRound( x[0] ), tqRound( y[0] ),
+ tqRound( x[1] ), tqRound( y[1] ),
+ tqRound( x[2] ), tqRound( y[2] ),
+ tqRound( x[3] ), tqRound( y[3] ) );
+ return a;
+}
+
+/*!
+\internal
+*/
+TQRegion TQWMatrix::operator * (const TQRegion &r ) const
+{
+ if ( isIdentity() )
+ return r;
+ TQMemArray<TQRect> rects = r.rects();
+ TQRegion result;
+ register TQRect *rect = rects.data();
+ register int i = rects.size();
+ if ( _m12 == 0.0F && _m21 == 0.0F && _m11 > 1.0F && _m22 > 1.0F ) {
+ // simple case, no rotation
+ while ( i ) {
+ int x = tqRound( _m11*rect->x() + _dx );
+ int y = tqRound( _m22*rect->y() + _dy );
+ int w = tqRound( _m11*rect->width() );
+ int h = tqRound( _m22*rect->height() );
+ if ( w < 0 ) {
+ w = -w;
+ x -= w-1;
+ }
+ if ( h < 0 ) {
+ h = -h;
+ y -= h-1;
+ }
+ *rect = TQRect( x, y, w, h );
+ rect++;
+ i--;
+ }
+ result.setRects( rects.data(), rects.size() );
+ } else {
+ while ( i ) {
+ result |= operator *( *rect );
+ rect++;
+ i--;
+ }
+ }
+ return result;
+}
+
+/*!
+ Resets the matrix to an identity matrix.
+
+ All elements are set to zero, except \e m11 and \e m22 (scaling)
+ which are set to 1.
+
+ \sa isIdentity()
+*/
+
+void TQWMatrix::reset()
+{
+ _m11 = _m22 = 1.0;
+ _m12 = _m21 = _dx = _dy = 0.0;
+}
+
+/*!
+ Returns TRUE if the matrix is the identity matrix; otherwise returns FALSE.
+
+ \sa reset()
+*/
+bool TQWMatrix::isIdentity() const
+{
+ return _m11 == 1.0 && _m22 == 1.0 && _m12 == 0.0 && _m21 == 0.0
+ && _dx == 0.0 && _dy == 0.0;
+}
+
+/*!
+ Moves the coordinate system \a dx along the X-axis and \a dy along
+ the Y-axis.
+
+ Returns a reference to the matrix.
+
+ \sa scale(), shear(), rotate()
+*/
+
+TQWMatrix &TQWMatrix::translate( double dx, double dy )
+{
+ _dx += dx*_m11 + dy*_m21;
+ _dy += dy*_m22 + dx*_m12;
+ return *this;
+}
+
+/*!
+ Scales the coordinate system unit by \a sx horizontally and \a sy
+ vertically.
+
+ Returns a reference to the matrix.
+
+ \sa translate(), shear(), rotate()
+*/
+
+TQWMatrix &TQWMatrix::scale( double sx, double sy )
+{
+ _m11 *= sx;
+ _m12 *= sx;
+ _m21 *= sy;
+ _m22 *= sy;
+ return *this;
+}
+
+/*!
+ Shears the coordinate system by \a sh horizontally and \a sv
+ vertically.
+
+ Returns a reference to the matrix.
+
+ \sa translate(), scale(), rotate()
+*/
+
+TQWMatrix &TQWMatrix::shear( double sh, double sv )
+{
+ double tm11 = sv*_m21;
+ double tm12 = sv*_m22;
+ double tm21 = sh*_m11;
+ double tm22 = sh*_m12;
+ _m11 += tm11;
+ _m12 += tm12;
+ _m21 += tm21;
+ _m22 += tm22;
+ return *this;
+}
+
+const double deg2rad = 0.017453292519943295769; // pi/180
+
+/*!
+ Rotates the coordinate system \a a degrees counterclockwise.
+
+ Returns a reference to the matrix.
+
+ \sa translate(), scale(), shear()
+*/
+
+TQWMatrix &TQWMatrix::rotate( double a )
+{
+ double b = deg2rad*a; // convert to radians
+#if defined(TQ_WS_X11)
+ double sina = qsincos(b,FALSE); // fast and convenient
+ double cosa = qsincos(b,TRUE);
+#else
+ double sina = sin(b);
+ double cosa = cos(b);
+#endif
+ double tm11 = cosa*_m11 + sina*_m21;
+ double tm12 = cosa*_m12 + sina*_m22;
+ double tm21 = -sina*_m11 + cosa*_m21;
+ double tm22 = -sina*_m12 + cosa*_m22;
+ _m11 = tm11; _m12 = tm12;
+ _m21 = tm21; _m22 = tm22;
+ return *this;
+}
+
+/*!
+ \fn bool TQWMatrix::isInvertible() const
+
+ Returns TRUE if the matrix is invertible; otherwise returns FALSE.
+
+ \sa invert()
+*/
+
+/*!
+ \fn double TQWMatrix::det() const
+
+ Returns the matrix's determinant.
+*/
+
+
+/*!
+ Returns the inverted matrix.
+
+ If the matrix is singular (not invertible), the identity matrix is
+ returned.
+
+ If \a invertible is not 0: the value of \a *invertible is set
+ to TRUE if the matrix is invertible; otherwise \a *invertible is
+ set to FALSE.
+
+ \sa isInvertible()
+*/
+
+TQWMatrix TQWMatrix::invert( bool *invertible ) const
+{
+ double determinant = det();
+ if ( determinant == 0.0 ) {
+ if ( invertible )
+ *invertible = FALSE; // singular matrix
+ TQWMatrix defaultMatrix;
+ return defaultMatrix;
+ }
+ else { // invertible matrix
+ if ( invertible )
+ *invertible = TRUE;
+ double dinv = 1.0/determinant;
+ TQWMatrix imatrix( (_m22*dinv), (-_m12*dinv),
+ (-_m21*dinv), ( _m11*dinv),
+ ((_m21*_dy - _m22*_dx)*dinv),
+ ((_m12*_dx - _m11*_dy)*dinv) );
+ return imatrix;
+ }
+}
+
+
+/*!
+ Returns TRUE if this matrix is equal to \a m; otherwise returns FALSE.
+*/
+
+bool TQWMatrix::operator==( const TQWMatrix &m ) const
+{
+ return _m11 == m._m11 &&
+ _m12 == m._m12 &&
+ _m21 == m._m21 &&
+ _m22 == m._m22 &&
+ _dx == m._dx &&
+ _dy == m._dy;
+}
+
+/*!
+ Returns TRUE if this matrix is not equal to \a m; otherwise returns FALSE.
+*/
+
+bool TQWMatrix::operator!=( const TQWMatrix &m ) const
+{
+ return _m11 != m._m11 ||
+ _m12 != m._m12 ||
+ _m21 != m._m21 ||
+ _m22 != m._m22 ||
+ _dx != m._dx ||
+ _dy != m._dy;
+}
+
+/*!
+ Returns the result of multiplying this matrix by matrix \a m.
+*/
+
+TQWMatrix &TQWMatrix::operator*=( const TQWMatrix &m )
+{
+ double tm11 = _m11*m._m11 + _m12*m._m21;
+ double tm12 = _m11*m._m12 + _m12*m._m22;
+ double tm21 = _m21*m._m11 + _m22*m._m21;
+ double tm22 = _m21*m._m12 + _m22*m._m22;
+
+ double tdx = _dx*m._m11 + _dy*m._m21 + m._dx;
+ double tdy = _dx*m._m12 + _dy*m._m22 + m._dy;
+
+ _m11 = tm11; _m12 = tm12;
+ _m21 = tm21; _m22 = tm22;
+ _dx = tdx; _dy = tdy;
+ return *this;
+}
+
+/*!
+ \overload
+ \relates TQWMatrix
+ Returns the product of \a m1 * \a m2.
+
+ Note that matrix multiplication is not commutative, i.e. a*b !=
+ b*a.
+*/
+
+TQWMatrix operator*( const TQWMatrix &m1, const TQWMatrix &m2 )
+{
+ TQWMatrix result = m1;
+ result *= m2;
+ return result;
+}
+
+/*****************************************************************************
+ TQWMatrix stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQWMatrix
+
+ Writes the matrix \a m to the stream \a s and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQWMatrix &m )
+{
+ if ( s.version() == 1 )
+ s << (float)m.m11() << (float)m.m12() << (float)m.m21()
+ << (float)m.m22() << (float)m.dx() << (float)m.dy();
+ else
+ s << m.m11() << m.m12() << m.m21() << m.m22()
+ << m.dx() << m.dy();
+ return s;
+}
+
+/*!
+ \relates TQWMatrix
+
+ Reads the matrix \a m from the stream \a s and returns a reference
+ to the stream.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQWMatrix &m )
+{
+ if ( s.version() == 1 ) {
+ float m11, m12, m21, m22, dx, dy;
+ s >> m11; s >> m12; s >> m21; s >> m22;
+ s >> dx; s >> dy;
+ m.setMatrix( m11, m12, m21, m22, dx, dy );
+ }
+ else {
+ double m11, m12, m21, m22, dx, dy;
+ s >> m11; s >> m12; s >> m21; s >> m22;
+ s >> dx; s >> dy;
+ m.setMatrix( m11, m12, m21, m22, dx, dy );
+ }
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+#endif // USE_QT4
+
+#endif // TQT_NO_WMATRIX
+
diff --git a/tqtinterface/qt4/src/kernel/tqwmatrix.h b/tqtinterface/qt4/src/kernel/tqwmatrix.h
new file mode 100644
index 0000000..81d3734
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwmatrix.h
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Definition of TQWMatrix class
+**
+** Created : 941020
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWMATRIX_H
+#define TQWMATRIX_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqpointarray.h"
+#include "tqrect.h"
+#include "tqregion.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_WMATRIX
+
+#ifdef USE_QT4
+
+#include <Qt/qpixmap.h>
+#include <Qt/qbitmap.h>
+
+// #include "tqimage.h"
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQWMatrix : public QMatrix, virtual public TQt
+{
+public:
+ TQWMatrix() : QMatrix() {}
+ TQWMatrix( double m11, double m12, double m21, double m22, double dx, double dy ) : QMatrix( m11, m12, m21, m22, dx, dy ) {}
+
+ //TQWMatrix invert(bool *invertible=0);
+ inline TQWMatrix invert(bool *invertible=0) const { const QMatrix &ref = inverted(invertible); return (*static_cast<const TQWMatrix*>(&ref)); }
+ inline TQWMatrix translate( double dx, double dy ) { const QMatrix &ref = this->translate(dx, dy); return (*static_cast<const TQWMatrix*>(&ref)); }
+
+ inline TQRect map(const QRect &r) const { return mapRect(r); }
+
+ inline void map( int x, int y, int *tx, int *ty ) const { return QMatrix::map(x, y, tx, ty); }
+ inline void map( double x, double y, double *tx, double *ty ) const { return QMatrix::map(x, y, tx, ty); }
+ inline TQPoint map( const QPoint &p ) const { return QMatrix::map(p); }
+ inline TQRegion map( const QRegion &r ) const { return QMatrix::map(r); }
+ inline TQPointArray map( const TQPointArray &a ) const { return operator * ( a ); }
+
+ TQRegion mapToRegion(const QRect &r) const;
+
+ enum TransformationMode {
+ Points, Areas
+ };
+ static void setTransformationMode( TQWMatrix::TransformationMode m );
+ static TransformationMode transformationMode();
+
+ TQPointArray operator * ( const TQPointArray &a ) const;
+
+ TQWMatrix &operator*=( const TQWMatrix & );
+
+ // Interoperability
+ inline TQWMatrix &operator=( const QMatrix &qm ) { return *this = qm; }
+
+// TQWMatrix(QMatrix a) {
+// setMatrix(a.m11(), a.m12()
+// }
+
+// inline operator QMatrix() const { return *this; }
+
+ // Interoperability
+ static const TQWMatrix& convertFromQMatrix( QMatrix& qs );
+};
+
+// Interoperability
+inline static const TQWMatrix& convertFromQMatrix( const QMatrix& qs ) {
+ return (*static_cast<const TQWMatrix*>(&qs));
+}
+
+TQ_EXPORT TQWMatrix operator*( const TQWMatrix &, const TQWMatrix & );
+
+#else // USE_QT4
+
+class TQ_EXPORT TQWMatrix // 2D transform matrix
+{
+public:
+ TQWMatrix();
+ TQWMatrix( double m11, double m12, double m21, double m22,
+ double dx, double dy );
+
+ void setMatrix( double m11, double m12, double m21, double m22,
+ double dx, double dy );
+
+ double m11() const { return _m11; }
+ double m12() const { return _m12; }
+ double m21() const { return _m21; }
+ double m22() const { return _m22; }
+ double dx() const { return _dx; }
+ double dy() const { return _dy; }
+
+ void map( int x, int y, int *tx, int *ty ) const;
+ void map( double x, double y, double *tx, double *ty ) const;
+ TQRect mapRect( const TQRect & ) const;
+
+ TQPoint map( const TQPoint &p ) const { return operator *( p ); }
+ TQRect map( const TQRect &r ) const { return mapRect ( r ); }
+ TQPointArray map( const TQPointArray &a ) const { return operator * ( a ); }
+ TQRegion map( const TQRegion &r ) const { return operator *( r ); }
+ TQRegion mapToRegion( const TQRect &r ) const { return operator *( r ); }
+ TQPointArray mapToPolygon( const TQRect &r ) const;
+
+ void reset();
+ bool isIdentity() const;
+
+ TQWMatrix &translate( double dx, double dy );
+ TQWMatrix &scale( double sx, double sy );
+ TQWMatrix &shear( double sh, double sv );
+ TQWMatrix &rotate( double a );
+
+ bool isInvertible() const { return (_m11*_m22 - _m12*_m21) != 0; }
+ double det() const { return _m11*_m22 - _m12*_m21; }
+
+ TQWMatrix invert( bool * = 0 ) const;
+
+ bool operator==( const TQWMatrix & ) const;
+ bool operator!=( const TQWMatrix & ) const;
+ TQWMatrix &operator*=( const TQWMatrix & );
+
+ /* we use matrix multiplication semantics here */
+ TQPoint operator * (const TQPoint & ) const;
+ TQRegion operator * (const TQRect & ) const;
+ TQRegion operator * (const TQRegion & ) const;
+ TQPointArray operator * ( const TQPointArray &a ) const;
+
+ enum TransformationMode {
+ Points, Areas
+ };
+ static void setTransformationMode( TQWMatrix::TransformationMode m );
+ static TransformationMode transformationMode();
+private:
+ double _m11, _m12;
+ double _m21, _m22;
+ double _dx, _dy;
+};
+
+TQ_EXPORT TQWMatrix operator*( const TQWMatrix &, const TQWMatrix & );
+
+
+/*****************************************************************************
+ TQWMatrix stream functions
+ *****************************************************************************/
+
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQWMatrix & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQWMatrix & );
+
+#endif // USE_QT4
+
+#endif // TQT_NO_WMATRIX
+
+#endif // TQWMATRIX_H
diff --git a/tqtinterface/qt4/src/kernel/tqwmatrix.h~ b/tqtinterface/qt4/src/kernel/tqwmatrix.h~
new file mode 100644
index 0000000..0ce4085
--- /dev/null
+++ b/tqtinterface/qt4/src/kernel/tqwmatrix.h~
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Definition of TQWMatrix class
+**
+** Created : 941020
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWMATRIX_H
+#define TQWMATRIX_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#include "tqpointarray.h"
+#include "tqrect.h"
+#include "tqregion.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_WMATRIX
+
+#ifdef USE_QT4
+
+#include <Qt/qpixmap.h>
+#include <Qt/qbitmap.h>
+
+// #include "tqimage.h"
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQWMatrix : public QMatrix, virtual public TQt
+{
+public:
+ TQWMatrix() : QMatrix() {}
+ TQWMatrix( double m11, double m12, double m21, double m22, double dx, double dy ) : QMatrix( m11, m12, m21, m22, dx, dy ) {}
+
+ //TQWMatrix invert(bool *invertible=0);
+ inline TQWMatrix invert(bool *invertible=0) const { const QMatrix &ref = inverted(invertible); return (*static_cast<const TQWMatrix*>(&ref)); }
+
+ inline TQRect map(const QRect &r) const { return mapRect(r); }
+
+ inline void map( int x, int y, int *tx, int *ty ) const { return QMatrix::map(x, y, tx, ty); }
+ inline void map( double x, double y, double *tx, double *ty ) const { return QMatrix::map(x, y, tx, ty); }
+ inline TQPoint map( const QPoint &p ) const { return QMatrix::map(p); }
+ inline TQRegion map( const QRegion &r ) const { return QMatrix::map(r); }
+ TQPointArray map( const TQPointArray &a ) const;
+
+ TQRegion mapToRegion(const QRect &r) const;
+
+ enum TransformationMode {
+ Points, Areas
+ };
+ static void setTransformationMode( TQWMatrix::TransformationMode m );
+ static TransformationMode transformationMode();
+
+ TQPointArray operator * ( const TQPointArray &a ) const;
+
+ TQWMatrix &operator*=( const TQWMatrix & );
+
+ // Interoperability
+ inline TQWMatrix &operator=( const QMatrix &qm ) { return *this = qm; }
+
+// TQWMatrix(QMatrix a) {
+// setMatrix(a.m11(), a.m12()
+// }
+
+// inline operator QMatrix() const { return *this; }
+
+ // Interoperability
+ static const TQWMatrix& convertFromQMatrix( QMatrix& qs );
+};
+
+// Interoperability
+inline static const TQWMatrix& convertFromQMatrix( const QMatrix& qs ) {
+ return (*static_cast<const TQWMatrix*>(&qs));
+}
+
+TQ_EXPORT TQWMatrix operator*( const TQWMatrix &, const TQWMatrix & );
+
+#else // USE_QT4
+
+class TQ_EXPORT TQWMatrix // 2D transform matrix
+{
+public:
+ TQWMatrix();
+ TQWMatrix( double m11, double m12, double m21, double m22,
+ double dx, double dy );
+
+ void setMatrix( double m11, double m12, double m21, double m22,
+ double dx, double dy );
+
+ double m11() const { return _m11; }
+ double m12() const { return _m12; }
+ double m21() const { return _m21; }
+ double m22() const { return _m22; }
+ double dx() const { return _dx; }
+ double dy() const { return _dy; }
+
+ void map( int x, int y, int *tx, int *ty ) const;
+ void map( double x, double y, double *tx, double *ty ) const;
+ TQRect mapRect( const TQRect & ) const;
+
+ TQPoint map( const TQPoint &p ) const { return operator *( p ); }
+ TQRect map( const TQRect &r ) const { return mapRect ( r ); }
+ TQPointArray map( const TQPointArray &a ) const { return operator * ( a ); }
+ TQRegion map( const TQRegion &r ) const { return operator *( r ); }
+ TQRegion mapToRegion( const TQRect &r ) const { return operator *( r ); }
+ TQPointArray mapToPolygon( const TQRect &r ) const;
+
+ void reset();
+ bool isIdentity() const;
+
+ TQWMatrix &translate( double dx, double dy );
+ TQWMatrix &scale( double sx, double sy );
+ TQWMatrix &shear( double sh, double sv );
+ TQWMatrix &rotate( double a );
+
+ bool isInvertible() const { return (_m11*_m22 - _m12*_m21) != 0; }
+ double det() const { return _m11*_m22 - _m12*_m21; }
+
+ TQWMatrix invert( bool * = 0 ) const;
+
+ bool operator==( const TQWMatrix & ) const;
+ bool operator!=( const TQWMatrix & ) const;
+ TQWMatrix &operator*=( const TQWMatrix & );
+
+ /* we use matrix multiplication semantics here */
+ TQPoint operator * (const TQPoint & ) const;
+ TQRegion operator * (const TQRect & ) const;
+ TQRegion operator * (const TQRegion & ) const;
+ TQPointArray operator * ( const TQPointArray &a ) const;
+
+ enum TransformationMode {
+ Points, Areas
+ };
+ static void setTransformationMode( TQWMatrix::TransformationMode m );
+ static TransformationMode transformationMode();
+private:
+ double _m11, _m12;
+ double _m21, _m22;
+ double _dx, _dy;
+};
+
+TQ_EXPORT TQWMatrix operator*( const TQWMatrix &, const TQWMatrix & );
+
+
+/*****************************************************************************
+ TQWMatrix stream functions
+ *****************************************************************************/
+
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQWMatrix & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQWMatrix & );
+
+#endif // USE_QT4
+
+#endif // TQT_NO_WMATRIX
+
+#endif // TQWMATRIX_H
diff --git a/tqtinterface/qt4/src/libtqt.map b/tqtinterface/qt4/src/libtqt.map
new file mode 100644
index 0000000..135f4b2
--- /dev/null
+++ b/tqtinterface/qt4/src/libtqt.map
@@ -0,0 +1,50 @@
+{
+ global:
+ extern "C++"
+ {
+ TQGuardedPtrPrivate::*
+ };
+ local:
+ extern "C++"
+ {
+ TQClipboardWatcher::*;
+ TQColorLuminancePicker::*;
+ TQErrorMessageTextView::*;
+ TQETWidget::*;
+ TQFDProgress*;
+ TQFileDialogQFileListView::*;
+ TQFtpDTP::*;
+ TQFtpPI*;
+ TQHttpNormalRequest::*;
+ TQHttpRequest::*;
+ TQHttpResponseHeader::*;
+ TQMainWindowLayout::*;
+ TQ*Private::*; # collides with QGuardedPtrPrivate
+ TQPSPrinter*;
+ TQ*RegExpEngine::*;
+ TQ*SvgDevice::*;
+ *TQSvgDeviceState*;
+ ImgElement::*;
+ PixElement::*;
+ TQRenameEdit::*;
+ TQRollEffect::*;
+ TQSharedDoubleBufferCleaner::*;
+ TQSmSocketReceiver::*;
+ TQSpinBoxValidator::*;
+ TQSplitterHandle::*;
+ TQSqlRecordShared::*;
+ TQSVChildRec::*;
+ qt_xdnd_*;
+ TQTipLabel::*;
+ TQUnicodeTables::*;
+ TQViewportWidget::*;
+ TQWFlagWidget::*;
+ TQWorkspaceChild::*;
+ TQFontDef::*;
+ TQFontStruct::*;
+ TQFont*Codec::*;
+ TQInputContext::*
+ };
+ TT_*;
+ TTO_*;
+};
diff --git a/tqtinterface/qt4/src/network/qt_network.pri b/tqtinterface/qt4/src/network/qt_network.pri
new file mode 100644
index 0000000..6b8986a
--- /dev/null
+++ b/tqtinterface/qt4/src/network/qt_network.pri
@@ -0,0 +1,23 @@
+# Qt network module
+
+network {
+ HEADERS += $$NETWORK_H/tqdns.h \
+ $$NETWORK_H/tqftp.h \
+ $$NETWORK_H/tqhttp.h \
+ $$NETWORK_H/tqhostaddress.h \
+ $$NETWORK_H/tqnetwork.h \
+ $$NETWORK_H/tqserversocket.h \
+ $$NETWORK_H/tqsocket.h \
+ $$NETWORK_H/tqsocketdevice.h
+ NETWORK_SOURCES = $$NETWORK_CPP/tqdns.cpp \
+ $$NETWORK_CPP/tqftp.cpp \
+ $$NETWORK_CPP/tqhttp.cpp \
+ $$NETWORK_CPP/tqhostaddress.cpp \
+ $$NETWORK_CPP/tqnetwork.cpp \
+ $$NETWORK_CPP/tqserversocket.cpp \
+ $$NETWORK_CPP/tqsocket.cpp \
+ $$NETWORK_CPP/tqsocketdevice.cpp
+ unix:NETWORK_SOURCES += $$NETWORK_CPP/tqsocketdevice_unix.cpp
+ win32:NETWORK_SOURCES += $$NETWORK_CPP/tqsocketdevice_win.cpp
+ SOURCES += $$NETWORK_SOURCES
+}
diff --git a/tqtinterface/qt4/src/network/tqdns.cpp b/tqtinterface/qt4/src/network/tqdns.cpp
new file mode 100644
index 0000000..24b5401
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqdns.cpp
@@ -0,0 +1,5294 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+// #include "Qt/qplatformdefs.h"
+
+#include "Qt/qbytearray.h"
+#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined(Q_OS_CYGWIN)
+# include "qt_windows.h"
+#else
+# include <sys/types.h>
+# include <netinet/in.h>
+# include <arpa/nameser.h>
+# include <resolv.h>
+extern "C" int res_init();
+#endif
+
+// POSIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
+#if defined(connect)
+# undef connect
+#endif
+
+// UnixWare 7 redefines socket -> _socket
+#if defined(socket)
+# undef socket
+#endif
+
+#include "tqdns.h"
+
+#ifndef QT_NO_DNS
+
+#include "Qt/qdatetime.h"
+#include "tqdict.h"
+#include "tqptrlist.h"
+#include "Qt/qstring.h"
+#include "Qt/qtimer.h"
+#include "Qt/qapplication.h"
+#include "tqptrvector.h"
+#include "tqstrlist.h"
+#include "tqptrdict.h"
+#include "Qt/qfile.h"
+#include "Qt/qtextstream.h"
+#include "tqsocketdevice.h"
+#include "tqcleanuphandler.h"
+#include <limits.h>
+
+// #include "Qt/qhostaddress.h"
+// #include "Qt/qsocketnotifier.h"
+
+QT_BEGIN_NAMESPACE
+
+//#define TQDNS_DEBUG
+
+static Q_UINT16 theId; // ### seeded started by now()
+
+
+static QDateTime * originOfTime = 0;
+
+static TQCleanupHandler<QDateTime> q3dns_cleanup_time;
+
+static Q_UINT32 now()
+{
+ if ( originOfTime )
+ return originOfTime->secsTo( QDateTime::currentDateTime() );
+
+ originOfTime = new QDateTime( QDateTime::currentDateTime() );
+ theId = originOfTime->time().msec() * 60 + originOfTime->time().second();
+ q3dns_cleanup_time.add( &originOfTime );
+ return 0;
+}
+
+
+static TQPtrList<TQHostAddress> * theNs = 0;
+static TQStrList * theDomains = 0;
+static bool ipv6support = false;
+
+class TQDnsPrivate {
+public:
+ TQDnsPrivate() : queryTimer( 0 ), noNames(false)
+ {
+#if defined(Q_DNS_SYNCHRONOUS)
+#if defined(Q_OS_UNIX)
+ noEventLoop = qApp==0 || qApp->loopLevel()==0;
+#else
+ noEventLoop = false;
+#endif
+#endif
+ }
+ ~TQDnsPrivate()
+ {
+ delete queryTimer;
+ }
+private:
+ TQTimer * queryTimer;
+ bool noNames;
+#if defined(Q_DNS_SYNCHRONOUS)
+ bool noEventLoop;
+#endif
+
+ friend class TQDns;
+ friend class TQDnsAnswer;
+};
+
+
+class TQDnsRR;
+class TQDnsDomain;
+
+
+
+// TQDnsRR is the class used to store a single RR. TQDnsRR can store
+// all of the supported RR types. a TQDnsRR is always cached.
+
+// TQDnsRR is mostly constructed from the outside. a but hacky, but
+// permissible since the entire class is internal.
+
+class TQDnsRR {
+public:
+ TQDnsRR( const TQString & label );
+ ~TQDnsRR();
+
+public:
+ TQDnsDomain * domain;
+ TQDns::RecordType t;
+ bool nxdomain;
+ bool current;
+ Q_UINT32 expireTime;
+ Q_UINT32 deleteTime;
+ // somewhat space-wasting per-type data
+ // a / aaaa
+ TQHostAddress address;
+ // cname / mx / srv / ptr
+ TQString target;
+ // mx / srv
+ Q_UINT16 priority;
+ // srv
+ Q_UINT16 weight;
+ Q_UINT16 port;
+ // txt
+ TQString text; // could be overloaded into target...
+private:
+
+};
+
+
+class TQDnsDomain {
+public:
+ TQDnsDomain( const TQString & label );
+ ~TQDnsDomain();
+
+ static void add( const TQString & label, TQDnsRR * );
+ static TQPtrList<TQDnsRR> * cached( const TQDns * );
+
+ void take( TQDnsRR * );
+
+ void sweep( Q_UINT32 thisSweep );
+
+ bool isEmpty() const { return rrs == 0 || rrs->isEmpty(); }
+
+ TQString name() const { return l; }
+
+public:
+ TQString l;
+ TQPtrList<TQDnsRR> * rrs;
+};
+
+
+class TQDnsQuery: public TQTimer { // this inheritance is a very evil hack
+public:
+ TQDnsQuery():
+ id( 0 ), t( TQDns::None ), step(0), started(0),
+ dns( new TQPtrDict<void>(17) ) {}
+ ~TQDnsQuery() { delete dns; }
+ Q_UINT16 id;
+ TQDns::RecordType t;
+ TQString l;
+
+ uint step;
+ Q_UINT32 started;
+
+ TQPtrDict<void> * dns;
+};
+
+
+
+class TQDnsAnswer {
+public:
+ TQDnsAnswer( TQDnsQuery * );
+ TQDnsAnswer( const TQByteArray &, TQDnsQuery * );
+ ~TQDnsAnswer();
+
+ void parse();
+ void notify();
+
+ bool ok;
+
+private:
+ TQDnsQuery * query;
+
+ Q_UINT8 * answer;
+ int size;
+ int pp;
+
+ TQPtrList<TQDnsRR> * rrs;
+
+ // convenience
+ int next;
+ int ttl;
+ TQString label;
+ TQDnsRR * rr;
+
+ TQString readString(bool multipleLabels = true);
+ void parseA();
+ void parseAaaa();
+ void parseMx();
+ void parseSrv();
+ void parseCname();
+ void parsePtr();
+ void parseTxt();
+ void parseNs();
+};
+
+
+TQDnsRR::TQDnsRR( const TQString & label )
+ : domain( 0 ), t( TQDns::None ),
+ nxdomain( false ), current( false ),
+ expireTime( 0 ), deleteTime( 0 ),
+ priority( 0 ), weight( 0 ), port( 0 )
+{
+ TQDnsDomain::add( label, this );
+}
+
+
+// not supposed to be deleted except by TQDnsDomain
+TQDnsRR::~TQDnsRR()
+{
+ // nothing is necessary
+}
+
+
+// this one just sticks in a NXDomain
+TQDnsAnswer::TQDnsAnswer( TQDnsQuery * query_ )
+{
+ ok = true;
+
+ answer = 0;
+ size = 0;
+ query = query_;
+ pp = 0;
+ rrs = new TQPtrList<TQDnsRR>;
+ rrs->setAutoDelete( false );
+ next = size;
+ ttl = 0;
+ label.clear();
+ rr = 0;
+
+ TQDnsRR * newrr = new TQDnsRR( query->l );
+ newrr->t = query->t;
+ newrr->deleteTime = query->started + 10;
+ newrr->expireTime = query->started + 10;
+ newrr->nxdomain = true;
+ newrr->current = true;
+ rrs->append( newrr );
+}
+
+
+TQDnsAnswer::TQDnsAnswer( const TQByteArray& answer_,
+ TQDnsQuery * query_ )
+{
+ ok = true;
+
+ answer = (Q_UINT8 *)(answer_.data());
+ size = (int)answer_.size();
+ query = query_;
+ pp = 0;
+ rrs = new TQPtrList<TQDnsRR>;
+ rrs->setAutoDelete( false );
+ next = size;
+ ttl = 0;
+ label.clear();
+ rr = 0;
+}
+
+
+TQDnsAnswer::~TQDnsAnswer()
+{
+ if ( !ok && rrs ) {
+ TQPtrListIterator<TQDnsRR> it( *rrs );
+ TQDnsRR * tmprr;
+ while( (tmprr=it.current()) != 0 ) {
+ ++it;
+ tmprr->t = TQDns::None; // will be deleted soonish
+ }
+ }
+ delete rrs;
+}
+
+
+TQString TQDnsAnswer::readString(bool multipleLabels)
+{
+ int p = pp;
+ TQString r;
+ Q_UINT8 b;
+ for( ;; ) {
+ b = 128;
+ // Read one character
+ if ( p >= 0 && p < size )
+ b = answer[p];
+
+ switch( b >> 6 ) {
+ case 0:
+ // b is less than 64
+ p++;
+
+ // Detect end of data
+ if ( b == 0 ) {
+ if ( p > pp )
+ pp = p;
+ return r.isNull() ? TQT_TQSTRING(TQLatin1String( "." )) : r;
+ }
+
+ // Read a label of size 'b' characters
+ if ( !r.isNull() )
+ r += QLatin1Char('.');
+ while( b-- > 0 )
+ r += QLatin1Char( answer[p++] );
+
+ // Return immediately if we were only supposed to read one
+ // label.
+ if (!multipleLabels)
+ return r;
+
+ break;
+ default:
+ // Ignore unrecognized control character, or p was out of
+ // range.
+ goto not_ok;
+ case 3:
+ // Use the next character to determine the relative offset
+ // to jump to before continuing the packet parsing.
+ int q = ( (answer[p] & 0x3f) << 8 ) + answer[p+1];
+
+ if ( q >= pp || q >= p )
+ goto not_ok;
+ if ( p >= pp )
+ pp = p + 2;
+ p = q;
+ }
+ }
+not_ok:
+ ok = false;
+ return TQString();
+}
+
+
+
+void TQDnsAnswer::parseA()
+{
+ if ( next != pp + 4 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %d bytes long IN A for %s",
+ next - pp, label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->t = TQDns::A;
+ rr->address = TQHostAddress( ( answer[pp+0] << 24 ) +
+ ( answer[pp+1] << 16 ) +
+ ( answer[pp+2] << 8 ) +
+ ( answer[pp+3] ) );
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN A %s (ttl %d)", label.ascii(),
+ rr->address.toString().ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parseAaaa()
+{
+ if ( next != pp + 16 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %d bytes long IN Aaaa for %s",
+ next - pp, label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->t = TQDns::Aaaa;
+ rr->address = TQHostAddress( answer+pp );
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN Aaaa %s (ttl %d)", label.ascii(),
+ rr->address.toString().ascii(), ttl );
+#endif
+}
+
+
+
+void TQDnsAnswer::parseMx()
+{
+ if ( next < pp + 2 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %d bytes long IN MX for %s",
+ next - pp, label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->priority = (answer[pp] << 8) + answer[pp+1];
+ pp += 2;
+ rr->target = readString().lower();
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad string in MX for %s", label.ascii() );
+#endif
+ return;
+ }
+ rr->t = TQDns::Mx;
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN MX %d %s (ttl %d)", label.ascii(),
+ rr->priority, rr->target.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parseSrv()
+{
+ if ( next < pp + 6 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %d bytes long IN SRV for %s",
+ next - pp, label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->priority = (answer[pp] << 8) + answer[pp+1];
+ rr->weight = (answer[pp+2] << 8) + answer[pp+3];
+ rr->port = (answer[pp+4] << 8) + answer[pp+5];
+ pp += 6;
+ rr->target = readString().lower();
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad string in SRV for %s", label.ascii() );
+#endif
+ return;
+ }
+ rr->t = TQDns::Srv;
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN SRV %d %d %d %s (ttl %d)", label.ascii(),
+ rr->priority, rr->weight, rr->port, rr->target.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parseCname()
+{
+ TQString target = readString().lower();
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad cname for for %s", label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->t = TQDns::Cname;
+ rr->target = target;
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN CNAME %s (ttl %d)", label.ascii(),
+ rr->target.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parseNs()
+{
+ TQString target = readString().lower();
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad cname for for %s", label.ascii() );
+#endif
+ return;
+ }
+
+ // parse, but ignore
+
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN NS %s (ttl %d)", label.ascii(),
+ target.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parsePtr()
+{
+ TQString target = readString().lower();
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad PTR for for %s", label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->t = TQDns::Ptr;
+ rr->target = target;
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN PTR %s (ttl %d)", label.ascii(),
+ rr->target.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parseTxt()
+{
+ TQString text = readString(false);
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad TXT for for %s", label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->t = TQDns::Txt;
+ rr->text = text;
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN TXT \"%s\" (ttl %d)", label.ascii(),
+ rr->text.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parse()
+{
+ // okay, do the work...
+ if ( (answer[2] & 0x78) != 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: answer to wrong query type (%d)", answer[1] );
+#endif
+ ok = false;
+ return;
+ }
+
+ // AA
+ bool aa = (answer[2] & 4) != 0;
+
+ // TC
+ if ( (answer[2] & 2) != 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: truncated answer; pressing on" );
+#endif
+ }
+
+ // RD
+ bool rd = (answer[2] & 1) != 0;
+
+ // we don't test RA
+ // we don't test the MBZ fields
+
+ if ( (answer[3] & 0x0f) == 3 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: saw NXDomain for %s", query->l.ascii() );
+#endif
+ // NXDomain. cache that for one minute.
+ rr = new TQDnsRR( query->l );
+ rr->t = query->t;
+ rr->deleteTime = query->started + 60;
+ rr->expireTime = query->started + 60;
+ rr->nxdomain = true;
+ rr->current = true;
+ rrs->append( rr );
+ return;
+ }
+
+ if ( (answer[3] & 0x0f) != 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: error code %d", answer[3] & 0x0f );
+#endif
+ ok = false;
+ return;
+ }
+
+ int qdcount = ( answer[4] << 8 ) + answer[5];
+ int ancount = ( answer[6] << 8 ) + answer[7];
+ int nscount = ( answer[8] << 8 ) + answer[9];
+ int adcount = (answer[10] << 8 ) +answer[11];
+
+ pp = 12;
+
+ // read query
+ while( qdcount > 0 && pp < size ) {
+ // should I compare the string against query->l?
+ (void)readString();
+ if ( !ok )
+ return;
+ pp += 4;
+ qdcount--;
+ }
+
+ // answers and stuff
+ int rrno = 0;
+ // if we parse the answer completely, but there are no answers,
+ // ignore the entire thing.
+ int answers = 0;
+ while( ( rrno < ancount ||
+ ( ok && answers >0 && rrno < ancount + nscount + adcount ) ) &&
+ pp < size ) {
+ label = readString().lower();
+ if ( !ok )
+ return;
+ int rdlength = 0;
+ if ( pp + 10 <= size )
+ rdlength = ( answer[pp+8] << 8 ) + answer[pp+9];
+ if ( pp + 10 + rdlength > size ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: ran out of stuff to parse (%d+%d>%d (%d)",
+ pp, rdlength, size, rrno < ancount );
+#endif
+ // if we're still in the AN section, we should go back and
+ // at least down the TTLs. probably best to invalidate
+ // the results.
+ // the rrs list is good for this
+ ok = ( rrno < ancount );
+ return;
+ }
+ uint type, clas;
+ type = ( answer[pp+0] << 8 ) + answer[pp+1];
+ clas = ( answer[pp+2] << 8 ) + answer[pp+3];
+ ttl = ( answer[pp+4] << 24 ) + ( answer[pp+5] << 16 ) +
+ ( answer[pp+6] << 8 ) + answer[pp+7];
+ pp = pp + 10;
+ if ( clas != 1 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: class %d (not internet) for %s",
+ clas, label.isNull() ? "." : label.ascii() );
+#endif
+ } else {
+ next = pp + rdlength;
+ rr = 0;
+ switch( type ) {
+ case 1:
+ parseA();
+ break;
+ case 28:
+ parseAaaa();
+ break;
+ case 15:
+ parseMx();
+ break;
+ case 33:
+ parseSrv();
+ break;
+ case 5:
+ parseCname();
+ break;
+ case 12:
+ parsePtr();
+ break;
+ case 16:
+ parseTxt();
+ break;
+ case 2:
+ parseNs();
+ break;
+ default:
+ // something we don't know
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: type %d for %s", type,
+ label.isNull() ? "." : label.ascii() );
+#endif
+ break;
+ }
+ if ( rr ) {
+ rr->deleteTime = 0;
+ if ( ttl > 0 )
+ rr->expireTime = query->started + ttl;
+ else
+ rr->expireTime = query->started + 20;
+ if ( rrno < ancount ) {
+ answers++;
+ rr->deleteTime = rr->expireTime;
+ }
+ rr->current = true;
+ rrs->append( rr );
+ }
+ }
+ if ( !ok )
+ return;
+ pp = next;
+ next = size;
+ rrno++;
+ }
+ if ( answers == 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: answer contained no answers" );
+#endif
+ ok = ( aa && rd );
+ }
+
+ // now go through the list and mark all the As that are referenced
+ // by something we care about. we want to cache such As.
+ rrs->first();
+ TQDict<void> used( 17 );
+ used.setAutoDelete( false );
+ while( (rr=rrs->current()) != 0 ) {
+ rrs->next();
+ if ( rr->target.length() && rr->deleteTime > 0 && rr->current )
+ used.insert( rr->target, (void*)42 );
+ if ( ( rr->t == TQDns::A || rr->t == TQDns::Aaaa ) &&
+ used.tqfind( rr->domain->name() ) != 0 )
+ rr->deleteTime = rr->expireTime;
+ }
+
+ // next, for each RR, delete any older RRs that are equal to it
+ rrs->first();
+ while( (rr=rrs->current()) != 0 ) {
+ rrs->next();
+ if ( rr && rr->domain && rr->domain->rrs ) {
+ TQPtrList<TQDnsRR> * drrs = rr->domain->rrs;
+ drrs->first();
+ TQDnsRR * older;
+ while( (older=drrs->current()) != 0 ) {
+ if ( older != rr &&
+ older->t == rr->t &&
+ older->nxdomain == rr->nxdomain &&
+ older->address == rr->address &&
+ older->target == rr->target &&
+ older->priority == rr->priority &&
+ older->weight == rr->weight &&
+ older->port == rr->port &&
+ older->text == rr->text ) {
+ // well, it's equal, but it's not the same. so we kill it,
+ // but use its expiry time.
+#if defined(TQDNS_DEBUG)
+ qDebug( "killing off old %d for %s, expire was %d",
+ older->t, older->domain->name().latin1(),
+ rr->expireTime );
+#endif
+ older->t = TQDns::None;
+ rr->expireTime = QMAX( older->expireTime, rr->expireTime );
+ rr->deleteTime = QMAX( older->deleteTime, rr->deleteTime );
+ older->deleteTime = 0;
+#if defined(TQDNS_DEBUG)
+ qDebug( " adjusted expire is %d", rr->expireTime );
+#endif
+ }
+ drrs->next();
+ }
+ }
+ }
+
+#if defined(TQDNS_DEBUG)
+ //qDebug( "DNS Manager: ()" );
+#endif
+}
+
+
+class TQDnsUgleHack: public TQDns {
+public:
+ void ugle( bool emitAnyway=false );
+};
+
+
+void TQDnsAnswer::notify()
+{
+ if ( !rrs || !ok || !query || !query->dns )
+ return;
+
+ TQPtrDict<void> notified;
+ notified.setAutoDelete( false );
+
+ TQPtrDictIterator<void> it( *query->dns );
+ TQDns * dns;
+ it.toFirst();
+ while( (dns=(TQDns*)(it.current())) != 0 ) {
+ ++it;
+ if ( notified.tqfind( (void*)dns ) == 0 ) {
+ notified.insert( (void*)dns, (void*)42 );
+ if ( rrs->count() == 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: found no answers!" );
+#endif
+ dns->d->noNames = true;
+ ((TQDnsUgleHack*)dns)->ugle( true );
+ } else {
+ TQStringList n = dns->qualifiedNames();
+ if ( query && n.tqcontains(query->l) )
+ ((TQDnsUgleHack*)dns)->ugle();
+#if defined(TQDNS_DEBUG)
+ else
+ qDebug( "DNS Manager: DNS thing %s not notified for %s",
+ dns->label().ascii(), query->l.ascii() );
+#endif
+ }
+ }
+ }
+}
+
+
+//
+//
+// TQDnsManager
+//
+//
+
+
+class TQDnsManager: public TQDnsSocket {
+private:
+public: // just to silence the moronic g++.
+ TQDnsManager();
+ ~TQDnsManager();
+public:
+ static TQDnsManager * manager();
+
+ TQDnsDomain * domain( const TQString & );
+
+ void transmitQuery( TQDnsQuery * );
+ void transmitQuery( int );
+
+ // reimplementation of the slots
+ void cleanCache();
+ void retransmit();
+ void answer();
+
+public:
+ TQPtrVector<TQDnsQuery> queries;
+ TQDict<TQDnsDomain> cache;
+ TQSocketDevice * ipv4Socket;
+#if !defined (QT_NO_IPV6)
+ TQSocketDevice * ipv6Socket;
+#endif
+};
+
+
+
+static TQDnsManager * globalManager = 0;
+
+static void cleanupDns()
+{
+ delete globalManager;
+ globalManager = 0;
+}
+
+TQDnsManager * TQDnsManager::manager()
+{
+ if ( !globalManager ) {
+ qAddPostRoutine(cleanupDns);
+ new TQDnsManager();
+ }
+ return globalManager;
+}
+
+
+void TQDnsUgleHack::ugle( bool emitAnyway)
+{
+ if ( emitAnyway || !isWorking() ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: status change for %s (type %d)",
+ label().ascii(), recordType() );
+#endif
+ emit resultsReady();
+ }
+}
+
+
+TQDnsManager::TQDnsManager()
+ : TQDnsSocket( qApp, "Internal DNS manager" ),
+ queries( TQPtrVector<TQDnsQuery>( 0 ) ),
+ cache( TQDict<TQDnsDomain>( 83, false ) ),
+ ipv4Socket( new TQSocketDevice( TQSocketDevice::Datagram, TQSocketDevice::IPv4, 0 ) )
+#if !defined (QT_NO_IPV6)
+ , ipv6Socket( new TQSocketDevice( TQSocketDevice::Datagram, TQSocketDevice::IPv6, 0 ) )
+#endif
+{
+ cache.setAutoDelete( true );
+ globalManager = this;
+
+ TQTimer * sweepTimer = new TQTimer( this );
+ sweepTimer->start( 1000 * 60 * 3 );
+ connect( sweepTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(cleanCache()) );
+
+ TQSocketNotifier * rn4 = new TQSocketNotifier( ipv4Socket->socket(),
+ TQSocketNotifier::Read,
+ TQT_TQOBJECT(this), "dns IPv4 socket watcher" );
+ ipv4Socket->setAddressReusable( false );
+ ipv4Socket->setBlocking( false );
+ connect( rn4, TQT_SIGNAL(activated(int)), TQT_SLOT(answer()) );
+
+#if !defined (QT_NO_IPV6)
+ // Don't connect the IPv6 socket notifier if the host does not
+ // support IPv6.
+ if ( ipv6Socket->socket() != -1 ) {
+ TQSocketNotifier * rn6 = new TQSocketNotifier( ipv6Socket->socket(),
+ TQSocketNotifier::Read,
+ TQT_TQOBJECT(this), "dns IPv6 socket watcher" );
+
+ ipv6support = true;
+ ipv6Socket->setAddressReusable( false );
+ ipv6Socket->setBlocking( false );
+ connect( rn6, TQT_SIGNAL(activated(int)), TQT_SLOT(answer()) );
+ }
+#endif
+
+ if ( !theNs )
+ TQDns::doResInit();
+
+ // O(n*n) stuff here. but for 3 and 6, O(n*n) with a low k should
+ // be perfect. the point is to eliminate any duplicates that
+ // might be hidden in the lists.
+ TQPtrList<TQHostAddress> * ns = new TQPtrList<TQHostAddress>;
+
+ theNs->first();
+ TQHostAddress * h;
+ while( (h=theNs->current()) != 0 ) {
+ ns->first();
+ while( ns->current() != 0 && !(*ns->current() == *h) )
+ ns->next();
+ if ( !ns->current() ) {
+ ns->append( new TQHostAddress(*h) );
+#if defined(TQDNS_DEBUG)
+ qDebug( "using name server %s", h->toString().latin1() );
+ } else {
+ qDebug( "skipping address %s", h->toString().latin1() );
+#endif
+ }
+ theNs->next();
+ }
+
+ delete theNs;
+ theNs = ns;
+ theNs->setAutoDelete( true );
+
+ TQStrList * domains = new TQStrList( true );
+
+ theDomains->first();
+ const char * s;
+ while( (s=theDomains->current()) != 0 ) {
+ domains->first();
+ while( domains->current() != 0 && qstrcmp( domains->current(), s ) )
+ domains->next();
+ if ( !domains->current() ) {
+ domains->append( s );
+#if defined(TQDNS_DEBUG)
+ qDebug( "searching domain %s", s );
+ } else {
+ qDebug( "skipping domain %s", s );
+#endif
+ }
+ theDomains->next();
+ }
+
+ delete theDomains;
+ theDomains = domains;
+ theDomains->setAutoDelete( true );
+}
+
+
+TQDnsManager::~TQDnsManager()
+{
+ if ( globalManager )
+ globalManager = 0;
+ queries.setAutoDelete( true );
+ cache.setAutoDelete( true );
+ delete ipv4Socket;
+#if !defined (QT_NO_IPV6)
+ delete ipv6Socket;
+#endif
+}
+
+static Q_UINT32 lastSweep = 0;
+
+void TQDnsManager::cleanCache()
+{
+ bool again = false;
+ TQDictIterator<TQDnsDomain> it( cache );
+ TQDnsDomain * d;
+ Q_UINT32 thisSweep = now();
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDnsManager::cleanCache(: Called, time is %u, last was %u",
+ thisSweep, lastSweep );
+#endif
+
+ while( (d=it.current()) != 0 ) {
+ ++it;
+ d->sweep( thisSweep ); // after this, d may be empty
+ if ( !again )
+ again = !d->isEmpty();
+ }
+ if ( !again )
+ delete this;
+ lastSweep = thisSweep;
+}
+
+
+void TQDnsManager::retransmit()
+{
+ const TQT_BASE_OBJECT_NAME * o = sender();
+ if ( o == 0 || globalManager == 0 || this != globalManager )
+ return;
+ uint q = 0;
+ while( q < queries.size() && queries[q] != o )
+ q++;
+ if ( q < queries.size() )
+ transmitQuery( q );
+}
+
+
+void TQDnsManager::answer()
+{
+ TQByteArray a( 16383 ); // large enough for anything, one suspects
+
+ int r;
+#if defined (QT_NO_IPV6)
+ r = ipv4Socket->readBlock(a.data(), a.size());
+#else
+ if (((TQSocketNotifier *)sender())->socket() == ipv4Socket->socket())
+ r = ipv4Socket->readBlock(a.data(), a.size());
+ else
+ r = ipv6Socket->readBlock(a.data(), a.size());
+#endif
+#if defined(TQDNS_DEBUG)
+#if !defined (QT_NO_IPV6)
+ qDebug("DNS Manager: answer arrived: %d bytes from %s:%d", r,
+ useIpv4Socket ? ipv4Socket->peerAddress().toString().ascii()
+ : ipv6Socket->peerAddress().toString().ascii(),
+ useIpv4Socket ? ipv4Socket->peerPort() : ipv6Socket->peerPort() );
+#else
+ qDebug("DNS Manager: answer arrived: %d bytes from %s:%d", r,
+ ipv4Socket->peerAddress().toString().ascii(), ipv4Socket->peerPort());;
+#endif
+#endif
+ if ( r < 12 )
+ return;
+ // maybe we should check that the answer comes from port 53 on one
+ // of our name servers...
+ a.resize( r );
+
+ Q_UINT16 aid = (((Q_UINT8)a[0]) << 8) + ((Q_UINT8)a[1]);
+ uint i = 0;
+ while( i < queries.size() &&
+ !( queries[i] && queries[i]->id == aid ) )
+ i++;
+ if ( i == queries.size() ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: bad id (0x%04x) %d", aid, i );
+#endif
+ return;
+ }
+
+ // at this point queries[i] is whatever we asked for.
+
+ if ( ( (Q_UINT8)(a[2]) & 0x80 ) == 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: received a query" );
+#endif
+ return;
+ }
+
+ TQDnsQuery * q = queries[i];
+ TQDnsAnswer answer( a, q );
+ answer.parse();
+ if ( answer.ok ) {
+ queries.take( i );
+ answer.notify();
+ delete q;
+ }
+}
+
+
+void TQDnsManager::transmitQuery( TQDnsQuery * query_ )
+{
+ if ( !query_ )
+ return;
+
+ uint i = 0;
+ while( i < queries.size() && queries[i] != 0 )
+ i++;
+ if ( i == queries.size() )
+ queries.resize( i+1 );
+ queries.insert( i, query_ );
+ transmitQuery( i );
+}
+
+
+void TQDnsManager::transmitQuery( int i )
+{
+ if ( i < 0 || i >= (int)queries.size() )
+ return;
+ TQDnsQuery * q = queries[i];
+
+ if ( q && q->step > 8 ) {
+ // okay, we've run out of retransmissions. we fake an NXDomain
+ // with a very short life time...
+ TQDnsAnswer answer( q );
+ answer.notify();
+ // and then get rid of the query
+ queries.take( i );
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: giving up on query 0x%04x", q->id );
+#endif
+ delete q;
+ TQTimer::singleShot( 0, TQDnsManager::manager(), TQT_SLOT(cleanCache()) );
+ // and don't process anything more
+ return;
+ }
+
+ if ((q && !q->dns) || q->dns->isEmpty())
+ // no one currently wants the answer, so there's no point in
+ // retransmitting the query. we keep it, though. an answer may
+ // arrive for an earlier query transmission, and if it does we
+ // may benefit from caching the result.
+ return;
+
+ TQByteArray p( 12 + q->l.length() + 2 + 4 );
+ if ( p.size() > 500 )
+ return; // way over the limit, so don't even try
+
+ // header
+ // id
+ p[0] = (q->id & 0xff00) >> 8;
+ p[1] = q->id & 0x00ff;
+ p[2] = 1; // recursion desired, rest is 0
+ p[3] = 0; // all is 0
+ // one query
+ p[4] = 0;
+ p[5] = 1;
+ // no answers, name servers or additional data
+ p[6] = p[7] = p[8] = p[9] = p[10] = p[11] = 0;
+
+ // the name is composed of several components. each needs to be
+ // written by itself... so we write...
+ // oh, and we assume that there's no funky characters in there.
+ int pp = 12;
+ uint lp = 0;
+ while( lp < (uint) q->l.length() ) {
+ int le = q->l.tqfind( QLatin1Char('.'), lp );
+ if ( le < 0 )
+ le = q->l.length();
+ TQString component = q->l.mid( lp, le-lp );
+ p[pp++] = component.length();
+ int cp;
+ for( cp=0; cp < (int)component.length(); cp++ )
+ p[pp++] = component[cp].latin1();
+ lp = le + 1;
+ }
+ // final null
+ p[pp++] = 0;
+ // query type
+ p[pp++] = 0;
+ switch( q->t ) {
+ case TQDns::A:
+ p[pp++] = 1;
+ break;
+ case TQDns::Aaaa:
+ p[pp++] = 28;
+ break;
+ case TQDns::Mx:
+ p[pp++] = 15;
+ break;
+ case TQDns::Srv:
+ p[pp++] = 33;
+ break;
+ case TQDns::Cname:
+ p[pp++] = 5;
+ break;
+ case TQDns::Ptr:
+ p[pp++] = 12;
+ break;
+ case TQDns::Txt:
+ p[pp++] = 16;
+ break;
+ default:
+ p[pp++] = (char)255; // any
+ break;
+ }
+ // query class (always internet)
+ p[pp++] = 0;
+ p[pp++] = 1;
+
+ // if we have no name servers, we should regenerate ns in case
+ // name servers have recently been defined (like on windows,
+ // plugging/unplugging the network cable will change the name
+ // server entries)
+ if ( !theNs || theNs->isEmpty() )
+ TQDns::doResInit();
+
+ if ( !theNs || theNs->isEmpty() ) {
+ // we don't tqfind any name servers. We fake an NXDomain
+ // with a very short life time...
+ TQDnsAnswer answer( q );
+ answer.notify();
+ // and then get rid of the query
+ queries.take( i );
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: no DNS server found on query 0x%04x", q->id );
+#endif
+ delete q;
+ TQTimer::singleShot( 1000*10, TQDnsManager::manager(), TQT_SLOT(cleanCache()) );
+ // and don't process anything more
+ return;
+ }
+
+ TQHostAddress receiver = *theNs->at( q->step % theNs->count() );
+ if (receiver.isIPv4Address())
+ ipv4Socket->writeBlock( p.data(), pp, receiver, 53 );
+#if !defined (QT_NO_IPV6)
+ else
+ ipv6Socket->writeBlock( p.data(), pp, receiver, 53 );
+#endif
+#if defined(TQDNS_DEBUG)
+ qDebug( "issuing query 0x%04x (%d) about %s type %d to %s",
+ q->id, q->step, q->l.ascii(), q->t,
+ ns->at( q->step % ns->count() )->toString().ascii() );
+#endif
+ if ( theNs->count() > 1 && q->step == 0 && queries.count() == 1 ) {
+ // if it's the first time, and we don't have any other
+ // outstanding queries, send nonrecursive queries to the other
+ // name servers too.
+ p[2] = 0;
+ TQHostAddress * server;
+ while( (server=theNs->next()) != 0 ) {
+ if (server->isIPv4Address())
+ ipv4Socket->writeBlock( p.data(), pp, *server, 53 );
+#if !defined (QT_NO_IPV6)
+ else
+ ipv6Socket->writeBlock( p.data(), pp, *server, 53 );
+#endif
+#if defined(TQDNS_DEBUG)
+ qDebug( "copying query to %s", server->toString().ascii() );
+#endif
+ }
+ }
+ q->step++;
+ // some testing indicates that normal dns queries take up to 0.6
+ // seconds. the graph becomes steep around that point, and the
+ // number of errors rises... so it seems good to retry at that
+ // point.
+ q->start( q->step < theNs->count() ? 800 : 1500, true );
+}
+
+
+TQDnsDomain * TQDnsManager::domain( const TQString & label )
+{
+ TQDnsDomain * d = cache.tqfind( label );
+ if ( !d ) {
+ d = new TQDnsDomain( label );
+ cache.insert( label, d );
+ }
+ return d;
+}
+
+
+//
+//
+// the TQDnsDomain class looks after and coordinates queries for TQDnsRRs for
+// each domain, and the cached TQDnsRRs. (A domain, in DNS terminology, is
+// a node in the DNS. "no", "trolltech.com" and "lupinella.troll.no" are
+// all domains.)
+//
+//
+
+
+TQDnsDomain::TQDnsDomain( const TQString & label )
+{
+ l = label;
+ rrs = 0;
+}
+
+
+TQDnsDomain::~TQDnsDomain()
+{
+ delete rrs;
+ rrs = 0;
+}
+
+
+void TQDnsDomain::add( const TQString & label, TQDnsRR * rr )
+{
+ TQDnsDomain * d = TQDnsManager::manager()->domain( label );
+ if ( !d->rrs ) {
+ d->rrs = new TQPtrList<TQDnsRR>;
+ d->rrs->setAutoDelete( true );
+ }
+ d->rrs->append( rr );
+ rr->domain = d;
+}
+
+
+TQPtrList<TQDnsRR> * TQDnsDomain::cached( const TQDns * r )
+{
+ TQPtrList<TQDnsRR> * l = new TQPtrList<TQDnsRR>;
+
+ // test at first if you have to start a query at all
+ if ( r->recordType() == TQDns::A ) {
+ if ( r->label().lower() == TQLatin1String("localhost") ) {
+ // undocumented hack. ipv4-specific. also, may be a memory
+ // leak? not sure. would be better to do this in doResInit(),
+ // anyway.
+ TQDnsRR *rrTmp = new TQDnsRR( r->label() );
+ rrTmp->t = TQDns::A;
+ rrTmp->address = TQHostAddress( 0x7f000001 );
+ rrTmp->current = true;
+ l->append( rrTmp );
+ return l;
+ }
+ TQHostAddress tmp;
+ if ( tmp.setAddress( r->label() ) ) {
+ TQDnsRR *rrTmp = new TQDnsRR( r->label() );
+ if ( tmp.isIPv4Address() ) {
+ rrTmp->t = TQDns::A;
+ rrTmp->address = tmp;
+ rrTmp->current = true;
+ l->append( rrTmp );
+ } else {
+ rrTmp->nxdomain = true;
+ }
+ return l;
+ }
+ }
+ if ( r->recordType() == TQDns::Aaaa ) {
+ TQHostAddress tmp;
+ if ( tmp.setAddress(r->label()) ) {
+ TQDnsRR *rrTmp = new TQDnsRR( r->label() );
+ if ( tmp.isIPv6Address() ) {
+ rrTmp->t = TQDns::Aaaa;
+ rrTmp->address = tmp;
+ rrTmp->current = true;
+ l->append( rrTmp );
+ } else {
+ rrTmp->nxdomain = true;
+ }
+ return l;
+ }
+ }
+
+ // if you reach this point, you have to do the query
+ TQDnsManager * m = TQDnsManager::manager();
+ TQStringList n = r->qualifiedNames();
+ bool nxdomain;
+ int cnamecount = 0;
+ int it = 0;
+ while( it < n.count() ) {
+ TQString s = *(n.at(it++));
+ nxdomain = false;
+#if defined(TQDNS_DEBUG)
+ qDebug( "looking at cache for %s (%s %d)",
+ s.ascii(), r->label().ascii(), r->recordType() );
+#endif
+ TQDnsDomain * d = m->domain( s );
+#if defined(TQDNS_DEBUG)
+ qDebug( " - found %d RRs", d && d->rrs ? d->rrs->count() : 0 );
+#endif
+ if ( d->rrs )
+ d->rrs->first();
+ TQDnsRR * rr;
+ bool answer = false;
+ while( d->rrs && (rr=d->rrs->current()) != 0 ) {
+ if ( rr->t == TQDns::Cname && r->recordType() != TQDns::Cname &&
+ !rr->nxdomain && cnamecount < 16 ) {
+ // cname. if the code is ugly, that may just
+ // possibly be because the concept is.
+#if defined(TQDNS_DEBUG)
+ qDebug( "found cname from %s to %s",
+ r->label().ascii(), rr->target.ascii() );
+#endif
+ s = rr->target;
+ d = m->domain( s );
+ if ( d->rrs )
+ d->rrs->first();
+ it = n.count();
+ // we've elegantly moved over to whatever the cname
+ // pointed to. well, not elegantly. let's remember
+ // that we've done something, anyway, so we can't be
+ // fooled into an infinte loop as well.
+ cnamecount++;
+ } else {
+ if ( rr->t == r->recordType() ) {
+ if ( rr->nxdomain )
+ nxdomain = true;
+ else
+ answer = true;
+ l->append( rr );
+ if ( rr->deleteTime <= lastSweep ) {
+ // we're returning something that'll be
+ // deleted soon. we assume that if the client
+ // wanted it twice, it'll want it again, so we
+ // ask the name server again right now.
+ TQDnsQuery * query = new TQDnsQuery;
+ query->started = now();
+ query->id = ++theId;
+ query->t = rr->t;
+ query->l = rr->domain->name();
+ // note that here, we don't bother about
+ // notification. but we do bother about
+ // timeouts: we make sure to use high timeouts
+ // and few tramsissions.
+ query->step = theNs->count();
+ TQT_BASE_OBJECT_NAME::connect( query, TQT_SIGNAL(timeout()),
+ TQDnsManager::manager(),
+ TQT_SLOT(retransmit()) );
+ TQDnsManager::manager()->transmitQuery( query );
+ }
+ }
+ d->rrs->next();
+ }
+ }
+ // if we found a positive result, return quickly
+ if ( answer && l->count() ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "found %d records for %s",
+ l->count(), r->label().ascii() );
+ l->first();
+ while( l->current() ) {
+ qDebug( " type %d target %s address %s",
+ l->current()->t,
+ l->current()->target.latin1(),
+ l->current()->address.toString().latin1() );
+ l->next();
+ }
+#endif
+ l->first();
+ return l;
+ }
+
+#if defined(TQDNS_DEBUG)
+ if ( nxdomain )
+ qDebug( "found NXDomain %s", s.ascii() );
+#endif
+
+ if ( !nxdomain ) {
+ // if we didn't, and not a negative result either, perhaps
+ // we need to transmit a query.
+ uint q = 0;
+ while ( q < m->queries.size() &&
+ ( m->queries[q] == 0 ||
+ m->queries[q]->t != r->recordType() ||
+ m->queries[q]->l != s ) )
+ q++;
+ // we haven't done it before, so maybe we should. but
+ // wait - if it's an unqualified name, only ask when all
+ // the other alternatives are exhausted.
+ if ( q == m->queries.size() && ( s.tqfind( QLatin1Char('.') ) >= 0 ||
+ int(l->count()) >= n.count()-1 ) ) {
+ TQDnsQuery * query = new TQDnsQuery;
+ query->started = now();
+ query->id = ++theId;
+ query->t = r->recordType();
+ query->l = s;
+ query->dns->tqreplace( (void*)r, (void*)r );
+ TQT_BASE_OBJECT_NAME::connect( query, TQT_SIGNAL(timeout()),
+ TQDnsManager::manager(), TQT_SLOT(retransmit()) );
+ TQDnsManager::manager()->transmitQuery( query );
+ } else if ( q < m->queries.size() ) {
+ // if we've found an earlier query for the same
+ // domain/type, subscribe to its answer
+ m->queries[q]->dns->tqreplace( (void*)r, (void*)r );
+ }
+ }
+ }
+ l->first();
+ return l;
+}
+
+
+void TQDnsDomain::sweep( Q_UINT32 thisSweep )
+{
+ if ( !rrs )
+ return;
+
+ TQDnsRR * rr;
+ rrs->first();
+ while( (rr=rrs->current()) != 0 ) {
+ if ( !rr->deleteTime )
+ rr->deleteTime = thisSweep; // will hit next time around
+
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::sweep: %s type %d expires %u %u - %s / %s",
+ rr->domain->name().latin1(), rr->t,
+ rr->expireTime, rr->deleteTime,
+ rr->target.latin1(), rr->address.toString().latin1());
+#endif
+ if ( rr->current == false ||
+ rr->t == TQDns::None ||
+ rr->deleteTime <= thisSweep ||
+ rr->expireTime <= thisSweep )
+ rrs->remove();
+ else
+ rrs->next();
+ }
+
+ if ( rrs->isEmpty() ) {
+ delete rrs;
+ rrs = 0;
+ }
+}
+
+
+
+
+// the itsy-bitsy little socket class I don't really need except for
+// so I can subclass and reimplement the slots.
+
+
+TQDnsSocket::TQDnsSocket( TQT_BASE_OBJECT_NAME * parent, const char * name )
+ : TQObject( parent, name )
+{
+ // nothing
+}
+
+
+TQDnsSocket::~TQDnsSocket()
+{
+ // nothing
+}
+
+
+void TQDnsSocket::cleanCache()
+{
+ // nothing
+}
+
+
+void TQDnsSocket::retransmit()
+{
+ // nothing
+}
+
+
+void TQDnsSocket::answer()
+{
+ // nothing
+}
+
+
+/*!
+ \class TQDns
+ \brief The TQDns class provides asynchronous DNS lookups.
+
+ \compat
+
+ Both Windows and Unix provide synchronous DNS lookups; Windows
+ provides some asynchronous support too. At the time of writing
+ neither operating system provides asynchronous support for
+ anything other than hostname-to-address mapping.
+
+ TQDns rectifies this shortcoming, by providing asynchronous caching
+ lookups for the record types that we expect modern GUI
+ applications to need in the near future.
+
+ The class is \e not straightforward to use (although it is much
+ simpler than the native APIs); TQSocket provides much easier to use
+ TCP connection facilities. The aim of TQDns is to provide a correct
+ and small API to the DNS and nothing more. (We use "correctness"
+ to mean that the DNS information is correctly cached, and
+ correctly timed out.)
+
+ The API comprises a constructor, functions to set the DNS node
+ (the domain in DNS terminology) and record type (setLabel() and
+ setRecordType()), the corresponding get functions, an isWorking()
+ function to determine whether TQDns is working or reading, a
+ resultsReady() signal and query functions for the result.
+
+ There is one query function for each RecordType, namely
+ addresses(), mailServers(), servers(), hostNames() and texts().
+ There are also two generic query functions: canonicalName()
+ returns the name you'll presumably end up using (the exact meaning
+ of this depends on the record type) and qualifiedNames() returns a
+ list of the fully qualified names label() maps to.
+
+ \sa TQSocket
+*/
+
+/*!
+ Constructs a DNS query object with invalid settings for both the
+ label and the search type.
+*/
+
+TQDns::TQDns()
+{
+ d = new TQDnsPrivate;
+ t = None;
+}
+
+
+
+
+/*!
+ Constructs a DNS query object that will return record type \a rr
+ information about \a label.
+
+ The DNS lookup is started the next time the application enters the
+ event loop. When the result is found the signal resultsReady() is
+ emitted.
+
+ \a rr defaults to \c A, IPv4 addresses.
+*/
+
+TQDns::TQDns( const TQString & label, RecordType rr )
+{
+ d = new TQDnsPrivate;
+ t = rr;
+ setLabel( label );
+ setStartQueryTimer(); // start query the next time we enter event loop
+}
+
+
+
+/*!
+ Constructs a DNS query object that will return record type \a rr
+ information about host address \a address. The label is set to the
+ IN-ADDR.ARPA domain name. This is useful in combination with the
+ \c Ptr record type (e.g. if you want to look up a hostname for a
+ given address).
+
+ The DNS lookup is started the next time the application enters the
+ event loop. When the result is found the signal resultsReady() is
+ emitted.
+
+ \a rr defaults to \c Ptr, that maps addresses to hostnames.
+*/
+
+TQDns::TQDns( const TQHostAddress & address, RecordType rr )
+{
+ d = new TQDnsPrivate;
+ t = rr;
+ setLabel( address );
+ setStartQueryTimer(); // start query the next time we enter event loop
+}
+
+
+
+
+/*!
+ Destroys the DNS query object and frees its allocated resources.
+*/
+
+TQDns::~TQDns()
+{
+ if ( globalManager ) {
+ uint q = 0;
+ TQDnsManager * m = globalManager;
+ while( q < m->queries.size() ) {
+ TQDnsQuery * query=m->queries[q];
+ if ( query && query->dns )
+ (void)query->dns->take( (void*) this );
+ q++;
+ }
+
+ }
+
+ delete d;
+ d = 0;
+}
+
+
+
+
+/*!
+ Sets this DNS query object to query for information about \a
+ label.
+
+ This does not change the recordType(), but its isWorking() status
+ will probably change as a result.
+
+ The DNS lookup is started the next time the application enters the
+ event loop. When the result is found the signal resultsReady() is
+ emitted.
+*/
+
+void TQDns::setLabel( const TQString & label )
+{
+ l = label;
+ d->noNames = false;
+
+ // construct a list of qualified names
+ n.clear();
+ if ( l.length() > 1 && l[(int)l.length()-1] == QLatin1Char('.') ) {
+ n.append( TQT_TQSTRING(l.left( l.length()-1 )).lower() );
+ } else {
+ int i = l.length();
+ int dots = 0;
+ const int maxDots = 2;
+ while( i && dots < maxDots ) {
+ if ( l[--i] == QLatin1Char('.') )
+ dots++;
+ }
+ if ( dots < maxDots ) {
+ (void)TQDnsManager::manager(); // create a TQDnsManager, if it is not already there
+ TQStrListIterator it( *theDomains );
+ const char * dom;
+ while( (dom=it.current()) != 0 ) {
+ ++it;
+ n.append( l.lower() + QLatin1Char('.') + TQLatin1String(dom) );
+ }
+ }
+ n.append( l.lower() );
+ }
+
+#if defined(Q_DNS_SYNCHRONOUS)
+ if ( d->noEventLoop ) {
+ doSynchronousLookup();
+ } else {
+ setStartQueryTimer(); // start query the next time we enter event loop
+ }
+#else
+ setStartQueryTimer(); // start query the next time we enter event loop
+#endif
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::setLabel: %d address(es) for %s", n.count(), l.ascii() );
+ int i = 0;
+ for( i = 0; i < (int)n.count(); i++ )
+ qDebug( "TQDns::setLabel: %d: %s", i, n[i].ascii() );
+#endif
+}
+
+
+/*!
+ \overload
+
+ Sets this DNS query object to query for information about the host
+ address \a address. The label is set to the IN-ADDR.ARPA domain
+ name. This is useful in combination with the \c Ptr record type
+ (e.g. if you want to look up a hostname for a given address).
+*/
+
+void TQDns::setLabel( const TQHostAddress & address )
+{
+ setLabel( toInAddrArpaDomain( address ) );
+}
+
+
+/*!
+ \fn TQStringList TQDns::qualifiedNames() const
+
+ Returns a list of the fully qualified names label() maps to.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 0
+
+*/
+
+
+/*!
+ \fn TQString TQDns::label() const
+
+ Returns the domain name for which this object returns information.
+
+ \sa setLabel()
+*/
+
+/*!
+ \enum TQDns::RecordType
+
+ This enum type defines the record types TQDns can handle. The DNS
+ provides many more; these are the ones we've judged to be in
+ current use, useful for GUI programs and important enough to
+ support right away:
+
+ \value None No information. This exists only so that TQDns can
+ have a default.
+
+ \value A IPv4 addresses. By far the most common type.
+
+ \value Aaaa IPv6 addresses. So far mostly unused.
+
+ \value Mx Mail eXchanger names. Used for mail delivery.
+
+ \value Srv SeRVer names. Generic record type for tqfinding
+ servers. So far mostly unused.
+
+ \value Cname Canonical names. Maps from nicknames to the true
+ name (the canonical name) for a host.
+
+ \value Ptr name PoinTeRs. Maps from IPv4 or IPv6 addresses to hostnames.
+
+ \value Txt arbitrary TeXT for domains.
+
+ We expect that some support for the
+ \l{http://www.rfc-editor.org/rfc/rfc2535.txt}{RFC 2535}
+ extensions will be added in future versions.
+*/
+
+/*!
+ Sets this object to query for record type \a rr records.
+
+ The DNS lookup is started the next time the application enters the
+ event loop. When the result is found the signal resultsReady() is
+ emitted.
+
+ \sa RecordType
+*/
+
+void TQDns::setRecordType( RecordType rr )
+{
+ t = rr;
+ d->noNames = false;
+ setStartQueryTimer(); // start query the next time we enter event loop
+}
+
+/*!
+ \internal
+
+ Private slot for starting the query.
+*/
+void TQDns::startQuery()
+{
+ // isWorking() starts the query (if necessary)
+ if ( !isWorking() )
+ emit resultsReady();
+}
+
+/*!
+ The three functions TQDns::TQDns(TQString, RecordType),
+ TQDns::setLabel() and TQDns::setRecordType() may start a DNS lookup.
+ This function handles setting up the single shot timer.
+*/
+void TQDns::setStartQueryTimer()
+{
+#if defined(Q_DNS_SYNCHRONOUS)
+ if ( !d->queryTimer && !d->noEventLoop )
+#else
+ if ( !d->queryTimer )
+#endif
+ {
+ // start the query the next time we enter event loop
+ d->queryTimer = new TQTimer( this );
+ connect( d->queryTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(startQuery()) );
+ d->queryTimer->start( 0, true );
+ }
+}
+
+/*
+ Transforms the host address \a address to the IN-ADDR.ARPA domain
+ name. Returns something indeterminate if you're sloppy or
+ naughty. This function has an IPv4-specific name, but works for
+ IPv6 too.
+*/
+TQString TQDns::toInAddrArpaDomain( const TQHostAddress &address )
+{
+ TQString s;
+ if ( address.isNull() ) {
+ // if the address isn't valid, neither of the other two make
+ // cases make sense. better to just return.
+ } else if ( address.isIp4Addr() ) {
+ Q_UINT32 i = address.ip4Addr();
+ s.sprintf( "%d.%d.%d.%d.IN-ADDR.ARPA",
+ i & 0xff, (i >> 8) & 0xff, (i>>16) & 0xff, (i>>24) & 0xff );
+ } else {
+ // RFC 3152. (1886 is deprecated, and clients no longer need to
+ // support it, in practice).
+ Q_IPV6ADDR i = address.toIPv6Address();
+ s = TQLatin1String("ip6.arpa");
+ uint b = 0;
+ while( b < 16 ) {
+ s = TQString::number( i.c[b]%16, 16 ) + QLatin1Char('.') +
+ TQString::number( i.c[b]/16, 16 ) + QLatin1Char('.') + s;
+ b++;
+ }
+ }
+ return s;
+}
+
+
+/*!
+ \fn TQDns::RecordType TQDns::recordType() const
+
+ Returns the record type of this DNS query object.
+
+ \sa setRecordType() RecordType
+*/
+
+/*!
+ \fn void TQDns::resultsReady()
+
+ This signal is emitted when results are available for one of the
+ qualifiedNames().
+*/
+
+/*!
+ Returns true if TQDns is doing a lookup for this object (i.e. if it
+ does not already have the necessary information); otherwise
+ returns false.
+
+ TQDns emits the resultsReady() signal when the status changes to false.
+*/
+
+bool TQDns::isWorking() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::isWorking (%s, %d)", l.ascii(), t );
+#endif
+ if ( t == None )
+ return false;
+
+#if defined(Q_DNS_SYNCHRONOUS)
+ if ( d->noEventLoop )
+ return true;
+#endif
+
+ TQPtrList<TQDnsRR> * ll = TQDnsDomain::cached( this );
+ Q_LONG queries = n.count();
+ while( ll->current() != 0 ) {
+ if ( ll->current()->nxdomain ) {
+ queries--;
+ } else {
+ delete ll;
+ return false;
+ }
+ ll->next();
+ }
+ delete ll;
+
+ if ( queries <= 0 )
+ return false;
+ if ( d->noNames )
+ return false;
+ return true;
+}
+
+
+/*!
+ Returns a list of the addresses for this name if this TQDns object
+ has a recordType() of TQDns::A or TQDns::Aaaa and the answer
+ is available; otherwise returns an empty list.
+
+ As a special case, if label() is a valid numeric IP address, this
+ function returns that address.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 1
+
+*/
+
+TQValueList<TQHostAddress> TQDns::addresses() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::addresses (%s)", l.ascii() );
+#endif
+ TQValueList<TQHostAddress> result;
+ if ( t != A && t != Aaaa )
+ return result;
+
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain )
+ result.append( rr->address );
+ cached->next();
+ }
+ delete cached;
+ return result;
+}
+
+
+/*!
+ \class TQDns::MailServer
+ \brief The TQDns::MailServer class is described in TQDns::mailServers().
+
+ \internal
+*/
+
+/*!
+ Returns a list of mail servers if the record type is \c Mx. The
+ class TQDns::MailServer tqcontains the following public variables:
+ \list
+ \i TQString TQDns::MailServer::name
+ \i Q_UINT16 TQDns::MailServer::priority
+ \endlist
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 2
+
+*/
+TQValueList<TQDns::MailServer> TQDns::mailServers() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::mailServers (%s)", l.ascii() );
+#endif
+ TQValueList<TQDns::MailServer> result;
+ if ( t != Mx )
+ return result;
+
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain ) {
+ MailServer ms( rr->target, rr->priority );
+ result.append( ms );
+ }
+ cached->next();
+ }
+ delete cached;
+ return result;
+}
+
+
+/*!
+ \class TQDns::Server
+ \brief The TQDns::Server class is described in TQDns::servers().
+
+ \internal
+*/
+
+/*!
+ Returns a list of servers if the record type is \c Srv. The class
+ TQDns::Server tqcontains the following public variables:
+ \list
+ \i TQString TQDns::Server::name
+ \i Q_UINT16 TQDns::Server::priority
+ \i Q_UINT16 TQDns::Server::weight
+ \i Q_UINT16 TQDns::Server::port
+ \endlist
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 3
+*/
+TQValueList<TQDns::Server> TQDns::servers() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::servers (%s)", l.ascii() );
+#endif
+ TQValueList<TQDns::Server> result;
+ if ( t != Srv )
+ return result;
+
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain ) {
+ Server s( rr->target, rr->priority, rr->weight, rr->port );
+ result.append( s );
+ }
+ cached->next();
+ }
+ delete cached;
+ return result;
+}
+
+
+/*!
+ Returns a list of host names if the record type is \c Ptr.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 4
+
+*/
+TQStringList TQDns::hostNames() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::hostNames (%s)", l.ascii() );
+#endif
+ TQStringList result;
+ if ( t != Ptr )
+ return result;
+
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain ) {
+ TQString str( rr->target );
+ result.append( str );
+ }
+ cached->next();
+ }
+ delete cached;
+ return result;
+}
+
+
+/*!
+ Returns a list of texts if the record type is \c Txt.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \snippet doc/src/snippets/code/src_qt3support_network_q3dns.cpp 5
+*/
+TQStringList TQDns::texts() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::texts (%s)", l.ascii() );
+#endif
+ TQStringList result;
+ if ( t != Txt )
+ return result;
+
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain ) {
+ TQString str( rr->text );
+ result.append( str );
+ }
+ cached->next();
+ }
+ delete cached;
+ return result;
+}
+
+
+/*!
+ Returns the canonical name for this DNS node. (This works
+ regardless of what recordType() is set to.)
+
+ If the canonical name isn't known, this function returns a null
+ string.
+
+ The canonical name of a DNS node is its full name, or the full
+ name of the target of its CNAME. For example, if l.trolltech.com
+ is a CNAME to lillian.troll.no, and the search path for TQDns is
+ "trolltech.com", then the canonical name for all of "lillian",
+ "l", "lillian.troll.no." and "l.trolltech.com" is
+ "lillian.troll.no.".
+*/
+
+TQString TQDns::canonicalName() const
+{
+ // the cname should work regardless of the recordType(), so set the record
+ // type temporarily to cname when you look at the cache
+ TQDns *that = (TQDns*) this; // mutable function
+ RecordType oldType = t;
+ that->t = Cname;
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( that );
+ that->t = oldType;
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain && rr->domain ) {
+ delete cached;
+ return rr->target;
+ }
+ cached->next();
+ }
+ delete cached;
+ return TQString();
+}
+
+#if defined(Q_DNS_SYNCHRONOUS)
+/*! \reimp
+*/
+void TQDns::connectNotify( const char *signal )
+{
+ if ( d->noEventLoop && qstrcmp(signal,TQT_SIGNAL(resultsReady()) )==0 ) {
+ doSynchronousLookup();
+ }
+}
+#endif
+
+#if defined(Q_OS_WIN32) || defined(Q_OS_CYGWIN)
+
+#if defined(Q_DNS_SYNCHRONOUS)
+void TQDns::doSynchronousLookup()
+{
+ // ### not implemented yet
+}
+#endif
+
+// the following typedefs are needed for GetNetworkParams() API call
+#ifndef IP_TYPES_INCLUDED
+#define MAX_HOSTNAME_LEN 128
+#define MAX_DOMAIN_NAME_LEN 128
+#define MAX_SCOPE_ID_LEN 256
+typedef struct {
+ char String[4 * 4];
+} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
+typedef struct _IP_ADDR_STRING {
+ struct _IP_ADDR_STRING* Next;
+ IP_ADDRESS_STRING IpAddress;
+ IP_MASK_STRING IpMask;
+ DWORD Context;
+} IP_ADDR_STRING, *PIP_ADDR_STRING;
+typedef struct {
+ char HostName[MAX_HOSTNAME_LEN + 4] ;
+ char DomainName[MAX_DOMAIN_NAME_LEN + 4];
+ PIP_ADDR_STRING CurrentDnsServer;
+ IP_ADDR_STRING DnsServerList;
+ UINT NodeType;
+ char ScopeId[MAX_SCOPE_ID_LEN + 4];
+ UINT EnableRouting;
+ UINT EnableProxy;
+ UINT EnableDns;
+} FIXED_INFO, *PFIXED_INFO;
+#endif
+typedef DWORD (WINAPI *GNP)( PFIXED_INFO, PULONG );
+
+// ### FIXME: this code is duplicated in qfiledialog.cpp
+static TQString getWindowsRegString(HKEY key, const TQString &subKey)
+{
+ TQString s;
+
+ wchar_t buf[1024];
+ DWORD bsz = sizeof(buf) / sizeof(wchar_t);
+ int r = RegQueryValueEx(key, (wchar_t*)subKey.utf16(), 0, 0, (LPBYTE)buf, &bsz);
+ if (r == ERROR_SUCCESS) {
+ s = TQString::fromWCharArray(buf);
+ } else if (r == ERROR_MORE_DATA) {
+ char *ptr = new char[bsz+1];
+ r = RegQueryValueEx(key, (wchar_t*)subKey.utf16(), 0, 0, (LPBYTE)ptr, &bsz);
+ if (r == ERROR_SUCCESS)
+ s = TQLatin1String(ptr);
+ delete [] ptr;
+ }
+
+ return s;
+}
+
+static bool getDnsParamsFromRegistry( const TQString &path,
+ TQString *domainName, TQString *nameServer, TQString *searchList )
+{
+ HKEY k;
+ int r = RegOpenKeyEx( HKEY_LOCAL_MACHINE, (wchar_t*)path.utf16(), 0, KEY_READ, &k );
+
+ if ( r == ERROR_SUCCESS ) {
+ *domainName = getWindowsRegString( k, TQLatin1String("DhcpDomain") );
+ if ( domainName->isEmpty() )
+ *domainName = getWindowsRegString( k, TQLatin1String("Domain") );
+
+ *nameServer = getWindowsRegString( k, TQLatin1String("DhcpNameServer") );
+ if ( nameServer->isEmpty() )
+ *nameServer = getWindowsRegString( k, TQLatin1String("NameServer") );
+
+ *searchList = getWindowsRegString( k, TQLatin1String("SearchList") );
+ }
+ RegCloseKey( k );
+ return r == ERROR_SUCCESS;
+}
+
+void TQDns::doResInit()
+{
+ char separator = 0;
+
+ if ( theNs )
+ delete theNs;
+ theNs = new TQPtrList<TQHostAddress>;
+ theNs->setAutoDelete( true );
+ theDomains = new TQStrList( true );
+ theDomains->setAutoDelete( true );
+
+ TQString domainName, nameServer, searchList;
+
+ bool gotNetworkParams = false;
+ // try the API call GetNetworkParams() first and use registry lookup only
+ // as a fallback
+ HINSTANCE hinstLib = LoadLibrary( L"iphlpapi" );
+ if ( hinstLib != 0 ) {
+#ifdef Q_OS_WINCE
+ GNP getNetworkParams = (GNP) GetProcAddress( hinstLib, L"GetNetworkParams" );
+#else
+ GNP getNetworkParams = (GNP) GetProcAddress( hinstLib, "GetNetworkParams" );
+#endif
+ if ( getNetworkParams != 0 ) {
+ ULONG l = 0;
+ DWORD res;
+ res = getNetworkParams( 0, &l );
+ if ( res == ERROR_BUFFER_OVERFLOW ) {
+ FIXED_INFO *finfo = (FIXED_INFO*)new char[l];
+ res = getNetworkParams( finfo, &l );
+ if ( res == ERROR_SUCCESS ) {
+ domainName = TQLatin1String(finfo->DomainName);
+ nameServer = TQLatin1String("");
+ IP_ADDR_STRING *dnsServer = &finfo->DnsServerList;
+ while ( dnsServer != 0 ) {
+ nameServer += TQLatin1String(dnsServer->IpAddress.String);
+ dnsServer = dnsServer->Next;
+ if ( dnsServer != 0 )
+ nameServer += QLatin1Char(' ');
+ }
+ searchList = TQLatin1String("");
+ separator = ' ';
+ gotNetworkParams = true;
+ }
+ delete[] finfo;
+ }
+ }
+ FreeLibrary( hinstLib );
+ }
+ if ( !gotNetworkParams ) {
+ if ( getDnsParamsFromRegistry(
+ TQLatin1String("System\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
+ &domainName, &nameServer, &searchList )) {
+ separator = ' ';
+ } else {
+ // Could not access the TCP/IP parameters
+ domainName = TQLatin1String("");
+ nameServer = TQLatin1String("127.0.0.1");
+ searchList = TQLatin1String("");
+ separator = ' ';
+ }
+ }
+
+ nameServer = nameServer.simplifyWhiteSpace();
+ int first, last;
+ if ( !nameServer.isEmpty() ) {
+ first = 0;
+ do {
+ last = nameServer.tqfind( QLatin1Char(separator), first );
+ if ( last < 0 )
+ last = nameServer.length();
+ TQDns tmp( nameServer.mid( first, last-first ), TQDns::A );
+ TQValueList<TQHostAddress> address = tmp.addresses();
+ Q_LONG i = address.count();
+ while( i )
+ theNs->append( new TQHostAddress(address[--i]) );
+ first = last+1;
+ } while( first < (int)nameServer.length() );
+ }
+
+ searchList += QLatin1Char(' ') + domainName;
+ searchList = searchList.simplifyWhiteSpace().lower();
+ first = 0;
+ do {
+ last = searchList.tqfind( QLatin1Char(separator), first );
+ if ( last < 0 )
+ last = searchList.length();
+ theDomains->append( qstrdup( searchList.mid( first, last-first ).latin1() ) );
+ first = last+1;
+ } while( first < (int)searchList.length() );
+}
+
+#elif defined(Q_OS_UNIX)
+
+#if defined(Q_DNS_SYNCHRONOUS)
+void TQDns::doSynchronousLookup()
+{
+ if ( t!=None && !l.isEmpty() ) {
+ TQValueListIterator<TQString> it = n.begin();
+ TQValueListIterator<TQString> end = n.end();
+ int type;
+ switch( t ) {
+ case TQDns::A:
+ type = 1;
+ break;
+ case TQDns::Aaaa:
+ type = 28;
+ break;
+ case TQDns::Mx:
+ type = 15;
+ break;
+ case TQDns::Srv:
+ type = 33;
+ break;
+ case TQDns::Cname:
+ type = 5;
+ break;
+ case TQDns::Ptr:
+ type = 12;
+ break;
+ case TQDns::Txt:
+ type = 16;
+ break;
+ default:
+ type = (char)255; // any
+ break;
+ }
+ while( it != end ) {
+ TQString s = *it;
+ it++;
+ TQByteArray ba( 512 );
+ int len = res_search( s.latin1(), 1, type, (uchar*)ba.data(), ba.size() );
+ if ( len > 0 ) {
+ ba.resize( len );
+
+ TQDnsQuery * query = new TQDnsQuery;
+ query->started = now();
+ query->id = ++theId;
+ query->t = t;
+ query->l = s;
+ TQDnsAnswer a( ba, query );
+ a.parse();
+ } else if ( len == -1 ) {
+ // res_search error
+ }
+ }
+ emit resultsReady();
+ }
+}
+#endif
+
+#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 3)))
+#define Q_MODERN_RES_API
+#endif
+
+void TQDns::doResInit()
+{
+ if ( theNs )
+ return;
+ theNs = new TQPtrList<TQHostAddress>;
+ theNs->setAutoDelete( true );
+ theDomains = new TQStrList( true );
+ theDomains->setAutoDelete( true );
+
+ // read resolv.conf manually.
+ QFile resolvConf(TQLatin1String("/etc/resolv.conf"));
+ if (resolvConf.open(QIODevice::ReadOnly)) {
+ QTextStream stream( &resolvConf );
+ TQString line;
+
+ while ( !stream.atEnd() ) {
+ line = stream.readLine();
+ TQStringList list = TQStringList::split( TQLatin1String(" "), line );
+ if( line.startsWith( QLatin1Char('#') ) || list.size() < 2 )
+ continue;
+ const TQString type = list[0].lower();
+
+ if ( type == TQLatin1String("nameserver") ) {
+ TQHostAddress *address = new TQHostAddress();
+ if ( address->setAddress( TQString(list[1]) ) ) {
+ // only add ipv6 addresses from resolv.conf if
+ // this host supports ipv6.
+ if ( address->isIPv4Address() || ipv6support )
+ theNs->append( address );
+ else
+ delete address;
+ } else {
+ delete address;
+ }
+ } else if ( type == TQLatin1String("search") ) {
+ TQStringList srch = TQStringList::split( TQLatin1String(" "), list[1] );
+ for ( TQStringList::Iterator i = srch.begin(); i != srch.end(); ++i )
+ theDomains->append( (*i).lower().local8Bit() );
+
+ } else if ( type == TQLatin1String("domain") ) {
+ theDomains->append( list[1].lower().local8Bit() );
+ }
+ }
+ }
+
+ if (theNs->isEmpty()) {
+#if defined(Q_MODERN_RES_API)
+ struct __res_state res;
+ res_ninit( &res );
+ int i;
+ // tqfind the name servers to use
+ for( i=0; i < MAXNS && i < res.nscount; i++ )
+ theNs->append( new TQHostAddress( ntohl( res.nsaddr_list[i].sin_addr.s_addr ) ) );
+# if defined(MAXDFLSRCH)
+ for( i=0; i < MAXDFLSRCH; i++ ) {
+ if ( res.dnsrch[i] && *(res.dnsrch[i]) )
+ theDomains->append( TQT_TQSTRING(TQString::fromLatin1( res.dnsrch[i] )).lower().local8Bit() );
+ else
+ break;
+ }
+# endif
+ if ( *res.defdname )
+ theDomains->append( TQT_TQSTRING(TQString::fromLatin1( res.defdname )).lower().local8Bit() );
+#else
+ res_init();
+ int i;
+ // tqfind the name servers to use
+ for( i=0; i < MAXNS && i < _res.nscount; i++ )
+ theNs->append( new TQHostAddress( ntohl( _res.nsaddr_list[i].sin_addr.s_addr ) ) );
+# if defined(MAXDFLSRCH)
+ for( i=0; i < MAXDFLSRCH; i++ ) {
+ if ( _res.dnsrch[i] && *(_res.dnsrch[i]) )
+ theDomains->append( TQString::fromLatin1( _res.dnsrch[i] ).lower().local8Bit() );
+ else
+ break;
+ }
+# endif
+ if ( *_res.defdname )
+ theDomains->append( TQString::fromLatin1( _res.defdname ).lower().local8Bit() );
+#endif
+
+ // the code above adds "0.0.0.0" as a name server at the slightest
+ // hint of trouble. so remove those again.
+ theNs->first();
+ while( theNs->current() ) {
+ if ( theNs->current()->isNull() )
+ delete theNs->take();
+ else
+ theNs->next();
+ }
+ }
+
+ QFile hosts( TQString::fromLatin1( "/etc/hosts" ) );
+ if ( hosts.open( QIODevice::ReadOnly ) ) {
+ // read the /etc/hosts file, creating long-life A and PTR RRs
+ // for the things we tqfind.
+ QTextStream i( &hosts );
+ TQString line;
+ while( !i.atEnd() ) {
+ line = TQT_TQSTRING(i.readLine()).simplifyWhiteSpace().lower();
+ uint n = 0;
+ while( (int) n < line.length() && line[(int)n] != QLatin1Char('#') )
+ n++;
+ line.truncate( n );
+ n = 0;
+ while( (int) n < line.length() && !line[(int)n].isSpace() )
+ n++;
+ TQString ip = line.left( n );
+ TQHostAddress a;
+ a.setAddress( ip );
+ if ( ( a.isIPv4Address() || a.isIPv6Address() ) && !a.isNull() ) {
+ bool first = true;
+ line = line.mid( n+1 );
+ n = 0;
+ while( (int) n < line.length() && !line[(int)n].isSpace() )
+ n++;
+ TQString hostname = line.left( n );
+ // ### in case of bad syntax, hostname is invalid. do we care?
+ if ( n ) {
+ TQDnsRR * rr = new TQDnsRR( hostname );
+ if ( a.isIPv4Address() )
+ rr->t = TQDns::A;
+ else
+ rr->t = TQDns::Aaaa;
+ rr->address = a;
+ rr->deleteTime = UINT_MAX;
+ rr->expireTime = UINT_MAX;
+ rr->current = true;
+ if ( first ) {
+ first = false;
+ TQDnsRR * ptr = new TQDnsRR( TQDns::toInAddrArpaDomain( a ) );
+ ptr->t = TQDns::Ptr;
+ ptr->target = hostname;
+ ptr->deleteTime = UINT_MAX;
+ ptr->expireTime = UINT_MAX;
+ ptr->current = true;
+ }
+ }
+ }
+ }
+ }
+}
+
+#endif
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_DNS
+
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of TQDns class.
+**
+** Created : 991122
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// POSIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED.
+#if defined(connect)
+# undef connect
+#endif
+
+// UnixWare 7 redefines socket -> _socket
+#if defined(socket)
+# undef socket
+#endif
+
+#include "tqdns.h"
+
+#ifndef TQT_NO_DNS
+
+#include "tqdatetime.h"
+#include "tqdict.h"
+#include "tqptrlist.h"
+#include "tqstring.h"
+#include "tqtimer.h"
+#include "tqapplication.h"
+#include "tqptrvector.h"
+#include "tqstrlist.h"
+#include "tqptrdict.h"
+#include "tqfile.h"
+#include "tqtextstream.h"
+#include "tqsocketdevice.h"
+#include "tqcleanuphandler.h"
+#include <limits.h>
+#ifdef TQ_OS_MAC
+#include "../3rdparty/dlcompat/dlfcn.h"
+#endif
+
+//#define TQDNS_DEBUG
+
+static TQ_UINT16 id; // ### seeded started by now()
+
+
+static TQDateTime * originOfTime = 0;
+
+static TQCleanupHandler<TQDateTime> qdns_cleanup_time;
+
+static TQ_UINT32 now()
+{
+ if ( originOfTime )
+ return originOfTime->secsTo( TQDateTime::tqcurrentDateTime() );
+
+ originOfTime = new TQDateTime( TQDateTime::tqcurrentDateTime() );
+ ::id = originOfTime->time().msec() * 60 + originOfTime->time().second();
+ qdns_cleanup_time.add( &originOfTime );
+ return 0;
+}
+
+
+static TQPtrList<TQHostAddress> * ns = 0;
+static TQStrList * domains = 0;
+static bool ipv6support = FALSE;
+
+static int qdns_res_init()
+{
+#ifdef TQ_OS_MAC
+ typedef int (*PtrRes_init)();
+ static PtrRes_init ptrRes_init = 0;
+ if (!ptrRes_init)
+ ptrRes_init = (PtrRes_init)DL_PREFIX(dlsym)(RTLD_NEXT, "res_init");
+ if (ptrRes_init)
+ return (*ptrRes_init)();
+ else
+ return -1;
+#elif defined(TQ_OS_UNIX)
+ return res_init();
+#else
+ return 0; // not called at all on Windows.
+#endif
+}
+
+
+class TQDnsPrivate {
+public:
+ TQDnsPrivate() : queryTimer( 0 ), noNames(FALSE)
+ {
+#if defined(TQ_DNS_SYNCHRONOUS)
+#if defined(TQ_OS_UNIX)
+ noEventLoop = tqApp==0 || tqApp->loopLevel()==0;
+#else
+ noEventLoop = FALSE;
+#endif
+#endif
+ }
+ ~TQDnsPrivate()
+ {
+ delete queryTimer;
+ }
+private:
+ TQTimer * queryTimer;
+ bool noNames;
+#if defined(TQ_DNS_SYNCHRONOUS)
+ bool noEventLoop;
+#endif
+
+ friend class TQDns;
+ friend class TQDnsAnswer;
+};
+
+
+class TQDnsRR;
+class TQDnsDomain;
+
+
+
+// TQDnsRR is the class used to store a single RR. TQDnsRR can store
+// all of the supported RR types. a TQDnsRR is always cached.
+
+// TQDnsRR is mostly constructed from the outside. a but hacky, but
+// permissible since the entire class is internal.
+
+class TQDnsRR {
+public:
+ TQDnsRR( const TQString & label );
+ ~TQDnsRR();
+
+public:
+ TQDnsDomain * domain;
+ TQDns::RecordType t;
+ bool nxdomain;
+ bool current;
+ TQ_UINT32 expireTime;
+ TQ_UINT32 deleteTime;
+ // somewhat space-wasting per-type data
+ // a / aaaa
+ TQHostAddress address;
+ // cname / mx / srv / ptr
+ TQString target;
+ // mx / srv
+ TQ_UINT16 priority;
+ // srv
+ TQ_UINT16 weight;
+ TQ_UINT16 port;
+ // txt
+ TQString text; // could be overloaded into target...
+private:
+
+};
+
+
+class TQDnsDomain {
+public:
+ TQDnsDomain( const TQString & label );
+ ~TQDnsDomain();
+
+ static void add( const TQString & label, TQDnsRR * );
+ static TQPtrList<TQDnsRR> * cached( const TQDns * );
+
+ void take( TQDnsRR * );
+
+ void sweep( TQ_UINT32 thisSweep );
+
+ bool isEmpty() const { return rrs == 0 || rrs->isEmpty(); }
+
+ TQString name() const { return l; }
+
+public:
+ TQString l;
+ TQPtrList<TQDnsRR> * rrs;
+};
+
+
+class TQDnsQuery: public TQTimer { // this inheritance is a very evil hack
+public:
+ TQDnsQuery():
+ id( 0 ), t( TQDns::None ), step(0), started(0),
+ dns( new TQPtrDict<void>(17) ) {}
+ ~TQDnsQuery() { delete dns; }
+ TQ_UINT16 id;
+ TQDns::RecordType t;
+ TQString l;
+
+ uint step;
+ TQ_UINT32 started;
+
+ TQPtrDict<void> * dns;
+};
+
+
+
+class TQDnsAnswer {
+public:
+ TQDnsAnswer( TQDnsQuery * );
+ TQDnsAnswer( const TQByteArray &, TQDnsQuery * );
+ ~TQDnsAnswer();
+
+ void parse();
+ void notify();
+
+ bool ok;
+
+private:
+ TQDnsQuery * query;
+
+ TQ_UINT8 * answer;
+ int size;
+ int pp;
+
+ TQPtrList<TQDnsRR> * rrs;
+
+ // convenience
+ int next;
+ int ttl;
+ TQString label;
+ TQDnsRR * rr;
+
+ TQString readString(bool multipleLabels = TRUE);
+ void parseA();
+ void parseAaaa();
+ void parseMx();
+ void parseSrv();
+ void parseCname();
+ void parsePtr();
+ void parseTxt();
+ void parseNs();
+};
+
+
+TQDnsRR::TQDnsRR( const TQString & label )
+ : domain( 0 ), t( TQDns::None ),
+ nxdomain( FALSE ), current( FALSE ),
+ expireTime( 0 ), deleteTime( 0 ),
+ priority( 0 ), weight( 0 ), port( 0 )
+{
+ TQDnsDomain::add( label, this );
+}
+
+
+// not supposed to be deleted except by TQDnsDomain
+TQDnsRR::~TQDnsRR()
+{
+ // nothing is necessary
+}
+
+
+// this one just sticks in a NXDomain
+TQDnsAnswer::TQDnsAnswer( TQDnsQuery * query_ )
+{
+ ok = TRUE;
+
+ answer = 0;
+ size = 0;
+ query = query_;
+ pp = 0;
+ rrs = new TQPtrList<TQDnsRR>;
+ rrs->setAutoDelete( FALSE );
+ next = size;
+ ttl = 0;
+ label = TQString::null;
+ rr = 0;
+
+ TQDnsRR * newrr = new TQDnsRR( query->l );
+ newrr->t = query->t;
+ newrr->deleteTime = query->started + 10;
+ newrr->expireTime = query->started + 10;
+ newrr->nxdomain = TRUE;
+ newrr->current = TRUE;
+ rrs->append( newrr );
+}
+
+
+TQDnsAnswer::TQDnsAnswer( const TQByteArray& answer_,
+ TQDnsQuery * query_ )
+{
+ ok = TRUE;
+
+ answer = (TQ_UINT8 *)(answer_.data());
+ size = (int)answer_.size();
+ query = query_;
+ pp = 0;
+ rrs = new TQPtrList<TQDnsRR>;
+ rrs->setAutoDelete( FALSE );
+ next = size;
+ ttl = 0;
+ label = TQString::null;
+ rr = 0;
+}
+
+
+TQDnsAnswer::~TQDnsAnswer()
+{
+ if ( !ok && rrs ) {
+ TQPtrListIterator<TQDnsRR> it( *rrs );
+ TQDnsRR * tmprr;
+ while( (tmprr=it.current()) != 0 ) {
+ ++it;
+ tmprr->t = TQDns::None; // will be deleted soonish
+ }
+ }
+ delete rrs;
+}
+
+
+TQString TQDnsAnswer::readString(bool multipleLabels)
+{
+ int p = pp;
+ TQString r = TQString::null;
+ TQ_UINT8 b;
+ for( ;; ) {
+ b = 128;
+ // Read one character
+ if ( p >= 0 && p < size )
+ b = answer[p];
+
+ switch( b >> 6 ) {
+ case 0:
+ // b is less than 64
+ p++;
+
+ // Detect end of data
+ if ( b == 0 ) {
+ if ( p > pp )
+ pp = p;
+ return r.isNull() ? TQString( "." ) : r;
+ }
+
+ // Read a label of size 'b' characters
+ if ( !r.isNull() )
+ r += '.';
+ while( b-- > 0 ) {
+ r += TQChar( answer[p] );
+ p++;
+ }
+
+ // Return immediately if we were only supposed to read one
+ // label.
+ if (!multipleLabels)
+ return r;
+
+ break;
+ default:
+ // Ignore unrecognized control character, or p was out of
+ // range.
+ goto not_ok;
+ case 3:
+ // Use the next character to determine the relative offset
+ // to jump to before continuing the packet parsing.
+ int q = ( (answer[p] & 0x3f) << 8 ) + answer[p+1];
+
+ if ( q >= pp || q >= p )
+ goto not_ok;
+ if ( p >= pp )
+ pp = p + 2;
+ p = q;
+ }
+ }
+not_ok:
+ ok = FALSE;
+ return TQString::null;
+}
+
+
+
+void TQDnsAnswer::parseA()
+{
+ if ( next != pp + 4 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %d bytes long IN A for %s",
+ next - pp, label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->t = TQDns::A;
+ rr->address = TQHostAddress( ( answer[pp+0] << 24 ) +
+ ( answer[pp+1] << 16 ) +
+ ( answer[pp+2] << 8 ) +
+ ( answer[pp+3] ) );
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN A %s (ttl %d)", label.ascii(),
+ rr->address.toString().ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parseAaaa()
+{
+ if ( next != pp + 16 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %d bytes long IN Aaaa for %s",
+ next - pp, label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->t = TQDns::Aaaa;
+ rr->address = TQHostAddress( answer+pp );
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN Aaaa %s (ttl %d)", label.ascii(),
+ rr->address.toString().ascii(), ttl );
+#endif
+}
+
+
+
+void TQDnsAnswer::parseMx()
+{
+ if ( next < pp + 2 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %d bytes long IN MX for %s",
+ next - pp, label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->priority = (answer[pp] << 8) + answer[pp+1];
+ pp += 2;
+ rr->target = readString().lower();
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad string in MX for %s", label.ascii() );
+#endif
+ return;
+ }
+ rr->t = TQDns::Mx;
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN MX %d %s (ttl %d)", label.ascii(),
+ rr->priority, rr->target.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parseSrv()
+{
+ if ( next < pp + 6 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %d bytes long IN SRV for %s",
+ next - pp, label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->priority = (answer[pp] << 8) + answer[pp+1];
+ rr->weight = (answer[pp+2] << 8) + answer[pp+3];
+ rr->port = (answer[pp+4] << 8) + answer[pp+5];
+ pp += 6;
+ rr->target = readString().lower();
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad string in SRV for %s", label.ascii() );
+#endif
+ return;
+ }
+ rr->t = TQDns::Srv;
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN SRV %d %d %d %s (ttl %d)", label.ascii(),
+ rr->priority, rr->weight, rr->port, rr->target.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parseCname()
+{
+ TQString target = readString().lower();
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad cname for for %s", label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->t = TQDns::Cname;
+ rr->target = target;
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN CNAME %s (ttl %d)", label.ascii(),
+ rr->target.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parseNs()
+{
+ TQString target = readString().lower();
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad cname for for %s", label.ascii() );
+#endif
+ return;
+ }
+
+ // parse, but ignore
+
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN NS %s (ttl %d)", label.ascii(),
+ target.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parsePtr()
+{
+ TQString target = readString().lower();
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad PTR for for %s", label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->t = TQDns::Ptr;
+ rr->target = target;
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN PTR %s (ttl %d)", label.ascii(),
+ rr->target.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parseTxt()
+{
+ TQString text = readString(FALSE);
+ if ( !ok ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw bad TXT for for %s", label.ascii() );
+#endif
+ return;
+ }
+
+ rr = new TQDnsRR( label );
+ rr->t = TQDns::Txt;
+ rr->text = text;
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns: saw %s IN TXT \"%s\" (ttl %d)", label.ascii(),
+ rr->text.ascii(), ttl );
+#endif
+}
+
+
+void TQDnsAnswer::parse()
+{
+ // okay, do the work...
+ if ( (answer[2] & 0x78) != 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: answer to wrong query type (%d)", answer[1] );
+#endif
+ ok = FALSE;
+ return;
+ }
+
+ // AA
+ bool aa = (answer[2] & 4) != 0;
+
+ // TC
+ if ( (answer[2] & 2) != 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: truncated answer; pressing on" );
+#endif
+ }
+
+ // RD
+ bool rd = (answer[2] & 1) != 0;
+
+ // we don't test RA
+ // we don't test the MBZ fields
+
+ if ( (answer[3] & 0x0f) == 3 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: saw NXDomain for %s", query->l.ascii() );
+#endif
+ // NXDomain. cache that for one minute.
+ rr = new TQDnsRR( query->l );
+ rr->t = query->t;
+ rr->deleteTime = query->started + 60;
+ rr->expireTime = query->started + 60;
+ rr->nxdomain = TRUE;
+ rr->current = TRUE;
+ rrs->append( rr );
+ return;
+ }
+
+ if ( (answer[3] & 0x0f) != 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: error code %d", answer[3] & 0x0f );
+#endif
+ ok = FALSE;
+ return;
+ }
+
+ int qdcount = ( answer[4] << 8 ) + answer[5];
+ int ancount = ( answer[6] << 8 ) + answer[7];
+ int nscount = ( answer[8] << 8 ) + answer[9];
+ int adcount = (answer[10] << 8 ) +answer[11];
+
+ pp = 12;
+
+ // read query
+ while( qdcount > 0 && pp < size ) {
+ // should I compare the string against query->l?
+ (void)readString();
+ if ( !ok )
+ return;
+ pp += 4;
+ qdcount--;
+ }
+
+ // answers and stuff
+ int rrno = 0;
+ // if we parse the answer completely, but there are no answers,
+ // ignore the entire thing.
+ int answers = 0;
+ while( ( rrno < ancount ||
+ ( ok && answers >0 && rrno < ancount + nscount + adcount ) ) &&
+ pp < size ) {
+ label = readString().lower();
+ if ( !ok )
+ return;
+ int rdlength = 0;
+ if ( pp + 10 <= size )
+ rdlength = ( answer[pp+8] << 8 ) + answer[pp+9];
+ if ( pp + 10 + rdlength > size ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: ran out of stuff to parse (%d+%d>%d (%d)",
+ pp, rdlength, size, rrno < ancount );
+#endif
+ // if we're still in the AN section, we should go back and
+ // at least down the TTLs. probably best to tqinvalidate
+ // the results.
+ // the rrs list is good for this
+ ok = ( rrno < ancount );
+ return;
+ }
+ uint type, clas;
+ type = ( answer[pp+0] << 8 ) + answer[pp+1];
+ clas = ( answer[pp+2] << 8 ) + answer[pp+3];
+ ttl = ( answer[pp+4] << 24 ) + ( answer[pp+5] << 16 ) +
+ ( answer[pp+6] << 8 ) + answer[pp+7];
+ pp = pp + 10;
+ if ( clas != 1 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: class %d (not internet) for %s",
+ clas, label.isNull() ? "." : label.ascii() );
+#endif
+ } else {
+ next = pp + rdlength;
+ rr = 0;
+ switch( type ) {
+ case 1:
+ parseA();
+ break;
+ case 28:
+ parseAaaa();
+ break;
+ case 15:
+ parseMx();
+ break;
+ case 33:
+ parseSrv();
+ break;
+ case 5:
+ parseCname();
+ break;
+ case 12:
+ parsePtr();
+ break;
+ case 16:
+ parseTxt();
+ break;
+ case 2:
+ parseNs();
+ break;
+ default:
+ // something we don't know
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: type %d for %s", type,
+ label.isNull() ? "." : label.ascii() );
+#endif
+ break;
+ }
+ if ( rr ) {
+ rr->deleteTime = 0;
+ if ( ttl > 0 )
+ rr->expireTime = query->started + ttl;
+ else
+ rr->expireTime = query->started + 20;
+ if ( rrno < ancount ) {
+ answers++;
+ rr->deleteTime = rr->expireTime;
+ }
+ rr->current = TRUE;
+ rrs->append( rr );
+ }
+ }
+ if ( !ok )
+ return;
+ pp = next;
+ next = size;
+ rrno++;
+ }
+ if ( answers == 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: answer contained no answers" );
+#endif
+ ok = ( aa && rd );
+ }
+
+ // now go through the list and mark all the As that are referenced
+ // by something we care about. we want to cache such As.
+ rrs->first();
+ TQDict<void> used( 17 );
+ used.setAutoDelete( FALSE );
+ while( (rr=rrs->current()) != 0 ) {
+ rrs->next();
+ if ( rr->target.length() && rr->deleteTime > 0 && rr->current )
+ used.insert( rr->target, (void*)42 );
+ if ( ( rr->t == TQDns::A || rr->t == TQDns::Aaaa ) &&
+ used.tqfind( rr->domain->name() ) != 0 )
+ rr->deleteTime = rr->expireTime;
+ }
+
+ // next, for each RR, delete any older RRs that are equal to it
+ rrs->first();
+ while( (rr=rrs->current()) != 0 ) {
+ rrs->next();
+ if ( rr && rr->domain && rr->domain->rrs ) {
+ TQPtrList<TQDnsRR> * drrs = rr->domain->rrs;
+ drrs->first();
+ TQDnsRR * older;
+ while( (older=drrs->current()) != 0 ) {
+ if ( older != rr &&
+ older->t == rr->t &&
+ older->nxdomain == rr->nxdomain &&
+ older->address == rr->address &&
+ older->target == rr->target &&
+ older->priority == rr->priority &&
+ older->weight == rr->weight &&
+ older->port == rr->port &&
+ older->text == rr->text ) {
+ // well, it's equal, but it's not the same. so we kill it,
+ // but use its expiry time.
+#if defined(TQDNS_DEBUG)
+ qDebug( "killing off old %d for %s, expire was %d",
+ older->t, older->domain->name().latin1(),
+ rr->expireTime );
+#endif
+ older->t = TQDns::None;
+ rr->expireTime = TQMAX( older->expireTime, rr->expireTime );
+ rr->deleteTime = TQMAX( older->deleteTime, rr->deleteTime );
+ older->deleteTime = 0;
+#if defined(TQDNS_DEBUG)
+ qDebug( " adjusted expire is %d", rr->expireTime );
+#endif
+ }
+ drrs->next();
+ }
+ }
+ }
+
+#if defined(TQDNS_DEBUG)
+ //qDebug( "DNS Manager: ()" );
+#endif
+}
+
+
+class TQDnsUgleHack: public TQDns {
+public:
+ void ugle( bool emitAnyway=FALSE );
+};
+
+
+void TQDnsAnswer::notify()
+{
+ if ( !rrs || !ok || !query || !query->dns )
+ return;
+
+ TQPtrDict<void> notified;
+ notified.setAutoDelete( FALSE );
+
+ TQPtrDictIterator<void> it( *query->dns );
+ TQDns * dns;
+ it.toFirst();
+ while( (dns=(TQDns*)(it.current())) != 0 ) {
+ ++it;
+ if ( notified.tqfind( (void*)dns ) == 0 ) {
+ notified.insert( (void*)dns, (void*)42 );
+ if ( rrs->count() == 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: found no answers!" );
+#endif
+ dns->d->noNames = TRUE;
+ ((TQDnsUgleHack*)dns)->ugle( TRUE );
+ } else {
+ TQStringList n = dns->qualifiedNames();
+ if ( query && n.tqcontains(query->l) )
+ ((TQDnsUgleHack*)dns)->ugle();
+#if defined(TQDNS_DEBUG)
+ else
+ qDebug( "DNS Manager: DNS thing %s not notified for %s",
+ dns->label().ascii(), query->l.ascii() );
+#endif
+ }
+ }
+ }
+}
+
+
+//
+//
+// TQDnsManager
+//
+//
+
+
+class TQDnsManager: public TQDnsSocket {
+private:
+public: // just to silence the moronic g++.
+ TQDnsManager();
+ ~TQDnsManager();
+public:
+ static TQDnsManager * manager();
+
+ TQDnsDomain * domain( const TQString & );
+
+ void transmitQuery( TQDnsQuery * );
+ void transmitQuery( int );
+
+ // reimplementation of the Q_SLOTS
+ void cleanCache();
+ void retransmit();
+ void answer();
+
+public:
+ TQPtrVector<TQDnsQuery> queries;
+ TQDict<TQDnsDomain> cache;
+ TQSocketDevice * ipv4Socket;
+#if !defined (TQT_NO_IPV6)
+ TQSocketDevice * ipv6Socket;
+#endif
+};
+
+
+
+static TQDnsManager * globalManager = 0;
+
+static void cleanupDns()
+{
+ delete globalManager;
+ globalManager = 0;
+}
+
+TQDnsManager * TQDnsManager::manager()
+{
+ if ( !globalManager ) {
+ qAddPostRoutine(cleanupDns);
+ new TQDnsManager();
+ }
+ return globalManager;
+}
+
+
+void TQDnsUgleHack::ugle( bool emitAnyway)
+{
+ if ( emitAnyway || !isWorking() ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: status change for %s (type %d)",
+ label().ascii(), recordType() );
+#endif
+ emit resultsReady();
+ }
+}
+
+
+TQDnsManager::TQDnsManager()
+ : TQDnsSocket( tqApp, "Internal DNS manager" ),
+ queries( TQPtrVector<TQDnsQuery>( 0 ) ),
+ cache( TQDict<TQDnsDomain>( 83, FALSE ) ),
+ ipv4Socket( new TQSocketDevice( TQSocketDevice::Datagram, TQSocketDevice::IPv4, 0 ) )
+#if !defined (TQT_NO_IPV6)
+ , ipv6Socket( new TQSocketDevice( TQSocketDevice::Datagram, TQSocketDevice::IPv6, 0 ) )
+#endif
+{
+ cache.setAutoDelete( TRUE );
+ globalManager = this;
+
+ TQTimer * sweepTimer = new TQTimer( this );
+ sweepTimer->start( 1000 * 60 * 3 );
+ connect( sweepTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(cleanCache()) );
+
+ TQSocketNotifier * rn4 = new TQSocketNotifier( ipv4Socket->socket(),
+ TQSocketNotifier::Read,
+ TQT_TQOBJECT(this), "dns IPv4 socket watcher" );
+ ipv4Socket->setAddressReusable( FALSE );
+ ipv4Socket->setBlocking( FALSE );
+ connect( rn4, TQT_SIGNAL(activated(int)), TQT_SLOT(answer()) );
+
+#if !defined (TQT_NO_IPV6)
+ // Don't connect the IPv6 socket notifier if the host does not
+ // support IPv6.
+ if ( ipv6Socket->socket() != -1 ) {
+ TQSocketNotifier * rn6 = new TQSocketNotifier( ipv6Socket->socket(),
+ TQSocketNotifier::Read,
+ TQT_TQOBJECT(this), "dns IPv6 socket watcher" );
+
+ ipv6support = TRUE;
+ ipv6Socket->setAddressReusable( FALSE );
+ ipv6Socket->setBlocking( FALSE );
+ connect( rn6, TQT_SIGNAL(activated(int)), TQT_SLOT(answer()) );
+ }
+#endif
+
+ if ( !ns )
+ TQDns::doResInit();
+
+ // O(n*n) stuff here. but for 3 and 6, O(n*n) with a low k should
+ // be perfect. the point is to eliminate any duplicates that
+ // might be hidden in the lists.
+ TQPtrList<TQHostAddress> * ns = new TQPtrList<TQHostAddress>;
+
+ ::ns->first();
+ TQHostAddress * h;
+ while( (h=::ns->current()) != 0 ) {
+ ns->first();
+ while( ns->current() != 0 && !(*ns->current() == *h) )
+ ns->next();
+ if ( !ns->current() ) {
+ ns->append( new TQHostAddress(*h) );
+#if defined(TQDNS_DEBUG)
+ qDebug( "using name server %s", h->toString().latin1() );
+ } else {
+ qDebug( "skipping address %s", h->toString().latin1() );
+#endif
+ }
+ ::ns->next();
+ }
+
+ delete ::ns;
+ ::ns = ns;
+ ::ns->setAutoDelete( TRUE );
+
+ TQStrList * domains = new TQStrList( TRUE );
+
+ ::domains->first();
+ const char * s;
+ while( (s=::domains->current()) != 0 ) {
+ domains->first();
+ while( domains->current() != 0 && qstrcmp( domains->current(), s ) )
+ domains->next();
+ if ( !domains->current() ) {
+ domains->append( s );
+#if defined(TQDNS_DEBUG)
+ qDebug( "searching domain %s", s );
+ } else {
+ qDebug( "skipping domain %s", s );
+#endif
+ }
+ ::domains->next();
+ }
+
+ delete ::domains;
+ ::domains = domains;
+ ::domains->setAutoDelete( TRUE );
+}
+
+
+TQDnsManager::~TQDnsManager()
+{
+ if ( globalManager )
+ globalManager = 0;
+ queries.setAutoDelete( TRUE );
+ cache.setAutoDelete( TRUE );
+ delete ipv4Socket;
+#if !defined (TQT_NO_IPV6)
+ delete ipv6Socket;
+#endif
+}
+
+static TQ_UINT32 lastSweep = 0;
+
+void TQDnsManager::cleanCache()
+{
+ bool again = FALSE;
+ TQDictIterator<TQDnsDomain> it( cache );
+ TQDnsDomain * d;
+ TQ_UINT32 thisSweep = now();
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDnsManager::cleanCache(: Called, time is %u, last was %u",
+ thisSweep, lastSweep );
+#endif
+
+ while( (d=it.current()) != 0 ) {
+ ++it;
+ d->sweep( thisSweep ); // after this, d may be empty
+ if ( !again )
+ again = !d->isEmpty();
+ }
+ if ( !again )
+ delete this;
+ lastSweep = thisSweep;
+}
+
+
+void TQDnsManager::retransmit()
+{
+ const TQObject * o = sender();
+ if ( o == 0 || globalManager == 0 || this != globalManager )
+ return;
+ uint q = 0;
+ while( q < queries.size() && queries[q] != o )
+ q++;
+ if ( q < queries.size() )
+ transmitQuery( q );
+}
+
+
+void TQDnsManager::answer()
+{
+ TQByteArray a( 16383 ); // large enough for anything, one suspects
+
+ int r;
+#if defined (TQT_NO_IPV6)
+ r = ipv4Socket->readBlock(a.data(), a.size());
+#else
+ if (((TQSocketNotifier *)sender())->socket() == ipv4Socket->socket())
+ r = ipv4Socket->readBlock(a.data(), a.size());
+ else
+ r = ipv6Socket->readBlock(a.data(), a.size());
+#endif
+#if defined(TQDNS_DEBUG)
+#if !defined (TQT_NO_IPV6)
+ qDebug("DNS Manager: answer arrived: %d bytes from %s:%d", r,
+ useIpv4Socket ? ipv4Socket->peerAddress().toString().ascii()
+ : ipv6Socket->peerAddress().toString().ascii(),
+ useIpv4Socket ? ipv4Socket->peerPort() : ipv6Socket->peerPort() );
+#else
+ qDebug("DNS Manager: answer arrived: %d bytes from %s:%d", r,
+ ipv4Socket->peerAddress().toString().ascii(), ipv4Socket->peerPort());;
+#endif
+#endif
+ if ( r < 12 )
+ return;
+ // maybe we should check that the answer comes from port 53 on one
+ // of our name servers...
+ a.resize( r );
+
+ TQ_UINT16 aid = (((TQ_UINT8)a[0]) << 8) + ((TQ_UINT8)a[1]);
+ uint i = 0;
+ while( i < queries.size() &&
+ !( queries[i] && queries[i]->id == aid ) )
+ i++;
+ if ( i == queries.size() ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: bad id (0x%04x) %d", aid, i );
+#endif
+ return;
+ }
+
+ // at this point queries[i] is whatever we asked for.
+
+ if ( ( (TQ_UINT8)(a[2]) & 0x80 ) == 0 ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: received a query" );
+#endif
+ return;
+ }
+
+ TQDnsQuery * q = queries[i];
+ TQDnsAnswer answer( a, q );
+ answer.parse();
+ if ( answer.ok ) {
+ queries.take( i );
+ answer.notify();
+ delete q;
+ }
+}
+
+
+void TQDnsManager::transmitQuery( TQDnsQuery * query_ )
+{
+ if ( !query_ )
+ return;
+
+ uint i = 0;
+ while( i < queries.size() && queries[i] != 0 )
+ i++;
+ if ( i == queries.size() )
+ queries.resize( i+1 );
+ queries.insert( i, query_ );
+ transmitQuery( i );
+}
+
+
+void TQDnsManager::transmitQuery( int i )
+{
+ if ( i < 0 || i >= (int)queries.size() )
+ return;
+ TQDnsQuery * q = queries[i];
+
+ if ( q && q->step > 8 ) {
+ // okay, we've run out of retransmissions. we fake an NXDomain
+ // with a very short life time...
+ TQDnsAnswer answer( q );
+ answer.notify();
+
+ if (globalManager == 0)
+ return;
+
+ // and then get rid of the query
+ queries.take( i );
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: giving up on query 0x%04x", q->id );
+#endif
+ delete q;
+ TQTimer::singleShot( 0, TQDnsManager::manager(), TQT_SLOT(cleanCache()) );
+ // and don't process anything more
+ return;
+ }
+
+ if ( q && !q->dns || q->dns->isEmpty() )
+ // noone currently wants the answer, so there's no point in
+ // retransmitting the query. we keep it, though. an answer may
+ // arrive for an earlier query transmission, and if it does we
+ // may benefit from caching the result.
+ return;
+
+ TQByteArray p( 12 + q->l.length() + 2 + 4 );
+ if ( p.size() > 500 )
+ return; // way over the limit, so don't even try
+
+ // header
+ // id
+ p[0] = (q->id & 0xff00) >> 8;
+ p[1] = q->id & 0x00ff;
+ p[2] = 1; // recursion desired, rest is 0
+ p[3] = 0; // all is 0
+ // one query
+ p[4] = 0;
+ p[5] = 1;
+ // no answers, name servers or additional data
+ p[6] = p[7] = p[8] = p[9] = p[10] = p[11] = 0;
+
+ // the name is composed of several components. each needs to be
+ // written by itself... so we write...
+ // oh, and we assume that there's no funky characters in there.
+ int pp = 12;
+ uint lp = 0;
+ while( lp < q->l.length() ) {
+ int le = q->l.tqfind( '.', lp );
+ if ( le < 0 )
+ le = q->l.length();
+ TQString component = q->l.mid( lp, le-lp );
+ p[pp++] = component.length();
+ int cp;
+ for( cp=0; cp < (int)component.length(); cp++ )
+ p[pp++] = component[cp].latin1();
+ lp = le + 1;
+ }
+ // final null
+ p[pp++] = 0;
+ // query type
+ p[pp++] = 0;
+ switch( q->t ) {
+ case TQDns::A:
+ p[pp++] = 1;
+ break;
+ case TQDns::Aaaa:
+ p[pp++] = 28;
+ break;
+ case TQDns::Mx:
+ p[pp++] = 15;
+ break;
+ case TQDns::Srv:
+ p[pp++] = 33;
+ break;
+ case TQDns::Cname:
+ p[pp++] = 5;
+ break;
+ case TQDns::Ptr:
+ p[pp++] = 12;
+ break;
+ case TQDns::Txt:
+ p[pp++] = 16;
+ break;
+ default:
+ p[pp++] = (char)255; // any
+ break;
+ }
+ // query class (always internet)
+ p[pp++] = 0;
+ p[pp++] = 1;
+
+ // if we have no name servers, we should regenerate ns in case
+ // name servers have recently been defined (like on windows,
+ // plugging/unplugging the network cable will change the name
+ // server entries)
+ if ( !ns || ns->isEmpty() )
+ TQDns::doResInit();
+
+ if ( !ns || ns->isEmpty() ) {
+ // we don't tqfind any name servers. We fake an NXDomain
+ // with a very short life time...
+ TQDnsAnswer answer( q );
+ answer.notify();
+ // and then get rid of the query
+ queries.take( i );
+#if defined(TQDNS_DEBUG)
+ qDebug( "DNS Manager: no DNS server found on query 0x%04x", q->id );
+#endif
+ delete q;
+ TQTimer::singleShot( 1000*10, TQDnsManager::manager(), TQT_SLOT(cleanCache()) );
+ // and don't process anything more
+ return;
+ }
+
+ TQHostAddress receiver = *ns->at( q->step % ns->count() );
+ if (receiver.isIPv4Address())
+ ipv4Socket->writeBlock( p.data(), pp, receiver, 53 );
+#if !defined (TQT_NO_IPV6)
+ else
+ ipv6Socket->writeBlock( p.data(), pp, receiver, 53 );
+#endif
+#if defined(TQDNS_DEBUG)
+ qDebug( "issuing query 0x%04x (%d) about %s type %d to %s",
+ q->id, q->step, q->l.ascii(), q->t,
+ ns->at( q->step % ns->count() )->toString().ascii() );
+#endif
+ if ( ns->count() > 1 && q->step == 0 && queries.count() == 1 ) {
+ // if it's the first time, and we don't have any other
+ // outstanding queries, send nonrecursive queries to the other
+ // name servers too.
+ p[2] = 0;
+ TQHostAddress * server;
+ while( (server=ns->next()) != 0 ) {
+ if (server->isIPv4Address())
+ ipv4Socket->writeBlock( p.data(), pp, *server, 53 );
+#if !defined (TQT_NO_IPV6)
+ else
+ ipv6Socket->writeBlock( p.data(), pp, *server, 53 );
+#endif
+#if defined(TQDNS_DEBUG)
+ qDebug( "copying query to %s", server->toString().ascii() );
+#endif
+ }
+ }
+ q->step++;
+ // some testing indicates that normal dns queries take up to 0.6
+ // seconds. the graph becomes steep around that point, and the
+ // number of errors rises... so it seems good to retry at that
+ // point.
+ q->start( q->step < ns->count() ? 800 : 1500, TRUE );
+}
+
+
+TQDnsDomain * TQDnsManager::domain( const TQString & label )
+{
+ TQDnsDomain * d = cache.tqfind( label );
+ if ( !d ) {
+ d = new TQDnsDomain( label );
+ cache.insert( label, d );
+ }
+ return d;
+}
+
+
+//
+//
+// the TQDnsDomain class looks after and coordinates queries for TQDnsRRs for
+// each domain, and the cached TQDnsRRs. (A domain, in DNS terminology, is
+// a node in the DNS. "no", "trolltech.com" and "lupinella.troll.no" are
+// all domains.)
+//
+//
+
+
+// this is ONLY to be called by TQDnsManager::domain(). noone else.
+TQDnsDomain::TQDnsDomain( const TQString & label )
+{
+ l = label;
+ rrs = 0;
+}
+
+
+TQDnsDomain::~TQDnsDomain()
+{
+ delete rrs;
+ rrs = 0;
+}
+
+
+void TQDnsDomain::add( const TQString & label, TQDnsRR * rr )
+{
+ TQDnsDomain * d = TQDnsManager::manager()->domain( label );
+ if ( !d->rrs ) {
+ d->rrs = new TQPtrList<TQDnsRR>;
+ d->rrs->setAutoDelete( TRUE );
+ }
+ d->rrs->append( rr );
+ rr->domain = d;
+}
+
+
+TQPtrList<TQDnsRR> * TQDnsDomain::cached( const TQDns * r )
+{
+ TQPtrList<TQDnsRR> * l = new TQPtrList<TQDnsRR>;
+
+ // test at first if you have to start a query at all
+ if ( r->recordType() == TQDns::A ) {
+ if ( r->label().lower() == "localhost" ) {
+ // undocumented hack. ipv4-specific. also, may be a memory
+ // leak? not sure. would be better to do this in doResInit(),
+ // anyway.
+ TQDnsRR *rrTmp = new TQDnsRR( r->label() );
+ rrTmp->t = TQDns::A;
+ rrTmp->address = TQHostAddress( 0x7f000001 );
+ rrTmp->current = TRUE;
+ l->append( rrTmp );
+ return l;
+ }
+ TQHostAddress tmp;
+ if ( tmp.setAddress( r->label() ) ) {
+ TQDnsRR *rrTmp = new TQDnsRR( r->label() );
+ if ( tmp.isIPv4Address() ) {
+ rrTmp->t = TQDns::A;
+ rrTmp->address = tmp;
+ rrTmp->current = TRUE;
+ l->append( rrTmp );
+ } else {
+ rrTmp->nxdomain = TRUE;
+ }
+ return l;
+ }
+ }
+ if ( r->recordType() == TQDns::Aaaa ) {
+ TQHostAddress tmp;
+ if ( tmp.setAddress(r->label()) ) {
+ TQDnsRR *rrTmp = new TQDnsRR( r->label() );
+ if ( tmp.isIPv6Address() ) {
+ rrTmp->t = TQDns::Aaaa;
+ rrTmp->address = tmp;
+ rrTmp->current = TRUE;
+ l->append( rrTmp );
+ } else {
+ rrTmp->nxdomain = TRUE;
+ }
+ return l;
+ }
+ }
+
+ // if you reach this point, you have to do the query
+ TQDnsManager * m = TQDnsManager::manager();
+ TQStringList n = r->qualifiedNames();
+ TQValueListIterator<TQString> it = n.begin();
+ TQValueListIterator<TQString> end = n.end();
+ bool nxdomain;
+ int cnamecount = 0;
+ while( it != end ) {
+ TQString s = *it++;
+ nxdomain = FALSE;
+#if defined(TQDNS_DEBUG)
+ qDebug( "looking at cache for %s (%s %d)",
+ s.ascii(), r->label().ascii(), r->recordType() );
+#endif
+ TQDnsDomain * d = m->domain( s );
+#if defined(TQDNS_DEBUG)
+ qDebug( " - found %d RRs", d && d->rrs ? d->rrs->count() : 0 );
+#endif
+ if ( d->rrs )
+ d->rrs->first();
+ TQDnsRR * rr;
+ bool answer = FALSE;
+ while( d->rrs && (rr=d->rrs->current()) != 0 ) {
+ if ( rr->t == TQDns::Cname && r->recordType() != TQDns::Cname &&
+ !rr->nxdomain && cnamecount < 16 ) {
+ // cname. if the code is ugly, that may just
+ // possibly be because the concept is.
+#if defined(TQDNS_DEBUG)
+ qDebug( "found cname from %s to %s",
+ r->label().ascii(), rr->target.ascii() );
+#endif
+ s = rr->target;
+ d = m->domain( s );
+ if ( d->rrs )
+ d->rrs->first();
+ it = end;
+ // we've elegantly moved over to whatever the cname
+ // pointed to. well, not elegantly. let's remember
+ // that we've done something, anyway, so we can't be
+ // fooled into an infinte loop as well.
+ cnamecount++;
+ } else {
+ if ( rr->t == r->recordType() ) {
+ if ( rr->nxdomain )
+ nxdomain = TRUE;
+ else
+ answer = TRUE;
+ l->append( rr );
+ if ( rr->deleteTime <= lastSweep ) {
+ // we're returning something that'll be
+ // deleted soon. we assume that if the client
+ // wanted it twice, it'll want it again, so we
+ // ask the name server again right now.
+ TQDnsQuery * query = new TQDnsQuery;
+ query->started = now();
+ query->id = ++::id;
+ query->t = rr->t;
+ query->l = rr->domain->name();
+ // note that here, we don't bother about
+ // notification. but we do bother about
+ // timeouts: we make sure to use high timeouts
+ // and few tramsissions.
+ query->step = ns->count();
+ TQObject::connect( query, TQT_SIGNAL(timeout()),
+ TQDnsManager::manager(),
+ TQT_SLOT(retransmit()) );
+ TQDnsManager::manager()->transmitQuery( query );
+ }
+ }
+ d->rrs->next();
+ }
+ }
+ // if we found a positive result, return quickly
+ if ( answer && l->count() ) {
+#if defined(TQDNS_DEBUG)
+ qDebug( "found %d records for %s",
+ l->count(), r->label().ascii() );
+ l->first();
+ while( l->current() ) {
+ qDebug( " type %d target %s address %s",
+ l->current()->t,
+ l->current()->target.latin1(),
+ l->current()->address.toString().latin1() );
+ l->next();
+ }
+#endif
+ l->first();
+ return l;
+ }
+
+#if defined(TQDNS_DEBUG)
+ if ( nxdomain )
+ qDebug( "found NXDomain %s", s.ascii() );
+#endif
+
+ if ( !nxdomain ) {
+ // if we didn't, and not a negative result either, perhaps
+ // we need to transmit a query.
+ uint q = 0;
+ while ( q < m->queries.size() &&
+ ( m->queries[q] == 0 ||
+ m->queries[q]->t != r->recordType() ||
+ m->queries[q]->l != s ) )
+ q++;
+ // we haven't done it before, so maybe we should. but
+ // wait - if it's an unqualified name, only ask when all
+ // the other alternatives are exhausted.
+ if ( q == m->queries.size() && ( s.tqfind( '.' ) >= 0 ||
+ l->count() >= n.count()-1 ) ) {
+ TQDnsQuery * query = new TQDnsQuery;
+ query->started = now();
+ query->id = ++::id;
+ query->t = r->recordType();
+ query->l = s;
+ query->dns->tqreplace( (void*)r, (void*)r );
+ TQObject::connect( query, TQT_SIGNAL(timeout()),
+ TQDnsManager::manager(), TQT_SLOT(retransmit()) );
+ TQDnsManager::manager()->transmitQuery( query );
+ } else if ( q < m->queries.size() ) {
+ // if we've found an earlier query for the same
+ // domain/type, subscribe to its answer
+ m->queries[q]->dns->tqreplace( (void*)r, (void*)r );
+ }
+ }
+ }
+ l->first();
+ return l;
+}
+
+
+void TQDnsDomain::sweep( TQ_UINT32 thisSweep )
+{
+ if ( !rrs )
+ return;
+
+ TQDnsRR * rr;
+ rrs->first();
+ while( (rr=rrs->current()) != 0 ) {
+ if ( !rr->deleteTime )
+ rr->deleteTime = thisSweep; // will hit next time around
+
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::sweep: %s type %d expires %u %u - %s / %s",
+ rr->domain->name().latin1(), rr->t,
+ rr->expireTime, rr->deleteTime,
+ rr->target.latin1(), rr->address.toString().latin1());
+#endif
+ if ( rr->current == FALSE ||
+ rr->t == TQDns::None ||
+ rr->deleteTime <= thisSweep ||
+ rr->expireTime <= thisSweep )
+ rrs->remove();
+ else
+ rrs->next();
+ }
+
+ if ( rrs->isEmpty() ) {
+ delete rrs;
+ rrs = 0;
+ }
+}
+
+
+
+
+// the itsy-bitsy little socket class I don't really need except for
+// so I can subclass and reimplement the Q_SLOTS.
+
+
+TQDnsSocket::TQDnsSocket( TQObject * tqparent, const char * name )
+ : TQObject( tqparent, name )
+{
+ // nothing
+}
+
+
+TQDnsSocket::~TQDnsSocket()
+{
+ // nothing
+}
+
+
+void TQDnsSocket::cleanCache()
+{
+ // nothing
+}
+
+
+void TQDnsSocket::retransmit()
+{
+ // nothing
+}
+
+
+void TQDnsSocket::answer()
+{
+ // nothing
+}
+
+
+/*!
+ \class TQDns tqdns.h
+ \brief The TQDns class provides asynchronous DNS lookups.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module network
+ \ingroup io
+
+ Both Windows and Unix provide synchronous DNS lookups; Windows
+ provides some asynchronous support too. At the time of writing
+ neither operating system provides asynchronous support for
+ anything other than hostname-to-address mapping.
+
+ TQDns rectifies this shortcoming, by providing asynchronous caching
+ lookups for the record types that we expect modern GUI
+ applications to need in the near future.
+
+ The class is \e not straightforward to use (although it is much
+ simpler than the native APIs); TQSocket provides much easier to use
+ TCP connection facilities. The aim of TQDns is to provide a correct
+ and small API to the DNS and nothing more. (We use "correctness"
+ to mean that the DNS information is correctly cached, and
+ correctly timed out.)
+
+ The API comprises a constructor, functions to set the DNS node
+ (the domain in DNS terminology) and record type (setLabel() and
+ setRecordType()), the corresponding get functions, an isWorking()
+ function to determine whether TQDns is working or reading, a
+ resultsReady() signal and query functions for the result.
+
+ There is one query function for each RecordType, namely
+ addresses(), mailServers(), servers(), hostNames() and texts().
+ There are also two generic query functions: canonicalName()
+ returns the name you'll presumably end up using (the exact meaning
+ of this depends on the record type) and qualifiedNames() returns a
+ list of the fully qualified names label() maps to.
+
+ \sa TQSocket
+*/
+
+/*!
+ Constructs a DNS query object with invalid settings for both the
+ label and the search type.
+*/
+
+TQDns::TQDns()
+{
+ d = new TQDnsPrivate;
+ t = None;
+}
+
+
+
+
+/*!
+ Constructs a DNS query object that will return record type \a rr
+ information about \a label.
+
+ The DNS lookup is started the next time the application enters the
+ event loop. When the result is found the signal resultsReady() is
+ emitted.
+
+ \a rr defaults to \c A, IPv4 addresses.
+*/
+
+TQDns::TQDns( const TQString & label, RecordType rr )
+{
+ d = new TQDnsPrivate;
+ t = rr;
+ setLabel( label );
+ setStartQueryTimer(); // start query the next time we enter event loop
+}
+
+
+
+/*!
+ Constructs a DNS query object that will return record type \a rr
+ information about host address \a address. The label is set to the
+ IN-ADDR.ARPA domain name. This is useful in combination with the
+ \c Ptr record type (e.g. if you want to look up a hostname for a
+ given address).
+
+ The DNS lookup is started the next time the application enters the
+ event loop. When the result is found the signal resultsReady() is
+ emitted.
+
+ \a rr defaults to \c Ptr, that maps addresses to hostnames.
+*/
+
+TQDns::TQDns( const TQHostAddress & address, RecordType rr )
+{
+ d = new TQDnsPrivate;
+ t = rr;
+ setLabel( address );
+ setStartQueryTimer(); // start query the next time we enter event loop
+}
+
+
+
+
+/*!
+ Destroys the DNS query object and frees its allocated resources.
+*/
+
+TQDns::~TQDns()
+{
+ if ( globalManager ) {
+ uint q = 0;
+ TQDnsManager * m = globalManager;
+ while( q < m->queries.size() ) {
+ TQDnsQuery * query=m->queries[q];
+ if ( query && query->dns )
+ (void)query->dns->take( (void*) this );
+ q++;
+ }
+
+ }
+
+ delete d;
+ d = 0;
+}
+
+
+
+
+/*!
+ Sets this DNS query object to query for information about \a
+ label.
+
+ This does not change the recordType(), but its isWorking() status
+ will probably change as a result.
+
+ The DNS lookup is started the next time the application enters the
+ event loop. When the result is found the signal resultsReady() is
+ emitted.
+*/
+
+void TQDns::setLabel( const TQString & label )
+{
+ l = label;
+ d->noNames = FALSE;
+
+ // construct a list of qualified names
+ n.clear();
+ if ( l.length() > 1 && l[(int)l.length()-1] == '.' ) {
+ n.append( l.left( l.length()-1 ).lower() );
+ } else {
+ int i = l.length();
+ int dots = 0;
+ const int maxDots = 2;
+ while( i && dots < maxDots ) {
+ if ( l[--i] == '.' )
+ dots++;
+ }
+ if ( dots < maxDots ) {
+ (void)TQDnsManager::manager(); // create a TQDnsManager, if it is not already there
+ TQStrListIterator it( *domains );
+ const char * dom;
+ while( (dom=it.current()) != 0 ) {
+ ++it;
+ n.append( l.lower() + "." + dom );
+ }
+ }
+ n.append( l.lower() );
+ }
+
+#if defined(TQ_DNS_SYNCHRONOUS)
+ if ( d->noEventLoop ) {
+ doSynchronousLookup();
+ } else {
+ setStartQueryTimer(); // start query the next time we enter event loop
+ }
+#else
+ setStartQueryTimer(); // start query the next time we enter event loop
+#endif
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::setLabel: %d address(es) for %s", n.count(), l.ascii() );
+ int i = 0;
+ for( i = 0; i < (int)n.count(); i++ )
+ qDebug( "TQDns::setLabel: %d: %s", i, n[i].ascii() );
+#endif
+}
+
+
+/*!
+ \overload
+
+ Sets this DNS query object to query for information about the host
+ address \a address. The label is set to the IN-ADDR.ARPA domain
+ name. This is useful in combination with the \c Ptr record type
+ (e.g. if you want to look up a hostname for a given address).
+*/
+
+void TQDns::setLabel( const TQHostAddress & address )
+{
+ setLabel( toInAddrArpaDomain( address ) );
+}
+
+
+/*!
+ \fn TQStringList TQDns::qualifiedNames() const
+
+ Returns a list of the fully qualified names label() maps to.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myDns.qualifiedNames();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+*/
+
+
+/*!
+ \fn TQString TQDns::label() const
+
+ Returns the domain name for which this object returns information.
+
+ \sa setLabel()
+*/
+
+/*!
+ \enum TQDns::RecordType
+
+ This enum type defines the record types TQDns can handle. The DNS
+ provides many more; these are the ones we've judged to be in
+ current use, useful for GUI programs and important enough to
+ support right away:
+
+ \value None No information. This exists only so that TQDns can
+ have a default.
+
+ \value A IPv4 addresses. By far the most common type.
+
+ \value Aaaa IPv6 addresses. So far mostly unused.
+
+ \value Mx Mail eXchanger names. Used for mail delivery.
+
+ \value Srv SeRVer names. Generic record type for tqfinding
+ servers. So far mostly unused.
+
+ \value Cname Canonical names. Maps from nicknames to the true
+ name (the canonical name) for a host.
+
+ \value Ptr name PoinTeRs. Maps from IPv4 or IPv6 addresses to hostnames.
+
+ \value Txt arbitrary TeXT for domains.
+
+ We expect that some support for the
+ \link http://www.dns.net/dnsrd/rfc/rfc2535.html RFC-2535 \endlink
+ extensions will be added in future versions.
+*/
+
+/*!
+ Sets this object to query for record type \a rr records.
+
+ The DNS lookup is started the next time the application enters the
+ event loop. When the result is found the signal resultsReady() is
+ emitted.
+
+ \sa RecordType
+*/
+
+void TQDns::setRecordType( RecordType rr )
+{
+ t = rr;
+ d->noNames = FALSE;
+ setStartQueryTimer(); // start query the next time we enter event loop
+}
+
+/*!
+ \internal
+
+ Private slot for starting the query.
+*/
+void TQDns::startQuery()
+{
+ // isWorking() starts the query (if necessary)
+ if ( !isWorking() )
+ emit resultsReady();
+}
+
+/*!
+ The three functions TQDns::TQDns(TQString, RecordType),
+ TQDns::setLabel() and TQDns::setRecordType() may start a DNS lookup.
+ This function handles setting up the single shot timer.
+*/
+void TQDns::setStartQueryTimer()
+{
+#if defined(TQ_DNS_SYNCHRONOUS)
+ if ( !d->queryTimer && !d->noEventLoop )
+#else
+ if ( !d->queryTimer )
+#endif
+ {
+ // start the query the next time we enter event loop
+ d->queryTimer = new TQTimer( this );
+ connect( d->queryTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(startQuery()) );
+ d->queryTimer->start( 0, TRUE );
+ }
+}
+
+/*
+ Transforms the host address \a address to the IN-ADDR.ARPA domain
+ name. Returns something indeterminate if you're sloppy or
+ naughty. This function has an IPv4-specific name, but works for
+ IPv6 too.
+*/
+TQString TQDns::toInAddrArpaDomain( const TQHostAddress &address )
+{
+ TQString s;
+ if ( address.isNull() ) {
+ // if the address isn't valid, neither of the other two make
+ // cases make sense. better to just return.
+ } else if ( address.isIp4Addr() ) {
+ TQ_UINT32 i = address.ip4Addr();
+ s.sprintf( "%d.%d.%d.%d.IN-ADDR.ARPA",
+ i & 0xff, (i >> 8) & 0xff, (i>>16) & 0xff, (i>>24) & 0xff );
+ } else {
+ // RFC 3152. (1886 is deprecated, and clients no longer need to
+ // support it, in practice).
+ TQ_IPV6ADDR i = address.toIPv6Address();
+ s = "ip6.arpa";
+ uint b = 0;
+ while( b < 16 ) {
+ s = TQString::number( i.c[b]%16, 16 ) + "." +
+ TQString::number( i.c[b]/16, 16 ) + "." + s;
+ b++;
+ }
+ }
+ return s;
+}
+
+
+/*!
+ \fn TQDns::RecordType TQDns::recordType() const
+
+ Returns the record type of this DNS query object.
+
+ \sa setRecordType() RecordType
+*/
+
+/*!
+ \fn void TQDns::resultsReady()
+
+ This signal is emitted when results are available for one of the
+ qualifiedNames().
+*/
+
+/*!
+ Returns TRUE if TQDns is doing a lookup for this object (i.e. if it
+ does not already have the necessary information); otherwise
+ returns FALSE.
+
+ TQDns emits the resultsReady() signal when the status changes to FALSE.
+*/
+
+bool TQDns::isWorking() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::isWorking (%s, %d)", l.ascii(), t );
+#endif
+ if ( t == None )
+ return FALSE;
+
+#if defined(TQ_DNS_SYNCHRONOUS)
+ if ( d->noEventLoop )
+ return TRUE;
+#endif
+
+ TQPtrList<TQDnsRR> * ll = TQDnsDomain::cached( this );
+ TQ_LONG queries = n.count();
+ while( ll->current() != 0 ) {
+ if ( ll->current()->nxdomain ) {
+ queries--;
+ } else {
+ delete ll;
+ return FALSE;
+ }
+ ll->next();
+ }
+ delete ll;
+
+ if ( queries <= 0 )
+ return FALSE;
+ if ( d->noNames )
+ return FALSE;
+ return TRUE;
+}
+
+
+/*!
+ Returns a list of the addresses for this name if this TQDns object
+ has a recordType() of \c TQDns::A or \c TQDns::Aaaa and the answer
+ is available; otherwise returns an empty list.
+
+ As a special case, if label() is a valid numeric IP address, this
+ function returns that address.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQHostAddress> list = myDns.addresses();
+ TQValueList<TQHostAddress>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+*/
+
+TQValueList<TQHostAddress> TQDns::addresses() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::addresses (%s)", l.ascii() );
+#endif
+ TQValueList<TQHostAddress> result;
+ if ( t != A && t != Aaaa )
+ return result;
+
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain )
+ result.append( rr->address );
+ cached->next();
+ }
+ delete cached;
+ return result;
+}
+
+
+/*!
+ \class TQDns::MailServer
+ \brief The TQDns::MailServer class is described in TQDns::mailServers().
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+
+ \internal
+*/
+
+/*!
+ Returns a list of mail servers if the record type is \c Mx. The
+ class \c TQDns::MailServer tqcontains the following public variables:
+ \list
+ \i TQString TQDns::MailServer::name
+ \i TQ_UINT16 TQDns::MailServer::priority
+ \endlist
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQDns::MailServer> list = myDns.mailServers();
+ TQValueList<TQDns::MailServer>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+*/
+TQValueList<TQDns::MailServer> TQDns::mailServers() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::mailServers (%s)", l.ascii() );
+#endif
+ TQValueList<TQDns::MailServer> result;
+ if ( t != Mx )
+ return result;
+
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain ) {
+ MailServer ms( rr->target, rr->priority );
+ result.append( ms );
+ }
+ cached->next();
+ }
+ delete cached;
+ return result;
+}
+
+
+/*!
+ \class TQDns::Server
+ \brief The TQDns::Server class is described in TQDns::servers().
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+
+ \internal
+*/
+
+/*!
+ Returns a list of servers if the record type is \c Srv. The class
+ \c TQDns::Server tqcontains the following public variables:
+ \list
+ \i TQString TQDns::Server::name
+ \i TQ_UINT16 TQDns::Server::priority
+ \i TQ_UINT16 TQDns::Server::weight
+ \i TQ_UINT16 TQDns::Server::port
+ \endlist
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<TQDns::Server> list = myDns.servers();
+ TQValueList<TQDns::Server>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQValueList<TQDns::Server> TQDns::servers() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::servers (%s)", l.ascii() );
+#endif
+ TQValueList<TQDns::Server> result;
+ if ( t != Srv )
+ return result;
+
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain ) {
+ Server s( rr->target, rr->priority, rr->weight, rr->port );
+ result.append( s );
+ }
+ cached->next();
+ }
+ delete cached;
+ return result;
+}
+
+
+/*!
+ Returns a list of host names if the record type is \c Ptr.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myDns.hostNames();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+*/
+TQStringList TQDns::hostNames() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::hostNames (%s)", l.ascii() );
+#endif
+ TQStringList result;
+ if ( t != Ptr )
+ return result;
+
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain ) {
+ TQString str( rr->target );
+ result.append( str );
+ }
+ cached->next();
+ }
+ delete cached;
+ return result;
+}
+
+
+/*!
+ Returns a list of texts if the record type is \c Txt.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myDns.texts();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQStringList TQDns::texts() const
+{
+#if defined(TQDNS_DEBUG)
+ qDebug( "TQDns::texts (%s)", l.ascii() );
+#endif
+ TQStringList result;
+ if ( t != Txt )
+ return result;
+
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( this );
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain ) {
+ TQString str( rr->text );
+ result.append( str );
+ }
+ cached->next();
+ }
+ delete cached;
+ return result;
+}
+
+
+/*!
+ Returns the canonical name for this DNS node. (This works
+ regardless of what recordType() is set to.)
+
+ If the canonical name isn't known, this function returns a null
+ string.
+
+ The canonical name of a DNS node is its full name, or the full
+ name of the target of its CNAME. For example, if l.trolltech.com
+ is a CNAME to lillian.troll.no, and the search path for TQDns is
+ "trolltech.com", then the canonical name for all of "lillian",
+ "l", "lillian.troll.no." and "l.trolltech.com" is
+ "lillian.troll.no.".
+*/
+
+TQString TQDns::canonicalName() const
+{
+ // the cname should work regardless of the recordType(), so set the record
+ // type temporarily to cname when you look at the cache
+ TQDns *that = (TQDns*) this; // mutable function
+ RecordType oldType = t;
+ that->t = Cname;
+ TQPtrList<TQDnsRR> * cached = TQDnsDomain::cached( that );
+ that->t = oldType;
+
+ TQDnsRR * rr;
+ while( (rr=cached->current()) != 0 ) {
+ if ( rr->current && !rr->nxdomain && rr->domain ) {
+ delete cached;
+ return rr->target;
+ }
+ cached->next();
+ }
+ delete cached;
+ return TQString::null;
+}
+
+#if defined(TQ_DNS_SYNCHRONOUS)
+/*! \reimp
+*/
+void TQDns::connectNotify( const char *signal )
+{
+ if ( d->noEventLoop && qstrcmp(signal,TQT_SIGNAL(resultsReady()) )==0 ) {
+ doSynchronousLookup();
+ }
+}
+#endif
+
+#if defined(TQ_OS_WIN32) || defined(TQ_OS_CYGWIN)
+
+#if defined(TQ_DNS_SYNCHRONOUS)
+void TQDns::doSynchronousLookup()
+{
+ // ### not implemented yet
+}
+#endif
+
+// the following typedefs are needed for GetNetworkParams() API call
+#ifndef IP_TYPES_INCLUDED
+#define MAX_HOSTNAME_LEN 128
+#define MAX_DOMAIN_NAME_LEN 128
+#define MAX_SCOPE_ID_LEN 256
+typedef struct {
+ char String[4 * 4];
+} IP_ADDRESS_STRING, *PIP_ADDRESS_STRING, IP_MASK_STRING, *PIP_MASK_STRING;
+typedef struct _IP_ADDR_STRING {
+ struct _IP_ADDR_STRING* Next;
+ IP_ADDRESS_STRING IpAddress;
+ IP_MASK_STRING IpMask;
+ DWORD Context;
+} IP_ADDR_STRING, *PIP_ADDR_STRING;
+typedef struct {
+ char HostName[MAX_HOSTNAME_LEN + 4] ;
+ char DomainName[MAX_DOMAIN_NAME_LEN + 4];
+ PIP_ADDR_STRING CurrentDnsServer;
+ IP_ADDR_STRING DnsServerList;
+ UINT NodeType;
+ char ScopeId[MAX_SCOPE_ID_LEN + 4];
+ UINT EnableRouting;
+ UINT EnableProxy;
+ UINT EnableDns;
+} FIXED_INFO, *PFIXED_INFO;
+#endif
+typedef DWORD (WINAPI *GNP)( PFIXED_INFO, PULONG );
+
+// ### FIXME: this code is duplicated in qfiledialog.cpp
+static TQString getWindowsRegString( HKEY key, const TQString &subKey )
+{
+ TQString s;
+ TQT_WA( {
+ char buf[1024];
+ DWORD bsz = sizeof(buf);
+ int r = RegQueryValueEx( key, (TCHAR*)subKey.ucs2(), 0, 0, (LPBYTE)buf, &bsz );
+ if ( r == ERROR_SUCCESS ) {
+ s = TQString::fromUcs2( (unsigned short *)buf );
+ } else if ( r == ERROR_MORE_DATA ) {
+ char *ptr = new char[bsz+1];
+ r = RegQueryValueEx( key, (TCHAR*)subKey.ucs2(), 0, 0, (LPBYTE)ptr, &bsz );
+ if ( r == ERROR_SUCCESS )
+ s = ptr;
+ delete [] ptr;
+ }
+ } , {
+ char buf[512];
+ DWORD bsz = sizeof(buf);
+ int r = RegQueryValueExA( key, subKey.local8Bit(), 0, 0, (LPBYTE)buf, &bsz );
+ if ( r == ERROR_SUCCESS ) {
+ s = buf;
+ } else if ( r == ERROR_MORE_DATA ) {
+ char *ptr = new char[bsz+1];
+ r = RegQueryValueExA( key, subKey.local8Bit(), 0, 0, (LPBYTE)ptr, &bsz );
+ if ( r == ERROR_SUCCESS )
+ s = ptr;
+ delete [] ptr;
+ }
+ } );
+ return s;
+}
+
+static bool getDnsParamsFromRegistry( const TQString &path,
+ TQString *domainName, TQString *nameServer, TQString *searchList )
+{
+ HKEY k;
+ int r;
+ TQT_WA( {
+ r = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
+ (TCHAR*)path.ucs2(),
+ 0, KEY_READ, &k );
+ } , {
+ r = RegOpenKeyExA( HKEY_LOCAL_MACHINE,
+ path,
+ 0, KEY_READ, &k );
+ } );
+
+ if ( r == ERROR_SUCCESS ) {
+ *domainName = getWindowsRegString( k, "DhcpDomain" );
+ if ( domainName->isEmpty() )
+ *domainName = getWindowsRegString( k, "Domain" );
+
+ *nameServer = getWindowsRegString( k, "DhcpNameServer" );
+ if ( nameServer->isEmpty() )
+ *nameServer = getWindowsRegString( k, "NameServer" );
+
+ *searchList = getWindowsRegString( k, "SearchList" );
+ }
+ RegCloseKey( k );
+ return r == ERROR_SUCCESS;
+}
+
+void TQDns::doResInit()
+{
+ char separator = 0;
+
+ if ( ns )
+ delete ns;
+ ns = new TQPtrList<TQHostAddress>;
+ ns->setAutoDelete( TRUE );
+ domains = new TQStrList( TRUE );
+ domains->setAutoDelete( TRUE );
+
+ TQString domainName, nameServer, searchList;
+
+ bool gotNetworkParams = FALSE;
+ // try the API call GetNetworkParams() first and use registry lookup only
+ // as a fallback
+#ifdef TQ_OS_TEMP
+ HINSTANCE hinstLib = LoadLibraryW( L"iphlpapi" );
+#else
+ HINSTANCE hinstLib = LoadLibraryA( "iphlpapi" );
+#endif
+ if ( hinstLib != 0 ) {
+#ifdef TQ_OS_TEMP
+ GNP getNetworkParams = (GNP) GetProcAddressW( hinstLib, L"GetNetworkParams" );
+#else
+ GNP getNetworkParams = (GNP) GetProcAddress( hinstLib, "GetNetworkParams" );
+#endif
+ if ( getNetworkParams != 0 ) {
+ ULONG l = 0;
+ DWORD res;
+ res = getNetworkParams( 0, &l );
+ if ( res == ERROR_BUFFER_OVERFLOW ) {
+ FIXED_INFO *finfo = (FIXED_INFO*)new char[l];
+ res = getNetworkParams( finfo, &l );
+ if ( res == ERROR_SUCCESS ) {
+ domainName = finfo->DomainName;
+ nameServer = "";
+ IP_ADDR_STRING *dnsServer = &finfo->DnsServerList;
+ while ( dnsServer != 0 ) {
+ nameServer += dnsServer->IpAddress.String;
+ dnsServer = dnsServer->Next;
+ if ( dnsServer != 0 )
+ nameServer += " ";
+ }
+ searchList = "";
+ separator = ' ';
+ gotNetworkParams = TRUE;
+ }
+ delete[] finfo;
+ }
+ }
+ FreeLibrary( hinstLib );
+ }
+ if ( !gotNetworkParams ) {
+ if ( getDnsParamsFromRegistry(
+ TQString( "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" ),
+ &domainName, &nameServer, &searchList )) {
+ // for NT
+ separator = ' ';
+ } else if ( getDnsParamsFromRegistry(
+ TQString( "System\\CurrentControlSet\\Services\\VxD\\MSTCP" ),
+ &domainName, &nameServer, &searchList )) {
+ // for 95/98
+ separator = ',';
+ } else {
+ // Could not access the TCP/IP parameters
+ domainName = "";
+ nameServer = "127.0.0.1";
+ searchList = "";
+ separator = ' ';
+ }
+ }
+
+ nameServer = nameServer.simplifyWhiteSpace();
+ int first, last;
+ if ( !nameServer.isEmpty() ) {
+ first = 0;
+ do {
+ last = nameServer.tqfind( separator, first );
+ if ( last < 0 )
+ last = nameServer.length();
+ TQDns tmp( nameServer.mid( first, last-first ), TQDns::A );
+ TQValueList<TQHostAddress> address = tmp.addresses();
+ TQ_LONG i = address.count();
+ while( i )
+ ns->append( new TQHostAddress(address[--i]) );
+ first = last+1;
+ } while( first < (int)nameServer.length() );
+ }
+
+ searchList = searchList + " " + domainName;
+ searchList = searchList.simplifyWhiteSpace().lower();
+ first = 0;
+ do {
+ last = searchList.tqfind( separator, first );
+ if ( last < 0 )
+ last = searchList.length();
+ domains->append( qstrdup( searchList.mid( first, last-first ) ) );
+ first = last+1;
+ } while( first < (int)searchList.length() );
+}
+
+#elif defined(TQ_OS_UNIX)
+
+#if defined(TQ_DNS_SYNCHRONOUS)
+void TQDns::doSynchronousLookup()
+{
+ if ( t!=None && !l.isEmpty() ) {
+ TQValueListIterator<TQString> it = n.begin();
+ TQValueListIterator<TQString> end = n.end();
+ int type;
+ switch( t ) {
+ case TQDns::A:
+ type = 1;
+ break;
+ case TQDns::Aaaa:
+ type = 28;
+ break;
+ case TQDns::Mx:
+ type = 15;
+ break;
+ case TQDns::Srv:
+ type = 33;
+ break;
+ case TQDns::Cname:
+ type = 5;
+ break;
+ case TQDns::Ptr:
+ type = 12;
+ break;
+ case TQDns::Txt:
+ type = 16;
+ break;
+ default:
+ type = (char)255; // any
+ break;
+ }
+ while( it != end ) {
+ TQString s = *it;
+ it++;
+ TQByteArray ba( 512 );
+ int len = res_search( s.latin1(), 1, type, (uchar*)ba.data(), ba.size() );
+ if ( len > 0 ) {
+ ba.resize( len );
+
+ TQDnsQuery * query = new TQDnsQuery;
+ query->started = now();
+ query->id = ++::id;
+ query->t = t;
+ query->l = s;
+ TQDnsAnswer a( ba, query );
+ a.parse();
+ } else if ( len == -1 ) {
+ // res_search error
+ }
+ }
+ emit resultsReady();
+ }
+}
+#endif
+
+#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 3)))
+#define TQ_MODERN_RES_API
+#else
+#endif
+
+void TQDns::doResInit()
+{
+ if ( ns )
+ return;
+ ns = new TQPtrList<TQHostAddress>;
+ ns->setAutoDelete( TRUE );
+ domains = new TQStrList( TRUE );
+ domains->setAutoDelete( TRUE );
+
+ // read resolv.conf manually.
+ TQFile resolvConf("/etc/resolv.conf");
+ if (resolvConf.open(IO_ReadOnly)) {
+ TQTextStream stream( &resolvConf );
+ TQString line;
+
+ while ( !stream.atEnd() ) {
+ line = stream.readLine();
+ TQStringList list = TQStringList::split( " ", line );
+ if ( line.startsWith( "#" ) || list.count() < 2 )
+ continue;
+ const TQString type = list[0].lower();
+
+ if ( type == "nameserver" ) {
+ TQHostAddress *address = new TQHostAddress();
+ if ( address->setAddress( TQString(list[1]) ) ) {
+ // only add ipv6 addresses from resolv.conf if
+ // this host supports ipv6.
+ if ( address->isIPv4Address() || ipv6support )
+ ns->append( address );
+ else
+ delete address;
+ } else {
+ delete address;
+ }
+ } else if ( type == "search" ) {
+ TQStringList srch = TQStringList::split( " ", list[1] );
+ for ( TQStringList::Iterator i = srch.begin(); i != srch.end(); ++i )
+ domains->append( (*i).lower() );
+
+ } else if ( type == "domain" ) {
+ domains->append( list[1].lower() );
+ }
+ }
+ }
+
+ if (ns->isEmpty()) {
+#if defined(TQ_MODERN_RES_API)
+ struct __res_state res;
+ res_ninit( &res );
+ int i;
+ // tqfind the name servers to use
+ for( i=0; i < MAXNS && i < res.nscount; i++ )
+ ns->append( new TQHostAddress( ntohl( res.nsaddr_list[i].sin_addr.s_addr ) ) );
+# if defined(MAXDFLSRCH)
+ for( i=0; i < MAXDFLSRCH; i++ ) {
+ if ( res.dnsrch[i] && *(res.dnsrch[i]) )
+ domains->append( TQString::tqfromLatin1( res.dnsrch[i] ).lower() );
+ else
+ break;
+ }
+# endif
+ if ( *res.defdname )
+ domains->append( TQString::tqfromLatin1( res.defdname ).lower() );
+#else
+ qdns_res_init();
+ int i;
+ // tqfind the name servers to use
+ for( i=0; i < MAXNS && i < _res.nscount; i++ )
+ ns->append( new TQHostAddress( ntohl( _res.nsaddr_list[i].sin_addr.s_addr ) ) );
+# if defined(MAXDFLSRCH)
+ for( i=0; i < MAXDFLSRCH; i++ ) {
+ if ( _res.dnsrch[i] && *(_res.dnsrch[i]) )
+ domains->append( TQString::tqfromLatin1( _res.dnsrch[i] ).lower() );
+ else
+ break;
+ }
+# endif
+ if ( *_res.defdname )
+ domains->append( TQString::tqfromLatin1( _res.defdname ).lower() );
+#endif
+
+ // the code above adds "0.0.0.0" as a name server at the slightest
+ // hint of trouble. so remove those again.
+ ns->first();
+ while( ns->current() ) {
+ if ( ns->current()->isNull() )
+ delete ns->take();
+ else
+ ns->next();
+ }
+ }
+
+ TQFile hosts( TQString::tqfromLatin1( "/etc/hosts" ) );
+ if ( hosts.open( IO_ReadOnly ) ) {
+ // read the /etc/hosts file, creating long-life A and PTR RRs
+ // for the things we tqfind.
+ TQTextStream i( &hosts );
+ TQString line;
+ while( !i.atEnd() ) {
+ line = i.readLine().simplifyWhiteSpace().lower();
+ uint n = 0;
+ while( n < line.length() && line[(int)n] != '#' )
+ n++;
+ line.truncate( n );
+ n = 0;
+ while( n < line.length() && !line[(int)n].isSpace() )
+ n++;
+ TQString ip = line.left( n );
+ TQHostAddress a;
+ a.setAddress( ip );
+ if ( ( a.isIPv4Address() || a.isIPv6Address() ) && !a.isNull() ) {
+ bool first = TRUE;
+ line = line.mid( n+1 );
+ n = 0;
+ while( n < line.length() && !line[(int)n].isSpace() )
+ n++;
+ TQString hostname = line.left( n );
+ // ### in case of bad syntax, hostname is invalid. do we care?
+ if ( n ) {
+ TQDnsRR * rr = new TQDnsRR( hostname );
+ if ( a.isIPv4Address() )
+ rr->t = TQDns::A;
+ else
+ rr->t = TQDns::Aaaa;
+ rr->address = a;
+ rr->deleteTime = UINT_MAX;
+ rr->expireTime = UINT_MAX;
+ rr->current = TRUE;
+ if ( first ) {
+ first = FALSE;
+ TQDnsRR * ptr = new TQDnsRR( TQDns::toInAddrArpaDomain( a ) );
+ ptr->t = TQDns::Ptr;
+ ptr->target = hostname;
+ ptr->deleteTime = UINT_MAX;
+ ptr->expireTime = UINT_MAX;
+ ptr->current = TRUE;
+ }
+ }
+ }
+ }
+ }
+}
+
+#endif
+
+#endif // TQT_NO_DNS
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/network/tqdns.h b/tqtinterface/qt4/src/network/tqdns.h
new file mode 100644
index 0000000..14a5e65
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqdns.h
@@ -0,0 +1,382 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TQDNS_H
+#define TQDNS_H
+
+#include <Qt/qobject.h>
+#include <Qt/qhostaddress.h>
+#include <Qt/qsocketnotifier.h>
+#include <tqstringlist.h>
+#include <tqvaluelist.h>
+
+#include "tqtimer.h"
+#include "tqobject.h"
+#include "tqhostaddress.h"
+#include "tqsocketnotifier.h"
+
+#define TQLatin1String TQString
+#define TQLatin1Char TQChar
+
+typedef qint8 Q_INT8;
+typedef quint8 Q_UINT8;
+typedef qint16 Q_INT16;
+typedef quint16 Q_UINT16;
+typedef qint32 Q_INT32;
+typedef quint32 Q_UINT32;
+typedef qint64 Q_INT64;
+typedef quint64 Q_UINT64;
+typedef qint64 Q_LLONG;
+typedef quint64 Q_ULLONG;
+#if defined(Q_OS_WIN64)
+typedef __int64 Q_LONG; /* word up to 64 bit signed */
+typedef unsigned __int64 Q_ULONG; /* word up to 64 bit unsigned */
+#else
+typedef long Q_LONG; /* word up to 64 bit signed */
+typedef unsigned long Q_ULONG; /* word up to 64 bit unsigned */
+#endif
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3Support)
+
+#ifndef QT_NO_DNS
+
+//#define Q_DNS_SYNCHRONOUS
+
+class TQDnsPrivate;
+
+class Q_COMPAT_EXPORT TQDns: public TQObject {
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ enum RecordType {
+ None,
+ A, Aaaa,
+ Mx, Srv,
+ Cname,
+ Ptr,
+ Txt
+ };
+
+ TQDns();
+ TQDns( const TQString & label, RecordType rr = A );
+ TQDns( const TQHostAddress & address, RecordType rr = Ptr );
+ virtual ~TQDns();
+
+ // to set/change the query
+ virtual void setLabel( const TQString & label );
+ virtual void setLabel( const TQHostAddress & address );
+ TQString label() const { return l; }
+
+ virtual void setRecordType( RecordType rr = A );
+ RecordType recordType() const { return t; }
+
+ // whether something is happening behind the scenes
+ bool isWorking() const;
+
+ // to query for replies
+ TQValueList<TQHostAddress> addresses() const;
+
+ class Q_COMPAT_EXPORT MailServer {
+ public:
+ MailServer( const TQString & n=TQString(), Q_UINT16 p=0 )
+ :name(n), priority(p) {}
+ TQString name;
+ Q_UINT16 priority;
+ Q_DUMMY_COMPARISON_OPERATOR(MailServer)
+ };
+ TQValueList<MailServer> mailServers() const;
+
+ class Q_COMPAT_EXPORT Server {
+ public:
+ Server(const TQString & n=TQString(), Q_UINT16 p=0, Q_UINT16 w=0, Q_UINT16 po=0 )
+ : name(n), priority(p), weight(w), port(po) {}
+ TQString name;
+ Q_UINT16 priority;
+ Q_UINT16 weight;
+ Q_UINT16 port;
+ Q_DUMMY_COMPARISON_OPERATOR(Server)
+ };
+ TQValueList<Server> servers() const;
+
+ TQStringList hostNames() const;
+
+ TQStringList texts() const;
+
+ TQString canonicalName() const; // ### real-world but uncommon: TQStringList
+
+ TQStringList qualifiedNames() const { return n; }
+
+#if defined(Q_DNS_SYNCHRONOUS)
+protected:
+ void connectNotify( const char *signal );
+#endif
+
+Q_SIGNALS:
+ void resultsReady();
+
+private Q_SLOTS:
+ void startQuery();
+
+private:
+ static void doResInit();
+ void setStartQueryTimer();
+ static TQString toInAddrArpaDomain( const TQHostAddress &address );
+#if defined(Q_DNS_SYNCHRONOUS)
+ void doSynchronousLookup();
+#endif
+
+ TQString l;
+ TQStringList n;
+ RecordType t;
+ TQDnsPrivate * d;
+
+ friend class TQDnsAnswer;
+ friend class TQDnsManager;
+};
+
+
+// TQDnsSocket are sockets that are used for DNS lookup
+
+class TQDnsSocket: public TQObject {
+ Q_OBJECT
+ // note: Private not public. This class contains NO public API.
+protected:
+ TQDnsSocket( TQT_BASE_OBJECT_NAME *, const char * );
+ virtual ~TQDnsSocket();
+
+private Q_SLOTS:
+ virtual void cleanCache();
+ virtual void retransmit();
+ virtual void answer();
+};
+
+#endif // QT_NO_DNS
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // TQDNS_H
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Definition of TQDns class.
+**
+** Created : 991122
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDNS_H
+#define TQDNS_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqhostaddress.h"
+#include "tqsocketnotifier.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
+#define TQM_EXPORT_DNS
+#else
+#define TQM_EXPORT_DNS TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_DNS
+
+//#define TQ_DNS_SYNCHRONOUS
+
+class TQDnsPrivate;
+
+class TQM_EXPORT_DNS TQDns: public TQObject {
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ enum RecordType {
+ None,
+ A, Aaaa,
+ Mx, Srv,
+ Cname,
+ Ptr,
+ Txt
+ };
+
+ TQDns();
+ TQDns( const TQString & label, RecordType rr = A );
+ TQDns( const TQHostAddress & address, RecordType rr = Ptr );
+ virtual ~TQDns();
+
+ // to set/change the query
+ virtual void setLabel( const TQString & label );
+ virtual void setLabel( const TQHostAddress & address );
+ TQString label() const { return l; }
+
+ virtual void setRecordType( RecordType rr = A );
+ RecordType recordType() const { return t; }
+
+ // whether something is happening behind the scenes
+ bool isWorking() const;
+
+ // to query for replies
+ TQValueList<TQHostAddress> addresses() const;
+
+ class TQM_EXPORT_DNS MailServer {
+ public:
+ MailServer( const TQString & n=TQString::null, TQ_UINT16 p=0 )
+ :name(n), priority(p) {}
+ TQString name;
+ TQ_UINT16 priority;
+ TQ_DUMMY_COMPARISON_OPERATOR(MailServer)
+ };
+ TQValueList<MailServer> mailServers() const;
+
+ class TQM_EXPORT_DNS Server {
+ public:
+ Server(const TQString & n=TQString::null, TQ_UINT16 p=0, TQ_UINT16 w=0, TQ_UINT16 po=0 )
+ : name(n), priority(p), weight(w), port(po) {}
+ TQString name;
+ TQ_UINT16 priority;
+ TQ_UINT16 weight;
+ TQ_UINT16 port;
+ TQ_DUMMY_COMPARISON_OPERATOR(Server)
+ };
+ TQValueList<Server> servers() const;
+
+ TQStringList hostNames() const;
+
+ TQStringList texts() const;
+
+ TQString canonicalName() const; // ### real-world but uncommon: TQStringList
+
+ TQStringList qualifiedNames() const { return n; }
+
+#if defined(TQ_DNS_SYNCHRONOUS)
+protected:
+ void connectNotify( const char *signal );
+#endif
+
+Q_SIGNALS:
+ void resultsReady();
+
+private Q_SLOTS:
+ void startQuery();
+
+private:
+ static void doResInit();
+ void setStartQueryTimer();
+ static TQString toInAddrArpaDomain( const TQHostAddress &address );
+#if defined(TQ_DNS_SYNCHRONOUS)
+ void doSynchronousLookup();
+#endif
+
+ TQString l;
+ TQStringList n;
+ RecordType t;
+ TQDnsPrivate * d;
+
+ friend class TQDnsAnswer;
+ friend class TQDnsManager;
+};
+
+
+// TQDnsSocket are sockets that are used for DNS lookup
+
+class TQDnsSocket: public TQObject {
+ Q_OBJECT
+ TQ_OBJECT
+ // note: Private not public. This class tqcontains NO public API.
+protected:
+ TQDnsSocket( TQObject *, const char * );
+ virtual ~TQDnsSocket();
+
+private Q_SLOTS:
+ virtual void cleanCache();
+ virtual void retransmit();
+ virtual void answer();
+};
+
+#endif // TQT_NO_DNS
+
+#endif // TQDNS_H
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/network/tqftp.cpp b/tqtinterface/qt4/src/network/tqftp.cpp
new file mode 100644
index 0000000..7fb239e
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqftp.cpp
@@ -0,0 +1,2421 @@
+/****************************************************************************
+**
+** Implementation of TQFtp class.
+**
+** Created : 970521
+**
+** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqftp.h"
+
+#ifndef TQT_NO_NETWORKPROTOCOL_FTP
+
+#include "tqsocket.h"
+#include "tqsocketdevice.h"
+#include "tqurlinfo.h"
+#include "tqurloperator.h"
+#include "tqstringlist.h"
+#include "tqregexp.h"
+#include "tqtimer.h"
+#include "tqfileinfo.h"
+#include "tqptrdict.h" // binary compatibility
+
+#ifndef TQT_NO_TEXTCODEC
+#include "tqtextcodec.h"
+#endif
+
+//#define TQFTPPI_DEBUG
+//#define TQFTPDTP_DEBUG
+
+
+class TQFtpPI;
+
+class TQFtpDTP : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ enum ConnectState {
+ CsHostFound,
+ CsConnected,
+ CsClosed,
+ CsHostNotFound,
+ CsConnectionRefused
+ };
+
+ TQFtpDTP( TQFtpPI *p, TQObject *tqparent=0, const char *name=0 );
+
+ void setData( TQByteArray * );
+ void setDevice( TQIODevice * );
+ void writeData();
+
+ void setBytesTotal( int bytes )
+ {
+ bytesTotal = bytes;
+ bytesDone = 0;
+ emit dataTransferProgress( bytesDone, bytesTotal );
+ }
+
+ bool hasError() const;
+ TQString errorMessage() const;
+ void clearError();
+
+ void connectToHost( const TQString & host, TQ_UINT16 port )
+ { socket.connectToHost( host, port ); }
+
+ TQSocket::State socketState() const
+ { return socket.state(); }
+
+ TQ_ULONG bytesAvailable() const
+ { return socket.bytesAvailable(); }
+
+ TQ_LONG readBlock( char *data, TQ_ULONG maxlen )
+ {
+ TQ_LONG read = socket.readBlock( data, maxlen );
+ bytesDone += read;
+ return read;
+ }
+
+ TQByteArray readAll()
+ {
+ TQByteArray tmp = TQT_TQBYTEARRAY_OBJECT(socket.readAll());
+ bytesDone += tmp.size();
+ return tmp;
+ }
+
+ void abortConnection();
+
+ static bool parseDir( const TQString &buffer, const TQString &userName, TQUrlInfo *info );
+
+Q_SIGNALS:
+ void listInfo( const TQUrlInfo& );
+ void readyRead();
+ void dataTransferProgress( int, int );
+
+ void connectState( int );
+
+private Q_SLOTS:
+ void socketConnected();
+ void socketReadyRead();
+ void socketError( int );
+ void socketConnectionClosed();
+ void socketBytesWritten( int );
+
+private:
+ void clearData()
+ {
+ is_ba = FALSE;
+ data.dev = 0;
+ }
+
+ TQSocket socket;
+ TQFtpPI *pi;
+ TQString err;
+ int bytesDone;
+ int bytesTotal;
+ bool callWriteData;
+
+ // If is_ba is TRUE, ba is used; ba is never 0.
+ // Otherwise dev is used; dev can be 0 or not.
+ union {
+ TQByteArray *ba;
+ TQIODevice *dev;
+ } data;
+ bool is_ba;
+};
+
+class TQFtpPI : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQFtpPI( TQObject *tqparent = 0 );
+
+ void connectToHost( const TQString &host, TQ_UINT16 port );
+
+ bool sendCommands( const TQStringList &cmds );
+ bool sendCommand( const TQString &cmd )
+ { return sendCommands( TQStringList( cmd ) ); }
+
+ void clearPendingCommands();
+ void abort();
+
+ TQString currentCommand() const
+ { return currentCmd; }
+
+ bool rawCommand;
+
+ TQFtpDTP dtp; // the PI has a DTP which is not the design of RFC 959, but it
+ // makes the design simpler this way
+Q_SIGNALS:
+ void connectState( int );
+ void finished( const TQString& );
+ void error( int, const TQString& );
+ void rawFtpReply( int, const TQString& );
+
+private Q_SLOTS:
+ void hostFound();
+ void connected();
+ void connectionClosed();
+ void delayedCloseFinished();
+ void readyRead();
+ void error( int );
+
+ void dtpConnectState( int );
+
+private:
+ // the states are modelled after the generalized state diagram of RFC 959,
+ // page 58
+ enum State {
+ Begin,
+ Idle,
+ Waiting,
+ Success,
+ Failure
+ };
+
+ enum AbortState {
+ None,
+ AbortStarted,
+ WaitForAbortToFinish
+ };
+
+ bool processReply();
+ bool startNextCmd();
+
+ TQSocket commandSocket;
+ TQString replyText;
+ char replyCode[3];
+ State state;
+ AbortState abortState;
+ TQStringList pendingCommands;
+ TQString currentCmd;
+
+ bool waitForDtpToConnect;
+ bool waitForDtpToClose;
+};
+
+/**********************************************************************
+ *
+ * TQFtpCommand implemenatation
+ *
+ *********************************************************************/
+class TQFtpCommand
+{
+public:
+ TQFtpCommand( TQFtp::Command cmd, TQStringList raw );
+ TQFtpCommand( TQFtp::Command cmd, TQStringList raw, const TQByteArray &ba );
+ TQFtpCommand( TQFtp::Command cmd, TQStringList raw, TQIODevice *dev );
+ ~TQFtpCommand();
+
+ int id;
+ TQFtp::Command command;
+ TQStringList rawCmds;
+
+ // If is_ba is TRUE, ba is used; ba is never 0.
+ // Otherwise dev is used; dev can be 0 or not.
+ union {
+ TQByteArray *ba;
+ TQIODevice *dev;
+ } data;
+ bool is_ba;
+
+ static int idCounter;
+};
+
+int TQFtpCommand::idCounter = 0;
+
+TQFtpCommand::TQFtpCommand( TQFtp::Command cmd, TQStringList raw )
+ : command(cmd), rawCmds(raw), is_ba(FALSE)
+{
+ id = ++idCounter;
+ data.dev = 0;
+}
+
+TQFtpCommand::TQFtpCommand( TQFtp::Command cmd, TQStringList raw, const TQByteArray &ba )
+ : command(cmd), rawCmds(raw), is_ba(TRUE)
+{
+ id = ++idCounter;
+ data.ba = new TQByteArray( ba );
+}
+
+TQFtpCommand::TQFtpCommand( TQFtp::Command cmd, TQStringList raw, TQIODevice *dev )
+ : command(cmd), rawCmds(raw), is_ba(FALSE)
+{
+ id = ++idCounter;
+ data.dev = dev;
+}
+
+TQFtpCommand::~TQFtpCommand()
+{
+ if ( is_ba )
+ delete data.ba;
+}
+
+/**********************************************************************
+ *
+ * TQFtpDTP implemenatation
+ *
+ *********************************************************************/
+TQFtpDTP::TQFtpDTP( TQFtpPI *p, TQObject *tqparent, const char *name ) :
+ TQObject( tqparent, name ),
+ socket( 0, "TQFtpDTP_socket" ),
+ pi( p ),
+ callWriteData( FALSE )
+{
+ clearData();
+
+ connect( &socket, TQT_SIGNAL( connected() ),
+ TQT_SLOT( socketConnected() ) );
+ connect( &socket, TQT_SIGNAL( readyRead() ),
+ TQT_SLOT( socketReadyRead() ) );
+ connect( &socket, TQT_SIGNAL( error(int) ),
+ TQT_SLOT( socketError(int) ) );
+ connect( &socket, TQT_SIGNAL( connectionClosed() ),
+ TQT_SLOT( socketConnectionClosed() ) );
+ connect( &socket, TQT_SIGNAL( bytesWritten(int) ),
+ TQT_SLOT( socketBytesWritten(int) ) );
+}
+
+void TQFtpDTP::setData( TQByteArray *ba )
+{
+ is_ba = TRUE;
+ data.ba = ba;
+}
+
+void TQFtpDTP::setDevice( TQIODevice *dev )
+{
+ is_ba = FALSE;
+ data.dev = dev;
+}
+
+void TQFtpDTP::writeData()
+{
+ if ( is_ba ) {
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP::writeData: write %d bytes", data.ba->size() );
+#endif
+ if ( data.ba->size() == 0 )
+ emit dataTransferProgress( 0, bytesTotal );
+ else
+ socket.writeBlock( data.ba->data(), data.ba->size() );
+ socket.close();
+ clearData();
+ } else if ( data.dev ) {
+ callWriteData = FALSE;
+ const int blockSize = 16*1024;
+ char buf[blockSize];
+ while ( !data.dev->atEnd() && socket.bytesToWrite()==0 ) {
+ TQ_LONG read = data.dev->readBlock( buf, blockSize );
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP::writeData: writeBlock() of size %d bytes", (int)read );
+#endif
+ socket.writeBlock( buf, read );
+ if ( !data.dev )
+ return; // this can happen when a command is aborted
+ }
+ if ( data.dev->atEnd() ) {
+ if ( bytesDone==0 && socket.bytesToWrite()==0 )
+ emit dataTransferProgress( 0, bytesTotal );
+ socket.close();
+ clearData();
+ } else {
+ callWriteData = TRUE;
+ }
+ }
+}
+
+inline bool TQFtpDTP::hasError() const
+{
+ return !err.isNull();
+}
+
+inline TQString TQFtpDTP::errorMessage() const
+{
+ return err;
+}
+
+inline void TQFtpDTP::clearError()
+{
+ err = TQString::null;
+}
+
+void TQFtpDTP::abortConnection()
+{
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP::abortConnection" );
+#endif
+ callWriteData = FALSE;
+ clearData();
+
+ socket.clearPendingData();
+ socket.close();
+}
+
+bool TQFtpDTP::parseDir( const TQString &buffer, const TQString &userName, TQUrlInfo *info )
+{
+ TQStringList lst = TQStringList::split( " ", buffer );
+
+ if ( lst.count() < 9 )
+ return FALSE;
+
+ TQString tmp;
+
+ // permissions
+ tmp = lst[ 0 ];
+
+ if ( tmp[ 0 ] == TQChar( 'd' ) ) {
+ info->setDir( TRUE );
+ info->setFile( FALSE );
+ info->setSymLink( FALSE );
+ } else if ( tmp[ 0 ] == TQChar( '-' ) ) {
+ info->setDir( FALSE );
+ info->setFile( TRUE );
+ info->setSymLink( FALSE );
+ } else if ( tmp[ 0 ] == TQChar( 'l' ) ) {
+ info->setDir( TRUE ); // #### todo
+ info->setFile( FALSE );
+ info->setSymLink( TRUE );
+ } else {
+ return FALSE;
+ }
+
+ static int user = 0;
+ static int group = 1;
+ static int other = 2;
+ static int readable = 0;
+ static int writable = 1;
+ static int executable = 2;
+
+ bool perms[ 3 ][ 3 ];
+ perms[0][0] = (tmp[ 1 ] == 'r');
+ perms[0][1] = (tmp[ 2 ] == 'w');
+ perms[0][2] = (tmp[ 3 ] == 'x');
+ perms[1][0] = (tmp[ 4 ] == 'r');
+ perms[1][1] = (tmp[ 5 ] == 'w');
+ perms[1][2] = (tmp[ 6 ] == 'x');
+ perms[2][0] = (tmp[ 7 ] == 'r');
+ perms[2][1] = (tmp[ 8 ] == 'w');
+ perms[2][2] = (tmp[ 9 ] == 'x');
+
+ // owner
+ tmp = lst[ 2 ];
+ info->setOwner( tmp );
+
+ // group
+ tmp = lst[ 3 ];
+ info->setGroup( tmp );
+
+ // ### not correct
+ info->setWritable( ( userName == info->owner() && perms[ user ][ writable ] ) ||
+ perms[ other ][ writable ] );
+ info->setReadable( ( userName == info->owner() && perms[ user ][ readable ] ) ||
+ perms[ other ][ readable ] );
+
+ int p = 0;
+ if ( perms[ user ][ readable ] )
+ p |= TQUrlInfo::ReadOwner;
+ if ( perms[ user ][ writable ] )
+ p |= TQUrlInfo::WriteOwner;
+ if ( perms[ user ][ executable ] )
+ p |= TQUrlInfo::ExeOwner;
+ if ( perms[ group ][ readable ] )
+ p |= TQUrlInfo::ReadGroup;
+ if ( perms[ group ][ writable ] )
+ p |= TQUrlInfo::WriteGroup;
+ if ( perms[ group ][ executable ] )
+ p |= TQUrlInfo::ExeGroup;
+ if ( perms[ other ][ readable ] )
+ p |= TQUrlInfo::ReadOther;
+ if ( perms[ other ][ writable ] )
+ p |= TQUrlInfo::WriteOther;
+ if ( perms[ other ][ executable ] )
+ p |= TQUrlInfo::ExeOther;
+ info->setPermissions( p );
+
+ // size
+ tmp = lst[ 4 ];
+ info->setSize( tmp.toInt() );
+
+ // date and time
+ TQTime time;
+ TQString dateStr;
+ dateStr += "Sun ";
+ lst[ 5 ][ 0 ] = lst[ 5 ][ 0 ].upper();
+ dateStr += lst[ 5 ];
+ dateStr += ' ';
+ dateStr += lst[ 6 ];
+ dateStr += ' ';
+
+ if ( lst[ 7 ].tqcontains( ":" ) ) {
+ time = TQTime( lst[ 7 ].left( 2 ).toInt(), lst[ 7 ].right( 2 ).toInt() );
+ dateStr += TQString::number( TQDate::currentDate().year() );
+ } else {
+ dateStr += lst[ 7 ];
+ }
+
+ TQDate date = TQT_TQDATE_OBJECT(TQDate::fromString( dateStr ));
+ info->setLastModified( TQDateTime( date, time ) );
+
+ if ( lst[ 7 ].tqcontains( ":" ) ) {
+ const int futureTolerance = 600;
+ if( info->lastModified().secsTo( TQDateTime::tqcurrentDateTime() ) < -futureTolerance ) {
+ TQDateTime dt = info->lastModified();
+ TQDate d = TQT_TQDATE_OBJECT(dt.date());
+ d.setYMD(d.year()-1, d.month(), d.day());
+ dt.setDate(d);
+ info->setLastModified(dt);
+ }
+ }
+
+ // name
+ if ( info->isSymLink() )
+ info->setName( lst[ 8 ].stripWhiteSpace() );
+ else {
+ TQString n;
+ for ( uint i = 8; i < lst.count(); ++i )
+ n += lst[ i ] + " ";
+ n = n.stripWhiteSpace();
+ info->setName( n );
+ }
+ return TRUE;
+}
+
+void TQFtpDTP::socketConnected()
+{
+#if !defined (TQ_WS_TQWS)
+ // Use a large send buffer to reduce the number
+ // of writeBlocks when download and uploading files.
+ // The actual size used here (128k) is default on most
+ // Unixes.
+ socket.socketDevice()->setSendBufferSize(128 * 1024);
+ socket.socketDevice()->setReceiveBufferSize(128 * 1024);
+#endif
+
+ bytesDone = 0;
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP::connectState( CsConnected )" );
+#endif
+ emit connectState( TQFtpDTP::CsConnected );
+}
+
+void TQFtpDTP::socketReadyRead()
+{
+ if ( pi->currentCommand().isEmpty() ) {
+ socket.close();
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP::connectState( CsClosed )" );
+#endif
+ emit connectState( TQFtpDTP::CsClosed );
+ return;
+ }
+
+ if ( pi->currentCommand().startsWith("LIST") ) {
+ while ( socket.canReadLine() ) {
+ TQUrlInfo i;
+ TQString line = socket.readLine();
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP read (list): '%s'", line.latin1() );
+#endif
+ if ( parseDir( line, "", &i ) ) {
+ emit listInfo( i );
+ } else {
+ // some FTP servers don't return a 550 if the file or directory
+ // does not exist, but rather write a text to the data socket
+ // -- try to catch these cases
+ if ( line.endsWith( "No such file or directory\r\n" ) )
+ err = line;
+ }
+ }
+ } else {
+ if ( !is_ba && data.dev ) {
+ TQByteArray ba( socket.bytesAvailable() );
+ TQ_LONG bytesRead = socket.readBlock( ba.data(), ba.size() );
+ if ( bytesRead < 0 ) {
+ // ### error handling
+ return;
+ }
+ ba.resize( bytesRead );
+ bytesDone += bytesRead;
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP read: %d bytes (total %d bytes)", (int)bytesRead, bytesDone );
+#endif
+ emit dataTransferProgress( bytesDone, bytesTotal );
+ if (data.dev) // make sure it wasn't deleted in the slot
+ data.dev->writeBlock( ba );
+ } else {
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP readyRead: %d bytes available (total %d bytes read)", (int)bytesAvailable(), bytesDone );
+#endif
+ emit dataTransferProgress( bytesDone+socket.bytesAvailable(), bytesTotal );
+ emit readyRead();
+ }
+ }
+}
+
+void TQFtpDTP::socketError( int e )
+{
+ if ( e == TQSocket::ErrHostNotFound ) {
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP::connectState( CsHostNotFound )" );
+#endif
+ emit connectState( TQFtpDTP::CsHostNotFound );
+ } else if ( e == TQSocket::ErrConnectionRefused ) {
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP::connectState( CsConnectionRefused )" );
+#endif
+ emit connectState( TQFtpDTP::CsConnectionRefused );
+ }
+}
+
+void TQFtpDTP::socketConnectionClosed()
+{
+ if ( !is_ba && data.dev ) {
+ clearData();
+ }
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP::connectState( CsClosed )" );
+#endif
+ emit connectState( TQFtpDTP::CsClosed );
+}
+
+void TQFtpDTP::socketBytesWritten( int bytes )
+{
+ bytesDone += bytes;
+#if defined(TQFTPDTP_DEBUG)
+ qDebug( "TQFtpDTP::bytesWritten( %d )", bytesDone );
+#endif
+ emit dataTransferProgress( bytesDone, bytesTotal );
+ if ( callWriteData )
+ writeData();
+}
+
+/**********************************************************************
+ *
+ * TQFtpPI implemenatation
+ *
+ *********************************************************************/
+TQFtpPI::TQFtpPI( TQObject *tqparent ) :
+ TQObject( tqparent ),
+ rawCommand(FALSE),
+ dtp( this ),
+ commandSocket( 0, "TQFtpPI_socket" ),
+ state( Begin ), abortState( None ),
+ currentCmd( TQString::null ),
+ waitForDtpToConnect( FALSE ),
+ waitForDtpToClose( FALSE )
+{
+ connect( &commandSocket, TQT_SIGNAL(hostFound()),
+ TQT_SLOT(hostFound()) );
+ connect( &commandSocket, TQT_SIGNAL(connected()),
+ TQT_SLOT(connected()) );
+ connect( &commandSocket, TQT_SIGNAL(connectionClosed()),
+ TQT_SLOT(connectionClosed()) );
+ connect( &commandSocket, TQT_SIGNAL(delayedCloseFinished()),
+ TQT_SLOT(delayedCloseFinished()) );
+ connect( &commandSocket, TQT_SIGNAL(readyRead()),
+ TQT_SLOT(readyRead()) );
+ connect( &commandSocket, TQT_SIGNAL(error(int)),
+ TQT_SLOT(error(int)) );
+
+ connect( &dtp, TQT_SIGNAL(connectState(int)),
+ TQT_SLOT(dtpConnectState(int)) );
+}
+
+void TQFtpPI::connectToHost( const TQString &host, TQ_UINT16 port )
+{
+ emit connectState( TQFtp::HostLookup );
+ commandSocket.connectToHost( host, port );
+}
+
+/*
+ Sends the sequence of commands \a cmds to the FTP server. When the commands
+ are all done the finished() signal is emitted. When an error occurs, the
+ error() signal is emitted.
+
+ If there are pending commands in the queue this functions returns FALSE and
+ the \a cmds are not added to the queue; otherwise it returns TRUE.
+*/
+bool TQFtpPI::sendCommands( const TQStringList &cmds )
+{
+ if ( !pendingCommands.isEmpty() )
+ return FALSE;
+
+ if ( commandSocket.state()!=TQSocket::Connected || state!=Idle ) {
+ emit error( TQFtp::NotConnected, TQFtp::tr( "Not connected" ) );
+ return TRUE; // there are no pending commands
+ }
+
+ pendingCommands = cmds;
+ startNextCmd();
+ return TRUE;
+}
+
+void TQFtpPI::clearPendingCommands()
+{
+ pendingCommands.clear();
+ dtp.abortConnection();
+ currentCmd = TQString::null;
+ state = Idle;
+}
+
+void TQFtpPI::abort()
+{
+ pendingCommands.clear();
+
+ if ( abortState != None )
+ // ABOR already sent
+ return;
+
+ abortState = AbortStarted;
+#if defined(TQFTPPI_DEBUG)
+ qDebug( "TQFtpPI send: ABOR" );
+#endif
+ commandSocket.writeBlock( "ABOR\r\n", 6 );
+
+ if ( currentCmd.startsWith("STOR ") )
+ dtp.abortConnection();
+}
+
+void TQFtpPI::hostFound()
+{
+ emit connectState( TQFtp::Connecting );
+}
+
+void TQFtpPI::connected()
+{
+ state = Begin;
+#if defined(TQFTPPI_DEBUG)
+// qDebug( "TQFtpPI state: %d [connected()]", state );
+#endif
+ emit connectState( TQFtp::Connected );
+}
+
+void TQFtpPI::connectionClosed()
+{
+ commandSocket.close();
+ emit connectState( TQFtp::Unconnected );
+}
+
+void TQFtpPI::delayedCloseFinished()
+{
+ emit connectState( TQFtp::Unconnected );
+}
+
+void TQFtpPI::error( int e )
+{
+ if ( e == TQSocket::ErrHostNotFound ) {
+ emit connectState( TQFtp::Unconnected );
+ emit error( TQFtp::HostNotFound,
+ TQFtp::tr( "Host %1 not found" ).arg( commandSocket.peerName() ) );
+ } else if ( e == TQSocket::ErrConnectionRefused ) {
+ emit connectState( TQFtp::Unconnected );
+ emit error( TQFtp::ConnectionRefused,
+ TQFtp::tr( "Connection refused to host %1" ).arg( commandSocket.peerName() ) );
+ }
+}
+
+void TQFtpPI::readyRead()
+{
+ if ( waitForDtpToClose )
+ return;
+
+ while ( commandSocket.canReadLine() ) {
+ // read line with respect to line continuation
+ TQString line = commandSocket.readLine();
+ if ( replyText.isEmpty() ) {
+ if ( line.length() < 3 ) {
+ // ### protocol error
+ return;
+ }
+ const int lowerLimit[3] = {1,0,0};
+ const int upperLimit[3] = {5,5,9};
+ for ( int i=0; i<3; i++ ) {
+ replyCode[i] = line[i].digitValue();
+ if ( replyCode[i]<lowerLimit[i] || replyCode[i]>upperLimit[i] ) {
+ // ### protocol error
+ return;
+ }
+ }
+ }
+ TQString endOfMultiLine;
+ endOfMultiLine[0] = '0' + replyCode[0];
+ endOfMultiLine[1] = '0' + replyCode[1];
+ endOfMultiLine[2] = '0' + replyCode[2];
+ endOfMultiLine[3] = ' ';
+ TQString lineCont( endOfMultiLine );
+ lineCont[3] = '-';
+ TQString lineLeft4 = line.left(4);
+
+ while ( lineLeft4 != endOfMultiLine ) {
+ if ( lineLeft4 == lineCont )
+ replyText += line.mid( 4 ); // strip 'xyz-'
+ else
+ replyText += line;
+ if ( !commandSocket.canReadLine() )
+ return;
+ line = commandSocket.readLine();
+ lineLeft4 = line.left(4);
+ }
+ replyText += line.mid( 4 ); // strip reply code 'xyz '
+ if ( replyText.endsWith("\r\n") )
+ replyText.truncate( replyText.length()-2 );
+
+ if ( processReply() )
+ replyText = "";
+ }
+}
+
+/*
+ Process a reply from the FTP server.
+
+ Returns TRUE if the reply was processed or FALSE if the reply has to be
+ processed at a later point.
+*/
+bool TQFtpPI::processReply()
+{
+#if defined(TQFTPPI_DEBUG)
+// qDebug( "TQFtpPI state: %d [processReply() begin]", state );
+ if ( replyText.length() < 400 )
+ qDebug( "TQFtpPI recv: %d %s", 100*replyCode[0]+10*replyCode[1]+replyCode[2], replyText.latin1() );
+ else
+ qDebug( "TQFtpPI recv: %d (text skipped)", 100*replyCode[0]+10*replyCode[1]+replyCode[2] );
+#endif
+
+ // process 226 replies ("Closing Data Connection") only when the data
+ // connection is really closed to avoid short reads of the DTP
+ if ( 100*replyCode[0]+10*replyCode[1]+replyCode[2] == 226 ) {
+ if ( dtp.socketState() != TQSocket::Idle ) {
+ waitForDtpToClose = TRUE;
+ return FALSE;
+ }
+ }
+
+ switch ( abortState ) {
+ case AbortStarted:
+ abortState = WaitForAbortToFinish;
+ break;
+ case WaitForAbortToFinish:
+ abortState = None;
+ return TRUE;
+ default:
+ break;
+ }
+
+ // get new state
+ static const State table[5] = {
+ /* 1yz 2yz 3yz 4yz 5yz */
+ Waiting, Success, Idle, Failure, Failure
+ };
+ switch ( state ) {
+ case Begin:
+ if ( replyCode[0] == 1 ) {
+ return TRUE;
+ } else if ( replyCode[0] == 2 ) {
+ state = Idle;
+ emit finished( TQFtp::tr( "Connected to host %1" ).arg( commandSocket.peerName() ) );
+ break;
+ }
+ // ### error handling
+ return TRUE;
+ case Waiting:
+ if ( replyCode[0]<0 || replyCode[0]>5 )
+ state = Failure;
+ else
+ state = table[ replyCode[0] - 1 ];
+ break;
+ default:
+ // ### spontaneous message
+ return TRUE;
+ }
+#if defined(TQFTPPI_DEBUG)
+// qDebug( "TQFtpPI state: %d [processReply() intermediate]", state );
+#endif
+
+ // special actions on certain replies
+ int replyCodeInt = 100*replyCode[0] + 10*replyCode[1] + replyCode[2];
+ emit rawFtpReply( replyCodeInt, replyText );
+ if ( rawCommand ) {
+ rawCommand = FALSE;
+ } else if ( replyCodeInt == 227 ) {
+ // 227 Entering Passive Mode (h1,h2,h3,h4,p1,p2)
+ // rfc959 does not define this response precisely, and gives
+ // both examples where the parenthesis are used, and where
+ // they are missing. We need to scan for the address and host
+ // info.
+ TQRegExp addrPortPattern("(\\d+),(\\d+),(\\d+),(\\d+),(\\d+),(\\d+)");
+ if (addrPortPattern.search(replyText) == -1) {
+#if defined(TQFTPPI_DEBUG)
+ qDebug( "TQFtp: bad 227 response -- address and port information missing" );
+#endif
+ // ### error handling
+ } else {
+ QStringList lst = addrPortPattern.capturedTexts();
+ TQString host = lst[1] + "." + lst[2] + "." + lst[3] + "." + lst[4];
+ TQ_UINT16 port = ( lst[5].toUInt() << 8 ) + lst[6].toUInt();
+ waitForDtpToConnect = TRUE;
+ dtp.connectToHost( host, port );
+ }
+ } else if ( replyCodeInt == 230 ) {
+ if ( currentCmd.startsWith("USER ") && pendingCommands.count()>0 &&
+ pendingCommands.first().startsWith("PASS ") ) {
+ // no need to send the PASS -- we are already logged in
+ pendingCommands.pop_front();
+ }
+ // 230 User logged in, proceed.
+ emit connectState( TQFtp::LoggedIn );
+ } else if ( replyCodeInt == 213 ) {
+ // 213 File status.
+ if ( currentCmd.startsWith("SIZE ") )
+ dtp.setBytesTotal( replyText.simplifyWhiteSpace().toInt() );
+ } else if ( replyCode[0]==1 && currentCmd.startsWith("STOR ") ) {
+ dtp.writeData();
+ }
+
+ // react on new state
+ switch ( state ) {
+ case Begin:
+ // ### should never happen
+ break;
+ case Success:
+ // ### success handling
+ state = Idle;
+ // no break!
+ case Idle:
+ if ( dtp.hasError() ) {
+ emit error( TQFtp::UnknownError, dtp.errorMessage() );
+ dtp.clearError();
+ }
+ startNextCmd();
+ break;
+ case Waiting:
+ // ### do nothing
+ break;
+ case Failure:
+ emit error( TQFtp::UnknownError, replyText );
+ state = Idle;
+ startNextCmd();
+ break;
+ }
+#if defined(TQFTPPI_DEBUG)
+// qDebug( "TQFtpPI state: %d [processReply() end]", state );
+#endif
+ return TRUE;
+}
+
+#ifndef TQT_NO_TEXTCODEC
+TQM_EXPORT_FTP TQTextCodec *qt_ftp_filename_codec = 0;
+#endif
+
+/*
+ Starts next pending command. Returns FALSE if there are no pending commands,
+ otherwise it returns TRUE.
+*/
+bool TQFtpPI::startNextCmd()
+{
+ if ( waitForDtpToConnect )
+ // don't process any new commands until we are connected
+ return TRUE;
+
+#if defined(TQFTPPI_DEBUG)
+ if ( state != Idle )
+ qDebug( "TQFtpPI startNextCmd: Internal error! TQFtpPI called in non-Idle state %d", state );
+#endif
+ if ( pendingCommands.isEmpty() ) {
+ currentCmd = TQString::null;
+ emit finished( replyText );
+ return FALSE;
+ }
+ currentCmd = pendingCommands.first();
+ pendingCommands.pop_front();
+#if defined(TQFTPPI_DEBUG)
+ qDebug( "TQFtpPI send: %s", currentCmd.left( currentCmd.length()-2 ).latin1() );
+#endif
+ state = Waiting;
+#ifndef TQT_NO_TEXTCODEC
+ if ( qt_ftp_filename_codec ) {
+ int len = 0;
+ TQCString enc = qt_ftp_filename_codec->fromUnicode(currentCmd,len);
+ commandSocket.writeBlock( enc.data(), len );
+ } else
+#endif
+ {
+ commandSocket.writeBlock( currentCmd.latin1(), currentCmd.length() );
+ }
+ return TRUE;
+}
+
+void TQFtpPI::dtpConnectState( int s )
+{
+ switch ( s ) {
+ case TQFtpDTP::CsClosed:
+ if ( waitForDtpToClose ) {
+ // there is an unprocessed reply
+ if ( processReply() )
+ replyText = "";
+ else
+ return;
+ }
+ waitForDtpToClose = FALSE;
+ readyRead();
+ return;
+ case TQFtpDTP::CsConnected:
+ waitForDtpToConnect = FALSE;
+ startNextCmd();
+ return;
+ case TQFtpDTP::CsHostNotFound:
+ case TQFtpDTP::CsConnectionRefused:
+ emit error( TQFtp::ConnectionRefused,
+ TQFtp::tr( "Connection refused for data connection" ) );
+ startNextCmd();
+ return;
+ default:
+ return;
+ }
+}
+
+/**********************************************************************
+ *
+ * TQFtpPrivate
+ *
+ *********************************************************************/
+class TQFtpPrivate
+{
+public:
+ TQFtpPrivate() :
+ close_waitForStateChange(FALSE),
+ state( TQFtp::Unconnected ),
+ error( TQFtp::NoError ),
+ npWaitForLoginDone( FALSE )
+ { pending.setAutoDelete( TRUE ); }
+
+ TQFtpPI pi;
+ TQPtrList<TQFtpCommand> pending;
+ bool close_waitForStateChange;
+ TQFtp::State state;
+ TQFtp::Error error;
+ TQString errorString;
+
+ bool npWaitForLoginDone;
+};
+
+static TQPtrDict<TQFtpPrivate> *d_ptr = 0;
+static void cleanup_d_ptr()
+{
+ delete d_ptr;
+ d_ptr = 0;
+}
+static TQFtpPrivate* d( const TQFtp* foo )
+{
+ if ( !d_ptr ) {
+ d_ptr = new TQPtrDict<TQFtpPrivate>;
+ d_ptr->setAutoDelete( TRUE );
+ qAddPostRoutine( cleanup_d_ptr );
+ }
+ TQFtpPrivate* ret = d_ptr->tqfind( (void*)foo );
+ if ( ! ret ) {
+ ret = new TQFtpPrivate;
+ d_ptr->tqreplace( (void*) foo, ret );
+ }
+ return ret;
+}
+
+static void delete_d( const TQFtp* foo )
+{
+ if ( d_ptr )
+ d_ptr->remove( (void*) foo );
+}
+
+/**********************************************************************
+ *
+ * TQFtp implementation
+ *
+ *********************************************************************/
+/*!
+ \class TQFtp tqftp.h
+ \brief The TQFtp class provides an implementation of the FTP protocol.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \module network
+
+ This class provides two different interfaces: one is the
+ TQNetworkProtocol interface that allows you to use FTP through the
+ TQUrlOperator abstraction. The other is a direct interface to FTP
+ that gives you lower-level access to the FTP protocol for finer
+ control. Using the direct interface you can also execute arbitrary
+ FTP commands.
+
+ Don't mix the two interfaces, since the behavior is not
+ well-defined.
+
+ If you want to use TQFtp with the TQNetworkProtocol interface, you
+ do not use it directly, but rather through a TQUrlOperator, for
+ example:
+
+ \code
+ TQUrlOperator op( "ftp://ftp.trolltech.com" );
+ op.listChildren(); // Asks the server to provide a directory listing
+ \endcode
+
+ This code will only work if the TQFtp class is registered; to
+ register the class, you must call qInitNetworkProtocols() before
+ using a TQUrlOperator with TQFtp.
+
+ The rest of this descrption describes the direct interface to FTP.
+
+ The class works asynchronously, so there are no blocking
+ functions. If an operation cannot be executed immediately, the
+ function will still return straight away and the operation will be
+ scheduled for later execution. The results of scheduled operations
+ are reported via Q_SIGNALS. This approach depends on the event loop
+ being in operation.
+
+ The operations that can be scheduled (they are called "commands"
+ in the rest of the documentation) are the following:
+ connectToHost(), login(), close(), list(), cd(), get(), put(),
+ remove(), mkdir(), rmdir(), rename() and rawCommand().
+
+ All of these commands return a unique identifier that allows you
+ to keep track of the command that is currently being executed.
+ When the execution of a command starts, the commandStarted()
+ signal with the command's identifier is emitted. When the command
+ is finished, the commandFinished() signal is emitted with the
+ command's identifier and a bool that indicates whether the command
+ finished with an error.
+
+ In some cases, you might want to execute a sequence of commands,
+ e.g. if you want to connect and login to a FTP server. This is
+ simply achieved:
+
+ \code
+ TQFtp *ftp = new TQFtp( this ); // this is an optional TQObject tqparent
+ ftp->connectToHost( "ftp.trolltech.com" );
+ ftp->login();
+ \endcode
+
+ In this case two FTP commands have been scheduled. When the last
+ scheduled command has finished, a done() signal is emitted with
+ a bool argument that tells you whether the sequence finished with
+ an error.
+
+ If an error occurs during the execution of one of the commands in
+ a sequence of commands, all the pending commands (i.e. scheduled,
+ but not yet executed commands) are cleared and no Q_SIGNALS are
+ emitted for them.
+
+ Some commands, e.g. list(), emit additional Q_SIGNALS to report
+ their results.
+
+ Example: If you want to download the INSTALL file from Trolltech's
+ FTP server, you would write this:
+
+ \code
+ ftp->connectToHost( "ftp.trolltech.com" ); // id == 1
+ ftp->login(); // id == 2
+ ftp->cd( "qt" ); // id == 3
+ ftp->get( "INSTALL" ); // id == 4
+ ftp->close(); // id == 5
+ \endcode
+
+ For this example the following sequence of Q_SIGNALS is emitted
+ (with small variations, depending on network traffic, etc.):
+
+ \code
+ start( 1 )
+ stateChanged( HostLookup )
+ stateChanged( Connecting )
+ stateChanged( Connected )
+ finished( 1, FALSE )
+
+ start( 2 )
+ stateChanged( LoggedIn )
+ finished( 2, FALSE )
+
+ start( 3 )
+ finished( 3, FALSE )
+
+ start( 4 )
+ dataTransferProgress( 0, 3798 )
+ dataTransferProgress( 2896, 3798 )
+ readyRead()
+ dataTransferProgress( 3798, 3798 )
+ readyRead()
+ finished( 4, FALSE )
+
+ start( 5 )
+ stateChanged( Closing )
+ stateChanged( Unconnected )
+ finished( 5, FALSE )
+
+ done( FALSE )
+ \endcode
+
+ The dataTransferProgress() signal in the above example is useful
+ if you want to show a \link TQProgressBar progressbar \endlink to
+ inform the user about the progress of the download. The
+ readyRead() signal tells you that there is data ready to be read.
+ The amount of data can be queried then with the bytesAvailable()
+ function and it can be read with the readBlock() or readAll()
+ function.
+
+ If the login fails for the above example, the Q_SIGNALS would look
+ like this:
+
+ \code
+ start( 1 )
+ stateChanged( HostLookup )
+ stateChanged( Connecting )
+ stateChanged( Connected )
+ finished( 1, FALSE )
+
+ start( 2 )
+ finished( 2, TRUE )
+
+ done( TRUE )
+ \endcode
+
+ You can then get details about the error with the error() and
+ errorString() functions.
+
+ The functions currentId() and currentCommand() provide more
+ information about the currently executing command.
+
+ The functions hasPendingCommands() and clearPendingCommands()
+ allow you to query and clear the list of pending commands.
+
+ The safest and easiest way to use the FTP protocol is to use
+ TQUrlOperator() or the FTP commands described above. If you are an
+ experienced network programmer and want to have complete control
+ you can use rawCommand() to execute arbitrary FTP commands.
+
+ \sa \link network.html TQt Network Documentation \endlink TQNetworkProtocol, TQUrlOperator TQHttp
+*/
+
+/*!
+ Constructs a TQFtp object.
+*/
+TQFtp::TQFtp() : TQNetworkProtocol()
+{
+ init();
+}
+
+/*!
+ Constructs a TQFtp object. The \a tqparent and \a name parameters
+ are passed to the TQObject constructor.
+*/
+TQFtp::TQFtp( TQObject *tqparent, const char *name ) : TQNetworkProtocol()
+{
+ if ( tqparent )
+ tqparent->insertChild( this );
+ TQT_TQOBJECT(this)->setName( name );
+ init();
+}
+
+void TQFtp::init()
+{
+ TQFtpPrivate *d = ::d( this );
+ d->errorString = tr( "Unknown error" );
+
+ connect( &d->pi, TQT_SIGNAL(connectState(int)),
+ TQT_SLOT(piConnectState(int)) );
+ connect( &d->pi, TQT_SIGNAL(finished(const TQString&)),
+ TQT_SLOT(piFinished(const TQString&)) );
+ connect( &d->pi, TQT_SIGNAL(error(int,const TQString&)),
+ TQT_SLOT(piError(int,const TQString&)) );
+ connect( &d->pi, TQT_SIGNAL(rawFtpReply(int,const TQString&)),
+ TQT_SLOT(piFtpReply(int,const TQString&)) );
+
+ connect( &d->pi.dtp, TQT_SIGNAL(readyRead()),
+ TQT_SIGNAL(readyRead()) );
+ connect( &d->pi.dtp, TQT_SIGNAL(dataTransferProgress(int,int)),
+ TQT_SIGNAL(dataTransferProgress(int,int)) );
+ connect( &d->pi.dtp, TQT_SIGNAL(listInfo(const TQUrlInfo&)),
+ TQT_SIGNAL(listInfo(const TQUrlInfo&)) );
+}
+
+/*!
+ \enum TQFtp::State
+
+ This enum defines the connection state:
+
+ \value Unconnected There is no connection to the host.
+ \value HostLookup A host name lookup is in progress.
+ \value Connecting An attempt to connect to the host is in progress.
+ \value Connected Connection to the host has been achieved.
+ \value LoggedIn Connection and user login have been achieved.
+ \value Closing The connection is closing down, but it is not yet
+ closed. (The state will be \c Unconnected when the connection is
+ closed.)
+
+ \sa stateChanged() state()
+*/
+/*!
+ \enum TQFtp::Error
+
+ This enum identifies the error that occurred.
+
+ \value NoError No error occurred.
+ \value HostNotFound The host name lookup failed.
+ \value ConnectionRefused The server refused the connection.
+ \value NotConnected Tried to send a command, but there is no connection to
+ a server.
+ \value UnknownError An error other than those specified above
+ occurred.
+
+ \sa error()
+*/
+
+/*!
+ \enum TQFtp::Command
+
+ This enum is used as the return value for the currentCommand() function.
+ This allows you to perform specific actions for particular
+ commands, e.g. in a FTP client, you might want to clear the
+ directory view when a list() command is started; in this case you
+ can simply check in the slot connected to the start() signal if
+ the currentCommand() is \c List.
+
+ \value None No command is being executed.
+ \value ConnectToHost connectToHost() is being executed.
+ \value Login login() is being executed.
+ \value Close close() is being executed.
+ \value List list() is being executed.
+ \value Cd cd() is being executed.
+ \value Get get() is being executed.
+ \value Put put() is being executed.
+ \value Remove remove() is being executed.
+ \value Mkdir mkdir() is being executed.
+ \value Rmdir rmdir() is being executed.
+ \value Rename rename() is being executed.
+ \value RawCommand rawCommand() is being executed.
+
+ \sa currentCommand()
+*/
+
+/*!
+ \fn void TQFtp::stateChanged( int state )
+
+ This signal is emitted when the state of the connection changes.
+ The argument \a state is the new state of the connection; it is
+ one of the \l State values.
+
+ It is usually emitted in response to a connectToHost() or close()
+ command, but it can also be emitted "spontaneously", e.g. when the
+ server closes the connection unexpectedly.
+
+ \sa connectToHost() close() state() State
+*/
+
+/*!
+ \fn void TQFtp::listInfo( const TQUrlInfo &i );
+
+ This signal is emitted for each directory entry the list() command
+ tqfinds. The details of the entry are stored in \a i.
+
+ \sa list()
+*/
+
+/*!
+ \fn void TQFtp::commandStarted( int id )
+
+ This signal is emitted when processing the command identified by
+ \a id starts.
+
+ \sa commandFinished() done()
+*/
+
+/*!
+ \fn void TQFtp::commandFinished( int id, bool error )
+
+ This signal is emitted when processing the command identified by
+ \a id has finished. \a error is TRUE if an error occurred during
+ the processing; otherwise \a error is FALSE.
+
+ \sa commandStarted() done() error() errorString()
+*/
+
+/*!
+ \fn void TQFtp::done( bool error )
+
+ This signal is emitted when the last pending command has finished;
+ (it is emitted after the last command's commandFinished() signal).
+ \a error is TRUE if an error occurred during the processing;
+ otherwise \a error is FALSE.
+
+ \sa commandFinished() error() errorString()
+*/
+
+/*!
+ \fn void TQFtp::readyRead()
+
+ This signal is emitted in response to a get() command when there
+ is new data to read.
+
+ If you specify a tqdevice as the second argument in the get()
+ command, this signal is \e not emitted; instead the data is
+ written directly to the tqdevice.
+
+ You can read the data with the readAll() or readBlock() functions.
+
+ This signal is useful if you want to process the data in chunks as
+ soon as it becomes available. If you are only interested in the
+ complete data, just connect to the commandFinished() signal and
+ read the data then instead.
+
+ \sa get() readBlock() readAll() bytesAvailable()
+*/
+
+/*!
+ \fn void TQFtp::dataTransferProgress( int done, int total )
+
+ This signal is emitted in response to a get() or put() request to
+ indicate the current progress of the download or upload.
+
+ \a done is the amount of data that has already been transferred
+ and \a total is the total amount of data to be read or written. It
+ is possible that the TQFtp class is not able to determine the total
+ amount of data that should be transferred, in which case \a total
+ is 0. (If you connect this signal to a TQProgressBar, the progress
+ bar shows a busy indicator if the total is 0).
+
+ \warning \a done and \a total are not necessarily the size in
+ bytes, since for large files these values might need to be
+ "scaled" to avoid overflow.
+
+ \sa get() put() TQProgressBar::setProgress()
+*/
+
+/*!
+ \fn void TQFtp::rawCommandReply( int replyCode, const TQString &detail );
+
+ This signal is emitted in response to the rawCommand() function.
+ \a replyCode is the 3 digit reply code and \a detail is the text
+ that follows the reply code.
+
+ \sa rawCommand()
+*/
+
+/*!
+ Connects to the FTP server \a host using port \a port.
+
+ The stateChanged() signal is emitted when the state of the
+ connecting process changes, e.g. to \c HostLookup, then \c
+ Connecting, then \c Connected.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa stateChanged() commandStarted() commandFinished()
+*/
+int TQFtp::connectToHost( const TQString &host, TQ_UINT16 port )
+{
+ TQStringList cmds;
+ cmds << host;
+ cmds << TQString::number( (uint)port );
+ return addCommand( new TQFtpCommand( ConnectToHost, cmds ) );
+}
+
+/*!
+ Logs in to the FTP server with the username \a user and the
+ password \a password.
+
+ The stateChanged() signal is emitted when the state of the
+ connecting process changes, e.g. to \c LoggedIn.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa commandStarted() commandFinished()
+*/
+int TQFtp::login( const TQString &user, const TQString &password )
+{
+ TQStringList cmds;
+ cmds << ( TQString("USER ") + ( user.isNull() ? TQString("anonymous") : user ) + "\r\n" );
+ cmds << ( TQString("PASS ") + ( password.isNull() ? TQString("anonymous@") : password ) + "\r\n" );
+ return addCommand( new TQFtpCommand( Login, cmds ) );
+}
+
+/*!
+ Closes the connection to the FTP server.
+
+ The stateChanged() signal is emitted when the state of the
+ connecting process changes, e.g. to \c Closing, then \c
+ Unconnected.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa stateChanged() commandStarted() commandFinished()
+*/
+int TQFtp::close()
+{
+ return addCommand( new TQFtpCommand( Close, TQStringList("TQUIT\r\n") ) );
+}
+
+/*!
+ Lists the contents of directory \a dir on the FTP server. If \a
+ dir is empty, it lists the contents of the current directory.
+
+ The listInfo() signal is emitted for each directory entry found.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa listInfo() commandStarted() commandFinished()
+*/
+int TQFtp::list( const TQString &dir )
+{
+ TQStringList cmds;
+ cmds << "TYPE A\r\n";
+ cmds << "PASV\r\n";
+ if ( dir.isEmpty() )
+ cmds << "LIST\r\n";
+ else
+ cmds << ( "LIST " + dir + "\r\n" );
+ return addCommand( new TQFtpCommand( List, cmds ) );
+}
+
+/*!
+ Changes the working directory of the server to \a dir.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa commandStarted() commandFinished()
+*/
+int TQFtp::cd( const TQString &dir )
+{
+ return addCommand( new TQFtpCommand( Cd, TQStringList("CWD "+dir+"\r\n") ) );
+}
+
+/*!
+ Downloads the file \a file from the server.
+
+ If \a dev is 0, then the readyRead() signal is emitted when there
+ is data available to read. You can then read the data with the
+ readBlock() or readAll() functions.
+
+ If \a dev is not 0, the data is written directly to the tqdevice \a
+ dev. Make sure that the \a dev pointer is valid for the duration
+ of the operation (it is safe to delete it when the
+ commandFinished() signal is emitted). In this case the readyRead()
+ signal is \e not emitted and you cannot read data with the
+ readBlock() or readAll() functions.
+
+ If you don't read the data immediately it becomes available, i.e.
+ when the readyRead() signal is emitted, it is still available
+ until the next command is started.
+
+ For example, if you want to present the data to the user as soon
+ as there is something available, connect to the readyRead() signal
+ and read the data immediately. On the other hand, if you only want
+ to work with the complete data, you can connect to the
+ commandFinished() signal and read the data when the get() command
+ is finished.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa readyRead() dataTransferProgress() commandStarted()
+ commandFinished()
+*/
+int TQFtp::get( const TQString &file, TQIODevice *dev )
+{
+ TQStringList cmds;
+ cmds << ( "SIZE " + file + "\r\n" );
+ cmds << "TYPE I\r\n";
+ cmds << "PASV\r\n";
+ cmds << ( "RETR " + file + "\r\n" );
+ if ( dev )
+ return addCommand( new TQFtpCommand( Get, cmds, dev ) );
+ return addCommand( new TQFtpCommand( Get, cmds ) );
+}
+
+/*!
+ \overload
+
+ Writes the data \a data to the file called \a file on the server.
+ The progress of the upload is reported by the
+ dataTransferProgress() signal.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa dataTransferProgress() commandStarted() commandFinished()
+*/
+int TQFtp::put( const TQByteArray &data, const TQString &file )
+{
+ TQStringList cmds;
+ cmds << "TYPE I\r\n";
+ cmds << "PASV\r\n";
+ cmds << ( "ALLO " + TQString::number(data.size()) + "\r\n" );
+ cmds << ( "STOR " + file + "\r\n" );
+ return addCommand( new TQFtpCommand( Put, cmds, data ) );
+}
+
+/*!
+ Reads the data from the IO tqdevice \a dev, and writes it to the
+ file called \a file on the server. The data is read in chunks from
+ the IO tqdevice, so this overload allows you to transmit large
+ amounts of data without the need to read all the data into memory
+ at once.
+
+ Make sure that the \a dev pointer is valid for the duration of the
+ operation (it is safe to delete it when the commandFinished() is
+ emitted).
+*/
+int TQFtp::put( TQIODevice *dev, const TQString &file )
+{
+ TQStringList cmds;
+ cmds << "TYPE I\r\n";
+ cmds << "PASV\r\n";
+ if ( !dev->isSequentialAccess() )
+ cmds << ( "ALLO " + TQString::number(dev->size()) + "\r\n" );
+ cmds << ( "STOR " + file + "\r\n" );
+ return addCommand( new TQFtpCommand( Put, cmds, dev ) );
+}
+
+/*!
+ Deletes the file called \a file from the server.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa commandStarted() commandFinished()
+*/
+int TQFtp::remove( const TQString &file )
+{
+ return addCommand( new TQFtpCommand( Remove, TQStringList("DELE "+file+"\r\n") ) );
+}
+
+/*!
+ Creates a directory called \a dir on the server.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa commandStarted() commandFinished()
+*/
+int TQFtp::mkdir( const TQString &dir )
+{
+ return addCommand( new TQFtpCommand( Mkdir, TQStringList("MKD "+dir+"\r\n") ) );
+}
+
+/*!
+ Removes the directory called \a dir from the server.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa commandStarted() commandFinished()
+*/
+int TQFtp::rmdir( const TQString &dir )
+{
+ return addCommand( new TQFtpCommand( Rmdir, TQStringList("RMD "+dir+"\r\n") ) );
+}
+
+/*!
+ Renames the file called \a oldname to \a newname on the server.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa commandStarted() commandFinished()
+*/
+int TQFtp::rename( const TQString &oldname, const TQString &newname )
+{
+ TQStringList cmds;
+ cmds << ( "RNFR " + oldname + "\r\n" );
+ cmds << ( "RNTO " + newname + "\r\n" );
+ return addCommand( new TQFtpCommand( Rename, cmds ) );
+}
+
+/*!
+ Sends the raw FTP command \a command to the FTP server. This is
+ useful for low-level FTP access. If the operation you wish to
+ perform has an equivalent TQFtp function, we recommend using the
+ function instead of raw FTP commands since the functions are
+ easier and safer.
+
+ The function does not block and returns immediately. The command
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ commandStarted() and commandFinished().
+
+ When the command is started the commandStarted() signal is
+ emitted. When it is finished the commandFinished() signal is
+ emitted.
+
+ \sa rawCommandReply() commandStarted() commandFinished()
+*/
+int TQFtp::rawCommand( const TQString &command )
+{
+ TQString cmd = command.stripWhiteSpace() + "\r\n";
+ return addCommand( new TQFtpCommand( RawCommand, TQStringList(cmd) ) );
+}
+
+/*!
+ Returns the number of bytes that can be read from the data socket
+ at the moment.
+
+ \sa get() readyRead() readBlock() readAll()
+*/
+TQ_ULONG TQFtp::bytesAvailable() const
+{
+ TQFtpPrivate *d = ::d( this );
+ return d->pi.dtp.bytesAvailable();
+}
+
+/*!
+ Reads \a maxlen bytes from the data socket into \a data and
+ returns the number of bytes read. Returns -1 if an error occurred.
+
+ \sa get() readyRead() bytesAvailable() readAll()
+*/
+TQ_LONG TQFtp::readBlock( char *data, TQ_ULONG maxlen )
+{
+ TQFtpPrivate *d = ::d( this );
+ return d->pi.dtp.readBlock( data, maxlen );
+}
+
+/*!
+ Reads all the bytes available from the data socket and returns
+ them.
+
+ \sa get() readyRead() bytesAvailable() readBlock()
+*/
+TQByteArray TQFtp::readAll()
+{
+ TQFtpPrivate *d = ::d( this );
+ return d->pi.dtp.readAll();
+}
+
+/*!
+ Aborts the current command and deletes all scheduled commands.
+
+ If there is an unfinished command (i.e. a command for which the
+ commandStarted() signal has been emitted, but for which the
+ commandFinished() signal has not been emitted), this function
+ sends an \c ABORT command to the server. When the server replies
+ that the command is aborted, the commandFinished() signal with the
+ \c error argument set to \c TRUE is emitted for the command. Due
+ to timing issues, it is possible that the command had already
+ finished before the abort request reached the server, in which
+ case, the commandFinished() signal is emitted with the \c error
+ argument set to \c FALSE.
+
+ For all other commands that are affected by the abort(), no
+ Q_SIGNALS are emitted.
+
+ If you don't start further FTP commands directly after the
+ abort(), there won't be any scheduled commands and the done()
+ signal is emitted.
+
+ \warning Some FTP servers, for example the BSD FTP daemon (version
+ 0.3), wrongly return a positive reply even when an abort has
+ occurred. For these servers the commandFinished() signal has its
+ error flag set to \c FALSE, even though the command did not
+ complete successfully.
+
+ \sa clearPendingCommands()
+*/
+void TQFtp::abort()
+{
+ TQFtpPrivate *d = ::d( this );
+ if ( d->pending.isEmpty() )
+ return;
+
+ clearPendingCommands();
+ d->pi.abort();
+}
+
+/*!
+ Returns the identifier of the FTP command that is being executed
+ or 0 if there is no command being executed.
+
+ \sa currentCommand()
+*/
+int TQFtp::currentId() const
+{
+ TQFtpPrivate *d = ::d( this );
+ TQFtpCommand *c = d->pending.getFirst();
+ if ( c == 0 )
+ return 0;
+ return c->id;
+}
+
+/*!
+ Returns the command type of the FTP command being executed or \c
+ None if there is no command being executed.
+
+ \sa currentId()
+*/
+TQFtp::Command TQFtp::currentCommand() const
+{
+ TQFtpPrivate *d = ::d( this );
+ TQFtpCommand *c = d->pending.getFirst();
+ if ( c == 0 )
+ return None;
+ return c->command;
+}
+
+/*!
+ Returns the TQIODevice pointer that is used by the FTP command to read data
+ from or store data to. If there is no current FTP command being executed or
+ if the command does not use an IO tqdevice, this function returns 0.
+
+ This function can be used to delete the TQIODevice in the slot connected to
+ the commandFinished() signal.
+
+ \sa get() put()
+*/
+TQIODevice* TQFtp::currentDevice() const
+{
+ TQFtpPrivate *d = ::d( this );
+ TQFtpCommand *c = d->pending.getFirst();
+ if ( !c )
+ return 0;
+ if ( c->is_ba )
+ return 0;
+ return c->data.dev;
+}
+
+/*!
+ Returns TRUE if there are any commands scheduled that have not yet
+ been executed; otherwise returns FALSE.
+
+ The command that is being executed is \e not considered as a
+ scheduled command.
+
+ \sa clearPendingCommands() currentId() currentCommand()
+*/
+bool TQFtp::hasPendingCommands() const
+{
+ TQFtpPrivate *d = ::d( this );
+ return d->pending.count() > 1;
+}
+
+/*!
+ Deletes all pending commands from the list of scheduled commands.
+ This does not affect the command that is being executed. If you
+ want to stop this this as well, use abort().
+
+ \sa hasPendingCommands() abort()
+*/
+void TQFtp::clearPendingCommands()
+{
+ TQFtpPrivate *d = ::d( this );
+ TQFtpCommand *c = 0;
+ if ( d->pending.count() > 0 )
+ c = d->pending.take( 0 );
+ d->pending.clear();
+ if ( c )
+ d->pending.append( c );
+}
+
+/*!
+ Returns the current state of the object. When the state changes,
+ the stateChanged() signal is emitted.
+
+ \sa State stateChanged()
+*/
+TQFtp::State TQFtp::state() const
+{
+ TQFtpPrivate *d = ::d( this );
+ return d->state;
+}
+
+/*!
+ Returns the last error that occurred. This is useful to tqfind out
+ what when wrong when receiving a commandFinished() or a done()
+ signal with the \c error argument set to \c TRUE.
+
+ If you start a new command, the error status is reset to \c NoError.
+*/
+TQFtp::Error TQFtp::error() const
+{
+ TQFtpPrivate *d = ::d( this );
+ return d->error;
+}
+
+/*!
+ Returns a human-readable description of the last error that
+ occurred. This is useful for presenting a error message to the
+ user when receiving a commandFinished() or a done() signal with
+ the \c error argument set to \c TRUE.
+
+ The error string is often (but not always) the reply from the
+ server, so it is not always possible to translate the string. If
+ the message comes from TQt, the string has already passed through
+ tr().
+*/
+TQString TQFtp::errorString() const
+{
+ TQFtpPrivate *d = ::d( this );
+ return d->errorString;
+}
+
+int TQFtp::addCommand( TQFtpCommand *cmd )
+{
+ TQFtpPrivate *d = ::d( this );
+ d->pending.append( cmd );
+
+ if ( d->pending.count() == 1 )
+ // don't emit the commandStarted() signal before the id is returned
+ TQTimer::singleShot( 0, this, TQT_SLOT(startNextCommand()) );
+
+ return cmd->id;
+}
+
+void TQFtp::startNextCommand()
+{
+ TQFtpPrivate *d = ::d( this );
+
+ TQFtpCommand *c = d->pending.getFirst();
+ if ( c == 0 )
+ return;
+
+ d->error = NoError;
+ d->errorString = tr( "Unknown error" );
+
+ if ( bytesAvailable() )
+ readAll(); // clear the data
+ emit commandStarted( c->id );
+
+ if ( c->command == ConnectToHost ) {
+ d->pi.connectToHost( c->rawCmds[0], c->rawCmds[1].toUInt() );
+ } else {
+ if ( c->command == Put ) {
+ if ( c->is_ba ) {
+ d->pi.dtp.setData( c->data.ba );
+ d->pi.dtp.setBytesTotal( c->data.ba->size() );
+ } else if ( c->data.dev && (c->data.dev->isOpen() || c->data.dev->open(IO_ReadOnly) ) ) {
+ d->pi.dtp.setDevice( c->data.dev );
+ if ( c->data.dev->isSequentialAccess() )
+ d->pi.dtp.setBytesTotal( 0 );
+ else
+ d->pi.dtp.setBytesTotal( c->data.dev->size() );
+ }
+ } else if ( c->command == Get ) {
+ if ( !c->is_ba && c->data.dev ) {
+ d->pi.dtp.setDevice( c->data.dev );
+ }
+ } else if ( c->command == Close ) {
+ d->state = TQFtp::Closing;
+ emit stateChanged( d->state );
+ }
+ if ( !d->pi.sendCommands( c->rawCmds ) ) {
+ // ### error handling (this case should not happen)
+ }
+ }
+}
+
+void TQFtp::piFinished( const TQString& )
+{
+ TQFtpPrivate *d = ::d( this );
+ TQFtpCommand *c = d->pending.getFirst();
+ if ( c == 0 )
+ return;
+
+ if ( c->command == Close ) {
+ // The order of in which the Q_SLOTS are called is arbitrary, so
+ // disconnect the SIGNAL-TQT_SIGNAL temporary to make sure that we
+ // don't get the commandFinished() signal before the stateChanged()
+ // signal.
+ if ( d->state != TQFtp::Unconnected ) {
+ d->close_waitForStateChange = TRUE;
+ return;
+ }
+ }
+ emit commandFinished( c->id, FALSE );
+
+ d->pending.removeFirst();
+ if ( d->pending.isEmpty() ) {
+ emit done( FALSE );
+ } else {
+ startNextCommand();
+ }
+}
+
+void TQFtp::piError( int errorCode, const TQString &text )
+{
+ TQFtpPrivate *d = ::d( this );
+ TQFtpCommand *c = d->pending.getFirst();
+
+ // non-fatal errors
+ if ( c->command==Get && d->pi.currentCommand().startsWith("SIZE ") ) {
+ d->pi.dtp.setBytesTotal( -1 );
+ return;
+ } else if ( c->command==Put && d->pi.currentCommand().startsWith("ALLO ") ) {
+ return;
+ }
+
+ d->error = (Error)errorCode;
+ switch ( currentCommand() ) {
+ case ConnectToHost:
+ d->errorString = tr( "Connecting to host failed:\n%1" ).arg( text );
+ break;
+ case Login:
+ d->errorString = tr( "Login failed:\n%1" ).arg( text );
+ break;
+ case List:
+ d->errorString = tr( "Listing directory failed:\n%1" ).arg( text );
+ break;
+ case Cd:
+ d->errorString = tr( "Changing directory failed:\n%1" ).arg( text );
+ break;
+ case Get:
+ d->errorString = tr( "Downloading file failed:\n%1" ).arg( text );
+ break;
+ case Put:
+ d->errorString = tr( "Uploading file failed:\n%1" ).arg( text );
+ break;
+ case Remove:
+ d->errorString = tr( "Removing file failed:\n%1" ).arg( text );
+ break;
+ case Mkdir:
+ d->errorString = tr( "Creating directory failed:\n%1" ).arg( text );
+ break;
+ case Rmdir:
+ d->errorString = tr( "Removing directory failed:\n%1" ).arg( text );
+ break;
+ default:
+ d->errorString = text;
+ break;
+ }
+
+ d->pi.clearPendingCommands();
+ clearPendingCommands();
+ emit commandFinished( c->id, TRUE );
+
+ d->pending.removeFirst();
+ if ( d->pending.isEmpty() )
+ emit done( TRUE );
+ else
+ startNextCommand();
+}
+
+void TQFtp::piConnectState( int state )
+{
+ TQFtpPrivate *d = ::d( this );
+ d->state = (State)state;
+ emit stateChanged( d->state );
+ if ( d->close_waitForStateChange ) {
+ d->close_waitForStateChange = FALSE;
+ piFinished( tr( "Connection closed" ) );
+ }
+}
+
+void TQFtp::piFtpReply( int code, const TQString &text )
+{
+ if ( currentCommand() == RawCommand ) {
+ TQFtpPrivate *d = ::d( this );
+ d->pi.rawCommand = TRUE;
+ emit rawCommandReply( code, text );
+ }
+}
+
+/*!
+ Destructor.
+*/
+TQFtp::~TQFtp()
+{
+ abort();
+ close();
+ delete_d( this );
+}
+
+/**********************************************************************
+ *
+ * TQFtp implementation of the TQNetworkProtocol interface
+ *
+ *********************************************************************/
+/*! \reimp
+*/
+void TQFtp::operationListChildren( TQNetworkOperation *op )
+{
+ op->setState( StInProgress );
+
+ cd( ( url()->path().isEmpty() ? TQString( "/" ) : url()->path() ) );
+ list();
+ emit start( op );
+}
+
+/*! \reimp
+*/
+void TQFtp::operationMkDir( TQNetworkOperation *op )
+{
+ op->setState( StInProgress );
+
+ mkdir( op->arg( 0 ) );
+}
+
+/*! \reimp
+*/
+void TQFtp::operationRemove( TQNetworkOperation *op )
+{
+ op->setState( StInProgress );
+
+ cd( ( url()->path().isEmpty() ? TQString( "/" ) : url()->path() ) );
+ remove( TQUrl( op->arg( 0 ) ).path() );
+}
+
+/*! \reimp
+*/
+void TQFtp::operationRename( TQNetworkOperation *op )
+{
+ op->setState( StInProgress );
+
+ cd( ( url()->path().isEmpty() ? TQString( "/" ) : url()->path() ) );
+ rename( op->arg( 0 ), op->arg( 1 ));
+}
+
+/*! \reimp
+*/
+void TQFtp::operationGet( TQNetworkOperation *op )
+{
+ op->setState( StInProgress );
+
+ TQUrl u( op->arg( 0 ) );
+ get( u.path() );
+}
+
+/*! \reimp
+*/
+void TQFtp::operationPut( TQNetworkOperation *op )
+{
+ op->setState( StInProgress );
+
+ TQUrl u( op->arg( 0 ) );
+ put( op->rawArg(1), u.path() );
+}
+
+/*! \reimp
+*/
+bool TQFtp::checkConnection( TQNetworkOperation *op )
+{
+ TQFtpPrivate *d = ::d( this );
+ if ( state() == Unconnected && !d->npWaitForLoginDone ) {
+ connect( this, TQT_SIGNAL(listInfo(const TQUrlInfo&)),
+ this, TQT_SLOT(npListInfo(const TQUrlInfo&)) );
+ connect( this, TQT_SIGNAL(done(bool)),
+ this, TQT_SLOT(npDone(bool)) );
+ connect( this, TQT_SIGNAL(stateChanged(int)),
+ this, TQT_SLOT(npStateChanged(int)) );
+ connect( this, TQT_SIGNAL(dataTransferProgress(int,int)),
+ this, TQT_SLOT(npDataTransferProgress(int,int)) );
+ connect( this, TQT_SIGNAL(readyRead()),
+ this, TQT_SLOT(npReadyRead()) );
+
+ d->npWaitForLoginDone = TRUE;
+ switch ( op->operation() ) {
+ case OpGet:
+ case OpPut:
+ {
+ TQUrl u( op->arg( 0 ) );
+ connectToHost( u.host(), u.port() != -1 ? u.port() : 21 );
+ }
+ break;
+ default:
+ connectToHost( url()->host(), url()->port() != -1 ? url()->port() : 21 );
+ break;
+ }
+ TQString user = url()->user().isEmpty() ? TQString( "anonymous" ) : url()->user();
+ TQString pass = url()->password().isEmpty() ? TQString( "anonymous@" ) : url()->password();
+ login( user, pass );
+ }
+
+ if ( state() == LoggedIn )
+ return TRUE;
+ return FALSE;
+}
+
+/*! \reimp
+*/
+int TQFtp::supportedOperations() const
+{
+ return OpListChildren | OpMkDir | OpRemove | OpRename | OpGet | OpPut;
+}
+
+/*! \internal
+ Parses the string, \a buffer, which is one line of a directory
+ listing which came from the FTP server, and sets the values which
+ have been parsed to the url info object, \a info.
+*/
+void TQFtp::parseDir( const TQString &buffer, TQUrlInfo &info )
+{
+ TQFtpDTP::parseDir( buffer, url()->user(), &info );
+}
+
+void TQFtp::npListInfo( const TQUrlInfo & i )
+{
+ if ( url() ) {
+ TQRegExp filt( url()->nameFilter(), FALSE, TRUE );
+ if ( i.isDir() || filt.search( i.name() ) != -1 ) {
+ emit newChild( i, operationInProgress() );
+ }
+ } else {
+ emit newChild( i, operationInProgress() );
+ }
+}
+
+void TQFtp::npDone( bool err )
+{
+ TQFtpPrivate *d = ::d( this );
+
+ bool emitFinishedSignal = FALSE;
+ TQNetworkOperation *op = operationInProgress();
+ if ( op ) {
+ if ( err ) {
+ op->setProtocolDetail( errorString() );
+ op->setState( StFailed );
+ if ( error() == HostNotFound ) {
+ op->setErrorCode( (int)ErrHostNotFound );
+ } else {
+ switch ( op->operation() ) {
+ case OpListChildren:
+ op->setErrorCode( (int)ErrListChildren );
+ break;
+ case OpMkDir:
+ op->setErrorCode( (int)ErrMkDir );
+ break;
+ case OpRemove:
+ op->setErrorCode( (int)ErrRemove );
+ break;
+ case OpRename:
+ op->setErrorCode( (int)ErrRename );
+ break;
+ case OpGet:
+ op->setErrorCode( (int)ErrGet );
+ break;
+ case OpPut:
+ op->setErrorCode( (int)ErrPut );
+ break;
+ }
+ }
+ emitFinishedSignal = TRUE;
+ } else if ( !d->npWaitForLoginDone ) {
+ switch ( op->operation() ) {
+ case OpRemove:
+ emit removed( op );
+ break;
+ case OpMkDir:
+ {
+ TQUrlInfo inf( op->arg( 0 ), 0, "", "", 0, TQDateTime(),
+ TQDateTime(), TRUE, FALSE, FALSE, TRUE, TRUE, TRUE );
+ emit newChild( inf, op );
+ emit createdDirectory( inf, op );
+ }
+ break;
+ case OpRename:
+ emit itemChanged( operationInProgress() );
+ break;
+ default:
+ break;
+ }
+ op->setState( StDone );
+ emitFinishedSignal = TRUE;
+ }
+ }
+ d->npWaitForLoginDone = FALSE;
+
+ if ( state() == Unconnected ) {
+ disconnect( this, TQT_SIGNAL(listInfo(const TQUrlInfo&)),
+ this, TQT_SLOT(npListInfo(const TQUrlInfo&)) );
+ disconnect( this, TQT_SIGNAL(done(bool)),
+ this, TQT_SLOT(npDone(bool)) );
+ disconnect( this, TQT_SIGNAL(stateChanged(int)),
+ this, TQT_SLOT(npStateChanged(int)) );
+ disconnect( this, TQT_SIGNAL(dataTransferProgress(int,int)),
+ this, TQT_SLOT(npDataTransferProgress(int,int)) );
+ disconnect( this, TQT_SIGNAL(readyRead()),
+ this, TQT_SLOT(npReadyRead()) );
+ }
+
+ // emit the finished() signal at the very end to avoid reentrance problems
+ if ( emitFinishedSignal )
+ emit finished( op );
+}
+
+void TQFtp::npStateChanged( int state )
+{
+ if ( url() ) {
+ if ( state == Connecting )
+ emit connectionStateChanged( ConHostFound, tr( "Host %1 found" ).arg( url()->host() ) );
+ else if ( state == Connected )
+ emit connectionStateChanged( ConConnected, tr( "Connected to host %1" ).arg( url()->host() ) );
+ else if ( state == Unconnected )
+ emit connectionStateChanged( ConClosed, tr( "Connection to %1 closed" ).arg( url()->host() ) );
+ } else {
+ if ( state == Connecting )
+ emit connectionStateChanged( ConHostFound, tr( "Host found" ) );
+ else if ( state == Connected )
+ emit connectionStateChanged( ConConnected, tr( "Connected to host" ) );
+ else if ( state == Unconnected )
+ emit connectionStateChanged( ConClosed, tr( "Connection closed" ) );
+ }
+}
+
+void TQFtp::npDataTransferProgress( int bDone, int bTotal )
+{
+ emit TQNetworkProtocol::dataTransferProgress( bDone, bTotal, operationInProgress() );
+}
+
+void TQFtp::npReadyRead()
+{
+ emit data( readAll(), operationInProgress() );
+}
+
+// ### unused -- delete in TQt 4.0
+/*! \internal
+*/
+void TQFtp::hostFound()
+{
+}
+/*! \internal
+*/
+void TQFtp::connected()
+{
+}
+/*! \internal
+*/
+void TQFtp::closed()
+{
+}
+/*! \internal
+*/
+void TQFtp::dataHostFound()
+{
+}
+/*! \internal
+*/
+void TQFtp::dataConnected()
+{
+}
+/*! \internal
+*/
+void TQFtp::dataClosed()
+{
+}
+/*! \internal
+*/
+void TQFtp::dataReadyRead()
+{
+}
+/*! \internal
+*/
+void TQFtp::dataBytesWritten( int )
+{
+}
+/*! \internal
+*/
+void TQFtp::error( int )
+{
+}
+
+#include "tqftp.tqmoc"
+
+#endif // TQT_NO_NETWORKPROTOCOL_FTP
diff --git a/tqtinterface/qt4/src/network/tqftp.h b/tqtinterface/qt4/src/network/tqftp.h
new file mode 100644
index 0000000..ee49afc
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqftp.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Definition of TQFtp class.
+**
+** Created : 970521
+**
+** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFTP_H
+#define TQFTP_H
+
+#ifndef TQT_H
+#include "tqstring.h" // char*->TQString conversion
+#include "tqurlinfo.h"
+#include "tqcstring.h"
+#include "tqnetworkprotocol.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
+#define TQM_EXPORT_FTP
+#else
+#define TQM_EXPORT_FTP TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_NETWORKPROTOCOL_FTP
+
+
+class TQSocket;
+class TQFtpCommand;
+
+class TQM_EXPORT_FTP TQFtp : public TQNetworkProtocol
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQFtp(); // ### TQt 4.0: get rid of this overload
+ TQFtp( TQObject *tqparent, const char *name=0 );
+ virtual ~TQFtp();
+
+ int supportedOperations() const;
+
+ // non-TQNetworkProtocol functions:
+ enum State {
+ Unconnected,
+ HostLookup,
+ Connecting,
+ Connected,
+ LoggedIn,
+ Closing
+ };
+ enum Error {
+ NoError,
+ UnknownError,
+ HostNotFound,
+ ConnectionRefused,
+ NotConnected
+ };
+ enum Command {
+ None,
+ ConnectToHost,
+ Login,
+ Close,
+ List,
+ Cd,
+ Get,
+ Put,
+ Remove,
+ Mkdir,
+ Rmdir,
+ Rename,
+ RawCommand
+ };
+
+ int connectToHost( const TQString &host, TQ_UINT16 port=21 );
+ int login( const TQString &user=TQString::null, const TQString &password=TQString::null );
+ int close();
+ int list( const TQString &dir=TQString::null );
+ int cd( const TQString &dir );
+ int get( const TQString &file, TQIODevice *dev=0 );
+ int put( const TQByteArray &data, const TQString &file );
+ int put( TQIODevice *dev, const TQString &file );
+ int remove( const TQString &file );
+ int mkdir( const TQString &dir );
+ int rmdir( const TQString &dir );
+ int rename( const TQString &oldname, const TQString &newname );
+
+ int rawCommand( const TQString &command );
+
+ TQ_ULONG bytesAvailable() const;
+ TQ_LONG readBlock( char *data, TQ_ULONG maxlen );
+ TQByteArray readAll();
+
+ int currentId() const;
+ TQIODevice* currentDevice() const;
+ Command currentCommand() const;
+ bool hasPendingCommands() const;
+ void clearPendingCommands();
+
+ State state() const;
+
+ Error error() const;
+ TQString errorString() const;
+
+public Q_SLOTS:
+ void abort();
+
+Q_SIGNALS:
+ void stateChanged( int );
+ void listInfo( const TQUrlInfo& );
+ void readyRead();
+ void dataTransferProgress( int, int );
+ void rawCommandReply( int, const TQString& );
+
+ void commandStarted( int );
+ void commandFinished( int, bool );
+ void done( bool );
+
+protected:
+ void parseDir( const TQString &buffer, TQUrlInfo &info ); // ### TQt 4.0: delete this? (not public API)
+ void operationListChildren( TQNetworkOperation *op );
+ void operationMkDir( TQNetworkOperation *op );
+ void operationRemove( TQNetworkOperation *op );
+ void operationRename( TQNetworkOperation *op );
+ void operationGet( TQNetworkOperation *op );
+ void operationPut( TQNetworkOperation *op );
+
+ // ### TQt 4.0: delete these
+ // unused variables:
+ TQSocket *commandSocket, *dataSocket;
+ bool connectionReady, passiveMode;
+ int getTotalSize, getDoneSize;
+ bool startGetOnFail;
+ int putToWrite, putWritten;
+ bool errorInListChildren;
+
+private:
+ void init();
+ int addCommand( TQFtpCommand * );
+
+ bool checkConnection( TQNetworkOperation *op );
+
+private Q_SLOTS:
+ void startNextCommand();
+ void piFinished( const TQString& );
+ void piError( int, const TQString& );
+ void piConnectState( int );
+ void piFtpReply( int, const TQString& );
+
+private Q_SLOTS:
+ void npListInfo( const TQUrlInfo & );
+ void npDone( bool );
+ void npStateChanged( int );
+ void npDataTransferProgress( int, int );
+ void npReadyRead();
+
+protected Q_SLOTS:
+ // ### TQt 4.0: delete these
+ void hostFound();
+ void connected();
+ void closed();
+ void dataHostFound();
+ void dataConnected();
+ void dataClosed();
+ void dataReadyRead();
+ void dataBytesWritten( int nbytes );
+ void error( int );
+};
+
+#endif // TQT_NO_NETWORKPROTOCOL_FTP
+
+#endif // TQFTP_H
diff --git a/tqtinterface/qt4/src/network/tqhostaddress.cpp b/tqtinterface/qt4/src/network/tqhostaddress.cpp
new file mode 100644
index 0000000..f6720e4
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqhostaddress.cpp
@@ -0,0 +1,459 @@
+/****************************************************************************
+**
+** Implementation of TQHostAddress class.
+**
+** Created : 979899
+**
+** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqhostaddress.h"
+#include "tqstringlist.h"
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+#ifndef TQT_NO_NETWORK
+class TQHostAddressPrivate
+{
+public:
+ TQHostAddressPrivate( TQ_UINT32 a_=0 ) : a(a_), isIp4(TRUE)
+ {
+ }
+ TQHostAddressPrivate( TQ_UINT8 *a_ );
+ TQHostAddressPrivate(const TQ_IPV6ADDR &a_);
+ ~TQHostAddressPrivate()
+ {
+ }
+
+ TQHostAddressPrivate & operator=( const TQHostAddressPrivate &from )
+ {
+ a = from.a;
+ isIp4 = from.isIp4;
+ a6 = from.a6;
+ return *this;
+ }
+
+private:
+ TQ_UINT32 a; // ip 4 address
+ TQ_IPV6ADDR a6; // ip 6 address
+ bool isIp4;
+
+ friend class TQHostAddress;
+};
+
+TQHostAddressPrivate::TQHostAddressPrivate(TQ_UINT8 *a_) : a(0), isIp4(FALSE)
+{
+ for ( int i=0; i<16; i++ ) {
+ a6.c[i] = a_[i];
+ }
+}
+
+TQHostAddressPrivate::TQHostAddressPrivate(const TQ_IPV6ADDR &a_) : a(0), isIp4(FALSE)
+{
+ a6 = a_;
+}
+
+/*!
+ \class TQHostAddress tqhostaddress.h
+ \brief The TQHostAddress class provides an IP address.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \module network
+
+ This class tqcontains an IP address in a platform and protocol
+ independent manner. It stores both IPv4 and IPv6 addresses in a
+ way that you can easily access on any platform.
+
+ TQHostAddress is normally used with the classes TQSocket,
+ TQServerSocket and TQSocketDevice to set up a server or to connect
+ to a host.
+
+ Host addresses may be set with setAddress() and retrieved with
+ ip4Addr() or toString().
+
+ \sa TQSocket, TQServerSocket, TQSocketDevice
+*/
+
+
+/*!
+ Creates a host address object with the IP address 0.0.0.0.
+*/
+TQHostAddress::TQHostAddress()
+ : d( new TQHostAddressPrivate )
+{
+}
+
+
+/*!
+ Creates a host address object for the IPv4 address \a ip4Addr.
+*/
+TQHostAddress::TQHostAddress( TQ_UINT32 ip4Addr )
+ : d( new TQHostAddressPrivate( ip4Addr ) )
+{
+}
+
+
+/*!
+ Creates a host address object with the specified IPv6 address.
+
+ \a ip6Addr must be a 16 byte array in network byte order
+ (high-order byte first).
+*/
+TQHostAddress::TQHostAddress( TQ_UINT8 *ip6Addr )
+ : d( new TQHostAddressPrivate( ip6Addr ) )
+{
+}
+
+/*!
+ Creates a host address object with the IPv6 address, \a ip6Addr.
+*/
+TQHostAddress::TQHostAddress(const TQ_IPV6ADDR &ip6Addr)
+ : d(new TQHostAddressPrivate(ip6Addr))
+{
+}
+
+// ### DOC: Can only make this public if we specify precisely the
+// format of the address string.
+/*!
+ \internal
+*/
+TQHostAddress::TQHostAddress(const TQString &address)
+ : d( new TQHostAddressPrivate )
+{
+ setAddress( address );
+}
+
+/*!
+ Creates a copy of \a address.
+*/
+TQHostAddress::TQHostAddress( const TQHostAddress &address )
+ : d( new TQHostAddressPrivate )
+{
+ *d = *(address.d);
+}
+
+
+/*!
+ Destroys the host address object.
+*/
+TQHostAddress::~TQHostAddress()
+{
+ delete d;
+}
+
+
+/*!
+ Assigns another host address object \a address to this object and
+ returns a reference to this object.
+*/
+TQHostAddress & TQHostAddress::operator=( const TQHostAddress & address )
+{
+ *d = *(address.d);
+ return *this;
+}
+
+
+/*!
+ Set the IPv4 address specified by \a ip4Addr.
+*/
+void TQHostAddress::setAddress( TQ_UINT32 ip4Addr )
+{
+ delete d;
+ d = new TQHostAddressPrivate( ip4Addr );
+}
+
+
+/*!
+ \overload
+
+ Set the IPv6 address specified by \a ip6Addr.
+
+ \a ip6Addr must be a 16 byte array in network byte order
+ (high-order byte first).
+*/
+void TQHostAddress::setAddress( TQ_UINT8 *ip6Addr )
+{
+ delete d;
+ d = new TQHostAddressPrivate( ip6Addr );
+}
+
+#ifndef TQT_NO_STRINGLIST
+static bool parseIp4(const TQString& address, TQ_UINT32 *addr)
+{
+ TQStringList ipv4 = TQStringList::split(".", address, FALSE);
+ if (ipv4.count() == 4) {
+ int i = 0;
+ bool ok = TRUE;
+ while(ok && i < 4) {
+ uint byteValue = ipv4[i].toUInt(&ok);
+ if (byteValue > 255)
+ ok = FALSE;
+ if (ok)
+ *addr = (*addr << 8) + byteValue;
+ ++i;
+ }
+ if (ok)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*!
+ \overload
+
+ Sets the IPv4 or IPv6 address specified by the string
+ representation \a address (e.g. "127.0.0.1"). Returns TRUE and
+ sets the address if the address was successfully parsed; otherwise
+ returns FALSE and leaves the address unchanged.
+*/
+bool TQHostAddress::setAddress(const TQString& address)
+{
+ TQString a = address.simplifyWhiteSpace();
+
+ // try ipv4
+ TQ_UINT32 maybeIp4 = 0;
+ if (parseIp4(address, &maybeIp4)) {
+ setAddress(maybeIp4);
+ return TRUE;
+ }
+
+ // try ipv6
+ TQStringList ipv6 = TQStringList::split(":", a, TRUE);
+ int count = (int)ipv6.count();
+ if (count < 3)
+ return FALSE; // there must be at least two ":"
+ if (count > 8)
+ return FALSE; // maximum of seven ":" exceeded
+ TQ_UINT8 maybeIp6[16];
+ int mc = 16;
+ int fillCount = 9 - count;
+ for (int i=count-1; i>=0; --i) {
+ if ( mc <= 0 )
+ return FALSE;
+
+ if (ipv6[i].isEmpty()) {
+ if (i==count-1) {
+ // special case: ":" is last character
+ if (!ipv6[i-1].isEmpty())
+ return FALSE;
+ maybeIp6[--mc] = 0;
+ maybeIp6[--mc] = 0;
+ } else if (i==0) {
+ // special case: ":" is first character
+ if (!ipv6[i+1].isEmpty())
+ return FALSE;
+ maybeIp6[--mc] = 0;
+ maybeIp6[--mc] = 0;
+ } else {
+ for (int j=0; j<fillCount; ++j) {
+ if ( mc <= 0 )
+ return FALSE;
+ maybeIp6[--mc] = 0;
+ maybeIp6[--mc] = 0;
+ }
+ }
+ } else {
+ bool ok = FALSE;
+ uint byteValue = ipv6[i].toUInt(&ok, 16);
+ if (ok && byteValue <= 0xffff) {
+ maybeIp6[--mc] = byteValue & 0xff;
+ maybeIp6[--mc] = (byteValue >> 8) & 0xff;
+ } else {
+ if (i == count-1) {
+ // parse the ipv4 part of a mixed type
+ if (!parseIp4(ipv6[i], &maybeIp4))
+ return FALSE;
+ maybeIp6[--mc] = maybeIp4 & 0xff;
+ maybeIp6[--mc] = (maybeIp4 >> 8) & 0xff;
+ maybeIp6[--mc] = (maybeIp4 >> 16) & 0xff;
+ maybeIp6[--mc] = (maybeIp4 >> 24) & 0xff;
+ --fillCount;
+ } else {
+ return FALSE;
+ }
+ }
+ }
+ }
+ if (mc == 0) {
+ setAddress(maybeIp6);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+#endif
+
+/*!
+ \obsolete
+
+ Use isIPv4Address() instead.
+*/
+bool TQHostAddress::isIp4Addr() const
+{
+ return isIPv4Address();
+}
+
+/*!
+ Returns TRUE if the host address represents an IPv4 address;
+ otherwise returns FALSE.
+*/
+bool TQHostAddress::isIPv4Address() const
+{
+ return d->isIp4;
+}
+
+/*!
+ \obsolete
+
+ Use toIPv4Address() instead.
+*/
+TQ_UINT32 TQHostAddress::ip4Addr() const
+{
+ return toIPv4Address();
+}
+
+/*!
+ Returns the IPv4 address as a number.
+
+ For example, if the address is 127.0.0.1, the returned value is
+ 2130706433 (i.e. 0x7f000001).
+
+ This value is only valid when isIp4Addr() returns TRUE.
+
+ \sa toString()
+*/
+TQ_UINT32 TQHostAddress::toIPv4Address() const
+{
+ return d->a;
+}
+
+/*!
+ Returns TRUE if the host address represents an IPv6 address;
+ otherwise returns FALSE.
+*/
+bool TQHostAddress::isIPv6Address() const
+{
+ return !d->isIp4;
+}
+
+/*!
+ Returns the IPv6 address as a TQ_IPV6ADDR structure. The structure
+ consists of 16 unsigned characters.
+
+ \code
+ TQ_IPV6ADDR addr = hostAddr.ip6Addr();
+ // addr.c[] tqcontains 16 unsigned characters
+
+ for (int i = 0; i < 16; ++i) {
+ // process addr.c[i]
+ }
+ \endcode
+
+ This value is only valid when isIPv6Address() returns TRUE.
+
+ \sa toString()
+*/
+TQ_IPV6ADDR TQHostAddress::toIPv6Address() const
+{
+ return d->a6;
+}
+
+#ifndef TQT_NO_SPRINTF
+/*!
+ Returns the address as a string.
+
+ For example, if the address is the IPv4 address 127.0.0.1, the
+ returned string is "127.0.0.1".
+
+ \sa ip4Addr()
+*/
+TQString TQHostAddress::toString() const
+{
+ if ( d->isIp4 ) {
+ TQ_UINT32 i = ip4Addr();
+ TQString s;
+ s.sprintf( "%d.%d.%d.%d", (i>>24) & 0xff, (i>>16) & 0xff,
+ (i >> 8) & 0xff, i & 0xff );
+ return s;
+ } else {
+ TQ_UINT16 ugle[8];
+ for ( int i=0; i<8; i++ ) {
+ ugle[i] = ( (TQ_UINT16)( d->a6.c[2*i] ) << 8 ) |
+ ( (TQ_UINT16)( d->a6.c[2*i+1] ) );
+ }
+ TQString s;
+ s.sprintf( "%X:%X:%X:%X:%X:%X:%X:%X",
+ ugle[0], ugle[1], ugle[2], ugle[3],
+ ugle[4], ugle[5], ugle[6], ugle[7] );
+ return s;
+ }
+}
+#endif
+
+
+/*!
+ Returns TRUE if this host address is the same as \a other;
+ otherwise returns FALSE.
+*/
+bool TQHostAddress::operator==( const TQHostAddress & other ) const
+{
+ return d->a == other.d->a;
+}
+
+
+/*!
+ Returns TRUE if this host address is null (INADDR_ANY or in6addr_any). The
+ default constructor creates a null address, and that address isn't valid
+ for any particular host or interface.
+*/
+bool TQHostAddress::isNull() const
+{
+ if ( d->isIp4 )
+ return d->a == 0;
+ int i = 0;
+ while( i < 16 ) {
+ if ( d->a6.c[i++] != 0 )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#endif //TQT_NO_NETWORK
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/network/tqhostaddress.h b/tqtinterface/qt4/src/network/tqhostaddress.h
new file mode 100644
index 0000000..692bfd8
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqhostaddress.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Definition of TQHostAddress class.
+**
+** Created : 979899
+**
+** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQHOSTADDRESS_H
+#define TQHOSTADDRESS_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
+#define TQM_EXPORT_NETWORK
+#else
+#define TQM_EXPORT_NETWORK TQ_EXPORT
+#endif
+
+#ifdef USE_QT4
+
+#include <Qt/qhostaddress.h>
+
+#endif // USE_QT4
+
+#ifndef TQT_NO_NETWORK
+class TQHostAddressPrivate;
+
+typedef Q_IPV6ADDR TQ_IPV6ADDR;
+
+#ifdef USE_QT4
+
+class TQM_EXPORT_NETWORK TQHostAddress : public QHostAddress
+{
+public:
+ TQHostAddress() : QHostAddress() {}
+ TQHostAddress( TQ_UINT32 ip4Addr ) : QHostAddress( ip4Addr ) {}
+ TQHostAddress( TQ_UINT8 *ip6Addr ) : QHostAddress( ip6Addr ) {}
+ TQHostAddress(const TQ_IPV6ADDR &ip6Addr) : QHostAddress( ip6Addr ) {}
+#ifndef TQT_NO_STRINGLIST
+ TQHostAddress(const QString &address) : QHostAddress( address ) {}
+#endif
+ TQHostAddress( const QHostAddress &tqha ) : QHostAddress( tqha ) {}
+
+ inline quint32 ip4Addr() const { return toIPv4Address(); }
+ inline bool isIPv4Address() const { return protocol() == QAbstractSocket::IPv4Protocol || protocol() == QAbstractSocket::UnknownNetworkLayerProtocol; }
+ inline bool isIp4Addr() const { return protocol() == QAbstractSocket::IPv4Protocol || protocol() == QAbstractSocket::UnknownNetworkLayerProtocol; }
+ inline bool isIPv6Address() const { return protocol() == QAbstractSocket::IPv6Protocol; }
+};
+
+#else // USE_QT4
+
+class TQM_EXPORT_NETWORK TQHostAddress
+{
+public:
+ TQHostAddress();
+ TQHostAddress( TQ_UINT32 ip4Addr );
+ TQHostAddress( TQ_UINT8 *ip6Addr );
+ TQHostAddress(const TQ_IPV6ADDR &ip6Addr);
+#ifndef TQT_NO_STRINGLIST
+ TQHostAddress(const TQString &address);
+#endif
+ TQHostAddress( const TQHostAddress & );
+ virtual ~TQHostAddress();
+
+ TQHostAddress & operator=( const TQHostAddress & );
+
+ void setAddress( TQ_UINT32 ip4Addr );
+ void setAddress( TQ_UINT8 *ip6Addr );
+#ifndef TQT_NO_STRINGLIST
+ bool setAddress( const TQString& address );
+#endif
+ bool isIp4Addr() const; // obsolete
+ TQ_UINT32 ip4Addr() const; // obsolete
+
+ bool isIPv4Address() const;
+ TQ_UINT32 toIPv4Address() const;
+ bool isIPv6Address() const;
+ TQ_IPV6ADDR toIPv6Address() const;
+
+#ifndef TQT_NO_SPRINTF
+ TQString toString() const;
+#endif
+
+ bool operator==( const TQHostAddress & ) const;
+ bool isNull() const;
+
+private:
+ TQHostAddressPrivate* d;
+};
+
+#endif // USE_QT4
+
+#endif //TQT_NO_NETWORK
+#endif
diff --git a/tqtinterface/qt4/src/network/tqhttp.cpp b/tqtinterface/qt4/src/network/tqhttp.cpp
new file mode 100644
index 0000000..7d324ea
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqhttp.cpp
@@ -0,0 +1,2384 @@
+/****************************************************************************
+**
+** Implementation of TQHttp and related classes.
+**
+** Created : 970521
+**
+** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqhttp.h"
+
+#ifndef TQT_NO_NETWORKPROTOCOL_HTTP
+
+#include "tqsocket.h"
+#include "tqtextstream.h"
+#include "tqmap.h"
+#include "tqstring.h"
+#include "tqstringlist.h"
+#include "tqcstring.h"
+#include "tqbuffer.h"
+#include "tqurloperator.h"
+#include "tqtimer.h"
+#include "private/tqinternal_p.h"
+
+//#define TQHTTP_DEBUG
+
+class TQHttpPrivate
+{
+public:
+ TQHttpPrivate() :
+ state( TQHttp::Unconnected ),
+ error( TQHttp::NoError ),
+ hostname( TQString::null ),
+ port( 0 ),
+ toDevice( 0 ),
+ postDevice( 0 ),
+ bytesDone( 0 ),
+ chunkedSize( -1 ),
+ idleTimer( 0 )
+ {
+ pending.setAutoDelete( TRUE );
+ }
+
+ TQSocket socket;
+ TQPtrList<TQHttpRequest> pending;
+
+ TQHttp::State state;
+ TQHttp::Error error;
+ TQString errorString;
+
+ TQString hostname;
+ TQ_UINT16 port;
+
+ TQByteArray buffer;
+ TQIODevice* toDevice;
+ TQIODevice* postDevice;
+
+ uint bytesDone;
+ uint bytesTotal;
+ TQ_LONG chunkedSize;
+
+ TQHttpRequestHeader header;
+
+ bool readHeader;
+ TQString headerStr;
+ TQHttpResponseHeader response;
+
+ int idleTimer;
+
+ TQMembuf rba;
+};
+
+class TQHttpRequest
+{
+public:
+ TQHttpRequest()
+ {
+ id = ++idCounter;
+ }
+ virtual ~TQHttpRequest()
+ { }
+
+ virtual void start( TQHttp * ) = 0;
+ virtual bool hasRequestHeader();
+ virtual TQHttpRequestHeader requestHeader();
+
+ virtual TQIODevice* sourceDevice() = 0;
+ virtual TQIODevice* destinationDevice() = 0;
+
+ int id;
+
+private:
+ static int idCounter;
+};
+
+int TQHttpRequest::idCounter = 0;
+
+bool TQHttpRequest::hasRequestHeader()
+{
+ return FALSE;
+}
+
+TQHttpRequestHeader TQHttpRequest::requestHeader()
+{
+ return TQHttpRequestHeader();
+}
+
+/****************************************************
+ *
+ * TQHttpNormalRequest
+ *
+ ****************************************************/
+
+class TQHttpNormalRequest : public TQHttpRequest
+{
+public:
+ TQHttpNormalRequest( const TQHttpRequestHeader &h, TQIODevice *d, TQIODevice *t ) :
+ header(h), to(t)
+ {
+ is_ba = FALSE;
+ data.dev = d;
+ }
+
+ TQHttpNormalRequest( const TQHttpRequestHeader &h, TQByteArray *d, TQIODevice *t ) :
+ header(h), to(t)
+ {
+ is_ba = TRUE;
+ data.ba = d;
+ }
+
+ ~TQHttpNormalRequest()
+ {
+ if ( is_ba )
+ delete data.ba;
+ }
+
+ void start( TQHttp * );
+ bool hasRequestHeader();
+ TQHttpRequestHeader requestHeader();
+
+ TQIODevice* sourceDevice();
+ TQIODevice* destinationDevice();
+
+protected:
+ TQHttpRequestHeader header;
+
+private:
+ union {
+ TQByteArray *ba;
+ TQIODevice *dev;
+ } data;
+ bool is_ba;
+ TQIODevice *to;
+};
+
+void TQHttpNormalRequest::start( TQHttp *http )
+{
+ http->d->header = header;
+
+ if ( is_ba ) {
+ http->d->buffer = *data.ba;
+ if ( http->d->buffer.size() > 0 )
+ http->d->header.setContentLength( http->d->buffer.size() );
+
+ http->d->postDevice = 0;
+ } else {
+ http->d->buffer = TQByteArray();
+
+ if ( data.dev && ( data.dev->isOpen() || data.dev->open(IO_ReadOnly) ) ) {
+ http->d->postDevice = data.dev;
+ if ( http->d->postDevice->size() > 0 )
+ http->d->header.setContentLength( http->d->postDevice->size() );
+ } else {
+ http->d->postDevice = 0;
+ }
+ }
+
+ if ( to && ( to->isOpen() || to->open(IO_WriteOnly) ) )
+ http->d->toDevice = to;
+ else
+ http->d->toDevice = 0;
+
+ http->sendRequest();
+}
+
+bool TQHttpNormalRequest::hasRequestHeader()
+{
+ return TRUE;
+}
+
+TQHttpRequestHeader TQHttpNormalRequest::requestHeader()
+{
+ return header;
+}
+
+TQIODevice* TQHttpNormalRequest::sourceDevice()
+{
+ if ( is_ba )
+ return 0;
+ return data.dev;
+}
+
+TQIODevice* TQHttpNormalRequest::destinationDevice()
+{
+ return to;
+}
+
+/****************************************************
+ *
+ * TQHttpPGHRequest
+ * (like a TQHttpNormalRequest, but for the convenience
+ * functions put(), get() and head() -- i.e. set the
+ * host header field correctly before sending the
+ * request)
+ *
+ ****************************************************/
+
+class TQHttpPGHRequest : public TQHttpNormalRequest
+{
+public:
+ TQHttpPGHRequest( const TQHttpRequestHeader &h, TQIODevice *d, TQIODevice *t ) :
+ TQHttpNormalRequest( h, d, t )
+ { }
+
+ TQHttpPGHRequest( const TQHttpRequestHeader &h, TQByteArray *d, TQIODevice *t ) :
+ TQHttpNormalRequest( h, d, t )
+ { }
+
+ ~TQHttpPGHRequest()
+ { }
+
+ void start( TQHttp * );
+};
+
+void TQHttpPGHRequest::start( TQHttp *http )
+{
+ header.setValue( "Host", http->d->hostname );
+ TQHttpNormalRequest::start( http );
+}
+
+/****************************************************
+ *
+ * TQHttpSetHostRequest
+ *
+ ****************************************************/
+
+class TQHttpSetHostRequest : public TQHttpRequest
+{
+public:
+ TQHttpSetHostRequest( const TQString &h, TQ_UINT16 p ) :
+ hostname(h), port(p)
+ { }
+
+ void start( TQHttp * );
+
+ TQIODevice* sourceDevice()
+ { return 0; }
+ TQIODevice* destinationDevice()
+ { return 0; }
+
+private:
+ TQString hostname;
+ TQ_UINT16 port;
+};
+
+void TQHttpSetHostRequest::start( TQHttp *http )
+{
+ http->d->hostname = hostname;
+ http->d->port = port;
+ http->finishedWithSuccess();
+}
+
+/****************************************************
+ *
+ * TQHttpCloseRequest
+ *
+ ****************************************************/
+
+class TQHttpCloseRequest : public TQHttpRequest
+{
+public:
+ TQHttpCloseRequest()
+ { }
+ void start( TQHttp * );
+
+ TQIODevice* sourceDevice()
+ { return 0; }
+ TQIODevice* destinationDevice()
+ { return 0; }
+};
+
+void TQHttpCloseRequest::start( TQHttp *http )
+{
+ http->close();
+}
+
+/****************************************************
+ *
+ * TQHttpHeader
+ *
+ ****************************************************/
+
+/*!
+ \class TQHttpHeader tqhttp.h
+ \brief The TQHttpHeader class tqcontains header information for HTTP.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \module network
+
+ In most cases you should use the more specialized derivatives of
+ this class, TQHttpResponseHeader and TQHttpRequestHeader, rather
+ than directly using TQHttpHeader.
+
+ TQHttpHeader provides the HTTP header fields. A HTTP header field
+ consists of a name followed by a colon, a single space, and the
+ field value. (See RFC 1945.) Field names are case-insensitive. A
+ typical header field looks like this:
+ \code
+ content-type: text/html
+ \endcode
+
+ In the API the header field name is called the "key" and the
+ content is called the "value". You can get and set a header
+ field's value by using its key with value() and setValue(), e.g.
+ \code
+ header.setValue( "content-type", "text/html" );
+ TQString contentType = header.value( "content-type" );
+ \endcode
+
+ Some fields are so common that getters and setters are provided
+ for them as a convenient alternative to using \l value() and
+ \l setValue(), e.g. contentLength() and contentType(),
+ setContentLength() and setContentType().
+
+ Each header key has a \e single value associated with it. If you
+ set the value for a key which already exists the previous value
+ will be discarded.
+
+ \sa TQHttpRequestHeader TQHttpResponseHeader
+*/
+
+/*!
+ \fn int TQHttpHeader::majorVersion() const
+
+ Returns the major protocol-version of the HTTP header.
+*/
+
+/*!
+ \fn int TQHttpHeader::minorVersion() const
+
+ Returns the minor protocol-version of the HTTP header.
+*/
+
+/*!
+ Constructs an empty HTTP header.
+*/
+TQHttpHeader::TQHttpHeader()
+ : valid( TRUE )
+{
+}
+
+/*!
+ Constructs a copy of \a header.
+*/
+TQHttpHeader::TQHttpHeader( const TQHttpHeader& header )
+ : valid( header.valid )
+{
+ values = header.values;
+}
+
+/*!
+ Constructs a HTTP header for \a str.
+
+ This constructor parses the string \a str for header fields and
+ adds this information. The \a str should consist of one or more
+ "\r\n" delimited lines; each of these lines should have the format
+ key, colon, space, value.
+*/
+TQHttpHeader::TQHttpHeader( const TQString& str )
+ : valid( TRUE )
+{
+ parse( str );
+}
+
+/*!
+ Destructor.
+*/
+TQHttpHeader::~TQHttpHeader()
+{
+}
+
+/*!
+ Assigns \a h and returns a reference to this http header.
+*/
+TQHttpHeader& TQHttpHeader::operator=( const TQHttpHeader& h )
+{
+ values = h.values;
+ valid = h.valid;
+ return *this;
+}
+
+/*!
+ Returns TRUE if the HTTP header is valid; otherwise returns FALSE.
+
+ A TQHttpHeader is invalid if it was created by parsing a malformed string.
+*/
+bool TQHttpHeader::isValid() const
+{
+ return valid;
+}
+
+/*! \internal
+ Parses the HTTP header string \a str for header fields and adds
+ the keys/values it tqfinds. If the string is not parsed successfully
+ the TQHttpHeader becomes \link isValid() invalid\endlink.
+
+ Returns TRUE if \a str was successfully parsed; otherwise returns FALSE.
+
+ \sa toString()
+*/
+bool TQHttpHeader::parse( const TQString& str )
+{
+ TQStringList lst;
+ int pos = str.tqfind( '\n' );
+ if ( pos > 0 && str.at( pos - 1 ) == '\r' )
+ lst = TQStringList::split( "\r\n", str.stripWhiteSpace(), FALSE );
+ else
+ lst = TQStringList::split( "\n", str.stripWhiteSpace(), FALSE );
+
+ if ( lst.isEmpty() )
+ return TRUE;
+
+ TQStringList lines;
+ TQStringList::Iterator it = lst.begin();
+ for( ; it != lst.end(); ++it ) {
+ if ( !(*it).isEmpty() ) {
+ if ( (*it)[0].isSpace() ) {
+ if ( !lines.isEmpty() ) {
+ lines.last() += " ";
+ lines.last() += (*it).stripWhiteSpace();
+ }
+ } else {
+ lines.append( (*it) );
+ }
+ }
+ }
+
+ int number = 0;
+ it = lines.begin();
+ for( ; it != lines.end(); ++it ) {
+ if ( !parseLine( *it, number++ ) ) {
+ valid = FALSE;
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/*! \internal
+*/
+void TQHttpHeader::setValid( bool v )
+{
+ valid = v;
+}
+
+/*!
+ Returns the value for the entry with the given \a key. If no entry
+ has this \a key, an empty string is returned.
+
+ \sa setValue() removeValue() hasKey() keys()
+*/
+TQString TQHttpHeader::value( const TQString& key ) const
+{
+ return values[ key.lower() ];
+}
+
+/*!
+ Returns a list of the keys in the HTTP header.
+
+ \sa hasKey()
+*/
+TQStringList TQHttpHeader::keys() const
+{
+ return values.keys();
+}
+
+/*!
+ Returns TRUE if the HTTP header has an entry with the given \a
+ key; otherwise returns FALSE.
+
+ \sa value() setValue() keys()
+*/
+bool TQHttpHeader::hasKey( const TQString& key ) const
+{
+ return values.tqcontains( key.lower() );
+}
+
+/*!
+ Sets the value of the entry with the \a key to \a value.
+
+ If no entry with \a key exists, a new entry with the given \a key
+ and \a value is created. If an entry with the \a key already
+ exists, its value is discarded and tqreplaced with the given \a
+ value.
+
+ \sa value() hasKey() removeValue()
+*/
+void TQHttpHeader::setValue( const TQString& key, const TQString& value )
+{
+ values[ key.lower() ] = value;
+}
+
+/*!
+ Removes the entry with the key \a key from the HTTP header.
+
+ \sa value() setValue()
+*/
+void TQHttpHeader::removeValue( const TQString& key )
+{
+ values.remove( key.lower() );
+}
+
+/*! \internal
+ Parses the single HTTP header line \a line which has the format
+ key, colon, space, value, and adds key/value to the headers. The
+ linenumber is \a number. Returns TRUE if the line was successfully
+ parsed and the key/value added; otherwise returns FALSE.
+
+ \sa parse()
+*/
+bool TQHttpHeader::parseLine( const TQString& line, int )
+{
+ int i = line.tqfind( ":" );
+ if ( i == -1 )
+ return FALSE;
+
+ values.insert( TQT_TQSTRING(line.left( i )).stripWhiteSpace().lower(), TQT_TQSTRING(line.mid( i + 1 )).stripWhiteSpace() );
+
+ return TRUE;
+}
+
+/*!
+ Returns a string representation of the HTTP header.
+
+ The string is suitable for use by the constructor that takes a
+ TQString. It consists of lines with the format: key, colon, space,
+ value, "\r\n".
+*/
+TQString TQHttpHeader::toString() const
+{
+ if ( !isValid() )
+ return "";
+
+ TQString ret = "";
+
+ TQMap<TQString,TQString>::ConstIterator it = values.begin();
+ for( ; it != values.end(); ++it )
+ ret += it.key() + ": " + it.data() + "\r\n";
+
+ return ret;
+}
+
+/*!
+ Returns TRUE if the header has an entry for the special HTTP
+ header field \c content-length; otherwise returns FALSE.
+
+ \sa contentLength() setContentLength()
+*/
+bool TQHttpHeader::hasContentLength() const
+{
+ return hasKey( "content-length" );
+}
+
+/*!
+ Returns the value of the special HTTP header field \c
+ content-length.
+
+ \sa setContentLength() hasContentLength()
+*/
+uint TQHttpHeader::contentLength() const
+{
+ return values[ "content-length" ].toUInt();
+}
+
+/*!
+ Sets the value of the special HTTP header field \c content-length
+ to \a len.
+
+ \sa contentLength() hasContentLength()
+*/
+void TQHttpHeader::setContentLength( int len )
+{
+ values[ "content-length" ] = TQString::number( len );
+}
+
+/*!
+ Returns TRUE if the header has an entry for the the special HTTP
+ header field \c content-type; otherwise returns FALSE.
+
+ \sa contentType() setContentType()
+*/
+bool TQHttpHeader::hasContentType() const
+{
+ return hasKey( "content-type" );
+}
+
+/*!
+ Returns the value of the special HTTP header field \c content-type.
+
+ \sa setContentType() hasContentType()
+*/
+TQString TQHttpHeader::contentType() const
+{
+ TQString type = values[ "content-type" ];
+ if ( type.isEmpty() )
+ return TQString::null;
+
+ int pos = type.tqfind( ";" );
+ if ( pos == -1 )
+ return type;
+
+ return TQT_TQSTRING(type.left( pos )).stripWhiteSpace();
+}
+
+/*!
+ Sets the value of the special HTTP header field \c content-type to
+ \a type.
+
+ \sa contentType() hasContentType()
+*/
+void TQHttpHeader::setContentType( const TQString& type )
+{
+ values[ "content-type" ] = type;
+}
+
+/****************************************************
+ *
+ * TQHttpResponseHeader
+ *
+ ****************************************************/
+
+/*!
+ \class TQHttpResponseHeader tqhttp.h
+ \brief The TQHttpResponseHeader class tqcontains response header information for HTTP.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \module network
+
+ This class is used by the TQHttp class to report the header
+ information that the client received from the server.
+
+ HTTP responses have a status code that indicates the status of the
+ response. This code is a 3-digit integer result code (for details
+ see to RFC 1945). In addition to the status code, you can also
+ specify a human-readable text that describes the reason for the
+ code ("reason phrase"). This class allows you to get the status
+ code and the reason phrase.
+
+ \sa TQHttpRequestHeader TQHttp
+*/
+
+/*!
+ Constructs an empty HTTP response header.
+*/
+TQHttpResponseHeader::TQHttpResponseHeader()
+{
+ setValid( FALSE );
+}
+
+/*!
+ Constructs a HTTP response header with the status code \a code,
+ the reason phrase \a text and the protocol-version \a majorVer and
+ \a minorVer.
+*/
+TQHttpResponseHeader::TQHttpResponseHeader( int code, const TQString& text, int majorVer, int minorVer )
+ : TQHttpHeader(), statCode( code ), reasonPhr( text ), majVer( majorVer ), minVer( minorVer )
+{
+}
+
+/*!
+ Constructs a copy of \a header.
+*/
+TQHttpResponseHeader::TQHttpResponseHeader( const TQHttpResponseHeader& header )
+ : TQHttpHeader( header ), statCode( header.statCode ), reasonPhr( header.reasonPhr ), majVer( header.majVer ), minVer( header.minVer )
+{
+}
+
+/*!
+ Constructs a HTTP response header from the string \a str. The
+ string is parsed and the information is set. The \a str should
+ consist of one or more "\r\n" delimited lines; the first line should be the
+ status-line (format: HTTP-version, space, status-code, space,
+ reason-phrase); each of remaining lines should have the format key, colon,
+ space, value.
+*/
+TQHttpResponseHeader::TQHttpResponseHeader( const TQString& str )
+ : TQHttpHeader()
+{
+ parse( str );
+}
+
+/*!
+ Sets the status code to \a code, the reason phrase to \a text and
+ the protocol-version to \a majorVer and \a minorVer.
+
+ \sa statusCode() reasonPhrase() majorVersion() minorVersion()
+*/
+void TQHttpResponseHeader::setqStatusLine( int code, const TQString& text, int majorVer, int minorVer )
+{
+ setValid( TRUE );
+ statCode = code;
+ reasonPhr = text;
+ majVer = majorVer;
+ minVer = minorVer;
+}
+
+/*!
+ Returns the status code of the HTTP response header.
+
+ \sa reasonPhrase() majorVersion() minorVersion()
+*/
+int TQHttpResponseHeader::statusCode() const
+{
+ return statCode;
+}
+
+/*!
+ Returns the reason phrase of the HTTP response header.
+
+ \sa statusCode() majorVersion() minorVersion()
+*/
+TQString TQHttpResponseHeader::reasonPhrase() const
+{
+ return reasonPhr;
+}
+
+/*!
+ Returns the major protocol-version of the HTTP response header.
+
+ \sa minorVersion() statusCode() reasonPhrase()
+*/
+int TQHttpResponseHeader::majorVersion() const
+{
+ return majVer;
+}
+
+/*!
+ Returns the minor protocol-version of the HTTP response header.
+
+ \sa majorVersion() statusCode() reasonPhrase()
+*/
+int TQHttpResponseHeader::minorVersion() const
+{
+ return minVer;
+}
+
+/*! \reimp
+*/
+bool TQHttpResponseHeader::parseLine( const TQString& line, int number )
+{
+ if ( number != 0 )
+ return TQHttpHeader::parseLine( line, number );
+
+ TQString l = line.simplifyWhiteSpace();
+ if ( l.length() < 10 )
+ return FALSE;
+
+ if ( l.left( 5 ) == "HTTP/" && l[5].isDigit() && l[6] == '.' &&
+ l[7].isDigit() && l[8] == ' ' && l[9].isDigit() ) {
+ majVer = l[5].latin1() - '0';
+ minVer = l[7].latin1() - '0';
+
+ int pos = l.tqfind( ' ', 9 );
+ if ( pos != -1 ) {
+ reasonPhr = l.mid( pos + 1 );
+ statCode = l.mid( 9, pos - 9 ).toInt();
+ } else {
+ statCode = l.mid( 9 ).toInt();
+ reasonPhr = TQString::null;
+ }
+ } else {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*! \reimp
+*/
+TQString TQHttpResponseHeader::toString() const
+{
+ TQString ret( "HTTP/%1.%2 %3 %4\r\n%5\r\n" );
+ return ret.arg( majVer ).arg ( minVer ).arg( statCode ).arg( reasonPhr ).arg( TQHttpHeader::toString() );
+}
+
+/****************************************************
+ *
+ * TQHttpRequestHeader
+ *
+ ****************************************************/
+
+/*!
+ \class TQHttpRequestHeader tqhttp.h
+ \brief The TQHttpRequestHeader class tqcontains request header information for
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+ HTTP.
+\if defined(commercial_edition)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \module network
+
+ This class is used in the TQHttp class to report the header
+ information if the client requests something from the server.
+
+ HTTP requests have a method which describes the request's action.
+ The most common requests are "GET" and "POST". In addition to the
+ request method the header also includes a request-URI to specify
+ the location for the method to use.
+
+ The method, request-URI and protocol-version can be set using a
+ constructor or later using setRequest(). The values can be
+ obtained using method(), path(), majorVersion() and
+ minorVersion().
+
+ This class is a TQHttpHeader subclass so that class's functions,
+ e.g. \link TQHttpHeader::setValue() setValue()\endlink, \link
+ TQHttpHeader::value() value()\endlink, etc. are also available.
+
+ \sa TQHttpResponseHeader TQHttp
+
+ \important value() setValue()
+*/
+
+/*!
+ Constructs an empty HTTP request header.
+*/
+TQHttpRequestHeader::TQHttpRequestHeader()
+ : TQHttpHeader()
+{
+ setValid( FALSE );
+}
+
+/*!
+ Constructs a HTTP request header for the method \a method, the
+ request-URI \a path and the protocol-version \a majorVer and \a minorVer.
+*/
+TQHttpRequestHeader::TQHttpRequestHeader( const TQString& method, const TQString& path, int majorVer, int minorVer )
+ : TQHttpHeader(), m( method ), p( path ), majVer( majorVer ), minVer( minorVer )
+{
+}
+
+/*!
+ Constructs a copy of \a header.
+*/
+TQHttpRequestHeader::TQHttpRequestHeader( const TQHttpRequestHeader& header )
+ : TQHttpHeader( header ), m( header.m ), p( header.p ), majVer( header.majVer ), minVer( header.minVer )
+{
+}
+
+/*!
+ Constructs a HTTP request header from the string \a str. The \a
+ str should consist of one or more "\r\n" delimited lines; the first line
+ should be the request-line (format: method, space, request-URI, space
+ HTTP-version); each of the remaining lines should have the format key,
+ colon, space, value.
+*/
+TQHttpRequestHeader::TQHttpRequestHeader( const TQString& str )
+ : TQHttpHeader()
+{
+ parse( str );
+}
+
+/*!
+ This function sets the request method to \a method, the
+ request-URI to \a path and the protocol-version to \a majorVer and
+ \a minorVer.
+
+ \sa method() path() majorVersion() minorVersion()
+*/
+void TQHttpRequestHeader::setRequest( const TQString& method, const TQString& path, int majorVer, int minorVer )
+{
+ setValid( TRUE );
+ m = method;
+ p = path;
+ majVer = majorVer;
+ minVer = minorVer;
+}
+
+/*!
+ Returns the method of the HTTP request header.
+
+ \sa path() majorVersion() minorVersion() setRequest()
+*/
+TQString TQHttpRequestHeader::method() const
+{
+ return m;
+}
+
+/*!
+ Returns the request-URI of the HTTP request header.
+
+ \sa method() majorVersion() minorVersion() setRequest()
+*/
+TQString TQHttpRequestHeader::path() const
+{
+ return p;
+}
+
+/*!
+ Returns the major protocol-version of the HTTP request header.
+
+ \sa minorVersion() method() path() setRequest()
+*/
+int TQHttpRequestHeader::majorVersion() const
+{
+ return majVer;
+}
+
+/*!
+ Returns the minor protocol-version of the HTTP request header.
+
+ \sa majorVersion() method() path() setRequest()
+*/
+int TQHttpRequestHeader::minorVersion() const
+{
+ return minVer;
+}
+
+/*! \reimp
+*/
+bool TQHttpRequestHeader::parseLine( const TQString& line, int number )
+{
+ if ( number != 0 )
+ return TQHttpHeader::parseLine( line, number );
+
+ TQStringList lst = TQStringList::split( " ", line.simplifyWhiteSpace() );
+ if ( lst.count() > 0 ) {
+ m = lst[0];
+ if ( lst.count() > 1 ) {
+ p = lst[1];
+ if ( lst.count() > 2 ) {
+ TQString v = lst[2];
+ if ( v.length() >= 8 && v.left( 5 ) == "HTTP/" &&
+ v[5].isDigit() && v[6] == '.' && v[7].isDigit() ) {
+ majVer = v[5].latin1() - '0';
+ minVer = v[7].latin1() - '0';
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+/*! \reimp
+*/
+TQString TQHttpRequestHeader::toString() const
+{
+ TQString first( "%1 %2");
+ TQString last(" HTTP/%3.%4\r\n%5\r\n" );
+ return first.arg( m ).arg( p ) +
+ last.arg( majVer ).arg( minVer ).arg( TQHttpHeader::toString());
+}
+
+
+/****************************************************
+ *
+ * TQHttp
+ *
+ ****************************************************/
+/*!
+ \class TQHttp tqhttp.h
+ \brief The TQHttp class provides an implementation of the HTTP protocol.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \module network
+
+ This class provides two different interfaces: one is the
+ TQNetworkProtocol interface that allows you to use HTTP through the
+ TQUrlOperator abstraction. The other is a direct interface to HTTP
+ that allows you to have more control over the requests and that
+ allows you to access the response header fields.
+
+ Don't mix the two interfaces, since the behavior is not
+ well-defined.
+
+ If you want to use TQHttp with the TQNetworkProtocol interface, you
+ do not use it directly, but rather through a TQUrlOperator, for
+ example:
+
+ \code
+ TQUrlOperator op( "http://www.trolltech.com" );
+ op.get( "index.html" );
+ \endcode
+
+ This code will only work if the TQHttp class is registered; to
+ register the class, you must call qInitNetworkProtocols() before
+ using a TQUrlOperator with HTTP.
+
+ The TQNetworkProtocol interface for HTTP only supports the
+ operations operationGet() and operationPut(), i.e.
+ TQUrlOperator::get() and TQUrlOperator::put(), if you use it with a
+ TQUrlOperator.
+
+ The rest of this descrption describes the direct interface to
+ HTTP.
+
+ The class works asynchronously, so there are no blocking
+ functions. If an operation cannot be executed immediately, the
+ function will still return straight away and the operation will be
+ scheduled for later execution. The results of scheduled operations
+ are reported via Q_SIGNALS. This approach depends on the event loop
+ being in operation.
+
+ The operations that can be scheduled (they are called "requests"
+ in the rest of the documentation) are the following: setHost(),
+ get(), post(), head() and request().
+
+ All of these requests return a unique identifier that allows you
+ to keep track of the request that is currently executed. When the
+ execution of a request starts, the requestStarted() signal with
+ the identifier is emitted and when the request is finished, the
+ requestFinished() signal is emitted with the identifier and a bool
+ that indicates if the request finished with an error.
+
+ To make an HTTP request you must set up suitable HTTP headers. The
+ following example demonstrates, how to request the main HTML page
+ from the Trolltech home page (i.e. the URL
+ http://www.trolltech.com/index.html):
+
+ \code
+ TQHttpRequestHeader header( "GET", "/index.html" );
+ header.setValue( "Host", "www.trolltech.com" );
+ http->setHost( "www.trolltech.com" );
+ http->request( header );
+ \endcode
+
+ For the common HTTP requests \c GET, \c POST and \c HEAD, TQHttp
+ provides the convenience functions get(), post() and head(). They
+ already use a reasonable header and if you don't have to set
+ special header fields, they are easier to use. The above example
+ can also be written as:
+
+ \code
+ http->setHost( "www.trolltech.com" ); // id == 1
+ http->get( "/index.html" ); // id == 2
+ \endcode
+
+ For this example the following sequence of Q_SIGNALS is emitted
+ (with small variations, depending on network traffic, etc.):
+
+ \code
+ requestStarted( 1 )
+ requestFinished( 1, FALSE )
+
+ requestStarted( 2 )
+ stateChanged( Connecting )
+ stateChanged( Sending )
+ dataSendProgress( 77, 77 )
+ stateChanged( Reading )
+ responseHeaderReceived( responseheader )
+ dataReadProgress( 5388, 0 )
+ readyRead( responseheader )
+ dataReadProgress( 18300, 0 )
+ readyRead( responseheader )
+ stateChanged( Connected )
+ requestFinished( 2, FALSE )
+
+ done( FALSE )
+
+ stateChanged( Closing )
+ stateChanged( Unconnected )
+ \endcode
+
+ The dataSendProgress() and dataReadProgress() Q_SIGNALS in the above
+ example are useful if you want to show a \link TQProgressBar
+ progressbar\endlink to inform the user about the progress of the
+ download. The second argument is the total size of data. In
+ certain cases it is not possible to know the total amount in
+ advance, in which case the second argument is 0. (If you connect
+ to a TQProgressBar a total of 0 results in a busy indicator.)
+
+ When the response header is read, it is reported with the
+ responseHeaderReceived() signal.
+
+ The readyRead() signal tells you that there is data ready to be
+ read. The amount of data can then be queried with the
+ bytesAvailable() function and it can be read with the readBlock()
+ or readAll() functions.
+
+ If an error occurs during the execution of one of the commands in
+ a sequence of commands, all the pending commands (i.e. scheduled,
+ but not yet executed commands) are cleared and no Q_SIGNALS are
+ emitted for them.
+
+ For example, if you have the following sequence of reqeusts
+
+ \code
+ http->setHost( "www.foo.bar" ); // id == 1
+ http->get( "/index.html" ); // id == 2
+ http->post( "register.html", data ); // id == 3
+ \endcode
+
+ and the get() request fails because the host lookup fails, then
+ the post() request is never executed and the Q_SIGNALS would look
+ like this:
+
+ \code
+ requestStarted( 1 )
+ requestFinished( 1, FALSE )
+
+ requestStarted( 2 )
+ stateChanged( HostLookup )
+ requestFinished( 2, TRUE )
+
+ done( TRUE )
+
+ stateChanged( Unconnected )
+ \endcode
+
+ You can then get details about the error with the error() and
+ errorString() functions. Note that only unexpected behaviour, like
+ network failure is considered as an error. If the server response
+ tqcontains an error status, like a 404 response, this is reported as
+ a normal response case. So you should always check the \link
+ TQHttpResponseHeader::statusCode() status code \endlink of the
+ response header.
+
+ The functions currentId() and currentRequest() provide more
+ information about the currently executing request.
+
+ The functions hasPendingRequests() and clearPendingRequests()
+ allow you to query and clear the list of pending requests.
+
+ \sa \link network.html TQt Network Documentation \endlink TQNetworkProtocol, TQUrlOperator TQFtp
+*/
+
+/*!
+ Constructs a TQHttp object.
+*/
+TQHttp::TQHttp()
+{
+ init();
+}
+
+/*!
+ Constructs a TQHttp object. The parameters \a tqparent and \a name
+ are passed on to the TQObject constructor.
+*/
+TQHttp::TQHttp( TQObject* tqparent, const char* name )
+{
+ if ( tqparent )
+ tqparent->insertChild( this );
+ setName( name );
+ init();
+}
+
+/*!
+ Constructs a TQHttp object. Subsequent requests are done by
+ connecting to the server \a hostname on port \a port. The
+ parameters \a tqparent and \a name are passed on to the TQObject
+ constructor.
+
+ \sa setHost()
+*/
+TQHttp::TQHttp( const TQString &hostname, TQ_UINT16 port, TQObject* tqparent, const char* name )
+{
+ if ( tqparent )
+ tqparent->insertChild( this );
+ setName( name );
+ init();
+
+ d->hostname = hostname;
+ d->port = port;
+}
+
+void TQHttp::init()
+{
+ bytesRead = 0;
+ d = new TQHttpPrivate;
+ d->errorString = tr( "Unknown error" );
+
+ connect( &d->socket, TQT_SIGNAL( connected() ),
+ this, TQT_SLOT( slotConnected() ) );
+ connect( &d->socket, TQT_SIGNAL( connectionClosed() ),
+ this, TQT_SLOT( slotClosed() ) );
+ connect( &d->socket, TQT_SIGNAL( delayedCloseFinished() ),
+ this, TQT_SLOT( slotClosed() ) );
+ connect( &d->socket, TQT_SIGNAL( readyRead() ),
+ this, TQT_SLOT( slotReadyRead() ) );
+ connect( &d->socket, TQT_SIGNAL( error(int) ),
+ this, TQT_SLOT( slotError(int) ) );
+ connect( &d->socket, TQT_SIGNAL( bytesWritten(int) ),
+ this, TQT_SLOT( slotBytesWritten(int) ) );
+
+ d->idleTimer = startTimer( 0 );
+}
+
+/*!
+ Destroys the TQHttp object. If there is an open connection, it is
+ closed.
+*/
+TQHttp::~TQHttp()
+{
+ abort();
+ delete d;
+}
+
+/*!
+ \enum TQHttp::State
+
+ This enum is used to specify the state the client is in:
+
+ \value Unconnected There is no connection to the host.
+ \value HostLookup A host name lookup is in progress.
+ \value Connecting An attempt to connect to the host is in progress.
+ \value Sending The client is sending its request to the server.
+ \value Reading The client's request has been sent and the client
+ is reading the server's response.
+ \value Connected The connection to the host is open, but the client is
+ neither sending a request, nor waiting for a response.
+ \value Closing The connection is closing down, but is not yet
+ closed. (The state will be \c Unconnected when the connection is
+ closed.)
+
+ \sa stateChanged() state()
+*/
+
+/*! \enum TQHttp::Error
+
+ This enum identifies the error that occurred.
+
+ \value NoError No error occurred.
+ \value HostNotFound The host name lookup failed.
+ \value ConnectionRefused The server refused the connection.
+ \value UnexpectedClose The server closed the connection unexpectedly.
+ \value InvalidResponseHeader The server sent an invalid response header.
+ \value WrongContentLength The client could not read the content correctly
+ because an error with respect to the content length occurred.
+ \value Aborted The request was aborted with abort().
+ \value UnknownError An error other than those specified above
+ occurred.
+
+ \sa error()
+*/
+
+/*!
+ \fn void TQHttp::stateChanged( int state )
+
+ This signal is emitted when the state of the TQHttp object changes.
+ The argument \a state is the new state of the connection; it is
+ one of the \l State values.
+
+ This usually happens when a request is started, but it can also
+ happen when the server closes the connection or when a call to
+ closeConnection() succeeded.
+
+ \sa get() post() head() request() closeConnection() state() State
+*/
+
+/*!
+ \fn void TQHttp::responseHeaderReceived( const TQHttpResponseHeader& resp )
+
+ This signal is emitted when the HTTP header of a server response
+ is available. The header is passed in \a resp.
+
+ \sa get() post() head() request() readyRead()
+*/
+
+/*!
+ \fn void TQHttp::readyRead( const TQHttpResponseHeader& resp )
+
+ This signal is emitted when there is new response data to read.
+
+ If you specified a tqdevice in the request where the data should be
+ written to, then this signal is \e not emitted; instead the data
+ is written directly to the tqdevice.
+
+ The response header is passed in \a resp.
+
+ You can read the data with the readAll() or readBlock() functions
+
+ This signal is useful if you want to process the data in chunks as
+ soon as it becomes available. If you are only interested in the
+ complete data, just connect to the requestFinished() signal and
+ read the data then instead.
+
+ \sa get() post() request() readAll() readBlock() bytesAvailable()
+*/
+
+/*!
+ \fn void TQHttp::dataSendProgress( int done, int total )
+
+ This signal is emitted when this object sends data to a HTTP
+ server to inform it about the progress of the upload.
+
+ \a done is the amount of data that has already arrived and \a
+ total is the total amount of data. It is possible that the total
+ amount of data that should be transferred cannot be determined, in
+ which case \a total is 0.(If you connect to a TQProgressBar, the
+ progress bar shows a busy indicator if the total is 0).
+
+ \warning \a done and \a total are not necessarily the size in
+ bytes, since for large files these values might need to be
+ "scaled" to avoid overflow.
+
+ \sa dataReadProgress() post() request() TQProgressBar::setProgress()
+*/
+
+/*!
+ \fn void TQHttp::dataReadProgress( int done, int total )
+
+ This signal is emitted when this object reads data from a HTTP
+ server to indicate the current progress of the download.
+
+ \a done is the amount of data that has already arrived and \a
+ total is the total amount of data. It is possible that the total
+ amount of data that should be transferred cannot be determined, in
+ which case \a total is 0.(If you connect to a TQProgressBar, the
+ progress bar shows a busy indicator if the total is 0).
+
+ \warning \a done and \a total are not necessarily the size in
+ bytes, since for large files these values might need to be
+ "scaled" to avoid overflow.
+
+ \sa dataSendProgress() get() post() request() TQProgressBar::setProgress()
+*/
+
+/*!
+ \fn void TQHttp::requestStarted( int id )
+
+ This signal is emitted when processing the request identified by
+ \a id starts.
+
+ \sa requestFinished() done()
+*/
+
+/*!
+ \fn void TQHttp::requestFinished( int id, bool error )
+
+ This signal is emitted when processing the request identified by
+ \a id has finished. \a error is TRUE if an error occurred during
+ the processing; otherwise \a error is FALSE.
+
+ \sa requestStarted() done() error() errorString()
+*/
+
+/*!
+ \fn void TQHttp::done( bool error )
+
+ This signal is emitted when the last pending request has finished;
+ (it is emitted after the last request's requestFinished() signal).
+ \a error is TRUE if an error occurred during the processing;
+ otherwise \a error is FALSE.
+
+ \sa requestFinished() error() errorString()
+*/
+
+/*!
+ Aborts the current request and deletes all scheduled requests.
+
+ For the current request, the requestFinished() signal with the \c
+ error argument \c TRUE is emitted. For all other requests that are
+ affected by the abort(), no Q_SIGNALS are emitted.
+
+ Since this slot also deletes the scheduled requests, there are no
+ requests left and the done() signal is emitted (with the \c error
+ argument \c TRUE).
+
+ \sa clearPendingRequests()
+*/
+void TQHttp::abort()
+{
+ TQHttpRequest *r = d->pending.getFirst();
+ if ( r == 0 )
+ return;
+
+ finishedWithError( tr("Request aborted"), Aborted );
+ clearPendingRequests();
+ d->socket.clearPendingData();
+ close();
+}
+
+/*!
+ Returns the number of bytes that can be read from the response
+ content at the moment.
+
+ \sa get() post() request() readyRead() readBlock() readAll()
+*/
+TQ_ULONG TQHttp::bytesAvailable() const
+{
+#if defined(TQHTTP_DEBUG)
+ qDebug( "TQHttp::bytesAvailable(): %d bytes", (int)d->rba.size() );
+#endif
+ return d->rba.size();
+}
+
+/*!
+ Reads \a maxlen bytes from the response content into \a data and
+ returns the number of bytes read. Returns -1 if an error occurred.
+
+ \sa get() post() request() readyRead() bytesAvailable() readAll()
+*/
+TQ_LONG TQHttp::readBlock( char *data, TQ_ULONG maxlen )
+{
+ if ( data == 0 && maxlen != 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQHttp::readBlock: Null pointer error" );
+#endif
+ return -1;
+ }
+ if ( maxlen >= d->rba.size() )
+ maxlen = d->rba.size();
+ d->rba.consumeBytes( maxlen, data );
+
+ d->bytesDone += maxlen;
+#if defined(TQHTTP_DEBUG)
+ qDebug( "TQHttp::readBlock(): read %d bytes (%d bytes done)", (int)maxlen, d->bytesDone );
+#endif
+ return maxlen;
+}
+
+/*!
+ Reads all the bytes from the response content and returns them.
+
+ \sa get() post() request() readyRead() bytesAvailable() readBlock()
+*/
+TQByteArray TQHttp::readAll()
+{
+ TQ_ULONG avail = bytesAvailable();
+ TQByteArray tmp( avail );
+ TQ_LONG read = readBlock( tmp.data(), avail );
+ tmp.resize( read );
+ return tmp;
+}
+
+/*!
+ Returns the identifier of the HTTP request being executed or 0 if
+ there is no request being executed (i.e. they've all finished).
+
+ \sa currentRequest()
+*/
+int TQHttp::currentId() const
+{
+ TQHttpRequest *r = d->pending.getFirst();
+ if ( r == 0 )
+ return 0;
+ return r->id;
+}
+
+/*!
+ Returns the request header of the HTTP request being executed. If
+ the request is one issued by setHost() or closeConnection(), it
+ returns an invalid request header, i.e.
+ TQHttpRequestHeader::isValid() returns FALSE.
+
+ \sa currentId()
+*/
+TQHttpRequestHeader TQHttp::currentRequest() const
+{
+ TQHttpRequest *r = d->pending.getFirst();
+ if ( r != 0 && r->hasRequestHeader() )
+ return r->requestHeader();
+ return TQHttpRequestHeader();
+}
+
+/*!
+ Returns the TQIODevice pointer that is used as the data source of the HTTP
+ request being executed. If there is no current request or if the request
+ does not use an IO tqdevice as the data source, this function returns 0.
+
+ This function can be used to delete the TQIODevice in the slot connected to
+ the requestFinished() signal.
+
+ \sa currentDestinationDevice() post() request()
+*/
+TQIODevice* TQHttp::currentSourceDevice() const
+{
+ TQHttpRequest *r = d->pending.getFirst();
+ if ( !r )
+ return 0;
+ return r->sourceDevice();
+}
+
+/*!
+ Returns the TQIODevice pointer that is used as to store the data of the HTTP
+ request being executed. If there is no current request or if the request
+ does not store the data to an IO tqdevice, this function returns 0.
+
+ This function can be used to delete the TQIODevice in the slot connected to
+ the requestFinished() signal.
+
+ \sa currentDestinationDevice() get() post() request()
+*/
+TQIODevice* TQHttp::currentDestinationDevice() const
+{
+ TQHttpRequest *r = d->pending.getFirst();
+ if ( !r )
+ return 0;
+ return r->destinationDevice();
+}
+
+/*!
+ Returns TRUE if there are any requests scheduled that have not yet
+ been executed; otherwise returns FALSE.
+
+ The request that is being executed is \e not considered as a
+ scheduled request.
+
+ \sa clearPendingRequests() currentId() currentRequest()
+*/
+bool TQHttp::hasPendingRequests() const
+{
+ return d->pending.count() > 1;
+}
+
+/*!
+ Deletes all pending requests from the list of scheduled requests.
+ This does not affect the request that is being executed. If
+ you want to stop this this as well, use abort().
+
+ \sa hasPendingRequests() abort()
+*/
+void TQHttp::clearPendingRequests()
+{
+ TQHttpRequest *r = 0;
+ if ( d->pending.count() > 0 )
+ r = d->pending.take( 0 );
+ d->pending.clear();
+ if ( r )
+ d->pending.append( r );
+}
+
+/*!
+ Sets the HTTP server that is used for requests to \a hostname on
+ port \a port.
+
+ The function does not block and returns immediately. The request
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ requestStarted() and requestFinished().
+
+ When the request is started the requestStarted() signal is
+ emitted. When it is finished the requestFinished() signal is
+ emitted.
+
+ \sa get() post() head() request() requestStarted() requestFinished() done()
+*/
+int TQHttp::setHost(const TQString &hostname, TQ_UINT16 port )
+{
+ return addRequest( new TQHttpSetHostRequest( hostname, port ) );
+}
+
+/*!
+ Sends a get request for \a path to the server set by setHost() or
+ as specified in the constructor.
+
+ \a path must be an absolute path like \c /index.html or an
+ absolute URI like \c http://www.trolltech.com/index.html.
+
+ If the IO tqdevice \a to is 0 the readyRead() signal is emitted
+ every time new content data is available to read.
+
+ If the IO tqdevice \a to is not 0, the content data of the response
+ is written directly to the tqdevice. Make sure that the \a to
+ pointer is valid for the duration of the operation (it is safe to
+ delete it when the requestFinished() signal is emitted).
+
+ The function does not block and returns immediately. The request
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ requestStarted() and requestFinished().
+
+ When the request is started the requestStarted() signal is
+ emitted. When it is finished the requestFinished() signal is
+ emitted.
+
+ \sa setHost() post() head() request() requestStarted() requestFinished() done()
+*/
+int TQHttp::get( const TQString& path, TQIODevice* to )
+{
+ TQHttpRequestHeader header( "GET", path );
+ header.setValue( "Connection", "Keep-Alive" );
+ return addRequest( new TQHttpPGHRequest( header, (TQIODevice*)0, to ) );
+}
+
+/*!
+ Sends a post request for \a path to the server set by setHost() or
+ as specified in the constructor.
+
+ \a path must be an absolute path like \c /index.html or an
+ absolute URI like \c http://www.trolltech.com/index.html.
+
+ The incoming data comes via the \a data IO tqdevice.
+
+ If the IO tqdevice \a to is 0 the readyRead() signal is emitted
+ every time new content data is available to read.
+
+ If the IO tqdevice \a to is not 0, the content data of the response
+ is written directly to the tqdevice. Make sure that the \a to
+ pointer is valid for the duration of the operation (it is safe to
+ delete it when the requestFinished() signal is emitted).
+
+ The function does not block and returns immediately. The request
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ requestStarted() and requestFinished().
+
+ When the request is started the requestStarted() signal is
+ emitted. When it is finished the requestFinished() signal is
+ emitted.
+
+ \sa setHost() get() head() request() requestStarted() requestFinished() done()
+*/
+int TQHttp::post( const TQString& path, TQIODevice* data, TQIODevice* to )
+{
+ TQHttpRequestHeader header( "POST", path );
+ header.setValue( "Connection", "Keep-Alive" );
+ return addRequest( new TQHttpPGHRequest( header, data, to ) );
+}
+
+/*!
+ \overload
+
+ \a data is used as the content data of the HTTP request.
+*/
+int TQHttp::post( const TQString& path, const TQByteArray& data, TQIODevice* to )
+{
+ TQHttpRequestHeader header( "POST", path );
+ header.setValue( "Connection", "Keep-Alive" );
+ return addRequest( new TQHttpPGHRequest( header, new TQByteArray(data), to ) );
+}
+
+/*!
+ Sends a header request for \a path to the server set by setHost()
+ or as specified in the constructor.
+
+ \a path must be an absolute path like \c /index.html or an
+ absolute URI like \c http://www.trolltech.com/index.html.
+
+ The function does not block and returns immediately. The request
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ requestStarted() and requestFinished().
+
+ When the request is started the requestStarted() signal is
+ emitted. When it is finished the requestFinished() signal is
+ emitted.
+
+ \sa setHost() get() post() request() requestStarted() requestFinished() done()
+*/
+int TQHttp::head( const TQString& path )
+{
+ TQHttpRequestHeader header( "HEAD", path );
+ header.setValue( "Connection", "Keep-Alive" );
+ return addRequest( new TQHttpPGHRequest( header, (TQIODevice*)0, 0 ) );
+}
+
+/*!
+ Sends a request to the server set by setHost() or as specified in
+ the constructor. Uses the \a header as the HTTP request header.
+ You are responsible for setting up a header that is appropriate
+ for your request.
+
+ The incoming data comes via the \a data IO tqdevice.
+
+ If the IO tqdevice \a to is 0 the readyRead() signal is emitted
+ every time new content data is available to read.
+
+ If the IO tqdevice \a to is not 0, the content data of the response
+ is written directly to the tqdevice. Make sure that the \a to
+ pointer is valid for the duration of the operation (it is safe to
+ delete it when the requestFinished() signal is emitted).
+
+ The function does not block and returns immediately. The request
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ requestStarted() and requestFinished().
+
+ When the request is started the requestStarted() signal is
+ emitted. When it is finished the requestFinished() signal is
+ emitted.
+
+ \sa setHost() get() post() head() requestStarted() requestFinished() done()
+*/
+int TQHttp::request( const TQHttpRequestHeader &header, TQIODevice *data, TQIODevice *to )
+{
+ return addRequest( new TQHttpNormalRequest( header, data, to ) );
+}
+
+/*!
+ \overload
+
+ \a data is used as the content data of the HTTP request.
+*/
+int TQHttp::request( const TQHttpRequestHeader &header, const TQByteArray &data, TQIODevice *to )
+{
+ return addRequest( new TQHttpNormalRequest( header, new TQByteArray(data), to ) );
+}
+
+/*!
+ Closes the connection; this is useful if you have a keep-alive
+ connection and want to close it.
+
+ For the requests issued with get(), post() and head(), TQHttp sets
+ the connection to be keep-alive. You can also do this using the
+ header you pass to the request() function. TQHttp only closes the
+ connection to the HTTP server if the response header requires it
+ to do so.
+
+ The function does not block and returns immediately. The request
+ is scheduled, and its execution is performed asynchronously. The
+ function returns a unique identifier which is passed by
+ requestStarted() and requestFinished().
+
+ When the request is started the requestStarted() signal is
+ emitted. When it is finished the requestFinished() signal is
+ emitted.
+
+ If you want to close the connection immediately, you have to use
+ abort() instead.
+
+ \sa stateChanged() abort() requestStarted() requestFinished() done()
+*/
+int TQHttp::closeConnection()
+{
+ return addRequest( new TQHttpCloseRequest() );
+}
+
+int TQHttp::addRequest( TQHttpRequest *req )
+{
+ d->pending.append( req );
+
+ if ( d->pending.count() == 1 )
+ // don't emit the requestStarted() signal before the id is returned
+ TQTimer::singleShot( 0, this, TQT_SLOT(startNextRequest()) );
+
+ return req->id;
+}
+
+void TQHttp::startNextRequest()
+{
+ TQHttpRequest *r = d->pending.getFirst();
+ if ( r == 0 )
+ return;
+
+ d->error = NoError;
+ d->errorString = tr( "Unknown error" );
+
+ if ( bytesAvailable() )
+ readAll(); // clear the data
+ emit requestStarted( r->id );
+ r->start( this );
+}
+
+void TQHttp::sendRequest()
+{
+ if ( d->hostname.isNull() ) {
+ finishedWithError( tr("No server set to connect to"), UnknownError );
+ return;
+ }
+
+ killIdleTimer();
+
+ // Do we need to setup a new connection or can we reuse an
+ // existing one ?
+ if ( d->socket.peerName() != d->hostname || d->socket.peerPort() != d->port
+ || d->socket.state() != TQSocket::Connection ) {
+ setState( TQHttp::Connecting );
+ d->socket.connectToHost( d->hostname, d->port );
+ } else {
+ slotConnected();
+ }
+
+}
+
+void TQHttp::finishedWithSuccess()
+{
+ TQHttpRequest *r = d->pending.getFirst();
+ if ( r == 0 )
+ return;
+
+ emit requestFinished( r->id, FALSE );
+ d->pending.removeFirst();
+ if ( d->pending.isEmpty() ) {
+ emit done( FALSE );
+ } else {
+ startNextRequest();
+ }
+}
+
+void TQHttp::finishedWithError( const TQString& detail, int errorCode )
+{
+ TQHttpRequest *r = d->pending.getFirst();
+ if ( r == 0 )
+ return;
+
+ d->error = (Error)errorCode;
+ d->errorString = detail;
+ emit requestFinished( r->id, TRUE );
+
+ d->pending.clear();
+ emit done( TRUE );
+}
+
+void TQHttp::slotClosed()
+{
+ if ( d->state == Closing )
+ return;
+
+ if ( d->state == Reading ) {
+ if ( d->response.hasKey( "content-length" ) ) {
+ // We got Content-Length, so did we get all bytes?
+ if ( d->bytesDone+bytesAvailable() != d->response.contentLength() ) {
+ finishedWithError( tr("Wrong content length"), WrongContentLength );
+ }
+ }
+ } else if ( d->state == Connecting || d->state == Sending ) {
+ finishedWithError( tr("Server closed connection unexpectedly"), UnexpectedClose );
+ }
+
+ d->postDevice = 0;
+ setState( Closing );
+ d->idleTimer = startTimer( 0 );
+}
+
+void TQHttp::slotConnected()
+{
+ if ( d->state != Sending ) {
+ d->bytesDone = 0;
+ setState( Sending );
+ }
+
+ TQString str = d->header.toString();
+ d->bytesTotal = str.length();
+ d->socket.writeBlock( str.latin1(), d->bytesTotal );
+#if defined(TQHTTP_DEBUG)
+ qDebug( "TQHttp: write request header:\n---{\n%s}---", str.latin1() );
+#endif
+
+ if ( d->postDevice ) {
+ d->bytesTotal += d->postDevice->size();
+ } else {
+ d->bytesTotal += d->buffer.size();
+ d->socket.writeBlock( d->buffer.data(), d->buffer.size() );
+ d->buffer = TQByteArray(); // save memory
+ }
+}
+
+void TQHttp::slotError( int err )
+{
+ d->postDevice = 0;
+
+ if ( d->state == Connecting || d->state == Reading || d->state == Sending ) {
+ switch ( err ) {
+ case TQSocket::ErrConnectionRefused:
+ finishedWithError( tr("Connection refused"), ConnectionRefused );
+ break;
+ case TQSocket::ErrHostNotFound:
+ finishedWithError( tr("Host %1 not found").arg(d->socket.peerName()), HostNotFound );
+ break;
+ default:
+ finishedWithError( tr("HTTP request failed"), UnknownError );
+ break;
+ }
+ }
+
+ close();
+}
+
+void TQHttp::slotBytesWritten( int written )
+{
+ d->bytesDone += written;
+ emit dataSendProgress( d->bytesDone, d->bytesTotal );
+
+ if ( !d->postDevice )
+ return;
+
+ if ( d->socket.bytesToWrite() == 0 ) {
+ int max = TQMIN( 4096, d->postDevice->size() - d->postDevice->at() );
+ TQByteArray arr( max );
+
+ int n = d->postDevice->readBlock( arr.data(), max );
+ if ( n != max ) {
+ qWarning("Could not read enough bytes from the tqdevice");
+ close();
+ return;
+ }
+ if ( d->postDevice->atEnd() ) {
+ d->postDevice = 0;
+ }
+
+ d->socket.writeBlock( arr.data(), max );
+ }
+}
+
+void TQHttp::slotReadyRead()
+{
+ if ( d->state != Reading ) {
+ setState( Reading );
+ d->buffer = TQByteArray();
+ d->readHeader = TRUE;
+ d->headerStr = "";
+ d->bytesDone = 0;
+ d->chunkedSize = -1;
+ }
+
+ while ( d->readHeader ) {
+ bool end = FALSE;
+ TQString tmp;
+ while ( !end && d->socket.canReadLine() ) {
+ tmp = d->socket.readLine();
+ if ( tmp == "\r\n" || tmp == "\n" )
+ end = TRUE;
+ else
+ d->headerStr += tmp;
+ }
+
+ if ( !end )
+ return;
+
+#if defined(TQHTTP_DEBUG)
+ qDebug( "TQHttp: read response header:\n---{\n%s}---", d->headerStr.latin1() );
+#endif
+ d->response = TQHttpResponseHeader( d->headerStr );
+ d->headerStr = "";
+#if defined(TQHTTP_DEBUG)
+ qDebug( "TQHttp: read response header:\n---{\n%s}---", d->response.toString().latin1() );
+#endif
+ // Check header
+ if ( !d->response.isValid() ) {
+ finishedWithError( tr("Invalid HTTP response header"), InvalidResponseHeader );
+ close();
+ return;
+ }
+
+ // The 100-continue header is ignored, because when using the
+ // POST method, we send both the request header and data in
+ // one chunk.
+ if (d->response.statusCode() != 100) {
+ d->readHeader = FALSE;
+ if ( d->response.hasKey( "transfer-encoding" ) &&
+ d->response.value( "transfer-encoding" ).lower().tqcontains( "chunked" ) )
+ d->chunkedSize = 0;
+
+ emit responseHeaderReceived( d->response );
+ }
+ }
+
+ if ( !d->readHeader ) {
+ bool everythingRead = FALSE;
+
+ if ( currentRequest().method() == "HEAD" ) {
+ everythingRead = TRUE;
+ } else {
+ TQ_ULONG n = d->socket.bytesAvailable();
+ TQByteArray *arr = 0;
+ if ( d->chunkedSize != -1 ) {
+ // transfer-encoding is chunked
+ for ( ;; ) {
+ // get chunk size
+ if ( d->chunkedSize == 0 ) {
+ if ( !d->socket.canReadLine() )
+ break;
+ TQString sizeString = d->socket.readLine();
+ int tPos = sizeString.tqfind( ';' );
+ if ( tPos != -1 )
+ sizeString.truncate( tPos );
+ bool ok;
+ d->chunkedSize = sizeString.toInt( &ok, 16 );
+ if ( !ok ) {
+ finishedWithError( tr("Invalid HTTP chunked body"), WrongContentLength );
+ close();
+ delete arr;
+ return;
+ }
+ if ( d->chunkedSize == 0 ) // last-chunk
+ d->chunkedSize = -2;
+ }
+
+ // read trailer
+ while ( d->chunkedSize == -2 && d->socket.canReadLine() ) {
+ TQString read = d->socket.readLine();
+ if ( read == "\r\n" || read == "\n" )
+ d->chunkedSize = -1;
+ }
+ if ( d->chunkedSize == -1 ) {
+ everythingRead = TRUE;
+ break;
+ }
+
+ // make sure that you can read the terminating CRLF,
+ // otherwise wait until next time...
+ n = d->socket.bytesAvailable();
+ if ( n == 0 )
+ break;
+ if ( (TQ_LONG)n == d->chunkedSize || (TQ_LONG)n == d->chunkedSize+1 ) {
+ n = d->chunkedSize - 1;
+ if ( n == 0 )
+ break;
+ }
+
+ // read data
+ uint toRead = TQMIN( (TQ_LONG)n, (d->chunkedSize < 0 ? (TQ_LONG)n : d->chunkedSize) );
+ if ( !arr )
+ arr = new TQByteArray( 0 );
+ uint oldArrSize = arr->size();
+ arr->resize( oldArrSize + toRead );
+ TQ_LONG read = d->socket.readBlock( arr->data()+oldArrSize, toRead );
+ arr->resize( oldArrSize + read );
+
+ d->chunkedSize -= read;
+
+ if ( d->chunkedSize == 0 && n - read >= 2 ) {
+ // read terminating CRLF
+ char tmp[2];
+ d->socket.readBlock( tmp, 2 );
+ if ( tmp[0] != '\r' || tmp[1] != '\n' ) {
+ finishedWithError( tr("Invalid HTTP chunked body"), WrongContentLength );
+ close();
+ return;
+ }
+ }
+ }
+ } else if ( d->response.hasContentLength() ) {
+ n = TQMIN( d->response.contentLength() - d->bytesDone, n );
+ if ( n > 0 ) {
+ arr = new TQByteArray( n );
+ TQ_LONG read = d->socket.readBlock( arr->data(), n );
+ arr->resize( read );
+ }
+ if ( d->bytesDone + bytesAvailable() + n == d->response.contentLength() )
+ everythingRead = TRUE;
+ } else if ( n > 0 ) {
+ // workaround for VC++ bug
+ TQByteArray temp = TQT_TQBYTEARRAY_OBJECT(d->socket.readAll());
+ arr = new TQByteArray( temp );
+ }
+
+ if ( arr ) {
+ n = arr->size();
+ if ( d->toDevice ) {
+ d->toDevice->writeBlock( arr->data(), n );
+ delete arr;
+ d->bytesDone += n;
+#if defined(TQHTTP_DEBUG)
+ qDebug( "TQHttp::slotReadyRead(): read %ld bytes (%d bytes done)", n, d->bytesDone );
+#endif
+ if ( d->response.hasContentLength() )
+ emit dataReadProgress( d->bytesDone, d->response.contentLength() );
+ else
+ emit dataReadProgress( d->bytesDone, 0 );
+ } else {
+ d->rba.append( arr );
+#if defined(TQHTTP_DEBUG)
+ qDebug( "TQHttp::slotReadyRead(): read %ld bytes (%ld bytes done)", n, d->bytesDone + bytesAvailable() );
+#endif
+ if ( d->response.hasContentLength() )
+ emit dataReadProgress( d->bytesDone + bytesAvailable(), d->response.contentLength() );
+ else
+ emit dataReadProgress( d->bytesDone + bytesAvailable(), 0 );
+ emit readyRead( d->response );
+ }
+ }
+ }
+
+ if ( everythingRead ) {
+ // Handle "Connection: close"
+ if ( d->response.value("connection").lower() == "close" ) {
+ close();
+ } else {
+ setState( Connected );
+ // Start a timer, so that we emit the keep alive signal
+ // "after" this method returned.
+ d->idleTimer = startTimer( 0 );
+ }
+ }
+ }
+}
+
+/*!
+ Returns the current state of the object. When the state changes,
+ the stateChanged() signal is emitted.
+
+ \sa State stateChanged()
+*/
+TQHttp::State TQHttp::state() const
+{
+ return d->state;
+}
+
+/*!
+ Returns the last error that occurred. This is useful to tqfind out
+ what happened when receiving a requestFinished() or a done()
+ signal with the \c error argument \c TRUE.
+
+ If you start a new request, the error status is reset to \c NoError.
+*/
+TQHttp::Error TQHttp::error() const
+{
+ return d->error;
+}
+
+/*!
+ Returns a human-readable description of the last error that
+ occurred. This is useful to present a error message to the user
+ when receiving a requestFinished() or a done() signal with the \c
+ error argument \c TRUE.
+*/
+TQString TQHttp::errorString() const
+{
+ return d->errorString;
+}
+
+/*! \reimp
+*/
+void TQHttp::timerEvent( TQTimerEvent *e )
+{
+ if ( e->timerId() == d->idleTimer ) {
+ killTimer( d->idleTimer );
+ d->idleTimer = 0;
+
+ if ( d->state == Connected ) {
+ finishedWithSuccess();
+ } else if ( d->state != Unconnected ) {
+ setState( Unconnected );
+ finishedWithSuccess();
+ }
+ } else {
+ TQObject::timerEvent( e );
+ }
+}
+
+void TQHttp::killIdleTimer()
+{
+ killTimer( d->idleTimer );
+ d->idleTimer = 0;
+}
+
+void TQHttp::setState( int s )
+{
+#if defined(TQHTTP_DEBUG)
+ qDebug( "TQHttp state changed %d -> %d", d->state, s );
+#endif
+ d->state = (State)s;
+ emit stateChanged( s );
+}
+
+void TQHttp::close()
+{
+ // If no connection is open -> ignore
+ if ( d->state == Closing || d->state == Unconnected )
+ return;
+
+ d->postDevice = 0;
+ setState( Closing );
+
+ // Already closed ?
+ if ( !d->socket.isOpen() ) {
+ d->idleTimer = startTimer( 0 );
+ } else {
+ // Close now.
+ d->socket.close();
+
+ // Did close succeed immediately ?
+ if ( d->socket.state() == TQSocket::Idle ) {
+ // Prepare to emit the requestFinished() signal.
+ d->idleTimer = startTimer( 0 );
+ }
+ }
+}
+
+/**********************************************************************
+ *
+ * TQHttp implementation of the TQNetworkProtocol interface
+ *
+ *********************************************************************/
+/*! \reimp
+*/
+int TQHttp::supportedOperations() const
+{
+ return OpGet | OpPut;
+}
+
+/*! \reimp
+*/
+void TQHttp::operationGet( TQNetworkOperation *op )
+{
+ connect( this, TQT_SIGNAL(readyRead(const TQHttpResponseHeader&)),
+ this, TQT_SLOT(clientReply(const TQHttpResponseHeader&)) );
+ connect( this, TQT_SIGNAL(done(bool)),
+ this, TQT_SLOT(clientDone(bool)) );
+ connect( this, TQT_SIGNAL(stateChanged(int)),
+ this, TQT_SLOT(clientStateChanged(int)) );
+
+ bytesRead = 0;
+ op->setState( StInProgress );
+ TQUrl u( operationInProgress()->arg( 0 ) );
+ TQHttpRequestHeader header( "GET", u.encodedPathAndQuery(), 1, 0 );
+ header.setValue( "Host", u.host() );
+ setHost( u.host(), u.port() != -1 ? u.port() : 80 );
+ request( header );
+}
+
+/*! \reimp
+*/
+void TQHttp::operationPut( TQNetworkOperation *op )
+{
+ connect( this, TQT_SIGNAL(readyRead(const TQHttpResponseHeader&)),
+ this, TQT_SLOT(clientReply(const TQHttpResponseHeader&)) );
+ connect( this, TQT_SIGNAL(done(bool)),
+ this, TQT_SLOT(clientDone(bool)) );
+ connect( this, TQT_SIGNAL(stateChanged(int)),
+ this, TQT_SLOT(clientStateChanged(int)) );
+
+ bytesRead = 0;
+ op->setState( StInProgress );
+ TQUrl u( operationInProgress()->arg( 0 ) );
+ TQHttpRequestHeader header( "POST", u.encodedPathAndQuery(), 1, 0 );
+ header.setValue( "Host", u.host() );
+ setHost( u.host(), u.port() != -1 ? u.port() : 80 );
+ request( header, op->rawArg(1) );
+}
+
+void TQHttp::clientReply( const TQHttpResponseHeader &rep )
+{
+ TQNetworkOperation *op = operationInProgress();
+ if ( op ) {
+ if ( rep.statusCode() >= 400 && rep.statusCode() < 600 ) {
+ op->setState( StFailed );
+ op->setProtocolDetail(
+ TQString("%1 %2").arg(rep.statusCode()).arg(rep.reasonPhrase())
+ );
+ switch ( rep.statusCode() ) {
+ case 401:
+ case 403:
+ case 405:
+ op->setErrorCode( ErrPermissionDenied );
+ break;
+ case 404:
+ op->setErrorCode(ErrFileNotExisting );
+ break;
+ default:
+ if ( op->operation() == OpGet )
+ op->setErrorCode( ErrGet );
+ else
+ op->setErrorCode( ErrPut );
+ break;
+ }
+ }
+ // ### In cases of an error, should we still emit the data() Q_SIGNALS?
+ if ( op->operation() == OpGet && bytesAvailable() > 0 ) {
+ TQByteArray ba = readAll();
+ emit data( ba, op );
+ bytesRead += ba.size();
+ if ( rep.hasContentLength() ) {
+ emit dataTransferProgress( bytesRead, rep.contentLength(), op );
+ }
+ }
+ }
+}
+
+void TQHttp::clientDone( bool err )
+{
+ disconnect( this, TQT_SIGNAL(readyRead(const TQHttpResponseHeader&)),
+ this, TQT_SLOT(clientReply(const TQHttpResponseHeader&)) );
+ disconnect( this, TQT_SIGNAL(done(bool)),
+ this, TQT_SLOT(clientDone(bool)) );
+ disconnect( this, TQT_SIGNAL(stateChanged(int)),
+ this, TQT_SLOT(clientStateChanged(int)) );
+
+ if ( err ) {
+ TQNetworkOperation *op = operationInProgress();
+ if ( op ) {
+ op->setState( TQNetworkProtocol::StFailed );
+ op->setProtocolDetail( errorString() );
+ switch ( error() ) {
+ case ConnectionRefused:
+ op->setErrorCode( ErrHostNotFound );
+ break;
+ case HostNotFound:
+ op->setErrorCode( ErrHostNotFound );
+ break;
+ default:
+ if ( op->operation() == OpGet )
+ op->setErrorCode( ErrGet );
+ else
+ op->setErrorCode( ErrPut );
+ break;
+ }
+ emit finished( op );
+ }
+ } else {
+ TQNetworkOperation *op = operationInProgress();
+ if ( op ) {
+ if ( op->state() != StFailed ) {
+ op->setState( TQNetworkProtocol::StDone );
+ op->setErrorCode( TQNetworkProtocol::NoError );
+ }
+ emit finished( op );
+ }
+ }
+
+}
+
+void TQHttp::clientStateChanged( int state )
+{
+ if ( url() ) {
+ switch ( (State)state ) {
+ case Connecting:
+ emit connectionStateChanged( ConHostFound, tr( "Host %1 found" ).arg( url()->host() ) );
+ break;
+ case Sending:
+ emit connectionStateChanged( ConConnected, tr( "Connected to host %1" ).arg( url()->host() ) );
+ break;
+ case Unconnected:
+ emit connectionStateChanged( ConClosed, tr( "Connection to %1 closed" ).arg( url()->host() ) );
+ break;
+ default:
+ break;
+ }
+ } else {
+ switch ( (State)state ) {
+ case Connecting:
+ emit connectionStateChanged( ConHostFound, tr( "Host found" ) );
+ break;
+ case Sending:
+ emit connectionStateChanged( ConConnected, tr( "Connected to host" ) );
+ break;
+ case Unconnected:
+ emit connectionStateChanged( ConClosed, tr( "Connection closed" ) );
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/network/tqhttp.h b/tqtinterface/qt4/src/network/tqhttp.h
new file mode 100644
index 0000000..37ab916
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqhttp.h
@@ -0,0 +1,278 @@
+/****************************************************************************
+**
+** Definition of TQHttp and related classes.
+**
+** Created : 970521
+**
+** Copyright (C) 1997-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQHTTP_H
+#define TQHTTP_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqnetworkprotocol.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
+#define TQM_EXPORT_HTTP
+#define TQM_TEMPLATE_EXTERN_HTTP
+#else
+#define TQM_EXPORT_HTTP TQ_EXPORT
+#define TQM_TEMPLATE_EXTERN_HTTP TQ_TEMPLATE_EXTERN
+#endif
+
+#ifndef TQT_NO_NETWORKPROTOCOL_HTTP
+
+class TQSocket;
+class TQTimerEvent;
+class TQTextStream;
+class TQIODevice;
+
+class TQHttpPrivate;
+class TQHttpRequest;
+
+class TQM_EXPORT_HTTP TQHttpHeader
+{
+public:
+ TQHttpHeader();
+ TQHttpHeader( const TQHttpHeader& header );
+ TQHttpHeader( const TQString& str );
+ virtual ~TQHttpHeader();
+
+ TQHttpHeader& operator=( const TQHttpHeader& h );
+
+ TQString value( const TQString& key ) const;
+ void setValue( const TQString& key, const TQString& value );
+ void removeValue( const TQString& key );
+
+ TQStringList keys() const;
+ bool hasKey( const TQString& key ) const;
+
+ bool hasContentLength() const;
+ uint contentLength() const;
+ void setContentLength( int len );
+
+ bool hasContentType() const;
+ TQString contentType() const;
+ void setContentType( const TQString& type );
+
+ virtual TQString toString() const;
+ bool isValid() const;
+
+ virtual int majorVersion() const = 0;
+ virtual int minorVersion() const = 0;
+
+protected:
+ virtual bool parseLine( const TQString& line, int number );
+ bool parse( const TQString& str );
+ void setValid( bool );
+
+private:
+ TQMap<TQString,TQString> values;
+ bool valid;
+};
+
+class TQM_EXPORT_HTTP TQHttpResponseHeader : public TQHttpHeader
+{
+private:
+ TQHttpResponseHeader( int code, const TQString& text = TQString::null, int majorVer = 1, int minorVer = 1 );
+ TQHttpResponseHeader( const TQString& str );
+
+ void setqStatusLine( int code, const TQString& text = TQString::null, int majorVer = 1, int minorVer = 1 );
+
+public:
+ TQHttpResponseHeader();
+ TQHttpResponseHeader( const TQHttpResponseHeader& header );
+
+ int statusCode() const;
+ TQString reasonPhrase() const;
+
+ int majorVersion() const;
+ int minorVersion() const;
+
+ TQString toString() const;
+
+protected:
+ bool parseLine( const TQString& line, int number );
+
+private:
+ int statCode;
+ TQString reasonPhr;
+ int majVer;
+ int minVer;
+
+ friend class TQHttp;
+};
+
+class TQM_EXPORT_HTTP TQHttpRequestHeader : public TQHttpHeader
+{
+public:
+ TQHttpRequestHeader();
+ TQHttpRequestHeader( const TQString& method, const TQString& path, int majorVer = 1, int minorVer = 1 );
+ TQHttpRequestHeader( const TQHttpRequestHeader& header );
+ TQHttpRequestHeader( const TQString& str );
+
+ void setRequest( const TQString& method, const TQString& path, int majorVer = 1, int minorVer = 1 );
+
+ TQString method() const;
+ TQString path() const;
+
+ int majorVersion() const;
+ int minorVersion() const;
+
+ TQString toString() const;
+
+protected:
+ bool parseLine( const TQString& line, int number );
+
+private:
+ TQString m;
+ TQString p;
+ int majVer;
+ int minVer;
+};
+
+class TQM_EXPORT_HTTP TQHttp : public TQNetworkProtocol
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQHttp();
+ TQHttp( TQObject* tqparent, const char* name = 0 ); // ### TQt 4.0: make tqparent=0 and get rid of the TQHttp() constructor
+ TQHttp( const TQString &hostname, TQ_UINT16 port=80, TQObject* tqparent=0, const char* name = 0 );
+ virtual ~TQHttp();
+
+ int supportedOperations() const;
+
+ enum State { Unconnected, HostLookup, Connecting, Sending, Reading, Connected, Closing };
+ enum Error {
+ NoError,
+ UnknownError,
+ HostNotFound,
+ ConnectionRefused,
+ UnexpectedClose,
+ InvalidResponseHeader,
+ WrongContentLength,
+ Aborted
+ };
+
+ int setHost(const TQString &hostname, TQ_UINT16 port=80 );
+
+ int get( const TQString& path, TQIODevice* to=0 );
+ int post( const TQString& path, TQIODevice* data, TQIODevice* to=0 );
+ int post( const TQString& path, const TQByteArray& data, TQIODevice* to=0 );
+ int head( const TQString& path );
+ int request( const TQHttpRequestHeader &header, TQIODevice *tqdevice=0, TQIODevice *to=0 );
+ int request( const TQHttpRequestHeader &header, const TQByteArray &data, TQIODevice *to=0 );
+
+ int closeConnection();
+
+ TQ_ULONG bytesAvailable() const;
+ TQ_LONG readBlock( char *data, TQ_ULONG maxlen );
+ TQByteArray readAll();
+
+ int currentId() const;
+ TQIODevice* currentSourceDevice() const;
+ TQIODevice* currentDestinationDevice() const;
+ TQHttpRequestHeader currentRequest() const;
+ bool hasPendingRequests() const;
+ void clearPendingRequests();
+
+ State state() const;
+
+ Error error() const;
+ TQString errorString() const;
+
+public Q_SLOTS:
+ void abort();
+
+Q_SIGNALS:
+ void stateChanged( int );
+ void responseHeaderReceived( const TQHttpResponseHeader& resp );
+ void readyRead( const TQHttpResponseHeader& resp );
+ void dataSendProgress( int, int );
+ void dataReadProgress( int, int );
+
+ void requestStarted( int );
+ void requestFinished( int, bool );
+ void done( bool );
+
+protected:
+ void operationGet( TQNetworkOperation *op );
+ void operationPut( TQNetworkOperation *op );
+
+ void timerEvent( TQTimerEvent * );
+
+private Q_SLOTS:
+ void clientReply( const TQHttpResponseHeader &rep );
+ void clientDone( bool );
+ void clientStateChanged( int );
+
+ void startNextRequest();
+ void slotReadyRead();
+ void slotConnected();
+ void slotError( int );
+ void slotClosed();
+ void slotBytesWritten( int );
+
+private:
+ TQHttpPrivate *d;
+ void *unused; // ### TQt 4.0: remove this (in for binary compatibility)
+ int bytesRead;
+
+ int addRequest( TQHttpRequest * );
+ void sendRequest();
+ void finishedWithSuccess();
+ void finishedWithError( const TQString& detail, int errorCode );
+
+ void killIdleTimer();
+
+ void init();
+ void setState( int );
+ void close();
+
+ friend class TQHttpNormalRequest;
+ friend class TQHttpSetHostRequest;
+ friend class TQHttpCloseRequest;
+ friend class TQHttpPGHRequest;
+};
+
+#define TQ_DEFINED_TQHTTP
+#include "tqwinexport.h"
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/network/tqnetwork.cpp b/tqtinterface/qt4/src/network/tqnetwork.cpp
new file mode 100644
index 0000000..14cdda5
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqnetwork.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Implementation of qInitNetworkProtocols function.
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqnetwork.h"
+
+#ifndef TQT_NO_NETWORK
+
+#include "tqnetworkprotocol.h"
+
+// protocols
+#include "tqftp.h"
+#include "tqhttp.h"
+
+/*! \file tqnetwork.h */
+/*!
+ \relates TQUrlOperator
+
+ This function registers the network protocols for FTP and HTTP.
+ You must call this function before you use TQUrlOperator for
+ these protocols.
+
+ This function is declared in \l tqnetwork.h.
+*/
+void qInitNetworkProtocols()
+{
+#ifndef TQT_NO_NETWORKPROTOCOL_FTP
+ TQNetworkProtocol::registerNetworkProtocol( "ftp", new TQNetworkProtocolFactory< TQFtp > );
+#endif
+#ifndef TQT_NO_NETWORKPROTOCOL_HTTP
+ TQNetworkProtocol::registerNetworkProtocol( "http", new TQNetworkProtocolFactory< TQHttp > );
+#endif
+}
+
+#endif // TQT_NO_NETWORK
diff --git a/tqtinterface/qt4/src/network/tqnetwork.h b/tqtinterface/qt4/src/network/tqnetwork.h
new file mode 100644
index 0000000..131f40f
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqnetwork.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Definition of qInitNetworkProtocols function.
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQNETWORK_H
+#define TQNETWORK_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
+#define TQM_EXPORT_NETWORK
+#else
+#define TQM_EXPORT_NETWORK TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_NETWORK
+
+TQM_EXPORT_NETWORK void qInitNetworkProtocols();
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/network/tqserversocket.cpp b/tqtinterface/qt4/src/network/tqserversocket.cpp
new file mode 100644
index 0000000..bd067b1
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqserversocket.cpp
@@ -0,0 +1,297 @@
+/****************************************************************************
+**
+** Implementation of TQServerSocket class.
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqserversocket.h"
+
+#ifndef TQT_NO_NETWORK
+
+#include "tqsocketnotifier.h"
+
+class TQServerSocketPrivate {
+public:
+ TQServerSocketPrivate(): s(0), n(0) {}
+ ~TQServerSocketPrivate() { delete n; delete s; }
+ TQSocketDevice *s;
+ TQSocketNotifier *n;
+};
+
+
+/*!
+ \class TQServerSocket tqserversocket.h
+ \brief The TQServerSocket class provides a TCP-based server.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \module network
+
+ This class is a convenience class for accepting incoming TCP
+ connections. You can specify the port or have TQServerSocket pick
+ one, and listen on just one address or on all the machine's
+ addresses.
+
+ Using the API is very simple: subclass TQServerSocket, call the
+ constructor of your choice, and implement newConnection() to
+ handle new incoming connections. There is nothing more to do.
+
+ (Note that due to lack of support in the underlying APIs,
+ TQServerSocket cannot accept or reject connections conditionally.)
+
+ \sa TQSocket, TQSocketDevice, TQHostAddress, TQSocketNotifier
+*/
+
+
+/*!
+ Creates a server socket object, that will serve the given \a port
+ on all the addresses of this host. If \a port is 0, TQServerSocket
+ will pick a suitable port in a system-dependent manner. Use \a
+ backlog to specify how many pending connections the server can
+ have.
+
+ The \a tqparent and \a name arguments are passed on to the TQObject
+ constructor.
+
+ \warning On Tru64 Unix systems a value of 0 for \a backlog means
+ that you don't accept any connections at all; you should specify a
+ value larger than 0.
+*/
+
+TQServerSocket::TQServerSocket( TQ_UINT16 port, int backlog,
+ TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name )
+{
+ d = new TQServerSocketPrivate;
+ init( TQHostAddress(), port, backlog );
+}
+
+
+/*!
+ Creates a server socket object, that will serve the given \a port
+ only on the given \a address. Use \a backlog to specify how many
+ pending connections the server can have.
+
+ The \a tqparent and \a name arguments are passed on to the TQObject
+ constructor.
+
+ \warning On Tru64 Unix systems a value of 0 for \a backlog means
+ that you don't accept any connections at all; you should specify a
+ value larger than 0.
+*/
+
+TQServerSocket::TQServerSocket( const TQHostAddress & address, TQ_UINT16 port,
+ int backlog,
+ TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name )
+{
+ d = new TQServerSocketPrivate;
+ init( address, port, backlog );
+}
+
+
+/*!
+ Construct an empty server socket.
+
+ This constructor, in combination with setSocket(), allows us to
+ use the TQServerSocket class as a wrapper for other socket types
+ (e.g. Unix Domain Sockets under Unix).
+
+ The \a tqparent and \a name arguments are passed on to the TQObject
+ constructor.
+
+ \sa setSocket()
+*/
+
+TQServerSocket::TQServerSocket( TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name )
+{
+ d = new TQServerSocketPrivate;
+}
+
+
+/*!
+ Returns TRUE if the construction succeeded; otherwise returns FALSE.
+*/
+bool TQServerSocket::ok() const
+{
+ return !!d->s;
+}
+
+/*
+ The common bit of the constructors.
+ */
+void TQServerSocket::init( const TQHostAddress & address, TQ_UINT16 port, int backlog )
+{
+ d->s = new TQSocketDevice( TQSocketDevice::Stream, address.isIPv4Address()
+ ? TQSocketDevice::IPv4 : TQSocketDevice::IPv6, 0 );
+#if !defined(TQ_OS_WIN32)
+ // Under Unix, we want to be able to use the port, even if a socket on the
+ // same address-port is in TIME_WAIT. Under Windows this is possible anyway
+ // -- furthermore, the meaning of reusable is different: it means that you
+ // can use the same address-port for multiple listening sockets.
+ d->s->setAddressReusable( TRUE );
+#endif
+ if ( d->s->bind( address, port )
+ && d->s->listen( backlog ) )
+ {
+ d->n = new TQSocketNotifier( d->s->socket(), TQSocketNotifier::Read,
+ this, "accepting new connections" );
+ connect( d->n, TQT_SIGNAL(activated(int)),
+ this, TQT_SLOT(incomingConnection(int)) );
+ } else {
+ qWarning( "TQServerSocket: failed to bind or listen to the socket" );
+ delete d->s;
+ d->s = 0;
+ }
+}
+
+
+/*!
+ Destroys the socket.
+
+ This causes any backlogged connections (connections that have
+ reached the host, but not yet been completely set up by calling
+ TQSocketDevice::accept()) to be severed.
+
+ Existing connections continue to exist; this only affects the
+ acceptance of new connections.
+*/
+TQServerSocket::~TQServerSocket()
+{
+ delete d;
+}
+
+
+/*!
+ \fn void TQServerSocket::newConnection( int socket )
+
+ This pure virtual function is responsible for setting up a new
+ incoming connection. \a socket is the fd (file descriptor) for the
+ newly accepted connection.
+*/
+
+
+void TQServerSocket::incomingConnection( int )
+{
+ int fd = d->s->accept();
+ if ( fd >= 0 )
+ newConnection( fd );
+}
+
+
+/*!
+ Returns the port number on which this server socket listens. This
+ is always non-zero; if you specify 0 in the constructor,
+ TQServerSocket will pick a non-zero port itself. ok() must be TRUE
+ before calling this function.
+
+ \sa address() TQSocketDevice::port()
+*/
+TQ_UINT16 TQServerSocket::port() const
+{
+ if ( !d || !d->s )
+ return 0;
+ return d->s->port();
+}
+
+
+/*!
+ Returns the operating system socket.
+*/
+int TQServerSocket::socket() const
+{
+ if ( !d || !d->s )
+ return -1;
+
+ return d->s->socket();
+}
+
+/*!
+ Returns the address on which this object listens, or 0.0.0.0 if
+ this object listens on more than one address. ok() must be TRUE
+ before calling this function.
+
+ \sa port() TQSocketDevice::address()
+*/
+TQHostAddress TQServerSocket::address() const
+{
+ if ( !d || !d->s )
+ return TQHostAddress();
+
+ return d->s->address();
+}
+
+
+/*!
+ Returns a pointer to the internal socket tqdevice. The returned
+ pointer is 0 if there is no connection or pending connection.
+
+ There is normally no need to manipulate the socket tqdevice directly
+ since this class does all the necessary setup for most client or
+ server socket applications.
+*/
+TQSocketDevice *TQServerSocket::socketDevice()
+{
+ if ( !d )
+ return 0;
+
+ return d->s;
+}
+
+
+/*!
+ Sets the socket to use \a socket. bind() and listen() should
+ already have been called for \a socket.
+
+ This allows us to use the TQServerSocket class as a wrapper for
+ other socket types (e.g. Unix Domain Sockets).
+*/
+void TQServerSocket::setSocket( int socket )
+{
+ delete d;
+ d = new TQServerSocketPrivate;
+ d->s = new TQSocketDevice( socket, TQSocketDevice::Stream );
+ d->n = new TQSocketNotifier( d->s->socket(), TQSocketNotifier::Read,
+ this, "accepting new connections" );
+ connect( d->n, TQT_SIGNAL(activated(int)),
+ this, TQT_SLOT(incomingConnection(int)) );
+}
+
+#endif //TQT_NO_NETWORK
diff --git a/tqtinterface/qt4/src/network/tqserversocket.h b/tqtinterface/qt4/src/network/tqserversocket.h
new file mode 100644
index 0000000..5024c62
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqserversocket.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Definition of TQServerSocketClass.
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSERVERSOCKET_H
+#define TQSERVERSOCKET_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqhostaddress.h"
+#include "tqsocketdevice.h" // ### remove or keep for users' convenience?
+#endif // TQT_H
+#ifndef TQT_NO_NETWORK
+
+#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
+#define TQM_EXPORT_NETWORK
+#else
+#define TQM_EXPORT_NETWORK TQ_EXPORT
+#endif
+
+class TQServerSocketPrivate;
+
+
+class TQM_EXPORT_NETWORK TQServerSocket : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQServerSocket( TQ_UINT16 port, int backlog = 1,
+ TQObject *tqparent=0, const char *name=0 );
+ TQServerSocket( const TQHostAddress & address, TQ_UINT16 port, int backlog = 1,
+ TQObject *tqparent=0, const char *name=0 );
+ TQServerSocket( TQObject *tqparent=0, const char *name=0 );
+ virtual ~TQServerSocket();
+
+ bool ok() const;
+
+ TQ_UINT16 port() const ;
+
+ int socket() const ;
+ virtual void setSocket( int socket );
+
+ TQHostAddress address() const ;
+
+ virtual void newConnection( int socket ) = 0;
+
+protected:
+ TQSocketDevice *socketDevice();
+
+private Q_SLOTS:
+ void incomingConnection( int socket );
+
+private:
+ TQServerSocketPrivate *d;
+ void init( const TQHostAddress & address, TQ_UINT16 port, int backlog );
+};
+
+#endif // TQT_NO_NETWORK
+#endif // TQSERVERSOCKET_H
diff --git a/tqtinterface/qt4/src/network/tqsocket.cpp b/tqtinterface/qt4/src/network/tqsocket.cpp
new file mode 100644
index 0000000..52d95cc
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqsocket.cpp
@@ -0,0 +1,1668 @@
+/****************************************************************************
+**
+** Implementation of TQSocket class.
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsocket.h"
+#ifndef TQT_NO_NETWORK
+#include "tqptrlist.h"
+#include "tqtimer.h"
+#include "tqsocketdevice.h"
+#include "tqdns.h"
+#include "private/tqinternal_p.h"
+
+#include <string.h>
+#ifndef NO_ERRNO_H
+#include <errno.h>
+#endif
+
+//#define TQSOCKET_DEBUG
+
+/*
+ Perhaps this private functionality needs to be refactored.
+
+ Comment from Robert D Gatlin (Intel):
+
+ It would be nice to have the functionality inherent in TQSocket available
+ as a separate class as a standard part of the TQt library, something along
+ the line of:
+
+ class TQByteBuffer : public TQIODevice { ... }
+
+ The same class could/would be used within TQSocket for the Read/Write
+ buffers.
+
+ The above class could be used in the following way(s):
+
+ buffer.open( IO_WriteOnly | IO_Append );
+ buffer.writeBlock( a ); // a = TQByteArray
+ buffer.close();
+
+ TQByteArray b;
+ b.resize( buffer.size() );
+ buffer.open( IO_ReadOnly );
+ buffer.readBlock( b.data(), b.size() );
+ buffer.close();
+
+ But would also be useable with TQDataStream (via TQIODevice) with:
+
+ buffer.open( IO_WriteOnly | IO_Append );
+ TQDataStream is( &buffer );
+ is << 100;
+ buffer.close();
+
+ buffer.open( IO_ReadOnly );
+ TQDataStream os( &buffer );
+ TQ_UINT32 x;
+ os >> x;
+ buffer.close();
+
+ The real usefulness is with any situations where data (TQByteArray) arrives
+ incrementally (as in TQSocket and filter case above).
+
+ I tried using TQBuffer, but TQBuffer does not trim bytes from the front of
+ the buffer in cases like:
+
+ TQBuffer buf;
+ buf.open( IO_ReadOnly );
+ TQDataStream ds( &buf );
+ TQ_INT32 x;
+ ds >> x;
+ buf.close();
+
+ In the above case, buf.size() will be identical before and after the
+ operation with TQDataStream. Based on the implementation of TQBuffer, it
+ does not appear well suited for this kind of operation.
+*/
+
+// Private class for TQSocket
+
+class TQSocketPrivate {
+public:
+ TQSocketPrivate();
+ ~TQSocketPrivate();
+ void closeSocket();
+ void close();
+ void connectionClosed();
+ void setSocketDevice( TQSocket *q, TQSocketDevice *tqdevice );
+
+ TQSocket::State state; // connection state
+ TQString host; // host name
+ TQ_UINT16 port; // host port
+ TQSocketDevice *socket; // connection socket
+ TQSocketNotifier *rsn, *wsn; // socket notifiers
+ TQMembuf rba; // read buffer
+ TQ_ULONG readBufferSize; // limit for the read buffer size
+ TQPtrList<TQByteArray> wba; // list of write bufs
+ TQHostAddress addr; // connection address
+ TQValueList<TQHostAddress> addresses; // alternatives looked up
+ TQIODevice::Offset wsize; // write total buf size
+ TQIODevice::Offset windex; // write index
+#ifndef TQT_NO_DNS
+ TQDns *dns4;
+ TQDns *dns6;
+#endif
+ static TQPtrList<TQSocket> sn_read_alreadyCalled; // used to avoid unwanted recursion
+ TQValueList<TQHostAddress> l4;
+ TQValueList<TQHostAddress> l6;
+};
+
+TQPtrList<TQSocket> TQSocketPrivate::sn_read_alreadyCalled;
+
+TQSocketPrivate::TQSocketPrivate()
+ : state(TQSocket::Idle), host(TQString::tqfromLatin1("")), port(0),
+ socket(0), rsn(0), wsn(0), readBufferSize(0), wsize(0), windex(0)
+{
+#ifndef TQT_NO_DNS
+ dns4 = 0;
+ dns6 = 0;
+#endif
+ wba.setAutoDelete( TRUE );
+}
+
+TQSocketPrivate::~TQSocketPrivate()
+{
+ close();
+ delete socket;
+#ifndef TQT_NO_DNS
+ delete dns4;
+ delete dns6;
+#endif
+}
+
+void TQSocketPrivate::closeSocket()
+{
+ // Order is important here - the socket notifiers must go away
+ // before the socket does, otherwise libc or the kernel will
+ // become unhappy.
+ delete rsn;
+ rsn = 0;
+ delete wsn;
+ wsn = 0;
+ if ( socket )
+ socket->close();
+}
+
+void TQSocketPrivate::close()
+{
+ closeSocket();
+ wsize = 0;
+ rba.clear(); wba.clear();
+ windex = 0;
+}
+
+void TQSocketPrivate::connectionClosed()
+{
+ // We keep the open state in case there's unread incoming data
+ state = TQSocket::Idle;
+ closeSocket();
+ wba.clear();
+ windex = wsize = 0;
+}
+
+void TQSocketPrivate::setSocketDevice( TQSocket *q, TQSocketDevice *tqdevice )
+{
+ delete socket;
+ delete rsn;
+ delete wsn;
+
+ if ( tqdevice ) {
+ socket = tqdevice;
+ } else {
+ socket = new TQSocketDevice( TQSocketDevice::Stream,
+ ( addr.isIPv4Address() ?
+ TQSocketDevice::IPv4 :
+ TQSocketDevice::IPv6 ), 0 );
+ socket->setBlocking( FALSE );
+ socket->setAddressReusable( TRUE );
+ }
+
+ rsn = new TQSocketNotifier( socket->socket(),
+ TQSocketNotifier::Read, TQT_TQOBJECT(q), "read" );
+ wsn = new TQSocketNotifier( socket->socket(),
+ TQSocketNotifier::Write, TQT_TQOBJECT(q), "write" );
+
+ TQObject::connect( rsn, TQT_SIGNAL(activated(int)), q, TQT_SLOT(sn_read()) );
+ rsn->setEnabled( FALSE );
+ TQObject::connect( wsn, TQT_SIGNAL(activated(int)), q, TQT_SLOT(sn_write()) );
+ wsn->setEnabled( FALSE );
+}
+
+/*!
+ \class TQSocket tqsocket.h
+ \brief The TQSocket class provides a buffered TCP connection.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \module network
+
+ It provides a totally non-blocking TQIODevice, and modifies and
+ extends the API of TQIODevice with socket-specific code.
+
+ Note that a TQApplication must have been constructed before this
+ class can be used.
+
+ The functions you're likely to call most are connectToHost(),
+ bytesAvailable(), canReadLine() and the ones it inherits from
+ TQIODevice.
+
+ connectToHost() is the most-used function. As its name implies,
+ it opens a connection to a named host.
+
+ Most network protocols are either packet-oriented or
+ line-oriented. canReadLine() indicates whether a connection
+ tqcontains an entire unread line or not, and bytesAvailable()
+ returns the number of bytes available for reading.
+
+ The Q_SIGNALS error(), connected(), readyRead() and
+ connectionClosed() inform you of the progress of the connection.
+ There are also some less commonly used Q_SIGNALS. hostFound() is
+ emitted when connectToHost() has finished its DNS lookup and is
+ starting its TCP connection. delayedCloseFinished() is emitted
+ when close() succeeds. bytesWritten() is emitted when TQSocket
+ moves data from its "to be written" queue into the TCP
+ implementation.
+
+ There are several access functions for the socket: state() returns
+ whether the object is idle, is doing a DNS lookup, is connecting,
+ has an operational connection, etc. address() and port() return
+ the IP address and port used for the connection. The peerAddress()
+ and peerPort() functions return the IP address and port used by
+ the peer, and peerName() returns the name of the peer (normally
+ the name that was passed to connectToHost()). socketDevice()
+ returns a pointer to the TQSocketDevice used for this socket.
+
+ TQSocket inherits TQIODevice, and reimplements some functions. In
+ general, you can treat it as a TQIODevice for writing, and mostly
+ also for reading. The match isn't perfect, since the TQIODevice
+ API is designed for tqdevices that are controlled by the same
+ machine, and an asynchronous peer-to-peer network connection isn't
+ quite like that. For example, there is nothing that matches
+ TQIODevice::size() exactly. The documentation for open(), close(),
+ flush(), size(), at(), atEnd(), readBlock(), writeBlock(),
+ getch(), putch(), ungetch() and readLine() describes the
+ differences in detail.
+
+ \warning TQSocket is not suitable for use in threads. If you need
+ to uses sockets in threads use the lower-level TQSocketDevice class.
+
+ \warning Because TQt doesn't use the native socketstream
+ implementation on Mac OS X, TQSocket has an implicit transfer
+ latency of 100ms. You can achieve lower latency on Mac OS X by
+ using TQSocketDevice instead.
+
+ \sa TQSocketDevice, TQHostAddress, TQSocketNotifier
+*/
+
+#ifdef USE_QT4
+
+/*!
+ Reads \a maxlen bytes from the socket into \a data and returns the
+ number of bytes read. Returns -1 if an error occurred.
+*/
+
+qint64 TQSocket::readData( char *data, qint64 maxlen )
+{
+ if ( data == 0 && maxlen != 0 ) {
+#if defined(QT_CHECK_NULL)
+ qWarning( "TQSocket::readBlock: Null pointer error" );
+#endif
+ return -1;
+ }
+ if ( !isOpen() ) {
+#if defined(QT_CHECK_STATE)
+ qWarning( "TQSocket::readBlock: Socket is not open" );
+#endif
+ return -1;
+ }
+ if ( maxlen >= d->rba.size() )
+ maxlen = d->rba.size();
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): readBlock %d bytes", name(), (int)maxlen );
+#endif
+ d->rba.consumeBytes( maxlen, data );
+ // After we read data from our internal buffer, if we use the
+ // setReadBufferSize() to limit our buffer, we might now be able to
+ // read more data in our buffer. So enable the read socket notifier,
+ // but do this only if we are not in a slot connected to the
+ // readyRead() signal since this might cause a bad recursive behavior.
+ // We can test for this condition by looking at the
+ // sn_read_alreadyCalled flag.
+ if ( d->rsn && TQSocketPrivate::sn_read_alreadyCalled.tqfindRef(this) == -1 )
+ d->rsn->setEnabled( true );
+ return maxlen;
+}
+
+
+/*!
+ Writes \a len bytes to the socket from \a data and returns the
+ number of bytes written. Returns -1 if an error occurred.
+*/
+
+qint64 TQSocket::writeData( const char *data, qint64 len )
+{
+#if defined(QT_CHECK_NULL)
+ if ( data == 0 && len != 0 ) {
+ qWarning( "TQSocket::writeBlock: Null pointer error" );
+ }
+#endif
+#if defined(QT_CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "TQSocket::writeBlock: Socket is not open" );
+ return -1;
+ }
+#endif
+#if defined(QT_CHECK_STATE)
+ if ( d->state == Closing ) {
+ qWarning( "TQSocket::writeBlock: Cannot write, socket is closing" );
+ }
+#endif
+ if ( len == 0 || d->state == Closing || d->state == Idle )
+ return 0;
+ TQByteArray *a = d->wba.last();
+
+ // next bit is sensitive. if we're writing really small chunks,
+ // try to buffer up since system calls are expensive, and nagle's
+ // algorithm is even more expensive. but if anything even
+ // remotely large is being written, try to issue a write at once.
+
+ bool writeNow = ( d->wsize + len >= 1400 || len > 512 );
+
+ if ( a && a->size() + len < 128 ) {
+ // small buffer, resize
+ int i = a->size();
+ a->resize( i+len );
+ memcpy( a->data()+i, data, len );
+ } else {
+ // append new buffer
+ a = new TQByteArray( len );
+ memcpy( a->data(), data, len );
+ d->wba.append( a );
+ }
+ d->wsize += len;
+ if ( writeNow )
+ flush();
+ else if ( d->wsn )
+ d->wsn->setEnabled( true );
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): writeBlock %d bytes", name(), (int)len );
+#endif
+ return len;
+}
+
+#endif // USE_QT4
+
+
+/*!
+ Creates a TQSocket object in \c TQSocket::Idle state.
+
+ The \a tqparent and \a name arguments are passed on to the TQObject
+ constructor.
+
+ Note that a TQApplication must have been constructed before sockets
+ can be used.
+*/
+
+TQSocket::TQSocket( TQObject *tqparent, const char *name )
+#ifdef USE_QT4
+ : TQIODevice()
+#else // USE_QT4
+ : TQObject( tqparent, name )
+#endif // USE_QT4
+{
+#ifdef USE_QT4
+ setParent(tqparent);
+ setObjectName(name);
+#endif // USE_QT4
+ d = new TQSocketPrivate;
+ setSocketDevice( 0 );
+ setFlags( IO_Direct );
+ resetqStatus();
+}
+
+
+/*!
+ Destroys the socket. Closes the connection if necessary.
+
+ \sa close()
+*/
+
+TQSocket::~TQSocket()
+{
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): Destroy", name() );
+#endif
+ if ( state() != Idle )
+ close();
+ TQ_ASSERT( d != 0 );
+ delete d;
+}
+
+
+/*!
+ Returns a pointer to the internal socket tqdevice.
+
+ There is normally no need to manipulate the socket tqdevice directly
+ since this class does the necessary setup for most applications.
+*/
+
+TQSocketDevice *TQSocket::socketDevice()
+{
+ return d->socket;
+}
+
+/*!
+ Sets the internal socket tqdevice to \a tqdevice. Passing a \a tqdevice
+ of 0 will cause the internal socket tqdevice to be used. Any
+ existing connection will be disconnected before using the new \a
+ tqdevice.
+
+ The new tqdevice should not be connected before being associated
+ with a TQSocket; after setting the socket call connectToHost() to
+ make the connection.
+
+ This function is useful if you need to subclass TQSocketDevice and
+ want to use the TQSocket API, for example, to implement Unix domain
+ sockets.
+*/
+
+void TQSocket::setSocketDevice( TQSocketDevice *tqdevice )
+{
+ if ( state() != Idle )
+ close();
+ d->setSocketDevice( this, tqdevice );
+}
+
+/*!
+ \enum TQSocket::State
+
+ This enum defines the connection states:
+
+ \value Idle if there is no connection
+ \value HostLookup during a DNS lookup
+ \value Connecting during TCP connection establishment
+ \value Connected when there is an operational connection
+ \value Closing if the socket is closing down, but is not yet closed.
+*/
+
+/*!
+ Returns the current state of the socket connection.
+
+ \sa TQSocket::State
+*/
+
+TQSocket::State TQSocket::state() const
+{
+ return d->state;
+}
+
+
+#ifndef TQT_NO_DNS
+
+/*!
+ Attempts to make a connection to \a host on the specified \a port
+ and return immediately.
+
+ Any connection or pending connection is closed immediately, and
+ TQSocket goes into the \c HostLookup state. When the lookup
+ succeeds, it emits hostFound(), starts a TCP connection and goes
+ into the \c Connecting state. Finally, when the connection
+ succeeds, it emits connected() and goes into the \c Connected
+ state. If there is an error at any point, it emits error().
+
+ \a host may be an IP address in string form, or it may be a DNS
+ name. TQSocket will do a normal DNS lookup if required. Note that
+ \a port is in native byte order, unlike some other libraries.
+
+ \sa state()
+*/
+
+void TQSocket::connectToHost( const TQString &host, TQ_UINT16 port )
+{
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s)::connectToHost: host %s, port %d",
+ name(), host.ascii(), port );
+#endif
+ setSocketIntern( -1 );
+ d->state = HostLookup;
+ d->host = host;
+ d->port = port;
+ d->dns4 = new TQDns( host, TQDns::A );
+ d->dns6 = new TQDns( host, TQDns::Aaaa );
+
+ // try if the address is already available (for faster connecting...)
+ tryConnecting();
+ if ( d->state == HostLookup ) {
+ connect( d->dns4, TQT_SIGNAL(resultsReady()),
+ this, TQT_SLOT(tryConnecting()) );
+ connect( d->dns6, TQT_SIGNAL(resultsReady()),
+ this, TQT_SLOT(tryConnecting()) );
+ }
+}
+
+#endif
+
+
+/*!
+ This private Q_SLOTS continues the connection process where
+ connectToHost() leaves off.
+*/
+
+void TQSocket::tryConnecting()
+{
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s)::tryConnecting()", name() );
+#endif
+ // ### this ifdef isn't correct - addresses() also does /etc/hosts and
+ // numeric-address-as-string handling.
+#ifndef TQT_NO_DNS
+
+ if ( d->dns4 ) {
+ d->l4 = d->dns4->addresses();
+ if ( !d->l4.isEmpty() || !d->dns4->isWorking() ) {
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s)::tryConnecting: host %s, port %d: "
+ "%d IPv4 addresses",
+ name(), d->host.ascii(), d->port, d->l4.count() );
+#endif
+ delete d->dns4;
+ d->dns4 = 0;
+ }
+ }
+
+ if ( d->dns6 ) {
+ d->l6 = d->dns6->addresses();
+ if ( !d->l6.isEmpty() || !d->dns6->isWorking() ) {
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s)::tryConnecting: host %s, port %d: "
+ "%d IPv6 addresses",
+ name(), d->host.ascii(), d->port, d->l6.count() );
+#endif
+ delete d->dns6;
+ d->dns6 = 0;
+ }
+ }
+
+ if ( d->state == HostLookup ) {
+ if ( d->l4.isEmpty() && d->l6.isEmpty() &&
+ !d->dns4 && !d->dns6 ) {
+ // no results and we're not still looking: give up
+ d->state = Idle;
+ emit error( ErrHostNotFound );
+ return;
+ }
+ if ( d->l4.isEmpty() && d->l6.isEmpty() ) {
+ // no results (yet): try again later
+ return;
+ }
+
+ // we've found something. press on with that. if we later tqfind
+ // more, fine.
+ emit hostFound();
+ d->state = Connecting;
+ }
+
+ if ( d->state == Connecting ) {
+ d->addresses += d->l4;
+ d->addresses += d->l6;
+ d->l4.clear();
+ d->l6.clear();
+
+ // try one address at a time, falling back to the next one if
+ // there is a connection failure. (should also support a timeout,
+ // or do multiple TCP-level connects at a time, with staggered
+ // starts to avoid bandwidth waste and cause fewer
+ // "connect-and-abort" errors. but that later.)
+ bool stuck = TRUE;
+ while( stuck ) {
+ stuck = FALSE;
+ if ( d->socket &&
+ d->socket->connect( d->addr, d->port ) == FALSE ) {
+ if ( d->socket->error() == TQSocketDevice::NoError ) {
+ if ( d->wsn )
+ d->wsn->setEnabled( TRUE );
+ return; // not serious, try again later
+ }
+
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s)::tryConnecting: "
+ "Gave up on IP address %s",
+ name(), d->socket->peerAddress().toString().ascii() );
+#endif
+ delete d->wsn;
+ d->wsn = 0;
+ delete d->rsn;
+ d->rsn = 0;
+ delete d->socket;
+ d->socket = 0;
+
+ if(d->addresses.isEmpty()) {
+ emit error( ErrConnectionRefused );
+ return;
+ }
+ }
+ // if the host has more addresses, try another some.
+ if ( d->socket == 0 && !d->addresses.isEmpty() ) {
+ d->addr = *d->addresses.begin();
+ d->addresses.remove( d->addresses.begin() );
+ d->setSocketDevice( this, 0 );
+ stuck = TRUE;
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s)::tryConnecting: Trying IP address %s",
+ name(), d->addr.toString().ascii() );
+#endif
+ }
+ };
+
+ // The socket write notifier will fire when the connection succeeds
+ if ( d->wsn )
+ d->wsn->setEnabled( TRUE );
+ }
+#endif
+}
+
+/*!
+ \enum TQSocket::Error
+
+ This enum specifies the possible errors:
+ \value ErrConnectionRefused if the connection was refused
+ \value ErrHostNotFound if the host was not found
+ \value ErrSocketRead if a read from the socket failed
+*/
+
+/*!
+ \fn void TQSocket::error( int )
+
+ This signal is emitted after an error occurred. The parameter is
+ the \l Error value.
+*/
+
+/*!
+ \fn void TQSocket::hostFound()
+
+ This signal is emitted after connectToHost() has been called and
+ the host lookup has succeeded.
+
+ \sa connected()
+*/
+
+
+/*!
+ \fn void TQSocket::connected()
+
+ This signal is emitted after connectToHost() has been called and a
+ connection has been successfully established.
+
+ \sa connectToHost(), connectionClosed()
+*/
+
+
+/*!
+ \fn void TQSocket::connectionClosed()
+
+ This signal is emitted when the other end has closed the
+ connection. The read buffers may contain buffered input data which
+ you can read after the connection was closed.
+
+ \sa connectToHost(), close()
+*/
+
+
+/*!
+ \fn void TQSocket::delayedCloseFinished()
+
+ This signal is emitted when a delayed close is finished.
+
+ If you call close() and there is buffered output data to be
+ written, TQSocket goes into the \c TQSocket::Closing state and
+ returns immediately. It will then keep writing to the socket until
+ all the data has been written. Then, the delayedCloseFinished()
+ signal is emitted.
+
+ \sa close()
+*/
+
+
+/*!
+ \fn void TQSocket::readyRead()
+
+ This signal is emitted every time there is new incoming data.
+
+ Bear in mind that new incoming data is only reported once; if you do not
+ read all the data, this class buffers the data and you can read it later,
+ but no signal is emitted unless new data arrives. A good practice is to
+ read all data in the slot connected to this signal unless you are sure that
+ you need to receive more data to be able to process it.
+
+ \sa readBlock(), readLine(), bytesAvailable()
+*/
+
+
+/*!
+ \fn void TQSocket::bytesWritten( int nbytes )
+
+ This signal is emitted when data has been written to the network.
+ The \a nbytes parameter specifies how many bytes were written.
+
+ The bytesToWrite() function is often used in the same context; it
+ indicates how many buffered bytes there are left to write.
+
+ \sa writeBlock(), bytesToWrite()
+*/
+
+
+/*!
+ Opens the socket using the specified TQIODevice file mode \a m.
+ This function is called automatically when needed and you should
+ not call it yourself.
+
+ \sa close()
+*/
+
+bool TQSocket::open( int m )
+{
+ if ( isOpen() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSocket::open: Already open" );
+#endif
+ return FALSE;
+ }
+ TQIODevice::setMode( m & IO_ReadWrite );
+ setState( IO_Open );
+ return TRUE;
+}
+
+
+/*!
+ Closes the socket.
+
+ The read buffer is cleared.
+
+ If the output buffer is empty, the state is set to \c
+ TQSocket::Idle and the connection is terminated immediately. If the
+ output buffer still tqcontains data to be written, TQSocket goes into
+ the \c TQSocket::Closing state and the rest of the data will be
+ written. When all of the outgoing data have been written, the
+ state is set to \c TQSocket::Idle and the connection is terminated.
+ At this point, the delayedCloseFinished() signal is emitted.
+
+ If you don't want that the data of the output buffer is written, call
+ clearPendingData() before you call close().
+
+ \sa state(), bytesToWrite() clearPendingData()
+*/
+
+void TQSocket::close()
+{
+ if ( !isOpen() || d->state == Idle ) // already closed
+ return;
+ if ( d->state == Closing )
+ return;
+ if ( !d->rsn || !d->wsn )
+ return;
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): close socket", name() );
+#endif
+ if ( d->socket && d->wsize ) { // there's data to be written
+ d->state = Closing;
+ if ( d->rsn )
+ d->rsn->setEnabled( FALSE );
+ if ( d->wsn )
+ d->wsn->setEnabled( TRUE );
+ d->rba.clear(); // clear incoming data
+ return;
+ }
+ setFlags( IO_Sequential );
+ resetqStatus();
+ setState( 0 );
+ d->close();
+ d->state = Idle;
+}
+
+
+/*!
+ This function consumes \a nbytes bytes of data from the write
+ buffer.
+*/
+
+bool TQSocket::consumeWriteBuf( TQ_ULONG nbytes )
+{
+ if ( nbytes <= 0 || nbytes > d->wsize )
+ return FALSE;
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): skipWriteBuf %d bytes", name(), (int)nbytes );
+#endif
+ d->wsize -= nbytes;
+ for ( ;; ) {
+ TQByteArray *a = d->wba.first();
+ if ( d->windex + nbytes >= a->size() ) {
+ nbytes -= a->size() - d->windex;
+ d->wba.remove();
+ d->windex = 0;
+ if ( nbytes == 0 )
+ break;
+ } else {
+ d->windex += nbytes;
+ break;
+ }
+ }
+ return TRUE;
+}
+
+
+
+/*!
+ Implementation of the abstract virtual TQIODevice::flush() function.
+*/
+
+void TQSocket::flush()
+{
+ if ( !d->socket )
+ return;
+ bool osBufferFull = FALSE;
+ int consumed = 0;
+ while ( !osBufferFull && d->state >= Connecting && d->wsize > 0 ) {
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): flush: Write data to the socket", name() );
+#endif
+ TQByteArray *a = d->wba.first();
+ int nwritten;
+ int i = 0;
+ if ( (int)a->size() - d->windex < 1460 ) {
+ // Concatenate many smaller blocks. the first may be
+ // partial, but each subsequent block is copied entirely
+ // or not at all. the sizes here are picked so that we
+ // generally won't trigger nagle's algorithm in the tcp
+ // implementation: we concatenate if we'd otherwise send
+ // less than PMTU bytes (we assume PMTU is 1460 bytes),
+ // and concatenate up to the largest payload TCP/IP can
+ // carry. with these precautions, nagle's algorithm
+ // should apply only when really appropriate.
+ TQByteArray out( 65536 );
+ int j = d->windex;
+ int s = a->size() - j;
+ while ( a && i+s < (int)out.size() ) {
+ memcpy( out.data()+i, a->data()+j, s );
+ j = 0;
+ i += s;
+ a = d->wba.next();
+ s = a ? a->size() : 0;
+ }
+ nwritten = d->socket->writeBlock( out.data(), i );
+ if ( d->wsn )
+ d->wsn->setEnabled( FALSE ); // the TQSocketNotifier documentation says so
+ } else {
+ // Big block, write it immediately
+ i = a->size() - d->windex;
+ nwritten = d->socket->writeBlock( a->data() + d->windex, i );
+ if ( d->wsn )
+ d->wsn->setEnabled( FALSE ); // the TQSocketNotifier documentation says so
+ }
+ if ( nwritten > 0 ) {
+ if ( consumeWriteBuf( nwritten ) )
+ consumed += nwritten;
+ }
+ if ( nwritten < i )
+ osBufferFull = TRUE;
+ }
+ if ( consumed > 0 ) {
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): flush: wrote %d bytes, %d left",
+ name(), consumed, (int)d->wsize );
+#endif
+ emit bytesWritten( consumed );
+ }
+ if ( d->state == Closing && d->wsize == 0 ) {
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): flush: Delayed close done. Terminating.",
+ name() );
+#endif
+ setFlags( IO_Sequential );
+ resetqStatus();
+ setState( 0 );
+ d->close();
+ d->state = Idle;
+ emit delayedCloseFinished();
+ return;
+ }
+ if ( !d->socket->isOpen() ) {
+ d->connectionClosed();
+ emit connectionClosed();
+ return;
+ }
+ if ( d->wsn )
+ d->wsn->setEnabled( d->wsize > 0 ); // write if there's data
+}
+
+
+/*!
+ Returns the number of incoming bytes that can be read right now
+ (like bytesAvailable()).
+*/
+
+#ifdef USE_QT4
+qint64 TQSocket::size() const
+#else // USE_QT4
+TQIODevice::Offset TQSocket::size() const
+#endif // USE_QT4
+{
+ return (Offset)bytesAvailable();
+}
+
+
+/*!
+ Returns the current read index. Since TQSocket is a sequential
+ tqdevice, the current read index is always zero.
+*/
+
+#ifdef USE_QT4
+qint64 TQSocket::at() const
+#else // USE_QT4
+TQIODevice::Offset TQSocket::at() const
+#endif // USE_QT4
+{
+ return 0;
+}
+
+
+/*!
+ \overload
+
+ Moves the read index forward to \a index and returns TRUE if the
+ operation was successful; otherwise returns FALSE. Moving the
+ index forward means skipping incoming data.
+*/
+
+bool TQSocket::at( Offset index )
+{
+ if ( index > d->rba.size() )
+ return FALSE;
+ d->rba.consumeBytes( (TQ_ULONG)index, 0 ); // throw away data 0..index-1
+ // After we read data from our internal buffer, if we use the
+ // setReadBufferSize() to limit our buffer, we might now be able to
+ // read more data in our buffer. So enable the read socket notifier,
+ // but do this only if we are not in a slot connected to the
+ // readyRead() signal since this might cause a bad recursive behavior.
+ // We can test for this condition by looking at the
+ // sn_read_alreadyCalled flag.
+ if ( d->rsn && TQSocketPrivate::sn_read_alreadyCalled.tqfindRef(this) == -1 )
+ d->rsn->setEnabled( TRUE );
+ return TRUE;
+}
+
+
+/*!
+ Returns TRUE if there is no more data to read; otherwise returns FALSE.
+*/
+
+bool TQSocket::atEnd() const
+{
+ if ( d->socket == 0 )
+ return TRUE;
+ TQSocket * that = (TQSocket *)this;
+ if ( that->d->socket->bytesAvailable() ) // a little slow, perhaps...
+ that->sn_read();
+ return that->d->rba.size() == 0;
+}
+
+
+/*!
+ Returns the number of incoming bytes that can be read, i.e. the
+ size of the input buffer. Equivalent to size().
+
+ This function can trigger the readyRead() signal, if more data has
+ arrived on the socket.
+
+ \sa bytesToWrite()
+*/
+
+#ifdef USE_QT4
+qint64 TQSocket::bytesAvailable() const
+#else // USE_QT4
+TQ_ULONG TQSocket::bytesAvailable() const
+#endif // USE_QT4
+{
+ if ( d->socket == 0 )
+ return 0;
+ TQSocket * that = (TQSocket *)this;
+ if ( that->d->socket->bytesAvailable() ) // a little slow, perhaps...
+ (void)that->sn_read();
+ return that->d->rba.size();
+}
+
+
+/*!
+ Wait up to \a msecs milliseconds for more data to be available.
+
+ If \a msecs is -1 the call will block indefinitely.
+
+ Returns the number of bytes available.
+
+ If \a timeout is non-null and no error occurred (i.e. it does not
+ return -1): this function sets \a *timeout to TRUE, if the reason
+ for returning was that the timeout was reached; otherwise it sets
+ \a *timeout to FALSE. This is useful to tqfind out if the peer
+ closed the connection.
+
+ \warning This is a blocking call and should be avoided in event
+ driven applications.
+
+ \sa bytesAvailable()
+*/
+
+TQ_ULONG TQSocket::waitForMore( int msecs, bool *timeout ) const
+{
+ if ( d->socket == 0 )
+ return 0;
+ TQSocket * that = (TQSocket *)this;
+ if ( that->d->socket->waitForMore( msecs, timeout ) > 0 )
+ (void)that->sn_read( TRUE );
+ return that->d->rba.size();
+}
+
+/*! \overload
+*/
+
+TQ_ULONG TQSocket::waitForMore( int msecs ) const
+{
+ return waitForMore( msecs, 0 );
+}
+
+/*!
+ Returns the number of bytes that are waiting to be written, i.e.
+ the size of the output buffer.
+
+ \sa bytesAvailable() clearPendingData()
+*/
+
+#ifdef USE_QT4
+qint64 TQSocket::bytesToWrite() const
+#else // USE_QT4
+TQ_ULONG TQSocket::bytesToWrite() const
+#endif // USE_QT4
+{
+ return d->wsize;
+}
+
+/*!
+ Deletes the data that is waiting to be written. This is useful if you want
+ to close the socket without waiting for all the data to be written.
+
+ \sa bytesToWrite() close() delayedCloseFinished()
+*/
+
+void TQSocket::clearPendingData()
+{
+ d->wba.clear();
+ d->windex = d->wsize = 0;
+}
+
+/*!
+ Reads \a maxlen bytes from the socket into \a data and returns the
+ number of bytes read. Returns -1 if an error occurred.
+*/
+
+TQ_LONG TQSocket::readBlock( char *data, TQ_ULONG maxlen )
+{
+ if ( data == 0 && maxlen != 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQSocket::readBlock: Null pointer error" );
+#endif
+ return -1;
+ }
+ if ( !isOpen() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSocket::readBlock: Socket is not open" );
+#endif
+ return -1;
+ }
+ if ( maxlen >= d->rba.size() )
+ maxlen = d->rba.size();
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): readBlock %d bytes", name(), (int)maxlen );
+#endif
+ d->rba.consumeBytes( maxlen, data );
+ // After we read data from our internal buffer, if we use the
+ // setReadBufferSize() to limit our buffer, we might now be able to
+ // read more data in our buffer. So enable the read socket notifier,
+ // but do this only if we are not in a slot connected to the
+ // readyRead() signal since this might cause a bad recursive behavior.
+ // We can test for this condition by looking at the
+ // sn_read_alreadyCalled flag.
+ if ( d->rsn && TQSocketPrivate::sn_read_alreadyCalled.tqfindRef(this) == -1 )
+ d->rsn->setEnabled( TRUE );
+ return maxlen;
+}
+
+
+/*!
+ Writes \a len bytes to the socket from \a data and returns the
+ number of bytes written. Returns -1 if an error occurred.
+*/
+
+TQ_LONG TQSocket::writeBlock( const char *data, TQ_ULONG len )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( data == 0 && len != 0 ) {
+ qWarning( "TQSocket::writeBlock: Null pointer error" );
+ }
+#endif
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "TQSocket::writeBlock: Socket is not open" );
+ return -1;
+ }
+#endif
+#if defined(TQT_CHECK_STATE)
+ if ( d->state == Closing ) {
+ qWarning( "TQSocket::writeBlock: Cannot write, socket is closing" );
+ }
+#endif
+ if ( len == 0 || d->state == Closing || d->state == Idle )
+ return 0;
+ TQByteArray *a = d->wba.last();
+
+ // next bit is sensitive. if we're writing really small chunks,
+ // try to buffer up since system calls are expensive, and nagle's
+ // algorithm is even more expensive. but if anything even
+ // remotely large is being written, try to issue a write at once.
+
+ bool writeNow = ( d->wsize + len >= 1400 || len > 512 );
+
+ if ( a && a->size() + len < 128 ) {
+ // small buffer, resize
+ int i = a->size();
+ a->resize( i+len );
+ memcpy( a->data()+i, data, len );
+ } else {
+ // append new buffer
+ a = new TQByteArray( len );
+ memcpy( a->data(), data, len );
+ d->wba.append( a );
+ }
+ d->wsize += len;
+ if ( writeNow )
+ flush();
+ else if ( d->wsn )
+ d->wsn->setEnabled( TRUE );
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): writeBlock %d bytes", name(), (int)len );
+#endif
+ return len;
+}
+
+
+/*!
+ Reads a single byte/character from the internal read buffer.
+ Returns the byte/character read, or -1 if there is nothing to be
+ read.
+
+ \sa bytesAvailable(), putch()
+*/
+
+int TQSocket::getch()
+{
+ if ( isOpen() && d->rba.size() > 0 ) {
+ uchar c;
+ d->rba.consumeBytes( 1, (char*)&c );
+ // After we read data from our internal buffer, if we use the
+ // setReadBufferSize() to limit our buffer, we might now be able to
+ // read more data in our buffer. So enable the read socket notifier,
+ // but do this only if we are not in a slot connected to the
+ // readyRead() signal since this might cause a bad recursive behavior.
+ // We can test for this condition by looking at the
+ // sn_read_alreadyCalled flag.
+ if ( d->rsn && TQSocketPrivate::sn_read_alreadyCalled.tqfindRef(this) == -1 )
+ d->rsn->setEnabled( TRUE );
+ return c;
+ }
+ return -1;
+}
+
+
+/*!
+ Writes the character \a ch to the output buffer.
+
+ Returns \a ch, or -1 if an error occurred.
+
+ \sa getch()
+*/
+
+int TQSocket::putch( int ch )
+{
+ char buf[2];
+ buf[0] = ch;
+ return writeBlock(buf, 1) == 1 ? ch : -1;
+}
+
+
+/*!
+ This implementation of the virtual function TQIODevice::ungetch()
+ prepends the character \a ch to the read buffer so that the next
+ read returns this character as the first character of the output.
+*/
+
+int TQSocket::ungetch( int ch )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "TQSocket::ungetch: Socket not open" );
+ return -1;
+ }
+#endif
+ return d->rba.ungetch( ch );
+}
+
+
+/*!
+ Returns TRUE if it's possible to read an entire line of text from
+ this socket at this time; otherwise returns FALSE.
+
+ Note that if the peer closes the connection unexpectedly, this
+ function returns FALSE. This means that loops such as this won't
+ work:
+
+ \code
+ while( !socket->canReadLine() ) // WRONG
+ ;
+ \endcode
+
+ \sa readLine()
+*/
+
+bool TQSocket::canReadLine() const
+{
+ if ( ((TQSocket*)this)->d->rba.scanNewline( 0 ) )
+ return TRUE;
+ return ( bytesAvailable() > 0 &&
+ ((TQSocket*)this)->d->rba.scanNewline( 0 ) );
+}
+
+/*!
+ \reimp
+ \internal
+ So that it's not hidden by our other readLine().
+*/
+TQ_LONG TQSocket::readLine( char *data, TQ_ULONG maxlen )
+{
+ return TQIODevice::readLine(data,maxlen);
+}
+
+/*!
+ Returns a line of text including a terminating newline character
+ (\n). Returns "" if canReadLine() returns FALSE.
+
+ \sa canReadLine()
+*/
+
+TQString TQSocket::readLine()
+{
+ TQByteArray a(256);
+ bool nl = d->rba.scanNewline( &a );
+ TQString s;
+ if ( nl ) {
+ at( a.size() ); // skips the data read
+ s = TQString( a );
+ }
+ return s;
+}
+
+/*!
+ \internal
+ Internal slot for handling socket read notifications.
+
+ This function has can usually only be entered once (i.e. no
+ recursive calls). If the argument \a force is TRUE, the function
+ is executed, but no readyRead() Q_SIGNALS are emitted. This
+ behaviour is useful for the waitForMore() function, so that it is
+ possible to call waitForMore() in a slot connected to the
+ readyRead() signal.
+*/
+
+void TQSocket::sn_read( bool force )
+{
+ TQ_LONG maxToRead = 0;
+ if ( d->readBufferSize > 0 ) {
+ maxToRead = d->readBufferSize - d->rba.size();
+ if ( maxToRead <= 0 ) {
+ if ( d->rsn )
+ d->rsn->setEnabled( FALSE );
+ return;
+ }
+ }
+
+ // Use TQSocketPrivate::sn_read_alreadyCalled to avoid recursive calls of
+ // sn_read() (and as a result avoid emitting the readyRead() signal in a
+ // slot for readyRead(), if you use bytesAvailable()).
+ if ( !force && TQSocketPrivate::sn_read_alreadyCalled.tqfindRef(this) != -1 )
+ return;
+ TQSocketPrivate::sn_read_alreadyCalled.append( this );
+
+ char buf[4096];
+ TQ_LONG nbytes = d->socket->bytesAvailable();
+ TQ_LONG nread;
+ TQByteArray *a = 0;
+
+ if ( state() == Connecting ) {
+ if ( nbytes > 0 ) {
+ tryConnection();
+ } else {
+ // nothing to do, nothing to care about
+ TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
+ return;
+ }
+ }
+ if ( state() == Idle ) {
+ TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
+ return;
+ }
+
+ if ( nbytes <= 0 ) { // connection closed?
+ // On Windows this may happen when the connection is still open.
+ // This happens when the system is heavily loaded and we have
+ // read all the data on the socket before a new WSAAsyncSelect
+ // event is processed. A new read operation would then block.
+ // This code is also useful when TQSocket is used without an
+ // event loop.
+ nread = d->socket->readBlock( buf, maxToRead ? TQMIN((TQ_LONG)sizeof(buf),maxToRead) : sizeof(buf) );
+ if ( nread == 0 ) { // really closed
+ if ( !d->socket->isOpen() ) {
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): sn_read: Connection closed", name() );
+#endif
+ d->connectionClosed();
+ emit connectionClosed();
+ }
+ TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
+ return;
+ } else {
+ if ( nread < 0 ) {
+ if ( d->socket->error() == TQSocketDevice::NoError ) {
+ // all is fine
+ TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
+ return;
+ }
+#if defined(TQSOCKET_DEBUG)
+ qWarning( "TQSocket::sn_read (%s): Close error", name() );
+#endif
+ if ( d->rsn )
+ d->rsn->setEnabled( FALSE );
+ emit error( ErrSocketRead );
+ TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
+ return;
+ }
+ a = new TQByteArray( nread );
+ memcpy( a->data(), buf, nread );
+ }
+
+ } else { // data to be read
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): sn_read: %ld incoming bytes", name(), nbytes );
+#endif
+ if ( nbytes > (int)sizeof(buf) ) {
+ // big
+ a = new TQByteArray( nbytes );
+ nread = d->socket->readBlock( a->data(), maxToRead ? TQMIN(nbytes,maxToRead) : nbytes );
+ } else {
+ a = 0;
+ nread = d->socket->readBlock( buf, maxToRead ? TQMIN((TQ_LONG)sizeof(buf),maxToRead) : sizeof(buf) );
+ if ( nread > 0 ) {
+ // ##### could setRawData
+ a = new TQByteArray( nread );
+ memcpy( a->data(), buf, nread );
+ }
+ }
+ if ( nread == 0 ) {
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): sn_read: Connection closed", name() );
+#endif
+ // ### we should rather ask the socket tqdevice if it is closed
+ d->connectionClosed();
+ emit connectionClosed();
+ TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
+ delete a;
+ return;
+ } else if ( nread < 0 ) {
+ delete a;
+
+ if ( d->socket->error() == TQSocketDevice::NoError ) {
+ // all is fine
+ TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
+ return;
+ }
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQSocket::sn_read: Read error" );
+#endif
+ if ( d->rsn )
+ d->rsn->setEnabled( FALSE );
+ emit error( ErrSocketRead );
+ TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
+ return;
+ }
+ if ( nread != (int)a->size() ) { // unexpected
+#if defined(CHECK_RANGE) && !defined(TQ_OS_WIN32)
+ qWarning( "TQSocket::sn_read: Unexpected short read" );
+#endif
+ a->resize( nread );
+ }
+ }
+ d->rba.append( a );
+ if ( !force ) {
+ if ( d->rsn )
+ d->rsn->setEnabled( FALSE );
+ emit readyRead();
+ if ( d->rsn )
+ d->rsn->setEnabled( TRUE );
+ }
+
+ TQSocketPrivate::sn_read_alreadyCalled.removeRef( this );
+}
+
+
+/*!
+ \internal
+ Internal slot for handling socket write notifications.
+*/
+
+void TQSocket::sn_write()
+{
+ if ( d->state == Connecting ) // connection established?
+ tryConnection();
+ flush();
+}
+
+void TQSocket::emitErrorConnectionRefused()
+{
+ emit error( ErrConnectionRefused );
+}
+
+void TQSocket::tryConnection()
+{
+ if ( d->socket->connect( d->addr, d->port ) ) {
+ d->state = Connected;
+#if defined(TQSOCKET_DEBUG)
+ qDebug( "TQSocket (%s): sn_write: Got connection to %s",
+ name(), peerName().ascii() );
+#endif
+ if ( d->rsn )
+ d->rsn->setEnabled( TRUE );
+ emit connected();
+ } else {
+ d->state = Idle;
+ TQTimer::singleShot( 0, this, TQT_SLOT(emitErrorConnectionRefused()) );
+ return;
+ }
+}
+
+
+/*!
+ Returns the socket number, or -1 if there is no socket at the moment.
+*/
+
+int TQSocket::socket() const
+{
+ if ( d->socket == 0 )
+ return -1;
+ return d->socket->socket();
+}
+
+/*!
+ Sets the socket to use \a socket and the state() to \c Connected.
+ The socket must already be connected.
+
+ This allows us to use the TQSocket class as a wrapper for other
+ socket types (e.g. Unix Domain Sockets).
+*/
+
+void TQSocket::setSocket( int socket )
+{
+ setSocketIntern( socket );
+ d->state = Connection;
+ d->rsn->setEnabled( TRUE );
+}
+
+
+/*!
+ Sets the socket to \a socket. This is used by both setSocket() and
+ connectToHost() and can also be used on unconnected sockets.
+*/
+
+void TQSocket::setSocketIntern( int socket )
+{
+ if ( state() != Idle ) {
+ clearPendingData();
+ close();
+ }
+ TQ_ULONG oldBufferSize = d ? d->readBufferSize : 0;
+ delete d;
+
+ d = new TQSocketPrivate;
+ if (oldBufferSize)
+ d->readBufferSize = oldBufferSize;
+ if ( socket >= 0 ) {
+ TQSocketDevice *sd = new TQSocketDevice( socket, TQSocketDevice::Stream );
+ sd->setBlocking( FALSE );
+ sd->setAddressReusable( TRUE );
+ d->setSocketDevice( this, sd );
+ }
+ d->state = Idle;
+
+ // Initialize the IO tqdevice flags
+ setFlags( IO_Direct );
+ resetqStatus();
+ open( IO_ReadWrite );
+
+ // hm... this is not very nice.
+ d->host = TQString::null;
+ d->port = 0;
+#ifndef TQT_NO_DNS
+ delete d->dns4;
+ d->dns4 = 0;
+ delete d->dns6;
+ d->dns6 = 0;
+#endif
+}
+
+
+/*!
+ Returns the host port number of this socket, in native byte order.
+*/
+
+TQ_UINT16 TQSocket::port() const
+{
+ if ( d->socket == 0 )
+ return 0;
+ return d->socket->port();
+}
+
+
+/*!
+ Returns the peer's host port number, normally as specified to the
+ connectToHost() function. If none has been set, this function
+ returns 0.
+
+ Note that TQt always uses native byte order, i.e. 67 is 67 in TQt;
+ there is no need to call htons().
+*/
+
+TQ_UINT16 TQSocket::peerPort() const
+{
+ if ( d->socket == 0 )
+ return 0;
+ return d->socket->peerPort();
+}
+
+
+/*!
+ Returns the host address of this socket. (This is normally the
+ main IP address of the host, but can be e.g. 127.0.0.1 for
+ connections to localhost.)
+*/
+
+TQHostAddress TQSocket::address() const
+{
+ if ( d->socket == 0 ) {
+ TQHostAddress tmp;
+ return tmp;
+ }
+ return d->socket->address();
+}
+
+
+/*!
+ Returns the address of the connected peer if the socket is in
+ Connected state; otherwise an empty TQHostAddress is returned.
+*/
+
+TQHostAddress TQSocket::peerAddress() const
+{
+ if ( d->socket == 0 ) {
+ TQHostAddress tmp;
+ return tmp;
+ }
+ return d->socket->peerAddress();
+}
+
+
+/*!
+ Returns the host name as specified to the connectToHost()
+ function. An empty string is returned if none has been set.
+*/
+
+TQString TQSocket::peerName() const
+{
+ return d->host;
+}
+
+/*!
+ Sets the size of the TQSocket's internal read buffer to \a bufSize.
+
+ Usually TQSocket reads all data that is available from the operating
+ system's socket. If the buffer size is limited to a certain size, this
+ means that the TQSocket class doesn't buffer more than this size of data.
+
+ If the size of the read buffer is 0, the read buffer is unlimited and all
+ incoming data is buffered. This is the default.
+
+ If you read the data in the readyRead() signal, you shouldn't use this
+ option since it might slow down your program unnecessary. This option is
+ useful if you only need to read the data at certain points in time, like in
+ a realtime streaming application.
+
+ \sa readBufferSize()
+*/
+
+void TQSocket::setReadBufferSize( TQ_ULONG bufSize )
+{
+ d->readBufferSize = bufSize;
+}
+
+/*!
+ Returns the size of the read buffer.
+
+ \sa setReadBufferSize()
+*/
+
+TQ_ULONG TQSocket::readBufferSize() const
+{
+ return d->readBufferSize;
+}
+
+#endif //TQT_NO_NETWORK
diff --git a/tqtinterface/qt4/src/network/tqsocket.h b/tqtinterface/qt4/src/network/tqsocket.h
new file mode 100644
index 0000000..664356c
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqsocket.h
@@ -0,0 +1,174 @@
+/****************************************************************************
+**
+** Definition of TQSocket class.
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSOCKET_H
+#define TQSOCKET_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqiodevice.h"
+#include "tqhostaddress.h" // int->TQHostAddress conversion
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
+#define TQM_EXPORT_NETWORK
+#else
+#define TQM_EXPORT_NETWORK TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_NETWORK
+class TQSocketPrivate;
+class TQSocketDevice;
+
+// #ifdef USE_QT4
+class TQM_EXPORT_NETWORK TQSocket : public TQIODevice
+// #else // USE_QT4
+// class TQM_EXPORT_NETWORK TQSocket : public TQObject, public TQIODevice
+// #endif // USE_QT4
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ enum Error {
+ ErrConnectionRefused,
+ ErrHostNotFound,
+ ErrSocketRead
+ };
+
+ TQSocket( TQObject *tqparent=0, const char *name=0 );
+ virtual ~TQSocket();
+
+ enum State { Idle, HostLookup, Connecting,
+ Connected, Closing,
+ Connection=Connected };
+ State state() const;
+
+ int socket() const;
+ virtual void setSocket( int );
+
+ TQSocketDevice *socketDevice();
+ virtual void setSocketDevice( TQSocketDevice * );
+
+#ifndef TQT_NO_DNS
+ virtual void connectToHost( const TQString &host, TQ_UINT16 port );
+#endif
+ TQString peerName() const;
+
+ // Implementation of TQIODevice abstract virtual functions
+ bool open( int mode );
+ void close();
+ void flush();
+#ifdef USE_QT4
+ qint64 size() const;
+ qint64 at() const;
+#else // USE_QT4
+ Offset size() const;
+ Offset at() const;
+#endif // USE_QT4
+ bool at( Offset );
+ bool atEnd() const;
+
+#ifdef USE_QT4
+ qint64 bytesAvailable() const; // ### TQIODevice::Offset instead?
+ qint64 bytesToWrite() const;
+#else // USE_QT4
+ TQ_ULONG bytesAvailable() const; // ### TQIODevice::Offset instead?
+ TQ_ULONG bytesToWrite() const;
+#endif // USE_QT4
+ TQ_ULONG waitForMore( int msecs, bool *timeout ) const;
+ TQ_ULONG waitForMore( int msecs ) const; // ### TQt 4.0: merge the two overloads
+ void clearPendingData();
+
+ TQ_LONG readBlock( char *data, TQ_ULONG maxlen );
+ TQ_LONG writeBlock( const char *data, TQ_ULONG len );
+ TQ_LONG readLine( char *data, TQ_ULONG maxlen );
+
+ int getch();
+ int putch( int );
+ int ungetch(int);
+
+ bool canReadLine() const;
+ virtual TQString readLine();
+
+ TQ_UINT16 port() const;
+ TQ_UINT16 peerPort() const;
+ TQHostAddress address() const;
+ TQHostAddress peerAddress() const;
+
+ void setReadBufferSize( TQ_ULONG );
+ TQ_ULONG readBufferSize() const;
+
+Q_SIGNALS:
+ void hostFound();
+ void connected();
+ void connectionClosed();
+ void delayedCloseFinished();
+ void readyRead();
+ void bytesWritten( int nbytes );
+ void error( int );
+
+protected Q_SLOTS:
+ virtual void sn_read( bool force=FALSE );
+ virtual void sn_write();
+
+private Q_SLOTS:
+ void tryConnecting();
+ void emitErrorConnectionRefused();
+
+private:
+ TQSocketPrivate *d;
+
+ bool consumeWriteBuf( TQ_ULONG nbytes );
+ void tryConnection();
+ void setSocketIntern( int socket );
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSocket( const TQSocket & );
+ TQSocket &operator=( const TQSocket & );
+#endif
+
+protected:
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+};
+
+#endif //TQT_NO_NETWORK
+#endif // TQSOCKET_H
diff --git a/tqtinterface/qt4/src/network/tqsocketdevice.cpp b/tqtinterface/qt4/src/network/tqsocketdevice.cpp
new file mode 100644
index 0000000..e2f7287
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqsocketdevice.cpp
@@ -0,0 +1,584 @@
+/****************************************************************************
+**
+** Implementation of TQSocketDevice class.
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsocketdevice.h"
+#ifndef TQT_NO_NETWORK
+
+#include "tqwindowdefs.h"
+#include <string.h>
+
+
+//#define TQSOCKETDEVICE_DEBUG
+
+
+class TQSocketDevicePrivate
+{
+public:
+ TQSocketDevicePrivate( TQSocketDevice::Protocol p )
+ : protocol(p)
+ { }
+
+ TQSocketDevice::Protocol protocol;
+};
+
+
+/*!
+ \class TQSocketDevice tqsocketdevice.h
+ \brief The TQSocketDevice class provides a platform-independent low-level socket API.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup io
+ \module network
+
+ This class provides a low level API for working with sockets. Users of
+ this class are assumed to have networking experience. For most users the
+ TQSocket class provides a much easier and high level alternative, but
+ certain things (like UDP) can't be done with TQSocket and if you need a
+ platform-independent API for those, TQSocketDevice is the right choice.
+
+ The essential purpose of the class is to provide a TQIODevice that
+ works on sockets, wrapped in a platform-independent API.
+
+ When calling connect() or bind(), TQSocketDevice detects the
+ protocol family (IPv4, IPv6) automatically. Passing the protocol
+ family to TQSocketDevice's constructor or to setSocket() forces
+ creation of a socket tqdevice of a specific protocol. If not set, the
+ protocol will be detected at the first call to connect() or bind().
+
+ \sa TQSocket, TQSocketNotifier, TQHostAddress
+*/
+
+
+/*!
+ \enum TQSocketDevice::Protocol
+
+ This enum type describes the protocol family of the socket. Possible values
+ are:
+
+ \value IPv4 The socket is an IPv4 socket.
+ \value IPv6 The socket is an IPv6 socket.
+ \value Unknown The protocol family of the socket is not known. This can
+ happen if you use TQSocketDevice with an already existing socket; it
+ tries to determine the protocol family, but this can fail if the
+ protocol family is not known to TQSocketDevice.
+
+ \sa protocol() setSocket()
+*/
+
+/*!
+ \enum TQSocketDevice::Error
+
+ This enum type describes the error states of TQSocketDevice.
+
+ \value NoError No error has occurred.
+
+ \value AlreadyBound The tqdevice is already bound, according to bind().
+
+ \value Inaccessible The operating system or firewall prohibited
+ the action.
+
+ \value NoResources The operating system ran out of a resource.
+
+ \value InternalError An internal error occurred in TQSocketDevice.
+
+ \value Impossible An attempt was made to do something which makes
+ no sense. For example:
+ \code
+ ::close( sd->socket() );
+ sd->writeBlock( someData, 42 );
+ \endcode
+ The libc ::close() closes the socket, but TQSocketDevice is not aware
+ of this. So when you call writeBlock(), the impossible happens.
+
+ \value NoFiles The operating system will not let TQSocketDevice open
+ another file.
+
+ \value ConnectionRefused A connection attempt was rejected by the
+ peer.
+
+ \value NetworkFailure There is a network failure.
+
+ \value UnknownError The operating system did something
+ unexpected.
+*/
+
+/*!
+ \enum TQSocketDevice::Type
+
+ This enum type describes the type of the socket:
+ \value Stream a stream socket (TCP, usually)
+ \value Datagram a datagram socket (UDP, usually)
+*/
+
+
+/*!
+ Creates a TQSocketDevice object for the existing socket \a socket.
+
+ The \a type argument must match the actual socket type; use \c
+ TQSocketDevice::Stream for a reliable, connection-oriented TCP
+ socket, or \c TQSocketDevice::Datagram for an unreliable,
+ connectionless UDP socket.
+*/
+TQSocketDevice::TQSocketDevice( int socket, Type type )
+ : fd( socket ), t( type ), p( 0 ), pp( 0 ), e( NoError ),
+ d(new TQSocketDevicePrivate(Unknown))
+{
+#if defined(TQSOCKETDEVICE_DEBUG)
+ qDebug( "TQSocketDevice: Created TQSocketDevice %p (socket %x, type %d)",
+ this, socket, type );
+#endif
+ init();
+ setSocket( socket, type );
+}
+
+/*!
+ Creates a TQSocketDevice object for a stream or datagram socket.
+
+ The \a type argument must be either \c TQSocketDevice::Stream for a
+ reliable, connection-oriented TCP socket, or \c
+ TQSocketDevice::Datagram for an unreliable UDP socket.
+
+ The socket is created as an IPv4 socket.
+
+ \sa blocking() protocol()
+*/
+TQSocketDevice::TQSocketDevice( Type type )
+ : fd( -1 ), t( type ), p( 0 ), pp( 0 ), e( NoError ),
+ d(new TQSocketDevicePrivate(IPv4))
+{
+#if defined(TQSOCKETDEVICE_DEBUG)
+ qDebug( "TQSocketDevice: Created TQSocketDevice object %p, type %d",
+ this, type );
+#endif
+ init();
+ setSocket( createNewSocket(), type );
+}
+
+/*!
+ Creates a TQSocketDevice object for a stream or datagram socket.
+
+ The \a type argument must be either \c TQSocketDevice::Stream for a
+ reliable, connection-oriented TCP socket, or \c
+ TQSocketDevice::Datagram for an unreliable UDP socket.
+
+ The \a protocol indicates whether the socket should be of type IPv4
+ or IPv6. Passing \c Unknown is not meaningful in this context and you
+ should avoid using (it creates an IPv4 socket, but your code is not easily
+ readable).
+
+ The argument \a dummy is necessary for compatibility with some
+ compilers.
+
+ \sa blocking() protocol()
+*/
+TQSocketDevice::TQSocketDevice( Type type, Protocol protocol, int )
+ : fd( -1 ), t( type ), p( 0 ), pp( 0 ), e( NoError ),
+ d(new TQSocketDevicePrivate(protocol))
+{
+#if defined(TQSOCKETDEVICE_DEBUG)
+ qDebug( "TQSocketDevice: Created TQSocketDevice object %p, type %d",
+ this, type );
+#endif
+ init();
+ setSocket( createNewSocket(), type );
+}
+
+/*!
+ Destroys the socket tqdevice and closes the socket if it is open.
+*/
+TQSocketDevice::~TQSocketDevice()
+{
+ close();
+ delete d;
+ d = 0;
+#if defined(TQSOCKETDEVICE_DEBUG)
+ qDebug( "TQSocketDevice: Destroyed TQSocketDevice %p", this );
+#endif
+}
+
+
+/*!
+ Returns TRUE if this is a valid socket; otherwise returns FALSE.
+
+ \sa socket()
+*/
+bool TQSocketDevice::isValid() const
+{
+ return fd != -1;
+}
+
+
+/*!
+ \fn Type TQSocketDevice::type() const
+
+ Returns the socket type which is either \c TQSocketDevice::Stream
+ or \c TQSocketDevice::Datagram.
+
+ \sa socket()
+*/
+TQSocketDevice::Type TQSocketDevice::type() const
+{
+ return t;
+}
+
+/*!
+ Returns the socket's protocol family, which is one of \c Unknown, \c IPv4,
+ or \c IPv6.
+
+ TQSocketDevice either creates a socket with a well known protocol family or
+ it uses an already existing socket. In the first case, this function
+ returns the protocol family it was constructed with. In the second case, it
+ tries to determine the protocol family of the socket; if this fails, it
+ returns \c Unknown.
+
+ \sa Protocol setSocket()
+*/
+TQSocketDevice::Protocol TQSocketDevice::protocol() const
+{
+ if ( d->protocol == Unknown )
+ d->protocol = getProtocol();
+ return d->protocol;
+}
+
+/*!
+ Returns the socket number, or -1 if it is an invalid socket.
+
+ \sa isValid(), type()
+*/
+int TQSocketDevice::socket() const
+{
+ return fd;
+}
+
+
+/*!
+ Sets the socket tqdevice to operate on the existing socket \a
+ socket.
+
+ The \a type argument must match the actual socket type; use \c
+ TQSocketDevice::Stream for a reliable, connection-oriented TCP
+ socket, or \c TQSocketDevice::Datagram for an unreliable,
+ connectionless UDP socket.
+
+ Any existing socket is closed.
+
+ \sa isValid(), close()
+*/
+void TQSocketDevice::setSocket( int socket, Type type )
+{
+ if ( fd != -1 ) // close any open socket
+ close();
+#if defined(TQSOCKETDEVICE_DEBUG)
+ qDebug( "TQSocketDevice::setSocket: socket %x, type %d", socket, type );
+#endif
+ t = type;
+ fd = socket;
+ d->protocol = Unknown;
+ e = NoError;
+ setFlags( IO_Sequential );
+ resetqStatus();
+ open( IO_ReadWrite );
+ fetchConnectionParameters();
+}
+
+
+/*!
+ \reimp
+
+ Opens the socket using the specified TQIODevice file \a mode. This
+ function is called from the TQSocketDevice constructors and from
+ the setSocket() function. You should not call it yourself.
+
+ \sa close().
+*/
+bool TQSocketDevice::open( int mode )
+{
+ if ( isOpen() || !isValid() )
+ return FALSE;
+#if defined(TQSOCKETDEVICE_DEBUG)
+ qDebug( "TQSocketDevice::open: mode %x", mode );
+#endif
+ setMode( mode & IO_ReadWrite );
+ setState( IO_Open );
+ return TRUE;
+}
+
+
+/*!
+ \reimp
+
+ The current TQSocketDevice implementation does not buffer at all,
+ so this is a no-op.
+*/
+void TQSocketDevice::flush()
+{
+}
+
+
+/*!
+ \reimp
+
+ The size is meaningless for a socket, therefore this function returns 0.
+*/
+#ifdef USE_QT4
+qint64 TQSocketDevice::size() const
+#else // USE_QT4
+TQIODevice::Offset TQSocketDevice::size() const
+#endif // USE_QT4
+{
+ return 0;
+}
+
+
+/*!
+ \reimp
+
+ The read/write index is meaningless for a socket, therefore this
+ function returns 0.
+*/
+#ifdef USE_QT4
+qint64 TQSocketDevice::at() const
+#else // USE_QT4
+TQIODevice::Offset TQSocketDevice::at() const
+#endif // USE_QT4
+{
+ return 0;
+}
+
+
+/*!
+ \reimp
+
+ The read/write index is meaningless for a socket, therefore this
+ function does nothing and returns TRUE.
+*/
+bool TQSocketDevice::at( Offset )
+{
+ return TRUE;
+}
+
+
+/*!
+ \reimp
+
+ Returns TRUE if no data is currently available at the socket;
+ otherwise returns FALSE.
+*/
+bool TQSocketDevice::atEnd() const
+{
+ return bytesAvailable() <= 0;
+}
+
+
+/*!
+ \reimp
+
+ \warning getch() is implemented as a one-byte readBlock(), so it
+ may be very slow if you call it more than a few times.
+
+ \sa putch() readBlock()
+*/
+int TQSocketDevice::getch()
+{
+ char buf[2];
+ return readBlock(buf,1) == 1 ? buf[0] : -1;
+}
+
+
+/*!
+ \reimp
+
+ \warning putch() is implemented as a one-byte writeBlock(), so it
+ may be very slow if you call it more than a few times.
+
+ \sa getch()
+*/
+int TQSocketDevice::putch( int ch )
+{
+ char buf[2];
+ buf[0] = ch;
+ return writeBlock(buf, 1) == 1 ? ch : -1;
+}
+
+
+/*!
+ \reimp
+
+ This implementation of ungetch returns -1 (error). A socket is a
+ sequential tqdevice and does not allow any ungetch operation.
+*/
+int TQSocketDevice::ungetch( int )
+{
+ return -1;
+}
+
+
+/*!
+ Returns TRUE if the address of this socket can be used by other
+ sockets at the same time, and FALSE if this socket claims
+ exclusive ownership.
+
+ \sa setAddressReusable()
+*/
+bool TQSocketDevice::addressReusable() const
+{
+ return option( ReuseAddress );
+}
+
+
+/*!
+ Sets the address of this socket to be usable by other sockets too
+ if \a enable is TRUE, and to be used exclusively by this socket if
+ \a enable is FALSE.
+
+ When a socket is reusable, other sockets can use the same port
+ number (and IP address), which is generally useful. Of course
+ other sockets cannot use the same
+ (address,port,peer-address,peer-port) 4-tuple as this socket, so
+ there is no risk of confusing the two TCP connections.
+
+ \sa addressReusable()
+*/
+void TQSocketDevice::setAddressReusable( bool enable )
+{
+ setOption( ReuseAddress, enable );
+}
+
+
+/*!
+ Returns the size of the operating system receive buffer.
+
+ \sa setReceiveBufferSize()
+*/
+int TQSocketDevice::receiveBufferSize() const
+{
+ return option( ReceiveBuffer );
+}
+
+
+/*!
+ Sets the size of the operating system receive buffer to \a size.
+
+ The operating system receive buffer size effectively limits two
+ things: how much data can be in transit at any one moment, and how
+ much data can be received in one iteration of the main event loop.
+
+ The default is operating system-dependent. A socket that receives
+ large amounts of data is probably best with a buffer size of
+ 49152.
+*/
+void TQSocketDevice::setReceiveBufferSize( uint size )
+{
+ setOption( ReceiveBuffer, size );
+}
+
+
+/*!
+ Returns the size of the operating system send buffer.
+
+ \sa setSendBufferSize()
+*/
+int TQSocketDevice::sendBufferSize() const
+{
+ return option( SendBuffer );
+}
+
+
+/*!
+ Sets the size of the operating system send buffer to \a size.
+
+ The operating system send buffer size effectively limits how much
+ data can be in transit at any one moment.
+
+ The default is operating system-dependent. A socket that sends
+ large amounts of data is probably best with a buffer size of
+ 49152.
+*/
+void TQSocketDevice::setSendBufferSize( uint size )
+{
+ setOption( SendBuffer, size );
+}
+
+
+/*!
+ Returns the port number of this socket tqdevice. This may be 0 for a
+ while, but is set to something sensible as soon as a sensible
+ value is available.
+
+ Note that TQt always uses native byte order, i.e. 67 is 67 in TQt;
+ there is no need to call htons().
+*/
+TQ_UINT16 TQSocketDevice::port() const
+{
+ return p;
+}
+
+
+/*!
+ Returns the address of this socket tqdevice. This may be 0.0.0.0 for
+ a while, but is set to something sensible as soon as a sensible
+ value is available.
+*/
+TQHostAddress TQSocketDevice::address() const
+{
+ return a;
+}
+
+
+/*!
+ Returns the first error seen.
+*/
+TQSocketDevice::Error TQSocketDevice::error() const
+{
+ return e;
+}
+
+
+/*!
+ Allows subclasses to set the error state to \a err.
+*/
+void TQSocketDevice::setError( Error err )
+{
+ e = err;
+}
+#endif //TQT_NO_NETWORK
+
diff --git a/tqtinterface/qt4/src/network/tqsocketdevice.h b/tqtinterface/qt4/src/network/tqsocketdevice.h
new file mode 100644
index 0000000..050ad5b
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqsocketdevice.h
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Definition of TQSocketDevice class.
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSOCKETDEVICE_H
+#define TQSOCKETDEVICE_H
+
+#ifndef TQT_H
+#include "tqiodevice.h"
+#include "tqhostaddress.h" // int->TQHostAddress conversion
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_NETWORK ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_NETWORK )
+#define TQM_EXPORT_NETWORK
+#else
+#define TQM_EXPORT_NETWORK TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_NETWORK
+class TQSocketDevicePrivate;
+
+#define QT_SOCKLEN_T socklen_t
+
+class TQM_EXPORT_NETWORK TQSocketDevice: public TQIODevice
+{
+public:
+ enum Type { Stream, Datagram };
+ enum Protocol { IPv4, IPv6, Unknown };
+
+ TQSocketDevice( Type type = Stream );
+ TQSocketDevice( Type type, Protocol protocol, int dummy );
+ TQSocketDevice( int socket, Type type );
+ virtual ~TQSocketDevice();
+
+ bool isValid() const;
+ Type type() const;
+ Protocol protocol() const;
+
+ int socket() const;
+ virtual void setSocket( int socket, Type type );
+
+ bool open( int mode );
+ void close();
+ void flush();
+
+ // Implementation of TQIODevice abstract virtual functions
+#ifdef USE_QT4
+ qint64 size() const;
+ qint64 at() const;
+#else // USE_QT4
+ Offset size() const;
+ Offset at() const;
+#endif // USE_QT4
+ bool at( Offset );
+ bool atEnd() const;
+
+ bool blocking() const;
+ virtual void setBlocking( bool );
+
+ bool addressReusable() const;
+ virtual void setAddressReusable( bool );
+
+ int receiveBufferSize() const;
+ virtual void setReceiveBufferSize( uint );
+ int sendBufferSize() const;
+ virtual void setSendBufferSize( uint );
+
+ virtual bool connect( const TQHostAddress &, TQ_UINT16 );
+
+ virtual bool bind( const TQHostAddress &, TQ_UINT16 );
+ virtual bool listen( int backlog );
+ virtual int accept();
+
+#ifdef USE_QT4
+ qint64 bytesAvailable() const;
+#else // USE_QT4
+ TQ_LONG bytesAvailable() const;
+#endif // USE_QT4
+ TQ_LONG waitForMore( int msecs, bool *timeout=0 ) const;
+ TQ_LONG readBlock( char *data, TQ_ULONG maxlen );
+ TQ_LONG writeBlock( const char *data, TQ_ULONG len );
+ virtual TQ_LONG writeBlock( const char *data, TQ_ULONG len,
+ const TQHostAddress & host, TQ_UINT16 port );
+
+ int getch();
+ int putch( int );
+ int ungetch(int);
+
+ TQ_UINT16 port() const;
+ TQ_UINT16 peerPort() const;
+ TQHostAddress address() const;
+ TQHostAddress peerAddress() const;
+
+ enum Error {
+ NoError,
+ AlreadyBound,
+ Inaccessible,
+ NoResources,
+ InternalError,
+ Bug = InternalError, // ### remove in 4.0?
+ Impossible,
+ NoFiles,
+ ConnectionRefused,
+ NetworkFailure,
+ UnknownError
+ };
+ Error error() const;
+
+protected:
+ void setError( Error err );
+
+private:
+ int fd;
+ Type t;
+ TQ_UINT16 p;
+ TQHostAddress a;
+ TQ_UINT16 pp;
+ TQHostAddress pa;
+ TQSocketDevice::Error e;
+ TQSocketDevicePrivate * d;
+
+ enum Option { Broadcast, ReceiveBuffer, ReuseAddress, SendBuffer };
+
+ int option( Option ) const;
+ virtual void setOption( Option, int );
+
+ void fetchConnectionParameters();
+#if defined(TQ_OS_WIN32)
+ void fetchPeerConnectionParameters();
+#endif
+
+ static void init();
+ int createNewSocket();
+ Protocol getProtocol() const;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSocketDevice( const TQSocketDevice & );
+ TQSocketDevice &operator=( const TQSocketDevice & );
+#endif
+
+protected:
+// void setError( Error err );
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+};
+
+#endif // TQT_NO_NETWORK
+#endif // TQSOCKETDEVICE_H
diff --git a/tqtinterface/qt4/src/network/tqsocketdevice_unix.cpp b/tqtinterface/qt4/src/network/tqsocketdevice_unix.cpp
new file mode 100644
index 0000000..a0bf65d
--- /dev/null
+++ b/tqtinterface/qt4/src/network/tqsocketdevice_unix.cpp
@@ -0,0 +1,1269 @@
+/****************************************************************************
+**
+** Implementation of TQSocketDevice class.
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the network module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// Almost always the same. If not, specify in qplatformdefs.h.
+#if !defined(TQT_SOCKOPTLEN_T)
+# define TQT_SOCKOPTLEN_T TQT_SOCKLEN_T
+#endif
+
+// Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDED
+static inline int qt_socket_accept(int s, struct sockaddr *addr, TQT_SOCKLEN_T *addrlen)
+{ return ::accept(s, addr, addrlen); }
+#if defined(accept)
+# undef accept
+#endif
+
+// Solaris redefines bind -> __xnet_bind with _XOPEN_SOURCE_EXTENDED
+static inline int qt_socket_bind(int s, struct sockaddr *addr, TQT_SOCKLEN_T addrlen)
+{ return ::bind(s, addr, addrlen); }
+#if defined(bind)
+# undef bind
+#endif
+
+// Solaris redefines connect -> __xnet_connect with _XOPEN_SOURCE_EXTENDED
+static inline int qt_socket_connect(int s, struct sockaddr *addr, TQT_SOCKLEN_T addrlen)
+{ return ::connect(s, addr, addrlen); }
+#if defined(connect)
+# undef connect
+#endif
+
+// UnixWare 7 redefines listen -> _listen
+static inline int qt_socket_listen(int s, int backlog)
+{ return ::listen(s, backlog); }
+#if defined(listen)
+# undef listen
+#endif
+
+// UnixWare 7 redefines socket -> _socket
+static inline int qt_socket_socket(int domain, int type, int protocol)
+{ return ::socket(domain, type, protocol); }
+#if defined(socket)
+# undef socket
+#endif
+
+#include "tqsocketdevice.h"
+
+#ifndef TQT_NO_NETWORK
+
+#include "tqwindowdefs.h"
+
+#include <errno.h>
+#include <sys/types.h>
+
+
+static inline void qt_socket_getportaddr( struct sockaddr *sa,
+ TQ_UINT16 *port, TQHostAddress *addr )
+{
+#if !defined(TQT_NO_IPV6)
+ if ( sa->sa_family == AF_INET6 ) {
+ struct sockaddr_in6 *sa6 = ( struct sockaddr_in6 * )sa;
+ TQ_IPV6ADDR tmp;
+ memcpy( &tmp, &sa6->sin6_addr.s6_addr, sizeof(tmp) );
+ TQHostAddress a( tmp );
+ *addr = a;
+ *port = ntohs( sa6->sin6_port );
+ return;
+ }
+#endif
+ struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;
+ TQHostAddress a( ntohl( sa4->sin_addr.s_addr ) );
+ *port = ntohs( sa4->sin_port );
+ *addr = TQHostAddress( ntohl( sa4->sin_addr.s_addr ) );
+ return;
+}
+
+#ifdef USE_QT4
+
+qint64 TQSocketDevice::readData( char *data, qint64 maxlen )
+{
+#if defined(QT_CHECK_NULL)
+ if ( data == 0 && maxlen != 0 ) {
+ qWarning( "TQSocketDevice::readBlock: Null pointer error" );
+ }
+#endif
+#if defined(QT_CHECK_STATE)
+ if ( !isValid() ) {
+ qWarning( "TQSocketDevice::readBlock: Invalid socket" );
+ return -1;
+ }
+ if ( !isOpen() ) {
+ qWarning( "TQSocketDevice::readBlock: Device is not open" );
+ return -1;
+ }
+ if ( !isReadable() ) {
+ qWarning( "TQSocketDevice::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ bool done = false;
+ int r = 0;
+ while ( done == false ) {
+ if ( t == Datagram ) {
+#if !defined(QT_NO_IPV6)
+ struct sockaddr_storage aa;
+#else
+ struct sockaddr_in aa;
+#endif
+ memset( &aa, 0, sizeof(aa) );
+ QT_SOCKLEN_T sz;
+ sz = sizeof( aa );
+ r = ::recvfrom( fd, data, maxlen, 0,
+ (struct sockaddr *)&aa, &sz );
+
+ qt_socket_getportaddr( (struct sockaddr *)&aa, &pp, &pa);
+
+ } else {
+ r = ::read( fd, data, maxlen );
+ }
+ done = true;
+ if ( r == 0 && t == Stream && maxlen > 0 ) {
+ // connection closed
+ close();
+ } else if ( r >= 0 || errno == EAGAIN || errno == EWOULDBLOCK ) {
+ // nothing
+ } else if ( errno == EINTR ) {
+ done = false;
+ } else if ( e == NoError ) {
+ switch( errno ) {
+ case EIO:
+ case EISDIR:
+ case EBADF:
+ case EINVAL:
+ case EFAULT:
+ case ENOTCONN:
+ case ENOTSOCK:
+ e = Impossible;
+ break;
+#if defined(ENONET)
+ case ENONET:
+#endif
+ case EHOSTUNREACH:
+ case ENETDOWN:
+ case ENETUNREACH:
+ case ETIMEDOUT:
+ e = NetworkFailure;
+ break;
+ case EPIPE:
+ case ECONNRESET:
+ // connection closed
+ close();
+ r = 0;
+ break;
+ default:
+ e = UnknownError;
+ break;
+ }
+ }
+ }
+ return r;
+}
+
+
+qint64 TQSocketDevice::writeData( const char *data, qint64 len )
+{
+ if ( data == 0 && len != 0 ) {
+#if defined(QT_CHECK_NULL) || defined(QSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::writeBlock: Null pointer error" );
+#endif
+ return -1;
+ }
+ if ( !isValid() ) {
+#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::writeBlock: Invalid socket" );
+#endif
+ return -1;
+ }
+ if ( !isOpen() ) {
+#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::writeBlock: Device is not open" );
+#endif
+ return -1;
+ }
+ if ( !isWritable() ) {
+#if defined(QT_CHECK_STATE) || defined(QSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::writeBlock: Write operation not permitted" );
+#endif
+ return -1;
+ }
+ bool done = false;
+ int r = 0;
+ bool timeout;
+ while ( !done ) {
+ r = ::write( fd, data, len );
+ done = true;
+ if ( r < 0 && e == NoError &&
+ errno != EAGAIN && errno != EWOULDBLOCK ) {
+ switch( errno ) {
+ case EINTR: // signal - call read() or whatever again
+ done = false;
+ break;
+ case EPIPE:
+ case ECONNRESET:
+ // connection closed
+ close();
+ r = 0;
+ break;
+ case ENOSPC:
+ case EIO:
+ case EISDIR:
+ case EBADF:
+ case EINVAL:
+ case EFAULT:
+ case ENOTCONN:
+ case ENOTSOCK:
+ e = Impossible;
+ break;
+#if defined(ENONET)
+ case ENONET:
+#endif
+ case EHOSTUNREACH:
+ case ENETDOWN:
+ case ENETUNREACH:
+ case ETIMEDOUT:
+ e = NetworkFailure;
+ break;
+ default:
+ e = UnknownError;
+ break;
+ }
+ } else if ( waitForMore( 0, &timeout ) == 0 ) {
+ if ( !timeout ) {
+ // connection closed
+ close();
+ }
+ }
+ }
+ return r;
+}
+
+#endif // USE_QT4
+
+
+//#define TQSOCKETDEVICE_DEBUG
+
+// internal
+void TQSocketDevice::init()
+{
+}
+
+
+TQSocketDevice::Protocol TQSocketDevice::getProtocol() const
+{
+ if ( isValid() ) {
+#if !defined (TQT_NO_IPV6)
+ struct sockaddr_storage sa;
+#else
+ struct sockaddr sa;
+#endif
+ memset( &sa, 0, sizeof(sa) );
+ TQT_SOCKLEN_T sz = sizeof( sa );
+#if !defined (TQT_NO_IPV6)
+ struct sockaddr *sap = reinterpret_cast<struct sockaddr *>(&sa);
+ if ( !::getsockname(fd, sap, &sz) ) {
+ switch ( sap->sa_family ) {
+ case AF_INET:
+ return IPv4;
+ case AF_INET6:
+ return IPv6;
+ default:
+ return Unknown;
+ }
+ }
+#else
+ if ( !::getsockname(fd, &sa, &sz) ) {
+ switch ( sa.sa_family ) {
+ case AF_INET:
+ return IPv4;
+ default:
+ return Unknown;
+ }
+ }
+#endif
+ }
+ return Unknown;
+}
+
+/*!
+ Creates a new socket identifier. Returns -1 if there is a failure
+ to create the new identifier; error() explains why.
+
+ \sa setSocket()
+*/
+
+int TQSocketDevice::createNewSocket()
+{
+#if !defined(TQT_NO_IPV6)
+ int s = qt_socket_socket( protocol() == IPv6 ? AF_INET6 : AF_INET,
+ t == Datagram ? SOCK_DGRAM : SOCK_STREAM, 0 );
+#else
+ int s = qt_socket_socket( AF_INET, t==Datagram?SOCK_DGRAM:SOCK_STREAM, 0 );
+#endif
+ if ( s < 0 ) {
+ switch( errno ) {
+ case EPROTONOSUPPORT:
+ e = InternalError; // 0 is supposed to work for both types
+ break;
+ case ENFILE:
+ e = NoFiles; // special case for this
+ break;
+ case EACCES:
+ e = Inaccessible;
+ break;
+ case ENOBUFS:
+ case ENOMEM:
+ e = NoResources;
+ break;
+ case EINVAL:
+ e = Impossible;
+ break;
+ default:
+ e = UnknownError;
+ break;
+ }
+ } else {
+ // ensure that the socket is closed on exec..() after being dup()'ed by
+ // fork() in TQProcess.
+ ::fcntl(s, F_SETFD, FD_CLOEXEC);
+ return s;
+ }
+ return -1;
+}
+
+/*!
+ \reimp
+
+ Closes the socket and sets the socket identifier to -1 (invalid).
+
+ (This function ignores errors; if there are any then a file
+ descriptor leakage might result. As far as we know, the only error
+ that can arise is EBADF, and that would of course not cause
+ leakage. There may be OS-specfic errors that we haven't come
+ across, however.)
+
+ \sa open()
+*/
+void TQSocketDevice::close()
+{
+ if ( fd == -1 || !isOpen() ) // already closed
+ return;
+ setFlags( IO_Sequential );
+ resetqStatus();
+ setState( 0 );
+ ::close( fd );
+#if defined(TQSOCKETDEVICE_DEBUG)
+ qDebug( "TQSocketDevice::close: Closed socket %x", fd );
+#endif
+ fd = -1;
+ fetchConnectionParameters();
+}
+
+
+/*!
+ Returns TRUE if the socket is valid and in blocking mode;
+ otherwise returns FALSE.
+
+ Note that this function does not set error().
+
+ \warning On Windows, this function always returns TRUE since the
+ ioctlsocket() function is broken.
+
+ \sa setBlocking(), isValid()
+*/
+bool TQSocketDevice::blocking() const
+{
+ if ( !isValid() )
+ return TRUE;
+ int s = fcntl(fd, F_GETFL, 0);
+ return !(s >= 0 && ((s & O_NDELAY) != 0));
+}
+
+
+/*!
+ Makes the socket blocking if \a enable is TRUE or nonblocking if
+ \a enable is FALSE.
+
+ Sockets are blocking by default, but we recommend using
+ nonblocking socket operations, especially for GUI programs that
+ need to be responsive.
+
+ \warning On Windows, this function should be used with care since
+ whenever you use a TQSocketNotifier on Windows, the socket is
+ immediately made nonblocking.
+
+ \sa blocking(), isValid()
+*/
+void TQSocketDevice::setBlocking( bool enable )
+{
+#if defined(TQSOCKETDEVICE_DEBUG)
+ qDebug( "TQSocketDevice::setBlocking( %d )", enable );
+#endif
+ if ( !isValid() )
+ return;
+ int tmp = ::fcntl(fd, F_GETFL, 0);
+ if ( tmp >= 0 )
+ tmp = ::fcntl( fd, F_SETFL, enable ? (tmp&~O_NDELAY) : (tmp|O_NDELAY) );
+ if ( tmp >= 0 )
+ return;
+ if ( e )
+ return;
+ switch( errno ) {
+ case EACCES:
+ case EBADF:
+ e = Impossible;
+ break;
+ case EFAULT:
+ case EAGAIN:
+#if EAGAIN != EWOULDBLOCK
+ case EWOULDBLOCK:
+#endif
+ case EDEADLK:
+ case EINTR:
+ case EINVAL:
+ case EMFILE:
+ case ENOLCK:
+ case EPERM:
+ default:
+ e = UnknownError;
+ }
+}
+
+
+/*!
+ Returns the value of the socket option \a opt.
+*/
+int TQSocketDevice::option( Option opt ) const
+{
+ if ( !isValid() )
+ return -1;
+ int n = -1;
+ int v = -1;
+ switch ( opt ) {
+ case Broadcast:
+ n = SO_BROADCAST;
+ break;
+ case ReceiveBuffer:
+ n = SO_RCVBUF;
+ break;
+ case ReuseAddress:
+ n = SO_REUSEADDR;
+ break;
+ case SendBuffer:
+ n = SO_SNDBUF;
+ break;
+ }
+ if ( n != -1 ) {
+ TQT_SOCKOPTLEN_T len;
+ len = sizeof(v);
+ int r = ::getsockopt( fd, SOL_SOCKET, n, (char*)&v, &len );
+ if ( r >= 0 )
+ return v;
+ if ( !e ) {
+ TQSocketDevice *that = (TQSocketDevice*)this; // mutable function
+ switch( errno ) {
+ case EBADF:
+ case ENOTSOCK:
+ that->e = Impossible;
+ break;
+ case EFAULT:
+ that->e = InternalError;
+ break;
+ default:
+ that->e = UnknownError;
+ break;
+ }
+ }
+ return -1;
+ }
+ return v;
+}
+
+
+/*!
+ Sets the socket option \a opt to \a v.
+*/
+void TQSocketDevice::setOption( Option opt, int v )
+{
+ if ( !isValid() )
+ return;
+ int n = -1; // for really, really bad compilers
+ switch ( opt ) {
+ case Broadcast:
+ n = SO_BROADCAST;
+ break;
+ case ReceiveBuffer:
+ n = SO_RCVBUF;
+ break;
+ case ReuseAddress:
+ n = SO_REUSEADDR;
+ break;
+ case SendBuffer:
+ n = SO_SNDBUF;
+ break;
+ default:
+ return;
+ }
+ if ( ::setsockopt( fd, SOL_SOCKET, n, (char*)&v, sizeof(v)) < 0 &&
+ e == NoError ) {
+ switch( errno ) {
+ case EBADF:
+ case ENOTSOCK:
+ e = Impossible;
+ break;
+ case EFAULT:
+ e = InternalError;
+ break;
+ default:
+ e = UnknownError;
+ break;
+ }
+ }
+}
+
+
+/*!
+ Connects to the IP address and port specified by \a addr and \a
+ port. Returns TRUE if it establishes a connection; otherwise returns FALSE.
+ If it returns FALSE, error() explains why.
+
+ Note that error() commonly returns NoError for non-blocking
+ sockets; this just means that you can call connect() again in a
+ little while and it'll probably succeed.
+*/
+bool TQSocketDevice::connect( const TQHostAddress &addr, TQ_UINT16 port )
+{
+ if ( !isValid() )
+ return FALSE;
+
+ pa = addr;
+ pp = port;
+
+ struct sockaddr_in a4;
+ struct sockaddr *aa;
+ TQT_SOCKLEN_T aalen;
+
+#if !defined(TQT_NO_IPV6)
+ struct sockaddr_in6 a6;
+
+ if ( addr.isIPv6Address() ) {
+ memset( &a6, 0, sizeof(a6) );
+ a6.sin6_family = AF_INET6;
+ a6.sin6_port = htons( port );
+ TQ_IPV6ADDR ip6 = addr.toIPv6Address();
+ memcpy( &a6.sin6_addr.s6_addr, &ip6, sizeof(ip6) );
+
+ aalen = sizeof( a6 );
+ aa = (struct sockaddr *)&a6;
+ } else
+#endif
+ if ( addr.isIPv4Address() ) {
+ memset( &a4, 0, sizeof(a4) );
+ a4.sin_family = AF_INET;
+ a4.sin_port = htons( port );
+ a4.sin_addr.s_addr = htonl( addr.toIPv4Address() );
+
+ aalen = sizeof(a4);
+ aa = (struct sockaddr *)&a4;
+ } else {
+ e = Impossible;
+ return FALSE;
+ }
+
+ int r = qt_socket_connect( fd, aa, aalen );
+ if ( r == 0 ) {
+ fetchConnectionParameters();
+ return TRUE;
+ }
+ if ( errno == EISCONN || errno == EALREADY || errno == EINPROGRESS ) {
+ fetchConnectionParameters();
+ return TRUE;
+ }
+ if ( e != NoError || errno == EAGAIN || errno == EWOULDBLOCK ) {
+ return FALSE;
+ }
+ switch( errno ) {
+ case EBADF:
+ case ENOTSOCK:
+ e = Impossible;
+ break;
+ case EFAULT:
+ case EAFNOSUPPORT:
+ e = InternalError;
+ break;
+ case ECONNREFUSED:
+ e = ConnectionRefused;
+ break;
+ case ETIMEDOUT:
+ case ENETUNREACH:
+ e = NetworkFailure;
+ break;
+ case EADDRINUSE:
+ e = NoResources;
+ break;
+ case EACCES:
+ case EPERM:
+ e = Inaccessible;
+ break;
+ default:
+ e = UnknownError;
+ break;
+ }
+ return FALSE;
+}
+
+
+/*!
+ Assigns a name to an unnamed socket. The name is the host address
+ \a address and the port number \a port. If the operation succeeds,
+ bind() returns TRUE; otherwise it returns FALSE without changing
+ what port() and address() return.
+
+ bind() is used by servers for setting up incoming connections.
+ Call bind() before listen().
+*/
+bool TQSocketDevice::bind( const TQHostAddress &address, TQ_UINT16 port )
+{
+ if ( !isValid() )
+ return FALSE;
+ int r;
+ struct sockaddr_in a4;
+#if !defined(TQT_NO_IPV6)
+ struct sockaddr_in6 a6;
+
+ if ( address.isIPv6Address() ) {
+ memset( &a6, 0, sizeof(a6) );
+ a6.sin6_family = AF_INET6;
+ a6.sin6_port = htons( port );
+ TQ_IPV6ADDR tmp = address.toIPv6Address();
+ memcpy( &a6.sin6_addr.s6_addr, &tmp, sizeof(tmp) );
+
+ r = qt_socket_bind( fd, (struct sockaddr *)&a6, sizeof(a6) );
+ } else
+#endif
+ if ( address.isIPv4Address() ) {
+ memset( &a4, 0, sizeof(a4) );
+ a4.sin_family = AF_INET;
+ a4.sin_port = htons( port );
+ a4.sin_addr.s_addr = htonl( address.toIPv4Address() );
+
+ r = qt_socket_bind( fd, (struct sockaddr*)&a4, sizeof(a4) );
+ } else {
+ e = Impossible;
+ return FALSE;
+ }
+
+ if ( r < 0 ) {
+ switch( errno ) {
+ case EINVAL:
+ e = AlreadyBound;
+ break;
+ case EACCES:
+ e = Inaccessible;
+ break;
+ case ENOMEM:
+ e = NoResources;
+ break;
+ case EFAULT: // a was illegal
+ case ENAMETOOLONG: // sz was wrong
+ e = InternalError;
+ break;
+ case EBADF: // AF_UNIX only
+ case ENOTSOCK: // AF_UNIX only
+ case EROFS: // AF_UNIX only
+ case ENOENT: // AF_UNIX only
+ case ENOTDIR: // AF_UNIX only
+ case ELOOP: // AF_UNIX only
+ e = Impossible;
+ break;
+ default:
+ e = UnknownError;
+ break;
+ }
+ return FALSE;
+ }
+ fetchConnectionParameters();
+ return TRUE;
+}
+
+
+/*!
+ Specifies how many pending connections a server socket can have.
+ Returns TRUE if the operation was successful; otherwise returns
+ FALSE. A \a backlog value of 50 is quite common.
+
+ The listen() call only applies to sockets where type() is \c
+ Stream, i.e. not to \c Datagram sockets. listen() must not be
+ called before bind() or after accept().
+
+ \sa bind(), accept()
+*/
+bool TQSocketDevice::listen( int backlog )
+{
+ if ( !isValid() )
+ return FALSE;
+ if ( qt_socket_listen( fd, backlog ) >= 0 )
+ return TRUE;
+ if ( !e )
+ e = Impossible;
+ return FALSE;
+}
+
+
+/*!
+ Extracts the first connection from the queue of pending
+ connections for this socket and returns a new socket identifier.
+ Returns -1 if the operation failed.
+
+ \sa bind(), listen()
+*/
+int TQSocketDevice::accept()
+{
+ if ( !isValid() )
+ return -1;
+
+#if !defined (TQT_NO_IPV6)
+ struct sockaddr_storage aa;
+#else
+ struct sockaddr aa;
+#endif
+ TQT_SOCKLEN_T l = sizeof( aa );
+ bool done;
+ int s;
+ do {
+ s = qt_socket_accept( fd, (struct sockaddr*)&aa, &l );
+ // we'll blithely throw away the stuff accept() wrote to aa
+ done = TRUE;
+ if ( s < 0 && e == NoError ) {
+ switch( errno ) {
+ case EINTR:
+ done = FALSE;
+ break;
+#if defined(EPROTO)
+ case EPROTO:
+#endif
+#if defined(ENONET)
+ case ENONET:
+#endif
+ case ENOPROTOOPT:
+ case EHOSTDOWN:
+ case EOPNOTSUPP:
+ case EHOSTUNREACH:
+ case ENETDOWN:
+ case ENETUNREACH:
+ case ETIMEDOUT:
+ // in all these cases, an error happened during connection
+ // setup. we're not interested in what happened, so we
+ // just treat it like the client-closed-quickly case.
+ case EPERM:
+ // firewalling wouldn't let us accept. we treat it like
+ // the client-closed-quickly case.
+ case EAGAIN:
+#if EAGAIN != EWOULDBLOCK
+ case EWOULDBLOCK:
+#endif
+ // the client closed the connection before we got around
+ // to accept()ing it.
+ break;
+ case EBADF:
+ case ENOTSOCK:
+ e = Impossible;
+ break;
+ case EFAULT:
+ e = InternalError;
+ break;
+ case ENOMEM:
+ case ENOBUFS:
+ e = NoResources;
+ break;
+ default:
+ e = UnknownError;
+ break;
+ }
+ }
+ } while (!done);
+ // ensure that the socket is closed on exec..() after being dup()'ed by
+ // fork() in TQProcess.
+ ::fcntl(s, F_SETFD, FD_CLOEXEC);
+ return s;
+}
+
+
+/*!
+ Returns the number of bytes available for reading, or -1 if an
+ error occurred.
+
+ \warning On Microsoft Windows, we use the ioctlsocket() function
+ to determine the number of bytes queued on the socket. According
+ to Microsoft (KB Q125486), ioctlsocket() sometimes returns an
+ incorrect number. The only safe way to determine the amount of
+ data on the socket is to read it using readBlock(). TQSocket has
+ workarounds to deal with this problem.
+*/
+#ifdef USE_QT4
+qint64 TQSocketDevice::bytesAvailable() const
+#else // USE_QT4
+TQ_LONG TQSocketDevice::bytesAvailable() const
+#endif // USE_QT4
+{
+ if ( !isValid() )
+ return -1;
+
+ /*
+ Apparently, there is not consistency among different operating
+ systems on how to use FIONREAD.
+
+ FreeBSD, Linux and Solaris all expect the 3rd argument to
+ ioctl() to be an int, which is normally 32-bit even on 64-bit
+ machines.
+
+ IRIX, on the other hand, expects a size_t, which is 64-bit on
+ 64-bit machines.
+
+ So, the solution is to use size_t initialized to zero to make
+ sure all bits are set to zero, preventing underflow with the
+ FreeBSD/Linux/Solaris ioctls.
+ */
+ size_t nbytes = 0;
+ // gives shorter than true amounts on Unix domain sockets.
+ if ( ::ioctl(fd, FIONREAD, (char*)&nbytes) < 0 )
+ return -1;
+ return (TQ_LONG) *((int *) &nbytes);
+}
+
+
+/*!
+ Wait up to \a msecs milliseconds for more data to be available. If
+ \a msecs is -1 the call will block indefinitely.
+
+ Returns the number of bytes available for reading, or -1 if an
+ error occurred.
+
+ If \a timeout is non-null and no error occurred (i.e. it does not
+ return -1): this function sets \a *timeout to TRUE, if the reason
+ for returning was that the timeout was reached; otherwise it sets
+ \a *timeout to FALSE. This is useful to tqfind out if the peer
+ closed the connection.
+
+ \warning This is a blocking call and should be avoided in event
+ driven applications.
+
+ \sa bytesAvailable()
+*/
+TQ_LONG TQSocketDevice::waitForMore( int msecs, bool *timeout ) const
+{
+ if ( !isValid() )
+ return -1;
+ if ( fd >= FD_SETSIZE )
+ return -1;
+
+ fd_set fds;
+ struct timeval tv;
+
+ FD_ZERO( &fds );
+ FD_SET( fd, &fds );
+
+ tv.tv_sec = msecs / 1000;
+ tv.tv_usec = (msecs % 1000) * 1000;
+
+ int rv = select( fd+1, &fds, 0, 0, msecs < 0 ? 0 : &tv );
+
+ if ( rv < 0 )
+ return -1;
+
+ if ( timeout ) {
+ if ( rv == 0 )
+ *timeout = TRUE;
+ else
+ *timeout = FALSE;
+ }
+
+ return bytesAvailable();
+}
+
+
+/*!
+ Reads \a maxlen bytes from the socket into \a data and returns the
+ number of bytes read. Returns -1 if an error occurred. Returning 0
+ is not an error. For Stream sockets, 0 is returned when the remote
+ host closes the connection. For Datagram sockets, 0 is a valid
+ datagram size.
+*/
+TQ_LONG TQSocketDevice::readBlock( char *data, TQ_ULONG maxlen )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( data == 0 && maxlen != 0 ) {
+ qWarning( "TQSocketDevice::readBlock: Null pointer error" );
+ }
+#endif
+#if defined(TQT_CHECK_STATE)
+ if ( !isValid() ) {
+ qWarning( "TQSocketDevice::readBlock: Invalid socket" );
+ return -1;
+ }
+ if ( !isOpen() ) {
+ qWarning( "TQSocketDevice::readBlock: Device is not open" );
+ return -1;
+ }
+ if ( !isReadable() ) {
+ qWarning( "TQSocketDevice::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ bool done = FALSE;
+ int r = 0;
+ while ( done == FALSE ) {
+ if ( t == Datagram ) {
+#if !defined(TQT_NO_IPV6)
+ struct sockaddr_storage aa;
+#else
+ struct sockaddr_in aa;
+#endif
+ memset( &aa, 0, sizeof(aa) );
+ TQT_SOCKLEN_T sz;
+ sz = sizeof( aa );
+ r = ::recvfrom( fd, data, maxlen, 0,
+ (struct sockaddr *)&aa, &sz );
+
+ qt_socket_getportaddr( (struct sockaddr *)&aa, &pp, &pa);
+
+ } else {
+ r = ::read( fd, data, maxlen );
+ }
+ done = TRUE;
+ if ( r == 0 && t == Stream && maxlen > 0 ) {
+ // connection closed
+ close();
+ } else if ( r >= 0 || errno == EAGAIN || errno == EWOULDBLOCK ) {
+ // nothing
+ } else if ( errno == EINTR ) {
+ done = FALSE;
+ } else if ( e == NoError ) {
+ switch( errno ) {
+ case EIO:
+ case EISDIR:
+ case EBADF:
+ case EINVAL:
+ case EFAULT:
+ case ENOTCONN:
+ case ENOTSOCK:
+ e = Impossible;
+ break;
+#if defined(ENONET)
+ case ENONET:
+#endif
+ case EHOSTUNREACH:
+ case ENETDOWN:
+ case ENETUNREACH:
+ case ETIMEDOUT:
+ e = NetworkFailure;
+ break;
+ case EPIPE:
+ case ECONNRESET:
+ // connection closed
+ close();
+ r = 0;
+ break;
+ default:
+ e = UnknownError;
+ break;
+ }
+ }
+ }
+ return r;
+}
+
+
+/*!
+ Writes \a len bytes to the socket from \a data and returns the
+ number of bytes written. Returns -1 if an error occurred.
+
+ This is used for \c TQSocketDevice::Stream sockets.
+*/
+TQ_LONG TQSocketDevice::writeBlock( const char *data, TQ_ULONG len )
+{
+ if ( data == 0 && len != 0 ) {
+#if defined(TQT_CHECK_NULL) || defined(TQSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::writeBlock: Null pointer error" );
+#endif
+ return -1;
+ }
+ if ( !isValid() ) {
+#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::writeBlock: Invalid socket" );
+#endif
+ return -1;
+ }
+ if ( !isOpen() ) {
+#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::writeBlock: Device is not open" );
+#endif
+ return -1;
+ }
+ if ( !isWritable() ) {
+#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::writeBlock: Write operation not permitted" );
+#endif
+ return -1;
+ }
+ bool done = FALSE;
+ int r = 0;
+ bool timeout;
+ while ( !done ) {
+ r = ::write( fd, data, len );
+ done = TRUE;
+ if ( r < 0 && e == NoError &&
+ errno != EAGAIN && errno != EWOULDBLOCK ) {
+ switch( errno ) {
+ case EINTR: // signal - call read() or whatever again
+ done = FALSE;
+ break;
+ case EPIPE:
+ case ECONNRESET:
+ // connection closed
+ close();
+ r = 0;
+ break;
+ case ENOSPC:
+ case EIO:
+ case EISDIR:
+ case EBADF:
+ case EINVAL:
+ case EFAULT:
+ case ENOTCONN:
+ case ENOTSOCK:
+ e = Impossible;
+ break;
+#if defined(ENONET)
+ case ENONET:
+#endif
+ case EHOSTUNREACH:
+ case ENETDOWN:
+ case ENETUNREACH:
+ case ETIMEDOUT:
+ e = NetworkFailure;
+ break;
+ default:
+ e = UnknownError;
+ break;
+ }
+ } else if ( waitForMore( 0, &timeout ) == 0 ) {
+ if ( !timeout ) {
+ // connection closed
+ close();
+ }
+ }
+ }
+ return r;
+}
+
+
+/*!
+ \overload
+
+ Writes \a len bytes to the socket from \a data and returns the
+ number of bytes written. Returns -1 if an error occurred.
+
+ This is used for \c TQSocketDevice::Datagram sockets. You must
+ specify the \a host and \a port of the destination of the data.
+*/
+TQ_LONG TQSocketDevice::writeBlock( const char * data, TQ_ULONG len,
+ const TQHostAddress & host, TQ_UINT16 port )
+{
+ if ( t != Datagram ) {
+#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::sendBlock: Not datagram" );
+#endif
+ return -1; // for now - later we can do t/tcp
+ }
+
+ if ( data == 0 && len != 0 ) {
+#if defined(TQT_CHECK_NULL) || defined(TQSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::sendBlock: Null pointer error" );
+#endif
+ return -1;
+ }
+ if ( !isValid() ) {
+#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::sendBlock: Invalid socket" );
+#endif
+ return -1;
+ }
+ if ( !isOpen() ) {
+#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::sendBlock: Device is not open" );
+#endif
+ return -1;
+ }
+ if ( !isWritable() ) {
+#if defined(TQT_CHECK_STATE) || defined(TQSOCKETDEVICE_DEBUG)
+ qWarning( "TQSocketDevice::sendBlock: Write operation not permitted" );
+#endif
+ return -1;
+ }
+ struct sockaddr_in a4;
+ struct sockaddr *aa;
+ TQT_SOCKLEN_T slen;
+#if !defined(TQT_NO_IPV6)
+ struct sockaddr_in6 a6;
+ if ( host.isIPv6Address() ) {
+ memset( &a6, 0, sizeof(a6) );
+ a6.sin6_family = AF_INET6;
+ a6.sin6_port = htons( port );
+
+ TQ_IPV6ADDR tmp = host.toIPv6Address();
+ memcpy( &a6.sin6_addr.s6_addr, &tmp, sizeof(tmp) );
+ slen = sizeof( a6 );
+ aa = (struct sockaddr *)&a6;
+ } else
+#endif
+ if ( host.isIPv4Address() ) {
+ memset( &a4, 0, sizeof(a4) );
+ a4.sin_family = AF_INET;
+ a4.sin_port = htons( port );
+ a4.sin_addr.s_addr = htonl( host.toIPv4Address() );
+ slen = sizeof(a4);
+ aa = (struct sockaddr *)&a4;
+ } else {
+ e = Impossible;
+ return -1;
+ }
+
+ // we'd use MSG_DONTWAIT + MSG_NOTQT_SIGNAL if Stevens were right.
+ // but apparently Stevens and most implementors disagree
+ bool done = FALSE;
+ int r = 0;
+ while ( !done ) {
+ r = ::sendto( fd, data, len, 0, aa, slen);
+ done = TRUE;
+ if ( r < 0 && e == NoError &&
+ errno != EAGAIN && errno != EWOULDBLOCK ) {
+ switch( errno ) {
+ case EINTR: // signal - call read() or whatever again
+ done = FALSE;
+ break;
+ case ENOSPC:
+ case EPIPE:
+ case EIO:
+ case EISDIR:
+ case EBADF:
+ case EINVAL:
+ case EFAULT:
+ case ENOTCONN:
+ case ENOTSOCK:
+ e = Impossible;
+ break;
+#if defined(ENONET)
+ case ENONET:
+#endif
+ case EHOSTUNREACH:
+ case ENETDOWN:
+ case ENETUNREACH:
+ case ETIMEDOUT:
+ e = NetworkFailure;
+ break;
+ default:
+ e = UnknownError;
+ break;
+ }
+ }
+ }
+ return r;
+}
+
+
+/*!
+ Fetches information about both ends of the connection: whatever is
+ available.
+*/
+void TQSocketDevice::fetchConnectionParameters()
+{
+ if ( !isValid() ) {
+ p = 0;
+ a = TQHostAddress();
+ pp = 0;
+ pa = TQHostAddress();
+ return;
+ }
+#if !defined(TQT_NO_IPV6)
+ struct sockaddr_storage sa;
+#else
+ struct sockaddr_in sa;
+#endif
+ memset( &sa, 0, sizeof(sa) );
+ TQT_SOCKLEN_T sz;
+ sz = sizeof( sa );
+ if ( !::getsockname( fd, (struct sockaddr *)(&sa), &sz ) )
+ qt_socket_getportaddr( (struct sockaddr *)&sa, &p, &a );
+
+ sz = sizeof( sa );
+ if ( !::getpeername( fd, (struct sockaddr *)(&sa), &sz ) )
+ qt_socket_getportaddr( (struct sockaddr *)&sa, &pp, &pa );
+}
+
+
+/*!
+ Returns the port number of the port this socket tqdevice is
+ connected to. This may be 0 for a while, but is set to something
+ sensible as soon as a sensible value is available.
+
+ Note that for Datagram sockets, this is the source port of the
+ last packet received, and that it is in native byte order.
+*/
+TQ_UINT16 TQSocketDevice::peerPort() const
+{
+ return pp;
+}
+
+
+/*!
+ Returns the address of the port this socket tqdevice is connected
+ to. This may be 0.0.0.0 for a while, but is set to something
+ sensible as soon as a sensible value is available.
+
+ Note that for Datagram sockets, this is the source port of the
+ last packet received.
+*/
+TQHostAddress TQSocketDevice::peerAddress() const
+{
+ return pa;
+}
+
+#endif //TQT_NO_NETWORK
diff --git a/tqtinterface/qt4/src/opengl/qt_opengl.pri b/tqtinterface/qt4/src/opengl/qt_opengl.pri
new file mode 100644
index 0000000..9e324db
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/qt_opengl.pri
@@ -0,0 +1,18 @@
+# Qt opengl module
+
+opengl {
+ HEADERS += $$OPENGL_H/tqgl.h \
+ $$OPENGL_H/tqglcolormap.h
+ SOURCES += $$OPENGL_CPP/tqgl.cpp \
+ $$OPENGL_CPP/tqglcolormap.cpp
+ x11 {
+ HEADERS += $$OPENGL_H/tqgl_x11_p.h
+ SOURCES += $$OPENGL_CPP/tqgl_x11.cpp
+ }
+ else:mac:SOURCES += $$OPENGL_CPP/tqgl_mac.cpp
+ else:win32:SOURCES += $$OPENGL_CPP/tqgl_win.cpp
+
+ dlopen_opengl:DEFINES+=TQT_DLOPEN_OPENGL
+}
+
+
diff --git a/tqtinterface/qt4/src/opengl/tqgl.cpp b/tqtinterface/qt4/src/opengl/tqgl.cpp
new file mode 100644
index 0000000..80e3658
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqgl.cpp
@@ -0,0 +1,2374 @@
+/****************************************************************************
+**
+** Implementation of OpenGL classes for TQt
+**
+** Created : 970112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the opengl module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqgl.h"
+#include "tqpixmap.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqimage.h"
+#include "tqcleanuphandler.h"
+#include "tqptrdict.h"
+
+static TQGLFormat* qgl_default_format = 0;
+static TQGLFormat* qgl_default_overlay_format = 0;
+
+#if defined(TQ_WS_X11)
+#include "private/tqt_x11_p.h"
+#define INT32 dummy_INT32
+#define INT8 dummy_INT8
+#include <GL/glx.h>
+#undef INT32
+#undef INT8
+#include "tqgl_x11_p.h"
+#endif
+
+static TQCleanupHandler<TQGLFormat> qgl_cleanup_format;
+
+
+/*!
+ \class TQGL tqgl.h
+ \brief The TQGL class is a namespace for miscellaneous identifiers
+ in the TQt OpenGL module.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module OpenGL
+ \ingroup graphics
+ \ingroup images
+
+
+ Normally you can ignore this class. TQGLWidget and the other
+ OpenGL<sup>*</sup> module classes inherit it, so when you make your
+ own TQGLWidget subclass you can use the identifiers in the TQGL
+ namespace without qualification.
+
+ However, you may occasionally tqfind yourself in situations where you
+ need to refer to these identifiers from outside the TQGL namespace's
+ scope, e.g. in static functions. In such cases, simply write e.g. \c
+ TQGL::DoubleBuffer instead of just \c DoubleBuffer.
+
+ <sup>*</sup> OpenGL is a trademark of Silicon Graphics, Inc. in the
+ United States and other countries.
+
+*/
+
+
+/*****************************************************************************
+ TQGLFormat implementation
+ *****************************************************************************/
+
+
+/*!
+ \class TQGLFormat tqgl.h
+ \brief The TQGLFormat class specifies the display format of an OpenGL
+ rendering context.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup graphics
+ \ingroup images
+ \module OpenGL
+
+ A display format has several characteristics:
+ \list
+ \i \link setDoubleBuffer() Double or single buffering.\endlink
+ \i \link setDepth() Depth buffer.\endlink
+ \i \link setRgba() RGBA or color index mode.\endlink
+ \i \link setAlpha() Alpha channel.\endlink
+ \i \link setAccum() Accumulation buffer.\endlink
+ \i \link setStencil() Stencil buffer.\endlink
+ \i \link setStereo() Stereo buffers.\endlink
+ \i \link setDirectRendering() Direct rendering.\endlink
+ \i \link setOverlay() Presence of an overlay.\endlink
+ \i \link setPlane() The plane of an overlay format.\endlink
+ \endlist
+
+ You create and tell a TQGLFormat object what rendering options you
+ want from an OpenGL<sup>*</sup> rendering context.
+
+ OpenGL drivers or accelerated hardware may or may not support
+ advanced features such as alpha channel or stereographic viewing.
+ If you request some features that the driver/hardware does not
+ provide when you create a TQGLWidget, you will get a rendering
+ context with the nearest subset of features.
+
+ There are different ways to define the display characteristics of
+ a rendering context. One is to create a TQGLFormat and make it the
+ default for the entire application:
+ \code
+ TQGLFormat f;
+ f.setAlpha( TRUE );
+ f.setStereo( TRUE );
+ TQGLFormat::setDefaultFormat( f );
+ \endcode
+
+ Or you can specify the desired format when creating an object of
+ your TQGLWidget subclass:
+ \code
+ TQGLFormat f;
+ f.setDoubleBuffer( FALSE ); // single buffer
+ f.setDirectRendering( FALSE ); // software rendering
+ MyGLWidget* myWidget = new MyGLWidget( f, ... );
+ \endcode
+
+ After the widget has been created, you can tqfind out which of the
+ requested features the system was able to provide:
+ \code
+ TQGLFormat f;
+ f.setOverlay( TRUE );
+ f.setStereo( TRUE );
+ MyGLWidget* myWidget = new MyGLWidget( f, ... );
+ if ( !w->format().stereo() ) {
+ // ok, goggles off
+ if ( !w->format().hasOverlay() ) {
+ qFatal( "Cool hardware required" );
+ }
+ }
+ \endcode
+
+ <sup>*</sup> OpenGL is a trademark of Silicon Graphics, Inc. in the
+ United States and other countries.
+
+ \sa TQGLContext, TQGLWidget
+*/
+
+
+/*!
+ Constructs a TQGLFormat object with the factory default settings:
+ \list
+ \i \link setDoubleBuffer() Double buffer:\endlink Enabled.
+ \i \link setDepth() Depth buffer:\endlink Enabled.
+ \i \link setRgba() RGBA:\endlink Enabled (i.e., color index disabled).
+ \i \link setAlpha() Alpha channel:\endlink Disabled.
+ \i \link setAccum() Accumulator buffer:\endlink Disabled.
+ \i \link setStencil() Stencil buffer:\endlink Disabled.
+ \i \link setStereo() Stereo:\endlink Disabled.
+ \i \link setDirectRendering() Direct rendering:\endlink Enabled.
+ \i \link setOverlay() Overlay:\endlink Disabled.
+ \i \link setPlane() Plane:\endlink 0 (i.e., normal plane).
+ \endlist
+*/
+
+TQGLFormat::TQGLFormat()
+{
+ opts = DoubleBuffer | DepthBuffer | Rgba | DirectRendering;
+ pln = 0;
+}
+
+
+/*!
+ Creates a TQGLFormat object that is a copy of the current \link
+ defaultFormat() application default format\endlink.
+
+ If \a options is not 0, this copy is modified by these format
+ options. The \a options parameter should be \c FormatOption values
+ OR'ed together.
+
+ This constructor makes it easy to specify a certain desired format
+ in classes derived from TQGLWidget, for example:
+ \code
+ // The rendering in MyGLWidget depends on using
+ // stencil buffer and alpha channel
+ MyGLWidget::MyGLWidget( TQWidget* tqparent, const char* name )
+ : TQGLWidget( TQGLFormat( StencilBuffer | AlphaChannel ), tqparent, name )
+ {
+ if ( !format().stencil() )
+ qWarning( "Could not get stencil buffer; results will be suboptimal" );
+ if ( !format().alphaChannel() )
+ qWarning( "Could not get alpha channel; results will be suboptimal" );
+ ...
+ }
+ \endcode
+
+ Note that there are \c FormatOption values to turn format settings
+ both on and off, e.g. \c DepthBuffer and \c NoDepthBuffer,
+ \c DirectRendering and \c IndirectRendering, etc.
+
+ The \a plane parameter defaults to 0 and is the plane which this
+ format should be associated with. Not all OpenGL implmentations
+ supports overlay/underlay rendering planes.
+
+ \sa defaultFormat(), setOption()
+*/
+
+TQGLFormat::TQGLFormat( int options, int plane )
+{
+ uint newOpts = options;
+ opts = defaultFormat().opts;
+ opts |= ( newOpts & 0xffff );
+ opts &= ~( newOpts >> 16 );
+ pln = plane;
+}
+
+
+/*!
+ \fn bool TQGLFormat::doubleBuffer() const
+
+ Returns TRUE if double buffering is enabled; otherwise returns
+ FALSE. Double buffering is enabled by default.
+
+ \sa setDoubleBuffer()
+*/
+
+/*!
+ If \a enable is TRUE sets double buffering; otherwise sets single
+ buffering.
+
+ Double buffering is enabled by default.
+
+ Double buffering is a technique where graphics are rendered on an
+ off-screen buffer and not directly to the screen. When the drawing
+ has been completed, the program calls a swapBuffers() function to
+ exchange the screen contents with the buffer. The result is
+ flicker-free drawing and often better performance.
+
+ \sa doubleBuffer(), TQGLContext::swapBuffers(),
+ TQGLWidget::swapBuffers()
+*/
+
+void TQGLFormat::setDoubleBuffer( bool enable )
+{
+ setOption( enable ? DoubleBuffer : SingleBuffer );
+}
+
+
+/*!
+ \fn bool TQGLFormat::depth() const
+
+ Returns TRUE if the depth buffer is enabled; otherwise returns
+ FALSE. The depth buffer is enabled by default.
+
+ \sa setDepth()
+*/
+
+/*!
+ If \a enable is TRUE enables the depth buffer; otherwise disables
+ the depth buffer.
+
+ The depth buffer is enabled by default.
+
+ The purpose of a depth buffer (or Z-buffering) is to remove hidden
+ surfaces. Pixels are assigned Z values based on the distance to
+ the viewer. A pixel with a high Z value is closer to the viewer
+ than a pixel with a low Z value. This information is used to
+ decide whether to draw a pixel or not.
+
+ \sa depth()
+*/
+
+void TQGLFormat::setDepth( bool enable )
+{
+ setOption( enable ? DepthBuffer : NoDepthBuffer );
+}
+
+
+/*!
+ \fn bool TQGLFormat::rgba() const
+
+ Returns TRUE if RGBA color mode is set. Returns FALSE if color
+ index mode is set. The default color mode is RGBA.
+
+ \sa setRgba()
+*/
+
+/*!
+ If \a enable is TRUE sets RGBA mode. If \a enable is FALSE sets
+ color index mode.
+
+ The default color mode is RGBA.
+
+ RGBA is the preferred mode for most OpenGL applications. In RGBA
+ color mode you specify colors as red + green + blue + alpha
+ quadruplets.
+
+ In color index mode you specify an index into a color lookup
+ table.
+
+ \sa rgba()
+*/
+
+void TQGLFormat::setRgba( bool enable )
+{
+ setOption( enable ? Rgba : ColorIndex );
+}
+
+
+/*!
+ \fn bool TQGLFormat::alpha() const
+
+ Returns TRUE if the alpha channel of the framebuffer is enabled;
+ otherwise returns FALSE. The alpha channel is disabled by default.
+
+ \sa setAlpha()
+*/
+
+/*!
+ If \a enable is TRUE enables the alpha channel; otherwise disables
+ the alpha channel.
+
+ The alpha buffer is disabled by default.
+
+ The alpha channel is typically used for implementing transparency
+ or translucency. The A in RGBA specifies the transparency of a
+ pixel.
+
+ \sa alpha()
+*/
+
+void TQGLFormat::setAlpha( bool enable )
+{
+ setOption( enable ? AlphaChannel : NoAlphaChannel );
+}
+
+
+/*!
+ \fn bool TQGLFormat::accum() const
+
+ Returns TRUE if the accumulation buffer is enabled; otherwise
+ returns FALSE. The accumulation buffer is disabled by default.
+
+ \sa setAccum()
+*/
+
+/*!
+ If \a enable is TRUE enables the accumulation buffer; otherwise
+ disables the accumulation buffer.
+
+ The accumulation buffer is disabled by default.
+
+ The accumulation buffer is used to create blur effects and
+ multiple exposures.
+
+ \sa accum()
+*/
+
+void TQGLFormat::setAccum( bool enable )
+{
+ setOption( enable ? AccumBuffer : NoAccumBuffer );
+}
+
+
+/*!
+ \fn bool TQGLFormat::stencil() const
+
+ Returns TRUE if the stencil buffer is enabled; otherwise returns
+ FALSE. The stencil buffer is disabled by default.
+
+ \sa setStencil()
+*/
+
+/*!
+ If \a enable is TRUE enables the stencil buffer; otherwise
+ disables the stencil buffer.
+
+ The stencil buffer is disabled by default.
+
+ The stencil buffer masks certain parts of the drawing area so that
+ masked parts are not drawn on.
+
+ \sa stencil()
+*/
+
+void TQGLFormat::setStencil( bool enable )
+{
+ setOption( enable ? StencilBuffer: NoStencilBuffer );
+}
+
+
+/*!
+ \fn bool TQGLFormat::stereo() const
+
+ Returns TRUE if stereo buffering is enabled; otherwise returns
+ FALSE. Stereo buffering is disabled by default.
+
+ \sa setStereo()
+*/
+
+/*!
+ If \a enable is TRUE enables stereo buffering; otherwise disables
+ stereo buffering.
+
+ Stereo buffering is disabled by default.
+
+ Stereo buffering provides extra color buffers to generate left-eye
+ and right-eye images.
+
+ \sa stereo()
+*/
+
+void TQGLFormat::setStereo( bool enable )
+{
+ setOption( enable ? StereoBuffers : NoStereoBuffers );
+}
+
+
+/*!
+ \fn bool TQGLFormat::directRendering() const
+
+ Returns TRUE if direct rendering is enabled; otherwise returns
+ FALSE.
+
+ Direct rendering is enabled by default.
+
+ \sa setDirectRendering()
+*/
+
+/*!
+ If \a enable is TRUE enables direct rendering; otherwise disables
+ direct rendering.
+
+ Direct rendering is enabled by default.
+
+ Enabling this option will make OpenGL bypass the underlying window
+ system and render directly from hardware to the screen, if this is
+ supported by the system.
+
+ \sa directRendering()
+*/
+
+void TQGLFormat::setDirectRendering( bool enable )
+{
+ setOption( enable ? DirectRendering : IndirectRendering );
+}
+
+
+/*!
+ \fn bool TQGLFormat::hasOverlay() const
+
+ Returns TRUE if overlay plane is enabled; otherwise returns FALSE.
+
+ Overlay is disabled by default.
+
+ \sa setOverlay()
+*/
+
+/*!
+ If \a enable is TRUE enables an overlay plane; otherwise disables
+ the overlay plane.
+
+ Enabling the overlay plane will cause TQGLWidget to create an
+ additional context in an overlay plane. See the TQGLWidget
+ documentation for further information.
+
+ \sa hasOverlay()
+*/
+
+void TQGLFormat::setOverlay( bool enable )
+{
+ setOption( enable ? HasOverlay : NoOverlay );
+}
+
+/*!
+ Returns the plane of this format. The default for normal formats
+ is 0, which means the normal plane. The default for overlay
+ formats is 1, which is the first overlay plane.
+
+ \sa setPlane()
+*/
+int TQGLFormat::plane() const
+{
+ return pln;
+}
+
+/*!
+ Sets the requested plane to \a plane. 0 is the normal plane, 1 is
+ the first overlay plane, 2 is the second overlay plane, etc.; -1,
+ -2, etc. are underlay planes.
+
+ Note that in contrast to other format specifications, the plane
+ specifications will be matched exactly. This means that if you
+ specify a plane that the underlying OpenGL system cannot provide,
+ an \link TQGLWidget::isValid() invalid\endlink TQGLWidget will be
+ created.
+
+ \sa plane()
+*/
+void TQGLFormat::setPlane( int plane )
+{
+ pln = plane;
+}
+
+/*!
+ Sets the format option to \a opt.
+
+ \sa testOption()
+*/
+
+void TQGLFormat::setOption( FormatOption opt )
+{
+ if ( opt & 0xffff )
+ opts |= opt;
+ else
+ opts &= ~( opt >> 16 );
+}
+
+
+
+/*!
+ Returns TRUE if format option \a opt is set; otherwise returns FALSE.
+
+ \sa setOption()
+*/
+
+bool TQGLFormat::testOption( FormatOption opt ) const
+{
+ if ( opt & 0xffff )
+ return ( opts & opt ) != 0;
+ else
+ return ( opts & ( opt >> 16 ) ) == 0;
+}
+
+
+
+/*!
+ \fn bool TQGLFormat::hasOpenGL()
+
+ Returns TRUE if the window system has any OpenGL support;
+ otherwise returns FALSE.
+
+ \warning This function must not be called until the TQApplication
+ object has been created.
+*/
+
+
+
+/*!
+ \fn bool TQGLFormat::hasOpenGLOverlays()
+
+ Returns TRUE if the window system supports OpenGL overlays;
+ otherwise returns FALSE.
+
+ \warning This function must not be called until the TQApplication
+ object has been created.
+*/
+
+/*!
+ Returns the default TQGLFormat for the application. All TQGLWidgets
+ that are created use this format unless another format is
+ specified, e.g. when they are constructed.
+
+ If no special default format has been set using
+ setDefaultFormat(), the default format is the same as that created
+ with TQGLFormat().
+
+ \sa setDefaultFormat()
+*/
+
+TQGLFormat TQGLFormat::defaultFormat()
+{
+ if ( !qgl_default_format ) {
+ qgl_default_format = new TQGLFormat;
+ qgl_cleanup_format.add( &qgl_default_format );
+ }
+ return *qgl_default_format;
+}
+
+/*!
+ Sets a new default TQGLFormat for the application to \a f. For
+ example, to set single buffering as the default instead of double
+ buffering, your main() might contain code like this:
+ \code
+ TQApplication a(argc, argv);
+ TQGLFormat f;
+ f.setDoubleBuffer( FALSE );
+ TQGLFormat::setDefaultFormat( f );
+ \endcode
+
+ \sa defaultFormat()
+*/
+
+void TQGLFormat::setDefaultFormat( const TQGLFormat &f )
+{
+ if ( !qgl_default_format ) {
+ qgl_default_format = new TQGLFormat;
+ qgl_cleanup_format.add( &qgl_default_format );
+ }
+ *qgl_default_format = f;
+}
+
+
+/*!
+ Returns the default TQGLFormat for overlay contexts.
+
+ The factory default overlay format is:
+ \list
+ \i \link setDoubleBuffer() Double buffer:\endlink Disabled.
+ \i \link setDepth() Depth buffer:\endlink Disabled.
+ \i \link setRgba() RGBA:\endlink Disabled (i.e., color index enabled).
+ \i \link setAlpha() Alpha channel:\endlink Disabled.
+ \i \link setAccum() Accumulator buffer:\endlink Disabled.
+ \i \link setStencil() Stencil buffer:\endlink Disabled.
+ \i \link setStereo() Stereo:\endlink Disabled.
+ \i \link setDirectRendering() Direct rendering:\endlink Enabled.
+ \i \link setOverlay() Overlay:\endlink Disabled.
+ \i \link setPlane() Plane:\endlink 1 (i.e., first overlay plane).
+ \endlist
+
+ \sa setDefaultFormat()
+*/
+
+TQGLFormat TQGLFormat::defaultOverlayFormat()
+{
+ if ( !qgl_default_overlay_format ) {
+ qgl_default_overlay_format = new TQGLFormat;
+ qgl_default_overlay_format->opts = DirectRendering;
+ qgl_default_overlay_format->pln = 1;
+ qgl_cleanup_format.add( &qgl_default_overlay_format );
+ }
+ return *qgl_default_overlay_format;
+}
+
+/*!
+ Sets a new default TQGLFormat for overlay contexts to \a f. This
+ format is used whenever a TQGLWidget is created with a format that
+ hasOverlay() enabled.
+
+ For example, to get a double buffered overlay context (if
+ available), use code like this:
+
+ \code
+ TQGLFormat f = TQGLFormat::defaultOverlayFormat();
+ f.setDoubleBuffer( TRUE );
+ TQGLFormat::setDefaultOverlayFormat( f );
+ \endcode
+
+ As usual, you can tqfind out after widget creation whether the
+ underlying OpenGL system was able to provide the requested
+ specification:
+
+ \code
+ // ...continued from above
+ MyGLWidget* myWidget = new MyGLWidget( TQGLFormat( TQGL::HasOverlay ), ... );
+ if ( myWidget->format().hasOverlay() ) {
+ // Yes, we got an overlay, let's check _its_ format:
+ TQGLContext* olContext = myWidget->overlayContext();
+ if ( olContext->format().doubleBuffer() )
+ ; // yes, we got a double buffered overlay
+ else
+ ; // no, only single buffered overlays are available
+ }
+ \endcode
+
+ \sa defaultOverlayFormat()
+*/
+
+void TQGLFormat::setDefaultOverlayFormat( const TQGLFormat &f )
+{
+ if ( !qgl_default_overlay_format ) {
+ qgl_default_overlay_format = new TQGLFormat;
+ qgl_cleanup_format.add( &qgl_default_overlay_format );
+ }
+ *qgl_default_overlay_format = f;
+ // Make sure the user doesn't request that the overlays themselves
+ // have overlays, since it is unlikely that the system supports
+ // infinitely many planes...
+ qgl_default_overlay_format->setOverlay( FALSE );
+}
+
+
+/*!
+ Returns TRUE if all the options of the two TQGLFormats are equal;
+ otherwise returns FALSE.
+*/
+
+bool operator==( const TQGLFormat& a, const TQGLFormat& b )
+{
+ return (a.opts == b.opts) && (a.pln == b.pln);
+}
+
+
+/*!
+ Returns FALSE if all the options of the two TQGLFormats are equal;
+ otherwise returns TRUE.
+*/
+
+bool operator!=( const TQGLFormat& a, const TQGLFormat& b )
+{
+ return !( a == b );
+}
+
+
+
+/*****************************************************************************
+ TQGLContext implementation
+ *****************************************************************************/
+
+TQGLContext* TQGLContext::currentCtx = 0;
+
+/*!
+ \class TQGLContext tqgl.h
+ \brief The TQGLContext class encapsulates an OpenGL rendering context.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup graphics
+ \ingroup images
+ \module OpenGL
+
+ An OpenGL<sup>*</sup> rendering context is a complete set of
+ OpenGL state variables.
+
+ The context's \link TQGL::FormatOption format\endlink is set in the
+ constructor or later with setFormat(). The format options that are
+ actually set are returned by format(); the options you asked for
+ are returned by requestedFormat(). Note that after a TQGLContext
+ object has been constructed, the actual OpenGL context must be
+ created by explicitly calling the \link create() create()\endlink
+ function. The makeCurrent() function makes this context the
+ current rendering context. You can make \e no context current
+ using doneCurrent(). The reset() function will reset the context
+ and make it invalid.
+
+ You can examine properties of the context with, e.g. isValid(),
+ isSharing(), initialized(), windowCreated() and
+ overlayTransparentColor().
+
+ If you're using double buffering you can swap the screen contents
+ with the off-screen buffer using swapBuffers().
+
+ Please note that TQGLContext is not thread safe.
+
+ <sup>*</sup> OpenGL is a trademark of Silicon Graphics, Inc. in the
+ United States and other countries.
+
+*/
+
+
+/*!
+ Constructs an OpenGL context for the paint tqdevice \a tqdevice, which
+ can be a widget or a pixmap. The \a format specifies several
+ display options for the context.
+
+ If the underlying OpenGL/Window system cannot satisfy all the
+ features requested in \a format, the nearest subset of features
+ will be used. After creation, the format() method will return the
+ actual format obtained.
+
+ Note that after a TQGLContext object has been constructed, \link
+ create() create()\endlink must be called explicitly to create
+ the actual OpenGL context. The context will be \link isValid()
+ invalid\endlink if it was not possible to obtain a GL context at
+ all.
+
+ \sa format(), isValid()
+*/
+
+TQGLContext::TQGLContext( const TQGLFormat &format, TQPaintDevice *tqdevice )
+ : glFormat(format), reqFormat(format)
+{
+ init( tqdevice );
+}
+
+/*!
+ \overload
+ \internal
+*/
+TQGLContext::TQGLContext( const TQGLFormat &format )
+ : glFormat( format ), reqFormat(format)
+{
+ init();
+}
+
+/*!
+ Destroys the OpenGL context and frees its resources.
+*/
+
+TQGLContext::~TQGLContext()
+{
+ reset();
+ if ( d )
+ delete d;
+}
+
+
+/*!
+ \fn TQGLFormat TQGLContext::format() const
+
+ Returns the frame buffer format that was obtained (this may be a
+ subset of what was requested).
+
+ \sa requestedFormat()
+*/
+
+/*!
+ \fn TQGLFormat TQGLContext::requestedFormat() const
+
+ Returns the frame buffer format that was originally requested in
+ the constructor or setFormat().
+
+ \sa format()
+*/
+
+/*!
+ Sets a \a format for this context. The context is \link reset()
+ reset\endlink.
+
+ Call create() to create a new GL context that tries to match the
+ new format.
+
+ \code
+ TQGLContext *cx;
+ // ...
+ TQGLFormat f;
+ f.setStereo( TRUE );
+ cx->setFormat( f );
+ if ( !cx->create() )
+ exit(); // no OpenGL support, or cannot render on the specified painttqdevice
+ if ( !cx->format().stereo() )
+ exit(); // could not create stereo context
+ \endcode
+
+ \sa format(), reset(), create()
+*/
+
+void TQGLContext::setFormat( const TQGLFormat &format )
+{
+ reset();
+ glFormat = reqFormat = format;
+}
+
+/*!
+ \internal
+*/
+void TQGLContext::setDevice( TQPaintDevice *pDev )
+{
+ if ( isValid() )
+ reset();
+ d->paintDevice = pDev;
+ if ( d->paintDevice && (d->paintDevice->devType() != TQInternal::Widget
+ && d->paintDevice->devType() != TQInternal::Pixmap) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQGLContext: Unsupported paint tqdevice type" );
+#endif
+ }
+}
+
+void TQGLContext::init( TQPaintDevice *dev )
+{
+ d = new Private;
+ d->valid = FALSE;
+#if defined(TQ_WS_X11)
+ qt_resolve_gl_symbols();
+ gpm = 0;
+#endif
+ setDevice( dev );
+#if defined(TQ_WS_WIN)
+ dc = 0;
+ win = 0;
+ pixelFormatId = 0;
+ cmap = 0;
+#endif
+#if defined(TQ_WS_MAC)
+ d->oldR = TQRect(1, 1, 1, 1);
+#endif
+ d->crWin = FALSE;
+ d->initDone = FALSE;
+ d->sharing = FALSE;
+}
+
+/*!
+ \fn bool TQGLContext::isValid() const
+
+ Returns TRUE if a GL rendering context has been successfully
+ created; otherwise returns FALSE.
+*/
+
+/*!
+ \fn void TQGLContext::setValid( bool valid )
+ \internal
+
+ Forces the GL rendering context to be valid.
+*/
+
+/*!
+ \fn bool TQGLContext::isSharing() const
+
+ Returns TRUE if display list sharing with another context was
+ requested in the create() call and the GL system was able to
+ fulfill this request; otherwise returns FALSE. Note that display
+ list sharing might not be supported between contexts with
+ different formats.
+*/
+
+/*!
+ \fn bool TQGLContext::tqdeviceIsPixmap() const
+
+ Returns TRUE if the paint tqdevice of this context is a pixmap;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQGLContext::windowCreated() const
+
+ Returns TRUE if a window has been created for this context;
+ otherwise returns FALSE.
+
+ \sa setWindowCreated()
+*/
+
+/*!
+ \fn void TQGLContext::setWindowCreated( bool on )
+
+ If \a on is TRUE the context has had a window created for it. If
+ \a on is FALSE no window has been created for the context.
+
+ \sa windowCreated()
+*/
+
+/*!
+ \fn uint TQGLContext::colorIndex( const TQColor& c ) const
+
+ \internal
+
+ Returns a colormap index for the color c, in ColorIndex mode. Used
+ by qglColor() and qglClearColor().
+*/
+
+
+/*!
+ \fn bool TQGLContext::initialized() const
+
+ Returns TRUE if this context has been initialized, i.e. if
+ TQGLWidget::initializeGL() has been performed on it; otherwise
+ returns FALSE.
+
+ \sa setInitialized()
+*/
+
+/*!
+ \fn void TQGLContext::setInitialized( bool on )
+
+ If \a on is TRUE the context has been initialized, i.e.
+ TQGLContext::setInitialized() has been called on it. If \a on is
+ FALSE the context has not been initialized.
+
+ \sa initialized()
+*/
+
+/*!
+ \fn const TQGLContext* TQGLContext::currentContext()
+
+ Returns the current context, i.e. the context to which any OpenGL
+ commands will currently be directed. Returns 0 if no context is
+ current.
+
+ \sa makeCurrent()
+*/
+
+/*!
+ \fn TQColor TQGLContext::overlayTransparentColor() const
+
+ If this context is a valid context in an overlay plane, returns
+ the plane's transtqparent color. Otherwise returns an \link
+ TQColor::isValid() invalid \endlink color.
+
+ The returned color's \link TQColor::pixel() pixel \endlink value is
+ the index of the transtqparent color in the colormap of the overlay
+ plane. (Naturally, the color's RGB values are meaningless.)
+
+ The returned TQColor object will generally work as expected only
+ when passed as the argument to TQGLWidget::qglColor() or
+ TQGLWidget::qglClearColor(). Under certain circumstances it can
+ also be used to draw transtqparent graphics with a TQPainter. See the
+ examples/opengl/overlay_x11 example for details.
+*/
+
+
+/*!
+ Creates the GL context. Returns TRUE if it was successful in
+ creating a valid GL rendering context on the paint tqdevice
+ specified in the constructor; otherwise returns FALSE (i.e. the
+ context is invalid).
+
+ After successful creation, format() returns the set of features of
+ the created GL rendering context.
+
+ If \a shareContext points to a valid TQGLContext, this method will
+ try to establish OpenGL display list sharing between this context
+ and the \a shareContext. Note that this may fail if the two
+ contexts have different formats. Use isSharing() to see if sharing
+ succeeded.
+
+ \warning Implementation note: initialization of C++ class
+ members usually takes place in the class constructor. TQGLContext
+ is an exception because it must be simple to customize. The
+ virtual functions chooseContext() (and chooseVisual() for X11) can
+ be reimplemented in a subclass to select a particular context. The
+ problem is that virtual functions are not properly called during
+ construction (even though this is correct C++) because C++
+ constructs class hierarchies from the bottom up. For this reason
+ we need a create() function.
+
+ \sa chooseContext(), format(), isValid()
+*/
+
+bool TQGLContext::create( const TQGLContext* shareContext )
+{
+ reset();
+ d->valid = chooseContext( shareContext );
+ return d->valid;
+}
+
+
+
+/*!
+ \fn bool TQGLContext::chooseContext( const TQGLContext* shareContext = 0 )
+
+ This semi-internal function is called by create(). It creates a
+ system-dependent OpenGL handle that matches the format() of \a
+ shareContext as closely as possible.
+
+ On Windows, it calls the virtual function choosePixelFormat(),
+ which tqfinds a matching pixel format identifier. On X11, it calls
+ the virtual function chooseVisual() which tqfinds an appropriate X
+ visual. On other platforms it may work differently.
+*/
+
+
+/*!
+ \fn void TQGLContext::reset()
+
+ Resets the context and makes it invalid.
+
+ \sa create(), isValid()
+*/
+
+
+/*!
+ \fn void TQGLContext::makeCurrent()
+
+ Makes this context the current OpenGL rendering context. All GL
+ functions you call operate on this context until another context
+ is made current.
+
+ In some very rare cases the underlying call may fail. If this
+ occurs an error message is output to stderr.
+*/
+
+
+/*!
+ \fn void TQGLContext::swapBuffers() const
+
+ Swaps the screen contents with an off-screen buffer. Only works if
+ the context is in double buffer mode.
+
+ \sa TQGLFormat::setDoubleBuffer()
+*/
+
+
+/*!
+ \fn void TQGLContext::doneCurrent()
+
+ Makes no GL context the current context. Normally, you do not need
+ to call this function; TQGLContext calls it as necessary.
+*/
+
+
+/*!
+ \fn TQPaintDevice* TQGLContext::tqdevice() const
+
+ Returns the paint tqdevice set for this context.
+
+ \sa TQGLContext::TQGLContext()
+*/
+
+/*!
+ \fn void TQGLContext::generateFontDisplayLists( const TQFont& font, int listBase )
+
+ Generates a set of 256 display lists for the 256 first characters
+ in the font \a font. The first list will start at index \a listBase.
+
+ \sa TQGLWidget::renderText()
+*/
+
+
+/*****************************************************************************
+ TQGLWidget implementation
+ *****************************************************************************/
+
+
+/*!
+ \class TQGLWidget tqgl.h
+ \brief The TQGLWidget class is a widget for rendering OpenGL graphics.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup graphics
+ \ingroup images
+ \mainclass
+ \module OpenGL
+
+ TQGLWidget provides functionality for displaying OpenGL<sup>*</sup>
+ graphics integrated into a TQt application. It is very simple to
+ use. You inherit from it and use the subclass like any other
+ TQWidget, except that instead of drawing the widget's contents
+ using TQPainter etc. you use the standard OpenGL rendering
+ commands.
+
+ TQGLWidget provides three convenient virtual functions that you can
+ reimplement in your subclass to perform the typical OpenGL tasks:
+
+ \list
+ \i paintGL() - Renders the OpenGL scene. Gets called whenever the widget
+ needs to be updated.
+ \i resizeGL() - Sets up the OpenGL viewport, projection, etc. Gets
+ called whenever the the widget has been resized (and also when it
+ is shown for the first time because all newly created widgets get a
+ resize event automatically).
+ \i initializeGL() - Sets up the OpenGL rendering context, defines display
+ lists, etc. Gets called once before the first time resizeGL() or
+ paintGL() is called.
+ \endlist
+
+ Here is a rough outline of how a TQGLWidget subclass might look:
+
+ \code
+ class MyGLDrawer : public TQGLWidget
+ {
+ TQ_OBJECT // must include this if you use TQt Q_SIGNALS/Q_SLOTS
+
+ public:
+ MyGLDrawer( TQWidget *tqparent, const char *name )
+ : TQGLWidget(tqparent, name) {}
+
+ protected:
+
+ void initializeGL()
+ {
+ // Set up the rendering context, define display lists etc.:
+ ...
+ glClearColor( 0.0, 0.0, 0.0, 0.0 );
+ glEnable(GL_DEPTH_TEST);
+ ...
+ }
+
+ void resizeGL( int w, int h )
+ {
+ // setup viewport, projection etc.:
+ glViewport( 0, 0, (GLint)w, (GLint)h );
+ ...
+ glFrustum( ... );
+ ...
+ }
+
+ void paintGL()
+ {
+ // draw the scene:
+ ...
+ glRotatef( ... );
+ glMaterialfv( ... );
+ glBegin( GL_TQUADS );
+ glVertex3f( ... );
+ glVertex3f( ... );
+ ...
+ glEnd();
+ ...
+ }
+
+ };
+ \endcode
+
+ If you need to trigger a tqrepaint from places other than paintGL()
+ (a typical example is when using \link TQTimer timers\endlink to
+ animate scenes), you should call the widget's updateGL() function.
+
+ Your widget's OpenGL rendering context is made current when
+ paintGL(), resizeGL(), or initializeGL() is called. If you need to
+ call the standard OpenGL API functions from other places (e.g. in
+ your widget's constructor or in your own paint functions), you
+ must call makeCurrent() first.
+
+ TQGLWidget provides functions for requesting a new display \link
+ TQGLFormat format\endlink and you can also create widgets with
+ customized rendering \link TQGLContext contexts\endlink.
+
+ You can also share OpenGL display lists between TQGLWidgets (see
+ the documentation of the TQGLWidget constructors for details).
+
+ \section1 Overlays
+
+ The TQGLWidget creates a GL overlay context in addition to the
+ normal context if overlays are supported by the underlying system.
+
+ If you want to use overlays, you specify it in the \link TQGLFormat
+ format\endlink. (Note: Overlay must be requested in the format
+ passed to the TQGLWidget constructor.) Your GL widget should also
+ implement some or all of these virtual methods:
+
+ \list
+ \i paintOverlayGL()
+ \i resizeOverlayGL()
+ \i initializeOverlayGL()
+ \endlist
+
+ These methods work in the same way as the normal paintGL() etc.
+ functions, except that they will be called when the overlay
+ context is made current. You can explicitly make the overlay
+ context current by using makeOverlayCurrent(), and you can access
+ the overlay context directly (e.g. to ask for its transtqparent
+ color) by calling overlayContext().
+
+ On X servers in which the default visual is in an overlay plane,
+ non-GL TQt windows can also be used for overlays. See the
+ examples/opengl/overlay_x11 example program for details.
+
+ <sup>*</sup> OpenGL is a trademark of Silicon Graphics, Inc. in the
+ United States and other countries.
+*/
+
+// ### BCI - fix in 4.0
+
+// the display list cache can't be global because display lists are
+// tied to the GL contexts for each individual widget
+
+class TQGLWidgetPrivate
+{
+public:
+ TQMap<TQString, int> displayListCache;
+};
+
+static TQPtrDict<TQGLWidgetPrivate> * qgl_d_ptr = 0;
+static TQSingleCleanupHandler< TQPtrDict<TQGLWidgetPrivate> > qgl_cleanup_d_ptr;
+
+static TQGLWidgetPrivate * qgl_d( const TQGLWidget * w )
+{
+ if ( !qgl_d_ptr ) {
+ qgl_d_ptr = new TQPtrDict<TQGLWidgetPrivate>;
+ qgl_cleanup_d_ptr.set( &qgl_d_ptr );
+ qgl_d_ptr->setAutoDelete( TRUE );
+ }
+ TQGLWidgetPrivate * ret = qgl_d_ptr->tqfind( (void *) w );
+ if ( !ret ) {
+ ret = new TQGLWidgetPrivate;
+ qgl_d_ptr->tqreplace( (void *) w, ret );
+ }
+ return ret;
+}
+
+void qgl_delete_d( const TQGLWidget * w )
+{
+ if ( qgl_d_ptr )
+ qgl_d_ptr->remove( (void *) w );
+}
+
+/*!
+ Constructs an OpenGL widget with a \a tqparent widget and a \a name.
+
+ The \link TQGLFormat::defaultFormat() default format\endlink is
+ used. The widget will be \link isValid() invalid\endlink if the
+ system has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink.
+
+ The \a tqparent, \a name and widget flag, \a f, arguments are passed
+ to the TQWidget constructor.
+
+ If the \a shareWidget parameter points to a valid TQGLWidget, this
+ widget will share OpenGL display lists with \a shareWidget. If
+ this widget and \a shareWidget have different \link format()
+ formats\endlink, display list sharing may fail. You can check
+ whether display list sharing succeeded by calling isSharing().
+
+ The initialization of OpenGL rendering state, etc. should be done
+ by overriding the initializeGL() function, rather than in the
+ constructor of your TQGLWidget subclass.
+
+ \sa TQGLFormat::defaultFormat()
+*/
+
+TQGLWidget::TQGLWidget( TQWidget *tqparent, const char *name,
+ const TQGLWidget* shareWidget, WFlags f )
+ : TQWidget( tqparent, name, (WFlags)(f | TQt::WWinOwnDC | WNoAutoErase) )
+{
+ init( new TQGLContext(TQGLFormat::defaultFormat(), TQT_TQPAINTDEVICE(this)), shareWidget );
+}
+
+
+/*!
+ Constructs an OpenGL widget with tqparent \a tqparent, called \a name.
+
+ The \a format argument specifies the desired \link TQGLFormat
+ rendering options \endlink. If the underlying OpenGL/Window system
+ cannot satisfy all the features requested in \a format, the
+ nearest subset of features will be used. After creation, the
+ format() method will return the actual format obtained.
+
+ The widget will be \link isValid() invalid\endlink if the system
+ has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink.
+
+ The \a tqparent, \a name and widget flag, \a f, arguments are passed
+ to the TQWidget constructor.
+
+ If the \a shareWidget parameter points to a valid TQGLWidget, this
+ widget will share OpenGL display lists with \a shareWidget. If
+ this widget and \a shareWidget have different \link format()
+ formats\endlink, display list sharing may fail. You can check
+ whether display list sharing succeeded by calling isSharing().
+
+ The initialization of OpenGL rendering state, etc. should be done
+ by overriding the initializeGL() function, rather than in the
+ constructor of your TQGLWidget subclass.
+
+ \sa TQGLFormat::defaultFormat(), isValid()
+*/
+
+TQGLWidget::TQGLWidget( const TQGLFormat &format, TQWidget *tqparent,
+ const char *name, const TQGLWidget* shareWidget,
+ WFlags f )
+ : TQWidget( tqparent, name, f | (WFlags)(TQt::WWinOwnDC | WNoAutoErase) )
+{
+ init( new TQGLContext(format, TQT_TQPAINTDEVICE(this)), shareWidget );
+}
+
+/*!
+ Constructs an OpenGL widget with tqparent \a tqparent, called \a name.
+
+ The \a context argument is a pointer to the TQGLContext that
+ you wish to be bound to this widget. This allows you to pass in
+ your own TQGLContext sub-classes.
+
+ The widget will be \link isValid() invalid\endlink if the system
+ has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink.
+
+ The \a tqparent, \a name and widget flag, \a f, arguments are passed
+ to the TQWidget constructor.
+
+ If the \a shareWidget parameter points to a valid TQGLWidget, this
+ widget will share OpenGL display lists with \a shareWidget. If
+ this widget and \a shareWidget have different \link format()
+ formats\endlink, display list sharing may fail. You can check
+ whether display list sharing succeeded by calling isSharing().
+
+ The initialization of OpenGL rendering state, etc. should be done
+ by overriding the initializeGL() function, rather than in the
+ constructor of your TQGLWidget subclass.
+
+ \sa TQGLFormat::defaultFormat(), isValid()
+*/
+TQGLWidget::TQGLWidget( TQGLContext *context, TQWidget *tqparent,
+ const char *name, const TQGLWidget *shareWidget, WFlags f )
+ : TQWidget( tqparent, name, (WFlags)(f | TQt::WWinOwnDC | WNoAutoErase) )
+{
+ init( context, shareWidget );
+}
+
+/*!
+ Destroys the widget.
+*/
+
+TQGLWidget::~TQGLWidget()
+{
+#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT)
+ bool doRelease = ( glcx && glcx->windowCreated() );
+#endif
+ qgl_delete_d( this );
+ delete glcx;
+#if defined(TQ_WGL)
+ delete olcx;
+#endif
+#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT)
+ if ( doRelease )
+ glXReleaseBuffersMESA( x11Display(), winId() );
+#endif
+#if defined(TQ_WS_MAC)
+ if(gl_pix) {
+ delete gl_pix;
+ gl_pix = NULL;
+ }
+#endif
+ cleanupColormaps();
+}
+
+
+
+
+
+/*!
+ \fn TQGLFormat TQGLWidget::format() const
+
+ Returns the format of the contained GL rendering context.
+*/
+
+/*!
+ \fn bool TQGLWidget::doubleBuffer() const
+
+ Returns TRUE if the contained GL rendering context has double
+ buffering; otherwise returns FALSE.
+
+ \sa TQGLFormat::doubleBuffer()
+*/
+
+/*!
+ \fn void TQGLWidget::setAutoBufferSwap( bool on )
+
+ If \a on is TRUE automatic GL buffer swapping is switched on;
+ otherwise it is switched off.
+
+ If \a on is TRUE and the widget is using a double-buffered format,
+ the background and foreground GL buffers will automatically be
+ swapped after each paintGL() call.
+
+ The buffer auto-swapping is on by default.
+
+ \sa autoBufferSwap(), doubleBuffer(), swapBuffers()
+*/
+
+/*!
+ \fn bool TQGLWidget::autoBufferSwap() const
+
+ Returns TRUE if the widget is doing automatic GL buffer swapping;
+ otherwise returns FALSE.
+
+ \sa setAutoBufferSwap()
+*/
+
+/*!
+ \fn bool TQGLWidget::isValid() const
+
+ Returns TRUE if the widget has a valid GL rendering context;
+ otherwise returns FALSE. A widget will be invalid if the system
+ has no \link TQGLFormat::hasOpenGL() OpenGL support\endlink.
+*/
+
+bool TQGLWidget::isValid() const
+{
+ return glcx->isValid();
+}
+
+/*!
+ \fn bool TQGLWidget::isSharing() const
+
+ Returns TRUE if display list sharing with another TQGLWidget was
+ requested in the constructor, and the GL system was able to
+ provide it; otherwise returns FALSE. The GL system may fail to
+ provide display list sharing if the two TQGLWidgets use different
+ formats.
+
+ \sa format()
+*/
+
+bool TQGLWidget::isSharing() const
+{
+ return glcx->isSharing();
+}
+
+/*!
+ \fn void TQGLWidget::makeCurrent()
+
+ Makes this widget the current widget for OpenGL operations, i.e.
+ makes the widget's rendering context the current OpenGL rendering
+ context.
+*/
+
+void TQGLWidget::makeCurrent()
+{
+#if defined( TQ_WS_MAC )
+ macInternalDoubleBuffer(); //make sure the correct context is used
+#endif
+ glcx->makeCurrent();
+}
+
+/*!
+ \fn void TQGLWidget::doneCurrent()
+
+ Makes no GL context the current context. Normally, you do not need
+ to call this function; TQGLContext calls it as necessary. However,
+ it may be useful in multithreaded environments.
+*/
+
+void TQGLWidget::doneCurrent()
+{
+ glcx->doneCurrent();
+}
+
+/*!
+ \fn void TQGLWidget::swapBuffers()
+
+ Swaps the screen contents with an off-screen buffer. This only
+ works if the widget's format specifies double buffer mode.
+
+ Normally, there is no need to explicitly call this function
+ because it is done automatically after each widget tqrepaint, i.e.
+ each time after paintGL() has been executed.
+
+ \sa doubleBuffer(), setAutoBufferSwap(), TQGLFormat::setDoubleBuffer()
+*/
+
+void TQGLWidget::swapBuffers()
+{
+ glcx->swapBuffers();
+#if defined(TQ_WS_MAC)
+ if(macInternalDoubleBuffer() && gl_pix)
+ bitBlt(this, 0, 0, gl_pix);
+#endif
+}
+
+
+/*!
+ \fn const TQGLContext* TQGLWidget::overlayContext() const
+
+ Returns the overlay context of this widget, or 0 if this widget
+ has no overlay.
+
+ \sa context()
+*/
+
+
+
+/*!
+ \fn void TQGLWidget::makeOverlayCurrent()
+
+ Makes the overlay context of this widget current. Use this if you
+ need to issue OpenGL commands to the overlay context outside of
+ initializeOverlayGL(), resizeOverlayGL(), and paintOverlayGL().
+
+ Does nothing if this widget has no overlay.
+
+ \sa makeCurrent()
+*/
+
+
+/*
+ \obsolete
+
+ Sets a new format for this widget.
+
+ If the underlying OpenGL/Window system cannot satisfy all the
+ features requested in \a format, the nearest subset of features will
+ be used. After creation, the format() method will return the actual
+ rendering context format obtained.
+
+ The widget will be assigned a new TQGLContext, and the initializeGL()
+ function will be executed for this new context before the first
+ resizeGL() or paintGL().
+
+ This method will try to keep any existing display list sharing with
+ other TQGLWidgets, but it may fail. Use isSharing() to test.
+
+ \sa format(), isSharing(), isValid()
+*/
+
+void TQGLWidget::setFormat( const TQGLFormat &format )
+{
+ setContext( new TQGLContext(format,TQT_TQPAINTDEVICE(this)) );
+}
+
+
+
+
+/*!
+ \fn const TQGLContext *TQGLWidget::context() const
+
+ Returns the context of this widget.
+
+ It is possible that the context is not valid (see isValid()), for
+ example, if the underlying hardware does not support the format
+ attributes that were requested.
+*/
+
+/*
+ \obsolete
+
+ \fn void TQGLWidget::setContext( TQGLContext *context,
+ const TQGLContext* shareContext,
+ bool deleteOldContext )
+
+ Sets a new context for this widget. The TQGLContext \a context must
+ be created using \e new. TQGLWidget will delete \a context when
+ another context is set or when the widget is destroyed.
+
+ If \a context is invalid, TQGLContext::create() is performed on
+ it. The initializeGL() function will then be executed for the new
+ context before the first resizeGL() or paintGL().
+
+ If \a context is invalid, this method will try to keep any existing
+ display list sharing with other TQGLWidgets this widget currently
+ has, or (if \a shareContext points to a valid context) start display
+ list sharing with that context, but it may fail. Use isSharing() to
+ test.
+
+ If \a deleteOldContext is TRUE (the default), the existing context
+ will be deleted. You may use FALSE here if you have kept a pointer
+ to the old context (as returned by context()), and want to restore
+ that context later.
+
+ \sa context(), isSharing()
+*/
+
+
+
+/*!
+ \fn void TQGLWidget::updateGL()
+
+ Updates the widget by calling glDraw().
+*/
+
+void TQGLWidget::updateGL()
+{
+ glDraw();
+}
+
+
+/*!
+ \fn void TQGLWidget::updateOverlayGL()
+
+ Updates the widget's overlay (if any). Will cause the virtual
+ function paintOverlayGL() to be executed.
+
+ The widget's rendering context will become the current context and
+ initializeGL() will be called if it hasn't already been called.
+*/
+
+
+/*!
+ This virtual function is called once before the first call to
+ paintGL() or resizeGL(), and then once whenever the widget has
+ been assigned a new TQGLContext. Reimplement it in a subclass.
+
+ This function should set up any required OpenGL context rendering
+ flags, defining display lists, etc.
+
+ There is no need to call makeCurrent() because this has already
+ been done when this function is called.
+*/
+
+void TQGLWidget::initializeGL()
+{
+}
+
+
+/*!
+ This virtual function is called whenever the widget needs to be
+ painted. Reimplement it in a subclass.
+
+ There is no need to call makeCurrent() because this has already
+ been done when this function is called.
+*/
+
+void TQGLWidget::paintGL()
+{
+}
+
+
+/*!
+ \fn void TQGLWidget::resizeGL( int width , int height )
+
+ This virtual function is called whenever the widget has been
+ resized. The new size is passed in \a width and \a height.
+ Reimplement it in a subclass.
+
+ There is no need to call makeCurrent() because this has already
+ been done when this function is called.
+*/
+
+void TQGLWidget::resizeGL( int, int )
+{
+}
+
+
+
+/*!
+ This virtual function is used in the same manner as initializeGL()
+ except that it operates on the widget's overlay context instead of
+ the widget's main context. This means that initializeOverlayGL()
+ is called once before the first call to paintOverlayGL() or
+ resizeOverlayGL(). Reimplement it in a subclass.
+
+ This function should set up any required OpenGL context rendering
+ flags, defining display lists, etc. for the overlay context.
+
+ There is no need to call makeOverlayCurrent() because this has
+ already been done when this function is called.
+*/
+
+void TQGLWidget::initializeOverlayGL()
+{
+}
+
+
+/*!
+ This virtual function is used in the same manner as paintGL()
+ except that it operates on the widget's overlay context instead of
+ the widget's main context. This means that paintOverlayGL() is
+ called whenever the widget's overlay needs to be painted.
+ Reimplement it in a subclass.
+
+ There is no need to call makeOverlayCurrent() because this has
+ already been done when this function is called.
+*/
+
+void TQGLWidget::paintOverlayGL()
+{
+}
+
+
+/*!
+ \fn void TQGLWidget::resizeOverlayGL( int width , int height )
+
+ This virtual function is used in the same manner as paintGL()
+ except that it operates on the widget's overlay context instead of
+ the widget's main context. This means that resizeOverlayGL() is
+ called whenever the widget has been resized. The new size is
+ passed in \a width and \a height. Reimplement it in a subclass.
+
+ There is no need to call makeOverlayCurrent() because this has
+ already been done when this function is called.
+*/
+
+void TQGLWidget::resizeOverlayGL( int, int )
+{
+}
+
+
+
+
+/*!
+ Handles paint events. Will cause the virtual paintGL() function to
+ be called.
+
+ The widget's rendering context will become the current context and
+ initializeGL() will be called if it hasn't already been called.
+*/
+
+void TQGLWidget::paintEvent( TQPaintEvent * )
+{
+ glDraw();
+ updateOverlayGL();
+}
+
+
+/*!
+ \fn void TQGLWidget::resizeEvent( TQResizeEvent * )
+
+ Handles resize events. Calls the virtual function resizeGL().
+*/
+
+
+/*!
+ \fn void TQGLWidget::setMouseTracking( bool enable )
+
+ \reimp
+*/
+
+
+/*!
+ Renders the current scene on a pixmap and returns the pixmap.
+
+ You can use this method on both visible and invisible TQGLWidgets.
+
+ This method will create a pixmap and a temporary TQGLContext to
+ render on the pixmap. It will then call initializeGL(),
+ resizeGL(), and paintGL() on this context. Finally, the widget's
+ original GL context is restored.
+
+ The size of the pixmap will be \a w pixels wide and \a h pixels
+ high unless one of these parameters is 0 (the default), in which
+ case the pixmap will have the same size as the widget.
+
+ If \a useContext is TRUE, this method will try to be more
+ efficient by using the existing GL context to render the pixmap.
+ The default is FALSE. Only use TRUE if you understand the risks.
+
+ Overlays are not rendered onto the pixmap.
+
+ If the GL rendering context and the desktop have different bit
+ depths, the result will most likely look surprising.
+
+ Note that the creation of display lists, modifications of the view
+ frustum etc. should be done from within initializeGL(). If this is
+ not done, the temporary TQGLContext will not be initialized
+ properly, and the rendered pixmap may be incomplete/corrupted.
+*/
+
+TQPixmap TQGLWidget::renderPixmap( int w, int h, bool useContext )
+{
+ TQSize sz = size();
+ if ( (w > 0) && (h > 0) )
+ sz = TQSize( w, h );
+
+#ifdef USE_QT4
+ // [FIXME]
+ bool needConversion = false;
+ TQPixmap pm;
+ pm.resize( sz );
+#else // USE_QT4
+#if defined(TQ_WS_X11)
+ TQPixmap pm( sz.width(), sz.height(), x11Depth() );
+ bool needConversion = x11Visual() != TQPaintDevice::x11AppVisual();
+
+ // make sure the pixmap uses the same visual as the widget itself
+ if ( needConversion ) {
+ TQPaintDeviceX11Data* xd = pm.getX11Data( TRUE );
+ xd->x_depth = x11Depth();
+ xd->x_visual = (Visual *) x11Visual();
+ pm.setX11Data( xd );
+ }
+#else
+ TQPixmap pm;
+ pm.resize( sz );
+#endif
+#endif // USE_QT4
+
+ glcx->doneCurrent();
+
+ bool success = TRUE;
+
+ if ( useContext && isValid() && renderCxPm( &pm ) )
+ return pm;
+
+ TQGLFormat fmt = glcx->requestedFormat();
+ fmt.setDirectRendering( FALSE ); // Direct is unlikely to work
+ fmt.setDoubleBuffer( FALSE ); // We don't need dbl buf
+
+ TQGLContext* ocx = glcx;
+ bool wasCurrent = (TQGLContext::currentContext() == ocx );
+ ocx->doneCurrent();
+ glcx = new TQGLContext( fmt, TQT_TQPAINTDEVICE(&pm) );
+ glcx->create();
+
+ if ( glcx->isValid() )
+ updateGL();
+ else
+ success = FALSE;
+
+ delete glcx;
+ glcx = ocx;
+
+ if ( wasCurrent )
+ ocx->makeCurrent();
+
+ if ( success ) {
+#if defined(TQ_WS_X11)
+ if ( needConversion ) {
+ TQImage image = pm.convertToImage();
+ TQPixmap p;
+ p = image;
+ return p;
+ }
+#endif
+ return pm;
+ } else
+ return TQPixmap();
+}
+
+
+
+/*!
+ Returns an image of the frame buffer. If \a withAlpha is TRUE the
+ alpha channel is included.
+
+ Depending on your hardware, you can explicitly select which color
+ buffer to grab with a glReadBuffer() call before calling this
+ function.
+*/
+TQImage TQGLWidget::grabFrameBuffer( bool withAlpha )
+{
+#if defined( TQ_WS_MAC )
+ if(dblbuf == macInternalDoubleBuffer(FALSE) && gl_pix) //why not optimize?
+ return ((TQPixmap*)gl_pix)->convertToImage();
+#endif
+ makeCurrent();
+ TQImage res;
+ int w = width();
+ int h = height();
+ if ( format().rgba() ) {
+ res = TQImage( w, h, 32 );
+ glReadPixels( 0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, res.bits() );
+ if ( TQImage::systemByteOrder() == TQImage::BigEndian ) {
+ // OpenGL gives RGBA; TQt wants ARGB
+ uint *p = (uint*)res.bits();
+ uint *end = p + w*h;
+ if ( withAlpha && format().alpha() ) {
+ while ( p < end ) {
+ uint a = *p << 24;
+ *p = (*p >> 8) | a;
+ p++;
+ }
+ }
+ else {
+ while ( p < end )
+ *p++ >>= 8;
+ }
+ }
+ else {
+ // OpenGL gives ABGR (i.e. RGBA backwards); TQt wants ARGB
+ res = res.swapRGB();
+ }
+ res.setAlphaBuffer( withAlpha && format().alpha() );
+ }
+ else {
+#if defined (TQ_WS_WIN)
+ res = TQImage( w, h, 8 );
+ glReadPixels( 0, 0, w, h, GL_COLOR_INDEX, GL_UNSIGNED_BYTE,
+ res.bits() );
+ int palSize = 0;
+ const TQRgb* pal = TQColor::palette( &palSize );
+ if ( pal && palSize ) {
+ res.setNumColors( palSize );
+ for ( int i = 0; i < palSize; i++ )
+ res.setColor( i, pal[i] );
+ }
+#endif
+ }
+
+ return res.mirror();
+}
+
+
+
+/*!
+ Initializes OpenGL for this widget's context. Calls the virtual
+ function initializeGL().
+*/
+
+void TQGLWidget::glInit()
+{
+ if ( !isValid() )
+ return;
+ makeCurrent();
+ initializeGL();
+ glcx->setInitialized( TRUE );
+}
+
+
+/*!
+ Executes the virtual function paintGL().
+
+ The widget's rendering context will become the current context and
+ initializeGL() will be called if it hasn't already been called.
+*/
+
+void TQGLWidget::glDraw()
+{
+ if ( !isValid() )
+ return;
+ makeCurrent();
+ if ( glcx->tqdeviceIsPixmap() )
+ glDrawBuffer( GL_FRONT );
+ if ( !glcx->initialized() ) {
+ glInit();
+ TQPaintDeviceMetrics dm( glcx->tqdevice() );
+ resizeGL( dm.width(), dm.height() ); // New context needs this "resize"
+ }
+ paintGL();
+ if ( doubleBuffer() ) {
+ if ( autoSwap )
+ swapBuffers();
+ } else {
+ glFlush();
+#if defined( TQ_WS_MAC )
+ if(dblbuf && gl_pix)
+ bitBlt(this, 0, 0, gl_pix);
+#endif
+ }
+}
+
+
+/*!
+ Convenience function for specifying a drawing color to OpenGL.
+ Calls glColor3 (in RGBA mode) or glIndex (in color-index mode)
+ with the color \a c. Applies to the current GL context.
+
+ \sa qglClearColor(), TQGLContext::currentContext(), TQColor
+*/
+
+void TQGLWidget::qglColor( const TQColor& c ) const
+{
+ const TQGLContext* ctx = TQGLContext::currentContext();
+ if ( ctx ) {
+ if ( ctx->format().rgba() )
+ glColor3ub( c.red(), c.green(), c.blue() );
+
+ else if ( ctx->tqdevice() == context()->tqdevice()
+ && !cmap.isEmpty() ) { // TQGLColormap in use?
+ int i = cmap.tqfind( c.rgb() );
+ if ( i < 0 )
+ i = cmap.tqfindNearest( c.rgb() );
+ glIndexi( i );
+ } else
+ glIndexi( ctx->colorIndex( c ) );
+ }
+}
+
+/*!
+ Convenience function for specifying the clearing color to OpenGL.
+ Calls glClearColor (in RGBA mode) or glClearIndex (in color-index
+ mode) with the color \a c. Applies to the current GL context.
+
+ \sa qglColor(), TQGLContext::currentContext(), TQColor
+*/
+
+void TQGLWidget::qglClearColor( const TQColor& c ) const
+{
+ const TQGLContext* ctx = TQGLContext::currentContext();
+ if ( ctx ) {
+ if ( ctx->format().rgba() )
+ glClearColor( (GLfloat)c.red() / 255.0, (GLfloat)c.green() / 255.0,
+ (GLfloat)c.blue() / 255.0, (GLfloat) 0.0 );
+ else if ( ctx->tqdevice() == context()->tqdevice()
+ && !cmap.isEmpty() ) { // TQGLColormap in use?
+ int i = cmap.tqfind( c.rgb() );
+ if ( i < 0 )
+ i = cmap.tqfindNearest( c.rgb() );
+ glClearIndex( i );
+ } else
+ glClearIndex( ctx->colorIndex( c ) );
+ }
+}
+
+
+/*!
+ Converts the image \a img into the unnamed format expected by
+ OpenGL functions such as glTexImage2D(). The returned image is not
+ usable as a TQImage, but TQImage::width(), TQImage::height() and
+ TQImage::bits() may be used with OpenGL. The following few lines
+ are from the texture example. Most of the code is irrelevant, so
+ we just quote the relevant bits:
+
+ \quotefile opengl/texture/gltexobj.cpp
+ \skipto tex1
+ \printline tex1
+ \printline gllogo.bmp
+
+ We create \e tex1 (and another variable) for OpenGL, and load a real
+ image into \e buf.
+
+ \skipto convertToGLFormat
+ \printline convertToGLFormat
+
+ A few lines later, we convert \e buf into OpenGL format and store it
+ in \e tex1.
+
+ \skipto glTexImage2D
+ \printline glTexImage2D
+ \printline tex1.bits
+
+ Note the dimension restrictions for texture images as described in
+ the glTexImage2D() documentation. The width must be 2^m + 2*border
+ and the height 2^n + 2*border where m and n are integers and
+ border is either 0 or 1.
+
+ Another function in the same example uses \e tex1 with OpenGL.
+*/
+
+
+TQImage TQGLWidget::convertToGLFormat( const TQImage& img )
+{
+ TQImage res = img.convertDepth( 32 );
+ res = res.mirror();
+
+ if ( TQImage::systemByteOrder() == TQImage::BigEndian ) {
+ // TQt has ARGB; OpenGL wants RGBA
+ for ( int i=0; i < res.height(); i++ ) {
+ uint *p = (uint*)res.scanLine( i );
+ uint *end = p + res.width();
+ while ( p < end ) {
+ *p = (*p << 8) | ((*p >> 24) & 0xFF);
+ p++;
+ }
+ }
+ }
+ else {
+ // TQt has ARGB; OpenGL wants ABGR (i.e. RGBA backwards)
+ res = res.swapRGB();
+ }
+ return res;
+}
+
+
+/*!
+ \fn TQGLColormap & TQGLWidget::colormap() const
+
+ Returns the colormap for this widget.
+
+ Usually it is only top-level widgets that can have different
+ colormaps installed. Asking for the colormap of a child widget
+ will return the colormap for the child's top-level widget.
+
+ If no colormap has been set for this widget, the TQColormap
+ returned will be empty.
+
+ \sa setColormap()
+*/
+
+/*!
+ \fn void TQGLWidget::setColormap( const TQGLColormap & cmap )
+
+ Set the colormap for this widget to \a cmap. Usually it is only
+ top-level widgets that can have colormaps installed.
+
+ \sa colormap()
+*/
+
+int TQGLWidget::displayListBase( const TQFont & fnt, int listBase )
+{
+ int base;
+
+ TQGLWidgetPrivate * d = qgl_d( this );
+ if ( !d || !glcx ) { // this can't happen unless we run out of mem
+ return 0;
+ }
+
+ // always regenerate font disp. lists for pixmaps - hw accelerated
+ // contexts can't handle this otherwise
+ bool regenerate = glcx->tqdeviceIsPixmap();
+
+#if 0 // TQT_NO_XFTFREETYPE
+ // font color needs to be part of the font cache key when using
+ // antialiased fonts since one set of glyphs needs to be generated
+ // for each font color
+ TQString color_key;
+ if (fnt.styleStrategy() != TQFont::NoAntialias) {
+ GLfloat color[4];
+ glGetFloatv(GL_CURRENT_COLOR, color);
+ color_key.sprintf("%f_%f_%f",color[0], color[1], color[2]);
+ }
+ TQString key = fnt.key() + color_key + TQString::number((int) regenerate);
+#else
+ TQString key = fnt.key() + TQString::number((int) regenerate);
+#endif
+
+ if ( !regenerate && (d->displayListCache.tqfind( key ) != d->displayListCache.end()) ) {
+ base = d->displayListCache[ key ];
+ } else {
+ int maxBase = listBase - 256;
+ TQMapConstIterator<TQString,int> it;
+ for ( it = d->displayListCache.begin(); it != d->displayListCache.end(); ++it ) {
+ if ( maxBase < it.data() ) {
+ maxBase = it.data();
+ }
+ }
+ maxBase += 256;
+ glcx->generateFontDisplayLists( fnt, maxBase );
+ d->displayListCache[ key ] = maxBase;
+ base = maxBase;
+ }
+ return base;
+}
+
+/*!
+ Renders the string \a str into the GL context of this widget.
+
+ \a x and \a y are specified in window coordinates, with the origin
+ in the upper left-hand corner of the window. If \a fnt is not
+ specified, the currently set application font will be used to
+ render the string. To change the color of the rendered text you can
+ use the glColor() call (or the qglColor() convenience function),
+ just before the renderText() call. Note that if you have
+ GL_LIGHTING enabled, the string will not appear in the color you
+ want. You should therefore switch lighting off before using
+ renderText().
+
+ \a listBase specifies the index of the first display list that is
+ generated by this function. The default value is 2000. 256 display
+ lists will be generated, one for each of the first 256 characters
+ in the font that is used to render the string. If several fonts are
+ used in the same widget, the display lists for these fonts will
+ follow the last generated list. You would normally not have to
+ change this value unless you are using lists in the same range. The
+ lists are deleted when the widget is destroyed.
+
+ Note: This function only works reliably with ASCII strings.
+*/
+
+void TQGLWidget::renderText( int x, int y, const TQString & str, const TQFont & fnt, int listBase )
+{
+ if (str.isEmpty())
+ return;
+ makeCurrent();
+ glPushAttrib( GL_TRANSFORM_BIT | GL_VIEWPORT_BIT | GL_LIST_BIT | GL_CURRENT_BIT );
+ glMatrixMode( GL_PROJECTION );
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho( 0, width(), height(), 0, -1, 1 );
+ glMatrixMode( GL_MODELVIEW );
+ glPushMatrix();
+ glLoadIdentity();
+
+ glRasterPos2i( 0, 0 );
+ glBitmap(0, 0, 0, 0, x, -y, NULL);
+ glListBase( displayListBase( fnt, listBase ) );
+ const char *cstr = str.latin1();
+ glCallLists( tqstrlen(cstr), GL_UNSIGNED_BYTE, cstr );
+
+ // restore the matrix stacks and GL state
+ glPopMatrix();
+ glMatrixMode( GL_PROJECTION );
+ glPopMatrix();
+ glPopAttrib();
+}
+
+/*! \overload
+
+ \a x, \a y and \a z are specified in scene or object coordinates
+ relative to the currently set projection and model matrices. This
+ can be useful if you want to annotate models with text labels and
+ have the labels move with the model as it is rotated etc.
+*/
+void TQGLWidget::renderText( double x, double y, double z, const TQString & str, const TQFont & fnt,
+ int listBase )
+{
+ if (str.isEmpty())
+ return;
+ makeCurrent();
+ glRasterPos3d( x, y, z );
+ glPushAttrib( GL_LIST_BIT );
+ glListBase( displayListBase( fnt, listBase ) );
+ const char *cstr = str.latin1();
+ glCallLists( tqstrlen(cstr), GL_UNSIGNED_BYTE, cstr );
+ glPopAttrib();
+}
+
+/*****************************************************************************
+ TQGL classes overview documentation.
+ *****************************************************************************/
+
+/*!
+
+\page opengl.html
+
+\title TQt OpenGL 3D Graphics
+
+\if defined(commercial)
+This module is part of the \link commercialeditions.html TQt Enterprise
+Edition\endlink.
+\endif
+
+\section1 Introduction
+
+OpenGL is a standard API for rendering 3D graphics.
+
+OpenGL only deals with 3D rendering and provides little or no support
+for GUI programming issues. The user interface for an
+OpenGL<sup>*</sup> application must be created with another toolkit,
+such as Motif on the X platform, Microsoft Foundation Classes (MFC)
+under Windows, or TQt on \e both platforms.
+
+The TQt OpenGL module makes it easy to use OpenGL in TQt applications.
+It provides an OpenGL widget class that can be used just like any
+other TQt widget, except that it opens an OpenGL display buffer where
+you can use the OpenGL API to render the contents.
+
+The TQt OpenGL module is implemented as a platform-independent TQt/C++
+wrapper around the platform-dependent GLX, WGL, or AGL C APIs. The
+functionality provided is very similar to Mark Kilgard's GLUT library,
+but with much more non-OpenGL-specific GUI functionality, i.e. the
+whole TQt API.
+
+\section1 Installation
+
+When you install TQt for X11, the configure script will autodetect if
+OpenGL headers and libraries are installed on your system, and if so,
+it will include the TQt OpenGL module in the TQt library. (If your
+OpenGL headers or libraries are placed in a non-standard directory,
+you may need to change the TQMAKE_INCDIR_OPENGL and/or
+TQMAKE_LIBDIR_OPENGL in the config file for your system). Some
+configurations require threading to be enabled for OpenGL, so if
+OpenGL is not detected, try \c{configure -thread}.
+
+When you install TQt for Windows, the TQt OpenGL module is always
+included.
+
+The TQt OpenGL module is not licensed for use with the TQt Professional
+Edition. Consider upgrading to the TQt Enterprise Edition if you
+require OpenGL support.
+
+Note about using Mesa on X11: Mesa versions earlier than 3.1 would use
+the name "MesaGL" and "MesaGLU" for the libraries, instead of "GL" and
+"GLU". If you want to use a pre-3.1 version of Mesa, you must change
+the Makefiles to use these library names instead. The easiest way to
+do this is to edit the TQMAKE_LIBS_OPENGL line in the config file you
+are using, changing "-lGL -lGLU" to "-lMesaGL -lMesaGLU"; then run
+"configure" again.
+
+\section1 The TQGL Classes
+
+The OpenGL support classes in TQt are:
+\list
+\i \link TQGLWidget TQGLWidget\endlink: An easy-to-use TQt
+ widget for rendering OpenGL scenes.
+\i \link TQGLContext TQGLContext\endlink: Encapsulates an OpenGL rendering context.
+\i \link TQGLFormat TQGLFormat\endlink: Specifies the
+display format of a rendering context.
+\i \link TQGLColormap TQGLColormap\endlink: Handles indexed
+colormaps in GL-index mode.
+\endlist
+
+Many applications only need the high-level TQGLWidget class. The other
+TQGL classes provide advanced features. X11 users might like to read
+the notes on \link opengl-x11-overlays.html overlays\endlink.
+
+See also the \link opengl-examples.html OpenGL examples\endlink.
+
+The TQGL documentation assumes that you are familiar with OpenGL
+programming. If you're new to the subject a good starting point is
+\l{http://www.opengl.org/}.
+
+
+<sup>*</sup> OpenGL is a trademark of Silicon Graphics, Inc. in the
+United States and other countries.
+
+*/
+
+/*!
+ \enum TQGL::FormatOption
+
+ This enum specifies the format options.
+
+ \value DoubleBuffer
+ \value DepthBuffer
+ \value Rgba
+ \value AlphaChannel
+ \value AccumBuffer
+ \value StencilBuffer
+ \value StereoBuffers
+ \value DirectRendering
+ \value HasOverlay
+ \value SingleBuffer
+ \value NoDepthBuffer
+ \value ColorIndex
+ \value NoAlphaChannel
+ \value NoAccumBuffer
+ \value NoStencilBuffer
+ \value NoStereoBuffers
+ \value IndirectRendering
+ \value NoOverlay
+*/
diff --git a/tqtinterface/qt4/src/opengl/tqgl.h b/tqtinterface/qt4/src/opengl/tqgl.h
new file mode 100644
index 0000000..4b6fce4
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqgl.h
@@ -0,0 +1,542 @@
+/****************************************************************************
+**
+** Definition of OpenGL classes for TQt
+**
+** Created : 970112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the opengl module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGL_H
+#define TQGL_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqglcolormap.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_OPENGL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_OPENGL
+#else
+#define TQM_EXPORT_OPENGL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_COMPAT
+#define TQGL_VERSION 450
+#define TQGL_VERSION_STR "4.5"
+TQM_EXPORT_OPENGL inline const char *qGLVersion() {
+ qObsolete( 0, "qGLVersion", "qVersion" );
+ return TQGL_VERSION_STR;
+}
+#endif
+
+#if defined(TQ_WS_WIN)
+# include "tqt_windows.h"
+#endif
+
+#if defined(TQ_WS_MAC)
+#if !defined( TQMAC_OPENGL_DOUBLEBUFFER )
+/* This macro is different now. If the macro is not defined TQGLWidget will
+ * try to determine when you need double buffering. If set to 0 it will
+ * never double buffer and *can* be acclerated. If set to 1 (the default)
+ * it will always double buffer. Unlike before the value of this macro does
+ * not upset binary compatability either. */
+#if TQT_MACOSX_VERSION >= 0x1020
+# define TQMAC_OPENGL_DOUBLEBUFFER 0
+#endif
+#endif
+# include <OpenGL/gl.h>
+# include <OpenGL/glu.h>
+#else
+# include <GL/gl.h>
+# include <GL/glu.h>
+#endif
+
+#if defined(TQ_WS_WIN) || defined(TQ_WS_MAC)
+class TQGLCmap;
+#endif
+
+class TQPixmap;
+#if defined(TQ_WS_X11)
+class TQGLOverlayWidget;
+#endif
+
+// Namespace class:
+class TQM_EXPORT_OPENGL TQGL
+{
+public:
+ enum FormatOption {
+ DoubleBuffer = 0x0001,
+ DepthBuffer = 0x0002,
+ Rgba = 0x0004,
+ AlphaChannel = 0x0008,
+ AccumBuffer = 0x0010,
+ StencilBuffer = 0x0020,
+ StereoBuffers = 0x0040,
+ DirectRendering = 0x0080,
+ HasOverlay = 0x0100,
+ SingleBuffer = DoubleBuffer << 16,
+ NoDepthBuffer = DepthBuffer << 16,
+ ColorIndex = Rgba << 16,
+ NoAlphaChannel = AlphaChannel << 16,
+ NoAccumBuffer = AccumBuffer << 16,
+ NoStencilBuffer = StencilBuffer << 16,
+ NoStereoBuffers = StereoBuffers << 16,
+ IndirectRendering = DirectRendering << 16,
+ NoOverlay = HasOverlay << 16
+ };
+};
+
+
+
+class TQM_EXPORT_OPENGL TQGLFormat : public TQGL
+{
+public:
+ TQGLFormat();
+ TQGLFormat( int options, int plane = 0 );
+
+ bool doubleBuffer() const;
+ void setDoubleBuffer( bool enable );
+ bool depth() const;
+ void setDepth( bool enable );
+ bool rgba() const;
+ void setRgba( bool enable );
+ bool alpha() const;
+ void setAlpha( bool enable );
+ bool accum() const;
+ void setAccum( bool enable );
+ bool stencil() const;
+ void setStencil( bool enable );
+ bool stereo() const;
+ void setStereo( bool enable );
+ bool directRendering() const;
+ void setDirectRendering( bool enable );
+ bool hasOverlay() const;
+ void setOverlay( bool enable );
+
+ int plane() const;
+ void setPlane( int plane );
+
+ void setOption( FormatOption opt );
+ bool testOption( FormatOption opt ) const;
+
+ static TQGLFormat defaultFormat();
+ static void setDefaultFormat( const TQGLFormat& f );
+
+ static TQGLFormat defaultOverlayFormat();
+ static void setDefaultOverlayFormat( const TQGLFormat& f );
+
+ static bool hasOpenGL();
+ static bool hasOpenGLOverlays();
+
+ friend TQM_EXPORT_OPENGL bool operator==( const TQGLFormat&,
+ const TQGLFormat& );
+ friend TQM_EXPORT_OPENGL bool operator!=( const TQGLFormat&,
+ const TQGLFormat& );
+private:
+ uint opts;
+ int pln;
+};
+
+
+TQM_EXPORT_OPENGL bool operator==( const TQGLFormat&, const TQGLFormat& );
+TQM_EXPORT_OPENGL bool operator!=( const TQGLFormat&, const TQGLFormat& );
+
+class TQM_EXPORT_OPENGL TQGLContext : public TQGL
+{
+public:
+ TQGLContext( const TQGLFormat& format, TQPaintDevice* tqdevice );
+ TQGLContext( const TQGLFormat& format );
+ virtual ~TQGLContext();
+
+ virtual bool create( const TQGLContext* shareContext = 0 );
+ bool isValid() const;
+ bool isSharing() const;
+ virtual void reset();
+
+ TQGLFormat format() const;
+ TQGLFormat requestedFormat() const;
+ virtual void setFormat( const TQGLFormat& format );
+
+ virtual void makeCurrent();
+ virtual void swapBuffers() const;
+
+ TQPaintDevice* tqdevice() const;
+
+ TQColor overlayTransparentColor() const;
+
+ static const TQGLContext* currentContext();
+
+protected:
+ virtual bool chooseContext( const TQGLContext* shareContext = 0 );
+ virtual void doneCurrent(); // ### 4.0: make this public - needed for multithreading stuff
+
+#if defined(TQ_WS_WIN)
+ virtual int choosePixelFormat( void* pfd, HDC pdc );
+#endif
+#if defined(TQ_WS_X11)
+ virtual void* tryVisual( const TQGLFormat& f, int bufDepth = 1 );
+ virtual void* chooseVisual();
+#endif
+#if defined(TQ_WS_MAC)
+ virtual void* chooseMacVisual(GDHandle);
+#endif
+
+ bool tqdeviceIsPixmap() const;
+ bool windowCreated() const;
+ void setWindowCreated( bool on );
+ bool initialized() const;
+ void setInitialized( bool on );
+ void generateFontDisplayLists( const TQFont & fnt, int listBase );
+
+ uint colorIndex( const TQColor& c ) const;
+ void setValid( bool valid );
+ void setDevice( TQPaintDevice *pDev );
+
+protected:
+#if defined(TQ_WS_WIN)
+ HGLRC rc;
+ HDC dc;
+ WId win;
+ int pixelFormatId;
+ TQGLCmap* cmap;
+#elif defined(TQ_WS_X11) || defined(TQ_WS_MAC)
+ void* vi;
+ void* cx;
+#if defined(TQ_WS_X11)
+ TQ_UINT32 gpm;
+#endif
+#endif
+ TQGLFormat glFormat;
+ TQGLFormat reqFormat;
+ static TQGLContext* currentCtx;
+
+private:
+ void init( TQPaintDevice *dev = 0 );
+ class Private {
+ public:
+ bool valid;
+ bool sharing;
+ bool initDone;
+ bool crWin;
+ TQPaintDevice* paintDevice;
+ TQColor transpColor;
+#ifdef TQ_WS_MAC
+ TQRect oldR;
+#endif
+ };
+ Private* d;
+
+ friend class TQGLWidget;
+#ifdef TQ_WS_MAC
+ void fixBufferRect();
+#endif
+
+private: // Disabled copy constructor and operator=
+ TQGLContext() {}
+ TQGLContext( const TQGLContext& ) {}
+ TQGLContext& operator=( const TQGLContext& ) { return *this; }
+};
+
+
+
+
+class TQM_EXPORT_OPENGL TQGLWidget : public TQWidget, public TQGL
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQGLWidget( TQWidget* tqparent=0, const char* name=0,
+ const TQGLWidget* shareWidget = 0, WFlags f=0 );
+ TQGLWidget( TQGLContext *context, TQWidget* tqparent, const char* name=0,
+ const TQGLWidget* shareWidget = 0, WFlags f=0 );
+ TQGLWidget( const TQGLFormat& format, TQWidget* tqparent=0, const char* name=0,
+ const TQGLWidget* shareWidget = 0, WFlags f=0 );
+ ~TQGLWidget();
+
+ void qglColor( const TQColor& c ) const;
+ void qglClearColor( const TQColor& c ) const;
+
+ bool isValid() const;
+ bool isSharing() const;
+ virtual void makeCurrent();
+ void doneCurrent();
+
+ bool doubleBuffer() const;
+ virtual void swapBuffers();
+
+ TQGLFormat format() const;
+#ifndef TQ_TQDOC
+ virtual void setFormat( const TQGLFormat& format );
+#endif
+
+ const TQGLContext* context() const;
+#ifndef TQ_TQDOC
+ virtual void setContext( TQGLContext* context,
+ const TQGLContext* shareContext = 0,
+ bool deleteOldContext = TRUE );
+#endif
+
+ virtual TQPixmap renderPixmap( int w = 0, int h = 0,
+ bool useContext = FALSE );
+ virtual TQImage grabFrameBuffer( bool withAlpha = FALSE );
+
+ virtual void makeOverlayCurrent();
+ const TQGLContext* overlayContext() const;
+
+ static TQImage convertToGLFormat( const TQImage& img );
+
+ void setMouseTracking( bool enable );
+ virtual void reparent( TQWidget* tqparent, WFlags f, const TQPoint& p,
+ bool showIt = FALSE );
+
+ const TQGLColormap & colormap() const;
+ void setColormap( const TQGLColormap & map );
+
+ void renderText( int x, int y, const TQString & str,
+ const TQFont & fnt = TQFont(), int listBase = 2000 );
+ void renderText( double x, double y, double z, const TQString & str,
+ const TQFont & fnt = TQFont(), int listBase = 2000 );
+public Q_SLOTS:
+ virtual void updateGL();
+ virtual void updateOverlayGL();
+
+protected:
+ virtual void initializeGL();
+ virtual void resizeGL( int w, int h );
+ virtual void paintGL();
+
+ virtual void initializeOverlayGL();
+ virtual void resizeOverlayGL( int w, int h );
+ virtual void paintOverlayGL();
+
+ void setAutoBufferSwap( bool on );
+ bool autoBufferSwap() const;
+
+ void paintEvent( TQPaintEvent* );
+ void resizeEvent( TQResizeEvent* );
+
+ virtual void glInit();
+ virtual void glDraw();
+
+private:
+ int displayListBase( const TQFont & fnt, int listBase );
+ void cleanupColormaps();
+ void init( TQGLContext *context, const TQGLWidget* shareWidget );
+ bool renderCxPm( TQPixmap* pm );
+ TQGLContext* glcx;
+ bool autoSwap;
+
+ TQGLColormap cmap;
+
+#if defined(TQ_WS_WIN) || defined(TQ_WS_MAC)
+ TQGLContext* olcx;
+#elif defined(TQ_WS_X11)
+ TQGLOverlayWidget* olw;
+ friend class TQGLOverlayWidget;
+#endif
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQGLWidget( const TQGLWidget& );
+ TQGLWidget& operator=( const TQGLWidget& );
+#endif
+
+#if defined(TQ_WS_MAC)
+private:
+ const TQGLContext *slcx;
+ uint pending_fix : 1,
+ glcx_dblbuf : 2,
+ dblbuf : 1,
+ clp_serial : 15;
+ TQPixmap *gl_pix;
+ TQGLFormat req_format;
+
+ void macInternalRecreateContext( TQGLContext *ctx,
+ const TQGLContext* = NULL,
+ bool update = TRUE );
+ bool macInternalDoubleBuffer( bool fix = TRUE );
+ virtual void setRegionDirty( bool );
+ virtual void macWidgetChangedWindow();
+#endif
+private Q_SLOTS:
+ void macInternalFixBufferRect();
+};
+
+
+//
+// TQGLFormat inline functions
+//
+
+inline bool TQGLFormat::doubleBuffer() const
+{
+ return testOption( DoubleBuffer );
+}
+
+inline bool TQGLFormat::depth() const
+{
+ return testOption( DepthBuffer );
+}
+
+inline bool TQGLFormat::rgba() const
+{
+ return testOption( Rgba );
+}
+
+inline bool TQGLFormat::alpha() const
+{
+ return testOption( AlphaChannel );
+}
+
+inline bool TQGLFormat::accum() const
+{
+ return testOption( AccumBuffer );
+}
+
+inline bool TQGLFormat::stencil() const
+{
+ return testOption( StencilBuffer );
+}
+
+inline bool TQGLFormat::stereo() const
+{
+ return testOption( StereoBuffers );
+}
+
+inline bool TQGLFormat::directRendering() const
+{
+ return testOption( DirectRendering );
+}
+
+inline bool TQGLFormat::hasOverlay() const
+{
+ return testOption( HasOverlay );
+}
+
+//
+// TQGLContext inline functions
+//
+
+inline bool TQGLContext::isValid() const
+{
+ return d->valid;
+}
+
+inline void TQGLContext::setValid( bool valid )
+{
+ d->valid = valid;
+}
+
+inline bool TQGLContext::isSharing() const
+{
+ return d->sharing;
+}
+
+inline TQGLFormat TQGLContext::format() const
+{
+ return glFormat;
+}
+
+inline TQGLFormat TQGLContext::requestedFormat() const
+{
+ return reqFormat;
+}
+
+inline TQPaintDevice* TQGLContext::tqdevice() const
+{
+ return d->paintDevice;
+}
+
+inline bool TQGLContext::tqdeviceIsPixmap() const
+{
+ return d->paintDevice->devType() == TQInternal::Pixmap;
+}
+
+
+inline bool TQGLContext::windowCreated() const
+{
+ return d->crWin;
+}
+
+
+inline void TQGLContext::setWindowCreated( bool on )
+{
+ d->crWin = on;
+}
+
+inline bool TQGLContext::initialized() const
+{
+ return d->initDone;
+}
+
+inline void TQGLContext::setInitialized( bool on )
+{
+ d->initDone = on;
+}
+
+inline const TQGLContext* TQGLContext::currentContext()
+{
+ return currentCtx;
+}
+
+//
+// TQGLWidget inline functions
+//
+
+inline TQGLFormat TQGLWidget::format() const
+{
+ return glcx->format();
+}
+
+inline const TQGLContext *TQGLWidget::context() const
+{
+ return glcx;
+}
+
+inline bool TQGLWidget::doubleBuffer() const
+{
+ return glcx->format().doubleBuffer();
+}
+
+inline void TQGLWidget::setAutoBufferSwap( bool on )
+{
+ autoSwap = on;
+}
+
+inline bool TQGLWidget::autoBufferSwap() const
+{
+ return autoSwap;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/opengl/tqgl_x11.cpp b/tqtinterface/qt4/src/opengl/tqgl_x11.cpp
new file mode 100644
index 0000000..56fc053
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqgl_x11.cpp
@@ -0,0 +1,1425 @@
+/****************************************************************************
+**
+** Implementation of OpenGL classes for TQt
+**
+** Created : 970112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the opengl module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqgl.h"
+
+#if defined(TQ_WS_X11)
+
+#include "tqmap.h"
+#include "tqpixmap.h"
+#include "tqapplication.h"
+
+#include "tqintdict.h"
+#include "private/tqfontengine_p.h"
+
+#define INT8 dummy_INT8
+#define INT32 dummy_INT32
+#include <GL/glx.h>
+#undef INT8
+#undef INT32
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xos.h>
+#include <X11/Xatom.h>
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+#ifndef TQT_DLOPEN_OPENGL
+extern "C" {
+ Status XmuLookupStandardColormap( Display *dpy, int screen, VisualID visualid,
+ unsigned int depth, Atom property,
+ Bool tqreplace, Bool retain );
+}
+#endif
+
+#include "tqgl_x11_p.h"
+#ifdef TQT_DLOPEN_OPENGL
+#include "tqlibrary.h"
+
+extern "C" {
+_glCallLists qt_glCallLists;
+_glClearColor qt_glClearColor;
+_glClearIndex qt_glClearIndex;
+_glColor3ub qt_glColor3ub;
+_glDeleteLists qt_glDeleteLists;
+_glDrawBuffer qt_glDrawBuffer;
+_glFlush qt_glFlush;
+_glIndexi qt_glIndexi;
+_glListBase qt_glListBase;
+_glLoadIdentity qt_glLoadIdentity;
+_glMatrixMode qt_glMatrixMode;
+_glOrtho qt_glOrtho;
+_glPopAttrib qt_glPopAttrib;
+_glPopMatrix qt_glPopMatrix;
+_glPushAttrib qt_glPushAttrib;
+_glPushMatrix qt_glPushMatrix;
+_glRasterPos2i qt_glRasterPos2i;
+_glRasterPos3d qt_glRasterPos3d;
+_glReadPixels qt_glReadPixels;
+_glViewport qt_glViewport;
+_glPixelStorei qt_glPixelStorei;
+_glBitmap qt_glBitmap;
+_glDrawPixels qt_glDrawPixels;
+_glNewList qt_glNewList;
+_glGetFloatv qt_glGetFloatv;
+_glGetIntegerv qt_glGetIntegerv;
+_glEndList qt_glEndList;
+
+_glXChooseVisual qt_glXChooseVisual;
+_glXCreateContext qt_glXCreateContext;
+_glXCreateGLXPixmap qt_glXCreateGLXPixmap;
+_glXDestroyContext qt_glXDestroyContext;
+_glXDestroyGLXPixmap qt_glXDestroyGLXPixmap;
+_glXGetClientString qt_glXGetClientString;
+_glXGetConfig qt_glXGetConfig;
+_glXIsDirect qt_glXIsDirect;
+_glXMakeCurrent qt_glXMakeCurrent;
+_glXQueryExtension qt_glXQueryExtension;
+_glXQueryExtensionsString qt_glXQueryExtensionsString;
+_glXQueryServerString qt_glXQueryServerString;
+_glXSwapBuffers qt_glXSwapBuffers;
+_glXUseXFont qt_glXUseXFont;
+_glXWaitX qt_glXWaitX;
+};
+
+bool qt_resolve_gl_symbols(bool fatal)
+{
+ static bool gl_syms_resolved = FALSE;
+ if (gl_syms_resolved)
+ return TRUE;
+
+ TQLibrary gl("GL");
+ gl.setAutoUnload(FALSE);
+
+ qt_glCallLists = (_glCallLists) gl.resolve("glCallLists");
+
+ if (!qt_glCallLists) { // if this fails the rest will surely fail
+ if (fatal)
+ qFatal("Unable to resolve GL/GLX symbols - please check your GL library installation.");
+ return FALSE;
+ }
+
+ qt_glClearColor = (_glClearColor) gl.resolve("glClearColor");
+ qt_glClearIndex = (_glClearIndex) gl.resolve("glClearIndex");
+ qt_glColor3ub = (_glColor3ub) gl.resolve("glColor3ub");
+ qt_glDeleteLists = (_glDeleteLists) gl.resolve("glDeleteLists");
+ qt_glDrawBuffer = (_glDrawBuffer) gl.resolve("glDrawBuffer");
+ qt_glFlush = (_glFlush) gl.resolve("glFlush");
+ qt_glIndexi = (_glIndexi) gl.resolve("glIndexi");
+ qt_glListBase = (_glListBase) gl.resolve("glListBase");
+ qt_glLoadIdentity = (_glLoadIdentity) gl.resolve("glLoadIdentity");
+ qt_glMatrixMode = (_glMatrixMode) gl.resolve("glMatrixMode");
+ qt_glOrtho = (_glOrtho) gl.resolve("glOrtho");
+ qt_glPopAttrib = (_glPopAttrib) gl.resolve("glPopAttrib");
+ qt_glPopMatrix = (_glPopMatrix) gl.resolve("glPopMatrix");
+ qt_glPushAttrib = (_glPushAttrib) gl.resolve("glPushAttrib");
+ qt_glPushMatrix = (_glPushMatrix) gl.resolve("glPushMatrix");
+ qt_glRasterPos2i = (_glRasterPos2i) gl.resolve("glRasterPos2i");
+ qt_glRasterPos3d = (_glRasterPos3d) gl.resolve("glRasterPos3d");
+ qt_glReadPixels = (_glReadPixels) gl.resolve("glReadPixels");
+ qt_glViewport = (_glViewport) gl.resolve("glViewport");
+ qt_glPixelStorei = (_glPixelStorei) gl.resolve("glPixelStorei");
+ qt_glBitmap = (_glBitmap) gl.resolve("glBitmap");
+ qt_glDrawPixels = (_glDrawPixels) gl.resolve("glDrawPixels");
+ qt_glNewList = (_glNewList) gl.resolve("glNewList");
+ qt_glGetFloatv = (_glGetFloatv) gl.resolve("glGetFloatv");
+ qt_glGetIntegerv = (_glGetIntegerv) gl.resolve("glGetIntegerv");
+ qt_glEndList = (_glEndList) gl.resolve("glEndList");
+
+ qt_glXChooseVisual = (_glXChooseVisual) gl.resolve("glXChooseVisual");
+ qt_glXCreateContext = (_glXCreateContext) gl.resolve("glXCreateContext");
+ qt_glXCreateGLXPixmap = (_glXCreateGLXPixmap) gl.resolve("glXCreateGLXPixmap");
+ qt_glXDestroyContext = (_glXDestroyContext) gl.resolve("glXDestroyContext");
+ qt_glXDestroyGLXPixmap = (_glXDestroyGLXPixmap) gl.resolve("glXDestroyGLXPixmap");
+ qt_glXGetClientString = (_glXGetClientString) gl.resolve("glXGetClientString");
+ qt_glXGetConfig = (_glXGetConfig) gl.resolve("glXGetConfig");
+ qt_glXIsDirect = (_glXIsDirect) gl.resolve("glXIsDirect");
+ qt_glXMakeCurrent = (_glXMakeCurrent) gl.resolve("glXMakeCurrent");
+ qt_glXQueryExtension = (_glXQueryExtension) gl.resolve("glXQueryExtension");
+ qt_glXQueryExtensionsString = (_glXQueryExtensionsString) gl.resolve("glXQueryExtensionsString");
+ qt_glXQueryServerString = (_glXQueryServerString) gl.resolve("glXQueryServerString");
+ qt_glXSwapBuffers = (_glXSwapBuffers) gl.resolve("glXSwapBuffers");
+ qt_glXUseXFont = (_glXUseXFont) gl.resolve("glXUseXFont");
+ qt_glXWaitX = (_glXWaitX) gl.resolve("glXWaitX");
+ gl_syms_resolved = TRUE;
+ return TRUE;
+}
+#endif // TQT_DLOPEN_OPENGL
+
+
+/*
+ The choose_cmap function is internal and used by TQGLWidget::setContext()
+ and GLX (not Windows). If the application can't tqfind any sharable
+ colormaps, it must at least create as few colormaps as possible. The
+ dictionary solution below ensures only one colormap is created per visual.
+ Colormaps are also deleted when the application terminates.
+*/
+
+struct CMapEntry {
+ CMapEntry();
+ ~CMapEntry();
+ Colormap cmap;
+ bool alloc;
+ XStandardColormap scmap;
+};
+
+CMapEntry::CMapEntry()
+{
+ cmap = 0;
+ alloc = FALSE;
+ scmap.colormap = 0;
+}
+
+CMapEntry::~CMapEntry()
+{
+ if ( alloc )
+ XFreeColormap( TQPaintDevice::x11AppDisplay(), cmap );
+}
+
+static TQIntDict<CMapEntry> *cmap_dict = 0;
+static bool mesa_gl = FALSE;
+static TQIntDict< TQMap<int, TQRgb> > *qglcmap_dict = 0;
+
+static void cleanup_cmaps()
+{
+ if (cmap_dict) {
+ cmap_dict->setAutoDelete(TRUE);
+ delete cmap_dict;
+ cmap_dict = 0;
+ }
+ if (qglcmap_dict) {
+ qglcmap_dict->setAutoDelete(TRUE);
+ delete qglcmap_dict;
+ qglcmap_dict = 0;
+ }
+}
+
+static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
+{
+ if ( !cmap_dict ) {
+ cmap_dict = new TQIntDict<CMapEntry>;
+ const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
+ if ( v )
+ mesa_gl = strstr(v,"Mesa") != 0;
+ qAddPostRoutine( cleanup_cmaps );
+ }
+
+ CMapEntry *x = cmap_dict->tqfind( (long) vi->visualid + ( vi->screen * 256 ) );
+ if ( x ) // found colormap for visual
+ return x->cmap;
+
+ x = new CMapEntry();
+
+ XStandardColormap *c;
+ int n, i;
+
+ // qDebug( "Choosing cmap for vID %0x", vi->visualid );
+
+ if ( vi->visualid ==
+ XVisualIDFromVisual( (Visual*)TQPaintDevice::x11AppVisual( vi->screen ) ) ) {
+ // qDebug( "Using x11AppColormap" );
+ return TQPaintDevice::x11AppColormap( vi->screen );
+ }
+
+ if ( mesa_gl ) { // we're using MesaGL
+ Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", TRUE );
+ if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 ) {
+ if ( XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
+ hp_cmaps) ) {
+ i = 0;
+ while ( i < n && x->cmap == 0 ) {
+ if ( c[i].visualid == vi->visual->visualid ) {
+ x->cmap = c[i].colormap;
+ x->scmap = c[i];
+ //qDebug( "Using HP_RGB scmap" );
+
+ }
+ i++;
+ }
+ XFree( (char *)c );
+ }
+ }
+ }
+#if !defined(TQ_OS_SOLARIS)
+ if ( !x->cmap ) {
+#ifdef TQT_DLOPEN_OPENGL
+ typedef Status (*_XmuLookupStandardColormap)( Display *dpy, int screen, VisualID visualid, unsigned int depth,
+ Atom property, Bool tqreplace, Bool retain );
+ _XmuLookupStandardColormap qt_XmuLookupStandardColormap;
+ qt_XmuLookupStandardColormap = (_XmuLookupStandardColormap) TQLibrary::resolve("Xmu", "XmuLookupStandardColormap");
+ if (!qt_XmuLookupStandardColormap)
+ qFatal("Unable to resolve Xmu symbols - please check your Xmu library installation.");
+#define XmuLookupStandardColormap qt_XmuLookupStandardColormap
+
+#endif
+
+ if ( XmuLookupStandardColormap(dpy,vi->screen,vi->visualid,vi->depth,
+ XA_RGB_DEFAULT_MAP,FALSE,TRUE) ) {
+ if ( XGetRGBColormaps(dpy,RootWindow(dpy,vi->screen),&c,&n,
+ XA_RGB_DEFAULT_MAP) ) {
+ i = 0;
+ while ( i < n && x->cmap == 0 ) {
+ if ( c[i].visualid == vi->visualid ) {
+ x->cmap = c[i].colormap;
+ x->scmap = c[i];
+ //qDebug( "Using RGB_DEFAULT scmap" );
+ }
+ i++;
+ }
+ XFree( (char *)c );
+ }
+ }
+ }
+#endif
+ if ( !x->cmap ) { // no shared cmap found
+ x->cmap = XCreateColormap( dpy, RootWindow(dpy,vi->screen), vi->visual,
+ AllocNone );
+ x->alloc = TRUE;
+ // qDebug( "Allocating cmap" );
+ }
+
+ // associate cmap with visualid
+ cmap_dict->insert( (long) vi->visualid + ( vi->screen * 256 ), x );
+ return x->cmap;
+}
+
+struct TransColor
+{
+ VisualID vis;
+ int screen;
+ long color;
+};
+
+static TQMemArray<TransColor> trans_colors;
+static int trans_colors_init = FALSE;
+
+
+static void tqfind_trans_colors()
+{
+ struct OverlayProp {
+ long visual;
+ long type;
+ long value;
+ long layer;
+ };
+
+ trans_colors_init = TRUE;
+
+ Display* appDisplay = TQPaintDevice::x11AppDisplay();
+
+ int scr;
+ int lastsize = 0;
+ for ( scr = 0; scr < ScreenCount( appDisplay ); scr++ ) {
+ TQWidget* rootWin = TQT_TQWIDGET(TQApplication::desktop()->screen( scr ));
+ if ( !rootWin )
+ return; // Should not happen
+ Atom overlayVisualsAtom = XInternAtom( appDisplay,
+ "SERVER_OVERLAY_VISUALS", True );
+ if ( overlayVisualsAtom == None )
+ return; // Server has no overlays
+
+ Atom actualType;
+ int actualFormat;
+ ulong nItems;
+ ulong bytesAfter;
+ OverlayProp* overlayProps = 0;
+ int res = XGetWindowProperty( appDisplay, rootWin->winId(),
+ overlayVisualsAtom, 0, 10000, False,
+ overlayVisualsAtom, &actualType,
+ &actualFormat, &nItems, &bytesAfter,
+ (uchar**)&overlayProps );
+
+ if ( res != Success || actualType != overlayVisualsAtom
+ || actualFormat != 32 || nItems < 4 || !overlayProps )
+ return; // Error reading property
+
+ int numProps = nItems / 4;
+ trans_colors.resize( lastsize + numProps );
+ int j = lastsize;
+ for ( int i = 0; i < numProps; i++ ) {
+ if ( overlayProps[i].type == 1 ) {
+ trans_colors[j].vis = (VisualID)overlayProps[i].visual;
+ trans_colors[j].screen = scr;
+ trans_colors[j].color = (int)overlayProps[i].value;
+ j++;
+ }
+ }
+ XFree( overlayProps );
+ lastsize = j;
+ trans_colors.truncate( lastsize );
+ }
+}
+
+
+/*****************************************************************************
+ TQGLFormat UNIX/GLX-specific code
+ *****************************************************************************/
+
+bool TQGLFormat::hasOpenGL()
+{
+ if (!qt_resolve_gl_symbols(FALSE))
+ return FALSE;
+ return glXQueryExtension(qt_xdisplay(),0,0) != 0;
+}
+
+
+bool TQGLFormat::hasOpenGLOverlays()
+{
+ qt_resolve_gl_symbols();
+ if ( !trans_colors_init )
+ tqfind_trans_colors();
+ return trans_colors.size() > 0;
+}
+
+
+
+/*****************************************************************************
+ TQGLContext UNIX/GLX-specific code
+ *****************************************************************************/
+
+bool TQGLContext::chooseContext( const TQGLContext* shareContext )
+{
+ Display* disp = d->paintDevice->x11Display();
+ vi = chooseVisual();
+ if ( !vi )
+ return FALSE;
+
+ if ( tqdeviceIsPixmap() &&
+ (((XVisualInfo*)vi)->depth != d->paintDevice->x11Depth() ||
+ ((XVisualInfo*)vi)->screen != d->paintDevice->x11Screen()) )
+ {
+ XFree( vi );
+ XVisualInfo appVisInfo;
+ memset( &appVisInfo, 0, sizeof(XVisualInfo) );
+ appVisInfo.visualid = XVisualIDFromVisual( (Visual*)d->paintDevice->x11Visual() );
+ appVisInfo.screen = d->paintDevice->x11Screen();
+ int nvis;
+ vi = XGetVisualInfo( disp, VisualIDMask | VisualScreenMask, &appVisInfo, &nvis );
+ if ( !vi )
+ return FALSE;
+
+ int useGL;
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_USE_GL, &useGL );
+ if ( !useGL )
+ return FALSE; //# Chickening out already...
+ }
+ int res;
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_LEVEL, &res );
+ glFormat.setPlane( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_DOUBLEBUFFER, &res );
+ glFormat.setDoubleBuffer( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_DEPTH_SIZE, &res );
+ glFormat.setDepth( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_RGBA, &res );
+ glFormat.setRgba( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_ALPHA_SIZE, &res );
+ glFormat.setAlpha( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_ACCUM_RED_SIZE, &res );
+ glFormat.setAccum( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_STENCIL_SIZE, &res );
+ glFormat.setStencil( res );
+ glXGetConfig( disp, (XVisualInfo*)vi, GLX_STEREO, &res );
+ glFormat.setStereo( res );
+
+ Bool direct = format().directRendering() ? True : False;
+
+ if ( shareContext &&
+ ( !shareContext->isValid() || !shareContext->cx ) ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning("TQGLContext::chooseContext(): Cannot share with invalid context");
+#endif
+ shareContext = 0;
+ }
+
+ // 1. Sharing between rgba and color-index will give wrong colors.
+ // 2. Contexts cannot be shared btw. direct/non-direct renderers.
+ // 3. Pixmaps cannot share contexts that are set up for direct rendering.
+ if ( shareContext && (format().rgba() != shareContext->format().rgba() ||
+ (tqdeviceIsPixmap() &&
+ glXIsDirect( disp, (GLXContext)shareContext->cx ))))
+ shareContext = 0;
+
+ cx = 0;
+ if ( shareContext ) {
+ cx = glXCreateContext( disp, (XVisualInfo *)vi,
+ (GLXContext)shareContext->cx, direct );
+ if ( cx )
+ d->sharing = TRUE;
+ }
+ if ( !cx )
+ cx = glXCreateContext( disp, (XVisualInfo *)vi, None, direct );
+ if ( !cx )
+ return FALSE;
+ glFormat.setDirectRendering( glXIsDirect( disp, (GLXContext)cx ) );
+ if ( tqdeviceIsPixmap() ) {
+#if defined(GLX_MESA_pixmap_colormap) && defined(TQGL_USE_MESA_EXT)
+ gpm = glXCreateGLXPixmapMESA( disp, (XVisualInfo *)vi,
+ d->paintDevice->handle(),
+ choose_cmap( disp, (XVisualInfo *)vi ) );
+#else
+ gpm = (TQ_UINT32)glXCreateGLXPixmap( disp, (XVisualInfo *)vi,
+ d->paintDevice->handle() );
+#endif
+ if ( !gpm )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+/*!
+ <strong>X11 only</strong>: This virtual function tries to tqfind a
+ visual that matches the format, reducing the demands if the original
+ request cannot be met.
+
+ The algorithm for reducing the demands of the format is quite
+ simple-minded, so override this method in your subclass if your
+ application has spcific requirements on visual selection.
+
+ \sa chooseContext()
+*/
+
+void *TQGLContext::chooseVisual()
+{
+ static int bufDepths[] = { 8, 4, 2, 1 }; // Try 16, 12 also?
+ //todo: if pixmap, also make sure that vi->depth == pixmap->depth
+ void* vis = 0;
+ int i = 0;
+ bool fail = FALSE;
+ TQGLFormat fmt = format();
+ bool tryDouble = !fmt.doubleBuffer(); // Some GL impl's only have double
+ bool triedDouble = FALSE;
+ while( !fail && !( vis = tryVisual( fmt, bufDepths[i] ) ) ) {
+ if ( !fmt.rgba() && bufDepths[i] > 1 ) {
+ i++;
+ continue;
+ }
+ if ( tryDouble ) {
+ fmt.setDoubleBuffer( TRUE );
+ tryDouble = FALSE;
+ triedDouble = TRUE;
+ continue;
+ }
+ else if ( triedDouble ) {
+ fmt.setDoubleBuffer( FALSE );
+ triedDouble = FALSE;
+ }
+ if ( fmt.stereo() ) {
+ fmt.setStereo( FALSE );
+ continue;
+ }
+ if ( fmt.accum() ) {
+ fmt.setAccum( FALSE );
+ continue;
+ }
+ if ( fmt.stencil() ) {
+ fmt.setStencil( FALSE );
+ continue;
+ }
+ if ( fmt.alpha() ) {
+ fmt.setAlpha( FALSE );
+ continue;
+ }
+ if ( fmt.depth() ) {
+ fmt.setDepth( FALSE );
+ continue;
+ }
+ if ( fmt.doubleBuffer() ) {
+ fmt.setDoubleBuffer( FALSE );
+ continue;
+ }
+ fail = TRUE;
+ }
+ glFormat = fmt;
+ return vis;
+}
+
+
+/*!
+
+ \internal
+
+ <strong>X11 only</strong>: This virtual function chooses a visual
+ that matches the OpenGL \link format() format\endlink. Reimplement this
+ function in a subclass if you need a custom visual.
+
+ \sa chooseContext()
+*/
+
+void *TQGLContext::tryVisual( const TQGLFormat& f, int bufDepth )
+{
+ int spec[40];
+ int i = 0;
+ spec[i++] = GLX_LEVEL;
+ spec[i++] = f.plane();
+
+#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info)
+ static bool useTranspExt = FALSE;
+ static bool useTranspExtChecked = FALSE;
+ if ( f.plane() && !useTranspExtChecked && d->paintDevice ) {
+ TQCString estr( glXQueryExtensionsString( d->paintDevice->x11Display(),
+ d->paintDevice->x11Screen() ) );
+ useTranspExt = estr.tqcontains( "GLX_EXT_visual_info" );
+ //# (A bit simplistic; that could theoretically be a substring)
+ if ( useTranspExt ) {
+ TQCString cstr( glXGetClientString( d->paintDevice->x11Display(),
+ GLX_VENDOR ) );
+ useTranspExt = !cstr.tqcontains( "Xi Graphics" ); // bug workaround
+ if ( useTranspExt ) {
+ // bug workaround - some systems (eg. FireGL) refuses to return an overlay
+ // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specfied, even if
+ // the implementation supports transtqparent overlays
+ int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT,
+ f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT,
+ None };
+ XVisualInfo * vinf = glXChooseVisual( d->paintDevice->x11Display(),
+ d->paintDevice->x11Screen(), tmpSpec );
+ if ( !vinf ) {
+ useTranspExt = FALSE;
+ }
+ }
+ }
+
+ useTranspExtChecked = TRUE;
+ }
+ if ( f.plane() && useTranspExt ) {
+ // Required to avoid non-transtqparent overlay visual(!) on some systems
+ spec[i++] = GLX_TRANSPARENT_TYPE_EXT;
+ spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
+ }
+#endif
+
+ if ( f.doubleBuffer() )
+ spec[i++] = GLX_DOUBLEBUFFER;
+ if ( f.depth() ) {
+ spec[i++] = GLX_DEPTH_SIZE;
+ spec[i++] = 1;
+ }
+ if ( f.stereo() ) {
+ spec[i++] = GLX_STEREO;
+ }
+ if ( f.stencil() ) {
+ spec[i++] = GLX_STENCIL_SIZE;
+ spec[i++] = 1;
+ }
+ if ( f.rgba() ) {
+ spec[i++] = GLX_RGBA;
+ spec[i++] = GLX_RED_SIZE;
+ spec[i++] = 1;
+ spec[i++] = GLX_GREEN_SIZE;
+ spec[i++] = 1;
+ spec[i++] = GLX_BLUE_SIZE;
+ spec[i++] = 1;
+ if ( f.alpha() ) {
+ spec[i++] = GLX_ALPHA_SIZE;
+ spec[i++] = 1;
+ }
+ if ( f.accum() ) {
+ spec[i++] = GLX_ACCUM_RED_SIZE;
+ spec[i++] = 1;
+ spec[i++] = GLX_ACCUM_GREEN_SIZE;
+ spec[i++] = 1;
+ spec[i++] = GLX_ACCUM_BLUE_SIZE;
+ spec[i++] = 1;
+ if ( f.alpha() ) {
+ spec[i++] = GLX_ACCUM_ALPHA_SIZE;
+ spec[i++] = 1;
+ }
+ }
+ }
+ else {
+ spec[i++] = GLX_BUFFER_SIZE;
+ spec[i++] = bufDepth;
+ }
+
+ spec[i] = None;
+ return glXChooseVisual( d->paintDevice->x11Display(),
+ d->paintDevice->x11Screen(), spec );
+}
+
+
+void TQGLContext::reset()
+{
+ if ( !d->valid )
+ return;
+ doneCurrent();
+ if ( gpm )
+ glXDestroyGLXPixmap( d->paintDevice->x11Display(), (GLXPixmap)gpm );
+ gpm = 0;
+ glXDestroyContext( d->paintDevice->x11Display(), (GLXContext)cx );
+ if ( vi )
+ XFree( vi );
+ vi = 0;
+ cx = 0;
+ d->crWin = FALSE;
+ d->sharing = FALSE;
+ d->valid = FALSE;
+ d->transpColor = TQColor();
+ d->initDone = FALSE;
+}
+
+
+void TQGLContext::makeCurrent()
+{
+ if ( !d->valid ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQGLContext::makeCurrent(): Cannot make invalid context current.");
+#endif
+ return;
+ }
+ bool ok = TRUE;
+ if ( tqdeviceIsPixmap() )
+ ok = glXMakeCurrent( d->paintDevice->x11Display(),
+ (GLXPixmap)gpm,
+ (GLXContext)cx );
+
+ else
+ ok = glXMakeCurrent( d->paintDevice->x11Display(),
+ ((TQWidget *)d->paintDevice)->winId(),
+ (GLXContext)cx );
+#if defined(TQT_CHECK_NULL)
+ // qDebug("makeCurrent: %i, vi=%i, vi->vi=%i, vi->id=%i", (int)this, (int)vi, (int)((XVisualInfo*)vi)->visual, (int)((XVisualInfo*)vi)->visualid );
+ if ( !ok )
+ qWarning("TQGLContext::makeCurrent(): Failed.");
+#endif
+ if ( ok )
+ currentCtx = this;
+}
+
+void TQGLContext::doneCurrent()
+{
+ glXMakeCurrent( d->paintDevice->x11Display(), 0, 0 );
+ currentCtx = 0;
+}
+
+
+void TQGLContext::swapBuffers() const
+{
+ if ( !d->valid )
+ return;
+ if ( !tqdeviceIsPixmap() )
+ glXSwapBuffers( d->paintDevice->x11Display(),
+ ((TQWidget *)d->paintDevice)->winId() );
+}
+
+TQColor TQGLContext::overlayTransparentColor() const
+{
+ //### make more efficient using the transpColor member
+ if ( isValid() ) {
+ if ( !trans_colors_init )
+ tqfind_trans_colors();
+
+ VisualID myVisualId = ((XVisualInfo*)vi)->visualid;
+ int myScreen = ((XVisualInfo*)vi)->screen;
+ for ( int i = 0; i < (int)trans_colors.size(); i++ ) {
+ if ( trans_colors[i].vis == myVisualId &&
+ trans_colors[i].screen == myScreen ) {
+ XColor col;
+ col.pixel = trans_colors[i].color;
+ col.red = col.green = col.blue = 0;
+ col.flags = 0;
+ Display *dpy = d->paintDevice->x11Display();
+ if (col.pixel > (uint) ((XVisualInfo *)vi)->colormap_size - 1)
+ col.pixel = ((XVisualInfo *)vi)->colormap_size - 1;
+ XQueryColor(dpy, choose_cmap(dpy, (XVisualInfo *) vi), &col);
+ uchar r = (uchar)((col.red / 65535.0) * 255.0 + 0.5);
+ uchar g = (uchar)((col.green / 65535.0) * 255.0 + 0.5);
+ uchar b = (uchar)((col.blue / 65535.0) * 255.0 + 0.5);
+ return TQColor(tqRgb(r,g,b), trans_colors[i].color);
+ }
+ }
+ }
+ return TQColor(); // Invalid color
+}
+
+
+uint TQGLContext::colorIndex( const TQColor& c ) const
+{
+ int screen = ((XVisualInfo *)vi)->screen;
+ if ( isValid() ) {
+ if ( format().plane()
+ && c.pixel( screen ) == overlayTransparentColor().pixel( screen ) )
+ return c.pixel( screen ); // Special; don't look-up
+ if ( ((XVisualInfo*)vi)->visualid ==
+ XVisualIDFromVisual( (Visual*)TQPaintDevice::x11AppVisual( screen ) ) )
+ return c.pixel( screen ); // We're using TQColor's cmap
+
+ XVisualInfo *info = (XVisualInfo *) vi;
+ CMapEntry *x = cmap_dict->tqfind( (long) info->visualid + ( info->screen * 256 ) );
+ if ( x && !x->alloc) { // It's a standard colormap
+ int rf = (int)(((float)c.red() * (x->scmap.red_max+1))/256.0);
+ int gf = (int)(((float)c.green() * (x->scmap.green_max+1))/256.0);
+ int bf = (int)(((float)c.blue() * (x->scmap.blue_max+1))/256.0);
+ uint p = x->scmap.base_pixel
+ + ( rf * x->scmap.red_mult )
+ + ( gf * x->scmap.green_mult )
+ + ( bf * x->scmap.blue_mult );
+ return p;
+ } else {
+ if (!qglcmap_dict) {
+ qglcmap_dict = new TQIntDict< TQMap<int, TQRgb> >;
+ }
+ TQMap<int, TQRgb> *cmap;
+ if ((cmap = qglcmap_dict->tqfind((long) info->visualid)) == 0) {
+ cmap = new TQMap<int, TQRgb>;
+ qglcmap_dict->insert((long) info->visualid, cmap);
+ }
+
+ // already in the map?
+ TQRgb target = c.rgb();
+ TQMap<int, TQRgb>::Iterator it = cmap->begin();
+ for (; it != cmap->end(); ++it) {
+ if ((*it) == target)
+ return it.key();
+ }
+
+ // need to alloc color
+ unsigned long plane_mask[2];
+ unsigned long color_map_entry;
+ if (!XAllocColorCells (TQPaintDevice::x11AppDisplay(), x->cmap, TRUE, plane_mask, 0,
+ &color_map_entry, 1))
+ return c.pixel(screen);
+
+ XColor col;
+ col.flags = DoRed | DoGreen | DoBlue;
+ col.pixel = color_map_entry;
+ col.red = (ushort)((tqRed(c.rgb()) / 255.0) * 65535.0 + 0.5);
+ col.green = (ushort)((tqGreen(c.rgb()) / 255.0) * 65535.0 + 0.5);
+ col.blue = (ushort)((tqBlue(c.rgb()) / 255.0) * 65535.0 + 0.5);
+ XStoreColor(TQPaintDevice::x11AppDisplay(), x->cmap, &col);
+
+ cmap->insert(color_map_entry, target);
+ return color_map_entry;
+ }
+ }
+ return 0;
+}
+
+#ifdef USE_QT4
+// [FIXME] Implement this or switch to Qt4's OpenGL classes (preferred)
+void TQGLContext::generateFontDisplayLists( const TQFont & fnt, int listBase )
+{
+ printf("[FIXME] void TQGLContext::generateFontDisplayLists( const TQFont & fnt, int listBase ) unimplemented\n\r");
+}
+#else // USE_QT4
+#ifndef TQT_NO_XFTFREETYPE
+/*! \internal
+ This is basically a substitute for glxUseXFont() which can only
+ handle XLFD fonts. This version relies on XFT v2 to render the
+ glyphs, but it works with all fonts that XFT2 provides - both
+ antialiased and aliased bitmap and outline fonts.
+*/
+void qgl_use_font(TQFontEngineXft *engine, int first, int count, int listBase)
+{
+ GLfloat color[4];
+ glGetFloatv(GL_CURRENT_COLOR, color);
+
+ // save the pixel unpack state
+ GLint gl_swapbytes, gl_lsbfirst, gl_rowlength, gl_skiprows, gl_skippixels, gl_tqalignment;
+ glGetIntegerv (GL_UNPACK_SWAP_BYTES, &gl_swapbytes);
+ glGetIntegerv (GL_UNPACK_LSB_FIRST, &gl_lsbfirst);
+ glGetIntegerv (GL_UNPACK_ROW_LENGTH, &gl_rowlength);
+ glGetIntegerv (GL_UNPACK_SKIP_ROWS, &gl_skiprows);
+ glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &gl_skippixels);
+ glGetIntegerv (GL_UNPACK_ALIGNMENT, &gl_tqalignment);
+
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ Bool antialiased = False;
+#if 0 // disable antialias support for now
+ XftPatternGetBool(engine->pattern(), XFT_ANTIALIAS, 0, &antialiased);
+#endif
+#ifdef TQT_XFT2
+ FT_Face face = XftLockFace(engine->font());
+#else
+ FT_Face face = engine->face();
+#endif
+ // start generating font glyphs
+ for (int i = first; i < count; ++i) {
+ int list = listBase + i;
+ GLfloat x0, y0, dx, dy;
+
+ FT_Error err;
+
+ err = FT_Load_Glyph(face, FT_Get_Char_Index(face, i), FT_LOAD_DEFAULT);
+ if (err) {
+ qDebug("failed loading glyph %d from font", i);
+ TQ_ASSERT(!err);
+ }
+ err = FT_Render_Glyph(face->glyph, (antialiased ? ft_render_mode_normal
+ : ft_render_mode_mono));
+ if (err) {
+ qDebug("failed rendering glyph %d from font", i);
+ TQ_ASSERT(!err);
+ }
+
+ FT_Bitmap bm = face->glyph->bitmap;
+ x0 = face->glyph->metrics.horiBearingX >> 6;
+ y0 = (face->glyph->metrics.height - face->glyph->metrics.horiBearingY) >> 6;
+ dx = face->glyph->metrics.horiAdvance >> 6;
+ dy = 0;
+ int sz = bm.pitch * bm.rows;
+ uint *aa_glyph = 0;
+ uchar *ua_glyph = 0;
+
+ if (antialiased)
+ aa_glyph = new uint[sz];
+ else
+ ua_glyph = new uchar[sz];
+
+ // convert to GL format
+ for (int y = 0; y < bm.rows; ++y) {
+ for (int x = 0; x < bm.pitch; ++x) {
+ int c1 = y*bm.pitch + x;
+ int c2 = (bm.rows - y - 1) > 0 ? (bm.rows-y-1)*bm.pitch + x : x;
+ if (antialiased) {
+ aa_glyph[c1] = (int(color[0]*255) << 24)
+ | (int(color[1]*255) << 16)
+ | (int(color[2]*255) << 8) | bm.buffer[c2];
+ } else {
+ ua_glyph[c1] = bm.buffer[c2];
+ }
+ }
+ }
+
+ glNewList(list, GL_COMPILE);
+ if (antialiased) {
+ // calling glBitmap() is just a trick to move the current
+ // raster pos, since glGet*() won't work in display lists
+ glBitmap(0, 0, 0, 0, x0, -y0, 0);
+ glDrawPixels(bm.pitch, bm.rows, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, aa_glyph);
+ glBitmap(0, 0, 0, 0, dx-x0, y0, 0);
+ } else {
+ glBitmap(bm.pitch*8, bm.rows, -x0, y0, dx, dy, ua_glyph);
+ }
+ glEndList();
+ antialiased ? delete[] aa_glyph : delete[] ua_glyph;
+ }
+
+#ifdef TQT_XFT2
+ XftUnlockFace(engine->font());
+#endif
+
+ // restore pixel unpack settings
+ glPixelStorei(GL_UNPACK_SWAP_BYTES, gl_swapbytes);
+ glPixelStorei(GL_UNPACK_LSB_FIRST, gl_lsbfirst);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, gl_rowlength);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, gl_skiprows);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, gl_skippixels);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, gl_tqalignment);
+}
+#endif
+
+void TQGLContext::generateFontDisplayLists( const TQFont & fnt, int listBase )
+{
+ TQFont f(fnt);
+ TQFontEngine *engine = f.d->engineForScript(TQFont::Latin);
+
+#ifndef TQT_NO_XFTFREETYPE
+ if(engine->type() == TQFontEngine::Xft) {
+ qgl_use_font((TQFontEngineXft *) engine, 0, 256, listBase);
+ return;
+ }
+#endif
+ // glXUseXFont() only works with XLFD font structures and a few GL
+ // drivers crash if 0 is passed as the font handle
+ f.setStyleStrategy(TQFont::OpenGLCompatible);
+ if (f.handle() && (engine->type() == TQFontEngine::XLFD
+ || engine->type() == TQFontEngine::LatinXLFD)) {
+ glXUseXFont((Font) f.handle(), 0, 256, listBase);
+ }
+}
+
+#endif // USE_QT4
+
+/*****************************************************************************
+ TQGLOverlayWidget (Internal overlay class for X11)
+ *****************************************************************************/
+
+class TQGLOverlayWidget : public TQGLWidget
+{
+ TQ_OBJECT
+public:
+ TQGLOverlayWidget( const TQGLFormat& format, TQGLWidget* tqparent,
+ const char* name=0, const TQGLWidget* shareWidget=0 );
+
+protected:
+ void initializeGL();
+ void paintGL();
+ void resizeGL( int w, int h );
+
+private:
+ TQGLWidget* realWidget;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQGLOverlayWidget( const TQGLOverlayWidget& );
+ TQGLOverlayWidget& operator=( const TQGLOverlayWidget& );
+#endif
+};
+
+
+TQGLOverlayWidget::TQGLOverlayWidget( const TQGLFormat& format, TQGLWidget* tqparent,
+ const char* name,
+ const TQGLWidget* shareWidget )
+ : TQGLWidget( format, tqparent, name, shareWidget ? shareWidget->olw : 0 )
+{
+ realWidget = tqparent;
+}
+
+
+
+void TQGLOverlayWidget::initializeGL()
+{
+ TQColor transparentColor = context()->overlayTransparentColor();
+ if ( transparentColor.isValid() )
+ qglClearColor( transparentColor );
+ else
+ qWarning( "TQGLOverlayWidget::initializeGL(): Could not get transtqparent color" );
+ realWidget->initializeOverlayGL();
+}
+
+
+void TQGLOverlayWidget::resizeGL( int w, int h )
+{
+ glViewport( 0, 0, w, h );
+ realWidget->resizeOverlayGL( w, h );
+}
+
+
+void TQGLOverlayWidget::paintGL()
+{
+ realWidget->paintOverlayGL();
+}
+
+#undef Bool
+#include "tqgl_x11.tqmoc"
+
+/*****************************************************************************
+ TQGLWidget UNIX/GLX-specific code
+ *****************************************************************************/
+void TQGLWidget::init( TQGLContext *context, const TQGLWidget *shareWidget )
+{
+ qt_resolve_gl_symbols();
+
+ glcx = 0;
+ olw = 0;
+ autoSwap = TRUE;
+ if ( !context->tqdevice() )
+ context->setDevice( TQT_TQPAINTDEVICE(this) );
+
+ if ( shareWidget )
+ setContext( context, shareWidget->context() );
+ else
+ setContext( context );
+ setBackgroundMode( TQt::NoBackground );
+
+ if ( isValid() && context->format().hasOverlay() ) {
+ TQCString olwName( name() );
+ olwName += "-TQGL_internal_overlay_widget";
+ olw = new TQGLOverlayWidget( TQGLFormat::defaultOverlayFormat(),
+ this, olwName, shareWidget );
+ if ( olw->isValid() ) {
+ olw->setAutoBufferSwap( FALSE );
+ olw->setFocusProxy( this );
+ }
+ else {
+ delete olw;
+ olw = 0;
+ glcx->glFormat.setOverlay( FALSE );
+ }
+ }
+}
+
+/*! \reimp */
+void TQGLWidget::reparent( TQWidget* tqparent, WFlags f, const TQPoint& p,
+ bool showIt )
+{
+ if (glcx)
+ glcx->doneCurrent();
+ TQWidget::reparent( tqparent, f, p, FALSE );
+ if ( showIt )
+ show();
+}
+
+
+void TQGLWidget::setMouseTracking( bool enable )
+{
+ if ( olw )
+ olw->setMouseTracking( enable );
+ TQWidget::setMouseTracking( enable );
+}
+
+
+void TQGLWidget::resizeEvent( TQResizeEvent * )
+{
+ if ( !isValid() )
+ return;
+ makeCurrent();
+ if ( !glcx->initialized() )
+ glInit();
+ glXWaitX();
+ resizeGL( width(), height() );
+ if ( olw )
+ olw->setGeometry( rect() );
+}
+
+const TQGLContext* TQGLWidget::overlayContext() const
+{
+ if ( olw )
+ return olw->context();
+ else
+ return 0;
+}
+
+
+void TQGLWidget::makeOverlayCurrent()
+{
+ if ( olw )
+ olw->makeCurrent();
+}
+
+
+void TQGLWidget::updateOverlayGL()
+{
+ if ( olw )
+ olw->updateGL();
+}
+
+void TQGLWidget::setContext( TQGLContext *context,
+ const TQGLContext* shareContext,
+ bool deleteOldContext )
+{
+ if ( context == 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQGLWidget::setContext: Cannot set null context" );
+#endif
+ return;
+ }
+ if ( !context->tqdeviceIsPixmap() && context->tqdevice() != TQT_TQPAINTDEVICE(this) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQGLWidget::setContext: Context must refer to this widget" );
+#endif
+ return;
+ }
+
+ if ( glcx )
+ glcx->doneCurrent();
+ TQGLContext* oldcx = glcx;
+ glcx = context;
+
+ bool createFailed = FALSE;
+ if ( !glcx->isValid() ) {
+ if ( !glcx->create( shareContext ? shareContext : oldcx ) )
+ createFailed = TRUE;
+ }
+ if ( createFailed ) {
+ if ( deleteOldContext )
+ delete oldcx;
+ return;
+ }
+
+ if ( glcx->windowCreated() || glcx->tqdeviceIsPixmap() ) {
+ if ( deleteOldContext )
+ delete oldcx;
+ return;
+ }
+
+ bool visible = isVisible();
+ if ( visible )
+ hide();
+
+ XVisualInfo *vi = (XVisualInfo*)glcx->vi;
+ XSetWindowAttributes a;
+
+ a.colormap = choose_cmap( x11Display(), vi ); // tqfind best colormap
+ a.background_pixel = backgroundColor().pixel( vi->screen );
+ a.border_pixel = TQt::black.pixel( vi->screen );
+ Window p = RootWindow( x11Display(), vi->screen );
+ if ( parentWidget() )
+ p = parentWidget()->winId();
+
+ Window w = XCreateWindow( x11Display(), p, x(), y(), width(), height(),
+ 0, vi->depth, InputOutput, vi->visual,
+ CWBackPixel|CWBorderPixel|CWColormap, &a );
+
+ Window *cmw;
+ Window *cmwret;
+ int count;
+ if ( XGetWMColormapWindows( x11Display(), tqtopLevelWidget()->winId(),
+ &cmwret, &count ) ) {
+ cmw = new Window[count+1];
+ memcpy( (char *)cmw, (char *)cmwret, sizeof(Window)*count );
+ XFree( (char *)cmwret );
+ int i;
+ for ( i=0; i<count; i++ ) {
+ if ( cmw[i] == winId() ) { // tqreplace old window
+ cmw[i] = w;
+ break;
+ }
+ }
+ if ( i >= count ) // append new window
+ cmw[count++] = w;
+ } else {
+ count = 1;
+ cmw = new Window[count];
+ cmw[0] = w;
+ }
+
+#if defined(GLX_MESA_release_buffers) && defined(TQGL_USE_MESA_EXT)
+ if ( oldcx && oldcx->windowCreated() )
+ glXReleaseBuffersMESA( x11Display(), winId() );
+#endif
+ if ( deleteOldContext )
+ delete oldcx;
+ oldcx = 0;
+
+ create( w );
+
+ XSetWMColormapWindows( x11Display(), tqtopLevelWidget()->winId(), cmw,
+ count );
+ delete [] cmw;
+
+ if ( visible )
+ show();
+ XFlush( x11Display() );
+ glcx->setWindowCreated( TRUE );
+}
+
+
+bool TQGLWidget::renderCxPm( TQPixmap* pm )
+{
+ if ( ((XVisualInfo*)glcx->vi)->depth != pm->depth() )
+ return FALSE;
+
+ GLXPixmap glPm;
+#if defined(GLX_MESA_pixmap_colormap) && defined(TQGL_USE_MESA_EXT)
+ glPm = glXCreateGLXPixmapMESA( x11Display(),
+ (XVisualInfo*)glcx->vi,
+ (Pixmap)pm->handle(),
+ choose_cmap( pm->x11Display(),
+ (XVisualInfo*)glcx->vi ) );
+#else
+ glPm = (TQ_UINT32)glXCreateGLXPixmap( x11Display(),
+ (XVisualInfo*)glcx->vi,
+ (Pixmap)pm->handle() );
+#endif
+
+ if ( !glXMakeCurrent( x11Display(), glPm, (GLXContext)glcx->cx ) ) {
+ glXDestroyGLXPixmap( x11Display(), glPm );
+ return FALSE;
+ }
+
+ glDrawBuffer( GL_FRONT );
+ if ( !glcx->initialized() )
+ glInit();
+ resizeGL( pm->width(), pm->height() );
+ paintGL();
+ glFlush();
+ makeCurrent();
+ glXDestroyGLXPixmap( x11Display(), glPm );
+ resizeGL( width(), height() );
+ return TRUE;
+}
+
+const TQGLColormap & TQGLWidget::colormap() const
+{
+ return cmap;
+}
+
+/*\internal
+ Store color values in the given colormap.
+*/
+static void qStoreColors( TQWidget * tlw, Colormap cmap,
+ const TQGLColormap & cols )
+{
+ XColor c;
+ TQRgb color;
+
+ for ( int i = 0; i < cols.size(); i++ ) {
+ color = cols.entryRgb( i );
+ c.pixel = i;
+ c.red = (ushort)( (tqRed( color ) / 255.0) * 65535.0 + 0.5 );
+ c.green = (ushort)( (tqGreen( color ) / 255.0) * 65535.0 + 0.5 );
+ c.blue = (ushort)( (tqBlue( color ) / 255.0) * 65535.0 + 0.5 );
+ c.flags = DoRed | DoGreen | DoBlue;
+ XStoreColor( tlw->x11Display(), cmap, &c );
+ }
+}
+
+#ifdef USE_QT4
+/*\internal
+ Check whether the given visual supports dynamic colormaps or not.
+*/
+static bool qCanAllocColors( TQWidget * w )
+{
+ return false;
+}
+#else // USE_QT4
+/*\internal
+ Check whether the given visual supports dynamic colormaps or not.
+*/
+static bool qCanAllocColors( TQWidget * w )
+{
+ bool validVisual = FALSE;
+ int numVisuals;
+ long tqmask;
+ XVisualInfo templ;
+ XVisualInfo * visuals;
+ VisualID id = XVisualIDFromVisual( (Visual *)
+ w->tqtopLevelWidget()->x11Visual() );
+
+ tqmask = VisualScreenMask;
+ templ.screen = w->x11Screen();
+ visuals = XGetVisualInfo( w->x11Display(), tqmask, &templ, &numVisuals );
+
+ for ( int i = 0; i < numVisuals; i++ ) {
+ if ( visuals[i].visualid == id ) {
+ switch ( visuals[i].c_class ) {
+ case TrueColor:
+ case StaticColor:
+ case StaticGray:
+ case GrayScale:
+ validVisual = FALSE;
+ break;
+ case DirectColor:
+ case PseudoColor:
+ validVisual = TRUE;
+ break;
+ }
+ break;
+ }
+ }
+ XFree( visuals );
+
+ if ( !validVisual )
+ return FALSE;
+ return TRUE;
+}
+
+void TQGLWidget::setColormap( const TQGLColormap & c )
+{
+ TQWidget * tlw = tqtopLevelWidget(); // must return a valid widget
+
+ cmap = c;
+ if ( !cmap.d )
+ return;
+
+ if ( !cmap.d->cmapHandle && !qCanAllocColors( this ) ) {
+ qWarning( "TQGLWidget::setColormap: Cannot create a read/write "
+ "colormap for this visual" );
+ return;
+ }
+
+ // If the child GL widget is not of the same visual class as the
+ // toplevel widget we will get in trouble..
+ Window wid = tlw->winId();
+ Visual * vis = (Visual *) tlw->x11Visual();;
+ VisualID cvId = XVisualIDFromVisual( (Visual *) x11Visual() );
+ VisualID tvId = XVisualIDFromVisual( (Visual *) tlw->x11Visual() );
+ if ( cvId != tvId ) {
+ wid = winId();
+ vis = (Visual *) x11Visual();
+ }
+
+ if ( !cmap.d->cmapHandle ) // allocate a cmap if necessary
+ cmap.d->cmapHandle = XCreateColormap( x11Display(), wid, vis,
+ AllocAll );
+
+ qStoreColors( this, (Colormap) cmap.d->cmapHandle, c );
+ XSetWindowColormap( x11Display(), wid, (Colormap) cmap.d->cmapHandle );
+
+ // tell the wm that this window has a special colormap
+ Window * cmw;
+ Window * cmwret;
+ int count;
+ if ( XGetWMColormapWindows( x11Display(), tlw->winId(), &cmwret,
+ &count ) )
+ {
+ cmw = new Window[count+1];
+ memcpy( (char *) cmw, (char *) cmwret, sizeof(Window) * count );
+ XFree( (char *) cmwret );
+ int i;
+ for ( i = 0; i < count; i++ ) {
+ if ( cmw[i] == winId() ) {
+ break;
+ }
+ }
+ if ( i >= count ) // append new window only if not in the list
+ cmw[count++] = winId();
+ } else {
+ count = 1;
+ cmw = new Window[count];
+ cmw[0] = winId();
+ }
+ XSetWMColormapWindows( x11Display(), tlw->winId(), cmw, count );
+ delete [] cmw;
+}
+#endif // USE_QT4
+
+/*! \internal
+ Free up any allocated colormaps. This fn is only called for
+ top-level widgets.
+*/
+void TQGLWidget::cleanupColormaps()
+{
+ if ( !cmap.d )
+ return;
+
+ if ( cmap.d->cmapHandle ) {
+ XFreeColormap( tqtopLevelWidget()->x11Display(),
+ (Colormap) cmap.d->cmapHandle );
+ cmap.d->cmapHandle = 0;
+ }
+}
+
+void TQGLWidget::macInternalFixBufferRect()
+{
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/opengl/tqgl_x11_p.h b/tqtinterface/qt4/src/opengl/tqgl_x11_p.h
new file mode 100644
index 0000000..cb88352
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqgl_x11_p.h
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Definitions needed for resolving GL/GLX symbols using dlopen()
+** under X11.
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the OpenGL module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** Licensees holding valid TQt Commercial licenses may use this file in
+** accordance with the TQt Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGL_P_H
+#define TQGL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifdef TQT_DLOPEN_OPENGL
+// resolve the GL symbols we use ourselves
+bool qt_resolve_gl_symbols(bool = TRUE);
+extern "C" {
+// GL symbols
+typedef void (*_glCallLists)( GLsizei n, GLenum type, const GLvoid *lists );
+typedef void (*_glClearColor)( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha );
+typedef void (*_glClearIndex)( GLfloat c );
+typedef void (*_glColor3ub)( GLubyte red, GLubyte green, GLubyte blue );
+typedef void (*_glDeleteLists)( GLuint list, GLsizei range );
+typedef void (*_glDrawBuffer)( GLenum mode );
+typedef void (*_glFlush)( void );
+typedef void (*_glIndexi)( GLint c );
+typedef void (*_glListBase)( GLuint base );
+typedef void (*_glLoadIdentity)( void );
+typedef void (*_glMatrixMode)( GLenum mode );
+typedef void (*_glOrtho)( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val );
+typedef void (*_glPopAttrib)( void );
+typedef void (*_glPopMatrix)( void );
+typedef void (*_glPushAttrib)( GLbitfield tqmask );
+typedef void (*_glPushMatrix)( void );
+typedef void (*_glRasterPos2i)( GLint x, GLint y );
+typedef void (*_glRasterPos3d)( GLdouble x, GLdouble y, GLdouble z );
+typedef void (*_glReadPixels)( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels );
+typedef void (*_glViewport)( GLint x, GLint y, GLsizei width, GLsizei height );
+typedef void (*_glPixelStorei)( GLenum pname, GLint param );
+typedef void (*_glBitmap)( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove,
+ const GLubyte *bitmap );
+typedef void (*_glDrawPixels)( GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels );
+typedef void (*_glNewList)( GLuint list, GLenum mode );
+typedef void (*_glGetFloatv)( GLenum pname, GLfloat *params );
+typedef void (*_glGetIntegerv)( GLenum pname, GLint *params );
+typedef void (*_glEndList)( void );
+
+
+// GLX symbols - should be in the GL lib as well
+typedef XVisualInfo* (*_glXChooseVisual)(Display *dpy, int screen, int *attribList);
+typedef GLXContext (*_glXCreateContext)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct);
+typedef GLXPixmap (*_glXCreateGLXPixmap)(Display *dpy, XVisualInfo *vis, Pixmap pixmap);
+typedef void (*_glXDestroyContext)(Display *dpy, GLXContext ctx);
+typedef void (*_glXDestroyGLXPixmap)(Display *dpy, GLXPixmap pix);
+typedef const char* (*_glXGetClientString)(Display *dpy, int name );
+typedef int (*_glXGetConfig)(Display *dpy, XVisualInfo *vis, int attrib, int *value);
+typedef Bool (*_glXIsDirect)(Display *dpy, GLXContext ctx);
+typedef Bool (*_glXMakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
+typedef Bool (*_glXQueryExtension)(Display *dpy, int *errorBase, int *eventBase);
+typedef const char* (*_glXQueryExtensionsString)(Display *dpy, int screen);
+typedef const char* (*_glXQueryServerString)(Display *dpy, int screen, int name);
+typedef void (*_glXSwapBuffers)(Display *dpy, GLXDrawable drawable);
+typedef void (*_glXUseXFont)(Font font, int first, int count, int listBase);
+typedef void (*_glXWaitX)(void);
+
+extern _glCallLists qt_glCallLists;
+extern _glClearColor qt_glClearColor;
+extern _glClearIndex qt_glClearIndex;
+extern _glColor3ub qt_glColor3ub;
+extern _glDeleteLists qt_glDeleteLists;
+extern _glDrawBuffer qt_glDrawBuffer;
+extern _glFlush qt_glFlush;
+extern _glIndexi qt_glIndexi;
+extern _glListBase qt_glListBase;
+extern _glLoadIdentity qt_glLoadIdentity;
+extern _glMatrixMode qt_glMatrixMode;
+extern _glOrtho qt_glOrtho;
+extern _glPopAttrib qt_glPopAttrib;
+extern _glPopMatrix qt_glPopMatrix;
+extern _glPushAttrib qt_glPushAttrib;
+extern _glPushMatrix qt_glPushMatrix;
+extern _glRasterPos2i qt_glRasterPos2i;
+extern _glRasterPos3d qt_glRasterPos3d;
+extern _glReadPixels qt_glReadPixels;
+extern _glViewport qt_glViewport;
+extern _glPixelStorei qt_glPixelStorei;
+extern _glBitmap qt_glBitmap;
+extern _glDrawPixels qt_glDrawPixels;
+extern _glNewList qt_glNewList;
+extern _glGetFloatv qt_glGetFloatv;
+extern _glGetIntegerv qt_glGetIntegerv;
+extern _glEndList qt_glEndList;
+
+extern _glXChooseVisual qt_glXChooseVisual;
+extern _glXCreateContext qt_glXCreateContext;
+extern _glXCreateGLXPixmap qt_glXCreateGLXPixmap;
+extern _glXDestroyContext qt_glXDestroyContext;
+extern _glXDestroyGLXPixmap qt_glXDestroyGLXPixmap;
+extern _glXGetClientString qt_glXGetClientString;
+extern _glXGetConfig qt_glXGetConfig;
+extern _glXIsDirect qt_glXIsDirect;
+extern _glXMakeCurrent qt_glXMakeCurrent;
+extern _glXQueryExtension qt_glXQueryExtension;
+extern _glXQueryExtensionsString qt_glXQueryExtensionsString;
+extern _glXQueryServerString qt_glXQueryServerString;
+extern _glXSwapBuffers qt_glXSwapBuffers;
+extern _glXUseXFont qt_glXUseXFont;
+extern _glXWaitX qt_glXWaitX;
+}; // extern "C"
+
+#define glCallLists qt_glCallLists
+#define glClearColor qt_glClearColor
+#define glClearIndex qt_glClearIndex
+#define glColor3ub qt_glColor3ub
+#define glDeleteLists qt_glDeleteLists
+#define glDrawBuffer qt_glDrawBuffer
+#define glFlush qt_glFlush
+#define glIndexi qt_glIndexi
+#define glListBase qt_glListBase
+#define glLoadIdentity qt_glLoadIdentity
+#define glMatrixMode qt_glMatrixMode
+#define glOrtho qt_glOrtho
+#define glPopAttrib qt_glPopAttrib
+#define glPopMatrix qt_glPopMatrix
+#define glPushAttrib qt_glPushAttrib
+#define glPushMatrix qt_glPushMatrix
+#define glRasterPos2i qt_glRasterPos2i
+#define glRasterPos3d qt_glRasterPos3d
+#define glReadPixels qt_glReadPixels
+#define glViewport qt_glViewport
+#define glPixelStorei qt_glPixelStorei
+#define glBitmap qt_glBitmap
+#define glDrawPixels qt_glDrawPixels
+#define glNewList qt_glNewList
+#define glGetFloatv qt_glGetFloatv
+#define glGetIntegerv qt_glGetIntegerv
+#define glEndList qt_glEndList
+
+#define glXChooseVisual qt_glXChooseVisual
+#define glXCreateContext qt_glXCreateContext
+#define glXCreateGLXPixmap qt_glXCreateGLXPixmap
+#define glXDestroyContext qt_glXDestroyContext
+#define glXDestroyGLXPixmap qt_glXDestroyGLXPixmap
+#define glXGetClientString qt_glXGetClientString
+#define glXGetConfig qt_glXGetConfig
+#define glXIsDirect qt_glXIsDirect
+#define glXMakeCurrent qt_glXMakeCurrent
+#define glXQueryExtension qt_glXQueryExtension
+#define glXQueryExtensionsString qt_glXQueryExtensionsString
+#define glXQueryServerString qt_glXQueryServerString
+#define glXSwapBuffers qt_glXSwapBuffers
+#define glXUseXFont qt_glXUseXFont
+#define glXWaitX qt_glXWaitX
+
+#else
+inline bool qt_resolve_gl_symbols(bool = TRUE) { return TRUE; }
+#endif // TQT_DLOPEN_OPENGL
+#endif // TQGL_P_H
diff --git a/tqtinterface/qt4/src/opengl/tqglcolormap.cpp b/tqtinterface/qt4/src/opengl/tqglcolormap.cpp
new file mode 100644
index 0000000..6366e8b
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqglcolormap.cpp
@@ -0,0 +1,292 @@
+/****************************************************************************
+**
+** Implementation of TQGLColormap class
+**
+** Created : 20010326
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the opengl module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+/*!
+ \class TQGLColormap tqglcolormap.h
+ \brief The TQGLColormap class is used for installing custom colormaps into
+ TQGLWidgets.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module OpenGL
+ \ingroup graphics
+ \ingroup images
+
+ TQGLColormap provides a platform independent way of specifying and
+ installing indexed colormaps into TQGLWidgets. TQGLColormap is
+ especially useful when using the \link opengl.html OpenGL\endlink
+ color-index mode.
+
+ Under X11 you must use an X server that supports either a \c
+ PseudoColor or \c DirectColor visual class. If your X server
+ currently only provides a \c GrayScale, \c TrueColor, \c
+ StaticColor or \c StaticGray visual, you will not be able to
+ allocate colorcells for writing. If this is the case, try setting
+ your X server to 8 bit mode. It should then provide you with at
+ least a \c PseudoColor visual. Note that you may experience
+ colormap flashing if your X server is running in 8 bit mode.
+
+ Under Windows the size of the colormap is always set to 256
+ colors. Note that under Windows you can also install colormaps
+ in child widgets.
+
+ This class uses explicit sharing (see \link shclass.html Shared
+ Classes\endlink).
+
+ Example of use:
+ \code
+ #include <tqapplication.h>
+ #include <tqglcolormap.h>
+
+ int main()
+ {
+ TQApplication a( argc, argv );
+
+ MySuperGLWidget widget( 0 ); // A TQGLWidget in color-index mode
+ TQGLColormap colormap;
+
+ // This will fill the colormap with colors ranging from
+ // black to white.
+ for ( int i = 0; i < colormap.size(); i++ )
+ colormap.setEntry( i, tqRgb( i, i, i ) );
+
+ widget.setColormap( colormap );
+ widget.show();
+ return a.exec();
+ }
+ \endcode
+
+ \sa TQGLWidget::setColormap(), TQGLWidget::colormap()
+*/
+
+#include "tqglcolormap.h"
+#include "tqmemarray.h"
+
+
+/*!
+ Construct a TQGLColormap.
+*/
+TQGLColormap::TQGLColormap()
+{
+ d = 0;
+}
+
+
+/*!
+ Construct a shallow copy of \a map.
+*/
+TQGLColormap::TQGLColormap( const TQGLColormap & map )
+{
+ d = map.d;
+ if ( d )
+ d->ref();
+}
+
+/*!
+ Dereferences the TQGLColormap and deletes it if this was the last
+ reference to it.
+*/
+TQGLColormap::~TQGLColormap()
+{
+ if ( d && d->deref() ) {
+ delete d;
+ d = 0;
+ }
+}
+
+/*!
+ Assign a shallow copy of \a map to this TQGLColormap.
+*/
+TQGLColormap & TQGLColormap::operator=( const TQGLColormap & map )
+{
+ if ( map.d != 0 )
+ map.d->ref();
+
+ if ( d && d->deref() )
+ delete d;
+ d = map.d;
+
+ return *this;
+}
+
+/*!
+ Detaches this TQGLColormap from the shared block.
+*/
+void TQGLColormap::detach()
+{
+ if ( d && d->count != 1 ) {
+ // ### What about the actual colormap handle?
+ Private * newd = new Private();
+ newd->cells = d->cells;
+ newd->cells.detach();
+ if ( d->deref() )
+ delete d;
+ d = newd;
+ }
+}
+
+/*!
+ Set cell at index \a idx in the colormap to color \a color.
+*/
+void TQGLColormap::setEntry( int idx, TQRgb color )
+{
+ if ( !d )
+ d = new Private();
+
+#if defined(TQT_CHECK_RANGE)
+ if ( idx < 0 || idx > (int) d->cells.size() ) {
+ qWarning( "TQGLColormap::setRgb: Index out of range." );
+ return;
+ }
+#endif
+ d->cells[ idx ] = color;
+}
+
+/*!
+ Set an array of cells in this colormap. \a count is the number of
+ colors that should be set, \a colors is the array of colors, and
+ \a base is the starting index.
+*/
+void TQGLColormap::setEntries( int count, const TQRgb * colors, int base )
+{
+ if ( !d )
+ d = new Private();
+
+ if ( !colors || base < 0 || base >= (int) d->cells.size() )
+ return;
+
+ for( int i = base; i < base + count; i++ ) {
+ if ( i < (int) d->cells.size() )
+ setEntry( i, colors[i] );
+ else
+ break;
+ }
+}
+
+/*!
+ Returns the TQRgb value in the colorcell with index \a idx.
+*/
+TQRgb TQGLColormap::entryRgb( int idx ) const
+{
+ if ( !d || idx < 0 || idx > (int) d->cells.size() )
+ return 0;
+ else
+ return d->cells[ idx ];
+}
+
+/*!
+ \overload
+
+ Set the cell with index \a idx in the colormap to color \a color.
+*/
+void TQGLColormap::setEntry( int idx, const TQColor & color )
+{
+ setEntry( idx, color.rgb() );
+}
+
+/*!
+ Returns the TQRgb value in the colorcell with index \a idx.
+*/
+TQColor TQGLColormap::entryColor( int idx ) const
+{
+ if ( !d || idx < 0 || idx > (int) d->cells.size() )
+ return TQColor();
+ else
+ return TQColor( d->cells[ idx ] );
+}
+
+/*!
+ Returns TRUE if the colormap is empty; otherwise returns FALSE. A
+ colormap with no color values set is considered to be empty.
+*/
+bool TQGLColormap::isEmpty() const
+{
+ return (d == 0) || (d->cells.size() == 0) || (d->cmapHandle == 0);
+}
+
+
+/*!
+ Returns the number of colorcells in the colormap.
+*/
+int TQGLColormap::size() const
+{
+ return d != 0 ? d->cells.size() : 0;
+}
+
+/*!
+ Returns the index of the color \a color. If \a color is not in the
+ map, -1 is returned.
+*/
+int TQGLColormap::tqfind( TQRgb color ) const
+{
+ if ( d )
+ return d->cells.tqfind( color );
+ return -1;
+}
+
+/*!
+ Returns the index of the color that is the closest match to color
+ \a color.
+*/
+int TQGLColormap::tqfindNearest( TQRgb color ) const
+{
+ int idx = tqfind( color );
+ if ( idx >= 0 )
+ return idx;
+ int mapSize = size();
+ int mindist = 200000;
+ int r = tqRed( color );
+ int g = tqGreen( color );
+ int b = tqBlue( color );
+ int rx, gx, bx, dist;
+ for ( int i=0; i < mapSize; i++ ) {
+ TQRgb ci = d->cells[i];
+ rx = r - tqRed( ci );
+ gx = g - tqGreen( ci );
+ bx = b - tqBlue( ci );
+ dist = rx*rx + gx*gx + bx*bx; // calculate distance
+ if ( dist < mindist ) { // minimal?
+ mindist = dist;
+ idx = i;
+ }
+ }
+ return idx;
+}
diff --git a/tqtinterface/qt4/src/opengl/tqglcolormap.h b/tqtinterface/qt4/src/opengl/tqglcolormap.h
new file mode 100644
index 0000000..d6fec59
--- /dev/null
+++ b/tqtinterface/qt4/src/opengl/tqglcolormap.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Definition of TQGLColormap class
+**
+** Created : 20010326
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the opengl module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGLCOLORMAP_H
+#define TQGLCOLORMAP_H
+
+#ifndef TQT_H
+#include "tqcolor.h"
+#include "tqmemarray.h"
+#include "tqshared.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_OPENGL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_OPENGL
+#else
+#define TQM_EXPORT_OPENGL TQ_EXPORT
+#endif
+
+class TQWidget;
+class TQM_EXPORT_OPENGL TQGLColormap
+{
+public:
+ TQGLColormap();
+ TQGLColormap( const TQGLColormap & );
+ ~TQGLColormap();
+
+ TQGLColormap &operator=( const TQGLColormap & );
+
+ bool isEmpty() const;
+ int size() const;
+ void detach();
+
+ void setEntries( int count, const TQRgb * colors, int base = 0 );
+ void setEntry( int idx, TQRgb color );
+ void setEntry( int idx, const TQColor & color );
+ TQRgb entryRgb( int idx ) const;
+ TQColor entryColor( int idx ) const;
+ int tqfind( TQRgb color ) const;
+ int tqfindNearest( TQRgb color ) const;
+
+private:
+ class Private : public TQShared
+ {
+ public:
+ Private() {
+ cells.resize( 256 ); // ### hardcoded to 256 entries for now
+ cmapHandle = 0;
+ }
+
+ ~Private() {
+ }
+
+ TQMemArray<TQRgb> cells;
+ TQt::HANDLE cmapHandle;
+ };
+
+ Private * d;
+
+ friend class TQGLWidget;
+};
+
+#endif
diff --git a/tqtinterface/qt4/src/qt.pro b/tqtinterface/qt4/src/qt.pro
new file mode 100644
index 0000000..cfa6fc3
--- /dev/null
+++ b/tqtinterface/qt4/src/qt.pro
@@ -0,0 +1,195 @@
+# Qt project file
+TEMPLATE = lib
+TARGET = tqt
+embedded:TARGET = tqte
+VERSION = 3.3.8
+DESTDIR = $$QMAKE_LIBDIR_QT
+DLLDESTDIR = ../bin
+
+CONFIG += qt warn_on depend_includepath
+CONFIG += qmake_cache
+
+win32:!shared:CONFIG += staticlib
+
+win32-borland {
+ mng:QMAKE_CFLAGS_WARN_ON += -w-par
+ mng:TQMAKE_CXXFLAGS_WARN_ON += -w-par
+ # Keep the size of the .tds file for the Qt library smaller than
+ # 34 Mbytes to avoid linking problems
+ QMAKE_CFLAGS_DEBUG += -vi -y-
+ TQMAKE_CXXFLAGS_DEBUG += -vi -y-
+}
+
+linux-*:version_script {
+ QMAKE_LFLAGS += -Wl,--version-script=libtqt.map
+ TARGETDEPS += libtqt.map
+ TQMAKE_CXXFLAGS += -I /usr/include/qt4/
+}
+
+KERNEL_CPP = kernel
+CANVAS_CPP = canvas
+WIDGETS_CPP = widgets
+SQL_CPP = sql
+TABLE_CPP = table
+DIALOGS_CPP = dialogs
+ICONVIEW_CPP = iconview
+NETWORK_CPP = network
+OPENGL_CPP = opengl
+TOOLS_CPP = tools
+CODECS_CPP = codecs
+WORKSPACE_CPP = workspace
+XML_CPP = xml
+STYLES_CPP = styles
+EMBEDDED_CPP = embedded
+
+win32 {
+ tqcontains(TQT_PRODUCT,qt-internal) {
+ SQL_H = $$SQL_CPP
+ KERNEL_H = $$KERNEL_CPP
+ WIDGETS_H = $$WIDGETS_CPP
+ TABLE_H = $$TABLE_CPP
+ DIALOGS_H = $$DIALOGS_CPP
+ ICONVIEW_H = $$ICONVIEW_CPP
+ NETWORK_H = $$NETWORK_CPP
+ OPENGL_H = $$OPENGL_CPP
+ TOOLS_H = $$TOOLS_CPP
+ CODECS_H = $$CODECS_CPP
+ WORKSPACE_H = $$WORKSPACE_CPP
+ XML_H = $$XML_CPP
+ CANVAS_H = $$CANVAS_CPP
+ STYLES_H = $$STYLES_CPP
+ } else {
+ WIN_ALL_H = ../include
+ SQL_H = $$WIN_ALL_H
+ KERNEL_H = $$WIN_ALL_H
+ WIDGETS_H = $$WIN_ALL_H
+ TABLE_H = $$WIN_ALL_H
+ DIALOGS_H = $$WIN_ALL_H
+ ICONVIEW_H = $$WIN_ALL_H
+ NETWORK_H = $$WIN_ALL_H
+ OPENGL_H = $$WIN_ALL_H
+ TOOLS_H = $$WIN_ALL_H
+ CODECS_H = $$WIN_ALL_H
+ WORKSPACE_H = $$WIN_ALL_H
+ XML_H = $$WIN_ALL_H
+ CANVAS_H = $$WIN_ALL_H
+ STYLES_H = $$WIN_ALL_H
+ CONFIG -= incremental
+ }
+
+ CONFIG += zlib
+ INCLUDEPATH += tmp
+ !staticlib {
+ DEFINES+=TQT_MAKEDLL
+ exists(qt.rc):RC_FILE = qt.rc
+ }
+}
+win32-borland:INCLUDEPATH += kernel
+
+unix {
+ CANVAS_H = $$CANVAS_CPP
+ KERNEL_H = $$KERNEL_CPP
+ WIDGETS_H = $$WIDGETS_CPP
+ SQL_H = $$SQL_CPP
+ TABLE_H = $$TABLE_CPP
+ DIALOGS_H = $$DIALOGS_CPP
+ ICONVIEW_H = $$ICONVIEW_CPP
+ NETWORK_H = $$NETWORK_CPP
+ OPENGL_H = $$OPENGL_CPP
+ TOOLS_H = $$TOOLS_CPP
+ CODECS_H = $$CODECS_CPP
+ WORKSPACE_H = $$WORKSPACE_CPP
+ XML_H = $$XML_CPP
+ STYLES_H = $$STYLES_CPP
+ !embedded:!mac:CONFIG += x11 x11inc
+ TQMAKE_CXXFLAGS += -I /usr/include/qt4
+}
+
+aix-g++ {
+ QMAKE_CFLAGS += -mminimal-toc
+ TQMAKE_CXXFLAGS += -mminimal-toc
+}
+
+embedded {
+ EMBEDDED_H = $$EMBEDDED_CPP
+}
+
+DEPENDPATH += ;$$NETWORK_H;$$KERNEL_H;$$WIDGETS_H;$$SQL_H;$$TABLE_H;$$DIALOGS_H;
+DEPENDPATH += $$ICONVIEW_H;$$OPENGL_H;$$TOOLS_H;$$CODECS_H;$$WORKSPACE_H;$$XML_H;
+DEPENDPATH += $$CANVAS_H;$$STYLES_H
+embedded:DEPENDPATH += ;$$EMBEDDED_H
+
+thread {
+ !win32-borland:TARGET = tqt
+ win32-borland:TARGET = tqt
+ embedded:TARGET = tqte
+ DEFINES += TQT_THREAD_SUPPORT
+}
+
+!cups:DEFINES += TQT_NO_CUPS
+
+!nis:DEFINES += TQT_NO_NIS
+
+largefile {
+ unix:!darwin:DEFINES += _LARGEFILE_SOURCE _LARGE_FILES _FILE_OFFSET_BITS=64
+}
+
+#here for compatability, should go away ####
+include($$KERNEL_CPP/qt_compat.pri)
+
+#platforms
+x11:include($$KERNEL_CPP/qt_x11.pri)
+mac:include($$KERNEL_CPP/qt_mac.pri)
+win32:include($$KERNEL_CPP/qt_win.pri)
+embedded:include($$KERNEL_CPP/qt_qws.pri)
+
+#modules
+include($$KERNEL_CPP/qt_kernel.pri)
+include($$WIDGETS_CPP/qt_widgets.pri)
+include($$DIALOGS_CPP/qt_dialogs.pri)
+include($$ICONVIEW_CPP/qt_iconview.pri)
+include($$WORKSPACE_CPP/qt_workspace.pri)
+include($$NETWORK_CPP/qt_network.pri)
+include($$CANVAS_CPP/qt_canvas.pri)
+include($$TABLE_CPP/qt_table.pri)
+include($$XML_CPP/qt_xml.pri)
+include($$OPENGL_CPP/qt_opengl.pri)
+include($$SQL_CPP/qt_sql.pri)
+include($$KERNEL_CPP/qt_gfx.pri)
+include($$TOOLS_CPP/qt_tools.pri)
+include($$CODECS_CPP/qt_codecs.pri)
+include($$STYLES_CPP/qt_styles.pri)
+embedded:include($$EMBEDDED_CPP/qt_embedded.pri)
+
+# qconfig.cpp
+exists($$TQT_BUILD_TREE/src/tools/tqconfig.cpp) {
+ SOURCES += $$TQT_BUILD_TREE/src/tools/tqconfig.cpp
+}
+
+#install directives
+include(qt_install.pri)
+!staticlib:PRL_EXPORT_DEFINES += TQT_SHARED
+
+unix {
+ CONFIG += create_libtool create_pc
+ QMAKE_PKGCONFIG_LIBDIR = $$target.path
+ QMAKE_PKGCONFIG_INCDIR = $$headers.path
+}
+
+wince-* {
+ CONFIG -= incremental
+ message( ...removing plugin stuff... (not permanent) )
+ HEADERS -= $$TOOLS_CPP/tqcomlibrary.h \
+ $$KERNEL_CPP/tqgplugin.h \
+ $$KERNEL_CPP/tqimageformatplugin.h \
+ $$STYLES_CPP/tqstyleplugin.h \
+ $$CODECS_CPP/tqtextcodecplugin.h \
+ $$WIDGETS_CPP/tqwidgetplugin.h
+
+ SOURCES -= $$TOOLS_CPP/tqcomlibrary.cpp \
+ $$KERNEL_CPP/tqgplugin.cpp \
+ $$KERNEL_CPP/tqimageformatplugin.cpp \
+ $$STYLES_CPP/tqstyleplugin.cpp \
+ $$CODECS_CPP/tqtextcodecplugin.cpp \
+ $$WIDGETS_CPP/tqwidgetplugin.cpp
+}
diff --git a/tqtinterface/qt4/src/qt_install.pri b/tqtinterface/qt4/src/qt_install.pri
new file mode 100644
index 0000000..4702b1d
--- /dev/null
+++ b/tqtinterface/qt4/src/qt_install.pri
@@ -0,0 +1,33 @@
+#always install the library
+target.path=$$libs.path
+INSTALLS += target
+
+#headers
+headers.files = ../include/*.h
+headers.files += $$TQT_BUILD_TREE/include/tqconfig.h \
+ $$TQT_BUILD_TREE/include/tqmodules.h
+headers.files += ../include/private/t*.h
+isEmpty(headers_p.path):headers_p.path=$$headers.path/private
+headers_p.files = ../include/private/qt4_*.h
+headers_p.files += ../include/private/t*_p.h
+INSTALLS += headers headers_p
+
+#docs
+htmldocs.files = ../doc/html/*
+htmldocs.path = $$docs.path/html
+INSTALLS += htmldocs
+
+#translations
+translations.files = ../translations/*.qm
+INSTALLS += translations
+
+framework:macx { #mac framework
+ QtFramework = /Library/Frameworks/Qt.framework
+ QtDocs = /Developer/Documentation/Qt
+ framework.path = $$QtFramework/Headers/private $$QtDocs
+ framework.extra = -cp -rf $$htmldocs.files $(INSTALL_ROOT)/$$QtDocs;
+ framework.extra += cp -rf $$target.path/$(TARGET) $(INSTALL_ROOT)/$$QtFramework/Qt;
+ framework.extra += cp -rf $$headers.files $(INSTALL_ROOT)/$$QtFramework/Headers;
+ framework.extra += cp -rf $$headers_p.files $(INSTALL_ROOT)/$$QtFramework/Headers/private
+ INSTALLS += framework
+}
diff --git a/tqtinterface/qt4/src/qt_professional.pri b/tqtinterface/qt4/src/qt_professional.pri
new file mode 100644
index 0000000..f9179d0
--- /dev/null
+++ b/tqtinterface/qt4/src/qt_professional.pri
@@ -0,0 +1,96 @@
+!xml:tqcontains( DEFINES, TQT_INTERNAL_XML ) {
+ CONFIG += xml
+ XML_CPP = $$TQT_SOURCE_TREE/src/xml
+ win32 {
+ WIN_ALL_H = $$TQT_SOURCE_TREE/include
+ XML_H = $$WIN_ALL_H
+ }
+ unix {
+ XML_H = $$XML_CPP
+ #needed for svg
+ LIBS += -lm
+ }
+ INCLUDEPATH += $$TQT_SOURCE_TREE/src/xml
+ include( $$TQT_SOURCE_TREE/src/xml/qt_xml.pri )
+ DEFINES *= TQT_MODULE_XML
+}
+
+!network:tqcontains( DEFINES, TQT_INTERNAL_NETWORK) {
+ CONFIG += network
+ NETWORK_CPP = $$TQT_SOURCE_TREE/src/network
+ win32 {
+ WIN_ALL_H = $$TQT_SOURCE_TREE/include
+ NETWORK_H = $$WIN_ALL_H
+ }
+ unix {
+ NETWORK_H = $$NETWORK_CPP
+ }
+ mac:INCLUDEPATH += $$TQT_SOURCE_TREE/src/3rdparty/dlcompat
+ INCLUDEPATH += $$TQT_SOURCE_TREE/src/network
+ include( $$TQT_SOURCE_TREE/src/network/qt_network.pri )
+ DEFINES *= TQT_MODULE_NETWORK
+}
+
+!workspace:tqcontains( DEFINES, TQT_INTERNAL_WORKSPACE ) {
+ CONFIG += workspace
+ WORKSPACE_CPP = $$TQT_SOURCE_TREE/src/workspace
+ win32 {
+ WIN_ALL_H = $$TQT_SOURCE_TREE/include
+ WORKSPACE_H = $$WIN_ALL_H
+ }
+ unix {
+ WORKSPACE_H = $$WORKSPACE_CPP
+ }
+ INCLUDEPATH += $$TQT_SOURCE_TREE/src/workspace
+ include( $$TQT_SOURCE_TREE/src/workspace/qt_workspace.pri )
+ DEFINES *= TQT_MODULE_WORKSPACE
+}
+
+!iconview:tqcontains( DEFINES, TQT_INTERNAL_ICONVIEW ) {
+ CONFIG += iconview
+ ICONVIEW_CPP = $$TQT_SOURCE_TREE/src/iconview
+ win32 {
+ WIN_ALL_H = $$TQT_SOURCE_TREE/include
+ ICONVIEW_H = $$WIN_ALL_H
+ }
+ unix {
+ ICONVIEW_H = $$ICONVIEW_CPP
+ }
+ INCLUDEPATH += $$TQT_SOURCE_TREE/src/iconview
+ include( $$TQT_SOURCE_TREE/src/iconview/qt_iconview.pri )
+ DEFINES *= TQT_MODULE_ICONVIEW
+}
+
+!canvas:tqcontains( DEFINES, TQT_INTERNAL_CANVAS ) {
+ CONFIG += canvas
+ CANVAS_CPP = $$TQT_SOURCE_TREE/src/canvas
+ win32 {
+ WIN_ALL_H = $$TQT_SOURCE_TREE/include
+ CANVAS_H = $$WIN_ALL_H
+ }
+ unix {
+ CANVAS_H = $$CANVAS_CPP
+ }
+ INCLUDEPATH += $$TQT_SOURCE_TREE/src/canvas
+ include( $$TQT_SOURCE_TREE/src/canvas/qt_canvas.pri )
+ DEFINES *= TQT_MODULE_CANVAS
+}
+
+!table:tqcontains( DEFINES, TQT_INTERNAL_TABLE ) {
+ CONFIG += table
+ TABLE_CPP = $$TQT_SOURCE_TREE/src/table
+ win32 {
+ WIN_ALL_H = $$TQT_SOURCE_TREE/include
+ TABLE_H = $$WIN_ALL_H
+ }
+ unix {
+ TABLE_H = $$TABLE_CPP
+ }
+ INCLUDEPATH += $$TQT_SOURCE_TREE/src/table
+ include( $$TQT_SOURCE_TREE/src/table/qt_table.pri )
+ DEFINES *= TQT_MODULE_TABLE
+}
+
+tqcontains(TQT_PRODUCT,qt-professional) {
+ DEFINES *= TQT_LICENSE_PROFESSIONAL
+}
diff --git a/tqtinterface/qt4/src/qtmain.pro b/tqtinterface/qt4/src/qtmain.pro
new file mode 100644
index 0000000..6be946d
--- /dev/null
+++ b/tqtinterface/qt4/src/qtmain.pro
@@ -0,0 +1,18 @@
+# Additional Qt project file for tqtmain lib on Windows
+TEMPLATE = lib
+TARGET = tqtmain
+VERSION = 3.1.0
+DESTDIR = $$QMAKE_LIBDIR_QT
+
+CONFIG += qt staticlib warn_on release
+CONFIG -= dll
+
+win32 {
+ SOURCES = kernel/tqtmain_win.cpp
+ CONFIG += png zlib
+ CONFIG -= jpeg
+ INCLUDEPATH += tmp
+}
+win32-borland:INCLUDEPATH += kernel
+
+!win32-*:!wince-*:error("${QMAKE_FILE} is intended only for Windows!")
diff --git a/tqtinterface/qt4/src/sql/README.module b/tqtinterface/qt4/src/sql/README.module
new file mode 100644
index 0000000..511d90e
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/README.module
@@ -0,0 +1,37 @@
+Before building the Qt library, the Qt SQL module can be enabled for
+specific databases using 'configure'. 'configure' is located at the
+top of your QTDIR.
+
+Specific databases drivers can be enabled using one of the following
+options:
+
+ ./configure [-qt-sql-<driver>] [-plugin-sql-<driver>]
+
+or disabled using the following option:
+
+ ./configure [-no-sql-<driver>]
+
+Where <driver> is the name of the driver, for example 'psql'. This
+will configure the Qt library to compile the specified driver into
+the Qt lib itself.
+
+For example, to build the PostgreSQL driver directly into the Qt
+library, configure Qt like this:
+
+ ./configure -qt-sql-psql
+
+In addition, you may need to specify an extra include path, as some
+database drivers require headers for the database they are using,
+for example:
+
+ ./configure -qt-sql-psql -I/usr/local/include
+
+If instead you need to build the PostgreSQL driver as a dynamically
+loaded plugin, configure Qt like this:
+
+ ./configure -plugin-sql-psql
+
+To compile drivers as dynamically loaded plugins, see the
+QTDIR/plugins/src/sqldrivers directory. Use 'configure -help'
+for a complete list of configure options. See the Qt documentation
+for a complete list of supported database drivers.
diff --git a/tqtinterface/qt4/src/sql/drivers/cache/tqsqlcachedresult.cpp b/tqtinterface/qt4/src/sql/drivers/cache/tqsqlcachedresult.cpp
new file mode 100644
index 0000000..39195e9
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/cache/tqsqlcachedresult.cpp
@@ -0,0 +1,259 @@
+/****************************************************************************
+**
+** Implementation of cached TQt SQL result classes
+**
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlcachedresult.h"
+#include <tqdatetime.h>
+
+#ifndef TQT_NO_SQL
+static const uint initial_cache_size = 128;
+
+class TQtSqlCachedResultPrivate
+{
+public:
+ TQtSqlCachedResultPrivate();
+ bool seek(int i);
+ void init(int count, bool fo);
+ void cleanup();
+ TQtSqlCachedResult::RowCache* next();
+ void revertLast();
+
+ TQtSqlCachedResult::RowsetCache *cache;
+ TQtSqlCachedResult::RowCache *current;
+ int rowCacheEnd;
+ int colCount;
+ bool forwardOnly;
+};
+
+TQtSqlCachedResultPrivate::TQtSqlCachedResultPrivate():
+ cache(0), current(0), rowCacheEnd(0), colCount(0), forwardOnly(FALSE)
+{
+}
+
+void TQtSqlCachedResultPrivate::cleanup()
+{
+ if (cache) {
+ for (int i = 0; i < rowCacheEnd; ++i)
+ delete (*cache)[i];
+ delete cache;
+ cache = 0;
+ }
+ if (forwardOnly)
+ delete current;
+ current = 0;
+ forwardOnly = FALSE;
+ colCount = 0;
+ rowCacheEnd = 0;
+}
+
+void TQtSqlCachedResultPrivate::init(int count, bool fo)
+{
+ cleanup();
+ forwardOnly = fo;
+ colCount = count;
+ if (fo)
+ current = new TQtSqlCachedResult::RowCache(count);
+ else
+ cache = new TQtSqlCachedResult::RowsetCache(initial_cache_size);
+}
+
+TQtSqlCachedResult::RowCache *TQtSqlCachedResultPrivate::next()
+{
+ if (forwardOnly)
+ return current;
+
+ TQ_ASSERT(cache);
+ current = new TQtSqlCachedResult::RowCache(colCount);
+ if (rowCacheEnd == (int)cache->size())
+ cache->resize(cache->size() * 2);
+ cache->insert(rowCacheEnd++, current);
+ return current;
+}
+
+bool TQtSqlCachedResultPrivate::seek(int i)
+{
+ if (forwardOnly || i < 0)
+ return FALSE;
+ if (i >= rowCacheEnd)
+ return FALSE;
+ current = (*cache)[i];
+ return TRUE;
+}
+
+void TQtSqlCachedResultPrivate::revertLast()
+{
+ if (forwardOnly)
+ return;
+ --rowCacheEnd;
+ delete current;
+ current = 0;
+}
+
+//////////////
+
+TQtSqlCachedResult::TQtSqlCachedResult(const TQSqlDriver * db ): TQSqlResult ( db )
+{
+ d = new TQtSqlCachedResultPrivate();
+}
+
+TQtSqlCachedResult::~TQtSqlCachedResult()
+{
+ delete d;
+}
+
+void TQtSqlCachedResult::init(int colCount)
+{
+ d->init(colCount, isForwardOnly());
+}
+
+bool TQtSqlCachedResult::fetch(int i)
+{
+ if ((!isActive()) || (i < 0))
+ return FALSE;
+ if (at() == i)
+ return TRUE;
+ if (d->forwardOnly) {
+ // speed hack - do not copy values if not needed
+ if (at() > i || at() == TQSql::AfterLast)
+ return FALSE;
+ while(at() < i - 1) {
+ if (!gotoNext(0))
+ return FALSE;
+ setAt(at() + 1);
+ }
+ if (!gotoNext(d->current))
+ return FALSE;
+ setAt(at() + 1);
+ return TRUE;
+ }
+ if (d->seek(i)) {
+ setAt(i);
+ return TRUE;
+ }
+ setAt(d->rowCacheEnd - 1);
+ while (at() < i) {
+ if (!cacheNext())
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool TQtSqlCachedResult::fetchNext()
+{
+ if (d->seek(at() + 1)) {
+ setAt(at() + 1);
+ return TRUE;
+ }
+ return cacheNext();
+}
+
+bool TQtSqlCachedResult::fetchPrev()
+{
+ return fetch(at() - 1);
+}
+
+bool TQtSqlCachedResult::fetchFirst()
+{
+ if (d->forwardOnly && at() != TQSql::BeforeFirst) {
+ return FALSE;
+ }
+ if (d->seek(0)) {
+ setAt(0);
+ return TRUE;
+ }
+ return cacheNext();
+}
+
+bool TQtSqlCachedResult::fetchLast()
+{
+ if (at() == TQSql::AfterLast) {
+ if (d->forwardOnly)
+ return FALSE;
+ else
+ return fetch(d->rowCacheEnd - 1);
+ }
+
+ int i = at();
+ while (fetchNext())
+ i++; /* brute force */
+ if (d->forwardOnly && at() == TQSql::AfterLast) {
+ setAt(i);
+ return TRUE;
+ } else {
+ return fetch(d->rowCacheEnd - 1);
+ }
+}
+
+TQVariant TQtSqlCachedResult::data(int i)
+{
+ if (!d->current || i >= (int)d->current->size() || i < 0)
+ return TQVariant();
+
+ return (*d->current)[i];
+}
+
+bool TQtSqlCachedResult::isNull(int i)
+{
+ if (!d->current || i >= (int)d->current->size() || i < 0)
+ return TRUE;
+
+ return (*d->current)[i].isNull();
+}
+
+void TQtSqlCachedResult::cleanup()
+{
+ setAt(TQSql::BeforeFirst);
+ setActive(FALSE);
+ d->cleanup();
+}
+
+bool TQtSqlCachedResult::cacheNext()
+{
+ if (!gotoNext(d->next())) {
+ d->revertLast();
+ return FALSE;
+ }
+ setAt(at() + 1);
+ return TRUE;
+}
+
+int TQtSqlCachedResult::colCount() const
+{
+ return d->colCount;
+}
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/drivers/cache/tqsqlcachedresult.h b/tqtinterface/qt4/src/sql/drivers/cache/tqsqlcachedresult.h
new file mode 100644
index 0000000..c066770
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/cache/tqsqlcachedresult.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Definition of shared TQt SQL module classes
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLCACHEDRESULT_H
+#define TQSQLCACHEDRESULT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of other TQt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#include <tqglobal.h>
+#include <tqvariant.h>
+#include <tqptrvector.h>
+#include <tqvaluevector.h>
+#include <tqsqlresult.h>
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQtSqlCachedResultPrivate;
+
+class TQM_EXPORT_SQL TQtSqlCachedResult: public TQSqlResult
+{
+public:
+ virtual ~TQtSqlCachedResult();
+
+ typedef TQValueVector<TQVariant> RowCache;
+ typedef TQPtrVector<RowCache> RowsetCache;
+
+protected:
+ TQtSqlCachedResult(const TQSqlDriver * db);
+
+ void init(int colCount);
+ void cleanup();
+ bool cacheNext();
+
+ virtual bool gotoNext(RowCache* row) = 0;
+
+ TQVariant data(int i);
+ bool isNull(int i);
+ bool fetch(int i);
+ bool fetchNext();
+ bool fetchPrev();
+ bool fetchFirst();
+ bool fetchLast();
+
+ int colCount() const;
+
+private:
+ TQtSqlCachedResultPrivate *d;
+};
+
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/drivers/ibase/tqsql_ibase.cpp b/tqtinterface/qt4/src/sql/drivers/ibase/tqsql_ibase.cpp
new file mode 100644
index 0000000..955ecc4
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/ibase/tqsql_ibase.cpp
@@ -0,0 +1,1078 @@
+/****************************************************************************
+**
+** Implementation of Interbase driver classes.
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+** EDITIONS: FREE, ENTERPRISE
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "tqsql_ibase.h"
+
+#include <tqdatetime.h>
+#include <private/tqsqlextension_p.h>
+
+#include <ibase.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <math.h>
+
+#define TQIBASE_DRIVER_NAME "TQIBASE"
+
+class TQIBasePreparedExtension : public TQSqlExtension
+{
+public:
+ TQIBasePreparedExtension(TQIBaseResult *r)
+ : result(r) {}
+
+ bool prepare(const TQString &query)
+ {
+ return result->prepare(query);
+ }
+
+ bool exec()
+ {
+ return result->exec();
+ }
+
+ TQIBaseResult *result;
+};
+
+static bool getIBaseError(TQString& msg, ISC_STATUS* status, long &sqlcode)
+{
+ if (status[0] != 1 || status[1] <= 0)
+ return FALSE;
+
+ sqlcode = isc_sqlcode(status);
+ char buf[512];
+ isc_sql_interprete(sqlcode, buf, 512);
+ msg = TQString::fromUtf8(buf);
+ return TRUE;
+}
+
+static void createDA(XSTQLDA *&sqlda)
+{
+ sqlda = (XSTQLDA *) malloc(XSTQLDA_LENGTH(1));
+ sqlda->sqln = 1;
+ sqlda->sqld = 0;
+ sqlda->version = STQLDA_VERSION1;
+ sqlda->sqlvar[0].sqlind = 0;
+ sqlda->sqlvar[0].sqldata = 0;
+}
+
+static void enlargeDA(XSTQLDA *&sqlda, int n)
+{
+ free(sqlda);
+ sqlda = (XSTQLDA *) malloc(XSTQLDA_LENGTH(n));
+ sqlda->sqln = n;
+ sqlda->version = STQLDA_VERSION1;
+}
+
+static void initDA(XSTQLDA *sqlda)
+{
+ for (int i = 0; i < sqlda->sqld; ++i) {
+ switch (sqlda->sqlvar[i].sqltype & ~1) {
+ case STQL_INT64:
+ case STQL_LONG:
+ case STQL_SHORT:
+ case STQL_FLOAT:
+ case STQL_DOUBLE:
+ case STQL_TIMESTAMP:
+ case STQL_TYPE_TIME:
+ case STQL_TYPE_DATE:
+ case STQL_TEXT:
+ case STQL_BLOB:
+ sqlda->sqlvar[i].sqldata = (char*)malloc(sqlda->sqlvar[i].sqllen);
+ break;
+ case STQL_VARYING:
+ sqlda->sqlvar[i].sqldata = (char*)malloc(sqlda->sqlvar[i].sqllen + sizeof(short));
+ break;
+ default:
+ // not supported - do not bind.
+ sqlda->sqlvar[i].sqldata = 0;
+ break;
+ }
+ if (sqlda->sqlvar[i].sqltype & 1) {
+ sqlda->sqlvar[i].sqlind = (short*)malloc(sizeof(short));
+ *(sqlda->sqlvar[i].sqlind) = 0;
+ } else {
+ sqlda->sqlvar[i].sqlind = 0;
+ }
+ }
+}
+
+static void delDA(XSTQLDA *&sqlda)
+{
+ if (!sqlda)
+ return;
+ for (int i = 0; i < sqlda->sqld; ++i) {
+ free(sqlda->sqlvar[i].sqlind);
+ free(sqlda->sqlvar[i].sqldata);
+ }
+ free(sqlda);
+ sqlda = 0;
+}
+
+static TQVariant::Type qIBaseTypeName(int iType)
+{
+ switch (iType) {
+ case blr_varying:
+ case blr_varying2:
+ case blr_text:
+ case blr_cstring:
+ case blr_cstring2:
+ return TQVariant::String;
+ case blr_sql_time:
+ return TQVariant::Time;
+ case blr_sql_date:
+ return TQVariant::Date;
+ case blr_timestamp:
+ return TQVariant::DateTime;
+ case blr_blob:
+ return TQVariant::ByteArray;
+ case blr_quad:
+ case blr_short:
+ case blr_long:
+ return TQVariant::Int;
+ case blr_int64:
+ return TQVariant::LongLong;
+ case blr_float:
+ case blr_d_float:
+ case blr_double:
+ return TQVariant::Double;
+ }
+ return TQVariant::Invalid;
+}
+
+static TQVariant::Type qIBaseTypeName2(int iType)
+{
+ switch(iType & ~1) {
+ case STQL_VARYING:
+ case STQL_TEXT:
+ return TQVariant::String;
+ case STQL_LONG:
+ case STQL_SHORT:
+ return TQVariant::Int;
+ case STQL_INT64:
+ return TQVariant::LongLong;
+ case STQL_FLOAT:
+ case STQL_DOUBLE:
+ return TQVariant::Double;
+ case STQL_TIMESTAMP:
+ return TQVariant::DateTime;
+ case STQL_TYPE_DATE:
+ return TQVariant::Date;
+ case STQL_TYPE_TIME:
+ return TQVariant::Time;
+ default:
+ return TQVariant::Invalid;
+ }
+}
+
+static ISC_TIME toTime(const TQTime &t)
+{
+ static const TQTime midnight(0, 0, 0, 0);
+ return (ISC_TIME)midnight.msecsTo(t) * 10;
+}
+
+static ISC_DATE toDate(const TQDate &d)
+{
+ static const TQDate basedate(1858, 11, 17);
+ return (ISC_DATE)basedate.daysTo(d);
+}
+
+static ISC_TIMESTAMP toTimeStamp(const TQDateTime &dt)
+{
+ ISC_TIMESTAMP ts;
+ ts.timestamp_time = toTime(dt.time());
+ ts.timestamp_date = toDate(dt.date());
+ return ts;
+}
+
+static TQTime toTQTime(ISC_TIME time)
+{
+ // have to demangle the structure ourselves because isc_decode_time
+ // strips the msecs
+ static const TQTime t;
+ return t.addMSecs(time / 10);
+}
+
+static TQDate toTQDate(ISC_DATE d)
+{
+ static const TQDate bd(1858, 11, 17);
+ return bd.addDays(d);
+}
+
+static TQDateTime toTQDateTime(ISC_TIMESTAMP *ts)
+{
+ return TQDateTime(toTQDate(ts->timestamp_date), toTQTime(ts->timestamp_time));
+}
+
+class TQIBaseDriverPrivate
+{
+public:
+ TQIBaseDriverPrivate(TQIBaseDriver *d): q(d)
+ {
+ ibase = 0;
+ trans = 0;
+ }
+
+ bool isError(const TQString &msg = TQString::null, TQSqlError::Type typ = TQSqlError::Unknown)
+ {
+ TQString imsg;
+ long sqlcode;
+ if (!getIBaseError(imsg, status, sqlcode))
+ return FALSE;
+
+ q->setLastError(TQSqlError(msg, imsg, typ, (int)sqlcode));
+ return TRUE;
+ }
+
+public:
+ TQIBaseDriver* q;
+ isc_db_handle ibase;
+ isc_tr_handle trans;
+ ISC_STATUS status[20];
+};
+
+class TQIBaseResultPrivate
+{
+public:
+ TQIBaseResultPrivate(TQIBaseResult *d, const TQIBaseDriver *ddb);
+ ~TQIBaseResultPrivate() { cleanup(); }
+
+ void cleanup();
+ bool isError(const TQString &msg = TQString::null, TQSqlError::Type typ = TQSqlError::Unknown)
+ {
+ TQString imsg;
+ long sqlcode;
+ if (!getIBaseError(imsg, status, sqlcode))
+ return FALSE;
+
+ q->setLastError(TQSqlError(msg, imsg, typ, (int)sqlcode));
+ return TRUE;
+ }
+
+ bool transaction();
+ bool commit();
+
+ bool isSelect();
+ TQVariant fetchBlob(ISC_TQUAD *bId);
+ void writeBlob(int i, const TQByteArray &ba);
+
+public:
+ TQIBaseResult *q;
+ const TQIBaseDriver *db;
+ ISC_STATUS status[20];
+ isc_tr_handle trans;
+ //indicator whether we have a local transaction or a transaction on driver level
+ bool localTransaction;
+ isc_stmt_handle stmt;
+ isc_db_handle ibase;
+ XSTQLDA *sqlda; // output sqlda
+ XSTQLDA *inda; // input parameters
+ int queryType;
+};
+
+TQIBaseResultPrivate::TQIBaseResultPrivate(TQIBaseResult *d, const TQIBaseDriver *ddb):
+ q(d), db(ddb), trans(0), stmt(0), ibase(ddb->d->ibase), sqlda(0), inda(0), queryType(-1)
+{
+ localTransaction = (ddb->d->ibase == 0);
+}
+
+void TQIBaseResultPrivate::cleanup()
+{
+ if (stmt) {
+ isc_dsql_free_statement(status, &stmt, DSTQL_drop);
+ stmt = 0;
+ }
+
+ commit();
+ if (!localTransaction)
+ trans = 0;
+
+ delDA(sqlda);
+ delDA(inda);
+
+ queryType = -1;
+ q->cleanup();
+}
+
+void TQIBaseResultPrivate::writeBlob(int i, const TQByteArray &ba)
+{
+ isc_blob_handle handle = 0;
+ ISC_TQUAD *bId = (ISC_TQUAD*)inda->sqlvar[i].sqldata;
+ isc_create_blob2(status, &ibase, &trans, &handle, bId, 0, 0);
+ if (!isError("Unable to create BLOB", TQSqlError::Statement)) {
+ uint i = 0;
+ while (i < ba.size()) {
+ isc_put_segment(status, &handle, TQMIN(ba.size() - i, SHRT_MAX), ba.data());
+ if (isError("Unable to write BLOB"))
+ break;
+ i += SHRT_MAX;
+ }
+ }
+ isc_close_blob(status, &handle);
+}
+
+TQVariant TQIBaseResultPrivate::fetchBlob(ISC_TQUAD *bId)
+{
+ isc_blob_handle handle = 0;
+
+ isc_open_blob2(status, &ibase, &trans, &handle, bId, 0, 0);
+ if (isError("Unable to open BLOB", TQSqlError::Statement))
+ return TQVariant();
+
+ unsigned short len = 0;
+ TQByteArray ba(255);
+ ISC_STATUS stat = isc_get_segment(status, &handle, &len, ba.size(), ba.data());
+ while (status[1] == isc_segment) {
+ uint osize = ba.size();
+ // double the amount of data fetched on each iteration
+ ba.resize(TQMIN(ba.size() * 2, SHRT_MAX));
+ stat = isc_get_segment(status, &handle, &len, osize, ba.data() + osize);
+ }
+ bool isErr = isError("Unable to read BLOB", TQSqlError::Statement);
+ isc_close_blob(status, &handle);
+ if (isErr)
+ return TQVariant();
+
+ if (ba.size() > 255)
+ ba.resize(ba.size() / 2 + len);
+ else
+ ba.resize(len);
+
+ return ba;
+}
+
+bool TQIBaseResultPrivate::isSelect()
+{
+ char acBuffer[9];
+ char qType = isc_info_sql_stmt_type;
+ isc_dsql_sql_info(status, &stmt, 1, &qType, sizeof(acBuffer), acBuffer);
+ if (isError("Could not get query info", TQSqlError::Statement))
+ return FALSE;
+ int iLength = isc_vax_integer(&acBuffer[1], 2);
+ queryType = isc_vax_integer(&acBuffer[3], iLength);
+ return (queryType == isc_info_sql_stmt_select);
+}
+
+bool TQIBaseResultPrivate::transaction()
+{
+ if (trans)
+ return TRUE;
+ if (db->d->trans) {
+ localTransaction = FALSE;
+ trans = db->d->trans;
+ return TRUE;
+ }
+ localTransaction = TRUE;
+
+ isc_start_transaction(status, &trans, 1, &ibase, 0, NULL);
+ if (isError("Could not start transaction", TQSqlError::Statement))
+ return FALSE;
+
+ return TRUE;
+}
+
+// does nothing if the transaction is on the
+// driver level
+bool TQIBaseResultPrivate::commit()
+{
+ if (!trans)
+ return FALSE;
+ // don't commit driver's transaction, the driver will do it for us
+ if (!localTransaction)
+ return TRUE;
+
+ isc_commit_transaction(status, &trans);
+ trans = 0;
+ return !isError("Unable to commit transaction", TQSqlError::Statement);
+}
+
+//////////
+
+TQIBaseResult::TQIBaseResult(const TQIBaseDriver* db):
+ TQtSqlCachedResult(db)
+{
+ d = new TQIBaseResultPrivate(this, db);
+ setExtension(new TQIBasePreparedExtension(this));
+}
+
+TQIBaseResult::~TQIBaseResult()
+{
+ delete d;
+}
+
+bool TQIBaseResult::prepare(const TQString& query)
+{
+ //qDebug("prepare: %s", query.ascii());
+ if (!driver() || !driver()->isOpen() || driver()->isOpenError())
+ return FALSE;
+ d->cleanup();
+ setActive(FALSE);
+ setAt(TQSql::BeforeFirst);
+
+ createDA(d->sqlda);
+ createDA(d->inda);
+
+ if (!d->transaction())
+ return FALSE;
+
+ isc_dsql_allocate_statement(d->status, &d->ibase, &d->stmt);
+ if (d->isError("Could not allocate statement", TQSqlError::Statement))
+ return FALSE;
+ isc_dsql_prepare(d->status, &d->trans, &d->stmt, 0, query.utf8().data(), 3, d->sqlda);
+ if (d->isError("Could not prepare statement", TQSqlError::Statement))
+ return FALSE;
+
+ isc_dsql_describe_bind(d->status, &d->stmt, 1, d->inda);
+ if (d->isError("Could not describe input statement", TQSqlError::Statement))
+ return FALSE;
+ if (d->inda->sqld > d->inda->sqln) {
+ enlargeDA(d->inda, d->inda->sqld);
+
+ isc_dsql_describe_bind(d->status, &d->stmt, 1, d->inda);
+ if (d->isError("Could not describe input statement", TQSqlError::Statement))
+ return FALSE;
+ }
+ initDA(d->inda);
+ if (d->sqlda->sqld > d->sqlda->sqln) {
+ // need more field descriptors
+ enlargeDA(d->sqlda, d->sqlda->sqld);
+
+ isc_dsql_describe(d->status, &d->stmt, 1, d->sqlda);
+ if (d->isError("Could not describe statement", TQSqlError::Statement))
+ return FALSE;
+ }
+ initDA(d->sqlda);
+
+ setSelect(d->isSelect());
+ if (!isSelect()) {
+ free(d->sqlda);
+ d->sqlda = 0;
+ }
+
+ return TRUE;
+}
+
+bool TQIBaseResult::exec()
+{
+ if (!driver() || !driver()->isOpen() || driver()->isOpenError())
+ return FALSE;
+ setActive(FALSE);
+ setAt(TQSql::BeforeFirst);
+
+ if (d->inda && extension()->index.count() > 0) {
+ TQMap<int, TQString>::ConstIterator it;
+ if ((int)extension()->index.count() > d->inda->sqld) {
+ qWarning("TQIBaseResult::exec: Parameter mismatch, expected %d, got %d parameters", d->inda->sqld, extension()->index.count());
+ return FALSE;
+ }
+ int para = 0;
+ for (it = extension()->index.constBegin(); it != extension()->index.constEnd(); ++it, ++para) {
+ if (para >= d->inda->sqld)
+ break;
+ if (!d->inda->sqlvar[para].sqldata)
+ continue;
+ const TQVariant val(extension()->values[it.data()].value);
+ if (d->inda->sqlvar[para].sqltype & 1) {
+ if (val.isNull()) {
+ // set null indicator
+ *(d->inda->sqlvar[para].sqlind) = 1;
+ // and set the value to 0, otherwise it would count as empty string.
+ *((short*)d->inda->sqlvar[para].sqldata) = 0;
+ continue;
+ }
+ // a value of 0 means non-null.
+ *(d->inda->sqlvar[para].sqlind) = 0;
+ }
+ switch(d->inda->sqlvar[para].sqltype & ~1) {
+ case STQL_INT64:
+ if (d->inda->sqlvar[para].sqlscale < 0)
+ *((TQ_LLONG*)d->inda->sqlvar[para].sqldata) = TQ_LLONG(val.toDouble() *
+ pow(10.0, d->inda->sqlvar[para].sqlscale * -1));
+ else
+ *((TQ_LLONG*)d->inda->sqlvar[para].sqldata) = val.toLongLong();
+ break;
+ case STQL_LONG:
+ *((long*)d->inda->sqlvar[para].sqldata) = (long)val.toLongLong();
+ break;
+ case STQL_SHORT:
+ *((short*)d->inda->sqlvar[para].sqldata) = (short)val.toInt();
+ break;
+ case STQL_FLOAT:
+ *((float*)d->inda->sqlvar[para].sqldata) = (float)val.toDouble();
+ break;
+ case STQL_DOUBLE:
+ *((double*)d->inda->sqlvar[para].sqldata) = val.toDouble();
+ break;
+ case STQL_TIMESTAMP:
+ *((ISC_TIMESTAMP*)d->inda->sqlvar[para].sqldata) = toTimeStamp(val.toDateTime());
+ break;
+ case STQL_TYPE_TIME:
+ *((ISC_TIME*)d->inda->sqlvar[para].sqldata) = toTime(val.toTime());
+ break;
+ case STQL_TYPE_DATE:
+ *((ISC_DATE*)d->inda->sqlvar[para].sqldata) = toDate(val.toDate());
+ break;
+ case STQL_VARYING: {
+ TQCString str(val.toString().utf8()); // keep a copy of the string alive in this scope
+ short buflen = d->inda->sqlvar[para].sqllen;
+ if (str.length() < (uint)buflen)
+ buflen = str.length();
+ *(short*)d->inda->sqlvar[para].sqldata = buflen; // first two bytes is the length
+ memcpy(d->inda->sqlvar[para].sqldata + sizeof(short), str.data(), buflen);
+ break; }
+ case STQL_TEXT: {
+ TQCString str(val.toString().utf8().leftJustify(d->inda->sqlvar[para].sqllen, ' ', TRUE));
+ memcpy(d->inda->sqlvar[para].sqldata, str.data(), d->inda->sqlvar[para].sqllen);
+ break; }
+ case STQL_BLOB:
+ d->writeBlob(para, val.toByteArray());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ if (colCount()) {
+ isc_dsql_free_statement(d->status, &d->stmt, DSTQL_close);
+ if (d->isError("Unable to close statement"))
+ return FALSE;
+ cleanup();
+ }
+ if (d->sqlda)
+ init(d->sqlda->sqld);
+ isc_dsql_execute2(d->status, &d->trans, &d->stmt, 1, d->inda, 0);
+ if (d->isError("Unable to execute query"))
+ return FALSE;
+
+ setActive(TRUE);
+ return TRUE;
+}
+
+bool TQIBaseResult::reset (const TQString& query)
+{
+// qDebug("reset: %s", query.ascii());
+ if (!driver() || !driver()->isOpen() || driver()->isOpenError())
+ return FALSE;
+ d->cleanup();
+ setActive(FALSE);
+ setAt(TQSql::BeforeFirst);
+
+ createDA(d->sqlda);
+
+ if (!d->transaction())
+ return FALSE;
+
+ isc_dsql_allocate_statement(d->status, &d->ibase, &d->stmt);
+ if (d->isError("Could not allocate statement", TQSqlError::Statement))
+ return FALSE;
+ isc_dsql_prepare(d->status, &d->trans, &d->stmt, 0, query.utf8().data(), 3, d->sqlda);
+ if (d->isError("Could not prepare statement", TQSqlError::Statement))
+ return FALSE;
+
+ if (d->sqlda->sqld > d->sqlda->sqln) {
+ // need more field descriptors
+ int n = d->sqlda->sqld;
+ free(d->sqlda);
+ d->sqlda = (XSTQLDA *) malloc(XSTQLDA_LENGTH(n));
+ d->sqlda->sqln = n;
+ d->sqlda->version = STQLDA_VERSION1;
+
+ isc_dsql_describe(d->status, &d->stmt, 1, d->sqlda);
+ if (d->isError("Could not describe statement", TQSqlError::Statement))
+ return FALSE;
+ }
+
+ initDA(d->sqlda);
+
+ setSelect(d->isSelect());
+ if (isSelect()) {
+ init(d->sqlda->sqld);
+ } else {
+ free(d->sqlda);
+ d->sqlda = 0;
+ }
+
+ isc_dsql_execute(d->status, &d->trans, &d->stmt, 1, 0);
+ if (d->isError("Unable to execute query"))
+ return FALSE;
+
+ // commit non-select queries (if they are local)
+ if (!isSelect() && !d->commit())
+ return FALSE;
+
+ setActive(TRUE);
+ return TRUE;
+}
+
+bool TQIBaseResult::gotoNext(TQtSqlCachedResult::RowCache* row)
+{
+ ISC_STATUS stat = isc_dsql_fetch(d->status, &d->stmt, 1, d->sqlda);
+
+ if (stat == 100) {
+ // no more rows
+ setAt(TQSql::AfterLast);
+ return FALSE;
+ }
+ if (d->isError("Could not fetch next item", TQSqlError::Statement))
+ return FALSE;
+ if (!row) // not interested in actual values
+ return TRUE;
+
+ TQ_ASSERT(row);
+ TQ_ASSERT((int)row->size() == d->sqlda->sqld);
+ for (int i = 0; i < d->sqlda->sqld; ++i) {
+ char *buf = d->sqlda->sqlvar[i].sqldata;
+ int size = d->sqlda->sqlvar[i].sqllen;
+ TQ_ASSERT(buf);
+
+ if ((d->sqlda->sqlvar[i].sqltype & 1) && *d->sqlda->sqlvar[i].sqlind) {
+ // null value
+ TQVariant v;
+ v.cast(qIBaseTypeName2(d->sqlda->sqlvar[i].sqltype));
+ (*row)[i] = v;
+ continue;
+ }
+
+ switch(d->sqlda->sqlvar[i].sqltype & ~1) {
+ case STQL_VARYING:
+ // pascal strings - a short with a length information followed by the data
+ (*row)[i] = TQString::fromUtf8(buf + sizeof(short), *(short*)buf);
+ break;
+ case STQL_INT64:
+ if (d->sqlda->sqlvar[i].sqlscale < 0)
+ (*row)[i] = *(TQ_LLONG*)buf * pow(10.0, d->sqlda->sqlvar[i].sqlscale);
+ else
+ (*row)[i] = TQVariant(*(TQ_LLONG*)buf);
+ break;
+ case STQL_LONG:
+ if (sizeof(int) == sizeof(long)) //dear compiler: please optimize me out.
+ (*row)[i] = TQVariant((int)(*(long*)buf));
+ else
+ (*row)[i] = TQVariant((TQ_LLONG)(*(long*)buf));
+ break;
+ case STQL_SHORT:
+ (*row)[i] = TQVariant((int)(*(short*)buf));
+ break;
+ case STQL_FLOAT:
+ (*row)[i] = TQVariant((double)(*(float*)buf));
+ break;
+ case STQL_DOUBLE:
+ (*row)[i] = TQVariant(*(double*)buf);
+ break;
+ case STQL_TIMESTAMP:
+ (*row)[i] = toTQDateTime((ISC_TIMESTAMP*)buf);
+ break;
+ case STQL_TYPE_TIME:
+ (*row)[i] = toTQTime(*(ISC_TIME*)buf);
+ break;
+ case STQL_TYPE_DATE:
+ (*row)[i] = toTQDate(*(ISC_DATE*)buf);
+ break;
+ case STQL_TEXT:
+ (*row)[i] = TQString::fromUtf8(buf, size);
+ break;
+ case STQL_BLOB:
+ (*row)[i] = d->fetchBlob((ISC_TQUAD*)buf);
+ break;
+ default:
+ // unknown type - don't even try to fetch
+ (*row)[i] = TQVariant();
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+int TQIBaseResult::size()
+{
+ static char sizeInfo[] = {isc_info_sql_records};
+ char buf[33];
+
+ if (!isActive() || !isSelect())
+ return -1;
+
+ isc_dsql_sql_info(d->status, &d->stmt, sizeof(sizeInfo), sizeInfo, sizeof(buf), buf);
+ for (char* c = buf + 3; *c != isc_info_end; /*nothing*/) {
+ char ct = *c++;
+ short len = isc_vax_integer(c, 2);
+ c += 2;
+ int val = isc_vax_integer(c, len);
+ c += len;
+ if (ct == isc_info_req_select_count)
+ return val;
+ }
+ return -1;
+}
+
+int TQIBaseResult::numRowsAffected()
+{
+ static char acCountInfo[] = {isc_info_sql_records};
+ char cCountType;
+
+ switch (d->queryType) {
+ case isc_info_sql_stmt_select:
+ cCountType = isc_info_req_select_count;
+ break;
+ case isc_info_sql_stmt_update:
+ cCountType = isc_info_req_update_count;
+ break;
+ case isc_info_sql_stmt_delete:
+ cCountType = isc_info_req_delete_count;
+ break;
+ case isc_info_sql_stmt_insert:
+ cCountType = isc_info_req_insert_count;
+ break;
+ }
+
+ char acBuffer[33];
+ int iResult = -1;
+ isc_dsql_sql_info(d->status, &d->stmt, sizeof(acCountInfo), acCountInfo, sizeof(acBuffer), acBuffer);
+ if (d->isError("Could not get statement info", TQSqlError::Statement))
+ return -1;
+ for (char *pcBuf = acBuffer + 3; *pcBuf != isc_info_end; /*nothing*/) {
+ char cType = *pcBuf++;
+ short sLength = isc_vax_integer (pcBuf, 2);
+ pcBuf += 2;
+ int iValue = isc_vax_integer (pcBuf, sLength);
+ pcBuf += sLength;
+
+ if (cType == cCountType) {
+ iResult = iValue;
+ break;
+ }
+ }
+ return iResult;
+}
+
+/*********************************/
+
+TQIBaseDriver::TQIBaseDriver(TQObject * tqparent, const char * name)
+ : TQSqlDriver(tqparent, name ? name : TQIBASE_DRIVER_NAME)
+{
+ d = new TQIBaseDriverPrivate(this);
+}
+
+TQIBaseDriver::TQIBaseDriver(void *connection, TQObject *tqparent, const char *name)
+ : TQSqlDriver(tqparent, name ? name : TQIBASE_DRIVER_NAME)
+{
+ d = new TQIBaseDriverPrivate(this);
+ d->ibase = (isc_db_handle)connection;
+ setOpen(TRUE);
+ setOpenError(FALSE);
+}
+
+TQIBaseDriver::~TQIBaseDriver()
+{
+ delete d;
+}
+
+bool TQIBaseDriver::hasFeature(DriverFeature f) const
+{
+ switch (f) {
+ case Transactions:
+// case QuerySize:
+ case PreparedQueries:
+ case PositionalPlaceholders:
+ case Unicode:
+ case BLOB:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+bool TQIBaseDriver::open(const TQString & db,
+ const TQString & user,
+ const TQString & password,
+ const TQString & host,
+ int /*port*/,
+ const TQString & /* connOpts */)
+{
+ if (isOpen())
+ close();
+
+ static const char enc[8] = "UTF_FSS";
+ TQCString usr = user.local8Bit();
+ TQCString pass = password.local8Bit();
+ usr.truncate(255);
+ pass.truncate(255);
+
+ TQByteArray ba(usr.length() + pass.length() + sizeof(enc) + 6);
+ int i = -1;
+ ba[++i] = isc_dpb_version1;
+ ba[++i] = isc_dpb_user_name;
+ ba[++i] = usr.length();
+ memcpy(&ba[++i], usr.data(), usr.length());
+ i += usr.length();
+ ba[i] = isc_dpb_password;
+ ba[++i] = pass.length();
+ memcpy(&ba[++i], pass.data(), pass.length());
+ i += pass.length();
+ ba[i] = isc_dpb_lc_ctype;
+ ba[++i] = sizeof(enc) - 1;
+ memcpy(&ba[++i], enc, sizeof(enc) - 1);
+ i += sizeof(enc) - 1;
+
+ TQString ldb;
+ if (!host.isEmpty())
+ ldb += host + ":";
+ ldb += db;
+ isc_attach_database(d->status, 0, (char*)ldb.latin1(), &d->ibase, i, ba.data());
+ if (d->isError("Error opening database", TQSqlError::Connection)) {
+ setOpenError(TRUE);
+ return FALSE;
+ }
+
+ setOpen(TRUE);
+ return TRUE;
+}
+
+void TQIBaseDriver::close()
+{
+ if (isOpen()) {
+ isc_detach_database(d->status, &d->ibase);
+ d->ibase = 0;
+ setOpen(FALSE);
+ setOpenError(FALSE);
+ }
+}
+
+TQSqlQuery TQIBaseDriver::createQuery() const
+{
+ return TQSqlQuery(new TQIBaseResult(this));
+}
+
+bool TQIBaseDriver::beginTransaction()
+{
+ if (!isOpen() || isOpenError())
+ return FALSE;
+ if (d->trans)
+ return FALSE;
+
+ isc_start_transaction(d->status, &d->trans, 1, &d->ibase, 0, NULL);
+ return !d->isError("Could not start transaction", TQSqlError::Transaction);
+}
+
+bool TQIBaseDriver::commitTransaction()
+{
+ if (!isOpen() || isOpenError())
+ return FALSE;
+ if (!d->trans)
+ return FALSE;
+
+ isc_commit_transaction(d->status, &d->trans);
+ d->trans = 0;
+ return !d->isError("Unable to commit transaction", TQSqlError::Transaction);
+}
+
+bool TQIBaseDriver::rollbackTransaction()
+{
+ if (!isOpen() || isOpenError())
+ return FALSE;
+ if (!d->trans)
+ return FALSE;
+
+ isc_rollback_transaction(d->status, &d->trans);
+ d->trans = 0;
+ return !d->isError("Unable to rollback transaction", TQSqlError::Transaction);
+}
+
+TQStringList TQIBaseDriver::tables(const TQString& typeName) const
+{
+ TQStringList res;
+ if (!isOpen())
+ return res;
+
+ int type = typeName.isEmpty() ? (int)TQSql::Tables | (int)TQSql::Views : typeName.toInt();
+ TQString typeFilter;
+
+ if (type == (int)TQSql::SystemTables) {
+ typeFilter += "RDB$SYSTEM_FLAG != 0";
+ } else if (type == ((int)TQSql::SystemTables | (int)TQSql::Views)) {
+ typeFilter += "RDB$SYSTEM_FLAG != 0 OR RDB$VIEW_BLR NOT NULL";
+ } else {
+ if (!(type & (int)TQSql::SystemTables))
+ typeFilter += "RDB$SYSTEM_FLAG = 0 AND ";
+ if (!(type & (int)TQSql::Views))
+ typeFilter += "RDB$VIEW_BLR IS NULL AND ";
+ if (!(type & (int)TQSql::Tables))
+ typeFilter += "RDB$VIEW_BLR IS NOT NULL AND ";
+ if (!typeFilter.isEmpty())
+ typeFilter.truncate(typeFilter.length() - 5);
+ }
+ if (!typeFilter.isEmpty())
+ typeFilter.prepend("where ");
+
+ TQSqlQuery q = createQuery();
+ q.setForwardOnly(TRUE);
+ if (!q.exec("select rdb$relation_name from rdb$relations " + typeFilter))
+ return res;
+ while(q.next())
+ res << q.value(0).toString().stripWhiteSpace();
+
+ return res;
+}
+
+TQSqlRecord TQIBaseDriver::record(const TQString& tablename) const
+{
+ TQSqlRecord rec;
+ if (!isOpen())
+ return rec;
+
+ TQSqlQuery q = createQuery();
+ q.setForwardOnly(TRUE);
+
+ q.exec("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE "
+ "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b "
+ "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE "
+ "AND a.RDB$RELATION_NAME = '" + tablename.upper()+ "' "
+ "ORDER BY RDB$FIELD_POSITION");
+ while (q.next()) {
+ TQSqlField field(q.value(0).toString().stripWhiteSpace(), qIBaseTypeName(q.value(1).toInt()));
+ rec.append(field);
+ }
+
+ return rec;
+}
+
+TQSqlRecordInfo TQIBaseDriver::recordInfo(const TQString& tablename) const
+{
+ TQSqlRecordInfo rec;
+ if (!isOpen())
+ return rec;
+
+ TQSqlQuery q = createQuery();
+ q.setForwardOnly(TRUE);
+
+ q.exec("SELECT a.RDB$FIELD_NAME, b.RDB$FIELD_TYPE, b.RDB$FIELD_LENGTH, b.RDB$FIELD_SCALE, "
+ "b.RDB$FIELD_PRECISION, a.RDB$NULL_FLAG "
+ "FROM RDB$RELATION_FIELDS a, RDB$FIELDS b "
+ "WHERE b.RDB$FIELD_NAME = a.RDB$FIELD_SOURCE "
+ "AND a.RDB$RELATION_NAME = '" + tablename.upper() + "' "
+ "ORDER BY a.RDB$FIELD_POSITION");
+
+ while (q.next()) {
+ TQVariant::Type type = qIBaseTypeName(q.value(1).toInt());
+ TQSqlFieldInfo field(q.value(0).toString().stripWhiteSpace(), type, q.value(5).toInt(),
+ q.value(2).toInt(), q.value(4).toInt(), TQVariant());
+
+ rec.append(field);
+ }
+
+ return rec;
+}
+
+TQSqlIndex TQIBaseDriver::primaryIndex(const TQString &table) const
+{
+ TQSqlIndex index(table);
+ if (!isOpen())
+ return index;
+
+ TQSqlQuery q = createQuery();
+ q.setForwardOnly(TRUE);
+ q.exec("SELECT a.RDB$INDEX_NAME, b.RDB$FIELD_NAME, d.RDB$FIELD_TYPE "
+ "FROM RDB$RELATION_CONSTRAINTS a, RDB$INDEX_SEGMENTS b, RDB$RELATION_FIELDS c, RDB$FIELDS d "
+ "WHERE a.RDB$CONSTRAINT_TYPE = 'PRIMARY KEY' "
+ "AND a.RDB$RELATION_NAME = '" + table.upper() + "' "
+ "AND a.RDB$INDEX_NAME = b.RDB$INDEX_NAME "
+ "AND c.RDB$RELATION_NAME = a.RDB$RELATION_NAME "
+ "AND c.RDB$FIELD_NAME = b.RDB$FIELD_NAME "
+ "AND d.RDB$FIELD_NAME = c.RDB$FIELD_SOURCE "
+ "ORDER BY b.RDB$FIELD_POSITION");
+
+ while (q.next()) {
+ TQSqlField field(q.value(1).toString().stripWhiteSpace(), qIBaseTypeName(q.value(2).toInt()));
+ index.append(field); //TODO: asc? desc?
+ index.setName(q.value(0).toString());
+ }
+
+ return index;
+}
+
+TQSqlRecord TQIBaseDriver::record(const TQSqlQuery& query) const
+{
+ TQSqlRecord rec;
+ if (query.isActive() && query.driver() == this) {
+ TQIBaseResult* result = (TQIBaseResult*)query.result();
+ if (!result->d->sqlda)
+ return rec;
+ XSTQLVAR v;
+ for (int i = 0; i < result->d->sqlda->sqld; ++i) {
+ v = result->d->sqlda->sqlvar[i];
+ TQSqlField f(TQString::tqfromLatin1(v.sqlname, v.sqlname_length).stripWhiteSpace(),
+ qIBaseTypeName2(result->d->sqlda->sqlvar[i].sqltype));
+ rec.append(f);
+ }
+ }
+ return rec;
+}
+
+TQSqlRecordInfo TQIBaseDriver::recordInfo(const TQSqlQuery& query) const
+{
+ TQSqlRecordInfo rec;
+ if (query.isActive() && query.driver() == this) {
+ TQIBaseResult* result = (TQIBaseResult*)query.result();
+ if (!result->d->sqlda)
+ return rec;
+ XSTQLVAR v;
+ for (int i = 0; i < result->d->sqlda->sqld; ++i) {
+ v = result->d->sqlda->sqlvar[i];
+ TQSqlFieldInfo f(TQString::tqfromLatin1(v.sqlname, v.sqlname_length).stripWhiteSpace(),
+ qIBaseTypeName2(result->d->sqlda->sqlvar[i].sqltype),
+ -1, v.sqllen, TQABS(v.sqlscale), TQVariant(), v.sqltype);
+ rec.append(f);
+ }
+ }
+ return rec;
+}
+
+TQString TQIBaseDriver::formatValue(const TQSqlField* field, bool trimStrings) const
+{
+ switch (field->type()) {
+ case TQVariant::DateTime: {
+ TQDateTime datetime = field->value().toDateTime();
+ if (datetime.isValid())
+ return "'" + TQString::number(datetime.date().year()) + "-" +
+ TQString::number(datetime.date().month()) + "-" +
+ TQString::number(datetime.date().day()) + " " +
+ TQString::number(datetime.time().hour()) + ":" +
+ TQString::number(datetime.time().minute()) + ":" +
+ TQString::number(datetime.time().second()) + "." +
+ TQString::number(datetime.time().msec()).rightJustify(3, '0', TRUE) + "'";
+ else
+ return "NULL";
+ }
+ case TQVariant::Time: {
+ TQTime time = field->value().toTime();
+ if (time.isValid())
+ return "'" + TQString::number(time.hour()) + ":" +
+ TQString::number(time.minute()) + ":" +
+ TQString::number(time.second()) + "." +
+ TQString::number(time.msec()).rightJustify(3, '0', TRUE) + "'";
+ else
+ return "NULL";
+ }
+ case TQVariant::Date: {
+ TQDate date = field->value().toDate();
+ if (date.isValid())
+ return "'" + TQString::number(date.year()) + "-" +
+ TQString::number(date.month()) + "-" +
+ TQString::number(date.day()) + "'";
+ else
+ return "NULL";
+ }
+ default:
+ return TQSqlDriver::formatValue(field, trimStrings);
+ }
+}
diff --git a/tqtinterface/qt4/src/sql/drivers/ibase/tqsql_ibase.h b/tqtinterface/qt4/src/sql/drivers/ibase/tqsql_ibase.h
new file mode 100644
index 0000000..be5bfd5
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/ibase/tqsql_ibase.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Definition of Interbase driver classes
+**
+** Created : 030911
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQL_IBASE_H
+#define TQSQL_IBASE_H
+
+#include "tqsqlresult.h"
+#include "tqsqldriver.h"
+#include "../cache/tqsqlcachedresult.h"
+
+
+class TQIBaseDriverPrivate;
+class TQIBaseResultPrivate;
+class TQIBaseDriver;
+
+class TQIBaseResult : public TQtSqlCachedResult
+{
+ friend class TQIBaseDriver;
+ friend class TQIBaseResultPrivate;
+
+public:
+ TQIBaseResult(const TQIBaseDriver* db);
+ virtual ~TQIBaseResult();
+
+ bool prepare(const TQString& query);
+ bool exec();
+
+protected:
+ bool gotoNext(TQtSqlCachedResult::RowCache* row);
+ bool reset (const TQString& query);
+ int size();
+ int numRowsAffected();
+
+private:
+ TQIBaseResultPrivate* d;
+};
+
+class TQIBaseDriver : public TQSqlDriver
+{
+ friend class TQIBaseDriverPrivate;
+ friend class TQIBaseResultPrivate;
+ friend class TQIBaseResult;
+public:
+ TQIBaseDriver(TQObject *tqparent = 0, const char *name = 0);
+ TQIBaseDriver(void *connection, TQObject *tqparent = 0, const char *name = 0);
+ virtual ~TQIBaseDriver();
+ bool hasFeature(DriverFeature f) const;
+ bool open(const TQString & db,
+ const TQString & user,
+ const TQString & password,
+ const TQString & host,
+ int port,
+ const TQString & connOpts);
+ bool open( const TQString & db,
+ const TQString & user,
+ const TQString & password,
+ const TQString & host,
+ int port ) { return open (db, user, password, host, port, TQString()); }
+ void close();
+ TQSqlQuery createQuery() const;
+ bool beginTransaction();
+ bool commitTransaction();
+ bool rollbackTransaction();
+ TQStringList tables(const TQString& typeName) const;
+
+ TQSqlRecord record(const TQString& tablename) const;
+ TQSqlRecordInfo recordInfo(const TQString& tablename) const;
+ TQSqlIndex primaryIndex(const TQString &table) const;
+ TQSqlRecord record(const TQSqlQuery& query) const;
+ TQSqlRecordInfo recordInfo(const TQSqlQuery& query) const;
+
+ TQString formatValue(const TQSqlField* field, bool trimStrings) const;
+
+private:
+ TQIBaseDriverPrivate* d;
+};
+
+
+#endif
+
diff --git a/tqtinterface/qt4/src/sql/drivers/mysql/tqsql_mysql.cpp b/tqtinterface/qt4/src/sql/drivers/mysql/tqsql_mysql.cpp
new file mode 100644
index 0000000..f97cd2e
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/mysql/tqsql_mysql.cpp
@@ -0,0 +1,775 @@
+/****************************************************************************
+**
+** Implementation of MYSQL driver classes
+**
+** Created : 001103
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsql_mysql.h"
+#include <private/tqsqlextension_p.h>
+
+#include <tqdatetime.h>
+#include <tqvaluevector.h>
+#include <tqsqlrecord.h>
+
+#define TQMYSTQL_DRIVER_NAME "TQMYSQL3"
+
+#ifdef TQ_OS_WIN32
+// comment the next line out if you want to use MySQL/embedded on Win32 systems.
+// note that it will crash if you don't statically link to the mysql/e library!
+# define TQ_NO_MYSTQL_EMBEDDED
+#endif
+
+TQPtrDict<TQSqlOpenExtension> *qSqlOpenExtDict();
+
+static int qMySqlConnectionCount = 0;
+static bool qMySqlInitHandledByUser = FALSE;
+
+class TQMYSTQLOpenExtension : public TQSqlOpenExtension
+{
+public:
+ TQMYSTQLOpenExtension( TQMYSTQLDriver *dri )
+ : TQSqlOpenExtension(), driver(dri) {}
+ ~TQMYSTQLOpenExtension() {}
+
+ bool open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts );
+
+private:
+ TQMYSTQLDriver *driver;
+};
+
+bool TQMYSTQLOpenExtension::open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts )
+{
+ return driver->open( db, user, password, host, port, connOpts );
+}
+
+class TQMYSTQLDriverPrivate
+{
+public:
+ TQMYSTQLDriverPrivate() : mysql(0) {}
+ MYSQL* mysql;
+};
+
+class TQMYSTQLResultPrivate : public TQMYSTQLDriverPrivate
+{
+public:
+ TQMYSTQLResultPrivate() : TQMYSTQLDriverPrivate(), result(0) {}
+ MYSTQL_RES* result;
+ MYSTQL_ROW row;
+ TQValueVector<TQVariant::Type> fieldTypes;
+};
+
+TQSqlError qMakeError( const TQString& err, int type, const TQMYSTQLDriverPrivate* p )
+{
+ return TQSqlError(TQMYSTQL_DRIVER_NAME ": " + err, TQString(mysql_error( p->mysql )), type, mysql_errno( p->mysql ));
+}
+
+TQVariant::Type qDecodeMYSTQLType( int mysqltype, uint flags )
+{
+ TQVariant::Type type;
+ switch ( mysqltype ) {
+ case FIELD_TYPE_TINY :
+ case FIELD_TYPE_SHORT :
+ case FIELD_TYPE_LONG :
+ case FIELD_TYPE_INT24 :
+ type = (flags & UNSIGNED_FLAG) ? TQVariant::UInt : TQVariant::Int;
+ break;
+ case FIELD_TYPE_YEAR :
+ type = TQVariant::Int;
+ break;
+ case FIELD_TYPE_LONGLONG :
+ type = (flags & UNSIGNED_FLAG) ? TQVariant::ULongLong : TQVariant::LongLong;
+ break;
+ case FIELD_TYPE_DECIMAL :
+ case FIELD_TYPE_FLOAT :
+ case FIELD_TYPE_DOUBLE :
+ type = TQVariant::Double;
+ break;
+ case FIELD_TYPE_DATE :
+ type = TQVariant::Date;
+ break;
+ case FIELD_TYPE_TIME :
+ type = TQVariant::Time;
+ break;
+ case FIELD_TYPE_DATETIME :
+ case FIELD_TYPE_TIMESTAMP :
+ type = TQVariant::DateTime;
+ break;
+ case FIELD_TYPE_BLOB :
+ case FIELD_TYPE_TINY_BLOB :
+ case FIELD_TYPE_MEDIUM_BLOB :
+ case FIELD_TYPE_LONG_BLOB :
+ type = (flags & BINARY_FLAG) ? TQVariant::ByteArray : TQVariant::CString;
+ break;
+ default:
+ case FIELD_TYPE_ENUM :
+ case FIELD_TYPE_SET :
+ case FIELD_TYPE_STRING :
+ case FIELD_TYPE_VAR_STRING :
+ type = TQVariant::String;
+ break;
+ }
+ return type;
+}
+
+TQMYSTQLResult::TQMYSTQLResult( const TQMYSTQLDriver* db )
+: TQSqlResult( db )
+{
+ d = new TQMYSTQLResultPrivate();
+ d->mysql = db->d->mysql;
+}
+
+TQMYSTQLResult::~TQMYSTQLResult()
+{
+ cleanup();
+ delete d;
+}
+
+MYSTQL_RES* TQMYSTQLResult::result()
+{
+ return d->result;
+}
+
+void TQMYSTQLResult::cleanup()
+{
+ if ( d->result ) {
+ mysql_free_result( d->result );
+ }
+ d->result = NULL;
+ d->row = NULL;
+ setAt( -1 );
+ setActive( FALSE );
+}
+
+bool TQMYSTQLResult::fetch( int i )
+{
+ if ( isForwardOnly() ) { // fake a forward seek
+ if ( at() < i ) {
+ int x = i - at();
+ while ( --x && fetchNext() );
+ return fetchNext();
+ } else {
+ return FALSE;
+ }
+ }
+ if ( at() == i )
+ return TRUE;
+ mysql_data_seek( d->result, i );
+ d->row = mysql_fetch_row( d->result );
+ if ( !d->row )
+ return FALSE;
+ setAt( i );
+ return TRUE;
+}
+
+bool TQMYSTQLResult::fetchNext()
+{
+ d->row = mysql_fetch_row( d->result );
+ if ( !d->row )
+ return FALSE;
+ setAt( at() + 1 );
+ return TRUE;
+}
+
+bool TQMYSTQLResult::fetchLast()
+{
+ if ( isForwardOnly() ) { // fake this since MySQL can't seek on forward only queries
+ bool success = fetchNext(); // did we move at all?
+ while ( fetchNext() );
+ return success;
+ }
+ my_ulonglong numRows = mysql_num_rows( d->result );
+ if ( !numRows )
+ return FALSE;
+ return fetch( numRows - 1 );
+}
+
+bool TQMYSTQLResult::fetchFirst()
+{
+ if ( isForwardOnly() ) // again, fake it
+ return fetchNext();
+ return fetch( 0 );
+}
+
+TQVariant TQMYSTQLResult::data( int field )
+{
+ if ( !isSelect() || field >= (int) d->fieldTypes.count() ) {
+ qWarning( "TQMYSTQLResult::data: column %d out of range", field );
+ return TQVariant();
+ }
+
+ TQString val( d->row[field] );
+ switch ( d->fieldTypes.at( field ) ) {
+ case TQVariant::LongLong:
+ return TQVariant( val.toLongLong() );
+ case TQVariant::ULongLong:
+ return TQVariant( val.toULongLong() );
+ case TQVariant::Int:
+ return TQVariant( val.toInt() );
+ case TQVariant::UInt:
+ return TQVariant( val.toUInt() );
+ case TQVariant::Double:
+ return TQVariant( val.toDouble() );
+ case TQVariant::Date:
+ if ( val.isEmpty() ) {
+ return TQVariant( TQDate() );
+ } else {
+ return TQVariant( TQDate::fromString( val, TQt::ISODate ) );
+ }
+ case TQVariant::Time:
+ if ( val.isEmpty() ) {
+ return TQVariant( TQTime() );
+ } else {
+ return TQVariant( TQTime::fromString( val, TQt::ISODate ) );
+ }
+ case TQVariant::DateTime:
+ if ( val.isEmpty() )
+ return TQVariant( TQDateTime() );
+ if ( val.length() == 14u )
+ // TIMESTAMPS have the format yyyyMMddhhmmss
+ val.insert(4, "-").insert(7, "-").insert(10, 'T').insert(13, ':').insert(16, ':');
+ return TQVariant( TQDateTime::fromString( val, TQt::ISODate ) );
+ case TQVariant::ByteArray: {
+ unsigned long* fl = mysql_fetch_lengths( d->result );
+ TQByteArray ba;
+ ba.duplicate( d->row[field], fl[field] );
+ return TQVariant( ba );
+ }
+ default:
+ case TQVariant::String:
+ case TQVariant::CString:
+ return TQVariant( val );
+ }
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQMYSTQLResult::data: unknown data type");
+#endif
+ return TQVariant();
+}
+
+bool TQMYSTQLResult::isNull( int field )
+{
+ if ( d->row[field] == NULL )
+ return TRUE;
+ return FALSE;
+}
+
+bool TQMYSTQLResult::reset ( const TQString& query )
+{
+ if ( !driver() )
+ return FALSE;
+ if ( !driver()-> isOpen() || driver()->isOpenError() )
+ return FALSE;
+ cleanup();
+
+ const char *encQuery = query.ascii();
+ if ( mysql_real_query( d->mysql, encQuery, tqstrlen(encQuery) ) ) {
+ setLastError( qMakeError("Unable to execute query", TQSqlError::Statement, d ) );
+ return FALSE;
+ }
+ if ( isForwardOnly() ) {
+ if ( isActive() || isValid() ) // have to empty the results from previous query
+ fetchLast();
+ d->result = mysql_use_result( d->mysql );
+ } else {
+ d->result = mysql_store_result( d->mysql );
+ }
+ if ( !d->result && mysql_field_count( d->mysql ) > 0 ) {
+ setLastError( qMakeError( "Unable to store result", TQSqlError::Statement, d ) );
+ return FALSE;
+ }
+ int numFields = mysql_field_count( d->mysql );
+ setSelect( !( numFields == 0) );
+ d->fieldTypes.resize( numFields );
+ if ( isSelect() ) {
+ for( int i = 0; i < numFields; i++) {
+ MYSTQL_FIELD* field = mysql_fetch_field_direct( d->result, i );
+ if ( field->type == FIELD_TYPE_DECIMAL )
+ d->fieldTypes[i] = TQVariant::String;
+ else
+ d->fieldTypes[i] = qDecodeMYSTQLType( field->type, field->flags );
+ }
+ }
+ setActive( TRUE );
+ return TRUE;
+}
+
+int TQMYSTQLResult::size()
+{
+ return isSelect() ? (int)mysql_num_rows( d->result ) : -1;
+}
+
+int TQMYSTQLResult::numRowsAffected()
+{
+ return (int)mysql_affected_rows( d->mysql );
+}
+
+/////////////////////////////////////////////////////////
+static void qServerEnd()
+{
+#ifndef TQ_NO_MYSTQL_EMBEDDED
+# if MYSTQL_VERSION_ID >= 40000
+ mysql_server_end();
+# endif // MYSTQL_VERSION_ID
+#endif // TQ_NO_MYSTQL_EMBEDDED
+}
+
+static void qServerInit()
+{
+#ifndef TQ_NO_MYSTQL_EMBEDDED
+# if MYSTQL_VERSION_ID >= 40000
+ if ( qMySqlInitHandledByUser || qMySqlConnectionCount > 1 )
+ return;
+
+ // this should only be called once
+ // has no effect on client/server library
+ // but is vital for the embedded lib
+ if ( mysql_server_init( 0, 0, 0 ) ) {
+# ifdef TQT_CHECK_RANGE
+ qWarning( "TQMYSTQLDriver::qServerInit: unable to start server." );
+# endif
+ }
+
+# endif // MYSTQL_VERSION_ID
+#endif // TQ_NO_MYSTQL_EMBEDDED
+}
+
+TQMYSTQLDriver::TQMYSTQLDriver( TQObject * tqparent, const char * name )
+ : TQSqlDriver( tqparent, name ? name : TQMYSTQL_DRIVER_NAME )
+{
+ init();
+ qServerInit();
+}
+
+/*!
+ Create a driver instance with an already open connection handle.
+*/
+
+TQMYSTQLDriver::TQMYSTQLDriver( MYSQL * con, TQObject * tqparent, const char * name )
+ : TQSqlDriver( tqparent, name ? name : TQMYSTQL_DRIVER_NAME )
+{
+ init();
+ if ( con ) {
+ d->mysql = (MYSQL *) con;
+ setOpen( TRUE );
+ setOpenError( FALSE );
+ if (qMySqlConnectionCount == 1)
+ qMySqlInitHandledByUser = TRUE;
+ } else {
+ qServerInit();
+ }
+}
+
+void TQMYSTQLDriver::init()
+{
+ qSqlOpenExtDict()->insert( this, new TQMYSTQLOpenExtension(this) );
+ d = new TQMYSTQLDriverPrivate();
+ d->mysql = 0;
+ qMySqlConnectionCount++;
+}
+
+TQMYSTQLDriver::~TQMYSTQLDriver()
+{
+ qMySqlConnectionCount--;
+ if (qMySqlConnectionCount == 0 && !qMySqlInitHandledByUser)
+ qServerEnd();
+
+ delete d;
+ if ( !qSqlOpenExtDict()->isEmpty() ) {
+ TQSqlOpenExtension *ext = qSqlOpenExtDict()->take( this );
+ delete ext;
+ }
+}
+
+bool TQMYSTQLDriver::hasFeature( DriverFeature f ) const
+{
+ switch ( f ) {
+ case Transactions:
+// CLIENT_TRANSACTION should be defined in all recent mysql client libs > 3.23.34
+#ifdef CLIENT_TRANSACTIONS
+ if ( d->mysql ) {
+ if ( ( d->mysql->server_capabilities & CLIENT_TRANSACTIONS ) == CLIENT_TRANSACTIONS )
+ return TRUE;
+ }
+#endif
+ return FALSE;
+ case QuerySize:
+ return TRUE;
+ case BLOB:
+ return TRUE;
+ case Unicode:
+ return FALSE;
+ default:
+ return FALSE;
+ }
+}
+
+bool TQMYSTQLDriver::open( const TQString&,
+ const TQString&,
+ const TQString&,
+ const TQString&,
+ int )
+{
+ qWarning("TQMYSTQLDriver::open(): This version of open() is no longer supported." );
+ return FALSE;
+}
+
+bool TQMYSTQLDriver::open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts )
+{
+ if ( isOpen() )
+ close();
+
+ unsigned int optionFlags = 0;
+
+ TQStringList raw = TQStringList::split( ';', connOpts );
+ TQStringList opts;
+ TQStringList::ConstIterator it;
+
+ // extract the real options from the string
+ for ( it = raw.begin(); it != raw.end(); ++it ) {
+ TQString tmp( *it );
+ int idx;
+ if ( (idx = tmp.tqfind( '=' )) != -1 ) {
+ TQString val( tmp.mid( idx + 1 ) );
+ val.simplifyWhiteSpace();
+ if ( val == "TRUE" || val == "1" )
+ opts << tmp.left( idx );
+ else
+ qWarning( "TQMYSTQLDriver::open: Illegal connect option value '%s'", tmp.latin1() );
+ } else {
+ opts << tmp;
+ }
+ }
+
+ for ( it = opts.begin(); it != opts.end(); ++it ) {
+ TQString opt( (*it).upper() );
+ if ( opt == "CLIENT_COMPRESS" )
+ optionFlags |= CLIENT_COMPRESS;
+ else if ( opt == "CLIENT_FOUND_ROWS" )
+ optionFlags |= CLIENT_FOUND_ROWS;
+ else if ( opt == "CLIENT_IGNORE_SPACE" )
+ optionFlags |= CLIENT_IGNORE_SPACE;
+ else if ( opt == "CLIENT_INTERACTIVE" )
+ optionFlags |= CLIENT_INTERACTIVE;
+ else if ( opt == "CLIENT_NO_SCHEMA" )
+ optionFlags |= CLIENT_NO_SCHEMA;
+ else if ( opt == "CLIENT_ODBC" )
+ optionFlags |= CLIENT_ODBC;
+ else if ( opt == "CLIENT_SSL" )
+ optionFlags |= CLIENT_SSL;
+ else
+ qWarning( "TQMYSTQLDriver::open: Unknown connect option '%s'", (*it).latin1() );
+ }
+
+ if ( (d->mysql = mysql_init((MYSQL*) 0)) &&
+ mysql_real_connect( d->mysql,
+ host,
+ user,
+ password,
+ db.isNull() ? TQString("") : db,
+ (port > -1) ? port : 0,
+ NULL,
+ optionFlags ) )
+ {
+ if ( !db.isEmpty() && mysql_select_db( d->mysql, db )) {
+ setLastError( qMakeError("Unable open database '" + db + "'", TQSqlError::Connection, d ) );
+ mysql_close( d->mysql );
+ setOpenError( TRUE );
+ return FALSE;
+ }
+ } else {
+ setLastError( qMakeError( "Unable to connect", TQSqlError::Connection, d ) );
+ mysql_close( d->mysql );
+ setOpenError( TRUE );
+ return FALSE;
+ }
+ setOpen( TRUE );
+ setOpenError( FALSE );
+ return TRUE;
+}
+
+void TQMYSTQLDriver::close()
+{
+ if ( isOpen() ) {
+ mysql_close( d->mysql );
+ setOpen( FALSE );
+ setOpenError( FALSE );
+ }
+}
+
+TQSqlQuery TQMYSTQLDriver::createQuery() const
+{
+ return TQSqlQuery( new TQMYSTQLResult( this ) );
+}
+
+TQStringList TQMYSTQLDriver::tables( const TQString& typeName ) const
+{
+ TQStringList tl;
+ if ( !isOpen() )
+ return tl;
+ if ( !typeName.isEmpty() && !(typeName.toInt() & (int)TQSql::Tables) )
+ return tl;
+
+ MYSTQL_RES* tableRes = mysql_list_tables( d->mysql, NULL );
+ MYSTQL_ROW row;
+ int i = 0;
+ while ( tableRes && TRUE ) {
+ mysql_data_seek( tableRes, i );
+ row = mysql_fetch_row( tableRes );
+ if ( !row )
+ break;
+ tl.append( TQString(row[0]) );
+ i++;
+ }
+ mysql_free_result( tableRes );
+ return tl;
+}
+
+TQSqlIndex TQMYSTQLDriver::primaryIndex( const TQString& tablename ) const
+{
+ TQSqlIndex idx;
+ if ( !isOpen() )
+ return idx;
+ TQSqlQuery i = createQuery();
+ TQString stmt( "show index from %1;" );
+ TQSqlRecord fil = record( tablename );
+ i.exec( stmt.arg( tablename ) );
+ while ( i.isActive() && i.next() ) {
+ if ( i.value(2).toString() == "PRIMARY" ) {
+ idx.append( *fil.field( i.value(4).toString() ) );
+ idx.setCursorName( i.value(0).toString() );
+ idx.setName( i.value(2).toString() );
+ }
+ }
+ return idx;
+}
+
+TQSqlRecord TQMYSTQLDriver::record( const TQString& tablename ) const
+{
+ TQSqlRecord fil;
+ if ( !isOpen() )
+ return fil;
+ MYSTQL_RES* r = mysql_list_fields( d->mysql, tablename.local8Bit().data(), 0);
+ if ( !r ) {
+ return fil;
+ }
+ MYSTQL_FIELD* field;
+ while ( (field = mysql_fetch_field( r ))) {
+ TQSqlField f ( TQString( field->name ) , qDecodeMYSTQLType( (int)field->type, field->flags ) );
+ fil.append ( f );
+ }
+ mysql_free_result( r );
+ return fil;
+}
+
+TQSqlRecord TQMYSTQLDriver::record( const TQSqlQuery& query ) const
+{
+ TQSqlRecord fil;
+ if ( !isOpen() )
+ return fil;
+ if ( query.isActive() && query.isSelect() && query.driver() == this ) {
+ TQMYSTQLResult* result = (TQMYSTQLResult*)query.result();
+ TQMYSTQLResultPrivate* p = result->d;
+ if ( !mysql_errno( p->mysql ) ) {
+ for ( ;; ) {
+ MYSTQL_FIELD* f = mysql_fetch_field( p->result );
+ if ( f ) {
+ TQSqlField fi( TQString((const char*)f->name), qDecodeMYSTQLType( f->type, f->flags ) );
+ fil.append( fi );
+ } else
+ break;
+ }
+ }
+ mysql_field_seek( p->result, 0 );
+ }
+ return fil;
+}
+
+TQSqlRecordInfo TQMYSTQLDriver::recordInfo( const TQString& tablename ) const
+{
+ TQSqlRecordInfo info;
+ if ( !isOpen() )
+ return info;
+ MYSTQL_RES* r = mysql_list_fields( d->mysql, tablename.local8Bit().data(), 0);
+ if ( !r ) {
+ return info;
+ }
+ MYSTQL_FIELD* field;
+ while ( (field = mysql_fetch_field( r ))) {
+ info.append ( TQSqlFieldInfo( TQString( field->name ),
+ qDecodeMYSTQLType( (int)field->type, field->flags ),
+ IS_NOT_NULL( field->flags ),
+ (int)field->length,
+ (int)field->decimals,
+ TQString( field->def ),
+ (int)field->type ) );
+ }
+ mysql_free_result( r );
+ return info;
+}
+
+TQSqlRecordInfo TQMYSTQLDriver::recordInfo( const TQSqlQuery& query ) const
+{
+ TQSqlRecordInfo info;
+ if ( !isOpen() )
+ return info;
+ if ( query.isActive() && query.isSelect() && query.driver() == this ) {
+ TQMYSTQLResult* result = (TQMYSTQLResult*)query.result();
+ TQMYSTQLResultPrivate* p = result->d;
+ if ( !mysql_errno( p->mysql ) ) {
+ for ( ;; ) {
+ MYSTQL_FIELD* field = mysql_fetch_field( p->result );
+ if ( field ) {
+ info.append ( TQSqlFieldInfo( TQString( field->name ),
+ qDecodeMYSTQLType( (int)field->type, field->flags ),
+ IS_NOT_NULL( field->flags ),
+ (int)field->length,
+ (int)field->decimals,
+ TQVariant(),
+ (int)field->type ) );
+
+ } else
+ break;
+ }
+ }
+ mysql_field_seek( p->result, 0 );
+ }
+ return info;
+}
+
+MYSQL* TQMYSTQLDriver::mysql()
+{
+ return d->mysql;
+}
+
+bool TQMYSTQLDriver::beginTransaction()
+{
+#ifndef CLIENT_TRANSACTIONS
+ return FALSE;
+#endif
+ if ( !isOpen() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQMYSTQLDriver::beginTransaction: Database not open" );
+#endif
+ return FALSE;
+ }
+ if ( mysql_query( d->mysql, "BEGIN WORK" ) ) {
+ setLastError( qMakeError("Unable to begin transaction", TQSqlError::Statement, d ) );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool TQMYSTQLDriver::commitTransaction()
+{
+#ifndef CLIENT_TRANSACTIONS
+ return FALSE;
+#endif
+ if ( !isOpen() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQMYSTQLDriver::commitTransaction: Database not open" );
+#endif
+ return FALSE;
+ }
+ if ( mysql_query( d->mysql, "COMMIT" ) ) {
+ setLastError( qMakeError("Unable to commit transaction", TQSqlError::Statement, d ) );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool TQMYSTQLDriver::rollbackTransaction()
+{
+#ifndef CLIENT_TRANSACTIONS
+ return FALSE;
+#endif
+ if ( !isOpen() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQMYSTQLDriver::rollbackTransaction: Database not open" );
+#endif
+ return FALSE;
+ }
+ if ( mysql_query( d->mysql, "ROLLBACK" ) ) {
+ setLastError( qMakeError("Unable to rollback transaction", TQSqlError::Statement, d ) );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+TQString TQMYSTQLDriver::formatValue( const TQSqlField* field, bool trimStrings ) const
+{
+ TQString r;
+ if ( field->isNull() ) {
+ r = nullText();
+ } else {
+ switch( field->type() ) {
+ case TQVariant::ByteArray: {
+
+ const TQByteArray ba = field->value().toByteArray();
+ // buffer has to be at least length*2+1 bytes
+ char* buffer = new char[ ba.size() * 2 + 1 ];
+ /*uint escapedSize =*/ mysql_escape_string( buffer, ba.data(), ba.size() );
+ r.append("'").append(buffer).append("'");
+ delete[] buffer;
+ }
+ break;
+ case TQVariant::String:
+ case TQVariant::CString: {
+ // Escape '\' characters
+ r = TQSqlDriver::formatValue( field );
+ r.tqreplace( "\\", "\\\\" );
+ break;
+ }
+ default:
+ r = TQSqlDriver::formatValue( field, trimStrings );
+ }
+ }
+ return r;
+}
diff --git a/tqtinterface/qt4/src/sql/drivers/mysql/tqsql_mysql.h b/tqtinterface/qt4/src/sql/drivers/mysql/tqsql_mysql.h
new file mode 100644
index 0000000..ef4f4ce
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/mysql/tqsql_mysql.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Definition of MySQL driver classes
+**
+** Created : 001103
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQL_MYSTQL_H
+#define TQSQL_MYSTQL_H
+
+#include <tqsqldriver.h>
+#include <tqsqlresult.h>
+#include <tqsqlfield.h>
+#include <tqsqlindex.h>
+
+#if defined (TQ_OS_WIN32)
+#include <tqt_windows.h>
+#endif
+
+#include <mysql.h>
+
+#ifdef TQT_PLUGIN
+#define TQ_EXPORT_STQLDRIVER_MYSQL
+#else
+#define TQ_EXPORT_STQLDRIVER_MYSQL TQ_EXPORT
+#endif
+
+class TQMYSTQLDriverPrivate;
+class TQMYSTQLResultPrivate;
+class TQMYSTQLDriver;
+class TQSqlRecordInfo;
+
+class TQMYSTQLResult : public TQSqlResult
+{
+ friend class TQMYSTQLDriver;
+public:
+ TQMYSTQLResult( const TQMYSTQLDriver* db );
+ ~TQMYSTQLResult();
+
+ MYSTQL_RES* result();
+protected:
+ void cleanup();
+ bool fetch( int i );
+ bool fetchNext();
+ bool fetchLast();
+ bool fetchFirst();
+ TQVariant data( int field );
+ bool isNull( int field );
+ bool reset ( const TQString& query );
+ int size();
+ int numRowsAffected();
+private:
+ TQMYSTQLResultPrivate* d;
+};
+
+class TQ_EXPORT_STQLDRIVER_MYSQL TQMYSTQLDriver : public TQSqlDriver
+{
+ friend class TQMYSTQLResult;
+public:
+ TQMYSTQLDriver( TQObject * tqparent=0, const char * name=0 );
+ TQMYSTQLDriver( MYSQL * con, TQObject * tqparent=0, const char * name=0 );
+ ~TQMYSTQLDriver();
+ bool hasFeature( DriverFeature f ) const;
+ bool open( const TQString & db,
+ const TQString & user = TQString::null,
+ const TQString & password = TQString::null,
+ const TQString & host = TQString::null,
+ int port = -1 );
+ void close();
+ TQSqlQuery createQuery() const;
+ TQStringList tables( const TQString& user ) const;
+ TQSqlIndex primaryIndex( const TQString& tablename ) const;
+ TQSqlRecord record( const TQString& tablename ) const;
+ TQSqlRecord record( const TQSqlQuery& query ) const;
+ TQSqlRecordInfo recordInfo( const TQString& tablename ) const;
+ TQSqlRecordInfo recordInfo( const TQSqlQuery& query ) const;
+ TQString formatValue( const TQSqlField* field,
+ bool trimStrings ) const;
+ MYSQL* mysql();
+ // ### remove me for 4.0
+ bool open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts );
+
+protected:
+ bool beginTransaction();
+ bool commitTransaction();
+ bool rollbackTransaction();
+private:
+ void init();
+ TQMYSTQLDriverPrivate* d;
+};
+
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/drivers/odbc/tqsql_odbc.cpp b/tqtinterface/qt4/src/sql/drivers/odbc/tqsql_odbc.cpp
new file mode 100644
index 0000000..fda38a8
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/odbc/tqsql_odbc.cpp
@@ -0,0 +1,2035 @@
+/****************************************************************************
+**
+** Implementation of ODBC driver classes
+**
+** Created : 001103
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsql_odbc.h"
+#include <tqsqlrecord.h>
+
+#if defined (TQ_OS_WIN32)
+#include <tqt_windows.h>
+#include <tqapplication.h>
+#endif
+#include <tqdatetime.h>
+#include <private/tqsqlextension_p.h>
+#include <private/tqinternal_p.h>
+#include <stdlib.h>
+
+// undefine this to prevent initial check of the ODBC driver
+#define ODBC_CHECK_DRIVER
+
+#if defined(TQ_ODBC_VERSION_2)
+//crude hack to get non-tqunicode capable driver managers to work
+# undef UNICODE
+# define STQLTCHAR STQLCHAR
+# define STQL_C_WCHAR STQL_C_CHAR
+#endif
+
+// newer platform SDKs use STQLLEN instead of STQLINTEGER
+#ifdef STQLLEN
+# define TQSTQLLEN STQLLEN
+#else
+# define TQSTQLLEN STQLINTEGER
+#endif
+
+#ifdef STQLULEN
+# define TQSQLULEN STQLULEN
+#else
+# define TQSQLULEN STQLUINTEGER
+#endif
+
+
+static const TQSTQLLEN COLNAMESIZE = 256;
+//Map TQt parameter types to ODBC types
+static const STQLSMALLINT qParamType[ 4 ] = { STQL_PARAM_INPUT, STQL_PARAM_INPUT, STQL_PARAM_OUTPUT, STQL_PARAM_INPUT_OUTPUT };
+
+class TQODBCPrivate
+{
+public:
+ TQODBCPrivate()
+ : hEnv(0), hDbc(0), hStmt(0), useSchema(FALSE)
+ {
+ sql_char_type = sql_varchar_type = sql_longvarchar_type = TQVariant::CString;
+ tqunicode = FALSE;
+ }
+
+ STQLHANDLE hEnv;
+ STQLHANDLE hDbc;
+ STQLHANDLE hStmt;
+
+ bool tqunicode;
+ bool useSchema;
+ TQVariant::Type sql_char_type;
+ TQVariant::Type sql_varchar_type;
+ TQVariant::Type sql_longvarchar_type;
+
+ TQSqlRecordInfo rInf;
+
+ bool checkDriver() const;
+ void checkUnicode();
+ void checkSchemaUsage();
+ bool setConnectionOptions( const TQString& connOpts );
+ void splitTableQualifier(const TQString &qualifier, TQString &catalog,
+ TQString &schema, TQString &table);
+};
+
+class TQODBCPreparedExtension : public TQSqlExtension
+{
+public:
+ TQODBCPreparedExtension( TQODBCResult * r )
+ : result( r ) {}
+
+ bool prepare( const TQString& query )
+ {
+ return result->prepare( query );
+ }
+
+ bool exec()
+ {
+ return result->exec();
+ }
+
+ TQODBCResult * result;
+};
+
+TQPtrDict<TQSqlOpenExtension> *qSqlOpenExtDict();
+
+class TQODBCOpenExtension : public TQSqlOpenExtension
+{
+public:
+ TQODBCOpenExtension( TQODBCDriver *dri )
+ : TQSqlOpenExtension(), driver(dri) {}
+ ~TQODBCOpenExtension() {}
+
+ bool open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts );
+private:
+ TQODBCDriver *driver;
+};
+
+bool TQODBCOpenExtension::open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts )
+{
+ return driver->open( db, user, password, host, port, connOpts );
+}
+
+static TQString qWarnODBCHandle(int handleType, STQLHANDLE handle)
+{
+ STQLINTEGER nativeCode_;
+ STQLSMALLINT msgLen;
+ STQLRETURN r = STQL_ERROR;
+ STQLTCHAR state_[STQL_STQLSTATE_SIZE+1];
+ STQLTCHAR description_[STQL_MAX_MESSAGE_LENGTH];
+ r = STQLGetDiagRec( handleType,
+ handle,
+ 1,
+ (STQLTCHAR*)state_,
+ &nativeCode_,
+ (STQLTCHAR*)description_,
+ STQL_MAX_MESSAGE_LENGTH-1, /* in bytes, not in characters */
+ &msgLen);
+ if ( r == STQL_SUCCESS || r == STQL_SUCCESS_WITH_INFO )
+#ifdef UNICODE
+ return TQString( (const TQChar*)description_, (uint)msgLen );
+#else
+ return TQString::fromLocal8Bit( (const char*)description_ );
+#endif
+ return TQString::null;
+}
+
+static TQString qODBCWarn( const TQODBCPrivate* odbc)
+{
+ return ( qWarnODBCHandle( STQL_HANDLE_ENV, odbc->hEnv ) + " "
+ + qWarnODBCHandle( STQL_HANDLE_DBC, odbc->hDbc ) + " "
+ + qWarnODBCHandle( STQL_HANDLE_STMT, odbc->hStmt ) );
+}
+
+static void qSqlWarning( const TQString& message, const TQODBCPrivate* odbc )
+{
+#ifdef TQT_CHECK_RANGE
+ qWarning( "%s\tError: %s", message.local8Bit().data(), qODBCWarn( odbc ).local8Bit().data() );
+#endif
+}
+
+static TQSqlError qMakeError( const TQString& err, int type, const TQODBCPrivate* p )
+{
+ return TQSqlError( "TQODBC3: " + err, qODBCWarn(p), type );
+}
+
+static TQVariant::Type qDecodeODBCType( STQLSMALLINT sqltype, const TQODBCPrivate* p )
+{
+ TQVariant::Type type = TQVariant::Invalid;
+ switch ( sqltype ) {
+ case STQL_DECIMAL:
+ case STQL_NUMERIC:
+ case STQL_REAL:
+ case STQL_FLOAT:
+ case STQL_DOUBLE:
+ type = TQVariant::Double;
+ break;
+ case STQL_SMALLINT:
+ case STQL_INTEGER:
+ case STQL_BIT:
+ case STQL_TINYINT:
+ type = TQVariant::Int;
+ break;
+ case STQL_BIGINT:
+ type = TQVariant::LongLong;
+ break;
+ case STQL_BINARY:
+ case STQL_VARBINARY:
+ case STQL_LONGVARBINARY:
+ type = TQVariant::ByteArray;
+ break;
+ case STQL_DATE:
+ case STQL_TYPE_DATE:
+ type = TQVariant::Date;
+ break;
+ case STQL_TIME:
+ case STQL_TYPE_TIME:
+ type = TQVariant::Time;
+ break;
+ case STQL_TIMESTAMP:
+ case STQL_TYPE_TIMESTAMP:
+ type = TQVariant::DateTime;
+ break;
+#ifndef TQ_ODBC_VERSION_2
+ case STQL_WCHAR:
+ case STQL_WVARCHAR:
+ case STQL_WLONGVARCHAR:
+ type = TQVariant::String;
+ break;
+#endif
+ case STQL_CHAR:
+ type = p->sql_char_type;
+ break;
+ case STQL_VARCHAR:
+ type = p->sql_varchar_type;
+ break;
+ case STQL_LONGVARCHAR:
+ type = p->sql_longvarchar_type;
+ break;
+ default:
+ type = TQVariant::CString;
+ break;
+ }
+ return type;
+}
+
+static TQString qGetStringData( STQLHANDLE hStmt, int column, int colSize, bool& isNull, bool tqunicode = FALSE )
+{
+ TQString fieldVal;
+ STQLRETURN r = STQL_ERROR;
+ TQSTQLLEN lengthIndicator = 0;
+
+ if ( colSize <= 0 ) {
+ colSize = 256;
+ } else if ( colSize > 65536 ) { // limit buffer size to 64 KB
+ colSize = 65536;
+ } else {
+ colSize++; // make sure there is room for more than the 0 termination
+ if ( tqunicode ) {
+ colSize *= 2; // a tiny bit faster, since it saves a STQLGetData() call
+ }
+ }
+ char* buf = new char[ colSize ];
+ while ( TRUE ) {
+ r = STQLGetData( hStmt,
+ column+1,
+ tqunicode ? STQL_C_WCHAR : STQL_C_CHAR,
+ (STQLPOINTER)buf,
+ (TQSTQLLEN)colSize,
+ &lengthIndicator );
+ if ( r == STQL_SUCCESS || r == STQL_SUCCESS_WITH_INFO ) {
+ if ( lengthIndicator == STQL_NULL_DATA || lengthIndicator == STQL_NO_TOTAL ) {
+ fieldVal = TQString::null;
+ isNull = TRUE;
+ break;
+ }
+ // if STQL_SUCCESS_WITH_INFO is returned, indicating that
+ // more data can be fetched, the length indicator does NOT
+ // contain the number of bytes returned - it tqcontains the
+ // total number of bytes that CAN be fetched
+ // colSize-1: remove 0 termination when there is more data to fetch
+ int rSize = (r == STQL_SUCCESS_WITH_INFO) ? (tqunicode ? colSize-2 : colSize-1) : lengthIndicator;
+ if ( tqunicode ) {
+ fieldVal += TQString( (TQChar*) buf, rSize / 2 );
+ } else {
+ buf[ rSize ] = 0;
+ fieldVal += buf;
+ }
+ if ( lengthIndicator < colSize ) {
+ // workaround for Drivermanagers that don't return STQL_NO_DATA
+ break;
+ }
+ } else if ( r == STQL_NO_DATA ) {
+ break;
+ } else {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "qGetStringData: Error while fetching data (%d)", r );
+#endif
+ fieldVal = TQString::null;
+ break;
+ }
+ }
+ delete[] buf;
+ return fieldVal;
+}
+
+static TQByteArray qGetBinaryData( STQLHANDLE hStmt, int column, TQSTQLLEN& lengthIndicator, bool& isNull )
+{
+ TQByteArray fieldVal;
+ STQLSMALLINT colNameLen;
+ STQLSMALLINT colType;
+ TQSQLULEN colSize;
+ STQLSMALLINT colScale;
+ STQLSMALLINT nullable;
+ STQLRETURN r = STQL_ERROR;
+
+ STQLTCHAR colName[COLNAMESIZE];
+ r = STQLDescribeCol( hStmt,
+ column+1,
+ colName,
+ COLNAMESIZE,
+ &colNameLen,
+ &colType,
+ &colSize,
+ &colScale,
+ &nullable );
+#ifdef TQT_CHECK_RANGE
+ if ( r != STQL_SUCCESS )
+ qWarning( "qGetBinaryData: Unable to describe column %d", column );
+#endif
+ // STQLDescribeCol may return 0 if size cannot be determined
+ if (!colSize) {
+ colSize = 256;
+ }
+ if ( colSize > 65536 ) { // read the field in 64 KB chunks
+ colSize = 65536;
+ }
+ char * buf = new char[ colSize ];
+ while ( TRUE ) {
+ r = STQLGetData( hStmt,
+ column+1,
+ STQL_C_BINARY,
+ (STQLPOINTER) buf,
+ (TQSTQLLEN)colSize,
+ &lengthIndicator );
+ if ( r == STQL_SUCCESS || r == STQL_SUCCESS_WITH_INFO ) {
+ if ( lengthIndicator == STQL_NULL_DATA ) {
+ isNull = TRUE;
+ break;
+ } else {
+ int rSize;
+ r == STQL_SUCCESS ? rSize = lengthIndicator : rSize = colSize;
+ if ( lengthIndicator == STQL_NO_TOTAL ) { // size cannot be determined
+ rSize = colSize;
+ }
+ // NB! This is not a memleak - the mem will be deleted by TQByteArray when
+ // no longer ref'd
+ char * tmp = (char *) malloc( rSize + fieldVal.size() );
+ if ( fieldVal.size() ) {
+ memcpy( tmp, fieldVal.data(), fieldVal.size() );
+ }
+ memcpy( tmp + fieldVal.size(), buf, rSize );
+ fieldVal = fieldVal.assign( tmp, fieldVal.size() + rSize );
+
+ if ( r == STQL_SUCCESS ) { // the whole field was read in one chunk
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ delete [] buf;
+ return fieldVal;
+}
+
+static int qGetIntData( STQLHANDLE hStmt, int column, bool& isNull )
+{
+ TQSTQLLEN intbuf = 0;
+ isNull = FALSE;
+ TQSTQLLEN lengthIndicator = 0;
+ STQLRETURN r = STQLGetData( hStmt,
+ column+1,
+ STQL_C_SLONG,
+ (STQLPOINTER)&intbuf,
+ (TQSTQLLEN)0,
+ &lengthIndicator );
+ if ( ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) || lengthIndicator == STQL_NULL_DATA ) {
+ isNull = TRUE;
+ return 0;
+ }
+ return (int)intbuf;
+}
+
+static double qGetDoubleData( STQLHANDLE hStmt, int column, bool& isNull )
+{
+ STQLDOUBLE dblbuf;
+ TQSTQLLEN lengthIndicator = 0;
+ isNull = FALSE;
+ STQLRETURN r = STQLGetData( hStmt,
+ column+1,
+ STQL_C_DOUBLE,
+ (STQLPOINTER)&dblbuf,
+ (TQSTQLLEN)0,
+ &lengthIndicator );
+ if ( ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) || lengthIndicator == STQL_NULL_DATA ) {
+ isNull = TRUE;
+ return 0.0;
+ }
+
+ return (double) dblbuf;
+}
+
+static STQLBIGINT qGetBigIntData( STQLHANDLE hStmt, int column, bool& isNull )
+{
+ STQLBIGINT lngbuf = TQ_INT64_C( 0 );
+ isNull = FALSE;
+ TQSTQLLEN lengthIndicator = 0;
+ STQLRETURN r = STQLGetData( hStmt,
+ column+1,
+ STQL_C_SBIGINT,
+ (STQLPOINTER) &lngbuf,
+ (TQSTQLLEN)0,
+ &lengthIndicator );
+ if ( ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) || lengthIndicator == STQL_NULL_DATA )
+ isNull = TRUE;
+
+ return lngbuf;
+}
+
+// creates a TQSqlFieldInfo from a valid hStmt generated
+// by STQLColumns. The hStmt has to point to a valid position.
+static TQSqlFieldInfo qMakeFieldInfo( const STQLHANDLE hStmt, const TQODBCPrivate* p )
+{
+ bool isNull;
+ TQString fname = qGetStringData( hStmt, 3, -1, isNull, p->tqunicode );
+ int type = qGetIntData( hStmt, 4, isNull ); // column type
+ int required = qGetIntData( hStmt, 10, isNull ); // nullable-flag
+ // required can be STQL_NO_NULLS, STQL_NULLABLE or STQL_NULLABLE_UNKNOWN
+ if ( required == STQL_NO_NULLS ) {
+ required = 1;
+ } else if ( required == STQL_NULLABLE ) {
+ required = 0;
+ } else {
+ required = -1;
+ }
+ int size = qGetIntData( hStmt, 6, isNull ); // column size
+ int prec = qGetIntData( hStmt, 8, isNull ); // precision
+ return TQSqlFieldInfo( fname, qDecodeODBCType( type, p ), required, size, prec, TQVariant(), type );
+}
+
+static TQSqlFieldInfo qMakeFieldInfo( const TQODBCPrivate* p, int i )
+{
+ STQLSMALLINT colNameLen;
+ STQLSMALLINT colType;
+ TQSQLULEN colSize;
+ STQLSMALLINT colScale;
+ STQLSMALLINT nullable;
+ STQLRETURN r = STQL_ERROR;
+ STQLTCHAR colName[ COLNAMESIZE ];
+ r = STQLDescribeCol( p->hStmt,
+ i+1,
+ colName,
+ (TQSQLULEN)COLNAMESIZE,
+ &colNameLen,
+ &colType,
+ &colSize,
+ &colScale,
+ &nullable);
+
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( TQString("qMakeField: Unable to describe column %1").arg(i), p );
+#endif
+ return TQSqlFieldInfo();
+ }
+#ifdef UNICODE
+ TQString qColName( (const TQChar*)colName, (uint)colNameLen );
+#else
+ TQString qColName = TQString::fromLocal8Bit( (const char*)colName );
+#endif
+ // nullable can be STQL_NO_NULLS, STQL_NULLABLE or STQL_NULLABLE_UNKNOWN
+ int required = -1;
+ if ( nullable == STQL_NO_NULLS ) {
+ required = 1;
+ } else if ( nullable == STQL_NULLABLE ) {
+ required = 0;
+ }
+ TQVariant::Type type = qDecodeODBCType( colType, p );
+ return TQSqlFieldInfo( qColName,
+ type,
+ required,
+ (int)colSize == 0 ? -1 : (int)colSize,
+ (int)colScale == 0 ? -1 : (int)colScale,
+ TQVariant(),
+ (int)colType );
+}
+
+bool TQODBCPrivate::setConnectionOptions( const TQString& connOpts )
+{
+ // Set any connection attributes
+ TQStringList raw = TQStringList::split( ';', connOpts );
+ TQStringList opts;
+ STQLRETURN r = STQL_SUCCESS;
+ TQMap<TQString, TQString> connMap;
+ for ( TQStringList::ConstIterator it = raw.begin(); it != raw.end(); ++it ) {
+ TQString tmp( *it );
+ int idx;
+ if ( (idx = tmp.tqfind( '=' )) != -1 )
+ connMap[ tmp.left( idx ) ] = tmp.mid( idx + 1 ).simplifyWhiteSpace();
+ else
+ qWarning( "TQODBCDriver::open: Illegal connect option value '%s'", tmp.latin1() );
+ }
+ if ( connMap.count() ) {
+ TQMap<TQString, TQString>::ConstIterator it;
+ TQString opt, val;
+ STQLUINTEGER v = 0;
+ for ( it = connMap.begin(); it != connMap.end(); ++it ) {
+ opt = it.key().upper();
+ val = it.data().upper();
+ r = STQL_SUCCESS;
+ if ( opt == "STQL_ATTR_ACCESS_MODE" ) {
+ if ( val == "STQL_MODE_READ_ONLY" ) {
+ v = STQL_MODE_READ_ONLY;
+ } else if ( val == "STQL_MODE_READ_WRITE" ) {
+ v = STQL_MODE_READ_WRITE;
+ } else {
+ qWarning( TQString( "TQODBCDriver::open: Unknown option value '%1'" ).arg( *it ) );
+ break;
+ }
+ r = STQLSetConnectAttr( hDbc, STQL_ATTR_ACCESS_MODE, (STQLPOINTER) v, 0 );
+ } else if ( opt == "STQL_ATTR_CONNECTION_TIMEOUT" ) {
+ v = val.toUInt();
+ r = STQLSetConnectAttr( hDbc, STQL_ATTR_CONNECTION_TIMEOUT, (STQLPOINTER) v, 0 );
+ } else if ( opt == "STQL_ATTR_LOGIN_TIMEOUT" ) {
+ v = val.toUInt();
+ r = STQLSetConnectAttr( hDbc, STQL_ATTR_LOGIN_TIMEOUT, (STQLPOINTER) v, 0 );
+ } else if ( opt == "STQL_ATTR_CURRENT_CATALOG" ) {
+ val.ucs2(); // 0 terminate
+ r = STQLSetConnectAttr( hDbc, STQL_ATTR_CURRENT_CATALOG,
+#ifdef UNICODE
+ (STQLWCHAR*) val.tqunicode(),
+#else
+ (STQLCHAR*) val.latin1(),
+#endif
+ STQL_NTS );
+ } else if ( opt == "STQL_ATTR_METADATA_ID" ) {
+ if ( val == "STQL_TRUE" ) {
+ v = STQL_TRUE;
+ } else if ( val == "STQL_FALSE" ) {
+ v = STQL_FALSE;
+ } else {
+ qWarning( TQString( "TQODBCDriver::open: Unknown option value '%1'" ).arg( *it ) );
+ break;
+ }
+ r = STQLSetConnectAttr( hDbc, STQL_ATTR_METADATA_ID, (STQLPOINTER) v, 0 );
+ } else if ( opt == "STQL_ATTR_PACKET_SIZE" ) {
+ v = val.toUInt();
+ r = STQLSetConnectAttr( hDbc, STQL_ATTR_PACKET_SIZE, (STQLPOINTER) v, 0 );
+ } else if ( opt == "STQL_ATTR_TRACEFILE" ) {
+ val.ucs2(); // 0 terminate
+ r = STQLSetConnectAttr( hDbc, STQL_ATTR_TRACEFILE,
+#ifdef UNICODE
+ (STQLWCHAR*) val.tqunicode(),
+#else
+ (STQLCHAR*) val.latin1(),
+#endif
+ STQL_NTS );
+ } else if ( opt == "STQL_ATTR_TRACE" ) {
+ if ( val == "STQL_OPT_TRACE_OFF" ) {
+ v = STQL_OPT_TRACE_OFF;
+ } else if ( val == "STQL_OPT_TRACE_ON" ) {
+ v = STQL_OPT_TRACE_ON;
+ } else {
+ qWarning( TQString( "TQODBCDriver::open: Unknown option value '%1'" ).arg( *it ) );
+ break;
+ }
+ r = STQLSetConnectAttr( hDbc, STQL_ATTR_TRACE, (STQLPOINTER) v, 0 );
+ }
+#ifdef TQT_CHECK_RANGE
+ else {
+ qWarning( TQString("TQODBCDriver::open: Unknown connection attribute '%1'").arg( opt ) );
+ }
+#endif
+ if ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( TQString("TQODBCDriver::open: Unable to set connection attribute '%1'").arg( opt ), this );
+#endif
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+void TQODBCPrivate::splitTableQualifier(const TQString & qualifier, TQString &catalog,
+ TQString &schema, TQString &table)
+{
+ if (!useSchema) {
+ table = qualifier;
+ return;
+ }
+ TQStringList l = TQStringList::split( ".", qualifier, TRUE );
+ if ( l.count() > 3 )
+ return; // can't possibly be a valid table qualifier
+ int i = 0, n = l.count();
+ if ( n == 1 ) {
+ table = qualifier;
+ } else {
+ for ( TQStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
+ if ( n == 3 ) {
+ if ( i == 0 ) {
+ catalog = *it;
+ } else if ( i == 1 ) {
+ schema = *it;
+ } else if ( i == 2 ) {
+ table = *it;
+ }
+ } else if ( n == 2 ) {
+ if ( i == 0 ) {
+ schema = *it;
+ } else if ( i == 1 ) {
+ table = *it;
+ }
+ }
+ i++;
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////
+
+TQODBCResult::TQODBCResult( const TQODBCDriver * db, TQODBCPrivate* p )
+: TQSqlResult(db)
+{
+ d = new TQODBCPrivate();
+ (*d) = (*p);
+ setExtension( new TQODBCPreparedExtension( this ) );
+}
+
+TQODBCResult::~TQODBCResult()
+{
+ if ( d->hStmt && driver()->isOpen() ) {
+ STQLRETURN r = STQLFreeHandle( STQL_HANDLE_STMT, d->hStmt );
+#ifdef TQT_CHECK_RANGE
+ if ( r != STQL_SUCCESS )
+ qSqlWarning( "TQODBCDriver: Unable to free statement handle " + TQString::number(r), d );
+#endif
+ }
+
+ delete d;
+}
+
+bool TQODBCResult::reset ( const TQString& query )
+{
+ setActive( FALSE );
+ setAt( TQSql::BeforeFirst );
+ STQLRETURN r;
+
+ d->rInf.clear();
+ // Always reallocate the statement handle - the statement attributes
+ // are not reset if STQLFreeStmt() is called which causes some problems.
+ if ( d->hStmt ) {
+ r = STQLFreeHandle( STQL_HANDLE_STMT, d->hStmt );
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCResult::reset: Unable to free statement handle", d );
+#endif
+ return FALSE;
+ }
+ }
+ r = STQLAllocHandle( STQL_HANDLE_STMT,
+ d->hDbc,
+ &d->hStmt );
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCResult::reset: Unable to allocate statement handle", d );
+#endif
+ return FALSE;
+ }
+
+ if ( isForwardOnly() ) {
+ r = STQLSetStmtAttr( d->hStmt,
+ STQL_ATTR_CURSOR_TYPE,
+ (STQLPOINTER)STQL_CURSOR_FORWARD_ONLY,
+ STQL_IS_UINTEGER );
+ } else {
+ r = STQLSetStmtAttr( d->hStmt,
+ STQL_ATTR_CURSOR_TYPE,
+ (STQLPOINTER)STQL_CURSOR_STATIC,
+ STQL_IS_UINTEGER );
+ }
+ if ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCResult::reset: Unable to set 'STQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration", d );
+#endif
+ return FALSE;
+ }
+
+#ifdef UNICODE
+ r = STQLExecDirect( d->hStmt,
+ (STQLWCHAR*) query.tqunicode(),
+ (STQLINTEGER) query.length() );
+#else
+ TQCString query8 = query.local8Bit();
+ r = STQLExecDirect( d->hStmt,
+ (STQLCHAR*) query8.data(),
+ (STQLINTEGER) query8.length() );
+#endif
+ if ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) {
+ setLastError( qMakeError( "Unable to execute statement", TQSqlError::Statement, d ) );
+ return FALSE;
+ }
+ STQLSMALLINT count;
+ r = STQLNumResultCols( d->hStmt, &count );
+ if ( count ) {
+ setSelect( TRUE );
+ for ( int i = 0; i < count; ++i ) {
+ d->rInf.append( qMakeFieldInfo( d, i ) );
+ }
+ } else {
+ setSelect( FALSE );
+ }
+ setActive( TRUE );
+ return TRUE;
+}
+
+bool TQODBCResult::fetch(int i)
+{
+ if ( isForwardOnly() && i < at() )
+ return FALSE;
+ if ( i == at() )
+ return TRUE;
+ fieldCache.clear();
+ nullCache.clear();
+ int actualIdx = i + 1;
+ if ( actualIdx <= 0 ) {
+ setAt( TQSql::BeforeFirst );
+ return FALSE;
+ }
+ STQLRETURN r;
+ if ( isForwardOnly() ) {
+ bool ok = TRUE;
+ while ( ok && i > at() )
+ ok = fetchNext();
+ return ok;
+ } else {
+ r = STQLFetchScroll( d->hStmt,
+ STQL_FETCH_ABSOLUTE,
+ actualIdx );
+ }
+ if ( r != STQL_SUCCESS ){
+ return FALSE;
+ }
+ setAt( i );
+ return TRUE;
+}
+
+bool TQODBCResult::fetchNext()
+{
+ STQLRETURN r;
+ fieldCache.clear();
+ nullCache.clear();
+ r = STQLFetchScroll( d->hStmt,
+ STQL_FETCH_NEXT,
+ 0 );
+ if ( r != STQL_SUCCESS )
+ return FALSE;
+ setAt( at() + 1 );
+ return TRUE;
+}
+
+bool TQODBCResult::fetchFirst()
+{
+ if ( isForwardOnly() && at() != TQSql::BeforeFirst )
+ return FALSE;
+ STQLRETURN r;
+ fieldCache.clear();
+ nullCache.clear();
+ if ( isForwardOnly() ) {
+ return fetchNext();
+ }
+ r = STQLFetchScroll( d->hStmt,
+ STQL_FETCH_FIRST,
+ 0 );
+ if ( r != STQL_SUCCESS )
+ return FALSE;
+ setAt( 0 );
+ return TRUE;
+}
+
+bool TQODBCResult::fetchPrior()
+{
+ if ( isForwardOnly() )
+ return FALSE;
+ STQLRETURN r;
+ fieldCache.clear();
+ nullCache.clear();
+ r = STQLFetchScroll( d->hStmt,
+ STQL_FETCH_PRIOR,
+ 0 );
+ if ( r != STQL_SUCCESS )
+ return FALSE;
+ setAt( at() - 1 );
+ return TRUE;
+}
+
+bool TQODBCResult::fetchLast()
+{
+ STQLRETURN r;
+ fieldCache.clear();
+ nullCache.clear();
+
+ if ( isForwardOnly() ) {
+ // cannot seek to last row in forwardOnly mode, so we have to use brute force
+ int i = at();
+ if ( i == TQSql::AfterLast )
+ return FALSE;
+ if ( i == TQSql::BeforeFirst )
+ i = 0;
+ while ( fetchNext() )
+ ++i;
+ setAt( i );
+ return TRUE;
+ }
+
+ r = STQLFetchScroll( d->hStmt,
+ STQL_FETCH_LAST,
+ 0 );
+ if ( r != STQL_SUCCESS ) {
+ return FALSE;
+ }
+ STQLINTEGER currRow;
+ r = STQLGetStmtAttr( d->hStmt,
+ STQL_ROW_NUMBER,
+ &currRow,
+ STQL_IS_INTEGER,
+ 0 );
+ if ( r != STQL_SUCCESS )
+ return FALSE;
+ setAt( currRow-1 );
+ return TRUE;
+}
+
+TQVariant TQODBCResult::data( int field )
+{
+ if ( field >= (int) d->rInf.count() ) {
+ qWarning( "TQODBCResult::data: column %d out of range", field );
+ return TQVariant();
+ }
+ if ( fieldCache.tqcontains( field ) )
+ return fieldCache[ field ];
+ STQLRETURN r(0);
+ TQSTQLLEN lengthIndicator = 0;
+ bool isNull = FALSE;
+ int current = fieldCache.count();
+ for ( ; current < (field + 1); ++current ) {
+ const TQSqlFieldInfo info = d->rInf[ current ];
+ switch ( info.type() ) {
+ case TQVariant::LongLong:
+ fieldCache[ current ] = TQVariant( (TQ_LLONG) qGetBigIntData( d->hStmt, current, isNull ) );
+ nullCache[ current ] = isNull;
+ break;
+ case TQVariant::Int:
+ fieldCache[ current ] = TQVariant( qGetIntData( d->hStmt, current, isNull ) );
+ nullCache[ current ] = isNull;
+ break;
+ case TQVariant::Date:
+ DATE_STRUCT dbuf;
+ r = STQLGetData( d->hStmt,
+ current+1,
+ STQL_C_DATE,
+ (STQLPOINTER)&dbuf,
+ (TQSTQLLEN)0,
+ &lengthIndicator );
+ if ( ( r == STQL_SUCCESS || r == STQL_SUCCESS_WITH_INFO ) && ( lengthIndicator != STQL_NULL_DATA ) ) {
+ fieldCache[ current ] = TQVariant( TQDate( dbuf.year, dbuf.month, dbuf.day ) );
+ nullCache[ current ] = FALSE;
+ } else {
+ fieldCache[ current ] = TQVariant( TQDate() );
+ nullCache[ current ] = TRUE;
+ }
+ break;
+ case TQVariant::Time:
+ TIME_STRUCT tbuf;
+ r = STQLGetData( d->hStmt,
+ current+1,
+ STQL_C_TIME,
+ (STQLPOINTER)&tbuf,
+ (TQSTQLLEN)0,
+ &lengthIndicator );
+ if ( ( r == STQL_SUCCESS || r == STQL_SUCCESS_WITH_INFO ) && ( lengthIndicator != STQL_NULL_DATA ) ) {
+ fieldCache[ current ] = TQVariant( TQTime( tbuf.hour, tbuf.minute, tbuf.second ) );
+ nullCache[ current ] = FALSE;
+ } else {
+ fieldCache[ current ] = TQVariant( TQTime() );
+ nullCache[ current ] = TRUE;
+ }
+ break;
+ case TQVariant::DateTime:
+ TIMESTAMP_STRUCT dtbuf;
+ r = STQLGetData( d->hStmt,
+ current+1,
+ STQL_C_TIMESTAMP,
+ (STQLPOINTER)&dtbuf,
+ (TQSTQLLEN)0,
+ &lengthIndicator );
+ if ( ( r == STQL_SUCCESS || r == STQL_SUCCESS_WITH_INFO ) && ( lengthIndicator != STQL_NULL_DATA ) ) {
+ fieldCache[ current ] = TQVariant( TQDateTime( TQDate( dtbuf.year, dtbuf.month, dtbuf.day ), TQTime( dtbuf.hour, dtbuf.minute, dtbuf.second, dtbuf.fraction / 1000000 ) ) );
+ nullCache[ current ] = FALSE;
+ } else {
+ fieldCache[ current ] = TQVariant( TQDateTime() );
+ nullCache[ current ] = TRUE;
+ }
+ break;
+ case TQVariant::ByteArray: {
+ isNull = FALSE;
+ TQByteArray val = qGetBinaryData( d->hStmt, current, lengthIndicator, isNull );
+ fieldCache[ current ] = TQVariant( val );
+ nullCache[ current ] = isNull;
+ break; }
+ case TQVariant::String:
+ isNull = FALSE;
+ fieldCache[ current ] = TQVariant( qGetStringData( d->hStmt, current,
+ info.length(), isNull, TRUE ) );
+ nullCache[ current ] = isNull;
+ break;
+ case TQVariant::Double:
+ if ( info.typeID() == STQL_DECIMAL || info.typeID() == STQL_NUMERIC )
+ // bind Double values as string to prevent loss of precision
+ fieldCache[ current ] = TQVariant( qGetStringData( d->hStmt, current,
+ info.length() + 1, isNull, FALSE ) ); // length + 1 for the comma
+ else
+ fieldCache[ current ] = TQVariant( qGetDoubleData( d->hStmt, current, isNull ) );
+ nullCache[ current ] = isNull;
+ break;
+ case TQVariant::CString:
+ default:
+ isNull = FALSE;
+ fieldCache[ current ] = TQVariant( qGetStringData( d->hStmt, current,
+ info.length(), isNull, FALSE ) );
+ nullCache[ current ] = isNull;
+ break;
+ }
+ }
+ return fieldCache[ --current ];
+}
+
+bool TQODBCResult::isNull( int field )
+{
+ if ( !fieldCache.tqcontains( field ) ) {
+ // since there is no good way to tqfind out whether the value is NULL
+ // without fetching the field we'll fetch it here.
+ // (data() also sets the NULL flag)
+ data( field );
+ }
+ return nullCache[ field ];
+}
+
+int TQODBCResult::size()
+{
+ return -1;
+}
+
+int TQODBCResult::numRowsAffected()
+{
+ TQSTQLLEN affectedRowCount(0);
+ STQLRETURN r = STQLRowCount( d->hStmt, &affectedRowCount );
+ if ( r == STQL_SUCCESS )
+ return affectedRowCount;
+#ifdef TQT_CHECK_RANGE
+ else
+ qSqlWarning( "TQODBCResult::numRowsAffected: Unable to count affected rows", d );
+#endif
+ return -1;
+}
+
+bool TQODBCResult::prepare( const TQString& query )
+{
+ setActive( FALSE );
+ setAt( TQSql::BeforeFirst );
+ STQLRETURN r;
+
+ d->rInf.clear();
+ if ( d->hStmt ) {
+ r = STQLFreeHandle( STQL_HANDLE_STMT, d->hStmt );
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCResult::prepare: Unable to close statement", d );
+#endif
+ return FALSE;
+ }
+ }
+ r = STQLAllocHandle( STQL_HANDLE_STMT,
+ d->hDbc,
+ &d->hStmt );
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCResult::prepare: Unable to allocate statement handle", d );
+#endif
+ return FALSE;
+ }
+
+ if ( isForwardOnly() ) {
+ r = STQLSetStmtAttr( d->hStmt,
+ STQL_ATTR_CURSOR_TYPE,
+ (STQLPOINTER)STQL_CURSOR_FORWARD_ONLY,
+ STQL_IS_UINTEGER );
+ } else {
+ r = STQLSetStmtAttr( d->hStmt,
+ STQL_ATTR_CURSOR_TYPE,
+ (STQLPOINTER)STQL_CURSOR_STATIC,
+ STQL_IS_UINTEGER );
+ }
+ if ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCResult::prepare: Unable to set 'STQL_CURSOR_STATIC' as statement attribute. Please check your ODBC driver configuration", d );
+#endif
+ return FALSE;
+ }
+
+#ifdef UNICODE
+ r = STQLPrepare( d->hStmt,
+ (STQLWCHAR*) query.tqunicode(),
+ (STQLINTEGER) query.length() );
+#else
+ TQCString query8 = query.local8Bit();
+ r = STQLPrepare( d->hStmt,
+ (STQLCHAR*) query8.data(),
+ (STQLINTEGER) query8.length() );
+#endif
+
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCResult::prepare: Unable to prepare statement", d );
+#endif
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool TQODBCResult::exec()
+{
+ STQLRETURN r;
+ TQPtrList<TQVirtualDestructor> tmpStorage; // holds temporary ptrs. which will be deleted on fu exit
+ tmpStorage.setAutoDelete( TRUE );
+
+ setActive( FALSE );
+ setAt( TQSql::BeforeFirst );
+ d->rInf.clear();
+
+ if ( !d->hStmt ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCResult::exec: No statement handle available", d );
+#endif
+ return FALSE;
+ } else {
+ r = STQLFreeStmt( d->hStmt, STQL_CLOSE );
+ if ( r != STQL_SUCCESS ) {
+ qSqlWarning( "TQODBCResult::exec: Unable to close statement handle", d );
+ return FALSE;
+ }
+ }
+
+ // bind parameters - only positional binding allowed
+ if ( extension()->index.count() > 0 ) {
+ TQMap<int, TQString>::Iterator it;
+ int para = 1;
+ TQVariant val;
+ for ( it = extension()->index.begin(); it != extension()->index.end(); ++it ) {
+ val = extension()->values[ it.data() ].value;
+ TQSTQLLEN *ind = new TQSTQLLEN( STQL_NTS );
+ tmpStorage.append( qAutoDeleter(ind) );
+ if ( val.isNull() ) {
+ *ind = STQL_NULL_DATA;
+ }
+ switch ( val.type() ) {
+ case TQVariant::Date: {
+ DATE_STRUCT * dt = new DATE_STRUCT;
+ tmpStorage.append( qAutoDeleter(dt) );
+ TQDate qdt = val.toDate();
+ dt->year = qdt.year();
+ dt->month = qdt.month();
+ dt->day = qdt.day();
+ r = STQLBindParameter( d->hStmt,
+ para,
+ qParamType[ (int)extension()->values[ it.data() ].typ ],
+ STQL_C_DATE,
+ STQL_DATE,
+ 0,
+ 0,
+ (void *) dt,
+ (TQSTQLLEN)0,
+ *ind == STQL_NULL_DATA ? ind : NULL );
+ break; }
+ case TQVariant::Time: {
+ TIME_STRUCT * dt = new TIME_STRUCT;
+ tmpStorage.append( qAutoDeleter(dt) );
+ TQTime qdt = val.toTime();
+ dt->hour = qdt.hour();
+ dt->minute = qdt.minute();
+ dt->second = qdt.second();
+ r = STQLBindParameter( d->hStmt,
+ para,
+ qParamType[ (int)extension()->values[ it.data() ].typ ],
+ STQL_C_TIME,
+ STQL_TIME,
+ 0,
+ 0,
+ (void *) dt,
+ (TQSTQLLEN)0,
+ *ind == STQL_NULL_DATA ? ind : NULL );
+ break; }
+ case TQVariant::DateTime: {
+ TIMESTAMP_STRUCT * dt = new TIMESTAMP_STRUCT;
+ tmpStorage.append( qAutoDeleter(dt) );
+ TQDateTime qdt = val.toDateTime();
+ dt->year = qdt.date().year();
+ dt->month = qdt.date().month();
+ dt->day = qdt.date().day();
+ dt->hour = qdt.time().hour();
+ dt->minute = qdt.time().minute();
+ dt->second = qdt.time().second();
+ dt->fraction = 0;
+ r = STQLBindParameter( d->hStmt,
+ para,
+ qParamType[ (int)extension()->values[ it.data() ].typ ],
+ STQL_C_TIMESTAMP,
+ STQL_TIMESTAMP,
+ 0,
+ 0,
+ (void *) dt,
+ (TQSTQLLEN)0,
+ *ind == STQL_NULL_DATA ? ind : NULL );
+ break; }
+ case TQVariant::Int: {
+ int * v = new int( val.toInt() );
+ tmpStorage.append( qAutoDeleter(v) );
+ r = STQLBindParameter( d->hStmt,
+ para,
+ qParamType[ (int)extension()->values[ it.data() ].typ ],
+ STQL_C_SLONG,
+ STQL_INTEGER,
+ 0,
+ 0,
+ (void *) v,
+ (TQSTQLLEN)0,
+ *ind == STQL_NULL_DATA ? ind : NULL );
+ break; }
+ case TQVariant::Double: {
+ double * v = new double( val.toDouble() );
+ tmpStorage.append( qAutoDeleter(v) );
+ r = STQLBindParameter( d->hStmt,
+ para,
+ qParamType[ (int)extension()->values[ it.data() ].typ ],
+ STQL_C_DOUBLE,
+ STQL_DOUBLE,
+ 0,
+ 0,
+ (void *) v,
+ (TQSTQLLEN)0,
+ *ind == STQL_NULL_DATA ? ind : NULL );
+ break; }
+ case TQVariant::ByteArray: {
+ if ( *ind != STQL_NULL_DATA ) {
+ *ind = val.asByteArray().size();
+ }
+ r = STQLBindParameter( d->hStmt,
+ para,
+ qParamType[ (int)extension()->values[ it.data() ].typ ],
+ STQL_C_BINARY,
+ STQL_LONGVARBINARY,
+ val.asByteArray().size(),
+ 0,
+ (void *) val.asByteArray().data(),
+ (TQSTQLLEN)val.asByteArray().size(),
+ ind );
+ break; }
+#ifndef TQ_ODBC_VERSION_2
+ case TQVariant::String:
+ if ( d->tqunicode ) {
+ TQString * str = new TQString( val.asString() );
+ str->ucs2();
+ int len = str->length()*2;
+ tmpStorage.append( qAutoDeleter(str) );
+ r = STQLBindParameter( d->hStmt,
+ para,
+ qParamType[ (int)extension()->values[ it.data() ].typ ],
+ STQL_C_WCHAR,
+ len > 8000 ? STQL_WLONGVARCHAR : STQL_WVARCHAR,
+ len > 8000 ? len : 0,
+ 0,
+ (void *) str->tqunicode(),
+ (TQSTQLLEN) len,
+ ind );
+ break;
+ }
+#endif
+ // fall through
+ default: {
+ TQCString * str = new TQCString( val.asString().local8Bit() );
+ tmpStorage.append( qAutoDeleter(str) );
+ r = STQLBindParameter( d->hStmt,
+ para,
+ qParamType[ (int)extension()->values[ it.data() ].typ ],
+ STQL_C_CHAR,
+ str->length() > 4000 ? STQL_LONGVARCHAR : STQL_VARCHAR,
+ str->length() + 1,
+ 0,
+ (void *) str->data(),
+ (TQSTQLLEN)(str->length() + 1),
+ ind );
+ break; }
+ }
+ para++;
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQODBCResult::exec: unable to bind variable: %s", qODBCWarn( d ).local8Bit().data() );
+#endif
+ setLastError( qMakeError( "Unable to bind variable", TQSqlError::Statement, d ) );
+ return FALSE;
+ }
+ }
+ }
+ r = STQLExecute( d->hStmt );
+ if ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQODBCResult::exec: Unable to execute statement: %s", qODBCWarn( d ).local8Bit().data() );
+#endif
+ setLastError( qMakeError( "Unable to execute statement", TQSqlError::Statement, d ) );
+ return FALSE;
+ }
+ STQLSMALLINT count;
+ r = STQLNumResultCols( d->hStmt, &count );
+ if ( count ) {
+ setSelect( TRUE );
+ for ( int i = 0; i < count; ++i ) {
+ d->rInf.append( qMakeFieldInfo( d, i ) );
+ }
+ } else {
+ setSelect( FALSE );
+ }
+ setActive( TRUE );
+
+ //get out parameters
+ if ( extension()->index.count() > 0 ) {
+ TQMap<int, TQString>::Iterator it;
+ for ( it = extension()->index.begin(); it != extension()->index.end(); ++it ) {
+
+ STQLINTEGER* indPtr = qAutoDeleterData( (TQAutoDeleter<STQLINTEGER>*)tmpStorage.getFirst() );
+ if ( !indPtr )
+ return FALSE;
+ bool isNull = (*indPtr == STQL_NULL_DATA);
+ tmpStorage.removeFirst();
+
+ TQVariant::Type type = extension()->values[ it.data() ].value.type();
+ if ( isNull ) {
+ TQVariant v;
+ v.cast(type);
+ extension()->values[ it.data() ].value = v;
+ if (type != TQVariant::ByteArray)
+ tmpStorage.removeFirst();
+ continue;
+ }
+
+ switch (type) {
+ case TQVariant::Date: {
+ DATE_STRUCT * ds = qAutoDeleterData( (TQAutoDeleter<DATE_STRUCT>*)tmpStorage.getFirst() );
+ extension()->values[ it.data() ].value = TQVariant( TQDate( ds->year, ds->month, ds->day ) );
+ break; }
+ case TQVariant::Time: {
+ TIME_STRUCT * dt = qAutoDeleterData( (TQAutoDeleter<TIME_STRUCT>*)tmpStorage.getFirst() );
+ extension()->values[ it.data() ].value = TQVariant( TQTime( dt->hour, dt->minute, dt->second ) );
+ break; }
+ case TQVariant::DateTime: {
+ TIMESTAMP_STRUCT * dt = qAutoDeleterData( (TQAutoDeleter<TIMESTAMP_STRUCT>*)tmpStorage.getFirst() );
+ extension()->values[ it.data() ].value = TQVariant( TQDateTime( TQDate( dt->year, dt->month, dt->day ),
+ TQTime( dt->hour, dt->minute, dt->second ) ) );
+ break; }
+ case TQVariant::Int: {
+ int * v = qAutoDeleterData( (TQAutoDeleter<int>*)tmpStorage.getFirst() );
+ extension()->values[ it.data() ].value = TQVariant( *v );
+ break; }
+ case TQVariant::Double: {
+ double * v = qAutoDeleterData( (TQAutoDeleter<double>*)tmpStorage.getFirst() );
+ extension()->values[ it.data() ].value = TQVariant( *v );
+ break; }
+ case TQVariant::ByteArray:
+ break;
+ case TQVariant::String:
+ if ( d->tqunicode ) {
+ TQString * str = qAutoDeleterData( (TQAutoDeleter<TQString>*)tmpStorage.getFirst() );
+ extension()->values[ it.data() ].value = TQVariant( *str );
+ break;
+ }
+ // fall through
+ default: {
+ TQCString * str = qAutoDeleterData( (TQAutoDeleter<TQCString>*)tmpStorage.getFirst() );
+ extension()->values[ it.data() ].value = TQVariant( *str );
+ break; }
+ }
+ if (type != TQVariant::ByteArray)
+ tmpStorage.removeFirst();
+ }
+ }
+
+ return TRUE;
+}
+
+////////////////////////////////////////
+
+
+TQODBCDriver::TQODBCDriver( TQObject * tqparent, const char * name )
+ : TQSqlDriver(tqparent,name ? name : "TQODBC")
+{
+ init();
+}
+
+TQODBCDriver::TQODBCDriver( STQLHANDLE env, STQLHANDLE con, TQObject * tqparent, const char * name )
+ : TQSqlDriver(tqparent,name ? name : "TQODBC")
+{
+ init();
+ d->hEnv = env;
+ d->hDbc = con;
+ if ( env && con ) {
+ setOpen( TRUE );
+ setOpenError( FALSE );
+ }
+}
+
+void TQODBCDriver::init()
+{
+ qSqlOpenExtDict()->insert( this, new TQODBCOpenExtension(this) );
+ d = new TQODBCPrivate();
+}
+
+TQODBCDriver::~TQODBCDriver()
+{
+ cleanup();
+ delete d;
+ if ( !qSqlOpenExtDict()->isEmpty() ) {
+ TQSqlOpenExtension *ext = qSqlOpenExtDict()->take( this );
+ delete ext;
+ }
+}
+
+bool TQODBCDriver::hasFeature( DriverFeature f ) const
+{
+ switch ( f ) {
+ case Transactions: {
+ if ( !d->hDbc )
+ return FALSE;
+ STQLUSMALLINT txn;
+ STQLSMALLINT t;
+ int r = STQLGetInfo( d->hDbc,
+ (STQLUSMALLINT)STQL_TXN_CAPABLE,
+ &txn,
+ sizeof(txn),
+ &t);
+ if ( r != STQL_SUCCESS || txn == STQL_TC_NONE )
+ return FALSE;
+ else
+ return TRUE;
+ }
+ case QuerySize:
+ return FALSE;
+ case BLOB:
+ return TRUE;
+ case Unicode:
+ return d->tqunicode;
+ case PreparedQueries:
+ return TRUE;
+ case PositionalPlaceholders:
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+bool TQODBCDriver::open( const TQString&,
+ const TQString&,
+ const TQString&,
+ const TQString&,
+ int )
+{
+ qWarning("TQODBCDriver::open(): This version of open() is no longer supported." );
+ return FALSE;
+}
+
+bool TQODBCDriver::open( const TQString & db,
+ const TQString & user,
+ const TQString & password,
+ const TQString &,
+ int,
+ const TQString& connOpts )
+{
+ if ( isOpen() )
+ close();
+ STQLRETURN r;
+ r = STQLAllocHandle( STQL_HANDLE_ENV,
+ STQL_NULL_HANDLE,
+ &d->hEnv);
+ if ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCDriver::open: Unable to allocate environment", d );
+#endif
+ setOpenError( TRUE );
+ return FALSE;
+ }
+ r = STQLSetEnvAttr( d->hEnv,
+ STQL_ATTR_ODBC_VERSION,
+ (STQLPOINTER)STQL_OV_ODBC2,
+ STQL_IS_UINTEGER );
+ r = STQLAllocHandle( STQL_HANDLE_DBC,
+ d->hEnv,
+ &d->hDbc);
+ if ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCDriver::open: Unable to allocate connection", d );
+#endif
+ setOpenError( TRUE );
+ return FALSE;
+ }
+
+ if ( !d->setConnectionOptions( connOpts ) )
+ return FALSE;
+
+ // Create the connection string
+ TQString connTQStr;
+ // support the "DRIVER={SQL SERVER};SERVER=blah" syntax
+ if ( db.tqcontains(".dsn") )
+ connTQStr = "FILEDSN=" + db;
+ else if ( db.tqcontains( "DRIVER" ) || db.tqcontains( "SERVER" ) )
+ connTQStr = db;
+ else
+ connTQStr = "DSN=" + db;
+ connTQStr += ";UID=" + user + ";PWD=" + password;
+ STQLSMALLINT cb;
+ STQLTCHAR connOut[1024];
+ r = STQLDriverConnect( d->hDbc,
+ NULL,
+#ifdef UNICODE
+ (STQLWCHAR*)connTQStr.tqunicode(),
+#else
+ (STQLCHAR*)connTQStr.latin1(),
+#endif
+ (STQLSMALLINT)connTQStr.length(),
+ connOut,
+ 1024,
+ &cb,
+ STQL_DRIVER_NOPROMPT );
+ if ( r != STQL_SUCCESS && r != STQL_SUCCESS_WITH_INFO ) {
+ setLastError( qMakeError( "Unable to connect", TQSqlError::Connection, d ) );
+ setOpenError( TRUE );
+ return FALSE;
+ }
+
+ if ( !d->checkDriver() ) {
+ setLastError( qMakeError( "Unable to connect - Driver doesn't support all needed functionality", TQSqlError::Connection, d ) );
+ setOpenError( TRUE );
+ return FALSE;
+ }
+
+ d->checkUnicode();
+ d->checkSchemaUsage();
+
+ setOpen( TRUE );
+ setOpenError( FALSE );
+ return TRUE;
+}
+
+void TQODBCDriver::close()
+{
+ cleanup();
+ setOpen( FALSE );
+ setOpenError( FALSE );
+}
+
+void TQODBCDriver::cleanup()
+{
+ STQLRETURN r;
+ if ( !d )
+ return;
+
+ if( d->hDbc ) {
+ // Open statements/descriptors handles are automatically cleaned up by STQLDisconnect
+ if ( isOpen() ) {
+ r = STQLDisconnect( d->hDbc );
+#ifdef TQT_CHECK_RANGE
+ if ( r != STQL_SUCCESS )
+ qSqlWarning( "TQODBCDriver::disconnect: Unable to disconnect datasource", d );
+#endif
+ }
+
+ r = STQLFreeHandle( STQL_HANDLE_DBC, d->hDbc );
+#ifdef TQT_CHECK_RANGE
+ if ( r != STQL_SUCCESS )
+ qSqlWarning( "TQODBCDriver::cleanup: Unable to free connection handle", d );
+#endif
+ d->hDbc = 0;
+ }
+
+ if ( d->hEnv ) {
+ r = STQLFreeHandle( STQL_HANDLE_ENV, d->hEnv );
+#ifdef TQT_CHECK_RANGE
+ if ( r != STQL_SUCCESS )
+ qSqlWarning( "TQODBCDriver::cleanup: Unable to free environment handle", d );
+#endif
+ d->hEnv = 0;
+ }
+}
+
+// checks whether the server can return char, varchar and longvarchar
+// as two byte tqunicode characters
+void TQODBCPrivate::checkUnicode()
+{
+#if defined(TQ_WS_WIN)
+ if ( !qt_wintqunicode ) {
+ tqunicode = FALSE;
+ return;
+ }
+#endif
+ STQLRETURN r;
+ STQLUINTEGER fFunc;
+
+ tqunicode = FALSE;
+ r = STQLGetInfo( hDbc,
+ STQL_CONVERT_CHAR,
+ (STQLPOINTER)&fFunc,
+ sizeof(fFunc),
+ NULL );
+ if ( ( r == STQL_SUCCESS || r == STQL_SUCCESS_WITH_INFO ) && ( fFunc & STQL_CVT_WCHAR ) ) {
+ sql_char_type = TQVariant::String;
+ tqunicode = TRUE;
+ }
+
+ r = STQLGetInfo( hDbc,
+ STQL_CONVERT_VARCHAR,
+ (STQLPOINTER)&fFunc,
+ sizeof(fFunc),
+ NULL );
+ if ( ( r == STQL_SUCCESS || r == STQL_SUCCESS_WITH_INFO ) && ( fFunc & STQL_CVT_WVARCHAR ) ) {
+ sql_varchar_type = TQVariant::String;
+ tqunicode = TRUE;
+ }
+
+ r = STQLGetInfo( hDbc,
+ STQL_CONVERT_LONGVARCHAR,
+ (STQLPOINTER)&fFunc,
+ sizeof(fFunc),
+ NULL );
+ if ( ( r == STQL_SUCCESS || r == STQL_SUCCESS_WITH_INFO ) && ( fFunc & STQL_CVT_WLONGVARCHAR ) ) {
+ sql_longvarchar_type = TQVariant::String;
+ tqunicode = TRUE;
+ }
+}
+
+bool TQODBCPrivate::checkDriver() const
+{
+#ifdef ODBC_CHECK_DRIVER
+ // do not query for STQL_API_STQLFETCHSCROLL because it can't be used at this time
+ static const STQLUSMALLINT reqFunc[] = {
+ STQL_API_STQLDESCRIBECOL, STQL_API_STQLGETDATA, STQL_API_STQLCOLUMNS,
+ STQL_API_STQLGETSTMTATTR, STQL_API_STQLGETDIAGREC, STQL_API_STQLEXECDIRECT,
+ STQL_API_STQLGETINFO, STQL_API_STQLTABLES, 0
+ };
+
+ // these functions are optional
+ static const STQLUSMALLINT optFunc[] = {
+ STQL_API_STQLNUMRESULTCOLS, STQL_API_STQLROWCOUNT, 0
+ };
+
+ STQLRETURN r;
+ STQLUSMALLINT sup;
+
+
+ int i;
+ // check the required functions
+ for ( i = 0; reqFunc[ i ] != 0; ++i ) {
+
+ r = STQLGetFunctions( hDbc, reqFunc[ i ], &sup );
+
+#ifdef TQT_CHECK_RANGE
+ if ( r != STQL_SUCCESS ) {
+ qSqlWarning( "TQODBCDriver::checkDriver: Cannot get list of supported functions", this );
+ return FALSE;
+ }
+#endif
+ if ( sup == STQL_FALSE ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning ( "TQODBCDriver::open: Warning - Driver doesn't support all needed functionality (%d). "
+ "Please look at the TQt SQL Module Driver documentation for more information.", reqFunc[ i ] );
+#endif
+ return FALSE;
+ }
+ }
+
+ // these functions are optional and just generate a warning
+ for ( i = 0; optFunc[ i ] != 0; ++i ) {
+
+ r = STQLGetFunctions( hDbc, optFunc[ i ], &sup );
+
+#ifdef TQT_CHECK_RANGE
+ if ( r != STQL_SUCCESS ) {
+ qSqlWarning( "TQODBCDriver::checkDriver: Cannot get list of supported functions", this );
+ return FALSE;
+ }
+#endif
+ if ( sup == STQL_FALSE ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQODBCDriver::checkDriver: Warning - Driver doesn't support some non-critical functions (%d)", optFunc[ i ] );
+#endif
+ return TRUE;
+ }
+ }
+#endif //ODBC_CHECK_DRIVER
+
+ return TRUE;
+}
+
+void TQODBCPrivate::checkSchemaUsage()
+{
+ STQLRETURN r;
+ STQLUINTEGER val;
+
+ r = STQLGetInfo(hDbc,
+ STQL_SCHEMA_USAGE,
+ (STQLPOINTER) &val,
+ sizeof(val),
+ NULL);
+ if (r == STQL_SUCCESS || r == STQL_SUCCESS_WITH_INFO)
+ useSchema = (val != 0);
+}
+
+TQSqlQuery TQODBCDriver::createQuery() const
+{
+ return TQSqlQuery( new TQODBCResult( this, d ) );
+}
+
+bool TQODBCDriver::beginTransaction()
+{
+ if ( !isOpen() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning(" TQODBCDriver::beginTransaction: Database not open" );
+#endif
+ return FALSE;
+ }
+ STQLUINTEGER ac(STQL_AUTOCOMMIT_OFF);
+ STQLRETURN r = STQLSetConnectAttr( d->hDbc,
+ STQL_ATTR_AUTOCOMMIT,
+ (STQLPOINTER)ac,
+ sizeof(ac) );
+ if ( r != STQL_SUCCESS ) {
+ setLastError( qMakeError( "Unable to disable autocommit", TQSqlError::Transaction, d ) );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool TQODBCDriver::commitTransaction()
+{
+ if ( !isOpen() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning(" TQODBCDriver::commitTransaction: Database not open" );
+#endif
+ return FALSE;
+ }
+ STQLRETURN r = STQLEndTran( STQL_HANDLE_DBC,
+ d->hDbc,
+ STQL_COMMIT );
+ if ( r != STQL_SUCCESS ) {
+ setLastError( qMakeError("Unable to commit transaction", TQSqlError::Transaction, d ) );
+ return FALSE;
+ }
+ return endTrans();
+}
+
+bool TQODBCDriver::rollbackTransaction()
+{
+ if ( !isOpen() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning(" TQODBCDriver::rollbackTransaction: Database not open" );
+#endif
+ return FALSE;
+ }
+ STQLRETURN r = STQLEndTran( STQL_HANDLE_DBC,
+ d->hDbc,
+ STQL_ROLLBACK );
+ if ( r != STQL_SUCCESS ) {
+ setLastError( qMakeError( "Unable to rollback transaction", TQSqlError::Transaction, d ) );
+ return FALSE;
+ }
+ return endTrans();
+}
+
+bool TQODBCDriver::endTrans()
+{
+ STQLUINTEGER ac(STQL_AUTOCOMMIT_ON);
+ STQLRETURN r = STQLSetConnectAttr( d->hDbc,
+ STQL_ATTR_AUTOCOMMIT,
+ (STQLPOINTER)ac,
+ sizeof(ac));
+ if ( r != STQL_SUCCESS ) {
+ setLastError( qMakeError( "Unable to enable autocommit", TQSqlError::Transaction, d ) );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+TQStringList TQODBCDriver::tables( const TQString& typeName ) const
+{
+ TQStringList tl;
+ if ( !isOpen() )
+ return tl;
+ int type = typeName.toInt();
+ STQLHANDLE hStmt;
+
+ STQLRETURN r = STQLAllocHandle( STQL_HANDLE_STMT,
+ d->hDbc,
+ &hStmt );
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCDriver::tables: Unable to allocate handle", d );
+#endif
+ return tl;
+ }
+ r = STQLSetStmtAttr( hStmt,
+ STQL_ATTR_CURSOR_TYPE,
+ (STQLPOINTER)STQL_CURSOR_FORWARD_ONLY,
+ STQL_IS_UINTEGER );
+ TQString tableType;
+ if ( typeName.isEmpty() || ((type & (int)TQSql::Tables) == (int)TQSql::Tables) )
+ tableType += "TABLE,";
+ if ( (type & (int)TQSql::Views) == (int)TQSql::Views )
+ tableType += "VIEW,";
+ if ( (type & (int)TQSql::SystemTables) == (int)TQSql::SystemTables )
+ tableType += "SYSTEM TABLE,";
+ if ( tableType.isEmpty() )
+ return tl;
+ tableType.truncate( tableType.length() - 1 );
+
+ r = STQLTables( hStmt,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ 0,
+#ifdef UNICODE
+ (STQLWCHAR*)tableType.tqunicode(),
+#else
+ (STQLCHAR*)tableType.latin1(),
+#endif
+ tableType.length() /* characters, not bytes */ );
+
+#ifdef TQT_CHECK_RANGE
+ if ( r != STQL_SUCCESS )
+ qSqlWarning( "TQODBCDriver::tables Unable to execute table list", d );
+#endif
+ r = STQLFetchScroll( hStmt,
+ STQL_FETCH_NEXT,
+ 0);
+ while ( r == STQL_SUCCESS ) {
+ bool isNull;
+ TQString fieldVal = qGetStringData( hStmt, 2, -1, isNull, d->tqunicode );
+ tl.append( fieldVal );
+ r = STQLFetchScroll( hStmt,
+ STQL_FETCH_NEXT,
+ 0);
+ }
+
+ r = STQLFreeHandle( STQL_HANDLE_STMT, hStmt );
+ if ( r!= STQL_SUCCESS )
+ qSqlWarning( "TQODBCDriver: Unable to free statement handle" + TQString::number(r), d );
+ return tl;
+}
+
+TQSqlIndex TQODBCDriver::primaryIndex( const TQString& tablename ) const
+{
+ TQSqlIndex index( tablename );
+ if ( !isOpen() )
+ return index;
+ bool usingSpecialColumns = FALSE;
+ TQSqlRecord rec = record( tablename );
+
+ STQLHANDLE hStmt;
+ STQLRETURN r = STQLAllocHandle( STQL_HANDLE_STMT,
+ d->hDbc,
+ &hStmt );
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCDriver::primaryIndex: Unable to list primary key", d );
+#endif
+ return index;
+ }
+ TQString catalog, schema, table;
+ d->splitTableQualifier( tablename, catalog, schema, table );
+ r = STQLSetStmtAttr( hStmt,
+ STQL_ATTR_CURSOR_TYPE,
+ (STQLPOINTER)STQL_CURSOR_FORWARD_ONLY,
+ STQL_IS_UINTEGER );
+ r = STQLPrimaryKeys( hStmt,
+#ifdef UNICODE
+ catalog.length() == 0 ? NULL : (STQLWCHAR*)catalog.tqunicode(),
+#else
+ catalog.length() == 0 ? NULL : (STQLCHAR*)catalog.latin1(),
+#endif
+ catalog.length(),
+#ifdef UNICODE
+ schema.length() == 0 ? NULL : (STQLWCHAR*)schema.tqunicode(),
+#else
+ schema.length() == 0 ? NULL : (STQLCHAR*)schema.latin1(),
+#endif
+ schema.length(),
+#ifdef UNICODE
+ (STQLWCHAR*)table.tqunicode(),
+#else
+ (STQLCHAR*)table.latin1(),
+#endif
+ table.length() /* in characters, not in bytes */);
+
+ // if the STQLPrimaryKeys() call does not succeed (e.g the driver
+ // does not support it) - try an alternative method to get hold of
+ // the primary index (e.g MS Access and FoxPro)
+ if ( r != STQL_SUCCESS ) {
+ r = STQLSpecialColumns( hStmt,
+ STQL_BEST_ROWID,
+#ifdef UNICODE
+ catalog.length() == 0 ? NULL : (STQLWCHAR*)catalog.tqunicode(),
+#else
+ catalog.length() == 0 ? NULL : (STQLCHAR*)catalog.latin1(),
+#endif
+ catalog.length(),
+#ifdef UNICODE
+ schema.length() == 0 ? NULL : (STQLWCHAR*)schema.tqunicode(),
+#else
+ schema.length() == 0 ? NULL : (STQLCHAR*)schema.latin1(),
+#endif
+ schema.length(),
+#ifdef UNICODE
+ (STQLWCHAR*)table.tqunicode(),
+#else
+ (STQLCHAR*)table.latin1(),
+#endif
+
+ table.length(),
+ STQL_SCOPE_CURROW,
+ STQL_NULLABLE );
+
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCDriver::primaryIndex: Unable to execute primary key list", d );
+#endif
+ } else {
+ usingSpecialColumns = TRUE;
+ }
+ }
+ r = STQLFetchScroll( hStmt,
+ STQL_FETCH_NEXT,
+ 0 );
+ bool isNull;
+ int fakeId = 0;
+ TQString cName, idxName;
+ // Store all fields in a StringList because some drivers can't detail fields in this FETCH loop
+ while ( r == STQL_SUCCESS ) {
+ if ( usingSpecialColumns ) {
+ cName = qGetStringData( hStmt, 1, -1, isNull, d->tqunicode ); // column name
+ idxName = TQString::number( fakeId++ ); // invent a fake index name
+ } else {
+ cName = qGetStringData( hStmt, 3, -1, isNull, d->tqunicode ); // column name
+ idxName = qGetStringData( hStmt, 5, -1, isNull, d->tqunicode ); // pk index name
+ }
+ TQSqlField *fld = rec.field(cName);
+ if (fld)
+ index.append(*fld);
+ index.setName( idxName );
+ r = STQLFetchScroll( hStmt,
+ STQL_FETCH_NEXT,
+ 0 );
+ }
+ r = STQLFreeHandle( STQL_HANDLE_STMT, hStmt );
+ if ( r!= STQL_SUCCESS )
+ qSqlWarning( "TQODBCDriver: Unable to free statement handle" + TQString::number(r), d );
+ return index;
+}
+
+TQSqlRecord TQODBCDriver::record( const TQString& tablename ) const
+{
+ return recordInfo( tablename ).toRecord();
+}
+
+TQSqlRecord TQODBCDriver::record( const TQSqlQuery& query ) const
+{
+ return recordInfo( query ).toRecord();
+}
+
+TQSqlRecordInfo TQODBCDriver::recordInfo( const TQString& tablename ) const
+{
+ TQSqlRecordInfo fil;
+ if ( !isOpen() )
+ return fil;
+
+ STQLHANDLE hStmt;
+ TQString catalog, schema, table;
+ d->splitTableQualifier( tablename, catalog, schema, table );
+ STQLRETURN r = STQLAllocHandle( STQL_HANDLE_STMT,
+ d->hDbc,
+ &hStmt );
+ if ( r != STQL_SUCCESS ) {
+#ifdef TQT_CHECK_RANGE
+ qSqlWarning( "TQODBCDriver::record: Unable to allocate handle", d );
+#endif
+ return fil;
+ }
+ r = STQLSetStmtAttr( hStmt,
+ STQL_ATTR_CURSOR_TYPE,
+ (STQLPOINTER)STQL_CURSOR_FORWARD_ONLY,
+ STQL_IS_UINTEGER );
+ r = STQLColumns( hStmt,
+#ifdef UNICODE
+ catalog.length() == 0 ? NULL : (STQLWCHAR*)catalog.tqunicode(),
+#else
+ catalog.length() == 0 ? NULL : (STQLCHAR*)catalog.latin1(),
+#endif
+ catalog.length(),
+#ifdef UNICODE
+ schema.length() == 0 ? NULL : (STQLWCHAR*)schema.tqunicode(),
+#else
+ schema.length() == 0 ? NULL : (STQLCHAR*)schema.latin1(),
+#endif
+ schema.length(),
+#ifdef UNICODE
+ (STQLWCHAR*)table.tqunicode(),
+#else
+ (STQLCHAR*)table.latin1(),
+#endif
+ table.length(),
+ NULL,
+ 0 );
+#ifdef TQT_CHECK_RANGE
+ if ( r != STQL_SUCCESS )
+ qSqlWarning( "TQODBCDriver::record: Unable to execute column list", d );
+#endif
+ r = STQLFetchScroll( hStmt,
+ STQL_FETCH_NEXT,
+ 0);
+ // Store all fields in a StringList because some drivers can't detail fields in this FETCH loop
+ while ( r == STQL_SUCCESS ) {
+
+ fil.append( qMakeFieldInfo( hStmt, d ) );
+
+ r = STQLFetchScroll( hStmt,
+ STQL_FETCH_NEXT,
+ 0);
+ }
+
+ r = STQLFreeHandle( STQL_HANDLE_STMT, hStmt );
+ if ( r!= STQL_SUCCESS )
+ qSqlWarning( "TQODBCDriver: Unable to free statement handle " + TQString::number(r), d );
+
+ return fil;
+}
+
+TQSqlRecordInfo TQODBCDriver::recordInfo( const TQSqlQuery& query ) const
+{
+ TQSqlRecordInfo fil;
+ if ( !isOpen() )
+ return fil;
+ if ( query.isActive() && query.driver() == this ) {
+ TQODBCResult* result = (TQODBCResult*)query.result();
+ fil = result->d->rInf;
+ }
+ return fil;
+}
+
+STQLHANDLE TQODBCDriver::environment()
+{
+ return d->hEnv;
+}
+
+STQLHANDLE TQODBCDriver::connection()
+{
+ return d->hDbc;
+}
+
+TQString TQODBCDriver::formatValue( const TQSqlField* field,
+ bool trimStrings ) const
+{
+ TQString r;
+ if ( field->isNull() ) {
+ r = nullText();
+ } else if ( field->type() == TQVariant::DateTime ) {
+ // Use an escape sequence for the datetime fields
+ if ( field->value().toDateTime().isValid() ){
+ TQDate dt = field->value().toDateTime().date();
+ TQTime tm = field->value().toDateTime().time();
+ // Dateformat has to be "yyyy-MM-dd hh:mm:ss", with leading zeroes if month or day < 10
+ r = "{ ts '" +
+ TQString::number(dt.year()) + "-" +
+ TQString::number(dt.month()).rightJustify( 2, '0', TRUE ) + "-" +
+ TQString::number(dt.day()).rightJustify( 2, '0', TRUE ) + " " +
+ tm.toString() +
+ "' }";
+ } else
+ r = nullText();
+ } else if ( field->type() == TQVariant::ByteArray ) {
+ TQByteArray ba = field->value().toByteArray();
+ TQString res;
+ static const char hexchars[] = "0123456789abcdef";
+ for ( uint i = 0; i < ba.size(); ++i ) {
+ uchar s = (uchar) ba[(int)i];
+ res += hexchars[s >> 4];
+ res += hexchars[s & 0x0f];
+ }
+ r = "0x" + res;
+ } else {
+ r = TQSqlDriver::formatValue( field, trimStrings );
+ }
+ return r;
+}
diff --git a/tqtinterface/qt4/src/sql/drivers/odbc/tqsql_odbc.h b/tqtinterface/qt4/src/sql/drivers/odbc/tqsql_odbc.h
new file mode 100644
index 0000000..74ab4e7
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/odbc/tqsql_odbc.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+**
+** Definition of ODBC driver classes
+**
+** Created : 001103
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQL_ODBC_H
+#define TQSQL_ODBC_H
+
+#include <tqmap.h>
+#include <tqstring.h>
+#include <tqsqldriver.h>
+#include <tqsqlfield.h>
+#include <tqsqlresult.h>
+#include <tqsqlindex.h>
+
+#if defined (TQ_OS_WIN32)
+#include <tqt_windows.h>
+#endif
+
+#if defined (TQ_OS_MAC)
+// assume we use iodbc on MAC
+// comment next line out if you use a
+// tqunicode compatible manager
+# define TQ_ODBC_VERSION_2
+#endif
+
+#ifdef TQT_PLUGIN
+#define TQ_EXPORT_STQLDRIVER_ODBC
+#else
+#define TQ_EXPORT_STQLDRIVER_ODBC TQ_EXPORT
+#endif
+
+#ifdef TQ_OS_UNIX
+#define HAVE_LONG_LONG 1 // force UnixODBC NOT to fall back to a struct for BIGINTs
+#endif
+
+#if defined(TQ_CC_BOR)
+// workaround for Borland to make sure that STQLBIGINT is defined
+# define _MSC_VER 900
+#endif
+#include <sql.h>
+#if defined(TQ_CC_BOR)
+# undef _MSC_VER
+#endif
+
+#ifndef TQ_ODBC_VERSION_2
+#include <sqlucode.h>
+#endif
+
+#include <sqlext.h>
+
+class TQODBCPrivate;
+class TQODBCDriver;
+class TQSqlRecordInfo;
+
+class TQODBCResult : public TQSqlResult
+{
+ friend class TQODBCDriver;
+public:
+ TQODBCResult( const TQODBCDriver * db, TQODBCPrivate* p );
+ ~TQODBCResult();
+
+ STQLHANDLE statement();
+ bool prepare( const TQString& query );
+ bool exec();
+
+protected:
+ bool fetchNext();
+ bool fetchFirst();
+ bool fetchLast();
+ bool fetchPrior();
+ bool fetch(int i);
+ bool reset ( const TQString& query );
+ TQVariant data( int field );
+ bool isNull( int field );
+ int size();
+ int numRowsAffected();
+private:
+ TQODBCPrivate* d;
+ typedef TQMap<int,TQVariant> FieldCache;
+ FieldCache fieldCache;
+ typedef TQMap<int,bool> NullCache;
+ NullCache nullCache;
+};
+
+class TQ_EXPORT_STQLDRIVER_ODBC TQODBCDriver : public TQSqlDriver
+{
+public:
+ TQODBCDriver( TQObject * tqparent=0, const char * name=0 );
+ TQODBCDriver( STQLHANDLE env, STQLHANDLE con, TQObject * tqparent=0, const char * name=0 );
+ ~TQODBCDriver();
+ bool hasFeature( DriverFeature f ) const;
+ bool open( const TQString & db,
+ const TQString & user = TQString::null,
+ const TQString & password = TQString::null,
+ const TQString & host = TQString::null,
+ int port = -1 );
+ void close();
+ TQSqlQuery createQuery() const;
+ TQStringList tables( const TQString& user ) const;
+ TQSqlRecord record( const TQString& tablename ) const;
+ TQSqlRecord record( const TQSqlQuery& query ) const;
+ TQSqlRecordInfo recordInfo( const TQString& tablename ) const;
+ TQSqlRecordInfo recordInfo( const TQSqlQuery& query ) const;
+ TQSqlIndex primaryIndex( const TQString& tablename ) const;
+ STQLHANDLE environment();
+ STQLHANDLE connection();
+
+ TQString formatValue( const TQSqlField* field,
+ bool trimStrings ) const;
+ // ### remove me for 4.0
+ bool open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts );
+
+protected:
+ bool beginTransaction();
+ bool commitTransaction();
+ bool rollbackTransaction();
+private:
+ void init();
+ bool endTrans();
+ void cleanup();
+ TQODBCPrivate* d;
+};
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/drivers/psql/tqsql_psql.cpp b/tqtinterface/qt4/src/sql/drivers/psql/tqsql_psql.cpp
new file mode 100644
index 0000000..db233ce
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/psql/tqsql_psql.cpp
@@ -0,0 +1,1117 @@
+/****************************************************************************
+**
+** Implementation of PostgreSQL driver classes
+**
+** Created : 001103
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsql_psql.h"
+#include <private/tqsqlextension_p.h>
+
+#include <math.h>
+
+#include <tqpointarray.h>
+#include <tqsqlrecord.h>
+#include <tqregexp.h>
+#include <tqdatetime.h>
+// PostgreSQL header <utils/elog.h> included by <postgres.h> redefines DEBUG.
+#if defined(DEBUG)
+# undef DEBUG
+#endif
+#include <postgres.h>
+#include <libpq/libpq-fs.h>
+// PostgreSQL header <catalog/pg_type.h> redefines errno erroneously.
+#if defined(errno)
+# undef errno
+#endif
+#define errno qt_psql_errno
+#include <catalog/pg_type.h>
+#undef errno
+#ifdef open
+# undef open
+#endif
+
+TQPtrDict<TQSqlDriverExtension> *qSqlDriverExtDict();
+TQPtrDict<TQSqlOpenExtension> *qSqlOpenExtDict();
+
+class TQPSTQLPrivate
+{
+public:
+ TQPSTQLPrivate():connection(0), result(0), isUtf8(FALSE) {}
+ PGconn *connection;
+ PGresult *result;
+ bool isUtf8;
+};
+
+class TQPSTQLDriverExtension : public TQSqlDriverExtension
+{
+public:
+ TQPSTQLDriverExtension( TQPSTQLDriver *dri )
+ : TQSqlDriverExtension(), driver(dri) { }
+ ~TQPSTQLDriverExtension() {}
+
+ bool isOpen() const;
+private:
+ TQPSTQLDriver *driver;
+};
+
+bool TQPSTQLDriverExtension::isOpen() const
+{
+ return PQstatus( driver->connection() ) == CONNECTION_OK;
+}
+
+class TQPSTQLOpenExtension : public TQSqlOpenExtension
+{
+public:
+ TQPSTQLOpenExtension( TQPSTQLDriver *dri )
+ : TQSqlOpenExtension(), driver(dri) { }
+ ~TQPSTQLOpenExtension() {}
+
+ bool open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts );
+private:
+ TQPSTQLDriver *driver;
+};
+
+bool TQPSTQLOpenExtension::open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts )
+{
+ return driver->open( db, user, password, host, port, connOpts );
+}
+
+static TQSqlError qMakeError( const TQString& err, int type, const TQPSTQLPrivate* p )
+{
+ const char *s = PQerrorMessage(p->connection);
+ TQString msg = p->isUtf8 ? TQString::fromUtf8(s) : TQString::fromLocal8Bit(s);
+ return TQSqlError("TQPSQL: " + err, msg, type);
+}
+
+static TQVariant::Type qDecodePSTQLType( int t )
+{
+ TQVariant::Type type = TQVariant::Invalid;
+ switch ( t ) {
+ case BOOLOID :
+ type = TQVariant::Bool;
+ break;
+ case INT8OID :
+ type = TQVariant::LongLong;
+ break;
+ case INT2OID :
+ // case INT2VECTOROID : // 7.x
+ case INT4OID :
+ type = TQVariant::Int;
+ break;
+ case NUMERICOID :
+ case FLOAT4OID :
+ case FLOAT8OID :
+ type = TQVariant::Double;
+ break;
+ case ABSTIMEOID :
+ case RELTIMEOID :
+ case DATEOID :
+ type = TQVariant::Date;
+ break;
+ case TIMEOID :
+#ifdef TIMETZOID // 7.x
+ case TIMETZOID :
+#endif
+ type = TQVariant::Time;
+ break;
+ case TIMESTAMPOID :
+#ifdef DATETIMEOID
+ // Postgres 6.x datetime workaround.
+ // DATETIMEOID == TIMESTAMPOID (only the names have changed)
+ case DATETIMEOID :
+#endif
+#ifdef TIMESTAMPTZOID
+ // Postgres 7.2 workaround
+ // TIMESTAMPTZOID == TIMESTAMPOID == DATETIMEOID
+ case TIMESTAMPTZOID :
+#endif
+ type = TQVariant::DateTime;
+ break;
+ // case ZPBITOID : // 7.x
+ // case VARBITOID : // 7.x
+ case OIDOID :
+ case BYTEAOID :
+ type = TQVariant::ByteArray;
+ break;
+ case REGPROCOID :
+ case TIDOID :
+ case XIDOID :
+ case CIDOID :
+ // case OIDVECTOROID : // 7.x
+ case UNKNOWNOID :
+ // case TINTERVALOID : // 7.x
+ type = TQVariant::Invalid;
+ break;
+ default:
+ case CHAROID :
+ case BPCHAROID :
+ // case LZTEXTOID : // 7.x
+ case VARCHAROID :
+ case TEXTOID :
+ case NAMEOID :
+ case CASHOID :
+ case INETOID :
+ case CIDROID :
+ case CIRCLEOID :
+ type = TQVariant::String;
+ break;
+ }
+ return type;
+}
+
+TQPSTQLResult::TQPSTQLResult( const TQPSTQLDriver* db, const TQPSTQLPrivate* p )
+: TQSqlResult( db ),
+ currentSize( 0 )
+{
+ d = new TQPSTQLPrivate();
+ (*d) = (*p);
+}
+
+TQPSTQLResult::~TQPSTQLResult()
+{
+ cleanup();
+ delete d;
+}
+
+PGresult* TQPSTQLResult::result()
+{
+ return d->result;
+}
+
+void TQPSTQLResult::cleanup()
+{
+ if ( d->result )
+ PQclear( d->result );
+ d->result = 0;
+ setAt( -1 );
+ currentSize = 0;
+ setActive( FALSE );
+}
+
+bool TQPSTQLResult::fetch( int i )
+{
+ if ( !isActive() )
+ return FALSE;
+ if ( i < 0 )
+ return FALSE;
+ if ( i >= currentSize )
+ return FALSE;
+ if ( at() == i )
+ return TRUE;
+ setAt( i );
+ return TRUE;
+}
+
+bool TQPSTQLResult::fetchFirst()
+{
+ return fetch( 0 );
+}
+
+bool TQPSTQLResult::fetchLast()
+{
+ return fetch( PQntuples( d->result ) - 1 );
+}
+
+// some Postgres conversions
+static TQPoint pointFromString( const TQString& s)
+{
+ // format '(x,y)'
+ int pivot = s.tqfind( ',' );
+ if ( pivot != -1 ) {
+ int x = s.mid( 1, pivot-1 ).toInt();
+ int y = s.mid( pivot+1, s.length()-pivot-2 ).toInt();
+ return TQPoint( x, y ) ;
+ } else
+ return TQPoint();
+}
+
+TQVariant TQPSTQLResult::data( int i )
+{
+ if ( i >= PQnfields( d->result ) ) {
+ qWarning( "TQPSTQLResult::data: column %d out of range", i );
+ return TQVariant();
+ }
+ int ptype = PQftype( d->result, i );
+ TQVariant::Type type = qDecodePSTQLType( ptype );
+ const TQString val = ( d->isUtf8 && ptype != BYTEAOID ) ?
+ TQString::fromUtf8( PQgetvalue( d->result, at(), i ) ) :
+ TQString::fromLocal8Bit( PQgetvalue( d->result, at(), i ) );
+ if ( PQgetisnull( d->result, at(), i ) ) {
+ TQVariant v;
+ v.cast( type );
+ return v;
+ }
+ switch ( type ) {
+ case TQVariant::Bool:
+ {
+ TQVariant b ( (bool)(val == "t"), 0 );
+ return ( b );
+ }
+ case TQVariant::String:
+ return TQVariant( val );
+ case TQVariant::LongLong:
+ if ( val[0] == '-' )
+ return TQVariant( val.toLongLong() );
+ else
+ return TQVariant( val.toULongLong() );
+ case TQVariant::Int:
+ return TQVariant( val.toInt() );
+ case TQVariant::Double:
+ if ( ptype == NUMERICOID )
+ return TQVariant( val );
+ return TQVariant( val.toDouble() );
+ case TQVariant::Date:
+ if ( val.isEmpty() ) {
+ return TQVariant( TQDate() );
+ } else {
+ return TQVariant( TQDate::fromString( val, TQt::ISODate ) );
+ }
+ case TQVariant::Time:
+ if ( val.isEmpty() )
+ return TQVariant( TQTime() );
+ if ( val.at( val.length() - 3 ) == '+' )
+ // strip the timezone
+ return TQVariant( TQTime::fromString( val.left( val.length() - 3 ), TQt::ISODate ) );
+ return TQVariant( TQTime::fromString( val, TQt::ISODate ) );
+ case TQVariant::DateTime: {
+ if ( val.length() < 10 )
+ return TQVariant( TQDateTime() );
+ // remove the timezone
+ TQString dtval = val;
+ if ( dtval.at( dtval.length() - 3 ) == '+' )
+ dtval.truncate( dtval.length() - 3 );
+ // milliseconds are sometimes returned with 2 digits only
+ if ( dtval.at( dtval.length() - 3 ).isPunct() )
+ dtval += '0';
+ if ( dtval.isEmpty() )
+ return TQVariant( TQDateTime() );
+ else
+ return TQVariant( TQDateTime::fromString( dtval, TQt::ISODate ) );
+ }
+ case TQVariant::Point:
+ return TQVariant( pointFromString( val ) );
+ case TQVariant::Rect: // format '(x,y),(x',y')'
+ {
+ int pivot = val.tqfind( "),(" );
+ if ( pivot != -1 )
+ return TQVariant( TQRect( pointFromString( val.mid(pivot+2,val.length()) ), pointFromString( val.mid(0,pivot+1) ) ) );
+ return TQVariant( TQRect() );
+ }
+ case TQVariant::PointArray: // format '((x,y),(x1,y1),...,(xn,yn))'
+ {
+ TQRegExp pointPattern("\\([0-9-]*,[0-9-]*\\)");
+ int points = val.tqcontains( pointPattern );
+ TQPointArray parray( points );
+ int idx = 1;
+ for ( int i = 0; i < points; i++ ){
+ int start = val.tqfind( pointPattern, idx );
+ int end = -1;
+ if ( start != -1 ) {
+ end = val.tqfind( ')', start+1 );
+ if ( end != -1 ) {
+ parray.setPoint( i, pointFromString( val.mid(idx, end-idx+1) ) );
+ }
+ else
+ parray.setPoint( i, TQPoint() );
+ } else {
+ parray.setPoint( i, TQPoint() );
+ break;
+ }
+ idx = end+2;
+ }
+ return TQVariant( parray );
+ }
+ case TQVariant::ByteArray: {
+ if ( ptype == BYTEAOID ) {
+ uint i = 0;
+ int index = 0;
+ uint len = val.length();
+ static const TQChar backslash( '\\' );
+ TQByteArray ba( (int)len );
+ while ( i < len ) {
+ if ( val.at( i ) == backslash ) {
+ if ( val.at( i + 1 ).isDigit() ) {
+ ba[ index++ ] = (char)(val.mid( i + 1, 3 ).toInt( 0, 8 ));
+ i += 4;
+ } else {
+ ba[ index++ ] = val.at( i + 1 );
+ i += 2;
+ }
+ } else {
+ ba[ index++ ] = val.at( i++ ).tqunicode();
+ }
+ }
+ ba.resize( index );
+ return TQVariant( ba );
+ }
+
+ TQByteArray ba;
+ ((TQSqlDriver*)driver())->beginTransaction();
+ Oid oid = val.toInt();
+ int fd = lo_open( d->connection, oid, INV_READ );
+#ifdef TQT_CHECK_RANGE
+ if ( fd < 0) {
+ qWarning( "TQPSTQLResult::data: unable to open large object for read" );
+ ((TQSqlDriver*)driver())->commitTransaction();
+ return TQVariant( ba );
+ }
+#endif
+ int size = 0;
+ int retval = lo_lseek( d->connection, fd, 0L, SEEK_END );
+ if ( retval >= 0 ) {
+ size = lo_tell( d->connection, fd );
+ lo_lseek( d->connection, fd, 0L, SEEK_SET );
+ }
+ if ( size == 0 ) {
+ lo_close( d->connection, fd );
+ ((TQSqlDriver*)driver())->commitTransaction();
+ return TQVariant( ba );
+ }
+ char * buf = new char[ size ];
+
+#ifdef TQ_OS_WIN32
+ // ### For some reason lo_read() fails if we try to read more than
+ // ### 32760 bytes
+ char * p = buf;
+ int nread = 0;
+
+ while( size < nread ){
+ retval = lo_read( d->connection, fd, p, 32760 );
+ nread += retval;
+ p += retval;
+ }
+#else
+ retval = lo_read( d->connection, fd, buf, size );
+#endif
+
+ if (retval < 0) {
+ qWarning( "TQPSTQLResult::data: unable to read large object" );
+ } else {
+ ba.duplicate( buf, size );
+ }
+ delete [] buf;
+ lo_close( d->connection, fd );
+ ((TQSqlDriver*)driver())->commitTransaction();
+ return TQVariant( ba );
+ }
+ default:
+ case TQVariant::Invalid:
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQPSTQLResult::data: unknown data type");
+#endif
+ ;
+ }
+ return TQVariant();
+}
+
+bool TQPSTQLResult::isNull( int field )
+{
+ PQgetvalue( d->result, at(), field );
+ return PQgetisnull( d->result, at(), field );
+}
+
+bool TQPSTQLResult::reset ( const TQString& query )
+{
+ cleanup();
+ if ( !driver() )
+ return FALSE;
+ if ( !driver()->isOpen() || driver()->isOpenError() )
+ return FALSE;
+ setActive( FALSE );
+ setAt( TQSql::BeforeFirst );
+ if ( d->result )
+ PQclear( d->result );
+ if ( d->isUtf8 ) {
+ d->result = PQexec( d->connection, query.utf8().data() );
+ } else {
+ d->result = PQexec( d->connection, query.local8Bit().data() );
+ }
+ int status = PQresultqStatus( d->result );
+ if ( status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK ) {
+ if ( status == PGRES_TUPLES_OK ) {
+ setSelect( TRUE );
+ currentSize = PQntuples( d->result );
+ } else {
+ setSelect( FALSE );
+ currentSize = -1;
+ }
+ setActive( TRUE );
+ return TRUE;
+ }
+ setLastError( qMakeError( "Unable to create query", TQSqlError::Statement, d ) );
+ return FALSE;
+}
+
+int TQPSTQLResult::size()
+{
+ return currentSize;
+}
+
+int TQPSTQLResult::numRowsAffected()
+{
+ return TQString( PQcmdTuples( d->result ) ).toInt();
+}
+
+///////////////////////////////////////////////////////////////////
+
+static bool setEncodingUtf8( PGconn* connection )
+{
+ PGresult* result = PQexec( connection, "SET CLIENT_ENCODING TO 'UNICODE'" );
+ int status = PQresultqStatus( result );
+ PQclear( result );
+ return status == PGRES_COMMAND_OK;
+}
+
+static void setDatestyle( PGconn* connection )
+{
+ PGresult* result = PQexec( connection, "SET DATESTYLE TO 'ISO'" );
+#ifdef TQT_CHECK_RANGE
+ int status = PQresultqStatus( result );
+ if ( status != PGRES_COMMAND_OK )
+ qWarning( "%s", PQerrorMessage( connection ) );
+#endif
+ PQclear( result );
+}
+
+static TQPSTQLDriver::Protocol getPSTQLVersion( PGconn* connection )
+{
+ PGresult* result = PQexec( connection, "select version()" );
+ int status = PQresultqStatus( result );
+ if ( status == PGRES_COMMAND_OK || status == PGRES_TUPLES_OK ) {
+ TQString val( PQgetvalue( result, 0, 0 ) );
+ PQclear( result );
+ TQRegExp rx( "(\\d+)\\.(\\d+)" );
+ rx.setMinimal ( TRUE ); // enforce non-greedy RegExp
+ if ( rx.search( val ) != -1 ) {
+ int vMaj = rx.cap( 1 ).toInt();
+ int vMin = rx.cap( 2 ).toInt();
+ if ( vMaj < 6 ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "This version of PostgreSQL is not supported and may not work." );
+#endif
+ return TQPSTQLDriver::Version6;
+ }
+ if ( vMaj == 6 ) {
+ return TQPSTQLDriver::Version6;
+ } else if ( vMaj == 7 ) {
+ if ( vMin < 1 )
+ return TQPSTQLDriver::Version7;
+ else if ( vMin < 3 )
+ return TQPSTQLDriver::Version71;
+ }
+ return TQPSTQLDriver::Version73;
+ }
+ } else {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "This version of PostgreSQL is not supported and may not work." );
+#endif
+ }
+
+ return TQPSTQLDriver::Version6;
+}
+
+TQPSTQLDriver::TQPSTQLDriver( TQObject * tqparent, const char * name )
+ : TQSqlDriver(tqparent,name ? name : "TQPSQL"), pro( TQPSTQLDriver::Version6 )
+{
+ init();
+}
+
+TQPSTQLDriver::TQPSTQLDriver( PGconn * conn, TQObject * tqparent, const char * name )
+ : TQSqlDriver(tqparent,name ? name : "TQPSQL"), pro( TQPSTQLDriver::Version6 )
+{
+ init();
+ d->connection = conn;
+ if ( conn ) {
+ pro = getPSTQLVersion( d->connection );
+ setOpen( TRUE );
+ setOpenError( FALSE );
+ }
+}
+
+void TQPSTQLDriver::init()
+{
+ qSqlDriverExtDict()->insert( this, new TQPSTQLDriverExtension(this) );
+ qSqlOpenExtDict()->insert( this, new TQPSTQLOpenExtension(this) );
+
+ d = new TQPSTQLPrivate();
+}
+
+TQPSTQLDriver::~TQPSTQLDriver()
+{
+ if ( d->connection )
+ PQfinish( d->connection );
+ delete d;
+ if ( !qSqlDriverExtDict()->isEmpty() ) {
+ TQSqlDriverExtension *ext = qSqlDriverExtDict()->take( this );
+ delete ext;
+ }
+ if ( !qSqlOpenExtDict()->isEmpty() ) {
+ TQSqlOpenExtension *ext = qSqlOpenExtDict()->take( this );
+ delete ext;
+ }
+}
+
+PGconn* TQPSTQLDriver::connection()
+{
+ return d->connection;
+}
+
+
+bool TQPSTQLDriver::hasFeature( DriverFeature f ) const
+{
+ switch ( f ) {
+ case Transactions:
+ return TRUE;
+ case QuerySize:
+ return TRUE;
+ case BLOB:
+ return pro >= TQPSTQLDriver::Version71;
+ case Unicode:
+ return d->isUtf8;
+ default:
+ return FALSE;
+ }
+}
+
+bool TQPSTQLDriver::open( const TQString&,
+ const TQString&,
+ const TQString&,
+ const TQString&,
+ int )
+{
+ qWarning("TQPSTQLDriver::open(): This version of open() is no longer supported." );
+ return FALSE;
+}
+
+bool TQPSTQLDriver::open( const TQString & db,
+ const TQString & user,
+ const TQString & password,
+ const TQString & host,
+ int port,
+ const TQString& connOpts )
+{
+ if ( isOpen() )
+ close();
+ TQString connectString;
+ if ( host.length() )
+ connectString.append( "host=" ).append( host );
+ if ( db.length() )
+ connectString.append( " dbname=" ).append( db );
+ if ( user.length() )
+ connectString.append( " user=" ).append( user );
+ if ( password.length() )
+ connectString.append( " password=" ).append( password );
+ if ( port > -1 )
+ connectString.append( " port=" ).append( TQString::number( port ) );
+
+ // add any connect options - the server will handle error detection
+ if ( !connOpts.isEmpty() )
+ connectString += " " + TQStringList::split( ';', connOpts ).join( " " );
+
+ d->connection = PQconnectdb( connectString.local8Bit().data() );
+ if ( PQstatus( d->connection ) == CONNECTION_BAD ) {
+ setLastError( qMakeError("Unable to connect", TQSqlError::Connection, d ) );
+ setOpenError( TRUE );
+ return FALSE;
+ }
+
+ pro = getPSTQLVersion( d->connection );
+ d->isUtf8 = setEncodingUtf8( d->connection );
+ setDatestyle( d->connection );
+
+ setOpen( TRUE );
+ setOpenError( FALSE );
+ return TRUE;
+}
+
+void TQPSTQLDriver::close()
+{
+ if ( isOpen() ) {
+ if (d->connection)
+ PQfinish( d->connection );
+ d->connection = 0;
+ setOpen( FALSE );
+ setOpenError( FALSE );
+ }
+}
+
+TQSqlQuery TQPSTQLDriver::createQuery() const
+{
+ return TQSqlQuery( new TQPSTQLResult( this, d ) );
+}
+
+bool TQPSTQLDriver::beginTransaction()
+{
+ if ( !isOpen() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQPSTQLDriver::beginTransaction: Database not open" );
+#endif
+ return FALSE;
+ }
+ PGresult* res = PQexec( d->connection, "BEGIN" );
+ if ( !res || PQresultqStatus( res ) != PGRES_COMMAND_OK ) {
+ PQclear( res );
+ setLastError( qMakeError( "Could not begin transaction", TQSqlError::Transaction, d ) );
+ return FALSE;
+ }
+ PQclear( res );
+ return TRUE;
+}
+
+bool TQPSTQLDriver::commitTransaction()
+{
+ if ( !isOpen() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQPSTQLDriver::commitTransaction: Database not open" );
+#endif
+ return FALSE;
+ }
+ PGresult* res = PQexec( d->connection, "COMMIT" );
+ if ( !res || PQresultqStatus( res ) != PGRES_COMMAND_OK ) {
+ PQclear( res );
+ setLastError( qMakeError( "Could not commit transaction", TQSqlError::Transaction, d ) );
+ return FALSE;
+ }
+ PQclear( res );
+ return TRUE;
+}
+
+bool TQPSTQLDriver::rollbackTransaction()
+{
+ if ( !isOpen() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQPSTQLDriver::rollbackTransaction: Database not open" );
+#endif
+ return FALSE;
+ }
+ PGresult* res = PQexec( d->connection, "ROLLBACK" );
+ if ( !res || PQresultqStatus( res ) != PGRES_COMMAND_OK ) {
+ setLastError( qMakeError( "Could not rollback transaction", TQSqlError::Transaction, d ) );
+ PQclear( res );
+ return FALSE;
+ }
+ PQclear( res );
+ return TRUE;
+}
+
+TQStringList TQPSTQLDriver::tables( const TQString& typeName ) const
+{
+ TQStringList tl;
+ if ( !isOpen() )
+ return tl;
+ int type = typeName.toInt();
+ TQSqlQuery t = createQuery();
+ t.setForwardOnly( TRUE );
+
+ if ( typeName.isEmpty() || ((type & (int)TQSql::Tables) == (int)TQSql::Tables) ) {
+
+ TQString query("select relname from pg_class where (relkind = 'r') "
+ "and (relname !~ '^Inv') "
+ "and (relname !~ '^pg_') ");
+ if (pro >= TQPSTQLDriver::Version73)
+ query.append("and (relnamespace not in "
+ "(select oid from pg_namespace where nspname = 'information_schema')) "
+ "and pg_table_is_visible(pg_class.oid) ");
+ t.exec(query);
+ while ( t.next() )
+ tl.append( t.value(0).toString() );
+ }
+ if ( (type & (int)TQSql::Views) == (int)TQSql::Views ) {
+ TQString query("select relname from pg_class where ( relkind = 'v' ) "
+ "and ( relname !~ '^Inv' ) "
+ "and ( relname !~ '^pg_' ) ");
+ if (pro >= TQPSTQLDriver::Version73)
+ query.append("and (relnamespace not in "
+ "(select oid from pg_namespace where nspname = 'information_schema')) "
+ "and pg_table_is_visible(pg_class.oid) ");
+ t.exec(query);
+ while ( t.next() )
+ tl.append( t.value(0).toString() );
+ }
+ if ( (type & (int)TQSql::SystemTables) == (int)TQSql::SystemTables ) {
+ TQString query( "select relname from pg_class where ( relkind = 'r' ) "
+ "and ( relname like 'pg_%' ) " );
+ if (pro >= TQPSTQLDriver::Version73)
+ query.append( "and pg_table_is_visible(pg_class.oid) " );
+ t.exec(query);
+ while ( t.next() )
+ tl.append( t.value(0).toString() );
+ }
+
+ return tl;
+}
+
+TQSqlIndex TQPSTQLDriver::primaryIndex( const TQString& tablename ) const
+{
+ TQSqlIndex idx( tablename );
+ if ( !isOpen() )
+ return idx;
+ TQSqlQuery i = createQuery();
+ TQString stmt;
+
+ switch( pro ) {
+ case TQPSTQLDriver::Version6:
+ stmt = "select pg_att1.attname, int(pg_att1.atttypid), pg_att2.attnum, pg_cl.relname "
+ "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind "
+ "where lower(pg_cl.relname) = '%1_pkey' ";
+ break;
+ case TQPSTQLDriver::Version7:
+ case TQPSTQLDriver::Version71:
+ stmt = "select pg_att1.attname, pg_att1.atttypid::int, pg_cl.relname "
+ "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind "
+ "where lower(pg_cl.relname) = '%1_pkey' ";
+ break;
+ case TQPSTQLDriver::Version73:
+ stmt = "select pg_att1.attname, pg_att1.atttypid::int, pg_cl.relname "
+ "from pg_attribute pg_att1, pg_attribute pg_att2, pg_class pg_cl, pg_index pg_ind "
+ "where lower(pg_cl.relname) = '%1_pkey' "
+ "and pg_table_is_visible(pg_cl.oid) "
+ "and pg_att1.attisdropped = false ";
+ break;
+ }
+ stmt += "and pg_cl.oid = pg_ind.indexrelid "
+ "and pg_att2.attrelid = pg_ind.indexrelid "
+ "and pg_att1.attrelid = pg_ind.indrelid "
+ "and pg_att1.attnum = pg_ind.indkey[pg_att2.attnum-1] "
+ "order by pg_att2.attnum";
+
+ i.exec( stmt.arg( tablename.lower() ) );
+ while ( i.isActive() && i.next() ) {
+ TQSqlField f( i.value(0).toString(), qDecodePSTQLType( i.value(1).toInt() ) );
+ idx.append( f );
+ idx.setName( i.value(2).toString() );
+ }
+ return idx;
+}
+
+TQSqlRecord TQPSTQLDriver::record( const TQString& tablename ) const
+{
+ TQSqlRecord fil;
+ if ( !isOpen() )
+ return fil;
+ TQString stmt;
+ switch( pro ) {
+ case TQPSTQLDriver::Version6:
+ stmt = "select pg_attribute.attname, int(pg_attribute.atttypid) "
+ "from pg_class, pg_attribute "
+ "where lower(pg_class.relname) = '%1' "
+ "and pg_attribute.attnum > 0 "
+ "and pg_attribute.attrelid = pg_class.oid ";
+ break;
+ case TQPSTQLDriver::Version7:
+ case TQPSTQLDriver::Version71:
+ stmt = "select pg_attribute.attname, pg_attribute.atttypid::int "
+ "from pg_class, pg_attribute "
+ "where lower(pg_class.relname) = '%1' "
+ "and pg_attribute.attnum > 0 "
+ "and pg_attribute.attrelid = pg_class.oid ";
+ break;
+ case TQPSTQLDriver::Version73:
+ stmt = "select pg_attribute.attname, pg_attribute.atttypid::int "
+ "from pg_class, pg_attribute "
+ "where lower(pg_class.relname) = '%1' "
+ "and pg_table_is_visible(pg_class.oid) "
+ "and pg_attribute.attnum > 0 "
+ "and pg_attribute.attisdropped = false "
+ "and pg_attribute.attrelid = pg_class.oid ";
+ break;
+ }
+
+ TQSqlQuery fi = createQuery();
+ fi.exec( stmt.arg( tablename.lower() ) );
+ while ( fi.next() ) {
+ TQSqlField f( fi.value(0).toString(), qDecodePSTQLType( fi.value(1).toInt() ) );
+ fil.append( f );
+ }
+ return fil;
+}
+
+TQSqlRecord TQPSTQLDriver::record( const TQSqlQuery& query ) const
+{
+ TQSqlRecord fil;
+ if ( !isOpen() )
+ return fil;
+ if ( query.isActive() && query.driver() == this ) {
+ TQPSTQLResult* result = (TQPSTQLResult*)query.result();
+ int count = PQnfields( result->d->result );
+ for ( int i = 0; i < count; ++i ) {
+ TQString name = PQfname( result->d->result, i );
+ TQVariant::Type type = qDecodePSTQLType( PQftype( result->d->result, i ) );
+ TQSqlField rf( name, type );
+ fil.append( rf );
+ }
+ }
+ return fil;
+}
+
+TQSqlRecordInfo TQPSTQLDriver::recordInfo( const TQString& tablename ) const
+{
+ TQSqlRecordInfo info;
+ if ( !isOpen() )
+ return info;
+
+ TQString stmt;
+ switch( pro ) {
+ case TQPSTQLDriver::Version6:
+ stmt = "select pg_attribute.attname, int(pg_attribute.atttypid), pg_attribute.attnotnull, "
+ "pg_attribute.attlen, pg_attribute.atttypmod, int(pg_attribute.attrelid), pg_attribute.attnum "
+ "from pg_class, pg_attribute "
+ "where lower(pg_class.relname) = '%1' "
+ "and pg_attribute.attnum > 0 "
+ "and pg_attribute.attrelid = pg_class.oid ";
+ break;
+ case TQPSTQLDriver::Version7:
+ stmt = "select pg_attribute.attname, pg_attribute.atttypid::int, pg_attribute.attnotnull, "
+ "pg_attribute.attlen, pg_attribute.atttypmod, pg_attribute.attrelid::int, pg_attribute.attnum "
+ "from pg_class, pg_attribute "
+ "where lower(pg_class.relname) = '%1' "
+ "and pg_attribute.attnum > 0 "
+ "and pg_attribute.attrelid = pg_class.oid ";
+ break;
+ case TQPSTQLDriver::Version71:
+ stmt = "select pg_attribute.attname, pg_attribute.atttypid::int, pg_attribute.attnotnull, "
+ "pg_attribute.attlen, pg_attribute.atttypmod, pg_attrdef.adsrc "
+ "from pg_class, pg_attribute "
+ "left join pg_attrdef on (pg_attrdef.adrelid = pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) "
+ "where lower(pg_class.relname) = '%1' "
+ "and pg_attribute.attnum > 0 "
+ "and pg_attribute.attrelid = pg_class.oid "
+ "order by pg_attribute.attnum ";
+ break;
+ case TQPSTQLDriver::Version73:
+ stmt = "select pg_attribute.attname, pg_attribute.atttypid::int, pg_attribute.attnotnull, "
+ "pg_attribute.attlen, pg_attribute.atttypmod, pg_attrdef.adsrc "
+ "from pg_class, pg_attribute "
+ "left join pg_attrdef on (pg_attrdef.adrelid = pg_attribute.attrelid and pg_attrdef.adnum = pg_attribute.attnum) "
+ "where lower(pg_class.relname) = '%1' "
+ "and pg_table_is_visible(pg_class.oid) "
+ "and pg_attribute.attnum > 0 "
+ "and pg_attribute.attrelid = pg_class.oid "
+ "and pg_attribute.attisdropped = false "
+ "order by pg_attribute.attnum ";
+ break;
+ }
+
+ TQSqlQuery query = createQuery();
+ query.exec( stmt.arg( tablename.lower() ) );
+ if ( pro >= TQPSTQLDriver::Version71 ) {
+ while ( query.next() ) {
+ int len = query.value( 3 ).toInt();
+ int precision = query.value( 4 ).toInt();
+ // swap length and precision if length == -1
+ if ( len == -1 && precision > -1 ) {
+ len = precision - 4;
+ precision = -1;
+ }
+ TQString defVal = query.value( 5 ).toString();
+ if ( !defVal.isEmpty() && defVal.startsWith( "'" ) )
+ defVal = defVal.mid( 1, defVal.length() - 2 );
+ info.append( TQSqlFieldInfo( query.value( 0 ).toString(),
+ qDecodePSTQLType( query.value( 1 ).toInt() ),
+ query.value( 2 ).toBool(),
+ len,
+ precision,
+ defVal,
+ query.value( 1 ).toInt() ) );
+ }
+ } else {
+ // Postgres < 7.1 cannot handle outer joins
+ while ( query.next() ) {
+ TQString defVal;
+ TQString stmt2 = "select pg_attrdef.adsrc from pg_attrdef where "
+ "pg_attrdef.adrelid = %1 and pg_attrdef.adnum = %2 ";
+ TQSqlQuery query2 = createQuery();
+ query2.exec( stmt2.arg( query.value( 5 ).toInt() ).arg( query.value( 6 ).toInt() ) );
+ if ( query2.isActive() && query2.next() )
+ defVal = query2.value( 0 ).toString();
+ if ( !defVal.isEmpty() && defVal.startsWith( "'" ) )
+ defVal = defVal.mid( 1, defVal.length() - 2 );
+ int len = query.value( 3 ).toInt();
+ int precision = query.value( 4 ).toInt();
+ // swap length and precision if length == -1
+ if ( len == -1 && precision > -1 ) {
+ len = precision - 4;
+ precision = -1;
+ }
+ info.append( TQSqlFieldInfo( query.value( 0 ).toString(),
+ qDecodePSTQLType( query.value( 1 ).toInt() ),
+ query.value( 2 ).toBool(),
+ len,
+ precision,
+ defVal,
+ query.value( 1 ).toInt() ) );
+ }
+ }
+
+ return info;
+}
+
+TQSqlRecordInfo TQPSTQLDriver::recordInfo( const TQSqlQuery& query ) const
+{
+ TQSqlRecordInfo info;
+ if ( !isOpen() )
+ return info;
+ if ( query.isActive() && query.driver() == this ) {
+ TQPSTQLResult* result = (TQPSTQLResult*)query.result();
+ int count = PQnfields( result->d->result );
+ for ( int i = 0; i < count; ++i ) {
+ TQString name = PQfname( result->d->result, i );
+ int len = PQfsize( result->d->result, i );
+ int precision = PQfmod( result->d->result, i );
+ // swap length and precision if length == -1
+ if ( len == -1 && precision > -1 ) {
+ len = precision - 4;
+ precision = -1;
+ }
+ info.append( TQSqlFieldInfo( name,
+ qDecodePSTQLType( PQftype( result->d->result, i ) ),
+ -1,
+ len,
+ precision,
+ TQVariant(),
+ PQftype( result->d->result, i ) ) );
+ }
+ }
+ return info;
+}
+
+TQString TQPSTQLDriver::formatValue( const TQSqlField* field,
+ bool ) const
+{
+ TQString r;
+ if ( field->isNull() ) {
+ r = nullText();
+ } else {
+ switch ( field->type() ) {
+ case TQVariant::DateTime:
+ if ( field->value().toDateTime().isValid() ) {
+ TQDate dt = field->value().toDateTime().date();
+ TQTime tm = field->value().toDateTime().time();
+ // msecs need to be right aligned otherwise psql
+ // interpretes them wrong
+ r = "'" + TQString::number( dt.year() ) + "-" +
+ TQString::number( dt.month() ) + "-" +
+ TQString::number( dt.day() ) + " " +
+ tm.toString() + "." +
+ TQString::number( tm.msec() ).rightJustify( 3, '0' ) + "'";
+ } else {
+ r = nullText();
+ }
+ break;
+ case TQVariant::Time:
+ if ( field->value().toTime().isValid() ) {
+ r = field->value().toTime().toString( TQt::ISODate );
+ } else {
+ r = nullText();
+ }
+ case TQVariant::String:
+ case TQVariant::CString: {
+ switch ( field->value().type() ) {
+ case TQVariant::Rect: {
+ TQRect rec = field->value().toRect();
+ // upper right corner then lower left according to psql docs
+ r = "'(" + TQString::number( rec.right() ) +
+ "," + TQString::number( rec.bottom() ) +
+ "),(" + TQString::number( rec.left() ) +
+ "," + TQString::number( rec.top() ) + ")'";
+ break;
+ }
+ case TQVariant::Point: {
+ TQPoint p = field->value().toPoint();
+ r = "'(" + TQString::number( p.x() ) +
+ "," + TQString::number( p.y() ) + ")'";
+ break;
+ }
+ case TQVariant::PointArray: {
+ TQPointArray pa = field->value().toPointArray();
+ r = "' ";
+ for ( int i = 0; i < (int)pa.size(); ++i ) {
+ r += "(" + TQString::number( pa[i].x() ) +
+ "," + TQString::number( pa[i].y() ) + "),";
+ }
+ r.truncate( r.length() - 1 );
+ r += "'";
+ break;
+ }
+ default:
+ // Escape '\' characters
+ r = TQSqlDriver::formatValue( field );
+ r.tqreplace( "\\", "\\\\" );
+ break;
+ }
+ break;
+ }
+ case TQVariant::Bool:
+ if ( field->value().toBool() )
+ r = "TRUE";
+ else
+ r = "FALSE";
+ break;
+ case TQVariant::ByteArray: {
+ TQByteArray ba = field->value().asByteArray();
+ TQString res;
+ r = "'";
+ unsigned char uc;
+ for ( int i = 0; i < (int)ba.size(); ++i ) {
+ uc = (unsigned char) ba[ i ];
+ if ( uc > 40 && uc < 92 ) {
+ r += uc;
+ } else {
+ r += "\\\\";
+ r += TQString::number( (unsigned char) ba[ i ], 8 ).rightJustify( 3, '0', TRUE );
+ }
+ }
+ r += "'";
+ break;
+ }
+ default:
+ r = TQSqlDriver::formatValue( field );
+ break;
+ }
+ }
+ return r;
+}
diff --git a/tqtinterface/qt4/src/sql/drivers/psql/tqsql_psql.h b/tqtinterface/qt4/src/sql/drivers/psql/tqsql_psql.h
new file mode 100644
index 0000000..c005107
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/psql/tqsql_psql.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Definition of PostgreSQL driver classes
+**
+** Created : 001103
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQL_PSTQL_H
+#define TQSQL_PSTQL_H
+
+#include <tqsqlresult.h>
+#include <tqsqlfield.h>
+#include <tqsqldriver.h>
+#include <libpq-fe.h>
+
+#ifdef TQT_PLUGIN
+#define TQ_EXPORT_STQLDRIVER_PSQL
+#else
+#define TQ_EXPORT_STQLDRIVER_PSQL TQ_EXPORT
+#endif
+
+class TQPSTQLPrivate;
+class TQPSTQLDriver;
+class TQSqlRecordInfo;
+
+class TQPSTQLResult : public TQSqlResult
+{
+ friend class TQPSTQLDriver;
+public:
+ TQPSTQLResult( const TQPSTQLDriver* db, const TQPSTQLPrivate* p );
+ ~TQPSTQLResult();
+ PGresult* result();
+protected:
+ void cleanup();
+ bool fetch( int i );
+ bool fetchFirst();
+ bool fetchLast();
+ TQVariant data( int i );
+ bool isNull( int field );
+ bool reset ( const TQString& query );
+ int size();
+ int numRowsAffected();
+private:
+ int currentSize;
+ TQPSTQLPrivate* d;
+};
+
+class TQ_EXPORT_STQLDRIVER_PSQL TQPSTQLDriver : public TQSqlDriver
+{
+public:
+ enum Protocol {
+ Version6 = 6,
+ Version7 = 7,
+ Version71 = 8,
+ Version73 = 9
+ };
+
+ TQPSTQLDriver( TQObject * tqparent=0, const char * name=0 );
+ TQPSTQLDriver( PGconn * conn, TQObject * tqparent=0, const char * name=0 );
+ ~TQPSTQLDriver();
+ bool hasFeature( DriverFeature f ) const;
+ bool open( const TQString & db,
+ const TQString & user = TQString::null,
+ const TQString & password = TQString::null,
+ const TQString & host = TQString::null,
+ int port = -1 );
+ void close();
+ TQSqlQuery createQuery() const;
+ TQStringList tables( const TQString& user ) const;
+ TQSqlIndex primaryIndex( const TQString& tablename ) const;
+ TQSqlRecord record( const TQString& tablename ) const;
+ TQSqlRecord record( const TQSqlQuery& query ) const;
+ TQSqlRecordInfo recordInfo( const TQString& tablename ) const;
+ TQSqlRecordInfo recordInfo( const TQSqlQuery& query ) const;
+
+ Protocol protocol() const { return pro; }
+ PGconn* connection();
+ TQString formatValue( const TQSqlField* field,
+ bool trimStrings ) const;
+
+ // ### remove me for 4.0
+ bool open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts );
+protected:
+ bool beginTransaction();
+ bool commitTransaction();
+ bool rollbackTransaction();
+private:
+ void init();
+ Protocol pro;
+ TQPSTQLPrivate* d;
+};
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/drivers/sqlite/tqsql_sqlite.cpp b/tqtinterface/qt4/src/sql/drivers/sqlite/tqsql_sqlite.cpp
new file mode 100644
index 0000000..c94f595
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/sqlite/tqsql_sqlite.cpp
@@ -0,0 +1,513 @@
+/****************************************************************************
+**
+** Implementation of STQLite driver classes.
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+** EDITIONS: FREE, ENTERPRISE
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "tqsql_sqlite.h"
+
+#include <tqdatetime.h>
+#include <tqregexp.h>
+#include <tqfile.h>
+
+#if (TQT_VERSION-0 < 0x030000)
+# include <tqvector.h>
+# if !defined TQ_WS_WIN32
+# include <unistd.h>
+# endif
+# include "../../../3rdparty/libraries/sqlite/sqlite.h"
+#else
+# include <tqptrvector.h>
+# if !defined TQ_WS_WIN32
+# include <unistd.h>
+# endif
+# include <sqlite.h>
+#endif
+
+typedef struct sqlite_vm sqlite_vm;
+
+#define TQSQLITE_DRIVER_NAME "TQSQLITE"
+
+static TQSqlVariant::Type nameToType(const TQString& typeName)
+{
+ TQString tName = typeName.upper();
+ if (tName.startsWith("INT"))
+ return TQSqlVariant::Int;
+ if (tName.startsWith("FLOAT") || tName.startsWith("NUMERIC"))
+ return TQSqlVariant::Double;
+ if (tName.startsWith("BOOL"))
+ return TQSqlVariant::Bool;
+ // STQLite is typeless - consider everything else as string
+ return TQSqlVariant::String;
+}
+
+class TQSTQLiteDriverPrivate
+{
+public:
+ TQSTQLiteDriverPrivate();
+ sqlite *access;
+ bool utf8;
+};
+
+TQSTQLiteDriverPrivate::TQSTQLiteDriverPrivate() : access(0)
+{
+ utf8 = (qstrcmp(sqlite_encoding, "UTF-8") == 0);
+}
+
+class TQSTQLiteResultPrivate
+{
+public:
+ TQSTQLiteResultPrivate(TQSTQLiteResult *res);
+ void cleanup();
+ bool fetchNext(TQtSqlCachedResult::RowCache *row);
+ bool isSelect();
+ // initializes the recordInfo and the cache
+ void init(const char **cnames, int numCols, TQtSqlCachedResult::RowCache **row = 0);
+ void finalize();
+
+ TQSTQLiteResult* q;
+ sqlite *access;
+
+ // and we have too keep our own struct for the data (sqlite works via
+ // callback.
+ const char *currentTail;
+ sqlite_vm *currentMachine;
+
+ uint skippedtqStatus: 1; // the status of the fetchNext() that's skipped
+ TQtSqlCachedResult::RowCache *skipRow;
+
+ uint utf8: 1;
+ TQSqlRecordInfo rInf;
+};
+
+static const uint initial_cache_size = 128;
+
+TQSTQLiteResultPrivate::TQSTQLiteResultPrivate(TQSTQLiteResult* res) : q(res), access(0), currentTail(0),
+ currentMachine(0), skippedtqStatus(FALSE), skipRow(0), utf8(FALSE)
+{
+}
+
+void TQSTQLiteResultPrivate::cleanup()
+{
+ finalize();
+ rInf.clear();
+ currentTail = 0;
+ currentMachine = 0;
+ skippedtqStatus = FALSE;
+ delete skipRow;
+ skipRow = 0;
+ q->setAt(TQSql::BeforeFirst);
+ q->setActive(FALSE);
+ q->cleanup();
+}
+
+void TQSTQLiteResultPrivate::finalize()
+{
+ if (!currentMachine)
+ return;
+
+ char* err = 0;
+ int res = sqlite_finalize(currentMachine, &err);
+ if (err) {
+ q->setLastError(TQSqlError("Unable to fetch results", err, TQSqlError::Statement, res));
+ sqlite_freemem(err);
+ }
+ currentMachine = 0;
+}
+
+// called on first fetch
+void TQSTQLiteResultPrivate::init(const char **cnames, int numCols, TQtSqlCachedResult::RowCache **row)
+{
+ if (!cnames)
+ return;
+
+ rInf.clear();
+ if (numCols <= 0)
+ return;
+
+ for (int i = 0; i < numCols; ++i) {
+ const char* lastDot = strrchr(cnames[i], '.');
+ const char* fieldName = lastDot ? lastDot + 1 : cnames[i];
+ rInf.append(TQSqlFieldInfo(fieldName, nameToType(cnames[i+numCols])));
+ }
+ // skip the first fetch
+ if (row && !*row) {
+ *row = new TQtSqlCachedResult::RowCache(numCols);
+ skipRow = *row;
+ }
+}
+
+bool TQSTQLiteResultPrivate::fetchNext(TQtSqlCachedResult::RowCache* row)
+{
+ // may be caching.
+ const char **fvals;
+ const char **cnames;
+ int colNum;
+ int res;
+ int i;
+
+ if (skipRow) {
+ // already fetched
+ if (row)
+ *row = *skipRow;
+ delete skipRow;
+ skipRow = 0;
+ return skippedtqStatus;
+ }
+
+ if (!currentMachine)
+ return FALSE;
+
+ // keep trying while busy, wish I could implement this better.
+ while ((res = sqlite_step(currentMachine, &colNum, &fvals, &cnames)) == STQLITE_BUSY) {
+ // sleep instead requesting result again immidiately.
+#if defined TQ_WS_WIN32
+ Sleep(1000);
+#else
+ sleep(1);
+#endif
+ }
+
+ switch(res) {
+ case STQLITE_ROW:
+ // check to see if should fill out columns
+ if (rInf.isEmpty())
+ // must be first call.
+ init(cnames, colNum, &row);
+ if (!fvals)
+ return FALSE;
+ if (!row)
+ return TRUE;
+ for (i = 0; i < colNum; ++i)
+ (*row)[i] = utf8 ? TQString::fromUtf8(fvals[i]) : TQString(fvals[i]);
+ return TRUE;
+ case STQLITE_DONE:
+ if (rInf.isEmpty())
+ // must be first call.
+ init(cnames, colNum);
+ q->setAt(TQSql::AfterLast);
+ return FALSE;
+ case STQLITE_ERROR:
+ case STQLITE_MISUSE:
+ default:
+ // something wrong, don't get col info, but still return false
+ finalize(); // finalize to get the error message.
+ q->setAt(TQSql::AfterLast);
+ return FALSE;
+ }
+ return FALSE;
+}
+
+TQSTQLiteResult::TQSTQLiteResult(const TQSTQLiteDriver* db)
+: TQtSqlCachedResult(db)
+{
+ d = new TQSTQLiteResultPrivate(this);
+ d->access = db->d->access;
+ d->utf8 = db->d->utf8;
+}
+
+TQSTQLiteResult::~TQSTQLiteResult()
+{
+ d->cleanup();
+ delete d;
+}
+
+/*
+ Execute \a query.
+*/
+bool TQSTQLiteResult::reset (const TQString& query)
+{
+ // this is where we build a query.
+ if (!driver())
+ return FALSE;
+ if (!driver()-> isOpen() || driver()->isOpenError())
+ return FALSE;
+
+ d->cleanup();
+
+ // Um, ok. callback based so.... pass private static function for this.
+ setSelect(FALSE);
+ char *err = 0;
+ int res = sqlite_compile(d->access,
+ d->utf8 ? (const char*)query.utf8().data() : query.ascii(),
+ &(d->currentTail),
+ &(d->currentMachine),
+ &err);
+ if (res != STQLITE_OK || err) {
+ setLastError(TQSqlError("Unable to execute statement", err, TQSqlError::Statement, res));
+ sqlite_freemem(err);
+ }
+ //if (*d->currentTail != '\000' then there is more sql to eval
+ if (!d->currentMachine) {
+ setActive(FALSE);
+ return FALSE;
+ }
+ // we have to fetch one row to tqfind out about
+ // the structure of the result set
+ d->skippedtqStatus = d->fetchNext(0);
+ setSelect(!d->rInf.isEmpty());
+ if (isSelect())
+ init(d->rInf.count());
+ setActive(TRUE);
+ return TRUE;
+}
+
+bool TQSTQLiteResult::gotoNext(TQtSqlCachedResult::RowCache* row)
+{
+ return d->fetchNext(row);
+}
+
+int TQSTQLiteResult::size()
+{
+ return -1;
+}
+
+int TQSTQLiteResult::numRowsAffected()
+{
+ return sqlite_changes(d->access);
+}
+
+/////////////////////////////////////////////////////////
+
+TQSTQLiteDriver::TQSTQLiteDriver(TQObject * tqparent, const char * name)
+ : TQSqlDriver(tqparent, name ? name : TQSQLITE_DRIVER_NAME)
+{
+ d = new TQSTQLiteDriverPrivate();
+}
+
+TQSTQLiteDriver::TQSTQLiteDriver(sqlite *connection, TQObject *tqparent, const char *name)
+ : TQSqlDriver(tqparent, name ? name : TQSQLITE_DRIVER_NAME)
+{
+ d = new TQSTQLiteDriverPrivate();
+ d->access = connection;
+ setOpen(TRUE);
+ setOpenError(FALSE);
+}
+
+
+TQSTQLiteDriver::~TQSTQLiteDriver()
+{
+ delete d;
+}
+
+bool TQSTQLiteDriver::hasFeature(DriverFeature f) const
+{
+ switch (f) {
+ case Transactions:
+ return TRUE;
+#if (TQT_VERSION-0 >= 0x030000)
+ case Unicode:
+ return d->utf8;
+#endif
+// case BLOB:
+ default:
+ return FALSE;
+ }
+}
+
+/*
+ STQLite dbs have no user name, passwords, hosts or ports.
+ just file names.
+*/
+bool TQSTQLiteDriver::open(const TQString & db, const TQString &, const TQString &, const TQString &, int, const TQString &)
+{
+ if (isOpen())
+ close();
+
+ if (db.isEmpty())
+ return FALSE;
+
+ char* err = 0;
+ d->access = sqlite_open(TQFile::encodeName(db), 0, &err);
+ if (err) {
+ setLastError(TQSqlError("Error to open database", err, TQSqlError::Connection));
+ sqlite_freemem(err);
+ err = 0;
+ }
+
+ if (d->access) {
+ setOpen(TRUE);
+ setOpenError(FALSE);
+ return TRUE;
+ }
+ setOpenError(TRUE);
+ return FALSE;
+}
+
+void TQSTQLiteDriver::close()
+{
+ if (isOpen()) {
+ sqlite_close(d->access);
+ d->access = 0;
+ setOpen(FALSE);
+ setOpenError(FALSE);
+ }
+}
+
+TQSqlQuery TQSTQLiteDriver::createQuery() const
+{
+ return TQSqlQuery(new TQSTQLiteResult(this));
+}
+
+bool TQSTQLiteDriver::beginTransaction()
+{
+ if (!isOpen() || isOpenError())
+ return FALSE;
+
+ char* err;
+ int res = sqlite_exec(d->access, "BEGIN", 0, this, &err);
+
+ if (res == STQLITE_OK)
+ return TRUE;
+
+ setLastError(TQSqlError("Unable to begin transaction", err, TQSqlError::Transaction, res));
+ sqlite_freemem(err);
+ return FALSE;
+}
+
+bool TQSTQLiteDriver::commitTransaction()
+{
+ if (!isOpen() || isOpenError())
+ return FALSE;
+
+ char* err;
+ int res = sqlite_exec(d->access, "COMMIT", 0, this, &err);
+
+ if (res == STQLITE_OK)
+ return TRUE;
+
+ setLastError(TQSqlError("Unable to commit transaction", err, TQSqlError::Transaction, res));
+ sqlite_freemem(err);
+ return FALSE;
+}
+
+bool TQSTQLiteDriver::rollbackTransaction()
+{
+ if (!isOpen() || isOpenError())
+ return FALSE;
+
+ char* err;
+ int res = sqlite_exec(d->access, "ROLLBACK", 0, this, &err);
+
+ if (res == STQLITE_OK)
+ return TRUE;
+
+ setLastError(TQSqlError("Unable to rollback Transaction", err, TQSqlError::Transaction, res));
+ sqlite_freemem(err);
+ return FALSE;
+}
+
+TQStringList TQSTQLiteDriver::tables(const TQString &typeName) const
+{
+ TQStringList res;
+ if (!isOpen())
+ return res;
+ int type = typeName.toInt();
+
+ TQSqlQuery q = createQuery();
+ q.setForwardOnly(TRUE);
+#if (TQT_VERSION-0 >= 0x030000)
+ if ((type & (int)TQSql::Tables) && (type & (int)TQSql::Views))
+ q.exec("SELECT name FROM sqlite_master WHERE type='table' OR type='view'");
+ else if (typeName.isEmpty() || (type & (int)TQSql::Tables))
+ q.exec("SELECT name FROM sqlite_master WHERE type='table'");
+ else if (type & (int)TQSql::Views)
+ q.exec("SELECT name FROM sqlite_master WHERE type='view'");
+#else
+ q.exec("SELECT name FROM sqlite_master WHERE type='table' OR type='view'");
+#endif
+
+
+ if (q.isActive()) {
+ while(q.next())
+ res.append(q.value(0).toString());
+ }
+
+#if (TQT_VERSION-0 >= 0x030000)
+ if (type & (int)TQSql::SystemTables) {
+ // there are no internal tables beside this one:
+ res.append("sqlite_master");
+ }
+#endif
+
+ return res;
+}
+
+TQSqlIndex TQSTQLiteDriver::primaryIndex(const TQString &tblname) const
+{
+ TQSqlRecordInfo rec(recordInfo(tblname)); // expensive :(
+
+ if (!isOpen())
+ return TQSqlIndex();
+
+ TQSqlQuery q = createQuery();
+ q.setForwardOnly(TRUE);
+ // finrst tqfind a UNITQUE INDEX
+ q.exec("PRAGMA index_list('" + tblname + "');");
+ TQString indexname;
+ while(q.next()) {
+ if (q.value(2).toInt()==1) {
+ indexname = q.value(1).toString();
+ break;
+ }
+ }
+ if (indexname.isEmpty())
+ return TQSqlIndex();
+
+ q.exec("PRAGMA index_info('" + indexname + "');");
+
+ TQSqlIndex index(tblname, indexname);
+ while(q.next()) {
+ TQString name = q.value(2).toString();
+ TQSqlVariant::Type type = TQSqlVariant::Invalid;
+ if (rec.tqcontains(name))
+ type = rec.tqfind(name).type();
+ index.append(TQSqlField(name, type));
+ }
+ return index;
+}
+
+TQSqlRecordInfo TQSTQLiteDriver::recordInfo(const TQString &tbl) const
+{
+ if (!isOpen())
+ return TQSqlRecordInfo();
+
+ TQSqlQuery q = createQuery();
+ q.setForwardOnly(TRUE);
+ q.exec("SELECT * FROM " + tbl + " LIMIT 1");
+ return recordInfo(q);
+}
+
+TQSqlRecord TQSTQLiteDriver::record(const TQString &tblname) const
+{
+ if (!isOpen())
+ return TQSqlRecord();
+
+ return recordInfo(tblname).toRecord();
+}
+
+TQSqlRecord TQSTQLiteDriver::record(const TQSqlQuery& query) const
+{
+ if (query.isActive() && query.driver() == this) {
+ TQSTQLiteResult* result = (TQSTQLiteResult*)query.result();
+ return result->d->rInf.toRecord();
+ }
+ return TQSqlRecord();
+}
+
+TQSqlRecordInfo TQSTQLiteDriver::recordInfo(const TQSqlQuery& query) const
+{
+ if (query.isActive() && query.driver() == this) {
+ TQSTQLiteResult* result = (TQSTQLiteResult*)query.result();
+ return result->d->rInf;
+ }
+ return TQSqlRecordInfo();
+}
diff --git a/tqtinterface/qt4/src/sql/drivers/sqlite/tqsql_sqlite.h b/tqtinterface/qt4/src/sql/drivers/sqlite/tqsql_sqlite.h
new file mode 100644
index 0000000..5350ba1
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/drivers/sqlite/tqsql_sqlite.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Definition of STQLite driver classes.
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+** EDITIONS: FREE, ENTERPRISE
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef TQSQL_STQLITE_H
+#define TQSQL_STQLITE_H
+
+#include <tqsqldriver.h>
+#include <tqsqlresult.h>
+#include <tqsqlrecord.h>
+#include <tqsqlindex.h>
+#include "../cache/tqsqlcachedresult.h"
+
+#if (TQT_VERSION-0 >= 0x030000)
+typedef TQVariant TQSqlVariant;
+#endif
+
+#if defined (TQ_OS_WIN32)
+# include <tqt_windows.h>
+#endif
+
+class TQSTQLiteDriverPrivate;
+class TQSTQLiteResultPrivate;
+class TQSTQLiteDriver;
+struct sqlite;
+
+class TQSTQLiteResult : public TQtSqlCachedResult
+{
+ friend class TQSTQLiteDriver;
+ friend class TQSTQLiteResultPrivate;
+public:
+ TQSTQLiteResult(const TQSTQLiteDriver* db);
+ ~TQSTQLiteResult();
+
+protected:
+ bool gotoNext(TQtSqlCachedResult::RowCache* row);
+ bool reset (const TQString& query);
+ int size();
+ int numRowsAffected();
+
+private:
+ TQSTQLiteResultPrivate* d;
+};
+
+class TQSTQLiteDriver : public TQSqlDriver
+{
+ friend class TQSTQLiteResult;
+public:
+ TQSTQLiteDriver(TQObject *tqparent = 0, const char *name = 0);
+ TQSTQLiteDriver(sqlite *connection, TQObject *tqparent = 0, const char *name = 0);
+ ~TQSTQLiteDriver();
+ bool hasFeature(DriverFeature f) const;
+ bool open(const TQString & db,
+ const TQString & user,
+ const TQString & password,
+ const TQString & host,
+ int port,
+ const TQString & connOpts);
+ bool open( const TQString & db,
+ const TQString & user,
+ const TQString & password,
+ const TQString & host,
+ int port ) { return open (db, user, password, host, port, TQString()); }
+ void close();
+ TQSqlQuery createQuery() const;
+ bool beginTransaction();
+ bool commitTransaction();
+ bool rollbackTransaction();
+ TQStringList tables(const TQString& user) const;
+
+ TQSqlRecord record(const TQString& tablename) const;
+ TQSqlRecordInfo recordInfo(const TQString& tablename) const;
+ TQSqlIndex primaryIndex(const TQString &table) const;
+ TQSqlRecord record(const TQSqlQuery& query) const;
+ TQSqlRecordInfo recordInfo(const TQSqlQuery& query) const;
+
+private:
+ TQSTQLiteDriverPrivate* d;
+};
+#endif
diff --git a/tqtinterface/qt4/src/sql/qt_sql.pri b/tqtinterface/qt4/src/sql/qt_sql.pri
new file mode 100644
index 0000000..198edee
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/qt_sql.pri
@@ -0,0 +1,254 @@
+# Qt sql module
+
+sql {
+
+ !table {
+ message(table must be enabled for sql support)
+ REQUIRES += table
+ }
+
+ SQL_P = sql
+ HEADERS += $$SQL_H/tqsql.h \
+ $$SQL_H/tqsqlquery.h \
+ $$SQL_H/tqsqldatabase.h \
+ $$SQL_H/tqsqlfield.h \
+ $$SQL_H/tqsqlrecord.h \
+ $$SQL_H/tqsqlcursor.h \
+ $$SQL_H/tqsqlform.h \
+ $$SQL_H/tqeditorfactory.h \
+ $$SQL_H/tqsqleditorfactory.h \
+ $$SQL_H/tqsqldriver.h \
+ $$SQL_P/tqsqldriverinterface_p.h \
+ $$SQL_P/tqsqlextension_p.h \
+ $$SQL_H/tqsqldriverplugin.h \
+ $$SQL_H/tqsqlerror.h \
+ $$SQL_H/tqsqlresult.h \
+ $$SQL_H/tqsqlindex.h \
+ $$SQL_H/tqsqlpropertymap.h \
+ $$SQL_P/tqsqlmanager_p.h \
+ $$SQL_H/tqdatatable.h \
+ $$SQL_H/tqdataview.h \
+ $$SQL_H/tqdatabrowser.h \
+ $$SQL_H/tqsqlselectcursor.h
+
+ SOURCES += $$SQL_CPP/tqsqlquery.cpp \
+ $$SQL_CPP/tqsqldatabase.cpp \
+ $$SQL_CPP/tqsqlfield.cpp \
+ $$SQL_CPP/tqsqlrecord.cpp \
+ $$SQL_CPP/tqsqlform.cpp \
+ $$SQL_CPP/tqsqlcursor.cpp \
+ $$SQL_CPP/tqeditorfactory.cpp \
+ $$SQL_CPP/tqsqleditorfactory.cpp \
+ $$SQL_CPP/tqsqldriver.cpp \
+ $$SQL_CPP/tqsqlextension_p.cpp \
+ $$SQL_CPP/tqsqldriverplugin.cpp \
+ $$SQL_CPP/tqsqlerror.cpp \
+ $$SQL_CPP/tqsqlresult.cpp \
+ $$SQL_CPP/tqsqlindex.cpp \
+ $$SQL_CPP/tqsqlpropertymap.cpp \
+ $$SQL_CPP/tqsqlmanager_p.cpp \
+ $$SQL_CPP/tqdatatable.cpp \
+ $$SQL_CPP/tqdataview.cpp \
+ $$SQL_CPP/tqdatabrowser.cpp \
+ $$SQL_CPP/tqsqlselectcursor.cpp \
+ $$SQL_CPP/drivers/cache/tqsqlcachedresult.cpp
+
+ tqcontains(sql-drivers, all ) {
+ sql-driver += psql mysql odbc oci tds db2 sqlite ibase
+ }
+
+ tqcontains(sql-drivers, psql) {
+ HEADERS += $$SQL_CPP/drivers/psql/tqsql_psql.h
+ SOURCES += $$SQL_CPP/drivers/psql/tqsql_psql.cpp
+ DEFINES += TQT_SQL_POSTGRES
+ unix {
+ !tqcontains( LIBS, .*pq.* ) {
+ LIBS *= -lpq
+ }
+ }
+ win32 {
+ !tqcontains( LIBS, .*libpq.* ) {
+ LIBS *= libpqdll.lib
+ }
+# win32-msvc: {
+# LIBS *= delayimp.lib
+# QMAKE_LFLAGS += /DELAYLOAD:libpqdll.dll
+# }
+# win32-borland: {
+# QMAKE_LFLAGS += /dlibpqdll.dll
+# }
+ }
+ }
+
+ tqcontains(sql-drivers, mysql) {
+ HEADERS += $$SQL_CPP/drivers/mysql/tqsql_mysql.h
+ SOURCES += $$SQL_CPP/drivers/mysql/tqsql_mysql.cpp
+ DEFINES += TQT_SQL_MYSQL
+ unix {
+ !tqcontains( LIBS, .*mysql.* ) {
+ LIBS *= -lmysqlclient
+ }
+ }
+ win32 {
+ !tqcontains( LIBS, .*mysql.* ) {
+ LIBS *= libmysql.lib
+ }
+# win32-msvc: {
+# LIBS *= delayimp.lib
+# QMAKE_LFLAGS += /DELAYLOAD:libmysql.dll
+# }
+# win32-borland: {
+# QMAKE_LFLAGS += /dlibmysql.dll
+# }
+ }
+ }
+
+ tqcontains(sql-drivers, odbc) {
+ HEADERS += $$SQL_CPP/drivers/odbc/tqsql_odbc.h
+ SOURCES += $$SQL_CPP/drivers/odbc/tqsql_odbc.cpp
+ DEFINES += TQT_SQL_ODBC
+
+ mac {
+ !tqcontains( LIBS, .*odbc.* ) {
+ LIBS *= -liodbc
+ }
+ }
+
+ unix {
+ !tqcontains( LIBS, .*odbc.* ) {
+ LIBS *= -lodbc
+ }
+ }
+
+ win32 {
+ !win32-borland:LIBS *= odbc32.lib
+ win32-borland:LIBS *= $(BCB)/lib/PSDK/odbc32.lib
+ }
+
+ }
+
+ tqcontains(sql-drivers, oci) {
+ HEADERS += $$SQL_CPP/drivers/oci/tqsql_oci.h
+ SOURCES += $$SQL_CPP/drivers/oci/tqsql_oci.cpp
+ DEFINES += TQT_SQL_OCI
+ unix {
+ !tqcontains( LIBS, .*clnts.* ) {
+ LIBS += -lclntsh -lwtc8
+ }
+ }
+ win32 {
+ LIBS += oci.lib
+# win32-msvc: {
+# LIBS *= delayimp.lib
+# QMAKE_LFLAGS += /DELAYLOAD:oci.dll
+# }
+# win32-borland: {
+# QMAKE_LFLAGS += /doci.dll
+# }
+ }
+ }
+
+ tqcontains(sql-drivers, tds) {
+ HEADERS += $$SQL_CPP/drivers/tds/tqsql_tds.h \
+ $$SQL_CPP/drivers/shared/tqsql_result.h
+ SOURCES += $$SQL_CPP/drivers/tds/tqsql_tds.cpp \
+ $$SQL_CPP/drivers/shared/tqsql_result.cpp
+ DEFINES += TQT_SQL_TDS
+ unix {
+ LIBS += -L$SYBASE/lib -lsybdb
+ }
+ win32 {
+ !win32-borland:LIBS += NTWDBLIB.LIB
+ win32-borland:LIBS += $(BCB)/lib/PSDK/NTWDBLIB.LIB
+# win32-msvc: {
+# LIBS *= delayimp.lib
+# QMAKE_LFLAGS += /DELAYLOAD:ntwdblib.dll
+# }
+# win32-borland: {
+# QMAKE_LFLAGS += /dntwdblib.dll
+# }
+ }
+ }
+
+ tqcontains(sql-drivers, db2) {
+ HEADERS += $$SQL_CPP/drivers/db2/tqsql_db2.h
+ SOURCES += $$SQL_CPP/drivers/db2/tqsql_db2.cpp
+ DEFINES += TQT_SQL_DB2
+ unix {
+ LIBS += -ldb2
+ }
+ win32 {
+ !win32-borland:LIBS += db2cli.lib
+# win32-borland:LIBS += $(BCB)/lib/PSDK/db2cli.lib
+ }
+ }
+
+ tqcontains(sql-drivers, ibase) {
+ HEADERS += $$SQL_CPP/drivers/ibase/tqsql_ibase.h
+ SOURCES += $$SQL_CPP/drivers/ibase/tqsql_ibase.cpp
+ DEFINES += TQT_SQL_IBASE
+ unix {
+ LIBS *= -lgds
+ }
+ win32 {
+ !win32-borland:LIBS *= gds32_ms.lib
+ win32-borland:LIBS += gds32.lib
+ }
+ }
+
+ tqcontains(sql-drivers, sqlite) {
+ !tqcontains( LIBS, .*sqlite.* ) {
+
+ INCLUDEPATH += $$SQL_CPP/../3rdparty/sqlite/
+
+ HEADERS += $$SQL_CPP/../3rdparty/sqlite/btree.h \
+ $$SQL_CPP/../3rdparty/sqlite/config.h \
+ $$SQL_CPP/../3rdparty/sqlite/hash.h \
+ $$SQL_CPP/../3rdparty/sqlite/opcodes.h \
+ $$SQL_CPP/../3rdparty/sqlite/os.h \
+ $$SQL_CPP/../3rdparty/sqlite/pager.h \
+ $$SQL_CPP/../3rdparty/sqlite/parse.h \
+ $$SQL_CPP/../3rdparty/sqlite/sqlite.h \
+ $$SQL_CPP/../3rdparty/sqlite/sqliteInt.h \
+ $$SQL_CPP/../3rdparty/sqlite/vdbe.h \
+ $$SQL_CPP/../3rdparty/sqlite/vdbeInt.h
+
+ SOURCES += $$SQL_CPP/../3rdparty/sqlite/attach.c \
+ $$SQL_CPP/../3rdparty/sqlite/auth.c \
+ $$SQL_CPP/../3rdparty/sqlite/btree.c \
+ $$SQL_CPP/../3rdparty/sqlite/btree_rb.c \
+ $$SQL_CPP/../3rdparty/sqlite/build.c \
+ $$SQL_CPP/../3rdparty/sqlite/copy.c \
+ $$SQL_CPP/../3rdparty/sqlite/date.c \
+ $$SQL_CPP/../3rdparty/sqlite/delete.c \
+ $$SQL_CPP/../3rdparty/sqlite/expr.c \
+ $$SQL_CPP/../3rdparty/sqlite/func.c \
+ $$SQL_CPP/../3rdparty/sqlite/hash.c \
+ $$SQL_CPP/../3rdparty/sqlite/insert.c \
+ $$SQL_CPP/../3rdparty/sqlite/main.c \
+ $$SQL_CPP/../3rdparty/sqlite/opcodes.c \
+ $$SQL_CPP/../3rdparty/sqlite/os.c \
+ $$SQL_CPP/../3rdparty/sqlite/pager.c \
+ $$SQL_CPP/../3rdparty/sqlite/parse.c \
+ $$SQL_CPP/../3rdparty/sqlite/pragma.c \
+ $$SQL_CPP/../3rdparty/sqlite/printf.c \
+ $$SQL_CPP/../3rdparty/sqlite/random.c \
+ $$SQL_CPP/../3rdparty/sqlite/select.c \
+ $$SQL_CPP/../3rdparty/sqlite/shell.c \
+ $$SQL_CPP/../3rdparty/sqlite/table.c \
+ $$SQL_CPP/../3rdparty/sqlite/tokenize.c \
+ $$SQL_CPP/../3rdparty/sqlite/trigger.c \
+ $$SQL_CPP/../3rdparty/sqlite/update.c \
+ $$SQL_CPP/../3rdparty/sqlite/util.c \
+ $$SQL_CPP/../3rdparty/sqlite/vacuum.c \
+ $$SQL_CPP/../3rdparty/sqlite/vdbe.c \
+ $$SQL_CPP/../3rdparty/sqlite/vdbeaux.c \
+ $$SQL_CPP/../3rdparty/sqlite/where.c
+ }
+
+ HEADERS += $$SQL_CPP/drivers/sqlite/tqsql_sqlite.h
+ SOURCES += $$SQL_CPP/drivers/sqlite/tqsql_sqlite.cpp
+ DEFINES += TQT_SQL_SQLITE
+ }
+}
+
diff --git a/tqtinterface/qt4/src/sql/tqdatabrowser.cpp b/tqtinterface/qt4/src/sql/tqdatabrowser.cpp
new file mode 100644
index 0000000..bf27e14
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqdatabrowser.cpp
@@ -0,0 +1,1284 @@
+/****************************************************************************
+**
+** Implementation of TQDataBrowser class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdatabrowser.h"
+
+#ifndef TQT_NO_STQL_VIEW_WIDGETS
+
+#include "tqsqlform.h"
+#include "tqsqlmanager_p.h"
+#include "tqsqlresult.h"
+
+class TQDataBrowserPrivate
+{
+public:
+ TQDataBrowserPrivate() : boundaryCheck( TRUE ), readOnly( FALSE ) {}
+ TQSqlCursorManager cur;
+ TQSqlFormManager frm;
+ TQDataManager dat;
+ bool boundaryCheck;
+ bool readOnly;
+};
+
+/*!
+ \class TQDataBrowser tqdatabrowser.h
+ \brief The TQDataBrowser class provides data manipulation and
+ navigation for data entry forms.
+
+ \ingroup database
+ \mainclass
+ \module sql
+
+ A high-level API is provided for navigating through data records
+ in a cursor, for inserting, updating and deleting records, and for
+ refreshing data in the display.
+
+ If you want a read-only form to present database data use
+ TQDataView; if you want a table-based presentation of your data use
+ TQDataTable.
+
+ A TQDataBrowser is used to associate a dataset with a form in much
+ the same way as a TQDataTable associates a dataset with a table.
+ Once the data browser has been constructed it can be associated
+ with a dataset with setSqlCursor(), and with a form with
+ setForm(). Boundary checking, sorting and filtering can be set
+ with setBoundaryChecking(), setSort() and setFilter(),
+ respectively.
+
+ The insertCurrent() function reads the fields from the default
+ form into the default cursor and performs the insert. The
+ updateCurrent() and deleteCurrent() functions perform similarly to
+ update and delete the current record respectively.
+
+ The user can be asked to confirm all edits with setConfirmEdits().
+ For more precise control use setConfirmInsert(),
+ setConfirmUpdate(), setConfirmDelete() and setConfirmCancels().
+ Use setAutoEdit() to control the behaviour of the form when the
+ user edits a record and then navigates.
+
+ The record set is navigated using first(), next(), prev(), last()
+ and seek(). The form's display is updated with refresh(). When
+ navigation takes place the firstRecordAvailable(),
+ lastRecordAvailable(), nextRecordAvailable() and
+ prevRecordAvailable() Q_SIGNALS are emitted. When the cursor record
+ is changed due to navigation the cursorChanged() signal is
+ emitted.
+
+ If you want finer control of the insert, update and delete
+ processes then you can use the lower level functions to perform
+ these operations as described below.
+
+ The form is populated with data from the database with
+ readFields(). If the user is allowed to edit, (see setReadOnly()),
+ write the form's data back to the cursor's edit buffer with
+ writeFields(). You can clear the values in the form with
+ clearValues(). Editing is performed as follows:
+ \list
+ \i \e insert When the data browser enters insertion mode it emits the
+ primeInsert() signal which you can connect to, for example to
+ pre-populate fields. Call writeFields() to write the user's edits to
+ the cursor's edit buffer then call insert() to insert the record
+ into the database. The beforeInsert() signal is emitted just before
+ the cursor's edit buffer is inserted into the database; connect to
+ this for example, to populate fields such as an auto-generated
+ primary key.
+ \i \e update For updates the primeUpdate() signal is emitted when
+ the data browser enters update mode. After calling writeFields()
+ call update() to update the record and connect to the beforeUpdate()
+ signal to manipulate the user's data before the update takes place.
+ \i \e delete For deletion the primeDelete() signal is emitted when
+ the data browser enters deletion mode. After calling writeFields()
+ call del() to delete the record and connect to the beforeDelete()
+ signal, for example to record an audit of the deleted record.
+ \endlist
+
+*/
+
+/*!
+ \enum TQDataBrowser::Boundary
+
+ This enum describes where the data browser is positioned.
+
+ \value Unknown the boundary cannot be determined (usually because
+ there is no default cursor, or the default cursor is not active).
+
+ \value None the browser is not positioned on a boundary, but it is
+ positioned on a record somewhere in the middle.
+
+ \value BeforeBeginning the browser is positioned before the
+ first available record.
+
+ \value Beginning the browser is positioned at the first record.
+
+ \value End the browser is positioned at the last
+ record.
+
+ \value AfterEnd the browser is positioned after the last
+ available record.
+*/
+
+/*!
+ Constructs a data browser which is a child of \a tqparent, with the
+ name \a name and widget flags set to \a fl.
+*/
+
+TQDataBrowser::TQDataBrowser( TQWidget *tqparent, const char *name, WFlags fl )
+ : TQWidget( tqparent, name, fl )
+{
+ d = new TQDataBrowserPrivate();
+ d->dat.setMode( TQSql::Update );
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQDataBrowser::~TQDataBrowser()
+{
+ delete d;
+}
+
+
+/*!
+ Returns an enum indicating the boundary status of the browser.
+
+ This is achieved by moving the default cursor and checking the
+ position, however the current default form values will not be
+ altered. After checking for the boundary, the cursor is moved back
+ to its former position. See \l TQDataBrowser::Boundary.
+
+ \sa Boundary
+*/
+
+TQDataBrowser::Boundary TQDataBrowser::boundary()
+{
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !cur || !cur->isActive() )
+ return Unknown;
+ if ( !cur->isValid() ) {
+ if ( cur->at() == TQSql::BeforeFirst )
+ return BeforeBeginning;
+ if ( cur->at() == TQSql::AfterLast )
+ return AfterEnd;
+ return Unknown;
+ }
+ if ( cur->at() == 0 )
+ return Beginning;
+ int currentAt = cur->at();
+
+ Boundary b = None;
+ if ( !cur->prev() )
+ b = Beginning;
+ else
+ cur->seek( currentAt );
+ if ( b == None && !cur->next() )
+ b = End;
+ cur->seek( currentAt );
+ return b;
+}
+
+
+/*!
+ \property TQDataBrowser::boundaryChecking
+ \brief whether boundary checking is active
+
+ When boundary checking is active (the default), Q_SIGNALS are
+ emitted indicating the current position of the default cursor.
+
+ \sa boundary()
+*/
+
+void TQDataBrowser::setBoundaryChecking( bool active )
+{
+ d->boundaryCheck = active;
+}
+
+bool TQDataBrowser::boundaryChecking() const
+{
+ return d->boundaryCheck;
+}
+
+/*!
+ \property TQDataBrowser::sort
+ \brief the data browser's sort
+
+ The data browser's sort affects the order in which records are
+ viewed in the browser. Call refresh() to apply the new sort.
+
+ When retrieving the sort property, a string list is returned in
+ the form 'fieldname order', e.g. 'id ASC', 'surname DESC'.
+
+ There is no default sort.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myDataBrowser.sort();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+
+void TQDataBrowser::setSort( const TQStringList& sort )
+{
+ d->cur.setSort( sort );
+}
+
+/*!
+ \overload
+
+ Sets the data browser's sort to the TQSqlIndex \a sort. To apply
+ the new sort, use refresh().
+
+*/
+void TQDataBrowser::setSort( const TQSqlIndex& sort )
+{
+ d->cur.setSort( sort );
+}
+
+TQStringList TQDataBrowser::sort() const
+{
+ return d->cur.sort();
+}
+
+
+/*!
+ \property TQDataBrowser::filter
+ \brief the data browser's filter
+
+ The filter applies to the data shown in the browser. Call
+ refresh() to apply the new filter. A filter is a string containing
+ a SQL WHERE clause without the WHERE keyword, e.g. "id>1000",
+ "name LIKE 'A%'", etc.
+
+ There is no default filter.
+
+ \sa sort()
+*/
+
+void TQDataBrowser::setFilter( const TQString& filter )
+{
+ d->cur.setFilter( filter );
+}
+
+
+TQString TQDataBrowser::filter() const
+{
+ return d->cur.filter();
+}
+
+
+/*!
+ Sets the default cursor used by the data browser to \a cursor. If
+ \a autoDelete is TRUE (the default is FALSE), the data browser
+ takes ownership of the \a cursor pointer, which will be deleted
+ when the browser is destroyed, or when setSqlCursor() is called
+ again. To activate the \a cursor use refresh(). The cursor's edit
+ buffer is used in the default form to browse and edit records.
+
+ \sa sqlCursor() form() setForm()
+*/
+
+void TQDataBrowser::setSqlCursor( TQSqlCursor* cursor, bool autoDelete )
+{
+ if ( !cursor )
+ return;
+ d->cur.setCursor( cursor, autoDelete );
+ d->frm.setRecord( cursor->editBuffer() );
+ if ( cursor->isReadOnly() )
+ setReadOnly( TRUE );
+}
+
+
+/*!
+ Returns the default cursor used for navigation, or 0 if there is
+ no default cursor.
+
+ \sa setSqlCursor()
+*/
+
+TQSqlCursor* TQDataBrowser::sqlCursor() const
+{
+ return d->cur.cursor();
+}
+
+
+/*!
+ Sets the browser's default form to \a form. The cursor and all
+ navigation and data manipulation functions that the browser
+ provides become available to the \a form.
+*/
+
+void TQDataBrowser::setForm( TQSqlForm* form )
+{
+ d->frm.setForm( form );
+}
+
+
+/*!
+ Returns the data browser's default form or 0 if no form has been
+ set.
+*/
+
+TQSqlForm* TQDataBrowser::form()
+{
+ return d->frm.form();
+}
+
+/*!
+ \property TQDataBrowser::readOnly
+ \brief whether the browser is read-only
+
+ The default is FALSE, i.e. data can be edited. If the data browser
+ is read-only, no database edits will be allowed.
+*/
+
+void TQDataBrowser::setReadOnly( bool active )
+{
+ d->readOnly = active;
+}
+
+bool TQDataBrowser::isReadOnly() const
+{
+ return d->readOnly;
+}
+
+void TQDataBrowser::setConfirmEdits( bool confirm )
+{
+ d->dat.setConfirmEdits( confirm );
+}
+
+/*!
+ \property TQDataBrowser::confirmInsert
+ \brief whether the data browser confirms insertions
+
+ If this property is TRUE, the browser confirms insertions,
+ otherwise insertions happen immediately.
+
+ \sa confirmCancels() confirmEdits() confirmUpdate() confirmDelete() confirmEdit()
+*/
+
+void TQDataBrowser::setConfirmInsert( bool confirm )
+{
+ d->dat.setConfirmInsert( confirm );
+}
+
+/*!
+ \property TQDataBrowser::confirmUpdate
+ \brief whether the browser confirms updates
+
+ If this property is TRUE, the browser confirms updates, otherwise
+ updates happen immediately.
+
+ \sa confirmCancels() confirmEdits() confirmInsert() confirmDelete() confirmEdit()
+*/
+
+void TQDataBrowser::setConfirmUpdate( bool confirm )
+{
+ d->dat.setConfirmUpdate( confirm );
+}
+
+/*!
+ \property TQDataBrowser::confirmDelete
+ \brief whether the browser confirms deletions
+
+ If this property is TRUE, the browser confirms deletions,
+ otherwise deletions happen immediately.
+
+ \sa confirmCancels() confirmEdits() confirmUpdate() confirmInsert() confirmEdit()
+*/
+
+void TQDataBrowser::setConfirmDelete( bool confirm )
+{
+ d->dat.setConfirmDelete( confirm );
+}
+
+/*!
+ \property TQDataBrowser::confirmEdits
+ \brief whether the browser confirms edits
+
+ If this property is TRUE, the browser confirms all edit operations
+ (insertions, updates and deletions), otherwise all edit operations
+ happen immediately. Confirmation is achieved by presenting the
+ user with a message box -- this behavior can be changed by
+ reimplementing the confirmEdit() function,
+
+ \sa confirmEdit() confirmCancels() confirmInsert() confirmUpdate() confirmDelete()
+*/
+
+bool TQDataBrowser::confirmEdits() const
+{
+ return ( d->dat.confirmEdits() );
+}
+
+bool TQDataBrowser::confirmInsert() const
+{
+ return ( d->dat.confirmInsert() );
+}
+
+bool TQDataBrowser::confirmUpdate() const
+{
+ return ( d->dat.confirmUpdate() );
+}
+
+bool TQDataBrowser::confirmDelete() const
+{
+ return ( d->dat.confirmDelete() );
+}
+
+/*!
+ \property TQDataBrowser::confirmCancels
+ \brief whether the browser confirms cancel operations
+
+ If this property is TRUE, all cancels must be confirmed by the
+ user through a message box (this behavior can be changed by
+ overriding the confirmCancel() function), otherwise all cancels
+ occur immediately. The default is FALSE.
+
+ \sa confirmEdits() confirmCancel()
+*/
+
+void TQDataBrowser::setConfirmCancels( bool confirm )
+{
+ d->dat.setConfirmCancels( confirm );
+}
+
+bool TQDataBrowser::confirmCancels() const
+{
+ return d->dat.confirmCancels();
+}
+
+/*!
+ \property TQDataBrowser::autoEdit
+ \brief whether the browser automatically applies edits
+
+ The default value for this property is TRUE. When the user begins
+ an insertion or an update on a form there are two possible
+ outcomes when they navigate to another record:
+
+ \list
+ \i the insert or update is is performed -- this occurs if autoEdit is TRUE
+ \i the insert or update is discarded -- this occurs if autoEdit is FALSE
+ \endlist
+*/
+
+void TQDataBrowser::setAutoEdit( bool autoEdit )
+{
+ d->dat.setAutoEdit( autoEdit );
+}
+
+bool TQDataBrowser::autoEdit() const
+{
+ return d->dat.autoEdit();
+}
+
+/*!
+ \fn void TQDataBrowser::firstRecordAvailable( bool available )
+
+ This signal is emitted whenever the position of the cursor
+ changes. The \a available parameter indicates whether or not the
+ first record in the default cursor is available.
+*/
+
+/*!
+ \fn void TQDataBrowser::lastRecordAvailable( bool available )
+
+ This signal is emitted whenever the position of the cursor
+ changes. The \a available parameter indicates whether or not the
+ last record in the default cursor is available.
+*/
+
+/*!
+ \fn void TQDataBrowser::nextRecordAvailable( bool available )
+
+ This signal is emitted whenever the position of the cursor
+ changes. The \a available parameter indicates whether or not the
+ next record in the default cursor is available.
+*/
+
+
+/*!
+ \fn void TQDataBrowser::prevRecordAvailable( bool available )
+
+ This signal is emitted whenever the position of the cursor
+ changes. The \a available parameter indicates whether or not the
+ previous record in the default cursor is available.
+*/
+
+
+/*!
+ \fn void TQDataBrowser::currentChanged( const TQSqlRecord* record )
+
+ This signal is emitted whenever the current cursor position
+ changes. The \a record parameter points to the contents of the
+ current cursor's record.
+*/
+
+
+/*!
+ \fn void TQDataBrowser::primeInsert( TQSqlRecord* buf )
+
+ This signal is emitted when the data browser enters insertion
+ mode. The \a buf parameter points to the record buffer that is to
+ be inserted. Connect to this signal to, for example, prime the
+ record buffer with default data values, auto-numbered fields etc.
+ (Note that TQSqlCursor::primeInsert() is \e not called on the
+ default cursor, as this would corrupt values in the form.)
+
+ \sa insert()
+*/
+
+
+/*!
+ \fn void TQDataBrowser::primeUpdate( TQSqlRecord* buf )
+
+ This signal is emitted when the data browser enters update mode.
+ Note that during navigation (first(), last(), next(), prev()),
+ each record that is shown in the default form is primed for
+ update. The \a buf parameter points to the record buffer being
+ updated. (Note that TQSqlCursor::primeUpdate() is \e not called on
+ the default cursor, as this would corrupt values in the form.)
+ Connect to this signal in order to, for example, keep track of
+ which records have been updated, perhaps for auditing purposes.
+
+ \sa update()
+*/
+
+/*!
+ \fn void TQDataBrowser::primeDelete( TQSqlRecord* buf )
+
+ This signal is emitted when the data browser enters deletion mode.
+ The \a buf parameter points to the record buffer being deleted.
+ (Note that TQSqlCursor::primeDelete() is \e not called on the
+ default cursor, as this would corrupt values in the form.)
+ Connect to this signal in order to, for example, save a copy of
+ the deleted record for auditing purposes.
+
+ \sa del()
+*/
+
+
+/*!
+ \fn void TQDataBrowser::cursorChanged( TQSqlCursor::Mode mode )
+
+ This signal is emitted whenever the cursor record was changed due
+ to navigation. The \a mode parameter is the edit that just took
+ place, e.g. Insert, Update or Delete. See \l TQSqlCursor::Mode.
+*/
+
+
+/*!
+ Refreshes the data browser's data using the default cursor. The
+ browser's current filter and sort are applied if they have been
+ set.
+
+ \sa setFilter() setSort()
+*/
+
+void TQDataBrowser::refresh()
+{
+ d->cur.refresh();
+}
+
+
+/*!
+ Performs an insert operation on the data browser's cursor. If
+ there is no default cursor or no default form, nothing happens.
+
+ If auto-editing is on (see setAutoEdit()), the following happens:
+
+ \list
+ \i If the browser is already actively inserting a record,
+ the current form's data is inserted into the database.
+ \i If the browser is not inserting a record, but the current record
+ was changed by the user, the record is updated in the database with
+ the current form's data (i.e. with the changes).
+ \endlist
+
+ If there is an error handling any of the above auto-edit actions,
+ handleError() is called and no insert or update is performed.
+
+ If no error occurred, or auto-editing is not enabled, the data browser
+ begins actively inserting a record into the database by performing the
+ following actions:
+
+ \list
+ \i The default cursor is primed for insert using TQSqlCursor::primeInsert().
+ \i The primeInsert() signal is emitted.
+ \i The form is updated with the values in the default cursor's.
+ edit buffer so that the user can fill in the values to be inserted.
+ \endlist
+
+*/
+
+void TQDataBrowser::insert()
+{
+ TQSqlRecord* buf = d->frm.record();
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !buf || !cur )
+ return;
+ bool doIns = TRUE;
+ TQSql::Confirm conf = TQSql::Yes;
+ switch ( d->dat.mode() ) {
+ case TQSql::Insert:
+ if ( autoEdit() ) {
+ if ( confirmInsert() )
+ conf = confirmEdit( TQSql::Insert );
+ switch ( conf ) {
+ case TQSql::Yes:
+ insertCurrent();
+ break;
+ case TQSql::No:
+ break;
+ case TQSql::Cancel:
+ doIns = FALSE;
+ break;
+ }
+ }
+ break;
+ default:
+ if ( autoEdit() && currentEdited() ) {
+ if ( confirmUpdate() )
+ conf = confirmEdit( TQSql::Update );
+ switch ( conf ) {
+ case TQSql::Yes:
+ updateCurrent();
+ break;
+ case TQSql::No:
+ break;
+ case TQSql::Cancel:
+ doIns = FALSE;
+ break;
+ }
+ }
+ break;
+ }
+ if ( doIns ) {
+ d->dat.setMode( TQSql::Insert );
+ sqlCursor()->primeInsert();
+ emit primeInsert( d->frm.record() );
+ readFields();
+ }
+}
+
+
+/*!
+ Performs an update operation on the data browser's cursor.
+
+ If there is no default cursor or no default form, nothing happens.
+ Otherwise, the following happens:
+
+ If the data browser is actively inserting a record (see insert()),
+ that record is inserted into the database using insertCurrent().
+ Otherwise, the database is updated with the current form's data
+ using updateCurrent(). If there is an error handling either
+ action, handleError() is called.
+*/
+
+void TQDataBrowser::update()
+{
+ TQSqlRecord* buf = d->frm.record();
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !buf || !cur )
+ return;
+ TQSql::Confirm conf = TQSql::Yes;
+ switch ( d->dat.mode() ){
+ case TQSql::Insert:
+ if ( confirmInsert() )
+ conf = confirmEdit( TQSql::Insert );
+ switch ( conf ) {
+ case TQSql::Yes:
+ if ( insertCurrent() )
+ d->dat.setMode( TQSql::Update );
+ break;
+ case TQSql::No:
+ d->dat.setMode( TQSql::Update );
+ cur->editBuffer( TRUE );
+ readFields();
+ break;
+ case TQSql::Cancel:
+ break;
+ }
+ break;
+ default:
+ d->dat.setMode( TQSql::Update );
+ if ( confirmUpdate() )
+ conf = confirmEdit( TQSql::Update );
+ switch ( conf ) {
+ case TQSql::Yes:
+ updateCurrent();
+ break;
+ case TQSql::No:
+ case TQSql::Cancel:
+ break;
+ }
+ break;
+ }
+}
+
+
+/*!
+ Performs a delete operation on the data browser's cursor. If there
+ is no default cursor or no default form, nothing happens.
+
+ Otherwise, the following happens:
+
+ The current form's record is deleted from the database, providing
+ that the data browser is not in insert mode. If the data browser
+ is actively inserting a record (see insert()), the insert action
+ is canceled, and the browser navigates to the last valid record
+ that was current. If there is an error, handleError() is called.
+*/
+
+void TQDataBrowser::del()
+{
+ TQSqlRecord* buf = d->frm.record();
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !buf || !cur )
+ return;
+ TQSql::Confirm conf = TQSql::Yes;
+ switch ( d->dat.mode() ){
+ case TQSql::Insert:
+ if ( confirmCancels() )
+ conf = confirmCancel( TQSql::Insert );
+ if ( conf == TQSql::Yes ) {
+ cur->editBuffer( TRUE ); /* restore from cursor */
+ readFields();
+ d->dat.setMode( TQSql::Update );
+ } else
+ d->dat.setMode( TQSql::Insert );
+ break;
+ default:
+ if ( confirmDelete() )
+ conf = confirmEdit( TQSql::Delete );
+ switch ( conf ) {
+ case TQSql::Yes:
+ emit primeDelete( buf );
+ deleteCurrent();
+ break;
+ case TQSql::No:
+ case TQSql::Cancel:
+ break;
+ }
+ d->dat.setMode( TQSql::Update );
+ break;
+ }
+}
+
+/*!
+ Moves the default cursor to the record specified by the index \a i
+ and refreshes the default form to display this record. If there is
+ no default form or no default cursor, nothing happens. If \a
+ relative is TRUE (the default is FALSE), the cursor is moved
+ relative to its current position. If the data browser successfully
+ navigated to the desired record, the default cursor is primed for
+ update and the primeUpdate() signal is emitted.
+
+ If the browser is already positioned on the desired record nothing
+ happens.
+*/
+
+bool TQDataBrowser::seek( int i, bool relative )
+{
+ int b = 0;
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !cur )
+ return FALSE;
+ if ( preNav() )
+ b = cur->seek( i, relative );
+ postNav( b );
+ return b;
+}
+
+/*!
+ Moves the default cursor to the first record and refreshes the
+ default form to display this record. If there is no default form
+ or no default cursor, nothing happens. If the data browser
+ successfully navigated to the first record, the default cursor is
+ primed for update and the primeUpdate() signal is emitted.
+
+ If the browser is already positioned on the first record nothing
+ happens.
+
+*/
+
+void TQDataBrowser::first()
+{
+ nav( &TQSqlCursor::first );
+}
+
+
+/*!
+ Moves the default cursor to the last record and refreshes the
+ default form to display this record. If there is no default form
+ or no default cursor, nothing happens. If the data browser
+ successfully navigated to the last record, the default cursor is
+ primed for update and the primeUpdate() signal is emitted.
+
+ If the browser is already positioned on the last record nothing
+ happens.
+*/
+
+void TQDataBrowser::last()
+{
+ nav( &TQSqlCursor::last );
+}
+
+
+/*!
+ Moves the default cursor to the next record and refreshes the
+ default form to display this record. If there is no default form
+ or no default cursor, nothing happens. If the data browser
+ successfully navigated to the next record, the default cursor is
+ primed for update and the primeUpdate() signal is emitted.
+
+ If the browser is positioned on the last record nothing happens.
+*/
+
+void TQDataBrowser::next()
+{
+ nav( &TQSqlCursor::next );
+}
+
+
+/*!
+ Moves the default cursor to the previous record and refreshes the
+ default form to display this record. If there is no default form
+ or no default cursor, nothing happens. If the data browser
+ successfully navigated to the previous record, the default cursor
+ is primed for update and the primeUpdate() signal is emitted.
+
+ If the browser is positioned on the first record nothing happens.
+*/
+
+void TQDataBrowser::prev()
+{
+ nav( &TQSqlCursor::prev );
+}
+
+/*!
+ Reads the fields from the default cursor's edit buffer and
+ displays them in the form. If there is no default cursor or no
+ default form, nothing happens.
+*/
+
+void TQDataBrowser::readFields()
+{
+ d->frm.readFields();
+}
+
+
+/*!
+ Writes the form's data to the default cursor's edit buffer. If
+ there is no default cursor or no default form, nothing happens.
+*/
+
+void TQDataBrowser::writeFields()
+{
+ d->frm.writeFields();
+}
+
+
+/*!
+ Clears all the values in the form.
+
+ All the edit buffer field values are set to their 'zero state',
+ e.g. 0 for numeric fields and "" for string fields. Then the
+ widgets are updated using the property map. For example, a
+ combobox that is property-mapped to integers would scroll to the
+ first item. See the \l TQSqlPropertyMap constructor for the default
+ mappings of widgets to properties.
+*/
+
+void TQDataBrowser::clearValues()
+{
+ d->frm.clearValues();
+}
+
+/*!
+ Reads the fields from the default form into the default cursor and
+ performs an insert on the default cursor. If there is no default
+ form or no default cursor, nothing happens. If an error occurred
+ during the insert into the database, handleError() is called and
+ FALSE is returned. If the insert was successfull, the cursor is
+ refreshed and relocated to the newly inserted record, the
+ cursorChanged() signal is emitted, and TRUE is returned.
+
+ \sa cursorChanged() sqlCursor() form() handleError()
+*/
+
+bool TQDataBrowser::insertCurrent()
+{
+ if ( isReadOnly() )
+ return FALSE;
+ TQSqlRecord* buf = d->frm.record();
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !buf || !cur )
+ return FALSE;
+ writeFields();
+ emit beforeInsert( buf );
+ int ar = cur->insert();
+ if ( !ar || !cur->isActive() ) {
+ handleError( cur->lastError() );
+ refresh();
+ updateBoundary();
+ } else {
+ refresh();
+ d->cur.tqfindBuffer( cur->primaryIndex() );
+ updateBoundary();
+ cursorChanged( TQSqlCursor::Insert );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*!
+ Reads the fields from the default form into the default cursor and
+ performs an update on the default cursor. If there is no default
+ form or no default cursor, nothing happens. If an error occurred
+ during the update on the database, handleError() is called and
+ FALSE is returned. If the update was successfull, the cursor is
+ refreshed and relocated to the updated record, the cursorChanged()
+ signal is emitted, and TRUE is returned.
+
+ \sa cursor() form() handleError()
+*/
+
+bool TQDataBrowser::updateCurrent()
+{
+ if ( isReadOnly() )
+ return FALSE;
+ TQSqlRecord* buf = d->frm.record();
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !buf || !cur )
+ return FALSE;
+ writeFields();
+ emit beforeUpdate( buf );
+ int ar = cur->update();
+ if ( !ar || !cur->isActive() ) {
+ handleError( cur->lastError() );
+ refresh();
+ updateBoundary();
+ } else {
+ refresh();
+ d->cur.tqfindBuffer( cur->primaryIndex() );
+ updateBoundary();
+ cur->editBuffer( TRUE );
+ cursorChanged( TQSqlCursor::Update );
+ readFields();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*!
+ Performs a delete on the default cursor using the values from the
+ default form and updates the default form. If there is no default
+ form or no default cursor, nothing happens. If the deletion was
+ successful, the cursor is repositioned to the nearest record and
+ TRUE is returned. The nearest record is the next record if there
+ is one otherwise the previous record if there is one. If an error
+ occurred during the deletion from the database, handleError() is
+ called and FALSE is returned.
+
+ \sa cursor() form() handleError()
+*/
+
+bool TQDataBrowser::deleteCurrent()
+{
+ if ( isReadOnly() )
+ return FALSE;
+ TQSqlRecord* buf = d->frm.record();
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !buf || !cur )
+ return FALSE;
+ writeFields();
+ int n = cur->at();
+ emit beforeDelete( buf );
+ int ar = cur->del();
+ if ( ar ) {
+ refresh();
+ updateBoundary();
+ cursorChanged( TQSqlCursor::Delete );
+ if ( !cur->seek( n ) )
+ last();
+ if ( cur->isValid() ) {
+ cur->editBuffer( TRUE );
+ readFields();
+ } else {
+ clearValues();
+ }
+ return TRUE;
+ } else {
+ if ( !cur->isActive() ) {
+ handleError( cur->lastError() );
+ refresh();
+ updateBoundary();
+ }
+ }
+ return FALSE;
+}
+
+
+/*!
+ Returns TRUE if the form's edit buffer differs from the current
+ cursor buffer; otherwise returns FALSE.
+*/
+
+bool TQDataBrowser::currentEdited()
+{
+ TQSqlRecord* buf = d->frm.record();
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !buf || !cur )
+ return FALSE;
+ if ( !cur->isActive() || !cur->isValid() )
+ return FALSE;
+ writeFields();
+ for ( uint i = 0; i < cur->count(); ++i ) {
+ if ( cur->value(i) != buf->value(i) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*! \internal
+
+ Pre-navigation checking.
+*/
+
+bool TQDataBrowser::preNav()
+{
+ TQSqlRecord* buf = d->frm.record();
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !buf || !cur )
+ return FALSE;
+
+ if ( !isReadOnly() && autoEdit() && currentEdited() ) {
+ bool ok = TRUE;
+ TQSql::Confirm conf = TQSql::Yes;
+ switch ( d->dat.mode() ){
+ case TQSql::Insert:
+ if ( confirmInsert() )
+ conf = confirmEdit( TQSql::Insert );
+ switch ( conf ) {
+ case TQSql::Yes:
+ ok = insertCurrent();
+ d->dat.setMode( TQSql::Update );
+ break;
+ case TQSql::No:
+ d->dat.setMode( TQSql::Update );
+ break;
+ case TQSql::Cancel:
+ return FALSE;
+ }
+ break;
+ default:
+ if ( confirmUpdate() )
+ conf = confirmEdit( TQSql::Update );
+ switch ( conf ) {
+ case TQSql::Yes:
+ ok = updateCurrent();
+ break;
+ case TQSql::No:
+ break;
+ case TQSql::Cancel:
+ return FALSE;
+ }
+ }
+ return ok;
+ }
+ return TRUE;
+}
+
+/*! \internal
+
+ Handles post-navigation according to \a primeUpd.
+*/
+
+void TQDataBrowser::postNav( bool primeUpd )
+{
+ if ( primeUpd ) {
+ TQSqlRecord* buf = d->frm.record();
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !buf || !cur )
+ return;
+ currentChanged( cur );
+ cur->primeUpdate();
+ emit primeUpdate( buf );
+ readFields();
+ }
+ updateBoundary();
+}
+
+/*! \internal
+
+ Navigate default cursor according to \a nav. Handles autoEdit.
+
+*/
+void TQDataBrowser::nav( Nav nav )
+{
+ int b = 0;
+ TQSqlCursor* cur = d->cur.cursor();
+ if ( !cur )
+ return;
+ if ( preNav() )
+ b = (cur->*nav)();
+ postNav( b );
+}
+
+/*!
+ If boundaryChecking() is TRUE, checks the boundary of the current
+ default cursor and emits Q_SIGNALS which indicate the position of
+ the cursor.
+*/
+
+void TQDataBrowser::updateBoundary()
+{
+ if ( d->boundaryCheck ) {
+ Boundary bound = boundary();
+ switch ( bound ) {
+ case Unknown:
+ case None:
+ emit firstRecordAvailable( TRUE );
+ emit prevRecordAvailable( TRUE );
+ emit nextRecordAvailable( TRUE );
+ emit lastRecordAvailable( TRUE );
+ break;
+
+ case BeforeBeginning:
+ emit firstRecordAvailable( FALSE );
+ emit prevRecordAvailable( FALSE );
+ emit nextRecordAvailable( TRUE );
+ emit lastRecordAvailable( TRUE );
+ break;
+
+ case Beginning:
+ emit firstRecordAvailable( FALSE );
+ emit prevRecordAvailable( FALSE );
+ emit nextRecordAvailable( TRUE );
+ emit lastRecordAvailable( TRUE );
+ break;
+
+ case End:
+ emit firstRecordAvailable( TRUE );
+ emit prevRecordAvailable( TRUE );
+ emit nextRecordAvailable( FALSE );
+ emit lastRecordAvailable( FALSE );
+ break;
+
+ case AfterEnd:
+ emit firstRecordAvailable( TRUE );
+ emit prevRecordAvailable( TRUE );
+ emit nextRecordAvailable( FALSE );
+ emit lastRecordAvailable( FALSE );
+ break;
+ }
+ }
+}
+
+/*!
+ Virtual function which handles the error \a error. The default
+ implementation warns the user with a message box.
+*/
+
+void TQDataBrowser::handleError( const TQSqlError& error )
+{
+ d->dat.handleError( this, error );
+}
+
+/*!
+ Protected virtual function which returns a confirmation for an
+ edit of mode \a m. Derived classes can reimplement this function
+ and provide their own confirmation dialog. The default
+ implementation uses a message box which prompts the user to
+ confirm the edit action.
+*/
+
+TQSql::Confirm TQDataBrowser::confirmEdit( TQSql::Op m )
+{
+ return d->dat.confirmEdit( this, m );
+}
+
+/*!
+ Protected virtual function which returns a confirmation for
+ cancelling an edit mode \a m. Derived classes can reimplement this
+ function and provide their own confirmation dialog. The default
+ implementation uses a message box which prompts the user to
+ confirm the edit action.
+*/
+
+TQSql::Confirm TQDataBrowser::confirmCancel( TQSql::Op m )
+{
+ return d->dat.confirmCancel( this, m );
+}
+
+/*!
+ \fn void TQDataBrowser::beforeInsert( TQSqlRecord* buf )
+
+ This signal is emitted just before the cursor's edit buffer is
+ inserted into the database. The \a buf parameter points to the
+ edit buffer being inserted. You might connect to this signal to
+ populate a generated primary key for example.
+*/
+
+/*!
+ \fn void TQDataBrowser::beforeUpdate( TQSqlRecord* buf )
+
+ This signal is emitted just before the cursor's edit buffer is
+ updated in the database. The \a buf parameter points to the edit
+ buffer being updated. You might connect to this signal to capture
+ some auditing information about the update.
+*/
+
+/*!
+ \fn void TQDataBrowser::beforeDelete( TQSqlRecord* buf )
+
+ This signal is emitted just before the cursor's edit buffer is
+ deleted from the database. The \a buf parameter points to the edit
+ buffer being deleted. You might connect to this signal to capture
+ some auditing information about the deletion.
+*/
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqdatabrowser.h b/tqtinterface/qt4/src/sql/tqdatabrowser.h
new file mode 100644
index 0000000..5379b78
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqdatabrowser.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Definition of TQDataBrowser class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDATABROWSER_H
+#define TQDATABROWSER_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqstring.h"
+#include "tqstringlist.h"
+#include "tqsql.h"
+#include "tqsqlindex.h"
+#include "tqsqlcursor.h"
+#include "tqsqlerror.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_STQL_VIEW_WIDGETS
+
+class TQSqlForm;
+class TQDataBrowserPrivate;
+
+class TQ_EXPORT TQDataBrowser : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool boundaryChecking READ boundaryChecking WRITE setBoundaryChecking )
+ Q_PROPERTY( TQString filter READ filter WRITE setFilter )
+ Q_PROPERTY( TQStringList sort READ sort WRITE setSort )
+ Q_PROPERTY( bool confirmEdits READ confirmEdits WRITE setConfirmEdits )
+ Q_PROPERTY( bool confirmInsert READ confirmInsert WRITE setConfirmInsert )
+ Q_PROPERTY( bool confirmUpdate READ confirmUpdate WRITE setConfirmUpdate )
+ Q_PROPERTY( bool confirmDelete READ confirmDelete WRITE setConfirmDelete )
+ Q_PROPERTY( bool confirmCancels READ confirmCancels WRITE setConfirmCancels )
+ Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly )
+ Q_PROPERTY( bool autoEdit READ autoEdit WRITE setAutoEdit )
+
+public:
+ TQDataBrowser( TQWidget* tqparent=0, const char* name=0, WFlags fl = 0 );
+ ~TQDataBrowser();
+
+ enum Boundary {
+ Unknown,
+ None,
+ BeforeBeginning,
+ Beginning,
+ End,
+ AfterEnd
+ };
+
+ Boundary boundary();
+ void setBoundaryChecking( bool active );
+ bool boundaryChecking() const;
+
+ void setSort( const TQSqlIndex& sort );
+ void setSort( const TQStringList& sort );
+ TQStringList sort() const;
+ void setFilter( const TQString& filter );
+ TQString filter() const;
+ virtual void setSqlCursor( TQSqlCursor* cursor, bool autoDelete = FALSE );
+ TQSqlCursor* sqlCursor() const;
+ virtual void setForm( TQSqlForm* form );
+ TQSqlForm* form();
+
+ virtual void setConfirmEdits( bool confirm );
+ virtual void setConfirmInsert( bool confirm );
+ virtual void setConfirmUpdate( bool confirm );
+ virtual void setConfirmDelete( bool confirm );
+ virtual void setConfirmCancels( bool confirm );
+ bool confirmEdits() const;
+ bool confirmInsert() const;
+ bool confirmUpdate() const;
+ bool confirmDelete() const;
+ bool confirmCancels() const;
+
+ virtual void setReadOnly( bool active );
+ bool isReadOnly() const;
+ virtual void setAutoEdit( bool autoEdit );
+ bool autoEdit() const;
+
+ virtual bool seek( int i, bool relative = FALSE );
+
+Q_SIGNALS:
+ void firstRecordAvailable( bool available );
+ void lastRecordAvailable( bool available );
+ void nextRecordAvailable( bool available );
+ void prevRecordAvailable( bool available );
+
+ void currentChanged( const TQSqlRecord* record );
+ void primeInsert( TQSqlRecord* buf );
+ void primeUpdate( TQSqlRecord* buf );
+ void primeDelete( TQSqlRecord* buf );
+ void beforeInsert( TQSqlRecord* buf );
+ void beforeUpdate( TQSqlRecord* buf );
+ void beforeDelete( TQSqlRecord* buf );
+ void cursorChanged( TQSqlCursor::Mode mode );
+
+public Q_SLOTS:
+ virtual void refresh();
+
+ virtual void insert();
+ virtual void update();
+ virtual void del();
+
+ virtual void first();
+ virtual void last();
+ virtual void next();
+ virtual void prev();
+
+ virtual void readFields();
+ virtual void writeFields();
+ virtual void clearValues();
+
+ void updateBoundary();
+
+protected:
+ virtual bool insertCurrent();
+ virtual bool updateCurrent();
+ virtual bool deleteCurrent();
+ virtual bool currentEdited();
+
+ virtual TQSql::Confirm confirmEdit( TQSql::Op m );
+ virtual TQSql::Confirm confirmCancel( TQSql::Op m );
+
+ virtual void handleError( const TQSqlError& error );
+
+private:
+ typedef bool (TQSqlCursor::*Nav)();
+ bool preNav();
+ void postNav( bool primeUpd );
+ void nav( Nav nav );
+ TQDataBrowserPrivate* d;
+
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQDataBrowser( const TQDataBrowser & );
+ TQDataBrowser &operator=( const TQDataBrowser & );
+#endif
+};
+
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqdatatable.cpp b/tqtinterface/qt4/src/sql/tqdatatable.cpp
new file mode 100644
index 0000000..496da9d
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqdatatable.cpp
@@ -0,0 +1,2322 @@
+/****************************************************************************
+**
+** Implementation of TQDataTable class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdatatable.h"
+
+#ifndef TQT_NO_STQL_VIEW_WIDGETS
+
+#include "tqsqldriver.h"
+#include "tqsqleditorfactory.h"
+#include "tqsqlpropertymap.h"
+#include "tqapplication.h"
+#include "tqlayout.h"
+#include "tqpainter.h"
+#include "tqpopupmenu.h"
+#include "tqvaluelist.h"
+#include "tqsqlmanager_p.h"
+#include "tqdatetime.h"
+#include "tqcursor.h"
+#include "tqtimer.h"
+
+//#define TQT_DEBUG_DATATABLE
+
+class TQDataTablePrivate
+{
+public:
+ TQDataTablePrivate()
+ : nullTxtChanged( FALSE ),
+ haveAllRows( FALSE ),
+ continuousEdit( FALSE ),
+ editorFactory( 0 ),
+ propertyMap( 0 ),
+ editRow( -1 ),
+ editCol( -1 ),
+ insertRowLast( -1 ),
+ insertPreRows( -1 ),
+ editBuffer( 0 ),
+ cancelMode( FALSE ),
+ cancelInsert( FALSE ),
+ cancelUpdate( FALSE )
+ {}
+ ~TQDataTablePrivate() { if ( propertyMap ) delete propertyMap; }
+
+ TQString nullTxt;
+ bool nullTxtChanged;
+ typedef TQValueList< uint > ColIndex;
+ ColIndex colIndex;
+ bool haveAllRows;
+ bool continuousEdit;
+ TQSqlEditorFactory* editorFactory;
+ TQSqlPropertyMap* propertyMap;
+ TQString trueTxt;
+ Qt::DateFormat datefmt;
+ TQString falseTxt;
+ int editRow;
+ int editCol;
+ int insertRowLast;
+ TQString insertHeaderLabelLast;
+ int insertPreRows;
+ TQSqlRecord* editBuffer;
+ bool cancelMode;
+ bool cancelInsert;
+ bool cancelUpdate;
+ int lastAt;
+ TQString ftr;
+ TQStringList srt;
+ TQStringList fld;
+ TQStringList fldLabel;
+ TQValueList<int> fldWidth;
+ TQValueList<TQIconSet> fldIcon;
+ TQValueList<bool> fldHidden;
+ TQSqlCursorManager cur;
+ TQDataManager dat;
+};
+
+#ifdef TQT_DEBUG_DATATABLE
+void qt_debug_buffer( const TQString& msg, TQSqlRecord* cursor )
+{
+ qDebug("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+ qDebug(msg);
+ for ( uint j = 0; j < cursor->count(); ++j ) {
+ qDebug(cursor->field(j)->name() + " type:" + TQString(cursor->field(j)->value().typeName()) + " value:" + cursor->field(j)->value().toString() );
+ }
+}
+#endif
+
+/*!
+ \enum TQDataTable::Refresh
+
+ This enum describes the refresh options.
+
+ \value RefreshData refresh the data, i.e. read it from the database
+ \value RefreshColumns refresh the list of fields, e.g. the column headings
+ \value RefreshAll refresh both the data and the list of fields
+*/
+
+
+/*!
+ \class TQDataTable tqdatatable.h
+ \brief The TQDataTable class provides a flexible SQL table widget that supports browsing and editing.
+
+ \ingroup database
+ \mainclass
+ \module sql
+
+ TQDataTable supports various functions for presenting and editing
+ SQL data from a \l TQSqlCursor in a table.
+
+ If you want a to present your data in a form use TQDataBrowser, or
+ for read-only forms, TQDataView.
+
+ When displaying data, TQDataTable only retrieves data for visible
+ rows. If the driver supports the 'query size' property the
+ TQDataTable will have the correct number of rows and the vertical
+ scrollbar will accurately reflect the number of rows displayed in
+ proportion to the number of rows in the dataset. If the driver
+ does not support the 'query size' property, rows are dynamically
+ fetched from the database on an as-needed basis with the scrollbar
+ becoming more accurate as the user scrolls down through the
+ records. This allows extremely large queries to be displayed as
+ quickly as possible, with minimum memory usage.
+
+ TQDataTable inherits TQTable's API and extends it with functions to
+ sort and filter the data and sort columns. See setSqlCursor(),
+ setFilter(), setSort(), setSorting(), sortColumn() and refresh().
+
+ When displaying editable cursors, cell editing will be enabled.
+ (For more information on editable cursors, see \l TQSqlCursor).
+ TQDataTable can be used to modify existing data and to add new
+ records. When a user makes changes to a field in the table, the
+ cursor's edit buffer is used. The table will not send changes in
+ the edit buffer to the database until the user moves to a
+ different record in the grid or presses Enter. Cell editing is
+ initiated by pressing F2 (or right clicking and then clicking the
+ appropriate popup menu item) and canceled by pressing Esc. If
+ there is a problem updating or adding data, errors are handled
+ automatically (see handleError() to change this behavior). Note
+ that if autoEdit() is FALSE navigating to another record will
+ cancel the insert or update.
+
+ The user can be asked to confirm all edits with setConfirmEdits().
+ For more precise control use setConfirmInsert(),
+ setConfirmUpdate(), setConfirmDelete() and setConfirmCancels().
+ Use setAutoEdit() to control the behaviour of the table when the
+ user edits a record and then navigates. (Note that setAutoDelete()
+ is unrelated; it is used to set whether the TQSqlCursor is deleted
+ when the table is deleted.)
+
+ Since the data table can perform edits, it must be able to
+ uniquely identify every record so that edits are correctly
+ applied. Because of this the underlying cursor must have a valid
+ primary index to ensure that a unique record is inserted, updated
+ or deleted within the database otherwise the database may be
+ changed to an inconsistent state.
+
+ TQDataTable creates editors using the default \l TQSqlEditorFactory.
+ Different editor factories can be used by calling
+ installEditorFactory(). A property map is used to map between the
+ cell's value and the editor. You can use your own property map
+ with installPropertyMap().
+
+ The contents of a cell is available as a TQString with text() or as
+ a TQVariant with value(). The current record is returned by
+ currentRecord(). Use the tqfind() function to search for a string in
+ the table.
+
+ Editing actions can be applied programatically. For example, the
+ insertCurrent() function reads the fields from the current record
+ into the cursor and performs the insert. The updateCurrent() and
+ deleteCurrent() functions perform similarly to update and delete
+ the current record respectively.
+
+ Columns in the table can be created automatically based on the
+ cursor (see setSqlCursor()). Columns can be manipulated manually
+ using addColumn(), removeColumn() and setColumn().
+
+ The table automatically copies many of the properties of the
+ cursor to format the display of data within cells (tqalignment,
+ visibility, etc.). The cursor can be changed with setSqlCursor().
+ The filter (see setFilter()) and sort defined within the table are
+ used instead of the filter and sort set on the cursor. For sorting
+ options see setSort(), sortColumn(), sortAscending() and
+ sortDescending(). Note that sorting operations will not behave as
+ expected if you are using a TQSqlSelectCursor because it uses
+ user-defined SQL queries to obtain data.
+
+ The text used to represent NULL, TRUE and FALSE values can be
+ changed with setNullText(), setTrueText() and setFalseText()
+ respectively. You can change the appearance of cells by
+ reimplementing paintField().
+
+ Whenever a new row is selected in the table the currentChanged()
+ signal is emitted. The primeInsert() signal is emitted when an
+ insert is initiated. The primeUpdate() and primeDelete() Q_SIGNALS
+ are emitted when update and deletion are initiated respectively.
+ Just before the database is updated a signal is emitted;
+ beforeInsert(), beforeUpdate() or beforeDelete() as appropriate.
+
+*/
+
+/*!
+ Constructs a data table which is a child of \a tqparent, called
+ name \a name.
+*/
+
+TQDataTable::TQDataTable ( TQWidget * tqparent, const char * name )
+ : TQTable( tqparent, name )
+{
+ init();
+}
+
+/*!
+ Constructs a data table which is a child of \a tqparent, called name
+ \a name using the cursor \a cursor.
+
+ If \a autoPopulate is TRUE (the default is FALSE), columns are
+ automatically created based upon the fields in the \a cursor
+ record. Note that \a autoPopulate only governs the creation of
+ columns; to load the cursor's data into the table use refresh().
+
+ If the \a cursor is read-only, the table also becomes read-only.
+ In addition, the table adopts the cursor's driver's definition for
+ representing NULL values as strings.
+*/
+
+TQDataTable::TQDataTable ( TQSqlCursor* cursor, bool autoPopulate, TQWidget * tqparent, const char * name )
+ : TQTable( tqparent, name )
+{
+ init();
+ setSqlCursor( cursor, autoPopulate );
+}
+
+/*! \internal
+*/
+
+
+void TQDataTable::init()
+{
+ d = new TQDataTablePrivate();
+ setAutoEdit( TRUE );
+ setSelectionMode( SingleRow );
+ setFocusStyle( FollowStyle );
+ d->trueTxt = tr( "True" );
+ d->falseTxt = tr( "False" );
+ d->datefmt = Qt::LocalDate;
+ reset();
+ connect( this, TQT_SIGNAL( selectionChanged() ),
+ TQT_SLOT( updateCurrentSelection()));
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQDataTable::~TQDataTable()
+{
+ delete d;
+}
+
+
+/*!
+ Adds the next column to be displayed using the field \a fieldName,
+ column label \a label, width \a width and iconset \a iconset.
+
+ If \a label is specified, it is used as the column's header label,
+ otherwise the field's display label is used when setSqlCursor() is
+ called. The \a iconset is used to set the icon used by the column
+ header; by default there is no icon.
+
+ \sa setSqlCursor() refresh()
+*/
+
+void TQDataTable::addColumn( const TQString& fieldName,
+ const TQString& label,
+ int width,
+ const TQIconSet& iconset )
+{
+ d->fld += fieldName;
+ d->fldLabel += label;
+ d->fldIcon += iconset;
+ d->fldWidth += width;
+ d->fldHidden += FALSE;
+}
+
+/*!
+ Sets the \a col column to display using the field \a fieldName,
+ column label \a label, width \a width and iconset \a iconset.
+
+ If \a label is specified, it is used as the column's header label,
+ otherwise the field's display label is used when setSqlCursor() is
+ called. The \a iconset is used to set the icon used by the column
+ header; by default there is no icon.
+
+ \sa setSqlCursor() refresh()
+*/
+
+void TQDataTable::setColumn( uint col, const TQString& fieldName,
+ const TQString& label,
+ int width,
+ const TQIconSet& iconset )
+{
+ d->fld[col]= fieldName;
+ d->fldLabel[col] = label;
+ d->fldIcon[col] = iconset;
+ d->fldWidth[col] = width;
+ d->fldHidden[col] = FALSE;
+}
+
+/*!
+ Removes column \a col from the list of columns to be displayed. If
+ \a col does not exist, nothing happens.
+
+ \sa TQSqlField
+*/
+
+void TQDataTable::removeColumn( uint col )
+{
+ if ( d->fld.at( col ) != d->fld.end() ) {
+ d->fld.remove( d->fld.at( col ) );
+ d->fldLabel.remove( d->fldLabel.at( col ) );
+ d->fldIcon.remove( d->fldIcon.at( col ) );
+ d->fldWidth.remove( d->fldWidth.at( col ) );
+ d->fldHidden.remove( d->fldHidden.at( col ) );
+ }
+}
+
+/*!
+ Sets the column \a col to the width \a w. Note that unlike TQTable
+ the TQDataTable is not immediately redrawn, you must call
+ refresh(TQDataTable::RefreshColumns)
+ yourself.
+
+ \sa refresh()
+*/
+void TQDataTable::setColumnWidth( int col, int w )
+{
+ if ( d->fldWidth.at( col ) != d->fldWidth.end() ) {
+ d->fldWidth[col] = w;
+ }
+}
+
+/*!
+ Resizes column \a col so that the column width is wide enough to
+ display the widest item the column tqcontains (including the column
+ label). If the table's TQSqlCursor is not currently active, the
+ cursor will be refreshed before the column width is calculated. Be
+ aware that this function may be slow on tables that contain large
+ result sets.
+*/
+void TQDataTable::adjustColumn( int col )
+{
+ TQSqlCursor * cur = sqlCursor();
+ if ( !cur || cur->count() <= (uint)col )
+ return;
+ if ( !cur->isActive() ) {
+ d->cur.refresh();
+ }
+ int oldRow = currentRow();
+ int w = fontMetrics().width( horizontalHeader()->label( col ) + "W" );
+ cur->seek( TQSql::BeforeFirst );
+ while ( cur->next() ) {
+ w = TQMAX( w, fontMetrics().width( fieldToString( cur->field( indexOf( col ) ) ) ) + 10 );
+ }
+ setColumnWidth( col, w );
+ cur->seek( oldRow );
+ refresh( RefreshColumns );
+}
+
+/*! \reimp
+*/
+void TQDataTable::setColumnStretchable( int col, bool s )
+{
+ if ( numCols() == 0 ) {
+ refresh( RefreshColumns );
+ }
+ if ( numCols() > col ) {
+ TQTable::setColumnStretchable( col, s );
+ }
+}
+
+TQString TQDataTable::filter() const
+{
+ return d->cur.filter();
+}
+
+/*!
+ \property TQDataTable::filter
+ \brief the data filter for the data table
+
+ The filter applies to the data shown in the table. To view data
+ with a new filter, use refresh(). A filter string is an SQL WHERE
+ clause without the WHERE keyword.
+
+ There is no default filter.
+
+ \sa sort()
+
+*/
+
+void TQDataTable::setFilter( const TQString& filter )
+{
+ d->cur.setFilter( filter );
+}
+
+
+/*!
+ \property TQDataTable::sort
+ \brief the data table's sort
+
+ The table's sort affects the order in which data records are
+ displayed in the table. To apply a sort, use refresh().
+
+ When examining the sort property, a string list is returned with
+ each item having the form 'fieldname order' (e.g., 'id ASC',
+ 'surname DESC').
+
+ There is no default sort.
+
+ Note that if you want to iterate over the sort list, you should
+ iterate over a copy, e.g.
+ \code
+ TQStringList list = myDataTable.sort();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa filter() refresh()
+*/
+
+void TQDataTable::setSort( const TQStringList& sort )
+{
+ d->cur.setSort( sort );
+}
+
+/*!
+ \overload
+
+ Sets the sort to be applied to the displayed data to \a sort. If
+ there is no current cursor, nothing happens. A TQSqlIndex tqcontains
+ field names and their ordering (ASC or DESC); these are used to
+ compose the ORDER BY clause.
+
+ \sa sort()
+*/
+
+void TQDataTable::setSort( const TQSqlIndex& sort )
+{
+ d->cur.setSort( sort );
+}
+
+TQStringList TQDataTable::sort() const
+{
+ return d->cur.sort();
+}
+
+/*!
+ Returns the cursor used by the data table.
+*/
+
+TQSqlCursor* TQDataTable::sqlCursor() const
+{
+ return d->cur.cursor();
+}
+
+void TQDataTable::setConfirmEdits( bool confirm )
+{
+ d->dat.setConfirmEdits( confirm );
+}
+
+void TQDataTable::setConfirmInsert( bool confirm )
+{
+ d->dat.setConfirmInsert( confirm );
+}
+
+void TQDataTable::setConfirmUpdate( bool confirm )
+{
+ d->dat.setConfirmUpdate( confirm );
+}
+
+void TQDataTable::setConfirmDelete( bool confirm )
+{
+ d->dat.setConfirmDelete( confirm );
+}
+
+/*!
+ \property TQDataTable::confirmEdits
+ \brief whether the data table confirms edit operations
+
+ If the confirmEdits property is TRUE, the data table confirms all
+ edit operations (inserts, updates and deletes). Finer control of
+ edit confirmation can be achieved using \l confirmCancels, \l
+ confirmInsert, \l confirmUpdate and \l confirmDelete.
+
+ \sa confirmCancels() confirmInsert() confirmUpdate() confirmDelete()
+*/
+
+bool TQDataTable::confirmEdits() const
+{
+ return ( d->dat.confirmEdits() );
+}
+
+/*!
+ \property TQDataTable::confirmInsert
+ \brief whether the data table confirms insert operations
+
+ If the confirmInsert property is TRUE, all insertions must be
+ confirmed by the user through a message box (this behaviour can be
+ changed by overriding the confirmEdit() function), otherwise all
+ insert operations occur immediately.
+
+ \sa confirmCancels() confirmEdits() confirmUpdate() confirmDelete()
+*/
+
+bool TQDataTable::confirmInsert() const
+{
+ return ( d->dat.confirmInsert() );
+}
+
+/*!
+ \property TQDataTable::confirmUpdate
+ \brief whether the data table confirms update operations
+
+ If the confirmUpdate property is TRUE, all updates must be
+ confirmed by the user through a message box (this behaviour can be
+ changed by overriding the confirmEdit() function), otherwise all
+ update operations occur immediately.
+
+ \sa confirmCancels() confirmEdits() confirmInsert() confirmDelete()
+*/
+
+bool TQDataTable::confirmUpdate() const
+{
+ return ( d->dat.confirmUpdate() );
+}
+
+/*!
+ \property TQDataTable::confirmDelete
+ \brief whether the data table confirms delete operations
+
+ If the confirmDelete property is TRUE, all deletions must be
+ confirmed by the user through a message box (this behaviour can be
+ changed by overriding the confirmEdit() function), otherwise all
+ delete operations occur immediately.
+
+ \sa confirmCancels() confirmEdits() confirmUpdate() confirmInsert()
+*/
+
+bool TQDataTable::confirmDelete() const
+{
+ return ( d->dat.confirmDelete() );
+}
+
+/*!
+ \property TQDataTable::confirmCancels
+ \brief whether the data table confirms cancel operations
+
+ If the confirmCancel property is TRUE, all cancels must be
+ confirmed by the user through a message box (this behavior can be
+ changed by overriding the confirmCancel() function), otherwise all
+ cancels occur immediately. The default is FALSE.
+
+ \sa confirmEdits() confirmCancel()
+*/
+
+void TQDataTable::setConfirmCancels( bool confirm )
+{
+ d->dat.setConfirmCancels( confirm );
+}
+
+bool TQDataTable::confirmCancels() const
+{
+ return d->dat.confirmCancels();
+}
+
+/*!
+ \reimp
+
+ For an editable table, creates an editor suitable for the field in
+ column \a col. The editor is created using the default editor
+ factory, unless a different editor factory was installed with
+ installEditorFactory(). The editor is primed with the value of the
+ field in \a col using a property map. The property map used is the
+ default property map, unless a new property map was installed with
+ installPropertMap(). If \a initFromCell is TRUE then the editor is
+ primed with the value in the TQDataTable cell.
+*/
+
+TQWidget * TQDataTable::createEditor( int , int col, bool initFromCell ) const
+{
+ if ( d->dat.mode() == TQSql::None )
+ return 0;
+
+ TQSqlEditorFactory * f = (d->editorFactory == 0) ?
+ TQSqlEditorFactory::defaultFactory() : d->editorFactory;
+
+ TQSqlPropertyMap * m = (d->propertyMap == 0) ?
+ TQSqlPropertyMap::defaultMap() : d->propertyMap;
+
+ TQWidget * w = 0;
+ if( initFromCell && d->editBuffer ){
+ w = f->createEditor( viewport(), d->editBuffer->field( indexOf( col ) ) );
+ if ( w )
+ m->setProperty( w, d->editBuffer->value( indexOf( col ) ) );
+ }
+ return w;
+}
+
+/*! \reimp */
+bool TQDataTable::eventFilter( TQObject *o, TQEvent *e )
+{
+ if ( d->cancelMode )
+ return TRUE;
+
+ int r = currentRow();
+ int c = currentColumn();
+
+ if ( d->dat.mode() != TQSql::None ) {
+ r = d->editRow;
+ c = d->editCol;
+ }
+
+ d->cancelInsert = FALSE;
+ d->cancelUpdate = FALSE;
+ switch ( e->type() ) {
+ case TQEvent::KeyPress: {
+ int conf = TQSql::Yes;
+ TQKeyEvent *ke = (TQKeyEvent*)e;
+ if ( ( ke->key() == Qt::Key_Tab || ke->key() == TQt::Key_BackTab )
+ && ke->state() & ControlButton )
+ return FALSE;
+
+ if ( ke->key() == Key_Escape && d->dat.mode() == TQSql::Insert ){
+ if ( confirmCancels() && !d->cancelMode ) {
+ d->cancelMode = TRUE;
+ conf = confirmCancel( TQSql::Insert );
+ d->cancelMode = FALSE;
+ }
+ if ( conf == TQSql::Yes ) {
+ d->cancelInsert = TRUE;
+ } else {
+ TQWidget *editorWidget = cellWidget( r, c );
+ if ( editorWidget ) {
+ editorWidget->setActiveWindow();
+ editorWidget->setFocus();
+ }
+ return TRUE;
+ }
+ }
+ if ( ke->key() == Key_Escape && d->dat.mode() == TQSql::Update ) {
+ if ( confirmCancels() && !d->cancelMode ) {
+ d->cancelMode = TRUE;
+ conf = confirmCancel( TQSql::Update );
+ d->cancelMode = FALSE;
+ }
+ if ( conf == TQSql::Yes ){
+ d->cancelUpdate = TRUE;
+ } else {
+ TQWidget *editorWidget = cellWidget( r, c );
+ if ( editorWidget ) {
+ editorWidget->setActiveWindow();
+ editorWidget->setFocus();
+ }
+ return TRUE;
+ }
+ }
+ if ( ke->key() == Qt::Key_Insert && d->dat.mode() == TQSql::None ) {
+ beginInsert();
+ return TRUE;
+ }
+ if ( ke->key() == Qt::Key_Delete && d->dat.mode() == TQSql::None ) {
+ deleteCurrent();
+ return TRUE;
+ }
+ if ( d->dat.mode() != TQSql::None ) {
+ if ( (ke->key() == Qt::Key_Tab) && (c < numCols() - 1) && (!isColumnReadOnly( c+1 ) || d->dat.mode() == TQSql::Insert) )
+ d->continuousEdit = TRUE;
+ else if ( (ke->key() == TQt::Key_BackTab) && (c > 0) && (!isColumnReadOnly( c-1 ) || d->dat.mode() == TQSql::Insert) )
+ d->continuousEdit = TRUE;
+ else
+ d->continuousEdit = FALSE;
+ }
+ TQSqlCursor * sql = sqlCursor();
+ if ( sql && sql->driver() &&
+ !sql->driver()->hasFeature( TQSqlDriver::QuerySize ) &&
+ ke->key() == Qt::Key_End && d->dat.mode() == TQSql::None ) {
+#ifndef TQT_NO_CURSOR
+ TQApplication::setOverrideCursor( TQt::WaitCursor );
+#endif
+ int i = sql->at();
+ if ( i < 0 ) {
+ i = 0;
+ sql->seek(0);
+ }
+ while ( sql->next() )
+ i++;
+ setNumRows( i+1 );
+ setCurrentCell( i+1, currentColumn() );
+#ifndef TQT_NO_CURSOR
+ TQApplication::restoreOverrideCursor();
+#endif
+ return TRUE;
+ }
+ break;
+ }
+ case TQEvent::FocusOut: {
+ TQWidget *editorWidget = cellWidget( r, c );
+ repaintCell( currentRow(), currentColumn() );
+ if ( !d->cancelMode && editorWidget && TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(editorWidget) &&
+ ( d->dat.mode() == TQSql::Insert) && !d->continuousEdit) {
+ setCurrentCell( r, c );
+ d->cancelInsert = TRUE;
+ }
+ d->continuousEdit = FALSE;
+ break;
+ }
+ case TQEvent::FocusIn:
+ repaintCell( currentRow(), currentColumn() );
+ break;
+ default:
+ break;
+ }
+ return TQTable::eventFilter( o, e );
+}
+
+/*! \reimp */
+void TQDataTable::resizeEvent ( TQResizeEvent * e )
+{
+ if ( sqlCursor() &&
+ sqlCursor()->driver() &&
+ !sqlCursor()->driver()->hasFeature( TQSqlDriver::QuerySize ) )
+ loadNextPage();
+ TQTable::resizeEvent( e );
+}
+
+/*! \reimp */
+void TQDataTable::contentsContextMenuEvent( TQContextMenuEvent* e )
+{
+ TQTable::contentsContextMenuEvent( e );
+ if ( isEditing() && d->dat.mode() != TQSql::None )
+ endEdit( d->editRow, d->editCol, autoEdit(), FALSE );
+ if ( !sqlCursor() )
+ return;
+ if ( d->dat.mode() == TQSql::None ) {
+ if ( isReadOnly() )
+ return;
+ enum {
+ IdInsert,
+ IdUpdate,
+ IdDelete
+ };
+ TQGuardedPtr<TQPopupMenu> popup = new TQPopupMenu( this, "qt_datatable_menu" );
+ int id[ 3 ];
+ id[ IdInsert ] = popup->insertItem( tr( "Insert" ) );
+ id[ IdUpdate ] = popup->insertItem( tr( "Update" ) );
+ id[ IdDelete ] = popup->insertItem( tr( "Delete" ) );
+ bool enableInsert = sqlCursor()->canInsert();
+ popup->setItemEnabled( id[ IdInsert ], enableInsert );
+ bool enableUpdate = currentRow() > -1 && sqlCursor()->canUpdate() && !isColumnReadOnly( currentColumn() );
+ popup->setItemEnabled( id[ IdUpdate ], enableUpdate );
+ bool enableDelete = currentRow() > -1 && sqlCursor()->canDelete();
+ popup->setItemEnabled( id[ IdDelete ], enableDelete );
+ int r = popup->exec( e->globalPos() );
+ delete (TQPopupMenu*) popup;
+ if ( r == id[ IdInsert ] )
+ beginInsert();
+ else if ( r == id[ IdUpdate ] ) {
+ if ( beginEdit( currentRow(), currentColumn(), FALSE ) )
+ setEditMode( Editing, currentRow(), currentColumn() );
+ else
+ endUpdate();
+ }
+ else if ( r == id[ IdDelete ] )
+ deleteCurrent();
+ e->accept();
+ }
+}
+
+/*! \reimp */
+void TQDataTable::contentsMousePressEvent( TQMouseEvent* e )
+{
+ TQTable::contentsMousePressEvent( e );
+}
+
+/*! \reimp */
+TQWidget* TQDataTable::beginEdit ( int row, int col, bool tqreplace )
+{
+ d->editRow = -1;
+ d->editCol = -1;
+ if ( !sqlCursor() )
+ return 0;
+ if ( d->dat.mode() == TQSql::Insert && !sqlCursor()->canInsert() )
+ return 0;
+ if ( d->dat.mode() == TQSql::Update && !sqlCursor()->canUpdate() )
+ return 0;
+ d->editRow = row;
+ d->editCol = col;
+ if ( d->continuousEdit ) {
+ // see comment in beginInsert()
+ bool fakeReadOnly = isColumnReadOnly( col );
+ setColumnReadOnly( col, FALSE );
+ TQWidget* w = TQTable::beginEdit( row, col, tqreplace );
+ setColumnReadOnly( col, fakeReadOnly );
+ return w;
+ }
+ if ( d->dat.mode() == TQSql::None && sqlCursor()->canUpdate() && sqlCursor()->primaryIndex().count() > 0 )
+ return beginUpdate( row, col, tqreplace );
+ return 0;
+}
+
+/*! \reimp */
+void TQDataTable::endEdit( int row, int col, bool, bool )
+{
+ bool accept = autoEdit() && !d->cancelInsert && !d->cancelUpdate;
+
+ TQWidget *editor = cellWidget( row, col );
+ if ( !editor )
+ return;
+ if ( d->cancelMode )
+ return;
+ if ( d->dat.mode() != TQSql::None && d->editBuffer ) {
+ TQSqlPropertyMap * m = (d->propertyMap == 0) ?
+ TQSqlPropertyMap::defaultMap() : d->propertyMap;
+ d->editBuffer->setValue( indexOf( col ), m->property( editor ) );
+ clearCellWidget( row, col );
+ if ( !d->continuousEdit ) {
+ switch ( d->dat.mode() ) {
+ case TQSql::Insert:
+ if ( accept )
+ TQTimer::singleShot( 0, this, TQT_SLOT( doInsertCurrent() ) );
+ else
+ endInsert();
+ break;
+ case TQSql::Update:
+ if ( accept )
+ TQTimer::singleShot( 0, this, TQT_SLOT( doUpdateCurrent() ) );
+ else
+ endUpdate();
+ break;
+ default:
+ break;
+ }
+ }
+ } else {
+ setEditMode( NotEditing, -1, -1 );
+ }
+ if ( d->dat.mode() == TQSql::None )
+ viewport()->setFocus();
+ updateCell( row, col );
+ emit valueChanged( row, col );
+}
+
+/*! \internal */
+void TQDataTable::doInsertCurrent()
+{
+ insertCurrent();
+}
+
+/*! \internal */
+void TQDataTable::doUpdateCurrent()
+{
+ updateCurrent();
+ if ( d->dat.mode() == TQSql::None ) {
+ viewport()->setFocus();
+ }
+}
+
+/*! \reimp */
+void TQDataTable::activateNextCell()
+{
+// if ( d->dat.mode() == TQSql::None )
+// TQTable::activateNextCell();
+}
+
+/*! \internal
+*/
+
+void TQDataTable::endInsert()
+{
+ if ( d->dat.mode() != TQSql::Insert )
+ return;
+ d->dat.setMode( TQSql::None );
+ d->editBuffer = 0;
+ verticalHeader()->setLabel( d->editRow, TQString::number( d->editRow +1 ) );
+ d->editRow = -1;
+ d->editCol = -1;
+ d->insertRowLast = -1;
+ d->insertHeaderLabelLast = TQString::null;
+ setEditMode( NotEditing, -1, -1 );
+ setNumRows( d->insertPreRows );
+ d->insertPreRows = -1;
+ viewport()->setFocus();
+}
+
+/*! \internal
+*/
+
+void TQDataTable::endUpdate()
+{
+ d->dat.setMode( TQSql::None );
+ d->editBuffer = 0;
+ updateRow( d->editRow );
+ d->editRow = -1;
+ d->editCol = -1;
+ setEditMode( NotEditing, -1, -1 );
+}
+
+/*!
+ Protected virtual function called when editing is about to begin
+ on a new record. If the table is read-only, or if there's no
+ cursor or the cursor does not allow inserts, nothing happens.
+
+ Editing takes place using the cursor's edit buffer(see
+ TQSqlCursor::editBuffer()).
+
+ When editing begins, a new row is created in the table marked with
+ an asterisk '*' in the row's vertical header column, i.e. at the
+ left of the row.
+*/
+
+bool TQDataTable::beginInsert()
+{
+ if ( !sqlCursor() || isReadOnly() || !numCols() )
+ return FALSE;
+ if ( !sqlCursor()->canInsert() )
+ return FALSE;
+ int i = 0;
+ int row = currentRow();
+
+ d->insertPreRows = numRows();
+ if ( row < 0 || numRows() < 1 )
+ row = 0;
+ setNumRows( d->insertPreRows + 1 );
+ setCurrentCell( row, 0 );
+ d->editBuffer = sqlCursor()->primeInsert();
+ emit primeInsert( d->editBuffer );
+ d->dat.setMode( TQSql::Insert );
+ int lastRow = row;
+ int lastY = contentsY() + visibleHeight();
+ for ( i = row; i < numRows() ; ++i ) {
+ TQRect cg = cellGeometry( i, 0 );
+ if ( (cg.y()+cg.height()) > lastY ) {
+ lastRow = i;
+ break;
+ }
+ }
+ if ( lastRow == row && ( numRows()-1 > row ) )
+ lastRow = numRows() - 1;
+ d->insertRowLast = lastRow;
+ d->insertHeaderLabelLast = verticalHeader()->label( d->insertRowLast );
+ verticalHeader()->setLabel( row, "*" );
+ d->editRow = row;
+ // in the db world it's common to allow inserting new records
+ // into a table that has read-only columns - temporarily
+ // switch off read-only mode for such columns
+ bool fakeReadOnly = isColumnReadOnly( 0 );
+ setColumnReadOnly( 0, FALSE );
+ if ( TQTable::beginEdit( row, 0, FALSE ) )
+ setEditMode( Editing, row, 0 );
+ setColumnReadOnly( 0, fakeReadOnly );
+ return TRUE;
+}
+
+/*!
+ Protected virtual function called when editing is about to begin
+ on an existing row. If the table is read-only, or if there's no
+ cursor, nothing happens.
+
+ Editing takes place using the cursor's edit buffer (see
+ TQSqlCursor::editBuffer()).
+
+ \a row and \a col refer to the row and column in the TQDataTable.
+
+ (\a tqreplace is provided for reimplementors and reflects the API of
+ TQTable::beginEdit().)
+*/
+
+TQWidget* TQDataTable::beginUpdate ( int row, int col, bool tqreplace )
+{
+ if ( !sqlCursor() || isReadOnly() || isColumnReadOnly( col ) )
+ return 0;
+ setCurrentCell( row, col );
+ d->dat.setMode( TQSql::Update );
+ if ( sqlCursor()->seek( row ) ) {
+ d->editBuffer = sqlCursor()->primeUpdate();
+ sqlCursor()->seek( currentRow() );
+ emit primeUpdate( d->editBuffer );
+ return TQTable::beginEdit( row, col, tqreplace );
+ }
+ return 0;
+}
+
+/*!
+ For an editable table, issues an insert on the current cursor
+ using the values in the cursor's edit buffer. If there is no
+ current cursor or there is no current "insert" row, nothing
+ happens. If confirmEdits() or confirmInsert() is TRUE,
+ confirmEdit() is called to confirm the insert. Returns TRUE if the
+ insert succeeded; otherwise returns FALSE.
+
+ The underlying cursor must have a valid primary index to ensure
+ that a unique record is inserted within the database otherwise the
+ database may be changed to an inconsistent state.
+*/
+
+bool TQDataTable::insertCurrent()
+{
+ if ( d->dat.mode() != TQSql::Insert || ! numCols() )
+ return FALSE;
+ if ( !sqlCursor()->canInsert() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQDataTable::insertCurrent: insert not allowed for %s",
+ sqlCursor()->name().latin1() );
+#endif
+ endInsert();
+ return FALSE;
+ }
+ int b = 0;
+ int conf = TQSql::Yes;
+ if ( confirmEdits() || confirmInsert() )
+ conf = confirmEdit( TQSql::Insert );
+ switch ( conf ) {
+ case TQSql::Yes: {
+#ifndef TQT_NO_CURSOR
+ TQApplication::setOverrideCursor( Qt::WaitCursor );
+#endif
+ emit beforeInsert( d->editBuffer );
+ b = sqlCursor()->insert();
+#ifndef TQT_NO_CURSOR
+ TQApplication::restoreOverrideCursor();
+#endif
+ if ( ( !b && !sqlCursor()->isActive() ) || !sqlCursor()->isActive() ) {
+ handleError( sqlCursor()->lastError() );
+ endInsert(); // cancel the insert if anything goes wrong
+ refresh();
+ } else {
+ endInsert();
+ refresh();
+ TQSqlIndex idx = sqlCursor()->primaryIndex();
+ tqfindBuffer( idx, d->lastAt );
+ repaintContents( contentsX(), contentsY(), visibleWidth(), visibleHeight(), FALSE );
+ emit cursorChanged( TQSql::Insert );
+ }
+ break;
+ }
+ case TQSql::No:
+ endInsert();
+ break;
+ case TQSql::Cancel:
+ if ( TQTable::beginEdit( currentRow(), currentColumn(), FALSE ) )
+ setEditMode( Editing, currentRow(), currentColumn() );
+ break;
+ }
+ return ( b > 0 );
+}
+
+/*! \internal
+
+ Updates the row \a row.
+*/
+
+void TQDataTable::updateRow( int row )
+{
+ for ( int i = 0; i < numCols(); ++i )
+ updateCell( row, i );
+}
+
+/*!
+ For an editable table, issues an update using the cursor's edit
+ buffer. If there is no current cursor or there is no current
+ selection, nothing happens. If confirmEdits() or confirmUpdate()
+ is TRUE, confirmEdit() is called to confirm the update. Returns
+ TRUE if the update succeeded; otherwise returns FALSE.
+
+ The underlying cursor must have a valid primary index to ensure
+ that a unique record is updated within the database otherwise the
+ database may be changed to an inconsistent state.
+*/
+
+bool TQDataTable::updateCurrent()
+{
+ if ( d->dat.mode() != TQSql::Update )
+ return FALSE;
+ if ( sqlCursor()->primaryIndex().count() == 0 ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQDataTable::updateCurrent: no primary index for %s",
+ sqlCursor()->name().latin1() );
+#endif
+ endUpdate();
+ return FALSE;
+ }
+ if ( !sqlCursor()->canUpdate() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQDataTable::updateCurrent: updates not allowed for %s",
+ sqlCursor()->name().latin1() );
+#endif
+ endUpdate();
+ return FALSE;
+ }
+ int b = 0;
+ int conf = TQSql::Yes;
+ if ( confirmEdits() || confirmUpdate() )
+ conf = confirmEdit( TQSql::Update );
+ switch ( conf ) {
+ case TQSql::Yes: {
+#ifndef TQT_NO_CURSOR
+ TQApplication::setOverrideCursor( Qt::WaitCursor );
+#endif
+ emit beforeUpdate( d->editBuffer );
+ b = sqlCursor()->update();
+#ifndef TQT_NO_CURSOR
+ TQApplication::restoreOverrideCursor();
+#endif
+ if ( ( !b && !sqlCursor()->isActive() ) || !sqlCursor()->isActive() ) {
+ handleError( sqlCursor()->lastError() );
+ endUpdate();
+ refresh();
+ setCurrentCell( d->editRow, d->editCol );
+ if ( TQTable::beginEdit( d->editRow, d->editCol, FALSE ) )
+ setEditMode( Editing, d->editRow, d->editCol );
+ } else {
+ emit cursorChanged( TQSql::Update );
+ refresh();
+ endUpdate();
+ }
+ break;
+ }
+ case TQSql::No:
+ endUpdate();
+ setEditMode( NotEditing, -1, -1 );
+ break;
+ case TQSql::Cancel:
+ setCurrentCell( d->editRow, d->editCol );
+ if ( TQTable::beginEdit( d->editRow, d->editCol, FALSE ) )
+ setEditMode( Editing, d->editRow, d->editCol );
+ break;
+ }
+ return ( b > 0 );
+}
+
+/*!
+ For an editable table, issues a delete on the current cursor's
+ primary index using the values of the currently selected row. If
+ there is no current cursor or there is no current selection,
+ nothing happens. If confirmEdits() or confirmDelete() is TRUE,
+ confirmEdit() is called to confirm the delete. Returns TRUE if the
+ delete succeeded; otherwise FALSE.
+
+ The underlying cursor must have a valid primary index to ensure
+ that a unique record is deleted within the database otherwise the
+ database may be changed to an inconsistent state.
+*/
+
+bool TQDataTable::deleteCurrent()
+{
+ if ( !sqlCursor() || isReadOnly() )
+ return FALSE;
+ if ( sqlCursor()->primaryIndex().count() == 0 ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQDataTable::deleteCurrent: no primary index %s",
+ sqlCursor()->name().latin1() );
+#endif
+ return FALSE;
+ }
+ if ( !sqlCursor()->canDelete() )
+ return FALSE;
+
+ int b = 0;
+ int conf = TQSql::Yes;
+ if ( confirmEdits() || confirmDelete() )
+ conf = confirmEdit( TQSql::Delete );
+
+ // Have to have this here - the confirmEdit() might pop up a
+ // dialog that causes a tqrepaint which the cursor to the
+ // record it has to tqrepaint.
+ if ( !sqlCursor()->seek( currentRow() ) )
+ return FALSE;
+ switch ( conf ) {
+ case TQSql::Yes:{
+#ifndef TQT_NO_CURSOR
+ TQApplication::setOverrideCursor( Qt::WaitCursor );
+#endif
+ sqlCursor()->primeDelete();
+ emit primeDelete( sqlCursor()->editBuffer() );
+ emit beforeDelete( sqlCursor()->editBuffer() );
+ b = sqlCursor()->del();
+#ifndef TQT_NO_CURSOR
+ TQApplication::restoreOverrideCursor();
+#endif
+ if ( !b )
+ handleError( sqlCursor()->lastError() );
+ refresh();
+ emit cursorChanged( TQSql::Delete );
+ setCurrentCell( currentRow(), currentColumn() );
+ repaintContents( contentsX(), contentsY(), visibleWidth(), visibleHeight(), FALSE );
+ verticalHeader()->tqrepaint(); // get rid of trailing garbage
+ }
+ break;
+ case TQSql::No:
+ setEditMode( NotEditing, -1, -1 );
+ break;
+ }
+ return ( b > 0 );
+}
+
+/*!
+ Protected virtual function which returns a confirmation for an
+ edit of mode \a m. Derived classes can reimplement this function
+ to provide their own confirmation dialog. The default
+ implementation uses a message box which prompts the user to
+ confirm the edit action.
+*/
+
+TQSql::Confirm TQDataTable::confirmEdit( TQSql::Op m )
+{
+ return d->dat.confirmEdit( this, m );
+}
+
+/*!
+ Protected virtual function which returns a confirmation for
+ cancelling an edit mode of \a m. Derived classes can reimplement
+ this function to provide their own cancel dialog. The default
+ implementation uses a message box which prompts the user to
+ confirm the cancel.
+*/
+
+TQSql::Confirm TQDataTable::confirmCancel( TQSql::Op m )
+{
+ return d->dat.confirmCancel( this, m );
+}
+
+
+/*!
+ Searches the current cursor for a cell containing the string \a
+ str starting at the current cell and working forwards (or
+ backwards if \a backwards is TRUE). If the string is found, the
+ cell containing the string is set as the current cell. If \a
+ caseSensitive is FALSE the case of \a str will be ignored.
+
+ The search will wrap, i.e. if the first (or if backwards is TRUE,
+ last) cell is reached without tqfinding \a str the search will
+ continue until it reaches the starting cell. If \a str is not
+ found the search will fail and the current cell will remain
+ unchanged.
+*/
+void TQDataTable::tqfind( const TQString & str, bool caseSensitive, bool backwards )
+{
+ if ( !sqlCursor() )
+ return;
+
+ TQSqlCursor * r = sqlCursor();
+ TQString tmp, text;
+ uint row = currentRow(), startRow = row,
+ col = backwards ? currentColumn() - 1 : currentColumn() + 1;
+ bool wrap = TRUE, found = FALSE;
+
+ if( str.isEmpty() || str.isNull() )
+ return;
+
+ if( !caseSensitive )
+ tmp = str.lower();
+ else
+ tmp = str;
+
+#ifndef TQT_NO_CURSOR
+ TQApplication::setOverrideCursor( Qt::WaitCursor );
+#endif
+ while( wrap ){
+ while( !found && r->seek( row ) ){
+ for( int i = col; backwards ? (i >= 0) : (i < (int) numCols());
+ backwards ? i-- : i++ )
+ {
+ text = r->value( indexOf( i ) ).toString();
+ if( !caseSensitive ){
+ text = text.lower();
+ }
+ if( text.tqcontains( tmp ) ){
+ setCurrentCell( row, i );
+ col = i;
+ found = TRUE;
+ }
+ }
+ if( !backwards ){
+ col = 0;
+ row++;
+ } else {
+ col = numCols() - 1;
+ row--;
+ }
+ }
+ if( !backwards ){
+ if( startRow != 0 ){
+ startRow = 0;
+ } else {
+ wrap = FALSE;
+ }
+ r->first();
+ row = 0;
+ } else {
+ if( startRow != (uint) (numRows() - 1) ){
+ startRow = numRows() - 1;
+ } else {
+ wrap = FALSE;
+ }
+ r->last();
+ row = numRows() - 1;
+ }
+ }
+#ifndef TQT_NO_CURSOR
+ TQApplication::restoreOverrideCursor();
+#endif
+}
+
+
+/*!
+ Resets the table so that it displays no data.
+
+ \sa setSqlCursor()
+*/
+
+void TQDataTable::reset()
+{
+ clearCellWidget( currentRow(), currentColumn() );
+ switch ( d->dat.mode() ) {
+ case TQSql::Insert:
+ endInsert();
+ break;
+ case TQSql::Update:
+ endUpdate();
+ break;
+ default:
+ break;
+ }
+ ensureVisible( 0, 0 );
+ verticalScrollBar()->setValue(0);
+ setNumRows(0);
+
+ d->haveAllRows = FALSE;
+ d->continuousEdit = FALSE;
+ d->dat.setMode( TQSql::None );
+ d->editRow = -1;
+ d->editCol = -1;
+ d->insertRowLast = -1;
+ d->insertHeaderLabelLast = TQString::null;
+ d->cancelMode = FALSE;
+ d->lastAt = -1;
+ d->fld.clear();
+ d->fldLabel.clear();
+ d->fldWidth.clear();
+ d->fldIcon.clear();
+ d->fldHidden.clear();
+ if ( sorting() )
+ horizontalHeader()->setSortIndicator( -1 );
+}
+
+/*!
+ Returns the index of the field within the current SQL query that
+ is displayed in column \a i.
+*/
+
+int TQDataTable::indexOf( uint i ) const
+{
+ TQDataTablePrivate::ColIndex::ConstIterator it = d->colIndex.at( i );
+ if ( it != d->colIndex.end() )
+ return *it;
+ return -1;
+}
+
+/*!
+ Returns TRUE if the table will automatically delete the cursor
+ specified by setSqlCursor(); otherwise returns FALSE.
+*/
+
+bool TQDataTable::autoDelete() const
+{
+ return d->cur.autoDelete();
+}
+
+/*!
+ Sets the cursor auto-delete flag to \a enable. If \a enable is
+ TRUE, the table will automatically delete the cursor specified by
+ setSqlCursor(). If \a enable is FALSE (the default), the cursor
+ will not be deleted.
+*/
+
+void TQDataTable::setAutoDelete( bool enable )
+{
+ d->cur.setAutoDelete( enable );
+}
+
+/*!
+ \property TQDataTable::autoEdit
+ \brief whether the data table automatically applies edits
+
+ The default value for this property is TRUE. When the user begins
+ an insert or update in the table there are two possible outcomes
+ when they navigate to another record:
+
+ \list 1
+ \i the insert or update is is performed -- this occurs if autoEdit is TRUE
+ \i the insert or update is abandoned -- this occurs if autoEdit is FALSE
+ \endlist
+*/
+
+void TQDataTable::setAutoEdit( bool autoEdit )
+{
+ d->dat.setAutoEdit( autoEdit );
+}
+
+bool TQDataTable::autoEdit() const
+{
+ return d->dat.autoEdit();
+}
+
+/*!
+ \property TQDataTable::nullText
+ \brief the text used to represent NULL values
+
+ The nullText property will be used to represent NULL values in the
+ table. The default value is provided by the cursor's driver.
+*/
+
+void TQDataTable::setNullText( const TQString& nullText )
+{
+ d->nullTxt = nullText;
+ d->nullTxtChanged = TRUE;
+}
+
+TQString TQDataTable::nullText() const
+{
+ return d->nullTxt;
+}
+
+/*!
+ \property TQDataTable::trueText
+ \brief the text used to represent true values
+
+ The trueText property will be used to represent NULL values in the
+ table. The default value is "True".
+*/
+
+void TQDataTable::setTrueText( const TQString& trueText )
+{
+ d->trueTxt = trueText;
+}
+
+TQString TQDataTable::trueText() const
+{
+ return d->trueTxt;
+}
+
+/*!
+ \property TQDataTable::falseText
+ \brief the text used to represent false values
+
+ The falseText property will be used to represent NULL values in
+ the table. The default value is "False".
+*/
+
+void TQDataTable::setFalseText( const TQString& falseText )
+{
+ d->falseTxt = falseText;
+}
+
+TQString TQDataTable::falseText() const
+{
+ return d->falseTxt;
+}
+
+/*!
+ \property TQDataTable::dateFormat
+ \brief the format used for displaying date/time values
+
+ The dateFormat property is used for displaying date/time values in
+ the table. The default value is \c TQt::LocalDate.
+*/
+
+void TQDataTable::setDateFormat( const Qt::DateFormat f )
+{
+ d->datefmt = f;
+}
+
+Qt::DateFormat TQDataTable::dateFormat() const
+{
+ return d->datefmt;
+}
+
+/*!
+ \property TQDataTable::numRows
+
+ \brief the number of rows in the table
+*/
+
+int TQDataTable::numRows() const
+{
+ return TQTable::numRows();
+}
+
+/*!
+ \reimp
+
+ The number of rows in the table will be determined by the cursor
+ (see setSqlCursor()), so normally this function should never be
+ called. It is included for completeness.
+*/
+
+void TQDataTable::setNumRows ( int r )
+{
+ TQTable::setNumRows( r );
+}
+
+/*!
+ \reimp
+
+ The number of columns in the table will be determined
+ automatically (see addColumn()), so normally this function should
+ never be called. It is included for completeness.
+*/
+
+void TQDataTable::setNumCols ( int r )
+{
+ TQTable::setNumCols( r );
+}
+
+/*!
+ \property TQDataTable::numCols
+
+ \brief the number of columns in the table
+*/
+
+int TQDataTable::numCols() const
+{
+ return TQTable::numCols();
+}
+
+/*!
+ Returns the text in cell \a row, \a col, or an empty string if the
+ cell is empty. If the cell's value is NULL then nullText() will be
+ returned. If the cell does not exist then TQString::null is
+ returned.
+*/
+
+TQString TQDataTable::text ( int row, int col ) const
+{
+ if ( !sqlCursor() )
+ return TQString::null;
+
+ TQString s;
+ if ( sqlCursor()->seek( row ) )
+ s = sqlCursor()->value( indexOf( col ) ).toString();
+ sqlCursor()->seek( currentRow() );
+ return s;
+}
+
+/*!
+ Returns the value in cell \a row, \a col, or an invalid value if
+ the cell does not exist or has no value.
+*/
+
+TQVariant TQDataTable::value ( int row, int col ) const
+{
+ if ( !sqlCursor() )
+ return TQVariant();
+
+ TQVariant v;
+ if ( sqlCursor()->seek( row ) )
+ v = sqlCursor()->value( indexOf( col ) );
+ sqlCursor()->seek( currentRow() );
+ return v;
+}
+
+/*! \internal
+ Used to update the table when the size of the result set cannot be
+ determined - divide the result set into pages and load the pages as
+ the user moves around in the table.
+*/
+void TQDataTable::loadNextPage()
+{
+ if ( d->haveAllRows )
+ return;
+ if ( !sqlCursor() )
+ return;
+ int pageSize = 0;
+ int lookAhead = 0;
+ if ( height() ) {
+ pageSize = (int)( height() * 2 / 20 );
+ lookAhead = pageSize / 2;
+ }
+ int startIdx = verticalScrollBar()->value() / 20;
+ int endIdx = startIdx + pageSize + lookAhead;
+ if ( endIdx < numRows() || endIdx < 0 )
+ return;
+
+ // check for empty result set
+ if ( sqlCursor()->at() == TQSql::BeforeFirst && !sqlCursor()->next() ) {
+ d->haveAllRows = TRUE;
+ return;
+ }
+
+ while ( endIdx > 0 && !sqlCursor()->seek( endIdx ) )
+ endIdx--;
+ if ( endIdx != ( startIdx + pageSize + lookAhead ) )
+ d->haveAllRows = TRUE;
+ // small hack to prevent TQTable from moving the view when a row
+ // is selected and the contents is resized
+ SelectionMode m = selectionMode();
+ clearSelection();
+ setSelectionMode( NoSelection );
+ setNumRows( endIdx + 1 );
+ sqlCursor()->seek( currentRow() );
+ setSelectionMode( m );
+}
+
+/*! \internal */
+void TQDataTable::sliderPressed()
+{
+ disconnect( verticalScrollBar(), TQT_SIGNAL( valueChanged(int) ),
+ this, TQT_SLOT( loadNextPage() ) );
+}
+
+/*! \internal */
+void TQDataTable::sliderReleased()
+{
+ loadNextPage();
+ connect( verticalScrollBar(), TQT_SIGNAL( valueChanged(int) ),
+ this, TQT_SLOT( loadNextPage() ) );
+}
+
+/*!
+ Sorts column \a col in ascending order if \a ascending is TRUE
+ (the default); otherwise sorts in descending order.
+
+ The \a wholeRows parameter is ignored; TQDataTable always sorts
+ whole rows by the specified column.
+*/
+
+void TQDataTable::sortColumn ( int col, bool ascending,
+ bool )
+{
+ if ( sorting() ) {
+ if ( isEditing() && d->dat.mode() != TQSql::None )
+ endEdit( d->editRow, d->editCol, autoEdit(), FALSE );
+ if ( !sqlCursor() )
+ return;
+ TQSqlIndex lastSort = sqlCursor()->sort();
+ TQSqlIndex newSort( lastSort.cursorName(), "newSort" );
+ TQSqlField *field = sqlCursor()->field( indexOf( col ) );
+ if ( field )
+ newSort.append( *field );
+ newSort.setDescending( 0, !ascending );
+ horizontalHeader()->setSortIndicator( col, ascending );
+ setSort( newSort );
+ refresh();
+ }
+}
+
+/*! \reimp */
+void TQDataTable::columnClicked ( int col )
+{
+ if ( sorting() ) {
+ if ( !sqlCursor() )
+ return;
+ TQSqlIndex lastSort = sqlCursor()->sort();
+ bool asc = TRUE;
+ if ( lastSort.count() && lastSort.field( 0 )->name() == sqlCursor()->field( indexOf( col ) )->name() )
+ asc = lastSort.isDescending( 0 );
+ sortColumn( col, asc );
+ emit currentChanged( sqlCursor() );
+ }
+}
+
+/*!
+ \reimp
+
+ Repaints the cell at \a row, \a col.
+*/
+void TQDataTable::repaintCell( int row, int col )
+{
+ TQRect cg = cellGeometry( row, col );
+ TQRect re( TQPoint( cg.x() - 2, cg.y() - 2 ),
+ TQSize( cg.width() + 4, cg.height() + 4 ) );
+ repaintContents( re, FALSE );
+}
+
+/*!
+ \reimp
+
+ This function renders the cell at \a row, \a col with the value of
+ the corresponding cursor field on the painter \a p. Depending on
+ the table's current edit mode, paintField() is called for the
+ appropriate cursor field. \a cr describes the cell coordinates in
+ the content coordinate system. If \a selected is TRUE the cell has
+ been selected and would normally be rendered differently than an
+ unselected cell.
+
+ \sa TQSql::isNull()
+*/
+
+void TQDataTable::paintCell( TQPainter * p, int row, int col, const TQRect & cr,
+ bool selected, const TQColorGroup &cg )
+{
+ TQTable::paintCell( p, row, col, cr, selected, cg ); // empty cell
+
+ if ( !sqlCursor() )
+ return;
+
+ p->setPen( selected ? cg.highlightedText() : cg.text() );
+ if ( d->dat.mode() != TQSql::None ) {
+ if ( row == d->editRow && d->editBuffer ) {
+ paintField( p, d->editBuffer->field( indexOf( col ) ), cr,
+ selected );
+ } else if ( row > d->editRow && d->dat.mode() == TQSql::Insert ) {
+ if ( sqlCursor()->seek( row - 1 ) )
+ paintField( p, sqlCursor()->field( indexOf( col ) ), cr,
+ selected );
+ } else {
+ if ( sqlCursor()->seek( row ) )
+ paintField( p, sqlCursor()->field( indexOf( col ) ), cr,
+ selected );
+ }
+ } else {
+ if ( sqlCursor()->seek( row ) )
+ paintField( p, sqlCursor()->field( indexOf( col ) ), cr, selected );
+
+ }
+}
+
+
+/*!
+ Paints the \a field on the painter \a p. The painter has already
+ been translated to the appropriate cell's origin where the \a
+ field is to be rendered. \a cr describes the cell coordinates in
+ the content coordinate system. The \a selected parameter is
+ ignored.
+
+ If you want to draw custom field content you must reimplement
+ paintField() to do the custom drawing. The default implementation
+ renders the \a field value as text. If the field is NULL,
+ nullText() is displayed in the cell. If the field is Boolean,
+ trueText() or falseText() is displayed as appropriate.
+*/
+
+void TQDataTable::paintField( TQPainter * p, const TQSqlField* field,
+ const TQRect & cr, bool )
+{
+ if ( !field )
+ return;
+ p->drawText( 2,2, cr.width()-4, cr.height()-4, fieldAlignment( field ), fieldToString( field ) );
+}
+
+/*!
+ Returns the tqalignment for \a field.
+*/
+
+int TQDataTable::fieldAlignment( const TQSqlField* /*field*/ )
+{
+ return TQt::AlignLeft | TQt::AlignVCenter; //## Reggie: add tqalignment to TQTable
+}
+
+
+/*!
+ If the cursor's \a sql driver supports query sizes, the number of
+ rows in the table is set to the size of the query. Otherwise, the
+ table dynamically resizes itself as it is scrolled. If \a sql is
+ not active, it is made active by issuing a select() on the cursor
+ using the \a sql cursor's current filter and current sort.
+*/
+
+void TQDataTable::setSize( TQSqlCursor* sql )
+{
+ // ### what are the connect/disconnect calls doing here!? move to refresh()
+ if ( sql->driver() && sql->driver()->hasFeature( TQSqlDriver::QuerySize ) ) {
+ setVScrollBarMode( Auto );
+ disconnect( verticalScrollBar(), TQT_SIGNAL( sliderPressed() ),
+ this, TQT_SLOT( sliderPressed() ) );
+ disconnect( verticalScrollBar(), TQT_SIGNAL( sliderReleased() ),
+ this, TQT_SLOT( sliderReleased() ) );
+ disconnect( verticalScrollBar(), TQT_SIGNAL( valueChanged(int) ),
+ this, TQT_SLOT( loadNextPage() ) );
+ if ( numRows() != sql->size() )
+ setNumRows( sql->size() );
+ } else {
+ setVScrollBarMode( AlwaysOn );
+ connect( verticalScrollBar(), TQT_SIGNAL( sliderPressed() ),
+ this, TQT_SLOT( sliderPressed() ) );
+ connect( verticalScrollBar(), TQT_SIGNAL( sliderReleased() ),
+ this, TQT_SLOT( sliderReleased() ) );
+ connect( verticalScrollBar(), TQT_SIGNAL( valueChanged(int) ),
+ this, TQT_SLOT( loadNextPage() ) );
+ setNumRows(0);
+ loadNextPage();
+ }
+}
+
+/*!
+ Sets \a cursor as the data source for the table. To force the
+ display of the data from \a cursor, use refresh(). If \a
+ autoPopulate is TRUE, columns are automatically created based upon
+ the fields in the \a cursor record. If \a autoDelete is TRUE (the
+ default is FALSE), the table will take ownership of the \a cursor
+ and delete it when appropriate. If the \a cursor is read-only, the
+ table becomes read-only. The table adopts the cursor's driver's
+ definition for representing NULL values as strings.
+
+ \sa refresh() setReadOnly() setAutoDelete() TQSqlDriver::nullText()
+*/
+
+void TQDataTable::setSqlCursor( TQSqlCursor* cursor, bool autoPopulate, bool autoDelete )
+{
+ setUpdatesEnabled( FALSE );
+ d->cur.setCursor( 0 );
+ if ( cursor ) {
+ d->cur.setCursor( cursor, autoDelete );
+ if ( autoPopulate ) {
+ d->fld.clear();
+ d->fldLabel.clear();
+ d->fldWidth.clear();
+ d->fldIcon.clear();
+ d->fldHidden.clear();
+ for ( uint i = 0; i < sqlCursor()->count(); ++i ) {
+ addColumn( sqlCursor()->field( i )->name(), sqlCursor()->field( i )->name() );
+ setColumnReadOnly( i, sqlCursor()->field( i )->isReadOnly() );
+ }
+ }
+ setReadOnly( sqlCursor()->isReadOnly() );
+ if ( sqlCursor()->driver() && !d->nullTxtChanged )
+ setNullText(sqlCursor()->driver()->nullText() );
+ setAutoDelete( autoDelete );
+ } else {
+ setNumRows( 0 );
+ setNumCols( 0 );
+ }
+ setUpdatesEnabled( TRUE );
+}
+
+
+/*!
+ Protected virtual function which is called when an error \a e has
+ occurred on the current cursor(). The default implementation
+ displays a warning message to the user with information about the
+ error.
+*/
+void TQDataTable::handleError( const TQSqlError& e )
+{
+ d->dat.handleError( this, e );
+}
+
+/*! \reimp
+ */
+
+void TQDataTable::keyPressEvent( TQKeyEvent* e )
+{
+ switch( e->key() ) {
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case TQt::Key_Prior:
+ case TQt::Key_Next:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_F2:
+ case Qt::Key_Enter: case Qt::Key_Return:
+ case Qt::Key_Tab: case TQt::Key_BackTab:
+ TQTable::keyPressEvent( e );
+ default:
+ return;
+ }
+}
+
+/*! \reimp
+*/
+
+void TQDataTable::resizeData ( int )
+{
+
+}
+
+/*! \reimp
+*/
+
+TQTableItem * TQDataTable::item ( int, int ) const
+{
+ return 0;
+}
+
+/*! \reimp
+*/
+
+void TQDataTable::setItem ( int , int , TQTableItem * )
+{
+
+}
+
+/*! \reimp
+*/
+
+void TQDataTable::clearCell ( int , int )
+{
+
+}
+
+/*! \reimp
+*/
+
+void TQDataTable::setPixmap ( int , int , const TQPixmap & )
+{
+
+}
+
+/*! \reimp */
+void TQDataTable::takeItem ( TQTableItem * )
+{
+
+}
+
+/*!
+ Installs a new SQL editor factory \a f. This enables the user to
+ create and instantiate their own editors for use in cell editing.
+ Note that TQDataTable takes ownership of this pointer, and will
+ delete it when it is no longer needed or when
+ installEditorFactory() is called again.
+
+ \sa TQSqlEditorFactory
+*/
+
+void TQDataTable::installEditorFactory( TQSqlEditorFactory * f )
+{
+ if( f ) {
+ delete d->editorFactory;
+ d->editorFactory = f;
+ }
+}
+
+/*!
+ Installs a new property map \a m. This enables the user to create
+ and instantiate their own property maps for use in cell editing.
+ Note that TQDataTable takes ownership of this pointer, and will
+ delete it when it is no longer needed or when installPropertMap()
+ is called again.
+
+ \sa TQSqlPropertyMap
+*/
+
+void TQDataTable::installPropertyMap( TQSqlPropertyMap* m )
+{
+ if ( m ) {
+ delete d->propertyMap;
+ d->propertyMap = m;
+ }
+}
+
+/*! \internal
+
+ Sets the current selection to \a row, \a col.
+*/
+
+void TQDataTable::setCurrentSelection( int row, int )
+{
+ if ( !sqlCursor() )
+ return;
+ if ( row == d->lastAt )
+ return;
+ if ( !sqlCursor()->seek( row ) )
+ return;
+ d->lastAt = row;
+ emit currentChanged( sqlCursor() );
+}
+
+void TQDataTable::updateCurrentSelection()
+{
+ setCurrentSelection( currentRow(), -1 );
+}
+
+/*!
+ Returns the currently selected record, or 0 if there is no current
+ selection. The table owns the pointer, so do \e not delete it or
+ otherwise modify it or the cursor it points to.
+*/
+
+TQSqlRecord* TQDataTable::currentRecord() const
+{
+ if ( !sqlCursor() || currentRow() < 0 )
+ return 0;
+ if ( !sqlCursor()->seek( currentRow() ) )
+ return 0;
+ return sqlCursor();
+}
+
+/*!
+ Sorts column \a col in ascending order.
+
+ \sa setSorting()
+*/
+
+void TQDataTable::sortAscending( int col )
+{
+ sortColumn( col, TRUE );
+}
+
+/*!
+ Sorts column \a col in descending order.
+
+ \sa setSorting()
+*/
+
+void TQDataTable::sortDescending( int col )
+{
+ sortColumn( col, FALSE );
+}
+
+/*!
+ \overload void TQDataTable::refresh( Refresh mode )
+
+ Refreshes the table. If there is no currently defined cursor (see
+ setSqlCursor()), nothing happens. The \a mode parameter determines
+ which type of refresh will take place.
+
+ \sa Refresh setSqlCursor() addColumn()
+*/
+
+void TQDataTable::refresh( TQDataTable::Refresh mode )
+{
+ TQSqlCursor* cur = sqlCursor();
+ if ( !cur )
+ return;
+ bool refreshData = ( (mode & RefreshData) == RefreshData );
+ bool refreshCol = ( (mode & RefreshColumns) == RefreshColumns );
+ if ( ( (mode & RefreshAll) == RefreshAll ) ) {
+ refreshData = TRUE;
+ refreshCol = TRUE;
+ }
+ if ( !refreshCol && d->fld.count() && numCols() == 0 )
+ refreshCol = TRUE;
+ viewport()->setUpdatesEnabled( FALSE );
+ d->haveAllRows = FALSE;
+ if ( refreshData ) {
+ if ( !d->cur.refresh() && d->cur.cursor() ) {
+ handleError( d->cur.cursor()->lastError() );
+ }
+ d->lastAt = -1;
+ }
+ if ( refreshCol ) {
+ setNumCols( 0 );
+ d->colIndex.clear();
+ if ( d->fld.count() ) {
+ TQSqlField* field = 0;
+ int i;
+ int fpos = -1;
+ for ( i = 0; i < (int)d->fld.count(); ++i ) {
+ if ( cur->field( i ) && cur->field( i )->name() == d->fld[ i ] )
+ // if there is a field with the desired name on the desired position
+ // then we take that
+ fpos = i;
+ else
+ // otherwise we take the first field that matches the desired name
+ fpos = cur->position( d->fld[ i ] );
+ field = cur->field( fpos );
+ if ( field && ( cur->isGenerated( fpos ) ||
+ cur->isCalculated( field->name() ) ) )
+ {
+ setNumCols( numCols() + 1 );
+ d->colIndex.append( fpos );
+ setColumnReadOnly( numCols()-1, field->isReadOnly() || isColumnReadOnly( numCols()-1 ) );
+ horizontalHeader()->setLabel( numCols()-1, d->fldIcon[ i ], d->fldLabel[ i ] );
+ if ( d->fldHidden[ i ] ) {
+ TQTable::showColumn( i ); // ugly but necessary
+ TQTable::hideColumn( i );
+ } else {
+ TQTable::showColumn( i );
+ }
+ if ( d->fldWidth[ i ] > -1 )
+ TQTable::setColumnWidth( i, d->fldWidth[i] );
+ }
+ }
+ }
+ }
+ viewport()->setUpdatesEnabled( TRUE );
+ viewport()->tqrepaint( FALSE );
+ horizontalHeader()->tqrepaint();
+ verticalHeader()->tqrepaint();
+ setSize( cur );
+ // keep others aware
+ if ( d->lastAt == -1 )
+ setCurrentSelection( -1, -1 );
+ else if ( d->lastAt != currentRow() )
+ setCurrentSelection( currentRow(), currentColumn() );
+ if ( cur->isValid() )
+ emit currentChanged( sqlCursor() );
+}
+
+/*!
+ Refreshes the table. The cursor is refreshed using the current
+ filter, the current sort, and the currently defined columns.
+ Equivalent to calling refresh( TQDataTable::RefreshData ).
+*/
+
+void TQDataTable::refresh()
+{
+ refresh( RefreshData );
+}
+
+/*!
+ \reimp
+
+ Selects the record in the table using the current cursor edit
+ buffer and the fields specified by the index \a idx. If \a atHint
+ is specified, it will be used as a hint about where to begin
+ searching.
+*/
+
+bool TQDataTable::tqfindBuffer( const TQSqlIndex& idx, int atHint )
+{
+ TQSqlCursor* cur = sqlCursor();
+ if ( !cur )
+ return FALSE;
+ bool found = d->cur.tqfindBuffer( idx, atHint );
+ if ( found )
+ setCurrentCell( cur->at(), currentColumn() );
+ return found;
+}
+
+/*! \internal
+ Returns the string representation of a database field.
+*/
+TQString TQDataTable::fieldToString( const TQSqlField * field )
+{
+ TQString text;
+ if ( field->isNull() ) {
+ text = nullText();
+ } else {
+ TQVariant val = field->value();
+ switch ( val.type() ) {
+ case TQVariant::Bool:
+ text = val.toBool() ? d->trueTxt : d->falseTxt;
+ break;
+ case TQVariant::Date:
+ text = val.toDate().toString( (Qt::DateFormat)d->datefmt );
+ break;
+ case TQVariant::Time:
+ text = val.toTime().toString( (Qt::DateFormat)d->datefmt );
+ break;
+ case TQVariant::DateTime:
+ text = val.toDateTime().toString( (Qt::DateFormat)d->datefmt );
+ break;
+ default:
+ text = val.toString();
+ break;
+ }
+ }
+ return text;
+}
+
+/*!
+ \reimp
+*/
+
+void TQDataTable::swapColumns( int col1, int col2, bool )
+{
+ TQString fld = d->fld[ col1 ];
+ TQString fldLabel = d->fldLabel[ col1 ];
+ TQIconSet fldIcon = d->fldIcon[ col1 ];
+ int fldWidth = d->fldWidth[ col1 ];
+
+ d->fld[ col1 ] = d->fld[ col2 ];
+ d->fldLabel[ col1 ] = d->fldLabel[ col2 ];
+ d->fldIcon[ col1 ] = d->fldIcon[ col2 ];
+ d->fldWidth[ col1 ] = d->fldWidth[ col2 ];
+
+ d->fld[ col2 ] = fld;
+ d->fldLabel[ col2 ] = fldLabel;
+ d->fldIcon[ col2 ] = fldIcon;
+ d->fldWidth[ col2 ] = fldWidth;
+
+ int colIndex = d->colIndex[ col1 ];
+ d->colIndex[ col1 ] = d->colIndex[ col2 ];
+ d->colIndex[ col2 ] = colIndex;
+}
+
+/*!
+ \reimp
+*/
+
+void TQDataTable::drawContents( TQPainter * p, int cx, int cy, int cw, int ch )
+{
+ TQTable::drawContents( p, cx, cy, cw, ch );
+ if ( sqlCursor() && currentRow() >= 0 )
+ sqlCursor()->seek( currentRow() );
+}
+
+/*!
+ \reimp
+*/
+
+void TQDataTable::hideColumn( int col )
+{
+ d->fldHidden[col] = TRUE;
+ refresh( RefreshColumns );
+}
+
+/*!
+ \reimp
+*/
+
+void TQDataTable::showColumn( int col )
+{
+ d->fldHidden[col] = FALSE;
+ refresh( RefreshColumns );
+}
+
+/*!
+ \fn void TQDataTable::currentChanged( TQSqlRecord* record )
+
+ This signal is emitted whenever a new row is selected in the
+ table. The \a record parameter points to the contents of the newly
+ selected record.
+*/
+
+/*!
+ \fn void TQDataTable::primeInsert( TQSqlRecord* buf )
+
+ This signal is emitted after the cursor is primed for insert by
+ the table, when an insert action is beginning on the table. The \a
+ buf parameter points to the edit buffer being inserted. Connect to
+ this signal in order to, for example, prime the record buffer with
+ default data values.
+*/
+
+/*!
+ \fn void TQDataTable::primeUpdate( TQSqlRecord* buf )
+
+ This signal is emitted after the cursor is primed for update by
+ the table, when an update action is beginning on the table. The \a
+ buf parameter points to the edit buffer being updated. Connect to
+ this signal in order to, for example, provide some visual feedback
+ that the user is in 'edit mode'.
+*/
+
+/*!
+ \fn void TQDataTable::primeDelete( TQSqlRecord* buf )
+
+ This signal is emitted after the cursor is primed for delete by
+ the table, when a delete action is beginning on the table. The \a
+ buf parameter points to the edit buffer being deleted. Connect to
+ this signal in order to, for example, record auditing information
+ on deletions.
+*/
+
+/*!
+ \fn void TQDataTable::beforeInsert( TQSqlRecord* buf )
+
+ This signal is emitted just before the cursor's edit buffer is
+ inserted into the database. The \a buf parameter points to the
+ edit buffer being inserted. Connect to this signal to, for
+ example, populate a key field with a unique sequence number.
+*/
+
+/*!
+ \fn void TQDataTable::beforeUpdate( TQSqlRecord* buf )
+
+ This signal is emitted just before the cursor's edit buffer is
+ updated in the database. The \a buf parameter points to the edit
+ buffer being updated. Connect to this signal when you want to
+ transform the user's data behind-the-scenes.
+*/
+
+/*!
+ \fn void TQDataTable::beforeDelete( TQSqlRecord* buf )
+
+ This signal is emitted just before the currently selected record
+ is deleted from the database. The \a buf parameter points to the
+ edit buffer being deleted. Connect to this signal to, for example,
+ copy some of the fields for later use.
+*/
+
+/*!
+ \fn void TQDataTable::cursorChanged( TQSql::Op mode )
+
+ This signal is emitted whenever the cursor record was changed due
+ to an edit. The \a mode parameter is the type of edit that just
+ took place.
+*/
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqdatatable.h b/tqtinterface/qt4/src/sql/tqdatatable.h
new file mode 100644
index 0000000..657dc9c
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqdatatable.h
@@ -0,0 +1,245 @@
+/****************************************************************************
+**
+** Definition of TQDataTable class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDATATABLE_H
+#define TQDATATABLE_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqvariant.h"
+#include "tqtable.h"
+#include "tqsql.h"
+#include "tqsqlcursor.h"
+#include "tqsqlindex.h"
+#include "tqsqleditorfactory.h"
+#include "tqiconset.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_STQL_VIEW_WIDGETS
+
+class TQPainter;
+class TQSqlField;
+class TQSqlPropertyMap;
+class TQDataTablePrivate;
+
+class TQM_EXPORT_SQL TQDataTable : public TQTable
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+ Q_PROPERTY( TQString nullText READ nullText WRITE setNullText )
+ Q_PROPERTY( TQString trueText READ trueText WRITE setTrueText )
+ Q_PROPERTY( TQString falseText READ falseText WRITE setFalseText )
+// Q_PROPERTY( DateFormat dateFormat READ dateFormat WRITE setDateFormat )
+ Q_PROPERTY( bool confirmEdits READ confirmEdits WRITE setConfirmEdits )
+ Q_PROPERTY( bool confirmInsert READ confirmInsert WRITE setConfirmInsert )
+ Q_PROPERTY( bool confirmUpdate READ confirmUpdate WRITE setConfirmUpdate )
+ Q_PROPERTY( bool confirmDelete READ confirmDelete WRITE setConfirmDelete )
+ Q_PROPERTY( bool confirmCancels READ confirmCancels WRITE setConfirmCancels )
+ Q_PROPERTY( bool autoEdit READ autoEdit WRITE setAutoEdit )
+ Q_PROPERTY( TQString filter READ filter WRITE setFilter )
+ Q_PROPERTY( TQStringList sort READ sort WRITE setSort )
+ Q_PROPERTY( int numCols READ numCols )
+ Q_PROPERTY( int numRows READ numRows )
+
+public:
+ TQDataTable ( TQWidget* tqparent=0, const char* name=0 );
+ TQDataTable ( TQSqlCursor* cursor, bool autoPopulate = FALSE, TQWidget* tqparent=0, const char* name=0 );
+ ~TQDataTable();
+
+ virtual void addColumn( const TQString& fieldName,
+ const TQString& label = TQString::null,
+ int width = -1,
+ const TQIconSet& iconset = TQIconSet() );
+ virtual void removeColumn( uint col );
+ virtual void setColumn( uint col, const TQString& fieldName,
+ const TQString& label = TQString::null,
+ int width = -1,
+ const TQIconSet& iconset = TQIconSet() );
+
+ TQString nullText() const;
+ TQString trueText() const;
+ TQString falseText() const;
+ Qt::DateFormat dateFormat() const;
+ bool confirmEdits() const;
+ bool confirmInsert() const;
+ bool confirmUpdate() const;
+ bool confirmDelete() const;
+ bool confirmCancels() const;
+ bool autoDelete() const;
+ bool autoEdit() const;
+ TQString filter() const;
+ TQStringList sort() const;
+
+ virtual void setSqlCursor( TQSqlCursor* cursor = 0,
+ bool autoPopulate = FALSE, bool autoDelete = FALSE );
+ TQSqlCursor* sqlCursor() const;
+
+ virtual void setNullText( const TQString& nullText );
+ virtual void setTrueText( const TQString& trueText );
+ virtual void setFalseText( const TQString& falseText );
+ virtual void setDateFormat( const Qt::DateFormat f );
+ virtual void setConfirmEdits( bool confirm );
+ virtual void setConfirmInsert( bool confirm );
+ virtual void setConfirmUpdate( bool confirm );
+ virtual void setConfirmDelete( bool confirm );
+ virtual void setConfirmCancels( bool confirm );
+ virtual void setAutoDelete( bool enable );
+ virtual void setAutoEdit( bool autoEdit );
+ virtual void setFilter( const TQString& filter );
+ virtual void setSort( const TQStringList& sort );
+ virtual void setSort( const TQSqlIndex& sort );
+
+ enum Refresh {
+ RefreshData = 1,
+ RefreshColumns = 2,
+ RefreshAll = 3
+ };
+ void refresh( Refresh mode );
+ void sortColumn ( int col, bool ascending = TRUE,
+ bool wholeRows = FALSE );
+ TQString text ( int row, int col ) const;
+ TQVariant value ( int row, int col ) const;
+ TQSqlRecord* currentRecord() const;
+
+ void installEditorFactory( TQSqlEditorFactory * f );
+ void installPropertyMap( TQSqlPropertyMap* m );
+
+ int numCols() const;
+ int numRows() const;
+ void setNumCols( int c );
+ void setNumRows ( int r );
+ bool tqfindBuffer( const TQSqlIndex& idx, int atHint = 0 );
+
+ void hideColumn( int col );
+ void showColumn( int col );
+Q_SIGNALS:
+ void currentChanged( TQSqlRecord* record );
+ void primeInsert( TQSqlRecord* buf );
+ void primeUpdate( TQSqlRecord* buf );
+ void primeDelete( TQSqlRecord* buf );
+ void beforeInsert( TQSqlRecord* buf );
+ void beforeUpdate( TQSqlRecord* buf );
+ void beforeDelete( TQSqlRecord* buf );
+ void cursorChanged( TQSql::Op mode );
+
+public Q_SLOTS:
+ virtual void tqfind( const TQString & str, bool caseSensitive,
+ bool backwards );
+ virtual void sortAscending( int col );
+ virtual void sortDescending( int col );
+ virtual void refresh();
+ void setColumnWidth( int col, int w );
+ void adjustColumn( int col );
+ void setColumnStretchable( int col, bool stretch );
+ void swapColumns( int col1, int col2, bool swapHeaders = FALSE );
+
+protected:
+ virtual bool insertCurrent();
+ virtual bool updateCurrent();
+ virtual bool deleteCurrent();
+
+ virtual TQSql::Confirm confirmEdit( TQSql::Op m );
+ virtual TQSql::Confirm confirmCancel( TQSql::Op m );
+
+ virtual void handleError( const TQSqlError& e );
+
+ virtual bool beginInsert();
+ virtual TQWidget* beginUpdate ( int row, int col, bool tqreplace );
+
+ bool eventFilter( TQObject *o, TQEvent *e );
+ void keyPressEvent( TQKeyEvent* );
+ void resizeEvent ( TQResizeEvent * );
+ void contentsMousePressEvent( TQMouseEvent* e );
+ void contentsContextMenuEvent( TQContextMenuEvent* e );
+ void endEdit( int row, int col, bool accept, bool tqreplace );
+ TQWidget * createEditor( int row, int col, bool initFromCell ) const;
+ void activateNextCell();
+ int indexOf( uint i ) const; // ### make this public in 4.0
+ void reset();
+ void setSize( TQSqlCursor* sql );
+ void repaintCell( int row, int col );
+ void paintCell ( TQPainter * p, int row, int col, const TQRect & cr,
+ bool selected, const TQColorGroup &cg );
+ virtual void paintField( TQPainter * p, const TQSqlField* field, const TQRect & cr,
+ bool selected );
+ void drawContents( TQPainter * p, int cx, int cy, int cw, int ch );
+ virtual int fieldAlignment( const TQSqlField* field );
+ void columnClicked ( int col );
+ void resizeData ( int len );
+
+ TQTableItem * item ( int row, int col ) const;
+ void setItem ( int row, int col, TQTableItem * item );
+ void clearCell ( int row, int col ) ;
+ void setPixmap ( int row, int col, const TQPixmap & pix );
+ void takeItem ( TQTableItem * i );
+
+private Q_SLOTS:
+ void loadNextPage();
+ void setCurrentSelection( int row, int col );
+ void updateCurrentSelection();
+ void sliderPressed();
+ void sliderReleased();
+ void doInsertCurrent();
+ void doUpdateCurrent();
+
+private:
+ TQString fieldToString( const TQSqlField * field );
+ void init();
+ TQWidget* beginEdit ( int row, int col, bool tqreplace );
+ void updateRow( int row );
+ void endInsert();
+ void endUpdate();
+ TQDataTablePrivate* d;
+
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQDataTable( const TQDataTable & );
+ TQDataTable &operator=( const TQDataTable & );
+#endif
+};
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqdataview.cpp b/tqtinterface/qt4/src/sql/tqdataview.cpp
new file mode 100644
index 0000000..b2fbecf
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqdataview.cpp
@@ -0,0 +1,208 @@
+/****************************************************************************
+**
+** Implementation of TQDataView class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdataview.h"
+
+#ifndef TQT_NO_STQL_VIEW_WIDGETS
+
+#include "tqsqlmanager_p.h"
+
+class TQDataViewPrivate
+{
+public:
+ TQDataViewPrivate() {}
+ TQSqlFormManager frm;
+};
+
+
+/*!
+ \class TQDataView tqdataview.h
+ \brief The TQDataView class provides read-only SQL forms.
+
+ \ingroup database
+ \mainclass
+ \module sql
+
+ This class provides a form which displays SQL field data from a
+ record buffer. Because TQDataView does not support editing it uses
+ less resources than a TQDataBrowser. This class is well suited for
+ displaying read-only data from a SQL database.
+
+ If you want a to present your data in an editable form use
+ TQDataBrowser; if you want a table-based presentation of your data
+ use TQDataTable.
+
+ The form is associated with the data view with setForm() and the
+ record is associated with setRecord(). You can also pass a
+ TQSqlRecord to the refresh() function which will set the record to
+ the given record and read the record's fields into the form.
+*/
+
+/*!
+ Constructs a data view which is a child of \a tqparent, called \a
+ name, and with widget flags \a fl.
+*/
+
+TQDataView::TQDataView( TQWidget *tqparent, const char *name, WFlags fl )
+ : TQWidget( tqparent, name, fl )
+{
+ d = new TQDataViewPrivate();
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQDataView::~TQDataView()
+{
+ delete d;
+}
+
+/*!
+ Clears the default form's values. If there is no default form,
+ nothing happens. All the values are set to their 'zero state',
+ e.g. 0 for numeric fields, "" for string fields.
+*/
+
+void TQDataView::clearValues()
+{
+ d->frm.clearValues();
+}
+
+/*!
+ Sets the form used by the data view to \a form. If a record has
+ already been assigned to the data view, the form will display that
+ record's data.
+
+ \sa form()
+*/
+
+void TQDataView::setForm( TQSqlForm* form )
+{
+ d->frm.setForm( form );
+}
+
+
+/*!
+ Returns the default form used by the data view, or 0 if there is
+ none.
+
+ \sa setForm()
+*/
+
+TQSqlForm* TQDataView::form()
+{
+ return d->frm.form();
+}
+
+
+/*!
+ Sets the record used by the data view to \a record. If a form has
+ already been assigned to the data view, the form will display the
+ data from \a record in that form.
+
+ \sa record()
+*/
+
+void TQDataView::setRecord( TQSqlRecord* record )
+{
+ d->frm.setRecord( record );
+}
+
+
+/*!
+ Returns the default record used by the data view, or 0 if there is
+ none.
+
+ \sa setRecord()
+*/
+
+TQSqlRecord* TQDataView::record()
+{
+ return d->frm.record();
+}
+
+
+/*!
+ Causes the default form to read its fields from the record buffer.
+ If there is no default form, or no record, nothing happens.
+
+ \sa setForm()
+*/
+
+void TQDataView::readFields()
+{
+ d->frm.readFields();
+}
+
+/*!
+ Causes the default form to write its fields to the record buffer.
+ If there is no default form, or no record, nothing happens.
+
+ \sa setForm()
+*/
+
+void TQDataView::writeFields()
+{
+ d->frm.writeFields();
+}
+
+/*!
+ Causes the default form to display the contents of \a buf. If
+ there is no default form, nothing happens.The \a buf also becomes
+ the default record for all subsequent calls to readFields() and
+ writefields(). This slot is equivalant to calling:
+
+ \code
+ myView.setRecord( record );
+ myView.readFields();
+ \endcode
+
+ \sa setRecord() readFields()
+*/
+
+void TQDataView::refresh( TQSqlRecord* buf )
+{
+ if ( buf && buf != record() )
+ setRecord( buf );
+ readFields();
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqdataview.h b/tqtinterface/qt4/src/sql/tqdataview.h
new file mode 100644
index 0000000..017fae6
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqdataview.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Definition of TQDataView class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDATAVIEW_H
+#define TQDATAVIEW_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_STQL_VIEW_WIDGETS
+
+class TQSqlForm;
+class TQSqlRecord;
+class TQDataViewPrivate;
+
+class TQM_EXPORT_SQL TQDataView : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQDataView( TQWidget* tqparent=0, const char* name=0, WFlags fl = 0 );
+ ~TQDataView();
+
+ virtual void setForm( TQSqlForm* form );
+ TQSqlForm* form();
+ virtual void setRecord( TQSqlRecord* record );
+ TQSqlRecord* record();
+
+public Q_SLOTS:
+ virtual void refresh( TQSqlRecord* buf );
+ virtual void readFields();
+ virtual void writeFields();
+ virtual void clearValues();
+
+private:
+ TQDataViewPrivate* d;
+
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQDataView( const TQDataView & );
+ TQDataView &operator=( const TQDataView & );
+#endif
+};
+
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqeditorfactory.cpp b/tqtinterface/qt4/src/sql/tqeditorfactory.cpp
new file mode 100644
index 0000000..2d02088
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqeditorfactory.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Implementation of TQEditorFactory class
+**
+** Created : 2000-11-17
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcleanuphandler.h"
+#include "tqlabel.h"
+#include "tqlineedit.h"
+#include "tqspinbox.h"
+#include "tqcombobox.h"
+
+#include "tqeditorfactory.h"
+#include "tqdatetimeedit.h"
+
+#ifndef TQT_NO_STQL_EDIT_WIDGETS
+
+/*!
+ \class TQEditorFactory tqeditorfactory.h
+ \brief The TQEditorFactory class is used to create editor widgets
+ for TQVariant data types.
+
+ \ingroup database
+ \module sql
+
+ Each editor factory provides the createEditor() function which
+ given a TQVariant will create and return a TQWidget that can edit
+ that TQVariant. For example if you have a TQVariant::String type, a
+ TQLineEdit would be the default editor returned, whereas a
+ TQVariant::Int's default editor would be a TQSpinBox.
+
+ If you want to create different editors for fields with the same
+ data type, subclass TQEditorFactory and reimplement the
+ createEditor() function.
+*/
+
+/*!
+ Constructs an editor factory with tqparent \a tqparent, called \a name.
+*/
+
+TQEditorFactory::TQEditorFactory ( TQObject * tqparent, const char * name )
+ : TQObject( tqparent, name )
+{
+
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQEditorFactory::~TQEditorFactory()
+{
+
+}
+
+static TQEditorFactory * defaultfactory = 0;
+static TQCleanupHandler< TQEditorFactory > q_cleanup_editor_factory;
+
+/*!
+ Returns an instance of a default editor factory.
+*/
+
+TQEditorFactory * TQEditorFactory::defaultFactory()
+{
+ if( defaultfactory == 0 ){
+ defaultfactory = new TQEditorFactory();
+ q_cleanup_editor_factory.add( &defaultfactory );
+ }
+
+ return defaultfactory;
+}
+
+/*!
+ Replaces the default editor factory with \a factory.
+ \e{TQEditorFactory takes ownership of factory, and destroys it
+ when it is no longer needed.}
+*/
+
+void TQEditorFactory::installDefaultFactory( TQEditorFactory * factory )
+{
+ if( factory == 0 || factory == defaultfactory ) return;
+
+ if( defaultfactory != 0 ){
+ q_cleanup_editor_factory.remove( &defaultfactory );
+ delete defaultfactory;
+ }
+ defaultfactory = factory;
+ q_cleanup_editor_factory.add( &defaultfactory );
+}
+
+/*!
+ Creates and returns the appropriate editor for the TQVariant \a v.
+ If the TQVariant is invalid, 0 is returned. The \a tqparent is passed
+ to the appropriate editor's constructor.
+*/
+
+TQWidget * TQEditorFactory::createEditor( TQWidget * tqparent, const TQVariant & v )
+{
+ TQWidget * w = 0;
+ switch( v.type() ){
+ case TQVariant::Invalid:
+ w = 0;
+ break;
+ case TQVariant::Bool:
+ w = new TQComboBox( tqparent, "qt_editor_bool" );
+ ((TQComboBox *) w)->insertItem( "False" );
+ ((TQComboBox *) w)->insertItem( "True" );
+ break;
+ case TQVariant::UInt:
+ w = new TQSpinBox( 0, 999999, 1, tqparent, "qt_editor_spinbox" );
+ break;
+ case TQVariant::Int:
+ w = new TQSpinBox( -999999, 999999, 1, tqparent, "qt_editor_int" );
+ break;
+ case TQVariant::String:
+ case TQVariant::CString:
+ case TQVariant::Double:
+ w = new TQLineEdit( tqparent, "qt_editor_double" );
+ ((TQLineEdit*)w)->setFrame( FALSE );
+ break;
+ case TQVariant::Date:
+ w = new TQDateEdit( tqparent, "qt_editor_date" );
+ break;
+ case TQVariant::Time:
+ w = new TQTimeEdit( tqparent, "qt_editor_time" );
+ break;
+ case TQVariant::DateTime:
+ w = new TQDateTimeEdit( tqparent, "qt_editor_datetime" );
+ break;
+#ifndef TQT_NO_LABEL
+ case TQVariant::Pixmap:
+ w = new TQLabel( tqparent, "qt_editor_pixmap" );
+ break;
+#endif
+ case TQVariant::Palette:
+ case TQVariant::ColorGroup:
+ case TQVariant::Color:
+ case TQVariant::Font:
+ case TQVariant::Brush:
+ case TQVariant::Bitmap:
+ case TQVariant::Cursor:
+ case TQVariant::Map:
+ case TQVariant::StringList:
+ case TQVariant::Rect:
+ case TQVariant::Size:
+ case TQVariant::IconSet:
+ case TQVariant::Point:
+ case TQVariant::PointArray:
+ case TQVariant::Region:
+ case TQVariant::SizePolicy:
+ case TQVariant::ByteArray:
+ default:
+ w = new TQWidget( tqparent, "qt_editor_default" );
+ break;
+ }
+ return w;
+}
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/tqeditorfactory.h b/tqtinterface/qt4/src/sql/tqeditorfactory.h
new file mode 100644
index 0000000..fb67e0f
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqeditorfactory.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Definition of TQEditorFactory class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQEDITORFACTORY_H
+#define TQEDITORFACTORY_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqvariant.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_STQL_EDIT_WIDGETS
+
+class TQM_EXPORT_SQL TQEditorFactory : public TQObject
+{
+public:
+ TQEditorFactory ( TQObject * tqparent = 0, const char * name = 0 );
+ ~TQEditorFactory();
+
+ virtual TQWidget * createEditor( TQWidget * tqparent, const TQVariant & v );
+
+ static TQEditorFactory * defaultFactory();
+ static void installDefaultFactory( TQEditorFactory * factory);
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQEditorFactory( const TQEditorFactory & );
+ TQEditorFactory &operator=( const TQEditorFactory & );
+#endif
+};
+
+#endif // TQT_NO_SQL
+#endif // TQEDITORFACTORY_H
diff --git a/tqtinterface/qt4/src/sql/tqsql.cpp b/tqtinterface/qt4/src/sql/tqsql.cpp
new file mode 100644
index 0000000..ab497c6
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsql.cpp
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Implementation of TQSql class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+
+/*!
+ \class TQSql tqsql.h
+ \brief The TQSql class is a namespace for TQt SQL identifiers that
+ need to be global-like.
+
+ \ingroup database
+ \mainclass
+ \module sql
+
+ Normally, you can ignore this class. Several TQt SQL classes
+ inherit it, so all the identifiers in the TQt SQL namespace are
+ visible without qualification.
+*/
+
+/*!
+ \enum TQSql::Confirm
+
+ This enum type describes edit confirmations.
+
+ \value Yes
+ \value No
+ \value Cancel
+*/
+
+/*!
+ \enum TQSql::Op
+
+ This enum type describes edit operations.
+
+ \value None
+ \value Insert
+ \value Update
+ \value Delete
+*/
+
+
+/*!
+ \enum TQSql::Location
+
+ This enum type describes SQL navigation locations.
+
+ \value BeforeFirst
+ \value AfterLast
+*/
+
+/*!
+ \enum TQSql::ParameterType
+
+ This enum is used to set the type of a bind parameter
+
+ \value In the bind parameter is used to put data into the database
+ \value Out the bind parameter is used to receive data from the database
+ \value InOut the bind parameter is used to put data into the
+ database; it will be overwritten with output data on executing
+ a query.
+*/
+
+/*!
+ \enum TQSql::TableType
+
+ This enum type describes types of tables
+
+ \value Tables All the tables visible to the user
+ \value SystemTables Internal tables used by the DBMS
+ \value Views All the views visible to the user
+ \value AllTables All of the above
+*/
+
+/*!
+ \fn TQSql::TQSql()
+
+ Constructs a TQt SQL namespace class
+*/
diff --git a/tqtinterface/qt4/src/sql/tqsql.h b/tqtinterface/qt4/src/sql/tqsql.h
new file mode 100644
index 0000000..ffb7d99
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsql.h
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Definition of TQSql class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQL_H
+#define TQSQL_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQM_EXPORT_SQL TQSql
+{
+public:
+ TQSql() {}
+ enum Op {
+ None = -1,
+ Insert = 0,
+ Update = 1,
+ Delete = 2
+ };
+
+ enum Location {
+ BeforeFirst = -1,
+ AfterLast = -2
+ };
+
+ enum Confirm {
+ Cancel = -1,
+ No = 0,
+ Yes = 1
+ };
+
+ enum ParameterType {
+ In = 1,
+ Out = 2,
+ InOut = 3 //InOut = In | Out
+ };
+
+ enum TableType {
+ Tables = 0x01,
+ SystemTables = 0x02,
+ Views = 0x04,
+ AllTables = 0xff
+ };
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSql( const TQSql & );
+ TQSql &operator=( const TQSql & );
+#endif
+
+};
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlcursor.cpp b/tqtinterface/qt4/src/sql/tqsqlcursor.cpp
new file mode 100644
index 0000000..0d9fc53
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlcursor.cpp
@@ -0,0 +1,1549 @@
+/****************************************************************************
+**
+** Implementation of TQSqlCursor class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlcursor.h"
+
+#ifndef TQT_NO_SQL
+
+#include "tqsqldriver.h"
+#include "tqsqlresult.h"
+#include "tqdatetime.h"
+#include "tqsqldatabase.h"
+#include "tqsql.h"
+
+class TQSqlCursorPrivate
+{
+public:
+
+ TQSqlCursorPrivate( const TQString& name, TQSqlDatabase* sdb )
+ : lastAt( TQSql::BeforeFirst ), nm( name ), srt( name ), md( 0 ), db( sdb ), q( 0 )
+ {}
+ ~TQSqlCursorPrivate()
+ {
+ delete q;
+ }
+
+ TQSqlQuery* query()
+ {
+ if ( !q )
+ q = new TQSqlQuery( 0, db );
+ return q;
+ }
+
+ int lastAt;
+ TQString nm; //name
+ TQSqlIndex srt; //sort
+ TQString ftr; //filter
+ int md; //mode
+ TQSqlIndex priIndx; //primary index
+ TQSqlRecord editBuffer;
+ // the primary index as it was before the user changed the values in editBuffer
+ TQString editIndex;
+ TQSqlRecordInfo infoBuffer;
+ TQSqlDatabase* db;
+ TQSqlQuery* q;
+};
+
+TQString qOrderByClause( const TQSqlIndex & i, const TQString& prefix = TQString::null )
+{
+ TQString str;
+ int k = i.count();
+ if( k == 0 ) return TQString::null;
+ str = " order by " + i.toString( prefix );
+ return str;
+}
+
+TQString qWhereClause( const TQString& prefix, TQSqlField* field, const TQSqlDriver* driver )
+{
+ TQString f;
+ if ( field && driver ) {
+ f = ( prefix.length() > 0 ? prefix + TQString(".") : TQString() ) + field->name();
+ if ( field->isNull() ) {
+ f += " IS NULL";
+ } else {
+ f += " = " + driver->formatValue( field );
+ }
+ }
+ return f;
+}
+
+TQString qWhereClause( TQSqlRecord* rec, const TQString& prefix, const TQString& sep,
+ const TQSqlDriver* driver )
+{
+ static TQString blank( " " );
+ TQString filter;
+ bool separator = FALSE;
+ for ( uint j = 0; j < rec->count(); ++j ) {
+ TQSqlField* f = rec->field( j );
+ if ( rec->isGenerated( j ) ) {
+ if ( separator )
+ filter += sep + blank;
+ filter += qWhereClause( prefix, f, driver );
+ filter += blank;
+ separator = TRUE;
+ }
+ }
+ return filter;
+}
+
+/*!
+ \class TQSqlCursor tqsqlcursor.h
+ \brief The TQSqlCursor class provides browsing and editing of SQL
+ tables and views.
+
+ \ingroup database
+ \module sql
+
+ A TQSqlCursor is a database record (see \l TQSqlRecord) that
+ corresponds to a table or view within an SQL database (see \l
+ TQSqlDatabase). There are two buffers in a cursor, one used for
+ browsing and one used for editing records. Each buffer tqcontains a
+ list of fields which correspond to the fields in the table or
+ view.
+
+ When positioned on a valid record, the browse buffer tqcontains the
+ values of the current record's fields from the database. The edit
+ buffer is separate, and is used for editing existing records and
+ inserting new records.
+
+ For browsing data, a cursor must first select() data from the
+ database. After a successful select() the cursor is active
+ (isActive() returns TRUE), but is initially not positioned on a
+ valid record (isValid() returns FALSE). To position the cursor on
+ a valid record, use one of the navigation functions, next(),
+ prev(), first(), last(), or seek(). Once positioned on a valid
+ record, data can be retrieved from the browse buffer using
+ value(). If a navigation function is not successful, it returns
+ FALSE, the cursor will no longer be positioned on a valid record
+ and the values returned by value() are undefined.
+
+ For example:
+
+ \quotefile sql/overview/retrieve2/main.cpp
+ \skipto TQSqlCursor
+ \printline TQSqlCursor
+ \printuntil }
+
+ In the above example, a cursor is created specifying a table or
+ view name in the database. Then, select() is called, which can be
+ optionally parameterised to filter and order the records
+ retrieved. Each record in the cursor is retrieved using next().
+ When next() returns FALSE, there are no more records to process,
+ and the loop terminates.
+
+ For editing records (rows of data), a cursor tqcontains a separate
+ edit buffer which is independent of the fields used when browsing.
+ The functions insert(), update() and del() operate on the edit
+ buffer. This allows the cursor to be repositioned to other
+ records while simultaneously maintaining a separate buffer for
+ edits. You can get a pointer to the edit buffer using
+ editBuffer(). The primeInsert(), primeUpdate() and primeDelete()
+ functions also return a pointer to the edit buffer and prepare it
+ for insert, update and delete respectively. Edit operations only
+ affect a single row at a time. Note that update() and del()
+ require that the table or view contain a primaryIndex() to ensure
+ that edit operations affect a unique record within the database.
+
+ For example:
+
+ \quotefile sql/overview/update/main.cpp
+ \skipto prices
+ \printline prices
+ \printuntil update
+ \printline
+
+ To edit an existing database record, first move to the record you
+ wish to update. Call primeUpdate() to get the pointer to the
+ cursor's edit buffer. Then use this pointer to modify the values
+ in the edit buffer. Finally, call update() to save the changes to
+ the database. The values in the edit buffer will be used to
+ locate the appropriate record when updating the database (see
+ primaryIndex()).
+
+ Similarly, when deleting an existing database record, first move
+ to the record you wish to delete. Then, call primeDelete() to get
+ the pointer to the edit buffer. Finally, call del() to delete the
+ record from the database. Again, the values in the edit buffer
+ will be used to locate and delete the appropriate record.
+
+ To insert a new record, call primeInsert() to get the pointer to
+ the edit buffer. Use this pointer to populate the edit buffer
+ with new values and then insert() the record into the database.
+
+ After calling insert(), update() or del(), the cursor is no longer
+ positioned on a valid record and can no longer be navigated
+ (isValid() return FALSE). The reason for this is that any changes
+ made to the database will not be visible until select() is called
+ to refresh the cursor. You can change this behavior by passing
+ FALSE to insert(), update() or del() which will prevent the cursor
+ from becoming invalid. The edits will still not be visible when
+ navigating the cursor until select() is called.
+
+ TQSqlCursor tqcontains virtual methods which allow editing behavior
+ to be customized by subclasses. This allows custom cursors to be
+ created that encapsulate the editing behavior of a database table
+ for an entire application. For example, a cursor can be customized
+ to always auto-number primary index fields, or provide fields with
+ suitable default values, when inserting new records. TQSqlCursor
+ generates SQL statements which are sent to the database engine;
+ you can control which fields are included in these statements
+ using setGenerated().
+
+ Note that TQSqlCursor does not inherit from TQObject. This means
+ that you are responsible for destroying instances of this class
+ yourself. However if you create a TQSqlCursor and use it in a
+ \l TQDataTable, \l TQDataBrowser or a \l TQDataView these classes will
+ usually take ownership of the cursor and destroy it when they
+ don't need it anymore. The documentation for TQDataTable,
+ TQDataBrowser and TQDataView explicitly states which calls take
+ ownership of the cursor.
+*/
+
+/*!
+ \enum TQSqlCursor::Mode
+
+ This enum type describes how TQSqlCursor operates on records in the
+ database.
+
+ \value ReadOnly the cursor can only SELECT records from the
+ database.
+
+ \value Insert the cursor can INSERT records into the database.
+
+ \value Update the cursor can UPDATE records in the database.
+
+ \value Delete the cursor can DELETE records from the database.
+
+ \value Writable the cursor can INSERT, UPDATE and DELETE records
+ in the database.
+*/
+
+/*!
+ Constructs a cursor on database \a db using table or view \a name.
+
+ If \a autopopulate is TRUE (the default), the \a name of the
+ cursor must correspond to an existing table or view name in the
+ database so that field information can be automatically created.
+ If the table or view does not exist, the cursor will not be
+ functional.
+
+ The cursor is created with an initial mode of TQSqlCursor::Writable
+ (meaning that records can be inserted, updated or deleted using
+ the cursor). If the cursor does not have a unique primary index,
+ update and deletes cannot be performed.
+
+ Note that \a autopopulate refers to populating the cursor with
+ meta-data, e.g. the names of the table's fields, not with
+ retrieving data. The select() function is used to populate the
+ cursor with data.
+
+ \sa setName() setMode()
+*/
+
+TQSqlCursor::TQSqlCursor( const TQString & name, bool autopopulate, TQSqlDatabase* db )
+ : TQSqlRecord(), TQSqlQuery( TQString::null, db )
+{
+ d = new TQSqlCursorPrivate( name, db );
+ setMode( Writable );
+ if ( !d->nm.isNull() )
+ setName( d->nm, autopopulate );
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+
+TQSqlCursor::TQSqlCursor( const TQSqlCursor & other )
+ : TQSqlRecord( other ), TQSqlQuery( other )
+{
+ d = new TQSqlCursorPrivate( other.d->nm, other.d->db );
+ d->lastAt = other.d->lastAt;
+ d->nm = other.d->nm;
+ d->srt = other.d->srt;
+ d->ftr = other.d->ftr;
+ d->priIndx = other.d->priIndx;
+ d->editBuffer = other.d->editBuffer;
+ d->infoBuffer = other.d->infoBuffer;
+ d->q = 0; // do not share queries
+ setMode( other.mode() );
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlCursor::~TQSqlCursor()
+{
+ delete d;
+}
+
+/*!
+ Sets the cursor equal to \a other.
+*/
+
+TQSqlCursor& TQSqlCursor::operator=( const TQSqlCursor& other )
+{
+ TQSqlRecord::operator=( other );
+ TQSqlQuery::operator=( other );
+ delete d;
+ d = new TQSqlCursorPrivate( other.d->nm, other.d->db );
+ d->lastAt = other.d->lastAt;
+ d->nm = other.d->nm;
+ d->srt = other.d->srt;
+ d->ftr = other.d->ftr;
+ d->priIndx = other.d->priIndx;
+ d->editBuffer = other.d->editBuffer;
+ d->infoBuffer = other.d->infoBuffer;
+ d->q = 0; // do not share queries
+ setMode( other.mode() );
+ return *this;
+}
+
+/*!
+ Sets the current sort to \a sort. Note that no new records are
+ selected. To select new records, use select(). The \a sort will
+ apply to any subsequent select() calls that do not explicitly
+ specify a sort.
+*/
+
+void TQSqlCursor::setSort( const TQSqlIndex& sort )
+{
+ d->srt = sort;
+}
+
+/*!
+ Returns the current sort, or an empty index if there is no current
+ sort.
+*/
+TQSqlIndex TQSqlCursor::sort() const
+{
+ return d->srt;
+}
+
+/*!
+ Sets the current filter to \a filter. Note that no new records are
+ selected. To select new records, use select(). The \a filter will
+ apply to any subsequent select() calls that do not explicitly
+ specify a filter.
+
+ The filter is a SQL \c WHERE clause without the keyword 'WHERE',
+ e.g. \c{name='Dave'} which will be processed by the DBMS.
+*/
+void TQSqlCursor::setFilter( const TQString& filter )
+{
+ d->ftr = filter;
+}
+
+/*!
+ Returns the current filter, or an empty string if there is no
+ current filter.
+*/
+TQString TQSqlCursor::filter() const
+{
+ return d->ftr;
+}
+
+/*!
+ Sets the name of the cursor to \a name. If \a autopopulate is TRUE
+ (the default), the \a name must correspond to a valid table or
+ view name in the database. Also, note that all references to the
+ cursor edit buffer become invalidated when fields are
+ auto-populated. See the TQSqlCursor constructor documentation for
+ more information.
+*/
+void TQSqlCursor::setName( const TQString& name, bool autopopulate )
+{
+ d->nm = name;
+ if ( autopopulate ) {
+ if ( driver() ) {
+ d->infoBuffer = driver()->recordInfo( name );
+ *this = d->infoBuffer.toRecord();
+ d->editBuffer = *this;
+ d->priIndx = driver()->primaryIndex( name );
+ }
+#ifdef TQT_CHECK_RANGE
+ if ( isEmpty() )
+ qWarning("TQSqlCursor::setName: unable to build record, does '%s' exist?", name.latin1() );
+#endif
+ }
+}
+
+/*!
+ Returns the name of the cursor.
+*/
+
+TQString TQSqlCursor::name() const
+{
+ return d->nm;
+}
+
+/*! \reimp
+*/
+
+TQString TQSqlCursor::toString( const TQString& prefix, const TQString& sep ) const
+{
+ TQString pflist;
+ TQString pfix = prefix.isEmpty() ? TQString() : prefix + ".";
+ bool comma = FALSE;
+
+ for ( uint i = 0; i < count(); ++i ) {
+ const TQString fname = fieldName( i );
+ if ( isGenerated( i ) ) {
+ if( comma )
+ pflist += sep + " ";
+ pflist += pfix + fname;
+ comma = TRUE;
+ }
+ }
+ return pflist;
+}
+
+/*!
+ \internal
+
+ Assigns the record \a list.
+
+*/
+TQSqlRecord & TQSqlCursor::operator=( const TQSqlRecord & list )
+{
+ return TQSqlRecord::operator=( list );
+}
+
+/*!
+ Append a copy of field \a fieldInfo to the end of the cursor. Note
+ that all references to the cursor edit buffer become invalidated.
+*/
+
+void TQSqlCursor::append( const TQSqlFieldInfo& fieldInfo )
+{
+ d->editBuffer.append( fieldInfo.toField() );
+ d->editBuffer.setGenerated( d->editBuffer.count() - 1, fieldInfo.isGenerated() );
+ d->infoBuffer.append( fieldInfo );
+ TQSqlRecord::append( fieldInfo.toField() );
+ TQSqlRecord::setGenerated( TQSqlRecord::count() - 1, fieldInfo.isGenerated() );
+}
+
+/*!
+ Removes all fields from the cursor. Note that all references to
+ the cursor edit buffer become invalidated.
+*/
+void TQSqlCursor::clear()
+{
+ d->editBuffer.clear();
+ d->infoBuffer.clear();
+ TQSqlRecord::clear();
+}
+
+
+/*!
+ Insert a copy of \a fieldInfo at position \a pos. If a field
+ already exists at \a pos, it is removed. Note that all references
+ to the cursor edit buffer become invalidated.
+*/
+
+void TQSqlCursor::insert( int pos, const TQSqlFieldInfo& fieldInfo )
+{
+ d->editBuffer.insert( pos, fieldInfo.toField() );
+ d->editBuffer.setGenerated( pos, fieldInfo.isGenerated() );
+ d->infoBuffer[ pos ] = fieldInfo;
+ TQSqlRecord::insert( pos, fieldInfo.toField() );
+ TQSqlRecord::setGenerated( pos, fieldInfo.isGenerated() );
+}
+
+/*!
+ Removes the field at \a pos. If \a pos does not exist, nothing
+ happens. Note that all references to the cursor edit buffer become
+ invalidated.
+*/
+
+void TQSqlCursor::remove( int pos )
+{
+ d->editBuffer.remove( pos );
+ d->infoBuffer[ pos ] = TQSqlFieldInfo();
+ TQSqlRecord::remove( pos );
+}
+
+/*!
+ Sets the generated flag for the field \a name to \a generated. If
+ the field does not exist, nothing happens. Only fields that have
+ \a generated set to TRUE are included in the SQL that is
+ generated by insert(), update() or del().
+
+ \sa isGenerated()
+*/
+
+void TQSqlCursor::setGenerated( const TQString& name, bool generated )
+{
+ int pos = position( name );
+ if ( pos == -1 )
+ return;
+ TQSqlRecord::setGenerated( name, generated );
+ d->editBuffer.setGenerated( name, generated );
+ d->infoBuffer[ pos ].setGenerated( generated );
+}
+
+/*!
+ \overload
+
+ Sets the generated flag for the field \a i to \a generated.
+
+ \sa isGenerated()
+*/
+void TQSqlCursor::setGenerated( int i, bool generated )
+{
+ if ( i < 0 || i >= (int)d->infoBuffer.count() )
+ return;
+ TQSqlRecord::setGenerated( i, generated );
+ d->editBuffer.setGenerated( i, generated );
+ d->infoBuffer[i].setGenerated( generated );
+}
+
+/*!
+ Returns the primary index associated with the cursor as defined in
+ the database, or an empty index if there is no primary index. If
+ \a setFromCursor is TRUE (the default), the index fields are
+ populated with the corresponding values in the cursor's current
+ record.
+*/
+
+TQSqlIndex TQSqlCursor::primaryIndex( bool setFromCursor ) const
+{
+ if ( setFromCursor ) {
+ for ( uint i = 0; i < d->priIndx.count(); ++i ) {
+ const TQString fn = d->priIndx.fieldName( i );
+ if ( tqcontains( fn ) )
+ d->priIndx.setValue( i, value( fn ) );
+ }
+ }
+ return d->priIndx;
+}
+
+/*!
+ Sets the primary index associated with the cursor to the index \a
+ idx. Note that this index must contain a field or set of fields
+ which identify a unique record within the underlying database
+ table or view so that update() and del() will execute as expected.
+
+ \sa update() del()
+*/
+
+void TQSqlCursor::setPrimaryIndex( const TQSqlIndex& idx )
+{
+ d->priIndx = idx;
+}
+
+
+/*!
+ Returns an index composed of \a fieldNames, all in ASCending
+ order. Note that all field names must exist in the cursor,
+ otherwise an empty index is returned.
+
+ \sa TQSqlIndex
+*/
+
+TQSqlIndex TQSqlCursor::index( const TQStringList& fieldNames ) const
+{
+ TQSqlIndex idx;
+ for ( TQStringList::ConstIterator it = fieldNames.begin(); it != fieldNames.end(); ++it ) {
+ const TQSqlField* f = field( (*it) );
+ if ( !f ) { /* all fields must exist */
+ idx.clear();
+ break;
+ }
+ idx.append( *f );
+ }
+ return idx;
+}
+
+/*!
+ \overload
+
+ Returns an index based on \a fieldName.
+*/
+
+TQSqlIndex TQSqlCursor::index( const TQString& fieldName ) const
+{
+ TQStringList fl( fieldName );
+ return index( fl );
+}
+
+/*!
+ \overload
+
+ Returns an index based on \a fieldName.
+*/
+
+TQSqlIndex TQSqlCursor::index( const char* fieldName ) const
+{
+ return index( TQStringList( TQString( fieldName ) ) );
+}
+
+/*!
+ Selects all fields in the cursor from the database matching the
+ filter criteria \a filter. The data is returned in the order
+ specified by the index \a sort. Returns TRUE if the data was
+ successfully selected; otherwise returns FALSE.
+
+ The \a filter is a string containing a SQL \c WHERE clause but
+ without the 'WHERE' keyword. The cursor is initially positioned at
+ an invalid row after this function is called. To move to a valid
+ row, use seek(), first(), last(), prev() or next().
+
+ Example:
+ \code
+ TQSqlCursor cur( "Employee" ); // Use the Employee table or view
+ cur.select( "deptno=10" ); // select all records in department 10
+ while( cur.next() ) {
+ ... // process data
+ }
+ ...
+ // select records in other departments, ordered by department number
+ cur.select( "deptno>10", cur.index( "deptno" ) );
+ ...
+ \endcode
+
+ The filter will apply to any subsequent select() calls that do not
+ explicitly specify another filter. Similarly the sort will apply
+ to any subsequent select() calls that do not explicitly specify
+ another sort.
+
+ \code
+ TQSqlCursor cur( "Employee" );
+ cur.select( "deptno=10" ); // select all records in department 10
+ while( cur.next() ) {
+ ... // process data
+ }
+ ...
+ cur.select(); // re-selects all records in department 10
+ ...
+ \endcode
+
+*/
+
+bool TQSqlCursor::select( const TQString & filter, const TQSqlIndex & sort )
+{
+ TQString fieldList = toString( d->nm );
+ if ( fieldList.isEmpty() )
+ return FALSE;
+ TQString str= "select " + fieldList;
+ str += " from " + d->nm;
+ if ( !filter.isEmpty() ) {
+ d->ftr = filter;
+ str += " where " + filter;
+ } else
+ d->ftr = TQString::null;
+ if ( sort.count() > 0 )
+ str += " order by " + sort.toString( d->nm );
+ d->srt = sort;
+ return exec( str );
+}
+
+/*!
+ \overload
+
+ Selects all fields in the cursor from the database. The rows are
+ returned in the order specified by the last call to setSort() or
+ the last call to select() that specified a sort, whichever is the
+ most recent. If there is no current sort, the order in which the
+ rows are returned is undefined. The records are filtered according
+ to the filter specified by the last call to setFilter() or the
+ last call to select() that specified a filter, whichever is the
+ most recent. If there is no current filter, all records are
+ returned. The cursor is initially positioned at an invalid row. To
+ move to a valid row, use seek(), first(), last(), prev() or
+ next().
+
+ \sa setSort() setFilter()
+*/
+
+bool TQSqlCursor::select()
+{
+ return select( filter(), sort() );
+}
+
+/*!
+ \overload
+
+ Selects all fields in the cursor from the database. The data is
+ returned in the order specified by the index \a sort. The records
+ are filtered according to the filter specified by the last call to
+ setFilter() or the last call to select() that specified a filter,
+ whichever is the most recent. The cursor is initially positioned
+ at an invalid row. To move to a valid row, use seek(), first(),
+ last(), prev() or next().
+*/
+
+bool TQSqlCursor::select( const TQSqlIndex& sort )
+{
+ return select( filter(), sort );
+}
+
+/*!
+ \overload
+
+ Selects all fields in the cursor matching the filter index \a
+ filter. The data is returned in the order specified by the index
+ \a sort. The \a filter index works by constructing a WHERE clause
+ using the names of the fields from the \a filter and their values
+ from the current cursor record. The cursor is initially positioned
+ at an invalid row. To move to a valid row, use seek(), first(),
+ last(), prev() or next(). This function is useful, for example,
+ for retrieving data based upon a table's primary index:
+
+ \code
+ TQSqlCursor cur( "Employee" );
+ TQSqlIndex pk = cur.primaryIndex();
+ cur.setValue( "id", 10 );
+ cur.select( pk, pk ); // generates "SELECT ... FROM Employee WHERE id=10 ORDER BY id"
+ ...
+ \endcode
+
+ In this example the TQSqlIndex, pk, is used for two different
+ purposes. When used as the filter (first) argument, the field
+ names it tqcontains are used to construct the WHERE clause, each set
+ to the current cursor value, \c{WHERE id=10}, in this case. When
+ used as the sort (second) argument the field names it tqcontains are
+ used for the ORDER BY clause, \c{ORDER BY id} in this example.
+*/
+
+bool TQSqlCursor::select( const TQSqlIndex & filter, const TQSqlIndex & sort )
+{
+ return select( toString( filter, this, d->nm, "=", "and" ), sort );
+}
+
+/*!
+ Sets the cursor mode to \a mode. This value can be an OR'ed
+ combination of \l TQSqlCursor::Mode values. The default mode for a
+ cursor is \c TQSqlCursor::Writable.
+
+ \code
+ TQSqlCursor cur( "Employee" );
+ cur.setMode( TQSqlCursor::Writable ); // allow insert/update/delete
+ ...
+ cur.setMode( TQSqlCursor::Insert | TQSqlCursor::Update ); // allow inserts and updates only
+ ...
+ cur.setMode( TQSqlCursor::ReadOnly ); // no inserts/updates/deletes allowed
+
+ \endcode
+*/
+
+void TQSqlCursor::setMode( int mode )
+{
+ d->md = mode;
+}
+
+/*!
+ Returns the current cursor mode.
+
+ \sa setMode()
+*/
+
+int TQSqlCursor::mode() const
+{
+ return d->md;
+}
+
+/*!
+ Sets field \a name to \a calculated. If the field \a name does not
+ exist, nothing happens. The value of a calculated field is set by
+ the calculateField() virtual function which you must reimplement
+ (or the field value will be an invalid TQVariant). Calculated
+ fields do not appear in generated SQL statements sent to the
+ database.
+
+ \sa calculateField() TQSqlRecord::setGenerated()
+*/
+
+void TQSqlCursor::setCalculated( const TQString& name, bool calculated )
+{
+ int pos = position( name );
+ if ( pos < 0 )
+ return;
+ d->infoBuffer[ pos ].setCalculated( calculated );
+ if ( calculated )
+ setGenerated( pos, FALSE );
+}
+
+/*!
+ Returns TRUE if the field \a name exists and is calculated;
+ otherwise returns FALSE.
+
+ \sa setCalculated()
+*/
+
+bool TQSqlCursor::isCalculated( const TQString& name ) const
+{
+ int pos = position( name );
+ if ( pos < 0 )
+ return FALSE;
+ return d->infoBuffer[ pos ].isCalculated();
+}
+
+/*!
+ Sets field \a{name}'s trimmed status to \a trim. If the field \a
+ name does not exist, nothing happens.
+
+ When a trimmed field of type string or cstring is read from the
+ database any trailing (right-most) spaces are removed.
+
+ \sa isTrimmed() TQVariant
+*/
+
+void TQSqlCursor::setTrimmed( const TQString& name, bool trim )
+{
+ int pos = position( name );
+ if ( pos < 0 )
+ return;
+ d->infoBuffer[ pos ].setTrim( trim );
+}
+
+/*!
+ Returns TRUE if the field \a name exists and is trimmed; otherwise
+ returns FALSE.
+
+ When a trimmed field of type string or cstring is read from the
+ database any trailing (right-most) spaces are removed.
+
+ \sa setTrimmed()
+*/
+
+bool TQSqlCursor::isTrimmed( const TQString& name ) const
+{
+ int pos = position( name );
+ if ( pos < 0 )
+ return FALSE;
+ return d->infoBuffer[ pos ].isTrim();
+}
+
+/*!
+ Returns TRUE if the cursor is read-only; otherwise returns FALSE.
+ The default is FALSE. Read-only cursors cannot be edited using
+ insert(), update() or del().
+
+ \sa setMode()
+*/
+
+bool TQSqlCursor::isReadOnly() const
+{
+ return d->md == 0;
+}
+
+/*!
+ Returns TRUE if the cursor will perform inserts; otherwise returns
+ FALSE.
+
+ \sa setMode()
+*/
+
+bool TQSqlCursor::canInsert() const
+{
+ return ( ( d->md & Insert ) == Insert ) ;
+}
+
+
+/*!
+ Returns TRUE if the cursor will perform updates; otherwise returns
+ FALSE.
+
+ \sa setMode()
+*/
+
+bool TQSqlCursor::canUpdate() const
+{
+ return ( ( d->md & Update ) == Update ) ;
+}
+
+/*!
+ Returns TRUE if the cursor will perform deletes; otherwise returns
+ FALSE.
+
+ \sa setMode()
+*/
+
+bool TQSqlCursor::canDelete() const
+{
+ return ( ( d->md & Delete ) == Delete ) ;
+}
+
+/*!
+ \overload
+
+ Returns a formatted string composed of the \a prefix (e.g. table
+ or view name), ".", the \a field name, the \a fieldSep and the
+ field value. If the \a prefix is empty then the string will begin
+ with the \a field name. This function is useful for generating SQL
+ statements.
+*/
+
+TQString TQSqlCursor::toString( const TQString& prefix, TQSqlField* field, const TQString& fieldSep ) const
+{
+ TQString f;
+ if ( field && driver() ) {
+ f = ( prefix.length() > 0 ? prefix + TQString(".") : TQString() ) + field->name();
+ f += " " + fieldSep + " ";
+ if ( field->isNull() ) {
+ f += "NULL";
+ } else {
+ f += driver()->formatValue( field );
+ }
+ }
+ return f;
+}
+
+/*!
+ Returns a formatted string composed of all the fields in \a rec.
+ Each field is composed of the \a prefix (e.g. table or view name),
+ ".", the field name, the \a fieldSep and the field value. If the
+ \a prefix is empty then each field will begin with the field name.
+ The fields are then joined together separated by \a sep. Fields
+ where isGenerated() returns FALSE are not included. This function
+ is useful for generating SQL statements.
+*/
+
+TQString TQSqlCursor::toString( TQSqlRecord* rec, const TQString& prefix, const TQString& fieldSep,
+ const TQString& sep ) const
+{
+ static TQString blank( " " );
+ TQString filter;
+ bool separator = FALSE;
+ for ( uint j = 0; j < count(); ++j ) {
+ TQSqlField* f = rec->field( j );
+ if ( rec->isGenerated( j ) ) {
+ if ( separator )
+ filter += sep + blank;
+ filter += toString( prefix, f, fieldSep );
+ filter += blank;
+ separator = TRUE;
+ }
+ }
+ return filter;
+}
+
+/*!
+ \overload
+
+ Returns a formatted string composed of all the fields in the index
+ \a i. Each field is composed of the \a prefix (e.g. table or view
+ name), ".", the field name, the \a fieldSep and the field value.
+ If the \a prefix is empty then each field will begin with the field
+ name. The field values are taken from \a rec. The fields are then
+ joined together separated by \a sep. Fields where isGenerated()
+ returns FALSE are ignored. This function is useful for generating
+ SQL statements.
+*/
+
+TQString TQSqlCursor::toString( const TQSqlIndex& i, TQSqlRecord* rec, const TQString& prefix,
+ const TQString& fieldSep, const TQString& sep ) const
+{
+ TQString filter;
+ bool separator = FALSE;
+ for( uint j = 0; j < i.count(); ++j ){
+ if ( rec->isGenerated( j ) ) {
+ if( separator ) {
+ filter += " " + sep + " " ;
+ }
+ TQString fn = i.fieldName( j );
+ TQSqlField* f = rec->field( fn );
+ filter += toString( prefix, f, fieldSep );
+ separator = TRUE;
+ }
+ }
+ return filter;
+}
+
+/*!
+ \overload
+
+ Inserts the current contents of the cursor's edit record buffer
+ into the database, if the cursor allows inserts. Returns the
+ number of rows affected by the insert. For error information, use
+ lastError().
+
+ If \a tqinvalidate is TRUE (the default), the cursor will no longer
+ be positioned on a valid record and can no longer be navigated. A
+ new select() call must be made before navigating to a valid
+ record.
+
+ \quotefile sql/overview/insert2/main.cpp
+ \skipto prices
+ \printline prices
+ \printuntil insert
+
+ In the above example, a cursor is created on the 'prices' table
+ and a pointer to the insert buffer is aquired using primeInsert().
+ Each field's value is set to the desired value and then insert()
+ is called to insert the data into the database. Remember: all edit
+ operations (insert(), update() and delete()) operate on the
+ contents of the cursor edit buffer and not on the contents of the
+ cursor itself.
+
+ \sa setMode() lastError()
+*/
+
+int TQSqlCursor::insert( bool tqinvalidate )
+{
+ if ( ( d->md & Insert ) != Insert || !driver() )
+ return FALSE;
+ int k = d->editBuffer.count();
+ if ( k == 0 )
+ return 0;
+
+ TQString fList;
+ TQString vList;
+ bool comma = FALSE;
+ // use a prepared query if the driver supports it
+ if ( driver()->hasFeature( TQSqlDriver::PreparedQueries ) ) {
+ int cnt = 0;
+ bool oraStyle = driver()->hasFeature( TQSqlDriver::NamedPlaceholders );
+ for( int j = 0; j < k; ++j ) {
+ TQSqlField* f = d->editBuffer.field( j );
+ if ( d->editBuffer.isGenerated( j ) ) {
+ if ( comma ) {
+ fList += ",";
+ vList += ",";
+ }
+ fList += f->name();
+ vList += (oraStyle == TRUE) ? ":f" + TQString::number(cnt) : TQString("?");
+ cnt++;
+ comma = TRUE;
+ }
+ }
+ if ( !comma ) {
+ return 0;
+ }
+ TQString str;
+ str.append( "insert into " ).append( name() ).append( "(" ).append( fList ).append( ") values (" ).append( vList ). append ( ")" );
+ return applyPrepared( str, tqinvalidate );
+ } else {
+ for( int j = 0; j < k; ++j ) {
+ TQSqlField* f = d->editBuffer.field( j );
+ if ( d->editBuffer.isGenerated( j ) ) {
+ if ( comma ) {
+ fList += ",";
+ vList += ",";
+ }
+ fList += f->name();
+ vList += driver()->formatValue( f );
+ comma = TRUE;
+ }
+ }
+
+ if ( !comma ) {
+ // no valid fields found
+ return 0;
+ }
+ TQString str;
+ str.append( "insert into " ).append( name() ).append( "(" ).append( fList ).append( ") values (" ).append( vList ). append ( ")" );
+ return apply( str, tqinvalidate );
+ }
+}
+
+/*!
+ Returns the current internal edit buffer. If \a copy is TRUE (the
+ default is FALSE), the current cursor field values are first
+ copied into the edit buffer. The edit buffer is valid as long as
+ the cursor remains valid. The cursor retains ownership of the
+ returned pointer, so it must not be deleted or modified.
+
+ \sa primeInsert(), primeUpdate() primeDelete()
+*/
+
+TQSqlRecord* TQSqlCursor::editBuffer( bool copy )
+{
+ if ( copy ) {
+ for(uint i = 0; i < d->editBuffer.count(); i++) {
+ if ( TQSqlRecord::isNull( i ) ) {
+ d->editBuffer.setNull( i );
+ } else {
+ d->editBuffer.setValue( i, value( i ) );
+ }
+ }
+ }
+ return &d->editBuffer;
+}
+
+/*!
+ This function primes the edit buffer's field values for update and
+ returns the edit buffer. The default implementation copies the
+ field values from the current cursor record into the edit buffer
+ (therefore, this function is equivalent to calling editBuffer(
+ TRUE ) ). The cursor retains ownership of the returned pointer, so
+ it must not be deleted or modified.
+
+ \sa editBuffer() update()
+*/
+
+TQSqlRecord* TQSqlCursor::primeUpdate()
+{
+ // memorize the primary keys as they were before the user changed the values in editBuffer
+ TQSqlRecord* buf = editBuffer( TRUE );
+ TQSqlIndex idx = primaryIndex( FALSE );
+ if ( !idx.isEmpty() )
+ d->editIndex = toString( idx, buf, d->nm, "=", "and" );
+ else
+ d->editIndex = qWhereClause( buf, d->nm, "and", driver() );
+ return buf;
+}
+
+/*!
+ This function primes the edit buffer's field values for delete and
+ returns the edit buffer. The default implementation copies the
+ field values from the current cursor record into the edit buffer
+ (therefore, this function is equivalent to calling editBuffer(
+ TRUE ) ). The cursor retains ownership of the returned pointer, so
+ it must not be deleted or modified.
+
+ \sa editBuffer() del()
+*/
+
+TQSqlRecord* TQSqlCursor::primeDelete()
+{
+ return editBuffer( TRUE );
+}
+
+/*!
+ This function primes the edit buffer's field values for insert and
+ returns the edit buffer. The default implementation clears all
+ field values in the edit buffer. The cursor retains ownership of
+ the returned pointer, so it must not be deleted or modified.
+
+ \sa editBuffer() insert()
+*/
+
+TQSqlRecord* TQSqlCursor::primeInsert()
+{
+ d->editBuffer.clearValues();
+ return &d->editBuffer;
+}
+
+
+/*!
+ Updates the database with the current contents of the edit buffer.
+ Returns the number of records which were updated.
+ For error information, use lastError().
+
+ Only records which meet the filter criteria specified by the
+ cursor's primary index are updated. If the cursor does not contain
+ a primary index, no update is performed and 0 is returned.
+
+ If \a tqinvalidate is TRUE (the default), the current cursor can no
+ longer be navigated. A new select() call must be made before you
+ can move to a valid record. For example:
+
+ \quotefile sql/overview/update/main.cpp
+ \skipto prices
+ \printline prices
+ \printuntil update
+ \printline
+
+ In the above example, a cursor is created on the 'prices' table
+ and is positioned on the record to be updated. Then a pointer to
+ the cursor's edit buffer is acquired using primeUpdate(). A new
+ value is calculated and placed into the edit buffer with the
+ setValue() call. Finally, an update() call is made on the cursor
+ which uses the tables's primary index to update the record in the
+ database with the contents of the cursor's edit buffer. Remember:
+ all edit operations (insert(), update() and delete()) operate on
+ the contents of the cursor edit buffer and not on the contents of
+ the cursor itself.
+
+ Note that if the primary index does not uniquely distinguish
+ records the database may be changed into an inconsistent state.
+
+ \sa setMode() lastError()
+*/
+
+int TQSqlCursor::update( bool tqinvalidate )
+{
+ if ( d->editIndex.isEmpty() )
+ return 0;
+ return update( d->editIndex, tqinvalidate );
+}
+
+/*!
+ \overload
+
+ Updates the database with the current contents of the cursor edit
+ buffer using the specified \a filter. Returns the number of
+ records which were updated.
+ For error information, use lastError().
+
+ Only records which meet the filter criteria are updated, otherwise
+ all records in the table are updated.
+
+ If \a tqinvalidate is TRUE (the default), the cursor can no longer
+ be navigated. A new select() call must be made before you can move
+ to a valid record.
+
+ \sa primeUpdate() setMode() lastError()
+*/
+
+int TQSqlCursor::update( const TQString & filter, bool tqinvalidate )
+{
+ if ( ( d->md & Update ) != Update ) {
+ return FALSE;
+ }
+ int k = count();
+ if ( k == 0 ) {
+ return 0;
+ }
+
+ // use a prepared query if the driver supports it
+ if ( driver()->hasFeature( TQSqlDriver::PreparedQueries ) ) {
+ TQString fList;
+ bool comma = FALSE;
+ int cnt = 0;
+ bool oraStyle = driver()->hasFeature( TQSqlDriver::NamedPlaceholders );
+ for( int j = 0; j < k; ++j ) {
+ TQSqlField* f = d->editBuffer.field( j );
+ if ( d->editBuffer.isGenerated( j ) ) {
+ if ( comma ) {
+ fList += ",";
+ }
+ fList += f->name() + " = " + (oraStyle == TRUE ? ":f" + TQString::number(cnt) : TQString("?"));
+ cnt++;
+ comma = TRUE;
+ }
+ }
+ if ( !comma ) {
+ return 0;
+ }
+ TQString str = "update " + name() + " set " + fList;
+ if ( filter.length() ) {
+ str+= " where " + filter;
+ }
+ return applyPrepared( str, tqinvalidate );
+ } else {
+ TQString str = "update " + name();
+ str += " set " + toString( &d->editBuffer, TQString::null, "=", "," );
+ if ( filter.length() ) {
+ str+= " where " + filter;
+ }
+ return apply( str, tqinvalidate );
+ }
+}
+
+/*!
+ Deletes a record from the database using the cursor's primary
+ index and the contents of the cursor edit buffer. Returns the
+ number of records which were deleted.
+ For error information, use lastError().
+
+ Only records which meet the filter criteria specified by the
+ cursor's primary index are deleted. If the cursor does not contain
+ a primary index, no delete is performed and 0 is returned. If \a
+ tqinvalidate is TRUE (the default), the current cursor can no longer
+ be navigated. A new select() call must be made before you can move
+ to a valid record. For example:
+
+ \quotefile sql/overview/delete/main.cpp
+ \skipto prices
+ \printline prices
+ \printuntil }
+
+ In the above example, a cursor is created on the 'prices' table
+ and positioned to the record to be deleted. First primeDelete() is
+ called to populate the edit buffer with the current cursor values,
+ e.g. with an id of 999, and then del() is called to actually
+ delete the record from the database. Remember: all edit operations
+ (insert(), update() and delete()) operate on the contents of the
+ cursor edit buffer and not on the contents of the cursor itself.
+
+ \sa primeDelete() setMode() lastError()
+*/
+
+int TQSqlCursor::del( bool tqinvalidate )
+{
+ TQSqlIndex idx = primaryIndex( FALSE );
+ if ( idx.isEmpty() )
+ return del( qWhereClause( &d->editBuffer, d->nm, "and", driver() ), tqinvalidate );
+ else
+ return del( toString( primaryIndex(), &d->editBuffer, d->nm,
+ "=", "and" ), tqinvalidate );
+}
+
+/*!
+ \overload
+
+ Deletes the current cursor record from the database using the
+ filter \a filter. Only records which meet the filter criteria are
+ deleted. Returns the number of records which were deleted. If \a
+ tqinvalidate is TRUE (the default), the current cursor can no longer
+ be navigated. A new select() call must be made before you can move
+ to a valid record. For error information, use lastError().
+
+ The \a filter is an SQL \c WHERE clause, e.g. \c{id=500}.
+
+ \sa setMode() lastError()
+*/
+
+int TQSqlCursor::del( const TQString & filter, bool tqinvalidate )
+{
+ if ( ( d->md & Delete ) != Delete )
+ return 0;
+ int k = count();
+ if( k == 0 ) return 0;
+ TQString str = "delete from " + name();
+ if ( filter.length() )
+ str+= " where " + filter;
+ return apply( str, tqinvalidate );
+}
+
+/*
+ \internal
+*/
+
+int TQSqlCursor::apply( const TQString& q, bool tqinvalidate )
+{
+ int ar = 0;
+ if ( tqinvalidate ) {
+ if ( exec( q ) )
+ ar = numRowsAffected();
+ } else if ( driver() ) {
+ TQSqlQuery* sql = d->query();
+ if ( sql && sql->exec( q ) )
+ ar = sql->numRowsAffected();
+ }
+ return ar;
+}
+
+/*
+ \internal
+*/
+
+int TQSqlCursor::applyPrepared( const TQString& q, bool tqinvalidate )
+{
+ int ar = 0;
+ TQSqlQuery* sql = 0;
+
+ if ( tqinvalidate ) {
+ sql = (TQSqlQuery*)this;
+ d->lastAt = TQSql::BeforeFirst;
+ } else {
+ sql = d->query();
+ }
+ if ( !sql )
+ return 0;
+
+ if ( tqinvalidate || sql->lastQuery() != q ) {
+ if ( !sql->prepare( q ) )
+ return 0;
+ }
+
+ int cnt = 0;
+ int fieldCount = (int)count();
+ for ( int j = 0; j < fieldCount; ++j ) {
+ const TQSqlField* f = d->editBuffer.field( j );
+ if ( d->editBuffer.isGenerated( j ) ) {
+ sql->bindValue( cnt, f->value() );
+ cnt++;
+ }
+ }
+ if ( sql->exec() ) {
+ ar = sql->numRowsAffected();
+ }
+ return ar;
+}
+
+/*! \reimp
+
+ Executes the SQL query \a sql. Returns TRUE of the cursor is
+ active, otherwise returns FALSE.
+
+*/
+bool TQSqlCursor::exec( const TQString & sql )
+{
+ d->lastAt = TQSql::BeforeFirst;
+ TQSqlQuery::exec( sql );
+ return isActive();
+}
+
+/*!
+ Protected virtual function which is called whenever a field needs
+ to be calculated. If calculated fields are being used, derived
+ classes must reimplement this function and return the appropriate
+ value for field \a name. The default implementation returns an
+ invalid TQVariant.
+
+ \sa setCalculated()
+*/
+
+TQVariant TQSqlCursor::calculateField( const TQString& )
+{
+ return TQVariant();
+}
+
+/*! \internal
+ Ensure fieldlist is synced with query.
+
+*/
+
+static TQString qTrim( const TQString& s )
+{
+ TQString result = s;
+ int end = result.length() - 1;
+ while ( end >= 0 && result[end].isSpace() ) // skip white space from end
+ end--;
+ result.truncate( end + 1 );
+ return result;
+}
+
+/*! \internal
+ */
+
+void TQSqlCursor::sync()
+{
+ if ( isActive() && isValid() && d->lastAt != at() ) {
+ d->lastAt = at();
+ uint i = 0;
+ uint j = 0;
+ bool haveCalculatedFields = FALSE;
+ for ( ; i < count(); ++i ) {
+ if ( !haveCalculatedFields && d->infoBuffer[i].isCalculated() ) {
+ haveCalculatedFields = TRUE;
+ }
+ if ( TQSqlRecord::isGenerated( i ) ) {
+ TQVariant v = TQSqlQuery::value( j );
+ if ( ( v.type() == TQVariant::String || v.type() == TQVariant::CString ) &&
+ d->infoBuffer[ i ].isTrim() ) {
+ v = qTrim( v.toString() );
+ }
+ TQSqlRecord::setValue( i, v );
+ if ( TQSqlQuery::isNull( j ) )
+ TQSqlRecord::field( i )->setNull();
+ j++;
+ }
+ }
+ if ( haveCalculatedFields ) {
+ for ( i = 0; i < count(); ++i ) {
+ if ( d->infoBuffer[i].isCalculated() )
+ TQSqlRecord::setValue( i, calculateField( fieldName( i ) ) );
+ }
+ }
+ }
+}
+
+/*! \reimp
+
+*/
+
+void TQSqlCursor::afterSeek()
+{
+ sync();
+}
+
+/*!
+ \reimp
+
+ Returns the value of field number \a i.
+*/
+
+TQVariant TQSqlCursor::value( int i ) const
+{
+ return TQSqlRecord::value( i );
+}
+
+/*!
+ \reimp
+
+ Returns the value of the field called \a name.
+*/
+
+TQVariant TQSqlCursor::value( const TQString& name ) const
+{
+ return TQSqlRecord::value( name );
+}
+
+/*! \internal
+ cursors should be filled with TQSqlFieldInfos...
+*/
+void TQSqlCursor::append( const TQSqlField& field )
+{
+ append( TQSqlFieldInfo( field ) );
+}
+/*! \internal
+ cursors should be filled with TQSqlFieldInfos...
+*/
+void TQSqlCursor::insert( int pos, const TQSqlField& field )
+{
+ insert( pos, TQSqlFieldInfo( field ) );
+}
+
+/*!
+ Returns TRUE if the field \a i is NULL or if there is no field at
+ position \a i; otherwise returns FALSE.
+
+ This is the same as calling TQSqlRecord::isNull( \a i )
+*/
+bool TQSqlCursor::isNull( int i ) const
+{
+ return TQSqlRecord::isNull( i );
+}
+/*!
+ \overload
+
+ Returns TRUE if the field called \a name is NULL or if there is no
+ field called \a name; otherwise returns FALSE.
+
+ This is the same as calling TQSqlRecord::isNull( \a name )
+*/
+bool TQSqlCursor::isNull( const TQString& name ) const
+{
+ return TQSqlRecord::isNull( name );
+}
+
+/*! \reimp */
+void TQSqlCursor::setValue( int i, const TQVariant& val )
+{
+#ifdef TQT_DEBUG
+ qDebug("TQSqlCursor::setValue(): This will not affect actual database values. Use primeInsert(), primeUpdate() or primeDelete().");
+#endif
+ TQSqlRecord::setValue( i, val );
+}
+
+/*! \reimp */
+void TQSqlCursor::setValue( const TQString& name, const TQVariant& val )
+{
+#ifdef TQT_DEBUG
+ qDebug("TQSqlCursor::setValue(): This will not affect actual database values. Use primeInsert(), primeUpdate() or primeDelete().");
+#endif
+ TQSqlRecord::setValue( name, val );
+}
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlcursor.h b/tqtinterface/qt4/src/sql/tqsqlcursor.h
new file mode 100644
index 0000000..9617b12
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlcursor.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Definition of TQSqlCursor class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLCURSOR_H
+#define TQSQLCURSOR_H
+
+#ifndef TQT_H
+#include "tqsqlrecord.h"
+#include "tqstringlist.h"
+#include "tqsqlquery.h"
+#include "tqsqlindex.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQSqlDatabase;
+class TQSqlCursorPrivate;
+
+class TQM_EXPORT_SQL TQSqlCursor : public TQSqlRecord, public TQSqlQuery
+{
+public:
+ TQSqlCursor( const TQString & name = TQString::null, bool autopopulate = TRUE, TQSqlDatabase* db = 0 );
+ TQSqlCursor( const TQSqlCursor & other );
+ TQSqlCursor& operator=( const TQSqlCursor& other );
+ ~TQSqlCursor();
+
+ enum Mode {
+ ReadOnly = 0,
+ Insert = 1,
+ Update = 2,
+ Delete = 4,
+ Writable = 7
+ };
+
+ TQVariant value( int i ) const;
+ TQVariant value( const TQString& name ) const;
+ void setValue( int i, const TQVariant& val );
+ void setValue( const TQString& name, const TQVariant& val );
+ virtual TQSqlIndex primaryIndex( bool prime = TRUE ) const;
+ virtual TQSqlIndex index( const TQStringList& fieldNames ) const;
+ TQSqlIndex index( const TQString& fieldName ) const;
+ TQSqlIndex index( const char* fieldName ) const;
+ virtual void setPrimaryIndex( const TQSqlIndex& idx );
+
+ virtual void append( const TQSqlFieldInfo& fieldInfo );
+ virtual void insert( int pos, const TQSqlFieldInfo& fieldInfo );
+ void remove( int pos );
+ void clear();
+ void setGenerated( const TQString& name, bool generated );
+ void setGenerated( int i, bool generated );
+
+ virtual TQSqlRecord* editBuffer( bool copy = FALSE );
+ virtual TQSqlRecord* primeInsert();
+ virtual TQSqlRecord* primeUpdate();
+ virtual TQSqlRecord* primeDelete();
+ virtual int insert( bool tqinvalidate = TRUE );
+ virtual int update( bool tqinvalidate = TRUE );
+ virtual int del( bool tqinvalidate = TRUE );
+
+ virtual void setMode( int flags );
+ int mode() const;
+ virtual void setCalculated( const TQString& name, bool calculated );
+ bool isCalculated( const TQString& name ) const;
+ virtual void setTrimmed( const TQString& name, bool trim );
+ bool isTrimmed( const TQString& name ) const;
+
+ bool isReadOnly() const;
+ bool canInsert() const;
+ bool canUpdate() const;
+ bool canDelete() const;
+
+ bool select();
+ bool select( const TQSqlIndex& sort );
+ bool select( const TQSqlIndex & filter, const TQSqlIndex & sort );
+ virtual bool select( const TQString & filter, const TQSqlIndex & sort = TQSqlIndex() );
+
+ virtual void setSort( const TQSqlIndex& sort );
+ TQSqlIndex sort() const;
+ virtual void setFilter( const TQString& filter );
+ TQString filter() const;
+ virtual void setName( const TQString& name, bool autopopulate = TRUE );
+ TQString name() const;
+ TQString toString( const TQString& prefix = TQString::null,
+ const TQString& sep = "," ) const;
+ bool isNull( int i ) const;
+ bool isNull( const TQString& name ) const;
+
+protected:
+ void afterSeek();
+ bool exec( const TQString & sql );
+
+ virtual TQVariant calculateField( const TQString& name );
+ virtual int update( const TQString & filter, bool tqinvalidate = TRUE );
+ virtual int del( const TQString & filter, bool tqinvalidate = TRUE );
+
+ virtual TQString toString( const TQString& prefix, TQSqlField* field, const TQString& fieldSep ) const;
+ virtual TQString toString( TQSqlRecord* rec, const TQString& prefix, const TQString& fieldSep,
+ const TQString& sep ) const;
+ virtual TQString toString( const TQSqlIndex& i, TQSqlRecord* rec, const TQString& prefix,
+ const TQString& fieldSep, const TQString& sep ) const;
+
+private:
+ void sync();
+ int apply( const TQString& q, bool tqinvalidate );
+ int applyPrepared( const TQString& q, bool tqinvalidate );
+ TQSqlRecord& operator=( const TQSqlRecord & list );
+ void append( const TQSqlField& field );
+ void insert( int pos, const TQSqlField& field );
+
+ TQSqlCursorPrivate* d;
+};
+
+
+
+
+#endif // TQT_NO_SQL
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqldatabase.cpp b/tqtinterface/qt4/src/sql/tqsqldatabase.cpp
new file mode 100644
index 0000000..45cca58
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqldatabase.cpp
@@ -0,0 +1,1332 @@
+/****************************************************************************
+**
+** Implementation of TQSqlDatabase class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqldatabase.h"
+
+#ifndef TQT_NO_SQL
+
+#ifdef TQ_OS_WIN32
+// Conflicting declarations of LPCBYTE in sqlfront.h and winscard.h
+#define _WINSCARD_H_
+#endif
+
+#ifdef TQT_STQL_POSTGRES
+#include "drivers/psql/tqsql_psql.h"
+#endif
+#ifdef TQT_STQL_MYSQL
+#include "drivers/mysql/tqsql_mysql.h"
+#endif
+#ifdef TQT_STQL_ODBC
+#include "drivers/odbc/tqsql_odbc.h"
+#endif
+#ifdef TQT_STQL_OCI
+#include "drivers/oci/tqsql_oci.h"
+#endif
+#ifdef TQT_STQL_TDS
+#include "drivers/tds/tqsql_tds.h"
+#endif
+#ifdef TQT_STQL_DB2
+#include "drivers/db2/tqsql_db2.h"
+#endif
+#ifdef TQT_STQL_STQLITE
+#include "drivers/sqlite/tqsql_sqlite.h"
+#endif
+#ifdef TQT_STQL_IBASE
+#include "drivers/ibase/tqsql_ibase.h"
+#endif
+
+#include "tqapplication.h"
+#include "tqsqlresult.h"
+#include "tqsqldriver.h"
+#include "tqsqldriverinterface_p.h"
+#include <private/tqpluginmanager_p.h>
+#include <private/tqsqlextension_p.h>
+#include "tqobject.h"
+#include "tqguardedptr.h"
+#include "tqcleanuphandler.h"
+#include "tqdict.h"
+#include <stdlib.h>
+
+TQT_STATIC_CONST_IMPL char * const TQSqlDatabase::defaultConnection = "qt_sql_default_connection";
+
+TQPtrDict<TQSqlDriverExtension> *qt_driver_extension_dict = 0;
+TQPtrDict<TQSqlOpenExtension> *qt_open_extension_dict = 0;
+
+static TQSingleCleanupHandler< TQPtrDict<TQSqlDriverExtension> > qt_driver_ext_cleanup;
+static TQSingleCleanupHandler< TQPtrDict<TQSqlOpenExtension> > qt_open_ext_cleanup;
+
+TQ_EXPORT TQPtrDict<TQSqlDriverExtension> *qSqlDriverExtDict()
+{
+ if ( !qt_driver_extension_dict ) {
+ qt_driver_extension_dict = new TQPtrDict<TQSqlDriverExtension>;
+ qt_driver_ext_cleanup.set( &qt_driver_extension_dict );
+ }
+ return qt_driver_extension_dict;
+}
+
+TQ_EXPORT TQPtrDict<TQSqlOpenExtension> *qSqlOpenExtDict()
+{
+ if ( !qt_open_extension_dict ) {
+ qt_open_extension_dict = new TQPtrDict<TQSqlOpenExtension>;
+ qt_open_ext_cleanup.set( &qt_open_extension_dict );
+ }
+ return qt_open_extension_dict;
+}
+
+class TQNullResult : public TQSqlResult
+{
+public:
+ TQNullResult(const TQSqlDriver* d): TQSqlResult(d){}
+ ~TQNullResult(){}
+protected:
+ TQVariant data( int ) { return TQVariant(); }
+ bool reset ( const TQString& sqlquery ) { TQString s(sqlquery); return FALSE; }
+ bool fetch( int i ) { i = i; return FALSE; }
+ bool fetchFirst() { return FALSE; }
+ bool fetchLast() { return FALSE; }
+ bool isNull( int ) {return FALSE; }
+ TQSqlRecord record() {return TQSqlRecord();}
+ int size() {return 0;}
+ int numRowsAffected() {return 0;}
+};
+
+class TQNullDriver : public TQSqlDriver
+{
+public:
+ TQNullDriver(): TQSqlDriver(){}
+ ~TQNullDriver(){}
+ bool hasFeature( DriverFeature /* f */ ) const { return FALSE; } ;
+ bool open( const TQString & ,
+ const TQString & ,
+ const TQString & ,
+ const TQString &,
+ int ) {
+ return FALSE;
+ }
+ void close() {}
+ TQSqlQuery createQuery() const { return TQSqlQuery( new TQNullResult(this) ); }
+};
+
+typedef TQDict<TQSqlDriverCreatorBase> TQDriverDict;
+
+class TQSqlDatabaseManager : public TQObject
+{
+public:
+ TQSqlDatabaseManager( TQObject * tqparent = 0, const char * name = 0 );
+ ~TQSqlDatabaseManager();
+ static TQSqlDatabase* database( const TQString& name, bool open );
+ static TQSqlDatabase* addDatabase( TQSqlDatabase* db, const TQString & name );
+ static void removeDatabase( const TQString& name );
+ static void removeDatabase( TQSqlDatabase* db );
+ static bool tqcontains( const TQString& name );
+ static TQDriverDict* driverDict();
+
+protected:
+ static TQSqlDatabaseManager* instance();
+ TQDict< TQSqlDatabase > dbDict;
+ TQDriverDict* drDict;
+};
+
+/*!
+ Constructs an SQL database manager.
+*/
+
+TQSqlDatabaseManager::TQSqlDatabaseManager( TQObject * tqparent, const char * name )
+ : TQObject( tqparent, name ), dbDict( 1 ), drDict( 0 )
+{
+}
+
+/*!
+ Destroys the object and frees any allocated resources. All open
+ database connections are closed. All database connections are
+ deleted.
+*/
+
+TQSqlDatabaseManager::~TQSqlDatabaseManager()
+{
+ TQDictIterator< TQSqlDatabase > it( dbDict );
+ while ( it.current() ) {
+ it.current()->close();
+ delete it.current();
+ ++it;
+ }
+ delete drDict;
+}
+
+/*!
+ \internal
+*/
+TQDriverDict* TQSqlDatabaseManager::driverDict()
+{
+ TQSqlDatabaseManager* sqlConnection = instance();
+ if ( !sqlConnection->drDict ) {
+ sqlConnection->drDict = new TQDriverDict();
+ sqlConnection->drDict->setAutoDelete( TRUE );
+ }
+ return sqlConnection->drDict;
+}
+
+
+/*!
+ \internal
+*/
+TQSqlDatabaseManager* TQSqlDatabaseManager::instance()
+{
+ static TQGuardedPtr<TQSqlDatabaseManager> sqlConnection = 0;
+ if ( !sqlConnection ) {
+ if( tqApp == 0 ){
+ qFatal( "TQSqlDatabaseManager: A TQApplication object has to be "
+ "instantiated in order to use the SQL module." );
+ return 0;
+ }
+ sqlConnection = new TQSqlDatabaseManager( TQT_TQOBJECT(tqApp), "database manager" );
+ }
+ return (TQSqlDatabaseManager*)sqlConnection;
+}
+
+/*!
+ Returns the database connection called \a name. If \a open is
+ TRUE, the database connection is opened. If \a name does not exist
+ in the list of managed databases, 0 is returned.
+*/
+
+TQSqlDatabase* TQSqlDatabaseManager::database( const TQString& name, bool open )
+{
+ if ( !tqcontains( name ) )
+ return 0;
+
+ TQSqlDatabaseManager* sqlConnection = instance();
+ TQSqlDatabase* db = sqlConnection->dbDict.tqfind( name );
+ if ( db && !db->isOpen() && open ) {
+ db->open();
+#ifdef TQT_CHECK_RANGE
+ if ( !db->isOpen() )
+ qWarning("TQSqlDatabaseManager::database: unable to open database: %s: %s",
+ db->lastError().databaseText().latin1(), db->lastError().driverText().latin1() );
+#endif
+ }
+ return db;
+}
+
+/*!
+ Returns TRUE if the list of database connections tqcontains \a name;
+ otherwise returns FALSE.
+*/
+
+bool TQSqlDatabaseManager::tqcontains( const TQString& name )
+{
+ TQSqlDatabaseManager* sqlConnection = instance();
+ TQSqlDatabase* db = sqlConnection->dbDict.tqfind( name );
+ if ( db )
+ return TRUE;
+ return FALSE;
+}
+
+
+/*!
+ Adds a database to the SQL connection manager. The database
+ connection is referred to by \a name. The newly added database
+ connection is returned. This function will only return 0 if it is
+ called \e before a TQApplication object has been instantiated. Use
+ the output of drivers() to determine whether a particular driver
+ is available or not.
+
+ The returned TQSqlDatabase object is owned by the framework and
+ must not be deleted. If you want to explicitly remove the connection,
+ use removeDatabase().
+
+ \sa TQSqlDatabase database()
+*/
+
+TQSqlDatabase* TQSqlDatabaseManager::addDatabase( TQSqlDatabase* db, const TQString & name )
+{
+ TQSqlDatabaseManager* sqlConnection = instance();
+ if( sqlConnection == 0 )
+ return 0;
+ if ( tqcontains( name ) )
+ sqlConnection->removeDatabase( name );
+ sqlConnection->dbDict.insert( name, db );
+ return db;
+}
+
+/*!
+ Removes the database connection \a name from the SQL connection
+ manager.
+
+ \warning There should be no open queries on the database
+ connection when this function is called, otherwise a resource leak
+ will occur.
+*/
+
+void TQSqlDatabaseManager::removeDatabase( const TQString& name )
+{
+ TQSqlDatabaseManager* sqlConnection = instance();
+ sqlConnection->dbDict.setAutoDelete( TRUE );
+ sqlConnection->dbDict.remove( name );
+ sqlConnection->dbDict.setAutoDelete( FALSE );
+}
+
+
+/*!
+ Removes the database connection \a db from the SQL connection
+ manager. The TQSqlDatabase object is destroyed when it is removed
+ from the manager.
+
+ \warning The \a db pointer is not valid after this function has
+ been called.
+*/
+
+void TQSqlDatabaseManager::removeDatabase( TQSqlDatabase* db )
+{
+ TQSqlDatabaseManager* sqlConnection = instance();
+ if ( !sqlConnection )
+ return;
+ TQDictIterator< TQSqlDatabase > it( sqlConnection->dbDict );
+ while ( it.current() ) {
+ if ( it.current() == db ) {
+ sqlConnection->dbDict.remove( it.currentKey() );
+ db->close();
+ delete db;
+ break;
+ }
+ ++it;
+ }
+}
+
+class TQSqlDatabasePrivate
+{
+public:
+ TQSqlDatabasePrivate():
+ driver(0),
+#ifndef TQT_NO_COMPONENT
+ plugIns(0),
+#endif
+ port(-1) {}
+ ~TQSqlDatabasePrivate()
+ {
+ }
+ TQSqlDriver* driver;
+#ifndef TQT_NO_COMPONENT
+ TQPluginManager<TQSqlDriverFactoryInterface> *plugIns;
+#endif
+ TQString dbname;
+ TQString uname;
+ TQString pword;
+ TQString hname;
+ TQString drvName;
+ int port;
+ TQString connOptions;
+};
+
+/*!
+ \class TQSqlDatabase tqsqldatabase.h
+ \brief The TQSqlDatabase class is used to create SQL database
+ connections and to provide transaction handling.
+
+ \ingroup database
+ \mainclass
+ \module sql
+
+ Note that transaction handling is not supported by every SQL
+ database. You can tqfind out whether transactions are supported
+ using TQSqlDriver::hasFeature().
+
+ The TQSqlDatabase class provides an abstract interface for
+ accessing many types of database backends. Database-specific
+ drivers are used internally to actually access and manipulate
+ data, (see TQSqlDriver). Result set objects provide the interface
+ for executing and manipulating SQL queries (see TQSqlQuery).
+*/
+
+/*!
+ Adds a database to the list of database connections using the
+ driver \a type and the connection name \a connectionName.
+
+ The database connection is referred to by \a connectionName. The
+ newly added database connection is returned. This pointer is owned
+ by TQSqlDatabase and will be deleted on program exit or when
+ removeDatabase() is called.
+
+ If \a connectionName is not specified, the newly added database
+ connection becomes the default database connection for the
+ application, and subsequent calls to database() (without a
+ database name parameter) will return a pointer to it. If \a
+ connectionName is given, use \link TQSqlDatabase::database()
+ database(connectionName)\endlink to retrieve a pointer to the
+ database connection.
+
+ \warning If you add a database with the same name as an
+ existing database, the new database will tqreplace the old one.
+ This will happen automatically if you call this function more
+ than once without specifying \a connectionName.
+
+ \sa database() removeDatabase()
+*/
+TQSqlDatabase* TQSqlDatabase::addDatabase( const TQString& type, const TQString& connectionName )
+{
+ return TQSqlDatabaseManager::addDatabase( new TQSqlDatabase( type, connectionName ), connectionName );
+}
+
+/*!
+ Returns the database connection called \a connectionName. The
+ database connection must have been previously added with
+ addDatabase(). If \a open is TRUE (the default) and the database
+ connection is not already open it is opened now. If no \a
+ connectionName is specified the default connection is used. If \a
+ connectionName does not exist in the list of databases, 0 is
+ returned. The pointer returned is owned by TQSqlDatabase and should
+ \e not be deleted.
+
+ \warning There are restrictions on the use of database connections
+ in threaded applications. Please see the \link threads.html#threads-sql
+ Thread Support in TQt\endlink document for more information about
+ threading and SQL databases.
+*/
+
+TQSqlDatabase* TQSqlDatabase::database( const TQString& connectionName, bool open )
+{
+ return TQSqlDatabaseManager::database( connectionName, open );
+}
+
+/*!
+ Removes the database connection \a connectionName from the list of
+ database connections.
+
+ \warning There should be no open queries on the database
+ connection when this function is called, otherwise a resource leak
+ will occur.
+*/
+
+void TQSqlDatabase::removeDatabase( const TQString& connectionName )
+{
+ TQSqlDatabaseManager::removeDatabase( connectionName );
+}
+
+/*!
+ \overload
+
+ Removes the database connection \a db from the list of database
+ connections. The TQSqlDatabase object is destroyed when it is removed
+ from the list.
+
+ \warning The \a db pointer is not valid after this function has
+ been called. There should be no open queries on the database
+ connection when this function is called, otherwise a resource leak
+ will occur.
+*/
+
+void TQSqlDatabase::removeDatabase( TQSqlDatabase* db )
+{
+ TQSqlDatabaseManager::removeDatabase( db );
+}
+
+/*!
+ Returns a list of all the available database drivers.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = TQSqlDatabase::drivers();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+
+TQStringList TQSqlDatabase::drivers()
+{
+ TQStringList l;
+
+#ifndef TQT_NO_COMPONENT
+ TQPluginManager<TQSqlDriverFactoryInterface> *plugIns;
+ plugIns = new TQPluginManager<TQSqlDriverFactoryInterface>( IID_TQSqlDriverFactory, TQApplication::libraryPaths(), TQString("/sqldrivers") );
+
+ l = plugIns->featureList();
+ delete plugIns;
+#endif
+
+ TQDictIterator<TQSqlDriverCreatorBase> itd( *TQSqlDatabaseManager::driverDict() );
+ while ( itd.current() ) {
+ if ( !l.tqcontains( itd.currentKey() ) )
+ l << itd.currentKey();
+ ++itd;
+ }
+
+#ifdef TQT_STQL_POSTGRES
+ if ( !l.tqcontains( "TQPSQL7" ) )
+ l << "TQPSQL7";
+#endif
+#ifdef TQT_STQL_MYSQL
+ if ( !l.tqcontains( "TQMYSQL3" ) )
+ l << "TQMYSQL3";
+#endif
+#ifdef TQT_STQL_ODBC
+ if ( !l.tqcontains( "TQODBC3" ) )
+ l << "TQODBC3";
+#endif
+#ifdef TQT_STQL_OCI
+ if ( !l.tqcontains( "TQOCI8" ) )
+ l << "TQOCI8";
+#endif
+#ifdef TQT_STQL_TDS
+ if ( !l.tqcontains( "TQTDS7" ) )
+ l << "TQTDS7";
+#endif
+#ifdef TQT_STQL_DB2
+ if ( !l.tqcontains( "TQDB2" ) )
+ l << "TQDB2";
+#endif
+#ifdef TQT_STQL_STQLITE
+ if ( !l.tqcontains( "TQSQLITE" ) )
+ l << "TQSQLITE";
+#endif
+#ifdef TQT_STQL_IBASE
+ if ( !l.tqcontains( "TQIBASE" ) )
+ l << "TQIBASE";
+#endif
+
+ return l;
+}
+
+/*!
+ This function registers a new SQL driver called \a name, within
+ the SQL framework. This is useful if you have a custom SQL driver
+ and don't want to compile it as a plugin.
+
+ Example usage:
+
+ \code
+ TQSqlDatabase::registerSqlDriver( "MYDRIVER", new TQSqlDriverCreator<MyDatabaseDriver> );
+ TQSqlDatabase* db = TQSqlDatabase::addDatabase( "MYDRIVER" );
+ ...
+ \endcode
+
+ \warning The framework takes ownership of the \a creator pointer,
+ so it should not be deleted.
+*/
+void TQSqlDatabase::registerSqlDriver( const TQString& name, const TQSqlDriverCreatorBase* creator )
+{
+ TQSqlDatabaseManager::driverDict()->remove( name );
+ if ( creator )
+ TQSqlDatabaseManager::driverDict()->insert( name, creator );
+}
+
+/*!
+ Returns TRUE if the list of database connections tqcontains \a
+ connectionName; otherwise returns FALSE.
+*/
+
+bool TQSqlDatabase::tqcontains( const TQString& connectionName )
+{
+ return TQSqlDatabaseManager::tqcontains( connectionName );
+}
+
+
+/*!
+ Creates a TQSqlDatabase connection called \a name that uses the
+ driver referred to by \a type, with the tqparent \a tqparent and the
+ object name \a objname. If the \a type is not recognized, the
+ database connection will have no functionality.
+
+ The currently available drivers are:
+
+ \table
+ \header \i Driver Type \i Description
+ \row \i TQODBC3 \i ODBC Driver (includes Microsoft SQL Server)
+ \row \i TQOCI8 \i Oracle Call Interface Driver
+ \row \i TQPSQL7 \i PostgreSQL v6.x and v7.x Driver
+ \row \i TQTDS7 \i Sybase Adaptive Server
+ \row \i TQMYSQL3 \i MySQL Driver
+ \row \i TQDB2 \i IBM DB2, v7.1 and higher
+ \row \i TQSQLITE \i STQLite Driver
+ \row \i TQIBASE \i Borland Interbase Driver
+ \endtable
+
+ Additional third party drivers, including your own custom drivers,
+ can be loaded dynamically.
+
+ \sa registerSqlDriver()
+*/
+
+TQSqlDatabase::TQSqlDatabase( const TQString& type, const TQString& name, TQObject * tqparent, const char * objname )
+ : TQObject( tqparent, objname )
+{
+ init( type, name );
+}
+
+
+/*!
+ \overload
+
+ Creates a database connection using the driver \a driver, with
+ the tqparent \a tqparent and the object name \a objname.
+
+ \warning The framework takes ownership of the \a driver pointer,
+ so it should not be deleted.
+*/
+
+TQSqlDatabase::TQSqlDatabase( TQSqlDriver* driver, TQObject * tqparent, const char * objname )
+ : TQObject( tqparent, objname )
+{
+ d = new TQSqlDatabasePrivate();
+ d->driver = driver;
+}
+
+/*!
+ \internal
+
+ Create the actual driver instance \a type.
+*/
+
+void TQSqlDatabase::init( const TQString& type, const TQString& )
+{
+ d = new TQSqlDatabasePrivate();
+ d->drvName = type;
+
+ if ( !d->driver ) {
+
+#ifdef TQT_STQL_POSTGRES
+ if ( type == "TQPSQL7" )
+ d->driver = new TQPSTQLDriver();
+#endif
+
+#ifdef TQT_STQL_MYSQL
+ if ( type == "TQMYSQL3" )
+ d->driver = new TQMYSTQLDriver();
+#endif
+
+#ifdef TQT_STQL_ODBC
+ if ( type == "TQODBC3" )
+ d->driver = new TQODBCDriver();
+#endif
+
+#ifdef TQT_STQL_OCI
+ if ( type == "TQOCI8" )
+ d->driver = new TQOCIDriver();
+#endif
+
+#ifdef TQT_STQL_TDS
+ if ( type == "TQTDS7" )
+ d->driver = new TQTDSDriver();
+#endif
+
+#ifdef TQT_STQL_DB2
+ if ( type == "TQDB2" )
+ d->driver = new TQDB2Driver();
+#endif
+
+#ifdef TQT_STQL_STQLITE
+ if ( type == "TQSQLITE" )
+ d->driver = new TQSTQLiteDriver();
+#endif
+
+#ifdef TQT_STQL_IBASE
+ if ( type == "TQIBASE" )
+ d->driver = new TQIBaseDriver();
+#endif
+
+ }
+
+ if ( !d->driver ) {
+ TQDictIterator<TQSqlDriverCreatorBase> it( *TQSqlDatabaseManager::driverDict() );
+ while ( it.current() && !d->driver ) {
+ if ( type == it.currentKey() ) {
+ d->driver = it.current()->createObject();
+ }
+ ++it;
+ }
+ }
+
+#ifndef TQT_NO_COMPONENT
+ if ( !d->driver ) {
+ d->plugIns =
+ new TQPluginManager<TQSqlDriverFactoryInterface>( IID_TQSqlDriverFactory, TQApplication::libraryPaths(), "/sqldrivers" );
+
+ TQInterfacePtr<TQSqlDriverFactoryInterface> iface = 0;
+ d->plugIns->queryInterface( type, &iface );
+ if( iface )
+ d->driver = iface->create( type );
+ }
+#endif
+
+ if ( !d->driver ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQSqlDatabase: %s driver not loaded", type.latin1() );
+ qWarning( "TQSqlDatabase: available drivers: %s", drivers().join(" ").latin1() );
+#endif
+ d->driver = new TQNullDriver();
+ d->driver->setLastError( TQSqlError( "Driver not loaded", "Driver not loaded" ) );
+ }
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlDatabase::~TQSqlDatabase()
+{
+ delete d->driver;
+#ifndef TQT_NO_COMPONENT
+ delete d->plugIns;
+#endif
+ delete d;
+}
+
+/*!
+ Executes a SQL statement (e.g. an \c INSERT, \c UPDATE or \c
+ DELETE statement) on the database, and returns a TQSqlQuery object.
+ Use lastError() to retrieve error information. If \a query is
+ TQString::null, an empty, invalid query is returned and lastError()
+ is not affected.
+
+ \sa TQSqlQuery lastError()
+*/
+
+TQSqlQuery TQSqlDatabase::exec( const TQString & query ) const
+{
+ TQSqlQuery r = d->driver->createQuery();
+ if ( !query.isNull() ) {
+ r.exec( query );
+ d->driver->setLastError( r.lastError() );
+ }
+ return r;
+}
+
+/*!
+ Opens the database connection using the current connection values.
+ Returns TRUE on success; otherwise returns FALSE. Error
+ information can be retrieved using the lastError() function.
+
+ \sa lastError()
+*/
+
+bool TQSqlDatabase::open()
+{
+ return d->driver->open( d->dbname, d->uname, d->pword, d->hname,
+ d->port, d->connOptions );
+}
+
+/*!
+ \overload
+
+ Opens the database connection using the given \a user name and \a
+ password. Returns TRUE on success; otherwise returns FALSE. Error
+ information can be retrieved using the lastError() function.
+
+ This function does not store the password it is given. Instead,
+ the password is passed directly to the driver for opening a
+ connection and is then discarded.
+
+ \sa lastError()
+*/
+
+bool TQSqlDatabase::open( const TQString& user, const TQString& password )
+{
+ setUserName( user );
+ return d->driver->open( d->dbname, user, password, d->hname,
+ d->port, d->connOptions );
+}
+
+/*!
+ Closes the database connection, freeing any resources acquired.
+
+ \sa removeDatabase()
+*/
+
+void TQSqlDatabase::close()
+{
+ d->driver->close();
+}
+
+/*!
+ Returns TRUE if the database connection is currently open;
+ otherwise returns FALSE.
+*/
+
+bool TQSqlDatabase::isOpen() const
+{
+ return d->driver->isOpen();
+}
+
+/*!
+ Returns TRUE if there was an error opening the database
+ connection; otherwise returns FALSE. Error information can be
+ retrieved using the lastError() function.
+*/
+
+bool TQSqlDatabase::isOpenError() const
+{
+ return d->driver->isOpenError();
+}
+
+/*!
+ Begins a transaction on the database if the driver supports
+ transactions. Returns TRUE if the operation succeeded; otherwise
+ returns FALSE.
+
+ \sa TQSqlDriver::hasFeature() commit() rollback()
+*/
+
+bool TQSqlDatabase::transaction()
+{
+ if ( !d->driver->hasFeature( TQSqlDriver::Transactions ) )
+ return FALSE;
+ return d->driver->beginTransaction();
+}
+
+/*!
+ Commits a transaction to the database if the driver supports
+ transactions. Returns TRUE if the operation succeeded; otherwise
+ returns FALSE.
+
+ \sa TQSqlDriver::hasFeature() rollback()
+*/
+
+bool TQSqlDatabase::commit()
+{
+ if ( !d->driver->hasFeature( TQSqlDriver::Transactions ) )
+ return FALSE;
+ return d->driver->commitTransaction();
+}
+
+/*!
+ Rolls a transaction back on the database if the driver supports
+ transactions. Returns TRUE if the operation succeeded; otherwise
+ returns FALSE.
+
+ \sa TQSqlDriver::hasFeature() commit() transaction()
+*/
+
+bool TQSqlDatabase::rollback()
+{
+ if ( !d->driver->hasFeature( TQSqlDriver::Transactions ) )
+ return FALSE;
+ return d->driver->rollbackTransaction();
+}
+
+/*!
+ \property TQSqlDatabase::databaseName
+ \brief the name of the database
+
+ Note that the database name is the TNS Service Name for the TQOCI8
+ (Oracle) driver.
+
+ For the TQODBC3 driver it can either be a DSN, a DSN filename (the
+ file must have a \c .dsn extension), or a connection string. MS
+ Access users can for example use the following connection string
+ to open a \c .mdb file directly, instead of having to create a DSN
+ entry in the ODBC manager:
+
+ \code
+ ...
+ db = TQSqlDatabase::addDatabase( "TQODBC3" );
+ db->setDatabaseName( "DRIVER={Microsoft Access Driver (*.mdb)};FIL={MS Access};DBQ=myaccessfile.mdb" );
+ if ( db->open() ) {
+ // success!
+ }
+ ...
+ \endcode
+ ("FIL" is the required spelling in Microsoft's API.)
+
+ There is no default value.
+*/
+
+void TQSqlDatabase::setDatabaseName( const TQString& name )
+{
+ d->dbname = name;
+}
+
+/*!
+ \property TQSqlDatabase::userName
+ \brief the user name connected to the database
+
+ There is no default value.
+*/
+
+void TQSqlDatabase::setUserName( const TQString& name )
+{
+ d->uname = name;
+}
+
+/*!
+ \property TQSqlDatabase::password
+ \brief the password used to connect to the database
+
+ There is no default value.
+
+ \warning This function stores the password in plain text within
+ TQt. Use the open() call that takes a password as parameter to
+ avoid this behaviour.
+
+ \sa open()
+*/
+
+void TQSqlDatabase::setPassword( const TQString& password )
+{
+ d->pword = password;
+}
+
+/*!
+ \property TQSqlDatabase::hostName
+ \brief the host name where the database resides
+
+ There is no default value.
+*/
+
+void TQSqlDatabase::setHostName( const TQString& host )
+{
+ d->hname = host;
+}
+
+/*!
+ \property TQSqlDatabase::port
+ \brief the port used to connect to the database
+
+ There is no default value.
+*/
+
+void TQSqlDatabase::setPort( int p )
+{
+ d->port = p;
+}
+
+TQString TQSqlDatabase::databaseName() const
+{
+ return d->dbname;
+}
+
+TQString TQSqlDatabase::userName() const
+{
+ return d->uname;
+}
+
+TQString TQSqlDatabase::password() const
+{
+ return d->pword;
+}
+
+TQString TQSqlDatabase::hostName() const
+{
+ return d->hname;
+}
+
+/*!
+ Returns the name of the driver used by the database connection.
+*/
+TQString TQSqlDatabase::driverName() const
+{
+ return d->drvName;
+}
+
+int TQSqlDatabase::port() const
+{
+ return d->port;
+}
+
+/*!
+ Returns the database driver used to access the database
+ connection.
+*/
+
+TQSqlDriver* TQSqlDatabase::driver() const
+{
+ return d->driver;
+}
+
+/*!
+ Returns information about the last error that occurred on the
+ database. See TQSqlError for more information.
+*/
+
+TQSqlError TQSqlDatabase::lastError() const
+{
+ return d->driver->lastError();
+}
+
+
+/*!
+ \overload
+
+ Returns a list of the database's tables that are visible to the
+ user. To include views or system tables, use the version of this
+ function that takes a table \c type parameter.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myDatabase.tables();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+
+TQStringList TQSqlDatabase::tables() const
+{
+ return tables( TQSql::Tables );
+}
+
+/*!
+ Returns a list of the database's tables, system tables and views,
+ as specified by the parameter \a type.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myDatabase.tables( TQSql::Tables | TQSql::Views );
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+
+TQStringList TQSqlDatabase::tables( TQSql::TableType type ) const
+{
+ return d->driver->tables( TQString::number( (int)type ) );
+}
+
+/*!
+ Returns the primary index for table \a tablename. If no primary
+ index exists an empty TQSqlIndex will be returned.
+*/
+
+TQSqlIndex TQSqlDatabase::primaryIndex( const TQString& tablename ) const
+{
+ return d->driver->primaryIndex( tablename );
+}
+
+
+/*!
+ Returns a TQSqlRecord populated with the names of all the fields in
+ the table (or view) called \a tablename. The order in which the
+ fields appear in the record is undefined. If no such table (or
+ view) exists, an empty record is returned.
+
+ \sa recordInfo()
+*/
+
+TQSqlRecord TQSqlDatabase::record( const TQString& tablename ) const
+{
+ return d->driver->record( tablename );
+}
+
+
+/*!
+ \overload
+
+ Returns a TQSqlRecord populated with the names of all the fields
+ used in the SQL \a query. If the query is a "SELECT *" the order
+ in which fields appear in the record is undefined.
+
+ \sa recordInfo()
+*/
+
+TQSqlRecord TQSqlDatabase::record( const TQSqlQuery& query ) const
+{
+ return d->driver->record( query );
+}
+
+/*!
+ Returns a TQSqlRecordInfo populated with meta data about the table
+ or view \a tablename. If no such table (or view) exists, an empty
+ record is returned.
+
+ \sa TQSqlRecordInfo, TQSqlFieldInfo, record()
+*/
+TQSqlRecordInfo TQSqlDatabase::recordInfo( const TQString& tablename ) const
+{
+ return d->driver->recordInfo( tablename );
+}
+
+/*!
+ \overload
+
+ Returns a TQSqlRecordInfo object with meta data for the TQSqlQuery
+ \a query. Note that this overloaded function may return less
+ information than the recordInfo() function which takes the name of
+ a table as parameter.
+
+ \sa TQSqlRecordInfo, TQSqlFieldInfo, record()
+*/
+TQSqlRecordInfo TQSqlDatabase::recordInfo( const TQSqlQuery& query ) const
+{
+ return d->driver->recordInfo( query );
+}
+
+/*!
+ \property TQSqlDatabase::connectOptions
+ \brief the database connect options
+
+ The format of the options string is a semi-colon separated list of
+ option names or option = value pairs. The options depend on the
+ database client used:
+
+ \table
+ \header \i ODBC \i MySQL \i PostgreSQL
+ \row
+
+ \i
+ \list
+ \i STQL_ATTR_ACCESS_MODE
+ \i STQL_ATTR_LOGIN_TIMEOUT
+ \i STQL_ATTR_CONNECTION_TIMEOUT
+ \i STQL_ATTR_CURRENT_CATALOG
+ \i STQL_ATTR_METADATA_ID
+ \i STQL_ATTR_PACKET_SIZE
+ \i STQL_ATTR_TRACEFILE
+ \i STQL_ATTR_TRACE
+ \endlist
+
+ \i
+ \list
+ \i CLIENT_COMPRESS
+ \i CLIENT_FOUND_ROWS
+ \i CLIENT_IGNORE_SPACE
+ \i CLIENT_SSL
+ \i CLIENT_ODBC
+ \i CLIENT_NO_SCHEMA
+ \i CLIENT_INTERACTIVE
+ \endlist
+
+ \i
+ \list
+ \i connect_timeout
+ \i options
+ \i tty
+ \i requiressl
+ \i service
+ \endlist
+
+ \header \i DB2 \i OCI \i TDS
+ \row
+
+ \i
+ \list
+ \i STQL_ATTR_ACCESS_MODE
+ \i STQL_ATTR_LOGIN_TIMEOUT
+ \endlist
+
+ \i
+ \e none
+
+ \i
+ \e none
+
+ \endtable
+
+ Example of usage:
+ \code
+ ...
+ // MySQL connection
+ db->setConnectOptions( "CLIENT_SSL;CLIENT_IGNORE_SPACE" ); // use an SSL connection to the server
+ if ( !db->open() ) {
+ db->setConnectOptions(); // clears the connect option string
+ ...
+ }
+ ...
+ // PostgreSQL connection
+ db->setConnectOptions( "requiressl=1" ); // enable PostgreSQL SSL connections
+ if ( !db->open() ) {
+ db->setConnectOptions(); // clear options
+ ...
+ }
+ ...
+ // ODBC connection
+ db->setConnectOptions( "STQL_ATTR_ACCESS_MODE=STQL_MODE_READ_ONLY;STQL_ATTR_TRACE=STQL_OPT_TRACE_ON" ); // set ODBC options
+ if ( !db->open() ) {
+ db->setConnectOptions(); // don't try to set this option
+ ...
+ }
+ \endcode
+
+ Please refer to the client library documentation for more
+ information about the different options. The options will be set
+ prior to opening the database connection. Setting new options
+ without re-opening the connection does nothing.
+
+ \sa connectOptions()
+*/
+
+void TQSqlDatabase::setConnectOptions( const TQString& options )
+{
+ d->connOptions = options;
+}
+
+TQString TQSqlDatabase::connectOptions() const
+{
+ return d->connOptions;
+}
+
+/*!
+ Returns TRUE if a driver called \a name is available; otherwise
+ returns FALSE.
+
+ \sa drivers()
+*/
+
+bool TQSqlDatabase::isDriverAvailable( const TQString& name )
+{
+ TQStringList l = drivers();
+ TQStringList::ConstIterator it = l.begin();
+ for ( ;it != l.end(); ++it ) {
+ if ( *it == name )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*! \overload
+
+ This function is useful if you need to set up the database
+ connection and instantiate the driver yourself. If you do this, it
+ is recommended that you include the driver code in your own
+ application. For example, setting up a custom PostgreSQL
+ connection and instantiating the TQPSQL7 driver can be done the
+ following way:
+
+ \code
+ #include "tqtdir/src/sql/drivers/psql/qsql_psql.cpp"
+ \endcode
+ (We assume that \c qtdir is the directory where TQt is installed.)
+ This will pull in the code that is needed to use the PostgreSQL
+ client library and to instantiate a TQPSTQLDriver object, assuming
+ that you have the PostgreSQL headers somewhere in your include
+ search path.
+
+ \code
+ PGconn* con = PQconnectdb( "host=server user=bart password=simpson dbname=springfield" );
+ TQPSTQLDriver* drv = new TQPSTQLDriver( con );
+ TQSqlDatabase* db = TQSqlDatabase::addDatabase( drv ); // becomes the new default connection
+ TQSqlQuery q;
+ q.exec( "SELECT * FROM people" );
+ ...
+ \endcode
+
+ The above code sets up a PostgreSQL connection and instantiates a
+ TQPSTQLDriver object. Next, addDatabase() is called to add the
+ connection to the known connections so that it can be used by the
+ TQt SQL classes. When a driver is instantiated with a connection
+ handle (or set of handles), TQt assumes that you have already
+ opened the database connection.
+
+ Remember that you must link your application against the database
+ client library as well. The simplest way to do this is to add
+ lines like those below to your \c .pro file:
+
+ \code
+ unix:LIBS += -lpq
+ win32:LIBS += libpqdll.lib
+ \endcode
+
+ You will need to have the client library in your linker's search
+ path.
+
+ The method described above will work for all the drivers, the only
+ difference is the arguments the driver constructors take. Below is
+ an overview of the drivers and their constructor arguments.
+
+ \table
+ \header \i Driver \i Class name \i Constructor arguments \i File to include
+ \row
+ \i TQPSQL7
+ \i TQPSTQLDriver
+ \i PGconn* connection
+ \i \c qsql_psql.cpp
+ \row
+ \i TQMYSQL3
+ \i TQMYSTQLDriver
+ \i MYSQL* connection
+ \i \c qsql_mysql.cpp
+ \row
+ \i TQOCI8
+ \i TQOCIDriver
+ \i OCIEnv* environment, OCIError* error, OCISvcCtx* serviceContext
+ \i \c qsql_oci.cpp
+ \row
+ \i TQODBC3
+ \i TQODBCDriver
+ \i STQLHANDLE environment, STQLHANDLE connection
+ \i \c qsql_odbc.cpp
+ \row
+ \i TQDB2
+ \i TQDB2
+ \i STQLHANDLE environment, STQLHANDLE connection
+ \i \c qsql_db2.cpp
+ \row
+ \i TQTDS7
+ \i TQTDSDriver
+ \i LOGINREC* loginRecord, DBPROCESS* dbProcess, const TQString& hostName
+ \i \c qsql_tds.cpp
+ \row
+ \i TQSQLITE
+ \i TQSTQLiteDriver
+ \i sqlite* connection
+ \i \c qsql_sqlite.cpp
+ \row
+ \i TQIBASE
+ \i TQIBaseDriver
+ \i isc_db_handle connection
+ \i \c qsql_ibase.cpp
+ \endtable
+
+ Note: The host name (or service name) is needed when constructing
+ the TQTDSDriver for creating new connections for internal
+ queries. This is to prevent the simultaneous usage of several
+ TQSqlQuery/\l{TQSqlCursor} objects from blocking each other.
+
+ \warning The SQL framework takes ownership of the \a driver pointer,
+ and it should not be deleted. The returned TQSqlDatabase object is
+ owned by the framework and must not be deleted. If you want to
+ explicitly remove the connection, use removeDatabase()
+
+ \sa drivers()
+*/
+
+TQSqlDatabase* TQSqlDatabase::addDatabase( TQSqlDriver* driver, const TQString& connectionName )
+{
+ return TQSqlDatabaseManager::addDatabase( new TQSqlDatabase( driver ), connectionName );
+}
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/tqsqldatabase.h b/tqtinterface/qt4/src/sql/tqsqldatabase.h
new file mode 100644
index 0000000..730fb44
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqldatabase.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Definition of TQSqlDatabase class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLDATABASE_H
+#define TQSQLDATABASE_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqstring.h"
+#include "tqsqlquery.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQSqlError;
+class TQSqlDriver;
+class TQSqlIndex;
+class TQSqlRecord;
+class TQSqlRecordInfo;
+class TQSqlDatabasePrivate;
+
+class TQM_EXPORT_SQL TQSqlDriverCreatorBase
+{
+public:
+ virtual TQSqlDriver* createObject() = 0;
+};
+
+template <class type>
+class TQM_EXPORT_SQL TQSqlDriverCreator: public TQSqlDriverCreatorBase
+{
+public:
+ TQSqlDriver* createObject() { return new type; }
+};
+
+class TQM_EXPORT_SQL TQSqlDatabase : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( TQString databaseName READ databaseName WRITE setDatabaseName )
+ Q_PROPERTY( TQString userName READ userName WRITE setUserName )
+ Q_PROPERTY( TQString password READ password WRITE setPassword )
+ Q_PROPERTY( TQString hostName READ hostName WRITE setHostName )
+ Q_PROPERTY( int port READ port WRITE setPort )
+ Q_PROPERTY( TQString connectOptions READ connectOptions WRITE setConnectOptions )
+
+public:
+ ~TQSqlDatabase();
+
+ bool open();
+ bool open( const TQString& user, const TQString& password );
+ void close();
+ bool isOpen() const;
+ bool isOpenError() const;
+ TQStringList tables() const;
+ TQStringList tables( TQSql::TableType type ) const;
+ TQSqlIndex primaryIndex( const TQString& tablename ) const;
+ TQSqlRecord record( const TQString& tablename ) const;
+ TQSqlRecord record( const TQSqlQuery& query ) const;
+ TQSqlRecordInfo recordInfo( const TQString& tablename ) const;
+ TQSqlRecordInfo recordInfo( const TQSqlQuery& query ) const;
+ TQSqlQuery exec( const TQString& query = TQString::null ) const;
+ TQSqlError lastError() const;
+
+ bool transaction();
+ bool commit();
+ bool rollback();
+
+ virtual void setDatabaseName( const TQString& name );
+ virtual void setUserName( const TQString& name );
+ virtual void setPassword( const TQString& password );
+ virtual void setHostName( const TQString& host );
+ virtual void setPort( int p );
+ void setConnectOptions( const TQString& options = TQString::null );
+ TQString databaseName() const;
+ TQString userName() const;
+ TQString password() const;
+ TQString hostName() const;
+ TQString driverName() const;
+ int port() const;
+ TQString connectOptions() const;
+
+ TQSqlDriver* driver() const;
+
+ // TQMOC_SKIP_BEGIN
+ TQT_STATIC_CONST char * const defaultConnection;
+ // TQMOC_SKIP_END
+
+ static TQSqlDatabase* addDatabase( const TQString& type, const TQString& connectionName = defaultConnection );
+ static TQSqlDatabase* addDatabase( TQSqlDriver* driver, const TQString& connectionName = defaultConnection );
+ static TQSqlDatabase* database( const TQString& connectionName = defaultConnection, bool open = TRUE );
+ static void removeDatabase( const TQString& connectionName );
+ static void removeDatabase( TQSqlDatabase* db );
+ static bool tqcontains( const TQString& connectionName = defaultConnection );
+ static TQStringList drivers();
+ static void registerSqlDriver( const TQString& name, const TQSqlDriverCreatorBase* creator ); // ### 4.0: creator should not be const
+ static bool isDriverAvailable( const TQString& name );
+
+protected:
+ TQSqlDatabase( const TQString& type, const TQString& name, TQObject * tqparent=0, const char * objname=0 );
+ TQSqlDatabase( TQSqlDriver* driver, TQObject * tqparent=0, const char * objname=0 );
+private:
+ void init( const TQString& type, const TQString& name );
+ TQSqlDatabasePrivate* d;
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQSqlDatabase( const TQSqlDatabase & );
+ TQSqlDatabase &operator=( const TQSqlDatabase & );
+#endif
+
+};
+
+#endif // TQT_NO_SQL
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqldriver.cpp b/tqtinterface/qt4/src/sql/tqsqldriver.cpp
new file mode 100644
index 0000000..3f8cdca
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqldriver.cpp
@@ -0,0 +1,509 @@
+/****************************************************************************
+**
+** Implementation of TQSqlDriver class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqldriver.h"
+
+#ifndef TQT_NO_SQL
+
+#include "tqdatetime.h"
+#include "tqsqlextension_p.h"
+
+// database states
+#define DBState_Open 0x0001
+#define DBState_OpenError 0x0002
+
+// ### This needs to go in 4.0!
+TQPtrDict<TQSqlDriverExtension> *qSqlDriverExtDict();
+TQPtrDict<TQSqlOpenExtension> *qSqlOpenExtDict();
+
+/*!
+ \class TQSqlDriver tqsqldriver.h
+ \brief The TQSqlDriver class is an abstract base class for accessing
+ SQL databases.
+
+ \ingroup database
+ \module sql
+
+ This class should not be used directly. Use TQSqlDatabase instead.
+*/
+
+/*!
+ Default constructor. Creates a new driver with tqparent \a tqparent,
+ called \a name.
+
+*/
+
+TQSqlDriver::TQSqlDriver( TQObject * tqparent, const char * name )
+: TQObject(tqparent, name),
+ dbState(0),
+ error()
+{
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlDriver::~TQSqlDriver()
+{
+}
+
+/*!
+ \fn bool TQSqlDriver::open( const TQString& db, const TQString& user,
+ const TQString& password, const TQString& host, int port )
+
+ Derived classes must reimplement this abstract virtual function in
+ order to open a database connection on database \a db, using user
+ name \a user, password \a password, host \a host and port \a port.
+
+ The function \e must return TRUE on success and FALSE on failure.
+
+ \sa setOpen()
+
+*/
+
+/*!
+ \fn bool TQSqlDriver::close()
+
+ Derived classes must reimplement this abstract virtual function in
+ order to close the database connection. Return TRUE on success,
+ FALSE on failure.
+
+ \sa setOpen()
+
+*/
+
+/*!
+ \fn TQSqlQuery TQSqlDriver::createQuery() const
+
+ Creates an empty SQL result on the database. Derived classes must
+ reimplement this function and return a TQSqlQuery object
+ appropriate for their database to the caller.
+
+*/
+
+//void TQSqlDriver::destroyResult( TQSqlResult* r ) const
+//{
+// if ( r )
+// delete r;
+//}
+
+/*!
+ Returns TRUE if the database connection is open; otherwise returns
+ FALSE.
+*/
+
+bool TQSqlDriver::isOpen() const
+{
+ if ( !qSqlDriverExtDict()->isEmpty() ) {
+ TQSqlDriverExtension *ext = qSqlDriverExtDict()->tqfind( (TQSqlDriver *) this );
+ if ( ext )
+ return ext->isOpen();
+ }
+
+ return ((dbState & DBState_Open) == DBState_Open);
+}
+
+/*!
+ Returns TRUE if the there was an error opening the database
+ connection; otherwise returns FALSE.
+*/
+
+bool TQSqlDriver::isOpenError() const
+{
+ return ((dbState & DBState_OpenError) == DBState_OpenError);
+}
+
+/*!
+ \enum TQSqlDriver::DriverFeature
+
+ This enum tqcontains a list of features a driver may support. Use
+ hasFeature() to query whether a feature is supported or not.
+
+ \value Transactions whether the driver supports SQL transactions
+ \value QuerySize whether the database is capable of reporting the size
+ of a query. Note that some databases do not support returning the size
+ (i.e. number of rows returned) of a query, in which case
+ TQSqlQuery::size() will return -1
+ \value BLOB whether the driver supports Binary Large Object fields
+ \value Unicode whether the driver supports Unicode strings if the
+ database server does
+ \value PreparedQueries whether the driver supports prepared query execution
+ \value NamedPlaceholders whether the driver supports usage of named placeholders
+ \value PositionalPlaceholders whether the driver supports usage of positional placeholders
+
+ More information about supported features can be found in the
+ \link sql-driver.html TQt SQL driver\endlink documentation.
+
+ \sa hasFeature()
+*/
+
+/*!
+ \fn bool TQSqlDriver::hasFeature( DriverFeature f ) const
+
+ Returns TRUE if the driver supports feature \a f; otherwise
+ returns FALSE.
+
+ Note that some databases need to be open() before this can be
+ determined.
+
+ \sa DriverFeature
+*/
+
+/*!
+ Protected function which sets the open state of the database to \a
+ o. Derived classes can use this function to report the status of
+ open().
+
+ \sa open(), setOpenError()
+*/
+
+void TQSqlDriver::setOpen( bool o )
+{
+ if ( o )
+ dbState |= DBState_Open;
+ else
+ dbState &= ~DBState_Open;
+}
+
+/*!
+ Protected function which sets the open error state of the database
+ to \a e. Derived classes can use this function to report the
+ status of open(). Note that if \a e is TRUE the open state of the
+ database is set to closed (i.e. isOpen() returns FALSE).
+
+ \sa open(), setOpenError()
+*/
+
+void TQSqlDriver::setOpenError( bool e )
+{
+ if ( e ) {
+ dbState |= DBState_OpenError;
+ dbState &= ~DBState_Open;
+ }
+ else
+ dbState &= ~DBState_OpenError;
+}
+
+/*!
+ Protected function which derived classes can reimplement to begin
+ a transaction. If successful, return TRUE, otherwise return FALSE.
+ The default implementation returns FALSE.
+
+ \sa commitTransaction(), rollbackTransaction()
+*/
+
+bool TQSqlDriver::beginTransaction()
+{
+ return FALSE;
+}
+
+/*!
+ Protected function which derived classes can reimplement to commit
+ a transaction. If successful, return TRUE, otherwise return FALSE.
+ The default implementation returns FALSE.
+
+ \sa beginTransaction(), rollbackTransaction()
+*/
+
+bool TQSqlDriver::commitTransaction()
+{
+ return FALSE;
+}
+
+/*!
+ Protected function which derived classes can reimplement to
+ rollback a transaction. If successful, return TRUE, otherwise
+ return FALSE. The default implementation returns FALSE.
+
+ \sa beginTransaction(), commitTransaction()
+*/
+
+bool TQSqlDriver::rollbackTransaction()
+{
+ return FALSE;
+}
+
+/*!
+ Protected function which allows derived classes to set the value
+ of the last error, \a e, that occurred on the database.
+
+ \sa lastError()
+*/
+
+void TQSqlDriver::setLastError( const TQSqlError& e )
+{
+ error = e;
+}
+
+/*!
+ Returns a TQSqlError object which tqcontains information about the
+ last error that occurred on the database.
+*/
+
+TQSqlError TQSqlDriver::lastError() const
+{
+ return error;
+}
+
+/*!
+ Returns a list of tables in the database. The default
+ implementation returns an empty list.
+
+ The \a tableType argument describes what types of tables
+ should be returned. Due to binary compatibility, the string
+ tqcontains the value of the enum TQSql::TableTypes as text.
+ An empty string should be treated as TQSql::Tables for
+ downward compatibility.
+
+ \sa TQSql::TableType
+*/
+
+TQStringList TQSqlDriver::tables( const TQString& ) const
+{
+ return TQStringList();
+}
+
+/*!
+ Returns the primary index for table \a tableName. Returns an empty
+ TQSqlIndex if the table doesn't have a primary index. The default
+ implementation returns an empty index.
+*/
+
+TQSqlIndex TQSqlDriver::primaryIndex( const TQString& ) const
+{
+ return TQSqlIndex();
+}
+
+
+/*!
+ Returns a TQSqlRecord populated with the names of the fields in
+ table \a tableName. If no such table exists, an empty record is
+ returned. The default implementation returns an empty record.
+*/
+
+TQSqlRecord TQSqlDriver::record( const TQString& ) const
+{
+ return TQSqlRecord();
+}
+
+/*!
+ \overload
+
+ Returns a TQSqlRecord populated with the names of the fields in the
+ SQL \a query. The default implementation returns an empty record.
+*/
+
+TQSqlRecord TQSqlDriver::record( const TQSqlQuery& ) const
+{
+ return TQSqlRecord();
+}
+
+/*!
+ Returns a TQSqlRecordInfo object with meta data about the table \a
+ tablename.
+*/
+TQSqlRecordInfo TQSqlDriver::recordInfo( const TQString& tablename ) const
+{
+ return TQSqlRecordInfo( record( tablename ) );
+}
+
+/*!
+ \overload
+
+ Returns a TQSqlRecordInfo object with meta data for the TQSqlQuery
+ \a query. Note that this overloaded function may return less
+ information than the recordInfo() function which takes the name of
+ a table as parameter.
+*/
+TQSqlRecordInfo TQSqlDriver::recordInfo( const TQSqlQuery& query ) const
+{
+ return TQSqlRecordInfo( record( query ) );
+}
+
+
+/*!
+ Returns a string representation of the NULL value for the
+ database. This is used, for example, when constructing INSERT and
+ UPDATE statements. The default implementation returns the string
+ "NULL".
+*/
+
+TQString TQSqlDriver::nullText() const
+{
+ return "NULL";
+}
+
+/*!
+ Returns a string representation of the \a field value for the
+ database. This is used, for example, when constructing INSERT and
+ UPDATE statements.
+
+ The default implementation returns the value formatted as a string
+ according to the following rules:
+
+ \list
+
+ \i If \a field is NULL, nullText() is returned.
+
+ \i If \a field is character data, the value is returned enclosed
+ in single quotation marks, which is appropriate for many SQL
+ databases. Any embedded single-quote characters are escaped
+ (tqreplaced with two single-quote characters). If \a trimStrings is
+ TRUE (the default is FALSE), all trailing whitespace is trimmed
+ from the field.
+
+ \i If \a field is date/time data, the value is formatted in ISO
+ format and enclosed in single quotation marks. If the date/time
+ data is invalid, nullText() is returned.
+
+ \i If \a field is bytearray data, and the driver can edit binary
+ fields, the value is formatted as a hexadecimal string.
+
+ \i For any other field type toString() will be called on its value
+ and the result returned.
+
+ \endlist
+
+ \sa TQVariant::toString().
+
+*/
+TQString TQSqlDriver::formatValue( const TQSqlField* field, bool trimStrings ) const
+{
+ TQString r;
+ if ( field->isNull() )
+ r = nullText();
+ else {
+ switch ( field->type() ) {
+ case TQVariant::Int:
+ case TQVariant::UInt:
+ if ( field->value().type() == TQVariant::Bool )
+ r = field->value().toBool() ? "1" : "0";
+ else
+ r = field->value().toString();
+ break;
+ case TQVariant::Date:
+ if ( field->value().toDate().isValid() )
+ r = "'" + field->value().toDate().toString( Qt::ISODate ) + "'";
+ else
+ r = nullText();
+ break;
+ case TQVariant::Time:
+ if ( field->value().toTime().isValid() )
+ r = "'" + field->value().toTime().toString( Qt::ISODate ) + "'";
+ else
+ r = nullText();
+ break;
+ case TQVariant::DateTime:
+ if ( field->value().toDateTime().isValid() )
+ r = "'" +
+ field->value().toDateTime().toString( Qt::ISODate ) + "'";
+ else
+ r = nullText();
+ break;
+ case TQVariant::String:
+ case TQVariant::CString: {
+ TQString result = field->value().toString();
+ if ( trimStrings ) {
+ int end = result.length() - 1;
+ while ( end && result[end].isSpace() ) /* skip white space from end */
+ end--;
+ result.truncate( end );
+ }
+ /* escape the "'" character */
+ result.tqreplace( TQChar( '\'' ), "''" );
+ r = "'" + result + "'";
+ break;
+ }
+ case TQVariant::Bool:
+ if ( field->value().toBool() )
+ r = "1";
+ else
+ r = "0";
+ break;
+ case TQVariant::ByteArray : {
+ if ( hasFeature( BLOB ) ) {
+ TQByteArray ba = TQT_TQBYTEARRAY_OBJECT(field->value().toByteArray());
+ TQString res;
+ static const char hexchars[] = "0123456789abcdef";
+ for ( uint i = 0; i < ba.size(); ++i ) {
+ uchar s = (uchar) ba[(int)i];
+ res += hexchars[s >> 4];
+ res += hexchars[s & 0x0f];
+ }
+ r = "'" + res + "'";
+ break;
+ }
+ }
+ default:
+ r = field->value().toString();
+ break;
+ }
+ }
+ return r;
+}
+
+/*!
+ \overload
+
+ Open a database connection on database \a db, using user name \a
+ user, password \a password, host \a host, port \a port and
+ connection options \a connOpts.
+
+ Returns TRUE on success and FALSE on failure.
+
+ \sa setOpen()
+*/
+bool TQSqlDriver::open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts )
+{
+ if ( !qSqlOpenExtDict()->isEmpty() ) {
+ TQSqlOpenExtension *ext = qSqlOpenExtDict()->tqfind( (TQSqlDriver *) this );
+ if ( ext )
+ return ext->open( db, user, password, host, port, connOpts );
+ }
+ return open( db, user, password, host, port );
+}
+
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/tqsqldriver.h b/tqtinterface/qt4/src/sql/tqsqldriver.h
new file mode 100644
index 0000000..84e936c
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqldriver.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Definition of TQSqlDriver class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLDRIVER_H
+#define TQSQLDRIVER_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqptrdict.h"
+#include "tqstring.h"
+#include "tqsqlerror.h"
+#include "tqsqlquery.h"
+#include "tqsqlfield.h"
+#include "tqsqlindex.h"
+#include "tqstringlist.h"
+#include "tqmap.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQSqlDriverExtension;
+
+class TQSqlDatabase;
+
+class TQM_EXPORT_SQL TQSqlDriver : public TQObject
+{
+ friend class TQSqlDatabase;
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ enum DriverFeature { Transactions, QuerySize, BLOB, Unicode, PreparedQueries,
+ NamedPlaceholders, PositionalPlaceholders };
+
+ TQSqlDriver( TQObject * tqparent=0, const char * name=0 );
+ ~TQSqlDriver();
+ bool isOpen() const;
+ bool isOpenError() const;
+
+ virtual bool beginTransaction();
+ virtual bool commitTransaction();
+ virtual bool rollbackTransaction();
+ virtual TQStringList tables( const TQString& tableType ) const;
+ virtual TQSqlIndex primaryIndex( const TQString& tableName ) const;
+ virtual TQSqlRecord record( const TQString& tableName ) const;
+ virtual TQSqlRecord record( const TQSqlQuery& query ) const;
+ virtual TQSqlRecordInfo recordInfo( const TQString& tablename ) const;
+ virtual TQSqlRecordInfo recordInfo( const TQSqlQuery& query ) const;
+ virtual TQString nullText() const;
+ virtual TQString formatValue( const TQSqlField* field, bool trimStrings = FALSE ) const;
+ TQSqlError lastError() const;
+
+ virtual bool hasFeature( DriverFeature f ) const = 0;
+ virtual bool open( const TQString & db,
+ const TQString & user = TQString::null,
+ const TQString & password = TQString::null,
+ const TQString & host = TQString::null,
+ int port = -1 ) = 0;
+ virtual void close() = 0;
+ virtual TQSqlQuery createQuery() const = 0;
+
+ // ### remove for 4.0
+ bool open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts );
+protected:
+ virtual void setOpen( bool o );
+ virtual void setOpenError( bool e );
+ virtual void setLastError( const TQSqlError& e );
+private:
+ // ### This class needs a d-pointer in 4.0.
+ int dbState;
+ TQSqlError error;
+#if defined(TQ_DISABLE_COPY)
+ TQSqlDriver( const TQSqlDriver & );
+ TQSqlDriver &operator=( const TQSqlDriver & );
+#endif
+};
+
+#endif // TQT_NO_SQL
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqldriverinterface_p.h b/tqtinterface/qt4/src/sql/tqsqldriverinterface_p.h
new file mode 100644
index 0000000..661a9b1
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqldriverinterface_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Definition of TQSqlDriverInterface class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLDRIVERINTERFACE_H
+#define TQSQLDRIVERINTERFACE_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include <private/tqcom_p.h>
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+#ifndef TQT_NO_COMPONENT
+
+// {EDDD5AD5-DF3C-400c-A711-163B72FE5F61}
+#ifndef IID_TQSqlDriverFactory
+#define IID_TQSqlDriverFactory TQUuid(0xeddd5ad5, 0xdf3c, 0x400c, 0xa7, 0x11, 0x16, 0x3b, 0x72, 0xfe, 0x5f, 0x61)
+#endif
+
+class TQSqlDriver;
+
+struct TQM_EXPORT_SQL TQSqlDriverFactoryInterface : public TQFeatureListInterface
+{
+ virtual TQSqlDriver* create( const TQString& name ) = 0;
+};
+
+#endif //TQT_NO_COMPONENT
+#endif // TQT_NO_SQL
+
+#endif // TQSQLDRIVERINTERFACE_P_H
diff --git a/tqtinterface/qt4/src/sql/tqsqldriverplugin.cpp b/tqtinterface/qt4/src/sql/tqsqldriverplugin.cpp
new file mode 100644
index 0000000..c97dec5
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqldriverplugin.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Implementation of TQSqlDriverPlugin class
+**
+** Created : 2001-09-20
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqldriverplugin.h"
+
+#ifndef TQT_NO_SQL
+#ifndef TQT_NO_COMPONENT
+
+#include "tqsqldriverinterface_p.h"
+
+/*!
+ \class TQSqlDriverPlugin tqsqldriverplugin.h
+ \brief The TQSqlDriverPlugin class provides an abstract base for custom TQSqlDriver plugins.
+
+ \ingroup plugins
+ \mainclass
+
+ The SQL driver plugin is a simple plugin interface that makes it
+ easy to create your own SQL driver plugins that can be loaded
+ dynamically by TQt.
+
+ Writing a SQL plugin is achieved by subclassing this base class,
+ reimplementing the pure virtual functions keys() and create(), and
+ exporting the class with the \c TQ_EXPORT_PLUGIN macro. See the SQL
+ plugins that come with TQt for example implementations (in the
+ \c{plugins/src/sqldrivers} subdirectory of the source
+ distribution). Read the \link plugins-howto.html plugins
+ documentation\endlink for more information on plugins.
+*/
+
+/*!
+ \fn TQStringList TQSqlDriverPlugin::keys() const
+
+ Returns the list of drivers (keys) this plugin supports.
+
+ These keys are usually the class names of the custom drivers that
+ are implemented in the plugin.
+
+ \sa create()
+*/
+
+/*!
+ \fn TQSqlDriver* TQSqlDriverPlugin::create( const TQString& key )
+
+ Creates and returns a TQSqlDriver object for the driver key \a key.
+ The driver key is usually the class name of the required driver.
+
+ \sa keys()
+*/
+
+class TQSqlDriverPluginPrivate : public TQSqlDriverFactoryInterface
+{
+public:
+ TQSqlDriverPluginPrivate( TQSqlDriverPlugin *p )
+ : plugin( p )
+ {
+ }
+ virtual ~TQSqlDriverPluginPrivate();
+
+ TQRESULT queryInterface( const TQUuid &iid, TQUnknownInterface **iface );
+ TQ_REFCOUNT;
+
+ TQStringList featureList() const;
+ TQSqlDriver *create( const TQString &key );
+
+private:
+ TQSqlDriverPlugin *plugin;
+};
+
+TQSqlDriverPluginPrivate::~TQSqlDriverPluginPrivate()
+{
+ delete plugin;
+}
+
+TQRESULT TQSqlDriverPluginPrivate::queryInterface( const TQUuid &iid, TQUnknownInterface **iface )
+{
+ *iface = 0;
+
+ if ( iid == IID_TQUnknown )
+ *iface = this;
+ else if ( iid == IID_TQFeatureList )
+ *iface = this;
+ else if ( iid == IID_TQSqlDriverFactory )
+ *iface = this;
+ else
+ return TQE_NOINTERFACE;
+
+ (*iface)->addRef();
+ return TQS_OK;
+}
+
+TQStringList TQSqlDriverPluginPrivate::featureList() const
+{
+ return plugin->keys();
+}
+
+TQSqlDriver *TQSqlDriverPluginPrivate::create( const TQString &key )
+{
+ return plugin->create( key );
+}
+
+/*!
+ Constructs a SQL driver plugin. This is invoked automatically by
+ the \c TQ_EXPORT_PLUGIN macro.
+*/
+
+TQSqlDriverPlugin::TQSqlDriverPlugin()
+ : TQGPlugin( d = new TQSqlDriverPluginPrivate( this ) )
+{
+}
+
+/*!
+ Destroys the SQL driver plugin.
+
+ You never have to call this explicitly. TQt destroys a plugin
+ automatically when it is no longer used.
+*/
+TQSqlDriverPlugin::~TQSqlDriverPlugin()
+{
+ // don't delete d, as this is deleted by d
+}
+
+#endif // TQT_NO_COMPONENT
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/tqsqldriverplugin.h b/tqtinterface/qt4/src/sql/tqsqldriverplugin.h
new file mode 100644
index 0000000..4311083
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqldriverplugin.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Definition of TQSqlDriverPlugin class
+**
+** Created : 2001-09-20
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLDRIVERPLUGIN_H
+#define TQSQLDRIVERPLUGIN_H
+
+#ifndef TQT_H
+#include "tqgplugin.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SQL
+#ifndef TQT_NO_COMPONENT
+
+class TQSqlDriver;
+class TQSqlDriverPluginPrivate;
+
+class TQ_EXPORT TQSqlDriverPlugin : public TQGPlugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQSqlDriverPlugin();
+ ~TQSqlDriverPlugin();
+
+ virtual TQStringList keys() const = 0;
+ virtual TQSqlDriver *create( const TQString &key ) = 0;
+
+private:
+ TQSqlDriverPluginPrivate *d;
+};
+
+#endif // TQT_NO_COMPONENT
+#endif // TQT_NO_SQL
+
+#endif // TQSQLDRIVERPLUGIN_H
diff --git a/tqtinterface/qt4/src/sql/tqsqleditorfactory.cpp b/tqtinterface/qt4/src/sql/tqsqleditorfactory.cpp
new file mode 100644
index 0000000..0c6b16f
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqleditorfactory.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Implementation of TQSqlEditorFactory class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqleditorfactory.h"
+
+#ifndef TQT_NO_STQL_EDIT_WIDGETS
+
+#include "tqsqlfield.h"
+#include "tqcleanuphandler.h"
+#include "tqlabel.h"
+#include "tqlineedit.h"
+#include "tqspinbox.h"
+#include "tqcombobox.h"
+#include "tqdatetimeedit.h"
+
+/*!
+ \class TQSqlEditorFactory tqsqleditorfactory.h
+ \brief The TQSqlEditorFactory class is used to create the editors
+ used by TQDataTable and TQSqlForm.
+
+ \ingroup database
+ \module sql
+
+ TQSqlEditorFactory is used by TQDataTable and TQSqlForm to
+ automatically create appropriate editors for a given TQSqlField.
+ For example if the field is a TQVariant::String a TQLineEdit would
+ be the default editor, whereas a TQVariant::Int's default editor
+ would be a TQSpinBox.
+
+ If you want to create different editors for fields with the same
+ data type, subclass TQSqlEditorFactory and reimplement the
+ createEditor() function.
+
+ \sa TQDataTable, TQSqlForm
+*/
+
+
+/*!
+ Constructs a SQL editor factory with tqparent \a tqparent, called \a
+ name.
+*/
+
+TQSqlEditorFactory::TQSqlEditorFactory ( TQObject * tqparent, const char * name )
+ : TQEditorFactory( tqparent, name )
+{
+
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlEditorFactory::~TQSqlEditorFactory()
+{
+
+}
+
+static TQSqlEditorFactory * defaultfactory = 0;
+static TQCleanupHandler< TQSqlEditorFactory > qsql_cleanup_editor_factory;
+
+/*!
+ Returns an instance of a default editor factory.
+*/
+
+TQSqlEditorFactory * TQSqlEditorFactory::defaultFactory()
+{
+ if( defaultfactory == 0 ){
+ defaultfactory = new TQSqlEditorFactory();
+ qsql_cleanup_editor_factory.add( &defaultfactory );
+ }
+
+ return defaultfactory;
+}
+
+/*!
+ Replaces the default editor factory with \a factory. All
+ TQDataTable and TQSqlForm instantiations will use this new factory
+ for creating field editors. \e{TQSqlEditorFactory takes ownership
+ of \a factory, and destroys it when it is no longer needed.}
+*/
+
+void TQSqlEditorFactory::installDefaultFactory( TQSqlEditorFactory * factory )
+{
+ if( factory == 0 ) return;
+
+ if( defaultfactory != 0 ){
+ qsql_cleanup_editor_factory.remove( &defaultfactory );
+ delete defaultfactory;
+ }
+ defaultfactory = factory;
+ qsql_cleanup_editor_factory.add( &defaultfactory );
+}
+
+/*!
+ Creates and returns the appropriate editor widget for the TQVariant
+ \a variant.
+
+ The widget that is returned has the tqparent \a tqparent (which may be
+ zero). If \a variant is invalid, 0 is returned.
+*/
+
+TQWidget * TQSqlEditorFactory::createEditor( TQWidget * tqparent,
+ const TQVariant & variant )
+{
+ return TQEditorFactory::createEditor( tqparent, variant );
+}
+
+/*!
+ \overload
+
+ Creates and returns the appropriate editor for the TQSqlField \a
+ field.
+*/
+
+TQWidget * TQSqlEditorFactory::createEditor( TQWidget * tqparent,
+ const TQSqlField * field )
+{
+ if ( !field ) {
+ return 0;
+ }
+
+ TQWidget * w = 0;
+ switch( field->type() ){
+ case TQVariant::Invalid:
+ w = 0;
+ break;
+ case TQVariant::Bool:
+ w = new TQComboBox( tqparent, "qt_editor_bool" );
+ ((TQComboBox *) w)->insertItem( "False" );
+ ((TQComboBox *) w)->insertItem( "True" );
+ break;
+ case TQVariant::UInt:
+ w = new TQSpinBox( 0, 2147483647, 1, tqparent, "qt_editor_spinbox" );
+ break;
+ case TQVariant::Int:
+ w = new TQSpinBox( -2147483647, 2147483647, 1, tqparent, "qt_editor_int" );
+ break;
+ case TQVariant::LongLong:
+ case TQVariant::ULongLong:
+ case TQVariant::String:
+ case TQVariant::CString:
+ case TQVariant::Double:
+ w = new TQLineEdit( tqparent, "qt_editor_double" );
+ ((TQLineEdit*)w)->setFrame( FALSE );
+ break;
+ case TQVariant::Date:
+ w = new TQDateEdit( tqparent, "qt_editor_date" );
+ break;
+ case TQVariant::Time:
+ w = new TQTimeEdit( tqparent, "qt_editor_time" );
+ break;
+ case TQVariant::DateTime:
+ w = new TQDateTimeEdit( tqparent, "qt_editor_datetime" );
+ break;
+#ifndef TQT_NO_LABEL
+ case TQVariant::Pixmap:
+ w = new TQLabel( tqparent, "qt_editor_pixmap" );
+ break;
+#endif
+ case TQVariant::Palette:
+ case TQVariant::ColorGroup:
+ case TQVariant::Color:
+ case TQVariant::Font:
+ case TQVariant::Brush:
+ case TQVariant::Bitmap:
+ case TQVariant::Cursor:
+ case TQVariant::Map:
+ case TQVariant::StringList:
+ case TQVariant::Rect:
+ case TQVariant::Size:
+ case TQVariant::IconSet:
+ case TQVariant::Point:
+ case TQVariant::PointArray:
+ case TQVariant::Region:
+ case TQVariant::SizePolicy:
+ case TQVariant::ByteArray:
+ default:
+ w = new TQWidget( tqparent, "qt_editor_default" );
+ break;
+ }
+ return w;
+}
+
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/tqsqleditorfactory.h b/tqtinterface/qt4/src/sql/tqsqleditorfactory.h
new file mode 100644
index 0000000..151fb5e
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqleditorfactory.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Definition of TQSqlEditorFactory class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTQLEDITORFACTORY_H
+#define TQSTQLEDITORFACTORY_H
+
+#ifndef TQT_H
+#include "tqeditorfactory.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_STQL_EDIT_WIDGETS
+
+class TQSqlField;
+
+class TQM_EXPORT_SQL TQSqlEditorFactory : public TQEditorFactory
+{
+public:
+ TQSqlEditorFactory ( TQObject * tqparent = 0, const char * name = 0 );
+ ~TQSqlEditorFactory();
+ virtual TQWidget * createEditor( TQWidget * tqparent, const TQVariant & variant );
+ virtual TQWidget * createEditor( TQWidget * tqparent, const TQSqlField * field );
+
+ static TQSqlEditorFactory * defaultFactory();
+ static void installDefaultFactory( TQSqlEditorFactory * factory );
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQSqlEditorFactory( const TQSqlEditorFactory & );
+ TQSqlEditorFactory &operator=( const TQSqlEditorFactory & );
+#endif
+};
+
+#endif // TQT_NO_SQL
+#endif // TQSTQLEDITORFACTORY_H
diff --git a/tqtinterface/qt4/src/sql/tqsqlerror.cpp b/tqtinterface/qt4/src/sql/tqsqlerror.cpp
new file mode 100644
index 0000000..55d9820
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlerror.cpp
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Implementation of TQSqlError class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlerror.h"
+#include <tqmessagebox.h>
+
+#ifndef TQT_NO_SQL
+
+/*!
+ \class TQSqlError tqsqlerror.h
+ \brief The TQSqlError class provides SQL database error information.
+
+ \ingroup database
+ \module sql
+
+ This class is used to report database-specific errors. An error
+ description and (if appropriate) a database-specific error number
+ can be obtained using this class.
+*/
+
+/*!
+ \enum TQSqlError::Type
+
+ This enum type describes the type of SQL error that occurred.
+
+ \value None no error occurred
+ \value Connection connection error
+ \value Statement SQL statement syntax error
+ \value Transaction transaction failed error
+ \value Unknown unknown error
+*/
+
+/*!
+ Constructs an error containing the driver error text \a
+ driverText, the database-specific error text \a databaseText, the
+ type \a type and the optional error number \a number.
+*/
+
+TQSqlError::TQSqlError( const TQString& driverText,
+ const TQString& databaseText,
+ int type,
+ int number )
+: driverError(driverText),
+ databaseError(databaseText),
+ errorType(type),
+ errorNumber(number)
+{
+}
+
+/*!
+ Creates a copy of \a other.
+*/
+
+TQSqlError::TQSqlError( const TQSqlError& other )
+: driverError(other.driverError),
+ databaseError(other.databaseError),
+ errorType(other.errorType),
+ errorNumber(other.errorNumber)
+{
+}
+
+/*!
+ Sets the error equal to \a other.
+*/
+
+TQSqlError& TQSqlError::operator=( const TQSqlError& other )
+{
+ driverError = other.driverError;
+ databaseError = other.databaseError;
+ errorType = other.errorType;
+ errorNumber = other.errorNumber;
+ return *this;
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlError::~TQSqlError()
+{
+}
+
+/*!
+ Returns the text of the error as reported by the driver. This may
+ contain database-specific descriptions.
+*/
+TQString TQSqlError::driverText() const
+{
+ return driverError;
+}
+
+/*!
+ Sets the driver error text to the value of \a driverText.
+*/
+
+void TQSqlError::setDriverText( const TQString& driverText )
+{
+ driverError = driverText;
+}
+
+/*!
+ Returns the text of the error as reported by the database. This
+ may contain database-specific descriptions.
+*/
+
+TQString TQSqlError::databaseText() const
+{
+ return databaseError;
+}
+
+/*!
+ Sets the database error text to the value of \a databaseText.
+*/
+
+void TQSqlError::setDatabaseText( const TQString& databaseText )
+{
+ databaseError = databaseText;
+}
+
+/*!
+ Returns the error type, or -1 if the type cannot be determined.
+
+ \sa TQSqlError::Type.
+*/
+
+int TQSqlError::type() const
+{
+ return errorType;
+}
+
+/*!
+ Sets the error type to the value of \a type.
+*/
+
+void TQSqlError::setType( int type )
+{
+ errorType = type;
+}
+
+/*!
+ Returns the database-specific error number, or -1 if it cannot be
+ determined.
+*/
+
+int TQSqlError::number() const
+{
+ return errorNumber;
+}
+
+/*!
+ Sets the database-specific error number to \a number.
+*/
+
+void TQSqlError::setNumber( int number )
+{
+ errorNumber = number;
+}
+
+/*!
+ This is a convenience function that returns databaseText() and
+ driverText() concatenated into a single string.
+
+ \sa showMessage(), driverText(), databaseText()
+*/
+
+TQString TQSqlError::text() const
+{
+ if ( databaseError.endsWith("\n") )
+ return databaseError + driverError;
+ else
+ return databaseError + " " + driverError;
+}
+
+/*!
+ \obsolete
+
+ This is a convenience function that pops up a TQMessageBox
+ containing the message returned by text(). An additional string
+ can be passed in via the \a msg parameter, which will be
+ concatenated with the text() message.
+
+ \sa text(), driverText(), databaseText()
+*/
+void TQSqlError::showMessage( const TQString& msg ) const
+{
+#ifndef TQT_NO_MESSAGEBOX
+ TQMessageBox::warning( NULL, "SQL Error", msg + text(),
+ TQMessageBox::Ok, TQMessageBox::NoButton );
+#endif // TQT_NO_MESSAGEBOX
+}
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/tqsqlerror.h b/tqtinterface/qt4/src/sql/tqsqlerror.h
new file mode 100644
index 0000000..3970185
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlerror.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Definition of TQSqlError class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLERROR_H
+#define TQSQLERROR_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQM_EXPORT_SQL TQSqlError
+{
+public:
+ enum Type {
+ None,
+ Connection,
+ Statement,
+ Transaction,
+ Unknown
+ };
+ TQSqlError( const TQString& driverText = TQString::null,
+ const TQString& databaseText = TQString::null,
+ int type = TQSqlError::None,
+ int number = -1 );
+ TQSqlError( const TQSqlError& other );
+ TQSqlError& operator=( const TQSqlError& other );
+ virtual ~TQSqlError();
+
+ TQString driverText() const;
+ virtual void setDriverText( const TQString& driverText );
+ TQString databaseText() const;
+ virtual void setDatabaseText( const TQString& databaseText );
+ int type() const;
+ virtual void setType( int type );
+ int number() const;
+ virtual void setNumber( int number );
+ TQString text() const;
+ void showMessage( const TQString& msg = TQString::null ) const;
+
+private:
+ TQString driverError;
+ TQString databaseError;
+ int errorType;
+ int errorNumber;
+};
+
+#endif // TQT_NO_SQL
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlextension_p.cpp b/tqtinterface/qt4/src/sql/tqsqlextension_p.cpp
new file mode 100644
index 0000000..dd4f1fb
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlextension_p.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Implementation of the TQSqlExtension class
+**
+** Created : 2002-06-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlextension_p.h"
+
+#ifndef TQT_NO_SQL
+TQSqlExtension::TQSqlExtension()
+ : bindm( BindByPosition ), bindCount( 0 )
+{
+}
+
+TQSqlExtension::~TQSqlExtension()
+{
+}
+
+bool TQSqlExtension::prepare( const TQString& /*query*/ )
+{
+ return FALSE;
+}
+
+bool TQSqlExtension::exec()
+{
+ return FALSE;
+}
+
+void TQSqlExtension::bindValue( const TQString& placeholder, const TQVariant& val, TQSql::ParameterType tp )
+{
+ bindm = BindByName;
+ // if the index has already been set when doing emulated named
+ // bindings - don't reset it
+ if ( index.tqcontains( (int)values.count() ) ) {
+ index[ (int)values.count() ] = placeholder;
+ }
+ values[ placeholder ] = Param( val, tp );
+}
+
+void TQSqlExtension::bindValue( int pos, const TQVariant& val, TQSql::ParameterType tp )
+{
+ bindm = BindByPosition;
+ index[ pos ] = TQString::number( pos );
+ TQString nm = TQString::number( pos );
+ values[ nm ] = Param( val, tp );
+}
+
+void TQSqlExtension::addBindValue( const TQVariant& val, TQSql::ParameterType tp )
+{
+ bindm = BindByPosition;
+ bindValue( bindCount++, val, tp );
+}
+
+void TQSqlExtension::clearValues()
+{
+ values.clear();
+ bindCount = 0;
+}
+
+void TQSqlExtension::resetBindCount()
+{
+ bindCount = 0;
+}
+
+void TQSqlExtension::clearIndex()
+{
+ index.clear();
+ holders.clear();
+}
+
+void TQSqlExtension::clear()
+{
+ clearValues();
+ clearIndex();
+}
+
+TQVariant TQSqlExtension::parameterValue( const TQString& holder )
+{
+ return values[ holder ].value;
+}
+
+TQVariant TQSqlExtension::parameterValue( int pos )
+{
+ return values[ index[ pos ] ].value;
+}
+
+TQVariant TQSqlExtension::boundValue( const TQString& holder ) const
+{
+ return values[ holder ].value;
+}
+
+TQVariant TQSqlExtension::boundValue( int pos ) const
+{
+ return values[ index[ pos ] ].value;
+}
+
+TQMap<TQString, TQVariant> TQSqlExtension::boundValues() const
+{
+ TQMap<TQString, Param>::ConstIterator it;
+ TQMap<TQString, TQVariant> m;
+ if ( bindm == BindByName ) {
+ for ( it = values.begin(); it != values.end(); ++it )
+ m.insert( it.key(), it.data().value );
+ } else {
+ TQString key, tmp, fmt;
+ fmt.sprintf( "%%0%dd", TQString::number( values.count()-1 ).length() );
+ for ( it = values.begin(); it != values.end(); ++it ) {
+ tmp.sprintf( fmt.ascii(), it.key().toInt() );
+ m.insert( tmp, it.data().value );
+ }
+ }
+ return m;
+}
+
+TQSqlExtension::BindMethod TQSqlExtension::bindMethod()
+{
+ return bindm;
+}
+
+TQSqlDriverExtension::TQSqlDriverExtension()
+{
+}
+
+TQSqlDriverExtension::~TQSqlDriverExtension()
+{
+}
+
+TQSqlOpenExtension::TQSqlOpenExtension()
+{
+}
+
+TQSqlOpenExtension::~TQSqlOpenExtension()
+{
+}
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlextension_p.h b/tqtinterface/qt4/src/sql/tqsqlextension_p.h
new file mode 100644
index 0000000..419240d
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlextension_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Definition of the TQSqlExtension class
+**
+** Created : 2002-06-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLEXTENSION_P_H
+#define TQSQLEXTENSION_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of other TQt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqmap.h"
+#include "tqvaluevector.h"
+#include "tqstring.h"
+#include "tqvariant.h"
+#include "tqsql.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SQL
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#define TQM_TEMPLATE_EXTERN_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#define TQM_TEMPLATE_EXTERN_SQL TQ_TEMPLATE_EXTERN
+#endif
+
+struct Param {
+ Param( const TQVariant& v = TQVariant(), TQSql::ParameterType t = TQSql::In ): value( v ), typ( t ) {}
+ TQVariant value;
+ TQSql::ParameterType typ;
+ TQ_DUMMY_COMPARISON_OPERATOR(Param)
+};
+
+struct Holder {
+ Holder( const TQString& hldr = TQString::null, int pos = -1 ): holderName( hldr ), holderPos( pos ) {}
+ bool operator==( const Holder& h ) const { return h.holderPos == holderPos && h.holderName == holderName; }
+ bool operator!=( const Holder& h ) const { return h.holderPos != holderPos || h.holderName != holderName; }
+ TQString holderName;
+ int holderPos;
+};
+
+#define TQ_DEFINED_TQSQLEXTENSION
+#include "tqwinexport.h"
+
+class TQM_EXPORT_SQL TQSqlExtension {
+public:
+ TQSqlExtension();
+ virtual ~TQSqlExtension();
+ virtual bool prepare( const TQString& query );
+ virtual bool exec();
+ virtual void bindValue( const TQString& holder, const TQVariant& value, TQSql::ParameterType = TQSql::In );
+ virtual void bindValue( int pos, const TQVariant& value, TQSql::ParameterType = TQSql::In );
+ virtual void addBindValue( const TQVariant& value, TQSql::ParameterType = TQSql::In );
+ virtual TQVariant parameterValue( const TQString& holder );
+ virtual TQVariant parameterValue( int pos );
+ TQVariant boundValue( const TQString& holder ) const;
+ TQVariant boundValue( int pos ) const;
+ TQMap<TQString, TQVariant> boundValues() const;
+ void clear();
+ void clearValues();
+ void clearIndex();
+ void resetBindCount();
+
+ enum BindMethod { BindByPosition, BindByName };
+ BindMethod bindMethod(); // ### 4.0: make this const
+ BindMethod bindm;
+ int bindCount;
+
+ TQMap<int, TQString> index;
+ typedef TQMap<TQString, Param> ValueMap;
+ ValueMap values;
+
+ // convenience container for TQSqlQuery
+ // to map holders <-> positions
+ typedef TQValueVector<Holder> HolderVector;
+ HolderVector holders;
+};
+
+class TQM_EXPORT_SQL TQSqlDriverExtension
+{
+public:
+ TQSqlDriverExtension();
+ virtual ~TQSqlDriverExtension();
+ virtual bool isOpen() const = 0;
+};
+
+class TQM_EXPORT_SQL TQSqlOpenExtension
+{
+public:
+ TQSqlOpenExtension();
+ virtual ~TQSqlOpenExtension();
+ virtual bool open( const TQString& db,
+ const TQString& user,
+ const TQString& password,
+ const TQString& host,
+ int port,
+ const TQString& connOpts ) = 0;
+};
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlfield.cpp b/tqtinterface/qt4/src/sql/tqsqlfield.cpp
new file mode 100644
index 0000000..fcbb08d
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlfield.cpp
@@ -0,0 +1,563 @@
+/****************************************************************************
+**
+** Implementation of TQSqlField class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlfield.h"
+
+#ifndef TQT_NO_SQL
+
+
+/*!
+ \class TQSqlField tqsqlfield.h
+ \brief The TQSqlField class manipulates the fields in SQL database tables
+ and views.
+
+ \ingroup database
+ \module sql
+
+ TQSqlField represents the characteristics of a single column in a
+ database table or view, such as the data type and column name. A
+ field also tqcontains the value of the database column, which can be
+ viewed or changed.
+
+ Field data values are stored as TQVariants. Using an incompatible
+ type is not permitted. For example:
+
+ \code
+ TQSqlField f( "myfield", TQVariant::Int );
+ f.setValue( TQPixmap() ); // will not work
+ \endcode
+
+ However, the field will attempt to cast certain data types to the
+ field data type where possible:
+
+ \code
+ TQSqlField f( "myfield", TQVariant::Int );
+ f.setValue( TQString("123") ); // casts TQString to int
+ \endcode
+
+ TQSqlField objects are rarely created explicitly in application
+ code. They are usually accessed indirectly through \l TQSqlRecord
+ or \l TQSqlCursor which already contain a list of fields. For
+ example:
+
+ \code
+ TQSqlCursor cur( "Employee" ); // create cursor using the 'Employee' table
+ TQSqlField* f = cur.field( "name" ); // use the 'name' field
+ f->setValue( "Dave" ); // set field value
+ ...
+ \endcode
+
+ In practice we rarely need to extract a pointer to a field at all.
+ The previous example would normally be written:
+
+ \code
+ TQSqlCursor cur( "Employee" );
+ cur.setValue( "name", "Dave" );
+ ...
+ \endcode
+*/
+
+/*!
+ Constructs an empty field called \a fieldName of type \a type.
+*/
+
+TQSqlField::TQSqlField( const TQString& fieldName, TQVariant::Type type )
+ : nm(fieldName), ro(FALSE), nul(FALSE)
+{
+ d = new TQSqlFieldPrivate();
+ d->type = type;
+ val.cast( type );
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+
+TQSqlField::TQSqlField( const TQSqlField& other )
+ : nm( other.nm ), val( other.val ), ro( other.ro ), nul( other.nul )
+{
+ d = new TQSqlFieldPrivate();
+ d->type = other.d->type;
+}
+
+/*!
+ Sets the field equal to \a other.
+*/
+
+TQSqlField& TQSqlField::operator=( const TQSqlField& other )
+{
+ nm = other.nm;
+ val = other.val;
+ ro = other.ro;
+ nul = other.nul;
+ d->type = other.d->type;
+ return *this;
+}
+
+/*!
+ Returns TRUE if the field is equal to \a other; otherwise returns
+ FALSE. Fields are considered equal when the following field
+ properties are the same:
+
+ \list
+ \i \c name()
+ \i \c isNull()
+ \i \c value()
+ \i \c isReadOnly()
+ \endlist
+
+*/
+bool TQSqlField::operator==(const TQSqlField& other) const
+{
+ return ( nm == other.nm &&
+ val == other.val &&
+ ro == other.ro &&
+ nul == other.nul &&
+ d->type == other.d->type );
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlField::~TQSqlField()
+{
+ delete d;
+}
+
+
+/*!
+ \fn TQVariant TQSqlField::value() const
+
+ Returns the value of the field as a TQVariant.
+*/
+
+/*!
+ Sets the value of the field to \a value. If the field is read-only
+ (isReadOnly() returns TRUE), nothing happens. If the data type of
+ \a value differs from the field's current data type, an attempt is
+ made to cast it to the proper type. This preserves the data type
+ of the field in the case of assignment, e.g. a TQString to an
+ integer data type. For example:
+
+ \code
+ TQSqlCursor cur( "Employee" ); // 'Employee' table
+ TQSqlField* f = cur.field( "student_count" ); // an integer field
+ ...
+ f->setValue( myLineEdit->text() ); // cast the line edit text to an integer
+ \endcode
+
+ \sa isReadOnly()
+*/
+
+void TQSqlField::setValue( const TQVariant& value )
+{
+ if ( isReadOnly() )
+ return;
+ if ( value.type() != d->type ) {
+ if ( !val.canCast( d->type ) )
+ qWarning("TQSqlField::setValue: %s cannot cast from %s to %s",
+ nm.local8Bit().data(), value.typeName(), TQVariant::typeToName( d->type ) );
+ }
+ val = value;
+
+ if ( value.isNull() )
+ nul = TRUE;
+ else
+ nul = val.type() == TQVariant::Invalid;
+}
+
+/*!
+ Clears the value of the field. If the field is read-only, nothing
+ happens. If \a nullify is TRUE (the default), the field is set to
+ NULL.
+*/
+
+void TQSqlField::clear( bool nullify )
+{
+ if ( isReadOnly() )
+ return;
+ TQVariant v;
+ v.cast( type() );
+ val = v;
+ if ( nullify )
+ nul = TRUE;
+}
+
+/*!
+ \fn void TQSqlField::setName( const TQString& name )
+
+ Sets the name of the field to \a name.
+*/
+
+void TQSqlField::setName( const TQString& name )
+{
+ nm = name;
+}
+
+/*!
+ \fn void TQSqlField::setNull()
+
+ Sets the field to NULL and clears the value using clear(). If the
+ field is read-only, nothing happens.
+
+ \sa isReadOnly() clear()
+*/
+
+void TQSqlField::setNull()
+{
+ clear( TRUE );
+}
+
+/*!
+ \fn void TQSqlField::setReadOnly( bool readOnly )
+
+ Sets the read only flag of the field's value to \a readOnly.
+
+ \sa setValue()
+*/
+void TQSqlField::setReadOnly( bool readOnly )
+{
+ ro = readOnly;
+}
+
+/*!
+ \fn TQString TQSqlField::name() const
+
+ Returns the name of the field.
+*/
+
+/*!
+ \fn TQVariant::Type TQSqlField::type() const
+
+ Returns the field's type as stored in the database.
+ Note that the actual value might have a different type,
+ Numerical values that are too large to store in a long
+ int or double are usually stored as strings to prevent
+ precision loss.
+*/
+
+/*!
+ \fn bool TQSqlField::isReadOnly() const
+
+ Returns TRUE if the field's value is read only; otherwise returns
+ FALSE.
+*/
+
+/*!
+ \fn bool TQSqlField::isNull() const
+
+ Returns TRUE if the field is currently NULL; otherwise returns
+ FALSE.
+*/
+
+
+/******************************************/
+/******* TQSqlFieldInfo Impl ******/
+/******************************************/
+
+struct TQSqlFieldInfoPrivate
+{
+ int required, len, prec, typeID;
+ uint generated: 1;
+ uint trim: 1;
+ uint calculated: 1;
+ TQString name;
+ TQString typeName;
+ TQVariant::Type typ;
+ TQVariant defValue;
+};
+
+/*!
+ \class TQSqlFieldInfo tqsqlfield.h
+ \brief The TQSqlFieldInfo class stores meta data associated with a SQL field.
+
+ \ingroup database
+ \module sql
+
+ TQSqlFieldInfo objects only store meta data; field values are
+ stored in TQSqlField objects.
+
+ All values must be set in the constructor, and may be retrieved
+ using isRequired(), type(), length(), precision(), defaultValue(),
+ name(), isGenerated() and typeID().
+*/
+
+/*!
+ Constructs a TQSqlFieldInfo with the following parameters:
+ \table
+ \row \i \a name \i the name of the field.
+ \row \i \a typ \i the field's type in a TQVariant.
+ \row \i \a required \i greater than 0 if the field is required, 0
+ if its value can be NULL and less than 0 if it cannot be
+ determined whether the field is required or not.
+ \row \i \a len \i the length of the field. Note that for
+ non-character types some databases return either the length in
+ bytes or the number of digits. -1 signifies that the length cannot
+ be determined.
+ \row \i \a prec \i the precision of the field, or -1 if the field
+ has no precision or it cannot be determined.
+ \row \i \a defValue \i the default value that is inserted into
+ the table if none is specified by the user. TQVariant() if there is
+ no default value or it cannot be determined.
+ \row \i \a typeID \i the internal typeID of the database system
+ (only useful for low-level programming). 0 if unknown.
+ \row \i \a generated \i TRUE indicates that this field should be
+ included in auto-generated SQL statments, e.g. in TQSqlCursor.
+ \row \i \a trim \i TRUE indicates that widgets should remove
+ trailing whitespace from character fields. This does not affect
+ the field value but only its representation inside widgets.
+ \row \i \a calculated \i TRUE indicates that the value of this
+ field is calculated. The value of calculated fields can by
+ modified by subclassing TQSqlCursor and overriding
+ TQSqlCursor::calculateField().
+ \endtable
+*/
+TQSqlFieldInfo::TQSqlFieldInfo( const TQString& name,
+ TQVariant::Type typ,
+ int required,
+ int len,
+ int prec,
+ const TQVariant& defValue,
+ int typeID,
+ bool generated,
+ bool trim,
+ bool calculated )
+{
+ d = new TQSqlFieldInfoPrivate();
+ d->name = name;
+ d->typ = typ;
+ d->required = required;
+ d->len = len;
+ d->prec = prec;
+ d->defValue = defValue;
+ d->typeID = typeID;
+ d->generated = generated;
+ d->trim = trim;
+ d->calculated = calculated;
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+TQSqlFieldInfo::TQSqlFieldInfo( const TQSqlFieldInfo & other )
+{
+ d = new TQSqlFieldInfoPrivate( *(other.d) );
+}
+
+/*!
+ Creates a TQSqlFieldInfo object with the type and the name of the
+ TQSqlField \a other. If \a generated is TRUE this field will be
+ included in auto-generated SQL statments, e.g. in TQSqlCursor.
+*/
+TQSqlFieldInfo::TQSqlFieldInfo( const TQSqlField & other, bool generated )
+{
+ d = new TQSqlFieldInfoPrivate();
+ d->name = other.name();
+ d->typ = other.type();
+ d->required = -1;
+ d->len = -1;
+ d->prec = -1;
+ d->typeID = 0;
+ d->generated = generated;
+ d->trim = FALSE;
+ d->calculated = FALSE;
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+TQSqlFieldInfo::~TQSqlFieldInfo()
+{
+ delete d;
+}
+
+/*!
+ Assigns \a other to this field info and returns a reference to it.
+*/
+TQSqlFieldInfo& TQSqlFieldInfo::operator=( const TQSqlFieldInfo& other )
+{
+ delete d;
+ d = new TQSqlFieldInfoPrivate( *(other.d) );
+ return *this;
+}
+
+/*!
+ Returns TRUE if this fieldinfo is equal to \a f; otherwise returns
+ FALSE.
+
+ Two field infos are considered equal if all their attributes
+ match.
+*/
+bool TQSqlFieldInfo::operator==( const TQSqlFieldInfo& f ) const
+{
+ return ( d->name == f.d->name &&
+ d->typ == f.d->typ &&
+ d->required == f.d->required &&
+ d->len == f.d->len &&
+ d->prec == f.d->prec &&
+ d->defValue == f.d->defValue &&
+ d->typeID == f.d->typeID &&
+ d->generated == f.d->generated &&
+ d->trim == f.d->trim &&
+ d->calculated == f.d->calculated );
+}
+
+/*!
+ Returns an empty TQSqlField based on the information in this
+ TQSqlFieldInfo.
+*/
+TQSqlField TQSqlFieldInfo::toField() const
+{ return TQSqlField( d->name, d->typ ); }
+
+/*!
+ Returns a value greater than 0 if the field is required (NULL
+ values are not allowed), 0 if it isn't required (NULL values are
+ allowed) or less than 0 if it cannot be determined whether the
+ field is required or not.
+*/
+int TQSqlFieldInfo::isRequired() const
+{ return d->required; }
+
+/*!
+ Returns the field's type or TQVariant::Invalid if the type is
+ unknown.
+*/
+TQVariant::Type TQSqlFieldInfo::type() const
+{ return d->typ; }
+
+/*!
+ Returns the field's length. For fields storing text the return
+ value is the maximum number of characters the field can hold. For
+ non-character fields some database systems return the number of
+ bytes needed or the number of digits allowed. If the length cannot
+ be determined -1 is returned.
+*/
+int TQSqlFieldInfo::length() const
+{ return d->len; }
+
+/*!
+ Returns the field's precision or -1 if the field has no precision
+ or it cannot be determined.
+*/
+int TQSqlFieldInfo::precision() const
+{ return d->prec; }
+
+/*!
+ Returns the field's default value or an empty TQVariant if the
+ field has no default value or the value couldn't be determined.
+ The default value is the value inserted in the database when it
+ is not explicitly specified by the user.
+*/
+TQVariant TQSqlFieldInfo::defaultValue() const
+{ return d->defValue; }
+
+/*!
+ Returns the name of the field in the SQL table.
+*/
+TQString TQSqlFieldInfo::name() const
+{ return d->name; }
+
+/*!
+ Returns the internal type identifier as returned from the database
+ system. The return value is 0 if the type is unknown.
+
+ \warning This information is only useful for low-level database
+ programming and is \e not database independent.
+*/
+int TQSqlFieldInfo::typeID() const
+{ return d->typeID; }
+
+/*!
+ Returns TRUE if the field should be included in auto-generated
+ SQL statments, e.g. in TQSqlCursor; otherwise returns FALSE.
+
+ \sa setGenerated()
+*/
+bool TQSqlFieldInfo::isGenerated() const
+{ return d->generated; }
+
+/*!
+ Returns TRUE if trailing whitespace should be removed from
+ character fields; otherwise returns FALSE.
+
+ \sa setTrim()
+*/
+bool TQSqlFieldInfo::isTrim() const
+{ return d->trim; }
+
+/*!
+ Returns TRUE if the field is calculated; otherwise returns FALSE.
+
+ \sa setCalculated()
+*/
+bool TQSqlFieldInfo::isCalculated() const
+{ return d->calculated; }
+
+/*!
+ If \a trim is TRUE widgets should remove trailing whitespace from
+ character fields. This does not affect the field value but only
+ its representation inside widgets.
+
+ \sa isTrim()
+*/
+void TQSqlFieldInfo::setTrim( bool trim )
+{ d->trim = trim; }
+
+/*!
+ \a gen set to FALSE indicates that this field should not appear
+ in auto-generated SQL statements (for example in TQSqlCursor).
+
+ \sa isGenerated()
+*/
+void TQSqlFieldInfo::setGenerated( bool gen )
+{ d->generated = gen; }
+
+/*!
+ \a calc set to TRUE indicates that this field is a calculated
+ field. The value of calculated fields can by modified by subclassing
+ TQSqlCursor and overriding TQSqlCursor::calculateField().
+
+ \sa isCalculated()
+*/
+void TQSqlFieldInfo::setCalculated( bool calc )
+{ d->calculated = calc; }
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlfield.h b/tqtinterface/qt4/src/sql/tqsqlfield.h
new file mode 100644
index 0000000..2983ba7
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlfield.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Definition of TQSqlField class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLFIELD_H
+#define TQSQLFIELD_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqvariant.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQSqlFieldPrivate
+{
+public:
+ TQVariant::Type type;
+};
+
+class TQM_EXPORT_SQL TQSqlField
+{
+public:
+ TQSqlField( const TQString& fieldName = TQString::null, TQVariant::Type type = TQVariant::Invalid );
+ TQSqlField( const TQSqlField& other );
+ TQSqlField& operator=( const TQSqlField& other );
+ bool operator==(const TQSqlField& other) const;
+ virtual ~TQSqlField();
+
+ virtual void setValue( const TQVariant& value );
+ virtual TQVariant value() const;
+ virtual void setName( const TQString& name );
+ TQString name() const;
+ virtual void setNull();
+ bool isNull() const;
+ virtual void setReadOnly( bool readOnly );
+ bool isReadOnly() const;
+ void clear( bool nullify = TRUE );
+ TQVariant::Type type() const;
+
+private:
+ TQString nm;
+ TQVariant val;
+ uint ro: 1;
+ uint nul: 1;
+ TQSqlFieldPrivate* d;
+};
+
+inline TQVariant TQSqlField::value() const
+{ return val; }
+
+inline TQString TQSqlField::name() const
+{ return nm; }
+
+inline bool TQSqlField::isNull() const
+{ return nul; }
+
+inline bool TQSqlField::isReadOnly() const
+{ return ro; }
+
+inline TQVariant::Type TQSqlField::type() const
+{ return d->type; }
+
+
+/******************************************/
+/******* TQSqlFieldInfo Class ******/
+/******************************************/
+
+struct TQSqlFieldInfoPrivate;
+
+class TQM_EXPORT_SQL TQSqlFieldInfo
+{
+public:
+ TQSqlFieldInfo( const TQString& name = TQString::null,
+ TQVariant::Type typ = TQVariant::Invalid,
+ int required = -1,
+ int len = -1,
+ int prec = -1,
+ const TQVariant& defValue = TQVariant(),
+ int sqlType = 0,
+ bool generated = TRUE,
+ bool trim = FALSE,
+ bool calculated = FALSE );
+ TQSqlFieldInfo( const TQSqlFieldInfo & other );
+ TQSqlFieldInfo( const TQSqlField & other, bool generated = TRUE );
+ virtual ~TQSqlFieldInfo();
+ TQSqlFieldInfo& operator=( const TQSqlFieldInfo& other );
+ bool operator==( const TQSqlFieldInfo& f ) const;
+
+ TQSqlField toField() const;
+ int isRequired() const;
+ TQVariant::Type type() const;
+ int length() const;
+ int precision() const;
+ TQVariant defaultValue() const;
+ TQString name() const;
+ int typeID() const;
+ bool isGenerated() const;
+ bool isTrim() const;
+ bool isCalculated() const;
+
+ virtual void setTrim( bool trim );
+ virtual void setGenerated( bool gen );
+ virtual void setCalculated( bool calc );
+
+private:
+ TQSqlFieldInfoPrivate* d;
+};
+
+
+#endif // TQT_NO_SQL
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlform.cpp b/tqtinterface/qt4/src/sql/tqsqlform.cpp
new file mode 100644
index 0000000..ed1f935
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlform.cpp
@@ -0,0 +1,403 @@
+/****************************************************************************
+**
+** Implementation of TQSqlForm class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlform.h"
+
+#ifndef TQT_NO_STQL_FORM
+
+#include "tqsqlfield.h"
+#include "tqsqlpropertymap.h"
+#include "tqsqlrecord.h"
+#include "tqstringlist.h"
+#include "tqwidget.h"
+#include "tqdict.h"
+
+class TQSqlFormPrivate
+{
+public:
+ TQSqlFormPrivate() : propertyMap( 0 ), buf( 0 ), dirty( FALSE ) {}
+ ~TQSqlFormPrivate() { if ( propertyMap ) delete propertyMap; }
+ TQStringList fld;
+ TQDict<TQWidget> wgt;
+ TQMap< TQWidget *, TQSqlField * > map;
+ TQSqlPropertyMap * propertyMap;
+ TQSqlRecord* buf;
+ bool dirty;
+};
+
+/*!
+ \class TQSqlForm
+ \brief The TQSqlForm class creates and manages data entry forms
+ tied to SQL databases.
+
+ \ingroup database
+ \mainclass
+ \module sql
+
+ Typical use of a TQSqlForm consists of the following steps:
+ \list
+ \i Create the widgets you want to appear in the form.
+ \i Create a cursor and navigate to the record to be edited.
+ \i Create the TQSqlForm.
+ \i Set the form's record buffer to the cursor's update buffer.
+ \i Insert each widget and the field it is to edit into the form.
+ \i Use readFields() to update the editor widgets with values from
+ the database's fields.
+ \i Display the form and let the user edit values etc.
+ \i Use writeFields() to update the database's field values with
+ the values in the editor widgets.
+ \endlist
+
+ Note that a TQSqlForm does not access the database directly, but
+ most often via TQSqlFields which are part of a TQSqlCursor. A
+ TQSqlCursor::insert(), TQSqlCursor::update() or TQSqlCursor::del()
+ call is needed to actually write values to the database.
+
+ Some sample code to initialize a form successfully:
+
+ \code
+ TQLineEdit myEditor( this );
+ TQSqlForm myForm( this );
+ TQSqlCursor myCursor( "mytable" );
+
+ // Execute a query to make the cursor valid
+ myCursor.select();
+ // Move the cursor to a valid record (the first record)
+ myCursor.next();
+ // Set the form's record pointer to the cursor's edit buffer (which
+ // tqcontains the current record's values)
+ myForm.setRecord( myCursor.primeUpdate() );
+
+ // Insert a field into the form that uses myEditor to edit the
+ // field 'somefield' in 'mytable'
+ myForm.insert( &myEditor, "somefield" );
+
+ // Update myEditor with the value from the mapped database field
+ myForm.readFields();
+ ...
+ // Let the user edit the form
+ ...
+ // Update the database
+ myForm.writeFields(); // Update the cursor's edit buffer from the form
+ myCursor.update(); // Update the database from the cursor's buffer
+ \endcode
+
+ If you want to use custom editors for displaying and editing data
+ fields, you must install a custom TQSqlPropertyMap. The form
+ uses this object to get or set the value of a widget.
+
+ Note that \link designer-manual.book TQt Designer\endlink provides
+ a visual means of creating data-aware forms.
+
+ \sa installPropertyMap(), TQSqlPropertyMap
+*/
+
+
+/*!
+ Constructs a TQSqlForm with tqparent \a tqparent and called \a name.
+*/
+TQSqlForm::TQSqlForm( TQObject * tqparent, const char * name )
+ : TQObject( tqparent, name )
+{
+ d = new TQSqlFormPrivate();
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+TQSqlForm::~TQSqlForm()
+{
+ delete d;
+}
+
+/*!
+ Installs a custom TQSqlPropertyMap. This is useful if you plan to
+ create your own custom editor widgets.
+
+ TQSqlForm takes ownership of \a pmap, so \a pmap is deleted when
+ TQSqlForm goes out of scope.
+
+ \sa TQDataTable::installEditorFactory()
+*/
+void TQSqlForm::installPropertyMap( TQSqlPropertyMap * pmap )
+{
+ if( d->propertyMap )
+ delete d->propertyMap;
+ d->propertyMap = pmap;
+}
+
+/*!
+ Sets \a buf as the record buffer for the form. To force the
+ display of the data from \a buf, use readFields().
+
+ \sa readFields() writeFields()
+*/
+
+void TQSqlForm::setRecord( TQSqlRecord* buf )
+{
+ d->dirty = TRUE;
+ d->buf = buf;
+}
+
+/*!
+ Inserts a \a widget, and the name of the \a field it is to be
+ mapped to, into the form. To actually associate inserted widgets
+ with an edit buffer, use setRecord().
+
+ \sa setRecord()
+*/
+
+void TQSqlForm::insert( TQWidget * widget, const TQString& field )
+{
+ d->dirty = TRUE;
+ d->wgt.insert( field, widget );
+ d->fld += field;
+}
+
+/*!
+ \overload
+
+ Removes \a field from the form.
+*/
+
+void TQSqlForm::remove( const TQString& field )
+{
+ d->dirty = TRUE;
+ if ( d->fld.tqfind( field ) != d->fld.end() )
+ d->fld.remove( d->fld.tqfind( field ) );
+ d->wgt.remove( field );
+}
+
+/*!
+ \overload
+
+ Inserts a \a widget, and the \a field it is to be mapped to, into
+ the form.
+*/
+
+void TQSqlForm::insert( TQWidget * widget, TQSqlField * field )
+{
+ d->map[widget] = field;
+}
+
+/*!
+ Removes a \a widget, and hence the field it's mapped to, from the
+ form.
+*/
+
+void TQSqlForm::remove( TQWidget * widget )
+{
+ d->map.remove( widget );
+}
+
+/*!
+ Clears the values in all the widgets, and the fields they are
+ mapped to, in the form. If \a nullify is TRUE (the default is
+ FALSE), each field is also set to NULL.
+*/
+void TQSqlForm::clearValues( bool nullify )
+{
+ TQMap< TQWidget *, TQSqlField * >::Iterator it;
+ for( it = d->map.begin(); it != d->map.end(); ++it ){
+ TQSqlField* f = (*it);
+ if ( f )
+ f->clear( nullify );
+ }
+ readFields();
+}
+
+/*!
+ Removes every widget, and the fields they're mapped to, from the form.
+*/
+void TQSqlForm::clear()
+{
+ d->dirty = TRUE;
+ d->fld.clear();
+ clearMap();
+}
+
+/*!
+ Returns the number of widgets in the form.
+*/
+uint TQSqlForm::count() const
+{
+ return (uint)d->map.count();
+}
+
+/*!
+ Returns the \a{i}-th widget in the form. Useful for traversing
+ the widgets in the form.
+*/
+TQWidget * TQSqlForm::widget( uint i ) const
+{
+ TQMap< TQWidget *, TQSqlField * >::ConstIterator it;
+ uint cnt = 0;
+
+ if( i > d->map.count() ) return 0;
+ for( it = d->map.begin(); it != d->map.end(); ++it ){
+ if( cnt++ == i )
+ return it.key();
+ }
+ return 0;
+}
+
+/*!
+ Returns the widget that field \a field is mapped to.
+*/
+TQWidget * TQSqlForm::fieldToWidget( TQSqlField * field ) const
+{
+ TQMap< TQWidget *, TQSqlField * >::ConstIterator it;
+ for( it = d->map.begin(); it != d->map.end(); ++it ){
+ if( *it == field )
+ return it.key();
+ }
+ return 0;
+}
+
+/*!
+ Returns the SQL field that widget \a widget is mapped to.
+*/
+TQSqlField * TQSqlForm::widgetToField( TQWidget * widget ) const
+{
+ if( d->map.tqcontains( widget ) )
+ return d->map[widget];
+ else
+ return 0;
+}
+
+/*!
+ Updates the widgets in the form with current values from the SQL
+ fields they are mapped to.
+*/
+void TQSqlForm::readFields()
+{
+ sync();
+ TQSqlField * f;
+ TQMap< TQWidget *, TQSqlField * >::Iterator it;
+ TQSqlPropertyMap * pmap = (d->propertyMap == 0) ?
+ TQSqlPropertyMap::defaultMap() : d->propertyMap;
+ for(it = d->map.begin() ; it != d->map.end(); ++it ){
+ f = widgetToField( it.key() );
+ if( !f )
+ continue;
+ pmap->setProperty( it.key(), f->value() );
+ }
+}
+
+/*!
+ Updates the SQL fields with values from the widgets they are
+ mapped to. To actually update the database with the contents of
+ the record buffer, use TQSqlCursor::insert(), TQSqlCursor::update()
+ or TQSqlCursor::del() as appropriate.
+*/
+void TQSqlForm::writeFields()
+{
+ sync();
+ TQSqlField * f;
+ TQMap< TQWidget *, TQSqlField * >::Iterator it;
+ TQSqlPropertyMap * pmap = (d->propertyMap == 0) ?
+ TQSqlPropertyMap::defaultMap() : d->propertyMap;
+
+ for(it = d->map.begin() ; it != d->map.end(); ++it ){
+ f = widgetToField( it.key() );
+ if( !f )
+ continue;
+ f->setValue( pmap->property( it.key() ) );
+ }
+}
+
+/*!
+ Updates the widget \a widget with the value from the SQL field it
+ is mapped to. Nothing happens if no SQL field is mapped to the \a
+ widget.
+*/
+void TQSqlForm::readField( TQWidget * widget )
+{
+ sync();
+ TQSqlField * field = 0;
+ TQSqlPropertyMap * pmap = (d->propertyMap == 0) ?
+ TQSqlPropertyMap::defaultMap() : d->propertyMap;
+ field = widgetToField( widget );
+ if( field )
+ pmap->setProperty( widget, field->value() );
+}
+
+/*!
+ Updates the SQL field with the value from the \a widget it is
+ mapped to. Nothing happens if no SQL field is mapped to the \a
+ widget.
+*/
+void TQSqlForm::writeField( TQWidget * widget )
+{
+ sync();
+ TQSqlField * field = 0;
+ TQSqlPropertyMap * pmap = (d->propertyMap == 0) ?
+ TQSqlPropertyMap::defaultMap() : d->propertyMap;
+ field = widgetToField( widget );
+ if( field )
+ field->setValue( pmap->property( widget ) );
+}
+
+/*! \internal
+*/
+
+void TQSqlForm::sync()
+{
+ if ( d->dirty ) {
+ clearMap();
+ if ( d->buf ) {
+ for ( uint i = 0; i < d->fld.count(); ++i )
+ insert( d->wgt[ d->fld[ i ] ], d->buf->field( d->fld[ i ] ) );
+ }
+ }
+ d->dirty = FALSE;
+}
+
+/*! \internal
+
+ Clears the internal map of widget/field associations
+*/
+
+void TQSqlForm::clearMap()
+{
+ d->map.clear();
+}
+
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/tqsqlform.h b/tqtinterface/qt4/src/sql/tqsqlform.h
new file mode 100644
index 0000000..14cdca1
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlform.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Definition of TQSqlForm class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLFORM_H
+#define TQSQLFORM_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqmap.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_STQL_FORM
+
+class TQSqlField;
+class TQSqlRecord;
+class TQSqlEditorFactory;
+class TQSqlPropertyMap;
+class TQWidget;
+class TQSqlFormPrivate;
+
+class TQM_EXPORT_SQL TQSqlForm : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQSqlForm( TQObject * tqparent = 0, const char * name = 0 );
+ ~TQSqlForm();
+
+ virtual void insert( TQWidget * widget, const TQString& field );
+ virtual void remove( const TQString& field );
+ uint count() const;
+
+ TQWidget * widget( uint i ) const;
+ TQSqlField * widgetToField( TQWidget * widget ) const;
+ TQWidget * fieldToWidget( TQSqlField * field ) const;
+
+ void installPropertyMap( TQSqlPropertyMap * map );
+
+ virtual void setRecord( TQSqlRecord* buf );
+
+public Q_SLOTS:
+ virtual void readField( TQWidget * widget );
+ virtual void writeField( TQWidget * widget );
+ virtual void readFields();
+ virtual void writeFields();
+
+ virtual void clear();
+ virtual void clearValues( bool nullify = FALSE );
+
+protected:
+ virtual void insert( TQWidget * widget, TQSqlField * field );
+ virtual void remove( TQWidget * widget );
+ void clearMap();
+
+private:
+ virtual void sync();
+ TQSqlFormPrivate* d;
+
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQSqlForm( const TQSqlForm & );
+ TQSqlForm &operator=( const TQSqlForm & );
+#endif
+};
+
+#endif // TQT_NO_SQL
+#endif // TQSQLFORM_H
diff --git a/tqtinterface/qt4/src/sql/tqsqlindex.cpp b/tqtinterface/qt4/src/sql/tqsqlindex.cpp
new file mode 100644
index 0000000..525b1cd
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlindex.cpp
@@ -0,0 +1,301 @@
+/****************************************************************************
+**
+** Implementation of TQSqlIndex class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlindex.h"
+
+#ifndef TQT_NO_SQL
+
+#include "tqsqlcursor.h"
+
+/*!
+ \class TQSqlIndex tqsqlindex.h
+ \brief The TQSqlIndex class provides functions to manipulate and
+ describe TQSqlCursor and TQSqlDatabase indexes.
+
+ \ingroup database
+ \module sql
+
+ This class is used to describe and manipulate TQSqlCursor and
+ TQSqlDatabase indexes. An index refers to a single table or view
+ in a database. Information about the fields that comprise the
+ index can be used to generate SQL statements, or to affect the
+ behavior of a \l TQSqlCursor object.
+
+ Normally, TQSqlIndex objects are created by \l TQSqlDatabase or
+ TQSqlCursor.
+*/
+
+/*!
+ Constructs an empty index using the cursor name \a cursorname and
+ index name \a name.
+*/
+
+TQSqlIndex::TQSqlIndex( const TQString& cursorname, const TQString& name )
+ : TQSqlRecord(), cursor(cursorname), nm(name)
+{
+
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+
+TQSqlIndex::TQSqlIndex( const TQSqlIndex& other )
+ : TQSqlRecord(other), cursor(other.cursor), nm(other.nm), sorts(other.sorts)
+{
+}
+
+/*!
+ Sets the index equal to \a other.
+*/
+
+TQSqlIndex& TQSqlIndex::operator=( const TQSqlIndex& other )
+{
+ cursor = other.cursor;
+ nm = other.nm;
+ sorts = other.sorts;
+ TQSqlRecord::operator=( other );
+ return *this;
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlIndex::~TQSqlIndex()
+{
+
+}
+
+/*!
+ Sets the name of the index to \a name.
+*/
+
+void TQSqlIndex::setName( const TQString& name )
+{
+ nm = name;
+}
+
+/*!
+ \fn TQString TQSqlIndex::name() const
+
+ Returns the name of the index.
+*/
+
+/*!
+ Appends the field \a field to the list of indexed fields. The
+ field is appended with an ascending sort order.
+*/
+
+void TQSqlIndex::append( const TQSqlField& field )
+{
+ append( field, FALSE );
+}
+
+/*!
+ \overload
+
+ Appends the field \a field to the list of indexed fields. The
+ field is appended with an ascending sort order, unless \a desc is
+ TRUE.
+*/
+
+void TQSqlIndex::append( const TQSqlField& field, bool desc )
+{
+ sorts.append( desc );
+ TQSqlRecord::append( field );
+}
+
+
+/*!
+ Returns TRUE if field \a i in the index is sorted in descending
+ order; otherwise returns FALSE.
+*/
+
+bool TQSqlIndex::isDescending( int i ) const
+{
+ if ( sorts.at( i ) != sorts.end() )
+ return sorts[i];
+ return FALSE;
+}
+
+/*!
+ If \a desc is TRUE, field \a i is sorted in descending order.
+ Otherwise, field \a i is sorted in ascending order (the default).
+ If the field does not exist, nothing happens.
+*/
+
+void TQSqlIndex::setDescending( int i, bool desc )
+{
+ if ( sorts.at( i ) != sorts.end() )
+ sorts[i] = desc;
+}
+
+/*!
+ \reimp
+
+ Returns a comma-separated list of all the index's field names as a
+ string. This string is suitable, for example, for generating a
+ SQL SELECT statement. Only generated fields are included in the
+ list (see \l{isGenerated()}). If a \a prefix is specified, e.g. a
+ table name, it is prepended before all field names in the form:
+
+ "\a{prefix}.<fieldname>"
+
+ If \a sep is specified, each field is separated by \a sep. If \a
+ verbose is TRUE (the default), each field tqcontains a suffix
+ indicating an ASCending or DESCending sort order.
+*/
+
+TQString TQSqlIndex::toString( const TQString& prefix, const TQString& sep, bool verbose ) const
+{
+ TQString s;
+ bool comma = FALSE;
+ for ( uint i = 0; i < count(); ++i ) {
+ if( comma )
+ s += sep + " ";
+ s += createField( i, prefix, verbose );
+ comma = TRUE;
+ }
+ return s;
+}
+
+/*!
+ \reimp
+
+ Returns a list of all the index's field names. Only generated
+ fields are included in the list (see \l{isGenerated()}). If a \a
+ prefix is specified, e.g. a table name, all fields are prefixed in
+ the form:
+
+ "\a{prefix}.<fieldname>"
+
+ If \a verbose is TRUE (the default), each field tqcontains a suffix
+ indicating an ASCending or DESCending sort order.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myIndex.toStringList();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+*/
+TQStringList TQSqlIndex::toStringList( const TQString& prefix, bool verbose ) const
+{
+ TQStringList s;
+ for ( uint i = 0; i < count(); ++i )
+ s += createField( i, prefix, verbose );
+ return s;
+}
+
+/*! \internal
+
+ Creates a string representing the field number \a i using prefix \a
+ prefix. If \a verbose is TRUE, ASC or DESC is included in the field
+ description if the field is sorted in ASCending or DESCending order.
+*/
+
+TQString TQSqlIndex::createField( int i, const TQString& prefix, bool verbose ) const
+{
+ TQString f;
+ if ( !prefix.isEmpty() )
+ f += prefix + ".";
+ f += field( i )->name();
+ if ( verbose )
+ f += " " + TQString( ( isDescending( i ) ? "DESC" : "ASC" ) );
+ return f;
+}
+
+/*!
+ Returns an index based on the field descriptions in \a l and the
+ cursor \a cursor. The field descriptions should be in the same
+ format that toStringList() produces, for example, a surname field
+ in the people table might be in one of these forms: "surname",
+ "surname DESC" or "people.surname ASC".
+
+ \sa toStringList()
+*/
+
+TQSqlIndex TQSqlIndex::fromStringList( const TQStringList& l, const TQSqlCursor* cursor )
+{
+ TQSqlIndex newSort;
+ for ( uint i = 0; i < l.count(); ++i ) {
+ TQString f = l[ i ];
+ bool desc = FALSE;
+ if ( f.mid( f.length()-3 ) == "ASC" )
+ f = f.mid( 0, f.length()-3 );
+ if ( f.mid( f.length()-4 ) == "DESC" ) {
+ desc = TRUE;
+ f = f.mid( 0, f.length()-4 );
+ }
+ int dot = f.tqfindRev( '.' );
+ if ( dot != -1 )
+ f = f.mid( dot+1 );
+ const TQSqlField* field = cursor->field( f.simplifyWhiteSpace() );
+ if ( field )
+ newSort.append( *field, desc );
+ else
+ qWarning( "TQSqlIndex::fromStringList: unknown field: '%s'", f.latin1());
+ }
+ return newSort;
+}
+
+/*!
+ \fn TQString TQSqlIndex::cursorName() const
+
+ Returns the name of the cursor which the index is associated with.
+*/
+
+
+/*!
+ Sets the name of the cursor that the index is associated with to
+ \a cursorName.
+*/
+void TQSqlIndex::setCursorName( const TQString& cursorName )
+{
+ cursor = cursorName;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlindex.h b/tqtinterface/qt4/src/sql/tqsqlindex.h
new file mode 100644
index 0000000..4f22cd4
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlindex.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Definition of TQSqlIndex class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLINDEX_H
+#define TQSQLINDEX_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqstringlist.h"
+#include "tqsqlfield.h"
+#include "tqsqlrecord.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#define TQM_TEMPLATE_EXTERN_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#define TQM_TEMPLATE_EXTERN_SQL TQ_TEMPLATE_EXTERN
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQSqlCursor;
+
+class TQM_EXPORT_SQL TQSqlIndex : public TQSqlRecord
+{
+public:
+ TQSqlIndex( const TQString& cursorName = TQString::null, const TQString& name = TQString::null );
+ TQSqlIndex( const TQSqlIndex& other );
+ ~TQSqlIndex();
+ TQSqlIndex& operator=( const TQSqlIndex& other );
+ virtual void setCursorName( const TQString& cursorName );
+ TQString cursorName() const { return cursor; }
+ virtual void setName( const TQString& name );
+ TQString name() const { return nm; }
+
+ void append( const TQSqlField& field );
+ virtual void append( const TQSqlField& field, bool desc );
+
+ bool isDescending( int i ) const;
+ virtual void setDescending( int i, bool desc );
+
+ TQString toString( const TQString& prefix = TQString::null,
+ const TQString& sep = ",",
+ bool verbose = TRUE ) const;
+ TQStringList toStringList( const TQString& prefix = TQString::null,
+ bool verbose = TRUE ) const;
+
+ static TQSqlIndex fromStringList( const TQStringList& l, const TQSqlCursor* cursor );
+
+private:
+ TQString createField( int i, const TQString& prefix, bool verbose ) const;
+ TQString cursor;
+ TQString nm;
+ TQValueList<bool> sorts;
+};
+
+#define TQ_DEFINED_TQSQLINDEX
+#include "tqwinexport.h"
+#endif // TQT_NO_SQL
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlmanager_p.cpp b/tqtinterface/qt4/src/sql/tqsqlmanager_p.cpp
new file mode 100644
index 0000000..8412c94
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlmanager_p.cpp
@@ -0,0 +1,941 @@
+/****************************************************************************
+**
+** Implementation of sql manager classes
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlmanager_p.h"
+
+#ifndef TQT_NO_SQL
+
+#include "tqapplication.h"
+#include "tqwidget.h"
+#include "tqsqlcursor.h"
+#include "tqsqlform.h"
+#include "tqsqldriver.h"
+#include "tqstring.h"
+#include "tqmessagebox.h"
+#include "tqbitarray.h"
+
+//#define TQT_DEBUG_DATAMANAGER
+
+class TQSqlCursorManagerPrivate
+{
+public:
+ TQSqlCursorManagerPrivate()
+ : cur( 0 ), autoDelete( FALSE )
+ {}
+
+ TQString ftr;
+ TQStringList srt;
+ TQSqlCursor* cur;
+ bool autoDelete;
+};
+
+/*!
+ \class TQSqlCursorManager qsqlmanager_p.h
+ \brief The TQSqlCursorManager class manages a database cursor.
+
+ \module sql
+
+ \internal
+
+ This class provides common cursor management functionality. This
+ includes saving and applying sorts and filters, refreshing (i.e.,
+ re-selecting) the cursor and searching for records within the
+ cursor.
+
+*/
+
+/*! \internal
+
+ Constructs a cursor manager.
+
+*/
+
+TQSqlCursorManager::TQSqlCursorManager()
+{
+ d = new TQSqlCursorManagerPrivate;
+}
+
+
+/*! \internal
+
+ Destroys the object and frees any allocated resources.
+
+*/
+
+TQSqlCursorManager::~TQSqlCursorManager()
+{
+ if ( d->autoDelete )
+ delete d->cur;
+ delete d;
+}
+
+/*! \internal
+
+ Sets the manager's sort to the index \a sort. To apply the new
+ sort, use refresh().
+
+ */
+
+void TQSqlCursorManager::setSort( const TQSqlIndex& sort )
+{
+ setSort( sort.toStringList() );
+}
+
+/*! \internal
+
+ Sets the manager's sort to the stringlist \a sort. To apply the
+ new sort, use refresh().
+
+ */
+
+void TQSqlCursorManager::setSort( const TQStringList& sort )
+{
+ d->srt = sort;
+}
+
+/*! \internal
+
+ Returns the current sort, or an empty stringlist if there is none.
+
+*/
+
+TQStringList TQSqlCursorManager::sort() const
+{
+ return d->srt;
+}
+
+/*! \internal
+
+ Sets the manager's filter to the string \a filter. To apply the
+ new filter, use refresh().
+
+*/
+
+void TQSqlCursorManager::setFilter( const TQString& filter )
+{
+ d->ftr = filter;
+}
+
+/*! \internal
+
+ Returns the current filter, or an empty string if there is none.
+
+*/
+
+TQString TQSqlCursorManager::filter() const
+{
+ return d->ftr;
+}
+
+/*! \internal
+
+ Sets auto-delete to \a enable. If TRUE, the default cursor will
+ be deleted when necessary.
+
+ \sa autoDelete()
+*/
+
+void TQSqlCursorManager::setAutoDelete( bool enable )
+{
+ d->autoDelete = enable;
+}
+
+
+/*! \internal
+
+ Returns TRUE if auto-deletion is enabled, otherwise FALSE.
+
+ \sa setAutoDelete()
+
+*/
+
+bool TQSqlCursorManager::autoDelete() const
+{
+ return d->autoDelete;
+}
+
+/*! \internal
+
+ Sets the default cursor used by the manager to \a cursor. If \a
+ autoDelete is TRUE (the default is FALSE), the manager takes
+ ownership of the \a cursor pointer, which will be deleted when the
+ manager is destroyed, or when setCursor() is called again. To
+ activate the \a cursor use refresh().
+
+ \sa cursor()
+
+*/
+
+void TQSqlCursorManager::setCursor( TQSqlCursor* cursor, bool autoDelete )
+{
+ if ( d->autoDelete )
+ delete d->cur;
+ d->cur = cursor;
+ d->autoDelete = autoDelete;
+}
+
+/*! \internal
+
+ Returns a pointer to the default cursor used for navigation, or 0
+ if there is no default cursor.
+
+ \sa setCursor()
+
+*/
+
+TQSqlCursor* TQSqlCursorManager::cursor() const
+{
+ return d->cur;
+}
+
+
+/*! \internal
+
+ Refreshes the manager using the default cursor. The manager's
+ filter and sort are applied. Returns TRUE on success, FALSE if an
+ error occurred or there is no current cursor.
+
+ \sa setFilter() setSort()
+
+*/
+
+bool TQSqlCursorManager::refresh()
+{
+ TQSqlCursor* cur = cursor();
+ if ( !cur )
+ return FALSE;
+ TQString currentFilter = d->ftr;
+ TQStringList currentSort = d->srt;
+ TQSqlIndex newSort = TQSqlIndex::fromStringList( currentSort, cur );
+ return cur->select( currentFilter, newSort );
+}
+
+/* \internal
+
+ Returns TRUE if the \a buf field values that correspond to \a idx
+ match the field values in \a cur that correspond to \a idx.
+*/
+
+static bool index_matches( const TQSqlCursor* cur, const TQSqlRecord* buf,
+ const TQSqlIndex& idx )
+{
+ bool indexEquals = FALSE;
+ for ( uint i = 0; i < idx.count(); ++i ) {
+ const TQString fn( idx.field(i)->name() );
+ if ( cur->value( fn ) == buf->value( fn ) )
+ indexEquals = TRUE;
+ else {
+ indexEquals = FALSE;
+ break;
+ }
+ }
+ return indexEquals;
+}
+
+/*
+ Return less than, equal to or greater than 0 if buf1 is less than,
+ equal to or greater than buf2 according to fields described in idx.
+ (### Currently only uses first field.)
+*/
+
+static int compare_recs( const TQSqlRecord* buf1, const TQSqlRecord* buf2,
+ const TQSqlIndex& idx )
+{
+ int cmp = 0;
+
+ int i = 0;
+ const TQString fn( idx.field(i)->name() );
+ const TQSqlField* f1 = buf1->field( fn );
+
+ if ( f1 ) {
+ switch ( f1->type() ) { // ### more types?
+ case TQVariant::String:
+ case TQVariant::CString:
+ cmp = TQT_TQSTRING(f1->value().toString()).simplifyWhiteSpace().compare(
+ TQT_TQSTRING(buf2->value(fn).toString()).simplifyWhiteSpace() );
+ break;
+ default:
+ if ( f1->value().toDouble() < buf2->value( fn ).toDouble() )
+ cmp = -1;
+ else if ( f1->value().toDouble() > buf2->value( fn ).toDouble() )
+ cmp = 1;
+ }
+ }
+
+ if ( idx.isDescending(i) )
+ cmp = -cmp;
+ return cmp;
+}
+
+#ifdef TQT_DEBUG_DATAMANAGER
+static void debug_datamanager_buffer( const TQString& msg, TQSqlRecord* cursor )
+{
+ qDebug("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+ qDebug( "%s", msg.latin1() );
+ for ( uint j = 0; j < cursor->count(); ++j ) {
+ qDebug( "%s", (cursor->field(j)->name() + " type:"
+ + TQString(cursor->field(j)->value().typeName())
+ + " value:" + cursor->field(j)->value().toString())
+ .latin1() );
+ }
+}
+#endif
+
+
+/*! \internal
+
+ Relocates the default cursor to the record matching the cursor's
+edit buffer. Only the field names specified by \a idx are used to
+determine an exact match of the cursor to the edit buffer. However,
+other fields in the edit buffer are also used during the search,
+therefore all fields in the edit buffer should be primed with desired
+values for the record being sought. This function is typically used
+to relocate a cursor to the correct position after an insert or
+update. For example:
+
+\code
+ TQSqlCursor* myCursor = myManager.cursor();
+ ...
+ TQSqlRecord* buf = myCursor->primeUpdate();
+ buf->setValue( "name", "Ola" );
+ buf->setValue( "city", "Oslo" );
+ ...
+ myCursor->update(); // update current record
+ myCursor->select(); // refresh the cursor
+ myManager.tqfindBuffer( myCursor->primaryIndex() ); // go to the updated record
+\endcode
+
+*/
+
+//## possibly add tqsizeHint parameter
+bool TQSqlCursorManager::tqfindBuffer( const TQSqlIndex& idx, int atHint )
+{
+#ifdef TQT_DEBUG_DATAMANAGER
+ qDebug("TQSqlCursorManager::tqfindBuffer:");
+#endif
+ TQSqlCursor* cur = cursor();
+ if ( !cur )
+ return FALSE;
+ if ( !cur->isActive() )
+ return FALSE;
+ if ( !idx.count() ) {
+ if ( cur->at() == TQSql::BeforeFirst )
+ cur->next();
+ return FALSE;
+ }
+ TQSqlRecord* buf = cur->editBuffer();
+ bool indexEquals = FALSE;
+#ifdef TQT_DEBUG_DATAMANAGER
+ qDebug(" Checking hint...");
+#endif
+ /* check the hint */
+ if ( cur->seek( atHint ) )
+ indexEquals = index_matches( cur, buf, idx );
+
+ if ( !indexEquals ) {
+#ifdef TQT_DEBUG_DATAMANAGER
+ qDebug(" Checking current page...");
+#endif
+ /* check current page */
+ int pageSize = 20;
+ int startIdx = TQMAX( atHint - pageSize, 0 );
+ int endIdx = atHint + pageSize;
+ for ( int j = startIdx; j <= endIdx; ++j ) {
+ if ( cur->seek( j ) ) {
+ indexEquals = index_matches( cur, buf, idx );
+ if ( indexEquals )
+ break;
+ }
+ }
+ }
+
+ if ( !indexEquals && cur->driver()->hasFeature( TQSqlDriver::QuerySize )
+ && cur->sort().count() ) {
+#ifdef TQT_DEBUG_DATAMANAGER
+ qDebug(" Using binary search...");
+#endif
+ // binary search based on record buffer and current sort fields
+ int lo = 0;
+ int hi = cur->size();
+ int mid;
+ if ( compare_recs( buf, cur, cur->sort() ) >= 0 )
+ lo = cur->at();
+ while ( lo != hi ) {
+ mid = lo + (hi - lo) / 2;
+ if ( !cur->seek( mid ) )
+ break;
+ if ( index_matches( cur, buf, idx ) ) {
+ indexEquals = TRUE;
+ break;
+ }
+ int c = compare_recs( buf, cur, cur->sort() );
+ if ( c < 0 ) {
+ hi = mid;
+ } else if ( c == 0 ) {
+ // found it, but there may be duplicates
+ int at = mid;
+ do {
+ mid--;
+ if ( !cur->seek( mid ) )
+ break;
+ if ( index_matches( cur, buf, idx ) ) {
+ indexEquals = TRUE;
+ break;
+ }
+ } while ( compare_recs( buf, cur, cur->sort() ) == 0 );
+
+ if ( !indexEquals ) {
+ mid = at;
+ do {
+ mid++;
+ if ( !cur->seek( mid ) )
+ break;
+ if ( index_matches( cur, buf, idx ) ) {
+ indexEquals = TRUE;
+ break;
+ }
+ } while ( compare_recs( buf, cur, cur->sort() ) == 0 );
+ }
+ break;
+ } else if ( c > 0 ) {
+ lo = mid + 1;
+ }
+ }
+ }
+
+ if ( !indexEquals ) {
+#ifdef TQT_DEBUG_DATAMANAGER
+ qDebug(" Using brute search...");
+#endif
+#ifndef TQT_NO_CURSOR
+ TQApplication::setOverrideCursor( TQt::WaitCursor );
+#endif
+ /* give up, use brute force */
+ int startIdx = 0;
+ if ( cur->at() != startIdx ) {
+ cur->seek( startIdx );
+ }
+ for ( ;; ) {
+ indexEquals = FALSE;
+ indexEquals = index_matches( cur, buf, idx );
+ if ( indexEquals )
+ break;
+ if ( !cur->next() )
+ break;
+ }
+#ifndef TQT_NO_CURSOR
+ TQApplication::restoreOverrideCursor();
+#endif
+ }
+#ifdef TQT_DEBUG_DATAMANAGER
+ qDebug(" Done, result:" + TQString::number( indexEquals ) );
+#endif
+ return indexEquals;
+}
+
+#ifndef TQT_NO_STQL_FORM
+
+class TQSqlFormManagerPrivate
+{
+public:
+ TQSqlFormManagerPrivate() : frm(0), rcd(0) {}
+ TQSqlForm* frm;
+ TQSqlRecord* rcd;
+};
+
+
+/*! \internal
+
+ Creates a form manager.
+
+*/
+
+TQSqlFormManager::TQSqlFormManager()
+{
+ d = new TQSqlFormManagerPrivate();
+}
+
+/*! \internal
+
+ Destroys the object and frees any allocated resources.
+
+*/
+
+TQSqlFormManager::~TQSqlFormManager()
+{
+ delete d;
+}
+
+/*! \internal
+
+ Clears the default form values. If there is no default form,
+ nothing happens,
+
+*/
+
+void TQSqlFormManager::clearValues()
+{
+ if ( form() )
+ form()->clearValues();
+}
+
+/*! \internal
+
+ Sets the form used by the form manager to \a form. If a record has
+ already been assigned to the form manager, that record is also used by
+ the \a form to display data.
+
+ \sa form()
+
+*/
+
+void TQSqlFormManager::setForm( TQSqlForm* form )
+{
+ d->frm = form;
+ if ( d->rcd && d->frm )
+ d->frm->setRecord( d->rcd );
+}
+
+
+/*! \internal
+
+ Returns the default form used by the form manager, or 0 if there is
+ none.
+
+ \sa setForm()
+
+*/
+
+TQSqlForm* TQSqlFormManager::form()
+{
+ return d->frm;
+}
+
+
+/*! \internal
+
+ Sets the record used by the form manager to \a record. If a form has
+ already been assigned to the form manager, \a record is also used by
+ the default form to display data.
+
+ \sa record()
+
+*/
+
+void TQSqlFormManager::setRecord( TQSqlRecord* record )
+{
+ d->rcd = record;
+ if ( d->frm ) {
+ d->frm->setRecord( d->rcd );
+ }
+}
+
+
+/*! \internal
+
+ Returns the default record used by the form manager, or 0 if there is
+ none.
+
+ \sa setRecord()
+*/
+
+TQSqlRecord* TQSqlFormManager::record()
+{
+ return d->rcd;
+}
+
+
+/*! \internal
+
+ Causes the default form to read its fields . If there is no
+ default form, nothing happens.
+
+ \sa setForm()
+
+*/
+
+void TQSqlFormManager::readFields()
+{
+ if ( d->frm ) {
+ d->frm->readFields();
+ }
+}
+
+/*! \internal
+
+ Causes the default form to write its fields . If there is no
+ default form, nothing happens.
+
+ \sa setForm()
+
+*/
+
+void TQSqlFormManager::writeFields()
+{
+ if ( d->frm ) {
+ d->frm->writeFields();
+ }
+}
+
+#endif // TQT_NO_STQL_FORM
+
+class TQDataManagerPrivate
+{
+public:
+ TQDataManagerPrivate()
+ : mode( TQSql::None ), autoEd( TRUE ), confEdits( 3 ),
+ confCancs( FALSE ) {}
+ TQSql::Op mode;
+ bool autoEd;
+ TQBitArray confEdits;
+ bool confCancs;
+
+};
+
+/*!
+ \class TQDataManager qsqlmanager_p.h
+ \ingroup database
+
+ \brief The TQDataManager class is an internal class for implementing
+ the data-aware widgets.
+
+ \internal
+
+ TQDataManager is a strictly internal class that acts as a base class
+ for other data-aware widgets.
+
+*/
+
+
+/*! \internal
+
+ Constructs an empty data handler.
+
+*/
+
+TQDataManager::TQDataManager()
+{
+ d = new TQDataManagerPrivate();
+}
+
+
+/*! \internal
+
+ Destroys the object and frees any allocated resources.
+
+*/
+
+TQDataManager::~TQDataManager()
+{
+ delete d;
+}
+
+
+/*! \internal
+
+ Virtual function which is called when an error has occurred The
+ default implementation displays a warning message to the user with
+ information about the error.
+
+*/
+void TQDataManager::handleError( TQWidget* tqparent, const TQSqlError& e )
+{
+#ifndef TQT_NO_MESSAGEBOX
+ if (e.driverText().isEmpty() && e.databaseText().isEmpty()) {
+ TQMessageBox::warning ( tqparent, "Warning", "An error occurred while accessing the database");
+ } else {
+ TQMessageBox::warning ( tqparent, "Warning", e.driverText() + "\n" + e.databaseText(),
+ 0, 0 );
+ }
+#endif // TQT_NO_MESSAGEBOX
+}
+
+
+/*! \internal
+
+ Sets the internal mode to \a m.
+
+*/
+
+void TQDataManager::setMode( TQSql::Op m )
+{
+ d->mode = m;
+}
+
+
+/*! \internal
+
+ Returns the current mode.
+
+*/
+
+TQSql::Op TQDataManager::mode() const
+{
+ return d->mode;
+}
+
+
+/*! \internal
+
+ Sets the auto-edit mode to \a auto.
+
+*/
+
+void TQDataManager::setAutoEdit( bool autoEdit )
+{
+ d->autoEd = autoEdit;
+}
+
+
+
+/*! \internal
+
+ Returns TRUE if auto-edit mode is enabled; otherwise returns FALSE.
+
+*/
+
+bool TQDataManager::autoEdit() const
+{
+ return d->autoEd;
+}
+
+/*! \internal
+
+ If \a confirm is TRUE, all edit operations (inserts, updates and
+ deletes) will be confirmed by the user. If \a confirm is FALSE (the
+ default), all edits are posted to the database immediately.
+
+*/
+void TQDataManager::setConfirmEdits( bool confirm )
+{
+ d->confEdits.fill( confirm );
+}
+
+/*! \internal
+
+ If \a confirm is TRUE, all inserts will be confirmed by the user.
+ If \a confirm is FALSE (the default), all edits are posted to the
+ database immediately.
+
+*/
+
+void TQDataManager::setConfirmInsert( bool confirm )
+{
+ d->confEdits[ TQSql::Insert ] = confirm;
+}
+
+/*! \internal
+
+ If \a confirm is TRUE, all updates will be confirmed by the user.
+ If \a confirm is FALSE (the default), all edits are posted to the
+ database immediately.
+
+*/
+
+void TQDataManager::setConfirmUpdate( bool confirm )
+{
+ d->confEdits[ TQSql::Update ] = confirm;
+}
+
+/*! \internal
+
+ If \a confirm is TRUE, all deletes will be confirmed by the user.
+ If \a confirm is FALSE (the default), all edits are posted to the
+ database immediately.
+
+*/
+
+void TQDataManager::setConfirmDelete( bool confirm )
+{
+ d->confEdits[ TQSql::Delete ] = confirm;
+}
+
+/*! \internal
+
+ Returns TRUE if the table confirms all edit operations (inserts,
+ updates and deletes), otherwise returns FALSE.
+*/
+
+bool TQDataManager::confirmEdits() const
+{
+ return ( confirmInsert() && confirmUpdate() && confirmDelete() );
+}
+
+/*! \internal
+
+ Returns TRUE if the table confirms inserts, otherwise returns
+ FALSE.
+*/
+
+bool TQDataManager::confirmInsert() const
+{
+ return d->confEdits[ TQSql::Insert ];
+}
+
+/*! \internal
+
+ Returns TRUE if the table confirms updates, otherwise returns
+ FALSE.
+*/
+
+bool TQDataManager::confirmUpdate() const
+{
+ return d->confEdits[ TQSql::Update ];
+}
+
+/*! \internal
+
+ Returns TRUE if the table confirms deletes, otherwise returns
+ FALSE.
+*/
+
+bool TQDataManager::confirmDelete() const
+{
+ return d->confEdits[ TQSql::Delete ];
+}
+
+/*! \internal
+
+ If \a confirm is TRUE, all cancels will be confirmed by the user
+ through a message box. If \a confirm is FALSE (the default), all
+ cancels occur immediately.
+*/
+
+void TQDataManager::setConfirmCancels( bool confirm )
+{
+ d->confCancs = confirm;
+}
+
+/*! \internal
+
+ Returns TRUE if the table confirms cancels, otherwise returns FALSE.
+*/
+
+bool TQDataManager::confirmCancels() const
+{
+ return d->confCancs;
+}
+
+/*! \internal
+
+ Virtual function which returns a confirmation for an edit of mode \a
+ m. Derived classes can reimplement this function and provide their
+ own confirmation dialog. The default implementation uses a message
+ box which prompts the user to confirm the edit action. The dialog
+ is centered over \a tqparent.
+
+*/
+
+TQSql::Confirm TQDataManager::confirmEdit( TQWidget* tqparent, TQSql::Op m )
+{
+ int ans = 2;
+ if ( m == TQSql::Delete ) {
+#ifndef TQT_NO_MESSAGEBOX
+ ans = TQMessageBox::information( tqparent,
+ tqApp->translate( "TQSql", "Delete" ),
+ tqApp->translate( "TQSql", "Delete this record?" ),
+ tqApp->translate( "TQSql", "Yes" ),
+ tqApp->translate( "TQSql", "No" ),
+ TQString::null, 0, 1 );
+#else
+ ans = TQSql::No;
+#endif // TQT_NO_MESSAGEBOX
+ } else if ( m != TQSql::None ) {
+ TQString caption;
+ if ( m == TQSql::Insert ) {
+ caption = tqApp->translate( "TQSql", "Insert" );
+ } else { // TQSql::Update
+ caption = tqApp->translate( "TQSql", "Update" );
+ }
+#ifndef TQT_NO_MESSAGEBOX
+ ans = TQMessageBox::information( tqparent, caption,
+ tqApp->translate( "TQSql", "Save edits?" ),
+ tqApp->translate( "TQSql", "Yes" ),
+ tqApp->translate( "TQSql", "No" ),
+ tqApp->translate( "TQSql", "Cancel" ),
+ 0, 2 );
+#else
+ ans = TQSql::No;
+#endif // TQT_NO_MESSAGEBOX
+ }
+
+ switch ( ans ) {
+ case 0:
+ return TQSql::Yes;
+ case 1:
+ return TQSql::No;
+ default:
+ return TQSql::Cancel;
+ }
+}
+
+/*! \internal
+
+ Virtual function which returns a confirmation for cancelling an edit
+ mode \a m. Derived classes can reimplement this function and
+ provide their own confirmation dialog. The default implementation
+ uses a message box which prompts the user to confirm the edit
+ action. The dialog is centered over \a tqparent.
+
+
+*/
+
+TQSql::Confirm TQDataManager::confirmCancel( TQWidget* tqparent, TQSql::Op )
+{
+#ifndef TQT_NO_MESSAGEBOX
+ switch ( TQMessageBox::information( tqparent,
+ tqApp->translate( "TQSql", "Confirm" ),
+ tqApp->translate( "TQSql", "Cancel your edits?" ),
+ tqApp->translate( "TQSql", "Yes" ),
+ tqApp->translate( "TQSql", "No" ),
+ TQString::null, 0, 1 ) ) {
+ case 0:
+ return TQSql::Yes;
+ case 1:
+ return TQSql::No;
+ default:
+ return TQSql::Cancel;
+ }
+#else
+ return TQSql::Yes;
+#endif // TQT_NO_MESSAGEBOX
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlmanager_p.h b/tqtinterface/qt4/src/sql/tqsqlmanager_p.h
new file mode 100644
index 0000000..9f19335
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlmanager_p.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Definition of TQSqlManager class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLMANAGER_P_H
+#define TQSQLMANAGER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of other TQt classes. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqstring.h"
+#include "tqstringlist.h"
+#include "tqsql.h"
+#include "tqsqlerror.h"
+#include "tqsqlindex.h"
+#include "tqsqlcursor.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQSqlCursor;
+class TQSqlForm;
+class TQSqlCursorManagerPrivate;
+
+class TQM_EXPORT_SQL TQSqlCursorManager
+{
+public:
+ TQSqlCursorManager();
+ virtual ~TQSqlCursorManager();
+
+ virtual void setSort( const TQSqlIndex& sort );
+ virtual void setSort( const TQStringList& sort );
+ TQStringList sort() const;
+ virtual void setFilter( const TQString& filter );
+ TQString filter() const;
+ virtual void setCursor( TQSqlCursor* cursor, bool autoDelete = FALSE );
+ TQSqlCursor* cursor() const;
+
+ virtual void setAutoDelete( bool enable );
+ bool autoDelete() const;
+
+ virtual bool refresh();
+ virtual bool tqfindBuffer( const TQSqlIndex& idx, int atHint = 0 );
+
+private:
+ TQSqlCursorManagerPrivate* d;
+};
+
+#ifndef TQT_NO_STQL_FORM
+
+class TQSqlFormManagerPrivate;
+
+class TQM_EXPORT_SQL TQSqlFormManager
+{
+public:
+ TQSqlFormManager();
+ virtual ~TQSqlFormManager();
+
+ virtual void setForm( TQSqlForm* form );
+ TQSqlForm* form();
+ virtual void setRecord( TQSqlRecord* record );
+ TQSqlRecord* record();
+
+ virtual void clearValues();
+ virtual void readFields();
+ virtual void writeFields();
+
+private:
+ TQSqlFormManagerPrivate* d;
+};
+
+#endif
+
+class TQWidget;
+class TQDataManagerPrivate;
+
+class TQM_EXPORT_SQL TQDataManager
+{
+public:
+ TQDataManager();
+ virtual ~TQDataManager();
+
+ virtual void setMode( TQSql::Op m );
+ TQSql::Op mode() const;
+ virtual void setAutoEdit( bool autoEdit );
+ bool autoEdit() const;
+
+ virtual void handleError( TQWidget* tqparent, const TQSqlError& error );
+ virtual TQSql::Confirm confirmEdit( TQWidget* tqparent, TQSql::Op m );
+ virtual TQSql::Confirm confirmCancel( TQWidget* tqparent, TQSql::Op m );
+
+ virtual void setConfirmEdits( bool confirm );
+ virtual void setConfirmInsert( bool confirm );
+ virtual void setConfirmUpdate( bool confirm );
+ virtual void setConfirmDelete( bool confirm );
+ virtual void setConfirmCancels( bool confirm );
+
+ bool confirmEdits() const;
+ bool confirmInsert() const;
+ bool confirmUpdate() const;
+ bool confirmDelete() const;
+ bool confirmCancels() const;
+
+private:
+ TQDataManagerPrivate* d;
+};
+
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlpropertymap.cpp b/tqtinterface/qt4/src/sql/tqsqlpropertymap.cpp
new file mode 100644
index 0000000..63b7e3a
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlpropertymap.cpp
@@ -0,0 +1,304 @@
+/****************************************************************************
+**
+** Definition of TQSqlPropertyMap class
+**
+** Created : 2000-11-20
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlpropertymap.h"
+
+#ifndef TQT_NO_STQL_FORM
+
+#include "tqwidget.h"
+#include "tqcleanuphandler.h"
+#include "tqmetaobject.h"
+#include "tqmap.h"
+
+class TQSqlPropertyMapPrivate
+{
+public:
+ TQSqlPropertyMapPrivate() {}
+ TQMap< TQString, TQString > propertyMap;
+};
+
+/*!
+ \class TQSqlPropertyMap tqsqlpropertymap.h
+ \brief The TQSqlPropertyMap class is used to map widgets to SQL fields.
+
+ \ingroup database
+ \module sql
+
+ The SQL module uses TQt \link properties.html object
+ properties\endlink to insert and extract values from editor
+ widgets.
+
+ This class is used to map editors to SQL fields. This works by
+ associating SQL editor class names to the properties used to
+ insert and extract values to/from the editor.
+
+ For example, a TQLineEdit can be used to edit text strings and
+ other data types in TQDataTables or TQSqlForms. Several properties
+ are defined in TQLineEdit, but only the \e text property is used to
+ insert and extract text from a TQLineEdit. Both TQDataTable and
+ TQSqlForm use the global TQSqlPropertyMap for inserting and
+ extracting values to and from an editor widget. The global
+ property map defines several common widgets and properties that
+ are suitable for many applications. You can add and remove widget
+ properties to suit your specific needs.
+
+ If you want to use custom editors with your TQDataTable or
+ TQSqlForm, you must install your own TQSqlPropertyMap for that table
+ or form. Example:
+
+ \code
+ TQSqlPropertyMap *myMap = new TQSqlPropertyMap();
+ TQSqlForm *myForm = new TQSqlForm( this );
+ MyEditor myEditor( this );
+
+ // Set the TQSqlForm's record buffer to the update buffer of
+ // a pre-existing TQSqlCursor called 'cur'.
+ myForm->setRecord( cur->primeUpdate() );
+
+ // Install the customized map
+ myMap->insert( "MyEditor", "content" );
+ myForm->installPropertyMap( myMap ); // myForm now owns myMap
+ ...
+ // Insert a field into the form that uses a myEditor to edit the
+ // field 'somefield'
+ myForm->insert( &myEditor, "somefield" );
+
+ // Update myEditor with the value from the mapped database field
+ myForm->readFields();
+ ...
+ // Let the user edit the form
+ ...
+ // Update the database fields with the values in the form
+ myForm->writeFields();
+ ...
+ \endcode
+
+ You can also tqreplace the global TQSqlPropertyMap that is used by
+ default. (Bear in mind that TQSqlPropertyMap takes ownership of the
+ new default map.)
+
+ \code
+ TQSqlPropertyMap *myMap = new TQSqlPropertyMap;
+
+ myMap->insert( "MyEditor", "content" );
+ TQSqlPropertyMap::installDefaultMap( myMap );
+ ...
+ \endcode
+
+ \sa TQDataTable, TQSqlForm, TQSqlEditorFactory
+*/
+
+/*!
+
+Constructs a TQSqlPropertyMap.
+
+The default property mappings used by TQt widgets are:
+\table
+\header \i Widgets \i Property
+\row \i \l TQCheckBox,
+ \l TQRadioButton
+ \i checked
+\row \i \l TQComboBox,
+ \l TQListBox
+ \i currentItem
+\row \i \l TQDateEdit
+ \i date
+\row \i \l TQDateTimeEdit
+ \i dateTime
+\row \i \l TQTextBrowser
+ \i source
+\row \i \l TQButton,
+ \l TQDial,
+ \l TQLabel,
+ \l TQLineEdit,
+ \l TQMultiLineEdit,
+ \l TQPushButton,
+ \l TQTextEdit,
+ \i text
+\row \i \l TQTimeEdit
+ \i time
+\row \i \l TQLCDNumber,
+ \l TQScrollBar
+ \l TQSlider,
+ \l TQSpinBox
+ \i value
+\endtable
+*/
+
+TQSqlPropertyMap::TQSqlPropertyMap()
+{
+ d = new TQSqlPropertyMapPrivate();
+ const struct MapData {
+ const char *classname;
+ const char *property;
+ } mapData[] = {
+ { "TQButton", "text" },
+ { "TQCheckBox", "checked" },
+ { "TQRadioButton", "checked" },
+ { "TQComboBox", "currentItem" },
+ { "TQDateEdit", "date" },
+ { "TQDateTimeEdit", "dateTime" },
+ { "TQDial", "value" },
+ { "TQLabel", "text" },
+ { "TQLCDNumber", "value" },
+ { "TQLineEdit", "text" },
+ { "TQListBox", "currentItem" },
+ { "TQMultiLineEdit", "text" },
+ { "TQPushButton", "text" },
+ { "TQScrollBar", "value" },
+ { "TQSlider", "value" },
+ { "TQSpinBox", "value" },
+ { "TQTextBrowser", "source" },
+ { "TQTextEdit", "text" },
+ { "TQTextView", "text" },
+ { "TQTimeEdit", "time" }
+ };
+
+ const MapData *m = mapData;
+ for ( uint i = 0; i < sizeof(mapData)/sizeof(MapData); i++, m++ )
+ d->propertyMap.insert( m->classname, m->property );
+}
+
+/*!
+ Destroys the TQSqlPropertyMap.
+
+ Note that if the TQSqlPropertyMap is installed with
+ installPropertyMap() the object it was installed into, e.g. the
+ TQSqlForm, takes ownership and will delete the TQSqlPropertyMap when
+ necessary.
+*/
+TQSqlPropertyMap::~TQSqlPropertyMap()
+{
+ delete d;
+}
+
+/*!
+ Returns the mapped property of \a widget as a TQVariant.
+*/
+TQVariant TQSqlPropertyMap::property( TQWidget * widget )
+{
+ if( !widget ) return TQVariant();
+ const QMetaObject* mo = widget->metaObject();
+ while ( mo && !d->propertyMap.tqcontains( TQString( mo->className() ) ) )
+ mo = mo->superClass();
+
+ if ( !mo ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlPropertyMap::property: %s does not exist", widget->metaObject()->className() );
+#endif
+ return TQVariant();
+ }
+ return TQT_TQVARIANT_OBJECT(widget->property( d->propertyMap[ mo->className() ] ));
+}
+
+/*!
+ Sets the property of \a widget to \a value.
+*/
+void TQSqlPropertyMap::setProperty( TQWidget * widget, const TQVariant & value )
+{
+ if( !widget ) return;
+
+ QMetaObject* mo = const_cast<QMetaObject*>(widget->metaObject());
+ while ( mo && !d->propertyMap.tqcontains( TQString( mo->className() ) ) )
+ mo = const_cast<QMetaObject*>(mo->superClass());
+ if ( !mo ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlPropertyMap::setProperty: %s not handled by TQSqlPropertyMap", widget->metaObject()->className() );
+#endif
+ return;
+ }
+
+ widget->setProperty( d->propertyMap[ mo->className() ], value );
+}
+
+/*!
+ Insert a new classname/property pair, which is used for custom SQL
+ field editors. There \e must be a \c Q_PROPERTY clause in the \a
+ classname class declaration for the \a property.
+*/
+void TQSqlPropertyMap::insert( const TQString & classname,
+ const TQString & property )
+{
+ d->propertyMap[ classname ] = property;
+}
+
+/*!
+ Removes \a classname from the map.
+*/
+void TQSqlPropertyMap::remove( const TQString & classname )
+{
+ d->propertyMap.remove( classname );
+}
+
+static TQSqlPropertyMap * defaultmap = 0;
+static TQCleanupHandler< TQSqlPropertyMap > qsql_cleanup_property_map;
+
+/*!
+ Returns the application global TQSqlPropertyMap.
+*/
+TQSqlPropertyMap * TQSqlPropertyMap::defaultMap()
+{
+ if( defaultmap == 0 ){
+ defaultmap = new TQSqlPropertyMap();
+ qsql_cleanup_property_map.add( &defaultmap );
+ }
+ return defaultmap;
+}
+
+/*!
+ Replaces the global default property map with \a map. All
+ TQDataTable and TQSqlForm instantiations will use this new map for
+ inserting and extracting values to and from editors.
+ \e{TQSqlPropertyMap takes ownership of \a map, and destroys it
+ when it is no longer needed.}
+*/
+void TQSqlPropertyMap::installDefaultMap( TQSqlPropertyMap * map )
+{
+ if( map == 0 ) return;
+
+ if( defaultmap != 0 ){
+ qsql_cleanup_property_map.remove( &defaultmap );
+ delete defaultmap;
+ }
+ defaultmap = map;
+ qsql_cleanup_property_map.add( &defaultmap );
+}
+
+#endif // TQT_NO_STQL_FORM
diff --git a/tqtinterface/qt4/src/sql/tqsqlpropertymap.h b/tqtinterface/qt4/src/sql/tqsqlpropertymap.h
new file mode 100644
index 0000000..c356f5e
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlpropertymap.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Definition of TQSqlPropertyMap class
+**
+** Created : 2000-11-20
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLPROPERTYMAP_H
+#define TQSQLPROPERTYMAP_H
+
+#ifndef TQT_H
+#include "tqvariant.h"
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_STQL_FORM
+
+class TQWidget;
+class TQSqlPropertyMapPrivate;
+
+class TQ_EXPORT TQSqlPropertyMap {
+public:
+ TQSqlPropertyMap();
+ virtual ~TQSqlPropertyMap();
+
+ TQVariant property( TQWidget * widget );
+ virtual void setProperty( TQWidget * widget, const TQVariant & value );
+
+ void insert( const TQString & classname, const TQString & property );
+ void remove( const TQString & classname );
+
+ static TQSqlPropertyMap * defaultMap();
+ static void installDefaultMap( TQSqlPropertyMap * map );
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSqlPropertyMap( const TQSqlPropertyMap & );
+ TQSqlPropertyMap &operator=( const TQSqlPropertyMap & );
+#endif
+ TQSqlPropertyMapPrivate* d;
+
+};
+
+#endif // TQT_NO_STQL_FORM
+#endif // TQSQLPROPERTYMAP_H
diff --git a/tqtinterface/qt4/src/sql/tqsqlquery.cpp b/tqtinterface/qt4/src/sql/tqsqlquery.cpp
new file mode 100644
index 0000000..9a6f649
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlquery.cpp
@@ -0,0 +1,1215 @@
+/****************************************************************************
+**
+** Implementation of TQSqlQuery class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlquery.h"
+
+#ifndef TQT_NO_SQL
+
+//#define TQT_DEBUG_SQL
+
+#include "tqsqlresult.h"
+#include "tqsqldriver.h"
+#include "tqsqldatabase.h"
+#include "tqsql.h"
+#include "tqregexp.h"
+#include "private/tqsqlextension_p.h"
+
+
+/*!
+\internal
+*/
+TQSqlResultShared::TQSqlResultShared( TQSqlResult* result ): sqlResult(result)
+{
+ if ( result )
+ connect( result->driver(), TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotResultDestroyed()) );
+}
+
+/*!
+\internal
+*/
+TQSqlResultShared::~TQSqlResultShared()
+{
+ delete sqlResult;
+}
+
+/*!
+\internal
+
+In case a plugin gets unloaded the pointer to the sqlResult gets invalid
+*/
+void TQSqlResultShared::slotResultDestroyed()
+{
+ delete sqlResult;
+ sqlResult = 0;
+}
+
+/*!
+ \class TQSqlQuery tqsqlquery.h
+ \brief The TQSqlQuery class provides a means of executing and
+ manipulating SQL statements.
+
+ \ingroup database
+ \mainclass
+ \module sql
+
+ TQSqlQuery encapsulates the functionality involved in creating,
+ navigating and retrieving data from SQL queries which are executed
+ on a \l TQSqlDatabase. It can be used to execute DML (data
+ manipulation language) statements, e.g. \c SELECT, \c INSERT, \c
+ UPDATE and \c DELETE, and also DDL (data definition language)
+ statements, e.g. \c{CREATE TABLE}. It can also be used to
+ execute database-specific commands which are not standard SQL
+ (e.g. \c{SET DATESTYLE=ISO} for PostgreSQL).
+
+ Successfully executed SQL statements set the query's state to
+ active (isActive() returns TRUE); otherwise the query's state is
+ set to inactive. In either case, when executing a new SQL
+ statement, the query is positioned on an invalid record; an active
+ query must be navigated to a valid record (so that isValid()
+ returns TRUE) before values can be retrieved.
+
+ Navigating records is performed with the following functions:
+
+ \list
+ \i \c next()
+ \i \c prev()
+ \i \c first()
+ \i \c last()
+ \i \c \link TQSqlQuery::seek() seek\endlink(int)
+ \endlist
+
+ These functions allow the programmer to move forward, backward or
+ arbitrarily through the records returned by the query. If you only
+ need to move forward through the results, e.g. using next() or
+ using seek() with a positive offset, you can use setForwardOnly()
+ and save a significant amount of memory overhead. Once an active
+ query is positioned on a valid record, data can be retrieved using
+ value(). All data is transferred from the SQL backend using
+ TQVariants.
+
+ For example:
+
+ \code
+ TQSqlQuery query( "SELECT name FROM customer" );
+ while ( query.next() ) {
+ TQString name = query.value(0).toString();
+ doSomething( name );
+ }
+ \endcode
+
+ To access the data returned by a query, use the value() method.
+ Each field in the data returned by a SELECT statement is accessed
+ by passing the field's position in the statement, starting from 0.
+ Information about the fields can be obtained via TQSqlDatabase::record().
+ For the sake of efficiency there are no functions to access a field
+ by name. (The \l TQSqlCursor class provides a higher-level interface
+ with field access by name and automatic SQL generation.)
+
+ TQSqlQuery supports prepared query execution and the binding of
+ parameter values to placeholders. Some databases don't support
+ these features, so for them TQt emulates the required
+ functionality. For example, the Oracle and ODBC drivers have
+ proper prepared query support, and TQt makes use of it; but for
+ databases that don't have this support, TQt implements the feature
+ itself, e.g. by replacing placeholders with actual values when a
+ query is executed. The exception is positional binding using named
+ placeholders, which requires that the database supports prepared
+ queries.
+
+ Oracle databases identify placeholders by using a colon-name
+ syntax, e.g \c{:name}. ODBC simply uses \c ? characters. TQt
+ supports both syntaxes (although you can't mix them in the same
+ query).
+
+ Below we present the same example using each of the four different
+ binding approaches.
+
+ <b>Named binding using named placeholders</b>
+ \code
+ TQSqlQuery query;
+ query.prepare( "INSERT INTO atable (id, forename, surname) "
+ "VALUES (:id, :forename, :surname)" );
+ query.bindValue( ":id", 1001 );
+ query.bindValue( ":forename", "Bart" );
+ query.bindValue( ":surname", "Simpson" );
+ query.exec();
+ \endcode
+
+ <b>Positional binding using named placeholders</b>
+ \code
+ TQSqlQuery query;
+ query.prepare( "INSERT INTO atable (id, forename, surname) "
+ "VALUES (:id, :forename, :surname)" );
+ query.bindValue( 0, 1001 );
+ query.bindValue( 1, "Bart" );
+ query.bindValue( 2, "Simpson" );
+ query.exec();
+ \endcode
+ <b>Note:</b> Using positional binding with named placeholders will
+ only work if the database supports prepared queries. This can be
+ checked with TQSqlDriver::hasFeature() using TQSqlDriver::PreparedQueries
+ as argument for driver feature.
+
+ <b>Binding values using positional placeholders #1</b>
+ \code
+ TQSqlQuery query;
+ query.prepare( "INSERT INTO atable (id, forename, surname) "
+ "VALUES (?, ?, ?)" );
+ query.bindValue( 0, 1001 );
+ query.bindValue( 1, "Bart" );
+ query.bindValue( 2, "Simpson" );
+ query.exec();
+ \endcode
+
+ <b>Binding values using positional placeholders #2</b>
+ \code
+ query.prepare( "INSERT INTO atable (id, forename, surname) "
+ "VALUES (?, ?, ?)" );
+ query.addBindValue( 1001 );
+ query.addBindValue( "Bart" );
+ query.addBindValue( "Simpson" );
+ query.exec();
+ \endcode
+
+ <b>Binding values to a stored procedure</b>
+ This code calls a stored procedure called \c AsciiToInt(), passing
+ it a character through its in parameter, and taking its result in
+ the out parameter.
+ \code
+ TQSqlQuery query;
+ query.prepare( "call AsciiToInt(?, ?)" );
+ query.bindValue( 0, "A" );
+ query.bindValue( 1, 0, TQSql::Out );
+ query.exec();
+ int i = query.boundValue( 1 ).toInt(); // i is 65.
+ \endcode
+
+ \sa TQSqlDatabase TQSqlCursor TQVariant
+*/
+
+/*!
+ Creates a TQSqlQuery object which uses the TQSqlResult \a r to
+ communicate with a database.
+*/
+
+TQSqlQuery::TQSqlQuery( TQSqlResult * r )
+{
+ d = new TQSqlResultShared( r );
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlQuery::~TQSqlQuery()
+{
+ if (d->deref()) {
+ delete d;
+ }
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+
+TQSqlQuery::TQSqlQuery( const TQSqlQuery& other )
+ : d(other.d)
+{
+ d->ref();
+}
+
+/*!
+ Creates a TQSqlQuery object using the SQL \a query and the database
+ \a db. If \a db is 0, (the default), the application's default
+ database is used. If \a query is not a null string, it will be
+ executed.
+
+ \sa TQSqlDatabase
+*/
+TQSqlQuery::TQSqlQuery( const TQString& query, TQSqlDatabase* db )
+{
+ init( query, db );
+}
+
+/*!
+ Creates a TQSqlQuery object using the database \a db. If \a db is
+ 0, the application's default database is used.
+
+ \sa TQSqlDatabase
+*/
+
+TQSqlQuery::TQSqlQuery( TQSqlDatabase* db )
+{
+ init( TQString::null, db );
+}
+
+/*! \internal
+*/
+
+void TQSqlQuery::init( const TQString& query, TQSqlDatabase* db )
+{
+ d = new TQSqlResultShared( 0 );
+ TQSqlDatabase* database = db;
+ if ( !database )
+ database = TQSqlDatabase::database( TQSqlDatabase::defaultConnection, FALSE );
+ if ( database )
+ *this = database->driver()->createQuery();
+ if ( !query.isNull() )
+ exec( query );
+}
+
+/*!
+ Assigns \a other to the query.
+*/
+
+TQSqlQuery& TQSqlQuery::operator=( const TQSqlQuery& other )
+{
+ other.d->ref();
+ deref();
+ d = other.d;
+ return *this;
+}
+
+/*!
+ Returns TRUE if the query is active and positioned on a valid
+ record and the \a field is NULL; otherwise returns FALSE. Note
+ that for some drivers isNull() will not return accurate
+ information until after an attempt is made to retrieve data.
+
+ \sa isActive() isValid() value()
+*/
+
+bool TQSqlQuery::isNull( int field ) const
+{
+ if ( !d->sqlResult )
+ return FALSE;
+ if ( d->sqlResult->isActive() && d->sqlResult->isValid() )
+ return d->sqlResult->isNull( field );
+ return FALSE;
+}
+
+/*!
+ Executes the SQL in \a query. Returns TRUE and sets the query
+ state to active if the query was successful; otherwise returns
+ FALSE and sets the query state to inactive. The \a query string
+ must use syntax appropriate for the SQL database being queried,
+ for example, standard SQL.
+
+ After the query is executed, the query is positioned on an \e
+ invalid record, and must be navigated to a valid record before
+ data values can be retrieved, e.g. using next().
+
+ Note that the last error for this query is reset when exec() is
+ called.
+
+ \sa isActive() isValid() next() prev() first() last() seek()
+*/
+
+bool TQSqlQuery::exec ( const TQString& query )
+{
+ if ( !d->sqlResult )
+ return FALSE;
+ if ( d->sqlResult->extension() && driver()->hasFeature( TQSqlDriver::PreparedQueries ) )
+ d->sqlResult->extension()->clear();
+ d->sqlResult->setActive( FALSE );
+ d->sqlResult->setLastError( TQSqlError() );
+ d->sqlResult->setAt( TQSql::BeforeFirst );
+ if ( !driver() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlQuery::exec: no driver" );
+#endif
+ return FALSE;
+ }
+ if ( d->count > 1 )
+ *this = driver()->createQuery();
+ d->sqlResult->setQuery( query.stripWhiteSpace() );
+ d->executedQuery = d->sqlResult->lastQuery();
+ if ( !driver()->isOpen() || driver()->isOpenError() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlQuery::exec: database not open" );
+#endif
+ return FALSE;
+ }
+ if ( query.isNull() || query.length() == 0 ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlQuery::exec: empty query" );
+#endif
+ return FALSE;
+ }
+#ifdef TQT_DEBUG_SQL
+ qDebug( "\n TQSqlQuery: " + query );
+#endif
+ return d->sqlResult->reset( query );
+}
+
+/*!
+ Returns the value of the \a{i}-th field in the query (zero based).
+
+ The fields are numbered from left to right using the text of the
+ \c SELECT statement, e.g. in \c{SELECT forename, surname FROM people},
+ field 0 is \c forename and field 1 is \c surname. Using \c{SELECT *}
+ is not recommended because the order of the fields in the query is
+ undefined.
+
+ An invalid TQVariant is returned if field \a i does not exist, if
+ the query is inactive, or if the query is positioned on an invalid
+ record.
+
+ \sa prev() next() first() last() seek() isActive() isValid()
+*/
+
+TQVariant TQSqlQuery::value( int i ) const
+{
+ if ( !d->sqlResult )
+ return TQVariant();
+ if ( isActive() && isValid() && ( i > TQSql::BeforeFirst ) ) {
+ return d->sqlResult->data( i );
+ } else {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQSqlQuery::value: not positioned on a valid record" );
+#endif
+ }
+ return TQVariant();
+}
+
+/*!
+ Returns the current internal position of the query. The first
+ record is at position zero. If the position is invalid, a
+ TQSql::Location will be returned indicating the invalid position.
+
+ \sa prev() next() first() last() seek() isActive() isValid()
+*/
+
+int TQSqlQuery::at() const
+{
+ if ( !d->sqlResult )
+ return TQSql::BeforeFirst;
+ return d->sqlResult->at();
+}
+
+/*!
+ Returns the text of the current query being used, or TQString::null
+ if there is no current query text.
+
+ \sa executedQuery()
+*/
+
+TQString TQSqlQuery::lastQuery() const
+{
+ if ( !d->sqlResult )
+ return TQString::null;
+ return d->sqlResult->lastQuery();
+}
+
+/*!
+ Returns the database driver associated with the query.
+*/
+
+const TQSqlDriver* TQSqlQuery::driver() const
+{
+ if ( !d->sqlResult )
+ return 0;
+ return d->sqlResult->driver();
+}
+
+/*!
+ Returns the result associated with the query.
+*/
+
+const TQSqlResult* TQSqlQuery::result() const
+{
+ return d->sqlResult;
+}
+
+/*!
+ Retrieves the record at position (offset) \a i, if available, and
+ positions the query on the retrieved record. The first record is
+ at position 0. Note that the query must be in an active state and
+ isSelect() must return TRUE before calling this function.
+
+ If \a relative is FALSE (the default), the following rules apply:
+
+ \list
+ \i If \a i is negative, the result is positioned before the
+ first record and FALSE is returned.
+ \i Otherwise, an attempt is made to move to the record at position
+ \a i. If the record at position \a i could not be retrieved, the
+ result is positioned after the last record and FALSE is returned. If
+ the record is successfully retrieved, TRUE is returned.
+ \endlist
+
+ If \a relative is TRUE, the following rules apply:
+
+ \list
+ \i If the result is currently positioned before the first
+ record or on the first record, and \a i is negative, there is no
+ change, and FALSE is returned.
+ \i If the result is currently located after the last record, and
+ \a i is positive, there is no change, and FALSE is returned.
+ \i If the result is currently located somewhere in the middle,
+ and the relative offset \a i moves the result below zero, the
+ result is positioned before the first record and FALSE is
+ returned.
+ \i Otherwise, an attempt is made to move to the record \a i
+ records ahead of the current record (or \a i records behind the
+ current record if \a i is negative). If the record at offset \a i
+ could not be retrieved, the result is positioned after the last
+ record if \a i >= 0, (or before the first record if \a i is
+ negative), and FALSE is returned. If the record is successfully
+ retrieved, TRUE is returned.
+ \endlist
+
+ \sa next() prev() first() last() at() isActive() isValid()
+*/
+bool TQSqlQuery::seek( int i, bool relative )
+{
+ if ( !isSelect() || !isActive() )
+ return FALSE;
+ beforeSeek();
+ checkDetach();
+ int actualIdx;
+ if ( !relative ) { // arbitrary seek
+ if ( i < 0 ) {
+ d->sqlResult->setAt( TQSql::BeforeFirst );
+ afterSeek();
+ return FALSE;
+ }
+ actualIdx = i;
+ } else {
+ switch ( at() ) { // relative seek
+ case TQSql::BeforeFirst:
+ if ( i > 0 )
+ actualIdx = i;
+ else {
+ afterSeek();
+ return FALSE;
+ }
+ break;
+ case TQSql::AfterLast:
+ if ( i < 0 ) {
+ d->sqlResult->fetchLast();
+ actualIdx = at() + i;
+ } else {
+ afterSeek();
+ return FALSE;
+ }
+ break;
+ default:
+ if ( ( at() + i ) < 0 ) {
+ d->sqlResult->setAt( TQSql::BeforeFirst );
+ afterSeek();
+ return FALSE;
+ }
+ actualIdx = at() + i;
+ break;
+ }
+ }
+ // let drivers optimize
+ if ( isForwardOnly() && actualIdx < at() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlQuery::seek: cannot seek backwards in a forward only query" );
+#endif
+ afterSeek();
+ return FALSE;
+ }
+ if ( actualIdx == ( at() + 1 ) && at() != TQSql::BeforeFirst ) {
+ if ( !d->sqlResult->fetchNext() ) {
+ d->sqlResult->setAt( TQSql::AfterLast );
+ afterSeek();
+ return FALSE;
+ }
+ afterSeek();
+ return TRUE;
+ }
+ if ( actualIdx == ( at() - 1 ) ) {
+ if ( !d->sqlResult->fetchPrev() ) {
+ d->sqlResult->setAt( TQSql::BeforeFirst );
+ afterSeek();
+ return FALSE;
+ }
+ afterSeek();
+ return TRUE;
+ }
+ if ( !d->sqlResult->fetch( actualIdx ) ) {
+ d->sqlResult->setAt( TQSql::AfterLast );
+ afterSeek();
+ return FALSE;
+ }
+ afterSeek();
+ return TRUE;
+}
+
+/*!
+ Retrieves the next record in the result, if available, and
+ positions the query on the retrieved record. Note that the result
+ must be in an active state and isSelect() must return TRUE before
+ calling this function or it will do nothing and return FALSE.
+
+ The following rules apply:
+
+ \list
+ \i If the result is currently located before the first
+ record, e.g. immediately after a query is executed, an attempt is
+ made to retrieve the first record.
+
+ \i If the result is currently located after the last record,
+ there is no change and FALSE is returned.
+
+ \i If the result is located somewhere in the middle, an attempt
+ is made to retrieve the next record.
+ \endlist
+
+ If the record could not be retrieved, the result is positioned after
+ the last record and FALSE is returned. If the record is successfully
+ retrieved, TRUE is returned.
+
+ \sa prev() first() last() seek() at() isActive() isValid()
+*/
+
+bool TQSqlQuery::next()
+{
+ if ( !isSelect() || !isActive() )
+ return FALSE;
+ beforeSeek();
+ checkDetach();
+ bool b = FALSE;
+ switch ( at() ) {
+ case TQSql::BeforeFirst:
+ b = d->sqlResult->fetchFirst();
+ afterSeek();
+ return b;
+ case TQSql::AfterLast:
+ afterSeek();
+ return FALSE;
+ default:
+ if ( !d->sqlResult->fetchNext() ) {
+ d->sqlResult->setAt( TQSql::AfterLast );
+ afterSeek();
+ return FALSE;
+ }
+ afterSeek();
+ return TRUE;
+ }
+}
+
+/*!
+ Retrieves the previous record in the result, if available, and
+ positions the query on the retrieved record. Note that the result
+ must be in an active state and isSelect() must return TRUE before
+ calling this function or it will do nothing and return FALSE.
+
+ The following rules apply:
+
+ \list
+ \i If the result is currently located before the first record,
+ there is no change and FALSE is returned.
+
+ \i If the result is currently located after the last record, an
+ attempt is made to retrieve the last record.
+
+ \i If the result is somewhere in the middle, an attempt is made
+ to retrieve the previous record.
+ \endlist
+
+ If the record could not be retrieved, the result is positioned
+ before the first record and FALSE is returned. If the record is
+ successfully retrieved, TRUE is returned.
+
+ \sa next() first() last() seek() at() isActive() isValid()
+*/
+
+bool TQSqlQuery::prev()
+{
+ if ( !isSelect() || !isActive() )
+ return FALSE;
+ if ( isForwardOnly() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlQuery::seek: cannot seek backwards in a forward only query" );
+#endif
+ return FALSE;
+ }
+
+ beforeSeek();
+ checkDetach();
+ bool b = FALSE;
+ switch ( at() ) {
+ case TQSql::BeforeFirst:
+ afterSeek();
+ return FALSE;
+ case TQSql::AfterLast:
+ b = d->sqlResult->fetchLast();
+ afterSeek();
+ return b;
+ default:
+ if ( !d->sqlResult->fetchPrev() ) {
+ d->sqlResult->setAt( TQSql::BeforeFirst );
+ afterSeek();
+ return FALSE;
+ }
+ afterSeek();
+ return TRUE;
+ }
+}
+
+/*!
+ Retrieves the first record in the result, if available, and
+ positions the query on the retrieved record. Note that the result
+ must be in an active state and isSelect() must return TRUE before
+ calling this function or it will do nothing and return FALSE.
+ Returns TRUE if successful. If unsuccessful the query position is
+ set to an invalid position and FALSE is returned.
+
+ \sa next() prev() last() seek() at() isActive() isValid()
+*/
+
+bool TQSqlQuery::first()
+{
+ if ( !isSelect() || !isActive() )
+ return FALSE;
+ if ( isForwardOnly() && at() > TQSql::BeforeFirst ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlQuery::seek: cannot seek backwards in a forward only query" );
+#endif
+ return FALSE;
+ }
+ beforeSeek();
+ checkDetach();
+ bool b = FALSE;
+ b = d->sqlResult->fetchFirst();
+ afterSeek();
+ return b;
+}
+
+/*!
+ Retrieves the last record in the result, if available, and
+ positions the query on the retrieved record. Note that the result
+ must be in an active state and isSelect() must return TRUE before
+ calling this function or it will do nothing and return FALSE.
+ Returns TRUE if successful. If unsuccessful the query position is
+ set to an invalid position and FALSE is returned.
+
+ \sa next() prev() first() seek() at() isActive() isValid()
+*/
+
+bool TQSqlQuery::last()
+{
+ if ( !isSelect() || !isActive() )
+ return FALSE;
+ beforeSeek();
+ checkDetach();
+ bool b = FALSE;
+ b = d->sqlResult->fetchLast();
+ afterSeek();
+ return b;
+}
+
+/*!
+ Returns the size of the result, (number of rows returned), or -1
+ if the size cannot be determined or if the database does not
+ support reporting information about query sizes. Note that for
+ non-\c SELECT statements (isSelect() returns FALSE), size() will
+ return -1. If the query is not active (isActive() returns FALSE),
+ -1 is returned.
+
+ To determine the number of rows affected by a non-SELECT
+ statement, use numRowsAffected().
+
+ \sa isActive() numRowsAffected() TQSqlDriver::hasFeature()
+*/
+int TQSqlQuery::size() const
+{
+ if ( !d->sqlResult )
+ return -1;
+ if ( isActive() && d->sqlResult->driver()->hasFeature( TQSqlDriver::QuerySize ) )
+ return d->sqlResult->size();
+ return -1;
+}
+
+/*!
+ Returns the number of rows affected by the result's SQL statement,
+ or -1 if it cannot be determined. Note that for \c SELECT
+ statements, the value is undefined; see size() instead. If the
+ query is not active (isActive() returns FALSE), -1 is returned.
+
+ \sa size() TQSqlDriver::hasFeature()
+*/
+
+int TQSqlQuery::numRowsAffected() const
+{
+ if ( !d->sqlResult )
+ return -1;
+ if ( isActive() )
+ return d->sqlResult->numRowsAffected();
+ return -1;
+}
+
+/*!
+ Returns error information about the last error (if any) that
+ occurred.
+
+ \sa TQSqlError
+*/
+
+TQSqlError TQSqlQuery::lastError() const
+{
+ if ( !d->sqlResult )
+ return TQSqlError();
+ return d->sqlResult->lastError();
+}
+
+/*!
+ Returns TRUE if the query is currently positioned on a valid
+ record; otherwise returns FALSE.
+*/
+
+bool TQSqlQuery::isValid() const
+{
+ if ( !d->sqlResult )
+ return FALSE;
+ return d->sqlResult->isValid();
+}
+
+/*!
+ Returns TRUE if the query is currently active; otherwise returns
+ FALSE.
+*/
+
+bool TQSqlQuery::isActive() const
+{
+ if ( !d->sqlResult )
+ return FALSE;
+ return d->sqlResult->isActive();
+}
+
+/*!
+ Returns TRUE if the current query is a \c SELECT statement;
+ otherwise returns FALSE.
+*/
+
+bool TQSqlQuery::isSelect() const
+{
+ if ( !d->sqlResult )
+ return FALSE;
+ return d->sqlResult->isSelect();
+}
+
+/*!
+ Returns TRUE if you can only scroll \e forward through a result
+ set; otherwise returns FALSE.
+
+ \sa setForwardOnly()
+*/
+bool TQSqlQuery::isForwardOnly() const
+{
+ if ( !d->sqlResult )
+ return FALSE;
+ return d->sqlResult->isForwardOnly();
+}
+
+/*!
+ Sets forward only mode to \a forward. If forward is TRUE only
+ next(), and seek() with positive values, are allowed for
+ navigating the results. Forward only mode needs far less memory
+ since results do not need to be cached.
+
+ Forward only mode is off by default.
+
+ Forward only mode cannot be used with data aware widgets like
+ TQDataTable, since they must to be able to scroll backward as well
+ as forward.
+
+ \sa isForwardOnly(), next(), seek()
+*/
+void TQSqlQuery::setForwardOnly( bool forward )
+{
+ if ( d->sqlResult )
+ d->sqlResult->setForwardOnly( forward );
+}
+
+/*!
+ \internal
+*/
+
+void TQSqlQuery::deref()
+{
+ if ( d->deref() ) {
+ delete d;
+ d = 0;
+ }
+}
+
+/*!
+ \internal
+*/
+
+bool TQSqlQuery::checkDetach()
+{
+ if ( d->count > 1 && d->sqlResult ) {
+ TQString sql = d->sqlResult->lastQuery();
+ *this = driver()->createQuery();
+ exec( sql );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*!
+ Protected virtual function called before the internal record
+ pointer is moved to a new record. The default implementation does
+ nothing.
+*/
+
+void TQSqlQuery::beforeSeek()
+{
+
+}
+
+
+/*!
+ Protected virtual function called after the internal record
+ pointer is moved to a new record. The default implementation does
+ nothing.
+*/
+
+void TQSqlQuery::afterSeek()
+{
+
+}
+
+// XXX: Hack to keep BCI - remove in 4.0. TQSqlExtension should be
+// removed, and the prepare(), exec() etc. fu's should be
+// made virtual members of TQSqlQuery/TQSqlResult
+
+/*!
+ Prepares the SQL query \a query for execution. The query may
+ contain placeholders for binding values. Both Oracle style
+ colon-name (e.g. \c{:surname}), and ODBC style (e.g. \c{?})
+ placeholders are supported; but they cannot be mixed in the same
+ query. See the \link #details Description\endlink for examples.
+
+ \sa exec(), bindValue(), addBindValue()
+*/
+bool TQSqlQuery::prepare( const TQString& query )
+{
+ if ( !d->sqlResult || !d->sqlResult->extension() )
+ return FALSE;
+ d->sqlResult->setActive( FALSE );
+ d->sqlResult->setLastError( TQSqlError() );
+ d->sqlResult->setAt( TQSql::BeforeFirst );
+ d->sqlResult->extension()->clear();
+ if ( !driver() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlQuery::prepare: no driver" );
+#endif
+ return FALSE;
+ }
+ if ( d->count > 1 )
+ *this = driver()->createQuery();
+ d->sqlResult->setQuery( query.stripWhiteSpace() );
+ if ( !driver()->isOpen() || driver()->isOpenError() ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlQuery::prepare: database not open" );
+#endif
+ return FALSE;
+ }
+ if ( query.isNull() || query.length() == 0 ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQSqlQuery::prepare: empty query" );
+#endif
+ return FALSE;
+ }
+#ifdef TQT_DEBUG_SQL
+ qDebug( "\n TQSqlQuery: " + query );
+#endif
+ TQString q = query;
+ TQRegExp rx(TQString::tqfromLatin1("'[^']*'|:([a-zA-Z0-9_]+)"));
+ if ( driver()->hasFeature( TQSqlDriver::PreparedQueries ) ) {
+ // below we substitute Oracle placeholders with ODBC ones and
+ // vice versa to make this db independent
+ int i = 0, cnt = 0;
+ if ( driver()->hasFeature( TQSqlDriver::NamedPlaceholders ) ) {
+ TQRegExp rx(TQString::tqfromLatin1("'[^']*'|\\?"));
+ while ( (i = rx.search( q, i )) != -1 ) {
+ if ( rx.cap(0) == "?" ) {
+ q = q.tqreplace( i, 1, ":f" + TQString::number(cnt) );
+ cnt++;
+ }
+ i += rx.matchedLength();
+ }
+ } else if ( driver()->hasFeature( TQSqlDriver::PositionalPlaceholders ) ) {
+ while ( (i = rx.search( q, i )) != -1 ) {
+ if ( rx.cap(1).isEmpty() ) {
+ i += rx.matchedLength();
+ } else {
+ // record the index of the placeholder - needed
+ // for emulating named bindings with ODBC
+ d->sqlResult->extension()->index[ cnt ]= rx.cap(0);
+ q = q.tqreplace( i, rx.matchedLength(), "?" );
+ i++;
+ cnt++;
+ }
+ }
+ }
+ d->executedQuery = q;
+ return d->sqlResult->extension()->prepare( q );
+ } else {
+ int i = 0;
+ while ( (i = rx.search( q, i )) != -1 ) {
+ if ( !rx.cap(1).isEmpty() )
+ d->sqlResult->extension()->holders.append( Holder( rx.cap(0), i ) );
+ i += rx.matchedLength();
+ }
+ return TRUE; // fake prepares should always succeed
+ }
+}
+
+/*!
+ \overload
+
+ Executes a previously prepared SQL query. Returns TRUE if the
+ query executed successfully; otherwise returns FALSE.
+
+ \sa prepare(), bindValue(), addBindValue()
+*/
+bool TQSqlQuery::exec()
+{
+ bool ret;
+ if ( !d->sqlResult || !d->sqlResult->extension() )
+ return FALSE;
+ if ( driver()->hasFeature( TQSqlDriver::PreparedQueries ) ) {
+ ret = d->sqlResult->extension()->exec();
+ } else {
+ // fake preparation - just tqreplace the placeholders..
+ TQString query = d->sqlResult->lastQuery();
+ if ( d->sqlResult->extension()->bindMethod() == TQSqlExtension::BindByName ) {
+ int i;
+ TQVariant val;
+ TQString holder;
+ for ( i = (int)d->sqlResult->extension()->holders.count() - 1; i >= 0; --i ) {
+ holder = d->sqlResult->extension()->holders[ (uint)i ].holderName;
+ val = d->sqlResult->extension()->values[ holder ].value;
+ TQSqlField f( "", val.type() );
+ if ( val.isNull() )
+ f.setNull();
+ else
+ f.setValue( val );
+ query = query.tqreplace( (uint)d->sqlResult->extension()->holders[ (uint)i ].holderPos,
+ holder.length(), driver()->formatValue( &f ) );
+ }
+ } else {
+ TQMap<int, TQString>::ConstIterator it;
+ TQString val;
+ int i = 0;
+ for ( it = d->sqlResult->extension()->index.begin();
+ it != d->sqlResult->extension()->index.end(); ++it ) {
+ i = query.tqfind( '?', i );
+ if ( i > -1 ) {
+ TQSqlField f( "", d->sqlResult->extension()->values[ it.data() ].value.type() );
+ if ( d->sqlResult->extension()->values[ it.data() ].value.isNull() )
+ f.setNull();
+ else
+ f.setValue( d->sqlResult->extension()->values[ it.data() ].value );
+ val = driver()->formatValue( &f );
+ query = query.tqreplace( i, 1, driver()->formatValue( &f ) );
+ i += val.length();
+ }
+ }
+ }
+ // have to retain the original query w/placeholders..
+ TQString orig = d->sqlResult->lastQuery();
+ ret = exec( query );
+ d->executedQuery = query;
+ d->sqlResult->setQuery( orig );
+ }
+ d->sqlResult->extension()->resetBindCount();
+ return ret;
+}
+
+/*!
+ Set the placeholder \a placeholder to be bound to value \a val in
+ the prepared statement. Note that the placeholder mark (e.g \c{:})
+ must be included when specifying the placeholder name. If \a type
+ is \c TQSql::Out or \c TQSql::InOut, the placeholder will be
+ overwritten with data from the database after the exec() call.
+
+ \sa addBindValue(), prepare(), exec()
+*/
+void TQSqlQuery::bindValue( const TQString& placeholder, const TQVariant& val, TQSql::ParameterType type )
+{
+ if ( !d->sqlResult || !d->sqlResult->extension() )
+ return;
+ d->sqlResult->extension()->bindValue( placeholder, val, type );
+}
+
+/*!
+ \overload
+
+ Set the placeholder in position \a pos to be bound to value \a val
+ in the prepared statement. Field numbering starts at 0. If \a type
+ is \c TQSql::Out or \c TQSql::InOut, the placeholder will be
+ overwritten with data from the database after the exec() call.
+
+ \sa addBindValue(), prepare(), exec()
+*/
+void TQSqlQuery::bindValue( int pos, const TQVariant& val, TQSql::ParameterType type )
+{
+ if ( !d->sqlResult || !d->sqlResult->extension() )
+ return;
+ d->sqlResult->extension()->bindValue( pos, val, type );
+}
+
+/*!
+ Adds the value \a val to the list of values when using positional
+ value binding. The order of the addBindValue() calls determines
+ which placeholder a value will be bound to in the prepared query.
+ If \a type is \c TQSql::Out or \c TQSql::InOut, the placeholder will
+ be overwritten with data from the database after the exec() call.
+
+ \sa bindValue(), prepare(), exec()
+*/
+void TQSqlQuery::addBindValue( const TQVariant& val, TQSql::ParameterType type )
+{
+ if ( !d->sqlResult || !d->sqlResult->extension() )
+ return;
+ d->sqlResult->extension()->addBindValue( val, type );
+}
+
+
+/*!
+ \overload
+
+ Binds the placeholder with type \c TQSql::In.
+*/
+void TQSqlQuery::bindValue( const TQString& placeholder, const TQVariant& val )
+{
+ bindValue( placeholder, val, TQSql::In );
+}
+
+/*!
+ \overload
+
+ Binds the placeholder at position \a pos with type \c TQSql::In.
+*/
+void TQSqlQuery::bindValue( int pos, const TQVariant& val )
+{
+ bindValue( pos, val, TQSql::In );
+}
+
+/*!
+ \overload
+
+ Binds the placeholder with type \c TQSql::In.
+*/
+void TQSqlQuery::addBindValue( const TQVariant& val )
+{
+ addBindValue( val, TQSql::In );
+}
+
+/*!
+ Returns the value for the \a placeholder.
+*/
+TQVariant TQSqlQuery::boundValue( const TQString& placeholder ) const
+{
+ if ( !d->sqlResult || !d->sqlResult->extension() )
+ return TQVariant();
+ return d->sqlResult->extension()->boundValue( placeholder );
+}
+
+/*!
+ \overload
+
+ Returns the value for the placeholder at position \a pos.
+*/
+TQVariant TQSqlQuery::boundValue( int pos ) const
+{
+ if ( !d->sqlResult || !d->sqlResult->extension() )
+ return TQVariant();
+ return d->sqlResult->extension()->boundValue( pos );
+}
+
+/*!
+ Returns a map of the bound values.
+
+ The bound values can be examined in the following way:
+ \code
+ TQSqlQuery query;
+ ...
+ // Examine the bound values - bound using named binding
+ TQMap<TQString, TQVariant>::ConstIterator it;
+ TQMap<TQString, TQVariant> vals = query.boundValues();
+ for ( it = vals.begin(); it != vals.end(); ++it )
+ qWarning( "Placeholder: " + it.key() + ", Value: " + (*it).toString() );
+ ...
+
+ // Examine the bound values - bound using positional binding
+ TQValueList<TQVariant>::ConstIterator it;
+ TQValueList<TQVariant> list = query.boundValues().values();
+ int i = 0;
+ for ( it = list.begin(); it != list.end(); ++it )
+ qWarning( "Placeholder pos: %d, Value: " + (*it).toString(), i++ );
+ ...
+
+ \endcode
+*/
+TQMap<TQString,TQVariant> TQSqlQuery::boundValues() const
+{
+ if ( !d->sqlResult || !d->sqlResult->extension() )
+ return TQMap<TQString,TQVariant>();
+ return d->sqlResult->extension()->boundValues();
+}
+
+/*!
+ Returns the last query that was executed.
+
+ In most cases this function returns the same as lastQuery(). If a
+ prepared query with placeholders is executed on a DBMS that does
+ not support it, the preparation of this query is emulated. The
+ placeholders in the original query are tqreplaced with their bound
+ values to form a new query. This function returns the modified
+ query. Useful for debugging purposes.
+
+ \sa lastQuery()
+*/
+TQString TQSqlQuery::executedQuery() const
+{
+ return d->executedQuery;
+}
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/tqsqlquery.h b/tqtinterface/qt4/src/sql/tqsqlquery.h
new file mode 100644
index 0000000..4fac1f2
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlquery.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Definition of TQSqlQuery class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSQLTQUERY_H
+#define TQSQLTQUERY_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqstring.h"
+#include "tqvariant.h"
+#include "tqvaluelist.h"
+#include "tqsqlerror.h"
+#include "tqsqlfield.h"
+#include "tqsql.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SQL
+
+class TQSqlDriver;
+class TQSqlResult;
+class TQSqlDatabase;
+
+class TQ_EXPORT TQSqlResultShared : public TQObject, public TQShared
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQSqlResultShared( TQSqlResult* result );
+ virtual ~TQSqlResultShared();
+ TQSqlResult* sqlResult;
+ TQString executedQuery;
+private Q_SLOTS:
+ void slotResultDestroyed();
+};
+
+class TQ_EXPORT TQSqlQuery
+{
+public:
+ TQSqlQuery( TQSqlResult * r );
+ TQSqlQuery( const TQString& query = TQString::null, TQSqlDatabase* db = 0 );
+ TQ_EXPLICIT TQSqlQuery( TQSqlDatabase* db );
+ TQSqlQuery( const TQSqlQuery& other );
+ TQSqlQuery& operator=( const TQSqlQuery& other );
+ virtual ~TQSqlQuery();
+
+ bool isValid() const;
+ bool isActive() const;
+ bool isNull( int field ) const;
+ int at() const;
+ TQString lastQuery() const;
+ int numRowsAffected() const;
+ TQSqlError lastError() const;
+ bool isSelect() const;
+ int size() const;
+ const TQSqlDriver* driver() const;
+ const TQSqlResult* result() const;
+ bool isForwardOnly() const;
+ void setForwardOnly( bool forward );
+
+ virtual bool exec ( const TQString& query );
+ virtual TQVariant value( int i ) const;
+
+ virtual bool seek( int i, bool relative = FALSE );
+ virtual bool next();
+ virtual bool prev();
+ virtual bool first();
+ virtual bool last();
+
+ // prepared query support
+ bool exec();
+ bool prepare( const TQString& query );
+ void bindValue( const TQString& placeholder, const TQVariant& val );
+ void bindValue( int pos, const TQVariant& val );
+ void addBindValue( const TQVariant& val );
+ // remove these overloads in 4.0
+ void bindValue( const TQString& placeholder, const TQVariant& val, TQSql::ParameterType type );
+ void bindValue( int pos, const TQVariant& val, TQSql::ParameterType type );
+ void addBindValue( const TQVariant& val, TQSql::ParameterType type );
+ TQVariant boundValue( const TQString& placeholder ) const;
+ TQVariant boundValue( int pos ) const;
+ TQMap<TQString, TQVariant> boundValues() const;
+ TQString executedQuery() const;
+
+protected:
+ virtual void beforeSeek();
+ virtual void afterSeek();
+
+private:
+ void init( const TQString& query, TQSqlDatabase* db );
+ void deref();
+ bool checkDetach();
+ TQSqlResultShared* d;
+};
+
+
+#endif // TQT_NO_SQL
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlrecord.cpp b/tqtinterface/qt4/src/sql/tqsqlrecord.cpp
new file mode 100644
index 0000000..c082d16
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlrecord.cpp
@@ -0,0 +1,774 @@
+/****************************************************************************
+**
+** Implementation of TQSqlRecord class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlrecord.h"
+
+#ifndef TQT_NO_SQL
+
+#include "tqregexp.h"
+#include "tqvaluevector.h"
+#include "tqshared.h"
+#include "tqnamespace.h"
+
+class TQSqlRecordPrivate
+{
+public:
+ class info {
+ public:
+ info() : nogen(FALSE){}
+ ~info() {}
+ info( const info& other )
+ : field( other.field ), nogen( other.nogen )
+ {
+ }
+ info& operator=(const info& other)
+ {
+ field = other.field;
+ nogen = other.nogen;
+ return *this;
+ }
+ bool isValid() const
+ {
+ return !field.name().isNull();
+ }
+ TQ_DUMMY_COMPARISON_OPERATOR(info)
+ TQSqlField field;
+ bool nogen;
+ };
+
+ TQSqlRecordPrivate(): cnt(0)
+ {
+ }
+ TQSqlRecordPrivate( const TQSqlRecordPrivate& other )
+ {
+ *this = other;
+ }
+ ~TQSqlRecordPrivate() {};
+ TQSqlRecordPrivate& operator=( const TQSqlRecordPrivate& other )
+ {
+ fi = other.fi;
+ cnt = other.cnt;
+ return *this;
+ }
+ void append( const TQSqlField& field )
+ {
+ info i;
+ i.field = field;
+ fi.append( i );
+ cnt++;
+ }
+ void insert( int pos, const TQSqlField& field )
+ {
+ info i;
+ i.field = field;
+ if ( pos == (int)fi.size() )
+ append( field );
+ if ( pos > (int)fi.size() ) {
+ fi.resize( pos + 1 );
+ cnt++;
+ }
+ fi[ pos ] = i;
+ }
+ void remove( int i )
+ {
+ info inf;
+ if ( i >= (int)fi.count() )
+ return;
+ if ( fi[ i ].isValid() )
+ cnt--;
+ fi[ i ] = inf;
+ // clean up some memory
+ while ( fi.count() && !fi.back().isValid() )
+ fi.pop_back();
+ }
+ void clear()
+ {
+ fi.clear();
+ cnt = 0;
+ }
+ bool isEmpty()
+ {
+ return cnt == 0;
+ }
+ info* fieldInfo( int i )
+ {
+ if ( i < (int)fi.count() )
+ return &fi[i];
+ return 0;
+ }
+ uint count() const
+ {
+ return cnt;
+ }
+ bool tqcontains( int i ) const
+ {
+ return i >= 0 && i < (int)fi.count() && fi[ i ].isValid();
+ }
+private:
+ TQValueVector< info > fi;
+ uint cnt;
+};
+
+TQSqlRecordShared::~TQSqlRecordShared()
+{
+ if ( d )
+ delete d;
+}
+
+/*!
+ \class TQSqlRecord tqsqlfield.h
+ \brief The TQSqlRecord class encapsulates a database record, i.e. a
+ set of database fields.
+
+ \ingroup database
+ \module sql
+
+ The TQSqlRecord class encapsulates the functionality and
+ characteristics of a database record (usually a table or view within
+ the database). TQSqlRecords support adding and removing fields as
+ well as setting and retrieving field values.
+
+ TQSqlRecord is implicitly shared. This means you can make copies of
+ the record in time O(1). If multiple TQSqlRecord instances share
+ the same data and one is modifying the record's data then this
+ modifying instance makes a copy and modifies its private copy -
+ thus it does not affect other instances.
+
+ \sa TQSqlRecordInfo
+*/
+
+
+/*!
+ Constructs an empty record.
+*/
+
+TQSqlRecord::TQSqlRecord()
+{
+ sh = new TQSqlRecordShared( new TQSqlRecordPrivate() );
+}
+
+/*!
+ Constructs a copy of \a other.
+*/
+
+TQSqlRecord::TQSqlRecord( const TQSqlRecord& other )
+ : sh( other.sh )
+{
+ sh->ref();
+}
+
+/*!
+ Sets the record equal to \a other.
+*/
+
+TQSqlRecord& TQSqlRecord::operator=( const TQSqlRecord& other )
+{
+ other.sh->ref();
+ deref();
+ sh = other.sh;
+ return *this;
+}
+
+/*! \internal
+*/
+
+void TQSqlRecord::deref()
+{
+ if ( sh->deref() ) {
+ delete sh;
+ sh = 0;
+ }
+}
+
+/*! \internal
+*/
+
+bool TQSqlRecord::checkDetach()
+{
+ if ( sh->count > 1 ) {
+ sh->deref();
+ sh = new TQSqlRecordShared( new TQSqlRecordPrivate( *sh->d ) );
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlRecord::~TQSqlRecord()
+{
+ deref();
+}
+
+/*!
+ Returns the value of the field located at position \a i in the
+ record. If field \a i does not exist the resultant behaviour is
+ undefined.
+
+ This function should be used with \l{TQSqlQuery}s. When working
+ with a TQSqlCursor the \link TQSqlCursor::value() value(const
+ TQString&)\endlink overload which uses field names is more
+ appropriate.
+*/
+
+TQVariant TQSqlRecord::value( int i ) const
+{
+ const TQSqlField * f = field(i);
+
+ if( f )
+ return f->value();
+ return TQVariant();
+}
+
+/*!
+ \overload
+
+ Returns the value of the field called \a name in the record. If
+ field \a name does not exist the resultant behaviour is undefined.
+*/
+
+TQVariant TQSqlRecord::value( const TQString& name ) const
+{
+ const TQSqlField * f = field( name );
+
+ if( f )
+ return f->value();
+ return TQVariant();
+}
+
+/*!
+ Returns the name of the field at position \a i. If the field does
+ not exist, TQString::null is returned.
+*/
+
+TQString TQSqlRecord::fieldName( int i ) const
+{
+ const TQSqlField* f = field( i );
+ if ( f )
+ return f->name();
+ return TQString::null;
+}
+
+/*!
+ Returns the position of the field called \a name within the
+ record, or -1 if it cannot be found. Field names are not
+ case-sensitive. If more than one field matches, the first one is
+ returned.
+*/
+
+int TQSqlRecord::position( const TQString& name ) const
+{
+ for ( uint i = 0; i < count(); ++i ) {
+ if ( fieldName(i).upper() == name.upper() )
+ return i;
+ }
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQSqlRecord::position: unable to tqfind field %s", name.latin1() );
+#endif
+ return -1;
+}
+
+/*!
+ Returns the field at position \a i within the record, or 0 if it
+ cannot be found.
+*/
+
+TQSqlField* TQSqlRecord::field( int i )
+{
+ checkDetach();
+ if ( !sh->d->tqcontains( i ) ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQSqlRecord::field: index out of range: %d", i );
+#endif
+ return 0;
+ }
+ return &sh->d->fieldInfo( i )->field;
+}
+
+/*!
+ \overload
+
+ Returns the field called \a name within the record, or 0 if it
+ cannot be found. Field names are not case-sensitive.
+*/
+
+TQSqlField* TQSqlRecord::field( const TQString& name )
+{
+ checkDetach();
+ if ( !sh->d->tqcontains( position( name ) ) )
+ return 0;
+ return &sh->d->fieldInfo( position( name ) )->field;
+}
+
+
+/*!
+ \overload
+*/
+
+const TQSqlField* TQSqlRecord::field( int i ) const
+{
+ if ( !sh->d->tqcontains( i ) ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQSqlRecord::field: index out of range: %d", i );
+#endif // TQT_CHECK_RANGE
+ return 0;
+ }
+ return &sh->d->fieldInfo( i )->field;
+}
+
+/*!
+ \overload
+
+ Returns the field called \a name within the record, or 0 if it
+ cannot be found. Field names are not case-sensitive.
+*/
+
+const TQSqlField* TQSqlRecord::field( const TQString& name ) const
+{
+ if( !sh->d->tqcontains( position( name ) ) )
+ return 0;
+ return &sh->d->fieldInfo( position( name ) )->field;
+}
+
+/*!
+ Append a copy of field \a field to the end of the record.
+*/
+
+void TQSqlRecord::append( const TQSqlField& field )
+{
+ checkDetach();
+ sh->d->append( field );
+}
+
+/*!
+ Insert a copy of \a field at position \a pos. If a field already
+ exists at \a pos, it is removed.
+*/
+
+void TQSqlRecord::insert( int pos, const TQSqlField& field ) // ### 4.0: rename to ::tqreplace
+{
+ checkDetach();
+ sh->d->insert( pos, field );
+}
+
+/*!
+ Removes the field at \a pos. If \a pos does not exist, nothing
+ happens.
+*/
+
+void TQSqlRecord::remove( int pos )
+{
+ checkDetach();
+ sh->d->remove( pos );
+}
+
+/*!
+ Removes all the record's fields.
+
+ \sa clearValues()
+*/
+
+void TQSqlRecord::clear()
+{
+ checkDetach();
+ sh->d->clear();
+}
+
+/*!
+ Returns TRUE if there are no fields in the record; otherwise
+ returns FALSE.
+*/
+
+bool TQSqlRecord::isEmpty() const
+{
+ return sh->d->isEmpty();
+}
+
+
+/*!
+ Returns TRUE if there is a field in the record called \a name;
+ otherwise returns FALSE.
+*/
+
+bool TQSqlRecord::tqcontains( const TQString& name ) const
+{
+ for ( uint i = 0; i < count(); ++i ) {
+ if ( fieldName(i).upper() == name.upper() )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*!
+ Clears the value of all fields in the record. If \a nullify is
+ TRUE, (the default is FALSE), each field is set to NULL.
+*/
+
+void TQSqlRecord::clearValues( bool nullify )
+{
+ checkDetach();
+ int cnt = (int)count();
+ int i;
+ for ( i = 0; i < cnt; ++i ) {
+ field( i )->clear( nullify );
+ }
+}
+
+/*!
+ Sets the generated flag for the field called \a name to \a
+ generated. If the field does not exist, nothing happens. Only
+ fields that have \a generated set to TRUE are included in the SQL
+ that is generated, e.g. by TQSqlCursor.
+
+ \sa isGenerated()
+*/
+
+void TQSqlRecord::setGenerated( const TQString& name, bool generated )
+{
+ setGenerated( position( name ), generated );
+}
+
+/*!
+ \overload
+
+ Sets the generated flag for the field \a i to \a generated.
+
+ \sa isGenerated()
+*/
+
+void TQSqlRecord::setGenerated( int i, bool generated )
+{
+ checkDetach();
+ if ( !field( i ) )
+ return;
+ sh->d->fieldInfo( i )->nogen = !generated;
+}
+
+/*!
+ \internal
+ ### Remove in 4.0
+*/
+bool TQSqlRecord::isNull( int i )
+{
+ checkDetach();
+ TQSqlField* f = field( i );
+ if ( f ) {
+ return f->isNull();
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+ ### Remove in 4.0
+*/
+bool TQSqlRecord::isNull( const TQString& name )
+{
+ return isNull( position( name ) );
+}
+
+/*!
+ \overload
+
+ Returns TRUE if the field \a i is NULL or if there is no field at
+ position \a i; otherwise returns FALSE.
+
+ \sa fieldName()
+*/
+bool TQSqlRecord::isNull( int i ) const
+{
+ const TQSqlField* f = field( i );
+ if ( f ) {
+ return f->isNull();
+ }
+ return TRUE;
+}
+
+/*!
+ Returns TRUE if the field called \a name is NULL or if there is no
+ field called \a name; otherwise returns FALSE.
+
+ \sa position()
+*/
+bool TQSqlRecord::isNull( const TQString& name ) const
+{
+ return isNull( position( name ) );
+}
+
+/*!
+ Sets the value of field \a i to NULL. If the field does not exist,
+ nothing happens.
+*/
+void TQSqlRecord::setNull( int i )
+{
+ checkDetach();
+ TQSqlField* f = field( i );
+ if ( f ) {
+ f->setNull();
+ }
+}
+
+/*!
+ \overload
+
+ Sets the value of the field called \a name to NULL. If the field
+ does not exist, nothing happens.
+*/
+void TQSqlRecord::setNull( const TQString& name )
+{
+ setNull( position( name ) );
+}
+
+
+/*!
+ Returns TRUE if the record has a field called \a name and this
+ field is to be generated (the default); otherwise returns FALSE.
+
+ \sa setGenerated()
+*/
+bool TQSqlRecord::isGenerated( const TQString& name ) const
+{
+ return isGenerated( position( name ) );
+}
+
+/*!
+ \overload
+
+ Returns TRUE if the record has a field at position \a i and this
+ field is to be generated (the default); otherwise returns FALSE.
+
+ \sa setGenerated()
+*/
+bool TQSqlRecord::isGenerated( int i ) const
+{
+ if ( !field( i ) )
+ return FALSE;
+ return !sh->d->fieldInfo( i )->nogen;
+}
+
+
+/*!
+ Returns a list of all the record's field names as a string
+ separated by \a sep.
+
+ Note that fields which are not generated are \e not included (see
+ \l{isGenerated()}). The returned string is suitable, for example, for
+ generating SQL SELECT statements. If a \a prefix is specified,
+ e.g. a table name, all fields are prefixed in the form:
+
+ "\a{prefix}.\<fieldname\>"
+*/
+
+TQString TQSqlRecord::toString( const TQString& prefix, const TQString& sep ) const
+{
+ TQString pflist;
+ bool comma = FALSE;
+ for ( uint i = 0; i < count(); ++i ){
+ if ( isGenerated( field(i)->name() ) ) {
+ if( comma )
+ pflist += sep + " ";
+ pflist += createField( i, prefix );
+ comma = TRUE;
+ }
+ }
+ return pflist;
+}
+
+/*!
+ Returns a list of all the record's field names, each having the
+ prefix \a prefix.
+
+ Note that fields which have generated set to FALSE are \e not
+ included. (See \l{isGenerated()}). If \a prefix is supplied, e.g.
+ a table name, all fields are prefixed in the form:
+
+ "\a{prefix}.\<fieldname\>"
+*/
+
+TQStringList TQSqlRecord::toStringList( const TQString& prefix ) const
+{
+ TQStringList s;
+ for ( uint i = 0; i < count(); ++i ) {
+ if ( isGenerated( field(i)->name() ) )
+ s += createField( i, prefix );
+ }
+ return s;
+}
+
+/*! \internal
+*/
+
+TQString TQSqlRecord::createField( int i, const TQString& prefix ) const
+{
+ TQString f;
+ if ( !prefix.isEmpty() )
+ f = prefix + ".";
+ f += field( i )->name();
+ return f;
+}
+
+/*!
+ Returns the number of fields in the record.
+*/
+
+uint TQSqlRecord::count() const
+{
+ return sh->d->count();
+}
+
+/*!
+ Sets the value of the field at position \a i to \a val. If the
+ field does not exist, nothing happens.
+*/
+
+void TQSqlRecord::setValue( int i, const TQVariant& val )
+{
+ checkDetach();
+ TQSqlField* f = field( i );
+ if ( f ) {
+ f->setValue( val );
+ }
+}
+
+
+/*!
+ \overload
+
+ Sets the value of the field called \a name to \a val. If the field
+ does not exist, nothing happens.
+*/
+
+void TQSqlRecord::setValue( const TQString& name, const TQVariant& val )
+{
+ setValue( position( name ), val );
+}
+
+
+/******************************************/
+/******* TQSqlRecordInfo Impl ******/
+/******************************************/
+
+/*!
+ \class TQSqlRecordInfo tqsqlrecord.h
+ \brief The TQSqlRecordInfo class encapsulates a set of database field meta data.
+
+ \ingroup database
+ \module sql
+
+ This class is a TQValueList that holds a set of database field meta
+ data. Use tqcontains() to see if a given field name exists in the
+ record, and use tqfind() to get a TQSqlFieldInfo record for a named
+ field.
+
+ \sa TQValueList, TQSqlFieldInfo
+*/
+
+
+/*!
+ Constructs a TQSqlRecordInfo object based on the fields in the
+ TQSqlRecord \a other.
+*/
+TQSqlRecordInfo::TQSqlRecordInfo( const TQSqlRecord& other )
+{
+ for ( uint i = 0; i < other.count(); ++i ) {
+ push_back( TQSqlFieldInfo( *(other.field( i )), other.isGenerated( i ) ) );
+ }
+}
+
+/*!
+ Returns the number of times a field called \a fieldName occurs in
+ the record. Returns 0 if no field by that name could be found.
+*/
+TQSqlRecordInfo::size_type TQSqlRecordInfo::tqcontains( const TQString& fieldName ) const
+{
+ size_type i = 0;
+ TQString fName = fieldName.upper();
+ for( const_iterator it = begin(); it != end(); ++it ) {
+ if ( (*it).name().upper() == fName ) {
+ ++i;
+ }
+ }
+ return i;
+}
+
+/*!
+ Returns a TQSqlFieldInfo object for the first field in the record
+ which has the field name \a fieldName. If no matching field is
+ found then an empty TQSqlFieldInfo object is returned.
+*/
+TQSqlFieldInfo TQSqlRecordInfo::tqfind( const TQString& fieldName ) const
+{
+ TQString fName = fieldName.upper();
+ for( const_iterator it = begin(); it != end(); ++it ) {
+ if ( (*it).name().upper() == fName ) {
+ return *it;
+ }
+ }
+ return TQSqlFieldInfo();
+}
+
+/*!
+ Returns an empty TQSqlRecord based on the field information
+ in this TQSqlRecordInfo.
+*/
+TQSqlRecord TQSqlRecordInfo::toRecord() const
+{
+ TQSqlRecord buf;
+ for( const_iterator it = begin(); it != end(); ++it ) {
+ buf.append( (*it).toField() );
+ }
+ return buf;
+}
+
+/*!
+ \fn TQSqlRecordInfo::TQSqlRecordInfo()
+
+ Constructs an empty record info object
+*/
+
+/*!
+ \fn TQSqlRecordInfo::TQSqlRecordInfo( const TQSqlFieldInfoList& other )
+
+ Constructs a copy of \a other.
+*/
+
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlrecord.h b/tqtinterface/qt4/src/sql/tqsqlrecord.h
new file mode 100644
index 0000000..1dd99a3
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlrecord.h
@@ -0,0 +1,141 @@
+/****************************************************************************
+**
+** Definition of TQSqlRecord class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTQLRECORD_H
+#define TQSTQLRECORD_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqstringlist.h"
+#include "tqvariant.h"
+#include "tqsqlfield.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SQL
+
+class TQSqlRecordPrivate;
+
+class TQSqlRecordShared : public TQShared
+{
+public:
+ TQSqlRecordShared( TQSqlRecordPrivate* sqlRecordPrivate )
+ : d( sqlRecordPrivate )
+ {}
+ virtual ~TQSqlRecordShared();
+ TQSqlRecordPrivate* d;
+};
+
+class TQ_EXPORT TQSqlRecord
+{
+public:
+ TQSqlRecord();
+ TQSqlRecord( const TQSqlRecord& other );
+ TQSqlRecord& operator=( const TQSqlRecord& other );
+ virtual ~TQSqlRecord();
+ virtual TQVariant value( int i ) const;
+ virtual TQVariant value( const TQString& name ) const;
+ virtual void setValue( int i, const TQVariant& val );
+ virtual void setValue( const TQString& name, const TQVariant& val );
+ bool isGenerated( int i ) const;
+ bool isGenerated( const TQString& name ) const;
+ virtual void setGenerated( const TQString& name, bool generated );
+ virtual void setGenerated( int i, bool generated );
+ virtual void setNull( int i );
+ virtual void setNull( const TQString& name );
+ bool isNull( int i ); // remove in 4.0
+ bool isNull( const TQString& name ); // remove in 4.0
+ bool isNull( int i ) const;
+ bool isNull( const TQString& name ) const;
+
+ int position( const TQString& name ) const;
+ TQString fieldName( int i ) const;
+ TQSqlField* field( int i );
+ TQSqlField* field( const TQString& name );
+ const TQSqlField* field( int i ) const;
+ const TQSqlField* field( const TQString& name ) const;
+
+ virtual void append( const TQSqlField& field );
+ virtual void insert( int pos, const TQSqlField& field );
+ virtual void remove( int pos );
+
+ bool isEmpty() const;
+ bool tqcontains( const TQString& name ) const;
+ virtual void clear();
+ virtual void clearValues( bool nullify = FALSE );
+ uint count() const;
+ virtual TQString toString( const TQString& prefix = TQString::null,
+ const TQString& sep = "," ) const;
+ virtual TQStringList toStringList( const TQString& prefix = TQString::null ) const;
+
+private:
+ TQString createField( int i, const TQString& prefix ) const;
+ void deref();
+ bool checkDetach();
+ TQSqlRecordShared* sh;
+};
+
+/******************************************/
+/******* TQSqlRecordInfo Class ******/
+/******************************************/
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueList<TQSqlFieldInfo>;
+// TQMOC_SKIP_END
+#endif
+
+typedef TQValueList<TQSqlFieldInfo> TQSqlFieldInfoList;
+
+class TQ_EXPORT TQSqlRecordInfo: public TQSqlFieldInfoList
+{
+public:
+ TQSqlRecordInfo(): TQSqlFieldInfoList() {}
+ TQSqlRecordInfo( const TQSqlFieldInfoList& other ): TQSqlFieldInfoList( other ) {}
+ TQSqlRecordInfo( const TQSqlRecord& other );
+
+ size_type tqcontains( const TQString& fieldName ) const;
+ TQSqlFieldInfo tqfind( const TQString& fieldName ) const;
+ TQSqlRecord toRecord() const;
+
+};
+
+
+#endif // TQT_NO_SQL
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlresult.cpp b/tqtinterface/qt4/src/sql/tqsqlresult.cpp
new file mode 100644
index 0000000..0555929
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlresult.cpp
@@ -0,0 +1,368 @@
+/****************************************************************************
+**
+** Implementation of TQSqlResult class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlresult.h"
+#include "private/tqsqlextension_p.h"
+
+#ifndef TQT_NO_SQL
+
+class TQSqlResultPrivate
+{
+public:
+ const TQSqlDriver* sqldriver;
+ int idx;
+ TQString sql;
+ bool active;
+ bool isSel;
+ TQSqlError error;
+ TQSqlExtension * ext;
+};
+
+/*!
+ \class TQSqlResult
+ \brief The TQSqlResult class provides an abstract interface for
+ accessing data from SQL databases.
+
+ \ingroup database
+ \module sql
+
+ Normally you would use TQSqlQuery instead of TQSqlResult since TQSqlQuery
+ provides a generic wrapper for database-specific implementations of
+ TQSqlResult.
+
+ \sa TQSql
+*/
+
+
+/*!
+ Protected constructor which creates a TQSqlResult using database \a
+ db. The object is initialized to an inactive state.
+*/
+
+TQSqlResult::TQSqlResult( const TQSqlDriver * db ): forwardOnly( FALSE )
+{
+ d = new TQSqlResultPrivate();
+ d->sqldriver = db;
+ d->idx = TQSql::BeforeFirst;
+ d->isSel = FALSE;
+ d->active = FALSE;
+ d->ext = new TQSqlExtension();
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQSqlResult::~TQSqlResult()
+{
+ if ( d->ext )
+ delete d->ext;
+ delete d;
+}
+
+/*!
+ Sets the current query for the result to \a query. The result must
+ be reset() in order to execute the query on the database.
+*/
+
+void TQSqlResult::setQuery( const TQString& query )
+{
+ d->sql = query;
+}
+
+/*!
+ Returns the current SQL query text, or TQString::null if there is none.
+*/
+
+TQString TQSqlResult::lastQuery() const
+{
+ return d->sql;
+}
+
+/*!
+ Returns the current (zero-based) position of the result.
+*/
+
+int TQSqlResult::at() const
+{
+ return d->idx;
+}
+
+
+/*!
+ Returns TRUE if the result is positioned on a valid record (that
+ is, the result is not positioned before the first or after the
+ last record); otherwise returns FALSE.
+*/
+
+bool TQSqlResult::isValid() const
+{
+ return ( d->idx != TQSql::BeforeFirst && \
+ d->idx != TQSql::AfterLast ) ? TRUE : FALSE;
+}
+
+/*!
+ \fn bool TQSqlResult::isNull( int i )
+
+ Returns TRUE if the field at position \a i is NULL; otherwise
+ returns FALSE.
+*/
+
+
+/*!
+ Returns TRUE if the result has records to be retrieved; otherwise
+ returns FALSE.
+*/
+
+bool TQSqlResult::isActive() const
+{
+ return d->active;
+}
+
+/*!
+ Protected function provided for derived classes to set the
+ internal (zero-based) result index to \a at.
+
+ \sa at()
+*/
+
+void TQSqlResult::setAt( int at )
+{
+ d->idx = at;
+}
+
+
+/*!
+ Protected function provided for derived classes to indicate
+ whether or not the current statement is a SQL SELECT statement.
+ The \a s parameter should be TRUE if the statement is a SELECT
+ statement, or FALSE otherwise.
+*/
+
+void TQSqlResult::setSelect( bool s )
+{
+ d->isSel = s;
+}
+
+/*!
+ Returns TRUE if the current result is from a SELECT statement;
+ otherwise returns FALSE.
+*/
+
+bool TQSqlResult::isSelect() const
+{
+ return d->isSel;
+}
+
+/*!
+ Returns the driver associated with the result.
+*/
+
+const TQSqlDriver* TQSqlResult::driver() const
+{
+ return d->sqldriver;
+}
+
+
+/*!
+ Protected function provided for derived classes to set the
+ internal active state to the value of \a a.
+
+ \sa isActive()
+*/
+
+void TQSqlResult::setActive( bool a )
+{
+ d->active = a;
+}
+
+/*!
+ Protected function provided for derived classes to set the last
+ error to the value of \a e.
+
+ \sa lastError()
+*/
+
+void TQSqlResult::setLastError( const TQSqlError& e )
+{
+ d->error = e;
+}
+
+
+/*!
+ Returns the last error associated with the result.
+*/
+
+TQSqlError TQSqlResult::lastError() const
+{
+ return d->error;
+}
+
+/*!
+ \fn int TQSqlResult::size()
+
+ Returns the size of the result or -1 if it cannot be determined.
+*/
+
+/*!
+ \fn int TQSqlResult::numRowsAffected()
+
+ Returns the number of rows affected by the last query executed.
+*/
+
+/*!
+ \fn TQVariant TQSqlResult::data( int i )
+
+ Returns the data for field \a i (zero-based) as a TQVariant. This
+ function is only called if the result is in an active state and is
+ positioned on a valid record and \a i is non-negative.
+ Derived classes must reimplement this function and return the value
+ of field \a i, or TQVariant() if it cannot be determined.
+*/
+
+/*!
+ \fn bool TQSqlResult::reset( const TQString& query )
+
+ Sets the result to use the SQL statement \a query for subsequent
+ data retrieval. Derived classes must reimplement this function and
+ apply the \a query to the database. This function is called only
+ after the result is set to an inactive state and is positioned
+ before the first record of the new result. Derived classes should
+ return TRUE if the query was successful and ready to be used,
+ or FALSE otherwise.
+*/
+
+/*!
+ \fn bool TQSqlResult::fetch( int i )
+
+ Positions the result to an arbitrary (zero-based) index \a i. This
+ function is only called if the result is in an active state. Derived
+ classes must reimplement this function and position the result to the
+ index \a i, and call setAt() with an appropriate value. Return TRUE
+ to indicate success, or FALSE to signify failure.
+*/
+
+/*!
+ \fn bool TQSqlResult::fetchFirst()
+
+ Positions the result to the first record in the result. This
+ function is only called if the result is in an active state.
+ Derived classes must reimplement this function and position the result
+ to the first record, and call setAt() with an appropriate value.
+ Return TRUE to indicate success, or FALSE to signify failure.
+*/
+
+/*!
+ \fn bool TQSqlResult::fetchLast()
+
+ Positions the result to the last record in the result. This
+ function is only called if the result is in an active state.
+ Derived classes must reimplement this function and position the result
+ to the last record, and call setAt() with an appropriate value.
+ Return TRUE to indicate success, or FALSE to signify failure.
+*/
+
+/*!
+ Positions the result to the next available record in the result.
+ This function is only called if the result is in an active state.
+ The default implementation calls fetch() with the next index.
+ Derived classes can reimplement this function and position the result
+ to the next record in some other way, and call setAt() with an
+ appropriate value. Return TRUE to indicate success, or FALSE to
+ signify failure.
+*/
+
+bool TQSqlResult::fetchNext()
+{
+ return fetch( at() + 1 );
+}
+
+/*!
+ Positions the result to the previous available record in the
+ result. This function is only called if the result is in an active
+ state. The default implementation calls fetch() with the previous
+ index. Derived classes can reimplement this function and position the
+ result to the next record in some other way, and call setAt() with
+ an appropriate value. Return TRUE to indicate success, or FALSE to
+ signify failure.
+*/
+
+bool TQSqlResult::fetchPrev()
+{
+ return fetch( at() - 1 );
+}
+
+/*!
+ Returns TRUE if you can only scroll forward through a result set;
+ otherwise returns FALSE.
+*/
+bool TQSqlResult::isForwardOnly() const
+{
+ return forwardOnly;
+}
+
+/*!
+ Sets forward only mode to \a forward. If forward is TRUE only
+ fetchNext() is allowed for navigating the results. Forward only
+ mode needs far less memory since results do not have to be cached.
+ forward only mode is off by default.
+
+ \sa fetchNext()
+*/
+void TQSqlResult::setForwardOnly( bool forward )
+{
+ forwardOnly = forward;
+}
+
+// XXX BCI HACK - remove in 4.0
+/*! \internal */
+void TQSqlResult::setExtension( TQSqlExtension * ext )
+{
+ if ( d->ext )
+ delete d->ext;
+ d->ext = ext;
+}
+
+/*! \internal */
+TQSqlExtension * TQSqlResult::extension()
+{
+ return d->ext;
+}
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/tqsqlresult.h b/tqtinterface/qt4/src/sql/tqsqlresult.h
new file mode 100644
index 0000000..5da9bc6
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlresult.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Definition of TQSqlResult class
+**
+** Created : 2000-11-03
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTQLRESULT_H
+#define TQSTQLRESULT_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqvariant.h"
+#include "tqsqlerror.h"
+#include "tqsqlfield.h"
+#include "tqsql.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQSqlDriver;
+class TQSql;
+class TQSqlResultPrivate;
+class TQSqlExtension;
+
+class TQM_EXPORT_SQL TQSqlResult
+{
+friend class TQSqlQuery;
+friend class TQSqlResultShared;
+public:
+ virtual ~TQSqlResult();
+
+ // BCI HACK - remove in 4.0
+ void setExtension( TQSqlExtension * ext );
+ TQSqlExtension * extension();
+
+protected:
+ TQSqlResult(const TQSqlDriver * db );
+ int at() const;
+ TQString lastQuery() const;
+ TQSqlError lastError() const;
+ bool isValid() const;
+ bool isActive() const;
+ bool isSelect() const;
+ bool isForwardOnly() const;
+ const TQSqlDriver* driver() const;
+ virtual void setAt( int at );
+ virtual void setActive( bool a );
+ virtual void setLastError( const TQSqlError& e );
+ virtual void setQuery( const TQString& query );
+ virtual void setSelect( bool s );
+ virtual void setForwardOnly( bool forward );
+
+ virtual TQVariant data( int i ) = 0;
+ virtual bool isNull( int i ) = 0;
+ virtual bool reset ( const TQString& sqlquery ) = 0;
+ virtual bool fetch( int i ) = 0;
+ virtual bool fetchNext();
+ virtual bool fetchPrev();
+ virtual bool fetchFirst() = 0;
+ virtual bool fetchLast() = 0;
+ virtual int size() = 0;
+ virtual int numRowsAffected() = 0;
+private:
+ TQSqlResultPrivate* d;
+ bool forwardOnly;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSqlResult( const TQSqlResult & );
+ TQSqlResult &operator=( const TQSqlResult & );
+#endif
+};
+
+#endif // TQT_NO_SQL
+#endif
diff --git a/tqtinterface/qt4/src/sql/tqsqlselectcursor.cpp b/tqtinterface/qt4/src/sql/tqsqlselectcursor.cpp
new file mode 100644
index 0000000..77d0548
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlselectcursor.cpp
@@ -0,0 +1,249 @@
+/****************************************************************************
+**
+** Definition of TQSqlSelectCursor class
+**
+** Created : 2002-11-13
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsqlselectcursor.h"
+#include "tqsqldriver.h"
+
+#ifndef TQT_NO_SQL
+
+class TQSqlSelectCursorPrivate
+{
+public:
+ TQSqlSelectCursorPrivate() : populated( FALSE ) {}
+ TQString query;
+ bool populated : 1;
+};
+
+/*!
+ \class TQSqlSelectCursor tqsqlselectcursor.h
+ \brief The TQSqlSelectCursor class provides browsing of general SQL
+ SELECT statements.
+
+ \ingroup database
+ \module sql
+
+ TQSqlSelectCursor is a convenience class that makes it possible to
+ display result sets from general SQL \c SELECT statements in
+ data-aware TQt widgets. TQSqlSelectCursor is read-only and does not
+ support \c INSERT, \c UPDATE or \c DELETE operations.
+
+ Pass the query in at construction time, or use the
+ TQSqlSelectCursor::exec() function.
+
+ Example:
+ \code
+ ...
+ TQSqlSelectCursor* cur = new TQSqlSelectCursor( "SELECT id, firstname, lastname FROM author" );
+ TQDataTable* table = new TQDataTable( this );
+ table->setSqlCursor( cur, TRUE, TRUE );
+ table->refresh();
+ ...
+ cur->exec( "SELECT * FROM books" );
+ table->refresh();
+ ...
+ \endcode
+*/
+
+/*!
+ Constructs a read only cursor on database \a db using the query \a query.
+ */
+TQSqlSelectCursor::TQSqlSelectCursor( const TQString& query, TQSqlDatabase* db )
+ : TQSqlCursor( TQString::null, FALSE, db )
+{
+ d = new TQSqlSelectCursorPrivate;
+ d->query = query;
+ TQSqlCursor::setMode( ReadOnly );
+ if ( !query.isNull() )
+ exec( query );
+}
+
+/*! Constructs a copy of \a other */
+TQSqlSelectCursor::TQSqlSelectCursor( const TQSqlSelectCursor& other )
+ : TQSqlCursor( other )
+{
+ d = new TQSqlSelectCursorPrivate;
+ d->query = other.d->query;
+ d->populated = other.d->populated;
+}
+
+/*! Destroys the object and frees any allocated resources */
+TQSqlSelectCursor::~TQSqlSelectCursor()
+{
+ delete d;
+}
+
+/*! \reimp */
+bool TQSqlSelectCursor::exec( const TQString& query )
+{
+ d->query = query;
+ bool ret = TQSqlCursor::exec( query );
+ if ( ret ) {
+ TQSqlCursor::clear();
+ populateCursor();
+ }
+ return ret;
+}
+
+/*! \fn bool TQSqlSelectCursor::select()
+ \reimp
+*/
+
+/*! \reimp */
+bool TQSqlSelectCursor::select( const TQString&, const TQSqlIndex& )
+{
+ bool ret = TQSqlCursor::exec( d->query );
+ if ( ret && !d->populated )
+ populateCursor();
+ return ret;
+}
+
+/*! \internal */
+void TQSqlSelectCursor::populateCursor()
+{
+ TQSqlRecordInfo inf = driver()->recordInfo( *(TQSqlQuery*)this );
+ for ( TQSqlRecordInfo::const_iterator it = inf.begin(); it != inf.end(); ++it )
+ TQSqlCursor::append( *it );
+ d->populated = TRUE;
+}
+
+/*! \fn TQSqlIndex TQSqlSelectCursor::primaryIndex( bool ) const
+ \reimp
+*/
+
+/*! \fn TQSqlIndex TQSqlSelectCursor::index( const TQStringList& ) const
+ \reimp
+*/
+
+/*! \fn TQSqlIndex TQSqlSelectCursor::index( const TQString& ) const
+ \reimp
+*/
+
+/*! \fn TQSqlIndex TQSqlSelectCursor::index( const char* ) const
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::setPrimaryIndex( const TQSqlIndex& )
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::append( const TQSqlFieldInfo& )
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::insert( int, const TQSqlFieldInfo& )
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::remove( int )
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::clear()
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::setGenerated( const TQString&, bool )
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::setGenerated( int, bool )
+ \reimp
+*/
+
+/*! \fn TQSqlRecord* TQSqlSelectCursor::editBuffer( bool )
+ \reimp
+*/
+
+/*! \fn TQSqlRecord* TQSqlSelectCursor::primeInsert()
+ \reimp
+*/
+
+/*! \fn TQSqlRecord* TQSqlSelectCursor::primeUpdate()
+ \reimp
+*/
+
+/*! \fn TQSqlRecord* TQSqlSelectCursor::primeDelete()
+ \reimp
+*/
+
+/*! \fn int TQSqlSelectCursor::insert( bool )
+ \reimp
+*/
+
+/*! \fn int TQSqlSelectCursor::update( bool )
+ \reimp
+*/
+
+/*! \fn int TQSqlSelectCursor::del( bool )
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::setMode( int )
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::setSort( const TQSqlIndex& )
+ \reimp
+*/
+
+/*! \fn TQSqlIndex TQSqlSelectCursor::sort() const
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::setFilter( const TQString& )
+ \reimp
+*/
+
+/*! \fn TQString TQSqlSelectCursor::filter() const
+ \reimp
+*/
+
+/*! \fn void TQSqlSelectCursor::setName( const TQString&, bool )
+ \reimp
+*/
+
+/*! \fn TQString TQSqlSelectCursor::name() const
+ \reimp
+*/
+
+/*! \fn TQString TQSqlSelectCursor::toString( const TQString&, const TQString& ) const
+ \reimp
+*/
+#endif // TQT_NO_SQL
diff --git a/tqtinterface/qt4/src/sql/tqsqlselectcursor.h b/tqtinterface/qt4/src/sql/tqsqlselectcursor.h
new file mode 100644
index 0000000..db72664
--- /dev/null
+++ b/tqtinterface/qt4/src/sql/tqsqlselectcursor.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Definition of TQSqlSelectCursor class
+**
+** Created : 2002-11-13
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the sql module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTQLSELECTCURSOR_H
+#define TQSTQLSELECTCURSOR_H
+
+#ifndef TQT_H
+#include "tqsqlcursor.h"
+#endif // TQT_H
+
+#if !defined( TQT_MODULE_SQL ) || defined( TQT_LICENSE_PROFESSIONAL )
+#define TQM_EXPORT_SQL
+#else
+#define TQM_EXPORT_SQL TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SQL
+
+class TQSqlSelectCursorPrivate;
+
+class TQM_EXPORT_SQL TQSqlSelectCursor : public TQSqlCursor
+{
+public:
+ TQSqlSelectCursor( const TQString& query = TQString::null, TQSqlDatabase* db = 0 );
+ TQSqlSelectCursor( const TQSqlSelectCursor& other );
+ ~TQSqlSelectCursor();
+ bool exec( const TQString& query );
+ bool select() { return TQSqlCursor::select(); }
+
+protected:
+ TQSqlIndex primaryIndex( bool = TRUE ) const { return TQSqlIndex(); }
+ TQSqlIndex index( const TQStringList& ) const { return TQSqlIndex(); }
+ TQSqlIndex index( const TQString& ) const { return TQSqlIndex(); }
+ TQSqlIndex index( const char* ) const { return TQSqlIndex(); }
+ void setPrimaryIndex( const TQSqlIndex& ) {}
+ void append( const TQSqlFieldInfo& ) {}
+ void insert( int, const TQSqlFieldInfo& ) {}
+ void remove( int ) {}
+ void clear() {}
+ void setGenerated( const TQString&, bool ) {}
+ void setGenerated( int, bool ) {}
+ TQSqlRecord* editBuffer( bool = FALSE ) { return 0; }
+ TQSqlRecord* primeInsert() { return 0; }
+ TQSqlRecord* primeUpdate() { return 0; }
+ TQSqlRecord* primeDelete() { return 0; }
+ int insert( bool = TRUE ) { return 0; }
+ int update( bool = TRUE ) { return 0; }
+ int del( bool = TRUE ) { return 0; }
+ void setMode( int ) {}
+
+ void setSort( const TQSqlIndex& ) {}
+ TQSqlIndex sort() const { return TQSqlIndex(); }
+ void setFilter( const TQString& ) {}
+ TQString filter() const { return TQString::null; }
+ void setName( const TQString&, bool = TRUE ) {}
+ TQString name() const { return TQString::null; }
+ TQString toString( const TQString& = TQString::null, const TQString& = "," ) const { return TQString::null; }
+ bool select( const TQString &, const TQSqlIndex& = TQSqlIndex() );
+
+private:
+ void populateCursor();
+
+ TQSqlSelectCursorPrivate * d;
+};
+
+#endif // TQT_NO_SQL
+#endif // TQSTQLSELECTCURSOR_H
diff --git a/tqtinterface/qt4/src/styles/qt_styles.pri b/tqtinterface/qt4/src/styles/qt_styles.pri
new file mode 100644
index 0000000..baf36d5
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/qt_styles.pri
@@ -0,0 +1,140 @@
+# Qt styles module
+
+styles {
+ STYLES_P = styles
+ HEADERS +=$$STYLES_H/tqstylefactory.h \
+ $$STYLES_P/tqstyleinterface_p.h \
+ $$STYLES_H/tqstyleplugin.h \
+ $$STYLES_H/tqcommonstyle.h
+ SOURCES +=$$STYLES_CPP/tqstylefactory.cpp \
+ $$STYLES_CPP/tqstyleplugin.cpp \
+ $$STYLES_CPP/tqcommonstyle.cpp
+
+ tqcontains( styles, all ) {
+ styles += mac cde motifplus sgi platinum compact interlace windows motif
+ }
+
+ x11|embedded|!macx-*:styles -= mac
+ tqcontains( styles, mac ) {
+ HEADERS +=$$STYLES_H/tqmacstyle_mac.h \
+ $$STYLES_H/tqmacstylepixmaps_mac_p.h
+ SOURCES +=$$STYLES_CPP/tqmacstyle_mac.cpp
+ HEADERS *= $$STYLES_CPP/tqaquastyle_p.h
+ SOURCES *= $$STYLES_CPP/tqaquastyle_p.cpp
+
+ !tqcontains( styles, windows ) {
+ message( mac requires windows )
+ styles += windows
+ }
+ }
+ else:DEFINES += TQT_NO_STYLE_MAC
+
+ #embedded|!macx-*:styles -= aqua
+ tqcontains( styles, aqua ) {
+ HEADERS += $$STYLES_H/tqaquastyle.h
+ SOURCES += $$STYLES_CPP/tqaquastyle.cpp
+ HEADERS *= $$STYLES_CPP/tqaquastyle_p.h
+ SOURCES *= $$STYLES_CPP/tqaquastyle_p.cpp
+
+ !tqcontains( styles, windows ) {
+ message( aqua requires windows )
+ styles += windows
+ }
+ }
+ else:DEFINES += TQT_NO_STYLE_AQUA
+
+ tqcontains( styles, cde ) {
+ HEADERS +=$$STYLES_H/tqcdestyle.h
+ SOURCES +=$$STYLES_CPP/tqcdestyle.cpp
+
+ !tqcontains( styles, motif ) {
+ message( cde requires motif )
+ styles += motif
+ }
+ }
+ else:DEFINES += TQT_NO_STYLE_CDE
+
+ tqcontains( styles, motifplus ) {
+ HEADERS +=$$STYLES_H/tqmotifplusstyle.h
+ SOURCES +=$$STYLES_CPP/tqmotifplusstyle.cpp
+ !tqcontains( styles, motif ) {
+ message( motifplus requires motif )
+ styles += motif
+ }
+ }
+ else:DEFINES += TQT_NO_STYLE_MOTIFPLUS
+
+ tqcontains( styles, interlace ) {
+ HEADERS +=$$STYLES_H/tqinterlacestyle.h
+ SOURCES +=$$STYLES_CPP/tqinterlacestyle.cpp
+ !tqcontains( styles, windows ) {
+ message( interlace requires windows )
+ styles += windows
+ }
+ }
+ else:DEFINES += TQT_NO_STYLE_INTERLACE
+
+ tqcontains( styles, platinum ) {
+ HEADERS +=$$STYLES_H/tqplatinumstyle.h
+ SOURCES +=$$STYLES_CPP/tqplatinumstyle.cpp
+ !tqcontains( styles, windows ) {
+ message( platinum requires windows )
+ styles += windows
+ }
+ }
+ else:DEFINES += TQT_NO_STYLE_PLATINUM
+
+ tqcontains( styles, windowsxp ) {
+ HEADERS +=$$STYLES_H/tqwindowsxpstyle.h
+ SOURCES +=$$STYLES_CPP/tqwindowsxpstyle.cpp
+ !tqcontains( styles, windowsxp ) {
+ message( windowsxp requires windows )
+ styles += windows
+ }
+ }
+ else:DEFINES += TQT_NO_STYLE_WINDOWSXP
+
+ tqcontains( styles, sgi ) {
+ HEADERS +=$$STYLES_H/tqsgistyle.h
+ SOURCES +=$$STYLES_CPP/tqsgistyle.cpp
+ !tqcontains( styles, motif ) {
+ message( sgi requires motif )
+ styles += motif
+ }
+ }
+ else:DEFINES += TQT_NO_STYLE_SGI
+
+ tqcontains( styles, compact ) {
+ HEADERS +=$$STYLES_H/tqcompactstyle.h
+ SOURCES +=$$STYLES_CPP/tqcompactstyle.cpp
+ !tqcontains( styles, windows ) {
+ message( compact requires windows )
+ styles += windows
+ }
+ }
+ else:DEFINES += TQT_NO_STYLE_COMPACT
+
+ wince-*:styles += pocketpc
+ tqcontains( styles, pocketpc ) {
+ HEADERS +=$$STYLES_H/tqpocketpcstyle_wce.h
+ SOURCES +=$$STYLES_CPP/tqpocketpcstyle_wce.cpp
+
+ !tqcontains( styles, windows ) {
+ message( pocketpc requires windows )
+ styles += windows
+ }
+ }
+ else:DEFINES += TQT_NO_STYLE_POCKETPC
+
+ tqcontains( styles, windows ) {
+ HEADERS +=$$STYLES_H/tqwindowsstyle.h
+ SOURCES +=$$STYLES_CPP/tqwindowsstyle.cpp
+ }
+ else:DEFINES += TQT_NO_STYLE_WINDOWS
+
+ tqcontains( styles, motif ) {
+ HEADERS +=$$STYLES_H/tqmotifstyle.h
+ SOURCES +=$$STYLES_CPP/tqmotifstyle.cpp
+ }
+ else:DEFINES += TQT_NO_STYLE_MOTIF
+}
diff --git a/tqtinterface/qt4/src/styles/tqcdestyle.cpp b/tqtinterface/qt4/src/styles/tqcdestyle.cpp
new file mode 100644
index 0000000..8dda161
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqcdestyle.cpp
@@ -0,0 +1,367 @@
+/****************************************************************************
+**
+** Implementation of CDE-like style class
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcdestyle.h"
+
+#if !defined(TQT_NO_STYLE_CDE) || defined(TQT_PLUGIN)
+
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqbutton.h"
+#include <limits.h>
+
+/*!
+ \class TQCDEStyle tqcdestyle.h
+ \brief The TQCDEStyle class provides a CDE look and feel.
+
+ \ingroup appearance
+
+ This style provides a slightly improved Motif look similar to some
+ versions of the Common Desktop Environment (CDE). The main
+ differences are thinner frames and more modern radio buttons and
+ checkboxes. Together with a dark background and a bright
+ text/foreground color, the style looks quite attractive (at least
+ for Motif fans).
+
+ Note that the functions provided by TQCDEStyle are
+ reimplementations of TQStyle functions; see TQStyle for their
+ documentation.
+*/
+
+/*!
+ Constructs a TQCDEStyle.
+
+ If \a useHighlightCols is FALSE (the default), then the style will
+ polish the application's color palette to emulate the Motif way of
+ highlighting, which is a simple inversion between the base and the
+ text color.
+*/
+TQCDEStyle::TQCDEStyle( bool useHighlightCols ) : TQMotifStyle( useHighlightCols )
+{
+}
+
+/*!
+ Destroys the style.
+*/
+TQCDEStyle::~TQCDEStyle()
+{
+}
+
+
+/*!\reimp
+*/
+int TQCDEStyle::tqpixelMetric( PixelMetric metric, const TQWidget *widget ) const
+{
+ int ret;
+
+ switch( metric ) {
+ case PM_DefaultFrameWidth:
+ ret = 1;
+ break ;
+ case PM_MenuBarFrameWidth:
+ ret = 1;
+ break;
+ case PM_ScrollBarExtent:
+ ret = 13;
+ break;
+ default:
+ ret = TQMotifStyle::tqpixelMetric( metric, widget );
+ break;
+ }
+ return ret;
+}
+
+/*! \reimp
+*/
+void TQCDEStyle::tqdrawControl( ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how,
+ const TQStyleOption& opt ) const
+{
+
+ switch( element ) {
+ case CE_MenuBarItem:
+ {
+ if ( how & Style_Active ) // active item
+ qDrawShadePanel( p, r, cg, TRUE, 1,
+ &cg.brush( TQColorGroup::Button ) );
+ else // other item
+ p->fillRect( r, cg.brush( TQColorGroup::Button ) );
+ TQCommonStyle::tqdrawControl( element, p, widget, r, cg, how, opt );
+ break;
+ }
+ default:
+ TQMotifStyle::tqdrawControl( element, p, widget, r, cg, how, opt );
+ break;
+ }
+
+
+}
+
+/*! \reimp
+*/
+void TQCDEStyle::tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ switch( pe ) {
+ case PE_Indicator: {
+#ifndef TQT_NO_BUTTON
+ bool down = flags & Style_Down;
+ bool on = flags & Style_On;
+ bool showUp = !( down ^ on );
+ TQBrush fill = showUp || flags & Style_NoChange ? cg.brush( TQColorGroup::Button ) : cg.brush( TQColorGroup::Mid );
+ qDrawShadePanel( p, r, cg, !showUp, tqpixelMetric( PM_DefaultFrameWidth ), &cg.brush( TQColorGroup::Button ) );
+
+ if ( !( flags & Style_Off ) ) {
+ TQPointArray a( 7 * 2 );
+ int i, xx, yy;
+ xx = r.x() + 3;
+ yy = r.y() + 5;
+ for ( i = 0; i < 3; i++ ) {
+ a.setPoint( 2 * i, xx, yy );
+ a.setPoint( 2 * i + 1, xx, yy + 2 );
+ xx++; yy++;
+ }
+ yy -= 2;
+ for ( i = 3; i < 7; i++ ) {
+ a.setPoint( 2 * i, xx, yy );
+ a.setPoint( 2 * i + 1, xx, yy + 2 );
+ xx++; yy--;
+ }
+ if ( flags & Style_NoChange )
+ p->setPen( cg.dark() );
+ else
+ p->setPen( cg.foreground() );
+ p->drawLineSegments( a );
+ }
+#endif
+ }
+ break;
+ case PE_ExclusiveIndicator:
+ {
+#define TQCOORDARRLEN(x) sizeof(x)/(sizeof(TQCOORD)*2)
+ static const TQCOORD pts1[] = { // up left lines
+ 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 };
+ static const TQCOORD pts4[] = { // bottom right lines
+ 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7,
+ 11,4, 10,3, 10,2 };
+ static const TQCOORD pts5[] = { // inner fill
+ 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 };
+ bool down = flags & Style_Down;
+ bool on = flags & Style_On;
+ p->eraseRect( r );
+ TQPointArray a( TQCOORDARRLEN(pts1), pts1 );
+ a.translate( r.x(), r.y() );
+ p->setPen( ( down || on ) ? cg.dark() : cg.light() );
+ p->drawPolyline( a );
+ a.setPoints( TQCOORDARRLEN(pts4), pts4 );
+ a.translate( r.x(), r.y() );
+ p->setPen( ( down || on ) ? cg.light() : cg.dark() );
+ p->drawPolyline( a );
+ a.setPoints( TQCOORDARRLEN(pts5), pts5 );
+ a.translate( r.x(), r.y() );
+ TQColor fillColor = on ? cg.dark() : cg.background();
+ p->setPen( fillColor );
+ p->setBrush( on ? cg.brush( TQColorGroup::Dark ) :
+ cg.brush( TQColorGroup::Background ) );
+ p->drawPolygon( a );
+ break;
+ }
+
+ case PE_ExclusiveIndicatorMask:
+ {
+ static const TQCOORD pts1[] = {
+ // up left lines
+ 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1,
+ // bottom right lines
+ 10,2, 10,3, 11,4, 11,7, 10,8, 10,9, 9,10, 8,10, 7,11, 4,11, 3,10, 2,10
+ };
+ TQPointArray a(TQCOORDARRLEN(pts1), pts1);
+ a.translate(r.x(), r.y());
+ p->setPen(Qt::color1);
+ p->setBrush(Qt::color1);
+ p->drawPolygon(a);
+ break;
+ }
+ case PE_ArrowUp:
+ case PE_ArrowDown:
+ case PE_ArrowRight:
+ case PE_ArrowLeft: {
+ TQRect rect = r;
+ TQPointArray bFill; // fill polygon
+ TQPointArray bTop; // top shadow.
+ TQPointArray bBot; // bottom shadow.
+ TQPointArray bLeft; // left shadow.
+ TQWMatrix matrix; // xform matrix
+ bool vertical = pe == PE_ArrowUp || pe == PE_ArrowDown;
+ bool horizontal = !vertical;
+ int dim = rect.width() < rect.height() ? rect.width() : rect.height();
+ int colspec = 0x0000; // color specification array
+
+ if ( dim < 2 ) // too small arrow
+ return;
+
+ // adjust size and center (to fix rotation below)
+ if ( rect.width() > dim ) {
+ rect.setX( rect.x() + ( ( rect.width() - dim ) / 2 ) );
+ rect.setWidth( dim );
+ }
+ if ( rect.height() > dim ) {
+ rect.setY( rect.y() + ( ( rect.height() - dim ) / 2 ) );
+ rect.setHeight( dim );
+ }
+
+ if ( dim > 3 ) {
+ bFill.resize( dim & 1 ? 3 : 4 );
+ bTop.resize( 2 );
+ bBot.resize( 2 );
+ bLeft.resize( 2 );
+ bLeft.putPoints( 0, 2, 0, 0, 0, dim-1 );
+ bTop.putPoints( 0, 2, 1, 0, dim-1, dim/2 );
+ bBot.putPoints( 0, 2, 1, dim-1, dim-1, dim/2 );
+
+ if ( dim > 6 ) { // dim>6: must fill interior
+ bFill.putPoints( 0, 2, 1, dim-1, 1, 1 );
+ if ( dim & 1 ) // if size is an odd number
+ bFill.setPoint( 2, dim - 2, dim / 2 );
+ else
+ bFill.putPoints( 2, 2, dim-2, dim/2-1, dim-2, dim/2 );
+ }
+ } else {
+ if ( dim == 3 ) { // 3x3 arrow pattern
+ bLeft.setPoints( 4, 0,0, 0,2, 1,1, 1,1 );
+ bTop .setPoints( 2, 1,0, 1,0 );
+ bBot .setPoints( 2, 1,2, 2,1 );
+ } else { // 2x2 arrow pattern
+ bLeft.setPoints( 2, 0,0, 0,1 );
+ bTop .setPoints( 2, 1,0, 1,0 );
+ bBot .setPoints( 2, 1,1, 1,1 );
+ }
+ }
+
+ if ( pe == PE_ArrowUp || pe == PE_ArrowLeft ) {
+ matrix.translate( rect.x(), rect.y() );
+ if ( vertical ) {
+ matrix.translate( 0, rect.height() - 1 );
+ matrix.rotate( -90 );
+ } else {
+ matrix.translate( rect.width() - 1, rect.height() - 1 );
+ matrix.rotate( 180 );
+ }
+ if ( flags & Style_Down )
+ colspec = horizontal ? 0x2334 : 0x2343;
+ else
+ colspec = horizontal ? 0x1443 : 0x1434;
+ } else if ( pe == PE_ArrowDown || pe == PE_ArrowRight ) {
+ matrix.translate( rect.x(), rect.y() );
+ if ( vertical ) {
+ matrix.translate( rect.width()-1, 0 );
+ matrix.rotate( 90 );
+ }
+ if ( flags & Style_Down )
+ colspec = horizontal ? 0x2443 : 0x2434;
+ else
+ colspec = horizontal ? 0x1334 : 0x1343;
+ }
+
+ TQColor *cols[5];
+ if ( flags & Style_Enabled ) {
+ cols[0] = 0;
+ cols[1] = (TQColor *)&cg.button();
+ cols[2] = (TQColor *)&cg.mid();
+ cols[3] = (TQColor *)&cg.light();
+ cols[4] = (TQColor *)&cg.dark();
+ } else {
+ cols[0] = 0;
+ cols[1] = (TQColor *)&cg.button();
+ cols[2] = (TQColor *)&cg.button();
+ cols[3] = (TQColor *)&cg.button();
+ cols[4] = (TQColor *)&cg.button();
+ }
+
+#define CMID *cols[ (colspec>>12) & 0xf ]
+#define CLEFT *cols[ (colspec>>8) & 0xf ]
+#define CTOP *cols[ (colspec>>4) & 0xf ]
+#define CBOT *cols[ colspec & 0xf ]
+
+ TQPen savePen = p->pen(); // save current pen
+ TQBrush saveBrush = p->brush(); // save current brush
+ TQWMatrix wxm = p->tqworldMatrix();
+ TQPen pen( Qt::NoPen );
+ TQBrush brush = cg.brush( flags & Style_Enabled ? TQColorGroup::Button :
+ TQColorGroup::Mid );
+
+ p->setPen( pen );
+ p->setBrush( brush );
+ p->setWorldMatrix( matrix, TRUE ); // set transformation matrix
+ p->drawPolygon( bFill ); // fill arrow
+ p->setBrush( Qt::NoBrush ); // don't fill
+
+ p->setPen( CLEFT );
+ p->drawLineSegments( bLeft );
+ p->setPen( CBOT );
+ p->drawLineSegments( bBot );
+ p->setPen( CTOP );
+ p->drawLineSegments( bTop );
+
+ p->setWorldMatrix( wxm );
+ p->setBrush( saveBrush ); // restore brush
+ p->setPen( savePen ); // restore pen
+
+#undef CMID
+#undef CLEFT
+#undef CTOP
+#undef CBOT
+
+ }
+ break;
+ default:
+ TQMotifStyle::tqdrawPrimitive( pe, p, r, cg, flags, opt );
+ }
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/styles/tqcdestyle.h b/tqtinterface/qt4/src/styles/tqcdestyle.h
new file mode 100644
index 0000000..e248082
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqcdestyle.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Definition of the CDE-like style class
+**
+** Created : 990513
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+
+#ifndef TQCDESTYLE_H
+#define TQCDESTYLE_H
+
+#ifndef TQT_H
+#include "tqmotifstyle.h"
+#endif // TQT_H
+
+#if !defined(TQT_NO_STYLE_CDE) || defined(TQT_PLUGIN)
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_STYLE_CDE
+#else
+#define TQ_EXPORT_STYLE_CDE TQ_EXPORT
+#endif
+
+class TQ_EXPORT_STYLE_CDE TQCDEStyle : public TQMotifStyle
+{
+ TQ_OBJECT
+public:
+
+ TQCDEStyle( bool useHighlightCols = FALSE );
+ virtual ~TQCDEStyle();
+
+ int tqpixelMetric( PixelMetric metric, const TQWidget *widget = 0 ) const;
+
+ void tqdrawControl( ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+};
+
+#endif // TQT_NO_STYLE_CDE
+
+#endif // TQCDESTYLE_H
diff --git a/tqtinterface/qt4/src/styles/tqcommonstyle.cpp b/tqtinterface/qt4/src/styles/tqcommonstyle.cpp
new file mode 100644
index 0000000..c69fea7
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqcommonstyle.cpp
@@ -0,0 +1,2726 @@
+/****************************************************************************
+**
+** Implementation of the TQCommonStyle class
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcommonstyle.h"
+
+#ifndef TQT_NO_STYLE
+
+#include "tqmenubar.h"
+#include "tqapplication.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqpixmap.h"
+#include "tqpushbutton.h"
+#include "tqtabbar.h"
+#include "tqscrollbar.h"
+#include "tqtoolbutton.h"
+#include "tqtoolbar.h"
+#include "tqdockarea.h"
+#include "tqheader.h"
+#include "tqspinbox.h"
+#include "tqrangecontrol.h"
+#include "tqgroupbox.h"
+#include "tqslider.h"
+#include "tqlistview.h"
+#include "tqcheckbox.h"
+#include "tqradiobutton.h"
+#include "tqbitmap.h"
+#include "tqprogressbar.h"
+#include "private/tqdialogbuttons_p.h"
+#include <limits.h>
+#include <tqpixmap.h>
+#include "../widgets/tqtitlebar_p.h"
+#include <tqtoolbox.h>
+
+/*!
+ \class TQCommonStyle tqcommonstyle.h
+ \brief The TQCommonStyle class encapsulates the common Look and Feel of a GUI.
+
+ \ingroup appearance
+
+ This abstract class implements some of the widget's look and feel
+ that is common to all GUI styles provided and shipped as part of
+ TQt.
+
+ All the functions are documented in \l TQStyle.
+*/
+
+/*!
+ \enum TQt::ArrowType
+
+ \value UpArrow
+ \value DownArrow
+ \value LeftArrow
+ \value RightArrow
+
+*/
+
+// the active painter, if any... this is used as an optimzation to
+// avoid creating a painter if we have an active one (since
+// TQStyle::tqitemRect() needs a painter to operate correctly
+static TQPainter *activePainter = 0;
+
+/*!
+ Constructs a TQCommonStyle.
+*/
+TQCommonStyle::TQCommonStyle() : TQStyle()
+{
+ activePainter = 0;
+}
+
+/*! \reimp */
+TQCommonStyle::~TQCommonStyle()
+{
+ activePainter = 0;
+}
+
+
+static const char * const check_list_controller_xpm[] = {
+"16 16 4 1",
+" c None",
+". c #000000000000",
+"X c #FFFFFFFF0000",
+"o c #C71BC30BC71B",
+" ",
+" ",
+" .......... ",
+" .XXXXXXXX. ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" .XXXXXXXX.oo ",
+" ..........oo ",
+" oooooooooo ",
+" oooooooooo ",
+" ",
+" "};
+
+/*! \reimp */
+void TQCommonStyle::tqdrawPrimitive( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ activePainter = p;
+
+ switch (pe) {
+#ifndef TQT_NO_LISTVIEW
+ case TQStyle::PE_CheckListController: {
+ p->drawPixmap(r, TQPixmap((const char **)check_list_controller_xpm));
+ break; }
+ case TQStyle::PE_CheckListExclusiveIndicator: {
+ TQCheckListItem *item = opt.checkListItem();
+ TQListView *lv = item->listView();
+ if(!item)
+ return;
+ int x = r.x(), y = r.y();
+#define TQCOORDARRLEN(x) sizeof(x)/(sizeof(TQCOORD)*2)
+ static const TQCOORD pts1[] = { // dark lines
+ 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 };
+ static const TQCOORD pts2[] = { // black lines
+ 2,8, 1,7, 1,4, 2,3, 2,2, 3,2, 4,1, 7,1, 8,2, 9,2 };
+ static const TQCOORD pts3[] = { // background lines
+ 2,9, 3,9, 4,10, 7,10, 8,9, 9,9, 9,8, 10,7, 10,4, 9,3 };
+ static const TQCOORD pts4[] = { // white lines
+ 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7,
+ 11,4, 10,3, 10,2 };
+ // static const TQCOORD pts5[] = { // inner fill
+ // 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 };
+ //TQPointArray a;
+ // p->eraseRect( x, y, w, h );
+
+ if ( flags & Style_Enabled )
+ p->setPen( cg.text() );
+ else
+ p->setPen( TQPen( lv->tqpalette().color( TQPalette::Disabled, TQColorGroup::Text ) ) );
+ TQPointArray a( TQCOORDARRLEN(pts1), pts1 );
+ a.translate( x, y );
+ //p->setPen( cg.dark() );
+ p->drawPolyline( a );
+ a.setPoints( TQCOORDARRLEN(pts2), pts2 );
+ a.translate( x, y );
+ p->drawPolyline( a );
+ a.setPoints( TQCOORDARRLEN(pts3), pts3 );
+ a.translate( x, y );
+ // p->setPen( black );
+ p->drawPolyline( a );
+ a.setPoints( TQCOORDARRLEN(pts4), pts4 );
+ a.translate( x, y );
+ // p->setPen( blue );
+ p->drawPolyline( a );
+ // a.setPoints( TQCOORDARRLEN(pts5), pts5 );
+ // a.translate( x, y );
+ // TQColor fillColor = isDown() ? g.background() : g.base();
+ // p->setPen( fillColor );
+ // p->setBrush( fillColor );
+ // p->drawPolygon( a );
+ if ( flags & Style_On ) {
+ p->setPen( TQt::NoPen );
+ p->setBrush( cg.text() );
+ p->drawRect( x+5, y+4, 2, 4 );
+ p->drawRect( x+4, y+5, 4, 2 );
+ }
+ break; }
+ case TQStyle::PE_CheckListIndicator: {
+ TQCheckListItem *item = opt.checkListItem();
+ TQListView *lv = item->listView();
+ if(!item)
+ return;
+ int x = r.x(), y = r.y(), w = r.width(), h = r.width(), marg = lv->itemMargin();
+
+ if ( flags & Style_Enabled )
+ p->setPen( TQPen( cg.text(), 2 ) );
+ else
+ p->setPen( TQPen( lv->tqpalette().color( TQPalette::Disabled, TQColorGroup::Text ),
+ 2 ) );
+ bool parentControl = FALSE;
+ if ( item->tqparent() && item->tqparent()->rtti() == 1 &&
+ ((TQCheckListItem*) item->tqparent())->type() == TQCheckListItem::Controller )
+ parentControl = TRUE;
+ if ( flags & Style_Selected && !lv->rootIsDecorated() && !parentControl ) {
+ p->fillRect( 0, 0, x + marg + w + 4, item->height(),
+ cg.brush( TQColorGroup::Highlight ) );
+ if ( item->isEnabled() )
+ p->setPen( TQPen( cg.highlightedText(), 2 ) );
+ }
+
+ if ( flags & Style_NoChange )
+ p->setBrush( cg.brush( TQColorGroup::Button ) );
+ p->drawRect( x+marg, y+2, w-4, h-4 );
+ /////////////////////
+ x++;
+ y++;
+ if ( ( flags & Style_On) || ( flags & Style_NoChange ) ) {
+ TQPointArray a( 7*2 );
+ int i, xx = x+1+marg, yy=y+5;
+ for ( i=0; i<3; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy++;
+ }
+ yy -= 2;
+ for ( i=3; i<7; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy--;
+ }
+ p->drawLineSegments( a );
+ }
+ break; }
+#endif
+ case TQStyle::PE_HeaderArrow:
+ p->save();
+ if ( flags & Style_Down ) {
+ TQPointArray pa( 3 );
+ p->setPen( cg.light() );
+ p->drawLine( r.x() + r.width(), r.y(), r.x() + r.width() / 2, r.height() );
+ p->setPen( cg.dark() );
+ pa.setPoint( 0, r.x() + r.width() / 2, r.height() );
+ pa.setPoint( 1, r.x(), r.y() );
+ pa.setPoint( 2, r.x() + r.width(), r.y() );
+ p->drawPolyline( pa );
+ } else {
+ TQPointArray pa( 3 );
+ p->setPen( cg.light() );
+ pa.setPoint( 0, r.x(), r.height() );
+ pa.setPoint( 1, r.x() + r.width(), r.height() );
+ pa.setPoint( 2, r.x() + r.width() / 2, r.y() );
+ p->drawPolyline( pa );
+ p->setPen( cg.dark() );
+ p->drawLine( r.x(), r.height(), r.x() + r.width() / 2, r.y() );
+ }
+ p->restore();
+ break;
+
+ case TQStyle::PE_StatusBarSection:
+ qDrawShadeRect( p, r, cg, TRUE, 1, 0, 0 );
+ break;
+
+ case TQStyle::PE_ButtonCommand:
+ case TQStyle::PE_ButtonBevel:
+ case TQStyle::PE_ButtonTool:
+ case TQStyle::PE_ButtonDropDown:
+ case TQStyle::PE_HeaderSection:
+ qDrawShadePanel(p, r, cg, flags & (Style_Sunken | Style_Down | Style_On) , 1,
+ &cg.brush(TQColorGroup::Button));
+ break;
+
+ case TQStyle::PE_Separator:
+ qDrawShadeLine( p, r.left(), r.top(), r.right(), r.bottom(), cg,
+ flags & Style_Sunken, 1, 0);
+ break;
+
+ case TQStyle::PE_FocusRect: {
+ const TQColor *bg = 0;
+
+ if (!opt.isDefault())
+ bg = &opt.color();
+
+ TQPen oldPen = p->pen();
+
+ if (bg) {
+ int h, s, v;
+ bg->hsv(&h, &s, &v);
+ if (v >= 128)
+ p->setPen(TQt::black);
+ else
+ p->setPen(TQt::white);
+ } else
+ p->setPen(cg.foreground());
+
+ if (flags & Style_FocusAtBorder)
+ p->drawRect(TQRect(r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2));
+ else
+ p->drawRect(r);
+
+ p->setPen(oldPen);
+ break; }
+
+ case TQStyle::PE_SpinWidgetPlus:
+ case TQStyle::PE_SpinWidgetMinus: {
+ p->save();
+ int fw = tqpixelMetric( PM_DefaultFrameWidth, 0 );
+ TQRect br;
+ br.setRect( r.x() + fw, r.y() + fw, r.width() - fw*2,
+ r.height() - fw*2 );
+
+ p->fillRect( br, cg.brush( TQColorGroup::Button ) );
+ p->setPen( cg.buttonText() );
+ p->setBrush( cg.buttonText() );
+
+ int length;
+ int x = r.x(), y = r.y(), w = r.width(), h = r.height();
+ if ( w <= 8 || h <= 6 )
+ length = TQMIN( w-2, h-2 );
+ else
+ length = TQMIN( 2*w / 3, 2*h / 3 );
+
+ if ( !(length & 1) )
+ length -=1;
+ int xmarg = ( w - length ) / 2;
+ int ymarg = ( h - length ) / 2;
+
+ p->drawLine( x + xmarg, ( y + h / 2 - 1 ),
+ x + xmarg + length - 1, ( y + h / 2 - 1 ) );
+ if ( pe == TQStyle::PE_SpinWidgetPlus )
+ p->drawLine( ( x+w / 2 ) - 1, y + ymarg,
+ ( x+w / 2 ) - 1, y + ymarg + length - 1 );
+ p->restore();
+ break; }
+
+ case TQStyle::PE_SpinWidgetUp:
+ case TQStyle::PE_SpinWidgetDown: {
+ int fw = tqpixelMetric( PM_DefaultFrameWidth, 0 );
+ TQRect br;
+ br.setRect( r.x() + fw, r.y() + fw, r.width() - fw*2,
+ r.height() - fw*2 );
+ p->fillRect( br, cg.brush( TQColorGroup::Button ) );
+ int x = r.x(), y = r.y(), w = r.width(), h = r.height();
+ int sw = w-4;
+ if ( sw < 3 )
+ break;
+ else if ( !(sw & 1) )
+ sw--;
+ sw -= ( sw / 7 ) * 2; // Empty border
+ int sh = sw/2 + 2; // Must have empty row at foot of arrow
+
+ int sx = x + w / 2 - sw / 2 - 1;
+ int sy = y + h / 2 - sh / 2 - 1;
+
+ TQPointArray a;
+ if ( pe == TQStyle::PE_SpinWidgetDown )
+ a.setPoints( 3, 0, 1, sw-1, 1, sh-2, sh-1 );
+ else
+ a.setPoints( 3, 0, sh-1, sw-1, sh-1, sh-2, 1 );
+ int bsx = 0;
+ int bsy = 0;
+ if ( flags & Style_Sunken ) {
+ bsx = tqpixelMetric(PM_ButtonShiftHorizontal);
+ bsy = tqpixelMetric(PM_ButtonShiftVertical);
+ }
+ p->save();
+ p->translate( sx + bsx, sy + bsy );
+ p->setPen( cg.buttonText() );
+ p->setBrush( cg.buttonText() );
+ p->drawPolygon( a );
+ p->restore();
+ break; }
+
+ case TQStyle::PE_Indicator: {
+ if (flags & Style_NoChange) {
+ p->setPen(cg.foreground());
+ p->fillRect(r, cg.brush(TQColorGroup::Button));
+ p->drawRect(r);
+ p->drawLine(r.topLeft(), r.bottomRight());
+ } else
+ qDrawShadePanel(p, r.x(), r.y(), r.width(), r.height(),
+ cg, flags & (Style_Sunken | Style_On), 1,
+ &cg.brush(TQColorGroup::Button));
+ break; }
+
+ case TQStyle::PE_IndicatorMask: {
+ p->fillRect(r, Qt::color1);
+ break; }
+
+ case TQStyle::PE_ExclusiveIndicator: {
+ TQRect ir = r;
+ p->setPen(cg.dark());
+ p->drawArc(r, 0, 5760);
+
+ if (flags & (Style_Sunken | Style_On)) {
+ ir.addCoords(2, 2, -2, -2);
+ p->setBrush(cg.foreground());
+ p->drawEllipse(ir);
+ }
+
+ break; }
+
+ case TQStyle::PE_ExclusiveIndicatorMask: {
+ p->setPen(Qt::color1);
+ p->setBrush(Qt::color1);
+ p->drawEllipse(r);
+ break; }
+
+ case TQStyle::PE_DockWindowHandle: {
+ bool highlight = flags & Style_On;
+
+ p->save();
+ p->translate( r.x(), r.y() );
+ if ( flags & Style_Horizontal ) {
+ int x = r.width() / 3;
+ if ( r.height() > 4 ) {
+ qDrawShadePanel( p, x, 2, 3, r.height() - 4,
+ cg, highlight, 1, 0 );
+ qDrawShadePanel( p, x+3, 2, 3, r.height() - 4,
+ cg, highlight, 1, 0 );
+ }
+ } else {
+ if ( r.width() > 4 ) {
+ int y = r.height() / 3;
+ qDrawShadePanel( p, 2, y, r.width() - 4, 3,
+ cg, highlight, 1, 0 );
+ qDrawShadePanel( p, 2, y+3, r.width() - 4, 3,
+ cg, highlight, 1, 0 );
+ }
+ }
+ p->restore();
+ break;
+ }
+
+ case TQStyle::PE_DockWindowSeparator: {
+ TQPoint p1, p2;
+ if ( flags & Style_Horizontal ) {
+ p1 = TQPoint( r.width()/2, 0 );
+ p2 = TQPoint( p1.x(), r.height() );
+ } else {
+ p1 = TQPoint( 0, r.height()/2 );
+ p2 = TQPoint( r.width(), p1.y() );
+ }
+ qDrawShadeLine( p, p1, p2, cg, 1, 1, 0 );
+ break; }
+
+ case TQStyle::PE_Panel:
+ case TQStyle::PE_PanelPopup: {
+ int lw = opt.isDefault() ? tqpixelMetric(PM_DefaultFrameWidth)
+ : opt.lineWidth();
+
+ qDrawShadePanel(p, r, cg, (flags & Style_Sunken), lw);
+ break; }
+
+ case TQStyle::PE_PanelDockWindow: {
+ int lw = opt.isDefault() ? tqpixelMetric(PM_DockWindowFrameWidth)
+ : opt.lineWidth();
+
+ qDrawShadePanel(p, r, cg, FALSE, lw);
+ break; }
+
+ case TQStyle::PE_PanelMenuBar: {
+ int lw = opt.isDefault() ? tqpixelMetric(PM_MenuBarFrameWidth)
+ : opt.lineWidth();
+
+ qDrawShadePanel(p, r, cg, FALSE, lw, &cg.brush(TQColorGroup::Button));
+ break; }
+
+ case TQStyle::PE_SizeGrip: {
+ p->save();
+
+ int x, y, w, h;
+ r.rect(&x, &y, &w, &h);
+
+ int sw = TQMIN( h,w );
+ if ( h > w )
+ p->translate( 0, h - w );
+ else
+ p->translate( w - h, 0 );
+
+ int sx = x;
+ int sy = y;
+ int s = sw / 3;
+
+ if ( TQApplication::reverseLayout() ) {
+ sx = x + sw;
+ for ( int i = 0; i < 4; ++i ) {
+ p->setPen( TQPen( cg.light(), 1 ) );
+ p->drawLine( x, sy - 1 , sx + 1, sw );
+ p->setPen( TQPen( cg.dark(), 1 ) );
+ p->drawLine( x, sy, sx, sw );
+ p->setPen( TQPen( cg.dark(), 1 ) );
+ p->drawLine( x, sy + 1, sx - 1, sw );
+ sx -= s;
+ sy += s;
+ }
+ } else {
+ for ( int i = 0; i < 4; ++i ) {
+ p->setPen( TQPen( cg.light(), 1 ) );
+ p->drawLine( sx-1, sw, sw, sy-1 );
+ p->setPen( TQPen( cg.dark(), 1 ) );
+ p->drawLine( sx, sw, sw, sy );
+ p->setPen( TQPen( cg.dark(), 1 ) );
+ p->drawLine( sx+1, sw, sw, sy+1 );
+ sx += s;
+ sy += s;
+ }
+ }
+
+ p->restore();
+ break; }
+
+ case TQStyle::PE_CheckMark: {
+ const int markW = r.width() > 7 ? 7 : r.width();
+ const int markH = markW;
+ int posX = r.x() + ( r.width() - markW )/2 + 1;
+ int posY = r.y() + ( r.height() - markH )/2;
+
+ // Could do with some optimizing/caching...
+ TQPointArray a( markH*2 );
+ int i, xx, yy;
+ xx = posX;
+ yy = 3 + posY;
+ for ( i=0; i<markW/2; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy++;
+ }
+ yy -= 2;
+ for ( ; i<markH; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy--;
+ }
+ if ( !(flags & Style_Enabled) && !(flags & Style_On)) {
+ int pnt;
+ p->setPen( cg.highlightedText() );
+ TQPoint offset(1,1);
+ for ( pnt = 0; pnt < (int)a.size(); pnt++ )
+ a[pnt] += offset;
+ p->drawLineSegments( a );
+ for ( pnt = 0; pnt < (int)a.size(); pnt++ )
+ a[pnt] -= offset;
+ }
+ p->setPen( cg.text() );
+ p->drawLineSegments( a );
+ break; }
+
+ case TQStyle::PE_PanelGroupBox: //We really do not need TQStyle::PE_GroupBoxFrame anymore, nasty holdover ###
+ tqdrawPrimitive( TQStyle::PE_GroupBoxFrame, p, r, cg, flags, opt );
+ break;
+ case TQStyle::PE_GroupBoxFrame: {
+#ifndef TQT_NO_FRAME
+ if ( opt.isDefault() )
+ break;
+ int lwidth = opt.lineWidth(), mlwidth = opt.midLineWidth();
+ if ( flags & (Style_Sunken|Style_Raised))
+ qDrawShadeRect( p, r.x(), r.y(), r.width(), r.height(), cg, flags & Style_Sunken, lwidth, mlwidth );
+ else
+ qDrawPlainRect( p, r.x(), r.y(), r.width(), r.height(), cg.foreground(), lwidth );
+#endif
+ break; }
+
+ case TQStyle::PE_ProgressBarChunk:
+ p->fillRect( r.x(), r.y() + 3, r.width() -2, r.height() - 6,
+ cg.brush(TQColorGroup::Highlight));
+ break;
+
+ case TQStyle::PE_PanelLineEdit:
+ case TQStyle::PE_PanelTabWidget:
+ case TQStyle::PE_WindowFrame:
+ tqdrawPrimitive( TQStyle::PE_Panel, p, r, cg, flags, opt );
+ break;
+
+ case TQStyle::PE_RubberBand:
+ tqdrawPrimitive(TQStyle::PE_FocusRect, p, r, cg, flags, opt);
+ break;
+ default:
+ break;
+ }
+
+ activePainter = 0;
+}
+
+/*! \reimp */
+void TQCommonStyle::tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+#if defined(TQT_CHECK_STATE)
+ if (! widget) {
+ qWarning("TQCommonStyle::tqdrawControl: widget parameter cannot be zero!");
+ return;
+ }
+#endif
+
+ activePainter = p;
+
+ switch (element) {
+ case CE_MenuBarEmptyArea: {
+ TQRegion reg;
+ if(p->hasClipping()) //ick
+ reg = p->clipRegion();
+ else
+ reg = r;
+ ((TQWidget *)widget)->erase( reg );
+ break; }
+ case CE_PushButton:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *button = (const TQPushButton *) widget;
+ TQRect br = r;
+ int dbi = tqpixelMetric(PM_ButtonDefaultIndicator, widget);
+
+ if (button->isDefault() || button->autoDefault()) {
+ if ( button->isDefault())
+ tqdrawPrimitive(TQStyle::PE_ButtonDefault, p, br, cg, flags);
+
+ br.setCoords(br.left() + dbi,
+ br.top() + dbi,
+ br.right() - dbi,
+ br.bottom() - dbi);
+ }
+
+ p->save();
+ p->setBrushOrigin( -widget->backgroundOffset().x(),
+ -widget->backgroundOffset().y() );
+ tqdrawPrimitive(TQStyle::PE_ButtonCommand, p, br, cg, flags);
+ p->restore();
+#endif
+ break;
+ }
+
+ case CE_PushButtonLabel:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *button = (const TQPushButton *) widget;
+ TQRect ir = r;
+
+ if (button->isDown() || button->isOn()) {
+ flags |= Style_Sunken;
+ ir.moveBy(tqpixelMetric(PM_ButtonShiftHorizontal, widget),
+ tqpixelMetric(PM_ButtonShiftVertical, widget));
+ }
+
+ if (button->isMenuButton()) {
+ int mbi = tqpixelMetric(PM_MenuButtonIndicator, widget);
+ TQRect ar(ir.right() - mbi, ir.y() + 2, mbi - 4, ir.height() - 4);
+ tqdrawPrimitive(TQStyle::PE_ArrowDown, p, ar, cg, flags, opt);
+ ir.setWidth(ir.width() - mbi);
+ }
+
+ int tf=TQt::AlignVCenter | TQt::ShowPrefix;
+ if (!tqstyleHint(SH_UnderlineAccelerator, widget, TQStyleOption::Default, 0))
+ tf |= TQt::NoAccel;
+
+#ifndef TQT_NO_ICONSET
+ if ( button->iconSet() && ! button->iconSet()->isNull() ) {
+ TQIconSet::Mode mode =
+ button->isEnabled() ? TQIconSet::Normal : TQIconSet::Disabled;
+ if ( mode == TQIconSet::Normal && button->hasFocus() )
+ mode = TQIconSet::Active;
+
+ TQIconSet::State state = TQIconSet::Off;
+ if ( button->isToggleButton() && button->isOn() )
+ state = TQIconSet::On;
+
+ TQPixmap pixmap = button->iconSet()->pixmap( TQIconSet::Small, mode, state );
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+
+ //Center the icon if there is neither text nor pixmap
+ if ( button->text().isEmpty() && !button->pixmap() )
+ p->drawPixmap( ir.x() + ir.width() / 2 - pixw / 2, ir.y() + ir.height() / 2 - pixh / 2, pixmap );
+ else
+ p->drawPixmap( ir.x() + 2, ir.y() + ir.height() / 2 - pixh / 2, pixmap );
+
+ ir.moveBy(pixw + 4, 0);
+ ir.setWidth(ir.width() - (pixw + 4));
+ // left-align text if there is
+ if (!button->text().isEmpty())
+ tf |= TQt::AlignLeft;
+ else if (button->pixmap())
+ tf |= TQt::AlignHCenter;
+ } else
+#endif //TQT_NO_ICONSET
+ tf |= TQt::AlignHCenter;
+ drawItem(p, ir, tf, cg,
+ flags & Style_Enabled, button->pixmap(), button->text(),
+ button->text().length(), TQT_TQCOLOR_CONST(&(cg.buttonText())) );
+
+ if (flags & Style_HasFocus)
+ tqdrawPrimitive(TQStyle::PE_FocusRect, p, subRect(SR_PushButtonFocusRect, widget),
+ cg, flags);
+#endif
+ break;
+ }
+
+ case CE_CheckBox:
+ tqdrawPrimitive(TQStyle::PE_Indicator, p, r, cg, flags, opt);
+ break;
+
+ case CE_CheckBoxLabel:
+ {
+#ifndef TQT_NO_CHECKBOX
+ const TQCheckBox *checkbox = (const TQCheckBox *) widget;
+
+ int tqalignment = TQApplication::reverseLayout() ? TQt::AlignRight : TQt::AlignLeft;
+ if (!tqstyleHint(SH_UnderlineAccelerator, widget, TQStyleOption::Default, 0))
+ tqalignment |= TQt::NoAccel;
+
+ drawItem(p, r, tqalignment | TQt::AlignVCenter | TQt::ShowPrefix, cg,
+ flags & Style_Enabled, checkbox->pixmap(), checkbox->text());
+
+ if (flags & Style_HasFocus) {
+ TQRect fr = tqvisualRect(subRect(SR_CheckBoxFocusRect, widget), widget);
+ tqdrawPrimitive(TQStyle::PE_FocusRect, p, fr, cg, flags);
+ }
+#endif
+ break;
+ }
+
+ case CE_RadioButton:
+ tqdrawPrimitive(TQStyle::PE_ExclusiveIndicator, p, r, cg, flags, opt);
+ break;
+
+ case CE_RadioButtonLabel:
+ {
+#ifndef TQT_NO_RADIOBUTTON
+ const TQRadioButton *radiobutton = (const TQRadioButton *) widget;
+
+ int tqalignment = TQApplication::reverseLayout() ? TQt::AlignRight : TQt::AlignLeft;
+ if (!tqstyleHint(SH_UnderlineAccelerator, widget, TQStyleOption::Default, 0))
+ tqalignment |= TQt::NoAccel;
+ drawItem(p, r, tqalignment | TQt::AlignVCenter | TQt::ShowPrefix, cg,
+ flags & Style_Enabled, radiobutton->pixmap(), radiobutton->text());
+
+ if (flags & Style_HasFocus) {
+ TQRect fr = tqvisualRect(subRect(SR_RadioButtonFocusRect, widget), widget);
+ tqdrawPrimitive(TQStyle::PE_FocusRect, p, fr, cg, flags);
+ }
+#endif
+ break;
+ }
+
+#ifndef TQT_NO_TABBAR
+ case CE_TabBarTab:
+ {
+ const TQTabBar * tb = (const TQTabBar *) widget;
+
+ if ( tb->tqshape() == TQTabBar::TriangularAbove ||
+ tb->tqshape() == TQTabBar::TriangularBelow ) {
+ // triangular, above or below
+ int y;
+ int x;
+ TQPointArray a( 10 );
+ a.setPoint( 0, 0, -1 );
+ a.setPoint( 1, 0, 0 );
+ y = r.height()-2;
+ x = y/3;
+ a.setPoint( 2, x++, y-1 );
+ a.setPoint( 3, x++, y );
+ a.setPoint( 3, x++, y++ );
+ a.setPoint( 4, x, y );
+
+ int i;
+ int right = r.width() - 1;
+ for ( i = 0; i < 5; i++ )
+ a.setPoint( 9-i, right - a.point( i ).x(), a.point( i ).y() );
+
+ if ( tb->tqshape() == TQTabBar::TriangularAbove )
+ for ( i = 0; i < 10; i++ )
+ a.setPoint( i, a.point(i).x(),
+ r.height() - 1 - a.point( i ).y() );
+
+ a.translate( r.left(), r.top() );
+
+ if ( flags & Style_Selected )
+ p->setBrush( cg.base() );
+ else
+ p->setBrush( cg.background() );
+ p->setPen( cg.foreground() );
+ p->drawPolygon( a );
+ p->setBrush( TQt::NoBrush );
+ }
+ break;
+ }
+
+ case CE_TabBarLabel:
+ {
+ if ( opt.isDefault() )
+ break;
+
+ const TQTabBar * tb = (const TQTabBar *) widget;
+ TQTab * t = opt.tab();
+
+ TQRect tr = r;
+ if ( t->identifier() == tb->currentTab() )
+ tr.setBottom( tr.bottom() -
+ tqpixelMetric( TQStyle::PM_DefaultFrameWidth, tb ) );
+
+ int tqalignment = TQt::AlignCenter | TQt::ShowPrefix;
+ if (!tqstyleHint(SH_UnderlineAccelerator, widget, TQStyleOption::Default, 0))
+ tqalignment |= TQt::NoAccel;
+ drawItem( p, tr, tqalignment, cg,
+ flags & Style_Enabled, 0, t->text() );
+
+ if ( (flags & Style_HasFocus) && !t->text().isEmpty() )
+ tqdrawPrimitive( TQStyle::PE_FocusRect, p, r, cg );
+ break;
+ }
+#endif // TQT_NO_TABBAR
+#ifndef TQT_NO_TOOLBOX
+ case CE_ToolBoxTab:
+ {
+ int d = 20 + r.height() - 3;
+ TQPointArray a( 7 );
+ a.setPoint( 0, -1, r.height() + 1 );
+ a.setPoint( 1, -1, 1 );
+ a.setPoint( 2, r.width() - d, 1 );
+ a.setPoint( 3, r.width() - 20, r.height() - 2 );
+ a.setPoint( 4, r.width() - 1, r.height() - 2 );
+ a.setPoint( 5, r.width() - 1, r.height() + 1 );
+ a.setPoint( 6, -1, r.height() + 1 );
+
+ const TQToolBox *tb = (const TQToolBox*)widget;
+
+ if ( flags & Style_Selected && tb->currentItem() )
+ p->setBrush( tb->currentItem()->paletteBackgroundColor() );
+ else
+ p->setBrush( cg.brush(TQColorGroup::Background) );
+
+ p->setPen( cg.mid().dark( 150 ) );
+ p->drawPolygon( a );
+ p->setPen( cg.light() );
+ p->drawLine( 0, 2, r.width() - d, 2 );
+ p->drawLine( r.width() - d - 1, 2, r.width() - 21, r.height() - 1 );
+ p->drawLine( r.width() - 20, r.height() - 1, r.width(), r.height() - 1 );
+ p->setBrush( TQt::NoBrush );
+ break;
+ }
+#endif // TQT_NO_TOOLBOX
+ case CE_ProgressBarGroove:
+ qDrawShadePanel(p, r, cg, TRUE, 1, &cg.brush(TQColorGroup::Background));
+ break;
+
+#ifndef TQT_NO_PROGRESSBAR
+ case CE_ProgressBarContents:
+ {
+ const TQProgressBar *progressbar = (const TQProgressBar *) widget;
+ // Correct the highlight color if same as background,
+ // or else we cannot see the progress...
+ TQColorGroup cgh = cg;
+ if ( cgh.highlight() == cgh.background() )
+ cgh.setColor( TQColorGroup::Highlight, progressbar->tqpalette().active().highlight() );
+ bool reverse = TQApplication::reverseLayout();
+ int fw = 2;
+ int w = r.width() - 2*fw;
+ if ( !progressbar->totalSteps() ) {
+ // draw busy indicator
+ int x = progressbar->progress() % (w * 2);
+ if (x > w)
+ x = 2 * w - x;
+ x = reverse ? r.right() - x : x + r.x();
+ p->setPen( TQPen(cgh.highlight(), 4) );
+ p->drawLine(x, r.y() + 1, x, r.height() - fw);
+ } else {
+ const int unit_width = tqpixelMetric(PM_ProgressBarChunkWidth, widget);
+ int u;
+ if ( unit_width > 1 )
+ u = (r.width()+unit_width/3) / unit_width;
+ else
+ u = w / unit_width;
+ int p_v = progressbar->progress();
+ int t_s = progressbar->totalSteps() ? progressbar->totalSteps() : 1;
+
+ if ( u > 0 && p_v >= INT_MAX / u && t_s >= u ) {
+ // scale down to something usable.
+ p_v /= u;
+ t_s /= u;
+ }
+
+ // nu < tnu, if last chunk is only a partial chunk
+ int tnu, nu;
+ tnu = nu = p_v * u / t_s;
+
+ if (nu * unit_width > w)
+ nu--;
+
+ // Draw nu units out of a possible u of unit_width
+ // width, each a rectangle bordered by background
+ // color, all in a sunken panel with a percentage text
+ // display at the end.
+ int x = 0;
+ int x0 = reverse ? r.right() - ((unit_width > 1) ?
+ unit_width : fw) : r.x() + fw;
+ for (int i=0; i<nu; i++) {
+ tqdrawPrimitive( TQStyle::PE_ProgressBarChunk, p,
+ TQRect( x0+x, r.y(), unit_width, r.height() ),
+ cgh, Style_Default, opt );
+ x += reverse ? -unit_width: unit_width;
+ }
+
+ // Draw the last partial chunk to fill up the
+ // progressbar entirely
+ if (nu < tnu) {
+ int pixels_left = w - (nu*unit_width);
+ int offset = reverse ? x0+x+unit_width-pixels_left : x0+x;
+ tqdrawPrimitive( TQStyle::PE_ProgressBarChunk, p,
+ TQRect( offset, r.y(), pixels_left,
+ r.height() ), cgh, Style_Default,
+ opt );
+ }
+ }
+ }
+ break;
+
+ case CE_ProgressBarLabel:
+ {
+ const TQProgressBar *progressbar = (const TQProgressBar *) widget;
+ TQColor penColor = cg.highlightedText();
+ TQColor *pcolor = 0;
+ if ( progressbar->centerIndicator() && !progressbar->indicatorFollowsStyle() &&
+ progressbar->progress()*2 >= progressbar->totalSteps() )
+ pcolor = &penColor;
+ drawItem(p, r, TQt::AlignCenter | TQt::SingleLine, cg, flags & Style_Enabled, 0,
+ progressbar->progressString(), -1, pcolor );
+ }
+ break;
+#endif // TQT_NO_PROGRESSBAR
+
+ case CE_MenuBarItem:
+ {
+#ifndef TQT_NO_MENUDATA
+ if (opt.isDefault())
+ break;
+
+ TQMenuItem *mi = opt.menuItem();
+ int tqalignment = TQt::AlignCenter|TQt::ShowPrefix|TQt::DontClip|TQt::SingleLine;
+ if (!tqstyleHint(SH_UnderlineAccelerator, widget, TQStyleOption::Default, 0))
+ tqalignment |= TQt::NoAccel;
+ drawItem( p, r, tqalignment, cg,
+ flags & Style_Enabled, mi->pixmap(), mi->text(), -1,
+ TQT_TQCOLOR_CONST(&cg.buttonText()) );
+#endif
+ break;
+ }
+
+#ifndef TQT_NO_TOOLBUTTON
+ case CE_ToolButtonLabel:
+ {
+ const TQToolButton *toolbutton = (const TQToolButton *) widget;
+ TQRect rect = r;
+ TQt::ArrowType arrowType = opt.isDefault()
+ ? TQt::DownArrow : opt.arrowType();
+
+ int shiftX = 0;
+ int shiftY = 0;
+ if (flags & (Style_Down | Style_On)) {
+ shiftX = tqpixelMetric(PM_ButtonShiftHorizontal, widget);
+ shiftY = tqpixelMetric(PM_ButtonShiftVertical, widget);
+ }
+
+ if (!opt.isDefault()) {
+ PrimitiveElement pe;
+ switch (arrowType) {
+ case TQt::LeftArrow: pe = TQStyle::PE_ArrowLeft; break;
+ case TQt::RightArrow: pe = TQStyle::PE_ArrowRight; break;
+ case TQt::UpArrow: pe = TQStyle::PE_ArrowUp; break;
+ default:
+ case TQt::DownArrow: pe = TQStyle::PE_ArrowDown; break;
+ }
+
+ rect.moveBy(shiftX, shiftY);
+ tqdrawPrimitive(pe, p, rect, cg, flags, opt);
+ } else {
+ TQColor btext = toolbutton->paletteForegroundColor();
+
+ if (toolbutton->iconSet().isNull() &&
+ ! toolbutton->text().isNull() &&
+ ! toolbutton->usesTextLabel()) {
+ int tqalignment = TQt::AlignCenter | TQt::ShowPrefix;
+ if (!tqstyleHint(SH_UnderlineAccelerator, widget, TQStyleOption::Default, 0))
+ tqalignment |= TQt::NoAccel;
+
+ rect.moveBy(shiftX, shiftY);
+ drawItem(p, rect, tqalignment, cg,
+ flags & Style_Enabled, 0, toolbutton->text(),
+ toolbutton->text().length(), &btext);
+ } else {
+ TQPixmap pm;
+ TQIconSet::Size size =
+ toolbutton->usesBigPixmap() ? TQIconSet::Large : TQIconSet::Small;
+ TQIconSet::State state =
+ toolbutton->isOn() ? TQIconSet::On : TQIconSet::Off;
+ TQIconSet::Mode mode;
+ if (! toolbutton->isEnabled())
+ mode = TQIconSet::Disabled;
+ else if ((flags & (Style_Down | Style_On)) ||
+ ((flags & Style_Raised) && (flags & Style_AutoRaise)))
+ mode = TQIconSet::Active;
+ else
+ mode = TQIconSet::Normal;
+ pm = toolbutton->iconSet().pixmap( size, mode, state );
+
+ if ( toolbutton->usesTextLabel() ) {
+ p->setFont( toolbutton->font() );
+ TQRect pr = rect, tr = rect;
+ int tqalignment = TQt::ShowPrefix;
+ if (!tqstyleHint(SH_UnderlineAccelerator, widget, TQStyleOption::Default, 0))
+ tqalignment |= TQt::NoAccel;
+
+ if ( toolbutton->textPosition() == TQToolButton::Under ) {
+ int fh = p->fontMetrics().height();
+ pr.addCoords( 0, 1, 0, -fh-3 );
+ tr.addCoords( 0, pr.bottom(), 0, -3 );
+ pr.moveBy(shiftX, shiftY);
+ drawItem( p, pr, TQt::AlignCenter, cg, TRUE, &pm, TQString::null );
+ tqalignment |= TQt::AlignCenter;
+ } else {
+ pr.setWidth( pm.width() + 8 );
+ tr.addCoords( pr.right(), 0, 0, 0 );
+ pr.moveBy(shiftX, shiftY);
+
+ drawItem( p, pr, TQt::AlignCenter, cg, TRUE, &pm, TQString::null );
+ tqalignment |= TQt::AlignLeft | TQt::AlignVCenter;
+ }
+
+ tr.moveBy(shiftX, shiftY);
+ drawItem( p, tr, tqalignment, cg,
+ flags & Style_Enabled, 0, toolbutton->textLabel(),
+ toolbutton->textLabel().length(), &btext);
+ } else {
+ rect.moveBy(shiftX, shiftY);
+ drawItem( p, rect, TQt::AlignCenter, cg, TRUE, &pm, TQString::null );
+ }
+ }
+ }
+
+ break;
+ }
+#endif // TQT_NO_TOOLBUTTON
+#ifndef TQT_NO_HEADER
+ case CE_HeaderLabel:
+ {
+ TQRect rect = r;
+ const TQHeader* header = (const TQHeader *) widget;
+ int section = opt.headerSection();
+
+ TQIconSet* icon = header->iconSet( section );
+ if ( icon ) {
+ TQPixmap pixmap = icon->pixmap( TQIconSet::Small,
+ flags & Style_Enabled ?
+ TQIconSet::Normal : TQIconSet::Disabled );
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ // "pixh - 1" because of tricky integer division
+
+ TQRect pixRect = rect;
+ pixRect.setY( rect.center().y() - (pixh - 1) / 2 );
+ drawItem ( p, pixRect, TQt::AlignVCenter, cg, flags & Style_Enabled,
+ &pixmap, TQString::null );
+ if (TQApplication::reverseLayout())
+ rect.setRight(rect.right() - pixw - 2);
+ else
+ rect.setLeft(rect.left() + pixw + 2);
+ }
+
+ if (rect.isValid())
+ drawItem ( p, rect, TQt::AlignVCenter, cg, flags & Style_Enabled,
+ 0, header->label( section ), -1, TQT_TQCOLOR_CONST(&(cg.buttonText())) );
+ }
+#endif // TQT_NO_HEADER
+ default:
+ break;
+ }
+
+ activePainter = 0;
+}
+
+/*! \reimp */
+void TQCommonStyle::tqdrawControlMask( TQ_ControlElement control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQStyleOption& opt ) const
+{
+ TQ_UNUSED(widget);
+
+ activePainter = p;
+
+ TQColorGroup cg(Qt::color1,Qt::color1,Qt::color1,Qt::color1,Qt::color1,Qt::color1,Qt::color1,Qt::color1,Qt::color0);
+
+ switch (control) {
+ case CE_PushButton:
+ tqdrawPrimitive(TQStyle::PE_ButtonCommand, p, r, cg, Style_Default, opt);
+ break;
+
+ case CE_CheckBox:
+ tqdrawPrimitive(TQStyle::PE_IndicatorMask, p, r, cg, Style_Default, opt);
+ break;
+
+ case CE_RadioButton:
+ tqdrawPrimitive(TQStyle::PE_ExclusiveIndicatorMask, p, r, cg, Style_Default, opt);
+ break;
+
+ default:
+ p->fillRect(r, Qt::color1);
+ break;
+ }
+
+ activePainter = 0;
+}
+
+/*! \reimp */
+TQRect TQCommonStyle::subRect(SubRect r, const TQWidget *widget) const
+{
+#if defined(TQT_CHECK_STATE)
+ if (! widget) {
+ qWarning("TQCommonStyle::subRect: widget parameter cannot be zero!");
+ return TQRect();
+ }
+#endif
+
+ TQRect rect, wrect(widget->rect());
+
+ switch (r) {
+#ifndef TQT_NO_DIALOGBUTTONS
+ case SR_DialogButtonAbort:
+ case SR_DialogButtonRetry:
+ case SR_DialogButtonIgnore:
+ case SR_DialogButtonAccept:
+ case SR_DialogButtonReject:
+ case SR_DialogButtonApply:
+ case SR_DialogButtonHelp:
+ case SR_DialogButtonAll:
+ case SR_DialogButtonCustom: {
+ TQDialogButtons::Button srch = TQDialogButtons::None;
+ if(r == SR_DialogButtonAccept)
+ srch = TQDialogButtons::Accept;
+ else if(r == SR_DialogButtonReject)
+ srch = TQDialogButtons::Reject;
+ else if(r == SR_DialogButtonAll)
+ srch = TQDialogButtons::All;
+ else if(r == SR_DialogButtonApply)
+ srch = TQDialogButtons::Apply;
+ else if(r == SR_DialogButtonHelp)
+ srch = TQDialogButtons::Help;
+ else if(r == SR_DialogButtonRetry)
+ srch = TQDialogButtons::Retry;
+ else if(r == SR_DialogButtonIgnore)
+ srch = TQDialogButtons::Ignore;
+ else if(r == SR_DialogButtonAbort)
+ srch = TQDialogButtons::Abort;
+
+ const int bwidth = tqpixelMetric(PM_DialogButtonsButtonWidth, widget),
+ bheight = tqpixelMetric(PM_DialogButtonsButtonHeight, widget),
+ bspace = tqpixelMetric(PM_DialogButtonsSeparator, widget),
+ fw = tqpixelMetric(PM_DefaultFrameWidth, widget);
+ const TQDialogButtons *dbtns = (const TQDialogButtons *) widget;
+ int start = fw;
+ if(dbtns->orientation() == Qt::Horizontal)
+ start = wrect.right() - fw;
+ TQDialogButtons::Button btns[] = { TQDialogButtons::All, TQDialogButtons::Reject, TQDialogButtons::Accept, //reverse order (right to left)
+ TQDialogButtons::Apply, TQDialogButtons::Retry, TQDialogButtons::Ignore, TQDialogButtons::Abort,
+ TQDialogButtons::Help };
+ for(unsigned int i = 0, cnt = 0; i < (sizeof(btns)/sizeof(btns[0])); i++) {
+ if(dbtns->isButtonVisible(btns[i])) {
+ TQSize szH = dbtns->tqsizeHint(btns[i]);
+ int mwidth = TQMAX(bwidth, szH.width()), mheight = TQMAX(bheight, szH.height());
+ if(dbtns->orientation() == Qt::Horizontal) {
+ start -= mwidth;
+ if(cnt)
+ start -= bspace;
+ } else if(cnt) {
+ start += mheight;
+ start += bspace;
+ }
+ cnt++;
+ if(btns[i] == srch) {
+ if(dbtns->orientation() == Qt::Horizontal)
+ return TQRect(start, wrect.bottom() - fw - mheight, mwidth, mheight);
+ else
+ return TQRect(fw, start, mwidth, mheight);
+ }
+ }
+ }
+ if(r == SR_DialogButtonCustom) {
+ if(dbtns->orientation() == Qt::Horizontal)
+ return TQRect(fw, fw, start - fw - bspace, wrect.height() - (fw*2));
+ else
+ return TQRect(fw, start, wrect.width() - (fw*2), wrect.height() - start - (fw*2));
+ }
+ return TQRect(); }
+#endif //TQT_NO_DIALOGBUTTONS
+ case SR_PushButtonContents:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *button = (const TQPushButton *) widget;
+ int dx1, dx2;
+
+ dx1 = tqpixelMetric(PM_DefaultFrameWidth, widget);
+ if (button->isDefault() || button->autoDefault())
+ dx1 += tqpixelMetric(PM_ButtonDefaultIndicator, widget);
+ dx2 = dx1 * 2;
+
+ rect.setRect(wrect.x() + dx1,
+ wrect.y() + dx1,
+ wrect.width() - dx2,
+ wrect.height() - dx2);
+#endif
+ break;
+ }
+
+ case SR_PushButtonFocusRect:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *button = (const TQPushButton *) widget;
+ int dbw1 = 0, dbw2 = 0;
+ if (button->isDefault() || button->autoDefault()) {
+ dbw1 = tqpixelMetric(PM_ButtonDefaultIndicator, widget);
+ dbw2 = dbw1 * 2;
+ }
+
+ int dfw1 = tqpixelMetric(PM_DefaultFrameWidth, widget) * 2,
+ dfw2 = dfw1 * 2;
+
+ rect.setRect(wrect.x() + dfw1 + dbw1,
+ wrect.y() + dfw1 + dbw1,
+ wrect.width() - dfw2 - dbw2,
+ wrect.height() - dfw2 - dbw2);
+#endif
+ break;
+ }
+
+ case SR_CheckBoxIndicator:
+ {
+ int h = tqpixelMetric( PM_IndicatorHeight, widget );
+ rect.setRect(0, ( wrect.height() - h ) / 2,
+ tqpixelMetric( PM_IndicatorWidth, widget ), h );
+ break;
+ }
+
+ case SR_CheckBoxContents:
+ {
+#ifndef TQT_NO_CHECKBOX
+ TQRect ir = subRect(SR_CheckBoxIndicator, widget);
+ rect.setRect(ir.right() + 6, wrect.y(),
+ wrect.width() - ir.width() - 6, wrect.height());
+#endif
+ break;
+ }
+
+ case SR_CheckBoxFocusRect:
+ {
+#ifndef TQT_NO_CHECKBOX
+ const TQCheckBox *checkbox = (const TQCheckBox *) widget;
+ if ( !checkbox->pixmap() && checkbox->text().isEmpty() ) {
+ rect = subRect( SR_CheckBoxIndicator, widget );
+ rect.addCoords( 1, 1, -1, -1 );
+ break;
+ }
+ TQRect cr = subRect(SR_CheckBoxContents, widget);
+
+ // don't create a painter if we have an active one
+ TQPainter *p = 0;
+ if (! activePainter)
+ p = new TQPainter(checkbox);
+ rect = tqitemRect((activePainter ? activePainter : p),
+ cr, TQt::AlignLeft | TQt::AlignVCenter | TQt::ShowPrefix,
+ checkbox->isEnabled(),
+ checkbox->pixmap(),
+ checkbox->text());
+
+ delete p;
+
+ rect.addCoords( -3, -2, 3, 2 );
+ rect = rect.intersect(wrect);
+#endif
+ break;
+ }
+
+ case SR_RadioButtonIndicator:
+ {
+ int h = tqpixelMetric( PM_ExclusiveIndicatorHeight, widget );
+ rect.setRect(0, ( wrect.height() - h ) / 2,
+ tqpixelMetric( PM_ExclusiveIndicatorWidth, widget ), h );
+ break;
+ }
+
+ case SR_RadioButtonContents:
+ {
+ TQRect ir = subRect(SR_RadioButtonIndicator, widget);
+ rect.setRect(ir.right() + 6, wrect.y(),
+ wrect.width() - ir.width() - 6, wrect.height());
+ break;
+ }
+
+ case SR_RadioButtonFocusRect:
+ {
+#ifndef TQT_NO_RADIOBUTTON
+ const TQRadioButton *radiobutton = (const TQRadioButton *) widget;
+ if ( !radiobutton->pixmap() && radiobutton->text().isEmpty() ) {
+ rect = subRect( SR_RadioButtonIndicator, widget );
+ rect.addCoords( 1, 1, -1, -1 );
+ break;
+ }
+ TQRect cr = subRect(SR_RadioButtonContents, widget);
+
+ // don't create a painter if we have an active one
+ TQPainter *p = 0;
+ if (! activePainter)
+ p = new TQPainter(radiobutton);
+ rect = tqitemRect((activePainter ? activePainter : p),
+ cr, TQt::AlignLeft | TQt::AlignVCenter | TQt::ShowPrefix,
+ radiobutton->isEnabled(),
+ radiobutton->pixmap(),
+ radiobutton->text());
+ delete p;
+
+ rect.addCoords( -3, -2, 3, 2 );
+ rect = rect.intersect(wrect);
+#endif
+ break;
+ }
+
+ case SR_ComboBoxFocusRect:
+ rect.setRect(3, 3, widget->width()-6-16, widget->height()-6);
+ break;
+
+#ifndef TQT_NO_SLIDER
+ case SR_SliderFocusRect:
+ {
+ const TQSlider * sl = (const TQSlider *) widget;
+ int tickOffset = tqpixelMetric( PM_SliderTickmarkOffset, sl );
+ int thickness = tqpixelMetric( PM_SliderControlThickness, sl );
+
+ if ( sl->orientation() == Qt::Horizontal )
+ rect.setRect( 0, tickOffset-1, sl->width(), thickness+2 );
+ else
+ rect.setRect( tickOffset-1, 0, thickness+2, sl->height() );
+ rect = rect.intersect( sl->rect() ); // ## is this really necessary?
+ break;
+ }
+#endif // TQT_NO_SLIDER
+
+#ifndef TQT_NO_MAINWINDOW
+ case SR_DockWindowHandleRect:
+ {
+ if (! widget->parentWidget())
+ break;
+
+ const TQDockWindow * dw = (const TQDockWindow *) widget->parentWidget();
+
+ if ( !dw->area() || !dw->isCloseEnabled() )
+ rect.setRect( 0, 0, widget->width(), widget->height() );
+ else {
+ if ( dw->area()->orientation() == Qt::Horizontal )
+ rect.setRect(0, 15, widget->width(), widget->height() - 15);
+ else
+ rect.setRect(0, 1, widget->width() - 15, widget->height() - 1);
+ }
+ break;
+ }
+#endif // TQT_NO_MAINWINDOW
+
+ case SR_ProgressBarGroove:
+ case SR_ProgressBarContents:
+ {
+#ifndef TQT_NO_PROGRESSBAR
+ TQFontMetrics fm( ( widget ? widget->fontMetrics() :
+ TQApplication::fontMetrics() ) );
+ const TQProgressBar *progressbar = (const TQProgressBar *) widget;
+ int textw = 0;
+ if (progressbar->percentageVisible())
+ textw = fm.width("100%") + 6;
+
+ if (progressbar->indicatorFollowsStyle() ||
+ ! progressbar->centerIndicator())
+ rect.setCoords(wrect.left(), wrect.top(),
+ wrect.right() - textw, wrect.bottom());
+ else
+ rect = wrect;
+#endif
+ break;
+ }
+
+ case SR_ProgressBarLabel:
+ {
+#ifndef TQT_NO_PROGRESSBAR
+ TQFontMetrics fm( ( widget ? widget->fontMetrics() :
+ TQApplication::fontMetrics() ) );
+ const TQProgressBar *progressbar = (const TQProgressBar *) widget;
+ int textw = 0;
+ if (progressbar->percentageVisible())
+ textw = fm.width("100%") + 6;
+
+ if (progressbar->indicatorFollowsStyle() ||
+ ! progressbar->centerIndicator())
+ rect.setCoords(wrect.right() - textw, wrect.top(),
+ wrect.right(), wrect.bottom());
+ else
+ rect = wrect;
+#endif
+ break;
+ }
+
+ case SR_ToolButtonContents:
+ rect = querySubControlMetrics(CC_ToolButton, widget, SC_ToolButton);
+ break;
+
+ case SR_ToolBoxTabContents:
+ rect = wrect;
+ rect.addCoords( 0, 0, -30, 0 );
+ break;
+
+ default:
+ rect = wrect;
+ break;
+ }
+
+ return rect;
+}
+
+#ifndef TQT_NO_RANGECONTROL
+/*
+ I really need this and I don't want to expose it in TQRangeControl..
+*/
+static int qPositionFromValue( const TQRangeControl * rc, int logical_val,
+ int span )
+{
+ if ( span <= 0 || logical_val < rc->minValue() ||
+ rc->maxValue() <= rc->minValue() )
+ return 0;
+ if ( logical_val > rc->maxValue() )
+ return span;
+
+ uint range = rc->maxValue() - rc->minValue();
+ uint p = logical_val - rc->minValue();
+
+ if ( range > (uint)INT_MAX/4096 ) {
+ const int scale = 4096*2;
+ return ( (p/scale) * span ) / (range/scale);
+ // ### the above line is probably not 100% correct
+ // ### but fixing it isn't worth the extreme pain...
+ } else if ( range > (uint)span ) {
+ return (2*p*span + range) / (2*range);
+ } else {
+ uint div = span / range;
+ uint mod = span % range;
+ return p*div + (2*p*mod + range) / (2*range);
+ }
+ //equiv. to (p*span)/range + 0.5
+ // no overflow because of this implicit assumption:
+ // span <= 4096
+}
+#endif // TQT_NO_RANGECONTROL
+
+/*! \reimp */
+void TQCommonStyle::tqdrawComplexControl( TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ SCFlags controls,
+ SCFlags active,
+ const TQStyleOption& opt ) const
+{
+#if defined(TQT_CHECK_STATE)
+ if (! widget) {
+ qWarning("TQCommonStyle::tqdrawComplexControl: widget parameter cannot be zero!");
+ return;
+ }
+#endif
+
+ activePainter = p;
+
+ switch (control) {
+#ifndef TQT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ {
+ const TQScrollBar *scrollbar = (const TQScrollBar *) widget;
+ TQRect addline, subline, addpage, subpage, slider, first, last;
+ bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue());
+
+ subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, opt);
+ addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, opt);
+ subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, opt);
+ addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, opt);
+ slider = querySubControlMetrics(control, widget, SC_ScrollBarSlider, opt);
+ first = querySubControlMetrics(control, widget, SC_ScrollBarFirst, opt);
+ last = querySubControlMetrics(control, widget, SC_ScrollBarLast, opt);
+
+ if ((controls & SC_ScrollBarSubLine) && subline.isValid())
+ tqdrawPrimitive(TQStyle::PE_ScrollBarSubLine, p, subline, cg,
+ (SFlags)(((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarSubLine) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : 0)));
+ if ((controls & SC_ScrollBarAddLine) && addline.isValid())
+ tqdrawPrimitive(TQStyle::PE_ScrollBarAddLine, p, addline, cg,
+ (SFlags)(((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarAddLine) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : 0)));
+ if ((controls & SC_ScrollBarSubPage) && subpage.isValid())
+ tqdrawPrimitive(TQStyle::PE_ScrollBarSubPage, p, subpage, cg,
+ (SFlags)(((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarSubPage) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : 0)));
+ if ((controls & SC_ScrollBarAddPage) && addpage.isValid())
+ tqdrawPrimitive(TQStyle::PE_ScrollBarAddPage, p, addpage, cg,
+ (SFlags)(((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarAddPage) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : 0)));
+ if ((controls & SC_ScrollBarFirst) && first.isValid())
+ tqdrawPrimitive(TQStyle::PE_ScrollBarFirst, p, first, cg,
+ (SFlags)(((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarFirst) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : 0)));
+ if ((controls & SC_ScrollBarLast) && last.isValid())
+ tqdrawPrimitive(TQStyle::PE_ScrollBarLast, p, last, cg,
+ (SFlags)(((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarLast) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : 0)));
+ if ((controls & SC_ScrollBarSlider) && slider.isValid()) {
+ tqdrawPrimitive(TQStyle::PE_ScrollBarSlider, p, slider, cg,
+ (SFlags)(((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarSlider) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : 0)));
+
+ // ### perhaps this should not be able to accept focus if maxedOut?
+ if (scrollbar->hasFocus()) {
+ TQRect fr(slider.x() + 2, slider.y() + 2,
+ slider.width() - 5, slider.height() - 5);
+ tqdrawPrimitive(TQStyle::PE_FocusRect, p, fr, cg, Style_Default);
+ }
+ }
+
+ break;
+ }
+#endif // TQT_NO_SCROLLBAR
+
+#ifndef TQT_NO_TOOLBUTTON
+ case CC_ToolButton:
+ {
+ const TQToolButton *toolbutton = (const TQToolButton *) widget;
+
+ TQColorGroup c = cg;
+ if ( toolbutton->backgroundMode() != TQt::PaletteButton )
+ c.setBrush( TQColorGroup::Button,
+ toolbutton->paletteBackgroundColor() );
+ TQRect button, menuarea;
+ button = tqvisualRect( querySubControlMetrics(control, widget, SC_ToolButton, opt), widget );
+ menuarea = tqvisualRect( querySubControlMetrics(control, widget, SC_ToolButtonMenu, opt), widget );
+
+ SFlags bflags = flags,
+ mflags = flags;
+
+ if (active & SC_ToolButton)
+ bflags |= Style_Down;
+ if (active & SC_ToolButtonMenu)
+ mflags |= Style_Down;
+
+ if (controls & SC_ToolButton) {
+ if (bflags & (Style_Down | Style_On | Style_Raised)) {
+ tqdrawPrimitive(TQStyle::PE_ButtonTool, p, button, c, bflags, opt);
+ } else if ( toolbutton->parentWidget() &&
+ toolbutton->parentWidget()->backgroundPixmap() &&
+ ! toolbutton->parentWidget()->backgroundPixmap()->isNull() ) {
+ TQPixmap pixmap =
+ *(toolbutton->parentWidget()->backgroundPixmap());
+
+ p->drawTiledPixmap( r, pixmap, toolbutton->pos() );
+ }
+ }
+
+ if (controls & SC_ToolButtonMenu) {
+ if (mflags & (Style_Down | Style_On | Style_Raised))
+ tqdrawPrimitive(TQStyle::PE_ButtonDropDown, p, menuarea, c, mflags, opt);
+ tqdrawPrimitive(TQStyle::PE_ArrowDown, p, menuarea, c, mflags, opt);
+ }
+
+ if (toolbutton->hasFocus() && !toolbutton->focusProxy()) {
+ TQRect fr = toolbutton->rect();
+ fr.addCoords(3, 3, -3, -3);
+ tqdrawPrimitive(TQStyle::PE_FocusRect, p, fr, c);
+ }
+
+ break;
+ }
+#endif // TQT_NO_TOOLBUTTON
+
+#ifndef TQT_NO_TITLEBAR
+ case CC_TitleBar:
+ {
+ const TQTitleBar *titlebar = (const TQTitleBar *) widget;
+ if ( controls & SC_TitleBarLabel ) {
+ TQColorGroup cgroup = titlebar->usesActiveColor() ?
+ titlebar->tqpalette().active() : titlebar->tqpalette().inactive();
+
+ TQColor left = cgroup.highlight();
+ TQColor right = cgroup.base();
+
+ if ( left != right ) {
+ double rS = left.red();
+ double gS = left.green();
+ double bS = left.blue();
+
+ const double rD = double(right.red() - rS) / titlebar->width();
+ const double gD = double(right.green() - gS) / titlebar->width();
+ const double bD = double(right.blue() - bS) / titlebar->width();
+
+ const int w = titlebar->width();
+ for ( int sx = 0; sx < w; sx++ ) {
+ rS+=rD;
+ gS+=gD;
+ bS+=bD;
+ p->setPen( TQColor( (int)rS, (int)gS, (int)bS ) );
+ p->drawLine( sx, 0, sx, titlebar->height() );
+ }
+ } else {
+ p->fillRect( titlebar->rect(), left );
+ }
+
+ TQRect ir = tqvisualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarLabel ), widget );
+
+ p->setPen( cgroup.highlightedText() );
+ p->drawText(ir.x()+2, ir.y(), ir.width()-2, ir.height(),
+ TQt::AlignAuto | TQt::AlignVCenter | TQt::SingleLine, titlebar->visibleText() );
+ }
+
+ TQRect ir;
+ bool down = FALSE;
+ TQPixmap pm;
+
+ if ( controls & SC_TitleBarCloseButton ) {
+ ir = tqvisualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarCloseButton ), widget );
+ down = active & SC_TitleBarCloseButton;
+ if ( widget->testWFlags( TQt::WStyle_Tool )
+#ifndef TQT_NO_MAINWINDOW
+ || ::tqqt_cast<TQDockWindow*>(widget)
+#endif
+ )
+ pm = stylePixmap(SP_DockWindowCloseButton, widget);
+ else
+ pm = stylePixmap(SP_TitleBarCloseButton, widget);
+ tqdrawPrimitive(TQStyle::PE_ButtonTool, p, ir, titlebar->tqcolorGroup(),
+ down ? Style_Down : Style_Raised);
+
+ p->save();
+ if( down )
+ p->translate( tqpixelMetric(PM_ButtonShiftHorizontal, widget),
+ tqpixelMetric(PM_ButtonShiftVertical, widget) );
+ drawItem( p, ir, TQt::AlignCenter, titlebar->tqcolorGroup(), TRUE, &pm, TQString::null );
+ p->restore();
+ }
+
+ if ( titlebar->window() ) {
+ if ( controls & SC_TitleBarMaxButton ) {
+ ir = tqvisualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarMaxButton ), widget );
+
+ down = active & SC_TitleBarMaxButton;
+ pm = TQPixmap(stylePixmap(SP_TitleBarMaxButton, widget));
+ tqdrawPrimitive(TQStyle::PE_ButtonTool, p, ir, titlebar->tqcolorGroup(),
+ down ? Style_Down : Style_Raised);
+
+ p->save();
+ if( down )
+ p->translate( tqpixelMetric(PM_ButtonShiftHorizontal, widget),
+ tqpixelMetric(PM_ButtonShiftVertical, widget) );
+ drawItem( p, ir, TQt::AlignCenter, titlebar->tqcolorGroup(), TRUE, &pm, TQString::null );
+ p->restore();
+ }
+
+ if ( controls & SC_TitleBarNormalButton || controls & SC_TitleBarMinButton ) {
+ ir = tqvisualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarMinButton ), widget );
+ TQStyle::SubControl ctrl = (controls & SC_TitleBarNormalButton ?
+ SC_TitleBarNormalButton :
+ SC_TitleBarMinButton);
+ TQStyle::StylePixmap spixmap = (controls & SC_TitleBarNormalButton ?
+ SP_TitleBarNormalButton :
+ SP_TitleBarMinButton);
+ down = active & ctrl;
+ pm = TQPixmap(stylePixmap(spixmap, widget));
+ tqdrawPrimitive(TQStyle::PE_ButtonTool, p, ir, titlebar->tqcolorGroup(),
+ down ? Style_Down : Style_Raised);
+
+ p->save();
+ if( down )
+ p->translate( tqpixelMetric(PM_ButtonShiftHorizontal, widget),
+ tqpixelMetric(PM_ButtonShiftVertical, widget) );
+ drawItem( p, ir, TQt::AlignCenter, titlebar->tqcolorGroup(), TRUE, &pm, TQString::null );
+ p->restore();
+ }
+
+ if ( controls & SC_TitleBarShadeButton ) {
+ ir = tqvisualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarShadeButton ), widget );
+
+ down = active & SC_TitleBarShadeButton;
+ pm = TQPixmap(stylePixmap(SP_TitleBarShadeButton, widget));
+ tqdrawPrimitive(TQStyle::PE_ButtonTool, p, ir, titlebar->tqcolorGroup(),
+ down ? Style_Down : Style_Raised);
+ p->save();
+ if( down )
+ p->translate( tqpixelMetric(PM_ButtonShiftHorizontal, widget),
+ tqpixelMetric(PM_ButtonShiftVertical, widget) );
+ drawItem( p, ir, TQt::AlignCenter, titlebar->tqcolorGroup(), TRUE, &pm, TQString::null );
+ p->restore();
+ }
+
+ if ( controls & SC_TitleBarUnshadeButton ) {
+ ir = tqvisualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarUnshadeButton ), widget );
+
+ down = active & SC_TitleBarUnshadeButton;
+ pm = TQPixmap(stylePixmap(SP_TitleBarUnshadeButton, widget));
+ tqdrawPrimitive(TQStyle::PE_ButtonTool, p, ir, titlebar->tqcolorGroup(),
+ down ? Style_Down : Style_Raised);
+ p->save();
+ if( down )
+ p->translate( tqpixelMetric(PM_ButtonShiftHorizontal, widget),
+ tqpixelMetric(PM_ButtonShiftVertical, widget) );
+ drawItem( p, ir, TQt::AlignCenter, titlebar->tqcolorGroup(), TRUE, &pm, TQString::null );
+ p->restore();
+ }
+ }
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( controls & SC_TitleBarSysMenu ) {
+ if ( titlebar->icon() ) {
+ ir = tqvisualRect( querySubControlMetrics( CC_TitleBar, widget, SC_TitleBarSysMenu ), widget );
+ drawItem( p, ir, TQt::AlignCenter, titlebar->tqcolorGroup(), TRUE, titlebar->icon(), TQString::null );
+ }
+ }
+#endif
+ break;
+ }
+#endif //TQT_NO_TITLEBAR
+
+ case CC_SpinWidget: {
+#ifndef TQT_NO_SPINWIDGET
+ const TQSpinWidget * sw = (const TQSpinWidget *) widget;
+ SFlags flags;
+ PrimitiveElement pe;
+
+ if ( controls & SC_SpinWidgetFrame )
+ qDrawWinPanel( p, r, cg, TRUE ); //cstyle == Sunken );
+
+ if ( controls & SC_SpinWidgetUp ) {
+ flags = Style_Default | Style_Enabled;
+ if (active == SC_SpinWidgetUp ) {
+ flags |= Style_On;
+ flags |= Style_Sunken;
+ } else
+ flags |= Style_Raised;
+ if ( sw->buttonSymbols() == TQSpinWidget::PlusMinus )
+ pe = TQStyle::PE_SpinWidgetPlus;
+ else
+ pe = TQStyle::PE_SpinWidgetUp;
+
+ TQRect re = sw->upRect();
+ TQColorGroup ucg = sw->isUpEnabled() ? cg : sw->tqpalette().disabled();
+ tqdrawPrimitive(TQStyle::PE_ButtonBevel, p, re, ucg, flags);
+ tqdrawPrimitive(pe, p, re, ucg, flags);
+ }
+
+ if ( controls & SC_SpinWidgetDown ) {
+ flags = Style_Default | Style_Enabled;
+ if (active == SC_SpinWidgetDown ) {
+ flags |= Style_On;
+ flags |= Style_Sunken;
+ } else
+ flags |= Style_Raised;
+ if ( sw->buttonSymbols() == TQSpinWidget::PlusMinus )
+ pe = TQStyle::PE_SpinWidgetMinus;
+ else
+ pe = TQStyle::PE_SpinWidgetDown;
+
+ TQRect re = sw->downRect();
+ TQColorGroup dcg = sw->isDownEnabled() ? cg : sw->tqpalette().disabled();
+ tqdrawPrimitive(TQStyle::PE_ButtonBevel, p, re, dcg, flags);
+ tqdrawPrimitive(pe, p, re, dcg, flags);
+ }
+#endif
+ break; }
+
+#ifndef TQT_NO_SLIDER
+ case CC_Slider:
+ switch ( controls ) {
+ case SC_SliderTickmarks: {
+ const TQSlider * sl = (const TQSlider *) widget;
+ int tickOffset = tqpixelMetric( PM_SliderTickmarkOffset, sl );
+ int ticks = sl->tickmarks();
+ int thickness = tqpixelMetric( PM_SliderControlThickness, sl );
+ int len = tqpixelMetric( PM_SliderLength, sl );
+ int available = tqpixelMetric( PM_SliderSpaceAvailable, sl );
+ int interval = sl->tickInterval();
+
+ if ( interval <= 0 ) {
+ interval = sl->lineStep();
+ if ( qPositionFromValue( sl, interval, available ) -
+ qPositionFromValue( sl, 0, available ) < 3 )
+ interval = sl->pageStep();
+ }
+
+ int fudge = len / 2;
+ int pos;
+
+ if ( ticks & TQSlider::Above ) {
+ p->setPen( cg.foreground() );
+ int v = sl->minValue();
+ if ( !interval )
+ interval = 1;
+ while ( v <= sl->maxValue() + 1 ) {
+ pos = qPositionFromValue( sl, v, available ) + fudge;
+ if ( sl->orientation() == Qt::Horizontal )
+ p->drawLine( pos, 0, pos, tickOffset-2 );
+ else
+ p->drawLine( 0, pos, tickOffset-2, pos );
+ v += interval;
+ }
+ }
+
+ if ( ticks & TQSlider::Below ) {
+ p->setPen( cg.foreground() );
+ int v = sl->minValue();
+ if ( !interval )
+ interval = 1;
+ while ( v <= sl->maxValue() + 1 ) {
+ pos = qPositionFromValue( sl, v, available ) + fudge;
+ if ( sl->orientation() == Qt::Horizontal )
+ p->drawLine( pos, tickOffset+thickness+1, pos,
+ tickOffset+thickness+1 + available-2 );
+ else
+ p->drawLine( tickOffset+thickness+1, pos,
+ tickOffset+thickness+1 + available-2,
+ pos );
+ v += interval;
+ }
+
+ }
+
+ break; }
+ }
+ break;
+#endif // TQT_NO_SLIDER
+#ifndef TQT_NO_LISTVIEW
+ case CC_ListView:
+ if ( controls & SC_ListView ) {
+ TQListView *listview = (TQListView*)widget;
+ p->fillRect( r, listview->viewport()->backgroundBrush() );
+ }
+ break;
+#endif //TQT_NO_LISTVIEW
+ default:
+ break;
+ }
+
+ activePainter = 0;
+}
+
+
+/*! \reimp */
+void TQCommonStyle::tqdrawComplexControlMask( TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQStyleOption& opt ) const
+{
+ TQ_UNUSED(control);
+ TQ_UNUSED(widget);
+ TQ_UNUSED(opt);
+
+ p->fillRect(r, Qt::color1);
+}
+
+
+/*! \reimp */
+TQRect TQCommonStyle::querySubControlMetrics( TQ_ComplexControl control,
+ const TQWidget *widget,
+ SubControl sc,
+ const TQStyleOption &opt ) const
+{
+#if defined(TQT_CHECK_STATE)
+ if (! widget) {
+ qWarning("TQCommonStyle::querySubControlMetrics: widget parameter cannot be zero!");
+ return TQRect();
+ }
+#endif
+
+ switch ( control ) {
+ case CC_SpinWidget: {
+ int fw = tqpixelMetric( PM_SpinBoxFrameWidth, widget);
+ TQSize bs;
+ bs.setHeight( widget->height()/2 - fw );
+ if ( bs.height() < 8 )
+ bs.setHeight( 8 );
+ bs.setWidth( TQMIN( bs.height() * 8 / 5, widget->width() / 4 ) ); // 1.6 -approximate golden mean
+ bs = bs.expandedTo( TQApplication::globalStrut() );
+ int y = fw;
+ int x, lx, rx;
+ x = widget->width() - y - bs.width();
+ lx = fw;
+ rx = x - fw;
+ switch ( sc ) {
+ case SC_SpinWidgetUp:
+ return TQRect(x, y, bs.width(), bs.height());
+ case SC_SpinWidgetDown:
+ return TQRect(x, y + bs.height(), bs.width(), bs.height());
+ case SC_SpinWidgetButtonField:
+ return TQRect(x, y, bs.width(), widget->height() - 2*fw);
+ case SC_SpinWidgetEditField:
+ return TQRect(lx, fw, rx, widget->height() - 2*fw);
+ case SC_SpinWidgetFrame:
+ return widget->rect();
+ default:
+ break;
+ }
+ break; }
+
+ case CC_ComboBox: {
+ int x = 0, y = 0, wi = widget->width(), he = widget->height();
+ int xpos = x;
+ xpos += wi - 2 - 16;
+
+ switch ( sc ) {
+ case SC_ComboBoxFrame:
+ return widget->rect();
+ case SC_ComboBoxArrow:
+ return TQRect(xpos, y+2, 16, he-4);
+ case SC_ComboBoxEditField:
+ return TQRect(x+3, y+3, wi-6-16, he-6);
+ case SC_ComboBoxListBoxPopup:
+ return opt.rect();
+ default:
+ break;
+ }
+ break; }
+
+#ifndef TQT_NO_SCROLLBAR
+ case CC_ScrollBar: {
+ const TQScrollBar *scrollbar = (const TQScrollBar *) widget;
+ int sliderstart = 0;
+ int sbextent = tqpixelMetric(PM_ScrollBarExtent, widget);
+ int maxlen = ((scrollbar->orientation() == Qt::Horizontal) ?
+ scrollbar->width() : scrollbar->height()) - (sbextent * 2);
+ int sliderlen;
+
+ sliderstart = scrollbar->sliderStart();
+
+ // calculate slider length
+ if (scrollbar->maxValue() != scrollbar->minValue()) {
+ uint range = scrollbar->maxValue() - scrollbar->minValue();
+ sliderlen = (TQ_LLONG(scrollbar->pageStep()) * maxlen) / (range + scrollbar->pageStep());
+
+ int slidermin = tqpixelMetric( PM_ScrollBarSliderMin, widget );
+ if ( sliderlen < slidermin || range > INT_MAX / 2 )
+ sliderlen = slidermin;
+ if ( sliderlen > maxlen )
+ sliderlen = maxlen;
+ } else
+ sliderlen = maxlen;
+
+ switch (sc) {
+ case SC_ScrollBarSubLine: // top/left button
+ if (scrollbar->orientation() == Qt::Horizontal) {
+ int buttonWidth = TQMIN(scrollbar->width()/2, sbextent);
+ return TQRect( 0, 0, buttonWidth, sbextent );
+ } else {
+ int buttonHeight = TQMIN(scrollbar->height()/2, sbextent);
+ return TQRect( 0, 0, sbextent, buttonHeight );
+ }
+
+ case SC_ScrollBarAddLine: // bottom/right button
+ if (scrollbar->orientation() == Qt::Horizontal) {
+ int buttonWidth = TQMIN(scrollbar->width()/2, sbextent);
+ return TQRect( scrollbar->width() - buttonWidth, 0, buttonWidth, sbextent );
+ } else {
+ int buttonHeight = TQMIN(scrollbar->height()/2, sbextent);
+ return TQRect( 0, scrollbar->height() - buttonHeight, sbextent, buttonHeight );
+ }
+
+ case SC_ScrollBarSubPage: // between top/left button and slider
+ if (scrollbar->orientation() == Qt::Horizontal)
+ return TQRect(sbextent, 0, sliderstart - sbextent, sbextent);
+ return TQRect(0, sbextent, sbextent, sliderstart - sbextent);
+
+ case SC_ScrollBarAddPage: // between bottom/right button and slider
+ if (scrollbar->orientation() == Qt::Horizontal)
+ return TQRect(sliderstart + sliderlen, 0,
+ maxlen - sliderstart - sliderlen + sbextent, sbextent);
+ return TQRect(0, sliderstart + sliderlen,
+ sbextent, maxlen - sliderstart - sliderlen + sbextent);
+
+ case SC_ScrollBarGroove:
+ if (scrollbar->orientation() == Qt::Horizontal)
+ return TQRect(sbextent, 0, scrollbar->width() - sbextent * 2,
+ scrollbar->height());
+ return TQRect(0, sbextent, scrollbar->width(),
+ scrollbar->height() - sbextent * 2);
+
+ case SC_ScrollBarSlider:
+ if (scrollbar->orientation() == Qt::Horizontal)
+ return TQRect(sliderstart, 0, sliderlen, sbextent);
+ return TQRect(0, sliderstart, sbextent, sliderlen);
+
+ default: break;
+ }
+
+ break; }
+#endif // TQT_NO_SCROLLBAR
+
+#ifndef TQT_NO_SLIDER
+ case CC_Slider: {
+ const TQSlider * sl = (const TQSlider *) widget;
+ int tickOffset = tqpixelMetric( PM_SliderTickmarkOffset, sl );
+ int thickness = tqpixelMetric( PM_SliderControlThickness, sl );
+
+ switch ( sc ) {
+ case SC_SliderHandle: {
+ int sliderPos = 0;
+ int len = tqpixelMetric( PM_SliderLength, sl );
+
+ sliderPos = sl->sliderStart();
+
+ if ( sl->orientation() == Qt::Horizontal )
+ return TQRect( sliderPos, tickOffset, len, thickness );
+ return TQRect( tickOffset, sliderPos, thickness, len ); }
+ case SC_SliderGroove: {
+ if ( sl->orientation() == Qt::Horizontal )
+ return TQRect( 0, tickOffset, sl->width(), thickness );
+ return TQRect( tickOffset, 0, thickness, sl->height() ); }
+
+ default:
+ break;
+ }
+ break; }
+#endif // TQT_NO_SLIDER
+
+#if !defined(TQT_NO_TOOLBUTTON) && !defined(TQT_NO_POPUPMENU)
+ case CC_ToolButton: {
+ const TQToolButton *toolbutton = (const TQToolButton *) widget;
+ int mbi = tqpixelMetric(PM_MenuButtonIndicator, widget);
+
+ TQRect rect = toolbutton->rect();
+ switch (sc) {
+ case SC_ToolButton:
+ if (toolbutton->popup() && ! toolbutton->popupDelay())
+ rect.addCoords(0, 0, -mbi, 0);
+ return rect;
+
+ case SC_ToolButtonMenu:
+ if (toolbutton->popup() && ! toolbutton->popupDelay())
+ rect.addCoords(rect.width() - mbi, 0, 0, 0);
+ return rect;
+
+ default: break;
+ }
+ break;
+ }
+#endif // TQT_NO_TOOLBUTTON && TQT_NO_POPUPMENU
+
+#ifndef TQT_NO_TITLEBAR
+ case CC_TitleBar: {
+ const TQTitleBar *titlebar = (const TQTitleBar *) widget;
+ const int controlTop = 2;
+ const int controlHeight = widget->height() - controlTop * 2;
+
+ switch (sc) {
+ case SC_TitleBarLabel: {
+ const TQTitleBar *titlebar = (TQTitleBar*)widget;
+ TQRect ir( 0, 0, titlebar->width(), titlebar->height() );
+ if ( titlebar->testWFlags( TQt::WStyle_Tool ) ) {
+ if ( titlebar->testWFlags( TQt::WStyle_SysMenu ) )
+ ir.addCoords( 0, 0, -controlHeight-3, 0 );
+ if ( titlebar->testWFlags( TQt::WStyle_MinMax ) )
+ ir.addCoords( 0, 0, -controlHeight-2, 0 );
+ } else {
+ if ( titlebar->testWFlags( TQt::WStyle_SysMenu ) )
+ ir.addCoords( controlHeight+3, 0, -controlHeight-3, 0 );
+ if ( titlebar->testWFlags( TQt::WStyle_Minimize ) )
+ ir.addCoords( 0, 0, -controlHeight-2, 0 );
+ if ( titlebar->testWFlags( TQt::WStyle_Maximize ) )
+ ir.addCoords( 0, 0, -controlHeight-2, 0 );
+ }
+ return ir; }
+
+ case SC_TitleBarCloseButton:
+ return TQRect( titlebar->width() - ( controlHeight + controlTop ),
+ controlTop, controlHeight, controlHeight );
+
+ case SC_TitleBarMaxButton:
+ case SC_TitleBarShadeButton:
+ case SC_TitleBarUnshadeButton:
+ return TQRect( titlebar->width() - ( ( controlHeight + controlTop ) * 2 ),
+ controlTop, controlHeight, controlHeight );
+
+ case SC_TitleBarMinButton:
+ case SC_TitleBarNormalButton: {
+ int offset = controlHeight + controlTop;
+ if ( !titlebar->testWFlags( TQt::WStyle_Maximize ) )
+ offset *= 2;
+ else
+ offset *= 3;
+ return TQRect( titlebar->width() - offset, controlTop, controlHeight, controlHeight );
+ }
+
+ case SC_TitleBarSysMenu:
+ return TQRect( 3, controlTop, controlHeight, controlHeight);
+
+ default: break;
+ }
+ break; }
+#endif //TQT_NO_TITLEBAR
+
+ default:
+ break;
+ }
+ return TQRect();
+}
+
+
+/*! \reimp */
+TQStyle::SubControl TQCommonStyle::querySubControl(TQ_ComplexControl control,
+ const TQWidget *widget,
+ const TQPoint &pos,
+ const TQStyleOption& opt ) const
+{
+ SubControl ret = SC_None;
+
+ switch (control) {
+#ifndef TQT_NO_LISTVIEW
+ case CC_ListView:
+ {
+ if(pos.x() >= 0 && pos.x() <
+ opt.listViewItem()->listView()->treeStepSize())
+ ret = SC_ListViewExpand;
+ break;
+ }
+#endif
+#ifndef TQT_NO_SCROLLBAR
+ case CC_ScrollBar:
+ {
+ TQRect r;
+ uint ctrl = SC_ScrollBarAddLine;
+
+ // we can do this because subcontrols were designed to be masks as well...
+ while (ret == SC_None && ctrl <= SC_ScrollBarGroove) {
+ r = querySubControlMetrics(control, widget,
+ (TQStyle::SubControl) ctrl, opt);
+ if (r.isValid() && r.tqcontains(pos))
+ ret = (TQStyle::SubControl) ctrl;
+
+ ctrl <<= 1;
+ }
+
+ break;
+ }
+#endif
+ case CC_TitleBar:
+ {
+#ifndef TQT_NO_TITLEBAR
+ const TQTitleBar *titlebar = (TQTitleBar*)widget;
+ TQRect r;
+ uint ctrl = SC_TitleBarLabel;
+
+ // we can do this because subcontrols were designed to be masks as well...
+ while (ret == SC_None && ctrl <= SC_TitleBarUnshadeButton) {
+ r = tqvisualRect( querySubControlMetrics( control, widget, (TQStyle::SubControl) ctrl, opt ), widget );
+ if (r.isValid() && r.tqcontains(pos))
+ ret = (TQStyle::SubControl) ctrl;
+
+ ctrl <<= 1;
+ }
+ if ( titlebar->window() ) {
+ if (titlebar->testWFlags( TQt::WStyle_Tool )) {
+ if ( ret == SC_TitleBarMinButton || ret == SC_TitleBarMaxButton ) {
+ if ( titlebar->window()->isMinimized() )
+ ret = SC_TitleBarUnshadeButton;
+ else
+ ret = SC_TitleBarShadeButton;
+ }
+ } else if ( ret == SC_TitleBarMinButton && titlebar->window()->isMinimized() ) {
+ ret = TQStyle::SC_TitleBarNormalButton;
+ }
+ }
+#endif
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+
+/*! \reimp */
+int TQCommonStyle::tqpixelMetric(PixelMetric m, const TQWidget *widget) const
+{
+ int ret;
+
+ switch (m) {
+ case PM_DialogButtonsSeparator:
+ ret = 5;
+ break;
+ case PM_DialogButtonsButtonWidth:
+ ret = 70;
+ break;
+ case PM_DialogButtonsButtonHeight:
+ ret = 30;
+ break;
+ case PM_CheckListControllerSize:
+ case PM_CheckListButtonSize:
+ ret = 16;
+ break;
+ case PM_TitleBarHeight: {
+ if ( widget ) {
+ if ( widget->testWFlags( TQt::WStyle_Tool ) ) {
+ ret = TQMAX( widget->fontMetrics().lineSpacing(), 16 );
+#ifndef TQT_NO_MAINWINDOW
+ } else if ( ::tqqt_cast<TQDockWindow*>(widget) ) {
+ ret = TQMAX( widget->fontMetrics().lineSpacing(), 13 );
+#endif
+ } else {
+ ret = TQMAX( widget->fontMetrics().lineSpacing(), 18 );
+ }
+ } else {
+ ret = 0;
+ }
+
+ break; }
+ case PM_ScrollBarSliderMin:
+ ret = 9;
+ break;
+
+ case PM_ButtonMargin:
+ ret = 6;
+ break;
+
+ case PM_ButtonDefaultIndicator:
+ ret = 0;
+ break;
+
+ case PM_MenuButtonIndicator:
+ if (! widget)
+ ret = 12;
+ else
+ ret = TQMAX(12, (widget->height() - 4) / 3);
+ break;
+
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 0;
+ break;
+
+ case PM_SpinBoxFrameWidth:
+ case PM_DefaultFrameWidth:
+ ret = 2;
+ break;
+
+ case PM_MDIFrameWidth:
+ ret = 2;
+ break;
+
+ case PM_MDIMinimizedWidth:
+ ret = 196;
+ break;
+
+#ifndef TQT_NO_SCROLLBAR
+ case PM_ScrollBarExtent:
+ if ( !widget ) {
+ ret = 16;
+ } else {
+ const TQScrollBar *bar = (const TQScrollBar*)widget;
+ int s = bar->orientation() == Qt::Horizontal ?
+ TQApplication::globalStrut().height()
+ : TQApplication::globalStrut().width();
+ ret = TQMAX( 16, s );
+ }
+ break;
+#endif
+ case PM_MaximumDragDistance:
+ ret = -1;
+ break;
+
+#ifndef TQT_NO_SLIDER
+ case PM_SliderThickness:
+ ret = 16;
+ break;
+
+ case PM_SliderTickmarkOffset:
+ {
+ if (! widget) {
+ ret = 0;
+ break;
+ }
+
+ const TQSlider * sl = (const TQSlider *) widget;
+ int space = (sl->orientation() == Qt::Horizontal) ? sl->height() :
+ sl->width();
+ int thickness = tqpixelMetric( PM_SliderControlThickness, sl );
+ int ticks = sl->tickmarks();
+
+ if ( ticks == TQSlider::Both )
+ ret = (space - thickness) / 2;
+ else if ( ticks == TQSlider::Above )
+ ret = space - thickness;
+ else
+ ret = 0;
+ break;
+ }
+
+ case PM_SliderSpaceAvailable:
+ {
+ const TQSlider * sl = (const TQSlider *) widget;
+ if ( sl->orientation() == Qt::Horizontal )
+ ret = sl->width() - tqpixelMetric( PM_SliderLength, sl );
+ else
+ ret = sl->height() - tqpixelMetric( PM_SliderLength, sl );
+ break;
+ }
+#endif // TQT_NO_SLIDER
+
+ case PM_DockWindowSeparatorExtent:
+ ret = 6;
+ break;
+
+ case PM_DockWindowHandleExtent:
+ ret = 8;
+ break;
+
+ case PM_DockWindowFrameWidth:
+ ret = 1;
+ break;
+
+ case PM_MenuBarFrameWidth:
+ ret = 2;
+ break;
+
+ case PM_MenuBarItemSpacing:
+ case PM_ToolBarItemSpacing:
+ ret = 0;
+ break;
+
+ case PM_TabBarTabOverlap:
+ ret = 3;
+ break;
+
+ case PM_TabBarBaseHeight:
+ ret = 0;
+ break;
+
+ case PM_TabBarBaseOverlap:
+ ret = 0;
+ break;
+
+ case PM_TabBarTabHSpace:
+ ret = 24;
+ break;
+
+ case PM_TabBarTabShiftHorizontal:
+ case PM_TabBarTabShiftVertical:
+ ret = 2;
+ break;
+
+#ifndef TQT_NO_TABBAR
+ case PM_TabBarTabVSpace:
+ {
+ const TQTabBar * tb = (const TQTabBar *) widget;
+ if ( tb && ( tb->tqshape() == TQTabBar::RoundedAbove ||
+ tb->tqshape() == TQTabBar::RoundedBelow ) )
+ ret = 10;
+ else
+ ret = 0;
+ break;
+ }
+#endif
+
+ case PM_ProgressBarChunkWidth:
+ ret = 9;
+ break;
+
+ case PM_IndicatorWidth:
+ ret = 13;
+ break;
+
+ case PM_IndicatorHeight:
+ ret = 13;
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ ret = 12;
+ break;
+
+ case PM_ExclusiveIndicatorHeight:
+ ret = 12;
+ break;
+
+ case PM_PopupMenuFrameHorizontalExtra:
+ case PM_PopupMenuFrameVerticalExtra:
+ ret = 0;
+ break;
+
+ case PM_HeaderMargin:
+ ret = 4;
+ break;
+ case PM_HeaderMarkSize:
+ ret = 32;
+ break;
+ case PM_HeaderGripMargin:
+ ret = 4;
+ break;
+ case PM_TabBarScrollButtonWidth:
+ ret = 16;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+
+/*! \reimp */
+TQSize TQCommonStyle::tqsizeFromContents(ContentsType contents,
+ const TQWidget *widget,
+ const TQSize &contentsSize,
+ const TQStyleOption& opt ) const
+{
+ TQSize sz(contentsSize);
+
+#if defined(TQT_CHECK_STATE)
+ if (! widget) {
+ qWarning("TQCommonStyle::tqsizeFromContents: widget parameter cannot be zero!");
+ return sz;
+ }
+#endif
+
+ switch (contents) {
+#ifndef TQT_NO_DIALOGBUTTONS
+ case CT_DialogButtons: {
+ const TQDialogButtons *dbtns = (const TQDialogButtons *)widget;
+ int w = contentsSize.width(), h = contentsSize.height();
+ const int bwidth = tqpixelMetric(PM_DialogButtonsButtonWidth, widget),
+ bspace = tqpixelMetric(PM_DialogButtonsSeparator, widget),
+ bheight = tqpixelMetric(PM_DialogButtonsButtonHeight, widget);
+ if(dbtns->orientation() == Qt::Horizontal) {
+ if(!w)
+ w = bwidth;
+ } else {
+ if(!h)
+ h = bheight;
+ }
+ TQDialogButtons::Button btns[] = { TQDialogButtons::All, TQDialogButtons::Reject, TQDialogButtons::Accept, //reverse order (right to left)
+ TQDialogButtons::Apply, TQDialogButtons::Retry, TQDialogButtons::Ignore, TQDialogButtons::Abort,
+ TQDialogButtons::Help };
+ for(unsigned int i = 0, cnt = 0; i < (sizeof(btns)/sizeof(btns[0])); i++) {
+ if(dbtns->isButtonVisible(btns[i])) {
+ TQSize szH = dbtns->tqsizeHint(btns[i]);
+ int mwidth = TQMAX(bwidth, szH.width()), mheight = TQMAX(bheight, szH.height());
+ if(dbtns->orientation() == Qt::Horizontal)
+ h = TQMAX(h, mheight);
+ else
+ w = TQMAX(w, mwidth);
+
+ if(cnt)
+ w += bspace;
+ cnt++;
+ if(dbtns->orientation() == Qt::Horizontal)
+ w += mwidth;
+ else
+ h += mheight;
+ }
+ }
+ const int fw = tqpixelMetric(PM_DefaultFrameWidth, widget) * 2;
+ sz = TQSize(w + fw, h + fw);
+ break; }
+#endif //TQT_NO_DIALOGBUTTONS
+ case CT_PushButton:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *button = (const TQPushButton *) widget;
+ int w = contentsSize.width(),
+ h = contentsSize.height(),
+ bm = tqpixelMetric(PM_ButtonMargin, widget),
+ fw = tqpixelMetric(PM_DefaultFrameWidth, widget) * 2;
+
+ w += bm + fw;
+ h += bm + fw;
+
+ if (button->isDefault() || button->autoDefault()) {
+ int dbw = tqpixelMetric(PM_ButtonDefaultIndicator, widget) * 2;
+ w += dbw;
+ h += dbw;
+ }
+
+ sz = TQSize(w, h);
+#endif
+ break;
+ }
+
+ case CT_CheckBox:
+ {
+#ifndef TQT_NO_CHECKBOX
+ const TQCheckBox *checkbox = (const TQCheckBox *) widget;
+ TQRect irect = subRect(SR_CheckBoxIndicator, widget);
+ int h = tqpixelMetric( PM_IndicatorHeight, widget );
+ int margins = (!checkbox->pixmap() && checkbox->text().isEmpty()) ? 0 : 10;
+ sz += TQSize(irect.right() + margins, 4 );
+ sz.setHeight( TQMAX( sz.height(), h ) );
+#endif
+ break;
+ }
+
+ case CT_RadioButton:
+ {
+#ifndef TQT_NO_RADIOBUTTON
+ const TQRadioButton *radiobutton = (const TQRadioButton *) widget;
+ TQRect irect = subRect(SR_RadioButtonIndicator, widget);
+ int h = tqpixelMetric( PM_ExclusiveIndicatorHeight, widget );
+ int margins = (!radiobutton->pixmap() && radiobutton->text().isEmpty()) ? 0 : 10;
+ sz += TQSize(irect.right() + margins, 4 );
+ sz.setHeight( TQMAX( sz.height(), h ) );
+#endif
+ break;
+ }
+
+ case CT_ToolButton:
+ {
+ sz = TQSize(sz.width() + 6, sz.height() + 5);
+ break;
+ }
+
+ case CT_ComboBox:
+ {
+ int dfw = tqpixelMetric(PM_DefaultFrameWidth, widget) * 2;
+ sz = TQSize(sz.width() + dfw + 21, sz.height() + dfw );
+ break;
+ }
+
+ case CT_PopupMenuItem:
+ {
+#ifndef TQT_NO_POPUPMENU
+ if (opt.isDefault())
+ break;
+
+ const TQPopupMenu *popup = (const TQPopupMenu *) widget;
+ bool checkable = popup->isCheckable();
+ TQMenuItem *mi = opt.menuItem();
+ int maxpmw = opt.maxIconWidth();
+ int w = sz.width(), h = sz.height();
+
+ if (mi->custom()) {
+ w = mi->custom()->tqsizeHint().width();
+ h = mi->custom()->tqsizeHint().height();
+ if (! mi->custom()->fullSpan())
+ h += 8;
+ } else if ( mi->widget() ) {
+ } else if (mi->isSeparator()) {
+ w = 10;
+ h = 2;
+ } else {
+ if (mi->pixmap())
+ h = TQMAX(h, mi->pixmap()->height() + 4);
+ else
+ h = TQMAX(h, popup->fontMetrics().height() + 8);
+
+ if (mi->iconSet() != 0)
+ h = TQMAX(h, mi->iconSet()->pixmap(TQIconSet::Small,
+ TQIconSet::Normal).height() + 4);
+ }
+
+ if (! mi->text().isNull()) {
+ if (mi->text().tqfind('\t') >= 0)
+ w += 12;
+ }
+
+ if (maxpmw)
+ w += maxpmw + 6;
+ if (checkable && maxpmw < 20)
+ w += 20 - maxpmw;
+ if (checkable || maxpmw > 0)
+ w += 2;
+ w += 12;
+
+ sz = TQSize(w, h);
+#endif
+ break;
+ }
+
+ case CT_LineEdit:
+ case CT_Header:
+ case CT_Slider:
+ case CT_ProgressBar:
+ // just return the contentsSize for now
+ // fall through intended
+
+ default:
+ break;
+ }
+
+ return sz;
+}
+
+
+/*! \reimp */
+int TQCommonStyle::tqstyleHint(TQ_StyleHint sh, const TQWidget * w, const TQStyleOption &, TQStyleHintReturn *) const
+{
+ int ret;
+
+ switch (sh) {
+#ifndef TQT_NO_DIALOGBUTTONS
+ case SH_DialogButtons_DefaultButton:
+ ret = TQDialogButtons::Accept;
+ break;
+#endif
+ case SH_GroupBox_TextLabelVerticalAlignment:
+ ret = TQt::TQt::AlignVCenter;
+ break;
+
+ case SH_GroupBox_TextLabelColor:
+ ret = (int) ( w ? w->paletteForegroundColor().rgb() : 0 );
+ break;
+
+ case SH_ListViewExpand_SelectMouseType:
+ case SH_TabBar_SelectMouseType:
+ ret = TQEvent::MouseButtonPress;
+ break;
+
+ case SH_GUIStyle:
+ ret = TQt::WindowsStyle;
+ break;
+
+ case SH_ScrollBar_BackgroundMode:
+ ret = TQt::PaletteBackground;
+ break;
+
+ case SH_TabBar_Alignment:
+ case SH_Header_ArrowAlignment:
+ ret = TQt::AlignLeft;
+ break;
+
+ case SH_PopupMenu_SubMenuPopupDelay:
+ ret = 256;
+ break;
+
+ case SH_ProgressDialog_TextLabelAlignment:
+ ret = TQt::AlignCenter;
+ break;
+
+ case SH_BlinkCursorWhenTextSelected:
+ ret = 1;
+ break;
+
+ case SH_Table_GridLineColor:
+ ret = -1;
+ break;
+
+ case SH_LineEdit_PasswordCharacter:
+ ret = '*';
+ break;
+
+ case SH_ToolBox_SelectedPageTitleBold:
+ ret = 1;
+ break;
+
+ case SH_UnderlineAccelerator:
+ ret = 1;
+ break;
+
+ case SH_ToolButton_Uses3D:
+ ret = 1;
+ break;
+
+ default:
+ ret = 0;
+ break;
+ }
+
+ return ret;
+}
+
+/*! \reimp */
+TQPixmap TQCommonStyle::stylePixmap(StylePixmap, const TQWidget *, const TQStyleOption&) const
+{
+ return TQPixmap();
+}
+
+
+#endif // TQT_NO_STYLE
diff --git a/tqtinterface/qt4/src/styles/tqcommonstyle.h b/tqtinterface/qt4/src/styles/tqcommonstyle.h
new file mode 100644
index 0000000..ef01d89
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqcommonstyle.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Definition of TQCommonStyle class
+**
+** Created : 980616
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCOMMONSTYLE_H
+#define TQCOMMONSTYLE_H
+
+#ifndef TQT_H
+#include "tqstyle.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_STYLE
+
+class TQ_EXPORT TQCommonStyle: public TQStyle
+{
+ TQ_OBJECT
+
+public:
+ TQCommonStyle();
+ ~TQCommonStyle();
+
+ // Compatibility functions
+ // For example, a TQt application may call tqdrawPrimitive with a ControlElement parameter
+ // TQt "knows" that the application should have called tqdrawControl instead, and translates accordingly.
+ inline void tqdrawPrimitive( TQ_ControlElement element, TQPainter *p, const TQRect &r, const TQColorGroup &cg, SFlags flags = Style_Default, const TQStyleOption &opt = TQStyleOption::Default ) const {
+ TQ_UNUSED(r);
+ TQ_UNUSED(cg);
+ TQ_UNUSED(flags);
+ drawControl((QStyle::ControlElement)(int)element, &opt, p, 0); // [FIXME] What should widget really be? I imagine 0 is *wrong*!!!
+ }
+ inline void tqdrawPrimitive( TQ_ComplexControl element, TQPainter *p, const TQRect &r, const TQColorGroup &cg, SFlags flags = Style_Default, const TQStyleOption &opt = TQStyleOption::Default ) const {
+ TQ_UNUSED(r);
+ TQ_UNUSED(cg);
+ TQ_UNUSED(flags);
+ drawComplexControl((QStyle::ComplexControl)(int)element, 0, p, 0); // [FIXME] What should widget and complexcontrol really be? I imagine 0 is *wrong*!!!
+ }
+ inline void tqdrawPrimitive( TQ_ControlElement element, TQPainter *p, const TQRect &r, const TQColorGroup &cg, int flags, const TQStyleOption &opt = TQStyleOption::Default ) const { tqdrawPrimitive( element, p, r, cg, (SFlags)flags, opt); }
+
+ void tqdrawPrimitive( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawControlMask( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ TQRect subRect( SubRect r, const TQWidget *widget ) const;
+
+ void tqdrawComplexControl( TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+#ifdef TQ_TQDOC
+ SCFlags sub = SC_All,
+#else
+ SCFlags sub = (uint)SC_All,
+#endif
+ SCFlags subActive = SC_None,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawComplexControlMask( TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ TQRect querySubControlMetrics( TQ_ComplexControl control,
+ const TQWidget *widget,
+ SubControl sc,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ SubControl querySubControl( TQ_ComplexControl control,
+ const TQWidget *widget,
+ const TQPoint &pos,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ int tqpixelMetric( PixelMetric m, const TQWidget *widget = 0 ) const;
+
+ TQSize tqsizeFromContents( ContentsType s,
+ const TQWidget *widget,
+ const TQSize &contentsSize,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ int tqstyleHint(TQ_StyleHint sh, const TQWidget *, const TQStyleOption &, TQStyleHintReturn *) const;
+
+ TQPixmap stylePixmap( StylePixmap sp,
+ const TQWidget *widget = 0,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+
+private:
+ // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQCommonStyle( const TQCommonStyle & );
+ TQCommonStyle &operator=( const TQCommonStyle & );
+#endif
+};
+
+
+
+#endif // TQT_NO_STYLE
+
+#endif // TQCOMMONSTYLE_H
diff --git a/tqtinterface/qt4/src/styles/tqcompactstyle.cpp b/tqtinterface/qt4/src/styles/tqcompactstyle.cpp
new file mode 100644
index 0000000..44cd711
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqcompactstyle.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Implementation of compact style class
+**
+** Created : 006231
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcompactstyle.h"
+
+#if !defined(TQT_NO_STYLE_COMPACT) || defined(TQT_PLUGIN)
+
+#include "tqfontmetrics.h"
+#include "tqpalette.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqmenudata.h"
+#include "tqpopupmenu.h"
+
+TQCompactStyle::TQCompactStyle()
+: TQWindowsStyle()
+{
+}
+
+/*! \reimp */
+int TQCompactStyle::tqpixelMetric( PixelMetric metric, const TQWidget *widget )
+{
+ int ret;
+ switch ( metric ) {
+ case PM_ButtonMargin:
+ ret = 2;
+ break;
+ // tws - I added this in to stop this "Windows Scroll behaivor." Remove it
+ // if you don't want it.
+ case PM_MaximumDragDistance:
+ ret = -1;
+ break;
+ default:
+ ret = TQWindowsStyle::tqpixelMetric( metric, widget );
+ break;
+ }
+ return ret;
+}
+
+static const int motifItemFrame = 0; // menu item frame width
+static const int motifSepHeight = 2; // separator item height
+static const int motifItemHMargin = 1; // menu item hor text margin
+static const int motifItemVMargin = 2; // menu item ver text margin
+static const int motifArrowHMargin = 0; // arrow horizontal margin
+static const int motifTabSpacing = 4; // space between text and tab
+static const int motifCheckMarkHMargin = 1; // horiz. margins of check mark
+static const int windowsRightBorder = 8; // right border on windows
+static const int windowsCheckMarkWidth = 2; // checkmarks width on windows
+
+static int extraPopupMenuItemWidth( bool checkable, int maxpmw, TQMenuItem* mi, const TQFontMetrics& /*fm*/ )
+{
+ int w = 2*motifItemHMargin + 2*motifItemFrame; // a little bit of border can never harm
+
+ if ( mi->isSeparator() )
+ return 10; // arbitrary
+ else if ( mi->pixmap() )
+ w += mi->pixmap()->width(); // pixmap only
+
+ if ( !mi->text().isNull() ) {
+ if ( mi->text().tqfind('\t') >= 0 ) // string tqcontains tab
+ w += motifTabSpacing;
+ }
+
+ if ( maxpmw ) { // we have iconsets
+ w += maxpmw;
+ w += 6; // add a little extra border around the iconset
+ }
+
+ if ( checkable && maxpmw < windowsCheckMarkWidth ) {
+ w += windowsCheckMarkWidth - maxpmw; // space for the checkmarks
+ }
+
+ if ( maxpmw > 0 || checkable ) // we have a check-column ( iconsets or checkmarks)
+ w += motifCheckMarkHMargin; // add space to separate the columns
+
+ w += windowsRightBorder; // windows has a strange wide border on the right side
+
+ return w;
+}
+
+static int popupMenuItemHeight( bool /*checkable*/, TQMenuItem* mi, const TQFontMetrics& fm )
+{
+ int h = 0;
+ if ( mi->isSeparator() ) // separator height
+ h = motifSepHeight;
+ else if ( mi->pixmap() ) // pixmap height
+ h = mi->pixmap()->height() + 2*motifItemFrame;
+ else // text height
+ h = fm.height() + 2*motifItemVMargin + 2*motifItemFrame - 1;
+
+ if ( !mi->isSeparator() && mi->iconSet() != 0 ) {
+ h = TQMAX( h, mi->iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).height() + 2*motifItemFrame );
+ }
+ if ( mi->custom() )
+ h = TQMAX( h, mi->custom()->tqsizeHint().height() + 2*motifItemVMargin + 2*motifItemFrame ) - 1;
+ return h;
+}
+
+void drawPopupMenuItem( TQPainter* p, bool checkable,
+ int maxpmw, int tab, TQMenuItem* mi,
+ const TQPalette& pal, bool act,
+ bool enabled,
+ int x, int y, int w, int h)
+{
+
+}
+
+/*! \reimp */
+void TQCompactStyle::tqdrawControl( ControlElement element, TQPainter *p, const TQWidget *widget, const TQRect &r,
+ const TQColorGroup &g, SFlags flags, const TQStyleOption& opt )
+{
+ switch ( element ) {
+ case CE_PopupMenuItem:
+ {
+ if (! widget || opt.isDefault())
+ break;
+
+ const TQPopupMenu *popupmenu = (const TQPopupMenu *) widget;
+ TQMenuItem *mi = opt.menuItem();
+ if ( !mi )
+ break;
+
+ int tab = opt.tabWidth();
+ int maxpmw = opt.maxIconWidth();
+ bool dis = !(flags & Style_Enabled);
+ bool checkable = popupmenu->isCheckable();
+ bool act = flags & Style_Active;
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+
+ TQColorGroup itemg = g;
+
+ if ( checkable )
+ maxpmw = TQMAX( maxpmw, 8 ); // space for the checkmarks
+
+ int checkcol = maxpmw;
+
+ if ( mi && mi->isSeparator() ) { // draw separator
+ p->setPen( g.dark() );
+ p->drawLine( x, y, x+w, y );
+ p->setPen( g.light() );
+ p->drawLine( x, y+1, x+w, y+1 );
+ return;
+ }
+
+ TQBrush fill = act? g.brush( TQColorGroup::Highlight ) :
+ g.brush( TQColorGroup::Button );
+ p->fillRect( x, y, w, h, fill);
+
+ if ( !mi )
+ return;
+
+ if ( mi->isChecked() ) {
+ if ( act && !dis ) {
+ qDrawShadePanel( p, x, y, checkcol, h,
+ g, TRUE, 1, &g.brush( TQColorGroup::Button ) );
+ } else {
+ qDrawShadePanel( p, x, y, checkcol, h,
+ g, TRUE, 1, &g.brush( TQColorGroup::Midlight ) );
+ }
+ } else if ( !act ) {
+ p->fillRect(x, y, checkcol , h,
+ g.brush( TQColorGroup::Button ));
+ }
+
+ if ( mi->iconSet() ) { // draw iconset
+ TQIconSet::Mode mode = dis ? TQIconSet::Disabled : TQIconSet::Normal;
+ if (act && !dis )
+ mode = TQIconSet::Active;
+ TQPixmap pixmap;
+ if ( checkable && mi->isChecked() )
+ pixmap = mi->iconSet()->pixmap( TQIconSet::Small, mode, TQIconSet::On );
+ else
+ pixmap = mi->iconSet()->pixmap( TQIconSet::Small, mode );
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ if ( act && !dis ) {
+ if ( !mi->isChecked() )
+ qDrawShadePanel( p, x, y, checkcol, h, g, FALSE, 1, &g.brush( TQColorGroup::Button ) );
+ }
+ TQRect cr( x, y, checkcol, h );
+ TQRect pmr( 0, 0, pixw, pixh );
+ pmr.moveCenter( cr.center() );
+ p->setPen( itemg.text() );
+ p->drawPixmap( pmr.topLeft(), pixmap );
+
+ TQBrush fill = act? g.brush( TQColorGroup::Highlight ) :
+ g.brush( TQColorGroup::Button );
+ p->fillRect( x+checkcol + 1, y, w - checkcol - 1, h, fill);
+ } else if ( checkable ) { // just "checking"...
+ int mw = checkcol + motifItemFrame;
+ int mh = h - 2*motifItemFrame;
+ if ( mi->isChecked() ) {
+
+ SFlags cflags = Style_Default;
+ if (! dis)
+ cflags |= Style_Enabled;
+ if (act)
+ cflags |= Style_On;
+
+ drawPrimitive( PE_CheckMark, p, TQRect(x + motifItemFrame + 2, y + motifItemFrame,
+ mw, mh), itemg, cflags, opt );
+ }
+ }
+
+ p->setPen( act ? g.highlightedText() : g.buttonText() );
+
+ TQColor discol;
+ if ( dis ) {
+ discol = itemg.text();
+ p->setPen( discol );
+ }
+
+ int xm = motifItemFrame + checkcol + motifItemHMargin;
+
+ if ( mi->custom() ) {
+ int m = motifItemVMargin;
+ p->save();
+ if ( dis && !act ) {
+ p->setPen( g.light() );
+ mi->custom()->paint( p, itemg, act, !dis,
+ x+xm+1, y+m+1, w-xm-tab+1, h-2*m );
+ p->setPen( discol );
+ }
+ mi->custom()->paint( p, itemg, act, !dis,
+ x+xm, y+m, w-xm-tab+1, h-2*m );
+ p->restore();
+ }
+ TQString s = mi->text();
+ if ( !s.isNull() ) { // draw text
+ int t = s.tqfind( '\t' );
+ int m = motifItemVMargin;
+ const int text_flags = AlignVCenter|ShowPrefix | DontClip | SingleLine;
+ if ( t >= 0 ) { // draw tab text
+ if ( dis && !act ) {
+ p->setPen( g.light() );
+ p->drawText( x+w-tab-windowsRightBorder-motifItemHMargin-motifItemFrame+1,
+ y+m+1, tab, h-2*m, text_flags, s.mid( t+1 ));
+ p->setPen( discol );
+ }
+ p->drawText( x+w-tab-windowsRightBorder-motifItemHMargin-motifItemFrame,
+ y+m, tab, h-2*m, text_flags, s.mid( t+1 ) );
+ s = s.left( t );
+ }
+ if ( dis && !act ) {
+ p->setPen( g.light() );
+ p->drawText( x+xm+1, y+m+1, w-xm+1, h-2*m, text_flags, s, t );
+ p->setPen( discol );
+ }
+ p->drawText( x+xm, y+m, w-xm-tab+1, h-2*m, text_flags, s, t );
+ } else if ( mi->pixmap() ) { // draw pixmap
+ TQPixmap *pixmap = mi->pixmap();
+ if ( pixmap->depth() == 1 )
+ p->setBackgroundMode( OpaqueMode );
+ p->drawPixmap( x+xm, y+motifItemFrame, *pixmap );
+ if ( pixmap->depth() == 1 )
+ p->setBackgroundMode( TransparentMode );
+ }
+ if ( mi->popup() ) { // draw sub menu arrow
+ int dim = (h-2*motifItemFrame) / 2;
+ if ( act ) {
+ if ( !dis )
+ discol = white;
+ TQColorGroup g2( discol, g.highlight(),
+ white, white,
+ dis ? discol : white,
+ discol, white );
+ drawPrimitive(PE_ArrowRight, p, TQRect(x+w - motifArrowHMargin - motifItemFrame - dim, y + h / 2 - dim / 2, dim, dim),
+ g2, Style_Enabled);
+ } else {
+ drawPrimitive(PE_ArrowRight, p, TQRect(x+w - motifArrowHMargin - motifItemFrame - dim, y + h / 2 - dim / 2, dim, dim),
+ g, !dis ? Style_Enabled : Style_Default);
+ }
+ }
+ }
+ break;
+
+ default:
+ TQWindowsStyle::tqdrawControl( element, p, widget, r, g, flags, opt );
+ break;
+ }
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/styles/tqcompactstyle.h b/tqtinterface/qt4/src/styles/tqcompactstyle.h
new file mode 100644
index 0000000..24c7b3a
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqcompactstyle.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Definition of compact style class, good for small displays
+**
+** Created : 000623
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCOMPACTSTYLE_H
+#define TQCOMPACTSTYLE_H
+
+#ifndef TQT_H
+#include "tqwindowsstyle.h"
+#endif // TQT_H
+
+#if !defined(TQT_NO_STYLE_COMPACT) || defined(TQT_PLUGIN)
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_STYLE_COMPACT
+#else
+#define TQ_EXPORT_STYLE_COMPACT TQ_EXPORT
+#endif
+
+class TQ_EXPORT_STYLE_COMPACT TQCompactStyle : public TQWindowsStyle
+{
+public:
+ TQCompactStyle();
+
+ int tqpixelMetric( PixelMetric metric, const TQWidget *widget = 0 );
+
+ void tqdrawControl( ControlElement element, TQPainter *p, const TQWidget *w, const TQRect &r,
+ const TQColorGroup &cg, SFlags how = Style_Default, const TQStyleOption& = TQStyleOption::Default );
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQCompactStyle( const TQCompactStyle & );
+ TQCompactStyle& operator=( const TQCompactStyle & );
+#endif
+};
+
+#endif // TQT_NO_STYLE_WINDOWS
+
+#endif // TQCOMPACTSTYLE_H
diff --git a/tqtinterface/qt4/src/styles/tqinterlacestyle.cpp b/tqtinterface/qt4/src/styles/tqinterlacestyle.cpp
new file mode 100644
index 0000000..042f099
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqinterlacestyle.cpp
@@ -0,0 +1,805 @@
+/****************************************************************************
+**
+** Implementation of TQInterlaceStyle class
+**
+** Created : 010122
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#if 0 // ###### not ported to new API yet
+
+#include "tqinterlacestyle.h"
+
+#if !defined(TQT_NO_STYLE_INTERLACE) || defined(TQT_PLUGIN)
+
+#include "tqapplication.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h" // for now
+#include "tqpalette.h" // for now
+#include "tqwidget.h"
+#include "tqlabel.h"
+#include "tqpushbutton.h"
+#include "tqwidget.h"
+#include "tqrangecontrol.h"
+#include "tqscrollbar.h"
+#include "tqlistbox.h"
+
+#include <limits.h>
+
+/*!
+ \class TQInterlaceStyle tqinterlacestyle.h
+ \brief The TQInterlaceStyle class provides a Look and Feel suitable for interlaced displays.
+ \ingroup appearance
+
+ This class implements a look and feel that reduces flicker as much as
+ possible on interlaced displays (i.e. television). It is an experimental
+ style. In addition to using this style you will need to select a font
+ that does not flicker.
+*/
+
+/*!
+ Constructs a TQInterlaceStyle
+*/
+TQInterlaceStyle::TQInterlaceStyle() : TQMotifStyle()
+{
+ setUseHighlightColors( TRUE );
+}
+
+/*! \reimp
+*/
+int TQInterlaceStyle::buttonDefaultIndicatorWidth() const
+{
+ return 0;
+}
+
+/*! \reimp
+*/
+int TQInterlaceStyle::setSliderThickness() const
+{
+ return 18;
+}
+
+/*! \reimp
+*/
+TQSize TQInterlaceStyle::scrollBarExtent() const
+{
+ return TQSize( 18, 18 );
+}
+
+/*! \reimp
+*/
+int TQInterlaceStyle::defaultFrameWidth() const
+{
+ return 2;
+}
+
+/*!
+ \reimp
+ */
+void TQInterlaceStyle::polish( TQApplication *app)
+{
+ oldPalette = app->palette();
+#if 0
+ TQColor bg( 128, 64, 128 );
+ TQColor btn( 255, 145, 0 );
+ TQColor mid = bg.dark( 120 );
+ TQColor low = mid.dark( 120 );
+ TQColor fg( white );
+#else
+ TQColor bg( 224, 224, 224 );
+ TQColor btn = bg.dark( 105 );
+ TQColor mid = bg.dark( 120 );
+ TQColor low = mid.dark( 120 );
+ TQColor fg( black );
+#endif
+
+ TQColorGroup cg( fg, btn, low, low, mid, black, black, white, bg );
+ cg.setColor( TQColorGroup::Highlight, TQColor( 255, 255, 192 ) );
+ cg.setColor( TQColorGroup::HighlightedText, black );
+
+ TQColorGroup dcg( cg );
+ dcg.setColor( TQColorGroup::ButtonText, low );
+ dcg.setColor( TQColorGroup::Text, low );
+
+ app->setPalette( TQPalette( cg, dcg, cg ), TRUE );
+}
+
+/*!
+ \reimp
+ */
+void TQInterlaceStyle::unPolish( TQApplication *app)
+{
+ app->setPalette(oldPalette, TRUE);
+}
+
+/*!
+ \reimp
+ */
+void TQInterlaceStyle::polish( TQWidget* w)
+{
+
+ // the polish function sets some widgets to transtqparent mode and
+ // some to translate background mode in order to get the full
+ // benefit from the nice pixmaps in the color group.
+
+ if ( w->inherits("TQLCDNumber") ){
+ return;
+ }
+
+ if ( !w->isTopLevel() ) {
+ if ( w->inherits("TQGroupBox")
+ || w->inherits("TQTabWidget")
+ || w->inherits("TQPushButton") ) {
+ w->setAutoMask( TRUE );
+ return;
+ }
+ if (w->inherits("TQLabel")
+ || w->inherits("TQSlider")
+ || w->inherits("TQButton")
+ || w->inherits("TQProgressBar")
+ ){
+ w->setBackgroundOrigin( TQWidget::ParentOrigin );
+ }
+ }
+
+ if ( w->inherits( "TQFrame" ) ) {
+ TQFrame *f = (TQFrame *)w;
+ switch ( f->frameShape() ) {
+ case TQFrame::WinPanel:
+ f->setFrameShape( TQFrame::StyledPanel );
+
+ case TQFrame::Panel:
+ case TQFrame::Box:
+ case TQFrame::StyledPanel:
+ case TQFrame::PopupPanel:
+ if ( f->frameWidth() == 1 )
+ f->setLineWidth( 2 );
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ( w->inherits( "TQListBox" ) ) {
+ // the list box in combos has an ugly border otherwise
+ TQFrame *f = (TQFrame *)w;
+ if ( f->frameShadow() == TQFrame::Plain ) {
+ f->setFrameShadow( TQFrame::Raised );
+ f->setLineWidth( 1 );
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::unPolish( TQWidget* w)
+{
+
+ // the polish function sets some widgets to transtqparent mode and
+ // some to translate background mode in order to get the full
+ // benefit from the nice pixmaps in the color group.
+
+ if ( w->inherits("TQLCDNumber") ){
+ return;
+ }
+
+ if ( !w->isTopLevel() ) {
+ if ( w->inherits("TQGroupBox")
+ || w->inherits("TQTabWidget")
+ || w->inherits("TQPushButton" ) ) {
+ w->setAutoMask( FALSE );
+ return;
+ }
+ if (w->inherits("TQLabel")
+ || w->inherits("TQSlider")
+ || w->inherits("TQButton")
+ || w->inherits("TQProgressBar")
+ ){
+ w->setBackgroundOrigin( TQWidget::WidgetOrigin );
+ }
+ }
+
+}
+
+/*!
+ \reimp
+*/
+TQRect TQInterlaceStyle::pushButtonContentsRect( TQPushButton *btn )
+{
+ int fw = 0;
+ if ( btn->isDefault() || btn->autoDefault() )
+ fw = buttonDefaultIndicatorWidth();
+
+ return buttonRect( fw+5, fw, btn->width()-2*fw-10, btn->height()-2*fw );
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawFocusRect ( TQPainter *p, const TQRect &/*r*/, const TQColorGroup &g, const TQColor * bg, bool /*atBorder*/ )
+{
+ if (bg ) {
+ int h,s,v;
+ bg->hsv(&h,&s,&v);
+ if (v >= 128)
+ p->setPen( TQt::black );
+ else
+ p->setPen( TQt::white );
+ }
+ else
+ p->setPen( g.foreground() );
+/*
+ p->setBrush( NoBrush );
+ if ( atBorder ) {
+ p->drawRect( TQRect( r.x()+1, r.y()+2, r.width()-2, r.height()-4 ) );
+ p->drawRect( TQRect( r.x()+2, r.y()+1, r.width()-4, r.height()-2 ) );
+ } else {
+ p->drawRect( TQRect( r.x(), r.y()+1, r.width(), r.height()-2 ) );
+ p->drawRect( TQRect( r.x()+1, r.y(), r.width()-2, r.height() ) );
+ }
+*/
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawButton( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool /* sunken */,
+ const TQBrush *fill )
+{
+ const int lineWidth = 2;
+
+ p->setBrush( g.brush( TQColorGroup::Dark ) );
+ p->setPen( NoPen );
+ p->drawRect( x+1, y+1, 2, 2 );
+ p->drawRect( x+w-3, y+1, 2, 2 );
+ p->drawRect( x+1, y+h-3, 2, 2 );
+ p->drawRect( x+w-3, y+h-3, 2, 2 );
+
+ p->drawRect( x+2, y, w-4, 2 );
+ p->drawRect( x+2, y+h-lineWidth, w-4, lineWidth );
+ p->drawRect( x, y+2, lineWidth, h-4 );
+ p->drawRect( x+w-lineWidth, y+2, lineWidth, h-4 );
+
+ if ( fill ) {
+ x += 2;
+ y += 2;
+ w -= 4;
+ h -= 4;
+ p->setBrush( *fill );
+ p->setPen( NoPen );
+ p->drawRect( x+1, y, w-2, 1 );
+ p->drawRect( x, y+1, w, h-2 );
+ p->drawRect( x+1, y+h-1, w-2, 1 );
+ }
+}
+
+/*! \reimp */
+void TQInterlaceStyle::drawButtonMask( TQPainter * p, int x, int y, int w, int h )
+{
+ TQBrush fill( color1 );
+ TQColorGroup cg;
+ cg.setBrush( TQColorGroup::Dark, color1 );
+ drawButton( p, x, y, w, h, cg, FALSE, &fill );
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawBevelButton( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool sunken, const TQBrush* fill )
+{
+ TQInterlaceStyle::drawButton(p, x, y, w, h, g, sunken, fill);
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawPushButton( TQPushButton* btn, TQPainter *p)
+{
+ TQColorGroup g = btn->tqcolorGroup();
+ int x1, y1, x2, y2;
+
+ btn->rect().coords( &x1, &y1, &x2, &y2 ); // get coordinates
+
+ TQBrush fill( g.button() );
+ if ( btn->isDown() || btn->isOn() )
+ fill = g.mid();
+
+ if ( btn->hasFocus() )
+ g.setBrush( TQColorGroup::Dark, black );
+ drawButton( p, x1, y1, x2-x1+1, y2-y1+1, g, FALSE, &fill );
+
+ if ( btn->isMenuButton() ) {
+ int dx = (y1-y2-4)/3;
+ drawArrow( p, DownArrow, FALSE,
+ x2 - dx, dx, y1, y2 - y1,
+ g, btn->isEnabled() );
+ }
+
+ if ( p->brush().style() != NoBrush )
+ p->setBrush( NoBrush );
+}
+
+/*!
+ \reimp
+*/
+TQSize TQInterlaceStyle::indicatorSize () const
+{
+ return TQSize(13,13);
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawIndicator( TQPainter * p, int x, int y, int w, int h, const TQColorGroup &g, int s, bool down, bool enabled )
+{
+ p->fillRect( x, y, w, h, g.brush( TQColorGroup::Background ) );
+ TQBrush fill;
+ if ( s == TQButton::NoChange ) {
+ TQBrush b = p->brush();
+ TQColor c = p->backgroundColor();
+ p->setBackgroundMode( TransparentMode );
+ p->setBackgroundColor( green );
+ fill = TQBrush(g.base(), Dense4Pattern);
+ p->setBackgroundColor( c );
+ p->setBrush( b );
+ } else if ( down )
+ fill = g.brush( TQColorGroup::Button );
+ else
+ fill = g.brush( enabled ? TQColorGroup::Base : TQColorGroup::Background );
+
+ drawButton( p, x, y, w, h, g, FALSE, &fill );
+
+ if ( s != TQButton::Off ) {
+ TQPointArray a( 7*2 );
+ int i, xx, yy;
+ xx = x+3;
+ yy = y+5;
+ for ( i=0; i<3; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy++;
+ }
+ yy -= 2;
+ for ( i=3; i<7; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy--;
+ }
+ if ( s == TQButton::NoChange ) {
+ p->setPen( g.dark() );
+ } else {
+ p->setPen( g.text() );
+ }
+ p->drawLineSegments( a );
+ }
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawIndicatorMask( TQPainter *p, int x, int y, int w, int h, int )
+{
+ drawButtonMask( p, x, y, w, h );
+}
+
+/*!
+ \reimp
+*/
+TQSize TQInterlaceStyle::exclusiveIndicatorSize() const
+{
+ return TQSize(13,13);
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawExclusiveIndicator( TQPainter *p, int x, int y, int w, int h, const TQColorGroup &g, bool on, bool down, bool enabled )
+{
+ p->fillRect( x, y, w, h, g.brush( TQColorGroup::Background ) );
+ p->setBrush( g.dark() );
+ p->setPen( TQPen( NoPen ) );
+ p->drawEllipse( x, y, w, h );
+
+ x += 2;
+ y += 2;
+ w -= 4;
+ h -= 4;
+ TQColor fillColor = ( down || !enabled ) ? g.button() : g.base();
+ p->setBrush( fillColor );
+ p->drawEllipse( x, y, w, h );
+
+ if ( on ) {
+ p->setBrush( g.text() );
+ p->drawEllipse( x+2, y+2, w-4, h-4 );
+ }
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawExclusiveIndicatorMask( TQPainter *p, int x, int y, int w, int h, bool )
+{
+ p->setBrush( color1 );
+ p->setPen( TQPen( NoPen ) );
+ p->drawEllipse( x, y, w, h );
+}
+
+static int get_combo_extra_width( int h, int *return_awh=0 )
+{
+ int awh;
+ if ( h < 8 ) {
+ awh = 6;
+ } else if ( h < 14 ) {
+ awh = h - 2;
+ } else {
+ awh = h/2;
+ }
+ if ( return_awh )
+ *return_awh = awh;
+ return awh*3/2;
+}
+
+/*!
+ \reimp
+*/
+TQRect TQInterlaceStyle::comboButtonRect ( int x, int y, int w, int h )
+{
+ TQRect r = buttonRect( x, y, w, h );
+ int ew = get_combo_extra_width( r.height() );
+ return TQRect(r.x(), r.y(), r.width()-ew, r.height());
+}
+
+static void get_combo_parameters( const TQRect &r,
+ int &ew, int &awh, int &ax,
+ int &ay, int &sh, int &dh,
+ int &sy )
+{
+ ew = get_combo_extra_width( r.height(), &awh );
+
+ sh = (awh+3)/4;
+ if ( sh < 3 )
+ sh = 3;
+ dh = sh/2 + 1;
+
+ ay = r.y() + (r.height()-awh-sh-dh)/2;
+ if ( ay < 0 ) {
+ //panic mode
+ ay = 0;
+ sy = r.height();
+ } else {
+ sy = ay+awh+dh;
+ }
+ ax = r.x() + r.width() - ew +(ew-awh)/2;
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawComboButton( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g,
+ bool /* sunken */,
+ bool /*editable*/,
+ bool /*enabled */,
+ const TQBrush *fb )
+{
+ TQBrush fill = fb ? *fb : g.brush( TQColorGroup::Button );
+
+ int awh, ax, ay, sh, sy, dh, ew;
+ get_combo_parameters( buttonRect(x,y,w,h), ew, awh, ax, ay, sh, dh, sy );
+
+ drawButton( p, x, y, w, h, g, FALSE, &fill );
+
+ qDrawArrow( p, DownArrow, MotifStyle, FALSE, ax, ay, awh, awh, g, TRUE );
+
+ p->setPen( g.dark() );
+ p->drawRect( ax+1, sy+1, awh-1, sh-1 );
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawPushButtonLabel( TQPushButton* btn, TQPainter *p)
+{
+ TQRect r = btn->rect();
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+
+ int x1, y1, x2, y2;
+ btn->rect().coords( &x1, &y1, &x2, &y2 ); // get coordinates
+ int dx = 0;
+ int dy = 0;
+ if ( btn->isMenuButton() )
+ dx = (y2-y1) / 3;
+ if ( btn->isOn() || btn->isDown() ) {
+// dx--;
+// dy--;
+ }
+ if ( dx || dy )
+ p->translate( dx, dy );
+
+ x += 2; y += 2; w -= 4; h -= 4;
+ TQColorGroup g = btn->tqcolorGroup();
+ const TQColor *col = &btn->tqcolorGroup().buttonText();
+ if ( (btn->isDown() || btn->isOn()) )
+ col = &btn->tqcolorGroup().brightText();
+ else if ( !btn->isEnabled() )
+ col = &btn->tqcolorGroup().dark();
+ drawItem( p, x, y, w, h,
+ AlignCenter|ShowPrefix,
+ g, btn->isEnabled(),
+ btn->pixmap(), btn->text(), -1, col );
+
+ if ( dx || dy )
+ p->translate( -dx, -dy );
+}
+
+#define HORIZONTAL (sb->orientation() == TQScrollBar::Horizontal)
+#define VERTICAL !HORIZONTAL
+#define MOTIF_BORDER defaultFrameWidth()
+#define SLIDER_MIN 9 // ### motif says 6 but that's too small
+
+
+/*! \reimp */
+
+void TQInterlaceStyle::scrollBarMetrics( const TQScrollBar* sb, int &sliderMin, int &sliderMax, int &sliderLength, int &buttonDim )
+{
+ int maxLength;
+ int b = MOTIF_BORDER;
+ int length = HORIZONTAL ? sb->width() : sb->height();
+ int extent = HORIZONTAL ? sb->height() : sb->width();
+
+ if ( length > ( extent - b*2 - 1 )*2 + b*2 )
+ buttonDim = extent - b*2;
+ else
+ buttonDim = ( length - b*2 )/2 - 1;
+
+ sliderMin = b + buttonDim;
+ maxLength = length - b*2 - buttonDim*2;
+
+ if ( sb->maxValue() == sb->minValue() ) {
+ sliderLength = maxLength;
+ } else {
+ uint range = sb->maxValue()-sb->minValue();
+ sliderLength = (sb->pageStep()*maxLength)/
+ (range + sb->pageStep());
+ if ( sliderLength < SLIDER_MIN || range > INT_MAX/2 )
+ sliderLength = SLIDER_MIN;
+ if ( sliderLength > maxLength )
+ sliderLength = maxLength;
+ }
+ sliderMax = sliderMin + maxLength - sliderLength;
+
+}
+
+
+/*! \reimp */
+
+void TQInterlaceStyle::drawScrollBarControls( TQPainter* p, const TQScrollBar* sb,
+ int sliderStart, uint controls,
+ uint activeControl )
+{
+#define ADD_LINE_ACTIVE ( activeControl == AddLine )
+#define SUB_LINE_ACTIVE ( activeControl == SubLine )
+ TQColorGroup g = sb->tqcolorGroup();
+
+ int sliderMin, sliderMax, sliderLength, buttonDim;
+ scrollBarMetrics( sb, sliderMin, sliderMax, sliderLength, buttonDim );
+
+ TQBrush fill = g.brush( TQColorGroup::Mid );
+ if (sb->backgroundPixmap() ){
+ fill = TQBrush( g.mid(), *sb->backgroundPixmap() );
+ }
+
+ if ( controls == (AddLine | SubLine | AddPage | SubPage | Slider | First | Last ) )
+ drawPanel( p, 0, 0, sb->width(), sb->height(), g, FALSE, 2, &fill );
+
+ if (sliderStart > sliderMax) { // sanity check
+ sliderStart = sliderMax;
+ }
+
+ int b = MOTIF_BORDER;
+ int dimB = buttonDim;
+ TQRect addB;
+ TQRect subB;
+ TQRect addPageR;
+ TQRect subPageR;
+ TQRect sliderR;
+ int addX, addY, subX, subY;
+ int length = HORIZONTAL ? sb->width() : sb->height();
+ int extent = HORIZONTAL ? sb->height() : sb->width();
+
+ if ( HORIZONTAL ) {
+ subY = addY = ( extent - dimB ) / 2;
+ subX = b;
+ addX = length - dimB - b;
+ } else {
+ subX = addX = ( extent - dimB ) / 2;
+ subY = b;
+ addY = length - dimB - b;
+ }
+
+ subB.setRect( subX,subY,dimB,dimB );
+ addB.setRect( addX,addY,dimB,dimB );
+
+ int sliderEnd = sliderStart + sliderLength;
+ int sliderW = extent - b*2;
+ if ( HORIZONTAL ) {
+ subPageR.setRect( subB.right() + 1, b,
+ sliderStart - subB.right() , sliderW );
+ addPageR.setRect( sliderEnd-1, b, addX - sliderEnd+1, sliderW );
+ sliderR .setRect( sliderStart, b, sliderLength, sliderW );
+ } else {
+ subPageR.setRect( b, subB.bottom()+1, sliderW,
+ sliderStart - subB.bottom() );
+ addPageR.setRect( b, sliderEnd-1, sliderW, addY - sliderEnd + 1);
+ sliderR .setRect( b, sliderStart, sliderW, sliderLength );
+ }
+
+ if ( controls & AddLine )
+ drawArrow( p, VERTICAL ? DownArrow : RightArrow,
+ ADD_LINE_ACTIVE, addB.x(), addB.y(),
+ addB.width(), addB.height(), g, TRUE );
+ if ( controls & SubLine )
+ drawArrow( p, VERTICAL ? UpArrow : LeftArrow,
+ SUB_LINE_ACTIVE, subB.x(), subB.y(),
+ subB.width(), subB.height(), g, TRUE );
+
+ if ( controls & SubPage )
+ p->fillRect( subPageR, fill );
+
+ if ( controls & AddPage )
+ p->fillRect( addPageR, fill );
+
+ if ( controls & Slider ) {
+ TQPoint bo = p->brushOrigin();
+ p->setBrushOrigin(sliderR.topLeft());
+ if ( sliderR.isValid() )
+ drawButton( p, sliderR.x(), sliderR.y(),
+ sliderR.width(), sliderR.height(), g,
+ FALSE, &g.brush( TQColorGroup::Button ) );
+ p->setBrushOrigin(bo);
+ }
+
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawSlider ( TQPainter * p, int x, int y, int w, int h, const TQColorGroup & g, Orientation orient, bool, bool)
+{
+ p->fillRect( x, y, w, h, g.brush( TQColorGroup::Background ) );
+ drawButton( p, x, y, w, h, g, FALSE, &g.brush( TQColorGroup::Button ) );
+ if ( orient == Horizontal ) {
+ TQCOORD mid = x + w / 2;
+ qDrawShadeLine( p, mid, y , mid, y + h - 2, g, TRUE, 1);
+ } else {
+ TQCOORD mid = y +h / 2;
+ qDrawShadeLine( p, x, mid, x + w - 2, mid, g, TRUE, 1);
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawSliderGroove ( TQPainter * p, int x, int y, int w, int h, const TQColorGroup & g, TQCOORD , Orientation o)
+{
+ p->setBrush( g.brush( TQColorGroup::Dark ) );
+ p->setPen( NoPen );
+
+ if ( o == Horizontal )
+ drawButton( p, x, y+h/2-3, w, 6, g, FALSE, &g.brush( TQColorGroup::Mid ) );
+ else
+ drawButton( p, x+w/2-3, y, 6, h, g, FALSE, &g.brush( TQColorGroup::Mid ) );
+}
+
+
+/*!
+ \reimp
+*/
+int TQInterlaceStyle::splitterWidth() const
+{
+ return TQMAX( 12, TQApplication::globalStrut().width() );
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawSplitter( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, Orientation orient)
+{
+ const int motifOffset = 12;
+ int sw = splitterWidth();
+ if ( orient == Horizontal ) {
+ TQCOORD xPos = x + w/2;
+ TQCOORD kPos = motifOffset;
+ TQCOORD kSize = sw - 4;
+
+ qDrawShadeLine( p, xPos, kPos + kSize - 1 ,
+ xPos, h, g );
+ drawPanel( p, xPos-sw/2+2, kPos,
+ kSize, kSize, g, FALSE, 2,
+ &g.brush( TQColorGroup::Button ));
+ qDrawShadeLine( p, xPos, 0, xPos, kPos, g );
+ } else {
+ TQCOORD yPos = y + h/2;
+ TQCOORD kPos = w - motifOffset - sw;
+ TQCOORD kSize = sw - 4;
+
+ qDrawShadeLine( p, 0, yPos, kPos, yPos, g );
+ drawPanel( p, kPos, yPos-sw/2+2,
+ kSize, kSize, g, FALSE, 2,
+ &g.brush( TQColorGroup::Button ));
+ qDrawShadeLine( p, kPos + kSize -1, yPos,
+ w, yPos, g );
+ }
+
+}
+
+/*!
+ \reimp
+*/
+void TQInterlaceStyle::drawPanel( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool /*sunken*/,
+ int lineWidth, const TQBrush *fill )
+{
+ if ( lineWidth < 2 )
+ lineWidth = 2;
+
+ p->setBrush( g.brush( TQColorGroup::Dark ) );
+ p->setPen( NoPen );
+
+ p->drawRect( x, y, w, lineWidth );
+ p->drawRect( x, y+h-lineWidth, w, lineWidth );
+ p->drawRect( x, y, lineWidth, h );
+ p->drawRect( x+w-lineWidth, y, lineWidth, h );
+
+ if ( fill ) {
+ x += lineWidth;
+ y += lineWidth;
+ w -= 2*lineWidth;
+ h -= 2*lineWidth;
+ p->setBrush( *fill );
+ p->setPen( NoPen );
+ p->drawRect( x, y, w, h );
+ }
+}
+
+#endif // TQT_NO_STYLE_INTERLACE
+
+#endif
diff --git a/tqtinterface/qt4/src/styles/tqinterlacestyle.h b/tqtinterface/qt4/src/styles/tqinterlacestyle.h
new file mode 100644
index 0000000..a0e4af5
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqinterlacestyle.h
@@ -0,0 +1,107 @@
+/****************************************************************************
+**
+** Implementation of TQInterlaceStyle widget class
+**
+** Created : 010122
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#if 0 // ###### not ported to new API yet
+#ifndef TQINTERLACESTYLE_H
+#define TQINTERLACESTYLE_H
+
+#ifndef TQT_H
+#include "tqmotifstyle.h"
+#endif // TQT_H
+
+#if !defined(TQT_NO_STYLE_INTERLACE) || defined(TQT_PLUGIN)
+
+#include "tqpalette.h"
+
+class TQ_EXPORT TQInterlaceStyle : public TQMotifStyle
+{
+public:
+ TQInterlaceStyle();
+ void polish( TQApplication*);
+ void unPolish( TQApplication*);
+ void polish( TQWidget* );
+ void unPolish( TQWidget* );
+
+ int defaultFrameWidth() const;
+ TQRect pushButtonContentsRect( TQPushButton *btn );
+
+ void drawFocusRect ( TQPainter *, const TQRect &, const TQColorGroup &, const TQColor * bg = 0, bool = FALSE );
+ void drawButton( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool sunken = FALSE,
+ const TQBrush *fill = 0 );
+ void drawButtonMask ( TQPainter * p, int x, int y, int w, int h );
+ void drawBevelButton( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool sunken = FALSE,
+ const TQBrush *fill = 0 );
+
+ void drawPushButton( TQPushButton* btn, TQPainter *p);
+ TQSize indicatorSize () const;
+ void drawIndicator ( TQPainter * p, int x, int y, int w, int h, const TQColorGroup & g, int state, bool down = FALSE, bool enabled = TRUE );
+ void drawIndicatorMask( TQPainter *p, int x, int y, int w, int h, int );
+ TQSize exclusiveIndicatorSize () const;
+ void drawExclusiveIndicator( TQPainter * p, int x, int y, int w, int h, const TQColorGroup & g, bool on, bool down = FALSE, bool enabled = TRUE );
+ void drawExclusiveIndicatorMask( TQPainter * p, int x, int y, int w, int h, bool );
+ TQRect comboButtonRect ( int x, int y, int w, int h );
+ void drawComboButton( TQPainter *p, int x, int y, int w, int h, const TQColorGroup &g, bool sunken, bool editable, bool enabled, const TQBrush *fb );
+ void drawPushButtonLabel( TQPushButton* btn, TQPainter *p);
+ void drawPanel( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &, bool sunken,
+ int lineWidth, const TQBrush *fill );
+
+ void scrollBarMetrics( const TQScrollBar* sb, int &sliderMin, int &sliderMax, int &sliderLength, int &buttonDim );
+ void drawScrollBarControls( TQPainter* p, const TQScrollBar* sb, int sliderStart, uint controls, uint activeControl );
+ void drawSlider( TQPainter * p, int x, int y, int w, int h, const TQColorGroup & g, Orientation, bool tickAbove, bool tickBelow );
+ void drawSliderGroove( TQPainter * p, int x, int y, int w, int h, const TQColorGroup & g, TQCOORD c, Orientation );
+ int splitterWidth() const;
+ void drawSplitter( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, Orientation orient);
+
+ int buttonDefaultIndicatorWidth() const;
+ int setSliderThickness() const;
+ TQSize scrollBarExtent() const;
+
+private:
+ TQPalette oldPalette;
+};
+
+#endif // TQT_NO_STYLE_INTERLACE
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/styles/tqmotifplusstyle.cpp b/tqtinterface/qt4/src/styles/tqmotifplusstyle.cpp
new file mode 100644
index 0000000..bef75db
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqmotifplusstyle.cpp
@@ -0,0 +1,1586 @@
+/****************************************************************************
+**
+** Implementation of TQMotifPlusStyle class
+**
+** Created : 000727
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmotifplusstyle.h"
+
+#if !defined(TQT_NO_STYLE_MOTIFPLUS) || defined(TQT_PLUGIN)
+
+#include "tqmenubar.h"
+#include "tqapplication.h"
+#include "tqpainter.h"
+#include "tqpalette.h"
+#include "tqframe.h"
+#include "tqpushbutton.h"
+#include "tqcheckbox.h"
+#include "tqradiobutton.h"
+#include "tqcombobox.h"
+#include "tqlineedit.h"
+#include "tqspinbox.h"
+#include "tqslider.h"
+#include "tqdrawutil.h"
+#include "tqscrollbar.h"
+#include "tqtabbar.h"
+#include "tqtoolbar.h"
+#include "tqguardedptr.h"
+#include "tqlayout.h"
+
+
+struct TQMotifPlusStylePrivate
+{
+ TQMotifPlusStylePrivate()
+ : hoverWidget(0), hovering(FALSE), sliderActive(FALSE), mousePressed(FALSE),
+ scrollbarElement(0), lastElement(0), ref(1)
+ { ; }
+
+ TQGuardedPtr<TQWidget> hoverWidget;
+ bool hovering, sliderActive, mousePressed;
+ int scrollbarElement, lastElement, ref;
+ TQPoint mousePos;
+};
+
+static TQMotifPlusStylePrivate * singleton = 0;
+
+
+static void drawMotifPlusShade(TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &g,
+ bool sunken, bool mouseover,
+ const TQBrush *fill = 0)
+{
+ TQPen oldpen = p->pen();
+ TQPointArray a(4);
+ TQColor button =
+ mouseover ? g.midlight() : g.button();
+ TQBrush brush =
+ mouseover ? g.brush(TQColorGroup::Midlight) : g.brush(TQColorGroup::Button);
+ int x, y, w, h;
+
+ r.rect(&x, &y, &w, &h);
+
+ if (sunken) p->setPen(g.dark()); else p->setPen(g.light());
+ a.setPoint(0, x, y + h - 1);
+ a.setPoint(1, x, y);
+ a.setPoint(2, x, y);
+ a.setPoint(3, x + w - 1, y);
+ p->drawLineSegments(a);
+
+ if (sunken) p->setPen(TQt::black); else p->setPen(button);
+ a.setPoint(0, x + 1, y + h - 2);
+ a.setPoint(1, x + 1, y + 1);
+ a.setPoint(2, x + 1, y + 1);
+ a.setPoint(3, x + w - 2, y + 1);
+ p->drawLineSegments(a);
+
+ if (sunken) p->setPen(button); else p->setPen(g.dark());
+ a.setPoint(0, x + 2, y + h - 2);
+ a.setPoint(1, x + w - 2, y + h - 2);
+ a.setPoint(2, x + w - 2, y + h - 2);
+ a.setPoint(3, x + w - 2, y + 2);
+ p->drawLineSegments(a);
+
+ if (sunken) p->setPen(g.light()); else p->setPen(TQt::black);
+ a.setPoint(0, x + 1, y + h - 1);
+ a.setPoint(1, x + w - 1, y + h - 1);
+ a.setPoint(2, x + w - 1, y + h - 1);
+ a.setPoint(3, x + w - 1, y);
+ p->drawLineSegments(a);
+
+ if (fill)
+ p->fillRect(x + 2, y + 2, w - 4, h - 4, *fill);
+ else
+ p->fillRect(x + 2, y + 2, w - 4, h - 4, brush);
+
+ p->setPen(oldpen);
+}
+
+
+/*!
+ \class TQMotifPlusStyle tqmotifplusstyle.h
+ \brief The TQMotifPlusStyle class provides a more sophisticated Motif-ish look and feel.
+
+ \ingroup appearance
+
+ This class implements a Motif-ish look and feel with the more
+ sophisticated bevelling as used by the GIMP Toolkit (GTK+) for
+ Unix/X11.
+*/
+
+/*!
+ Constructs a TQMotifPlusStyle
+
+ If \a hoveringHighlight is TRUE (the default), then the style will
+ not highlight push buttons, checkboxes, radiobuttons, comboboxes,
+ scrollbars or sliders.
+*/
+TQMotifPlusStyle::TQMotifPlusStyle(bool hoveringHighlight) : TQMotifStyle(TRUE)
+{
+ if ( !singleton )
+ singleton = new TQMotifPlusStylePrivate;
+ else
+ singleton->ref++;
+
+ useHoveringHighlight = hoveringHighlight;
+}
+
+/*! \reimp */
+TQMotifPlusStyle::~TQMotifPlusStyle()
+{
+ if ( singleton && singleton->ref-- <= 0) {
+ delete singleton;
+ singleton = 0;
+ }
+}
+
+
+/*! \reimp */
+void TQMotifPlusStyle::polish(TQPalette &)
+{
+}
+
+
+/*! \reimp */
+void TQMotifPlusStyle::polish(TQWidget *widget)
+{
+#ifndef TQT_NO_FRAME
+ if (::tqqt_cast<TQFrame*>(widget) && ((TQFrame *) widget)->frameStyle() == TQFrame::Panel)
+ ((TQFrame *) widget)->setFrameStyle(TQFrame::WinPanel);
+#endif
+
+#ifndef TQT_NO_MENUBAR
+ if (::tqqt_cast<TQMenuBar*>(widget) && ((TQMenuBar *) widget)->frameStyle() != TQFrame::NoFrame)
+ ((TQMenuBar *) widget)->setFrameStyle(TQFrame::StyledPanel | TQFrame::Raised);
+#endif
+
+#ifndef TQT_NO_TOOLBAR
+ if (::tqqt_cast<TQToolBar*>(widget))
+ widget->tqlayout()->setMargin(2);
+#endif
+ if (useHoveringHighlight) {
+ if (::tqqt_cast<TQButton*>(widget) || ::tqqt_cast<TQComboBox*>(widget))
+ widget->installEventFilter(this);
+
+ if (::tqqt_cast<TQScrollBar*>(widget) || ::tqqt_cast<TQSlider*>(widget)) {
+ widget->setMouseTracking(TRUE);
+ widget->installEventFilter(this);
+ }
+ }
+
+ TQMotifStyle::polish(widget);
+}
+
+
+/*! \reimp */
+void TQMotifPlusStyle::unPolish(TQWidget *widget)
+{
+ widget->removeEventFilter(this);
+ TQMotifStyle::unPolish(widget);
+}
+
+
+/*! \reimp */
+void TQMotifPlusStyle::polish(TQApplication *)
+{
+}
+
+
+/*! \reimp */
+void TQMotifPlusStyle::unPolish(TQApplication *)
+{
+}
+
+
+/*! \reimp */
+int TQMotifPlusStyle::tqpixelMetric(PixelMetric metric, const TQWidget *widget) const
+{
+ int ret;
+
+ switch (metric) {
+ case PM_ScrollBarExtent:
+ ret = 15;
+ break;
+
+ case PM_ButtonDefaultIndicator:
+ ret = 5;
+ break;
+
+ case PM_ButtonMargin:
+ ret = 4;
+ break;
+
+ case PM_SliderThickness:
+ ret = 15;
+ break;
+
+ case PM_IndicatorWidth:
+ case PM_IndicatorHeight:
+ ret = 10;
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ ret = 11;
+ break;
+
+ default:
+ ret = TQMotifStyle::tqpixelMetric(metric, widget);
+ break;
+ }
+
+ return ret;
+}
+
+
+/*! \reimp */
+void TQMotifPlusStyle::tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ switch (pe) {
+#ifndef USE_QT4
+ case PE_HeaderSection:
+#endif // USE_QT4
+
+ case PE_ButtonCommand:
+ case PE_ButtonBevel:
+ case PE_ButtonTool:
+ if (flags & (Style_Down | Style_On | Style_Raised | Style_Sunken))
+ drawMotifPlusShade( p, r, cg, bool(flags & (Style_Down | Style_On)),
+ bool(flags & Style_MouseOver));
+ else if (flags & Style_MouseOver)
+ p->fillRect(r, cg.brush(TQColorGroup::Midlight));
+ else
+ p->fillRect(r, cg.brush(TQColorGroup::Button));
+ break;
+
+ case PE_Panel:
+ case PE_PanelPopup:
+ case PE_PanelMenuBar:
+ case PE_PanelDockWindow:
+ if ( opt.lineWidth() )
+ drawMotifPlusShade( p, r, cg, (flags & Style_Sunken), (flags & Style_MouseOver));
+ else if ( flags & Style_MouseOver )
+ p->fillRect(r, cg.brush(TQColorGroup::Midlight));
+ else
+ p->fillRect(r, cg.brush(TQColorGroup::Button));
+ break;
+
+ case PE_SpinWidgetUp:
+ tqdrawPrimitive(PE_ArrowUp, p, r, cg, flags, opt);
+ break;
+
+ case PE_SpinWidgetDown:
+ tqdrawPrimitive(PE_ArrowDown, p, r, cg, flags, opt);
+ break;
+
+ case PE_Indicator:
+ {
+ TQBrush fill;
+ if (flags & Style_On)
+ fill = cg.brush(TQColorGroup::Mid);
+ else if (flags & Style_MouseOver)
+ fill = cg.brush(TQColorGroup::Midlight);
+ else
+ fill = cg.brush(TQColorGroup::Button);
+
+ if (flags & Style_NoChange) {
+ qDrawPlainRect(p, r, cg.text(), 1, &fill);
+ p->drawLine(r.topRight(), r.bottomLeft());
+ } else
+ drawMotifPlusShade(p, r, cg, (flags & Style_On),
+ (flags & Style_MouseOver), &fill);
+ break;
+ }
+
+ case PE_ExclusiveIndicator:
+ {
+ TQPen oldpen = p->pen();
+ TQPointArray thick(8);
+ TQPointArray thin(4);
+ TQColor button = ((flags & Style_MouseOver) ? cg.midlight() : cg.button());
+ TQBrush brush = ((flags & Style_MouseOver) ?
+ cg.brush(TQColorGroup::Midlight) :
+ cg.brush(TQColorGroup::Button));
+ int x, y, w, h;
+ r.rect(&x, &y, &w, &h);
+
+ p->fillRect(x, y, w, h, brush);
+
+
+ if (flags & Style_On) {
+ thick.setPoint(0, x, y + (h / 2));
+ thick.setPoint(1, x + (w / 2), y);
+ thick.setPoint(2, x + 1, y + (h / 2));
+ thick.setPoint(3, x + (w / 2), y + 1);
+ thick.setPoint(4, x + (w / 2), y);
+ thick.setPoint(5, x + w - 1, y + (h / 2));
+ thick.setPoint(6, x + (w / 2), y + 1);
+ thick.setPoint(7, x + w - 2, y + (h / 2));
+ p->setPen(cg.dark());
+ p->drawLineSegments(thick);
+
+ thick.setPoint(0, x + 1, y + (h / 2) + 1);
+ thick.setPoint(1, x + (w / 2), y + h - 1);
+ thick.setPoint(2, x + 2, y + (h / 2) + 1);
+ thick.setPoint(3, x + (w / 2), y + h - 2);
+ thick.setPoint(4, x + (w / 2), y + h - 1);
+ thick.setPoint(5, x + w - 2, y + (h / 2) + 1);
+ thick.setPoint(6, x + (w / 2), y + h - 2);
+ thick.setPoint(7, x + w - 3, y + (h / 2) + 1);
+ p->setPen(cg.light());
+ p->drawLineSegments(thick);
+
+ thin.setPoint(0, x + 2, y + (h / 2));
+ thin.setPoint(1, x + (w / 2), y + 2);
+ thin.setPoint(2, x + (w / 2), y + 2);
+ thin.setPoint(3, x + w - 3, y + (h / 2));
+ p->setPen(TQt::black);
+ p->drawLineSegments(thin);
+
+ thin.setPoint(0, x + 3, y + (h / 2) + 1);
+ thin.setPoint(1, x + (w / 2), y + h - 3);
+ thin.setPoint(2, x + (w / 2), y + h - 3);
+ thin.setPoint(3, x + w - 4, y + (h / 2) + 1);
+ p->setPen(cg.mid());
+ p->drawLineSegments(thin);
+ } else {
+ thick.setPoint(0, x, y + (h / 2));
+ thick.setPoint(1, x + (w / 2), y);
+ thick.setPoint(2, x + 1, y + (h / 2));
+ thick.setPoint(3, x + (w / 2), y + 1);
+ thick.setPoint(4, x + (w / 2), y);
+ thick.setPoint(5, x + w - 1, y + (h / 2));
+ thick.setPoint(6, x + (w / 2), y + 1);
+ thick.setPoint(7, x + w - 2, y + (h / 2));
+ p->setPen(cg.light());
+ p->drawLineSegments(thick);
+
+ thick.setPoint(0, x + 2, y + (h / 2) + 1);
+ thick.setPoint(1, x + (w / 2), y + h - 2);
+ thick.setPoint(2, x + 3, y + (h / 2) + 1);
+ thick.setPoint(3, x + (w / 2), y + h - 3);
+ thick.setPoint(4, x + (w / 2), y + h - 2);
+ thick.setPoint(5, x + w - 3, y + (h / 2) + 1);
+ thick.setPoint(6, x + (w / 2), y + h - 3);
+ thick.setPoint(7, x + w - 4, y + (h / 2) + 1);
+ p->setPen(cg.dark());
+ p->drawLineSegments(thick);
+
+ thin.setPoint(0, x + 2, y + (h / 2));
+ thin.setPoint(1, x + (w / 2), y + 2);
+ thin.setPoint(2, x + (w / 2), y + 2);
+ thin.setPoint(3, x + w - 3, y + (h / 2));
+ p->setPen(button);
+ p->drawLineSegments(thin);
+
+ thin.setPoint(0, x + 1, y + (h / 2) + 1);
+ thin.setPoint(1, x + (w / 2), y + h - 1);
+ thin.setPoint(2, x + (w / 2), y + h - 1);
+ thin.setPoint(3, x + w - 2, y + (h / 2) + 1);
+ p->setPen(TQt::black);
+ p->drawLineSegments(thin);
+ }
+
+ p->setPen(oldpen);
+ break;
+ }
+
+
+
+ case PE_ArrowDown:
+ case PE_ArrowLeft:
+ case PE_ArrowRight:
+ case PE_ArrowUp:
+ {
+ TQPen oldpen = p->pen();
+ TQBrush oldbrush = p->brush();
+ TQPointArray poly(3);
+ TQColor button = (flags & Style_MouseOver) ? cg.midlight() : cg.button();
+ bool down = (flags & Style_Down);
+ int x, y, w, h;
+ r.rect(&x, &y, &w, &h);
+
+ p->save();
+ p->setBrush(button);
+
+ switch (pe) {
+ case PE_ArrowUp:
+ {
+ poly.setPoint(0, x + (w / 2), y );
+ poly.setPoint(1, x, y + h - 1);
+ poly.setPoint(2, x + w - 1, y + h - 1);
+ p->drawPolygon(poly);
+
+ if (down)
+ p->setPen(button);
+ else
+ p->setPen(cg.dark());
+ p->drawLine(x + 1, y + h - 2, x + w - 2, y + h - 2);
+
+ if (down)
+ p->setPen(cg.light());
+ else
+ p->setPen(TQt::black);
+ p->drawLine(x, y + h - 1, x + w - 1, y + h - 1);
+
+ if (down)
+ p->setPen(button);
+ else
+ p->setPen(cg.dark());
+ p->drawLine(x + w - 2, y + h - 1, x + (w / 2), y + 1);
+
+ if (down)
+ p->setPen(cg.light());
+ else
+ p->setPen(TQt::black);
+ p->drawLine(x + w - 1, y + h - 1, x + (w / 2), y);
+
+ if (down)
+ p->setPen(TQt::black);
+ else
+ p->setPen(button);
+ p->drawLine(x + (w / 2), y + 1, x + 1, y + h - 1);
+
+ if (down)
+ p->setPen(cg.dark());
+ else
+ p->setPen(cg.light());
+ p->drawLine(x + (w / 2), y, x, y + h - 1);
+ break;
+ }
+
+ case PE_ArrowDown:
+ {
+ poly.setPoint(0, x + w - 1, y);
+ poly.setPoint(1, x, y);
+ poly.setPoint(2, x + (w / 2), y + h - 1);
+ p->drawPolygon(poly);
+
+ if (down)
+ p->setPen(TQt::black);
+ else
+ p->setPen(button);
+ p->drawLine(x + w - 2, y + 1, x + 1, y + 1);
+
+ if (down)
+ p->setPen(cg.dark());
+ else
+ p->setPen(cg.light());
+ p->drawLine(x + w - 1, y, x, y);
+
+ if (down)
+ p->setPen(TQt::black);
+ else
+ p->setPen(button);
+ p->drawLine(x + 1, y, x + (w / 2), y + h - 2);
+
+ if (down)
+ p->setPen(cg.dark());
+ else
+ p->setPen(cg.light());
+ p->drawLine(x, y, x + (w / 2), y + h - 1);
+
+ if (down)
+ p->setPen(button);
+ else
+ p->setPen(cg.dark());
+ p->drawLine(x + (w / 2), y + h - 2, x + w - 2, y);
+
+ if (down)
+ p->setPen(cg.light());
+ else
+ p->setPen(TQt::black);
+ p->drawLine(x + (w / 2), y + h - 1, x + w - 1, y);
+ break;
+ }
+
+ case PE_ArrowLeft:
+ {
+ poly.setPoint(0, x, y + (h / 2));
+ poly.setPoint(1, x + w - 1, y + h - 1);
+ poly.setPoint(2, x + w - 1, y);
+ p->drawPolygon(poly);
+
+ if (down)
+ p->setPen(button);
+ else
+ p->setPen(cg.dark());
+ p->drawLine(x + 1, y + (h / 2), x + w - 1, y + h - 1);
+
+ if (down)
+ p->setPen(cg.light());
+ else
+ p->setPen(TQt::black);
+ p->drawLine(x, y + (h / 2), x + w - 1, y + h - 1);
+
+ if (down)
+ p->setPen(button);
+ else
+ p->setPen(cg.dark());
+ p->drawLine(x + w - 2, y + h - 1, x + w - 2, y + 1);
+
+ if (down)
+ p->setPen(cg.light());
+ else
+ p->setPen(TQt::black);
+ p->drawLine(x + w - 1, y + h - 1, x + w - 1, y);
+
+ if (down)
+ p->setPen(TQt::black);
+ else
+ p->setPen(button);
+ p->drawLine(x + w - 1, y + 1, x + 1, y + (h / 2));
+
+ if (down)
+ p->setPen(cg.dark());
+ else
+ p->setPen(cg.light());
+ p->drawLine(x + w - 1, y, x, y + (h / 2));
+ break;
+ }
+
+ case PE_ArrowRight:
+ {
+ poly.setPoint(0, x + w - 1, y + (h / 2));
+ poly.setPoint(1, x, y);
+ poly.setPoint(2, x, y + h - 1);
+ p->drawPolygon(poly);
+
+ if (down)
+ p->setPen(TQt::black);
+ else
+ p->setPen(button);
+ p->drawLine( x + w - 1, y + (h / 2), x + 1, y + 1);
+
+ if (down)
+ p->setPen(cg.dark());
+ else
+ p->setPen(cg.light());
+ p->drawLine(x + w - 1, y + (h / 2), x, y);
+
+ if (down)
+ p->setPen(TQt::black);
+ else
+ p->setPen(button);
+ p->drawLine(x + 1, y + 1, x + 1, y + h - 2);
+
+ if (down)
+ p->setPen(cg.dark());
+ else
+ p->setPen(cg.light());
+ p->drawLine(x, y, x, y + h - 1);
+
+ if (down)
+ p->setPen(button);
+ else
+ p->setPen(cg.dark());
+ p->drawLine(x + 1, y + h - 2, x + w - 1, y + (h / 2));
+
+ if (down)
+ p->setPen(cg.light());
+ else
+ p->setPen(TQt::black);
+ p->drawLine(x, y + h - 1, x + w - 1, y + (h / 2));
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ p->restore();
+ p->setBrush(oldbrush);
+ p->setPen(oldpen);
+ break;
+ }
+
+ default:
+ TQMotifStyle::tqdrawPrimitive(pe, p, r, cg, flags, opt);
+ break;
+ }
+}
+
+
+/*! \reimp
+*/
+void TQMotifPlusStyle::tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ if (widget == singleton->hoverWidget)
+ flags |= Style_MouseOver;
+
+ switch (element) {
+ case CE_PushButton:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *button = (const TQPushButton *) widget;
+ TQRect br = r;
+ int dbi = tqpixelMetric(PM_ButtonDefaultIndicator, widget);
+
+ if (button->isDefault() || button->autoDefault()) {
+ if (button->isDefault())
+ drawMotifPlusShade(p, br, cg, TRUE, FALSE,
+ &TQT_TQBRUSH_OBJECT(cg.brush(TQColorGroup::Background)));
+
+ br.setCoords(br.left() + dbi,
+ br.top() + dbi,
+ br.right() - dbi,
+ br.bottom() - dbi);
+ }
+
+ if (flags & Style_HasFocus)
+ br.addCoords(1, 1, -1, -1);
+ p->save();
+ p->setBrushOrigin( -button->backgroundOffset().x(),
+ -button->backgroundOffset().y() );
+ tqdrawPrimitive(PE_ButtonCommand, p, br, cg, flags);
+ p->restore();
+#endif
+ break;
+ }
+
+ case CE_CheckBoxLabel:
+ {
+#ifndef TQT_NO_CHECKBOX
+ const TQCheckBox *checkbox = (const TQCheckBox *) widget;
+
+ if (flags & Style_MouseOver) {
+ TQRegion r(checkbox->rect());
+ r -= tqvisualRect(subRect(SR_CheckBoxIndicator, widget), widget);
+ p->setClipRegion(r);
+ p->fillRect(checkbox->rect(), cg.brush(TQColorGroup::Midlight));
+ p->setClipping(FALSE);
+ }
+
+ int tqalignment = TQApplication::reverseLayout() ? TQt::AlignRight : TQt::AlignLeft;
+ drawItem(p, r, tqalignment | TQt::AlignVCenter | TQt::ShowPrefix, cg,
+ flags & Style_Enabled, checkbox->pixmap(), checkbox->text());
+
+ if (checkbox->hasFocus()) {
+ TQRect fr = tqvisualRect(subRect(SR_CheckBoxFocusRect, widget), widget);
+ tqdrawPrimitive(PE_FocusRect, p, fr, cg, flags);
+ }
+#endif
+ break;
+ }
+
+ case CE_RadioButtonLabel:
+ {
+#ifndef TQT_NO_RADIOBUTTON
+ const TQRadioButton *radiobutton = (const TQRadioButton *) widget;
+
+ if (flags & Style_MouseOver) {
+ TQRegion r(radiobutton->rect());
+ r -= tqvisualRect(subRect(SR_RadioButtonIndicator, widget), widget);
+ p->setClipRegion(r);
+ p->fillRect(radiobutton->rect(), cg.brush(TQColorGroup::Midlight));
+ p->setClipping(FALSE);
+ }
+
+ int tqalignment = TQApplication::reverseLayout() ? TQt::AlignRight : TQt::AlignLeft;
+ drawItem(p, r, tqalignment | TQt::AlignVCenter | TQt::ShowPrefix, cg,
+ flags & Style_Enabled, radiobutton->pixmap(), radiobutton->text());
+
+ if (radiobutton->hasFocus()) {
+ TQRect fr = tqvisualRect(subRect(SR_RadioButtonFocusRect, widget), widget);
+ tqdrawPrimitive(PE_FocusRect, p, fr, cg, flags);
+ }
+#endif
+ break;
+ }
+
+ case CE_MenuBarItem:
+ {
+#ifndef TQT_NO_MENUDATA
+ if (opt.isDefault())
+ break;
+
+ TQMenuItem *mi = opt.menuItem();
+ if ((flags & Style_Enabled) && (flags & Style_Active))
+ drawMotifPlusShade(p, r, cg, FALSE, TRUE);
+ else
+ p->fillRect(r, cg.button());
+
+ drawItem(p, r, TQt::AlignCenter | TQt::ShowPrefix | TQt::DontClip | TQt::SingleLine,
+ cg, flags & Style_Enabled, mi->pixmap(), mi->text(), -1,
+ TQT_TQCOLOR_CONST(&cg.buttonText()));
+#endif
+ break;
+ }
+
+
+#ifndef TQT_NO_POPUPMENU
+ case CE_PopupMenuItem:
+ {
+ if (! widget || opt.isDefault())
+ break;
+
+ TQPopupMenu *popupmenu = (TQPopupMenu *) widget;
+ TQMenuItem *mi = opt.menuItem();
+ if ( !mi )
+ break;
+
+ int tab = opt.tabWidth();
+ int maxpmw = opt.maxIconWidth();
+ bool dis = ! (flags & Style_Enabled);
+ bool checkable = popupmenu->isCheckable();
+ bool act = flags & Style_Active;
+ int x, y, w, h;
+
+ r.rect(&x, &y, &w, &h);
+
+ if (checkable)
+ maxpmw = TQMAX(maxpmw, 15);
+
+ int checkcol = maxpmw;
+
+ if (mi && mi->isSeparator()) {
+ p->setPen( cg.dark() );
+ p->drawLine( x, y, x+w, y );
+ p->setPen( cg.light() );
+ p->drawLine( x, y+1, x+w, y+1 );
+ return;
+ }
+
+ if ( act && !dis )
+ drawMotifPlusShade(p, TQRect(x, y, w, h), cg, FALSE, TRUE);
+ else
+ p->fillRect(x, y, w, h, cg.brush( TQColorGroup::Button ));
+
+ if ( !mi )
+ return;
+
+ TQRect vrect = tqvisualRect( TQRect( x+2, y+2, checkcol, h-2 ), r );
+ if ( mi->isChecked() ) {
+ if ( mi->iconSet() ) {
+ qDrawShadePanel( p, vrect.x(), y+2, checkcol, h-2*2,
+ cg, TRUE, 1, &cg.brush( TQColorGroup::Midlight ) );
+ }
+ } else if ( !act ) {
+ p->fillRect(vrect,
+ cg.brush( TQColorGroup::Button ));
+ }
+
+ if ( mi->iconSet() ) { // draw iconset
+ TQIconSet::Mode mode = (!dis) ? TQIconSet::Normal : TQIconSet::Disabled;
+
+ if (act && !dis)
+ mode = TQIconSet::Active;
+
+ TQPixmap pixmap;
+ if ( checkable && mi->isChecked() )
+ pixmap = mi->iconSet()->pixmap( TQIconSet::Small, mode,
+ TQIconSet::On );
+ else
+ pixmap = mi->iconSet()->pixmap( TQIconSet::Small, mode );
+
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+
+ TQRect pmr( 0, 0, pixw, pixh );
+
+ pmr.moveCenter(vrect.center());
+
+ p->setPen( cg.text() );
+ p->drawPixmap( pmr.topLeft(), pixmap );
+
+ } else if (checkable) {
+ if (mi->isChecked()) {
+ SFlags cflags = Style_Default;
+ if (! dis)
+ cflags |= Style_Enabled;
+ if (act)
+ cflags |= Style_On;
+
+ tqdrawPrimitive(PE_CheckMark, p, vrect, cg, cflags);
+ }
+ }
+
+ p->setPen( cg.buttonText() );
+
+ TQColor discol;
+ if (dis) {
+ discol = cg.text();
+ p->setPen( discol );
+ }
+
+ vrect = tqvisualRect( TQRect(x + checkcol + 4, y + 2,
+ w - checkcol - tab - 3, h - 4), r );
+ if (mi->custom()) {
+ p->save();
+ mi->custom()->paint(p, cg, act, !dis, vrect.x(), y + 2,
+ w - checkcol - tab - 3, h - 4);
+ p->restore();
+ }
+
+ TQString s = mi->text();
+ if ( !s.isNull() ) { // draw text
+ int t = s.tqfind( '\t' );
+ int m = 2;
+ int text_flags = TQt::AlignVCenter|TQt::ShowPrefix | TQt::DontClip | TQt::SingleLine;
+ text_flags |= (TQApplication::reverseLayout() ? TQt::AlignRight : TQt::AlignLeft );
+ if ( t >= 0 ) { // draw tab text
+ TQRect vr = tqvisualRect( TQRect(x+w-tab-2-2,
+ y+m, tab, h-2*m), r );
+ p->drawText( vr.x(),
+ y+m, tab, h-2*m, text_flags, s.mid( t+1 ) );
+ }
+ p->drawText(vrect.x(), y + 2, w - checkcol -tab - 3, h - 4,
+ text_flags, s, t);
+ } else if (mi->pixmap()) {
+ TQPixmap *pixmap = mi->pixmap();
+
+ if (pixmap->depth() == 1) p->setBackgroundMode(Qt::OpaqueMode);
+ TQRect vr = tqvisualRect( TQRect( x + checkcol + 2, y + 2, w - checkcol - 1, h - 4 ), r );
+ p->drawPixmap(vr.x(), y + 2, *pixmap);
+ if (pixmap->depth() == 1) p->setBackgroundMode(Qt::TransparentMode);
+ }
+
+ if (mi->popup()) {
+ int hh = h / 2;
+ TQStyle::PrimitiveElement arrow = (TQApplication::reverseLayout() ? PE_ArrowLeft : PE_ArrowRight);
+ vrect = tqvisualRect( TQRect(x + w - hh - 6, y + (hh / 2), hh, hh), r );
+ tqdrawPrimitive(arrow, p,
+ vrect, cg,
+ ((act && !dis) ?
+ Style_Down : Style_Default) |
+ ((!dis) ? Style_Enabled : Style_Default));
+ }
+ break;
+ }
+#endif // TQT_NO_POPUPMENU
+
+ case CE_TabBarTab:
+ {
+#ifndef TQT_NO_TABBAR
+ const TQTabBar *tabbar = (const TQTabBar *) widget;
+ bool selected = flags & Style_Selected;
+
+ TQColorGroup g = tabbar->tqcolorGroup();
+ TQPen oldpen = p->pen();
+ TQRect fr(r);
+
+ if (! selected) {
+ if (tabbar->tqshape() == TQTabBar::RoundedAbove ||
+ tabbar->tqshape() == TQTabBar::TriangularAbove) {
+ fr.setTop(fr.top() + 2);
+ } else {
+ fr.setBottom(fr.bottom() - 2);
+ }
+ }
+
+ fr.setWidth(fr.width() - 3);
+
+ p->fillRect(fr.left() + 1, fr.top() + 1, fr.width() - 2, fr.height() - 2,
+ (selected) ? cg.brush(TQColorGroup::Button)
+ : cg.brush(TQColorGroup::Mid));
+
+ if (tabbar->tqshape() == TQTabBar::RoundedAbove) {
+ // "rounded" tabs on top
+ fr.setBottom(fr.bottom() - 1);
+
+ p->setPen(g.light());
+ p->drawLine(fr.left(), fr.top() + 1,
+ fr.left(), fr.bottom() - 1);
+ p->drawLine(fr.left() + 1, fr.top(),
+ fr.right() - 1, fr.top());
+ if (! selected)
+ p->drawLine(fr.left(), fr.bottom(),
+ fr.right() + 3, fr.bottom());
+
+ if (fr.left() == 0)
+ p->drawLine(fr.left(), fr.bottom(),
+ fr.left(), fr.bottom() + 1);
+
+ p->setPen(g.dark());
+ p->drawLine(fr.right() - 1, fr.top() + 2,
+ fr.right() - 1, fr.bottom() - 1);
+
+ p->setPen(TQt::black);
+ p->drawLine(fr.right(), fr.top() + 1,
+ fr.right(), fr.bottom() - 1);
+ } else if (tabbar->tqshape() == TQTabBar::RoundedBelow) {
+ // "rounded" tabs on bottom
+ fr.setTop(fr.top() + 1);
+
+ p->setPen(g.dark());
+ p->drawLine(fr.right() + 3, fr.top() - 1,
+ fr.right() - 1, fr.top() - 1);
+ p->drawLine(fr.right() - 1, fr.top(),
+ fr.right() - 1, fr.bottom() - 2);
+ p->drawLine(fr.right() - 1, fr.bottom() - 2,
+ fr.left() + 2, fr.bottom() - 2);
+ if (! selected) {
+ p->drawLine(fr.right(), fr.top() - 1,
+ fr.left() + 1, fr.top() - 1);
+
+ if (fr.left() != 0)
+ p->drawPoint(fr.left(), fr.top() - 1);
+ }
+
+ p->setPen(TQt::black);
+ p->drawLine(fr.right(), fr.top(),
+ fr.right(), fr.bottom() - 2);
+ p->drawLine(fr.right() - 1, fr.bottom() - 1,
+ fr.left(), fr.bottom() - 1);
+ if (! selected)
+ p->drawLine(fr.right() + 3, fr.top(),
+ fr.left(), fr.top());
+ else
+ p->drawLine(fr.right() + 3, fr.top(),
+ fr.right(), fr.top());
+
+ p->setPen(g.light());
+ p->drawLine(fr.left(), fr.top() + 1,
+ fr.left(), fr.bottom() - 2);
+
+ if (selected) {
+ p->drawPoint(fr.left(), fr.top());
+ if (fr.left() == 0)
+ p->drawPoint(fr.left(), fr.top() - 1);
+
+ p->setPen(g.button());
+ p->drawLine(fr.left() + 2, fr.top() - 1,
+ fr.left() + 1, fr.top() - 1);
+ }
+ } else
+ // triangular drawing code
+ TQMotifStyle::tqdrawControl(element, p, widget, r, cg, flags, opt);
+
+ p->setPen(oldpen);
+#endif
+ break;
+ }
+
+ default:
+ TQMotifStyle::tqdrawControl(element, p, widget, r, cg, flags, opt);
+ break;
+ }
+}
+
+
+/*! \reimp
+*/
+TQRect TQMotifPlusStyle::subRect(SubRect r, const TQWidget *widget) const
+{
+ TQRect rect;
+
+ switch (r) {
+ case SR_PushButtonFocusRect:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *button = (const TQPushButton *) widget;
+ int dfi = tqpixelMetric(PM_ButtonDefaultIndicator, widget);
+
+ rect = button->rect();
+ if (button->isDefault() || button->autoDefault())
+ rect.addCoords(dfi, dfi, -dfi, -dfi);
+#endif
+ break;
+ }
+
+ case SR_CheckBoxIndicator:
+ {
+ int h = tqpixelMetric( PM_IndicatorHeight );
+ rect.setRect(( widget->rect().height() - h ) / 2,
+ ( widget->rect().height() - h ) / 2,
+ tqpixelMetric( PM_IndicatorWidth ), h );
+ break;
+ }
+
+ case SR_RadioButtonIndicator:
+ {
+ int h = tqpixelMetric( PM_ExclusiveIndicatorHeight );
+ rect.setRect( ( widget->rect().height() - h ) / 2,
+ ( widget->rect().height() - h ) / 2,
+ tqpixelMetric( PM_ExclusiveIndicatorWidth ), h );
+ break;
+ }
+
+ case SR_CheckBoxFocusRect:
+ case SR_RadioButtonFocusRect:
+ rect = widget->rect();
+ break;
+
+ case SR_ComboBoxFocusRect:
+ {
+#ifndef TQT_NO_COMBOBOX
+ const TQComboBox *combobox = (const TQComboBox *) widget;
+
+ if (combobox->editable()) {
+ rect = querySubControlMetrics(CC_ComboBox, widget,
+ SC_ComboBoxEditField);
+ rect.addCoords(-3, -3, 3, 3);
+ } else
+ rect = combobox->rect();
+#endif
+ break;
+ }
+
+ case SR_SliderFocusRect:
+ {
+#ifndef TQT_NO_SLIDER
+ const TQSlider *slider = (const TQSlider *) widget;
+ int tickOffset = tqpixelMetric( PM_SliderTickmarkOffset, widget );
+ int thickness = tqpixelMetric( PM_SliderControlThickness, widget );
+ int x, y, wi, he;
+
+ if ( slider->orientation() == Qt::Horizontal ) {
+ x = 0;
+ y = tickOffset;
+ wi = slider->width();
+ he = thickness;
+ } else {
+ x = tickOffset;
+ y = 0;
+ wi = thickness;
+ he = slider->height();
+ }
+
+ rect.setRect(x, y, wi, he);
+#endif
+ break;
+ }
+
+ default:
+ rect = TQMotifStyle::subRect(r, widget);
+ break;
+ }
+
+ return rect;
+}
+
+
+/*! \reimp */
+void TQMotifPlusStyle::tqdrawComplexControl(TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ SCFlags controls,
+ SCFlags active,
+ const TQStyleOption& opt ) const
+{
+ if (widget == singleton->hoverWidget)
+ flags |= Style_MouseOver;
+
+ switch (control) {
+ case CC_ScrollBar:
+ {
+#ifndef TQT_NO_SCROLLBAR
+ const TQScrollBar *scrollbar = (const TQScrollBar *) widget;
+ TQRect addline, subline, addpage, subpage, slider, first, last;
+ bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue());
+
+ subline = querySubControlMetrics(control, widget, SC_ScrollBarSubLine, opt);
+ addline = querySubControlMetrics(control, widget, SC_ScrollBarAddLine, opt);
+ subpage = querySubControlMetrics(control, widget, SC_ScrollBarSubPage, opt);
+ addpage = querySubControlMetrics(control, widget, SC_ScrollBarAddPage, opt);
+ slider = querySubControlMetrics(control, widget, SC_ScrollBarSlider, opt);
+ first = querySubControlMetrics(control, widget, SC_ScrollBarFirst, opt);
+ last = querySubControlMetrics(control, widget, SC_ScrollBarLast, opt);
+
+ bool skipUpdate = FALSE;
+ if (singleton->hovering) {
+ if (addline.tqcontains(singleton->mousePos)) {
+ skipUpdate =
+ (singleton->scrollbarElement == SC_ScrollBarAddLine);
+ singleton->scrollbarElement = SC_ScrollBarAddLine;
+ } else if (subline.tqcontains(singleton->mousePos)) {
+ skipUpdate =
+ (singleton->scrollbarElement == SC_ScrollBarSubLine);
+ singleton->scrollbarElement = SC_ScrollBarSubLine;
+ } else if (slider.tqcontains(singleton->mousePos)) {
+ skipUpdate =
+ (singleton->scrollbarElement == SC_ScrollBarSlider);
+ singleton->scrollbarElement = SC_ScrollBarSlider;
+ } else {
+ skipUpdate =
+ (singleton->scrollbarElement == 0);
+ singleton->scrollbarElement = 0;
+ }
+ } else
+ singleton->scrollbarElement = 0;
+
+ if (skipUpdate && singleton->scrollbarElement == singleton->lastElement)
+ break;
+
+ singleton->lastElement = singleton->scrollbarElement;
+
+ if (controls == (SC_ScrollBarAddLine | SC_ScrollBarSubLine |
+ SC_ScrollBarAddPage | SC_ScrollBarSubPage |
+ SC_ScrollBarFirst | SC_ScrollBarLast | SC_ScrollBarSlider))
+ drawMotifPlusShade(p, widget->rect(), cg, TRUE, FALSE,
+ &TQT_TQBRUSH_OBJECT(cg.brush(TQColorGroup::Mid)));
+
+ if ((controls & SC_ScrollBarSubLine) && subline.isValid())
+ tqdrawPrimitive(PE_ScrollBarSubLine, p, subline, cg,
+ ((active == SC_ScrollBarSubLine ||
+ singleton->scrollbarElement == SC_ScrollBarSubLine) ?
+ Style_MouseOver: Style_Default) |
+ ((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarSubLine) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : Style_Default));
+ if ((controls & SC_ScrollBarAddLine) && addline.isValid())
+ tqdrawPrimitive(PE_ScrollBarAddLine, p, addline, cg,
+ ((active == SC_ScrollBarAddLine ||
+ singleton->scrollbarElement == SC_ScrollBarAddLine) ?
+ Style_MouseOver: Style_Default) |
+ ((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarAddLine) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : Style_Default));
+ if ((controls & SC_ScrollBarSubPage) && subpage.isValid())
+ tqdrawPrimitive(PE_ScrollBarSubPage, p, subpage, cg,
+ ((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarSubPage) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : Style_Default));
+ if ((controls & SC_ScrollBarAddPage) && addpage.isValid())
+ tqdrawPrimitive(PE_ScrollBarAddPage, p, addpage, cg,
+ ((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarAddPage) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : Style_Default));
+ if ((controls & SC_ScrollBarFirst) && first.isValid())
+ tqdrawPrimitive(PE_ScrollBarFirst, p, first, cg,
+ ((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarFirst) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : Style_Default));
+ if ((controls & SC_ScrollBarLast) && last.isValid())
+ tqdrawPrimitive(PE_ScrollBarLast, p, last, cg,
+ ((maxedOut) ? Style_Default : Style_Enabled) |
+ ((active == SC_ScrollBarLast) ?
+ Style_Down : Style_Default) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : Style_Default));
+ if ((controls & SC_ScrollBarSlider) && slider.isValid()) {
+ tqdrawPrimitive(PE_ScrollBarSlider, p, slider, cg,
+ ((active == SC_ScrollBarSlider ||
+ singleton->scrollbarElement == SC_ScrollBarSlider) ?
+ Style_MouseOver: Style_Default) |
+ ((maxedOut) ? Style_Default : Style_Enabled) |
+ ((scrollbar->orientation() == Qt::Horizontal) ?
+ Style_Horizontal : Style_Default));
+
+ // ### perhaps this should not be able to accept focus if maxedOut?
+ if (scrollbar->hasFocus()) {
+ TQRect fr(slider.x() + 2, slider.y() + 2,
+ slider.width() - 5, slider.height() - 5);
+ tqdrawPrimitive(PE_FocusRect, p, fr, cg, Style_Default);
+ }
+ }
+#endif
+ break;
+ }
+
+ case CC_ComboBox:
+ {
+#ifndef TQT_NO_COMBOBOX
+ const TQComboBox *combobox = (const TQComboBox *) widget;
+
+ TQRect editfield, arrow;
+ editfield =
+ tqvisualRect(querySubControlMetrics(CC_ComboBox,
+ combobox,
+ SC_ComboBoxEditField,
+ opt), widget);
+ arrow =
+ tqvisualRect(querySubControlMetrics(CC_ComboBox,
+ combobox,
+ SC_ComboBoxArrow,
+ opt), widget);
+
+ if (combobox->editable()) {
+ if (controls & SC_ComboBoxEditField && editfield.isValid()) {
+ editfield.addCoords(-3, -3, 3, 3);
+ if (combobox->hasFocus())
+ editfield.addCoords(1, 1, -1, -1);
+ drawMotifPlusShade(p, editfield, cg, TRUE, FALSE,
+ (widget->isEnabled() ?
+ &TQT_TQBRUSH_OBJECT(cg.brush(TQColorGroup::Base)) :
+ &TQT_TQBRUSH_OBJECT(cg.brush(TQColorGroup::Background))));
+ }
+
+ if (controls & SC_ComboBoxArrow && arrow.isValid()) {
+ drawMotifPlusShade(p, arrow, cg, (active == SC_ComboBoxArrow),
+ (flags & Style_MouseOver));
+
+ int space = (r.height() - 13) / 2;
+ arrow.addCoords(space, space, -space, -space);
+
+ if (active == SC_ComboBoxArrow)
+ flags |= Style_Sunken;
+ tqdrawPrimitive(PE_ArrowDown, p, arrow, cg, flags);
+ }
+ } else {
+ if (controls & SC_ComboBoxEditField && editfield.isValid()) {
+ editfield.addCoords(-3, -3, 3, 3);
+ if (combobox->hasFocus())
+ editfield.addCoords(1, 1, -1, -1);
+ drawMotifPlusShade(p, editfield, cg, FALSE,
+ (flags & Style_MouseOver));
+ }
+
+ if (controls & SC_ComboBoxArrow && arrow.isValid())
+ drawMotifPlusShade(p, arrow, cg, FALSE, (flags & Style_MouseOver));
+ }
+
+ if (combobox->hasFocus() ||
+ (combobox->editable() && combobox->lineEdit()->hasFocus())) {
+ TQRect fr = tqvisualRect(subRect(SR_ComboBoxFocusRect, widget), widget);
+ tqdrawPrimitive(PE_FocusRect, p, fr, cg, flags);
+ }
+#endif
+ break;
+ }
+
+ case CC_SpinWidget:
+ {
+#ifndef TQT_NO_SPINWIDGET
+ const TQSpinWidget * sw = (const TQSpinWidget *) widget;
+ SFlags flags = Style_Default;
+
+ if (controls & SC_SpinWidgetFrame)
+ drawMotifPlusShade(p, r, cg, TRUE, FALSE, &TQT_TQBRUSH_OBJECT(cg.brush(TQColorGroup::Base)));
+
+ if (controls & SC_SpinWidgetUp) {
+ flags = Style_Enabled;
+ if (active == SC_SpinWidgetUp )
+ flags |= Style_Down;
+
+ PrimitiveElement pe;
+ if ( sw->buttonSymbols() == TQSpinWidget::PlusMinus )
+ pe = PE_SpinWidgetPlus;
+ else
+ pe = PE_SpinWidgetUp;
+
+ TQRect re = sw->upRect();
+ TQColorGroup ucg = sw->isUpEnabled() ? cg : sw->tqpalette().disabled();
+ tqdrawPrimitive(pe, p, re, ucg, flags);
+ }
+
+ if (controls & SC_SpinWidgetDown) {
+ flags = Style_Enabled;
+ if (active == SC_SpinWidgetDown )
+ flags |= Style_Down;
+
+ PrimitiveElement pe;
+ if ( sw->buttonSymbols() == TQSpinWidget::PlusMinus )
+ pe = PE_SpinWidgetMinus;
+ else
+ pe = PE_SpinWidgetDown;
+
+ TQRect re = sw->downRect();
+ TQColorGroup dcg = sw->isDownEnabled() ? cg : sw->tqpalette().disabled();
+ tqdrawPrimitive(pe, p, re, dcg, flags);
+ }
+#endif
+ break;
+ }
+
+ case CC_Slider:
+ {
+#ifndef TQT_NO_SLIDER
+ const TQSlider *slider = (const TQSlider *) widget;
+ bool mouseover = (flags & Style_MouseOver);
+
+ TQRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove,
+ opt),
+ handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle,
+ opt);
+
+ if ((controls & SC_SliderGroove) && groove.isValid()) {
+ drawMotifPlusShade(p, groove, cg, TRUE, FALSE,
+ &TQT_TQBRUSH_OBJECT(cg.brush(TQColorGroup::Mid)));
+
+ if ( flags & Style_HasFocus ) {
+ TQRect fr = subRect( SR_SliderFocusRect, widget );
+ tqdrawPrimitive( PE_FocusRect, p, fr, cg, flags );
+ }
+ }
+
+ if ((controls & SC_SliderHandle) && handle.isValid()) {
+ if ((mouseover && handle.tqcontains(singleton->mousePos)) ||
+ singleton->sliderActive)
+ flags |= Style_MouseOver;
+ else
+ flags &= ~Style_MouseOver;
+ tqdrawPrimitive(PE_ButtonBevel, p, handle, cg, flags | Style_Raised);
+
+ if ( slider->orientation() == Qt::Horizontal ) {
+ TQCOORD mid = handle.x() + handle.width() / 2;
+ qDrawShadeLine( p, mid, handle.y() + 1, mid ,
+ handle.y() + handle.height() - 3,
+ cg, TRUE, 1);
+ } else {
+ TQCOORD mid = handle.y() + handle.height() / 2;
+ qDrawShadeLine( p, handle.x() + 1, mid,
+ handle.x() + handle.width() - 3, mid,
+ cg, TRUE, 1);
+ }
+ }
+
+ if (controls & SC_SliderTickmarks)
+ TQMotifStyle::tqdrawComplexControl(control, p, widget, r, cg, flags,
+ SC_SliderTickmarks, active, opt);
+#endif
+ break;
+ }
+
+ default:
+ TQMotifStyle::tqdrawComplexControl(control, p, widget, r, cg, flags,
+ controls, active, opt);
+ }
+}
+
+
+/*! \reimp
+*/
+TQRect TQMotifPlusStyle::querySubControlMetrics(TQ_ComplexControl control,
+ const TQWidget *widget,
+ SubControl subcontrol,
+ const TQStyleOption& opt) const
+{
+ switch (control) {
+ case CC_SpinWidget: {
+ int fw = tqpixelMetric( PM_SpinBoxFrameWidth, 0 );
+ TQSize bs;
+ bs.setHeight( (widget->height() + 1)/2 );
+ if ( bs.height() < 10 )
+ bs.setHeight( 10 );
+ bs.setWidth( bs.height() ); // 1.6 -approximate golden mean
+ bs = bs.expandedTo( TQApplication::globalStrut() );
+ int y = 0;
+ int x, lx, rx, h;
+ x = widget->width() - y - bs.width();
+ lx = fw;
+ rx = x - fw * 2;
+ h = bs.height() * 2;
+
+ switch ( subcontrol ) {
+ case SC_SpinWidgetUp:
+ return TQRect(x + 1, y, bs.width(), bs.height() - 1);
+ case SC_SpinWidgetDown:
+ return TQRect(x + 1, y + bs.height() + 1, bs.width(), bs.height());
+ case SC_SpinWidgetButtonField:
+ return TQRect(x, y, bs.width(), h - 2*fw);
+ case SC_SpinWidgetEditField:
+ return TQRect(lx, fw, rx, h - 2*fw);
+ case SC_SpinWidgetFrame:
+ return TQRect( 0, 0, widget->width() - bs.width(), h);
+ default:
+ break;
+ }
+ break; }
+
+#ifndef TQT_NO_COMBOBOX
+ case CC_ComboBox: {
+ const TQComboBox *combobox = (const TQComboBox *) widget;
+ if (combobox->editable()) {
+ int space = (combobox->height() - 13) / 2;
+ switch (subcontrol) {
+ case SC_ComboBoxFrame:
+ return TQRect();
+ case SC_ComboBoxEditField: {
+ TQRect rect = widget->rect();
+ rect.setWidth(rect.width() - 13 - space * 2);
+ rect.addCoords(3, 3, -3, -3);
+ return rect; }
+ case SC_ComboBoxArrow:
+ return TQRect(combobox->width() - 13 - space * 2, 0,
+ 13 + space * 2, combobox->height());
+ default: break; // shouldn't get here
+ }
+
+ } else {
+ int space = (combobox->height() - 7) / 2;
+ switch (subcontrol) {
+ case SC_ComboBoxFrame:
+ return TQRect();
+ case SC_ComboBoxEditField: {
+ TQRect rect = widget->rect();
+ rect.addCoords(3, 3, -3, -3);
+ return rect; }
+ case SC_ComboBoxArrow: // 12 wide, 7 tall
+ return TQRect(combobox->width() - 12 - space, space, 12, 7);
+ default: break; // shouldn't get here
+ }
+ }
+ break; }
+#endif
+
+#ifndef TQT_NO_SLIDER
+ case CC_Slider: {
+
+ if (subcontrol == SC_SliderHandle) {
+ const TQSlider *slider = (const TQSlider *) widget;
+ int tickOffset = tqpixelMetric( PM_SliderTickmarkOffset, widget );
+ int thickness = tqpixelMetric( PM_SliderControlThickness, widget );
+ int len = tqpixelMetric( PM_SliderLength, widget ) + 2;
+ int sliderPos = slider->sliderStart();
+ int motifBorder = 2;
+
+ if ( slider->orientation() == Qt::Horizontal )
+ return TQRect( sliderPos + motifBorder, tickOffset + motifBorder, len,
+ thickness - 2*motifBorder );
+ return TQRect( tickOffset + motifBorder, sliderPos + motifBorder,
+ thickness - 2*motifBorder, len);
+ }
+ break; }
+#endif
+ default: break;
+ }
+ return TQMotifStyle::querySubControlMetrics(control, widget, subcontrol, opt);
+}
+
+
+/*! \reimp */
+bool TQMotifPlusStyle::eventFilter(TQObject *object, TQEvent *event)
+{
+ switch(event->type()) {
+ case TQEvent::MouseButtonPress:
+ {
+ singleton->mousePressed = TRUE;
+
+ if (!::tqqt_cast<TQSlider*>(object))
+ break;
+
+ singleton->sliderActive = TRUE;
+ break;
+ }
+
+ case TQEvent::MouseButtonRelease:
+ {
+ singleton->mousePressed = FALSE;
+
+ if (!::tqqt_cast<TQSlider*>(object))
+ break;
+
+ singleton->sliderActive = FALSE;
+ ((TQWidget *) object)->tqrepaint(FALSE);
+ break;
+ }
+
+ case TQEvent::Enter:
+ {
+ if (! object->isWidgetType())
+ break;
+
+ singleton->hoverWidget = (TQWidget *) object;
+ if (! singleton->hoverWidget->isEnabled()) {
+ singleton->hoverWidget = 0;
+ break;
+ }
+ singleton->hoverWidget->tqrepaint(FALSE);
+ break;
+ }
+
+ case TQEvent::Leave:
+ {
+ if (object != TQT_TQOBJECT(singleton->hoverWidget))
+ break;
+ TQWidget *w = singleton->hoverWidget;
+ singleton->hoverWidget = 0;
+ w->tqrepaint(FALSE);
+ break;
+ }
+
+ case TQEvent::MouseMove:
+ {
+ if (! object->isWidgetType() || object != TQT_TQOBJECT(singleton->hoverWidget))
+ break;
+
+ if (!::tqqt_cast<TQScrollBar*>(object) && ! ::tqqt_cast<TQSlider*>(object))
+ break;
+
+ singleton->mousePos = ((TQMouseEvent *) event)->pos();
+ if (! singleton->mousePressed) {
+ singleton->hovering = TRUE;
+ singleton->hoverWidget->tqrepaint(FALSE);
+ singleton->hovering = FALSE;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return TQMotifStyle::eventFilter(object, event);
+}
+
+
+/*! \reimp */
+int TQMotifPlusStyle::tqstyleHint(TQ_StyleHint hint,
+ const TQWidget *widget,
+ const TQStyleOption &opt,
+ TQStyleHintReturn *returnData) const
+{
+ int ret;
+ switch (hint) {
+ case SH_PopupMenu_MouseTracking:
+ ret = 1;
+ break;
+ default:
+ ret = TQMotifStyle::tqstyleHint(hint, widget, opt, returnData);
+ break;
+ }
+ return ret;
+}
+
+
+#endif // TQT_NO_STYLE_MOTIFPLUS
diff --git a/tqtinterface/qt4/src/styles/tqmotifplusstyle.h b/tqtinterface/qt4/src/styles/tqmotifplusstyle.h
new file mode 100644
index 0000000..0336f60
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqmotifplusstyle.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Definition of TQMotifPlusStyle class
+**
+** Created : 000727
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMOTIFPLUSSTYLE_H
+#define TQMOTIFPLUSSTYLE_H
+
+
+#ifndef TQT_H
+#include "tqmotifstyle.h"
+#endif // TQT_H
+
+#if !defined(TQT_NO_STYLE_MOTIFPLUS) || defined(TQT_PLUGIN)
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_STYLE_MOTIFPLUS
+#else
+#define TQ_EXPORT_STYLE_MOTIFPLUS TQ_EXPORT
+#endif
+
+class TQ_EXPORT_STYLE_MOTIFPLUS TQMotifPlusStyle : public TQMotifStyle
+{
+ TQ_OBJECT
+
+public:
+ TQMotifPlusStyle(bool hoveringHighlight = TRUE);
+ virtual ~TQMotifPlusStyle();
+
+ void polish(TQPalette &pal);
+ void polish(TQWidget *widget);
+ void unPolish(TQWidget*widget);
+
+ void polish(TQApplication *app);
+ void unPolish(TQApplication *app);
+
+ void tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ TQRect subRect(SubRect r, const TQWidget *widget) const;
+
+ void tqdrawComplexControl(TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+#ifdef TQ_TQDOC
+ SCFlags controls = SC_All,
+#else
+ SCFlags controls = (uint)SC_All,
+#endif
+ SCFlags active = SC_None,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ TQRect querySubControlMetrics(TQ_ComplexControl control,
+ const TQWidget *widget,
+ SubControl subcontrol,
+ const TQStyleOption& = TQStyleOption::Default) const;
+
+ int tqpixelMetric(PixelMetric metric, const TQWidget *widget = 0) const;
+
+ int tqstyleHint(TQ_StyleHint sh, const TQWidget *, const TQStyleOption & = TQStyleOption::Default,
+ TQStyleHintReturn* = 0) const;
+
+protected:
+ bool eventFilter(TQObject *, TQEvent *);
+
+
+private:
+ bool useHoveringHighlight;
+};
+
+
+#endif // TQT_NO_STYLE_MOTIFPLUS
+
+#endif // TQMOTIFPLUSSTYLE_H
diff --git a/tqtinterface/qt4/src/styles/tqmotifstyle.cpp b/tqtinterface/qt4/src/styles/tqmotifstyle.cpp
new file mode 100644
index 0000000..257c0ad
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqmotifstyle.cpp
@@ -0,0 +1,2367 @@
+/****************************************************************************
+**
+** Implementation of Motif-like style class
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmotifstyle.h"
+
+#if !defined(TQT_NO_STYLE_MOTIF) || defined(TQT_PLUGIN)
+
+#include "tqpopupmenu.h"
+#include "tqapplication.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqpixmap.h"
+#include "tqpalette.h"
+#include "tqwidget.h"
+#include "tqpushbutton.h"
+#include "tqscrollbar.h"
+#include "tqtabbar.h"
+#include "tqtabwidget.h"
+#include "tqlistview.h"
+#include "tqsplitter.h"
+#include "tqslider.h"
+#include "tqcombobox.h"
+#include "tqdockwindow.h"
+#include "tqdockarea.h"
+#include "tqprogressbar.h"
+#include "tqimage.h"
+#include <limits.h>
+
+
+
+// old constants that might still be useful...
+static const int motifItemFrame = 2; // menu item frame width
+static const int motifSepHeight = 2; // separator item height
+static const int motifItemHMargin = 3; // menu item hor text margin
+static const int motifItemVMargin = 2; // menu item ver text margin
+static const int motifArrowHMargin = 6; // arrow horizontal margin
+static const int motifTabSpacing = 12; // space between text and tab
+static const int motifCheckMarkHMargin = 2; // horiz. margins of check mark
+static const int motifCheckMarkSpace = 12;
+
+
+/*!
+ \class TQMotifStyle tqmotifstyle.h
+ \brief The TQMotifStyle class provides Motif look and feel.
+
+ \ingroup appearance
+
+ This class implements the Motif look and feel. It closely
+ resembles the original Motif look as defined by the Open Group,
+ but with some minor improvements. The Motif style is TQt's default
+ GUI style on UNIX platforms.
+*/
+
+/*!
+ Constructs a TQMotifStyle.
+
+ If \a useHighlightCols is FALSE (the default), the style will
+ polish the application's color palette to emulate the Motif way of
+ highlighting, which is a simple inversion between the base and the
+ text color.
+*/
+TQMotifStyle::TQMotifStyle( bool useHighlightCols ) : TQCommonStyle()
+{
+ highlightCols = useHighlightCols;
+}
+
+/*!\reimp
+*/
+TQMotifStyle::~TQMotifStyle()
+{
+}
+
+/*!
+ If \a arg is FALSE, the style will polish the application's color
+ palette to emulate the Motif way of highlighting, which is a
+ simple inversion between the base and the text color.
+
+ The effect will show up the next time an application palette is
+ set via TQApplication::setPalette(). The current color palette of
+ the application remains unchanged.
+
+ \sa TQStyle::polish()
+*/
+void TQMotifStyle::setUseHighlightColors( bool arg )
+{
+ highlightCols = arg;
+}
+
+/*!
+ Returns TRUE if the style treats the highlight colors of the
+ palette in a Motif-like manner, which is a simple inversion
+ between the base and the text color; otherwise returns FALSE. The
+ default is FALSE.
+*/
+bool TQMotifStyle::useHighlightColors() const
+{
+ return highlightCols;
+}
+
+/*! \reimp */
+
+void TQMotifStyle::polish( TQPalette& pal )
+{
+ if ( pal.active().light() == pal.active().base() ) {
+ TQColor nlight = pal.active().light().dark(108 );
+ pal.setColor( TQPalette::Active, TQColorGroup::Light, nlight ) ;
+ pal.setColor( TQPalette::Disabled, TQColorGroup::Light, nlight ) ;
+ pal.setColor( TQPalette::Inactive, TQColorGroup::Light, nlight ) ;
+ }
+
+ if ( highlightCols )
+ return;
+
+ // force the ugly motif way of highlighting *sigh*
+ TQColorGroup disabled = pal.disabled();
+ TQColorGroup active = pal.active();
+
+ pal.setColor( TQPalette::Active, TQColorGroup::Highlight,
+ active.text() );
+ pal.setColor( TQPalette::Active, TQColorGroup::HighlightedText,
+ active.base());
+ pal.setColor( TQPalette::Disabled, TQColorGroup::Highlight,
+ disabled.text() );
+ pal.setColor( TQPalette::Disabled, TQColorGroup::HighlightedText,
+ disabled.base() );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::Highlight,
+ active.text() );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::HighlightedText,
+ active.base() );
+}
+
+/*!
+ \reimp
+ \internal
+ Keep TQStyle::polish() visible.
+*/
+void TQMotifStyle::polish( TQWidget* w )
+{
+ TQStyle::polish(w);
+}
+
+/*!
+ \reimp
+ \internal
+ Keep TQStyle::polish() visible.
+*/
+void TQMotifStyle::polish( TQApplication* a )
+{
+ TQStyle::polish(a);
+}
+
+static void rot(TQPointArray& a, int n)
+{
+ TQPointArray r(a.size());
+ for (int i = 0; i < (int)a.size(); i++) {
+ switch (n) {
+ case 1: r.setPoint(i,-a[i].y(),a[i].x()); break;
+ case 2: r.setPoint(i,-a[i].x(),-a[i].y()); break;
+ case 3: r.setPoint(i,a[i].y(),-a[i].x()); break;
+ }
+ }
+ a = r;
+}
+
+
+/*!\reimp
+*/
+void TQMotifStyle::tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ switch( pe ) {
+#ifndef TQT_NO_LISTVIEW
+ case PE_CheckListExclusiveIndicator: {
+ TQCheckListItem *item = opt.checkListItem();
+ TQListView *lv = item->listView();
+ if(!item)
+ return;
+
+ if ( item->isEnabled() )
+ p->setPen( TQPen( cg.text() ) );
+ else
+ p->setPen( TQPen( lv->tqpalette().color( TQPalette::Disabled, TQColorGroup::Text ) ) );
+ TQPointArray a;
+
+ int cx = r.width()/2 - 1;
+ int cy = r.height()/2;
+ int e = r.width()/2 - 1;
+ for ( int i = 0; i < 3; i++ ) { //penWidth 2 doesn't quite work
+ a.setPoints( 4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e );
+ p->drawPolygon( a );
+ e--;
+ }
+ if ( item->isOn() ) {
+ if ( item->isEnabled() )
+ p->setPen( TQPen( cg.text()) );
+ else
+ p->setPen( TQPen( item->listView()->tqpalette().color( TQPalette::Disabled,
+ TQColorGroup::Text ) ) );
+ TQBrush saveBrush = p->brush();
+ p->setBrush( cg.text() );
+ e = e - 2;
+ a.setPoints( 4, cx-e, cy, cx, cy-e, cx+e, cy, cx, cy+e );
+ p->drawPolygon( a );
+ p->setBrush( saveBrush );
+ }
+ break; }
+#endif
+ case PE_ButtonCommand:
+ case PE_ButtonBevel:
+ case PE_ButtonTool:
+#ifndef USE_QT4 // [FIXME]
+ case PE_HeaderSection:
+#endif // USE_QT4
+ qDrawShadePanel( p, r, cg, bool(flags & (Style_Down | Style_On )),
+ tqpixelMetric(PM_DefaultFrameWidth),
+ &cg.brush(TQColorGroup::Button) );
+ break;
+
+ case PE_Indicator: {
+#ifndef TQT_NO_BUTTON
+ bool on = flags & Style_On;
+ bool down = flags & Style_Down;
+ bool showUp = !( down ^ on );
+ TQBrush fill = showUp || flags & Style_NoChange ? cg.brush( TQColorGroup::Button ) : cg.brush(TQColorGroup::Mid );
+ if ( flags & Style_NoChange ) {
+ qDrawPlainRect( p, r, cg.text(),
+ 1, &fill );
+ p->drawLine( r.x() + r.width() - 1, r.y(),
+ r.x(), r.y() + r.height() - 1);
+ } else
+ qDrawShadePanel( p, r, cg, !showUp,
+ tqpixelMetric(PM_DefaultFrameWidth), &fill );
+#endif
+ break;
+ }
+
+ case PE_ExclusiveIndicator:
+ {
+#define TQCOORDARRLEN(x) sizeof(x)/(sizeof(TQCOORD)*2)
+ TQCOORD inner_pts[] = { // used for filling diamond
+ 2,r.height()/2,
+ r.width()/2,2,
+ r.width()-3,r.height()/2,
+ r.width()/2,r.height()-3
+ };
+ TQCOORD top_pts[] = { // top (^) of diamond
+ 0,r.height()/2,
+ r.width()/2,0,
+ r.width()-2,r.height()/2-1,
+ r.width()-3,r.height()/2-1,
+ r.width()/2,1,
+ 1,r.height()/2,
+ 2,r.height()/2,
+ r.width()/2,2,
+ r.width()-4,r.height()/2-1
+ };
+ TQCOORD bottom_pts[] = { // bottom (v) of diamond
+ 1,r.height()/2+1,
+ r.width()/2,r.height()-1,
+ r.width()-1,r.height()/2,
+ r.width()-2,r.height()/2,
+ r.width()/2,r.height()-2,
+ 2,r.height()/2+1,
+ 3,r.height()/2+1,
+ r.width()/2,r.height()-3,
+ r.width()-3,r.height()/2
+ };
+ bool on = flags & Style_On;
+ bool down = flags & Style_Down;
+ bool showUp = !(down ^ on );
+ TQPointArray a( TQCOORDARRLEN(inner_pts), inner_pts );
+ p->eraseRect( r );
+ p->setPen( Qt::NoPen );
+ p->setBrush( showUp ? cg.brush( TQColorGroup::Button ) :
+ cg.brush( TQColorGroup::Mid ) );
+ a.translate( r.x(), r.y() );
+ p->drawPolygon( a );
+ p->setPen( showUp ? cg.light() : cg.dark() );
+ p->setBrush( Qt::NoBrush );
+ a.setPoints( TQCOORDARRLEN(top_pts), top_pts );
+ a.translate( r.x(), r.y() );
+ p->drawPolyline( a );
+ p->setPen( showUp ? cg.dark() : cg.light() );
+ a.setPoints( TQCOORDARRLEN(bottom_pts), bottom_pts );
+ a.translate( r.x(), r.y() );
+ p->drawPolyline( a );
+
+ break;
+ }
+
+ case PE_ExclusiveIndicatorMask:
+ {
+ static TQCOORD inner_pts[] = { // used for filling diamond
+ 0,r.height()/2,
+ r.width()/2,0,
+ r.width()-1,r.height()/2,
+ r.width()/2,r.height()-1
+ };
+ TQPointArray a(TQCOORDARRLEN(inner_pts), inner_pts);
+ p->setPen(Qt::color1);
+ p->setBrush(Qt::color1);
+ a.translate(r.x(), r.y());
+ p->drawPolygon(a);
+ break;
+ }
+
+ case PE_ArrowUp:
+ case PE_ArrowDown:
+ case PE_ArrowRight:
+ case PE_ArrowLeft:
+ {
+ TQRect rect = r;
+ TQPointArray bFill;
+ TQPointArray bTop;
+ TQPointArray bBot;
+ TQPointArray bLeft;
+ bool vertical = pe == PE_ArrowUp || pe == PE_ArrowDown;
+ bool horizontal = !vertical;
+ int dim = rect.width() < rect.height() ? rect.width() : rect.height();
+ int colspec = 0x0000;
+
+ if ( dim < 2 )
+ break;
+
+ // adjust size and center (to fix rotation below)
+ if ( rect.width() > dim ) {
+ rect.setX( rect.x() + ((rect.width() - dim ) / 2) );
+ rect.setWidth( dim );
+ }
+ if ( rect.height() > dim ) {
+ rect.setY( rect.y() + ((rect.height() - dim ) / 2 ));
+ rect.setHeight( dim );
+ }
+
+ if ( dim > 3 ) {
+ if ( dim > 6 )
+ bFill.resize( dim & 1 ? 3 : 4 );
+ bTop.resize( (dim/2)*2 );
+ bBot.resize( dim & 1 ? dim + 1 : dim );
+ bLeft.resize( dim > 4 ? 4 : 2 );
+ bLeft.putPoints( 0, 2, 0,0, 0,dim-1 );
+ if ( dim > 4 )
+ bLeft.putPoints( 2, 2, 1,2, 1,dim-3 );
+ bTop.putPoints( 0, 4, 1,0, 1,1, 2,1, 3,1 );
+ bBot.putPoints( 0, 4, 1,dim-1, 1,dim-2, 2,dim-2, 3,dim-2 );
+
+ for( int i=0; i<dim/2-2 ; i++ ) {
+ bTop.putPoints( i*2+4, 2, 2+i*2,2+i, 5+i*2, 2+i );
+ bBot.putPoints( i*2+4, 2, 2+i*2,dim-3-i, 5+i*2,dim-3-i );
+ }
+ if ( dim & 1 ) // odd number size: extra line
+ bBot.putPoints( dim-1, 2, dim-3,dim/2, dim-1,dim/2 );
+ if ( dim > 6 ) { // dim>6: must fill interior
+ bFill.putPoints( 0, 2, 1,dim-3, 1,2 );
+ if ( dim & 1 ) // if size is an odd number
+ bFill.setPoint( 2, dim - 3, dim / 2 );
+ else
+ bFill.putPoints( 2, 2, dim-4,dim/2-1, dim-4,dim/2 );
+ }
+ }
+ else {
+ if ( dim == 3 ) { // 3x3 arrow pattern
+ bLeft.setPoints( 4, 0,0, 0,2, 1,1, 1,1 );
+ bTop .setPoints( 2, 1,0, 1,0 );
+ bBot .setPoints( 2, 1,2, 2,1 );
+ }
+ else { // 2x2 arrow pattern
+ bLeft.setPoints( 2, 0,0, 0,1 );
+ bTop .setPoints( 2, 1,0, 1,0 );
+ bBot .setPoints( 2, 1,1, 1,1 );
+ }
+ }
+
+ // We use rot() and translate() as it is more efficient that
+ // matrix transformations on the painter, and because it still
+ // works with TQT_NO_TRANSFORMATIONS defined.
+
+ if ( pe == PE_ArrowUp || pe == PE_ArrowLeft ) {
+ if ( vertical ) {
+ rot(bFill,3);
+ rot(bLeft,3);
+ rot(bTop,3);
+ rot(bBot,3);
+ bFill.translate( 0, rect.height() - 1 );
+ bLeft.translate( 0, rect.height() - 1 );
+ bTop.translate( 0, rect.height() - 1 );
+ bBot.translate( 0, rect.height() - 1 );
+ } else {
+ rot(bFill,2);
+ rot(bLeft,2);
+ rot(bTop,2);
+ rot(bBot,2);
+ bFill.translate( rect.width() - 1, rect.height() - 1 );
+ bLeft.translate( rect.width() - 1, rect.height() - 1 );
+ bTop.translate( rect.width() - 1, rect.height() - 1 );
+ bBot.translate( rect.width() - 1, rect.height() - 1 );
+ }
+ if ( flags & Style_Down )
+ colspec = horizontal ? 0x2334 : 0x2343;
+ else
+ colspec = horizontal ? 0x1443 : 0x1434;
+ } else {
+ if ( vertical ) {
+ rot(bFill,1);
+ rot(bLeft,1);
+ rot(bTop,1);
+ rot(bBot,1);
+ bFill.translate( rect.width() - 1, 0 );
+ bLeft.translate( rect.width() - 1, 0 );
+ bTop.translate( rect.width() - 1, 0 );
+ bBot.translate( rect.width() - 1, 0 );
+ }
+ if ( flags & Style_Down )
+ colspec = horizontal ? 0x2443 : 0x2434;
+ else
+ colspec = horizontal ? 0x1334 : 0x1343;
+ }
+ bFill.translate( rect.x(), rect.y() );
+ bLeft.translate( rect.x(), rect.y() );
+ bTop.translate( rect.x(), rect.y() );
+ bBot.translate( rect.x(), rect.y() );
+
+ TQColor *cols[5];
+ if ( flags & Style_Enabled ) {
+ cols[0] = 0;
+ cols[1] = (TQColor *)&cg.button();
+ cols[2] = (TQColor *)&cg.mid();
+ cols[3] = (TQColor *)&cg.light();
+ cols[4] = (TQColor *)&cg.dark();
+ } else {
+ cols[0] = 0;
+ cols[1] = (TQColor *)&cg.button();
+ cols[2] = (TQColor *)&cg.button();
+ cols[3] = (TQColor *)&cg.button();
+ cols[4] = (TQColor *)&cg.button();
+ }
+
+#define CMID *cols[ (colspec>>12) & 0xf ]
+#define CLEFT *cols[ (colspec>>8) & 0xf ]
+#define CTOP *cols[ (colspec>>4) & 0xf ]
+#define CBOT *cols[ colspec & 0xf ]
+
+ TQPen savePen = p->pen();
+ TQBrush saveBrush = p->brush();
+ TQPen pen( Qt::NoPen );
+ TQBrush brush = cg.brush( flags & Style_Enabled ? TQColorGroup::Button :
+ TQColorGroup::Mid );
+ p->setPen( pen );
+ p->setBrush( brush );
+ p->drawPolygon( bFill );
+ p->setBrush( Qt::NoBrush );
+
+ p->setPen( CLEFT );
+ p->drawLineSegments( bLeft );
+ p->setPen( CTOP );
+ p->drawLineSegments( bTop );
+ p->setPen( CBOT );
+ p->drawLineSegments( bBot );
+
+ p->setBrush( saveBrush );
+ p->setPen( savePen );
+#undef CMID
+#undef CLEFT
+#undef CTOP
+#undef CBOT
+ break;
+ }
+
+ case PE_SpinWidgetPlus:
+ case PE_SpinWidgetMinus:
+ {
+ p->save();
+ int fw = tqpixelMetric( PM_DefaultFrameWidth );
+ TQRect br;
+ br.setRect( r.x() + fw, r.y() + fw, r.width() - fw*2,
+ r.height() - fw*2 );
+
+ if ( flags & Style_Sunken )
+ p->fillRect( r, cg.brush( TQColorGroup::Dark ) );
+ else
+ p->fillRect( r, cg.brush( TQColorGroup::Button ) );
+
+ p->setPen( cg.buttonText() );
+ p->setBrush( cg.buttonText() );
+
+ int length;
+ int x = r.x(), y = r.y(), w = r.width(), h = r.height();
+ if ( w <= 8 || h <= 6 )
+ length = TQMIN( w-2, h-2 );
+ else
+ length = TQMIN( 2*w / 3, 2*h / 3 );
+
+ if ( !(length & 1) )
+ length -=1;
+ int xmarg = ( w - length ) / 2;
+ int ymarg = ( h - length ) / 2;
+
+ p->drawLine( x + xmarg, ( y + h / 2 - 1 ),
+ x + xmarg + length - 1, ( y + h / 2 - 1 ) );
+ if ( pe == PE_SpinWidgetPlus )
+ p->drawLine( ( x+w / 2 ) - 1, y + ymarg,
+ ( x+w / 2 ) - 1, y + ymarg + length - 1 );
+ p->restore();
+ break;
+ }
+
+ case PE_SpinWidgetUp:
+ case PE_SpinWidgetDown:
+ {
+ p->save();
+ int fw = tqpixelMetric( PM_DefaultFrameWidth );
+ TQRect br;
+ br.setRect( r.x() + fw, r.y() + fw, r.width() - fw*2,
+ r.height() - fw*2 );
+ if ( flags & Style_Sunken )
+ p->fillRect( br, cg.brush( TQColorGroup::Mid ) );
+ else
+ p->fillRect( br, cg.brush( TQColorGroup::Button ) );
+
+ int x = r.x(), y = r.y(), w = r.width(), h = r.height();
+ int sw = w-4;
+ if ( sw < 3 )
+ return;
+ else if ( !(sw & 1) )
+ sw--;
+ sw -= ( sw / 7 ) * 2; // Empty border
+ int sh = sw/2 + 2; // Must have empty row at foot of arrow
+
+ int sx = x + w / 2 - sw / 2 - 1;
+ int sy = y + h / 2 - sh / 2 - 1;
+
+ TQPointArray a;
+ if ( pe == PE_SpinWidgetDown )
+ a.setPoints( 3, 0, 1, sw-1, 1, sh-2, sh-1 );
+ else
+ a.setPoints( 3, 0, sh-1, sw-1, sh-1, sh-2, 1 );
+ int bsx = 0;
+ int bsy = 0;
+ if ( flags & Style_Sunken ) {
+ bsx = tqpixelMetric(PM_ButtonShiftHorizontal);
+ bsy = tqpixelMetric(PM_ButtonShiftVertical);
+ }
+ p->translate( sx + bsx, sy + bsy );
+ p->setPen( cg.buttonText() );
+ p->setBrush( cg.buttonText() );
+ p->drawPolygon( a );
+ p->restore();
+ break;
+ }
+
+ case PE_DockWindowHandle:
+ {
+ p->save();
+ p->translate( r.x(), r.y() );
+
+ TQColor dark( cg.dark() );
+ TQColor light( cg.light() );
+ unsigned int i;
+ if ( flags & Style_Horizontal ) {
+ int h = r.height();
+ if ( h > 6 ) {
+ if ( flags & Style_On )
+ p->fillRect( 1, 1, 8, h - 2, cg.highlight() );
+ TQPointArray a( 2 * ((h-6)/3) );
+ int y = 3 + (h%3)/2;
+ p->setPen( dark );
+ p->drawLine( 8, 1, 8, h-2 );
+ for( i=0; 2*i < a.size(); i ++ ) {
+ a.setPoint( 2*i, 5, y+1+3*i );
+ a.setPoint( 2*i+1, 2, y+2+3*i );
+ }
+ p->drawPoints( a );
+ p->setPen( light );
+ p->drawLine( 9, 1, 9, h-2 );
+ for( i=0; 2*i < a.size(); i++ ) {
+ a.setPoint( 2*i, 4, y+3*i );
+ a.setPoint( 2*i+1, 1, y+1+3*i );
+ }
+ p->drawPoints( a );
+ // if ( drawBorder ) {
+ // p->setPen( TQPen( TQt::darkGray ) );
+ // p->drawLine( 0, r.height() - 1,
+ // tbExtent, r.height() - 1 );
+ // }
+ }
+ } else {
+ int w = r.width();
+ if ( w > 6 ) {
+ if ( flags & Style_On )
+ p->fillRect( 1, 1, w - 2, 9, cg.highlight() );
+ TQPointArray a( 2 * ((w-6)/3) );
+
+ int x = 3 + (w%3)/2;
+ p->setPen( dark );
+ p->drawLine( 1, 8, w-2, 8 );
+ for( i=0; 2*i < a.size(); i ++ ) {
+ a.setPoint( 2*i, x+1+3*i, 6 );
+ a.setPoint( 2*i+1, x+2+3*i, 3 );
+ }
+ p->drawPoints( a );
+ p->setPen( light );
+ p->drawLine( 1, 9, w-2, 9 );
+ for( i=0; 2*i < a.size(); i++ ) {
+ a.setPoint( 2*i, x+3*i, 5 );
+ a.setPoint( 2*i+1, x+1+3*i, 2 );
+ }
+ p->drawPoints( a );
+ // if ( drawBorder ) {
+ // p->setPen( TQPen( TQt::darkGray ) );
+ // p->drawLine( r.width() - 1, 0,
+ // r.width() - 1, tbExtent );
+ // }
+ }
+ }
+ p->restore();
+ break;
+ }
+
+ case PE_Splitter:
+ if (flags & Style_Horizontal)
+ flags &= ~Style_Horizontal;
+ else
+ flags |= Style_Horizontal;
+ // fall through intended
+
+#ifndef USE_QT4 // [FIXME]
+ case PE_DockWindowResizeHandle:
+#endif // USE_QT4
+ {
+ const int motifOffset = 10;
+ int sw = tqpixelMetric( PM_SplitterWidth );
+ if ( flags & Style_Horizontal ) {
+ TQCOORD yPos = r.y() + r.height() / 2;
+ TQCOORD kPos = r.width() - motifOffset - sw;
+ TQCOORD kSize = sw - 2;
+
+ qDrawShadeLine( p, 0, yPos, kPos, yPos, cg );
+ qDrawShadePanel( p, kPos, yPos - sw / 2 + 1, kSize, kSize,
+ cg, FALSE, 1, &cg.brush( TQColorGroup::Button ) );
+ qDrawShadeLine( p, kPos + kSize - 1, yPos, r.width(), yPos, cg );
+ } else {
+ TQCOORD xPos = r.x() + r.width() / 2;
+ TQCOORD kPos = motifOffset;
+ TQCOORD kSize = sw - 2;
+
+ qDrawShadeLine( p, xPos, kPos + kSize - 1, xPos, r.height(), cg );
+ qDrawShadePanel( p, xPos - sw / 2 + 1, kPos, kSize, kSize, cg,
+ FALSE, 1, &cg.brush( TQColorGroup::Button ) );
+ qDrawShadeLine( p, xPos, 0, xPos, kPos, cg );
+ }
+ break;
+ }
+
+#ifndef USE_QT4 // [FIXME]
+ case PE_CheckMark:
+ {
+ const int markW = 6;
+ const int markH = 6;
+ int posX = r.x() + ( r.width() - markW ) / 2 - 1;
+ int posY = r.y() + ( r.height() - markH ) / 2;
+ int dfw = tqpixelMetric(PM_DefaultFrameWidth);
+
+ if (dfw < 2) {
+ // Could do with some optimizing/caching...
+ TQPointArray a( 7*2 );
+ int i, xx, yy;
+ xx = posX;
+ yy = 3 + posY;
+ for ( i=0; i<3; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy++;
+ }
+ yy -= 2;
+ for ( i=3; i<7; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy--;
+ }
+ if ( ! (flags & Style_Enabled) && ! (flags & Style_On) ) {
+ int pnt;
+ p->setPen( cg.highlightedText() );
+ TQPoint offset(1,1);
+ for ( pnt = 0; pnt < (int)a.size(); pnt++ )
+ a[pnt] += offset;
+ p->drawLineSegments( a );
+ for ( pnt = 0; pnt < (int)a.size(); pnt++ )
+ a[pnt] -= offset;
+ }
+ p->setPen( cg.text() );
+ p->drawLineSegments( a );
+
+ qDrawShadePanel( p, posX-2, posY-2, markW+4, markH+6, cg, TRUE, dfw);
+ } else
+ qDrawShadePanel( p, posX, posY, markW, markH, cg, TRUE, dfw,
+ &cg.brush( TQColorGroup::Mid ) );
+
+ break;
+ }
+#endif // USE_QT4
+
+ case PE_ScrollBarSubLine:
+ tqdrawPrimitive(((flags & Style_Horizontal) ? PE_ArrowLeft : PE_ArrowUp),
+ p, r, cg, Style_Enabled | flags);
+ break;
+
+ case PE_ScrollBarAddLine:
+ tqdrawPrimitive(((flags & Style_Horizontal) ? PE_ArrowRight : PE_ArrowDown),
+ p, r, cg, Style_Enabled | flags);
+ break;
+
+ case PE_ScrollBarSubPage:
+ case PE_ScrollBarAddPage:
+ p->fillRect(r, cg.brush(TQColorGroup::Mid));
+ break;
+
+ case PE_ScrollBarSlider:
+ tqdrawPrimitive(PE_ButtonBevel, p, r, cg,
+ (flags | Style_Raised) & ~Style_Down);
+ break;
+
+#ifndef USE_QT4 // [FIXME]
+ case PE_ProgressBarChunk:
+ p->fillRect( r.x(), r.y() + 2, r.width() - 2,
+ r.height() - 4, cg.brush(TQColorGroup::Highlight));
+ break;
+#endif // USE_QT4
+
+ default:
+ TQCommonStyle::tqdrawPrimitive( pe, p, r, cg, flags, opt );
+ break;
+ }
+}
+
+
+/*!\reimp
+*/
+void TQMotifStyle::tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ switch( element ) {
+ case CE_PushButton:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ int diw, x1, y1, x2, y2;
+ const TQPushButton *btn;
+ TQColorGroup newCg = cg;
+ btn = ( const TQPushButton * )widget;
+ p->setPen( cg.foreground() );
+ p->setBrush( TQBrush( cg.button(), Qt::NoBrush ) );
+ diw = tqpixelMetric( PM_ButtonDefaultIndicator );
+ r.coords( &x1, &y1, &x2, &y2 );
+ if ( btn->isDefault() || btn->autoDefault() ) {
+ x1 += diw;
+ y1 += diw;
+ x2 -= diw;
+ y2 -= diw;
+ }
+ TQBrush fill;
+ if ( btn->isDown() )
+ fill = newCg.brush( TQColorGroup::Mid );
+ else if ( btn->isOn() )
+ fill = TQBrush( newCg.mid(), Qt::Dense4Pattern );
+ else
+ fill = newCg.brush( TQColorGroup::Button );
+
+ newCg.setBrush( TQColorGroup::Button, fill );
+ if ( btn->isDefault() ) {
+ if ( diw == 0 ) {
+ TQPointArray a;
+ a.setPoints( 9,
+ x1, y1, x2, y1, x2, y2, x1, y2, x1, y1+1,
+ x2-1, y1+1, x2-1, y2-1, x1+1, y2-1, x1+1, y1+1 );
+ p->setPen( newCg.shadow() );
+ p->drawPolygon( a );
+ x1 += 2;
+ y1 += 2;
+ x2 -= 2;
+ y2 -= 2;
+ } else {
+ qDrawShadePanel( p, r, newCg, TRUE );
+ }
+ }
+ if ( !btn->isFlat() || btn->isOn() || btn->isDown() ) {
+ TQRect tmp( x1, y1, x2 - x1 + 1, y2 - y1 + 1 );
+ SFlags flags = Style_Default;
+ if ( btn->isOn())
+ flags |= Style_On;
+ if (btn->isDown())
+ flags |= Style_Down;
+ p->save();
+ p->setBrushOrigin( -widget->backgroundOffset().x(),
+ -widget->backgroundOffset().y() );
+ tqdrawPrimitive( PE_ButtonCommand, p,
+ tmp, newCg,
+ flags );
+ p->restore();
+ }
+ if ( p->brush().style() != Qt::NoBrush )
+ p->setBrush( Qt::NoBrush );
+#endif
+ break;
+ }
+
+ case CE_TabBarTab:
+ {
+#ifndef TQT_NO_TABBAR
+ if ( !widget || !widget->parentWidget() || !opt.tab() )
+ break;
+
+ const TQTabBar * tb = (const TQTabBar *) widget;
+ const TQTab * t = opt.tab();
+
+ int dfw = tqpixelMetric( PM_DefaultFrameWidth, tb );
+ bool selected = flags & Style_Selected;
+ int o = dfw > 1 ? 1 : 0;
+ bool lastTab = FALSE;
+
+ TQRect r2( r );
+ if ( tb->tqshape() == TQTabBar::RoundedAbove ) {
+ if ( tqstyleHint( SH_TabBar_Alignment, tb ) == TQt::AlignRight &&
+ tb->indexOf( t->identifier() ) == tb->count()-1 )
+ lastTab = TRUE;
+
+ if ( o ) {
+ p->setPen( tb->tqcolorGroup().light() );
+ p->drawLine( r2.left(), r2.bottom(), r2.right(), r2.bottom() );
+ p->setPen( tb->tqcolorGroup().light() );
+ p->drawLine( r2.left(), r2.bottom()-1, r2.right(), r2.bottom()-1 );
+ if ( r2.left() == 0 )
+ p->drawPoint( tb->rect().bottomLeft() );
+ }
+ else {
+ p->setPen( tb->tqcolorGroup().light() );
+ p->drawLine( r2.left(), r2.bottom(), r2.right(), r2.bottom() );
+ }
+
+ if ( selected ) {
+ p->fillRect( TQRect( r2.left()+1, r2.bottom()-o, r2.width()-3, 2),
+ tb->tqpalette().active().brush( TQColorGroup::Background ));
+ p->setPen( tb->tqcolorGroup().background() );
+ // p->drawLine( r2.left()+1, r2.bottom(), r2.right()-2, r2.bottom() );
+ // if (o)
+ // p->drawLine( r2.left()+1, r2.bottom()-1, r2.right()-2, r2.bottom()-1 );
+ p->drawLine( r2.left()+1, r2.bottom(), r2.left()+1, r2.top()+2 );
+ p->setPen( tb->tqcolorGroup().light() );
+ } else {
+ p->setPen( tb->tqcolorGroup().light() );
+ r2.setRect( r2.left() + 2, r2.top() + 2,
+ r2.width() - 4, r2.height() - 2 );
+ }
+
+ p->drawLine( r2.left(), r2.bottom()-1, r2.left(), r2.top() + 2 );
+ p->drawPoint( r2.left()+1, r2.top() + 1 );
+ p->drawLine( r2.left()+2, r2.top(),
+ r2.right() - 2, r2.top() );
+ p->drawPoint( r2.left(), r2.bottom());
+
+ if ( o ) {
+ p->drawLine( r2.left()+1, r2.bottom(), r2.left()+1, r2.top() + 2 );
+ p->drawLine( r2.left()+2, r2.top()+1,
+ r2.right() - 2, r2.top()+1 );
+ }
+
+ p->setPen( tb->tqcolorGroup().dark() );
+ p->drawLine( r2.right() - 1, r2.top() + 2,
+ r2.right() - 1, r2.bottom() - 1 + (selected ? o : -o));
+ if ( o ) {
+ p->drawPoint( r2.right() - 1, r2.top() + 1 );
+ p->drawLine( r2.right(), r2.top() + 2, r2.right(),
+ r2.bottom() -
+ (selected ? (lastTab ? 0:1):1+o));
+ p->drawPoint( r2.right() - 1, r2.top() + 1 );
+ }
+ } else if ( tb->tqshape() == TQTabBar::RoundedBelow ) {
+ if ( tqstyleHint( SH_TabBar_Alignment, tb ) == TQt::AlignLeft &&
+ tb->indexOf( t->identifier() ) == tb->count()-1 )
+ lastTab = TRUE;
+ if ( selected ) {
+ p->fillRect( TQRect( r2.left()+1, r2.top(), r2.width()-3, 1),
+ tb->tqpalette().active().brush( TQColorGroup::Background ));
+ p->setPen( tb->tqcolorGroup().background() );
+ // p->drawLine( r2.left()+1, r2.top(), r2.right()-2, r2.top() );
+ p->drawLine( r2.left()+1, r2.top(), r2.left()+1, r2.bottom()-2 );
+ p->setPen( tb->tqcolorGroup().dark() );
+ } else {
+ p->setPen( tb->tqcolorGroup().dark() );
+ p->drawLine( r2.left(), r2.top(), r2.right(), r2.top() );
+ p->drawLine( r2.left() + 1, r2.top() + 1,
+ r2.right() - (lastTab ? 0 : 2),
+ r2.top() + 1 );
+ r2.setRect( r2.left() + 2, r2.top(),
+ r2.width() - 4, r2.height() - 2 );
+ }
+
+ p->drawLine( r2.right() - 1, r2.top(),
+ r2.right() - 1, r2.bottom() - 2 );
+ p->drawPoint( r2.right() - 2, r2.bottom() - 2 );
+ p->drawLine( r2.right() - 2, r2.bottom() - 1,
+ r2.left() + 1, r2.bottom() - 1 );
+ p->drawPoint( r2.left() + 1, r2.bottom() - 2 );
+
+ if (dfw > 1) {
+ p->drawLine( r2.right(), r2.top(),
+ r2.right(), r2.bottom() - 1 );
+ p->drawPoint( r2.right() - 1, r2.bottom() - 1 );
+ p->drawLine( r2.right() - 1, r2.bottom(),
+ r2.left() + 2, r2.bottom() );
+ }
+
+ p->setPen( tb->tqcolorGroup().light() );
+ p->drawLine( r2.left(), r2.top() + (selected ? 0 : 2),
+ r2.left(), r2.bottom() - 2 );
+ p->drawLine( r2.left() + 1, r2.top() + (selected ? 0 : 2),
+ r2.left() + 1, r2.bottom() - 3 );
+
+ } else {
+ TQCommonStyle::tqdrawControl( element, p, widget, r, cg, flags, opt );
+ }
+#endif
+ break;
+ }
+
+ case CE_ProgressBarGroove:
+ qDrawShadePanel(p, r, cg, TRUE, 2);
+ break;
+
+ case CE_ProgressBarLabel:
+ {
+#ifndef TQT_NO_PROGRESSBAR
+ const TQProgressBar * pb = (const TQProgressBar *) widget;
+ const int unit_width = tqpixelMetric( PM_ProgressBarChunkWidth, pb );
+ int u = r.width() / unit_width;
+ int p_v = pb->progress();
+ int t_s = pb->totalSteps();
+ if ( u > 0 && pb->progress() >= INT_MAX / u && t_s >= u ) {
+ // scale down to something usable.
+ p_v /= u;
+ t_s /= u;
+ }
+ if ( pb->percentageVisible() && pb->totalSteps() ) {
+ int nu = ( u * p_v + t_s/2 ) / t_s;
+ int x = unit_width * nu;
+ if (pb->indicatorFollowsStyle() || pb->centerIndicator()) {
+ p->setPen( cg.highlightedText() );
+ p->setClipRect( r.x(), r.y(), x, r.height() );
+ p->drawText( r, TQt::AlignCenter | TQt::SingleLine, pb->progressString() );
+
+ if ( pb->progress() != pb->totalSteps() ) {
+ p->setClipRect( r.x() + x, r.y(), r.width() - x, r.height() );
+ p->setPen( cg.highlight() );
+ p->drawText( r, TQt::AlignCenter | TQt::SingleLine, pb->progressString() );
+ }
+ } else {
+ p->setPen( cg.text() );
+ p->drawText( r, TQt::AlignCenter | TQt::SingleLine, pb->progressString() );
+ }
+ }
+#endif
+ break;
+ }
+
+#ifndef TQT_NO_POPUPMENU
+ case CE_PopupMenuItem:
+ {
+ if (! widget || opt.isDefault())
+ break;
+
+ const TQPopupMenu *popupmenu = (const TQPopupMenu *) widget;
+ TQMenuItem *mi = opt.menuItem();
+ if ( !mi )
+ break;
+
+ int tab = opt.tabWidth();
+ int maxpmw = opt.maxIconWidth();
+ bool dis = ! (flags & Style_Enabled);
+ bool checkable = popupmenu->isCheckable();
+ bool act = flags & Style_Active;
+ int x, y, w, h;
+
+ r.rect(&x, &y, &w, &h);
+
+ if ( checkable )
+ maxpmw = TQMAX( maxpmw, motifCheckMarkSpace );
+
+ int checkcol = maxpmw;
+
+ if ( mi && mi->isSeparator() ) { // draw separator
+ p->setPen( cg.dark() );
+ p->drawLine( x, y, x+w, y );
+ p->setPen( cg.light() );
+ p->drawLine( x, y+1, x+w, y+1 );
+ return;
+ }
+
+ int pw = motifItemFrame;
+
+ if ( act && !dis ) { // active item frame
+ if (tqpixelMetric( PM_DefaultFrameWidth ) > 1)
+ qDrawShadePanel( p, x, y, w, h, cg, FALSE, pw,
+ &cg.brush( TQColorGroup::Button ) );
+ else
+ qDrawShadePanel( p, x+1, y+1, w-2, h-2, cg, TRUE, 1,
+ &cg.brush( TQColorGroup::Button ) );
+ }
+ else // incognito frame
+ p->fillRect(x, y, w, h, cg.brush( TQColorGroup::Button ));
+
+ if ( !mi )
+ return;
+
+ TQRect vrect = tqvisualRect( TQRect( x+motifItemFrame, y+motifItemFrame, checkcol, h-2*motifItemFrame ), r );
+ int xvis = vrect.x();
+ if ( mi->isChecked() ) {
+ if ( mi->iconSet() ) {
+ qDrawShadePanel( p, xvis, y+motifItemFrame, checkcol, h-2*motifItemFrame,
+ cg, TRUE, 1, &cg.brush( TQColorGroup::Midlight ) );
+ }
+ } else if ( !act ) {
+ p->fillRect(xvis, y+motifItemFrame, checkcol, h-2*motifItemFrame,
+ cg.brush( TQColorGroup::Button ));
+ }
+
+ if ( mi->iconSet() ) { // draw iconset
+ TQIconSet::Mode mode = TQIconSet::Normal; // no disabled icons in Motif
+ if (act && !dis )
+ mode = TQIconSet::Active;
+ TQPixmap pixmap;
+ if ( checkable && mi->isChecked() )
+ pixmap = mi->iconSet()->pixmap( TQIconSet::Small, mode, TQIconSet::On );
+ else
+ pixmap = mi->iconSet()->pixmap( TQIconSet::Small, mode );
+
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ TQRect pmr( 0, 0, pixw, pixh );
+ pmr.moveCenter( vrect.center() );
+ p->setPen( cg.text() );
+ p->drawPixmap( pmr.topLeft(), pixmap );
+
+ } else if ( checkable ) { // just "checking"...
+ int mw = checkcol;
+ int mh = h - 2*motifItemFrame;
+ if ( mi->isChecked() ) {
+ SFlags cflags = Style_Default;
+ if (! dis)
+ cflags |= Style_Enabled;
+ if (act)
+ cflags |= Style_On;
+
+ tqdrawPrimitive(PE_CheckMark, p,
+ TQRect(xvis, y+motifItemFrame, mw, mh),
+ cg, cflags);
+ }
+ }
+
+
+ p->setPen( cg.buttonText() );
+
+ TQColor discol;
+ if ( dis ) {
+ discol = cg.text();
+ p->setPen( discol );
+ }
+
+ int xm = motifItemFrame + checkcol + motifItemHMargin;
+
+ vrect = tqvisualRect( TQRect( x+xm, y+motifItemVMargin, w-xm-tab, h-2*motifItemVMargin ), r );
+ xvis = vrect.x();
+ if ( mi->custom() ) {
+ int m = motifItemVMargin;
+ p->save();
+ mi->custom()->paint( p, cg, act, !dis,
+ xvis, y+m, w-xm-tab+1, h-2*m );
+ p->restore();
+ }
+ TQString s = mi->text();
+ if ( !s.isNull() ) { // draw text
+ int t = s.tqfind( '\t' );
+ int m = motifItemVMargin;
+ int text_flags = TQt::AlignVCenter|TQt::ShowPrefix | TQt::DontClip | TQt::SingleLine;
+ text_flags |= (TQApplication::reverseLayout() ? TQt::AlignRight : TQt::AlignLeft );
+ if ( t >= 0 ) { // draw tab text
+ TQRect vr = tqvisualRect( TQRect( x+w-tab-motifItemHMargin-motifItemFrame,
+ y+motifItemVMargin, tab, h-2*motifItemVMargin ), r );
+ int xv = vr.x();
+ p->drawText( xv, y+m, tab, h-2*m, text_flags, s.mid( t+1 ) );
+ s = s.left( t );
+ }
+ p->drawText( xvis, y+m, w-xm-tab+1, h-2*m, text_flags, s, t );
+ } else if ( mi->pixmap() ) { // draw pixmap
+ TQPixmap *pixmap = mi->pixmap();
+ if ( pixmap->depth() == 1 )
+ p->setBackgroundMode( Qt::OpaqueMode );
+ p->drawPixmap( xvis, y+motifItemFrame, *pixmap );
+ if ( pixmap->depth() == 1 )
+ p->setBackgroundMode( Qt::TransparentMode );
+ }
+ if ( mi->popup() ) { // draw sub menu arrow
+ int dim = (h-2*motifItemFrame) / 2;
+ TQStyle::PrimitiveElement arrow = (TQApplication::reverseLayout() ? PE_ArrowLeft : PE_ArrowRight);
+ TQRect vr = tqvisualRect( TQRect(x+w - motifArrowHMargin - motifItemFrame - dim,
+ y+h/2-dim/2, dim, dim), r );
+ if ( act )
+ tqdrawPrimitive(arrow, p, vr, cg,
+ (Style_Down |
+ (dis ? Style_Default : Style_Enabled)) );
+ else
+ tqdrawPrimitive(arrow, p, vr, cg,
+ (dis ? Style_Default : Style_Enabled));
+ }
+
+ break;
+ }
+#endif // TQT_NO_POPUPMENU
+
+ case CE_MenuBarItem:
+ {
+ if ( flags & Style_Active ) // active item
+ qDrawShadePanel( p, r, cg, FALSE, motifItemFrame,
+ &cg.brush(TQColorGroup::Button) );
+ else // other item
+ p->fillRect( r, cg.brush(TQColorGroup::Button) );
+ TQCommonStyle::tqdrawControl( element, p, widget, r, cg, flags, opt );
+ break;
+ }
+
+ default:
+ TQCommonStyle::tqdrawControl( element, p, widget, r, cg, flags, opt );
+ break;
+ }
+}
+
+static int get_combo_extra_width( int h, int w, int *return_awh=0 )
+{
+ int awh,
+ tmp;
+ if ( h < 8 ) {
+ awh = 6;
+ } else if ( h < 14 ) {
+ awh = h - 2;
+ } else {
+ awh = h/2;
+ }
+ tmp = (awh * 3) / 2;
+ if ( tmp > w / 2 ) {
+ awh = w / 2 - 3;
+ tmp = w / 2 + 3;
+ }
+
+ if ( return_awh )
+ *return_awh = awh;
+
+ return tmp;
+}
+
+static void get_combo_parameters( const TQRect &r,
+ int &ew, int &awh, int &ax,
+ int &ay, int &sh, int &dh,
+ int &sy )
+{
+ ew = get_combo_extra_width( r.height(), r.width(), &awh );
+
+ sh = (awh+3)/4;
+ if ( sh < 3 )
+ sh = 3;
+ dh = sh/2 + 1;
+
+ ay = r.y() + (r.height()-awh-sh-dh)/2;
+ if ( ay < 0 ) {
+ //panic mode
+ ay = 0;
+ sy = r.height();
+ } else {
+ sy = ay+awh+dh;
+ }
+ ax = r.x() + r.width() - ew;
+ ax += (ew-awh)/2;
+}
+
+/*!\reimp
+*/
+void TQMotifStyle::tqdrawComplexControl( TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ SCFlags sub,
+ SCFlags subActive,
+ const TQStyleOption& opt ) const
+{
+ switch ( control ) {
+ case CC_SpinWidget: {
+ SCFlags drawSub = SC_None;
+ if ( sub & SC_SpinWidgetFrame )
+ qDrawShadePanel( p, r, cg, TRUE,
+ tqpixelMetric( PM_DefaultFrameWidth) );
+
+ if ( sub & SC_SpinWidgetUp || sub & SC_SpinWidgetDown ) {
+ if ( sub & SC_SpinWidgetUp )
+ drawSub |= SC_SpinWidgetUp;
+ if ( sub & SC_SpinWidgetDown )
+ drawSub |= SC_SpinWidgetDown;
+
+ TQCommonStyle::tqdrawComplexControl( control, p, widget, r, cg, flags,
+ drawSub, subActive, opt );
+ }
+ break; }
+
+ case CC_Slider:
+ {
+#ifndef TQT_NO_SLIDER
+ const TQSlider * slider = (const TQSlider *) widget;
+
+ TQRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove,
+ opt),
+ handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle,
+ opt);
+
+ if ((sub & SC_SliderGroove) && groove.isValid()) {
+ qDrawShadePanel( p, groove, cg, TRUE, 2,
+ &cg.brush( TQColorGroup::Mid ) );
+
+
+ if ( flags & Style_HasFocus ) {
+ TQRect fr = subRect( SR_SliderFocusRect, widget );
+ tqdrawPrimitive( PE_FocusRect, p, fr, cg );
+ }
+ }
+
+ if (( sub & SC_SliderHandle ) && handle.isValid()) {
+ tqdrawPrimitive( PE_ButtonBevel, p, handle, cg );
+
+ if ( slider->orientation() == Qt::Horizontal ) {
+ TQCOORD mid = handle.x() + handle.width() / 2;
+ qDrawShadeLine( p, mid, handle.y(), mid,
+ handle.y() + handle.height() - 2,
+ cg, TRUE, 1);
+ } else {
+ TQCOORD mid = handle.y() + handle.height() / 2;
+ qDrawShadeLine( p, handle.x(), mid,
+ handle.x() + handle.width() - 2, mid,
+ cg, TRUE, 1);
+ }
+ }
+
+ if ( sub & SC_SliderTickmarks )
+ TQCommonStyle::tqdrawComplexControl( control, p, widget, r, cg, flags,
+ SC_SliderTickmarks, subActive,
+ opt );
+#endif
+ break;
+ }
+
+ case CC_ComboBox:
+#ifndef TQT_NO_COMBOBOX
+ if ( sub & SC_ComboBoxArrow ) {
+ const TQComboBox * cb = (const TQComboBox *) widget;
+ int awh, ax, ay, sh, sy, dh, ew;
+ int fw = tqpixelMetric( PM_DefaultFrameWidth, cb);
+
+ tqdrawPrimitive( PE_ButtonCommand, p, r, cg, flags );
+ TQRect ar = TQStyle::tqvisualRect( querySubControlMetrics( CC_ComboBox, cb, SC_ComboBoxArrow,
+ opt ), cb );
+ tqdrawPrimitive( PE_ArrowDown, p, ar, cg, flags | Style_Enabled );
+
+ TQRect tr = r;
+ tr.addCoords( fw, fw, -fw, -fw );
+ get_combo_parameters( tr, ew, awh, ax, ay, sh, dh, sy );
+
+ // draws the shaded line under the arrow
+ p->setPen( cg.light() );
+ p->drawLine( ar.x(), sy, ar.x()+awh-1, sy );
+ p->drawLine( ar.x(), sy, ar.x(), sy+sh-1 );
+ p->setPen( cg.dark() );
+ p->drawLine( ar.x()+1, sy+sh-1, ar.x()+awh-1, sy+sh-1 );
+ p->drawLine( ar.x()+awh-1, sy+1, ar.x()+awh-1, sy+sh-1 );
+
+ if ( cb->hasFocus() ) {
+ TQRect re = TQStyle::tqvisualRect( subRect( SR_ComboBoxFocusRect, cb ), cb );
+ tqdrawPrimitive( PE_FocusRect, p, re, cg );
+ }
+ }
+
+ if ( sub & SC_ComboBoxEditField ) {
+ TQComboBox * cb = (TQComboBox *) widget;
+ if ( cb->editable() ) {
+ TQRect er = TQStyle::tqvisualRect( querySubControlMetrics( CC_ComboBox, cb,
+ SC_ComboBoxEditField ), cb );
+ er.addCoords( -1, -1, 1, 1);
+ qDrawShadePanel( p, er, cg, TRUE, 1,
+ &cg.brush( TQColorGroup::Button ));
+ }
+ }
+#endif
+ p->setPen(cg.buttonText());
+ break;
+
+ case CC_ScrollBar:
+ {
+ if (sub == (SC_ScrollBarAddLine | SC_ScrollBarSubLine | SC_ScrollBarAddPage |
+ SC_ScrollBarSubPage | SC_ScrollBarFirst | SC_ScrollBarLast |
+ SC_ScrollBarSlider))
+ qDrawShadePanel(p, widget->rect(), cg, TRUE,
+ tqpixelMetric(PM_DefaultFrameWidth, widget),
+ &cg.brush(TQColorGroup::Mid));
+ TQCommonStyle::tqdrawComplexControl(control, p, widget, r, cg, flags, sub,
+ subActive, opt);
+ break;
+ }
+
+#ifndef TQT_NO_LISTVIEW
+ case CC_ListView:
+ {
+ if ( sub & SC_ListView ) {
+ TQCommonStyle::tqdrawComplexControl( control, p, widget, r, cg, flags, sub, subActive, opt );
+ }
+ if ( sub & ( SC_ListViewBranch | SC_ListViewExpand ) ) {
+ if (opt.isDefault())
+ break;
+
+ TQListViewItem *item = opt.listViewItem();
+ TQListViewItem *child = item->firstChild();
+
+ int y = r.y();
+ int c;
+ TQPointArray dotlines;
+ if ( subActive == (uint)SC_All && sub == SC_ListViewExpand ) {
+ c = 2;
+ dotlines.resize(2);
+ dotlines[0] = TQPoint( r.right(), r.top() );
+ dotlines[1] = TQPoint( r.right(), r.bottom() );
+ } else {
+ int linetop = 0, linebot = 0;
+ // each branch needs at most two lines, ie. four end points
+ dotlines.resize( item->childCount() * 4 );
+ c = 0;
+
+ // skip the stuff above the exposed rectangle
+ while ( child && y + child->height() <= 0 ) {
+ y += child->totalHeight();
+ child = child->nextSibling();
+ }
+
+ int bx = r.width() / 2;
+
+ // paint stuff in the magical area
+ TQListView* v = item->listView();
+ while ( child && y < r.height() ) {
+ if (child->isVisible()) {
+ int lh;
+ if ( !item->multiLinesEnabled() )
+ lh = child->height();
+ else
+ lh = p->fontMetrics().height() + 2 * v->itemMargin();
+ lh = TQMAX( lh, TQApplication::globalStrut().height() );
+ if ( lh % 2 > 0 )
+ lh++;
+ linebot = y + lh/2;
+ if ( (child->isExpandable() || child->childCount()) &&
+ (child->height() > 0) ) {
+ // needs a box
+ p->setPen( cg.text() );
+ p->drawRect( bx-4, linebot-4, 9, 9 );
+ TQPointArray a;
+ if ( child->isOpen() )
+ a.setPoints( 3, bx-2, linebot-2,
+ bx, linebot+2,
+ bx+2, linebot-2 ); //RightArrow
+ else
+ a.setPoints( 3, bx-2, linebot-2,
+ bx+2, linebot,
+ bx-2, linebot+2 ); //DownArrow
+ p->setBrush( cg.text() );
+ p->drawPolygon( a );
+ p->setBrush( Qt::NoBrush );
+ // dotlinery
+ dotlines[c++] = TQPoint( bx, linetop );
+ dotlines[c++] = TQPoint( bx, linebot - 5 );
+ dotlines[c++] = TQPoint( bx + 5, linebot );
+ dotlines[c++] = TQPoint( r.width(), linebot );
+ linetop = linebot + 5;
+ } else {
+ // just dotlinery
+ dotlines[c++] = TQPoint( bx+1, linebot );
+ dotlines[c++] = TQPoint( r.width(), linebot );
+ }
+ y += child->totalHeight();
+ }
+ child = child->nextSibling();
+ }
+
+ // Expand line height to edge of rectangle if there's any
+ // visible child below
+ while ( child && child->height() <= 0)
+ child = child->nextSibling();
+ if ( child )
+ linebot = r.height();
+
+ if ( linetop < linebot ) {
+ dotlines[c++] = TQPoint( bx, linetop );
+ dotlines[c++] = TQPoint( bx, linebot );
+ }
+ }
+
+ int line; // index into dotlines
+ p->setPen( cg.text() );
+ if ( sub & SC_ListViewBranch ) for( line = 0; line < c; line += 2 ) {
+ p->drawLine( dotlines[line].x(), dotlines[line].y(),
+ dotlines[line+1].x(), dotlines[line+1].y() );
+ }
+ }
+
+ break;
+ }
+#endif // TQT_NO_LISTVIEW
+
+ default:
+ TQCommonStyle::tqdrawComplexControl( control, p, widget, r, cg, flags,
+ sub, subActive, opt );
+ }
+}
+
+
+/*! \reimp */
+int TQMotifStyle::tqpixelMetric( PixelMetric metric, const TQWidget *widget ) const
+{
+ int ret;
+
+ switch( metric ) {
+ case PM_ButtonDefaultIndicator:
+ ret = 3;
+ break;
+
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 0;
+ break;
+
+ case PM_SplitterWidth:
+ ret = TQMAX( 10, TQApplication::globalStrut().width() );
+ break;
+
+ case PM_SliderLength:
+ ret = 30;
+ break;
+
+ case PM_SliderThickness:
+ ret = 24;
+ break;
+
+ case PM_SliderControlThickness:
+ {
+#ifndef TQT_NO_SLIDER
+ const TQSlider * sl = (const TQSlider *) widget;
+ int space = (sl->orientation() == Qt::Horizontal) ? sl->height()
+ : sl->width();
+ int ticks = sl->tickmarks();
+ int n = 0;
+ if ( ticks & TQSlider::Above ) n++;
+ if ( ticks & TQSlider::Below ) n++;
+ if ( !n ) {
+ ret = space;
+ break;
+ }
+
+ int thick = 6; // Magic constant to get 5 + 16 + 5
+
+ space -= thick;
+ //### the two sides may be unequal in size
+ if ( space > 0 )
+ thick += (space * 2) / (n + 2);
+ ret = thick;
+#endif
+ break;
+ }
+
+ case PM_SliderSpaceAvailable:
+ {
+#ifndef TQT_NO_SLIDER
+ const TQSlider * sl = (const TQSlider *) widget;
+ if ( sl->orientation() == Qt::Horizontal )
+ ret = sl->width() - tqpixelMetric( PM_SliderLength, sl ) - 6;
+ else
+ ret = sl->height() - tqpixelMetric( PM_SliderLength, sl ) - 6;
+#endif
+ break;
+ }
+
+ case PM_DockWindowHandleExtent:
+ ret = 9;
+ break;
+
+ case PM_ProgressBarChunkWidth:
+ ret = 1;
+ break;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ ret = 13;
+ break;
+
+ default:
+ ret = TQCommonStyle::tqpixelMetric( metric, widget );
+ break;
+ }
+ return ret;
+}
+
+
+/*!\reimp
+*/
+TQRect TQMotifStyle::querySubControlMetrics( TQ_ComplexControl control,
+ const TQWidget *widget,
+ SubControl sc,
+ const TQStyleOption& opt ) const
+{
+ switch ( control ) {
+ case CC_SpinWidget: {
+ if ( !widget )
+ return TQRect();
+ int fw = tqpixelMetric( PM_SpinBoxFrameWidth, 0 );
+ TQSize bs;
+ bs.setHeight( widget->height()/2 );
+ if ( bs.height() < 8 )
+ bs.setHeight( 8 );
+ bs.setWidth( TQMIN( bs.height() * 8 / 5, widget->width() / 4 ) ); // 1.6 -approximate golden mean
+ bs = bs.expandedTo( TQApplication::globalStrut() );
+ int y = 0;
+ int x, lx, rx;
+ x = widget->width() - y - bs.width();
+ lx = fw;
+ rx = x - fw * 2;
+ switch ( sc ) {
+ case SC_SpinWidgetUp:
+ return TQRect(x, y, bs.width(), bs.height());
+ case SC_SpinWidgetDown:
+ return TQRect(x, y + bs.height(), bs.width(), bs.height());
+ case SC_SpinWidgetButtonField:
+ return TQRect(x, y, bs.width(), widget->height() - 2*fw);
+ case SC_SpinWidgetEditField:
+ return TQRect(lx, fw, rx, widget->height() - 2*fw);
+ case SC_SpinWidgetFrame:
+ return TQRect( 0, 0,
+ widget->width() - bs.width(), widget->height() );
+ default:
+ break;
+ }
+ break; }
+
+#ifndef TQT_NO_SLIDER
+ case CC_Slider: {
+ if (sc == SC_SliderHandle) {
+ const TQSlider * sl = (const TQSlider *) widget;
+ int tickOffset = tqpixelMetric( PM_SliderTickmarkOffset, sl );
+ int thickness = tqpixelMetric( PM_SliderControlThickness, sl );
+ int sliderPos = sl->sliderStart();
+ int len = tqpixelMetric( PM_SliderLength, sl );
+ int motifBorder = 3;
+
+ if ( sl->orientation() == Qt::Horizontal )
+ return TQRect( sliderPos + motifBorder, tickOffset + motifBorder, len,
+ thickness - 2*motifBorder );
+ return TQRect( tickOffset + motifBorder, sliderPos + motifBorder,
+ thickness - 2*motifBorder, len );
+ }
+ break; }
+#endif
+
+#ifndef TQT_NO_SCROLLBAR
+ case CC_ScrollBar: {
+ if (! widget)
+ return TQRect();
+
+ const TQScrollBar *scrollbar = (const TQScrollBar *) widget;
+ int sliderstart = scrollbar->sliderStart();
+ int sbextent = tqpixelMetric(PM_ScrollBarExtent, widget);
+ int fw = tqpixelMetric(PM_DefaultFrameWidth, widget);
+ int buttonw = sbextent - (fw * 2);
+ int buttonh = sbextent - (fw * 2);
+ int maxlen = ((scrollbar->orientation() == Qt::Horizontal) ?
+ scrollbar->width() : scrollbar->height()) -
+ (buttonw * 2) - (fw * 2);
+ int sliderlen;
+
+ // calculate slider length
+ if (scrollbar->maxValue() != scrollbar->minValue()) {
+ uint range = scrollbar->maxValue() - scrollbar->minValue();
+ sliderlen = (scrollbar->pageStep() * maxlen) /
+ (range + scrollbar->pageStep());
+
+ if ( sliderlen < 9 || range > INT_MAX/2 )
+ sliderlen = 9;
+ if ( sliderlen > maxlen )
+ sliderlen = maxlen;
+ } else
+ sliderlen = maxlen;
+
+ switch (sc) {
+ case SC_ScrollBarSubLine:
+ // top/left button
+ if (scrollbar->orientation() == Qt::Horizontal) {
+ if ( scrollbar->width()/2 < sbextent )
+ buttonw = scrollbar->width()/2 - (fw*2);
+ return TQRect(fw, fw, buttonw, buttonh);
+ } else {
+ if ( scrollbar->height()/2 < sbextent )
+ buttonh = scrollbar->height()/2 - (fw*2);
+ return TQRect(fw, fw, buttonw, buttonh);
+ }
+ case SC_ScrollBarAddLine:
+ // bottom/right button
+ if (scrollbar->orientation() == Qt::Horizontal) {
+ if ( scrollbar->width()/2 < sbextent )
+ buttonw = scrollbar->width()/2 - (fw*2);
+ return TQRect(scrollbar->width() - buttonw - fw, fw,
+ buttonw, buttonh);
+ } else {
+ if ( scrollbar->height()/2 < sbextent )
+ buttonh = scrollbar->height()/2 - (fw*2);
+ return TQRect(fw, scrollbar->height() - buttonh - fw,
+ buttonw, buttonh);
+ }
+ case SC_ScrollBarSubPage:
+ if (scrollbar->orientation() == Qt::Horizontal)
+ return TQRect(buttonw + fw, fw, sliderstart - buttonw - fw, buttonw);
+ return TQRect(fw, buttonw + fw, buttonw, sliderstart - buttonw - fw);
+
+ case SC_ScrollBarAddPage:
+ if (scrollbar->orientation() == Qt::Horizontal)
+ return TQRect(sliderstart + sliderlen, fw,
+ maxlen - sliderstart - sliderlen + buttonw + fw, buttonw);
+ return TQRect(fw, sliderstart + sliderlen, buttonw,
+ maxlen - sliderstart - sliderlen + buttonw + fw);
+
+ case SC_ScrollBarGroove:
+ if (scrollbar->orientation() == Qt::Horizontal)
+ return TQRect(buttonw + fw, fw, maxlen, buttonw);
+ return TQRect(fw, buttonw + fw, buttonw, maxlen);
+
+ case SC_ScrollBarSlider:
+ if (scrollbar->orientation() == Qt::Horizontal)
+ return TQRect(sliderstart, fw, sliderlen, buttonw);
+ return TQRect(fw, sliderstart, buttonw, sliderlen);
+
+ default:
+ break;
+ }
+ break; }
+#endif
+
+#ifndef TQT_NO_COMBOBOX
+ case CC_ComboBox:
+
+ switch ( sc ) {
+ case SC_ComboBoxArrow: {
+ const TQComboBox * cb = (const TQComboBox *) widget;
+ int ew, awh, sh, dh, ax, ay, sy;
+ int fw = tqpixelMetric( PM_DefaultFrameWidth, cb );
+ TQRect cr = cb->rect();
+ cr.addCoords( fw, fw, -fw, -fw );
+ get_combo_parameters( cr, ew, awh, ax, ay, sh, dh, sy );
+ return TQRect( ax, ay, awh, awh ); }
+
+ case SC_ComboBoxEditField: {
+ const TQComboBox * cb = (const TQComboBox *) widget;
+ int fw = tqpixelMetric( PM_DefaultFrameWidth, cb );
+ TQRect rect = cb->rect();
+ rect.addCoords( fw, fw, -fw, -fw );
+ int ew = get_combo_extra_width( rect.height(), rect.width() );
+ rect.addCoords( 1, 1, -1-ew, -1 );
+ return rect; }
+
+ default:
+ break;
+ }
+ break;
+#endif
+ default: break;
+ }
+ return TQCommonStyle::querySubControlMetrics( control, widget, sc, opt );
+}
+
+/*!\reimp
+*/
+TQSize TQMotifStyle::tqsizeFromContents( ContentsType contents,
+ const TQWidget *widget,
+ const TQSize &contentsSize,
+ const TQStyleOption& opt ) const
+{
+ TQSize sz(contentsSize);
+
+ switch(contents) {
+ case CT_PushButton:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *button = (const TQPushButton *) widget;
+ sz = TQCommonStyle::tqsizeFromContents(contents, widget, contentsSize, opt);
+ if ((button->isDefault() || button->autoDefault()) &&
+ sz.width() < 80 && ! button->pixmap())
+ sz.setWidth(80);
+#endif
+ break;
+ }
+
+ case CT_PopupMenuItem:
+ {
+#ifndef TQT_NO_POPUPMENU
+ if (! widget || opt.isDefault())
+ break;
+
+ const TQPopupMenu *popup = (TQPopupMenu *) widget;
+ bool checkable = popup->isCheckable();
+ TQMenuItem *mi = opt.menuItem();
+ int maxpmw = opt.maxIconWidth();
+ int w = sz.width(), h = sz.height();
+
+ if (mi->custom()) {
+ w = mi->custom()->tqsizeHint().width();
+ h = mi->custom()->tqsizeHint().height();
+ if (! mi->custom()->fullSpan())
+ h += 2*motifItemVMargin + 2*motifItemFrame;
+ } else if ( mi->widget() ) {
+ } else if ( mi->isSeparator() ) {
+ w = 10;
+ h = motifSepHeight;
+ } else if (mi->pixmap() || ! mi->text().isNull())
+ h += 2*motifItemVMargin + 2*motifItemFrame;
+
+ // a little bit of border can never harm
+ w += 2*motifItemHMargin + 2*motifItemFrame;
+
+ if ( !mi->text().isNull() && mi->text().tqfind('\t') >= 0 )
+ // string tqcontains tab
+ w += motifTabSpacing;
+ else if (mi->popup())
+ // submenu indicator needs some room if we don't have a tab column
+ w += motifArrowHMargin + 4*motifItemFrame;
+
+ if ( checkable && maxpmw <= 0)
+ // if we are checkable and have no iconsets, add space for a checkmark
+ w += motifCheckMarkSpace;
+ else if (checkable && maxpmw < motifCheckMarkSpace)
+ // make sure the check-column is wide enough if we have iconsets
+ w += (motifCheckMarkSpace - maxpmw);
+
+ // if we have a check-column ( iconsets of checkmarks), add space
+ // to separate the columns
+ if ( maxpmw > 0 || checkable )
+ w += motifCheckMarkHMargin;
+
+ sz = TQSize(w, h);
+#endif
+ break;
+ }
+
+ default:
+ sz = TQCommonStyle::tqsizeFromContents( contents, widget, contentsSize, opt );
+ break;
+ }
+
+ return sz;
+}
+
+/*!\reimp
+*/
+TQRect TQMotifStyle::subRect( SubRect r, const TQWidget *widget ) const
+{
+ TQRect rect;
+ TQRect wrect = widget->rect();
+
+ switch ( r ) {
+ case SR_SliderFocusRect:
+ rect = TQCommonStyle::subRect( r, widget );
+ rect.addCoords( 2, 2, -2, -2 );
+ break;
+
+ case SR_ComboBoxFocusRect:
+ {
+ int awh, ax, ay, sh, sy, dh, ew;
+ int fw = tqpixelMetric( PM_DefaultFrameWidth, widget );
+ TQRect tr = wrect;
+
+ tr.addCoords( fw, fw, -fw, -fw );
+ get_combo_parameters( tr, ew, awh, ax, ay, sh, dh, sy );
+ rect.setRect(ax-2, ay-2, awh+4, awh+sh+dh+4);
+ break;
+ }
+
+ case SR_DockWindowHandleRect:
+ {
+#ifndef TQT_NO_MAINWINDOW
+ if ( !widget || !widget->tqparent() )
+ break;
+
+ const TQDockWindow * dw = (const TQDockWindow *) widget->tqparent();
+ if ( !dw->area() || !dw->isCloseEnabled() )
+ rect.setRect( 0, 0, widget->width(), widget->height() );
+ else {
+ if ( dw->area()->orientation() == Qt::Horizontal )
+ rect.setRect(2, 15, widget->width()-2, widget->height() - 15);
+ else
+ rect.setRect(0, 2, widget->width() - 15, widget->height() - 2);
+ }
+#endif
+ break;
+ }
+
+ case SR_ProgressBarGroove:
+ case SR_ProgressBarContents:
+ {
+#ifndef TQT_NO_PROGRESSBAR
+ TQFontMetrics fm( ( widget ? widget->fontMetrics() :
+ TQApplication::fontMetrics() ) );
+ const TQProgressBar *progressbar = (const TQProgressBar *) widget;
+ int textw = 0;
+ if (progressbar->percentageVisible())
+ textw = fm.width("100%") + 6;
+
+ if (progressbar->indicatorFollowsStyle() ||
+ progressbar->centerIndicator())
+ rect = wrect;
+ else
+ rect.setCoords(wrect.left(), wrect.top(),
+ wrect.right() - textw, wrect.bottom());
+#endif
+ break;
+ }
+
+ case SR_ProgressBarLabel:
+ {
+#ifndef TQT_NO_PROGRESSBAR
+ TQFontMetrics fm( ( widget ? widget->fontMetrics() :
+ TQApplication::fontMetrics() ) );
+ const TQProgressBar *progressbar = (const TQProgressBar *) widget;
+ int textw = 0;
+ if (progressbar->percentageVisible())
+ textw = fm.width("100%") + 6;
+
+ if (progressbar->indicatorFollowsStyle() ||
+ progressbar->centerIndicator())
+ rect = wrect;
+ else
+ rect.setCoords(wrect.right() - textw, wrect.top(),
+ wrect.right(), wrect.bottom());
+#endif
+ break;
+ }
+
+ case SR_CheckBoxContents:
+ {
+#ifndef TQT_NO_CHECKBOX
+ TQRect ir = subRect(SR_CheckBoxIndicator, widget);
+ rect.setRect(ir.right() + 10, wrect.y(),
+ wrect.width() - ir.width() - 10, wrect.height());
+#endif
+ break;
+ }
+
+ case SR_RadioButtonContents:
+ {
+ TQRect ir = subRect(SR_RadioButtonIndicator, widget);
+ rect.setRect(ir.right() + 10, wrect.y(),
+ wrect.width() - ir.width() - 10, wrect.height());
+ break;
+ }
+
+ default:
+ rect = TQCommonStyle::subRect( r, widget );
+ }
+
+ return rect;
+}
+
+/*! \reimp
+*/
+void TQMotifStyle::polishPopupMenu( TQPopupMenu* p)
+{
+#ifndef TQT_NO_POPUPMENU
+ if ( !p->testWState( TQt::WState_Polished ) )
+ p->setCheckable( FALSE );
+#endif
+}
+
+
+#ifndef TQT_NO_IMAGEIO_XPM
+static const char * const qt_close_xpm[] = {
+"12 12 2 1",
+" s None c None",
+". c black",
+" ",
+" ",
+" . . ",
+" ... ... ",
+" ...... ",
+" .... ",
+" .... ",
+" ...... ",
+" ... ... ",
+" . . ",
+" ",
+" "};
+
+static const char * const qt_maximize_xpm[] = {
+"12 12 2 1",
+" s None c None",
+". c black",
+" ",
+" ",
+" ",
+" . ",
+" ... ",
+" ..... ",
+" ....... ",
+" ......... ",
+" ",
+" ",
+" ",
+" "};
+
+static const char * const qt_minimize_xpm[] = {
+"12 12 2 1",
+" s None c None",
+". c black",
+" ",
+" ",
+" ",
+" ",
+" ......... ",
+" ....... ",
+" ..... ",
+" ... ",
+" . ",
+" ",
+" ",
+" "};
+
+#if 0 // ### not used???
+static const char * const qt_normalize_xpm[] = {
+"12 12 2 1",
+" s None c None",
+". c black",
+" ",
+" ",
+" . ",
+" .. ",
+" ... ",
+" .... ",
+" ..... ",
+" ...... ",
+" ....... ",
+" ",
+" ",
+" "};
+#endif
+
+static const char * const qt_normalizeup_xpm[] = {
+"12 12 2 1",
+" s None c None",
+". c black",
+" ",
+" ",
+" ",
+" ....... ",
+" ...... ",
+" ..... ",
+" .... ",
+" ... ",
+" .. ",
+" . ",
+" ",
+" "};
+
+static const char * const qt_shade_xpm[] = {
+"12 12 2 1", "# c #000000",
+". c None",
+"............",
+"............",
+".#########..",
+".#########..",
+"............",
+"............",
+"............",
+"............",
+"............",
+"............",
+"............",
+"............"};
+
+
+static const char * const qt_unshade_xpm[] = {
+"12 12 2 1",
+"# c #000000",
+". c None",
+"............",
+"............",
+".#########..",
+".#########..",
+".#.......#..",
+".#.......#..",
+".#.......#..",
+".#.......#..",
+".#.......#..",
+".#########..",
+"............",
+"............"};
+
+
+static const char * dock_window_close_xpm[] = {
+"8 8 2 1",
+"# c #000000",
+". c None",
+"##....##",
+".##..##.",
+"..####..",
+"...##...",
+"..####..",
+".##..##.",
+"##....##",
+"........"};
+
+// Message box icons, from page 210 of the Windows style guide.
+
+// Hand-drawn to resemble Microsoft's icons, but in the Mac/Netscape palette.
+// Thanks to TrueColor displays, it is slightly more efficient to have
+// them duplicated.
+/* XPM */
+static const char * const information_xpm[]={
+"32 32 5 1",
+". c None",
+"c c #000000",
+"* c #999999",
+"a c #ffffff",
+"b c #0000ff",
+"...........********.............",
+"........***aaaaaaaa***..........",
+"......**aaaaaaaaaaaaaa**........",
+".....*aaaaaaaaaaaaaaaaaa*.......",
+"....*aaaaaaaabbbbaaaaaaaac......",
+"...*aaaaaaaabbbbbbaaaaaaaac.....",
+"..*aaaaaaaaabbbbbbaaaaaaaaac....",
+".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
+".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
+"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+"..*aaaaaaaaaabbbbbaaaaaaaaac***.",
+"...caaaaaaabbbbbbbbbaaaaaac****.",
+"....caaaaaaaaaaaaaaaaaaaac****..",
+".....caaaaaaaaaaaaaaaaaac****...",
+"......ccaaaaaaaaaaaaaacc****....",
+".......*cccaaaaaaaaccc*****.....",
+"........***cccaaaac*******......",
+"..........****caaac*****........",
+".............*caaac**...........",
+"...............caac**...........",
+"................cac**...........",
+".................cc**...........",
+"..................***...........",
+"...................**..........."};
+/* XPM */
+static const char* const warning_xpm[]={
+"32 32 4 1",
+". c None",
+"a c #ffff00",
+"* c #000000",
+"b c #999999",
+".............***................",
+"............*aaa*...............",
+"...........*aaaaa*b.............",
+"...........*aaaaa*bb............",
+"..........*aaaaaaa*bb...........",
+"..........*aaaaaaa*bb...........",
+".........*aaaaaaaaa*bb..........",
+".........*aaaaaaaaa*bb..........",
+"........*aaaaaaaaaaa*bb.........",
+"........*aaaa***aaaa*bb.........",
+".......*aaaa*****aaaa*bb........",
+".......*aaaa*****aaaa*bb........",
+"......*aaaaa*****aaaaa*bb.......",
+"......*aaaaa*****aaaaa*bb.......",
+".....*aaaaaa*****aaaaaa*bb......",
+".....*aaaaaa*****aaaaaa*bb......",
+"....*aaaaaaaa***aaaaaaaa*bb.....",
+"....*aaaaaaaa***aaaaaaaa*bb.....",
+"...*aaaaaaaaa***aaaaaaaaa*bb....",
+"...*aaaaaaaaaa*aaaaaaaaaa*bb....",
+"..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
+"..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
+".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
+".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
+"*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
+"*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
+"..*************************bbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
+".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
+/* XPM */
+static const char* const critical_xpm[]={
+"32 32 4 1",
+". c None",
+"a c #999999",
+"* c #ff0000",
+"b c #ffffff",
+"...........********.............",
+".........************...........",
+".......****************.........",
+"......******************........",
+".....********************a......",
+"....**********************a.....",
+"...************************a....",
+"..*******b**********b*******a...",
+"..******bbb********bbb******a...",
+".******bbbbb******bbbbb******a..",
+".*******bbbbb****bbbbb*******a..",
+"*********bbbbb**bbbbb*********a.",
+"**********bbbbbbbbbb**********a.",
+"***********bbbbbbbb***********aa",
+"************bbbbbb************aa",
+"************bbbbbb************aa",
+"***********bbbbbbbb***********aa",
+"**********bbbbbbbbbb**********aa",
+"*********bbbbb**bbbbb*********aa",
+".*******bbbbb****bbbbb*******aa.",
+".******bbbbb******bbbbb******aa.",
+"..******bbb********bbb******aaa.",
+"..*******b**********b*******aa..",
+"...************************aaa..",
+"....**********************aaa...",
+"....a********************aaa....",
+".....a******************aaa.....",
+"......a****************aaa......",
+".......aa************aaaa.......",
+".........aa********aaaaa........",
+"...........aaaaaaaaaaa..........",
+".............aaaaaaa............"};
+/* XPM */
+static const char *const question_xpm[] = {
+"32 32 5 1",
+". c None",
+"c c #000000",
+"* c #999999",
+"a c #ffffff",
+"b c #0000ff",
+"...........********.............",
+"........***aaaaaaaa***..........",
+"......**aaaaaaaaaaaaaa**........",
+".....*aaaaaaaaaaaaaaaaaa*.......",
+"....*aaaaaaaaaaaaaaaaaaaac......",
+"...*aaaaaaaabbbbbbaaaaaaaac.....",
+"..*aaaaaaaabaaabbbbaaaaaaaac....",
+".*aaaaaaaabbaaaabbbbaaaaaaaac...",
+".*aaaaaaaabbbbaabbbbaaaaaaaac*..",
+"*aaaaaaaaabbbbaabbbbaaaaaaaaac*.",
+"*aaaaaaaaaabbaabbbbaaaaaaaaaac*.",
+"*aaaaaaaaaaaaabbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbbaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**",
+".*aaaaaaaaaaaabbaaaaaaaaaaaac***",
+".*aaaaaaaaaaabbbbaaaaaaaaaaac***",
+"..*aaaaaaaaaabbbbaaaaaaaaaac***.",
+"...caaaaaaaaaabbaaaaaaaaaac****.",
+"....caaaaaaaaaaaaaaaaaaaac****..",
+".....caaaaaaaaaaaaaaaaaac****...",
+"......ccaaaaaaaaaaaaaacc****....",
+".......*cccaaaaaaaaccc*****.....",
+"........***cccaaaac*******......",
+"..........****caaac*****........",
+".............*caaac**...........",
+"...............caac**...........",
+"................cac**...........",
+".................cc**...........",
+"..................***...........",
+"...................**...........",
+};
+#endif
+
+/*!
+ \reimp
+ */
+TQPixmap TQMotifStyle::stylePixmap(StylePixmap sp,
+ const TQWidget *widget,
+ const TQStyleOption& opt) const
+{
+#ifndef TQT_NO_IMAGEIO_XPM
+ switch (sp) {
+ case SP_TitleBarShadeButton:
+ return TQPixmap((const char **)qt_shade_xpm);
+ case SP_TitleBarUnshadeButton:
+ return TQPixmap((const char **)qt_unshade_xpm);
+ case SP_TitleBarNormalButton:
+ return TQPixmap((const char **)qt_normalizeup_xpm);
+ case SP_TitleBarMinButton:
+ return TQPixmap((const char **)qt_minimize_xpm);
+ case SP_TitleBarMaxButton:
+ return TQPixmap((const char **)qt_maximize_xpm);
+ case SP_TitleBarCloseButton:
+ return TQPixmap((const char **)qt_close_xpm);
+ case SP_DockWindowCloseButton:
+ return TQPixmap((const char **)dock_window_close_xpm );
+
+ case SP_MessageBoxInformation:
+ case SP_MessageBoxWarning:
+ case SP_MessageBoxCritical:
+ case SP_MessageBoxQuestion:
+ {
+ const char * const * xpm_data;
+ switch ( sp ) {
+ case SP_MessageBoxInformation:
+ xpm_data = information_xpm;
+ break;
+ case SP_MessageBoxWarning:
+ xpm_data = warning_xpm;
+ break;
+ case SP_MessageBoxCritical:
+ xpm_data = critical_xpm;
+ break;
+ case SP_MessageBoxQuestion:
+ xpm_data = question_xpm;
+ break;
+ default:
+ xpm_data = 0;
+ break;
+ }
+ TQPixmap pm;
+ if ( xpm_data ) {
+ TQImage image( (const char **) xpm_data);
+ // All that color looks ugly in Motif
+ TQColorGroup g = TQApplication::tqpalette().active();
+ switch ( sp ) {
+ case SP_MessageBoxInformation:
+ case SP_MessageBoxQuestion:
+ image.setColor( 2, 0xff000000 | g.dark().rgb() );
+ image.setColor( 3, 0xff000000 | g.base().rgb() );
+ image.setColor( 4, 0xff000000 | g.text().rgb() );
+ break;
+ case SP_MessageBoxWarning:
+ image.setColor( 1, 0xff000000 | g.base().rgb() );
+ image.setColor( 2, 0xff000000 | g.text().rgb() );
+ image.setColor( 3, 0xff000000 | g.dark().rgb() );
+ break;
+ case SP_MessageBoxCritical:
+ image.setColor( 1, 0xff000000 | g.dark().rgb() );
+ image.setColor( 2, 0xff000000 | g.text().rgb() );
+ image.setColor( 3, 0xff000000 | g.base().rgb() );
+ break;
+ default:
+ break;
+ }
+ pm.convertFromImage(image);
+ }
+ return pm;
+ }
+
+ default:
+ break;
+ }
+#endif
+
+ return TQCommonStyle::stylePixmap(sp, widget, opt);
+}
+
+
+/*! \reimp */
+int TQMotifStyle::tqstyleHint(TQ_StyleHint hint,
+ const TQWidget *widget,
+ const TQStyleOption &opt,
+ TQStyleHintReturn *returnData) const
+{
+ int ret;
+
+ switch (hint) {
+ case SH_GUIStyle:
+ ret = TQt::MotifStyle;
+ break;
+
+ case SH_ScrollBar_BackgroundMode:
+ ret = TQt::PaletteMid;
+ break;
+
+ case SH_ScrollBar_MiddleClickAbsolutePosition:
+ case SH_Slider_SloppyKeyEvents:
+ case SH_ProgressDialog_CenterCancelButton:
+ case SH_PopupMenu_SpaceActivatesItem:
+ case SH_ScrollView_FrameOnlyAroundContents:
+ ret = 1;
+ break;
+
+ case SH_PopupMenu_SubMenuPopupDelay:
+ ret = 96;
+ break;
+
+ case SH_ProgressDialog_TextLabelAlignment:
+ ret = TQt::AlignAuto | TQt::AlignVCenter;
+ break;
+
+ case SH_ItemView_ChangeHighlightOnFocus:
+ ret = 0;
+ break;
+
+ default:
+ ret = TQCommonStyle::tqstyleHint(hint, widget, opt, returnData);
+ break;
+ }
+
+ return ret;
+}
+
+
+#endif
diff --git a/tqtinterface/qt4/src/styles/tqmotifstyle.h b/tqtinterface/qt4/src/styles/tqmotifstyle.h
new file mode 100644
index 0000000..f5d6a52
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqmotifstyle.h
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** Definition of Motif-like style class
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMOTIFSTYLE_H
+#define TQMOTIFSTYLE_H
+
+#ifndef TQT_H
+#include "tqcommonstyle.h"
+#endif // TQT_H
+
+#if !defined(TQT_NO_STYLE_MOTIF) || defined(TQT_PLUGIN)
+
+class TQPalette;
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_STYLE_MOTIF
+#else
+#define TQ_EXPORT_STYLE_MOTIF TQ_EXPORT
+#endif
+
+
+class TQ_EXPORT_STYLE_MOTIF TQMotifStyle : public TQCommonStyle
+{
+ TQ_OBJECT
+public:
+ TQMotifStyle( bool useHighlightCols=FALSE );
+ virtual ~TQMotifStyle();
+
+ void setUseHighlightColors( bool );
+ bool useHighlightColors() const;
+
+ void polish( TQPalette& );
+ void polish( TQWidget* );
+ void polish( TQApplication* );
+
+ void polishPopupMenu( TQPopupMenu* );
+
+ // new style API
+ void tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawComplexControl( TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget* widget,
+ const TQRect& r,
+ const TQColorGroup& cg,
+ SFlags how = Style_Default,
+#ifdef TQ_TQDOC
+ SCFlags sub = SC_All,
+#else
+ SCFlags sub = (uint)SC_All,
+#endif
+ SCFlags subActive = SC_None,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ TQRect querySubControlMetrics( TQ_ComplexControl control,
+ const TQWidget *widget,
+ SubControl sc,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ int tqpixelMetric( PixelMetric metric, const TQWidget *widget = 0 ) const;
+
+ TQSize tqsizeFromContents( ContentsType contents,
+ const TQWidget *widget,
+ const TQSize &contentsSize,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ TQRect subRect( SubRect r, const TQWidget *widget ) const;
+
+ TQPixmap stylePixmap(StylePixmap, const TQWidget * = 0, const TQStyleOption& = TQStyleOption::Default) const;
+
+ int tqstyleHint(TQ_StyleHint sh, const TQWidget *, const TQStyleOption & = TQStyleOption::Default,
+ TQStyleHintReturn* = 0) const;
+
+private:
+ bool highlightCols;
+
+ // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQMotifStyle( const TQMotifStyle & );
+ TQMotifStyle& operator=( const TQMotifStyle & );
+#endif
+};
+
+#endif // TQT_NO_STYLE_MOTIF
+
+#endif // TQMOTIFSTYLE_H
diff --git a/tqtinterface/qt4/src/styles/tqplatinumstyle.cpp b/tqtinterface/qt4/src/styles/tqplatinumstyle.cpp
new file mode 100644
index 0000000..2be69b0
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqplatinumstyle.cpp
@@ -0,0 +1,1557 @@
+/****************************************************************************
+**
+** Implementation of Platinum-like style class
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatinumstyle.h"
+
+#if !defined(TQT_NO_STYLE_PLATINUM) || defined(TQT_PLUGIN)
+
+#include "tqapplication.h"
+#include "tqcombobox.h"
+#include "tqdrawutil.h"
+#include "tqpainter.h"
+#include "tqpalette.h"
+#include "tqpixmap.h"
+#include "tqpushbutton.h"
+#include "tqscrollbar.h"
+#include "tqslider.h"
+#include <limits.h>
+
+/*!
+ \class TQPlatinumStyle tqplatinumstyle.h
+ \brief The TQPlatinumStyle class provides Mac/Platinum look and feel.
+
+ \ingroup appearance
+
+ This class implements the Platinum look and feel. It's an
+ experimental class that tries to resemble a Macinosh-like GUI
+ style with the TQStyle system. The emulation is currently far from
+ perfect.
+
+ \sa TQAquaStyle
+*/
+
+
+/*!
+ Constructs a TQPlatinumStyle
+*/
+TQPlatinumStyle::TQPlatinumStyle()
+{
+}
+
+/*!\reimp
+*/
+TQPlatinumStyle::~TQPlatinumStyle()
+{
+}
+
+
+/*!\reimp
+ */
+void TQPlatinumStyle::tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ switch (pe) {
+ case PE_HeaderSection:
+ {
+ // adjust the sunken flag, otherwise headers are drawn
+ // sunken...
+ if ( flags & Style_Sunken )
+ flags ^= Style_Sunken;
+ tqdrawPrimitive( PE_ButtonBevel, p, r, cg, flags, opt );
+ break;
+ }
+ case PE_ButtonTool:
+ {
+ // tool buttons don't change color when pushed in platinum,
+ // so we need to make the mid and button color the same
+ TQColorGroup myCG = cg;
+ TQBrush fill;
+
+ // quick trick to make sure toolbuttons drawn sunken
+ // when they are activated...
+ if ( flags & Style_On )
+ flags |= Style_Sunken;
+
+ fill = myCG.brush( TQColorGroup::Button );
+ myCG.setBrush( TQColorGroup::Mid, fill );
+ tqdrawPrimitive( PE_ButtonBevel, p, r, myCG, flags, opt );
+ break;
+ }
+ case PE_ButtonBevel:
+ {
+ int x,
+ y,
+ w,
+ h;
+ r.rect( &x, &y, &w, &h );
+
+ TQPen oldPen = p->pen();
+ if ( w * h < 1600 ||
+ TQABS(w - h) > 10 ) {
+ // small buttons
+
+ if ( !(flags & (Style_Sunken | Style_Down)) ) {
+ p->fillRect( x + 2, y + 2, w - 4, h - 4,
+ cg.brush(TQColorGroup::Button) );
+ // the bright side
+ p->setPen( cg.dark() );
+ // the bright side
+ p->setPen( cg.dark() );
+ p->drawLine( x, y, x + w - 1, y );
+ p->drawLine( x, y, x, y + h - 1 );
+
+ p->setPen( cg.light() );
+ p->drawLine( x + 1, y + 1, x + w - 2, y + 1 );
+ p->drawLine( x + 1, y + 1, x + 1, y + h - 2 );
+
+ // the dark side
+ p->setPen( cg.mid() );
+ p->drawLine( x + 2, y + h - 2, x + w - 2, y + h - 2 );
+ p->drawLine( x + w - 2, y + 2, x + w - 2, y + h - 3 );
+
+ p->setPen( cg.dark().dark() );
+ p->drawLine( x + 1, y + h - 1, x + w - 1,
+ y + h - 1 );
+ p->drawLine( x + w - 1, y + 1,
+ x + w - 1,
+ y + h - 2 );
+ } else {
+ p->fillRect(x + 2, y + 2,
+ w - 4, h - 4,
+ cg.brush( TQColorGroup::Mid ));
+
+ // the dark side
+ p->setPen( cg.dark().dark() );
+ p->drawLine( x, y, x + w - 1, y );
+ p->drawLine( x, y, x, y + h - 1 );
+
+ p->setPen( cg.mid().dark());
+ p->drawLine( x + 1, y + 1,
+ x + w-2, y + 1);
+ p->drawLine( x + 1, y + 1,
+ x + 1, y + h - 2 );
+
+
+ // the bright side!
+
+ p->setPen(cg.button());
+ p->drawLine( x + 1, y + h - 2,
+ x + w - 2,
+ y + h - 2 );
+ p->drawLine( x + w - 2, y + 1,
+ x + w - 2,
+ y + h - 2 );
+ p->setPen(cg.dark());
+ p->drawLine(x, y + h - 1,
+ x + w - 1,
+ y + h - 1 );
+ p->drawLine(x + w - 1, y,
+ x + w - 1,
+ y + h - 1 );
+ }
+ } else {
+ // big ones
+ if ( !(flags & (Style_Sunken | Style_Down)) ) {
+ p->fillRect( x + 3, y + 3, w - 6,
+ h - 6,
+ cg.brush(TQColorGroup::Button) );
+
+ // the bright side
+ p->setPen( cg.button().dark() );
+ p->drawLine( x, y, x + w - 1, y );
+ p->drawLine( x, y, x, y + h - 1 );
+
+ p->setPen( cg.button() );
+ p->drawLine( x + 1, y + 1,
+ x + w - 2, y + 1 );
+ p->drawLine( x + 1, y + 1,
+ x + 1, y + h - 2 );
+
+ p->setPen( cg.light() );
+ p->drawLine( x + 2, y + 2,
+ x + 2, y + h - 2 );
+ p->drawLine( x + 2, y + 2,
+ x + w - 2, y + 2 );
+ // the dark side!
+
+ p->setPen( cg.mid() );
+ p->drawLine( x + 3, y + h - 3,
+ x + w - 3,
+ y + h - 3 );
+ p->drawLine( x + w - 3, y + 3,
+ x + w - 3,
+ y + h - 3 );
+ p->setPen( cg.dark() );
+ p->drawLine( x + 2, y + h - 2,
+ x + w - 2,
+ y + h - 2 );
+ p->drawLine( x + w - 2, y + 2,
+ x + w - 2,
+ y + h - 2 );
+
+ p->setPen( cg.dark().dark() );
+ p->drawLine( x + 1, y + h - 1,
+ x + w - 1,
+ y + h - 1 );
+ p->drawLine( x + w - 1, y + 1,
+ x + w - 1,
+ y + h - 1 );
+ } else {
+ p->fillRect( x + 3, y + 3, w - 6,
+ h - 6,
+ cg.brush( TQColorGroup::Mid ) );
+
+ // the dark side
+ p->setPen( cg.dark().dark().dark() );
+ p->drawLine( x, y, x + w - 1, y );
+ p->drawLine( x, y, x, y + h - 1 );
+
+ p->setPen( cg.dark().dark() );
+ p->drawLine( x + 1, y + 1,
+ x + w - 2, y + 1 );
+ p->drawLine( x + 1, y + 1,
+ x + 1, y + h - 2 );
+
+ p->setPen( cg.mid().dark() );
+ p->drawLine( x + 2, y + 2,
+ x + 2, y + w - 2 );
+ p->drawLine( x + 2, y + 2,
+ x + w - 2, y + 2 );
+
+
+ // the bright side!
+
+ p->setPen( cg.button() );
+ p->drawLine( x + 2, y + h - 3,
+ x + w - 3,
+ y + h - 3 );
+ p->drawLine( x + w - 3, y + 3,
+ x + w - 3,
+ y + h - 3 );
+
+ p->setPen( cg.midlight() );
+ p->drawLine( x + 1, y + h - 2,
+ x + w - 2,
+ y + h - 2 );
+ p->drawLine( x + w - 2, y + 1,
+ x + w - 2,
+ y + h - 2 );
+
+ p->setPen( cg.dark() );
+ p->drawLine( x, y + h - 1,
+ x + w - 1,
+ y + h - 1 );
+ p->drawLine( x + w - 1, y,
+ x + w - 1,
+ y + h - 1 );
+
+
+ // corners
+ p->setPen( mixedColor(cg.dark().dark().dark(),
+ cg.dark()) );
+ p->drawPoint( x, y + h - 1 );
+ p->drawPoint( x + w - 1, y );
+
+ p->setPen( mixedColor(cg.dark().dark(), cg.midlight()) );
+ p->drawPoint( x + 1, y + h - 2 );
+ p->drawPoint( x + w - 2, y + 1 );
+
+ p->setPen( mixedColor(cg.mid().dark(), cg.button() ) );
+ p->drawPoint( x + 2, y + h - 3 );
+ p->drawPoint( x + w - 3, y + 2 );
+ }
+ }
+ p->setPen( oldPen );
+ break;
+ }
+ case PE_ButtonCommand:
+ {
+ TQPen oldPen = p->pen();
+ int x,
+ y,
+ w,
+ h;
+ r.rect( &x, &y, &w, &h);
+
+ if ( !(flags & (Style_Down | Style_On)) ) {
+ p->fillRect( x+3, y+3, w-6, h-6,
+ cg.brush( TQColorGroup::Button ));
+ // the bright side
+ p->setPen( cg.shadow() );
+ p->drawLine( x, y, x+w-1, y );
+ p->drawLine( x, y, x, y + h - 1 );
+
+ p->setPen( cg.button() );
+ p->drawLine( x + 1, y + 1, x + w - 2, y + 1 );
+ p->drawLine( x + 1, y + 1, x + 1, y + h - 2 );
+
+ p->setPen( cg.light() );
+ p->drawLine( x + 2, y + 2, x + 2, y + h - 2 );
+ p->drawLine( x + 2, y + 2, x + w - 2, y + 2 );
+
+
+ // the dark side!
+
+ p->setPen( cg.mid() );
+ p->drawLine( x + 3, y + h - 3 ,x + w - 3, y + h - 3 );
+ p->drawLine( x + w - 3, y + 3, x + w - 3, y + h - 3 );
+
+ p->setPen( cg.dark() );
+ p->drawLine( x + 2, y + h - 2, x + w - 2, y + h - 2 );
+ p->drawLine( x + w - 2, y + 2, x + w - 2, y + h - 2 );
+
+ p->setPen( cg.shadow() );
+ p->drawLine( x + 1, y + h - 1, x + w - 1, y + h - 1 );
+ p->drawLine( x + w - 1, y, x + w - 1, y + h - 1 );
+
+
+ // top left corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x, y );
+ p->drawPoint( x + 1, y );
+ p->drawPoint( x, y+1 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + 1, y + 1 );
+ p->setPen( cg.button() );
+ p->drawPoint( x + 2, y + 2 );
+ p->setPen( Qt::white );
+ p->drawPoint( x + 3, y + 3 );
+ // bottom left corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x, y + h - 1 );
+ p->drawPoint( x + 1, y + h - 1 );
+ p->drawPoint( x, y + h - 2 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + 1, y + h - 2 );
+ p->setPen( cg.dark() );
+ p->drawPoint( x + 2, y + h - 3 );
+ // top right corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x + w -1, y );
+ p->drawPoint( x + w - 2, y );
+ p->drawPoint( x + w - 1, y + 1 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + w - 2, y + 1 );
+ p->setPen( cg.dark() );
+ p->drawPoint( x + w - 3, y + 2 );
+ // bottom right corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x + w - 1, y + h - 1 );
+ p->drawPoint( x + w - 2, y + h - 1 );
+ p->drawPoint( x + w - 1, y + h - 2 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + w - 2, y + h - 2 );
+ p->setPen( cg.dark() );
+ p->drawPoint( x + w - 3, y + h - 3 );
+ p->setPen( cg.mid() );
+ p->drawPoint( x + w - 4, y + h - 4 );
+
+ } else {
+ p->fillRect( x + 2, y + 2, w - 4, h - 4,
+ cg.brush(TQColorGroup::Dark) );
+
+ // the dark side
+ p->setPen( cg.shadow() );
+ p->drawLine( x, y, x + w - 1, y );
+ p->drawLine( x, y, x, y + h - 1 );
+
+ p->setPen( cg.dark().dark() );
+ p->drawLine( x + 1, y + 1, x + w - 2, y + 1 );
+ p->drawLine( x + 1, y + 1, x + 1, y + h - 2 );
+
+ // the bright side!
+
+ p->setPen( cg.button() );
+ p->drawLine( x + 1, y + h - 2, x + w - 2, y + h - 2 );
+ p->drawLine( x + w - 2, y + 1, x + w - 2, y + h - 2 );
+
+ p->setPen( cg.dark() );
+ p->drawLine( x, y + h - 1, x + w - 1, y + h - 1 );
+ p->drawLine( x + w - 1, y, x + w - 1, y + h - 1 );
+
+ // top left corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x, y );
+ p->drawPoint( x + 1, y );
+ p->drawPoint( x, y + 1 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + 1, y + 1 );
+ p->setPen( cg.dark().dark() );
+ p->drawPoint( x + 3, y + 3 );
+ // bottom left corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x, y + h - 1 );
+ p->drawPoint( x + 1, y + h - 1 );
+ p->drawPoint( x, y + h - 2 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + 1, y + h - 2 );
+ // top right corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x + w - 1, y );
+ p->drawPoint( x + w - 2, y );
+ p->drawPoint( x + w - 1, y + 1 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + w - 2, y + 1 );
+ // bottom right corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x + w - 1, y + h - 1 );
+ p->drawPoint( x + w - 2, y + h - 1 );
+ p->drawPoint( x + w - 1, y + h - 2 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + w - 2, y + h - 2 );
+ p->setPen( cg.dark() );
+ p->drawPoint( x + w - 3, y + h - 3 );
+ p->setPen( cg.mid() );
+ p->drawPoint( x + w - 4, y + h - 4 );
+ }
+ p->setPen( oldPen );
+ break;
+ }
+ case PE_Indicator:
+ {
+ tqdrawPrimitive( PE_ButtonBevel, p, TQRect(r.x(), r.y(),
+ r.width() - 2, r.height()),
+ cg, flags );
+ p->fillRect( r.x() + r.width() - 2, r.y(), 2, r.height(),
+ cg.brush( TQColorGroup::Background ) );
+ p->setPen( cg.shadow() );
+ p->drawRect( r.x(), r.y(), r.width() - 2, r.height() );
+
+ static const TQCOORD nochange_mark[] = { 3,5, 9,5, 3,6, 9,6 };
+ static const TQCOORD check_mark[] = {
+ 3,5, 5,5, 4,6, 5,6, 5,7, 6,7, 5,8, 6,8, 6,9, 9,9,
+ 6,10, 8,10, 7,11, 8,11, 7,12, 7,12, 8,8, 9,8, 8,7, 10,7,
+ 9,6, 10,6, 9,5, 11,5, 10,4, 11,4, 10,3, 12,3,
+ 11,2, 12,2, 11,1, 13,1, 12,0, 13,0 };
+ if ( !(flags & Style_Off) ) {
+ TQPen oldPen = p->pen();
+ int x1 = r.x();
+ int y1 = r.y();
+ if ( flags & Style_Down ) {
+ x1++;
+ y1++;
+ }
+ TQPointArray amark;
+ if ( flags & Style_On ) {
+ amark = TQPointArray( sizeof(check_mark)/(sizeof(TQCOORD)*2),
+ check_mark );
+ // ### KLUDGE!!
+ flags ^= Style_On;
+ flags ^= Style_Down;
+ } else if ( flags & Style_NoChange ) {
+ amark = TQPointArray( sizeof(nochange_mark)
+ / (sizeof(TQCOORD) * 2),
+ nochange_mark );
+ }
+
+ amark.translate( x1 + 1, y1 + 1 );
+ p->setPen( cg.dark() );
+ p->drawLineSegments( amark );
+ amark.translate( -1, -1 );
+ p->setPen( cg.foreground() );
+ p->drawLineSegments( amark );
+ p->setPen( oldPen );
+ }
+ break;
+ }
+ case PE_IndicatorMask:
+ {
+ int x,
+ y,
+ w,
+ h;
+ r.rect( &x, &y, &w, &h );
+ p->fillRect( x, y, w - 2, h, Qt::color1);
+ if ( flags & Style_Off ) {
+ TQPen oldPen = p->pen();
+ p->setPen ( TQPen(Qt::color1, 2));
+ p->drawLine( x + 2, y + h / 2 - 1,
+ x + w / 2 - 1, y + h - 4 );
+ p->drawLine( x + w / 2 - 1, y + h - 4,
+ x + w, 0);
+ p->setPen( oldPen );
+ }
+ break;
+ }
+ case PE_ExclusiveIndicator:
+ {
+#define TQCOORDARRLEN(x) sizeof(x) / (sizeof(TQCOORD) * 2 )
+ bool down = flags & Style_Down;
+ bool on = flags & Style_On;
+
+ static const TQCOORD pts1[] = { // normal circle
+ 5,0, 8,0, 9,1, 10,1, 11,2, 12,3, 12,4, 13,5,
+ 13,8, 12,9, 12,10, 11,11, 10,12, 9,12, 8,13,
+ 5,13, 4,12, 3,12, 2,11, 1,10, 1,9, 0,8, 0,5,
+ 1,4, 1,3, 2,2, 3,1, 4,1 };
+ static const TQCOORD pts2[] = { // top left shadow
+ 5,1, 8,1, 3,2, 7,2, 2,3, 5,3, 2,4, 4,4,
+ 1,5, 3,5, 1,6, 1,8, 2,6, 2,7 };
+ static const TQCOORD pts3[] = { // bottom right, dark
+ 5,12, 8,12, 7,11, 10,11, 8,10, 11,10,
+ 9,9, 11,9, 10,8, 12,8, 11,7, 11,7,
+ 12,5, 12,7 };
+ static const TQCOORD pts4[] = { // bottom right, light
+ 5,12, 8,12, 7,11, 10,11, 9,10, 11,10,
+ 10,9, 11,9, 11,7, 11,8, 12,5, 12,8 };
+ static const TQCOORD pts5[] = { // check mark
+ 6,4, 8,4, 10,6, 10,8, 8,10, 6,10, 4,8, 4,6 };
+ static const TQCOORD pts6[] = { // check mark extras
+ 4,5, 5,4, 9,4, 10,5, 10,9, 9,10, 5,10, 4,9 };
+ int x, y;
+ x = r.x();
+ y = r.y();
+ p->eraseRect( r );
+ p->setBrush( (down||on) ? cg.brush( TQColorGroup::Dark )
+ : cg.brush( TQColorGroup::Button) );
+ p->setPen( Qt::NoPen );
+ p->drawEllipse( x, y, 13, 13 );
+ p->setPen( cg.shadow() );
+ TQPointArray a( TQCOORDARRLEN(pts1), pts1 );
+ a.translate( x, y );
+ p->drawPolyline( a ); // draw normal circle
+ TQColor tc, bc;
+ const TQCOORD *bp;
+ int bl;
+ if ( down || on ) { // pressed down or on
+ tc = cg.dark().dark();
+ bc = cg.light();
+ bp = pts4;
+ bl = TQCOORDARRLEN(pts4);
+ } else { // released
+ tc = cg.light();
+ bc = cg.dark();
+ bp = pts3;
+ bl = TQCOORDARRLEN(pts3);
+ }
+ p->setPen( tc );
+ a.setPoints( TQCOORDARRLEN(pts2), pts2 );
+ a.translate( x, y );
+ p->drawLineSegments( a ); // draw top shadow
+ p->setPen( bc );
+ a.setPoints( bl, bp );
+ a.translate( x, y );
+ p->drawLineSegments( a );
+ if ( on ) { // draw check mark
+ int x1 = x,
+ y1 = y;
+ p->setBrush( cg.foreground() );
+ p->setPen( cg.foreground() );
+ a.setPoints( TQCOORDARRLEN(pts5), pts5 );
+ a.translate( x1, y1 );
+ p->drawPolygon( a );
+ p->setBrush( Qt::NoBrush );
+ p->setPen( cg.dark() );
+ a.setPoints( TQCOORDARRLEN(pts6), pts6 );
+ a.translate( x1, y1 );
+ p->drawLineSegments( a );
+ }
+ break;
+ }
+
+ case PE_ExclusiveIndicatorMask:
+ {
+ static const TQCOORD pts1[] = { // normal circle
+ 5,0, 8,0, 9,1, 10,1, 11,2, 12,3, 12,4, 13,5,
+ 13,8, 12,9, 12,10, 11,11, 10,12, 9,12, 8,13,
+ 5,13, 4,12, 3,12, 2,11, 1,10, 1,9, 0,8, 0,5,
+ 1,4, 1,3, 2,2, 3,1, 4,1 };
+ TQPointArray a(TQCOORDARRLEN(pts1), pts1);
+ a.translate(r.x(), r.y());
+ p->setPen(Qt::color1);
+ p->setBrush(Qt::color1);
+ p->drawPolygon(a);
+ break;
+ }
+ case PE_ScrollBarAddLine:
+ {
+ tqdrawPrimitive( PE_ButtonBevel, p, r, cg,
+ (flags & Style_Enabled) | ((flags & Style_Down)
+ ? Style_Sunken
+ : Style_Raised) );
+ p->setPen( cg.shadow() );
+ p->drawRect( r );
+ tqdrawPrimitive( ((flags & Style_Horizontal) ? PE_ArrowRight
+ : PE_ArrowDown), p, TQRect(r.x() + 2,
+ r.y() + 2,
+ r.width() - 4,
+ r.height() - 4),
+ cg, flags );
+ break;
+ }
+ case PE_ScrollBarSubLine:
+ {
+ tqdrawPrimitive( PE_ButtonBevel, p, r, cg,
+ (flags & Style_Enabled) | ((flags & Style_Down)
+ ? Style_Sunken
+ : Style_Raised) );
+ p->setPen( cg.shadow() );
+ p->drawRect( r );
+ tqdrawPrimitive( ((flags & Style_Horizontal) ? PE_ArrowLeft
+ : PE_ArrowUp ), p, TQRect(r.x() + 2,
+ r.y() + 2,
+ r.width() - 4,
+ r.height() - 4),
+ cg, flags );
+ break;
+ }
+ case PE_ScrollBarAddPage:
+ case PE_ScrollBarSubPage:
+ {
+ TQPen oldPen = p->pen();
+ if ( r.width() < 3 || r.height() < 3 ) {
+ p->fillRect( r, cg.brush(TQColorGroup::Mid) );
+ p->setPen( cg.shadow() );
+ p->drawRect( r );
+ p->setPen( oldPen );
+ } else {
+ int x,
+ y,
+ w,
+ h;
+ r.rect( &x, &y, &w, &h );
+ if ( flags & Style_Horizontal ) {
+ p->fillRect( x + 2, y + 2, w - 2,
+ h - 4,
+ cg.brush(TQColorGroup::Mid) );
+ // the dark side
+ p->setPen( cg.dark().dark() );
+ p->drawLine( x, y, x + w - 1, y );
+ p->setPen( cg.shadow());
+ p->drawLine( x, y, x, y + h - 1 );
+
+ p->setPen( cg.mid().dark());
+ p->drawLine( x + 1, y + 1, x + w - 1,
+ y + 1 );
+ p->drawLine( x + 1, y + 1, x + 1,
+ y + h - 2 );
+
+ // the bright side!
+
+ p->setPen( cg.button());
+ p->drawLine( x + 1, y + h - 2,
+ x + w - 1,
+ y + h - 2 );
+ p->setPen( cg.shadow());
+ p->drawLine( x, y + h - 1,
+ x + w - 1,
+ y + h - 1 );
+
+ } else {
+ p->fillRect( x + 2, y + 2, w - 4,
+ h - 2,
+ cg.brush(TQColorGroup::Mid) );
+
+ // the dark side
+ p->setPen( cg.dark().dark() );
+ p->drawLine( x, y, x + w - 1, y );
+ p->setPen( cg.shadow() );
+ p->drawLine( x, y, x, y + h - 1 );
+
+ p->setPen( cg.mid().dark() );
+ p->drawLine( x + 1, y + 1, x + w - 2,
+ y + 1 );
+ p->drawLine( x + 1, y + 1, x + 1,
+ y + h - 1 );
+
+ // the bright side!
+ p->setPen( cg.button() );
+ p->drawLine( x + w - 2, y + 1,
+ x + w - 2,
+ y + h - 1 );
+
+ p->setPen( cg.shadow() );
+ p->drawLine( x + w - 1, y,
+ x + w - 1,
+ y + h - 1 );
+
+ }
+ }
+ p->setPen( oldPen );
+ break;
+ }
+ case PE_ScrollBarSlider:
+ {
+ TQPoint bo = p->brushOrigin();
+ p->setBrushOrigin( r.topLeft() );
+ tqdrawPrimitive( PE_ButtonBevel, p, r, cg, Style_Raised );
+ p->setBrushOrigin( bo );
+ drawRiffles( p, r.x(), r.y(), r.width(), r.height(), cg,
+ flags & Style_Horizontal );
+ p->setPen( cg.shadow() );
+ p->drawRect( r );
+ if ( flags & Style_HasFocus ) {
+ tqdrawPrimitive( PE_FocusRect, p, TQRect(r.x() + 2, r.y() + 2,
+ r.width() - 5,
+ r.height() - 5 ),
+ cg, flags );
+ }
+ break;
+ }
+ default:
+ TQWindowsStyle::tqdrawPrimitive( pe, p, r, cg, flags, opt );
+ break;
+ }
+
+}
+
+/*!\reimp
+ */
+void TQPlatinumStyle::tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how,
+ const TQStyleOption& opt ) const
+{
+ switch( element ) {
+ case CE_PushButton:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ TQColorGroup myCg( cg );
+ const TQPushButton *btn;
+ int x1, y1, x2, y2;
+ bool useBevelButton;
+ SFlags flags;
+ flags = Style_Default;
+ btn = (const TQPushButton*)widget;
+ p->setBrushOrigin( -widget->backgroundOffset().x(),
+ -widget->backgroundOffset().y() );
+
+ // take care of the flags based on what we know...
+ if ( btn->isDown() )
+ flags |= Style_Down;
+ if ( btn->isOn() )
+ flags |= Style_On;
+ if ( btn->isEnabled() )
+ flags |= Style_Enabled;
+ if ( btn->isDefault() )
+ flags |= Style_Default;
+ if (! btn->isFlat() && !(flags & Style_Down))
+ flags |= Style_Raised;
+
+ r.coords( &x1, &y1, &x2, &y2 );
+
+ p->setPen( cg.foreground() );
+ p->setBrush( TQBrush(cg.button(), Qt::NoBrush) );
+
+ TQBrush fill;
+ if ( btn->isDown() ) {
+ fill = cg.brush( TQColorGroup::Dark );
+ // this could be done differently, but this
+ // makes a down Bezel drawn correctly...
+ myCg.setBrush( TQColorGroup::Mid, fill );
+ } else if ( btn->isOn() ) {
+ fill = TQBrush( cg.mid(), Qt::Dense4Pattern );
+ myCg.setBrush( TQColorGroup::Mid, fill );
+ }
+ // to quote the old TQPlatinumStlye drawPushButton...
+ // small or square image buttons as well as toggle buttons are
+ // bevel buttons (what a heuristic....)
+ if ( btn->isToggleButton()
+ || ( btn->pixmap() &&
+ (btn->width() * btn->height() < 1600 ||
+ TQABS( btn->width() - btn->height()) < 10 )) )
+ useBevelButton = TRUE;
+ else
+ useBevelButton = FALSE;
+
+ int diw = tqpixelMetric( PM_ButtonDefaultIndicator, widget );
+ if ( btn->isDefault() ) {
+ x1 += 1;
+ y1 += 1;
+ x2 -= 1;
+ y2 -= 1;
+ TQColorGroup cg2( myCg );
+ SFlags myFlags = flags;
+ // don't draw the default button sunken, unless it's necessary.
+ if ( myFlags & Style_Down )
+ myFlags ^= Style_Down;
+ if ( myFlags & Style_Sunken )
+ myFlags ^= Style_Sunken;
+
+ cg2.setColor( TQColorGroup::Button, cg.mid() );
+ if ( useBevelButton ) {
+ tqdrawPrimitive( PE_ButtonBevel, p, TQRect( x1, y1,
+ x2 - x1 + 1,
+ y2 - y1 + 1 ),
+ myCg, myFlags, opt );
+ } else {
+ tqdrawPrimitive( PE_ButtonCommand, p, TQRect( x1, y1,
+ x2 - x1 + 1,
+ y2 - y1 + 1 ),
+ cg2, myFlags, opt );
+ }
+ }
+
+ if ( btn->isDefault() || btn->autoDefault() ) {
+ x1 += diw;
+ y1 += diw;
+ x2 -= diw;
+ y2 -= diw;
+ }
+
+ if ( !btn->isFlat() || btn->isOn() || btn->isDown() ) {
+ if ( useBevelButton ) {
+ // fix for toggle buttons...
+ if ( flags & (Style_Down | Style_On) )
+ flags |= Style_Sunken;
+ tqdrawPrimitive( PE_ButtonBevel, p, TQRect( x1, y1,
+ x2 - x1 + 1,
+ y2 - y1 + 1 ),
+ myCg, flags, opt );
+ } else {
+
+ tqdrawPrimitive( PE_ButtonCommand, p, TQRect( x1, y1,
+ x2 - x1 + 1,
+ y2 - y1 + 1 ),
+ myCg, flags, opt );
+ }
+ }
+
+
+ if ( p->brush().style() != Qt::NoBrush )
+ p->setBrush( Qt::NoBrush );
+ break;
+#endif
+ }
+ case CE_PushButtonLabel:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *btn;
+ bool on;
+ int x, y, w, h;
+ SFlags flags;
+ flags = Style_Default;
+ btn = (const TQPushButton*)widget;
+ on = btn->isDown() || btn->isOn();
+ r.rect( &x, &y, &w, &h );
+ if ( btn->isMenuButton() ) {
+ int dx = tqpixelMetric( PM_MenuButtonIndicator, widget );
+
+ TQColorGroup g = cg;
+ int xx = x + w - dx - 4;
+ int yy = y - 3;
+ int hh = h + 6;
+
+ if ( !on ) {
+ p->setPen( g.mid() );
+ p->drawLine( xx, yy + 2, xx, yy + hh - 3 );
+ p->setPen( g.button() );
+ p->drawLine( xx + 1, yy + 1, xx + 1, yy + hh - 2 );
+ p->setPen( g.light() );
+ p->drawLine( xx + 2, yy + 2, xx + 2, yy + hh - 2 );
+ }
+ if ( btn->isEnabled() )
+ flags |= Style_Enabled;
+ tqdrawPrimitive( PE_ArrowDown, p, TQRect(x + w - dx - 1, y + 2,
+ dx, h - 4),
+ g, flags, opt );
+ w -= dx;
+ }
+#ifndef TQT_NO_ICONSET
+ if ( btn->iconSet() && !btn->iconSet()->isNull() ) {
+ TQIconSet::Mode mode = btn->isEnabled()
+ ? TQIconSet::Normal : TQIconSet::Disabled;
+ if ( mode == TQIconSet::Normal && btn->hasFocus() )
+ mode = TQIconSet::Active;
+ TQIconSet::State state = TQIconSet::Off;
+ if ( btn->isToggleButton() && btn->isOn() )
+ state = TQIconSet::On;
+ TQPixmap pixmap = btn->iconSet()->pixmap( TQIconSet::Small,
+ mode, state );
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ p->drawPixmap( x + 2, y + h / 2 - pixh / 2, pixmap );
+ x += pixw + 4;
+ w -= pixw + 4;
+ }
+#endif
+ drawItem( p, TQRect( x, y, w, h ),
+ TQt::AlignCenter | TQt::ShowPrefix,
+ btn->tqcolorGroup(), btn->isEnabled(),
+ btn->pixmap(), btn->text(), -1,
+ on ? TQT_TQCOLOR_CONST(&btn->tqcolorGroup().brightText())
+ : TQT_TQCOLOR_CONST(&btn->tqcolorGroup().buttonText()) );
+ if ( btn->hasFocus() )
+ tqdrawPrimitive( PE_FocusRect, p,
+ subRect(SR_PushButtonFocusRect, widget),
+ cg, flags );
+ break;
+#endif
+ }
+ default:
+ TQWindowsStyle::tqdrawControl( element, p, widget, r, cg, how, opt );
+ break;
+ }
+}
+
+/*!\reimp
+ */
+void TQPlatinumStyle::tqdrawComplexControl( TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how,
+ SCFlags sub,
+ SCFlags subActive,
+ const TQStyleOption& opt ) const
+{
+ switch ( control ) {
+ case CC_ComboBox:
+ {
+ int x,
+ y,
+ w,
+ h;
+ r.rect( &x, &y, &w, &h );
+ p->fillRect( x + 2, y + 2, w - 4,
+ h - 4, cg.brush(TQColorGroup::Button) );
+ // the bright side
+ p->setPen(cg.shadow());
+ p->drawLine( x, y, x + w - 1, y );
+ p->drawLine( x, y, x, y + h - 1 );
+
+ p->setPen( cg.light() );
+ p->drawLine( x + 1, y + 1,
+ x + w - 2, y + 1 );
+ p->drawLine( x + 1, y + 1,
+ x + 1, y + h - 2 );
+
+ // the dark side!
+
+
+ p->setPen( cg.mid() );
+ p->drawLine( x + 2, y + h - 2,
+ x + w - 2, y + h - 2 );
+ p->drawLine( x + w - 2, y + 2,
+ x + w - 2, y + h - 2 );
+
+ p->setPen (cg.shadow() );
+ p->drawLine( x + 1, y + h - 1,
+ x + w - 1, y + h - 1 );
+ p->drawLine( x + w - 1, y,
+ x + w - 1, y + h - 1 );
+
+ // top left corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x, y );
+ p->drawPoint( x + 1, y );
+ p->drawPoint( x, y + 1 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + 1, y + 1 );
+ p->setPen( Qt::white );
+ p->drawPoint( x + 3, y + 3 );
+ // bottom left corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x, y + h - 1 );
+ p->drawPoint( x + 1, y + h - 1 );
+ p->drawPoint( x, y + h - 2 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + 1, y + h - 2 );
+ // top right corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x + w - 1, y );
+ p->drawPoint( x + w - 2, y );
+ p->drawPoint( x + w - 1, y + 1 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + w - 2, y + 1 );
+ // bottom right corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x + w - 1, y + h - 1 );
+ p->drawPoint( x + w - 2, y + h - 1 );
+ p->drawPoint( x + w - 1, y + h - 2 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x + w - 2, y + h - 2 );
+ p->setPen( cg.dark() );
+ p->drawPoint( x + w - 3, y + h - 3 );
+
+ if ( sub & SC_ComboBoxArrow ) {
+ TQRect rTmp = querySubControlMetrics( CC_ComboBox, widget,
+ SC_ComboBoxArrow, opt );
+ int xx = rTmp.x(),
+ yy = rTmp.y(),
+ ww = rTmp.width(),
+ hh = rTmp.height();
+ // the bright side
+
+ p->setPen( cg.mid() );
+ p->drawLine( xx, yy+2, xx, yy+hh-3 );
+
+ p->setPen( cg.button() );
+ p->drawLine( xx+1, yy+1, xx+ww-2, yy+1 );
+ p->drawLine( xx+1, yy+1, xx+1, yy+hh-2 );
+
+ p->setPen( cg.light() );
+ p->drawLine( xx+2, yy+2, xx+2, yy+hh-2 );
+ p->drawLine( xx+2, yy+2, xx+ww-2, yy+2 );
+
+
+ // the dark side!
+
+ p->setPen( cg.mid() );
+ p->drawLine( xx+3, yy+hh-3 ,xx+ww-3, yy+hh-3 );
+ p->drawLine( xx+ww-3, yy+3, xx+ww-3, yy+hh-3 );
+
+ p->setPen( cg.dark() );
+ p->drawLine( xx+2, yy+hh-2 ,xx+ww-2, yy+hh-2 );
+ p->drawLine( xx+ww-2, yy+2, xx+ww-2, yy+hh-2 );
+
+ p->setPen( cg.shadow() );
+ p->drawLine( xx+1, yy+hh-1,xx+ww-1, yy+hh-1 );
+ p->drawLine( xx+ww-1, yy, xx+ww-1, yy+hh-1 );
+
+ // top right corner:
+ p->setPen( cg.background() );
+ p->drawPoint( xx + ww - 1, yy );
+ p->drawPoint( xx + ww - 2, yy );
+ p->drawPoint( xx + ww - 1, yy + 1 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( xx + ww - 2, yy + 1 );
+ // bottom right corner:
+ p->setPen( cg.background() );
+ p->drawPoint( xx + ww - 1, yy + hh - 1 );
+ p->drawPoint( xx + ww - 2, yy + hh - 1 );
+ p->drawPoint( xx + ww - 1, yy + hh - 2 );
+ p->setPen( cg.shadow() );
+ p->drawPoint( xx + ww - 2, yy + hh - 2 );
+ p->setPen( cg.dark() );
+ p->drawPoint( xx + ww - 3, yy + hh - 3 );
+ p->setPen( cg.mid() );
+ p->drawPoint( xx + ww - 4, yy + hh - 4 );
+
+ // and the arrows
+ p->setPen( cg.foreground() );
+ TQPointArray a ;
+ a.setPoints( 7, -3,1, 3,1, -2,0, 2,0, -1,-1, 1,-1, 0,-2 );
+ a.translate( xx + ww / 2, yy + hh / 2 - 3 );
+ p->drawLineSegments( a, 0, 3 ); // draw arrow
+ p->drawPoint( a[6] );
+ a.setPoints( 7, -3,-1, 3,-1, -2,0, 2,0, -1,1, 1,1, 0,2 );
+ a.translate( xx + ww / 2, yy + hh / 2 + 2 );
+ p->drawLineSegments( a, 0, 3 ); // draw arrow
+ p->drawPoint( a[6] );
+
+ }
+#ifndef TQT_NO_COMBOBOX
+ if ( sub & SC_ComboBoxEditField ) {
+ const TQComboBox *cmb;
+ cmb = (const TQComboBox*)widget;
+ // sadly this is pretty much the windows code, except
+ // for the first fillRect call...
+ TQRect re =
+ TQStyle::tqvisualRect( querySubControlMetrics( CC_ComboBox,
+ widget,
+ SC_ComboBoxEditField ),
+ widget );
+ if ( cmb->hasFocus() && !cmb->editable() )
+ p->fillRect( re.x() + 1, re.y() + 1,
+ re.width() - 2, re.height() - 2,
+ cg.brush( TQColorGroup::Highlight ) );
+
+ if ( cmb->hasFocus() ) {
+ p->setPen( cg.highlightedText() );
+ p->setBackgroundColor( cg.highlight() );
+ } else {
+ p->setPen( cg.text() );
+ p->setBackgroundColor( cg.background() );
+ }
+
+ if ( cmb->hasFocus() && !cmb->editable() ) {
+ TQRect re =
+ TQStyle::tqvisualRect( subRect( SR_ComboBoxFocusRect,
+ cmb ),
+ widget );
+ tqdrawPrimitive( PE_FocusRect, p, re, cg,
+ Style_FocusAtBorder,
+ TQStyleOption(cg.highlight()));
+ }
+ if ( cmb->editable() ) {
+ // need this for the moment...
+ // was the code in comboButton rect
+ TQRect ir( x + 3, y + 3,
+ w - 6 - 16, h - 6 );
+ if ( TQApplication::reverseLayout() )
+ ir.moveBy( 16, 0 );
+ // end comboButtonRect...
+ ir.setRect( ir.left() - 1, ir.top() - 1, ir.width() + 2,
+ ir.height() + 2 );
+ qDrawShadePanel( p, ir, cg, TRUE, 2, 0 );
+ }
+ }
+#endif
+ break;
+ }
+ case CC_Slider:
+ {
+#ifndef TQT_NO_SLIDER
+ const TQSlider *slider = (const TQSlider *) widget;
+ int thickness = tqpixelMetric( PM_SliderControlThickness, widget );
+ int len = tqpixelMetric( PM_SliderLength, widget );
+ int ticks = slider->tickmarks();
+
+ TQRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove,
+ opt),
+ handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle,
+ opt);
+
+ if ((sub & SC_SliderGroove) && groove.isValid()) {
+ p->fillRect( groove, cg.brush(TQColorGroup::Background) );
+
+ int x, y, w, h;
+ int mid = thickness / 2;
+
+ if ( ticks & TQSlider::Above )
+ mid += len / 8;
+ if ( ticks & TQSlider::Below )
+ mid -= len / 8;
+
+ if ( slider->orientation() == Qt::Horizontal ) {
+ x = 0;
+ y = groove.y() + mid - 3;
+ w = slider->width();
+ h = 7;
+ } else {
+ x = groove.x() + mid - 3;
+ y = 0;
+ w = 7;
+ h = slider->height();
+ }
+
+ p->fillRect( x, y, w, h, cg.brush( TQColorGroup::Dark ));
+ // the dark side
+ p->setPen( cg.dark() );
+ p->drawLine( x, y, x + w - 1, y );
+ p->drawLine( x, y, x, y + h - 1);
+ p->setPen( cg.shadow() );
+ p->drawLine( x + 1, y + 1, x + w - 2, y + 1 );
+ p->drawLine( x + 1, y + 1, x + 1, y + h - 2 );
+ // the bright side!
+ p->setPen(cg.shadow());
+ p->drawLine( x + 1, y + h - 2, x + w - 2, y + h - 2 );
+ p->drawLine( x + w - 2, y + 1, x + w - 2, y + h - 2 );
+ p->setPen( cg.light() );
+ p->drawLine( x, y + h - 1, x + w - 1, y + h - 1 );
+ p->drawLine( x + w - 1, y, x + w - 1, y + h - 1 );
+ // top left corner:
+ p->setPen(cg.background());
+ p->drawPoint( x, y );
+ p->drawPoint( x + 1, y );
+ p->drawPoint( x, y + 1 );
+ p->setPen(cg.shadow());
+ p->drawPoint( x + 1, y + 1 );
+ // bottom left corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x, y + h - 1 );
+ p->drawPoint( x + 1, y + h - 1 );
+ p->drawPoint( x, y + h - 2 );
+ p->setPen( cg.light() );
+ p->drawPoint( x + 1, y + h - 2 );
+ // top right corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x + w - 1, y );
+ p->drawPoint( x + w - 2, y );
+ p->drawPoint( x + w - 1, y + 1 );
+ p->setPen( cg.dark() );
+ p->drawPoint( x + w - 2, y + 1 );
+ // bottom right corner:
+ p->setPen( cg.background() );
+ p->drawPoint( x + w - 1, y + h - 1 );
+ p->drawPoint( x + w - 2, y + h - 1 );
+ p->drawPoint( x + w - 1, y + h - 2 );
+ p->setPen( cg.light() );
+ p->drawPoint( x + w - 2, y + h - 2 );
+ p->setPen( cg.dark() );
+ p->drawPoint( x + w - 3, y + h - 3 );
+ // ### end slider groove
+
+ if ( how & Style_HasFocus )
+ tqdrawPrimitive( PE_FocusRect, p, groove, cg );
+ }
+
+ if ((sub & SC_SliderHandle) && handle.isValid()) {
+ const TQColor c0 = cg.shadow();
+ const TQColor c1 = cg.dark();
+ const TQColor c3 = cg.light();
+
+ int x1 = handle.x();
+ int x2 = handle.x() + handle.width() - 1;
+ int y1 = handle.y();
+ int y2 = handle.y() + handle.height() - 1;
+ int mx = handle.width() / 2;
+ int my = handle.height() / 2;
+
+ if ( slider->orientation() == Qt::Vertical ) {
+ // Background
+ TQBrush oldBrush = p->brush();
+ p->setBrush( cg.brush( TQColorGroup::Button ) );
+ p->setPen( Qt::NoPen );
+ TQPointArray a(6);
+ a.setPoint( 0, x1 + 1, y1 + 1 );
+ a.setPoint( 1, x2 - my + 2, y1 + 1 );
+ a.setPoint( 2, x2 - 1, y1 + my - 1 );
+ a.setPoint( 3, x2 - 1, y2 - my + 1 );
+ a.setPoint( 4, x2 - my + 2, y2 - 1 );
+ a.setPoint( 5, x1 + 1, y2 - 1 );
+ p->drawPolygon( a );
+ p->setBrush( oldBrush );
+
+ // shadow border
+ p->setPen( c0 );
+ p->drawLine( x1, y1 + 1, x1,y2 - 1 );
+ p->drawLine( x2 - my + 2, y1, x2, y1 + my - 2 );
+ p->drawLine( x2 - my + 2, y2, x2, y1 + my + 2 );
+ p->drawLine( x2, y1 + my - 2, x2, y1 + my + 2 );
+ p->drawLine( x1 + 1, y1, x2 - my + 2, y1 );
+ p->drawLine( x1 + 1, y2, x2 - my + 2, y2 );
+
+ // light shadow
+ p->setPen( c3 );
+ p->drawLine( x1 + 1, y1 + 2, x1 + 1, y2 - 2 );
+ p->drawLine( x1 + 1, y1 + 1, x2 - my + 2, y1 + 1 );
+ p->drawLine( x2 - my + 2, y1 + 1, x2 - 1, y1 + my - 2 );
+
+ // dark shadow
+ p->setPen(c1);
+ p->drawLine( x2 - 1, y1 + my - 2, x2 - 1, y1 + my + 2 );
+ p->drawLine( x2 - my + 2, y2 - 1, x2 - 1, y1 + my + 2 );
+ p->drawLine( x1 + 1, y2 - 1, x2 -my + 2, y2 - 1 );
+
+ drawRiffles( p, handle.x(), handle.y() + 2, handle.width() - 3,
+ handle.height() - 4, cg, TRUE );
+ } else { // Qt::Horizontal
+ TQBrush oldBrush = p->brush();
+ p->setBrush( cg.brush( TQColorGroup::Button ) );
+ p->setPen( Qt::NoPen );
+ TQPointArray a(6);
+ a.setPoint( 0, x2 - 1, y1 + 1 );
+ a.setPoint( 1, x2 - 1, y2 - mx + 2 );
+ a.setPoint( 2, x2 - mx + 1, y2 - 1 );
+ a.setPoint( 3, x1 + mx - 1, y2 - 1 );
+ a.setPoint( 4, x1 + 1, y2 - mx + 2 );
+ a.setPoint( 5, x1 + 1, y1 + 1 );
+ p->drawPolygon( a );
+ p->setBrush( oldBrush );
+
+ // shadow border
+ p->setPen( c0 );
+ p->drawLine( x1 + 1, y1, x2 - 1, y1 );
+ p->drawLine( x1, y2 - mx + 2, x1 + mx - 2, y2 );
+ p->drawLine( x2, y2 - mx + 2, x1 + mx + 2, y2 );
+ p->drawLine( x1 + mx - 2, y2, x1 + mx + 2, y2 );
+ p->drawLine( x1, y1 + 1, x1, y2 - mx + 2 );
+ p->drawLine( x2, y1 + 1, x2, y2 - mx + 2 );
+
+ // light shadow
+ p->setPen(c3);
+ p->drawLine( x1 + 1, y1 + 1, x2 - 1, y1 + 1 );
+ p->drawLine( x1 + 1, y1 + 1, x1 + 1, y2 - mx + 2 );
+
+ // dark shadow
+ p->setPen(c1);
+ p->drawLine( x2 - 1, y1 + 1, x2 - 1, y2 - mx + 2 );
+ p->drawLine( x1 + 1, y2 - mx + 2, x1 + mx - 2, y2 - 1 );
+ p->drawLine( x2 - 1, y2 - mx + 2, x1 + mx + 2, y2 - 1 );
+ p->drawLine( x1 + mx - 2, y2 - 1, x1 + mx + 2, y2 - 1 );
+
+ drawRiffles( p, handle.x() + 2, handle.y(), handle.width() - 4,
+ handle.height() - 5, cg, FALSE );
+ }
+ }
+
+ if ( sub & SC_SliderTickmarks )
+ TQCommonStyle::tqdrawComplexControl( control, p, widget, r,
+ cg, how, SC_SliderTickmarks,
+ subActive, opt );
+#endif
+ break;
+ }
+ default:
+ TQWindowsStyle::tqdrawComplexControl( control, p, widget, r, cg,
+ how, sub, subActive, opt );
+ break;
+ }
+}
+
+
+
+/*!\reimp
+ */
+TQRect TQPlatinumStyle::querySubControlMetrics( TQ_ComplexControl control,
+ const TQWidget *widget,
+ SubControl sc,
+ const TQStyleOption& opt ) const
+{
+ switch( control ) {
+#ifndef TQT_NO_COMBOBOX
+ case CC_ComboBox:
+ const TQComboBox *cb;
+ cb = (const TQComboBox *)widget;
+ switch( sc ) {
+ case SC_ComboBoxArrow: {
+ TQRect ir = cb->rect();
+ int xx;
+ if( TQApplication::reverseLayout() )
+ xx = ir.x();
+ else
+ xx = ir.x() + ir.width() - 20;
+ return TQRect( xx, ir.y(), 20, ir.height()); }
+ default:
+ break;
+ }
+ break;
+#endif
+#ifndef TQT_NO_SCROLLBAR
+ case CC_ScrollBar: {
+ const TQScrollBar *sb;
+ sb = (const TQScrollBar *)widget;
+ int sliderStart = sb->sliderStart();
+ int sbextent = tqpixelMetric( PM_ScrollBarExtent, widget );
+ int maxlen = ((sb->orientation() == Qt::Horizontal) ?
+ sb->width() : sb->height()) - ( sbextent * 2 );
+
+ int sliderlen;
+
+ // calculate length
+ if ( sb->maxValue() != sb->minValue() ) {
+ uint range = sb->maxValue() - sb->minValue();
+ sliderlen = ( sb->pageStep() * maxlen ) /
+ ( range + sb->pageStep() );
+
+ int slidermin = tqpixelMetric( PM_ScrollBarSliderMin, widget );
+ if ( sliderlen < slidermin || range > INT_MAX / 2 )
+ sliderlen = slidermin;
+ if ( sliderlen > maxlen )
+ sliderlen = maxlen;
+ } else {
+ sliderlen = maxlen;
+ }
+
+ switch ( sc ) {
+ case SC_ScrollBarSubLine:
+ if ( sb->orientation() == Qt::Horizontal ) {
+ int buttonw = TQMIN( sb->width() / 2, sbextent );
+ return TQRect( sb->width() - 2 * buttonw, 0, buttonw, sbextent );
+ } else {
+ int buttonh = TQMIN( sb->height() / 2, sbextent );
+ return TQRect( 0, sb->height() - 2 * buttonh, sbextent, buttonh );
+ }
+ case SC_ScrollBarAddLine:
+ if ( sb->orientation() == Qt::Horizontal ) {
+ int buttonw = TQMIN( sb->width() / 2, sbextent );
+ return TQRect( sb->width() - buttonw, 0, sbextent, buttonw );
+ } else {
+ int buttonh = TQMIN( sb->height() / 2, sbextent );
+ return TQRect(0, sb->height() - buttonh, sbextent, buttonh );
+ }
+ case SC_ScrollBarSubPage:
+ if ( sb->orientation() == Qt::Horizontal )
+ return TQRect( 1, 0, sliderStart, sbextent );
+ return TQRect( 0, 1, sbextent, sliderStart );
+ case SC_ScrollBarAddPage:
+ if ( sb->orientation() == Qt::Horizontal )
+ return TQRect( sliderStart + sliderlen, 0, maxlen - sliderStart - sliderlen, sbextent );
+ return TQRect( 0, sliderStart + sliderlen, sbextent, maxlen - sliderStart - sliderlen );
+ case SC_ScrollBarGroove:
+ if ( sb->orientation() == Qt::Horizontal )
+ return TQRect( 1, 0, sb->width() - sbextent * 2, sb->height() );
+ return TQRect( 0, 1, sb->width(), sb->height() - sbextent * 2 );
+ default:
+ break;
+ }
+ break; }
+#endif
+#ifndef TQT_NO_SLIDER
+ case CC_Slider: {
+
+ const TQSlider *slider = (const TQSlider *) widget;
+ int tickOffset = tqpixelMetric( PM_SliderTickmarkOffset, widget);
+ int thickness = tqpixelMetric( PM_SliderControlThickness, widget);
+ int mid = thickness / 2;
+ int ticks = slider->tickmarks();
+ int len = tqpixelMetric( PM_SliderLength, widget );
+
+ switch ( sc ) {
+ case SC_SliderGroove:
+ if ( ticks & TQSlider::Above )
+ mid += len / 8;
+ if ( ticks & TQSlider::Below )
+ mid -= len / 8;
+ if ( slider->orientation() == Qt::Horizontal )
+ return TQRect( 0, tickOffset, slider->width(), thickness );
+ return TQRect( tickOffset, 0, thickness, slider->height() );
+ default:
+ break;
+ }
+ break; }
+#endif
+ default:
+ break;
+ }
+ return TQWindowsStyle::querySubControlMetrics( control, widget, sc, opt );
+}
+
+
+/*!\reimp
+ */
+int TQPlatinumStyle::tqpixelMetric( PixelMetric metric,
+ const TQWidget *widget ) const
+{
+ int ret;
+ switch( metric ) {
+ case PM_ButtonDefaultIndicator:
+ ret = 3;
+ break;
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 0;
+ break;
+ case PM_IndicatorWidth:
+ ret = 15;
+ break;
+ case PM_IndicatorHeight:
+ ret = 13;
+ break;
+ case PM_ExclusiveIndicatorHeight:
+ case PM_ExclusiveIndicatorWidth:
+ ret = 15;
+ break;
+ case PM_SliderLength:
+ ret = 17;
+ break;
+ case PM_MaximumDragDistance:
+ ret = -1;
+ break;
+ default:
+ ret = TQWindowsStyle::tqpixelMetric( metric, widget );
+ break;
+ }
+ return ret;
+}
+
+/*!\reimp
+ */
+TQRect TQPlatinumStyle::subRect( SubRect r, const TQWidget *widget ) const
+{
+ TQRect rect;
+ switch ( r ) {
+ case SR_ComboBoxFocusRect:
+ {
+ TQRect tmpR = widget->rect();
+ rect = TQRect( tmpR.x() + 4, tmpR.y() + 4, tmpR.width() - 8 - 16,
+ tmpR.height() - 8 );
+ break;
+ }
+ default:
+ rect = TQWindowsStyle::subRect( r, widget );
+ break;
+ }
+ return rect;
+}
+
+/*!
+ Mixes two colors \a c1 and \a c2 to a new color.
+*/
+TQColor TQPlatinumStyle::mixedColor(const TQColor &c1, const TQColor &c2) const
+{
+ int h1,s1,v1,h2,s2,v2;
+ c1.hsv(&h1,&s1,&v1);
+ c2.hsv(&h2,&s2,&v2);
+ return TQColor( (h1+h2)/2, (s1+s2)/2, (v1+v2)/2, TQColor::Hsv );
+}
+
+/*!
+ Draws the nifty Macintosh decoration used on sliders using painter
+ \a p and colorgroup \a g. \a x, \a y, \a w, \a h and \a horizontal
+ specify the tqgeometry and orientation of the riffles.
+*/
+void TQPlatinumStyle::drawRiffles( TQPainter* p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool horizontal ) const
+{
+ if (!horizontal) {
+ if (h > 20) {
+ y += (h-20)/2 ;
+ h = 20;
+ }
+ if (h > 8) {
+ int n = h / 4;
+ int my = y+h/2-n;
+ int i ;
+ p->setPen(g.light());
+ for (i=0; i<n; i++) {
+ p->drawLine(x+3, my+2*i, x+w-5, my+2*i);
+ }
+ p->setPen(g.dark());
+ my++;
+ for (i=0; i<n; i++) {
+ p->drawLine(x+4, my+2*i, x+w-4, my+2*i);
+ }
+ }
+ }
+ else {
+ if (w > 20) {
+ x += (w-20)/2 ;
+ w = 20;
+ }
+ if (w > 8) {
+ int n = w / 4;
+ int mx = x+w/2-n;
+ int i ;
+ p->setPen(g.light());
+ for (i=0; i<n; i++) {
+ p->drawLine(mx+2*i, y+3, mx + 2*i, y+h-5);
+ }
+ p->setPen(g.dark());
+ mx++;
+ for (i=0; i<n; i++) {
+ p->drawLine(mx+2*i, y+4, mx + 2*i, y+h-4);
+ }
+ }
+ }
+}
+
+
+#endif
diff --git a/tqtinterface/qt4/src/styles/tqplatinumstyle.h b/tqtinterface/qt4/src/styles/tqplatinumstyle.h
new file mode 100644
index 0000000..0d53eb3
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqplatinumstyle.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Definition of Platinum-like style class
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPLATINUMSTYLE_H
+#define TQPLATINUMSTYLE_H
+
+#ifndef TQT_H
+#include "tqwindowsstyle.h"
+#endif // TQT_H
+
+#if !defined(TQT_NO_STYLE_PLATINUM) || defined(TQT_PLUGIN)
+
+class TQPalette;
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_STYLE_PLATINUM
+#else
+#define TQ_EXPORT_STYLE_PLATINUM TQ_EXPORT
+#endif
+
+class TQ_EXPORT_STYLE_PLATINUM TQPlatinumStyle : public TQWindowsStyle
+{
+ TQ_OBJECT
+public:
+ TQPlatinumStyle();
+ virtual ~TQPlatinumStyle();
+
+ // new Style Stuff
+ void tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawComplexControl( TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+#ifdef TQ_TQDOC
+ SCFlags sub = SC_All,
+#else
+ SCFlags sub = (uint)SC_All,
+#endif
+ SCFlags subActive = SC_None,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ TQRect querySubControlMetrics( TQ_ComplexControl control,
+ const TQWidget *widget,
+ SubControl sc,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ int tqpixelMetric( PixelMetric metric, const TQWidget *widget = 0 ) const;
+
+ TQRect subRect( SubRect r, const TQWidget *widget ) const;
+
+protected:
+ TQColor mixedColor(const TQColor &, const TQColor &) const;
+ void drawRiffles( TQPainter* p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool horizontal ) const;
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQPlatinumStyle( const TQPlatinumStyle & );
+ TQPlatinumStyle& operator=( const TQPlatinumStyle & );
+#endif
+};
+
+#endif // TQT_NO_STYLE_PLATINUM
+
+#endif // TQPLATINUMSTYLE_H
diff --git a/tqtinterface/qt4/src/styles/tqsgistyle.cpp b/tqtinterface/qt4/src/styles/tqsgistyle.cpp
new file mode 100644
index 0000000..6b8a17b
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqsgistyle.cpp
@@ -0,0 +1,1470 @@
+/****************************************************************************
+**
+** Implementation of Motif-like style class
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsgistyle.h"
+
+#if !defined(TQT_NO_STYLE_SGI) || defined(TQT_PLUGIN)
+
+#include "tqpopupmenu.h"
+#include "tqapplication.h"
+#include "tqbutton.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqpixmap.h"
+#include "tqpalette.h"
+#include "tqwidget.h"
+#include "tqpushbutton.h"
+#include "tqscrollbar.h"
+#include "tqcombobox.h"
+#include "tqslider.h"
+#include "tqtextedit.h"
+#include "tqtoolbar.h"
+#include "tqlineedit.h"
+#include "tqmenubar.h"
+#include <limits.h>
+
+#ifndef TQT_NO_SLIDER
+struct SliderLastPosition
+{
+ SliderLastPosition() : rect(0,-1,0,-1), slider(0) {}
+ TQRect rect;
+ const TQSlider* slider;
+};
+#endif
+
+#ifndef TQT_NO_SCROLLBAR
+struct ScrollbarLastPosition
+{
+ ScrollbarLastPosition() : rect( 0,-1, 0,-1 ), scrollbar(0) {}
+ TQRect rect;
+ const TQScrollBar *scrollbar;
+};
+#endif
+
+class TQSGIStylePrivate
+{
+public:
+ TQSGIStylePrivate()
+ : hotWidget( 0 ), mousePos( -1, -1 )
+ {
+ }
+
+ const TQWidget *hotWidget;
+ TQPoint mousePos;
+#ifndef TQT_NO_SCROLLBAR
+ ScrollbarLastPosition lastScrollbarRect;
+#endif
+#ifndef TQT_NO_SLIDER
+ SliderLastPosition lastSliderRect;
+#endif
+};
+
+/*!
+ \class TQSGIStyle tqsgistyle.h
+ \brief The TQSGIStyle class provides SGI/Irix look and feel.
+
+ \ingroup appearance
+
+ This class implements the SGI look and feel. It resembles the
+ SGI/Irix Motif GUI style as closely as TQStyle allows.
+*/
+
+/*!
+ Constructs a TQSGIStyle.
+
+ If \a useHighlightCols is FALSE (default value), the style will
+ polish the application's color palette to emulate the Motif way of
+ highlighting, which is a simple inversion between the base and the
+ text color.
+
+ \sa TQMotifStyle::useHighlightColors()
+*/
+TQSGIStyle::TQSGIStyle( bool useHighlightCols ) : TQMotifStyle( useHighlightCols ), isApplicationStyle( 0 )
+{
+ d = new TQSGIStylePrivate;
+}
+
+/*!
+ Destroys the style.
+*/
+TQSGIStyle::~TQSGIStyle()
+{
+ delete d;
+}
+
+/*!
+ \reimp
+
+ Changes some application-wide settings to be SGI-like, e.g. sets a
+ bold italic font for menu options.
+*/
+void
+TQSGIStyle::polish( TQApplication* app)
+{
+ isApplicationStyle = 1;
+ TQMotifStyle::polish( app );
+
+ TQPalette pal = TQApplication::palette();
+ // check this on SGI-Boxes
+ //pal.setColor( TQColorGroup::Background, pal.active().midlight() );
+ if (pal.active().button() == pal.active().background())
+ pal.setColor( TQColorGroup::Button, pal.active().button().dark(120) );
+ // darker basecolor in list-widgets
+ pal.setColor( TQColorGroup::Base, pal.active().base().dark(130) );
+ if (! useHighlightColors() ) {
+ pal.setColor( TQPalette::Active, TQColorGroup::Highlight, pal.active().text() );
+ pal.setColor( TQPalette::Active, TQColorGroup::HighlightedText, pal.active().base() );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::Highlight, pal.inactive().text() );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::HighlightedText, pal.inactive().base() );
+ pal.setColor( TQPalette::Disabled, TQColorGroup::Highlight, pal.disabled().text() );
+ pal.setColor( TQPalette::Disabled, TQColorGroup::HighlightedText, pal.disabled().base() );
+ }
+ TQApplication::tqsetPalette( pal, TRUE );
+
+ // different basecolor and highlighting in Q(Multi)LineEdit
+ pal.setColor( TQColorGroup::Base, TQColor(211,181,181) );
+ pal.setColor( TQPalette::Active, TQColorGroup::Highlight, pal.active().midlight() );
+ pal.setColor( TQPalette::Active, TQColorGroup::HighlightedText, pal.active().text() );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::Highlight, pal.inactive().midlight() );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::HighlightedText, pal.inactive().text() );
+ pal.setColor( TQPalette::Disabled, TQColorGroup::Highlight, pal.disabled().midlight() );
+ pal.setColor( TQPalette::Disabled, TQColorGroup::HighlightedText, pal.disabled().text() );
+
+ TQApplication::tqsetPalette( pal, TRUE, "TQLineEdit" );
+ TQApplication::tqsetPalette( pal, TRUE, "TQTextEdit" );
+ TQApplication::tqsetPalette( pal, TRUE, "TQDateTimeEditBase" );
+
+ pal = TQApplication::palette();
+ pal.setColor( TQColorGroup::Button, pal.active().background() );
+ TQApplication::tqsetPalette( pal, TRUE, "TQMenuBar" );
+ TQApplication::tqsetPalette( pal, TRUE, "TQToolBar" );
+ TQApplication::tqsetPalette( pal, TRUE, "TQPopupMenu" );
+}
+
+/*! \reimp
+*/
+void
+TQSGIStyle::unPolish( TQApplication* /* app */ )
+{
+ TQFont f = TQApplication::font();
+ TQApplication::tqsetFont( f, TRUE ); // get rid of the special fonts for special widget classes
+}
+
+/*!
+ \reimp
+
+ Installs an event filter for several widget classes to enable
+ hovering.
+*/
+void
+TQSGIStyle::polish( TQWidget* w )
+{
+ TQMotifStyle::polish(w);
+
+ if ( !isApplicationStyle ) {
+ TQPalette sgiPal = TQApplication::palette();
+
+ sgiPal.setColor( TQColorGroup::Background, sgiPal.active().midlight() );
+ if (sgiPal.active().button() == sgiPal.active().background())
+ sgiPal.setColor( TQColorGroup::Button, sgiPal.active().button().dark(110) );
+ sgiPal.setColor( TQColorGroup::Base, sgiPal.active().base().dark(130) );
+ if (! useHighlightColors() ) {
+ sgiPal.setColor( TQPalette::Active, TQColorGroup::Highlight, sgiPal.active().text() );
+ sgiPal.setColor( TQPalette::Active, TQColorGroup::HighlightedText, sgiPal.active().base() );
+ sgiPal.setColor( TQPalette::Inactive, TQColorGroup::Highlight, sgiPal.inactive().text() );
+ sgiPal.setColor( TQPalette::Inactive, TQColorGroup::HighlightedText, sgiPal.inactive().base() );
+ sgiPal.setColor( TQPalette::Disabled, TQColorGroup::Highlight, sgiPal.disabled().text() );
+ sgiPal.setColor( TQPalette::Disabled, TQColorGroup::HighlightedText, sgiPal.disabled().base() );
+ }
+
+ if ( ::tqqt_cast<TQLineEdit*>(w) || ::tqqt_cast<TQTextEdit*>(w) ) {
+ // different basecolor and highlighting in Q(Multi)LineEdit
+ sgiPal.setColor( TQColorGroup::Base, TQColor(211,181,181) );
+ sgiPal.setColor( TQPalette::Active, TQColorGroup::Highlight, sgiPal.active().midlight() );
+ sgiPal.setColor( TQPalette::Active, TQColorGroup::HighlightedText, sgiPal.active().text() );
+ sgiPal.setColor( TQPalette::Inactive, TQColorGroup::Highlight, sgiPal.inactive().midlight() );
+ sgiPal.setColor( TQPalette::Inactive, TQColorGroup::HighlightedText, sgiPal.inactive().text() );
+ sgiPal.setColor( TQPalette::Disabled, TQColorGroup::Highlight, sgiPal.disabled().midlight() );
+ sgiPal.setColor( TQPalette::Disabled, TQColorGroup::HighlightedText, sgiPal.disabled().text() );
+
+ } else if ( ::tqqt_cast<TQMenuBar*>(w) || ::tqqt_cast<TQToolBar*>(w) ) {
+ sgiPal.setColor( TQColorGroup::Button, sgiPal.active().midlight() );
+ }
+
+ w->setPalette( sgiPal );
+ }
+
+ if ( ::tqqt_cast<TQButton*>(w) || ::tqqt_cast<TQSlider*>(w) || ::tqqt_cast<TQScrollBar*>(w) ) {
+ w->installEventFilter( this );
+ w->setMouseTracking( TRUE );
+#ifndef TQT_NO_SCROLLBAR
+ if ( ::tqqt_cast<TQScrollBar*>(w) )
+ w->setBackgroundMode( TQt::NoBackground );
+#endif
+ } else if ( ::tqqt_cast<TQComboBox*>(w) ) {
+ TQFont f = TQApplication::font();
+ f.setBold( TRUE );
+ f.setItalic( TRUE );
+ w->setFont( f );
+#ifndef TQT_NO_MENUBAR
+ } else if ( ::tqqt_cast<TQMenuBar*>(w) ) {
+ ((TQFrame*) w)->setFrameStyle(TQFrame::StyledPanel | TQFrame::Raised);
+ w->setBackgroundMode( TQt::PaletteBackground );
+ TQFont f = TQApplication::font();
+ f.setBold( TRUE );
+ f.setItalic( TRUE );
+ w->setFont( f );
+#endif
+#ifndef TQT_NO_POPUPMENU
+ } else if ( ::tqqt_cast<TQPopupMenu*>(w) ) {
+ ((TQFrame*) w)->setLineWidth( tqpixelMetric( PM_DefaultFrameWidth ) + 1 );
+ TQFont f = TQApplication::font();
+ f.setBold( TRUE );
+ f.setItalic( TRUE );
+ w->setFont( f );
+#endif
+ } else if ( ::tqqt_cast<TQToolBar*>(w) || w->inherits("TQToolBarSeparator") ) {
+ w->setBackgroundMode( TQt::PaletteBackground );
+ }
+}
+
+/*! \reimp */
+void
+TQSGIStyle::unPolish( TQWidget* w )
+{
+ if ( ::tqqt_cast<TQButton*>(w) || ::tqqt_cast<TQSlider*>(w) || ::tqqt_cast<TQScrollBar*>(w) ) {
+ w->removeEventFilter( this );
+#ifndef TQT_NO_POPUPMENU
+ } else if ( ::tqqt_cast<TQPopupMenu*>(w) ) {
+ ((TQFrame*)w)->setLineWidth( tqpixelMetric( PM_DefaultFrameWidth ) );
+ w->setFont( TQApplication::font() );
+#endif
+#if !defined(TQT_NO_MENUBAR) || !defined(TQT_NO_COMBOBOX)
+ } else if ( ::tqqt_cast<TQMenuBar*>(w) || ::tqqt_cast<TQComboBox*>(w) ) {
+ w->setFont( TQApplication::font() );
+#endif
+ }
+}
+
+/*! \reimp */
+bool TQSGIStyle::eventFilter( TQObject* o, TQEvent* e )
+{
+ if ( !o->isWidgetType() || e->type() == TQEvent::Paint )
+ return TQMotifStyle::eventFilter( o, e );
+
+ TQWidget *widget = (TQWidget*)o;
+
+ switch ( e->type() ) {
+ case TQEvent::MouseButtonPress:
+ {
+#ifndef TQT_NO_SCROLLBAR
+ if ( ::tqqt_cast<TQScrollBar*>(widget) ) {
+ d->lastScrollbarRect.rect = ((TQScrollBar*)widget)->sliderRect();
+ d->lastScrollbarRect.scrollbar = ((TQScrollBar*)widget);
+ widget->tqrepaint( FALSE );
+ } else
+#endif
+ {
+#ifndef TQT_NO_SLIDER
+ if ( ::tqqt_cast<TQSlider*>(widget) ) {
+ d->lastSliderRect.rect = ((TQSlider*)widget)->sliderRect();
+ d->lastSliderRect.slider = ((TQSlider*)widget);
+ widget->tqrepaint( FALSE );
+ }
+#endif
+ }
+ }
+ break;
+
+ case TQEvent::MouseButtonRelease:
+ {
+ if ( 0 ) {
+#ifndef TQT_NO_SCROLLBAR
+ } else if ( ::tqqt_cast<TQScrollBar*>(widget) ) {
+ TQRect oldRect = d->lastScrollbarRect.rect;
+ d->lastScrollbarRect.rect = TQRect( 0, -1, 0, -1 );
+ widget->tqrepaint( oldRect, FALSE );
+#endif
+#ifndef TQT_NO_SLIDER
+ } else if ( ::tqqt_cast<TQSlider*>(widget) ) {
+ TQRect oldRect = d->lastSliderRect.rect;
+ d->lastSliderRect.rect = TQRect( 0, -1, 0, -1 );
+ widget->tqrepaint( oldRect, FALSE );
+#endif
+ }
+ }
+ break;
+
+ case TQEvent::MouseMove:
+ if ( !widget->isActiveWindow() )
+ break;
+ if ( ((TQMouseEvent*)e)->button() )
+ break;
+
+ d->hotWidget = widget;
+ d->mousePos = ((TQMouseEvent*)e)->pos();
+ widget->tqrepaint( FALSE );
+ break;
+
+ case TQEvent::Enter:
+ if ( !widget->isActiveWindow() )
+ break;
+ d->hotWidget = widget;
+ widget->tqrepaint( FALSE );
+ break;
+
+ case TQEvent::Leave:
+ if ( !widget->isActiveWindow() )
+ break;
+ if ( widget == d->hotWidget) {
+ d->hotWidget = 0;
+ widget->tqrepaint( FALSE );
+ }
+ break;
+
+ default:
+ break;
+ }
+ return TQMotifStyle::eventFilter( o, e );
+}
+
+static const int sgiItemFrame = 2; // menu item frame width
+// static const int sgiSepHeight = 1; // separator item height
+static const int sgiItemHMargin = 3; // menu item hor text margin
+static const int sgiItemVMargin = 2; // menu item ver text margin
+static const int sgiArrowHMargin = 6; // arrow horizontal margin
+static const int sgiTabSpacing = 12; // space between text and tab
+// static const int sgiCheckMarkHMargin = 2; // horiz. margins of check mark ### not used?!?
+static const int sgiCheckMarkSpace = 20;
+
+/*! \reimp */
+int TQSGIStyle::tqpixelMetric( PixelMetric metric, const TQWidget *widget ) const
+{
+ switch ( metric ) {
+ case PM_DefaultFrameWidth:
+ return 2;
+
+ case PM_ButtonDefaultIndicator:
+ return 4;
+
+ case PM_ScrollBarExtent:
+ return 21;
+
+ case PM_IndicatorWidth:
+ case PM_IndicatorHeight:
+ return 14;
+
+ case PM_ExclusiveIndicatorWidth:
+ case PM_ExclusiveIndicatorHeight:
+ return 12;
+
+ case PM_SplitterWidth:
+ return TQMAX( 10, TQApplication::globalStrut().width() );
+
+ default:
+ break;
+ }
+ return TQMotifStyle::tqpixelMetric( metric, widget );
+}
+
+static void drawPanel( TQPainter *p, int x, int y, int w, int h,
+ const TQColorGroup &g, bool sunken,
+ int lineWidth, const TQBrush* fill)
+{
+ if ( w == 0 || h == 0 )
+ return;
+#if defined(CHECK_RANGE)
+ ASSERT( w > 0 && h > 0 && lineWidth >= 0 );
+#endif
+ TQPen oldPen = p->pen(); // save pen
+ TQPointArray a( 4*lineWidth );
+ if ( sunken )
+ p->setPen( g.dark() );
+ else
+ p->setPen( g.light() );
+ int x1, y1, x2, y2;
+ int i;
+ int n = 0;
+ x1 = x;
+ y1 = y2 = y;
+ x2 = x+w-2;
+ for ( i=0; i<lineWidth; i++ ) { // top shadow
+ a.setPoint( n++, x1, y1++ );
+ a.setPoint( n++, x2--, y2++ );
+ }
+ x2 = x1;
+ y1 = y+h-2;
+ for ( i=0; i<lineWidth; i++ ) { // left shadow
+ a.setPoint( n++, x1++, y1 );
+ a.setPoint( n++, x2++, y2-- );
+ }
+ p->drawLineSegments( a );
+ n = 0;
+ if ( sunken )
+ p->setPen( g.light() );
+ else
+ p->setPen( g.dark() );
+ x1 = x;
+ y1 = y2 = y+h-1;
+ x2 = x+w-1;
+ for ( i=0; i<lineWidth; i++ ) { // bottom shadow
+ a.setPoint( n++, x1++, y1-- );
+ a.setPoint( n++, x2, y2-- );
+ }
+ x1 = x2;
+ y1 = y;
+ y2 = y+h-lineWidth-1;
+ for ( i=0; i<lineWidth; i++ ) { // right shadow
+ a.setPoint( n++, x1--, y1++ );
+ a.setPoint( n++, x2--, y2 );
+ }
+ p->drawLineSegments( a );
+ if ( fill ) { // fill with fill color
+ TQBrush oldBrush = p->brush();
+ p->setPen( TQt::NoPen );
+ p->setBrush( *fill );
+ p->drawRect( x+lineWidth, y+lineWidth, w-lineWidth*2, h-lineWidth*2 );
+ p->setBrush( oldBrush );
+ }
+ p->setPen( oldPen ); // restore pen
+}
+
+static void drawSeparator( TQPainter *p, int x1, int y1, int x2, int y2,
+ const TQColorGroup &g )
+{
+ TQPen oldPen = p->pen();
+
+ p->setPen( g.midlight() );
+ p->drawLine( x1, y1, x2, y2 );
+ p->setPen( g.shadow() );
+ if ( y2-y1 < x2-x1 )
+ p->drawLine( x1, y1+1, x2, y2+1 );
+ else
+ p->drawLine( x1+1, y1, x2+1, y2 );
+
+ p->setPen( oldPen );
+}
+
+static void drawSGIPrefix( TQPainter *p, int x, int y, TQString* miText )
+{
+ if ( miText && (!!(*miText)) ) {
+ int amp = 0;
+ bool nextAmp = FALSE;
+ while ( ( amp = miText->tqfind( '&', amp ) ) != -1 ) {
+ if ( (uint)amp == miText->length()-1 )
+ return;
+ miText->remove( amp,1 );
+ nextAmp = (*miText)[amp] == '&'; // next time if &&
+
+ if ( !nextAmp ) { // draw special underlining
+ uint ulx = p->fontMetrics().width(*miText, amp);
+
+ uint ulw = p->fontMetrics().width(*miText, amp+1) - ulx;
+
+ p->drawLine( x+ulx, y, x+ulx+ulw, y );
+ p->drawLine( x+ulx, y+1, x+ulx+ulw/2, y+1 );
+ p->drawLine( x+ulx, y+2, x+ulx+ulw/4, y+2 );
+ }
+ amp++;
+ }
+ }
+}
+
+static int get_combo_extra_width( int h, int *return_awh=0 )
+{
+ int awh;
+ if ( h < 8 ) {
+ awh = 6;
+ } else if ( h < 14 ) {
+ awh = h - 2;
+ } else {
+ awh = h/2;
+ }
+ if ( return_awh )
+ *return_awh = awh;
+ return awh*2;
+}
+
+static void get_combo_parameters( const TQRect &r,
+ int &ew, int &awh, int &ax,
+ int &ay, int &sh, int &dh,
+ int &sy )
+{
+ ew = get_combo_extra_width( r.height(), &awh );
+
+ sh = (awh+3)/4;
+ if ( sh < 3 )
+ sh = 3;
+ dh = sh/2 + 1;
+
+ ay = r.y() + (r.height()-awh-sh-dh)/2;
+ if ( ay < 0 ) {
+ //panic mode
+ ay = 0;
+ sy = r.height();
+ } else {
+ sy = ay+awh+dh;
+ }
+ if( TQApplication::reverseLayout() )
+ ax = r.x();
+ else
+ ax = r.x() + r.width() - ew;
+ ax += (ew-awh)/2;
+}
+
+/*! \reimp */
+void TQSGIStyle::tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ const int x = r.x();
+ const int y = r.y();
+ const int w = r.width();
+ const int h = r.height();
+ const bool sunken = flags & ( Style_Sunken | Style_Down | Style_On );
+ const int defaultFrameWidth = tqpixelMetric( PM_DefaultFrameWidth );
+ bool hot = ( flags & Style_MouseOver ) && ( flags & Style_Enabled );
+
+ switch ( pe ) {
+ case PE_ButtonCommand:
+ {
+ TQBrush fill;
+ if ( hot ) {
+ if ( sunken )
+ fill = cg.brush( TQColorGroup::Dark );
+ else
+ fill = cg.brush( TQColorGroup::Midlight );
+ } else if ( sunken ) {
+ fill = cg.brush( TQColorGroup::Mid );
+ } else {
+ fill = cg.brush( TQColorGroup::Button );
+ }
+
+ drawPanel( p, x, y, w, h, cg, sunken, defaultFrameWidth, &fill );
+ }
+ break;
+
+ case PE_PanelPopup:
+ case PE_ButtonBevel:
+ case PE_ButtonTool:
+ {
+ tqdrawPrimitive( PE_ButtonCommand, p, TQRect( x+1, y+1, w-2, h-2 ), cg, flags, opt );
+
+ TQPen oldPen = p->pen();
+ TQPointArray a;
+
+ // draw twocolored rectangle
+ p->setPen( sunken ? cg.light() : TQT_TQCOLOR_OBJECT(cg.dark().dark(200)) );
+ a.setPoints( 3, x, y+h-1, x+w-1, y+h-1, x+w-1, y );
+ p->drawPolyline( a );
+ p->setPen( cg.dark() );
+ a.setPoints( 3, x, y+h-2, x, y, x+w-2, y );
+ p->drawPolyline( a );
+
+ p->setPen( oldPen );
+ }
+ break;
+
+ case PE_ArrowUp:
+ case PE_ArrowDown:
+ case PE_ArrowLeft:
+ case PE_ArrowRight:
+ {
+ TQPointArray a; // arrow polygon
+ switch ( pe ) {
+ case PE_ArrowUp:
+ a.setPoints( 3, 0,-5, -5,4, 4,4 );
+ break;
+ case PE_ArrowDown:
+ a.setPoints( 3, 0,4, -4,-4, 4,-4 );
+ break;
+ case PE_ArrowLeft:
+ a.setPoints( 3, -4,0, 4,-5, 4,4 );
+ break;
+ case PE_ArrowRight:
+ a.setPoints( 3, 4,0, -4,-5, -4,4 );
+ break;
+ default:
+ return;
+ }
+
+ p->save();
+ p->setPen( TQt::NoPen );
+ a.translate( x+w/2, y+h/2 );
+ p->setBrush( flags & Style_Enabled ? cg.dark() : cg.light() );
+ p->drawPolygon( a ); // draw arrow
+ p->restore();
+ }
+ break;
+
+ case PE_Indicator:
+ {
+ TQRect er = r;
+ er.addCoords( 1, 1, -1, -1 );
+ int iflags = flags & ~Style_On;
+ tqdrawPrimitive( PE_ButtonBevel, p, er, cg, (QStyle::StateFlag)iflags, opt );
+ if ( !(flags & TQStyle::Style_Off) ) {
+ er = r;
+ er.addCoords( 1, 2, 1, 1 );
+ tqdrawPrimitive( PE_CheckMark, p, er, cg, flags, opt );
+ }
+ }
+ break;
+
+ case PE_IndicatorMask:
+ {
+ TQPen oldPen = p->pen();
+ TQBrush oldBrush = p->brush();
+
+ p->setPen( TQt::color1 );
+ p->setBrush( TQt::color1 );
+ p->fillRect( x, y, w, h, TQBrush( TQt::color0 ) );
+ TQRect er = r;
+ er.addCoords( 1, 1, -1, -1 );
+ p->fillRect(er, TQBrush(TQt::color1));
+
+ if ( !(flags & TQStyle::Style_Off) ) {
+ er = r;
+ er.addCoords( 1, 2, 1, 1 );
+ static const TQCOORD check_mark[] = {
+ 14,0, 10,0, 11,1, 8,1, 9,2, 7,2, 8,3, 6,3,
+ 7,4, 1,4, 6,5, 1,5, 6,6, 3,6, 5,7, 4,7,
+ 5,8, 5,8, 4,3, 2,3, 3,2, 3,2 };
+
+ TQPointArray amark;
+ amark = TQPointArray( sizeof(check_mark)/(sizeof(TQCOORD)*2), check_mark );
+ amark.translate( er.x()+1, er.y()+1 );
+ p->drawLineSegments( amark );
+ amark.translate( -1, -1 );
+ p->drawLineSegments( amark );
+ }
+
+ p->setBrush( oldBrush );
+ p->setPen( oldPen );
+ }
+ break;
+
+#ifndef USE_QT4 // [FIXME]
+ case PE_CheckMark:
+ {
+ static const TQCOORD check_mark[] = {
+ 14,0, 10,0, 11,1, 8,1, 9,2, 7,2, 8,3, 6,3,
+ 7,4, 1,4, 6,5, 1,5, 6,6, 3,6, 5,7, 4,7,
+ 5,8, 5,8, 4,3, 2,3, 3,2, 3,2 };
+
+ TQPen oldPen = p->pen();
+
+ TQPointArray amark;
+ amark = TQPointArray( sizeof(check_mark)/(sizeof(TQCOORD)*2), check_mark );
+ amark.translate( x+1, y+1 );
+
+ if ( flags & Style_On ) {
+ p->setPen( flags & Style_Enabled ? cg.shadow() : cg.dark() );
+ p->drawLineSegments( amark );
+ amark.translate( -1, -1 );
+ p->setPen( flags & Style_Enabled ? TQColor(255,0,0) : cg.dark() );
+ p->drawLineSegments( amark );
+ p->setPen( oldPen );
+ } else {
+ p->setPen( flags & Style_Enabled ? cg.dark() : cg.mid() );
+ p->drawLineSegments( amark );
+ amark.translate( -1, -1 );
+ p->setPen( flags & Style_Enabled ? TQColor(230,120,120) : cg.dark() );
+ p->drawLineSegments( amark );
+ p->setPen( oldPen );
+ }
+ }
+ break;
+#endif // USE_QT4
+
+ case PE_ExclusiveIndicator:
+ {
+ p->save();
+ p->eraseRect( x, y, w, h );
+ p->translate( x, y );
+
+ p->setPen( cg.button() );
+ p->setBrush( hot ? cg.midlight() : cg.button() );
+ TQPointArray a;
+ a.setPoints( 4, 5,0, 11,6, 6,11, 0,5);
+ p->drawPolygon( a );
+
+ p->setPen( cg.dark() );
+ p->drawLine( 0,5, 5,0 );
+ p->drawLine( 6,0, 11,5 );
+ p->setPen( flags & Style_Down ? cg.light() : cg.dark() );
+ p->drawLine( 11,6, 6,11 );
+ p->drawLine( 5,11, 0,6 );
+ p->drawLine( 2,7, 5,10 );
+ p->drawLine( 6,10, 9,7 );
+ p->setPen( cg.light() );
+ p->drawLine( 2,5, 5,2 );
+
+ if ( flags & Style_On ) {
+ p->setPen( flags & Style_Enabled ? TQt::blue : TQt::darkGray );
+ p->setBrush( flags & Style_Enabled ? TQt::blue : TQt::darkGray );
+ a.setPoints(3, 6,2, 8,4, 6,6 );
+ p->drawPolygon( a );
+ p->setBrush( TQt::NoBrush );
+
+ p->setPen( cg.shadow() );
+ p->drawLine( 7,7, 9,5 );
+ } else {
+ p->drawLine( 6,2, 9,5 );
+ }
+ p->restore();
+ }
+ break;
+
+ case PE_ExclusiveIndicatorMask:
+ {
+ p->save();
+ TQPen oldPen = p->pen();
+ TQBrush oldBrush = p->brush();
+
+ p->setPen( TQt::color1 );
+ p->setBrush( TQt::color1 );
+ TQPointArray a;
+ a.setPoints( 8, 0,5, 5,0, 6,0, 11,5, 11,6, 6,11, 5,11, 0,6 );
+ a.translate( x, y );
+ p->drawPolygon( a );
+
+ p->setBrush( oldBrush );
+ p->setPen( oldPen );
+ p->restore();
+ }
+ break;
+
+ case PE_Panel:
+ {
+ const int lineWidth = opt.isDefault() ? defaultFrameWidth : opt.lineWidth();
+ drawPanel( p, x, y, w, h, cg, flags & (Style_Sunken | Style_Down | Style_On), lineWidth, 0 );
+ if ( lineWidth <= 1 )
+ return;
+
+ // draw extra shadinglines
+ TQPen oldPen = p->pen();
+ p->setPen( cg.midlight() );
+ p->drawLine( x+1, y+h-3, x+1, y+1 );
+ p->drawLine( x+1, y+1, x+w-3, y+1 );
+ p->setPen( cg.mid() );
+ p->drawLine( x+1, y+h-2, x+w-2, y+h-2 );
+ p->drawLine( x+w-2, y+h-2, x+w-2, y+1 );
+ p->setPen(oldPen);
+ }
+ break;
+
+ case PE_ScrollBarSubLine:
+ if ( !r.tqcontains( d->mousePos ) && !(flags & Style_Active) )
+ flags &= ~Style_MouseOver;
+ tqdrawPrimitive( PE_ButtonCommand, p, r, cg, flags, opt );
+ tqdrawPrimitive(((flags & Style_Horizontal) ? PE_ArrowLeft : PE_ArrowUp),
+ p, r, cg, Style_Enabled | flags);
+ break;
+
+ case PE_ScrollBarAddLine:
+ if ( !r.tqcontains( d->mousePos ) )
+ flags &= ~Style_MouseOver;
+ tqdrawPrimitive( PE_ButtonCommand, p, r, cg, flags, opt );
+ tqdrawPrimitive(((flags & Style_Horizontal) ? PE_ArrowRight : PE_ArrowDown),
+ p, r, cg, Style_Enabled | flags);
+ break;
+
+ case PE_ScrollBarSubPage:
+ case PE_ScrollBarAddPage:
+ if ( !r.tqcontains( d->mousePos ) )
+ flags &= ~Style_MouseOver;
+ if ( r.isValid() )
+ qDrawShadePanel( p, x, y, w, h, cg, FALSE, 1, hot ? &cg.brush( TQColorGroup::Midlight ) : &cg.brush( TQColorGroup::Button ) );
+ break;
+
+ case PE_ScrollBarSlider:
+ {
+ if ( !r.isValid() )
+ break;
+ if ( !(r.tqcontains( d->mousePos ) || flags & Style_Active) || !(flags & Style_Enabled ) )
+ flags &= ~Style_MouseOver;
+
+ TQPixmap pm( r.width(), r.height() );
+ TQPainter bp( &pm );
+ tqdrawPrimitive(PE_ButtonBevel, &bp, TQRect(0,0,r.width(),r.height()), cg, flags | Style_Enabled | Style_Raised);
+ if ( flags & Style_Horizontal ) {
+ const int sliderM = r.width() / 2;
+ if ( r.width() > 20 ) {
+ drawSeparator( &bp, sliderM-5, 2, sliderM-5, r.height()-3, cg );
+ drawSeparator( &bp, sliderM+3, 2, sliderM+3, r.height()-3, cg );
+ }
+ if ( r.width() > 10 )
+ drawSeparator( &bp, sliderM-1, 2, sliderM-1, r.height()-3, cg );
+
+ } else {
+ const int sliderM = r.height() / 2;
+ if ( r.height() > 20 ) {
+ drawSeparator( &bp, 2, sliderM-5, r.width()-3, sliderM-5, cg );
+ drawSeparator( &bp, 2, sliderM+3, r.width()-3, sliderM+3, cg );
+ }
+ if ( r.height() > 10 )
+ drawSeparator( &bp, 2, sliderM-1, r.width()-3, sliderM-1, cg );
+ }
+ bp.end();
+ p->drawPixmap( r.x(), r.y(), pm );
+ }
+
+ break;
+
+ case PE_Splitter:
+ {
+ const int motifOffset = 10;
+ int sw = tqpixelMetric( PM_SplitterWidth );
+ if ( flags & Style_Horizontal ) {
+ int xPos = x + w/2;
+ int kPos = motifOffset;
+ int kSize = sw - 2;
+
+ qDrawShadeLine( p, xPos, kPos + kSize - 1 ,
+ xPos, h, cg );
+
+ tqdrawPrimitive( PE_ButtonBevel, p, TQRect(xPos-sw/2+1, kPos, kSize, kSize+1), cg, flags, opt );
+ qDrawShadeLine( p, xPos+2, 0, xPos, kPos, cg );
+ } else {
+ int yPos = y + h/2;
+ int kPos = w - motifOffset - sw;
+ int kSize = sw - 2;
+
+ qDrawShadeLine( p, 0, yPos, kPos, yPos, cg );
+ tqdrawPrimitive( PE_ButtonBevel, p, TQRect( kPos, yPos-sw/2+1, kSize+1, kSize ), cg, flags, opt );
+ qDrawShadeLine( p, kPos + kSize+1, yPos, w, yPos, cg );
+ }
+ }
+ break;
+
+ default:
+ TQMotifStyle::tqdrawPrimitive( pe, p, r, cg, flags, opt );
+ break;
+ }
+}
+
+/*! \reimp */
+void TQSGIStyle::tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ if ( widget == d->hotWidget )
+ flags |= Style_MouseOver;
+
+ switch ( element ) {
+ case CE_PushButton:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *btn = (TQPushButton*)widget;
+ int x1, y1, x2, y2;
+ r.coords( &x1, &y1, &x2, &y2 );
+
+ p->setPen( cg.foreground() );
+ p->setBrush( TQBrush( cg.button(), Qt::NoBrush ) );
+ p->setBrushOrigin( -widget->backgroundOffset().x(),
+ -widget->backgroundOffset().y() );
+
+ int diw = tqpixelMetric( TQStyle::PM_ButtonDefaultIndicator );
+ if ( btn->isDefault() || btn->autoDefault() ) {
+ x1 += diw;
+ y1 += diw;
+ x2 -= diw;
+ y2 -= diw;
+ }
+
+ TQPointArray a;
+ if ( btn->isDefault() ) {
+ if ( diw == 0 ) {
+ a.setPoints( 9,
+ x1, y1, x2, y1, x2, y2, x1, y2, x1, y1+1,
+ x2-1, y1+1, x2-1, y2-1, x1+1, y2-1, x1+1, y1+1 );
+ p->setPen( cg.shadow() );
+ p->drawPolyline( a );
+ x1 += 2;
+ y1 += 2;
+ x2 -= 2;
+ y2 -= 2;
+ } else {
+ qDrawShadePanel( p, btn->rect(), cg, TRUE );
+ }
+ }
+
+ TQBrush fill = cg.brush( TQColorGroup::Button );
+ if ( !btn->isFlat() || btn->isOn() || btn->isDown() )
+ tqdrawPrimitive( PE_ButtonBevel, p, TQRect( x1, y1, x2-x1+1, y2-y1+1 ), cg, flags, opt );
+
+ if ( p->brush().style() != TQt::NoBrush )
+ p->setBrush( TQt::NoBrush );
+#endif
+ }
+ break;
+
+ case CE_PopupMenuItem:
+ {
+#ifndef TQT_NO_POPUPMENU
+ if (! widget || opt.isDefault())
+ break;
+ TQMenuItem *mi = opt.menuItem();
+ if ( !mi )
+ break;
+ const TQPopupMenu *popupmenu = (const TQPopupMenu *) widget;
+ int tab = opt.tabWidth();
+ int maxpmw = opt.maxIconWidth();
+ bool dis = ! (flags & Style_Enabled);
+ bool checkable = popupmenu->isCheckable();
+ bool act = flags & Style_Active;
+ int x, y, w, h;
+
+ r.rect(&x, &y, &w, &h);
+
+ if ( checkable )
+ maxpmw = TQMAX( maxpmw, sgiCheckMarkSpace );
+ int checkcol = maxpmw;
+
+ if (mi && mi->isSeparator() ) {
+ p->setPen( cg.mid() );
+ p->drawLine(x, y, x+w, y );
+ return;
+ }
+
+ int pw = sgiItemFrame;
+
+ if ( act && !dis ) {
+ if ( tqpixelMetric( PM_DefaultFrameWidth ) > 1 )
+ drawPanel( p, x, y, w, h, cg, FALSE, pw,
+ &TQT_TQBRUSH_OBJECT(cg.brush( TQColorGroup::Light )) );
+ else
+ drawPanel( p, x+1, y+1, w-2, h-2, cg, FALSE, 1,
+ &TQT_TQBRUSH_OBJECT(cg.brush( TQColorGroup::Light )) );
+ } else {
+ p->fillRect( x, y, w, h, cg.brush( TQColorGroup::Button ) );
+ }
+
+ if ( !mi )
+ return;
+
+ if ( mi->isChecked() ) {
+ if ( mi->iconSet() ) {
+ drawPanel( p, x+sgiItemFrame, y+sgiItemFrame, checkcol, h-2*sgiItemFrame,
+ cg, TRUE, 1, &TQT_TQBRUSH_OBJECT(cg.brush( TQColorGroup::Light )) );
+ }
+ } else {
+ if ( !act )
+ p->fillRect( x+sgiItemFrame, y+sgiItemFrame, checkcol, h-2*sgiItemFrame,
+ cg.brush( TQColorGroup::Button ) );
+ }
+
+ if ( mi->iconSet() ) {
+ TQIconSet::Mode mode = TQIconSet::Normal;
+ if ( act && !dis )
+ mode = TQIconSet::Active;
+ TQPixmap pixmap;
+ if ( checkable && mi->isChecked() )
+ pixmap = mi->iconSet()->pixmap( TQIconSet::Small, mode, TQIconSet::On );
+ else
+ pixmap = mi->iconSet()->pixmap( TQIconSet::Small, mode );
+
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ TQRect cr( x+sgiItemFrame, y+sgiItemFrame, checkcol, h-2*sgiItemFrame );
+ TQRect pmr( 0, 0, pixw, pixh );
+ pmr.moveCenter( cr.center() );
+ p->setPen( cg.text() );
+ p->drawPixmap( pmr.topLeft(), pixmap );
+ } else {
+ if ( checkable ) {
+ SFlags cflags = Style_Default;
+ if (! dis)
+ cflags |= Style_Enabled;
+ if (act)
+ cflags |= Style_On;
+
+ if ( mi->isChecked() ) {
+ TQRect er( x+sgiItemFrame+1, y+sgiItemFrame+3,
+ tqpixelMetric(PM_IndicatorWidth),
+ tqpixelMetric(PM_IndicatorHeight) );
+ er.addCoords( 1, 1, -1, -1 );
+ tqdrawPrimitive( PE_ButtonBevel, p, er, cg, cflags, opt );
+ er.addCoords( 0, 1, 1, 1 );
+ tqdrawPrimitive( PE_CheckMark, p, er, cg, cflags | Style_On, opt );
+ }
+ }
+ }
+
+ p->setPen( cg.buttonText() );
+
+ TQColor discol;
+ if ( dis ) {
+ discol = cg.text();
+ p->setPen( discol );
+ }
+
+ int xm = sgiItemFrame + checkcol + sgiItemHMargin;
+
+ if ( mi->custom() ) {
+ int m = sgiItemVMargin;
+ p->save();
+ mi->custom()->paint( p, cg, act, !dis,
+ x+xm, y+m, w-xm-tab+1, h-2*m );
+ p->restore();
+ }
+
+ TQString s = mi->text();
+ if ( !!s ) {
+ int t = s.tqfind( '\t' );
+ int m = sgiItemVMargin;
+ const int text_flags = TQt::AlignVCenter | TQt::DontClip | TQt::SingleLine; //special underline for &x
+
+ TQString miText = s;
+ if ( t>=0 ) {
+ p->drawText(x+w-tab-sgiItemHMargin-sgiItemFrame,
+ y+m, tab, h-2*m, text_flags, miText.mid( t+1 ) );
+ miText = s.mid( 0, t );
+ }
+ TQRect br = p->fontMetrics().boundingRect( x+xm, y+m, w-xm-tab+1, h-2*m,
+ text_flags, mi->text() );
+
+ drawSGIPrefix( p, br.x()+p->fontMetrics().leftBearing(miText[0]),
+ br.y()+br.height()+p->fontMetrics().underlinePos()-2, &miText );
+ p->drawText( x+xm, y+m, w-xm-tab+1, h-2*m, text_flags, miText, miText.length() );
+ } else {
+ if ( mi->pixmap() ) {
+ TQPixmap *pixmap = mi->pixmap();
+ if ( pixmap->depth() == 1 )
+ p->setBackgroundMode( Qt::OpaqueMode );
+ p->drawPixmap( x+xm, y+sgiItemFrame, *pixmap );
+ if ( pixmap->depth() == 1 )
+ p->setBackgroundMode( Qt::TransparentMode );
+ }
+ }
+ if ( mi->popup() ) {
+ int dim = (h-2*sgiItemFrame) / 2;
+ tqdrawPrimitive( PE_ArrowRight, p, TQRect( x+w-sgiArrowHMargin-sgiItemFrame-dim, y+h/2-dim/2, dim, dim ), cg, flags );
+ }
+#endif
+ }
+ break;
+
+ case CE_MenuBarItem:
+ {
+#ifndef TQT_NO_MENUDATA
+ if (opt.isDefault())
+ break;
+
+ TQMenuItem *mi = opt.menuItem();
+
+ bool active = flags & Style_Active;
+ int x, y, w, h;
+ r.rect( &x, &y, &w, &h );
+
+ if ( active ) {
+ p->setPen( TQPen( cg.shadow(), 1) );
+ p->drawRect( x, y, w, h );
+ qDrawShadePanel( p, TQRect(x+1,y+1,w-2,h-2), cg, FALSE, 2,
+ &cg.brush( TQColorGroup::Light ));
+ } else {
+ p->fillRect( x, y, w, h, cg.brush( TQColorGroup::Button ));
+ }
+
+ if ( mi->pixmap() )
+ drawItem( p, r, TQt::AlignCenter|TQt::DontClip|TQt::SingleLine,
+ cg, mi->isEnabled(), mi->pixmap(), "", -1, TQT_TQCOLOR_CONST(&cg.buttonText()) );
+
+ if ( !!mi->text() ) {
+ TQString* text = new TQString(mi->text());
+ TQRect br = p->fontMetrics().boundingRect( x, y-2, w+1, h,
+ TQt::AlignCenter|TQt::DontClip|TQt::SingleLine|TQt::ShowPrefix, mi->text() );
+
+ drawSGIPrefix( p, br.x()+p->fontMetrics().leftBearing((*text)[0]),
+ br.y()+br.height()+p->fontMetrics().underlinePos()-2, text );
+ p->drawText( x, y-2, w+1, h, TQt::AlignCenter|TQt::DontClip|TQt::SingleLine, *text, text->length() );
+ delete text;
+ }
+#endif
+ }
+ break;
+
+ case CE_CheckBox:
+ TQMotifStyle::tqdrawControl( element, p, widget, r, cg, flags, opt );
+ break;
+
+ default:
+ TQMotifStyle::tqdrawControl( element, p, widget, r, cg, flags, opt );
+ break;
+ }
+}
+
+/*! \reimp */
+void TQSGIStyle::tqdrawComplexControl( TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget* widget,
+ const TQRect& r,
+ const TQColorGroup& cg,
+ SFlags flags,
+ SCFlags sub,
+ SCFlags subActive,
+ const TQStyleOption& opt ) const
+{
+ if ( widget == d->hotWidget )
+ flags |= Style_MouseOver;
+
+ switch ( control ) {
+ case CC_Slider:
+ {
+#ifndef TQT_NO_SLIDER
+ const TQSlider * slider = (const TQSlider *) widget;
+
+ TQRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove,
+ opt),
+ handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle,
+ opt);
+
+ if ((sub & SC_SliderGroove) && groove.isValid()) {
+ TQRegion region( groove );
+ if ( ( sub & SC_SliderHandle ) && handle.isValid() )
+ region = region.subtract( handle );
+ if ( d->lastSliderRect.slider == slider && d->lastSliderRect.rect.isValid() )
+ region = region.subtract( d->lastSliderRect.rect );
+ p->setClipRegion( region );
+
+ TQRect grooveTop = groove;
+ grooveTop.addCoords( 1, 1, -1, -1 );
+ tqdrawPrimitive( PE_ButtonBevel, p, grooveTop, cg, flags & ~Style_MouseOver, opt );
+
+ if ( flags & Style_HasFocus ) {
+ TQRect fr = subRect( SR_SliderFocusRect, widget );
+ tqdrawPrimitive( PE_FocusRect, p, fr, cg, flags & ~Style_MouseOver );
+ }
+
+ if ( d->lastSliderRect.slider == slider && d->lastSliderRect.rect.isValid() ) {
+ if ( ( sub & SC_SliderHandle ) && handle.isValid() ) {
+ region = widget->rect();
+ region = region.subtract( handle );
+ p->setClipRegion( region );
+ } else {
+ p->setClipping( FALSE );
+ }
+ qDrawShadePanel( p, d->lastSliderRect.rect, cg, TRUE, 1, &cg.brush( TQColorGroup::Dark ) );
+ }
+ p->setClipping( FALSE );
+ }
+
+ if (( sub & SC_SliderHandle ) && handle.isValid()) {
+ if ( flags & Style_MouseOver && !handle.tqcontains( d->mousePos ) && subActive != SC_SliderHandle )
+ flags &= ~Style_MouseOver;
+ tqdrawPrimitive( PE_ButtonBevel, p, handle, cg, flags );
+
+ if ( slider->orientation() == Qt::Horizontal ) {
+ TQCOORD mid = handle.x() + handle.width() / 2;
+ qDrawShadeLine( p, mid, handle.y(), mid,
+ handle.y() + handle.height() - 2,
+ cg, TRUE, 1);
+ } else {
+ TQCOORD mid = handle.y() + handle.height() / 2;
+ qDrawShadeLine( p, handle.x(), mid,
+ handle.x() + handle.width() - 2, mid,
+ cg, TRUE, 1);
+ }
+ }
+
+ if ( sub & SC_SliderTickmarks )
+ TQMotifStyle::tqdrawComplexControl( control, p, widget, r, cg, flags,
+ SC_SliderTickmarks, subActive,
+ opt );
+#endif
+ break;
+ }
+ case CC_ComboBox:
+ {
+#ifndef TQT_NO_COMBOBOX
+ const TQComboBox * cb = (TQComboBox *) widget;
+
+ if (sub & SC_ComboBoxFrame) {
+ TQRect fr =
+ TQStyle::tqvisualRect( querySubControlMetrics( CC_ComboBox, cb,
+ SC_ComboBoxFrame ), cb );
+ tqdrawPrimitive( PE_ButtonBevel, p, fr, cg, flags );
+ }
+
+ if ( sub & SC_ComboBoxArrow ) {
+ p->save();
+ TQRect er =
+ TQStyle::tqvisualRect( querySubControlMetrics( CC_ComboBox, cb, SC_ComboBoxArrow ), cb );
+
+ er.addCoords( 0, 3, 0, 0 );
+
+ tqdrawPrimitive( PE_ArrowDown, p, er, cg, flags | Style_Enabled, opt );
+
+ int awh, ax, ay, sh, sy, dh, ew;
+ get_combo_parameters( widget->rect(), ew, awh, ax, ay, sh, dh, sy );
+
+ TQBrush arrow = cg.brush( TQColorGroup::Dark );
+ p->fillRect( ax, sy-1, awh, sh, arrow );
+
+ p->restore();
+ if ( cb->hasFocus() ) {
+ TQRect re = TQStyle::tqvisualRect( subRect( SR_ComboBoxFocusRect, cb ), cb );
+ tqdrawPrimitive( PE_FocusRect, p, re, cg );
+ }
+ }
+ if ( sub & SC_ComboBoxEditField ) {
+ if ( cb->editable() ) {
+ TQRect er =
+ TQStyle::tqvisualRect( querySubControlMetrics( CC_ComboBox, cb,
+ SC_ComboBoxEditField ), cb );
+ er.addCoords( -1, -1, 1, 1);
+ qDrawShadePanel( p, TQRect( er.x()-1, er.y()-1,
+ er.width()+2, er.height()+2 ),
+ cg, TRUE, 1, &cg.brush( TQColorGroup::Button ) );
+ }
+ }
+#endif
+ p->setPen(cg.buttonText());
+ break;
+ }
+
+ case CC_ScrollBar:
+ {
+#ifndef TQT_NO_SCROLLBAR
+ TQScrollBar *scrollbar = (TQScrollBar*)widget;
+ bool maxedOut = (scrollbar->minValue() == scrollbar->maxValue());
+ if ( maxedOut )
+ flags &= ~Style_Enabled;
+
+ TQRect handle = TQStyle::tqvisualRect( querySubControlMetrics( CC_ScrollBar, widget, SC_ScrollBarSlider, opt ), widget );
+
+ if ( sub & SC_ScrollBarGroove ) {
+ }
+ if ( sub & SC_ScrollBarAddLine ) {
+ TQRect er = TQStyle::tqvisualRect( querySubControlMetrics( CC_ScrollBar, widget, SC_ScrollBarAddLine, opt ), widget );
+ tqdrawPrimitive( PE_ScrollBarAddLine, p, er, cg, flags, opt );
+ }
+ if ( sub & SC_ScrollBarSubLine ) {
+ TQRect er = TQStyle::tqvisualRect( querySubControlMetrics( CC_ScrollBar, widget, SC_ScrollBarSubLine, opt ), widget );
+ tqdrawPrimitive( PE_ScrollBarSubLine, p, er, cg, flags, opt );
+ }
+ if ( sub & SC_ScrollBarAddPage ) {
+ TQRect er = TQStyle::tqvisualRect( querySubControlMetrics( CC_ScrollBar, widget, SC_ScrollBarAddPage, opt ), widget );
+ TQRegion region( er );
+ if ( d->lastScrollbarRect.scrollbar == scrollbar &&
+ d->lastScrollbarRect.rect.isValid() &&
+ er.intersects( d->lastScrollbarRect.rect ) ) {
+ region = region.subtract( d->lastScrollbarRect.rect );
+ p->setClipRegion( region );
+ }
+ if ( sub & SC_ScrollBarSlider && er.intersects( handle ) ) {
+ region = region.subtract( handle );
+ p->setClipRegion( region );
+ }
+
+ tqdrawPrimitive( PE_ScrollBarAddPage, p, er, cg, flags & ~Style_MouseOver, opt );
+
+ if ( d->lastScrollbarRect.scrollbar == scrollbar &&
+ d->lastScrollbarRect.rect.isValid() &&
+ er.intersects( d->lastScrollbarRect.rect ) ) {
+ if ( sub & SC_ScrollBarSlider && handle.isValid() ) {
+ region = er;
+ region.subtract( handle );
+ p->setClipRegion( region );
+ } else {
+ p->setClipping( FALSE );
+ }
+ qDrawShadePanel( p, d->lastScrollbarRect.rect, cg, TRUE, 1, &cg.brush( TQColorGroup::Dark ) );
+ }
+ p->setClipping( FALSE );
+ }
+ if ( sub & SC_ScrollBarSubPage ) {
+ TQRect er = TQStyle::tqvisualRect( querySubControlMetrics( CC_ScrollBar, widget, SC_ScrollBarSubPage, opt ), widget );
+ TQRegion region( er );
+ if ( d->lastScrollbarRect.scrollbar == scrollbar &&
+ d->lastScrollbarRect.rect.isValid() &&
+ er.intersects( d->lastScrollbarRect.rect ) ) {
+ region = region.subtract( d->lastScrollbarRect.rect );
+ p->setClipRegion( region );
+ }
+ if ( sub & SC_ScrollBarSlider && er.intersects( handle ) ) {
+ region = region.subtract( handle );
+ p->setClipRegion( region );
+ }
+ tqdrawPrimitive( PE_ScrollBarSubPage, p, er, cg, flags & ~Style_MouseOver, opt );
+ if ( d->lastScrollbarRect.scrollbar == scrollbar &&
+ d->lastScrollbarRect.rect.isValid() &&
+ er.intersects( d->lastScrollbarRect.rect ) ) {
+ if ( sub & SC_ScrollBarSlider && handle.isValid() ) {
+ region = er;
+ region.subtract( handle );
+ p->setClipRegion( region );
+ } else {
+ p->setClipping( FALSE );
+ }
+ qDrawShadePanel( p, d->lastScrollbarRect.rect, cg, TRUE, 1, &cg.brush( TQColorGroup::Dark ) );
+ }
+ p->setClipping( FALSE );
+ }
+ if ( sub & SC_ScrollBarSlider ) {
+ p->setClipping( FALSE );
+ if ( subActive == SC_ScrollBarSlider )
+ flags |= Style_Active;
+
+ tqdrawPrimitive( PE_ScrollBarSlider, p, handle, cg, flags, opt );
+ }
+#endif
+ }
+ break;
+
+ default:
+ TQMotifStyle::tqdrawComplexControl( control, p, widget, r, cg, flags, sub, subActive, opt );
+ break;
+ }
+}
+
+/*!\reimp
+*/
+TQSize TQSGIStyle::tqsizeFromContents( ContentsType contents,
+ const TQWidget *widget,
+ const TQSize &contentsSize,
+ const TQStyleOption& opt ) const
+{
+ TQSize sz(contentsSize);
+
+ switch(contents) {
+ case CT_PopupMenuItem:
+ {
+#ifndef TQT_NO_POPUPMENU
+ if (! widget || opt.isDefault())
+ break;
+
+ TQMenuItem *mi = opt.menuItem();
+ sz = TQMotifStyle::tqsizeFromContents( contents, widget, contentsSize,
+ opt );
+ // SGI checkmark items needs a bit more room
+ const TQPopupMenu *popup = (TQPopupMenu *) widget;
+ if ( popup && popup->isCheckable() )
+ sz.setWidth( sz.width() + 8 );
+ // submenu indicator needs a bit more room
+ if (mi->popup())
+ sz.setWidth( sz.width() + sgiTabSpacing );
+#endif
+ break;
+ }
+ case CT_ComboBox:
+ sz.rwidth() += 30;
+ break;
+
+ default:
+ sz = TQMotifStyle::tqsizeFromContents( contents, widget, contentsSize, opt );
+ break;
+ }
+
+ return sz;
+}
+
+/*! \reimp */
+TQRect TQSGIStyle::subRect( SubRect r, const TQWidget *widget ) const
+{
+ TQRect rect;
+
+ switch ( r ) {
+ case SR_ComboBoxFocusRect:
+ {
+ int awh, ax, ay, sh, sy, dh, ew;
+ int fw = tqpixelMetric( PM_DefaultFrameWidth, widget );
+ TQRect tr = widget->rect();
+
+ tr.addCoords( fw, fw, -fw, -fw );
+ get_combo_parameters( tr, ew, awh, ax, ay, sh, dh, sy );
+ rect.setRect(ax-2, ay-2, awh+4, awh+sh+dh+4);
+ }
+ break;
+ default:
+ return TQMotifStyle::subRect( r, widget );
+ }
+
+ return rect;
+}
+
+/*! \reimp */
+TQRect TQSGIStyle::querySubControlMetrics( TQ_ComplexControl control,
+ const TQWidget *widget,
+ SubControl sub,
+ const TQStyleOption& opt ) const
+{
+ switch ( control ) {
+ case CC_ComboBox:
+ switch ( sub ) {
+ case SC_ComboBoxFrame:
+ return widget->rect();
+
+ case SC_ComboBoxArrow: {
+ int ew, awh, sh, dh, ax, ay, sy;
+ int fw = tqpixelMetric( PM_DefaultFrameWidth, widget );
+ TQRect cr = widget->rect();
+ cr.addCoords( fw, fw, -fw, -fw );
+ get_combo_parameters( cr, ew, awh, ax, ay, sh, dh, sy );
+ return TQRect( ax, ay, awh, awh ); }
+
+ case SC_ComboBoxEditField: {
+ int fw = tqpixelMetric( PM_DefaultFrameWidth, widget );
+ TQRect rect = widget->rect();
+ rect.addCoords( fw, fw, -fw, -fw );
+ int ew = get_combo_extra_width( rect.height() );
+ rect.addCoords( 1, 1, -1-ew, -1 );
+ return rect; }
+
+ default:
+ break;
+ }
+ break;
+ case CC_ScrollBar:
+ return TQCommonStyle::querySubControlMetrics( control, widget, sub, opt );
+ default: break;
+ }
+ return TQMotifStyle::querySubControlMetrics( control, widget, sub, opt );
+}
+
+#endif // TQT_NO_STYLE_SGI
diff --git a/tqtinterface/qt4/src/styles/tqsgistyle.h b/tqtinterface/qt4/src/styles/tqsgistyle.h
new file mode 100644
index 0000000..5ae9889
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqsgistyle.h
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Definition of SGI-like style class
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSGISTYLE_H
+#define TQSGISTYLE_H
+
+#ifndef TQT_H
+#include "tqmotifstyle.h"
+#include "tqguardedptr.h"
+#include "tqwidget.h"
+#endif // TQT_H
+
+#if !defined(TQT_NO_STYLE_SGI) || defined(TQT_PLUGIN)
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_STYLE_SGI
+#else
+#define TQ_EXPORT_STYLE_SGI TQ_EXPORT
+#endif
+
+class TQSGIStylePrivate;
+
+class TQ_EXPORT_STYLE_SGI TQSGIStyle: public TQMotifStyle
+{
+ TQ_OBJECT
+public:
+ TQSGIStyle( bool useHighlightCols = FALSE );
+ virtual ~TQSGIStyle();
+
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQMotifStyle::polish;
+#endif
+ void polish( TQWidget* );
+ void unPolish( TQWidget* );
+ void polish( TQApplication* );
+ void unPolish( TQApplication* );
+
+ void tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags how = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawComplexControl( TQ_ComplexControl control,
+ TQPainter *p,
+ const TQWidget* widget,
+ const TQRect& r,
+ const TQColorGroup& cg,
+ SFlags how = Style_Default,
+#ifdef TQ_TQDOC
+ SCFlags sub = SC_All,
+#else
+ SCFlags sub = (uint)SC_All,
+#endif
+ SCFlags subActive = SC_None,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ int tqpixelMetric( PixelMetric metric, const TQWidget *widget = 0 ) const;
+
+ TQSize tqsizeFromContents( ContentsType contents,
+ const TQWidget *widget,
+ const TQSize &contentsSize,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ TQRect subRect( SubRect r, const TQWidget *widget ) const;
+ TQRect querySubControlMetrics( TQ_ComplexControl control,
+ const TQWidget *widget,
+ SubControl sc,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+protected:
+ bool eventFilter( TQObject*, TQEvent*);
+
+private:
+ TQSGIStylePrivate *d;
+
+ uint isApplicationStyle :1;
+#if defined(TQ_DISABLE_COPY)
+ TQSGIStyle( const TQSGIStyle & );
+ TQSGIStyle& operator=( const TQSGIStyle & );
+#endif
+
+};
+
+#endif // TQT_NO_STYLE_SGI
+
+#endif // TQSGISTYLE_H
diff --git a/tqtinterface/qt4/src/styles/tqstylefactory.cpp b/tqtinterface/qt4/src/styles/tqstylefactory.cpp
new file mode 100644
index 0000000..42f1c2f
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqstylefactory.cpp
@@ -0,0 +1,268 @@
+/****************************************************************************
+**
+** Implementation of TQStyleFactory class
+**
+** Created : 001103
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqstyleinterface_p.h" // up here for GCC 2.7.* compatibility
+#include "tqstylefactory.h"
+
+#ifndef TQT_NO_STYLE
+
+#include "tqapplication.h"
+#include "tqwindowsstyle.h"
+#include "tqmotifstyle.h"
+#include "tqcdestyle.h"
+#include "tqmotifplusstyle.h"
+#include "tqplatinumstyle.h"
+#include "tqsgistyle.h"
+#include "tqcompactstyle.h"
+#ifndef TQT_NO_STYLE_WINDOWSXP
+#include "tqwindowsxpstyle.h"
+#endif
+#ifndef TQT_NO_STYLE_AQUA
+#include "tqaquastyle.h"
+#endif
+#ifndef TQT_NO_STYLE_POCKETPC
+#include "tqpocketpcstyle_wce.h"
+#endif
+
+#if !defined( TQT_NO_STYLE_MAC ) && defined( TQ_WS_MAC )
+TQString p2qstring(const unsigned char *c); //qglobal.cpp
+#include "tqt_mac.h"
+#include "tqmacstyle_mac.h"
+#endif
+#include <stdlib.h>
+
+#include <private/tqpluginmanager_p.h>
+#ifndef TQT_NO_COMPONENT
+class TQStyleFactoryPrivate : public TQObject
+{
+public:
+ TQStyleFactoryPrivate();
+ ~TQStyleFactoryPrivate();
+
+ static TQPluginManager<TQStyleFactoryInterface> *manager;
+};
+
+static TQStyleFactoryPrivate *instance = 0;
+TQPluginManager<TQStyleFactoryInterface> *TQStyleFactoryPrivate::manager = 0;
+
+TQStyleFactoryPrivate::TQStyleFactoryPrivate()
+: TQObject( tqApp )
+{
+ manager = new TQPluginManager<TQStyleFactoryInterface>( IID_TQStyleFactory, TQApplication::libraryPaths(), "/styles", FALSE );
+}
+
+TQStyleFactoryPrivate::~TQStyleFactoryPrivate()
+{
+ delete manager;
+ manager = 0;
+
+ instance = 0;
+}
+
+#endif //TQT_NO_COMPONENT
+
+/*!
+ \class TQStyleFactory tqstylefactory.h
+ \brief The TQStyleFactory class creates TQStyle objects.
+
+ The style factory creates a TQStyle object for a given key with
+ TQStyleFactory::create(key).
+
+ The styles are either built-in or dynamically loaded from a style
+ plugin (see \l TQStylePlugin).
+
+ TQStyleFactory::keys() returns a list of valid keys, typically
+ including "Windows", "Motif", "CDE", "MotifPlus", "Platinum",
+ "SGI" and "Compact". Depending on the platform, "WindowsXP",
+ "Aqua" or "Macintosh" may be available.
+*/
+
+/*!
+ Creates a TQStyle object that matches \a key case-insensitively.
+ This is either a built-in style, or a style from a style plugin.
+
+ \sa keys()
+*/
+TQStyle *TQStyleFactory::create( const TQString& key )
+{
+ TQStyle *ret = 0;
+ TQString style = key.lower();
+#ifndef TQT_NO_STYLE_WINDOWS
+ if ( style == "windows" )
+ ret = new TQWindowsStyle;
+ else
+#endif
+#ifndef TQT_NO_STYLE_WINDOWSXP
+ if ( style == "windowsxp" )
+ ret = new TQWindowsXPStyle;
+ else
+#endif
+#ifndef TQT_NO_STYLE_MOTIF
+ if ( style == "motif" )
+ ret = new TQMotifStyle;
+ else
+#endif
+#ifndef TQT_NO_STYLE_CDE
+ if ( style == "cde" )
+ ret = new TQCDEStyle;
+ else
+#endif
+#ifndef TQT_NO_STYLE_MOTIFPLUS
+ if ( style == "motifplus" )
+ ret = new TQMotifPlusStyle;
+ else
+#endif
+#ifndef TQT_NO_STYLE_PLATINUM
+ if ( style == "platinum" )
+ ret = new TQPlatinumStyle;
+ else
+#endif
+#ifndef TQT_NO_STYLE_SGI
+ if ( style == "sgi")
+ ret = new TQSGIStyle;
+ else
+#endif
+#ifndef TQT_NO_STYLE_COMPACT
+ if ( style == "compact" )
+ ret = new TQCompactStyle;
+ else
+#endif
+#ifndef TQT_NO_STYLE_AQUA
+ if ( style == "aqua" )
+ ret = new TQAquaStyle;
+#endif
+#ifndef TQT_NO_STYLE_POCKETPC
+ if ( style == "pocketpc" )
+ ret = new TQPocketPCStyle;
+#endif
+#if !defined( TQT_NO_STYLE_MAC ) && defined( TQ_WS_MAC )
+ if( style.left(9) == "macintosh" )
+ ret = new TQMacStyle;
+#endif
+ { } // Keep these here - they make the #ifdefery above work
+
+#ifndef TQT_NO_COMPONENT
+ if(!ret) {
+ if ( !instance )
+ instance = new TQStyleFactoryPrivate;
+
+ TQInterfacePtr<TQStyleFactoryInterface> iface;
+ TQStyleFactoryPrivate::manager->queryInterface( style, &iface );
+
+ if ( iface )
+ ret = iface->create( style );
+ }
+ if(ret)
+ TQT_TQOBJECT(ret)->setName(key);
+#endif
+ return ret;
+}
+
+#ifndef TQT_NO_STRINGLIST
+/*!
+ Returns the list of keys this factory can create styles for.
+
+ \sa create()
+*/
+TQStringList TQStyleFactory::keys()
+{
+ TQStringList list;
+#ifndef TQT_NO_COMPONENT
+ if ( !instance )
+ instance = new TQStyleFactoryPrivate;
+
+ list = TQStyleFactoryPrivate::manager->featureList();
+#endif //TQT_NO_COMPONENT
+
+#ifndef TQT_NO_STYLE_WINDOWS
+ if ( !list.tqcontains( "Windows" ) )
+ list << "Windows";
+#endif
+#ifndef TQT_NO_STYLE_WINDOWSXP
+ if ( !list.tqcontains( "WindowsXP" ) && TQWindowsXPStyle::resolveSymbols() )
+ list << "WindowsXP";
+#endif
+#ifndef TQT_NO_STYLE_MOTIF
+ if ( !list.tqcontains( "Motif" ) )
+ list << "Motif";
+#endif
+#ifndef TQT_NO_STYLE_CDE
+ if ( !list.tqcontains( "CDE" ) )
+ list << "CDE";
+#endif
+#ifndef TQT_NO_STYLE_MOTIFPLUS
+ if ( !list.tqcontains( "MotifPlus" ) )
+ list << "MotifPlus";
+#endif
+#ifndef TQT_NO_STYLE_PLATINUM
+ if ( !list.tqcontains( "Platinum" ) )
+ list << "Platinum";
+#endif
+#ifndef TQT_NO_STYLE_SGI
+ if ( !list.tqcontains( "SGI" ) )
+ list << "SGI";
+#endif
+#ifndef TQT_NO_STYLE_COMPACT
+ if ( !list.tqcontains( "Compact" ) )
+ list << "Compact";
+#endif
+#ifndef TQT_NO_STYLE_ATQUA
+ if ( !list.tqcontains( "Aqua" ) )
+ list << "Aqua";
+#endif
+#if !defined( TQT_NO_STYLE_MAC ) && defined( TQ_WS_MAC )
+ TQString mstyle = "Macintosh";
+ Collection c = NewCollection();
+ if (c) {
+ GetTheme(c);
+ Str255 str;
+ long int s = 256;
+ if(!GetCollectionItem(c, kThemeNameTag, 0, &s, &str))
+ mstyle += " (" + p2qstring(str) + ")";
+ }
+ if (!list.tqcontains(mstyle))
+ list << mstyle;
+ DisposeCollection(c);
+#endif
+
+ return list;
+}
+#endif
+#endif // TQT_NO_STYLE
diff --git a/tqtinterface/qt4/src/styles/tqstylefactory.h b/tqtinterface/qt4/src/styles/tqstylefactory.h
new file mode 100644
index 0000000..0b9a37d
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqstylefactory.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTYLEFACTORY_H
+#define TQSTYLEFACTORY_H
+
+#ifndef TQT_H
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_STYLE
+
+class TQString;
+class TQStyle;
+
+class TQ_EXPORT TQStyleFactory
+{
+public:
+#ifndef TQT_NO_STRINGLIST
+ static TQStringList keys();
+#endif
+ static TQStyle *create( const TQString& );
+};
+
+#endif //TQT_NO_STYLE
+
+#endif //TQSTYLEFACTORY_H
diff --git a/tqtinterface/qt4/src/styles/tqstyleinterface_p.h b/tqtinterface/qt4/src/styles/tqstyleinterface_p.h
new file mode 100644
index 0000000..6b401c2
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqstyleinterface_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTYLEINTERFACE_P_H
+#define TQSTYLEINTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include <private/tqcom_p.h>
+#endif // TQT_H
+
+#ifndef TQT_NO_STYLE
+#ifndef TQT_NO_COMPONENT
+
+class TQStyle;
+
+// {FC1B6EBE-053C-49c1-A483-C377739AB9A5}
+#ifndef IID_TQStyleFactory
+#define IID_TQStyleFactory TQUuid(0xfc1b6ebe, 0x53c, 0x49c1, 0xa4, 0x83, 0xc3, 0x77, 0x73, 0x9a, 0xb9, 0xa5)
+#endif
+
+struct TQ_EXPORT TQStyleFactoryInterface : public TQFeatureListInterface
+{
+ virtual TQStyle* create( const TQString& style ) = 0;
+};
+
+#endif //TQT_NO_COMPONENT
+#endif //TQT_NO_STYLE
+
+#endif //TQSTYLEINTERFACE_P_H
diff --git a/tqtinterface/qt4/src/styles/tqstyleplugin.cpp b/tqtinterface/qt4/src/styles/tqstyleplugin.cpp
new file mode 100644
index 0000000..970d4bb
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqstyleplugin.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** Implementation of TQSqlDriverPlugin class
+**
+** Created : 010920
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqstyleplugin.h"
+
+#ifndef TQT_NO_STYLE
+#ifndef TQT_NO_COMPONENT
+
+#include "tqstyleinterface_p.h"
+#include "tqobjectcleanuphandler.h"
+#include "tqstyle.h"
+
+/*!
+ \class TQStylePlugin tqstyleplugin.h
+ \brief The TQStylePlugin class provides an abstract base for custom TQStyle plugins.
+
+ \ingroup plugins
+
+ The style plugin is a simple plugin interface that makes it easy
+ to create custom styles that can be loaded dynamically into
+ applications with a TQStyleFactory.
+
+ Writing a style plugin is achieved by subclassing this base class,
+ reimplementing the pure virtual functions keys() and create(), and
+ exporting the class with the \c TQ_EXPORT_PLUGIN macro. See the
+ \link plugins-howto.html plugins documentation\endlink for an
+ example.
+*/
+
+/*!
+ \fn TQStringList TQStylePlugin::keys() const
+
+ Returns the list of style keys this plugin supports.
+
+ These keys are usually the class names of the custom styles that
+ are implemented in the plugin.
+
+ \sa create()
+*/
+
+/*!
+ \fn TQStyle* TQStylePlugin::create( const TQString& key )
+
+ Creates and returns a TQStyle object for the style key \a key. The
+ style key is usually the class name of the required style.
+
+ \sa keys()
+*/
+
+class TQStylePluginPrivate : public TQStyleFactoryInterface, public TQLibraryInterface
+{
+public:
+ TQStylePluginPrivate( TQStylePlugin *p )
+ : plugin( p )
+ {
+ }
+
+ virtual ~TQStylePluginPrivate();
+
+ TQRESULT queryInterface( const TQUuid &iid, TQUnknownInterface **iface );
+ TQ_REFCOUNT;
+
+ TQStringList featureList() const;
+ TQStyle *create( const TQString &key );
+
+ bool init();
+ void cleanup();
+ bool canUnload() const;
+
+private:
+ TQStylePlugin *plugin;
+ TQObjectCleanupHandler styles;
+};
+
+TQRESULT TQStylePluginPrivate::queryInterface( const TQUuid &iid, TQUnknownInterface **iface )
+{
+ *iface = 0;
+
+ if ( iid == IID_TQUnknown )
+ *iface = (TQStyleFactoryInterface*)this;
+ else if ( iid == IID_TQFeatureList )
+ *iface = (TQFeatureListInterface*)this;
+ else if ( iid == IID_TQStyleFactory )
+ *iface = (TQStyleFactoryInterface*)this;
+ else if ( iid == IID_TQLibrary )
+ *iface = (TQLibraryInterface*) this;
+ else
+ return TQE_NOINTERFACE;
+
+ (*iface)->addRef();
+ return TQS_OK;
+}
+
+TQStylePluginPrivate::~TQStylePluginPrivate()
+{
+ delete plugin;
+}
+
+TQStringList TQStylePluginPrivate::featureList() const
+{
+ return plugin->keys();
+}
+
+TQStyle *TQStylePluginPrivate::create( const TQString &key )
+{
+ TQStyle *st = plugin->create( key );
+ styles.add( TQT_TQOBJECT(st) );
+ return st;
+}
+
+bool TQStylePluginPrivate::init()
+{
+ return TRUE;
+}
+
+void TQStylePluginPrivate::cleanup()
+{
+ styles.clear();
+}
+
+bool TQStylePluginPrivate::canUnload() const
+{
+ return styles.isEmpty();
+}
+
+
+/*!
+ Constructs a style plugin. This is invoked automatically by the
+ \c TQ_EXPORT_PLUGIN macro.
+*/
+TQStylePlugin::TQStylePlugin()
+ : TQGPlugin( (TQStyleFactoryInterface*)(d = new TQStylePluginPrivate( this )) )
+{
+}
+
+/*!
+ Destroys the style plugin.
+
+ You never have to call this explicitly. TQt destroys a plugin
+ automatically when it is no longer used.
+*/
+TQStylePlugin::~TQStylePlugin()
+{
+ // don't delete d, as this is deleted by d
+}
+
+#endif // TQT_NO_COMPONENT
+#endif // TQT_NO_STYLE
diff --git a/tqtinterface/qt4/src/styles/tqstyleplugin.h b/tqtinterface/qt4/src/styles/tqstyleplugin.h
new file mode 100644
index 0000000..713eae9
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqstyleplugin.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Definition of TQStylePlugin class
+**
+** Created : 010920
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTYLEPLUGIN_H
+#define TQSTYLEPLUGIN_H
+
+#ifndef TQT_H
+#include "tqgplugin.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_STYLE
+#ifndef TQT_NO_COMPONENT
+
+class TQStyle;
+class TQStylePluginPrivate;
+
+class TQ_EXPORT TQStylePlugin : public TQGPlugin
+{
+ TQ_OBJECT
+public:
+ TQStylePlugin();
+ ~TQStylePlugin();
+
+ virtual TQStringList keys() const = 0;
+ virtual TQStyle *create( const TQString &key ) = 0;
+
+private:
+ TQStylePluginPrivate *d;
+};
+
+#endif // TQT_NO_COMPONENT
+#endif // TQT_NO_STYLE
+
+#endif // TQSTYLEPLUGIN_H
diff --git a/tqtinterface/qt4/src/styles/tqwindowsstyle.cpp b/tqtinterface/qt4/src/styles/tqwindowsstyle.cpp
new file mode 100644
index 0000000..aa65a5b
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqwindowsstyle.cpp
@@ -0,0 +1,2166 @@
+/****************************************************************************
+**
+** Implementation of Windows-like style class
+**
+** Created : 981231
+**
+** Copyright (C) 1998-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+// ** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwindowsstyle.h"
+
+#if !defined(TQT_NO_STYLE_WINDOWS) || defined(TQT_PLUGIN)
+
+#include "tqpopupmenu.h"
+#include "tqapplication.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h" // for now
+#include "tqpixmap.h" // for now
+#include "tqwidget.h"
+#include "tqbrush.h"
+#include "tqlabel.h"
+#include "tqimage.h"
+#include "tqpushbutton.h"
+#include "tqcombobox.h"
+#include "tqlistbox.h"
+#include "tqwidget.h"
+#include "tqrangecontrol.h"
+#include "tqscrollbar.h"
+#include "tqslider.h"
+#include "tqtabwidget.h"
+#include "tqtabbar.h"
+#include "tqlistview.h"
+#include "tqbitmap.h"
+#include "tqcleanuphandler.h"
+#include "tqdockwindow.h"
+#include "tqobjectlist.h"
+#include "tqmenubar.h"
+
+#if defined(TQ_WS_WIN)
+#include "tqt_windows.h"
+#endif
+
+#include <limits.h>
+
+
+static const int windowsItemFrame = 2; // menu item frame width
+static const int windowsSepHeight = 2; // separator item height
+static const int windowsItemHMargin = 3; // menu item hor text margin
+static const int windowsItemVMargin = 2; // menu item ver text margin
+static const int windowsArrowHMargin = 6; // arrow horizontal margin
+static const int windowsTabSpacing = 12; // space between text and tab
+static const int windowsCheckMarkHMargin = 2; // horiz. margins of check mark
+static const int windowsRightBorder = 12; // right border on windows
+static const int windowsCheckMarkWidth = 12; // checkmarks width on windows
+
+static bool use2000style = TRUE;
+
+enum TQSliderDirection { SlUp, SlDown, SlLeft, SlRight };
+
+// A friendly class providing access to TQMenuData's protected member.
+class FriendlyMenuData : public TQMenuData
+{
+ friend class TQWindowsStyle;
+};
+
+// Private class
+class TQWindowsStyle::Private : public TQObject
+{
+public:
+ Private(TQWindowsStyle *tqparent);
+
+ bool hasSeenAlt(const TQWidget *widget) const;
+ bool altDown() const { return alt_down; }
+
+protected:
+ bool eventFilter(TQObject *o, TQEvent *e);
+
+private:
+ TQPtrList<TQWidget> seenAlt;
+ bool alt_down;
+ int menuBarTimer;
+};
+
+TQWindowsStyle::Private::Private(TQWindowsStyle *tqparent)
+: TQObject(tqparent, "TQWindowsStylePrivate"), alt_down(FALSE), menuBarTimer(0)
+{
+}
+
+// Returns true if the toplevel tqparent of \a widget has seen the Alt-key
+bool TQWindowsStyle::Private::hasSeenAlt(const TQWidget *widget) const
+{
+ widget = widget->tqtopLevelWidget();
+ return seenAlt.tqcontains(widget);
+}
+
+// Records Alt- and Focus events
+bool TQWindowsStyle::Private::eventFilter(TQObject *o, TQEvent *e)
+{
+ if (!o->isWidgetType())
+ return TQObject::eventFilter(o, e);
+
+ TQWidget *widget = ::tqqt_cast<TQWidget*>(o);
+
+ switch(e->type()) {
+ case TQEvent::KeyPress:
+ if (((TQKeyEvent*)e)->key() == Qt::Key_Alt) {
+ widget = widget->tqtopLevelWidget();
+
+ // Alt has been pressed - tqfind all widgets that care
+ TQObjectList *l = widget->queryList("TQWidget");
+ TQObjectListIt it( *l );
+ TQWidget *w;
+ while ( (w = (TQWidget*)it.current()) != 0 ) {
+ ++it;
+ if (w->isTopLevel() || !w->isVisible() ||
+ w->tqstyle().tqstyleHint(SH_UnderlineAccelerator, w))
+ l->removeRef(TQT_TQOBJECT(w));
+ }
+ // Update states before repainting
+ seenAlt.append(widget);
+ alt_down = TRUE;
+
+ // Repaint all relevant widgets
+ it.toFirst();
+ while ( (w = (TQWidget*)it.current()) != 0 ) {
+ ++it;
+ w->tqrepaint(FALSE);
+ }
+ delete l;
+ }
+ break;
+ case TQEvent::KeyRelease:
+ if (((TQKeyEvent*)e)->key() == Qt::Key_Alt) {
+ widget = widget->tqtopLevelWidget();
+
+ // Update state
+ alt_down = FALSE;
+ // Repaint only menubars
+ TQObjectList *l = widget->queryList("TQMenuBar");
+ TQObjectListIt it( *l );
+ TQMenuBar *menuBar;
+ while ( (menuBar = (TQMenuBar*)it.current()) != 0) {
+ ++it;
+ menuBar->tqrepaint(FALSE);
+ }
+ }
+ break;
+ case TQEvent::FocusIn:
+ case TQEvent::FocusOut:
+ {
+ // Menubars toggle based on focus
+ TQMenuBar *menuBar = ::tqqt_cast<TQMenuBar*>(o);
+ if (menuBar && !menuBarTimer) // delayed tqrepaint to avoid flicker
+ menuBarTimer = menuBar->startTimer(0);
+ }
+ break;
+ case TQEvent::Close:
+ // Reset widget when closing
+ seenAlt.removeRef(TQT_TQWIDGET(widget));
+ seenAlt.removeRef(TQT_TQWIDGET(widget->tqtopLevelWidget()));
+ break;
+ case TQEvent::Timer:
+ {
+ TQMenuBar *menuBar = ::tqqt_cast<TQMenuBar*>(o);
+ TQTimerEvent *te = (TQTimerEvent*)e;
+ if (menuBar && te->timerId() == menuBarTimer) {
+ menuBar->killTimer(te->timerId());
+ menuBarTimer = 0;
+ menuBar->tqrepaint(FALSE);
+ return TRUE;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ return TQObject::eventFilter(o, e);
+}
+
+/*!
+ \class TQWindowsStyle tqwindowsstyle.h
+ \brief The TQWindowsStyle class provides a Microsoft Windows-like look and feel.
+
+ \ingroup appearance
+
+ This style is TQt's default GUI style on Windows.
+*/
+
+/*!
+ Constructs a TQWindowsStyle
+*/
+TQWindowsStyle::TQWindowsStyle() : TQCommonStyle(), d(0)
+{
+#if defined(TQ_OS_WIN32)
+ use2000style = qWinVersion() != TQt::WV_NT && qWinVersion() != TQt::WV_95;
+#endif
+}
+
+/*! \reimp */
+TQWindowsStyle::~TQWindowsStyle()
+{
+ delete d;
+}
+
+/*! \reimp */
+void TQWindowsStyle::polish(TQApplication *app)
+{
+ // We only need the overhead when shortcuts are sometimes hidden
+ if (!tqstyleHint(SH_UnderlineAccelerator, 0)) {
+ d = new Private(this);
+ app->installEventFilter(d);
+ }
+}
+
+/*! \reimp */
+void TQWindowsStyle::unPolish(TQApplication *)
+{
+ delete d;
+ d = 0;
+}
+
+/*! \reimp */
+void TQWindowsStyle::polish(TQWidget *widget)
+{
+ TQCommonStyle::polish(widget);
+}
+
+/*! \reimp */
+void TQWindowsStyle::unPolish(TQWidget *widget)
+{
+ TQCommonStyle::polish(widget);
+}
+
+/*! \reimp */
+void TQWindowsStyle::polish( TQPalette &pal )
+{
+ TQCommonStyle::polish(pal);
+}
+
+/*! \reimp */
+void TQWindowsStyle::tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ TQRect rr( r );
+ switch (pe) {
+ case PE_ButtonCommand:
+ {
+ TQBrush fill;
+
+ if (! (flags & Style_Down) && (flags & Style_On))
+ fill = TQBrush(cg.light(), Qt::Dense4Pattern);
+ else
+ fill = cg.brush(TQColorGroup::Button);
+
+ if (flags & Style_ButtonDefault && flags & Style_Down) {
+ p->setPen(cg.dark());
+ p->setBrush(fill);
+ p->drawRect(r);
+ } else if (flags & (Style_Raised | Style_Down | Style_On | Style_Sunken))
+ qDrawWinButton(p, r, cg, flags & (Style_Sunken | Style_Down |
+ Style_On), &fill);
+ else
+ p->fillRect(r, fill);
+ break;
+ }
+
+ case PE_ButtonBevel:
+ case PE_HeaderSection:
+ {
+ TQBrush fill;
+
+ if (! (flags & Style_Down) && (flags & Style_On))
+ fill = TQBrush(cg.light(), Qt::Dense4Pattern);
+ else
+ fill = cg.brush(TQColorGroup::Button);
+
+ if (flags & (Style_Raised | Style_Down | Style_On | Style_Sunken))
+ qDrawWinButton(p, r, cg, flags & (Style_Down | Style_On), &fill);
+ else
+ p->fillRect(r, fill);
+ break;
+ }
+#if defined(TQ_WS_WIN)
+ case PE_HeaderArrow:
+ p->save();
+ if ( flags & Style_Up ) { // invert logic to follow Windows style guide
+ TQPointArray pa( 3 );
+ p->setPen( cg.light() );
+ p->drawLine( r.x() + r.width(), r.y(), r.x() + r.width() / 2, r.height() );
+ p->setPen( cg.dark() );
+ pa.setPoint( 0, r.x() + r.width() / 2, r.height() );
+ pa.setPoint( 1, r.x(), r.y() );
+ pa.setPoint( 2, r.x() + r.width(), r.y() );
+ p->drawPolyline( pa );
+ } else {
+ TQPointArray pa( 3 );
+ p->setPen( cg.light() );
+ pa.setPoint( 0, r.x(), r.height() );
+ pa.setPoint( 1, r.x() + r.width(), r.height() );
+ pa.setPoint( 2, r.x() + r.width() / 2, r.y() );
+ p->drawPolyline( pa );
+ p->setPen( cg.dark() );
+ p->drawLine( r.x(), r.height(), r.x() + r.width() / 2, r.y() );
+ }
+ p->restore();
+ break;
+#endif
+
+ case PE_ButtonDefault:
+ p->setPen(cg.shadow());
+ p->drawRect(r);
+ break;
+
+ case PE_ButtonTool:
+ {
+ TQBrush fill;
+ bool stippled = FALSE;
+
+ if (! (flags & (Style_Down | Style_MouseOver)) &&
+ (flags & Style_On) &&
+ use2000style) {
+ fill = TQBrush(cg.light(), Qt::Dense4Pattern);
+ stippled = TRUE;
+ } else
+ fill = cg.brush(TQColorGroup::Button);
+
+ if (flags & (Style_Raised | Style_Down | Style_On)) {
+ if (flags & Style_AutoRaise) {
+ qDrawShadePanel(p, r, cg, flags & (Style_Down | Style_On),
+ 1, &fill);
+
+ if (stippled) {
+ p->setPen(cg.button());
+ p->drawRect(r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2);
+ }
+ } else
+ qDrawWinButton(p, r, cg, flags & (Style_Down | Style_On),
+ &fill);
+ } else
+ p->fillRect(r, fill);
+
+ break;
+ }
+
+ case PE_FocusRect:
+ if (opt.isDefault())
+ p->drawWinFocusRect(r);
+#ifndef USE_QT4 // [FIXME]
+ else
+ p->drawWinFocusRect(r, opt.color());
+#endif // USE_QT4
+ break;
+
+ case PE_Indicator:
+ {
+ TQBrush fill;
+ if (flags & Style_NoChange) {
+ TQBrush b = p->brush();
+ TQColor c = p->backgroundColor();
+ p->setBackgroundMode( Qt::TransparentMode );
+ p->setBackgroundColor( Qt::green );
+ fill = TQBrush(cg.base(), Qt::Dense4Pattern);
+ p->setBackgroundColor( c );
+ p->setBrush( b );
+ } else if (flags & Style_Down)
+ fill = cg.brush( TQColorGroup::Button );
+ else if (flags & Style_Enabled)
+ fill = cg.brush( TQColorGroup::Base );
+ else
+ fill = cg.brush( TQColorGroup::Background );
+
+ qDrawWinPanel( p, r, cg, TRUE, &fill );
+
+ if (flags & Style_NoChange )
+ p->setPen( cg.dark() );
+ else
+ p->setPen( cg.text() );
+ } // FALLTHROUGH
+ case PE_CheckListIndicator:
+ if ( pe == PE_CheckListIndicator ) { //since we fall through from PE_Indicator
+ if ( flags & Style_Enabled )
+ p->setPen( TQPen( cg.text(), 1 ) );
+ else
+ p->setPen( TQPen( cg.dark(), 1 ) );
+ if ( flags & Style_NoChange )
+ p->setBrush( cg.brush( TQColorGroup::Button ) );
+ p->drawRect( r.x()+1, r.y()+1, 11, 11 );
+ }
+ if (! (flags & Style_Off)) {
+ TQPointArray a( 7*2 );
+ int i, xx, yy;
+ xx = rr.x() + 3;
+ yy = rr.y() + 5;
+
+ for ( i=0; i<3; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy++;
+ }
+
+ yy -= 2;
+ for ( i=3; i<7; i++ ) {
+ a.setPoint( 2*i, xx, yy );
+ a.setPoint( 2*i+1, xx, yy+2 );
+ xx++; yy--;
+ }
+
+ p->drawLineSegments( a );
+ }
+ break;
+
+ case PE_ExclusiveIndicator:
+ {
+#define TQCOORDARRLEN(x) sizeof(x)/(sizeof(TQCOORD)*2)
+ static const TQCOORD pts1[] = { // dark lines
+ 1,9, 1,8, 0,7, 0,4, 1,3, 1,2, 2,1, 3,1, 4,0, 7,0, 8,1, 9,1 };
+ static const TQCOORD pts2[] = { // black lines
+ 2,8, 1,7, 1,4, 2,3, 2,2, 3,2, 4,1, 7,1, 8,2, 9,2 };
+ static const TQCOORD pts3[] = { // background lines
+ 2,9, 3,9, 4,10, 7,10, 8,9, 9,9, 9,8, 10,7, 10,4, 9,3 };
+ static const TQCOORD pts4[] = { // white lines
+ 2,10, 3,10, 4,11, 7,11, 8,10, 9,10, 10,9, 10,8, 11,7,
+ 11,4, 10,3, 10,2 };
+ static const TQCOORD pts5[] = { // inner fill
+ 4,2, 7,2, 9,4, 9,7, 7,9, 4,9, 2,7, 2,4 };
+
+ // make sure the indicator is square
+ TQRect ir = r;
+
+ if (r.width() < r.height()) {
+ ir.setTop(r.top() + (r.height() - r.width()) / 2);
+ ir.setHeight(r.width());
+ } else if (r.height() < r.width()) {
+ ir.setLeft(r.left() + (r.width() - r.height()) / 2);
+ ir.setWidth(r.height());
+ }
+
+ p->eraseRect(ir);
+ bool down = flags & Style_Down;
+ bool enabled = flags & Style_Enabled;
+ bool on = flags & Style_On;
+ TQPointArray a;
+ a.setPoints( TQCOORDARRLEN(pts1), pts1 );
+ a.translate( ir.x(), ir.y() );
+ p->setPen( cg.dark() );
+ p->drawPolyline( a );
+ a.setPoints( TQCOORDARRLEN(pts2), pts2 );
+ a.translate( ir.x(), ir.y() );
+ p->setPen( cg.shadow() );
+ p->drawPolyline( a );
+ a.setPoints( TQCOORDARRLEN(pts3), pts3 );
+ a.translate( ir.x(), ir.y() );
+ p->setPen( cg.midlight() );
+ p->drawPolyline( a );
+ a.setPoints( TQCOORDARRLEN(pts4), pts4 );
+ a.translate( ir.x(), ir.y() );
+ p->setPen( cg.light() );
+ p->drawPolyline( a );
+ a.setPoints( TQCOORDARRLEN(pts5), pts5 );
+ a.translate( ir.x(), ir.y() );
+ TQColor fillColor = ( down || !enabled ) ? cg.button() : cg.base();
+ p->setPen( fillColor );
+ p->setBrush( fillColor ) ;
+ p->drawPolygon( a );
+ if ( on ) {
+ p->setPen( Qt::NoPen );
+ p->setBrush( cg.text() );
+ p->drawRect( ir.x() + 5, ir.y() + 4, 2, 4 );
+ p->drawRect( ir.x() + 4, ir.y() + 5, 4, 2 );
+ }
+ break;
+ }
+
+ case PE_Panel:
+ case PE_PanelPopup:
+ {
+ int lw = opt.isDefault() ? tqpixelMetric(PM_DefaultFrameWidth)
+ : opt.lineWidth();
+
+ if (lw == 2) {
+ TQColorGroup popupCG = cg;
+ if ( pe == PE_PanelPopup ) {
+ popupCG.setColor( TQColorGroup::Light, cg.background() );
+ popupCG.setColor( TQColorGroup::Midlight, cg.light() );
+ }
+ qDrawWinPanel(p, r, popupCG, flags & Style_Sunken);
+ } else {
+ TQCommonStyle::tqdrawPrimitive(pe, p, r, cg, flags, opt);
+ }
+ break;
+ }
+
+ case PE_Splitter:
+ {
+ TQPen oldPen = p->pen();
+ p->setPen( cg.light() );
+ if ( flags & Style_Horizontal ) {
+ p->drawLine( r.x() + 1, r.y(), r.x() + 1, r.height() );
+ p->setPen( cg.dark() );
+ p->drawLine( r.x(), r.y(), r.x(), r.height() );
+ p->drawLine( r.right()-1, r.y(), r.right()-1, r.height() );
+ p->setPen( cg.shadow() );
+ p->drawLine( r.right(), r.y(), r.right(), r.height() );
+ } else {
+ p->drawLine( r.x(), r.y() + 1, r.width(), r.y() + 1 );
+ p->setPen( cg.dark() );
+ p->drawLine( r.x(), r.bottom() - 1, r.width(), r.bottom() - 1 );
+ p->setPen( cg.shadow() );
+ p->drawLine( r.x(), r.bottom(), r.width(), r.bottom() );
+ }
+ p->setPen( oldPen );
+ break;
+ }
+#ifndef USE_QT4 // [FIXME]
+ case PE_DockWindowResizeHandle:
+ {
+ TQPen oldPen = p->pen();
+ p->setPen( cg.light() );
+ if ( flags & Style_Horizontal ) {
+ p->drawLine( r.x(), r.y(), r.width(), r.y() );
+ p->setPen( cg.dark() );
+ p->drawLine( r.x(), r.bottom() - 1, r.width(), r.bottom() - 1 );
+ p->setPen( cg.shadow() );
+ p->drawLine( r.x(), r.bottom(), r.width(), r.bottom() );
+ } else {
+ p->drawLine( r.x(), r.y(), r.x(), r.height() );
+ p->setPen( cg.dark() );
+ p->drawLine( r.right()-1, r.y(), r.right()-1, r.height() );
+ p->setPen( cg.shadow() );
+ p->drawLine( r.right(), r.y(), r.right(), r.height() );
+ }
+ p->setPen( oldPen );
+ break;
+ }
+#endif // USE_QT4
+
+ case PE_ScrollBarSubLine:
+ if (use2000style) {
+ if (flags & Style_Down) {
+ p->setPen( cg.dark() );
+ p->setBrush( cg.brush( TQColorGroup::Button ) );
+ p->drawRect( r );
+ } else
+ tqdrawPrimitive(PE_ButtonBevel, p, r, cg, flags | Style_Raised);
+ } else
+ tqdrawPrimitive(PE_ButtonBevel, p, r, cg, (flags & Style_Enabled) |
+ ((flags & Style_Down) ? Style_Down : Style_Raised));
+
+ tqdrawPrimitive(((flags & Style_Horizontal) ? PE_ArrowLeft : PE_ArrowUp),
+ p, r, cg, flags);
+ break;
+
+ case PE_ScrollBarAddLine:
+ if (use2000style) {
+ if (flags & Style_Down) {
+ p->setPen( cg.dark() );
+ p->setBrush( cg.brush( TQColorGroup::Button ) );
+ p->drawRect( r );
+ } else
+ tqdrawPrimitive(PE_ButtonBevel, p, r, cg, flags | Style_Raised);
+ } else
+ tqdrawPrimitive(PE_ButtonBevel, p, r, cg, (flags & Style_Enabled) |
+ ((flags & Style_Down) ? Style_Down : Style_Raised));
+
+ tqdrawPrimitive(((flags & Style_Horizontal) ? PE_ArrowRight : PE_ArrowDown),
+ p, r, cg, flags);
+ break;
+
+ case PE_ScrollBarAddPage:
+ case PE_ScrollBarSubPage:
+ {
+ TQBrush br;
+ TQColor c = p->backgroundColor();
+
+ p->setPen(Qt::NoPen);
+ p->setBackgroundMode(Qt::OpaqueMode);
+
+ if (flags & Style_Down) {
+ br = TQBrush(cg.shadow(), Qt::Dense4Pattern);
+ p->setBackgroundColor( cg.dark() );
+ p->setBrush( TQBrush(cg.shadow(), Qt::Dense4Pattern) );
+ } else {
+ br = (TQT_TQBRUSH_OBJECT(cg.brush(TQColorGroup::Light)).pixmap() ?
+ cg.brush(TQColorGroup::Light) :
+ TQBrush(cg.light(), Qt::Dense4Pattern));
+ p->setBrush(br);
+ }
+
+ p->drawRect(r);
+ p->setBackgroundColor(c);
+ break;
+ }
+
+ case PE_ScrollBarSlider:
+ if (! (flags & Style_Enabled)) {
+ TQBrush br = (TQT_TQBRUSH_OBJECT(cg.brush(TQColorGroup::Light)).pixmap() ?
+ cg.brush(TQColorGroup::Light) :
+ TQBrush(cg.light(), Qt::Dense4Pattern));
+ p->setPen(Qt::NoPen);
+ p->setBrush(br);
+ p->setBackgroundMode(Qt::OpaqueMode);
+ p->drawRect(r);
+ } else
+ tqdrawPrimitive(PE_ButtonBevel, p, r, cg, Style_Enabled | Style_Raised);
+ break;
+
+ case PE_WindowFrame:
+ {
+ TQColorGroup popupCG = cg;
+ popupCG.setColor( TQColorGroup::Light, cg.background() );
+ popupCG.setColor( TQColorGroup::Midlight, cg.light() );
+ qDrawWinPanel(p, r, popupCG, flags & Style_Sunken);
+ }
+ break;
+
+ default:
+ if (pe >= PE_ArrowUp && pe <= PE_ArrowLeft) {
+ TQPointArray a;
+
+ switch ( pe ) {
+ case PE_ArrowUp:
+ a.setPoints( 7, -4,1, 2,1, -3,0, 1,0, -2,-1, 0,-1, -1,-2 );
+ break;
+
+ case PE_ArrowDown:
+ a.setPoints( 7, -4,-2, 2,-2, -3,-1, 1,-1, -2,0, 0,0, -1,1 );
+ break;
+
+ case PE_ArrowRight:
+ a.setPoints( 7, -2,-3, -2,3, -1,-2, -1,2, 0,-1, 0,1, 1,0 );
+ break;
+
+ case PE_ArrowLeft:
+ a.setPoints( 7, 0,-3, 0,3, -1,-2, -1,2, -2,-1, -2,1, -3,0 );
+ break;
+
+ default:
+ break;
+ }
+
+ if (a.isNull())
+ return;
+
+ p->save();
+ if ( flags & Style_Down )
+ p->translate( tqpixelMetric( PM_ButtonShiftHorizontal ),
+ tqpixelMetric( PM_ButtonShiftVertical ) );
+
+ if ( flags & Style_Enabled ) {
+ a.translate( r.x() + r.width() / 2, r.y() + r.height() / 2 );
+ p->setPen( cg.buttonText() );
+ p->drawLineSegments( a, 0, 3 ); // draw arrow
+ p->drawPoint( a[6] );
+ } else {
+ a.translate( r.x() + r.width() / 2 + 1, r.y() + r.height() / 2 + 1 );
+ p->setPen( cg.light() );
+ p->drawLineSegments( a, 0, 3 ); // draw arrow
+ p->drawPoint( a[6] );
+ a.translate( -1, -1 );
+ p->setPen( cg.mid() );
+ p->drawLineSegments( a, 0, 3 ); // draw arrow
+ p->drawPoint( a[6] );
+ }
+ p->restore();
+ } else
+ TQCommonStyle::tqdrawPrimitive(pe, p, r, cg, flags, opt);
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQWindowsStyle::tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ const TQStyleOption& opt ) const
+{
+ switch (element) {
+#ifndef TQT_NO_TABBAR
+ case CE_TabBarTab:
+ {
+ if ( !widget || !widget->parentWidget() || !opt.tab() )
+ break;
+
+ const TQTabBar * tb = (const TQTabBar *) widget;
+ const TQTab * t = opt.tab();
+ bool selected = flags & Style_Selected;
+ bool lastTab = (tb->indexOf( t->identifier() ) == tb->count()-1) ?
+ TRUE : FALSE;
+ TQRect r2( r );
+ if ( tb->tqshape() == TQTabBar::RoundedAbove ) {
+ p->setPen( cg.midlight() );
+
+ p->drawLine( r2.left(), r2.bottom(), r2.right(), r2.bottom() );
+ p->setPen( cg.light() );
+ p->drawLine( r2.left(), r2.bottom()-1, r2.right(), r2.bottom()-1 );
+ if ( r2.left() == 0 )
+ p->drawPoint( tb->rect().bottomLeft() );
+
+ if ( selected ) {
+ p->fillRect( TQRect( r2.left()+1, r2.bottom()-1, r2.width()-3, 2),
+ cg.brush( TQColorGroup::Background ));
+ p->setPen( cg.background() );
+ p->drawLine( r2.left()+1, r2.bottom(), r2.left()+1, r2.top()+2 );
+ p->setPen( cg.light() );
+ } else {
+ p->setPen( cg.light() );
+ r2.setRect( r2.left() + 2, r2.top() + 2,
+ r2.width() - 4, r2.height() - 2 );
+ }
+
+ int x1, x2;
+ x1 = r2.left();
+ x2 = r2.right() - 2;
+ p->drawLine( x1, r2.bottom()-1, x1, r2.top() + 2 );
+ x1++;
+ p->drawPoint( x1, r2.top() + 1 );
+ x1++;
+ p->drawLine( x1, r2.top(), x2, r2.top() );
+ if ( r2.left() > 0 ) {
+ p->setPen( cg.midlight() );
+ }
+ x1 = r2.left();
+ p->drawPoint( x1, r2.bottom());
+
+ p->setPen( cg.midlight() );
+ x1++;
+ p->drawLine( x1, r2.bottom(), x1, r2.top() + 2 );
+ x1++;
+ p->drawLine( x1, r2.top()+1, x2, r2.top()+1 );
+
+ p->setPen( cg.dark() );
+ x2 = r2.right() - 1;
+ p->drawLine( x2, r2.top() + 2, x2, r2.bottom() - 1 +
+ (selected ? 1:-1) );
+ p->setPen( cg.shadow() );
+ p->drawPoint( x2, r2.top() + 1 );
+ p->drawPoint( x2, r2.top() + 1 );
+ x2++;
+ p->drawLine( x2, r2.top() + 2, x2, r2.bottom() -
+ (selected ? (lastTab ? 0:1) :2));
+ } else if ( tb->tqshape() == TQTabBar::RoundedBelow ) {
+ bool rightAligned = tqstyleHint( SH_TabBar_Alignment, tb ) == TQt::AlignRight;
+ bool firstTab = tb->indexOf( t->identifier() ) == 0;
+ if ( selected ) {
+ p->fillRect( TQRect( r2.left()+1, r2.top(), r2.width()-3, 1),
+ cg.brush( TQColorGroup::Background ));
+ p->setPen( cg.background() );
+ p->drawLine( r2.left()+1, r2.top(), r2.left()+1, r2.bottom()-2 );
+ p->setPen( cg.dark() );
+ } else {
+ p->setPen( cg.shadow() );
+ p->drawLine( r2.left() +
+ (rightAligned && firstTab ? 0 : 1),
+ r2.top() + 1,
+ r2.right() - (lastTab ? 0 : 2),
+ r2.top() + 1 );
+
+ if ( rightAligned && lastTab )
+ p->drawPoint( r2.right(), r2.top() );
+ p->setPen( cg.dark() );
+ p->drawLine( r2.left(), r2.top(), r2.right() - 1,
+ r2.top() );
+ r2.setRect( r2.left() + 2, r2.top(),
+ r2.width() - 4, r2.height() - 2 );
+ }
+
+ p->drawLine( r2.right() - 1, r2.top() + (selected ? 0: 2),
+ r2.right() - 1, r2.bottom() - 2 );
+ p->drawPoint( r2.right() - 2, r2.bottom() - 2 );
+ p->drawLine( r2.right() - 2, r2.bottom() - 1,
+ r2.left() + 1, r2.bottom() - 1 );
+
+ p->setPen( cg.midlight() );
+ p->drawLine( r2.left() + 1, r2.bottom() - 2,
+ r2.left() + 1, r2.top() + (selected ? 0 : 2) );
+
+ p->setPen( cg.shadow() );
+ p->drawLine( r2.right(),
+ r2.top() + (lastTab && rightAligned &&
+ selected) ? 0 : 1,
+ r2.right(), r2.bottom() - 1 );
+ p->drawPoint( r2.right() - 1, r2.bottom() - 1 );
+ p->drawLine( r2.right() - 1, r2.bottom(),
+ r2.left() + 2, r2.bottom() );
+
+ p->setPen( cg.light() );
+ p->drawLine( r2.left(), r2.top() + (selected ? 0 : 2),
+ r2.left(), r2.bottom() - 2 );
+ } else {
+ TQCommonStyle::tqdrawControl(element, p, widget, r, cg, flags, opt);
+ }
+ break;
+ }
+#endif // TQT_NO_TABBAR
+ case CE_ToolBoxTab:
+ {
+ qDrawShadePanel( p, r, cg, flags & (Style_Sunken | Style_Down | Style_On) , 1,
+ &cg.brush(TQColorGroup::Button));
+ break;
+ }
+
+#ifndef TQT_NO_POPUPMENU
+ case CE_PopupMenuItem:
+ {
+ if (! widget || opt.isDefault())
+ break;
+
+ const TQPopupMenu *popupmenu = (const TQPopupMenu *) widget;
+ TQMenuItem *mi = opt.menuItem();
+ if ( !mi )
+ break;
+
+ int tab = opt.tabWidth();
+ int maxpmw = opt.maxIconWidth();
+ bool dis = !(flags&Style_Enabled);
+ bool checkable = popupmenu->isCheckable();
+ bool act = flags & Style_Active;
+ int x, y, w, h;
+
+ r.rect(&x, &y, &w, &h);
+
+ if ( checkable ) {
+ // space for the checkmarks
+ if (use2000style)
+ maxpmw = TQMAX( maxpmw, 20 );
+ else
+ maxpmw = TQMAX( maxpmw, 12 );
+ }
+
+ int checkcol = maxpmw;
+
+ if ( mi && mi->isSeparator() ) { // draw separator
+ p->setPen( cg.dark() );
+ p->drawLine( x, y, x+w, y );
+ p->setPen( cg.light() );
+ p->drawLine( x, y+1, x+w, y+1 );
+ return;
+ }
+
+ TQBrush fill = (act ?
+ cg.brush( TQColorGroup::Highlight ) :
+ cg.brush( TQColorGroup::Button ));
+ p->fillRect( x, y, w, h, fill);
+
+ if ( !mi )
+ return;
+
+ int xpos = x;
+ TQRect vrect = tqvisualRect( TQRect( xpos, y, checkcol, h ), r );
+ int xvis = vrect.x();
+ if ( mi->isChecked() ) {
+ if ( act && !dis )
+ qDrawShadePanel( p, xvis, y, checkcol, h,
+ cg, TRUE, 1, &cg.brush( TQColorGroup::Button ) );
+ else {
+ TQBrush fill( cg.light(), Qt::Dense4Pattern );
+ // set the brush origin for the hash pattern to the x/y coordinate
+ // of the menu item's checkmark... this way, the check marks have
+ // a consistent look
+ TQPoint origin = p->brushOrigin();
+ p->setBrushOrigin( xvis, y );
+ qDrawShadePanel( p, xvis, y, checkcol, h, cg, TRUE, 1,
+ &fill );
+ // restore the previous brush origin
+ p->setBrushOrigin( origin );
+ }
+ } else if (! act)
+ p->fillRect(xvis, y, checkcol , h, cg.brush( TQColorGroup::Button ));
+
+ if ( mi->iconSet() ) { // draw iconset
+ TQIconSet::Mode mode = dis ? TQIconSet::Disabled : TQIconSet::Normal;
+ if (act && !dis )
+ mode = TQIconSet::Active;
+ TQPixmap pixmap;
+ if ( checkable && mi->isChecked() )
+ pixmap = mi->iconSet()->pixmap( TQIconSet::Small, mode, TQIconSet::On );
+ else
+ pixmap = mi->iconSet()->pixmap( TQIconSet::Small, mode );
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ if ( act && !dis && !mi->isChecked() )
+ qDrawShadePanel( p, xvis, y, checkcol, h, cg, FALSE, 1,
+ &cg.brush( TQColorGroup::Button ) );
+ TQRect pmr( 0, 0, pixw, pixh );
+ pmr.moveCenter( vrect.center() );
+ p->setPen( cg.text() );
+ p->drawPixmap( pmr.topLeft(), pixmap );
+
+ fill = (act ?
+ cg.brush( TQColorGroup::Highlight ) :
+ cg.brush( TQColorGroup::Button ));
+ int xp = xpos + checkcol + 1;
+ p->fillRect( tqvisualRect( TQRect( xp, y, w - checkcol - 1, h ), r ), fill);
+ } else if ( checkable ) { // just "checking"...
+ if ( mi->isChecked() ) {
+ int xp = xpos + windowsItemFrame;
+
+ SFlags cflags = Style_Default;
+ if (! dis)
+ cflags |= Style_Enabled;
+ if (act)
+ cflags |= Style_On;
+
+ tqdrawPrimitive(PE_CheckMark, p,
+ tqvisualRect( TQRect(xp, y + windowsItemFrame,
+ checkcol - 2*windowsItemFrame,
+ h - 2*windowsItemFrame), r ), cg, cflags);
+ }
+ }
+
+ p->setPen( act ? cg.highlightedText() : cg.buttonText() );
+
+ TQColor discol;
+ if ( dis ) {
+ discol = cg.text();
+ p->setPen( discol );
+ }
+
+ int xm = windowsItemFrame + checkcol + windowsItemHMargin;
+ xpos += xm;
+
+ vrect = tqvisualRect( TQRect( xpos, y+windowsItemVMargin, w-xm-tab+1, h-2*windowsItemVMargin ), r );
+ xvis = vrect.x();
+ if ( mi->custom() ) {
+ p->save();
+ if ( dis && !act ) {
+ p->setPen( cg.light() );
+ mi->custom()->paint( p, cg, act, !dis,
+ xvis+1, y+windowsItemVMargin+1, w-xm-tab+1, h-2*windowsItemVMargin );
+ p->setPen( discol );
+ }
+ mi->custom()->paint( p, cg, act, !dis,
+ xvis, y+windowsItemVMargin, w-xm-tab+1, h-2*windowsItemVMargin );
+ p->restore();
+ }
+ TQString s = mi->text();
+ if ( !s.isNull() ) { // draw text
+ int t = s.tqfind( '\t' );
+ int text_flags = TQt::AlignVCenter|TQt::ShowPrefix | TQt::DontClip | TQt::SingleLine;
+ if (!tqstyleHint(SH_UnderlineAccelerator, widget))
+ text_flags |= TQt::NoAccel;
+ text_flags |= (TQApplication::reverseLayout() ? TQt::AlignRight : TQt::AlignLeft );
+ if ( t >= 0 ) { // draw tab text
+ int xp = x + w - tab - windowsItemHMargin - windowsItemFrame + 1;
+ if ( use2000style )
+ xp -= 20;
+ else
+ xp -= windowsRightBorder;
+ int xoff = tqvisualRect( TQRect( xp, y+windowsItemVMargin, tab, h-2*windowsItemVMargin ), r ).x();
+ if ( dis && !act ) {
+ p->setPen( cg.light() );
+ p->drawText( xoff+1, y+windowsItemVMargin+1, tab, h-2*windowsItemVMargin, text_flags, s.mid( t+1 ));
+ p->setPen( discol );
+ }
+ p->drawText( xoff, y+windowsItemVMargin, tab, h-2*windowsItemVMargin, text_flags, s.mid( t+1 ) );
+ s = s.left( t );
+ }
+ if ( dis && !act ) {
+ p->setPen( cg.light() );
+ p->drawText( xvis+1, y+windowsItemVMargin+1, w-xm-tab+1, h-2*windowsItemVMargin, text_flags, s, t );
+ p->setPen( discol );
+ }
+ p->drawText( xvis, y+windowsItemVMargin, w-xm-tab+1, h-2*windowsItemVMargin, text_flags, s, t );
+ } else if ( mi->pixmap() ) { // draw pixmap
+ TQPixmap *pixmap = mi->pixmap();
+ if ( pixmap->depth() == 1 )
+ p->setBackgroundMode( Qt::OpaqueMode );
+ p->drawPixmap( xvis, y+windowsItemFrame, *pixmap );
+ if ( pixmap->depth() == 1 )
+ p->setBackgroundMode( Qt::TransparentMode );
+ }
+ if ( mi->popup() ) { // draw sub menu arrow
+ int dim = (h-2*windowsItemFrame) / 2;
+ PrimitiveElement arrow;
+ arrow = ( TQApplication::reverseLayout() ? PE_ArrowLeft : PE_ArrowRight );
+ xpos = x+w - windowsArrowHMargin - windowsItemFrame - dim;
+ vrect = tqvisualRect( TQRect(xpos, y + h / 2 - dim / 2, dim, dim), r );
+ if ( act ) {
+ TQColorGroup g2 = cg;
+ g2.setColor( TQColorGroup::ButtonText, g2.highlightedText() );
+ tqdrawPrimitive(arrow, p, vrect,
+ g2, dis ? Style_Default : Style_Enabled);
+ } else {
+ tqdrawPrimitive(arrow, p, vrect,
+ cg, dis ? Style_Default : Style_Enabled );
+ }
+ }
+
+ break;
+ }
+#endif
+
+ case CE_MenuBarItem:
+ {
+ bool active = flags & Style_Active;
+ bool hasFocus = flags & Style_HasFocus;
+ bool down = flags & Style_Down;
+ TQRect pr = r;
+
+ p->fillRect( r, cg.brush( TQColorGroup::Button ) );
+ if ( active || hasFocus ) {
+ TQBrush b = cg.brush( TQColorGroup::Button );
+ if ( active && down )
+ p->setBrushOrigin(p->brushOrigin() + TQPoint(1,1));
+ if ( active && hasFocus )
+ qDrawShadeRect( p, r.x(), r.y(), r.width(), r.height(),
+ cg, active && down, 1, 0, &b );
+ if ( active && down ) {
+ pr.moveBy( tqpixelMetric(PM_ButtonShiftHorizontal, widget),
+ tqpixelMetric(PM_ButtonShiftVertical, widget) );
+ p->setBrushOrigin(p->brushOrigin() - TQPoint(1,1));
+ }
+ }
+ TQCommonStyle::tqdrawControl(element, p, widget, pr, cg, flags, opt);
+ break;
+ }
+
+ default:
+ TQCommonStyle::tqdrawControl(element, p, widget, r, cg, flags, opt);
+ }
+}
+
+
+/*!
+ \reimp
+*/
+int TQWindowsStyle::tqpixelMetric(PixelMetric metric, const TQWidget *widget) const
+{
+ int ret;
+
+ switch (metric) {
+ case PM_ButtonDefaultIndicator:
+ case PM_ButtonShiftHorizontal:
+ case PM_ButtonShiftVertical:
+ ret = 1;
+ break;
+
+ case PM_MaximumDragDistance:
+ ret = 60;
+ break;
+
+#ifndef TQT_NO_SLIDER
+ case PM_SliderLength:
+ ret = 11;
+ break;
+
+ // Returns the number of pixels to use for the business part of the
+ // slider (i.e., the non-tickmark portion). The remaining space is shared
+ // equally between the tickmark regions.
+ case PM_SliderControlThickness:
+ {
+ const TQSlider * sl = (const TQSlider *) widget;
+ int space = (sl->orientation() == Qt::Horizontal) ? sl->height()
+ : sl->width();
+ int ticks = sl->tickmarks();
+ int n = 0;
+ if ( ticks & TQSlider::Above ) n++;
+ if ( ticks & TQSlider::Below ) n++;
+ if ( !n ) {
+ ret = space;
+ break;
+ }
+
+ int thick = 6; // Magic constant to get 5 + 16 + 5
+ if ( ticks != TQSlider::Both && ticks != TQSlider::NoMarks )
+ thick += tqpixelMetric( PM_SliderLength, sl ) / 4;
+
+ space -= thick;
+ //### the two sides may be unequal in size
+ if ( space > 0 )
+ thick += (space * 2) / (n + 2);
+ ret = thick;
+ break;
+ }
+#endif // TQT_NO_SLIDER
+
+ case PM_MenuBarFrameWidth:
+ ret = 0;
+ break;
+
+#if defined(TQ_WS_WIN)
+ case PM_TitleBarHeight:
+ if ( widget && ( widget->testWFlags( WStyle_Tool ) || ::tqqt_cast<TQDockWindow*>(widget) ) ) {
+ // MS always use one less than they say
+#if defined(TQ_OS_TEMP)
+ ret = GetSystemMetrics( SM_CYCAPTION ) - 1;
+#else
+ ret = GetSystemMetrics( SM_CYSMCAPTION ) - 1;
+#endif
+ } else {
+ ret = GetSystemMetrics( SM_CYCAPTION ) - 1;
+ }
+ break;
+
+ case PM_ScrollBarExtent:
+ {
+#ifndef TQ_OS_TEMP
+ NONCLIENTMETRICS ncm;
+ ncm.cbSize = sizeof(NONCLIENTMETRICS);
+ if ( SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0 ) )
+ ret = TQMAX( ncm.iScrollHeight, ncm.iScrollWidth );
+ else
+#endif
+ ret = TQCommonStyle::tqpixelMetric( metric, widget );
+ }
+ break;
+#endif
+
+ case PM_SplitterWidth:
+ ret = TQMAX( 6, TQApplication::globalStrut().width() );
+ break;
+
+#if defined(TQ_WS_WIN)
+ case PM_MDIFrameWidth:
+ ret = GetSystemMetrics(SM_CYFRAME);
+ break;
+#endif
+
+ default:
+ ret = TQCommonStyle::tqpixelMetric(metric, widget);
+ break;
+ }
+
+ return ret;
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQWindowsStyle::tqsizeFromContents( ContentsType contents,
+ const TQWidget *widget,
+ const TQSize &contentsSize,
+ const TQStyleOption& opt ) const
+{
+ TQSize sz(contentsSize);
+
+ switch (contents) {
+ case CT_PushButton:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ const TQPushButton *button = (const TQPushButton *) widget;
+ sz = TQCommonStyle::tqsizeFromContents(contents, widget, contentsSize, opt);
+ int w = sz.width(), h = sz.height();
+
+ int defwidth = 0;
+ if (button->isDefault() || button->autoDefault())
+ defwidth = 2*tqpixelMetric( PM_ButtonDefaultIndicator, widget );
+
+ if (w < 80+defwidth && !button->pixmap())
+ w = 80+defwidth;
+ if (h < 23+defwidth)
+ h = 23+defwidth;
+
+ sz = TQSize(w, h);
+#endif
+ break;
+ }
+
+ case CT_PopupMenuItem:
+ {
+#ifndef TQT_NO_POPUPMENU
+ if (! widget || opt.isDefault())
+ break;
+
+ const TQPopupMenu *popup = (const TQPopupMenu *) widget;
+ bool checkable = popup->isCheckable();
+ TQMenuItem *mi = opt.menuItem();
+ int maxpmw = opt.maxIconWidth();
+ int w = sz.width(), h = sz.height();
+
+ if (mi->custom()) {
+ w = mi->custom()->tqsizeHint().width();
+ h = mi->custom()->tqsizeHint().height();
+ if (! mi->custom()->fullSpan())
+ h += 2*windowsItemVMargin + 2*windowsItemFrame;
+ } else if ( mi->widget() ) {
+ } else if (mi->isSeparator()) {
+ w = 10; // arbitrary
+ h = windowsSepHeight;
+ } else {
+ if (mi->pixmap())
+ h = TQMAX(h, mi->pixmap()->height() + 2*windowsItemFrame);
+ else if (! mi->text().isNull())
+ h = TQMAX(h, popup->fontMetrics().height() + 2*windowsItemVMargin +
+ 2*windowsItemFrame);
+
+ if (mi->iconSet() != 0)
+ h = TQMAX(h, mi->iconSet()->pixmap(TQIconSet::Small,
+ TQIconSet::Normal).height() +
+ 2*windowsItemFrame);
+ }
+
+ if (! mi->text().isNull() && mi->text().tqfind('\t') >= 0) {
+ if ( use2000style )
+ w += 20;
+ else
+ w += windowsTabSpacing;
+ } else if (mi->popup()) {
+ w += 2*windowsArrowHMargin;
+ }
+
+ if (use2000style) {
+ if (checkable && maxpmw < 20)
+ w += 20 - maxpmw;
+ } else {
+ if (checkable && maxpmw < windowsCheckMarkWidth)
+ w += windowsCheckMarkWidth - maxpmw;
+ }
+ if (checkable || maxpmw > 0)
+ w += windowsCheckMarkHMargin;
+ if (use2000style)
+ w += 20;
+ else
+ w += windowsRightBorder;
+
+ sz = TQSize(w, h);
+#endif
+ break;
+ }
+
+ default:
+ sz = TQCommonStyle::tqsizeFromContents(contents, widget, sz, opt);
+ break;
+ }
+
+ return sz;
+}
+
+/*! \reimp
+*/
+void TQWindowsStyle::polishPopupMenu( TQPopupMenu* p)
+{
+#ifndef TQT_NO_POPUPMENU
+ if ( !p->testWState( TQt::WState_Polished ) )
+ p->setCheckable( TRUE );
+#endif
+}
+
+#ifndef TQT_NO_IMAGEIO_XPM
+static const char * const qt_close_xpm[] = {
+"12 12 2 1",
+"# c #000000",
+". c None",
+"............",
+"............",
+"..##....##..",
+"...##..##...",
+"....####....",
+".....##.....",
+"....####....",
+"...##..##...",
+"..##....##..",
+"............",
+"............",
+"............"};
+
+static const char * const qt_maximize_xpm[]={
+"12 12 2 1",
+"# c #000000",
+". c None",
+"............",
+".#########..",
+".#########..",
+".#.......#..",
+".#.......#..",
+".#.......#..",
+".#.......#..",
+".#.......#..",
+".#.......#..",
+".#########..",
+"............",
+"............"};
+
+
+static const char * const qt_minimize_xpm[] = {
+"12 12 2 1",
+"# c #000000",
+". c None",
+"............",
+"............",
+"............",
+"............",
+"............",
+"............",
+"............",
+"............",
+"..######....",
+"..######....",
+"............",
+"............"};
+
+static const char * const qt_normalizeup_xpm[] = {
+"12 12 2 1",
+"# c #000000",
+". c None",
+"............",
+"....######..",
+"....######..",
+"....#....#..",
+"..######.#..",
+"..######.#..",
+"..#....###..",
+"..#....#....",
+"..#....#....",
+"..######....",
+"............",
+"............"};
+
+
+static const char * const qt_shade_xpm[] = {
+"12 12 2 1",
+"# c #000000",
+". c None",
+"............",
+"............",
+"............",
+"............",
+"............",
+".....#......",
+"....###.....",
+"...#####....",
+"..#######...",
+"............",
+"............",
+"............"};
+
+static const char * const qt_unshade_xpm[] = {
+"12 12 2 1",
+"# c #000000",
+". c None",
+"............",
+"............",
+"............",
+"............",
+"..#######...",
+"...#####....",
+"....###.....",
+".....#......",
+"............",
+"............",
+"............",
+"............"};
+
+static const char * dock_window_close_xpm[] = {
+"8 8 2 1",
+"# c #000000",
+". c None",
+"........",
+".##..##.",
+"..####..",
+"...##...",
+"..####..",
+".##..##.",
+"........",
+"........"};
+
+/* XPM */
+static const char * const information_xpm[]={
+"32 32 5 1",
+". c None",
+"c c #000000",
+"* c #999999",
+"a c #ffffff",
+"b c #0000ff",
+"...........********.............",
+"........***aaaaaaaa***..........",
+"......**aaaaaaaaaaaaaa**........",
+".....*aaaaaaaaaaaaaaaaaa*.......",
+"....*aaaaaaaabbbbaaaaaaaac......",
+"...*aaaaaaaabbbbbbaaaaaaaac.....",
+"..*aaaaaaaaabbbbbbaaaaaaaaac....",
+".*aaaaaaaaaaabbbbaaaaaaaaaaac...",
+".*aaaaaaaaaaaaaaaaaaaaaaaaaac*..",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac*.",
+"*aaaaaaaaaabbbbbbbaaaaaaaaaaac*.",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaabbbbbaaaaaaaaaaac**",
+".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+".*aaaaaaaaaaabbbbbaaaaaaaaaac***",
+"..*aaaaaaaaaabbbbbaaaaaaaaac***.",
+"...caaaaaaabbbbbbbbbaaaaaac****.",
+"....caaaaaaaaaaaaaaaaaaaac****..",
+".....caaaaaaaaaaaaaaaaaac****...",
+"......ccaaaaaaaaaaaaaacc****....",
+".......*cccaaaaaaaaccc*****.....",
+"........***cccaaaac*******......",
+"..........****caaac*****........",
+".............*caaac**...........",
+"...............caac**...........",
+"................cac**...........",
+".................cc**...........",
+"..................***...........",
+"...................**..........."};
+/* XPM */
+static const char* const warning_xpm[]={
+"32 32 4 1",
+". c None",
+"a c #ffff00",
+"* c #000000",
+"b c #999999",
+".............***................",
+"............*aaa*...............",
+"...........*aaaaa*b.............",
+"...........*aaaaa*bb............",
+"..........*aaaaaaa*bb...........",
+"..........*aaaaaaa*bb...........",
+".........*aaaaaaaaa*bb..........",
+".........*aaaaaaaaa*bb..........",
+"........*aaaaaaaaaaa*bb.........",
+"........*aaaa***aaaa*bb.........",
+".......*aaaa*****aaaa*bb........",
+".......*aaaa*****aaaa*bb........",
+"......*aaaaa*****aaaaa*bb.......",
+"......*aaaaa*****aaaaa*bb.......",
+".....*aaaaaa*****aaaaaa*bb......",
+".....*aaaaaa*****aaaaaa*bb......",
+"....*aaaaaaaa***aaaaaaaa*bb.....",
+"....*aaaaaaaa***aaaaaaaa*bb.....",
+"...*aaaaaaaaa***aaaaaaaaa*bb....",
+"...*aaaaaaaaaa*aaaaaaaaaa*bb....",
+"..*aaaaaaaaaaa*aaaaaaaaaaa*bb...",
+"..*aaaaaaaaaaaaaaaaaaaaaaa*bb...",
+".*aaaaaaaaaaaa**aaaaaaaaaaa*bb..",
+".*aaaaaaaaaaa****aaaaaaaaaa*bb..",
+"*aaaaaaaaaaaa****aaaaaaaaaaa*bb.",
+"*aaaaaaaaaaaaa**aaaaaaaaaaaa*bb.",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaa*bbb",
+".*aaaaaaaaaaaaaaaaaaaaaaaaa*bbbb",
+"..*************************bbbbb",
+"....bbbbbbbbbbbbbbbbbbbbbbbbbbb.",
+".....bbbbbbbbbbbbbbbbbbbbbbbbb.."};
+/* XPM */
+static const char* const critical_xpm[]={
+"32 32 4 1",
+". c None",
+"a c #999999",
+"* c #ff0000",
+"b c #ffffff",
+"...........********.............",
+".........************...........",
+".......****************.........",
+"......******************........",
+".....********************a......",
+"....**********************a.....",
+"...************************a....",
+"..*******b**********b*******a...",
+"..******bbb********bbb******a...",
+".******bbbbb******bbbbb******a..",
+".*******bbbbb****bbbbb*******a..",
+"*********bbbbb**bbbbb*********a.",
+"**********bbbbbbbbbb**********a.",
+"***********bbbbbbbb***********aa",
+"************bbbbbb************aa",
+"************bbbbbb************aa",
+"***********bbbbbbbb***********aa",
+"**********bbbbbbbbbb**********aa",
+"*********bbbbb**bbbbb*********aa",
+".*******bbbbb****bbbbb*******aa.",
+".******bbbbb******bbbbb******aa.",
+"..******bbb********bbb******aaa.",
+"..*******b**********b*******aa..",
+"...************************aaa..",
+"....**********************aaa...",
+"....a********************aaa....",
+".....a******************aaa.....",
+"......a****************aaa......",
+".......aa************aaaa.......",
+".........aa********aaaaa........",
+"...........aaaaaaaaaaa..........",
+".............aaaaaaa............"};
+/* XPM */
+static const char *const question_xpm[] = {
+"32 32 5 1",
+". c None",
+"c c #000000",
+"* c #999999",
+"a c #ffffff",
+"b c #0000ff",
+"...........********.............",
+"........***aaaaaaaa***..........",
+"......**aaaaaaaaaaaaaa**........",
+".....*aaaaaaaaaaaaaaaaaa*.......",
+"....*aaaaaaaaaaaaaaaaaaaac......",
+"...*aaaaaaaabbbbbbaaaaaaaac.....",
+"..*aaaaaaaabaaabbbbaaaaaaaac....",
+".*aaaaaaaabbaaaabbbbaaaaaaaac...",
+".*aaaaaaaabbbbaabbbbaaaaaaaac*..",
+"*aaaaaaaaabbbbaabbbbaaaaaaaaac*.",
+"*aaaaaaaaaabbaabbbbaaaaaaaaaac*.",
+"*aaaaaaaaaaaaabbbbaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbbaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaabbaaaaaaaaaaaaac**",
+"*aaaaaaaaaaaaaaaaaaaaaaaaaaaac**",
+".*aaaaaaaaaaaabbaaaaaaaaaaaac***",
+".*aaaaaaaaaaabbbbaaaaaaaaaaac***",
+"..*aaaaaaaaaabbbbaaaaaaaaaac***.",
+"...caaaaaaaaaabbaaaaaaaaaac****.",
+"....caaaaaaaaaaaaaaaaaaaac****..",
+".....caaaaaaaaaaaaaaaaaac****...",
+"......ccaaaaaaaaaaaaaacc****....",
+".......*cccaaaaaaaaccc*****.....",
+"........***cccaaaac*******......",
+"..........****caaac*****........",
+".............*caaac**...........",
+"...............caac**...........",
+"................cac**...........",
+".................cc**...........",
+"..................***...........",
+"...................**...........",
+};
+#endif //TQT_NO_IMAGEIO_XPM
+
+/*!
+ \reimp
+ */
+TQPixmap TQWindowsStyle::stylePixmap(StylePixmap stylepixmap,
+ const TQWidget *widget,
+ const TQStyleOption& opt) const
+{
+#ifndef TQT_NO_IMAGEIO_XPM
+ switch (stylepixmap) {
+ case SP_TitleBarShadeButton:
+ return TQPixmap( (const char **)qt_shade_xpm );
+ case SP_TitleBarUnshadeButton:
+ return TQPixmap( (const char **)qt_unshade_xpm );
+ case SP_TitleBarNormalButton:
+ return TQPixmap( (const char **)qt_normalizeup_xpm );
+ case SP_TitleBarMinButton:
+ return TQPixmap( (const char **)qt_minimize_xpm );
+ case SP_TitleBarMaxButton:
+ return TQPixmap( (const char **)qt_maximize_xpm );
+ case SP_TitleBarCloseButton:
+ return TQPixmap( (const char **)qt_close_xpm );
+ case SP_DockWindowCloseButton:
+ return TQPixmap( (const char **)dock_window_close_xpm );
+ case SP_MessageBoxInformation:
+ return TQPixmap( (const char **)information_xpm);
+ case SP_MessageBoxWarning:
+ return TQPixmap( (const char **)warning_xpm );
+ case SP_MessageBoxCritical:
+ return TQPixmap( (const char **)critical_xpm );
+ case SP_MessageBoxQuestion:
+ return TQPixmap( (const char **)question_xpm );
+ default:
+ break;
+ }
+#endif //TQT_NO_IMAGEIO_XPM
+ return TQCommonStyle::stylePixmap(stylepixmap, widget, opt);
+}
+
+/*!\reimp
+*/
+void TQWindowsStyle::tqdrawComplexControl( TQ_ComplexControl ctrl, TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags,
+ SCFlags sub,
+ SCFlags subActive,
+ const TQStyleOption& opt ) const
+{
+ switch (ctrl) {
+#ifndef TQT_NO_LISTVIEW
+ case CC_ListView:
+ {
+ if ( sub & SC_ListView ) {
+ TQCommonStyle::tqdrawComplexControl( ctrl, p, widget, r, cg, flags, sub, subActive, opt );
+ }
+ if ( sub & ( SC_ListViewBranch | SC_ListViewExpand ) ) {
+ if (opt.isDefault())
+ break;
+
+ TQListViewItem *item = opt.listViewItem(),
+ *child = item->firstChild();
+
+ int y = r.y();
+ int c;
+ int dotoffset = 0;
+ TQPointArray dotlines;
+ if ( subActive == (uint)SC_All && sub == SC_ListViewExpand ) {
+ c = 2;
+ dotlines.resize(2);
+ dotlines[0] = TQPoint( r.right(), r.top() );
+ dotlines[1] = TQPoint( r.right(), r.bottom() );
+ } else {
+ int linetop = 0, linebot = 0;
+ // each branch needs at most two lines, ie. four end points
+ dotoffset = (item->itemPos() + item->height() - y) %2;
+ dotlines.resize( item->childCount() * 4 );
+ c = 0;
+
+ // skip the stuff above the exposed rectangle
+ while ( child && y + child->height() <= 0 ) {
+ y += child->totalHeight();
+ child = child->nextSibling();
+ }
+
+ int bx = r.width() / 2;
+
+ // paint stuff in the magical area
+ TQListView* v = item->listView();
+ while ( child && y < r.height() ) {
+ if (child->isVisible()) {
+ int lh;
+ if ( !item->multiLinesEnabled() )
+ lh = child->height();
+ else
+ lh = p->fontMetrics().height() + 2 * v->itemMargin();
+ lh = TQMAX( lh, TQApplication::globalStrut().height() );
+ if ( lh % 2 > 0 )
+ lh++;
+ linebot = y + lh/2;
+ if ( (child->isExpandable() || child->childCount()) &&
+ (child->height() > 0) ) {
+ // needs a box
+ p->setPen( cg.mid() );
+ p->drawRect( bx-4, linebot-4, 9, 9 );
+ // plus or minus
+ p->setPen( cg.text() );
+ p->drawLine( bx - 2, linebot, bx + 2, linebot );
+ if ( !child->isOpen() )
+ p->drawLine( bx, linebot - 2, bx, linebot + 2 );
+ // dotlinery
+ p->setPen( cg.mid() );
+ dotlines[c++] = TQPoint( bx, linetop );
+ dotlines[c++] = TQPoint( bx, linebot - 4 );
+ dotlines[c++] = TQPoint( bx + 5, linebot );
+ dotlines[c++] = TQPoint( r.width(), linebot );
+ linetop = linebot + 5;
+ } else {
+ // just dotlinery
+ dotlines[c++] = TQPoint( bx+1, linebot -1);
+ dotlines[c++] = TQPoint( r.width(), linebot -1);
+ }
+ y += child->totalHeight();
+ }
+ child = child->nextSibling();
+ }
+
+ // Expand line height to edge of rectangle if there's any
+ // visible child below
+ while ( child && child->height() <= 0)
+ child = child->nextSibling();
+ if ( child )
+ linebot = r.height();
+
+ if ( linetop < linebot ) {
+ dotlines[c++] = TQPoint( bx, linetop );
+ dotlines[c++] = TQPoint( bx, linebot );
+ }
+ }
+ p->setPen( cg.text() );
+
+ static TQBitmap *verticalLine = 0, *horizontalLine = 0;
+ static TQCleanupHandler<TQBitmap> qlv_cleanup_bitmap;
+ if ( !verticalLine ) {
+ // make 128*1 and 1*128 bitmaps that can be used for
+ // drawing the right sort of lines.
+ verticalLine = new TQBitmap( 1, 129, TRUE );
+ horizontalLine = new TQBitmap( 128, 1, TRUE );
+ TQPointArray a( 64 );
+ TQPainter p;
+ p.begin( verticalLine );
+ int i;
+ for( i=0; i<64; i++ )
+ a.setPoint( i, 0, i*2+1 );
+ p.setPen( Qt::color1 );
+ p.drawPoints( a );
+ p.end();
+ TQApplication::flushX();
+ verticalLine->setMask( *verticalLine );
+ p.begin( horizontalLine );
+ for( i=0; i<64; i++ )
+ a.setPoint( i, i*2+1, 0 );
+ p.setPen( Qt::color1 );
+ p.drawPoints( a );
+ p.end();
+ TQApplication::flushX();
+ horizontalLine->setMask( *horizontalLine );
+ qlv_cleanup_bitmap.add( &verticalLine );
+ qlv_cleanup_bitmap.add( &horizontalLine );
+ }
+
+ int line; // index into dotlines
+ if ( sub & SC_ListViewBranch ) for( line = 0; line < c; line += 2 ) {
+ // assumptions here: lines are horizontal or vertical.
+ // lines always start with the numerically lowest
+ // coordinate.
+
+ // point ... relevant coordinate of current point
+ // end ..... same coordinate of the end of the current line
+ // other ... the other coordinate of the current point/line
+ if ( dotlines[line].y() == dotlines[line+1].y() ) {
+ int end = dotlines[line+1].x();
+ int point = dotlines[line].x();
+ int other = dotlines[line].y();
+ while( point < end ) {
+ int i = 128;
+ if ( i+point > end )
+ i = end-point;
+ p->drawPixmap( point, other, *horizontalLine,
+ 0, 0, i, 1 );
+ point += i;
+ }
+ } else {
+ int end = dotlines[line+1].y();
+ int point = dotlines[line].y();
+ int other = dotlines[line].x();
+ int pixmapoffset = ((point & 1) != dotoffset ) ? 1 : 0;
+ while( point < end ) {
+ int i = 128;
+ if ( i+point > end )
+ i = end-point;
+ p->drawPixmap( other, point, *verticalLine,
+ 0, pixmapoffset, 1, i );
+ point += i;
+ }
+ }
+ }
+ }
+ }
+ break;
+#endif //TQT_NO_LISTVIEW
+
+#ifndef TQT_NO_COMBOBOX
+ case CC_ComboBox:
+ if ( sub & SC_ComboBoxArrow ) {
+ SFlags flags = Style_Default;
+
+ qDrawWinPanel( p, r, cg, TRUE, widget->isEnabled() ?
+ &cg.brush( TQColorGroup::Base ):
+ &cg.brush( TQColorGroup::Background ) );
+
+ TQRect ar =
+ TQStyle::tqvisualRect( querySubControlMetrics( CC_ComboBox, widget,
+ SC_ComboBoxArrow ), widget );
+ if ( subActive == SC_ComboBoxArrow ) {
+ p->setPen( cg.dark() );
+ p->setBrush( cg.brush( TQColorGroup::Button ) );
+ p->drawRect( ar );
+ } else
+ qDrawWinPanel( p, ar, cg, FALSE,
+ &cg.brush( TQColorGroup::Button ) );
+
+ ar.addCoords( 2, 2, -2, -2 );
+ if ( widget->isEnabled() )
+ flags |= Style_Enabled;
+
+ if ( subActive == SC_ComboBoxArrow ) {
+ flags |= Style_Sunken;
+ }
+ tqdrawPrimitive( PE_ArrowDown, p, ar, cg, flags );
+ }
+
+ if ( sub & SC_ComboBoxEditField ) {
+ const TQComboBox * cb = (const TQComboBox *) widget;
+ TQRect re =
+ TQStyle::tqvisualRect( querySubControlMetrics( CC_ComboBox, widget,
+ SC_ComboBoxEditField ), widget );
+ if ( cb->hasFocus() && !cb->editable() )
+ p->fillRect( re.x(), re.y(), re.width(), re.height(),
+ cg.brush( TQColorGroup::Highlight ) );
+
+ if ( cb->hasFocus() ) {
+ p->setPen( cg.highlightedText() );
+ p->setBackgroundColor( cg.highlight() );
+
+ } else {
+ p->setPen( cg.text() );
+ p->setBackgroundColor( cg.background() );
+ }
+
+ if ( cb->hasFocus() && !cb->editable() ) {
+ TQRect re =
+ TQStyle::tqvisualRect( subRect( SR_ComboBoxFocusRect, cb ), widget );
+ tqdrawPrimitive( PE_FocusRect, p, re, cg, Style_FocusAtBorder, TQStyleOption(cg.highlight()));
+ }
+ }
+
+ break;
+#endif // TQT_NO_COMBOBOX
+
+#ifndef TQT_NO_SLIDER
+ case CC_Slider:
+ {
+ const TQSlider *sl = (const TQSlider *) widget;
+ int thickness = tqpixelMetric( PM_SliderControlThickness, widget );
+ int len = tqpixelMetric( PM_SliderLength, widget );
+ int ticks = sl->tickmarks();
+
+ TQRect groove = querySubControlMetrics(CC_Slider, widget, SC_SliderGroove,
+ opt),
+ handle = querySubControlMetrics(CC_Slider, widget, SC_SliderHandle,
+ opt);
+
+ if ((sub & SC_SliderGroove) && groove.isValid()) {
+ int mid = thickness / 2;
+
+ if ( ticks & TQSlider::Above )
+ mid += len / 8;
+ if ( ticks & TQSlider::Below )
+ mid -= len / 8;
+
+ p->setPen( cg.shadow() );
+ if ( sl->orientation() == Qt::Horizontal ) {
+ qDrawWinPanel( p, groove.x(), groove.y() + mid - 2,
+ groove.width(), 4, cg, TRUE );
+ p->drawLine( groove.x() + 1, groove.y() + mid - 1,
+ groove.x() + groove.width() - 3, groove.y() + mid - 1 );
+ } else {
+ qDrawWinPanel( p, groove.x() + mid - 2, groove.y(),
+ 4, groove.height(), cg, TRUE );
+ p->drawLine( groove.x() + mid - 1, groove.y() + 1,
+ groove.x() + mid - 1,
+ groove.y() + groove.height() - 3 );
+ }
+ }
+
+ if (sub & SC_SliderTickmarks)
+ TQCommonStyle::tqdrawComplexControl(ctrl, p, widget, r, cg, flags,
+ SC_SliderTickmarks, subActive,
+ opt );
+
+ if ( sub & SC_SliderHandle ) {
+ // 4444440
+ // 4333310
+ // 4322210
+ // 4322210
+ // 4322210
+ // 4322210
+ // *43210*
+ // **410**
+ // ***0***
+ const TQColor c0 = cg.shadow();
+ const TQColor c1 = cg.dark();
+ // const TQColor c2 = g.button();
+ const TQColor c3 = cg.midlight();
+ const TQColor c4 = cg.light();
+
+ int x = handle.x(), y = handle.y(),
+ wi = handle.width(), he = handle.height();
+
+ int x1 = x;
+ int x2 = x+wi-1;
+ int y1 = y;
+ int y2 = y+he-1;
+
+ Qt::Orientation orient = sl->orientation();
+ bool tickAbove = sl->tickmarks() == TQSlider::Above;
+ bool tickBelow = sl->tickmarks() == TQSlider::Below;
+
+ p->fillRect( x, y, wi, he, cg.brush( TQColorGroup::Background ) );
+
+ if ( flags & Style_HasFocus ) {
+ TQRect re = subRect( SR_SliderFocusRect, sl );
+ tqdrawPrimitive( PE_FocusRect, p, re, cg );
+ }
+
+ if ( (tickAbove && tickBelow) || (!tickAbove && !tickBelow) ) {
+ qDrawWinButton( p, TQRect(x,y,wi,he), cg, FALSE,
+ &cg.brush( TQColorGroup::Button ) );
+ return;
+ }
+
+ TQSliderDirection dir;
+
+ if ( orient == Qt::Horizontal )
+ if ( tickAbove )
+ dir = SlUp;
+ else
+ dir = SlDown;
+ else
+ if ( tickAbove )
+ dir = SlLeft;
+ else
+ dir = SlRight;
+
+ TQPointArray a;
+
+ int d = 0;
+ switch ( dir ) {
+ case SlUp:
+ y1 = y1 + wi/2;
+ d = (wi + 1) / 2 - 1;
+ a.setPoints(5, x1,y1, x1,y2, x2,y2, x2,y1, x1+d,y1-d );
+ break;
+ case SlDown:
+ y2 = y2 - wi/2;
+ d = (wi + 1) / 2 - 1;
+ a.setPoints(5, x1,y1, x1,y2, x1+d,y2+d, x2,y2, x2,y1 );
+ break;
+ case SlLeft:
+ d = (he + 1) / 2 - 1;
+ x1 = x1 + he/2;
+ a.setPoints(5, x1,y1, x1-d,y1+d, x1,y2, x2,y2, x2,y1);
+ break;
+ case SlRight:
+ d = (he + 1) / 2 - 1;
+ x2 = x2 - he/2;
+ a.setPoints(5, x1,y1, x1,y2, x2,y2, x2+d,y1+d, x2,y1 );
+ break;
+ }
+
+ TQBrush oldBrush = p->brush();
+ p->setBrush( cg.brush( TQColorGroup::Button ) );
+ p->setPen( Qt::NoPen );
+ p->drawRect( x1, y1, x2-x1+1, y2-y1+1 );
+ p->drawPolygon( a );
+ p->setBrush( oldBrush );
+
+ if ( dir != SlUp ) {
+ p->setPen( c4 );
+ p->drawLine( x1, y1, x2, y1 );
+ p->setPen( c3 );
+ p->drawLine( x1, y1+1, x2, y1+1 );
+ }
+ if ( dir != SlLeft ) {
+ p->setPen( c3 );
+ p->drawLine( x1+1, y1+1, x1+1, y2 );
+ p->setPen( c4 );
+ p->drawLine( x1, y1, x1, y2 );
+ }
+ if ( dir != SlRight ) {
+ p->setPen( c0 );
+ p->drawLine( x2, y1, x2, y2 );
+ p->setPen( c1 );
+ p->drawLine( x2-1, y1+1, x2-1, y2-1 );
+ }
+ if ( dir != SlDown ) {
+ p->setPen( c0 );
+ p->drawLine( x1, y2, x2, y2 );
+ p->setPen( c1 );
+ p->drawLine( x1+1, y2-1, x2-1, y2-1 );
+ }
+
+ switch ( dir ) {
+ case SlUp:
+ p->setPen( c4 );
+ p->drawLine( x1, y1, x1+d, y1-d);
+ p->setPen( c0 );
+ d = wi - d - 1;
+ p->drawLine( x2, y1, x2-d, y1-d);
+ d--;
+ p->setPen( c3 );
+ p->drawLine( x1+1, y1, x1+1+d, y1-d );
+ p->setPen( c1 );
+ p->drawLine( x2-1, y1, x2-1-d, y1-d);
+ break;
+ case SlDown:
+ p->setPen( c4 );
+ p->drawLine( x1, y2, x1+d, y2+d);
+ p->setPen( c0 );
+ d = wi - d - 1;
+ p->drawLine( x2, y2, x2-d, y2+d);
+ d--;
+ p->setPen( c3 );
+ p->drawLine( x1+1, y2, x1+1+d, y2+d );
+ p->setPen( c1 );
+ p->drawLine( x2-1, y2, x2-1-d, y2+d);
+ break;
+ case SlLeft:
+ p->setPen( c4 );
+ p->drawLine( x1, y1, x1-d, y1+d);
+ p->setPen( c0 );
+ d = he - d - 1;
+ p->drawLine( x1, y2, x1-d, y2-d);
+ d--;
+ p->setPen( c3 );
+ p->drawLine( x1, y1+1, x1-d, y1+1+d );
+ p->setPen( c1 );
+ p->drawLine( x1, y2-1, x1-d, y2-1-d);
+ break;
+ case SlRight:
+ p->setPen( c4 );
+ p->drawLine( x2, y1, x2+d, y1+d);
+ p->setPen( c0 );
+ d = he - d - 1;
+ p->drawLine( x2, y2, x2+d, y2-d);
+ d--;
+ p->setPen( c3 );
+ p->drawLine( x2, y1+1, x2+d, y1+1+d );
+ p->setPen( c1 );
+ p->drawLine( x2, y2-1, x2+d, y2-1-d);
+ break;
+ }
+ }
+
+ break;
+ }
+#endif // TQT_NO_SLIDER
+
+ default:
+ TQCommonStyle::tqdrawComplexControl( ctrl, p, widget, r, cg, flags, sub,
+ subActive, opt );
+ break;
+ }
+}
+
+
+/*! \reimp */
+int TQWindowsStyle::tqstyleHint( TQ_StyleHint hint,
+ const TQWidget *widget,
+ const TQStyleOption &opt,
+ TQStyleHintReturn *returnData ) const
+{
+ int ret;
+
+ switch (hint) {
+ case SH_EtchDisabledText:
+ case SH_Slider_SnapToValue:
+ case SH_PrintDialog_RightAlignButtons:
+ case SH_MainWindow_SpaceBelowMenuBar:
+ case SH_FontDialog_SelectAssociatedText:
+ case SH_PopupMenu_AllowActiveAndDisabled:
+ case SH_MenuBar_AltKeyNavigation:
+ case SH_MenuBar_MouseTracking:
+ case SH_PopupMenu_MouseTracking:
+ case SH_ComboBox_ListMouseTracking:
+ case SH_ScrollBar_StopMouseOverSlider:
+ ret = 1;
+ break;
+
+ case SH_ItemView_ChangeHighlightOnFocus:
+#if defined(TQ_WS_WIN)
+ if ( qWinVersion() != WV_95 && qWinVersion() != WV_NT )
+ ret = 1;
+ else
+#endif
+ ret = 0;
+ break;
+
+ case SH_ToolBox_SelectedPageTitleBold:
+ ret = 0;
+ break;
+
+#if defined(TQ_WS_WIN)
+ case SH_UnderlineAccelerator:
+ ret = 1;
+ if ( qWinVersion() != WV_95 && qWinVersion() != WV_98 && qWinVersion() != WV_NT ) {
+ BOOL cues;
+ SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &cues, 0);
+ ret = cues ? 1 : 0;
+ // Do nothing if we always paint underlines
+ if (!ret && widget && d) {
+ TQMenuBar *menuBar = ::tqqt_cast<TQMenuBar*>(widget);
+ TQPopupMenu *popupMenu = 0;
+ if (!menuBar)
+ popupMenu = ::tqqt_cast<TQPopupMenu*>(widget);
+
+ // If we paint a menubar draw underlines if it has focus, or if alt is down,
+ // or if a popup menu belonging to the menubar is active and paints underlines
+ if (menuBar) {
+ if (menuBar->hasFocus()) {
+ ret = 1;
+ } else if (d->altDown()) {
+ ret = 1;
+ } else if (tqApp->tqfocusWidget() && tqApp->tqfocusWidget()->isPopup()) {
+ popupMenu = ::tqqt_cast<TQPopupMenu*>(tqApp->tqfocusWidget());
+ TQMenuData *pm = popupMenu ? (TQMenuData*)popupMenu->tqqt_cast("TQMenuData") : 0;
+ if (pm && ((FriendlyMenuData*)pm)->parentMenu == menuBar) {
+ if (d->hasSeenAlt(menuBar))
+ ret = 1;
+ }
+ }
+ // If we paint a popup menu draw underlines if the respective menubar does
+ } else if (popupMenu) {
+ TQMenuData *pm = (TQMenuData*)popupMenu->tqqt_cast("TQMenuData");
+ while (pm) {
+ if (((FriendlyMenuData*)pm)->isMenuBar) {
+ menuBar = (TQMenuBar*)pm;
+ if (d->hasSeenAlt(menuBar))
+ ret = 1;
+ break;
+ }
+ pm = ((FriendlyMenuData*)pm)->parentMenu;
+ }
+ // Otherwise draw underlines if the toplevel widget has seen an alt-press
+ } else if (d->hasSeenAlt(widget)) {
+ ret = 1;
+ }
+ }
+
+ }
+ break;
+#endif
+
+ default:
+ ret = TQCommonStyle::tqstyleHint(hint, widget, opt, returnData);
+ break;
+ }
+
+ return ret;
+}
+
+/*! \reimp */
+TQRect TQWindowsStyle::subRect(SubRect r, const TQWidget *widget) const
+{
+ TQRect rect;
+
+ switch (r) {
+#ifndef TQT_NO_SLIDER
+ case SR_SliderFocusRect:
+ {
+ rect = widget->rect();
+ break;
+ }
+#endif // TQT_NO_SLIDER
+ case SR_ToolBoxTabContents:
+ rect = widget->rect();
+ break;
+ default:
+ rect = TQCommonStyle::subRect( r, widget );
+ break;
+ }
+
+ return rect;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/styles/tqwindowsstyle.h b/tqtinterface/qt4/src/styles/tqwindowsstyle.h
new file mode 100644
index 0000000..a5a6fe9
--- /dev/null
+++ b/tqtinterface/qt4/src/styles/tqwindowsstyle.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Definition of Windows-like style class
+**
+** Created : 981231
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWINDOWSSTYLE_H
+#define TQWINDOWSSTYLE_H
+
+#ifndef TQT_H
+#include "tqcommonstyle.h"
+#endif // TQT_H
+
+#if !defined(TQT_NO_STYLE_WINDOWS) || defined(TQT_PLUGIN)
+
+#if defined(TQT_PLUGIN)
+#define TQ_EXPORT_STYLE_WINDOWS
+#else
+#define TQ_EXPORT_STYLE_WINDOWS TQ_EXPORT
+#endif
+
+
+class TQ_EXPORT_STYLE_WINDOWS TQWindowsStyle : public TQCommonStyle
+{
+ TQ_OBJECT
+public:
+ TQWindowsStyle();
+ ~TQWindowsStyle();
+
+ void polish(TQApplication*);
+ void unPolish(TQApplication*);
+
+ void polish(TQWidget*);
+ void unPolish(TQWidget*);
+
+ void polish( TQPalette & );
+
+ virtual void polishPopupMenu( TQPopupMenu* );
+
+ // new stuff
+ void tqdrawPrimitiveBase( TQ_PrimitiveElement pe,
+ TQPainter *p,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawControl( TQ_ControlElement element,
+ TQPainter *p,
+ const TQWidget *widget,
+ const TQRect &r,
+ const TQColorGroup &cg,
+ SFlags flags = Style_Default,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ void tqdrawComplexControl( TQ_ComplexControl control,
+ TQPainter* p,
+ const TQWidget* widget,
+ const TQRect& r,
+ const TQColorGroup& cg,
+ SFlags flags = Style_Default,
+#ifdef TQ_TQDOC
+ SCFlags sub = SC_All,
+#else
+ SCFlags sub = (uint)SC_All,
+#endif
+ SCFlags subActive = SC_None,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ int tqpixelMetric( PixelMetric metric,
+ const TQWidget *widget = 0 ) const;
+
+ TQSize tqsizeFromContents( ContentsType contents,
+ const TQWidget *widget,
+ const TQSize &contentsSize,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ int tqstyleHint(TQ_StyleHint sh, const TQWidget *, const TQStyleOption & = TQStyleOption::Default,
+ TQStyleHintReturn* = 0) const;
+
+ TQPixmap stylePixmap( StylePixmap stylepixmap,
+ const TQWidget *widget = 0,
+ const TQStyleOption& = TQStyleOption::Default ) const;
+
+ TQRect subRect( SubRect r, const TQWidget *widget ) const;
+
+private:
+ class Private;
+ Private *d;
+
+ // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQWindowsStyle( const TQWindowsStyle & );
+ TQWindowsStyle& operator=( const TQWindowsStyle & );
+#endif
+};
+
+#endif // TQT_NO_STYLE_WINDOWS
+
+#endif // TQWINDOWSSTYLE_H
diff --git a/tqtinterface/qt4/src/table/qt_table.pri b/tqtinterface/qt4/src/table/qt_table.pri
new file mode 100644
index 0000000..fc98d82
--- /dev/null
+++ b/tqtinterface/qt4/src/table/qt_table.pri
@@ -0,0 +1,6 @@
+# Qt table module
+
+table {
+ HEADERS += $$TABLE_H/tqtable.h
+ SOURCES += $$TABLE_CPP/tqtable.cpp
+}
diff --git a/tqtinterface/qt4/src/table/tqtable.cpp b/tqtinterface/qt4/src/table/tqtable.cpp
new file mode 100644
index 0000000..d87914f
--- /dev/null
+++ b/tqtinterface/qt4/src/table/tqtable.cpp
@@ -0,0 +1,7375 @@
+/****************************************************************************
+**
+** Implementation of TQTable widget class
+**
+** Created : 000607
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the table module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqglobal.h"
+#if defined(TQ_CC_BOR)
+// needed for qsort() because of a std namespace problem on Borland
+#include "tqplatformdefs.h"
+#endif
+
+#include "tqtable.h"
+
+#ifndef TQT_NO_TABLE
+
+#include <tqpainter.h>
+#include <tqlineedit.h>
+#include <tqcursor.h>
+#include <tqapplication.h>
+#include <tqtimer.h>
+#include <tqobjectlist.h>
+#include <tqiconset.h>
+#include <tqcombobox.h>
+#include <tqcheckbox.h>
+#include <tqdragobject.h>
+#include <tqevent.h>
+#include <tqlistbox.h>
+#include <tqstyle.h>
+#include <tqdatatable.h>
+#include <tqvalidator.h>
+
+#include <stdlib.h>
+#include <limits.h>
+
+static bool qt_update_cell_widget = TRUE;
+static bool qt_table_clipper_enabled = TRUE;
+#ifndef TQT_INTERNAL_TABLE
+TQ_EXPORT
+#endif
+void qt_set_table_clipper_enabled( bool enabled )
+{
+ qt_table_clipper_enabled = enabled;
+}
+
+class TQM_EXPORT_TABLE TQTableHeader : public TQHeader
+{
+ friend class TQTable;
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ enum SectionState {
+ Normal,
+ Bold,
+ Selected
+ };
+
+ TQTableHeader( int, TQTable *t, TQWidget* tqparent=0, const char* name=0 );
+ ~TQTableHeader() {};
+ void addLabel( const TQString &s, int size );
+ void setLabel( int section, const TQString & s, int size = -1 );
+ void setLabel( int section, const TQIconSet & iconset, const TQString & s,
+ int size = -1 );
+
+ void setLabels(const TQStringList & labels);
+
+ void removeLabel( int section );
+
+ void setSectionState( int s, SectionState state );
+ void setSectionStateToAll( SectionState state );
+ SectionState sectionState( int s ) const;
+
+ int sectionSize( int section ) const;
+ int sectionPos( int section ) const;
+ int sectionAt( int section ) const;
+
+ void setSectionStretchable( int s, bool b );
+ bool isSectionStretchable( int s ) const;
+
+ void updateCache();
+
+Q_SIGNALS:
+ void sectionSizeChanged( int s );
+
+protected:
+ void paintEvent( TQPaintEvent *e );
+ void paintSection( TQPainter *p, int index, const TQRect& fr );
+ void mousePressEvent( TQMouseEvent *e );
+ void mouseMoveEvent( TQMouseEvent *e );
+ void mouseReleaseEvent( TQMouseEvent *e );
+ void mouseDoubleClickEvent( TQMouseEvent *e );
+ void resizeEvent( TQResizeEvent *e );
+
+private Q_SLOTS:
+ void doAutoScroll();
+ void sectionWidthChanged( int col, int os, int ns );
+ void indexChanged( int sec, int oldIdx, int newIdx );
+ void updateStretches();
+ void updateWidgetStretches();
+
+private:
+ void updateSelections();
+ void saveStates();
+ void setCaching( bool b );
+ void swapSections( int oldIdx, int newIdx, bool swapTable = TRUE );
+ bool doSelection( TQMouseEvent *e );
+ void sectionLabelChanged( int section );
+ void resizeArrays( int n );
+
+private:
+ TQMemArray<int> states, oldStates;
+ TQMemArray<bool> stretchable;
+ TQMemArray<int> sectionSizes, sectionPoses;
+ bool mousePressed;
+ int pressPos, startPos, endPos;
+ TQTable *table;
+ TQTimer *autoScrollTimer;
+ TQWidget *line1, *line2;
+ bool caching;
+ int resizedSection;
+ bool isResizing;
+ int numStretches;
+ TQTimer *stretchTimer, *widgetStretchTimer;
+ TQTableHeaderPrivate *d;
+
+};
+
+#ifdef _WS_TQWS_
+# define NO_LINE_WIDGET
+#endif
+
+
+
+struct TQTablePrivate
+{
+ TQTablePrivate() : hasRowSpan( FALSE ), hasColSpan( FALSE ),
+ inMenuMode( FALSE ), redirectMouseEvent( FALSE )
+ {
+ hiddenRows.setAutoDelete( TRUE );
+ hiddenCols.setAutoDelete( TRUE );
+ }
+ uint hasRowSpan : 1;
+ uint hasColSpan : 1;
+ uint inMenuMode : 1;
+ uint redirectMouseEvent : 1;
+ TQIntDict<int> hiddenRows, hiddenCols;
+ TQTimer *geomTimer;
+ int lastVisRow;
+ int lastVisCol;
+};
+
+struct TQTableHeaderPrivate
+{
+#ifdef NO_LINE_WIDGET
+ int oldLinePos;
+#endif
+};
+
+static bool isRowSelection( TQTable::SelectionMode selMode )
+{
+ return selMode == TQTable::SingleRow || selMode == TQTable::MultiRow;
+}
+
+/*!
+ \class TQTableSelection
+ \brief The TQTableSelection class provides access to a selected area in a
+ TQTable.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup advanced
+ \module table
+
+ The selection is a rectangular set of cells in a TQTable. One of
+ the rectangle's cells is called the anchor cell; this is the cell
+ that was selected first. The init() function sets the anchor and
+ the selection rectangle to exactly this cell; the expandTo()
+ function expands the selection rectangle to include additional
+ cells.
+
+ There are various access functions to tqfind out about the area:
+ anchorRow() and anchorCol() return the anchor's position;
+ leftCol(), rightCol(), topRow() and bottomRow() return the
+ rectangle's four edges. All four are part of the selection.
+
+ A newly created TQTableSelection is inactive -- isActive() returns
+ FALSE. You must use init() and expandTo() to activate it.
+
+ \sa TQTable TQTable::addSelection() TQTable::selection()
+ TQTable::selectCells() TQTable::selectRow() TQTable::selectColumn()
+*/
+
+/*!
+ Creates an inactive selection. Use init() and expandTo() to
+ activate it.
+*/
+
+TQTableSelection::TQTableSelection()
+ : active( FALSE ), inited( FALSE ), tRow( -1 ), lCol( -1 ),
+ bRow( -1 ), rCol( -1 ), aRow( -1 ), aCol( -1 )
+{
+}
+
+/*!
+ Creates an active selection, starting at \a start_row and \a
+ start_col, ending at \a end_row and \a end_col.
+*/
+
+TQTableSelection::TQTableSelection( int start_row, int start_col, int end_row, int end_col )
+ : active( FALSE ), inited( FALSE ), tRow( -1 ), lCol( -1 ),
+ bRow( -1 ), rCol( -1 ), aRow( -1 ), aCol( -1 )
+{
+ init( start_row, start_col );
+ expandTo( end_row, end_col );
+}
+
+/*!
+ Sets the selection anchor to cell \a row, \a col and the selection
+ to only contain this cell. The selection is not active until
+ expandTo() is called.
+
+ To extend the selection to include additional cells, call
+ expandTo().
+
+ \sa isActive()
+*/
+
+void TQTableSelection::init( int row, int col )
+{
+ aCol = lCol = rCol = col;
+ aRow = tRow = bRow = row;
+ active = FALSE;
+ inited = TRUE;
+}
+
+/*!
+ Expands the selection to include cell \a row, \a col. The new
+ selection rectangle is the bounding rectangle of \a row, \a col
+ and the previous selection rectangle. After calling this function
+ the selection is active.
+
+ If you haven't called init(), this function does nothing.
+
+ \sa init() isActive()
+*/
+
+void TQTableSelection::expandTo( int row, int col )
+{
+ if ( !inited )
+ return;
+ active = TRUE;
+
+ if ( row < aRow ) {
+ tRow = row;
+ bRow = aRow;
+ } else {
+ tRow = aRow;
+ bRow = row;
+ }
+
+ if ( col < aCol ) {
+ lCol = col;
+ rCol = aCol;
+ } else {
+ lCol = aCol;
+ rCol = col;
+ }
+}
+
+/*!
+ Returns TRUE if \a s includes the same cells as the selection;
+ otherwise returns FALSE.
+*/
+
+bool TQTableSelection::operator==( const TQTableSelection &s ) const
+{
+ return ( s.active == active &&
+ s.tRow == tRow && s.bRow == bRow &&
+ s.lCol == lCol && s.rCol == rCol );
+}
+
+/*!
+ \fn bool TQTableSelection::operator!=( const TQTableSelection &s ) const
+
+ Returns TRUE if \a s does not include the same cells as the
+ selection; otherwise returns FALSE.
+*/
+
+
+/*!
+ \fn int TQTableSelection::topRow() const
+
+ Returns the top row of the selection.
+
+ \sa bottomRow() leftCol() rightCol()
+*/
+
+/*!
+ \fn int TQTableSelection::bottomRow() const
+
+ Returns the bottom row of the selection.
+
+ \sa topRow() leftCol() rightCol()
+*/
+
+/*!
+ \fn int TQTableSelection::leftCol() const
+
+ Returns the left column of the selection.
+
+ \sa topRow() bottomRow() rightCol()
+*/
+
+/*!
+ \fn int TQTableSelection::rightCol() const
+
+ Returns the right column of the selection.
+
+ \sa topRow() bottomRow() leftCol()
+*/
+
+/*!
+ \fn int TQTableSelection::anchorRow() const
+
+ Returns the anchor row of the selection.
+
+ \sa anchorCol() expandTo()
+*/
+
+/*!
+ \fn int TQTableSelection::anchorCol() const
+
+ Returns the anchor column of the selection.
+
+ \sa anchorRow() expandTo()
+*/
+
+/*!
+ \fn int TQTableSelection::numRows() const
+
+ Returns the number of rows in the selection.
+
+ \sa numCols()
+*/
+int TQTableSelection::numRows() const
+{
+ return ( tRow < 0 ) ? 0 : bRow - tRow + 1;
+}
+
+/*!
+ Returns the number of columns in the selection.
+
+ \sa numRows()
+*/
+int TQTableSelection::numCols() const
+{
+ return ( lCol < 0 ) ? 0 : rCol - lCol + 1;
+}
+
+/*!
+ \fn bool TQTableSelection::isActive() const
+
+ Returns whether the selection is active or not. A selection is
+ active after init() \e and expandTo() have been called.
+*/
+
+/*!
+ \fn bool TQTableSelection::isEmpty() const
+
+ Returns whether the selection is empty or not.
+
+ \sa numRows(), numCols()
+*/
+
+/*!
+ \class TQTableItem
+ \brief The TQTableItem class provides the cell content for TQTable cells.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup advanced
+ \module table
+
+ For many applications TQTableItems are ideal for presenting and
+ editing the contents of TQTable cells. In situations where you need
+ to create very large tables you may prefer an alternative approach
+ to using TQTableItems: see the notes on large tables.
+
+ A TQTableItem tqcontains a cell's data, by default, a string and a
+ pixmap. The table item also holds the cell's display size and how
+ the data should be aligned. The table item specifies the cell's
+ \l EditType and the editor used for in-place editing (by default a
+ TQLineEdit). If you want checkboxes use \l{TQCheckTableItem}, and if
+ you want comboboxes use \l{TQComboTableItem}. The \l EditType (set
+ in the constructor) determines whether the cell's contents may be
+ edited.
+
+ If a pixmap is specified it is displayed to the left of any text.
+ You can change the text or pixmap with setText() and setPixmap()
+ respectively. For text you can use setWordWrap().
+
+ When sorting table items the key() function is used; by default
+ this returns the table item's text(). Reimplement key() to
+ customize how your table items will sort.
+
+ Table items are inserted into a table using TQTable::setItem(). If
+ you insert an item into a cell that already tqcontains a table item
+ the original item will be deleted.
+
+ Example:
+ \code
+ for ( int row = 0; row < table->numRows(); row++ ) {
+ for ( int col = 0; col < table->numCols(); col++ ) {
+ table->setItem( row, col,
+ new TQTableItem( table, TQTableItem::WhenCurrent, TQString::number( row * col ) ) );
+ }
+ }
+ \endcode
+
+ You can move a table item from one cell to another, in the same or
+ a different table, using TQTable::takeItem() and TQTable::setItem()
+ but see also TQTable::swapCells().
+
+ Table items can be deleted with delete in the standard way; the
+ table and cell will be updated accordingly.
+
+ Note, that if you have a table item that is not currently in a table
+ then anything you do to that item other than insert it into a table
+ will result in undefined behaviour.
+
+ Reimplement createEditor() and setContentFromEditor() if you want
+ to use your own widget instead of a TQLineEdit for editing cell
+ contents. Reimplement paint() if you want to display custom
+ content.
+
+ It is important to ensure that your custom widget can accept the
+ keyboard focus, so that the user can use the tab key to navigate the
+ table as normal. Therefore, if the widget returned by createEditor()
+ does not itself accept the keyboard focus, it is necessary to
+ nominate a child widget to do so on its behalf. For example, a
+ TQHBox with two child TQLineEdit widgets may use one of them to
+ accept the keyboard focus:
+
+ \code
+ TQWidget* MyTableItem::createEditor() const
+ {
+ TQHBox* hbox = new TQHBox( table()->viewport() );
+ hbox->setFocusProxy(new TQLineEdit( hbox ));
+ new TQLineEdit( hbox );
+ return hbox;
+ }
+ \endcode
+
+ By default, table items may be tqreplaced by new TQTableItems
+ during the lifetime of a TQTable. Therefore, if you create your
+ own subclass of TQTableItem, and you want to ensure that
+ this does not happen, you must call setReplaceable(FALSE)
+ in the constructor of your subclass.
+
+ \img qtableitems.png Table Items
+
+ \sa TQCheckTableItem TQComboTableItem
+
+*/
+
+/*!
+ \fn TQTable *TQTableItem::table() const
+
+ Returns the TQTable the table item belongs to.
+
+ \sa TQTable::setItem() TQTableItem()
+*/
+
+/*!
+ \enum TQTableItem::EditType
+
+ \target wheneditable
+ This enum is used to define whether a cell is editable or
+ read-only (in conjunction with other settings), and how the cell
+ should be displayed.
+
+ \value Always
+ The cell always \e looks editable.
+
+ Using this EditType ensures that the editor created with
+ createEditor() (by default a TQLineEdit) is always visible. This
+ has implications for the tqalignment of the content: the default
+ editor aligns everything (even numbers) to the left whilst
+ numerical values in the cell are by default aligned to the right.
+
+ If a cell with the edit type \c Always looks misaligned you could
+ reimplement createEditor() for these items.
+
+ \value WhenCurrent
+ The cell \e looks editable only when it has keyboard focus (see
+ TQTable::setCurrentCell()).
+
+ \value OnTyping
+ The cell \e looks editable only when the user types in it or
+ double-clicks it. It resembles the \c WhenCurrent functionality
+ but is, perhaps, nicer.
+
+ The \c OnTyping edit type is the default when TQTableItem objects
+ are created by the convenience functions TQTable::setText() and
+ TQTable::setPixmap().
+
+ \value Never The cell is not editable.
+
+ The cell is actually editable only if TQTable::isRowReadOnly() is
+ FALSE for its row, TQTable::isColumnReadOnly() is FALSE for its
+ column, and TQTable::isReadOnly() is FALSE.
+
+ TQComboTableItems have an isEditable() property. This property is
+ used to indicate whether the user may enter their own text or are
+ restricted to choosing one of the choices in the list.
+ TQComboTableItems may be interacted with only if they are editable
+ in accordance with their EditType as described above.
+
+*/
+
+/*!
+ Creates a table item that is a child of table \a table with no
+ text. The item has the \l EditType \a et.
+
+ The table item will use a TQLineEdit for its editor, will not
+ word-wrap and will occupy a single cell. Insert the table item
+ into a table with TQTable::setItem().
+
+ The table takes ownership of the table item, so a table item
+ should not be inserted into more than one table at a time.
+*/
+
+TQTableItem::TQTableItem( TQTable *table, EditType et )
+ : txt(), pix(), t( table ), edType( et ), wordwrap( FALSE ),
+ tcha( TRUE ), rw( -1 ), cl( -1 ), rowspan( 1 ), colspan( 1 )
+{
+ enabled = TRUE;
+}
+
+/*!
+ Creates a table item that is a child of table \a table with text
+ \a text. The item has the \l EditType \a et.
+
+ The table item will use a TQLineEdit for its editor, will not
+ word-wrap and will occupy a single cell. Insert the table item
+ into a table with TQTable::setItem().
+
+ The table takes ownership of the table item, so a table item
+ should not be inserted into more than one table at a time.
+*/
+
+TQTableItem::TQTableItem( TQTable *table, EditType et, const TQString &text )
+ : txt( text ), pix(), t( table ), edType( et ), wordwrap( FALSE ),
+ tcha( TRUE ), rw( -1 ), cl( -1 ), rowspan( 1 ), colspan( 1 )
+{
+ enabled = TRUE;
+}
+
+/*!
+ Creates a table item that is a child of table \a table with text
+ \a text and pixmap \a p. The item has the \l EditType \a et.
+
+ The table item will display the pixmap to the left of the text. It
+ will use a TQLineEdit for editing the text, will not word-wrap and
+ will occupy a single cell. Insert the table item into a table with
+ TQTable::setItem().
+
+ The table takes ownership of the table item, so a table item
+ should not be inserted in more than one table at a time.
+*/
+
+TQTableItem::TQTableItem( TQTable *table, EditType et,
+ const TQString &text, const TQPixmap &p )
+ : txt( text ), pix( p ), t( table ), edType( et ), wordwrap( FALSE ),
+ tcha( TRUE ), rw( -1 ), cl( -1 ), rowspan( 1 ), colspan( 1 )
+{
+ enabled = TRUE;
+}
+
+/*!
+ The destructor deletes this item and frees all allocated
+ resources.
+
+ If the table item is in a table (i.e. was inserted with
+ setItem()), it will be removed from the table and the cell it
+ occupied.
+*/
+
+TQTableItem::~TQTableItem()
+{
+ if ( table() )
+ table()->takeItem( this );
+}
+
+int TQTableItem::RTTI = 0;
+
+/*!
+ Returns the Run Time Type Identification value for this table item
+ which for TQTableItems is 0.
+
+ When you create subclasses based on TQTableItem make sure that each
+ subclass returns a unique rtti() value. It is advisable to use
+ values greater than 1000, preferably large random numbers, to
+ allow for extensions to this class.
+
+ \sa TQCheckTableItem::rtti() TQComboTableItem::rtti()
+*/
+
+int TQTableItem::rtti() const
+{
+ return RTTI;
+}
+
+/*!
+ Returns the table item's pixmap or a null pixmap if no pixmap has
+ been set.
+
+ \sa setPixmap() text()
+*/
+
+TQPixmap TQTableItem::pixmap() const
+{
+ return pix;
+}
+
+
+/*!
+ Returns the text of the table item or TQString::null if there is no
+ text.
+
+ To ensure that the current value of the editor is returned,
+ setContentFromEditor() is called:
+ \list 1
+ \i if the editMode() is \c Always, or
+ \i if editMode() is \e not \c Always but the editor of the cell is
+ active and the editor is not a TQLineEdit.
+ \endlist
+
+ This means that text() returns the original text value of the item
+ if the editor is a line edit, until the user commits an edit (e.g.
+ by pressing Enter or Tab) in which case the new text is returned.
+ For other editors (e.g. a combobox) setContentFromEditor() is
+ always called so the currently display value is the one returned.
+
+ \sa setText() pixmap()
+*/
+
+TQString TQTableItem::text() const
+{
+ TQWidget *w = table()->cellWidget( rw, cl );
+ if ( w && ( edType == Always ||
+ rtti() == TQComboTableItem::RTTI ||
+ rtti() == TQCheckTableItem::RTTI ) )
+ ( (TQTableItem*)this )->setContentFromEditor( w );
+ return txt;
+}
+
+/*!
+ Sets pixmap \a p to be this item's pixmap.
+
+ Note that setPixmap() does not update the cell the table item
+ belongs to. Use TQTable::updateCell() to tqrepaint the cell's
+ contents.
+
+ For \l{TQComboTableItem}s and \l{TQCheckTableItem}s this function
+ has no visible effect.
+
+ \sa TQTable::setPixmap() pixmap() setText()
+*/
+
+void TQTableItem::setPixmap( const TQPixmap &p )
+{
+ pix = p;
+}
+
+/*!
+ Changes the table item's text to \a str.
+
+ Note that setText() does not update the cell the table item
+ belongs to. Use TQTable::updateCell() to tqrepaint the cell's
+ contents.
+
+ \sa TQTable::setText() text() setPixmap() TQTable::updateCell()
+*/
+
+void TQTableItem::setText( const TQString &str )
+{
+ txt = str;
+}
+
+/*!
+ This virtual function is used to paint the contents of an item
+ using the painter \a p in the rectangular area \a cr using the
+ color group \a cg.
+
+ If \a selected is TRUE the cell is displayed in a way that
+ indicates that it is highlighted.
+
+ You don't usually need to use this function but if you want to
+ draw custom content in a cell you will need to reimplement it.
+
+ The painter passed to this function is translated so that 0, 0
+ is the top-left corner of the item that is being painted.
+
+ Note that the painter is not clipped by default in order to get
+ maximum efficiency. If you want clipping, use
+
+ \code
+ p->setClipRect( table()->cellRect(row, col), TQPainter::ClipPainter );
+ //... your drawing code
+ p->setClipping( FALSE );
+ \endcode
+
+*/
+
+void TQTableItem::paint( TQPainter *p, const TQColorGroup &cg,
+ const TQRect &cr, bool selected )
+{
+ p->fillRect( 0, 0, cr.width(), cr.height(),
+ selected ? cg.brush( TQColorGroup::Highlight )
+ : cg.brush( TQColorGroup::Base ) );
+
+ int w = cr.width();
+ int h = cr.height();
+
+ int x = 0;
+ if ( !pix.isNull() ) {
+ p->drawPixmap( 0, ( cr.height() - pix.height() ) / 2, pix );
+ x = pix.width() + 2;
+ }
+
+ if ( selected )
+ p->setPen( cg.highlightedText() );
+ else
+ p->setPen( cg.text() );
+ p->drawText( x + 2, 0, w - x - 4, h,
+ wordwrap ? (tqalignment() | WordBreak) : tqalignment(), text() );
+}
+
+/*!
+This virtual function creates an editor which the user can
+interact with to edit the cell's contents. The default
+implementation creates a TQLineEdit.
+
+If the function returns 0, the cell is read-only.
+
+The returned widget should preferably be invisible, ideally with
+TQTable::viewport() as tqparent.
+
+If you reimplement this function you'll almost certainly need to
+reimplement setContentFromEditor(), and may need to reimplement
+tqsizeHint().
+
+\quotefile table/statistics/statistics.cpp
+\skipto createEditor
+\printto }
+
+\sa TQTable::createEditor() setContentFromEditor() TQTable::viewport() setReplaceable()
+*/
+
+TQWidget *TQTableItem::createEditor() const
+{
+ TQLineEdit *e = new TQLineEdit( table()->viewport(), "qt_tableeditor" );
+ e->setFrame( FALSE );
+ e->setText( text() );
+ return e;
+}
+
+/*!
+Whenever the content of a cell has been edited by the editor \a w,
+TQTable calls this virtual function to copy the new values into the
+TQTableItem.
+
+If you reimplement createEditor() and return something that is not
+a TQLineEdit you will need to reimplement this function.
+
+\quotefile table/statistics/statistics.cpp
+\skipto setContentFromEditor
+\printto }
+
+\sa TQTable::setCellContentFromEditor()
+*/
+
+void TQTableItem::setContentFromEditor( TQWidget *w )
+{
+ TQLineEdit *le = ::tqqt_cast<TQLineEdit*>(w);
+ if ( le ) {
+ TQString input = le->text();
+ if ( le->validator() )
+ le->validator()->fixup( input );
+ setText( input );
+ }
+}
+
+/*!
+ The tqalignment function returns how the text contents of the cell
+ are aligned when drawn. The default implementation aligns numbers
+ to the right and any other text to the left.
+
+ \sa TQt::AlignmentFlags
+*/
+
+// ed: For consistency reasons a tqsetAlignment() should be provided
+// as well.
+
+int TQTableItem::tqalignment() const
+{
+ bool num;
+ bool ok1 = FALSE, ok2 = FALSE;
+ (void)text().toInt( &ok1 );
+ if ( !ok1 )
+ (void)text().toDouble( &ok2 ); // ### should be .-aligned
+ num = ok1 || ok2;
+
+ return ( num ? AlignRight : AlignLeft ) | AlignVCenter;
+}
+
+/*!
+ If \a b is TRUE, the cell's text will be wrapped over multiple
+ lines, when necessary, to fit the width of the cell; otherwise the
+ text will be written as a single line.
+
+ \sa wordWrap() TQTable::adjustColumn() TQTable::setColumnStretchable()
+*/
+
+void TQTableItem::setWordWrap( bool b )
+{
+ wordwrap = b;
+}
+
+/*!
+ Returns TRUE if word wrap is enabled for the cell; otherwise
+ returns FALSE.
+
+ \sa setWordWrap()
+*/
+
+bool TQTableItem::wordWrap() const
+{
+ return wordwrap;
+}
+
+/*! \internal */
+
+void TQTableItem::updateEditor( int oldRow, int oldCol )
+{
+ if ( edType != Always )
+ return;
+ if ( oldRow != -1 && oldCol != -1 )
+ table()->clearCellWidget( oldRow, oldCol );
+ if ( rw != -1 && cl != -1 )
+ table()->setCellWidget( rw, cl, createEditor() );
+}
+
+/*!
+ Returns the table item's edit type.
+
+ This is set when the table item is constructed.
+
+ \sa EditType TQTableItem()
+*/
+
+TQTableItem::EditType TQTableItem::editType() const
+{
+ return edType;
+}
+
+/*!
+ If \a b is TRUE it is acceptable to tqreplace the contents of the
+ cell with the contents of another TQTableItem. If \a b is FALSE the
+ contents of the cell may not be tqreplaced by the contents of
+ another table item. Table items that span more than one cell may
+ not have their contents tqreplaced by another table item.
+
+ (This differs from \l EditType because EditType is concerned with
+ whether the \e user is able to change the contents of a cell.)
+
+ \sa isReplaceable()
+*/
+
+void TQTableItem::setReplaceable( bool b )
+{
+ tcha = b;
+}
+
+/*!
+ This function returns whether the contents of the cell may be
+ tqreplaced with the contents of another table item. Regardless of
+ this setting, table items that span more than one cell may not
+ have their contents tqreplaced by another table item.
+
+ (This differs from \l EditType because EditType is concerned with
+ whether the \e user is able to change the contents of a cell.)
+
+ \sa setReplaceable() EditType
+*/
+
+bool TQTableItem::isReplaceable() const
+{
+ if ( rowspan > 1 || colspan > 1 )
+ return FALSE;
+ return tcha;
+}
+
+/*!
+ This virtual function returns the key that should be used for
+ sorting. The default implementation returns the text() of the
+ relevant item.
+
+ \sa TQTable::setSorting()
+*/
+
+TQString TQTableItem::key() const
+{
+ return text();
+}
+
+/*!
+ This virtual function returns the size a cell needs to show its
+ entire content.
+
+ If you subclass TQTableItem you will often need to reimplement this
+ function.
+*/
+
+TQSize TQTableItem::tqsizeHint() const
+{
+ TQSize strutSize = TQApplication::globalStrut();
+ if ( edType == Always && table()->cellWidget( rw, cl ) )
+ return table()->cellWidget( rw, cl )->tqsizeHint().expandedTo( strutSize );
+
+ TQSize s;
+ int x = 0;
+ if ( !pix.isNull() ) {
+ s = pix.size();
+ s.setWidth( s.width() + 2 );
+ x = pix.width() + 2;
+ }
+
+ TQString t = text();
+ if ( !wordwrap && t.tqfind( '\n' ) == -1 )
+ return TQSize( s.width() + table()->fontMetrics().width( text() ) + 10,
+ TQMAX( s.height(), table()->fontMetrics().height() ) ).expandedTo( strutSize );
+
+ TQRect r = table()->fontMetrics().boundingRect( x + 2, 0, table()->columnWidth( col() ) - x - 4, 0,
+ wordwrap ? (tqalignment() | WordBreak) : tqalignment(),
+ text() );
+ r.setWidth( TQMAX( r.width() + 10, table()->columnWidth( col() ) ) );
+ return TQSize( r.width(), TQMAX( s.height(), r.height() ) ).expandedTo( strutSize );
+}
+
+/*!
+ Changes the extent of the TQTableItem so that it spans multiple
+ cells covering \a rs rows and \a cs columns. The top left cell is
+ the original cell.
+
+ \warning This function only works if the item has already been
+ inserted into the table using e.g. TQTable::setItem(). This
+ function also checks to make sure if \a rs and \a cs are within
+ the bounds of the table and returns without changing the span if
+ they are not. In addition swapping, inserting or removing rows and
+ columns that cross TQTableItems spanning more than one cell is not
+ supported.
+
+ \sa rowSpan() colSpan()
+*/
+
+void TQTableItem::setSpan( int rs, int cs )
+{
+ if ( rs == rowspan && cs == colspan )
+ return;
+
+ if ( !table()->d->hasRowSpan )
+ table()->d->hasRowSpan = rs > 1;
+ if ( !table()->d->hasColSpan )
+ table()->d->hasColSpan = cs > 1;
+ // return if we are thinking too big...
+ if ( rw + rs > table()->numRows() )
+ return;
+
+ if ( cl + cs > table()->numCols() )
+ return;
+
+ if ( rw == -1 || cl == -1 )
+ return;
+
+ int rrow = rw;
+ int rcol = cl;
+ if ( rowspan > 1 || colspan > 1 ) {
+ TQTable* t = table();
+ t->takeItem( this );
+ t->setItem( rrow, rcol, this );
+ }
+
+ rowspan = rs;
+ colspan = cs;
+
+ for ( int r = 0; r < rowspan; ++r ) {
+ for ( int c = 0; c < colspan; ++c ) {
+ if ( r == 0 && c == 0 )
+ continue;
+ qt_update_cell_widget = FALSE;
+ table()->setItem( r + rw, c + cl, this );
+ qt_update_cell_widget = TRUE;
+ rw = rrow;
+ cl = rcol;
+ }
+ }
+
+ table()->updateCell( rw, cl );
+ TQWidget *w = table()->cellWidget( rw, cl );
+ if ( w )
+ w->resize( table()->cellGeometry( rw, cl ).size() );
+}
+
+/*!
+ Returns the row span of the table item, usually 1.
+
+ \sa setSpan() colSpan()
+*/
+
+int TQTableItem::rowSpan() const
+{
+ return rowspan;
+}
+
+/*!
+ Returns the column span of the table item, usually 1.
+
+ \sa setSpan() rowSpan()
+*/
+
+int TQTableItem::colSpan() const
+{
+ return colspan;
+}
+
+/*!
+ Sets row \a r as the table item's row. Usually you do not need to
+ call this function.
+
+ If the cell spans multiple rows, this function sets the top row
+ and retains the height of the multi-cell table item.
+
+ \sa row() setCol() rowSpan()
+*/
+
+void TQTableItem::setRow( int r )
+{
+ rw = r;
+}
+
+/*!
+ Sets column \a c as the table item's column. Usually you will not
+ need to call this function.
+
+ If the cell spans multiple columns, this function sets the
+ left-most column and retains the width of the multi-cell table
+ item.
+
+ \sa col() setRow() colSpan()
+*/
+
+void TQTableItem::setCol( int c )
+{
+ cl = c;
+}
+
+/*!
+ Returns the row where the table item is located. If the cell spans
+ multiple rows, this function returns the top-most row.
+
+ \sa col() setRow()
+*/
+
+int TQTableItem::row() const
+{
+ return rw;
+}
+
+/*!
+ Returns the column where the table item is located. If the cell
+ spans multiple columns, this function returns the left-most
+ column.
+
+ \sa row() setCol()
+*/
+
+int TQTableItem::col() const
+{
+ return cl;
+}
+
+/*!
+ If \a b is TRUE, the table item is enabled; if \a b is FALSE the
+ table item is disabled.
+
+ A disabled item doesn't respond to user interaction.
+
+ \sa isEnabled()
+*/
+
+void TQTableItem::setEnabled( bool b )
+{
+ if ( b == (bool)enabled )
+ return;
+ enabled = b;
+ table()->updateCell( row(), col() );
+}
+
+/*!
+ Returns TRUE if the table item is enabled; otherwise returns FALSE.
+
+ \sa setEnabled()
+*/
+
+bool TQTableItem::isEnabled() const
+{
+ return (bool)enabled;
+}
+
+/*!
+ \class TQComboTableItem
+ \brief The TQComboTableItem class provides a means of using
+ comboboxes in TQTables.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup advanced
+ \module table
+
+ A TQComboTableItem is a table item which looks and behaves like a
+ combobox. The advantage of using TQComboTableItems rather than real
+ comboboxes is that a TQComboTableItem uses far less resources than
+ real comboboxes in \l{TQTable}s. When the cell has the focus it
+ displays a real combobox which the user can interact with. When
+ the cell does not have the focus the cell \e looks like a
+ combobox. Only text items (i.e. no pixmaps) may be used in
+ TQComboTableItems.
+
+ TQComboTableItem items have the edit type \c WhenCurrent (see
+ \l{EditType}). The TQComboTableItem's list of items is provided by
+ a TQStringList passed to the constructor.
+
+ The list of items may be changed using setStringList(). The
+ current item can be set with setCurrentItem() and retrieved with
+ currentItem(). The text of the current item can be obtained with
+ currentText(), and the text of a particular item can be retrieved
+ with text().
+
+ If isEditable() is TRUE the TQComboTableItem will permit the user
+ to either choose an existing list item, or create a new list item
+ by entering their own text; otherwise the user may only choose one
+ of the existing list items.
+
+ To populate a table cell with a TQComboTableItem use
+ TQTable::setItem().
+
+ TQComboTableItems may be deleted with TQTable::clearCell().
+
+ TQComboTableItems can be distinguished from \l{TQTableItem}s and
+ \l{TQCheckTableItem}s using their Run Time Type Identification
+ number (see rtti()).
+
+ \img qtableitems.png Table Items
+
+ \sa TQCheckTableItem TQTableItem TQComboBox
+*/
+
+TQComboBox *TQComboTableItem::fakeCombo = 0;
+TQWidget *TQComboTableItem::fakeComboWidget = 0;
+int TQComboTableItem::fakeRef = 0;
+
+/*!
+ Creates a combo table item for the table \a table. The combobox's
+ list of items is passed in the \a list argument. If \a editable is
+ TRUE the user may type in new list items; if \a editable is FALSE
+ the user may only select from the list of items provided.
+
+ By default TQComboTableItems cannot be tqreplaced by other table
+ items since isReplaceable() returns FALSE by default.
+
+ \sa TQTable::clearCell() EditType
+*/
+
+TQComboTableItem::TQComboTableItem( TQTable *table, const TQStringList &list, bool editable )
+ : TQTableItem( table, WhenCurrent, "" ), entries( list ), current( 0 ), edit( editable )
+{
+ setReplaceable( FALSE );
+ if ( !TQComboTableItem::fakeCombo ) {
+ TQComboTableItem::fakeComboWidget = new TQWidget( 0, 0 );
+ TQComboTableItem::fakeCombo = new TQComboBox( FALSE, TQComboTableItem::fakeComboWidget, 0 );
+ TQComboTableItem::fakeCombo->hide();
+ }
+ ++TQComboTableItem::fakeRef;
+ if ( entries.count() )
+ setText( *entries.at( current ) );
+}
+
+/*!
+ TQComboTableItem destructor.
+*/
+TQComboTableItem::~TQComboTableItem()
+{
+ if (--TQComboTableItem::fakeRef <= 0) {
+ delete TQComboTableItem::fakeComboWidget;
+ TQComboTableItem::fakeComboWidget = 0;
+ TQComboTableItem::fakeCombo = 0;
+ }
+}
+
+/*!
+ Sets the list items of this TQComboTableItem to the strings in the
+ string list \a l.
+*/
+
+void TQComboTableItem::setStringList( const TQStringList &l )
+{
+ entries = l;
+ current = 0;
+ if ( entries.count() )
+ setText( *entries.at( current ) );
+ if ( table()->cellWidget( row(), col() ) ) {
+ cb->clear();
+ cb->insertStringList( entries );
+ }
+ table()->updateCell( row(), col() );
+}
+
+/*! \reimp */
+
+TQWidget *TQComboTableItem::createEditor() const
+{
+ // create an editor - a combobox in our case
+ ( (TQComboTableItem*)this )->cb = new TQComboBox( edit, table()->viewport(), "qt_editor_cb" );
+ cb->insertStringList( entries );
+ cb->setCurrentItem( current );
+ TQObject::connect( cb, TQT_SIGNAL( activated(int) ), table(), TQT_SLOT( doValueChanged() ) );
+ return cb;
+}
+
+/*! \reimp */
+
+void TQComboTableItem::setContentFromEditor( TQWidget *w )
+{
+ TQComboBox *cb = ::tqqt_cast<TQComboBox*>(w);
+ if ( cb ) {
+ entries.clear();
+ for ( int i = 0; i < cb->count(); ++i )
+ entries << cb->text( i );
+ current = cb->currentItem();
+ setText( *entries.at( current ) );
+ }
+}
+
+/*! \reimp */
+
+void TQComboTableItem::paint( TQPainter *p, const TQColorGroup &cg,
+ const TQRect &cr, bool selected )
+{
+ fakeCombo->resize( cr.width(), cr.height() );
+
+ TQColorGroup c( cg );
+ if ( selected ) {
+ c.setBrush( TQColorGroup::Base, cg.brush( TQColorGroup::Highlight ) );
+ c.setColor( TQColorGroup::Text, cg.highlightedText() );
+ }
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if(isEnabled() && table()->isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ table()->tqstyle().tqdrawComplexControl( TQStyle::CC_ComboBox, p, fakeCombo, fakeCombo->rect(), c, flags );
+
+ p->save();
+ TQRect textR = table()->tqstyle().querySubControlMetrics(TQStyle::CC_ComboBox, fakeCombo,
+ TQStyle::SC_ComboBoxEditField);
+ int align = tqalignment(); // tqalignment() changes entries
+ p->drawText( textR, wordWrap() ? ( align | WordBreak ) : align, *entries.at( current ) );
+ p->restore();
+}
+
+/*!
+ Sets the list item \a i to be the combo table item's current list
+ item.
+
+ \sa currentItem()
+*/
+
+void TQComboTableItem::setCurrentItem( int i )
+{
+ TQWidget *w = table()->cellWidget( row(), col() );
+ TQComboBox *cb = ::tqqt_cast<TQComboBox*>(w);
+ if ( cb ) {
+ cb->setCurrentItem( i );
+ current = i;
+ setText( cb->currentText() );
+ } else {
+ current = i;
+ setText( *entries.at( i ) );
+ table()->updateCell( row(), col() );
+ }
+}
+
+/*!
+ \overload
+
+ Sets the list item whose text is \a s to be the combo table item's
+ current list item. Does nothing if no list item has the text \a s.
+
+ \sa currentItem()
+*/
+
+void TQComboTableItem::setCurrentItem( const TQString &s )
+{
+ int i = entries.tqfindIndex( s );
+ if ( i != -1 )
+ setCurrentItem( i );
+}
+
+/*!
+ Returns the index of the combo table item's current list item.
+
+ \sa setCurrentItem()
+*/
+
+int TQComboTableItem::currentItem() const
+{
+ TQWidget *w = table()->cellWidget( row(), col() );
+ TQComboBox *cb = ::tqqt_cast<TQComboBox*>(w);
+ if ( cb )
+ return cb->currentItem();
+ return current;
+}
+
+/*!
+ Returns the text of the combo table item's current list item.
+
+ \sa currentItem() text()
+*/
+
+TQString TQComboTableItem::currentText() const
+{
+ TQWidget *w = table()->cellWidget( row(), col() );
+ TQComboBox *cb = ::tqqt_cast<TQComboBox*>(w);
+ if ( cb )
+ return cb->currentText();
+ return *entries.at( current );
+}
+
+/*!
+ Returns the total number of list items in the combo table item.
+*/
+
+int TQComboTableItem::count() const
+{
+ TQWidget *w = table()->cellWidget( row(), col() );
+ TQComboBox *cb = ::tqqt_cast<TQComboBox*>(w);
+ if ( cb )
+ return cb->count();
+ return (int)entries.count(); //### size_t/int cast
+}
+
+/*!
+ Returns the text of the combo's list item at index \a i.
+
+ \sa currentText()
+*/
+
+TQString TQComboTableItem::text( int i ) const
+{
+ TQWidget *w = table()->cellWidget( row(), col() );
+ TQComboBox *cb = ::tqqt_cast<TQComboBox*>(w);
+ if ( cb )
+ return cb->text( i );
+ return *entries.at( i );
+}
+
+/*!
+ If \a b is TRUE the combo table item can be edited, i.e. the user
+ may enter a new text item themselves. If \a b is FALSE the user may
+ may only choose one of the existing items.
+
+ \sa isEditable()
+*/
+
+void TQComboTableItem::setEditable( bool b )
+{
+ edit = b;
+}
+
+/*!
+ Returns TRUE if the user can add their own list items to the
+ combobox's list of items; otherwise returns FALSE.
+
+ \sa setEditable()
+*/
+
+bool TQComboTableItem::isEditable() const
+{
+ return edit;
+}
+
+int TQComboTableItem::RTTI = 1;
+
+/*!
+ \fn int TQComboTableItem::rtti() const
+
+ Returns 1.
+
+ Make your derived classes return their own values for rtti()to
+ distinguish between different table item subclasses. You should
+ use values greater than 1000, preferably a large random number, to
+ allow for extensions to this class.
+
+
+ \sa TQTableItem::rtti()
+*/
+
+int TQComboTableItem::rtti() const
+{
+ return RTTI;
+}
+
+/*! \reimp */
+
+TQSize TQComboTableItem::tqsizeHint() const
+{
+ fakeCombo->insertItem( currentText() );
+ fakeCombo->setCurrentItem( fakeCombo->count() - 1 );
+ TQSize sh = fakeCombo->tqsizeHint();
+ fakeCombo->removeItem( fakeCombo->count() - 1 );
+ return sh.expandedTo( TQApplication::globalStrut() );
+}
+
+/*!
+ \class TQCheckTableItem
+ \brief The TQCheckTableItem class provides checkboxes in TQTables.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup advanced
+ \module table
+
+ A TQCheckTableItem is a table item which looks and behaves like a
+ checkbox. The advantage of using TQCheckTableItems rather than real
+ checkboxes is that a TQCheckTableItem uses far less resources than
+ a real checkbox would in a \l{TQTable}. When the cell has the focus
+ it displays a real checkbox which the user can interact with. When
+ the cell does not have the focus the cell \e looks like a
+ checkbox. Pixmaps may not be used in TQCheckTableItems.
+
+ TQCheckTableItem items have the edit type \c WhenCurrent (see
+ \l{EditType}).
+
+ To change the checkbox's label use setText(). The checkbox can be
+ checked and unchecked with setChecked() and its state retrieved
+ using isChecked().
+
+ To populate a table cell with a TQCheckTableItem use
+ TQTable::setItem().
+
+ TQCheckTableItems can be distinguished from \l{TQTableItem}s and
+ \l{TQComboTableItem}s using their Run Time Type Identification
+ (rtti) value.
+
+ \img qtableitems.png Table Items
+
+ \sa rtti() EditType TQComboTableItem TQTableItem TQCheckBox
+*/
+
+/*!
+ Creates a TQCheckTableItem with an \l{EditType} of \c WhenCurrent
+ as a child of \a table. The checkbox is initially unchecked and
+ its label is set to the string \a txt.
+*/
+
+TQCheckTableItem::TQCheckTableItem( TQTable *table, const TQString &txt )
+ : TQTableItem( table, WhenCurrent, txt ), checked( FALSE )
+{
+}
+
+/*! \reimp */
+
+void TQCheckTableItem::setText( const TQString &t )
+{
+ TQTableItem::setText( t );
+ TQWidget *w = table()->cellWidget( row(), col() );
+ TQCheckBox *cb = ::tqqt_cast<TQCheckBox*>(w);
+ if ( cb )
+ cb->setText( t );
+}
+
+
+/*! \reimp */
+
+TQWidget *TQCheckTableItem::createEditor() const
+{
+ // create an editor - a combobox in our case
+ ( (TQCheckTableItem*)this )->cb = new TQCheckBox( table()->viewport(), "qt_editor_checkbox" );
+ cb->setChecked( checked );
+ cb->setText( text() );
+ cb->setBackgroundColor( table()->viewport()->backgroundColor() );
+ TQObject::connect( cb, TQT_SIGNAL( toggled(bool) ), table(), TQT_SLOT( doValueChanged() ) );
+ return cb;
+}
+
+/*! \reimp */
+
+void TQCheckTableItem::setContentFromEditor( TQWidget *w )
+{
+ TQCheckBox *cb = ::tqqt_cast<TQCheckBox*>(w);
+ if ( cb )
+ checked = cb->isChecked();
+}
+
+/*! \reimp */
+
+void TQCheckTableItem::paint( TQPainter *p, const TQColorGroup &cg,
+ const TQRect &cr, bool selected )
+{
+ p->fillRect( 0, 0, cr.width(), cr.height(),
+ selected ? cg.brush( TQColorGroup::Highlight )
+ : cg.brush( TQColorGroup::Base ) );
+
+ int w = cr.width();
+ int h = cr.height();
+ TQSize sz = TQSize( table()->tqstyle().tqpixelMetric( TQStyle::PM_IndicatorWidth ),
+ table()->tqstyle().tqpixelMetric( TQStyle::PM_IndicatorHeight ) );
+ TQColorGroup c( cg );
+ c.setBrush( TQColorGroup::Background, c.brush( TQColorGroup::Base ) );
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if(isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if ( checked )
+ flags |= TQStyle::Style_On;
+ else
+ flags |= TQStyle::Style_Off;
+ if ( isEnabled() && table()->isEnabled() )
+ flags |= TQStyle::Style_Enabled;
+
+ table()->tqstyle().tqdrawPrimitive( TQStyle::PE_Indicator, p,
+ TQRect( 0, ( cr.height() - sz.height() ) / 2, sz.width(), sz.height() ), c, flags );
+ int x = sz.width() + 6;
+ w = w - x;
+ if ( selected )
+ p->setPen( cg.highlightedText() );
+ else
+ p->setPen( cg.text() );
+ p->drawText( x, 0, w, h, wordWrap() ? ( tqalignment() | WordBreak ) : tqalignment(), text() );
+}
+
+/*!
+ If \a b is TRUE the checkbox is checked; if \a b is FALSE the
+ checkbox is unchecked.
+
+ \sa isChecked()
+*/
+
+void TQCheckTableItem::setChecked( bool b )
+{
+ checked = b;
+ table()->updateCell( row(), col() );
+ TQWidget *w = table()->cellWidget( row(), col() );
+ TQCheckBox *cb = ::tqqt_cast<TQCheckBox*>(w);
+ if ( cb )
+ cb->setChecked( b );
+}
+
+/*!
+ Returns TRUE if the checkbox table item is checked; otherwise
+ returns FALSE.
+
+ \sa setChecked()
+*/
+
+bool TQCheckTableItem::isChecked() const
+{
+ // #### why was this next line here. It must not be here, as
+ // #### people want to call isChecked() from within paintCell()
+ // #### and end up in an infinite loop that way
+ // table()->updateCell( row(), col() );
+ TQWidget *w = table()->cellWidget( row(), col() );
+ TQCheckBox *cb = ::tqqt_cast<TQCheckBox*>(w);
+ if ( cb )
+ return cb->isChecked();
+ return checked;
+}
+
+int TQCheckTableItem::RTTI = 2;
+
+/*!
+ \fn int TQCheckTableItem::rtti() const
+
+ Returns 2.
+
+ Make your derived classes return their own values for rtti()to
+ distinguish between different table item subclasses. You should
+ use values greater than 1000, preferably a large random number, to
+ allow for extensions to this class.
+
+ \sa TQTableItem::rtti()
+*/
+
+int TQCheckTableItem::rtti() const
+{
+ return RTTI;
+}
+
+/*! \reimp */
+
+TQSize TQCheckTableItem::tqsizeHint() const
+{
+ TQSize sz = TQSize( table()->tqstyle().tqpixelMetric( TQStyle::PM_IndicatorWidth ),
+ table()->tqstyle().tqpixelMetric( TQStyle::PM_IndicatorHeight ) );
+ sz.setWidth( sz.width() + 6 );
+ TQSize sh( TQTableItem::tqsizeHint() );
+ return TQSize( sh.width() + sz.width(), TQMAX( sh.height(), sz.height() ) ).
+ expandedTo( TQApplication::globalStrut() );
+}
+
+/*! \file table/small-table-demo/main.cpp */
+/*! \file table/bigtable/main.cpp */
+/*! \file table/statistics/statistics.cpp */
+
+/*!
+ \class TQTable
+ \brief The TQTable class provides a flexible editable table widget.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \mainclass
+ \ingroup advanced
+ \module table
+
+ TQTable is easy to use, although it does have a large API because
+ of the comprehensive functionality that it provides. TQTable
+ includes functions for manipulating \link #headers
+ headers\endlink, \link #columnsrows rows and columns\endlink,
+ \link #cells cells\endlink and \link #selections
+ selections\endlink. TQTable also provides in-place editing and
+ \link dnd.html drag and drop\endlink, as well as a useful set of
+ \link #Q_SIGNALS Q_SIGNALS\endlink. TQTable efficiently supports very
+ large tables, for example, tables one million by one million cells
+ are perfectly possible. TQTable is economical with memory, using
+ none for unused cells.
+
+ \code
+ TQTable *table = new TQTable( 100, 250, this );
+ table->setPixmap( 3, 2, pix );
+ table->setText( 3, 2, "A pixmap" );
+ \endcode
+
+ The first line constructs the table specifying its size in rows
+ and columns. We then insert a pixmap and some text into the \e
+ same \link #cells cell\endlink, with the pixmap appearing to the
+ left of the text. TQTable cells can be populated with
+ \l{TQTableItem}s, \l{TQComboTableItem}s or by \l{TQCheckTableItem}s.
+ By default a vertical header appears at the left of the table
+ showing row numbers and a horizontal header appears at the top of
+ the table showing column numbers. (The numbers displayed start at
+ 1, although row and column numbers within TQTable begin at 0.)
+
+ If you want to use mouse tracking call setMouseTracking( TRUE ) on
+ the \e viewport; (see \link tqscrollview.html#allviews
+ TQScrollView\endlink).
+
+ \img qtableitems.png Table Items
+
+ \target headers
+ \section1 Headers
+
+ TQTable supports a header column, e.g. to display row numbers, and
+ a header row, e.g to display column titles. To set row or column
+ labels use TQHeader::setLabel() on the pointers returned by
+ verticalHeader() and horizontalHeader() respectively. The vertical
+ header is displayed within the table's left margin whose width is
+ set with setLeftMargin(). The horizontal header is displayed
+ within the table's top margin whose height is set with
+ setTopMargin(). The table's grid can be switched off with
+ setShowGrid(). If you want to hide a horizontal header call
+ hide(), and call setTopMargin( 0 ) so that the area the header
+ would have occupied is reduced to zero size.
+
+ Header labels are indexed via their section numbers. Note that the
+ default behavior of TQHeader regarding section numbers is overriden
+ for TQTable. See the explanation below in the Rows and Columns
+ section in the discussion of moving columns and rows.
+
+ \target columnsrows
+ \section1 Rows and Columns
+
+ Row and column sizes are set with setRowHeight() and
+ setColumnWidth(). If you want a row high enough to show the
+ tallest item in its entirety, use adjustRow(). Similarly, to make
+ a column wide enough to show the widest item use adjustColumn().
+ If you want the row height and column width to adjust
+ automatically as the height and width of the table changes use
+ setRowStretchable() and setColumnStretchable().
+
+ Rows and columns can be hidden and shown with hideRow(),
+ hideColumn(), showRow() and showColumn(). New rows and columns are
+ inserted using insertRows() and insertColumns(). Additional rows
+ and columns are added at the bottom (rows) or right (columns) if
+ you set setNumRows() or setNumCols() to be larger than numRows()
+ or numCols(). Existing rows and columns are removed with
+ removeRow() and removeColumn(). Multiple rows and columns can be
+ removed with removeRows() and removeColumns().
+
+ Rows and columns can be set to be moveable using
+ rowMovingEnabled() and columnMovingEnabled(). The user can drag
+ them to reorder them holding down the Ctrl key and dragging the
+ mouse. For performance reasons, the default behavior of TQHeader
+ section numbers is overridden by TQTable. Currently in TQTable, when
+ a row or column is dragged and reordered, the section number is
+ also changed to its new position. Therefore, there is no
+ difference between the section and the index fields in TQHeader.
+ The TQTable TQHeader classes do not provide a mechanism for indexing
+ independently of the user interface ordering.
+
+ The table can be sorted using sortColumn(). Users can sort a
+ column by clicking its header if setSorting() is set to TRUE. Rows
+ can be swapped with swapRows(), columns with swapColumns() and
+ cells with swapCells().
+
+ For editable tables (see setReadOnly()) you can set the read-only
+ property of individual rows and columns with setRowReadOnly() and
+ setColumnReadOnly(). (Whether a cell is editable or read-only
+ depends on these settings and the cell's \link
+ qtableitem.html#wheneditable TQTableItem::EditType\endlink.)
+
+ The row and column which have the focus are returned by
+ currentRow() and currentColumn() respectively.
+
+ Although many TQTable functions operate in terms of rows and
+ columns the indexOf() function returns a single integer
+ identifying a particular cell.
+
+ \target cells
+ \section1 Cells
+
+ All of a TQTable's cells are empty when the table is constructed.
+
+ There are two approaches to populating the table's cells. The
+ first and simplest approach is to use TQTableItems or TQTableItem
+ subclasses. The second approach doesn't use TQTableItems at all
+ which is useful for very large sparse tables but requires you to
+ reimplement a number of functions. We'll look at each approach in
+ turn.
+
+ To put a string in a cell use setText(). This function will create
+ a new TQTableItem for the cell if one doesn't already exist, and
+ displays the text in it. By default the table item's widget will
+ be a TQLineEdit. A pixmap may be put in a cell with setPixmap(),
+ which also creates a table item if required. A cell may contain \e
+ both a pixmap and text; the pixmap is displayed to the left of the
+ text. Another approach is to construct a TQTableItem or TQTableItem
+ subclass, set its properties, then insert it into a cell with
+ setItem().
+
+ If you want cells which contain comboboxes use the TQComboTableItem
+ class. Similarly if you require cells containing checkboxes use
+ the TQCheckTableItem class. These table items look and behave just
+ like the combobox or checkbox widgets but consume far less memory.
+
+ \quotefile table/small-table-demo/main.cpp
+ \skipto int j
+ \printuntil TQCheckTableItem
+ In the example above we create a column of TQCheckTableItems and
+ insert them into the table using setItem().
+
+ TQTable takes ownership of its TQTableItems and will delete them
+ when the table itself is destroyed. You can take ownership of a
+ table item using takeItem() which you use to move a cell's
+ contents from one cell to another, either within the same table,
+ or from one table to another. (See also, swapCells()).
+
+ In-place editing of the text in TQTableItems, and the values in
+ TQComboTableItems and TQCheckTableItems works automatically. Cells
+ may be editable or read-only, see \link
+ qtableitem.html#wheneditable TQTableItem::EditType\endlink. If you
+ want fine control over editing see beginEdit() and endEdit().
+
+ The contents of a cell can be retrieved as a TQTableItem using
+ item(), or as a string with text() or as a pixmap (if there is
+ one) with pixmap(). A cell's bounding rectangle is given by
+ cellGeometry(). Use updateCell() to tqrepaint a cell, for example to
+ clear away a cell's visual representation after it has been
+ deleted with clearCell(). The table can be forced to scroll to
+ show a particular cell with ensureCellVisible(). The isSelected()
+ function indicates if a cell is selected.
+
+ It is possible to use your own widget as a cell's widget using
+ setCellWidget(), but subclassing TQTableItem might be a simpler
+ approach. The cell's widget (if there is one) can be removed with
+ clearCellWidget().
+
+ \keyword notes on large tables
+ \target bigtables
+ \section2 Large tables
+
+ For large, sparse, tables using TQTableItems or other widgets is
+ inefficient. The solution is to \e draw the cell as it should
+ appear and to create and destroy cell editors on demand.
+
+ This approach requires that you reimplement various functions.
+ Reimplement paintCell() to display your data, and createEditor()
+ and setCellContentFromEditor() to support in-place editing. It
+ is very important to reimplement resizeData() to have no
+ functionality, to prevent TQTable from attempting to create a huge
+ array. You will also need to reimplement item(), setItem(),
+ takeItem(), clearCell(), and insertWidget(), cellWidget() and
+ clearCellWidget(). In almost every circumstance (for sorting,
+ removing and inserting columns and rows, etc.), you also need
+ to reimplement swapRows(), swapCells() and swapColumns(), including
+ header handling.
+
+ If you represent active cells with a dictionary of TQTableItems and
+ TQWidgets, i.e. only store references to cells that are actually
+ used, many of the functions can be implemented with a single line
+ of code. (See the \l table/bigtable/main.cpp example.)
+
+ For more information on cells see the TQTableItem documenation.
+
+ \target selections
+ \section1 Selections
+
+ TQTable's support single selection, multi-selection (multiple
+ cells) or no selection. The selection mode is set with
+ setSelectionMode(). Use isSelected() to determine if a particular
+ cell is selected, and isRowSelected() and isColumnSelected() to
+ see if a row or column is selected.
+
+ TQTable's support many simultaneous selections. You can
+ programmatically select cells with addSelection(). The number of
+ selections is given by numSelections(). The current selection is
+ returned by currentSelection(). You can remove a selection with
+ removeSelection() and remove all selections with
+ clearSelection(). Selections are TQTableSelection objects.
+
+ To easily add a new selection use selectCells(), selectRow() or
+ selectColumn().
+
+ Alternatively, use addSelection() to add new selections using
+ TQTableSelection objects. The advantage of using TQTableSelection
+ objects is that you can call TQTableSelection::expandTo() to resize
+ the selection and can query and compare them.
+
+ The number of selections is given by numSelections(). The current
+ selection is returned by currentSelection(). You can remove a
+ selection with removeSelection() and remove all selections with
+ clearSelection().
+
+ \target Q_SIGNALS
+ \section1 Signals
+
+ When the user clicks a cell the currentChanged() signal is
+ emitted. You can also connect to the lower level clicked(),
+ doubleClicked() and pressed() Q_SIGNALS. If the user changes the
+ selection the selectionChanged() signal is emitted; similarly if
+ the user changes a cell's value the valueChanged() signal is
+ emitted. If the user right-clicks (or presses the appropriate
+ platform-specific key sequence) the contextMenuRequested() signal
+ is emitted. If the user drops a drag and drop object the dropped()
+ signal is emitted with the drop event.
+*/
+
+/*!
+ \fn void TQTable::currentChanged( int row, int col )
+
+ This signal is emitted when the current cell has changed to \a
+ row, \a col.
+*/
+
+/*!
+ \fn void TQTable::valueChanged( int row, int col )
+
+ This signal is emitted when the user changed the value in the cell
+ at \a row, \a col.
+*/
+
+/*!
+ \fn int TQTable::currentRow() const
+
+ Returns the current row.
+
+ \sa currentColumn()
+*/
+
+/*!
+ \fn int TQTable::currentColumn() const
+
+ Returns the current column.
+
+ \sa currentRow()
+*/
+
+/*!
+ \enum TQTable::EditMode
+
+ \value NotEditing No cell is currently being edited.
+
+ \value Editing A cell is currently being edited. The editor was
+ initialised with the cell's contents.
+
+ \value Replacing A cell is currently being edited. The editor was
+ not initialised with the cell's contents.
+*/
+
+/*!
+ \enum TQTable::SelectionMode
+
+ \value NoSelection No cell can be selected by the user.
+
+ \value Single The user may only select a single range of cells.
+
+ \value Multi The user may select multiple ranges of cells.
+
+ \value SingleRow The user may select one row at once.
+
+ \value MultiRow The user may select multiple rows.
+*/
+
+/*!
+ \enum TQTable::FocusStyle
+
+ Specifies how the current cell (focus cell) is drawn.
+
+ \value FollowStyle The current cell is drawn according to the
+ current style and the cell's background is also drawn selected, if
+ the current cell is within a selection
+
+ \value SpreadSheet The current cell is drawn as in a spreadsheet.
+ This means, it is signified by a black rectangle around the cell,
+ and the background of the current cell is always drawn with the
+ widget's base color - even when selected.
+
+*/
+
+/*!
+ \fn void TQTable::clicked( int row, int col, int button, const TQPoint &mousePos )
+
+ This signal is emitted when mouse button \a button is clicked. The
+ cell where the event took place is at \a row, \a col, and the
+ mouse's position is in \a mousePos.
+
+ \sa TQt::ButtonState
+*/
+
+/*!
+ \fn void TQTable::doubleClicked( int row, int col, int button, const TQPoint &mousePos )
+
+ This signal is emitted when mouse button \a button is
+ double-clicked. The cell where the event took place is at \a row,
+ \a col, and the mouse's position is in \a mousePos.
+
+ \sa TQt::ButtonState
+*/
+
+/*!
+ \fn void TQTable::pressed( int row, int col, int button, const TQPoint &mousePos )
+
+ This signal is emitted when mouse button \a button is pressed. The
+ cell where the event took place is at \a row, \a col, and the
+ mouse's position is in \a mousePos.
+
+ \sa TQt::ButtonState
+*/
+
+/*!
+ \fn void TQTable::selectionChanged()
+
+ This signal is emitted whenever a selection changes.
+
+ \sa TQTableSelection
+*/
+
+/*!
+ \fn void TQTable::contextMenuRequested( int row, int col, const TQPoint & pos )
+
+ This signal is emitted when the user invokes a context menu with
+ the right mouse button (or with a system-specific keypress). The
+ cell where the event took place is at \a row, \a col. \a pos is
+ the position where the context menu will appear in the global
+ coordinate system. This signal is always emitted, even if the
+ contents of the cell are disabled.
+*/
+
+/*!
+ Creates an empty table object called \a name as a child of \a
+ tqparent.
+
+ Call setNumRows() and setNumCols() to set the table size before
+ populating the table if you're using TQTableItems.
+
+ \sa TQWidget::clearWFlags() TQt::WidgetFlags
+*/
+
+TQTable::TQTable( TQWidget *tqparent, const char *name )
+ : TQScrollView( tqparent, name, (WFlags)(WNoAutoErase | TQt::WStaticContents) ),
+ leftHeader( 0 ), topHeader( 0 ),
+ currentSel( 0 ), lastSortCol( -1 ), sGrid( TRUE ), mRows( FALSE ), mCols( FALSE ),
+ asc( TRUE ), doSort( TRUE ), readOnly( FALSE )
+{
+ init( 0, 0 );
+}
+
+/*!
+ Constructs an empty table called \a name with \a numRows rows and
+ \a numCols columns. The table is a child of \a tqparent.
+
+ If you're using \l{TQTableItem}s to populate the table's cells, you
+ can create TQTableItem, TQComboTableItem and TQCheckTableItem items
+ and insert them into the table using setItem(). (See the notes on
+ large tables for an alternative to using TQTableItems.)
+
+ \sa TQWidget::clearWFlags() TQt::WidgetFlags
+*/
+
+TQTable::TQTable( int numRows, int numCols, TQWidget *tqparent, const char *name )
+ : TQScrollView( tqparent, name, (WFlags)(WNoAutoErase | TQt::WStaticContents) ),
+ leftHeader( 0 ), topHeader( 0 ),
+ currentSel( 0 ), lastSortCol( -1 ), sGrid( TRUE ), mRows( FALSE ), mCols( FALSE ),
+ asc( TRUE ), doSort( TRUE ), readOnly( FALSE )
+{
+ init( numRows, numCols );
+}
+
+/*! \internal
+*/
+
+void TQTable::init( int rows, int cols )
+{
+#ifndef TQT_NO_DRAGANDDROP
+ setDragAutoScroll( FALSE );
+#endif
+ d = new TQTablePrivate;
+ d->geomTimer = new TQTimer( this );
+ d->lastVisCol = 0;
+ d->lastVisRow = 0;
+ connect( d->geomTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( updateGeometriesSlot() ) );
+ shouldClearSelection = FALSE;
+ dEnabled = FALSE;
+ roRows.setAutoDelete( TRUE );
+ roCols.setAutoDelete( TRUE );
+ setSorting( FALSE );
+
+ unused = TRUE; // It's unused, ain't it? :)
+
+ selMode = Multi;
+
+ contents.setAutoDelete( TRUE );
+ widgets.setAutoDelete( TRUE );
+
+ // Enable clipper and set background mode
+ enableClipper( qt_table_clipper_enabled );
+
+ viewport()->setFocusProxy( this );
+ viewport()->setFocusPolicy( Qt::WheelFocus );
+
+ viewport()->setBackgroundMode( TQt::PaletteBase );
+ setBackgroundMode( TQt::PaletteBackground, TQt::PaletteBase );
+ setResizePolicy( Manual );
+ selections.setAutoDelete( TRUE );
+
+ // Create headers
+ leftHeader = new TQTableHeader( rows, this, this, "left table header" );
+ leftHeader->setOrientation( Qt::Vertical );
+ leftHeader->setTracking( TRUE );
+ leftHeader->setMovingEnabled( TRUE );
+ topHeader = new TQTableHeader( cols, this, this, "right table header" );
+ topHeader->setOrientation( Qt::Horizontal );
+ topHeader->setTracking( TRUE );
+ topHeader->setMovingEnabled( TRUE );
+ if ( TQApplication::reverseLayout() )
+ setMargins( 0, fontMetrics().height() + 4, 30, 0 );
+ else
+ setMargins( 30, fontMetrics().height() + 4, 0, 0 );
+
+ topHeader->setUpdatesEnabled( FALSE );
+ leftHeader->setUpdatesEnabled( FALSE );
+ // Initialize headers
+ int i = 0;
+ for ( i = 0; i < numCols(); ++i )
+ topHeader->resizeSection( i, TQMAX( 100, TQApplication::globalStrut().height() ) );
+ for ( i = 0; i < numRows(); ++i )
+ leftHeader->resizeSection( i, TQMAX( 20, TQApplication::globalStrut().width() ) );
+ topHeader->setUpdatesEnabled( TRUE );
+ leftHeader->setUpdatesEnabled( TRUE );
+
+ // Prepare for contents
+ contents.setAutoDelete( FALSE );
+
+ // Connect header, table and scrollbars
+ connect( horizontalScrollBar(), TQT_SIGNAL( valueChanged(int) ),
+ topHeader, TQT_SLOT( setOffset(int) ) );
+ connect( verticalScrollBar(), TQT_SIGNAL( valueChanged(int) ),
+ leftHeader, TQT_SLOT( setOffset(int) ) );
+ connect( topHeader, TQT_SIGNAL( sectionSizeChanged(int) ),
+ this, TQT_SLOT( columnWidthChanged(int) ) );
+ connect( topHeader, TQT_SIGNAL( indexChange(int,int,int) ),
+ this, TQT_SLOT( columnIndexChanged(int,int,int) ) );
+ connect( topHeader, TQT_SIGNAL( sectionClicked(int) ),
+ this, TQT_SLOT( columnClicked(int) ) );
+ connect( leftHeader, TQT_SIGNAL( sectionSizeChanged(int) ),
+ this, TQT_SLOT( rowHeightChanged(int) ) );
+ connect( leftHeader, TQT_SIGNAL( indexChange(int,int,int) ),
+ this, TQT_SLOT( rowIndexChanged(int,int,int) ) );
+
+ // Initialize variables
+ autoScrollTimer = new TQTimer( this );
+ connect( autoScrollTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( doAutoScroll() ) );
+ curRow = curCol = 0;
+ topHeader->setSectionState( curCol, TQTableHeader::Bold );
+ leftHeader->setSectionState( curRow, TQTableHeader::Bold );
+ edMode = NotEditing;
+ editRow = editCol = -1;
+
+ drawActiveSelection = TRUE;
+
+ installEventFilter( this );
+
+ focusStl = SpreadSheet;
+
+ was_visible = FALSE;
+
+ // initial size
+ resize( 640, 480 );
+}
+
+/*!
+ Releases all the resources used by the TQTable object,
+ including all \l{TQTableItem}s and their widgets.
+*/
+
+TQTable::~TQTable()
+{
+ setUpdatesEnabled( FALSE );
+ contents.setAutoDelete( TRUE );
+ contents.clear();
+ widgets.clear();
+
+ delete d;
+}
+
+void TQTable::setReadOnly( bool b )
+{
+ readOnly = b;
+
+ TQTableItem *i = item(curRow, curCol);
+ if (readOnly && isEditing()) {
+ endEdit(editRow, editCol, TRUE, FALSE);
+ } else if (!readOnly && i && (i->editType() == TQTableItem::WhenCurrent
+ || i->editType() == TQTableItem::Always)) {
+ editCell(curRow, curCol);
+ }
+}
+
+/*!
+ If \a ro is TRUE, row \a row is set to be read-only; otherwise the
+ row is set to be editable.
+
+ Whether a cell in this row is editable or read-only depends on the
+ cell's EditType, and this setting:
+ see \link qtableitem.html#wheneditable TQTableItem::EditType\endlink.
+
+ \sa isRowReadOnly() setColumnReadOnly() setReadOnly()
+*/
+
+void TQTable::setRowReadOnly( int row, bool ro )
+{
+ if ( ro )
+ roRows.tqreplace( row, new int( 0 ) );
+ else
+ roRows.remove( row );
+
+ if (curRow == row) {
+ TQTableItem *i = item(curRow, curCol);
+ if (ro && isEditing()) {
+ endEdit(editRow, editCol, TRUE, FALSE);
+ } else if (!ro && i && (i->editType() == TQTableItem::WhenCurrent
+ || i->editType() == TQTableItem::Always)) {
+ editCell(curRow, curCol);
+ }
+ }
+}
+
+/*!
+ If \a ro is TRUE, column \a col is set to be read-only; otherwise
+ the column is set to be editable.
+
+ Whether a cell in this column is editable or read-only depends on
+ the cell's EditType, and this setting:
+ see \link qtableitem.html#wheneditable TQTableItem::EditType\endlink.
+
+ \sa isColumnReadOnly() setRowReadOnly() setReadOnly()
+
+*/
+
+void TQTable::setColumnReadOnly( int col, bool ro )
+{
+ if ( ro )
+ roCols.tqreplace( col, new int( 0 ) );
+ else
+ roCols.remove( col );
+
+ if (curCol == col) {
+ TQTableItem *i = item(curRow, curCol);
+ if (ro && isEditing()) {
+ endEdit(editRow, editCol, TRUE, FALSE);
+ } else if (!ro && i && (i->editType() == TQTableItem::WhenCurrent
+ || i->editType() == TQTableItem::Always)) {
+ editCell(curRow, curCol);
+ }
+ }
+}
+
+/*!
+ \property TQTable::readOnly
+ \brief whether the table is read-only
+
+ Whether a cell in the table is editable or read-only depends on
+ the cell's \link TQTableItem::EditType EditType\endlink, and this setting:
+ see \link qtableitem.html#wheneditable
+ TQTableItem::EditType\endlink.
+
+ \sa TQWidget::enabled setColumnReadOnly() setRowReadOnly()
+*/
+
+bool TQTable::isReadOnly() const
+{
+ return readOnly;
+}
+
+/*!
+ Returns TRUE if row \a row is read-only; otherwise returns FALSE.
+
+ Whether a cell in this row is editable or read-only depends on the
+ cell's \link TQTableItem::EditType EditType\endlink, and this
+ setting: see \link qtableitem.html#wheneditable
+ TQTableItem::EditType\endlink.
+
+ \sa setRowReadOnly() isColumnReadOnly()
+*/
+
+bool TQTable::isRowReadOnly( int row ) const
+{
+ return (roRows.tqfind( row ) != 0);
+}
+
+/*!
+ Returns TRUE if column \a col is read-only; otherwise returns
+ FALSE.
+
+ Whether a cell in this column is editable or read-only depends on
+ the cell's EditType, and this setting: see \link
+ qtableitem.html#wheneditable TQTableItem::EditType\endlink.
+
+ \sa setColumnReadOnly() isRowReadOnly()
+*/
+
+bool TQTable::isColumnReadOnly( int col ) const
+{
+ return (roCols.tqfind( col ) != 0);
+}
+
+void TQTable::setSelectionMode( SelectionMode mode )
+{
+ if ( mode == selMode )
+ return;
+ selMode = mode;
+ clearSelection();
+ if ( isRowSelection( selMode ) && numRows() > 0 && numCols() > 0 ) {
+ currentSel = new TQTableSelection();
+ selections.append( currentSel );
+ currentSel->init( curRow, 0 );
+ currentSel->expandTo( curRow, numCols() - 1 );
+ repaintSelections( 0, currentSel );
+ }
+}
+
+/*!
+ \property TQTable::selectionMode
+ \brief the current selection mode
+
+ The default mode is \c Multi which allows the user to select
+ multiple ranges of cells.
+
+ \sa SelectionMode setSelectionMode()
+*/
+
+TQTable::SelectionMode TQTable::selectionMode() const
+{
+ return selMode;
+}
+
+/*!
+ \property TQTable::focusStyle
+ \brief how the current (focus) cell is drawn
+
+ The default style is \c SpreadSheet.
+
+ \sa TQTable::FocusStyle
+*/
+
+void TQTable::setFocusStyle( FocusStyle fs )
+{
+ focusStl = fs;
+ updateCell( curRow, curCol );
+}
+
+TQTable::FocusStyle TQTable::focusStyle() const
+{
+ return focusStl;
+}
+
+/*!
+ This functions updates all the header states to be in sync with
+ the current selections. This should be called after
+ programatically changing, adding or removing selections, so that
+ the headers are updated.
+*/
+
+void TQTable::updateHeaderStates()
+{
+ horizontalHeader()->setUpdatesEnabled( FALSE );
+ verticalHeader()->setUpdatesEnabled( FALSE );
+
+ ( (TQTableHeader*)verticalHeader() )->setSectionStateToAll( TQTableHeader::Normal );
+ ( (TQTableHeader*)horizontalHeader() )->setSectionStateToAll( TQTableHeader::Normal );
+
+ TQPtrListIterator<TQTableSelection> it( selections );
+ TQTableSelection *s;
+ while ( ( s = it.current() ) != 0 ) {
+ ++it;
+ if ( s->isActive() ) {
+ if ( s->leftCol() == 0 &&
+ s->rightCol() == numCols() - 1 ) {
+ for ( int i = 0; i < s->bottomRow() - s->topRow() + 1; ++i )
+ leftHeader->setSectionState( s->topRow() + i, TQTableHeader::Selected );
+ }
+ if ( s->topRow() == 0 &&
+ s->bottomRow() == numRows() - 1 ) {
+ for ( int i = 0; i < s->rightCol() - s->leftCol() + 1; ++i )
+ topHeader->setSectionState( s->leftCol() + i, TQTableHeader::Selected );
+ }
+ }
+ }
+
+ horizontalHeader()->setUpdatesEnabled( TRUE );
+ verticalHeader()->setUpdatesEnabled( TRUE );
+ horizontalHeader()->tqrepaint( FALSE );
+ verticalHeader()->tqrepaint( FALSE );
+}
+
+/*!
+ Returns the table's top TQHeader.
+
+ This header tqcontains the column labels.
+
+ To modify a column label use TQHeader::setLabel(), e.g.
+ \quotefile table/statistics/statistics.cpp
+ \skipto horizontalHeader
+ \printline
+
+ \sa verticalHeader() setTopMargin() TQHeader
+*/
+
+TQHeader *TQTable::horizontalHeader() const
+{
+ return (TQHeader*)topHeader;
+}
+
+/*!
+ Returns the table's vertical TQHeader.
+
+ This header tqcontains the row labels.
+
+ \sa horizontalHeader() setLeftMargin() TQHeader
+*/
+
+TQHeader *TQTable::verticalHeader() const
+{
+ return (TQHeader*)leftHeader;
+}
+
+void TQTable::setShowGrid( bool b )
+{
+ if ( sGrid == b )
+ return;
+ sGrid = b;
+ updateContents();
+}
+
+/*!
+ \property TQTable::showGrid
+ \brief whether the table's grid is displayed
+
+ The grid is shown by default.
+*/
+
+bool TQTable::showGrid() const
+{
+ return sGrid;
+}
+
+/*!
+ \property TQTable::columnMovingEnabled
+ \brief whether columns can be moved by the user
+
+ The default is FALSE. Columns are moved by dragging whilst holding
+ down the Ctrl key.
+
+ \warning If TQTable is used to move header sections as a result of user
+ interaction, the mapping between header indexes and section exposed by
+ TQHeader will not reflect the order of the headers in the table; i.e.,
+ TQTable does not call TQHeader::moveSection() to move sections but handles
+ move operations internally.
+
+ \sa rowMovingEnabled
+*/
+
+void TQTable::setColumnMovingEnabled( bool b )
+{
+ mCols = b;
+}
+
+bool TQTable::columnMovingEnabled() const
+{
+ return mCols;
+}
+
+/*!
+ \property TQTable::rowMovingEnabled
+ \brief whether rows can be moved by the user
+
+ The default is FALSE. Rows are moved by dragging whilst holding
+ down the Ctrl key.
+
+ \warning If TQTable is used to move header sections as a result of user
+ interaction, the mapping between header indexes and section exposed by
+ TQHeader will not reflect the order of the headers in the table; i.e.,
+ TQTable does not call TQHeader::moveSection() to move sections but handles
+ move operations internally.
+
+ \sa columnMovingEnabled
+*/
+
+void TQTable::setRowMovingEnabled( bool b )
+{
+ mRows = b;
+}
+
+bool TQTable::rowMovingEnabled() const
+{
+ return mRows;
+}
+
+/*!
+ This is called when TQTable's internal array needs to be resized to
+ \a len elements.
+
+ If you don't use TQTableItems you should reimplement this as an
+ empty method to avoid wasting memory. See the notes on large
+ tables for further details.
+*/
+
+void TQTable::resizeData( int len )
+{
+ contents.resize( len );
+ widgets.resize( len );
+}
+
+/*!
+ Swaps the data in \a row1 and \a row2.
+
+ This function is used to swap the positions of two rows. It is
+ called when the user changes the order of rows (see
+ setRowMovingEnabled()), and when rows are sorted.
+
+ If you don't use \l{TQTableItem}s and want your users to be able to
+ swap rows, e.g. for sorting, you will need to reimplement this
+ function. (See the notes on large tables.)
+
+ If \a swapHeader is TRUE, the rows' header contents is also
+ swapped.
+
+ This function will not update the TQTable, you will have to do
+ this manually, e.g. by calling updateContents().
+
+ \sa swapColumns() swapCells()
+*/
+
+void TQTable::swapRows( int row1, int row2, bool swapHeader )
+{
+ if ( swapHeader )
+ leftHeader->swapSections( row1, row2, FALSE );
+
+ TQPtrVector<TQTableItem> tmpContents;
+ tmpContents.resize( numCols() );
+ TQPtrVector<TQWidget> tmpWidgets;
+ tmpWidgets.resize( numCols() );
+ int i;
+
+ contents.setAutoDelete( FALSE );
+ widgets.setAutoDelete( FALSE );
+ for ( i = 0; i < numCols(); ++i ) {
+ TQTableItem *i1, *i2;
+ i1 = item( row1, i );
+ i2 = item( row2, i );
+ if ( i1 || i2 ) {
+ tmpContents.insert( i, i1 );
+ contents.remove( indexOf( row1, i ) );
+ contents.insert( indexOf( row1, i ), i2 );
+ contents.remove( indexOf( row2, i ) );
+ contents.insert( indexOf( row2, i ), tmpContents[ i ] );
+ if ( contents[ indexOf( row1, i ) ] )
+ contents[ indexOf( row1, i ) ]->setRow( row1 );
+ if ( contents[ indexOf( row2, i ) ] )
+ contents[ indexOf( row2, i ) ]->setRow( row2 );
+ }
+
+ TQWidget *w1, *w2;
+ w1 = cellWidget( row1, i );
+ w2 = cellWidget( row2, i );
+ if ( w1 || w2 ) {
+ tmpWidgets.insert( i, w1 );
+ widgets.remove( indexOf( row1, i ) );
+ widgets.insert( indexOf( row1, i ), w2 );
+ widgets.remove( indexOf( row2, i ) );
+ widgets.insert( indexOf( row2, i ), tmpWidgets[ i ] );
+ }
+ }
+ contents.setAutoDelete( FALSE );
+ widgets.setAutoDelete( TRUE );
+
+ updateRowWidgets( row1 );
+ updateRowWidgets( row2 );
+ if ( curRow == row1 )
+ curRow = row2;
+ else if ( curRow == row2 )
+ curRow = row1;
+ if ( editRow == row1 )
+ editRow = row2;
+ else if ( editRow == row2 )
+ editRow = row1;
+}
+
+/*!
+ Sets the left margin to be \a m pixels wide.
+
+ The verticalHeader(), which displays row labels, occupies this
+ margin.
+
+ In an Arabic or Hebrew localization, the verticalHeader() will
+ appear on the right side of the table, and this call will set the
+ right margin.
+
+ \sa leftMargin() setTopMargin() verticalHeader()
+*/
+
+void TQTable::setLeftMargin( int m )
+{
+ if ( TQApplication::reverseLayout() )
+ setMargins( leftMargin(), topMargin(), m, bottomMargin() );
+ else
+ setMargins( m, topMargin(), rightMargin(), bottomMargin() );
+ updateGeometries();
+}
+
+/*!
+ Sets the top margin to be \a m pixels high.
+
+ The horizontalHeader(), which displays column labels, occupies
+ this margin.
+
+ \sa topMargin() setLeftMargin()
+*/
+
+void TQTable::setTopMargin( int m )
+{
+ setMargins( leftMargin(), m, rightMargin(), bottomMargin() );
+ updateGeometries();
+}
+
+/*!
+ Swaps the data in \a col1 with \a col2.
+
+ This function is used to swap the positions of two columns. It is
+ called when the user changes the order of columns (see
+ setColumnMovingEnabled(), and when columns are sorted.
+
+ If you don't use \l{TQTableItem}s and want your users to be able to
+ swap columns you will need to reimplement this function. (See the
+ notes on large tables.)
+
+ If \a swapHeader is TRUE, the columns' header contents is also
+ swapped.
+
+ \sa swapCells()
+*/
+
+void TQTable::swapColumns( int col1, int col2, bool swapHeader )
+{
+ if ( swapHeader )
+ topHeader->swapSections( col1, col2, FALSE );
+
+ TQPtrVector<TQTableItem> tmpContents;
+ tmpContents.resize( numRows() );
+ TQPtrVector<TQWidget> tmpWidgets;
+ tmpWidgets.resize( numRows() );
+ int i;
+
+ contents.setAutoDelete( FALSE );
+ widgets.setAutoDelete( FALSE );
+ for ( i = 0; i < numRows(); ++i ) {
+ TQTableItem *i1, *i2;
+ i1 = item( i, col1 );
+ i2 = item( i, col2 );
+ if ( i1 || i2 ) {
+ tmpContents.insert( i, i1 );
+ contents.remove( indexOf( i, col1 ) );
+ contents.insert( indexOf( i, col1 ), i2 );
+ contents.remove( indexOf( i, col2 ) );
+ contents.insert( indexOf( i, col2 ), tmpContents[ i ] );
+ if ( contents[ indexOf( i, col1 ) ] )
+ contents[ indexOf( i, col1 ) ]->setCol( col1 );
+ if ( contents[ indexOf( i, col2 ) ] )
+ contents[ indexOf( i, col2 ) ]->setCol( col2 );
+ }
+
+ TQWidget *w1, *w2;
+ w1 = cellWidget( i, col1 );
+ w2 = cellWidget( i, col2 );
+ if ( w1 || w2 ) {
+ tmpWidgets.insert( i, w1 );
+ widgets.remove( indexOf( i, col1 ) );
+ widgets.insert( indexOf( i, col1 ), w2 );
+ widgets.remove( indexOf( i, col2 ) );
+ widgets.insert( indexOf( i, col2 ), tmpWidgets[ i ] );
+ }
+ }
+ contents.setAutoDelete( FALSE );
+ widgets.setAutoDelete( TRUE );
+
+ columnWidthChanged( col1 );
+ columnWidthChanged( col2 );
+ if ( curCol == col1 )
+ curCol = col2;
+ else if ( curCol == col2 )
+ curCol = col1;
+ if ( editCol == col1 )
+ editCol = col2;
+ else if ( editCol == col2 )
+ editCol = col1;
+}
+
+/*!
+ Swaps the contents of the cell at \a row1, \a col1 with the
+ contents of the cell at \a row2, \a col2.
+
+ This function is also called when the table is sorted.
+
+ If you don't use \l{TQTableItem}s and want your users to be able to
+ swap cells, you will need to reimplement this function. (See the
+ notes on large tables.)
+
+ \sa swapColumns() swapRows()
+*/
+
+void TQTable::swapCells( int row1, int col1, int row2, int col2 )
+{
+ contents.setAutoDelete( FALSE );
+ widgets.setAutoDelete( FALSE );
+ TQTableItem *i1, *i2;
+ i1 = item( row1, col1 );
+ i2 = item( row2, col2 );
+ if ( i1 || i2 ) {
+ TQTableItem *tmp = i1;
+ contents.remove( indexOf( row1, col1 ) );
+ contents.insert( indexOf( row1, col1 ), i2 );
+ contents.remove( indexOf( row2, col2 ) );
+ contents.insert( indexOf( row2, col2 ), tmp );
+ if ( contents[ indexOf( row1, col1 ) ] ) {
+ contents[ indexOf( row1, col1 ) ]->setRow( row1 );
+ contents[ indexOf( row1, col1 ) ]->setCol( col1 );
+ }
+ if ( contents[ indexOf( row2, col2 ) ] ) {
+ contents[ indexOf( row2, col2 ) ]->setRow( row2 );
+ contents[ indexOf( row2, col2 ) ]->setCol( col2 );
+ }
+ }
+
+ TQWidget *w1, *w2;
+ w1 = cellWidget( row1, col1 );
+ w2 = cellWidget( row2, col2 );
+ if ( w1 || w2 ) {
+ TQWidget *tmp = w1;
+ widgets.remove( indexOf( row1, col1 ) );
+ widgets.insert( indexOf( row1, col1 ), w2 );
+ widgets.remove( indexOf( row2, col2 ) );
+ widgets.insert( indexOf( row2, col2 ), tmp );
+ }
+
+ updateRowWidgets( row1 );
+ updateRowWidgets( row2 );
+ updateColWidgets( col1 );
+ updateColWidgets( col2 );
+ contents.setAutoDelete( FALSE );
+ widgets.setAutoDelete( TRUE );
+}
+
+static bool is_child_of( TQWidget *child, TQWidget *tqparent )
+{
+ while ( child ) {
+ if ( child == tqparent )
+ return TRUE;
+ child = child->parentWidget();
+ }
+ return FALSE;
+}
+
+/*!
+ Draws the table contents on the painter \a p. This function is
+ optimized so that it only draws the cells inside the \a cw pixels
+ wide and \a ch pixels high clipping rectangle at position \a cx,
+ \a cy.
+
+ Additionally, drawContents() highlights the current cell.
+*/
+
+void TQTable::drawContents( TQPainter *p, int cx, int cy, int cw, int ch )
+{
+ int colfirst = columnAt( cx );
+ int collast = columnAt( cx + cw );
+ int rowfirst = rowAt( cy );
+ int rowlast = rowAt( cy + ch );
+
+ if ( rowfirst == -1 || colfirst == -1 ) {
+ paintEmptyArea( p, cx, cy, cw, ch );
+ return;
+ }
+
+ drawActiveSelection = hasFocus() || viewport()->hasFocus() || d->inMenuMode
+ || is_child_of( tqApp->tqfocusWidget(), viewport() )
+ || !tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this );
+ if ( rowlast == -1 )
+ rowlast = numRows() - 1;
+ if ( collast == -1 )
+ collast = numCols() - 1;
+
+ bool currentInSelection = FALSE;
+
+ TQPtrListIterator<TQTableSelection> it( selections );
+ TQTableSelection *s;
+ while ( ( s = it.current() ) != 0 ) {
+ ++it;
+ if ( s->isActive() &&
+ curRow >= s->topRow() &&
+ curRow <= s->bottomRow() &&
+ curCol >= s->leftCol() &&
+ curCol <= s->rightCol() ) {
+ currentInSelection = s->topRow() != curRow || s->bottomRow() != curRow || s->leftCol() != curCol || s->rightCol() != curCol;
+ break;
+ }
+ }
+
+ // Go through the rows
+ for ( int r = rowfirst; r <= rowlast; ++r ) {
+ // get row position and height
+ int rowp = rowPos( r );
+ int rowh = rowHeight( r );
+
+ // Go through the columns in row r
+ // if we know from where to where, go through [colfirst, collast],
+ // else go through all of them
+ for ( int c = colfirst; c <= collast; ++c ) {
+ // get position and width of column c
+ int colp, colw;
+ colp = columnPos( c );
+ colw = columnWidth( c );
+ int oldrp = rowp;
+ int oldrh = rowh;
+
+ TQTableItem *itm = item( r, c );
+ if ( itm &&
+ ( itm->colSpan() > 1 || itm->rowSpan() > 1 ) ) {
+ bool goon = (r == itm->row() && c == itm->col()) ||
+ (r == rowfirst && c == itm->col()) ||
+ (r == itm->row() && c == colfirst);
+ if ( !goon )
+ continue;
+ rowp = rowPos( itm->row() );
+ rowh = 0;
+ int i;
+ for ( i = 0; i < itm->rowSpan(); ++i )
+ rowh += rowHeight( i + itm->row() );
+ colp = columnPos( itm->col() );
+ colw = 0;
+ for ( i = 0; i < itm->colSpan(); ++i )
+ colw += columnWidth( i + itm->col() );
+ }
+
+ // Translate painter and draw the cell
+ p->translate( colp, rowp );
+ bool selected = isSelected( r, c );
+ if ( focusStl != FollowStyle && selected && !currentInSelection &&
+ r == curRow && c == curCol )
+ selected = FALSE;
+ paintCell( p, r, c, TQRect( colp, rowp, colw, rowh ), selected );
+ p->translate( -colp, -rowp );
+
+ rowp = oldrp;
+ rowh = oldrh;
+
+ TQWidget *w = cellWidget( r, c );
+ TQRect cg( cellGeometry( r, c ) );
+ if ( w && w->tqgeometry() != TQRect( contentsToViewport( cg.topLeft() ), cg.size() - TQSize( 1, 1 ) ) ) {
+ moveChild( w, colp, rowp );
+ w->resize( cg.size() - TQSize( 1, 1 ) );
+ }
+ }
+ }
+ d->lastVisCol = collast;
+ d->lastVisRow = rowlast;
+
+ // draw indication of current cell
+ TQRect focusRect = cellGeometry( curRow, curCol );
+ p->translate( focusRect.x(), focusRect.y() );
+ paintFocus( p, focusRect );
+ p->translate( -focusRect.x(), -focusRect.y() );
+
+ // Paint empty rects
+ paintEmptyArea( p, cx, cy, cw, ch );
+
+ drawActiveSelection = TRUE;
+}
+
+/*!
+ \reimp
+
+ (Implemented to get rid of a compiler warning.)
+*/
+
+void TQTable::drawContents( TQPainter * )
+{
+}
+
+/*!
+ Returns the tqgeometry of cell \a row, \a col in the cell's
+ coordinate system. This is a convenience function useful in
+ paintCell(). It is equivalent to TQRect( TQPoint(0,0), cellGeometry(
+ row, col).size() );
+
+ \sa cellGeometry()
+*/
+
+TQRect TQTable::cellRect( int row, int col ) const
+{
+ return TQRect( TQPoint(0,0), cellGeometry( row, col ).size() );
+}
+
+/*!
+ \overload
+
+ Use the other paintCell() function. This function is only included
+ for backwards compatibilty.
+*/
+
+void TQTable::paintCell( TQPainter* p, int row, int col,
+ const TQRect &cr, bool selected )
+{
+ if ( cr.width() == 0 || cr.height() == 0 )
+ return;
+#if defined(TQ_WS_WIN)
+ const TQColorGroup &cg = ( !drawActiveSelection && tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus ) ? tqpalette().inactive() : tqcolorGroup() );
+#else
+ const TQColorGroup &cg = tqcolorGroup();
+#endif
+
+ TQTableItem *itm = item( row, col );
+ TQColorGroup cg2( cg );
+ if ( itm && !itm->isEnabled() )
+ cg2 = tqpalette().disabled();
+
+ paintCell( p, row, col, cr, selected, cg2 );
+}
+
+/*!
+ Paints the cell at \a row, \a col on the painter \a p. The painter
+ has already been translated to the cell's origin. \a cr describes
+ the cell coordinates in the content coordinate system.
+
+ If \a selected is TRUE the cell is highlighted.
+
+ \a cg is the colorgroup which should be used to draw the cell
+ content.
+
+ If you want to draw custom cell content, for example right-aligned
+ text, you must either reimplement paintCell(), or subclass
+ TQTableItem and reimplement TQTableItem::paint() to do the custom
+ drawing.
+
+ If you're using a TQTableItem subclass, for example, to store a
+ data structure, then reimplementing TQTableItem::paint() may be the
+ best approach. For data you want to draw immediately, e.g. data
+ retrieved from a database, it is probably best to reimplement
+ paintCell(). Note that if you reimplement paintCell(), i.e. don't
+ use \l{TQTableItem}s, you must reimplement other functions: see the
+ notes on large tables.
+
+ Note that the painter is not clipped by default in order to get
+ maximum efficiency. If you want clipping, use code like this:
+
+ \code
+ p->setClipRect( cellRect(row, col), TQPainter::CoordPainter );
+ //... your drawing code
+ p->setClipping( FALSE );
+ \endcode
+*/
+
+void TQTable::paintCell( TQPainter *p, int row, int col,
+ const TQRect &cr, bool selected, const TQColorGroup &cg )
+{
+ if ( focusStl == SpreadSheet && selected &&
+ row == curRow &&
+ col == curCol && ( hasFocus() || viewport()->hasFocus() ) )
+ selected = FALSE;
+
+ int w = cr.width();
+ int h = cr.height();
+ int x2 = w - 1;
+ int y2 = h - 1;
+
+
+ TQTableItem *itm = item( row, col );
+ if ( itm ) {
+ p->save();
+ itm->paint( p, cg, cr, selected );
+ p->restore();
+ } else {
+ p->fillRect( 0, 0, w, h, selected ? cg.brush( TQColorGroup::Highlight ) : cg.brush( TQColorGroup::Base ) );
+ }
+
+ if ( sGrid ) {
+ // Draw our lines
+ TQPen pen( p->pen() );
+ int gridColor = tqstyle().tqstyleHint( TQStyle::SH_Table_GridLineColor, this );
+ if (gridColor != -1) {
+ const TQPalette &pal = tqpalette();
+ if (cg != tqcolorGroup()
+ && cg != pal.disabled()
+ && cg != pal.inactive())
+ p->setPen(cg.mid());
+ else
+ p->setPen((TQRgb)gridColor);
+ } else {
+ p->setPen(cg.mid());
+ }
+ p->drawLine( x2, 0, x2, y2 );
+ p->drawLine( 0, y2, x2, y2 );
+ p->setPen( pen );
+ }
+}
+
+/*!
+ Draws the focus rectangle of the current cell (see currentRow(),
+ currentColumn()).
+
+ The painter \a p is already translated to the cell's origin, while
+ \a cr specifies the cell's tqgeometry in content coordinates.
+*/
+
+void TQTable::paintFocus( TQPainter *p, const TQRect &cr )
+{
+ if ( !hasFocus() && !viewport()->hasFocus() )
+ return;
+ TQRect focusRect( 0, 0, cr.width(), cr.height() );
+ if ( focusStyle() == SpreadSheet ) {
+ p->setPen( TQPen( Qt::black, 1 ) );
+ p->setBrush( Qt::NoBrush );
+ p->drawRect( focusRect.x(), focusRect.y(), focusRect.width() - 1, focusRect.height() - 1 );
+ p->drawRect( focusRect.x() - 1, focusRect.y() - 1, focusRect.width() + 1, focusRect.height() + 1 );
+ } else {
+ TQColor c = isSelected( curRow, curCol, FALSE ) ?
+ tqcolorGroup().highlight() : tqcolorGroup().base();
+ tqstyle().tqdrawPrimitive( TQStyle::PE_FocusRect, p, focusRect, tqcolorGroup(),
+ ( isSelected( curRow, curCol, FALSE ) ?
+ TQStyle::Style_FocusAtBorder :
+ TQStyle::Style_Default ),
+ TQStyleOption(c) );
+ }
+}
+
+/*!
+ This function fills the \a cw pixels wide and \a ch pixels high
+ rectangle starting at position \a cx, \a cy with the background
+ color using the painter \a p.
+
+ paintEmptyArea() is invoked by drawContents() to erase or fill
+ unused areas.
+*/
+
+void TQTable::paintEmptyArea( TQPainter *p, int cx, int cy, int cw, int ch )
+{
+ // Regions work with shorts, so avoid an overflow and adjust the
+ // table size to the visible size
+ TQSize ts( tableSize() );
+ ts.setWidth( TQMIN( ts.width(), visibleWidth() ) );
+ ts.setHeight( TQMIN( ts.height(), visibleHeight() ) );
+
+ // Region of the rect we should draw, calculated in viewport
+ // coordinates, as a region can't handle bigger coordinates
+ contentsToViewport2( cx, cy, cx, cy );
+ TQRegion reg( TQRect( cx, cy, cw, ch ) );
+
+ // Subtract the table from it
+ reg = reg.subtract( TQRect( TQPoint( 0, 0 ), ts ) );
+
+ // And draw the rectangles (transformed inc contents coordinates as needed)
+ TQMemArray<TQRect> r = reg.tqrects();
+ for ( int i = 0; i < (int)r.count(); ++i )
+ p->fillRect( TQRect(viewportToContents2(r[i].topLeft()),r[i].size()), viewport()->backgroundBrush() );
+}
+
+/*!
+ Returns the TQTableItem representing the contents of the cell at \a
+ row, \a col.
+
+ If \a row or \a col are out of range or no content has been set
+ for this cell, item() returns 0.
+
+ If you don't use \l{TQTableItem}s you may need to reimplement this
+ function: see the notes on large tables.
+
+ \sa setItem()
+*/
+
+TQTableItem *TQTable::item( int row, int col ) const
+{
+ if ( row < 0 || col < 0 || row > numRows() - 1 ||
+ col > numCols() - 1 || row * col >= (int)contents.size() )
+ return 0;
+
+ return contents[ indexOf( row, col ) ]; // contents array lookup
+}
+
+/*!
+ Inserts the table item \a item into the table at row \a row,
+ column \a col, and repaints the cell. If a table item already
+ exists in this cell it is deleted and tqreplaced with \a item. The
+ table takes ownership of the table item.
+
+ If you don't use \l{TQTableItem}s you may need to reimplement this
+ function: see the notes on large tables.
+
+ \sa item() takeItem()
+*/
+
+void TQTable::setItem( int row, int col, TQTableItem *item )
+{
+ if ( !item )
+ return;
+
+ if ( (int)contents.size() != numRows() * numCols() )
+ resizeData( numRows() * numCols() );
+
+ int orow = item->row();
+ int ocol = item->col();
+ clearCell( row, col );
+
+ contents.insert( indexOf( row, col ), item );
+ item->setRow( row );
+ item->setCol( col );
+ item->t = this;
+ updateCell( row, col );
+ if ( qt_update_cell_widget )
+ item->updateEditor( orow, ocol );
+
+ if ( row == curRow && col == curCol && item->editType() == TQTableItem::WhenCurrent ) {
+ if ( beginEdit( row, col, FALSE ) )
+ setEditMode( Editing, row, col );
+ }
+}
+
+/*!
+ Removes the TQTableItem at \a row, \a col.
+
+ If you don't use \l{TQTableItem}s you may need to reimplement this
+ function: see the notes on large tables.
+*/
+
+void TQTable::clearCell( int row, int col )
+{
+ if ( (int)contents.size() != numRows() * numCols() )
+ resizeData( numRows() * numCols() );
+ clearCellWidget( row, col );
+ contents.setAutoDelete( TRUE );
+ contents.remove( indexOf( row, col ) );
+ contents.setAutoDelete( FALSE );
+}
+
+/*!
+ Sets the text in the cell at \a row, \a col to \a text.
+
+ If the cell does not contain a table item a TQTableItem is created
+ with an \link TQTableItem::EditType EditType\endlink of \c OnTyping,
+ otherwise the existing table item's text (if any) is tqreplaced with
+ \a text.
+
+ \sa text() setPixmap() setItem() TQTableItem::setText()
+*/
+
+void TQTable::setText( int row, int col, const TQString &text )
+{
+ TQTableItem *itm = item( row, col );
+ if ( itm ) {
+ itm->setText( text );
+ itm->updateEditor( row, col );
+ updateCell( row, col );
+ } else {
+ TQTableItem *i = new TQTableItem( this, TQTableItem::OnTyping,
+ text, TQPixmap() );
+ setItem( row, col, i );
+ }
+}
+
+/*!
+ Sets the pixmap in the cell at \a row, \a col to \a pix.
+
+ If the cell does not contain a table item a TQTableItem is created
+ with an \link TQTableItem::EditType EditType\endlink of \c OnTyping,
+ otherwise the existing table item's pixmap (if any) is tqreplaced
+ with \a pix.
+
+ Note that \l{TQComboTableItem}s and \l{TQCheckTableItem}s don't show
+ pixmaps.
+
+ \sa pixmap() setText() setItem() TQTableItem::setPixmap()
+*/
+
+void TQTable::setPixmap( int row, int col, const TQPixmap &pix )
+{
+ TQTableItem *itm = item( row, col );
+ if ( itm ) {
+ itm->setPixmap( pix );
+ updateCell( row, col );
+ } else {
+ TQTableItem *i = new TQTableItem( this, TQTableItem::OnTyping,
+ TQString::null, pix );
+ setItem( row, col, i );
+ }
+}
+
+/*!
+ Returns the text in the cell at \a row, \a col, or TQString::null
+ if the relevant item does not exist or has no text.
+
+ \sa setText() setPixmap()
+*/
+
+TQString TQTable::text( int row, int col ) const
+{
+ TQTableItem *itm = item( row, col );
+ if ( itm )
+ return itm->text();
+ return TQString::null;
+}
+
+/*!
+ Returns the pixmap set for the cell at \a row, \a col, or a
+ null-pixmap if the cell tqcontains no pixmap.
+
+ \sa setPixmap()
+*/
+
+TQPixmap TQTable::pixmap( int row, int col ) const
+{
+ TQTableItem *itm = item( row, col );
+ if ( itm )
+ return itm->pixmap();
+ return TQPixmap();
+}
+
+/*!
+ Moves the focus to the cell at \a row, \a col.
+
+ \sa currentRow() currentColumn()
+*/
+
+void TQTable::setCurrentCell( int row, int col )
+{
+ setCurrentCell( row, col, TRUE, TRUE );
+}
+
+// need to use a define, as leftMargin() is protected
+#define VERTICALMARGIN \
+( TQApplication::reverseLayout() ? \
+ rightMargin() \
+ : \
+ leftMargin() \
+)
+
+/*! \internal */
+
+void TQTable::setCurrentCell( int row, int col, bool updateSelections, bool ensureVisible )
+{
+ TQTableItem *oldItem = item( curRow, curCol );
+
+ if ( row > numRows() - 1 )
+ row = numRows() - 1;
+ if ( col > numCols() - 1 )
+ col = numCols() - 1;
+
+ if ( curRow == row && curCol == col )
+ return;
+
+
+ TQTableItem *itm = oldItem;
+ if ( itm && itm->editType() != TQTableItem::Always && itm->editType() != TQTableItem::Never )
+ endEdit( itm->row(), itm->col(), TRUE, FALSE );
+ int oldRow = curRow;
+ int oldCol = curCol;
+ curRow = row;
+ curCol = col;
+ repaintCell( oldRow, oldCol );
+ repaintCell( curRow, curCol );
+ if ( ensureVisible )
+ ensureCellVisible( curRow, curCol );
+ emit currentChanged( row, col );
+
+ if ( oldCol != curCol ) {
+ if ( !isColumnSelected( oldCol ) )
+ topHeader->setSectionState( oldCol, TQTableHeader::Normal );
+ else if ( isRowSelection( selectionMode() ) )
+ topHeader->setSectionState( oldCol, TQTableHeader::Selected );
+ topHeader->setSectionState( curCol, isColumnSelected( curCol, TRUE ) ?
+ TQTableHeader::Selected : TQTableHeader::Bold );
+ }
+
+ if ( oldRow != curRow ) {
+ if ( !isRowSelected( oldRow ) )
+ leftHeader->setSectionState( oldRow, TQTableHeader::Normal );
+ leftHeader->setSectionState( curRow, isRowSelected( curRow, TRUE ) ?
+ TQTableHeader::Selected : TQTableHeader::Bold );
+ }
+
+ itm = item( curRow, curCol );
+
+ TQPoint cellPos( columnPos( curCol ) + leftMargin() - contentsX(),
+ rowPos( curRow ) + topMargin() - contentsY() );
+ setMicroFocusHint( cellPos.x(), cellPos.y(), columnWidth( curCol ),
+ rowHeight( curRow ), ( itm && itm->editType() != TQTableItem::Never ) );
+
+ if ( cellWidget( oldRow, oldCol ) &&
+ cellWidget( oldRow, oldCol )->hasFocus() )
+ viewport()->setFocus();
+
+ if ( itm && itm->editType() == TQTableItem::WhenCurrent ) {
+ if ( beginEdit( itm->row(), itm->col(), FALSE ) )
+ setEditMode( Editing, itm->row(), itm->col() );
+ } else if ( itm && itm->editType() == TQTableItem::Always ) {
+ if ( cellWidget( itm->row(), itm->col() ) )
+ cellWidget( itm->row(), itm->col() )->setFocus();
+ }
+
+ if ( updateSelections && isRowSelection( selectionMode() ) &&
+ !isSelected( curRow, curCol, FALSE ) ) {
+ if ( selectionMode() == TQTable::SingleRow )
+ clearSelection();
+ currentSel = new TQTableSelection();
+ selections.append( currentSel );
+ currentSel->init( curRow, 0 );
+ currentSel->expandTo( curRow, numCols() - 1 );
+ repaintSelections( 0, currentSel );
+ }
+}
+
+/*!
+ Scrolls the table until the cell at \a row, \a col becomes
+ visible.
+*/
+
+void TQTable::ensureCellVisible( int row, int col )
+{
+ if ( !isUpdatesEnabled() || !viewport()->isUpdatesEnabled() )
+ return;
+ int cw = columnWidth( col );
+ int rh = rowHeight( row );
+ if ( cw < visibleWidth() )
+ ensureVisible( columnPos( col ) + cw / 2, rowPos( row ) + rh / 2, cw / 2, rh / 2 );
+ else
+ ensureVisible( columnPos( col ), rowPos( row ) + rh / 2, 0, rh / 2 );
+}
+
+/*!
+ Returns TRUE if the cell at \a row, \a col is selected; otherwise
+ returns FALSE.
+
+ \sa isRowSelected() isColumnSelected()
+*/
+
+bool TQTable::isSelected( int row, int col ) const
+{
+ return isSelected( row, col, TRUE );
+}
+
+/*! \internal */
+
+bool TQTable::isSelected( int row, int col, bool includeCurrent ) const
+{
+ TQPtrListIterator<TQTableSelection> it( selections );
+ TQTableSelection *s;
+ while ( ( s = it.current() ) != 0 ) {
+ ++it;
+ if ( s->isActive() &&
+ row >= s->topRow() &&
+ row <= s->bottomRow() &&
+ col >= s->leftCol() &&
+ col <= s->rightCol() )
+ return TRUE;
+ if ( includeCurrent && row == currentRow() && col == currentColumn() )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if row \a row is selected; otherwise returns FALSE.
+
+ If \a full is FALSE (the default), 'row is selected' means that at
+ least one cell in the row is selected. If \a full is TRUE, then 'row
+ is selected' means every cell in the row is selected.
+
+ \sa isColumnSelected() isSelected()
+*/
+
+bool TQTable::isRowSelected( int row, bool full ) const
+{
+ if ( !full ) {
+ TQPtrListIterator<TQTableSelection> it( selections );
+ TQTableSelection *s;
+ while ( ( s = it.current() ) != 0 ) {
+ ++it;
+ if ( s->isActive() &&
+ row >= s->topRow() &&
+ row <= s->bottomRow() )
+ return TRUE;
+ if ( row == currentRow() )
+ return TRUE;
+ }
+ } else {
+ TQPtrListIterator<TQTableSelection> it( selections );
+ TQTableSelection *s;
+ while ( ( s = it.current() ) != 0 ) {
+ ++it;
+ if ( s->isActive() &&
+ row >= s->topRow() &&
+ row <= s->bottomRow() &&
+ s->leftCol() == 0 &&
+ s->rightCol() == numCols() - 1 )
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if column \a col is selected; otherwise returns FALSE.
+
+ If \a full is FALSE (the default), 'column is selected' means that
+ at least one cell in the column is selected. If \a full is TRUE,
+ then 'column is selected' means every cell in the column is
+ selected.
+
+ \sa isRowSelected() isSelected()
+*/
+
+bool TQTable::isColumnSelected( int col, bool full ) const
+{
+ if ( !full ) {
+ TQPtrListIterator<TQTableSelection> it( selections );
+ TQTableSelection *s;
+ while ( ( s = it.current() ) != 0 ) {
+ ++it;
+ if ( s->isActive() &&
+ col >= s->leftCol() &&
+ col <= s->rightCol() )
+ return TRUE;
+ if ( col == currentColumn() )
+ return TRUE;
+ }
+ } else {
+ TQPtrListIterator<TQTableSelection> it( selections );
+ TQTableSelection *s;
+ while ( ( s = it.current() ) != 0 ) {
+ ++it;
+ if ( s->isActive() &&
+ col >= s->leftCol() &&
+ col <= s->rightCol() &&
+ s->topRow() == 0 &&
+ s->bottomRow() == numRows() - 1 )
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*!
+ \property TQTable::numSelections
+ \brief The number of selections.
+
+ \sa currentSelection()
+*/
+
+int TQTable::numSelections() const
+{
+ return selections.count();
+}
+
+/*!
+ Returns selection number \a num, or an inactive TQTableSelection if \a
+ num is out of range (see TQTableSelection::isActive()).
+*/
+
+TQTableSelection TQTable::selection( int num ) const
+{
+ if ( num < 0 || num >= (int)selections.count() )
+ return TQTableSelection();
+
+ TQTableSelection *s = ( (TQTable*)this )->selections.at( num );
+ return *s;
+}
+
+/*!
+ Adds a selection described by \a s to the table and returns its
+ number or -1 if the selection is invalid.
+
+ Remember to call TQTableSelection::init() and
+ TQTableSelection::expandTo() to make the selection valid (see also
+ TQTableSelection::isActive(), or use the
+ TQTableSelection(int,int,int,int) constructor).
+
+ \sa numSelections() removeSelection() clearSelection()
+*/
+
+int TQTable::addSelection( const TQTableSelection &s )
+{
+ if ( !s.isActive() )
+ return -1;
+
+ const int maxr = numRows()-1;
+ const int maxc = numCols()-1;
+ TQTableSelection *sel = new TQTableSelection( TQMIN(s.anchorRow(), maxr), TQMIN(s.anchorCol(), maxc),
+ TQMIN(s.bottomRow(), maxr), TQMIN(s.rightCol(), maxc) );
+
+ selections.append( sel );
+
+ repaintSelections( 0, sel, TRUE, TRUE );
+
+ emit selectionChanged();
+
+ return selections.count() - 1;
+}
+
+/*!
+ If the table has a selection, \a s, this selection is removed from
+ the table.
+
+ \sa addSelection() numSelections()
+*/
+
+void TQTable::removeSelection( const TQTableSelection &s )
+{
+ selections.setAutoDelete( FALSE );
+ for ( TQTableSelection *sel = selections.first(); sel; sel = selections.next() ) {
+ if ( s == *sel ) {
+ selections.removeRef( sel );
+ repaintSelections( sel, 0, TRUE, TRUE );
+ if ( sel == currentSel )
+ currentSel = 0;
+ delete sel;
+ }
+ }
+ selections.setAutoDelete( TRUE );
+ emit selectionChanged();
+}
+
+/*!
+ \overload
+
+ Removes selection number \a num from the table.
+
+ \sa numSelections() addSelection() clearSelection()
+*/
+
+void TQTable::removeSelection( int num )
+{
+ if ( num < 0 || num >= (int)selections.count() )
+ return;
+
+ TQTableSelection *s = selections.at( num );
+ if ( s == currentSel )
+ currentSel = 0;
+ selections.removeRef( s );
+ repaintContents( FALSE );
+}
+
+/*!
+ Returns the number of the current selection or -1 if there is no
+ current selection.
+
+ \sa numSelections()
+*/
+
+int TQTable::currentSelection() const
+{
+ if ( !currentSel )
+ return -1;
+ return ( (TQTable*)this )->selections.tqfindRef( currentSel );
+}
+
+/*! Selects the range starting at \a start_row and \a start_col and
+ ending at \a end_row and \a end_col.
+
+ \sa TQTableSelection
+*/
+
+void TQTable::selectCells( int start_row, int start_col, int end_row, int end_col )
+{
+ const int maxr = numRows()-1;
+ const int maxc = numCols()-1;
+
+ start_row = TQMIN( maxr, TQMAX( 0, start_row ) );
+ start_col = TQMIN( maxc, TQMAX( 0, start_col ) );
+ end_row = TQMIN( maxr, end_row );
+ end_col = TQMIN( maxc, end_col );
+ TQTableSelection sel( start_row, start_col, end_row, end_col );
+ addSelection( sel );
+}
+
+/*! Selects the row \a row.
+
+ \sa TQTableSelection
+*/
+
+// ### Make this virtual in 4.0 and remove hack for TQDataTable
+void TQTable::selectRow( int row )
+{
+ row = TQMIN(numRows()-1, row);
+ if ( row < 0 )
+ return;
+ bool isDataTable = FALSE;
+#ifndef TQT_NO_SQL
+ isDataTable = ::tqqt_cast<TQDataTable*>(this) != 0;
+#endif
+ if ( isDataTable || selectionMode() == SingleRow ) {
+ setCurrentCell( row, currentColumn() );
+ } else {
+ TQTableSelection sel( row, 0, row, numCols() - 1 );
+ addSelection( sel );
+ }
+}
+
+/*! Selects the column \a col.
+
+ \sa TQTableSelection
+*/
+
+// ### Make this virtual in 4.0
+void TQTable::selectColumn( int col )
+{
+ col = TQMIN(numCols()-1, col);
+ TQTableSelection sel( 0, col, numRows() - 1, col );
+ addSelection( sel );
+}
+
+/*! \reimp
+*/
+void TQTable::contentsMousePressEvent( TQMouseEvent* e )
+{
+ contentsMousePressEventEx( e );
+}
+
+void TQTable::contentsMousePressEventEx( TQMouseEvent* e )
+{
+ shouldClearSelection = FALSE;
+ if ( isEditing() ) {
+ if ( !cellGeometry( editRow, editCol ).tqcontains( e->pos() ) ) {
+ endEdit( editRow, editCol, TRUE, edMode != Editing );
+ } else {
+ e->ignore();
+ return;
+ }
+ }
+
+ d->redirectMouseEvent = FALSE;
+
+ int tmpRow = rowAt( e->pos().y() );
+ int tmpCol = columnAt( e->pos().x() );
+ pressedRow = tmpRow;
+ pressedCol = tmpCol;
+ fixRow( tmpRow, e->pos().y() );
+ fixCol( tmpCol, e->pos().x() );
+ startDragCol = -1;
+ startDragRow = -1;
+
+ if ( isSelected( tmpRow, tmpCol ) ) {
+ startDragCol = tmpCol;
+ startDragRow = tmpRow;
+ dragStartPos = e->pos();
+ }
+
+ TQTableItem *itm = item( pressedRow, pressedCol );
+ if ( itm && !itm->isEnabled() ) {
+ emit pressed( tmpRow, tmpCol, e->button(), e->pos() );
+ return;
+ }
+
+ if ( ( e->state() & ShiftButton ) == ShiftButton ) {
+ int oldRow = curRow;
+ int oldCol = curCol;
+ setCurrentCell( tmpRow, tmpCol, selMode == SingleRow, TRUE );
+ if ( selMode != NoSelection && selMode != SingleRow ) {
+ if ( !currentSel ) {
+ currentSel = new TQTableSelection();
+ selections.append( currentSel );
+ if ( !isRowSelection( selectionMode() ) )
+ currentSel->init( oldRow, oldCol );
+ else
+ currentSel->init( oldRow, 0 );
+ }
+ TQTableSelection oldSelection = *currentSel;
+ if ( !isRowSelection( selectionMode() ) )
+ currentSel->expandTo( tmpRow, tmpCol );
+ else
+ currentSel->expandTo( tmpRow, numCols() - 1 );
+ repaintSelections( &oldSelection, currentSel );
+ emit selectionChanged();
+ }
+ } else if ( ( e->state() & ControlButton ) == ControlButton ) {
+ setCurrentCell( tmpRow, tmpCol, FALSE, TRUE );
+ if ( selMode != NoSelection ) {
+ if ( selMode == Single || (selMode == SingleRow && !isSelected( tmpRow, tmpCol, FALSE )) )
+ clearSelection();
+ if ( !(selMode == SingleRow && isSelected( tmpRow, tmpCol, FALSE )) ) {
+ currentSel = new TQTableSelection();
+ selections.append( currentSel );
+ if ( !isRowSelection( selectionMode() ) ) {
+ currentSel->init( tmpRow, tmpCol );
+ currentSel->expandTo( tmpRow, tmpCol );
+ } else {
+ currentSel->init( tmpRow, 0 );
+ currentSel->expandTo( tmpRow, numCols() - 1 );
+ repaintSelections( 0, currentSel );
+ }
+ emit selectionChanged();
+ }
+ }
+ } else {
+ setCurrentCell( tmpRow, tmpCol, FALSE, TRUE );
+ TQTableItem *itm = item( tmpRow, tmpCol );
+ if ( itm && itm->editType() == TQTableItem::WhenCurrent ) {
+ TQWidget *w = cellWidget( tmpRow, tmpCol );
+ if ( ::tqqt_cast<TQComboBox*>(w) || ::tqqt_cast<TQButton*>(w) ) {
+ TQMouseEvent ev( e->type(), w->mapFromGlobal( e->globalPos() ),
+ e->globalPos(), e->button(), e->state() );
+ TQApplication::sendPostedEvents( w, 0 );
+ TQApplication::sendEvent( w, &ev );
+ d->redirectMouseEvent = TRUE;
+ }
+ }
+ if ( isSelected( tmpRow, tmpCol, FALSE ) ) {
+ shouldClearSelection = TRUE;
+ } else {
+ bool b = tqsignalsBlocked();
+ if ( selMode != NoSelection )
+ blockSignals( TRUE );
+ clearSelection();
+ blockSignals( b );
+ if ( selMode != NoSelection ) {
+ currentSel = new TQTableSelection();
+ selections.append( currentSel );
+ if ( !isRowSelection( selectionMode() ) ) {
+ currentSel->init( tmpRow, tmpCol );
+ currentSel->expandTo( tmpRow, tmpCol );
+ } else {
+ currentSel->init( tmpRow, 0 );
+ currentSel->expandTo( tmpRow, numCols() - 1 );
+ repaintSelections( 0, currentSel );
+ }
+ emit selectionChanged();
+ }
+ }
+ }
+
+ emit pressed( tmpRow, tmpCol, e->button(), e->pos() );
+}
+
+/*! \reimp
+*/
+
+void TQTable::contentsMouseDoubleClickEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+ if ( !isRowSelection( selectionMode() ) )
+ clearSelection();
+ int tmpRow = rowAt( e->pos().y() );
+ int tmpCol = columnAt( e->pos().x() );
+ TQTableItem *itm = item( tmpRow, tmpCol );
+ if ( itm && !itm->isEnabled() )
+ return;
+ if ( tmpRow != -1 && tmpCol != -1 ) {
+ if ( beginEdit( tmpRow, tmpCol, FALSE ) )
+ setEditMode( Editing, tmpRow, tmpCol );
+ }
+
+ emit doubleClicked( tmpRow, tmpCol, e->button(), e->pos() );
+}
+
+/*!
+ Sets the current edit mode to \a mode, the current edit row to \a
+ row and the current edit column to \a col.
+
+ \sa EditMode
+*/
+
+void TQTable::setEditMode( EditMode mode, int row, int col )
+{
+ edMode = mode;
+ editRow = row;
+ editCol = col;
+}
+
+
+/*! \reimp
+*/
+
+void TQTable::contentsMouseMoveEvent( TQMouseEvent *e )
+{
+ if ( (e->state() & Qt::MouseButtonMask) == Qt::NoButton )
+ return;
+ int tmpRow = rowAt( e->pos().y() );
+ int tmpCol = columnAt( e->pos().x() );
+ fixRow( tmpRow, e->pos().y() );
+ fixCol( tmpCol, e->pos().x() );
+
+#ifndef TQT_NO_DRAGANDDROP
+ if ( dragEnabled() && startDragRow != -1 && startDragCol != -1 ) {
+ if (TQPoint(dragStartPos - e->pos()).manhattanLength() > TQApplication::startDragDistance())
+ startDrag();
+ return;
+ }
+#endif
+ if ( selectionMode() == MultiRow && ( e->state() & ControlButton ) == ControlButton )
+ shouldClearSelection = FALSE;
+
+ if ( shouldClearSelection ) {
+ clearSelection();
+ if ( selMode != NoSelection ) {
+ currentSel = new TQTableSelection();
+ selections.append( currentSel );
+ if ( !isRowSelection( selectionMode() ) )
+ currentSel->init( tmpRow, tmpCol );
+ else
+ currentSel->init( tmpRow, 0 );
+ emit selectionChanged();
+ }
+ shouldClearSelection = FALSE;
+ }
+
+ TQPoint pos = mapFromGlobal( e->globalPos() );
+ pos -= TQPoint( leftHeader->width(), topHeader->height() );
+ autoScrollTimer->stop();
+ doAutoScroll();
+ if ( pos.x() < 0 || pos.x() > visibleWidth() || pos.y() < 0 || pos.y() > visibleHeight() )
+ autoScrollTimer->start( 100, TRUE );
+}
+
+/*! \internal
+ */
+
+void TQTable::doValueChanged()
+{
+ emit valueChanged( editRow, editCol );
+}
+
+/*! \internal
+*/
+
+void TQTable::doAutoScroll()
+{
+ TQPoint pos = TQCursor::pos();
+ pos = mapFromGlobal( pos );
+ pos -= TQPoint( leftHeader->width(), topHeader->height() );
+
+ int tmpRow = curRow;
+ int tmpCol = curCol;
+ if ( pos.y() < 0 )
+ tmpRow--;
+ else if ( pos.y() > visibleHeight() )
+ tmpRow++;
+ if ( pos.x() < 0 )
+ tmpCol--;
+ else if ( pos.x() > visibleWidth() )
+ tmpCol++;
+
+ pos += TQPoint( contentsX(), contentsY() );
+ if ( tmpRow == curRow )
+ tmpRow = rowAt( pos.y() );
+ if ( tmpCol == curCol )
+ tmpCol = columnAt( pos.x() );
+ pos -= TQPoint( contentsX(), contentsY() );
+
+ fixRow( tmpRow, pos.y() );
+ fixCol( tmpCol, pos.x() );
+
+ if ( tmpRow < 0 || tmpRow > numRows() - 1 )
+ tmpRow = currentRow();
+ if ( tmpCol < 0 || tmpCol > numCols() - 1 )
+ tmpCol = currentColumn();
+
+ ensureCellVisible( tmpRow, tmpCol );
+
+ if ( currentSel && selMode != NoSelection ) {
+ TQTableSelection oldSelection = *currentSel;
+ bool useOld = TRUE;
+ if ( selMode != SingleRow ) {
+ if ( !isRowSelection( selectionMode() ) ) {
+ currentSel->expandTo( tmpRow, tmpCol );
+ } else {
+ currentSel->expandTo( tmpRow, numCols() - 1 );
+ }
+ } else {
+ bool currentInSelection = tmpRow == curRow && isSelected( tmpRow, tmpCol );
+ if ( !currentInSelection ) {
+ useOld = FALSE;
+ clearSelection();
+ currentSel = new TQTableSelection();
+ selections.append( currentSel );
+ currentSel->init( tmpRow, 0 );
+ currentSel->expandTo( tmpRow, numCols() - 1 );
+ repaintSelections( 0, currentSel );
+ } else {
+ currentSel->expandTo( tmpRow, numCols() - 1 );
+ }
+ }
+ setCurrentCell( tmpRow, tmpCol, FALSE, TRUE );
+ repaintSelections( useOld ? &oldSelection : 0, currentSel );
+ if ( currentSel && oldSelection != *currentSel )
+ emit selectionChanged();
+ } else {
+ setCurrentCell( tmpRow, tmpCol, FALSE, TRUE );
+ }
+
+ if ( pos.x() < 0 || pos.x() > visibleWidth() || pos.y() < 0 || pos.y() > visibleHeight() )
+ autoScrollTimer->start( 100, TRUE );
+}
+
+/*! \reimp
+*/
+
+void TQTable::contentsMouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( pressedRow == curRow && pressedCol == curCol )
+ emit clicked( curRow, curCol, e->button(), e->pos() );
+
+ if ( e->button() != Qt::LeftButton )
+ return;
+ if ( shouldClearSelection ) {
+ int tmpRow = rowAt( e->pos().y() );
+ int tmpCol = columnAt( e->pos().x() );
+ fixRow( tmpRow, e->pos().y() );
+ fixCol( tmpCol, e->pos().x() );
+ clearSelection();
+ if ( selMode != NoSelection ) {
+ currentSel = new TQTableSelection();
+ selections.append( currentSel );
+ if ( !isRowSelection( selectionMode() ) ) {
+ currentSel->init( tmpRow, tmpCol );
+ } else {
+ currentSel->init( tmpRow, 0 );
+ currentSel->expandTo( tmpRow, numCols() - 1 );
+ repaintSelections( 0, currentSel );
+ }
+ emit selectionChanged();
+ }
+ shouldClearSelection = FALSE;
+ }
+ autoScrollTimer->stop();
+
+ if ( d->redirectMouseEvent && pressedRow == curRow && pressedCol == curCol &&
+ item( pressedRow, pressedCol ) && item( pressedRow, pressedCol )->editType() ==
+ TQTableItem::WhenCurrent ) {
+ TQWidget *w = cellWidget( pressedRow, pressedCol );
+ if ( w ) {
+ TQMouseEvent ev( e->type(), w->mapFromGlobal( e->globalPos() ),
+ e->globalPos(), e->button(), e->state() );
+ TQApplication::sendPostedEvents( w, 0 );
+ TQApplication::sendEvent( w, &ev );
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQTable::contentsContextMenuEvent( TQContextMenuEvent *e )
+{
+ if ( !tqreceivers( TQT_SIGNAL(contextMenuRequested(int,int,const TQPoint&)) ) ) {
+ e->ignore();
+ return;
+ }
+ if ( e->reason() == TQContextMenuEvent::Keyboard ) {
+ TQRect r = cellGeometry( curRow, curCol );
+ emit contextMenuRequested( curRow, curCol, viewport()->mapToGlobal( contentsToViewport( r.center() ) ) );
+ } else {
+ int tmpRow = rowAt( e->pos().y() );
+ int tmpCol = columnAt( e->pos().x() );
+ emit contextMenuRequested( tmpRow, tmpCol, e->globalPos() );
+ }
+}
+
+
+/*! \reimp
+*/
+
+bool TQTable::eventFilter( TQObject *o, TQEvent *e )
+{
+ TQWidget *editorWidget = cellWidget( editRow, editCol );
+ switch ( e->type() ) {
+ case TQEvent::KeyPress: {
+ TQTableItem *itm = item( curRow, curCol );
+ int editRow = this->editRow;
+ int editCol = this->editCol;
+ if ((d->hasRowSpan || d->hasColSpan) && !editorWidget) {
+ if (TQTableItem *eitm = item(editRow, editCol)) {
+ editRow = eitm->row();
+ editCol = eitm->col();
+ editorWidget = cellWidget(editRow, editCol);
+ }
+ }
+ if ( isEditing() && editorWidget && TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(editorWidget) ) {
+ itm = item( editRow, editCol );
+ TQKeyEvent *ke = (TQKeyEvent*)e;
+ if ( ke->key() == Key_Escape ) {
+ if ( !itm || itm->editType() == TQTableItem::OnTyping )
+ endEdit( editRow, editCol, FALSE, edMode != Editing );
+ return TRUE;
+ }
+
+ if ( ( ke->state() == Qt::NoButton || ke->state() == TQt::Keypad )
+ && ( ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter ) ) {
+ if ( !itm || itm->editType() == TQTableItem::OnTyping )
+ endEdit( editRow, editCol, TRUE, edMode != Editing );
+ activateNextCell();
+ return TRUE;
+ }
+
+ if ( ke->key() == Qt::Key_Tab || ke->key() == TQt::Key_BackTab ) {
+ if ( ke->state() & ControlButton )
+ return FALSE;
+ if ( !itm || itm->editType() == TQTableItem::OnTyping )
+ endEdit( editRow, editCol, TRUE, edMode != Editing );
+ if ( (ke->key() == Qt::Key_Tab) && !(ke->state() & ShiftButton) ) {
+ if ( currentColumn() >= numCols() - 1 )
+ return TRUE;
+ int cc = TQMIN( numCols() - 1, currentColumn() + 1 );
+ while ( cc < numCols() ) {
+ TQTableItem *i = item( currentRow(), cc );
+ if ( !d->hiddenCols.tqfind( cc ) && !isColumnReadOnly( cc ) && (!i || i->isEnabled()) )
+ break;
+ ++cc;
+ }
+ setCurrentCell( currentRow(), cc );
+ } else { // Qt::Key_BackTab
+ if ( currentColumn() == 0 )
+ return TRUE;
+ int cc = TQMAX( 0, currentColumn() - 1 );
+ while ( cc >= 0 ) {
+ TQTableItem *i = item( currentRow(), cc );
+ if ( !d->hiddenCols.tqfind( cc ) && !isColumnReadOnly( cc ) && (!i || i->isEnabled()) )
+ break;
+ --cc;
+ }
+ setCurrentCell( currentRow(), cc );
+ }
+ itm = item( curRow, curCol );
+ if ( beginEdit( curRow, curCol, FALSE ) )
+ setEditMode( Editing, curRow, curCol );
+ return TRUE;
+ }
+
+ if ( ( edMode == Replacing ||
+ (itm && itm->editType() == TQTableItem::WhenCurrent) ) &&
+ ( ke->key() == Qt::Key_Up || ke->key() == TQt::Key_Prior ||
+ ke->key() == Qt::Key_Home || ke->key() == Qt::Key_Down ||
+ ke->key() == TQt::Key_Next || ke->key() == Qt::Key_End ||
+ ke->key() == Qt::Key_Left || ke->key() == Qt::Key_Right ) ) {
+ if ( !itm || itm->editType() == TQTableItem::OnTyping ) {
+ endEdit( editRow, editCol, TRUE, edMode != Editing );
+ }
+ keyPressEvent( ke );
+ return TRUE;
+ }
+ } else {
+ TQObjectList *l = viewport()->queryList( "TQWidget" );
+ if ( l && l->tqfind( o ) != -1 ) {
+ delete l;
+ TQKeyEvent *ke = (TQKeyEvent*)e;
+ if ( ( ke->state() & ControlButton ) == ControlButton ||
+ ( ke->key() != Qt::Key_Left && ke->key() != Qt::Key_Right &&
+ ke->key() != Qt::Key_Up && ke->key() != Qt::Key_Down &&
+ ke->key() != TQt::Key_Prior && ke->key() != TQt::Key_Next &&
+ ke->key() != Qt::Key_Home && ke->key() != Qt::Key_End ) )
+ return FALSE;
+ keyPressEvent( (TQKeyEvent*)e );
+ return TRUE;
+ }
+ delete l;
+ }
+
+ } break;
+ case TQEvent::FocusOut:
+ if ( isEditing() && editorWidget && TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(editorWidget) && ( (TQFocusEvent*)e )->reason() != TQFocusEvent::Popup ) {
+ TQTableItem *itm = item( editRow, editCol );
+ if ( !itm || itm->editType() == TQTableItem::OnTyping ) {
+ endEdit( editRow, editCol, TRUE, edMode != Editing );
+ return TRUE;
+ }
+ }
+ break;
+#ifndef TQT_NO_WHEELEVENT
+ case TQEvent::Wheel:
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) || TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(viewport()) ) {
+ TQWheelEvent* we = (TQWheelEvent*)e;
+ scrollBy( 0, -we->delta() );
+ we->accept();
+ return TRUE;
+ }
+#endif
+ default:
+ break;
+ }
+
+ return TQScrollView::eventFilter( o, e );
+}
+
+void TQTable::fixCell( int &row, int &col, int key )
+{
+ if ( rowHeight( row ) > 0 && columnWidth( col ) > 0 )
+ return;
+ if ( rowHeight( row ) <= 0 ) {
+ if ( key == Qt::Key_Down ||
+ key == TQt::Key_Next ||
+ key == Qt::Key_End ) {
+ while ( row < numRows() && rowHeight( row ) <= 0 )
+ row++;
+ if ( rowHeight( row ) <= 0 )
+ row = curRow;
+ } else if ( key == Qt::Key_Up ||
+ key == TQt::Key_Prior ||
+ key == Qt::Key_Home )
+ while ( row >= 0 && rowHeight( row ) <= 0 )
+ row--;
+ if ( rowHeight( row ) <= 0 )
+ row = curRow;
+ } else if ( columnWidth( col ) <= 0 ) {
+ if ( key == Qt::Key_Left ) {
+ while ( col >= 0 && columnWidth( col ) <= 0 )
+ col--;
+ if ( columnWidth( col ) <= 0 )
+ col = curCol;
+ } else if ( key == Qt::Key_Right ) {
+ while ( col < numCols() && columnWidth( col ) <= 0 )
+ col++;
+ if ( columnWidth( col ) <= 0 )
+ col = curCol;
+ }
+ }
+}
+
+/*! \reimp
+*/
+
+void TQTable::keyPressEvent( TQKeyEvent* e )
+{
+ if ( isEditing() && item( editRow, editCol ) &&
+ item( editRow, editCol )->editType() == TQTableItem::OnTyping )
+ return;
+
+ int tmpRow = curRow;
+ int tmpCol = curCol;
+ int oldRow = tmpRow;
+ int oldCol = tmpCol;
+
+ bool navigationKey = FALSE;
+ int r;
+ switch ( e->key() ) {
+ case Qt::Key_Left:
+ tmpCol = TQMAX( 0, tmpCol - 1 );
+ navigationKey = TRUE;
+ break;
+ case Qt::Key_Right:
+ tmpCol = TQMIN( numCols() - 1, tmpCol + 1 );
+ navigationKey = TRUE;
+ break;
+ case Qt::Key_Up:
+ tmpRow = TQMAX( 0, tmpRow - 1 );
+ navigationKey = TRUE;
+ break;
+ case Qt::Key_Down:
+ tmpRow = TQMIN( numRows() - 1, tmpRow + 1 );
+ navigationKey = TRUE;
+ break;
+ case TQt::Key_Prior:
+ r = TQMAX( 0, rowAt( rowPos( tmpRow ) - visibleHeight() ) );
+ if ( r < tmpRow || tmpRow < 0 )
+ tmpRow = r;
+ navigationKey = TRUE;
+ break;
+ case TQt::Key_Next:
+ r = TQMIN( numRows() - 1, rowAt( rowPos( tmpRow ) + visibleHeight() ) );
+ if ( r > tmpRow )
+ tmpRow = r;
+ else
+ tmpRow = numRows() - 1;
+ navigationKey = TRUE;
+ break;
+ case Qt::Key_Home:
+ tmpRow = 0;
+ navigationKey = TRUE;
+ break;
+ case Qt::Key_End:
+ tmpRow = numRows() - 1;
+ navigationKey = TRUE;
+ break;
+ case Qt::Key_F2:
+ if ( beginEdit( tmpRow, tmpCol, FALSE ) )
+ setEditMode( Editing, tmpRow, tmpCol );
+ break;
+ case Qt::Key_Enter: case Qt::Key_Return:
+ activateNextCell();
+ return;
+ case Qt::Key_Tab: case TQt::Key_BackTab:
+ if ( (e->key() == Qt::Key_Tab) && !(e->state() & ShiftButton) ) {
+ if ( currentColumn() >= numCols() - 1 )
+ return;
+ int cc = TQMIN( numCols() - 1, currentColumn() + 1 );
+ while ( cc < numCols() ) {
+ TQTableItem *i = item( currentRow(), cc );
+ if ( !d->hiddenCols.tqfind( cc ) && !isColumnReadOnly( cc ) && (!i || i->isEnabled()) )
+ break;
+ ++cc;
+ }
+ setCurrentCell( currentRow(), cc );
+ } else { // Qt::Key_BackTab
+ if ( currentColumn() == 0 )
+ return;
+ int cc = TQMAX( 0, currentColumn() - 1 );
+ while ( cc >= 0 ) {
+ TQTableItem *i = item( currentRow(), cc );
+ if ( !d->hiddenCols.tqfind( cc ) && !isColumnReadOnly( cc ) && (!i || i->isEnabled()) )
+ break;
+ --cc;
+ }
+ setCurrentCell( currentRow(), cc );
+ }
+ return;
+ case Key_Escape:
+ e->ignore();
+ return;
+ default: // ... or start in-place editing
+ if ( e->text()[ 0 ].isPrint() ) {
+ TQTableItem *itm = item( tmpRow, tmpCol );
+ if ( !itm || itm->editType() == TQTableItem::OnTyping ) {
+ TQWidget *w = beginEdit( tmpRow, tmpCol,
+ itm ? itm->isReplaceable() : TRUE );
+ if ( w ) {
+ setEditMode( ( !itm || (itm && itm->isReplaceable())
+ ? Replacing : Editing ), tmpRow, tmpCol );
+ TQApplication::sendEvent( w, e );
+ return;
+ }
+ }
+ }
+ e->ignore();
+ return;
+ }
+
+ if ( navigationKey ) {
+ fixCell( tmpRow, tmpCol, e->key() );
+ if ( ( e->state() & ShiftButton ) == ShiftButton &&
+ selMode != NoSelection && selMode != SingleRow ) {
+ bool justCreated = FALSE;
+ setCurrentCell( tmpRow, tmpCol, FALSE, TRUE );
+ if ( !currentSel ) {
+ justCreated = TRUE;
+ currentSel = new TQTableSelection();
+ selections.append( currentSel );
+ if ( !isRowSelection( selectionMode() ) )
+ currentSel->init( oldRow, oldCol );
+ else
+ currentSel->init( oldRow < 0 ? 0 : oldRow, 0 );
+ }
+ TQTableSelection oldSelection = *currentSel;
+ if ( !isRowSelection( selectionMode() ) )
+ currentSel->expandTo( tmpRow, tmpCol );
+ else
+ currentSel->expandTo( tmpRow, numCols() - 1 );
+ repaintSelections( justCreated ? 0 : &oldSelection, currentSel );
+ emit selectionChanged();
+ } else {
+ setCurrentCell( tmpRow, tmpCol, FALSE, TRUE );
+ if ( !isRowSelection( selectionMode() ) ) {
+ clearSelection();
+ } else {
+ bool currentInSelection = tmpRow == oldRow && isSelected( tmpRow, tmpCol, FALSE );
+ if ( !currentInSelection ) {
+ bool hasOldSel = FALSE;
+ TQTableSelection oldSelection;
+ if ( selectionMode() == MultiRow ) {
+ bool b = tqsignalsBlocked();
+ blockSignals( TRUE );
+ clearSelection();
+ blockSignals( b );
+ } else {
+ if ( currentSel ) {
+ oldSelection = *currentSel;
+ hasOldSel = TRUE;
+ selections.removeRef( currentSel );
+ leftHeader->setSectionState( oldSelection.topRow(), TQTableHeader::Normal );
+ }
+ }
+ currentSel = new TQTableSelection();
+ selections.append( currentSel );
+ currentSel->init( tmpRow, 0 );
+ currentSel->expandTo( tmpRow, numCols() - 1 );
+ repaintSelections( hasOldSel ? &oldSelection : 0, currentSel, !hasOldSel );
+ emit selectionChanged();
+ }
+ }
+ }
+ } else {
+ setCurrentCell( tmpRow, tmpCol, FALSE, TRUE );
+ }
+}
+
+/*! \reimp
+*/
+
+void TQTable::focusInEvent( TQFocusEvent* )
+{
+ d->inMenuMode = FALSE;
+ TQWidget *editorWidget = cellWidget( editRow, editCol );
+ updateCell( curRow, curCol );
+ if ( tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this ) )
+ repaintSelections();
+ if ( isEditing() && editorWidget )
+ editorWidget->setFocus();
+
+ TQPoint cellPos( columnPos( curCol ) + leftMargin() - contentsX(), rowPos( curRow ) + topMargin() - contentsY() );
+ TQTableItem *itm = item( curRow, curCol );
+ setMicroFocusHint( cellPos.x(), cellPos.y(), columnWidth( curCol ), rowHeight( curRow ), ( itm && itm->editType() != TQTableItem::Never ) );
+}
+
+
+/*! \reimp
+*/
+
+void TQTable::focusOutEvent( TQFocusEvent* tqfe )
+{
+ updateCell( curRow, curCol );
+ if (tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this )) {
+ d->inMenuMode =
+#ifdef USE_QT4
+ tqfe->reason() == TQFocusEvent::Popup ||
+#else // USE_QT4
+ TQFocusEvent::reason() == TQFocusEvent::Popup ||
+#endif // USE_QT4
+ (tqApp->tqfocusWidget() && tqApp->tqfocusWidget()->inherits("TQMenuBar"));
+ if ( !d->inMenuMode )
+ repaintSelections();
+ }
+}
+
+/*! \reimp
+*/
+
+TQSize TQTable::tqsizeHint() const
+{
+ if ( cachedSizeHint().isValid() )
+ return cachedSizeHint();
+
+ constPolish();
+
+ TQSize s = tableSize();
+ TQSize sh;
+ if ( s.width() < 500 && s.height() < 500 ) {
+ sh = TQSize( tableSize().width() + VERTICALMARGIN + 5,
+ tableSize().height() + topMargin() + 5 );
+ } else {
+ sh = TQScrollView::tqsizeHint();
+ if ( !topHeader->isHidden() )
+ sh.setHeight( sh.height() + topHeader->height() );
+ if ( !leftHeader->isHidden() )
+ sh.setWidth( sh.width() + leftHeader->width() );
+ }
+ setCachedSizeHint( sh );
+ return sh;
+}
+
+/*! \reimp
+*/
+
+void TQTable::viewportResizeEvent( TQResizeEvent *e )
+{
+ TQScrollView::viewportResizeEvent( e );
+ updateGeometries();
+}
+
+/*! \reimp
+*/
+
+void TQTable::showEvent( TQShowEvent *e )
+{
+ TQScrollView::showEvent( e );
+ TQRect r( cellGeometry( numRows() - 1, numCols() - 1 ) );
+ resizeContents( r.right() + 1, r.bottom() + 1 );
+ updateGeometries();
+}
+
+/*! \reimp
+*/
+
+void TQTable::paintEvent( TQPaintEvent *e )
+{
+ TQRect topLeftCorner = TQStyle::tqvisualRect( TQRect(frameWidth(), frameWidth(), VERTICALMARGIN, topMargin() ), rect() );
+ erase( topLeftCorner ); // erase instead of widget on top
+ TQScrollView::paintEvent( e );
+
+#ifdef TQ_OS_TEMP
+ TQPainter p( this );
+ p.drawLine( topLeftCorner.bottomLeft(), topLeftCorner.bottomRight() );
+ p.drawLine( topLeftCorner.bottomRight(), topLeftCorner.topRight() );
+#endif
+}
+
+static bool inUpdateCell = FALSE;
+
+/*!
+ Repaints the cell at \a row, \a col.
+*/
+
+void TQTable::updateCell( int row, int col )
+{
+ if ( inUpdateCell || row < 0 || col < 0 )
+ return;
+ inUpdateCell = TRUE;
+ TQRect cg = cellGeometry( row, col );
+ TQRect r( contentsToViewport( TQPoint( cg.x() - 2, cg.y() - 2 ) ),
+ TQSize( cg.width() + 4, cg.height() + 4 ) );
+ if (viewport()->rect().intersects(r))
+ TQApplication::postEvent( viewport(), new TQPaintEvent( r, FALSE ) );
+ inUpdateCell = FALSE;
+}
+
+void TQTable::repaintCell( int row, int col )
+{
+ if ( row == -1 || col == -1 )
+ return;
+ TQRect cg = cellGeometry( row, col );
+ TQRect r( TQPoint( cg.x() - 2, cg.y() - 2 ),
+ TQSize( cg.width() + 4, cg.height() + 4 ) );
+
+ TQRect v = viewport()->rect();
+ v.moveBy(contentsX(), contentsY());
+ if (v.intersects(r))
+ repaintContents( r, FALSE );
+}
+
+void TQTable::contentsToViewport2( int x, int y, int& vx, int& vy )
+{
+ const TQPoint v = contentsToViewport2( TQPoint( x, y ) );
+ vx = v.x();
+ vy = v.y();
+}
+
+TQPoint TQTable::contentsToViewport2( const TQPoint &p )
+{
+ return TQPoint( p.x() - contentsX(),
+ p.y() - contentsY() );
+}
+
+TQPoint TQTable::viewportToContents2( const TQPoint& vp )
+{
+ return TQPoint( vp.x() + contentsX(),
+ vp.y() + contentsY() );
+}
+
+void TQTable::viewportToContents2( int vx, int vy, int& x, int& y )
+{
+ const TQPoint c = viewportToContents2( TQPoint( vx, vy ) );
+ x = c.x();
+ y = c.y();
+}
+
+/*!
+ This function should be called whenever the column width of \a col
+ has been changed. It updates the tqgeometry of any affected columns
+ and repaints the table to reflect the changes it has made.
+*/
+
+void TQTable::columnWidthChanged( int col )
+{
+ int p = columnPos( col );
+ if ( d->hasColSpan )
+ p = contentsX();
+ updateContents( p, contentsY(), contentsWidth(), visibleHeight() );
+ TQSize s( tableSize() );
+ int w = contentsWidth();
+ resizeContents( s.width(), s.height() );
+ if ( contentsWidth() < w )
+ repaintContents( s.width(), contentsY(),
+ w - s.width() + 1, visibleHeight(), TRUE );
+ else
+ repaintContents( w, contentsY(),
+ s.width() - w + 1, visibleHeight(), FALSE );
+
+ // update widgets that are affected by this change
+ if ( widgets.size() ) {
+ int last = isHidden() ? numCols() - 1 : d->lastVisCol;
+ for ( int c = col; c <= last; ++c )
+ updateColWidgets( c );
+ }
+ delayedUpdateGeometries();
+}
+
+/*!
+ This function should be called whenever the row height of \a row
+ has been changed. It updates the tqgeometry of any affected rows and
+ repaints the table to reflect the changes it has made.
+*/
+
+void TQTable::rowHeightChanged( int row )
+{
+ int p = rowPos( row );
+ if ( d->hasRowSpan )
+ p = contentsY();
+ updateContents( contentsX(), p, visibleWidth(), contentsHeight() );
+ TQSize s( tableSize() );
+ int h = contentsHeight();
+ resizeContents( s.width(), s.height() );
+ if ( contentsHeight() < h ) {
+ repaintContents( contentsX(), contentsHeight(),
+ visibleWidth(), h - s.height() + 1, TRUE );
+ } else {
+ repaintContents( contentsX(), h,
+ visibleWidth(), s.height() - h + 1, FALSE );
+ }
+
+ // update widgets that are affected by this change
+ if ( widgets.size() ) {
+ d->lastVisRow = rowAt( contentsY() + visibleHeight() + ( s.height() - h + 1 ) );
+ int last = isHidden() ? numRows() - 1 : d->lastVisRow;
+ for ( int r = row; r <= last; ++r )
+ updateRowWidgets( r );
+ }
+ delayedUpdateGeometries();
+}
+
+/*! \internal */
+
+void TQTable::updateRowWidgets( int row )
+{
+ for ( int i = 0; i < numCols(); ++i ) {
+ TQWidget *w = cellWidget( row, i );
+ if ( !w )
+ continue;
+ moveChild( w, columnPos( i ), rowPos( row ) );
+ w->resize( columnWidth( i ) - 1, rowHeight( row ) - 1 );
+ }
+}
+
+/*! \internal */
+
+void TQTable::updateColWidgets( int col )
+{
+ for ( int i = 0; i < numRows(); ++i ) {
+ TQWidget *w = cellWidget( i, col );
+ if ( !w )
+ continue;
+ moveChild( w, columnPos( col ), rowPos( i ) );
+ w->resize( columnWidth( col ) - 1, rowHeight( i ) - 1 );
+ }
+}
+
+/*!
+ This function is called when column order is to be changed, i.e.
+ when the user moved the column header \a section from \a fromIndex
+ to \a toIndex.
+
+ If you want to change the column order programmatically, call
+ swapRows() or swapColumns();
+
+ \sa TQHeader::indexChange() rowIndexChanged()
+*/
+
+void TQTable::columnIndexChanged( int, int fromIndex, int toIndex )
+{
+ if ( doSort && lastSortCol == fromIndex && topHeader )
+ topHeader->setSortIndicator( toIndex, topHeader->sortIndicatorOrder() );
+ repaintContents( contentsX(), contentsY(),
+ visibleWidth(), visibleHeight(), FALSE );
+}
+
+/*!
+ This function is called when the order of the rows is to be
+ changed, i.e. the user moved the row header section \a section
+ from \a fromIndex to \a toIndex.
+
+ If you want to change the order programmatically, call swapRows()
+ or swapColumns();
+
+ \sa TQHeader::indexChange() columnIndexChanged()
+*/
+
+void TQTable::rowIndexChanged( int, int, int )
+{
+ repaintContents( contentsX(), contentsY(),
+ visibleWidth(), visibleHeight(), FALSE );
+}
+
+/*!
+ This function is called when the column \a col has been clicked.
+ The default implementation sorts this column if sorting() is TRUE.
+*/
+
+void TQTable::columnClicked( int col )
+{
+ if ( !sorting() )
+ return;
+
+ if ( col == lastSortCol ) {
+ asc = !asc;
+ } else {
+ lastSortCol = col;
+ asc = TRUE;
+ }
+ sortColumn( lastSortCol, asc );
+}
+
+/*!
+ \property TQTable::sorting
+ \brief whether a click on the header of a column sorts that column
+
+ \sa sortColumn()
+*/
+
+void TQTable::setSorting( bool b )
+{
+ doSort = b;
+ if ( topHeader )
+ topHeader->setSortIndicator( b ? lastSortCol : -1 );
+}
+
+bool TQTable::sorting() const
+{
+ return doSort;
+}
+
+static bool inUpdateGeometries = FALSE;
+
+void TQTable::delayedUpdateGeometries()
+{
+ d->geomTimer->start( 0, TRUE );
+}
+
+void TQTable::updateGeometriesSlot()
+{
+ updateGeometries();
+}
+
+/*!
+ This function updates the geometries of the left and top header.
+ You do not normally need to call this function.
+*/
+
+void TQTable::updateGeometries()
+{
+ if ( inUpdateGeometries )
+ return;
+ inUpdateGeometries = TRUE;
+ TQSize ts = tableSize();
+ if ( topHeader->offset() &&
+ ts.width() < topHeader->offset() + topHeader->width() )
+ horizontalScrollBar()->setValue( ts.width() - topHeader->width() );
+ if ( leftHeader->offset() &&
+ ts.height() < leftHeader->offset() + leftHeader->height() )
+ verticalScrollBar()->setValue( ts.height() - leftHeader->height() );
+
+ leftHeader->setGeometry( TQStyle::tqvisualRect( TQRect( frameWidth(), topMargin() + frameWidth(),
+ VERTICALMARGIN, visibleHeight() ), rect() ) );
+ topHeader->setGeometry( TQStyle::tqvisualRect( TQRect(VERTICALMARGIN + frameWidth(), frameWidth(),
+ visibleWidth(), topMargin() ), rect() ) );
+ horizontalScrollBar()->raise();
+ verticalScrollBar()->raise();
+ topHeader->updateStretches();
+ leftHeader->updateStretches();
+ inUpdateGeometries = FALSE;
+}
+
+/*!
+ Returns the width of column \a col.
+
+ \sa setColumnWidth() rowHeight()
+*/
+
+int TQTable::columnWidth( int col ) const
+{
+ return topHeader->sectionSize( col );
+}
+
+/*!
+ Returns the height of row \a row.
+
+ \sa setRowHeight() columnWidth()
+*/
+
+int TQTable::rowHeight( int row ) const
+{
+ return leftHeader->sectionSize( row );
+}
+
+/*!
+ Returns the x-coordinate of the column \a col in content
+ coordinates.
+
+ \sa columnAt() rowPos()
+*/
+
+int TQTable::columnPos( int col ) const
+{
+ return topHeader->sectionPos( col );
+}
+
+/*!
+ Returns the y-coordinate of the row \a row in content coordinates.
+
+ \sa rowAt() columnPos()
+*/
+
+int TQTable::rowPos( int row ) const
+{
+ return leftHeader->sectionPos( row );
+}
+
+/*!
+ Returns the number of the column at position \a x. \a x must be
+ given in content coordinates.
+
+ \sa columnPos() rowAt()
+*/
+
+int TQTable::columnAt( int x ) const
+{
+ return topHeader->sectionAt( x );
+}
+
+/*!
+ Returns the number of the row at position \a y. \a y must be given
+ in content coordinates.
+
+ \sa rowPos() columnAt()
+*/
+
+int TQTable::rowAt( int y ) const
+{
+ return leftHeader->sectionAt( y );
+}
+
+/*!
+ Returns the bounding rectangle of the cell at \a row, \a col in
+ content coordinates.
+*/
+
+TQRect TQTable::cellGeometry( int row, int col ) const
+{
+ TQTableItem *itm = item( row, col );
+
+ if ( !itm || (itm->rowSpan() == 1 && itm->colSpan() == 1) )
+ return TQRect( columnPos( col ), rowPos( row ),
+ columnWidth( col ), rowHeight( row ) );
+
+ while ( row != itm->row() )
+ row--;
+ while ( col != itm->col() )
+ col--;
+
+ TQRect rect( columnPos( col ), rowPos( row ),
+ columnWidth( col ), rowHeight( row ) );
+
+ for ( int r = 1; r < itm->rowSpan(); ++r )
+ rect.setHeight( rect.height() + rowHeight( r + row ) );
+
+ for ( int c = 1; c < itm->colSpan(); ++c )
+ rect.setWidth( rect.width() + columnWidth( c + col ) );
+
+ return rect;
+}
+
+/*!
+ Returns the size of the table.
+
+ This is the same as the coordinates of the bottom-right edge of
+ the last table cell.
+*/
+
+TQSize TQTable::tableSize() const
+{
+ return TQSize( columnPos( numCols() - 1 ) + columnWidth( numCols() - 1 ),
+ rowPos( numRows() - 1 ) + rowHeight( numRows() - 1 ) );
+}
+
+/*!
+ \property TQTable::numRows
+ \brief The number of rows in the table
+
+ \sa numCols
+*/
+
+int TQTable::numRows() const
+{
+ return leftHeader->count();
+}
+
+/*!
+ \property TQTable::numCols
+ \brief The number of columns in the table
+
+ \sa numRows
+*/
+
+int TQTable::numCols() const
+{
+ return topHeader->count();
+}
+
+void TQTable::saveContents( TQPtrVector<TQTableItem> &tmp,
+ TQPtrVector<TQTable::TableWidget> &tmp2)
+{
+ int nCols = numCols();
+ if ( editRow != -1 && editCol != -1 )
+ endEdit( editRow, editCol, FALSE, edMode != Editing );
+ tmp.resize( contents.size() );
+ tmp2.resize( widgets.size() );
+ int i;
+ for ( i = 0; i < (int)tmp.size(); ++i ) {
+ TQTableItem *item = contents[ i ];
+ if ( item && ( item->row() * nCols) + item->col() == i )
+ tmp.insert( i, item );
+ else
+ tmp.insert( i, 0 );
+ }
+ for ( i = 0; i < (int)tmp2.size(); ++i ) {
+ TQWidget *w = widgets[ i ];
+ if ( w )
+ tmp2.insert( i, new TableWidget( w, i / nCols, i % nCols ) );
+ else
+ tmp2.insert( i, 0 );
+ }
+}
+
+void TQTable::updateHeaderAndResizeContents( TQTableHeader *header,
+ int num, int rowCol,
+ int width, bool &updateBefore )
+{
+ updateBefore = rowCol < num;
+ if ( rowCol > num ) {
+ header->TQHeader::resizeArrays( rowCol );
+ header->TQTableHeader::resizeArrays( rowCol );
+ int old = num;
+ clearSelection( FALSE );
+ int i = 0;
+ for ( i = old; i < rowCol; ++i )
+ header->addLabel( TQString::null, width );
+ } else {
+ clearSelection( FALSE );
+ if ( header == leftHeader ) {
+ while ( numRows() > rowCol )
+ header->removeLabel( numRows() - 1 );
+ } else {
+ while ( numCols() > rowCol )
+ header->removeLabel( numCols() - 1 );
+ }
+ }
+
+ contents.setAutoDelete( FALSE );
+ contents.clear();
+ contents.setAutoDelete( TRUE );
+ widgets.setAutoDelete( FALSE );
+ widgets.clear();
+ widgets.setAutoDelete( TRUE );
+ resizeData( numRows() * numCols() );
+
+ // keep numStretches in sync
+ int n = 0;
+ for ( uint i = 0; i < header->stretchable.size(); i++ )
+ n += ( header->stretchable.at(i) & 1 ); // avoid cmp
+ header->numStretches = n;
+}
+
+void TQTable::restoreContents( TQPtrVector<TQTableItem> &tmp,
+ TQPtrVector<TQTable::TableWidget> &tmp2 )
+{
+ int i;
+ int nCols = numCols();
+ for ( i = 0; i < (int)tmp.size(); ++i ) {
+ TQTableItem *it = tmp[ i ];
+ if ( it ) {
+ int idx = ( it->row() * nCols ) + it->col();
+ if ( (uint)idx < contents.size() &&
+ it->row() == idx / nCols && it->col() == idx % nCols ) {
+ contents.insert( idx, it );
+ if ( it->rowSpan() > 1 || it->colSpan() > 1 ) {
+ int ridx, iidx;
+ for ( int irow = 0; irow < it->rowSpan(); irow++ ) {
+ ridx = idx + irow * nCols;
+ for ( int icol = 0; icol < it->colSpan(); icol++ ) {
+ iidx = ridx + icol;
+ if ( idx != iidx && (uint)iidx < contents.size() )
+ contents.insert( iidx, it );
+ }
+ }
+
+ }
+ } else {
+ delete it;
+ }
+ }
+ }
+ for ( i = 0; i < (int)tmp2.size(); ++i ) {
+ TableWidget *w = tmp2[ i ];
+ if ( w ) {
+ int idx = ( w->row * nCols ) + w->col;
+ if ( (uint)idx < widgets.size() &&
+ w->row == idx / nCols && w->col == idx % nCols )
+ widgets.insert( idx, w->wid );
+ else
+ delete w->wid;
+ delete w;
+ }
+ }
+}
+
+void TQTable::finishContentsResze( bool updateBefore )
+{
+ TQRect r( cellGeometry( numRows() - 1, numCols() - 1 ) );
+ resizeContents( r.right() + 1, r.bottom() + 1 );
+ updateGeometries();
+ if ( updateBefore )
+ repaintContents( contentsX(), contentsY(),
+ visibleWidth(), visibleHeight(), TRUE );
+ else
+ repaintContents( contentsX(), contentsY(),
+ visibleWidth(), visibleHeight(), FALSE );
+
+ if ( isRowSelection( selectionMode() ) ) {
+ int r = curRow;
+ curRow = -1;
+ setCurrentCell( r, curCol );
+ }
+}
+
+void TQTable::setNumRows( int r )
+{
+ if ( r < 0 )
+ return;
+
+ if (r < numRows()) {
+ // Removed rows are no longer hidden, and should thus be removed from "hiddenRows"
+ for (int rr = numRows()-1; rr >= r; --rr) {
+ if (d->hiddenRows.tqfind(rr))
+ d->hiddenRows.remove(rr);
+ }
+ }
+
+ fontChange(font()); // tqinvalidate the tqsizeHintCache
+
+ TQPtrVector<TQTableItem> tmp;
+ TQPtrVector<TableWidget> tmp2;
+ saveContents( tmp, tmp2 );
+
+ bool isUpdatesEnabled = leftHeader->isUpdatesEnabled();
+ leftHeader->setUpdatesEnabled( FALSE );
+
+ bool updateBefore;
+ updateHeaderAndResizeContents( leftHeader, numRows(), r, 20, updateBefore );
+
+ int w = fontMetrics().width( TQString::number( r ) + "W" );
+ if ( VERTICALMARGIN > 0 && w > VERTICALMARGIN )
+ setLeftMargin( w );
+
+ restoreContents( tmp, tmp2 );
+
+ leftHeader->calculatePositions();
+ finishContentsResze( updateBefore );
+ leftHeader->setUpdatesEnabled( isUpdatesEnabled );
+ if ( isUpdatesEnabled )
+ leftHeader->update();
+ leftHeader->updateCache();
+ if ( curRow >= numRows() ) {
+ curRow = numRows() - 1;
+ if ( curRow < 0 )
+ curCol = -1;
+ else
+ repaintCell( curRow, curCol );
+ }
+
+ if ( curRow > numRows() )
+ curRow = numRows();
+}
+
+void TQTable::setNumCols( int c )
+{
+ if ( c < 0 )
+ return;
+
+ if (c < numCols()) {
+ // Removed columns are no longer hidden, and should thus be removed from "hiddenCols"
+ for (int cc = numCols()-1; cc >= c; --cc) {
+ if (d->hiddenCols.tqfind(cc))
+ d->hiddenCols.remove(cc);
+ }
+ }
+
+ fontChange(font()); // tqinvalidate the tqsizeHintCache
+
+ TQPtrVector<TQTableItem> tmp;
+ TQPtrVector<TableWidget> tmp2;
+ saveContents( tmp, tmp2 );
+
+ bool isUpdatesEnabled = topHeader->isUpdatesEnabled();
+ topHeader->setUpdatesEnabled( FALSE );
+
+ bool updateBefore;
+ updateHeaderAndResizeContents( topHeader, numCols(), c, 100, updateBefore );
+
+ restoreContents( tmp, tmp2 );
+
+ topHeader->calculatePositions();
+ finishContentsResze( updateBefore );
+ topHeader->setUpdatesEnabled( isUpdatesEnabled );
+ if ( isUpdatesEnabled )
+ topHeader->update();
+ topHeader->updateCache();
+ if ( curCol >= numCols() ) {
+ curCol = numCols() - 1;
+ if ( curCol < 0 )
+ curRow = -1;
+ else
+ repaintCell( curRow, curCol );
+ }
+}
+
+/*! Sets the section labels of the verticalHeader() to \a labels */
+
+void TQTable::setRowLabels( const TQStringList &labels )
+{
+ leftHeader->setLabels(labels);
+}
+
+/*! Sets the section labels of the horizontalHeader() to \a labels */
+
+void TQTable::setColumnLabels( const TQStringList &labels )
+{
+ topHeader->setLabels(labels);
+}
+
+/*!
+ This function returns the widget which should be used as an editor
+ for the contents of the cell at \a row, \a col.
+
+ If \a initFromCell is TRUE, the editor is used to edit the current
+ contents of the cell (so the editor widget should be initialized
+ with this content). If \a initFromCell is FALSE, the content of
+ the cell is tqreplaced with the new content which the user entered
+ into the widget created by this function.
+
+ The default functionality is as follows: if \a initFromCell is
+ TRUE or the cell has a TQTableItem and the table item's
+ TQTableItem::isReplaceable() is FALSE then the cell is asked to
+ create an appropriate editor (using TQTableItem::createEditor()).
+ Otherwise a TQLineEdit is used as the editor.
+
+ If you want to create your own editor for certain cells, implement
+ a custom TQTableItem subclass and reimplement
+ TQTableItem::createEditor().
+
+ If you are not using \l{TQTableItem}s and you don't want to use a
+ TQLineEdit as the default editor, subclass TQTable and reimplement
+ this function with code like this:
+ \code
+ TQTableItem *i = item( row, col );
+ if ( initFromCell || ( i && !i->isReplaceable() ) )
+ // If we had a TQTableItem ask the base class to create the editor
+ return TQTable::createEditor( row, col, initFromCell );
+ else
+ return ...(create your own editor)
+ \endcode
+ Ownership of the editor widget is transferred to the caller.
+
+ If you reimplement this function return 0 for read-only cells. You
+ will need to reimplement setCellContentFromEditor() to retrieve
+ the data the user entered.
+
+ \sa TQTableItem::createEditor()
+*/
+
+TQWidget *TQTable::createEditor( int row, int col, bool initFromCell ) const
+{
+ if ( isReadOnly() || isRowReadOnly( row ) || isColumnReadOnly( col ) )
+ return 0;
+
+ TQWidget *e = 0;
+
+ // the current item in the cell should be edited if possible
+ TQTableItem *i = item( row, col );
+ if ( initFromCell || ( i && !i->isReplaceable() ) ) {
+ if ( i ) {
+ if ( i->editType() == TQTableItem::Never )
+ return 0;
+
+ e = i->createEditor();
+ if ( !e )
+ return 0;
+ }
+ }
+
+ // no contents in the cell yet, so open the default editor
+ if ( !e ) {
+ e = new TQLineEdit( viewport(), "qt_lineeditor" );
+ ( (TQLineEdit*)e )->setFrame( FALSE );
+ }
+
+ return e;
+}
+
+/*!
+ This function is called to start in-place editing of the cell at
+ \a row, \a col. Editing is achieved by creating an editor
+ (createEditor() is called) and setting the cell's editor with
+ setCellWidget() to the newly created editor. (After editing is
+ complete endEdit() will be called to tqreplace the cell's content
+ with the editor's content.) If \a tqreplace is TRUE the editor will
+ start empty; otherwise it will be initialized with the cell's
+ content (if any), i.e. the user will be modifying the original
+ cell content.
+
+ \sa endEdit()
+*/
+
+TQWidget *TQTable::beginEdit( int row, int col, bool tqreplace )
+{
+ if ( isReadOnly() || isRowReadOnly( row ) || isColumnReadOnly( col ) )
+ return 0;
+ if ( row < 0 || row >= numRows() || col < 0 || col >= numCols() )
+ return 0;
+
+ TQTableItem *itm = item( row, col );
+ if ( itm && !itm->isEnabled() )
+ return 0;
+ if ( cellWidget( row, col ) )
+ return 0;
+ ensureCellVisible( row, col );
+ TQWidget *e = createEditor( row, col, !tqreplace );
+ if ( !e )
+ return 0;
+ setCellWidget( row, col, e );
+ e->setActiveWindow();
+ e->setFocus();
+ updateCell( row, col );
+ return e;
+}
+
+/*!
+ This function is called when in-place editing of the cell at \a
+ row, \a col is requested to stop.
+
+ If the cell is not being edited or \a accept is FALSE the function
+ returns and the cell's contents are left unchanged.
+
+ If \a accept is TRUE the content of the editor must be transferred
+ to the relevant cell. If \a tqreplace is TRUE the current content of
+ this cell should be tqreplaced by the content of the editor (this
+ means removing the current TQTableItem of the cell and creating a
+ new one for the cell). Otherwise (if possible) the content of the
+ editor should just be set to the existing TQTableItem of this cell.
+
+ setCellContentFromEditor() is called to tqreplace the contents of
+ the cell with the contents of the cell's editor.
+
+ Finally clearCellWidget() is called to remove the editor widget.
+
+ \sa setCellContentFromEditor(), beginEdit()
+*/
+
+void TQTable::endEdit( int row, int col, bool accept, bool tqreplace )
+{
+ TQWidget *editor = cellWidget( row, col );
+ if ( !editor )
+ return;
+
+ if ( !accept ) {
+ if ( row == editRow && col == editCol )
+ setEditMode( NotEditing, -1, -1 );
+ clearCellWidget( row, col );
+ updateCell( row, col );
+ viewport()->setFocus();
+ updateCell( row, col );
+ return;
+ }
+
+ TQTableItem *i = item( row, col );
+ TQString oldContent;
+ if ( i )
+ oldContent = i->text();
+
+ if ( !i || tqreplace ) {
+ setCellContentFromEditor( row, col );
+ i = item( row, col );
+ } else {
+ i->setContentFromEditor( editor );
+ }
+
+ if ( row == editRow && col == editCol )
+ setEditMode( NotEditing, -1, -1 );
+
+ viewport()->setFocus();
+ updateCell( row, col );
+
+ if (!i || (oldContent != i->text()))
+ emit valueChanged( row, col );
+
+ clearCellWidget( row, col );
+}
+
+/*!
+ This function is called to tqreplace the contents of the cell at \a
+ row, \a col with the contents of the cell's editor.
+
+ If there already exists a TQTableItem for the cell,
+ it calls TQTableItem::setContentFromEditor() on this TQTableItem.
+
+ If, for example, you want to create different \l{TQTableItem}s
+ depending on the contents of the editor, you might reimplement
+ this function.
+
+ If you want to work without \l{TQTableItem}s, you will need to
+ reimplement this function to save the data the user entered into
+ your data structure. (See the notes on large tables.)
+
+ \sa TQTableItem::setContentFromEditor() createEditor()
+*/
+
+void TQTable::setCellContentFromEditor( int row, int col )
+{
+ TQWidget *editor = cellWidget( row, col );
+ if ( !editor )
+ return;
+
+ TQTableItem *i = item( row, col );
+ if ( i ) {
+ i->setContentFromEditor( editor );
+ } else {
+ TQLineEdit *le = ::tqqt_cast<TQLineEdit*>(editor);
+ if ( le )
+ setText( row, col, le->text() );
+ }
+}
+
+/*!
+ Returns TRUE if the \l EditMode is \c Editing or \c Replacing;
+ otherwise (i.e. the \l EditMode is \c NotEditing) returns FALSE.
+
+ \sa TQTable::EditMode
+*/
+
+bool TQTable::isEditing() const
+{
+ return edMode != NotEditing;
+}
+
+/*!
+ Returns the current edit mode
+
+ \sa TQTable::EditMode
+*/
+
+TQTable::EditMode TQTable::editMode() const
+{
+ return edMode;
+}
+
+/*!
+ Returns the current edited row
+*/
+
+int TQTable::currEditRow() const
+{
+ return editRow;
+}
+
+/*!
+ Returns the current edited column
+*/
+
+int TQTable::currEditCol() const
+{
+ return editCol;
+}
+
+/*!
+ Returns a single integer which identifies a particular \a row and \a
+ col by mapping the 2D table to a 1D array.
+
+ This is useful, for example, if you have a sparse table and want to
+ use a TQIntDict to map integers to the cells that are used.
+*/
+
+int TQTable::indexOf( int row, int col ) const
+{
+ return ( row * numCols() ) + col;
+}
+
+/*! \internal
+*/
+
+void TQTable::repaintSelections( TQTableSelection *oldSelection,
+ TQTableSelection *newSelection,
+ bool updateVertical, bool updateHorizontal )
+{
+ if ( !oldSelection && !newSelection )
+ return;
+ if ( oldSelection && newSelection && *oldSelection == *newSelection )
+ return;
+ if ( oldSelection && !oldSelection->isActive() )
+ oldSelection = 0;
+
+ bool optimizeOld = FALSE;
+ bool optimizeNew = FALSE;
+
+ TQRect old;
+ if ( oldSelection )
+ old = rangeGeometry( oldSelection->topRow(),
+ oldSelection->leftCol(),
+ oldSelection->bottomRow(),
+ oldSelection->rightCol(),
+ optimizeOld );
+ else
+ old = TQRect( 0, 0, 0, 0 );
+
+ TQRect cur;
+ if ( newSelection )
+ cur = rangeGeometry( newSelection->topRow(),
+ newSelection->leftCol(),
+ newSelection->bottomRow(),
+ newSelection->rightCol(),
+ optimizeNew );
+ else
+ cur = TQRect( 0, 0, 0, 0 );
+ int i;
+
+ if ( !optimizeOld || !optimizeNew ||
+ old.width() > SHRT_MAX || old.height() > SHRT_MAX ||
+ cur.width() > SHRT_MAX || cur.height() > SHRT_MAX ) {
+ TQRect rr = cur.unite( old );
+ repaintContents( rr, FALSE );
+ } else {
+ old = TQRect( contentsToViewport2( old.topLeft() ), old.size() );
+ cur = TQRect( contentsToViewport2( cur.topLeft() ), cur.size() );
+ TQRegion r1( old );
+ TQRegion r2( cur );
+ TQRegion r3 = r1.subtract( r2 );
+ TQRegion r4 = r2.subtract( r1 );
+
+ for ( i = 0; i < (int)r3.rects().count(); ++i ) {
+ TQRect r( r3.rects()[ i ] );
+ r = TQRect( viewportToContents2( r.topLeft() ), r.size() );
+ repaintContents( r, FALSE );
+ }
+ for ( i = 0; i < (int)r4.rects().count(); ++i ) {
+ TQRect r( r4.rects()[ i ] );
+ r = TQRect( viewportToContents2( r.topLeft() ), r.size() );
+ repaintContents( r, FALSE );
+ }
+ }
+
+ int top, left, bottom, right;
+ {
+ int oldTopRow = oldSelection ? oldSelection->topRow() : numRows() - 1;
+ int newTopRow = newSelection ? newSelection->topRow() : numRows() - 1;
+ top = TQMIN(oldTopRow, newTopRow);
+ }
+
+ {
+ int oldLeftCol = oldSelection ? oldSelection->leftCol() : numCols() - 1;
+ int newLeftCol = newSelection ? newSelection->leftCol() : numCols() - 1;
+ left = TQMIN(oldLeftCol, newLeftCol);
+ }
+
+ {
+ int oldBottomRow = oldSelection ? oldSelection->bottomRow() : 0;
+ int newBottomRow = newSelection ? newSelection->bottomRow() : 0;
+ bottom = TQMAX(oldBottomRow, newBottomRow);
+ }
+
+ {
+ int oldRightCol = oldSelection ? oldSelection->rightCol() : 0;
+ int newRightCol = newSelection ? newSelection->rightCol() : 0;
+ right = TQMAX(oldRightCol, newRightCol);
+ }
+
+ if ( updateHorizontal && numCols() > 0 && left >= 0 && !isRowSelection( selectionMode() ) ) {
+ register int *s = &topHeader->states.data()[left];
+ for ( i = left; i <= right; ++i ) {
+ if ( !isColumnSelected( i ) )
+ *s = TQTableHeader::Normal;
+ else if ( isColumnSelected( i, TRUE ) )
+ *s = TQTableHeader::Selected;
+ else
+ *s = TQTableHeader::Bold;
+ ++s;
+ }
+ topHeader->tqrepaint( FALSE );
+ }
+
+ if ( updateVertical && numRows() > 0 && top >= 0 ) {
+ register int *s = &leftHeader->states.data()[top];
+ for ( i = top; i <= bottom; ++i ) {
+ if ( !isRowSelected( i ) )
+ *s = TQTableHeader::Normal;
+ else if ( isRowSelected( i, TRUE ) )
+ *s = TQTableHeader::Selected;
+ else
+ *s = TQTableHeader::Bold;
+ ++s;
+ }
+ leftHeader->tqrepaint( FALSE );
+ }
+}
+
+/*!
+ Repaints all selections
+*/
+
+void TQTable::repaintSelections()
+{
+ if ( selections.isEmpty() )
+ return;
+
+ TQRect r;
+ for ( TQTableSelection *s = selections.first(); s; s = selections.next() ) {
+ bool b;
+ r = r.unite( rangeGeometry( s->topRow(),
+ s->leftCol(),
+ s->bottomRow(),
+ s->rightCol(), b ) );
+ }
+
+ repaintContents( r, FALSE );
+}
+
+/*!
+ Clears all selections and repaints the appropriate regions if \a
+ tqrepaint is TRUE.
+
+ \sa removeSelection()
+*/
+
+void TQTable::clearSelection( bool tqrepaint )
+{
+ if ( selections.isEmpty() )
+ return;
+ bool needRepaint = !selections.isEmpty();
+
+ TQRect r;
+ for ( TQTableSelection *s = selections.first(); s; s = selections.next() ) {
+ bool b;
+ r = r.unite( rangeGeometry( s->topRow(),
+ s->leftCol(),
+ s->bottomRow(),
+ s->rightCol(), b ) );
+ }
+
+ currentSel = 0;
+ selections.clear();
+
+ if ( needRepaint && tqrepaint )
+ repaintContents( r, FALSE );
+
+ leftHeader->setSectionStateToAll( TQTableHeader::Normal );
+ leftHeader->tqrepaint( FALSE );
+ if ( !isRowSelection( selectionMode() ) ) {
+ topHeader->setSectionStateToAll( TQTableHeader::Normal );
+ topHeader->tqrepaint( FALSE );
+ }
+ topHeader->setSectionState( curCol, TQTableHeader::Bold );
+ leftHeader->setSectionState( curRow, TQTableHeader::Bold );
+ emit selectionChanged();
+}
+
+/*! \internal
+*/
+
+TQRect TQTable::rangeGeometry( int topRow, int leftCol,
+ int bottomRow, int rightCol, bool &optimize )
+{
+ topRow = TQMAX( topRow, rowAt( contentsY() ) );
+ leftCol = TQMAX( leftCol, columnAt( contentsX() ) );
+ int ra = rowAt( contentsY() + visibleHeight() );
+ if ( ra != -1 )
+ bottomRow = TQMIN( bottomRow, ra );
+ int ca = columnAt( contentsX() + visibleWidth() );
+ if ( ca != -1 )
+ rightCol = TQMIN( rightCol, ca );
+ optimize = TRUE;
+ TQRect rect;
+ for ( int r = topRow; r <= bottomRow; ++r ) {
+ for ( int c = leftCol; c <= rightCol; ++c ) {
+ rect = rect.unite( cellGeometry( r, c ) );
+ TQTableItem *i = item( r, c );
+ if ( i && ( i->rowSpan() > 1 || i->colSpan() > 1 ) )
+ optimize = FALSE;
+ }
+ }
+ return rect;
+}
+
+/*!
+ This function is called to activate the next cell if in-place
+ editing was finished by pressing the Enter key.
+
+ The default behaviour is to move from top to bottom, i.e. move to
+ the cell beneath the cell being edited. Reimplement this function
+ if you want different behaviour, e.g. moving from left to right.
+*/
+
+void TQTable::activateNextCell()
+{
+ int firstRow = 0;
+ while ( d->hiddenRows.tqfind( firstRow ) )
+ firstRow++;
+ int firstCol = 0;
+ while ( d->hiddenCols.tqfind( firstCol ) )
+ firstCol++;
+ int nextRow = curRow;
+ int nextCol = curCol;
+ while ( d->hiddenRows.tqfind( ++nextRow ) );
+ if ( nextRow >= numRows() ) {
+ nextRow = firstRow;
+ while ( d->hiddenCols.tqfind( ++nextCol ) );
+ if ( nextCol >= numCols() )
+ nextCol = firstCol;
+ }
+
+ if ( !currentSel || !currentSel->isActive() ||
+ ( currentSel->leftCol() == currentSel->rightCol() &&
+ currentSel->topRow() == currentSel->bottomRow() ) ) {
+ clearSelection();
+ setCurrentCell( nextRow, nextCol );
+ } else {
+ if ( curRow < currentSel->bottomRow() )
+ setCurrentCell( nextRow, curCol );
+ else if ( curCol < currentSel->rightCol() )
+ setCurrentCell( currentSel->topRow(), nextCol );
+ else
+ setCurrentCell( currentSel->topRow(), currentSel->leftCol() );
+ }
+
+}
+
+/*! \internal
+*/
+
+void TQTable::fixRow( int &row, int y )
+{
+ if ( row == -1 ) {
+ if ( y < 0 )
+ row = 0;
+ else
+ row = numRows() - 1;
+ }
+}
+
+/*! \internal
+*/
+
+void TQTable::fixCol( int &col, int x )
+{
+ if ( col == -1 ) {
+ if ( x < 0 )
+ col = 0;
+ else
+ col = numCols() - 1;
+ }
+}
+
+struct SortableTableItem
+{
+ TQTableItem *item;
+};
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+#ifdef TQ_OS_TEMP
+static int _cdecl cmpTableItems( const void *n1, const void *n2 )
+#else
+static int cmpTableItems( const void *n1, const void *n2 )
+#endif
+{
+ if ( !n1 || !n2 )
+ return 0;
+
+ SortableTableItem *i1 = (SortableTableItem *)n1;
+ SortableTableItem *i2 = (SortableTableItem *)n2;
+
+ return i1->item->key().localeAwareCompare( i2->item->key() );
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+/*!
+ Sorts column \a col. If \a ascending is TRUE the sort is in
+ ascending order, otherwise the sort is in descending order.
+
+ If \a wholeRows is TRUE, entire rows are sorted using swapRows();
+ otherwise only cells in the column are sorted using swapCells().
+
+ Note that if you are not using TQTableItems you will need to
+ reimplement swapRows() and swapCells(). (See the notes on large
+ tables.)
+
+ \sa swapRows()
+*/
+
+void TQTable::sortColumn( int col, bool ascending, bool wholeRows )
+{
+ int filledRows = 0, i;
+ for ( i = 0; i < numRows(); ++i ) {
+ TQTableItem *itm = item( i, col );
+ if ( itm )
+ filledRows++;
+ }
+
+ if ( !filledRows )
+ return;
+
+ SortableTableItem *items = new SortableTableItem[ filledRows ];
+ int j = 0;
+ for ( i = 0; i < numRows(); ++i ) {
+ TQTableItem *itm = item( i, col );
+ if ( !itm )
+ continue;
+ items[ j++ ].item = itm;
+ }
+
+ qsort( items, filledRows, sizeof( SortableTableItem ), cmpTableItems );
+
+ bool updatesEnabled = isUpdatesEnabled();
+ setUpdatesEnabled( FALSE );
+ for ( i = 0; i < numRows(); ++i ) {
+ if ( i < filledRows ) {
+ if ( ascending ) {
+ if ( items[ i ].item->row() == i )
+ continue;
+ if ( wholeRows )
+ swapRows( items[ i ].item->row(), i );
+ else
+ swapCells( items[ i ].item->row(), col, i, col );
+ } else {
+ if ( items[ i ].item->row() == filledRows - i - 1 )
+ continue;
+ if ( wholeRows )
+ swapRows( items[ i ].item->row(), filledRows - i - 1 );
+ else
+ swapCells( items[ i ].item->row(), col,
+ filledRows - i - 1, col );
+ }
+ }
+ }
+ setUpdatesEnabled( updatesEnabled );
+ if ( topHeader )
+ topHeader->setSortIndicator( col, ascending ? TQt::Ascending : TQt::Descending );
+
+ if ( !wholeRows )
+ repaintContents( columnPos( col ), contentsY(),
+ columnWidth( col ), visibleHeight(), FALSE );
+ else
+ repaintContents( contentsX(), contentsY(),
+ visibleWidth(), visibleHeight(), FALSE );
+
+ delete [] items;
+}
+
+/*!
+ Hides row \a row.
+
+ \sa showRow() hideColumn()
+*/
+
+void TQTable::hideRow( int row )
+{
+ if ( d->hiddenRows.tqfind( row ) )
+ return;
+ d->hiddenRows.tqreplace( row, new int( leftHeader->sectionSize( row ) ) );
+ leftHeader->resizeSection( row, 0 );
+ leftHeader->setResizeEnabled( FALSE, row );
+ if ( isRowStretchable(row) )
+ leftHeader->numStretches--;
+ rowHeightChanged( row );
+ if ( curRow == row ) {
+ int r = curRow;
+ int c = curCol;
+ int k = ( r >= numRows() - 1 ? Qt::Key_Up : Qt::Key_Down );
+ fixCell( r, c, k );
+ if ( numRows() > 0 )
+ setCurrentCell( r, c );
+ }
+}
+
+/*!
+ Hides column \a col.
+
+ \sa showColumn() hideRow()
+*/
+
+void TQTable::hideColumn( int col )
+{
+ if ( !numCols() || d->hiddenCols.tqfind( col ) )
+ return;
+ d->hiddenCols.tqreplace( col, new int( topHeader->sectionSize( col ) ) );
+ topHeader->resizeSection( col, 0 );
+ topHeader->setResizeEnabled( FALSE, col );
+ if ( isColumnStretchable(col) )
+ topHeader->numStretches--;
+ columnWidthChanged( col );
+ if ( curCol == col ) {
+ int r = curRow;
+ int c = curCol;
+ int k = ( c >= numCols() - 1 ? Qt::Key_Left : Qt::Key_Right );
+ fixCell( r, c, k );
+ if ( numCols() > 0 )
+ setCurrentCell( r, c );
+ }
+}
+
+/*!
+ Shows row \a row.
+
+ \sa hideRow() showColumn()
+*/
+
+void TQTable::showRow( int row )
+{
+ int *h = d->hiddenRows.tqfind( row );
+ if ( h ) {
+ int rh = *h;
+ d->hiddenRows.remove( row );
+ setRowHeight( row, rh );
+ if ( isRowStretchable(row) )
+ leftHeader->numStretches++;
+ } else if ( rowHeight( row ) == 0 ) {
+ setRowHeight( row, 20 );
+ }
+ leftHeader->setResizeEnabled( TRUE, row );
+}
+
+/*!
+ Shows column \a col.
+
+ \sa hideColumn() showRow()
+*/
+
+void TQTable::showColumn( int col )
+{
+ int *w = d->hiddenCols.tqfind( col );
+ if ( w ) {
+ int cw = *w;
+ d->hiddenCols.remove( col );
+ setColumnWidth( col, cw );
+ if ( isColumnStretchable( col ) )
+ topHeader->numStretches++;
+ } else if ( columnWidth( col ) == 0 ) {
+ setColumnWidth( col, 20 );
+ }
+ topHeader->setResizeEnabled( TRUE, col );
+}
+
+/*!
+ Returns TRUE if row \a row is hidden; otherwise returns
+ FALSE.
+
+ \sa hideRow(), isColumnHidden()
+*/
+bool TQTable::isRowHidden( int row ) const
+{
+ return d->hiddenRows.tqfind( row );
+}
+
+/*!
+ Returns TRUE if column \a col is hidden; otherwise returns
+ FALSE.
+
+ \sa hideColumn(), isRowHidden()
+*/
+bool TQTable::isColumnHidden( int col ) const
+{
+ return d->hiddenCols.tqfind( col );
+}
+
+/*!
+ Resizes column \a col to be \a w pixels wide.
+
+ \sa columnWidth() setRowHeight()
+*/
+
+void TQTable::setColumnWidth( int col, int w )
+{
+ int *ow = d->hiddenCols.tqfind( col );
+ if ( ow ) {
+ d->hiddenCols.tqreplace( col, new int( w ) );
+ } else {
+ topHeader->resizeSection( col, w );
+ columnWidthChanged( col );
+ }
+}
+
+/*!
+ Resizes row \a row to be \a h pixels high.
+
+ \sa rowHeight() setColumnWidth()
+*/
+
+void TQTable::setRowHeight( int row, int h )
+{
+ int *oh = d->hiddenRows.tqfind( row );
+ if ( oh ) {
+ d->hiddenRows.tqreplace( row, new int( h ) );
+ } else {
+ leftHeader->resizeSection( row, h );
+ rowHeightChanged( row );
+ }
+}
+
+/*!
+ Resizes column \a col so that the column width is wide enough to
+ display the widest item the column tqcontains.
+
+ \sa adjustRow()
+*/
+
+void TQTable::adjustColumn( int col )
+{
+ int w;
+ if ( currentColumn() == col ) {
+ TQFont f = font();
+ f.setBold(true);
+ w = topHeader->sectionSizeHint( col, TQFontMetrics(f) ).width();
+ } else {
+ w = topHeader->sectionSizeHint( col, fontMetrics() ).width();
+ }
+ if ( topHeader->iconSet( col ) )
+ w += topHeader->iconSet( col )->pixmap().width();
+ w = TQMAX( w, 20 );
+ for ( int i = 0; i < numRows(); ++i ) {
+ TQTableItem *itm = item( i, col );
+ if ( !itm ) {
+ TQWidget *widget = cellWidget( i, col );
+ if ( widget )
+ w = TQMAX( w, widget->tqsizeHint().width() );
+ } else {
+ if ( itm->colSpan() > 1 )
+ w = TQMAX( w, itm->tqsizeHint().width() / itm->colSpan() );
+ else
+ w = TQMAX( w, itm->tqsizeHint().width() );
+ }
+ }
+ w = TQMAX( w, TQApplication::globalStrut().width() );
+ setColumnWidth( col, w );
+}
+
+/*!
+ Resizes row \a row so that the row height is tall enough to
+ display the tallest item the row tqcontains.
+
+ \sa adjustColumn()
+*/
+
+void TQTable::adjustRow( int row )
+{
+ int h = 20;
+ h = TQMAX( h, leftHeader->sectionSizeHint( row, leftHeader->fontMetrics() ).height() );
+ if ( leftHeader->iconSet( row ) )
+ h = TQMAX( h, leftHeader->iconSet( row )->pixmap().height() );
+ for ( int i = 0; i < numCols(); ++i ) {
+ TQTableItem *itm = item( row, i );
+ if ( !itm ) {
+ TQWidget *widget = cellWidget( row, i );
+ if ( widget )
+ h = TQMAX( h, widget->tqsizeHint().height() );
+ } else {
+ if ( itm->rowSpan() > 1 )
+ h = TQMAX( h, itm->tqsizeHint().height() / itm->rowSpan() );
+ else
+ h = TQMAX( h, itm->tqsizeHint().height() );
+ }
+ }
+ h = TQMAX( h, TQApplication::globalStrut().height() );
+ setRowHeight( row, h );
+}
+
+/*!
+ If \a stretch is TRUE, column \a col is set to be stretchable;
+ otherwise column \a col is set to be unstretchable.
+
+ If the table widget's width decreases or increases stretchable
+ columns will grow narrower or wider to fit the space available as
+ completely as possible. The user cannot manually resize stretchable
+ columns.
+
+ \sa isColumnStretchable() setRowStretchable() adjustColumn()
+*/
+
+void TQTable::setColumnStretchable( int col, bool stretch )
+{
+ topHeader->setSectionStretchable( col, stretch );
+
+ if ( stretch && d->hiddenCols.tqfind(col) )
+ topHeader->numStretches--;
+}
+
+/*!
+ If \a stretch is TRUE, row \a row is set to be stretchable;
+ otherwise row \a row is set to be unstretchable.
+
+ If the table widget's height decreases or increases stretchable
+ rows will grow shorter or taller to fit the space available as
+ completely as possible. The user cannot manually resize
+ stretchable rows.
+
+ \sa isRowStretchable() setColumnStretchable()
+*/
+
+void TQTable::setRowStretchable( int row, bool stretch )
+{
+ leftHeader->setSectionStretchable( row, stretch );
+
+ if ( stretch && d->hiddenRows.tqfind(row) )
+ leftHeader->numStretches--;
+}
+
+/*!
+ Returns TRUE if column \a col is stretchable; otherwise returns
+ FALSE.
+
+ \sa setColumnStretchable() isRowStretchable()
+*/
+
+bool TQTable::isColumnStretchable( int col ) const
+{
+ return topHeader->isSectionStretchable( col );
+}
+
+/*!
+ Returns TRUE if row \a row is stretchable; otherwise returns
+ FALSE.
+
+ \sa setRowStretchable() isColumnStretchable()
+*/
+
+bool TQTable::isRowStretchable( int row ) const
+{
+ return leftHeader->isSectionStretchable( row );
+}
+
+/*!
+ Takes the table item \a i out of the table. This function does \e
+ not delete the table item. You must either delete the table item
+ yourself or put it into a table (using setItem()) which will then
+ take ownership of it.
+
+ Use this function if you want to move an item from one cell in a
+ table to another, or to move an item from one table to another,
+ reinserting the item with setItem().
+
+ If you want to exchange two cells use swapCells().
+*/
+
+void TQTable::takeItem( TQTableItem *i )
+{
+ if ( !i )
+ return;
+ TQRect rect = cellGeometry( i->row(), i->col() );
+ contents.setAutoDelete( FALSE );
+ int bottom = i->row() + i->rowSpan();
+ if ( bottom > numRows() )
+ bottom = numRows();
+ int right = i->col() + i->colSpan();
+ if ( right > numCols() )
+ right = numCols();
+ for ( int r = i->row(); r < bottom; ++r ) {
+ for ( int c = i->col(); c < right; ++c )
+ contents.remove( indexOf( r, c ) );
+ }
+ contents.setAutoDelete( TRUE );
+ repaintContents( rect, FALSE );
+ int orow = i->row();
+ int ocol = i->col();
+ i->setRow( -1 );
+ i->setCol( -1 );
+ i->updateEditor( orow, ocol );
+ i->t = 0;
+}
+
+/*!
+ Sets the widget \a e to the cell at \a row, \a col and takes care of
+ placing and resizing the widget when the cell tqgeometry changes.
+
+ By default widgets are inserted into a vector with numRows() *
+ numCols() elements. In very large tables you will probably want to
+ store the widgets in a data structure that consumes less memory (see
+ the notes on large tables). To support the use of your own data
+ structure this function calls insertWidget() to add the widget to
+ the internal data structure. To use your own data structure
+ reimplement insertWidget(), cellWidget() and clearCellWidget().
+
+ Cell widgets are created dynamically with the \c new operator. The
+ cell widgets are destroyed automatically once the table is
+ destroyed; the table takes ownership of the widget when using
+ setCellWidget.
+
+*/
+
+void TQTable::setCellWidget( int row, int col, TQWidget *e )
+{
+ if ( !e || row >= numRows() || col >= numCols() )
+ return;
+
+ TQWidget *w = cellWidget( row, col );
+ if ( w && row == editRow && col == editCol )
+ endEdit( editRow, editCol, FALSE, edMode != Editing );
+
+ e->installEventFilter( this );
+ clearCellWidget( row, col );
+ if ( e->tqparent() != TQT_TQOBJECT(viewport()) )
+ e->reparent( viewport(), TQPoint( 0,0 ) );
+ TQTableItem *itm = item(row, col);
+ if (itm && itm->row() >= 0 && itm->col() >= 0) { // get the correct row and col if the item is spanning
+ row = itm->row();
+ col = itm->col();
+ }
+ insertWidget( row, col, e );
+ TQRect cr = cellGeometry( row, col );
+ e->resize( cr.size() );
+ moveChild( e, cr.x(), cr.y() );
+ e->show();
+}
+
+/*!
+ Inserts widget \a w at \a row, \a col into the internal
+ data structure. See the documentation of setCellWidget() for
+ further details.
+
+ If you don't use \l{TQTableItem}s you may need to reimplement this
+ function: see the notes on large tables.
+*/
+
+void TQTable::insertWidget( int row, int col, TQWidget *w )
+{
+ if ( row < 0 || col < 0 || row > numRows() - 1 || col > numCols() - 1 )
+ return;
+
+ if ( (int)widgets.size() != numRows() * numCols() )
+ widgets.resize( numRows() * numCols() );
+
+ widgets.insert( indexOf( row, col ), w );
+}
+
+/*!
+ Returns the widget that has been set for the cell at \a row, \a
+ col, or 0 if no widget has been set.
+
+ If you don't use \l{TQTableItem}s you may need to reimplement this
+ function: see the notes on large tables.
+
+ \sa clearCellWidget() setCellWidget()
+*/
+
+TQWidget *TQTable::cellWidget( int row, int col ) const
+{
+ if ( row < 0 || col < 0 || row > numRows() - 1 || col > numCols() - 1 )
+ return 0;
+
+ if ( (int)widgets.size() != numRows() * numCols() )
+ ( (TQTable*)this )->widgets.resize( numRows() * numCols() );
+
+ return widgets[ indexOf( row, col ) ];
+}
+
+/*!
+ Removes the widget (if there is one) set for the cell at \a row,
+ \a col.
+
+ If you don't use \l{TQTableItem}s you may need to reimplement this
+ function: see the notes on large tables.
+
+ This function deletes the widget at \a row, \a col. Note that the
+ widget is not deleted immediately; instead TQObject::deleteLater()
+ is called on the widget to avoid problems with timing issues.
+
+ \sa cellWidget() setCellWidget()
+*/
+
+void TQTable::clearCellWidget( int row, int col )
+{
+ if ( row < 0 || col < 0 || row > numRows() - 1 || col > numCols() - 1 )
+ return;
+
+ if ( (int)widgets.size() != numRows() * numCols() )
+ widgets.resize( numRows() * numCols() );
+
+ TQWidget *w = cellWidget( row, col );
+ if ( w ) {
+ w->removeEventFilter( this );
+ w->deleteLater();
+ }
+ widgets.setAutoDelete( FALSE );
+ widgets.remove( indexOf( row, col ) );
+ widgets.setAutoDelete( TRUE );
+}
+
+/*!
+ \fn void TQTable::dropped ( TQDropEvent * e )
+
+ This signal is emitted when a drop event occurred on the table.
+
+ \a e tqcontains information about the drop.
+*/
+
+/*!
+ If \a b is TRUE, the table starts a drag (see dragObject()) when
+ the user presses and moves the mouse on a selected cell.
+*/
+
+void TQTable::setDragEnabled( bool b )
+{
+ dEnabled = b;
+}
+
+/*!
+ If this function returns TRUE, the table supports dragging.
+
+ \sa setDragEnabled();
+*/
+
+bool TQTable::dragEnabled() const
+{
+ return dEnabled;
+}
+
+/*!
+ Inserts \a count empty rows at row \a row. Also clears the selection(s).
+
+ \sa insertColumns() removeRow()
+*/
+
+void TQTable::insertRows( int row, int count )
+{
+ // special case, so a call like insertRow( currentRow(), 1 ) also
+ // works, when we have 0 rows and currentRow() is -1
+ if ( row == -1 && curRow == -1 )
+ row = 0;
+ if ( row < 0 || count <= 0 )
+ return;
+
+ if ( curRow >= row && curRow < row + count )
+ curRow = row + count;
+
+ --row;
+ if ( row >= numRows() )
+ return;
+
+ bool updatesEnabled = isUpdatesEnabled();
+ setUpdatesEnabled( FALSE );
+ bool leftHeaderUpdatesEnabled = leftHeader->isUpdatesEnabled();
+ leftHeader->setUpdatesEnabled( FALSE );
+ int oldLeftMargin = leftMargin();
+
+ setNumRows( numRows() + count );
+
+ for ( int i = numRows() - count - 1; i > row; --i )
+ leftHeader->swapSections( i, i + count );
+
+ leftHeader->setUpdatesEnabled( leftHeaderUpdatesEnabled );
+ setUpdatesEnabled( updatesEnabled );
+
+ int cr = TQMAX( 0, currentRow() );
+ int cc = TQMAX( 0, currentColumn() );
+ if ( curRow > row )
+ curRow -= count; // this is where curRow was
+ setCurrentCell( cr, cc, TRUE, FALSE ); // without ensureCellVisible
+
+ // Repaint the header
+ if ( leftHeaderUpdatesEnabled ) {
+ int y = rowPos( row ) - contentsY();
+ if ( leftMargin() != oldLeftMargin || d->hasRowSpan )
+ y = 0; // full tqrepaint
+ TQRect rect( 0, y, leftHeader->width(), contentsHeight() );
+ leftHeader->update( rect );
+ }
+
+ if ( updatesEnabled ) {
+ int p = rowPos( row );
+ if ( d->hasRowSpan )
+ p = contentsY();
+ updateContents( contentsX(), p, visibleWidth(), contentsHeight() + 1 );
+ }
+}
+
+/*!
+ Inserts \a count empty columns at column \a col. Also clears the selection(s).
+
+ \sa insertRows() removeColumn()
+*/
+
+void TQTable::insertColumns( int col, int count )
+{
+ // see comment in insertRows()
+ if ( col == -1 && curCol == -1 )
+ col = 0;
+ if ( col < 0 || count <= 0 )
+ return;
+
+ if ( curCol >= col && curCol < col + count )
+ curCol = col + count;
+
+ --col;
+ if ( col >= numCols() )
+ return;
+
+ bool updatesEnabled = isUpdatesEnabled();
+ setUpdatesEnabled( FALSE );
+ bool topHeaderUpdatesEnabled = topHeader->isUpdatesEnabled();
+ topHeader->setUpdatesEnabled( FALSE );
+ int oldTopMargin = topMargin();
+
+ setNumCols( numCols() + count );
+
+ for ( int i = numCols() - count - 1; i > col; --i )
+ topHeader->swapSections( i, i + count );
+
+ topHeader->setUpdatesEnabled( topHeaderUpdatesEnabled );
+ setUpdatesEnabled( updatesEnabled );
+
+ int cr = TQMAX( 0, currentRow() );
+ int cc = TQMAX( 0, currentColumn() );
+ if ( curCol > col )
+ curCol -= count; // this is where curCol was
+ setCurrentCell( cr, cc, TRUE, FALSE ); // without ensureCellVisible
+
+ // Repaint the header
+ if ( topHeaderUpdatesEnabled ) {
+ int x = columnPos( col ) - contentsX();
+ if ( topMargin() != oldTopMargin || d->hasColSpan )
+ x = 0; // full tqrepaint
+ TQRect rect( x, 0, contentsWidth(), topHeader->height() );
+ topHeader->update( rect );
+ }
+
+ if ( updatesEnabled ) {
+ int p = columnPos( col );
+ if ( d->hasColSpan )
+ p = contentsX();
+ updateContents( p, contentsY(), contentsWidth() + 1, visibleHeight() );
+ }
+}
+
+/*!
+ Removes row \a row, and deletes all its cells including any table
+ items and widgets the cells may contain. Also clears the selection(s).
+
+ \sa hideRow() insertRows() removeColumn() removeRows()
+*/
+
+void TQTable::removeRow( int row )
+{
+ if ( row < 0 || row >= numRows() )
+ return;
+ if ( row < numRows() - 1 ) {
+ if (d->hiddenRows.tqfind(row))
+ d->hiddenRows.remove(row);
+
+ for ( int i = row; i < numRows() - 1; ++i )
+ ( (TQTableHeader*)verticalHeader() )->swapSections( i, i + 1 );
+ }
+ setNumRows( numRows() - 1 );
+}
+
+/*!
+ Removes the rows listed in the array \a rows, and deletes all their
+ cells including any table items and widgets the cells may contain.
+
+ The array passed in must only contain valid rows (in the range
+ from 0 to numRows() - 1) with no duplicates, and must be sorted in
+ ascending order. Also clears the selection(s).
+
+ \sa removeRow() insertRows() removeColumns()
+*/
+
+void TQTable::removeRows( const TQMemArray<int> &rows )
+{
+ if ( rows.count() == 0 )
+ return;
+ int i;
+ for ( i = 0; i < (int)rows.count() - 1; ++i ) {
+ for ( int j = rows[i] - i; j < rows[i + 1] - i - 1; j++ ) {
+ ( (TQTableHeader*)verticalHeader() )->swapSections( j, j + i + 1 );
+ }
+ }
+
+ for ( int j = rows[i] - i; j < numRows() - (int)rows.size(); j++)
+ ( (TQTableHeader*)verticalHeader() )->swapSections( j, j + rows.count() );
+
+ setNumRows( numRows() - rows.count() );
+}
+
+/*!
+ Removes column \a col, and deletes all its cells including any
+ table items and widgets the cells may contain. Also clears the
+ selection(s).
+
+ \sa removeColumns() hideColumn() insertColumns() removeRow()
+*/
+
+void TQTable::removeColumn( int col )
+{
+ if ( col < 0 || col >= numCols() )
+ return;
+ if ( col < numCols() - 1 ) {
+ if (d->hiddenCols.tqfind(col))
+ d->hiddenCols.remove(col);
+
+ for ( int i = col; i < numCols() - 1; ++i )
+ ( (TQTableHeader*)horizontalHeader() )->swapSections( i, i + 1 );
+ }
+ setNumCols( numCols() - 1 );
+}
+
+/*!
+ Removes the columns listed in the array \a cols, and deletes all
+ their cells including any table items and widgets the cells may
+ contain.
+
+ The array passed in must only contain valid columns (in the range
+ from 0 to numCols() - 1) with no duplicates, and must be sorted in
+ ascending order. Also clears the selection(s).
+
+ \sa removeColumn() insertColumns() removeRows()
+*/
+
+void TQTable::removeColumns( const TQMemArray<int> &cols )
+{
+ if ( cols.count() == 0 )
+ return;
+ int i;
+ for ( i = 0; i < (int)cols.count() - 1; ++i ) {
+ for ( int j = cols[i] - i; j < cols[i + 1] - i - 1; j++ ) {
+ ( (TQTableHeader*)horizontalHeader() )->swapSections( j, j + i + 1 );
+ }
+ }
+
+ for ( int j = cols[i] - i; j < numCols() - (int)cols.size(); j++)
+ ( (TQTableHeader*)horizontalHeader() )->swapSections( j, j + cols.count() );
+
+ setNumCols( numCols() - cols.count() );
+}
+
+/*!
+ Starts editing the cell at \a row, \a col.
+
+ If \a tqreplace is TRUE the content of this cell will be tqreplaced by
+ the content of the editor when editing is finished, i.e. the user
+ will be entering new data; otherwise the current content of the
+ cell (if any) will be modified in the editor.
+
+ \sa beginEdit()
+*/
+
+void TQTable::editCell( int row, int col, bool tqreplace )
+{
+ if ( row < 0 || col < 0 || row > numRows() - 1 || col > numCols() - 1 )
+ return;
+
+ if ( beginEdit( row, col, tqreplace ) ) {
+ edMode = Editing;
+ editRow = row;
+ editCol = col;
+ }
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler is called whenever a TQTable object receives a
+ \l TQDragEnterEvent \a e, i.e. when the user pressed the mouse
+ button to drag something.
+
+ The focus is moved to the cell where the TQDragEnterEvent occurred.
+*/
+
+void TQTable::contentsDragEnterEvent( TQDragEnterEvent *e )
+{
+ oldCurrentRow = curRow;
+ oldCurrentCol = curCol;
+ int tmpRow = rowAt( e->pos().y() );
+ int tmpCol = columnAt( e->pos().x() );
+ fixRow( tmpRow, e->pos().y() );
+ fixCol( tmpCol, e->pos().x() );
+ if (TQT_TQOBJECT(e->source()) != (TQObject*)cellWidget( currentRow(), currentColumn() ) )
+ setCurrentCell( tmpRow, tmpCol, FALSE, TRUE );
+ e->accept();
+}
+
+/*!
+ This event handler is called whenever a TQTable object receives a
+ \l TQDragMoveEvent \a e, i.e. when the user actually drags the
+ mouse.
+
+ The focus is moved to the cell where the TQDragMoveEvent occurred.
+*/
+
+void TQTable::contentsDragMoveEvent( TQDragMoveEvent *e )
+{
+ int tmpRow = rowAt( e->pos().y() );
+ int tmpCol = columnAt( e->pos().x() );
+ fixRow( tmpRow, e->pos().y() );
+ fixCol( tmpCol, e->pos().x() );
+ if (TQT_TQOBJECT(e->source()) != (TQObject*)cellWidget( currentRow(), currentColumn() ) )
+ setCurrentCell( tmpRow, tmpCol, FALSE, TRUE );
+ e->accept();
+}
+
+/*!
+ This event handler is called when a drag activity leaves \e this
+ TQTable object with event \a e.
+*/
+
+void TQTable::contentsDragLeaveEvent( TQDragLeaveEvent * )
+{
+ setCurrentCell( oldCurrentRow, oldCurrentCol, FALSE, TRUE );
+}
+
+/*!
+ This event handler is called when the user ends a drag and drop by
+ dropping something onto \e this TQTable and thus triggers the drop
+ event, \a e.
+*/
+
+void TQTable::contentsDropEvent( TQDropEvent *e )
+{
+ setCurrentCell( oldCurrentRow, oldCurrentCol, FALSE, TRUE );
+ emit dropped( e );
+}
+
+/*!
+ If the user presses the mouse on a selected cell, starts moving
+ (i.e. dragging), and dragEnabled() is TRUE, this function is
+ called to obtain a drag object. A drag using this object begins
+ immediately unless dragObject() returns 0.
+
+ By default this function returns 0. You might reimplement it and
+ create a TQDragObject depending on the selected items.
+
+ \sa dropped()
+*/
+
+TQDragObject *TQTable::dragObject()
+{
+ return 0;
+}
+
+/*!
+ Starts a drag.
+
+ Usually you don't need to call or reimplement this function yourself.
+
+ \sa dragObject();
+*/
+
+void TQTable::startDrag()
+{
+ if ( startDragRow == -1 || startDragCol == -1 )
+ return;
+
+ startDragRow = startDragCol = -1;
+
+ TQDragObject *drag = dragObject();
+ if ( !drag )
+ return;
+
+ drag->drag();
+}
+
+#endif
+
+/*! \reimp */
+void TQTable::windowActivationChange( bool oldActive )
+{
+ if ( oldActive && autoScrollTimer )
+ autoScrollTimer->stop();
+
+ if ( !isVisible() )
+ return;
+
+ if ( tqpalette().active() != tqpalette().inactive() )
+ updateContents();
+}
+
+/*! \reimp */
+void TQTable::setEnabled( bool b )
+{
+ if ( !b ) {
+ // editor will lose focus, causing a crash deep in setEnabled(),
+ // so we'll end the edit early.
+ endEdit( editRow, editCol, TRUE, edMode != Editing );
+ }
+ TQScrollView::setEnabled(b);
+}
+
+
+/*
+ \class TQTableHeader
+ \brief The TQTableHeader class allows for creation and manipulation
+ of table headers.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup advanced
+ \module table
+
+
+ TQTable uses this subclass of TQHeader for its headers. TQTable has a
+ horizontalHeader() for displaying column labels, and a
+ verticalHeader() for displaying row labels.
+
+*/
+
+/*
+ \enum TQTableHeader::SectionState
+
+ This enum type denotes the state of the header's text
+
+ \value Normal the default
+ \value Bold
+ \value Selected typically represented by showing the section "sunken"
+ or "pressed in"
+*/
+
+/*!
+ Creates a new table header called \a name with \a i sections. It
+ is a child of widget \a tqparent and attached to table \a t.
+*/
+
+TQTableHeader::TQTableHeader( int i, TQTable *t,
+ TQWidget *tqparent, const char *name )
+ : TQHeader( i, tqparent, name ), mousePressed(FALSE), startPos(-1),
+ table( t ), caching( FALSE ), resizedSection(-1),
+ numStretches( 0 )
+{
+ setIsATableHeader( TRUE );
+ d = 0;
+ states.resize( i );
+ stretchable.resize( i );
+ states.fill( Normal, -1 );
+ stretchable.fill( FALSE, -1 );
+ autoScrollTimer = new TQTimer( this );
+ connect( autoScrollTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( doAutoScroll() ) );
+#ifndef NO_LINE_WIDGET
+ line1 = new TQWidget( table->viewport(), "qt_line1" );
+ line1->hide();
+ line1->setBackgroundMode( TQt::PaletteText );
+ table->addChild( line1 );
+ line2 = new TQWidget( table->viewport(), "qt_line2" );
+ line2->hide();
+ line2->setBackgroundMode( TQt::PaletteText );
+ table->addChild( line2 );
+#else
+ d = new TQTableHeaderPrivate;
+ d->oldLinePos = -1; //outside, in contents coords
+#endif
+ connect( this, TQT_SIGNAL( sizeChange(int,int,int) ),
+ this, TQT_SLOT( sectionWidthChanged(int,int,int) ) );
+ connect( this, TQT_SIGNAL( indexChange(int,int,int) ),
+ this, TQT_SLOT( indexChanged(int,int,int) ) );
+
+ stretchTimer = new TQTimer( this );
+ widgetStretchTimer = new TQTimer( this );
+ connect( stretchTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( updateStretches() ) );
+ connect( widgetStretchTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( updateWidgetStretches() ) );
+ startPos = -1;
+}
+
+/*!
+ Adds a new section, \a size pixels wide (or high for vertical
+ headers) with the label \a s. If \a size is negative the section's
+ size is calculated based on the width (or height) of the label's
+ text.
+*/
+
+void TQTableHeader::addLabel( const TQString &s , int size )
+{
+ TQHeader::addLabel( s, size );
+ if ( count() > (int)states.size() ) {
+ int s = states.size();
+ states.resize( count() );
+ stretchable.resize( count() );
+ for ( ; s < count(); ++s ) {
+ states[ s ] = Normal;
+ stretchable[ s ] = FALSE;
+ }
+ }
+}
+
+void TQTableHeader::removeLabel( int section )
+{
+ TQHeader::removeLabel( section );
+ if ( section == (int)states.size() - 1 ) {
+ states.resize( states.size() - 1 );
+ stretchable.resize( stretchable.size() - 1 );
+ }
+}
+
+void TQTableHeader::resizeArrays( int n )
+{
+ int old = states.size();
+ states.resize( n );
+ stretchable.resize( n );
+ if ( n > old ) {
+ for ( int i = old; i < n; ++i ) {
+ stretchable[ i ] = FALSE;
+ states[ i ] = Normal;
+ }
+ }
+}
+
+void TQTableHeader::setLabel( int section, const TQString & s, int size )
+{
+ TQHeader::setLabel( section, s, size );
+ sectionLabelChanged( section );
+}
+
+void TQTableHeader::setLabel( int section, const TQIconSet & iconset,
+ const TQString & s, int size )
+{
+ TQHeader::setLabel( section, iconset, s, size );
+ sectionLabelChanged( section );
+}
+
+/*!
+ Sets the SectionState of section \a s to \a astate.
+
+ \sa sectionState()
+*/
+
+void TQTableHeader::setSectionState( int s, SectionState astate )
+{
+ if ( s < 0 || s >= (int)states.count() )
+ return;
+ if ( states.data()[ s ] == astate )
+ return;
+ if ( isRowSelection( table->selectionMode() ) && orientation() == Qt::Horizontal )
+ return;
+
+ states.data()[ s ] = astate;
+ if ( isUpdatesEnabled() ) {
+ if ( orientation() == Qt::Horizontal )
+ tqrepaint( sectionPos( s ) - offset(), 0, sectionSize( s ), height(), FALSE );
+ else
+ tqrepaint( 0, sectionPos( s ) - offset(), width(), sectionSize( s ), FALSE );
+ }
+}
+
+void TQTableHeader::setSectionStateToAll( SectionState state )
+{
+ if ( isRowSelection( table->selectionMode() ) && orientation() == Qt::Horizontal )
+ return;
+
+ register int *d = (int *) states.data();
+ int n = count();
+
+ while (n >= 4) {
+ d[0] = state;
+ d[1] = state;
+ d[2] = state;
+ d[3] = state;
+ d += 4;
+ n -= 4;
+ }
+
+ if (n > 0) {
+ d[0] = state;
+ if (n > 1) {
+ d[1] = state;
+ if (n > 2) {
+ d[2] = state;
+ }
+ }
+ }
+}
+
+/*!
+ Returns the SectionState of section \a s.
+
+ \sa setSectionState()
+*/
+
+TQTableHeader::SectionState TQTableHeader::sectionState( int s ) const
+{
+ return (s < 0 || s >= (int)states.count() ? Normal : (TQTableHeader::SectionState)states[s]);
+}
+
+/*! \reimp
+*/
+
+void TQTableHeader::paintEvent( TQPaintEvent *e )
+{
+ TQPainter p( this );
+ p.setPen( tqcolorGroup().buttonText() );
+ int pos = orientation() == Qt::Horizontal
+ ? e->rect().left()
+ : e->rect().top();
+ int id = mapToIndex( sectionAt( pos + offset() ) );
+ if ( id < 0 ) {
+ if ( pos > 0 )
+ return;
+ else
+ id = 0;
+ }
+
+ TQRegion reg = e->region();
+ for ( int i = id; i < count(); i++ ) {
+ TQRect r = sRect( i );
+ reg -= r;
+ p.save();
+ if ( !( orientation() == Qt::Horizontal && isRowSelection( table->selectionMode() ) ) &&
+ ( sectionState( i ) == Bold || sectionState( i ) == Selected ) ) {
+ TQFont f( font() );
+ f.setBold( TRUE );
+ p.setFont( f );
+ }
+ paintSection( &p, i, r );
+ p.restore();
+ if ( (orientation() == Qt::Horizontal && r. right() >= e->rect().right()) ||
+ (orientation() == Qt::Vertical && r. bottom() >= e->rect().bottom()) )
+ return;
+ }
+ if ( !reg.isEmpty() )
+ erase( reg );
+}
+
+/*!
+ \reimp
+
+ Paints the header section with index \a index into the rectangular
+ region \a fr on the painter \a p.
+*/
+
+void TQTableHeader::paintSection( TQPainter *p, int index, const TQRect& fr )
+{
+ int section = mapToSection( index );
+ if ( section < 0 || cellSize( section ) <= 0 )
+ return;
+
+ if ( sectionState( index ) != Selected ||
+ (orientation() == Qt::Horizontal && isRowSelection( table->selectionMode() )) ) {
+ TQHeader::paintSection( p, index, fr );
+ } else {
+ TQStyle::SFlags flags = TQStyle::Style_Off | ( orient == Qt::Horizontal ? TQStyle::Style_Horizontal : (TQStyle::SFlags)0 );
+ if(isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if(isClickEnabled()) {
+ if(sectionState(index) == Selected) {
+ flags |= TQStyle::Style_Down;
+ if(!mousePressed)
+ flags |= TQStyle::Style_Sunken;
+ }
+ }
+ if(!(flags & TQStyle::Style_Down))
+ flags |= TQStyle::Style_Raised;
+ tqstyle().tqdrawPrimitive( TQStyle::PE_HeaderSection, p, TQRect(fr.x(), fr.y(), fr.width(), fr.height()),
+ tqcolorGroup(), flags );
+ paintSectionLabel( p, index, fr );
+ }
+}
+
+static int real_pos( const TQPoint &p, TQt::Orientation o )
+{
+ if ( o == Qt::Horizontal )
+ return p.x();
+ return p.y();
+}
+
+/*! \reimp
+*/
+
+void TQTableHeader::mousePressEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+ TQHeader::mousePressEvent( e );
+ mousePressed = TRUE;
+ pressPos = real_pos( e->pos(), orientation() );
+ if ( !table->currentSel || ( e->state() & ShiftButton ) != ShiftButton )
+ startPos = -1;
+ setCaching( TRUE );
+ resizedSection = -1;
+#ifdef TQT_NO_CURSOR
+ isResizing = FALSE;
+#else
+ isResizing = cursor().shape() != ArrowCursor;
+ if ( !isResizing && sectionAt( pressPos ) != -1 )
+ doSelection( e );
+#endif
+}
+
+/*! \reimp
+*/
+
+void TQTableHeader::mouseMoveEvent( TQMouseEvent *e )
+{
+ if ( (e->state() & Qt::MouseButtonMask) != Qt::LeftButton // Using LeftButton simulates old behavior.
+#ifndef TQT_NO_CURSOR
+ || cursor().shape() != Qt::ArrowCursor
+#endif
+ || ( ( e->state() & ControlButton ) == ControlButton &&
+ ( orientation() == Qt::Horizontal
+ ? table->columnMovingEnabled() : table->rowMovingEnabled() ) ) ) {
+ TQHeader::mouseMoveEvent( e );
+ return;
+ }
+
+ if ( !doSelection( e ) )
+ TQHeader::mouseMoveEvent( e );
+}
+
+bool TQTableHeader::doSelection( TQMouseEvent *e )
+{
+ int p = real_pos( e->pos(), orientation() ) + offset();
+
+ if ( isRowSelection( table->selectionMode() ) ) {
+ if ( orientation() == Qt::Horizontal )
+ return TRUE;
+ if ( table->selectionMode() == TQTable::SingleRow ) {
+ int secAt = sectionAt( p );
+ if ( secAt == -1 )
+ return TRUE;
+ table->setCurrentCell( secAt, table->currentColumn() );
+ return TRUE;
+ }
+ }
+
+ if ( startPos == -1 ) {
+ int secAt = sectionAt( p );
+ if ( (( e->state() & ControlButton ) != ControlButton &&
+ ( e->state() & ShiftButton ) != ShiftButton) ||
+ table->selectionMode() == TQTable::Single ||
+ table->selectionMode() == TQTable::SingleRow ) {
+ startPos = p;
+ bool b = table->tqsignalsBlocked();
+ table->blockSignals( TRUE );
+ table->clearSelection();
+ table->blockSignals( b );
+ }
+ saveStates();
+
+ if ( table->selectionMode() != TQTable::NoSelection ) {
+ startPos = p;
+ TQTableSelection *oldSelection = table->currentSel;
+
+ if ( orientation() == Qt::Vertical ) {
+ if ( !table->isRowSelected( secAt, TRUE ) ) {
+ table->currentSel = new TQTableSelection();
+ table->selections.append( table->currentSel );
+ table->currentSel->init( secAt, 0 );
+ table->currentSel->expandTo( secAt, table->numCols() - 1 );
+ emit table->selectionChanged();
+ }
+ table->setCurrentCell( secAt, 0 );
+ } else { // orientation == Qt::Horizontal
+ if ( !table->isColumnSelected( secAt, TRUE ) ) {
+ table->currentSel = new TQTableSelection();
+ table->selections.append( table->currentSel );
+ table->currentSel->init( 0, secAt );
+ table->currentSel->expandTo( table->numRows() - 1, secAt );
+ emit table->selectionChanged();
+ }
+ table->setCurrentCell( 0, secAt );
+ }
+
+ if ( (orientation() == Qt::Horizontal && table->isColumnSelected(secAt)) ||
+ (orientation() == Qt::Vertical && table->isRowSelected(secAt))) {
+ setSectionState( secAt, Selected );
+ }
+
+ table->repaintSelections( oldSelection, table->currentSel,
+ orientation() == Qt::Horizontal,
+ orientation() == Qt::Vertical );
+ if ( sectionAt( p ) != -1 )
+ endPos = p;
+
+ return TRUE;
+ }
+ }
+
+ if ( sectionAt( p ) != -1 )
+ endPos = p;
+ if ( startPos != -1 ) {
+ updateSelections();
+ p -= offset();
+ if ( orientation() == Qt::Horizontal && ( p < 0 || p > width() ) ) {
+ doAutoScroll();
+ autoScrollTimer->start( 100, TRUE );
+ } else if ( orientation() == Qt::Vertical && ( p < 0 || p > height() ) ) {
+ doAutoScroll();
+ autoScrollTimer->start( 100, TRUE );
+ }
+ return TRUE;
+ }
+ return table->selectionMode() == TQTable::NoSelection;
+}
+
+static inline bool mayOverwriteMargin( int before, int after )
+{
+ /*
+ 0 is the only user value that we always respect. We also never
+ shrink a margin, in case the user wanted it that way.
+ */
+ return before != 0 && before < after;
+}
+
+void TQTableHeader::sectionLabelChanged( int section )
+{
+ emit sectionSizeChanged( section );
+
+ // this does not really belong here
+ if ( orientation() == Qt::Horizontal ) {
+ int h = tqsizeHint().height();
+ if ( h != height() && mayOverwriteMargin(table->topMargin(), h) )
+ table->setTopMargin( h );
+ } else {
+ int w = tqsizeHint().width();
+ if ( w != width() && mayOverwriteMargin( ( TQApplication::reverseLayout() ? table->rightMargin() : table->leftMargin() ), w) )
+ table->setLeftMargin( w );
+ }
+}
+
+/*! \reimp */
+void TQTableHeader::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+ autoScrollTimer->stop();
+ mousePressed = FALSE;
+ setCaching( FALSE );
+ TQHeader::mouseReleaseEvent( e );
+#ifndef NO_LINE_WIDGET
+ line1->hide();
+ line2->hide();
+#else
+ if ( d->oldLinePos >= 0 )
+ if ( orientation() == Qt::Horizontal )
+ table->updateContents( d->oldLinePos, table->contentsY(),
+ 1, table->visibleHeight() );
+ else
+ table->updateContents( table->contentsX(), d->oldLinePos,
+ table->visibleWidth(), 1 );
+ d->oldLinePos = -1;
+#endif
+ if ( resizedSection != -1 ) {
+ emit sectionSizeChanged( resizedSection );
+ updateStretches();
+ }
+
+ //Make sure all newly selected sections are painted one last time
+ TQRect selectedRects;
+ for ( int i = 0; i < count(); i++ ) {
+ if(sectionState( i ) == Selected)
+ selectedRects |= sRect( i );
+ }
+ if(!selectedRects.isNull())
+ tqrepaint(selectedRects);
+}
+
+/*! \reimp
+*/
+
+void TQTableHeader::mouseDoubleClickEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+ if ( isResizing ) {
+ int p = real_pos( e->pos(), orientation() ) + offset();
+ int section = sectionAt( p );
+ if ( section == -1 )
+ return;
+ section--;
+ if ( p >= sectionPos( count() - 1 ) + sectionSize( count() - 1 ) )
+ ++section;
+ while ( sectionSize( section ) == 0 )
+ section--;
+ if ( section < 0 )
+ return;
+ int oldSize = sectionSize( section );
+ if ( orientation() == Qt::Horizontal ) {
+ table->adjustColumn( section );
+ int newSize = sectionSize( section );
+ if ( oldSize != newSize )
+ emit sizeChange( section, oldSize, newSize );
+ for ( int i = 0; i < table->numCols(); ++i ) {
+ if ( table->isColumnSelected( i ) && sectionSize( i ) != 0 )
+ table->adjustColumn( i );
+ }
+ } else {
+ table->adjustRow( section );
+ int newSize = sectionSize( section );
+ if ( oldSize != newSize )
+ emit sizeChange( section, oldSize, newSize );
+ for ( int i = 0; i < table->numRows(); ++i ) {
+ if ( table->isRowSelected( i ) && sectionSize( i ) != 0 )
+ table->adjustRow( i );
+ }
+ }
+ }
+}
+
+/*! \reimp
+*/
+
+void TQTableHeader::resizeEvent( TQResizeEvent *e )
+{
+ stretchTimer->stop();
+ widgetStretchTimer->stop();
+ TQHeader::resizeEvent( e );
+ if ( numStretches == 0 )
+ return;
+ stretchTimer->start( 0, TRUE );
+}
+
+void TQTableHeader::updateStretches()
+{
+ if ( numStretches == 0 )
+ return;
+
+ int dim = orientation() == Qt::Horizontal ? width() : height();
+ if ( sectionPos(count() - 1) + sectionSize(count() - 1) == dim )
+ return;
+ int i;
+ int pd = dim - ( sectionPos(count() - 1)
+ + sectionSize(count() - 1) );
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ for ( i = 0; i < (int)stretchable.count(); ++i ) {
+ if ( !stretchable[i] ||
+ ( stretchable[i] && table->d->hiddenCols[i] ) )
+ continue;
+ pd += sectionSize( i );
+ }
+ pd /= numStretches;
+ for ( i = 0; i < (int)stretchable.count(); ++i ) {
+ if ( !stretchable[i] ||
+ ( stretchable[i] && table->d->hiddenCols[i] ) )
+ continue;
+ if ( i == (int)stretchable.count() - 1 &&
+ sectionPos( i ) + pd < dim )
+ pd = dim - sectionPos( i );
+ resizeSection( i, TQMAX( 20, pd ) );
+ }
+ blockSignals( block );
+ table->repaintContents( FALSE );
+ widgetStretchTimer->start( 100, TRUE );
+}
+
+void TQTableHeader::updateWidgetStretches()
+{
+ TQSize s = table->tableSize();
+ table->resizeContents( s.width(), s.height() );
+ for ( int i = 0; i < table->numCols(); ++i )
+ table->updateColWidgets( i );
+}
+
+void TQTableHeader::updateSelections()
+{
+ if ( table->selectionMode() == TQTable::NoSelection ||
+ (isRowSelection( table->selectionMode() ) && orientation() != Qt::Vertical ) )
+ return;
+ int a = sectionAt( startPos );
+ int b = sectionAt( endPos );
+ int start = TQMIN( a, b );
+ int end = TQMAX( a, b );
+ register int *s = states.data();
+ for ( int i = 0; i < count(); ++i ) {
+ if ( i < start || i > end )
+ *s = oldStates.data()[ i ];
+ else
+ *s = Selected;
+ ++s;
+ }
+ tqrepaint( FALSE );
+
+ if (table->currentSel) {
+ TQTableSelection oldSelection = *table->currentSel;
+ if ( orientation() == Qt::Vertical )
+ table->currentSel->expandTo( b, table->horizontalHeader()->count() - 1 );
+ else
+ table->currentSel->expandTo( table->verticalHeader()->count() - 1, b );
+ table->repaintSelections( &oldSelection, table->currentSel,
+ orientation() == Qt::Horizontal,
+ orientation() == Qt::Vertical );
+ }
+ emit table->selectionChanged();
+}
+
+void TQTableHeader::saveStates()
+{
+ oldStates.resize( count() );
+ register int *s = states.data();
+ register int *s2 = oldStates.data();
+ for ( int i = 0; i < count(); ++i ) {
+ *s2 = *s;
+ ++s2;
+ ++s;
+ }
+}
+
+void TQTableHeader::doAutoScroll()
+{
+ TQPoint pos = mapFromGlobal( TQCursor::pos() );
+ int p = real_pos( pos, orientation() ) + offset();
+ if ( sectionAt( p ) != -1 )
+ endPos = p;
+ if ( orientation() == Qt::Horizontal )
+ table->ensureVisible( endPos, table->contentsY() );
+ else
+ table->ensureVisible( table->contentsX(), endPos );
+ updateSelections();
+ autoScrollTimer->start( 100, TRUE );
+}
+
+void TQTableHeader::sectionWidthChanged( int col, int, int )
+{
+ resizedSection = col;
+ if ( orientation() == Qt::Horizontal ) {
+#ifndef NO_LINE_WIDGET
+ table->moveChild( line1, TQHeader::sectionPos( col ) - 1,
+ table->contentsY() );
+ line1->resize( 1, table->visibleHeight() );
+ line1->show();
+ line1->raise();
+ table->moveChild( line2,
+ TQHeader::sectionPos( col ) + TQHeader::sectionSize( col ) - 1,
+ table->contentsY() );
+ line2->resize( 1, table->visibleHeight() );
+ line2->show();
+ line2->raise();
+#else
+ TQPainter p( table->viewport() );
+ int lx = TQHeader::sectionPos( col ) + TQHeader::sectionSize( col ) - 1;
+ int ly = table->contentsY();
+
+ if ( lx != d->oldLinePos ) {
+ TQPoint pt = table->contentsToViewport( TQPoint( lx, ly ) );
+ p.drawLine( pt.x(), pt.y()+1,
+ pt.x(), pt.y()+ table->visibleHeight() );
+ if ( d->oldLinePos >= 0 )
+ table->repaintContents( d->oldLinePos, table->contentsY(),
+ 1, table->visibleHeight() );
+
+ d->oldLinePos = lx;
+ }
+#endif
+ } else {
+#ifndef NO_LINE_WIDGET
+ table->moveChild( line1, table->contentsX(),
+ TQHeader::sectionPos( col ) - 1 );
+ line1->resize( table->visibleWidth(), 1 );
+ line1->show();
+ line1->raise();
+ table->moveChild( line2, table->contentsX(),
+ TQHeader::sectionPos( col ) + TQHeader::sectionSize( col ) - 1 );
+ line2->resize( table->visibleWidth(), 1 );
+ line2->show();
+ line2->raise();
+
+#else
+ TQPainter p( table->viewport() );
+ int lx = table->contentsX();
+ int ly = TQHeader::sectionPos( col ) + TQHeader::sectionSize( col ) - 1;
+
+ if ( ly != d->oldLinePos ) {
+ TQPoint pt = table->contentsToViewport( TQPoint( lx, ly ) );
+ p.drawLine( pt.x()+1, pt.y(),
+ pt.x() + table->visibleWidth(), pt.y() );
+ if ( d->oldLinePos >= 0 )
+ table->repaintContents( table->contentsX(), d->oldLinePos,
+ table->visibleWidth(), 1 );
+ d->oldLinePos = ly;
+ }
+
+#endif
+ }
+}
+
+/*!
+ \reimp
+
+ Returns the size of section \a section in pixels or -1 if \a
+ section is out of range.
+*/
+
+int TQTableHeader::sectionSize( int section ) const
+{
+ if ( count() <= 0 || section < 0 || section >= count() )
+ return -1;
+ if ( caching && section < (int)sectionSizes.count() )
+ return sectionSizes[ section ];
+ return TQHeader::sectionSize( section );
+}
+
+/*!
+ \reimp
+
+ Returns the start position of section \a section in pixels or -1
+ if \a section is out of range.
+
+ \sa sectionAt()
+*/
+
+int TQTableHeader::sectionPos( int section ) const
+{
+ if ( count() <= 0 || section < 0 || section >= count() )
+ return -1;
+ if ( caching && section < (int)sectionPoses.count() )
+ return sectionPoses[ section ];
+ return TQHeader::sectionPos( section );
+}
+
+/*!
+ \reimp
+
+ Returns the number of the section at index position \a pos or -1
+ if there is no section at the position given.
+
+ \sa sectionPos()
+*/
+
+int TQTableHeader::sectionAt( int pos ) const
+{
+ if ( !caching || sectionSizes.count() <= 0 || sectionPoses.count() <= 0 )
+ return TQHeader::sectionAt( pos );
+ if ( count() <= 0 || pos > sectionPoses[ count() - 1 ] + sectionSizes[ count() - 1 ] )
+ return -1;
+ int l = 0;
+ int r = count() - 1;
+ int i = ( (l+r+1) / 2 );
+ while ( r - l ) {
+ if ( sectionPoses[i] > pos )
+ r = i -1;
+ else
+ l = i;
+ i = ( (l+r+1) / 2 );
+ }
+ if ( sectionPoses[i] <= pos &&
+ pos <= sectionPoses[i] + sectionSizes[ mapToSection( i ) ] )
+ return mapToSection( i );
+ return -1;
+}
+
+void TQTableHeader::updateCache()
+{
+ sectionPoses.resize( count() );
+ sectionSizes.resize( count() );
+ if ( !caching )
+ return;
+ for ( int i = 0; i < count(); ++i ) {
+ sectionSizes[ i ] = TQHeader::sectionSize( i );
+ sectionPoses[ i ] = TQHeader::sectionPos( i );
+ }
+}
+
+void TQTableHeader::setCaching( bool b )
+{
+ if ( caching == b )
+ return;
+ caching = b;
+ sectionPoses.resize( count() );
+ sectionSizes.resize( count() );
+ if ( b ) {
+ for ( int i = 0; i < count(); ++i ) {
+ sectionSizes[ i ] = TQHeader::sectionSize( i );
+ sectionPoses[ i ] = TQHeader::sectionPos( i );
+ }
+ }
+}
+
+/*!
+ If \a b is TRUE, section \a s is stretchable; otherwise the
+ section is not stretchable.
+
+ \sa isSectionStretchable()
+*/
+
+void TQTableHeader::setSectionStretchable( int s, bool b )
+{
+ if ( stretchable[ s ] == b )
+ return;
+ stretchable[ s ] = b;
+ if ( b )
+ numStretches++;
+ else
+ numStretches--;
+}
+
+/*!
+ Returns TRUE if section \a s is stretcheable; otherwise returns
+ FALSE.
+
+ \sa setSectionStretchable()
+*/
+
+bool TQTableHeader::isSectionStretchable( int s ) const
+{
+ return stretchable[ s ];
+}
+
+void TQTableHeader::swapSections( int oldIdx, int newIdx, bool swapTable )
+{
+ extern bool qt_qheader_label_return_null_strings; // qheader.cpp
+ qt_qheader_label_return_null_strings = TRUE;
+
+ TQIconSet oldIconSet, newIconSet;
+ if ( iconSet( oldIdx ) )
+ oldIconSet = *iconSet( oldIdx );
+ if ( iconSet( newIdx ) )
+ newIconSet = *iconSet( newIdx );
+ TQString oldLabel = label( oldIdx );
+ TQString newLabel = label( newIdx );
+ bool sectionsHasContent = !(oldIconSet.isNull() && newIconSet.isNull()
+ && oldLabel.isNull() && newLabel.isNull());
+ if (sectionsHasContent) {
+ setLabel( oldIdx, newIconSet, newLabel );
+ setLabel( newIdx, oldIconSet, oldLabel );
+ }
+
+ qt_qheader_label_return_null_strings = FALSE;
+
+ int w1 = sectionSize( oldIdx );
+ int w2 = sectionSize( newIdx );
+ if ( w1 != w2 ) {
+ resizeSection( oldIdx, w2 );
+ resizeSection( newIdx, w1 );
+ }
+
+ if ( !swapTable )
+ return;
+ if ( orientation() == Qt::Horizontal )
+ table->swapColumns( oldIdx, newIdx );
+ else
+ table->swapRows( oldIdx, newIdx );
+}
+
+void TQTableHeader::indexChanged( int sec, int oldIdx, int newIdx )
+{
+ newIdx = mapToIndex( sec );
+ if ( oldIdx > newIdx )
+ moveSection( sec, oldIdx + 1 );
+ else
+ moveSection( sec, oldIdx );
+
+ if ( oldIdx < newIdx ) {
+ while ( oldIdx < newIdx ) {
+ swapSections( oldIdx, oldIdx + 1 );
+ oldIdx++;
+ }
+ } else {
+ while ( oldIdx > newIdx ) {
+ swapSections( oldIdx - 1, oldIdx );
+ oldIdx--;
+ }
+ }
+
+ table->repaintContents( table->contentsX(), table->contentsY(),
+ table->visibleWidth(), table->visibleHeight() );
+}
+
+void TQTableHeader::setLabels(const TQStringList & labels)
+{
+ int i = 0;
+ bool updates = isUpdatesEnabled();
+ const int c = TQMIN(count(), (int)labels.count());
+ setUpdatesEnabled(FALSE);
+ for ( TQStringList::ConstIterator it = labels.begin(); i < c; ++i, ++it ) {
+ if (i == c - 1) {
+ setUpdatesEnabled(updates);
+ setLabel( i, *it );
+ } else {
+ TQHeader::setLabel( i, *it );
+ emit sectionSizeChanged( i );
+ }
+ }
+}
+
+#include "tqtable.tqmoc"
+
+#endif // TQT_NO_TABLE
diff --git a/tqtinterface/qt4/src/table/tqtable.h b/tqtinterface/qt4/src/table/tqtable.h
new file mode 100644
index 0000000..d978ad2
--- /dev/null
+++ b/tqtinterface/qt4/src/table/tqtable.h
@@ -0,0 +1,565 @@
+/****************************************************************************
+**
+** Definition of TQTable widget class
+**
+** Created : 000607
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the table module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTABLE_H
+#define TQTABLE_H
+
+#ifndef TQT_H
+#include "tqscrollview.h"
+#include "tqpixmap.h"
+#include "tqptrvector.h"
+#include "tqheader.h"
+#include "tqmemarray.h"
+#include "tqptrlist.h"
+#include "tqguardedptr.h"
+#include "tqshared.h"
+#include "tqintdict.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+
+#ifndef TQT_NO_TABLE
+
+#if !defined( TQT_MODULE_TABLE ) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_TABLE )
+#define TQM_EXPORT_TABLE
+#ifndef TQM_TEMPLATE_EXTERN_TABLE
+# define TQM_TEMPLATE_EXTERN_TABLE
+#endif
+#else
+#define TQM_EXPORT_TABLE TQ_EXPORT
+#define TQM_TEMPLATE_EXTERN_TABLE TQ_TEMPLATE_EXTERN
+#endif
+
+class TQTableHeader;
+class TQValidator;
+class TQTable;
+class TQPaintEvent;
+class TQTimer;
+class TQResizeEvent;
+class TQComboBox;
+class TQCheckBox;
+class TQDragObject;
+
+struct TQTablePrivate;
+struct TQTableHeaderPrivate;
+
+
+class TQM_EXPORT_TABLE TQTableSelection
+{
+public:
+ TQTableSelection();
+ TQTableSelection( int start_row, int start_col, int end_row, int end_col );
+ void init( int row, int col );
+ void expandTo( int row, int col );
+ bool operator==( const TQTableSelection &s ) const;
+ bool operator!=( const TQTableSelection &s ) const { return !(operator==(s)); }
+
+ int topRow() const { return tRow; }
+ int bottomRow() const { return bRow; }
+ int leftCol() const { return lCol; }
+ int rightCol() const { return rCol; }
+ int anchorRow() const { return aRow; }
+ int anchorCol() const { return aCol; }
+ int numRows() const;
+ int numCols() const;
+
+ bool isActive() const { return active; }
+ bool isEmpty() const { return numRows() == 0; }
+
+private:
+ uint active : 1;
+ uint inited : 1;
+ int tRow, lCol, bRow, rCol;
+ int aRow, aCol;
+};
+
+#define TQ_DEFINED_TQTABLE_SELECTION
+#include "tqwinexport.h"
+
+class TQM_EXPORT_TABLE TQTableItem : public TQt
+{
+ friend class TQTable;
+
+public:
+ enum EditType { Never, OnTyping, WhenCurrent, Always };
+
+ TQTableItem( TQTable *table, EditType et );
+ TQTableItem( TQTable *table, EditType et, const TQString &text );
+ TQTableItem( TQTable *table, EditType et, const TQString &text,
+ const TQPixmap &p );
+ virtual ~TQTableItem();
+
+ virtual TQPixmap pixmap() const;
+ virtual TQString text() const;
+ virtual void setPixmap( const TQPixmap &p );
+ virtual void setText( const TQString &t );
+ TQTable *table() const { return t; }
+
+ virtual int tqalignment() const;
+ virtual void setWordWrap( bool b );
+ bool wordWrap() const;
+
+ EditType editType() const;
+ virtual TQWidget *createEditor() const;
+ virtual void setContentFromEditor( TQWidget *w );
+ virtual void setReplaceable( bool );
+ bool isReplaceable() const;
+
+ virtual TQString key() const;
+ virtual TQSize tqsizeHint() const;
+
+ virtual void setSpan( int rs, int cs );
+ int rowSpan() const;
+ int colSpan() const;
+
+ virtual void setRow( int r );
+ virtual void setCol( int c );
+ int row() const;
+ int col() const;
+
+ virtual void paint( TQPainter *p, const TQColorGroup &cg,
+ const TQRect &cr, bool selected );
+
+ void updateEditor( int oldRow, int oldCol );
+
+ virtual void setEnabled( bool b );
+ bool isEnabled() const;
+
+ virtual int rtti() const;
+ static int RTTI;
+
+private:
+ TQString txt;
+ TQPixmap pix;
+ TQTable *t;
+ EditType edType;
+ uint wordwrap : 1;
+ uint tcha : 1;
+ uint enabled : 1;
+ int rw, cl;
+ int rowspan, colspan;
+#if (TQT_VERSION >= 0x040000)
+#error "Add a tqsetAlignment() function in 4.0 (but no d pointer)"
+#endif
+};
+
+#define TQ_DEFINED_TQTABLE_ITEM
+#include "tqwinexport.h"
+
+class TQM_EXPORT_TABLE TQComboTableItem : public TQTableItem
+{
+public:
+ TQComboTableItem( TQTable *table, const TQStringList &list, bool editable = FALSE );
+ ~TQComboTableItem();
+ virtual TQWidget *createEditor() const;
+ virtual void setContentFromEditor( TQWidget *w );
+ virtual void paint( TQPainter *p, const TQColorGroup &cg,
+ const TQRect &cr, bool selected );
+ virtual void setCurrentItem( int i );
+ virtual void setCurrentItem( const TQString &i );
+ int currentItem() const;
+ TQString currentText() const;
+ int count() const;
+#if !defined(TQ_NO_USING_KEYWORD)
+ using TQTableItem::text;
+#endif
+ TQString text( int i ) const;
+ virtual void setEditable( bool b );
+ bool isEditable() const;
+ virtual void setStringList( const TQStringList &l );
+
+ int rtti() const;
+ static int RTTI;
+
+ TQSize tqsizeHint() const;
+
+private:
+ TQComboBox *cb;
+ TQStringList entries;
+ int current;
+ bool edit;
+ static TQComboBox *fakeCombo;
+ static TQWidget *fakeComboWidget;
+ static int fakeRef;
+
+};
+
+class TQM_EXPORT_TABLE TQCheckTableItem : public TQTableItem
+{
+public:
+ TQCheckTableItem( TQTable *table, const TQString &txt );
+ void setText( const TQString &t );
+ virtual TQWidget *createEditor() const;
+ virtual void setContentFromEditor( TQWidget *w );
+ virtual void paint( TQPainter *p, const TQColorGroup &cg,
+ const TQRect &cr, bool selected );
+ virtual void setChecked( bool b );
+ bool isChecked() const;
+
+ int rtti() const;
+ static int RTTI;
+
+ TQSize tqsizeHint() const;
+
+private:
+ TQCheckBox *cb;
+ bool checked;
+
+};
+
+class TQM_EXPORT_TABLE TQTable : public TQScrollView
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( SelectionMode FocusStyle )
+ Q_PROPERTY( int numRows READ numRows WRITE setNumRows )
+ Q_PROPERTY( int numCols READ numCols WRITE setNumCols )
+ Q_PROPERTY( bool showGrid READ showGrid WRITE setShowGrid )
+ Q_PROPERTY( bool rowMovingEnabled READ rowMovingEnabled WRITE setRowMovingEnabled )
+ Q_PROPERTY( bool columnMovingEnabled READ columnMovingEnabled WRITE setColumnMovingEnabled )
+ Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly )
+ Q_PROPERTY( bool sorting READ sorting WRITE setSorting )
+ Q_PROPERTY( SelectionMode selectionMode READ selectionMode WRITE setSelectionMode )
+ Q_PROPERTY( FocusStyle focusStyle READ focusStyle WRITE setFocusStyle )
+ Q_PROPERTY( int numSelections READ numSelections )
+
+ friend class TQTableHeader;
+ friend class TQComboTableItem;
+ friend class TQCheckTableItem;
+ friend class TQTableItem;
+
+public:
+ TQTable( TQWidget* tqparent=0, const char* name=0 );
+ TQTable( int numRows, int numCols,
+ TQWidget* tqparent=0, const char* name=0 );
+ ~TQTable();
+
+ TQHeader *horizontalHeader() const;
+ TQHeader *verticalHeader() const;
+
+ enum SelectionMode { Single, Multi, SingleRow, MultiRow, NoSelection };
+ virtual void setSelectionMode( SelectionMode mode );
+ SelectionMode selectionMode() const;
+
+ virtual void setItem( int row, int col, TQTableItem *item );
+ virtual void setText( int row, int col, const TQString &text );
+ virtual void setPixmap( int row, int col, const TQPixmap &pix );
+ virtual TQTableItem *item( int row, int col ) const;
+ virtual TQString text( int row, int col ) const;
+ virtual TQPixmap pixmap( int row, int col ) const;
+ virtual void clearCell( int row, int col );
+
+ virtual TQRect cellGeometry( int row, int col ) const;
+ virtual int columnWidth( int col ) const;
+ virtual int rowHeight( int row ) const;
+ virtual int columnPos( int col ) const;
+ virtual int rowPos( int row ) const;
+ virtual int columnAt( int x ) const;
+ virtual int rowAt( int y ) const;
+
+ virtual int numRows() const;
+ virtual int numCols() const;
+
+ void updateCell( int row, int col );
+
+ bool eventFilter( TQObject * o, TQEvent * );
+
+ int currentRow() const { return curRow; }
+ int currentColumn() const { return curCol; }
+ void ensureCellVisible( int row, int col );
+
+ bool isSelected( int row, int col ) const;
+ bool isRowSelected( int row, bool full = FALSE ) const;
+ bool isColumnSelected( int col, bool full = FALSE ) const;
+ int numSelections() const;
+ TQTableSelection selection( int num ) const;
+ virtual int addSelection( const TQTableSelection &s );
+ virtual void removeSelection( const TQTableSelection &s );
+ virtual void removeSelection( int num );
+ virtual int currentSelection() const;
+
+ void selectCells( int start_row, int start_col, int end_row, int end_col );
+ void selectRow( int row );
+ void selectColumn( int col );
+
+ bool showGrid() const;
+
+ bool columnMovingEnabled() const;
+ bool rowMovingEnabled() const;
+
+ virtual void sortColumn( int col, bool ascending = TRUE,
+ bool wholeRows = FALSE );
+ bool sorting() const;
+
+ virtual void takeItem( TQTableItem *i );
+
+ virtual void setCellWidget( int row, int col, TQWidget *e );
+ virtual TQWidget *cellWidget( int row, int col ) const;
+ virtual void clearCellWidget( int row, int col );
+
+ virtual TQRect cellRect( int row, int col ) const;
+
+ virtual void paintCell( TQPainter *p, int row, int col,
+ const TQRect &cr, bool selected );
+ virtual void paintCell( TQPainter *p, int row, int col,
+ const TQRect &cr, bool selected, const TQColorGroup &cg );
+ virtual void paintFocus( TQPainter *p, const TQRect &r );
+ TQSize tqsizeHint() const;
+
+ bool isReadOnly() const;
+ bool isRowReadOnly( int row ) const;
+ bool isColumnReadOnly( int col ) const;
+
+ void setEnabled( bool b );
+
+ void repaintSelections();
+
+ enum FocusStyle { FollowStyle, SpreadSheet };
+ virtual void setFocusStyle( FocusStyle fs );
+ FocusStyle focusStyle() const;
+
+ void updateHeaderStates();
+
+public Q_SLOTS:
+ virtual void setNumRows( int r );
+ virtual void setNumCols( int r );
+ virtual void setShowGrid( bool b );
+ virtual void hideRow( int row );
+ virtual void hideColumn( int col );
+ virtual void showRow( int row );
+ virtual void showColumn( int col );
+ bool isRowHidden( int row ) const;
+ bool isColumnHidden( int col ) const;
+
+ virtual void setColumnWidth( int col, int w );
+ virtual void setRowHeight( int row, int h );
+
+ virtual void adjustColumn( int col );
+ virtual void adjustRow( int row );
+
+ virtual void setColumnStretchable( int col, bool stretch );
+ virtual void setRowStretchable( int row, bool stretch );
+ bool isColumnStretchable( int col ) const;
+ bool isRowStretchable( int row ) const;
+ virtual void setSorting( bool b );
+ virtual void swapRows( int row1, int row2, bool swapHeader = FALSE );
+ virtual void swapColumns( int col1, int col2, bool swapHeader = FALSE );
+ virtual void swapCells( int row1, int col1, int row2, int col2 );
+
+ virtual void setLeftMargin( int m );
+ virtual void setTopMargin( int m );
+ virtual void setCurrentCell( int row, int col );
+ void clearSelection( bool tqrepaint = TRUE );
+ virtual void setColumnMovingEnabled( bool b );
+ virtual void setRowMovingEnabled( bool b );
+
+ virtual void setReadOnly( bool b );
+ virtual void setRowReadOnly( int row, bool ro );
+ virtual void setColumnReadOnly( int col, bool ro );
+
+ virtual void setDragEnabled( bool b );
+ bool dragEnabled() const;
+
+ virtual void insertRows( int row, int count = 1 );
+ virtual void insertColumns( int col, int count = 1 );
+ virtual void removeRow( int row );
+ virtual void removeRows( const TQMemArray<int> &rows );
+ virtual void removeColumn( int col );
+ virtual void removeColumns( const TQMemArray<int> &cols );
+
+ virtual void editCell( int row, int col, bool tqreplace = FALSE );
+
+ void setRowLabels( const TQStringList &labels );
+ void setColumnLabels( const TQStringList &labels );
+
+protected:
+ enum EditMode { NotEditing, Editing, Replacing };
+ void drawContents( TQPainter *p, int cx, int cy, int cw, int ch );
+ void contentsMousePressEvent( TQMouseEvent* );
+ void contentsMouseMoveEvent( TQMouseEvent* );
+ void contentsMouseDoubleClickEvent( TQMouseEvent* );
+ void contentsMouseReleaseEvent( TQMouseEvent* );
+ void contentsContextMenuEvent( TQContextMenuEvent * e );
+ void keyPressEvent( TQKeyEvent* );
+ void focusInEvent( TQFocusEvent* );
+ void focusOutEvent( TQFocusEvent* );
+ void viewportResizeEvent( TQResizeEvent * );
+ void showEvent( TQShowEvent *e );
+ void paintEvent( TQPaintEvent *e );
+ void setEditMode( EditMode mode, int row, int col );
+#ifndef TQT_NO_DRAGANDDROP
+ virtual void contentsDragEnterEvent( TQDragEnterEvent *e );
+ virtual void contentsDragMoveEvent( TQDragMoveEvent *e );
+ virtual void contentsDragLeaveEvent( TQDragLeaveEvent *e );
+ virtual void contentsDropEvent( TQDropEvent *e );
+ virtual TQDragObject *dragObject();
+ virtual void startDrag();
+#endif
+
+ virtual void paintEmptyArea( TQPainter *p, int cx, int cy, int cw, int ch );
+ virtual void activateNextCell();
+ virtual TQWidget *createEditor( int row, int col, bool initFromCell ) const;
+ virtual void setCellContentFromEditor( int row, int col );
+ virtual TQWidget *beginEdit( int row, int col, bool tqreplace );
+ virtual void endEdit( int row, int col, bool accept, bool tqreplace );
+
+ virtual void resizeData( int len );
+ virtual void insertWidget( int row, int col, TQWidget *w );
+ int indexOf( int row, int col ) const;
+
+ void windowActivationChange( bool );
+ bool isEditing() const;
+ EditMode editMode() const;
+ int currEditRow() const;
+ int currEditCol() const;
+
+protected Q_SLOTS:
+ virtual void columnWidthChanged( int col );
+ virtual void rowHeightChanged( int row );
+ virtual void columnIndexChanged( int section, int fromIndex, int toIndex );
+ virtual void rowIndexChanged( int section, int fromIndex, int toIndex );
+ virtual void columnClicked( int col );
+
+Q_SIGNALS:
+ void currentChanged( int row, int col );
+ void clicked( int row, int col, int button, const TQPoint &mousePos );
+ void doubleClicked( int row, int col, int button, const TQPoint &mousePos );
+ void pressed( int row, int col, int button, const TQPoint &mousePos );
+ void selectionChanged();
+ void valueChanged( int row, int col );
+ void contextMenuRequested( int row, int col, const TQPoint &pos );
+#ifndef TQT_NO_DRAGANDDROP
+ void dropped( TQDropEvent *e );
+#endif
+
+private Q_SLOTS:
+ void doAutoScroll();
+ void doValueChanged();
+ void updateGeometriesSlot();
+
+private:
+ void contentsMousePressEventEx( TQMouseEvent* );
+ void drawContents( TQPainter* );
+ void updateGeometries();
+ void repaintSelections( TQTableSelection *oldSelection,
+ TQTableSelection *newSelection,
+ bool updateVertical = TRUE,
+ bool updateHorizontal = TRUE );
+ TQRect rangeGeometry( int topRow, int leftCol,
+ int bottomRow, int rightCol, bool &optimize );
+ void fixRow( int &row, int y );
+ void fixCol( int &col, int x );
+
+ void init( int numRows, int numCols );
+ TQSize tableSize() const;
+ void repaintCell( int row, int col );
+ void contentsToViewport2( int x, int y, int& vx, int& vy );
+ TQPoint contentsToViewport2( const TQPoint &p );
+ void viewportToContents2( int vx, int vy, int& x, int& y );
+ TQPoint viewportToContents2( const TQPoint &p );
+
+ void updateRowWidgets( int row );
+ void updateColWidgets( int col );
+ bool isSelected( int row, int col, bool includeCurrent ) const;
+ void setCurrentCell( int row, int col, bool updateSelections, bool ensureVisible = FALSE );
+ void fixCell( int &row, int &col, int key );
+ void delayedUpdateGeometries();
+ struct TableWidget
+ {
+ TableWidget( TQWidget *w, int r, int c ) : wid( w ), row( r ), col ( c ) {}
+ TQWidget *wid;
+ int row, col;
+ };
+ void saveContents( TQPtrVector<TQTableItem> &tmp,
+ TQPtrVector<TableWidget> &tmp2 );
+ void updateHeaderAndResizeContents( TQTableHeader *header,
+ int num, int colRow,
+ int width, bool &updateBefore );
+ void restoreContents( TQPtrVector<TQTableItem> &tmp,
+ TQPtrVector<TableWidget> &tmp2 );
+ void finishContentsResze( bool updateBefore );
+
+private:
+ TQPtrVector<TQTableItem> contents;
+ TQPtrVector<TQWidget> widgets;
+ int curRow;
+ int curCol;
+ TQTableHeader *leftHeader, *topHeader;
+ EditMode edMode;
+ int editCol, editRow;
+ TQPtrList<TQTableSelection> selections;
+ TQTableSelection *currentSel;
+ TQTimer *autoScrollTimer;
+ int lastSortCol;
+ bool sGrid : 1;
+ bool mRows : 1;
+ bool mCols : 1;
+ bool asc : 1;
+ bool doSort : 1;
+ bool unused : 1;
+ bool readOnly : 1;
+ bool shouldClearSelection : 1;
+ bool dEnabled : 1;
+ bool context_menu : 1;
+ bool drawActiveSelection : 1;
+ bool was_visible : 1;
+ SelectionMode selMode;
+ int pressedRow, pressedCol;
+ TQTablePrivate *d;
+ TQIntDict<int> roRows;
+ TQIntDict<int> roCols;
+ int startDragRow;
+ int startDragCol;
+ TQPoint dragStartPos;
+ int oldCurrentRow, oldCurrentCol;
+ TQWidget *unused_topLeftCorner; //### remove in 4.0
+ FocusStyle focusStl;
+ TQSize unused_cachedSizeHint; // ### remove in 4.0
+
+#if defined(TQ_DISABLE_COPY)
+ TQTable( const TQTable & );
+ TQTable &operator=( const TQTable & );
+#endif
+};
+
+#define TQ_DEFINED_TQTABLE
+#include "tqwinexport.h"
+#endif // TQT_NO_TABLE
+#endif // TABLE_H
diff --git a/tqtinterface/qt4/src/tmp/README b/tqtinterface/qt4/src/tmp/README
new file mode 100644
index 0000000..fb1136b
--- /dev/null
+++ b/tqtinterface/qt4/src/tmp/README
@@ -0,0 +1 @@
+This is a temporary directory for tqmoc output
diff --git a/tqtinterface/qt4/src/tools/qfeatures.txt b/tqtinterface/qt4/src/tools/qfeatures.txt
new file mode 100644
index 0000000..857e71e
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/qfeatures.txt
@@ -0,0 +1,1314 @@
+Feature: WORKSPACE
+Section: Widgets
+Requires: SCROLLBAR VBOX TITLEBAR RESIZEHANDLER POPUPMENU LABEL TOOLBUTTON MAINWINDOW TOOLBAR MENUBAR
+Name: QWorkSpace
+SeeAlso: ???
+
+Feature: WHEELEVENT
+Section: Kernel
+Requires:
+Name: Wheel-mouse events
+SeeAlso: ???
+
+Feature: WMATRIX
+Section: Data structures
+Requires:
+Name: QWMatrix
+SeeAlso: ???
+
+Feature: STL
+Section: Data structures
+Requires:
+Name: Standard template library compatiblity
+SeeAlso: ???
+
+Feature: CANVAS
+Section: Widgets
+Requires: SCROLLVIEW BEZIER
+Name: QCanvas
+SeeAlso: ???
+
+Feature: TOOLBOX
+Section: Widgets
+Requires: ICONSET SCROLLVIEW TOOLTIP LAYOUT TOOLBUTTON
+Name: Tool box
+SeeAlso: ???
+
+
+Feature: TABLE
+Section: Widgets
+Requires: COMBOBOX HEADER CHECKBOX
+Name: QTable
+SeeAlso: ???
+
+Feature: XML
+Section: Data structures
+Requires: TEXTSTREAM TEXTCODEC REGEXP_CAPTURE
+Name: XML
+SeeAlso: ???
+
+Feature: SQL
+Section: Database
+Requires: STRINGLIST REGEXP_CAPTURE VARIANT SPRINTF DATESTRING
+Name: SQL classes
+SeeAlso: ???
+
+Feature: SQL_FORM
+Section: Database
+Requires: SQL PROPERTIES
+Name: QSqlForm
+SeeAlso: ???
+
+Feature: SQL_EDIT_WIDGETS
+Section: Database
+Requires: SQL SPINBOX COMBOBOX CHECKBOX DATETIMEEDIT
+Name: SQL value editor widgets
+SeeAlso: ???
+
+Feature: SQL_VIEW_WIDGETS
+Section: Database
+Requires: SQL_FORM SQL_EDIT_WIDGETS TABLE
+Name: SQL table widgets
+SeeAlso: ???
+
+Feature: STRINGLIST
+Section: Data structures
+Requires:
+Name: QStringList
+SeeAlso: ???
+
+Feature: REGEXP
+Section: Data structures
+Requires:
+Name: Regular expression capture
+SeeAlso: ???
+
+Feature: REGEXP_CAPTURE
+Section: Data structures
+Requires: REGEXP STRINGLIST
+Name: Regular expression capture
+SeeAlso: ???
+
+Feature: TEMPLATE_VARIANT
+Section: Data structures
+Requires: VARIANT STRINGLIST
+Name: Template classes in QVariant
+SeeAlso: ???
+
+Feature: VARIANT
+Section: Data structures
+Requires:
+Name: QVariant
+SeeAlso: ???
+
+Feature: REGEXP_OPTIM
+Section: Data structures
+Requires: REGEXP
+Name: Regular expression optimization
+SeeAlso: ???
+
+Feature: REGEXP_LOOKAHEAD
+Section: Data structures
+Requires: REGEXP
+Name: Regular expression lookahead
+SeeAlso: ???
+
+Feature: REGEXP_INTERVAL
+Section: Data structures
+Requires: REGEXP
+Name: Regular expression interval
+SeeAlso: ???
+
+Feature: REGEXP_ESCAPE
+Section: Data structures
+Requires: REGEXP
+Name: Regular expression escape
+SeeAlso: ???
+
+Feature: REGEXP_CCLASS
+Section: Data structures
+Requires: REGEXP
+Name: Regular expression character-class
+SeeAlso: ???
+
+Feature: REGEXP_BACKREF
+Section: Data structures
+Requires: REGEXP
+Name: Regular expression back-reference
+SeeAlso: ???
+
+Feature: REGEXP_ANCHOR_ALT
+Section: Data structures
+Requires: REGEXP
+Name: Regular expression anchors
+SeeAlso: ???
+
+Feature: REGEXP_WILDCARD
+Section: Data structures
+Requires: REGEXP
+Name: Regular expression wildcard
+SeeAlso: ???
+
+Feature: SPRINTF
+Section: Data structures
+Requires: REGEXP
+Name: QString::sprintf()
+SeeAlso: ???
+
+Feature: QUUID_STRING
+Section: Data structures
+Requires: STRINGLIST
+Name: Convert UUID to/from string
+SeeAlso: ???
+
+Feature: TEXTDATE
+Section: Data structures
+Requires: STRINGLIST DATESTRING
+Name: Month and day names in dates
+SeeAlso: ???
+
+Feature: DATESTRING
+Section: Data structures
+Requires:
+Name: QDate/QTime/QDateTime toString() and fromString()
+SeeAlso: ???
+
+Feature: ICONSET
+Section: Images
+Requires: IMAGEIO IMAGE_SMOOTHSCALE PALETTE IMAGE_HEURISTIC_MASK
+Name: QIconSet
+SeeAlso: ???
+
+Feature: DIR
+Section: File I/O
+Requires: STRINGLIST REGEXP
+Name: QDir
+SeeAlso: ???
+
+Feature: PALETTE
+Section: Kernel
+Requires:
+Name: Palettes
+SeeAlso: ???
+
+Feature: TEXTSTREAM
+Section: File I/O
+Requires:
+Name: QTextStream
+SeeAlso: ???
+
+Feature: DATASTREAM
+Section: File I/O
+Requires:
+Name: QDataStream
+SeeAlso: ???
+
+Feature: LIBRARY
+Section: File I/O
+Requires: REGEXP
+Name: Shared library wrapper
+SeeAlso: ???
+
+Feature: COMPONENT
+Section: File I/O
+Requires: QUUID_STRING SETTINGS SPRINTF LIBRARY DATESTRING
+Name: Dynamic module linking
+SeeAlso: ???
+
+Feature: SETTINGS
+Section: File I/O
+Requires: DIR TEXTSTREAM REGEXP_CAPTURE
+Name: Persistent application settings
+SeeAlso: ???
+
+Feature: SIGNALMAPPER
+Section: Widgets
+Requires:
+Name: QSignalMapper
+SeeAlso: ???
+
+Feature: IMAGEIO
+Section: Images
+Requires: REGEXP
+Name: Image formats
+SeeAlso: ???
+
+Feature: IMAGEIO_BMP
+Section: Images
+Requires: IMAGEIO DATASTREAM
+Name: BMP image I/O
+SeeAlso: ???
+
+Feature: IMAGEIO_PPM
+Section: Images
+Requires: IMAGEIO
+Name: PPM image I/O
+SeeAlso: ???
+
+Feature: IMAGEIO_XBM
+Section: Images
+Requires: IMAGEIO
+Name: XBM image I/O
+SeeAlso: ???
+
+Feature: IMAGEIO_XPM
+Section: Images
+Requires: IMAGEIO SPRINTF TEXTSTREAM
+Name: XPM image I/O
+SeeAlso: ???
+
+Feature: IMAGEIO_PNG
+Section: Images
+Requires: IMAGEIO
+Name: PNG image I/O
+SeeAlso: ???
+
+Feature: IMAGEIO_MNG
+Section: Images
+Requires: IMAGEIO
+Name: MNG image I/O
+SeeAlso: ???
+
+Feature: IMAGEIO_JPEG
+Section: Images
+Requires: IMAGEIO
+Name: JPEG image I/O
+SeeAlso: ???
+
+Feature: ASYNC_IO
+Section: Images
+Requires:
+Name: Asynchronous I/O
+SeeAlso: ???
+
+Feature: ASYNC_IMAGE_IO
+Section: Images
+Requires: IMAGEIO
+Name: Asynchronous image I/O
+SeeAlso: ???
+
+Feature: MOVIE
+Section: Images
+Requires: ASYNC_IO ASYNC_IMAGE_IO
+Name: Animated images
+SeeAlso: ???
+
+Feature: FREETYPE
+Section: Fonts
+Requires:
+Name: Freetype font engine
+SeeAlso: ???
+
+Feature: BDF
+Section: Fonts
+Requires: TEXTSTREAM STRINGLIST
+Name: BDF font files
+SeeAlso: ???
+
+Feature: FONTDATABASE
+Section: Fonts
+Requires: STRINGLIST
+Name: QFontDatabase
+SeeAlso: ???
+
+Feature: TRANSLATION
+Section: Internationalization
+Requires: DATASTREAM
+Name: Translations via TQT_BASE_OBJECT_NAME::tr()
+SeeAlso: ???
+
+Feature: TRANSLATION_UTF8
+Section: Internationalization
+Requires: TRANSLATION TEXTCODEC
+Name: Translations via TQT_BASE_OBJECT_NAME::trUtf8()
+SeeAlso: ???
+
+Feature: TEXTCODEC
+Section: Internationalization
+Requires:
+Name: Character set conversions
+SeeAlso: ???
+
+Feature: CODECS
+Section: Internationalization
+Requires: TEXTCODEC
+Name: Non-Unicode text conversions
+SeeAlso: ???
+
+Feature: BIG_CODECS
+Section: Internationalization
+Requires: CODEC_HEBREW
+Name: Big Codecs (eg. CJK)
+SeeAlso: ???
+
+Feature: CODEC_HEBREW
+Section: Internationalization
+Requires: CODECS COMPLEXTEXT
+Name: Hebrew Codec
+SeeAlso: ???
+
+Feature: UNICODETABLES
+Section: Internationalization
+Requires:
+Name: Unicode property tables
+SeeAlso: ???
+
+Feature: MIME
+Section: File I/O
+Requires: DIR IMAGEIO TEXTCODEC
+Name: MIME
+SeeAlso: ???
+
+Feature: RICHTEXT
+Section: Widgets
+Requires: STYLE LAYOUT STRINGLIST TEXTSTREAM
+Name: RichText (HTML) display
+SeeAlso: ???
+
+Feature: TEXTCUSTOMITEM
+Section: Widgets
+Requires: RICHTEXT MIME
+Name: RichText (HTML) tables and images
+SeeAlso: ???
+
+
+Feature: COMPLEXTEXT
+Section: Internationalization
+Requires: RICHTEXT
+Name: Complex scripts (eg. BiDi)
+SeeAlso: ???
+
+Feature: DOM
+Section: File I/O
+Requires: XML MIME
+Name: Document Object Model
+SeeAlso: ???
+
+Feature: SOUND
+Section: Kernel
+Requires:
+Name: Playing sounds
+SeeAlso: ???
+
+Feature: QWS_SOUNDSERVER
+Section: Qt/Embedded-specific
+Requires: SOUND DIR DNS
+Name: Server to play sound
+SeeAlso: ???
+
+Feature: PROPERTIES
+Section: Kernel
+Requires: VARIANT STRINGLIST ICONSET
+Name: Properties
+SeeAlso: ???
+
+Feature: NETWORK
+Section: Networking
+Requires:
+Name: Networking
+SeeAlso: ???
+
+Feature: DNS
+Section: Networking
+Requires: NETWORK STRINGLIST TEXTSTREAM SPRINTF
+Name: DNS
+SeeAlso: ???
+
+Feature: URL
+Section: Networking
+Requires: DIR
+Name: URL parser
+SeeAlso: ???
+
+Feature: NETWORKPROTOCOL
+Section: Networking
+Requires: TEXTCODEC URL
+Name: Network file access
+SeeAlso: ???
+
+Feature: NETWORKPROTOCOL_FTP
+Section: Networking
+Requires: NETWORKPROTOCOL DNS TEXTDATE
+Name: FTP file access
+SeeAlso: ???
+
+Feature: NETWORKPROTOCOL_HTTP
+Section: Networking
+Requires: NETWORKPROTOCOL DNS
+Name: HTTP file access
+SeeAlso: ???
+
+Feature: PROCESS
+Section: File I/O
+Requires: STRINGLIST REGEXP
+Name: External process invocation.
+SeeAlso: ???
+
+Feature: QWS_MULTIPROCESS
+Section: Qt/Embedded-specific
+Requires: NETWORK
+Name: Multi-process architecture
+SeeAlso: ???
+
+Feature: COP
+Section: Networking
+Requires: DATASTREAM
+Name: QCop IPC
+SeeAlso: ???
+
+Feature: QWS_KEYBOARD
+Section: Qt/Embedded-specific
+Requires:
+Name: Console keyboard
+SeeAlso: ???
+
+Feature: QWS_KBD_SL5000
+Section: Qt/Embedded-specific
+Requires: QWS_KEYBOARD
+Name: Keyboard for SHARP Zaurus SL5xxx tqdevices
+SeeAlso: ???
+
+Feature: QWS_CURSOR
+Section: Qt/Embedded-specific
+Requires: CURSOR
+Name: Visible cursor
+SeeAlso: ???
+
+Feature: QWS_ALPHA_CURSOR
+Section: Qt/Embedded-specific
+Requires:
+Name: Alpha-blended cursor
+SeeAlso: ???
+
+Feature: QWS_MACH64
+Section: Qt/Embedded-specific
+Requires:
+Name: Mach64 acceleration
+SeeAlso: ???
+
+Feature: QWS_VOODOO3
+Section: Qt/Embedded-specific
+Requires:
+Name: Voodoo3 acceleration
+SeeAlso: ???
+
+Feature: QWS_MATROX
+Section: Qt/Embedded-specific
+Requires:
+Name: Matrox MGA acceleration
+SeeAlso: ???
+
+Feature: QWS_REPEATER
+Section: Qt/Embedded-specific
+Requires:
+Name: Repeater display
+SeeAlso: ???
+
+Feature: QWS_VFB
+Section: Qt/Embedded-specific
+Requires:
+Name: Virtual frame buffer
+SeeAlso: ???
+
+Feature: QWS_TRANSFORMED
+Section: Qt/Embedded-specific
+Requires: QWS_LINUXFB
+Name: Transformed frame buffer
+SeeAlso: ???
+
+Feature: QWS_LINUXFB
+Section: Qt/Embedded-specific
+Requires:
+Name: Linux framebuffer
+SeeAlso: ???
+
+Feature: QWS_VNC
+Section: Qt/Embedded-specific
+Requires: NETWORK
+Name: Remote frame buffer (VNC)
+SeeAlso: ???
+
+Feature: QWS_SHADOWFB
+Section: Qt/Embedded-specific
+Requires:
+Name: Shadow frame buffer
+SeeAlso: ???
+
+Feature: QWS_DEPTH_1
+Section: Qt/Embedded-specific
+Requires:
+Name: 1-bit monochrome
+SeeAlso: ???
+
+Feature: QWS_DEPTH_4
+Section: Qt/Embedded-specific
+Requires:
+Name: 4-bit grayscale
+SeeAlso: ???
+
+Feature: QWS_VGA_16
+Section: Qt/Embedded-specific
+Requires:
+Name: 4-bit VGA
+SeeAlso: ???
+
+Feature: QWS_DEPTH_8GRAYSCALE
+Section: Qt/Embedded-specific
+Requires:
+Name: 8-bit grayscale
+SeeAlso: ???
+
+Feature: QWS_DEPTH_8
+Section: Qt/Embedded-specific
+Requires:
+Name: 8-bit color
+SeeAlso: ???
+
+Feature: QWS_DEPTH_16
+Section: Qt/Embedded-specific
+Requires:
+Name: 15 or 16-bit color
+SeeAlso: ???
+
+Feature: QWS_DEPTH_24
+Section: Qt/Embedded-specific
+Requires:
+Name: 24-bit color
+SeeAlso: ???
+
+Feature: QWS_DEPTH_32
+Section: Qt/Embedded-specific
+Requires:
+Name: 32-bit color
+SeeAlso: ???
+
+Feature: QWS_DEPTH_32_BGR
+Section: Qt/Embedded-specific
+Requires: QWS_DEPTH_32
+Name: 32-bit color, BGR order
+SeeAlso: ???
+
+Feature: QWS_MANAGER
+Section: Qt/Embedded-specific
+Requires:
+Name: Window Manager
+SeeAlso: ???
+
+Feature: QWS_KDE2_WM_STYLE
+Section: Qt/Embedded-specific
+Requires: QWS_MANAGER
+Name: The "KDE2" style
+SeeAlso: ???
+
+Feature: QWS_HYDRO_WM_STYLE
+Section: Qt/Embedded-specific
+Requires: QWS_MANAGER
+Name: The "Hydro" style
+SeeAlso: ???
+
+Feature: QWS_BEOS_WM_STYLE
+Section: Qt/Embedded-specific
+Requires: QWS_MANAGER
+Name: The "BeOS" style
+SeeAlso: ???
+
+Feature: QWS_KDE_WM_STYLE
+Section: Qt/Embedded-specific
+Requires: QWS_MANAGER
+Name: The "KDE" style
+SeeAlso: ???
+
+Feature: QWS_WINDOWS_WM_STYLE
+Section: Qt/Embedded-specific
+Requires: QWS_MANAGER
+Name: The "Windows" style
+SeeAlso: ???
+
+Feature: QWS_MOUSE_AUTO
+Section: Qt/Embedded-specific
+Requires:
+Name: Autodetecting mouse driver
+SeeAlso: ???
+
+Feature: QWS_MOUSE_MANUAL
+Section: Qt/Embedded-specific
+Requires:
+Name: Non-autodetecting mouse driver
+SeeAlso: ???
+
+Feature: QWS_SAVEFONTS
+Section: Qt/Embedded-specific
+Requires:
+Name: Saving of fonts
+SeeAlso: ???
+
+Feature: QWS_GFX_SPEED
+Section: Qt/Embedded-specific
+Requires:
+Name: Favour code size over graphics speed
+SeeAlso: ???
+
+Feature: QWS_PROPERTIES
+Section: Qt/Embedded-specific
+Requires:
+Name: Qt/Embedded window system properties.
+SeeAlso: ???
+
+Feature: CLIPBOARD
+Section: Kernel
+Requires: QWS_PROPERTIES MIME
+Name: Cut and paste
+SeeAlso: ???
+
+Feature: DRAGANDDROP
+Section: Kernel
+Requires: MIME QWS_PROPERTIES IMAGEIO_XPM
+Name: Drag and drop
+SeeAlso: ???
+
+Feature: MIMECLIPBOARD
+Section: Kernel
+Requires: CLIPBOARD
+Name: Cut and paste non-text
+SeeAlso: ???
+
+Feature: DRAWUTIL
+Section: Kernel
+Requires: SPRINTF PALETTE
+Name: Drawing utility functions
+SeeAlso: ???
+
+Feature: IMAGE_TRUECOLOR
+Section: Images
+Requires:
+Name: TrueColor QImage
+SeeAlso: ???
+
+Feature: IMAGE_SMOOTHSCALE
+Section: Images
+Requires:
+Name: Smooth QImage scaling
+SeeAlso: ???
+
+Feature: IMAGE_DITHER_TO_1
+Section: Images
+Requires:
+Name: Dither QImage to 1-bit image
+SeeAlso: ???
+
+Feature: IMAGE_HEURISTIC_MASK
+Section: Images
+Requires:
+Name: QImage::createHeuristicMask()
+SeeAlso: ???
+
+Feature: IMAGE_MIRROR
+Section: Images
+Requires:
+Name: QImage mirroring
+SeeAlso: ???
+
+Feature: IMAGE_TEXT
+Section: Images
+Requires: STRINGLIST
+Name: Image file text strings
+SeeAlso: ???
+
+Feature: IMAGE_16_BIT
+Section: Qt/Embedded-specific
+Requires: IMAGE_TRUECOLOR
+Name: 16-bit QImage
+SeeAlso: ???
+
+Feature: CURSOR
+Section: Kernel
+Requires:
+Name: Cursors
+SeeAlso: ???
+
+Feature: COLORNAMES
+Section: Painting
+Requires:
+Name: Named colors
+SeeAlso: ???
+
+Feature: TRANSFORMATIONS
+Section: Painting
+Requires: WMATRIX
+Name: Scaling and rotation
+SeeAlso: ???
+
+Feature: PIXMAP_TRANSFORMATION
+Section: Painting
+Requires: WMATRIX
+Name: Pixmap transformations
+SeeAlso: ???
+
+Feature: IMAGE_TRANSFORMATION
+Section: Painting
+Requires: PIXMAP_TRANSFORMATION
+Name: Image transformations
+SeeAlso: ???
+
+Feature: SVG
+Section: Painting
+Requires: DOM TRANSFORMATIONS SPRINTF
+Name: Scalable Vector Graphics (SVG)
+SeeAlso: ???
+
+Feature: BEZIER
+Section: Painting
+Requires:
+Name: Bezier curves
+SeeAlso: ???
+
+Feature: PRINTER
+Section: Painting
+Requires: TEXTSTREAM SPRINTF FONTDATABASE DATESTRING REGEXP_CAPTURE
+Name: Printing
+SeeAlso: ???
+
+Feature: PICTURE
+Section: Painting
+Requires: DATASTREAM IMAGEIO
+Name: QPicture
+SeeAlso: ???
+
+Feature: LAYOUT
+Section: Kernel
+Requires:
+Name: Automatic widget tqlayout
+SeeAlso: ???
+
+Feature: STYLE
+Section: Widgets
+Requires: DRAWUTIL
+Name: QStyle
+SeeAlso: ???
+
+Feature: WIDGET_TOPEXTRA
+Section: Kernel
+Requires: IMAGE_HEURISTIC_MASK
+Name: Window icon and caption
+SeeAlso: ???
+
+Feature: DIALOG
+Section: Widgets
+Requires:
+Name: Dialogs
+SeeAlso: ???
+
+Feature: SEMIMODAL
+Section: Widgets
+Requires: DIALOG
+Name: Semi-modal dialogs
+SeeAlso: ???
+
+Feature: FRAME
+Section: Widgets
+Requires: STYLE
+Name: Framed widgets
+SeeAlso: ???
+
+Feature: EFFECTS
+Section: Kernel
+Requires:
+Name: Special widget effects (fading, scrolling)
+SeeAlso: ???
+
+Feature: LABEL
+Section: Widgets
+Requires: FRAME
+Name: QLabel
+SeeAlso: ???
+
+Feature: TOOLBAR
+Section: Widgets
+Requires: MAINWINDOW
+Name: Toolbars
+SeeAlso: ???
+
+Feature: BUTTON
+Section: Widgets
+Requires:
+Name: Buttons
+SeeAlso: ???
+
+Feature: CHECKBOX
+Section: Widgets
+Requires: BUTTON STYLE
+Name: Check-boxes
+SeeAlso: ???
+
+Feature: RADIOBUTTON
+Section: Widgets
+Requires: BUTTON STYLE
+Name: Radio-buttons
+SeeAlso: ???
+
+Feature: TOOLBUTTON
+Section: Widgets
+Requires: BUTTON ICONSET STYLE
+Name: Tool-buttons
+SeeAlso: ???
+
+Feature: GRID
+Section: Widgets
+Requires: LAYOUT FRAME
+Name: Grid tqlayout widgets
+SeeAlso: ???
+
+Feature: GROUPBOX
+Section: Widgets
+Requires: FRAME LAYOUT
+Name: Group boxes
+SeeAlso: ???
+
+Feature: BUTTONGROUP
+Section: Widgets
+Requires: GROUPBOX BUTTON RADIOBUTTON
+Name: Button groups
+SeeAlso: ???
+
+Feature: HGROUPBOX
+Section: Widgets
+Requires: GROUPBOX
+Name: Horizontal group boxes
+SeeAlso: ???
+
+Feature: VGROUPBOX
+Section: Widgets
+Requires: HGROUPBOX
+Name: Vertical group boxes
+SeeAlso: ???
+
+Feature: HBUTTONGROUP
+Section: Widgets
+Requires: BUTTONGROUP
+Name: Horizontal button groups
+SeeAlso: ???
+
+Feature: VBUTTONGROUP
+Section: Widgets
+Requires: HBUTTONGROUP
+Name: Vertical button groups
+SeeAlso: ???
+
+Feature: HBOX
+Section: Widgets
+Requires: LAYOUT FRAME
+Name: Horizontal box tqlayout widgets
+SeeAlso: ???
+
+Feature: VBOX
+Section: Widgets
+Requires: HBOX
+Name: Vertical box tqlayout widgets
+SeeAlso: ???
+
+Feature: MAINWINDOW
+Section: Widgets
+Requires: STRINGLIST POPUPMENU TITLEBAR RESIZEHANDLER TOOLBUTTON STATUSBAR
+Name: Main-windows
+SeeAlso: ???
+
+Feature: RESIZEHANDLER
+Section: Widgets
+Requires: FRAME
+Name: Internal resize handler
+SeeAlso: ???
+
+Feature: MENUDATA
+Section: Widgets
+Requires: ICONSET VARIANT
+Name: Menu-oriented widgets
+SeeAlso: ???
+
+Feature: POPUPMENU
+Section: Widgets
+Requires: MENUDATA FRAME
+Name: Popup-menus
+SeeAlso: ???
+
+Feature: MENUBAR
+Section: Widgets
+Requires: POPUPMENU
+Name: Menu bars
+SeeAlso: ???
+
+Feature: PUSHBUTTON
+Section: Widgets
+Requires: BUTTON STYLE
+Name: Push-buttons
+SeeAlso: ???
+
+Feature: PROGRESSBAR
+Section: Widgets
+Requires: FRAME
+Name: Progress bars
+SeeAlso: ???
+
+Feature: RANGECONTROL
+Section: Widgets
+Requires:
+Name: Range-control widgets
+SeeAlso: ???
+
+Feature: SCROLLBAR
+Section: Widgets
+Requires: RANGECONTROL STYLE
+Name: Scroll bars
+SeeAlso: ???
+
+Feature: SLIDER
+Section: Widgets
+Requires: RANGECONTROL STYLE
+Name: Sliders
+SeeAlso: ???
+
+Feature: DIAL
+Section: Widgets
+Requires: RANGECONTROL STYLE
+Name: Dials
+SeeAlso: ???
+
+Feature: SPINWIDGET
+Section: Widgets
+Requires: FRAME
+Name: Spinbox control widget
+SeeAlso: ???
+
+Feature: SCROLLVIEW
+Section: Widgets
+Requires: SCROLLBAR FRAME
+Name: Scrollable view widgets
+SeeAlso: ???
+
+Feature: ICONVIEW
+Section: Widgets
+Requires: SCROLLVIEW IMAGEIO_XPM IMAGE_HEURISTIC_MASK
+Name: QIconView
+SeeAlso: ???
+
+Feature: GRIDVIEW
+Section: Widgets
+Requires: SCROLLVIEW
+Name: QGridView
+SeeAlso: ???
+
+Feature: TEXTVIEW
+Section: Widgets
+Requires: TEXTEDIT
+Name: QTextView
+SeeAlso: ???
+
+Feature: TEXTEDIT
+Section: Widgets
+Requires: RICHTEXT SCROLLVIEW
+Name: Rich text edit
+SeeAlso: ???
+
+Feature: SYNTAXHIGHLIGHTER
+Section: Widgets
+Requires: TEXTEDIT
+Name: Rich text syntax highlighting
+SeeAlso: ???
+
+Feature: SPLASHSCREEN
+Section: Widgets
+Requires: IMAGEIO
+Name: Splash screen widget
+SeeAlso: ???
+
+
+Feature: TABLEVIEW
+Section: Widgets
+Requires: SCROLLBAR
+Name: Table-like widgets
+SeeAlso: ???
+
+Feature: LINEEDIT
+Section: Widgets
+Requires: FRAME
+Name: Single-line edits
+SeeAlso: ???
+
+Feature: MULTILINEEDIT
+Section: Widgets
+Requires: TEXTEDIT
+Name: Multi-line edits
+SeeAlso: ???
+
+Feature: SPINBOX
+Section: Widgets
+Requires: RANGECONTROL SPINWIDGET LINEEDIT VALIDATOR
+Name: Spin boxes
+SeeAlso: ???
+
+Feature: SPLITTER
+Section: Widgets
+Requires: FRAME LAYOUT
+Name: Splitters
+SeeAlso: ???
+
+Feature: STATUSBAR
+Section: Widgets
+Requires: LAYOUT STYLE
+Name: tqStatus bars
+SeeAlso: ???
+
+Feature: TABBAR
+Section: Widgets
+Requires: TOOLBUTTON
+Name: Tab-bars
+SeeAlso: ???
+
+Feature: TABWIDGET
+Section: Widgets
+Requires: TABBAR WIDGETSTACK
+Name: Tab widgets
+SeeAlso: ???
+
+Feature: TOOLTIP
+Section: Widgets
+Requires: LABEL
+Name: Tool tips
+SeeAlso: ???
+
+Feature: VALIDATOR
+Section: Widgets
+Requires:
+Name: Input validators
+SeeAlso: ???
+
+Feature: WHATSTHIS
+Section: Widgets
+Requires: TOOLTIP TOOLBUTTON
+Name: "What's this" help
+SeeAlso: ???
+
+Feature: WIDGETSTACK
+Section: Widgets
+Requires: FRAME
+Name: Widget stacks
+SeeAlso: ???
+
+Feature: TEXTBROWSER
+Section: Widgets
+Requires: TEXTVIEW MIME
+Name: QTextBrowser
+SeeAlso: ???
+
+Feature: LISTBOX
+Section: Widgets
+Requires: SCROLLVIEW STRINGLIST
+Name: QListBox
+SeeAlso: ???
+
+Feature: ACCEL
+Section: Kernel
+Requires: SPRINTF
+Name: Keyboard accelerators and shortcuts
+SeeAlso: ???
+
+Feature: SIZEGRIP
+Section: Widgets
+Requires: STYLE
+Name: QSizeGrip
+SeeAlso: ???
+
+Feature: HEADER
+Section: Widgets
+Requires: STYLE ICONSET
+Name: QHeader
+SeeAlso: ???
+
+Feature: TITLEBAR
+Section: Kernel
+Requires: STYLE
+Name: Internal titlebar widget
+SeeAlso: ???
+
+Feature: LCDNUMBER
+Section: Widgets
+Requires: FRAME
+Name: QLCDNumber
+SeeAlso: ???
+
+Feature: ACTION
+Section: Kernel
+Requires: TOOLBUTTON COMBOBOX
+Name: QAction
+SeeAlso: ???
+
+Feature: COMBOBOX
+Section: Widgets
+Requires: LISTBOX LINEEDIT POPUPMENU
+Name: QComboBox
+SeeAlso: ???
+
+Feature: LISTVIEW
+Section: Widgets
+Requires: SCROLLVIEW HEADER LINEEDIT
+Name: QListView
+SeeAlso: ???
+
+Feature: STYLE_WINDOWS
+Section: Widgets
+Requires: STYLE
+Name: Windows style
+SeeAlso: ???
+
+Feature: STYLE_MOTIF
+Section: Widgets
+Requires: STYLE
+Name: Motif style
+SeeAlso: ???
+
+Feature: STYLE_INTERLACE
+Section: Widgets
+Requires: STYLE_MOTIF
+Name: Interlace-friendly style
+SeeAlso: ???
+
+Feature: STYLE_COMPACT
+Section: Widgets
+Requires: STYLE_WINDOWS
+Name: Compact Windows style
+SeeAlso: ???
+
+Feature: STYLE_PLATINUM
+Section: Widgets
+Requires: STYLE_WINDOWS
+Name: Platinum style
+SeeAlso: ???
+
+Feature: STYLE_AQUA
+Section: Widgets
+Requires: STYLE_WINDOWS IMAGE_TRANSFORMATION
+Name: Aqua style
+SeeAlso: ???
+
+Feature: STYLE_CDE
+Section: Widgets
+Requires: STYLE_MOTIF TRANSFORMATIONS
+Name: CDE style
+SeeAlso: ???
+
+Feature: STYLE_SGI
+Section: Widgets
+Requires: STYLE_MOTIF TRANSFORMATIONS BUTTON SCROLLBAR SLIDER LINEEDIT MENUBAR
+Name: SGI style
+SeeAlso: ???
+
+Feature: STYLE_MOTIFPLUS
+Section: Widgets
+Requires: STYLE_MOTIF TRANSFORMATIONS BUTTON SCROLLBAR SLIDER
+Name: Motif-plus style
+SeeAlso: ???
+
+Feature: COLORDIALOG
+Section: Widgets
+Requires: DIALOG LABEL PUSHBUTTON LINEEDIT VALIDATOR GRIDVIEW LAYOUT
+Name: QColorDialog
+SeeAlso: ???
+
+Feature: MESSAGEBOX
+Section: Widgets
+Requires: DIALOG PUSHBUTTON LABEL
+Name: QMessageBox
+SeeAlso: ???
+
+Feature: TABDIALOG
+Section: Widgets
+Requires: DIALOG PUSHBUTTON LAYOUT TABWIDGET
+Name: QTabDialog
+SeeAlso: ???
+
+Feature: WIZARD
+Section: Widgets
+Requires: DIALOG WIDGETSTACK PUSHBUTTON LAYOUT LABEL
+Name: QWizard
+SeeAlso: ???
+
+Feature: FILEDIALOG
+Section: Widgets
+Requires: MESSAGEBOX LISTVIEW NETWORKPROTOCOL COMBOBOX SEMIMODAL REGEXP_CAPTURE TOOLBUTTON BUTTONGROUP VBOX SPLITTER PROGRESSBAR WIDGETSTACK DATESTRING
+Name: QFileDialog
+SeeAlso: ???
+
+Feature: FONTDIALOG
+Section: Widgets
+Requires: DIALOG FONTDATABASE COMBOBOX LABEL CHECKBOX PUSHBUTTON VGROUPBOX VALIDATOR
+Name: QFontDialog
+SeeAlso: ???
+
+Feature: PRINTDIALOG
+Section: Widgets
+Requires: DIALOG LISTVIEW PRINTER COMBOBOX LABEL BUTTONGROUP SPINBOX RADIOBUTTON PUSHBUTTON DIR
+Name: QPrintDialog
+SeeAlso: ???
+
+Feature: PROGRESSDIALOG
+Section: Widgets
+Requires: SEMIMODAL LABEL PUSHBUTTON PROGRESSBAR
+Name: QProgressDialog
+SeeAlso: ???
+
+Feature: INPUTDIALOG
+Section: Widgets
+Requires: DIALOG COMBOBOX LABEL PUSHBUTTON SPINBOX WIDGETSTACK LAYOUT
+Name: QInputDialog
+SeeAlso: ???
+
+Feature: ERRORMESSAGE
+Section: Widgets
+Requires: DIALOG PUSHBUTTON LABEL CHECKBOX TEXTVIEW
+Name: QErrorMessage
+SeeAlso: ???
+
+Feature: SESSIONMANAGER
+Section: Kernel
+Requires: STRINGLIST
+Name: Session management
+SeeAlso: ???
+
+Feature: DATETIMEEDIT
+Section: Widgets
+Requires: RICHTEXT SPINWIDGET DATESTRING
+Name: QDateTimeEdit
+SeeAlso: ???
+
+Feature: TEXTCODECPLUGIN
+Section: Internationalization
+Requires: COMPONENT TEXTCODEC
+Name: QTextCodecPlugin
+SeeAlso: ???
+
+
+Feature: IMAGEFORMATPLUGIN
+Section: Images
+Requires: COMPONENT IMAGEIO
+Name: QImageFormatPlugin
+SeeAlso: ???
+
+
+Feature: WIDGETPLUGIN
+Section: Widgets
+Requires: COMPONENT ICONSET
+Name: QWidgetPlugin
+SeeAlso: ???
+
+
+Feature: DIRECTPAINTER
+Section: Painting
+Requires:
+Name: QDirectPainter
+SeeAlso: ???
+
+
+Feature: DIALOGBUTTONS
+Section: Widgets
+Requires: LAYOUT STYLE PUSHBUTTON
+Name: Experimental internal class
+SeeAlso: ???
diff --git a/tqtinterface/qt4/src/tools/qt_tools.pri b/tqtinterface/qt4/src/tools/qt_tools.pri
new file mode 100644
index 0000000..44c0c62
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/qt_tools.pri
@@ -0,0 +1,150 @@
+# Qt tools module
+
+tools {
+ TOOLS_P = tools
+ HEADERS += $$TOOLS_H/tqmemarray.h \
+ $$TOOLS_H/tqasciicache.h \
+ $$TOOLS_H/tqasciidict.h \
+ $$TOOLS_H/tqbitarray.h \
+ $$TOOLS_H/tqbuffer.h \
+ $$TOOLS_H/tqcache.h \
+ $$TOOLS_H/tqcleanuphandler.h \
+ $$TOOLS_P/tqcomponentfactory_p.h \
+ $$TOOLS_P/tqcomlibrary_p.h \
+ $$TOOLS_H/tqcstring.h \
+ $$TOOLS_H/tqdatastream.h \
+ $$TOOLS_H/tqdatetime.h \
+ $$TOOLS_H/tqdeepcopy.h \
+ $$TOOLS_H/tqdict.h \
+ $$TOOLS_H/tqdir.h \
+ $$TOOLS_P/tqdir_p.h \
+ $$TOOLS_H/tqfile.h \
+ $$TOOLS_P/tqfiledefs_p.h \
+ $$TOOLS_H/tqfileinfo.h \
+ $$TOOLS_H/tqgarray.h \
+ $$TOOLS_H/tqgcache.h \
+ $$TOOLS_H/tqgdict.h \
+ $$TOOLS_H/tqgeneric.h \
+ $$TOOLS_H/tqglist.h \
+ $$TOOLS_H/tqglobal.h \
+ $$TOOLS_P/tqgpluginmanager_p.h \
+ $$TOOLS_H/tqgvector.h \
+ $$TOOLS_H/tqintcache.h \
+ $$TOOLS_H/tqintdict.h \
+ $$TOOLS_H/tqiodevice.h \
+ $$TOOLS_H/tqlibrary.h \
+ $$TOOLS_P/tqlibrary_p.h \
+ $$TOOLS_H/tqlocale.h \
+ $$TOOLS_P/tqlocale_p.h \
+ $$TOOLS_H/tqptrlist.h \
+ $$TOOLS_H/tqmap.h \
+ $$TOOLS_H/tqmutex.h \
+ $$TOOLS_P/tqmutex_p.h \
+ $$TOOLS_P/tqmutexpool_p.h \
+ $$TOOLS_P/tqpluginmanager_p.h \
+ $$TOOLS_H/tqptrcollection.h \
+ $$TOOLS_H/tqptrdict.h \
+ $$TOOLS_H/tqptrqueue.h \
+ $$TOOLS_H/tqregexp.h \
+ $$TOOLS_H/tqsemaphore.h \
+ $$TOOLS_H/tqsettings.h \
+ $$TOOLS_P/tqsettings_p.h \
+ $$TOOLS_H/tqshared.h \
+ $$TOOLS_H/tqsortedlist.h \
+ $$TOOLS_H/tqptrstack.h \
+ $$TOOLS_H/tqstring.h \
+ $$TOOLS_H/tqstringlist.h \
+ $$TOOLS_H/tqstrlist.h \
+ $$TOOLS_H/tqstrvec.h \
+ $$TOOLS_H/tqtextstream.h \
+ $$TOOLS_P/tqthreadinstance_p.h \
+ $$TOOLS_H/tqthreadstorage.h\
+ $$TOOLS_P/tqunicodetables_p.h \
+ $$TOOLS_H/tqptrvector.h \
+ $$TOOLS_H/tqvaluelist.h \
+ $$TOOLS_H/tqvaluestack.h \
+ $$TOOLS_H/tqvaluevector.h \
+ $$TOOLS_H/tqwaitcondition.h \
+ $$TOOLS_P/tqcom_p.h \
+ $$TOOLS_P/tqucom_p.h \
+ $$TOOLS_H/tquuid.h
+
+ win32:SOURCES += $$TOOLS_CPP/tqdir_win.cpp \
+ $$TOOLS_CPP/tqfile_win.cpp \
+ $$TOOLS_CPP/tqfileinfo_win.cpp \
+ $$TOOLS_CPP/tqlibrary_win.cpp \
+ $$TOOLS_CPP/tqsettings_win.cpp \
+ $$TOOLS_CPP/tqmutex_win.cpp \
+ $$TOOLS_CPP/tqwaitcondition_win.cpp \
+ $$TOOLS_CPP/tqthreadstorage_win.cpp \
+ $$TOOLS_CPP/tqcriticalsection_p.cpp
+
+ win32-borland:SOURCES += $$TOOLS_CPP/tqwinexport.cpp
+
+ wince-* {
+ SOURCES -= $$TOOLS_CPP/tqdir_win.cpp \
+ $$TOOLS_CPP/tqfile_win.cpp \
+ $$TOOLS_CPP/tqfileinfo_win.cpp
+ SOURCES += $$TOOLS_CPP/tqdir_wce.cpp \
+ $$TOOLS_CPP/tqfile_wce.cpp \
+ $$TOOLS_CPP/tqfileinfo_wce.cpp
+ }
+
+ offmac:SOURCES += $$TOOLS_CPP/tqdir_mac.cpp \
+ $$TOOLS_CPP/tqfile_mac.cpp \
+ $$TOOLS_CPP/tqfileinfo_mac.cpp
+ else:unix:SOURCES += $$TOOLS_CPP/tqdir_unix.cpp \
+ $$TOOLS_CPP/tqfile_unix.cpp \
+ $$TOOLS_CPP/tqfileinfo_unix.cpp \
+ $$TOOLS_CPP/tqmutex_unix.cpp \
+ $$TOOLS_CPP/tqthreadstorage_unix.cpp \
+ $$TOOLS_CPP/tqwaitcondition_unix.cpp
+
+ mac:!x11:!embedded:SOURCES += $$TOOLS_CPP/tqsettings_mac.cpp
+ mac {
+ SOURCES+=3rdparty/dlcompat/dlfcn.c
+ INCLUDEPATH+=3rdparty/dlcompat
+ }
+ unix:SOURCES += $$TOOLS_CPP/tqlibrary_unix.cpp
+
+ SOURCES += $$TOOLS_CPP/tqbitarray.cpp \
+ $$TOOLS_CPP/tqbuffer.cpp \
+ $$TOOLS_CPP/tqcomponentfactory.cpp \
+ $$TOOLS_CPP/tqcomlibrary.cpp \
+ $$TOOLS_CPP/tqcstring.cpp \
+ $$TOOLS_CPP/tqdatastream.cpp \
+ $$TOOLS_CPP/tqdatetime.cpp \
+ $$TOOLS_CPP/tqdeepcopy.cpp \
+ $$TOOLS_CPP/tqdir.cpp \
+ $$TOOLS_CPP/tqfile.cpp \
+ $$TOOLS_CPP/tqfileinfo.cpp \
+ $$TOOLS_CPP/tqgarray.cpp \
+ $$TOOLS_CPP/tqgcache.cpp \
+ $$TOOLS_CPP/tqgdict.cpp \
+ $$TOOLS_CPP/tqglist.cpp \
+ $$TOOLS_CPP/tqglobal.cpp \
+ $$TOOLS_CPP/tqgpluginmanager.cpp \
+ $$TOOLS_CPP/tqgvector.cpp \
+ $$TOOLS_CPP/tqiodevice.cpp \
+ $$TOOLS_CPP/tqlibrary.cpp \
+ $$TOOLS_CPP/tqlocale.cpp \
+ $$TOOLS_CPP/tqmap.cpp \
+ $$TOOLS_CPP/tqmutexpool.cpp \
+ $$TOOLS_CPP/tqptrcollection.cpp \
+ $$TOOLS_CPP/tqregexp.cpp \
+ $$TOOLS_CPP/tqstring.cpp \
+ $$TOOLS_CPP/tqsemaphore.cpp \
+ $$TOOLS_CPP/tqsettings.cpp \
+ $$TOOLS_CPP/tqstringlist.cpp \
+ $$TOOLS_CPP/tqtextstream.cpp \
+ $$TOOLS_CPP/tqunicodetables.cpp \
+ $$TOOLS_CPP/tqucom.cpp \
+ $$TOOLS_CPP/tquuid.cpp
+
+ irix-cc* {
+ CXXFLAGS_PRELINK = $$TQMAKE_CXXFLAGS
+ CXXFLAGS_PRELINK -= -O2
+ QMAKE_PRE_LINK = $(CXX) -c $$CXXFLAGS_PRELINK -O1 $(INCPATH) -o $(OBJECTS_DIR)/tqlocale.o tools/tqlocale.cpp
+ }
+}
+
diff --git a/tqtinterface/qt4/src/tools/tqasciicache.h b/tqtinterface/qt4/src/tools/tqasciicache.h
new file mode 100644
index 0000000..9a8d820
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqasciicache.h
@@ -0,0 +1,125 @@
+/****************************************************************************
+**
+** Definition of TQAsciiCache template/macro class
+**
+** Created : 950209
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQASCIICACHE_H
+#define TQASCIICACHE_H
+
+#ifndef TQT_H
+#include "tqgcache.h"
+#endif // TQT_H
+
+
+template<class type>
+class TQAsciiCache
+#ifdef TQ_TQDOC
+ : public TQPtrCollection
+#else
+ : public TQGCache
+#endif
+{
+public:
+ TQAsciiCache( const TQAsciiCache<type> &c ) : TQGCache(c) {}
+ TQAsciiCache( int maxCost=100, int size=17, bool caseSensitive=TRUE,
+ bool copyKeys=TRUE )
+ : TQGCache( maxCost, size, AsciiKey, caseSensitive, copyKeys ) {}
+ ~TQAsciiCache() { clear(); }
+ TQAsciiCache<type> &operator=( const TQAsciiCache<type> &c )
+ { return (TQAsciiCache<type>&)TQGCache::operator=(c); }
+ int maxCost() const { return TQGCache::maxCost(); }
+ int totalCost() const { return TQGCache::totalCost(); }
+ void setMaxCost( int m ) { TQGCache::setMaxCost(m); }
+ uint count() const { return TQGCache::count(); }
+ uint size() const { return TQGCache::size(); }
+ bool isEmpty() const { return TQGCache::count() == 0; }
+ void clear() { TQGCache::clear(); }
+ bool insert( const char *k, const type *d, int c=1, int p=0 )
+ { return TQGCache::insert_other(k,(Item)d,c,p);}
+ bool remove( const char *k )
+ { return TQGCache::remove_other(k); }
+ type *take( const char *k )
+ { return (type *)TQGCache::take_other(k); }
+ type *tqfind( const char *k, bool ref=TRUE ) const
+ { return (type *)TQGCache::tqfind_other(k,ref);}
+ type *operator[]( const char *k ) const
+ { return (type *)TQGCache::tqfind_other(k);}
+ void statistics() const { TQGCache::statistics(); }
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQAsciiCache<void>::deleteItem( TQPtrCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void TQAsciiCache<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+
+template<class type>
+class TQAsciiCacheIterator : public TQGCacheIterator
+{
+public:
+ TQAsciiCacheIterator( const TQAsciiCache<type> &c ):TQGCacheIterator((TQGCache &)c) {}
+ TQAsciiCacheIterator( const TQAsciiCacheIterator<type> &ci)
+ : TQGCacheIterator( (TQGCacheIterator &)ci ) {}
+ TQAsciiCacheIterator<type> &operator=(const TQAsciiCacheIterator<type>&ci)
+ { return ( TQAsciiCacheIterator<type>&)TQGCacheIterator::operator=( ci ); }
+ uint count() const { return TQGCacheIterator::count(); }
+ bool isEmpty() const { return TQGCacheIterator::count() == 0; }
+ bool atFirst() const { return TQGCacheIterator::atFirst(); }
+ bool atLast() const { return TQGCacheIterator::atLast(); }
+ type *toFirst() { return (type *)TQGCacheIterator::toFirst(); }
+ type *toLast() { return (type *)TQGCacheIterator::toLast(); }
+ operator type *() const { return (type *)TQGCacheIterator::get(); }
+ type *current() const { return (type *)TQGCacheIterator::get(); }
+ const char *currentKey() const { return TQGCacheIterator::getKeyAscii(); }
+ type *operator()() { return (type *)TQGCacheIterator::operator()();}
+ type *operator++() { return (type *)TQGCacheIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)TQGCacheIterator::operator+=(j);}
+ type *operator--() { return (type *)TQGCacheIterator::operator--(); }
+ type *operator-=(uint j) { return (type *)TQGCacheIterator::operator-=(j);}
+};
+
+
+#endif // TQASCIICACHE_H
diff --git a/tqtinterface/qt4/src/tools/tqasciidict.h b/tqtinterface/qt4/src/tools/tqasciidict.h
new file mode 100644
index 0000000..fdab8b2
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqasciidict.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Definition of TQAsciiDict template class
+**
+** Created : 920821
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQASCIIDICT_H
+#define TQASCIIDICT_H
+
+#ifndef TQT_H
+#include "tqgdict.h"
+#endif // TQT_H
+
+template<class type>
+class TQAsciiDict
+#ifdef TQ_TQDOC
+ : public TQPtrCollection
+#else
+ : public TQGDict
+#endif
+{
+public:
+ TQAsciiDict(int size=17, bool caseSensitive=TRUE, bool copyKeys=TRUE )
+ : TQGDict(size,AsciiKey,caseSensitive,copyKeys) {}
+ TQAsciiDict( const TQAsciiDict<type> &d ) : TQGDict(d) {}
+ ~TQAsciiDict() { clear(); }
+ TQAsciiDict<type> &operator=(const TQAsciiDict<type> &d)
+ { return (TQAsciiDict<type>&)TQGDict::operator=(d); }
+ uint count() const { return TQGDict::count(); }
+ uint size() const { return TQGDict::size(); }
+ bool isEmpty() const { return TQGDict::count() == 0; }
+
+ void insert( const char *k, const type *d )
+ { TQGDict::look_ascii(k,(Item)d,1); }
+ void tqreplace( const char *k, const type *d )
+ { TQGDict::look_ascii(k,(Item)d,2); }
+ bool remove( const char *k ) { return TQGDict::remove_ascii(k); }
+ type *take( const char *k ) { return (type *)TQGDict::take_ascii(k); }
+ type *tqfind( const char *k ) const
+ { return (type *)((TQGDict*)this)->TQGDict::look_ascii(k,0,0); }
+ type *operator[]( const char *k ) const
+ { return (type *)((TQGDict*)this)->TQGDict::look_ascii(k,0,0); }
+
+ void clear() { TQGDict::clear(); }
+ void resize( uint n ) { TQGDict::resize(n); }
+ void statistics() const { TQGDict::statistics(); }
+
+#ifdef TQ_TQDOC
+protected:
+ virtual TQDataStream& read( TQDataStream &, TQPtrCollection::Item & );
+ virtual TQDataStream& write( TQDataStream &, TQPtrCollection::Item ) const;
+#endif
+
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQAsciiDict<void>::deleteItem( TQPtrCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void TQAsciiDict<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+template<class type>
+class TQAsciiDictIterator : public TQGDictIterator
+{
+public:
+ TQAsciiDictIterator(const TQAsciiDict<type> &d)
+ : TQGDictIterator((TQGDict &)d) {}
+ ~TQAsciiDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)TQGDictIterator::toFirst(); }
+ operator type *() const { return (type *)TQGDictIterator::get(); }
+ type *current() const { return (type *)TQGDictIterator::get(); }
+ const char *currentKey() const { return TQGDictIterator::getKeyAscii(); }
+ type *operator()() { return (type *)TQGDictIterator::operator()(); }
+ type *operator++() { return (type *)TQGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)TQGDictIterator::operator+=(j);}
+};
+
+#define TQ_DEFINED_TQASCIIDICT
+#include "tqwinexport.h"
+#endif // TQASCIIDICT_H
diff --git a/tqtinterface/qt4/src/tools/tqbitarray.cpp b/tqtinterface/qt4/src/tools/tqbitarray.cpp
new file mode 100644
index 0000000..a741314
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqbitarray.cpp
@@ -0,0 +1,670 @@
+/****************************************************************************
+**
+** Implementation of TQBitArray class
+**
+** Created : 940118
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqbitarray.h"
+#include "tqdatastream.h"
+
+#define SHBLOCK ((bitarr_data*)(sharedBlock()))
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \class TQBitVal tqbitarray.h
+ \reentrant
+ \brief The TQBitVal class is an internal class, used with TQBitArray.
+
+ \ingroup collection
+
+ The TQBitVal is required by the indexing [] operator on bit arrays.
+ It is not for use in any other context.
+*/
+
+/*!
+ \fn TQBitVal::TQBitVal (TQBitArray* a, uint i)
+
+ Constructs a reference to element \a i in the TQBitArray \a a.
+ This is what TQBitArray::operator[] constructs its return value
+ with.
+*/
+
+/*!
+ \fn TQBitVal::operator int()
+
+ Returns the value referenced by the TQBitVal.
+*/
+
+/*!
+ \fn TQBitVal& TQBitVal::operator= (const TQBitVal& v)
+
+ Sets the value referenced by the TQBitVal to that referenced by
+ TQBitVal \a v.
+*/
+
+/*!
+ \overload TQBitVal& TQBitVal::operator= (bool v)
+
+ Sets the value referenced by the TQBitVal to \a v.
+*/
+
+
+/*!
+ \class TQBitArray tqbitarray.h
+ \reentrant
+ \brief The TQBitArray class provides an array of bits.
+
+ \ingroup collection
+ \ingroup tools
+ \ingroup shared
+
+ Because TQBitArray is a TQMemArray, it uses explicit \link
+ shclass.html sharing\endlink with a reference count.
+
+ A TQBitArray is a special byte array that can access individual
+ bits and perform bit-operations (AND, OR, XOR and NOT) on entire
+ arrays or bits.
+
+ Bits can be manipulated by the setBit() and clearBit() functions,
+ but it is also possible to use the indexing [] operator to test
+ and set individual bits. The [] operator is a little slower than
+ setBit() and clearBit() because some tricks are required to
+ implement single-bit assignments.
+
+ Example:
+ \code
+ TQBitArray a(3);
+ a.setBit( 0 );
+ a.clearBit( 1 );
+ a.setBit( 2 ); // a = [1 0 1]
+
+ TQBitArray b(3);
+ b[0] = 1;
+ b[1] = 1;
+ b[2] = 0; // b = [1 1 0]
+
+ TQBitArray c;
+ c = ~a & b; // c = [0 1 0]
+ \endcode
+
+ When a TQBitArray is constructed the bits are uninitialized. Use
+ fill() to set all the bits to 0 or 1. The array can be resized
+ with resize() and copied with copy(). Bits can be set with
+ setBit() and cleared with clearBit(). Bits can be toggled with
+ toggleBit(). A bit's value can be obtained with testBit() and with
+ at().
+
+ TQBitArray supports the \& (AND), | (OR), ^ (XOR) and ~ (NOT)
+ operators.
+*/
+
+/*! \class TQBitArray::bitarr_data
+ \brief The TQBitArray::bitarr_data class is internal.
+ \internal
+*/
+
+
+/*!
+ Constructs an empty bit array.
+*/
+
+TQBitArray::TQBitArray() : TQByteArray( 0, 0 )
+{
+ bitarr_data *x = new bitarr_data;
+ TQ_CHECK_PTR( x );
+ x->nbits = 0;
+ setSharedBlock( x );
+}
+
+/*!
+ Constructs a bit array of \a size bits. The bits are uninitialized.
+
+ \sa fill()
+*/
+
+TQBitArray::TQBitArray( uint size ) : TQByteArray( 0, 0 )
+{
+ bitarr_data *x = new bitarr_data;
+ TQ_CHECK_PTR( x );
+ x->nbits = 0;
+ setSharedBlock( x );
+ resize( size );
+}
+
+/*!
+ \fn TQBitArray::TQBitArray( const TQBitArray &a )
+
+ Constructs a shallow copy of \a a.
+*/
+
+/*!
+ \fn TQBitArray &TQBitArray::operator=( const TQBitArray &a )
+
+ Assigns a shallow copy of \a a to this bit array and returns a
+ reference to this array.
+*/
+
+
+/*!
+ Pad last byte with 0-bits.
+*/
+void TQBitArray::pad0()
+{
+ uint sz = size();
+ if ( sz && sz%8 )
+ *(data()+sz/8) &= (1 << (sz%8)) - 1;
+}
+
+
+/*!
+ \fn uint TQBitArray::size() const
+
+ Returns the bit array's size (number of bits).
+
+ \sa resize()
+*/
+
+/*!
+ Resizes the bit array to \a size bits and returns TRUE if the bit
+ array could be resized; otherwise returns FALSE. The array becomes
+ a null array if \a size == 0.
+
+ If the array is expanded, the new bits are set to 0.
+
+ \sa size()
+*/
+
+bool TQBitArray::resize( uint size )
+{
+ uint s = this->size();
+ if ( !TQByteArray::resize( (size+7)/8 ) )
+ return FALSE; // cannot resize
+ SHBLOCK->nbits = size;
+ if ( size != 0 ) { // not null array
+ int ds = (int)(size+7)/8 - (int)(s+7)/8;// number of bytes difference
+ if ( ds > 0 ) // expanding array
+ memset( data() + (s+7)/8, 0, ds ); // reset new data
+ }
+ return TRUE;
+}
+
+
+/*!
+ Fills the bit array with \a v (1's if \a v is TRUE, or 0's if \a v
+ is FALSE).
+
+ fill() resizes the bit array to \a size bits if \a size is
+ nonnegative.
+
+ Returns FALSE if a nonnegative \e size was specified and the bit
+ array could not be resized; otherwise returns TRUE.
+
+ \sa resize()
+*/
+
+bool TQBitArray::fill( bool v, int size )
+{
+ if ( size >= 0 ) { // resize first
+ if ( !resize( size ) )
+ return FALSE; // cannot resize
+ } else {
+ size = this->size();
+ }
+ if ( size > 0 )
+ memset( data(), v ? 0xff : 0, (size + 7) / 8 );
+ if ( v )
+ pad0();
+ return TRUE;
+}
+
+
+/*!
+ Detaches from shared bit array data and makes sure that this bit
+ array is the only one referring to the data.
+
+ If multiple bit arrays share common data, this bit array
+ dereferences the data and gets a copy of the data. Nothing happens
+ if there is only a single reference.
+
+ \sa copy()
+*/
+
+void TQBitArray::detach()
+{
+ int nbits = SHBLOCK->nbits;
+ this->duplicate( *this );
+ SHBLOCK->nbits = nbits;
+}
+
+/*!
+ Returns a deep copy of the bit array.
+
+ \sa detach()
+*/
+
+TQBitArray TQBitArray::copy() const
+{
+ TQBitArray tmp;
+ tmp.duplicate( *this );
+ ((bitarr_data*)(tmp.sharedBlock()))->nbits = SHBLOCK->nbits;
+ return tmp;
+}
+
+
+/*!
+ Returns TRUE if the bit at position \a index is set, i.e. is 1;
+ otherwise returns FALSE.
+
+ \sa setBit(), clearBit()
+*/
+
+bool TQBitArray::testBit( uint index ) const
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( index >= size() ) {
+ qWarning( "TQBitArray::testBit: Index %d out of range", index );
+ return FALSE;
+ }
+#endif
+ return (*(data()+(index>>3)) & (1 << (index & 7))) != 0;
+}
+
+/*!
+ \overload
+
+ Sets the bit at position \a index to 1.
+
+ \sa clearBit() toggleBit()
+*/
+
+void TQBitArray::setBit( uint index )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( index >= size() ) {
+ qWarning( "TQBitArray::setBit: Index %d out of range", index );
+ return;
+ }
+#endif
+ *(data()+(index>>3)) |= (1 << (index & 7));
+}
+
+/*!
+ \fn void TQBitArray::setBit( uint index, bool value )
+
+ Sets the bit at position \a index to \a value.
+
+ Equivalent to:
+ \code
+ if ( value )
+ setBit( index );
+ else
+ clearBit( index );
+ \endcode
+
+ \sa clearBit() toggleBit()
+*/
+
+/*!
+ Clears the bit at position \a index, i.e. sets it to 0.
+
+ \sa setBit(), toggleBit()
+*/
+
+void TQBitArray::clearBit( uint index )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( index >= size() ) {
+ qWarning( "TQBitArray::clearBit: Index %d out of range", index );
+ return;
+ }
+#endif
+ *(data()+(index>>3)) &= ~(1 << (index & 7));
+}
+
+/*!
+ Toggles the bit at position \a index.
+
+ If the previous value was 0, the new value will be 1. If the
+ previous value was 1, the new value will be 0.
+
+ \sa setBit(), clearBit()
+*/
+
+bool TQBitArray::toggleBit( uint index )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( index >= size() ) {
+ qWarning( "TQBitArray::toggleBit: Index %d out of range", index );
+ return FALSE;
+ }
+#endif
+ register uchar *p = (uchar *)data() + (index>>3);
+ uchar b = (1 << (index & 7)); // bit position
+ uchar c = *p & b; // read bit
+ *p ^= b; // toggle bit
+ return c;
+}
+
+
+/*!
+ \fn bool TQBitArray::at( uint index ) const
+
+ Returns the value (0 or 1) of the bit at position \a index.
+
+ \sa operator[]()
+*/
+
+/*!
+ \fn TQBitVal TQBitArray::operator[]( int index )
+
+ Implements the [] operator for bit arrays.
+
+ The returned TQBitVal is a context object. It makes it possible to
+ get and set a single bit value by its \a index position.
+
+ Example:
+ \code
+ TQBitArray a( 3 );
+ a[0] = 0;
+ a[1] = 1;
+ a[2] = a[0] ^ a[1];
+ \endcode
+
+ The functions testBit(), setBit() and clearBit() are faster.
+
+ \sa at()
+*/
+
+/*!
+ \overload bool TQBitArray::operator[]( int index ) const
+
+ Implements the [] operator for constant bit arrays.
+*/
+
+
+/*!
+ Performs the AND operation between all bits in this bit array and
+ \a a. Returns a reference to this bit array.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+ \code
+ TQBitArray a( 3 ), b( 2 );
+ a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
+ b[0] = 1; b[1] = 0; // b = [1 0]
+ a &= b; // a = [1 0 0]
+ \endcode
+
+ \sa operator|=(), operator^=(), operator~()
+*/
+
+TQBitArray &TQBitArray::operator&=( const TQBitArray &a )
+{
+ resize( TQMAX(size(), a.size()) );
+ register uchar *a1 = (uchar *)data();
+ register uchar *a2 = (uchar *)a.data();
+ int n = TQMIN( TQByteArray::size(), a.TQByteArray::size() );
+ int p = TQMAX( TQByteArray::size(), a.TQByteArray::size() ) - n;
+ while ( n-- > 0 )
+ *a1++ &= *a2++;
+ while ( p-- > 0 )
+ *a1++ = 0;
+ return *this;
+}
+
+/*!
+ Performs the OR operation between all bits in this bit array and
+ \a a. Returns a reference to this bit array.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+ \code
+ TQBitArray a( 3 ), b( 2 );
+ a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
+ b[0] = 1; b[1] = 0; // b = [1 0]
+ a |= b; // a = [1 0 1]
+ \endcode
+
+ \sa operator&=(), operator^=(), operator~()
+*/
+
+TQBitArray &TQBitArray::operator|=( const TQBitArray &a )
+{
+ resize( TQMAX(size(), a.size()) );
+ register uchar *a1 = (uchar *)data();
+ register uchar *a2 = (uchar *)a.data();
+ int n = TQMIN( TQByteArray::size(), a.TQByteArray::size() );
+ while ( n-- > 0 )
+ *a1++ |= *a2++;
+ return *this;
+}
+
+/*!
+ Performs the XOR operation between all bits in this bit array and
+ \a a. Returns a reference to this bit array.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+ \code
+ TQBitArray a( 3 ), b( 2 );
+ a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
+ b[0] = 1; b[1] = 0; // b = [1 0]
+ a ^= b; // a = [0 0 1]
+ \endcode
+
+ \sa operator&=(), operator|=(), operator~()
+*/
+
+TQBitArray &TQBitArray::operator^=( const TQBitArray &a )
+{
+ resize( TQMAX(size(), a.size()) );
+ register uchar *a1 = (uchar *)data();
+ register uchar *a2 = (uchar *)a.data();
+ int n = TQMIN( TQByteArray::size(), a.TQByteArray::size() );
+ while ( n-- > 0 )
+ *a1++ ^= *a2++;
+ return *this;
+}
+
+/*!
+ Returns a bit array that tqcontains the inverted bits of this bit array.
+
+ Example:
+ \code
+ TQBitArray a( 3 ), b;
+ a[0] = 1; a[1] = 0; a[2] = 1; // a = [1 0 1]
+ b = ~a; // b = [0 1 0]
+ \endcode
+*/
+
+TQBitArray TQBitArray::operator~() const
+{
+ TQBitArray a( size() );
+ register uchar *a1 = (uchar *)data();
+ register uchar *a2 = (uchar *)a.data();
+ int n = TQByteArray::size();
+ while ( n-- )
+ *a2++ = ~*a1++;
+ a.pad0();
+ return a;
+}
+
+
+/*!
+ \relates TQBitArray
+
+ Returns the AND result between the bit arrays \a a1 and \a a2.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+
+ \sa TQBitArray::operator&=()
+*/
+
+TQBitArray operator&( const TQBitArray &a1, const TQBitArray &a2 )
+{
+ TQBitArray tmp = a1.copy();
+ tmp &= a2;
+ return tmp;
+}
+
+/*!
+ \relates TQBitArray
+
+ Returns the OR result between the bit arrays \a a1 and \a a2.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+
+ \sa TQBitArray::operator|=()
+*/
+
+TQBitArray operator|( const TQBitArray &a1, const TQBitArray &a2 )
+{
+ TQBitArray tmp = a1.copy();
+ tmp |= a2;
+ return tmp;
+}
+
+/*!
+ \relates TQBitArray
+
+ Returns the XOR result between the bit arrays \a a1 and \a a2.
+
+ The result has the length of the longest of the two bit arrays,
+ with any missing bits (i.e. if one array is shorter than the
+ other), taken to be 0.
+
+ \sa TQBitArray::operator^()
+*/
+
+TQBitArray operator^( const TQBitArray &a1, const TQBitArray &a2 )
+{
+ TQBitArray tmp = a1.copy();
+ tmp ^= a2;
+ return tmp;
+}
+
+
+/* \enum TQGArray::array_data
+
+ \warning This will be renamed in the next major release of TQt. Until
+ then it is undocumented and we recommend against its use.
+
+ \internal
+
+ ### 3.0 rename ###
+ ### 3.0 move it to TQGArray? ###
+*/
+
+
+/*!
+ \fn TQBitArray::array_data * TQBitArray::newData()
+
+ \internal
+
+ Returns data specific to TQBitArray that extends what TQGArray provides.
+ TQPtrCollection mechanism for allowing extra/different data.
+*/
+
+
+/*!
+ \fn void TQBitArray::deleteData ( array_data * d )
+
+ \internal
+
+ Deletes data specific to TQBitArray that extended what TQGArray provided.
+
+ TQPtrCollection mechanism for allowing extra/different data.
+*/
+
+
+/*****************************************************************************
+ TQBitArray stream functions
+ *****************************************************************************/
+
+/*!
+ \relates TQBitArray
+
+ Writes bit array \a a to stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+#ifndef TQT_NO_DATASTREAM
+TQDataStream &operator<<( TQDataStream &s, const TQBitArray &a )
+{
+ TQ_UINT32 len = a.size();
+ s << len; // write size of array
+ if ( len > 0 ) // write data
+ s.writeRawBytes( a.data(), a.TQByteArray::size() );
+ return s;
+}
+
+/*!
+ \relates TQBitArray
+
+ Reads a bit array into \a a from stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQBitArray &a )
+{
+ TQ_UINT32 len;
+ s >> len; // read size of array
+ if ( !a.resize( (uint)len ) ) { // resize array
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQDataStream: Not enough memory to read TQBitArray" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // read data
+ s.readRawBytes( a.data(), a.TQByteArray::size() );
+ return s;
+}
+
+#endif // USE_QT4
+
+#endif // TQT_NO_DATASTREAM
diff --git a/tqtinterface/qt4/src/tools/tqbitarray.h b/tqtinterface/qt4/src/tools/tqbitarray.h
new file mode 100644
index 0000000..4529162
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqbitarray.h
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Definition of TQBitArray class
+**
+** Created : 940118
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQBITARRAY_H
+#define TQBITARRAY_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qbitarray.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+// class TQBitArray;
+
+// class TQ_EXPORT TQBitVal : public QBitRef
+// {
+// public:
+// TQBitVal( QBitArray *a, uint i ) : QBitRef ( *a, i ) {}
+// };
+
+typedef QBitRef TQBitVal;
+
+class TQ_EXPORT TQBitArray : public QBitArray
+{
+public:
+ TQBitArray() : QBitArray() {}
+ TQBitArray( uint size ) : QBitArray( size ) {}
+ TQBitArray( const QBitArray &a ) : QBitArray( a ) {}
+
+ inline TQBitArray copy() const { return TQBitArray(*this); }
+ inline bool tqat( uint index ) const { return at(index); }
+};
+
+#else // USE_QT4
+
+/*****************************************************************************
+ TQBitVal class; a context class for TQBitArray::operator[]
+ *****************************************************************************/
+
+class TQBitArray;
+
+class TQ_EXPORT TQBitVal
+{
+private:
+ TQBitArray *array;
+ uint index;
+public:
+ TQBitVal( TQBitArray *a, uint i ) : array(a), index(i) {}
+ operator int();
+ TQBitVal &operator=( const TQBitVal &v );
+ TQBitVal &operator=( bool v );
+};
+
+
+/*****************************************************************************
+ TQBitArray class
+ *****************************************************************************/
+
+class TQ_EXPORT TQBitArray : public TQByteArray
+{
+public:
+ TQBitArray();
+ TQBitArray( uint size );
+ TQBitArray( const TQBitArray &a ) : TQByteArray( a ) {}
+
+ TQBitArray &operator=( const TQBitArray & );
+
+ uint size() const;
+ bool resize( uint size );
+
+ bool fill( bool v, int size = -1 );
+
+ void detach();
+ TQBitArray copy() const;
+
+ bool testBit( uint index ) const;
+ void setBit( uint index );
+ void setBit( uint index, bool value );
+ void clearBit( uint index );
+ bool toggleBit( uint index );
+
+ bool at( uint index ) const;
+ bool tqat( uint index ) const { return at(index); }
+ TQBitVal operator[]( int index );
+ bool operator[]( int index ) const;
+
+ TQBitArray &operator&=( const TQBitArray & );
+ TQBitArray &operator|=( const TQBitArray & );
+ TQBitArray &operator^=( const TQBitArray & );
+ TQBitArray operator~() const;
+
+protected:
+ struct bitarr_data : public TQGArray::array_data {
+ uint nbits;
+ };
+ array_data *newData() { return new bitarr_data; }
+ void deleteData( array_data *d ) { delete (bitarr_data*)d; }
+private:
+ void pad0();
+};
+
+
+inline TQBitArray &TQBitArray::operator=( const TQBitArray &a )
+{ return (TQBitArray&)assign( a ); }
+
+inline uint TQBitArray::size() const
+{ return ((bitarr_data*)sharedBlock())->nbits; }
+
+inline void TQBitArray::setBit( uint index, bool value )
+{ if ( value ) setBit(index); else clearBit(index); }
+
+inline bool TQBitArray::at( uint index ) const
+{ return testBit(index); }
+
+inline TQBitVal TQBitArray::operator[]( int index )
+{ return TQBitVal( (TQBitArray*)this, index ); }
+
+inline bool TQBitArray::operator[]( int index ) const
+{ return testBit( index ); }
+
+
+/*****************************************************************************
+ Misc. TQBitArray operator functions
+ *****************************************************************************/
+
+TQ_EXPORT TQBitArray operator&( const TQBitArray &, const TQBitArray & );
+TQ_EXPORT TQBitArray operator|( const TQBitArray &, const TQBitArray & );
+TQ_EXPORT TQBitArray operator^( const TQBitArray &, const TQBitArray & );
+
+
+inline TQBitVal::operator int()
+{
+ return array->testBit( index );
+}
+
+inline TQBitVal &TQBitVal::operator=( const TQBitVal &v )
+{
+ array->setBit( index, v.array->testBit(v.index) );
+ return *this;
+}
+
+inline TQBitVal &TQBitVal::operator=( bool v )
+{
+ array->setBit( index, v );
+ return *this;
+}
+
+
+/*****************************************************************************
+ TQBitArray stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQBitArray & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQBitArray & );
+#endif
+
+#endif // USE_QT4
+
+#endif // TQBITARRAY_H
diff --git a/tqtinterface/qt4/src/tools/tqbuffer.cpp b/tqtinterface/qt4/src/tools/tqbuffer.cpp
new file mode 100644
index 0000000..81ad242
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqbuffer.cpp
@@ -0,0 +1,503 @@
+/****************************************************************************
+**
+** Implementation of TQBuffer class
+**
+** Created : 930812
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqbuffer.h"
+#include <stdlib.h>
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \class TQBuffer tqbuffer.h
+ \reentrant
+ \brief The TQBuffer class is an I/O tqdevice that operates on a TQByteArray.
+
+ \ingroup io
+ \ingroup collection
+
+ TQBuffer is used to read and write to a memory buffer. It is
+ normally used with a TQTextStream or a TQDataStream. TQBuffer has an
+ associated TQByteArray which holds the buffer data. The size() of
+ the buffer is automatically adjusted as data is written.
+
+ The constructor \c TQBuffer(TQByteArray) creates a TQBuffer using an
+ existing byte array. The byte array can also be set with
+ setBuffer(). Writing to the TQBuffer will modify the original byte
+ array because TQByteArray is \link shclass.html explicitly
+ shared.\endlink
+
+ Use open() to open the buffer before use and to set the mode
+ (read-only, write-only, etc.). close() closes the buffer. The
+ buffer must be closed before reopening or calling setBuffer().
+
+ A common way to use TQBuffer is through \l TQDataStream or \l
+ TQTextStream, which have constructors that take a TQBuffer
+ parameter. For convenience, there are also TQDataStream and
+ TQTextStream constructors that take a TQByteArray parameter. These
+ constructors create and open an internal TQBuffer.
+
+ Note that TQTextStream can also operate on a TQString (a Unicode
+ string); a TQBuffer cannot.
+
+ You can also use TQBuffer directly through the standard TQIODevice
+ functions readBlock(), writeBlock() readLine(), at(), getch(),
+ putch() and ungetch().
+
+ \sa TQFile, TQDataStream, TQTextStream, TQByteArray, \link shclass.html Shared Classes\endlink
+*/
+
+
+/*!
+ Constructs an empty buffer.
+*/
+
+TQBuffer::TQBuffer()
+{
+ setFlags( IO_Direct );
+ a_inc = 16; // initial increment
+ a_len = 0;
+ ioIndex = 0;
+}
+
+
+/*!
+ Constructs a buffer that operates on \a buf.
+
+ If you open the buffer in write mode (\c IO_WriteOnly or
+ \c IO_ReadWrite) and write something into the buffer, \a buf
+ will be modified.
+
+ Example:
+ \code
+ TQCString str = "abc";
+ TQBuffer b( str );
+ b.open( IO_WriteOnly );
+ b.at( 3 ); // position at the 4th character (the terminating \0)
+ b.writeBlock( "def", 4 ); // write "def" including the terminating \0
+ b.close();
+ // Now, str == "abcdef" with a terminating \0
+ \endcode
+
+ \sa setBuffer()
+*/
+
+TQBuffer::TQBuffer( TQByteArray buf ) : a(buf)
+{
+ setFlags( IO_Direct );
+ a_len = a.size();
+ a_inc = (a_len > 512) ? 512 : a_len; // initial increment
+ if ( a_inc < 16 )
+ a_inc = 16;
+ ioIndex = 0;
+}
+
+/*!
+ Destroys the buffer.
+*/
+
+TQBuffer::~TQBuffer()
+{
+}
+
+
+/*!
+ Replaces the buffer's contents with \a buf and returns TRUE.
+
+ Does nothing (and returns FALSE) if isOpen() is TRUE.
+
+ Note that if you open the buffer in write mode (\c IO_WriteOnly or
+ IO_ReadWrite) and write something into the buffer, \a buf is also
+ modified because TQByteArray is an explicitly shared class.
+
+ \sa buffer(), open(), close()
+*/
+
+bool TQBuffer::setBuffer( TQByteArray buf )
+{
+ if ( isOpen() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQBuffer::setBuffer: Buffer is open" );
+#endif
+ return FALSE;
+ }
+ a = buf;
+ a_len = a.size();
+ a_inc = (a_len > 512) ? 512 : a_len; // initial increment
+ if ( a_inc < 16 )
+ a_inc = 16;
+ ioIndex = 0;
+ return TRUE;
+}
+
+/*!
+ \fn TQByteArray TQBuffer::buffer() const
+
+ Returns this buffer's byte array.
+
+ \sa setBuffer()
+*/
+
+/*!
+ \reimp
+
+ Opens the buffer in mode \a m. Returns TRUE if successful;
+ otherwise returns FALSE. The buffer must be opened before use.
+
+ The mode parameter \a m must be a combination of the following flags.
+ \list
+ \i \c IO_ReadOnly opens the buffer in read-only mode.
+ \i \c IO_WriteOnly opens the buffer in write-only mode.
+ \i \c IO_ReadWrite opens the buffer in read/write mode.
+ \i \c IO_Append sets the buffer index to the end of the buffer.
+ \i \c IO_Truncate truncates the buffer.
+ \endlist
+
+ \sa close(), isOpen()
+*/
+
+bool TQBuffer::open( int m )
+{
+ if ( isOpen() ) { // buffer already open
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQBuffer::open: Buffer already open" );
+#endif
+ return FALSE;
+ }
+ setMode( m );
+ if ( m & IO_Truncate ) { // truncate buffer
+ a.resize( 0 );
+ a_len = 0;
+ }
+ if ( m & IO_Append ) { // append to end of buffer
+ ioIndex = a.size();
+ } else {
+ ioIndex = 0;
+ }
+ a_inc = 16;
+ setState( IO_Open );
+ resetqStatus();
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Closes an open buffer.
+
+ \sa open()
+*/
+
+void TQBuffer::close()
+{
+ if ( isOpen() ) {
+ setFlags( IO_Direct );
+ ioIndex = 0;
+ a_inc = 16;
+ }
+}
+
+/*!
+ \reimp
+
+ The flush function does nothing for a TQBuffer.
+*/
+
+void TQBuffer::flush()
+{
+ return;
+}
+
+
+/*!
+ \fn TQIODevice::Offset TQBuffer::at() const
+
+ \reimp
+*/
+
+/*!
+ \fn TQIODevice::Offset TQBuffer::size() const
+
+ \reimp
+*/
+
+/*!
+ \reimp
+*/
+
+bool TQBuffer::at( Offset pos )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "TQBuffer::at: Buffer is not open" );
+ return FALSE;
+ }
+#endif
+ if ( pos > a_len ) {
+#if defined(TQT_CHECK_RANGE)
+#if defined(TQT_ABI_QT4)
+ qWarning( "TQBuffer::at: Index %lld out of range", pos );
+#else
+ qWarning( "TQBuffer::at: Index %lu out of range", pos );
+#endif
+#endif
+ return FALSE;
+ }
+ ioIndex = pos;
+ return TRUE;
+}
+
+
+/*!
+ \reimp
+*/
+
+TQ_LONG TQBuffer::readBlock( char *p, TQ_ULONG len )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !p ) {
+ qWarning( "TQBuffer::readBlock: Null pointer error" );
+ return -1;
+ }
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "TQBuffer::readBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "TQBuffer::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( ioIndex + len > a.size() ) { // overflow
+ if ( ioIndex >= a.size() ) {
+ return 0;
+ } else {
+ len = a.size() - ioIndex;
+ }
+ }
+ memcpy(p, a.data() + ioIndex, len);
+ ioIndex += len;
+ return len;
+}
+
+/*!
+ \overload TQ_LONG TQBuffer::writeBlock( const TQByteArray& data )
+
+ This convenience function is the same as calling
+ \c{writeBlock( data.data(), data.size() )} with \a data.
+*/
+
+/*!
+ Writes \a len bytes from \a p into the buffer at the current
+ index position, overwriting any characters there and extending the
+ buffer if necessary. Returns the number of bytes actually written.
+
+ Returns -1 if an error occurred.
+
+ \sa readBlock()
+*/
+
+TQ_LONG TQBuffer::writeBlock( const char *p, TQ_ULONG len )
+{
+ if ( len == 0 )
+ return 0;
+
+#if defined(TQT_CHECK_NULL)
+ if ( p == 0 ) {
+ qWarning( "TQBuffer::writeBlock: Null pointer error" );
+ return -1;
+ }
+#endif
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "TQBuffer::writeBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "TQBuffer::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( ioIndex + len > a_len ) { // overflow
+ TQ_ULONG new_len = a_len + a_inc*((ioIndex+len-a_len)/a_inc+1);
+ if ( !a.resize( new_len ) ) { // could not resize
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQBuffer::writeBlock: Memory allocation error" );
+#endif
+ setqStatus( IO_ResourceError );
+ return -1;
+ }
+ a_inc *= 2; // double increment
+ a_len = new_len;
+ a.shd->len = ioIndex + len;
+ }
+ memcpy( a.data()+ioIndex, p, len );
+ ioIndex += len;
+ if ( a.shd->len < ioIndex )
+ a.shd->len = ioIndex; // fake (not alloc'd) length
+ return len;
+}
+
+
+/*!
+ \reimp
+*/
+
+TQ_LONG TQBuffer::readLine( char *p, TQ_ULONG maxlen )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( p == 0 ) {
+ qWarning( "TQBuffer::readLine: Null pointer error" );
+ return -1;
+ }
+#endif
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "TQBuffer::readLine: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "TQBuffer::readLine: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( maxlen == 0 )
+ return 0;
+ TQ_ULONG start = ioIndex;
+ char *d = a.data() + ioIndex;
+ maxlen--; // make room for 0-terminator
+ if ( a.size() - ioIndex < maxlen )
+ maxlen = a.size() - ioIndex;
+ while ( maxlen-- ) {
+ if ( (*p++ = *d++) == '\n' )
+ break;
+ }
+ *p = '\0';
+ ioIndex = d - a.data();
+ return ioIndex - start;
+}
+
+
+/*!
+ \reimp
+*/
+
+int TQBuffer::getch()
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "TQBuffer::getch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "TQBuffer::getch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( ioIndex+1 > a.size() ) { // overflow
+ setqStatus( IO_ReadError );
+ return -1;
+ }
+ return uchar(*(a.data()+ioIndex++));
+}
+
+/*!
+ \reimp
+
+ Writes the character \a ch into the buffer at the current index
+ position, overwriting any existing character and extending the
+ buffer if necessary.
+
+ Returns \a ch, or -1 if an error occurred.
+
+ \sa getch(), ungetch()
+*/
+
+int TQBuffer::putch( int ch )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "TQBuffer::putch: Buffer not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "TQBuffer::putch: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( ioIndex + 1 > a_len ) { // overflow
+ char buf[1];
+ buf[0] = (char)ch;
+ if ( writeBlock(buf,1) != 1 )
+ return -1; // write error
+ } else {
+ *(a.data() + ioIndex++) = (char)ch;
+ if ( a.shd->len < ioIndex )
+ a.shd->len = ioIndex;
+ }
+ return ch;
+}
+
+/*!
+ \reimp
+*/
+
+int TQBuffer::ungetch( int ch )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) { // buffer not open
+ qWarning( "TQBuffer::ungetch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "TQBuffer::ungetch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( ch != -1 ) {
+ if ( ioIndex )
+ ioIndex--;
+ else
+ ch = -1;
+ }
+ return ch;
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/tools/tqbuffer.h b/tqtinterface/qt4/src/tools/tqbuffer.h
new file mode 100644
index 0000000..1cc3fd0
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqbuffer.h
@@ -0,0 +1,220 @@
+/****************************************************************************
+**
+** Definition of TQBuffer class
+**
+** Created : 930812
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQBUFFER_H
+#define TQBUFFER_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqiodevice.h"
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qbuffer.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQBuffer : public QBuffer
+{
+public:
+#if defined(TQT_ABI_QT4)
+ typedef TQ_LLONG Offset;
+#else
+ typedef TQ_ULONG Offset;
+#endif
+
+ #warning Please remember that TQByteArray is no longer explicitly shared. If you get weird crashes while using TQt stream objects please see tqbuffer.h line 69
+ // NOTE:
+ // QByteArray was explicitly shared in Qt3
+ // This is no longer the case in Qt4
+ // If you get weird crashes inside TQBuffer, it probably means you did something like this:
+ //
+ // main() {
+ // aFunction();
+ // otherFunction();
+ // }
+ //
+ // aFunction() {
+ // TQBuffer m_Buffer(QByteArray());
+ // }
+ //
+ // otherFunction() {
+ // m_Buffer.putch('H');
+ // }
+ //
+ // The QByteArray object was created within aFunction, but as it went out of scope it was destroyed before otherFunction was called
+ // Therefore, the TQBuffer's internal reference to the TQByteArray was invalid at the time putch() was called
+ // You could do this instead:
+ //
+ // aFunction() {
+ // TQBuffer m_Buffer();
+ // m_Buffer.tqsetBufferFromCopy(QByteArray());
+ // }
+
+ TQBuffer() : QBuffer() {}
+ TQBuffer( TQByteArray &ba ) : QBuffer( &ba, 0 ) {}
+ TQBuffer( const TQByteArray &ba ) : QBuffer( const_cast<TQByteArray*>(&ba), 0 ) {}
+// TQBuffer( TQByteArray ba ) : QBuffer(), internal_ba_copy(ba) { QBuffer::setBuffer(&internal_ba_copy); } // Make a copy of ba
+
+ inline int state() const { return isOpen() ? 0x1000 : 0; }
+ inline int mode() const { return (int) openMode(); }
+ inline int flags() const { return (int) openMode(); }
+ inline bool tqopen( int mode ) { return open((OpenModeFlag)mode); }
+
+ inline Offset at() const { return pos(); }
+ inline bool at(Offset offset) { return seek(offset); }
+ inline Offset tqat() const { return pos(); }
+ inline bool tqat(Offset offset) { return seek(offset); }
+
+// virtual inline qint64 readBlock(char *data, quint64 maxlen) { return read(data, maxlen); }
+// virtual inline qint64 writeBlock(const char *data, quint64 len) { return write(data, len); }
+// virtual inline qint64 writeBlock(const QByteArray &data) { return write(data); }
+ inline qint64 readBlock(char *data, quint64 maxlen) { return read(data, maxlen); }
+ inline qint64 writeBlock(const char *data, quint64 len) { return write(data, len); }
+ inline qint64 writeBlock(const QByteArray &data) { return write(data); }
+
+// virtual inline qint64 readData ( char * data, qint64 maxSize ) { return readBlock(data, maxSize); }
+// virtual inline qint64 writeData ( const char * data, qint64 maxSize ) { return writeBlock(data, maxSize); }
+
+ inline int getch() { char c; return getChar(&c) ? int(uchar(c)) : -1; }
+ inline int putch(int c) { return putChar(char(c)) ? int(uchar(c)) : -1; }
+ inline int ungetch(int c) { ungetChar(uchar(c)); return c; }
+
+ inline bool isDirectAccess() const { return !isSequential(); }
+ inline bool isSequentialAccess() const { return isSequential(); }
+ inline bool isCombinedAccess() const { return false; }
+ inline bool isBuffered() const { return true; }
+ inline bool isRaw() const { return false; }
+ inline bool isSynchronous() const { return true; }
+ inline bool isAsynchronous() const { return false; }
+ inline bool isTranslated() const { return (openMode() & Text) != 0; }
+ inline bool isInactive() const { return !isOpen(); }
+
+ inline TQByteArray &buffer() { return static_cast<TQByteArray&>(QBuffer::buffer()); }
+ inline bool setBuffer( TQByteArray &tqba ) { if (isOpen() == TRUE) return FALSE; QBuffer::setBuffer(&tqba); return TRUE; }
+ inline bool tqsetBufferFromCopy( TQByteArray tqba ) { if (isOpen() == TRUE) return FALSE; internal_ba_copy = tqba; QBuffer::setBuffer(&internal_ba_copy); return TRUE; }
+// inline bool setBuffer( TQByteArray tqba ) { if (isOpen() == TRUE) return FALSE; internal_ba_copy = tqba; QBuffer::setBuffer(&internal_ba_copy); return TRUE; }
+
+public:
+ typedef int Status;
+ Status status() const {
+#if !defined(QT_NO_QOBJECT)
+ const QFile *f = qobject_cast<const QFile *>(this);
+ if (f) return (int) f->error();
+#endif
+ return isOpen() ? 0 /* IO_Ok */ : 8 /* IO_UnspecifiedError */;
+ }
+ void resetStatus() {
+#if !defined(QT_NO_QOBJECT)
+ QFile *f = qobject_cast<QFile *>(this);
+ if (f) f->unsetError();
+#endif
+ }
+
+protected:
+ void setqStatus( int ) { std::cout << "[WARNING] TQBuffer::setqStatus() UNIMPLEMENTED\n\r"; }
+ void resetqStatus() { resetStatus(); }
+
+private:
+ TQByteArray internal_ba_copy;
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQBuffer : public TQIODevice
+{
+public:
+ TQBuffer();
+ TQBuffer( TQByteArray );
+ ~TQBuffer();
+
+ TQByteArray buffer() const;
+ bool setBuffer( TQByteArray );
+
+ bool open( int );
+ void close();
+ void flush();
+
+ Offset size() const;
+ Offset at() const;
+ bool at( Offset );
+
+ TQ_LONG readBlock( char *p, TQ_ULONG );
+ TQ_LONG writeBlock( const char *p, TQ_ULONG );
+ TQ_LONG writeBlock( const TQByteArray& data )
+ { return TQIODevice::writeBlock(data); }
+ TQ_LONG readLine( char *p, TQ_ULONG );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+
+protected:
+ TQByteArray a;
+
+private:
+ uint a_len;
+ uint a_inc;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQBuffer( const TQBuffer & );
+ TQBuffer &operator=( const TQBuffer & );
+#endif
+};
+
+
+inline TQByteArray TQBuffer::buffer() const
+{ return a; }
+
+inline TQIODevice::Offset TQBuffer::size() const
+{ return (Offset)a.size(); }
+
+inline TQIODevice::Offset TQBuffer::at() const
+{ return ioIndex; }
+
+#endif // USE_QT4
+
+#endif // TQBUFFER_H
diff --git a/tqtinterface/qt4/src/tools/tqbuffer.h~ b/tqtinterface/qt4/src/tools/tqbuffer.h~
new file mode 100644
index 0000000..c939e50
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqbuffer.h~
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Definition of TQBuffer class
+**
+** Created : 930812
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQBUFFER_H
+#define TQBUFFER_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqiodevice.h"
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qbuffer.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQBuffer : public QBuffer
+{
+public:
+#if defined(TQT_ABI_QT4)
+ typedef TQ_LLONG Offset;
+#else
+ typedef TQ_ULONG Offset;
+#endif
+
+ #warning Please remember that TQByteArray is no longer explicitly shared. If you get weird crashes while using TQt stream objects please see tqbuffer.h line 69
+ // NOTE:
+ // QByteArray was explicitly shared in Qt3
+ // This is no longer the case in Qt4
+ // If you get weird crashes inside TQBuffer, it probably means you did something like this:
+ //
+ // main() {
+ // aFunction();
+ // otherFunction();
+ // }
+ //
+ // aFunction() {
+ // TQBuffer m_Buffer(QByteArray());
+ // }
+ //
+ // otherFunction() {
+ // m_Buffer.putch('H');
+ // }
+ //
+ // The QByteArray object was created within aFunction, but as it went out of scope it was destroyed before otherFunction was called
+ // Therefore, the TQBuffer's internal reference to the TQByteArray was invalid at the time putch() was called
+ // You could do this instead:
+ //
+ // aFunction() {
+ // TQBuffer m_Buffer();
+ // m_Buffer.tqsetBufferFromCopy(QByteArray());
+ // }
+
+ TQBuffer() : QBuffer() {}
+ TQBuffer( TQByteArray &ba ) : QBuffer( &ba, 0 ) {}
+ TQBuffer( const TQByteArray &ba ) : QBuffer( const_cast<TQByteArray*>(&ba), 0 ) {}
+// TQBuffer( TQByteArray ba ) : QBuffer(), internal_ba_copy(ba) { QBuffer::setBuffer(&internal_ba_copy); } // Make a copy of ba
+
+ inline int state() const { return isOpen() ? 0x1000 : 0; }
+ inline int mode() const { return (int) openMode(); }
+ inline int flags() const { return (int) openMode(); }
+ inline bool tqopen( int mode ) { return open((OpenModeFlag)mode); }
+
+ inline Offset at() const { return pos(); }
+ inline bool at(Offset offset) { return seek(offset); }
+ inline Offset tqat() const { return pos(); }
+ inline bool tqat(Offset offset) { return seek(offset); }
+
+// virtual inline qint64 readBlock(char *data, quint64 maxlen) { return read(data, maxlen); }
+// virtual inline qint64 writeBlock(const char *data, quint64 len) { return write(data, len); }
+// virtual inline qint64 writeBlock(const QByteArray &data) { return write(data); }
+ inline qint64 readBlock(char *data, quint64 maxlen) { return read(data, maxlen); }
+ inline qint64 writeBlock(const char *data, quint64 len) { return write(data, len); }
+ inline qint64 writeBlock(const QByteArray &data) { return write(data); }
+
+// virtual inline qint64 readData ( char * data, qint64 maxSize ) { return readBlock(data, maxSize); }
+// virtual inline qint64 writeData ( const char * data, qint64 maxSize ) { return writeBlock(data, maxSize); }
+
+ inline int getch() { char c; return getChar(&c) ? int(uchar(c)) : -1; }
+ inline int putch(int c) { return putChar(char(c)) ? int(uchar(c)) : -1; }
+ inline int ungetch(int c) { ungetChar(uchar(c)); return c; }
+
+ inline bool isDirectAccess() const { return !isSequential(); }
+ inline bool isSequentialAccess() const { return isSequential(); }
+ inline bool isCombinedAccess() const { return false; }
+ inline bool isBuffered() const { return true; }
+ inline bool isRaw() const { return false; }
+ inline bool isSynchronous() const { return true; }
+ inline bool isAsynchronous() const { return false; }
+ inline bool isTranslated() const { return (openMode() & Text) != 0; }
+ inline bool isInactive() const { return !isOpen(); }
+
+ inline TQByteArray &buffer() { return static_cast<TQByteArray&>(QBuffer::buffer()); }
+ inline bool setBuffer( TQByteArray &tqba ) { if (isOpen() == TRUE) return FALSE; QBuffer::setBuffer(&tqba); return TRUE; }
+ inline bool tqsetBufferFromCopy( TQByteArray tqba ) { if (isOpen() == TRUE) return FALSE; internal_ba_copy = tqba; QBuffer::setBuffer(&internal_ba_copy); return TRUE; }
+// inline bool setBuffer( TQByteArray tqba ) { if (isOpen() == TRUE) return FALSE; internal_ba_copy = tqba; QBuffer::setBuffer(&internal_ba_copy); return TRUE; }
+
+public:
+ typedef int Status;
+ Status status() const {
+#if !defined(QT_NO_QOBJECT)
+ const QFile *f = qobject_cast<const QFile *>(this);
+ if (f) return (int) f->error();
+#endif
+ return isOpen() ? 0 /* IO_Ok */ : 8 /* IO_UnspecifiedError */;
+ }
+ void resetStatus() {
+#if !defined(QT_NO_QOBJECT)
+ QFile *f = qobject_cast<QFile *>(this);
+ if (f) f->unsetError();
+#endif
+ }
+
+ void setqStatus( int ) { std::cout << "[WARNING] TQBuffer::setqStatus() UNIMPLEMENTED\n\r"; }
+ void resetqStatus() { resetStatus(); }
+
+private:
+ TQByteArray internal_ba_copy;
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQBuffer : public TQIODevice
+{
+public:
+ TQBuffer();
+ TQBuffer( TQByteArray );
+ ~TQBuffer();
+
+ TQByteArray buffer() const;
+ bool setBuffer( TQByteArray );
+
+ bool open( int );
+ void close();
+ void flush();
+
+ Offset size() const;
+ Offset at() const;
+ bool at( Offset );
+
+ TQ_LONG readBlock( char *p, TQ_ULONG );
+ TQ_LONG writeBlock( const char *p, TQ_ULONG );
+ TQ_LONG writeBlock( const TQByteArray& data )
+ { return TQIODevice::writeBlock(data); }
+ TQ_LONG readLine( char *p, TQ_ULONG );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+
+protected:
+ TQByteArray a;
+
+private:
+ uint a_len;
+ uint a_inc;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQBuffer( const TQBuffer & );
+ TQBuffer &operator=( const TQBuffer & );
+#endif
+};
+
+
+inline TQByteArray TQBuffer::buffer() const
+{ return a; }
+
+inline TQIODevice::Offset TQBuffer::size() const
+{ return (Offset)a.size(); }
+
+inline TQIODevice::Offset TQBuffer::at() const
+{ return ioIndex; }
+
+#endif // USE_QT4
+
+#endif // TQBUFFER_H
diff --git a/tqtinterface/qt4/src/tools/tqcache.h b/tqtinterface/qt4/src/tools/tqcache.h
new file mode 100644
index 0000000..72881d4
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcache.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Definition of TQCache template class
+**
+** Created : 950209
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCACHE_H
+#define TQCACHE_H
+
+#ifndef TQT_H
+#include "tqgcache.h"
+#endif // TQT_H
+
+template<class type>
+class TQCache
+#ifdef TQ_TQDOC
+ : public TQPtrCollection
+#else
+ : public TQGCache
+#endif
+{
+public:
+ TQCache( const TQCache<type> &c ) : TQGCache(c) {}
+ TQCache( int maxCost=100, int size=17, bool caseSensitive=TRUE )
+ : TQGCache( maxCost, size, StringKey, caseSensitive, FALSE ) {}
+ ~TQCache() { clear(); }
+ TQCache<type> &operator=( const TQCache<type> &c )
+ { return (TQCache<type>&)TQGCache::operator=(c); }
+ int maxCost() const { return TQGCache::maxCost(); }
+ int totalCost() const { return TQGCache::totalCost(); }
+ void setMaxCost( int m ) { TQGCache::setMaxCost(m); }
+ uint count() const { return TQGCache::count(); }
+ uint size() const { return TQGCache::size(); }
+ bool isEmpty() const { return TQGCache::count() == 0; }
+ void clear() { TQGCache::clear(); }
+ bool insert( const TQString &k, const type *d, int c=1, int p=0 )
+ { return TQGCache::insert_string(k,(Item)d,c,p);}
+ bool remove( const TQString &k )
+ { return TQGCache::remove_string(k); }
+ type *take( const TQString &k )
+ { return (type *)TQGCache::take_string(k); }
+ type *tqfind( const TQString &k, bool ref=TRUE ) const
+ { return (type *)TQGCache::tqfind_string(k,ref);}
+ type *operator[]( const TQString &k ) const
+ { return (type *)TQGCache::tqfind_string(k);}
+ void statistics() const { TQGCache::statistics(); }
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQCache<void>::deleteItem( TQPtrCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void TQCache<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+template<class type>
+class TQCacheIterator : public TQGCacheIterator
+{
+public:
+ TQCacheIterator( const TQCache<type> &c ):TQGCacheIterator((TQGCache &)c) {}
+ TQCacheIterator( const TQCacheIterator<type> &ci)
+ : TQGCacheIterator( (TQGCacheIterator &)ci ) {}
+ TQCacheIterator<type> &operator=(const TQCacheIterator<type>&ci)
+ { return ( TQCacheIterator<type>&)TQGCacheIterator::operator=( ci ); }
+ uint count() const { return TQGCacheIterator::count(); }
+ bool isEmpty() const { return TQGCacheIterator::count() == 0; }
+ bool atFirst() const { return TQGCacheIterator::atFirst(); }
+ bool atLast() const { return TQGCacheIterator::atLast(); }
+ type *toFirst() { return (type *)TQGCacheIterator::toFirst(); }
+ type *toLast() { return (type *)TQGCacheIterator::toLast(); }
+ operator type *() const { return (type *)TQGCacheIterator::get(); }
+ type *current() const { return (type *)TQGCacheIterator::get(); }
+ TQString currentKey() const{ return TQGCacheIterator::getKeyString(); }
+ type *operator()() { return (type *)TQGCacheIterator::operator()();}
+ type *operator++() { return (type *)TQGCacheIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)TQGCacheIterator::operator+=(j);}
+ type *operator--() { return (type *)TQGCacheIterator::operator--(); }
+ type *operator-=(uint j) { return (type *)TQGCacheIterator::operator-=(j);}
+};
+
+#endif // TQCACHE_H
diff --git a/tqtinterface/qt4/src/tools/tqcleanuphandler.h b/tqtinterface/qt4/src/tools/tqcleanuphandler.h
new file mode 100644
index 0000000..a7e5ea1
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcleanuphandler.h
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCLEANUPHANDLER_H
+#define TQCLEANUPHANDLER_H
+
+#ifndef TQT_H
+#include "tqptrlist.h"
+#endif // TQT_H
+
+template<class Type>
+class TQCleanupHandler
+{
+public:
+ TQCleanupHandler() : cleanupObjects( 0 ) {}
+ ~TQCleanupHandler() { clear(); }
+
+ Type* add( Type **object ) {
+ if ( !cleanupObjects )
+ cleanupObjects = new TQPtrList<Type*>;
+ cleanupObjects->insert( 0, object );
+ return *object;
+ }
+
+ void remove( Type **object ) {
+ if ( !cleanupObjects )
+ return;
+ if ( cleanupObjects->tqfindRef( object ) >= 0 )
+ (void) cleanupObjects->take();
+ }
+
+ bool isEmpty() const {
+ return cleanupObjects ? cleanupObjects->isEmpty() : TRUE;
+ }
+
+ void clear() {
+ if ( !cleanupObjects )
+ return;
+ TQPtrListIterator<Type*> it( *cleanupObjects );
+ Type **object;
+ while ( ( object = it.current() ) ) {
+ delete *object;
+ *object = 0;
+ cleanupObjects->remove( object );
+ }
+ delete cleanupObjects;
+ cleanupObjects = 0;
+ }
+
+private:
+ TQPtrList<Type*> *cleanupObjects;
+};
+
+template<class Type>
+class TQSingleCleanupHandler
+{
+public:
+ TQSingleCleanupHandler() : object( 0 ) {}
+ ~TQSingleCleanupHandler() {
+ if ( object ) {
+ delete *object;
+ *object = 0;
+ }
+ }
+ Type* set( Type **o ) {
+ object = o;
+ return *object;
+ }
+ void reset() { object = 0; }
+private:
+ Type **object;
+};
+
+template<class Type>
+class TQSharedCleanupHandler
+{
+public:
+ TQSharedCleanupHandler() : object( 0 ) {}
+ ~TQSharedCleanupHandler() {
+ if ( object ) {
+ if ( (*object)->deref() )
+ delete *object;
+ *object = 0;
+ }
+ }
+ Type* set( Type **o ) {
+ object = o;
+ return *object;
+ }
+ void reset() { object = 0; }
+private:
+ Type **object;
+};
+
+#endif //TQCLEANUPHANDLER_H
diff --git a/tqtinterface/qt4/src/tools/tqcom_p.h b/tqtinterface/qt4/src/tools/tqcom_p.h
new file mode 100644
index 0000000..2d41781
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcom_p.h
@@ -0,0 +1,344 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCOM_P_H
+#define TQCOM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqstringlist.h"
+#include "tquuid.h"
+#endif // TQT_H
+
+#if __GNUC__ - 0 > 3
+#pragma GCC system_header
+#endif
+
+#ifndef TQT_NO_COMPONENT
+
+class TQObject;
+struct TQUInterfaceDescription;
+struct TQUObject;
+
+#define TQRESULT unsigned long
+#define TQS_OK (TQRESULT)0x00000000
+#define TQS_FALSE (TQRESULT)0x00000001
+
+#define TQE_NOTIMPL (TQRESULT)0x80000001
+#define TQE_OUTOFMEMORY (TQRESULT)0x80000002
+#define TQE_INVALIDARG (TQRESULT)0x80000003
+#define TQE_NOINTERFACE (TQRESULT)0x80000004
+#define TQE_NOCOMPONENT (TQRESULT)0x80000005
+
+
+// {1D8518CD-E8F5-4366-99E8-879FD7E482DE}
+#ifndef IID_TQUnknown
+#define IID_TQUnknown TQUuid(0x1d8518cd, 0xe8f5, 0x4366, 0x99, 0xe8, 0x87, 0x9f, 0xd7, 0xe4, 0x82, 0xde)
+#endif
+
+struct TQ_EXPORT TQUnknownInterface
+{
+ virtual TQRESULT queryInterface( const TQUuid&, TQUnknownInterface** ) = 0;
+ virtual ulong addRef() = 0;
+ virtual ulong release() = 0;
+};
+
+// {FBAC965E-A441-413F-935E-CDF582573FAB}
+#ifndef IID_TQDispatch
+#define IID_TQDispatch TQUuid( 0xfbac965e, 0xa441, 0x413f, 0x93, 0x5e, 0xcd, 0xf5, 0x82, 0x57, 0x3f, 0xab)
+#endif
+
+// the dispatch interface that inherits the unknown interface.. It is
+// used to explore interfaces during runtime and to do dynamic calls.
+struct TQ_EXPORT TQDispatchInterface : public TQUnknownInterface
+{
+ // returns the interface description of this dispatch interface.
+ virtual const TQUInterfaceDescription* interfaceDescription() const = 0;
+
+ // returns the event description of this dispatch interface.
+ virtual const TQUInterfaceDescription* eventsDescription() const = 0;
+
+ // invokes method id with parameters V*. Returns some sort of
+ // exception code.
+ virtual TQRESULT invoke( int id, TQUObject* o ) = 0;
+
+ // installs listener as event listener
+ virtual void installListener( TQDispatchInterface* listener ) = 0;
+
+ // remove listener as event listener
+ virtual void removeListener( TQDispatchInterface* listener ) = 0;
+};
+
+template <class T>
+class TQInterfacePtr
+{
+public:
+ TQInterfacePtr():iface(0){}
+
+ TQInterfacePtr( T* i) {
+ if ( (iface = i) )
+ iface->addRef();
+ }
+
+ TQInterfacePtr(const TQInterfacePtr<T> &p) {
+ if ( (iface = p.iface) )
+ iface->addRef();
+ }
+
+ ~TQInterfacePtr() {
+ if ( iface )
+ iface->release();
+ }
+
+ TQInterfacePtr<T> &operator=(const TQInterfacePtr<T> &p) {
+ if ( iface != p.iface ) {
+ if ( iface )
+ iface->release();
+ if ( (iface = p.iface) )
+ iface->addRef();
+ }
+ return *this;
+ }
+
+ TQInterfacePtr<T> &operator=(T* i) {
+ if (iface != i ) {
+ if ( iface )
+ iface->release();
+ if ( (iface = i) )
+ iface->addRef();
+ }
+ return *this;
+ }
+
+ bool operator==( const TQInterfacePtr<T> &p ) const { return iface == p.iface; }
+
+ bool operator!= ( const TQInterfacePtr<T>& p ) const { return !( *this == p ); }
+
+ bool isNull() const { return !iface; }
+
+ T* operator->() const { return iface; }
+
+ T& operator*() const { return *iface; }
+
+ operator T*() const { return iface; }
+
+ TQUnknownInterface** operator &() const {
+ if( iface )
+ iface->release();
+ return (TQUnknownInterface**)&iface;
+ }
+
+ T** operator &() {
+ if ( iface )
+ iface->release();
+ return &iface;
+ }
+
+private:
+ T* iface;
+};
+
+// {10A1501B-4C5F-4914-95DD-C400486CF900}
+#ifndef IID_TQObject
+#define IID_TQObject TQUuid( 0x10a1501b, 0x4c5f, 0x4914, 0x95, 0xdd, 0xc4, 0x00, 0x48, 0x6c, 0xf9, 0x00)
+#endif
+
+struct TQ_EXPORT TQObjectInterface
+{
+ virtual TQObject* qObject() = 0;
+};
+
+// {5F3968A5-F451-45b1-96FB-061AD98F926E}
+#ifndef IID_TQComponentInformation
+#define IID_TQComponentInformation TQUuid(0x5f3968a5, 0xf451, 0x45b1, 0x96, 0xfb, 0x6, 0x1a, 0xd9, 0x8f, 0x92, 0x6e)
+#endif
+
+struct TQ_EXPORT TQComponentInformationInterface : public TQUnknownInterface
+{
+ virtual TQString name() const = 0;
+ virtual TQString description() const = 0;
+ virtual TQString author() const = 0;
+ virtual TQString version() const = 0;
+};
+
+// {6CAA771B-17BB-4988-9E78-BA5CDDAAC31E}
+#ifndef IID_TQComponentFactory
+#define IID_TQComponentFactory TQUuid( 0x6caa771b, 0x17bb, 0x4988, 0x9e, 0x78, 0xba, 0x5c, 0xdd, 0xaa, 0xc3, 0x1e)
+#endif
+
+struct TQ_EXPORT TQComponentFactoryInterface : public TQUnknownInterface
+{
+ virtual TQRESULT createInstance( const TQUuid &cid, const TQUuid &iid, TQUnknownInterface** instance, TQUnknownInterface *outer ) = 0;
+};
+
+// {D16111D4-E1E7-4C47-8599-24483DAE2E07}
+#ifndef IID_TQLibrary
+#define IID_TQLibrary TQUuid( 0xd16111d4, 0xe1e7, 0x4c47, 0x85, 0x99, 0x24, 0x48, 0x3d, 0xae, 0x2e, 0x07)
+#endif
+
+struct TQ_EXPORT TQLibraryInterface : public TQUnknownInterface
+{
+ virtual bool init() = 0;
+ virtual void cleanup() = 0;
+ virtual bool canUnload() const = 0;
+};
+
+// {3F8FDC44-3015-4f3e-B6D6-E4AAAABDEAAD}
+#ifndef IID_TQFeatureList
+#define IID_TQFeatureList TQUuid(0x3f8fdc44, 0x3015, 0x4f3e, 0xb6, 0xd6, 0xe4, 0xaa, 0xaa, 0xbd, 0xea, 0xad)
+#endif
+
+struct TQ_EXPORT TQFeatureListInterface : public TQUnknownInterface
+{
+ virtual TQStringList featureList() const = 0;
+};
+
+// {B5FEB5DE-E0CD-4E37-B0EB-8A812499A0C1}
+#ifndef IID_TQComponentRegistration
+#define IID_TQComponentRegistration TQUuid( 0xb5feb5de, 0xe0cd, 0x4e37, 0xb0, 0xeb, 0x8a, 0x81, 0x24, 0x99, 0xa0, 0xc1)
+#endif
+
+struct TQ_EXPORT TQComponentRegistrationInterface : public TQUnknownInterface
+{
+ virtual bool registerComponents( const TQString &filepath ) const = 0;
+ virtual bool unregisterComponents() const = 0;
+};
+
+// internal class that wraps an initialized ulong
+struct TQ_EXPORT TQtULong
+{
+ TQtULong() : ref( 0 ) { }
+ operator unsigned long () const { return ref; }
+ unsigned long& operator++() { return ++ref; }
+ unsigned long operator++( int ) { return ref++; }
+ unsigned long& operator--() { return --ref; }
+ unsigned long operator--( int ) { return ref--; }
+
+ unsigned long ref;
+};
+// default implementation of ref counting. A variable "ulong ref" has to be a member
+
+
+#define TQ_REFCOUNT \
+private: \
+ TQtULong qtrefcount; \
+public: \
+ ulong addRef() {return qtrefcount++;} \
+ ulong release() {if(!--qtrefcount){delete this;return 0;}return qtrefcount;}
+
+#ifndef TQ_EXPORT_COMPONENT
+#if defined(TQT_THREAD_SUPPORT)
+#define TQT_THREADED_BUILD 1
+#define TQ_UCM_FLAGS_STRING "11"
+#else
+#define TQT_THREADED_BUILD 0
+#define TQ_UCM_FLAGS_STRING "01"
+#endif
+
+#ifndef TQ_EXTERN_C
+#ifdef __cplusplus
+#define TQ_EXTERN_C extern "C"
+#else
+#define TQ_EXTERN_C extern
+#endif
+#endif
+
+// this is duplicated at TQ_PLUGIN_VERIFICATION_DATA in tqgplugin.h
+// NOTE: if you change pattern, you MUST change the pattern in
+// qcomlibrary.cpp as well. changing the pattern will break all
+// backwards compatibility as well (no old plugins will be loaded).
+#ifndef TQ_UCM_VERIFICATION_DATA
+# define TQ_UCM_VERIFICATION_DATA \
+ static const char *qt_ucm_verification_data = \
+ "pattern=""TQT_UCM_VERIFICATION_DATA""\n" \
+ "version="TQT_VERSION_STR"\n" \
+ "flags="TQ_UCM_FLAGS_STRING"\n" \
+ "buildkey="TQT_BUILD_KEY"\0";
+#endif // TQ_UCM_VERIFICATION_DATA
+
+// This macro expands to the default implementation of ucm_instantiate.
+#ifndef TQ_CREATE_INSTANCE
+# define TQ_CREATE_INSTANCE( IMPLEMENTATION ) \
+ IMPLEMENTATION *i = new IMPLEMENTATION; \
+ TQUnknownInterface* iface = 0; \
+ i->queryInterface( IID_TQUnknown, &iface ); \
+ return iface;
+#endif // TQ_CREATE_INSTANCE
+
+# ifdef TQ_WS_WIN
+# ifdef TQ_CC_BOR
+# define TQ_EXPORT_COMPONENT() \
+ TQ_UCM_VERIFICATION_DATA \
+ TQ_EXTERN_C __declspec(dllexport) \
+ const char * __stdcall qt_ucm_query_verification_data() \
+ { return qt_ucm_verification_data; } \
+ TQ_EXTERN_C __declspec(dllexport) TQUnknownInterface* \
+ __stdcall ucm_instantiate()
+# else
+# define TQ_EXPORT_COMPONENT() \
+ TQ_UCM_VERIFICATION_DATA \
+ TQ_EXTERN_C __declspec(dllexport) \
+ const char *qt_ucm_query_verification_data() \
+ { return qt_ucm_verification_data; } \
+ TQ_EXTERN_C __declspec(dllexport) TQUnknownInterface* ucm_instantiate()
+# endif
+# else
+# define TQ_EXPORT_COMPONENT() \
+ TQ_UCM_VERIFICATION_DATA \
+ TQ_EXTERN_C \
+ const char *qt_ucm_query_verification_data() \
+ { return qt_ucm_verification_data; } \
+ TQ_EXTERN_C TQUnknownInterface* ucm_instantiate()
+# endif
+# define TQ_EXPORT_INTERFACE() TQ_EXPORT_COMPONENT()
+#endif
+
+#endif //TQT_NO_COMPONENT
+
+#endif //TQCOM_P_H
diff --git a/tqtinterface/qt4/src/tools/tqcomlibrary.cpp b/tqtinterface/qt4/src/tools/tqcomlibrary.cpp
new file mode 100644
index 0000000..253f9bf
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcomlibrary.cpp
@@ -0,0 +1,538 @@
+/****************************************************************************
+**
+** Implementation of TQComLibrary class
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcomlibrary_p.h"
+
+#ifndef TQT_NO_COMPONENT
+#include <tqapplication.h>
+#include <tqsettings.h>
+#include <tqfileinfo.h>
+#include <tqdatetime.h>
+#include <tqcleanuphandler.h>
+#ifndef NO_ERRNO_H
+#include <errno.h>
+#endif // NO_ERROR_H
+
+#ifdef TQT_THREAD_SUPPORT
+# include "tqmutexpool_p.h"
+#endif // TQT_THREAD_SUPPORT
+
+#ifndef TQT_DEBUG_COMPONENT
+# if defined(TQT_DEBUG)
+# define TQT_DEBUG_COMPONENT 1
+# endif
+#endif
+
+
+TQComLibrary::TQComLibrary( const TQString &filename )
+ : TQLibrary( filename ), entry( 0 ), libiface( 0 ), qt_version( 0 )
+{
+}
+
+TQComLibrary::~TQComLibrary()
+{
+ if ( autoUnload() )
+ unload();
+ if ( libiface )
+ libiface->release();
+ if ( entry )
+ entry->release();
+}
+
+bool TQComLibrary::unload()
+{
+ int refs = entry ? entry->release() : 0;
+ entry = 0;
+ if (refs || !libiface)
+ return FALSE;
+
+ libiface->cleanup();
+ if ( !libiface->canUnload() )
+ return FALSE;
+ libiface->release();
+ libiface = 0;
+
+ return TQLibrary::unload();
+}
+
+static bool qt_verify( const TQString& library, uint version, uint flags,
+ const TQCString &key, bool warn )
+{
+ uint our_flags = 1;
+#if defined(TQT_THREAD_SUPPORT)
+ our_flags |= 2;
+#endif
+
+ if ( (flags & 1) == 0 ) {
+ if ( warn )
+ qWarning( "Conflict in %s:\n"
+ " Plugin cannot be queried successfully! [2]",
+ (const char*) TQFile::encodeName(library) );
+ } else if ( ( version > TQT_VERSION ) ||
+ ( ( TQT_VERSION & 0xff0000 ) > ( version & 0xff0000 ) ) ) {
+ if ( warn )
+ qWarning( "Conflict in %s:\n"
+ " Plugin uses incompatible TQt library (%d.%d.%d)!",
+ (const char*) TQFile::encodeName(library),
+ (version&0xff0000) >> 16, (version&0xff00) >> 8, version&0xff );
+ } else if ( (flags & 2) != (our_flags & 2) ) {
+ if ( warn )
+ qWarning( "Conflict in %s:\n"
+ " Plugin uses %s TQt library!",
+ (const char*) TQFile::encodeName(library),
+ (flags & 2) ? "multi threaded" : "single threaded" );
+ } else if ( key != TQT_BUILD_KEY ) {
+ if ( warn )
+ qWarning( "Conflict in %s:\n"
+ " Plugin uses incompatible TQt library!\n"
+ " expected build key \"%s\", got \"%s\".",
+ (const char*) TQFile::encodeName(library),
+ TQT_BUILD_KEY,
+ key.isEmpty() ? "<null>" : (const char *) key );
+ } else {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+struct qt_token_info
+{
+ qt_token_info( const char *f, const ulong fc )
+ : fields( f ), field_count( fc ), results( fc ), lengths( fc )
+ {
+ results.fill( 0 );
+ lengths.fill( 0 );
+ }
+
+ const char *fields;
+ const ulong field_count;
+
+ TQMemArray<const char *> results;
+ TQMemArray<ulong> lengths;
+};
+
+/*
+ return values:
+ 1 parse ok
+ 0 eos
+ -1 parse error
+*/
+static int qt_tokenize( const char *s, ulong s_len, ulong *advance,
+ const qt_token_info &token_info )
+{
+ ulong pos = 0, field = 0, fieldlen = 0;
+ char current;
+ int ret = -1;
+ *advance = 0;
+ for (;;) {
+ current = s[ pos ];
+
+ // next char
+ ++pos;
+ ++fieldlen;
+ ++*advance;
+
+ if ( ! current || pos == s_len + 1 ) {
+ // save result
+ token_info.results[ (int)field ] = s;
+ token_info.lengths[ (int)field ] = fieldlen - 1;
+
+ // end of string
+ ret = 0;
+ break;
+ }
+
+ if ( current == token_info.fields[ field ] ) {
+ // save result
+ token_info.results[ (int)field ] = s;
+ token_info.lengths[ (int)field ] = fieldlen - 1;
+
+ // end of field
+ fieldlen = 0;
+ ++field;
+ if ( field == token_info.field_count - 1 ) {
+ // parse ok
+ ret = 1;
+ }
+ if ( field == token_info.field_count ) {
+ // done parsing
+ break;
+ }
+
+ // reset string and its length
+ s = s + pos;
+ s_len -= pos;
+ pos = 0;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ returns TRUE if the string s was correctly parsed, FALSE otherwise.
+*/
+static bool tqt_parse_pattern( const char *s, uint *version, uint *flags,
+ TQCString *key )
+{
+ bool ret = TRUE;
+
+ qt_token_info pinfo("=\n", 2);
+ int parse;
+ ulong at = 0, advance, parselen = tqstrlen( s );
+ do {
+ parse = qt_tokenize( s + at, parselen, &advance, pinfo );
+ if ( parse == -1 ) {
+ ret = FALSE;
+ break;
+ }
+
+ at += advance;
+ parselen -= advance;
+
+ if ( tqstrncmp( "version", pinfo.results[ 0 ], pinfo.lengths[ 0 ] ) == 0 ) {
+ // parse version string
+ qt_token_info pinfo2("..-", 3);
+ if ( qt_tokenize( pinfo.results[ 1 ], pinfo.lengths[ 1 ],
+ &advance, pinfo2 ) != -1 ) {
+ TQCString m( pinfo2.results[ 0 ], pinfo2.lengths[ 0 ] + 1 );
+ TQCString n( pinfo2.results[ 1 ], pinfo2.lengths[ 1 ] + 1 );
+ TQCString p( pinfo2.results[ 2 ], pinfo2.lengths[ 2 ] + 1 );
+ *version = (m.toUInt() << 16) | (n.toUInt() << 8) | p.toUInt();
+ } else {
+ ret = FALSE;
+ break;
+ }
+ } else if ( tqstrncmp( "flags", pinfo.results[ 0 ], pinfo.lengths[ 0 ] ) == 0 ) {
+ // parse flags string
+ char ch;
+ *flags = 0;
+ ulong p = 0, c = 0, bit = 0;
+ while ( p < pinfo.lengths[ 1 ] ) {
+ ch = pinfo.results[ 1 ][ p ];
+ bit = pinfo.lengths[ 1 ] - p - 1;
+ c = 1 << bit;
+ if ( ch == '1' ) {
+ *flags |= c;
+ } else if ( ch != '0' ) {
+ ret = FALSE;
+ break;
+ }
+ ++p;
+ }
+ } else if ( tqstrncmp( "buildkey", pinfo.results[ 0 ],
+ pinfo.lengths[ 0 ] ) == 0 ){
+ // save buildkey
+ *key = TQCString( pinfo.results[ 1 ], pinfo.lengths[ 1 ] + 1 );
+ }
+ } while ( parse == 1 && parselen > 0 );
+
+ return ret;
+}
+
+#if defined(TQ_OS_UNIX)
+
+#if defined(TQ_OS_FREEBSD) || defined(TQ_OS_LINUX)
+# define USE_MMAP
+# include <sys/types.h>
+# include <sys/mman.h>
+#endif // TQ_OS_FREEBSD || TQ_OS_LINUX
+
+static long qt_tqfind_pattern( const char *s, ulong s_len,
+ const char *pattern, ulong p_len )
+{
+ /*
+ this uses the same algorithm as TQString::tqfindRev...
+
+ we search from the end of the file because on the supported
+ systems, the read-only data/text segments are placed at the end
+ of the file. HOWEVER, when building with debugging enabled, all
+ the debug symbols are placed AFTER the data/text segments.
+
+ what does this mean? when building in release mode, the search
+ is fast because the data we are looking for is at the end of the
+ file... when building in debug mode, the search is slower
+ because we have to skip over all the debugging symbols first
+ */
+
+ if ( ! s || ! pattern || p_len > s_len ) return -1;
+ ulong i, hs = 0, hp = 0, delta = s_len - p_len;
+
+ for (i = 0; i < p_len; ++i ) {
+ hs += s[delta + i];
+ hp += pattern[i];
+ }
+ i = delta;
+ for (;;) {
+ if ( hs == hp && tqstrncmp( s + i, pattern, p_len ) == 0 )
+ return i;
+ if ( i == 0 )
+ break;
+ --i;
+ hs -= s[i + p_len];
+ hs += s[i];
+ }
+
+ return -1;
+}
+
+/*
+ This opens the specified library, mmaps it into memory, and searches
+ for the TQT_UCM_VERIFICATION_DATA. The advantage of this approach is that
+ we can get the verification data without have to actually load the library.
+ This lets us detect mismatches more safely.
+
+ Returns FALSE if version/flags/key information is not present, or if the
+ information could not be read.
+ Returns TRUE if version/flags/key information is present and succesfully read.
+*/
+static bool tqt_unix_query( const TQString &library, uint *version, uint *flags,
+ TQCString *key )
+{
+ TQFile file( library );
+ if (! file.open( IO_ReadOnly ) ) {
+ qWarning( "%s: %s", (const char*) TQFile::encodeName(library),
+ strerror( errno ) );
+ return FALSE;
+ }
+
+ TQByteArray data;
+ char *filedata = 0;
+ ulong fdlen = 0;
+
+#ifdef USE_MMAP
+ char *mapaddr = 0;
+ size_t maplen = file.size();
+ mapaddr = (char *) mmap( mapaddr, maplen, PROT_READ, MAP_PRIVATE, file.handle(), 0 );
+ if ( mapaddr != MAP_FAILED ) {
+ // mmap succeeded
+ filedata = mapaddr;
+ fdlen = maplen;
+ } else {
+ // mmap failed
+ qWarning( "mmap: %s", strerror( errno ) );
+#endif // USE_MMAP
+ // try reading the data into memory instead
+ data = file.readAll();
+ filedata = data.data();
+ fdlen = data.size();
+#ifdef USE_MMAP
+ }
+#endif // USE_MMAP
+
+ // verify that the pattern is present in the plugin
+ const char *pattern = "pattern=TQT_UCM_VERIFICATION_DATA";
+ const ulong plen = tqstrlen( pattern );
+ long pos = qt_tqfind_pattern( filedata, fdlen, pattern, plen );
+
+ bool ret = FALSE;
+ if ( pos >= 0 ) {
+ ret = tqt_parse_pattern( filedata + pos, version, flags, key );
+ }
+
+#ifdef USE_MMAP
+ if ( mapaddr != MAP_FAILED && munmap(mapaddr, maplen) != 0 ) {
+ qWarning( "munmap: %s", strerror( errno ) );
+ }
+#endif // USE_MMAP
+
+ file.close();
+ return ret;
+}
+
+#endif // TQ_OS_UNIX
+
+
+static TQSettings *cache = 0;
+static TQSingleCleanupHandler<TQSettings> cleanup_cache;
+
+void TQComLibrary::createInstanceInternal()
+{
+ if ( library().isEmpty() )
+ return;
+
+ TQFileInfo fileinfo( library() );
+ TQString lastModified = fileinfo.lastModified().toString(Qt::ISODate);
+ TQString regkey = TQString("/TQt Plugins %1.%2/%3")
+ .arg( ( TQT_VERSION & 0xff0000 ) >> 16 )
+ .arg( ( TQT_VERSION & 0xff00 ) >> 8 )
+ .arg( library() );
+ TQStringList reg;
+ uint flags = 0;
+ TQCString key;
+ bool query_done = FALSE;
+ bool warn_mismatch = TRUE;
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &cache ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+
+ if ( ! cache ) {
+ cache = new TQSettings;
+ cache->insertSearchPath( TQSettings::Windows, "/Trolltech" );
+ cleanup_cache.set( &cache );
+ }
+
+ reg = cache->readListEntry( regkey );
+ if ( reg.count() == 4 ) {
+ // check timestamp
+ if ( lastModified == reg[3] ) {
+ qt_version = reg[0].toUInt(0, 16);
+ flags = reg[1].toUInt(0, 16);
+ key = reg[2].latin1();
+
+ query_done = TRUE;
+ warn_mismatch = FALSE;
+ }
+ }
+
+#if defined(TQ_OS_UNIX)
+ if ( ! query_done ) {
+ // get the query information directly from the plugin without loading
+ if ( tqt_unix_query( library(), &qt_version, &flags, &key ) ) {
+ // info read succesfully from library
+ query_done = TRUE;
+ }
+ }
+#else // !TQ_OS_UNIX
+ if ( ! query_done ) {
+ // get the query information by loading the plugin
+ if ( !isLoaded() ) {
+ TQ_ASSERT( entry == 0 );
+ if ( !load() )
+ return;
+ }
+
+# ifdef TQ_CC_BOR
+ typedef const char * __stdcall (*UCMQueryVerificationDataProc)();
+# else
+ typedef const char * (*UCMQueryVerificationDataProc)();
+# endif
+ UCMQueryVerificationDataProc ucmQueryVerificationdataProc;
+ ucmQueryVerificationdataProc =
+ (UCMQueryVerificationDataProc) resolve( "qt_ucm_query_verification_data" );
+
+ if ( !ucmQueryVerificationdataProc ||
+ !tqt_parse_pattern( ucmQueryVerificationdataProc(),
+ &qt_version, &flags, &key ) ) {
+ qt_version = flags = 0;
+ key = "unknown";
+ } else {
+ query_done = TRUE;
+ }
+ }
+#endif // TQ_OS_UNIX
+
+ TQStringList queried;
+ queried << TQString::number( qt_version,16 )
+ << TQString::number( flags, 16 )
+ << key
+ << lastModified;
+
+ if ( queried != reg ) {
+ cache->writeEntry( regkey, queried );
+ // delete the cache, which forces the settings to be written
+ delete cache;
+ cache = 0;
+ }
+
+ if ( ! query_done ) {
+ if ( warn_mismatch ) {
+ qWarning( "Conflict in %s:\n Plugin cannot be queried successfully! [1]",
+ (const char*) TQFile::encodeName( library() ) );
+ }
+ unload();
+ return;
+ }
+
+ if ( ! qt_verify( library(), qt_version, flags, key, warn_mismatch ) ) {
+ unload();
+ return;
+ } else if ( !isLoaded() ) {
+ TQ_ASSERT( entry == 0 );
+ if ( !load() )
+ return;
+ }
+
+#ifdef TQ_CC_BOR
+ typedef TQUnknownInterface* __stdcall (*UCMInstanceProc)();
+#else
+ typedef TQUnknownInterface* (*UCMInstanceProc)();
+#endif
+ UCMInstanceProc ucmInstanceProc;
+ ucmInstanceProc = (UCMInstanceProc) resolve( "ucm_instantiate" );
+#if defined(TQT_DEBUG_COMPONENT)
+ if ( !ucmInstanceProc )
+ qWarning( "%s: Not a UCOM library.", (const char*) TQFile::encodeName(library()) );
+#endif
+ entry = ucmInstanceProc ? ucmInstanceProc() : 0;
+
+ if ( entry ) {
+ if ( entry->queryInterface( IID_TQLibrary, (TQUnknownInterface**)&libiface ) == TQS_OK ) {
+ if ( libiface && !libiface->init() ) {
+ libiface->release();
+ libiface = 0;
+ unload();
+ return;
+ }
+ }
+ } else {
+#if defined(TQT_DEBUG_COMPONENT)
+ qWarning( "%s: No exported component provided.", (const char*) TQFile::encodeName(library()) );
+#endif
+ unload();
+ }
+}
+
+TQRESULT TQComLibrary::queryInterface( const TQUuid& request, TQUnknownInterface** iface )
+{
+ if ( !entry )
+ createInstanceInternal();
+ return entry ? entry->queryInterface( request, iface ) : TQE_NOCOMPONENT;
+}
+
+uint TQComLibrary::qtVersion()
+{
+ if ( !entry )
+ createInstanceInternal();
+ return entry ? qt_version : 0;
+}
+
+
+#endif // TQT_NO_COMPONENT
diff --git a/tqtinterface/qt4/src/tools/tqcomlibrary_p.h b/tqtinterface/qt4/src/tools/tqcomlibrary_p.h
new file mode 100644
index 0000000..470ff4c
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcomlibrary_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Definition of TQComLibrary class
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCOMLIBRARY_P_H
+#define TQCOMLIBRARY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqcom_p.h"
+#include "tqlibrary.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_COMPONENT
+
+class TQ_EXPORT TQComLibrary : public TQLibrary
+{
+public:
+ TQComLibrary( const TQString &filename );
+ ~TQComLibrary();
+
+ bool unload();
+ TQRESULT queryInterface( const TQUuid &iid, TQUnknownInterface **iface );
+ uint qtVersion();
+
+private:
+ void createInstanceInternal();
+
+ TQUnknownInterface *entry;
+ TQLibraryInterface *libiface;
+ uint qt_version;
+
+};
+
+#endif //TQT_NO_COMPONENT
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqcomponentfactory.cpp b/tqtinterface/qt4/src/tools/tqcomponentfactory.cpp
new file mode 100644
index 0000000..800e2b6
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcomponentfactory.cpp
@@ -0,0 +1,355 @@
+/****************************************************************************
+**
+** Implementation of the TQComponentFactory class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcomponentfactory_p.h"
+
+#ifndef TQT_NO_COMPONENT
+#include "tqsettings.h"
+#include <private/tqcomlibrary_p.h>
+#include "tqdir.h"
+#include "tqapplication.h"
+
+/*!
+ \class TQComponentFactory qcomponentfactory.h
+ \brief The TQComponentFactory class provides static functions to create and register components.
+
+ \internal
+
+ The static convenience functions can be used both by applications to instantiate components,
+ and by component servers to register components.
+
+ The createInstance() function provides a pointer to an interface implemented in a specific
+ component if the component requested has been installed properly and implements the interface.
+
+ Use registerServer() to load a component server and register its components, and unregisterServer()
+ to unregister the components. The component exported by the component server has to implement the
+ TQComponentRegistrationInterface.
+
+ The static functions registerComponent() and unregisterComponent() register and unregister a single
+ component in the system component registry, and should be used when implementing the
+ \link TQComponentRegistrationInterface::registerComponents() registerCompontents() \endlink and
+ \link TQComponentRegistrationInterface::unregisterComponents() unregisterCompontents() \endlink functions
+ in the TQComponentRegistrationInterface.
+
+ A component is registered using a UUID, but can additionally be registered with a name, version and
+ description. A component registered with a name and a version can be instantiated by client applications
+ using the name and specific version number, or the highest available version number for that component by
+ just using the name. A component that is registered calling
+
+ \code
+ TQComponentFactory::registerComponent( TQUuid(...), filename, "MyProgram.Component", 1 );
+ \endcode
+
+ can be instantiated calling either:
+
+ \code
+ TQComponentFactory::createInstance( TQUuid(...), IID_XYZ, (TQUnknownInterface**)&iface );
+ \endcode
+ or
+ \code
+ TQComponentFactory::createInstance( "MyProgram.Component", IID_XYZ, (TQUnknownInterface**)&iface );
+ \endcode
+ or
+ \code
+ TQComponentFactory::createInstance( "MyProgram.Component.1", IID_XYZ, (TQUnknownInterface**)&iface );
+ \endcode
+
+ The first and the last way will always instantiate exactly the component registered above, while
+ the second call might also return a later version of the same component. This allows smoother upgrading
+ of components, and is easier to use in application source code, but should only be used when new versions
+ of the component are guaranteed to work with the application.
+
+ The component name can be anything, but should be unique on the system the component is being
+ installed on. A common naming convention for components is \e application.component.
+
+ \sa TQComponentRegistrationInterface TQComponentFactoryInterface
+*/
+
+
+static TQPtrList<TQComLibrary> *libraries = 0;
+
+static void cleanup()
+{
+ delete libraries;
+ libraries = 0;
+}
+
+static TQPtrList<TQComLibrary> *liblist()
+{
+ if ( !libraries ) {
+ libraries = new TQPtrList<TQComLibrary>();
+ libraries->setAutoDelete( TRUE );
+ qAddPostRoutine( cleanup );
+ }
+ return libraries;
+}
+
+/*!
+ Searches for the component identifier \a cid in the system component registry,
+ loads the corresponding component server and queries for the interface \a iid.
+ \a iface is set to the resulting interface pointer. \a cid can either be the
+ UUID or the name of the component.
+
+ The parameter \a outer is a pointer to the outer interface used
+ for containment and aggregation and is propagated to the \link
+ TQComponentFactoryInterface::createInstance() createInstance() \endlink
+ implementation of the TQComponentFactoryInterface in the component server if
+ provided.
+
+ The function returns TQS_OK if the interface was successfully instantiated, TQE_NOINTERFACE if
+ the component does not provide an interface \a iid, or TQE_NOCOMPONENT if there was
+ an error loading the component.
+
+ Example:
+ \code
+ TQInterfacePtr<MyInterface> iface;
+ if ( TQComponentFactory::createInstance( IID_MyInterface, CID_MyComponent, (TQUnknownInterface**)&iface ) == TQS_OK )
+ iface->doSomething();
+ ...
+ }
+ \endcode
+*/
+TQRESULT TQComponentFactory::createInstance( const TQString &cid, const TQUuid &iid, TQUnknownInterface** iface, TQUnknownInterface *outer )
+{
+ TQSettings settings;
+ settings.insertSearchPath( TQSettings::Windows, "/Classes" );
+ bool ok = FALSE;
+ TQString cidStr = cid;
+ TQRESULT res = TQE_NOCOMPONENT;
+
+ TQUuid uuid( cidStr ); // try to parse, and resolve CLSID if necessary
+ if ( uuid.isNull() ) {
+ uuid = settings.readEntry( "/" + cid + "/CLSID/Default", TQString::null, &ok );
+ cidStr = uuid.toString().upper();
+ }
+
+ if ( cidStr.isEmpty() )
+ return res;
+
+ TQString file = settings.readEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", TQString::null, &ok );
+ if ( !ok )
+ return res;
+
+ TQComLibrary *library = new TQComLibrary( file );
+ library->setAutoUnload( FALSE );
+
+ TQComponentFactoryInterface *cfIface =0;
+ library->queryInterface( IID_TQComponentFactory, (TQUnknownInterface**)&cfIface );
+
+ if ( cfIface ) {
+ res = cfIface->createInstance( uuid, iid, iface, outer );
+ cfIface->release();
+ } else {
+ res = library->queryInterface( iid, iface );
+ }
+ TQLibraryInterface *libiface = 0;
+ if ( library->queryInterface( IID_TQLibrary, (TQUnknownInterface**)&libiface ) != TQS_OK || !tqApp ) {
+ delete library; // only deletes the object, thanks to TQLibrary::Manual
+ } else {
+ libiface->release();
+ library->setAutoUnload( TRUE );
+ liblist()->prepend( library );
+ }
+ return res;
+}
+
+/*!
+ Loads the shared library \a filename and queries for a
+ TQComponentRegistrationInterface. If the library implements this interface,
+ the \link TQComponentRegistrationInterface::registerComponents()
+ registerComponents() \endlink function is called.
+
+ Returns TRUE if the interface is found and successfully called,
+ otherwise returns FALSE.
+*/
+TQRESULT TQComponentFactory::registerServer( const TQString &filename )
+{
+ TQComLibrary lib( filename );
+ lib.load();
+ TQComponentRegistrationInterface *iface = 0;
+ TQRESULT res = lib.queryInterface( IID_TQComponentRegistration, (TQUnknownInterface**)&iface );
+ if ( res != TQS_OK )
+ return res;
+ TQDir dir( filename );
+ bool ok = iface->registerComponents( dir.absPath() );
+ iface->release();
+ return ok ? TQS_OK : TQS_FALSE;
+}
+
+/*!
+ Loads the shared library \a filename and queries for a
+ TQComponentRegistrationInterface. If the library implements this interface,
+ the \link TQComponentRegistrationInterface::unregisterComponents()
+ unregisterComponents() \endlink function is called.
+
+ Returns TRUE if the interface is found and successfully unregistered,
+ otherwise returns FALSE.
+*/
+TQRESULT TQComponentFactory::unregisterServer( const TQString &filename )
+{
+ TQComLibrary lib( filename );
+ lib.load();
+ TQComponentRegistrationInterface *iface = 0;
+ TQRESULT res = lib.queryInterface( IID_TQComponentRegistration, (TQUnknownInterface**)&iface );
+ if ( res != TQS_OK )
+ return res;
+ bool ok = iface->unregisterComponents();
+ iface->release();
+ return ok ? TQS_OK : TQS_FALSE;
+}
+
+/*!
+ Registers the component with id \a cid in the system component registry and
+ returns TRUE if the component was registerd successfully, otherwise returns
+ FALSE. The component is provided by the component server at \a filepath and
+ registered with an optional \a name, \a version and \a description.
+
+ This function does nothing and returns FALSE if a component with an identical
+ \a cid does already exist on the system.
+
+ A component that has been registered with a \a name can be created using both the
+ \a cid and the \a name value using createInstance().
+
+ Call this function for each component in an implementation of
+ \link TQComponentRegistrationInterface::registerComponents() registerComponents() \endlink.
+
+ \sa unregisterComponent(), registerServer(), createInstance()
+*/
+bool TQComponentFactory::registerComponent( const TQUuid &cid, const TQString &filepath, const TQString &name, int version, const TQString &description )
+{
+ bool ok = FALSE;
+ TQSettings settings;
+ settings.insertSearchPath( TQSettings::Windows, "/Classes" );
+
+ TQString cidStr = cid.toString().upper();
+ settings.readEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", TQString::null, &ok );
+ if ( ok ) // don't overwrite existing component
+ return FALSE;
+
+ ok = settings.writeEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", filepath );
+ if ( ok && !!description )
+ settings.writeEntry( "/CLSID/" + cidStr + "/Default", description );
+
+ // register the human readable part
+ if ( ok && !!name ) {
+ TQString vName = version ? name + "." + TQString::number( version ) : name;
+ settings.writeEntry( "/CLSID/" + cidStr + "/ProgID/Default", vName );
+ ok = settings.writeEntry( "/" + vName + "/CLSID/Default", cidStr );
+ if ( ok && !!description )
+ settings.writeEntry( "/" + vName + "/Default", description );
+
+ if ( ok && version ) {
+ settings.writeEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default", name );
+ TQString curVer = settings.readEntry( "/" + name + "/CurVer/Default" );
+ if ( !curVer || curVer < vName ) { // no previous, or a lesser version installed
+ settings.writeEntry( "/" + name + "/CurVer/Default", vName );
+ ok = settings.writeEntry( "/" + name + "/CLSID/Default", cidStr );
+ if ( ok && !!description )
+ settings.writeEntry( "/" + name + "/Default", description );
+ }
+ }
+ }
+
+ return ok;
+}
+
+/*!
+ Unregisters the component with id \a cid from the system component registry and returns
+ TRUE if the component was unregistered successfully, otherwise returns FALSE.
+
+ Call this function for each component in an implementation of
+ \link TQComponentRegistrationInterface::unregisterComponents() unregisterComponents() \endlink.
+
+ \sa registerComponent(), unregisterServer()
+*/
+bool TQComponentFactory::unregisterComponent( const TQUuid &cid )
+{
+ TQSettings settings;
+ bool ok = FALSE;
+ settings.insertSearchPath( TQSettings::Windows, "/Classes" );
+
+ TQString cidStr = cid.toString().upper();
+ if ( cidStr.isEmpty() )
+ return FALSE;
+
+ // unregister the human readable part
+ TQString vName = settings.readEntry( "/CLSID/" + cidStr + "/ProgID/Default", TQString::null, &ok );
+ if ( ok ) {
+ TQString name = settings.readEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default", TQString::null );
+ if ( !!name && settings.readEntry( "/" + name + "/CurVer/Default" ) == vName ) {
+ // unregistering the current version -> change CurVer to previous version
+ TQString version = vName.right( vName.length() - name.length() - 1 );
+ TQString newVerName;
+ TQString newCidStr;
+ if ( version.tqfind( '.' ) == -1 ) {
+ int ver = version.toInt();
+ // see if a lesser version is installed, and make that the CurVer
+ while ( ver-- ) {
+ newVerName = name + "." + TQString::number( ver );
+ newCidStr = settings.readEntry( "/" + newVerName + "/CLSID/Default" );
+ if ( !!newCidStr )
+ break;
+ }
+ } else {
+ // oh well...
+ }
+ if ( !!newCidStr ) {
+ settings.writeEntry( "/" + name + "/CurVer/Default", newVerName );
+ settings.writeEntry( "/" + name + "/CLSID/Default", newCidStr );
+ } else {
+ settings.removeEntry( "/" + name + "/CurVer/Default" );
+ settings.removeEntry( "/" + name + "/CLSID/Default" );
+ settings.removeEntry( "/" + name + "/Default" );
+ }
+ }
+
+ settings.removeEntry( "/" + vName + "/CLSID/Default" );
+ settings.removeEntry( "/" + vName + "/Default" );
+ }
+
+ settings.removeEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default" );
+ settings.removeEntry( "/CLSID/" + cidStr + "/ProgID/Default" );
+ settings.removeEntry( "/CLSID/" + cidStr + "/InprocServer32/Default" );
+ ok = settings.removeEntry( "/CLSID/" + cidStr + "/Default" );
+
+ return ok;
+}
+
+#endif // TQT_NO_COMPONENT
diff --git a/tqtinterface/qt4/src/tools/tqcomponentfactory_p.h b/tqtinterface/qt4/src/tools/tqcomponentfactory_p.h
new file mode 100644
index 0000000..acec9d4
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcomponentfactory_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Definition of the TQComponentFactory class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCOMPONENTFACTORY_P_H
+#define TQCOMPONENTFACTORY_P_H
+
+#ifndef TQT_H
+#include "tqcom_p.h"
+#endif // TQT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_NO_COMPONENT
+
+class TQ_EXPORT TQComponentFactory
+{
+public:
+ static TQRESULT createInstance( const TQString &cid, const TQUuid &iid, TQUnknownInterface** instance, TQUnknownInterface *outer = 0 );
+ static TQRESULT registerServer( const TQString &filename );
+ static TQRESULT unregisterServer( const TQString &filename );
+
+ static bool registerComponent( const TQUuid &cid, const TQString &filename, const TQString &name = TQString::null,
+ int version = 0, const TQString &description = TQString::null );
+ static bool unregisterComponent( const TQUuid &cid );
+};
+
+#endif // TQT_NO_COMPONENT
+
+#endif // TQCOMPONENTFACTORY_P_H
diff --git a/tqtinterface/qt4/src/tools/tqconfig-dist.h b/tqtinterface/qt4/src/tools/tqconfig-dist.h
new file mode 100644
index 0000000..1e4c589
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqconfig-dist.h
@@ -0,0 +1,11 @@
+#ifndef TQT_H
+#endif /* TQT_H */
+
+/*
+ Empty leaves all features enabled. See doc/html/features.html for choices.
+
+ Note that disabling some features will produce a libtqt that is not
+ compatible with other libtqt builds. Such modifications are only
+ supported on TQt/Embedded where reducing the library size is important
+ and where the application-suite is often a fixed set.
+*/
diff --git a/tqtinterface/qt4/src/tools/tqconfig-large.h b/tqtinterface/qt4/src/tools/tqconfig-large.h
new file mode 100644
index 0000000..2b44bf7
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqconfig-large.h
@@ -0,0 +1,42 @@
+#ifndef TQT_H
+#endif /* TQT_H */
+#ifndef TQT_NO_CODECS
+#define TQT_NO_CODECS
+#endif
+#define TQT_NO_UNICODETABLES
+#define TQT_NO_IMAGEIO_BMP
+#define TQT_NO_IMAGEIO_PPM
+#define TQT_NO_ASYNC_IO
+#define TQT_NO_ASYNC_IMAGE_IO
+/* #define TQT_NO_FREETYPE */
+#define TQT_NO_BDF
+//#define TQT_NO_FONTDATABASE
+#define TQT_NO_TRANSLATION
+#define TQT_NO_DRAGANDDROP
+#define TQT_NO_CLIPBOARD
+#define TQT_NO_SOUND
+#define TQT_NO_PROPERTIES
+#define TQT_NO_DNS
+#define TQT_NO_NETWORKPROTOCOL
+#define TQT_NO_URL
+#define TQT_NO_COLORNAMES
+#define TQT_NO_TRANSFORMATIONS
+#define TQT_NO_PRINTER
+#define TQT_NO_PICTURE
+#define TQT_NO_ICONVIEW
+#define TQT_NO_DIAL
+#define TQT_NO_WORKSPACE
+#define TQT_NO_TABLE
+#define TQT_NO_ACTION
+#define TQT_NO_STYLE_MOTIF
+#define TQT_NO_STYLE_PLATINUM
+/* #define TQT_NO_FILEDIALOG */
+#define TQT_NO_FONTDIALOG
+#define TQT_NO_PRINTDIALOG
+/* #define TQT_NO_COLORDIALOG */
+#define TQT_NO_INPUTDIALOG
+/* #define TQT_NO_MESSAGEBOX */
+#define TQT_NO_PROGRESSDIALOG
+/* #define TQT_NO_TABDIALOG */
+#define TQT_NO_WIZARD
+#define TQT_NO_EFFECTS
diff --git a/tqtinterface/qt4/src/tools/tqconfig-medium.h b/tqtinterface/qt4/src/tools/tqconfig-medium.h
new file mode 100644
index 0000000..36254aa
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqconfig-medium.h
@@ -0,0 +1,108 @@
+#ifndef TQT_H
+#endif /* TQT_H */
+#ifndef TQT_NO_TEXTCODEC /* tqmoc? */
+#define TQT_NO_TEXTCODEC
+#endif
+#define TQT_NO_UNICODETABLES
+#define TQT_NO_IMAGEIO_BMP
+#define TQT_NO_IMAGEIO_PPM
+/* #define TQT_NO_IMAGEIO_PNG */
+#define TQT_NO_ASYNC_IO
+#define TQT_NO_ASYNC_IMAGE_IO
+/* #define TQT_NO_FREETYPE */
+#define TQT_NO_BDF
+//#define TQT_NO_FONTDATABASE
+#define TQT_NO_TRANSLATION
+#define TQT_NO_DRAGANDDROP
+#define TQT_NO_CLIPBOARD
+#define TQT_NO_SOUND
+#define TQT_NO_PROPERTIES
+#define TQT_NO_DNS
+#define TQT_NO_NETWORKPROTOCOL
+#define TQT_NO_COLORNAMES
+#define TQT_NO_TRANSFORMATIONS
+#define TQT_NO_PRINTER
+#define TQT_NO_PICTURE
+#define TQT_NO_ICONVIEW
+#define TQT_NO_DIAL
+#define TQT_NO_WORKSPACE
+#define TQT_NO_TABLE
+#define TQT_NO_ACTION
+#define TQT_NO_STYLE_MOTIF
+#define TQT_NO_STYLE_PLATINUM
+/* #define TQT_NO_FILEDIALOG */
+#define TQT_NO_FONTDIALOG
+#define TQT_NO_PRINTDIALOG
+/* #define TQT_NO_COLORDIALOG */
+#define TQT_NO_INPUTDIALOG
+/* #define TQT_NO_MESSAGEBOX */
+#define TQT_NO_PROGRESSDIALOG
+/* #define TQT_NO_TABDIALOG */
+#define TQT_NO_WIZARD
+#define TQT_NO_EFFECTS
+
+
+#define TQT_NO_MIME
+/* #define TQT_NO_NETWORK //??? means single-process only */
+
+
+#define TQT_NO_IMAGE_TRUECOLOR
+/* #define TQT_NO_IMAGE_SMOOTHSCALE //needed for iconset --> pushbutton */
+#define TQT_NO_IMAGE_TEXT
+#define TQT_NO_DIR
+
+/* #define TQT_NO_TEXTSTREAM */
+#define TQT_NO_DATASTREAM
+#define TQT_NO_TQWS_SAVEFONTS
+
+#define TQT_NO_SESSIONMANAGER
+
+
+/* #define TQT_NO_DIALOG */
+
+#define TQT_NO_SEMIMODAL
+
+#define TQT_NO_EFFECTS
+#define TQT_NO_COP
+
+#define TQT_NO_TQWS_PROPERTIES
+
+/* #define TQT_NO_RANGECONTROL */
+/* #define TQT_NO_SPLITTER */
+#define TQT_NO_STATUSBAR
+#define TQT_NO_TABBAR
+#define TQT_NO_TOOLBAR
+#define TQT_NO_TOOLTIP
+/* #define TQT_NO_VALIDATOR */
+#define TQT_NO_WHATSTHIS
+#define TQT_NO_WIDGETSTACK
+#define TQT_NO_ACCEL
+#define TQT_NO_SIZEGRIP
+#define TQT_NO_HEADER
+#define TQT_NO_WORKSPACE
+#define TQT_NO_LCDNUMBER
+#define TQT_NO_STYLE_MOTIF
+#define TQT_NO_STYLE_PLATINUM
+#define TQT_NO_PROGRESSBAR
+
+#define TQT_NO_ICONVIEW
+#define TQT_NO_DIAL
+
+#define TQT_NO_TABLE
+
+/* #define TQT_NO_FILEDIALOG */
+#define TQT_NO_FONTDIALOG
+#define TQT_NO_PRINTDIALOG
+#define TQT_NO_COLORDIALOG
+#define TQT_NO_INPUTDIALOG
+/* #define TQT_NO_MESSAGEBOX */
+#define TQT_NO_PROGRESSDIALOG
+/* #define TQT_NO_TABDIALOG */
+#define TQT_NO_WIZARD
+#define TQT_NO_EFFECTS
+
+/* #define TQT_NO_TQWS_HYDRO_WM_STYLE */
+#define TQT_NO_TQWS_BEOS_WM_STYLE
+#define TQT_NO_TQWS_KDE2_WM_STYLE
+#define TQT_NO_TQWS_KDE_WM_STYLE
+/* #define TQT_NO_TQWS_WINDOWS_WM_STYLE */
diff --git a/tqtinterface/qt4/src/tools/tqconfig-minimal.h b/tqtinterface/qt4/src/tools/tqconfig-minimal.h
new file mode 100644
index 0000000..8c406bd
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqconfig-minimal.h
@@ -0,0 +1,97 @@
+#ifndef TQT_H
+#endif /* TQT_H */
+
+#ifndef TQT_NO_CHECK
+# define TQT_NO_CHECK
+#endif
+#define TQT_NO_PROCESS
+#define TQT_NO_PALETTE
+#define TQT_NO_ACTION
+#ifndef TQT_NO_TEXTCODEC /* tqmoc? */
+#define TQT_NO_TEXTCODEC
+#endif
+#define TQT_NO_UNICODETABLES
+#define TQT_NO_IMAGEIO_BMP
+#define TQT_NO_IMAGEIO_PPM
+#define TQT_NO_IMAGEIO_XBM
+#define TQT_NO_IMAGEIO_XPM
+/* #define TQT_NO_IMAGEIO_PNG //done by configure -no-png */
+#define TQT_NO_ASYNC_IO
+#define TQT_NO_ASYNC_IMAGE_IO
+/* //#define TQT_NO_FREETYPE //done by configure -no-freetype */
+#define TQT_NO_BDF
+//#define TQT_NO_FONTDATABASE
+#define TQT_NO_TRANSLATION
+#define TQT_NO_MIME
+#define TQT_NO_SOUND
+/* #define TQT_NO_PROPERTIES */
+#define TQT_NO_TQWS_CURSOR
+#define TQT_NO_CURSOR
+#define TQT_NO_TQWS_GFX_SPEED
+#define TQT_NO_NETWORK
+#define TQT_NO_COLORNAMES
+#define TQT_NO_TRANSFORMATIONS
+#define TQT_NO_PRINTER
+#define TQT_NO_PICTURE
+#define TQT_NO_LAYOUT
+#define TQT_NO_DRAWUTIL
+#define TQT_NO_IMAGE_TRUECOLOR
+#define TQT_NO_IMAGE_SMOOTHSCALE
+#define TQT_NO_IMAGE_TEXT
+#define TQT_NO_DIR
+#define TQT_NO_TQWS_MANAGER
+#define TQT_NO_TEXTSTREAM
+#define TQT_NO_DATASTREAM
+#define TQT_NO_TQWS_SAVEFONTS
+//#define TQT_NO_STRINGLIST
+#define TQT_NO_TEMPLATE_VARIANT
+#define TQT_NO_SESSIONMANAGER
+#define TQT_NO_TQWS_KEYBOARD
+#define TQT_NO_SYNTAXHIGHLIGHTER
+
+#define TQT_NO_ACCEL
+#define TQT_NO_BUTTON
+#define TQT_NO_DIALOG
+#define TQT_NO_FRAME
+#define TQT_NO_SEMIMODAL
+
+#define TQT_NO_STYLE
+#define TQT_NO_EFFECTS
+#define TQT_NO_COP
+
+#define TQT_NO_SQL
+
+#define TQT_NO_REGEXP_CAPTURE
+#define TQT_NO_REGEXP_WILDCARD
+
+#define TQT_NO_VALIDATOR
+#define TQT_NO_SPRINTF
+
+#define TQT_NO_REGEXP
+
+#define TQT_NO_IMAGEIO
+
+/* #define TQT_NO_VARIANT //needed for Q_SIGNALS/Q_SLOTS */
+
+#define TQT_NO_RANGECONTROL
+#define TQT_NO_TQUUID_STRING
+#define TQT_NO_SIGNALMAPPER
+
+#define TQT_NO_WHEELEVENT
+#define TQT_NO_BEZIER
+
+#define TQT_NO_TQWS_MOUSE_AUTO
+/* #define TQT_NO_TQWS_MOUSE_MANUAL */
+
+#define TQT_NO_IMAGE_DITHER_TO_1
+#define TQT_NO_IMAGE_HEURISTIC_MASK
+#define TQT_NO_IMAGE_MIRROR
+
+#ifndef TQT_NO_STL
+# define TQT_NO_STL
+#endif
+
+#define TQT_NO_DATESTRING
+#define TQT_NO_WMATRIX
+
+#define TQT_NO_DIRECTPAINTER
diff --git a/tqtinterface/qt4/src/tools/tqconfig-small.h b/tqtinterface/qt4/src/tools/tqconfig-small.h
new file mode 100644
index 0000000..f4b772a
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqconfig-small.h
@@ -0,0 +1,94 @@
+#define NO_CHECK
+#ifndef TQT_H
+#endif /* TQT_H */
+
+#define TQT_NO_ACTION
+#ifndef TQT_NO_TEXTCODEC /* tqmoc? */
+#define TQT_NO_TEXTCODEC
+#endif
+#define TQT_NO_UNICODETABLES
+#define TQT_NO_IMAGEIO_BMP
+#define TQT_NO_IMAGEIO_PPM
+#define TQT_NO_IMAGEIO_XBM
+#define TQT_NO_IMAGEIO_XPM
+/* #define TQT_NO_IMAGEIO_PNG //done by configure -no-png */
+#define TQT_NO_ASYNC_IO
+#define TQT_NO_ASYNC_IMAGE_IO
+/* #define TQT_NO_FREETYPE //done by configure -no-freetype */
+#define TQT_NO_BDF
+//#define TQT_NO_FONTDATABASE
+#define TQT_NO_TRANSLATION
+#define TQT_NO_MIME
+#define TQT_NO_SOUND
+#define TQT_NO_PROPERTIES
+#define TQT_NO_SYNTAXHIGHLIGHTER
+
+#define TQT_NO_TQWS_GFX_SPEED
+#define TQT_NO_NETWORK /* ?????????????? */
+#define TQT_NO_COLORNAMES
+#define TQT_NO_TRANSFORMATIONS
+#define TQT_NO_PRINTER
+#define TQT_NO_PICTURE
+
+#define TQT_NO_IMAGE_TRUECOLOR
+/* #define TQT_NO_IMAGE_SMOOTHSCALE //needed for iconset --> pushbutton */
+#define TQT_NO_IMAGE_TEXT
+#define TQT_NO_DIR
+
+#define TQT_NO_TEXTSTREAM
+#define TQT_NO_DATASTREAM
+#define TQT_NO_TQWS_SAVEFONTS
+//#define TQT_NO_STRINGLIST
+#define TQT_NO_SESSIONMANAGER
+
+
+#define TQT_NO_DIALOG
+
+#define TQT_NO_SEMIMODAL
+
+/* #define TQT_NO_STYLE //will require substantial work... */
+
+#define TQT_NO_EFFECTS
+#define TQT_NO_COP
+
+#define TQT_NO_TQWS_PROPERTIES
+
+#define TQT_NO_RANGECONTROL
+#define TQT_NO_SPLITTER
+#define TQT_NO_STATUSBAR
+#define TQT_NO_TABBAR
+#define TQT_NO_TOOLBAR
+#define TQT_NO_TOOLTIP
+#define TQT_NO_VALIDATOR
+#define TQT_NO_WHATSTHIS
+#define TQT_NO_WIDGETSTACK
+#define TQT_NO_ACCEL
+#define TQT_NO_SIZEGRIP
+#define TQT_NO_HEADER
+#define TQT_NO_WORKSPACE
+#define TQT_NO_LCDNUMBER
+#define TQT_NO_STYLE_MOTIF
+#define TQT_NO_STYLE_PLATINUM
+#define TQT_NO_PROGRESSBAR
+
+
+#define TQT_NO_TQWS_HYDRO_WM_STYLE
+#define TQT_NO_TQWS_BEOS_WM_STYLE
+#define TQT_NO_TQWS_KDE2_WM_STYLE
+#define TQT_NO_TQWS_KDE_WM_STYLE
+#define TQT_NO_TQWS_WINDOWS_WM_STYLE
+
+
+/* other widgets that could be removed: */
+/*
+#define TQT_NO_MENUDATA
+*/
+
+
+/* possible options: */
+/*
+#define TQT_NO_CURSOR
+#define TQT_NO_LAYOUT
+#define TQT_NO_TQWS_MANAGER
+#define TQT_NO_TQWS_KEYBOARD
+*/
diff --git a/tqtinterface/qt4/src/tools/tqcriticalsection_p.cpp b/tqtinterface/qt4/src/tools/tqcriticalsection_p.cpp
new file mode 100644
index 0000000..ed6ead8
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcriticalsection_p.cpp
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Implementation of TQCriticalSection class
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#if defined(TQT_THREAD_SUPPORT)
+
+#include "tqt_windows.h"
+
+#include <private/tqcriticalsection_p.h>
+
+class TQCriticalSectionPrivate
+{
+public:
+ TQCriticalSectionPrivate() {}
+
+ CRITICAL_SECTION section;
+};
+
+
+TQCriticalSection::TQCriticalSection()
+{
+ d = new TQCriticalSectionPrivate;
+ InitializeCriticalSection( &d->section );
+}
+
+TQCriticalSection::~TQCriticalSection()
+{
+ DeleteCriticalSection( &d->section );
+ delete d;
+}
+
+void TQCriticalSection::enter()
+{
+ EnterCriticalSection( &d->section );
+}
+
+void TQCriticalSection::leave()
+{
+ LeaveCriticalSection( &d->section );
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqcriticalsection_p.h b/tqtinterface/qt4/src/tools/tqcriticalsection_p.h
new file mode 100644
index 0000000..21d1f6d
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcriticalsection_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Definition of TQCriticalSection class
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCRITICALSECTION_P_H
+#define TQCRITICALSECTION_P_H
+
+#ifndef TQT_H
+#endif // TQT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of TQt Remote Control. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#if defined(TQT_THREAD_SUPPORT)
+
+#if defined(TQ_WS_WIN)
+
+/*
+ TQCriticalSection
+*/
+
+class TQCriticalSectionPrivate;
+
+class TQCriticalSection
+{
+public:
+ TQCriticalSection();
+ ~TQCriticalSection();
+ void enter();
+ void leave();
+
+private:
+ TQCriticalSectionPrivate *d;
+};
+
+#endif
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqcstring.cpp b/tqtinterface/qt4/src/tools/tqcstring.cpp
new file mode 100644
index 0000000..f81348f
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcstring.cpp
@@ -0,0 +1,4149 @@
+/****************************************************************************
+**
+** Implementation of extended char array operations, and TQByteArray and
+** TQCString classes
+**
+** Created : 920722
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqstring.h"
+#include "tqregexp.h"
+#include "tqdatastream.h"
+
+#ifdef TQT_THREAD_SUPPORT
+# include <private/tqmutexpool_p.h>
+#endif // TQT_THREAD_SUPPORT
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <limits.h>
+#ifndef TQT_NO_COMPRESS
+#include "../3rdparty/zlib/zlib.h"
+#endif
+
+/*****************************************************************************
+ Safe and portable C string functions; extensions to standard string.h
+ *****************************************************************************/
+
+/*!
+ \relates TQCString
+
+ This function is normally part of the C library. TQt implements
+ memmove() for platforms that do not provide it.
+
+ memmove() copies \a len bytes from \a src into \a dst. The data
+ is copied correctly even if \a src and \a dst overlap.
+*/
+
+void *tqmemmove( void *dst, const void *src, uint len )
+{
+ register char *d;
+ register char *s;
+ if ( dst > src ) {
+ d = (char *)dst + len - 1;
+ s = (char *)src + len - 1;
+ while ( len-- )
+ *d-- = *s--;
+ } else if ( dst < src ) {
+ d = (char *)dst;
+ s = (char *)src;
+ while ( len-- )
+ *d++ = *s++;
+ }
+ return dst;
+}
+
+
+/*!
+ \relates TQCString
+
+ Returns a duplicate string.
+
+ Allocates space for a copy of \a src, copies it, and returns a
+ pointer to the copy. If \a src is 0, it immediately returns 0.
+
+ The returned string must be deleted using \c delete[].
+*/
+
+char *tqstrdup( const char *src )
+{
+ if ( !src )
+ return 0;
+ char *dst = new char[strlen(src)+1];
+ TQ_CHECK_PTR( dst );
+ return strcpy( dst, src );
+}
+
+/*!
+ \fn char *qstrcpy( char *dst, const char *src )
+
+ \relates TQCString
+
+ A safe strcpy() function.
+
+ Copies all characters up to and including the '\0' from \a src
+ into \a dst and returns a pointer to \a dst.
+*/
+
+/*!
+ \relates TQCString
+
+ A safe strncpy() function.
+
+ Copies at most \a len bytes from \a src (stopping at \a len or the
+ terminating '\0' whichever comes first) into \a dst and returns a
+ pointer to \a dst. Guarantees that \a dst is '\0'-terminated. If
+ \a src or \a dst is 0, returns 0 immediately.
+
+ \sa qstrcpy()
+*/
+
+char *tqstrncpy( char *dst, const char *src, uint len )
+{
+ if ( !src || !dst )
+ return 0;
+ strncpy( dst, src, len );
+ if ( len > 0 )
+ dst[len-1] = '\0';
+ return dst;
+}
+
+/*!
+ \fn uint tqstrlen( const char *str );
+
+ \relates TQCString
+
+ A safe strlen function.
+
+ Returns the number of characters that precede the terminating '\0'.
+ or 0 if \a str is 0.
+*/
+
+/*!
+ \fn int qstrcmp( const char *str1, const char *str2 );
+
+ \relates TQCString
+
+ A safe strcmp() function.
+
+ Compares \a str1 and \a str2. Returns a negative value if \a str1
+ is less than \a str2, 0 if \a str1 is equal to \a str2 or a
+ positive value if \a str1 is greater than \a str2.
+
+ Special case I: Returns 0 if \a str1 and \a str2 are both 0.
+
+ Special case II: Returns a random nonzero value if \a str1 is 0
+ or \a str2 is 0 (but not both).
+
+ \sa tqstrncmp() qstricmp() qstrnicmp()
+ \link #asciinotion Note on character comparisons \endlink
+*/
+
+/*!
+ \fn int tqstrncmp( const char *str1, const char *str2, uint len );
+
+ \relates TQCString
+
+ A safe strncmp() function.
+
+ Compares at most \a len bytes of \a str1 and \a str2.
+
+ Returns a negative value if \a str1 is less than \a str2, 0 if \a
+ str1 is equal to \a str2 or a positive value if \a str1 is greater
+ than \a str2.
+
+ Special case I: Returns 0 if \a str1 and \a str2 are both 0.
+
+ Special case II: Returns a random nonzero value if \a str1 is 0
+ or \a str2 is 0 (but not both).
+
+ \sa qstrcmp(), qstricmp(), qstrnicmp()
+ \link #asciinotion Note on character comparisons \endlink
+*/
+
+/*!
+ \relates TQCString
+
+ A safe stricmp() function.
+
+ Compares \a str1 and \a str2 ignoring the case.
+
+ Returns a negative value if \a str1 is less than \a str2, 0 if \a
+ str1 is equal to \a str2 or a positive value if \a str1 is greater
+ than \a str2.
+
+ Special case I: Returns 0 if \a str1 and \a str2 are both 0.
+
+ Special case II: Returns a random nonzero value if \a str1 is 0
+ or \a str2 is 0 (but not both).
+
+ \sa qstrcmp(), tqstrncmp(), qstrnicmp()
+ \link #asciinotion Note on character comparisons \endlink
+*/
+
+int tqstricmp( const char *str1, const char *str2 )
+{
+ register const uchar *s1 = (const uchar *)str1;
+ register const uchar *s2 = (const uchar *)str2;
+ int res;
+ uchar c;
+ if ( !s1 || !s2 )
+ return s1 ? 1 : ( s2 ? -1 : 0 );
+ for ( ; !(res = (c=tolower(*s1)) - tolower(*s2)); s1++, s2++ )
+ if ( !c ) // strings are equal
+ break;
+ return res;
+}
+
+/*!
+ \relates TQCString
+
+ A safe strnicmp() function.
+
+ Compares at most \a len bytes of \a str1 and \a str2 ignoring the case.
+
+ Returns a negative value if \a str1 is less than \a str2, 0 if \a str1
+ is equal to \a str2 or a positive value if \a str1 is greater than \a
+ str2.
+
+ Special case I: Returns 0 if \a str1 and \a str2 are both 0.
+
+ Special case II: Returns a random nonzero value if \a str1 is 0
+ or \a str2 is 0 (but not both).
+
+ \sa qstrcmp(), tqstrncmp() qstricmp()
+ \link #asciinotion Note on character comparisons \endlink
+*/
+
+int tqstrnicmp( const char *str1, const char *str2, uint len )
+{
+ register const uchar *s1 = (const uchar *)str1;
+ register const uchar *s2 = (const uchar *)str2;
+ int res;
+ uchar c;
+ if ( !s1 || !s2 )
+ return s1 ? 1 : ( s2 ? -1 : 0 );
+ for ( ; len--; s1++, s2++ ) {
+ if ( (res = (c=tolower(*s1)) - tolower(*s2)) )
+ return res;
+ if ( !c ) // strings are equal
+ break;
+ }
+ return 0;
+}
+
+
+static TQ_UINT16 crc_tbl[16];
+static bool crc_tbl_init = FALSE;
+
+static void createCRC16Table() // build CRC16 lookup table
+{
+ register uint i;
+ register uint j;
+ uint v0, v1, v2, v3;
+ for ( i = 0; i < 16; i++ ) {
+ v0 = i & 1;
+ v1 = ( i >> 1 ) & 1;
+ v2 = ( i >> 2 ) & 1;
+ v3 = ( i >> 3 ) & 1;
+ j = 0;
+#undef SET_BIT
+#define SET_BIT(x, b, v) (x) |= (v) << (b)
+ SET_BIT( j, 0, v0 );
+ SET_BIT( j, 7, v0 );
+ SET_BIT( j, 12, v0 );
+ SET_BIT( j, 1, v1 );
+ SET_BIT( j, 8, v1 );
+ SET_BIT( j, 13, v1 );
+ SET_BIT( j, 2, v2 );
+ SET_BIT( j, 9, v2 );
+ SET_BIT( j, 14, v2 );
+ SET_BIT( j, 3, v3 );
+ SET_BIT( j, 10, v3 );
+ SET_BIT( j, 15, v3 );
+ crc_tbl[i] = j;
+ }
+}
+
+/*!
+ \relates TQMemArray
+
+ Returns the CRC-16 checksum of \a len bytes starting at \a data.
+
+ The checksum is independent of the byte order (endianness).
+*/
+
+TQ_UINT16 qChecksum( const char *data, uint len )
+{
+ if ( !crc_tbl_init ) { // create lookup table
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &crc_tbl_init ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+
+ if ( !crc_tbl_init ) {
+ createCRC16Table();
+ crc_tbl_init = TRUE;
+ }
+ }
+ register TQ_UINT16 crc = 0xffff;
+ uchar c;
+ uchar *p = (uchar *)data;
+ while ( len-- ) {
+ c = *p++;
+ crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)];
+ c >>= 4;
+ crc = ( (crc >> 4) & 0x0fff ) ^ crc_tbl[((crc ^ c) & 15)];
+ }
+ return ~crc & 0xffff;
+}
+
+/*!
+ \fn TQByteArray tqCompress( const TQByteArray& data )
+
+ \relates TQByteArray
+
+ Compresses the array \a data and returns the compressed byte
+ array using zlib.
+
+ \sa tqUncompress()
+*/
+
+/*!
+ \relates TQByteArray
+
+ \overload
+
+ Compresses the array \a data which is \a nbytes long and returns the
+ compressed byte array.
+*/
+
+#ifndef TQT_NO_COMPRESS
+TQByteArray tqCompress( const uchar* data, int nbytes )
+{
+ if ( nbytes == 0 ) {
+ TQByteArray tmp( 4 );
+ tmp.fill( 0 );
+ return tmp;
+ }
+ if ( !data ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "tqCompress: data is NULL." );
+#endif
+ return TQByteArray();
+ }
+
+ ulong len = nbytes + nbytes / 100 + 13;
+ TQByteArray bazip;
+ int res;
+ do {
+ bazip.resize( len + 4 );
+ res = ::compress( (uchar*)bazip.data()+4, &len, (uchar*)data, nbytes );
+
+ switch ( res ) {
+ case Z_OK:
+ bazip.resize( len + 4 );
+ bazip[0] = ( nbytes & 0xff000000 ) >> 24;
+ bazip[1] = ( nbytes & 0x00ff0000 ) >> 16;
+ bazip[2] = ( nbytes & 0x0000ff00 ) >> 8;
+ bazip[3] = ( nbytes & 0x000000ff );
+ break;
+ case Z_MEM_ERROR:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "tqCompress: Z_MEM_ERROR: Not enough memory." );
+#endif
+ bazip.resize( 0 );
+ break;
+ case Z_BUF_ERROR:
+ len *= 2;
+ break;
+ }
+ } while ( res == Z_BUF_ERROR );
+
+ return bazip;
+}
+#endif
+
+/*!
+ \fn TQByteArray tqUncompress( const TQByteArray& data )
+
+ \relates TQByteArray
+
+ Uncompresses the array \a data and returns the uncompressed byte
+ array.
+
+ Returns an empty TQByteArray if the input data was corrupt.
+ \omit
+ ADD THE FOLLOWING FOR TQt 4.0
+ This function will uncompress data compressed with tqCompress()
+ from this and any earlier TQt version, back to TQt 3.1 when this
+ feature was added.
+ \endomit
+
+ \sa tqCompress()
+*/
+
+/*!
+ \relates TQByteArray
+
+ \overload
+
+ Uncompresses the array \a data which is \a nbytes long and returns
+ the uncompressed byte array.
+*/
+
+#ifndef TQT_NO_COMPRESS
+TQByteArray tqUncompress( const uchar* data, int nbytes )
+{
+ if ( !data ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "tqUncompress: data is NULL." );
+#endif
+ return TQByteArray();
+ }
+ if ( nbytes <= 4 ) {
+#if defined(TQT_CHECK_RANGE)
+ if ( nbytes < 4 || ( data[0]!=0 || data[1]!=0 || data[2]!=0 || data[3]!=0 ) )
+ qWarning( "tqUncompress: Input data is corrupted." );
+#endif
+ return TQByteArray();
+ }
+ ulong expectedSize = ( data[0] << 24 ) | ( data[1] << 16 ) | ( data[2] << 8 ) | data[3];
+ ulong len = TQMAX( expectedSize, 1 );
+ TQByteArray baunzip;
+ int res;
+ do {
+ if ( baunzip.tqresize( len ) ) {
+ res = ::uncompress( (uchar*)baunzip.data(), &len,
+ (uchar*)data+4, nbytes-4 );
+ } else {
+ res = Z_MEM_ERROR;
+ }
+
+ switch ( res ) {
+ case Z_OK:
+ if ( len != baunzip.size() )
+ baunzip.resize( len );
+ break;
+ case Z_MEM_ERROR:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "tqUncompress: Z_MEM_ERROR: Not enough memory." );
+#endif
+ break;
+ case Z_BUF_ERROR:
+ len *= 2;
+ break;
+ case Z_DATA_ERROR:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "tqUncompress: Z_DATA_ERROR: Input data is corrupted." );
+#endif
+ break;
+ }
+ } while ( res == Z_BUF_ERROR );
+
+ if ( res != Z_OK )
+ baunzip = TQByteArray();
+
+ return baunzip;
+}
+#endif
+
+/*****************************************************************************
+ TQByteArray documentation
+ *****************************************************************************/
+
+/*!
+ \class TQByteArray
+ \reentrant
+ \brief The TQByteArray class provides an array of bytes.
+
+ \ingroup collection
+ \ingroup tools
+
+ The TQByteArray class provides an explicitly shared array of bytes.
+ It is useful for manipulating memory areas with custom data.
+ TQByteArray is implemented as a TQMemArray\<char\>. See the \l
+ TQMemArray documentation for further information.
+*/
+
+/*!
+ \fn TQByteArray::TQByteArray()
+
+ Constructs an empty TQByteArray.
+*/
+
+/*!
+ \fn TQByteArray::TQByteArray( int size )
+
+ Constructs a TQByteArray of size \a size.
+*/
+
+// /*****************************************************************************
+// TQByteArray stream functions
+// *****************************************************************************/
+//
+// /*!
+// \relates TQMemArray
+//
+// Writes byte array \a a to the stream \a s and returns a reference
+// to the stream.
+//
+// \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+// */
+// #ifndef TQT_NO_DATASTREAM
+//
+// TQDataStream &operator<<( TQDataStream &s, const TQByteArray &a )
+// {
+// return s.writeBytes( a.data(), a.size() );
+// }
+//
+// /*!
+// \relates TQMemArray
+//
+// Reads a byte array into \a a from the stream \a s and returns a
+// reference to the stream.
+//
+// \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+// */
+//
+// TQDataStream &operator>>( TQDataStream &s, TQByteArray &a )
+// {
+// TQ_UINT32 len;
+// s >> len; // read size of array
+// if ( len == 0 || s.eof() ) { // end of file reached
+// a.resize( 0 );
+// return s;
+// }
+// if ( !a.resize( (uint)len ) ) { // resize array
+// #if defined(TQT_CHECK_NULL)
+// qWarning( "TQDataStream: Not enough memory to read TQByteArray" );
+// #endif
+// len = 0;
+// }
+// if ( len > 0 ) // not null array
+// s.readRawBytes( a.data(), (uint)len );
+// return s;
+// }
+//
+// #endif //TQT_NO_DATASTREAM
+
+#ifdef USE_QT4
+
+/*****************************************************************************
+ TQByteArray stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQDataStream &operator<<( TQDataStream &d, const TQByteArray &s ) {
+ if (d.version() >= QDataStream::Qt_4_0) {
+ QDataStream &qds = operator<<(static_cast<QDataStream &>(d), static_cast<const QByteArray &>(s));
+ TQDataStream &tqds = *static_cast<TQDataStream*>(&qds);
+ return tqds;
+ }
+
+ // we need to add a NUL to keep compatibility with Qt 3's QByteArray
+ QByteArray copy = s;
+ copy.append('\0');
+
+ QDataStream &qds = operator<<(static_cast<QDataStream &>(d), static_cast<const QByteArray &>(s));
+ TQDataStream &tqds = *static_cast<TQDataStream*>(&qds);
+ return tqds;
+}
+
+TQDataStream &operator>>( TQDataStream &d, TQByteArray &s ) {
+ operator>>(d, static_cast<QByteArray &>(s));
+ if (d.version() < QDataStream::Qt_4_0 && s.endsWith('\0'))
+ s.chop(1); // ending NUL
+ return d;
+}
+#endif // TQT_NO_DATASTREAM
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+/*!
+ \reimp
+*/
+
+TQByteArray::~TQByteArray()
+{
+}
+
+#endif // USE_QT4
+
+/*****************************************************************************
+ TQCString member functions
+ *****************************************************************************/
+
+// #ifdef USE_QT4
+#if 0
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ Constructs a string with room for \a size characters, including
+ the '\0'-terminator. Makes a null string if \a size == 0.
+
+ If \a size \> 0, then the first and last characters in the string
+ are initialized to '\0'. All other characters are uninitialized.
+
+ \sa resize(), isNull()
+*/
+
+// TQCString::TQCString( int size )
+// : TQByteArray( size )
+// {
+// if ( size > 0 ) {
+// *data() = '\0'; // set terminator
+// *(data()+(size-1)) = '\0';
+// }
+// }
+
+TQCString::TQCString( int size )
+ : TQByteArray(size, '\0')
+{
+}
+
+/*!
+ Constructs a string that is a deep copy of \a str.
+
+ If \a str is 0 a null string is created.
+
+ \sa isNull()
+*/
+
+TQCString::TQCString( const char *str )
+{
+ duplicate( str, tqstrlen(str) + 1 );
+}
+
+
+/*!
+ Constructs a string that is a deep copy of \a str. The copy will
+ be at most \a maxsize bytes long including the '\0'-terminator.
+
+ Example:
+ \code
+ TQCString str( "helloworld", 6 ); // assigns "hello" to str
+ \endcode
+
+ If \a str tqcontains a 0 byte within the first \a maxsize bytes, the
+ resulting TQCString will be terminated by this 0. If \a str is 0 a
+ null string is created.
+
+ \sa isNull()
+*/
+
+TQCString::TQCString( const char *str, uint maxsize )
+{
+ if ( str == 0 )
+ return;
+ uint len; // index of first '\0'
+ for ( len = 0; len < maxsize - 1; len++ ) {
+ if ( str[len] == '\0' )
+ break;
+ }
+ TQByteArray::tqresize( len + 1 );
+ memcpy( data(), str, len );
+ data()[len] = 0;
+}
+
+// TQCString(int size) : TQByteArray(size, '\0') {}
+// TQCString(const char *str) : TQByteArray(str) {}
+// TQCString(const char *str, uint maxlen) : TQByteArray(str, qMin(tqstrlen(str), maxlen - 1)) {}
+// // TQCString(const char *str, uint maxlen) : TQByteArray(str, TQMIN(tqstrlen(str)+1, maxlen)) {} // This would seem to be more correct at first glance, however it completely breaks kconfig_compiler. As to why, I don't know!!! [FIXME]
+
+TQCString &TQCString::operator=(const TQCString &s) {
+ TQByteArray::operator=(s);
+ return *this;
+}
+
+TQCString &TQCString::operator=(const char *str) {
+// TQByteArray::operator=(str); return *this;
+ TQByteArray::operator=(duplicate( str, tqstrlen(str)+1 ));
+ return *this;
+}
+
+TQCString &TQCString::operator=(const QByteArray &ba) {
+ TQByteArray::operator=(ba);
+ return *this;
+}
+
+/*****************************************************************************
+ TQCString member functions
+ *****************************************************************************/
+
+/*!
+ \class TQCString
+ \reentrant
+ \brief The TQCString class provides an abstraction of the classic C
+ zero-terminated char array (char *).
+
+ \compat
+
+ TQCString tries to behave like a more convenient \c{const char *}.
+ The price of doing this is that some algorithms will perform
+ badly. For example, append() is O(length()) since it scans for a
+ null terminator. Although you might use TQCString for text that is
+ never exposed to the user, for most purposes, and especially for
+ user-visible text, you should use QString. QString provides
+ implicit sharing, Unicode and other internationalization support,
+ and is well optimized.
+
+ Note that for the TQCString methods that take a \c{const char *}
+ parameter the \c{const char *} must either be 0 (null) or not-null
+ and '\0' (NUL byte) terminated; otherwise the results are
+ undefined.
+
+ A default constructed TQCString is \e null, i.e. both the length
+ and the data pointer are 0 and isNull() returns true.
+
+ \note However, if you ask for the data pointer of a null TQCString
+ by calling data(), then because the internal representation of the
+ null TQCString is shared, it will be detached and tqreplaced with a
+ non-shared, empty representation, a non-null data pointer will be
+ returned, and subsequent calls to isNull() will return false. But
+ if you ask for the data pointer of a null TQCString by calling
+ constData(), the shared internal representation is not detached, a
+ null data pointer is returned, and subsequent calls to isNull()
+ will continue to return true.
+
+ A TQCString that references the empty string ("", a single '\0'
+ char) is \e empty, i.e. isEmpty() returns true. Both null and
+ empty TQCStrings are legal parameters to the methods. Assigning
+ \c{const char *} 0 to TQCString produces a null TQCString.
+
+ The length() function returns the length of the string; resize()
+ resizes the string and truncate() truncates the string. A string
+ can be filled with a character using fill(). Strings can be left
+ or right padded with characters using leftJustify() and
+ rightJustify(). Characters, strings and regular expressions can be
+ searched for using find() and findRev(), and counted using
+ tqcontains().
+
+ Strings and characters can be inserted with insert() and appended
+ with append(). A string can be prepended with prepend().
+ Characters can be removed from the string with remove() and
+ tqreplaced with tqreplace().
+
+ Portions of a string can be extracted using left(), right() and
+ mid(). Whitespace can be removed using stripWhiteSpace() and
+ simplifyWhiteSpace(). Strings can be converted to uppercase or
+ lowercase with upper() and lower() respectively.
+
+ Strings that contain numbers can be converted to numbers with
+ toShort(), toInt(), toLong(), toULong(), toFloat() and toDouble().
+ Numbers can be converted to strings with setNum().
+
+ Many operators are overloaded to work with TQCStrings. TQCString
+ also supports some more obscure functions, e.g. sprintf(),
+ setStr() and setExpand().
+
+ \sidebar Note on Character Comparisons
+
+ In TQCString the notion of uppercase and lowercase and of which
+ character is greater than or less than another character is locale
+ dependent. This affects functions which support a case insensitive
+ option or which compare or lowercase or uppercase their arguments.
+ Case insensitive operations and comparisons will be accurate if
+ both strings contain only ASCII characters. (If \c $LC_CTYPE is
+ set, most Unix systems do "the right thing".) Functions that this
+ affects include tqcontains(), find(), findRev(), \l operator<(), \l
+ operator<=(), \l operator>(), \l operator>=(), lower() and
+ upper().
+
+ This issue does not apply to \l{QString}s since they represent
+ characters using Unicode.
+ \endsidebar
+
+ Performance note: The TQCString methods for QRegExp searching are
+ implemented by converting the TQCString to a QString and performing
+ the search on that. This implies a deep copy of the TQCString data.
+ If you are going to perform many QRegExp searches on a large
+ TQCString, you will get better performance by converting the
+ TQCString to a QString yourself, and then searching in the QString.
+*/
+
+/*!
+ \fn TQCString TQCString::left(uint len) const
+
+ \internal
+*/
+
+/*!
+ \fn TQCString TQCString::right(uint len) const
+
+ \internal
+*/
+
+/*!
+ \fn TQCString TQCString::mid(uint index, uint len) const
+
+ \internal
+*/
+
+/*!
+ \fn TQCString TQCString::lower() const
+
+ Use QByteArray::toLower() instead.
+*/
+
+/*!
+ \fn TQCString TQCString::upper() const
+
+ Use QByteArray::toUpper() instead.
+*/
+
+/*!
+ \fn TQCString TQCString::stripWhiteSpace() const
+
+ Use QByteArray::trimmed() instead.
+*/
+
+/*!
+ \fn TQCString TQCString::simplifyWhiteSpace() const
+
+ Use QByteArray::simplified() instead.
+*/
+
+/*!
+ \fn TQCString& TQCString::insert(uint index, const char *c)
+
+ \internal
+*/
+
+/*!
+ \fn TQCString& TQCString::insert(uint index, char c)
+
+ \internal
+*/
+
+/*!
+ \fn TQCString& TQCString::prepend(const char *c)
+
+ \internal
+*/
+
+/*!
+ \fn TQCString& TQCString::remove(uint index, uint len)
+
+ \internal
+*/
+
+/*!
+ \fn TQCString& TQCString::tqreplace(uint index, uint len, const char *c)
+
+ \internal
+*/
+
+/*!
+ \fn TQCString& TQCString::tqreplace(char c, const TQCString &after)
+
+ \internal
+*/
+
+/*!
+ \fn TQCString& TQCString::tqreplace(char c, const char *after)
+
+ \internal
+*/
+
+/*!
+ \fn TQCString& TQCString::tqreplace(const TQCString &b, const TQCString &a)
+
+ \internal
+*/
+
+/*!
+ \fn TQCString& TQCString::tqreplace(const char *b, const char *a)
+
+ \internal
+*/
+
+/*!
+ \fn TQCString& TQCString::tqreplace(char b, char a)
+
+ \internal
+*/
+
+/*!
+ \fn TQCString::TQCString()
+
+ Constructs a null string.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn TQCString::TQCString(const QByteArray &ba)
+
+ Constructs a copy of \a ba.
+*/
+
+/*!
+ \fn TQCString::TQCString(const TQCString &s)
+
+ Constructs a shallow copy \a s.
+*/
+
+/*! \fn TQCString::TQCString(int size)
+ Constructs a string with room for \a size characters, including
+ the '\0'-terminator. Makes a null string if \a size == 0.
+
+ If \a size \> 0, then the first and last characters in the string
+ are initialized to '\0'. All other characters are uninitialized.
+
+ \sa resize(), isNull()
+*/
+
+/*! \fn TQCString::TQCString(const char *str)
+ Constructs a string that is a deep copy of \a str.
+
+ If \a str is 0 a null string is created.
+
+ \sa isNull()
+*/
+
+
+/*! \fn TQCString::TQCString(const char *str, uint maxsize)
+
+ Constructs a string that is a deep copy of \a str. The copy will
+ be at most \a maxsize bytes long including the '\0'-terminator.
+
+ Example:
+ \snippet doc/src/snippets/code/src_qt3support_tools_q3cstring.cpp 0
+
+ If \a str tqcontains a 0 byte within the first \a maxsize bytes, the
+ resulting TQCString will be terminated by this 0. If \a str is 0 a
+ null string is created.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn TQCString &TQCString::operator=(const QByteArray &ba)
+
+ Assigns byte array \a ba to this TQCString.
+*/
+
+/*!
+ \fn TQCString &TQCString::operator=(const TQCString &s)
+
+ Assigns a shallow copy of \a s to this string and returns a
+ reference to this string.
+*/
+
+/*!
+ \fn TQCString &TQCString::operator=(const char *str)
+ \overload
+
+ Assigns a deep copy of \a str to this string and returns a
+ reference to this string.
+
+ If \a str is 0 a null string is created.
+
+ \sa isNull()
+*/
+
+/*
+ \fn bool TQCString::isNull() const
+
+ Returns true if the string is null, i.e. if data() == 0; otherwise
+ returns false. A null string is also an empty string.
+
+ \note If you ask for the data pointer of a null TQCString by
+ calling data(), then because the internal representation of the
+ null TQCString is shared, it will be detached and tqreplaced with a
+ non-shared, empty representation, a non-null data pointer will be
+ returned, and subsequent calls to isNull() will return false. But
+ if you ask for the data pointer of a null TQCString by calling
+ constData(), the shared internal representation is not detached, a
+ null data pointer is returned, and subsequent calls to isNull()
+ will continue to return true.
+
+ Example:
+ \snippet doc/src/snippets/code/src.qt3support.tools.q3cstring.cpp 1
+
+ \sa isEmpty(), length(), size()
+*/
+
+/*
+ \fn bool TQCString::isEmpty() const
+
+ Returns true if the string is empty, i.e. if length() == 0;
+ otherwise returns false. An empty string is not always a null
+ string.
+
+ See example in isNull().
+
+ \sa isNull(), length(), size()
+*/
+
+/*
+ \fn uint TQCString::length() const
+
+ Returns the length of the string, excluding the '\0'-terminator.
+ Equivalent to calling \c strlen(data()).
+
+ Null strings and empty strings have zero length.
+
+ \sa size(), isNull(), isEmpty()
+*/
+
+/*
+ \fn bool TQCString::truncate(uint pos)
+
+ Truncates the string at position \a pos.
+
+ Equivalent to calling \c resize(pos+1).
+
+ Example:
+ \snippet doc/src/snippets/code/src.qt3support.tools.q3cstring.cpp 2
+
+ \sa resize()
+*/
+
+/*!
+ \reimp
+*/
+
+TQCString::~TQCString()
+{
+}
+
+/*!
+ Implemented as a call to the native vsprintf() (see the manual for
+ your C library).
+
+ If the string is shorter than 256 characters, this sprintf() calls
+ resize(256) to decrease the chance of memory corruption. The
+ string is resized back to its actual length before sprintf()
+ returns.
+
+ Example:
+ \snippet doc/src/snippets/code/src_qt3support_tools_q3cstring.cpp 3
+
+ \warning All vsprintf() implementations will write past the end of
+ the target string (*this) if the \a format specification and
+ arguments happen to be longer than the target string, and some
+ will also fail if the target string is longer than some arbitrary
+ implementation limit.
+
+ Giving user-supplied arguments to sprintf() is risky: Sooner or
+ later someone will paste a huge line into your application.
+*/
+
+TQCString &TQCString::sprintf(const char *format, ...)
+{
+ detach();
+ va_list ap;
+ va_start(ap, format);
+ if (size() < 256)
+ resize(256); // make string big enough
+ qvsnprintf(data(), size(), format, ap);
+ resize(qstrlen(constData()));
+ va_end(ap);
+ return *this;
+}
+
+
+
+/*!
+ \fn TQCString TQCString::copy() const
+
+ Returns a deep copy of this string.
+*/
+
+
+/*!
+ Returns a string of length \a width (plus one for the terminating
+ '\0') that tqcontains this string padded with the \a fill character.
+
+ If the length of the string exceeds \a width and \a truncate is
+ false (the default), then the returned string is a copy of the
+ string. If the length of the string exceeds \a width and \a
+ truncate is true, then the returned string is a left(\a width).
+
+ Example:
+ \snippet doc/src/snippets/code/src_qt3support_tools_q3cstring.cpp 4
+
+ \sa rightJustify()
+*/
+
+TQCString TQCString::leftJustify(uint width, char fill, bool truncate) const
+{
+ TQCString result;
+ int len = qstrlen(constData());
+ int padlen = width - len;
+ if (padlen > 0) {
+ result.resize(len+padlen);
+ memcpy(result.data(), constData(), len);
+ memset(result.data()+len, fill, padlen);
+ } else {
+ if (truncate)
+ result = left(width);
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns a string of length \a width (plus one for the terminating
+ '\0') that tqcontains zero or more of the \a fill character followed
+ by this string.
+
+ If the length of the string exceeds \a width and \a truncate is
+ false (the default), then the returned string is a copy of the
+ string. If the length of the string exceeds \a width and \a
+ truncate is true, then the returned string is a left(\a width).
+
+ Example:
+ \snippet doc/src/snippets/code/src_qt3support_tools_q3cstring.cpp 5
+
+ \sa leftJustify()
+*/
+
+TQCString TQCString::rightJustify(uint width, char fill, bool truncate) const
+{
+ TQCString result;
+ int len = qstrlen(constData());
+ int padlen = width - len;
+ if (padlen > 0) {
+ result.resize(len+padlen);
+ memset(result.data(), fill, padlen);
+ memcpy(result.data()+padlen, constData(), len);
+ } else {
+ if (truncate)
+ result = left(width);
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns the string converted to a \c long value.
+
+ If \a ok is not 0: *\a ok is set to false if the string is not a
+ number, or if it has trailing garbage; otherwise *\a ok is set to
+ true.
+*/
+
+long TQCString::toLong(bool *ok) const
+{
+ const char *p = constData();
+ long val=0;
+ const long max_mult = 214748364;
+ bool is_ok = false;
+ int neg = 0;
+ if (!p)
+ goto bye;
+ while (isspace((uchar) *p)) // skip leading space
+ p++;
+ if (*p == '-') {
+ p++;
+ neg = 1;
+ } else if (*p == '+') {
+ p++;
+ }
+ if (!isdigit((uchar) *p))
+ goto bye;
+ while (isdigit((uchar) *p)) {
+ if (val > max_mult || (val == max_mult && (*p-'0') > 7+neg))
+ goto bye;
+ val = 10*val + (*p++ - '0');
+ }
+ if (neg)
+ val = -val;
+ while (isspace((uchar) *p)) // skip trailing space
+ p++;
+ if (*p == '\0')
+ is_ok = true;
+bye:
+ if (ok)
+ *ok = is_ok;
+ return is_ok ? val : 0;
+}
+
+/*!
+ Returns the string converted to an \c{unsigned long} value.
+
+ If \a ok is not 0: *\a ok is set to false if the string is not a
+ number, or if it has trailing garbage; otherwise *\a ok is set to
+ true.
+*/
+
+ulong TQCString::toULong(bool *ok) const
+{
+ const char *p = constData();
+ ulong val=0;
+ const ulong max_mult = 429496729;
+ bool is_ok = false;
+ if (!p)
+ goto bye;
+ while (isspace((uchar) *p)) // skip leading space
+ p++;
+ if (*p == '+')
+ p++;
+ if (!isdigit((uchar) *p))
+ goto bye;
+ while (isdigit((uchar) *p)) {
+ if (val > max_mult || (val == max_mult && (*p-'0') > 5))
+ goto bye;
+ val = 10*val + (*p++ - '0');
+ }
+ while (isspace((uchar) *p)) // skip trailing space
+ p++;
+ if (*p == '\0')
+ is_ok = true;
+bye:
+ if (ok)
+ *ok = is_ok;
+ return is_ok ? val : 0;
+}
+
+/*!
+ Returns the string converted to a \c{short} value.
+
+ If \a ok is not 0: *\a ok is set to false if the string is not a
+ number, is out of range, or if it has trailing garbage; otherwise
+ *\a ok is set to true.
+*/
+
+short TQCString::toShort(bool *ok) const
+{
+ long v = toLong(ok);
+ if (ok && *ok && (v < -32768 || v > 32767))
+ *ok = false;
+ return (short)v;
+}
+
+/*!
+ Returns the string converted to an \c{unsigned short} value.
+
+ If \a ok is not 0: *\a ok is set to false if the string is not a
+ number, is out of range, or if it has trailing garbage; otherwise
+ *\a ok is set to true.
+*/
+
+ushort TQCString::toUShort(bool *ok) const
+{
+ ulong v = toULong(ok);
+ if (ok && *ok && (v > 65535))
+ *ok = false;
+ return (ushort)v;
+}
+
+
+/*!
+ Returns the string converted to a \c{int} value.
+
+ If \a ok is not 0: *\a ok is set to false if the string is not a
+ number, or if it has trailing garbage; otherwise *\a ok is set to
+ true.
+*/
+
+int TQCString::toInt(bool *ok) const
+{
+ return (int)toLong(ok);
+}
+
+/*!
+ Returns the string converted to an \c{unsigned int} value.
+
+ If \a ok is not 0: *\a ok is set to false if the string is not a
+ number, or if it has trailing garbage; otherwise *\a ok is set to
+ true.
+*/
+
+uint TQCString::toUInt(bool *ok) const
+{
+ return (uint)toULong(ok);
+}
+
+/*!
+ Returns the string converted to a \c{double} value.
+
+ If \a ok is not 0: *\a ok is set to false if the string is not a
+ number, or if it has trailing garbage; otherwise *\a ok is set to
+ true.
+*/
+
+double TQCString::toDouble(bool *ok) const
+{
+ char *end;
+ double val = strtod(constData() ? constData() : "", &end);
+ if (ok)
+ *ok = (constData() && *constData() && (end == 0 || *end == '\0'));
+ return val;
+}
+
+/*!
+ Returns the string converted to a \c{float} value.
+
+ If \a ok is not 0: *\a ok is set to false if the string is not a
+ number, or if it has trailing garbage; otherwise *\a ok is set to
+ true.
+*/
+
+float TQCString::toFloat(bool *ok) const
+{
+ return (float)toDouble(ok);
+}
+
+
+/*! \fn TQCString &TQCString::setStr(const char *str)
+ Makes a deep copy of \a str. Returns a reference to the string.
+*/
+
+/*!
+ \overload
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+TQCString &TQCString::setNum(long n)
+{
+ data();
+ char buf[20];
+ register char *p = &buf[19];
+ bool neg;
+ if (n < 0) {
+ neg = true;
+ n = -n;
+ } else {
+ neg = false;
+ }
+ *p = '\0';
+ do {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while (n);
+ if (neg)
+ *--p = '-';
+ *this = p;
+ return *this;
+}
+
+/*!
+ \overload
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+TQCString &TQCString::setNum(ulong n)
+{
+ data();
+ char buf[20];
+ register char *p = &buf[19];
+ *p = '\0';
+ do {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while (n);
+ *this = p;
+ return *this;
+}
+
+/*!
+ \fn TQCString &TQCString::setNum(int n)
+ \overload
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+/*!
+ \fn TQCString &TQCString::setNum(uint n)
+ \overload
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+/*!
+ \fn TQCString &TQCString::setNum(short n)
+ \overload
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+/*!
+ \fn TQCString &TQCString::setNum(ushort n)
+ \overload
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+/*!
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+
+ The format of the string representation is specified by the format
+ character \a f, and the precision (number of digits after the
+ decimal point) is specified with \a prec.
+
+ The valid formats for \a f are 'e', 'E', 'f', 'g' and 'G'. The
+ formats are the same as for sprintf(); they are explained in \l
+ QString::arg().
+*/
+
+TQCString &TQCString::setNum(double n, char f, int prec)
+{
+#ifndef QT_NO_DEBUG
+ if (!(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G'))
+ qWarning("TQCString::setNum: Invalid format char '%c'", f);
+#endif
+ char format[20];
+ register char *fs = format; // generate format string
+ *fs++ = '%'; // "%.<prec>l<f>"
+ if (prec > 99)
+ prec = 99;
+ *fs++ = '.';
+ if (prec >= 10) {
+ *fs++ = prec / 10 + '0';
+ *fs++ = prec % 10 + '0';
+ } else {
+ *fs++ = prec + '0';
+ }
+ *fs++ = 'l';
+ *fs++ = f;
+ *fs = '\0';
+ return sprintf(format, n);
+}
+
+/*! \fn TQCString &TQCString::setNum(float n, char f, int prec)
+ \overload
+*/
+
+/*!
+ Sets the character at position \a index to \a c and expands the
+ string if necessary, padding with spaces.
+
+ Returns false if \a index was out of range and the string could
+ not be expanded; otherwise returns true.
+*/
+
+bool TQCString::setExpand(uint index, char c)
+{
+ uint oldlen = length();
+ if (index >= oldlen) {
+ resize(index+1);
+ if (index > oldlen)
+ memset(data() + oldlen, ' ', index - oldlen);
+ }
+ *(data() + index) = c;
+ return true;
+}
+
+
+/*
+ \fn TQCString::operator const char *() const
+
+ Returns the string data.
+*/
+
+
+/*!
+ \fn TQCString& TQCString::append(const char *str)
+
+ Appends string \a str to the string and returns a reference to the
+ string. Equivalent to operator+=().
+*/
+
+#ifndef QT_NO_DATASTREAM
+/*! \fn QDataStream &operator<<(QDataStream &s, const TQCString &str)
+ \relates TQCString
+
+ Writes string \a str to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+QDataStream &operator<<(QDataStream &d, const TQCString &s)
+{
+printf("[WARNING] When using << on a QDataStream instead of a TQDataStream functionality may differ from Qt3\n\r");
+ if (d.version() >= QDataStream::Qt_4_0)
+ return operator<<(d, static_cast<const QByteArray &>(s));
+
+ // we need to add a NUL to keep compatibility with Qt 3's QByteArray
+ QByteArray copy = s;
+ copy.append('\0');
+ return operator<<(d, copy);
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &s, TQCString &str)
+ \relates TQCString
+
+ Reads a string into \a str from the stream \a s.
+
+ \sa \link datastreamformat.html Format of the QDataStream operators \endlink
+*/
+QDataStream &operator>>(QDataStream &d, TQCString &s) {
+printf("[WARNING] When using << on a QDataStream instead of a TQDataStream functionality may differ from Qt3\n\r");
+ operator>>(d, static_cast<QByteArray &>(s));
+ if (d.version() < QDataStream::Qt_4_0 && s.endsWith('\0'))
+ s.chop(1); // ending NUL
+ return d;
+}
+
+#if 0
+// I don't think this works...
+
+/*! \fn TQDataStream &operator<<(TQDataStream &s, const TQCString &str)
+ \relates TQCString
+
+ Writes string \a str to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+TQDataStream &operator<<(TQDataStream &d, const TQCString &s)
+{
+ if (d.version() >= QDataStream::Qt_4_0) {
+ QDataStream &qds = operator<<(static_cast<QDataStream &>(d), static_cast<const QByteArray &>(s));
+ TQDataStream &tqds = *static_cast<TQDataStream*>(&qds);
+ return tqds;
+ }
+
+ // we need to add a NUL to keep compatibility with Qt 3's QByteArray
+ QByteArray copy = s;
+ copy.append('\0');
+
+ QDataStream &qds = operator<<(static_cast<QDataStream &>(d), static_cast<const QByteArray &>(s));
+ TQDataStream &tqds = *static_cast<TQDataStream*>(&qds);
+ return tqds;
+}
+
+/*!
+ \fn TQDataStream &operator>>(TQDataStream &s, TQCString &str)
+ \relates TQCString
+
+ Reads a string into \a str from the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+TQDataStream &operator>>(TQDataStream &d, TQCString &s) {
+ operator>>(d, static_cast<QByteArray &>(s));
+ if (d.version() < QDataStream::Qt_4_0 && s.endsWith('\0'))
+ s.chop(1); // ending NUL
+ return d;
+}
+
+#endif
+
+#endif
+
+/*****************************************************************************
+ TQCString stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQCString
+
+ Writes string \a str to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+TQDataStream &operator<<( TQDataStream &s, const TQCString &str )
+{
+ return static_cast<TQDataStream &>(s.writeBytes( str.data(), str.size() ));
+}
+
+/*!
+ \relates TQCString
+
+ Reads a string into \a str from the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQCString &str )
+{
+ str.detach();
+ TQ_UINT32 len;
+ s >> len; // read size of string
+ if ( len == 0 || s.eof() ) { // end of file reached
+ str.resize( 0 );
+ return s;
+ }
+ if ( !str.TQByteArray::tqresize( (uint)len )) {// resize string
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQDataStream: Not enough memory to read TQCString" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // not null array
+ s.readRawBytes( str.data(), (uint)len );
+ return s;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*****************************************************************************
+ Documentation for related functions
+ *****************************************************************************/
+
+/*!
+ \fn bool operator==(const TQCString &s1, const TQCString &s2)
+
+ \relates TQCString
+
+ Returns true if \a s1 and \a s2 are equal; otherwise returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) == 0.
+*/
+
+/*!
+ \fn bool operator==(const TQCString &s1, const char *s2)
+ \overload
+
+ \relates TQCString
+
+ Returns true if \a s1 and \a s2 are equal; otherwise returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) == 0.
+*/
+
+/*!
+ \fn bool operator==(const char *s1, const TQCString &s2)
+ \overload
+
+ \relates TQCString
+
+ Returns true if \a s1 and \a s2 are equal; otherwise returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) == 0.
+*/
+
+/*!
+ \fn bool operator!=(const TQCString &s1, const TQCString &s2)
+
+ \relates TQCString
+
+ Returns true if \a s1 and \a s2 are different; otherwise returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) != 0.
+*/
+
+/*!
+ \fn bool operator!=(const TQCString &s1, const char *s2)
+ \overload
+
+ \relates TQCString
+
+ Returns true if \a s1 and \a s2 are different; otherwise returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) != 0.
+*/
+
+/*!
+ \fn bool operator!=(const char *s1, const TQCString &s2)
+ \overload
+
+ \relates TQCString
+
+ Returns true if \a s1 and \a s2 are different; otherwise returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) != 0.
+*/
+
+/*!
+ \fn bool operator<(const TQCString &s1, const char *s2)
+
+ \relates TQCString
+
+ Returns true if \a s1 is less than \a s2; otherwise returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \< 0.
+*/
+
+/*!
+ \fn bool operator<(const char *s1, const TQCString &s2)
+ \overload
+
+ \relates TQCString
+
+ Returns true if \a s1 is less than \a s2; otherwise returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \< 0.
+*/
+
+/*!
+ \fn bool operator<=(const TQCString &s1, const char *s2)
+
+ \relates TQCString
+
+ Returns true if \a s1 is less than or equal to \a s2; otherwise
+ returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \<= 0.
+*/
+
+/*!
+ \fn bool operator<=(const char *s1, const TQCString &s2)
+ \overload
+
+ \relates TQCString
+
+ Returns true if \a s1 is less than or equal to \a s2; otherwise
+ returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \<= 0.
+*/
+
+/*!
+ \fn bool operator>(const TQCString &s1, const char *s2)
+
+ \relates TQCString
+
+ Returns true if \a s1 is greater than \a s2; otherwise returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \> 0.
+*/
+
+/*!
+ \fn bool operator>(const char *s1, const TQCString &s2)
+ \overload
+
+ \relates TQCString
+
+ Returns true if \a s1 is greater than \a s2; otherwise returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \> 0.
+*/
+
+/*!
+ \fn bool operator>=(const TQCString &s1, const char *s2)
+
+ \relates TQCString
+
+ Returns true if \a s1 is greater than or equal to \a s2; otherwise
+ returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \>= 0.
+*/
+
+/*!
+ \fn bool operator>=(const char *s1, const TQCString &s2)
+ \overload
+
+ \relates TQCString
+
+ Returns true if \a s1 is greater than or equal to \a s2; otherwise
+ returns false.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \>= 0.
+*/
+
+/*!
+ \fn const TQCString operator+(const TQCString &s1, const TQCString &s2)
+
+ \relates TQCString
+
+ Returns a string which consists of the concatenation of \a s1 and
+ \a s2.
+*/
+
+/*!
+ \fn const TQCString operator+(const TQCString &s1, const char *s2)
+ \overload
+
+ \relates TQCString
+
+ Returns a string which consists of the concatenation of \a s1 and \a s2.
+*/
+
+/*!
+ \fn const TQCString operator+(const char *s1, const TQCString &s2)
+ \overload
+
+ \relates TQCString
+
+ Returns a string which consists of the concatenation of \a s1 and \a s2.
+*/
+
+/*!
+ \fn const TQCString operator+(const TQCString &s, char c)
+ \overload
+
+ \relates TQCString
+
+ Returns a string which consists of the concatenation of \a s and \a c.
+*/
+
+/*!
+ \fn const TQCString operator+(char c, const TQCString &s)
+ \overload
+
+ \relates TQCString
+ Returns a string which consists of the concatenation of \a c and \a s.
+*/
+
+/*!
+ Returns the number of times the character \a c occurs in the
+ string.
+
+ The match is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs if FALSE.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+int TQCString::tqcontains( char c, bool cs ) const
+{
+ int count = 0;
+ const char *d = data();
+ if ( !d )
+ return 0;
+ if ( cs ) { // case sensitive
+ while ( *d )
+ if ( *d++ == c )
+ count++;
+ } else { // case insensitive
+ c = tolower( (uchar) c );
+ while ( *d ) {
+ if ( tolower((uchar) *d) == c )
+ count++;
+ d++;
+ }
+ }
+ return count;
+}
+
+/*!
+ \overload
+
+ Counts the number of overlapping occurrences of \a rx in the string.
+
+ Example:
+ \code
+ TQString s = "banana and panama";
+ TQRegExp r = TQRegExp( "a[nm]a", TRUE, FALSE );
+ s.tqcontains( r ); // 4 matches
+ \endcode
+
+ \sa tqfind(), tqfindRev()
+
+ \warning If you want to apply this function repeatedly to the same
+ string it is more efficient to convert the string to a TQString and
+ apply the function to that.
+*/
+
+int TQCString::tqcontains( const QRegExp &rx ) const
+{
+ TQString d = TQString::fromAscii( data() );
+ return d.tqcontains( rx );
+}
+
+/*!
+ \overload
+
+ Returns the number of times \a str occurs in the string.
+
+ The match is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs if FALSE.
+
+ This function counts overlapping substrings, for example, "banana"
+ tqcontains two occurrences of "ana".
+
+ \sa tqfindRev()
+ \link #asciinotion Note on character comparisons \endlink
+*/
+
+int TQCString::tqcontains( const char *str, bool cs ) const
+{
+ int count = 0;
+ int i = -1;
+ uint l = length();
+ // use tqfind for the faster hashing algorithm
+ while ( ( i = tqfind ( str, i+1, cs, l ) ) != -1 )
+ count++;
+ return count;
+}
+
+#define REHASH( a ) \
+ if ( sl_minus_1 < sizeof(uint) * CHAR_BIT ) \
+ hashHaystack -= (a) << sl_minus_1; \
+ hashHaystack <<= 1
+
+/*!
+ Finds the first occurrence of the character \a c, starting at
+ position \a index.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs is FALSE.
+
+ Returns the position of \a c, or -1 if \a c could not be found.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+int TQCString::tqfind( char c, int index, bool cs ) const
+{
+ if ( (uint)index >= size() ) // index outside string
+ return -1;
+ register const char *d;
+ if ( cs ) { // case sensitive
+ d = strchr( data()+index, c );
+ } else {
+ d = data()+index;
+ c = tolower( (uchar) c );
+ while ( *d && tolower((uchar) *d) != c )
+ d++;
+ if ( !*d && c ) // not found
+ d = 0;
+ }
+ return d ? (int)(d - data()) : -1;
+}
+
+/*!
+ \overload
+
+ Finds the first occurrence of the string \a str, starting at
+ position \a index.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs is FALSE.
+
+ Returns the position of \a str, or -1 if \a str could not be
+ found.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+int TQCString::tqfind( const char *str, int index, bool cs ) const
+{
+ return tqfind( str, index, cs, length() );
+}
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+/*!
+ \overload
+
+ Finds the first occurrence of the regular expression \a rx,
+ starting at position \a index.
+
+ Returns the position of the next match, or -1 if \a rx was not
+ found.
+
+ \warning If you want to apply this function repeatedly to the same
+ string it is more efficient to convert the string to a TQString and
+ apply the function to that.
+*/
+
+int TQCString::tqfind( const QRegExp& rx, int index ) const
+{
+ TQString d = TQString::fromAscii( data() );
+ return d.tqfind( rx, index );
+}
+#endif // TQT_NO_REGEXP_CAPTURE
+
+int TQCString::tqfind( const char *str, int index, bool cs, uint l ) const
+{
+ if ( (uint)index >= size() )
+ return -1;
+ if ( !str )
+ return -1;
+ if ( !*str )
+ return index;
+ const uint sl = tqstrlen( str );
+ if ( sl + index > l )
+ return -1;
+
+ if ( sl == 1 )
+ return tqfind( *str, index, cs );
+
+ /*
+ See TQString::tqfind() for details.
+ */
+ const char* needle = str;
+ const char* haystack = data() + index;
+ const char* end = data() + (l-sl);
+ const uint sl_minus_1 = sl-1;
+ uint hashNeedle = 0, hashHaystack = 0,i;
+
+ if ( cs ) {
+ for ( i = 0; i < sl; ++i ) {
+ hashNeedle = ((hashNeedle<<1) + needle[i] );
+ hashHaystack = ((hashHaystack<<1) + haystack[i] );
+ }
+ hashHaystack -= *(haystack+sl_minus_1);
+
+ while ( haystack <= end ) {
+ hashHaystack += *(haystack+sl_minus_1);
+ if ( hashHaystack == hashNeedle && *needle == *haystack
+ && tqstrncmp( needle, haystack, sl ) == 0 )
+ return haystack - data();
+
+ REHASH( *haystack );
+ ++haystack;
+ }
+ } else {
+ for ( i = 0; i < sl; ++i ) {
+ hashNeedle = ((hashNeedle<<1) +
+ tolower( needle[i] ) );
+ hashHaystack = ((hashHaystack<<1) +
+ tolower( haystack[i] ) );
+ }
+ hashHaystack -= tolower(*(haystack+sl_minus_1));
+
+ while ( haystack <= end ) {
+ hashHaystack += tolower(*(haystack+sl_minus_1));
+ if ( hashHaystack == hashNeedle
+ && qstrnicmp( needle, haystack, sl ) == 0 )
+ return haystack - data();
+
+ REHASH( tolower(*haystack) );
+ ++haystack;
+ }
+ }
+ return -1;
+}
+
+#ifndef TQT_NO_REGEXP
+/*!
+ \overload
+
+ Replaces every occurrence of \a rx in the string with \a str.
+ Returns a reference to the string.
+
+ Example:
+ \code
+ TQString s = "banana";
+ s.tqreplace( TQRegExp("a.*a"), "" ); // becomes "b"
+
+ s = "banana";
+ s.tqreplace( TQRegExp("^[bn]a"), "X" ); // becomes "Xnana"
+
+ s = "banana";
+ s.tqreplace( TQRegExp("^[bn]a"), "" ); // becomes "nana"
+ \endcode
+
+ \warning If you want to apply this function repeatedly to the same
+ string it is more efficient to convert the string to a TQString and
+ apply the function to that.
+*/
+
+TQCString &TQCString::tqreplace( const QRegExp &rx, const char *str )
+{
+ TQString d = TQString::fromAscii( data() );
+ TQString r = TQString::fromAscii( str );
+ d.tqreplace( rx, r );
+ setStr( d.ascii() );
+ return *this;
+}
+#endif //TQT_NO_REGEXP
+
+/*!
+ Appends string \a str to the string and returns a reference to the string.
+*/
+
+TQCString& TQCString::operator+=( const char *str )
+{
+// if ( !str )
+// return *this; // nothing to append
+// detach();
+// uint len1 = length();
+// uint len2 = tqstrlen(str);
+// if ( !TQByteArray::tqresize( len1 + len2 + 1 ) )
+// return *this; // no memory
+// memcpy( data() + len1, str, len2 + 1 );
+// return *this;
+
+ uint len2 = tqstrlen(QByteArray::constData());
+ QByteArray::tqresize(len2); // Get rid of the old null terminator
+ QByteArray::append(str);
+ return *this;
+}
+
+/*!
+ \overload
+
+ Appends character \a c to the string and returns a reference to the string.
+*/
+
+TQCString &TQCString::operator+=( char c )
+{
+// detach();
+// uint len = length();
+// if ( !TQByteArray::tqresize( len + 2 ) )
+// return *this; // no memory
+// *(data() + len) = c;
+// *(data() + len+1) = '\0';
+// return *this;
+
+ uint len2 = tqstrlen(QByteArray::constData());
+ QByteArray::tqresize(len2); // Get rid of the old null terminator
+ QByteArray::append(c);
+ return *this;
+}
+
+TQCString& TQCString::operator+=( const QString qs )
+{
+ uint len2 = tqstrlen(QByteArray::constData());
+ QByteArray::tqresize(len2); // Get rid of the old null terminator
+ QByteArray tmp = qs.toAscii();
+ return append(tmp);
+}
+
+TQCString& TQCString::operator+=( const QByteArray qba )
+{
+ uint len2 = tqstrlen(QByteArray::constData());
+ QByteArray::tqresize(len2); // Get rid of the old null terminator
+ return append(qba);
+}
+
+TQCString& TQCString::operator+=( const TQCString tqcs ) {
+ return operator+=(tqcs.constData());
+}
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/*!
+ \class TQCString tqcstring.h
+ \reentrant
+ \brief The TQCString class provides an abstraction of the classic C
+ zero-terminated char array (char *).
+
+ \ingroup text
+ \ingroup collection
+ \ingroup tools
+ \ingroup shared
+
+ TQCString inherits TQByteArray, which is defined as
+ TQMemArray\<char\>. Since TQCString is a TQMemArray, it uses \link
+ shclass.html explicit sharing\endlink with a reference count.
+
+ TQCString tries to behave like a more convenient \c{const char *}.
+ The price of doing this is that some algorithms will perform
+ badly. For example, append() is O(length()) since it scans for a
+ null terminator. Although you might use TQCString for text that is
+ never exposed to the user, for most purposes, and especially for
+ user-visible text, you should use TQString. TQString provides
+ implicit sharing, Unicode and other internationalization support,
+ and is well optimized.
+
+ Note that for the TQCString methods that take a \c{const char *}
+ parameter the \c{const char *} must either be 0 (null) or not-null
+ and '\0' (NUL byte) terminated; otherwise the results are
+ undefined.
+
+ A TQCString that has not been assigned to anything is \e null, i.e.
+ both the length and the data pointer is 0. A TQCString that
+ references the empty string ("", a single '\0' char) is \e empty.
+ Both null and empty TQCStrings are legal parameters to the methods.
+ Assigning \c{const char *} 0 to TQCString produces a null TQCString.
+
+ The length() function returns the length of the string; resize()
+ resizes the string and truncate() truncates the string. A string
+ can be filled with a character using fill(). Strings can be left
+ or right padded with characters using leftJustify() and
+ rightJustify(). Characters, strings and regular expressions can be
+ searched for using tqfind() and tqfindRev(), and counted using
+ tqcontains().
+
+ Strings and characters can be inserted with insert() and appended
+ with append(). A string can be prepended with prepend().
+ Characters can be removed from the string with remove() and
+ tqreplaced with tqreplace().
+
+ Portions of a string can be extracted using left(), right() and
+ mid(). Whitespace can be removed using stripWhiteSpace() and
+ simplifyWhiteSpace(). Strings can be converted to uppercase or
+ lowercase with upper() and lower() respectively.
+
+ Strings that contain numbers can be converted to numbers with
+ toShort(), toInt(), toLong(), toULong(), toFloat() and toDouble().
+ Numbers can be converted to strings with setNum().
+
+ Many operators are overloaded to work with TQCStrings. TQCString
+ also supports some more obscure functions, e.g. sprintf(),
+ setStr() and setExpand().
+
+ \target asciinotion
+ \sidebar Note on Character Comparisons
+
+ In TQCString the notion of uppercase and lowercase and of which
+ character is greater than or less than another character is locale
+ dependent. This affects functions which support a case insensitive
+ option or which compare or lowercase or uppercase their arguments.
+ Case insensitive operations and comparisons will be accurate if
+ both strings contain only ASCII characters. (If \c $LC_CTYPE is
+ set, most Unix systems do "the right thing".) Functions that this
+ affects include tqcontains(), tqfind(), tqfindRev(), \l operator<(), \l
+ operator<=(), \l operator>(), \l operator>=(), lower() and
+ upper().
+
+ This issue does not apply to \l{TQString}s since they represent
+ characters using Unicode.
+ \endsidebar
+
+ Performance note: The TQCString methods for TQRegExp searching are
+ implemented by converting the TQCString to a TQString and performing
+ the search on that. This implies a deep copy of the TQCString data.
+ If you are going to perform many TQRegExp searches on a large
+ TQCString, you will get better performance by converting the
+ TQCString to a TQString yourself, and then searching in the TQString.
+*/
+
+/*!
+ \fn TQCString::TQCString()
+
+ Constructs a null string.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn TQCString::TQCString( const TQCString &s )
+
+ Constructs a shallow copy \a s.
+
+ \sa assign()
+*/
+
+/*!
+ Constructs a string with room for \a size characters, including
+ the '\0'-terminator. Makes a null string if \a size == 0.
+
+ If \a size \> 0, then the first and last characters in the string
+ are initialized to '\0'. All other characters are uninitialized.
+
+ \sa resize(), isNull()
+*/
+
+TQCString::TQCString( int size )
+ : TQByteArray( size )
+{
+ if ( size > 0 ) {
+ *data() = '\0'; // set terminator
+ *(data()+(size-1)) = '\0';
+ }
+}
+
+/*!
+ Constructs a string that is a deep copy of \a str.
+
+ If \a str is 0 a null string is created.
+
+ \sa isNull()
+*/
+
+TQCString::TQCString( const char *str )
+{
+ duplicate( str, tqstrlen(str) + 1 );
+}
+
+
+/*!
+ Constructs a string that is a deep copy of \a str. The copy will
+ be at most \a maxsize bytes long including the '\0'-terminator.
+
+ Example:
+ \code
+ TQCString str( "helloworld", 6 ); // assigns "hello" to str
+ \endcode
+
+ If \a str tqcontains a 0 byte within the first \a maxsize bytes, the
+ resulting TQCString will be terminated by this 0. If \a str is 0 a
+ null string is created.
+
+ \sa isNull()
+*/
+
+TQCString::TQCString( const char *str, uint maxsize )
+{
+ if ( str == 0 )
+ return;
+ uint len; // index of first '\0'
+ for ( len = 0; len < maxsize - 1; len++ ) {
+ if ( str[len] == '\0' )
+ break;
+ }
+ TQByteArray::tqresize( len + 1 );
+ memcpy( data(), str, len );
+ data()[len] = 0;
+}
+
+/*!
+ \reimp
+*/
+
+TQCString::~TQCString()
+{
+}
+
+TQCString &TQCString::operator=(const QByteArray &ba) {
+ TQByteArray::operator=(ba);
+ return *this;
+}
+
+/*!
+ \fn TQCString &TQCString::operator=( const TQCString &s )
+
+ Assigns a shallow copy of \a s to this string and returns a
+ reference to this string.
+*/
+
+/*!
+ \overload TQCString &TQCString::operator=( const char *str )
+
+ Assigns a deep copy of \a str to this string and returns a
+ reference to this string.
+
+ If \a str is 0 a null string is created.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn bool TQCString::isNull() const
+
+ Returns TRUE if the string is null, i.e. if data() == 0; otherwise
+ returns FALSE. A null string is also an empty string.
+
+ Example:
+ \code
+ TQCString a; // a.data() == 0, a.size() == 0, a.length() == 0
+ TQCString b == ""; // b.data() == "", b.size() == 1, b.length() == 0
+ a.isNull(); // TRUE because a.data() == 0
+ a.isEmpty(); // TRUE because a.length() == 0
+ b.isNull(); // FALSE because b.data() == ""
+ b.isEmpty(); // TRUE because b.length() == 0
+ \endcode
+
+ \sa isEmpty(), length(), size()
+*/
+
+/*!
+ \fn bool TQCString::isEmpty() const
+
+ Returns TRUE if the string is empty, i.e. if length() == 0;
+ otherwise returns FALSE. An empty string is not always a null
+ string.
+
+ See example in isNull().
+
+ \sa isNull(), length(), size()
+*/
+
+/*!
+ \fn uint TQCString::length() const
+
+ Returns the length of the string, excluding the '\0'-terminator.
+ Equivalent to calling \c strlen(data()).
+
+ Null strings and empty strings have zero length.
+
+ \sa size(), isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool TQCString::truncate( uint pos )
+
+ Truncates the string at position \a pos.
+
+ Equivalent to calling \c resize(pos+1).
+
+ Example:
+ \code
+ TQCString s = "truncate this string";
+ s.truncate( 5 ); // s == "trunc"
+ \endcode
+
+ \sa resize()
+*/
+
+/*!
+ Extends or shrinks the string to \a len bytes, including the
+ '\0'-terminator.
+
+ A '\0'-terminator is set at position \c{len - 1} unless
+ \c{len == 0}.
+
+ Example:
+ \code
+ TQCString s = "resize this string";
+ s.resize( 7 ); // s == "resize"
+ \endcode
+
+ \sa truncate()
+*/
+
+bool TQCString::tqresize( uint len )
+{
+ detach();
+ uint wasNull = isNull();
+ if ( !TQByteArray::tqresize(len) )
+ return FALSE;
+ if ( len )
+ data()[len - 1] = '\0';
+ if ( len > 0 && wasNull )
+ data()[0] = '\0';
+ return TRUE;
+}
+
+
+/*!
+ Implemented as a call to the native vsprintf() (see the manual for
+ your C library).
+
+ If the string is shorter than 256 characters, this sprintf() calls
+ resize(256) to decrease the chance of memory corruption. The
+ string is resized back to its actual length before sprintf()
+ returns.
+
+ Example:
+ \code
+ TQCString s;
+ s.sprintf( "%d - %s", 1, "first" ); // result < 256 chars
+
+ TQCString big( 25000 ); // very long string
+ big.sprintf( "%d - %s", 2, longString ); // result < 25000 chars
+ \endcode
+
+ \warning All vsprintf() implementations will write past the end of
+ the target string (*this) if the \a format specification and
+ arguments happen to be longer than the target string, and some
+ will also fail if the target string is longer than some arbitrary
+ implementation limit.
+
+ Giving user-supplied arguments to sprintf() is risky: Sooner or
+ later someone will paste a huge line into your application.
+*/
+
+TQCString &TQCString::sprintf( const char *format, ... )
+{
+ detach();
+ va_list ap;
+ va_start( ap, format );
+ if ( size() < 256 )
+ TQByteArray::tqresize( 256 ); // make string big enough
+#ifdef TQT_VSNPRINTF
+ TQT_VSNPRINTF( data(), size(), format, ap );
+#else
+ vsprintf( data(), format, ap );
+#endif
+ resize( tqstrlen(data()) + 1 ); // truncate
+ va_end( ap );
+ return *this;
+}
+
+
+/*!
+ Fills the string with \a len bytes of character \a c, followed by
+ a '\0'-terminator.
+
+ If \a len is negative, then the current string length is used.
+
+ Returns FALSE is \a len is nonnegative and there is not enough
+ memory to resize the string; otherwise returns TRUE.
+*/
+
+bool TQCString::fill( char c, int len )
+{
+ detach();
+ if ( len < 0 )
+ len = length();
+ if ( !TQByteArray::fill(c,len+1) )
+ return FALSE;
+ *(data()+len) = '\0';
+ return TRUE;
+}
+
+
+/*!
+ \fn TQCString TQCString::copy() const
+
+ Returns a deep copy of this string.
+
+ \sa detach()
+*/
+
+
+/*!
+ Finds the first occurrence of the character \a c, starting at
+ position \a index.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs is FALSE.
+
+ Returns the position of \a c, or -1 if \a c could not be found.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+int TQCString::tqfind( char c, int index, bool cs ) const
+{
+ if ( (uint)index >= size() ) // index outside string
+ return -1;
+ register const char *d;
+ if ( cs ) { // case sensitive
+ d = strchr( data()+index, c );
+ } else {
+ d = data()+index;
+ c = tolower( (uchar) c );
+ while ( *d && tolower((uchar) *d) != c )
+ d++;
+ if ( !*d && c ) // not found
+ d = 0;
+ }
+ return d ? (int)(d - data()) : -1;
+}
+
+#define REHASH( a ) \
+ if ( sl_minus_1 < sizeof(uint) * CHAR_BIT ) \
+ hashHaystack -= (a) << sl_minus_1; \
+ hashHaystack <<= 1
+
+/*!
+ \overload
+
+ Finds the first occurrence of the string \a str, starting at
+ position \a index.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs is FALSE.
+
+ Returns the position of \a str, or -1 if \a str could not be
+ found.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+int TQCString::tqfind( const char *str, int index, bool cs ) const
+{
+ return tqfind( str, index, cs, length() );
+}
+
+int TQCString::tqfind( const char *str, int index, bool cs, uint l ) const
+{
+ if ( (uint)index >= size() )
+ return -1;
+ if ( !str )
+ return -1;
+ if ( !*str )
+ return index;
+ const uint sl = tqstrlen( str );
+ if ( sl + index > l )
+ return -1;
+
+ if ( sl == 1 )
+ return tqfind( *str, index, cs );
+
+ /*
+ See TQString::tqfind() for details.
+ */
+ const char* needle = str;
+ const char* haystack = data() + index;
+ const char* end = data() + (l-sl);
+ const uint sl_minus_1 = sl-1;
+ uint hashNeedle = 0, hashHaystack = 0,i;
+
+ if ( cs ) {
+ for ( i = 0; i < sl; ++i ) {
+ hashNeedle = ((hashNeedle<<1) + needle[i] );
+ hashHaystack = ((hashHaystack<<1) + haystack[i] );
+ }
+ hashHaystack -= *(haystack+sl_minus_1);
+
+ while ( haystack <= end ) {
+ hashHaystack += *(haystack+sl_minus_1);
+ if ( hashHaystack == hashNeedle && *needle == *haystack
+ && tqstrncmp( needle, haystack, sl ) == 0 )
+ return haystack - data();
+
+ REHASH( *haystack );
+ ++haystack;
+ }
+ } else {
+ for ( i = 0; i < sl; ++i ) {
+ hashNeedle = ((hashNeedle<<1) +
+ tolower( needle[i] ) );
+ hashHaystack = ((hashHaystack<<1) +
+ tolower( haystack[i] ) );
+ }
+ hashHaystack -= tolower(*(haystack+sl_minus_1));
+
+ while ( haystack <= end ) {
+ hashHaystack += tolower(*(haystack+sl_minus_1));
+ if ( hashHaystack == hashNeedle
+ && qstrnicmp( needle, haystack, sl ) == 0 )
+ return haystack - data();
+
+ REHASH( tolower(*haystack) );
+ ++haystack;
+ }
+ }
+ return -1;
+}
+
+
+/*!
+ Finds the first occurrence of the character \a c, starting at
+ position \a index and searching backwards.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs is FALSE.
+
+ Returns the position of \a c, or -1 if \a c could not be found.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+int TQCString::tqfindRev( char c, int index, bool cs ) const
+{
+ register const char *b = data();
+ register const char *d;
+ if ( index < 0 )
+ index = length();
+ if ( (uint)index >= size() )
+ return -1;
+ d = b + index;
+ if ( cs ) {
+ while ( d >= b && *d != c )
+ d--;
+ } else {
+ c = tolower( (uchar) c );
+ while ( d >= b && tolower((uchar) *d) != c )
+ d--;
+ }
+ return d >= b ? (int)(d - b) : -1;
+}
+
+/*!
+ \overload
+
+ Finds the first occurrence of the string \a str, starting at
+ position \a index and searching backwards.
+
+ The search is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs is FALSE.
+
+ Returns the position of \a str, or -1 if \a str could not be
+ found.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+int TQCString::tqfindRev( const char *str, int index, bool cs ) const
+{
+ /*
+ See TQString::tqfind() for explanations.
+ */
+ const uint sl = tqstrlen( str );
+ const uint l = length();
+ int delta = l-sl;
+ if ( index < 0 )
+ index = delta;
+ if ( index < 0 || index > (int)l )
+ return -1;
+ if ( index > delta )
+ index = delta;
+
+ if ( sl == 1 )
+ return tqfindRev( *str, index, cs );
+
+ const char* needle = str;
+ const char* haystack = data() + index;
+ const char* end = data();
+ const uint sl_minus_1 = sl-1;
+ const char* n = needle+sl_minus_1;
+ const char* h = haystack+sl_minus_1;
+ uint hashNeedle = 0, hashHaystack = 0, i;
+
+ if ( cs ) {
+ for ( i = 0; i < sl; ++i ) {
+ hashNeedle = ((hashNeedle<<1) + *(n-i) );
+ hashHaystack = ((hashHaystack<<1) + *(h-i) );
+ }
+ hashHaystack -= *haystack;
+ while ( haystack >= end ) {
+ hashHaystack += *haystack;
+ if ( hashHaystack == hashNeedle && tqstrncmp( needle, haystack, sl ) == 0 )
+ return haystack-data();
+ --haystack;
+ REHASH( *(haystack+sl) );
+ }
+ } else {
+ for ( i = 0; i < sl; ++i ) {
+ hashNeedle = ((hashNeedle<<1) + tolower( *(n-i) ) );
+ hashHaystack = ((hashHaystack<<1) + tolower( *(h-i) ) );
+ }
+ hashHaystack -= tolower(*haystack);
+ while ( haystack >= end ) {
+ hashHaystack += tolower(*haystack);
+ if ( hashHaystack == hashNeedle && qstrnicmp( needle, haystack, sl ) == 0 )
+ return haystack-data();
+ --haystack;
+ REHASH( tolower(*(haystack+sl)) );
+ }
+ }
+ return -1;
+}
+
+
+/*!
+ Returns the number of times the character \a c occurs in the
+ string.
+
+ The match is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs if FALSE.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+int TQCString::tqcontains( char c, bool cs ) const
+{
+ int count = 0;
+ const char *d = data();
+ if ( !d )
+ return 0;
+ if ( cs ) { // case sensitive
+ while ( *d )
+ if ( *d++ == c )
+ count++;
+ } else { // case insensitive
+ c = tolower( (uchar) c );
+ while ( *d ) {
+ if ( tolower((uchar) *d) == c )
+ count++;
+ d++;
+ }
+ }
+ return count;
+}
+
+/*!
+ \overload
+
+ Returns the number of times \a str occurs in the string.
+
+ The match is case sensitive if \a cs is TRUE, or case insensitive
+ if \a cs if FALSE.
+
+ This function counts overlapping substrings, for example, "banana"
+ tqcontains two occurrences of "ana".
+
+ \sa tqfindRev()
+ \link #asciinotion Note on character comparisons \endlink
+*/
+
+int TQCString::tqcontains( const char *str, bool cs ) const
+{
+ int count = 0;
+ int i = -1;
+ uint l = length();
+ // use tqfind for the faster hashing algorithm
+ while ( ( i = tqfind ( str, i+1, cs, l ) ) != -1 )
+ count++;
+ return count;
+}
+
+/*!
+ Returns a substring that tqcontains the \a len leftmost characters
+ of the string.
+
+ The whole string is returned if \a len exceeds the length of the
+ string.
+
+ Example:
+ \code
+ TQCString s = "Pineapple";
+ TQCString t = s.left( 4 ); // t == "Pine"
+ \endcode
+
+ \sa right(), mid()
+*/
+TQCString TQCString::left( uint len ) const
+{
+ if ( isEmpty() ) {
+ TQCString empty;
+ return empty;
+ } else if ( len >= size() ) {
+ TQCString same( data() );
+ return same;
+ } else {
+ TQCString s( len+1 );
+ strncpy( s.data(), data(), len );
+ *(s.data()+len) = '\0';
+ return s;
+ }
+}
+
+/*!
+ Returns a substring that tqcontains the \a len rightmost characters
+ of the string.
+
+ The whole string is returned if \a len exceeds the length of the
+ string.
+
+ Example:
+ \code
+ TQCString s = "Pineapple";
+ TQCString t = s.right( 5 ); // t == "apple"
+ \endcode
+
+ \sa left(), mid()
+*/
+
+TQCString TQCString::right( uint len ) const
+{
+ if ( isEmpty() ) {
+ TQCString empty;
+ return empty;
+ } else {
+ uint l = length();
+ if ( len > l )
+ len = l;
+ char *p = const_cast<char*>(data()) + (l - len);
+ return TQCString( p );
+ }
+}
+
+/*!
+ Returns a substring that tqcontains at most \a len characters from
+ this string, starting at position \a index.
+
+ Returns a null string if the string is empty or if \a index is out
+ of range. Returns the whole string from \a index if \a index+len
+ exceeds the length of the string.
+
+ Example:
+ \code
+ TQCString s = "Two pineapples";
+ TQCString t = s.mid( 4, 3 ); // t == "pin"
+ \endcode
+
+ \sa left(), right()
+*/
+
+TQCString TQCString::mid( uint index, uint len ) const
+{
+ uint slen = tqstrlen( data() );
+ if ( isEmpty() || index >= slen ) {
+ TQCString empty;
+ return empty;
+ } else {
+ if ( len > slen-index )
+ len = slen - index;
+ register char *p = const_cast<char*>(data())+index;
+ TQCString s( len+1 );
+ strncpy( s.data(), p, len );
+ *(s.data()+len) = '\0';
+ return s;
+ }
+}
+
+/*!
+ Returns a string of length \a width (plus one for the terminating
+ '\0') that tqcontains this string padded with the \a fill character.
+
+ If the length of the string exceeds \a width and \a truncate is
+ FALSE (the default), then the returned string is a copy of the
+ string. If the length of the string exceeds \a width and \a
+ truncate is TRUE, then the returned string is a left(\a width).
+
+ Example:
+ \code
+ TQCString s("apple");
+ TQCString t = s.leftJustify(8, '.'); // t == "apple..."
+ \endcode
+
+ \sa rightJustify()
+*/
+
+TQCString TQCString::leftJustify( uint width, char fill, bool truncate ) const
+{
+ TQCString result;
+ int len = tqstrlen(data());
+ int padlen = width - len;
+ if ( padlen > 0 ) {
+ result.TQByteArray::tqresize( len+padlen+1 );
+ memcpy( result.data(), data(), len );
+ memset( result.data()+len, fill, padlen );
+ result[len+padlen] = '\0';
+ } else {
+ if ( truncate )
+ result = left( width );
+ else
+ result = copy();
+ }
+ return result;
+}
+
+/*!
+ Returns a string of length \a width (plus one for the terminating
+ '\0') that tqcontains zero or more of the \a fill character followed
+ by this string.
+
+ If the length of the string exceeds \a width and \a truncate is
+ FALSE (the default), then the returned string is a copy of the
+ string. If the length of the string exceeds \a width and \a
+ truncate is TRUE, then the returned string is a left(\a width).
+
+ Example:
+ \code
+ TQCString s("pie");
+ TQCString t = s.rightJustify(8, '.'); // t == ".....pie"
+ \endcode
+
+ \sa leftJustify()
+*/
+
+TQCString TQCString::rightJustify( uint width, char fill, bool truncate ) const
+{
+ TQCString result;
+ int len = tqstrlen(data());
+ int padlen = width - len;
+ if ( padlen > 0 ) {
+ result.TQByteArray::tqresize( len+padlen+1 );
+ memset( result.data(), fill, padlen );
+ memcpy( result.data()+padlen, data(), len );
+ result[len+padlen] = '\0';
+ } else {
+ if ( truncate )
+ result = left( width );
+ else
+ result = copy();
+ }
+ return result;
+}
+
+/*!
+ Returns a new string that is a copy of this string converted to lower
+ case.
+
+ Example:
+ \code
+ TQCString s("Credit");
+ TQCString t = s.lower(); // t == "credit"
+ \endcode
+
+ \sa upper()
+ \link #asciinotion Note on character comparisons \endlink
+*/
+
+TQCString TQCString::lower() const
+{
+ TQCString s( data() );
+ register char *p = s.data();
+ if ( p ) {
+ while ( *p ) {
+ *p = tolower( (uchar) *p );
+ p++;
+ }
+ }
+ return s;
+}
+
+/*!
+ Returns a new string that is a copy of this string converted to upper case.
+
+ Example:
+ \code
+ TQCString s( "Debit" );
+ TQCString t = s.upper(); // t == "DEBIT"
+ \endcode
+
+ \sa lower()
+ \link #asciinotion Note on character comparisons \endlink
+*/
+
+TQCString TQCString::upper() const
+{
+ TQCString s( data() );
+ register char *p = s.data();
+ if ( p ) {
+ while ( *p ) {
+ *p = toupper(*p);
+ p++;
+ }
+ }
+ return s;
+}
+
+
+/*!
+ Returns a new string that has white space removed from the start
+ and the end.
+
+ White space means the decimal ASCII codes 9, 10, 11, 12, 13 and
+ 32.
+
+ Example:
+ \code
+ TQCString s = " space ";
+ TQCString t = s.stripWhiteSpace(); // t == "space"
+ \endcode
+
+ \sa simplifyWhiteSpace()
+*/
+
+TQCString TQCString::stripWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return copy();
+
+ register char *s = const_cast<char*>(data());
+ TQCString result = s;
+ int reslen = result.length();
+ if ( !isspace((uchar) s[0]) && !isspace((uchar) s[reslen-1]) )
+ return result; // returns a copy
+
+ s = result.data();
+ int start = 0;
+ int end = reslen - 1;
+ while ( isspace((uchar) s[start]) ) // skip white space from start
+ start++;
+ if ( s[start] == '\0' ) { // only white space
+ result.resize( 1 );
+ return result;
+ }
+ while ( end && isspace((uchar) s[end]) ) // skip white space from end
+ end--;
+ end -= start - 1;
+ memmove( result.data(), &s[start], end );
+ result.resize( end + 1 );
+ return result;
+}
+
+
+/*!
+ Returns a new string that has white space removed from the start
+ and the end, plus any sequence of internal white space tqreplaced
+ with a single space (ASCII 32).
+
+ White space means the decimal ASCII codes 9, 10, 11, 12, 13 and
+ 32.
+
+ \code
+ TQCString s = " lots\t of\nwhite space ";
+ TQCString t = s.simplifyWhiteSpace(); // t == "lots of white space"
+ \endcode
+
+ \sa stripWhiteSpace()
+*/
+
+TQCString TQCString::simplifyWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return copy();
+ TQCString result( size() );
+ char *from = const_cast<char*>(data());
+ char *to = result.data();
+ char *first = to;
+ for ( ;; ) {
+ while ( isspace((uchar) *from) )
+ from++;
+ while ( *from && !isspace((uchar) *from) )
+ *to++ = *from++;
+ if ( *from )
+ *to++ = 0x20; // ' '
+ else
+ break;
+ }
+ if ( to > first && *(to-1) == 0x20 )
+ to--;
+ *to = '\0';
+ result.resize( (int)(to - result.data()) + 1 );
+ return result;
+}
+
+
+/*!
+ \overload
+
+ Inserts string \a s into the string at position \a index.
+
+ If \a index is beyond the end of the string, the string is
+ padded with spaces (ASCII 32) to length \a index and then \a s
+ is appended.
+
+ \code
+ TQCString s = "I like fish";
+ s.insert( 2, "don't "); // s == "I don't like fish"
+
+ s = "x"; // index 01234
+ s.insert( 3, "yz" ); // s == "x yz"
+ \endcode
+*/
+
+TQCString &TQCString::insert( uint index, const char *s )
+{
+ int len = tqstrlen(s);
+ if ( len == 0 )
+ return *this;
+ uint olen = length();
+ int nlen = olen + len;
+ if ( index >= olen ) { // insert after end of string
+ detach();
+ if ( TQByteArray::tqresize(nlen+index-olen+1 ) ) {
+ memset( data()+olen, ' ', index-olen );
+ memcpy( data()+index, s, len+1 );
+ }
+ } else {
+ detach();
+ if ( TQByteArray::tqresize(nlen+1 ) ) { // normal insert
+ memmove( data()+index+len, data()+index, olen-index+1 );
+ memcpy( data()+index, s, len );
+ }
+ }
+ return *this;
+}
+
+/*!
+ Inserts character \a c into the string at position \a index and
+ returns a reference to the string.
+
+ If \a index is beyond the end of the string, the string is
+ padded with spaces (ASCII 32) to length \a index and then \a c
+ is appended.
+
+ Example:
+ \code
+ TQCString s = "Yes";
+ s.insert( 3, '!'); // s == "Yes!"
+ \endcode
+
+ \sa remove(), tqreplace()
+*/
+
+TQCString &TQCString::insert( uint index, char c ) // insert char
+{
+ char buf[2];
+ buf[0] = c;
+ buf[1] = '\0';
+ return insert( index, buf );
+}
+
+/*!
+ \fn TQCString &TQCString::prepend( const char *s )
+
+ Prepend \a s to the string. Equivalent to insert(0, s).
+
+ \sa insert()
+*/
+
+/*!
+ Removes \a len characters from the string, starting at position \a
+ index, and returns a reference to the string.
+
+ If \a index is out of range, nothing happens. If \a index is
+ valid, but \a index + \a len is larger than the length of the
+ string, the string is truncated at position \a index.
+
+ \code
+ TQCString s = "Montreal";
+ s.remove( 1, 4 ); // s == "Meal"
+ \endcode
+
+ \sa insert(), tqreplace()
+*/
+
+TQCString &TQCString::remove( uint index, uint len )
+{
+ uint olen = length();
+ if ( index + len >= olen ) { // range problems
+ if ( index < olen ) { // index ok
+ detach();
+ resize( index+1 );
+ }
+ } else if ( len != 0 ) {
+ detach();
+ memmove( data()+index, data()+index+len, olen-index-len+1 );
+ TQByteArray::tqresize(olen-len+1 );
+ }
+ return *this;
+}
+
+/*!
+ Replaces \a len characters from the string, starting at position
+ \a index, with \a str, and returns a reference to the string.
+
+ If \a index is out of range, nothing is removed and \a str is
+ appended at the end of the string. If \a index is valid, but \a
+ index + \a len is larger than the length of the string, \a str
+ tqreplaces the rest of the string from position \a index.
+
+ \code
+ TQCString s = "Say yes!";
+ s.tqreplace( 4, 3, "NO" ); // s == "Say NO!"
+ \endcode
+
+ \sa insert(), remove()
+*/
+
+TQCString &TQCString::tqreplace( uint index, uint len, const char *str )
+{
+ remove( index, len );
+ insert( index, str );
+ return *this;
+}
+
+
+/*! \overload
+
+ Replaces every occurrence of the character \a c in the string
+ with \a after. Returns a reference to the string.
+
+ Example:
+ \code
+ TQCString s = "a,b,c";
+ s.tqreplace( ',', " or " );
+ // s == "a or b or c"
+ \endcode
+*/
+TQCString &TQCString::tqreplace( char c, const char *after )
+{
+ char str[2];
+ str[0] = c;
+ str[1] = '\0';
+ return tqreplace( str, after );
+}
+
+/*! \overload
+
+ Replaces every occurrence of the string \a before in the string
+ with the string \a after. Returns a reference to the string.
+
+ Example:
+ \code
+ TQCString s = "Greek is Greek";
+ s.tqreplace( "Greek", "English" );
+ // s == "English is English"
+ \endcode
+*/
+
+TQCString &TQCString::tqreplace( const char *before, const char *after )
+{
+ if ( before == after || isNull() )
+ return *this;
+
+ detach();
+
+ int index = 0;
+ const int bl = before ? int(strlen( before )) : 0;
+ const int al = after ? int(strlen( after )) : 0;
+ char *d = data();
+ uint len = length();
+
+ if ( bl == al ) {
+ if ( bl ) {
+ while( (index = tqfind( before, index, TRUE, len ) ) != -1 ) {
+ memcpy( d+index, after, al );
+ index += bl;
+ }
+ }
+ } else if ( al < bl ) {
+ uint to = 0;
+ uint movestart = 0;
+ uint num = 0;
+ while( (index = tqfind( before, index, TRUE, len ) ) != -1 ) {
+ if ( num ) {
+ int msize = index - movestart;
+ if ( msize > 0 ) {
+ memmove( d + to, d + movestart, msize );
+ to += msize;
+ }
+ } else {
+ to = index;
+ }
+ if ( al ) {
+ memcpy( d + to, after, al );
+ to += al;
+ }
+ index += bl;
+ movestart = index;
+ num++;
+ }
+ if ( num ) {
+ int msize = len - movestart;
+ if ( msize > 0 )
+ memmove( d + to, d + movestart, msize );
+ resize( len - num*(bl-al) + 1 );
+ }
+ } else {
+ // the most complex case. We don't want to loose performance by doing repeated
+ // copies and reallocs of the string.
+ while( index != -1 ) {
+ uint indices[4096];
+ uint pos = 0;
+ while( pos < 4095 ) {
+ index = tqfind(before, index, TRUE, len);
+ if ( index == -1 )
+ break;
+ indices[pos++] = index;
+ index += bl;
+ // avoid infinite loop
+ if ( !bl )
+ index++;
+ }
+ if ( !pos )
+ break;
+
+ // we have a table of tqreplacement positions, use them for fast replacing
+ int adjust = pos*(al-bl);
+ // index has to be adjusted in case we get back into the loop above.
+ if ( index != -1 )
+ index += adjust;
+ uint newlen = len + adjust;
+ int moveend = len;
+ if ( newlen > len ) {
+ resize( newlen + 1 );
+ len = newlen;
+ }
+ d = data();
+
+ while( pos ) {
+ pos--;
+ int movestart = indices[pos] + bl;
+ int insertstart = indices[pos] + pos*(al-bl);
+ int moveto = insertstart + al;
+ memmove( d + moveto, d + movestart, (moveend - movestart) );
+ if ( after )
+ memcpy( d + insertstart, after, al );
+ moveend = movestart - bl;
+ }
+ }
+ }
+ return *this;
+}
+
+/*! \overload
+
+ Replaces every occurrence of \a c1 with the char \a c2.
+ Returns a reference to the string.
+*/
+TQCString &TQCString::tqreplace( char c1, char c2 )
+{
+ detach();
+ uint i = 0;
+ char *d = data();
+ uint len = length();
+ while ( i < len ) {
+ if ( d[i] == c1 )
+ d[i] = c2;
+ i++;
+ }
+ return *this;
+}
+
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+/*!
+ \overload
+
+ Finds the first occurrence of the regular expression \a rx,
+ starting at position \a index.
+
+ Returns the position of the next match, or -1 if \a rx was not
+ found.
+
+ \warning If you want to apply this function repeatedly to the same
+ string it is more efficient to convert the string to a TQString and
+ apply the function to that.
+*/
+
+int TQCString::tqfind( const TQRegExp& rx, int index ) const
+{
+ TQString d = TQString::fromAscii( data() );
+ return d.tqfind( rx, index );
+}
+
+/*!
+ \overload
+
+ Finds the first occurrence of the regular expression \a rx,
+ starting at position \a index and searching backwards.
+
+ Returns the position of the next match (backwards), or -1 if \a rx
+ was not found.
+
+ \warning If you want to apply this function repeatedly to the same
+ string it is more efficient to convert the string to a TQString and
+ apply the function to that.
+*/
+
+int TQCString::tqfindRev( const TQRegExp& rx, int index ) const
+{
+ TQString d = TQString::fromAscii( data() );
+ return d.tqfindRev( rx, index );
+}
+
+/*!
+ \overload
+
+ Counts the number of overlapping occurrences of \a rx in the string.
+
+ Example:
+ \code
+ TQString s = "banana and panama";
+ TQRegExp r = TQRegExp( "a[nm]a", TRUE, FALSE );
+ s.tqcontains( r ); // 4 matches
+ \endcode
+
+ \sa tqfind(), tqfindRev()
+
+ \warning If you want to apply this function repeatedly to the same
+ string it is more efficient to convert the string to a TQString and
+ apply the function to that.
+*/
+
+int TQCString::tqcontains( const TQRegExp &rx ) const
+{
+ TQString d = TQString::fromAscii( data() );
+ return d.tqcontains( rx );
+}
+
+
+/*!
+ \overload
+
+ Replaces every occurrence of \a rx in the string with \a str.
+ Returns a reference to the string.
+
+ Example:
+ \code
+ TQString s = "banana";
+ s.tqreplace( TQRegExp("a.*a"), "" ); // becomes "b"
+
+ s = "banana";
+ s.tqreplace( TQRegExp("^[bn]a"), "X" ); // becomes "Xnana"
+
+ s = "banana";
+ s.tqreplace( TQRegExp("^[bn]a"), "" ); // becomes "nana"
+ \endcode
+
+ \warning If you want to apply this function repeatedly to the same
+ string it is more efficient to convert the string to a TQString and
+ apply the function to that.
+*/
+
+TQCString &TQCString::tqreplace( const TQRegExp &rx, const char *str )
+{
+ TQString d = TQString::fromAscii( data() );
+ TQString r = TQString::fromAscii( str );
+ d.tqreplace( rx, r );
+ setStr( d.ascii() );
+ return *this;
+}
+#endif //TQT_NO_REGEXP
+
+/*!
+ Returns the string converted to a \c long value.
+
+ If \a ok is not 0: \a *ok is set to FALSE if the string is not a
+ number, or if it has trailing garbage; otherwise \a *ok is set to
+ TRUE.
+*/
+
+long TQCString::toLong( bool *ok ) const
+{
+ char *p = const_cast<char*>(data());
+ long val=0;
+ const long max_mult = LONG_MAX / 10;
+ bool is_ok = FALSE;
+ int neg = 0;
+ if ( !p )
+ goto bye;
+ while ( isspace((uchar) *p) ) // skip leading space
+ p++;
+ if ( *p == '-' ) {
+ p++;
+ neg = 1;
+ } else if ( *p == '+' ) {
+ p++;
+ }
+ if ( !isdigit((uchar) *p) )
+ goto bye;
+ while ( isdigit((uchar) *p) ) {
+ if ( val > max_mult || (val == max_mult && (*p-'0') > 7+neg) )
+ goto bye;
+ val = 10*val + (*p++ - '0');
+ }
+ if ( neg )
+ val = -val;
+ while ( isspace((uchar) *p) ) // skip trailing space
+ p++;
+ if ( *p == '\0' )
+ is_ok = TRUE;
+bye:
+ if ( ok )
+ *ok = is_ok;
+ return is_ok ? val : 0;
+}
+
+/*!
+ Returns the string converted to an \c{unsigned long} value.
+
+ If \a ok is not 0: \a *ok is set to FALSE if the string is not a
+ number, or if it has trailing garbage; otherwise \a *ok is set to
+ TRUE.
+*/
+
+ulong TQCString::toULong( bool *ok ) const
+{
+ char *p = const_cast<char*>(data());
+ ulong val=0;
+ const ulong max_mult = ULONG_MAX / 10;
+ bool is_ok = FALSE;
+ if ( !p )
+ goto bye;
+ while ( isspace((uchar) *p) ) // skip leading space
+ p++;
+ if ( *p == '+' )
+ p++;
+ if ( !isdigit((uchar) *p) )
+ goto bye;
+ while ( isdigit((uchar) *p) ) {
+ if ( val > max_mult || (val == max_mult && (*p-'0') > 5) )
+ goto bye;
+ val = 10*val + (*p++ - '0');
+ }
+ while ( isspace((uchar) *p) ) // skip trailing space
+ p++;
+ if ( *p == '\0' )
+ is_ok = TRUE;
+bye:
+ if ( ok )
+ *ok = is_ok;
+ return is_ok ? val : 0;
+}
+
+/*!
+ Returns the string converted to a \c{short} value.
+
+ If \a ok is not 0: \a *ok is set to FALSE if the string is not a
+ number, is out of range, or if it has trailing garbage; otherwise
+ \a *ok is set to TRUE.
+*/
+
+short TQCString::toShort( bool *ok ) const
+{
+ long v = toLong( ok );
+ if ( v < SHRT_MIN || v > SHRT_MAX ) {
+ if ( ok )
+ *ok = FALSE;
+ v = 0;
+ }
+ return (short)v;
+}
+
+/*!
+ Returns the string converted to an \c{unsigned short} value.
+
+ If \a ok is not 0: \a *ok is set to FALSE if the string is not a
+ number, is out of range, or if it has trailing garbage; otherwise
+ \a *ok is set to TRUE.
+*/
+
+ushort TQCString::toUShort( bool *ok ) const
+{
+ ulong v = toULong( ok );
+ if ( v > USHRT_MAX ) {
+ if ( ok )
+ *ok = FALSE;
+ v = 0;
+ }
+ return (ushort)v;
+}
+
+
+/*!
+ Returns the string converted to a \c{int} value.
+
+ If \a ok is not 0: \a *ok is set to FALSE if the string is not a
+ number, or if it has trailing garbage; otherwise \a *ok is set to
+ TRUE.
+*/
+
+int TQCString::toInt( bool *ok ) const
+{
+ long v = toLong( ok );
+ if ( v < INT_MIN || v > INT_MAX ) {
+ if ( ok )
+ *ok = FALSE;
+ v = 0;
+ }
+ return (int)v;
+}
+
+/*!
+ Returns the string converted to an \c{unsigned int} value.
+
+ If \a ok is not 0: \a *ok is set to FALSE if the string is not a
+ number, or if it has trailing garbage; otherwise \a *ok is set to
+ TRUE.
+*/
+
+uint TQCString::toUInt( bool *ok ) const
+{
+ ulong v = toULong( ok );
+ if ( v > UINT_MAX ) {
+ if ( ok )
+ *ok = FALSE;
+ v = 0;
+ }
+ return (uint)v;
+}
+
+/*!
+ Returns the string converted to a \c{double} value.
+
+ If \a ok is not 0: \a *ok is set to FALSE if the string is not a
+ number, or if it has trailing garbage; otherwise \a *ok is set to
+ TRUE.
+*/
+
+double TQCString::toDouble( bool *ok ) const
+{
+ char *end;
+ double val = strtod( data() ? data() : "", &end );
+ if ( ok )
+ *ok = ( data() && *data() && ( end == 0 || *end == '\0' ) );
+ return val;
+}
+
+/*!
+ Returns the string converted to a \c{float} value.
+
+ If \a ok is not 0: \a *ok is set to FALSE if the string is not a
+ number, or if it has trailing garbage; otherwise \a *ok is set to
+ TRUE.
+*/
+
+float TQCString::toFloat( bool *ok ) const
+{
+ return (float)toDouble( ok );
+}
+
+
+/*!
+ Makes a deep copy of \a str. Returns a reference to the string.
+*/
+
+TQCString &TQCString::setStr( const char *str )
+{
+ detach();
+ if ( str ) { // valid string
+// store( str, tqstrlen(str)+1 );
+ int slen = tqstrlen(str)+1;
+ resize(slen);
+ memcpy(QByteArray::data(), str, slen);
+ }
+ else // empty
+ resize( 0 );
+ return *this;
+}
+
+/*!
+ \overload
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+TQCString &TQCString::setNum( long n )
+{
+ detach();
+ char buf[20];
+ register char *p = &buf[19];
+ bool neg;
+ if ( n < 0 ) {
+ neg = TRUE;
+ n = -n;
+ } else {
+ neg = FALSE;
+ }
+ *p = '\0';
+ do {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ if ( neg )
+ *--p = '-';
+// store( p, tqstrlen(p)+1 );
+ int slen = tqstrlen(p)+1;
+ resize(slen);
+ memcpy(QByteArray::data(), p, slen);
+ return *this;
+}
+
+/*!
+ \overload
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+TQCString &TQCString::setNum( ulong n )
+{
+ detach();
+ char buf[20];
+ register char *p = &buf[19];
+ *p = '\0';
+ do {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+// store( p, tqstrlen(p)+1 );
+ int slen = tqstrlen(p)+1;
+ resize(slen);
+ memcpy(QByteArray::data(), p, slen);
+ return *this;
+}
+
+/*!
+ \overload TQCString &TQCString::setNum( int n )
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+/*!
+ \overload TQCString &TQCString::setNum( uint n )
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+/*!
+ \overload TQCString &TQCString::setNum( short n )
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+/*!
+ \overload TQCString &TQCString::setNum( ushort n )
+
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+*/
+
+/*!
+ Sets the string to the string representation of the number \a n
+ and returns a reference to the string.
+
+ The format of the string representation is specified by the format
+ character \a f, and the precision (number of digits after the
+ decimal point) is specified with \a prec.
+
+ The valid formats for \a f are 'e', 'E', 'f', 'g' and 'G'. The
+ formats are the same as for sprintf(); they are explained in \l
+ TQString::arg().
+*/
+
+TQCString &TQCString::setNum( double n, char f, int prec )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( !(f=='f' || f=='F' || f=='e' || f=='E' || f=='g' || f=='G') )
+ qWarning( "TQCString::setNum: Invalid format char '%c'", f );
+#endif
+ char format[20];
+ register char *fs = format; // generate format string
+ *fs++ = '%'; // "%.<prec>l<f>"
+ if ( prec > 99 )
+ prec = 99;
+ *fs++ = '.';
+ if ( prec >= 10 ) {
+ *fs++ = prec / 10 + '0';
+ *fs++ = prec % 10 + '0';
+ } else {
+ *fs++ = prec + '0';
+ }
+ *fs++ = 'l';
+ *fs++ = f;
+ *fs = '\0';
+ return sprintf( format, n );
+}
+
+/*! \overload TQCString &TQCString::setNum( float n, char f, int prec ) */
+
+
+/*!
+ Sets the character at position \a index to \a c and expands the
+ string if necessary, padding with spaces.
+
+ Returns FALSE if \a index was out of range and the string could
+ not be expanded; otherwise returns TRUE.
+*/
+
+bool TQCString::setExpand( uint index, char c )
+{
+ detach();
+ uint oldlen = length();
+ if ( index >= oldlen ) {
+ if ( !TQByteArray::tqresize( index+2 ) ) // no memory
+ return FALSE;
+ if ( index > oldlen )
+ memset( data() + oldlen, ' ', index - oldlen );
+ *(data() + index+1) = '\0'; // terminate padded string
+ }
+ *(data() + index) = c;
+ return TRUE;
+}
+
+
+/*!
+ \fn TQCString::operator const char *() const
+
+ Returns the string data.
+*/
+
+
+/*!
+ \fn TQCString& TQCString::append( const char *str )
+
+ Appends string \a str to the string and returns a reference to the
+ string. Equivalent to operator+=().
+*/
+
+/*!
+ Appends string \a str to the string and returns a reference to the string.
+*/
+
+TQCString& TQCString::operator+=( const char *str )
+{
+ if ( !str )
+ return *this; // nothing to append
+ detach();
+ uint len1 = length();
+ uint len2 = tqstrlen(str);
+ if ( !TQByteArray::tqresize( len1 + len2 + 1 ) )
+ return *this; // no memory
+ memcpy( data() + len1, str, len2 + 1 );
+ return *this;
+}
+
+/*!
+ \overload
+
+ Appends character \a c to the string and returns a reference to the string.
+*/
+
+TQCString &TQCString::operator+=( char c )
+{
+ detach();
+ uint len = length();
+ if ( !TQByteArray::tqresize( len + 2 ) )
+ return *this; // no memory
+ *(data() + len) = c;
+ *(data() + len+1) = '\0';
+ return *this;
+}
+
+TQCString& TQCString::operator+=( const QString qs )
+{
+ uint len2 = tqstrlen(QByteArray::constData());
+ TQByteArray::tqresize(len2); // Get rid of the old null terminator
+ QByteArray tmp = qs.toAscii();
+ return append(tmp);
+}
+
+TQCString& TQCString::operator+=( const QByteArray qba )
+{
+ uint len2 = tqstrlen(QByteArray::constData());
+ TQByteArray::tqresize(len2); // Get rid of the old null terminator
+ return append(qba);
+}
+
+TQCString& TQCString::operator+=( const TQCString tqcs ) {
+ return operator+=(tqcs.constData());
+}
+
+
+/*****************************************************************************
+ TQCString stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQCString
+
+ Writes string \a str to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+TQDataStream &operator<<( TQDataStream &s, const TQCString &str )
+{
+ return static_cast<TQDataStream&>(s.writeBytes( str.data(), str.size() ));
+}
+
+/*!
+ \relates TQCString
+
+ Reads a string into \a str from the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQCString &str )
+{
+ str.detach();
+ TQ_UINT32 len;
+ s >> len; // read size of string
+ if ( len == 0 || s.eof() ) { // end of file reached
+ str.resize( 0 );
+ return s;
+ }
+ if ( !str.TQByteArray::tqresize( (uint)len )) {// resize string
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQDataStream: Not enough memory to read TQCString" );
+#endif
+ len = 0;
+ }
+ if ( len > 0 ) // not null array
+ s.readRawBytes( str.data(), (uint)len );
+ return s;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*****************************************************************************
+ Documentation for related functions
+ *****************************************************************************/
+
+/*!
+ \fn bool operator==( const TQCString &s1, const TQCString &s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 and \a s2 are equal; otherwise returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) == 0.
+*/
+
+/*!
+ \overload bool operator==( const TQCString &s1, const char *s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 and \a s2 are equal; otherwise returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) == 0.
+*/
+
+/*!
+ \overload bool operator==( const char *s1, const TQCString &s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 and \a s2 are equal; otherwise returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) == 0.
+*/
+
+/*!
+ \fn bool operator!=( const TQCString &s1, const TQCString &s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 and \a s2 are different; otherwise returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) != 0.
+*/
+
+/*!
+ \overload bool operator!=( const TQCString &s1, const char *s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 and \a s2 are different; otherwise returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) != 0.
+*/
+
+/*!
+ \overload bool operator!=( const char *s1, const TQCString &s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 and \a s2 are different; otherwise returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) != 0.
+*/
+
+/*!
+ \fn bool operator<( const TQCString &s1, const char *s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 is less than \a s2; otherwise returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \< 0.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+/*!
+ \overload bool operator<( const char *s1, const TQCString &s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 is less than \a s2; otherwise returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \< 0.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+/*!
+ \fn bool operator<=( const TQCString &s1, const char *s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 is less than or equal to \a s2; otherwise
+ returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \<= 0.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+/*!
+ \overload bool operator<=( const char *s1, const TQCString &s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 is less than or equal to \a s2; otherwise
+ returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \<= 0.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+/*!
+ \fn bool operator>( const TQCString &s1, const char *s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 is greater than \a s2; otherwise returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \> 0.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+/*!
+ \overload bool operator>( const char *s1, const TQCString &s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 is greater than \a s2; otherwise returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \> 0.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+/*!
+ \fn bool operator>=( const TQCString &s1, const char *s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 is greater than or equal to \a s2; otherwise
+ returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \>= 0.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+/*!
+ \overload bool operator>=( const char *s1, const TQCString &s2 )
+
+ \relates TQCString
+
+ Returns TRUE if \a s1 is greater than or equal to \a s2; otherwise
+ returns FALSE.
+
+ Equivalent to qstrcmp(\a s1, \a s2) \>= 0.
+
+ \sa \link #asciinotion Note on character comparisons \endlink
+*/
+
+/*!
+ \fn const TQCString operator+( const TQCString &s1, const TQCString &s2 )
+
+ \relates TQCString
+
+ Returns a string which consists of the concatenation of \a s1 and
+ \a s2.
+*/
+
+/*!
+ \overload const TQCString operator+( const TQCString &s1, const char *s2 )
+
+ \relates TQCString
+
+ Returns a string which consists of the concatenation of \a s1 and \a s2.
+*/
+
+/*!
+ \overload const TQCString operator+( const char *s1, const TQCString &s2 )
+
+ \relates TQCString
+
+ Returns a string which consists of the concatenation of \a s1 and \a s2.
+*/
+
+/*!
+ \overload const TQCString operator+( const TQCString &s, char c )
+
+ \relates TQCString
+
+ Returns a string which consists of the concatenation of \a s and \a c.
+*/
+
+/*!
+ \overload const TQCString operator+( char c, const TQCString &s )
+
+ \relates TQCString
+
+ Returns a string which consists of the concatenation of \a c and \a s.
+*/
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/tools/tqcstring.h b/tqtinterface/qt4/src/tools/tqcstring.h
new file mode 100644
index 0000000..8568713
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqcstring.h
@@ -0,0 +1,792 @@
+/****************************************************************************
+**
+** Definition of the extended char array operations,
+** and TQByteArray and TQCString classes
+**
+** Created : 920609
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCSTRING_H
+#define TQCSTRING_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqmemarray.h"
+#endif // TQT_H
+
+#include <string.h>
+
+#ifdef USE_QT4
+
+#include <Qt/qbytearray.h>
+#include <Qt/qregexp.h>
+#include <Qt/qstring.h>
+
+#endif // USE_QT4
+
+/*****************************************************************************
+ Safe and portable C string functions; extensions to standard string.h
+ *****************************************************************************/
+
+TQ_EXPORT void *tqmemmove( void *dst, const void *src, uint len );
+
+TQ_EXPORT char *tqstrdup( const char * );
+
+TQ_EXPORT inline uint tqstrlen( const char *str )
+{ return str ? (uint)strlen(str) : 0u; }
+
+TQ_EXPORT inline char *tqstrcpy( char *dst, const char *src )
+{ return src ? strcpy(dst, src) : 0; }
+
+TQ_EXPORT char *tqstrncpy( char *dst, const char *src, uint len );
+
+TQ_EXPORT inline int tqstrcmp( const char *str1, const char *str2 )
+{
+ return ( str1 && str2 ) ? strcmp( str1, str2 )
+ : ( str1 ? 1 : ( str2 ? -1 : 0 ) );
+}
+
+TQ_EXPORT inline int tqstrncmp( const char *str1, const char *str2, uint len )
+{
+ return ( str1 && str2 ) ? strncmp( str1, str2, len )
+ : ( str1 ? 1 : ( str2 ? -1 : 0 ) );
+}
+
+TQ_EXPORT int tqstricmp( const char *, const char * );
+
+TQ_EXPORT int tqstrnicmp( const char *, const char *, uint len );
+
+#ifndef TQT_CLEAN_NAMESPACE
+TQ_EXPORT inline uint cstrlen( const char *str )
+{ return (uint)strlen(str); }
+
+TQ_EXPORT inline char *cstrcpy( char *dst, const char *src )
+{ return strcpy(dst,src); }
+
+TQ_EXPORT inline int cstrcmp( const char *str1, const char *str2 )
+{ return strcmp(str1,str2); }
+
+TQ_EXPORT inline int cstrncmp( const char *str1, const char *str2, uint len )
+{ return strncmp(str1,str2,len); }
+#endif
+
+
+// qChecksum: Internet checksum
+
+TQ_EXPORT TQ_UINT16 qChecksum( const char *s, uint len );
+
+/*****************************************************************************
+ TQByteArray class
+ *****************************************************************************/
+
+#ifdef USE_QT4
+
+// NOTE: Qt4 uses implicit sharing
+// Qt3 used explicit sharing
+
+class TQ_EXPORT TQByteArray : public QByteArray
+{
+public:
+ TQByteArray() : QByteArray() {}
+ TQByteArray( int size ) : QByteArray( size, '\0' ) {}
+ ~TQByteArray();
+
+ TQByteArray(const char *cs) : QByteArray( cs ) {}
+ TQByteArray(const char *cs, int size) : QByteArray( cs, size ) {}
+ TQByteArray(int size, char c) : QByteArray( size, c ) {}
+ TQByteArray(int size, Qt::Initialization init ) : QByteArray( size, init ) {}
+ TQByteArray(const TQByteArray &ba ) : QByteArray( ba/*.data(), ba.size()*/ ) {}
+ TQByteArray(const QByteArray &ba ) : QByteArray( ba/*.data(), ba.size()*/ ) {}
+
+ inline char *data() { if (isNull()) return 0; return QByteArray::data(); }
+ inline const char *data() const { if (isNull()) return 0; return QByteArray::data(); }
+ inline const char *constData() const { if (isNull()) return 0; return QByteArray::constData(); }
+
+ inline TQByteArray& assign( const TQByteArray& a ) { *this->operator=(a); return *this; }
+ inline TQByteArray& assign( const char *a, uint n ) { clear(); resize(n); insert(0, a, n); return *this; }
+ inline TQByteArray& duplicate(const TQByteArray& a) { *this = a; return *this; }
+ inline TQByteArray& duplicate(const char *a, uint n) { *this = TQByteArray(a, n); return *this; }
+ inline bool fill( char ch, int size = -1 ) { QByteArray::fill(ch, size); return TRUE; }
+ inline void resetRawData(const char *, uint) { clear(); }
+ inline QByteArray& setRawData(const char *a, uint n) { *this = fromRawData(a, n); return *this; } // Yes, I know about the built-in Qt4 version of this function. It is potentially unstable (corrupts memory) as of Qt4.7 and should not yet be used. Reevaluate this at Qt4.8 or above. [FIXME]
+ inline QByteArray lower() const { return toLower(); }
+ inline QByteArray upper() const { return toUpper(); }
+ inline QByteArray stripWhiteSpace() const { return trimmed(); }
+ inline QByteArray simplifyWhiteSpace() const { return simplified(); }
+ inline int tqfind(int c, int from = 0) const { return indexOf(c, from); }
+ inline int tqfind(char c, int from = 0) const { return indexOf(c, from); }
+ inline int tqfind(const char *c, int from = 0) const { return indexOf(c, from); }
+ inline int tqfind(const QByteArray &ba, int from = 0) const { return indexOf(ba, from); }
+ inline int tqfindRev(char c, int from = -1) const { return lastIndexOf(c, from); }
+ inline int tqfindRev(const char *c, int from = -1) const { return lastIndexOf(c, from); }
+ inline int tqfindRev(const QByteArray &ba, int from = -1) const { return lastIndexOf(ba, from); }
+#ifndef QT_NO_CAST_TO_ASCII
+ inline int tqfind(const QString &s, int from = 0) const;
+ inline int tqfindRev(const QString &s, int from = -1) const;
+#endif
+ inline TQByteArray copy() const { return TQByteArray(*this); }
+ inline QByteRef tqat( int i ) {
+// #ifdef TQT_CHECK_RANGE
+ if ( (i >= size()) || (i < 0) ) {
+ qWarning( "TQByteArray::tqat: Absolute index %d out of range", i );
+ i = 0;
+ }
+// #endif
+ return QByteArray::operator[](i);
+ }
+ inline bool tqresize( uint newlen ) { resize(newlen); return true; }
+ inline bool tqresize( uint newlen, TQGArray::Optimization ) { resize(newlen); return true; }
+
+ inline char &operator[]( int i ) {
+// #ifdef TQT_CHECK_RANGE
+ if ( (i >= size()) || (i < 0) ) {
+ qWarning( "TQByteArray::operator[]: Absolute index %d out of range", i );
+ i = 0;
+ }
+// #endif
+ return *(this->data()+i);
+ }
+
+ using QByteArray::operator=;
+
+ // Interoperability
+// static const TQByteArray& convertFromQByteArray( QByteArray& qba );
+ static const TQByteArray convertFromQByteArray( QByteArray& qba );
+};
+
+// Interoperability
+// inline static const TQByteArray& convertFromQByteArray( const QByteArray& qba ) {
+// return (*static_cast<const TQByteArray*>(&qba));
+// }
+inline static const TQByteArray convertFromQByteArray( const QByteArray& qba ) {
+ return TQByteArray(qba);
+}
+
+#ifndef TQT_NO_COMPRESS
+TQ_EXPORT TQByteArray tqCompress( const uchar* data, int nbytes );
+TQ_EXPORT TQByteArray tqUncompress( const uchar* data, int nbytes );
+TQ_EXPORT inline TQByteArray tqCompress( const TQByteArray& data)
+{ return tqCompress( (const uchar*)data.data(), data.size() ); }
+TQ_EXPORT inline TQByteArray tqUncompress( const TQByteArray& data )
+{ return tqUncompress( (const uchar*)data.data(), data.size() ); }
+#endif
+
+/*****************************************************************************
+ TQByteArray stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &tqds, const TQByteArray &tqba );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &tqds, TQByteArray &tqba );
+#endif
+
+#else // USE_QT4
+
+#if defined(TQ_TQDOC)
+/*
+ We want qdoc to document TQByteArray as a real class that inherits
+ TQMemArray<char> and that is inherited by TQBitArray.
+*/
+class TQByteArray : public TQMemArray<char>
+{
+public:
+ TQByteArray();
+ TQByteArray( int size );
+};
+#else
+typedef TQMemArray<char> TQByteArray;
+#endif
+
+#ifndef TQT_NO_COMPRESS
+TQ_EXPORT TQByteArray tqCompress( const uchar* data, int nbytes );
+TQ_EXPORT TQByteArray tqUncompress( const uchar* data, int nbytes );
+TQ_EXPORT inline TQByteArray tqCompress( const TQByteArray& data)
+{ return tqCompress( (const uchar*)data.data(), data.size() ); }
+TQ_EXPORT inline TQByteArray tqUncompress( const TQByteArray& data )
+{ return tqUncompress( (const uchar*)data.data(), data.size() ); }
+#endif
+
+/*****************************************************************************
+ TQByteArray stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQByteArray & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQByteArray & );
+#endif
+
+#endif // USE_QT4
+
+/*****************************************************************************
+ TQCString class
+ *****************************************************************************/
+
+// #ifdef USE_QT4
+#if 0
+
+#include <QtCore/qbytearray.h>
+#include <QtCore/qdatastream.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3SupportLight)
+
+/*****************************************************************************
+ QCString class
+ *****************************************************************************/
+
+class QRegExp;
+
+class TQCString : public TQByteArray
+{
+public:
+ TQCString() : TQByteArray() {}
+ TQCString(int size);
+ TQCString(const TQCString &s) : TQByteArray(s) {}
+ TQCString(const QByteArray &ba) : TQByteArray(ba.constData()) {}
+ TQCString(const char *str);
+ TQCString(const char *str, uint maxlen);
+
+ ~TQCString();
+
+ TQCString &operator=(const TQCString &s);
+ TQCString &operator=(const char *str);
+ TQCString &operator=(const QByteArray &ba);
+
+ TQCString copy() const { return *this; }
+ TQCString &sprintf(const char *format, ...);
+
+ TQCString left(uint len) const { return QByteArray::left(len); }
+ TQCString right(uint len) const { return QByteArray::right(len); }
+ TQCString mid(uint index, uint len=0xffffffff) const { return QByteArray::mid(index, len); }
+
+ TQCString leftJustify(uint width, char fill=' ', bool trunc=false)const;
+ TQCString rightJustify(uint width, char fill=' ',bool trunc=false)const;
+
+ TQCString lower() const { return QByteArray::toLower(); }
+ TQCString upper() const { return QByteArray::toUpper(); }
+
+ TQCString stripWhiteSpace() const { return QByteArray::trimmed(); }
+ TQCString simplifyWhiteSpace() const { return QByteArray::simplified(); }
+
+ uint length() const;
+ bool truncate( uint pos );
+
+ TQCString &insert(uint index, const char *c) { QByteArray::insert(index, c); return *this; }
+ TQCString &insert(uint index, char c) { QByteArray::insert(index, c); return *this; }
+ TQCString &append(const char *c) { QByteArray::append(c); return *this; }
+ TQCString &prepend(const char *c) { QByteArray::prepend(c); return *this; }
+ TQCString &remove(uint index, uint len) { QByteArray::remove(index, len); return *this; }
+ TQCString &tqreplace(uint index, uint len, const char *c)
+ { TQByteArray::replace(index, len, c); return *this; }
+ TQCString &tqreplace(char c, const TQCString &after) { return tqreplace(c, after.constData()); }
+ TQCString &tqreplace(char c, const char *after) { QByteArray::replace(c, after); return *this; }
+ TQCString &tqreplace(const TQCString &b, const TQCString &a)
+ { return tqreplace(b.constData(), a.constData()); }
+ TQCString &tqreplace(const char *b, const char *a) { QByteArray::replace(b, a); return *this; }
+ TQCString &tqreplace(char b, char a) { QByteArray::replace(b, a); return *this; }
+
+ short toShort(bool *ok=0) const;
+ ushort toUShort(bool *ok=0) const;
+ int toInt(bool *ok=0) const;
+ uint toUInt(bool *ok=0) const;
+ long toLong(bool *ok=0) const;
+ ulong toULong(bool *ok=0) const;
+ float toFloat(bool *ok=0) const;
+ double toDouble(bool *ok=0) const;
+
+ TQCString &setStr(const char *s) { *this = s; return *this; }
+ TQCString &setNum(short);
+ TQCString &setNum(ushort);
+ TQCString &setNum(int);
+ TQCString &setNum(uint);
+ TQCString &setNum(long);
+ TQCString &setNum(ulong);
+ TQCString &setNum(float, char f='g', int prec=6);
+ TQCString &setNum(double, char f='g', int prec=6);
+
+ bool setExpand(uint index, char c);
+
+ int tqcontains( char c, bool cs=TRUE ) const;
+ int tqcontains( const char *str, bool cs=TRUE ) const;
+#ifndef TQT_NO_REGEXP
+ int tqcontains( const QRegExp & ) const;
+#endif
+
+ int tqfind( char c, int index=0, bool cs=TRUE ) const;
+ int tqfind( const char *str, int index=0, bool cs=TRUE ) const;
+#ifndef TQT_NO_REGEXP
+ int tqfind( const QRegExp &re, int index=0 ) const;
+#endif
+
+#ifndef TQT_NO_REGEXP
+ TQCString &tqreplace( const QRegExp &, const char * );
+#endif
+
+// inline const char * tqstringFromPos( int index ) { const char & ref = (*this)[index]; return &ref; }
+ inline const char * tqstringFromPos( int index ) { return constData() + index; }
+
+ operator const char *() const;
+
+ TQCString &operator+=( const char *str );
+ TQCString &operator+=( char c );
+ TQCString &operator+=( const QString qs );
+ TQCString &operator+=( const QByteArray qba );
+ TQCString &operator+=( const TQCString tqcs );
+
+private:
+ int tqfind( const char *str, int index, bool cs, uint l ) const;
+};
+
+inline TQCString::operator const char *() const
+{ return (const char *)data(); }
+
+/*****************************************************************************
+ TQCString stream functions
+ *****************************************************************************/
+#ifndef QT_NO_DATASTREAM
+QDataStream &operator<<(QDataStream &d, const TQCString &s);
+QDataStream &operator>>(QDataStream &d, TQCString &s);
+
+TQDataStream &operator<<(TQDataStream &d, const TQCString &s);
+TQDataStream &operator>>(TQDataStream &d, TQCString &s);
+#endif
+
+/*****************************************************************************
+ TQCString inline functions
+ *****************************************************************************/
+
+inline TQCString &TQCString::setNum(short n)
+{ return setNum(long(n)); }
+
+inline TQCString &TQCString::setNum(ushort n)
+{ return setNum(ulong(n)); }
+
+inline TQCString &TQCString::setNum(int n)
+{ return setNum(long(n)); }
+
+inline TQCString &TQCString::setNum(uint n)
+{ return setNum(ulong(n)); }
+
+inline TQCString &TQCString::setNum(float n, char f, int prec)
+{ return setNum(double(n),f,prec); }
+
+/*****************************************************************************
+ TQCString non-member operators
+ *****************************************************************************/
+
+Q_COMPAT_EXPORT inline bool operator==(const TQCString &s1, const TQCString &s2)
+{ return tqstrcmp(s1, s2) == 0; }
+
+Q_COMPAT_EXPORT inline bool operator==(const TQCString &s1, const char *s2)
+{ return tqstrcmp(s1, s2) == 0; }
+
+Q_COMPAT_EXPORT inline bool operator==(const char *s1, const TQCString &s2)
+{ return tqstrcmp(s1, s2) == 0; }
+
+Q_COMPAT_EXPORT inline bool operator!=(const TQCString &s1, const TQCString &s2)
+{ return tqstrcmp(s1, s2) != 0; }
+
+Q_COMPAT_EXPORT inline bool operator!=(const TQCString &s1, const char *s2)
+{ return tqstrcmp(s1, s2) != 0; }
+
+Q_COMPAT_EXPORT inline bool operator!=(const char *s1, const TQCString &s2)
+{ return tqstrcmp(s1, s2) != 0; }
+
+Q_COMPAT_EXPORT inline bool operator<(const TQCString &s1, const TQCString& s2)
+{ return tqstrcmp(s1, s2) < 0; }
+
+Q_COMPAT_EXPORT inline bool operator<(const TQCString &s1, const char *s2)
+{ return tqstrcmp(s1, s2) < 0; }
+
+Q_COMPAT_EXPORT inline bool operator<(const char *s1, const TQCString &s2)
+{ return tqstrcmp(s1, s2) < 0; }
+
+Q_COMPAT_EXPORT inline bool operator<=(const TQCString &s1, const TQCString &s2)
+{ return tqstrcmp(s1, s2) <= 0; }
+
+Q_COMPAT_EXPORT inline bool operator<=(const TQCString &s1, const char *s2)
+{ return tqstrcmp(s1, s2) <= 0; }
+
+Q_COMPAT_EXPORT inline bool operator<=(const char *s1, const TQCString &s2)
+{ return tqstrcmp(s1, s2) <= 0; }
+
+Q_COMPAT_EXPORT inline bool operator>(const TQCString &s1, const TQCString &s2)
+{ return tqstrcmp(s1, s2) > 0; }
+
+Q_COMPAT_EXPORT inline bool operator>(const TQCString &s1, const char *s2)
+{ return tqstrcmp(s1, s2) > 0; }
+
+Q_COMPAT_EXPORT inline bool operator>(const char *s1, const TQCString &s2)
+{ return tqstrcmp(s1, s2) > 0; }
+
+Q_COMPAT_EXPORT inline bool operator>=(const TQCString &s1, const TQCString& s2)
+{ return tqstrcmp(s1, s2) >= 0; }
+
+Q_COMPAT_EXPORT inline bool operator>=(const TQCString &s1, const char *s2)
+{ return tqstrcmp(s1, s2) >= 0; }
+
+Q_COMPAT_EXPORT inline bool operator>=(const char *s1, const TQCString &s2)
+{ return tqstrcmp(s1, s2) >= 0; }
+
+Q_COMPAT_EXPORT inline const TQCString operator+(const TQCString &s1,
+ const TQCString &s2)
+{
+ TQCString tmp(s1);
+ tmp += s2;
+ return tmp;
+}
+Q_COMPAT_EXPORT inline const TQCString operator+(const TQCString &s1,
+ const QByteArray &s2)
+{
+ QByteArray tmp(s1);
+ tmp += s2;
+ return tmp;
+}
+Q_COMPAT_EXPORT inline const TQCString operator+(const QByteArray &s1,
+ const TQCString &s2)
+{
+ QByteArray tmp(s1);
+ tmp += s2;
+ return tmp;
+}
+
+Q_COMPAT_EXPORT inline const TQCString operator+(const TQCString &s1, const char *s2)
+{
+ TQCString tmp(s1);
+ tmp += s2;
+ return tmp;
+}
+
+Q_COMPAT_EXPORT inline const TQCString operator+(const char *s1, const TQCString &s2)
+{
+ TQCString tmp(s1);
+ tmp += s2;
+ return tmp;
+}
+
+Q_COMPAT_EXPORT inline const TQCString operator+(const TQCString &s1, char c2)
+{
+ TQCString tmp(s1);
+ tmp += c2;
+ return tmp;
+}
+
+Q_COMPAT_EXPORT inline const TQCString operator+(char c1, const TQCString &s2)
+{
+ TQCString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+inline uint TQCString::length() const
+{
+ return tqstrlen( data() );
+}
+
+inline bool TQCString::truncate( uint pos )
+{
+ return tqresize(pos+1);
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#else // USE_QT4
+
+class TQRegExp;
+
+class TQ_EXPORT TQCString : public TQByteArray // C string class
+{
+public:
+ TQCString() {} // make null string
+ TQCString( int size ); // allocate size incl. \0
+ TQCString( const TQCString &s ) : TQByteArray( s ) {}
+ TQCString( const QByteArray ba ) : TQByteArray( ba ) {}
+ TQCString( const char *str ); // deep copy
+ TQCString( const char *str, uint maxlen ); // deep copy, max length
+ ~TQCString();
+
+ TQCString &operator=( const TQCString &s );// shallow copy
+ TQCString &operator=( const char *str ); // deep copy
+ TQCString &operator=(const QByteArray &ba);
+
+ bool isNull() const;
+ bool isEmpty() const;
+ uint length() const;
+ bool resize( uint newlen ) { return tqresize(newlen); }
+ bool tqresize( uint newlen );
+ bool truncate( uint pos );
+ bool fill( char c, int len = -1 );
+
+ TQCString copy() const;
+
+ TQCString &sprintf( const char *format, ... );
+
+ int tqfind( char c, int index=0, bool cs=TRUE ) const;
+ int tqfind( const char *str, int index=0, bool cs=TRUE ) const;
+#ifndef TQT_NO_REGEXP
+ int tqfind( const TQRegExp &, int index=0 ) const;
+#endif
+ int tqfindRev( char c, int index=-1, bool cs=TRUE) const;
+ int tqfindRev( const char *str, int index=-1, bool cs=TRUE) const;
+#ifndef TQT_NO_REGEXP_CAPTURE
+ int tqfindRev( const TQRegExp &, int index=-1 ) const;
+#endif
+ int tqcontains( char c, bool cs=TRUE ) const;
+ int tqcontains( const char *str, bool cs=TRUE ) const;
+#ifndef TQT_NO_REGEXP
+ int tqcontains( const TQRegExp & ) const;
+#endif
+ TQCString left( uint len ) const;
+ TQCString right( uint len ) const;
+ TQCString mid( uint index, uint len=0xffffffff) const;
+
+ TQCString leftJustify( uint width, char fill=' ', bool trunc=FALSE)const;
+ TQCString rightJustify( uint width, char fill=' ',bool trunc=FALSE)const;
+
+ TQCString lower() const;
+ TQCString upper() const;
+
+ TQCString stripWhiteSpace() const;
+ TQCString simplifyWhiteSpace() const;
+
+ TQCString &insert( uint index, const char * );
+ TQCString &insert( uint index, char );
+ TQCString &append( const char * );
+ TQCString &prepend( const char * );
+ TQCString &remove( uint index, uint len );
+ TQCString &tqreplace( uint index, uint len, const char * );
+#ifndef TQT_NO_REGEXP
+ TQCString &tqreplace( const TQRegExp &, const char * );
+#endif
+ TQCString &tqreplace( char c, const char *after );
+ TQCString &tqreplace( const char *, const char * );
+ TQCString &tqreplace( char, char );
+
+ short toShort( bool *ok=0 ) const;
+ ushort toUShort( bool *ok=0 ) const;
+ int toInt( bool *ok=0 ) const;
+ uint toUInt( bool *ok=0 ) const;
+ long toLong( bool *ok=0 ) const;
+ ulong toULong( bool *ok=0 ) const;
+ float toFloat( bool *ok=0 ) const;
+ double toDouble( bool *ok=0 ) const;
+
+ TQCString &setStr( const char *s );
+ TQCString &setNum( short );
+ TQCString &setNum( ushort );
+ TQCString &setNum( int );
+ TQCString &setNum( uint );
+ TQCString &setNum( long );
+ TQCString &setNum( ulong );
+ TQCString &setNum( float, char f='g', int prec=6 );
+ TQCString &setNum( double, char f='g', int prec=6 );
+
+ inline const char * tqstringFromPos( int index ) { return constData() + index; }
+
+ bool setExpand( uint index, char c );
+
+ operator const char *() const;
+ TQCString &operator+=( const char *str );
+ TQCString &operator+=( char c );
+ TQCString &operator+=( const QString qs );
+ TQCString &operator+=( const QByteArray qba );
+ TQCString &operator+=( const TQCString tqcs );
+private:
+ int tqfind( const char *str, int index, bool cs, uint l ) const;
+};
+
+/*****************************************************************************
+ TQCString stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQCString & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQCString & );
+#endif
+
+/*****************************************************************************
+ TQCString inline functions
+ *****************************************************************************/
+
+inline TQCString &TQCString::operator=( const TQCString &s )
+{ return (TQCString&)assign( s ); }
+
+inline TQCString &TQCString::operator=( const char *str )
+{ return (TQCString&)duplicate( str, tqstrlen(str)+1 ); }
+
+inline bool TQCString::isNull() const
+{ return data() == 0; }
+
+inline bool TQCString::isEmpty() const
+{ return data() == 0 || *data() == '\0'; }
+
+inline uint TQCString::length() const
+{ return tqstrlen( data() ); }
+
+inline bool TQCString::truncate( uint pos )
+{ return resize(pos+1); }
+
+inline TQCString TQCString::copy() const
+{ return TQCString( data() ); }
+
+inline TQCString &TQCString::prepend( const char *s )
+{ return insert(0,s); }
+
+inline TQCString &TQCString::append( const char *s )
+{ return operator+=(s); }
+
+inline TQCString &TQCString::setNum( short n )
+{ return setNum((long)n); }
+
+inline TQCString &TQCString::setNum( ushort n )
+{ return setNum((ulong)n); }
+
+inline TQCString &TQCString::setNum( int n )
+{ return setNum((long)n); }
+
+inline TQCString &TQCString::setNum( uint n )
+{ return setNum((ulong)n); }
+
+inline TQCString &TQCString::setNum( float n, char f, int prec )
+{ return setNum((double)n,f,prec); }
+
+inline TQCString::operator const char *() const
+{ return (const char *)data(); }
+
+
+/*****************************************************************************
+ TQCString non-member operators
+ *****************************************************************************/
+
+TQ_EXPORT inline bool operator==( const TQCString &s1, const TQCString &s2 )
+{ return tqstrcmp( s1.data(), s2.data() ) == 0; }
+
+TQ_EXPORT inline bool operator==( const TQCString &s1, const char *s2 )
+{ return tqstrcmp( s1.data(), s2 ) == 0; }
+
+TQ_EXPORT inline bool operator==( const char *s1, const TQCString &s2 )
+{ return tqstrcmp( s1, s2.data() ) == 0; }
+
+TQ_EXPORT inline bool operator!=( const TQCString &s1, const TQCString &s2 )
+{ return tqstrcmp( s1.data(), s2.data() ) != 0; }
+
+TQ_EXPORT inline bool operator!=( const TQCString &s1, const char *s2 )
+{ return tqstrcmp( s1.data(), s2 ) != 0; }
+
+TQ_EXPORT inline bool operator!=( const char *s1, const TQCString &s2 )
+{ return tqstrcmp( s1, s2.data() ) != 0; }
+
+TQ_EXPORT inline bool operator<( const TQCString &s1, const TQCString& s2 )
+{ return tqstrcmp( s1.data(), s2.data() ) < 0; }
+
+TQ_EXPORT inline bool operator<( const TQCString &s1, const char *s2 )
+{ return tqstrcmp( s1.data(), s2 ) < 0; }
+
+TQ_EXPORT inline bool operator<( const char *s1, const TQCString &s2 )
+{ return tqstrcmp( s1, s2.data() ) < 0; }
+
+TQ_EXPORT inline bool operator<=( const TQCString &s1, const TQCString &s2 )
+{ return tqstrcmp( s1.data(), s2.data() ) <= 0; }
+
+TQ_EXPORT inline bool operator<=( const TQCString &s1, const char *s2 )
+{ return tqstrcmp( s1.data(), s2 ) <= 0; }
+
+TQ_EXPORT inline bool operator<=( const char *s1, const TQCString &s2 )
+{ return tqstrcmp( s1, s2.data() ) <= 0; }
+
+TQ_EXPORT inline bool operator>( const TQCString &s1, const TQCString &s2 )
+{ return tqstrcmp( s1.data(), s2.data() ) > 0; }
+
+TQ_EXPORT inline bool operator>( const TQCString &s1, const char *s2 )
+{ return tqstrcmp( s1.data(), s2 ) > 0; }
+
+TQ_EXPORT inline bool operator>( const char *s1, const TQCString &s2 )
+{ return tqstrcmp( s1, s2.data() ) > 0; }
+
+TQ_EXPORT inline bool operator>=( const TQCString &s1, const TQCString& s2 )
+{ return tqstrcmp( s1.data(), s2.data() ) >= 0; }
+
+TQ_EXPORT inline bool operator>=( const TQCString &s1, const char *s2 )
+{ return tqstrcmp( s1.data(), s2 ) >= 0; }
+
+TQ_EXPORT inline bool operator>=( const char *s1, const TQCString &s2 )
+{ return tqstrcmp( s1, s2.data() ) >= 0; }
+
+TQ_EXPORT inline const TQCString operator+( const TQCString &s1,
+ const TQCString &s2 )
+{
+ TQCString tmp( s1.data() );
+ tmp += static_cast<const char *>(s2);
+ return tmp;
+}
+
+TQ_EXPORT inline const TQCString operator+( const TQCString &s1, const char *s2 )
+{
+ TQCString tmp( s1.data() );
+ tmp += s2;
+ return tmp;
+}
+
+TQ_EXPORT inline const TQCString operator+( const char *s1, const TQCString &s2 )
+{
+ TQCString tmp( s1 );
+ tmp += static_cast<const char *>(s2);
+ return tmp;
+}
+
+TQ_EXPORT inline const TQCString operator+( const TQCString &s1, char c2 )
+{
+ TQCString tmp( s1.data() );
+ tmp += c2;
+ return tmp;
+}
+
+TQ_EXPORT inline const TQCString operator+( char c1, const TQCString &s2 )
+{
+ TQCString tmp;
+ tmp += c1;
+ tmp += static_cast<const char *>(s2);
+ return tmp;
+}
+#include "tqwinexport.h"
+
+#endif // USE_QT4
+
+#endif // TQCSTRING_H
diff --git a/tqtinterface/qt4/src/tools/tqdatastream.cpp b/tqtinterface/qt4/src/tools/tqdatastream.cpp
new file mode 100644
index 0000000..bf9955a
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdatastream.cpp
@@ -0,0 +1,1176 @@
+/****************************************************************************
+**
+** Implementation of TQDataStream class
+**
+** Created : 930831
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdatastream.h"
+
+#ifndef TQT_NO_DATASTREAM
+#include "tqbuffer.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#ifndef TQ_OS_TEMP
+#include <locale.h>
+#else
+#include "tqt_windows.h"
+#endif
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \class TQDataStream tqdatastream.h
+ \reentrant
+ \brief The TQDataStream class provides serialization of binary data
+ to a TQIODevice.
+
+ \ingroup io
+
+ A data stream is a binary stream of encoded information which is
+ 100% independent of the host computer's operating system, CPU or
+ byte order. For example, a data stream that is written by a PC
+ under Windows can be read by a Sun SPARC running Solaris.
+
+ You can also use a data stream to read/write \link #raw raw
+ unencoded binary data\endlink. If you want a "parsing" input
+ stream, see TQTextStream.
+
+ The TQDataStream class implements the serialization of C++'s basic
+ data types, like \c char, \c short, \c int, \c char*, etc.
+ Serialization of more complex data is accomplished by breaking up
+ the data into primitive units.
+
+ A data stream cooperates closely with a TQIODevice. A TQIODevice
+ represents an input/output medium one can read data from and write
+ data to. The TQFile class is an example of an IO tqdevice.
+
+ Example (write binary data to a stream):
+ \code
+ TQFile file( "file.dat" );
+ file.open( IO_WriteOnly );
+ TQDataStream stream( &file ); // we will serialize the data into the file
+ stream << "the answer is"; // serialize a string
+ stream << (TQ_INT32)42; // serialize an integer
+ \endcode
+
+ Example (read binary data from a stream):
+ \code
+ TQFile file( "file.dat" );
+ file.open( IO_ReadOnly );
+ TQDataStream stream( &file ); // read the data serialized from the file
+ TQString str;
+ TQ_INT32 a;
+ stream >> str >> a; // extract "the answer is" and 42
+ \endcode
+
+ Each item written to the stream is written in a predefined binary
+ format that varies depending on the item's type. Supported TQt
+ types include TQBrush, TQColor, TQDateTime, TQFont, TQPixmap, TQString,
+ TQVariant and many others. For the complete list of all TQt types
+ supporting data streaming see the \link datastreamformat.html
+ Format of the TQDataStream operators \endlink.
+
+ For integers it is best to always cast to a TQt integer type for
+ writing, and to read back into the same TQt integer type. This
+ ensures that you get integers of the size you want and insulates
+ you from compiler and platform differences.
+
+ To take one example, a \c char* string is written as a 32-bit
+ integer equal to the length of the string including the NUL byte
+ ('\0'), followed by all the characters of the string including the
+ NUL byte. When reading a \c char* string, 4 bytes are read to
+ create the 32-bit length value, then that many characters for the
+ \c char* string including the NUL are read.
+
+ The initial IODevice is usually set in the constructor, but can be
+ changed with setDevice(). If you've reached the end of the data
+ (or if there is no IODevice set) atEnd() will return TRUE.
+
+ If you want the data to be compatible with an earlier version of
+ TQt use setVersion().
+
+ If you want the data to be human-readable, e.g. for debugging, you
+ can set the data stream into printable data mode with
+ setPrintableData(). The data is then written slower, in a bloated
+ but human readable format.
+
+ If you are producing a new binary data format, such as a file
+ format for documents created by your application, you could use a
+ TQDataStream to write the data in a portable format. Typically, you
+ would write a brief header containing a magic string and a version
+ number to give yourself room for future expansion. For example:
+
+ \code
+ TQFile file( "file.xxx" );
+ file.open( IO_WriteOnly );
+ TQDataStream stream( &file );
+
+ // Write a header with a "magic number" and a version
+ stream << (TQ_UINT32)0xA0B0C0D0;
+ stream << (TQ_INT32)123;
+
+ // Write the data
+ stream << [lots of interesting data]
+ \endcode
+
+ Then read it in with:
+
+ \code
+ TQFile file( "file.xxx" );
+ file.open( IO_ReadOnly );
+ TQDataStream stream( &file );
+
+ // Read and check the header
+ TQ_UINT32 magic;
+ stream >> magic;
+ if ( magic != 0xA0B0C0D0 )
+ return XXX_BAD_FILE_FORMAT;
+
+ // Read the version
+ TQ_INT32 version;
+ stream >> version;
+ if ( version < 100 )
+ return XXX_BAD_FILE_TOO_OLD;
+ if ( version > 123 )
+ return XXX_BAD_FILE_TOO_NEW;
+ if ( version <= 110 )
+ stream.setVersion(1);
+
+ // Read the data
+ stream >> [lots of interesting data];
+ if ( version > 120 )
+ stream >> [data new in XXX version 1.2];
+ stream >> [other interesting data];
+ \endcode
+
+ You can select which byte order to use when serializing data. The
+ default setting is big endian (MSB first). Changing it to little
+ endian breaks the portability (unless the reader also changes to
+ little endian). We recommend keeping this setting unless you have
+ special requirements.
+
+ \target raw
+ \section1 Reading and writing raw binary data
+
+ You may wish to read/write your own raw binary data to/from the
+ data stream directly. Data may be read from the stream into a
+ preallocated char* using readRawBytes(). Similarly data can be
+ written to the stream using writeRawBytes(). Notice that any
+ encoding/decoding of the data must be done by you.
+
+ A similar pair of functions is readBytes() and writeBytes(). These
+ differ from their \e raw counterparts as follows: readBytes()
+ reads a TQ_UINT32 which is taken to be the length of the data to be
+ read, then that number of bytes is read into the preallocated
+ char*; writeBytes() writes a TQ_UINT32 containing the length of the
+ data, followed by the data. Notice that any encoding/decoding of
+ the data (apart from the length TQ_UINT32) must be done by you.
+
+ \sa TQTextStream TQVariant
+*/
+
+/*!
+ \enum TQDataStream::ByteOrder
+
+ The byte order used for reading/writing the data.
+
+ \value BigEndian the default
+ \value LittleEndian
+*/
+
+
+/*****************************************************************************
+ TQDataStream member functions
+ *****************************************************************************/
+
+#if defined(TQT_CHECK_STATE)
+#undef CHECK_STREAM_PRECOND
+#define CHECK_STREAM_PRECOND if ( !dev ) { \
+ qWarning( "TQDataStream: No tqdevice" ); \
+ return *this; }
+#else
+#define CHECK_STREAM_PRECOND
+#endif
+
+static int systemWordSize = 0;
+static bool systemBigEndian;
+
+static const int DefaultStreamVersion = 6;
+// ### On next version bump, TQPen::width() should not be restricted to 8-bit values.
+// ### On next version bump, when streaming invalid TQVariants, just the type should
+// be written, no "data" after it
+// 6 is default in TQt 3.3
+// 5 is default in TQt 3.1
+// 4 is default in TQt 3.0
+// 3 is default in TQt 2.1
+// 2 is the TQt 2.0.x format
+// 1 is the TQt 1.x format
+
+/*!
+ Constructs a data stream that has no IO tqdevice.
+
+ \sa setDevice()
+*/
+
+TQDataStream::TQDataStream()
+{
+ if ( systemWordSize == 0 ) // get system features
+ qSysInfo( &systemWordSize, &systemBigEndian );
+ dev = 0; // no tqdevice set
+ owndev = FALSE;
+ byteorder = BigEndian; // default byte order
+ printable = FALSE;
+ ver = DefaultStreamVersion;
+ noswap = systemBigEndian;
+}
+
+/*!
+ Constructs a data stream that uses the IO tqdevice \a d.
+
+ \warning If you use TQSocket or TQSocketDevice as the IO tqdevice \a d
+ for reading data, you must make sure that enough data is available
+ on the socket for the operation to successfully proceed;
+ TQDataStream does not have any means to handle or recover from
+ short-reads.
+
+ \sa setDevice(), tqdevice()
+*/
+
+TQDataStream::TQDataStream( TQIODevice *d )
+{
+ if ( systemWordSize == 0 ) // get system features
+ qSysInfo( &systemWordSize, &systemBigEndian );
+ dev = d; // set tqdevice
+ owndev = FALSE;
+ byteorder = BigEndian; // default byte order
+ printable = FALSE;
+ ver = DefaultStreamVersion;
+ noswap = systemBigEndian;
+}
+
+/*!
+ Constructs a data stream that operates on a byte array, \a a,
+ through an internal TQBuffer tqdevice. The \a mode is a
+ TQIODevice::mode(), usually either \c IO_ReadOnly or \c
+ IO_WriteOnly.
+
+ Example:
+ \code
+ static char bindata[] = { 231, 1, 44, ... };
+ TQByteArray a;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ TQDataStream stream( a, IO_ReadOnly ); // open on a's data
+ stream >> [something]; // read raw bindata
+ a.resetRawData( bindata, sizeof(bindata) ); // finished
+ \endcode
+
+ The TQByteArray::setRawData() function is not for the inexperienced.
+*/
+
+TQDataStream::TQDataStream( TQByteArray a, int mode )
+{
+ if ( systemWordSize == 0 ) // get system features
+ qSysInfo( &systemWordSize, &systemBigEndian );
+ dev = new TQBuffer( a ); // create tqdevice
+ ((TQBuffer *)dev)->open( mode ); // open tqdevice
+ owndev = TRUE;
+ byteorder = BigEndian; // default byte order
+ printable = FALSE;
+ ver = DefaultStreamVersion;
+ noswap = systemBigEndian;
+}
+
+/*!
+ Destroys the data stream.
+
+ The destructor will not affect the current IO tqdevice, unless it is
+ an internal IO tqdevice processing a TQByteArray passed in the \e
+ constructor, in which case the internal IO tqdevice is destroyed.
+*/
+
+TQDataStream::~TQDataStream()
+{
+ if ( owndev )
+ delete dev;
+}
+
+
+/*!
+ \fn TQIODevice *TQDataStream::tqdevice() const
+
+ Returns the IO tqdevice currently set.
+
+ \sa setDevice(), unsetDevice()
+*/
+
+/*!
+ void TQDataStream::setDevice(TQIODevice *d )
+
+ Sets the IO tqdevice to \a d.
+
+ \sa tqdevice(), unsetDevice()
+*/
+
+void TQDataStream::setDevice(TQIODevice *d )
+{
+ if ( owndev ) {
+ delete dev;
+ owndev = FALSE;
+ }
+ dev = d;
+}
+
+/*!
+ Unsets the IO tqdevice. This is the same as calling setDevice( 0 ).
+
+ \sa tqdevice(), setDevice()
+*/
+
+void TQDataStream::unsetDevice()
+{
+ setDevice( 0 );
+}
+
+
+/*!
+ \fn bool TQDataStream::atEnd() const
+
+ Returns TRUE if the IO tqdevice has reached the end position (end of
+ the stream or file) or if there is no IO tqdevice set; otherwise
+ returns FALSE, i.e. if the current position of the IO tqdevice is
+ before the end position.
+
+ \sa TQIODevice::atEnd()
+*/
+
+/*!\fn bool TQDataStream::eof() const
+
+ \obsolete
+
+ Returns TRUE if the IO tqdevice has reached the end position (end of
+ stream or file) or if there is no IO tqdevice set.
+
+ Returns FALSE if the current position of the read/write head of the IO
+ tqdevice is somewhere before the end position.
+
+ \sa TQIODevice::atEnd()
+*/
+
+/*!
+ \fn int TQDataStream::byteOrder() const
+
+ Returns the current byte order setting -- either \c BigEndian or
+ \c LittleEndian.
+
+ \sa setByteOrder()
+*/
+
+/*!
+ Sets the serialization byte order to \a bo.
+
+ The \a bo parameter can be \c TQDataStream::BigEndian or \c
+ TQDataStream::LittleEndian.
+
+ The default setting is big endian. We recommend leaving this
+ setting unless you have special requirements.
+
+ \sa byteOrder()
+*/
+
+void TQDataStream::setByteOrder( int bo )
+{
+ byteorder = bo;
+ if ( systemBigEndian )
+ noswap = byteorder == BigEndian;
+ else
+ noswap = byteorder == LittleEndian;
+}
+
+
+/*!
+ \fn bool TQDataStream::isPrintableData() const
+
+ Returns TRUE if the printable data flag has been set; otherwise
+ returns FALSE.
+
+ \sa setPrintableData()
+*/
+
+/*!
+ \fn void TQDataStream::setPrintableData( bool enable )
+
+ If \a enable is TRUE, data will be output in a human readable
+ format. If \a enable is FALSE, data will be output in a binary
+ format.
+
+ If \a enable is TRUE, the write functions will generate output
+ that consists of printable characters (7 bit ASCII). This output
+ will typically be a lot larger than the default binary output, and
+ consequently slower to write.
+
+ We recommend only enabling printable data for debugging purposes.
+*/
+
+
+/*!
+ \fn int TQDataStream::version() const
+
+ Returns the version number of the data serialization format. In TQt
+ 3.1, this number is 5.
+
+ \sa setVersion()
+*/
+
+/*!
+ \fn void TQDataStream::setVersion( int v )
+
+ Sets the version number of the data serialization format to \a v.
+
+ You don't need to set a version if you are using the current
+ version of TQt.
+
+ In order to accommodate new functionality, the datastream
+ serialization format of some TQt classes has changed in some
+ versions of TQt. If you want to read data that was created by an
+ earlier version of TQt, or write data that can be read by a program
+ that was compiled with an earlier version of TQt, use this function
+ to modify the serialization format of TQDataStream.
+
+ \table
+ \header \i TQt Version \i TQDataStream Version
+ \row \i TQt 3.3 \i11 6
+ \row \i TQt 3.2 \i11 5
+ \row \i TQt 3.1 \i11 5
+ \row \i TQt 3.0 \i11 4
+ \row \i TQt 2.1.x and TQt 2.2.x \i11 3
+ \row \i TQt 2.0.x \i11 2
+ \row \i TQt 1.x \i11 1
+ \endtable
+
+ \sa version()
+*/
+
+/*****************************************************************************
+ TQDataStream read functions
+ *****************************************************************************/
+
+#if defined(TQ_OS_HPUX) && !defined(__LP64__)
+extern "C" long long __strtoll( const char *, char**, int );
+#endif
+
+static TQ_INT64 read_int_ascii( TQDataStream *s )
+{
+ register int n = 0;
+ char buf[40];
+ for ( ;; ) {
+ buf[n] = s->tqdevice()->getch();
+ if ( buf[n] == '\n' || n > 38 ) // $-terminator
+ break;
+ n++;
+ }
+ buf[n] = '\0';
+
+#if defined(__LP64__) || defined(TQ_OS_OSF)
+ // sizeof(long) == 8
+ return strtol(buf, (char **)0, 10);
+#else
+# if defined(TQ_OS_TEMP)
+ return strtol( buf, (char**)0, 10 );
+# elif defined(TQ_OS_WIN)
+ return _atoi64( buf );
+# elif defined(TQ_OS_HPUX)
+ return __strtoll( buf, (char**)0, 10 );
+# elif defined(TQ_OS_MACX) && defined(TQT_MACOSX_VERSION) && TQT_MACOSX_VERSION < 0x1020
+ return strtoq( buf, (char**)0, 10 );
+# else
+ return strtoll( buf, (char**)0, 10 ); // C99 function
+# endif
+#endif
+}
+
+/*!
+ \overload TQDataStream &TQDataStream::operator>>( TQ_UINT8 &i )
+
+ Reads an unsigned byte from the stream into \a i, and returns a
+ reference to the stream.
+*/
+
+/*!
+ Reads a signed byte from the stream into \a i, and returns a
+ reference to the stream.
+*/
+
+TQDataStream &TQDataStream::operator>>( TQ_INT8 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = (TQ_INT8)dev->getch();
+ if ( i == '\\' ) { // read octal code
+ char buf[4];
+ dev->readBlock( buf, 3 );
+ i = (buf[2] & 0x07)+((buf[1] & 0x07) << 3)+((buf[0] & 0x07) << 6);
+ }
+ } else { // data or text
+ i = (TQ_INT8)dev->getch();
+ }
+ return *this;
+}
+
+
+/*!
+ \overload TQDataStream &TQDataStream::operator>>( TQ_UINT16 &i )
+
+ Reads an unsigned 16-bit integer from the stream into \a i, and
+ returns a reference to the stream.
+*/
+
+/*!
+ \overload
+
+ Reads a signed 16-bit integer from the stream into \a i, and
+ returns a reference to the stream.
+*/
+
+TQDataStream &TQDataStream::operator>>( TQ_INT16 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = (TQ_INT16)read_int_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&i, sizeof(TQ_INT16) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[2];
+ dev->readBlock( b, 2 );
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+
+/*!
+ \overload TQDataStream &TQDataStream::operator>>( TQ_UINT32 &i )
+
+ Reads an unsigned 32-bit integer from the stream into \a i, and
+ returns a reference to the stream.
+*/
+
+/*!
+ \overload
+
+ Reads a signed 32-bit integer from the stream into \a i, and
+ returns a reference to the stream.
+*/
+
+TQDataStream &TQDataStream::operator>>( TQ_INT32 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = (TQ_INT32)read_int_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&i, sizeof(TQ_INT32) );
+ } else { // swap bytes
+ uchar *p = (uchar *)(&i);
+ char b[4];
+ dev->readBlock( b, 4 );
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+/*!
+ \overload TQDataStream &TQDataStream::operator>>( TQ_UINT64 &i )
+
+ Reads an unsigned 64-bit integer from the stream, into \a i, and
+ returns a reference to the stream.
+*/
+
+/*!
+ \overload
+
+ Reads a signed 64-bit integer from the stream into \a i, and
+ returns a reference to the stream.
+*/
+
+TQDataStream &TQDataStream::operator>>( TQ_INT64 &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = read_int_ascii( this );
+ } else if ( version() < 6 ) {
+ TQ_UINT32 i1, i2;
+ *this >> i2 >> i1;
+ i = ((TQ_UINT64)i1 << 32) + i2;
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&i, sizeof(TQ_INT64) );
+ } else { // swap bytes
+ uchar *p = (uchar *)(&i);
+ char b[8];
+ dev->readBlock( b, 8 );
+ *p++ = b[7];
+ *p++ = b[6];
+ *p++ = b[5];
+ *p++ = b[4];
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+
+/*!
+ \overload TQDataStream &TQDataStream::operator>>( TQ_ULONG &i )
+
+ Reads an unsigned integer of the system's word length from the
+ stream, into \a i, and returns a reference to the stream.
+*/
+
+#if !defined(TQ_OS_WIN64)
+/*!
+ \overload
+
+ Reads a signed integer of the system's word length from the stream
+ into \a i, and returns a reference to the stream.
+
+*/
+
+TQDataStream &TQDataStream::operator>>( TQ_LONG &i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ i = (TQ_LONG)read_int_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&i, sizeof(TQ_LONG) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[sizeof(TQ_LONG)];
+ dev->readBlock( b, sizeof(TQ_LONG) );
+ for ( int j = sizeof(TQ_LONG); j; )
+ *p++ = b[--j];
+ }
+ return *this;
+}
+#endif
+
+static double read_double_ascii( TQDataStream *s )
+{
+ register int n = 0;
+ char buf[80];
+ for ( ;; ) {
+ buf[n] = s->tqdevice()->getch();
+ if ( buf[n] == '\n' || n > 78 ) // $-terminator
+ break;
+ n++;
+ }
+ buf[n] = '\0';
+ return atof( buf );
+}
+
+
+/*!
+ \overload
+
+ Reads a 32-bit floating point number from the stream into \a f,
+ using the standard IEEE754 format. Returns a reference to the
+ stream.
+*/
+
+TQDataStream &TQDataStream::operator>>( float &f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ f = (float)read_double_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&f, sizeof(float) );
+ } else { // swap bytes
+ uchar *p = (uchar *)(&f);
+ char b[4];
+ dev->readBlock( b, 4 );
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Reads a 64-bit floating point number from the stream into \a f,
+ using the standard IEEE754 format. Returns a reference to the
+ stream.
+*/
+
+TQDataStream &TQDataStream::operator>>( double &f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ f = read_double_ascii( this );
+ } else if ( noswap ) { // no conversion needed
+ dev->readBlock( (char *)&f, sizeof(double) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&f);
+ char b[8];
+ dev->readBlock( b, 8 );
+ *p++ = b[7];
+ *p++ = b[6];
+ *p++ = b[5];
+ *p++ = b[4];
+ *p++ = b[3];
+ *p++ = b[2];
+ *p++ = b[1];
+ *p = b[0];
+ }
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Reads the '\0'-terminated string \a s from the stream and returns
+ a reference to the stream.
+
+ Space for the string is allocated using \c new -- the caller must
+ destroy it with delete[].
+*/
+
+TQDataStream &TQDataStream::operator>>( char *&s )
+{
+ uint len = 0;
+ return readBytes( s, len );
+}
+
+
+/*!
+ Reads the buffer \a s from the stream and returns a reference to
+ the stream.
+
+ The buffer \a s is allocated using \c new. Destroy it with the \c
+ delete[] operator. If the length is zero or \a s cannot be
+ allocated, \a s is set to 0.
+
+ The \a l parameter will be set to the length of the buffer.
+
+ The serialization format is a TQ_UINT32 length specifier first,
+ then \a l bytes of data. Note that the data is \e not encoded.
+
+ \sa readRawBytes(), writeBytes()
+*/
+
+TQDataStream &TQDataStream::readBytes( char *&s, uint &l )
+{
+ CHECK_STREAM_PRECOND
+ TQ_UINT32 len;
+ *this >> len; // first read length spec
+ l = (uint)len;
+ if ( len == 0 || eof() ) {
+ s = 0;
+ return *this;
+ } else {
+ s = new char[len]; // create char array
+ TQ_CHECK_PTR( s );
+ if ( !s ) // no memory
+ return *this;
+ return readRawBytes( s, (uint)len );
+ }
+}
+
+
+/*!
+ Reads \a len bytes from the stream into \a s and returns a
+ reference to the stream.
+
+ The buffer \a s must be preallocated. The data is \e not encoded.
+
+ \sa readBytes(), TQIODevice::readBlock(), writeRawBytes()
+*/
+
+TQDataStream &TQDataStream::readRawBytes( char *s, uint len )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ register TQ_INT8 *p = (TQ_INT8*)s;
+ if ( version() < 4 ) {
+ while ( len-- ) {
+ TQ_INT32 tmp;
+ *this >> tmp;
+ *p++ = tmp;
+ }
+ } else {
+ while ( len-- )
+ *this >> *p++;
+ }
+ } else { // read data char array
+ dev->readBlock( s, len );
+ }
+ return *this;
+}
+
+
+/*****************************************************************************
+ TQDataStream write functions
+ *****************************************************************************/
+
+
+/*!
+ \overload TQDataStream &TQDataStream::operator<<( TQ_UINT8 i )
+
+ Writes an unsigned byte, \a i, to the stream and returns a
+ reference to the stream.
+*/
+
+/*!
+ Writes a signed byte, \a i, to the stream and returns a reference
+ to the stream.
+*/
+
+TQDataStream &TQDataStream::operator<<( TQ_INT8 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable && (i == '\\' || !isprint((uchar) i)) ) {
+ char buf[6]; // write octal code
+ buf[0] = '\\';
+ buf[1] = '0' + ((i >> 6) & 0x07);
+ buf[2] = '0' + ((i >> 3) & 0x07);
+ buf[3] = '0' + (i & 0x07);
+ buf[4] = '\0';
+ dev->writeBlock( buf, 4 );
+ } else {
+ dev->putch( i );
+ }
+ return *this;
+}
+
+
+/*!
+ \overload TQDataStream &TQDataStream::operator<<( TQ_UINT16 i )
+
+ Writes an unsigned 16-bit integer, \a i, to the stream and returns
+ a reference to the stream.
+*/
+
+/*!
+ \overload
+
+ Writes a signed 16-bit integer, \a i, to the stream and returns a
+ reference to the stream.
+*/
+
+TQDataStream &TQDataStream::operator<<( TQ_INT16 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[16];
+ sprintf( buf, "%d\n", i );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&i, sizeof(TQ_INT16) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[2];
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 2 );
+ }
+ return *this;
+}
+
+/*!
+ \overload
+
+ Writes a signed 32-bit integer, \a i, to the stream and returns a
+ reference to the stream.
+*/
+
+TQDataStream &TQDataStream::operator<<( TQ_INT32 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[16];
+ sprintf( buf, "%d\n", i );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&i, sizeof(TQ_INT32) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[4];
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 4 );
+ }
+ return *this;
+}
+
+/*!
+ \overload TQDataStream &TQDataStream::operator<<( TQ_UINT64 i )
+
+ Writes an unsigned 64-bit integer, \a i, to the stream and returns a
+ reference to the stream.
+*/
+
+/*!
+ \overload
+
+ Writes a signed 64-bit integer, \a i, to the stream and returns a
+ reference to the stream.
+*/
+
+TQDataStream &TQDataStream::operator<<( TQ_INT64 i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[16];
+#ifdef TQ_OS_WIN
+ sprintf( buf, "%I64d\n", i );
+#else
+ sprintf( buf, "%lld\n", i );
+#endif
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( version() < 6 ) {
+ TQ_UINT32 i1 = i & 0xffffffff;
+ TQ_UINT32 i2 = i >> 32;
+ *this << i2 << i1;
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&i, sizeof(TQ_INT64) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[8];
+ b[7] = *p++;
+ b[6] = *p++;
+ b[5] = *p++;
+ b[4] = *p++;
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 8 );
+ }
+ return *this;
+}
+
+/*!
+ \overload TQDataStream &TQDataStream::operator<<( TQ_ULONG i )
+
+ Writes an unsigned integer \a i, of the system's word length, to
+ the stream and returns a reference to the stream.
+*/
+
+#if !defined(TQ_OS_WIN64)
+/*!
+ \overload
+
+ Writes a signed integer \a i, of the system's word length, to the
+ stream and returns a reference to the stream.
+*/
+
+TQDataStream &TQDataStream::operator<<( TQ_LONG i )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ char buf[20];
+ sprintf( buf, "%ld\n", i );
+ dev->writeBlock( buf, strlen(buf) );
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&i, sizeof(TQ_LONG) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&i);
+ char b[sizeof(TQ_LONG)];
+ for ( int j = sizeof(TQ_LONG); j; )
+ b[--j] = *p++;
+ dev->writeBlock( b, sizeof(TQ_LONG) );
+ }
+ return *this;
+}
+#endif
+
+
+/*!
+ \overload TQDataStream &TQDataStream::operator<<( TQ_UINT32 i )
+
+ Writes an unsigned integer, \a i, to the stream as a 32-bit
+ unsigned integer (TQ_UINT32). Returns a reference to the stream.
+*/
+
+/*!
+ \overload
+
+ Writes a 32-bit floating point number, \a f, to the stream using
+ the standard IEEE754 format. Returns a reference to the stream.
+*/
+
+TQDataStream &TQDataStream::operator<<( float f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ TQString num = TQString::number((double)f);
+ dev->writeBlock(num.latin1(), num.length());
+ dev->putch('\n');
+ } else {
+ float g = f; // fixes float-on-stack problem
+ if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&g, sizeof(float) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&g);
+ char b[4];
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 4 );
+ }
+ }
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Writes a 64-bit floating point number, \a f, to the stream using
+ the standard IEEE754 format. Returns a reference to the stream.
+*/
+
+TQDataStream &TQDataStream::operator<<( double f )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // printable data
+ TQString num = TQString::number((double)f);
+ dev->writeBlock(num.latin1(), num.length());
+ dev->putch('\n');
+ } else if ( noswap ) { // no conversion needed
+ dev->writeBlock( (char *)&f, sizeof(double) );
+ } else { // swap bytes
+ register uchar *p = (uchar *)(&f);
+ char b[8];
+ b[7] = *p++;
+ b[6] = *p++;
+ b[5] = *p++;
+ b[4] = *p++;
+ b[3] = *p++;
+ b[2] = *p++;
+ b[1] = *p++;
+ b[0] = *p;
+ dev->writeBlock( b, 8 );
+ }
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Writes the '\0'-terminated string \a s to the stream and returns a
+ reference to the stream.
+
+ The string is serialized using writeBytes().
+*/
+
+TQDataStream &TQDataStream::operator<<( const char *s )
+{
+ if ( !s ) {
+ *this << (TQ_UINT32)0;
+ return *this;
+ }
+ uint len = tqstrlen( s ) + 1; // also write null terminator
+ *this << (TQ_UINT32)len; // write length specifier
+ return writeRawBytes( s, len );
+}
+
+
+/*!
+ Writes the length specifier \a len and the buffer \a s to the
+ stream and returns a reference to the stream.
+
+ The \a len is serialized as a TQ_UINT32, followed by \a len bytes
+ from \a s. Note that the data is \e not encoded.
+
+ \sa writeRawBytes(), readBytes()
+*/
+
+TQDataStream &TQDataStream::writeBytes(const char *s, uint len)
+{
+ CHECK_STREAM_PRECOND
+ *this << (TQ_UINT32)len; // write length specifier
+ if ( len )
+ writeRawBytes( s, len );
+ return *this;
+}
+
+
+/*!
+ Writes \a len bytes from \a s to the stream and returns a
+ reference to the stream. The data is \e not encoded.
+
+ \sa writeBytes(), TQIODevice::writeBlock(), readRawBytes()
+*/
+
+TQDataStream &TQDataStream::writeRawBytes( const char *s, uint len )
+{
+ CHECK_STREAM_PRECOND
+ if ( printable ) { // write printable
+ if ( version() < 4 ) {
+ register char *p = (char *)s;
+ while ( len-- )
+ *this << *p++;
+ } else {
+ register TQ_INT8 *p = (TQ_INT8*)s;
+ while ( len-- )
+ *this << *p++;
+ }
+ } else { // write data char array
+ dev->writeBlock( s, len );
+ }
+ return *this;
+}
+
+#endif // TQT_NO_DATASTREAM
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/tools/tqdatastream.h b/tqtinterface/qt4/src/tools/tqdatastream.h
new file mode 100644
index 0000000..f47847f
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdatastream.h
@@ -0,0 +1,353 @@
+/****************************************************************************
+**
+** Definition of TQDataStream class
+**
+** Created : 930831
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDATASTREAM_H
+#define TQDATASTREAM_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqiodevice.h"
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qdatastream.h>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+class TQ_EXPORT TQDataStream : public QDataStream
+{
+public:
+ TQDataStream() : QDataStream() {}
+ TQDataStream( QIODevice * tio ) : QDataStream( tio ) {}
+ TQDataStream( QByteArray &ba, int mode ) : QDataStream( &ba, (QIODevice::OpenModeFlag)mode ) {}
+ TQDataStream( TQByteArray &ba, int mode ) : QDataStream( &ba, (QIODevice::OpenModeFlag)mode ) {}
+// TQDataStream( const TQByteArray &ba, int mode ) : QDataStream( &const_cast<TQByteArray&>(ba), (QIODevice::OpenModeFlag)mode ) {}
+ TQDataStream( const TQByteArray &ba, int mode ) : QDataStream( static_cast<const QByteArray&>(ba) ) { TQ_UNUSED(mode); }
+// TQDataStream( const QByteArray &ba, int mode ) : QDataStream( ba ) { TQ_UNUSED(mode); }
+ inline QDataStream &readRawBytes(char *str, uint len) { readRawData(str, static_cast<int>(len)); return *this; }
+ inline QDataStream &writeRawBytes(const char *str, uint len) { writeRawData(str, static_cast<int>(len)); return *this; }
+ inline bool isPrintableData() const { return false; }
+ inline void setPrintableData(bool) {}
+ inline TQIODevice *tqdevice() const { return static_cast<TQIODevice*>(device()); }
+ inline bool eof() const { return atEnd(); }
+
+ TQDataStream &operator>>( TQ_INT8 &i );
+ TQDataStream &operator>>( TQ_UINT8 &i );
+ TQDataStream &operator>>( TQ_INT16 &i );
+ TQDataStream &operator>>( TQ_UINT16 &i );
+ TQDataStream &operator>>( TQ_INT32 &i );
+ TQDataStream &operator>>( TQ_UINT32 &i );
+ TQDataStream &operator>>( TQ_INT64 &i );
+ TQDataStream &operator>>( TQ_UINT64 &i );
+#if !defined(TQ_OS_WIN64)
+ TQDataStream &operator>>( TQ_LONG &i );
+ TQDataStream &operator>>( TQ_ULONG &i );
+#endif
+
+ TQDataStream &operator>>( float &f );
+ TQDataStream &operator>>( double &f );
+ TQDataStream &operator>>( char *&str );
+
+ TQDataStream &operator>>( bool &i );
+
+ TQDataStream &operator<<( TQ_INT8 i );
+ TQDataStream &operator<<( TQ_UINT8 i );
+ TQDataStream &operator<<( TQ_INT16 i );
+ TQDataStream &operator<<( TQ_UINT16 i );
+ TQDataStream &operator<<( TQ_INT32 i );
+ TQDataStream &operator<<( TQ_UINT32 i );
+ TQDataStream &operator<<( TQ_INT64 i );
+ TQDataStream &operator<<( TQ_UINT64 i );
+#if !defined(TQ_OS_WIN64)
+ TQDataStream &operator<<( TQ_LONG i );
+ TQDataStream &operator<<( TQ_ULONG i );
+#endif
+ TQDataStream &operator<<( float f );
+ TQDataStream &operator<<( double f );
+ TQDataStream &operator<<( const char *str );
+
+ TQDataStream &operator<<( bool i );
+};
+
+inline TQDataStream &TQDataStream::operator>>( bool &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((bool&)i)); }
+
+inline TQDataStream &TQDataStream::operator>>( float &f )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((float&)f)); }
+
+inline TQDataStream &TQDataStream::operator>>( double &d )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((double&)d)); }
+
+inline TQDataStream &TQDataStream::operator>>( char *&str )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((char*&)str)); }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_INT8 &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((TQ_INT8&)i)); }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_INT16 &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((TQ_INT16&)i)); }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_INT32 &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((TQ_INT32&)i)); }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_INT64 &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((TQ_INT64&)i)); }
+
+#if !defined(TQ_OS_WIN64)
+inline TQDataStream &TQDataStream::operator>>( TQ_LONG &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((qint64&)i)); }
+#endif
+
+inline TQDataStream &TQDataStream::operator>>( TQ_UINT8 &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((TQ_INT8&)i)); }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_UINT16 &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((TQ_INT16&)i)); }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_UINT32 &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((TQ_INT32&)i)); }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_UINT64 &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((TQ_INT64&)i)); }
+
+#if !defined(TQ_OS_WIN64)
+inline TQDataStream &TQDataStream::operator>>( TQ_ULONG &i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator>>((quint64&)i)); }
+#endif
+
+inline TQDataStream &TQDataStream::operator<<( bool i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((bool)i)); }
+
+inline TQDataStream &TQDataStream::operator<<( float f )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((float)f)); }
+
+inline TQDataStream &TQDataStream::operator<<( double d )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((double)d)); }
+
+inline TQDataStream &TQDataStream::operator<<( const char *str )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((const char*)str)); }
+
+inline TQDataStream &TQDataStream::operator<<( TQ_INT8 i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((TQ_INT8)i)); }
+
+inline TQDataStream &TQDataStream::operator<<( TQ_INT16 i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((TQ_INT16)i)); }
+
+inline TQDataStream &TQDataStream::operator<<( TQ_INT32 i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((TQ_INT32)i)); }
+
+inline TQDataStream &TQDataStream::operator<<( TQ_INT64 i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((TQ_INT64)i)); }
+
+#if !defined(TQ_OS_WIN64)
+inline TQDataStream &TQDataStream::operator<<( TQ_LONG i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((qint64)i)); }
+#endif
+
+inline TQDataStream &TQDataStream::operator<<( TQ_UINT8 i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((TQ_INT8)i)); }
+
+inline TQDataStream &TQDataStream::operator<<( TQ_UINT16 i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((TQ_INT16)i)); }
+
+inline TQDataStream &TQDataStream::operator<<( TQ_UINT32 i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((TQ_INT32)i)); }
+
+inline TQDataStream &TQDataStream::operator<<( TQ_UINT64 i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((TQ_INT64)i)); }
+
+#if !defined(TQ_OS_WIN64)
+inline TQDataStream &TQDataStream::operator<<( TQ_ULONG i )
+{ return static_cast<TQDataStream&>(this->QDataStream::operator<<((quint64)i)); }
+#endif
+
+#else // USE_QT4
+
+#ifndef TQT_NO_DATASTREAM
+class TQ_EXPORT TQDataStream // data stream class
+{
+public:
+ TQDataStream();
+ TQDataStream( TQIODevice * );
+ TQDataStream( TQByteArray, int mode );
+ virtual ~TQDataStream();
+
+ TQIODevice *tqdevice() const;
+ void setDevice( TQIODevice * );
+ void unsetDevice();
+
+ bool atEnd() const;
+ bool eof() const;
+
+ enum ByteOrder { BigEndian, LittleEndian };
+ int byteOrder() const;
+ void setByteOrder( int );
+
+ bool isPrintableData() const;
+ void setPrintableData( bool );
+
+ int version() const;
+ void setVersion( int );
+
+ TQDataStream &operator>>( TQ_INT8 &i );
+ TQDataStream &operator>>( TQ_UINT8 &i );
+ TQDataStream &operator>>( TQ_INT16 &i );
+ TQDataStream &operator>>( TQ_UINT16 &i );
+ TQDataStream &operator>>( TQ_INT32 &i );
+ TQDataStream &operator>>( TQ_UINT32 &i );
+ TQDataStream &operator>>( TQ_INT64 &i );
+ TQDataStream &operator>>( TQ_UINT64 &i );
+#if !defined(TQ_OS_WIN64)
+ TQDataStream &operator>>( TQ_LONG &i );
+ TQDataStream &operator>>( TQ_ULONG &i );
+#endif
+
+ TQDataStream &operator>>( float &f );
+ TQDataStream &operator>>( double &f );
+ TQDataStream &operator>>( char *&str );
+
+ TQDataStream &operator<<( TQ_INT8 i );
+ TQDataStream &operator<<( TQ_UINT8 i );
+ TQDataStream &operator<<( TQ_INT16 i );
+ TQDataStream &operator<<( TQ_UINT16 i );
+ TQDataStream &operator<<( TQ_INT32 i );
+ TQDataStream &operator<<( TQ_UINT32 i );
+ TQDataStream &operator<<( TQ_INT64 i );
+ TQDataStream &operator<<( TQ_UINT64 i );
+#if !defined(TQ_OS_WIN64)
+ TQDataStream &operator<<( TQ_LONG i );
+ TQDataStream &operator<<( TQ_ULONG i );
+#endif
+ TQDataStream &operator<<( float f );
+ TQDataStream &operator<<( double f );
+ TQDataStream &operator<<( const char *str );
+
+ TQDataStream &readBytes( char *&, uint &len );
+ TQDataStream &readRawBytes( char *, uint len );
+
+ TQDataStream &writeBytes( const char *, uint len );
+ TQDataStream &writeRawBytes( const char *, uint len );
+
+private:
+ TQIODevice *dev;
+ bool owndev;
+ int byteorder;
+ bool printable;
+ bool noswap;
+ int ver;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQDataStream( const TQDataStream & );
+ TQDataStream &operator=( const TQDataStream & );
+#endif
+};
+
+
+/*****************************************************************************
+ TQDataStream inline functions
+ *****************************************************************************/
+
+inline TQIODevice *TQDataStream::tqdevice() const
+{ return dev; }
+
+inline bool TQDataStream::atEnd() const
+{ return dev ? dev->atEnd() : TRUE; }
+
+inline bool TQDataStream::eof() const
+{ return atEnd(); }
+
+inline int TQDataStream::byteOrder() const
+{ return byteorder; }
+
+inline bool TQDataStream::isPrintableData() const
+{ return printable; }
+
+inline void TQDataStream::setPrintableData( bool p )
+{ printable = p; }
+
+inline int TQDataStream::version() const
+{ return ver; }
+
+inline void TQDataStream::setVersion( int v )
+{ ver = v; }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_UINT8 &i )
+{ return *this >> (TQ_INT8&)i; }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_UINT16 &i )
+{ return *this >> (TQ_INT16&)i; }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_UINT32 &i )
+{ return *this >> (TQ_INT32&)i; }
+
+inline TQDataStream &TQDataStream::operator>>( TQ_UINT64 &i )
+{ return *this >> (TQ_INT64&)i; }
+
+#if !defined(TQ_OS_WIN64)
+inline TQDataStream &TQDataStream::operator>>( TQ_ULONG &i )
+{ return *this >> (TQ_LONG&)i; }
+#endif
+
+inline TQDataStream &TQDataStream::operator<<( TQ_UINT8 i )
+{ return *this << (TQ_INT8)i; }
+
+inline TQDataStream &TQDataStream::operator<<( TQ_UINT16 i )
+{ return *this << (TQ_INT16)i; }
+
+inline TQDataStream &TQDataStream::operator<<( TQ_UINT32 i )
+{ return *this << (TQ_INT32)i; }
+
+inline TQDataStream &TQDataStream::operator<<( TQ_UINT64 i )
+{ return *this << (TQ_INT64)i; }
+
+#if !defined(TQ_OS_WIN64)
+inline TQDataStream &TQDataStream::operator<<( TQ_ULONG i )
+{ return *this << (TQ_LONG)i; }
+#endif
+
+#endif // USE_QT4
+
+#endif // TQT_NO_DATASTREAM
+#endif // TQDATASTREAM_H
diff --git a/tqtinterface/qt4/src/tools/tqdatetime.cpp b/tqtinterface/qt4/src/tools/tqdatetime.cpp
new file mode 100644
index 0000000..4f95dd1
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdatetime.cpp
@@ -0,0 +1,2606 @@
+/****************************************************************************
+**
+** Implementation of date and time classes
+**
+** Created : 940124
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+#include "tqdatetime.h"
+#include "tqdatastream.h"
+#include "tqregexp.h"
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+#include <stdio.h>
+#ifndef TQ_OS_TEMP
+#include <time.h>
+#endif
+
+#if defined(TQ_OS_WIN32)
+#include <windows.h>
+#endif
+
+static const uint FIRST_DAY = 2361222; // Julian day for 1752-09-14
+static const int FIRST_YEAR = 1752; // ### wrong for many countries
+static const uint SECS_PER_DAY = 86400;
+static const uint MSECS_PER_DAY = 86400000;
+static const uint SECS_PER_HOUR = 3600;
+static const uint MSECS_PER_HOUR= 3600000;
+static const uint SECS_PER_MIN = 60;
+static const uint MSECS_PER_MIN = 60000;
+
+static const short monthDays[] = {
+ 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+static const char * const qt_shortMonthNames[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+#ifndef TQT_NO_DATESTRING
+/*****************************************************************************
+ Some static function used by TQDate, TQTime and TQDateTime
+ *****************************************************************************/
+
+// Replaces tokens by their value. See TQDateTime::toString() for a list of valid tokens
+static TQString getFmtString( const TQString& f, const TQTime* dt = 0, const TQDate* dd = 0, bool am_pm = FALSE )
+{
+ if ( f.isEmpty() )
+ return TQString::null;
+
+ TQString buf = f;
+
+ if ( dt ) {
+ if ( f == "h" ) {
+ if ( ( am_pm ) && ( dt->hour() > 12 ) )
+ buf = TQString::number( dt->hour() - 12 );
+ else if ( ( am_pm ) && ( dt->hour() == 0 ) )
+ buf = "12";
+ else
+ buf = TQString::number( dt->hour() );
+ } else if ( f == "hh" ) {
+ if ( ( am_pm ) && ( dt->hour() > 12 ) )
+ buf = TQT_TQSTRING(TQString::number( dt->hour() - 12 )).rightJustify( 2, '0', TRUE );
+ else if ( ( am_pm ) && ( dt->hour() == 0 ) )
+ buf = "12";
+ else
+ buf = TQT_TQSTRING(TQString::number( dt->hour() )).rightJustify( 2, '0', TRUE );
+ } else if ( f == "m" ) {
+ buf = TQString::number( dt->minute() );
+ } else if ( f == "mm" ) {
+ buf = TQT_TQSTRING(TQString::number( dt->minute() )).rightJustify( 2, '0', TRUE );
+ } else if ( f == "s" ) {
+ buf = TQString::number( dt->second() );
+ } else if ( f == "ss" ) {
+ buf = TQT_TQSTRING(TQString::number( dt->second() )).rightJustify( 2, '0', TRUE );
+ } else if ( f == "z" ) {
+ buf = TQString::number( dt->msec() );
+ } else if ( f == "zzz" ) {
+ buf = TQT_TQSTRING(TQString::number( dt->msec() )).rightJustify( 3, '0', TRUE );
+ } else if ( f == "ap" ) {
+ buf = dt->hour() < 12 ? "am" : "pm";
+ } else if ( f == "AP" ) {
+ buf = dt->hour() < 12 ? "AM" : "PM";
+ }
+ }
+
+ if ( dd ) {
+ if ( f == "d" ) {
+ buf = TQString::number( dd->day() );
+ } else if ( f == "dd" ) {
+ buf = TQT_TQSTRING(TQString::number( dd->day() )).rightJustify( 2, '0', TRUE );
+ } else if ( f == "M" ) {
+ buf = TQString::number( dd->month() );
+ } else if ( f == "MM" ) {
+ buf = TQT_TQSTRING(TQString::number( dd->month() )).rightJustify( 2, '0', TRUE );
+#ifndef TQT_NO_TEXTDATE
+ } else if ( f == "ddd" ) {
+ buf = dd->shortDayName( dd->dayOfWeek() );
+ } else if ( f == "dddd" ) {
+ buf = dd->longDayName( dd->dayOfWeek() );
+ } else if ( f == "MMM" ) {
+ buf = dd->shortMonthName( dd->month() );
+ } else if ( f == "MMMM" ) {
+ buf = dd->longMonthName( dd->month() );
+#endif
+ } else if ( f == "yy" ) {
+ buf = TQString::number( dd->year() ).right( 2 );
+ } else if ( f == "yyyy" ) {
+ buf = TQString::number( dd->year() );
+ }
+ }
+
+ return buf;
+}
+
+// Parses the format string and uses getFmtString to get the values for the tokens. Ret
+static TQString fmtDateTime( const TQString& f, const TQTime* dt = 0, const TQDate* dd = 0 )
+{
+ if ( f.isEmpty() ) {
+ return TQString::null;
+ }
+
+ if ( dt && !dt->isValid() )
+ return TQString::null;
+ if ( dd && !dd->isValid() )
+ return TQString::null;
+
+ bool ap = ( f.tqcontains( "AP" ) || f.tqcontains( "ap" ) );
+
+ TQString buf;
+ TQString frm;
+ TQChar status = '0';
+
+ for ( int i = 0; i < (int)f.length(); ++i ) {
+
+ if ( f[ i ] == status ) {
+ if ( ( ap ) && ( ( f[ i ] == 'P' ) || ( f[ i ] == 'p' ) ) )
+ status = '0';
+ frm += f[ i ];
+ } else {
+ buf += getFmtString( frm, dt, dd, ap );
+ frm = TQString::null;
+ if ( ( f[ i ] == 'h' ) || ( f[ i ] == 'm' ) || ( f[ i ] == 's' ) || ( f[ i ] == 'z' ) ) {
+ status = f[ i ];
+ frm += f[ i ];
+ } else if ( ( f[ i ] == 'd' ) || ( f[ i ] == 'M' ) || ( f[ i ] == 'y' ) ) {
+ status = f[ i ];
+ frm += f[ i ];
+ } else if ( ( ap ) && ( f[ i ] == 'A' ) ) {
+ status = 'P';
+ frm += f[ i ];
+ } else if( ( ap ) && ( f[ i ] == 'a' ) ) {
+ status = 'p';
+ frm += f[ i ];
+ } else {
+ buf += f[ i ];
+ status = '0';
+ }
+ }
+ }
+
+ buf += getFmtString( frm, dt, dd, ap );
+
+ return buf;
+}
+#endif // TQT_NO_DATESTRING
+
+/*****************************************************************************
+ TQDate member functions
+ *****************************************************************************/
+
+/*!
+ \class TQDate tqdatetime.h
+ \reentrant
+ \brief The TQDate class provides date functions.
+
+ \ingroup time
+ \mainclass
+
+ A TQDate object tqcontains a calendar date, i.e. year, month, and day
+ numbers, in the modern Western (Gregorian) calendar. It can read
+ the current date from the system clock. It provides functions for
+ comparing dates and for manipulating dates, e.g. by adding a
+ number of days or months or years.
+
+ A TQDate object is typically created either by giving the year,
+ month and day numbers explicitly, or by using the static function
+ tqcurrentDate(), which creates a TQDate object containing the system
+ clock's date. An explicit date can also be set using setYMD(). The
+ fromString() function returns a TQDate given a string and a date
+ format which is used to interpret the date within the string.
+
+ The year(), month(), and day() functions provide access to the
+ year, month, and day numbers. Also, dayOfWeek() and dayOfYear()
+ functions are provided. The same information is provided in
+ textual format by the toString(), shortDayName(), longDayName(),
+ shortMonthName() and longMonthName() functions.
+
+ TQDate provides a full set of operators to compare two TQDate
+ objects where smaller means earlier and larger means later.
+
+ You can increment (or decrement) a date by a given number of days
+ using addDays(). Similarly you can use addMonths() and addYears().
+ The daysTo() function returns the number of days between two
+ dates.
+
+ The daysInMonth() and daysInYear() functions return how many days
+ there are in this date's month and year, respectively. The
+ leapYear() function indicates whether this date is in a leap year.
+
+ Note that TQDate should not be used for date calculations for dates
+ prior to the introduction of the Gregorian calendar. This calendar
+ was adopted by England from the 14<sup><small>th</small></sup>
+ September 1752 (hence this is the earliest valid TQDate), and
+ subsequently by most other Western countries, until 1923.
+
+ The end of time is reached around the year 8000, by which time we
+ expect TQt to be obsolete.
+
+ \sa TQTime TQDateTime TQDateEdit TQDateTimeEdit
+*/
+
+/*!
+ \enum TQt::DateFormat
+
+ \value TextDate (default) TQt format
+ \value ISODate ISO 8601 extended format (YYYY-MM-DD, or with time,
+ YYYY-MM-DDTHH:MM:SS)
+ \value LocalDate locale dependent format
+*/
+
+
+/*!
+ \enum TQt::TimeSpec
+
+ \value LocalTime Locale dependent time (Timezones and Daylight Savings Time)
+ \value UTC Coordinated Universal Time, tqreplaces Greenwich Time
+*/
+
+/*!
+ \fn TQDate::TQDate()
+
+ Constructs a null date. Null dates are invalid.
+
+ \sa isNull(), isValid()
+*/
+
+
+/*!
+ Constructs a date with year \a y, month \a m and day \a d.
+
+ \a y must be in the range 1752..8000, \a m must be in the range
+ 1..12, and \a d must be in the range 1..31.
+
+ \warning If \a y is in the range 0..99, it is interpreted as
+ 1900..1999.
+
+ \sa isValid()
+*/
+
+TQDate::TQDate( int y, int m, int d )
+{
+ jd = 0;
+ setYMD( y, m, d );
+}
+
+
+/*!
+ \fn bool TQDate::isNull() const
+
+ Returns TRUE if the date is null; otherwise returns FALSE. A null
+ date is invalid.
+
+ \sa isValid()
+*/
+
+
+/*!
+ Returns TRUE if this date is valid; otherwise returns FALSE.
+
+ \sa isNull()
+*/
+
+bool TQDate::isValid() const
+{
+ return jd >= FIRST_DAY;
+}
+
+
+/*!
+ Returns the year (1752..8000) of this date.
+
+ \sa month(), day()
+*/
+
+int TQDate::year() const
+{
+ int y, m, d;
+ julianToGregorian( jd, y, m, d );
+ return y;
+}
+
+/*!
+ Returns the month (January=1..December=12) of this date.
+
+ \sa year(), day()
+*/
+
+int TQDate::month() const
+{
+ int y, m, d;
+ julianToGregorian( jd, y, m, d );
+ return m;
+}
+
+/*!
+ Returns the day of the month (1..31) of this date.
+
+ \sa year(), month(), dayOfWeek()
+*/
+
+int TQDate::day() const
+{
+ int y, m, d;
+ julianToGregorian( jd, y, m, d );
+ return d;
+}
+
+/*!
+ Returns the weekday (Monday=1..Sunday=7) for this date.
+
+ \sa day(), dayOfYear()
+*/
+
+int TQDate::dayOfWeek() const
+{
+ return ( jd % 7 ) + 1;
+}
+
+/*!
+ Returns the day of the year (1..365) for this date.
+
+ \sa day(), dayOfWeek()
+*/
+
+int TQDate::dayOfYear() const
+{
+ return jd - gregorianToJulian(year(), 1, 1) + 1;
+}
+
+/*!
+ Returns the number of days in the month (28..31) for this date.
+
+ \sa day(), daysInYear()
+*/
+
+int TQDate::daysInMonth() const
+{
+ int y, m, d;
+ julianToGregorian( jd, y, m, d );
+ if ( m == 2 && leapYear(y) )
+ return 29;
+ else
+ return monthDays[m];
+}
+
+/*!
+ Returns the number of days in the year (365 or 366) for this date.
+
+ \sa day(), daysInMonth()
+*/
+
+int TQDate::daysInYear() const
+{
+ int y, m, d;
+ julianToGregorian( jd, y, m, d );
+ return leapYear( y ) ? 366 : 365;
+}
+
+/*!
+ Returns the week number (1 to 53), and stores the year in \a
+ *yearNumber unless \a yearNumber is null (the default).
+
+ Returns 0 if the date is invalid.
+
+ In accordance with ISO 8601, weeks start on Monday and the first
+ Thursday of a year is always in week 1 of that year. Most years
+ have 52 weeks, but some have 53.
+
+ \a *yearNumber is not always the same as year(). For example, 1
+ January 2000 has week number 52 in the year 1999, and 31 December
+ 2002 has week number 1 in the year 2003.
+
+ \legalese
+
+ Copyright (c) 1989 The Regents of the University of California.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms are permitted
+ provided that the above copyright notice and this paragraph are
+ duplicated in all such forms and that any documentation,
+ advertising materials, and other materials related to such
+ distribution and use acknowledge that the software was developed
+ by the University of California, Berkeley. The name of the
+ University may not be used to endorse or promote products derived
+ from this software without specific prior written permission.
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+
+ \sa isValid()
+*/
+
+int TQDate::weekNumber( int *yearNumber ) const
+{
+ if ( !isValid() )
+ return 0;
+
+ int year = TQDate::year();
+ int yday = dayOfYear() - 1;
+ int wday = dayOfWeek();
+ if (wday == 7)
+ wday = 0;
+ int w;
+
+ for (;;) {
+ int len;
+ int bot;
+ int top;
+
+ len = leapYear(year) ? 366 : 365;
+ /*
+ ** What yday (-3 ... 3) does
+ ** the ISO year begin on?
+ */
+ bot = ((yday + 11 - wday) % 7) - 3;
+ /*
+ ** What yday does the NEXT
+ ** ISO year begin on?
+ */
+ top = bot - (len % 7);
+ if (top < -3)
+ top += 7;
+ top += len;
+ if (yday >= top) {
+ ++year;
+ w = 1;
+ break;
+ }
+ if (yday >= bot) {
+ w = 1 + ((yday - bot) / 7);
+ break;
+ }
+ --year;
+ yday += leapYear(year) ? 366 : 365;
+ }
+ if (yearNumber != 0)
+ *yearNumber = year;
+ return w;
+}
+
+/*!
+ \fn TQString TQDate::monthName( int month )
+ \obsolete
+
+ Use shortMonthName() instead.
+*/
+#ifndef TQT_NO_TEXTDATE
+/*!
+ Returns the name of the \a month.
+
+ 1 = "Jan", 2 = "Feb", ... 12 = "Dec"
+
+ The month names will be localized according to the system's locale
+ settings.
+
+ \sa toString(), longMonthName(), shortDayName(), longDayName()
+*/
+
+TQString TQDate::shortMonthName( int month )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( month < 1 || month > 12 ) {
+ qWarning( "TQDate::shortMonthName: Parameter out ouf range" );
+ month = 1;
+ }
+#endif
+#ifndef TQ_WS_WIN
+ char buffer[255];
+ tm tt;
+ memset( &tt, 0, sizeof( tm ) );
+ tt.tm_mon = month - 1;
+ if ( strftime( buffer, sizeof( buffer ), "%b", &tt ) )
+ return TQString::fromLocal8Bit( buffer );
+#else
+ SYSTEMTIME st;
+ memset( &st, 0, sizeof(SYSTEMTIME) );
+ st.wYear = 2000;
+ st.wMonth = month;
+ st.wDay = 1;
+ const wchar_t mmm_t[] = L"MMM"; // workaround for Borland
+ TQT_WA( {
+ TCHAR buf[255];
+ if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, mmm_t, buf, 255 ) )
+ return TQString::fromUcs2( (ushort*)buf );
+ } , {
+ char buf[255];
+ if ( GetDateFormatA( LOCALE_USER_DEFAULT, 0, &st, "MMM", (char*)&buf, 255 ) )
+ return TQString::fromLocal8Bit( buf );
+ } );
+#endif
+ return TQString::null;
+}
+
+/*!
+ Returns the long name of the \a month.
+
+ 1 = "January", 2 = "February", ... 12 = "December"
+
+ The month names will be localized according to the system's locale
+ settings.
+
+ \sa toString(), shortMonthName(), shortDayName(), longDayName()
+*/
+
+TQString TQDate::longMonthName( int month )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( month < 1 || month > 12 ) {
+ qWarning( "TQDate::longMonthName: Parameter out ouf range" );
+ month = 1;
+ }
+#endif
+#ifndef TQ_WS_WIN
+ char buffer[255];
+ tm tt;
+ memset( &tt, 0, sizeof( tm ) );
+ tt.tm_mon = month - 1;
+ if ( strftime( buffer, sizeof( buffer ), "%B", &tt ) )
+ return TQString::fromLocal8Bit( buffer );
+#else
+ SYSTEMTIME st;
+ memset( &st, 0, sizeof(SYSTEMTIME) );
+ st.wYear = 2000;
+ st.wMonth = month;
+ st.wDay = 1 ;
+ const wchar_t mmmm_t[] = L"MMMM"; // workaround for Borland
+ TQT_WA( {
+ TCHAR buf[255];
+ if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, mmmm_t, buf, 255 ) )
+ return TQString::fromUcs2( (ushort*)buf );
+ } , {
+ char buf[255];
+ if ( GetDateFormatA( LOCALE_USER_DEFAULT, 0, &st, "MMMM", (char*)&buf, 255 ) )
+ return TQString::fromLocal8Bit( buf );
+ } )
+#endif
+
+ return TQString::null;
+}
+
+/*!
+ \fn TQString TQDate::dayName( int weekday )
+ \obsolete
+
+ Use shortDayName() instead.
+*/
+
+/*!
+ Returns the name of the \a weekday.
+
+ 1 = "Mon", 2 = "Tue", ... 7 = "Sun"
+
+ The day names will be localized according to the system's locale
+ settings.
+
+ \sa toString(), shortMonthName(), longMonthName(), longDayName()
+*/
+
+TQString TQDate::shortDayName( int weekday )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( weekday < 1 || weekday > 7 ) {
+ qWarning( "TQDate::shortDayName: Parameter out of range" );
+ weekday = 1;
+ }
+#endif
+#ifndef TQ_WS_WIN
+ char buffer[255];
+ tm tt;
+ memset( &tt, 0, sizeof( tm ) );
+ tt.tm_wday = ( weekday == 7 ) ? 0 : weekday;
+ if ( strftime( buffer, sizeof( buffer ), "%a", &tt ) )
+ return TQString::fromLocal8Bit( buffer );
+#else
+ SYSTEMTIME st;
+ memset( &st, 0, sizeof(SYSTEMTIME) );
+ st.wYear = 2001;
+ st.wMonth = 10;
+ st.wDayOfWeek = ( weekday == 7 ) ? 0 : weekday;
+ st.wDay = 21 + st.wDayOfWeek;
+ const wchar_t ddd_t[] = L"ddd"; // workaround for Borland
+ TQT_WA( {
+ TCHAR buf[255];
+ if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, ddd_t, buf, 255 ) )
+ return TQString::fromUcs2( (ushort*)buf );
+ } , {
+ char buf[255];
+ if ( GetDateFormatA( LOCALE_USER_DEFAULT, 0, &st, "ddd", (char*)&buf, 255 ) )
+ return TQString::fromLocal8Bit( buf );
+ } );
+#endif
+
+ return TQString::null;
+}
+
+/*!
+ Returns the long name of the \a weekday.
+
+ 1 = "Monday", 2 = "Tuesday", ... 7 = "Sunday"
+
+ The day names will be localized according to the system's locale
+ settings.
+
+ \sa toString(), shortDayName(), shortMonthName(), longMonthName()
+*/
+
+TQString TQDate::longDayName( int weekday )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( weekday < 1 || weekday > 7 ) {
+ qWarning( "TQDate::longDayName: Parameter out of range" );
+ weekday = 1;
+ }
+#endif
+#ifndef TQ_WS_WIN
+ char buffer[255];
+ tm tt;
+ memset( &tt, 0, sizeof( tm ) );
+ tt.tm_wday = ( weekday == 7 ) ? 0 : weekday;
+ if ( strftime( buffer, sizeof( buffer ), "%A", &tt ) )
+ return TQString::fromLocal8Bit( buffer );
+#else
+ SYSTEMTIME st;
+ memset( &st, 0, sizeof(SYSTEMTIME) );
+ st.wYear = 2001;
+ st.wMonth = 10;
+ st.wDayOfWeek = ( weekday == 7 ) ? 0 : weekday;
+ st.wDay = 21 + st.wDayOfWeek;
+ const wchar_t dddd_t[] = L"dddd"; // workaround for Borland
+ TQT_WA( {
+ TCHAR buf[255];
+ if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, dddd_t, buf, 255 ) )
+ return TQString::fromUcs2( (ushort*)buf );
+ } , {
+ char buf[255];
+ if ( GetDateFormatA( LOCALE_USER_DEFAULT, 0, &st, "dddd", (char*)&buf, 255 ) )
+ return TQString::fromLocal8Bit( buf );
+ } );
+#endif
+
+ return TQString::null;
+}
+#endif //TQT_NO_TEXTDATE
+
+#ifndef TQT_NO_DATESTRING
+
+#if !defined(TQT_NO_SPRINTF)
+/*!
+ \overload
+
+ Returns the date as a string. The \a f parameter determines the
+ format of the string.
+
+ If \a f is \c TQt::TextDate, the string format is "Sat May 20 1995"
+ (using the shortDayName() and shortMonthName() functions to
+ generate the string, so the day and month names are locale
+ specific).
+
+ If \a f is \c TQt::ISODate, the string format corresponds to the
+ ISO 8601 specification for representations of dates, which is
+ YYYY-MM-DD where YYYY is the year, MM is the month of the year
+ (between 01 and 12), and DD is the day of the month between 01 and
+ 31.
+
+ If \a f is \c TQt::LocalDate, the string format depends on the
+ locale settings of the system.
+
+ If the date is an invalid date, then TQString::null will be returned.
+
+ \sa shortDayName(), shortMonthName()
+*/
+TQString TQDate::toString( TQt::DateFormat f ) const
+{
+ if ( !isValid() )
+ return TQString::null;
+ int y, m, d;
+ julianToGregorian( jd, y, m, d );
+ switch ( f ) {
+ case TQt::LocalDate:
+ {
+#ifndef TQ_WS_WIN
+ tm tt;
+ memset( &tt, 0, sizeof( tm ) );
+ char buf[255];
+ tt.tm_mday = day();
+ tt.tm_mon = month() - 1;
+ tt.tm_year = year() - 1900;
+
+ static const char * avoidEgcsWarning = "%x";
+ if ( strftime( buf, sizeof(buf), avoidEgcsWarning, &tt ) )
+ return TQString::fromLocal8Bit( buf );
+#else
+ SYSTEMTIME st;
+ memset( &st, 0, sizeof(SYSTEMTIME) );
+ st.wYear = year();
+ st.wMonth = month();
+ st.wDay = day();
+ TQT_WA( {
+ TCHAR buf[255];
+ if ( GetDateFormat( LOCALE_USER_DEFAULT, 0, &st, 0, buf, 255 ) )
+ return TQString::fromUcs2( (ushort*)buf );
+ } , {
+ char buf[255];
+ if ( GetDateFormatA( LOCALE_USER_DEFAULT, 0, &st, 0, (char*)&buf, 255 ) )
+ return TQString::fromLocal8Bit( buf );
+ } );
+#endif
+ return TQString::null;
+ }
+ default:
+#ifndef TQT_NO_TEXTDATE
+ case TQt::TextDate:
+ {
+ TQString buf = shortDayName( dayOfWeek() );
+ buf += ' ';
+ buf += shortMonthName( m );
+ TQString t;
+ t.sprintf( " %d %d", d, y );
+ buf += t;
+ return buf;
+ }
+#endif
+ case TQt::ISODate:
+ {
+ TQString month( TQT_TQSTRING(TQString::number( m )).rightJustify( 2, '0' ) );
+ TQString day( TQT_TQSTRING(TQString::number( d )).rightJustify( 2, '0' ) );
+ return TQString::number( y ) + "-" + month + "-" + day;
+ }
+ }
+}
+#endif //TQT_NO_SPRINTF
+
+/*!
+ Returns the date as a string. The \a format parameter determines
+ the format of the result string.
+
+ These expressions may be used:
+
+ \table
+ \header \i Expression \i Output
+ \row \i d \i the day as number without a leading zero (1-31)
+ \row \i dd \i the day as number with a leading zero (01-31)
+ \row \i ddd
+ \i the abbreviated localized day name (e.g. 'Mon'..'Sun').
+ Uses TQDate::shortDayName().
+ \row \i dddd
+ \i the long localized day name (e.g. 'Monday'..'Sunday').
+ Uses TQDate::longDayName().
+ \row \i M \i the month as number without a leading zero (1-12)
+ \row \i MM \i the month as number with a leading zero (01-12)
+ \row \i MMM
+ \i the abbreviated localized month name (e.g. 'Jan'..'Dec').
+ Uses TQDate::shortMonthName().
+ \row \i MMMM
+ \i the long localized month name (e.g. 'January'..'December').
+ Uses TQDate::longMonthName().
+ \row \i yy \i the year as two digit number (00-99)
+ \row \i yyyy \i the year as four digit number (1752-8000)
+ \endtable
+
+ All other input characters will be ignored.
+
+ Example format strings (assuming that the TQDate is the
+ 20<sup><small>th</small></sup> July 1969):
+ \table
+ \header \i Format \i Result
+ \row \i dd.MM.yyyy \i11 20.07.1969
+ \row \i ddd MMMM d yy \i11 Sun July 20 69
+ \endtable
+
+ If the date is an invalid date, then TQString::null will be returned.
+
+ \sa TQDateTime::toString() TQTime::toString()
+
+*/
+TQString TQDate::toString( const TQString& format ) const
+{
+ return fmtDateTime( format, 0, this );
+}
+#endif //TQT_NO_DATESTRING
+
+/*!
+ Sets the date's year \a y, month \a m and day \a d.
+
+ \a y must be in the range 1752..8000, \a m must be in the range
+ 1..12, and \a d must be in the range 1..31.
+
+ \warning If \a y is in the range 0..99, it is interpreted as
+ 1900..1999.
+
+ Returns TRUE if the date is valid; otherwise returns FALSE.
+*/
+
+bool TQDate::setYMD( int y, int m, int d )
+{
+ if ( year() == y && month() == m && day() == d )
+ return isValid();
+ if ( !isValid(y,m,d) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQDate::setYMD: Invalid date %04d-%02d-%02d", y, m, d );
+#endif
+ return FALSE;
+ }
+ jd = gregorianToJulian( y, m, d );
+ return TRUE;
+}
+
+/*!
+ Returns a TQDate object containing a date \a ndays later than the
+ date of this object (or earlier if \a ndays is negative).
+
+ \sa addMonths() addYears() daysTo()
+*/
+
+TQDate TQDate::addDays( int ndays ) const
+{
+ TQDate d;
+ d.jd = jd + ndays;
+ return d;
+}
+
+/*!
+ Returns a TQDate object containing a date \a nmonths later than the
+ date of this object (or earlier if \a nmonths is negative).
+
+ \sa addDays() addYears()
+*/
+
+TQDate TQDate::addMonths( int nmonths ) const
+{
+ int y, m, d;
+ julianToGregorian( jd, y, m, d );
+
+ while ( nmonths != 0 ) {
+ if ( nmonths < 0 && nmonths + 12 <= 0 ) {
+ y--;
+ nmonths+=12;
+ } else if ( nmonths < 0 ) {
+ m+= nmonths;
+ nmonths = 0;
+ if ( m <= 0 ) {
+ --y;
+ m+=12;
+ }
+ } else if ( nmonths - 12 >= 0 ) {
+ y++;
+ nmonths-=12;
+ } else if ( m == 12 ) {
+ y++;
+ m = 0;
+ } else {
+ m+= nmonths;
+ nmonths = 0;
+ if ( m > 12 ) {
+ ++y;
+ m -= 12;
+ }
+ }
+ }
+
+ TQDate tmp(y,m,1);
+
+ if( d > tmp.daysInMonth() )
+ d = tmp.daysInMonth();
+
+ TQDate date(y, m, d);
+ return date;
+
+}
+
+/*!
+ Returns a TQDate object containing a date \a nyears later than the
+ date of this object (or earlier if \a nyears is negative).
+
+ \sa addDays(), addMonths()
+*/
+
+TQDate TQDate::addYears( int nyears ) const
+{
+ int y, m, d;
+ julianToGregorian( jd, y, m, d );
+ y += nyears;
+
+ TQDate tmp(y,m,1);
+
+ if( d > tmp.daysInMonth() )
+ d = tmp.daysInMonth();
+
+ TQDate date(y, m, d);
+ return date;
+}
+
+
+
+/*!
+ Returns the number of days from this date to \a d (which is
+ negative if \a d is earlier than this date).
+
+ Example:
+ \code
+ TQDate d1( 1995, 5, 17 ); // May 17th 1995
+ TQDate d2( 1995, 5, 20 ); // May 20th 1995
+ d1.daysTo( d2 ); // returns 3
+ d2.daysTo( d1 ); // returns -3
+ \endcode
+
+ \sa addDays()
+*/
+
+int TQDate::daysTo( const TQDate &d ) const
+{
+ return d.jd - jd;
+}
+
+
+/*!
+ \fn bool TQDate::operator==( const TQDate &d ) const
+
+ Returns TRUE if this date is equal to \a d; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQDate::operator!=( const TQDate &d ) const
+
+ Returns TRUE if this date is different from \a d; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQDate::operator<( const TQDate &d ) const
+
+ Returns TRUE if this date is earlier than \a d, otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQDate::operator<=( const TQDate &d ) const
+
+ Returns TRUE if this date is earlier than or equal to \a d,
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQDate::operator>( const TQDate &d ) const
+
+ Returns TRUE if this date is later than \a d, otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQDate::operator>=( const TQDate &d ) const
+
+ Returns TRUE if this date is later than or equal to \a d,
+ otherwise returns FALSE.
+*/
+
+/*!
+ \overload
+ Returns the current date, as reported by the system clock.
+
+ \sa TQTime::currentTime(), TQDateTime::tqcurrentDateTime()
+*/
+
+TQDate TQDate::tqcurrentDate()
+{
+ return tqcurrentDate( TQt::LocalTime );
+}
+
+/*!
+ Returns the current date, as reported by the system clock, for the
+ TimeSpec \a ts. The default TimeSpec is LocalTime.
+
+ \sa TQTime::currentTime(), TQDateTime::tqcurrentDateTime(), TQt::TimeSpec
+*/
+TQDate TQDate::tqcurrentDate( TQt::TimeSpec ts )
+{
+ TQDate d;
+#if defined(TQ_OS_WIN32)
+ SYSTEMTIME t;
+ memset( &t, 0, sizeof(SYSTEMTIME) );
+ if ( ts == TQt::LocalTime )
+ GetLocalTime( &t );
+ else
+ GetSystemTime( &t );
+ d.jd = gregorianToJulian( t.wYear, t.wMonth, t.wDay );
+#else
+ // posix compliant system
+ time_t ltime;
+ time( &ltime );
+ tm *t;
+
+# if defined(TQT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant versions of localtime() and gmtime() where available
+ tm res;
+ if ( ts == TQt::LocalTime )
+ t = localtime_r( &ltime, &res );
+ else
+ t = gmtime_r( &ltime, &res );
+# else
+ if ( ts == TQt::LocalTime )
+ t = localtime( &ltime );
+ else
+ t = gmtime( &ltime );
+# endif // TQT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
+
+ d.jd = gregorianToJulian( t->tm_year + 1900, t->tm_mon + 1, t->tm_mday );
+#endif
+ return d;
+}
+
+#ifndef TQT_NO_DATESTRING
+/*!
+ Returns the TQDate represented by the string \a s, using the format
+ \a f, or an invalid date if the string cannot be parsed.
+
+ Note for \c TQt::TextDate: It is recommended that you use the
+ English short month names (e.g. "Jan"). Although localized month
+ names can also be used, they depend on the user's locale settings.
+
+ \warning \c TQt::LocalDate cannot be used here.
+*/
+TQDate TQDate::fromString( const TQString& s, TQt::DateFormat f )
+{
+ if ( ( s.isEmpty() ) || ( f == TQt::LocalDate ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQDate::fromString: Parameter out of range" );
+#endif
+ TQDate d;
+ d.jd = 0;
+ return d;
+ }
+ switch ( f ) {
+ case TQt::ISODate:
+ {
+ int year( s.mid( 0, 4 ).toInt() );
+ int month( s.mid( 5, 2 ).toInt() );
+ int day( s.mid( 8, 2 ).toInt() );
+ if ( year && month && day )
+ return TQDate( year, month, day );
+ }
+ break;
+ default:
+#ifndef TQT_NO_TEXTDATE
+ case TQt::TextDate:
+ {
+ /*
+ This will fail gracefully if the input string doesn't
+ contain any space.
+ */
+ int monthPos = s.tqfind( ' ' ) + 1;
+ int dayPos = s.tqfind( ' ', monthPos ) + 1;
+
+ TQString monthName( s.mid(monthPos, dayPos - monthPos - 1) );
+ int month = -1;
+
+ // try English names first
+ for ( int i = 0; i < 12; i++ ) {
+ if ( monthName == qt_shortMonthNames[i] ) {
+ month = i + 1;
+ break;
+ }
+ }
+
+ // try the localized names
+ if ( month == -1 ) {
+ for ( int i = 0; i < 12; i++ ) {
+ if ( monthName == shortMonthName( i + 1 ) ) {
+ month = i + 1;
+ break;
+ }
+ }
+ }
+#if defined(TQT_CHECK_RANGE)
+ if ( month < 1 || month > 12 ) {
+ qWarning( "TQDate::fromString: Parameter out of range" );
+ TQDate d;
+ d.jd = 0;
+ return d;
+ }
+#endif
+ int day = TQT_TQSTRING(s.mid( dayPos, 2 )).stripWhiteSpace().toInt();
+ int year = s.right( 4 ).toInt();
+ return TQDate( year, month, day );
+ }
+#else
+ break;
+#endif
+ }
+ return TQDate();
+}
+#endif //TQT_NO_DATESTRING
+
+/*!
+ \overload
+
+ Returns TRUE if the specified date (year \a y, month \a m and day
+ \a d) is valid; otherwise returns FALSE.
+
+ Example:
+ \code
+ TQDate::isValid( 2002, 5, 17 ); // TRUE May 17th 2002 is valid
+ TQDate::isValid( 2002, 2, 30 ); // FALSE Feb 30th does not exist
+ TQDate::isValid( 2004, 2, 29 ); // TRUE 2004 is a leap year
+ TQDate::isValid( 1202, 6, 6 ); // FALSE 1202 is pre-Gregorian
+ \endcode
+
+ \warning A \a y value in the range 00..99 is interpreted as
+ 1900..1999.
+
+ \sa isNull(), setYMD()
+*/
+
+bool TQDate::isValid( int y, int m, int d )
+{
+ if ( y >= 0 && y <= 99 )
+ y += 1900;
+ else if ( y < FIRST_YEAR || (y == FIRST_YEAR && (m < 9 ||
+ (m == 9 && d < 14))) )
+ return FALSE;
+ return (d > 0 && m > 0 && m <= 12) &&
+ (d <= monthDays[m] || (d == 29 && m == 2 && leapYear(y)));
+}
+
+/*!
+ Returns TRUE if the specified year \a y is a leap year; otherwise
+ returns FALSE.
+*/
+
+bool TQDate::leapYear( int y )
+{
+ return y % 4 == 0 && y % 100 != 0 || y % 400 == 0;
+}
+
+/*!
+ \internal
+ Converts a Gregorian date to a Julian day.
+ This algorithm is taken from Communications of the ACM, Vol 6, No 8.
+ \sa julianToGregorian()
+*/
+
+uint TQDate::gregorianToJulian( int y, int m, int d )
+{
+ uint c, ya;
+ if ( y <= 99 )
+ y += 1900;
+ if ( m > 2 ) {
+ m -= 3;
+ } else {
+ m += 9;
+ y--;
+ }
+ c = y; // NOTE: Sym C++ 6.0 bug
+ c /= 100;
+ ya = y - 100*c;
+ return 1721119 + d + (146097*c)/4 + (1461*ya)/4 + (153*m+2)/5;
+}
+
+/*!
+ \internal
+ Converts a Julian day to a Gregorian date.
+ This algorithm is taken from Communications of the ACM, Vol 6, No 8.
+ \sa gregorianToJulian()
+*/
+
+void TQDate::julianToGregorian( uint jd, int &y, int &m, int &d )
+{
+ uint x;
+ uint j = jd - 1721119;
+ y = (j*4 - 1)/146097;
+ j = j*4 - 146097*y - 1;
+ x = j/4;
+ j = (x*4 + 3) / 1461;
+ y = 100*y + j;
+ x = (x*4) + 3 - 1461*j;
+ x = (x + 4)/4;
+ m = (5*x - 3)/153;
+ x = 5*x - 3 - 153*m;
+ d = (x + 5)/5;
+ if ( m < 10 ) {
+ m += 3;
+ } else {
+ m -= 9;
+ y++;
+ }
+}
+
+
+/*****************************************************************************
+ TQTime member functions
+ *****************************************************************************/
+
+/*!
+ \class TQTime tqdatetime.h
+ \reentrant
+
+ \brief The TQTime class provides clock time functions.
+
+ \ingroup time
+ \mainclass
+
+ A TQTime object tqcontains a clock time, i.e. the number of hours,
+ minutes, seconds, and milliseconds since midnight. It can read the
+ current time from the system clock and measure a span of elapsed
+ time. It provides functions for comparing times and for
+ manipulating a time by adding a number of (milli)seconds.
+
+ TQTime uses the 24-hour clock format; it has no concept of AM/PM.
+ It operates in local time; it knows nothing about time zones or
+ daylight savings time.
+
+ A TQTime object is typically created either by giving the number of
+ hours, minutes, seconds, and milliseconds explicitly, or by using
+ the static function currentTime(), which creates a TQTime object
+ that tqcontains the system's clock time. Note that the accuracy
+ depends on the accuracy of the underlying operating system; not
+ all systems provide 1-millisecond accuracy.
+
+ The hour(), minute(), second(), and msec() functions provide
+ access to the number of hours, minutes, seconds, and milliseconds
+ of the time. The same information is provided in textual format by
+ the toString() function.
+
+ TQTime provides a full set of operators to compare two TQTime
+ objects. One time is considered smaller than another if it is
+ earlier than the other.
+
+ The time a given number of seconds or milliseconds later than a
+ given time can be found using the addSecs() or addMSecs()
+ functions. Correspondingly, the number of (milli)seconds between
+ two times can be found using the secsTo() or msecsTo() functions.
+
+ TQTime can be used to measure a span of elapsed time using the
+ start(), restart(), and elapsed() functions.
+
+ \sa TQDate, TQDateTime
+*/
+
+/*!
+ \fn TQTime::TQTime()
+
+ Constructs the time 0 hours, minutes, seconds and milliseconds,
+ i.e. 00:00:00.000 (midnight). This is a valid time.
+
+ \sa isValid()
+*/
+
+/*!
+ Constructs a time with hour \a h, minute \a m, seconds \a s and
+ milliseconds \a ms.
+
+ \a h must be in the range 0..23, \a m and \a s must be in the
+ range 0..59, and \a ms must be in the range 0..999.
+
+ \sa isValid()
+*/
+
+TQTime::TQTime( int h, int m, int s, int ms )
+{
+ setHMS( h, m, s, ms );
+}
+
+
+/*!
+ \fn bool TQTime::isNull() const
+
+ Returns TRUE if the time is equal to 00:00:00.000; otherwise
+ returns FALSE. A null time is valid.
+
+ \sa isValid()
+*/
+
+/*!
+ Returns TRUE if the time is valid; otherwise returns FALSE. The
+ time 23:30:55.746 is valid, whereas 24:12:30 is invalid.
+
+ \sa isNull()
+*/
+
+bool TQTime::isValid() const
+{
+ return ds < MSECS_PER_DAY;
+}
+
+
+/*!
+ Returns the hour part (0..23) of the time.
+*/
+
+int TQTime::hour() const
+{
+ return ds / MSECS_PER_HOUR;
+}
+
+/*!
+ Returns the minute part (0..59) of the time.
+*/
+
+int TQTime::minute() const
+{
+ return (ds % MSECS_PER_HOUR)/MSECS_PER_MIN;
+}
+
+/*!
+ Returns the second part (0..59) of the time.
+*/
+
+int TQTime::second() const
+{
+ return (ds / 1000)%SECS_PER_MIN;
+}
+
+/*!
+ Returns the millisecond part (0..999) of the time.
+*/
+
+int TQTime::msec() const
+{
+ return ds % 1000;
+}
+
+#ifndef TQT_NO_DATESTRING
+#ifndef TQT_NO_SPRINTF
+/*!
+ \overload
+
+ Returns the time as a string. Milliseconds are not included. The
+ \a f parameter determines the format of the string.
+
+ If \a f is \c TQt::TextDate, the string format is HH:MM:SS; e.g. 1
+ second before midnight would be "23:59:59".
+
+ If \a f is \c TQt::ISODate, the string format corresponds to the
+ ISO 8601 extended specification for representations of dates,
+ which is also HH:MM:SS.
+
+ If \a f is TQt::LocalDate, the string format depends on the locale
+ settings of the system.
+
+ If the time is an invalid time, then TQString::null will be returned.
+*/
+
+TQString TQTime::toString( TQt::DateFormat f ) const
+{
+ if ( !isValid() )
+ return TQString::null;
+
+ switch ( f ) {
+ case TQt::LocalDate:
+ {
+#ifndef TQ_WS_WIN
+ tm tt;
+ memset( &tt, 0, sizeof( tm ) );
+ char buf[255];
+ tt.tm_sec = second();
+ tt.tm_min = minute();
+ tt.tm_hour = hour();
+ if ( strftime( buf, sizeof(buf), "%X", &tt ) )
+ return TQString::fromLocal8Bit( buf );
+#else
+ SYSTEMTIME st;
+ memset( &st, 0, sizeof(SYSTEMTIME) );
+ st.wHour = hour();
+ st.wMinute = minute();
+ st.wSecond = second();
+ st.wMilliseconds = 0;
+ TQT_WA( {
+ TCHAR buf[255];
+ if ( GetTimeFormat( LOCALE_USER_DEFAULT, 0, &st, 0, buf, 255 ) )
+ return TQString::fromUcs2( (ushort*)buf );
+ } , {
+ char buf[255];
+ if ( GetTimeFormatA( LOCALE_USER_DEFAULT, 0, &st, 0, (char*)&buf, 255 ) )
+ return TQString::fromLocal8Bit( buf );
+ } );
+#endif
+ return TQString::null;
+ }
+ default:
+ case TQt::ISODate:
+ case TQt::TextDate:
+ TQString buf;
+ buf.sprintf( "%.2d:%.2d:%.2d", hour(), minute(), second() );
+ return buf;
+ }
+}
+#endif
+
+/*!
+ Returns the time as a string. The \a format parameter determines
+ the format of the result string.
+
+ These expressions may be used:
+
+ \table
+ \header \i Expression \i Output
+ \row \i h
+ \i the hour without a leading zero (0..23 or 1..12 if AM/PM display)
+ \row \i hh
+ \i the hour with a leading zero (00..23 or 01..12 if AM/PM display)
+ \row \i m \i the minute without a leading zero (0..59)
+ \row \i mm \i the minute with a leading zero (00..59)
+ \row \i s \i the second whithout a leading zero (0..59)
+ \row \i ss \i the second whith a leading zero (00..59)
+ \row \i z \i the milliseconds without leading zeroes (0..999)
+ \row \i zzz \i the milliseconds with leading zeroes (000..999)
+ \row \i AP
+ \i use AM/PM display. \e AP will be tqreplaced by either "AM" or "PM".
+ \row \i ap
+ \i use am/pm display. \e ap will be tqreplaced by either "am" or "pm".
+ \endtable
+
+ All other input characters will be ignored.
+
+ Example format strings (assuming that the TQTime is 14:13:09.042)
+
+ \table
+ \header \i Format \i Result
+ \row \i hh:mm:ss.zzz \i11 14:13:09.042
+ \row \i h:m:s ap \i11 2:13:9 pm
+ \endtable
+
+ If the time is an invalid time, then TQString::null will be returned.
+
+ \sa TQDate::toString() TQDateTime::toString()
+*/
+TQString TQTime::toString( const TQString& format ) const
+{
+ return fmtDateTime( format, this, 0 );
+}
+#endif //TQT_NO_DATESTRING
+/*!
+ Sets the time to hour \a h, minute \a m, seconds \a s and
+ milliseconds \a ms.
+
+ \a h must be in the range 0..23, \a m and \a s must be in the
+ range 0..59, and \a ms must be in the range 0..999. Returns TRUE
+ if the set time is valid; otherwise returns FALSE.
+
+ \sa isValid()
+*/
+
+bool TQTime::setHMS( int h, int m, int s, int ms )
+{
+ if ( !isValid(h,m,s,ms) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQTime::setHMS Invalid time %02d:%02d:%02d.%03d", h, m, s,
+ ms );
+#endif
+ ds = MSECS_PER_DAY; // make this invalid
+ return FALSE;
+ }
+ ds = (h*SECS_PER_HOUR + m*SECS_PER_MIN + s)*1000 + ms;
+ return TRUE;
+}
+
+/*!
+ Returns a TQTime object containing a time \a nsecs seconds later
+ than the time of this object (or earlier if \a nsecs is negative).
+
+ Note that the time will wrap if it passes midnight.
+
+ Example:
+ \code
+ TQTime n( 14, 0, 0 ); // n == 14:00:00
+ TQTime t;
+ t = n.addSecs( 70 ); // t == 14:01:10
+ t = n.addSecs( -70 ); // t == 13:58:50
+ t = n.addSecs( 10*60*60 + 5 ); // t == 00:00:05
+ t = n.addSecs( -15*60*60 ); // t == 23:00:00
+ \endcode
+
+ \sa addMSecs(), secsTo(), TQDateTime::addSecs()
+*/
+
+TQTime TQTime::addSecs( int nsecs ) const
+{
+ return addMSecs( nsecs * 1000 );
+}
+
+/*!
+ Returns the number of seconds from this time to \a t (which is
+ negative if \a t is earlier than this time).
+
+ Because TQTime measures time within a day and there are 86400
+ seconds in a day, the result is always between -86400 and 86400.
+
+ \sa addSecs() TQDateTime::secsTo()
+*/
+
+int TQTime::secsTo( const TQTime &t ) const
+{
+ return ((int)t.ds - (int)ds)/1000;
+}
+
+/*!
+ Returns a TQTime object containing a time \a ms milliseconds later
+ than the time of this object (or earlier if \a ms is negative).
+
+ Note that the time will wrap if it passes midnight. See addSecs()
+ for an example.
+
+ \sa addSecs(), msecsTo()
+*/
+
+TQTime TQTime::addMSecs( int ms ) const
+{
+ TQTime t;
+ if ( ms < 0 ) {
+ // % not well-defined for -ve, but / is.
+ int negdays = (MSECS_PER_DAY-ms) / MSECS_PER_DAY;
+ t.ds = ((int)ds + ms + negdays*MSECS_PER_DAY)
+ % MSECS_PER_DAY;
+ } else {
+ t.ds = ((int)ds + ms) % MSECS_PER_DAY;
+ }
+ return t;
+}
+
+/*!
+ Returns the number of milliseconds from this time to \a t (which
+ is negative if \a t is earlier than this time).
+
+ Because TQTime measures time within a day and there are 86400
+ seconds in a day, the result is always between -86400000 and
+ 86400000 msec.
+
+ \sa secsTo()
+*/
+
+int TQTime::msecsTo( const TQTime &t ) const
+{
+ return (int)t.ds - (int)ds;
+}
+
+
+/*!
+ \fn bool TQTime::operator==( const TQTime &t ) const
+
+ Returns TRUE if this time is equal to \a t; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQTime::operator!=( const TQTime &t ) const
+
+ Returns TRUE if this time is different from \a t; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQTime::operator<( const TQTime &t ) const
+
+ Returns TRUE if this time is earlier than \a t; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQTime::operator<=( const TQTime &t ) const
+
+ Returns TRUE if this time is earlier than or equal to \a t;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQTime::operator>( const TQTime &t ) const
+
+ Returns TRUE if this time is later than \a t; otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQTime::operator>=( const TQTime &t ) const
+
+ Returns TRUE if this time is later than or equal to \a t;
+ otherwise returns FALSE.
+*/
+
+
+
+/*!
+ \overload
+
+ Returns the current time as reported by the system clock.
+
+ Note that the accuracy depends on the accuracy of the underlying
+ operating system; not all systems provide 1-millisecond accuracy.
+*/
+
+TQTime TQTime::currentTime()
+{
+ return currentTime( TQt::LocalTime );
+}
+
+/*!
+ Returns the current time as reported by the system clock, for the
+ TimeSpec \a ts. The default TimeSpec is LocalTime.
+
+ Note that the accuracy depends on the accuracy of the underlying
+ operating system; not all systems provide 1-millisecond accuracy.
+
+ \sa TQt::TimeSpec
+*/
+TQTime TQTime::currentTime( TQt::TimeSpec ts )
+{
+ TQTime t;
+ currentTime( &t, ts );
+ return t;
+}
+
+#ifndef TQT_NO_DATESTRING
+/*!
+ Returns the representation \a s as a TQTime using the format \a f,
+ or an invalid time if this is not possible.
+
+ \warning Note that \c TQt::LocalDate cannot be used here.
+*/
+TQTime TQTime::fromString( const TQString& s, TQt::DateFormat f )
+{
+ if ( ( s.isEmpty() ) || ( f == TQt::LocalDate ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQTime::fromString: Parameter out of range" );
+#endif
+ TQTime t;
+ t.ds = MSECS_PER_DAY;
+ return t;
+ }
+
+ int hour( s.mid( 0, 2 ).toInt() );
+ int minute( s.mid( 3, 2 ).toInt() );
+ int second( s.mid( 6, 2 ).toInt() );
+ int msec( s.mid( 9, 3 ).toInt() );
+ return TQTime( hour, minute, second, msec );
+}
+#endif
+
+/*!
+ \internal
+ \obsolete
+
+ Fetches the current time and returns TRUE if the time is within one
+ minute after midnight, otherwise FALSE. The return value is used by
+ TQDateTime::tqcurrentDateTime() to ensure that the date there is correct.
+*/
+
+bool TQTime::currentTime( TQTime *ct )
+{
+ return currentTime( ct, TQt::LocalTime );
+}
+
+
+/*!
+ \internal
+
+ Fetches the current time, for the TimeSpec \a ts, and returns TRUE
+ if the time is within one minute after midnight, otherwise FALSE. The
+ return value is used by TQDateTime::tqcurrentDateTime() to ensure that
+ the date there is correct. The default TimeSpec is LocalTime.
+
+ \sa TQt::TimeSpec
+*/
+bool TQTime::currentTime( TQTime *ct, TQt::TimeSpec ts )
+{
+ if ( !ct ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQTime::currentTime(TQTime *): Null pointer not allowed" );
+#endif
+ return FALSE;
+ }
+
+#if defined(TQ_OS_WIN32)
+ SYSTEMTIME t;
+ if ( ts == TQt::LocalTime ) {
+ GetLocalTime( &t );
+ } else {
+ GetSystemTime( &t );
+ }
+ ct->ds = (uint)( MSECS_PER_HOUR*t.wHour + MSECS_PER_MIN*t.wMinute +
+ 1000*t.wSecond + t.wMilliseconds );
+#elif defined(TQ_OS_UNIX)
+ // posix compliant system
+ struct timeval tv;
+ gettimeofday( &tv, 0 );
+ time_t ltime = tv.tv_sec;
+ tm *t;
+
+# if defined(TQT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // use the reentrant versions of localtime() and gmtime() where available
+ tm res;
+ if ( ts == TQt::LocalTime )
+ t = localtime_r( &ltime, &res );
+ else
+ t = gmtime_r( &ltime, &res );
+# else
+ if ( ts == TQt::LocalTime )
+ t = localtime( &ltime );
+ else
+ t = gmtime( &ltime );
+# endif // TQT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
+
+ ct->ds = (uint)( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min +
+ 1000 * t->tm_sec + tv.tv_usec / 1000 );
+#else
+ time_t ltime; // no millisecond resolution
+ ::time( &ltime );
+ tm *t;
+ if ( ts == TQt::LocalTime )
+ localtime( &ltime );
+ else
+ gmtime( &ltime );
+ ct->ds = (uint) ( MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min +
+ 1000 * t->tm_sec );
+#endif
+ // 00:00.00 to 00:00.59.999 is considered as "midnight or right after"
+ return ct->ds < (uint) MSECS_PER_MIN;
+}
+
+/*!
+ \overload
+
+ Returns TRUE if the specified time is valid; otherwise returns
+ FALSE.
+
+ The time is valid if \a h is in the range 0..23, \a m and \a s are
+ in the range 0..59, and \a ms is in the range 0..999.
+
+ Example:
+ \code
+ TQTime::isValid(21, 10, 30); // returns TRUE
+ TQTime::isValid(22, 5, 62); // returns FALSE
+ \endcode
+*/
+
+bool TQTime::isValid( int h, int m, int s, int ms )
+{
+ return (uint)h < 24 && (uint)m < 60 && (uint)s < 60 && (uint)ms < 1000;
+}
+
+
+/*!
+ Sets this time to the current time. This is practical for timing:
+
+ \code
+ TQTime t;
+ t.start();
+ some_lengthy_task();
+ qDebug( "Time elapsed: %d ms", t.elapsed() );
+ \endcode
+
+ \sa restart(), elapsed(), currentTime()
+*/
+
+void TQTime::start()
+{
+ *this = currentTime();
+}
+
+/*!
+ Sets this time to the current time and returns the number of
+ milliseconds that have elapsed since the last time start() or
+ restart() was called.
+
+ This function is guaranteed to be atomic and is thus very handy
+ for repeated measurements. Call start() to start the first
+ measurement and then restart() for each later measurement.
+
+ Note that the counter wraps to zero 24 hours after the last call
+ to start() or restart().
+
+ \warning If the system's clock setting has been changed since the
+ last time start() or restart() was called, the result is
+ undefined. This can happen when daylight savings time is turned on
+ or off.
+
+ \sa start(), elapsed(), currentTime()
+*/
+
+int TQTime::restart()
+{
+ TQTime t = currentTime();
+ int n = msecsTo( t );
+ if ( n < 0 ) // passed midnight
+ n += 86400*1000;
+ *this = t;
+ return n;
+}
+
+/*!
+ Returns the number of milliseconds that have elapsed since the
+ last time start() or restart() was called.
+
+ Note that the counter wraps to zero 24 hours after the last call
+ to start() or restart.
+
+ Note that the accuracy depends on the accuracy of the underlying
+ operating system; not all systems provide 1-millisecond accuracy.
+
+ \warning If the system's clock setting has been changed since the
+ last time start() or restart() was called, the result is
+ undefined. This can happen when daylight savings time is turned on
+ or off.
+
+ \sa start(), restart()
+*/
+
+int TQTime::elapsed() const
+{
+ int n = msecsTo( currentTime() );
+ if ( n < 0 ) // passed midnight
+ n += 86400*1000;
+ return n;
+}
+
+
+/*****************************************************************************
+ TQDateTime member functions
+ *****************************************************************************/
+
+/*!
+ \class TQDateTime tqdatetime.h
+ \reentrant
+ \brief The TQDateTime class provides date and time functions.
+
+ \ingroup time
+ \mainclass
+
+ A TQDateTime object tqcontains a calendar date and a clock time (a
+ "datetime"). It is a combination of the TQDate and TQTime classes.
+ It can read the current datetime from the system clock. It
+ provides functions for comparing datetimes and for manipulating a
+ datetime by adding a number of seconds, days, months or years.
+
+ A TQDateTime object is typically created either by giving a date
+ and time explicitly in the constructor, or by using the static
+ function tqcurrentDateTime(), which returns a TQDateTime object set
+ to the system clock's time. The date and time can be changed with
+ setDate() and setTime(). A datetime can also be set using the
+ setTime_t() function, which takes a POSIX-standard "number of
+ seconds since 00:00:00 on January 1, 1970" value. The fromString()
+ function returns a TQDateTime given a string and a date format
+ which is used to interpret the date within the string.
+
+ The date() and time() functions provide access to the date and
+ time parts of the datetime. The same information is provided in
+ textual format by the toString() function.
+
+ TQDateTime provides a full set of operators to compare two
+ TQDateTime objects where smaller means earlier and larger means
+ later.
+
+ You can increment (or decrement) a datetime by a given number of
+ seconds using addSecs() or days using addDays(). Similarly you can
+ use addMonths() and addYears(). The daysTo() function returns the
+ number of days between two datetimes, and secsTo() returns the
+ number of seconds between two datetimes.
+
+ The range of a datetime object is constrained to the ranges of the
+ TQDate and TQTime objects which it embodies.
+
+ \sa TQDate TQTime TQDateTimeEdit
+*/
+
+
+/*!
+ \fn TQDateTime::TQDateTime()
+
+ Constructs a null datetime (i.e. null date and null time). A null
+ datetime is invalid, since the date is invalid.
+
+ \sa isValid()
+*/
+
+
+/*!
+ Constructs a datetime with date \a date and null (but valid) time
+ (00:00:00.000).
+*/
+
+TQDateTime::TQDateTime( const TQDate &date )
+ : d(date)
+{
+}
+
+/*!
+ Constructs a datetime with date \a date and time \a time.
+*/
+
+TQDateTime::TQDateTime( const TQDate &date, const TQTime &time )
+ : d(date), t(time)
+{
+}
+
+
+/*!
+ \fn bool TQDateTime::isNull() const
+
+ Returns TRUE if both the date and the time are null; otherwise
+ returns FALSE. A null datetime is invalid.
+
+ \sa TQDate::isNull(), TQTime::isNull()
+*/
+
+/*!
+ \fn bool TQDateTime::isValid() const
+
+ Returns TRUE if both the date and the time are valid; otherwise
+ returns FALSE.
+
+ \sa TQDate::isValid(), TQTime::isValid()
+*/
+
+/*!
+ \fn TQDate TQDateTime::date() const
+
+ Returns the date part of the datetime.
+
+ \sa setDate(), time()
+*/
+
+/*!
+ \fn TQTime TQDateTime::time() const
+
+ Returns the time part of the datetime.
+
+ \sa setTime(), date()
+*/
+
+/*!
+ \fn void TQDateTime::setDate( const TQDate &date )
+
+ Sets the date part of this datetime to \a date.
+
+ \sa date(), setTime()
+*/
+
+/*!
+ \fn void TQDateTime::setTime( const TQTime &time )
+
+ Sets the time part of this datetime to \a time.
+
+ \sa time(), setDate()
+*/
+
+
+/*!
+ Returns the datetime as the number of seconds that have passed
+ since 1970-01-01T00:00:00, Coordinated Universal Time (UTC).
+
+ On systems that do not support timezones, this function will
+ behave as if local time were UTC.
+
+ \sa setTime_t()
+*/
+
+uint TQDateTime::toTime_t() const
+{
+ tm brokenDown;
+ brokenDown.tm_sec = t.second();
+ brokenDown.tm_min = t.minute();
+ brokenDown.tm_hour = t.hour();
+ brokenDown.tm_mday = d.day();
+ brokenDown.tm_mon = d.month() - 1;
+ brokenDown.tm_year = d.year() - 1900;
+ brokenDown.tm_isdst = -1;
+ int secsSince1Jan1970UTC = (int) mktime( &brokenDown );
+ if ( secsSince1Jan1970UTC < -1 )
+ secsSince1Jan1970UTC = -1;
+ return (uint) secsSince1Jan1970UTC;
+}
+
+/*!
+ \overload
+
+ Convenience function that sets the date and time to local time
+ based on the given UTC time.
+*/
+
+void TQDateTime::setTime_t( uint secsSince1Jan1970UTC )
+{
+ setTime_t( secsSince1Jan1970UTC, TQt::LocalTime );
+}
+
+/*!
+ Sets the date and time to \a ts time (\c TQt::LocalTime or \c
+ TQt::UTC) given the number of seconds that have passed since
+ 1970-01-01T00:00:00, Coordinated Universal Time (UTC). On systems
+ that do not support timezones this function will behave as if
+ local time were UTC.
+
+ On Windows, only a subset of \a secsSince1Jan1970UTC values are
+ supported, as Windows starts counting from 1980.
+
+ \sa toTime_t()
+*/
+void TQDateTime::setTime_t( uint secsSince1Jan1970UTC, TQt::TimeSpec ts )
+{
+ time_t tmp = (time_t) secsSince1Jan1970UTC;
+ tm *brokenDown = 0;
+
+#if defined(TQ_OS_UNIX) && defined(TQT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS)
+ // posix compliant system
+ // use the reentrant versions of localtime() and gmtime() where available
+ tm res;
+ if ( ts == TQt::LocalTime )
+ brokenDown = localtime_r( &tmp, &res );
+ if ( !brokenDown ) {
+ brokenDown = gmtime_r( &tmp, &res );
+ if ( !brokenDown ) {
+ d.jd = TQDate::gregorianToJulian( 1970, 1, 1 );
+ t.ds = 0;
+ return;
+ }
+ }
+#else
+ if ( ts == TQt::LocalTime )
+ brokenDown = localtime( &tmp );
+ if ( !brokenDown ) {
+ brokenDown = gmtime( &tmp );
+ if ( !brokenDown ) {
+ d.jd = TQDate::gregorianToJulian( 1970, 1, 1 );
+ t.ds = 0;
+ return;
+ }
+ }
+#endif
+
+ d.jd = TQDate::gregorianToJulian( brokenDown->tm_year + 1900,
+ brokenDown->tm_mon + 1,
+ brokenDown->tm_mday );
+ t.ds = MSECS_PER_HOUR * brokenDown->tm_hour +
+ MSECS_PER_MIN * brokenDown->tm_min +
+ 1000 * brokenDown->tm_sec;
+}
+#ifndef TQT_NO_DATESTRING
+#ifndef TQT_NO_SPRINTF
+/*!
+ \overload
+
+ Returns the datetime as a string. The \a f parameter determines
+ the format of the string.
+
+ If \a f is \c TQt::TextDate, the string format is "Wed May 20
+ 03:40:13 1998" (using TQDate::shortDayName(), TQDate::shortMonthName(),
+ and TQTime::toString() to generate the string, so the day and month
+ names will have localized names).
+
+ If \a f is \c TQt::ISODate, the string format corresponds to the
+ ISO 8601 extended specification for representations of dates and
+ times, which is YYYY-MM-DDTHH:MM:SS.
+
+ If \a f is \c TQt::LocalDate, the string format depends on the
+ locale settings of the system.
+
+ If the format \a f is invalid or the datetime is invalid, toString()
+ returns a null string.
+
+ \sa TQDate::toString() TQTime::toString()
+*/
+
+TQString TQDateTime::toString( TQt::DateFormat f ) const
+{
+ if ( !isValid() )
+ return TQString::null;
+
+ if ( f == TQt::ISODate ) {
+ return d.toString( TQt::ISODate ) + "T" + t.toString( TQt::ISODate );
+ }
+#ifndef TQT_NO_TEXTDATE
+ else if ( f == TQt::TextDate ) {
+#ifndef TQ_WS_WIN
+ TQString buf = d.shortDayName( d.dayOfWeek() );
+ buf += ' ';
+ buf += d.shortMonthName( d.month() );
+ buf += ' ';
+ buf += TQString().setNum( d.day() );
+ buf += ' ';
+#else
+ TQString buf;
+ TQString winstr;
+ TQT_WA( {
+ TCHAR out[255];
+ GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_ILDATE, out, 255 );
+ winstr = TQString::fromUcs2( (ushort*)out );
+ } , {
+ char out[255];
+ GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_ILDATE, (char*)&out, 255 );
+ winstr = TQString::fromLocal8Bit( out );
+ } );
+ switch ( winstr.toInt() ) {
+ case 1:
+ buf = d.shortDayName( d.dayOfWeek() ) + " " + TQString().setNum( d.day() ) + ". " + d.shortMonthName( d.month() ) + " ";
+ break;
+ default:
+ buf = d.shortDayName( d.dayOfWeek() ) + " " + d.shortMonthName( d.month() ) + " " + TQString().setNum( d.day() ) + " ";
+ break;
+ }
+#endif
+ buf += t.toString();
+ buf += ' ';
+ buf += TQString().setNum( d.year() );
+ return buf;
+ }
+#endif
+ else if ( f == TQt::LocalDate ) {
+ return d.toString( TQt::LocalDate ) + " " + t.toString( TQt::LocalDate );
+ }
+ return TQString::null;
+}
+#endif
+
+/*!
+ Returns the datetime as a string. The \a format parameter
+ determines the format of the result string.
+
+ These expressions may be used for the date:
+
+ \table
+ \header \i Expression \i Output
+ \row \i d \i the day as number without a leading zero (1-31)
+ \row \i dd \i the day as number with a leading zero (01-31)
+ \row \i ddd
+ \i the abbreviated localized day name (e.g. 'Mon'..'Sun').
+ Uses TQDate::shortDayName().
+ \row \i dddd
+ \i the long localized day name (e.g. 'Monday'..'Sunday').
+ Uses TQDate::longDayName().
+ \row \i M \i the month as number without a leading zero (1-12)
+ \row \i MM \i the month as number with a leading zero (01-12)
+ \row \i MMM
+ \i the abbreviated localized month name (e.g. 'Jan'..'Dec').
+ Uses TQDate::shortMonthName().
+ \row \i MMMM
+ \i the long localized month name (e.g. 'January'..'December').
+ Uses TQDate::longMonthName().
+ \row \i yy \i the year as two digit number (00-99)
+ \row \i yyyy \i the year as four digit number (1752-8000)
+ \endtable
+
+ These expressions may be used for the time:
+
+ \table
+ \header \i Expression \i Output
+ \row \i h
+ \i the hour without a leading zero (0..23 or 1..12 if AM/PM display)
+ \row \i hh
+ \i the hour with a leading zero (00..23 or 01..12 if AM/PM display)
+ \row \i m \i the minute without a leading zero (0..59)
+ \row \i mm \i the minute with a leading zero (00..59)
+ \row \i s \i the second whithout a leading zero (0..59)
+ \row \i ss \i the second whith a leading zero (00..59)
+ \row \i z \i the milliseconds without leading zeroes (0..999)
+ \row \i zzz \i the milliseconds with leading zeroes (000..999)
+ \row \i AP
+ \i use AM/PM display. \e AP will be tqreplaced by either "AM" or "PM".
+ \row \i ap
+ \i use am/pm display. \e ap will be tqreplaced by either "am" or "pm".
+ \endtable
+
+ All other input characters will be ignored.
+
+ Example format strings (assumed that the TQDateTime is
+ 21<small><sup>st</sup></small> May 2001 14:13:09)
+
+ \table
+ \header \i Format \i Result
+ \row \i dd.MM.yyyy \i11 21.05.2001
+ \row \i ddd MMMM d yy \i11 Tue May 21 01
+ \row \i hh:mm:ss.zzz \i11 14:13:09.042
+ \row \i h:m:s ap \i11 2:13:9 pm
+ \endtable
+
+ If the datetime is an invalid datetime, then TQString::null will be returned.
+
+ \sa TQDate::toString() TQTime::toString()
+*/
+TQString TQDateTime::toString( const TQString& format ) const
+{
+ return fmtDateTime( format, &t, &d );
+}
+#endif //TQT_NO_DATESTRING
+
+/*!
+ Returns a TQDateTime object containing a datetime \a ndays days
+ later than the datetime of this object (or earlier if \a ndays is
+ negative).
+
+ \sa daysTo(), addMonths(), addYears(), addSecs()
+*/
+
+TQDateTime TQDateTime::addDays( int ndays ) const
+{
+ return TQDateTime( d.addDays(ndays), t );
+}
+
+/*!
+ Returns a TQDateTime object containing a datetime \a nmonths months
+ later than the datetime of this object (or earlier if \a nmonths
+ is negative).
+
+ \sa daysTo(), addDays(), addYears(), addSecs()
+*/
+
+TQDateTime TQDateTime::addMonths( int nmonths ) const
+{
+ return TQDateTime( d.addMonths(nmonths), t );
+}
+
+/*!
+ Returns a TQDateTime object containing a datetime \a nyears years
+ later than the datetime of this object (or earlier if \a nyears is
+ negative).
+
+ \sa daysTo(), addDays(), addMonths(), addSecs()
+*/
+
+TQDateTime TQDateTime::addYears( int nyears ) const
+{
+ return TQDateTime( d.addYears(nyears), t );
+}
+
+/*!
+ Returns a TQDateTime object containing a datetime \a nsecs seconds
+ later than the datetime of this object (or earlier if \a nsecs is
+ negative).
+
+ \sa secsTo(), addDays(), addMonths(), addYears()
+*/
+
+TQDateTime TQDateTime::addSecs( int nsecs ) const
+{
+ uint dd = d.jd;
+ int tt = t.ds;
+ int sign = 1;
+ if ( nsecs < 0 ) {
+ nsecs = -nsecs;
+ sign = -1;
+ }
+ if ( nsecs >= (int)SECS_PER_DAY ) {
+ dd += sign*(nsecs/SECS_PER_DAY);
+ nsecs %= SECS_PER_DAY;
+ }
+ tt += sign*nsecs*1000;
+ if ( tt < 0 ) {
+ tt = MSECS_PER_DAY - tt - 1;
+ dd -= tt / MSECS_PER_DAY;
+ tt = tt % MSECS_PER_DAY;
+ tt = MSECS_PER_DAY - tt - 1;
+ } else if ( tt >= (int)MSECS_PER_DAY ) {
+ dd += ( tt / MSECS_PER_DAY );
+ tt = tt % MSECS_PER_DAY;
+ }
+ TQDateTime ret;
+ ret.t.ds = tt;
+ ret.d.jd = dd;
+ return ret;
+}
+
+/*!
+ Returns the number of days from this datetime to \a dt (which is
+ negative if \a dt is earlier than this datetime).
+
+ \sa addDays(), secsTo()
+*/
+
+int TQDateTime::daysTo( const TQDateTime &dt ) const
+{
+ return d.daysTo( dt.d );
+}
+
+/*!
+ Returns the number of seconds from this datetime to \a dt (which
+ is negative if \a dt is earlier than this datetime).
+
+ Example:
+ \code
+ TQDateTime dt = TQDateTime::tqcurrentDateTime();
+ TQDateTime xmas( TQDate(dt.date().year(),12,24), TQTime(17,00) );
+ qDebug( "There are %d seconds to Christmas", dt.secsTo(xmas) );
+ \endcode
+
+ \sa addSecs(), daysTo(), TQTime::secsTo()
+*/
+
+int TQDateTime::secsTo( const TQDateTime &dt ) const
+{
+ return t.secsTo(dt.t) + d.daysTo(dt.d)*SECS_PER_DAY;
+}
+
+
+/*!
+ Returns TRUE if this datetime is equal to \a dt; otherwise returns FALSE.
+
+ \sa operator!=()
+*/
+
+bool TQDateTime::operator==( const TQDateTime &dt ) const
+{
+ return t == dt.t && d == dt.d;
+}
+
+/*!
+ Returns TRUE if this datetime is different from \a dt; otherwise
+ returns FALSE.
+
+ \sa operator==()
+*/
+
+bool TQDateTime::operator!=( const TQDateTime &dt ) const
+{
+ return t != dt.t || d != dt.d;
+}
+
+/*!
+ Returns TRUE if this datetime is earlier than \a dt; otherwise
+ returns FALSE.
+*/
+
+bool TQDateTime::operator<( const TQDateTime &dt ) const
+{
+ if ( d < dt.d )
+ return TRUE;
+ return d == dt.d ? t < dt.t : FALSE;
+}
+
+/*!
+ Returns TRUE if this datetime is earlier than or equal to \a dt;
+ otherwise returns FALSE.
+*/
+
+bool TQDateTime::operator<=( const TQDateTime &dt ) const
+{
+ if ( d < dt.d )
+ return TRUE;
+ return d == dt.d ? t <= dt.t : FALSE;
+}
+
+/*!
+ Returns TRUE if this datetime is later than \a dt; otherwise
+ returns FALSE.
+*/
+
+bool TQDateTime::operator>( const TQDateTime &dt ) const
+{
+ if ( d > dt.d )
+ return TRUE;
+ return d == dt.d ? t > dt.t : FALSE;
+}
+
+/*!
+ Returns TRUE if this datetime is later than or equal to \a dt;
+ otherwise returns FALSE.
+*/
+
+bool TQDateTime::operator>=( const TQDateTime &dt ) const
+{
+ if ( d > dt.d )
+ return TRUE;
+ return d == dt.d ? t >= dt.t : FALSE;
+}
+
+/*!
+ \overload
+
+ Returns the current datetime, as reported by the system clock.
+
+ \sa TQDate::tqcurrentDate(), TQTime::currentTime()
+*/
+
+TQDateTime TQDateTime::tqcurrentDateTime()
+{
+ return tqcurrentDateTime( TQt::LocalTime );
+}
+
+/*!
+ Returns the current datetime, as reported by the system clock, for the
+ TimeSpec \a ts. The default TimeSpec is LocalTime.
+
+ \sa TQDate::tqcurrentDate(), TQTime::currentTime(), TQt::TimeSpec
+*/
+
+TQDateTime TQDateTime::tqcurrentDateTime( TQt::TimeSpec ts )
+{
+ TQDateTime dt;
+ TQTime t;
+ dt.setDate( TQDate::tqcurrentDate(ts) );
+ if ( TQTime::currentTime(&t, ts) ) // midnight or right after?
+ dt.setDate( TQDate::tqcurrentDate(ts) ); // fetch date again
+ dt.setTime( t );
+ return dt;
+}
+
+#ifndef TQT_NO_DATESTRING
+/*!
+ Returns the TQDateTime represented by the string \a s, using the
+ format \a f, or an invalid datetime if this is not possible.
+
+ Note for \c TQt::TextDate: It is recommended that you use the
+ English short month names (e.g. "Jan"). Although localized month
+ names can also be used, they depend on the user's locale settings.
+
+ \warning Note that \c TQt::LocalDate cannot be used here.
+*/
+TQDateTime TQDateTime::fromString( const TQString& s, TQt::DateFormat f )
+{
+ if ( ( s.isEmpty() ) || ( f == TQt::LocalDate ) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQDateTime::fromString: Parameter out of range" );
+#endif
+ TQDateTime dt;
+ dt.d.jd = 0;
+ return dt;
+ }
+ if ( f == TQt::ISODate ) {
+ return TQDateTime( TQDate::fromString( s.mid(0,10), TQt::ISODate ),
+ TQTime::fromString( s.mid(11), TQt::ISODate ) );
+ }
+#if !defined(TQT_NO_REGEXP) && !defined(TQT_NO_TEXTDATE)
+ else if ( f == TQt::TextDate ) {
+ const int firstSpace = s.tqfind(' ');
+ TQString monthName( s.mid( firstSpace + 1, 3 ) );
+ int month = -1;
+ // Assume that English monthnames are the default
+ for ( int i = 0; i < 12; ++i ) {
+ if ( monthName == qt_shortMonthNames[i] ) {
+ month = i + 1;
+ break;
+ }
+ }
+ // If English names can't be found, search the localized ones
+ if ( month == -1 ) {
+ for ( int i = 1; i <= 12; ++i ) {
+ if ( monthName == TQDate::shortMonthName( i ) ) {
+ month = i;
+ break;
+ }
+ }
+ }
+#if defined(TQT_CHECK_RANGE)
+ if ( month < 1 || month > 12 ) {
+ qWarning( "TQDateTime::fromString: Parameter out of range" );
+ TQDateTime dt;
+ dt.d.jd = 0;
+ return dt;
+ }
+#endif
+ int day = TQT_TQSTRING(s.mid( firstSpace + 5, 2 )).simplifyWhiteSpace().toInt();
+ int year = s.right( 4 ).toInt();
+ TQDate date( year, month, day );
+ TQTime time;
+ int hour, minute, second;
+ int pivot = s.tqfind( TQRegExp(TQString::tqfromLatin1("[0-9][0-9]:[0-9][0-9]:[0-9][0-9]")) );
+ if ( pivot != -1 ) {
+ hour = s.mid( pivot, 2 ).toInt();
+ minute = s.mid( pivot+3, 2 ).toInt();
+ second = s.mid( pivot+6, 2 ).toInt();
+ time.setHMS( hour, minute, second );
+ }
+ return TQDateTime( date, time );
+ }
+#endif //TQT_NO_REGEXP
+ return TQDateTime();
+}
+#endif //TQT_NO_DATESTRING
+
+
+/*****************************************************************************
+ Date/time stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQDate
+
+ Writes the date, \a d, to the data stream, \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQDate &d )
+{
+ return s << (TQ_UINT32)(d.jd);
+}
+
+/*!
+ \relates TQDate
+
+ Reads a date from the stream \a s into \a d.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQDate &d )
+{
+ TQ_UINT32 jd;
+ s >> jd;
+ d.jd = jd;
+ return s;
+}
+
+/*!
+ \relates TQTime
+
+ Writes time \a t to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQTime &t )
+{
+ return s << (TQ_UINT32)(t.ds);
+}
+
+/*!
+ \relates TQTime
+
+ Reads a time from the stream \a s into \a t.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQTime &t )
+{
+ TQ_UINT32 ds;
+ s >> ds;
+ t.ds = ds;
+ return s;
+}
+
+/*!
+ \relates TQDateTime
+
+ Writes the datetime \a dt to the stream \a s.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQDateTime &dt )
+{
+ return s << dt.d << dt.t;
+}
+
+/*!
+ \relates TQDateTime
+
+ Reads a datetime from the stream \a s into \a dt.
+
+ \sa \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQDateTime &dt )
+{
+ s >> dt.d >> dt.t;
+ return s;
+}
+#endif //TQT_NO_DATASTREAM
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/tools/tqdatetime.h b/tqtinterface/qt4/src/tools/tqdatetime.h
new file mode 100644
index 0000000..aaf0727
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdatetime.h
@@ -0,0 +1,374 @@
+/*************************************************************************
+**
+** Definition of date and time classes
+**
+** Created : 940124
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDATETIME_H
+#define TQDATETIME_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqnamespace.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qdatetime.h>
+
+#endif // USE_QT4
+
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQDate : public QDate
+{
+public:
+ TQDate() : QDate() {}
+ TQDate( QDate date ) : QDate(date) {}
+ TQDate( int y, int m, int d ) : QDate( y, m, d ) {}
+
+ inline static TQString monthName(int month) { return shortMonthName(month); }
+ inline static TQString dayName(int weekday) { return shortDayName(weekday); }
+ inline static bool leapYear(int year) { return isLeapYear(year); }
+
+ static inline TQDate currentDate() { return TQT_TQDATE_OBJECT(QDate::currentDate()); }
+ static inline TQDate tqcurrentDate() { return currentDate(); }
+ static inline TQDate fromString( const TQString& s, Qt::DateFormat f = Qt::TextDate ) { return TQT_TQDATE_OBJECT(QDate::fromString(s, f)); }
+ static TQDate currentDate(Qt::TimeSpec spec);
+ static inline TQDate tqcurrentDate(Qt::TimeSpec spec) { return currentDate(spec); }
+
+ inline TQDate addDays( int days ) const { return TQT_TQDATE_OBJECT(addDays(days)); }
+ inline TQDate addMonths( int months ) const { return TQT_TQDATE_OBJECT(addMonths(months)); }
+ inline TQDate addYears( int years ) const { return TQT_TQDATE_OBJECT(addYears(years)); }
+
+ // Interoperability
+ inline static TQDate convertFromQDate( QDate q ) {
+ return (*static_cast<TQDate*>(&q));
+ }
+ inline static TQDate& convertFromQDate( QDate& q ) {
+ return (*static_cast<TQDate*>(&q));
+ }
+};
+
+class TQ_EXPORT TQTime : public QTime
+{
+public:
+ TQTime() : QTime() {}
+ TQTime( QTime time ) : QTime(time) {}
+ TQTime( int h, int m, int s=0, int ms=0 ) : QTime ( h, m, s, ms ) {}
+
+ inline static TQTime currentTime() { return TQT_TQTIME_OBJECT(QTime::currentTime()); }
+ inline static TQTime tqcurrentTime() { return currentTime(); }
+ inline static TQTime fromString( const TQString& s, Qt::DateFormat f = Qt::TextDate ) { return TQT_TQTIME_OBJECT(QTime::fromString(s, f)); }
+ static TQTime currentTime(Qt::TimeSpec spec);
+ inline static TQTime tqcurrentTime(Qt::TimeSpec spec) { return currentTime(spec); }
+
+ // Interoperability
+ inline static TQTime convertFromQTime( QTime q ) {
+ return (*static_cast<TQTime*>(&q));
+ }
+ inline static TQTime& convertFromQTime( QTime& q ) {
+ return (*static_cast<TQTime*>(&q));
+ }
+};
+
+class TQ_EXPORT TQDateTime : public QDateTime
+{
+public:
+ TQDateTime() : QDateTime() {}
+ TQDateTime( const QDateTime &dt ) : QDateTime ( dt ) {}
+ TQDateTime( const QDate &date ) : QDateTime ( date ) {}
+ TQDateTime( const QDate &date, const QTime &time ) : QDateTime( date, time ) {}
+
+ void setTime_t(uint secsSince1Jan1970UTC) { QDateTime::setTime_t(secsSince1Jan1970UTC); }
+ static inline TQDateTime tqcurrentDateTime() { return TQT_TQDATETIME_OBJECT(QDateTime::currentDateTime()); }
+ inline void setTime_t(uint secsSince1Jan1970UTC, Qt::TimeSpec spec) {
+ setTime_t(secsSince1Jan1970UTC);
+ if (spec == Qt::UTC)
+ *this = TQT_TQDATETIME_OBJECT(toUTC());
+ }
+ static inline TQDateTime tqcurrentDateTime(Qt::TimeSpec spec) {
+ if (spec == Qt::LocalTime)
+ return tqcurrentDateTime();
+ else
+ return TQT_TQDATETIME_OBJECT(currentDateTime().toUTC());
+ }
+
+ static inline TQDateTime fromString( const QString s, Qt::DateFormat f = Qt::TextDate ) { return TQT_TQDATETIME_OBJECT(QDateTime::fromString(s, f)); }
+
+ inline TQString toString(Qt::DateFormat f = Qt::TextDate) const { return QDateTime::toString(f); }
+ inline TQString toString(const QString &format) const { return QDateTime::toString(format); }
+
+ TQDate date() const { return TQT_TQDATE_OBJECT(QDateTime::date()); }
+ TQTime time() const { return TQT_TQTIME_OBJECT(QDateTime::time()); }
+
+ // Interoperability
+ inline static TQDateTime convertFromQDateTime( QDateTime q ) {
+ return (*static_cast<TQDateTime*>(&q));
+ }
+ inline static TQDateTime& convertFromQDateTime( QDateTime& q ) {
+ return (*static_cast<TQDateTime*>(&q));
+ }
+};
+
+inline TQDate TQDate::currentDate(Qt::TimeSpec spec)
+{
+ if (spec == Qt::LocalTime)
+ return TQT_TQDATE_OBJECT(currentDate());
+ else
+ return TQT_TQDATE_OBJECT(QDateTime::currentDateTime().toUTC().date());
+}
+
+inline TQTime TQTime::currentTime(Qt::TimeSpec spec)
+{
+ if (spec == Qt::LocalTime)
+ return TQT_TQTIME_OBJECT(currentTime());
+ else
+ return TQT_TQTIME_OBJECT(QDateTime::currentDateTime().toUTC().time());
+}
+
+#else // USE_QT4
+
+/*****************************************************************************
+ TQDate class
+ *****************************************************************************/
+
+class TQ_EXPORT TQDate
+{
+public:
+ TQDate() { jd = 0; }
+ TQDate( int y, int m, int d );
+
+ bool isNull() const { return jd == 0; }
+ bool isValid() const;
+
+ int year() const;
+ int month() const;
+ int day() const;
+ int dayOfWeek() const;
+ int dayOfYear() const;
+ int daysInMonth() const;
+ int daysInYear() const;
+ int weekNumber( int *yearNum = 0 ) const;
+
+#ifndef TQT_NO_TEXTDATE
+#ifndef TQT_NO_COMPAT
+ static TQString monthName( int month ) { return shortMonthName( month ); }
+ static TQString dayName( int weekday ) { return shortDayName( weekday ); }
+#endif
+ static TQString shortMonthName( int month );
+ static TQString shortDayName( int weekday );
+ static TQString longMonthName( int month );
+ static TQString longDayName( int weekday );
+#endif //TQT_NO_TEXTDATE
+#ifndef TQT_NO_TEXTSTRING
+#if !defined(TQT_NO_SPRINTF)
+ TQString toString( TQt::DateFormat f = TQt::TextDate ) const;
+#endif
+ TQString toString( const TQString& format ) const;
+#endif
+ bool setYMD( int y, int m, int d );
+
+ TQDate addDays( int days ) const;
+ TQDate addMonths( int months ) const;
+ TQDate addYears( int years ) const;
+ int daysTo( const TQDate & ) const;
+
+ bool operator==( const TQDate &d ) const { return jd == d.jd; }
+ bool operator!=( const TQDate &d ) const { return jd != d.jd; }
+ bool operator<( const TQDate &d ) const { return jd < d.jd; }
+ bool operator<=( const TQDate &d ) const { return jd <= d.jd; }
+ bool operator>( const TQDate &d ) const { return jd > d.jd; }
+ bool operator>=( const TQDate &d ) const { return jd >= d.jd; }
+
+ static TQDate currentDate();
+ static TQDate currentDate( TQt::TimeSpec );
+#ifndef TQT_NO_DATESTRING
+ static TQDate fromString( const TQString& s, TQt::DateFormat f = TQt::TextDate );
+#endif
+ static bool isValid( int y, int m, int d );
+ static bool leapYear( int year );
+
+ static uint gregorianToJulian( int y, int m, int d );
+ static void julianToGregorian( uint jd, int &y, int &m, int &d );
+private:
+ uint jd;
+ friend class TQDateTime;
+#ifndef TQT_NO_DATASTREAM
+ friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQDate & );
+ friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQDate & );
+#endif
+};
+
+
+/*****************************************************************************
+ TQTime class
+ *****************************************************************************/
+
+class TQ_EXPORT TQTime
+{
+public:
+ TQTime() { ds=0; } // set null time
+ TQTime( int h, int m, int s=0, int ms=0 ); // set time
+
+ bool isNull() const { return ds == 0; }
+ bool isValid() const; // valid time
+
+ int hour() const; // 0..23
+ int minute() const; // 0..59
+ int second() const; // 0..59
+ int msec() const; // 0..999
+#ifndef TQT_NO_DATESTRING
+#ifndef TQT_NO_SPRINTF
+ TQString toString( TQt::DateFormat f = TQt::TextDate ) const;
+#endif
+ TQString toString( const TQString& format ) const;
+#endif
+ bool setHMS( int h, int m, int s, int ms=0 );
+
+ TQTime addSecs( int secs ) const;
+ int secsTo( const TQTime & ) const;
+ TQTime addMSecs( int ms ) const;
+ int msecsTo( const TQTime & ) const;
+
+ bool operator==( const TQTime &d ) const { return ds == d.ds; }
+ bool operator!=( const TQTime &d ) const { return ds != d.ds; }
+ bool operator<( const TQTime &d ) const { return ds < d.ds; }
+ bool operator<=( const TQTime &d ) const { return ds <= d.ds; }
+ bool operator>( const TQTime &d ) const { return ds > d.ds; }
+ bool operator>=( const TQTime &d ) const { return ds >= d.ds; }
+
+ static TQTime currentTime();
+ static TQTime currentTime( TQt::TimeSpec );
+#ifndef TQT_NO_DATESTRING
+ static TQTime fromString( const TQString& s, TQt::DateFormat f = TQt::TextDate );
+#endif
+ static bool isValid( int h, int m, int s, int ms=0 );
+
+ void start();
+ int restart();
+ int elapsed() const;
+
+private:
+ static bool currentTime( TQTime * );
+ static bool currentTime( TQTime *, TQt::TimeSpec );
+
+ uint ds;
+ friend class TQDateTime;
+#ifndef TQT_NO_DATASTREAM
+ friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQTime & );
+ friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQTime & );
+#endif
+};
+
+
+/*****************************************************************************
+ TQDateTime class
+ *****************************************************************************/
+
+class TQ_EXPORT TQDateTime
+{
+public:
+ TQDateTime() {} // set null date and null time
+ TQDateTime( const TQDate & );
+ TQDateTime( const TQDate &, const TQTime & );
+
+ bool isNull() const { return d.isNull() && t.isNull(); }
+ bool isValid() const { return d.isValid() && t.isValid(); }
+
+ TQDate date() const { return d; }
+ TQTime time() const { return t; }
+ uint toTime_t() const;
+ void setDate( const TQDate &date ) { d = date; }
+ void setTime( const TQTime &time ) { t = time; }
+ void setTime_t( uint secsSince1Jan1970UTC );
+ void setTime_t( uint secsSince1Jan1970UTC, TQt::TimeSpec );
+#ifndef TQT_NO_DATESTRING
+#ifndef TQT_NO_SPRINTF
+ TQString toString( TQt::DateFormat f = TQt::TextDate ) const;
+#endif
+ TQString toString( const TQString& format ) const;
+#endif
+ TQDateTime addDays( int days ) const;
+ TQDateTime addMonths( int months ) const;
+ TQDateTime addYears( int years ) const;
+ TQDateTime addSecs( int secs ) const;
+ int daysTo( const TQDateTime & ) const;
+ int secsTo( const TQDateTime & ) const;
+
+ bool operator==( const TQDateTime &dt ) const;
+ bool operator!=( const TQDateTime &dt ) const;
+ bool operator<( const TQDateTime &dt ) const;
+ bool operator<=( const TQDateTime &dt ) const;
+ bool operator>( const TQDateTime &dt ) const;
+ bool operator>=( const TQDateTime &dt ) const;
+
+ static TQDateTime currentDateTime();
+ static TQDateTime currentDateTime( TQt::TimeSpec );
+#ifndef TQT_NO_DATESTRING
+ static TQDateTime fromString( const TQString& s, TQt::DateFormat f = TQt::TextDate );
+#endif
+private:
+ TQDate d;
+ TQTime t;
+#ifndef TQT_NO_DATASTREAM
+ friend TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQDateTime &);
+ friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQDateTime & );
+#endif
+};
+
+
+/*****************************************************************************
+ Date and time stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQDate & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQDate & );
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQTime & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQTime & );
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQDateTime & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQDateTime & );
+#endif // TQT_NO_DATASTREAM
+
+#endif // USE_QT4
+
+#endif // TQDATETIME_H
+
diff --git a/tqtinterface/qt4/src/tools/tqdeepcopy.cpp b/tqtinterface/qt4/src/tools/tqdeepcopy.cpp
new file mode 100644
index 0000000..4a5095e
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdeepcopy.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** Implementation of TQDeepCopy class
+**
+** Created : 20020613
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdeepcopy.h"
+
+/*!
+ \class TQDeepCopy tqdeepcopy.h
+ \brief The TQDeepCopy class is a template class which ensures that
+ implicitly shared and explicitly shared classes reference unique
+ data.
+
+ \reentrant
+
+ \ingroup tools
+ \ingroup shared
+
+ Normally, shared copies reference the same data to optimize memory
+ use and for maximum speed. In the example below, \c s1, \c s2, \c
+ s3, \c s4 and \c s5 share data.
+
+ \code
+ // all 5 strings share the same data
+ TQString s1 = "abcd";
+ TQString s2 = s1;
+ TQString s3 = s2;
+ TQString s4 = s3;
+ TQString s5 = s2;
+ \endcode
+
+ TQDeepCopy can be used several ways to ensure that an object
+ references unique, unshared data. In the example below, \c s1, \c
+ s2 and \c s5 share data, while neither \c s3 nor \c s4 share data.
+ \code
+ // s1, s2 and s5 share the same data, neither s3 nor s4 are shared
+ TQString s1 = "abcd";
+ TQString s2 = s1;
+ TQDeepCopy<TQString> s3 = s2; // s3 is a deep copy of s2
+ TQString s4 = s3; // s4 is a deep copy of s3
+ TQString s5 = s2;
+ \endcode
+
+ In the example below, \c s1, \c s2 and \c s5 share data, and \c s3
+ and \c s4 share data.
+ \code
+ // s1, s2 and s5 share the same data, s3 and s4 share the same data
+ TQString s1 = "abcd";
+ TQString s2 = s1;
+ TQString s3 = TQDeepCopy<TQString>( s2 ); // s3 is a deep copy of s2
+ TQString s4 = s3; // s4 is a shallow copy of s3
+ TQString s5 = s2;
+ \endcode
+
+ TQDeepCopy can also provide safety in multithreaded applications
+ that use shared classes. In the example below, the variable \c
+ global_string is used safely since the data contained in \c
+ global_string is always a deep copy. This ensures that all threads
+ get a unique copy of the data, and that any assignments to \c
+ global_string will result in a deep copy.
+
+ \code
+ TQDeepCopy<TQString> global_string; // global string data
+ TQMutex global_mutex; // mutex to protext global_string
+
+ ...
+
+ void setGlobalString( const TQString &str )
+ {
+ global_mutex.lock();
+ global_string = str; // global_string is a deep copy of str
+ global_mutex.unlock();
+ }
+
+ ...
+
+ void MyThread::run()
+ {
+ global_mutex.lock();
+ TQString str = global_string; // str is a deep copy of global_string
+ global_mutex.unlock();
+
+ // process the string data
+ ...
+
+ // update global_string
+ setGlobalString( str );
+ }
+ \endcode
+
+ \warning It is the application developer's responsibility to
+ protect the object shared across multiple threads.
+
+ The examples above use TQString, which is an implicitly shared
+ class. The behavior of TQDeepCopy is the same when using explicitly
+ shared classes like TQByteArray.
+
+ Currently, TQDeepCopy works with the following classes:
+ \list
+ \i TQMemArray (including subclasses like TQByteArray and TQCString)
+ \i TQMap
+ \i TQString
+ \i TQValueList (including subclasses like TQStringList and TQValueStack)
+ \i TQValueVector
+ \endlist
+
+ \sa \link threads.html Thread Support in TQt \endlink
+*/
+
+/*!
+ \fn TQDeepCopy::TQDeepCopy()
+
+ Constructs an empty instance of type \e T.
+*/
+
+/*!
+ \fn TQDeepCopy::TQDeepCopy( const T &t )
+
+ Constructs a deep copy of \a t.
+*/
+
+/*!
+ \fn TQDeepCopy<T>& TQDeepCopy::operator=( const T &t )
+
+ Assigns a deep copy of \a t.
+*/
+
+/*!
+ \fn TQDeepCopy::operator T ()
+
+ Returns a deep copy of the encapsulated data.
+*/
+
diff --git a/tqtinterface/qt4/src/tools/tqdeepcopy.h b/tqtinterface/qt4/src/tools/tqdeepcopy.h
new file mode 100644
index 0000000..900f9c0
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdeepcopy.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Definition of TQDeepCopy class
+**
+** Created : 20020613
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDEEPCOPY_H
+#define TQDEEPCOPY_H
+
+#ifndef TQT_H
+# include "tqglobal.h"
+#endif // TQT_H
+
+template <class T>
+class TQDeepCopy
+{
+public:
+ inline TQDeepCopy()
+ {
+ }
+
+ inline TQDeepCopy( const T &t )
+ : deepcopy( t )
+ {
+ deepcopy.detach();
+ }
+
+ inline TQDeepCopy<T> &operator=( const T &t )
+ {
+ deepcopy = t;
+ deepcopy.detach();
+ return *this;
+ }
+
+ inline operator T ()
+ {
+ T tmp = deepcopy;
+ tmp.detach();
+ return tmp;
+ }
+
+private:
+ T deepcopy;
+};
+
+#endif // TQDEEPCOPY_H
diff --git a/tqtinterface/qt4/src/tools/tqdict.h b/tqtinterface/qt4/src/tools/tqdict.h
new file mode 100644
index 0000000..1dc8a48
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdict.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Definition of TQDict template class
+**
+** Created : 920821
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDICT_H
+#define TQDICT_H
+
+#ifndef TQT_H
+#include "tqgdict.h"
+#endif // TQT_H
+
+template<class type>
+class TQDict
+#ifdef TQ_TQDOC
+ : public TQPtrCollection
+#else
+ : public TQGDict
+#endif
+{
+public:
+ TQDict( int size = 17, bool caseSensitive = TRUE )
+ : TQGDict( size, StringKey, caseSensitive, FALSE ) { }
+ TQDict( const TQDict<type> &d ) : TQGDict( d ) { }
+ ~TQDict() { clear(); }
+ TQDict<type> &operator=(const TQDict<type> &d)
+ { return (TQDict<type>&)TQGDict::operator=(d); }
+ uint count() const { return TQGDict::count(); }
+ uint size() const { return TQGDict::size(); }
+ bool isEmpty() const { return TQGDict::count() == 0; }
+
+ void insert( const TQString &k, const type *d )
+ { TQGDict::look_string(k,(Item)d,1); }
+ void tqreplace( const TQString &k, const type *d )
+ { TQGDict::look_string(k,(Item)d,2); }
+ bool remove( const TQString &k ) { return TQGDict::remove_string(k); }
+ type *take( const TQString &k ) { return (type *)TQGDict::take_string(k); }
+ type *tqfind( const TQString &k ) const
+ { return (type *)((TQGDict*)this)->TQGDict::look_string(k,0,0); }
+ type *operator[]( const TQString &k ) const
+ { return (type *)((TQGDict*)this)->TQGDict::look_string(k,0,0); }
+
+ void clear() { TQGDict::clear(); }
+ void resize( uint n ) { TQGDict::resize(n); }
+ void statistics() const { TQGDict::statistics(); }
+
+#ifdef TQ_TQDOC
+protected:
+ virtual TQDataStream& read( TQDataStream &, TQPtrCollection::Item & );
+ virtual TQDataStream& write( TQDataStream &, TQPtrCollection::Item ) const;
+#endif
+
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQDict<void>::deleteItem( Item )
+{
+}
+#endif
+
+template<class type> inline void TQDict<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+template<class type>
+class TQDictIterator : public TQGDictIterator
+{
+public:
+ TQDictIterator(const TQDict<type> &d) : TQGDictIterator((TQGDict &)d) { }
+ ~TQDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)TQGDictIterator::toFirst(); }
+ operator type *() const { return (type *)TQGDictIterator::get(); }
+ type *operator*() { return (type *)TQGDictIterator::get(); }
+ type *current() const { return (type *)TQGDictIterator::get(); }
+ TQString currentKey() const{ return TQGDictIterator::getKeyString(); }
+ type *operator()() { return (type *)TQGDictIterator::operator()(); }
+ type *operator++() { return (type *)TQGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)TQGDictIterator::operator+=(j); }
+};
+
+#define TQ_DEFINED_TQDICT
+#include "tqwinexport.h"
+#endif // TQDICT_H
diff --git a/tqtinterface/qt4/src/tools/tqdir.cpp b/tqtinterface/qt4/src/tools/tqdir.cpp
new file mode 100644
index 0000000..796162d
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdir.cpp
@@ -0,0 +1,1390 @@
+/****************************************************************************
+**
+** Implementation of TQDir class
+**
+** Created : 950427
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+#include "tqdir.h"
+
+#ifndef TQT_NO_DIR
+#include <private/tqdir_p.h>
+#include "tqfileinfo.h"
+#include "tqregexp.h"
+#include "tqstringlist.h"
+#include "tqdeepcopy.h"
+#include <limits.h>
+
+#if defined(TQ_FS_FAT) && !defined(TQ_OS_UNIX)
+const bool CaseSensitiveFS = FALSE;
+#else
+const bool CaseSensitiveFS = TRUE;
+#endif
+
+
+/*!
+ \class TQDir
+ \reentrant
+ \brief The TQDir class provides access to directory structures and their contents in a platform-independent way.
+
+ \ingroup io
+ \mainclass
+
+ A TQDir is used to manipulate path names, access information
+ regarding paths and files, and manipulate the underlying file
+ system.
+
+ A TQDir can point to a file using either a relative or an absolute
+ path. Absolute paths begin with the directory separator "/"
+ (optionally preceded by a drive specification under Windows). If
+ you always use "/" as a directory separator, TQt will translate
+ your paths to conform to the underlying operating system. Relative
+ file names begin with a directory name or a file name and specify
+ a path relative to the current directory.
+
+ The "current" path refers to the application's working directory.
+ A TQDir's own path is set and retrieved with setPath() and path().
+
+ An example of an absolute path is the string "/tmp/quartz", a
+ relative path might look like "src/fatlib". You can use the
+ function isRelative() to check if a TQDir is using a relative or an
+ absolute file path. Call convertToAbs() to convert a relative TQDir
+ to an absolute one. For a simplified path use cleanDirPath(). To
+ obtain a path which has no symbolic links or redundant ".."
+ elements use canonicalPath(). The path can be set with setPath(),
+ and changed with cd() and cdUp().
+
+ TQDir provides several static functions, for example, setCurrent()
+ to set the application's working directory and currentDirPath() to
+ retrieve the application's working directory. Access to some
+ common paths is provided with the static functions, current(),
+ home() and root() which return TQDir objects or currentDirPath(),
+ homeDirPath() and rootDirPath() which return the path as a string.
+ If you want to know about your application's path use
+ \l{TQApplication::applicationDirPath()}.
+
+ The number of entries in a directory is returned by count().
+ Obtain a string list of the names of all the files and directories
+ in a directory with entryList(). If you prefer a list of TQFileInfo
+ pointers use entryInfoList(). Both these functions can apply a
+ name filter, an attributes filter (e.g. read-only, files not
+ directories, etc.), and a sort order. The filters and sort may be
+ set with calls to setNameFilter(), setFilter() and setSorting().
+ They may also be specified in the entryList() and
+ entryInfoList()'s arguments.
+
+ Create a new directory with mkdir(), rename a directory with
+ rename() and remove an existing directory with rmdir(). Remove a
+ file with remove(). You can interrogate a directory with exists(),
+ isReadable() and isRoot().
+
+ To get a path with a filename use filePath(), and to get a
+ directory name use dirName(); neither of these functions checks
+ for the existence of the file or directory.
+
+ The list of root directories is provided by drives(); on Unix
+ systems this returns a list containing one root directory, "/"; on
+ Windows the list will usually contain "C:/", and possibly "D:/",
+ etc.
+
+ It is easiest to work with "/" separators in TQt code. If you need
+ to present a path to the user or need a path in a form suitable
+ for a function in the underlying operating system use
+ convertSeparators().
+
+ Examples:
+
+ See if a directory exists.
+ \code
+ TQDir d( "example" ); // "./example"
+ if ( !d.exists() )
+ qWarning( "Cannot find the example directory" );
+ \endcode
+
+ Traversing directories and reading a file.
+ \code
+ TQDir d = TQDir::root(); // "/"
+ if ( !d.cd("tmp") ) { // "/tmp"
+ qWarning( "Cannot find the \"/tmp\" directory" );
+ } else {
+ TQFile f( d.filePath("ex1.txt") ); // "/tmp/ex1.txt"
+ if ( !f.open(IO_ReadWrite) )
+ qWarning( "Cannot create the file %s", f.name() );
+ }
+ \endcode
+
+ A program that lists all the files in the current directory
+ (excluding symbolic links), sorted by size, smallest first:
+ \code
+ #include <stdio.h>
+ #include <tqdir.h>
+
+ int main( int argc, char **argv )
+ {
+ TQDir d;
+ d.setFilter( TQDir::Files | TQDir::Hidden | TQDir::NoSymLinks );
+ d.setSorting( TQDir::Size | TQDir::Reversed );
+
+ const TQFileInfoList *list = d.entryInfoList();
+ TQFileInfoListIterator it( *list );
+ TQFileInfo *fi;
+
+ printf( " Bytes Filename\n" );
+ while ( (fi = it.current()) != 0 ) {
+ printf( "%10li %s\n", fi->size(), fi->fileName().latin1() );
+ ++it;
+ }
+ return 0;
+ }
+ \endcode
+
+ \sa TQApplication::applicationDirPath()
+*/
+
+/*!
+ Constructs a TQDir pointing to the current directory (".").
+
+ \sa currentDirPath()
+*/
+
+TQDir::TQDir()
+{
+ dPath = TQString::tqfromLatin1(".");
+ init();
+}
+
+/*!
+ Constructs a TQDir with path \a path, that filters its entries by
+ name using \a nameFilter and by attributes using \a filterSpec. It
+ also sorts the names using \a sortSpec.
+
+ The default \a nameFilter is an empty string, which excludes
+ nothing; the default \a filterSpec is \c All, which also means
+ exclude nothing. The default \a sortSpec is \c Name|IgnoreCase,
+ i.e. sort by name case-insensitively.
+
+ Example that lists all the files in "/tmp":
+ \code
+ TQDir d( "/tmp" );
+ for ( int i = 0; i < d.count(); i++ )
+ printf( "%s\n", d[i] );
+ \endcode
+
+ If \a path is "" or TQString::null, TQDir uses "." (the current
+ directory). If \a nameFilter is "" or TQString::null, TQDir uses the
+ name filter "*" (all files).
+
+ Note that \a path need not exist.
+
+ \sa exists(), setPath(), setNameFilter(), setFilter(), setSorting()
+*/
+
+TQDir::TQDir( const TQString &path, const TQString &nameFilter,
+ int sortSpec, int filterSpec )
+{
+ init();
+ dPath = cleanDirPath( path );
+ if ( dPath.isEmpty() )
+ dPath = TQString::tqfromLatin1(".");
+ nameFilt = nameFilter;
+ if ( nameFilt.isEmpty() )
+ nameFilt = TQString::tqfromLatin1("*");
+ filtS = (FilterSpec)filterSpec;
+ sortS = (SortSpec)sortSpec;
+}
+
+/*!
+ Constructs a TQDir that is a copy of the directory \a d.
+
+ \sa operator=()
+*/
+
+TQDir::TQDir( const TQDir &d )
+{
+ dPath = d.dPath;
+ fList = 0;
+ fiList = 0;
+ nameFilt = d.nameFilt;
+ dirty = TRUE;
+ allDirs = d.allDirs;
+ filtS = d.filtS;
+ sortS = d.sortS;
+}
+
+/*!
+ Refreshes the directory information.
+*/
+void TQDir::refresh() const
+{
+ TQDir* that = (TQDir*) this;
+ that->dirty = TRUE;
+}
+
+void TQDir::init()
+{
+ fList = 0;
+ fiList = 0;
+ nameFilt = TQString::tqfromLatin1("*");
+ dirty = TRUE;
+ allDirs = FALSE;
+ filtS = All;
+ sortS = SortSpec(Name | IgnoreCase);
+}
+
+/*!
+ Destroys the TQDir frees up its resources.
+*/
+
+TQDir::~TQDir()
+{
+ delete fList;
+ delete fiList;
+}
+
+
+/*!
+ Sets the path of the directory to \a path. The path is cleaned of
+ redundant ".", ".." and of multiple separators. No check is made
+ to ensure that a directory with this path exists.
+
+ The path can be either absolute or relative. Absolute paths begin
+ with the directory separator "/" (optionally preceded by a drive
+ specification under Windows). Relative file names begin with a
+ directory name or a file name and specify a path relative to the
+ current directory. An example of an absolute path is the string
+ "/tmp/quartz", a relative path might look like "src/fatlib".
+
+ \sa path(), absPath(), exists(), cleanDirPath(), dirName(),
+ absFilePath(), isRelative(), convertToAbs()
+*/
+
+void TQDir::setPath( const TQString &path )
+{
+ dPath = cleanDirPath( path );
+ if ( dPath.isEmpty() )
+ dPath = TQString::tqfromLatin1(".");
+ dirty = TRUE;
+}
+
+/*!
+ \fn TQString TQDir::path() const
+
+ Returns the path, this may contain symbolic links, but never
+ tqcontains redundant ".", ".." or multiple separators.
+
+ The returned path can be either absolute or relative (see
+ setPath()).
+
+ \sa setPath(), absPath(), exists(), cleanDirPath(), dirName(),
+ absFilePath(), convertSeparators()
+*/
+
+/*!
+ Returns the absolute path (a path that starts with "/" or with a
+ drive specification), which may contain symbolic links, but never
+ tqcontains redundant ".", ".." or multiple separators.
+
+ \sa setPath(), canonicalPath(), exists(), cleanDirPath(),
+ dirName(), absFilePath()
+*/
+
+TQString TQDir::absPath() const
+{
+ if ( TQDir::isRelativePath(dPath) ) {
+ TQString tmp = currentDirPath();
+ if ( tmp.right(1) != TQString::tqfromLatin1("/") )
+ tmp += '/';
+ tmp += dPath;
+ return cleanDirPath( tmp );
+ } else {
+ return cleanDirPath( dPath );
+ }
+}
+
+/*!
+ Returns the name of the directory; this is \e not the same as the
+ path, e.g. a directory with the name "mail", might have the path
+ "/var/spool/mail". If the directory has no name (e.g. it is the
+ root directory) TQString::null is returned.
+
+ No check is made to ensure that a directory with this name
+ actually exists.
+
+ \sa path(), absPath(), absFilePath(), exists(), TQString::isNull()
+*/
+
+TQString TQDir::dirName() const
+{
+ int pos = dPath.tqfindRev( '/' );
+ if ( pos == -1 )
+ return dPath;
+ return dPath.right( dPath.length() - pos - 1 );
+}
+
+/*!
+ Returns the path name of a file in the directory. Does \e not
+ check if the file actually exists in the directory. If the TQDir is
+ relative the returned path name will also be relative. Redundant
+ multiple separators or "." and ".." directories in \a fileName
+ will not be removed (see cleanDirPath()).
+
+ If \a acceptAbsPath is TRUE a \a fileName starting with a
+ separator "/" will be returned without change. If \a acceptAbsPath
+ is FALSE an absolute path will be prepended to the fileName and
+ the resultant string returned.
+
+ \sa absFilePath(), isRelative(), canonicalPath()
+*/
+
+TQString TQDir::filePath( const TQString &fileName,
+ bool acceptAbsPath ) const
+{
+ if ( acceptAbsPath && !isRelativePath(fileName) )
+ return TQString(fileName);
+
+ TQString tmp = dPath;
+ if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
+ fileName[0] != '/') )
+ tmp += '/';
+ tmp += fileName;
+ return tmp;
+}
+
+/*!
+ Returns the absolute path name of a file in the directory. Does \e
+ not check if the file actually exists in the directory. Redundant
+ multiple separators or "." and ".." directories in \a fileName
+ will not be removed (see cleanDirPath()).
+
+ If \a acceptAbsPath is TRUE a \a fileName starting with a
+ separator "/" will be returned without change. If \a acceptAbsPath
+ is FALSE an absolute path will be prepended to the fileName and
+ the resultant string returned.
+
+ \sa filePath()
+*/
+
+TQString TQDir::absFilePath( const TQString &fileName,
+ bool acceptAbsPath ) const
+{
+ if ( acceptAbsPath && !isRelativePath( fileName ) )
+ return fileName;
+
+ TQString tmp = absPath();
+#ifdef TQ_OS_WIN32
+ if ( fileName[0].isLetter() && fileName[1] == ':' ) {
+ int drv = fileName.upper()[0].latin1() - 'A' + 1;
+ if ( _getdrive() != drv ) {
+ TQT_WA( {
+ TCHAR buf[PATH_MAX];
+ ::_wgetdcwd( drv, buf, PATH_MAX );
+ tmp.setUnicodeCodes( (ushort*)buf, (uint)::wcslen(buf) );
+ }, {
+ char buf[PATH_MAX];
+ ::_getdcwd( drv, buf, PATH_MAX );
+ tmp = buf;
+ } );
+ if ( !tmp.endsWith("\\") )
+ tmp += "\\";
+ tmp += fileName.right( fileName.length() - 2 );
+ int x;
+ for ( x = 0; x < (int) tmp.length(); x++ ) {
+ if ( tmp[x] == '\\' )
+ tmp[x] = '/';
+ }
+ }
+ } else
+#endif
+ {
+ if ( tmp.isEmpty() || (tmp[(int)tmp.length()-1] != '/' && !!fileName &&
+ fileName[0] != '/') )
+ tmp += '/';
+ tmp += fileName;
+ }
+ return tmp;
+}
+
+
+/*!
+ Returns \a pathName with the '/' separators converted to
+ separators that are appropriate for the underlying operating
+ system.
+
+ On Windows, convertSeparators("c:/winnt/system32") returns
+ "c:\winnt\system32".
+
+ The returned string may be the same as the argument on some
+ operating systems, for example on Unix.
+*/
+
+TQString TQDir::convertSeparators( const TQString &pathName )
+{
+ TQString n( pathName );
+#if defined(TQ_FS_FAT) || defined(TQ_OS_OS2EMX)
+ for ( int i=0; i<(int)n.length(); i++ ) {
+ if ( n[i] == '/' )
+ n[i] = '\\';
+ }
+#elif defined(TQ_OS_MAC9)
+ while(n.length() && n[0] == '/' ) n = n.right(n.length()-1);
+ for ( int i=0; i<(int)n.length(); i++ ) {
+ if ( n[i] == '/' )
+ n[i] = ':';
+ }
+ if(n.tqcontains(':') && n.left(1) != ':')
+ n.prepend(':');
+#endif
+ return n;
+}
+
+
+/*!
+ Changes the TQDir's directory to \a dirName.
+
+ If \a acceptAbsPath is TRUE a path starting with separator "/"
+ will cause the function to change to the absolute directory. If \a
+ acceptAbsPath is FALSE any number of separators at the beginning
+ of \a dirName will be removed and the function will descend into
+ \a dirName.
+
+ Returns TRUE if the new directory exists and is readable;
+ otherwise returns FALSE. Note that the logical cd() operation is
+ not performed if the new directory does not exist.
+
+ Calling cd( ".." ) is equivalent to calling cdUp().
+
+ \sa cdUp(), isReadable(), exists(), path()
+*/
+
+bool TQDir::cd( const TQString &dirName, bool acceptAbsPath )
+{
+ if ( dirName.isEmpty() || dirName == TQString::tqfromLatin1(".") )
+ return TRUE;
+ TQString old = dPath;
+ if ( acceptAbsPath && !isRelativePath(dirName) ) {
+ dPath = cleanDirPath( dirName );
+ } else {
+ if ( isRoot() ) {
+ if ( dirName == ".." ) {
+ dPath = old;
+ return FALSE;
+ }
+ } else {
+ dPath += '/';
+ }
+
+ dPath += dirName;
+ if ( dirName.tqfind('/') >= 0
+ || old == TQString::tqfromLatin1(".")
+ || dirName == TQString::tqfromLatin1("..") ) {
+ dPath = cleanDirPath( dPath );
+
+ /*
+ If dPath starts with .., we convert it to absolute to
+ avoid infinite looping on
+
+ TQDir dir( "." );
+ while ( dir.cdUp() )
+ ;
+ */
+ if ( dPath[0] == TQChar('.') && dPath[1] == TQChar('.') &&
+ (dPath.length() == 2 || dPath[2] == TQChar('/')) )
+ convertToAbs();
+ }
+ }
+ if ( !exists() ) {
+ dPath = old; // regret
+ return FALSE;
+ }
+ dirty = TRUE;
+ return TRUE;
+}
+
+/*!
+ Changes directory by moving one directory up from the TQDir's
+ current directory.
+
+ Returns TRUE if the new directory exists and is readable;
+ otherwise returns FALSE. Note that the logical cdUp() operation is
+ not performed if the new directory does not exist.
+
+ \sa cd(), isReadable(), exists(), path()
+*/
+
+bool TQDir::cdUp()
+{
+ return cd( TQString::tqfromLatin1("..") );
+}
+
+/*!
+ \fn TQString TQDir::nameFilter() const
+
+ Returns the string set by setNameFilter()
+*/
+
+/*!
+ Sets the name filter used by entryList() and entryInfoList() to \a
+ nameFilter.
+
+ The \a nameFilter is a wildcard (globbing) filter that understands
+ "*" and "?" wildcards. (See \link tqregexp.html#wildcard-matching
+ TQRegExp wildcard matching\endlink.) You may specify several filter
+ entries all separated by a single space " " or by a semi-colon
+ ";".
+
+ For example, if you want entryList() and entryInfoList() to list
+ all files ending with either ".cpp" or ".h", you would use either
+ dir.setNameFilter("*.cpp *.h") or dir.setNameFilter("*.cpp;*.h").
+
+ \sa nameFilter(), setFilter()
+*/
+
+void TQDir::setNameFilter( const TQString &nameFilter )
+{
+ nameFilt = nameFilter;
+ if ( nameFilt.isEmpty() )
+ nameFilt = TQString::tqfromLatin1("*");
+ dirty = TRUE;
+}
+
+/*!
+ \fn TQDir::FilterSpec TQDir::filter() const
+
+ Returns the value set by setFilter()
+*/
+
+/*!
+ \enum TQDir::FilterSpec
+
+ This enum describes the filtering options available to TQDir, e.g.
+ for entryList() and entryInfoList(). The filter value is specified
+ by OR-ing together values from the following list:
+
+ \value Dirs List directories only.
+ \value Files List files only.
+ \value Drives List disk drives (ignored under Unix).
+ \value NoSymLinks Do not list symbolic links (ignored by operating
+ systems that don't support symbolic links).
+ \value All List directories, files, drives and symlinks (this does not list
+ broken symlinks unless you specify System).
+ \value TypeMask A tqmask for the the Dirs, Files, Drives and
+ NoSymLinks flags.
+ \value Readable List files for which the application has read access.
+ \value Writable List files for which the application has write access.
+ \value Executable List files for which the application has execute
+ access. Executables needs to be combined with Dirs or Files.
+ \value RWEMask A tqmask for the Readable, Writable and Executable flags.
+ \value Modified Only list files that have been modified (ignored
+ under Unix).
+ \value Hidden List hidden files (on Unix, files starting with a .).
+ \value System List system files (on Unix, FIFOs, sockets and
+ tqdevice files)
+ \value AccessMask A tqmask for the Readable, Writable, Executable
+ Modified, Hidden and System flags
+ \value DefaultFilter Internal flag.
+
+ If you do not set any of \c Readable, \c Writable or \c
+ Executable, TQDir will set all three of them. This makes the
+ default easy to write and at the same time useful.
+
+ Examples: \c Readable|Writable means list all files for which the
+ application has read access, write access or both. \c Dirs|Drives
+ means list drives, directories, all files that the application can
+ read, write or execute, and also symlinks to such
+ files/directories.
+*/
+
+
+/*!
+ Sets the filter used by entryList() and entryInfoList() to \a
+ filterSpec. The filter is used to specify the kind of files that
+ should be returned by entryList() and entryInfoList(). See
+ \l{TQDir::FilterSpec}.
+
+ \sa filter(), setNameFilter()
+*/
+
+void TQDir::setFilter( int filterSpec )
+{
+ if ( filtS == (FilterSpec) filterSpec )
+ return;
+ filtS = (FilterSpec) filterSpec;
+ dirty = TRUE;
+}
+
+/*!
+ \fn TQDir::SortSpec TQDir::sorting() const
+
+ Returns the value set by setSorting()
+
+ \sa setSorting() SortSpec
+*/
+
+/*!
+ \enum TQDir::SortSpec
+
+ This enum describes the sort options available to TQDir, e.g. for
+ entryList() and entryInfoList(). The sort value is specified by
+ OR-ing together values from the following list:
+
+ \value Name Sort by name.
+ \value Time Sort by time (modification time).
+ \value Size Sort by file size.
+ \value Unsorted Do not sort.
+ \value SortByMask A tqmask for Name, Time and Size.
+
+ \value DirsFirst Put the directories first, then the files.
+ \value Reversed Reverse the sort order.
+ \value IgnoreCase Sort case-insensitively.
+ \value LocaleAware Sort names using locale aware compares
+ \value DefaultSort Internal flag.
+
+ You can only specify one of the first four.
+
+ If you specify both \c DirsFirst and \c Reversed, directories are
+ still put first, but in reverse order; the files will be listed
+ after the directories, again in reverse order.
+*/
+
+// ### Unsorted+DirsFirst ? Unsorted+Reversed?
+
+/*!
+ Sets the sort order used by entryList() and entryInfoList().
+
+ The \a sortSpec is specified by OR-ing values from the enum
+ \l{TQDir::SortSpec}.
+
+ \sa sorting() SortSpec
+*/
+
+void TQDir::setSorting( int sortSpec )
+{
+ if ( sortS == (SortSpec) sortSpec )
+ return;
+ sortS = (SortSpec) sortSpec;
+ dirty = TRUE;
+}
+
+/*!
+ \fn bool TQDir::matchAllDirs() const
+
+ Returns the value set by setMatchAllDirs()
+
+ \sa setMatchAllDirs()
+*/
+
+/*!
+ If \a enable is TRUE then all directories are included (e.g. in
+ entryList()), and the nameFilter() is only applied to the files.
+ If \a enable is FALSE then the nameFilter() is applied to both
+ directories and files.
+
+ \sa matchAllDirs()
+*/
+
+void TQDir::setMatchAllDirs( bool enable )
+{
+ if ( (bool)allDirs == enable )
+ return;
+ allDirs = enable;
+ dirty = TRUE;
+}
+
+
+/*!
+ Returns the total number of directories and files that were found.
+
+ Equivalent to entryList().count().
+
+ \sa operator[](), entryList()
+*/
+
+uint TQDir::count() const
+{
+ return (uint)entryList().count();
+}
+
+/*!
+ Returns the file name at position \a index in the list of file
+ names. Equivalent to entryList().at(index).
+
+ Returns a TQString::null if the \a index is out of range or if the
+ entryList() function failed.
+
+ \sa count(), entryList()
+*/
+
+TQString TQDir::operator[]( int index ) const
+{
+ entryList();
+ return fList && index >= 0 && index < (int)fList->count() ?
+ (*fList)[index] : TQString::null;
+}
+
+
+/*!
+ \obsolete
+ This function is included to easy porting from TQt 1.x to TQt 2.0,
+ it is the same as entryList(), but encodes the filenames as 8-bit
+ strings using TQFile::encodedName().
+
+ It is more efficient to use entryList().
+*/
+TQStrList TQDir::encodedEntryList( int filterSpec, int sortSpec ) const
+{
+ TQStrList r;
+ TQStringList l = entryList(filterSpec,sortSpec);
+ for ( TQStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
+ r.append( TQFile::encodeName(*it) );
+ }
+ return r;
+}
+
+/*!
+ \obsolete
+ \overload
+ This function is included to easy porting from TQt 1.x to TQt 2.0,
+ it is the same as entryList(), but encodes the filenames as 8-bit
+ strings using TQFile::encodedName().
+
+ It is more efficient to use entryList().
+*/
+TQStrList TQDir::encodedEntryList( const TQString &nameFilter,
+ int filterSpec,
+ int sortSpec ) const
+{
+ TQStrList r;
+ TQStringList l = entryList(nameFilter,filterSpec,sortSpec);
+ for ( TQStringList::Iterator it = l.begin(); it != l.end(); ++it ) {
+ r.append( TQFile::encodeName(*it) );
+ }
+ return r;
+}
+
+
+
+/*!
+ \overload
+
+ Returns a list of the names of all the files and directories in
+ the directory, ordered in accordance with setSorting() and
+ filtered in accordance with setFilter() and setNameFilter().
+
+ The filter and sorting specifications can be overridden using the
+ \a filterSpec and \a sortSpec arguments.
+
+ Returns an empty list if the directory is unreadable or does not
+ exist.
+
+ \sa entryInfoList(), setNameFilter(), setSorting(), setFilter()
+*/
+
+TQStringList TQDir::entryList( int filterSpec, int sortSpec ) const
+{
+ if ( !dirty && filterSpec == (int)DefaultFilter &&
+ sortSpec == (int)DefaultSort )
+ return *fList;
+ return entryList( nameFilt, filterSpec, sortSpec );
+}
+
+/*!
+ Returns a list of the names of all the files and directories in
+ the directory, ordered in accordance with setSorting() and
+ filtered in accordance with setFilter() and setNameFilter().
+
+ The filter and sorting specifications can be overridden using the
+ \a nameFilter, \a filterSpec and \a sortSpec arguments.
+
+ Returns an empty list if the directory is unreadable or does not
+ exist.
+
+ \sa entryInfoList(), setNameFilter(), setSorting(), setFilter()
+*/
+
+TQStringList TQDir::entryList( const TQString &nameFilter,
+ int filterSpec, int sortSpec ) const
+{
+ if ( filterSpec == (int)DefaultFilter )
+ filterSpec = filtS;
+ if ( sortSpec == (int)DefaultSort )
+ sortSpec = sortS;
+ TQDir *that = (TQDir*)this; // mutable function
+ if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) ) {
+ if ( that->fList )
+ return *that->fList;
+ }
+ return TQStringList();
+}
+
+/*!
+ \overload
+
+ Returns a list of TQFileInfo objects for all the files and
+ directories in the directory, ordered in accordance with
+ setSorting() and filtered in accordance with setFilter() and
+ setNameFilter().
+
+ The filter and sorting specifications can be overridden using the
+ \a filterSpec and \a sortSpec arguments.
+
+ Returns 0 if the directory is unreadable or does not exist.
+
+ The returned pointer is a const pointer to a TQFileInfoList. The
+ list is owned by the TQDir object and will be reused on the next
+ call to entryInfoList() for the same TQDir instance. If you want to
+ keep the entries of the list after a subsequent call to this
+ function you must copy them.
+
+ Note: TQFileInfoList is really a TQPtrList<TQFileInfo>.
+
+ \sa entryList(), setNameFilter(), setSorting(), setFilter()
+*/
+
+const TQFileInfoList *TQDir::entryInfoList( int filterSpec, int sortSpec ) const
+{
+ if ( !dirty && filterSpec == (int)DefaultFilter &&
+ sortSpec == (int)DefaultSort )
+ return fiList;
+ return entryInfoList( nameFilt, filterSpec, sortSpec );
+}
+
+/*!
+ Returns a list of TQFileInfo objects for all the files and
+ directories in the directory, ordered in accordance with
+ setSorting() and filtered in accordance with setFilter() and
+ setNameFilter().
+
+ The filter and sorting specifications can be overridden using the
+ \a nameFilter, \a filterSpec and \a sortSpec arguments.
+
+ Returns 0 if the directory is unreadable or does not exist.
+
+ The returned pointer is a const pointer to a TQFileInfoList. The
+ list is owned by the TQDir object and will be reused on the next
+ call to entryInfoList() for the same TQDir instance. If you want to
+ keep the entries of the list after a subsequent call to this
+ function you must copy them.
+
+ Note: TQFileInfoList is really a TQPtrList<TQFileInfo>.
+
+ \sa entryList(), setNameFilter(), setSorting(), setFilter()
+*/
+
+const TQFileInfoList *TQDir::entryInfoList( const TQString &nameFilter,
+ int filterSpec, int sortSpec ) const
+{
+ if ( filterSpec == (int)DefaultFilter )
+ filterSpec = filtS;
+ if ( sortSpec == (int)DefaultSort )
+ sortSpec = sortS;
+ TQDir *that = (TQDir*)this; // mutable function
+ if ( that->readDirEntries(nameFilter, filterSpec, sortSpec) )
+ return that->fiList;
+ else
+ return 0;
+}
+
+/*!
+ \overload
+
+ Returns TRUE if the \e directory exists; otherwise returns FALSE.
+ (If a file with the same name is found this function will return
+ FALSE).
+
+ \sa TQFileInfo::exists(), TQFile::exists()
+*/
+
+bool TQDir::exists() const
+{
+ TQFileInfo fi( dPath );
+ return fi.exists() && fi.isDir();
+}
+
+/*!
+ Returns TRUE if the directory path is relative to the current
+ directory and returns FALSE if the path is absolute (e.g. under
+ UNIX a path is relative if it does not start with a "/").
+
+ \sa convertToAbs()
+*/
+
+bool TQDir::isRelative() const
+{
+ return isRelativePath( dPath );
+}
+
+/*!
+ Converts the directory path to an absolute path. If it is already
+ absolute nothing is done.
+
+ \sa isRelative()
+*/
+
+void TQDir::convertToAbs()
+{
+ dPath = absPath();
+}
+
+/*!
+ Makes a copy of TQDir \a d and assigns it to this TQDir.
+*/
+
+TQDir &TQDir::operator=( const TQDir &d )
+{
+ dPath = d.dPath;
+ delete fList;
+ fList = 0;
+ delete fiList;
+ fiList = 0;
+ nameFilt = d.nameFilt;
+ dirty = TRUE;
+ allDirs = d.allDirs;
+ filtS = d.filtS;
+ sortS = d.sortS;
+ return *this;
+}
+
+/*!
+ \overload
+
+ Sets the directory path to be the given \a path.
+*/
+
+TQDir &TQDir::operator=( const TQString &path )
+{
+ dPath = cleanDirPath( path );
+ dirty = TRUE;
+ return *this;
+}
+
+
+/*!
+ \fn bool TQDir::operator!=( const TQDir &d ) const
+
+ Returns TRUE if directory \a d and this directory have different
+ paths or different sort or filter settings; otherwise returns
+ FALSE.
+
+ Example:
+ \code
+ // The current directory is "/usr/local"
+ TQDir d1( "/usr/local/bin" );
+ TQDir d2( "bin" );
+ if ( d1 != d2 )
+ qDebug( "They differ" );
+ \endcode
+*/
+
+/*!
+ Returns TRUE if directory \a d and this directory have the same
+ path and their sort and filter settings are the same; otherwise
+ returns FALSE.
+
+ Example:
+ \code
+ // The current directory is "/usr/local"
+ TQDir d1( "/usr/local/bin" );
+ TQDir d2( "bin" );
+ d2.convertToAbs();
+ if ( d1 == d2 )
+ qDebug( "They're the same" );
+ \endcode
+*/
+
+bool TQDir::operator==( const TQDir &d ) const
+{
+ return dPath == d.dPath &&
+ nameFilt == d.nameFilt &&
+ allDirs == d.allDirs &&
+ filtS == d.filtS &&
+ sortS == d.sortS;
+}
+
+
+/*!
+ Removes the file, \a fileName.
+
+ If \a acceptAbsPath is TRUE a path starting with separator "/"
+ will remove the file with the absolute path. If \a acceptAbsPath
+ is FALSE any number of separators at the beginning of \a fileName
+ will be removed and the resultant file name will be removed.
+
+ Returns TRUE if the file is removed successfully; otherwise
+ returns FALSE.
+*/
+
+bool TQDir::remove( const TQString &fileName, bool acceptAbsPath )
+{
+ if ( fileName.isEmpty() ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQDir::remove: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+ TQString p = filePath( fileName, acceptAbsPath );
+ return TQFile::remove( p );
+}
+
+/*!
+ Checks for the existence of the file \a name.
+
+ If \a acceptAbsPath is TRUE a path starting with separator "/"
+ will check the file with the absolute path. If \a acceptAbsPath is
+ FALSE any number of separators at the beginning of \a name will be
+ removed and the resultant file name will be checked.
+
+ Returns TRUE if the file exists; otherwise returns FALSE.
+
+ \sa TQFileInfo::exists(), TQFile::exists()
+*/
+
+bool TQDir::exists( const TQString &name, bool acceptAbsPath ) //### const in 4.0
+{
+ if ( name.isEmpty() ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQDir::exists: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+ TQString tmp = filePath( name, acceptAbsPath );
+ return TQFile::exists( tmp );
+}
+
+/*!
+ Returns the native directory separator; "/" under UNIX (including
+ Mac OS X) and "\" under Windows.
+
+ You do not need to use this function to build file paths. If you
+ always use "/", TQt will translate your paths to conform to the
+ underlying operating system.
+*/
+
+char TQDir::separator()
+{
+#if defined(TQ_OS_UNIX)
+ return '/';
+#elif defined (TQ_FS_FAT) || defined(TQ_WS_WIN)
+ return '\\';
+#elif defined (TQ_OS_MAC)
+ return ':';
+#else
+ return '/';
+#endif
+}
+
+/*!
+ Returns the application's current directory.
+
+ Use path() to access a TQDir object's path.
+
+ \sa currentDirPath(), TQDir::TQDir()
+*/
+
+TQDir TQDir::current()
+{
+ return TQDir( currentDirPath() );
+}
+
+/*!
+ Returns the home directory.
+
+ Under Windows the \c HOME environment variable is used. If this
+ does not exist the \c USERPROFILE environment variable is used. If
+ that does not exist the path is formed by concatenating the \c
+ HOMEDRIVE and \c HOMEPATH environment variables. If they don't
+ exist the rootDirPath() is used (this uses the \c SystemDrive
+ environment variable). If none of these exist "C:\" is used.
+
+ Under non-Windows operating systems the \c HOME environment
+ variable is used if it exists, otherwise rootDirPath() is used.
+
+ \sa homeDirPath()
+*/
+
+TQDir TQDir::home()
+{
+ return TQDir( homeDirPath() );
+}
+
+/*!
+ Returns the root directory.
+
+ \sa rootDirPath() drives()
+*/
+
+TQDir TQDir::root()
+{
+ return TQDir( rootDirPath() );
+}
+
+/*!
+ \fn TQString TQDir::homeDirPath()
+
+ Returns the absolute path of the user's home directory.
+
+ \sa home()
+*/
+
+TQValueList<TQRegExp> qt_makeFilterList( const TQString &filter )
+{
+ TQValueList<TQRegExp> regExps;
+ if ( filter.isEmpty() )
+ return regExps;
+
+ TQChar sep( ';' );
+ int i = filter.tqfind( sep, 0 );
+ if ( i == -1 && filter.tqfind( ' ', 0 ) != -1 )
+ sep = TQChar( ' ' );
+
+ TQStringList list = TQStringList::split( sep, filter );
+ TQStringList::Iterator it = list.begin();
+ while ( it != list.end() ) {
+ regExps << TQRegExp( (*it).stripWhiteSpace(), CaseSensitiveFS, TRUE );
+ ++it;
+ }
+ return regExps;
+}
+
+bool qt_matchFilterList( const TQValueList<TQRegExp>& filters,
+ const TQString &fileName )
+{
+ TQValueList<TQRegExp>::ConstIterator rit = filters.begin();
+ while ( rit != filters.end() ) {
+ if ( (*rit).exactMatch(fileName) )
+ return TRUE;
+ ++rit;
+ }
+ return FALSE;
+}
+
+
+/*!
+ \overload
+
+ Returns TRUE if the \a fileName matches any of the wildcard (glob)
+ patterns in the list of \a filters; otherwise returns FALSE.
+
+ (See \link tqregexp.html#wildcard-matching TQRegExp wildcard
+ matching.\endlink)
+ \sa TQRegExp::match()
+*/
+
+bool TQDir::match( const TQStringList &filters, const TQString &fileName )
+{
+ TQStringList::ConstIterator sit = filters.begin();
+ while ( sit != filters.end() ) {
+ TQRegExp rx( *sit, CaseSensitiveFS, TRUE );
+ if ( rx.exactMatch(fileName) )
+ return TRUE;
+ ++sit;
+ }
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the \a fileName matches the wildcard (glob)
+ pattern \a filter; otherwise returns FALSE. The \a filter may
+ contain multiple patterns separated by spaces or semicolons.
+
+ (See \link tqregexp.html#wildcard-matching TQRegExp wildcard
+ matching.\endlink)
+ \sa TQRegExp::match()
+*/
+
+bool TQDir::match( const TQString &filter, const TQString &fileName )
+{
+ return qt_matchFilterList( qt_makeFilterList(filter), fileName );
+}
+
+
+/*!
+ Removes all multiple directory separators "/" and resolves any
+ "."s or ".."s found in the path, \a filePath.
+
+ Symbolic links are kept. This function does not return the
+ canonical path, but rather the simplest version of the input.
+ For example, "./local" becomes "local", "local/../bin" becomes
+ "bin" and "/local/usr/../bin" becomes "/local/bin".
+
+ \sa absPath() canonicalPath()
+*/
+
+TQString TQDir::cleanDirPath( const TQString &filePath )
+{
+ TQString name = filePath;
+ TQString newPath;
+
+ if ( name.isEmpty() )
+ return name;
+
+ slashify( name );
+
+ bool addedSeparator = isRelativePath( name );
+ if ( addedSeparator )
+ name.insert( 0, '/' );
+
+ int ePos, pos, upLevel;
+
+ pos = ePos = name.length();
+ upLevel = 0;
+ int len;
+
+ while ( pos && (pos = name.tqfindRev('/', pos - 1)) != -1 ) {
+ len = ePos - pos - 1;
+ if ( len == 2 && name.at(pos + 1) == '.'
+ && name.at(pos + 2) == '.' ) {
+ upLevel++;
+ } else {
+ if ( len != 0 && (len != 1 || name.at(pos + 1) != '.') ) {
+ if ( !upLevel )
+ newPath = TQString::tqfromLatin1("/")
+ + name.mid(pos + 1, len) + newPath;
+ else
+ upLevel--;
+ }
+ }
+ ePos = pos;
+ }
+ if ( addedSeparator ) {
+ while ( upLevel-- )
+ newPath.insert( 0, TQString::tqfromLatin1("/..") );
+ if ( !newPath.isEmpty() )
+ newPath.remove( (uint)0, (uint)1 );
+ else
+ newPath = TQString::tqfromLatin1(".");
+ } else {
+ if ( newPath.isEmpty() )
+ newPath = TQString::tqfromLatin1("/");
+#if defined(TQ_FS_FAT) || defined(TQ_OS_OS2EMX)
+ if ( name[0] == '/' ) {
+ if ( name[1] == '/' ) // "\\machine\x\ ..."
+ newPath.insert( 0, '/' );
+ } else {
+ newPath = name.left(2) + newPath;
+ }
+#endif
+ }
+ return newPath;
+}
+
+int qt_cmp_si_sortSpec;
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+#ifdef TQ_OS_TEMP
+int __cdecl qt_cmp_si( const void *n1, const void *n2 )
+#else
+int qt_cmp_si( const void *n1, const void *n2 )
+#endif
+{
+ if ( !n1 || !n2 )
+ return 0;
+
+ TQDirSortItem* f1 = (TQDirSortItem*)n1;
+ TQDirSortItem* f2 = (TQDirSortItem*)n2;
+
+ if ( qt_cmp_si_sortSpec & TQDir::DirsFirst )
+ if ( f1->item->isDir() != f2->item->isDir() )
+ return f1->item->isDir() ? -1 : 1;
+
+ int r = 0;
+ int sortBy = qt_cmp_si_sortSpec & TQDir::SortByMask;
+
+ switch ( sortBy ) {
+ case TQDir::Time:
+ r = f1->item->lastModified().secsTo(f2->item->lastModified());
+ break;
+ case TQDir::Size:
+ r = f2->item->size() - f1->item->size();
+ break;
+ default:
+ ;
+ }
+
+ if ( r == 0 && sortBy != TQDir::Unsorted ) {
+ // Still not sorted - sort by name
+ bool ic = qt_cmp_si_sortSpec & TQDir::IgnoreCase;
+
+ if ( f1->filename_cache.isNull() )
+ f1->filename_cache = ic ? f1->item->fileName().lower()
+ : f1->item->fileName();
+ if ( f2->filename_cache.isNull() )
+ f2->filename_cache = ic ? f2->item->fileName().lower()
+ : f2->item->fileName();
+
+ r = qt_cmp_si_sortSpec & TQDir::LocaleAware
+ ? f1->filename_cache.localeAwareCompare(f2->filename_cache)
+ : f1->filename_cache.compare(f2->filename_cache);
+ }
+
+ if ( r == 0 ) {
+ // Enforce an order - the order the items appear in the array
+ r = (char*)n1 - (char*)n2;
+ }
+
+ if ( qt_cmp_si_sortSpec & TQDir::Reversed )
+ return -r;
+ else
+ return r;
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+/*! \internal
+ Detaches all internal data.
+*/
+void TQDir::detach()
+{
+ // deepcopy
+ dPath = TQDeepCopy<TQString>(dPath);
+ nameFilt = TQDeepCopy<TQString>(nameFilt);
+
+ if ( fList )
+ *fList = TQDeepCopy<TQStringList>( *fList );
+
+ if ( fiList ) {
+ TQFileInfoList *newlist = new TQFileInfoList( *fiList );
+ delete fiList;
+ fiList = newlist;
+ }
+}
+
+#endif // TQT_NO_DIR
diff --git a/tqtinterface/qt4/src/tools/tqdir.h b/tqtinterface/qt4/src/tools/tqdir.h
new file mode 100644
index 0000000..864a37e
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdir.h
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** Definition of TQDir class
+**
+** Created : 950427
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDIR_H
+#define TQDIR_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqstrlist.h"
+#include "tqfileinfo.h"
+#endif // TQT_H
+
+
+#ifndef TQT_NO_DIR
+typedef TQPtrList<TQFileInfo> TQFileInfoList;
+typedef TQPtrListIterator<TQFileInfo> TQFileInfoListIterator;
+class TQStringList;
+template <class T> class TQDeepCopy;
+
+
+class TQ_EXPORT TQDir
+{
+public:
+ enum FilterSpec { Dirs = 0x001,
+ Files = 0x002,
+ Drives = 0x004,
+ NoSymLinks = 0x008,
+ All = 0x007,
+ TypeMask = 0x00F,
+
+ Readable = 0x010,
+ Writable = 0x020,
+ Executable = 0x040,
+ RWEMask = 0x070,
+
+ Modified = 0x080,
+ Hidden = 0x100,
+ System = 0x200,
+ AccessMask = 0x3F0,
+
+ DefaultFilter = -1 };
+
+ enum SortSpec { Name = 0x00,
+ Time = 0x01,
+ Size = 0x02,
+ Unsorted = 0x03,
+ SortByMask = 0x03,
+
+ DirsFirst = 0x04,
+ Reversed = 0x08,
+ IgnoreCase = 0x10,
+ LocaleAware = 0x20,
+ DefaultSort = -1 };
+
+ TQDir();
+ TQDir( const TQString &path, const TQString &nameFilter = TQString::null,
+ int sortSpec = Name | IgnoreCase, int filterSpec = All );
+ TQDir( const TQDir & );
+
+ virtual ~TQDir();
+
+ TQDir &operator=( const TQDir & );
+ TQDir &operator=( const TQString &path );
+
+ virtual void setPath( const TQString &path );
+ virtual TQString path() const;
+ virtual TQString absPath() const;
+ virtual TQString canonicalPath() const;
+
+ virtual TQString dirName() const;
+ virtual TQString filePath( const TQString &fileName,
+ bool acceptAbsPath = TRUE ) const;
+ virtual TQString absFilePath( const TQString &fileName,
+ bool acceptAbsPath = TRUE ) const;
+
+ static TQString convertSeparators( const TQString &pathName );
+
+ virtual bool cd( const TQString &dirName, bool acceptAbsPath = TRUE );
+ virtual bool cdUp();
+
+ TQString nameFilter() const;
+ virtual void setNameFilter( const TQString &nameFilter );
+ FilterSpec filter() const;
+ virtual void setFilter( int filterSpec );
+ SortSpec sorting() const;
+ virtual void setSorting( int sortSpec );
+
+ bool matchAllDirs() const;
+ virtual void setMatchAllDirs( bool );
+
+ uint count() const;
+ TQString operator[]( int ) const;
+
+ virtual TQStrList encodedEntryList( int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual TQStrList encodedEntryList( const TQString &nameFilter,
+ int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual TQStringList entryList( int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual TQStringList entryList( const TQString &nameFilter,
+ int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+
+ virtual const TQFileInfoList *entryInfoList( int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+ virtual const TQFileInfoList *entryInfoList( const TQString &nameFilter,
+ int filterSpec = DefaultFilter,
+ int sortSpec = DefaultSort ) const;
+
+ static const TQFileInfoList *drives();
+
+ virtual bool mkdir( const TQString &dirName,
+ bool acceptAbsPath = TRUE ) const;
+ virtual bool rmdir( const TQString &dirName,
+ bool acceptAbsPath = TRUE ) const;
+
+ virtual bool isReadable() const;
+ virtual bool exists() const;
+ virtual bool isRoot() const;
+
+ virtual bool isRelative() const;
+ virtual void convertToAbs();
+
+ virtual bool operator==( const TQDir & ) const;
+ virtual bool operator!=( const TQDir & ) const;
+
+ virtual bool remove( const TQString &fileName,
+ bool acceptAbsPath = TRUE );
+ virtual bool rename( const TQString &name, const TQString &newName,
+ bool acceptAbsPaths = TRUE );
+ virtual bool exists( const TQString &name,
+ bool acceptAbsPath = TRUE );
+
+ static char separator();
+
+ static bool setCurrent( const TQString &path );
+ static TQDir current();
+ static TQDir home();
+ static TQDir root();
+ static TQString currentDirPath();
+ static TQString homeDirPath();
+ static TQString rootDirPath();
+
+ static bool match( const TQStringList &filters, const TQString &fileName );
+ static bool match( const TQString &filter, const TQString &fileName );
+ static TQString cleanDirPath( const TQString &dirPath );
+ static bool isRelativePath( const TQString &path );
+ void refresh() const;
+
+private:
+#ifdef TQ_OS_MAC
+ typedef struct FSSpec FSSpec;
+ static FSSpec *make_spec(const TQString &);
+#endif
+ void init();
+ virtual bool readDirEntries( const TQString &nameFilter,
+ int FilterSpec, int SortSpec );
+
+ static void slashify( TQString & );
+
+ TQString dPath;
+ TQStringList *fList;
+ TQFileInfoList *fiList;
+ TQString nameFilt;
+ FilterSpec filtS;
+ SortSpec sortS;
+ uint dirty : 1;
+ uint allDirs : 1;
+
+ void detach();
+ friend class TQDeepCopy< TQDir >;
+};
+
+
+inline TQString TQDir::path() const
+{
+ return dPath;
+}
+
+inline TQString TQDir::nameFilter() const
+{
+ return nameFilt;
+}
+
+inline TQDir::FilterSpec TQDir::filter() const
+{
+ return filtS;
+}
+
+inline TQDir::SortSpec TQDir::sorting() const
+{
+ return sortS;
+}
+
+inline bool TQDir::matchAllDirs() const
+{
+ return allDirs;
+}
+
+inline bool TQDir::operator!=( const TQDir &d ) const
+{
+ return !(*this == d);
+}
+
+
+struct TQDirSortItem {
+ TQString filename_cache;
+ TQFileInfo* item;
+};
+
+#endif // TQT_NO_DIR
+#endif // TQDIR_H
diff --git a/tqtinterface/qt4/src/tools/tqdir_p.h b/tqtinterface/qt4/src/tools/tqdir_p.h
new file mode 100644
index 0000000..802771a
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdir_p.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Definition of some private TQDir functions.
+**
+** Created : 001106
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDIR_P_H
+#define TQDIR_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qdir.cpp and qdir_*.cpp.
+// This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqregexp.h"
+#include "tqvaluelist.h"
+#endif // TQT_H
+
+extern TQValueList<TQRegExp> qt_makeFilterList( const TQString & );
+extern bool qt_matchFilterList( const TQValueList<TQRegExp> &, const TQString & );
+
+extern int qt_cmp_si_sortSpec;
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+#ifdef TQ_OS_TEMP
+extern int __cdecl qt_cmp_si( const void *, const void * );
+#else
+extern int qt_cmp_si( const void *, const void * );
+#endif
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+#endif // TQDIR_P_H
diff --git a/tqtinterface/qt4/src/tools/tqdir_unix.cpp b/tqtinterface/qt4/src/tools/tqdir_unix.cpp
new file mode 100644
index 0000000..5d69993
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqdir_unix.cpp
@@ -0,0 +1,302 @@
+/****************************************************************************
+**
+** Implementation of TQDir class
+**
+** Created : 950628
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+#include "tqdir.h"
+
+#ifndef TQT_NO_DIR
+
+#include "tqdir_p.h"
+#include "tqfileinfo.h"
+#include "tqregexp.h"
+#include "tqstringlist.h"
+
+#ifdef TQT_THREAD_SUPPORT
+# include <private/tqmutexpool_p.h>
+#endif // TQT_THREAD_SUPPORT
+
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+
+
+void TQDir::slashify( TQString& )
+{
+}
+
+TQString TQDir::homeDirPath()
+{
+ TQString d;
+ d = TQFile::decodeName(getenv("HOME"));
+ slashify( d );
+ if ( d.isNull() )
+ d = rootDirPath();
+ return d;
+}
+
+TQString TQDir::canonicalPath() const
+{
+ TQString r;
+ char cur[PATH_MAX+1];
+ if ( ::getcwd( cur, PATH_MAX ) ) {
+ char tmp[PATH_MAX+1];
+ // need the cast for old solaris versions of realpath that doesn't take
+ // a const char*.
+ if( ::realpath( (char*)TQFile::encodeName( dPath ).data(), tmp ) )
+ r = TQFile::decodeName( tmp );
+ slashify( r );
+
+ // always make sure we go back to the current dir
+ ::chdir( cur );
+ }
+ return r;
+}
+
+bool TQDir::mkdir( const TQString &dirName, bool acceptAbsPath ) const
+{
+#if defined(TQ_OS_MACX) // Mac X doesn't support trailing /'s
+ TQString name = dirName;
+ if (dirName[dirName.length() - 1] == "/")
+ name = dirName.left( dirName.length() - 1 );
+ int status =
+ ::mkdir( TQFile::encodeName(filePath(name,acceptAbsPath)), 0777 );
+#else
+ int status =
+ ::mkdir( TQFile::encodeName(filePath(dirName,acceptAbsPath)), 0777 );
+#endif
+ return status == 0;
+}
+
+bool TQDir::rmdir( const TQString &dirName, bool acceptAbsPath ) const
+{
+ return ::rmdir( TQFile::encodeName(filePath(dirName,acceptAbsPath)) ) == 0;
+}
+
+bool TQDir::isReadable() const
+{
+ return ::access( TQFile::encodeName(dPath), R_OK | X_OK ) == 0;
+}
+
+bool TQDir::isRoot() const
+{
+ return dPath == TQString::tqfromLatin1("/");
+}
+
+bool TQDir::rename( const TQString &name, const TQString &newName,
+ bool acceptAbsPaths )
+{
+ if ( name.isEmpty() || newName.isEmpty() ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQDir::rename: Empty or null file name(s)" );
+#endif
+ return FALSE;
+ }
+ TQString fn1 = filePath( name, acceptAbsPaths );
+ TQString fn2 = filePath( newName, acceptAbsPaths );
+ return ::rename( TQFile::encodeName(fn1),
+ TQFile::encodeName(fn2) ) == 0;
+}
+
+bool TQDir::setCurrent( const TQString &path )
+{
+ int r;
+ r = ::chdir( TQFile::encodeName(path) );
+ return r >= 0;
+}
+
+TQString TQDir::currentDirPath()
+{
+ TQString result;
+
+ struct stat st;
+ if ( ::stat( ".", &st ) == 0 ) {
+ char currentName[PATH_MAX+1];
+ if ( ::getcwd( currentName, PATH_MAX ) )
+ result = TQFile::decodeName(currentName);
+#if defined(TQT_DEBUG)
+ if ( result.isNull() )
+ qWarning( "TQDir::currentDirPath: getcwd() failed" );
+#endif
+ } else {
+#if defined(TQT_DEBUG)
+ qWarning( "TQDir::currentDirPath: stat(\".\") failed" );
+#endif
+ }
+ slashify( result );
+ return result;
+}
+
+TQString TQDir::rootDirPath()
+{
+ TQString d = TQString::tqfromLatin1( "/" );
+ return d;
+}
+
+bool TQDir::isRelativePath( const TQString &path )
+{
+ int len = path.length();
+ if ( len == 0 )
+ return TRUE;
+ return path[0] != '/';
+}
+
+bool TQDir::readDirEntries( const TQString &nameFilter,
+ int filterSpec, int sortSpec )
+{
+ int i;
+ if ( !fList ) {
+ fList = new TQStringList;
+ TQ_CHECK_PTR( fList );
+ fiList = new TQFileInfoList;
+ TQ_CHECK_PTR( fiList );
+ fiList->setAutoDelete( TRUE );
+ } else {
+ fList->clear();
+ fiList->clear();
+ }
+
+ TQValueList<TQRegExp> filters = qt_makeFilterList( nameFilter );
+
+ bool doDirs = (filterSpec & Dirs) != 0;
+ bool doFiles = (filterSpec & Files) != 0;
+ bool noSymLinks = (filterSpec & NoSymLinks) != 0;
+ bool doReadable = (filterSpec & Readable) != 0;
+ bool doWritable = (filterSpec & Writable) != 0;
+ bool doExecable = (filterSpec & Executable) != 0;
+ bool doHidden = (filterSpec & Hidden) != 0;
+ bool doSystem = (filterSpec & System) != 0;
+
+ TQFileInfo fi;
+ DIR *dir;
+ dirent *file;
+
+ dir = opendir( TQFile::encodeName(dPath) );
+ if ( !dir )
+ return FALSE; // cannot read the directory
+
+#if defined(TQT_THREAD_SUPPORT) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(TQ_OS_CYGWIN)
+ union {
+ struct dirent mt_file;
+ char b[sizeof(struct dirent) + MAXNAMLEN + 1];
+ } u;
+ while ( readdir_r(dir, &u.mt_file, &file ) == 0 && file )
+#else
+ while ( (file = readdir(dir)) )
+#endif // TQT_THREAD_SUPPORT && _POSIX_THREAD_SAFE_FUNCTIONS
+ {
+ TQString fn = TQFile::decodeName(file->d_name);
+ fi.setFile( *this, fn );
+ if ( !qt_matchFilterList(filters, fn) && !(allDirs && fi.isDir()) )
+ continue;
+ if ( (doDirs && fi.isDir()) || (doFiles && fi.isFile()) ||
+ (doSystem && (!fi.isFile() && !fi.isDir())) ) {
+ if ( noSymLinks && fi.isSymLink() )
+ continue;
+ if ( (filterSpec & RWEMask) != 0 )
+ if ( (doReadable && !fi.isReadable()) ||
+ (doWritable && !fi.isWritable()) ||
+ (doExecable && !fi.isExecutable()) )
+ continue;
+ if ( !doHidden && fn[0] == '.' &&
+ fn != TQString::tqfromLatin1(".")
+ && fn != TQString::tqfromLatin1("..") )
+ continue;
+ fiList->append( new TQFileInfo( fi ) );
+ }
+ }
+ if ( closedir(dir) != 0 ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQDir::readDirEntries: Cannot close the directory: %s",
+ dPath.local8Bit().data() );
+#endif
+ }
+
+ // Sort...
+ if(fiList->count()) {
+ TQDirSortItem* si= new TQDirSortItem[fiList->count()];
+ TQFileInfo* itm;
+ i=0;
+ for (itm = fiList->first(); itm; itm = fiList->next())
+ si[i++].item = itm;
+ qt_cmp_si_sortSpec = sortSpec;
+ qsort( si, i, sizeof(si[0]), qt_cmp_si );
+ // put them back in the list
+ fiList->setAutoDelete( FALSE );
+ fiList->clear();
+ int j;
+ for ( j=0; j<i; j++ ) {
+ fiList->append( si[j].item );
+ fList->append( si[j].item->fileName() );
+ }
+ delete [] si;
+ fiList->setAutoDelete( TRUE );
+ }
+
+ if ( filterSpec == (FilterSpec)filtS && sortSpec == (SortSpec)sortS &&
+ nameFilter == nameFilt )
+ dirty = FALSE;
+ else
+ dirty = TRUE;
+ return TRUE;
+}
+
+const TQFileInfoList * TQDir::drives()
+{
+ // at most one instance of TQFileInfoList is leaked, and this variable
+ // points to that list
+ static TQFileInfoList * knownMemoryLeak = 0;
+
+ if ( !knownMemoryLeak ) {
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &knownMemoryLeak ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+
+ if ( !knownMemoryLeak ) {
+ knownMemoryLeak = new TQFileInfoList;
+ // non-win32 versions both use just one root directory
+ knownMemoryLeak->append( new TQFileInfo( rootDirPath() ) );
+ }
+ }
+
+ return knownMemoryLeak;
+}
+#endif //TQT_NO_DIR
diff --git a/tqtinterface/qt4/src/tools/tqfeatures.h b/tqtinterface/qt4/src/tools/tqfeatures.h
new file mode 100644
index 0000000..f06fe39
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqfeatures.h
@@ -0,0 +1,984 @@
+// All feature and their dependencies
+//
+// This list is generated from $TQTDIR/src/tools/qfeatures.txt
+//
+// Asynchronous I/O
+//#define TQT_NO_ASYNC_IO
+
+// Bezier curves
+//#define TQT_NO_BEZIER
+
+// Buttons
+//#define TQT_NO_BUTTON
+
+// Named colors
+//#define TQT_NO_COLORNAMES
+
+// Cursors
+//#define TQT_NO_CURSOR
+
+// TQDataStream
+//#define TQT_NO_DATASTREAM
+
+// TQDate/TQTime/TQDateTime toString() and fromString()
+//#define TQT_NO_DATESTRING
+
+// Dialogs
+//#define TQT_NO_DIALOG
+
+// TQDirectPainter
+//#define TQT_NO_DIRECTPAINTER
+
+// Special widget effects (fading, scrolling)
+//#define TQT_NO_EFFECTS
+
+// Freetype font engine
+//#define TQT_NO_FREETYPE
+
+// Dither TQImage to 1-bit image
+//#define TQT_NO_IMAGE_DITHER_TO_1
+
+// TQImage::createHeuristicMask()
+//#define TQT_NO_IMAGE_HEURISTIC_MASK
+
+// TQImage mirroring
+//#define TQT_NO_IMAGE_MIRROR
+
+// Smooth TQImage scaling
+//#define TQT_NO_IMAGE_SMOOTHSCALE
+
+// TrueColor TQImage
+//#define TQT_NO_IMAGE_TRUECOLOR
+
+// Automatic widget tqlayout
+//#define TQT_NO_LAYOUT
+
+// Networking
+//#define TQT_NO_NETWORK
+
+// Palettes
+//#define TQT_NO_PALETTE
+
+// Alpha-blended cursor
+//#define TQT_NO_TQWS_ALPHA_CURSOR
+
+// 1-bit monochrome
+//#define TQT_NO_TQWS_DEPTH_1
+
+// 15 or 16-bit color
+//#define TQT_NO_TQWS_DEPTH_16
+
+// 24-bit color
+//#define TQT_NO_TQWS_DEPTH_24
+
+// 32-bit color
+//#define TQT_NO_TQWS_DEPTH_32
+
+// 4-bit grayscale
+//#define TQT_NO_TQWS_DEPTH_4
+
+// 8-bit color
+//#define TQT_NO_TQWS_DEPTH_8
+
+// 8-bit grayscale
+//#define TQT_NO_TQWS_DEPTH_8GRAYSCALE
+
+// Favour code size over graphics speed
+//#define TQT_NO_TQWS_GFX_SPEED
+
+// Console keyboard
+//#define TQT_NO_TQWS_KEYBOARD
+
+// Linux framebuffer
+//#define TQT_NO_TQWS_LINUXFB
+
+// Mach64 acceleration
+//#define TQT_NO_TQWS_MACH64
+
+// Window Manager
+//#define TQT_NO_TQWS_MANAGER
+
+// Matrox MGA acceleration
+//#define TQT_NO_TQWS_MATROX
+
+// Autodetecting mouse driver
+//#define TQT_NO_TQWS_MOUSE_AUTO
+
+// Non-autodetecting mouse driver
+//#define TQT_NO_TQWS_MOUSE_MANUAL
+
+// TQt/Embedded window system properties.
+//#define TQT_NO_TQWS_PROPERTIES
+
+// Repeater display
+//#define TQT_NO_TQWS_REPEATER
+
+// Saving of fonts
+//#define TQT_NO_TQWS_SAVEFONTS
+
+// Shadow frame buffer
+//#define TQT_NO_TQWS_SHADOWFB
+
+// Virtual frame buffer
+//#define TQT_NO_TQWS_VFB
+
+// 4-bit VGA
+//#define TQT_NO_TQWS_VGA_16
+
+// Voodoo3 acceleration
+//#define TQT_NO_TQWS_VOODOO3
+
+// Range-control widgets
+//#define TQT_NO_RANGECONTROL
+
+// Regular expression capture
+//#define TQT_NO_REGEXP
+
+// TQSignalMapper
+//#define TQT_NO_SIGNALMAPPER
+
+// Playing sounds
+//#define TQT_NO_SOUND
+
+// Standard template library compatiblity
+//#define TQT_NO_STL
+
+// TQStringList
+//#define TQT_NO_STRINGLIST
+
+// Character set conversions
+//#define TQT_NO_TEXTCODEC
+
+// TQTextStream
+//#define TQT_NO_TEXTSTREAM
+
+// Unicode property tables
+//#define TQT_NO_UNICODETABLES
+
+// Input validators
+//#define TQT_NO_VALIDATOR
+
+// TQVariant
+//#define TQT_NO_VARIANT
+
+// Wheel-mouse events
+//#define TQT_NO_WHEELEVENT
+
+// TQWMatrix
+//#define TQT_NO_WMATRIX
+
+// Non-Unicode text conversions
+#if !defined(TQT_NO_CODECS) && (defined(TQT_NO_TEXTCODEC))
+#define TQT_NO_CODECS
+#endif
+
+// TQCop IPC
+#if !defined(TQT_NO_COP) && (defined(TQT_NO_DATASTREAM))
+#define TQT_NO_COP
+#endif
+
+// TQFontDatabase
+#if !defined(TQT_NO_FONTDATABASE) && (defined(TQT_NO_STRINGLIST))
+#define TQT_NO_FONTDATABASE
+#endif
+
+// Image formats
+#if !defined(TQT_NO_IMAGEIO) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_IMAGEIO
+#endif
+
+// 16-bit TQImage
+#if !defined(TQT_NO_IMAGE_16_BIT) && (defined(TQT_NO_IMAGE_TRUECOLOR))
+#define TQT_NO_IMAGE_16_BIT
+#endif
+
+// Image file text strings
+#if !defined(TQT_NO_IMAGE_TEXT) && (defined(TQT_NO_STRINGLIST))
+#define TQT_NO_IMAGE_TEXT
+#endif
+
+// Shared library wrapper
+#if !defined(TQT_NO_LIBRARY) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_LIBRARY
+#endif
+
+// Pixmap transformations
+#if !defined(TQT_NO_PIXMAP_TRANSFORMATION) && (defined(TQT_NO_WMATRIX))
+#define TQT_NO_PIXMAP_TRANSFORMATION
+#endif
+
+// Convert UUID to/from string
+#if !defined(TQT_NO_TQUUID_STRING) && (defined(TQT_NO_STRINGLIST))
+#define TQT_NO_TQUUID_STRING
+#endif
+
+// The "BeOS" style
+#if !defined(TQT_NO_TQWS_BEOS_WM_STYLE) && (defined(TQT_NO_TQWS_MANAGER))
+#define TQT_NO_TQWS_BEOS_WM_STYLE
+#endif
+
+// Visible cursor
+#if !defined(TQT_NO_TQWS_CURSOR) && (defined(TQT_NO_CURSOR))
+#define TQT_NO_TQWS_CURSOR
+#endif
+
+// 32-bit color, BGR order
+#if !defined(TQT_NO_TQWS_DEPTH_32_BGR) && (defined(TQT_NO_TQWS_DEPTH_32))
+#define TQT_NO_TQWS_DEPTH_32_BGR
+#endif
+
+// The "Hydro" style
+#if !defined(TQT_NO_TQWS_HYDRO_WM_STYLE) && (defined(TQT_NO_TQWS_MANAGER))
+#define TQT_NO_TQWS_HYDRO_WM_STYLE
+#endif
+
+// Keyboard for SHARP Zaurus SL5xxx tqdevices
+#if !defined(TQT_NO_TQWS_KBD_SHARP) && (defined(TQT_NO_TQWS_KEYBOARD))
+#define TQT_NO_TQWS_KBD_SHARP
+#endif
+
+// The "KDE2" style
+#if !defined(TQT_NO_TQWS_KDE2_WM_STYLE) && (defined(TQT_NO_TQWS_MANAGER))
+#define TQT_NO_TQWS_KDE2_WM_STYLE
+#endif
+
+// The "KDE" style
+#if !defined(TQT_NO_TQWS_KDE_WM_STYLE) && (defined(TQT_NO_TQWS_MANAGER))
+#define TQT_NO_TQWS_KDE_WM_STYLE
+#endif
+
+// Multi-process architecture
+#if !defined(TQT_NO_TQWS_MULTIPROCESS) && (defined(TQT_NO_NETWORK))
+#define TQT_NO_TQWS_MULTIPROCESS
+#endif
+
+// Transformed frame buffer
+#if !defined(TQT_NO_TQWS_TRANSFORMED) && (defined(TQT_NO_TQWS_LINUXFB))
+#define TQT_NO_TQWS_TRANSFORMED
+#endif
+
+// Remote frame buffer (VNC)
+#if !defined(TQT_NO_TQWS_VNC) && (defined(TQT_NO_NETWORK))
+#define TQT_NO_TQWS_VNC
+#endif
+
+// The "Windows" style
+#if !defined(TQT_NO_TQWS_WINDOWS_WM_STYLE) && (defined(TQT_NO_TQWS_MANAGER))
+#define TQT_NO_TQWS_WINDOWS_WM_STYLE
+#endif
+
+// Regular expression anchors
+#if !defined(TQT_NO_REGEXP_ANCHOR_ALT) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_REGEXP_ANCHOR_ALT
+#endif
+
+// Regular expression back-reference
+#if !defined(TQT_NO_REGEXP_BACKREF) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_REGEXP_BACKREF
+#endif
+
+// Regular expression character-class
+#if !defined(TQT_NO_REGEXP_CCLASS) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_REGEXP_CCLASS
+#endif
+
+// Regular expression escape
+#if !defined(TQT_NO_REGEXP_ESCAPE) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_REGEXP_ESCAPE
+#endif
+
+// Regular expression interval
+#if !defined(TQT_NO_REGEXP_INTERVAL) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_REGEXP_INTERVAL
+#endif
+
+// Regular expression lookahead
+#if !defined(TQT_NO_REGEXP_LOOKAHEAD) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_REGEXP_LOOKAHEAD
+#endif
+
+// Regular expression optimization
+#if !defined(TQT_NO_REGEXP_OPTIM) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_REGEXP_OPTIM
+#endif
+
+// Regular expression wildcard
+#if !defined(TQT_NO_REGEXP_WILDCARD) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_REGEXP_WILDCARD
+#endif
+
+// Semi-modal dialogs
+#if !defined(TQT_NO_SEMIMODAL) && (defined(TQT_NO_DIALOG))
+#define TQT_NO_SEMIMODAL
+#endif
+
+// Session management
+#if !defined(TQT_NO_SESSIONMANAGER) && (defined(TQT_NO_STRINGLIST))
+#define TQT_NO_SESSIONMANAGER
+#endif
+
+// TQString::sprintf()
+#if !defined(TQT_NO_SPRINTF) && (defined(TQT_NO_REGEXP))
+#define TQT_NO_SPRINTF
+#endif
+
+// Scaling and rotation
+#if !defined(TQT_NO_TRANSFORMATIONS) && (defined(TQT_NO_WMATRIX))
+#define TQT_NO_TRANSFORMATIONS
+#endif
+
+// Translations via TQObject::tr()
+#if !defined(TQT_NO_TRANSLATION) && (defined(TQT_NO_DATASTREAM))
+#define TQT_NO_TRANSLATION
+#endif
+
+// Window icon and caption
+#if !defined(TQT_NO_WIDGET_TOPEXTRA) && (defined(TQT_NO_IMAGE_HEURISTIC_MASK))
+#define TQT_NO_WIDGET_TOPEXTRA
+#endif
+
+// Keyboard accelerators and shortcuts
+#if !defined(TQT_NO_ACCEL) && (defined(TQT_NO_SPRINTF))
+#define TQT_NO_ACCEL
+#endif
+
+// Asynchronous image I/O
+#if !defined(TQT_NO_ASYNC_IMAGE_IO) && (defined(TQT_NO_IMAGEIO))
+#define TQT_NO_ASYNC_IMAGE_IO
+#endif
+
+// BDF font files
+#if !defined(TQT_NO_BDF) && (defined(TQT_NO_TEXTSTREAM) || defined(TQT_NO_STRINGLIST))
+#define TQT_NO_BDF
+#endif
+
+// TQDir
+#if !defined(TQT_NO_DIR) && (defined(TQT_NO_STRINGLIST) || defined(TQT_NO_REGEXP))
+#define TQT_NO_DIR
+#endif
+
+// JPEG image I/O
+#if !defined(TQT_NO_IMAGEIO_JPEG) && (defined(TQT_NO_IMAGEIO))
+#define TQT_NO_IMAGEIO_JPEG
+#endif
+
+// MNG image I/O
+#if !defined(TQT_NO_IMAGEIO_MNG) && (defined(TQT_NO_IMAGEIO))
+#define TQT_NO_IMAGEIO_MNG
+#endif
+
+// PNG image I/O
+#if !defined(TQT_NO_IMAGEIO_PNG) && (defined(TQT_NO_IMAGEIO))
+#define TQT_NO_IMAGEIO_PNG
+#endif
+
+// PPM image I/O
+#if !defined(TQT_NO_IMAGEIO_PPM) && (defined(TQT_NO_IMAGEIO))
+#define TQT_NO_IMAGEIO_PPM
+#endif
+
+// XBM image I/O
+#if !defined(TQT_NO_IMAGEIO_XBM) && (defined(TQT_NO_IMAGEIO))
+#define TQT_NO_IMAGEIO_XBM
+#endif
+
+// Image transformations
+#if !defined(TQT_NO_IMAGE_TRANSFORMATION) && (defined(TQT_NO_PIXMAP_TRANSFORMATION))
+#define TQT_NO_IMAGE_TRANSFORMATION
+#endif
+
+// External process invocation.
+#if !defined(TQT_NO_PROCESS) && (defined(TQT_NO_STRINGLIST) || defined(TQT_NO_REGEXP))
+#define TQT_NO_PROCESS
+#endif
+
+// Regular expression capture
+#if !defined(TQT_NO_REGEXP_CAPTURE) && (defined(TQT_NO_REGEXP) || defined(TQT_NO_STRINGLIST))
+#define TQT_NO_REGEXP_CAPTURE
+#endif
+
+// Splash screen widget
+#if !defined(TQT_NO_SPLASHSCREEN) && (defined(TQT_NO_IMAGEIO))
+#define TQT_NO_SPLASHSCREEN
+#endif
+
+// Template classes in TQVariant
+#if !defined(TQT_NO_TEMPLATE_VARIANT) && (defined(TQT_NO_VARIANT) || defined(TQT_NO_STRINGLIST))
+#define TQT_NO_TEMPLATE_VARIANT
+#endif
+
+// Month and day names in dates
+#if !defined(TQT_NO_TEXTDATE) && (defined(TQT_NO_STRINGLIST) || defined(TQT_NO_DATESTRING))
+#define TQT_NO_TEXTDATE
+#endif
+
+// Drawing utility functions
+#if !defined(TQT_NO_DRAWUTIL) && (defined(TQT_NO_SPRINTF) || defined(TQT_NO_PALETTE))
+#define TQT_NO_DRAWUTIL
+#endif
+
+// BMP image I/O
+#if !defined(TQT_NO_IMAGEIO_BMP) && (defined(TQT_NO_IMAGEIO) || defined(TQT_NO_DATASTREAM))
+#define TQT_NO_IMAGEIO_BMP
+#endif
+
+// TQPicture
+#if !defined(TQT_NO_PICTURE) && (defined(TQT_NO_DATASTREAM) || defined(TQT_NO_IMAGEIO))
+#define TQT_NO_PICTURE
+#endif
+
+// Translations via TQObject::trUtf8()
+#if !defined(TQT_NO_TRANSLATION_UTF8) && (defined(TQT_NO_TRANSLATION) || defined(TQT_NO_TEXTCODEC))
+#define TQT_NO_TRANSLATION_UTF8
+#endif
+
+// URL parser
+#if !defined(TQT_NO_URL) && (defined(TQT_NO_DIR))
+#define TQT_NO_URL
+#endif
+
+// Animated images
+#if !defined(TQT_NO_MOVIE) && (defined(TQT_NO_ASYNC_IO) || defined(TQT_NO_ASYNC_IMAGE_IO))
+#define TQT_NO_MOVIE
+#endif
+
+// TQStyle
+#if !defined(TQT_NO_STYLE) && (defined(TQT_NO_DRAWUTIL))
+#define TQT_NO_STYLE
+#endif
+
+// DNS
+#if !defined(TQT_NO_DNS) && (defined(TQT_NO_NETWORK) || defined(TQT_NO_STRINGLIST) || defined(TQT_NO_TEXTSTREAM) || defined(TQT_NO_SPRINTF))
+#define TQT_NO_DNS
+#endif
+
+// Framed widgets
+#if !defined(TQT_NO_FRAME) && (defined(TQT_NO_STYLE))
+#define TQT_NO_FRAME
+#endif
+
+// TQIconSet
+#if !defined(TQT_NO_ICONSET) && (defined(TQT_NO_IMAGEIO) || defined(TQT_NO_IMAGE_SMOOTHSCALE) || defined(TQT_NO_PALETTE) || defined(TQT_NO_IMAGE_HEURISTIC_MASK))
+#define TQT_NO_ICONSET
+#endif
+
+// XPM image I/O
+#if !defined(TQT_NO_IMAGEIO_XPM) && (defined(TQT_NO_IMAGEIO) || defined(TQT_NO_SPRINTF) || defined(TQT_NO_TEXTSTREAM))
+#define TQT_NO_IMAGEIO_XPM
+#endif
+
+// Network file access
+#if !defined(TQT_NO_NETWORKPROTOCOL) && (defined(TQT_NO_TEXTCODEC) || defined(TQT_NO_URL))
+#define TQT_NO_NETWORKPROTOCOL
+#endif
+
+// TQSizeGrip
+#if !defined(TQT_NO_SIZEGRIP) && (defined(TQT_NO_STYLE))
+#define TQT_NO_SIZEGRIP
+#endif
+
+// Motif style
+#if !defined(TQT_NO_STYLE_MOTIF) && (defined(TQT_NO_STYLE))
+#define TQT_NO_STYLE_MOTIF
+#endif
+
+// Windows style
+#if !defined(TQT_NO_STYLE_WINDOWS) && (defined(TQT_NO_STYLE))
+#define TQT_NO_STYLE_WINDOWS
+#endif
+
+// Internal titlebar widget
+#if !defined(TQT_NO_TITLEBAR) && (defined(TQT_NO_STYLE))
+#define TQT_NO_TITLEBAR
+#endif
+
+// XML
+#if !defined(TQT_NO_XML) && (defined(TQT_NO_TEXTSTREAM) || defined(TQT_NO_TEXTCODEC) || defined(TQT_NO_REGEXP_CAPTURE))
+#define TQT_NO_XML
+#endif
+
+// Check-boxes
+#if !defined(TQT_NO_CHECKBOX) && (defined(TQT_NO_BUTTON) || defined(TQT_NO_STYLE))
+#define TQT_NO_CHECKBOX
+#endif
+
+// Dials
+#if !defined(TQT_NO_DIAL) && (defined(TQT_NO_RANGECONTROL) || defined(TQT_NO_STYLE))
+#define TQT_NO_DIAL
+#endif
+
+// TQLabel
+#if !defined(TQT_NO_LABEL) && (defined(TQT_NO_FRAME))
+#define TQT_NO_LABEL
+#endif
+
+// TQLCDNumber
+#if !defined(TQT_NO_LCDNUMBER) && (defined(TQT_NO_FRAME))
+#define TQT_NO_LCDNUMBER
+#endif
+
+// Single-line edits
+#if !defined(TQT_NO_LINEEDIT) && (defined(TQT_NO_FRAME))
+#define TQT_NO_LINEEDIT
+#endif
+
+// MIME
+#if !defined(TQT_NO_MIME) && (defined(TQT_NO_DIR) || defined(TQT_NO_IMAGEIO) || defined(TQT_NO_TEXTCODEC))
+#define TQT_NO_MIME
+#endif
+
+// Progress bars
+#if !defined(TQT_NO_PROGRESSBAR) && (defined(TQT_NO_FRAME))
+#define TQT_NO_PROGRESSBAR
+#endif
+
+// Push-buttons
+#if !defined(TQT_NO_PUSHBUTTON) && (defined(TQT_NO_BUTTON) || defined(TQT_NO_STYLE))
+#define TQT_NO_PUSHBUTTON
+#endif
+
+// Radio-buttons
+#if !defined(TQT_NO_RADIOBUTTON) && (defined(TQT_NO_BUTTON) || defined(TQT_NO_STYLE))
+#define TQT_NO_RADIOBUTTON
+#endif
+
+// Internal resize handler
+#if !defined(TQT_NO_RESIZEHANDLER) && (defined(TQT_NO_FRAME))
+#define TQT_NO_RESIZEHANDLER
+#endif
+
+// Scroll bars
+#if !defined(TQT_NO_SCROLLBAR) && (defined(TQT_NO_RANGECONTROL) || defined(TQT_NO_STYLE))
+#define TQT_NO_SCROLLBAR
+#endif
+
+// Sliders
+#if !defined(TQT_NO_SLIDER) && (defined(TQT_NO_RANGECONTROL) || defined(TQT_NO_STYLE))
+#define TQT_NO_SLIDER
+#endif
+
+// Spinbox control widget
+#if !defined(TQT_NO_SPINWIDGET) && (defined(TQT_NO_FRAME))
+#define TQT_NO_SPINWIDGET
+#endif
+
+// tqStatus bars
+#if !defined(TQT_NO_STATUSBAR) && (defined(TQT_NO_LAYOUT) || defined(TQT_NO_STYLE))
+#define TQT_NO_STATUSBAR
+#endif
+
+// Compact Windows style
+#if !defined(TQT_NO_STYLE_COMPACT) && (defined(TQT_NO_STYLE_WINDOWS))
+#define TQT_NO_STYLE_COMPACT
+#endif
+
+// Interlace-friendly style
+#if !defined(TQT_NO_STYLE_INTERLACE) && (defined(TQT_NO_STYLE_MOTIF))
+#define TQT_NO_STYLE_INTERLACE
+#endif
+
+// Platinum style
+#if !defined(TQT_NO_STYLE_PLATINUM) && (defined(TQT_NO_STYLE_WINDOWS))
+#define TQT_NO_STYLE_PLATINUM
+#endif
+
+// Widget stacks
+#if !defined(TQT_NO_WIDGETSTACK) && (defined(TQT_NO_FRAME))
+#define TQT_NO_WIDGETSTACK
+#endif
+
+// Grid tqlayout widgets
+#if !defined(TQT_NO_GRID) && (defined(TQT_NO_LAYOUT) || defined(TQT_NO_FRAME))
+#define TQT_NO_GRID
+#endif
+
+// Group boxes
+#if !defined(TQT_NO_GROUPBOX) && (defined(TQT_NO_FRAME) || defined(TQT_NO_LAYOUT))
+#define TQT_NO_GROUPBOX
+#endif
+
+// Horizontal box tqlayout widgets
+#if !defined(TQT_NO_HBOX) && (defined(TQT_NO_LAYOUT) || defined(TQT_NO_FRAME))
+#define TQT_NO_HBOX
+#endif
+
+// Menu-oriented widgets
+#if !defined(TQT_NO_MENUDATA) && (defined(TQT_NO_ICONSET) || defined(TQT_NO_VARIANT))
+#define TQT_NO_MENUDATA
+#endif
+
+// Persistent application settings
+#if !defined(TQT_NO_SETTINGS) && (defined(TQT_NO_DIR) || defined(TQT_NO_TEXTSTREAM) || defined(TQT_NO_REGEXP_CAPTURE))
+#define TQT_NO_SETTINGS
+#endif
+
+// Splitters
+#if !defined(TQT_NO_SPLITTER) && (defined(TQT_NO_FRAME) || defined(TQT_NO_LAYOUT))
+#define TQT_NO_SPLITTER
+#endif
+
+// Table-like widgets
+#if !defined(TQT_NO_TABLEVIEW) && (defined(TQT_NO_SCROLLBAR))
+#define TQT_NO_TABLEVIEW
+#endif
+
+// Tool tips
+#if !defined(TQT_NO_TOOLTIP) && (defined(TQT_NO_LABEL))
+#define TQT_NO_TOOLTIP
+#endif
+
+// Cut and paste
+#if !defined(TQT_NO_CLIPBOARD) && (defined(TQT_NO_TQWS_PROPERTIES) || defined(TQT_NO_MIME))
+#define TQT_NO_CLIPBOARD
+#endif
+
+// Horizontal group boxes
+#if !defined(TQT_NO_HGROUPBOX) && (defined(TQT_NO_GROUPBOX))
+#define TQT_NO_HGROUPBOX
+#endif
+
+// Properties
+#if !defined(TQT_NO_PROPERTIES) && (defined(TQT_NO_VARIANT) || defined(TQT_NO_STRINGLIST) || defined(TQT_NO_ICONSET))
+#define TQT_NO_PROPERTIES
+#endif
+
+// RichText (HTML) display
+#if !defined(TQT_NO_RICHTEXT) && (defined(TQT_NO_STYLE) || defined(TQT_NO_LAYOUT) || defined(TQT_NO_STRINGLIST) || defined(TQT_NO_TEXTSTREAM))
+#define TQT_NO_RICHTEXT
+#endif
+
+// SQL classes
+#if !defined(TQT_NO_SQL) && (defined(TQT_NO_STRINGLIST) || defined(TQT_NO_REGEXP_CAPTURE) || defined(TQT_NO_VARIANT) || defined(TQT_NO_SPRINTF) || defined(TQT_NO_DATESTRING))
+#define TQT_NO_SQL
+#endif
+
+// CDE style
+#if !defined(TQT_NO_STYLE_CDE) && (defined(TQT_NO_STYLE_MOTIF) || defined(TQT_NO_TRANSFORMATIONS))
+#define TQT_NO_STYLE_CDE
+#endif
+
+// Vertical box tqlayout widgets
+#if !defined(TQT_NO_VBOX) && (defined(TQT_NO_HBOX))
+#define TQT_NO_VBOX
+#endif
+
+// Button groups
+#if !defined(TQT_NO_BUTTONGROUP) && (defined(TQT_NO_GROUPBOX) || defined(TQT_NO_BUTTON))
+#define TQT_NO_BUTTONGROUP
+#endif
+
+// Complex scripts (eg. BiDi)
+#if !defined(TQT_NO_COMPLEXTEXT) && (defined(TQT_NO_RICHTEXT))
+#define TQT_NO_COMPLEXTEXT
+#endif
+
+// Cut and paste non-text
+#if !defined(TQT_NO_MIMECLIPBOARD) && (defined(TQT_NO_CLIPBOARD))
+#define TQT_NO_MIMECLIPBOARD
+#endif
+
+// Printing
+#if !defined(TQT_NO_PRINTER) && (defined(TQT_NO_TEXTSTREAM) || defined(TQT_NO_SPRINTF) || defined(TQT_NO_FONTDATABASE) || defined(TQT_NO_DATESTRING) || defined(TQT_NO_REGEXP_CAPTURE))
+#define TQT_NO_PRINTER
+#endif
+
+// Aqua style
+#if !defined(TQT_NO_STYLE_ATQUA) && (defined(TQT_NO_STYLE_WINDOWS) || defined(TQT_NO_IMAGE_TRANSFORMATION))
+#define TQT_NO_STYLE_ATQUA
+#endif
+
+// Vertical group boxes
+#if !defined(TQT_NO_VGROUPBOX) && (defined(TQT_NO_HGROUPBOX))
+#define TQT_NO_VGROUPBOX
+#endif
+
+// Horizontal button groups
+#if !defined(TQT_NO_HBUTTONGROUP) && (defined(TQT_NO_BUTTONGROUP))
+#define TQT_NO_HBUTTONGROUP
+#endif
+
+// Server to play sound
+#if !defined(TQT_NO_TQWS_SOUNDSERVER) && (defined(TQT_NO_SOUND) || defined(TQT_NO_DIR) || defined(TQT_NO_DNS))
+#define TQT_NO_TQWS_SOUNDSERVER
+#endif
+
+// TQHeader
+#if !defined(TQT_NO_HEADER) && (defined(TQT_NO_STYLE) || defined(TQT_NO_ICONSET))
+#define TQT_NO_HEADER
+#endif
+
+// Vertical button groups
+#if !defined(TQT_NO_VBUTTONGROUP) && (defined(TQT_NO_HBUTTONGROUP))
+#define TQT_NO_VBUTTONGROUP
+#endif
+
+// Hebrew Codec
+#if !defined(TQT_NO_CODEC_HEBREW) && (defined(TQT_NO_CODECS) || defined(TQT_NO_COMPLEXTEXT))
+#define TQT_NO_CODEC_HEBREW
+#endif
+
+// HTTP file access
+#if !defined(TQT_NO_NETWORKPROTOCOL_HTTP) && (defined(TQT_NO_NETWORKPROTOCOL) || defined(TQT_NO_DNS))
+#define TQT_NO_NETWORKPROTOCOL_HTTP
+#endif
+
+// Tool-buttons
+#if !defined(TQT_NO_TOOLBUTTON) && (defined(TQT_NO_BUTTON) || defined(TQT_NO_ICONSET) || defined(TQT_NO_STYLE))
+#define TQT_NO_TOOLBUTTON
+#endif
+
+// Big Codecs (eg. CJK)
+#if !defined(TQT_NO_BIG_CODECS) && (defined(TQT_NO_CODEC_HEBREW))
+#define TQT_NO_BIG_CODECS
+#endif
+
+// Experimental internal class
+#if !defined(TQT_NO_DIALOGBUTTONS) && (defined(TQT_NO_LAYOUT) || defined(TQT_NO_STYLE) || defined(TQT_NO_PUSHBUTTON))
+#define TQT_NO_DIALOGBUTTONS
+#endif
+
+// Document Object Model
+#if !defined(TQT_NO_DOM) && (defined(TQT_NO_XML) || defined(TQT_NO_MIME))
+#define TQT_NO_DOM
+#endif
+
+// Scrollable view widgets
+#if !defined(TQT_NO_SCROLLVIEW) && (defined(TQT_NO_SCROLLBAR) || defined(TQT_NO_FRAME))
+#define TQT_NO_SCROLLVIEW
+#endif
+
+// Tab-bars
+#if !defined(TQT_NO_TABBAR) && (defined(TQT_NO_TOOLBUTTON))
+#define TQT_NO_TABBAR
+#endif
+
+// Drag and drop
+#if !defined(TQT_NO_DRAGANDDROP) && (defined(TQT_NO_MIME) || defined(TQT_NO_TQWS_PROPERTIES) || defined(TQT_NO_IMAGEIO_XPM))
+#define TQT_NO_DRAGANDDROP
+#endif
+
+// TQGridView
+#if !defined(TQT_NO_GRIDVIEW) && (defined(TQT_NO_SCROLLVIEW))
+#define TQT_NO_GRIDVIEW
+#endif
+
+// Popup-menus
+#if !defined(TQT_NO_POPUPMENU) && (defined(TQT_NO_MENUDATA) || defined(TQT_NO_FRAME))
+#define TQT_NO_POPUPMENU
+#endif
+
+// TQCanvas
+#if !defined(TQT_NO_CANVAS) && (defined(TQT_NO_SCROLLVIEW) || defined(TQT_NO_BEZIER))
+#define TQT_NO_CANVAS
+#endif
+
+// Dynamic module linking
+#if !defined(TQT_NO_COMPONENT) && (defined(TQT_NO_TQUUID_STRING) || defined(TQT_NO_SETTINGS) || defined(TQT_NO_SPRINTF) || defined(TQT_NO_LIBRARY) || defined(TQT_NO_DATESTRING))
+#define TQT_NO_COMPONENT
+#endif
+
+// TQListBox
+#if !defined(TQT_NO_LISTBOX) && (defined(TQT_NO_SCROLLVIEW) || defined(TQT_NO_STRINGLIST))
+#define TQT_NO_LISTBOX
+#endif
+
+// Menu bars
+#if !defined(TQT_NO_MENUBAR) && (defined(TQT_NO_POPUPMENU))
+#define TQT_NO_MENUBAR
+#endif
+
+// TQMessageBox
+#if !defined(TQT_NO_MESSAGEBOX) && (defined(TQT_NO_DIALOG) || defined(TQT_NO_PUSHBUTTON) || defined(TQT_NO_LABEL))
+#define TQT_NO_MESSAGEBOX
+#endif
+
+// FTP file access
+#if !defined(TQT_NO_NETWORKPROTOCOL_FTP) && (defined(TQT_NO_NETWORKPROTOCOL) || defined(TQT_NO_DNS) || defined(TQT_NO_TEXTDATE))
+#define TQT_NO_NETWORKPROTOCOL_FTP
+#endif
+
+// Spin boxes
+#if !defined(TQT_NO_SPINBOX) && (defined(TQT_NO_RANGECONTROL) || defined(TQT_NO_SPINWIDGET) || defined(TQT_NO_LINEEDIT) || defined(TQT_NO_VALIDATOR))
+#define TQT_NO_SPINBOX
+#endif
+
+// RichText (HTML) tables and images
+#if !defined(TQT_NO_TEXTCUSTOMITEM) && (defined(TQT_NO_RICHTEXT) || defined(TQT_NO_MIME))
+#define TQT_NO_TEXTCUSTOMITEM
+#endif
+
+// TQDateTimeEdit
+#if !defined(TQT_NO_DATETIMEEDIT) && (defined(TQT_NO_RICHTEXT) || defined(TQT_NO_SPINWIDGET) || defined(TQT_NO_DATESTRING))
+#define TQT_NO_DATETIMEEDIT
+#endif
+
+// TQTextCodecPlugin
+#if !defined(TQT_NO_TEXTCODECPLUGIN) && (defined(TQT_NO_COMPONENT) || defined(TQT_NO_TEXTCODEC))
+#define TQT_NO_TEXTCODECPLUGIN
+#endif
+
+// TQImageFormatPlugin
+#if !defined(TQT_NO_IMAGEFORMATPLUGIN) && (defined(TQT_NO_COMPONENT) || defined(TQT_NO_IMAGEIO))
+#define TQT_NO_IMAGEFORMATPLUGIN
+#endif
+
+// TQSqlForm
+#if !defined(TQT_NO_STQL_FORM) && (defined(TQT_NO_SQL) || defined(TQT_NO_PROPERTIES))
+#define TQT_NO_STQL_FORM
+#endif
+
+// Scalable Vector Graphics (SVG)
+#if !defined(TQT_NO_SVG) && (defined(TQT_NO_DOM) || defined(TQT_NO_TRANSFORMATIONS) || defined(TQT_NO_SPRINTF))
+#define TQT_NO_SVG
+#endif
+
+// TQIconView
+#if !defined(TQT_NO_ICONVIEW) && (defined(TQT_NO_SCROLLVIEW) || defined(TQT_NO_IMAGEIO_XPM) || defined(TQT_NO_IMAGE_HEURISTIC_MASK))
+#define TQT_NO_ICONVIEW
+#endif
+
+// Tab widgets
+#if !defined(TQT_NO_TABWIDGET) && (defined(TQT_NO_TABBAR) || defined(TQT_NO_WIDGETSTACK))
+#define TQT_NO_TABWIDGET
+#endif
+
+// "What's this" help
+#if !defined(TQT_NO_WHATSTHIS) && (defined(TQT_NO_TOOLTIP) || defined(TQT_NO_TOOLBUTTON))
+#define TQT_NO_WHATSTHIS
+#endif
+
+// TQWidgetPlugin
+#if !defined(TQT_NO_WIDGETPLUGIN) && (defined(TQT_NO_COMPONENT) || defined(TQT_NO_ICONSET))
+#define TQT_NO_WIDGETPLUGIN
+#endif
+
+// TQProgressDialog
+#if !defined(TQT_NO_PROGRESSDIALOG) && (defined(TQT_NO_SEMIMODAL) || defined(TQT_NO_LABEL) || defined(TQT_NO_PUSHBUTTON) || defined(TQT_NO_PROGRESSBAR))
+#define TQT_NO_PROGRESSDIALOG
+#endif
+
+// Motif-plus style
+#if !defined(TQT_NO_STYLE_MOTIFPLUS) && (defined(TQT_NO_STYLE_MOTIF) || defined(TQT_NO_TRANSFORMATIONS) || defined(TQT_NO_BUTTON) || defined(TQT_NO_SCROLLBAR) || defined(TQT_NO_SLIDER))
+#define TQT_NO_STYLE_MOTIFPLUS
+#endif
+
+// Rich text edit
+#if !defined(TQT_NO_TEXTEDIT) && (defined(TQT_NO_RICHTEXT) || defined(TQT_NO_SCROLLVIEW))
+#define TQT_NO_TEXTEDIT
+#endif
+
+// TQWizard
+#if !defined(TQT_NO_WIZARD) && (defined(TQT_NO_DIALOG) || defined(TQT_NO_WIDGETSTACK) || defined(TQT_NO_PUSHBUTTON) || defined(TQT_NO_LAYOUT) || defined(TQT_NO_LABEL))
+#define TQT_NO_WIZARD
+#endif
+
+// Multi-line edits
+#if !defined(TQT_NO_MULTILINEEDIT) && (defined(TQT_NO_TEXTEDIT))
+#define TQT_NO_MULTILINEEDIT
+#endif
+
+// Rich text syntax highlighting
+#if !defined(TQT_NO_SYNTAXHIGHLIGHTER) && (defined(TQT_NO_TEXTEDIT))
+#define TQT_NO_SYNTAXHIGHLIGHTER
+#endif
+
+// TQTextView
+#if !defined(TQT_NO_TEXTVIEW) && (defined(TQT_NO_TEXTEDIT))
+#define TQT_NO_TEXTVIEW
+#endif
+
+// TQTabDialog
+#if !defined(TQT_NO_TABDIALOG) && (defined(TQT_NO_DIALOG) || defined(TQT_NO_PUSHBUTTON) || defined(TQT_NO_LAYOUT) || defined(TQT_NO_TABWIDGET))
+#define TQT_NO_TABDIALOG
+#endif
+
+// TQTextBrowser
+#if !defined(TQT_NO_TEXTBROWSER) && (defined(TQT_NO_TEXTVIEW) || defined(TQT_NO_MIME))
+#define TQT_NO_TEXTBROWSER
+#endif
+
+// TQListView
+#if !defined(TQT_NO_LISTVIEW) && (defined(TQT_NO_SCROLLVIEW) || defined(TQT_NO_HEADER) || defined(TQT_NO_LINEEDIT))
+#define TQT_NO_LISTVIEW
+#endif
+
+// TQComboBox
+#if !defined(TQT_NO_COMBOBOX) && (defined(TQT_NO_LISTBOX) || defined(TQT_NO_LINEEDIT) || defined(TQT_NO_POPUPMENU))
+#define TQT_NO_COMBOBOX
+#endif
+
+// TQColorDialog
+#if !defined(TQT_NO_COLORDIALOG) && (defined(TQT_NO_DIALOG) || defined(TQT_NO_LABEL) || defined(TQT_NO_PUSHBUTTON) || defined(TQT_NO_LINEEDIT) || defined(TQT_NO_VALIDATOR) || defined(TQT_NO_GRIDVIEW) || defined(TQT_NO_LAYOUT))
+#define TQT_NO_COLORDIALOG
+#endif
+
+// Tool box
+#if !defined(TQT_NO_TOOLBOX) && (defined(TQT_NO_ICONSET) || defined(TQT_NO_SCROLLVIEW) || defined(TQT_NO_TOOLTIP) || defined(TQT_NO_LAYOUT) || defined(TQT_NO_TOOLBUTTON))
+#define TQT_NO_TOOLBOX
+#endif
+
+// SGI style
+#if !defined(TQT_NO_STYLE_SGI) && (defined(TQT_NO_STYLE_MOTIF) || defined(TQT_NO_TRANSFORMATIONS) || defined(TQT_NO_BUTTON) || defined(TQT_NO_SCROLLBAR) || defined(TQT_NO_SLIDER) || defined(TQT_NO_LINEEDIT) || defined(TQT_NO_MENUBAR))
+#define TQT_NO_STYLE_SGI
+#endif
+
+// TQErrorMessage
+#if !defined(TQT_NO_ERRORMESSAGE) && (defined(TQT_NO_DIALOG) || defined(TQT_NO_PUSHBUTTON) || defined(TQT_NO_LABEL) || defined(TQT_NO_CHECKBOX) || defined(TQT_NO_TEXTVIEW))
+#define TQT_NO_ERRORMESSAGE
+#endif
+
+// Main-windows
+#if !defined(TQT_NO_MAINWINDOW) && (defined(TQT_NO_STRINGLIST) || defined(TQT_NO_POPUPMENU) || defined(TQT_NO_TITLEBAR) || defined(TQT_NO_RESIZEHANDLER) || defined(TQT_NO_TOOLBUTTON) || defined(TQT_NO_STATUSBAR))
+#define TQT_NO_MAINWINDOW
+#endif
+
+// Toolbars
+#if !defined(TQT_NO_TOOLBAR) && (defined(TQT_NO_MAINWINDOW))
+#define TQT_NO_TOOLBAR
+#endif
+
+// TQAction
+#if !defined(TQT_NO_ACTION) && (defined(TQT_NO_TOOLBUTTON) || defined(TQT_NO_COMBOBOX))
+#define TQT_NO_ACTION
+#endif
+
+// TQTable
+#if !defined(TQT_NO_TABLE) && (defined(TQT_NO_COMBOBOX) || defined(TQT_NO_HEADER) || defined(TQT_NO_CHECKBOX))
+#define TQT_NO_TABLE
+#endif
+
+// TQFontDialog
+#if !defined(TQT_NO_FONTDIALOG) && (defined(TQT_NO_DIALOG) || defined(TQT_NO_FONTDATABASE) || defined(TQT_NO_COMBOBOX) || defined(TQT_NO_LABEL) || defined(TQT_NO_CHECKBOX) || defined(TQT_NO_PUSHBUTTON) || defined(TQT_NO_VGROUPBOX) || defined(TQT_NO_VALIDATOR))
+#define TQT_NO_FONTDIALOG
+#endif
+
+// TQInputDialog
+#if !defined(TQT_NO_INPUTDIALOG) && (defined(TQT_NO_DIALOG) || defined(TQT_NO_COMBOBOX) || defined(TQT_NO_LABEL) || defined(TQT_NO_PUSHBUTTON) || defined(TQT_NO_SPINBOX) || defined(TQT_NO_WIDGETSTACK) || defined(TQT_NO_LAYOUT))
+#define TQT_NO_INPUTDIALOG
+#endif
+
+// SQL value editor widgets
+#if !defined(TQT_NO_STQL_EDIT_WIDGETS) && (defined(TQT_NO_SQL) || defined(TQT_NO_SPINBOX) || defined(TQT_NO_COMBOBOX) || defined(TQT_NO_CHECKBOX) || defined(TQT_NO_DATETIMEEDIT))
+#define TQT_NO_STQL_EDIT_WIDGETS
+#endif
+
+// TQPrintDialog
+#if !defined(TQT_NO_PRINTDIALOG) && (defined(TQT_NO_DIALOG) || defined(TQT_NO_LISTVIEW) || defined(TQT_NO_PRINTER) || defined(TQT_NO_COMBOBOX) || defined(TQT_NO_LABEL) || defined(TQT_NO_BUTTONGROUP) || defined(TQT_NO_SPINBOX) || defined(TQT_NO_RADIOBUTTON) || defined(TQT_NO_PUSHBUTTON) || defined(TQT_NO_DIR))
+#define TQT_NO_PRINTDIALOG
+#endif
+
+// TQFileDialog
+#if !defined(TQT_NO_FILEDIALOG) && (defined(TQT_NO_MESSAGEBOX) || defined(TQT_NO_LISTVIEW) || defined(TQT_NO_NETWORKPROTOCOL) || defined(TQT_NO_COMBOBOX) || defined(TQT_NO_SEMIMODAL) || defined(TQT_NO_REGEXP_CAPTURE) || defined(TQT_NO_TOOLBUTTON) || defined(TQT_NO_BUTTONGROUP) || defined(TQT_NO_VBOX) || defined(TQT_NO_SPLITTER) || defined(TQT_NO_PROGRESSBAR) || defined(TQT_NO_WIDGETSTACK) || defined(TQT_NO_DATESTRING))
+#define TQT_NO_FILEDIALOG
+#endif
+
+// SQL table widgets
+#if !defined(TQT_NO_STQL_VIEW_WIDGETS) && (defined(TQT_NO_STQL_FORM) || defined(TQT_NO_STQL_EDIT_WIDGETS) || defined(TQT_NO_TABLE))
+#define TQT_NO_STQL_VIEW_WIDGETS
+#endif
+
+// TQWorkSpace
+#if !defined(TQT_NO_WORKSPACE) && (defined(TQT_NO_SCROLLBAR) || defined(TQT_NO_VBOX) || defined(TQT_NO_TITLEBAR) || defined(TQT_NO_RESIZEHANDLER) || defined(TQT_NO_POPUPMENU) || defined(TQT_NO_LABEL) || defined(TQT_NO_TOOLBUTTON) || defined(TQT_NO_MAINWINDOW) || defined(TQT_NO_TOOLBAR) || defined(TQT_NO_MENUBAR))
+#define TQT_NO_WORKSPACE
+#endif
+
diff --git a/tqtinterface/qt4/src/tools/tqfile.cpp b/tqtinterface/qt4/src/tools/tqfile.cpp
new file mode 100644
index 0000000..c53c9f7
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqfile.cpp
@@ -0,0 +1,783 @@
+/****************************************************************************
+**
+** Implementation of TQFile class
+**
+** Created : 930812
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// POSIX Large File Support redefines open -> open64
+#if defined(open)
+# undef open
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+#include "tqfile.h"
+#ifndef NO_ERRNO_H
+#include <errno.h>
+#endif
+
+
+// Duplicated from tqobject.h, but we cannot include tqobject.h here since
+// it causes qmake to not build on irix g++
+#define TQT_TRANSLATE_NOOP(scope,x) (x)
+
+const char* qt_fileerr_unknown = TQT_TRANSLATE_NOOP( "TQFile", "Unknown error" );
+const char* qt_fileerr_read = TQT_TRANSLATE_NOOP( "TQFile", "Could not read from the file" );
+const char* qt_fileerr_write = TQT_TRANSLATE_NOOP( "TQFile", "Could not write to the file" );
+
+#define TQFILEERR_EACCES TQT_TRANSLATE_NOOP( "TQFile", "Permission denied" )
+#define TQFILEERR_EMFILE TQT_TRANSLATE_NOOP( "TQFile", "Too many open files" )
+#define TQFILEERR_ENOENT TQT_TRANSLATE_NOOP( "TQFile", "No such file or directory" )
+#define TQFILEERR_ENOSPC TQT_TRANSLATE_NOOP( "TQFile", "No space left on tqdevice" )
+
+#ifdef USE_QT4
+
+/*!
+ \overload
+
+ Reads a line of text.
+
+ Reads bytes from the file into string \a s, until end-of-line or
+ \a maxlen bytes have been read, whichever occurs first. Returns
+ the number of bytes read, or -1 if there was an error, e.g. end of
+ file. Any terminating newline is not stripped.
+
+ This function is only efficient for buffered files. Avoid using
+ readLine() for files that have been opened with the \c IO_Raw
+ flag.
+
+ Note that the string is read as plain Latin1 bytes, not Unicode.
+
+ \sa readBlock(), TQTextStream::readLine()
+*/
+
+TQ_LONG TQFile::readLine( TQString& s, TQ_ULONG maxlen )
+{
+ TQByteArray ba(maxlen);
+ TQ_LONG l = readLine(ba.data(),maxlen);
+ if ( l >= 0 ) {
+ ba.truncate(l);
+ s = TQString(ba);
+ }
+ return l;
+}
+
+#else // USE_QT4
+
+class TQFilePrivate
+{
+public:
+ TQString errorString;
+};
+
+extern bool qt_file_access( const TQString& fn, int t );
+
+/*!
+ \class TQFile tqfile.h
+ \reentrant
+ \brief The TQFile class is an I/O tqdevice that operates on files.
+
+ \ingroup io
+ \mainclass
+
+ TQFile is an I/O tqdevice for reading and writing binary and text
+ files. A TQFile may be used by itself or more conveniently with a
+ TQDataStream or TQTextStream.
+
+ The file name is usually passed in the constructor but can be
+ changed with setName(). You can check for a file's existence with
+ exists() and remove a file with remove().
+
+ The file is opened with open(), closed with close() and flushed
+ with flush(). Data is usually read and written using TQDataStream
+ or TQTextStream, but you can read with readBlock() and readLine()
+ and write with writeBlock(). TQFile also supports getch(),
+ ungetch() and putch().
+
+ The size of the file is returned by size(). You can get the
+ current file position or move to a new file position using the
+ at() functions. If you've reached the end of the file, atEnd()
+ returns TRUE. The file handle is returned by handle().
+
+ Here is a code fragment that uses TQTextStream to read a text file
+ line by line. It prints each line with a line number.
+ \code
+ TQStringList lines;
+ TQFile file( "file.txt" );
+ if ( file.open( IO_ReadOnly ) ) {
+ TQTextStream stream( &file );
+ TQString line;
+ int i = 1;
+ while ( !stream.atEnd() ) {
+ line = stream.readLine(); // line of text excluding '\n'
+ printf( "%3d: %s\n", i++, line.latin1() );
+ lines += line;
+ }
+ file.close();
+ }
+ \endcode
+
+ Writing text is just as easy. The following example shows how to
+ write the data we read into the string list from the previous
+ example:
+ \code
+ TQFile file( "file.txt" );
+ if ( file.open( IO_WriteOnly ) ) {
+ TQTextStream stream( &file );
+ for ( TQStringList::Iterator it = lines.begin(); it != lines.end(); ++it )
+ stream << *it << "\n";
+ file.close();
+ }
+ \endcode
+
+ The TQFileInfo class holds detailed information about a file, such
+ as access permissions, file dates and file types.
+
+ The TQDir class manages directories and lists of file names.
+
+ TQt uses Unicode file names. If you want to do your own I/O on Unix
+ systems you may want to use encodeName() (and decodeName()) to
+ convert the file name into the local encoding.
+
+ \important readAll() at()
+
+ \sa TQDataStream, TQTextStream
+*/
+
+/*!
+ \fn TQ_LONG TQFile::writeBlock( const TQByteArray& data )
+
+ \overload
+*/
+
+
+/*!
+ Constructs a TQFile with no name.
+*/
+
+TQFile::TQFile()
+: d(0)
+{
+ init();
+}
+
+/*!
+ Constructs a TQFile with a file name \a name.
+
+ \sa setName()
+*/
+
+TQFile::TQFile( const TQString &name )
+ : fn(name), d(0)
+{
+ init();
+}
+
+
+/*!
+ Destroys a TQFile. Calls close().
+*/
+
+TQFile::~TQFile()
+{
+ close();
+ delete d;
+}
+
+
+/*!
+ \internal
+ Initialize internal data.
+*/
+
+void TQFile::init()
+{
+ delete d;
+ d = new TQFilePrivate;
+ setFlags( IO_Direct );
+ setqStatus( IO_Ok );
+ setErrorString( qt_fileerr_unknown );
+ fh = 0;
+ fd = 0;
+ length = 0;
+ ioIndex = 0;
+ ext_f = FALSE; // not an external file handle
+}
+
+
+/*!
+ \fn TQString TQFile::name() const
+
+ Returns the name set by setName().
+
+ \sa setName(), TQFileInfo::fileName()
+*/
+
+/*!
+ Sets the name of the file to \a name. The name can have no path, a
+ relative path or an absolute absolute path.
+
+ Do not call this function if the file has already been opened.
+
+ If the file name has no path or a relative path, the path used
+ will be whatever the application's current directory path is
+ \e{at the time of the open()} call.
+
+ Example:
+ \code
+ TQFile file;
+ TQDir::setCurrent( "/tmp" );
+ file.setName( "readme.txt" );
+ TQDir::setCurrent( "/home" );
+ file.open( IO_ReadOnly ); // opens "/home/readme.txt" under Unix
+ \endcode
+
+ Note that the directory separator "/" works for all operating
+ systems supported by TQt.
+
+ \sa name(), TQFileInfo, TQDir
+*/
+
+void TQFile::setName( const TQString &name )
+{
+ if ( isOpen() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQFile::setName: File is open" );
+#endif
+ close();
+ }
+ fn = name;
+}
+
+/*!
+ \overload
+
+ Returns TRUE if this file exists; otherwise returns FALSE.
+
+ \sa name()
+*/
+
+bool TQFile::exists() const
+{
+ return qt_file_access( fn, F_OK );
+}
+
+/*!
+ Returns TRUE if the file given by \a fileName exists; otherwise
+ returns FALSE.
+*/
+
+bool TQFile::exists( const TQString &fileName )
+{
+ return qt_file_access( fileName, F_OK );
+}
+
+
+/*!
+ Removes the file specified by the file name currently set. Returns
+ TRUE if successful; otherwise returns FALSE.
+
+ The file is closed before it is removed.
+*/
+
+bool TQFile::remove()
+{
+ close();
+ return remove( fn );
+}
+
+#if defined(TQ_OS_MAC) || defined(TQ_OS_MSDOS) || defined(TQ_OS_WIN32) || defined(TQ_OS_OS2)
+# define HAS_TEXT_FILEMODE // has translate/text filemode
+#endif
+#if defined(O_NONBLOCK)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NONBLOCK
+#elif defined(O_NDELAY)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NDELAY
+#endif
+
+/*!
+ Flushes the file buffer to the disk.
+
+ close() also flushes the file buffer.
+*/
+
+void TQFile::flush()
+{
+ if ( isOpen() && fh ) { // can only flush open/buffered file
+ if ( fflush( fh ) ) { // write error
+ if ( errno == ENOSPC ) // disk is full
+ setqStatus( IO_ResourceError );
+ else
+ setqStatus( IO_WriteError );
+ setErrorStringErrno( errno );
+ }
+ }
+}
+
+/*! \reimp
+ \fn TQIODevice::Offset TQFile::at() const
+*/
+
+/*!
+ Returns TRUE if the end of file has been reached; otherwise returns FALSE.
+ If TQFile has not been open()'d, then the behavior is undefined.
+
+ \sa size()
+*/
+
+bool TQFile::atEnd() const
+{
+ if ( !isOpen() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQFile::atEnd: File is not open" );
+#endif
+ return FALSE;
+ }
+ if ( isDirectAccess() && !isTranslated() ) {
+ if ( at() < size() )
+ return FALSE;
+ }
+ const TQString errorString = d->errorString;
+ const bool ret = TQIODevice::atEnd();
+ if (errorString != d->errorString)
+ d->errorString = errorString;
+ return ret;
+}
+
+/*!
+ Reads a line of text.
+
+ Reads bytes from the file into the char* \a p, until end-of-line
+ or \a maxlen bytes have been read, whichever occurs first. Returns
+ the number of bytes read, or -1 if there was an error. Any
+ terminating newline is not stripped.
+
+ This function is only efficient for buffered files. Avoid
+ readLine() for files that have been opened with the \c IO_Raw
+ flag.
+
+ \sa readBlock(), TQTextStream::readLine()
+*/
+
+TQ_LONG TQFile::readLine( char *p, TQ_ULONG maxlen )
+{
+ if ( maxlen == 0 ) // application bug?
+ return 0;
+#if defined(TQT_CHECK_STATE)
+ TQ_CHECK_PTR( p );
+ if ( !isOpen() ) { // file not open
+ qWarning( "TQFile::readLine: File not open" );
+ return -1;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "TQFile::readLine: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ TQ_LONG nread; // number of bytes read
+ if ( isRaw() ) { // raw file
+ nread = TQIODevice::readLine( p, maxlen );
+ } else { // buffered file
+ p = fgets( p, maxlen, fh );
+ if ( p ) {
+ nread = tqstrlen( p );
+ if ( !isSequentialAccess() )
+ ioIndex += nread;
+ } else {
+ nread = -1;
+ setqStatus(IO_ReadError);
+ setErrorString( qt_fileerr_read );
+ }
+ }
+ return nread;
+}
+
+
+/*!
+ \overload
+
+ Reads a line of text.
+
+ Reads bytes from the file into string \a s, until end-of-line or
+ \a maxlen bytes have been read, whichever occurs first. Returns
+ the number of bytes read, or -1 if there was an error, e.g. end of
+ file. Any terminating newline is not stripped.
+
+ This function is only efficient for buffered files. Avoid using
+ readLine() for files that have been opened with the \c IO_Raw
+ flag.
+
+ Note that the string is read as plain Latin1 bytes, not Unicode.
+
+ \sa readBlock(), TQTextStream::readLine()
+*/
+
+TQ_LONG TQFile::readLine( TQString& s, TQ_ULONG maxlen )
+{
+ TQByteArray ba(maxlen);
+ TQ_LONG l = readLine(ba.data(),maxlen);
+ if ( l >= 0 ) {
+ ba.truncate(l);
+ s = TQString(ba);
+ }
+ return l;
+}
+
+
+/*!
+ Reads a single byte/character from the file.
+
+ Returns the byte/character read, or -1 if the end of the file has
+ been reached.
+
+ \sa putch(), ungetch()
+*/
+
+int TQFile::getch()
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "TQFile::getch: File not open" );
+ return EOF;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "TQFile::getch: Read operation not permitted" );
+ return EOF;
+ }
+#endif
+
+ int ch;
+
+ if ( !ungetchBuffer.isEmpty() ) {
+ int len = ungetchBuffer.length();
+ ch = ungetchBuffer[ len-1 ];
+ ungetchBuffer.truncate( len - 1 );
+ return ch;
+ }
+
+ if ( isRaw() ) { // raw file (inefficient)
+ char buf[1];
+ ch = readBlock( buf, 1 ) == 1 ? buf[0] : EOF;
+ } else { // buffered file
+ if ( (ch = getc( fh )) != EOF ) {
+ if ( !isSequentialAccess() )
+ ioIndex++;
+ } else {
+ setqStatus(IO_ReadError);
+ setErrorString( qt_fileerr_read );
+ }
+ }
+ return ch;
+}
+
+/*!
+ Writes the character \a ch to the file.
+
+ Returns \a ch, or -1 if some error occurred.
+
+ \sa getch(), ungetch()
+*/
+
+int TQFile::putch( int ch )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "TQFile::putch: File not open" );
+ return EOF;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "TQFile::putch: Write operation not permitted" );
+ return EOF;
+ }
+#endif
+ if ( isRaw() ) { // raw file (inefficient)
+ char buf[1];
+ buf[0] = ch;
+ ch = writeBlock( buf, 1 ) == 1 ? ch : EOF;
+ } else { // buffered file
+ if ( (ch = putc( ch, fh )) != EOF ) {
+ if ( !isSequentialAccess() )
+ ioIndex++;
+ if ( ioIndex > length ) // update file length
+ length = ioIndex;
+ } else {
+ setqStatus(IO_WriteError);
+ setErrorString( qt_fileerr_write );
+ }
+ }
+ return ch;
+}
+
+/*!
+ Puts the character \a ch back into the file and decrements the
+ index if it is not zero.
+
+ This function is normally called to "undo" a getch() operation.
+
+ Returns \a ch, or -1 if an error occurred.
+
+ \sa getch(), putch()
+*/
+
+int TQFile::ungetch( int ch )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "TQFile::ungetch: File not open" );
+ return EOF;
+ }
+ if ( !isReadable() ) { // reading not permitted
+ qWarning( "TQFile::ungetch: Read operation not permitted" );
+ return EOF;
+ }
+#endif
+ if ( ch == EOF ) // cannot unget EOF
+ return ch;
+
+ if ( isSequentialAccess() && !fh) {
+ // pipe or similar => we cannot ungetch, so do it manually
+ ungetchBuffer += TQChar(ch);
+ return ch;
+ }
+
+ if ( isRaw() ) { // raw file (very inefficient)
+ char buf[1];
+ at( ioIndex-1 );
+ buf[0] = ch;
+ if ( writeBlock(buf, 1) == 1 )
+ at ( ioIndex-1 );
+ else
+ ch = EOF;
+ } else { // buffered file
+ if ( (ch = ungetc(ch, fh)) != EOF ) {
+ if ( !isSequentialAccess() )
+ ioIndex--;
+ } else {
+ setqStatus( IO_ReadError );
+ setErrorString( qt_fileerr_read );
+ }
+ }
+ return ch;
+}
+
+
+static TQCString locale_encoder( const TQString &fileName )
+{
+ return fileName.local8Bit();
+}
+
+
+static TQFile::EncoderFn encoder = locale_encoder;
+
+/*!
+ When you use TQFile, TQFileInfo, and TQDir to access the file system
+ with TQt, you can use Unicode file names. On Unix, these file names
+ are converted to an 8-bit encoding. If you want to do your own
+ file I/O on Unix, you should convert the file name using this
+ function. On Windows NT/2000, Unicode file names are supported
+ directly in the file system and this function should be avoided.
+ On Windows 95, non-Latin1 locales are not supported.
+
+ By default, this function converts \a fileName to the local 8-bit
+ encoding determined by the user's locale. This is sufficient for
+ file names that the user chooses. File names hard-coded into the
+ application should only use 7-bit ASCII filename characters.
+
+ The conversion scheme can be changed using setEncodingFunction().
+ This might be useful if you wish to give the user an option to
+ store file names in UTF-8, etc., but be aware that such file names
+ would probably then be unrecognizable when seen by other programs.
+
+ \sa decodeName()
+*/
+
+TQCString TQFile::encodeName( const TQString &fileName )
+{
+ return (*encoder)(fileName);
+}
+
+/*!
+ \enum TQFile::EncoderFn
+
+ This is used by TQFile::setEncodingFunction().
+*/
+
+/*!
+ \nonreentrant
+
+ Sets the function for encoding Unicode file names to \a f. The
+ default encodes in the locale-specific 8-bit encoding.
+
+ \sa encodeName()
+*/
+void TQFile::setEncodingFunction( EncoderFn f )
+{
+ encoder = f;
+}
+
+static
+TQString locale_decoder( const TQCString &localFileName )
+{
+#ifndef TQ_WS_MAC
+ return TQString::fromLocal8Bit(localFileName);
+#else
+ extern TQString qt_mac_precomposeFileName(const TQString &); // qglobal.cpp
+ return qt_mac_precomposeFileName(TQString::fromLocal8Bit(localFileName));
+#endif
+}
+
+static TQFile::DecoderFn decoder = locale_decoder;
+
+/*!
+ This does the reverse of TQFile::encodeName() using \a localFileName.
+
+ \sa setDecodingFunction()
+*/
+TQString TQFile::decodeName( const TQCString &localFileName )
+{
+ return (*decoder)(localFileName);
+}
+
+/*!
+ \enum TQFile::DecoderFn
+
+ This is used by TQFile::setDecodingFunction().
+*/
+
+/*!
+ \nonreentrant
+
+ Sets the function for decoding 8-bit file names to \a f. The
+ default uses the locale-specific 8-bit encoding.
+
+ \sa encodeName(), decodeName()
+*/
+
+void TQFile::setDecodingFunction( DecoderFn f )
+{
+ decoder = f;
+}
+
+/*!
+ Returns a human-readable description of the reason of an error that occurred
+ on the tqdevice. The error described by the string corresponds to changes of
+ TQIODevice::status(). If the status is reset, the error string is also reset.
+
+ The returned strings are not translated with the TQObject::tr() or
+ TQApplication::translate() functions. They are marked as translatable
+ strings in the "TQFile" context. Before you show the string to the user you
+ should translate it first, for example:
+
+ \code
+ TQFile f( "address.dat" );
+ if ( !f.open( IO_ReadOnly ) {
+ TQMessageBox::critical(
+ this,
+ tr("Open failed"),
+ tr("Could not open file for reading: %1").arg( tqApp->translate("TQFile",f.errorString()) )
+ );
+ return;
+ }
+ \endcode
+
+ \sa TQIODevice::status(), TQIODevice::resetqStatus(), setErrorString()
+*/
+
+TQString TQFile::errorString() const
+{
+ if ( status() == IO_Ok )
+ return qt_fileerr_unknown;
+ return d->errorString;
+}
+
+/*!
+ \nonreentrant
+
+ Sets the error string returned by the errorString() function to \a str.
+
+ \sa errorString(), TQIODevice::status()
+*/
+
+void TQFile::setErrorString( const TQString& str )
+{
+ d->errorString = str;
+}
+
+void TQFile::setErrorStringErrno( int errnum )
+{
+ switch ( errnum ) {
+ case EACCES:
+ d->errorString = TQFILEERR_EACCES;
+ break;
+ case EMFILE:
+ d->errorString = TQFILEERR_EMFILE;
+ break;
+ case ENOENT:
+ d->errorString = TQFILEERR_ENOENT;
+ break;
+ case ENOSPC:
+ d->errorString = TQFILEERR_ENOSPC;
+ break;
+ default:
+#ifndef TQ_OS_TEMP
+ d->errorString = TQString::fromLocal8Bit( strerror( errnum ) );
+#else
+ {
+ unsigned short *string;
+ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ errnum,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&string,
+ 0,
+ NULL );
+ d->errorString = TQString::fromUcs2( string );
+ LocalFree( (HLOCAL)string );
+ }
+#endif
+ break;
+ }
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/tools/tqfile.h b/tqtinterface/qt4/src/tools/tqfile.h
new file mode 100644
index 0000000..10b69e6
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqfile.h
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Definition of TQFile class
+**
+** Created : 930831
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFILE_H
+#define TQFILE_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqiodevice.h"
+#include "tqstring.h"
+#include <stdio.h>
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qfile.h>
+
+#endif // USE_QT4
+
+class TQDir;
+class TQFilePrivate;
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQFile : public QFile
+{
+public:
+ TQFile() : QFile() {}
+ TQFile( const QString &name ) : QFile( name ) {}
+
+ bool open( int aFlags, FILE * f ) { return QFile::open( f, (QIODevice::OpenModeFlag)aFlags ); }
+ bool open( int aFlags, int f ) { return QFile::open( f, (QIODevice::OpenModeFlag)aFlags ); }
+ TQString name() const { return fileName(); }
+ void setName( const QString &name ) { setFileName(name); }
+ bool open( int om ) { return QFile::open((OpenMode)om); }
+ int state() const { return isOpen() ? 0x1000 : 0; }
+
+ inline TQ_LONG readLine( char *data, TQ_ULONG maxlen ) { return QFile::readLine(data, maxlen); }
+ TQ_LONG readLine( TQString &, TQ_ULONG maxlen );
+
+ TQIODevice::Status status() const {
+#if !defined(QT_NO_QOBJECT)
+ const QFile *f = qobject_cast<const QFile *>(this);
+ if (f) return (int) f->error();
+#endif
+ return isOpen() ? 0 /* IO_Ok */ : 8 /* IO_UnspecifiedError */;
+ }
+
+ inline TQIODevice::Offset at() const { return TQT_TQIODEVICE_CONST(this)->at(); }
+ inline bool at(TQIODevice::Offset offset) { return TQT_TQIODEVICE(this)->at(offset); }
+ inline TQIODevice::Offset tqat() const { return TQT_TQIODEVICE_CONST(this)->at(); }
+ inline bool tqat(TQIODevice::Offset offset) { return TQT_TQIODEVICE(this)->at(offset); }
+
+ inline qint64 readBlock(char *data, quint64 maxlen) { return read(data, maxlen); }
+ inline qint64 writeBlock(const char *data, quint64 len) { return write(data, len); }
+ inline qint64 writeBlock(const QByteArray &data) { return write(data); }
+
+ inline int getch() { char c; return getChar(&c) ? int(uchar(c)) : -1; }
+ inline int putch(int c) { return putChar(char(c)) ? int(uchar(c)) : -1; }
+ inline int ungetch(int c) { ungetChar(uchar(c)); return c; }
+
+ inline bool isDirectAccess() const { return !isSequential(); }
+ inline bool isSequentialAccess() const { return isSequential(); }
+ inline bool isCombinedAccess() const { return false; }
+ inline bool isBuffered() const { return true; }
+ inline bool isRaw() const { return false; }
+ inline bool isSynchronous() const { return true; }
+ inline bool isAsynchronous() const { return false; }
+ inline bool isTranslated() const { return (openMode() & Text) != 0; }
+ inline bool isInactive() const { return !isOpen(); }
+
+// inline bool open( int mode ) = 0;
+
+protected:
+ void setqStatus( int ) { std::cout << "[WARNING] TQIODevice::setqStatus() UNIMPLEMENTED\n\r"; }
+ void resetqStatus() { TQT_TQIODEVICE(this)->resetStatus(); }
+
+ void setFlags( int f ) { setOpenMode((QIODevice::OpenModeFlag)f); }
+ void setType( int ) { printf("[WARNING] TQIODevice::setType() unimplemented\n\r"); }
+ void setMode( int f ) { setOpenMode((QIODevice::OpenModeFlag)f); }
+ void setState( int state ) {
+ switch (state) {
+ case (IO_Open):
+ open(openMode());
+ break;
+ }
+ }
+};
+
+#else // USE_QT4
+
+class TQ_EXPORT TQFile : public TQIODevice // file I/O tqdevice class
+{
+public:
+ TQFile();
+ TQFile( const TQString &name );
+ ~TQFile();
+
+ TQString name() const;
+ void setName( const TQString &name );
+
+ typedef TQCString (*EncoderFn)( const TQString &fileName );
+ typedef TQString (*DecoderFn)( const TQCString &localfileName );
+ static TQCString encodeName( const TQString &fileName );
+ static TQString decodeName( const TQCString &localFileName );
+ static void setEncodingFunction( EncoderFn );
+ static void setDecodingFunction( DecoderFn );
+
+ bool exists() const;
+ static bool exists( const TQString &fileName );
+
+ bool remove();
+ static bool remove( const TQString &fileName );
+
+ bool open( int );
+ bool open( int, FILE * );
+ bool open( int, int );
+ void close();
+ void flush();
+
+ Offset size() const;
+ Offset at() const;
+ bool at( Offset );
+ bool atEnd() const;
+
+ TQ_LONG readBlock( char *data, TQ_ULONG len );
+ TQ_LONG writeBlock( const char *data, TQ_ULONG len );
+ TQ_LONG writeBlock( const TQByteArray& data )
+ { return TQIODevice::writeBlock(data); }
+ TQ_LONG readLine( char *data, TQ_ULONG maxlen );
+ TQ_LONG readLine( TQString &, TQ_ULONG maxlen );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+
+ int handle() const;
+
+ TQString errorString() const; // ### TQt 4: move into TQIODevice
+
+protected:
+ void setErrorString( const TQString& ); // ### TQt 4: move into TQIODevice
+ TQString fn;
+ FILE *fh;
+ int fd;
+ Offset length;
+ bool ext_f;
+ TQFilePrivate *d; // ### TQt 4: make private
+
+private:
+ void init();
+ void setErrorStringErrno( int );
+ TQCString ungetchBuffer;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQFile( const TQFile & );
+ TQFile &operator=( const TQFile & );
+#endif
+};
+
+
+inline TQString TQFile::name() const
+{ return fn; }
+
+inline TQIODevice::Offset TQFile::at() const
+{ return ioIndex; }
+
+#endif // USE_QT4
+
+#endif // TQFILE_H
diff --git a/tqtinterface/qt4/src/tools/tqfile_unix.cpp b/tqtinterface/qt4/src/tools/tqfile_unix.cpp
new file mode 100644
index 0000000..b76a2aa
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqfile_unix.cpp
@@ -0,0 +1,753 @@
+/****************************************************************************
+**
+** Implementation of TQFile class
+**
+** Created : 950628
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+#include "tqtglobaldefines.h"
+
+// POSIX Large File Support redefines open -> open64
+static inline int qt_open(const char *pathname, int flags, mode_t mode)
+{ return ::open(pathname, flags, mode); }
+#if defined(open)
+# undef open
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+#include "tqfile.h"
+#include <errno.h>
+#include <limits.h>
+
+extern const char* qt_fileerr_read;
+
+bool qt_file_access( const TQString& fn, int t )
+{
+ if ( fn.isEmpty() )
+ return FALSE;
+ return ::access( TQFile::encodeName(fn), t ) == 0;
+}
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \overload
+ Removes the file \a fileName.
+ Returns TRUE if successful, otherwise FALSE.
+*/
+
+bool TQFile::remove( const TQString &fileName )
+{
+ if ( fileName.isEmpty() ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQFile::remove: Empty or null file name" );
+#endif
+ return FALSE;
+ }
+ return unlink( TQFile::encodeName(fileName) ) == 0;
+}
+
+#if defined(O_NONBLOCK)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NONBLOCK
+#elif defined(O_NDELAY)
+# define HAS_ASYNC_FILEMODE
+# define OPEN_ASYNC O_NDELAY
+#endif
+
+/*!
+ Opens the file specified by the file name currently set, using the
+ mode \a m. Returns TRUE if successful, otherwise FALSE.
+
+ \keyword IO_Raw
+ \keyword IO_ReadOnly
+ \keyword IO_WriteOnly
+ \keyword IO_ReadWrite
+ \keyword IO_Append
+ \keyword IO_Truncate
+ \keyword IO_Translate
+
+ The mode parameter \a m must be a combination of the following flags:
+ \table
+ \header \i Flag \i Meaning
+ \row \i IO_Raw
+ \i Raw (non-buffered) file access.
+ \row \i IO_ReadOnly
+ \i Opens the file in read-only mode.
+ \row \i IO_WriteOnly
+ \i Opens the file in write-only mode. If this flag is used
+ with another flag, e.g. \c IO_ReadOnly or \c IO_Raw or \c
+ IO_Append, the file is \e not truncated; but if used on
+ its own (or with \c IO_Truncate), the file is truncated.
+ \row \i IO_ReadWrite
+ \i Opens the file in read/write mode, equivalent to \c
+ (IO_ReadOnly | IO_WriteOnly).
+ \row \i IO_Append
+ \i Opens the file in append mode. (You must actually use \c
+ (IO_WriteOnly | IO_Append) to make the file writable and
+ to go into append mode.) This mode is very useful when you
+ want to write something to a log file. The file index is
+ set to the end of the file. Note that the result is
+ undefined if you position the file index manually using
+ at() in append mode.
+ \row \i IO_Truncate
+ \i Truncates the file.
+ \row \i IO_Translate
+ \i Enables carriage returns and linefeed translation for text
+ files under Windows.
+ \endtable
+
+ The raw access mode is best when I/O is block-operated using a 4KB
+ block size or greater. Buffered access works better when reading
+ small portions of data at a time.
+
+ \warning When working with buffered files, data may not be written
+ to the file at once. Call flush() to make sure that the data is
+ really written.
+
+ \warning If you have a buffered file opened for both reading and
+ writing you must not perform an input operation immediately after
+ an output operation or vice versa. You should always call flush()
+ or a file positioning operation, e.g. at(), between input and
+ output operations, otherwise the buffer may contain garbage.
+
+ If the file does not exist and \c IO_WriteOnly or \c IO_ReadWrite
+ is specified, it is created.
+
+ Example:
+ \code
+ TQFile f1( "/tmp/data.bin" );
+ f1.open( IO_Raw | IO_ReadWrite );
+
+ TQFile f2( "readme.txt" );
+ f2.open( IO_ReadOnly | IO_Translate );
+
+ TQFile f3( "audit.log" );
+ f3.open( IO_WriteOnly | IO_Append );
+ \endcode
+
+ \sa name(), close(), isOpen(), flush()
+*/
+
+bool TQFile::open( int m )
+{
+ if ( isOpen() ) { // file already open
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ if ( fn.isEmpty() ) { // no file name defined
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQFile::open: No file name specified" );
+#endif
+ return FALSE;
+ }
+ init(); // reset params
+ setMode( m );
+ if ( !(isReadable() || isWritable()) ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQFile::open: File access not specified" );
+#endif
+ return FALSE;
+ }
+ bool ok = TRUE;
+ struct stat st;
+ if ( isRaw() ) {
+ int oflags = O_RDONLY;
+ if ( isReadable() && isWritable() )
+ oflags = O_RDWR;
+ else if ( isWritable() )
+ oflags = O_WRONLY;
+ if ( flags() & IO_Append ) { // append to end of file?
+ if ( flags() & IO_Truncate )
+ oflags |= (O_CREAT | O_TRUNC);
+ else
+ oflags |= (O_APPEND | O_CREAT);
+ setFlags( flags() | IO_WriteOnly ); // append implies write
+ } else if ( isWritable() ) { // create/trunc if writable
+ if ( flags() & IO_Truncate )
+ oflags |= (O_CREAT | O_TRUNC);
+ else
+ oflags |= O_CREAT;
+ }
+#if defined(HAS_TEXT_FILEMODE)
+ if ( isTranslated() )
+ oflags |= OPEN_TEXT;
+ else
+ oflags |= OPEN_BINARY;
+#endif
+#if defined(HAS_ASYNC_FILEMODE)
+ if ( isAsynchronous() )
+ oflags |= OPEN_ASYNC;
+#endif
+ fd = qt_open( TQFile::encodeName(fn), oflags, 0666 );
+
+ if ( fd != -1 ) { // open successful
+ ::fstat( fd, &st ); // get the stat for later usage
+ } else {
+ ok = FALSE;
+ }
+ } else { // buffered file I/O
+ TQCString perm;
+ char perm2[4];
+ bool try_create = FALSE;
+ if ( flags() & IO_Append ) { // append to end of file?
+ setFlags( flags() | IO_WriteOnly ); // append implies write
+ perm = isReadable() ? "a+" : "a";
+ } else {
+ if ( isReadWrite() ) {
+ if ( flags() & IO_Truncate ) {
+ perm = "w+";
+ } else {
+ perm = "r+";
+ try_create = TRUE; // try to create if not exists
+ }
+ } else if ( isReadable() ) {
+ perm = "r";
+ } else if ( isWritable() ) {
+ perm = "w";
+ }
+ }
+ qstrcpy( perm2, perm );
+#if defined(HAS_TEXT_FILEMODE)
+ if ( isTranslated() )
+ strcat( perm2, "t" );
+ else
+ strcat( perm2, "b" );
+#endif
+ for (;;) { // At most twice
+
+ fh = fopen( TQFile::encodeName(fn), perm2 );
+
+ if ( !fh && try_create ) {
+ perm2[0] = 'w'; // try "w+" instead of "r+"
+ try_create = FALSE;
+ } else {
+ break;
+ }
+ }
+ if ( fh ) {
+ ::fstat( fileno(fh), &st ); // get the stat for later usage
+ } else {
+ ok = FALSE;
+ }
+ }
+ if ( ok ) {
+ setState( IO_Open );
+ // on successful open the file stat was got; now test what type
+ // of file we have
+ if ( (st.st_mode & S_IFMT) != S_IFREG ) {
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ ioIndex = 0;
+ } else {
+#if defined(TQT_LARGEFILE_SUPPORT) && !defined(TQT_ABI_QT4)
+ length = st.st_size > UINT_MAX ? UINT_MAX : (Offset)st.st_size;
+#else
+ length = (Offset)st.st_size;
+#endif
+ ioIndex = (flags() & IO_Append) == 0 ? 0 : length;
+ if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // tqdevice; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ ioIndex = 0;
+ }
+ resetqStatus();
+ }
+ }
+ } else {
+ init();
+ if ( errno == EMFILE ) // no more file handles/descrs
+ setqStatus( IO_ResourceError );
+ else
+ setqStatus( IO_OpenError );
+ setErrorStringErrno( errno );
+ }
+ return ok;
+}
+
+/*!
+ \overload
+ Opens a file in the mode \a m using an existing file handle \a f.
+ Returns TRUE if successful, otherwise FALSE.
+
+ Example:
+ \code
+ #include <stdio.h>
+
+ void printError( const char* msg )
+ {
+ TQFile f;
+ f.open( IO_WriteOnly, stderr );
+ f.writeBlock( msg, tqstrlen(msg) ); // write to stderr
+ f.close();
+ }
+ \endcode
+
+ When a TQFile is opened using this function, close() does not actually
+ close the file, only flushes it.
+
+ \warning If \a f is \c stdin, \c stdout, \c stderr, you may not
+ be able to seek. See TQIODevice::isSequentialAccess() for more
+ information.
+
+ \sa close()
+*/
+
+bool TQFile::open( int m, FILE *f )
+{
+ if ( isOpen() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ init();
+ setMode( m &~IO_Raw );
+ setState( IO_Open );
+ fh = f;
+ ext_f = TRUE;
+ struct stat st;
+ ::fstat( fileno(fh), &st );
+#if defined(TQT_LARGEFILE_SUPPORT)
+#if !defined(TQT_ABI_QT4)
+ off_t tmp = ftello( fh );
+ ioIndex = tmp > UINT_MAX ? UINT_MAX : (Offset)tmp;
+#else
+ ioIndex = (Offset)ftello( fh );
+#endif
+#else
+ ioIndex = (Offset)ftell( fh );
+#endif
+ if ( (st.st_mode & S_IFMT) != S_IFREG || f == stdin ) { //stdin is non seekable
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ ioIndex = 0;
+ } else {
+#if defined(TQT_LARGEFILE_SUPPORT) && !defined(TQT_ABI_QT4)
+ length = st.st_size > UINT_MAX ? UINT_MAX : (Offset)st.st_size;
+#else
+ length = (Offset)st.st_size;
+#endif
+ if ( !(flags()&IO_Truncate) && length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // tqdevice; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ ioIndex = 0;
+ }
+ resetqStatus();
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ \overload
+ Opens a file in the mode \a m using an existing file descriptor \a f.
+ Returns TRUE if successful, otherwise FALSE.
+
+ When a TQFile is opened using this function, close() does not actually
+ close the file.
+
+ The TQFile that is opened using this function, is automatically set to be in
+ raw mode; this means that the file input/output functions are slow. If you
+ run into performance issues, you should try to use one of the other open
+ functions.
+
+ \warning If \a f is one of 0 (stdin), 1 (stdout) or 2 (stderr), you may not
+ be able to seek. size() is set to \c INT_MAX (in limits.h).
+
+ \sa close()
+*/
+
+
+bool TQFile::open( int m, int f )
+{
+ if ( isOpen() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQFile::open: File already open" );
+#endif
+ return FALSE;
+ }
+ init();
+ setMode( m |IO_Raw );
+ setState( IO_Open );
+ fd = f;
+ ext_f = TRUE;
+ struct stat st;
+ ::fstat( fd, &st );
+#if defined(TQT_LARGEFILE_SUPPORT) && !defined(TQT_ABI_QT4)
+ off_t tmp = ::lseek(fd, 0, SEEK_CUR);
+ ioIndex = tmp > UINT_MAX ? UINT_MAX : (Offset)tmp;
+#else
+ ioIndex = (Offset)::lseek(fd, 0, SEEK_CUR);
+#endif
+ if ( (st.st_mode & S_IFMT) != S_IFREG || f == 0 ) { // stdin is not seekable...
+ // non-seekable
+ setType( IO_Sequential );
+ length = INT_MAX;
+ ioIndex = 0;
+ } else {
+#if defined(TQT_LARGEFILE_SUPPORT) && !defined(TQT_ABI_QT4)
+ length = st.st_size > UINT_MAX ? UINT_MAX : (Offset)st.st_size;
+#else
+ length = (Offset)st.st_size;
+#endif
+ if ( length == 0 && isReadable() ) {
+ // try if you can read from it (if you can, it's a sequential
+ // tqdevice; e.g. a file in the /proc filesystem)
+ int c = getch();
+ if ( c != -1 ) {
+ ungetch(c);
+ setType( IO_Sequential );
+ length = INT_MAX;
+ ioIndex = 0;
+ }
+ resetqStatus();
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ Returns the file size.
+ \sa at()
+*/
+
+TQIODevice::Offset TQFile::size() const
+{
+ struct stat st;
+ int ret = 0;
+ if ( isOpen() ) {
+ ret = ::fstat( fh ? fileno(fh) : fd, &st );
+ } else {
+ ret = ::stat( TQFile::encodeName(fn), &st );
+ }
+ if ( ret == -1 )
+ return 0;
+#if defined(TQT_LARGEFILE_SUPPORT) && !defined(TQT_ABI_QT4)
+ return (uint)st.st_size > UINT_MAX ? UINT_MAX : (Offset)st.st_size;
+#else
+ return st.st_size;
+#endif
+}
+
+
+/*!
+ \overload
+
+ Sets the file index to \a pos. Returns TRUE if successful;
+ otherwise returns FALSE.
+
+ Example:
+ \code
+ TQFile f( "data.bin" );
+ f.open( IO_ReadOnly ); // index set to 0
+ f.at( 100 ); // set index to 100
+ f.at( f.at()+50 ); // set index to 150
+ f.at( f.size()-80 ); // set index to 80 before EOF
+ f.close();
+ \endcode
+
+ Use \c at() without arguments to retrieve the file offset.
+
+ \warning The result is undefined if the file was open()'ed using
+ the \c IO_Append specifier.
+
+ \sa size(), open()
+*/
+
+bool TQFile::at( Offset pos )
+{
+ if ( !isOpen() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQFile::at: File is not open" );
+#endif
+ return FALSE;
+ }
+ if ( isSequentialAccess() )
+ return FALSE;
+ bool ok;
+ if ( isRaw() ) {
+ off_t l = ::lseek( fd, pos, SEEK_SET );
+ ok = ( l != -1 );
+ pos = (Offset)l;
+ } else { // buffered file
+#if defined(TQT_LARGEFILE_SUPPORT)
+ ok = ( ::fseeko(fh, pos, SEEK_SET) == 0 );
+#else
+ ok = ( ::fseek(fh, pos, SEEK_SET) == 0 );
+#endif
+ }
+ if ( ok )
+#if defined(TQT_LARGEFILE_SUPPORT) && !defined(TQT_ABI_QT4)
+ ioIndex = pos > UINT_MAX ? UINT_MAX : (Offset)pos;
+#else
+ ioIndex = (Offset)pos;
+#endif
+#if defined(TQT_CHECK_RANGE)
+ else
+#if defined(TQT_ABI_QT4)
+ qWarning( "TQFile::at: Cannot set file position %lld", pos );
+#else
+ qWarning( "TQFile::at: Cannot set file position %lu", pos );
+#endif
+#endif
+ return ok;
+}
+
+/*!
+ \reimp
+
+ \warning We have experienced problems with some C libraries when a buffered
+ file is opened for both reading and writing. If a read operation takes place
+ immediately after a write operation, the read buffer tqcontains garbage data.
+ Worse, the same garbage is written to the file. Calling flush() before
+ readBlock() solved this problem.
+*/
+
+TQ_LONG TQFile::readBlock( char *p, TQ_ULONG len )
+{
+ if ( !len ) // nothing to do
+ return 0;
+
+#if defined(TQT_CHECK_NULL)
+ if ( !p )
+ qWarning( "TQFile::readBlock: Null pointer error" );
+#endif
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "TQFile::readBlock: File not open" );
+ return -1;
+ }
+ if ( !isReadable() ) {
+ qWarning( "TQFile::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ TQ_ULONG nread = 0; // number of bytes read
+ if ( !ungetchBuffer.isEmpty() ) {
+ // need to add these to the returned string.
+ uint l = ungetchBuffer.length();
+ while( nread < l ) {
+ *p = ungetchBuffer.at( l - nread - 1 );
+ p++;
+ nread++;
+ }
+ ungetchBuffer.truncate( l - nread );
+ }
+
+ if ( nread < len ) {
+ if ( isRaw() ) { // raw file
+ nread += ::read( fd, p, len-nread );
+ if ( len && nread <= 0 ) {
+ nread = 0;
+ setqStatus(IO_ReadError);
+ setErrorStringErrno( errno );
+ }
+ } else { // buffered file
+ nread += fread( p, 1, len-nread, fh );
+ if ( (uint)nread != len ) {
+ if ( ferror( fh ) || nread==0 ) {
+ setqStatus(IO_ReadError);
+ setErrorString( qt_fileerr_read );
+ }
+ }
+ }
+ }
+ if ( !isSequentialAccess() )
+ ioIndex += nread;
+ return nread;
+}
+
+
+/*! \reimp
+
+ Writes \a len bytes from \a p to the file and returns the number of
+ bytes actually written.
+
+ Returns -1 if a serious error occurred.
+
+ \warning When working with buffered files, data may not be written
+ to the file at once. Call flush() to make sure the data is really
+ written.
+
+ \sa readBlock()
+*/
+
+TQ_LONG TQFile::writeBlock( const char *p, TQ_ULONG len )
+{
+ if ( !len ) // nothing to do
+ return 0;
+
+#if defined(TQT_CHECK_NULL)
+ if ( p == 0 && len != 0 )
+ qWarning( "TQFile::writeBlock: Null pointer error" );
+#endif
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) { // file not open
+ qWarning( "TQFile::writeBlock: File not open" );
+ return -1;
+ }
+ if ( !isWritable() ) { // writing not permitted
+ qWarning( "TQFile::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+#endif
+ TQ_ULONG nwritten; // number of bytes written
+ if ( isRaw() ) // raw file
+ nwritten = ::write( fd, (void *)p, len );
+ else // buffered file
+ nwritten = fwrite( p, 1, len, fh );
+ if ( nwritten != len ) { // write error
+ if ( errno == ENOSPC ) // disk is full
+ setqStatus( IO_ResourceError );
+ else
+ setqStatus( IO_WriteError );
+ setErrorStringErrno( errno );
+ if ( !isSequentialAccess() ) {
+ if ( isRaw() ) { // recalc file position
+#if defined(TQT_LARGEFILE_SUPPORT) && !defined(TQT_ABI_QT4)
+ off_t tmp = ::lseek( fd, 0, SEEK_CUR );
+ ioIndex = tmp > UINT_MAX ? UINT_MAX : (Offset)tmp;
+#else
+ ioIndex = (Offset)::lseek( fd, 0, SEEK_CUR );
+#endif
+ } else {
+#if defined(TQT_LARGEFILE_SUPPORT)
+#if !defined(TQT_ABI_QT4)
+ off_t tmp = (Offset)::fseeko( fh, 0, SEEK_CUR );
+ ioIndex = tmp > UINT_MAX ? UINT_MAX : (Offset)tmp;
+#else
+ ioIndex = (Offset)::fseeko( fh, 0, SEEK_CUR );
+#endif
+#else
+ ioIndex = (Offset)::fseek( fh, 0, SEEK_CUR );
+#endif
+ }
+ }
+ } else {
+ if ( !isSequentialAccess() )
+ ioIndex += nwritten;
+ }
+ if ( ioIndex > length ) // update file length
+ length = ioIndex;
+ return nwritten;
+}
+
+/*!
+ Returns the file handle of the file.
+
+ This is a small positive integer, suitable for use with C library
+ functions such as fdopen() and fcntl(). On systems that use file
+ descriptors for sockets (ie. Unix systems, but not Windows) the handle
+ can be used with TQSocketNotifier as well.
+
+ If the file is not open or there is an error, handle() returns -1.
+
+ \sa TQSocketNotifier
+*/
+
+int TQFile::handle() const
+{
+ if ( !isOpen() )
+ return -1;
+ else if ( fh )
+ return fileno( fh );
+ else
+ return fd;
+}
+
+/*!
+ Closes an open file.
+
+ The file is not closed if it was opened with an existing file handle.
+ If the existing file handle is a \c FILE*, the file is flushed.
+ If the existing file handle is an \c int file descriptor, nothing
+ is done to the file.
+
+ Some "write-behind" filesystems may report an unspecified error on
+ closing the file. These errors only indicate that something may
+ have gone wrong since the previous open(). In such a case status()
+ reports IO_UnspecifiedError after close(), otherwise IO_Ok.
+
+ \sa open(), flush()
+*/
+
+
+void TQFile::close()
+{
+ bool ok = FALSE;
+ if ( isOpen() ) { // file is not open
+ if ( fh ) { // buffered file
+ if ( ext_f )
+ ok = fflush( fh ) != -1; // flush instead of closing
+ else
+ ok = fclose( fh ) != -1;
+ } else { // raw file
+ if ( ext_f )
+ ok = TRUE; // cannot close
+ else
+ ok = ::close( fd ) != -1;
+ }
+ init(); // restore internal state
+ }
+ if (!ok) {
+ setqStatus( IO_UnspecifiedError );
+ setErrorStringErrno( errno );
+ }
+}
+
+#endif // USE_QT4 \ No newline at end of file
diff --git a/tqtinterface/qt4/src/tools/tqfiledefs_p.h b/tqtinterface/qt4/src/tools/tqfiledefs_p.h
new file mode 100644
index 0000000..3ddd0bb
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqfiledefs_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Common macros and system include files for TQFile, TQFileInfo and TQDir.
+**
+** Created : 930812
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFILEDEFS_P_H
+#define TQFILEDEFS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qfileinfo*.cpp. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+// Be sure to include qplatformdefs.h first!
+struct TQFileInfoCache
+{
+#if defined(TQ_WS_WIN)
+ TQT_STATBUF st;
+#else
+ struct stat st;
+#endif
+};
+
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqfileinfo.cpp b/tqtinterface/qt4/src/tools/tqfileinfo.cpp
new file mode 100644
index 0000000..fbc1278
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqfileinfo.cpp
@@ -0,0 +1,710 @@
+/****************************************************************************
+**
+** Implementation of TQFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+#include "tqfileinfo.h"
+#include "tqdatetime.h"
+#include "tqdir.h"
+#include "tqfiledefs_p.h"
+#include "tqdeepcopy.h"
+#if defined(TQT_LARGEFILE_SUPPORT) && !defined(TQT_ABI_QT4)
+#include <limits.h>
+#endif
+
+
+extern bool qt_file_access( const TQString& fn, int t );
+
+/*!
+ \class TQFileInfo
+ \reentrant
+ \brief The TQFileInfo class provides system-independent file information.
+
+ \ingroup io
+
+ TQFileInfo provides information about a file's name and position
+ (path) in the file system, its access rights and whether it is a
+ directory or symbolic link, etc. The file's size and last
+ modified/read times are also available.
+
+ A TQFileInfo can point to a file with either a relative or an
+ absolute file path. Absolute file paths begin with the directory
+ separator "/" (or with a drive specification on Windows). Relative
+ file names begin with a directory name or a file name and specify
+ a path relative to the current working directory. An example of an
+ absolute path is the string "/tmp/quartz". A relative path might
+ look like "src/fatlib". You can use the function isRelative() to
+ check whether a TQFileInfo is using a relative or an absolute file
+ path. You can call the function convertToAbs() to convert a
+ relative TQFileInfo's path to an absolute path.
+
+ The file that the TQFileInfo works on is set in the constructor or
+ later with setFile(). Use exists() to see if the file exists and
+ size() to get its size.
+
+ To speed up performance, TQFileInfo caches information about the
+ file. Because files can be changed by other users or programs, or
+ even by other parts of the same program, there is a function that
+ refreshes the file information: refresh(). If you want to switch
+ off a TQFileInfo's caching and force it to access the file system
+ every time you request information from it call setCaching(FALSE).
+
+ The file's type is obtained with isFile(), isDir() and
+ isSymLink(). The readLink() function provides the name of the file
+ the symlink points to.
+
+ Elements of the file's name can be extracted with dirPath() and
+ fileName(). The fileName()'s parts can be extracted with
+ baseName() and extension().
+
+ The file's dates are returned by created(), lastModified() and
+ lastRead(). Information about the file's access permissions is
+ obtained with isReadable(), isWritable() and isExecutable(). The
+ file's ownership is available from owner(), ownerId(), group() and
+ groupId(). You can examine a file's permissions and ownership in a
+ single statement using the permission() function.
+
+ If you need to read and traverse directories, see the TQDir class.
+*/
+
+/*!
+ \enum TQFileInfo::PermissionSpec
+
+ This enum is used by the permission() function to report the
+ permissions and ownership of a file. The values may be OR-ed
+ together to test multiple permissions and ownership values.
+
+ \value ReadOwner The file is readable by the owner of the file.
+ \value WriteOwner The file is writable by the owner of the file.
+ \value ExeOwner The file is executable by the owner of the file.
+ \value ReadUser The file is readable by the user.
+ \value WriteUser The file is writable by the user.
+ \value ExeUser The file is executable by the user.
+ \value ReadGroup The file is readable by the group.
+ \value WriteGroup The file is writable by the group.
+ \value ExeGroup The file is executable by the group.
+ \value ReadOther The file is readable by anyone.
+ \value WriteOther The file is writable by anyone.
+ \value ExeOther The file is executable by anyone.
+
+ \warning The semantics of \c ReadUser, \c WriteUser and \c ExeUser are
+ unfortunately not platform independent: on Unix, the rights of the owner of
+ the file are returned and on Windows the rights of the current user are
+ returned. This behavior might change in a future TQt version. If you want to
+ tqfind the rights of the owner of the file, you should use the flags \c
+ ReadOwner, \c WriteOwner and \c ExeOwner. If you want to tqfind out the
+ rights of the current user, you should use isReadable(), isWritable() and
+ isExecutable().
+*/
+
+
+/*!
+ Constructs a new empty TQFileInfo.
+*/
+
+TQFileInfo::TQFileInfo()
+{
+ fic = 0;
+ cache = TRUE;
+#if defined(TQ_OS_UNIX)
+ symLink = FALSE;
+#endif
+}
+
+/*!
+ Constructs a new TQFileInfo that gives information about the given
+ file. The \a file can also include an absolute or relative path.
+
+ \warning Some functions might behave in a counter-intuitive way
+ if \a file has a trailing directory separator.
+
+ \sa setFile(), isRelative(), TQDir::setCurrent(), TQDir::isRelativePath()
+*/
+
+TQFileInfo::TQFileInfo( const QString &file )
+{
+ fn = file;
+ slashify( fn );
+ fic = 0;
+ cache = TRUE;
+#if defined(TQ_OS_UNIX)
+ symLink = FALSE;
+#endif
+}
+
+/*!
+ Constructs a new TQFileInfo that gives information about file \a
+ file.
+
+ If the \a file has a relative path, the TQFileInfo will also have a
+ relative path.
+
+ \sa isRelative()
+*/
+
+TQFileInfo::TQFileInfo( const TQFile &file )
+{
+ fn = file.name();
+ slashify( fn );
+ fic = 0;
+ cache = TRUE;
+#if defined(TQ_OS_UNIX)
+ symLink = FALSE;
+#endif
+}
+
+/*!
+ Constructs a new TQFileInfo that gives information about the file
+ called \a fileName in the directory \a d.
+
+ If \a d has a relative path, the TQFileInfo will also have a
+ relative path.
+
+ \sa isRelative()
+*/
+#ifndef TQT_NO_DIR
+TQFileInfo::TQFileInfo( const TQDir &d, const TQString &fileName )
+{
+ fn = d.filePath( fileName );
+ slashify( fn );
+ fic = 0;
+ cache = TRUE;
+#if defined(TQ_OS_UNIX)
+ symLink = FALSE;
+#endif
+}
+#endif
+/*!
+ Constructs a new TQFileInfo that is a copy of \a fi.
+*/
+
+TQFileInfo::TQFileInfo( const TQFileInfo &fi )
+{
+ fn = fi.fn;
+ if ( fi.fic ) {
+ fic = new TQFileInfoCache;
+ *fic = *fi.fic;
+ } else {
+ fic = 0;
+ }
+ cache = fi.cache;
+#if defined(TQ_OS_UNIX)
+ symLink = fi.symLink;
+#endif
+}
+
+/*!
+ Destroys the TQFileInfo and frees its resources.
+*/
+
+TQFileInfo::~TQFileInfo()
+{
+ delete fic;
+}
+
+
+/*!
+ Makes a copy of \a fi and assigns it to this TQFileInfo.
+*/
+
+TQFileInfo &TQFileInfo::operator=( const TQFileInfo &fi )
+{
+ fn = fi.fn;
+ if ( !fi.fic ) {
+ delete fic;
+ fic = 0;
+ } else {
+ if ( !fic ) {
+ fic = new TQFileInfoCache;
+ TQ_CHECK_PTR( fic );
+ }
+ *fic = *fi.fic;
+ }
+ cache = fi.cache;
+#if defined(TQ_OS_UNIX)
+ symLink = fi.symLink;
+#endif
+ return *this;
+}
+
+
+/*!
+ Sets the file that the TQFileInfo provides information about to \a
+ file.
+
+ The \a file can also include an absolute or relative file path.
+ Absolute paths begin with the directory separator (e.g. "/" under
+ Unix) or a drive specification (under Windows). Relative file
+ names begin with a directory name or a file name and specify a
+ path relative to the current directory.
+
+ Example:
+ \code
+ TQString absolute = "/local/bin";
+ TQString relative = "local/bin";
+ TQFileInfo absFile( absolute );
+ TQFileInfo relFile( relative );
+
+ TQDir::setCurrent( TQDir::rootDirPath() );
+ // absFile and relFile now point to the same file
+
+ TQDir::setCurrent( "/tmp" );
+ // absFile now points to "/local/bin",
+ // while relFile points to "/tmp/local/bin"
+ \endcode
+
+ \sa isRelative(), TQDir::setCurrent(), TQDir::isRelativePath()
+*/
+
+void TQFileInfo::setFile( const TQString &file )
+{
+ fn = file;
+ slashify( fn );
+ delete fic;
+ fic = 0;
+}
+
+/*!
+ \overload
+
+ Sets the file that the TQFileInfo provides information about to \a
+ file.
+
+ If \a file includes a relative path, the TQFileInfo will also have
+ a relative path.
+
+ \sa isRelative()
+*/
+
+void TQFileInfo::setFile( const TQFile &file )
+{
+ fn = file.name();
+ slashify( fn );
+ delete fic;
+ fic = 0;
+}
+
+/*!
+ \overload
+
+ Sets the file that the TQFileInfo provides information about to \a
+ fileName in directory \a d.
+
+ If \a fileName includes a relative path, the TQFileInfo will also
+ have a relative path.
+
+ \sa isRelative()
+*/
+#ifndef TQT_NO_DIR
+void TQFileInfo::setFile( const TQDir &d, const TQString &fileName )
+{
+ fn = d.filePath( fileName );
+ slashify( fn );
+ delete fic;
+ fic = 0;
+}
+#endif
+
+/*!
+ Returns TRUE if the file exists; otherwise returns FALSE.
+*/
+
+bool TQFileInfo::exists() const
+{
+ return qt_file_access( fn, F_OK );
+}
+
+/*!
+ Refreshes the information about the file, i.e. reads in information
+ from the file system the next time a cached property is fetched.
+
+ \sa setCaching()
+*/
+
+void TQFileInfo::refresh() const
+{
+ TQFileInfo *that = (TQFileInfo*)this; // Mutable function
+ delete that->fic;
+ that->fic = 0;
+}
+
+/*!
+ \fn bool TQFileInfo::caching() const
+
+ Returns TRUE if caching is enabled; otherwise returns FALSE.
+
+ \sa setCaching(), refresh()
+*/
+
+/*!
+ If \a enable is TRUE, enables caching of file information. If \a
+ enable is FALSE caching is disabled.
+
+ When caching is enabled, TQFileInfo reads the file information from
+ the file system the first time it's needed, but generally not
+ later.
+
+ Caching is enabled by default.
+
+ \sa refresh(), caching()
+*/
+
+void TQFileInfo::setCaching( bool enable )
+{
+ if ( cache == enable )
+ return;
+ cache = enable;
+ if ( cache ) {
+ delete fic;
+ fic = 0;
+ }
+}
+
+
+/*!
+ Returns the file name, including the path (which may be absolute
+ or relative).
+
+ \sa isRelative(), absFilePath()
+*/
+
+TQString TQFileInfo::filePath() const
+{
+ return fn;
+}
+
+/*!
+ Returns the base name of the file.
+
+ If \a complete is FALSE (the default) the base name consists of
+ all characters in the file name up to (but not including) the \e
+ first '.' character.
+
+ If \a complete is TRUE the base name consists of all characters in
+ the file up to (but not including) the \e last '.' character.
+
+ The path is not included in either case.
+
+ Example:
+ \code
+ TQFileInfo fi( "/tmp/archive.tar.gz" );
+ TQString base = fi.baseName(); // base = "archive"
+ base = fi.baseName( TRUE ); // base = "archive.tar"
+ \endcode
+
+ \sa fileName(), extension()
+*/
+
+TQString TQFileInfo::baseName( bool complete ) const
+{
+ TQString tmp = fileName();
+ int pos = complete ? tmp.tqfindRev( '.' ) : tmp.tqfind( '.' );
+ if ( pos == -1 )
+ return tmp;
+ else
+ return tmp.left( pos );
+}
+
+/*!
+ Returns the file's extension name.
+
+ If \a complete is TRUE (the default), extension() returns the
+ string of all characters in the file name after (but not
+ including) the first '.' character.
+
+ If \a complete is FALSE, extension() returns the string of all
+ characters in the file name after (but not including) the last '.'
+ character.
+
+ Example:
+ \code
+ TQFileInfo fi( "/tmp/archive.tar.gz" );
+ TQString ext = fi.extension(); // ext = "tar.gz"
+ ext = fi.extension( FALSE ); // ext = "gz"
+ \endcode
+
+ \sa fileName(), baseName()
+*/
+
+TQString TQFileInfo::extension( bool complete ) const
+{
+ TQString s = fileName();
+ int pos = complete ? s.tqfind( '.' ) : s.tqfindRev( '.' );
+ if ( pos < 0 )
+ return TQString::tqfromLatin1( "" );
+ else
+ return s.right( s.length() - pos - 1 );
+}
+
+/*!
+ Returns the file's path as a TQDir object.
+
+ If the TQFileInfo is relative and \a absPath is FALSE, the TQDir
+ will be relative; otherwise it will be absolute.
+
+ \sa dirPath(), filePath(), fileName(), isRelative()
+*/
+#ifndef TQT_NO_DIR
+TQDir TQFileInfo::dir( bool absPath ) const
+{
+ return TQDir( dirPath(absPath) );
+}
+#endif
+
+
+/*!
+ Returns TRUE if the file is readable; otherwise returns FALSE.
+
+ \sa isWritable(), isExecutable(), permission()
+*/
+
+bool TQFileInfo::isReadable() const
+{
+#ifdef TQ_WS_WIN
+ return qt_file_access( fn, R_OK ) && permission( ReadUser );
+#else
+ return qt_file_access( fn, R_OK );
+#endif
+}
+
+/*!
+ Returns TRUE if the file is writable; otherwise returns FALSE.
+
+ \sa isReadable(), isExecutable(), permission()
+*/
+
+bool TQFileInfo::isWritable() const
+{
+#ifdef TQ_WS_WIN
+ return qt_file_access( fn, W_OK ) && permission( WriteUser );
+#else
+ return qt_file_access( fn, W_OK );
+#endif
+}
+
+/*!
+ Returns TRUE if the file is executable; otherwise returns FALSE.
+
+ \sa isReadable(), isWritable(), permission()
+*/
+
+bool TQFileInfo::isExecutable() const
+{
+#ifdef TQ_WS_WIN
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ return permission( ExeUser );
+#else
+ return qt_file_access( fn, X_OK ) && permission( ExeUser );
+#endif //_MSC_VER >= 1400
+#else
+ return qt_file_access( fn, X_OK );
+#endif
+}
+
+#ifndef TQ_WS_WIN
+bool TQFileInfo::isHidden() const
+{
+ return fileName()[ 0 ] == TQChar( '.' );
+}
+#endif
+
+/*!
+ Returns TRUE if the file path name is relative. Returns FALSE if
+ the path is absolute (e.g. under Unix a path is absolute if it
+ begins with a "/").
+*/
+#ifndef TQT_NO_DIR
+bool TQFileInfo::isRelative() const
+{
+ return TQDir::isRelativePath( fn );
+}
+
+/*!
+ Converts the file's path to an absolute path.
+
+ If it is already absolute, nothing is done.
+
+ \sa filePath(), isRelative()
+*/
+
+bool TQFileInfo::convertToAbs()
+{
+ if ( isRelative() )
+ fn = absFilePath();
+ return TQDir::isRelativePath( fn );
+}
+#endif
+
+/*!
+ Returns the file size in bytes, or 0 if the file does not exist or
+ if the size is 0 or if the size cannot be fetched.
+*/
+#if defined(TQT_ABI_QT4)
+TQIODevice::Offset TQFileInfo::size() const
+#else
+uint TQFileInfo::size() const
+#endif
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+#if defined(TQT_ABI_QT4)
+ return (TQIODevice::Offset)fic->st.st_size;
+#elif defined(TQT_LARGEFILE_SUPPORT)
+ return (uint)fic->st.st_size > UINT_MAX ? UINT_MAX : (uint)fic->st.st_size;
+#else
+ return (uint)fic->st.st_size;
+#endif
+ else
+ return 0;
+}
+
+/*!
+ Returns the date and time when the file was created.
+
+ On platforms where this information is not available, returns the
+ same as lastModified().
+
+ \sa created() lastModified() lastRead()
+*/
+
+TQDateTime TQFileInfo::created() const
+{
+ TQDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic && fic->st.st_ctime != 0 ) {
+ dt.setTime_t( fic->st.st_ctime );
+ return dt;
+ } else {
+ return lastModified();
+ }
+}
+
+/*!
+ Returns the date and time when the file was last modified.
+
+ \sa created() lastModified() lastRead()
+*/
+
+TQDateTime TQFileInfo::lastModified() const
+{
+ TQDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ dt.setTime_t( fic->st.st_mtime );
+ return dt;
+}
+
+/*!
+ Returns the date and time when the file was last read (accessed).
+
+ On platforms where this information is not available, returns the
+ same as lastModified().
+
+ \sa created() lastModified() lastRead()
+*/
+
+TQDateTime TQFileInfo::lastRead() const
+{
+ TQDateTime dt;
+ if ( !fic || !cache )
+ doStat();
+ if ( fic && fic->st.st_atime != 0 ) {
+ dt.setTime_t( fic->st.st_atime );
+ return dt;
+ } else {
+ return lastModified();
+ }
+}
+
+#ifndef TQT_NO_DIR
+
+/*!
+ Returns the absolute path including the file name.
+
+ The absolute path name consists of the full path and the file
+ name. On Unix this will always begin with the root, '/',
+ directory. On Windows this will always begin 'D:/' where D is a
+ drive letter, except for network shares that are not mapped to a
+ drive letter, in which case the path will begin '//sharename/'.
+
+ This function returns the same as filePath(), unless isRelative()
+ is TRUE.
+
+ If the TQFileInfo is empty it returns TQDir::currentDirPath().
+
+ This function can be time consuming under Unix (in the order of
+ milliseconds).
+
+ \sa isRelative(), filePath()
+*/
+TQString TQFileInfo::absFilePath() const
+{
+ TQString tmp;
+ if ( TQDir::isRelativePath(fn)
+#if defined(TQ_OS_WIN32)
+ && fn[1] != ':'
+#endif
+ ) {
+ tmp = TQDir::currentDirPath();
+ tmp += '/';
+ }
+ tmp += fn;
+ makeAbs( tmp );
+ return TQDir::cleanDirPath( tmp );
+}
+
+/*! \internal
+ Detaches all internal data.
+*/
+void TQFileInfo::detach()
+{
+ fn = TQDeepCopy<TQString>( fn );
+ if ( fic ) {
+ TQFileInfoCache *cur = fic;
+ fic = new TQFileInfoCache;
+ *fic = *cur;
+ delete cur;
+ }
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqfileinfo.h b/tqtinterface/qt4/src/tools/tqfileinfo.h
new file mode 100644
index 0000000..b87b2ad
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqfileinfo.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Definition of TQFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFILEINFO_H
+#define TQFILEINFO_H
+
+#ifndef TQT_H
+#include "tqfile.h"
+#include "tqdatetime.h"
+#endif // TQT_H
+
+
+class TQDir;
+struct TQFileInfoCache;
+template <class T> class TQDeepCopy;
+
+
+class TQ_EXPORT TQFileInfo
+{
+public:
+ enum PermissionSpec {
+ ReadOwner = 04000, WriteOwner = 02000, ExeOwner = 01000,
+ ReadUser = 00400, WriteUser = 00200, ExeUser = 00100,
+ ReadGroup = 00040, WriteGroup = 00020, ExeGroup = 00010,
+ ReadOther = 00004, WriteOther = 00002, ExeOther = 00001 };
+
+ TQFileInfo();
+ TQFileInfo( const QString &file );
+ TQFileInfo( const TQFile & );
+#ifndef TQT_NO_DIR
+ TQFileInfo( const TQDir &, const TQString &fileName );
+#endif
+ TQFileInfo( const TQFileInfo & );
+ ~TQFileInfo();
+
+ TQFileInfo &operator=( const TQFileInfo & );
+
+ void setFile( const TQString &file );
+ void setFile( const TQFile & );
+#ifndef TQT_NO_DIR
+ void setFile( const TQDir &, const TQString &fileName );
+#endif
+ bool exists() const;
+ void refresh() const;
+ bool caching() const;
+ void setCaching( bool );
+
+ TQString filePath() const;
+ TQString fileName() const;
+#ifndef TQT_NO_DIR //###
+ TQString absFilePath() const;
+#endif
+ TQString baseName( bool complete = FALSE ) const;
+ TQString extension( bool complete = TRUE ) const;
+
+#ifndef TQT_NO_DIR //###
+ TQString dirPath( bool absPath = FALSE ) const;
+#endif
+#ifndef TQT_NO_DIR
+ TQDir dir( bool absPath = FALSE ) const;
+#endif
+ bool isReadable() const;
+ bool isWritable() const;
+ bool isExecutable() const;
+ bool isHidden() const;
+
+#ifndef TQT_NO_DIR //###
+ bool isRelative() const;
+ bool convertToAbs();
+#endif
+
+ bool isFile() const;
+ bool isDir() const;
+ bool isSymLink() const;
+
+ TQString readLink() const;
+
+ TQString owner() const;
+ uint ownerId() const;
+ TQString group() const;
+ uint groupId() const;
+
+ bool permission( int permissionSpec ) const;
+
+#if (TQT_VERSION-0 >= 0x040000)
+#error "TQFileInfo::size() should return TQIODevice::Offset instead of uint"
+#elif defined(TQT_ABI_QT4)
+ TQIODevice::Offset size() const;
+#else
+ uint size() const;
+#endif
+
+ TQDateTime created() const;
+ TQDateTime lastModified() const;
+ TQDateTime lastRead() const;
+
+private:
+ void doStat() const;
+ static void slashify( TQString & );
+ static void makeAbs( TQString & );
+
+ TQString fn;
+ TQFileInfoCache *fic;
+ bool cache;
+#if defined(TQ_OS_UNIX)
+ bool symLink;
+#endif
+
+ void detach();
+ friend class TQDeepCopy< TQFileInfo >;
+};
+
+
+inline bool TQFileInfo::caching() const
+{
+ return cache;
+}
+
+
+#endif // TQFILEINFO_H
diff --git a/tqtinterface/qt4/src/tools/tqfileinfo_unix.cpp b/tqtinterface/qt4/src/tools/tqfileinfo_unix.cpp
new file mode 100644
index 0000000..921b9f9
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqfileinfo_unix.cpp
@@ -0,0 +1,370 @@
+/****************************************************************************
+**
+** Implementation of TQFileInfo class
+**
+** Created : 950628
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+#include "tqfileinfo.h"
+#include "tqfiledefs_p.h"
+#include "tqdatetime.h"
+#include "tqdir.h"
+
+#include <limits.h>
+#if !defined(TQWS) && defined(TQ_OS_MAC)
+# include <tqt_mac.h>
+#endif
+
+void TQFileInfo::slashify( TQString& )
+{
+ return;
+}
+
+
+void TQFileInfo::makeAbs( TQString & )
+{
+ return;
+}
+
+/*!
+ Returns TRUE if this object points to a file. Returns FALSE if the
+ object points to something which isn't a file, e.g. a directory or
+ a symlink.
+
+ \sa isDir(), isSymLink()
+*/
+bool TQFileInfo::isFile() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? (fic->st.st_mode & S_IFMT) == S_IFREG : FALSE;
+}
+
+/*!
+ Returns TRUE if this object points to a directory or to a symbolic
+ link to a directory; otherwise returns FALSE.
+
+ \sa isFile(), isSymLink()
+*/
+bool TQFileInfo::isDir() const
+{
+ if ( !fic || !cache )
+ doStat();
+ return fic ? (fic->st.st_mode & S_IFMT) == S_IFDIR : FALSE;
+}
+
+/*!
+ Returns TRUE if this object points to a symbolic link (or to a
+ shortcut on Windows, or an alias on Mac OS X); otherwise returns
+ FALSE.
+
+ \sa isFile(), isDir(), readLink()
+*/
+
+bool TQFileInfo::isSymLink() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if(symLink)
+ return TRUE;
+#if !defined(TQWS) && defined(TQ_OS_MAC)
+ {
+ FSRef fref;
+ if(FSPathMakeRef((const UInt8 *)TQFile::encodeName(fn).data(), &fref, NULL) == noErr) {
+ Boolean isAlias, isFolder;
+ if(FSIsAliasFile(&fref, &isAlias, &isFolder) == noErr)
+ return isAlias;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+/*!
+ Returns the name a symlink (or shortcut on Windows) points to, or
+ a TQString::null if the object isn't a symbolic link.
+
+ This name may not represent an existing file; it is only a string.
+ TQFileInfo::exists() returns TRUE if the symlink points to an
+ existing file.
+
+ \sa exists(), isSymLink(), isDir(), isFile()
+*/
+
+TQString TQFileInfo::readLink() const
+{
+#if defined(TQ_OS_UNIX) && !defined(TQ_OS_OS2EMX)
+ char s[PATH_MAX+1];
+ if ( !isSymLink() )
+ return TQString();
+ int len = readlink( TQFile::encodeName(fn).data(), s, PATH_MAX );
+ if ( len >= 0 ) {
+ s[len] = '\0';
+ return TQFile::decodeName(s);
+ }
+#endif
+#if !defined(TQWS) && defined(TQ_OS_MAC)
+ {
+ FSRef fref;
+ if(FSPathMakeRef((const UInt8 *)TQFile::encodeName(fn).data(), &fref, NULL) == noErr) {
+ Boolean isAlias, isFolder;
+ if(FSResolveAliasFile(&fref, TRUE, &isFolder, &isAlias) == noErr && isAlias) {
+ AliasHandle alias;
+ if(FSNewAlias(0, &fref, &alias) == noErr && alias) {
+ CFStringRef cfstr;
+ if(FSCopyAliasInfo(alias, 0, 0, &cfstr, 0, 0) == noErr) {
+ TQString cfstring2qstring(CFStringRef str); //qglobal.cpp
+ return cfstring2qstring(cfstr);
+ }
+ }
+ }
+ }
+ }
+#endif
+ return TQString();
+}
+
+static const uint nobodyID = (uint) -2;
+
+/*!
+ Returns the owner of the file. On systems where files
+ do not have owners, or if an error occurs, TQString::null is
+ returned.
+
+ This function can be time consuming under Unix (in the order of
+ milliseconds).
+
+ \sa ownerId(), group(), groupId()
+*/
+
+TQString TQFileInfo::owner() const
+{
+ passwd *pw = getpwuid( ownerId() );
+ if ( pw )
+ return TQFile::decodeName( pw->pw_name );
+ return TQString::null;
+}
+
+/*!
+ Returns the id of the owner of the file.
+
+ On Windows and on systems where files do not have owners this
+ function returns ((uint) -2).
+
+ \sa owner(), group(), groupId()
+*/
+
+uint TQFileInfo::ownerId() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ return fic->st.st_uid;
+ return nobodyID;
+}
+
+/*!
+ Returns the group of the file. On Windows, on systems where files
+ do not have groups, or if an error occurs, TQString::null is
+ returned.
+
+ This function can be time consuming under Unix (in the order of
+ milliseconds).
+
+ \sa groupId(), owner(), ownerId()
+*/
+
+TQString TQFileInfo::group() const
+{
+ struct group *gr = getgrgid( groupId() );
+ if ( gr )
+ return TQFile::decodeName( gr->gr_name );
+ return TQString::null;
+}
+
+/*!
+ Returns the id of the group the file belongs to.
+
+ On Windows and on systems where files do not have groups this
+ function always returns (uint) -2.
+
+ \sa group(), owner(), ownerId()
+*/
+
+uint TQFileInfo::groupId() const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic )
+ return fic->st.st_gid;
+ return nobodyID;
+}
+
+
+/*!
+ Tests for file permissions. The \a permissionSpec argument can be
+ several flags of type \c PermissionSpec OR-ed together to check
+ for permission combinations.
+
+ On systems where files do not have permissions this function
+ always returns TRUE.
+
+ Example:
+ \code
+ TQFileInfo fi( "/tmp/archive.tar.gz" );
+ if ( fi.permission( TQFileInfo::WriteUser | TQFileInfo::ReadGroup ) )
+ qWarning( "I can change the file; my group can read the file" );
+ if ( fi.permission( TQFileInfo::WriteGroup | TQFileInfo::WriteOther ) )
+ qWarning( "The group or others can change the file" );
+ \endcode
+
+ \sa isReadable(), isWritable(), isExecutable()
+*/
+
+bool TQFileInfo::permission( int permissionSpec ) const
+{
+ if ( !fic || !cache )
+ doStat();
+ if ( fic ) {
+ uint tqmask = 0;
+ if ( permissionSpec & ReadOwner )
+ tqmask |= S_IRUSR;
+ if ( permissionSpec & WriteOwner )
+ tqmask |= S_IWUSR;
+ if ( permissionSpec & ExeOwner )
+ tqmask |= S_IXUSR;
+ if ( permissionSpec & ReadUser )
+ tqmask |= S_IRUSR;
+ if ( permissionSpec & WriteUser )
+ tqmask |= S_IWUSR;
+ if ( permissionSpec & ExeUser )
+ tqmask |= S_IXUSR;
+ if ( permissionSpec & ReadGroup )
+ tqmask |= S_IRGRP;
+ if ( permissionSpec & WriteGroup )
+ tqmask |= S_IWGRP;
+ if ( permissionSpec & ExeGroup )
+ tqmask |= S_IXGRP;
+ if ( permissionSpec & ReadOther )
+ tqmask |= S_IROTH;
+ if ( permissionSpec & WriteOther )
+ tqmask |= S_IWOTH;
+ if ( permissionSpec & ExeOther )
+ tqmask |= S_IXOTH;
+ if ( tqmask ) {
+ return (fic->st.st_mode & tqmask) == tqmask;
+ } else {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQFileInfo::permission: permissionSpec is 0" );
+#endif
+ return TRUE;
+ }
+ } else {
+ return FALSE;
+ }
+}
+
+void TQFileInfo::doStat() const
+{
+ TQFileInfo *that = ((TQFileInfo*)this); // mutable function
+ if ( !that->fic )
+ that->fic = new TQFileInfoCache;
+ that->symLink = FALSE;
+ struct stat *b = &that->fic->st;
+#if defined(TQ_OS_UNIX) && defined(S_IFLNK)
+ if ( ::lstat( TQFile::encodeName(fn), b ) == 0 ) {
+ if ( S_ISLNK( b->st_mode ) )
+ that->symLink = TRUE;
+ else
+ return;
+ }
+#endif
+
+ int r = ::stat( TQFile::encodeName(fn), b );
+ if ( r != 0 && !that->symLink ) {
+ delete that->fic;
+ that->fic = 0;
+ }
+}
+
+/*!
+ Returns the file's path.
+
+ If \a absPath is TRUE an absolute path is returned.
+
+ \sa dir(), filePath(), fileName(), isRelative()
+*/
+#ifndef TQT_NO_DIR
+TQString TQFileInfo::dirPath( bool absPath ) const
+{
+ TQString s;
+ if ( absPath )
+ s = absFilePath();
+ else
+ s = fn;
+ int pos = s.tqfindRev( '/' );
+ if ( pos == -1 ) {
+ return TQString::tqfromLatin1( "." );
+ } else {
+ if ( pos == 0 )
+ return TQString::tqfromLatin1( "/" );
+ return s.left( pos );
+ }
+}
+#endif
+
+/*!
+ Returns the name of the file, excluding the path.
+
+ Example:
+ \code
+ TQFileInfo fi( "/tmp/archive.tar.gz" );
+ TQString name = fi.fileName(); // name = "archive.tar.gz"
+ \endcode
+
+ \sa isRelative(), filePath(), baseName(), extension()
+*/
+
+TQString TQFileInfo::fileName() const
+{
+ int p = fn.tqfindRev( '/' );
+ if ( p == -1 ) {
+ return fn;
+ } else {
+ return fn.mid( p + 1 );
+ }
+}
diff --git a/tqtinterface/qt4/src/tools/tqgarray.cpp b/tqtinterface/qt4/src/tools/tqgarray.cpp
new file mode 100644
index 0000000..f0e89f9
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgarray.cpp
@@ -0,0 +1,830 @@
+/****************************************************************************
+**
+** Implementation of TQGArray class
+**
+** Created : 930906
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqglobal.h"
+#if defined(TQ_CC_BOR)
+ // needed for qsort() because of a std namespace problem on Borland
+# include "tqplatformdefs.h"
+#elif defined(TQ_WS_WIN)
+ // needed for bsearch on some platforms
+# include "tqt_windows.h"
+#endif
+
+#define TQGARRAY_CPP
+#include "tqgarray.h"
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef TQT_THREAD_SUPPORT
+# include <private/tqmutexpool_p.h>
+#endif // TQT_THREAD_SUPPORT
+
+/*
+ If USE_MALLOC isn't defined, we use new[] and delete[] to allocate
+ memory. The documentation for TQMemArray<T>::assign() explicitly
+ mentions that the array is freed using free(), so don't mess around
+ with USE_MALLOC unless you know what you're doing.
+*/
+#define USE_MALLOC
+
+#undef NEW
+#undef DELETE
+
+#if defined(USE_MALLOC)
+#define NEW(type,size) ((type*)malloc(size*sizeof(type)))
+#define DELETE(array) (free((char*)array))
+#else
+#define NEW(type,size) (new type[size])
+#define DELETE(array) (delete[] array)
+#define DONT_USE_REALLOC // comment to use realloc()
+#endif
+
+/*!
+ \class TQShared tqshared.h
+ \reentrant
+ \ingroup shared
+ \brief The TQShared class is used internally for implementing shared classes.
+
+ \internal
+
+ It only tqcontains a reference count and member functions to increment and
+ decrement it.
+
+ Shared classes normally have internal classes that inherit TQShared and
+ add the shared data.
+
+ \sa \link shclass.html Shared Classes\endlink
+*/
+
+/*!
+ \class TQGArray tqgarray.h
+ \reentrant
+ \ingroup shared
+ \ingroup collection
+ \brief The TQGArray class is an internal class for implementing the TQMemArray class.
+
+ \internal
+
+ TQGArray is a strictly internal class that acts as base class for the
+ TQMemArray template array.
+
+ It tqcontains an array of bytes and has no notion of an array element.
+*/
+
+
+/*!
+ Constructs a null array.
+*/
+
+TQGArray::TQGArray()
+{
+ shd = newData();
+ TQ_CHECK_PTR( shd );
+}
+
+/*!
+ Dummy constructor; does not allocate any data.
+
+ This constructor does not initialize any array data so subclasses
+ must do it. The intention is to make the code more efficient.
+*/
+
+TQGArray::TQGArray( int, int )
+{
+}
+
+/*!
+ Constructs an array with room for \a size bytes.
+*/
+
+TQGArray::TQGArray( int size )
+{
+ if ( size < 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQGArray: Cannot allocate array with negative length" );
+#endif
+ size = 0;
+ }
+ shd = newData();
+ TQ_CHECK_PTR( shd );
+ if ( size == 0 ) // zero length
+ return;
+ shd->data = NEW(char,size);
+ TQ_CHECK_PTR( shd->data );
+ shd->len =
+#ifdef TQT_TQGARRAY_SPEED_OPTIM
+ shd->maxl =
+#endif
+ size;
+}
+
+/*!
+ Constructs a shallow copy of \a a.
+*/
+
+TQGArray::TQGArray( const TQGArray &a )
+{
+ shd = a.shd;
+ shd->ref();
+}
+
+/*!
+ Dereferences the array data and deletes it if this was the last
+ reference.
+*/
+
+TQGArray::~TQGArray()
+{
+ if ( shd && shd->deref() ) { // delete when last reference
+ if ( shd->data ) // is lost
+ DELETE(shd->data);
+ deleteData( shd );
+ shd = 0;
+ }
+}
+
+
+/*!
+ \fn TQGArray &TQGArray::operator=( const TQGArray &a )
+
+ Assigns a shallow copy of \a a to this array and returns a reference to
+ this array. Equivalent to assign().
+*/
+
+/*!
+ \fn void TQGArray::detach()
+
+ Detaches this array from shared array data.
+*/
+
+/*!
+ \fn char *TQGArray::data() const
+
+ Returns a pointer to the actual array data.
+*/
+
+/*!
+ \fn uint TQGArray::nrefs() const
+
+ Returns the reference count.
+*/
+
+/*!
+ \fn uint TQGArray::size() const
+
+ Returns the size of the array, in bytes.
+*/
+
+
+/*!
+ Returns TRUE if this array is equal to \a a, otherwise FALSE.
+ The comparison is bitwise, of course.
+*/
+
+bool TQGArray::isEqual( const TQGArray &a ) const
+{
+ if ( size() != a.size() ) // different size
+ return FALSE;
+ if ( data() == a.data() ) // has same data
+ return TRUE;
+ return (size() ? memcmp( data(), a.data(), size() ) : 0) == 0;
+}
+
+
+/*!
+ Resizes the array to \a newsize bytes. \a optim is either
+ \c MemOptim (the default) or \c SpeedOptim.
+
+ <b>Note:</b> \c SpeedOptim is only available if TQt is built in a
+ particular configuration. By default, \c SpeedOptim is not available
+ for general use.
+*/
+bool TQGArray::resize( uint newsize, Optimization optim )
+{
+#ifndef TQT_TQGARRAY_SPEED_OPTIM
+ TQ_UNUSED(optim);
+#endif
+
+ if ( newsize == shd->len
+#ifdef TQT_TQGARRAY_SPEED_OPTIM
+ && newsize == shd->maxl
+#endif
+ ) // nothing to do
+ return TRUE;
+ if ( newsize == 0 ) { // remove array
+ if ( shd->data )
+ DELETE(shd->data);
+ shd->data = 0;
+ shd->len = 0;
+#ifdef TQT_TQGARRAY_SPEED_OPTIM
+ shd->maxl = 0;
+#endif
+ return TRUE;
+ }
+
+ uint newmaxl = newsize;
+#ifdef TQT_TQGARRAY_SPEED_OPTIM
+ if ( optim == SpeedOptim ) {
+ if ( newsize <= shd->maxl &&
+ ( newsize * 4 > shd->maxl || shd->maxl <= 4 ) ) {
+ shd->len = newsize;
+ return TRUE;
+ }
+ newmaxl = 4;
+ while ( newmaxl < newsize )
+ newmaxl *= 2;
+ // try to spare some memory
+ if ( newmaxl >= 1024 * 1024 && newsize <= newmaxl - (newmaxl >> 2) )
+ newmaxl -= newmaxl >> 2;
+ }
+ shd->maxl = newmaxl;
+#endif
+
+ if ( shd->data ) { // existing data
+#if defined(DONT_USE_REALLOC)
+ char *newdata = NEW(char,newsize); // manual realloc
+ memcpy( newdata, shd->data, TQMIN(shd->len,newmaxl) );
+ DELETE(shd->data);
+ shd->data = newdata;
+#else
+ shd->data = (char *)realloc( shd->data, newmaxl );
+#endif
+ } else {
+ shd->data = NEW(char,newmaxl);
+ }
+ if ( !shd->data ) // no memory
+ return FALSE;
+ shd->len = newsize;
+ return TRUE;
+}
+
+/*!\overload
+*/
+bool TQGArray::resize( uint newsize )
+{
+ return resize( newsize, MemOptim );
+}
+
+
+/*!
+ Fills the array with the repeated occurrences of \a d, which is
+ \a sz bytes long.
+ If \a len is specified as different from -1, then the array will be
+ resized to \a len*sz before it is filled.
+
+ Returns TRUE if successful, or FALSE if the memory cannot be allocated
+ (only when \a len != -1).
+
+ \sa resize()
+*/
+
+bool TQGArray::fill( const char *d, int len, uint sz )
+{
+ if ( len < 0 )
+ len = shd->len/sz; // default: use array length
+ else if ( !resize( len*sz ) )
+ return FALSE;
+ if ( sz == 1 ) // 8 bit elements
+ memset( data(), *d, len );
+ else if ( sz == 4 ) { // 32 bit elements
+ register TQ_INT32 *x = (TQ_INT32*)data();
+ TQ_INT32 v = *((TQ_INT32*)d);
+ while ( len-- )
+ *x++ = v;
+ } else if ( sz == 2 ) { // 16 bit elements
+ register TQ_INT16 *x = (TQ_INT16*)data();
+ TQ_INT16 v = *((TQ_INT16*)d);
+ while ( len-- )
+ *x++ = v;
+ } else { // any other size elements
+ register char *x = data();
+ while ( len-- ) { // more complicated
+ memcpy( x, d, sz );
+ x += sz;
+ }
+ }
+ return TRUE;
+}
+
+/*!
+ \overload
+ Shallow copy. Dereference the current array and references the data
+ contained in \a a instead. Returns a reference to this array.
+ \sa operator=()
+*/
+
+TQGArray &TQGArray::assign( const TQGArray &a )
+{
+ a.shd->ref(); // avoid 'a = a'
+ if ( shd->deref() ) { // delete when last reference
+ if ( shd->data ) // is lost
+ DELETE(shd->data);
+ deleteData( shd );
+ }
+ shd = a.shd;
+ return *this;
+}
+
+/*!
+ Shallow copy. Dereference the current array and references the
+ array data \a d, which tqcontains \a len bytes.
+ Returns a reference to this array.
+
+ Do not delete \a d later, because TQGArray takes care of that.
+*/
+
+TQGArray &TQGArray::assign( const char *d, uint len )
+{
+ if ( shd->count > 1 ) { // disconnect this
+ shd->count--;
+ shd = newData();
+ TQ_CHECK_PTR( shd );
+ } else {
+ if ( shd->data )
+ DELETE(shd->data);
+ }
+ shd->data = (char *)d;
+ shd->len =
+#ifdef TQT_TQGARRAY_SPEED_OPTIM
+ shd->maxl =
+#endif
+ len;
+ return *this;
+}
+
+/*!
+ Deep copy. Dereference the current array and obtains a copy of the data
+ contained in \a a instead. Returns a reference to this array.
+ \sa assign(), operator=()
+*/
+
+TQGArray &TQGArray::duplicate( const TQGArray &a )
+{
+ if ( a.shd == shd ) { // a.duplicate(a) !
+ if ( shd->count > 1 ) {
+ shd->count--;
+ register array_data *n = newData();
+ TQ_CHECK_PTR( n );
+ if ( (n->len=shd->len) ) {
+ n->data = NEW(char,n->len);
+ TQ_CHECK_PTR( n->data );
+ if ( n->data )
+ memcpy( n->data, shd->data, n->len );
+ } else {
+ n->data = 0;
+ }
+ shd = n;
+ }
+ return *this;
+ }
+ char *oldptr = 0;
+ if ( shd->count > 1 ) { // disconnect this
+ shd->count--;
+ shd = newData();
+ TQ_CHECK_PTR( shd );
+ } else { // delete after copy was made
+ oldptr = shd->data;
+ }
+ if ( a.shd->len ) { // duplicate data
+ shd->data = NEW(char,a.shd->len);
+ TQ_CHECK_PTR( shd->data );
+ if ( shd->data )
+ memcpy( shd->data, a.shd->data, a.shd->len );
+ } else {
+ shd->data = 0;
+ }
+ shd->len =
+#ifdef TQT_TQGARRAY_SPEED_OPTIM
+ shd->maxl =
+#endif
+ a.shd->len;
+ if ( oldptr )
+ DELETE(oldptr);
+ return *this;
+}
+
+/*!
+ \overload
+ Deep copy. Dereferences the current array and obtains a copy of
+ \a len characters from array data \a d instead. Returns a reference
+ to this array.
+ \sa assign(), operator=()
+*/
+
+TQGArray &TQGArray::duplicate( const char *d, uint len )
+{
+ char *data;
+ if ( d == 0 || len == 0 ) {
+ data = 0;
+ len = 0;
+ } else {
+ if ( shd->count == 1 && shd->len == len ) {
+ if ( shd->data != d ) // avoid self-assignment
+ memcpy( shd->data, d, len ); // use same buffer
+ return *this;
+ }
+ data = NEW(char,len);
+ TQ_CHECK_PTR( data );
+ memcpy( data, d, len );
+ }
+ if ( shd->count > 1 ) { // detach
+ shd->count--;
+ shd = newData();
+ TQ_CHECK_PTR( shd );
+ } else { // just a single reference
+ if ( shd->data )
+ DELETE(shd->data);
+ }
+ shd->data = data;
+ shd->len =
+#ifdef TQT_TQGARRAY_SPEED_OPTIM
+ shd->maxl =
+#endif
+ len;
+ return *this;
+}
+
+/*!
+ Resizes this array to \a len bytes and copies the \a len bytes at
+ address \a d into it.
+
+ \warning This function disregards the reference count mechanism. If
+ other TQGArrays reference the same data as this, all will be updated.
+*/
+
+void TQGArray::store( const char *d, uint len )
+{ // store, but not deref
+ resize( len );
+ memcpy( shd->data, d, len );
+}
+
+
+/*!
+ \fn array_data *TQGArray::sharedBlock() const
+
+ Returns a pointer to the shared array block.
+
+ \warning
+
+ Do not use this function. Using it is begging for trouble. We dare
+ not remove it, for fear of breaking code, but we \e strongly
+ discourage new use of it.
+*/
+
+/*!
+ \fn void TQGArray::setSharedBlock( array_data *p )
+
+ Sets the shared array block to \a p.
+
+ \warning
+
+ Do not use this function. Using it is begging for trouble. We dare
+ not remove it, for fear of breaking code, but we \e strongly
+ discourage new use of it.
+*/
+
+
+/*!
+ Sets raw data and returns a reference to the array.
+
+ Dereferences the current array and sets the new array data to \a d and
+ the new array size to \a len. Do not attempt to resize or re-assign the
+ array data when raw data has been set.
+ Call resetRawData(d,len) to reset the array.
+
+ Setting raw data is useful because it sets TQMemArray data without
+ allocating memory or copying data.
+
+ Example of intended use:
+ \code
+ static uchar bindata[] = { 231, 1, 44, ... };
+ TQByteArray a;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ TQDataStream s( a, IO_ReadOnly ); // open on a's data
+ s >> <something>; // read raw bindata
+ s.close();
+ a.resetRawData( bindata, sizeof(bindata) ); // finished
+ \endcode
+
+ Example of misuse (do not do this):
+ \code
+ static uchar bindata[] = { 231, 1, 44, ... };
+ TQByteArray a, b;
+ a.setRawData( bindata, sizeof(bindata) ); // a points to bindata
+ a.resize( 8 ); // will crash
+ b = a; // will crash
+ a[2] = 123; // might crash
+ // forget to resetRawData - will crash
+ \endcode
+
+ \warning If you do not call resetRawData(), TQGArray will attempt to
+ deallocate or reallocate the raw data, which might not be too good.
+ Be careful.
+*/
+
+TQGArray &TQGArray::setRawData( const char *d, uint len )
+{
+ duplicate( 0, 0 ); // set null data
+ shd->data = (char *)d;
+ shd->len = len;
+ return *this;
+}
+
+/*!
+ Resets raw data.
+
+ The arguments must be the data, \a d, and length \a len, that were
+ passed to setRawData(). This is for consistency checking.
+*/
+
+void TQGArray::resetRawData( const char *d, uint len )
+{
+ if ( d != shd->data || len != shd->len ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQGArray::resetRawData: Inconsistent arguments" );
+#endif
+ return;
+ }
+ shd->data = 0;
+ shd->len = 0;
+}
+
+
+/*!
+ Finds the first occurrence of \a d in the array from position \a index,
+ where \a sz is the size of the \a d element.
+
+ Note that \a index is given in units of \a sz, not bytes.
+
+ This function only compares whole cells, not bytes.
+*/
+
+int TQGArray::tqfind( const char *d, uint index, uint sz ) const
+{
+ index *= sz;
+ if ( index >= shd->len ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQGArray::tqfind: Index %d out of range", index/sz );
+#endif
+ return -1;
+ }
+ register uint i;
+ uint ii;
+ switch ( sz ) {
+ case 1: { // 8 bit elements
+ register char *x = data() + index;
+ char v = *d;
+ for ( i=index; i<shd->len; i++ ) {
+ if ( *x++ == v )
+ break;
+ }
+ ii = i;
+ }
+ break;
+ case 2: { // 16 bit elements
+ register TQ_INT16 *x = (TQ_INT16*)(data() + index);
+ TQ_INT16 v = *((TQ_INT16*)d);
+ for ( i=index; i<shd->len; i+=2 ) {
+ if ( *x++ == v )
+ break;
+ }
+ ii = i/2;
+ }
+ break;
+ case 4: { // 32 bit elements
+ register TQ_INT32 *x = (TQ_INT32*)(data() + index);
+ TQ_INT32 v = *((TQ_INT32*)d);
+ for ( i=index; i<shd->len; i+=4 ) {
+ if ( *x++ == v )
+ break;
+ }
+ ii = i/4;
+ }
+ break;
+ default: { // any size elements
+ for ( i=index; i<shd->len; i+=sz ) {
+ if ( memcmp( d, &shd->data[i], sz ) == 0 )
+ break;
+ }
+ ii = i/sz;
+ }
+ break;
+ }
+ return i<shd->len ? (int)ii : -1;
+}
+
+/*!
+ Returns the number of occurrences of \a d in the array, where \a sz is
+ the size of the \a d element.
+
+ This function only compares whole cells, not bytes.
+*/
+
+int TQGArray::tqcontains( const char *d, uint sz ) const
+{
+ register uint i = shd->len;
+ int count = 0;
+ switch ( sz ) {
+ case 1: { // 8 bit elements
+ register char *x = data();
+ char v = *d;
+ while ( i-- ) {
+ if ( *x++ == v )
+ count++;
+ }
+ }
+ break;
+ case 2: { // 16 bit elements
+ register TQ_INT16 *x = (TQ_INT16*)data();
+ TQ_INT16 v = *((TQ_INT16*)d);
+ i /= 2;
+ while ( i-- ) {
+ if ( *x++ == v )
+ count++;
+ }
+ }
+ break;
+ case 4: { // 32 bit elements
+ register TQ_INT32 *x = (TQ_INT32*)data();
+ TQ_INT32 v = *((TQ_INT32*)d);
+ i /= 4;
+ while ( i-- ) {
+ if ( *x++ == v )
+ count++;
+ }
+ }
+ break;
+ default: { // any size elements
+ for ( i=0; i<shd->len; i+=sz ) {
+ if ( memcmp(d, &shd->data[i], sz) == 0 )
+ count++;
+ }
+ }
+ break;
+ }
+ return count;
+}
+
+static int cmp_item_size = 0;
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+#ifdef TQ_OS_TEMP
+static int __cdecl cmp_arr( const void *n1, const void *n2 )
+#else
+static int cmp_arr( const void *n1, const void *n2 )
+#endif
+{
+ return ( n1 && n2 ) ? memcmp( n1, n2, cmp_item_size )
+ : ( n1 ? 1 : ( n2 ? -1 : 0 ) );
+ // ### TQt 3.0: Add a virtual compareItems() method and call that instead
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+/*!
+ Sorts the first \a sz items of the array.
+*/
+
+void TQGArray::sort( uint sz )
+{
+ int numItems = size() / sz;
+ if ( numItems < 2 )
+ return;
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &cmp_item_size ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+
+ cmp_item_size = sz;
+ qsort( shd->data, numItems, sz, cmp_arr );
+}
+
+/*!
+ Binary search; assumes that \a d is a sorted array of size \a sz.
+*/
+
+int TQGArray::bsearch( const char *d, uint sz ) const
+{
+ int numItems = size() / sz;
+ if ( !numItems )
+ return -1;
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &cmp_item_size ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+
+ cmp_item_size = sz;
+ char* r = (char*)::bsearch( d, shd->data, numItems, sz, cmp_arr );
+ if ( !r )
+ return -1;
+ while( (r >= shd->data + sz) && (cmp_arr( r - sz, d ) == 0) )
+ r -= sz; // search to first of equal elements; bsearch is undef
+ return (int)(( r - shd->data ) / sz);
+}
+
+
+/*!
+ \fn char *TQGArray::at( uint index ) const
+
+ Returns a pointer to the byte at offset \a index in the array.
+*/
+
+/*!
+ Expand the array if necessary, and copies (the first part of) its
+ contents from the \a index * \a sz bytes at \a d.
+
+ Returns TRUE if the operation succeeds, FALSE if it runs out of
+ memory.
+
+ \warning This function disregards the reference count mechanism. If
+ other TQGArrays reference the same data as this, all will be changed.
+*/
+
+bool TQGArray::setExpand( uint index, const char *d, uint sz )
+{
+ index *= sz;
+ if ( index >= shd->len ) {
+ if ( !resize( index+sz ) ) // no memory
+ return FALSE;
+ }
+ memcpy( data() + index, d, sz );
+ return TRUE;
+}
+
+
+/*!
+ Prints a warning message if at() or [] is given a bad index.
+*/
+
+void TQGArray::msg_index( uint index )
+{
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQGArray::at: Absolute index %d out of range", index );
+#else
+ TQ_UNUSED( index )
+#endif
+}
+
+
+/*!
+ Returns a new shared array block.
+*/
+
+TQGArray::array_data * TQGArray::newData()
+{
+ return new array_data;
+}
+
+
+/*!
+ Deletes the shared array block \a p.
+*/
+
+void TQGArray::deleteData( array_data *p )
+{
+ delete p;
+}
diff --git a/tqtinterface/qt4/src/tools/tqgarray.h b/tqtinterface/qt4/src/tools/tqgarray.h
new file mode 100644
index 0000000..b581621
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgarray.h
@@ -0,0 +1,134 @@
+/****************************************************************************
+**
+** Definition of TQGArray class
+**
+** Created : 930906
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGARRAY_H
+#define TQGARRAY_H
+
+#ifndef TQT_H
+#include "tqshared.h"
+#endif // TQT_H
+
+
+class TQ_EXPORT TQGArray // generic array
+{
+friend class TQBuffer;
+public:
+ // do not use this, even though this is public
+ // ### make protected or private in TQt 4.0 beta?
+ struct array_data : public TQShared { // shared array
+ array_data():data(0),len(0)
+#ifdef TQT_TQGARRAY_SPEED_OPTIM
+ ,maxl(0)
+#endif
+ {}
+ char *data; // actual array data
+ uint len;
+#ifdef TQT_TQGARRAY_SPEED_OPTIM
+ uint maxl;
+#endif
+ };
+ TQGArray();
+ enum Optimization { MemOptim, SpeedOptim };
+protected:
+ TQGArray( int, int ); // dummy; does not alloc
+ TQGArray( int size ); // allocate 'size' bytes
+ TQGArray( const TQGArray &a ); // shallow copy
+ virtual ~TQGArray();
+
+ TQGArray &operator=( const TQGArray &a ) { return assign( a ); }
+
+ virtual void detach() { duplicate(*this); }
+
+ // ### TQt 4.0: maybe provide two versions of data(), at(), etc.
+ char *data() const { return shd->data; }
+ uint nrefs() const { return shd->count; }
+ uint size() const { return shd->len; }
+ bool isEqual( const TQGArray &a ) const;
+
+ bool resize( uint newsize, Optimization optim );
+ bool resize( uint newsize );
+
+ bool fill( const char *d, int len, uint sz );
+
+ TQGArray &assign( const TQGArray &a );
+ TQGArray &assign( const char *d, uint len );
+ TQGArray &duplicate( const TQGArray &a );
+ TQGArray &duplicate( const char *d, uint len );
+ void store( const char *d, uint len );
+
+ array_data *sharedBlock() const { return shd; }
+ void setSharedBlock( array_data *p ) { shd=(array_data*)p; }
+
+ TQGArray &setRawData( const char *d, uint len );
+ void resetRawData( const char *d, uint len );
+
+ int tqfind( const char *d, uint index, uint sz ) const;
+ int tqcontains( const char *d, uint sz ) const;
+
+ void sort( uint sz );
+ int bsearch( const char *d, uint sz ) const;
+
+ char *at( uint index ) const;
+
+ bool setExpand( uint index, const char *d, uint sz );
+
+protected:
+ virtual array_data *newData();
+ virtual void deleteData( array_data *p );
+
+private:
+ static void msg_index( uint );
+ array_data *shd;
+};
+
+
+inline char *TQGArray::at( uint index ) const
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( index >= size() ) {
+ msg_index( index );
+ index = 0;
+ }
+#endif
+ return &shd->data[index];
+}
+
+
+#endif // TQGARRAY_H
diff --git a/tqtinterface/qt4/src/tools/tqgcache.cpp b/tqtinterface/qt4/src/tools/tqgcache.cpp
new file mode 100644
index 0000000..1d2d3bb
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgcache.cpp
@@ -0,0 +1,866 @@
+/****************************************************************************
+**
+** Implementation of TQGCache and TQGCacheIterator classes
+**
+** Created : 950208
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqgcache.h"
+#include "tqptrlist.h"
+#include "tqdict.h"
+#include "tqstring.h"
+
+/*!
+ \class TQGCache tqgcache.h
+ \reentrant
+ \ingroup shared
+ \ingroup collection
+ \brief The TQGCache class is an internal class for implementing TQCache
+ template classes.
+
+ \internal
+
+ TQGCache is a strictly internal class that acts as a base class for the
+ \link collection.html collection classes\endlink TQCache and TQIntCache.
+*/
+
+
+/*****************************************************************************
+ TQGCacheItem class (internal cache item)
+ *****************************************************************************/
+
+struct TQCacheItem
+{
+ TQCacheItem( void *k, TQPtrCollection::Item d, int c, short p )
+ : priority(p), skipPriority(p), cost(c), key(k), data(d), node(0) {}
+ short priority;
+ short skipPriority;
+ int cost;
+ void *key;
+ TQPtrCollection::Item data;
+ TQLNode *node;
+};
+
+
+/*****************************************************************************
+ TQCList class (internal list of cache items)
+ *****************************************************************************/
+
+class TQCList : private TQPtrList<TQCacheItem>
+{
+friend class TQGCacheIterator;
+friend class TQCListIt;
+public:
+ TQCList() {}
+ ~TQCList();
+
+ void insert( TQCacheItem * ); // insert according to priority
+ void insert( int, TQCacheItem * );
+ void take( TQCacheItem * );
+ void reference( TQCacheItem * );
+
+ void setAutoDelete( bool del ) { TQPtrCollection::setAutoDelete(del); }
+
+ bool removeFirst() { return TQPtrList<TQCacheItem>::removeFirst(); }
+ bool removeLast() { return TQPtrList<TQCacheItem>::removeLast(); }
+
+ TQCacheItem *first() { return TQPtrList<TQCacheItem>::first(); }
+ TQCacheItem *last() { return TQPtrList<TQCacheItem>::last(); }
+ TQCacheItem *prev() { return TQPtrList<TQCacheItem>::prev(); }
+ TQCacheItem *next() { return TQPtrList<TQCacheItem>::next(); }
+
+#if defined(TQT_DEBUG)
+ int inserts; // variables for statistics
+ int insertCosts;
+ int insertMisses;
+ int tqfinds;
+ int hits;
+ int hitCosts;
+ int dumps;
+ int dumpCosts;
+#endif
+};
+
+
+TQCList::~TQCList()
+{
+#if defined(TQT_DEBUG)
+ TQ_ASSERT( count() == 0 );
+#endif
+}
+
+
+void TQCList::insert( TQCacheItem *ci )
+{
+ TQCacheItem *item = first();
+ while( item && item->skipPriority > ci->priority ) {
+ item->skipPriority--;
+ item = next();
+ }
+ if ( item )
+ TQPtrList<TQCacheItem>::insert( at(), ci );
+ else
+ append( ci );
+#if defined(TQT_DEBUG)
+ TQ_ASSERT( ci->node == 0 );
+#endif
+ ci->node = currentNode();
+}
+
+inline void TQCList::insert( int i, TQCacheItem *ci )
+{
+ TQPtrList<TQCacheItem>::insert( i, ci );
+#if defined(TQT_DEBUG)
+ TQ_ASSERT( ci->node == 0 );
+#endif
+ ci->node = currentNode();
+}
+
+
+void TQCList::take( TQCacheItem *ci )
+{
+ if ( ci ) {
+#if defined(TQT_DEBUG)
+ TQ_ASSERT( ci->node != 0 );
+#endif
+ takeNode( ci->node );
+ ci->node = 0;
+ }
+}
+
+
+inline void TQCList::reference( TQCacheItem *ci )
+{
+#if defined(TQT_DEBUG)
+ TQ_ASSERT( ci != 0 && ci->node != 0 );
+#endif
+ ci->skipPriority = ci->priority;
+ relinkNode( ci->node ); // relink as first item
+}
+
+
+class TQCListIt: public TQPtrListIterator<TQCacheItem>
+{
+public:
+ TQCListIt( const TQCList *p ): TQPtrListIterator<TQCacheItem>( *p ) {}
+ TQCListIt( const TQCListIt *p ): TQPtrListIterator<TQCacheItem>( *p ) {}
+};
+
+
+/*****************************************************************************
+ TQCDict class (internal dictionary of cache items)
+ *****************************************************************************/
+
+//
+// Since we need to decide if the dictionary should use an int or const
+// char * key (the "bool trivial" argument in the constructor below)
+// we cannot use the macro/template dict, but inherit directly from TQGDict.
+//
+
+class TQCDict : public TQGDict
+{
+public:
+ TQCDict( uint size, uint kt, bool caseSensitive, bool copyKeys )
+ : TQGDict( size, (KeyType)kt, caseSensitive, copyKeys ) {}
+ ~TQCDict();
+
+ void clear() { TQGDict::clear(); }
+
+ TQCacheItem *tqfind_string(const TQString &key) const
+ { return (TQCacheItem*)((TQCDict*)this)->look_string(key, 0, 0); }
+ TQCacheItem *tqfind_ascii(const char *key) const
+ { return (TQCacheItem*)((TQCDict*)this)->look_ascii(key, 0, 0); }
+ TQCacheItem *tqfind_int(long key) const
+ { return (TQCacheItem*)((TQCDict*)this)->look_int(key, 0, 0); }
+
+ TQCacheItem *take_string(const TQString &key)
+ { return (TQCacheItem*)TQGDict::take_string(key); }
+ TQCacheItem *take_ascii(const char *key)
+ { return (TQCacheItem*)TQGDict::take_ascii(key); }
+ TQCacheItem *take_int(long key)
+ { return (TQCacheItem*)TQGDict::take_int(key); }
+
+ bool insert_string( const TQString &key, const TQCacheItem *ci )
+ { return TQGDict::look_string(key,(Item)ci,1)!=0;}
+ bool insert_ascii( const char *key, const TQCacheItem *ci )
+ { return TQGDict::look_ascii(key,(Item)ci,1)!=0;}
+ bool insert_int( long key, const TQCacheItem *ci )
+ { return TQGDict::look_int(key,(Item)ci,1)!=0;}
+
+ bool remove_string( TQCacheItem *item )
+ { return TQGDict::remove_string(*((TQString*)(item->key)),item); }
+ bool remove_ascii( TQCacheItem *item )
+ { return TQGDict::remove_ascii((const char *)item->key,item); }
+ bool remove_int( TQCacheItem *item )
+ { return TQGDict::remove_int((long)item->key,item);}
+
+ void statistics() { TQGDict::statistics(); }
+
+private:
+ void deleteItem( void *item )
+ { if ( del_item ) { TQCacheItem *d = (TQCacheItem*)item; delete d; } }
+};
+
+inline TQCDict::~TQCDict()
+{
+ clear();
+}
+
+/*****************************************************************************
+ TQGDict member functions
+ *****************************************************************************/
+
+/*!
+ Constructs a cache.
+ The maximum cost of the cache is given by \a maxCost and the size by \a
+ size. The key type is \a kt which may be \c StringKey, \c AsciiKey,
+ \c IntKey or \c PtrKey. The case-sensitivity of lookups is set with
+ \a caseSensitive. Keys are copied if \a copyKeys is TRUE.
+*/
+
+TQGCache::TQGCache( int maxCost, uint size, KeyType kt, bool caseSensitive,
+ bool copyKeys )
+{
+ keytype = kt;
+ lruList = new TQCList;
+ TQ_CHECK_PTR( lruList );
+ lruList->setAutoDelete( TRUE );
+ copyk = ((keytype == AsciiKey) && copyKeys);
+ dict = new TQCDict( size, kt, caseSensitive, FALSE );
+ TQ_CHECK_PTR( dict );
+ mCost = maxCost;
+ tCost = 0;
+#if defined(TQT_DEBUG)
+ lruList->inserts = 0;
+ lruList->insertCosts = 0;
+ lruList->insertMisses = 0;
+ lruList->tqfinds = 0;
+ lruList->hits = 0;
+ lruList->hitCosts = 0;
+ lruList->dumps = 0;
+ lruList->dumpCosts = 0;
+#endif
+}
+
+/*!
+ Cannot copy a cache.
+*/
+
+TQGCache::TQGCache( const TQGCache & )
+ : TQPtrCollection()
+{
+#if defined(TQT_CHECK_NULL)
+ qFatal( "TQGCache::TQGCache(TQGCache &): Cannot copy a cache" );
+#endif
+}
+
+/*!
+ Removes all items from the cache and destroys it.
+*/
+
+TQGCache::~TQGCache()
+{
+ clear();
+ delete dict;
+ delete lruList;
+}
+
+/*!
+ Cannot assign a cache.
+*/
+
+TQGCache &TQGCache::operator=( const TQGCache & )
+{
+#if defined(TQT_CHECK_NULL)
+ qFatal( "TQGCache::operator=: Cannot copy a cache" );
+#endif
+ return *this;
+}
+
+
+/*!
+ Returns the number of items in the cache.
+*/
+
+uint TQGCache::count() const
+{
+ return dict->count();
+}
+
+/*!
+ Returns the size of the hash array.
+*/
+
+uint TQGCache::size() const
+{
+ return dict->size();
+}
+
+/*!
+ \fn int TQGCache::maxCost() const
+
+ Returns the maximum cache cost.
+*/
+
+/*!
+ \fn int TQGCache::totalCost() const
+
+ Returns the total cache cost.
+*/
+
+/*!
+ Sets the maximum cache cost to \a maxCost.
+*/
+
+void TQGCache::setMaxCost( int maxCost )
+{
+ if ( maxCost < tCost ) {
+ if ( !makeRoomFor(tCost - maxCost) ) // remove excess cost
+ return;
+ }
+ mCost = maxCost;
+}
+
+
+/*!
+ Inserts an item with data \a data into the cache using key \a key.
+ The item has cost \a cost and priority \a priority.
+
+ \warning If this function returns FALSE, you must delete \a data
+ yourself. Additionally, be very careful about using \a data after
+ calling this function, as any other insertions into the cache, from
+ anywhere in the application, or within TQt itself, could cause the
+ data to be discarded from the cache, and the pointer to become
+ invalid.
+*/
+
+bool TQGCache::insert_string( const TQString &key, TQPtrCollection::Item data,
+ int cost, int priority)
+{
+ if ( tCost + cost > mCost ) {
+ if ( !makeRoomFor(tCost + cost - mCost, priority) ) {
+#if defined(TQT_DEBUG)
+ lruList->insertMisses++;
+#endif
+ return FALSE;
+ }
+ }
+#if defined(TQT_DEBUG)
+ TQ_ASSERT( keytype == StringKey );
+ lruList->inserts++;
+ lruList->insertCosts += cost;
+#endif
+ if ( priority < -32768 )
+ priority = -32768;
+ else if ( priority > 32767 )
+ priority = 32677;
+ TQCacheItem *ci = new TQCacheItem( new TQString(key), newItem(data),
+ cost, (short)priority );
+ TQ_CHECK_PTR( ci );
+ lruList->insert( 0, ci );
+ dict->insert_string( key, ci );
+ tCost += cost;
+ return TRUE;
+}
+
+bool TQGCache::insert_other( const char *key, TQPtrCollection::Item data,
+ int cost, int priority)
+{
+ if ( tCost + cost > mCost ) {
+ if ( !makeRoomFor(tCost + cost - mCost, priority) ) {
+#if defined(TQT_DEBUG)
+ lruList->insertMisses++;
+#endif
+ return FALSE;
+ }
+ }
+#if defined(TQT_DEBUG)
+ TQ_ASSERT( keytype != StringKey );
+ lruList->inserts++;
+ lruList->insertCosts += cost;
+#endif
+ if ( keytype == AsciiKey && copyk )
+ key = qstrdup( key );
+ if ( priority < -32768 )
+ priority = -32768;
+ else if ( priority > 32767 )
+ priority = 32677;
+ TQCacheItem *ci = new TQCacheItem( (void*)key, newItem(data), cost,
+ (short)priority );
+ TQ_CHECK_PTR( ci );
+ lruList->insert( 0, ci );
+ if ( keytype == AsciiKey )
+ dict->insert_ascii( key, ci );
+ else
+ dict->insert_int( (long)key, ci );
+ tCost += cost;
+ return TRUE;
+}
+
+
+/*!
+ Removes the item with key \a key from the cache. Returns TRUE if the
+ item was removed; otherwise returns FALSE.
+*/
+
+bool TQGCache::remove_string( const TQString &key )
+{
+ Item d = take_string( key );
+ if ( d )
+ deleteItem( d );
+ return d != 0;
+}
+
+bool TQGCache::remove_other( const char *key )
+{
+ Item d = take_other( key );
+ if ( d )
+ deleteItem( d );
+ return d != 0;
+}
+
+
+/*!
+ Takes the item with key \a key out of the cache. The item is not
+ deleted. If no item has this \a key 0 is returned.
+*/
+
+TQPtrCollection::Item TQGCache::take_string( const TQString &key )
+{
+ TQCacheItem *ci = dict->take_string( key ); // take from dict
+ Item d;
+ if ( ci ) {
+ d = ci->data;
+ tCost -= ci->cost;
+ lruList->take( ci ); // take from list
+ delete (TQString*)ci->key;
+ delete ci;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+/*!
+ Takes the item with key \a key out of the cache. The item is not
+ deleted. If no item has this \a key 0 is returned.
+*/
+
+TQPtrCollection::Item TQGCache::take_other( const char *key )
+{
+ TQCacheItem *ci;
+ if ( keytype == AsciiKey )
+ ci = dict->take_ascii( key );
+ else
+ ci = dict->take_int( (long)key );
+ Item d;
+ if ( ci ) {
+ d = ci->data;
+ tCost -= ci->cost;
+ lruList->take( ci ); // take from list
+ if ( copyk )
+ delete [] (char *)ci->key;
+ delete ci;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+
+/*!
+ Clears the cache.
+*/
+
+void TQGCache::clear()
+{
+ TQCacheItem *ci;
+ while ( (ci = lruList->first()) ) {
+ switch ( keytype ) {
+ case StringKey:
+ dict->remove_string( ci );
+ delete (TQString*)ci->key;
+ break;
+ case AsciiKey:
+ dict->remove_ascii( ci );
+ if ( copyk )
+ delete [] (char*)ci->key;
+ break;
+ case IntKey:
+ dict->remove_int( ci );
+ break;
+ case PtrKey: // unused
+ break;
+ }
+ deleteItem( ci->data ); // delete data
+ lruList->removeFirst(); // remove from list
+ }
+ tCost = 0;
+}
+
+
+/*!
+ Finds an item for \a key in the cache and adds a reference if \a ref is TRUE.
+*/
+
+TQPtrCollection::Item TQGCache::tqfind_string( const TQString &key, bool ref ) const
+{
+ TQCacheItem *ci = dict->tqfind_string( key );
+#if defined(TQT_DEBUG)
+ lruList->tqfinds++;
+#endif
+ if ( ci ) {
+#if defined(TQT_DEBUG)
+ lruList->hits++;
+ lruList->hitCosts += ci->cost;
+#endif
+ if ( ref )
+ lruList->reference( ci );
+ return ci->data;
+ }
+ return 0;
+}
+
+
+/*!
+ Finds an item for \a key in the cache and adds a reference if \a ref is TRUE.
+*/
+
+TQPtrCollection::Item TQGCache::tqfind_other( const char *key, bool ref ) const
+{
+ TQCacheItem *ci = keytype == AsciiKey ? dict->tqfind_ascii(key)
+ : dict->tqfind_int((long)key);
+#if defined(TQT_DEBUG)
+ lruList->tqfinds++;
+#endif
+ if ( ci ) {
+#if defined(TQT_DEBUG)
+ lruList->hits++;
+ lruList->hitCosts += ci->cost;
+#endif
+ if ( ref )
+ lruList->reference( ci );
+ return ci->data;
+ }
+ return 0;
+}
+
+
+/*!
+ Allocates cache space for one or more items.
+*/
+
+bool TQGCache::makeRoomFor( int cost, int priority )
+{
+ if ( cost > mCost ) // cannot make room for more
+ return FALSE; // than maximum cost
+ if ( priority == -1 )
+ priority = 32767;
+ register TQCacheItem *ci = lruList->last();
+ int cntCost = 0;
+ int dumps = 0; // number of items to dump
+ while ( cntCost < cost && ci && ci->skipPriority <= priority ) {
+ cntCost += ci->cost;
+ ci = lruList->prev();
+ dumps++;
+ }
+ if ( cntCost < cost ) // can enough cost be dumped?
+ return FALSE; // no
+#if defined(TQT_DEBUG)
+ TQ_ASSERT( dumps > 0 );
+#endif
+ while ( dumps-- ) {
+ ci = lruList->last();
+#if defined(TQT_DEBUG)
+ lruList->dumps++;
+ lruList->dumpCosts += ci->cost;
+#endif
+ switch ( keytype ) {
+ case StringKey:
+ dict->remove_string( ci );
+ delete (TQString*)ci->key;
+ break;
+ case AsciiKey:
+ dict->remove_ascii( ci );
+ if ( copyk )
+ delete [] (char *)ci->key;
+ break;
+ case IntKey:
+ dict->remove_int( ci );
+ break;
+ case PtrKey: // unused
+ break;
+ }
+ deleteItem( ci->data ); // delete data
+ lruList->removeLast(); // remove from list
+ }
+ tCost -= cntCost;
+ return TRUE;
+}
+
+
+/*!
+ Outputs debug statistics.
+*/
+
+void TQGCache::statistics() const
+{
+#if defined(TQT_DEBUG)
+ TQString line;
+ line.fill( '*', 80 );
+ qDebug( line.ascii() );
+ qDebug( "CACHE STATISTICS:" );
+ qDebug( "cache tqcontains %d item%s, with a total cost of %d",
+ count(), count() != 1 ? "s" : "", tCost );
+ qDebug( "maximum cost is %d, cache is %d%% full.",
+ mCost, (200*tCost + mCost) / (mCost*2) );
+ qDebug( "tqfind() has been called %d time%s",
+ lruList->tqfinds, lruList->tqfinds != 1 ? "s" : "" );
+ qDebug( "%d of these were hits, items found had a total cost of %d.",
+ lruList->hits,lruList->hitCosts );
+ qDebug( "%d item%s %s been inserted with a total cost of %d.",
+ lruList->inserts,lruList->inserts != 1 ? "s" : "",
+ lruList->inserts != 1 ? "have" : "has", lruList->insertCosts );
+ qDebug( "%d item%s %s too large or had too low priority to be inserted.",
+ lruList->insertMisses, lruList->insertMisses != 1 ? "s" : "",
+ lruList->insertMisses != 1 ? "were" : "was" );
+ qDebug( "%d item%s %s been thrown away with a total cost of %d.",
+ lruList->dumps, lruList->dumps != 1 ? "s" : "",
+ lruList->dumps != 1 ? "have" : "has", lruList->dumpCosts );
+ qDebug( "Statistics from internal dictionary class:" );
+ dict->statistics();
+ qDebug( line.ascii() );
+#endif
+}
+
+
+/*****************************************************************************
+ TQGCacheIterator member functions
+ *****************************************************************************/
+
+/*!
+ \class TQGCacheIterator tqgcache.h
+ \reentrant
+ \ingroup shared
+ \ingroup collection
+ \brief The TQGCacheIterator class is an internal class for implementing TQCacheIterator and
+ TQIntCacheIterator.
+
+ \internal
+
+ TQGCacheIterator is a strictly internal class that does the heavy work for
+ TQCacheIterator and TQIntCacheIterator.
+*/
+
+/*!
+ Constructs an iterator that operates on the cache \a c.
+*/
+
+TQGCacheIterator::TQGCacheIterator( const TQGCache &c )
+{
+ it = new TQCListIt( c.lruList );
+#if defined(TQT_DEBUG)
+ TQ_ASSERT( it != 0 );
+#endif
+}
+
+/*!
+ Constructs an iterator that operates on the same cache as \a ci.
+*/
+
+TQGCacheIterator::TQGCacheIterator( const TQGCacheIterator &ci )
+{
+ it = new TQCListIt( ci.it );
+#if defined(TQT_DEBUG)
+ TQ_ASSERT( it != 0 );
+#endif
+}
+
+/*!
+ Destroys the iterator.
+*/
+
+TQGCacheIterator::~TQGCacheIterator()
+{
+ delete it;
+}
+
+/*!
+ Assigns the iterator \a ci to this cache iterator.
+*/
+
+TQGCacheIterator &TQGCacheIterator::operator=( const TQGCacheIterator &ci )
+{
+ *it = *ci.it;
+ return *this;
+}
+
+/*!
+ Returns the number of items in the cache.
+*/
+
+uint TQGCacheIterator::count() const
+{
+ return it->count();
+}
+
+/*!
+ Returns TRUE if the iterator points to the first item.
+*/
+
+bool TQGCacheIterator::atFirst() const
+{
+ return it->atFirst();
+}
+
+/*!
+ Returns TRUE if the iterator points to the last item.
+*/
+
+bool TQGCacheIterator::atLast() const
+{
+ return it->atLast();
+}
+
+/*!
+ Sets the list iterator to point to the first item in the cache.
+*/
+
+TQPtrCollection::Item TQGCacheIterator::toFirst()
+{
+ TQCacheItem *item = it->toFirst();
+ return item ? item->data : 0;
+}
+
+/*!
+ Sets the list iterator to point to the last item in the cache.
+*/
+
+TQPtrCollection::Item TQGCacheIterator::toLast()
+{
+ TQCacheItem *item = it->toLast();
+ return item ? item->data : 0;
+}
+
+/*!
+ Returns the current item.
+*/
+
+TQPtrCollection::Item TQGCacheIterator::get() const
+{
+ TQCacheItem *item = it->current();
+ return item ? item->data : 0;
+}
+
+/*!
+ Returns the key of the current item.
+*/
+
+TQString TQGCacheIterator::getKeyString() const
+{
+ TQCacheItem *item = it->current();
+ return item ? *((TQString*)item->key) : TQString::null;
+}
+
+/*!
+ Returns the key of the current item, as a \0-terminated C string.
+*/
+
+const char *TQGCacheIterator::getKeyAscii() const
+{
+ TQCacheItem *item = it->current();
+ return item ? (const char *)item->key : 0;
+}
+
+/*!
+ Returns the key of the current item, as a long.
+*/
+
+long TQGCacheIterator::getKeyInt() const
+{
+ TQCacheItem *item = it->current();
+ return item ? (long)item->key : 0;
+}
+
+/*!
+ Moves to the next item (postfix).
+*/
+
+TQPtrCollection::Item TQGCacheIterator::operator()()
+{
+ TQCacheItem *item = it->operator()();
+ return item ? item->data : 0;
+}
+
+/*!
+ Moves to the next item (prefix).
+*/
+
+TQPtrCollection::Item TQGCacheIterator::operator++()
+{
+ TQCacheItem *item = it->operator++();
+ return item ? item->data : 0;
+}
+
+/*!
+ Moves \a jump positions forward.
+*/
+
+TQPtrCollection::Item TQGCacheIterator::operator+=( uint jump )
+{
+ TQCacheItem *item = it->operator+=(jump);
+ return item ? item->data : 0;
+}
+
+/*!
+ Moves to the previous item (prefix).
+*/
+
+TQPtrCollection::Item TQGCacheIterator::operator--()
+{
+ TQCacheItem *item = it->operator--();
+ return item ? item->data : 0;
+}
+
+/*!
+ Moves \a jump positions backward.
+*/
+
+TQPtrCollection::Item TQGCacheIterator::operator-=( uint jump )
+{
+ TQCacheItem *item = it->operator-=(jump);
+ return item ? item->data : 0;
+}
diff --git a/tqtinterface/qt4/src/tools/tqgcache.h b/tqtinterface/qt4/src/tools/tqgcache.h
new file mode 100644
index 0000000..7d54656
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgcache.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Definition of TQGCache and TQGCacheIterator classes
+**
+** Created : 950208
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGCACHE_H
+#define TQGCACHE_H
+
+#ifndef TQT_H
+#include "tqptrcollection.h"
+#include "tqglist.h"
+#include "tqgdict.h"
+#endif // TQT_H
+
+
+class TQCList; // internal classes
+class TQCListIt;
+class TQCDict;
+
+
+class TQ_EXPORT TQGCache : public TQPtrCollection // generic LRU cache
+{
+friend class TQGCacheIterator;
+protected:
+ enum KeyType { StringKey, AsciiKey, IntKey, PtrKey };
+ // identical to TQGDict's, but PtrKey is not used at the moment
+
+ TQGCache( int maxCost, uint size, KeyType kt, bool caseSensitive,
+ bool copyKeys );
+ TQGCache( const TQGCache & ); // not allowed, calls fatal()
+ ~TQGCache();
+ TQGCache &operator=( const TQGCache & ); // not allowed, calls fatal()
+
+ uint count() const;
+ uint size() const;
+ int maxCost() const { return mCost; }
+ int totalCost() const { return tCost; }
+ void setMaxCost( int maxCost );
+ void clear();
+
+ bool insert_string( const TQString &key, TQPtrCollection::Item,
+ int cost, int priority );
+ bool insert_other( const char *key, TQPtrCollection::Item,
+ int cost, int priority );
+ bool remove_string( const TQString &key );
+ bool remove_other( const char *key );
+ TQPtrCollection::Item take_string( const TQString &key );
+ TQPtrCollection::Item take_other( const char *key );
+
+ TQPtrCollection::Item tqfind_string( const TQString &key, bool ref=TRUE ) const;
+ TQPtrCollection::Item tqfind_other( const char *key, bool ref=TRUE ) const;
+
+ void statistics() const;
+
+private:
+ bool makeRoomFor( int cost, int priority = -1 );
+ KeyType keytype;
+ TQCList *lruList;
+ TQCDict *dict;
+ int mCost;
+ int tCost;
+ bool copyk;
+};
+
+
+class TQ_EXPORT TQGCacheIterator // generic cache iterator
+{
+protected:
+ TQGCacheIterator( const TQGCache & );
+ TQGCacheIterator( const TQGCacheIterator & );
+ ~TQGCacheIterator();
+ TQGCacheIterator &operator=( const TQGCacheIterator & );
+
+ uint count() const;
+ bool atFirst() const;
+ bool atLast() const;
+ TQPtrCollection::Item toFirst();
+ TQPtrCollection::Item toLast();
+
+ TQPtrCollection::Item get() const;
+ TQString getKeyString() const;
+ const char *getKeyAscii() const;
+ long getKeyInt() const;
+
+ TQPtrCollection::Item operator()();
+ TQPtrCollection::Item operator++();
+ TQPtrCollection::Item operator+=( uint );
+ TQPtrCollection::Item operator--();
+ TQPtrCollection::Item operator-=( uint );
+
+protected:
+ TQCListIt *it; // iterator on cache list
+};
+
+
+#endif // TQGCACHE_H
diff --git a/tqtinterface/qt4/src/tools/tqgdict.cpp b/tqtinterface/qt4/src/tools/tqgdict.cpp
new file mode 100644
index 0000000..c4c21d9
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgdict.cpp
@@ -0,0 +1,1151 @@
+/****************************************************************************
+**
+** Implementation of TQGDict and TQGDictIterator classes
+**
+** Created : 920529
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqgdict.h"
+#include "tqptrlist.h"
+#include "tqstring.h"
+#include "tqdatastream.h"
+#include <ctype.h>
+
+/*!
+ \class TQGDict
+ \reentrant
+ \ingroup collection
+ \brief The TQGDict class is an internal class for implementing TQDict template classes.
+
+ \internal
+
+ TQGDict is a strictly internal class that acts as a base class for the
+ \link collection.html collection classes\endlink TQDict and TQIntDict.
+
+ TQGDict has some virtual functions that can be reimplemented to customize
+ the subclasses.
+ \list
+ \i read() reads a collection/dictionary item from a TQDataStream.
+ \i write() writes a collection/dictionary item to a TQDataStream.
+ \endlist
+ Normally, you do not have to reimplement any of these functions.
+*/
+
+static const int op_tqfind = 0;
+static const int op_insert = 1;
+static const int op_tqreplace = 2;
+
+
+class TQGDItList : public TQPtrList<TQGDictIterator>
+{
+public:
+ TQGDItList() : TQPtrList<TQGDictIterator>() {}
+ TQGDItList( const TQGDItList &list ) : TQPtrList<TQGDictIterator>(list) {}
+ ~TQGDItList() { clear(); }
+ TQGDItList &operator=(const TQGDItList &list)
+ { return (TQGDItList&)TQPtrList<TQGDictIterator>::operator=(list); }
+};
+
+
+/*****************************************************************************
+ Default implementation of special and virtual functions
+ *****************************************************************************/
+
+/*!
+ Returns the hash key for \a key, when key is a string.
+*/
+
+int TQGDict::hashKeyString( const TQString &key )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( key.isNull() )
+ qWarning( "TQGDict::hashKeyString: Invalid null key" );
+#endif
+ int i;
+ register uint h=0;
+ uint g;
+ const TQChar *p = key.tqunicode();
+ if ( cases ) { // case sensitive
+ for ( i=0; i<(int)key.length(); i++ ) {
+ h = (h<<4) + p[i].cell();
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ } else { // case insensitive
+ for ( i=0; i<(int)key.length(); i++ ) {
+ h = (h<<4) + p[i].lower().cell();
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ }
+ int index = h;
+ if ( index < 0 ) // adjust index to table size
+ index = -index;
+ return index;
+}
+
+/*!
+ Returns the hash key for \a key, which is a C string.
+*/
+
+int TQGDict::hashKeyAscii( const char *key )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( key == 0 )
+ qWarning( "TQGDict::hashAsciiKey: Invalid null key" );
+#endif
+ register const char *k = key;
+ register uint h=0;
+ uint g;
+ if ( cases ) { // case sensitive
+ while ( *k ) {
+ h = (h<<4) + *k++;
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ } else { // case insensitive
+ while ( *k ) {
+ h = (h<<4) + tolower((uchar) *k);
+ if ( (g = h & 0xf0000000) )
+ h ^= g >> 24;
+ h &= ~g;
+ k++;
+ }
+ }
+ int index = h;
+ if ( index < 0 ) // adjust index to table size
+ index = -index;
+ return index;
+}
+
+#ifndef TQT_NO_DATASTREAM
+
+/*!
+ \overload
+ Reads a collection/dictionary item from the stream \a s and returns a
+ reference to the stream.
+
+ The default implementation sets \a item to 0.
+
+ \sa write()
+*/
+
+TQDataStream& TQGDict::read( TQDataStream &s, TQPtrCollection::Item &item )
+{
+ item = 0;
+ return s;
+}
+
+/*!
+ \overload
+ Writes a collection/dictionary item to the stream \a s and returns a
+ reference to the stream.
+
+ \sa read()
+*/
+
+TQDataStream& TQGDict::write( TQDataStream &s, TQPtrCollection::Item ) const
+{
+ return s;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*****************************************************************************
+ TQGDict member functions
+ *****************************************************************************/
+
+/*!
+ Constructs a dictionary.
+
+ \a len is the initial size of the dictionary.
+ The key type is \a kt which may be \c StringKey, \c AsciiKey,
+ \c IntKey or \c PtrKey. The case-sensitivity of lookups is set with
+ \a caseSensitive. Keys are copied if \a copyKeys is TRUE.
+*/
+
+TQGDict::TQGDict( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
+{
+ init( len, kt, caseSensitive, copyKeys );
+}
+
+
+void TQGDict::init( uint len, KeyType kt, bool caseSensitive, bool copyKeys )
+{
+ vlen = len ? len : 17;
+ vec = new TQBaseBucket *[ vlen ];
+
+ TQ_CHECK_PTR( vec );
+ memset( (char*)vec, 0, vlen*sizeof(TQBaseBucket*) );
+ numItems = 0;
+ iterators = 0;
+ // The caseSensitive and copyKey options don't make sense for
+ // all dict types.
+ switch ( (keytype = (uint)kt) ) {
+ case StringKey:
+ cases = caseSensitive;
+ copyk = FALSE;
+ break;
+ case AsciiKey:
+ cases = caseSensitive;
+ copyk = copyKeys;
+ break;
+ default:
+ cases = FALSE;
+ copyk = FALSE;
+ break;
+ }
+}
+
+
+/*!
+ Constructs a copy of \a dict.
+*/
+
+TQGDict::TQGDict( const TQGDict & dict )
+ : TQPtrCollection( dict )
+{
+ init( dict.vlen, (KeyType)dict.keytype, dict.cases, dict.copyk );
+ TQGDictIterator it( dict );
+ while ( it.get() ) { // copy from other dict
+ switch ( keytype ) {
+ case StringKey:
+ look_string( it.getKeyString(), it.get(), op_insert );
+ break;
+ case AsciiKey:
+ look_ascii( it.getKeyAscii(), it.get(), op_insert );
+ break;
+ case IntKey:
+ look_int( it.getKeyInt(), it.get(), op_insert );
+ break;
+ case PtrKey:
+ look_ptr( it.getKeyPtr(), it.get(), op_insert );
+ break;
+ }
+ ++it;
+ }
+}
+
+
+/*!
+ Removes all items from the dictionary and destroys it.
+*/
+
+TQGDict::~TQGDict()
+{
+ clear(); // delete everything
+ delete [] vec;
+ if ( !iterators ) // no iterators for this dict
+ return;
+ TQGDictIterator *i = iterators->first();
+ while ( i ) { // notify all iterators that
+ i->dict = 0; // this dict is deleted
+ i = iterators->next();
+ }
+ delete iterators;
+}
+
+
+/*!
+ Assigns \a dict to this dictionary.
+*/
+
+TQGDict &TQGDict::operator=( const TQGDict &dict )
+{
+ if ( &dict == this )
+ return *this;
+ clear();
+ TQGDictIterator it( dict );
+ while ( it.get() ) { // copy from other dict
+ switch ( keytype ) {
+ case StringKey:
+ look_string( it.getKeyString(), it.get(), op_insert );
+ break;
+ case AsciiKey:
+ look_ascii( it.getKeyAscii(), it.get(), op_insert );
+ break;
+ case IntKey:
+ look_int( it.getKeyInt(), it.get(), op_insert );
+ break;
+ case PtrKey:
+ look_ptr( it.getKeyPtr(), it.get(), op_insert );
+ break;
+ }
+ ++it;
+ }
+ return *this;
+}
+
+/*!
+ \fn uint TQGDict::count() const
+
+ Returns the number of items in the dictionary.
+*/
+
+/*!
+ \fn uint TQGDict::size() const
+
+ Returns the size of the hash array.
+*/
+
+/*!
+ The do-it-all function; \a op is one of op_tqfind, op_insert, op_tqreplace.
+ The key is \a key and the item is \a d.
+*/
+
+TQPtrCollection::Item TQGDict::look_string( const TQString &key, TQPtrCollection::Item d,
+ int op )
+{
+ TQStringBucket *n = 0;
+ int index = hashKeyString(key) % vlen;
+ if ( op == op_tqfind ) { // tqfind
+ if ( cases ) {
+ n = (TQStringBucket*)vec[index];
+ while( n != 0 ) {
+ if ( key == n->getKey() )
+ return n->getData(); // item found
+ n = (TQStringBucket*)n->getNext();
+ }
+ } else {
+ TQString k = key.lower();
+ n = (TQStringBucket*)vec[index];
+ while( n != 0 ) {
+ if ( k == n->getKey().lower() )
+ return n->getData(); // item found
+ n = (TQStringBucket*)n->getNext();
+ }
+ }
+ return 0; // not found
+ }
+ if ( op == op_tqreplace ) { // tqreplace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_string( key );
+ }
+ // op_insert or op_tqreplace
+ n = new TQStringBucket(key,newItem(d),vec[index]);
+ TQ_CHECK_PTR( n );
+#if defined(TQT_CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "TQDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+TQPtrCollection::Item TQGDict::look_ascii( const char *key, TQPtrCollection::Item d, int op )
+{
+ TQAsciiBucket *n;
+ int index = hashKeyAscii(key) % vlen;
+ if ( op == op_tqfind ) { // tqfind
+ if ( cases ) {
+ for ( n=(TQAsciiBucket*)vec[index]; n;
+ n=(TQAsciiBucket*)n->getNext() ) {
+ if ( qstrcmp(n->getKey(),key) == 0 )
+ return n->getData(); // item found
+ }
+ } else {
+ for ( n=(TQAsciiBucket*)vec[index]; n;
+ n=(TQAsciiBucket*)n->getNext() ) {
+ if ( qstricmp(n->getKey(),key) == 0 )
+ return n->getData(); // item found
+ }
+ }
+ return 0; // not found
+ }
+ if ( op == op_tqreplace ) { // tqreplace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_ascii( key );
+ }
+ // op_insert or op_tqreplace
+ n = new TQAsciiBucket(copyk ? qstrdup(key) : key,newItem(d),vec[index]);
+ TQ_CHECK_PTR( n );
+#if defined(TQT_CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "TQAsciiDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+TQPtrCollection::Item TQGDict::look_int( long key, TQPtrCollection::Item d, int op )
+{
+ TQIntBucket *n;
+ int index = (int)((ulong)key % vlen); // simple hash
+ if ( op == op_tqfind ) { // tqfind
+ for ( n=(TQIntBucket*)vec[index]; n;
+ n=(TQIntBucket*)n->getNext() ) {
+ if ( n->getKey() == key )
+ return n->getData(); // item found
+ }
+ return 0; // not found
+ }
+ if ( op == op_tqreplace ) { // tqreplace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_int( key );
+ }
+ // op_insert or op_tqreplace
+ n = new TQIntBucket(key,newItem(d),vec[index]);
+ TQ_CHECK_PTR( n );
+#if defined(TQT_CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "TQIntDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+TQPtrCollection::Item TQGDict::look_ptr( void *key, TQPtrCollection::Item d, int op )
+{
+ TQPtrBucket *n;
+ int index = (int)((ulong)key % vlen); // simple hash
+ if ( op == op_tqfind ) { // tqfind
+ for ( n=(TQPtrBucket*)vec[index]; n;
+ n=(TQPtrBucket*)n->getNext() ) {
+ if ( n->getKey() == key )
+ return n->getData(); // item found
+ }
+ return 0; // not found
+ }
+ if ( op == op_tqreplace ) { // tqreplace
+ if ( vec[index] != 0 ) // maybe something there
+ remove_ptr( key );
+ }
+ // op_insert or op_tqreplace
+ n = new TQPtrBucket(key,newItem(d),vec[index]);
+ TQ_CHECK_PTR( n );
+#if defined(TQT_CHECK_NULL)
+ if ( n->getData() == 0 )
+ qWarning( "TQPtrDict: Cannot insert null item" );
+#endif
+ vec[index] = n;
+ numItems++;
+ return n->getData();
+}
+
+
+/*!
+ Changes the size of the hashtable to \a newsize.
+ The contents of the dictionary are preserved,
+ but all iterators on the dictionary become invalid.
+*/
+void TQGDict::resize( uint newsize )
+{
+ // Save old information
+ TQBaseBucket **old_vec = vec;
+ uint old_vlen = vlen;
+ bool old_copyk = copyk;
+
+ vec = new TQBaseBucket *[vlen = newsize];
+ TQ_CHECK_PTR( vec );
+ memset( (char*)vec, 0, vlen*sizeof(TQBaseBucket*) );
+ numItems = 0;
+ copyk = FALSE;
+
+ // Reinsert every item from vec, deleting vec as we go
+ for ( uint index = 0; index < old_vlen; index++ ) {
+ switch ( keytype ) {
+ case StringKey:
+ {
+ TQStringBucket *n=(TQStringBucket *)old_vec[index];
+ while ( n ) {
+ look_string( n->getKey(), n->getData(), op_insert );
+ TQStringBucket *t=(TQStringBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ case AsciiKey:
+ {
+ TQAsciiBucket *n=(TQAsciiBucket *)old_vec[index];
+ while ( n ) {
+ look_ascii( n->getKey(), n->getData(), op_insert );
+ TQAsciiBucket *t=(TQAsciiBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ case IntKey:
+ {
+ TQIntBucket *n=(TQIntBucket *)old_vec[index];
+ while ( n ) {
+ look_int( n->getKey(), n->getData(), op_insert );
+ TQIntBucket *t=(TQIntBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ case PtrKey:
+ {
+ TQPtrBucket *n=(TQPtrBucket *)old_vec[index];
+ while ( n ) {
+ look_ptr( n->getKey(), n->getData(), op_insert );
+ TQPtrBucket *t=(TQPtrBucket *)n->getNext();
+ delete n;
+ n = t;
+ }
+ }
+ break;
+ }
+ }
+ delete [] old_vec;
+
+ // Restore state
+ copyk = old_copyk;
+
+ // Invalidate all iterators, since order is lost
+ if ( iterators && iterators->count() ) {
+ TQGDictIterator *i = iterators->first();
+ while ( i ) {
+ i->toFirst();
+ i = iterators->next();
+ }
+ }
+}
+
+/*!
+ Unlinks the bucket with the specified key (and specified data pointer,
+ if it is set).
+*/
+
+void TQGDict::unlink_common( int index, TQBaseBucket *node, TQBaseBucket *prev )
+{
+ if ( iterators && iterators->count() ) { // update iterators
+ TQGDictIterator *i = iterators->first();
+ while ( i ) { // tqinvalidate all iterators
+ if ( i->curNode == node ) // referring to pending node
+ i->operator++();
+ i = iterators->next();
+ }
+ }
+ if ( prev ) // unlink node
+ prev->setNext( node->getNext() );
+ else
+ vec[index] = node->getNext();
+ numItems--;
+}
+
+TQStringBucket *TQGDict::unlink_string( const TQString &key, TQPtrCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ TQStringBucket *n;
+ TQStringBucket *prev = 0;
+ int index = hashKeyString(key) % vlen;
+ if ( cases ) {
+ for ( n=(TQStringBucket*)vec[index]; n;
+ n=(TQStringBucket*)n->getNext() ) {
+ bool found = (key == n->getKey());
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ } else {
+ TQString k = key.lower();
+ for ( n=(TQStringBucket*)vec[index]; n;
+ n=(TQStringBucket*)n->getNext() ) {
+ bool found = (k == n->getKey().lower());
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ }
+ return 0;
+}
+
+TQAsciiBucket *TQGDict::unlink_ascii( const char *key, TQPtrCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ TQAsciiBucket *n;
+ TQAsciiBucket *prev = 0;
+ int index = hashKeyAscii(key) % vlen;
+ for ( n=(TQAsciiBucket *)vec[index]; n; n=(TQAsciiBucket *)n->getNext() ) {
+ bool found = (cases ? qstrcmp(n->getKey(),key)
+ : qstricmp(n->getKey(),key)) == 0;
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ return 0;
+}
+
+TQIntBucket *TQGDict::unlink_int( long key, TQPtrCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ TQIntBucket *n;
+ TQIntBucket *prev = 0;
+ int index = (int)((ulong)key % vlen);
+ for ( n=(TQIntBucket *)vec[index]; n; n=(TQIntBucket *)n->getNext() ) {
+ bool found = (n->getKey() == key);
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ return 0;
+}
+
+TQPtrBucket *TQGDict::unlink_ptr( void *key, TQPtrCollection::Item d )
+{
+ if ( numItems == 0 ) // nothing in dictionary
+ return 0;
+ TQPtrBucket *n;
+ TQPtrBucket *prev = 0;
+ int index = (int)((ulong)key % vlen);
+ for ( n=(TQPtrBucket *)vec[index]; n; n=(TQPtrBucket *)n->getNext() ) {
+ bool found = (n->getKey() == key);
+ if ( found && d )
+ found = (n->getData() == d);
+ if ( found ) {
+ unlink_common(index,n,prev);
+ return n;
+ }
+ prev = n;
+ }
+ return 0;
+}
+
+
+/*!
+ Removes the item with the specified \a key. If \a item is not null,
+ the remove will match the \a item as well (used to remove an
+ item when several items have the same key).
+*/
+
+bool TQGDict::remove_string( const TQString &key, TQPtrCollection::Item item )
+{
+ TQStringBucket *n = unlink_string( key, item );
+ if ( n ) {
+ deleteItem( n->getData() );
+ delete n;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+bool TQGDict::remove_ascii( const char *key, TQPtrCollection::Item item )
+{
+ TQAsciiBucket *n = unlink_ascii( key, item );
+ if ( n ) {
+ if ( copyk )
+ delete [] (char *)n->getKey();
+ deleteItem( n->getData() );
+ delete n;
+ }
+ return n != 0;
+}
+
+bool TQGDict::remove_int( long key, TQPtrCollection::Item item )
+{
+ TQIntBucket *n = unlink_int( key, item );
+ if ( n ) {
+ deleteItem( n->getData() );
+ delete n;
+ }
+ return n != 0;
+}
+
+bool TQGDict::remove_ptr( void *key, TQPtrCollection::Item item )
+{
+ TQPtrBucket *n = unlink_ptr( key, item );
+ if ( n ) {
+ deleteItem( n->getData() );
+ delete n;
+ }
+ return n != 0;
+}
+
+TQPtrCollection::Item TQGDict::take_string( const TQString &key )
+{
+ TQStringBucket *n = unlink_string( key );
+ Item d;
+ if ( n ) {
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+TQPtrCollection::Item TQGDict::take_ascii( const char *key )
+{
+ TQAsciiBucket *n = unlink_ascii( key );
+ Item d;
+ if ( n ) {
+ if ( copyk )
+ delete [] (char *)n->getKey();
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+TQPtrCollection::Item TQGDict::take_int( long key )
+{
+ TQIntBucket *n = unlink_int( key );
+ Item d;
+ if ( n ) {
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+TQPtrCollection::Item TQGDict::take_ptr( void *key )
+{
+ TQPtrBucket *n = unlink_ptr( key );
+ Item d;
+ if ( n ) {
+ d = n->getData();
+ delete n;
+ } else {
+ d = 0;
+ }
+ return d;
+}
+
+/*!
+ Removes all items from the dictionary.
+*/
+void TQGDict::clear()
+{
+ if ( !numItems )
+ return;
+ numItems = 0; // disable remove() function
+ for ( uint j=0; j<vlen; j++ ) { // destroy hash table
+ if ( vec[j] ) {
+ switch ( keytype ) {
+ case StringKey:
+ {
+ TQStringBucket *n=(TQStringBucket *)vec[j];
+ while ( n ) {
+ TQStringBucket *next = (TQStringBucket*)n->getNext();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ case AsciiKey:
+ {
+ TQAsciiBucket *n=(TQAsciiBucket *)vec[j];
+ while ( n ) {
+ TQAsciiBucket *next = (TQAsciiBucket*)n->getNext();
+ if ( copyk )
+ delete [] (char *)n->getKey();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ case IntKey:
+ {
+ TQIntBucket *n=(TQIntBucket *)vec[j];
+ while ( n ) {
+ TQIntBucket *next = (TQIntBucket*)n->getNext();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ case PtrKey:
+ {
+ TQPtrBucket *n=(TQPtrBucket *)vec[j];
+ while ( n ) {
+ TQPtrBucket *next = (TQPtrBucket*)n->getNext();
+ deleteItem( n->getData() );
+ delete n;
+ n = next;
+ }
+ }
+ break;
+ }
+ vec[j] = 0; // detach list of buckets
+ }
+ }
+ if ( iterators && iterators->count() ) { // tqinvalidate all iterators
+ TQGDictIterator *i = iterators->first();
+ while ( i ) {
+ i->curNode = 0;
+ i = iterators->next();
+ }
+ }
+}
+
+/*!
+ Outputs debug statistics.
+*/
+void TQGDict::statistics() const
+{
+#if defined(TQT_DEBUG)
+ TQString line;
+ line.fill( '-', 60 );
+ double real, ideal;
+ qDebug( line.ascii() );
+ qDebug( "DICTIONARY STATISTICS:" );
+ if ( count() == 0 ) {
+ qDebug( "Empty!" );
+ qDebug( line.ascii() );
+ return;
+ }
+ real = 0.0;
+ ideal = (float)count()/(2.0*size())*(count()+2.0*size()-1);
+ uint i = 0;
+ while ( i<size() ) {
+ TQBaseBucket *n = vec[i];
+ int b = 0;
+ while ( n ) { // count number of buckets
+ b++;
+ n = n->getNext();
+ }
+ real = real + (double)b * ((double)b+1.0)/2.0;
+ char buf[80], *pbuf;
+ if ( b > 78 )
+ b = 78;
+ pbuf = buf;
+ while ( b-- )
+ *pbuf++ = '*';
+ *pbuf = '\0';
+ qDebug( buf );
+ i++;
+ }
+ qDebug( "Array size = %d", size() );
+ qDebug( "# items = %d", count() );
+ qDebug( "Real dist = %g", real );
+ qDebug( "Rand dist = %g", ideal );
+ qDebug( "Real/Rand = %g", real/ideal );
+ qDebug( line.ascii() );
+#endif // TQT_DEBUG
+}
+
+
+/*****************************************************************************
+ TQGDict stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQDataStream &operator>>( TQDataStream &s, TQGDict &dict )
+{
+ return dict.read( s );
+}
+
+TQDataStream &operator<<( TQDataStream &s, const TQGDict &dict )
+{
+ return dict.write( s );
+}
+
+#if defined(TQ_CC_DEC) && defined(__alpha) && (__DECCXX_VER-0 >= 50190001)
+#pragma message disable narrowptr
+#endif
+
+/*!
+ Reads a dictionary from the stream \a s.
+*/
+
+TQDataStream &TQGDict::read( TQDataStream &s )
+{
+ uint num;
+ s >> num; // read number of items
+ clear(); // clear dict
+ while ( num-- ) { // read all items
+ Item d;
+ switch ( keytype ) {
+ case StringKey:
+ {
+ TQString k;
+ s >> k;
+ read( s, d );
+ look_string( k, d, op_insert );
+ }
+ break;
+ case AsciiKey:
+ {
+ char *k;
+ s >> k;
+ read( s, d );
+ look_ascii( k, d, op_insert );
+ if ( copyk )
+ delete [] k;
+ }
+ break;
+ case IntKey:
+ {
+ TQ_UINT32 k;
+ s >> k;
+ read( s, d );
+ look_int( k, d, op_insert );
+ }
+ break;
+ case PtrKey:
+ {
+ TQ_UINT32 k;
+ s >> k;
+ read( s, d );
+ // ### cannot insert 0 - this renders the thing
+ // useless since all pointers are written as 0,
+ // but hey, serializing pointers? can it be done
+ // at all, ever?
+ if ( k )
+ look_ptr( (void *)k, d, op_insert );
+ }
+ break;
+ }
+ }
+ return s;
+}
+
+/*!
+ Writes the dictionary to the stream \a s.
+*/
+
+TQDataStream& TQGDict::write( TQDataStream &s ) const
+{
+ s << count(); // write number of items
+ uint i = 0;
+ while ( i<size() ) {
+ TQBaseBucket *n = vec[i];
+ while ( n ) { // write all buckets
+ switch ( keytype ) {
+ case StringKey:
+ s << ((TQStringBucket*)n)->getKey();
+ break;
+ case AsciiKey:
+ s << ((TQAsciiBucket*)n)->getKey();
+ break;
+ case IntKey:
+ s << (TQ_UINT32)((TQIntBucket*)n)->getKey();
+ break;
+ case PtrKey:
+ s << (TQ_UINT32)0; // ### cannot serialize a pointer
+ break;
+ }
+ write( s, n->getData() ); // write data
+ n = n->getNext();
+ }
+ i++;
+ }
+ return s;
+}
+#endif //TQT_NO_DATASTREAM
+
+/*****************************************************************************
+ TQGDictIterator member functions
+ *****************************************************************************/
+
+/*!
+ \class TQGDictIterator tqgdict.h
+ \reentrant
+ \ingroup collection
+ \brief The TQGDictIterator class is an internal class for implementing TQDictIterator and TQIntDictIterator.
+
+ \internal
+
+ TQGDictIterator is a strictly internal class that does the heavy work for
+ TQDictIterator and TQIntDictIterator.
+*/
+
+/*!
+ Constructs an iterator that operates on the dictionary \a d.
+*/
+
+TQGDictIterator::TQGDictIterator( const TQGDict &d )
+{
+ dict = (TQGDict *)&d; // get reference to dict
+ toFirst(); // set to first noe
+ if ( !dict->iterators ) {
+ dict->iterators = new TQGDItList; // create iterator list
+ TQ_CHECK_PTR( dict->iterators );
+ }
+ dict->iterators->append( this ); // attach iterator to dict
+}
+
+/*!
+ Constructs a copy of the iterator \a it.
+*/
+
+TQGDictIterator::TQGDictIterator( const TQGDictIterator &it )
+{
+ dict = it.dict;
+ curNode = it.curNode;
+ curIndex = it.curIndex;
+ if ( dict )
+ dict->iterators->append( this ); // attach iterator to dict
+}
+
+/*!
+ Assigns a copy of the iterator \a it and returns a reference to this
+ iterator.
+*/
+
+TQGDictIterator &TQGDictIterator::operator=( const TQGDictIterator &it )
+{
+ if ( dict ) // detach from old dict
+ dict->iterators->removeRef( this );
+ dict = it.dict;
+ curNode = it.curNode;
+ curIndex = it.curIndex;
+ if ( dict )
+ dict->iterators->append( this ); // attach to new list
+ return *this;
+}
+
+/*!
+ Destroys the iterator.
+*/
+
+TQGDictIterator::~TQGDictIterator()
+{
+ if ( dict ) // detach iterator from dict
+ dict->iterators->removeRef( this );
+}
+
+
+/*!
+ Sets the iterator to point to the first item in the dictionary.
+*/
+
+TQPtrCollection::Item TQGDictIterator::toFirst()
+{
+ if ( !dict ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQGDictIterator::toFirst: Dictionary has been deleted" );
+#endif
+ return 0;
+ }
+ if ( dict->count() == 0 ) { // empty dictionary
+ curNode = 0;
+ return 0;
+ }
+ register uint i = 0;
+ register TQBaseBucket **v = dict->vec;
+ while ( !(*v++) )
+ i++;
+ curNode = dict->vec[i];
+ curIndex = i;
+ return curNode->getData();
+}
+
+
+/*!
+ Moves to the next item (postfix).
+*/
+
+TQPtrCollection::Item TQGDictIterator::operator()()
+{
+ if ( !dict ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQGDictIterator::operator(): Dictionary has been deleted" );
+#endif
+ return 0;
+ }
+ if ( !curNode )
+ return 0;
+ TQPtrCollection::Item d = curNode->getData();
+ this->operator++();
+ return d;
+}
+
+/*!
+ Moves to the next item (prefix).
+*/
+
+TQPtrCollection::Item TQGDictIterator::operator++()
+{
+ if ( !dict ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQGDictIterator::operator++: Dictionary has been deleted" );
+#endif
+ return 0;
+ }
+ if ( !curNode )
+ return 0;
+ curNode = curNode->getNext();
+ if ( !curNode ) { // no next bucket
+ register uint i = curIndex + 1; // look from next vec element
+ register TQBaseBucket **v = &dict->vec[i];
+ while ( i < dict->size() && !(*v++) )
+ i++;
+ if ( i == dict->size() ) { // nothing found
+ curNode = 0;
+ return 0;
+ }
+ curNode = dict->vec[i];
+ curIndex = i;
+ }
+ return curNode->getData();
+}
+
+/*!
+ Moves \a jumps positions forward.
+*/
+
+TQPtrCollection::Item TQGDictIterator::operator+=( uint jumps )
+{
+ while ( curNode && jumps-- )
+ operator++();
+ return curNode ? curNode->getData() : 0;
+}
diff --git a/tqtinterface/qt4/src/tools/tqgdict.h b/tqtinterface/qt4/src/tools/tqgdict.h
new file mode 100644
index 0000000..d9bd543
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgdict.h
@@ -0,0 +1,225 @@
+/****************************************************************************
+**
+** Definition of TQGDict and TQGDictIterator classes
+**
+** Created : 920529
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGDICT_H
+#define TQGDICT_H
+
+#ifndef TQT_H
+#include "tqptrcollection.h"
+#include "tqstring.h"
+#endif // TQT_H
+
+class TQGDictIterator;
+class TQGDItList;
+
+
+class TQBaseBucket // internal dict node
+{
+public:
+ TQPtrCollection::Item getData() { return data; }
+ TQPtrCollection::Item setData( TQPtrCollection::Item d ) { return data = d; }
+ TQBaseBucket *getNext() { return next; }
+ void setNext( TQBaseBucket *n) { next = n; }
+protected:
+ TQBaseBucket( TQPtrCollection::Item d, TQBaseBucket *n ) : data(d), next(n) {}
+ TQPtrCollection::Item data;
+ TQBaseBucket *next;
+};
+
+class TQStringBucket : public TQBaseBucket
+{
+public:
+ TQStringBucket( const TQString &k, TQPtrCollection::Item d, TQBaseBucket *n )
+ : TQBaseBucket(d,n), key(k) {}
+ const TQString &getKey() const { return key; }
+private:
+ TQString key;
+};
+
+class TQAsciiBucket : public TQBaseBucket
+{
+public:
+ TQAsciiBucket( const char *k, TQPtrCollection::Item d, TQBaseBucket *n )
+ : TQBaseBucket(d,n), key(k) {}
+ const char *getKey() const { return key; }
+private:
+ const char *key;
+};
+
+class TQIntBucket : public TQBaseBucket
+{
+public:
+ TQIntBucket( long k, TQPtrCollection::Item d, TQBaseBucket *n )
+ : TQBaseBucket(d,n), key(k) {}
+ long getKey() const { return key; }
+private:
+ long key;
+};
+
+class TQPtrBucket : public TQBaseBucket
+{
+public:
+ TQPtrBucket( void *k, TQPtrCollection::Item d, TQBaseBucket *n )
+ : TQBaseBucket(d,n), key(k) {}
+ void *getKey() const { return key; }
+private:
+ void *key;
+};
+
+
+class TQ_EXPORT TQGDict : public TQPtrCollection // generic dictionary class
+{
+public:
+ uint count() const { return numItems; }
+ uint size() const { return vlen; }
+ TQPtrCollection::Item look_string( const TQString& key, TQPtrCollection::Item,
+ int );
+ TQPtrCollection::Item look_ascii( const char *key, TQPtrCollection::Item, int );
+ TQPtrCollection::Item look_int( long key, TQPtrCollection::Item, int );
+ TQPtrCollection::Item look_ptr( void *key, TQPtrCollection::Item, int );
+#ifndef TQT_NO_DATASTREAM
+ TQDataStream &read( TQDataStream & );
+ TQDataStream &write( TQDataStream & ) const;
+#endif
+protected:
+ enum KeyType { StringKey, AsciiKey, IntKey, PtrKey };
+
+ TQGDict( uint len, KeyType kt, bool cs, bool ck );
+ TQGDict( const TQGDict & );
+ ~TQGDict();
+
+ TQGDict &operator=( const TQGDict & );
+
+ bool remove_string( const TQString &key, TQPtrCollection::Item item=0 );
+ bool remove_ascii( const char *key, TQPtrCollection::Item item=0 );
+ bool remove_int( long key, TQPtrCollection::Item item=0 );
+ bool remove_ptr( void *key, TQPtrCollection::Item item=0 );
+ TQPtrCollection::Item take_string( const TQString &key );
+ TQPtrCollection::Item take_ascii( const char *key );
+ TQPtrCollection::Item take_int( long key );
+ TQPtrCollection::Item take_ptr( void *key );
+
+ void clear();
+ void resize( uint );
+
+ int hashKeyString( const TQString & );
+ int hashKeyAscii( const char * );
+
+ void statistics() const;
+
+#ifndef TQT_NO_DATASTREAM
+ virtual TQDataStream &read( TQDataStream &, TQPtrCollection::Item & );
+ virtual TQDataStream &write( TQDataStream &, TQPtrCollection::Item ) const;
+#endif
+private:
+ TQBaseBucket **vec;
+ uint vlen;
+ uint numItems;
+ uint keytype : 2;
+ uint cases : 1;
+ uint copyk : 1;
+ TQGDItList *iterators;
+ void unlink_common( int, TQBaseBucket *, TQBaseBucket * );
+ TQStringBucket *unlink_string( const TQString &,
+ TQPtrCollection::Item item = 0 );
+ TQAsciiBucket *unlink_ascii( const char *, TQPtrCollection::Item item = 0 );
+ TQIntBucket *unlink_int( long, TQPtrCollection::Item item = 0 );
+ TQPtrBucket *unlink_ptr( void *, TQPtrCollection::Item item = 0 );
+ void init( uint, KeyType, bool, bool );
+ friend class TQGDictIterator;
+};
+
+
+class TQ_EXPORT TQGDictIterator // generic dictionary iterator
+{
+friend class TQGDict;
+public:
+ TQGDictIterator( const TQGDict & );
+ TQGDictIterator( const TQGDictIterator & );
+ TQGDictIterator &operator=( const TQGDictIterator & );
+ ~TQGDictIterator();
+
+ TQPtrCollection::Item toFirst();
+
+ TQPtrCollection::Item get() const;
+ TQString getKeyString() const;
+ const char *getKeyAscii() const;
+ long getKeyInt() const;
+ void *getKeyPtr() const;
+
+ TQPtrCollection::Item operator()();
+ TQPtrCollection::Item operator++();
+ TQPtrCollection::Item operator+=(uint);
+
+protected:
+ TQGDict *dict;
+
+private:
+ TQBaseBucket *curNode;
+ uint curIndex;
+};
+
+inline TQPtrCollection::Item TQGDictIterator::get() const
+{
+ return curNode ? curNode->getData() : 0;
+}
+
+inline TQString TQGDictIterator::getKeyString() const
+{
+ return curNode ? ((TQStringBucket*)curNode)->getKey() : TQString::null;
+}
+
+inline const char *TQGDictIterator::getKeyAscii() const
+{
+ return curNode ? ((TQAsciiBucket*)curNode)->getKey() : 0;
+}
+
+inline long TQGDictIterator::getKeyInt() const
+{
+ return curNode ? ((TQIntBucket*)curNode)->getKey() : 0;
+}
+
+inline void *TQGDictIterator::getKeyPtr() const
+{
+ return curNode ? ((TQPtrBucket*)curNode)->getKey() : 0;
+}
+
+
+#endif // TQGDICT_H
diff --git a/tqtinterface/qt4/src/tools/tqgeneric.h b/tqtinterface/qt4/src/tools/tqgeneric.h
new file mode 100644
index 0000000..9ab0d6f
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgeneric.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Macros for pasting tokens; utilized by our generic classes
+**
+** Created : 920529
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGENERIC_H
+#define TQGENERIC_H
+
+#error "do not include tqgeneric.h any more"
+
+#endif // TQGENERIC_H
diff --git a/tqtinterface/qt4/src/tools/tqglist.cpp b/tqtinterface/qt4/src/tools/tqglist.cpp
new file mode 100644
index 0000000..944c27c
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqglist.cpp
@@ -0,0 +1,1267 @@
+/****************************************************************************
+**
+** Implementation of TQGList and TQGListIterator classes
+**
+** Created : 920624
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqglist.h"
+#include "tqgvector.h"
+#include "tqdatastream.h"
+#include "tqvaluelist.h"
+
+/*!
+ \class TQLNode tqglist.h
+ \reentrant
+ \ingroup collection
+ \brief The TQLNode class is an internal class for the TQPtrList template collection.
+
+ \internal
+
+ TQLNode is a doubly-linked list node. It has three pointers:
+ \list 1
+ \i Pointer to the previous node.
+ \i Pointer to the next node.
+ \i Pointer to the actual data.
+ \endlist
+
+ It might sometimes be practical to have direct access to the list nodes
+ in a TQPtrList, but it is seldom required.
+
+ Be very careful if you want to access the list nodes. The heap can
+ easily get corrupted if you make a mistake.
+
+ \sa TQPtrList::currentNode(), TQPtrList::removeNode(), TQPtrList::takeNode()
+*/
+
+/*!
+ \fn TQPtrCollection::Item TQLNode::getData()
+ Returns a pointer (\c void*) to the actual data in the list node.
+*/
+
+
+/*!
+ \class TQGList tqglist.h
+ \reentrant
+ \ingroup collection
+ \brief The TQGList class is an internal class for implementing TQt collection classes.
+
+ \internal
+
+ TQGList is a strictly internal class that acts as a base class for
+ several collection classes; TQPtrList, TQPtrQueue and TQPtrStack.
+
+ TQGList has some virtual functions that can be reimplemented to
+ customize the subclasses, namely compareItems(), read() and
+ write. Normally, you do not have to reimplement any of these
+ functions. If you still want to reimplement them, see the TQStrList
+ class (tqstrlist.h) for an example.
+*/
+
+
+/* Internal helper class for TQGList. Contains some optimization for
+ the typically case where only one iterators is activre on the list.
+ */
+class TQGListIteratorList
+{
+public:
+ TQGListIteratorList()
+ : list(0), iterator(0) {
+ }
+ ~TQGListIteratorList() {
+ notifyClear( TRUE );
+ delete list;
+ }
+
+ void add( TQGListIterator* i ) {
+ if ( !iterator ) {
+ iterator = i;
+ } else if ( list ) {
+ list->push_front( i );
+ } else {
+ list = new TQValueList<TQGListIterator*>;
+ list->push_front( i );
+ }
+ }
+
+ void remove( TQGListIterator* i ) {
+ if ( iterator == i ) {
+ iterator = 0;
+ } else if ( list ) {
+ list->remove( i );
+ if ( list->isEmpty() ) {
+ delete list;
+ list = 0;
+ }
+ }
+ }
+
+ void notifyClear( bool zeroList ) {
+ if ( iterator ) {
+ if ( zeroList )
+ iterator->list = 0;
+ iterator->curNode = 0;
+ }
+ if ( list ) {
+ for ( TQValueList<TQGListIterator*>::Iterator i = list->begin(); i != list->end(); ++i ) {
+ if ( zeroList )
+ (*i)->list = 0;
+ (*i)->curNode = 0;
+ }
+ }
+ }
+
+ void notifyRemove( TQLNode* n, TQLNode* curNode ) {
+ if ( iterator ) {
+ if ( iterator->curNode == n )
+ iterator->curNode = curNode;
+ }
+ if ( list ) {
+ for ( TQValueList<TQGListIterator*>::Iterator i = list->begin(); i != list->end(); ++i ) {
+ if ( (*i)->curNode == n )
+ (*i)->curNode = curNode;
+ }
+ }
+ }
+
+private:
+ TQValueList<TQGListIterator*>* list;
+ TQGListIterator* iterator;
+};
+
+
+
+/*****************************************************************************
+ Default implementation of virtual functions
+ *****************************************************************************/
+
+/*!
+ Documented as TQPtrList::compareItems().
+
+ Compares \a item1 with \a item2.
+*/
+int TQGList::compareItems( TQPtrCollection::Item item1, TQPtrCollection::Item item2 )
+{
+ return item1 != item2; // compare pointers
+}
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \overload
+ Reads a collection/list item from the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation sets \a item to 0.
+
+ \sa write()
+*/
+
+TQDataStream &TQGList::read( TQDataStream &s, TQPtrCollection::Item &item )
+{
+ item = 0;
+ return s;
+}
+
+/*!
+ \overload
+ Writes a collection/list item to the stream \a s and
+ returns a reference to the stream.
+
+ The default implementation does nothing.
+
+ \sa read()
+*/
+
+TQDataStream &TQGList::write( TQDataStream &s, TQPtrCollection::Item ) const
+{
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+/*****************************************************************************
+ TQGList member functions
+ *****************************************************************************/
+
+/*!
+ Constructs an empty list.
+*/
+
+TQGList::TQGList()
+{
+ firstNode = lastNode = curNode = 0; // initialize list
+ numNodes = 0;
+ curIndex = -1;
+ iterators = 0; // initialize iterator list
+}
+
+/*!
+ Constructs a copy of \a list.
+*/
+
+TQGList::TQGList( const TQGList & list )
+ : TQPtrCollection( list )
+{
+ firstNode = lastNode = curNode = 0; // initialize list
+ numNodes = 0;
+ curIndex = -1;
+ iterators = 0; // initialize iterator list
+ TQLNode *n = list.firstNode;
+ while ( n ) { // copy all items from list
+ append( n->data );
+ n = n->next;
+ }
+}
+
+/*!
+ Removes all items from the list and destroys the list.
+*/
+
+TQGList::~TQGList()
+{
+ clear();
+ delete iterators;
+ // Workaround for GCC 2.7.* bug. Compiler constructs 'static' TQGList
+ // instances twice on the same address and therefore tries to destruct
+ // twice on the same address! This is insane but let's try not to crash
+ // here.
+ iterators = 0;
+}
+
+
+/*!
+ Assigns \a list to this list.
+*/
+
+TQGList& TQGList::operator=( const TQGList &list )
+{
+ if ( &list == this )
+ return *this;
+
+ clear();
+ if ( list.count() > 0 ) {
+ TQLNode *n = list.firstNode;
+ while ( n ) { // copy all items from list
+ append( n->data );
+ n = n->next;
+ }
+ curNode = firstNode;
+ curIndex = 0;
+ }
+ return *this;
+}
+
+/*!
+ Compares this list with \a list. Returns TRUE if the lists
+ contain the same data, otherwise FALSE.
+*/
+
+bool TQGList::operator==( const TQGList &list ) const
+{
+ if ( count() != list.count() )
+ return FALSE;
+
+ if ( count() == 0 )
+ return TRUE;
+
+ TQLNode *n1 = firstNode;
+ TQLNode *n2 = list.firstNode;
+ while ( n1 && n2 ) {
+ // should be mutable
+ if ( ( (TQGList*)this )->compareItems( n1->data, n2->data ) != 0 )
+ return FALSE;
+ n1 = n1->next;
+ n2 = n2->next;
+ }
+
+ return TRUE;
+}
+
+/*!
+ \fn uint TQGList::count() const
+
+ Returns the number of items in the list.
+*/
+
+
+/*!
+ Returns the node at position \a index. Sets this node to current.
+*/
+
+TQLNode *TQGList::locate( uint index )
+{
+ if ( index == (uint)curIndex ) // current node ?
+ return curNode;
+ if ( !curNode && firstNode ) { // set current node
+ curNode = firstNode;
+ curIndex = 0;
+ }
+ register TQLNode *node;
+ int distance = index - curIndex; // node distance to cur node
+ bool forward; // direction to traverse
+
+ if ( index >= numNodes )
+ return 0;
+
+ if ( distance < 0 )
+ distance = -distance;
+ if ( (uint)distance < index && (uint)distance < numNodes - index ) {
+ node = curNode; // start from current node
+ forward = index > (uint)curIndex;
+ } else if ( index < numNodes - index ) { // start from first node
+ node = firstNode;
+ distance = index;
+ forward = TRUE;
+ } else { // start from last node
+ node = lastNode;
+ distance = numNodes - index - 1;
+ if ( distance < 0 )
+ distance = 0;
+ forward = FALSE;
+ }
+ if ( forward ) { // now run through nodes
+ while ( distance-- )
+ node = node->next;
+ } else {
+ while ( distance-- )
+ node = node->prev;
+ }
+ curIndex = index; // must update index
+ return curNode = node;
+}
+
+
+/*!
+ Inserts item \a d at its sorted position in the list.
+*/
+
+void TQGList::inSort( TQPtrCollection::Item d )
+{
+ int index = 0;
+ register TQLNode *n = firstNode;
+ while ( n && compareItems(n->data,d) < 0 ){ // tqfind position in list
+ n = n->next;
+ index++;
+ }
+ insertAt( index, d );
+}
+
+
+/*!
+ Inserts item \a d at the start of the list.
+*/
+
+void TQGList::prepend( TQPtrCollection::Item d )
+{
+ register TQLNode *n = new TQLNode( newItem(d) );
+ TQ_CHECK_PTR( n );
+ n->prev = 0;
+ if ( (n->next = firstNode) ) // list is not empty
+ firstNode->prev = n;
+ else // initialize list
+ lastNode = n;
+ firstNode = curNode = n; // curNode affected
+ numNodes++;
+ curIndex = 0;
+}
+
+
+/*!
+ Inserts item \a d at the end of the list.
+*/
+
+void TQGList::append( TQPtrCollection::Item d )
+{
+ register TQLNode *n = new TQLNode( newItem(d) );
+ TQ_CHECK_PTR( n );
+ n->next = 0;
+ if ( (n->prev = lastNode) ) // list is not empty
+ lastNode->next = n;
+ else // initialize list
+ firstNode = n;
+ lastNode = curNode = n; // curNode affected
+ curIndex = numNodes;
+ numNodes++;
+}
+
+
+/*!
+ Inserts item \a d at position \a index in the list.
+*/
+
+bool TQGList::insertAt( uint index, TQPtrCollection::Item d )
+{
+ if ( index == 0 ) {
+ prepend( d );
+ return TRUE;
+ } else if ( index == numNodes ) {
+ append( d );
+ return TRUE;
+ }
+ TQLNode *nextNode = locate( index );
+ if ( !nextNode )
+ return FALSE;
+ TQLNode *prevNode = nextNode->prev;
+ register TQLNode *n = new TQLNode( newItem(d) );
+ TQ_CHECK_PTR( n );
+ nextNode->prev = n;
+ prevNode->next = n;
+ n->prev = prevNode; // link new node into list
+ n->next = nextNode;
+ curNode = n; // curIndex set by locate()
+ numNodes++;
+ return TRUE;
+}
+
+
+/*!
+ Relinks node \a n and makes it the first node in the list.
+*/
+
+void TQGList::relinkNode( TQLNode *n )
+{
+ if ( n == firstNode ) // already first
+ return;
+ curNode = n;
+ unlink();
+ n->prev = 0;
+ if ( (n->next = firstNode) ) // list is not empty
+ firstNode->prev = n;
+ else // initialize list
+ lastNode = n;
+ firstNode = curNode = n; // curNode affected
+ numNodes++;
+ curIndex = 0;
+}
+
+
+/*!
+ Unlinks the current list node and returns a pointer to this node.
+*/
+
+TQLNode *TQGList::unlink()
+{
+ if ( curNode == 0 ) // null current node
+ return 0;
+ register TQLNode *n = curNode; // unlink this node
+ if ( n == firstNode ) { // removing first node ?
+ if ( (firstNode = n->next) ) {
+ firstNode->prev = 0;
+ } else {
+ lastNode = curNode = 0; // list becomes empty
+ curIndex = -1;
+ }
+ } else {
+ if ( n == lastNode ) { // removing last node ?
+ lastNode = n->prev;
+ lastNode->next = 0;
+ } else { // neither last nor first node
+ n->prev->next = n->next;
+ n->next->prev = n->prev;
+ }
+ }
+
+ if ( n->next ) { // change current node
+ curNode = n->next;
+ } else if ( n->prev ) {
+ curNode = n->prev;
+ curIndex--;
+ }
+
+ if ( iterators )
+ iterators->notifyRemove( n, curNode );
+ numNodes--;
+ return n;
+}
+
+
+/*!
+ Removes the node \a n from the list.
+*/
+
+bool TQGList::removeNode( TQLNode *n )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( n == 0 || (n->prev && n->prev->next != n) ||
+ (n->next && n->next->prev != n) ) {
+ qWarning( "TQGList::removeNode: Corrupted node" );
+ return FALSE;
+ }
+#endif
+ curNode = n;
+ unlink(); // unlink node
+ deleteItem( n->data ); // deallocate this node
+ delete n;
+ curNode = firstNode;
+ curIndex = curNode ? 0 : -1;
+ return TRUE;
+}
+
+/*!
+ Removes the item \a d from the list. Uses compareItems() to tqfind the item.
+
+ If \a d is 0, removes the current item.
+*/
+
+bool TQGList::remove( TQPtrCollection::Item d )
+{
+ if ( d && tqfind(d) == -1 )
+ return FALSE;
+ TQLNode *n = unlink();
+ if ( !n )
+ return FALSE;
+ deleteItem( n->data );
+ delete n;
+ return TRUE;
+}
+
+/*!
+ Removes the item \a d from the list.
+*/
+
+bool TQGList::removeRef( TQPtrCollection::Item d )
+{
+ if ( tqfindRef(d) == -1 )
+ return FALSE;
+ TQLNode *n = unlink();
+ if ( !n )
+ return FALSE;
+ deleteItem( n->data );
+ delete n;
+ return TRUE;
+}
+
+/*!
+ \fn bool TQGList::removeFirst()
+
+ Removes the first item in the list.
+*/
+
+/*!
+ \fn bool TQGList::removeLast()
+
+ Removes the last item in the list.
+*/
+
+/*!
+ Removes the item at position \a index from the list.
+*/
+
+bool TQGList::removeAt( uint index )
+{
+ if ( !locate(index) )
+ return FALSE;
+ TQLNode *n = unlink();
+ if ( !n )
+ return FALSE;
+ deleteItem( n->data );
+ delete n;
+ return TRUE;
+}
+
+
+/*!
+ Replaces the item at index \a index with \a d.
+*/
+bool TQGList::tqreplaceAt( uint index, TQPtrCollection::Item d )
+{
+ TQLNode *n = locate( index );
+ if ( !n )
+ return FALSE;
+ if ( n->data != d ) {
+ deleteItem( n->data );
+ n->data = newItem( d );
+ }
+ return TRUE;
+}
+
+
+
+/*!
+ Takes the node \a n out of the list.
+*/
+
+TQPtrCollection::Item TQGList::takeNode( TQLNode *n )
+{
+#if defined(TQT_CHECK_NULL)
+ if ( n == 0 || (n->prev && n->prev->next != n) ||
+ (n->next && n->next->prev != n) ) {
+ qWarning( "TQGList::takeNode: Corrupted node" );
+ return 0;
+ }
+#endif
+ curNode = n;
+ unlink(); // unlink node
+ Item d = n->data;
+ delete n; // delete the node, not data
+ curNode = firstNode;
+ curIndex = curNode ? 0 : -1;
+ return d;
+}
+
+/*!
+ Takes the current item out of the list.
+*/
+
+TQPtrCollection::Item TQGList::take()
+{
+ TQLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n; // delete node, keep contents
+ return d;
+}
+
+/*!
+ Takes the item at position \a index out of the list.
+*/
+
+TQPtrCollection::Item TQGList::takeAt( uint index )
+{
+ if ( !locate(index) )
+ return 0;
+ TQLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n; // delete node, keep contents
+ return d;
+}
+
+/*!
+ Takes the first item out of the list.
+*/
+
+TQPtrCollection::Item TQGList::takeFirst()
+{
+ first();
+ TQLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n;
+ return d;
+}
+
+/*!
+ Takes the last item out of the list.
+*/
+
+TQPtrCollection::Item TQGList::takeLast()
+{
+ last();
+ TQLNode *n = unlink(); // unlink node
+ Item d = n ? n->data : 0;
+ delete n;
+ return d;
+}
+
+
+/*!
+ Removes all items from the list.
+*/
+
+void TQGList::clear()
+{
+ register TQLNode *n = firstNode;
+
+ firstNode = lastNode = curNode = 0; // initialize list
+ numNodes = 0;
+ curIndex = -1;
+
+ if ( iterators )
+ iterators->notifyClear( FALSE );
+
+ TQLNode *prevNode;
+ while ( n ) { // for all nodes ...
+ deleteItem( n->data ); // deallocate data
+ prevNode = n;
+ n = n->next;
+ delete prevNode; // deallocate node
+ }
+}
+
+
+/*!
+ Finds item \a d in the list. If \a fromStart is TRUE the search
+ begins at the first node; otherwise it begins at the current node.
+*/
+
+int TQGList::tqfindRef( TQPtrCollection::Item d, bool fromStart )
+{
+ register TQLNode *n;
+ int index;
+ if ( fromStart ) { // start from first node
+ n = firstNode;
+ index = 0;
+ } else { // start from current node
+ n = curNode;
+ index = curIndex;
+ }
+ while ( n && n->data != d ) { // tqfind exact match
+ n = n->next;
+ index++;
+ }
+ curNode = n;
+ curIndex = n ? index : -1;
+ return curIndex; // return position of item
+}
+
+/*!
+ Finds item \a d in the list using compareItems(). If \a fromStart is
+ TRUE the search begins at the first node; otherwise it begins at the
+ current node.
+*/
+
+int TQGList::tqfind( TQPtrCollection::Item d, bool fromStart )
+{
+ register TQLNode *n;
+ int index;
+ if ( fromStart ) { // start from first node
+ n = firstNode;
+ index = 0;
+ } else { // start from current node
+ n = curNode;
+ index = curIndex;
+ }
+ while ( n && compareItems(n->data,d) ){ // tqfind equal match
+ n = n->next;
+ index++;
+ }
+ curNode = n;
+ curIndex = n ? index : -1;
+ return curIndex; // return position of item
+}
+
+
+/*!
+ Counts the number item \a d occurs in the list.
+*/
+
+uint TQGList::tqcontainsRef( TQPtrCollection::Item d ) const
+{
+ register TQLNode *n = firstNode;
+ uint count = 0;
+ while ( n ) { // for all nodes...
+ if ( n->data == d ) // count # exact matches
+ count++;
+ n = n->next;
+ }
+ return count;
+}
+
+/*!
+ Counts the number of times item \a d occurs in the list. Uses
+ compareItems().
+*/
+
+uint TQGList::tqcontains( TQPtrCollection::Item d ) const
+{
+ register TQLNode *n = firstNode;
+ uint count = 0;
+ TQGList *that = (TQGList*)this; // mutable for compareItems()
+ while ( n ) { // for all nodes...
+ if ( !that->compareItems(n->data,d) ) // count # equal matches
+ count++;
+ n = n->next;
+ }
+ return count;
+}
+
+
+/*!
+ \overload TQPtrCollection::Item TQGList::at( uint index )
+
+ Sets the item at position \a index to the current item.
+*/
+
+/*!
+ \fn int TQGList::at() const
+
+ Returns the current index.
+*/
+
+/*!
+ \fn TQLNode *TQGList::currentNode() const
+
+ Returns the current node.
+*/
+
+/*!
+ \fn TQPtrCollection::Item TQGList::get() const
+
+ Returns the current item.
+*/
+
+/*!
+ \fn TQPtrCollection::Item TQGList::cfirst() const
+
+ Returns the first item in the list.
+*/
+
+/*!
+ \fn TQPtrCollection::Item TQGList::clast() const
+
+ Returns the last item in the list.
+*/
+
+
+/*!
+ Returns the first list item. Sets this to current.
+*/
+
+TQPtrCollection::Item TQGList::first()
+{
+ if ( firstNode ) {
+ curIndex = 0;
+ return (curNode=firstNode)->data;
+ }
+ return 0;
+}
+
+/*!
+ Returns the last list item. Sets this to current.
+*/
+
+TQPtrCollection::Item TQGList::last()
+{
+ if ( lastNode ) {
+ curIndex = numNodes-1;
+ return (curNode=lastNode)->data;
+ }
+ return 0;
+}
+
+/*!
+ Returns the next list item (after current). Sets this to current.
+*/
+
+TQPtrCollection::Item TQGList::next()
+{
+ if ( curNode ) {
+ if ( curNode->next ) {
+ curIndex++;
+ curNode = curNode->next;
+ return curNode->data;
+ }
+ curIndex = -1;
+ curNode = 0;
+ }
+ return 0;
+}
+
+/*!
+ Returns the previous list item (before current). Sets this to current.
+*/
+
+TQPtrCollection::Item TQGList::prev()
+{
+ if ( curNode ) {
+ if ( curNode->prev ) {
+ curIndex--;
+ curNode = curNode->prev;
+ return curNode->data;
+ }
+ curIndex = -1;
+ curNode = 0;
+ }
+ return 0;
+}
+
+
+/*!
+ Converts the list to a vector, \a vector.
+*/
+
+void TQGList::toVector( TQGVector *vector ) const
+{
+ vector->clear();
+ if ( !vector->resize( count() ) )
+ return;
+ register TQLNode *n = firstNode;
+ uint i = 0;
+ while ( n ) {
+ vector->insert( i, n->data );
+ n = n->next;
+ i++;
+ }
+}
+
+void TQGList::heapSortPushDown( TQPtrCollection::Item* heap, int first, int last )
+{
+ int r = first;
+ while( r <= last/2 ) {
+ // Node r has only one child ?
+ if ( last == 2*r ) {
+ // Need for swapping ?
+ if ( compareItems( heap[r], heap[ 2*r ] ) > 0 ) {
+ TQPtrCollection::Item tmp = heap[r];
+ heap[ r ] = heap[ 2*r ];
+ heap[ 2*r ] = tmp;
+ }
+ // That's it ...
+ r = last;
+ } else {
+ // Node has two tqchildren
+ if ( compareItems( heap[r], heap[ 2*r ] ) > 0 &&
+ compareItems( heap[ 2*r ], heap[ 2*r+1 ] ) <= 0 ) {
+ // Swap with left child
+ TQPtrCollection::Item tmp = heap[r];
+ heap[ r ] = heap[ 2*r ];
+ heap[ 2*r ] = tmp;
+ r *= 2;
+ } else if ( compareItems( heap[r], heap[ 2*r+1 ] ) > 0 &&
+ compareItems( heap[ 2*r+1 ], heap[ 2*r ] ) < 0 ) {
+ // Swap with right child
+ TQPtrCollection::Item tmp = heap[r];
+ heap[ r ] = heap[ 2*r+1 ];
+ heap[ 2*r+1 ] = tmp;
+ r = 2*r+1;
+ } else {
+ // We are done
+ r = last;
+ }
+ }
+ }
+}
+
+
+/*! Sorts the list by the result of the virtual compareItems() function.
+
+ The Heap-Sort algorithm is used for sorting. It sorts n items with
+ O(n*log n) compares. This is the asymptotic optimal solution of the
+ sorting problem.
+*/
+
+void TQGList::sort()
+{
+ uint n = count();
+ if ( n < 2 )
+ return;
+
+ // Create the heap
+ TQPtrCollection::Item* realheap = new TQPtrCollection::Item[ n ];
+ // Wow, what a fake. But I want the heap to be indexed as 1...n
+ TQPtrCollection::Item* heap = realheap - 1;
+ int size = 0;
+ TQLNode* insert = firstNode;
+ for( ; insert != 0; insert = insert->next ) {
+ heap[++size] = insert->data;
+ int i = size;
+ while( i > 1 && compareItems( heap[i], heap[ i / 2 ] ) < 0 ) {
+ TQPtrCollection::Item tmp = heap[ i ];
+ heap[ i ] = heap[ i/2 ];
+ heap[ i/2 ] = tmp;
+ i /= 2;
+ }
+ }
+
+ insert = firstNode;
+ // Now do the sorting
+ for ( int i = n; i > 0; i-- ) {
+ insert->data = heap[1];
+ insert = insert->next;
+ if ( i > 1 ) {
+ heap[1] = heap[i];
+ heapSortPushDown( heap, 1, i - 1 );
+ }
+ }
+
+ delete [] realheap;
+}
+
+
+/*****************************************************************************
+ TQGList stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+TQDataStream &operator>>( TQDataStream &s, TQGList &list )
+{ // read list
+ return list.read( s );
+}
+
+TQDataStream &operator<<( TQDataStream &s, const TQGList &list )
+{ // write list
+ return list.write( s );
+}
+
+/*!
+ Reads a list from the stream \a s.
+*/
+
+TQDataStream &TQGList::read( TQDataStream &s )
+{
+ uint num;
+ s >> num; // read number of items
+ clear(); // clear list
+ while ( num-- ) { // read all items
+ Item d;
+ read( s, d );
+ TQ_CHECK_PTR( d );
+ if ( !d ) // no memory
+ break;
+ TQLNode *n = new TQLNode( d );
+ TQ_CHECK_PTR( n );
+ if ( !n ) // no memory
+ break;
+ n->next = 0;
+ if ( (n->prev = lastNode) ) // list is not empty
+ lastNode->next = n;
+ else // initialize list
+ firstNode = n;
+ lastNode = n;
+ numNodes++;
+ }
+ curNode = firstNode;
+ curIndex = curNode ? 0 : -1;
+ return s;
+}
+
+/*!
+ Writes the list to the stream \a s.
+*/
+
+TQDataStream &TQGList::write( TQDataStream &s ) const
+{
+ s << count(); // write number of items
+ TQLNode *n = firstNode;
+ while ( n ) { // write all items
+ write( s, n->data );
+ n = n->next;
+ }
+ return s;
+}
+
+#endif // TQT_NO_DATASTREAM
+
+
+
+/*! \internal
+ */
+TQLNode* TQGList::erase( TQLNode* it )
+{
+ TQLNode* n = it;
+ it = it->next;
+ removeNode( n );
+ return it;
+}
+
+
+/*****************************************************************************
+ TQGListIterator member functions
+ *****************************************************************************/
+
+/*!
+ \class TQGListIterator tqglist.h
+ \reentrant
+ \ingroup collection
+ \brief The TQGListIterator class is an internal class for implementing TQPtrListIterator.
+
+ \internal
+
+ TQGListIterator is a strictly internal class that does the heavy work for
+ TQPtrListIterator.
+*/
+
+/*!
+ \internal
+ Constructs an iterator that operates on the list \a l.
+*/
+
+TQGListIterator::TQGListIterator( const TQGList &l )
+{
+ list = (TQGList *)&l; // get reference to list
+ curNode = list->firstNode; // set to first node
+ if ( !list->iterators ) {
+ list->iterators = new TQGListIteratorList; // create iterator list
+ TQ_CHECK_PTR( list->iterators );
+ }
+ list->iterators->add( this ); // attach iterator to list
+}
+
+/*!
+ \internal
+ Constructs a copy of the iterator \a it.
+*/
+
+TQGListIterator::TQGListIterator( const TQGListIterator &it )
+{
+ list = it.list;
+ curNode = it.curNode;
+ if ( list )
+ list->iterators->add( this ); // attach iterator to list
+}
+
+/*!
+ \internal
+ Assigns a copy of the iterator \a it and returns a reference to this
+ iterator.
+*/
+
+TQGListIterator &TQGListIterator::operator=( const TQGListIterator &it )
+{
+ if ( list ) // detach from old list
+ list->iterators->remove( this );
+ list = it.list;
+ curNode = it.curNode;
+ if ( list )
+ list->iterators->add( this ); // attach to new list
+ return *this;
+}
+
+/*!
+ \internal
+ Destroys the iterator.
+*/
+
+TQGListIterator::~TQGListIterator()
+{
+ if ( list ) // detach iterator from list
+ list->iterators->remove(this);
+}
+
+
+/*!
+ \fn bool TQGListIterator::atFirst() const
+ \internal
+ Returns TRUE if the iterator points to the first item, otherwise FALSE.
+*/
+
+/*!
+ \fn bool TQGListIterator::atLast() const
+ \internal
+ Returns TRUE if the iterator points to the last item, otherwise FALSE.
+*/
+
+
+/*!
+ \internal
+ Sets the list iterator to point to the first item in the list.
+*/
+
+TQPtrCollection::Item TQGListIterator::toFirst()
+{
+ if ( !list ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQGListIterator::toFirst: List has been deleted" );
+#endif
+ return 0;
+ }
+ return list->firstNode ? (curNode = list->firstNode)->getData() : 0;
+}
+
+/*!
+ \internal
+ Sets the list iterator to point to the last item in the list.
+*/
+
+TQPtrCollection::Item TQGListIterator::toLast()
+{
+ if ( !list ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQGListIterator::toLast: List has been deleted" );
+#endif
+ return 0;
+ }
+ return list->lastNode ? (curNode = list->lastNode)->getData() : 0;
+}
+
+
+/*!
+ \fn TQPtrCollection::Item TQGListIterator::get() const
+ \internal
+ Returns the iterator item.
+*/
+
+
+/*!
+ \internal
+ Moves to the next item (postfix).
+*/
+
+TQPtrCollection::Item TQGListIterator::operator()()
+{
+ if ( !curNode )
+ return 0;
+ TQPtrCollection::Item d = curNode->getData();
+ curNode = curNode->next;
+ return d;
+}
+
+/*!
+ \internal
+ Moves to the next item (prefix).
+*/
+
+TQPtrCollection::Item TQGListIterator::operator++()
+{
+ if ( !curNode )
+ return 0;
+ curNode = curNode->next;
+ return curNode ? curNode->getData() : 0;
+}
+
+/*!
+ \internal
+ Moves \a jumps positions forward.
+*/
+
+TQPtrCollection::Item TQGListIterator::operator+=( uint jumps )
+{
+ while ( curNode && jumps-- )
+ curNode = curNode->next;
+ return curNode ? curNode->getData() : 0;
+}
+
+/*!
+ \internal
+ Moves to the previous item (prefix).
+*/
+
+TQPtrCollection::Item TQGListIterator::operator--()
+{
+ if ( !curNode )
+ return 0;
+ curNode = curNode->prev;
+ return curNode ? curNode->getData() : 0;
+}
+
+/*!
+ \internal
+ Moves \a jumps positions backward.
+*/
+
+TQPtrCollection::Item TQGListIterator::operator-=( uint jumps )
+{
+ while ( curNode && jumps-- )
+ curNode = curNode->prev;
+ return curNode ? curNode->getData() : 0;
+}
diff --git a/tqtinterface/qt4/src/tools/tqglist.h b/tqtinterface/qt4/src/tools/tqglist.h
new file mode 100644
index 0000000..4c91453
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqglist.h
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Definition of TQGList and TQGListIterator classes
+**
+** Created : 920624
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGLIST_H
+#define TQGLIST_H
+
+#ifndef TQT_H
+#include "tqptrcollection.h"
+#endif // TQT_H
+
+class TQ_EXPORT TQLNode
+{
+friend class TQGList;
+friend class TQGListIterator;
+friend class TQGListStdIterator;
+public:
+ TQPtrCollection::Item getData() { return data; }
+private:
+ TQPtrCollection::Item data;
+ TQLNode *prev;
+ TQLNode *next;
+ TQLNode( TQPtrCollection::Item d ) { data = d; }
+};
+
+class TQGListIteratorList; // internal helper class
+
+class TQ_EXPORT TQGList : public TQPtrCollection // doubly linked generic list
+{
+friend class TQGListIterator;
+friend class TQGListIteratorList;
+friend class TQGVector; // needed by TQGVector::toList
+public:
+ uint count() const; // return number of nodes
+
+#ifndef TQT_NO_DATASTREAM
+ TQDataStream &read( TQDataStream & ); // read list from stream
+ TQDataStream &write( TQDataStream & ) const; // write list to stream
+#endif
+protected:
+ TQGList(); // create empty list
+ TQGList( const TQGList & ); // make copy of other list
+ virtual ~TQGList();
+
+ TQGList &operator=( const TQGList & ); // assign from other list
+ bool operator==( const TQGList& ) const;
+
+ void inSort( TQPtrCollection::Item ); // add item sorted in list
+ void append( TQPtrCollection::Item ); // add item at end of list
+ bool insertAt( uint index, TQPtrCollection::Item ); // add item at i'th position
+ void relinkNode( TQLNode * ); // relink as first item
+ bool removeNode( TQLNode * ); // remove node
+ bool remove( TQPtrCollection::Item = 0 ); // remove item (0=current)
+ bool removeRef( TQPtrCollection::Item = 0 ); // remove item (0=current)
+ bool removeFirst(); // remove first item
+ bool removeLast(); // remove last item
+ bool removeAt( uint ); // remove item at i'th position
+ bool tqreplaceAt( uint, TQPtrCollection::Item ); // tqreplace item at position i with item
+ TQPtrCollection::Item takeNode( TQLNode * ); // take out node
+ TQPtrCollection::Item take(); // take out current item
+ TQPtrCollection::Item takeAt( uint index ); // take out item at i'th pos
+ TQPtrCollection::Item takeFirst(); // take out first item
+ TQPtrCollection::Item takeLast(); // take out last item
+
+ void sort(); // sort all items;
+ void clear(); // remove all items
+
+ int tqfindRef( TQPtrCollection::Item, bool = TRUE ); // tqfind exact item in list
+ int tqfind( TQPtrCollection::Item, bool = TRUE ); // tqfind equal item in list
+
+ uint tqcontainsRef( TQPtrCollection::Item ) const; // get number of exact matches
+ uint tqcontains( TQPtrCollection::Item ) const; // get number of equal matches
+
+ TQPtrCollection::Item at( uint index ); // access item at i'th pos
+ int at() const; // get current index
+ TQLNode *currentNode() const; // get current node
+
+ TQPtrCollection::Item get() const; // get current item
+
+ TQPtrCollection::Item cfirst() const; // get ptr to first list item
+ TQPtrCollection::Item clast() const; // get ptr to last list item
+ TQPtrCollection::Item first(); // set first item in list curr
+ TQPtrCollection::Item last(); // set last item in list curr
+ TQPtrCollection::Item next(); // set next item in list curr
+ TQPtrCollection::Item prev(); // set prev item in list curr
+
+ void toVector( TQGVector * ) const; // put items in vector
+
+ virtual int compareItems( TQPtrCollection::Item, TQPtrCollection::Item );
+
+#ifndef TQT_NO_DATASTREAM
+ virtual TQDataStream &read( TQDataStream &, TQPtrCollection::Item & );
+ virtual TQDataStream &write( TQDataStream &, TQPtrCollection::Item ) const;
+#endif
+
+ TQLNode* begin() const { return firstNode; }
+ TQLNode* end() const { return 0; }
+ TQLNode* erase( TQLNode* it );
+
+private:
+ void prepend( TQPtrCollection::Item ); // add item at start of list
+
+ void heapSortPushDown( TQPtrCollection::Item* heap, int first, int last );
+
+ TQLNode *firstNode; // first node
+ TQLNode *lastNode; // last node
+ TQLNode *curNode; // current node
+ int curIndex; // current index
+ uint numNodes; // number of nodes
+ TQGListIteratorList *iterators; // list of iterators
+
+ TQLNode *locate( uint ); // get node at i'th pos
+ TQLNode *unlink(); // unlink node
+};
+
+
+inline uint TQGList::count() const
+{
+ return numNodes;
+}
+
+inline bool TQGList::removeFirst()
+{
+ first();
+ return remove();
+}
+
+inline bool TQGList::removeLast()
+{
+ last();
+ return remove();
+}
+
+inline int TQGList::at() const
+{
+ return curIndex;
+}
+
+inline TQPtrCollection::Item TQGList::at( uint index )
+{
+ TQLNode *n = locate( index );
+ return n ? n->data : 0;
+}
+
+inline TQLNode *TQGList::currentNode() const
+{
+ return curNode;
+}
+
+inline TQPtrCollection::Item TQGList::get() const
+{
+ return curNode ? curNode->data : 0;
+}
+
+inline TQPtrCollection::Item TQGList::cfirst() const
+{
+ return firstNode ? firstNode->data : 0;
+}
+
+inline TQPtrCollection::Item TQGList::clast() const
+{
+ return lastNode ? lastNode->data : 0;
+}
+
+
+/*****************************************************************************
+ TQGList stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQGList & );
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQGList & );
+#endif
+
+/*****************************************************************************
+ TQGListIterator class
+ *****************************************************************************/
+
+class TQ_EXPORT TQGListIterator // TQGList iterator
+{
+friend class TQGList;
+friend class TQGListIteratorList;
+protected:
+ TQGListIterator( const TQGList & );
+ TQGListIterator( const TQGListIterator & );
+ TQGListIterator &operator=( const TQGListIterator & );
+ ~TQGListIterator();
+
+ bool atFirst() const; // test if at first item
+ bool atLast() const; // test if at last item
+ TQPtrCollection::Item toFirst(); // move to first item
+ TQPtrCollection::Item toLast(); // move to last item
+
+ TQPtrCollection::Item get() const; // get current item
+ TQPtrCollection::Item operator()(); // get current and move to next
+ TQPtrCollection::Item operator++(); // move to next item (prefix)
+ TQPtrCollection::Item operator+=(uint); // move n positions forward
+ TQPtrCollection::Item operator--(); // move to prev item (prefix)
+ TQPtrCollection::Item operator-=(uint); // move n positions backward
+
+protected:
+ TQGList *list; // reference to list
+
+private:
+ TQLNode *curNode; // current node in list
+};
+
+
+inline bool TQGListIterator::atFirst() const
+{
+ return curNode == list->firstNode;
+}
+
+inline bool TQGListIterator::atLast() const
+{
+ return curNode == list->lastNode;
+}
+
+inline TQPtrCollection::Item TQGListIterator::get() const
+{
+ return curNode ? curNode->data : 0;
+}
+
+class TQ_EXPORT TQGListStdIterator
+{
+public:
+ inline TQGListStdIterator( TQLNode* n ) : node( n ){}
+ inline operator TQLNode* () { return node; }
+protected:
+ inline TQLNode *next() { return node->next; }
+ TQLNode *node;
+};
+
+
+#endif // TQGLIST_H
diff --git a/tqtinterface/qt4/src/tools/tqglobal.cpp b/tqtinterface/qt4/src/tools/tqglobal.cpp
new file mode 100644
index 0000000..0d548ed
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqglobal.cpp
@@ -0,0 +1,927 @@
+/****************************************************************************
+**
+** Global functions
+**
+** Created : 920604
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+#include "tqasciidict.h"
+#include <limits.h>
+#include <stdio.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#if defined(TQ_CC_MSVC) && !defined(TQ_CC_MSVC_NET) && !defined(TQ_OS_TEMP)
+#include <crtdbg.h>
+#endif
+
+
+/*!
+ \relates TQApplication
+
+ Returns the TQt version number as a string, for example, "2.3.0" or
+ "3.0.5".
+
+ The \c TQT_VERSION define has the numeric value in the form:
+ 0xmmiibb (m = major, i = minor, b = bugfix). For example, TQt
+ 3.0.5's \c TQT_VERSION is 0x030005.
+*/
+
+const char *qVersion()
+{
+ return TQT_VERSION_STR;
+}
+
+bool qSharedBuild()
+{
+#ifdef TQT_SHARED
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+/*****************************************************************************
+ System detection routines
+ *****************************************************************************/
+
+static bool si_alreadyDone = FALSE;
+static int si_wordSize;
+static bool si_bigEndian;
+
+/*!
+ \relates TQApplication
+
+ Obtains information about the system.
+
+ The system's word size in bits (typically 32) is returned in \a
+ *wordSize. The \a *bigEndian is set to TRUE if this is a big-endian
+ machine, or to FALSE if this is a little-endian machine.
+
+ In debug mode, this function calls qFatal() with a message if the
+ computer is truly weird (i.e. different endianness for 16 bit and
+ 32 bit integers); in release mode it returns FALSE.
+*/
+
+bool qSysInfo( int *wordSize, bool *bigEndian )
+{
+#if defined(TQT_CHECK_NULL)
+ TQ_ASSERT( wordSize != 0 );
+ TQ_ASSERT( bigEndian != 0 );
+#endif
+
+ if ( si_alreadyDone ) { // run it only once
+ *wordSize = si_wordSize;
+ *bigEndian = si_bigEndian;
+ return TRUE;
+ }
+
+ si_wordSize = 0;
+ TQ_ULONG n = (TQ_ULONG)(~0);
+ while ( n ) { // detect word size
+ si_wordSize++;
+ n /= 2;
+ }
+ *wordSize = si_wordSize;
+
+ if ( *wordSize != 64 &&
+ *wordSize != 32 &&
+ *wordSize != 16 ) { // word size: 16, 32 or 64
+#if defined(TQT_CHECK_RANGE)
+ qFatal( "qSysInfo: Unsupported system word size %d", *wordSize );
+#endif
+ return FALSE;
+ }
+ if ( sizeof(TQ_INT8) != 1 || sizeof(TQ_INT16) != 2 || sizeof(TQ_INT32) != 4 ||
+ sizeof(TQ_ULONG)*8 != si_wordSize || sizeof(float) != 4 || sizeof(double) != 8 ) {
+#if defined(TQT_CHECK_RANGE)
+ qFatal( "qSysInfo: Unsupported system data type size" );
+#endif
+ return FALSE;
+ }
+
+ bool be16, be32; // determine byte ordering
+ short ns = 0x1234;
+ int nl = 0x12345678;
+
+ unsigned char *p = (unsigned char *)(&ns); // 16-bit integer
+ be16 = *p == 0x12;
+
+ p = (unsigned char *)(&nl); // 32-bit integer
+ if ( p[0] == 0x12 && p[1] == 0x34 && p[2] == 0x56 && p[3] == 0x78 )
+ be32 = TRUE;
+ else
+ if ( p[0] == 0x78 && p[1] == 0x56 && p[2] == 0x34 && p[3] == 0x12 )
+ be32 = FALSE;
+ else
+ be32 = !be16;
+
+ if ( be16 != be32 ) { // strange machine!
+#if defined(TQT_CHECK_RANGE)
+ qFatal( "qSysInfo: Inconsistent system byte order" );
+#endif
+ return FALSE;
+ }
+
+ *bigEndian = si_bigEndian = be32;
+ si_alreadyDone = TRUE;
+ return TRUE;
+}
+
+#if !defined(TQWS) && defined(TQ_OS_MAC)
+
+#include "tqt_mac.h"
+
+// This function has descended from Apple Source Code (FSpLocationFromFullPath),
+// but changes have been made. [Creates a minimal alias from the full pathname]
+OSErr qt_mac_create_fsspec(const TQString &file, FSSpec *spec)
+{
+ FSRef fref;
+ TQCString utfs = file.utf8();
+ OSErr ret = FSPathMakeRef((const UInt8 *)utfs.data(), &fref, NULL);
+ if(ret == noErr)
+ ret = FSGetCatalogInfo(&fref, kFSCatInfoNone, NULL, NULL, spec, NULL);
+ return ret;
+}
+
+CFStringRef qstring2cfstring(const TQString &str)
+{
+ return CFStringCreateWithCharacters(0, (UniChar *)str.tqunicode(), str.length());
+}
+
+TQString cfstring2qstring(CFStringRef str)
+{
+ if(!str)
+ return TQString();
+
+ CFIndex length = CFStringGetLength(str);
+ if(const UniChar *chars = CFStringGetCharactersPtr(str))
+ return TQString((TQChar *)chars, length);
+ UniChar *buffer = (UniChar*)malloc(length * sizeof(UniChar));
+ CFStringGetCharacters(str, CFRangeMake(0, length), buffer);
+ TQString ret((TQChar *)buffer, length);
+ free(buffer);
+ return ret;
+}
+
+unsigned char *p_str(const TQString &s)
+{
+ CFStringRef cfstr = qstring2cfstring(s);
+ uchar *p = (uchar*)malloc(256);
+ CFStringGetPascalString(cfstr, p, 256, CFStringGetSystemEncoding());
+ CFRelease(cfstr);
+ return p;
+}
+
+TQString p2qstring(const unsigned char *c) {
+ CFStringRef cfstr = CFStringCreateWithPascalString(0, c, CFStringGetSystemEncoding());
+ TQString str = cfstring2qstring(cfstr);
+ CFRelease(cfstr);
+ return str;
+}
+
+int qMacVersion()
+{
+ static int macver = TQt::MV_Unknown;
+ static bool first = TRUE;
+ if(first) {
+ first = FALSE;
+ long gestalt_version;
+ if(Gestalt(gestaltSystemVersion, &gestalt_version) == noErr) {
+ macver = ((gestalt_version & 0x00f0) >> 4) + 2;
+
+ }
+ }
+ return macver;
+}
+TQt::MacintoshVersion qt_macver = (TQt::MacintoshVersion)qMacVersion();
+
+// HFS+ filesystems use decomposing tqunicode for certain layers in tqunicode
+// In general these don't look great as a user visible string.
+// Therefore it is a good idea to normalize them ourselves.
+// These technotes on Apple's website:
+// http://developer.apple.com/qa/qa2001/qa1235.html
+// http://developer.apple.com/qa/qa2001/qa1173.html
+TQString qt_mac_precomposeFileName(const TQString &str)
+{
+ if (str.isEmpty())
+ return str;
+ int strLength = str.length();
+ CFMutableStringRef cfmstr = CFStringCreateMutable(0, strLength);
+ CFStringAppendCharacters(cfmstr, (UniChar *)str.tqunicode(), strLength);
+ CFStringNormalize(cfmstr, kCFStringNormalizationFormC);
+ TQString newStr = cfstring2qstring(cfmstr);
+ CFRelease(cfmstr);
+ return newStr;
+}
+#elif defined(TQ_OS_WIN32) || defined(TQ_OS_CYGWIN) || defined(TQ_OS_TEMP)
+bool qt_wintqunicode;
+# ifdef TQ_OS_TEMP
+ DWORD qt_cever = 0;
+# endif // TQ_OS_TEMP
+
+#include "tqt_windows.h"
+
+int qWinVersion()
+{
+#ifndef VER_PLATFORM_WIN32s
+#define VER_PLATFORM_WIN32s 0
+#endif
+#ifndef VER_PLATFORM_WIN32_WINDOWS
+#define VER_PLATFORM_WIN32_WINDOWS 1
+#endif
+#ifndef VER_PLATFORM_WIN32_NT
+#define VER_PLATFORM_WIN32_NT 2
+#endif
+#ifndef VER_PLATFORM_WIN32_CE
+#define VER_PLATFORM_WIN32_CE 3
+#endif
+
+ static int winver = TQt::WV_NT;
+ static int t=0;
+ if ( !t ) {
+ t=1;
+#ifndef TQ_OS_TEMP
+ OSVERSIONINFOA osver;
+ osver.dwOSVersionInfoSize = sizeof(osver);
+ GetVersionExA( &osver );
+#else
+ OSVERSIONINFOW osver;
+ osver.dwOSVersionInfoSize = sizeof(osver);
+ GetVersionEx( &osver );
+ qt_cever = osver.dwMajorVersion * 100;
+ qt_cever += osver.dwMinorVersion * 10;
+#endif
+ switch ( osver.dwPlatformId ) {
+ case VER_PLATFORM_WIN32s:
+ winver = TQt::WV_32s;
+ break;
+ case VER_PLATFORM_WIN32_WINDOWS:
+ // We treat Windows Me (minor 90) the same as Windows 98
+ if ( osver.dwMinorVersion == 90 )
+ winver = TQt::WV_Me;
+ else if ( osver.dwMinorVersion == 10 )
+ winver = TQt::WV_98;
+ else
+ winver = TQt::WV_95;
+ break;
+ case VER_PLATFORM_WIN32_CE:
+#ifdef TQ_OS_TEMP
+ if ( qt_cever >= 400 )
+ winver = TQt::WV_CENET;
+ else
+#endif
+ winver = TQt::WV_CE;
+ break;
+ default: // VER_PLATFORM_WIN32_NT
+ if ( osver.dwMajorVersion < 5 ) {
+ winver = TQt::WV_NT;
+ } else if (osver.dwMajorVersion == 6) {
+ winver = TQt::WV_VISTA;
+ } else if ( osver.dwMinorVersion == 0 ) {
+ winver = TQt::WV_2000;
+ } else if ( osver.dwMinorVersion == 1 ) {
+ winver = TQt::WV_XP;
+ } else if ( osver.dwMinorVersion == 2 ) {
+ winver = TQt::WV_2003;
+ } else {
+ qWarning("Untested Windows version detected!");
+ winver = TQt::WV_NT_based;
+ }
+ }
+ }
+
+#if defined(UNICODE)
+ if ( winver & TQt::WV_NT_based )
+ qt_wintqunicode = TRUE;
+ else
+#endif
+ qt_wintqunicode = FALSE;
+
+ return winver;
+}
+
+TQt::WindowsVersion qt_winver = (TQt::WindowsVersion)qWinVersion();
+#endif
+
+
+/*****************************************************************************
+ Debug output routines
+ *****************************************************************************/
+
+/*!
+ \fn void qDebug( const char *msg, ... )
+
+ \relates TQApplication
+
+ Prints a debug message \a msg, or calls the message handler (if it
+ has been installed).
+
+ This function takes a format string and a list of arguments,
+ similar to the C printf() function.
+
+ Example:
+ \code
+ qDebug( "my window handle = %x", myWidget->id() );
+ \endcode
+
+ Under X11, the text is printed to stderr. Under Windows, the text
+ is sent to the debugger.
+
+ \warning The internal buffer is limited to 8196 bytes (including
+ the '\0'-terminator).
+
+ \warning Passing (const char *)0 as argument to qDebug might lead
+ to crashes on certain platforms due to the platforms printf implementation.
+
+ \sa qWarning(), qFatal(), tqInstallMsgHandler(),
+ \link debug.html Debugging\endlink
+*/
+
+/*!
+ \fn void qWarning( const char *msg, ... )
+
+ \relates TQApplication
+
+ Prints a warning message \a msg, or calls the message handler (if
+ it has been installed).
+
+ This function takes a format string and a list of arguments,
+ similar to the C printf() function.
+
+ Example:
+ \code
+ void f( int c )
+ {
+ if ( c > 200 )
+ qWarning( "f: bad argument, c == %d", c );
+ }
+ \endcode
+
+ Under X11, the text is printed to stderr. Under Windows, the text
+ is sent to the debugger.
+
+ \warning The internal buffer is limited to 8196 bytes (including
+ the '\0'-terminator).
+
+ \warning Passing (const char *)0 as argument to qWarning might lead
+ to crashes on certain platforms due to the platforms printf implementation.
+
+ \sa qDebug(), qFatal(), tqInstallMsgHandler(),
+ \link debug.html Debugging\endlink
+*/
+
+/*!
+ \fn void qFatal( const char *msg, ... )
+
+ \relates TQApplication
+
+ Prints a fatal error message \a msg and exits, or calls the
+ message handler (if it has been installed).
+
+ This function takes a format string and a list of arguments,
+ similar to the C printf() function.
+
+ Example:
+ \code
+ int divide( int a, int b )
+ {
+ if ( b == 0 ) // program error
+ qFatal( "divide: cannot divide by zero" );
+ return a/b;
+ }
+ \endcode
+
+ Under X11, the text is printed to stderr. Under Windows, the text
+ is sent to the debugger.
+
+ \warning The internal buffer is limited to 8196 bytes (including
+ the '\0'-terminator).
+
+ \warning Passing (const char *)0 as argument to qFatal might lead
+ to crashes on certain platforms due to the platforms printf implementation.
+
+ \sa qDebug(), qWarning(), tqInstallMsgHandler(),
+ \link debug.html Debugging\endlink
+*/
+
+
+static TQtMsgHandler handler = 0; // pointer to debug handler
+static const int TQT_BUFFER_LENGTH = 8196; // internal buffer length
+
+
+#ifdef TQ_CC_MWERKS
+
+#include "tqt_mac.h"
+
+extern bool qt_is_gui_used;
+static void mac_default_handler( const char *msg )
+{
+ if ( qt_is_gui_used ) {
+ const unsigned char *p = p_str(msg);
+ DebugStr(p);
+ free((void*)p);
+ } else {
+ fprintf( stderr, msg );
+ }
+}
+
+#endif
+
+
+void qDebug( const char *msg, ... )
+{
+ char buf[TQT_BUFFER_LENGTH];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+#if defined(TQT_VSNPRINTF)
+ TQT_VSNPRINTF( buf, TQT_BUFFER_LENGTH, msg, ap );
+#else
+ vsprintf( buf, msg, ap );
+#endif
+ va_end( ap );
+ if ( handler ) {
+ (*handler)( TQtDebugMsg, buf );
+ } else {
+#if defined(TQ_CC_MWERKS)
+ mac_default_handler(buf);
+#elif defined(TQ_OS_TEMP)
+ TQString fstr( buf );
+ OutputDebugString( (fstr + "\n").ucs2() );
+#else
+ fprintf( stderr, "%s\n", buf ); // add newline
+#endif
+ }
+}
+
+// copied... this looks really bad.
+void debug( const char *msg, ... )
+{
+ char buf[TQT_BUFFER_LENGTH];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+#if defined(TQT_VSNPRINTF)
+ TQT_VSNPRINTF( buf, TQT_BUFFER_LENGTH, msg, ap );
+#else
+ vsprintf( buf, msg, ap );
+#endif
+ va_end( ap );
+ if ( handler ) {
+ (*handler)( TQtDebugMsg, buf );
+ } else {
+#if defined(TQ_CC_MWERKS)
+ mac_default_handler(buf);
+#elif defined(TQ_OS_TEMP)
+ TQString fstr( buf );
+ OutputDebugString( (fstr + "\n").ucs2() );
+#else
+ fprintf( stderr, "%s\n", buf ); // add newline
+#endif
+ }
+}
+
+void qWarning( const char *msg, ... )
+{
+ char buf[TQT_BUFFER_LENGTH];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+#if defined(TQT_VSNPRINTF)
+ TQT_VSNPRINTF( buf, TQT_BUFFER_LENGTH, msg, ap );
+#else
+ vsprintf( buf, msg, ap );
+#endif
+ va_end( ap );
+ if ( handler ) {
+ (*handler)( TQtWarningMsg, buf );
+ } else {
+#if defined(TQ_CC_MWERKS)
+ mac_default_handler(buf);
+#elif defined(TQ_OS_TEMP)
+ TQString fstr( buf );
+ OutputDebugString( (fstr + "\n").ucs2() );
+#else
+ fprintf( stderr, "%s\n", buf ); // add newline
+#endif
+ }
+}
+
+
+// again, copied
+void warning( const char *msg, ... )
+{
+ char buf[TQT_BUFFER_LENGTH];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+#if defined(TQT_VSNPRINTF)
+ TQT_VSNPRINTF( buf, TQT_BUFFER_LENGTH, msg, ap );
+#else
+ vsprintf( buf, msg, ap );
+#endif
+ va_end( ap );
+ if ( handler ) {
+ (*handler)( TQtWarningMsg, buf );
+ } else {
+#if defined(TQ_CC_MWERKS)
+ mac_default_handler(buf);
+#elif defined(TQ_OS_TEMP)
+ TQString fstr( buf );
+ OutputDebugString( (fstr + "\n").ucs2() );
+#else
+ fprintf( stderr, "%s\n", buf ); // add newline
+#endif
+ }
+}
+
+void qFatal( const char *msg, ... )
+{
+ char buf[TQT_BUFFER_LENGTH];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+#if defined(TQT_VSNPRINTF)
+ TQT_VSNPRINTF( buf, TQT_BUFFER_LENGTH, msg, ap );
+#else
+ vsprintf( buf, msg, ap );
+#endif
+ va_end( ap );
+ if ( handler ) {
+ (*handler)( TQtFatalMsg, buf );
+ } else {
+#if defined(TQ_CC_MWERKS)
+ mac_default_handler(buf);
+#else
+ fprintf( stderr, "%s\n", buf ); // add newline
+#endif
+#if defined(TQ_OS_UNIX) && defined(TQT_DEBUG)
+ abort(); // trap; generates core dump
+#elif defined(TQ_OS_TEMP) && defined(TQT_DEBUG)
+ TQString fstr;
+ fstr.sprintf( "%s:%s %s %s\n", __FILE__, __LINE__, TQT_VERSION_STR, buf );
+ OutputDebugString( fstr.ucs2() );
+#elif defined(_CRT_ERROR) && defined(_DEBUG)
+ _CrtDbgReport( _CRT_ERROR, __FILE__, __LINE__, TQT_VERSION_STR, buf );
+#else
+ exit( 1 ); // goodbye cruel world
+#endif
+ }
+}
+
+// yet again, copied
+void fatal( const char *msg, ... )
+{
+ char buf[TQT_BUFFER_LENGTH];
+ va_list ap;
+ va_start( ap, msg ); // use variable arg list
+#if defined(TQT_VSNPRINTF)
+ TQT_VSNPRINTF( buf, TQT_BUFFER_LENGTH, msg, ap );
+#else
+ vsprintf( buf, msg, ap );
+#endif
+ va_end( ap );
+ if ( handler ) {
+ (*handler)( TQtFatalMsg, buf );
+ } else {
+#if defined(TQ_CC_MWERKS)
+ mac_default_handler(buf);
+#else
+ fprintf( stderr, "%s\n", buf ); // add newline
+#endif
+#if defined(TQ_OS_UNIX) && defined(TQT_DEBUG)
+ abort(); // trap; generates core dump
+#elif defined(TQ_OS_TEMP) && defined(TQT_DEBUG)
+ TQString fstr;
+ fstr.sprintf( "%s:%s %s %s\n", __FILE__, __LINE__, TQT_VERSION_STR, buf );
+ OutputDebugString( fstr.ucs2() );
+#elif defined(_CRT_ERROR) && defined(_DEBUG)
+ _CrtDbgReport( _CRT_ERROR, __FILE__, __LINE__, TQT_VERSION_STR, buf );
+#else
+ exit( 1 ); // goodbye cruel world
+#endif
+ }
+}
+
+/*!
+ \relates TQApplication
+
+ Prints the message \a msg and uses \a code to get a system specific
+ error message. When \a code is -1 (the default), the system's last
+ error code will be used if possible. Use this method to handle
+ failures in platform specific API calls.
+
+ This function does nothing when TQt is built with \c TQT_NO_DEBUG
+ defined.
+*/
+void tqSystemWarning( const char* msg, int code )
+{
+#ifndef TQT_NO_DEBUG
+#if defined(TQ_OS_WIN32)
+ if ( code == -1 )
+ code = GetLastError();
+
+ if ( !code )
+ return;
+
+ unsigned short *string;
+ TQT_WA( {
+ FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ code,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&string,
+ 0,
+ NULL );
+
+ qWarning( "%s\n\tError code %d - %s", msg, code, TQString::fromUcs2(string).latin1() );
+ }, {
+ FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ code,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (char*)&string,
+ 0,
+ NULL );
+
+ qWarning( "%s\n\tError code %d - %s", msg, code, (const char*)string );
+ } );
+ LocalFree( (HLOCAL)string );
+#else
+ if ( code != -1 )
+ qWarning( "%s\n\tError code %d - %s", msg, code, strerror( code ) );
+ else
+ qWarning( "%s", msg );
+#endif
+#else
+ TQ_UNUSED( msg );
+ TQ_UNUSED( code );
+#endif
+}
+
+/*!
+ \fn void TQ_ASSERT( bool test )
+
+ \relates TQApplication
+
+ Prints a warning message containing the source code file name and
+ line number if \a test is FALSE.
+
+ This is really a macro defined in \c tqglobal.h.
+
+ TQ_ASSERT is useful for testing pre- and post-conditions.
+
+ Example:
+ \code
+ //
+ // File: div.cpp
+ //
+
+ #include <tqglobal.h>
+
+ int divide( int a, int b )
+ {
+ TQ_ASSERT( b != 0 ); // this is line 9
+ return a/b;
+ }
+ \endcode
+
+ If \c b is zero, the TQ_ASSERT statement will output the following
+ message using the qWarning() function:
+ \code
+ ASSERT: "b != 0" in div.cpp (9)
+ \endcode
+
+ \sa qWarning(), \link debug.html Debugging\endlink
+*/
+
+
+/*!
+ \fn void TQ_CHECK_PTR( void *p )
+
+ \relates TQApplication
+
+ If \a p is 0, prints a warning message containing the source code file
+ name and line number, saying that the program ran out of memory.
+
+ This is really a macro defined in \c tqglobal.h.
+
+ Example:
+ \code
+ int *a;
+
+ TQ_CHECK_PTR( a = new int[80] ); // WRONG!
+
+ a = new (nothrow) int[80]; // Right
+ TQ_CHECK_PTR( a );
+ \endcode
+
+ \sa qWarning(), \link debug.html Debugging\endlink
+*/
+
+
+//
+// The TQ_CHECK_PTR macro calls this function to check if an allocation went ok.
+//
+#if (TQT_VERSION-0 >= 0x040000)
+#if defined(TQ_CC_GNU)
+#warning "Change TQ_CHECK_PTR to '{if ((p)==0) qt_check_pointer(__FILE__,__LINE__);}'"
+#warning "No need for qt_check_pointer() to return a value - make it void!"
+#endif
+#endif
+bool qt_check_pointer( bool c, const char *n, int l )
+{
+ if ( c )
+ qWarning( "In file %s, line %d: Out of memory", n, l );
+ return TRUE;
+}
+
+
+static bool firstObsoleteWarning(const char *obj, const char *oldfunc )
+{
+ static TQAsciiDict<int> *obsoleteDict = 0;
+ if ( !obsoleteDict ) { // first time func is called
+ obsoleteDict = new TQAsciiDict<int>;
+#if defined(TQT_DEBUG)
+ qDebug(
+ "You are using obsolete functions in the TQt library. Call the function\n"
+ "tqSuppressObsoleteWarnings() to suppress obsolete warnings.\n"
+ );
+#endif
+ }
+ TQCString s( obj );
+ s += "::";
+ s += oldfunc;
+ if ( obsoleteDict->tqfind(s.data()) == 0 ) {
+ obsoleteDict->insert( s.data(), (int*)1 ); // anything different from 0
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static bool suppressObsolete = FALSE;
+
+void tqSuppressObsoleteWarnings( bool suppress )
+{
+ suppressObsolete = suppress;
+}
+
+void qObsolete( const char *obj, const char *oldfunc, const char *newfunc )
+{
+ if ( suppressObsolete )
+ return;
+ if ( !firstObsoleteWarning(obj, oldfunc) )
+ return;
+ if ( obj )
+ qDebug( "%s::%s: This function is obsolete, use %s instead.",
+ obj, oldfunc, newfunc );
+ else
+ qDebug( "%s: This function is obsolete, use %s instead.",
+ oldfunc, newfunc );
+}
+
+void qObsolete( const char *obj, const char *oldfunc )
+{
+ if ( suppressObsolete )
+ return;
+ if ( !firstObsoleteWarning(obj, oldfunc) )
+ return;
+ if ( obj )
+ qDebug( "%s::%s: This function is obsolete.", obj, oldfunc );
+ else
+ qDebug( "%s: This function is obsolete.", oldfunc );
+}
+
+void qObsolete( const char *message )
+{
+ if ( suppressObsolete )
+ return;
+ if ( !firstObsoleteWarning( "TQt", message) )
+ return;
+ qDebug( "%s", message );
+}
+
+
+/*!
+ \relates TQApplication
+
+ Installs a TQt message handler \a h. Returns a pointer to the
+ message handler previously defined.
+
+ The message handler is a function that prints out debug messages,
+ warnings and fatal error messages. The TQt library (debug version)
+ tqcontains hundreds of warning messages that are printed when
+ internal errors (usually invalid function arguments) occur. If you
+ implement your own message handler, you get total control of these
+ messages.
+
+ The default message handler prints the message to the standard
+ output under X11 or to the debugger under Windows. If it is a
+ fatal message, the application aborts immediately.
+
+ Only one message handler can be defined, since this is usually
+ done on an application-wide basis to control debug output.
+
+ To restore the message handler, call \c tqInstallMsgHandler(0).
+
+ Example:
+ \code
+ #include <tqapplication.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ void myMessageOutput( TQtMsgType type, const char *msg )
+ {
+ switch ( type ) {
+ case TQtDebugMsg:
+ fprintf( stderr, "Debug: %s\n", msg );
+ break;
+ case TQtWarningMsg:
+ fprintf( stderr, "Warning: %s\n", msg );
+ break;
+ case TQtFatalMsg:
+ fprintf( stderr, "Fatal: %s\n", msg );
+ abort(); // deliberately core dump
+ }
+ }
+
+ int main( int argc, char **argv )
+ {
+ tqInstallMsgHandler( myMessageOutput );
+ TQApplication a( argc, argv );
+ ...
+ return a.exec();
+ }
+ \endcode
+
+ \sa qDebug(), qWarning(), qFatal(), \link debug.html Debugging\endlink
+*/
+
+TQtMsgHandler tqInstallMsgHandler( TQtMsgHandler h )
+{
+ TQtMsgHandler old = handler;
+ handler = h;
+ return old;
+}
+
+
+/*
+ Dijkstra's bisection algorithm to tqfind the square root as an integer.
+ Deliberately not exported as part of the TQt API, but used in both
+ qsimplerichtext.cpp and qgfxraster_qws.cpp
+*/
+unsigned int qt_int_sqrt( unsigned int n )
+{
+ // n must be in the range 0...UINT_MAX/2-1
+ if ( n >= ( UINT_MAX>>2 ) ) {
+ unsigned int r = 2 * qt_int_sqrt( n / 4 );
+ unsigned int r2 = r + 1;
+ return ( n >= r2 * r2 ) ? r2 : r;
+ }
+ uint h, p= 0, q= 1, r= n;
+ while ( q <= n )
+ q <<= 2;
+ while ( q != 1 ) {
+ q >>= 2;
+ h= p + q;
+ p >>= 1;
+ if ( r >= h ) {
+ p += q;
+ r -= h;
+ }
+ }
+ return p;
+}
+
diff --git a/tqtinterface/qt4/src/tools/tqglobal.h b/tqtinterface/qt4/src/tools/tqglobal.h
new file mode 100644
index 0000000..3fe0fb0
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqglobal.h
@@ -0,0 +1,1135 @@
+/****************************************************************************
+**
+** Global type declarations and definitions
+**
+** Created : 920529
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGLOBAL_H
+#define TQGLOBAL_H
+
+#define TQT_VERSION_STR "3.4.0"
+/*
+ TQT_VERSION is (major << 16) + (minor << 8) + patch.
+ */
+#define TQT_VERSION 0x030400
+
+/*
+ The operating system, must be one of: (TQ_OS_x)
+
+ MACX - Mac OS X
+ MAC9 - Mac OS 9
+ DARWIN - Darwin OS (Without Mac OS X)
+ MSDOS - MS-DOS and Windows
+ OS2 - OS/2
+ OS2EMX - XFree86 on OS/2 (not PM)
+ WIN32 - Win32 (Windows 95/98/ME and Windows NT/2000/XP)
+ CYGWIN - Cygwin
+ SOLARIS - Sun Solaris
+ HPUX - HP-UX
+ ULTRIX - DEC Ultrix
+ LINUX - Linux
+ FREEBSD - FreeBSD
+ NETBSD - NetBSD
+ OPENBSD - OpenBSD
+ BSDI - BSD/OS
+ IRIX - SGI Irix
+ OSF - HP Tru64 UNIX
+ SCO - SCO OpenServer 5
+ UNIXWARE - UnixWare 7, Open UNIX 8
+ AIX - AIX
+ HURD - GNU Hurd
+ DGUX - DG/UX
+ RELIANT - Reliant UNIX
+ DYNIX - DYNIX/ptx
+ TQNX - TQNX
+ TQNX6 - TQNX RTP 6.1
+ LYNX - LynxOS
+ BSD4 - Any BSD 4.4 system
+ UNIX - Any UNIX BSD/SYSV system
+*/
+
+#if defined(__DARWIN_X11__)
+# define TQ_OS_DARWIN
+#elif defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__))
+# define TQ_OS_MACX
+#elif defined(__MACOSX__)
+# define TQ_OS_MACX
+#elif defined(macintosh)
+# define TQ_OS_MAC9
+#elif defined(__CYGWIN__)
+# define TQ_OS_CYGWIN
+#elif defined(MSDOS) || defined(_MSDOS)
+# define TQ_OS_MSDOS
+#elif defined(__OS2__)
+# if defined(__EMX__)
+# define TQ_OS_OS2EMX
+# else
+# define TQ_OS_OS2
+# endif
+#elif !defined(SAG_COM) && (defined(WIN64) || defined(_WIN64) || defined(__WIN64__))
+# define TQ_OS_WIN32
+# define TQ_OS_WIN64
+#elif !defined(SAG_COM) && (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__))
+# define TQ_OS_WIN32
+#elif defined(__MWERKS__) && defined(__INTEL__)
+# define TQ_OS_WIN32
+#elif defined(__sun) || defined(sun)
+# define TQ_OS_SOLARIS
+#elif defined(hpux) || defined(__hpux)
+# define TQ_OS_HPUX
+#elif defined(__ultrix) || defined(ultrix)
+# define TQ_OS_ULTRIX
+#elif defined(sinix)
+# define TQ_OS_RELIANT
+#elif defined(__linux__) || defined(__linux)
+# define TQ_OS_LINUX
+#elif defined(__FreeBSD__) || defined(__DragonFly__)
+# define TQ_OS_FREEBSD
+# define TQ_OS_BSD4
+#elif defined(__NetBSD__)
+# define TQ_OS_NETBSD
+# define TQ_OS_BSD4
+#elif defined(__OpenBSD__)
+# define TQ_OS_OPENBSD
+# define TQ_OS_BSD4
+#elif defined(__bsdi__)
+# define TQ_OS_BSDI
+# define TQ_OS_BSD4
+#elif defined(__sgi)
+# define TQ_OS_IRIX
+#elif defined(__osf__)
+# define TQ_OS_OSF
+#elif defined(_AIX)
+# define TQ_OS_AIX
+#elif defined(__Lynx__)
+# define TQ_OS_LYNX
+#elif defined(__GNU_HURD__)
+# define TQ_OS_HURD
+#elif defined(__DGUX__)
+# define TQ_OS_DGUX
+#elif defined(__TQNXNTO__)
+# define TQ_OS_TQNX6
+#elif defined(__TQNX__)
+# define TQ_OS_TQNX
+#elif defined(_SETQUENT_)
+# define TQ_OS_DYNIX
+#elif defined(_SCO_DS) /* SCO OpenServer 5 + GCC */
+# define TQ_OS_SCO
+#elif defined(__USLC__) /* all SCO platforms + UDK or OUDK */
+# define TQ_OS_UNIXWARE
+# define TQ_OS_UNIXWARE7
+#elif defined(__svr4__) && defined(i386) /* Open UNIX 8 + GCC */
+# define TQ_OS_UNIXWARE
+# define TQ_OS_UNIXWARE7
+#elif defined(__MAKEDEPEND__)
+#else
+# error "TQt has not been ported to this OS - talk to qt-bugs@trolltech.com"
+#endif
+
+#if defined(TQ_OS_WIN32) || defined(TQ_OS_WIN64)
+# define TQ_OS_WIN
+#endif
+
+#if defined(TQ_OS_MAC9) || defined(TQ_OS_MACX)
+# define TQ_OS_MAC
+#endif
+
+#if defined(TQ_OS_MAC9) || defined(TQ_OS_MSDOS) || defined(TQ_OS_OS2) || defined(TQ_OS_WIN)
+# undef TQ_OS_UNIX
+#elif !defined(TQ_OS_UNIX)
+# define TQ_OS_UNIX
+#endif
+
+#if defined(TQ_OS_MACX)
+# ifdef MAC_OS_X_VERSION_MIN_RETQUIRED
+# undef MAC_OS_X_VERSION_MIN_RETQUIRED
+# endif
+# define MAC_OS_X_VERSION_MIN_RETQUIRED MAC_OS_X_VERSION_10_2
+# include <AvailabilityMacros.h>
+# if !defined(MAC_OS_X_VERSION_10_3)
+# define MAC_OS_X_VERSION_10_3 MAC_OS_X_VERSION_10_2 + 1
+# endif
+# if !defined(MAC_OS_X_VERSION_10_4)
+# define MAC_OS_X_VERSION_10_4 MAC_OS_X_VERSION_10_3 + 1
+# endif
+# if (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_4)
+# error "This version of Mac OS X is unsupported"
+# endif
+#endif
+
+
+/*
+ The compiler, must be one of: (TQ_CC_x)
+
+ SYM - Symantec C++ for both PC and Macintosh
+ MPW - MPW C++
+ MWERKS - Metrowerks CodeWarrior
+ MSVC - Microsoft Visual C/C++, Intel C++ for Windows
+ BOR - Borland/Turbo C++
+ WAT - Watcom C++
+ GNU - GNU C++
+ COMEAU - Comeau C++
+ EDG - Edison Design Group C++
+ OC - CenterLine C++
+ SUN - Sun WorkShop, Forte Developer, or Sun ONE Studio C++
+ MIPS - MIPSpro C++
+ DEC - DEC C++
+ HP - HPUX C++
+ HPACC - HPUX ANSI C++
+ USLC - SCO OUDK, UDK, and UnixWare 2.X C++
+ CDS - Reliant C++
+ KAI - KAI C++
+ INTEL - Intel C++ for Linux, Intel C++ for Windows
+ HIGHC - MetaWare High C/C++
+ PGI - Portland Group C++
+ GHS - Green Hills Optimizing C++ Compilers
+
+ Should be sorted most to least authoritative.
+*/
+
+/* Symantec C++ is now Digital Mars */
+#if defined(__DMC__) || defined(__SC__)
+# define TQ_CC_SYM
+/* "explicit" semantics implemented in 8.1e but keyword recognized since 7.5 */
+# if defined(__SC__) && __SC__ < 0x750
+# define TQ_NO_EXPLICIT_KEYWORD
+# endif
+# define TQ_NO_USING_KEYWORD
+# if !defined(_CPPUNWIND)
+# define TQ_NO_EXCEPTIONS
+# endif
+
+#elif defined(applec)
+# define TQ_CC_MPW
+# define TQ_NO_BOOL_TYPE
+# define TQ_NO_EXPLICIT_KEYWORD
+# define TQ_NO_USING_KEYWORD
+
+#elif defined(__MWERKS__)
+# define TQ_CC_MWERKS
+/* "explicit" recognized since 4.0d1 */
+# define TQMAC_PASCAL pascal
+
+#elif defined(_MSC_VER)
+# define TQ_CC_MSVC
+/* proper support of bool for _MSC_VER >= 1100 */
+# define TQ_CANNOT_DELETE_CONSTANT
+# define TQ_INLINE_TEMPLATES inline
+/* Visual C++.Net issues for _MSC_VER >= 1300 */
+# if _MSC_VER >= 1300
+# define TQ_CC_MSVC_NET
+# if _MSC_VER < 1310 || (defined(TQ_OS_WIN64) && defined(_M_IA64))
+# define TQ_TYPENAME
+# endif
+# endif
+/* Intel C++ disguising as Visual C++: the `using' keyword avoids warnings */
+# if defined(__INTEL_COMPILER)
+# define TQ_CC_INTEL
+# if !defined(__EXCEPTIONS)
+# define TQ_NO_EXCEPTIONS
+# endif
+# else
+# define TQ_NO_USING_KEYWORD /* ### check "using" status */
+# endif
+
+#elif defined(__BORLANDC__) || defined(__TURBOC__)
+# define TQ_CC_BOR
+# if __BORLANDC__ < 0x502
+# define TQ_NO_BOOL_TYPE
+# define TQ_NO_EXPLICIT_KEYWORD
+# endif
+# define TQ_NO_USING_KEYWORD /* ### check "using" status */
+
+#elif defined(__WATCOMC__)
+# define TQ_CC_WAT
+# if defined(TQ_OS_TQNX4)
+/* compiler flags */
+# define TQ_TYPENAME
+# define TQ_NO_BOOL_TYPE
+# define TQ_CANNOT_DELETE_CONSTANT
+# define mutable
+/* ??? */
+# define TQ_BROKEN_TEMPLATE_SPECIALIZATION
+/* no template classes in TQVariant */
+# define TQT_NO_TEMPLATE_VARIANT
+/* Wcc does not fill in functions needed by valuelists, maps, and
+ valuestacks implicitly */
+# define TQ_FULL_TEMPLATE_INSTANTIATION
+/* can we just compare the structures? */
+# define TQ_FULL_TEMPLATE_INSTANTIATION_MEMCMP
+/* these are not useful to our customers */
+# define TQT_TQWS_NO_SHM
+# define TQT_NO_TQWS_MULTIPROCESS
+# define TQT_NO_SQL
+# define TQT_NO_TQWS_CURSOR
+# endif
+
+#elif defined(__GNUC__)
+# define TQ_CC_GNU
+# define TQ_C_CALLBACKS
+# if __GNUC__ == 2 && __GNUC_MINOR__ <= 7
+# define TQ_FULL_TEMPLATE_INSTANTIATION
+# endif
+/* GCC 2.95 knows "using" but does not support it correctly */
+# if __GNUC__ == 2 && __GNUC_MINOR__ <= 95
+# define TQ_NO_USING_KEYWORD
+# endif
+/* GCC 3.1 and GCC 3.2 wrongly define _SB_CTYPE_MACROS on HP-UX */
+# if defined(TQ_OS_HPUX) && __GNUC__ == 3 && __GNUC_MINOR__ >= 1
+# define TQ_WRONG_SB_CTYPE_MACROS
+# endif
+
+/* ARM gcc pads structs to 32 bits, even when they contain a single
+ char, or short. We tell gcc to pack TQChars to 16 bits, to avoid
+ TQString bloat. However, gcc 3.4 doesn't allow us to create references to
+ members of a packed struct. (Pointers are OK, because then you
+ supposedly know what you are doing.) */
+# if (defined(__arm__) || defined(__ARMEL__)) && !defined(TQT_TQMOC_CPP)
+# define TQ_PACKED __attribute__ ((packed))
+# if __GNUC__ == 3 && __GNUC_MINOR__ >= 4
+# define TQ_NO_PACKED_REFERENCE
+# endif
+# endif
+# if !defined(__EXCEPTIONS)
+# define TQ_NO_EXCEPTIONS
+# endif
+
+/* IBM compiler versions are a bit messy. There are actually two products:
+ the C product, and the C++ product. The C++ compiler is always packaged
+ with the latest version of the C compiler. Version numbers do not always
+ match. This little table (I'm not sure it's accurate) should be helpful:
+
+ C++ product C product
+
+ C Set 3.1 C Compiler 3.0
+ ... ...
+ C++ Compiler 3.6.6 C Compiler 4.3
+ ... ...
+ Visual Age C++ 4.0 ...
+ ... ...
+ Visual Age C++ 5.0 C Compiler 5.0
+ ... ...
+ Visual Age C++ 6.0 C Compiler 6.0
+
+ Now:
+ __xlC__ is the version of the C compiler in hexadecimal notation
+ is only an approximation of the C++ compiler version
+ __IBMCPP__ is the version of the C++ compiler in decimal notation
+ but it is not defined on older compilers like C Set 3.1 */
+#elif defined(__xlC__)
+# define TQ_CC_XLC
+# define TQ_FULL_TEMPLATE_INSTANTIATION
+# if __xlC__ < 0x400
+# define TQ_NO_BOOL_TYPE
+# define TQ_NO_EXPLICIT_KEYWORD
+# define TQ_NO_USING_KEYWORD
+# define TQ_TYPENAME
+# define TQ_INLINE_TEMPLATES inline
+# define TQ_BROKEN_TEMPLATE_SPECIALIZATION
+# define TQ_CANNOT_DELETE_CONSTANT
+# endif
+
+/* Older versions of DEC C++ do not define __EDG__ or __EDG - observed
+ on DEC C++ V5.5-004. New versions do define __EDG__ - observed on
+ Compaq C++ V6.3-002.
+ This compiler is different enough from other EDG compilers to handle
+ it separately anyway. */
+#elif defined(__DECCXX) || defined(__DECC)
+# define TQ_CC_DEC
+/* Compaq C++ V6 compilers are EDG-based but I'm not sure about older
+ DEC C++ V5 compilers. */
+# if defined(__EDG__)
+# define TQ_CC_EDG
+# endif
+/* Compaq have disabled EDG's _BOOL macro and use _BOOL_EXISTS instead
+ - observed on Compaq C++ V6.3-002.
+ In any case versions prior to Compaq C++ V6.0-005 do not have bool. */
+# if !defined(_BOOL_EXISTS)
+# define TQ_NO_BOOL_TYPE
+# endif
+/* Spurious (?) error messages observed on Compaq C++ V6.5-014. */
+# define TQ_NO_USING_KEYWORD
+/* Apply to all versions prior to Compaq C++ V6.0-000 - observed on
+ DEC C++ V5.5-004. */
+# if __DECCXX_VER < 60060000
+# define TQ_TYPENAME
+# define TQ_BROKEN_TEMPLATE_SPECIALIZATION
+# define TQ_CANNOT_DELETE_CONSTANT
+# endif
+/* avoid undefined symbol problems with out-of-line template members */
+# define TQ_INLINE_TEMPLATES inline
+
+/* Compilers with EDG front end are similar. To detect them we test:
+ __EDG documented by SGI, observed on MIPSpro 7.3.1.1 and KAI C++ 4.0b
+ __EDG__ documented in EDG online docs, observed on Compaq C++ V6.3-002 */
+#elif defined(__EDG) || defined(__EDG__)
+# define TQ_CC_EDG
+/* From the EDG documentation (does not seem to apply to Compaq C++):
+ _BOOL
+ Defined in C++ mode when bool is a keyword. The name of this
+ predefined macro is specified by a configuration flag. _BOOL
+ is the default.
+ __BOOL_DEFINED
+ Defined in Microsoft C++ mode when bool is a keyword. */
+# if !defined(_BOOL) && !defined(__BOOL_DEFINED)
+# define TQ_NO_BOOL_TYPE
+# endif
+
+/* The Comeau compiler is based on EDG and does define __EDG__ */
+# if defined(__COMO__)
+# define TQ_CC_COMEAU
+# define TQ_C_CALLBACKS
+
+/* The `using' keyword was introduced to avoid KAI C++ warnings
+ but it's now causing KAI C++ errors instead. The standard is
+ unclear about the use of this keyword, and in practice every
+ compiler is using its own set of rules. Forget it. */
+# elif defined(__KCC)
+# define TQ_CC_KAI
+# if !defined(_EXCEPTIONS)
+# define TQ_NO_EXCEPTIONS
+# endif
+# define TQ_NO_USING_KEYWORD
+
+/* Using the `using' keyword avoids Intel C++ for Linux warnings */
+# elif defined(__INTEL_COMPILER)
+# define TQ_CC_INTEL
+# if !defined(__EXCEPTIONS)
+# define TQ_NO_EXCEPTIONS
+# endif
+
+/* The Portland Group compiler is based on EDG and does define __EDG__ */
+# elif defined(__PGI)
+# define TQ_CC_PGI
+# if !defined(__EXCEPTIONS)
+# define TQ_NO_EXCEPTIONS
+# endif
+
+/* Never tested! */
+# elif defined(__ghs)
+# define TQ_CC_GHS
+
+/* The UnixWare 7 UDK compiler is based on EDG and does define __EDG__ */
+# elif defined(__USLC__) && defined(__SCO_VERSION__)
+# define TQ_CC_USLC
+/* The latest UDK 7.1.1b does not need this, but previous versions do */
+# if !defined(__SCO_VERSION__) || (__SCO_VERSION__ < 302200010)
+# define TQ_INLINE_TEMPLATES inline
+# endif
+# define TQ_NO_USING_KEYWORD /* ### check "using" status */
+
+/* Never tested! */
+# elif defined(CENTERLINE_CLPP) || defined(OBJECTCENTER)
+# define TQ_CC_OC
+# define TQ_NO_USING_KEYWORD
+
+/* CDS++ defines __EDG__ although this is not documented in the Reliant
+ documentation. It also follows conventions like _BOOL and this documented */
+# elif defined(sinix)
+# define TQ_CC_CDS
+# define TQ_NO_USING_KEYWORD
+# if defined(__cplusplus) && (__cplusplus < 2) /* Cfront C++ mode */
+# define TQ_NO_EXCEPTIONS
+# endif
+
+/* The MIPSpro compiler in o32 mode is based on EDG but disables features
+ such as template specialization nevertheless */
+# elif defined(__sgi)
+# define TQ_CC_MIPS
+# if defined(_MIPS_SIM) && (_MIPS_SIM == _ABIO32) /* o32 ABI */
+# define TQ_TYPENAME
+# define TQ_BROKEN_TEMPLATE_SPECIALIZATION
+# define TQ_NO_EXPLICIT_KEYWORD
+# define TQ_INLINE_TEMPLATES inline
+# elif defined(_COMPILER_VERSION) && (_COMPILER_VERSION < 730) /* 7.2 */
+# define TQ_TYPENAME
+# define TQ_BROKEN_TEMPLATE_SPECIALIZATION
+# endif
+# define TQ_NO_USING_KEYWORD /* ### check "using" status */
+# if defined(_COMPILER_VERSION) && (_COMPILER_VERSION >= 740)
+# pragma set woff 3624,3625, 3649 /* turn off some harmless warnings */
+# endif
+# endif
+
+/* The older UnixWare 2.X compiler? */
+#elif defined(__USLC__)
+# define TQ_CC_USLC
+# define TQ_TYPENAME
+# define TQ_NO_BOOL_TYPE
+# define TQ_NO_EXPLICIT_KEYWORD
+# define TQ_NO_USING_KEYWORD
+# define TQ_INLINE_TEMPLATES inline
+
+/* Never tested! */
+#elif defined(__HIGHC__)
+# define TQ_CC_HIGHC
+
+#elif defined(__SUNPRO_CC) || defined(__SUNPRO_C)
+# define TQ_CC_SUN
+/* 5.0 compiler or better
+ 'bool' is enabled by default but can be disabled using -features=nobool
+ in which case _BOOL is not defined
+ this is the default in 4.2 compatibility mode triggered by -compat=4 */
+# if __SUNPRO_CC >= 0x500
+# if !defined(_BOOL)
+# define TQ_NO_BOOL_TYPE
+# endif
+# if defined(__SUNPRO_CC_COMPAT) && (__SUNPRO_CC_COMPAT <= 4)
+# define TQ_NO_USING_KEYWORD
+# endif
+# define TQ_C_CALLBACKS
+/* 4.2 compiler or older */
+# else
+# define TQ_NO_BOOL_TYPE
+# define TQ_NO_EXPLICIT_KEYWORD
+# define TQ_NO_USING_KEYWORD
+# endif
+
+/* CDS++ does not seem to define __EDG__ or __EDG according to Reliant
+ documentation but nevertheless uses EDG conventions like _BOOL */
+#elif defined(sinix)
+# define TQ_CC_EDG
+# define TQ_CC_CDS
+# if !defined(_BOOL)
+# define TQ_NO_BOOL_TYPE
+# endif
+# define TQ_BROKEN_TEMPLATE_SPECIALIZATION
+
+#elif defined(TQ_OS_HPUX)
+/* __HP_aCC was not defined in first aCC releases */
+# if defined(__HP_aCC) || __cplusplus >= 199707L
+# define TQ_CC_HPACC
+# else
+# define TQ_CC_HP
+# define TQ_NO_BOOL_TYPE
+# define TQ_FULL_TEMPLATE_INSTANTIATION
+# define TQ_BROKEN_TEMPLATE_SPECIALIZATION
+# define TQ_NO_EXPLICIT_KEYWORD
+# endif
+# define TQ_NO_USING_KEYWORD /* ### check "using" status */
+
+#else
+# error "TQt has not been tested with this compiler - talk to qt-bugs@trolltech.com"
+#endif
+
+#ifndef TQ_PACKED
+# define TQ_PACKED
+#endif
+
+
+/*
+ The window system, must be one of: (TQ_WS_x)
+
+ MACX - Mac OS X
+ MAC9 - Mac OS 9
+ TQWS - TQt/Embedded
+ WIN32 - Windows
+ X11 - X Window System
+ PM - unsupported
+ WIN16 - unsupported
+*/
+
+#if defined(TQ_OS_MAC9)
+# define TQ_WS_MAC9
+#elif defined(TQ_OS_MSDOS)
+# define TQ_WS_WIN16
+# error "TQt requires Win32 and does not work with Windows 3.x"
+#elif defined(_WIN32_X11_)
+# define TQ_WS_X11
+#elif defined(TQ_OS_WIN32)
+# define TQ_WS_WIN32
+# if defined(TQ_OS_WIN64)
+# define TQ_WS_WIN64
+# endif
+#elif defined(TQ_OS_OS2)
+# define TQ_WS_PM
+# error "TQt does not work with OS/2 Presentation Manager or Workplace Shell"
+#elif defined(TQ_OS_UNIX)
+# if defined(TQWS)
+# define TQ_WS_TQWS
+# define TQT_NO_TQWS_IM
+# elif defined(TQ_OS_MACX)
+# define TQ_WS_MACX
+# else
+# define TQ_WS_X11
+# endif
+#endif
+#if defined(TQ_OS_MAC) && !defined(TQMAC_PASCAL)
+# define TQMAC_PASCAL
+#endif
+
+#if defined(TQ_WS_WIN16) || defined(TQ_WS_WIN32)
+# define TQ_WS_WIN
+#endif
+
+#if (defined(TQ_WS_MAC9) || defined(TQ_WS_MACX)) && !defined(TQ_WS_TQWS) && !defined(TQ_WS_X11)
+# define TQ_WS_MAC
+#endif
+
+
+/*
+ Some classes do not permit copies to be made of an object.
+ These classes tqcontains a private copy constructor and operator=
+ to disable copying (the compiler gives an error message).
+ Undefine TQ_DISABLE_COPY to turn off this checking.
+*/
+
+#define TQ_DISABLE_COPY
+
+#if defined(__cplusplus)
+
+
+//
+// Useful type definitions for TQt
+//
+
+#if defined(TQ_NO_BOOL_TYPE)
+#if defined(TQ_CC_HP)
+// bool is an unsupported reserved keyword in later versions
+#define bool int
+#else
+typedef int bool;
+#endif
+#endif
+
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+typedef unsigned uint;
+typedef unsigned long ulong;
+typedef char *pchar;
+typedef uchar *puchar;
+typedef const char *pcchar;
+
+
+//
+// Constant bool values
+//
+
+#ifndef TRUE
+const bool FALSE = 0;
+const bool TRUE = !0;
+#endif
+#if defined(__WATCOMC__)
+# if defined(TQ_OS_TQNX4)
+const bool false = FALSE;
+const bool true = TRUE;
+# endif
+#endif
+
+//
+// Proper for-scoping
+// ### turn on in 4.0
+
+#if 0 && defined(TQ_CC_MSVC) && !defined(TQ_CC_MSVC_NET)
+# define for if(0){}else for
+#endif
+
+//
+// Use the "explicit" keyword on platforms that support it.
+//
+
+#if !defined(TQ_NO_EXPLICIT_KEYWORD)
+# define TQ_EXPLICIT explicit
+#else
+# define TQ_EXPLICIT
+#endif
+
+
+//
+// Workaround for static const members on MSVC++.
+//
+
+#if defined(TQ_CC_MSVC)
+# define TQT_STATIC_CONST static
+# define TQT_STATIC_CONST_IMPL
+#else
+# define TQT_STATIC_CONST static const
+# define TQT_STATIC_CONST_IMPL const
+#endif
+
+
+//
+// Utility macros and inline functions
+//
+
+#define TQMAX(a, b) ((b) < (a) ? (a) : (b))
+#define TQMIN(a, b) ((a) < (b) ? (a) : (b))
+#define TQABS(a) ((a) >= 0 ? (a) : -(a))
+
+inline int tqRound( double d )
+{
+ return d >= 0.0 ? int(d + 0.5) : int( d - ((int)d-1) + 0.5 ) + ((int)d-1);
+}
+
+
+//
+// Size-dependent types (architechture-dependent byte order)
+//
+
+#if !defined(TQT_CLEAN_NAMESPACE)
+// source compatibility with TQt 1.x
+typedef signed char INT8; // 8 bit signed
+typedef unsigned char UINT8; // 8 bit unsigned
+typedef short INT16; // 16 bit signed
+typedef unsigned short UINT16; // 16 bit unsigned
+// typedef int INT32; // 32 bit signed // [FIXME] Conflicts with Xorg headers
+typedef unsigned int UINT32; // 32 bit unsigned
+#endif
+
+typedef signed char TQ_INT8; // 8 bit signed
+typedef unsigned char TQ_UINT8; // 8 bit unsigned
+typedef short TQ_INT16; // 16 bit signed
+typedef unsigned short TQ_UINT16; // 16 bit unsigned
+typedef int TQ_INT32; // 32 bit signed
+typedef unsigned int TQ_UINT32; // 32 bit unsigned
+#if defined(TQ_OS_WIN64)
+typedef __int64 TQ_LONG; // word up to 64 bit signed
+typedef unsigned __int64 TQ_ULONG; // word up to 64 bit unsigned
+#else
+typedef long TQ_LONG; // word up to 64 bit signed
+typedef unsigned long TQ_ULONG; // word up to 64 bit unsigned
+#endif
+#if defined(TQ_OS_WIN) && !defined(TQ_CC_GNU)
+# define TQ_INT64_C(c) c ## i64 // signed 64 bit constant
+# define TQ_UINT64_C(c) c ## ui64 // unsigned 64 bit constant
+typedef __int64 TQ_INT64; // 64 bit signed
+typedef unsigned __int64 TQ_UINT64; // 64 bit unsigned
+#else
+# define TQ_INT64_C(c) c ## LL // signed 64 bit constant
+# define TQ_UINT64_C(c) c ## ULL // unsigned 64 bit constant
+typedef long long TQ_INT64; // 64 bit signed
+typedef unsigned long long TQ_UINT64; // 64 bit unsigned
+#endif
+typedef TQ_INT64 TQ_LLONG; // signed long long
+typedef TQ_UINT64 TQ_ULLONG; // unsigned long long
+
+#if defined(TQ_OS_MACX) && !defined(TQT_LARGEFILE_SUPPORT)
+# define TQT_LARGEFILE_SUPPORT 64
+#endif
+#if defined(TQT_LARGEFILE_SUPPORT)
+ typedef TQ_ULLONG TQtOffset;
+#else
+ typedef TQ_ULONG TQtOffset;
+#endif
+
+
+//
+// Data stream functions is provided by many classes (defined in tqdatastream.h)
+//
+
+class TQDataStream;
+
+
+//
+// Feature subsetting
+//
+// Note that disabling some features will produce a libtqt that is not
+// compatible with other libtqt builds. Such modifications are only
+// supported on TQt/Embedded where reducing the library size is important
+// and where the application-suite is often a fixed set.
+//
+
+#if !defined(TQT_TQMOC)
+#if defined(TQCONFIG_LOCAL)
+#include "tqconfig-local.h"
+#elif defined(TQCONFIG_MINIMAL)
+#include "tqconfig-minimal.h"
+#elif defined(TQCONFIG_SMALL)
+#include "tqconfig-small.h"
+#elif defined(TQCONFIG_MEDIUM)
+#include "tqconfig-medium.h"
+#elif defined(TQCONFIG_LARGE)
+#include "tqconfig-large.h"
+#else // everything...
+#include "tqconfig.h"
+#endif
+#endif
+
+
+#ifndef TQT_BUILD_KEY
+#define TQT_BUILD_KEY "unspecified"
+#endif
+
+// prune to local config
+#include "tqmodules.h"
+#ifndef TQT_MODULE_DIALOGS
+# define TQT_NO_DIALOG
+#endif
+#ifndef TQT_MODULE_ICONVIEW
+# define TQT_NO_ICONVIEW
+#endif
+#ifndef TQT_MODULE_WORKSPACE
+# define TQT_NO_WORKSPACE
+#endif
+#ifndef TQT_MODULE_NETWORK
+#define TQT_NO_NETWORK
+#endif
+#ifndef TQT_MODULE_CANVAS
+# define TQT_NO_CANVAS
+#endif
+#ifndef TQT_MODULE_TABLE
+#define TQT_NO_TABLE
+#endif
+#ifndef TQT_MODULE_XML
+# define TQT_NO_XML
+#endif
+#ifndef TQT_MODULE_OPENGL
+# define TQT_NO_OPENGL
+#endif
+#if !defined(TQT_MODULE_SQL)
+# define TQT_NO_SQL
+#endif
+
+#if defined(TQ_WS_MAC9)
+//No need for menu merging
+# ifndef TQMAC_TQMENUBAR_NO_MERGE
+# define TQMAC_TQMENUBAR_NO_MERGE
+# endif
+//Mac9 does not use quartz
+# ifndef TQMAC_NO_TQUARTZ
+# define TQMAC_NO_TQUARTZ
+# endif
+# ifndef TQMAC_TQMENUBAR_NO_EVENT
+# define TQMAC_TQMENUBAR_NO_EVENT
+# endif
+#endif
+#if defined(TQ_WS_MACX) //for no nobody uses quartz, just putting in first level hooks
+# ifndef TQMAC_NO_TQUARTZ
+# define TQMAC_NO_TQUARTZ
+# endif
+# ifndef TQMAC_TQMENUBAR_NO_EVENT
+# define TQMAC_TQMENUBAR_NO_EVENT
+# endif
+#endif
+
+#if !defined(TQ_WS_TQWS) && !defined(TQT_NO_COP)
+# define TQT_NO_COP
+#endif
+
+#ifndef TQT_H
+#include "tqfeatures.h"
+#endif /* TQT_H */
+
+
+//
+// Create TQt DLL if TQT_DLL is defined (Windows only)
+// or TQT_SHARED is defined (Kylix only)
+//
+
+#if defined(TQ_OS_WIN)
+# if defined(TQT_NODLL)
+# undef TQT_MAKEDLL
+# undef TQT_DLL
+# elif defined(TQT_MAKEDLL) /* create a TQt DLL library */
+# if defined(TQT_DLL)
+# undef TQT_DLL
+# endif
+# define TQ_EXPORT __declspec(dllexport)
+# define TQ_TEMPLATEDLL
+# define TQ_TEMPLATE_EXTERN
+# undef TQ_DISABLE_COPY /* avoid unresolved externals */
+# elif defined(TQT_DLL) /* use a TQt DLL library */
+# define TQ_EXPORT __declspec(dllimport)
+# define TQ_TEMPLATEDLL
+# ifndef TQ_TEMPLATE_EXTERN
+# if defined(TQ_CC_MSVC_NET)
+# define TQ_TEMPLATE_EXTERN extern
+# else
+# define TQ_TEMPLATE_EXTERN
+# endif
+# endif
+# undef TQ_DISABLE_COPY /* avoid unresolved externals */
+# endif
+#elif defined(TQ_OS_LINUX) && defined(TQ_CC_BOR)
+# if defined(TQT_SHARED) /* create a TQt shared library */
+# define TQ_EXPORT __declspec(dllexport)
+# define TQ_TEMPLATEDLL
+# define TQ_TEMPLATE_EXTERN
+# undef TQ_DISABLE_COPY /* avoid unresolved externals */
+# else
+# define TQ_TEMPLATEDLL
+# define TQ_TEMPLATE_EXTERN
+# undef TQ_DISABLE_COPY /* avoid unresolved externals */
+# endif
+#else
+# undef TQT_MAKEDLL /* ignore these for other platforms */
+# undef TQT_DLL
+#endif
+
+#ifndef TQ_EXPORT
+# define TQ_EXPORT
+#endif
+
+
+//
+// Some platform specific stuff
+//
+
+#if defined(TQ_WS_WIN)
+extern TQ_EXPORT bool qt_wintqunicode;
+#endif
+
+
+//
+// System information
+//
+
+TQ_EXPORT const char *qVersion();
+TQ_EXPORT bool qSysInfo( int *wordSize, bool *bigEndian );
+TQ_EXPORT bool qSharedBuild();
+#if defined(TQ_OS_MAC)
+int qMacVersion();
+#elif defined(TQ_WS_WIN)
+TQ_EXPORT int qWinVersion();
+#if defined(UNICODE)
+#define TQT_WA( uni, ansi ) if ( qt_wintqunicode ) { uni } else { ansi }
+#define TQT_WA_INLINE( uni, ansi ) ( qt_wintqunicode ? uni : ansi )
+#else
+#define TQT_WA( uni, ansi ) ansi
+#define TQT_WA_INLINE( uni, ansi ) ansi
+#endif
+#endif
+
+#ifdef TQ_OS_TEMP
+#ifdef TQT_WA
+#undef TQT_WA
+#undef TQT_WA_INLINE
+#endif
+#define TQT_WA( uni, ansi ) uni
+#define TQT_WA_INLINE( uni, ansi ) ( uni )
+#endif
+
+#ifndef TQ_INLINE_TEMPLATES
+# define TQ_INLINE_TEMPLATES
+#endif
+
+#ifndef TQ_TYPENAME
+# define TQ_TYPENAME typename
+#endif
+
+//
+// Use to avoid "unused parameter" warnings
+//
+#define TQ_UNUSED(x) (void)x;
+
+//
+// Debugging and error handling
+//
+
+#if !defined(TQT_NO_CHECK)
+# define TQT_CHECK_STATE // check state of objects etc.
+# define TQT_CHECK_RANGE // check range of indexes etc.
+# define TQT_CHECK_NULL // check null pointers
+# define TQT_CHECK_MATH // check math functions
+#endif
+
+#if !defined(TQT_NO_DEBUG) && !defined(TQT_DEBUG)
+# define TQT_DEBUG // display debug messages
+# if !defined(TQT_NO_COMPAT) // compatibility with TQt 2
+# if !defined(NO_DEBUG) && !defined(DEBUG)
+# if !defined(TQ_OS_MACX) // clash with MacOS X headers
+# define DEBUG
+# endif
+# endif
+# endif
+#endif
+
+
+TQ_EXPORT void qDebug( const char *, ... ) // print debug message
+#if defined(TQ_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+TQ_EXPORT void qWarning( const char *, ... ) // print warning message
+#if defined(TQ_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+TQ_EXPORT void qFatal( const char *, ... ) // print fatal message and exit
+#if defined(TQ_CC_GNU)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+TQ_EXPORT void tqSystemWarning( const char *, int code = -1 );
+
+#if !defined(TQT_CLEAN_NAMESPACE) // compatibility with TQt 1
+
+TQ_EXPORT void debug( const char *, ... ) // print debug message
+#if defined(TQ_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+TQ_EXPORT void warning( const char *, ... ) // print warning message
+#if defined(TQ_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+TQ_EXPORT void fatal( const char *, ... ) // print fatal message and exit
+#if defined(TQ_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 1, 2)))
+#endif
+;
+
+#endif // TQT_CLEAN_NAMESPACE
+
+
+#if !defined(TQ_ASSERT)
+# if defined(TQT_CHECK_STATE)
+# if defined(TQT_FATAL_ASSERT)
+# define TQ_ASSERT(x) ((x) ? (void)0 : qFatal("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__))
+# else
+# define TQ_ASSERT(x) ((x) ? (void)0 : qWarning("ASSERT: \"%s\" in %s (%d)",#x,__FILE__,__LINE__))
+# endif
+# else
+# define TQ_ASSERT(x)
+# endif
+#endif
+
+#if !defined(TQT_NO_COMPAT) // compatibility with TQt 2
+# if !defined(ASSERT)
+# if !defined(TQ_OS_TEMP)
+# define ASSERT(x) TQ_ASSERT(x)
+# endif
+# endif
+#endif // TQT_NO_COMPAT
+
+
+TQ_EXPORT bool qt_check_pointer( bool c, const char *, int );
+
+#if defined(TQT_CHECK_NULL)
+# define TQ_CHECK_PTR(p) (qt_check_pointer((p)==0,__FILE__,__LINE__))
+#else
+# define TQ_CHECK_PTR(p)
+#endif
+
+#if !defined(TQT_NO_COMPAT) // compatibility with TQt 2
+# if !defined(CHECK_PTR)
+# define CHECK_PTR(x) TQ_CHECK_PTR(x)
+# endif
+#endif // TQT_NO_COMPAT
+
+enum TQtMsgType { TQtDebugMsg, TQtWarningMsg, TQtFatalMsg };
+
+typedef void (*TQtMsgHandler)(TQtMsgType, const char *);
+TQ_EXPORT TQtMsgHandler tqInstallMsgHandler( TQtMsgHandler );
+
+#if !defined(TQT_NO_COMPAT) // compatibility with TQt 2
+typedef TQtMsgHandler msg_handler;
+#endif // TQT_NO_COMPAT
+
+TQ_EXPORT void tqSuppressObsoleteWarnings( bool = TRUE );
+
+TQ_EXPORT void qObsolete( const char *obj, const char *oldfunc,
+ const char *newfunc );
+TQ_EXPORT void qObsolete( const char *obj, const char *oldfunc );
+TQ_EXPORT void qObsolete( const char *message );
+
+
+//
+// Install paths from configure
+//
+
+TQ_EXPORT const char *qInstallPath();
+TQ_EXPORT const char *qInstallPathDocs();
+TQ_EXPORT const char *qInstallPathHeaders();
+TQ_EXPORT const char *qInstallPathLibs();
+TQ_EXPORT const char *qInstallPathBins();
+TQ_EXPORT const char *qInstallPathPlugins();
+TQ_EXPORT const char *qInstallPathData();
+TQ_EXPORT const char *qInstallPathTranslations();
+TQ_EXPORT const char *qInstallPathSysconf();
+
+#endif /* __cplusplus */
+
+/*
+ compilers which follow outdated template instantiation rules
+ require a class to have a comparison operator to exist when
+ a TQValueList of this type is instantiated. It's not actually
+ used in the list, though. Hence the dummy implementation.
+ Just in case other code relies on it we better trigger a warning
+ mandating a real implementation.
+*/
+#ifdef TQ_FULL_TEMPLATE_INSTANTIATION
+# define TQ_DUMMY_COMPARISON_OPERATOR(C) \
+ bool operator==( const C& ) const { \
+ qWarning( #C"::operator==( const "#C"& ) got called." ); \
+ return FALSE; \
+ }
+#else
+# define TQ_DUMMY_COMPARISON_OPERATOR(C)
+#endif
+
+#endif /* TQGLOBAL_H */
+
+/*
+ Avoid some particularly useless warnings from some stupid compilers.
+ To get ALL C++ compiler warnings, define TQT_CC_WARNINGS or comment out
+ the line "#define TQT_NO_WARNINGS"
+*/
+
+#if !defined(TQT_CC_WARNINGS)
+# define TQT_NO_WARNINGS
+#endif
+#if defined(TQT_NO_WARNINGS)
+# if defined(TQ_CC_MSVC)
+# pragma warning(disable: 4244) // 'conversion' conversion from 'type1' to 'type2', possible loss of data
+# pragma warning(disable: 4275) // non - DLL-interface classkey 'identifier' used as base for DLL-interface classkey 'identifier'
+# pragma warning(disable: 4514) // unreferenced inline/local function has been removed
+# pragma warning(disable: 4800) // 'type' : forcing value to bool 'true' or 'false' (performance warning)
+# pragma warning(disable: 4097) // typedef-name 'identifier1' used as synonym for class-name 'identifier2'
+# pragma warning(disable: 4706) // assignment within conditional expression
+# pragma warning(disable: 4786) // truncating debug info after 255 characters
+# pragma warning(disable: 4660) // template-class specialization 'identifier' is already instantiated
+# pragma warning(disable: 4355) // 'this' : used in base member initializer list
+# pragma warning(disable: 4231) // nonstandard extension used : 'extern' before template explicit instantiation
+# pragma warning(disable: 4710) // function not inlined
+# elif defined(TQ_CC_BOR)
+# pragma option -w-inl
+# pragma option -w-aus
+# pragma warn -inl
+# pragma warn -pia
+# pragma warn -ccc
+# pragma warn -rch
+# pragma warn -sig
+# endif
+#endif
+
diff --git a/tqtinterface/qt4/src/tools/tqgpluginmanager.cpp b/tqtinterface/qt4/src/tools/tqgpluginmanager.cpp
new file mode 100644
index 0000000..ef0ab02
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgpluginmanager.cpp
@@ -0,0 +1,550 @@
+/****************************************************************************
+**
+** Implementation of TQGPluginManager class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqgpluginmanager_p.h"
+#ifndef TQT_NO_COMPONENT
+#include "tqcomlibrary_p.h"
+#include "tqmap.h"
+#include "tqdir.h"
+
+/*
+ The following co-occurrence code is borrowed from TQt Linguist.
+
+ How similar are two texts? The approach used here relies on
+ co-occurrence matrices and is very efficient.
+
+ Let's see with an example: how similar are "here" and "hither"? The
+ co-occurrence matrix M for "here" is M[h,e] = 1, M[e,r] = 1,
+ M[r,e] = 1 and 0 elsewhere; the matrix N for "hither" is N[h,i] = 1,
+ N[i,t] = 1, ..., N[h,e] = 1, N[e,r] = 1 and 0 elsewhere. The union
+ U of both matrices is the matrix U[i,j] = max { M[i,j], N[i,j] },
+ and the intersection V is V[i,j] = min { M[i,j], N[i,j] }. The score
+ for a pair of texts is
+
+ score = (sum of V[i,j] over all i, j) / (sum of U[i,j] over all i, j),
+
+ a formula suggested by Arnt Gulbrandsen. Here we have
+
+ score = 2 / 6,
+
+ or one third.
+
+ The implementation differs from this in a few details. Most
+ importantly, repetitions are ignored; for input "xxx", M[x,x] equals
+ 1, not 2.
+*/
+
+/*
+ Every character is assigned to one of 20 buckets so that the
+ co-occurrence matrix requires only 20 * 20 = 400 bits, not
+ 256 * 256 = 65536 bits or even more if we want the whole Unicode.
+ Which character falls in which bucket is arbitrary.
+
+ The second half of the table is a replica of the first half, because of
+ laziness.
+*/
+static const char indexOf[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+// ! " # $ % & ' ( ) * + , - . /
+ 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0,
+// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
+ 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15,
+// @ A B C D E F G H I J K L M N O
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+// P Q R S T U V W X Y Z [ \ ] ^ _
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
+// ` a b c d e f g h i j k l m n o
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+// p q r s t u v w x y z { | } ~
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0,
+ 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14,
+ 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0
+};
+
+/*
+ The entry bitCount[i] (for i between 0 and 255) is the number of
+ bits used to represent i in binary.
+*/
+static const char bitCount[256] = {
+ 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+ 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+};
+
+class TQCoMatrix
+{
+public:
+ /*
+ The matrix has 20 * 20 = 400 entries. This requires 50 bytes, or
+ 13 words. Some operations are performed on words for more
+ efficiency.
+ */
+ union {
+ TQ_UINT8 b[52];
+ TQ_UINT32 w[13];
+ };
+
+ TQCoMatrix() { memset( b, 0, 52 ); }
+ TQCoMatrix( const char *text ) {
+ char c = '\0', d;
+ memset( b, 0, 52 );
+ while ( (d = *text) != '\0' ) {
+ setCoocc( c, d );
+ if ( (c = *++text) != '\0' ) {
+ setCoocc( d, c );
+ text++;
+ }
+ }
+ }
+
+ void setCoocc( char c, char d ) {
+ int k = indexOf[(uchar) c] + 20 * indexOf[(uchar) d];
+ b[k >> 3] |= k & 0x7;
+ }
+
+ int worth() const {
+ int result = 0;
+ for ( int i = 0; i < 50; i++ )
+ result += bitCount[b[i]];
+ return result;
+ }
+
+ static TQCoMatrix reunion( const TQCoMatrix& m, const TQCoMatrix& n )
+ {
+ TQCoMatrix p;
+ for ( int i = 0; i < 13; i++ )
+ p.w[i] = m.w[i] | n.w[i];
+ return p;
+ }
+ static TQCoMatrix intersection( const TQCoMatrix& m, const TQCoMatrix& n )
+ {
+ TQCoMatrix p;
+ for ( int i = 0; i < 13; i++ )
+ p.w[i] = m.w[i] & n.w[i];
+ return p;
+ }
+};
+
+/*
+ Returns an integer between 0 (dissimilar) and 15 (very similar)
+ depending on how similar the string is to \a target.
+
+ This function is efficient, but its results might change in future
+ versions of TQt as the algorithm evolves.
+
+ \code
+ TQString s( "color" );
+ a = similarity( s, "color" ); // a == 15
+ a = similarity( s, "colour" ); // a == 8
+ a = similarity( s, "flavor" ); // a == 4
+ a = similarity( s, "dahlia" ); // a == 0
+ \endcode
+*/
+static int similarity( const TQString& s1, const TQString& s2 )
+{
+ TQCoMatrix m1( s1 );
+ TQCoMatrix m2( s2 );
+ return ( 15 * (TQCoMatrix::intersection(m1, m2).worth() + 1) ) /
+ ( TQCoMatrix::reunion(m1, m2).worth() + 1 );
+}
+
+/*!
+ \class TQPluginManager qpluginmanager.h
+ \reentrant
+ \brief The TQPluginManager class provides basic functions to access a certain kind of functionality in libraries.
+ \ingroup componentmodel
+
+ \internal
+
+ A common usage of components is to extend the existing functionality in an application using plugins. The application
+ defines interfaces that abstract a certain group of functionality, and a plugin provides a specialized implementation
+ of one or more of those interfaces.
+
+ The TQPluginManager template has to be instantiated with an interface definition and the IID for this interface.
+
+ \code
+ TQPluginManager<MyPluginInterface> *manager = new TQPluginManager<MyPluginInterface>( IID_MyPluginInterface );
+ \endcode
+
+ It searches a specified directory for all shared libraries, queries for components that implement the specific interface and
+ reads information about the features the plugin wants to add to the application. The component can provide the set of features
+ provided by implementing either the TQFeatureListInterface or the TQComponentInformationInterface. The strings returned by the implementations
+ of
+
+ \code
+ TQStringList TQFeatureListInterface::featureList() const
+ \endcode
+
+ or
+
+ \code
+ TQString TQComponentInformationInterface::name() const
+ \endcode
+
+ respectively, can then be used to access the component that provides the requested feature:
+
+ \code
+ MyPluginInterface *iface;
+ manager->queryInterface( "feature", &iface );
+ if ( iface )
+ iface->execute( "feature" );
+ \endcode
+
+ The application can use a TQPluginManager instance to create parts of the user interface based on the list of features
+ found in plugins:
+
+ \code
+ TQPluginManager<MyPluginInterface> *manager = new TQPluginManager<MyPluginInterface>( IID_ImageFilterInterface );
+ manager->addLibraryPath(...);
+
+ TQStringList features = manager->featureList();
+ for ( TQStringList::Iterator it = features.begin(); it != features.end(); ++it ) {
+ MyPluginInterface *iface;
+ manager->queryInterface( *it, &iface );
+
+ // use TQAction to provide toolbuttons and menuitems for each feature...
+ }
+ \endcode
+*/
+
+/*!
+ \fn TQPluginManager::TQPluginManager( const TQUuid& id, const TQStringList& paths = TQString::null, const TQString &suffix = TQString::null, bool cs = TRUE )
+
+ Creates an TQPluginManager for interfaces \a id that will load all shared library files in the \a paths + \a suffix.
+ If \a cs is FALSE the manager will handle feature strings case insensitive.
+
+ \warning
+ Setting the cs flag to FALSE requires that components also convert to lower case when comparing with passed strings, so this has
+ to be handled with care and documented very well.
+
+ \sa TQApplication::libraryPaths()
+*/
+
+
+/*!
+ \fn TQRESULT TQPluginManager::queryInterface(const TQString& feature, Type** iface) const
+
+ Sets \a iface to point to the interface providing \a feature.
+
+ \sa featureList(), library()
+*/
+
+
+
+#include <tqptrlist.h>
+
+TQGPluginManager::TQGPluginManager( const TQUuid& id, const TQStringList& paths, const TQString &suffix, bool cs )
+ : interfaceId( id ), plugDict( 17, cs ), casesens( cs ), autounload( TRUE )
+{
+ // Every TQLibrary object is destroyed on destruction of the manager
+ libDict.setAutoDelete( TRUE );
+ for ( TQStringList::ConstIterator it = paths.begin(); it != paths.end(); ++it ) {
+ TQString path = *it;
+ addLibraryPath( path + suffix );
+ }
+}
+
+TQGPluginManager::~TQGPluginManager()
+{
+ if ( !autounload ) {
+ TQDictIterator<TQLibrary> it( libDict );
+ while ( it.current() ) {
+ TQLibrary *lib = it.current();
+ ++it;
+ lib->setAutoUnload( FALSE );
+ }
+ }
+}
+
+void TQGPluginManager::addLibraryPath( const TQString& path )
+{
+ if ( !enabled() || !TQDir( path ).exists( ".", TRUE ) )
+ return;
+
+#if defined(TQ_OS_WIN32)
+ TQString filter = "*.dll";
+#elif defined(TQ_OS_MACX)
+ TQString filter = "*.dylib; *.so; *.bundle";
+#elif defined(TQ_OS_HPUX)
+ TQString filter = "*.sl";
+#elif defined(TQ_OS_UNIX)
+ TQString filter = "*.so";
+#endif
+
+ TQStringList plugins = TQDir(path).entryList( filter );
+ for ( TQStringList::Iterator p = plugins.begin(); p != plugins.end(); ++p ) {
+ TQString lib = TQDir::cleanDirPath( path + "/" + *p );
+ if ( libList.tqcontains( lib ) )
+ continue;
+ libList.append( lib );
+ }
+}
+
+const TQLibrary* TQGPluginManager::library( const TQString& feature ) const
+{
+ if ( !enabled() || feature.isEmpty() )
+ return 0;
+
+ // We already have a TQLibrary object for this feature
+ TQLibrary *library = 0;
+ if ( ( library = plugDict[feature] ) )
+ return library;
+
+ // Find the filename that matches the feature request best
+ TQMap<int, TQStringList> map;
+ TQStringList::ConstIterator it = libList.begin();
+ int best = 0;
+ int worst = 15;
+ while ( it != libList.end() ) {
+ if ( (*it).isEmpty() || libDict[*it] ) {
+ ++it;
+ continue;
+ }
+ TQString basename = TQFileInfo(*it).baseName();
+ int s = similarity( feature, basename );
+ if ( s < worst )
+ worst = s;
+ if ( s > best )
+ best = s;
+ map[s].append( basename + TQChar(0xfffd) + *it );
+ ++it;
+ }
+
+ if ( map.isEmpty() )
+ return 0; // no libraries to add
+
+ // Start with the best match to get the library object
+ TQGPluginManager *that = (TQGPluginManager*)this;
+ for ( int s = best; s >= worst; --s ) {
+ TQStringList group = map[s];
+ group.sort(); // sort according to the base name
+ TQStringList::ConstIterator git = group.begin();
+ while ( git != group.end() ) {
+ TQString lib = (*git).mid( (*git).tqfind( TQChar(0xfffd) ) + 1 );
+ TQString basename = (*git).left( (*git).tqfind( TQChar(0xfffd) ) );
+ ++git;
+
+ TQStringList sameBasename;
+ while( git != group.end() &&
+ basename == (*git).left( (*git).tqfind( TQChar(0xfffd) ) ) ) {
+ sameBasename << (*git).mid( (*git).tqfind( TQChar(0xfffd) ) + 1 );
+ ++git;
+ }
+
+ if ( sameBasename.isEmpty() ) {
+ that->addLibrary( new TQComLibrary( lib ) );
+ } else {
+ TQPtrList<TQComLibrary> same;
+ same.setAutoDelete( TRUE );
+ same.append( new TQComLibrary( lib ) );
+ for ( TQStringList::ConstIterator bit = sameBasename.begin();
+ bit != sameBasename.end(); ++bit )
+ same.append( new TQComLibrary( *bit ) );
+ TQComLibrary* bestMatch = 0;
+ for ( TQComLibrary* candidate = same.first(); candidate; candidate = same.next() )
+ if ( candidate->qtVersion() && candidate->qtVersion() <= TQT_VERSION
+ && ( !bestMatch || candidate->qtVersion() > bestMatch->qtVersion() ) )
+ bestMatch = candidate;
+ if ( bestMatch ) {
+ same.tqfind( bestMatch );
+ that->addLibrary( same.take() );
+ }
+ }
+
+ if ( ( library = that->plugDict[feature] ) )
+ return library;
+ }
+ }
+ return 0;
+}
+
+TQStringList TQGPluginManager::featureList() const
+{
+ TQStringList features;
+
+ if ( !enabled() )
+ return features;
+
+ TQGPluginManager *that = (TQGPluginManager*)this;
+ TQStringList theLibs = libList;
+ TQStringList phase2Libs;
+ TQStringList phase2Deny;
+
+ /* In order to get the feature list we need to add all interesting
+ libraries. If there are libraries with the same base name, we
+ prioritze the one that fits our TQt version number and ignore the
+ others */
+ TQStringList::Iterator it;
+ for ( it = theLibs.begin(); it != theLibs.end(); ++it ) {
+ if ( (*it).isEmpty() || libDict[*it] )
+ continue;
+ TQComLibrary* library = new TQComLibrary( *it );
+ if ( library->qtVersion() == TQT_VERSION ) {
+ that->addLibrary( library );
+ phase2Deny << TQFileInfo( *it ).baseName();
+ } else {
+ delete library;
+ phase2Libs << *it;
+ }
+ }
+ for ( it = phase2Libs.begin(); it != phase2Libs.end(); ++it )
+ if ( !phase2Deny.tqcontains( TQFileInfo( *it ).baseName() ) )
+ that->addLibrary( new TQComLibrary( *it ) );
+
+ for ( TQDictIterator<TQLibrary> pit( plugDict ); pit.current(); ++pit )
+ features << pit.currentKey();
+
+ return features;
+}
+
+bool TQGPluginManager::addLibrary( TQLibrary* lib )
+{
+ if ( !enabled() || !lib )
+ return FALSE;
+
+ TQComLibrary* plugin = (TQComLibrary*)lib;
+ bool useful = FALSE;
+
+ TQUnknownInterface* iFace = 0;
+ plugin->queryInterface( interfaceId, &iFace );
+ if ( iFace ) {
+ TQFeatureListInterface *fliFace = 0;
+ TQComponentInformationInterface *cpiFace = 0;
+ iFace->queryInterface( IID_TQFeatureList, (TQUnknownInterface**)&fliFace );
+ if ( !fliFace )
+ plugin->queryInterface( IID_TQFeatureList, (TQUnknownInterface**)&fliFace );
+ if ( !fliFace ) {
+ iFace->queryInterface( IID_TQComponentInformation, (TQUnknownInterface**)&cpiFace );
+ if ( !cpiFace )
+ plugin->queryInterface( IID_TQComponentInformation, (TQUnknownInterface**)&cpiFace );
+ }
+ TQStringList fl;
+ if ( fliFace )
+ // Map all found features to the library
+ fl = fliFace->featureList();
+ else if ( cpiFace )
+ fl << cpiFace->name();
+
+ for ( TQStringList::Iterator f = fl.begin(); f != fl.end(); ++f ) {
+ TQLibrary *old = plugDict[*f];
+ if ( !old ) {
+ useful = TRUE;
+ plugDict.tqreplace( *f, plugin );
+ } else {
+ // we have old *and* plugin, which one to pick?
+ TQComLibrary* first = (TQComLibrary*)old;
+ TQComLibrary* second = (TQComLibrary*)plugin;
+ bool takeFirst = TRUE;
+ if ( first->qtVersion() != TQT_VERSION ) {
+ if ( second->qtVersion() == TQT_VERSION )
+ takeFirst = FALSE;
+ else if ( second->qtVersion() < TQT_VERSION &&
+ first->qtVersion() > TQT_VERSION )
+ takeFirst = FALSE;
+ }
+ if ( !takeFirst ) {
+ useful = TRUE;
+ plugDict.tqreplace( *f, plugin );
+ qWarning("%s: Discarding feature %s in %s!",
+ (const char*) TQFile::encodeName( plugin->library()),
+ (*f).latin1(),
+ (const char*) TQFile::encodeName( old->library() ) );
+ } else {
+ qWarning("%s: Feature %s already defined in %s!",
+ (const char*) TQFile::encodeName( old->library() ),
+ (*f).latin1(),
+ (const char*) TQFile::encodeName( plugin->library() ) );
+ }
+ }
+ }
+ if ( fliFace )
+ fliFace->release();
+ if ( cpiFace )
+ cpiFace->release();
+ iFace->release();
+ }
+
+ if ( useful ) {
+ libDict.tqreplace( plugin->library(), plugin );
+ if ( !libList.tqcontains( plugin->library() ) )
+ libList.append( plugin->library() );
+ return TRUE;
+ }
+ delete plugin;
+ return FALSE;
+}
+
+
+bool TQGPluginManager::enabled() const
+{
+#ifdef TQT_SHARED
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+TQRESULT TQGPluginManager::queryUnknownInterface(const TQString& feature, TQUnknownInterface** iface) const
+{
+ TQComLibrary* plugin = 0;
+ plugin = (TQComLibrary*)library( feature );
+ return plugin ? plugin->queryInterface( interfaceId, (TQUnknownInterface**)iface ) : TQE_NOINTERFACE;
+}
+
+#endif //TQT_NO_COMPONENT
diff --git a/tqtinterface/qt4/src/tools/tqgpluginmanager_p.h b/tqtinterface/qt4/src/tools/tqgpluginmanager_p.h
new file mode 100644
index 0000000..dd4709d
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgpluginmanager_p.h
@@ -0,0 +1,108 @@
+/**********************************************************************
+**
+** Definition of TQGPluginManager class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGPLUGINMANAGER_P_H
+#define TQGPLUGINMANAGER_P_H
+
+#include "tqdict.h"
+#include "tqlibrary.h"
+#include "tquuid.h"
+#include "tqstringlist.h"
+#include "tqcom_p.h"
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_NO_COMPONENT
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+//TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQDict<TQLibrary>;
+// TQMOC_SKIP_END
+#endif
+
+class TQ_EXPORT TQGPluginManager
+{
+public:
+ TQGPluginManager( const TQUuid& id, const TQStringList& paths = TQString(), const TQString &suffix = TQString::null, bool cs = TRUE );
+ ~TQGPluginManager();
+
+ void addLibraryPath( const TQString& path );
+ const TQLibrary* library( const TQString& feature ) const;
+ TQStringList featureList() const;
+
+ bool autoUnload() const;
+ void setAutoUnload( bool );
+
+protected:
+ bool enabled() const;
+ bool addLibrary( TQLibrary* plugin );
+
+ TQRESULT queryUnknownInterface(const TQString& feature, TQUnknownInterface** iface) const;
+
+ TQUuid interfaceId;
+ TQDict<TQLibrary> plugDict; // Dict to match feature with library
+ TQDict<TQLibrary> libDict; // Dict to match library file with library
+ TQStringList libList;
+
+ uint casesens : 1;
+ uint autounload : 1;
+};
+
+inline void TQGPluginManager::setAutoUnload( bool unload )
+{
+ autounload = unload;
+}
+
+inline bool TQGPluginManager::autoUnload() const
+{
+ return autounload;
+}
+
+#endif
+
+#endif //TQGPLUGINMANAGER_P_H
diff --git a/tqtinterface/qt4/src/tools/tqgvector.cpp b/tqtinterface/qt4/src/tools/tqgvector.cpp
new file mode 100644
index 0000000..e30c172
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgvector.cpp
@@ -0,0 +1,598 @@
+/****************************************************************************
+**
+** Implementation of TQGVector class
+**
+** Created : 930907
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqglobal.h"
+#if defined(TQ_CC_BOR)
+// needed for qsort() because of a std namespace problem on Borland
+#include "tqplatformdefs.h"
+#endif
+
+#define TQGVECTOR_CPP
+#include "tqgvector.h"
+#include "tqglist.h"
+#include "tqstring.h"
+#include "tqdatastream.h"
+#include <stdlib.h>
+
+#ifdef TQT_THREAD_SUPPORT
+# include <private/tqmutexpool_p.h>
+#endif // TQT_THREAD_SUPPORT
+
+#define USE_MALLOC // comment to use new/delete
+
+#undef NEW
+#undef DELETE
+
+#if defined(USE_MALLOC)
+#define NEW(type,size) ((type*)malloc(size*sizeof(type)))
+#define DELETE(array) (free((char*)array))
+#else
+#define NEW(type,size) (new type[size])
+#define DELETE(array) (delete[] array)
+#define DONT_USE_REALLOC // comment to use realloc()
+#endif
+
+/*!
+ \class TQGVector
+ \reentrant
+ \ingroup collection
+
+ \brief The TQGVector class is an internal class for implementing TQt
+ collection classes.
+
+ \internal
+
+ TQGVector is an internal class that acts as a base class for the
+ TQPtrVector collection class.
+
+ TQGVector has some virtual functions that may be reimplemented in
+ subclasses to customize behavior.
+
+ \list
+ \i compareItems() compares two collection/vector items.
+ \i read() reads a collection/vector item from a TQDataStream.
+ \i write() writes a collection/vector item to a TQDataStream.
+ \endlist
+*/
+
+/*****************************************************************************
+ Default implementation of virtual functions
+ *****************************************************************************/
+
+/*!
+ This virtual function compares two list items.
+
+ Returns:
+ <ul>
+ <li> 0 if \a d1 == \a d2
+ <li> non-zero if \a d1 != \a d2
+ </ul>
+
+ This function returns \e int rather than \e bool so that
+ reimplementations can return one of three values and use it to sort
+ by:
+ <ul>
+ <li> 0 if \a d1 == \a d2
+ <li> \> 0 (positive integer) if \a d1 \> \a d2
+ <li> \< 0 (negative integer) if \a d1 \< \a d2
+ </ul>
+
+ The TQPtrVector::sort() and TQPtrVector::bsearch() functions require that
+ compareItems() is implemented as described here.
+
+ This function should not modify the vector because some const
+ functions call compareItems().
+*/
+
+int TQGVector::compareItems( Item d1, Item d2 )
+{
+ return d1 != d2; // compare pointers
+}
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ Reads a collection/vector item from the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation sets \a d to 0.
+
+ \sa write()
+*/
+
+TQDataStream &TQGVector::read( TQDataStream &s, Item &d )
+{ // read item from stream
+ d = 0;
+ return s;
+}
+
+/*!
+ Writes a collection/vector item to the stream \a s and returns a reference
+ to the stream.
+
+ The default implementation does nothing.
+
+ \sa read()
+*/
+
+TQDataStream &TQGVector::write( TQDataStream &s, Item ) const
+{ // write item to stream
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+/*****************************************************************************
+ TQGVector member functions
+ *****************************************************************************/
+
+TQGVector::TQGVector() // create empty vector
+{
+ vec = 0;
+ len = numItems = 0;
+}
+
+TQGVector::TQGVector( uint size ) // create vectors with nullptrs
+{
+ len = size;
+ numItems = 0;
+ if ( len == 0 ) { // zero length
+ vec = 0;
+ return;
+ }
+ vec = NEW(Item,len);
+ TQ_CHECK_PTR( vec );
+ memset( (void*)vec, 0, len*sizeof(Item) ); // fill with nulls
+}
+
+TQGVector::TQGVector( const TQGVector &a ) // make copy of other vector
+ : TQPtrCollection( a )
+{
+ len = a.len;
+ numItems = a.numItems;
+ if ( len == 0 ) {
+ vec = 0;
+ return;
+ }
+ vec = NEW( Item, len );
+ TQ_CHECK_PTR( vec );
+ for ( uint i = 0; i < len; i++ ) {
+ if ( a.vec[i] ) {
+ vec[i] = newItem( a.vec[i] );
+ TQ_CHECK_PTR( vec[i] );
+ } else {
+ vec[i] = 0;
+ }
+ }
+}
+
+TQGVector::~TQGVector()
+{
+ clear();
+}
+
+TQGVector& TQGVector::operator=( const TQGVector &v )
+{
+ if ( &v == this )
+ return *this;
+
+ clear();
+ len = v.len;
+ numItems = v.numItems;
+ if ( len == 0 ) {
+ vec = 0;
+ return *this;
+ }
+ vec = NEW( Item, len );
+ TQ_CHECK_PTR( vec );
+ for ( uint i = 0; i < len; i++ ) {
+ if ( v.vec[i] ) {
+ vec[i] = newItem( v.vec[i] );
+ TQ_CHECK_PTR( vec[i] );
+ } else {
+ vec[i] = 0;
+ }
+ }
+ return *this;
+}
+
+
+bool TQGVector::insert( uint index, Item d ) // insert item at index
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "TQGVector::insert: Index %d out of range", index );
+ return FALSE;
+ }
+#endif
+ if ( vec[index] ) { // remove old item
+ deleteItem( vec[index] );
+ numItems--;
+ }
+ if ( d ) {
+ vec[index] = newItem( d );
+ TQ_CHECK_PTR( vec[index] );
+ numItems++;
+ return vec[index] != 0;
+ } else {
+ vec[index] = 0; // reset item
+ }
+ return TRUE;
+}
+
+bool TQGVector::remove( uint index ) // remove item at index
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "TQGVector::remove: Index %d out of range", index );
+ return FALSE;
+ }
+#endif
+ if ( vec[index] ) { // valid item
+ deleteItem( vec[index] ); // delete it
+ vec[index] = 0; // reset pointer
+ numItems--;
+ }
+ return TRUE;
+}
+
+TQPtrCollection::Item TQGVector::take( uint index ) // take out item
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "TQGVector::take: Index %d out of range", index );
+ return 0;
+ }
+#endif
+ Item d = vec[index]; // don't delete item
+ if ( d )
+ numItems--;
+ vec[index] = 0;
+ return d;
+}
+
+void TQGVector::clear() // clear vector
+{
+ if ( vec ) {
+ for ( uint i=0; i<len; i++ ) { // delete each item
+ if ( vec[i] )
+ deleteItem( vec[i] );
+ }
+ DELETE(vec);
+ vec = 0;
+ len = numItems = 0;
+ }
+}
+
+bool TQGVector::resize( uint newsize ) // resize array
+{
+ if ( newsize == len ) // nothing to do
+ return TRUE;
+ if ( vec ) { // existing data
+ if ( newsize < len ) { // shrink vector
+ uint i = newsize;
+ while ( i < len ) { // delete lost items
+ if ( vec[i] ) {
+ deleteItem( vec[i] );
+ numItems--;
+ }
+ i++;
+ }
+ }
+ if ( newsize == 0 ) { // vector becomes empty
+ DELETE(vec);
+ vec = 0;
+ len = numItems = 0;
+ return TRUE;
+ }
+#if defined(DONT_USE_REALLOC)
+ if ( newsize == 0 ) {
+ DELETE(vec);
+ vec = 0;
+ return FALSE;
+ }
+ Item *newvec = NEW(Item,newsize); // manual realloc
+ if (!newvec)
+ return FALSE;
+ memcpy( newvec, vec, (len < newsize ? len : newsize)*sizeof(Item) );
+ DELETE(vec);
+ vec = newvec;
+#else
+ Item *newvec = (Item*)realloc( (char *)vec, newsize*sizeof(Item) );
+ if (!newvec)
+ return FALSE;
+ vec = newvec;
+#endif
+ } else { // create new vector
+ vec = NEW(Item,newsize);
+ if (!vec)
+ return FALSE;
+ len = numItems = 0;
+ }
+ if ( newsize > len ) // init extra space added
+ memset( (void*)&vec[len], 0, (newsize-len)*sizeof(Item) );
+ len = newsize;
+ return TRUE;
+}
+
+
+bool TQGVector::fill( Item d, int flen ) // resize and fill vector
+{
+ if ( flen < 0 )
+ flen = len; // default: use vector length
+ else if ( !resize( flen ) )
+ return FALSE;
+ for ( uint i=0; i<(uint)flen; i++ ) // insert d at every index
+ insert( i, d );
+ return TRUE;
+}
+
+
+static TQGVector *sort_vec=0; // current sort vector
+
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+#ifdef TQ_OS_TEMP
+static int _cdecl cmp_vec( const void *n1, const void *n2 )
+#else
+static int cmp_vec( const void *n1, const void *n2 )
+#endif
+{
+ return sort_vec->compareItems( *((TQPtrCollection::Item*)n1), *((TQPtrCollection::Item*)n2) );
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+
+void TQGVector::sort() // sort vector
+{
+ if ( count() == 0 ) // no elements
+ return;
+ register Item *start = &vec[0];
+ register Item *end = &vec[len-1];
+ Item tmp;
+ for (;;) { // put all zero elements behind
+ while ( start < end && *start != 0 )
+ start++;
+ while ( end > start && *end == 0 )
+ end--;
+ if ( start < end ) {
+ tmp = *start;
+ *start = *end;
+ *end = tmp;
+ } else {
+ break;
+ }
+ }
+
+#ifdef TQT_THREAD_SUPPORT
+ TQMutexLocker locker( tqt_global_mutexpool ?
+ tqt_global_mutexpool->get( &sort_vec ) : 0 );
+#endif // TQT_THREAD_SUPPORT
+
+ sort_vec = (TQGVector*)this;
+ qsort( vec, count(), sizeof(Item), cmp_vec );
+ sort_vec = 0;
+}
+
+int TQGVector::bsearch( Item d ) const // binary search; when sorted
+{
+ if ( !len )
+ return -1;
+ if ( !d ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQGVector::bsearch: Cannot search for null object" );
+#endif
+ return -1;
+ }
+ int n1 = 0;
+ int n2 = len - 1;
+ int mid = 0;
+ bool found = FALSE;
+ while ( n1 <= n2 ) {
+ int res;
+ mid = (n1 + n2)/2;
+ if ( vec[mid] == 0 ) // null item greater
+ res = -1;
+ else
+ res = ((TQGVector*)this)->compareItems( d, vec[mid] );
+ if ( res < 0 )
+ n2 = mid - 1;
+ else if ( res > 0 )
+ n1 = mid + 1;
+ else { // found it
+ found = TRUE;
+ break;
+ }
+ }
+ if ( !found )
+ return -1;
+ // search to first of equal items
+ while ( (mid - 1 >= 0) && !((TQGVector*)this)->compareItems(d, vec[mid-1]) )
+ mid--;
+ return mid;
+}
+
+int TQGVector::tqfindRef( Item d, uint index) const // tqfind exact item in vector
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( index > len ) { // range error
+ qWarning( "TQGVector::tqfindRef: Index %d out of range", index );
+ return -1;
+ }
+#endif
+ for ( uint i=index; i<len; i++ ) {
+ if ( vec[i] == d )
+ return i;
+ }
+ return -1;
+}
+
+int TQGVector::tqfind( Item d, uint index ) const // tqfind equal item in vector
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( index >= len ) { // range error
+ qWarning( "TQGVector::tqfind: Index %d out of range", index );
+ return -1;
+ }
+#endif
+ for ( uint i=index; i<len; i++ ) {
+ if ( vec[i] == 0 && d == 0 ) // found null item
+ return i;
+ if ( vec[i] && ((TQGVector*)this)->compareItems( vec[i], d ) == 0 )
+ return i;
+ }
+ return -1;
+}
+
+uint TQGVector::tqcontainsRef( Item d ) const // get number of exact matches
+{
+ uint count = 0;
+ for ( uint i=0; i<len; i++ ) {
+ if ( vec[i] == d )
+ count++;
+ }
+ return count;
+}
+
+uint TQGVector::tqcontains( Item d ) const // get number of equal matches
+{
+ uint count = 0;
+ for ( uint i=0; i<len; i++ ) {
+ if ( vec[i] == 0 && d == 0 ) // count null items
+ count++;
+ if ( vec[i] && ((TQGVector*)this)->compareItems( vec[i], d ) == 0 )
+ count++;
+ }
+ return count;
+}
+
+bool TQGVector::insertExpand( uint index, Item d )// insert and grow if necessary
+{
+ if ( index >= len ) {
+ if ( !resize( index+1 ) ) // no memory
+ return FALSE;
+ }
+ insert( index, d );
+ return TRUE;
+}
+
+void TQGVector::toList( TQGList *list ) const // store items in list
+{
+ list->clear();
+ for ( uint i=0; i<len; i++ ) {
+ if ( vec[i] )
+ list->append( vec[i] );
+ }
+}
+
+
+void TQGVector::warningIndexRange( uint i )
+{
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQGVector::operator[]: Index %d out of range", i );
+#else
+ TQ_UNUSED( i )
+#endif
+}
+
+
+/*****************************************************************************
+ TQGVector stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQDataStream &operator>>( TQDataStream &s, TQGVector &vec )
+{ // read vector
+ return vec.read( s );
+}
+
+TQDataStream &operator<<( TQDataStream &s, const TQGVector &vec )
+{ // write vector
+ return vec.write( s );
+}
+
+TQDataStream &TQGVector::read( TQDataStream &s ) // read vector from stream
+{
+ uint num;
+ s >> num; // read number of items
+ clear(); // clear vector
+ resize( num );
+ for (uint i=0; i<num; i++) { // read all items
+ Item d;
+ read( s, d );
+ TQ_CHECK_PTR( d );
+ if ( !d ) // no memory
+ break;
+ vec[i] = d;
+ }
+ return s;
+}
+
+TQDataStream &TQGVector::write( TQDataStream &s ) const
+{ // write vector to stream
+ uint num = count();
+ s << num; // number of items to write
+ num = size();
+ for (uint i=0; i<num; i++) { // write non-null items
+ if ( vec[i] )
+ write( s, vec[i] );
+ }
+ return s;
+}
+
+/* Returns whether v equals this vector or not */
+
+bool TQGVector::operator==( const TQGVector &v ) const
+{
+ if ( size() != v.size() )
+ return FALSE;
+ if ( count() != v.count() )
+ return FALSE;
+ for ( int i = 0; i < (int)size(); ++i ) {
+ if ( ( (TQGVector*)this )->compareItems( at( i ), v.at( i ) ) != 0 )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+#endif // TQT_NO_DATASTREAM
diff --git a/tqtinterface/qt4/src/tools/tqgvector.h b/tqtinterface/qt4/src/tools/tqgvector.h
new file mode 100644
index 0000000..1cc5937
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqgvector.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Definition of TQGVector class
+**
+** Created : 930907
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGVECTOR_H
+#define TQGVECTOR_H
+
+#ifndef TQT_H
+#include "tqptrcollection.h"
+#endif // TQT_H
+
+
+class TQ_EXPORT TQGVector : public TQPtrCollection // generic vector
+{
+friend class TQGList; // needed by TQGList::toVector
+public:
+#ifndef TQT_NO_DATASTREAM
+ TQDataStream &read( TQDataStream & ); // read vector from stream
+ TQDataStream &write( TQDataStream & ) const; // write vector to stream
+#endif
+ virtual int compareItems( Item, Item );
+
+protected:
+ TQGVector(); // create empty vector
+ TQGVector( uint size ); // create vector with nullptrs
+ TQGVector( const TQGVector &v ); // make copy of other vector
+ ~TQGVector();
+
+ TQGVector &operator=( const TQGVector &v ); // assign from other vector
+ bool operator==( const TQGVector &v ) const;
+
+ Item *data() const { return vec; }
+ uint size() const { return len; }
+ uint count() const { return numItems; }
+
+ bool insert( uint index, Item ); // insert item at index
+ bool remove( uint index ); // remove item
+ Item take( uint index ); // take out item
+
+ void clear(); // clear vector
+ bool resize( uint newsize ); // resize vector
+
+ bool fill( Item, int flen ); // resize and fill vector
+
+ void sort(); // sort vector
+ int bsearch( Item ) const; // binary search (when sorted)
+
+ int tqfindRef( Item, uint index ) const; // tqfind exact item in vector
+ int tqfind( Item, uint index ) const; // tqfind equal item in vector
+ uint tqcontainsRef( Item ) const; // get number of exact matches
+ uint tqcontains( Item ) const; // get number of equal matches
+
+ Item at( uint index ) const // return indexed item
+ {
+#if defined(TQT_CHECK_RANGE)
+ if ( index >= len )
+ warningIndexRange( index );
+#endif
+ return vec[index];
+ }
+
+ bool insertExpand( uint index, Item ); // insert, expand if necessary
+
+ void toList( TQGList * ) const; // put items in list
+
+#ifndef TQT_NO_DATASTREAM
+ virtual TQDataStream &read( TQDataStream &, Item & );
+ virtual TQDataStream &write( TQDataStream &, Item ) const;
+#endif
+private:
+ Item *vec;
+ uint len;
+ uint numItems;
+
+ static void warningIndexRange( uint );
+};
+
+
+/*****************************************************************************
+ TQGVector stream functions
+ *****************************************************************************/
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQGVector & );
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQGVector & );
+#endif
+
+#endif // TQGVECTOR_H
diff --git a/tqtinterface/qt4/src/tools/tqintcache.h b/tqtinterface/qt4/src/tools/tqintcache.h
new file mode 100644
index 0000000..ed48fc3
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqintcache.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Definition of TQIntCache template class
+**
+** Created : 950209
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQINTCACHE_H
+#define TQINTCACHE_H
+
+#ifndef TQT_H
+#include "tqgcache.h"
+#endif // TQT_H
+
+
+template<class type>
+class TQIntCache
+#ifdef TQ_TQDOC
+ : public TQPtrCollection
+#else
+ : public TQGCache
+#endif
+{
+public:
+ TQIntCache( const TQIntCache<type> &c ) : TQGCache(c) {}
+ TQIntCache( int maxCost=100, int size=17 )
+ : TQGCache( maxCost, size, IntKey, FALSE, FALSE ) {}
+ ~TQIntCache() { clear(); }
+ TQIntCache<type> &operator=( const TQIntCache<type> &c )
+ { return (TQIntCache<type>&)TQGCache::operator=(c); }
+ int maxCost() const { return TQGCache::maxCost(); }
+ int totalCost() const { return TQGCache::totalCost(); }
+ void setMaxCost( int m) { TQGCache::setMaxCost(m); }
+ uint count() const { return TQGCache::count(); }
+ uint size() const { return TQGCache::size(); }
+ bool isEmpty() const { return TQGCache::count() == 0; }
+ bool insert( long k, const type *d, int c=1, int p=0 )
+ { return TQGCache::insert_other((const char*)k,(Item)d,c,p); }
+ bool remove( long k )
+ { return TQGCache::remove_other((const char*)k); }
+ type *take( long k )
+ { return (type *)TQGCache::take_other((const char*)k);}
+ void clear() { TQGCache::clear(); }
+ type *tqfind( long k, bool ref=TRUE ) const
+ { return (type *)TQGCache::tqfind_other( (const char*)k,ref);}
+ type *operator[]( long k ) const
+ { return (type *)TQGCache::tqfind_other( (const char*)k); }
+ void statistics() const { TQGCache::statistics(); }
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQIntCache<void>::deleteItem( TQPtrCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void TQIntCache<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+template<class type>
+class TQIntCacheIterator : public TQGCacheIterator
+{
+public:
+ TQIntCacheIterator( const TQIntCache<type> &c )
+ : TQGCacheIterator( (TQGCache &)c ) {}
+ TQIntCacheIterator( const TQIntCacheIterator<type> &ci )
+ : TQGCacheIterator((TQGCacheIterator &)ci) {}
+ TQIntCacheIterator<type> &operator=( const TQIntCacheIterator<type>&ci )
+ { return ( TQIntCacheIterator<type>&)TQGCacheIterator::operator=( ci );}
+ uint count() const { return TQGCacheIterator::count(); }
+ bool isEmpty() const { return TQGCacheIterator::count() == 0; }
+ bool atFirst() const { return TQGCacheIterator::atFirst(); }
+ bool atLast() const { return TQGCacheIterator::atLast(); }
+ type *toFirst() { return (type *)TQGCacheIterator::toFirst(); }
+ type *toLast() { return (type *)TQGCacheIterator::toLast(); }
+ operator type *() const { return (type *)TQGCacheIterator::get(); }
+ type *current() const { return (type *)TQGCacheIterator::get(); }
+ long currentKey() const { return (long)TQGCacheIterator::getKeyInt();}
+ type *operator()() { return (type *)TQGCacheIterator::operator()();}
+ type *operator++() { return (type *)TQGCacheIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)TQGCacheIterator::operator+=(j);}
+ type *operator--() { return (type *)TQGCacheIterator::operator--(); }
+ type *operator-=(uint j) { return (type *)TQGCacheIterator::operator-=(j);}
+};
+
+
+#endif // TQINTCACHE_H
diff --git a/tqtinterface/qt4/src/tools/tqintdict.h b/tqtinterface/qt4/src/tools/tqintdict.h
new file mode 100644
index 0000000..dc6cc2e
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqintdict.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Definition of TQIntDict template class
+**
+** Created : 940624
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQINTDICT_H
+#define TQINTDICT_H
+
+#ifndef TQT_H
+#include "tqgdict.h"
+#endif // TQT_H
+
+template<class type>
+class TQIntDict
+#ifdef TQ_TQDOC
+ : public TQPtrCollection
+#else
+ : public TQGDict
+#endif
+{
+public:
+ TQIntDict(int size=17) : TQGDict(size,IntKey,0,0) {}
+ TQIntDict( const TQIntDict<type> &d ) : TQGDict(d) {}
+ ~TQIntDict() { clear(); }
+ TQIntDict<type> &operator=(const TQIntDict<type> &d)
+ { return (TQIntDict<type>&)TQGDict::operator=(d); }
+ uint count() const { return TQGDict::count(); }
+ uint size() const { return TQGDict::size(); }
+ bool isEmpty() const { return TQGDict::count() == 0; }
+ void insert( long k, const type *d )
+ { TQGDict::look_int(k,(Item)d,1); }
+ void tqreplace( long k, const type *d )
+ { TQGDict::look_int(k,(Item)d,2); }
+ bool remove( long k ) { return TQGDict::remove_int(k); }
+ type *take( long k ) { return (type*)TQGDict::take_int(k); }
+ type *tqfind( long k ) const
+ { return (type *)((TQGDict*)this)->TQGDict::look_int(k,0,0); }
+ type *operator[]( long k ) const
+ { return (type *)((TQGDict*)this)->TQGDict::look_int(k,0,0); }
+ void clear() { TQGDict::clear(); }
+ void resize( uint n ) { TQGDict::resize(n); }
+ void statistics() const { TQGDict::statistics(); }
+
+#ifdef TQ_TQDOC
+protected:
+ virtual TQDataStream& read( TQDataStream &, TQPtrCollection::Item & );
+ virtual TQDataStream& write( TQDataStream &, TQPtrCollection::Item ) const;
+#endif
+
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQIntDict<void>::deleteItem( TQPtrCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void TQIntDict<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type*)d;
+}
+
+template<class type>
+class TQIntDictIterator : public TQGDictIterator
+{
+public:
+ TQIntDictIterator(const TQIntDict<type> &d) :TQGDictIterator((TQGDict &)d) {}
+ ~TQIntDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)TQGDictIterator::toFirst(); }
+ operator type *() const { return (type *)TQGDictIterator::get(); }
+ type *current() const { return (type *)TQGDictIterator::get(); }
+ long currentKey() const { return TQGDictIterator::getKeyInt(); }
+ type *operator()() { return (type *)TQGDictIterator::operator()(); }
+ type *operator++() { return (type *)TQGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)TQGDictIterator::operator+=(j);}
+};
+
+#define TQ_DEFINED_TQINTDICT
+#include "tqwinexport.h"
+#endif // TQINTDICT_H
diff --git a/tqtinterface/qt4/src/tools/tqiodevice.cpp b/tqtinterface/qt4/src/tools/tqiodevice.cpp
new file mode 100644
index 0000000..299d949
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqiodevice.cpp
@@ -0,0 +1,769 @@
+/****************************************************************************
+**
+** Implementation of TQIODevice class
+**
+** Created : 940913
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqiodevice.h"
+
+#ifdef USE_QT4
+
+#else // USE_QT4
+
+/*!
+ \class TQIODevice tqiodevice.h
+ \reentrant
+
+ \brief The TQIODevice class is the base class of I/O tqdevices.
+
+ \ingroup io
+
+ An I/O tqdevice represents a medium that one can read bytes from
+ and/or write bytes to. The TQIODevice class is the abstract
+ superclass of all such tqdevices; classes such as TQFile, TQBuffer and
+ TQSocket inherit TQIODevice and implement virtual functions such as
+ write() appropriately.
+
+ Although applications sometimes use TQIODevice directly, it is
+ usually better to use TQTextStream and TQDataStream, which provide
+ stream operations on any TQIODevice subclass. TQTextStream provides
+ text-oriented stream functionality (for human-readable ASCII
+ files, for example), whereas TQDataStream deals with binary data in
+ a totally platform-independent manner.
+
+ The public member functions in TQIODevice roughly fall into two
+ groups: the action functions and the state access functions. The
+ most important action functions are:
+
+ \list
+
+ \i open() opens a tqdevice for reading and/or writing, depending on
+ the mode argument.
+
+ \i close() closes the tqdevice and tidies up (e.g. flushes buffered
+ data)
+
+ \i readBlock() reads a block of data from the tqdevice.
+
+ \i writeBlock() writes a block of data to the tqdevice.
+
+ \i readLine() reads a line (of text, usually) from the tqdevice.
+
+ \i flush() ensures that all buffered data are written to the real tqdevice.
+
+ \endlist
+
+ There are also some other, less used, action functions:
+
+ \list
+
+ \i getch() reads a single character.
+
+ \i ungetch() forgets the last call to getch(), if possible.
+
+ \i putch() writes a single character.
+
+ \i size() returns the size of the tqdevice, if there is one.
+
+ \i at() returns the current read/write pointer's position, if there
+ is one for this tqdevice, or it moves the pointer if given an offset.
+
+ \i atEnd() indicates whether there is more to read, if this is
+ meaningful for this tqdevice.
+
+ \i reset() moves the read/write pointer to the start of the
+ tqdevice, if that is possible for this tqdevice.
+
+ \endlist
+
+ The state access are all "get" functions. The TQIODevice subclass
+ calls setState() to update the state, and simple access functions
+ tell the user of the tqdevice what the tqdevice's state is. Here are
+ the settings, and their associated access functions:
+
+ \list
+
+ \i Access type. Some tqdevices are direct access (it is possible
+ to read/write anywhere), whereas others are sequential. TQIODevice
+ provides the access functions (isDirectAccess(),
+ isSequentialAccess(), and isCombinedAccess()) to tell users what a
+ given I/O tqdevice supports.
+
+ \i Buffering. Some tqdevices are accessed in raw mode, whereas
+ others are buffered. Buffering usually provides greater
+ efficiency, particularly for small read/write operations.
+ isBuffered() tells the user whether a given tqdevice is buffered.
+ (This can often be set by the application in the call to open().)
+
+ \i Synchronicity. Synchronous tqdevices work immediately (for
+ example, files). When you read from a file, the file delivers its
+ data straight away. Other kinds of tqdevice, such as a socket
+ connected to a HTTP server, may not deliver the data until seconds
+ after you ask to read it. isSynchronous() and isAsynchronous()
+ tell the user how this tqdevice operates.
+
+ \i CR/LF translation. For simplicity, applications often like to
+ see just a single CR/LF style, and TQIODevice subclasses can
+ provide this. isTranslated() returns TRUE if this object
+ translates CR/LF to just LF. (This can often be set by the
+ application in the call to open().)
+
+ \i Permissions. Some files cannot be written. For example,
+ isReadable(), isWritable() and isReadWrite() tell the application
+ whether it can read from and write to a given tqdevice. (This can
+ often be set by the application in the call to open().)
+
+ \i Finally, isOpen() returns TRUE if the tqdevice is open, i.e.
+ after an open() call.
+
+ \endlist
+
+ TQIODevice provides numerous pure virtual functions that you need
+ to implement when subclassing it. Here is a skeleton subclass with
+ all the members you are sure to need and some that you will
+ probably need:
+
+ \code
+ class MyDevice : public TQIODevice
+ {
+ public:
+ MyDevice();
+ ~MyDevice();
+
+ bool open( int mode );
+ void close();
+ void flush();
+
+ uint size() const;
+ int at() const; // non-pure virtual
+ bool at( int ); // non-pure virtual
+ bool atEnd() const; // non-pure virtual
+
+ int readBlock( char *data, uint maxlen );
+ int writeBlock( const char *data, uint len );
+ int readLine( char *data, uint maxlen );
+
+ int getch();
+ int putch( int );
+ int ungetch( int );
+ };
+ \endcode
+
+ The three non-pure virtual functions need not be reimplemented for
+ sequential tqdevices.
+
+ \sa TQDataStream, TQTextStream
+*/
+
+/*!
+ \enum TQIODevice::Offset
+
+ The offset within the tqdevice.
+*/
+
+
+/*!
+ Constructs an I/O tqdevice.
+*/
+
+TQIODevice::TQIODevice()
+{
+ ioMode = 0; // initial mode
+ ioSt = IO_Ok;
+ ioIndex = 0;
+}
+
+/*!
+ Destroys the I/O tqdevice.
+*/
+
+TQIODevice::~TQIODevice()
+{
+}
+
+
+/*!
+ \fn int TQIODevice::flags() const
+
+ Returns the current I/O tqdevice flags setting.
+
+ Flags consists of mode flags and state flags.
+
+ \sa mode(), state()
+*/
+
+/*!
+ \fn int TQIODevice::mode() const
+
+ Returns bits OR'ed together that specify the current operation
+ mode.
+
+ These are the flags that were given to the open() function.
+
+ The flags are \c IO_ReadOnly, \c IO_WriteOnly, \c IO_ReadWrite,
+ \c IO_Append, \c IO_Truncate and \c IO_Translate.
+*/
+
+/*!
+ \fn int TQIODevice::state() const
+
+ Returns bits OR'ed together that specify the current state.
+
+ The flags are: \c IO_Open.
+
+ Subclasses may define additional flags.
+*/
+
+/*!
+ \fn bool TQIODevice::isDirectAccess() const
+
+ Returns TRUE if the I/O tqdevice is a direct access tqdevice;
+ otherwise returns FALSE, i.e. if the tqdevice is a sequential access
+ tqdevice.
+
+ \sa isSequentialAccess()
+*/
+
+/*!
+ \fn bool TQIODevice::isSequentialAccess() const
+
+ Returns TRUE if the tqdevice is a sequential access tqdevice;
+ otherwise returns FALSE, i.e. if the tqdevice is a direct access
+ tqdevice.
+
+ Operations involving size() and at(int) are not valid on
+ sequential tqdevices.
+
+ \sa isDirectAccess()
+*/
+
+/*!
+ \fn bool TQIODevice::isCombinedAccess() const
+
+ Returns TRUE if the I/O tqdevice is a combined access (both direct
+ and sequential) tqdevice; otherwise returns FALSE.
+
+ This access method is currently not in use.
+*/
+
+/*!
+ \fn bool TQIODevice::isBuffered() const
+
+ Returns TRUE if the I/O tqdevice is a buffered tqdevice; otherwise
+ returns FALSE, i.e. the tqdevice is a raw tqdevice.
+
+ \sa isRaw()
+*/
+
+/*!
+ \fn bool TQIODevice::isRaw() const
+
+ Returns TRUE if the tqdevice is a raw tqdevice; otherwise returns
+ FALSE, i.e. if the tqdevice is a buffered tqdevice.
+
+ \sa isBuffered()
+*/
+
+/*!
+ \fn bool TQIODevice::isSynchronous() const
+
+ Returns TRUE if the I/O tqdevice is a synchronous tqdevice; otherwise
+ returns FALSE, i.e. the tqdevice is an asynchronous tqdevice.
+
+ \sa isAsynchronous()
+*/
+
+/*!
+ \fn bool TQIODevice::isAsynchronous() const
+
+ Returns TRUE if the tqdevice is an asynchronous tqdevice; otherwise
+ returns FALSE, i.e. if the tqdevice is a synchronous tqdevice.
+
+ This mode is currently not in use.
+
+ \sa isSynchronous()
+*/
+
+/*!
+ \fn bool TQIODevice::isTranslated() const
+
+ Returns TRUE if the I/O tqdevice translates carriage-return and
+ linefeed characters; otherwise returns FALSE.
+
+ A TQFile is translated if it is opened with the \c IO_Translate
+ mode flag.
+*/
+
+/*!
+ \fn bool TQIODevice::isReadable() const
+
+ Returns TRUE if the I/O tqdevice was opened using \c IO_ReadOnly or
+ \c IO_ReadWrite mode; otherwise returns FALSE.
+
+ \sa isWritable(), isReadWrite()
+*/
+
+/*!
+ \fn bool TQIODevice::isWritable() const
+
+ Returns TRUE if the I/O tqdevice was opened using \c IO_WriteOnly or
+ \c IO_ReadWrite mode; otherwise returns FALSE.
+
+ \sa isReadable(), isReadWrite()
+*/
+
+/*!
+ \fn bool TQIODevice::isReadWrite() const
+
+ Returns TRUE if the I/O tqdevice was opened using \c IO_ReadWrite
+ mode; otherwise returns FALSE.
+
+ \sa isReadable(), isWritable()
+*/
+
+/*!
+ \fn bool TQIODevice::isInactive() const
+
+ Returns TRUE if the I/O tqdevice state is 0, i.e. the tqdevice is not
+ open; otherwise returns FALSE.
+
+ \sa isOpen()
+*/
+
+/*!
+ \fn bool TQIODevice::isOpen() const
+
+ Returns TRUE if the I/O tqdevice has been opened; otherwise returns
+ FALSE.
+
+ \sa isInactive()
+*/
+
+
+/*!
+ \fn int TQIODevice::status() const
+
+ Returns the I/O tqdevice status.
+
+ The I/O tqdevice status returns an error code. If open() returns
+ FALSE or readBlock() or writeBlock() return -1, this function can
+ be called to tqfind out the reason why the operation failed.
+
+ \keyword IO_Ok
+ \keyword IO_ReadError
+ \keyword IO_WriteError
+ \keyword IO_FatalError
+ \keyword IO_OpenError
+ \keyword IO_ConnectError
+ \keyword IO_AbortError
+ \keyword IO_TimeOutError
+ \keyword IO_UnspecifiedError
+
+ The status codes are:
+ \table
+ \header \i tqStatus code \i Meaning
+ \row \i \c IO_Ok \i The operation was successful.
+ \row \i \c IO_ReadError \i Could not read from the tqdevice.
+ \row \i \c IO_WriteError \i Could not write to the tqdevice.
+ \row \i \c IO_FatalError \i A fatal unrecoverable error occurred.
+ \row \i \c IO_OpenError \i Could not open the tqdevice.
+ \row \i \c IO_ConnectError \i Could not connect to the tqdevice.
+ \row \i \c IO_AbortError \i The operation was unexpectedly aborted.
+ \row \i \c IO_TimeOutError \i The operation timed out.
+ \row \i \c IO_UnspecifiedError \i An unspecified error happened on close.
+ \endtable
+
+ \sa resetqStatus()
+*/
+
+/*!
+ \fn void TQIODevice::resetqStatus()
+
+ Sets the I/O tqdevice status to \c IO_Ok.
+
+ \sa status()
+*/
+
+
+/*!
+ \fn void TQIODevice::setFlags( int flags )
+
+ Used by subclasses to set the tqdevice flags to the \a flags specified.
+*/
+
+/*!
+ \fn void TQIODevice::setType( int type )
+
+ Used by subclasses to set the tqdevice type to the \a type specified.
+*/
+
+void TQIODevice::setType( int t )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( (t & IO_TypeMask) != t )
+ qWarning( "TQIODevice::setType: Specified type out of range" );
+#endif
+ ioMode &= ~IO_TypeMask; // reset type bits
+ ioMode |= t;
+}
+
+/*!
+ \fn void TQIODevice::setMode( int mode )
+
+ Used by subclasses to set the tqdevice mode to the \a mode specified.
+*/
+
+void TQIODevice::setMode( int m )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( (m & IO_ModeMask) != m )
+ qWarning( "TQIODevice::setMode: Specified mode out of range" );
+#endif
+ ioMode &= ~IO_ModeMask; // reset mode bits
+ ioMode |= m;
+}
+
+/*!
+ \fn void TQIODevice::setState( int state )
+
+ Used by subclasses to set the tqdevice state to the \a state specified.
+*/
+
+void TQIODevice::setState( int s )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( ((uint)s & IO_StateMask) != (uint)s )
+ qWarning( "TQIODevice::setState: Specified state out of range" );
+#endif
+ ioMode &= ~IO_StateMask; // reset state bits
+ ioMode |= (uint)s;
+}
+
+/*!
+ Used by subclasses to set the tqdevice status (not state) to \a s.
+*/
+
+void TQIODevice::setqStatus( int s )
+{
+ ioSt = s;
+}
+
+
+/*!
+ \fn bool TQIODevice::open( int mode )
+
+ Opens the I/O tqdevice using the specified \a mode. Returns TRUE if
+ the tqdevice was successfully opened; otherwise returns FALSE.
+
+ The mode parameter \a mode must be an OR'ed combination of the
+ following flags.
+ \table
+ \header \i Mode flags \i Meaning
+ \row \i \c IO_Raw \i specifies raw (unbuffered) file access.
+ \row \i \c IO_ReadOnly \i opens a file in read-only mode.
+ \row \i \c IO_WriteOnly \i opens a file in write-only mode.
+ \row \i \c IO_ReadWrite \i opens a file in read/write mode.
+ \row \i \c IO_Append \i sets the file index to the end of the file.
+ \row \i \c IO_Truncate \i truncates the file.
+ \row \i \c IO_Translate \i enables carriage returns and linefeed
+ translation for text files under MS-DOS, Windows and Macintosh. On
+ Unix systems this flag has no effect. Use with caution as it will
+ also transform every linefeed written to the file into a CRLF
+ pair. This is likely to corrupt your file if you write write
+ binary data. Cannot be combined with \c IO_Raw.
+ \endtable
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa close()
+*/
+
+/*!
+ \fn void TQIODevice::close()
+
+ Closes the I/O tqdevice.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa open()
+*/
+
+/*!
+ \fn void TQIODevice::flush()
+
+ Flushes an open I/O tqdevice.
+
+ This virtual function must be reimplemented by all subclasses.
+*/
+
+
+/*!
+ \fn TQIODevice::Offset TQIODevice::size() const
+
+ Virtual function that returns the size of the I/O tqdevice.
+
+ \sa at()
+*/
+
+/*!
+ Virtual function that returns the current I/O tqdevice position.
+
+ This is the position of the data read/write head of the I/O
+ tqdevice.
+
+ \sa size()
+*/
+
+TQIODevice::Offset TQIODevice::at() const
+{
+ return ioIndex;
+}
+
+
+/*
+ The following is a "bad" overload, since it does "not behave essentially
+ the same" like the above. So don't use \overload in the documentation of
+ this function and we have to live with the qdoc warning which is generated
+ for this.
+*/
+/*!
+ Virtual function that sets the I/O tqdevice position to \a pos.
+ Returns TRUE if the position was successfully set, i.e. \a pos is
+ within range and the seek was successful; otherwise returns FALSE.
+
+ \sa size()
+*/
+
+bool TQIODevice::at( Offset pos )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( pos > size() ) {
+#if defined(TQT_ABI_QT4)
+ qWarning( "TQIODevice::at: Index %lld out of range", pos );
+#else
+ qWarning( "TQIODevice::at: Index %lu out of range", pos );
+#endif
+ return FALSE;
+ }
+#endif
+ ioIndex = pos;
+ return TRUE;
+}
+
+/*!
+ Virtual function that returns TRUE if the I/O tqdevice position is
+ at the end of the input; otherwise returns FALSE.
+*/
+
+bool TQIODevice::atEnd() const
+{
+ if ( isSequentialAccess() || isTranslated() ) {
+ TQIODevice* that = (TQIODevice*)this;
+ const int oldtqStatus = ioSt;
+ int c = that->getch();
+ bool result = c < 0;
+ that->ungetch(c);
+ if (ioSt != oldtqStatus)
+ that->ioSt = oldtqStatus;
+ return result;
+ } else {
+ return at() == size();
+ }
+}
+
+/*!
+ \fn bool TQIODevice::reset()
+
+ Sets the tqdevice index position to 0.
+
+ \sa at()
+*/
+
+
+/*!
+ \fn int TQIODevice::readBlock( char *data, TQ_ULONG maxlen )
+
+ Reads at most \a maxlen bytes from the I/O tqdevice into \a data and
+ returns the number of bytes actually read.
+
+ This function should return -1 if a fatal error occurs and should
+ return 0 if there are no bytes to read.
+
+ The tqdevice must be opened for reading, and \a data must not be 0.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa writeBlock() isOpen() isReadable()
+*/
+
+/*!
+ This convenience function returns all of the remaining data in the
+ tqdevice.
+*/
+TQByteArray TQIODevice::readAll()
+{
+ if ( isDirectAccess() ) {
+ // we know the size
+ int n = size()-at(); // ### fix for 64-bit or large files?
+ int totalRead = 0;
+ TQByteArray ba( n );
+ char* c = ba.data();
+ while ( n ) {
+ int r = readBlock( c, n );
+ if ( r < 0 )
+ return TQByteArray();
+ n -= r;
+ c += r;
+ totalRead += r;
+ // If we have a translated file, then it is possible that
+ // we read less bytes than size() reports
+ if ( atEnd() ) {
+ ba.resize( totalRead );
+ break;
+ }
+ }
+ return ba;
+ } else {
+ // read until we reach the end
+ const int blocksize = 512;
+ int nread = 0;
+ TQByteArray ba;
+ while ( !atEnd() ) {
+ ba.resize( nread + blocksize );
+ int r = readBlock( ba.data()+nread, blocksize );
+ if ( r < 0 )
+ return TQByteArray();
+ nread += r;
+ }
+ ba.resize( nread );
+ return ba;
+ }
+}
+
+/*!
+ \fn int TQIODevice::writeBlock( const char *data, TQ_ULONG len )
+
+ Writes \a len bytes from \a data to the I/O tqdevice and returns the
+ number of bytes actually written.
+
+ This function should return -1 if a fatal error occurs.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa readBlock()
+*/
+
+/*!
+ \overload
+
+ This convenience function is the same as calling writeBlock(
+ data.data(), data.size() ).
+*/
+TQ_LONG TQIODevice::writeBlock( const TQByteArray& data )
+{
+ return writeBlock( data.data(), data.size() );
+}
+
+/*!
+ Reads a line of text, (or up to \a maxlen bytes if a newline isn't
+ encountered) plus a terminating '\0' into \a data. If there is a
+ newline at the end if the line, it is not stripped.
+
+ Returns the number of bytes read including the terminating '\0',
+ or -1 if an error occurred.
+
+ This virtual function can be reimplemented much more efficiently
+ by the most subclasses.
+
+ \sa readBlock(), TQTextStream::readLine()
+*/
+
+TQ_LONG TQIODevice::readLine( char *data, TQ_ULONG maxlen )
+{
+ if ( maxlen == 0 ) // application bug?
+ return 0;
+ char *p = data;
+ while ( --maxlen && (readBlock(p,1)>0) ) { // read one byte at a time
+ if ( *p++ == '\n' ) // end of line
+ break;
+ }
+ *p++ = '\0';
+ return p - data;
+}
+
+
+/*!
+ \fn int TQIODevice::getch()
+
+ Reads a single byte/character from the I/O tqdevice.
+
+ Returns the byte/character read, or -1 if the end of the I/O
+ tqdevice has been reached.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa putch(), ungetch()
+*/
+
+/*!
+ \fn int TQIODevice::putch( int ch )
+
+ Writes the character \a ch to the I/O tqdevice.
+
+ Returns \a ch, or -1 if an error occurred.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa getch(), ungetch()
+*/
+
+/*!
+ \fn int TQIODevice::ungetch( int ch )
+
+ Puts the character \a ch back into the I/O tqdevice and decrements
+ the index position if it is not zero.
+
+ This function is normally called to "undo" a getch() operation.
+
+ Returns \a ch, or -1 if an error occurred.
+
+ This virtual function must be reimplemented by all subclasses.
+
+ \sa getch(), putch()
+*/
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/tools/tqiodevice.h b/tqtinterface/qt4/src/tools/tqiodevice.h
new file mode 100644
index 0000000..6fccc9d
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqiodevice.h
@@ -0,0 +1,311 @@
+/****************************************************************************
+**
+** Definition of TQIODevice class
+**
+** Created : 940913
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQIODEVICE_H
+#define TQIODEVICE_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqcstring.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qiodevice.h>
+#include <Qt/qfile.h>
+#include <iostream>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+#define IO_Direct 0x0100 // direct access tqdevice
+#define IO_Sequential 0x0200 // sequential access tqdevice
+#define IO_Combined 0x0300 // combined direct/sequential
+#define IO_TypeMask 0x0f00
+
+// IO handling modes
+
+#define IO_Raw 0x0040 // raw access (not buffered)
+#define IO_Async 0x0080 // asynchronous mode
+
+// IO tqdevice open modes
+
+#define IO_ReadOnly (QIODevice::OpenModeFlag)0x0001 // readable tqdevice
+#define IO_WriteOnly (QIODevice::OpenModeFlag)0x0002 // writable tqdevice
+#define IO_ReadWrite (QIODevice::OpenModeFlag)0x0003 // read+write tqdevice
+#define IO_Append (QIODevice::OpenModeFlag)0x0004 // append
+#define IO_Truncate (QIODevice::OpenModeFlag)0x0008 // truncate tqdevice
+#define IO_Translate (QIODevice::OpenModeFlag)0x0010 // translate CR+LF
+#define IO_ModeMask (QIODevice::OpenModeFlag)0x00ff
+
+// IO tqdevice state
+
+#define IO_Open 0x1000 // tqdevice is open
+#define IO_StateMask 0xf000
+
+// IO tqdevice status
+
+#define IO_Ok 0
+#define IO_ReadError 1 // read error
+#define IO_WriteError 2 // write error
+#define IO_FatalError 3 // fatal unrecoverable error
+#define IO_ResourceError 4 // resource limitation
+#define IO_OpenError 5 // cannot open tqdevice
+#define IO_ConnectError 5 // cannot connect to tqdevice
+#define IO_AbortError 6 // abort error
+#define IO_TimeOutError 7 // time out
+#define IO_UnspecifiedError 8 // unspecified error
+
+class TQ_EXPORT TQIODevice : public QIODevice
+{
+public:
+#if defined(TQT_ABI_QT4)
+ typedef TQ_LLONG Offset;
+#else
+ typedef TQ_ULONG Offset;
+#endif
+
+ TQIODevice() : QIODevice() {}
+
+ inline int state() const { return isOpen() ? 0x1000 : 0; }
+ inline int mode() const { return (int) openMode(); }
+ inline int flags() const { return (int) openMode(); }
+ inline bool tqopen( int mode ) { return open((OpenModeFlag)mode); }
+
+ inline Offset at() const { return pos(); }
+ inline bool at(Offset offset) { return seek(offset); }
+ inline Offset tqat() const { return pos(); }
+ inline bool tqat(Offset offset) { return seek(offset); }
+
+// virtual inline qint64 readBlock(char *data, quint64 maxlen) { return read(data, maxlen); }
+// virtual inline qint64 writeBlock(const char *data, quint64 len) { return write(data, len); }
+// virtual inline qint64 writeBlock(const QByteArray &data) { return write(data); }
+ inline qint64 readBlock(char *data, quint64 maxlen) { return read(data, maxlen); }
+ inline qint64 writeBlock(const char *data, quint64 len) { return write(data, len); }
+ inline qint64 writeBlock(const QByteArray &data) { return write(data); }
+
+// virtual inline qint64 readData ( char * data, qint64 maxSize ) { return readBlock(data, maxSize); }
+// virtual inline qint64 writeData ( const char * data, qint64 maxSize ) { return writeBlock(data, maxSize); }
+
+ inline int getch() { char c; return getChar(&c) ? int(uchar(c)) : -1; }
+ inline int putch(int c) { return putChar(char(c)) ? int(uchar(c)) : -1; }
+ inline int ungetch(int c) { ungetChar(uchar(c)); return c; }
+ virtual void flush() = 0;
+
+ inline bool isDirectAccess() const { return !isSequential(); }
+ inline bool isSequentialAccess() const { return isSequential(); }
+ inline bool isCombinedAccess() const { return false; }
+ inline bool isBuffered() const { return true; }
+ inline bool isRaw() const { return false; }
+ inline bool isSynchronous() const { return true; }
+ inline bool isAsynchronous() const { return false; }
+ inline bool isTranslated() const { return (openMode() & Text) != 0; }
+ inline bool isInactive() const { return !isOpen(); }
+
+// inline bool open( int mode ) = 0;
+
+protected:
+ void setFlags( int f ) { setOpenMode((QIODevice::OpenModeFlag)f); }
+ void setType( int ) { printf("[WARNING] TQIODevice::setType() unimplemented\n\r"); }
+ void setMode( int f ) { setOpenMode((QIODevice::OpenModeFlag)f); }
+ void setState( int state ) {
+ switch (state) {
+ case (IO_Open):
+ QIODevice::open(openMode());
+ break;
+ }
+ }
+
+public:
+ typedef int Status;
+ Status status() const {
+#if !defined(QT_NO_QOBJECT)
+ const QFile *f = qobject_cast<const QFile *>(this);
+ if (f) return (int) f->error();
+#endif
+ return isOpen() ? 0 /* IO_Ok */ : 8 /* IO_UnspecifiedError */;
+ }
+ void resetStatus() {
+#if !defined(QT_NO_QOBJECT)
+ QFile *f = qobject_cast<QFile *>(this);
+ if (f) f->unsetError();
+#endif
+ }
+
+ void setqStatus( int ) { std::cout << "[WARNING] TQIODevice::setqStatus() UNIMPLEMENTED\n\r"; }
+ void resetqStatus() { resetStatus(); }
+
+protected:
+ friend class TQFile;
+ friend class TQIODeviceSource;
+ friend class TQImageIO;
+ friend class TQBuffer;
+
+public:
+ // Interoperability
+ static TQIODevice& convertFromQIODevice( QIODevice& qiod );
+};
+
+// Interoperability
+inline static TQIODevice& convertFromQIODevice( QIODevice& qiod ) {
+ return (*static_cast<TQIODevice*>(&qiod));
+}
+
+#else // USE_QT4
+
+// IO tqdevice access types
+
+#define IO_Direct 0x0100 // direct access tqdevice
+#define IO_Sequential 0x0200 // sequential access tqdevice
+#define IO_Combined 0x0300 // combined direct/sequential
+#define IO_TypeMask 0x0f00
+
+// IO handling modes
+
+#define IO_Raw 0x0040 // raw access (not buffered)
+#define IO_Async 0x0080 // asynchronous mode
+
+// IO tqdevice open modes
+
+#define IO_ReadOnly 0x0001 // readable tqdevice
+#define IO_WriteOnly 0x0002 // writable tqdevice
+#define IO_ReadWrite 0x0003 // read+write tqdevice
+#define IO_Append 0x0004 // append
+#define IO_Truncate 0x0008 // truncate tqdevice
+#define IO_Translate 0x0010 // translate CR+LF
+#define IO_ModeMask 0x00ff
+
+// IO tqdevice state
+
+#define IO_Open 0x1000 // tqdevice is open
+#define IO_StateMask 0xf000
+
+// IO tqdevice status
+
+#define IO_Ok 0
+#define IO_ReadError 1 // read error
+#define IO_WriteError 2 // write error
+#define IO_FatalError 3 // fatal unrecoverable error
+#define IO_ResourceError 4 // resource limitation
+#define IO_OpenError 5 // cannot open tqdevice
+#define IO_ConnectError 5 // cannot connect to tqdevice
+#define IO_AbortError 6 // abort error
+#define IO_TimeOutError 7 // time out
+#define IO_UnspecifiedError 8 // unspecified error
+
+
+class TQ_EXPORT TQIODevice
+{
+public:
+#if defined(TQT_ABI_QT4)
+ typedef TQ_LLONG Offset;
+#else
+ typedef TQ_ULONG Offset;
+#endif
+
+ TQIODevice();
+ virtual ~TQIODevice();
+
+ int flags() const { return ioMode; }
+ int mode() const { return ioMode & IO_ModeMask; }
+ int state() const { return ioMode & IO_StateMask; }
+
+ bool isDirectAccess() const { return ((ioMode & IO_Direct) == IO_Direct); }
+ bool isSequentialAccess() const { return ((ioMode & IO_Sequential) == IO_Sequential); }
+ bool isCombinedAccess() const { return ((ioMode & IO_Combined) == IO_Combined); }
+ bool isBuffered() const { return ((ioMode & IO_Raw) != IO_Raw); }
+ bool isRaw() const { return ((ioMode & IO_Raw) == IO_Raw); }
+ bool isSynchronous() const { return ((ioMode & IO_Async) != IO_Async); }
+ bool isAsynchronous() const { return ((ioMode & IO_Async) == IO_Async); }
+ bool isTranslated() const { return ((ioMode & IO_Translate) == IO_Translate); }
+ bool isReadable() const { return ((ioMode & IO_ReadOnly) == IO_ReadOnly); }
+ bool isWritable() const { return ((ioMode & IO_WriteOnly) == IO_WriteOnly); }
+ bool isReadWrite() const { return ((ioMode & IO_ReadWrite) == IO_ReadWrite); }
+ bool isInactive() const { return state() == 0; }
+ bool isOpen() const { return state() == IO_Open; }
+
+ int status() const { return ioSt; }
+ void resetqStatus() { ioSt = IO_Ok; }
+
+ virtual bool open( int mode ) = 0;
+ virtual void close() = 0;
+ virtual void flush() = 0;
+
+ virtual Offset size() const = 0;
+ virtual Offset at() const;
+ virtual bool at( Offset );
+ virtual bool atEnd() const;
+ bool reset() { return at(0); }
+
+ virtual TQ_LONG readBlock( char *data, TQ_ULONG maxlen ) = 0;
+ virtual TQ_LONG writeBlock( const char *data, TQ_ULONG len ) = 0;
+ virtual TQ_LONG readLine( char *data, TQ_ULONG maxlen );
+ TQ_LONG writeBlock( const TQByteArray& data );
+ virtual TQByteArray readAll();
+
+ virtual int getch() = 0;
+ virtual int putch( int ) = 0;
+ virtual int ungetch( int ) = 0;
+
+protected:
+ void setFlags( int f ) { ioMode = f; }
+ void setType( int );
+ void setMode( int );
+ void setState( int );
+ void setqStatus( int );
+ Offset ioIndex;
+
+private:
+ int ioMode;
+ int ioSt;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQIODevice( const TQIODevice & );
+ TQIODevice &operator=( const TQIODevice & );
+#endif
+};
+
+#endif // USE_QT4
+
+#endif // TQIODEVICE_H
diff --git a/tqtinterface/qt4/src/tools/tqiodevice.h~ b/tqtinterface/qt4/src/tools/tqiodevice.h~
new file mode 100644
index 0000000..e34b65d
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqiodevice.h~
@@ -0,0 +1,310 @@
+/****************************************************************************
+**
+** Definition of TQIODevice class
+**
+** Created : 940913
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQIODEVICE_H
+#define TQIODEVICE_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqcstring.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qiodevice.h>
+#include <Qt/qfile.h>
+#include <iostream>
+
+#endif // USE_QT4
+
+#ifdef USE_QT4
+
+#define IO_Direct 0x0100 // direct access tqdevice
+#define IO_Sequential 0x0200 // sequential access tqdevice
+#define IO_Combined 0x0300 // combined direct/sequential
+#define IO_TypeMask 0x0f00
+
+// IO handling modes
+
+#define IO_Raw 0x0040 // raw access (not buffered)
+#define IO_Async 0x0080 // asynchronous mode
+
+// IO tqdevice open modes
+
+#define IO_ReadOnly (QIODevice::OpenModeFlag)0x0001 // readable tqdevice
+#define IO_WriteOnly (QIODevice::OpenModeFlag)0x0002 // writable tqdevice
+#define IO_ReadWrite (QIODevice::OpenModeFlag)0x0003 // read+write tqdevice
+#define IO_Append (QIODevice::OpenModeFlag)0x0004 // append
+#define IO_Truncate (QIODevice::OpenModeFlag)0x0008 // truncate tqdevice
+#define IO_Translate (QIODevice::OpenModeFlag)0x0010 // translate CR+LF
+#define IO_ModeMask (QIODevice::OpenModeFlag)0x00ff
+
+// IO tqdevice state
+
+#define IO_Open 0x1000 // tqdevice is open
+#define IO_StateMask 0xf000
+
+// IO tqdevice status
+
+#define IO_Ok 0
+#define IO_ReadError 1 // read error
+#define IO_WriteError 2 // write error
+#define IO_FatalError 3 // fatal unrecoverable error
+#define IO_ResourceError 4 // resource limitation
+#define IO_OpenError 5 // cannot open tqdevice
+#define IO_ConnectError 5 // cannot connect to tqdevice
+#define IO_AbortError 6 // abort error
+#define IO_TimeOutError 7 // time out
+#define IO_UnspecifiedError 8 // unspecified error
+
+class TQ_EXPORT TQIODevice : public QIODevice
+{
+public:
+#if defined(TQT_ABI_QT4)
+ typedef TQ_LLONG Offset;
+#else
+ typedef TQ_ULONG Offset;
+#endif
+
+ TQIODevice() : QIODevice() {}
+
+ inline int state() const { return isOpen() ? 0x1000 : 0; }
+ inline int mode() const { return (int) openMode(); }
+ inline int flags() const { return (int) openMode(); }
+ inline bool tqopen( int mode ) { return open((OpenModeFlag)mode); }
+
+ inline Offset at() const { return pos(); }
+ inline bool at(Offset offset) { return seek(offset); }
+ inline Offset tqat() const { return pos(); }
+ inline bool tqat(Offset offset) { return seek(offset); }
+
+// virtual inline qint64 readBlock(char *data, quint64 maxlen) { return read(data, maxlen); }
+// virtual inline qint64 writeBlock(const char *data, quint64 len) { return write(data, len); }
+// virtual inline qint64 writeBlock(const QByteArray &data) { return write(data); }
+ inline qint64 readBlock(char *data, quint64 maxlen) { return read(data, maxlen); }
+ inline qint64 writeBlock(const char *data, quint64 len) { return write(data, len); }
+ inline qint64 writeBlock(const QByteArray &data) { return write(data); }
+
+// virtual inline qint64 readData ( char * data, qint64 maxSize ) { return readBlock(data, maxSize); }
+// virtual inline qint64 writeData ( const char * data, qint64 maxSize ) { return writeBlock(data, maxSize); }
+
+ inline int getch() { char c; return getChar(&c) ? int(uchar(c)) : -1; }
+ inline int putch(int c) { return putChar(char(c)) ? int(uchar(c)) : -1; }
+ inline int ungetch(int c) { ungetChar(uchar(c)); return c; }
+ virtual void flush() = 0;
+
+ inline bool isDirectAccess() const { return !isSequential(); }
+ inline bool isSequentialAccess() const { return isSequential(); }
+ inline bool isCombinedAccess() const { return false; }
+ inline bool isBuffered() const { return true; }
+ inline bool isRaw() const { return false; }
+ inline bool isSynchronous() const { return true; }
+ inline bool isAsynchronous() const { return false; }
+ inline bool isTranslated() const { return (openMode() & Text) != 0; }
+ inline bool isInactive() const { return !isOpen(); }
+
+// inline bool open( int mode ) = 0;
+
+protected:
+ void setFlags( int f ) { setOpenMode((QIODevice::OpenModeFlag)f); }
+ void setType( int ) { printf("[WARNING] TQIODevice::setType() unimplemented\n\r"); }
+ void setMode( int f ) { setOpenMode((QIODevice::OpenModeFlag)f); }
+ void setState( int state ) {
+ switch (state) {
+ case (IO_Open):
+ QIODevice::open(openMode());
+ break;
+ }
+ }
+
+public:
+ typedef int Status;
+ Status status() const {
+#if !defined(QT_NO_QOBJECT)
+ const QFile *f = qobject_cast<const QFile *>(this);
+ if (f) return (int) f->error();
+#endif
+ return isOpen() ? 0 /* IO_Ok */ : 8 /* IO_UnspecifiedError */;
+ }
+ void resetStatus() {
+#if !defined(QT_NO_QOBJECT)
+ QFile *f = qobject_cast<QFile *>(this);
+ if (f) f->unsetError();
+#endif
+ }
+
+protected:
+ void setqStatus( int ) { std::cout << "[WARNING] TQIODevice::setqStatus() UNIMPLEMENTED\n\r"; }
+ void resetqStatus() { resetStatus(); }
+
+ friend class TQFile;
+ friend class TQIODeviceSource;
+ friend class TQImageIO;
+
+public:
+ // Interoperability
+ static TQIODevice& convertFromQIODevice( QIODevice& qiod );
+};
+
+// Interoperability
+inline static TQIODevice& convertFromQIODevice( QIODevice& qiod ) {
+ return (*static_cast<TQIODevice*>(&qiod));
+}
+
+#else // USE_QT4
+
+// IO tqdevice access types
+
+#define IO_Direct 0x0100 // direct access tqdevice
+#define IO_Sequential 0x0200 // sequential access tqdevice
+#define IO_Combined 0x0300 // combined direct/sequential
+#define IO_TypeMask 0x0f00
+
+// IO handling modes
+
+#define IO_Raw 0x0040 // raw access (not buffered)
+#define IO_Async 0x0080 // asynchronous mode
+
+// IO tqdevice open modes
+
+#define IO_ReadOnly 0x0001 // readable tqdevice
+#define IO_WriteOnly 0x0002 // writable tqdevice
+#define IO_ReadWrite 0x0003 // read+write tqdevice
+#define IO_Append 0x0004 // append
+#define IO_Truncate 0x0008 // truncate tqdevice
+#define IO_Translate 0x0010 // translate CR+LF
+#define IO_ModeMask 0x00ff
+
+// IO tqdevice state
+
+#define IO_Open 0x1000 // tqdevice is open
+#define IO_StateMask 0xf000
+
+// IO tqdevice status
+
+#define IO_Ok 0
+#define IO_ReadError 1 // read error
+#define IO_WriteError 2 // write error
+#define IO_FatalError 3 // fatal unrecoverable error
+#define IO_ResourceError 4 // resource limitation
+#define IO_OpenError 5 // cannot open tqdevice
+#define IO_ConnectError 5 // cannot connect to tqdevice
+#define IO_AbortError 6 // abort error
+#define IO_TimeOutError 7 // time out
+#define IO_UnspecifiedError 8 // unspecified error
+
+
+class TQ_EXPORT TQIODevice
+{
+public:
+#if defined(TQT_ABI_QT4)
+ typedef TQ_LLONG Offset;
+#else
+ typedef TQ_ULONG Offset;
+#endif
+
+ TQIODevice();
+ virtual ~TQIODevice();
+
+ int flags() const { return ioMode; }
+ int mode() const { return ioMode & IO_ModeMask; }
+ int state() const { return ioMode & IO_StateMask; }
+
+ bool isDirectAccess() const { return ((ioMode & IO_Direct) == IO_Direct); }
+ bool isSequentialAccess() const { return ((ioMode & IO_Sequential) == IO_Sequential); }
+ bool isCombinedAccess() const { return ((ioMode & IO_Combined) == IO_Combined); }
+ bool isBuffered() const { return ((ioMode & IO_Raw) != IO_Raw); }
+ bool isRaw() const { return ((ioMode & IO_Raw) == IO_Raw); }
+ bool isSynchronous() const { return ((ioMode & IO_Async) != IO_Async); }
+ bool isAsynchronous() const { return ((ioMode & IO_Async) == IO_Async); }
+ bool isTranslated() const { return ((ioMode & IO_Translate) == IO_Translate); }
+ bool isReadable() const { return ((ioMode & IO_ReadOnly) == IO_ReadOnly); }
+ bool isWritable() const { return ((ioMode & IO_WriteOnly) == IO_WriteOnly); }
+ bool isReadWrite() const { return ((ioMode & IO_ReadWrite) == IO_ReadWrite); }
+ bool isInactive() const { return state() == 0; }
+ bool isOpen() const { return state() == IO_Open; }
+
+ int status() const { return ioSt; }
+ void resetqStatus() { ioSt = IO_Ok; }
+
+ virtual bool open( int mode ) = 0;
+ virtual void close() = 0;
+ virtual void flush() = 0;
+
+ virtual Offset size() const = 0;
+ virtual Offset at() const;
+ virtual bool at( Offset );
+ virtual bool atEnd() const;
+ bool reset() { return at(0); }
+
+ virtual TQ_LONG readBlock( char *data, TQ_ULONG maxlen ) = 0;
+ virtual TQ_LONG writeBlock( const char *data, TQ_ULONG len ) = 0;
+ virtual TQ_LONG readLine( char *data, TQ_ULONG maxlen );
+ TQ_LONG writeBlock( const TQByteArray& data );
+ virtual TQByteArray readAll();
+
+ virtual int getch() = 0;
+ virtual int putch( int ) = 0;
+ virtual int ungetch( int ) = 0;
+
+protected:
+ void setFlags( int f ) { ioMode = f; }
+ void setType( int );
+ void setMode( int );
+ void setState( int );
+ void setqStatus( int );
+ Offset ioIndex;
+
+private:
+ int ioMode;
+ int ioSt;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQIODevice( const TQIODevice & );
+ TQIODevice &operator=( const TQIODevice & );
+#endif
+};
+
+#endif // USE_QT4
+
+#endif // TQIODEVICE_H
diff --git a/tqtinterface/qt4/src/tools/tqlibrary.cpp b/tqtinterface/qt4/src/tools/tqlibrary.cpp
new file mode 100644
index 0000000..140e017
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqlibrary.cpp
@@ -0,0 +1,442 @@
+/****************************************************************************
+**
+** Implementation of TQLibrary class
+**
+** Created : 000101
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+#include <private/tqlibrary_p.h>
+#include <tqstringlist.h>
+#include <tqfile.h>
+
+#ifndef TQT_NO_LIBRARY
+
+// uncomment this to get error messages
+//#define TQT_DEBUG_COMPONENT 1
+// uncomment this to get error and success messages
+//#define TQT_DEBUG_COMPONENT 2
+
+#ifndef TQT_DEBUG_COMPONENT
+# if defined(TQT_DEBUG)
+# define TQT_DEBUG_COMPONENT 1
+# endif
+#endif
+
+#if (defined(TQ_WS_WIN) && !defined(TQT_MAKEDLL)) \
+ || (defined(TQ_OS_FREEBSD) && defined(TQ_CC_INTEL)) \
+ || (defined(TQ_OS_IRIX) && defined(TQ_CC_GNU))
+#define TQT_NO_LIBRARY_UNLOAD
+#endif
+
+TQLibraryPrivate::TQLibraryPrivate( TQLibrary *lib )
+ : pHnd( 0 ), library( lib )
+{
+}
+
+
+/*!
+ \class TQLibrary tqlibrary.h
+ \reentrant
+ \brief The TQLibrary class provides a wrapper for handling shared libraries.
+
+ \mainclass
+ \ingroup plugins
+
+ An instance of a TQLibrary object can handle a single shared
+ library and provide access to the functionality in the library in
+ a platform independent way. If the library is a component server,
+ TQLibrary provides access to the exported component and can
+ directly query this component for interfaces.
+
+ TQLibrary ensures that the shared library is loaded and stays in
+ memory whilst it is in use. TQLibrary can also unload the library
+ on destruction and release unused resources.
+
+ A typical use of TQLibrary is to resolve an exported symbol in a
+ shared object, and to call the function that this symbol
+ represents. This is called "explicit linking" in contrast to
+ "implicit linking", which is done by the link step in the build
+ process when linking an executable against a library.
+
+ The following code snippet loads a library, resolves the symbol
+ "mysymbol", and calls the function if everything succeeded. If
+ something went wrong, e.g. the library file does not exist or the
+ symbol is not defined, the function pointer will be 0 and won't be
+ called. When the TQLibrary object is destroyed the library will be
+ unloaded, making all references to memory allocated in the library
+ invalid.
+
+ \code
+ typedef void (*MyPrototype)();
+ MyPrototype myFunction;
+
+ TQLibrary myLib( "mylib" );
+ myFunction = (MyPrototype) myLib.resolve( "mysymbol" );
+ if ( myFunction ) {
+ myFunction();
+ }
+ \endcode
+*/
+
+/*!
+ Creates a TQLibrary object for the shared library \a filename. The
+ library will be unloaded in the destructor.
+
+ Note that \a filename does not need to include the (platform specific)
+ file extension, so calling
+ \code
+ TQLibrary lib( "mylib" );
+ \endcode
+ is equivalent to calling
+ \code
+ TQLibrary lib( "mylib.dll" );
+ \endcode
+ on Windows, and
+ \code
+ TQLibrary lib( "libmylib.so" );
+ \endcode
+ on Unix. Specifying the extension is not recommended, since
+ doing so introduces a platform dependency.
+
+ If \a filename does not include a path, the library loader will
+ look for the file in the platform specific search paths.
+
+ \sa load() unload(), setAutoUnload()
+*/
+TQLibrary::TQLibrary( const TQString& filename )
+ : libfile( filename ), aunload( TRUE )
+{
+ libfile.tqreplace( '\\', '/' );
+ d = new TQLibraryPrivate( this );
+}
+
+/*!
+ Deletes the TQLibrary object.
+
+ The library will be unloaded if autoUnload() is TRUE (the
+ default), otherwise it stays in memory until the application
+ exits.
+
+ \sa unload(), setAutoUnload()
+*/
+TQLibrary::~TQLibrary()
+{
+ if ( autoUnload() )
+ unload();
+
+ delete d;
+}
+
+/*!
+ Returns the address of the exported symbol \a symb. The library is
+ loaded if necessary. The function returns 0 if the symbol could
+ not be resolved or the library could not be loaded.
+
+ \code
+ typedef int (*avgProc)( int, int );
+
+ avgProc avg = (avgProc) library->resolve( "avg" );
+ if ( avg )
+ return avg( 5, 8 );
+ else
+ return -1;
+ \endcode
+
+ The symbol must be exported as a C-function from the library. This
+ requires the \c {extern "C"} notation if the library is compiled
+ with a C++ compiler. On Windows you also have to explicitly export
+ the function from the DLL using the \c {__declspec(dllexport)}
+ compiler directive.
+
+ \code
+ extern "C" MY_EXPORT_MACRO int avg(int a, int b)
+ {
+ return (a + b) / 2;
+ }
+ \endcode
+
+ with \c MY_EXPORT defined as
+
+ \code
+ #ifdef TQ_WS_WIN
+ # define MY_EXPORT __declspec(dllexport)
+ #else
+ # define MY_EXPORT
+ #endif
+ \endcode
+
+ On Darwin and Mac OS X this function uses code from dlcompat, part of the
+ OpenDarwin project.
+
+ \legalese
+
+ Copyright (c) 2002 Jorge Acereda and Peter O'Gorman
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+void *TQLibrary::resolve( const char* symb )
+{
+ if ( !d->pHnd )
+ load();
+ if ( !d->pHnd )
+ return 0;
+
+ void *address = d->resolveSymbol( symb );
+
+ return address;
+}
+
+/*!
+ \overload
+
+ Loads the library \a filename and returns the address of the
+ exported symbol \a symb. Note that like the constructor, \a
+ filename does not need to include the (platform specific) file
+ extension. The library remains loaded until the process exits.
+
+ The function returns 0 if the symbol could not be resolved or the
+ library could not be loaded.
+
+ This function is useful only if you want to resolve a single
+ symbol, e.g. a function pointer from a specific library once:
+
+ \code
+ typedef void (*FunctionType)();
+ static FunctionType *ptrFunction = 0;
+ static bool triedResolve = FALSE;
+ if ( !ptrFunction && !triedResolve )
+ ptrFunction = TQLibrary::resolve( "mylib", "mysymb" );
+
+ if ( ptrFunction )
+ ptrFunction();
+ else
+ ...
+ \endcode
+
+ If you want to resolve multiple symbols, use a TQLibrary object and
+ call the non-static version of resolve().
+
+ \sa resolve()
+*/
+void *TQLibrary::resolve( const TQString &filename, const char *symb )
+{
+ TQLibrary lib( filename );
+ lib.setAutoUnload( FALSE );
+ return lib.resolve( symb );
+}
+
+/*!
+ Returns TRUE if the library is loaded; otherwise returns FALSE.
+
+ \sa unload()
+*/
+bool TQLibrary::isLoaded() const
+{
+ return d->pHnd != 0;
+}
+
+/*!
+ Loads the library. Since resolve() always calls this function
+ before resolving any symbols it is not necessary to call it
+ explicitly. In some situations you might want the library loaded
+ in advance, in which case you would use this function.
+
+ On Darwin and Mac OS X this function uses code from dlcompat, part of the
+ OpenDarwin project.
+
+ \legalese
+
+ Copyright (c) 2002 Jorge Acereda and Peter O'Gorman
+
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of this software and associated documentation files (the
+ "Software"), to deal in the Software without restriction, including
+ without limitation the rights to use, copy, modify, merge, publish,
+ distribute, sublicense, and/or sell copies of the Software, and to
+ permit persons to whom the Software is furnished to do so, subject to
+ the following conditions:
+
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+bool TQLibrary::load()
+{
+ if (libfile.isEmpty())
+ return FALSE;
+ return d->loadLibrary();
+}
+
+/*!
+ Unloads the library and returns TRUE if the library could be
+ unloaded; otherwise returns FALSE.
+
+ This function is called by the destructor if autoUnload() is
+ enabled.
+
+ \sa resolve()
+*/
+bool TQLibrary::unload()
+{
+ if ( !d->pHnd )
+ return TRUE;
+
+#if !defined(TQT_NO_LIBRARY_UNLOAD)
+ if ( !d->freeLibrary() ) {
+# if defined(TQT_DEBUG_COMPONENT)
+ qWarning( "%s could not be unloaded", (const char*) TQFile::encodeName(library()) );
+# endif
+ return FALSE;
+ }
+
+# if defined(TQT_DEBUG_COMPONENT) && TQT_DEBUG_COMPONENT == 2
+ qWarning( "%s has been unloaded", (const char*) TQFile::encodeName(library()) );
+# endif
+ d->pHnd = 0;
+#endif
+ return TRUE;
+}
+
+/*!
+ Returns TRUE if the library will be automatically unloaded when
+ this wrapper object is destructed; otherwise returns FALSE. The
+ default is TRUE.
+
+ \sa setAutoUnload()
+*/
+bool TQLibrary::autoUnload() const
+{
+ return (bool)aunload;
+}
+
+/*!
+ If \a enabled is TRUE (the default), the wrapper object is set to
+ automatically unload the library upon destruction. If \a enabled
+ is FALSE, the wrapper object is not unloaded unless you explicitly
+ call unload().
+
+ \sa autoUnload()
+*/
+void TQLibrary::setAutoUnload( bool enabled )
+{
+ aunload = enabled;
+}
+
+/*!
+ Returns the filename of the shared library this TQLibrary object
+ handles, including the platform specific file extension.
+
+ For example:
+ \code
+ TQLibrary lib( "mylib" );
+ TQString str = lib.library();
+ \endcode
+ will set \e str to "mylib.dll" on Windows, and "libmylib.so" on Linux.
+*/
+TQString TQLibrary::library() const
+{
+ if ( libfile.isEmpty() )
+ return libfile;
+
+ TQString filename = libfile;
+
+#if defined(TQ_WS_WIN)
+ if ( filename.tqfindRev( '.' ) <= filename.tqfindRev( '/' ) )
+ filename += ".dll";
+#else
+ TQStringList filters = "";
+#ifdef TQ_OS_MACX
+ filters << ".so";
+ filters << ".bundle";
+ filters << ".dylib"; //the last one is also the default one..
+#elif defined(TQ_OS_HPUX)
+ filters << ".sl";
+#else
+ filters << ".so";
+#endif
+ for(TQStringList::Iterator it = filters.begin(); TRUE; ) {
+ TQString filter = (*it);
+ ++it;
+
+ if(TQFile::exists(filename + filter)) {
+ filename += filter;
+ break;
+ } else if(!filter.isEmpty()) {
+ TQString tmpfilename = filename;
+ const int x = tmpfilename.tqfindRev( "/" );
+ if ( x != -1 ) {
+ TQString path = tmpfilename.left( x + 1 );
+ TQString file = tmpfilename.right( tmpfilename.length() - x - 1 );
+ tmpfilename = TQString( "%1lib%2" ).arg( path ).arg( file );
+ } else {
+ tmpfilename = TQString( "lib%1" ).arg( filename );
+ }
+ tmpfilename += filter;
+ if(TQFile::exists(tmpfilename) || it == filters.end()) {
+ filename = tmpfilename;
+ break;
+ }
+ }
+ }
+#endif
+ return filename;
+}
+#endif //TQT_NO_LIBRARY
diff --git a/tqtinterface/qt4/src/tools/tqlibrary.h b/tqtinterface/qt4/src/tools/tqlibrary.h
new file mode 100644
index 0000000..7d3f05a
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqlibrary.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Definition of TQLibrary class
+**
+** Created : 000101
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLIBRARY_H
+#define TQLIBRARY_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_LIBRARY
+
+class TQLibraryPrivate;
+
+class TQ_EXPORT TQLibrary
+{
+public:
+ TQLibrary( const TQString& filename );
+ virtual ~TQLibrary();
+
+ void *resolve( const char* );
+ static void *resolve( const TQString &filename, const char * );
+
+ bool load();
+ virtual bool unload();
+ bool isLoaded() const;
+
+ bool autoUnload() const;
+ void setAutoUnload( bool enable );
+
+ TQString library() const;
+
+private:
+ TQLibraryPrivate *d;
+
+ TQString libfile;
+ uint aunload : 1;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQLibrary( const TQLibrary & );
+ TQLibrary &operator=( const TQLibrary & );
+#endif
+};
+
+#define TQ_DEFINED_TQLIBRARY
+#include "tqwinexport.h"
+#endif //TQT_NO_LIBRARY
+#endif //TQLIBRARY_H
diff --git a/tqtinterface/qt4/src/tools/tqlibrary_p.h b/tqtinterface/qt4/src/tools/tqlibrary_p.h
new file mode 100644
index 0000000..dbd18a8
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqlibrary_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Definition of an internal TQLibrary class
+**
+** Created : 000101
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLIBRARY_P_H
+#define TQLIBRARY_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of the TQLibrary class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#include "tqlibrary.h"
+
+#ifndef TQT_NO_LIBRARY
+
+#ifndef TQT_H
+#include "tqwindowdefs.h"
+#endif // TQT_H
+
+class TQLibraryPrivate
+{
+public:
+ TQLibraryPrivate( TQLibrary *lib );
+
+#ifdef TQ_WS_WIN
+ HINSTANCE pHnd;
+#else
+ void *pHnd;
+#endif
+
+ bool loadLibrary();
+ bool freeLibrary();
+ void *resolveSymbol( const char * );
+
+private:
+ TQLibrary *library;
+};
+
+#endif // TQT_NO_LIBRARY
+#endif // TQLIBRARY_P_H
diff --git a/tqtinterface/qt4/src/tools/tqlibrary_unix.cpp b/tqtinterface/qt4/src/tools/tqlibrary_unix.cpp
new file mode 100644
index 0000000..62c909c
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqlibrary_unix.cpp
@@ -0,0 +1,169 @@
+/****************************************************************************
+**
+** Implementation of TQLibraryPrivate class
+**
+** Created : 000101
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+#include "private/tqlibrary_p.h"
+
+#ifndef TQT_NO_LIBRARY
+
+#if defined(TQT_AOUT_UNDERSCORE)
+#include <string.h>
+#endif
+
+/*
+ The platform dependent implementations of
+ - loadLibrary
+ - freeLibrary
+ - resolveSymbol
+
+ It's not too hard to guess what the functions do.
+*/
+
+#if defined(TQT_HPUX_LD) // for HP-UX < 11.x and 32 bit
+
+bool TQLibraryPrivate::loadLibrary()
+{
+ if ( pHnd )
+ return TRUE;
+
+ TQString filename = library->library();
+
+ pHnd = (void*)shl_load( filename.latin1(), BIND_DEFERRED | BIND_NONFATAL | DYNAMIC_PATH, 0 );
+#if defined(TQT_DEBUG) || defined(TQT_DEBUG_COMPONENT)
+ if ( !pHnd )
+ qWarning( "%s: failed to load library!", filename.latin1() );
+#endif
+ return pHnd != 0;
+}
+
+bool TQLibraryPrivate::freeLibrary()
+{
+ if ( !pHnd )
+ return TRUE;
+
+ if ( shl_unload( (shl_t)pHnd ) ) {
+#if defined(TQT_DEBUG) || defined(TQT_DEBUG_COMPONENT)
+ TQString filename = library->library();
+ qWarning( "%s: Failed to unload library!", filename.latin1() );
+#endif
+ return FALSE;
+ }
+ pHnd = 0;
+ return TRUE;
+}
+
+void* TQLibraryPrivate::resolveSymbol( const char* symbol )
+{
+ if ( !pHnd )
+ return 0;
+
+ void* address = 0;
+ if ( shl_tqfindsym( (shl_t*)&pHnd, symbol, TYPE_UNDEFINED, &address ) < 0 ) {
+#if defined(TQT_DEBUG_COMPONENT)
+ TQString filename = library->library();
+ qWarning( "%s: couldn't resolve symbol \"%s\"", filename.latin1(), symbol );
+#endif
+ }
+ return address;
+}
+
+#else // POSIX
+#include <dlfcn.h>
+#ifndef DL_PREFIX //for mac dlcompat
+# define DL_PREFIX(x) x
+#endif
+
+bool TQLibraryPrivate::loadLibrary()
+{
+ if ( pHnd )
+ return TRUE;
+
+ TQString filename = library->library();
+
+ pHnd = DL_PREFIX(dlopen)( filename.latin1(), RTLD_LAZY );
+#if defined(TQT_DEBUG) || defined(TQT_DEBUG_COMPONENT)
+ if ( !pHnd )
+ qWarning( "%s", DL_PREFIX(dlerror)() );
+#endif
+ return pHnd != 0;
+}
+
+bool TQLibraryPrivate::freeLibrary()
+{
+ if ( !pHnd )
+ return TRUE;
+
+ if ( DL_PREFIX(dlclose)( pHnd ) ) {
+#if defined(TQT_DEBUG) || defined(TQT_DEBUG_COMPONENT)
+ qWarning( "%s", DL_PREFIX(dlerror)() );
+#endif
+ return FALSE;
+ }
+
+ pHnd = 0;
+ return TRUE;
+}
+
+void* TQLibraryPrivate::resolveSymbol( const char* symbol )
+{
+ if ( !pHnd )
+ return 0;
+
+#if defined(TQT_AOUT_UNDERSCORE)
+ // older a.out systems add an underscore in front of symbols
+ char* undrscr_symbol = new char[strlen(symbol)+2];
+ undrscr_symbol[0] = '_';
+ strcpy(undrscr_symbol+1, symbol);
+ void* address = DL_PREFIX(dlsym)( pHnd, undrscr_symbol );
+ delete [] undrscr_symbol;
+#else
+ void* address = DL_PREFIX(dlsym)( pHnd, symbol );
+#endif
+#if defined(TQT_DEBUG_COMPONENT)
+ const char* error = DL_PREFIX(dlerror)();
+ if ( error )
+ qWarning( "%s", error );
+#endif
+ return address;
+}
+
+#endif // POSIX
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqlocale.cpp b/tqtinterface/qt4/src/tools/tqlocale.cpp
new file mode 100644
index 0000000..26a3230
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqlocale.cpp
@@ -0,0 +1,6311 @@
+/****************************************************************************
+**
+** Implementation of the TQLocale class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <float.h>
+#include <limits.h>
+#include <math.h>
+#include <stdlib.h>
+
+#include "tqlocale.h"
+#include "tqlocale_p.h"
+#include "tqnamespace.h"
+
+#ifdef TQT_TQLOCALE_USES_FCVT
+# include <tqmutex.h>
+# include <private/tqmutexpool_p.h>
+#endif
+
+#if defined (TQ_OS_WIN)
+# include <windows.h>
+# undef NAN // we want to use our fallback on Windows
+# undef INFINITY
+#endif
+
+#ifdef TQ_OS_LINUX
+# include <fenv.h>
+#endif
+
+#if !defined( TQWS ) && defined( TQ_OS_MAC )
+# include <Carbon/Carbon.h>
+#endif
+
+#if defined (TQ_OS_SOLARIS)
+# include <ieeefp.h>
+#endif
+
+#if defined (TQ_OS_OSF) && (defined(__DECC) || defined(__DECCXX))
+# define INFINITY DBL_INFINITY
+# define NAN DBL_TQNAN
+#endif
+
+#if (defined(TQ_CC_GNU) && defined(TQ_OS_WIN)) || __GNUC__ == 4 || defined(TQT_TQLOCALE_NEEDS_VOLATILE)
+# define NEEDS_VOLATILE volatile
+#else
+# define NEEDS_VOLATILE
+#endif
+
+enum {
+ LittleEndian,
+ BigEndian
+
+#ifdef TQ_BYTE_ORDER
+# if TQ_BYTE_ORDER == TQ_BIG_ENDIAN
+ , ByteOrder = BigEndian
+# elif TQ_BYTE_ORDER == TQ_LITTLE_ENDIAN
+ , ByteOrder = LittleEndian
+# else
+# error "undefined byte order"
+# endif
+};
+#else
+};
+static const unsigned int one = 1;
+static const bool ByteOrder = ((*((unsigned char *) &one) == 0) ? BigEndian : LittleEndian);
+#endif
+
+#if !defined(INFINITY)
+static const unsigned char be_inf_bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 };
+static const unsigned char le_inf_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f };
+static inline double inf()
+{
+ return (ByteOrder == BigEndian ?
+ *((const double *) be_inf_bytes) :
+ *((const double *) le_inf_bytes));
+}
+# define INFINITY (::inf())
+#endif
+
+#if !defined(NAN)
+static const unsigned char be_nan_bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 };
+static const unsigned char le_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f };
+static inline double nan()
+{
+ return (ByteOrder == BigEndian ?
+ *((const double *) be_nan_bytes) :
+ *((const double *) le_nan_bytes));
+}
+# define NAN (::nan())
+#endif
+
+// We can't rely on -NAN, since all operations on a NAN should return a NAN.
+static const unsigned char be_neg_nan_bytes[] = { 0xff, 0xf8, 0, 0, 0, 0, 0, 0 };
+static const unsigned char le_neg_nan_bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0xff };
+static inline double negNan()
+{
+ return (ByteOrder == BigEndian ?
+ *((const double *) be_neg_nan_bytes) :
+ *((const double *) le_neg_nan_bytes));
+}
+
+// Sizes as defined by the ISO C99 standard - fallback
+#ifndef LLONG_MAX
+# define LLONG_MAX TQ_INT64_C(9223372036854775807)
+#endif
+#ifndef LLONG_MIN
+# define LLONG_MIN (-LLONG_MAX - TQ_INT64_C(1))
+#endif
+#ifndef ULLONG_MAX
+# define ULLONG_MAX TQ_UINT64_C(0xffffffffffffffff)
+#endif
+
+#ifndef TQT_TQLOCALE_USES_FCVT
+static char *qdtoa(double d, int mode, int ndigits, int *decpt,
+ int *sign, char **rve, char **digits_str);
+static char *_qdtoa(double d, int mode, int ndigits, int *decpt,
+ int *sign, char **rve, char **digits_str);
+static double qstrtod(const char *s00, char const **se, bool *ok);
+#endif
+static TQ_LLONG qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok);
+static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok);
+
+static inline bool compareBits(double d1, double d2)
+{
+ return memcmp((const char*)&d1, (const char*)&d2, sizeof(double)) == 0;
+}
+
+static inline bool qIsInf(double d)
+{
+ return compareBits(d, INFINITY) || compareBits(d, -INFINITY);
+}
+
+static inline bool qIsNan(double d)
+{
+ return compareBits(d, NAN) || compareBits(d, negNan());
+}
+
+static const uint locale_index[] = {
+ 0, // unused
+ 0, // C
+ 0, // Abkhazian
+ 0, // Afan
+ 0, // Afar
+ 1, // Afrikaans
+ 2, // Albanian
+ 0, // Amharic
+ 3, // Arabic
+ 19, // Armenian
+ 0, // Assamese
+ 0, // Aymara
+ 20, // Azerbaijani
+ 0, // Bashkir
+ 21, // Basque
+ 22, // Bengali
+ 0, // Bhutani
+ 0, // Bihari
+ 0, // Bislama
+ 0, // Breton
+ 23, // Bulgarian
+ 0, // Burmese
+ 24, // Byelorussian
+ 0, // Cambodian
+ 25, // Catalan
+ 26, // Chinese
+ 0, // Corsican
+ 31, // Croatian
+ 32, // Czech
+ 33, // Danish
+ 34, // Dutch
+ 36, // English
+ 0, // Esperanto
+ 48, // Estonian
+ 49, // Faroese
+ 0, // Fiji
+ 50, // Finnish
+ 51, // French
+ 0, // Frisian
+ 0, // Gaelic
+ 57, // Galician
+ 58, // Georgian
+ 59, // German
+ 64, // Greek
+ 0, // Greenlandic
+ 0, // Guarani
+ 65, // Gujarati
+ 0, // Hausa
+ 66, // Hebrew
+ 67, // Hindi
+ 68, // Hungarian
+ 69, // Icelandic
+ 70, // Indonesian
+ 0, // Interlingua
+ 0, // Interlingue
+ 0, // Inuktitut
+ 0, // Inupiak
+ 0, // Irish
+ 71, // Italian
+ 73, // Japanese
+ 0, // Javanese
+ 74, // Kannada
+ 0, // Kashmiri
+ 75, // Kazakh
+ 0, // Kinyarwanda
+ 76, // Kirghiz
+ 77, // Korean
+ 0, // Kurdish
+ 0, // Kurundi
+ 0, // Laothian
+ 0, // Latin
+ 78, // Latvian
+ 0, // Lingala
+ 79, // Lithuanian
+ 80, // Macedonian
+ 0, // Malagasy
+ 81, // Malay
+ 0, // Malayalam
+ 0, // Maltese
+ 0, // Maori
+ 83, // Marathi
+ 0, // Moldavian
+ 84, // Mongolian
+ 0, // Nauru
+ 0, // Nepali
+ 85, // Norwegian
+ 0, // Occitan
+ 0, // Oriya
+ 0, // Pashto
+ 86, // Persian
+ 87, // Polish
+ 88, // Portuguese
+ 90, // Punjabi
+ 0, // Quechua
+ 0, // RhaetoRomance
+ 91, // Romanian
+ 92, // Russian
+ 0, // Samoan
+ 0, // Sangho
+ 93, // Sanskrit
+ 0, // Serbian
+ 0, // SerboCroatian
+ 0, // Sesotho
+ 0, // Setswana
+ 0, // Shona
+ 0, // Sindhi
+ 0, // Singhalese
+ 0, // Siswati
+ 94, // Slovak
+ 95, // Slovenian
+ 0, // Somali
+ 96, // Spanish
+ 0, // Sundanese
+ 115, // Swahili
+ 116, // Swedish
+ 0, // Tagalog
+ 0, // Tajik
+ 118, // Tamil
+ 0, // Tatar
+ 119, // Telugu
+ 120, // Thai
+ 0, // Tibetan
+ 0, // Tigrinya
+ 0, // Tonga
+ 0, // Tsonga
+ 121, // Turkish
+ 0, // Turkmen
+ 0, // Twi
+ 0, // Uigur
+ 122, // Ukrainian
+ 123, // Urdu
+ 124, // Uzbek
+ 125, // Vietnamese
+ 0, // Volapuk
+ 0, // Welsh
+ 0, // Wolof
+ 0, // Xhosa
+ 0, // Yiddish
+ 0, // Yoruba
+ 0, // Zhuang
+ 0, // Zulu
+ 0 // trailing 0
+};
+
+static const TQLocalePrivate locale_data[] = {
+// lang terr dec group list prcnt zero minus exp
+ { 1, 0, 46, 44, 59, 37, 48, 45, 101 }, // C/AnyCountry
+ { 5, 195, 46, 44, 44, 37, 48, 45, 101 }, // Afrikaans/SouthAfrica
+ { 6, 2, 44, 46, 59, 37, 48, 45, 101 }, // Albanian/Albania
+ { 8, 186, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SaudiArabia
+ { 8, 3, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Algeria
+ { 8, 17, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Bahrain
+ { 8, 64, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Egypt
+ { 8, 103, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Iraq
+ { 8, 109, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Jordan
+ { 8, 115, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Kuwait
+ { 8, 119, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Lebanon
+ { 8, 122, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/LibyanArabJamahiriya
+ { 8, 145, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Morocco
+ { 8, 162, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Oman
+ { 8, 175, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Qatar
+ { 8, 207, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/SyrianArabRepublic
+ { 8, 216, 46, 44, 59, 37, 48, 45, 101 }, // Arabic/Tunisia
+ { 8, 223, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/UnitedArabEmirates
+ { 8, 237, 46, 44, 59, 37, 1632, 45, 101 }, // Arabic/Yemen
+ { 9, 11, 46, 44, 44, 37, 48, 45, 101 }, // Armenian/Armenia
+ { 12, 15, 44, 160, 59, 37, 48, 45, 101 }, // Azerbaijani/Azerbaijan
+ { 14, 197, 44, 46, 59, 37, 48, 45, 101 }, // Basque/Spain
+ { 15, 100, 46, 44, 59, 37, 48, 45, 101 }, // Bengali/India
+ { 20, 33, 44, 160, 59, 37, 48, 45, 101 }, // Bulgarian/Bulgaria
+ { 22, 20, 44, 160, 59, 37, 48, 45, 101 }, // Byelorussian/Belarus
+ { 24, 197, 44, 46, 59, 37, 48, 45, 101 }, // Catalan/Spain
+ { 25, 44, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/China
+ { 25, 97, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/HongKong
+ { 25, 126, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Macau
+ { 25, 190, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Singapore
+ { 25, 208, 46, 44, 44, 37, 48, 45, 101 }, // Chinese/Taiwan
+ { 27, 54, 44, 46, 59, 37, 48, 45, 101 }, // Croatian/Croatia
+ { 28, 57, 44, 160, 59, 37, 48, 45, 101 }, // Czech/CzechRepublic
+ { 29, 58, 44, 46, 59, 37, 48, 45, 101 }, // Danish/Denmark
+ { 30, 151, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Netherlands
+ { 30, 21, 44, 46, 59, 37, 48, 45, 101 }, // Dutch/Belgium
+ { 31, 225, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedStates
+ { 31, 13, 46, 44, 44, 37, 48, 45, 101 }, // English/Australia
+ { 31, 22, 46, 44, 59, 37, 48, 45, 101 }, // English/Belize
+ { 31, 38, 46, 44, 44, 37, 48, 45, 101 }, // English/Canada
+ { 31, 104, 46, 44, 44, 37, 48, 45, 101 }, // English/Ireland
+ { 31, 107, 46, 44, 44, 37, 48, 45, 101 }, // English/Jamaica
+ { 31, 154, 46, 44, 44, 37, 48, 45, 101 }, // English/NewZealand
+ { 31, 170, 46, 44, 44, 37, 48, 45, 101 }, // English/Philippines
+ { 31, 195, 46, 44, 44, 37, 48, 45, 101 }, // English/SouthAfrica
+ { 31, 215, 46, 44, 59, 37, 48, 45, 101 }, // English/TrinidadAndTobago
+ { 31, 224, 46, 44, 44, 37, 48, 45, 101 }, // English/UnitedKingdom
+ { 31, 240, 46, 44, 44, 37, 48, 45, 101 }, // English/Zimbabwe
+ { 33, 68, 44, 160, 59, 37, 48, 45, 101 }, // Estonian/Estonia
+ { 34, 71, 44, 46, 59, 37, 48, 45, 101 }, // Faroese/FaroeIslands
+ { 36, 73, 44, 160, 59, 37, 48, 45, 101 }, // Finnish/Finland
+ { 37, 74, 44, 160, 59, 37, 48, 45, 101 }, // French/France
+ { 37, 21, 44, 46, 59, 37, 48, 45, 101 }, // French/Belgium
+ { 37, 38, 44, 160, 59, 37, 48, 45, 101 }, // French/Canada
+ { 37, 125, 44, 160, 59, 37, 48, 45, 101 }, // French/Luxembourg
+ { 37, 142, 44, 160, 59, 37, 48, 45, 101 }, // French/Monaco
+ { 37, 206, 46, 39, 59, 37, 48, 45, 101 }, // French/Switzerland
+ { 40, 197, 44, 46, 44, 37, 48, 45, 101 }, // Galician/Spain
+ { 41, 81, 44, 160, 59, 37, 48, 45, 101 }, // Georgian/Georgia
+ { 42, 82, 44, 46, 59, 37, 48, 45, 101 }, // German/Germany
+ { 42, 14, 44, 46, 59, 37, 48, 45, 101 }, // German/Austria
+ { 42, 123, 46, 39, 59, 37, 48, 45, 101 }, // German/Liechtenstein
+ { 42, 125, 44, 46, 59, 37, 48, 45, 101 }, // German/Luxembourg
+ { 42, 206, 46, 39, 59, 37, 48, 45, 101 }, // German/Switzerland
+ { 43, 85, 44, 46, 59, 37, 48, 45, 101 }, // Greek/Greece
+ { 46, 100, 46, 44, 44, 37, 2790, 45, 101 }, // Gujarati/India
+ { 48, 105, 46, 44, 44, 37, 48, 45, 101 }, // Hebrew/Israel
+ { 49, 100, 46, 44, 44, 37, 48, 45, 101 }, // Hindi/India
+ { 50, 98, 44, 160, 59, 37, 48, 45, 101 }, // Hungarian/Hungary
+ { 51, 99, 44, 46, 59, 37, 48, 45, 101 }, // Icelandic/Iceland
+ { 52, 101, 44, 46, 59, 37, 48, 45, 101 }, // Indonesian/Indonesia
+ { 58, 106, 44, 46, 59, 37, 48, 45, 101 }, // Italian/Italy
+ { 58, 206, 46, 39, 59, 37, 48, 45, 101 }, // Italian/Switzerland
+ { 59, 108, 46, 44, 44, 37, 48, 45, 101 }, // Japanese/Japan
+ { 61, 100, 46, 44, 44, 37, 3302, 45, 101 }, // Kannada/India
+ { 63, 110, 44, 160, 59, 37, 48, 45, 101 }, // Kazakh/Kazakhstan
+ { 65, 116, 44, 160, 59, 37, 48, 45, 101 }, // Kirghiz/Kyrgyzstan
+ { 66, 114, 46, 44, 44, 37, 48, 45, 101 }, // Korean/RepublicOfKorea
+ { 71, 118, 44, 160, 59, 37, 48, 45, 101 }, // Latvian/Latvia
+ { 73, 124, 44, 46, 59, 37, 48, 45, 101 }, // Lithuanian/Lithuania
+ { 74, 127, 44, 46, 59, 37, 48, 45, 101 }, // Macedonian/Macedonia
+ { 76, 130, 44, 46, 59, 37, 48, 45, 101 }, // Malay/Malaysia
+ { 76, 32, 44, 46, 59, 37, 48, 45, 101 }, // Malay/BruneiDarussalam
+ { 80, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Marathi/India
+ { 82, 143, 44, 160, 59, 37, 48, 45, 101 }, // Mongolian/Mongolia
+ { 85, 161, 44, 160, 59, 37, 48, 45, 101 }, // Norwegian/Norway
+ { 89, 102, 46, 44, 59, 37, 1776, 45, 101 }, // Persian/Iran
+ { 90, 172, 44, 160, 59, 37, 48, 45, 101 }, // Polish/Poland
+ { 91, 173, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Portugal
+ { 91, 30, 44, 46, 59, 37, 48, 45, 101 }, // Portuguese/Brazil
+ { 92, 100, 46, 44, 44, 37, 2662, 45, 101 }, // Punjabi/India
+ { 95, 177, 44, 46, 59, 37, 48, 45, 101 }, // Romanian/Romania
+ { 96, 178, 44, 160, 59, 37, 48, 45, 101 }, // Russian/RussianFederation
+ { 99, 100, 46, 44, 44, 37, 2406, 45, 101 }, // Sanskrit/India
+ { 108, 191, 44, 160, 59, 37, 48, 45, 101 }, // Slovak/Slovakia
+ { 109, 192, 44, 46, 59, 37, 48, 45, 101 }, // Slovenian/Slovenia
+ { 111, 197, 44, 46, 59, 37, 48, 45, 101 }, // Spanish/Spain
+ { 111, 10, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Argentina
+ { 111, 26, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Bolivia
+ { 111, 43, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Chile
+ { 111, 47, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Colombia
+ { 111, 52, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/CostaRica
+ { 111, 61, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/DominicanRepublic
+ { 111, 63, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Ecuador
+ { 111, 65, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/ElSalvador
+ { 111, 90, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Guatemala
+ { 111, 96, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Honduras
+ { 111, 139, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Mexico
+ { 111, 155, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Nicaragua
+ { 111, 166, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Panama
+ { 111, 168, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Paraguay
+ { 111, 169, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/Peru
+ { 111, 174, 46, 44, 44, 37, 48, 45, 101 }, // Spanish/PuertoRico
+ { 111, 227, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Uruguay
+ { 111, 231, 44, 46, 44, 37, 48, 45, 101 }, // Spanish/Venezuela
+ { 113, 111, 46, 44, 44, 37, 48, 45, 101 }, // Swahili/Kenya
+ { 114, 205, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Sweden
+ { 114, 73, 44, 160, 59, 37, 48, 45, 101 }, // Swedish/Finland
+ { 117, 100, 46, 44, 44, 37, 48, 45, 101 }, // Tamil/India
+ { 119, 100, 46, 44, 44, 37, 3174, 45, 101 }, // Telugu/India
+ { 120, 211, 46, 44, 44, 37, 3664, 45, 101 }, // Thai/Thailand
+ { 125, 217, 44, 46, 59, 37, 48, 45, 101 }, // Turkish/Turkey
+ { 129, 222, 44, 160, 59, 37, 48, 45, 101 }, // Ukrainian/Ukraine
+ { 130, 163, 46, 44, 59, 37, 1776, 45, 101 }, // Urdu/Pakistan
+ { 131, 228, 44, 160, 59, 37, 48, 45, 101 }, // Uzbek/Uzbekistan
+ { 132, 232, 44, 46, 44, 37, 48, 45, 101 }, // Vietnamese/VietNam
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0 } // trailing 0s
+};
+
+static const char language_name_list[] =
+"Default\0"
+"C\0"
+"Abkhazian\0"
+"Afan\0"
+"Afar\0"
+"Afrikaans\0"
+"Albanian\0"
+"Amharic\0"
+"Arabic\0"
+"Armenian\0"
+"Assamese\0"
+"Aymara\0"
+"Azerbaijani\0"
+"Bashkir\0"
+"Basque\0"
+"Bengali\0"
+"Bhutani\0"
+"Bihari\0"
+"Bislama\0"
+"Breton\0"
+"Bulgarian\0"
+"Burmese\0"
+"Byelorussian\0"
+"Cambodian\0"
+"Catalan\0"
+"Chinese\0"
+"Corsican\0"
+"Croatian\0"
+"Czech\0"
+"Danish\0"
+"Dutch\0"
+"English\0"
+"Esperanto\0"
+"Estonian\0"
+"Faroese\0"
+"Fiji\0"
+"Finnish\0"
+"French\0"
+"Frisian\0"
+"Gaelic\0"
+"Galician\0"
+"Georgian\0"
+"German\0"
+"Greek\0"
+"Greenlandic\0"
+"Guarani\0"
+"Gujarati\0"
+"Hausa\0"
+"Hebrew\0"
+"Hindi\0"
+"Hungarian\0"
+"Icelandic\0"
+"Indonesian\0"
+"Interlingua\0"
+"Interlingue\0"
+"Inuktitut\0"
+"Inupiak\0"
+"Irish\0"
+"Italian\0"
+"Japanese\0"
+"Javanese\0"
+"Kannada\0"
+"Kashmiri\0"
+"Kazakh\0"
+"Kinyarwanda\0"
+"Kirghiz\0"
+"Korean\0"
+"Kurdish\0"
+"Kurundi\0"
+"Laothian\0"
+"Latin\0"
+"Latvian\0"
+"Lingala\0"
+"Lithuanian\0"
+"Macedonian\0"
+"Malagasy\0"
+"Malay\0"
+"Malayalam\0"
+"Maltese\0"
+"Maori\0"
+"Marathi\0"
+"Moldavian\0"
+"Mongolian\0"
+"Nauru\0"
+"Nepali\0"
+"Norwegian\0"
+"Occitan\0"
+"Oriya\0"
+"Pashto\0"
+"Persian\0"
+"Polish\0"
+"Portuguese\0"
+"Punjabi\0"
+"Quechua\0"
+"RhaetoRomance\0"
+"Romanian\0"
+"Russian\0"
+"Samoan\0"
+"Sangho\0"
+"Sanskrit\0"
+"Serbian\0"
+"SerboCroatian\0"
+"Sesotho\0"
+"Setswana\0"
+"Shona\0"
+"Sindhi\0"
+"Singhalese\0"
+"Siswati\0"
+"Slovak\0"
+"Slovenian\0"
+"Somali\0"
+"Spanish\0"
+"Sundanese\0"
+"Swahili\0"
+"Swedish\0"
+"Tagalog\0"
+"Tajik\0"
+"Tamil\0"
+"Tatar\0"
+"Telugu\0"
+"Thai\0"
+"Tibetan\0"
+"Tigrinya\0"
+"Tonga\0"
+"Tsonga\0"
+"Turkish\0"
+"Turkmen\0"
+"Twi\0"
+"Uigur\0"
+"Ukrainian\0"
+"Urdu\0"
+"Uzbek\0"
+"Vietnamese\0"
+"Volapuk\0"
+"Welsh\0"
+"Wolof\0"
+"Xhosa\0"
+"Yiddish\0"
+"Yoruba\0"
+"Zhuang\0"
+"Zulu\0";
+
+static const uint language_name_index[] = {
+ 0,// Unused
+ 8,// C
+ 10,// Abkhazian
+ 20,// Afan
+ 25,// Afar
+ 30,// Afrikaans
+ 40,// Albanian
+ 49,// Amharic
+ 57,// Arabic
+ 64,// Armenian
+ 73,// Assamese
+ 82,// Aymara
+ 89,// Azerbaijani
+ 101,// Bashkir
+ 109,// Basque
+ 116,// Bengali
+ 124,// Bhutani
+ 132,// Bihari
+ 139,// Bislama
+ 147,// Breton
+ 154,// Bulgarian
+ 164,// Burmese
+ 172,// Byelorussian
+ 185,// Cambodian
+ 195,// Catalan
+ 203,// Chinese
+ 211,// Corsican
+ 220,// Croatian
+ 229,// Czech
+ 235,// Danish
+ 242,// Dutch
+ 248,// English
+ 256,// Esperanto
+ 266,// Estonian
+ 275,// Faroese
+ 283,// Fiji
+ 288,// Finnish
+ 296,// French
+ 303,// Frisian
+ 311,// Gaelic
+ 318,// Galician
+ 327,// Georgian
+ 336,// German
+ 343,// Greek
+ 349,// Greenlandic
+ 361,// Guarani
+ 369,// Gujarati
+ 378,// Hausa
+ 384,// Hebrew
+ 391,// Hindi
+ 397,// Hungarian
+ 407,// Icelandic
+ 417,// Indonesian
+ 428,// Interlingua
+ 440,// Interlingue
+ 452,// Inuktitut
+ 462,// Inupiak
+ 470,// Irish
+ 476,// Italian
+ 484,// Japanese
+ 493,// Javanese
+ 502,// Kannada
+ 510,// Kashmiri
+ 519,// Kazakh
+ 526,// Kinyarwanda
+ 538,// Kirghiz
+ 546,// Korean
+ 553,// Kurdish
+ 561,// Kurundi
+ 569,// Laothian
+ 578,// Latin
+ 584,// Latvian
+ 592,// Lingala
+ 600,// Lithuanian
+ 611,// Macedonian
+ 622,// Malagasy
+ 631,// Malay
+ 637,// Malayalam
+ 647,// Maltese
+ 655,// Maori
+ 661,// Marathi
+ 669,// Moldavian
+ 679,// Mongolian
+ 689,// Nauru
+ 695,// Nepali
+ 702,// Norwegian
+ 712,// Occitan
+ 720,// Oriya
+ 726,// Pashto
+ 733,// Persian
+ 741,// Polish
+ 748,// Portuguese
+ 759,// Punjabi
+ 767,// Quechua
+ 775,// RhaetoRomance
+ 789,// Romanian
+ 798,// Russian
+ 806,// Samoan
+ 813,// Sangho
+ 820,// Sanskrit
+ 829,// Serbian
+ 837,// SerboCroatian
+ 851,// Sesotho
+ 859,// Setswana
+ 868,// Shona
+ 874,// Sindhi
+ 881,// Singhalese
+ 892,// Siswati
+ 900,// Slovak
+ 907,// Slovenian
+ 917,// Somali
+ 924,// Spanish
+ 932,// Sundanese
+ 942,// Swahili
+ 950,// Swedish
+ 958,// Tagalog
+ 966,// Tajik
+ 972,// Tamil
+ 978,// Tatar
+ 984,// Telugu
+ 991,// Thai
+ 996,// Tibetan
+ 1004,// Tigrinya
+ 1013,// Tonga
+ 1019,// Tsonga
+ 1026,// Turkish
+ 1034,// Turkmen
+ 1042,// Twi
+ 1046,// Uigur
+ 1052,// Ukrainian
+ 1062,// Urdu
+ 1067,// Uzbek
+ 1073,// Vietnamese
+ 1084,// Volapuk
+ 1092,// Welsh
+ 1098,// Wolof
+ 1104,// Xhosa
+ 1110,// Yiddish
+ 1118,// Yoruba
+ 1125,// Zhuang
+ 1132// Zulu
+};
+
+static const char country_name_list[] =
+"Default\0"
+"Afghanistan\0"
+"Albania\0"
+"Algeria\0"
+"AmericanSamoa\0"
+"Andorra\0"
+"Angola\0"
+"Anguilla\0"
+"Antarctica\0"
+"AntiguaAndBarbuda\0"
+"Argentina\0"
+"Armenia\0"
+"Aruba\0"
+"Australia\0"
+"Austria\0"
+"Azerbaijan\0"
+"Bahamas\0"
+"Bahrain\0"
+"Bangladesh\0"
+"Barbados\0"
+"Belarus\0"
+"Belgium\0"
+"Belize\0"
+"Benin\0"
+"Bermuda\0"
+"Bhutan\0"
+"Bolivia\0"
+"BosniaAndHerzegowina\0"
+"Botswana\0"
+"BouvetIsland\0"
+"Brazil\0"
+"BritishIndianOceanTerritory\0"
+"BruneiDarussalam\0"
+"Bulgaria\0"
+"BurkinaFaso\0"
+"Burundi\0"
+"Cambodia\0"
+"Cameroon\0"
+"Canada\0"
+"CapeVerde\0"
+"CaymanIslands\0"
+"CentralAfricanRepublic\0"
+"Chad\0"
+"Chile\0"
+"China\0"
+"ChristmasIsland\0"
+"CocosIslands\0"
+"Colombia\0"
+"Comoros\0"
+"DetqmocraticRepublicOfCongo\0"
+"PeoplesRepublicOfCongo\0"
+"CookIslands\0"
+"CostaRica\0"
+"IvoryCoast\0"
+"Croatia\0"
+"Cuba\0"
+"Cyprus\0"
+"CzechRepublic\0"
+"Denmark\0"
+"Djibouti\0"
+"Dominica\0"
+"DominicanRepublic\0"
+"EastTimor\0"
+"Ecuador\0"
+"Egypt\0"
+"ElSalvador\0"
+"EquatorialGuinea\0"
+"Eritrea\0"
+"Estonia\0"
+"Ethiopia\0"
+"FalklandIslands\0"
+"FaroeIslands\0"
+"Fiji\0"
+"Finland\0"
+"France\0"
+"MetropolitanFrance\0"
+"FrenchGuiana\0"
+"FrenchPolynesia\0"
+"FrenchSouthernTerritories\0"
+"Gabon\0"
+"Gambia\0"
+"Georgia\0"
+"Germany\0"
+"Ghana\0"
+"Gibraltar\0"
+"Greece\0"
+"Greenland\0"
+"Grenada\0"
+"Guadeloupe\0"
+"Guam\0"
+"Guatemala\0"
+"Guinea\0"
+"GuineaBissau\0"
+"Guyana\0"
+"Haiti\0"
+"HeardAndMcDonaldIslands\0"
+"Honduras\0"
+"HongKong\0"
+"Hungary\0"
+"Iceland\0"
+"India\0"
+"Indonesia\0"
+"Iran\0"
+"Iraq\0"
+"Ireland\0"
+"Israel\0"
+"Italy\0"
+"Jamaica\0"
+"Japan\0"
+"Jordan\0"
+"Kazakhstan\0"
+"Kenya\0"
+"Kiribati\0"
+"DetqmocraticRepublicOfKorea\0"
+"RepublicOfKorea\0"
+"Kuwait\0"
+"Kyrgyzstan\0"
+"Lao\0"
+"Latvia\0"
+"Lebanon\0"
+"Lesotho\0"
+"Liberia\0"
+"LibyanArabJamahiriya\0"
+"Liechtenstein\0"
+"Lithuania\0"
+"Luxembourg\0"
+"Macau\0"
+"Macedonia\0"
+"Madagascar\0"
+"Malawi\0"
+"Malaysia\0"
+"Maldives\0"
+"Mali\0"
+"Malta\0"
+"MarshallIslands\0"
+"Martinique\0"
+"Mauritania\0"
+"Mauritius\0"
+"Mayotte\0"
+"Mexico\0"
+"Micronesia\0"
+"Moldova\0"
+"Monaco\0"
+"Mongolia\0"
+"Montserrat\0"
+"Morocco\0"
+"Mozambique\0"
+"Myanmar\0"
+"Namibia\0"
+"Nauru\0"
+"Nepal\0"
+"Netherlands\0"
+"NetherlandsAntilles\0"
+"NewCaledonia\0"
+"NewZealand\0"
+"Nicaragua\0"
+"Niger\0"
+"Nigeria\0"
+"Niue\0"
+"NorfolkIsland\0"
+"NorthernMarianaIslands\0"
+"Norway\0"
+"Oman\0"
+"Pakistan\0"
+"Palau\0"
+"PalestinianTerritory\0"
+"Panama\0"
+"PapuaNewGuinea\0"
+"Paraguay\0"
+"Peru\0"
+"Philippines\0"
+"Pitcairn\0"
+"Poland\0"
+"Portugal\0"
+"PuertoRico\0"
+"Qatar\0"
+"Reunion\0"
+"Romania\0"
+"RussianFederation\0"
+"Rwanda\0"
+"SaintKittsAndNevis\0"
+"StLucia\0"
+"StVincentAndTheGrenadines\0"
+"Samoa\0"
+"SanMarino\0"
+"SaoTomeAndPrincipe\0"
+"SaudiArabia\0"
+"Senegal\0"
+"Seychelles\0"
+"SierraLeone\0"
+"Singapore\0"
+"Slovakia\0"
+"Slovenia\0"
+"SolomonIslands\0"
+"Somalia\0"
+"SouthAfrica\0"
+"SouthGeorgiaAndTheSouthSandwichIslands\0"
+"Spain\0"
+"SriLanka\0"
+"StHelena\0"
+"StPierreAndMiquelon\0"
+"Sudan\0"
+"Suriname\0"
+"SvalbardAndJanMayenIslands\0"
+"Swaziland\0"
+"Sweden\0"
+"Switzerland\0"
+"SyrianArabRepublic\0"
+"Taiwan\0"
+"Tajikistan\0"
+"Tanzania\0"
+"Thailand\0"
+"Togo\0"
+"Tokelau\0"
+"Tonga\0"
+"TrinidadAndTobago\0"
+"Tunisia\0"
+"Turkey\0"
+"Turkmenistan\0"
+"TurksAndCaicosIslands\0"
+"Tuvalu\0"
+"Uganda\0"
+"Ukraine\0"
+"UnitedArabEmirates\0"
+"UnitedKingdom\0"
+"UnitedStates\0"
+"UnitedStatesMinorOutlyingIslands\0"
+"Uruguay\0"
+"Uzbekistan\0"
+"Vanuatu\0"
+"VaticanCityState\0"
+"Venezuela\0"
+"VietNam\0"
+"BritishVirginIslands\0"
+"USVirginIslands\0"
+"WallisAndFutunaIslands\0"
+"WesternSahara\0"
+"Yemen\0"
+"Yugoslavia\0"
+"Zambia\0"
+"Zimbabwe\0";
+
+static const uint country_name_index[] = {
+ 0,// AnyCountry
+ 8,// Afghanistan
+ 20,// Albania
+ 28,// Algeria
+ 36,// AmericanSamoa
+ 50,// Andorra
+ 58,// Angola
+ 65,// Anguilla
+ 74,// Antarctica
+ 85,// AntiguaAndBarbuda
+ 103,// Argentina
+ 113,// Armenia
+ 121,// Aruba
+ 127,// Australia
+ 137,// Austria
+ 145,// Azerbaijan
+ 156,// Bahamas
+ 164,// Bahrain
+ 172,// Bangladesh
+ 183,// Barbados
+ 192,// Belarus
+ 200,// Belgium
+ 208,// Belize
+ 215,// Benin
+ 221,// Bermuda
+ 229,// Bhutan
+ 236,// Bolivia
+ 244,// BosniaAndHerzegowina
+ 265,// Botswana
+ 274,// BouvetIsland
+ 287,// Brazil
+ 294,// BritishIndianOceanTerritory
+ 322,// BruneiDarussalam
+ 339,// Bulgaria
+ 348,// BurkinaFaso
+ 360,// Burundi
+ 368,// Cambodia
+ 377,// Cameroon
+ 386,// Canada
+ 393,// CapeVerde
+ 403,// CaymanIslands
+ 417,// CentralAfricanRepublic
+ 440,// Chad
+ 445,// Chile
+ 451,// China
+ 457,// ChristmasIsland
+ 473,// CocosIslands
+ 486,// Colombia
+ 495,// Comoros
+ 503,// DetqmocraticRepublicOfCongo
+ 529,// PeoplesRepublicOfCongo
+ 552,// CookIslands
+ 564,// CostaRica
+ 574,// IvoryCoast
+ 585,// Croatia
+ 593,// Cuba
+ 598,// Cyprus
+ 605,// CzechRepublic
+ 619,// Denmark
+ 627,// Djibouti
+ 636,// Dominica
+ 645,// DominicanRepublic
+ 663,// EastTimor
+ 673,// Ecuador
+ 681,// Egypt
+ 687,// ElSalvador
+ 698,// EquatorialGuinea
+ 715,// Eritrea
+ 723,// Estonia
+ 731,// Ethiopia
+ 740,// FalklandIslands
+ 756,// FaroeIslands
+ 769,// Fiji
+ 774,// Finland
+ 782,// France
+ 789,// MetropolitanFrance
+ 808,// FrenchGuiana
+ 821,// FrenchPolynesia
+ 837,// FrenchSouthernTerritories
+ 863,// Gabon
+ 869,// Gambia
+ 876,// Georgia
+ 884,// Germany
+ 892,// Ghana
+ 898,// Gibraltar
+ 908,// Greece
+ 915,// Greenland
+ 925,// Grenada
+ 933,// Guadeloupe
+ 944,// Guam
+ 949,// Guatemala
+ 959,// Guinea
+ 966,// GuineaBissau
+ 979,// Guyana
+ 986,// Haiti
+ 992,// HeardAndMcDonaldIslands
+ 1016,// Honduras
+ 1025,// HongKong
+ 1034,// Hungary
+ 1042,// Iceland
+ 1050,// India
+ 1056,// Indonesia
+ 1066,// Iran
+ 1071,// Iraq
+ 1076,// Ireland
+ 1084,// Israel
+ 1091,// Italy
+ 1097,// Jamaica
+ 1105,// Japan
+ 1111,// Jordan
+ 1118,// Kazakhstan
+ 1129,// Kenya
+ 1135,// Kiribati
+ 1144,// DetqmocraticRepublicOfKorea
+ 1170,// RepublicOfKorea
+ 1186,// Kuwait
+ 1193,// Kyrgyzstan
+ 1204,// Lao
+ 1208,// Latvia
+ 1215,// Lebanon
+ 1223,// Lesotho
+ 1231,// Liberia
+ 1239,// LibyanArabJamahiriya
+ 1260,// Liechtenstein
+ 1274,// Lithuania
+ 1284,// Luxembourg
+ 1295,// Macau
+ 1301,// Macedonia
+ 1311,// Madagascar
+ 1322,// Malawi
+ 1329,// Malaysia
+ 1338,// Maldives
+ 1347,// Mali
+ 1352,// Malta
+ 1358,// MarshallIslands
+ 1374,// Martinique
+ 1385,// Mauritania
+ 1396,// Mauritius
+ 1406,// Mayotte
+ 1414,// Mexico
+ 1421,// Micronesia
+ 1432,// Moldova
+ 1440,// Monaco
+ 1447,// Mongolia
+ 1456,// Montserrat
+ 1467,// Morocco
+ 1475,// Mozambique
+ 1486,// Myanmar
+ 1494,// Namibia
+ 1502,// Nauru
+ 1508,// Nepal
+ 1514,// Netherlands
+ 1526,// NetherlandsAntilles
+ 1546,// NewCaledonia
+ 1559,// NewZealand
+ 1570,// Nicaragua
+ 1580,// Niger
+ 1586,// Nigeria
+ 1594,// Niue
+ 1599,// NorfolkIsland
+ 1613,// NorthernMarianaIslands
+ 1636,// Norway
+ 1643,// Oman
+ 1648,// Pakistan
+ 1657,// Palau
+ 1663,// PalestinianTerritory
+ 1684,// Panama
+ 1691,// PapuaNewGuinea
+ 1706,// Paraguay
+ 1715,// Peru
+ 1720,// Philippines
+ 1732,// Pitcairn
+ 1741,// Poland
+ 1748,// Portugal
+ 1757,// PuertoRico
+ 1768,// Qatar
+ 1774,// Reunion
+ 1782,// Romania
+ 1790,// RussianFederation
+ 1808,// Rwanda
+ 1815,// SaintKittsAndNevis
+ 1834,// StLucia
+ 1842,// StVincentAndTheGrenadines
+ 1868,// Samoa
+ 1874,// SanMarino
+ 1884,// SaoTomeAndPrincipe
+ 1903,// SaudiArabia
+ 1915,// Senegal
+ 1923,// Seychelles
+ 1934,// SierraLeone
+ 1946,// Singapore
+ 1956,// Slovakia
+ 1965,// Slovenia
+ 1974,// SolomonIslands
+ 1989,// Somalia
+ 1997,// SouthAfrica
+ 2009,// SouthGeorgiaAndTheSouthSandwichIslands
+ 2048,// Spain
+ 2054,// SriLanka
+ 2063,// StHelena
+ 2072,// StPierreAndMiquelon
+ 2092,// Sudan
+ 2098,// Suriname
+ 2107,// SvalbardAndJanMayenIslands
+ 2134,// Swaziland
+ 2144,// Sweden
+ 2151,// Switzerland
+ 2163,// SyrianArabRepublic
+ 2182,// Taiwan
+ 2189,// Tajikistan
+ 2200,// Tanzania
+ 2209,// Thailand
+ 2218,// Togo
+ 2223,// Tokelau
+ 2231,// Tonga
+ 2237,// TrinidadAndTobago
+ 2255,// Tunisia
+ 2263,// Turkey
+ 2270,// Turkmenistan
+ 2283,// TurksAndCaicosIslands
+ 2305,// Tuvalu
+ 2312,// Uganda
+ 2319,// Ukraine
+ 2327,// UnitedArabEmirates
+ 2346,// UnitedKingdom
+ 2360,// UnitedStates
+ 2373,// UnitedStatesMinorOutlyingIslands
+ 2406,// Uruguay
+ 2414,// Uzbekistan
+ 2425,// Vanuatu
+ 2433,// VaticanCityState
+ 2450,// Venezuela
+ 2460,// VietNam
+ 2468,// BritishVirginIslands
+ 2489,// USVirginIslands
+ 2505,// WallisAndFutunaIslands
+ 2528,// WesternSahara
+ 2542,// Yemen
+ 2548,// Yugoslavia
+ 2559,// Zambia
+ 2566// Zimbabwe
+};
+
+static const char language_code_list[] =
+" " // Unused
+" " // C
+"ab" // Abkhazian
+"om" // Afan
+"aa" // Afar
+"af" // Afrikaans
+"sq" // Albanian
+"am" // Amharic
+"ar" // Arabic
+"hy" // Armenian
+"as" // Assamese
+"ay" // Aymara
+"az" // Azerbaijani
+"ba" // Bashkir
+"eu" // Basque
+"bn" // Bengali
+"dz" // Bhutani
+"bh" // Bihari
+"bi" // Bislama
+"br" // Breton
+"bg" // Bulgarian
+"my" // Burmese
+"be" // Byelorussian
+"km" // Cambodian
+"ca" // Catalan
+"zh" // Chinese
+"co" // Corsican
+"hr" // Croatian
+"cs" // Czech
+"da" // Danish
+"nl" // Dutch
+"en" // English
+"eo" // Esperanto
+"et" // Estonian
+"fo" // Faroese
+"fj" // Fiji
+"fi" // Finnish
+"fr" // French
+"fy" // Frisian
+"gd" // Gaelic
+"gl" // Galician
+"ka" // Georgian
+"de" // German
+"el" // Greek
+"kl" // Greenlandic
+"gn" // Guarani
+"gu" // Gujarati
+"ha" // Hausa
+"he" // Hebrew
+"hi" // Hindi
+"hu" // Hungarian
+"is" // Icelandic
+"id" // Indonesian
+"ia" // Interlingua
+"ie" // Interlingue
+"iu" // Inuktitut
+"ik" // Inupiak
+"ga" // Irish
+"it" // Italian
+"ja" // Japanese
+"jv" // Javanese
+"kn" // Kannada
+"ks" // Kashmiri
+"kk" // Kazakh
+"rw" // Kinyarwanda
+"ky" // Kirghiz
+"ko" // Korean
+"ku" // Kurdish
+"rn" // Kurundi
+"lo" // Laothian
+"la" // Latin
+"lv" // Latvian
+"ln" // Lingala
+"lt" // Lithuanian
+"mk" // Macedonian
+"mg" // Malagasy
+"ms" // Malay
+"ml" // Malayalam
+"mt" // Maltese
+"mi" // Maori
+"mr" // Marathi
+"mo" // Moldavian
+"mn" // Mongolian
+"na" // Nauru
+"ne" // Nepali
+"no" // Norwegian
+"oc" // Occitan
+"or" // Oriya
+"ps" // Pashto
+"fa" // Persian
+"pl" // Polish
+"pt" // Portuguese
+"pa" // Punjabi
+"qu" // Quechua
+"rm" // RhaetoRomance
+"ro" // Romanian
+"ru" // Russian
+"sm" // Samoan
+"sg" // Sangho
+"sa" // Sanskrit
+"sr" // Serbian
+"sh" // SerboCroatian
+"st" // Sesotho
+"tn" // Setswana
+"sn" // Shona
+"sd" // Sindhi
+"si" // Singhalese
+"ss" // Siswati
+"sk" // Slovak
+"sl" // Slovenian
+"so" // Somali
+"es" // Spanish
+"su" // Sundanese
+"sw" // Swahili
+"sv" // Swedish
+"tl" // Tagalog
+"tg" // Tajik
+"ta" // Tamil
+"tt" // Tatar
+"te" // Telugu
+"th" // Thai
+"bo" // Tibetan
+"ti" // Tigrinya
+"to" // Tonga
+"ts" // Tsonga
+"tr" // Turkish
+"tk" // Turkmen
+"tw" // Twi
+"ug" // Uigur
+"uk" // Ukrainian
+"ur" // Urdu
+"uz" // Uzbek
+"vi" // Vietnamese
+"vo" // Volapuk
+"cy" // Welsh
+"wo" // Wolof
+"xh" // Xhosa
+"yi" // Yiddish
+"yo" // Yoruba
+"za" // Zhuang
+"zu" // Zulu
+;
+
+static const char country_code_list[] =
+" " // AnyLanguage
+"AF" // Afghanistan
+"AL" // Albania
+"DZ" // Algeria
+"AS" // AmericanSamoa
+"AD" // Andorra
+"AO" // Angola
+"AI" // Anguilla
+"AQ" // Antarctica
+"AG" // AntiguaAndBarbuda
+"AR" // Argentina
+"AM" // Armenia
+"AW" // Aruba
+"AU" // Australia
+"AT" // Austria
+"AZ" // Azerbaijan
+"BS" // Bahamas
+"BH" // Bahrain
+"BD" // Bangladesh
+"BB" // Barbados
+"BY" // Belarus
+"BE" // Belgium
+"BZ" // Belize
+"BJ" // Benin
+"BM" // Bermuda
+"BT" // Bhutan
+"BO" // Bolivia
+"BA" // BosniaAndHerzegowina
+"BW" // Botswana
+"BV" // BouvetIsland
+"BR" // Brazil
+"IO" // BritishIndianOceanTerritory
+"BN" // BruneiDarussalam
+"BG" // Bulgaria
+"BF" // BurkinaFaso
+"BI" // Burundi
+"KH" // Cambodia
+"CM" // Cameroon
+"CA" // Canada
+"CV" // CapeVerde
+"KY" // CaymanIslands
+"CF" // CentralAfricanRepublic
+"TD" // Chad
+"CL" // Chile
+"CN" // China
+"CX" // ChristmasIsland
+"CC" // CocosIslands
+"CO" // Colombia
+"KM" // Comoros
+"CD" // DetqmocraticRepublicOfCongo
+"CG" // PeoplesRepublicOfCongo
+"CK" // CookIslands
+"CR" // CostaRica
+"CI" // IvoryCoast
+"HR" // Croatia
+"CU" // Cuba
+"CY" // Cyprus
+"CZ" // CzechRepublic
+"DK" // Denmark
+"DJ" // Djibouti
+"DM" // Dominica
+"DO" // DominicanRepublic
+"TL" // EastTimor
+"EC" // Ecuador
+"EG" // Egypt
+"SV" // ElSalvador
+"GQ" // EquatorialGuinea
+"ER" // Eritrea
+"EE" // Estonia
+"ET" // Ethiopia
+"FK" // FalklandIslands
+"FO" // FaroeIslands
+"FJ" // Fiji
+"FI" // Finland
+"FR" // France
+"FX" // MetropolitanFrance
+"GF" // FrenchGuiana
+"PF" // FrenchPolynesia
+"TF" // FrenchSouthernTerritories
+"GA" // Gabon
+"GM" // Gambia
+"GE" // Georgia
+"DE" // Germany
+"GH" // Ghana
+"GI" // Gibraltar
+"GR" // Greece
+"GL" // Greenland
+"GD" // Grenada
+"GP" // Guadeloupe
+"GU" // Guam
+"GT" // Guatemala
+"GN" // Guinea
+"GW" // GuineaBissau
+"GY" // Guyana
+"HT" // Haiti
+"HM" // HeardAndMcDonaldIslands
+"HN" // Honduras
+"HK" // HongKong
+"HU" // Hungary
+"IS" // Iceland
+"IN" // India
+"ID" // Indonesia
+"IR" // Iran
+"IQ" // Iraq
+"IE" // Ireland
+"IL" // Israel
+"IT" // Italy
+"JM" // Jamaica
+"JP" // Japan
+"JO" // Jordan
+"KZ" // Kazakhstan
+"KE" // Kenya
+"KI" // Kiribati
+"KP" // DetqmocraticRepublicOfKorea
+"KR" // RepublicOfKorea
+"KW" // Kuwait
+"KG" // Kyrgyzstan
+"LA" // Lao
+"LV" // Latvia
+"LB" // Lebanon
+"LS" // Lesotho
+"LR" // Liberia
+"LY" // LibyanArabJamahiriya
+"LI" // Liechtenstein
+"LT" // Lithuania
+"LU" // Luxembourg
+"MO" // Macau
+"MK" // Macedonia
+"MG" // Madagascar
+"MW" // Malawi
+"MY" // Malaysia
+"MV" // Maldives
+"ML" // Mali
+"MT" // Malta
+"MH" // MarshallIslands
+"MQ" // Martinique
+"MR" // Mauritania
+"MU" // Mauritius
+"YT" // Mayotte
+"MX" // Mexico
+"FM" // Micronesia
+"MD" // Moldova
+"MC" // Monaco
+"MN" // Mongolia
+"MS" // Montserrat
+"MA" // Morocco
+"MZ" // Mozambique
+"MM" // Myanmar
+"NA" // Namibia
+"NR" // Nauru
+"NP" // Nepal
+"NL" // Netherlands
+"AN" // NetherlandsAntilles
+"NC" // NewCaledonia
+"NZ" // NewZealand
+"NI" // Nicaragua
+"NE" // Niger
+"NG" // Nigeria
+"NU" // Niue
+"NF" // NorfolkIsland
+"MP" // NorthernMarianaIslands
+"NO" // Norway
+"OM" // Oman
+"PK" // Pakistan
+"PW" // Palau
+"PS" // PalestinianTerritory
+"PA" // Panama
+"PG" // PapuaNewGuinea
+"PY" // Paraguay
+"PE" // Peru
+"PH" // Philippines
+"PN" // Pitcairn
+"PL" // Poland
+"PT" // Portugal
+"PR" // PuertoRico
+"QA" // Qatar
+"RE" // Reunion
+"RO" // Romania
+"RU" // RussianFederation
+"RW" // Rwanda
+"KN" // SaintKittsAndNevis
+"LC" // StLucia
+"VC" // StVincentAndTheGrenadines
+"WS" // Samoa
+"SM" // SanMarino
+"ST" // SaoTomeAndPrincipe
+"SA" // SaudiArabia
+"SN" // Senegal
+"SC" // Seychelles
+"SL" // SierraLeone
+"SG" // Singapore
+"SK" // Slovakia
+"SI" // Slovenia
+"SB" // SolomonIslands
+"SO" // Somalia
+"ZA" // SouthAfrica
+"GS" // SouthGeorgiaAndTheSouthSandwichIslands
+"ES" // Spain
+"LK" // SriLanka
+"SH" // StHelena
+"PM" // StPierreAndMiquelon
+"SD" // Sudan
+"SR" // Suriname
+"SJ" // SvalbardAndJanMayenIslands
+"SZ" // Swaziland
+"SE" // Sweden
+"CH" // Switzerland
+"SY" // SyrianArabRepublic
+"TW" // Taiwan
+"TJ" // Tajikistan
+"TZ" // Tanzania
+"TH" // Thailand
+"TG" // Togo
+"TK" // Tokelau
+"TO" // Tonga
+"TT" // TrinidadAndTobago
+"TN" // Tunisia
+"TR" // Turkey
+"TM" // Turkmenistan
+"TC" // TurksAndCaicosIslands
+"TV" // Tuvalu
+"UG" // Uganda
+"UA" // Ukraine
+"AE" // UnitedArabEmirates
+"GB" // UnitedKingdom
+"US" // UnitedStates
+"UM" // UnitedStatesMinorOutlyingIslands
+"UY" // Uruguay
+"UZ" // Uzbekistan
+"VU" // Vanuatu
+"VA" // VaticanCityState
+"VE" // Venezuela
+"VN" // VietNam
+"VG" // BritishVirginIslands
+"VI" // USVirginIslands
+"WF" // WallisAndFutunaIslands
+"EH" // WesternSahara
+"YE" // Yemen
+"YU" // Yugoslavia
+"ZM" // Zambia
+"ZW" // Zimbabwe
+;
+
+static TQLocale::Language codeToLanguage(const TQString &code)
+{
+ if (code.length() != 2)
+ return TQLocale::C;
+
+ ushort uc1 = code.tqunicode()[0].tqunicode();
+ ushort uc2 = code.tqunicode()[1].tqunicode();
+
+ const char *c = language_code_list;
+ for (; *c != 0; c += 2) {
+ if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1])
+ return (TQLocale::Language) ((c - language_code_list)/2);
+ }
+
+ return TQLocale::C;
+}
+
+static TQLocale::Country codeToCountry(const TQString &code)
+{
+ if (code.length() != 2)
+ return TQLocale::AnyCountry;
+
+ ushort uc1 = code.tqunicode()[0].tqunicode();
+ ushort uc2 = code.tqunicode()[1].tqunicode();
+
+ const char *c = country_code_list;
+ for (; *c != 0; c += 2) {
+ if (uc1 == (unsigned char)c[0] && uc2 == (unsigned char)c[1])
+ return (TQLocale::Country) ((c - country_code_list)/2);
+ }
+
+ return TQLocale::AnyCountry;
+}
+
+static TQString languageToCode(TQLocale::Language language)
+{
+ if (language == TQLocale::C)
+ return "C";
+
+ TQString code;
+ code.setLength(2);
+ const char *c = language_code_list + 2*(uint)language;
+ code[0] = c[0];
+ code[1] = c[1];
+ return code;
+}
+
+static TQString countryToCode(TQLocale::Country country)
+{
+ if (country == TQLocale::AnyCountry)
+ return TQString::null;
+
+ TQString code;
+ code.setLength(2);
+ const char *c = country_code_list + 2*(uint)country;
+ code[0] = c[0];
+ code[1] = c[1];
+ return code;
+}
+
+const TQLocalePrivate *TQLocale::default_d = 0;
+
+TQString TQLocalePrivate::infinity() const
+{
+ return TQString::tqfromLatin1("inf");
+}
+
+TQString TQLocalePrivate::nan() const
+{
+ return TQString::tqfromLatin1("nan");
+}
+
+#if defined(TQ_OS_WIN)
+/* Win95 doesn't have a function to return the ISO lang/country name of the user's locale.
+ Instead it can return a "Windows code". This maps windows codes to ISO country names. */
+
+struct WindowsToISOListElt {
+ int windows_code;
+ char iso_name[6];
+};
+
+static const WindowsToISOListElt windows_to_iso_list[] = {
+ { 0x0401, "ar_SA" },
+ { 0x0402, "bg\0 " },
+ { 0x0403, "ca\0 " },
+ { 0x0404, "zh_TW" },
+ { 0x0405, "cs\0 " },
+ { 0x0406, "da\0 " },
+ { 0x0407, "de\0 " },
+ { 0x0408, "el\0 " },
+ { 0x0409, "en_US" },
+ { 0x040a, "es\0 " },
+ { 0x040b, "fi\0 " },
+ { 0x040c, "fr\0 " },
+ { 0x040d, "he\0 " },
+ { 0x040e, "hu\0 " },
+ { 0x040f, "is\0 " },
+ { 0x0410, "it\0 " },
+ { 0x0411, "ja\0 " },
+ { 0x0412, "ko\0 " },
+ { 0x0413, "nl\0 " },
+ { 0x0414, "no\0 " },
+ { 0x0415, "pl\0 " },
+ { 0x0416, "pt_BR" },
+ { 0x0418, "ro\0 " },
+ { 0x0419, "ru\0 " },
+ { 0x041a, "hr\0 " },
+ { 0x041c, "sq\0 " },
+ { 0x041d, "sv\0 " },
+ { 0x041e, "th\0 " },
+ { 0x041f, "tr\0 " },
+ { 0x0420, "ur\0 " },
+ { 0x0421, "in\0 " },
+ { 0x0422, "uk\0 " },
+ { 0x0423, "be\0 " },
+ { 0x0425, "et\0 " },
+ { 0x0426, "lv\0 " },
+ { 0x0427, "lt\0 " },
+ { 0x0429, "fa\0 " },
+ { 0x042a, "vi\0 " },
+ { 0x042d, "eu\0 " },
+ { 0x042f, "mk\0 " },
+ { 0x0436, "af\0 " },
+ { 0x0438, "fo\0 " },
+ { 0x0439, "hi\0 " },
+ { 0x043e, "ms\0 " },
+ { 0x0458, "mt\0 " },
+ { 0x0801, "ar_IQ" },
+ { 0x0804, "zh_CN" },
+ { 0x0807, "de_CH" },
+ { 0x0809, "en_GB" },
+ { 0x080a, "es_MX" },
+ { 0x080c, "fr_BE" },
+ { 0x0810, "it_CH" },
+ { 0x0812, "ko\0 " },
+ { 0x0813, "nl_BE" },
+ { 0x0814, "no\0 " },
+ { 0x0816, "pt\0 " },
+ { 0x081a, "sr\0 " },
+ { 0x081d, "sv_FI" },
+ { 0x0c01, "ar_EG" },
+ { 0x0c04, "zh_HK" },
+ { 0x0c07, "de_AT" },
+ { 0x0c09, "en_AU" },
+ { 0x0c0a, "es\0 " },
+ { 0x0c0c, "fr_CA" },
+ { 0x0c1a, "sr\0 " },
+ { 0x1001, "ar_LY" },
+ { 0x1004, "zh_SG" },
+ { 0x1007, "de_LU" },
+ { 0x1009, "en_CA" },
+ { 0x100a, "es_GT" },
+ { 0x100c, "fr_CH" },
+ { 0x1401, "ar_DZ" },
+ { 0x1407, "de_LI" },
+ { 0x1409, "en_NZ" },
+ { 0x140a, "es_CR" },
+ { 0x140c, "fr_LU" },
+ { 0x1801, "ar_MA" },
+ { 0x1809, "en_IE" },
+ { 0x180a, "es_PA" },
+ { 0x1c01, "ar_TN" },
+ { 0x1c09, "en_ZA" },
+ { 0x1c0a, "es_DO" },
+ { 0x2001, "ar_OM" },
+ { 0x2009, "en_JM" },
+ { 0x200a, "es_VE" },
+ { 0x2401, "ar_YE" },
+ { 0x2409, "en\0 " },
+ { 0x240a, "es_CO" },
+ { 0x2801, "ar_SY" },
+ { 0x2809, "en_BZ" },
+ { 0x280a, "es_PE" },
+ { 0x2c01, "ar_JO" },
+ { 0x2c09, "en_TT" },
+ { 0x2c0a, "es_AR" },
+ { 0x3001, "ar_LB" },
+ { 0x300a, "es_EC" },
+ { 0x3401, "ar_KW" },
+ { 0x340a, "es_CL" },
+ { 0x3801, "ar_AE" },
+ { 0x380a, "es_UY" },
+ { 0x3c01, "ar_BH" },
+ { 0x3c0a, "es_PY" },
+ { 0x4001, "ar_QA" },
+ { 0x400a, "es_BO" },
+ { 0x440a, "es_SV" },
+ { 0x480a, "es_HN" },
+ { 0x4c0a, "es_NI" },
+ { 0x500a, "es_PR" }
+};
+
+static const int windows_to_iso_count
+ = sizeof(windows_to_iso_list)/sizeof(WindowsToISOListElt);
+
+static const char *winLangCodeToIsoName(int code)
+{
+ int cmp = code - windows_to_iso_list[0].windows_code;
+ if (cmp < 0)
+ return 0;
+
+ if (cmp == 0)
+ return windows_to_iso_list[0].iso_name;
+
+ int begin = 0;
+ int end = windows_to_iso_count;
+
+ while (end - begin > 1) {
+ uint mid = (begin + end)/2;
+
+ const WindowsToISOListElt *elt = windows_to_iso_list + mid;
+ int cmp = code - elt->windows_code;
+ if (cmp < 0)
+ end = mid;
+ else if (cmp > 0)
+ begin = mid;
+ else
+ return elt->iso_name;
+ }
+
+ return 0;
+
+}
+#endif // TQ_OS_WIN
+
+const char* TQLocalePrivate::systemLocaleName()
+{
+ static TQCString lang;
+ lang = getenv( "LANG" );
+
+#if !defined( TQWS ) && defined( TQ_OS_MAC )
+ if ( !lang.isEmpty() )
+ return lang;
+
+ char mac_ret[255];
+ if(!LocaleRefGetPartString(NULL, kLocaleLanguageMask | kLocaleRegionMask, 255, mac_ret))
+ lang = mac_ret;
+#endif
+
+#if defined(TQ_WS_WIN)
+ if ( !lang.isEmpty() ) {
+ long id = 0;
+ bool ok = false;
+ id = qstrtoll(lang.data(), 0, 0, &ok);
+ if ( !ok || id == 0 || id < INT_MIN || id > INT_MAX )
+ return lang;
+ else
+ return winLangCodeToIsoName( (int)id );
+ }
+
+ if (qWinVersion() == TQt::WV_95) {
+ lang = winLangCodeToIsoName(GetUserDefaultLangID());
+ } else {
+ TQT_WA( {
+ wchar_t out[256];
+ TQString language;
+ TQString sublanguage;
+ if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME , out, 255 ) )
+ language = TQString::fromUcs2( (ushort*)out );
+ if ( GetLocaleInfoW( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) )
+ sublanguage = TQString::fromUcs2( (ushort*)out ).lower();
+ lang = language;
+ if ( sublanguage != language && !sublanguage.isEmpty() )
+ lang += "_" + sublanguage.upper();
+ } , {
+ char out[256];
+ TQString language;
+ TQString sublanguage;
+ if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, out, 255 ) )
+ language = TQString::fromLocal8Bit( out );
+ if ( GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, out, 255 ) )
+ sublanguage = TQString::fromLocal8Bit( out ).lower();
+ lang = language;
+ if ( sublanguage != language && !sublanguage.isEmpty() )
+ lang += "_" + sublanguage.upper();
+ } );
+ }
+#endif
+ if ( lang.isEmpty() )
+ lang = "C";
+
+ return lang;
+}
+
+static const TQLocalePrivate *tqfindLocale(TQLocale::Language language,
+ TQLocale::Country country)
+{
+ unsigned language_id = (unsigned)language;
+ unsigned country_id = (unsigned)country;
+
+ uint idx = locale_index[language_id];
+
+ const TQLocalePrivate *d = locale_data + idx;
+
+ if (idx == 0) // default language has no associated country
+ return d;
+
+ if (country == TQLocale::AnyCountry)
+ return d;
+
+ TQ_ASSERT(d->languageId() == language_id);
+
+ while (d->languageId() == language_id
+ && d->countryId() != country_id)
+ ++d;
+
+ if (d->countryId() == country_id
+ && d->languageId() == language_id)
+ return d;
+
+ return locale_data + idx;
+}
+
+/*!
+ \class TQLocale
+ \brief The TQLocale class converts between numbers and their
+ string representations in various languages.
+
+ \reentrant
+ \ingroup text
+
+ It is initialized with a country/language pair in its constructor
+ and offers number-to-string and string-to-number conversion
+ functions simmilar to those in TQString.
+
+ \code
+ TQLocale egyptian(TQLocale::Arabic, TQLocale::Egypt);
+ TQString s1 = egyptian.toString(1.571429E+07, 'e');
+ TQString s2 = egyptian.toString(10);
+
+ double d = egyptian.toDouble(s1);
+ int s2 = egyptian.toInt(s2);
+ \endcode
+
+ TQLocale supports the concept of a default locale, which is
+ determined from the system's locale settings at application
+ startup. The default locale can be changed by calling the
+ static member setDefault(). The default locale has the
+ following effects:
+
+ \list
+ \i If a TQLocale object is constructed with the default constructor,
+ it will use the default locale's settings.
+ \i TQString::toDouble() interprets the string according to the default
+ locale. If this fails, it falls back on the "C" locale.
+ \i TQString::arg() uses the default locale to format a number when
+ its position specifier in the format string tqcontains an 'L',
+ e.g. "%L1".
+ \endlist
+
+ \code
+ TQLocale::setDefault(TQLocale(TQLocale::Hebrew, TQLocale::Israel));
+ TQLocale hebrew; // Constructs a default TQLocale
+ TQString s1 = hebrew.toString(15714.3, 'e');
+
+ bool ok;
+ double d;
+
+ TQLocale::setDefault(TQLocale::C);
+ d = TQString( "1234,56" ).toDouble(&ok); // ok == false
+ d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56
+
+ TQLocale::setDefault(TQLocale::German);
+ d = TQString( "1234,56" ).toDouble(&ok); // ok == true, d == 1234.56
+ d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56
+
+ TQLocale::setDefault(TQLocale(TQLocale::English, TQLocale::UnitedStates));
+ str = TQString( "%1 %L2 %L3" )
+ .arg( 12345 )
+ .arg( 12345 )
+ .arg( 12345, 0, 16 );
+ // str == "12345 12,345 3039"
+ \endcode
+
+ When a language/country pair is specified in the constructor, one
+ of three things can happen:
+
+ \list
+ \i If the language/country pair is found in the database, it is used.
+ \i If the language is found but the country is not, or if the country
+ is \c AnyCountry, the language is used with the most
+ appropriate available country (for example, Germany for German),
+ \i If neither the language nor the country are found, TQLocale
+ defaults to the default locale (see setDefault()).
+ \endlist
+
+ The "C" locale is identical to English/UnitedStates.
+
+ Use language() and country() to determine the actual language and
+ country values used.
+
+ An alternative method for constructing a TQLocale object is by
+ specifying the locale name.
+
+ \code
+ TQLocale korean("ko");
+ TQLocale swiss("de_CH");
+ \endcode
+
+ This constructor converts the locale name to a language/country
+ pair; it does not use the system locale database.
+
+ All the methods in TQLocale, with the exception of setDefault(),
+ are reentrant.
+
+ \sa TQString::toDouble() TQString::arg()
+
+ The double-to-string and string-to-double conversion functions are
+ covered by the following licenses:
+
+ \legalese
+
+ Copyright (c) 1991 by AT&T.
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose without fee is hereby granted, provided that this entire notice
+ is included in all copies of any software which is or includes a copy
+ or modification of this software and in all copies of the supporting
+ documentation for such software.
+
+ THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
+ WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR AT&T MAKES ANY
+ REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
+ OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
+
+ This product includes software developed by the University of
+ California, Berkeley and its contributors.
+*/
+
+/*!
+ \enum TQLocale::Language
+
+ This enumerated type is used to specify a language.
+
+ \value C Identical to English/UnitedStates
+ \value Abkhazian
+ \value Afan
+ \value Afar
+ \value Afrikaans
+ \value Albanian
+ \value Amharic
+ \value Arabic
+ \value Armenian
+ \value Assamese
+ \value Aymara
+ \value Azerbaijani
+ \value Bashkir
+ \value Basque
+ \value Bengali
+ \value Bhutani
+ \value Bihari
+ \value Bislama
+ \value Breton
+ \value Bulgarian
+ \value Burmese
+ \value Byelorussian
+ \value Cambodian
+ \value Catalan
+ \value Chinese
+ \value Corsican
+ \value Croatian
+ \value Czech
+ \value Danish
+ \value Dutch
+ \value English
+ \value Esperanto
+ \value Estonian
+ \value Faroese
+ \value FijiLanguage
+ \value Finnish
+ \value French
+ \value Frisian
+ \value Gaelic
+ \value Galician
+ \value Georgian
+ \value German
+ \value Greek
+ \value Greenlandic
+ \value Guarani
+ \value Gujarati
+ \value Hausa
+ \value Hebrew
+ \value Hindi
+ \value Hungarian
+ \value Icelandic
+ \value Indonesian
+ \value Interlingua
+ \value Interlingue
+ \value Inuktitut
+ \value Inupiak
+ \value Irish
+ \value Italian
+ \value Japanese
+ \value Javanese
+ \value Kannada
+ \value Kashmiri
+ \value Kazakh
+ \value Kinyarwanda
+ \value Kirghiz
+ \value Korean
+ \value Kurdish
+ \value Kurundi
+ \value Laothian
+ \value Latin
+ \value Latvian
+ \value Lingala
+ \value Lithuanian
+ \value Macedonian
+ \value Malagasy
+ \value Malay
+ \value Malayalam
+ \value Maltese
+ \value Maori
+ \value Marathi
+ \value Moldavian
+ \value Mongolian
+ \value NauruLanguage
+ \value Nepali
+ \value Norwegian
+ \value Occitan
+ \value Oriya
+ \value Pashto
+ \value Persian
+ \value Polish
+ \value Portuguese
+ \value Punjabi
+ \value Quechua
+ \value RhaetoRomance
+ \value Romanian
+ \value Russian
+ \value Samoan
+ \value Sangho
+ \value Sanskrit
+ \value Serbian
+ \value SerboCroatian
+ \value Sesotho
+ \value Setswana
+ \value Shona
+ \value Sindhi
+ \value Singhalese
+ \value Siswati
+ \value Slovak
+ \value Slovenian
+ \value Somali
+ \value Spanish
+ \value Sundanese
+ \value Swahili
+ \value Swedish
+ \value Tagalog
+ \value Tajik
+ \value Tamil
+ \value Tatar
+ \value Telugu
+ \value Thai
+ \value Tibetan
+ \value Tigrinya
+ \value TongaLanguage
+ \value Tsonga
+ \value Turkish
+ \value Turkmen
+ \value Twi
+ \value Uigur
+ \value Ukrainian
+ \value Urdu
+ \value Uzbek
+ \value Vietnamese
+ \value Volapuk
+ \value Welsh
+ \value Wolof
+ \value Xhosa
+ \value Yiddish
+ \value Yoruba
+ \value Zhuang
+ \value Zulu
+*/
+
+/*!
+ \enum TQLocale::Country
+
+ This enumerated type is used to specify a country.
+
+ \value AnyCountry
+ \value Afghanistan
+ \value Albania
+ \value Algeria
+ \value AmericanSamoa
+ \value Andorra
+ \value Angola
+ \value Anguilla
+ \value Antarctica
+ \value AntiguaAndBarbuda
+ \value Argentina
+ \value Armenia
+ \value Aruba
+ \value Australia
+ \value Austria
+ \value Azerbaijan
+ \value Bahamas
+ \value Bahrain
+ \value Bangladesh
+ \value Barbados
+ \value Belarus
+ \value Belgium
+ \value Belize
+ \value Benin
+ \value Bermuda
+ \value Bhutan
+ \value Bolivia
+ \value BosniaAndHerzegowina
+ \value Botswana
+ \value BouvetIsland
+ \value Brazil
+ \value BritishIndianOceanTerritory
+ \value BruneiDarussalam
+ \value Bulgaria
+ \value BurkinaFaso
+ \value Burundi
+ \value Cambodia
+ \value Cameroon
+ \value Canada
+ \value CapeVerde
+ \value CaymanIslands
+ \value CentralAfricanRepublic
+ \value Chad
+ \value Chile
+ \value China
+ \value ChristmasIsland
+ \value CocosIslands
+ \value Colombia
+ \value Comoros
+ \value DetqmocraticRepublicOfCongo
+ \value PeoplesRepublicOfCongo
+ \value CookIslands
+ \value CostaRica
+ \value IvoryCoast
+ \value Croatia
+ \value Cuba
+ \value Cyprus
+ \value CzechRepublic
+ \value Denmark
+ \value Djibouti
+ \value Dominica
+ \value DominicanRepublic
+ \value EastTimor
+ \value Ecuador
+ \value Egypt
+ \value ElSalvador
+ \value EquatorialGuinea
+ \value Eritrea
+ \value Estonia
+ \value Ethiopia
+ \value FalklandIslands
+ \value FaroeIslands
+ \value FijiCountry
+ \value Finland
+ \value France
+ \value MetropolitanFrance
+ \value FrenchGuiana
+ \value FrenchPolynesia
+ \value FrenchSouthernTerritories
+ \value Gabon
+ \value Gambia
+ \value Georgia
+ \value Germany
+ \value Ghana
+ \value Gibraltar
+ \value Greece
+ \value Greenland
+ \value Grenada
+ \value Guadeloupe
+ \value Guam
+ \value Guatemala
+ \value Guinea
+ \value GuineaBissau
+ \value Guyana
+ \value Haiti
+ \value HeardAndMcDonaldIslands
+ \value Honduras
+ \value HongKong
+ \value Hungary
+ \value Iceland
+ \value India
+ \value Indonesia
+ \value Iran
+ \value Iraq
+ \value Ireland
+ \value Israel
+ \value Italy
+ \value Jamaica
+ \value Japan
+ \value Jordan
+ \value Kazakhstan
+ \value Kenya
+ \value Kiribati
+ \value DetqmocraticRepublicOfKorea
+ \value RepublicOfKorea
+ \value Kuwait
+ \value Kyrgyzstan
+ \value Lao
+ \value Latvia
+ \value Lebanon
+ \value Lesotho
+ \value Liberia
+ \value LibyanArabJamahiriya
+ \value Liechtenstein
+ \value Lithuania
+ \value Luxembourg
+ \value Macau
+ \value Macedonia
+ \value Madagascar
+ \value Malawi
+ \value Malaysia
+ \value Maldives
+ \value Mali
+ \value Malta
+ \value MarshallIslands
+ \value Martinique
+ \value Mauritania
+ \value Mauritius
+ \value Mayotte
+ \value Mexico
+ \value Micronesia
+ \value Moldova
+ \value Monaco
+ \value Mongolia
+ \value Montserrat
+ \value Morocco
+ \value Mozambique
+ \value Myanmar
+ \value Namibia
+ \value NauruCountry
+ \value Nepal
+ \value Netherlands
+ \value NetherlandsAntilles
+ \value NewCaledonia
+ \value NewZealand
+ \value Nicaragua
+ \value Niger
+ \value Nigeria
+ \value Niue
+ \value NorfolkIsland
+ \value NorthernMarianaIslands
+ \value Norway
+ \value Oman
+ \value Pakistan
+ \value Palau
+ \value PalestinianTerritory
+ \value Panama
+ \value PapuaNewGuinea
+ \value Paraguay
+ \value Peru
+ \value Philippines
+ \value Pitcairn
+ \value Poland
+ \value Portugal
+ \value PuertoRico
+ \value Qatar
+ \value Reunion
+ \value Romania
+ \value RussianFederation
+ \value Rwanda
+ \value SaintKittsAndNevis
+ \value StLucia
+ \value StVincentAndTheGrenadines
+ \value Samoa
+ \value SanMarino
+ \value SaoTomeAndPrincipe
+ \value SaudiArabia
+ \value Senegal
+ \value Seychelles
+ \value SierraLeone
+ \value Singapore
+ \value Slovakia
+ \value Slovenia
+ \value SolomonIslands
+ \value Somalia
+ \value SouthAfrica
+ \value SouthGeorgiaAndTheSouthSandwichIslands
+ \value Spain
+ \value SriLanka
+ \value StHelena
+ \value StPierreAndMiquelon
+ \value Sudan
+ \value Suriname
+ \value SvalbardAndJanMayenIslands
+ \value Swaziland
+ \value Sweden
+ \value Switzerland
+ \value SyrianArabRepublic
+ \value Taiwan
+ \value Tajikistan
+ \value Tanzania
+ \value Thailand
+ \value Togo
+ \value Tokelau
+ \value TongaCountry
+ \value TrinidadAndTobago
+ \value Tunisia
+ \value Turkey
+ \value Turkmenistan
+ \value TurksAndCaicosIslands
+ \value Tuvalu
+ \value Uganda
+ \value Ukraine
+ \value UnitedArabEmirates
+ \value UnitedKingdom
+ \value UnitedStates
+ \value UnitedStatesMinorOutlyingIslands
+ \value Uruguay
+ \value Uzbekistan
+ \value Vanuatu
+ \value VaticanCityState
+ \value Venezuela
+ \value VietNam
+ \value BritishVirginIslands
+ \value USVirginIslands
+ \value WallisAndFutunaIslands
+ \value WesternSahara
+ \value Yemen
+ \value Yugoslavia
+ \value Zambia
+ \value Zimbabwe
+*/
+
+/*!
+ Constructs a TQLocale object with the specified \a name,
+ which has the format
+ "language[_country][.codeset][@modifier]" or "C", where:
+
+ \list
+ \i language is a lowercase, two-letter, ISO 639 language code,
+ \i territory is an uppercase, two-letter, ISO 3166 country code,
+ \i and codeset and modifier are ignored.
+ \endlist
+
+ If the string violates the locale format, or language is not
+ a valid ISO 369 code, the "C" locale is used instead. If country
+ is not present, or is not a valid ISO 3166 code, the most
+ appropriate country is chosen for the specified language.
+
+ The language and country codes are converted to their respective
+ \c Language and \c Country enums. After this conversion is
+ performed the constructor behaves exactly like TQLocale(Country,
+ Language).
+
+ This constructor is much slower than TQLocale(Country, Language).
+
+ \sa name()
+*/
+
+TQLocale::TQLocale(const TQString &name)
+{
+ Language lang = C;
+ Country cntry = AnyCountry;
+
+ uint l = name.length();
+
+ do {
+ if (l < 2)
+ break;
+
+ const TQChar *uc = name.tqunicode();
+ if (l > 2
+ && uc[2] != '_'
+ && uc[2] != '.'
+ && uc[2] != '@')
+ break;
+
+ lang = codeToLanguage(name.mid(0, 2));
+ if (lang == C)
+ break;
+
+ if (l == 2 || uc[2] == '.' || uc[2] == '@')
+ break;
+
+ // we have uc[2] == '_'
+ if (l < 5)
+ break;
+
+ if (l > 5 && uc[5] != '.' && uc[5] != '@')
+ break;
+
+ cntry = codeToCountry(name.mid(3, 2));
+ } while (FALSE);
+
+ d = tqfindLocale(lang, cntry);
+}
+
+/*!
+ Constructs a TQLocale object initialized with the default locale.
+
+ \sa setDefault()
+*/
+
+TQLocale::TQLocale()
+{
+ if (default_d == 0)
+ default_d = system().d;
+
+ d = default_d;
+}
+
+/*!
+ Constructs a TQLocale object with the specified \a language and \a
+ country.
+
+ \list
+ \i If the language/country pair is found in the database, it is used.
+ \i If the language is found but the country is not, or if the country
+ is \c AnyCountry, the language is used with the most
+ appropriate available country (for example, Germany for German),
+ \i If neither the language nor the country are found, TQLocale
+ defaults to the default locale (see setDefault()).
+ \endlist
+
+ The language and country that are actually used can be queried
+ using language() and country().
+
+ \sa setDefault() language() country()
+*/
+
+TQLocale::TQLocale(Language language, Country country)
+{
+ d = tqfindLocale(language, country);
+
+ // If not found, should default to system
+ if (d->languageId() == TQLocale::C && language != TQLocale::C) {
+ if (default_d == 0)
+ default_d = system().d;
+
+ d = default_d;
+ }
+}
+
+/*!
+ Constructs a TQLocale object as a copy of \a other.
+*/
+
+TQLocale::TQLocale(const TQLocale &other)
+{
+ d = other.d;
+}
+
+/*!
+ Assigns \a other to this TQLocale object and returns a reference
+ to this TQLocale object.
+*/
+
+TQLocale &TQLocale::operator=(const TQLocale &other)
+{
+ d = other.d;
+ return *this;
+}
+
+/*!
+ \nonreentrant
+
+ Sets the global default locale to \a locale. These
+ values are used when a TQLocale object is constructed with
+ no arguments. If this function is not called, the system's
+ locale is used.
+
+ \warning In a multithreaded application, the default locale
+ should be set at application startup, before any non-GUI threads
+ are created.
+
+ \sa system() c()
+*/
+
+void TQLocale::setDefault(const TQLocale &locale)
+{
+ default_d = locale.d;
+}
+
+/*!
+ Returns the language of this locale.
+
+ \sa TQLocale()
+*/
+TQLocale::Language TQLocale::language() const
+{
+ return (Language)d->languageId();
+}
+
+/*!
+ Returns the country of this locale.
+
+ \sa TQLocale()
+*/
+TQLocale::Country TQLocale::country() const
+{
+ return (Country)d->countryId();
+}
+
+/*!
+ Returns the language and country of this locale as a
+ string of the form "language_country", where
+ language is a lowercase, two-letter ISO 639 language code,
+ and country is an uppercase, two-letter ISO 3166 country code.
+
+ \sa TQLocale()
+*/
+
+TQString TQLocale::name() const
+{
+ Language l = language();
+
+ TQString result = languageToCode(l);
+
+ if (l == C)
+ return result;
+
+ Country c = country();
+ if (c == AnyCountry)
+ return result;
+
+ result.append('_');
+ result.append(countryToCode(c));
+
+ return result;
+}
+
+/*!
+ Returns a TQString containing the name of \a language.
+*/
+
+TQString TQLocale::languageToString(Language language)
+{
+ if ((uint)language > (uint)TQLocale::LastLanguage)
+ return "Unknown";
+ return language_name_list + language_name_index[(uint)language];
+}
+
+/*!
+ Returns a TQString containing the name of \a country.
+*/
+
+TQString TQLocale::countryToString(Country country)
+{
+ if ((uint)country > (uint)TQLocale::LastCountry)
+ return "Unknown";
+ return country_name_list + country_name_index[(uint)country];
+}
+
+/*!
+ Returns the short int represented by the localized string \a s, or
+ 0 if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toString()
+*/
+
+short TQLocale::toShort(const TQString &s, bool *ok) const
+{
+ TQ_LLONG i = toLongLong(s, ok);
+ if (i < SHRT_MIN || i > SHRT_MAX) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+ return (short) i;
+}
+
+/*!
+ Returns the unsigned short int represented by the localized string
+ \a s, or 0 if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toString()
+*/
+
+ushort TQLocale::toUShort(const TQString &s, bool *ok) const
+{
+ TQ_ULLONG i = toULongLong(s, ok);
+ if (i > USHRT_MAX) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+ return (ushort) i;
+}
+
+/*!
+ Returns the int represented by the localized string \a s, or 0 if
+ the conversion failed.
+
+ If \a ok is not 0, reports failure by setting *ok to false and
+ success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toString()
+*/
+
+int TQLocale::toInt(const TQString &s, bool *ok) const
+{
+ TQ_LLONG i = toLongLong(s, ok);
+ if (i < INT_MIN || i > INT_MAX) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+ return (int) i;
+}
+
+/*!
+ Returns the unsigned int represented by the localized string \a s,
+ or 0 if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toString()
+*/
+
+uint TQLocale::toUInt(const TQString &s, bool *ok) const
+{
+ TQ_ULLONG i = toULongLong(s, ok);
+ if (i > UINT_MAX) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+ return (uint) i;
+}
+
+/*!
+ Returns the long int represented by the localized string \a s, or
+ 0 if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toString()
+*/
+
+TQ_LONG TQLocale::toLong(const TQString &s, bool *ok) const
+{
+ TQ_LLONG i = toLongLong(s, ok);
+ if (i < LONG_MIN || i > LONG_MAX) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+ return (TQ_LONG) i;
+}
+
+/*!
+ Returns the unsigned long int represented by the localized string
+ \a s, or 0 if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toString()
+*/
+
+TQ_ULONG TQLocale::toULong(const TQString &s, bool *ok) const
+{
+ TQ_ULLONG i = toULongLong(s, ok);
+ if (i > ULONG_MAX) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+ return (TQ_ULONG) i;
+}
+
+/*!
+ Returns the long long int represented by the localized string \a
+ s, or 0 if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toString()
+*/
+
+
+TQ_LLONG TQLocale::toLongLong(const TQString &s, bool *ok) const
+{
+ return d->stringToLongLong(s, 0, ok, TQLocalePrivate::ParseGroupSeparators);
+}
+
+/*!
+ Returns the unsigned long long int represented by the localized
+ string \a s, or 0 if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toString()
+*/
+
+
+TQ_ULLONG TQLocale::toULongLong(const TQString &s, bool *ok) const
+{
+ return d->stringToUnsLongLong(s, 0, ok, TQLocalePrivate::ParseGroupSeparators);
+}
+
+/*!
+ Returns the float represented by the localized string \a s, or 0.0
+ if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toString()
+*/
+
+#define TQT_MAX_FLOAT 3.4028234663852886e+38
+
+float TQLocale::toFloat(const TQString &s, bool *ok) const
+{
+ bool myOk;
+ double d = toDouble(s, &myOk);
+ if (!myOk || d > TQT_MAX_FLOAT || d < -TQT_MAX_FLOAT) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0.0;
+ }
+ if (ok != 0)
+ *ok = TRUE;
+ return (float) d;
+}
+
+/*!
+ Returns the double represented by the localized string \a s, or
+ 0.0 if the conversion failed.
+
+ If \a ok is not 0, reports failure by setting
+ *ok to false and success by setting *ok to true.
+
+ Unlike TQString::toDouble(), this function does not fall back to
+ the "C" locale if the string cannot be interpreted in this
+ locale.
+
+ \code
+ bool ok;
+ double d;
+
+ TQLocale c(TQLocale::C);
+ d = c.toDouble( "1234.56", &ok ); // ok == true, d == 1234.56
+ d = c.toDouble( "1,234.56", &ok ); // ok == true, d == 1234.56
+ d = c.toDouble( "1234,56", &ok ); // ok == false
+
+ TQLocale german(TQLocale::German);
+ d = german.toDouble( "1234,56", &ok ); // ok == true, d == 1234.56
+ d = german.toDouble( "1.234,56", &ok ); // ok == true, d == 1234.56
+ d = german.toDouble( "1234.56", &ok ); // ok == false
+
+ d = german.toDouble( "1.234", &ok ); // ok == true, d == 1234.0
+ \endcode
+
+ Notice that the last conversion returns 1234.0, because '.' is the
+ thousands group separator in the German locale.
+
+ This function ignores leading and trailing whitespace.
+
+ \sa toString() TQString::toDouble()
+*/
+
+double TQLocale::toDouble(const TQString &s, bool *ok) const
+{
+ return d->stringToDouble(s, ok, TQLocalePrivate::ParseGroupSeparators);
+}
+
+/*!
+ Returns a localized string representation of \a i.
+
+ \sa toLongLong()
+*/
+
+TQString TQLocale::toString(TQ_LLONG i) const
+{
+ return d->longLongToString(i, -1, 10, -1, TQLocalePrivate::ThousandsGroup);
+}
+
+/*!
+ \overload
+
+ \sa toULongLong()
+*/
+
+TQString TQLocale::toString(TQ_ULLONG i) const
+{
+ return d->unsLongLongToString(i, -1, 10, -1, TQLocalePrivate::ThousandsGroup);
+}
+
+static bool qIsUpper(char c)
+{
+ return c >= 'A' && c <= 'Z';
+}
+
+static char qToLower(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return c - 'A' + 'a';
+ else
+ return c;
+}
+
+/*!
+ \overload
+
+ \a f and \a prec have the same meaning as in TQString::number(double, char, int).
+
+ \sa toDouble()
+*/
+
+TQString TQLocale::toString(double i, char f, int prec) const
+{
+ TQLocalePrivate::DoubleForm form = TQLocalePrivate::DFDecimal;
+ uint flags = 0;
+
+ if (qIsUpper(f))
+ flags = TQLocalePrivate::CapitalEorX;
+ f = qToLower(f);
+
+ switch (f) {
+ case 'f':
+ form = TQLocalePrivate::DFDecimal;
+ break;
+ case 'e':
+ form = TQLocalePrivate::DFExponent;
+ break;
+ case 'g':
+ form = TQLocalePrivate::DFSignificantDigits;
+ break;
+ default:
+ break;
+ }
+
+ flags |= TQLocalePrivate::ThousandsGroup;
+ return d->doubleToString(i, prec, form, -1, flags);
+}
+
+/*!
+ \fn TQLocale TQLocale::c()
+
+ Returns a TQLocale object initialized to the "C" locale.
+
+ \sa system()
+*/
+
+/*!
+ Returns a TQLocale object initialized to the system locale.
+*/
+
+TQLocale TQLocale::system()
+{
+#ifdef TQ_OS_UNIX
+ const char *s = getenv("LC_NUMERIC");
+ if (s == 0)
+ s = getenv("LC_ALL");
+ if (s != 0)
+ return TQLocale(s);
+#endif
+ return TQLocale(TQLocalePrivate::systemLocaleName());
+}
+
+/*!
+\fn TQString TQLocale::toString(short i) const
+
+\overload
+
+\sa toShort()
+*/
+
+/*!
+\fn TQString TQLocale::toString(ushort i) const
+
+\overload
+
+\sa toUShort()
+*/
+
+/*!
+\fn TQString TQLocale::toString(int i) const
+
+\overload
+
+\sa toInt()
+*/
+
+/*!
+\fn TQString TQLocale::toString(uint i) const
+
+\overload
+
+\sa toUInt()
+*/
+
+/*!
+\fn TQString TQLocale::toString(TQ_LONG i) const
+
+\overload
+
+\sa toLong()
+*/
+
+/*!
+\fn TQString TQLocale::toString(TQ_ULONG i) const
+
+\overload
+
+\sa toULong()
+*/
+
+/*!
+\fn TQString TQLocale::toString(float i, char f = 'g', int prec = 6) const
+
+\overload
+
+\a f and \a prec have the same meaning as in TQString::number(double, char, int).
+
+\sa toDouble()
+*/
+
+
+bool TQLocalePrivate::isDigit(TQChar d) const
+{
+ return zero().tqunicode() <= d.tqunicode()
+ && zero().tqunicode() + 10 > d.tqunicode();
+}
+
+static char digitToCLocale(TQChar zero, TQChar d)
+{
+ if (zero.tqunicode() <= d.tqunicode()
+ && zero.tqunicode() + 10 > d.tqunicode())
+ return '0' + d.tqunicode() - zero.tqunicode();
+
+ qWarning("TQLocalePrivate::digitToCLocale(): bad digit: row=%d, cell=%d", d.row(), d.cell());
+ return TQChar(0);
+}
+
+static TQString qulltoa(TQ_ULLONG l, int base, const TQLocalePrivate &locale)
+{
+ TQChar buff[65]; // length of MAX_ULLONG in base 2
+ TQChar *p = buff + 65;
+
+ if (base != 10 || locale.zero().tqunicode() == '0') {
+ while (l != 0) {
+ int c = l % base;
+
+ --p;
+
+ if (c < 10)
+ *p = '0' + c;
+ else
+ *p = c - 10 + 'a';
+
+ l /= base;
+ }
+ }
+ else {
+ while (l != 0) {
+ int c = l % base;
+
+ *(--p) = locale.zero().tqunicode() + c;
+
+ l /= base;
+ }
+ }
+
+ return TQString(p, 65 - (p - buff));
+}
+
+static TQString qlltoa(TQ_LLONG l, int base, const TQLocalePrivate &locale)
+{
+ return qulltoa(l < 0 ? -l : l, base, locale);
+}
+
+enum PrecisionMode {
+ PMDecimalDigits = 0x01,
+ PMSignificantDigits = 0x02,
+ PMChopTrailingZeros = 0x03
+};
+
+static TQString &decimalForm(TQString &digits, int decpt, uint precision,
+ PrecisionMode pm,
+ bool always_show_decpt,
+ bool thousands_group,
+ const TQLocalePrivate &locale)
+{
+ if (decpt < 0) {
+ for (int i = 0; i < -decpt; ++i)
+ digits.prepend(locale.zero());
+ decpt = 0;
+ }
+ else if ((uint)decpt > digits.length()) {
+ for (uint i = digits.length(); i < (uint)decpt; ++i)
+ digits.append(locale.zero());
+ }
+
+ if (pm == PMDecimalDigits) {
+ uint decimal_digits = digits.length() - decpt;
+ for (uint i = decimal_digits; i < precision; ++i)
+ digits.append(locale.zero());
+ }
+ else if (pm == PMSignificantDigits) {
+ for (uint i = digits.length(); i < precision; ++i)
+ digits.append(locale.zero());
+ }
+ else { // pm == PMChopTrailingZeros
+ }
+
+ if (always_show_decpt || (uint)decpt < digits.length())
+ digits.insert(decpt, locale.decimal());
+
+ if (thousands_group) {
+ for (int i = decpt - 3; i > 0; i -= 3)
+ digits.insert(i, locale.group());
+ }
+
+ if (decpt == 0)
+ digits.prepend(locale.zero());
+
+ return digits;
+}
+
+static TQString &exponentForm(TQString &digits, int decpt, uint precision,
+ PrecisionMode pm,
+ bool always_show_decpt,
+ const TQLocalePrivate &locale)
+{
+ int exp = decpt - 1;
+
+ if (pm == PMDecimalDigits) {
+ for (uint i = digits.length(); i < precision + 1; ++i)
+ digits.append(locale.zero());
+ }
+ else if (pm == PMSignificantDigits) {
+ for (uint i = digits.length(); i < precision; ++i)
+ digits.append(locale.zero());
+ }
+ else { // pm == PMChopTrailingZeros
+ }
+
+ if (always_show_decpt || digits.length() > 1)
+ digits.insert(1, locale.decimal());
+
+ digits.append(locale.exponential());
+ digits.append(locale.longLongToString(exp, 2, 10,
+ -1, TQLocalePrivate::AlwaysShowSign));
+
+ return digits;
+}
+
+static bool isZero(double d)
+{
+ uchar *ch = (uchar *)&d;
+ if (ByteOrder == BigEndian) {
+ return !(ch[0] & 0x7F || ch[1] || ch[2] || ch[3] || ch[4] || ch[5] || ch[6] || ch[7]);
+ } else {
+ return !(ch[7] & 0x7F || ch[6] || ch[5] || ch[4] || ch[3] || ch[2] || ch[1] || ch[0]);
+ }
+}
+
+TQString TQLocalePrivate::doubleToString(double d,
+ int precision,
+ DoubleForm form,
+ int width,
+ unsigned flags) const
+{
+ if (precision == -1)
+ precision = 6;
+ if (width == -1)
+ width = 0;
+
+ bool negative = FALSE;
+ bool special_number = FALSE; // nan, +/-inf
+ TQString num_str;
+
+#ifdef TQ_OS_WIN
+ // Detect special numbers (nan, +/-inf)
+ if (qIsInf(d)) {
+ num_str = infinity();
+ special_number = TRUE;
+ negative = d < 0;
+ } else if (qIsNan(d)) {
+ num_str = nan();
+ special_number = TRUE;
+ }
+#else
+ // Comparing directly to INFINITY gives weird results on some systems.
+ double tmp_infinity = INFINITY;
+
+ // Detect special numbers (nan, +/-inf)
+ if (d == tmp_infinity || d == -tmp_infinity) {
+ num_str = infinity();
+ special_number = TRUE;
+ negative = d < 0;
+ } else if (qIsNan(d)) {
+ num_str = nan();
+ special_number = TRUE;
+ }
+#endif
+
+ // Handle normal numbers
+ if (!special_number) {
+ int decpt, sign;
+ TQString digits;
+
+#ifdef TQT_TQLOCALE_USES_FCVT
+#ifdef TQT_THREAD_SUPPORT
+ static bool dummy_for_mutex;
+ TQMutex *fcvt_mutex = tqt_global_mutexpool ? tqt_global_mutexpool->get( &dummy_for_mutex ) : 0;
+# define FCVT_LOCK if (fcvt_mutex) fcvt_mutex->lock()
+# define FCVT_UNLOCK if (fcvt_mutex) fcvt_mutex->unlock()
+#else
+# define FCVT_LOCK
+# define FCVT_UNLOCK
+#endif
+ if (form == DFDecimal) {
+ FCVT_LOCK;
+ digits = fcvt(d, precision, &decpt, &sign);
+ FCVT_UNLOCK;
+ } else {
+ int pr = precision;
+ if (form == DFExponent)
+ ++pr;
+ else if (form == DFSignificantDigits && pr == 0)
+ pr = 1;
+ FCVT_LOCK;
+ digits = ecvt(d, pr, &decpt, &sign);
+ FCVT_UNLOCK;
+
+ // Chop trailing zeros
+ if (digits.length() > 0) {
+ int last_nonzero_idx = digits.length() - 1;
+ while (last_nonzero_idx > 0
+ && digits.tqunicode()[last_nonzero_idx] == '0')
+ --last_nonzero_idx;
+ digits.truncate(last_nonzero_idx + 1);
+ }
+
+ }
+
+#else
+ int mode;
+ if (form == DFDecimal)
+ mode = 3;
+ else
+ mode = 2;
+
+ /* This next bit is a bit quirky. In DFExponent form, the precision
+ is the number of digits after decpt. So that would suggest using
+ mode=3 for qdtoa. But qdtoa behaves strangely when mode=3 and
+ precision=0. So we get around this by using mode=2 and reasoning
+ that we want precision+1 significant digits, since the decimal
+ point in this mode is always after the first digit. */
+ int pr = precision;
+ if (form == DFExponent)
+ ++pr;
+
+ char *rve = 0;
+ char *buff = 0;
+ digits = qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff);
+ if (buff != 0)
+ free(buff);
+#endif // TQT_TQLOCALE_USES_FCVT
+
+ if (zero().tqunicode() != '0') {
+ for (uint i = 0; i < digits.length(); ++i)
+ digits.ref(i).unicode() += zero().tqunicode() - '0';
+ }
+
+ bool always_show_decpt = flags & Alternate;
+ switch (form) {
+ case DFExponent: {
+ num_str = exponentForm(digits, decpt, precision, PMDecimalDigits,
+ always_show_decpt, *this);
+ break;
+ }
+ case DFDecimal: {
+ num_str = decimalForm(digits, decpt, precision, PMDecimalDigits,
+ always_show_decpt, flags & ThousandsGroup,
+ *this);
+ break;
+ }
+ case DFSignificantDigits: {
+ PrecisionMode mode = (flags & Alternate) ?
+ PMSignificantDigits : PMChopTrailingZeros;
+
+ if (decpt != (int)digits.length() && (decpt <= -4 || decpt > (int)precision))
+ num_str = exponentForm(digits, decpt, precision, mode,
+ always_show_decpt, *this);
+ else
+ num_str = decimalForm(digits, decpt, precision, mode,
+ always_show_decpt, flags & ThousandsGroup,
+ *this);
+ break;
+ }
+ }
+
+ negative = sign != 0 && !isZero(d);
+ }
+
+ // pad with zeros. LeftAdjusted overrides this flag). Also, we don't
+ // pad special numbers
+ if (flags & TQLocalePrivate::ZeroPadded
+ && !(flags & TQLocalePrivate::LeftAdjusted)
+ && !special_number) {
+ int num_pad_chars = width - (int)num_str.length();
+ // leave space for the sign
+ if (negative
+ || flags & TQLocalePrivate::AlwaysShowSign
+ || flags & TQLocalePrivate::BlankBeforePositive)
+ --num_pad_chars;
+
+ for (int i = 0; i < num_pad_chars; ++i)
+ num_str.prepend(zero());
+ }
+
+ // add sign
+ if (negative)
+ num_str.prepend(minus());
+ else if (flags & TQLocalePrivate::AlwaysShowSign)
+ num_str.prepend(plus());
+ else if (flags & TQLocalePrivate::BlankBeforePositive)
+ num_str.prepend(' ');
+
+ if (flags & TQLocalePrivate::CapitalEorX)
+ num_str = num_str.upper();
+
+ return num_str;
+}
+
+TQString TQLocalePrivate::longLongToString(TQ_LLONG l, int precision,
+ int base, int width,
+ unsigned flags) const
+{
+ bool precision_not_specified = FALSE;
+ if (precision == -1) {
+ precision_not_specified = TRUE;
+ precision = 1;
+ }
+
+ bool negative = l < 0;
+ if (base != 10) {
+ // these are not suported by sprintf for octal and hex
+ flags &= ~AlwaysShowSign;
+ flags &= ~BlankBeforePositive;
+ negative = FALSE; // neither are negative numbers
+ }
+
+ TQString num_str;
+ if (base == 10)
+ num_str = qlltoa(l, base, *this);
+ else
+ num_str = qulltoa(l, base, *this);
+
+ uint cnt_thousand_sep = 0;
+ if (flags & ThousandsGroup && base == 10) {
+ for (int i = (int)num_str.length() - 3; i > 0; i -= 3) {
+ num_str.insert(i, group());
+ ++cnt_thousand_sep;
+ }
+ }
+
+ for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)
+ num_str.prepend(base == 10 ? zero() : TQChar('0'));
+
+ if (flags & Alternate
+ && base == 8
+ && (num_str.isEmpty()
+ || num_str[0].unicode() != '0'))
+ num_str.prepend('0');
+
+ // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
+ // when precision is not specified in the format string
+ bool zero_padded = flags & ZeroPadded
+ && !(flags & LeftAdjusted)
+ && precision_not_specified;
+
+ if (zero_padded) {
+ int num_pad_chars = width - (int)num_str.length();
+
+ // leave space for the sign
+ if (negative
+ || flags & AlwaysShowSign
+ || flags & BlankBeforePositive)
+ --num_pad_chars;
+
+ // leave space for optional '0x' in hex form
+ if (base == 16
+ && flags & Alternate
+ && l != 0)
+ num_pad_chars -= 2;
+
+ for (int i = 0; i < num_pad_chars; ++i)
+ num_str.prepend(base == 10 ? zero() : TQChar('0'));
+ }
+
+ if (base == 16
+ && flags & Alternate
+ && l != 0)
+ num_str.prepend("0x");
+
+ // add sign
+ if (negative)
+ num_str.prepend(minus());
+ else if (flags & AlwaysShowSign)
+ num_str.prepend(base == 10 ? plus() : TQChar('+'));
+ else if (flags & BlankBeforePositive)
+ num_str.prepend(' ');
+
+ if (flags & CapitalEorX)
+ num_str = num_str.upper();
+
+ return num_str;
+}
+
+TQString TQLocalePrivate::unsLongLongToString(TQ_ULLONG l, int precision,
+ int base, int width,
+ unsigned flags) const
+{
+ bool precision_not_specified = FALSE;
+ if (precision == -1) {
+ precision_not_specified = TRUE;
+ precision = 1;
+ }
+
+ TQString num_str = qulltoa(l, base, *this);
+
+ uint cnt_thousand_sep = 0;
+ if (flags & ThousandsGroup && base == 10) {
+ for (int i = (int)num_str.length() - 3; i > 0; i -=3) {
+ num_str.insert(i, group());
+ ++cnt_thousand_sep;
+ }
+ }
+
+ for (int i = num_str.length()/* - cnt_thousand_sep*/; i < precision; ++i)
+ num_str.prepend(base == 10 ? zero() : TQChar('0'));
+
+ if (flags & Alternate
+ && base == 8
+ && (num_str.isEmpty()
+ || num_str[0].unicode() != '0'))
+ num_str.prepend('0');
+
+ // LeftAdjusted overrides this flag ZeroPadded. sprintf only padds
+ // when precision is not specified in the format string
+ bool zero_padded = flags & ZeroPadded
+ && !(flags & LeftAdjusted)
+ && precision_not_specified;
+
+ if (zero_padded) {
+ int num_pad_chars = width - (int)num_str.length();
+
+ // leave space for optional '0x' in hex form
+ if (base == 16
+ && flags & Alternate
+ && l != 0)
+ num_pad_chars -= 2;
+
+ for (int i = 0; i < num_pad_chars; ++i)
+ num_str.prepend(base == 10 ? zero() : TQChar('0'));
+ }
+
+ if (base == 16
+ && flags & Alternate
+ && l != 0)
+ num_str.prepend("0x");
+
+ if (flags & CapitalEorX)
+ num_str = num_str.upper();
+
+ return num_str;
+}
+
+static inline bool isLatin1Digit(const TQChar &c)
+{
+ return c.tqunicode() >= '0' && c.tqunicode() <= '9';
+}
+
+// Removes thousand-group separators, ie. the ',' in "1,234,567.89e-5"
+bool TQLocalePrivate::removeGroupSeparators(TQString &num_str) const
+{
+ int group_cnt = 0; // counts number of group chars
+ int decpt_idx = -1;
+
+ // Find the decimal point and check if there are any group chars
+ uint i = 0;
+ for (; i < num_str.length(); ++i) {
+ TQChar c = num_str.tqunicode()[i];
+
+ if (c.tqunicode() == ',') {
+ // check that there are digits before and after the separator
+ if (i == 0 || !isLatin1Digit(num_str.tqunicode()[i - 1]))
+ return FALSE;
+ if (i == num_str.length() + 1 || !isLatin1Digit(num_str.tqunicode()[i + 1]))
+ return FALSE;
+ ++group_cnt;
+ }
+ else if (c.tqunicode() == '.') {
+ // Fail if more than one decimal points
+ if (decpt_idx != -1)
+ return FALSE;
+ decpt_idx = i;
+ } else if (c.tqunicode() == 'e' || c.tqunicode() == 'E') {
+ // an 'e' or 'E' - if we have not encountered a decimal
+ // point, this is where it "is".
+ if (decpt_idx == -1)
+ decpt_idx = i;
+ }
+ }
+
+ // If no group chars, we're done
+ if (group_cnt == 0)
+ return TRUE;
+
+ // No decimal point means that it "is" at the end of the string
+ if (decpt_idx == -1)
+ decpt_idx = num_str.length();
+
+ i = 0;
+ while (i < num_str.length() && group_cnt > 0) {
+ TQChar c = num_str.tqunicode()[i];
+
+ if (c.tqunicode() == ',') {
+ // Don't allow group chars after the decimal point
+ if ((int)i > decpt_idx)
+ return FALSE;
+
+ // Check that it is placed correctly relative to the decpt
+ if ((decpt_idx - i) % 4 != 0)
+ return FALSE;
+
+ // Remove it
+ num_str.remove(i, 1);
+
+ --group_cnt;
+ --decpt_idx; // adjust decpt_idx
+ } else {
+ // Check that we are not missing a separator
+ if ((int)i < decpt_idx && (decpt_idx - i) % 4 == 0)
+ return FALSE;
+ ++i;
+ }
+ }
+
+ return TRUE;
+}
+
+static void stripWhiteSpaceInPlace(TQString &s)
+{
+ uint i = 0;
+ while (i < s.length() && s.tqunicode()[i].isSpace())
+ ++i;
+ if (i > 0)
+ s.remove(0, i);
+
+ i = s.length();
+
+ if (i == 0)
+ return;
+ --i;
+ while (i > 0 && s.tqunicode()[i].isSpace())
+ --i;
+ if (i + 1 < s.length())
+ s.truncate(i + 1);
+}
+
+/*
+ Converts a number in locale to its representation in the C locale.
+ Only has to guarantee that a string that is a correct representation of
+ a number will be converted. If junk is passed in, junk will be passed
+ out and the error will be detected during the actual conversion to a
+ number. We can't detect junk here, since we don't even know the base
+ of the number.
+*/
+bool TQLocalePrivate::numberToCLocale(TQString &l_num,
+ GroupSeparatorMode group_sep_mode) const
+{
+ stripWhiteSpaceInPlace(l_num);
+
+ if (l_num.isEmpty())
+ return FALSE;
+
+ for (uint idx = 0; idx < l_num.length(); ++idx) {
+ TQChar c = l_num.ref(idx);
+
+ if (isDigit(c))
+ c = digitToCLocale(zero(), c);
+ else if (c == plus())
+ c = '+';
+ else if (c == minus())
+ c = '-';
+ else if (c == decimal())
+ c = '.';
+ else if (c == group())
+ c = ',';
+ // In several languages group() is the char 0xA0, which looks like a space.
+ // People use a regular space instead of it and complain it doesn't work.
+ else if (group().tqunicode() == 0xA0 && c.tqunicode() == ' ')
+ c = ',';
+ else if (c == exponential() || c == exponential().upper())
+ c = 'e';
+ else if (c == list())
+ c = ';';
+ else if (c == percent())
+ c = '%';
+ else if (c.tqunicode() >= 'A' && c.tqunicode() <= 'Z')
+ c = c.lower();
+ else if (c.tqunicode() >= 'a' && c.tqunicode() <= 'z')
+ ; // do nothing
+ else
+ return FALSE;
+ }
+
+ if (group_sep_mode == ParseGroupSeparators
+ && !removeGroupSeparators(l_num))
+ return FALSE;
+
+ return TRUE;
+}
+
+double TQLocalePrivate::stringToDouble(TQString num,
+ bool *ok,
+ GroupSeparatorMode group_sep_mode) const
+{
+ if (!numberToCLocale(num, group_sep_mode)) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0.0;
+ }
+
+ if (ok != 0)
+ *ok = TRUE;
+
+ if (num == "nan")
+ return NAN;
+
+ if (num == "+inf"
+ || num == "inf")
+ return INFINITY;
+
+ if (num == "-inf")
+ return -INFINITY;
+
+ bool _ok;
+ const char *num_buff = num.latin1();
+
+#ifdef TQT_TQLOCALE_USES_FCVT
+ char *endptr;
+ double d = strtod(num_buff, &endptr);
+ _ok = TRUE;
+#else
+ const char *endptr;
+ double d = qstrtod(num_buff, &endptr, &_ok);
+#endif
+
+ if (!_ok || *endptr != '\0') {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0.0;
+ }
+ else
+ return d;
+}
+
+TQ_LLONG TQLocalePrivate::stringToLongLong(TQString num, int base,
+ bool *ok,
+ GroupSeparatorMode group_sep_mode) const
+{
+ if (!numberToCLocale(num, group_sep_mode)) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+
+ bool _ok;
+ const char *endptr;
+ const char *num_buff = num.latin1();
+ TQ_LLONG l = qstrtoll(num_buff, &endptr, base, &_ok);
+
+ if (!_ok || *endptr != '\0') {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+
+ if (ok != 0)
+ *ok = TRUE;
+ return l;
+}
+
+TQ_ULLONG TQLocalePrivate::stringToUnsLongLong(TQString num, int base,
+ bool *ok,
+ GroupSeparatorMode group_sep_mode) const
+{
+ if (!numberToCLocale(num, group_sep_mode)) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+
+ bool _ok;
+ const char *endptr;
+ const char *num_buff = num.latin1();
+ TQ_ULLONG l = qstrtoull(num_buff, &endptr, base, &_ok);
+
+ if (!_ok || *endptr != '\0') {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+
+ if (ok != 0)
+ *ok = TRUE;
+ return l;
+}
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSETQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+// static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93";
+// "$FreeBSD: src/lib/libc/stdlib/strtoull.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $";
+
+/*
+ * Convert a string to an TQ_ULLONG integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+static TQ_ULLONG qstrtoull(const char *nptr, const char **endptr, register int base, bool *ok)
+{
+ register const char *s = nptr;
+ register TQ_ULLONG acc;
+ register unsigned char c;
+ register TQ_ULLONG qbase, cutoff;
+ register int neg, any, cutlim;
+
+ if (ok != 0)
+ *ok = TRUE;
+
+ /*
+ * See strtoq for comments as to the logic used.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ if (ok != 0)
+ *ok = FALSE;
+ if (endptr != 0)
+ *endptr = s - 1;
+ return 0;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+ qbase = (unsigned)base;
+ cutoff = (TQ_ULLONG)ULLONG_MAX / qbase;
+ cutlim = (TQ_ULLONG)ULLONG_MAX % qbase;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= qbase;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = ULLONG_MAX;
+ if (ok != 0)
+ *ok = FALSE;
+ }
+ else if (neg)
+ acc = (~acc) + 1;
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
+
+
+// "$FreeBSD: src/lib/libc/stdlib/strtoll.c,v 1.5.2.1 2001/03/02 09:45:20 obrien Exp $";
+
+
+/*
+ * Convert a string to a TQ_LLONG integer.
+ *
+ * Ignores `locale' stuff. Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+static TQ_LLONG qstrtoll(const char *nptr, const char **endptr, register int base, bool *ok)
+{
+ register const char *s;
+ register TQ_ULLONG acc;
+ register unsigned char c;
+ register TQ_ULLONG qbase, cutoff;
+ register int neg, any, cutlim;
+
+ if (ok != 0)
+ *ok = TRUE;
+
+ /*
+ * Skip white space and pick up leading +/- sign if any.
+ * If base is 0, allow 0x for hex and 0 for octal, else
+ * assume decimal; if base is already 16, allow 0x.
+ */
+ s = nptr;
+ do {
+ c = *s++;
+ } while (isspace(c));
+ if (c == '-') {
+ neg = 1;
+ c = *s++;
+ } else {
+ neg = 0;
+ if (c == '+')
+ c = *s++;
+ }
+ if ((base == 0 || base == 16) &&
+ c == '0' && (*s == 'x' || *s == 'X')) {
+ c = s[1];
+ s += 2;
+ base = 16;
+ }
+ if (base == 0)
+ base = c == '0' ? 8 : 10;
+
+ /*
+ * Compute the cutoff value between legal numbers and illegal
+ * numbers. That is the largest legal value, divided by the
+ * base. An input number that is greater than this value, if
+ * followed by a legal input character, is too big. One that
+ * is equal to this value may be valid or not; the limit
+ * between valid and invalid numbers is then based on the last
+ * digit. For instance, if the range for quads is
+ * [-9223372036854775808..9223372036854775807] and the input base
+ * is 10, cutoff will be set to 922337203685477580 and cutlim to
+ * either 7 (neg==0) or 8 (neg==1), meaning that if we have
+ * accumulated a value > 922337203685477580, or equal but the
+ * next digit is > 7 (or 8), the number is too big, and we will
+ * return a range error.
+ *
+ * Set any if any `digits' consumed; make it negative to indicate
+ * overflow.
+ */
+ qbase = (unsigned)base;
+ cutoff = neg ? (TQ_ULLONG)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX
+ : LLONG_MAX;
+ cutlim = cutoff % qbase;
+ cutoff /= qbase;
+ for (acc = 0, any = 0;; c = *s++) {
+ if (!isascii(c))
+ break;
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+ any = -1;
+ else {
+ any = 1;
+ acc *= qbase;
+ acc += c;
+ }
+ }
+ if (any < 0) {
+ acc = neg ? LLONG_MIN : LLONG_MAX;
+ if (ok != 0)
+ *ok = FALSE;
+ } else if (neg) {
+ acc = (~acc) + 1;
+ }
+ if (endptr != 0)
+ *endptr = (char *)(any ? s - 1 : nptr);
+ return (acc);
+}
+
+#ifndef TQT_TQLOCALE_USES_FCVT
+
+/* From: NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp */
+/* $FreeBSD: src/lib/libc/stdlib/netbsd_strtod.c,v 1.2.2.2 2001/03/02 17:14:15 tegge Exp $ */
+
+/* Please send bug reports to
+ David M. Gay
+ AT&T Bell Laboratories, Room 2C-463
+ 600 Mountain Avenue
+ Murray Hill, NJ 07974-2070
+ U.S.A.
+ dmg@research.att.com or research!dmg
+ */
+
+/* strtod for IEEE-, VAX-, and IBM-arithmetic machines.
+ *
+ * This strtod returns a nearest machine number to the input decimal
+ * string (or sets errno to ERANGE). With IEEE arithmetic, ties are
+ * broken by the IEEE round-even rule. Otherwise ties are broken by
+ * biased rounding (add half and chop).
+ *
+ * Inspired loosely by William D. Clinger's paper "How to Read Floating
+ * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ *
+ * 1. We only require IEEE, IBM, or VAX double-precision
+ * arithmetic (not IEEE double-extended).
+ * 2. We get by with floating-point arithmetic in a case that
+ * Clinger missed -- when we're computing d * 10^n
+ * for a small integer d and the integer n is not too
+ * much larger than 22 (the maximum integer k for which
+ * we can represent 10^k exactly), we may be able to
+ * compute (d*10^k) * 10^(e-k) with just one roundoff.
+ * 3. Rather than a bit-at-a-time adjustment of the binary
+ * result in the hard case, we use floating-point
+ * arithmetic to determine the adjustment to within
+ * one bit; only in really hard cases do we need to
+ * compute a second residual.
+ * 4. Because of 3., we don't need a large table of powers of 10
+ * for ten-to-e (just some small tables, e.g. of 10^k
+ * for 0 <= k <= 22).
+ */
+
+/*
+ * #define IEEE_LITTLE_ENDIAN for IEEE-arithmetic machines where the least
+ * significant byte has the lowest address.
+ * #define IEEE_BIG_ENDIAN for IEEE-arithmetic machines where the most
+ * significant byte has the lowest address.
+ * #define Long int on machines with 32-bit ints and 64-bit longs.
+ * #define Sudden_Underflow for IEEE-format machines without gradual
+ * underflow (i.e., that flush to zero on underflow).
+ * #define IBM for IBM mainframe-style floating-point arithmetic.
+ * #define VAX for VAX-style floating-point arithmetic.
+ * #define Unsigned_Shifts if >> does treats its left operand as unsigned.
+ * #define No_leftright to omit left-right logic in fast floating-point
+ * computation of dtoa.
+ * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3.
+ * #define RND_PRODTQUOT to use rnd_prod and rnd_quot (assembly routines
+ * that use extended-precision instructions to compute rounded
+ * products and quotients) with IBM.
+ * #define ROUND_BIASED for IEEE-format with biased rounding.
+ * #define Inaccurate_Divide for IEEE-format with correctly rounded
+ * products but inaccurate quotients, e.g., for Intel i860.
+ * #define Just_16 to store 16 bits per 32-bit Long when doing high-precision
+ * integer arithmetic. Whether this speeds things up or slows things
+ * down depends on the machine and the number being converted.
+ * #define KR_headers for old-style C function headers.
+ * #define Bad_float_h if your system lacks a float.h or if it does not
+ * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP,
+ * FLT_RADIX, FLT_ROUNDS, and DBL_MAX.
+ * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n)
+ * if memory is available and otherwise does something you deem
+ * appropriate. If MALLOC is undefined, malloc will be invoked
+ * directly -- and assumed always to succeed.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: strtod.c,v 1.26 1998/02/03 18:44:21 perry Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+/*
+#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
+ defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
+ defined(__powerpc__) || defined(TQ_OS_WIN) || defined(TQ_OS_DARWIN) || defined(TQ_OS_MACX) || \
+ defined(mips) || defined(TQ_OS_AIX) || defined(TQ_OS_SOLARIS)
+# define IEEE_BIG_OR_LITTLE_ENDIAN 1
+#endif
+*/
+
+// *All* of our architectures have IEEE arithmetic, don't they?
+#define IEEE_BIG_OR_LITTLE_ENDIAN 1
+
+#ifdef __arm32__
+/*
+ * Although the CPU is little endian the FP has different
+ * byte and word endianness. The byte order is still little endian
+ * but the word order is big endian.
+ */
+#define IEEE_BIG_OR_LITTLE_ENDIAN
+#endif
+
+#ifdef vax
+#define VAX
+#endif
+
+#define Long TQ_INT32
+#define ULong TQ_UINT32
+
+#define MALLOC malloc
+#define CONST const
+
+#ifdef BSD_TQDTOA_DEBUG
+#include <stdio.h>
+#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
+#endif
+
+#ifdef Unsigned_Shifts
+#define Sign_Extend(a,b) if (b < 0) a |= 0xffff0000;
+#else
+#define Sign_Extend(a,b) /*no-op*/
+#endif
+
+#if (defined(IEEE_BIG_OR_LITTLE_ENDIAN) + defined(VAX) + defined(IBM)) != 1
+#error Exactly one of IEEE_BIG_OR_LITTLE_ENDIAN, VAX, or IBM should be defined.
+#endif
+
+inline ULong getWord0(const NEEDS_VOLATILE double x)
+{
+ const NEEDS_VOLATILE uchar *ptr = reinterpret_cast<const NEEDS_VOLATILE uchar *>(&x);
+ if (ByteOrder == BigEndian) {
+ return (ptr[0]<<24) + (ptr[1]<<16) + (ptr[2]<<8) + ptr[3];
+ } else {
+ return (ptr[7]<<24) + (ptr[6]<<16) + (ptr[5]<<8) + ptr[4];
+ }
+}
+
+inline void setWord0(NEEDS_VOLATILE double *x, ULong l)
+{
+ NEEDS_VOLATILE uchar *ptr = reinterpret_cast<NEEDS_VOLATILE uchar *>(x);
+ if (ByteOrder == BigEndian) {
+ ptr[0] = (uchar)(l>>24);
+ ptr[1] = (uchar)(l>>16);
+ ptr[2] = (uchar)(l>>8);
+ ptr[3] = (uchar)l;
+ } else {
+ ptr[7] = (uchar)(l>>24);
+ ptr[6] = (uchar)(l>>16);
+ ptr[5] = (uchar)(l>>8);
+ ptr[4] = (uchar)l;
+ }
+}
+
+inline ULong getWord1(const NEEDS_VOLATILE double x)
+{
+ const NEEDS_VOLATILE uchar *ptr = reinterpret_cast<const NEEDS_VOLATILE uchar *>(&x);
+ if (ByteOrder == BigEndian) {
+ return (ptr[4]<<24) + (ptr[5]<<16) + (ptr[6]<<8) + ptr[7];
+ } else {
+ return (ptr[3]<<24) + (ptr[2]<<16) + (ptr[1]<<8) + ptr[0];
+ }
+}
+inline void setWord1(NEEDS_VOLATILE double *x, ULong l)
+{
+ NEEDS_VOLATILE uchar *ptr = reinterpret_cast<uchar NEEDS_VOLATILE *>(x);
+ if (ByteOrder == BigEndian) {
+ ptr[4] = (uchar)(l>>24);
+ ptr[5] = (uchar)(l>>16);
+ ptr[6] = (uchar)(l>>8);
+ ptr[7] = (uchar)l;
+ } else {
+ ptr[3] = (uchar)(l>>24);
+ ptr[2] = (uchar)(l>>16);
+ ptr[1] = (uchar)(l>>8);
+ ptr[0] = (uchar)l;
+ }
+}
+
+static inline void Storeinc(ULong *&a, const ULong &b, const ULong &c)
+{
+
+ *a = (((unsigned short)b) << 16) | ((unsigned short)c);
+ ++a;
+}
+
+/* #define P DBL_MANT_DIG */
+/* Ten_pmax = floor(P*log(2)/log(5)) */
+/* Bletch = (highest power of 2 < DBL_MAX_10_EXP) / 16 */
+/* Quick_max = floor((P-1)*log(FLT_RADIX)/log(10) - 1) */
+/* Int_max = floor(P*log(FLT_RADIX)/log(10) - 1) */
+
+#if defined(IEEE_BIG_OR_LITTLE_ENDIAN)
+#define Exp_shift 20
+#define Exp_shift1 20
+#define Exp_msk1 0x100000
+#define Exp_msk11 0x100000
+#define Exp_mask 0x7ff00000
+#define P 53
+#define Bias 1023
+#define IEEE_Arith
+#define Emin (-1022)
+#define Exp_1 0x3ff00000
+#define Exp_11 0x3ff00000
+#define Ebits 11
+#define Frac_mask 0xfffff
+#define Frac_mask1 0xfffff
+#define Ten_pmax 22
+#define Bletch 0x10
+#define Bndry_mask 0xfffff
+#define Bndry_mask1 0xfffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 1
+#define Tiny0 0
+#define Tiny1 1
+#define Quick_max 14
+#define Int_max 14
+#define Infinite(x) (getWord0(x) == 0x7ff00000) /* sufficient test for here */
+#else
+#undef Sudden_Underflow
+#define Sudden_Underflow
+#ifdef IBM
+#define Exp_shift 24
+#define Exp_shift1 24
+#define Exp_msk1 0x1000000
+#define Exp_msk11 0x1000000
+#define Exp_mask 0x7f000000
+#define P 14
+#define Bias 65
+#define Exp_1 0x41000000
+#define Exp_11 0x41000000
+#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */
+#define Frac_mask 0xffffff
+#define Frac_mask1 0xffffff
+#define Bletch 4
+#define Ten_pmax 22
+#define Bndry_mask 0xefffff
+#define Bndry_mask1 0xffffff
+#define LSB 1
+#define Sign_bit 0x80000000
+#define Log2P 4
+#define Tiny0 0x100000
+#define Tiny1 0
+#define Quick_max 14
+#define Int_max 15
+#else /* VAX */
+#define Exp_shift 23
+#define Exp_shift1 7
+#define Exp_msk1 0x80
+#define Exp_msk11 0x800000
+#define Exp_mask 0x7f80
+#define P 56
+#define Bias 129
+#define Exp_1 0x40800000
+#define Exp_11 0x4080
+#define Ebits 8
+#define Frac_mask 0x7fffff
+#define Frac_mask1 0xffff007f
+#define Ten_pmax 24
+#define Bletch 2
+#define Bndry_mask 0xffff007f
+#define Bndry_mask1 0xffff007f
+#define LSB 0x10000
+#define Sign_bit 0x8000
+#define Log2P 1
+#define Tiny0 0x80
+#define Tiny1 0
+#define Quick_max 15
+#define Int_max 15
+#endif
+#endif
+
+#ifndef IEEE_Arith
+#define ROUND_BIASED
+#endif
+
+#ifdef RND_PRODTQUOT
+#define rounded_product(a,b) a = rnd_prod(a, b)
+#define rounded_quotient(a,b) a = rnd_quot(a, b)
+extern double rnd_prod(double, double), rnd_quot(double, double);
+#else
+#define rounded_product(a,b) a *= b
+#define rounded_quotient(a,b) a /= b
+#endif
+
+#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
+#define Big1 0xffffffff
+
+#ifndef Just_16
+/* When Pack_32 is not defined, we store 16 bits per 32-bit Long.
+ * This makes some inner loops simpler and sometimes saves work
+ * during multiplications, but it often seems to make things slightly
+ * slower. Hence the default is now to store 32 bits per Long.
+ */
+#ifndef Pack_32
+#define Pack_32
+#endif
+#endif
+
+#define Kmax 15
+
+struct
+Bigint {
+ struct Bigint *next;
+ int k, maxwds, sign, wds;
+ ULong x[1];
+};
+
+ typedef struct Bigint Bigint;
+
+static Bigint *Balloc(int k)
+{
+ int x;
+ Bigint *rv;
+
+ x = 1 << k;
+ rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long));
+ rv->k = k;
+ rv->maxwds = x;
+ rv->sign = rv->wds = 0;
+ return rv;
+}
+
+static void Bfree(Bigint *v)
+{
+ free(v);
+}
+
+#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
+y->wds*sizeof(Long) + 2*sizeof(int))
+
+/* multiply by m and add a */
+static Bigint *multadd(Bigint *b, int m, int a)
+{
+ int i, wds;
+ ULong *x, y;
+#ifdef Pack_32
+ ULong xi, z;
+#endif
+ Bigint *b1;
+
+ wds = b->wds;
+ x = b->x;
+ i = 0;
+ do {
+#ifdef Pack_32
+ xi = *x;
+ y = (xi & 0xffff) * m + a;
+ z = (xi >> 16) * m + (y >> 16);
+ a = (int)(z >> 16);
+ *x++ = (z << 16) + (y & 0xffff);
+#else
+ y = *x * m + a;
+ a = (int)(y >> 16);
+ *x++ = y & 0xffff;
+#endif
+ }
+ while(++i < wds);
+ if (a) {
+ if (wds >= b->maxwds) {
+ b1 = Balloc(b->k+1);
+ Bcopy(b1, b);
+ Bfree(b);
+ b = b1;
+ }
+ b->x[wds++] = a;
+ b->wds = wds;
+ }
+ return b;
+}
+
+static Bigint *s2b(CONST char *s, int nd0, int nd, ULong y9)
+{
+ Bigint *b;
+ int i, k;
+ Long x, y;
+
+ x = (nd + 8) / 9;
+ for(k = 0, y = 1; x > y; y <<= 1, k++) ;
+#ifdef Pack_32
+ b = Balloc(k);
+ b->x[0] = y9;
+ b->wds = 1;
+#else
+ b = Balloc(k+1);
+ b->x[0] = y9 & 0xffff;
+ b->wds = (b->x[1] = y9 >> 16) ? 2 : 1;
+#endif
+
+ i = 9;
+ if (9 < nd0) {
+ s += 9;
+ do b = multadd(b, 10, *s++ - '0');
+ while(++i < nd0);
+ s++;
+ }
+ else
+ s += 10;
+ for(; i < nd; i++)
+ b = multadd(b, 10, *s++ - '0');
+ return b;
+}
+
+static int hi0bits(ULong x)
+{
+ int k = 0;
+
+ if (!(x & 0xffff0000)) {
+ k = 16;
+ x <<= 16;
+ }
+ if (!(x & 0xff000000)) {
+ k += 8;
+ x <<= 8;
+ }
+ if (!(x & 0xf0000000)) {
+ k += 4;
+ x <<= 4;
+ }
+ if (!(x & 0xc0000000)) {
+ k += 2;
+ x <<= 2;
+ }
+ if (!(x & 0x80000000)) {
+ k++;
+ if (!(x & 0x40000000))
+ return 32;
+ }
+ return k;
+}
+
+static int lo0bits(ULong *y)
+{
+ int k;
+ ULong x = *y;
+
+ if (x & 7) {
+ if (x & 1)
+ return 0;
+ if (x & 2) {
+ *y = x >> 1;
+ return 1;
+ }
+ *y = x >> 2;
+ return 2;
+ }
+ k = 0;
+ if (!(x & 0xffff)) {
+ k = 16;
+ x >>= 16;
+ }
+ if (!(x & 0xff)) {
+ k += 8;
+ x >>= 8;
+ }
+ if (!(x & 0xf)) {
+ k += 4;
+ x >>= 4;
+ }
+ if (!(x & 0x3)) {
+ k += 2;
+ x >>= 2;
+ }
+ if (!(x & 1)) {
+ k++;
+ x >>= 1;
+ if (!x & 1)
+ return 32;
+ }
+ *y = x;
+ return k;
+}
+
+static Bigint *i2b(int i)
+{
+ Bigint *b;
+
+ b = Balloc(1);
+ b->x[0] = i;
+ b->wds = 1;
+ return b;
+}
+
+static Bigint *mult(Bigint *a, Bigint *b)
+{
+ Bigint *c;
+ int k, wa, wb, wc;
+ ULong carry, y, z;
+ ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0;
+#ifdef Pack_32
+ ULong z2;
+#endif
+
+ if (a->wds < b->wds) {
+ c = a;
+ a = b;
+ b = c;
+ }
+ k = a->k;
+ wa = a->wds;
+ wb = b->wds;
+ wc = wa + wb;
+ if (wc > a->maxwds)
+ k++;
+ c = Balloc(k);
+ for(x = c->x, xa = x + wc; x < xa; x++)
+ *x = 0;
+ xa = a->x;
+ xae = xa + wa;
+ xb = b->x;
+ xbe = xb + wb;
+ xc0 = c->x;
+#ifdef Pack_32
+ for(; xb < xbe; xb++, xc0++) {
+ if ((y = *xb & 0xffff) != 0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = (*x & 0xffff) * y + (*xc & 0xffff) + carry;
+ carry = z >> 16;
+ z2 = (*x++ >> 16) * y + (*xc >> 16) + carry;
+ carry = z2 >> 16;
+ Storeinc(xc, z2, z);
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ if ((y = *xb >> 16) != 0) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ z2 = *xc;
+ do {
+ z = (*x & 0xffff) * y + (*xc >> 16) + carry;
+ carry = z >> 16;
+ Storeinc(xc, z, z2);
+ z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry;
+ carry = z2 >> 16;
+ }
+ while(x < xae);
+ *xc = z2;
+ }
+ }
+#else
+ for(; xb < xbe; xc0++) {
+ if (y = *xb++) {
+ x = xa;
+ xc = xc0;
+ carry = 0;
+ do {
+ z = *x++ * y + *xc + carry;
+ carry = z >> 16;
+ *xc++ = z & 0xffff;
+ }
+ while(x < xae);
+ *xc = carry;
+ }
+ }
+#endif
+ for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ;
+ c->wds = wc;
+ return c;
+}
+
+static Bigint *p5s;
+
+static Bigint *pow5mult(Bigint *b, int k)
+{
+ Bigint *b1, *p5, *p51;
+ int i;
+ static const int p05[3] = { 5, 25, 125 };
+
+ if ((i = k & 3) != 0)
+ b = multadd(b, p05[i-1], 0);
+
+ if (!(k >>= 2))
+ return b;
+ if (!(p5 = p5s)) {
+ /* first time */
+ p5 = p5s = i2b(625);
+ p5->next = 0;
+ }
+ for(;;) {
+ if (k & 1) {
+ b1 = mult(b, p5);
+ Bfree(b);
+ b = b1;
+ }
+ if (!(k >>= 1))
+ break;
+ if (!(p51 = p5->next)) {
+ p51 = p5->next = mult(p5,p5);
+ p51->next = 0;
+ }
+ p5 = p51;
+ }
+ return b;
+}
+
+static Bigint *lshift(Bigint *b, int k)
+{
+ int i, k1, n, n1;
+ Bigint *b1;
+ ULong *x, *x1, *xe, z;
+
+#ifdef Pack_32
+ n = k >> 5;
+#else
+ n = k >> 4;
+#endif
+ k1 = b->k;
+ n1 = n + b->wds + 1;
+ for(i = b->maxwds; n1 > i; i <<= 1)
+ k1++;
+ b1 = Balloc(k1);
+ x1 = b1->x;
+ for(i = 0; i < n; i++)
+ *x1++ = 0;
+ x = b->x;
+ xe = x + b->wds;
+#ifdef Pack_32
+ if (k &= 0x1f) {
+ k1 = 32 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if ((*x1 = z) != 0)
+ ++n1;
+ }
+#else
+ if (k &= 0xf) {
+ k1 = 16 - k;
+ z = 0;
+ do {
+ *x1++ = *x << k & 0xffff | z;
+ z = *x++ >> k1;
+ }
+ while(x < xe);
+ if (*x1 = z)
+ ++n1;
+ }
+#endif
+ else do
+ *x1++ = *x++;
+ while(x < xe);
+ b1->wds = n1 - 1;
+ Bfree(b);
+ return b1;
+}
+
+static int cmp(Bigint *a, Bigint *b)
+{
+ ULong *xa, *xa0, *xb, *xb0;
+ int i, j;
+
+ i = a->wds;
+ j = b->wds;
+#ifdef BSD_TQDTOA_DEBUG
+ if (i > 1 && !a->x[i-1])
+ Bug("cmp called with a->x[a->wds-1] == 0");
+ if (j > 1 && !b->x[j-1])
+ Bug("cmp called with b->x[b->wds-1] == 0");
+#endif
+ if (i -= j)
+ return i;
+ xa0 = a->x;
+ xa = xa0 + j;
+ xb0 = b->x;
+ xb = xb0 + j;
+ for(;;) {
+ if (*--xa != *--xb)
+ return *xa < *xb ? -1 : 1;
+ if (xa <= xa0)
+ break;
+ }
+ return 0;
+}
+
+static Bigint *diff(Bigint *a, Bigint *b)
+{
+ Bigint *c;
+ int i, wa, wb;
+ Long borrow, y; /* We need signed shifts here. */
+ ULong *xa, *xae, *xb, *xbe, *xc;
+#ifdef Pack_32
+ Long z;
+#endif
+
+ i = cmp(a,b);
+ if (!i) {
+ c = Balloc(0);
+ c->wds = 1;
+ c->x[0] = 0;
+ return c;
+ }
+ if (i < 0) {
+ c = a;
+ a = b;
+ b = c;
+ i = 1;
+ }
+ else
+ i = 0;
+ c = Balloc(a->k);
+ c->sign = i;
+ wa = a->wds;
+ xa = a->x;
+ xae = xa + wa;
+ wb = b->wds;
+ xb = b->x;
+ xbe = xb + wb;
+ xc = c->x;
+ borrow = 0;
+#ifdef Pack_32
+ do {
+ y = (*xa & 0xffff) - (*xb & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) - (*xb++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = (*xa & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*xa++ >> 16) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(xc, z, y);
+ }
+#else
+ do {
+ y = *xa++ - *xb++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *xc++ = y & 0xffff;
+ }
+ while(xb < xbe);
+ while(xa < xae) {
+ y = *xa++ + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *xc++ = y & 0xffff;
+ }
+#endif
+ while(!*--xc)
+ wa--;
+ c->wds = wa;
+ return c;
+}
+
+static double ulp(double x)
+{
+ Long L;
+ double a;
+
+ L = (getWord0(x) & Exp_mask) - (P-1)*Exp_msk1;
+#ifndef Sudden_Underflow
+ if (L > 0) {
+#endif
+#ifdef IBM
+ L |= Exp_msk1 >> 4;
+#endif
+ setWord0(&a, L);
+ setWord1(&a, 0);
+#ifndef Sudden_Underflow
+ }
+ else {
+ L = -L >> Exp_shift;
+ if (L < Exp_shift) {
+ setWord0(&a, 0x80000 >> L);
+ setWord1(&a, 0);
+ }
+ else {
+ setWord0(&a, 0);
+ L -= Exp_shift;
+ setWord1(&a, L >= 31 ? 1U : 1U << (31 - L));
+ }
+ }
+#endif
+ return a;
+}
+
+static double b2d(Bigint *a, int *e)
+{
+ ULong *xa, *xa0, w, y, z;
+ int k;
+ double d;
+
+ xa0 = a->x;
+ xa = xa0 + a->wds;
+ y = *--xa;
+#ifdef BSD_TQDTOA_DEBUG
+ if (!y) Bug("zero y in b2d");
+#endif
+ k = hi0bits(y);
+ *e = 32 - k;
+#ifdef Pack_32
+ if (k < Ebits) {
+ setWord0(&d, Exp_1 | y >> (Ebits - k));
+ w = xa > xa0 ? *--xa : 0;
+ setWord1(&d, y << ((32-Ebits) + k) | w >> (Ebits - k));
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ if (k -= Ebits) {
+ setWord0(&d, Exp_1 | y << k | z >> (32 - k));
+ y = xa > xa0 ? *--xa : 0;
+ setWord1(&d, z << k | y >> (32 - k));
+ }
+ else {
+ setWord0(&d, Exp_1 | y);
+ setWord1(&d, z);
+ }
+#else
+ if (k < Ebits + 16) {
+ z = xa > xa0 ? *--xa : 0;
+ setWord0(&d, Exp_1 | y << k - Ebits | z >> Ebits + 16 - k);
+ w = xa > xa0 ? *--xa : 0;
+ y = xa > xa0 ? *--xa : 0;
+ setWord1(&d, z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k);
+ goto ret_d;
+ }
+ z = xa > xa0 ? *--xa : 0;
+ w = xa > xa0 ? *--xa : 0;
+ k -= Ebits + 16;
+ setWord0(&d, Exp_1 | y << k + 16 | z << k | w >> 16 - k);
+ y = xa > xa0 ? *--xa : 0;
+ setWord1(&d, w << k + 16 | y << k);
+#endif
+ ret_d:
+ return d;
+}
+
+static Bigint *d2b(double d, int *e, int *bits)
+{
+ Bigint *b;
+ int de, i, k;
+ ULong *x, y, z;
+
+#ifdef Pack_32
+ b = Balloc(1);
+#else
+ b = Balloc(2);
+#endif
+ x = b->x;
+
+ z = getWord0(d) & Frac_mask;
+ setWord0(&d, getWord0(d) & 0x7fffffff); /* clear sign bit, which we ignore */
+#ifdef Sudden_Underflow
+ de = (int)(getWord0(d) >> Exp_shift);
+#ifndef IBM
+ z |= Exp_msk11;
+#endif
+#else
+ if ((de = (int)(getWord0(d) >> Exp_shift)) != 0)
+ z |= Exp_msk1;
+#endif
+#ifdef Pack_32
+ if ((y = getWord1(d)) != 0) {
+ if ((k = lo0bits(&y)) != 0) {
+ x[0] = y | z << (32 - k);
+ z >>= k;
+ }
+ else
+ x[0] = y;
+ i = b->wds = (x[1] = z) ? 2 : 1;
+ }
+ else {
+#ifdef BSD_TQDTOA_DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ x[0] = z;
+ i = b->wds = 1;
+ k += 32;
+ }
+#else
+ if (y = getWord1(d)) {
+ if (k = lo0bits(&y))
+ if (k >= 16) {
+ x[0] = y | z << 32 - k & 0xffff;
+ x[1] = z >> k - 16 & 0xffff;
+ x[2] = z >> k;
+ i = 2;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16 | z << 16 - k & 0xffff;
+ x[2] = z >> k & 0xffff;
+ x[3] = z >> k+16;
+ i = 3;
+ }
+ else {
+ x[0] = y & 0xffff;
+ x[1] = y >> 16;
+ x[2] = z & 0xffff;
+ x[3] = z >> 16;
+ i = 3;
+ }
+ }
+ else {
+#ifdef BSD_TQDTOA_DEBUG
+ if (!z)
+ Bug("Zero passed to d2b");
+#endif
+ k = lo0bits(&z);
+ if (k >= 16) {
+ x[0] = z;
+ i = 0;
+ }
+ else {
+ x[0] = z & 0xffff;
+ x[1] = z >> 16;
+ i = 1;
+ }
+ k += 32;
+ }
+ while(!x[i])
+ --i;
+ b->wds = i + 1;
+#endif
+#ifndef Sudden_Underflow
+ if (de) {
+#endif
+#ifdef IBM
+ *e = (de - Bias - (P-1) << 2) + k;
+ *bits = 4*P + 8 - k - hi0bits(getWord0(d) & Frac_mask);
+#else
+ *e = de - Bias - (P-1) + k;
+ *bits = P - k;
+#endif
+#ifndef Sudden_Underflow
+ }
+ else {
+ *e = de - Bias - (P-1) + 1 + k;
+#ifdef Pack_32
+ *bits = 32*i - hi0bits(x[i-1]);
+#else
+ *bits = (i+2)*16 - hi0bits(x[i]);
+#endif
+ }
+#endif
+ return b;
+}
+
+static double ratio(Bigint *a, Bigint *b)
+{
+ double da, db;
+ int k, ka, kb;
+
+ da = b2d(a, &ka);
+ db = b2d(b, &kb);
+#ifdef Pack_32
+ k = ka - kb + 32*(a->wds - b->wds);
+#else
+ k = ka - kb + 16*(a->wds - b->wds);
+#endif
+#ifdef IBM
+ if (k > 0) {
+ setWord0(&da, getWord0(da) + (k >> 2)*Exp_msk1);
+ if (k &= 3)
+ da *= 1 << k;
+ }
+ else {
+ k = -k;
+ setWord0(&db, getWord0(db) + (k >> 2)*Exp_msk1);
+ if (k &= 3)
+ db *= 1 << k;
+ }
+#else
+ if (k > 0)
+ setWord0(&da, getWord0(da) + k*Exp_msk1);
+ else {
+ k = -k;
+ setWord0(&db, getWord0(db) + k*Exp_msk1);
+ }
+#endif
+ return da / db;
+}
+
+static CONST double tens[] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
+ 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+ 1e20, 1e21, 1e22
+#ifdef VAX
+ , 1e23, 1e24
+#endif
+};
+
+#ifdef IEEE_Arith
+static CONST double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
+#define n_bigtens 5
+#else
+#ifdef IBM
+static CONST double bigtens[] = { 1e16, 1e32, 1e64 };
+static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64 };
+#define n_bigtens 3
+#else
+static CONST double bigtens[] = { 1e16, 1e32 };
+static CONST double tinytens[] = { 1e-16, 1e-32 };
+#define n_bigtens 2
+#endif
+#endif
+
+/*
+ The pre-release gcc3.3 shipped with SuSE 8.2 has a bug which causes
+ the comparison 1e-100 == 0.0 to return true. As a workaround, we
+ compare it to a global variable containing 0.0, which produces
+ correct assembler output.
+
+ ### consider detecting the broken compilers and using the static
+ ### double for these, and use a #define for all working compilers
+*/
+static double g_double_zero = 0.0;
+
+static double qstrtod(CONST char *s00, CONST char **se, bool *ok)
+{
+ int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
+ e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
+ CONST char *s, *s0, *s1;
+ double aadj, aadj1, adj, rv, rv0;
+ Long L;
+ ULong y, z;
+ Bigint *bb1, *bd0;
+ Bigint *bb = NULL, *bd = NULL, *bs = NULL, *delta = NULL;/* pacify gcc */
+
+ /*
+ #ifndef KR_headers
+ CONST char decimal_point = localeconv()->decimal_point[0];
+ #else
+ CONST char decimal_point = '.';
+ #endif */
+ if (ok != 0)
+ *ok = TRUE;
+
+ CONST char decimal_point = '.';
+
+ sign = nz0 = nz = 0;
+ rv = 0.;
+
+
+ for(s = s00; isspace((unsigned char) *s); s++)
+ ;
+
+ if (*s == '-') {
+ sign = 1;
+ s++;
+ } else if (*s == '+') {
+ s++;
+ }
+
+ if (*s == '\0') {
+ s = s00;
+ goto ret;
+ }
+
+ if (*s == '0') {
+ nz0 = 1;
+ while(*++s == '0') ;
+ if (!*s)
+ goto ret;
+ }
+ s0 = s;
+ y = z = 0;
+ for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++)
+ if (nd < 9)
+ y = 10*y + c - '0';
+ else if (nd < 16)
+ z = 10*z + c - '0';
+ nd0 = nd;
+ if (c == decimal_point) {
+ c = *++s;
+ if (!nd) {
+ for(; c == '0'; c = *++s)
+ nz++;
+ if (c > '0' && c <= '9') {
+ s0 = s;
+ nf += nz;
+ nz = 0;
+ goto have_dig;
+ }
+ goto dig_done;
+ }
+ for(; c >= '0' && c <= '9'; c = *++s) {
+ have_dig:
+ nz++;
+ if (c -= '0') {
+ nf += nz;
+ for(i = 1; i < nz; i++)
+ if (nd++ < 9)
+ y *= 10;
+ else if (nd <= DBL_DIG + 1)
+ z *= 10;
+ if (nd++ < 9)
+ y = 10*y + c;
+ else if (nd <= DBL_DIG + 1)
+ z = 10*z + c;
+ nz = 0;
+ }
+ }
+ }
+ dig_done:
+ e = 0;
+ if (c == 'e' || c == 'E') {
+ if (!nd && !nz && !nz0) {
+ s = s00;
+ goto ret;
+ }
+ s00 = s;
+ esign = 0;
+ switch(c = *++s) {
+ case '-':
+ esign = 1;
+ case '+':
+ c = *++s;
+ }
+ if (c >= '0' && c <= '9') {
+ while(c == '0')
+ c = *++s;
+ if (c > '0' && c <= '9') {
+ L = c - '0';
+ s1 = s;
+ while((c = *++s) >= '0' && c <= '9')
+ L = 10*L + c - '0';
+ if (s - s1 > 8 || L > 19999)
+ /* Avoid confusion from exponents
+ * so large that e might overflow.
+ */
+ e = 19999; /* safe for 16 bit ints */
+ else
+ e = (int)L;
+ if (esign)
+ e = -e;
+ }
+ else
+ e = 0;
+ }
+ else
+ s = s00;
+ }
+ if (!nd) {
+ if (!nz && !nz0)
+ s = s00;
+ goto ret;
+ }
+ e1 = e -= nf;
+
+ /* Now we have nd0 digits, starting at s0, followed by a
+ * decimal point, followed by nd-nd0 digits. The number we're
+ * after is the integer represented by those digits times
+ * 10**e */
+
+ if (!nd0)
+ nd0 = nd;
+ k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1;
+ rv = y;
+ if (k > 9)
+ rv = tens[k - 9] * rv + z;
+ bd0 = 0;
+ if (nd <= DBL_DIG
+#ifndef RND_PRODTQUOT
+ && FLT_ROUNDS == 1
+#endif
+ ) {
+ if (!e)
+ goto ret;
+ if (e > 0) {
+ if (e <= Ten_pmax) {
+#ifdef VAX
+ goto vax_ovfl_check;
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+ goto ret;
+#endif
+ }
+ i = DBL_DIG - nd;
+ if (e <= Ten_pmax + i) {
+ /* A fancier test would sometimes let us do
+ * this for larger i values.
+ */
+ e -= i;
+ rv *= tens[i];
+#ifdef VAX
+ /* VAX exponent range is so narrow we must
+ * worry about overflow here...
+ */
+ vax_ovfl_check:
+ setWord0(&rv, getWord0(rv) - P*Exp_msk1);
+ /* rv = */ rounded_product(rv, tens[e]);
+ if ((getWord0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-1-P))
+ goto ovfl;
+ setWord0(&rv, getWord0(rv) + P*Exp_msk1);
+#else
+ /* rv = */ rounded_product(rv, tens[e]);
+#endif
+ goto ret;
+ }
+ }
+#ifndef Inaccurate_Divide
+ else if (e >= -Ten_pmax) {
+ /* rv = */ rounded_quotient(rv, tens[-e]);
+ goto ret;
+ }
+#endif
+ }
+ e1 += nd - k;
+
+ /* Get starting approximation = rv * 10**e1 */
+
+ if (e1 > 0) {
+ if ((i = e1 & 15) != 0)
+ rv *= tens[i];
+ if (e1 &= ~15) {
+ if (e1 > DBL_MAX_10_EXP) {
+ ovfl:
+ // errno = ERANGE;
+ if (ok != 0)
+ *ok = FALSE;
+#ifdef __STDC__
+ rv = HUGE_VAL;
+#else
+ /* Can't trust HUGE_VAL */
+#ifdef IEEE_Arith
+ setWord0(&rv, Exp_mask);
+ setWord1(&rv, 0);
+#else
+ setWord0(&rv, Big0);
+ setWord1(&rv, Big1);
+#endif
+#endif
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+ if (e1 >>= 4) {
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= bigtens[j];
+ /* The last multiplication could overflow. */
+ setWord0(&rv, getWord0(rv) - P*Exp_msk1);
+ rv *= bigtens[j];
+ if ((z = getWord0(rv) & Exp_mask)
+ > Exp_msk1*(DBL_MAX_EXP+Bias-P))
+ goto ovfl;
+ if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) {
+ /* set to largest number */
+ /* (Can't trust DBL_MAX) */
+ setWord0(&rv, Big0);
+ setWord1(&rv, Big1);
+ }
+ else
+ setWord0(&rv, getWord0(rv) + P*Exp_msk1);
+ }
+
+ }
+ }
+ else if (e1 < 0) {
+ e1 = -e1;
+ if ((i = e1 & 15) != 0)
+ rv /= tens[i];
+ if (e1 &= ~15) {
+ e1 >>= 4;
+ if (e1 >= 1 << n_bigtens)
+ goto undfl;
+ for(j = 0; e1 > 1; j++, e1 >>= 1)
+ if (e1 & 1)
+ rv *= tinytens[j];
+ /* The last multiplication could underflow. */
+ rv0 = rv;
+ rv *= tinytens[j];
+ if (rv == g_double_zero)
+ {
+ rv = 2.*rv0;
+ rv *= tinytens[j];
+ if (rv == g_double_zero)
+ {
+ undfl:
+ rv = 0.;
+ // errno = ERANGE;
+ if (ok != 0)
+ *ok = FALSE;
+ if (bd0)
+ goto retfree;
+ goto ret;
+ }
+ setWord0(&rv, Tiny0);
+ setWord1(&rv, Tiny1);
+ /* The refinement below will clean
+ * this approximation up.
+ */
+ }
+ }
+ }
+
+ /* Now the hard part -- adjusting rv to the correct value.*/
+
+ /* Put digits into bd: true value = bd * 10^e */
+
+ bd0 = s2b(s0, nd0, nd, y);
+
+ for(;;) {
+ bd = Balloc(bd0->k);
+ Bcopy(bd, bd0);
+ bb = d2b(rv, &bbe, &bbbits); /* rv = bb * 2^bbe */
+ bs = i2b(1);
+
+ if (e >= 0) {
+ bb2 = bb5 = 0;
+ bd2 = bd5 = e;
+ }
+ else {
+ bb2 = bb5 = -e;
+ bd2 = bd5 = 0;
+ }
+ if (bbe >= 0)
+ bb2 += bbe;
+ else
+ bd2 -= bbe;
+ bs2 = bb2;
+#ifdef Sudden_Underflow
+#ifdef IBM
+ j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3);
+#else
+ j = P + 1 - bbbits;
+#endif
+#else
+ i = bbe + bbbits - 1; /* logb(rv) */
+ if (i < Emin) /* denormal */
+ j = bbe + (P-Emin);
+ else
+ j = P + 1 - bbbits;
+#endif
+ bb2 += j;
+ bd2 += j;
+ i = bb2 < bd2 ? bb2 : bd2;
+ if (i > bs2)
+ i = bs2;
+ if (i > 0) {
+ bb2 -= i;
+ bd2 -= i;
+ bs2 -= i;
+ }
+ if (bb5 > 0) {
+ bs = pow5mult(bs, bb5);
+ bb1 = mult(bs, bb);
+ Bfree(bb);
+ bb = bb1;
+ }
+ if (bb2 > 0)
+ bb = lshift(bb, bb2);
+ if (bd5 > 0)
+ bd = pow5mult(bd, bd5);
+ if (bd2 > 0)
+ bd = lshift(bd, bd2);
+ if (bs2 > 0)
+ bs = lshift(bs, bs2);
+ delta = diff(bb, bd);
+ dsign = delta->sign;
+ delta->sign = 0;
+ i = cmp(delta, bs);
+ if (i < 0) {
+ /* Error is less than half an ulp -- check for
+ * special case of mantissa a power of two.
+ */
+ if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask)
+ break;
+ delta = lshift(delta,Log2P);
+ if (cmp(delta, bs) > 0)
+ goto drop_down;
+ break;
+ }
+ if (i == 0) {
+ /* exactly half-way between */
+ if (dsign) {
+ if ((getWord0(rv) & Bndry_mask1) == Bndry_mask1
+ && getWord1(rv) == 0xffffffff) {
+ /*boundary case -- increment exponent*/
+ setWord0(&rv, (getWord0(rv) & Exp_mask)
+ + Exp_msk1
+#ifdef IBM
+ | Exp_msk1 >> 4
+#endif
+ );
+ setWord1(&rv, 0);
+ break;
+ }
+ }
+ else if (!(getWord0(rv) & Bndry_mask) && !getWord1(rv)) {
+ drop_down:
+ /* boundary case -- decrement exponent */
+#ifdef Sudden_Underflow
+ L = getWord0(rv) & Exp_mask;
+#ifdef IBM
+ if (L < Exp_msk1)
+#else
+ if (L <= Exp_msk1)
+#endif
+ goto undfl;
+ L -= Exp_msk1;
+#else
+ L = (getWord0(rv) & Exp_mask) - Exp_msk1;
+#endif
+ setWord0(&rv, L | Bndry_mask1);
+ setWord1(&rv, 0xffffffff);
+#ifdef IBM
+ goto cont;
+#else
+ break;
+#endif
+ }
+#ifndef ROUND_BIASED
+ if (!(getWord1(rv) & LSB))
+ break;
+#endif
+ if (dsign)
+ rv += ulp(rv);
+#ifndef ROUND_BIASED
+ else {
+ rv -= ulp(rv);
+#ifndef Sudden_Underflow
+ if (rv == g_double_zero)
+ goto undfl;
+#endif
+ }
+#endif
+ break;
+ }
+ if ((aadj = ratio(delta, bs)) <= 2.) {
+ if (dsign)
+ aadj = aadj1 = 1.;
+ else if (getWord1(rv) || getWord0(rv) & Bndry_mask) {
+#ifndef Sudden_Underflow
+ if (getWord1(rv) == Tiny1 && !getWord0(rv))
+ goto undfl;
+#endif
+ aadj = 1.;
+ aadj1 = -1.;
+ }
+ else {
+ /* special case -- power of FLT_RADIX to be */
+ /* rounded down... */
+
+ if (aadj < 2./FLT_RADIX)
+ aadj = 1./FLT_RADIX;
+ else
+ aadj *= 0.5;
+ aadj1 = -aadj;
+ }
+ }
+ else {
+ aadj *= 0.5;
+ aadj1 = dsign ? aadj : -aadj;
+#ifdef Check_FLT_ROUNDS
+ switch(FLT_ROUNDS) {
+ case 2: /* towards +infinity */
+ aadj1 -= 0.5;
+ break;
+ case 0: /* towards 0 */
+ case 3: /* towards -infinity */
+ aadj1 += 0.5;
+ }
+#else
+ if (FLT_ROUNDS == 0)
+ aadj1 += 0.5;
+#endif
+ }
+ y = getWord0(rv) & Exp_mask;
+
+ /* Check for overflow */
+
+ if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
+ rv0 = rv;
+ setWord0(&rv, getWord0(rv) - P*Exp_msk1);
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ if ((getWord0(rv) & Exp_mask) >=
+ Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
+ if (getWord0(rv0) == Big0 && getWord1(rv0) == Big1)
+ goto ovfl;
+ setWord0(&rv, Big0);
+ setWord1(&rv, Big1);
+ goto cont;
+ }
+ else
+ setWord0(&rv, getWord0(rv) + P*Exp_msk1);
+ }
+ else {
+#ifdef Sudden_Underflow
+ if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1) {
+ rv0 = rv;
+ setWord0(&rv, getWord0(rv) + P*Exp_msk1);
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#ifdef IBM
+ if ((getWord0(rv) & Exp_mask) < P*Exp_msk1)
+#else
+ if ((getWord0(rv) & Exp_mask) <= P*Exp_msk1)
+#endif
+ {
+ if (getWord0(rv0) == Tiny0
+ && getWord1(rv0) == Tiny1)
+ goto undfl;
+ setWord0(&rv, Tiny0);
+ setWord1(&rv, Tiny1);
+ goto cont;
+ }
+ else
+ setWord0(&rv, getWord0(rv) - P*Exp_msk1);
+ }
+ else {
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+ }
+#else
+ /* Compute adj so that the IEEE rounding rules will
+ * correctly round rv + adj in some half-way cases.
+ * If rv * ulp(rv) is denormalized (i.e.,
+ * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid
+ * trouble from bits lost to denormalization;
+ * example: 1.2e-307 .
+ */
+ if (y <= (P-1)*Exp_msk1 && aadj >= 1.) {
+ aadj1 = (double)(int)(aadj + 0.5);
+ if (!dsign)
+ aadj1 = -aadj1;
+ }
+ adj = aadj1 * ulp(rv);
+ rv += adj;
+#endif
+ }
+ z = getWord0(rv) & Exp_mask;
+ if (y == z) {
+ /* Can we stop now? */
+ L = (Long) aadj;
+ aadj -= L;
+ /* The tolerances below are conservative. */
+ if (dsign || getWord1(rv) || getWord0(rv) & Bndry_mask) {
+ if (aadj < .4999999 || aadj > .5000001)
+ break;
+ }
+ else if (aadj < .4999999/FLT_RADIX)
+ break;
+ }
+ cont:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(delta);
+ }
+ retfree:
+ Bfree(bb);
+ Bfree(bd);
+ Bfree(bs);
+ Bfree(bd0);
+ Bfree(delta);
+ ret:
+ if (se)
+ *se = (char *)s;
+ return sign ? -rv : rv;
+}
+
+static int quorem(Bigint *b, Bigint *S)
+{
+ int n;
+ Long borrow, y;
+ ULong carry, q, ys;
+ ULong *bx, *bxe, *sx, *sxe;
+#ifdef Pack_32
+ Long z;
+ ULong si, zs;
+#endif
+
+ n = S->wds;
+#ifdef BSD_TQDTOA_DEBUG
+ /*debug*/ if (b->wds > n)
+ /*debug*/ Bug("oversize b in quorem");
+#endif
+ if (b->wds < n)
+ return 0;
+ sx = S->x;
+ sxe = sx + --n;
+ bx = b->x;
+ bxe = bx + n;
+ q = *bxe / (*sxe + 1); /* ensure q <= true quotient */
+#ifdef BSD_TQDTOA_DEBUG
+ /*debug*/ if (q > 9)
+ /*debug*/ Bug("oversized quotient in quorem");
+#endif
+ if (q) {
+ borrow = 0;
+ carry = 0;
+ do {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) * q + carry;
+ zs = (si >> 16) * q + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ * q + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ while(sx <= sxe);
+ if (!*bxe) {
+ bx = b->x;
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ if (cmp(b, S) >= 0) {
+ q++;
+ borrow = 0;
+ carry = 0;
+ bx = b->x;
+ sx = S->x;
+ do {
+#ifdef Pack_32
+ si = *sx++;
+ ys = (si & 0xffff) + carry;
+ zs = (si >> 16) + (ys >> 16);
+ carry = zs >> 16;
+ y = (*bx & 0xffff) - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ z = (*bx >> 16) - (zs & 0xffff) + borrow;
+ borrow = z >> 16;
+ Sign_Extend(borrow, z);
+ Storeinc(bx, z, y);
+#else
+ ys = *sx++ + carry;
+ carry = ys >> 16;
+ y = *bx - (ys & 0xffff) + borrow;
+ borrow = y >> 16;
+ Sign_Extend(borrow, y);
+ *bx++ = y & 0xffff;
+#endif
+ }
+ while(sx <= sxe);
+ bx = b->x;
+ bxe = bx + n;
+ if (!*bxe) {
+ while(--bxe > bx && !*bxe)
+ --n;
+ b->wds = n;
+ }
+ }
+ return q;
+}
+
+/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
+ *
+ * Inspired by "How to Print Floating-Point Numbers Accurately" by
+ * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 92-101].
+ *
+ * Modifications:
+ * 1. Rather than iterating, we use a simple numeric overestimate
+ * to determine k = floor(log10(d)). We scale relevant
+ * quantities using O(log2(k)) rather than O(k) multiplications.
+ * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't
+ * try to generate digits strictly left to right. Instead, we
+ * compute with fewer bits and propagate the carry if necessary
+ * when rounding the final digit up. This is often faster.
+ * 3. Under the assumption that input will be rounded nearest,
+ * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22.
+ * That is, we allow equality in stopping tests when the
+ * round-nearest rule will give the same floating-point value
+ * as would satisfaction of the stopping test with strict
+ * inequality.
+ * 4. We remove common factors of powers of 2 from relevant
+ * quantities.
+ * 5. When converting floating-point integers less than 1e16,
+ * we use floating-point arithmetic rather than resorting
+ * to multiple-precision integers.
+ * 6. When asked to produce fewer than 15 digits, we first try
+ * to get by with floating-point arithmetic; we resort to
+ * multiple-precision integer arithmetic only if we cannot
+ * guarantee that the floating-point calculation has given
+ * the correctly rounded result. For k requested digits and
+ * "uniformly" distributed input, the probability is
+ * something like 10^(k-15) that we must resort to the Long
+ * calculation.
+ */
+
+
+/* This actually sometimes returns a pointer to a string literal
+ cast to a char*. Do NOT try to modify the return value. */
+
+static char *qdtoa ( double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
+{
+ // Some values of the floating-point control word can cause _qdtoa to crash with an underflow.
+ // We set a safe value here.
+#ifdef TQ_OS_WIN
+#ifndef TQ_CC_BOR
+ unsigned int oldbits = _control87(0, 0);
+#ifndef _M_X64 //x64 does not support precition control
+ _control87(0x9001F, 0xFFFFF);
+#else
+ _control87(0x9001F, _MCW_DN|_MCW_EM|_MCW_RC);
+#endif //_M_X64
+#endif
+#endif
+
+#ifdef TQ_OS_LINUX
+ fenv_t envp;
+ feholdexcept(&envp);
+#endif
+
+ char *s = _qdtoa(d, mode, ndigits, decpt, sign, rve, resultp);
+
+#ifdef TQ_OS_WIN
+#ifndef TQ_CC_BOR
+ _clear87();
+#ifndef _M_X64
+ _control87(oldbits, 0xFFFFF);
+#else
+ _control87(oldbits, _MCW_DN|_MCW_EM|_MCW_RC);
+#endif //_M_X64
+#endif
+#endif
+
+#ifdef TQ_OS_LINUX
+ fesetenv(&envp);
+#endif
+
+ return s;
+}
+
+static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp)
+{
+ /*
+ Arguments ndigits, decpt, sign are similar to those
+ of ecvt and fcvt; trailing zeros are suppressed from
+ the returned string. If not null, *rve is set to point
+ to the end of the return value. If d is +-Infinity or NaN,
+ then *decpt is set to 9999.
+
+ mode:
+ 0 ==> shortest string that yields d when read in
+ and rounded to nearest.
+ 1 ==> like 0, but with Steele & White stopping rule;
+ e.g. with IEEE P754 arithmetic , mode 0 gives
+ 1e23 whereas mode 1 gives 9.999999999999999e22.
+ 2 ==> max(1,ndigits) significant digits. This gives a
+ return value similar to that of ecvt, except
+ that trailing zeros are suppressed.
+ 3 ==> through ndigits past the decimal point. This
+ gives a return value similar to that from fcvt,
+ except that trailing zeros are suppressed, and
+ ndigits can be negative.
+ 4-9 should give the same return values as 2-3, i.e.,
+ 4 <= mode <= 9 ==> same return as mode
+ 2 + (mode & 1). These modes are mainly for
+ debugging; often they run slower but sometimes
+ faster than modes 2-3.
+ 4,5,8,9 ==> left-to-right digit generation.
+ 6-9 ==> don't try fast floating-point estimate
+ (if applicable).
+
+ Values of mode other than 0-9 are treated as mode 0.
+
+ Sufficient space is allocated to the return value
+ to hold the suppressed trailing zeros.
+ */
+
+ int bbits, b2, b5, be, dig, i, ieps, ilim0,
+ j, j1, k, k0, k_check, leftright, m2, m5, s2, s5,
+ try_quick;
+ int ilim = 0, ilim1 = 0, spec_case = 0; /* pacify gcc */
+ Long L;
+#ifndef Sudden_Underflow
+ int denorm;
+ ULong x;
+#endif
+ Bigint *b, *b1, *delta, *mhi, *S;
+ Bigint *mlo = NULL; /* pacify gcc */
+ double d2;
+ double ds, eps;
+ char *s, *s0;
+
+ if (getWord0(d) & Sign_bit) {
+ /* set sign for everything, including 0's and NaNs */
+ *sign = 1;
+ setWord0(&d, getWord0(d) & ~Sign_bit); /* clear sign bit */
+ }
+ else
+ *sign = 0;
+
+#if defined(IEEE_Arith) + defined(VAX)
+#ifdef IEEE_Arith
+ if ((getWord0(d) & Exp_mask) == Exp_mask)
+#else
+ if (getWord0(d) == 0x8000)
+#endif
+ {
+ /* Infinity or NaN */
+ *decpt = 9999;
+ s =
+#ifdef IEEE_Arith
+ !getWord1(d) && !(getWord0(d) & 0xfffff) ? (char*)"Infinity" :
+#endif
+ (char*)"NaN";
+ if (rve)
+ *rve =
+#ifdef IEEE_Arith
+ s[3] ? s + 8 :
+#endif
+ s + 3;
+ return s;
+ }
+#endif
+#ifdef IBM
+ d += 0; /* normalize */
+#endif
+ if (d == g_double_zero)
+ {
+ *decpt = 1;
+ s = (char*) "0";
+ if (rve)
+ *rve = s + 1;
+ return s;
+ }
+
+ b = d2b(d, &be, &bbits);
+#ifdef Sudden_Underflow
+ i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1));
+#else
+ if ((i = (int)(getWord0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) != 0) {
+#endif
+ d2 = d;
+ setWord0(&d2, getWord0(d2) & Frac_mask1);
+ setWord0(&d2, getWord0(d2) | Exp_11);
+#ifdef IBM
+ if (j = 11 - hi0bits(getWord0(d2) & Frac_mask))
+ d2 /= 1 << j;
+#endif
+
+ /* log(x) ~=~ log(1.5) + (x-1.5)/1.5
+ * log10(x) = log(x) / log(10)
+ * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10))
+ * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2)
+ *
+ * This suggests computing an approximation k to log10(d) by
+ *
+ * k = (i - Bias)*0.301029995663981
+ * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 );
+ *
+ * We want k to be too large rather than too small.
+ * The error in the first-order Taylor series approximation
+ * is in our favor, so we just round up the constant enough
+ * to compensate for any error in the multiplication of
+ * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077,
+ * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14,
+ * adding 1e-13 to the constant term more than suffices.
+ * Hence we adjust the constant term to 0.1760912590558.
+ * (We could get a more accurate k by invoking log10,
+ * but this is probably not worthwhile.)
+ */
+
+ i -= Bias;
+#ifdef IBM
+ i <<= 2;
+ i += j;
+#endif
+#ifndef Sudden_Underflow
+ denorm = 0;
+ }
+ else {
+ /* d is denormalized */
+
+ i = bbits + be + (Bias + (P-1) - 1);
+ x = i > 32 ? getWord0(d) << (64 - i) | getWord1(d) >> (i - 32)
+ : getWord1(d) << (32 - i);
+ d2 = x;
+ setWord0(&d2, getWord0(d2) - 31*Exp_msk1); /* adjust exponent */
+ i -= (Bias + (P-1) - 1) + 1;
+ denorm = 1;
+ }
+#endif
+ ds = (d2-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981;
+ k = (int)ds;
+ if (ds < 0. && ds != k)
+ k--; /* want k = floor(ds) */
+ k_check = 1;
+ if (k >= 0 && k <= Ten_pmax) {
+ if (d < tens[k])
+ k--;
+ k_check = 0;
+ }
+ j = bbits - i - 1;
+ if (j >= 0) {
+ b2 = 0;
+ s2 = j;
+ }
+ else {
+ b2 = -j;
+ s2 = 0;
+ }
+ if (k >= 0) {
+ b5 = 0;
+ s5 = k;
+ s2 += k;
+ }
+ else {
+ b2 -= k;
+ b5 = -k;
+ s5 = 0;
+ }
+ if (mode < 0 || mode > 9)
+ mode = 0;
+ try_quick = 1;
+ if (mode > 5) {
+ mode -= 4;
+ try_quick = 0;
+ }
+ leftright = 1;
+ switch(mode) {
+ case 0:
+ case 1:
+ ilim = ilim1 = -1;
+ i = 18;
+ ndigits = 0;
+ break;
+ case 2:
+ leftright = 0;
+ /* no break */
+ case 4:
+ if (ndigits <= 0)
+ ndigits = 1;
+ ilim = ilim1 = i = ndigits;
+ break;
+ case 3:
+ leftright = 0;
+ /* no break */
+ case 5:
+ i = ndigits + k + 1;
+ ilim = i;
+ ilim1 = i - 1;
+ if (i <= 0)
+ i = 1;
+ }
+ *resultp = (char *) malloc(i + 1);
+ s = s0 = *resultp;
+
+ if (ilim >= 0 && ilim <= Quick_max && try_quick) {
+
+ /* Try to get by with floating-point arithmetic. */
+
+ i = 0;
+ d2 = d;
+ k0 = k;
+ ilim0 = ilim;
+ ieps = 2; /* conservative */
+ if (k > 0) {
+ ds = tens[k&0xf];
+ j = k >> 4;
+ if (j & Bletch) {
+ /* prevent overflows */
+ j &= Bletch - 1;
+ d /= bigtens[n_bigtens-1];
+ ieps++;
+ }
+ for(; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ ds *= bigtens[i];
+ }
+ d /= ds;
+ }
+ else if ((j1 = -k) != 0) {
+ d *= tens[j1 & 0xf];
+ for(j = j1 >> 4; j; j >>= 1, i++)
+ if (j & 1) {
+ ieps++;
+ d *= bigtens[i];
+ }
+ }
+ if (k_check && d < 1. && ilim > 0) {
+ if (ilim1 <= 0)
+ goto fast_failed;
+ ilim = ilim1;
+ k--;
+ d *= 10.;
+ ieps++;
+ }
+ eps = ieps*d + 7.;
+ setWord0(&eps, getWord0(eps) - (P-1)*Exp_msk1);
+ if (ilim == 0) {
+ S = mhi = 0;
+ d -= 5.;
+ if (d > eps)
+ goto one_digit;
+ if (d < -eps)
+ goto no_digits;
+ goto fast_failed;
+ }
+#ifndef No_leftright
+ if (leftright) {
+ /* Use Steele & White method of only
+ * generating digits needed.
+ */
+ eps = 0.5/tens[ilim-1] - eps;
+ for(i = 0;;) {
+ L = (Long)d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (d < eps)
+ goto ret1;
+ if (1. - d < eps)
+ goto bump_up;
+ if (++i >= ilim)
+ break;
+ eps *= 10.;
+ d *= 10.;
+ }
+ }
+ else {
+#endif
+ /* Generate ilim digits, then fix them up. */
+ eps *= tens[ilim-1];
+ for(i = 1;; i++, d *= 10.) {
+ L = (Long)d;
+ d -= L;
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ if (d > 0.5 + eps)
+ goto bump_up;
+ else if (d < 0.5 - eps) {
+ while(*--s == '0');
+ s++;
+ goto ret1;
+ }
+ break;
+ }
+ }
+#ifndef No_leftright
+ }
+#endif
+ fast_failed:
+ s = s0;
+ d = d2;
+ k = k0;
+ ilim = ilim0;
+ }
+
+ /* Do we have a "small" integer? */
+
+ if (be >= 0 && k <= Int_max) {
+ /* Yes. */
+ ds = tens[k];
+ if (ndigits < 0 && ilim <= 0) {
+ S = mhi = 0;
+ if (ilim < 0 || d <= 5*ds)
+ goto no_digits;
+ goto one_digit;
+ }
+ for(i = 1;; i++) {
+ L = (Long)(d / ds);
+ d -= L*ds;
+#ifdef Check_FLT_ROUNDS
+ /* If FLT_ROUNDS == 2, L will usually be high by 1 */
+ if (d < 0) {
+ L--;
+ d += ds;
+ }
+#endif
+ *s++ = '0' + (int)L;
+ if (i == ilim) {
+ d += d;
+ if (d > ds || (d == ds && L & 1)) {
+ bump_up:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s = '0';
+ break;
+ }
+ ++*s++;
+ }
+ break;
+ }
+ if ((d *= 10.) == g_double_zero)
+ break;
+ }
+ goto ret1;
+ }
+
+ m2 = b2;
+ m5 = b5;
+ mhi = mlo = 0;
+ if (leftright) {
+ if (mode < 2) {
+ i =
+#ifndef Sudden_Underflow
+ denorm ? be + (Bias + (P-1) - 1 + 1) :
+#endif
+#ifdef IBM
+ 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3);
+#else
+ 1 + P - bbits;
+#endif
+ }
+ else {
+ j = ilim - 1;
+ if (m5 >= j)
+ m5 -= j;
+ else {
+ s5 += j -= m5;
+ b5 += j;
+ m5 = 0;
+ }
+ if ((i = ilim) < 0) {
+ m2 -= i;
+ i = 0;
+ }
+ }
+ b2 += i;
+ s2 += i;
+ mhi = i2b(1);
+ }
+ if (m2 > 0 && s2 > 0) {
+ i = m2 < s2 ? m2 : s2;
+ b2 -= i;
+ m2 -= i;
+ s2 -= i;
+ }
+ if (b5 > 0) {
+ if (leftright) {
+ if (m5 > 0) {
+ mhi = pow5mult(mhi, m5);
+ b1 = mult(mhi, b);
+ Bfree(b);
+ b = b1;
+ }
+ if ((j = b5 - m5) != 0)
+ b = pow5mult(b, j);
+ }
+ else
+ b = pow5mult(b, b5);
+ }
+ S = i2b(1);
+ if (s5 > 0)
+ S = pow5mult(S, s5);
+
+ /* Check for special case that d is a normalized power of 2. */
+
+ if (mode < 2) {
+ if (!getWord1(d) && !(getWord0(d) & Bndry_mask)
+#ifndef Sudden_Underflow
+ && getWord0(d) & Exp_mask
+#endif
+ ) {
+ /* The special case */
+ b2 += Log2P;
+ s2 += Log2P;
+ spec_case = 1;
+ }
+ else
+ spec_case = 0;
+ }
+
+ /* Arrange for convenient computation of quotients:
+ * shift left if necessary so divisor has 4 leading 0 bits.
+ *
+ * Perhaps we should just compute leading 28 bits of S once
+ * and for all and pass them and a shift to quorem, so it
+ * can do shifts and ors to compute the numerator for q.
+ */
+#ifdef Pack_32
+ if ((i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) != 0)
+ i = 32 - i;
+#else
+ if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf)
+ i = 16 - i;
+#endif
+ if (i > 4) {
+ i -= 4;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ else if (i < 4) {
+ i += 28;
+ b2 += i;
+ m2 += i;
+ s2 += i;
+ }
+ if (b2 > 0)
+ b = lshift(b, b2);
+ if (s2 > 0)
+ S = lshift(S, s2);
+ if (k_check) {
+ if (cmp(b,S) < 0) {
+ k--;
+ b = multadd(b, 10, 0); /* we botched the k estimate */
+ if (leftright)
+ mhi = multadd(mhi, 10, 0);
+ ilim = ilim1;
+ }
+ }
+ if (ilim <= 0 && mode > 2) {
+ if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) {
+ /* no digits, fcvt style */
+ no_digits:
+ k = -1 - ndigits;
+ goto ret;
+ }
+ one_digit:
+ *s++ = '1';
+ k++;
+ goto ret;
+ }
+ if (leftright) {
+ if (m2 > 0)
+ mhi = lshift(mhi, m2);
+
+ /* Compute mlo -- check for special case
+ * that d is a normalized power of 2.
+ */
+
+ mlo = mhi;
+ if (spec_case) {
+ mhi = Balloc(mhi->k);
+ Bcopy(mhi, mlo);
+ mhi = lshift(mhi, Log2P);
+ }
+
+ for(i = 1;;i++) {
+ dig = quorem(b,S) + '0';
+ /* Do we yet have the shortest decimal string
+ * that will round to d?
+ */
+ j = cmp(b, mlo);
+ delta = diff(S, mhi);
+ j1 = delta->sign ? 1 : cmp(b, delta);
+ Bfree(delta);
+#ifndef ROUND_BIASED
+ if (j1 == 0 && !mode && !(getWord1(d) & 1)) {
+ if (dig == '9')
+ goto round_9_up;
+ if (j > 0)
+ dig++;
+ *s++ = dig;
+ goto ret;
+ }
+#endif
+ if (j < 0 || (j == 0 && !mode
+#ifndef ROUND_BIASED
+ && !(getWord1(d) & 1)
+#endif
+ )) {
+ if (j1 > 0) {
+ b = lshift(b, 1);
+ j1 = cmp(b, S);
+ if ((j1 > 0 || (j1 == 0 && dig & 1))
+ && dig++ == '9')
+ goto round_9_up;
+ }
+ *s++ = dig;
+ goto ret;
+ }
+ if (j1 > 0) {
+ if (dig == '9') { /* possible if i == 1 */
+ round_9_up:
+ *s++ = '9';
+ goto roundoff;
+ }
+ *s++ = dig + 1;
+ goto ret;
+ }
+ *s++ = dig;
+ if (i == ilim)
+ break;
+ b = multadd(b, 10, 0);
+ if (mlo == mhi)
+ mlo = mhi = multadd(mhi, 10, 0);
+ else {
+ mlo = multadd(mlo, 10, 0);
+ mhi = multadd(mhi, 10, 0);
+ }
+ }
+ }
+ else
+ for(i = 1;; i++) {
+ *s++ = dig = quorem(b,S) + '0';
+ if (i >= ilim)
+ break;
+ b = multadd(b, 10, 0);
+ }
+
+ /* Round off last digit */
+
+ b = lshift(b, 1);
+ j = cmp(b, S);
+ if (j > 0 || (j == 0 && dig & 1)) {
+ roundoff:
+ while(*--s == '9')
+ if (s == s0) {
+ k++;
+ *s++ = '1';
+ goto ret;
+ }
+ ++*s++;
+ }
+ else {
+ while(*--s == '0');
+ s++;
+ }
+ ret:
+ Bfree(S);
+ if (mhi) {
+ if (mlo && mlo != mhi)
+ Bfree(mlo);
+ Bfree(mhi);
+ }
+ ret1:
+ Bfree(b);
+ if (s == s0) { /* don't return empty string */
+ *s++ = '0';
+ k = 0;
+ }
+ *s = 0;
+ *decpt = k + 1;
+ if (rve)
+ *rve = s;
+ return s0;
+}
+
+#endif // TQT_TQLOCALE_USES_FCVT
diff --git a/tqtinterface/qt4/src/tools/tqlocale.h b/tqtinterface/qt4/src/tools/tqlocale.h
new file mode 100644
index 0000000..362f317
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqlocale.h
@@ -0,0 +1,494 @@
+/****************************************************************************
+**
+** Declaration of the TQLocale class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLOCALE_H
+#define TQLOCALE_H
+
+#include "tqstring.h"
+
+struct TQLocalePrivate;
+
+class TQ_EXPORT TQLocale
+{
+ friend class TQString;
+
+public:
+ enum Language {
+ C = 1,
+ Abkhazian = 2,
+ Afan = 3,
+ Afar = 4,
+ Afrikaans = 5,
+ Albanian = 6,
+ Amharic = 7,
+ Arabic = 8,
+ Armenian = 9,
+ Assamese = 10,
+ Aymara = 11,
+ Azerbaijani = 12,
+ Bashkir = 13,
+ Basque = 14,
+ Bengali = 15,
+ Bhutani = 16,
+ Bihari = 17,
+ Bislama = 18,
+ Breton = 19,
+ Bulgarian = 20,
+ Burmese = 21,
+ Byelorussian = 22,
+ Cambodian = 23,
+ Catalan = 24,
+ Chinese = 25,
+ Corsican = 26,
+ Croatian = 27,
+ Czech = 28,
+ Danish = 29,
+ Dutch = 30,
+ English = 31,
+ Esperanto = 32,
+ Estonian = 33,
+ Faroese = 34,
+ FijiLanguage = 35,
+ Finnish = 36,
+ French = 37,
+ Frisian = 38,
+ Gaelic = 39,
+ Galician = 40,
+ Georgian = 41,
+ German = 42,
+ Greek = 43,
+ Greenlandic = 44,
+ Guarani = 45,
+ Gujarati = 46,
+ Hausa = 47,
+ Hebrew = 48,
+ Hindi = 49,
+ Hungarian = 50,
+ Icelandic = 51,
+ Indonesian = 52,
+ Interlingua = 53,
+ Interlingue = 54,
+ Inuktitut = 55,
+ Inupiak = 56,
+ Irish = 57,
+ Italian = 58,
+ Japanese = 59,
+ Javanese = 60,
+ Kannada = 61,
+ Kashmiri = 62,
+ Kazakh = 63,
+ Kinyarwanda = 64,
+ Kirghiz = 65,
+ Korean = 66,
+ Kurdish = 67,
+ Kurundi = 68,
+ Laothian = 69,
+ Latin = 70,
+ Latvian = 71,
+ Lingala = 72,
+ Lithuanian = 73,
+ Macedonian = 74,
+ Malagasy = 75,
+ Malay = 76,
+ Malayalam = 77,
+ Maltese = 78,
+ Maori = 79,
+ Marathi = 80,
+ Moldavian = 81,
+ Mongolian = 82,
+ NauruLanguage = 83,
+ Nepali = 84,
+ Norwegian = 85,
+ Occitan = 86,
+ Oriya = 87,
+ Pashto = 88,
+ Persian = 89,
+ Polish = 90,
+ Portuguese = 91,
+ Punjabi = 92,
+ Quechua = 93,
+ RhaetoRomance = 94,
+ Romanian = 95,
+ Russian = 96,
+ Samoan = 97,
+ Sangho = 98,
+ Sanskrit = 99,
+ Serbian = 100,
+ SerboCroatian = 101,
+ Sesotho = 102,
+ Setswana = 103,
+ Shona = 104,
+ Sindhi = 105,
+ Singhalese = 106,
+ Siswati = 107,
+ Slovak = 108,
+ Slovenian = 109,
+ Somali = 110,
+ Spanish = 111,
+ Sundanese = 112,
+ Swahili = 113,
+ Swedish = 114,
+ Tagalog = 115,
+ Tajik = 116,
+ Tamil = 117,
+ Tatar = 118,
+ Telugu = 119,
+ Thai = 120,
+ Tibetan = 121,
+ Tigrinya = 122,
+ TongaLanguage = 123,
+ Tsonga = 124,
+ Turkish = 125,
+ Turkmen = 126,
+ Twi = 127,
+ Uigur = 128,
+ Ukrainian = 129,
+ Urdu = 130,
+ Uzbek = 131,
+ Vietnamese = 132,
+ Volapuk = 133,
+ Welsh = 134,
+ Wolof = 135,
+ Xhosa = 136,
+ Yiddish = 137,
+ Yoruba = 138,
+ Zhuang = 139,
+ Zulu = 140,
+ LastLanguage = Zulu
+ };
+
+ enum Country {
+ AnyCountry = 0,
+ Afghanistan = 1,
+ Albania = 2,
+ Algeria = 3,
+ AmericanSamoa = 4,
+ Andorra = 5,
+ Angola = 6,
+ Anguilla = 7,
+ Antarctica = 8,
+ AntiguaAndBarbuda = 9,
+ Argentina = 10,
+ Armenia = 11,
+ Aruba = 12,
+ Australia = 13,
+ Austria = 14,
+ Azerbaijan = 15,
+ Bahamas = 16,
+ Bahrain = 17,
+ Bangladesh = 18,
+ Barbados = 19,
+ Belarus = 20,
+ Belgium = 21,
+ Belize = 22,
+ Benin = 23,
+ Bermuda = 24,
+ Bhutan = 25,
+ Bolivia = 26,
+ BosniaAndHerzegowina = 27,
+ Botswana = 28,
+ BouvetIsland = 29,
+ Brazil = 30,
+ BritishIndianOceanTerritory = 31,
+ BruneiDarussalam = 32,
+ Bulgaria = 33,
+ BurkinaFaso = 34,
+ Burundi = 35,
+ Cambodia = 36,
+ Cameroon = 37,
+ Canada = 38,
+ CapeVerde = 39,
+ CaymanIslands = 40,
+ CentralAfricanRepublic = 41,
+ Chad = 42,
+ Chile = 43,
+ China = 44,
+ ChristmasIsland = 45,
+ CocosIslands = 46,
+ Colombia = 47,
+ Comoros = 48,
+ DetqmocraticRepublicOfCongo = 49,
+ PeoplesRepublicOfCongo = 50,
+ CookIslands = 51,
+ CostaRica = 52,
+ IvoryCoast = 53,
+ Croatia = 54,
+ Cuba = 55,
+ Cyprus = 56,
+ CzechRepublic = 57,
+ Denmark = 58,
+ Djibouti = 59,
+ Dominica = 60,
+ DominicanRepublic = 61,
+ EastTimor = 62,
+ Ecuador = 63,
+ Egypt = 64,
+ ElSalvador = 65,
+ EquatorialGuinea = 66,
+ Eritrea = 67,
+ Estonia = 68,
+ Ethiopia = 69,
+ FalklandIslands = 70,
+ FaroeIslands = 71,
+ FijiCountry = 72,
+ Finland = 73,
+ France = 74,
+ MetropolitanFrance = 75,
+ FrenchGuiana = 76,
+ FrenchPolynesia = 77,
+ FrenchSouthernTerritories = 78,
+ Gabon = 79,
+ Gambia = 80,
+ Georgia = 81,
+ Germany = 82,
+ Ghana = 83,
+ Gibraltar = 84,
+ Greece = 85,
+ Greenland = 86,
+ Grenada = 87,
+ Guadeloupe = 88,
+ Guam = 89,
+ Guatemala = 90,
+ Guinea = 91,
+ GuineaBissau = 92,
+ Guyana = 93,
+ Haiti = 94,
+ HeardAndMcDonaldIslands = 95,
+ Honduras = 96,
+ HongKong = 97,
+ Hungary = 98,
+ Iceland = 99,
+ India = 100,
+ Indonesia = 101,
+ Iran = 102,
+ Iraq = 103,
+ Ireland = 104,
+ Israel = 105,
+ Italy = 106,
+ Jamaica = 107,
+ Japan = 108,
+ Jordan = 109,
+ Kazakhstan = 110,
+ Kenya = 111,
+ Kiribati = 112,
+ DetqmocraticRepublicOfKorea = 113,
+ RepublicOfKorea = 114,
+ Kuwait = 115,
+ Kyrgyzstan = 116,
+ Lao = 117,
+ Latvia = 118,
+ Lebanon = 119,
+ Lesotho = 120,
+ Liberia = 121,
+ LibyanArabJamahiriya = 122,
+ Liechtenstein = 123,
+ Lithuania = 124,
+ Luxembourg = 125,
+ Macau = 126,
+ Macedonia = 127,
+ Madagascar = 128,
+ Malawi = 129,
+ Malaysia = 130,
+ Maldives = 131,
+ Mali = 132,
+ Malta = 133,
+ MarshallIslands = 134,
+ Martinique = 135,
+ Mauritania = 136,
+ Mauritius = 137,
+ Mayotte = 138,
+ Mexico = 139,
+ Micronesia = 140,
+ Moldova = 141,
+ Monaco = 142,
+ Mongolia = 143,
+ Montserrat = 144,
+ Morocco = 145,
+ Mozambique = 146,
+ Myanmar = 147,
+ Namibia = 148,
+ NauruCountry = 149,
+ Nepal = 150,
+ Netherlands = 151,
+ NetherlandsAntilles = 152,
+ NewCaledonia = 153,
+ NewZealand = 154,
+ Nicaragua = 155,
+ Niger = 156,
+ Nigeria = 157,
+ Niue = 158,
+ NorfolkIsland = 159,
+ NorthernMarianaIslands = 160,
+ Norway = 161,
+ Oman = 162,
+ Pakistan = 163,
+ Palau = 164,
+ PalestinianTerritory = 165,
+ Panama = 166,
+ PapuaNewGuinea = 167,
+ Paraguay = 168,
+ Peru = 169,
+ Philippines = 170,
+ Pitcairn = 171,
+ Poland = 172,
+ Portugal = 173,
+ PuertoRico = 174,
+ Qatar = 175,
+ Reunion = 176,
+ Romania = 177,
+ RussianFederation = 178,
+ Rwanda = 179,
+ SaintKittsAndNevis = 180,
+ StLucia = 181,
+ StVincentAndTheGrenadines = 182,
+ Samoa = 183,
+ SanMarino = 184,
+ SaoTomeAndPrincipe = 185,
+ SaudiArabia = 186,
+ Senegal = 187,
+ Seychelles = 188,
+ SierraLeone = 189,
+ Singapore = 190,
+ Slovakia = 191,
+ Slovenia = 192,
+ SolomonIslands = 193,
+ Somalia = 194,
+ SouthAfrica = 195,
+ SouthGeorgiaAndTheSouthSandwichIslands = 196,
+ Spain = 197,
+ SriLanka = 198,
+ StHelena = 199,
+ StPierreAndMiquelon = 200,
+ Sudan = 201,
+ Suriname = 202,
+ SvalbardAndJanMayenIslands = 203,
+ Swaziland = 204,
+ Sweden = 205,
+ Switzerland = 206,
+ SyrianArabRepublic = 207,
+ Taiwan = 208,
+ Tajikistan = 209,
+ Tanzania = 210,
+ Thailand = 211,
+ Togo = 212,
+ Tokelau = 213,
+ TongaCountry = 214,
+ TrinidadAndTobago = 215,
+ Tunisia = 216,
+ Turkey = 217,
+ Turkmenistan = 218,
+ TurksAndCaicosIslands = 219,
+ Tuvalu = 220,
+ Uganda = 221,
+ Ukraine = 222,
+ UnitedArabEmirates = 223,
+ UnitedKingdom = 224,
+ UnitedStates = 225,
+ UnitedStatesMinorOutlyingIslands = 226,
+ Uruguay = 227,
+ Uzbekistan = 228,
+ Vanuatu = 229,
+ VaticanCityState = 230,
+ Venezuela = 231,
+ VietNam = 232,
+ BritishVirginIslands = 233,
+ USVirginIslands = 234,
+ WallisAndFutunaIslands = 235,
+ WesternSahara = 236,
+ Yemen = 237,
+ Yugoslavia = 238,
+ Zambia = 239,
+ Zimbabwe = 240,
+ LastCountry = Zimbabwe
+ };
+
+ TQLocale();
+ TQLocale(const TQString &name);
+ TQLocale(Language language, Country country = AnyCountry);
+ TQLocale(const TQLocale &other);
+
+ TQLocale &operator=(const TQLocale &other);
+
+ Language language() const;
+ Country country() const;
+ TQString name() const;
+
+ short toShort(const TQString &s, bool *ok = 0) const;
+ ushort toUShort(const TQString &s, bool *ok = 0) const;
+ int toInt(const TQString &s, bool *ok = 0) const;
+ uint toUInt(const TQString &s, bool *ok = 0) const;
+ TQ_LONG toLong(const TQString &s, bool *ok = 0) const;
+ TQ_ULONG toULong(const TQString &s, bool *ok = 0) const;
+ TQ_LLONG toLongLong(const TQString &s, bool *ok = 0) const;
+ TQ_ULLONG toULongLong(const TQString &s, bool *ok = 0) const;
+ float toFloat(const TQString &s, bool *ok = 0) const;
+ double toDouble(const TQString &s, bool *ok = 0) const;
+
+ TQString toString(short i) const
+ { return toString((TQ_LLONG)i); }
+ TQString toString(ushort i) const
+ { return toString((TQ_ULLONG)i); }
+ TQString toString(int i) const
+ { return toString((TQ_LLONG)i); }
+ TQString toString(uint i) const
+ { return toString((TQ_ULLONG)i); }
+#if !defined(TQ_OS_WIN64)
+ TQString toString(TQ_LONG i) const
+ { return toString((TQ_LLONG)i); }
+ TQString toString(TQ_ULONG i) const
+ { return toString((TQ_ULLONG)i); }
+#endif
+ TQString toString(TQ_LLONG i) const;
+ TQString toString(TQ_ULLONG i) const;
+ TQString toString(float i, char f = 'g', int prec = 6) const
+ { return toString((double) i, f, prec); }
+ TQString toString(double i, char f = 'g', int prec = 6) const;
+
+ static TQString languageToString(Language language);
+ static TQString countryToString(Country country);
+ static void setDefault(const TQLocale &locale);
+
+ static TQLocale c() { return TQLocale(C); }
+ static TQLocale system();
+
+private:
+ const TQLocalePrivate *d;
+ static const TQLocalePrivate *default_d;
+};
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqlocale_p.h b/tqtinterface/qt4/src/tools/tqlocale_p.h
new file mode 100644
index 0000000..fbfc184
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqlocale_p.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** Declaration of the TQLocalePrivate class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLOCALE_P_H
+#define TQLOCALE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#include <tqstring.h>
+
+struct TQLocalePrivate
+{
+public:
+ const TQChar &decimal() const { return (TQChar&)m_decimal; }
+ const TQChar &group() const { return (TQChar&)m_group; }
+ const TQChar &list() const { return (TQChar&)m_list; }
+ const TQChar &percent() const { return (TQChar&)m_percent; }
+ const TQChar &zero() const { return (TQChar&)m_zero; }
+ TQChar plus() const { return TQChar('+'); }
+ const TQChar &minus() const { return (TQChar&)m_minus; }
+ const TQChar &exponential() const { return (TQChar&)m_exponential; }
+ TQString infinity() const;
+ TQString nan() const;
+
+ TQ_UINT32 languageId() const { return m_language_id; }
+ TQ_UINT32 countryId() const { return m_country_id; }
+
+ bool isDigit(TQChar d) const;
+
+ enum GroupSeparatorMode {
+ FailOnGroupSeparators,
+ ParseGroupSeparators
+ };
+
+ enum DoubleForm {
+ DFExponent = 0, // %e or %E
+ DFDecimal, // %f or %F
+ DFSignificantDigits, // %g or %G
+ _DFMax = DFSignificantDigits
+ };
+
+ enum Flags {
+ NoFlags = 0,
+
+ // These correspond to the options in a printf format string
+ Alternate = 0x01,
+ ZeroPadded = 0x02,
+ LeftAdjusted = 0x04,
+ BlankBeforePositive = 0x08,
+ AlwaysShowSign = 0x10,
+ ThousandsGroup = 0x20,
+ CapitalEorX = 0x40 // %x, %e, %f, %g vs. %X, %E, %F, %G
+ };
+
+ TQString doubleToString(double d,
+ int precision = -1,
+ DoubleForm form = DFSignificantDigits,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+ TQString longLongToString(TQ_LLONG l, int precision = -1,
+ int base = 10,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+ TQString unsLongLongToString(TQ_ULLONG l, int precision = -1,
+ int base = 10,
+ int width = -1,
+ unsigned flags = NoFlags) const;
+ double stringToDouble(TQString num, bool *ok, GroupSeparatorMode group_sep_mode) const;
+ TQ_LLONG stringToLongLong(TQString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
+ TQ_ULLONG stringToUnsLongLong(TQString num, int base, bool *ok, GroupSeparatorMode group_sep_mode) const;
+ bool removeGroupSeparators(TQString &num_str) const;
+ bool numberToCLocale(TQString &locale_num, GroupSeparatorMode group_sep_mode) const;
+
+ TQ_UINT32 m_language_id, m_country_id;
+
+ TQ_UINT16 m_decimal, m_group, m_list, m_percent,
+ m_zero, m_minus, m_exponential;
+
+ static const TQString m_infinity;
+ static const TQString m_nan;
+ static const TQChar m_plus;
+
+ static const char *systemLocaleName();
+};
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqmap.cpp b/tqtinterface/qt4/src/tools/tqmap.cpp
new file mode 100644
index 0000000..70d6342
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqmap.cpp
@@ -0,0 +1,257 @@
+/****************************************************************************
+**
+** Implementation of TQMap
+**
+** Created : 990406
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmap.h"
+
+typedef TQMapNodeBase* NodePtr;
+typedef TQMapNodeBase Node;
+
+
+void TQMapPrivateBase::rotateLeft( NodePtr x, NodePtr& root)
+{
+ NodePtr y = x->right;
+ x->right = y->left;
+ if (y->left !=0)
+ y->left->tqparent = x;
+ y->tqparent = x->tqparent;
+ if (x == root)
+ root = y;
+ else if (x == x->tqparent->left)
+ x->tqparent->left = y;
+ else
+ x->tqparent->right = y;
+ y->left = x;
+ x->tqparent = y;
+}
+
+
+void TQMapPrivateBase::rotateRight( NodePtr x, NodePtr& root )
+{
+ NodePtr y = x->left;
+ x->left = y->right;
+ if (y->right != 0)
+ y->right->tqparent = x;
+ y->tqparent = x->tqparent;
+ if (x == root)
+ root = y;
+ else if (x == x->tqparent->right)
+ x->tqparent->right = y;
+ else
+ x->tqparent->left = y;
+ y->right = x;
+ x->tqparent = y;
+}
+
+
+void TQMapPrivateBase::rebalance( NodePtr x, NodePtr& root)
+{
+ x->color = Node::Red;
+ while ( x != root && x->tqparent->color == Node::Red ) {
+ if ( x->tqparent == x->tqparent->tqparent->left ) {
+ NodePtr y = x->tqparent->tqparent->right;
+ if (y && y->color == Node::Red) {
+ x->tqparent->color = Node::Black;
+ y->color = Node::Black;
+ x->tqparent->tqparent->color = Node::Red;
+ x = x->tqparent->tqparent;
+ } else {
+ if (x == x->tqparent->right) {
+ x = x->tqparent;
+ rotateLeft( x, root );
+ }
+ x->tqparent->color = Node::Black;
+ x->tqparent->tqparent->color = Node::Red;
+ rotateRight (x->tqparent->tqparent, root );
+ }
+ } else {
+ NodePtr y = x->tqparent->tqparent->left;
+ if ( y && y->color == Node::Red ) {
+ x->tqparent->color = Node::Black;
+ y->color = Node::Black;
+ x->tqparent->tqparent->color = Node::Red;
+ x = x->tqparent->tqparent;
+ } else {
+ if (x == x->tqparent->left) {
+ x = x->tqparent;
+ rotateRight( x, root );
+ }
+ x->tqparent->color = Node::Black;
+ x->tqparent->tqparent->color = Node::Red;
+ rotateLeft( x->tqparent->tqparent, root );
+ }
+ }
+ }
+ root->color = Node::Black;
+}
+
+
+NodePtr TQMapPrivateBase::removeAndRebalance( NodePtr z, NodePtr& root,
+ NodePtr& leftmost,
+ NodePtr& rightmost )
+{
+ NodePtr y = z;
+ NodePtr x;
+ NodePtr x_tqparent;
+ if (y->left == 0) {
+ x = y->right;
+ } else {
+ if (y->right == 0)
+ x = y->left;
+ else
+ {
+ y = y->right;
+ while (y->left != 0)
+ y = y->left;
+ x = y->right;
+ }
+ }
+ if (y != z) {
+ z->left->tqparent = y;
+ y->left = z->left;
+ if (y != z->right) {
+ x_tqparent = y->tqparent;
+ if (x)
+ x->tqparent = y->tqparent;
+ y->tqparent->left = x;
+ y->right = z->right;
+ z->right->tqparent = y;
+ } else {
+ x_tqparent = y;
+ }
+ if (root == z)
+ root = y;
+ else if (z->tqparent->left == z)
+ z->tqparent->left = y;
+ else
+ z->tqparent->right = y;
+ y->tqparent = z->tqparent;
+ // Swap the colors
+ Node::Color c = y->color;
+ y->color = z->color;
+ z->color = c;
+ y = z;
+ } else {
+ x_tqparent = y->tqparent;
+ if (x)
+ x->tqparent = y->tqparent;
+ if (root == z)
+ root = x;
+ else if (z->tqparent->left == z)
+ z->tqparent->left = x;
+ else
+ z->tqparent->right = x;
+ if ( leftmost == z ) {
+ if (z->right == 0)
+ leftmost = z->tqparent;
+ else
+ leftmost = x->minimum();
+ }
+ if (rightmost == z) {
+ if (z->left == 0)
+ rightmost = z->tqparent;
+ else
+ rightmost = x->maximum();
+ }
+ }
+ if (y->color != Node::Red) {
+ while (x != root && (x == 0 || x->color == Node::Black)) {
+ if (x == x_tqparent->left) {
+ NodePtr w = x_tqparent->right;
+ if (w->color == Node::Red) {
+ w->color = Node::Black;
+ x_tqparent->color = Node::Red;
+ rotateLeft(x_tqparent, root);
+ w = x_tqparent->right;
+ }
+ if ((w->left == 0 || w->left->color == Node::Black) &&
+ (w->right == 0 || w->right->color == Node::Black)) {
+ w->color = Node::Red;
+ x = x_tqparent;
+ x_tqparent = x_tqparent->tqparent;
+ } else {
+ if (w->right == 0 || w->right->color == Node::Black) {
+ if (w->left)
+ w->left->color = Node::Black;
+ w->color = Node::Red;
+ rotateRight(w, root);
+ w = x_tqparent->right;
+ }
+ w->color = x_tqparent->color;
+ x_tqparent->color = Node::Black;
+ if (w->right)
+ w->right->color = Node::Black;
+ rotateLeft(x_tqparent, root);
+ break;
+ }
+ } else {
+ NodePtr w = x_tqparent->left;
+ if (w->color == Node::Red) {
+ w->color = Node::Black;
+ x_tqparent->color = Node::Red;
+ rotateRight(x_tqparent, root);
+ w = x_tqparent->left;
+ }
+ if ((w->right == 0 || w->right->color == Node::Black) &&
+ (w->left == 0 || w->left->color == Node::Black)) {
+ w->color = Node::Red;
+ x = x_tqparent;
+ x_tqparent = x_tqparent->tqparent;
+ } else {
+ if (w->left == 0 || w->left->color == Node::Black) {
+ if (w->right)
+ w->right->color = Node::Black;
+ w->color = Node::Red;
+ rotateLeft(w, root);
+ w = x_tqparent->left;
+ }
+ w->color = x_tqparent->color;
+ x_tqparent->color = Node::Black;
+ if (w->left)
+ w->left->color = Node::Black;
+ rotateRight(x_tqparent, root);
+ break;
+ }
+ }
+ }
+ if (x)
+ x->color = Node::Black;
+ }
+ return y;
+}
diff --git a/tqtinterface/qt4/src/tools/tqmap.h b/tqtinterface/qt4/src/tools/tqmap.h
new file mode 100644
index 0000000..029f4a3
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqmap.h
@@ -0,0 +1,946 @@
+/****************************************************************************
+**
+** Definition of TQMap class
+**
+** Created : 990406
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMAP_H
+#define TQMAP_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqshared.h"
+#include "tqdatastream.h"
+#include "tqpair.h"
+#include "tqvaluelist.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qmap.h>
+
+#endif // USE_QT4
+
+#ifndef TQT_NO_STL
+#include <iterator>
+#include <map>
+#endif
+
+//#define TQT_CHECK_MAP_RANGE
+
+struct TQ_EXPORT TQMapNodeBase
+{
+ enum Color { Red, Black };
+
+ TQMapNodeBase* left;
+ TQMapNodeBase* right;
+ TQMapNodeBase* tqparent;
+
+ Color color;
+
+ TQMapNodeBase* minimum() {
+ TQMapNodeBase* x = this;
+ while ( x->left )
+ x = x->left;
+ return x;
+ }
+
+ TQMapNodeBase* maximum() {
+ TQMapNodeBase* x = this;
+ while ( x->right )
+ x = x->right;
+ return x;
+ }
+};
+
+
+template <class K, class T>
+struct TQMapNode : public TQMapNodeBase
+{
+ TQMapNode( const K& _key, const T& _data ) { data = _data; key = _key; }
+ TQMapNode( const K& _key ) { key = _key; }
+ TQMapNode( const TQMapNode<K,T>& _n ) { key = _n.key; data = _n.data; }
+ TQMapNode() { }
+ T data;
+ K key;
+};
+
+
+template<class K, class T>
+class TQMapIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef TQMapNode< K, T >* NodePtr;
+#ifndef TQT_NO_STL
+ typedef std::bidirectional_iterator_tag iterator_category;
+#endif
+ typedef T value_type;
+#ifndef TQT_NO_STL
+ typedef ptrdiff_t difference_type;
+#else
+ typedef int difference_type;
+#endif
+ typedef T* pointer;
+ typedef T& reference;
+
+ /**
+ * Variables
+ */
+ TQMapNode<K,T>* node;
+
+ /**
+ * Functions
+ */
+ TQMapIterator() : node( 0 ) {}
+ TQMapIterator( TQMapNode<K,T>* p ) : node( p ) {}
+ TQMapIterator( const TQMapIterator<K,T>& it ) : node( it.node ) {}
+
+ bool operator==( const TQMapIterator<K,T>& it ) const { return node == it.node; }
+ bool operator!=( const TQMapIterator<K,T>& it ) const { return node != it.node; }
+ T& operator*() { return node->data; }
+ const T& operator*() const { return node->data; }
+ // UDT for T = x*
+ // T* operator->() const { return &node->data; }
+
+ const K& key() const { return node->key; }
+ T& data() { return node->data; }
+ const T& data() const { return node->data; }
+
+private:
+ int inc();
+ int dec();
+
+public:
+ TQMapIterator<K,T>& operator++() {
+ inc();
+ return *this;
+ }
+
+ TQMapIterator<K,T> operator++(int) {
+ TQMapIterator<K,T> tmp = *this;
+ inc();
+ return tmp;
+ }
+
+ TQMapIterator<K,T>& operator--() {
+ dec();
+ return *this;
+ }
+
+ TQMapIterator<K,T> operator--(int) {
+ TQMapIterator<K,T> tmp = *this;
+ dec();
+ return tmp;
+ }
+};
+
+template <class K, class T>
+TQ_INLINE_TEMPLATES int TQMapIterator<K,T>::inc()
+{
+ TQMapNodeBase* tmp = node;
+ if ( tmp->right ) {
+ tmp = tmp->right;
+ while ( tmp->left )
+ tmp = tmp->left;
+ } else {
+ TQMapNodeBase* y = tmp->tqparent;
+ while (tmp == y->right) {
+ tmp = y;
+ y = y->tqparent;
+ }
+ if (tmp->right != y)
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+}
+
+template <class K, class T>
+TQ_INLINE_TEMPLATES int TQMapIterator<K,T>::dec()
+{
+ TQMapNodeBase* tmp = node;
+ if (tmp->color == TQMapNodeBase::Red &&
+ tmp->tqparent->tqparent == tmp ) {
+ tmp = tmp->right;
+ } else if (tmp->left != 0) {
+ TQMapNodeBase* y = tmp->left;
+ while ( y->right )
+ y = y->right;
+ tmp = y;
+ } else {
+ TQMapNodeBase* y = tmp->tqparent;
+ while (tmp == y->left) {
+ tmp = y;
+ y = y->tqparent;
+ }
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+}
+
+template<class K, class T>
+class TQMapConstIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef TQMapNode< K, T >* NodePtr;
+#ifndef TQT_NO_STL
+ typedef std::bidirectional_iterator_tag iterator_category;
+#endif
+ typedef T value_type;
+#ifndef TQT_NO_STL
+ typedef ptrdiff_t difference_type;
+#else
+ typedef int difference_type;
+#endif
+ typedef const T* pointer;
+ typedef const T& reference;
+
+
+ /**
+ * Variables
+ */
+ TQMapNode<K,T>* node;
+
+ /**
+ * Functions
+ */
+ TQMapConstIterator() : node( 0 ) {}
+ TQMapConstIterator( TQMapNode<K,T>* p ) : node( p ) {}
+ TQMapConstIterator( const TQMapConstIterator<K,T>& it ) : node( it.node ) {}
+ TQMapConstIterator( const TQMapIterator<K,T>& it ) : node( it.node ) {}
+
+ bool operator==( const TQMapConstIterator<K,T>& it ) const { return node == it.node; }
+ bool operator!=( const TQMapConstIterator<K,T>& it ) const { return node != it.node; }
+ const T& operator*() const { return node->data; }
+ // UDT for T = x*
+ // const T* operator->() const { return &node->data; }
+
+ const K& key() const { return node->key; }
+ const T& data() const { return node->data; }
+
+private:
+ int inc();
+ int dec();
+
+public:
+ TQMapConstIterator<K,T>& operator++() {
+ inc();
+ return *this;
+ }
+
+ TQMapConstIterator<K,T> operator++(int) {
+ TQMapConstIterator<K,T> tmp = *this;
+ inc();
+ return tmp;
+ }
+
+ TQMapConstIterator<K,T>& operator--() {
+ dec();
+ return *this;
+ }
+
+ TQMapConstIterator<K,T> operator--(int) {
+ TQMapConstIterator<K,T> tmp = *this;
+ dec();
+ return tmp;
+ }
+};
+
+template <class K, class T>
+TQ_INLINE_TEMPLATES int TQMapConstIterator<K,T>::inc()
+{
+ TQMapNodeBase* tmp = node;
+ if ( tmp->right ) {
+ tmp = tmp->right;
+ while ( tmp->left )
+ tmp = tmp->left;
+ } else {
+ TQMapNodeBase* y = tmp->tqparent;
+ while (tmp == y->right) {
+ tmp = y;
+ y = y->tqparent;
+ }
+ if (tmp->right != y)
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+}
+
+template <class K, class T>
+TQ_INLINE_TEMPLATES int TQMapConstIterator<K,T>::dec()
+{
+ TQMapNodeBase* tmp = node;
+ if (tmp->color == TQMapNodeBase::Red &&
+ tmp->tqparent->tqparent == tmp ) {
+ tmp = tmp->right;
+ } else if (tmp->left != 0) {
+ TQMapNodeBase* y = tmp->left;
+ while ( y->right )
+ y = y->right;
+ tmp = y;
+ } else {
+ TQMapNodeBase* y = tmp->tqparent;
+ while (tmp == y->left) {
+ tmp = y;
+ y = y->tqparent;
+ }
+ tmp = y;
+ }
+ node = (NodePtr)tmp;
+ return 0;
+}
+
+// ### 4.0: rename to something without Private in it. Not really internal.
+class TQ_EXPORT TQMapPrivateBase : public TQShared
+{
+public:
+ TQMapPrivateBase() {
+ node_count = 0;
+ }
+ TQMapPrivateBase( const TQMapPrivateBase* _map) {
+ node_count = _map->node_count;
+ }
+
+ /**
+ * Implementations of basic tree algorithms
+ */
+ void rotateLeft( TQMapNodeBase* x, TQMapNodeBase*& root);
+ void rotateRight( TQMapNodeBase* x, TQMapNodeBase*& root );
+ void rebalance( TQMapNodeBase* x, TQMapNodeBase*& root );
+ TQMapNodeBase* removeAndRebalance( TQMapNodeBase* z, TQMapNodeBase*& root,
+ TQMapNodeBase*& leftmost,
+ TQMapNodeBase*& rightmost );
+
+ /**
+ * Variables
+ */
+ int node_count;
+};
+
+
+template <class Key, class T>
+class TQMapPrivate : public TQMapPrivateBase
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef TQMapIterator< Key, T > Iterator;
+ typedef TQMapConstIterator< Key, T > ConstIterator;
+ typedef TQMapNode< Key, T > Node;
+ typedef TQMapNode< Key, T >* NodePtr;
+
+ /**
+ * Functions
+ */
+ TQMapPrivate();
+ TQMapPrivate( const TQMapPrivate< Key, T >* _map );
+ ~TQMapPrivate() { clear(); delete header; }
+
+ NodePtr copy( NodePtr p );
+ void clear();
+ void clear( NodePtr p );
+
+ Iterator begin() { return Iterator( (NodePtr)(header->left ) ); }
+ Iterator end() { return Iterator( header ); }
+ ConstIterator begin() const { return ConstIterator( (NodePtr)(header->left ) ); }
+ ConstIterator end() const { return ConstIterator( header ); }
+
+ ConstIterator find(const Key& k) const;
+ ConstIterator tqfind(const Key& k) const;
+
+ void remove( Iterator it ) {
+ NodePtr del = (NodePtr) removeAndRebalance( it.node, header->tqparent, header->left, header->right );
+ delete del;
+ --node_count;
+ }
+
+#ifdef TQT_TQMAP_DEBUG
+ void inorder( TQMapNodeBase* x = 0, int level = 0 ){
+ if ( !x )
+ x = header->tqparent;
+ if ( x->left )
+ inorder( x->left, level + 1 );
+ //cout << level << " Key=" << key(x) << " Value=" << ((NodePtr)x)->data << endl;
+ if ( x->right )
+ inorder( x->right, level + 1 );
+ }
+#endif
+
+#if 0
+ Iterator insertMulti(const Key& v){
+ TQMapNodeBase* y = header;
+ TQMapNodeBase* x = header->tqparent;
+ while (x != 0){
+ y = x;
+ x = ( v < key(x) ) ? x->left : x->right;
+ }
+ return insert(x, y, v);
+ }
+#endif
+
+ Iterator insertSingle( const Key& k );
+ Iterator insert( TQMapNodeBase* x, TQMapNodeBase* y, const Key& k );
+
+protected:
+ /**
+ * Helpers
+ */
+ const Key& key( TQMapNodeBase* b ) const { return ((NodePtr)b)->key; }
+
+ /**
+ * Variables
+ */
+ NodePtr header;
+};
+
+
+template <class Key, class T>
+TQ_INLINE_TEMPLATES TQMapPrivate<Key,T>::TQMapPrivate() {
+ header = new Node;
+ header->color = TQMapNodeBase::Red; // Mark the header
+ header->tqparent = 0;
+ header->left = header->right = header;
+}
+template <class Key, class T>
+TQ_INLINE_TEMPLATES TQMapPrivate<Key,T>::TQMapPrivate( const TQMapPrivate< Key, T >* _map ) : TQMapPrivateBase( _map ) {
+ header = new Node;
+ header->color = TQMapNodeBase::Red; // Mark the header
+ if ( _map->header->tqparent == 0 ) {
+ header->tqparent = 0;
+ header->left = header->right = header;
+ } else {
+ header->tqparent = copy( (NodePtr)(_map->header->tqparent) );
+ header->tqparent->tqparent = header;
+ header->left = header->tqparent->minimum();
+ header->right = header->tqparent->maximum();
+ }
+}
+
+template <class Key, class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQMapPrivate<Key,T>::NodePtr TQMapPrivate<Key,T>::copy( TQ_TYPENAME TQMapPrivate<Key,T>::NodePtr p )
+{
+ if ( !p )
+ return 0;
+ NodePtr n = new Node( *p );
+ n->color = p->color;
+ if ( p->left ) {
+ n->left = copy( (NodePtr)(p->left) );
+ n->left->tqparent = n;
+ } else {
+ n->left = 0;
+ }
+ if ( p->right ) {
+ n->right = copy( (NodePtr)(p->right) );
+ n->right->tqparent = n;
+ } else {
+ n->right = 0;
+ }
+ return n;
+}
+
+template <class Key, class T>
+TQ_INLINE_TEMPLATES void TQMapPrivate<Key,T>::clear()
+{
+ clear( (NodePtr)(header->tqparent) );
+ header->color = TQMapNodeBase::Red;
+ header->tqparent = 0;
+ header->left = header->right = header;
+ node_count = 0;
+}
+
+template <class Key, class T>
+TQ_INLINE_TEMPLATES void TQMapPrivate<Key,T>::clear( TQ_TYPENAME TQMapPrivate<Key,T>::NodePtr p )
+{
+ while ( p != 0 ) {
+ clear( (NodePtr)p->right );
+ NodePtr y = (NodePtr)p->left;
+ delete p;
+ p = y;
+ }
+}
+
+template <class Key, class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQMapPrivate<Key,T>::ConstIterator TQMapPrivate<Key,T>::find(const Key& k) const
+{
+ return tqfind(k);
+}
+
+template <class Key, class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQMapPrivate<Key,T>::ConstIterator TQMapPrivate<Key,T>::tqfind(const Key& k) const
+{
+ TQMapNodeBase* y = header; // Last node
+ TQMapNodeBase* x = header->tqparent; // Root node.
+
+ while ( x != 0 ) {
+ // If as k <= key(x) go left
+ if ( !( key(x) < k ) ) {
+ y = x;
+ x = x->left;
+ } else {
+ x = x->right;
+ }
+ }
+
+ // Was k bigger/smaller then the biggest/smallest
+ // element of the tree ? Return end()
+ if ( y == header || k < key(y) )
+ return ConstIterator( header );
+ return ConstIterator( (NodePtr)y );
+}
+
+template <class Key, class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQMapPrivate<Key,T>::Iterator TQMapPrivate<Key,T>::insertSingle( const Key& k )
+{
+ // Search correct position in the tree
+ TQMapNodeBase* y = header;
+ TQMapNodeBase* x = header->tqparent;
+ bool result = TRUE;
+ while ( x != 0 ) {
+ result = ( k < key(x) );
+ y = x;
+ x = result ? x->left : x->right;
+ }
+ // Get iterator on the last not empty one
+ Iterator j( (NodePtr)y );
+ if ( result ) {
+ // Smaller then the leftmost one ?
+ if ( j == begin() ) {
+ return insert(x, y, k );
+ } else {
+ // Perhaps daddy is the right one ?
+ --j;
+ }
+ }
+ // Really bigger ?
+ if ( (j.node->key) < k )
+ return insert(x, y, k );
+ // We are going to tqreplace a node
+ return j;
+}
+
+
+template <class Key, class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQMapPrivate<Key,T>::Iterator TQMapPrivate<Key,T>::insert( TQMapNodeBase* x, TQMapNodeBase* y, const Key& k )
+{
+ NodePtr z = new Node( k );
+ if (y == header || x != 0 || k < key(y) ) {
+ y->left = z; // also makes leftmost = z when y == header
+ if ( y == header ) {
+ header->tqparent = z;
+ header->right = z;
+ } else if ( y == header->left )
+ header->left = z; // maintain leftmost pointing to min node
+ } else {
+ y->right = z;
+ if ( y == header->right )
+ header->right = z; // maintain rightmost pointing to max node
+ }
+ z->tqparent = y;
+ z->left = 0;
+ z->right = 0;
+ rebalance( z, header->tqparent );
+ ++node_count;
+ return Iterator(z);
+}
+
+
+#ifdef TQT_CHECK_RANGE
+# if !defined( TQT_NO_DEBUG ) && defined( TQT_CHECK_MAP_RANGE )
+# define TQT_CHECK_INVALID_MAP_ELEMENT if ( empty() ) qWarning( "TQMap: Warning invalid element" )
+# define TQT_CHECK_INVALID_MAP_ELEMENT_FATAL TQ_ASSERT( !empty() );
+# else
+# define TQT_CHECK_INVALID_MAP_ELEMENT
+# define TQT_CHECK_INVALID_MAP_ELEMENT_FATAL
+# endif
+#else
+# define TQT_CHECK_INVALID_MAP_ELEMENT
+# define TQT_CHECK_INVALID_MAP_ELEMENT_FATAL
+#endif
+
+template <class T> class TQDeepCopy;
+
+template<class Key, class T>
+class TQMap
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef Key key_type;
+ typedef T mapped_type;
+ typedef TQPair<const key_type, mapped_type> value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+#ifndef TQT_NO_STL
+ typedef ptrdiff_t difference_type;
+#else
+ typedef int difference_type;
+#endif
+ typedef size_t size_type;
+ typedef TQMapIterator<Key,T> iterator;
+ typedef TQMapConstIterator<Key,T> const_iterator;
+ typedef TQPair<iterator,bool> insert_pair;
+
+ typedef TQMapIterator< Key, T > Iterator;
+ typedef TQMapConstIterator< Key, T > ConstIterator;
+ typedef T ValueType;
+ typedef TQMapPrivate< Key, T > Priv;
+
+ /**
+ * API
+ */
+ TQMap()
+ {
+ sh = new TQMapPrivate< Key, T >;
+ }
+ TQMap( const TQMap<Key,T>& m )
+ {
+ sh = m.sh; sh->ref();
+ }
+
+#ifndef TQT_NO_STL
+ TQMap( const std::map<Key,T>& m )
+ {
+ sh = new TQMapPrivate<Key,T>;
+ TQ_TYPENAME std::map<Key,T>::const_iterator it = m.begin();
+ for ( ; it != m.end(); ++it ) {
+ value_type p( (*it).first, (*it).second );
+ insert( p );
+ }
+ }
+#endif
+ ~TQMap()
+ {
+ if ( sh->deref() )
+ delete sh;
+ }
+ TQMap<Key,T>& operator= ( const TQMap<Key,T>& m );
+#ifndef TQT_NO_STL
+ TQMap<Key,T>& operator= ( const std::map<Key,T>& m )
+ {
+ clear();
+ TQ_TYPENAME std::map<Key,T>::const_iterator it = m.begin();
+ for ( ; it != m.end(); ++it ) {
+ value_type p( (*it).first, (*it).second );
+ insert( p );
+ }
+ return *this;
+ }
+#endif
+
+#ifdef USE_QT4
+ // Interoperability
+ TQMap(const QMap<Key,T>& m)
+ {
+ QMapIterator<Key,T> i(m);
+ while (i.hasNext()) {
+ i.next();
+ insert(i.key(), i.value());
+ }
+ }
+ TQMap<Key,T>& operator= (const QMap<Key,T>& m)
+ {
+ this->clear();
+ QMapIterator<Key,T> i(m);
+ while (i.hasNext()) {
+ i.next();
+ insert(i.key(), i.value());
+ }
+ return *this;
+ }
+
+ // FIXME BROKEN!
+ operator QMap<Key,T>();
+ operator QMap<Key,T>() const;
+#endif // USE_QT4
+
+ iterator begin() { detach(); return sh->begin(); }
+ iterator end() { detach(); return sh->end(); }
+ const_iterator begin() const { return ((const Priv*)sh)->begin(); }
+ const_iterator end() const { return ((const Priv*)sh)->end(); }
+ const_iterator constBegin() const { return begin(); }
+ const_iterator constEnd() const { return end(); }
+
+ iterator tqreplace( const Key& k, const T& v )
+ {
+ remove( k );
+ return insert( k, v );
+ }
+
+ size_type size() const
+ {
+ return sh->node_count;
+ }
+ bool empty() const
+ {
+ return sh->node_count == 0;
+ }
+ TQPair<iterator,bool> insert( const value_type& x );
+
+ void erase( iterator it )
+ {
+ detach();
+ sh->remove( it );
+ }
+ void erase( const key_type& k );
+ size_type count( const key_type& k ) const;
+ T& operator[] ( const Key& k );
+ void clear();
+
+ iterator tqfind ( const Key& k )
+ {
+ detach();
+ return iterator( sh->tqfind( k ).node );
+ }
+ const_iterator tqfind ( const Key& k ) const { return sh->tqfind( k ); }
+
+ iterator find ( const Key& k ) { return tqfind(k); }
+ const_iterator find ( const Key& k ) const { return tqfind(k); }
+
+ const T& operator[] ( const Key& k ) const
+ { TQT_CHECK_INVALID_MAP_ELEMENT; return sh->tqfind( k ).data(); }
+ bool tqcontains ( const Key& k ) const
+ { return tqfind( k ) != end(); }
+ //{ return sh->tqfind( k ) != ((const Priv*)sh)->end(); }
+
+ size_type count() const { return sh->node_count; }
+
+ TQValueList<Key> keys() const {
+ TQValueList<Key> r;
+ for (const_iterator i=begin(); i!=end(); ++i)
+ r.append(i.key());
+ return r;
+ }
+
+ TQValueList<T> values() const {
+ TQValueList<T> r;
+ for (const_iterator i=begin(); i!=end(); ++i)
+ r.append(*i);
+ return r;
+ }
+
+ bool isEmpty() const { return sh->node_count == 0; }
+
+ iterator insert( const Key& key, const T& value, bool overwrite = TRUE );
+ void remove( iterator it ) { detach(); sh->remove( it ); }
+ void remove( const Key& k );
+
+#if defined(TQ_FULL_TEMPLATE_INSTANTIATION)
+ bool operator==( const TQMap<Key,T>& ) const { return FALSE; }
+#ifndef TQT_NO_STL
+ bool operator==( const std::map<Key,T>& ) const { return FALSE; }
+#endif
+#endif
+
+protected:
+ /**
+ * Helpers
+ */
+ void detach() { if ( sh->count > 1 ) detachInternal(); }
+
+ Priv* sh;
+private:
+ void detachInternal();
+
+ friend class TQDeepCopy< TQMap<Key,T> >;
+};
+
+#ifdef USE_QT4
+
+// Interoperability
+template<class Key, class T>
+TQMap<Key,T>::operator QMap<Key,T>() {
+ QMap<Key,T> map;
+ iterator it;
+ for ( it = this->begin(); it != this->end(); ++it) {
+ map.insert(it.key(), it.data());
+ }
+ return map;
+}
+
+// Interoperability
+template<class Key, class T>
+TQMap<Key,T>::operator QMap<Key,T>() const {
+ QMap<Key,T> map;
+ const_iterator it;
+ for ( it = this->begin(); it != this->end(); ++it) {
+ map.insert(it.key(), it.data());
+ }
+ return map;
+}
+
+#endif // USE_QT4
+
+template<class Key, class T>
+TQ_INLINE_TEMPLATES TQMap<Key,T>& TQMap<Key,T>::operator= ( const TQMap<Key,T>& m )
+{
+ m.sh->ref();
+ if ( sh->deref() )
+ delete sh;
+ sh = m.sh;
+ return *this;
+}
+
+template<class Key, class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQMap<Key,T>::insert_pair TQMap<Key,T>::insert( const TQ_TYPENAME TQMap<Key,T>::value_type& x )
+{
+ detach();
+ size_type n = size();
+ iterator it = sh->insertSingle( x.first );
+ bool inserted = FALSE;
+ if ( n < size() ) {
+ inserted = TRUE;
+ it.data() = x.second;
+ }
+ return TQPair<iterator,bool>( it, inserted );
+}
+
+template<class Key, class T>
+TQ_INLINE_TEMPLATES void TQMap<Key,T>::erase( const Key& k )
+{
+ detach();
+ iterator it( sh->tqfind( k ).node );
+ if ( it != end() )
+ sh->remove( it );
+}
+
+template<class Key, class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQMap<Key,T>::size_type TQMap<Key,T>::count( const Key& k ) const
+{
+ const_iterator it( sh->tqfind( k ).node );
+ if ( it != end() ) {
+ size_type c = 0;
+ while ( it != end() ) {
+ ++it;
+ ++c;
+ }
+ return c;
+ }
+ return 0;
+}
+
+template<class Key, class T>
+TQ_INLINE_TEMPLATES T& TQMap<Key,T>::operator[] ( const Key& k )
+{
+ detach();
+ TQMapNode<Key,T>* p = sh->tqfind( k ).node;
+ if ( p != sh->end().node )
+ return p->data;
+ return insert( k, T() ).data();
+}
+
+template<class Key, class T>
+TQ_INLINE_TEMPLATES void TQMap<Key,T>::clear()
+{
+ if ( sh->count == 1 )
+ sh->clear();
+ else {
+ sh->deref();
+ sh = new TQMapPrivate<Key,T>;
+ }
+}
+
+template<class Key, class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQMap<Key,T>::iterator TQMap<Key,T>::insert( const Key& key, const T& value, bool overwrite )
+{
+ detach();
+ size_type n = size();
+ iterator it = sh->insertSingle( key );
+ if ( overwrite || n < size() )
+ it.data() = value;
+ return it;
+}
+
+template<class Key, class T>
+TQ_INLINE_TEMPLATES void TQMap<Key,T>::remove( const Key& k )
+{
+ detach();
+ iterator it( sh->tqfind( k ).node );
+ if ( it != end() )
+ sh->remove( it );
+}
+
+template<class Key, class T>
+TQ_INLINE_TEMPLATES void TQMap<Key,T>::detachInternal()
+{
+ sh->deref(); sh = new TQMapPrivate<Key,T>( sh );
+}
+
+
+#ifndef TQT_NO_DATASTREAM
+template<class Key, class T>
+TQ_INLINE_TEMPLATES TQDataStream& operator>>( TQDataStream& s, TQMap<Key,T>& m ) {
+ m.clear();
+ TQ_UINT32 c;
+ s >> c;
+ for( TQ_UINT32 i = 0; i < c; ++i ) {
+ Key k; T t;
+ s >> k >> t;
+ m.insert( k, t );
+ if ( s.atEnd() )
+ break;
+ }
+ return s;
+}
+
+
+template<class Key, class T>
+TQ_INLINE_TEMPLATES TQDataStream& operator<<( TQDataStream& s, const TQMap<Key,T>& m ) {
+ s << (TQ_UINT32)m.size();
+ TQMapConstIterator<Key,T> it = m.begin();
+ for( ; it != m.end(); ++it )
+ s << it.key() << it.data();
+ return s;
+}
+#endif
+
+#define TQ_DEFINED_TQMAP
+#include "tqwinexport.h"
+#endif // TQMAP_H
diff --git a/tqtinterface/qt4/src/tools/tqmemarray.h b/tqtinterface/qt4/src/tools/tqmemarray.h
new file mode 100644
index 0000000..99e00b0
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqmemarray.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Definition of TQMemArray template/macro class
+**
+** Created : 930906
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMEMARRAY_H
+#define TQMEMARRAY_H
+
+#ifndef TQT_H
+#include "tqgarray.h"
+#endif // TQT_H
+
+
+template<class type>
+class TQMemArray : public TQGArray
+{
+public:
+ typedef type* Iterator;
+ typedef const type* ConstIterator;
+ typedef type ValueType;
+
+protected:
+ TQMemArray( int, int ) : TQGArray( 0, 0 ) {}
+
+public:
+ TQMemArray() {}
+ TQMemArray( int size ) : TQGArray(size*sizeof(type)) {} // ### 4.0 TQ_EXPLICIT
+ TQMemArray( const TQMemArray<type> &a ) : TQGArray(a) {}
+ ~TQMemArray() {}
+ TQMemArray<type> &operator=(const TQMemArray<type> &a)
+ { return (TQMemArray<type>&)TQGArray::assign(a); }
+ type *data() const { return (type *)TQGArray::data(); }
+ uint nrefs() const { return TQGArray::nrefs(); }
+ uint size() const { return TQGArray::size()/sizeof(type); }
+ uint count() const { return size(); }
+ bool isEmpty() const { return TQGArray::size() == 0; }
+ bool isNull() const { return TQGArray::data() == 0; }
+ bool resize( uint size ) { return TQGArray::resize(size*sizeof(type)); }
+ bool resize( uint size, Optimization optim ) { return TQGArray::resize(size*sizeof(type), optim); }
+ bool truncate( uint pos ) { return TQGArray::resize(pos*sizeof(type)); }
+ bool fill( const type &d, int size = -1 )
+ { return TQGArray::fill((char*)&d,size,sizeof(type) ); }
+ void detach() { TQGArray::detach(); }
+ TQMemArray<type> copy() const
+ { TQMemArray<type> tmp; return tmp.duplicate(*this); }
+ TQMemArray<type>& assign( const TQMemArray<type>& a )
+ { return (TQMemArray<type>&)TQGArray::assign(a); }
+ TQMemArray<type>& assign( const type *a, uint n )
+ { return (TQMemArray<type>&)TQGArray::assign((char*)a,n*sizeof(type)); }
+ TQMemArray<type>& duplicate( const TQMemArray<type>& a )
+ { return (TQMemArray<type>&)TQGArray::duplicate(a); }
+ TQMemArray<type>& duplicate( const type *a, uint n )
+ { return (TQMemArray<type>&)TQGArray::duplicate((char*)a,n*sizeof(type)); }
+ TQMemArray<type>& setRawData( const type *a, uint n )
+ { return (TQMemArray<type>&)TQGArray::setRawData((char*)a,
+ n*sizeof(type)); }
+ void resetRawData( const type *a, uint n )
+ { TQGArray::resetRawData((char*)a,n*sizeof(type)); }
+ int tqfind( const type &d, uint i=0 ) const
+ { return TQGArray::tqfind((char*)&d,i,sizeof(type)); }
+ int tqcontains( const type &d ) const
+ { return TQGArray::tqcontains((char*)&d,sizeof(type)); }
+ void sort() { TQGArray::sort(sizeof(type)); }
+ int bsearch( const type &d ) const
+ { return TQGArray::bsearch((const char*)&d,sizeof(type)); }
+ // ### TQt 4.0: maybe provide uint overload as work-around for MSVC bug
+ type& operator[]( int i ) const
+ { return (type &)(*(type *)TQGArray::at(i*sizeof(type))); }
+ type& at( uint i ) const
+ { return (type &)(*(type *)TQGArray::at(i*sizeof(type))); }
+ type& tqat( uint i ) const
+ { return (type &)(*(type *)TQGArray::at(i*sizeof(type))); }
+ operator const type*() const { return (const type *)TQGArray::data(); }
+ bool operator==( const TQMemArray<type> &a ) const { return isEqual(a); }
+ bool operator!=( const TQMemArray<type> &a ) const { return !isEqual(a); }
+ Iterator begin() { return data(); }
+ Iterator end() { return data() + size(); }
+ ConstIterator begin() const { return data(); }
+ ConstIterator end() const { return data() + size(); }
+};
+
+#ifndef TQT_NO_COMPAT
+#define TQArray TQMemArray
+#endif
+
+#define TQ_DEFINED_TQMEMARRAY
+#include "tqwinexport.h"
+#endif // TQARRAY_H
diff --git a/tqtinterface/qt4/src/tools/tqmutex.h b/tqtinterface/qt4/src/tools/tqmutex.h
new file mode 100644
index 0000000..2d0d8b3
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqmutex.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Definition of TQMutex class
+**
+** Created : 931107
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMUTEX_H
+#define TQMUTEX_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#if defined(TQT_THREAD_SUPPORT)
+
+class TQMutexPrivate;
+
+const int TQ_MUTEX_NORMAL = 0;
+const int TQ_MUTEX_RECURSIVE = 1;
+
+class TQ_EXPORT TQMutex
+{
+ friend class TQThread;
+ friend class TQWaitCondition;
+ friend class TQWaitConditionPrivate;
+
+public:
+ TQMutex(bool recursive = FALSE);
+ virtual ~TQMutex();
+
+ void lock();
+ void unlock();
+ bool locked();
+ bool tryLock();
+
+private:
+ TQMutexPrivate * d;
+
+#if defined(TQ_DISABLE_COPY)
+ TQMutex( const TQMutex & );
+ TQMutex &operator=( const TQMutex & );
+#endif
+};
+
+class TQ_EXPORT TQMutexLocker
+{
+public:
+ TQMutexLocker( TQMutex * );
+ ~TQMutexLocker();
+
+ TQMutex *mutex() const;
+
+private:
+ TQMutex *mtx;
+
+#if defined(TQ_DISABLE_COPY)
+ TQMutexLocker( const TQMutexLocker & );
+ TQMutexLocker &operator=( const TQMutexLocker & );
+#endif
+};
+
+inline TQMutexLocker::TQMutexLocker( TQMutex *m )
+ : mtx( m )
+{
+ if ( mtx ) mtx->lock();
+}
+
+inline TQMutexLocker::~TQMutexLocker()
+{
+ if ( mtx ) mtx->unlock();
+}
+
+inline TQMutex *TQMutexLocker::mutex() const
+{
+ return mtx;
+}
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqmutex_p.h b/tqtinterface/qt4/src/tools/tqmutex_p.h
new file mode 100644
index 0000000..0397d3e
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqmutex_p.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** TQMutex private class declarations
+**
+** Created : 20012507
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMUTEX_P_H
+#define TQMUTEX_P_H
+
+#ifndef TQT_H
+#endif // TQT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qmutex_unix.cpp and qmutex_win.cpp. This header file may change
+// from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+
+class TQMutexPrivate {
+public:
+ // TQ_MUTEX_T is defined in the various *.cpp files
+ TQ_MUTEX_T handle;
+
+ virtual ~TQMutexPrivate();
+
+ virtual void lock() = 0;
+ virtual void unlock() = 0;
+ virtual bool locked() = 0;
+ virtual bool trylock() = 0;
+ virtual int type() const = 0;
+};
+
+
+#endif // TQMUTEX_P_H
diff --git a/tqtinterface/qt4/src/tools/tqmutex_unix.cpp b/tqtinterface/qt4/src/tools/tqmutex_unix.cpp
new file mode 100644
index 0000000..540a128
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqmutex_unix.cpp
@@ -0,0 +1,695 @@
+/****************************************************************************
+**
+** TQMutex class for Unix
+**
+** Created : 20010725
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#if defined(TQT_THREAD_SUPPORT)
+
+#include "tqplatformdefs.h"
+
+typedef pthread_mutex_t TQ_MUTEX_T;
+
+// POSIX threads mutex types
+#if ((defined(PTHREAD_MUTEX_RECURSIVE) && defined(PTHREAD_MUTEX_DEFAULT)) || \
+ defined(TQ_OS_FREEBSD)) && !defined(TQ_OS_UNIXWARE) && !defined(TQ_OS_SOLARIS) && \
+ !defined(TQ_OS_MAC)
+// POSIX 1003.1c-1995 - We love this OS
+# define TQ_MUTEX_SET_TYPE(a, b) pthread_mutexattr_settype((a), (b))
+# if defined(TQT_CHECK_RANGE)
+# define TQ_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_ERRORCHECK
+# else
+# define TQ_NORMAL_MUTEX_TYPE PTHREAD_MUTEX_DEFAULT
+# endif
+# define TQ_RECURSIVE_MUTEX_TYPE PTHREAD_MUTEX_RECURSIVE
+#elif defined(MUTEX_NONRECURSIVE_NP) && defined(MUTEX_RECURSIVE_NP)
+// POSIX 1003.4a pthreads draft extensions
+# define TQ_MUTEX_SET_TYPE(a, b) pthread_mutexattr_setkind_np((a), (b));
+# define TQ_NORMAL_MUTEX_TYPE MUTEX_NONRECURSIVE_NP
+# define TQ_RECURSIVE_MUTEX_TYPE MUTEX_RECURSIVE_NP
+#else
+// Unknown mutex types - skip them
+# define TQ_MUTEX_SET_TYPE(a, b)
+# undef TQ_NORMAL_MUTEX_TYPE
+# undef TQ_RECURSIVE_MUTEX_TYPE
+#endif
+
+#include "tqmutex.h"
+#include "tqmutex_p.h"
+
+#include <errno.h>
+#include <string.h>
+
+
+// Private class declarations
+
+class TQRealMutexPrivate : public TQMutexPrivate {
+public:
+ TQRealMutexPrivate(bool = FALSE);
+
+ void lock();
+ void unlock();
+ bool locked();
+ bool trylock();
+ int type() const;
+
+ bool recursive;
+};
+
+#ifndef TQ_RECURSIVE_MUTEX_TYPE
+class TQRecursiveMutexPrivate : public TQMutexPrivate
+{
+public:
+ TQRecursiveMutexPrivate();
+ ~TQRecursiveMutexPrivate();
+
+ void lock();
+ void unlock();
+ bool locked();
+ bool trylock();
+ int type() const;
+
+ int count;
+ unsigned long owner;
+ pthread_mutex_t handle2;
+};
+#endif // !TQ_RECURSIVE_MUTEX_TYPE
+
+
+// Private class implementation
+
+// base destructor
+TQMutexPrivate::~TQMutexPrivate()
+{
+ int ret = pthread_mutex_destroy(&handle);
+
+#ifdef TQT_CHECK_RANGE
+ if ( ret )
+ qWarning( "Mutex destroy failure: %s", strerror( ret ) );
+#endif
+}
+
+// real mutex class
+TQRealMutexPrivate::TQRealMutexPrivate(bool recurs)
+ : recursive(recurs)
+{
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ TQ_MUTEX_SET_TYPE(&attr, recursive ? TQ_RECURSIVE_MUTEX_TYPE : TQ_NORMAL_MUTEX_TYPE);
+ TQ_UNUSED(recursive);
+ int ret = pthread_mutex_init(&handle, &attr);
+ pthread_mutexattr_destroy(&attr);
+
+#ifdef TQT_CHECK_RANGE
+ if( ret )
+ qWarning( "Mutex init failure: %s", strerror( ret ) );
+#endif // TQT_CHECK_RANGE
+}
+
+void TQRealMutexPrivate::lock()
+{
+ int ret = pthread_mutex_lock(&handle);
+
+#ifdef TQT_CHECK_RANGE
+ if (ret)
+ qWarning("Mutex lock failure: %s", strerror(ret));
+#endif
+}
+
+void TQRealMutexPrivate::unlock()
+{
+ int ret = pthread_mutex_unlock(&handle);
+
+#ifdef TQT_CHECK_RANGE
+ if (ret)
+ qWarning("Mutex unlock failure: %s", strerror(ret));
+#endif
+}
+
+bool TQRealMutexPrivate::locked()
+{
+ int ret = pthread_mutex_trylock(&handle);
+
+ if (ret == EBUSY) {
+ return TRUE;
+ } else if (ret) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("Mutex locktest failure: %s", strerror(ret));
+#endif
+ } else
+ pthread_mutex_unlock(&handle);
+
+ return FALSE;
+}
+
+bool TQRealMutexPrivate::trylock()
+{
+ int ret = pthread_mutex_trylock(&handle);
+
+ if (ret == EBUSY) {
+ return FALSE;
+ } else if (ret) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("Mutex trylock failure: %s", strerror(ret));
+#endif
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int TQRealMutexPrivate::type() const
+{
+ return recursive ? TQ_MUTEX_RECURSIVE : TQ_MUTEX_NORMAL;
+}
+
+
+#ifndef TQ_RECURSIVE_MUTEX_TYPE
+TQRecursiveMutexPrivate::TQRecursiveMutexPrivate()
+ : count(0), owner(0)
+{
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ TQ_MUTEX_SET_TYPE(&attr, TQ_NORMAL_MUTEX_TYPE);
+ int ret = pthread_mutex_init(&handle, &attr);
+ pthread_mutexattr_destroy(&attr);
+
+# ifdef TQT_CHECK_RANGE
+ if (ret)
+ qWarning( "Mutex init failure: %s", strerror(ret) );
+# endif
+
+ pthread_mutexattr_init(&attr);
+ ret = pthread_mutex_init( &handle2, &attr );
+ pthread_mutexattr_destroy(&attr);
+
+# ifdef TQT_CHECK_RANGE
+ if (ret)
+ qWarning( "Mutex init failure: %s", strerror(ret) );
+# endif
+}
+
+TQRecursiveMutexPrivate::~TQRecursiveMutexPrivate()
+{
+ int ret = pthread_mutex_destroy(&handle2);
+
+# ifdef TQT_CHECK_RANGE
+ if (ret)
+ qWarning( "Mutex destroy failure: %s", strerror(ret) );
+# endif
+}
+
+void TQRecursiveMutexPrivate::lock()
+{
+ pthread_mutex_lock(&handle2);
+
+ if (count > 0 && owner == (unsigned long) pthread_self()) {
+ count++;
+ } else {
+ pthread_mutex_unlock(&handle2);
+ pthread_mutex_lock(&handle);
+ pthread_mutex_lock(&handle2);
+ count = 1;
+ owner = (unsigned long) pthread_self();
+ }
+
+ pthread_mutex_unlock(&handle2);
+}
+
+void TQRecursiveMutexPrivate::unlock()
+{
+ pthread_mutex_lock(&handle2);
+
+ if (owner == (unsigned long) pthread_self()) {
+ // do nothing if the count is already 0... to reflect the behaviour described
+ // in the docs
+ if (count && (--count) < 1) {
+ count = 0;
+ pthread_mutex_unlock(&handle);
+ }
+ } else {
+#ifdef TQT_CHECK_RANGE
+ qWarning("TQMutex::unlock: unlock from different thread than locker");
+ qWarning(" was locked by %d, unlock attempt from %d",
+ (int)owner, (int)pthread_self());
+#endif
+ }
+
+ pthread_mutex_unlock(&handle2);
+}
+
+bool TQRecursiveMutexPrivate::locked()
+{
+ pthread_mutex_lock(&handle2);
+
+ bool ret;
+ int code = pthread_mutex_trylock(&handle);
+
+ if (code == EBUSY) {
+ ret = TRUE;
+ } else {
+#ifdef TQT_CHECK_RANGE
+ if (code)
+ qWarning("Mutex trylock failure: %s", strerror(code));
+#endif
+
+ pthread_mutex_unlock(&handle);
+ ret = FALSE;
+ }
+
+ pthread_mutex_unlock(&handle2);
+
+ return ret;
+}
+
+bool TQRecursiveMutexPrivate::trylock()
+{
+ bool ret = TRUE;
+
+ pthread_mutex_lock(&handle2);
+
+ if ( count > 0 && owner == (unsigned long) pthread_self() ) {
+ count++;
+ } else {
+ int code = pthread_mutex_trylock(&handle);
+
+ if (code == EBUSY) {
+ ret = FALSE;
+ } else if (code) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("Mutex trylock failure: %s", strerror(code));
+#endif
+ ret = FALSE;
+ } else {
+ count = 1;
+ owner = (unsigned long) pthread_self();
+ }
+ }
+
+ pthread_mutex_unlock(&handle2);
+
+ return ret;
+}
+
+int TQRecursiveMutexPrivate::type() const
+{
+ return TQ_MUTEX_RECURSIVE;
+}
+
+#endif // !TQ_RECURSIVE_MUTEX_TYPE
+
+
+/*!
+ \class TQMutex tqmutex.h
+ \threadsafe
+ \brief The TQMutex class provides access serialization between threads.
+
+ \ingroup thread
+ \ingroup environment
+
+ The purpose of a TQMutex is to protect an object, data structure or
+ section of code so that only one thread can access it at a time
+ (This is similar to the Java \c synchronized keyword). For
+ example, say there is a method which prints a message to the user
+ on two lines:
+
+ \code
+ int number = 6;
+
+ void method1()
+ {
+ number *= 5;
+ number /= 4;
+ }
+
+ void method2()
+ {
+ number *= 3;
+ number /= 2;
+ }
+ \endcode
+
+ If these two methods are called in succession, the following happens:
+
+ \code
+ // method1()
+ number *= 5; // number is now 30
+ number /= 4; // number is now 7
+
+ // method2()
+ number *= 3; // nubmer is now 21
+ number /= 2; // number is now 10
+ \endcode
+
+ If these two methods are called simultaneously from two threads then the
+ following sequence could result:
+
+ \code
+ // Thread 1 calls method1()
+ number *= 5; // number is now 30
+
+ // Thread 2 calls method2().
+ //
+ // Most likely Thread 1 has been put to sleep by the operating
+ // system to allow Thread 2 to run.
+ number *= 3; // number is now 90
+ number /= 2; // number is now 45
+
+ // Thread 1 finishes executing.
+ number /= 4; // number is now 11, instead of 10
+ \endcode
+
+ If we add a mutex, we should get the result we want:
+
+ \code
+ TQMutex mutex;
+ int number = 6;
+
+ void method1()
+ {
+ mutex.lock();
+ number *= 5;
+ number /= 4;
+ mutex.unlock();
+ }
+
+ void method2()
+ {
+ mutex.lock();
+ number *= 3;
+ number /= 2;
+ mutex.unlock();
+ }
+ \endcode
+
+ Then only one thread can modify \c number at any given time and
+ the result is correct. This is a trivial example, of course, but
+ applies to any other case where things need to happen in a
+ particular sequence.
+
+ When you call lock() in a thread, other threads that try to call
+ lock() in the same place will block until the thread that got the
+ lock calls unlock(). A non-blocking alternative to lock() is
+ tryLock().
+*/
+
+/*!
+ Constructs a new mutex. The mutex is created in an unlocked state.
+ A recursive mutex is created if \a recursive is TRUE; a normal
+ mutex is created if \a recursive is FALSE (the default). With a
+ recursive mutex, a thread can lock the same mutex multiple times
+ and it will not be unlocked until a corresponding number of
+ unlock() calls have been made.
+*/
+TQMutex::TQMutex(bool recursive)
+{
+#ifndef TQ_RECURSIVE_MUTEX_TYPE
+ if ( recursive )
+ d = new TQRecursiveMutexPrivate();
+ else
+#endif // !TQ_RECURSIVE_MUTEX_TYPE
+ d = new TQRealMutexPrivate(recursive);
+}
+
+/*!
+ Destroys the mutex.
+
+ \warning If you destroy a mutex that still holds a lock the
+ resultant behavior is undefined.
+*/
+TQMutex::~TQMutex()
+{
+ delete d;
+}
+
+/*!
+ Attempt to lock the mutex. If another thread has locked the mutex
+ then this call will \e block until that thread has unlocked it.
+
+ \sa unlock(), locked()
+*/
+void TQMutex::lock()
+{
+ d->lock();
+}
+
+/*!
+ Unlocks the mutex. Attempting to unlock a mutex in a different
+ thread to the one that locked it results in an error. Unlocking a
+ mutex that is not locked results in undefined behaviour (varies
+ between different Operating Systems' thread implementations).
+
+ \sa lock(), locked()
+*/
+void TQMutex::unlock()
+{
+ d->unlock();
+}
+
+/*!
+ Returns TRUE if the mutex is locked by another thread; otherwise
+ returns FALSE.
+
+ \warning Due to differing implementations of recursive mutexes on
+ various platforms, calling this function from the same thread that
+ previously locked the mutex will return undefined results.
+
+ \sa lock(), unlock()
+*/
+bool TQMutex::locked()
+{
+ return d->locked();
+}
+
+/*!
+ Attempt to lock the mutex. If the lock was obtained, this function
+ returns TRUE. If another thread has locked the mutex, this
+ function returns FALSE, instead of waiting for the mutex to become
+ available, i.e. it does not block.
+
+ If the lock was obtained, the mutex must be unlocked with unlock()
+ before another thread can successfully lock it.
+
+ \sa lock(), unlock(), locked()
+*/
+bool TQMutex::tryLock()
+{
+ return d->trylock();
+}
+
+/*!
+ \class TQMutexLocker tqmutex.h
+ \brief The TQMutexLocker class simplifies locking and unlocking TQMutexes.
+
+ \threadsafe
+
+ \ingroup thread
+ \ingroup environment
+
+ The purpose of TQMutexLocker is to simplify TQMutex locking and
+ unlocking. Locking and unlocking a TQMutex in complex functions and
+ statements or in exception handling code is error prone and
+ difficult to debug. TQMutexLocker should be used in such situations
+ to ensure that the state of the mutex is well defined and always
+ locked and unlocked properly.
+
+ TQMutexLocker should be created within a function where a TQMutex
+ needs to be locked. The mutex is locked when TQMutexLocker is
+ created, and unlocked when TQMutexLocker is destroyed.
+
+ For example, this complex function locks a TQMutex upon entering
+ the function and unlocks the mutex at all the exit points:
+
+ \code
+ int complexFunction( int flag )
+ {
+ mutex.lock();
+
+ int return_value = 0;
+
+ switch ( flag ) {
+ case 0:
+ case 1:
+ {
+ mutex.unlock();
+ return moreComplexFunction( flag );
+ }
+
+ case 2:
+ {
+ int status = anotherFunction();
+ if ( status < 0 ) {
+ mutex.unlock();
+ return -2;
+ }
+ return_value = status + flag;
+ break;
+ }
+
+ default:
+ {
+ if ( flag > 10 ) {
+ mutex.unlock();
+ return -1;
+ }
+ break;
+ }
+ }
+
+ mutex.unlock();
+ return return_value;
+ }
+ \endcode
+
+ This example function will get more complicated as it is
+ developed, which increases the likelihood that errors will occur.
+
+ Using TQMutexLocker greatly simplifies the code, and makes it more
+ readable:
+
+ \code
+ int complexFunction( int flag )
+ {
+ TQMutexLocker locker( &mutex );
+
+ int return_value = 0;
+
+ switch ( flag ) {
+ case 0:
+ case 1:
+ {
+ return moreComplexFunction( flag );
+ }
+
+ case 2:
+ {
+ int status = anotherFunction();
+ if ( status < 0 )
+ return -2;
+ return_value = status + flag;
+ break;
+ }
+
+ default:
+ {
+ if ( flag > 10 )
+ return -1;
+ break;
+ }
+ }
+
+ return return_value;
+ }
+ \endcode
+
+ Now, the mutex will always be unlocked when the TQMutexLocker
+ object is destroyed (when the function returns since \c locker is
+ an auto variable). Note that the mutex will be unlocked after
+ the call to moreComplexFunction() in this example, avoiding
+ possible bugs caused by unlocking the mutex too early, as in
+ the first example.
+
+ The same principle applies to code that throws and catches
+ exceptions. An exception that is not caught in the function that
+ has locked the mutex has no way of unlocking the mutex before the
+ exception is passed up the stack to the calling function.
+
+ TQMutexLocker also provides a mutex() member function that returns
+ the mutex on which the TQMutexLocker is operating. This is useful
+ for code that needs access to the mutex, such as
+ TQWaitCondition::wait(). For example:
+
+ \code
+ class SignalWaiter
+ {
+ private:
+ TQMutexLocker locker;
+
+ public:
+ SignalWaiter( TQMutex *mutex )
+ : locker( mutex )
+ {
+ }
+
+ void waitForSignal()
+ {
+ ...
+ ...
+ ...
+
+ while ( ! signalled )
+ waitcondition.wait( locker.mutex() );
+
+ ...
+ ...
+ ...
+ }
+ };
+ \endcode
+
+ \sa TQMutex, TQWaitCondition
+*/
+
+/*!
+ \fn TQMutexLocker::TQMutexLocker( TQMutex *mutex )
+
+ Constructs a TQMutexLocker and locks \a mutex. The mutex will be
+ unlocked when the TQMutexLocker is destroyed. If \a mutex is zero,
+ TQMutexLocker does nothing.
+
+ \sa TQMutex::lock()
+*/
+
+/*!
+ \fn TQMutexLocker::~TQMutexLocker()
+
+ Destroys the TQMutexLocker and unlocks the mutex which was locked
+ in the constructor.
+
+ \sa TQMutexLocker::TQMutexLocker(), TQMutex::unlock()
+*/
+
+/*!
+ \fn TQMutex *TQMutexLocker::mutex() const
+
+ Returns a pointer to the mutex which was locked in the
+ constructor.
+
+ \sa TQMutexLocker::TQMutexLocker()
+*/
+
+#endif // TQT_THREAD_SUPPORT
diff --git a/tqtinterface/qt4/src/tools/tqmutexpool.cpp b/tqtinterface/qt4/src/tools/tqmutexpool.cpp
new file mode 100644
index 0000000..3b14922
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqmutexpool.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmutexpool_p.h"
+
+#ifdef TQT_THREAD_SUPPORT
+
+#include <tqthread.h>
+
+TQ_EXPORT TQMutexPool *tqt_global_mutexpool = 0;
+
+
+/*!
+ \class TQMutexPool qmutexpool_p.h
+ \brief The TQMutexPool class provides a pool of TQMutex objects.
+
+ \internal
+
+ \ingroup thread
+
+ TQMutexPool is a convenience class that provides access to a fixed
+ number of TQMutex objects.
+
+ Typical use of a TQMutexPool is in situations where it is not
+ possible or feasible to use one TQMutex for every protected object.
+ The mutex pool will return a mutex based on the address of the
+ object that needs protection.
+
+ For example, consider this simple class:
+
+ \code
+ class Number {
+ public:
+ Number( double n ) : num ( n ) { }
+
+ void setNumber( double n ) { num = n; }
+ double number() const { return num; }
+
+ private:
+ double num;
+ };
+ \endcode
+
+ Adding a TQMutex member to the Number class does not make sense,
+ because it is so small. However, in order to ensure that access to
+ each Number is protected, you need to use a mutex. In this case, a
+ TQMutexPool would be ideal.
+
+ Code to calculate the square of a number would then look something
+ like this:
+
+ \code
+ void calcSquare( Number *num )
+ {
+ TQMutexLocker locker( mutexpool.get( num ) );
+ num.setNumber( num.number() * num.number() );
+ }
+ \endcode
+
+ This function will safely calculate the square of a number, since
+ it uses a mutex from a TQMutexPool. The mutex is locked and
+ unlocked automatically by the TQMutexLocker class. See the
+ TQMutexLocker documentation for more details.
+*/
+
+/*!
+ Constructs a TQMutexPool, reserving space for \a size TQMutexes. If
+ \a recursive is TRUE, all TQMutexes in the pool will be recursive
+ mutexes; otherwise they will all be non-recursive (the default).
+
+ The TQMutexes are created when needed, and deleted when the
+ TQMutexPool is destructed.
+*/
+TQMutexPool::TQMutexPool( bool recursive, int size )
+ : mutex( FALSE ), count( size ), recurs( recursive )
+{
+ mutexes = new TQMutex*[count];
+ for ( int index = 0; index < count; ++index ) {
+ mutexes[index] = 0;
+ }
+}
+
+/*!
+ Destructs a TQMutexPool. All TQMutexes that were created by the pool
+ are deleted.
+*/
+TQMutexPool::~TQMutexPool()
+{
+ TQMutexLocker locker( &mutex );
+ for ( int index = 0; index < count; ++index ) {
+ delete mutexes[index];
+ mutexes[index] = 0;
+ }
+ delete [] mutexes;
+ mutexes = 0;
+}
+
+/*!
+ Returns a TQMutex from the pool. TQMutexPool uses the value \a
+ address to determine which mutex is retured from the pool.
+*/
+TQMutex *TQMutexPool::get( void *address )
+{
+ int index = (int) ( (unsigned long) address % count );
+
+ if ( ! mutexes[index] ) {
+ // mutex not created, create one
+
+ TQMutexLocker locker( &mutex );
+ // we need to check once again that the mutex hasn't been created, since
+ // 2 threads could be trying to create a mutex as the same index...
+ if ( ! mutexes[index] ) {
+ mutexes[index] = new TQMutex( recurs );
+ }
+ }
+
+ return mutexes[index];
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqmutexpool_p.h b/tqtinterface/qt4/src/tools/tqmutexpool_p.h
new file mode 100644
index 0000000..4293274
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqmutexpool_p.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMUTEXPOOL_P_H
+#define TQMUTEXPOOL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of TQSettings. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifdef TQT_THREAD_SUPPORT
+
+#ifndef TQT_H
+#include "tqmutex.h"
+#include "tqmemarray.h"
+#endif // TQT_H
+
+class TQ_EXPORT TQMutexPool
+{
+public:
+ TQMutexPool( bool recursive = FALSE, int size = 17 );
+ ~TQMutexPool();
+
+ TQMutex *get( void *address );
+
+private:
+ TQMutex mutex;
+ TQMutex **mutexes;
+ int count;
+ bool recurs;
+};
+
+extern TQ_EXPORT TQMutexPool *tqt_global_mutexpool;
+
+#endif // TQT_THREAD_SUPPORT
+
+#endif // TQMUTEXPOOL_P_H
diff --git a/tqtinterface/qt4/src/tools/tqpair.h b/tqtinterface/qt4/src/tools/tqpair.h
new file mode 100644
index 0000000..0f1d743
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqpair.h
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Definition of TQPair class
+**
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPAIR_H
+#define TQPAIR_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqdatastream.h"
+#endif // TQT_H
+
+template <class T1, class T2>
+struct TQPair
+{
+ typedef T1 first_type;
+ typedef T2 second_type;
+
+ TQPair()
+ : first( T1() ), second( T2() )
+ {}
+ TQPair( const T1& t1, const T2& t2 )
+ : first( t1 ), second( t2 )
+ {}
+
+ TQPair<T1, T2>& operator=(const TQPair<T1, T2>& other)
+ {
+ if (this != &other) {
+ first = other.first;
+ second = other.second;
+ }
+ return *this;
+ }
+
+ T1 first;
+ T2 second;
+};
+
+template <class T1, class T2>
+TQ_INLINE_TEMPLATES bool operator==( const TQPair<T1, T2>& x, const TQPair<T1, T2>& y )
+{
+ return x.first == y.first && x.second == y.second;
+}
+
+template <class T1, class T2>
+TQ_INLINE_TEMPLATES bool operator<( const TQPair<T1, T2>& x, const TQPair<T1, T2>& y )
+{
+ return x.first < y.first ||
+ ( !( y.first < x.first ) && x.second < y.second );
+}
+
+template <class T1, class T2>
+TQ_INLINE_TEMPLATES TQPair<T1, T2> tqMakePair( const T1& x, const T2& y )
+{
+ return TQPair<T1, T2>( x, y );
+}
+
+#ifndef TQT_NO_DATASTREAM
+template <class T1, class T2>
+inline TQDataStream& operator>>( TQDataStream& s, TQPair<T1, T2>& p )
+{
+ s >> p.first >> p.second;
+ return s;
+}
+
+template <class T1, class T2>
+inline TQDataStream& operator<<( TQDataStream& s, const TQPair<T1, T2>& p )
+{
+ s << p.first << p.second;
+ return s;
+}
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqpluginmanager_p.h b/tqtinterface/qt4/src/tools/tqpluginmanager_p.h
new file mode 100644
index 0000000..58b9b26
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqpluginmanager_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Definition of TQPluginManager class
+**
+** Created : 000101
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPLUGINMANAGER_P_H
+#define TQPLUGINMANAGER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#include "tqgpluginmanager_p.h"
+
+#ifndef TQT_NO_COMPONENT
+
+template<class Type>
+class TQPluginManager : public TQGPluginManager
+{
+public:
+ TQPluginManager( const TQUuid& id, const QStringList& paths = TQString::null, const TQString &suffix = TQString::null, bool cs = TRUE )
+ : TQGPluginManager( id, TQT_TQSTRINGLIST_OBJECT(paths), suffix, cs ) {}
+ TQRESULT queryInterface(const TQString& feature, Type** iface) const
+ {
+ return queryUnknownInterface( feature, (TQUnknownInterface**)iface );
+ }
+};
+
+#endif //TQT_NO_COMPONENT
+
+#endif //TQPLUGINMANAGER_P_H
diff --git a/tqtinterface/qt4/src/tools/tqptrcollection.cpp b/tqtinterface/qt4/src/tools/tqptrcollection.cpp
new file mode 100644
index 0000000..38bbeef
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqptrcollection.cpp
@@ -0,0 +1,183 @@
+/****************************************************************************
+**
+** Implementation of base class for all pointer based collection classes
+**
+** Created : 920820
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqptrcollection.h"
+
+/*!
+ \class TQPtrCollection tqptrcollection.h
+ \reentrant
+ \brief The TQPtrCollection class is the base class of most pointer-based TQt collections.
+
+ \ingroup collection
+ \ingroup tools
+
+ The TQPtrCollection class is an abstract base class for the TQt
+ \link collection.html collection classes\endlink TQDict, TQPtrList,
+ etc. TQt also includes value based collections, e.g. TQValueList,
+ TQMap, etc.
+
+ A TQPtrCollection only knows about the number of objects in the
+ collection and the deletion strategy (see setAutoDelete()).
+
+ A collection is implemented using the \c Item (generic collection
+ item) type, which is a \c void*. The template classes that create
+ the real collections cast the \c Item to the required type.
+*/
+
+
+/*!
+ \enum TQPtrCollection::Item
+
+ This type is the generic "item" in a TQPtrCollection.
+*/
+
+
+/*!
+ \fn TQPtrCollection::TQPtrCollection()
+
+ Constructs a collection. The constructor is protected because
+ TQPtrCollection is an abstract class.
+*/
+
+/*!
+ \fn TQPtrCollection::TQPtrCollection( const TQPtrCollection & source )
+
+ Constructs a copy of \a source with autoDelete() set to FALSE. The
+ constructor is protected because TQPtrCollection is an abstract
+ class.
+
+ Note that if \a source has autoDelete turned on, copying it will
+ risk memory leaks, reading freed memory, or both.
+*/
+
+/*!
+ \fn TQPtrCollection::~TQPtrCollection()
+
+ Destroys the collection. The destructor is protected because
+ TQPtrCollection is an abstract class.
+*/
+
+
+/*!
+ \fn bool TQPtrCollection::autoDelete() const
+
+ Returns the setting of the auto-delete option. The default is FALSE.
+
+ \sa setAutoDelete()
+*/
+
+/*!
+ \fn void TQPtrCollection::setAutoDelete( bool enable )
+
+ Sets the collection to auto-delete its contents if \a enable is
+ TRUE and to never delete them if \a enable is FALSE.
+
+ If auto-deleting is turned on, all the items in a collection are
+ deleted when the collection itself is deleted. This is convenient
+ if the collection has the only pointer to the items.
+
+ The default setting is FALSE, for safety. If you turn it on, be
+ careful about copying the collection - you might tqfind yourself
+ with two collections deleting the same items.
+
+ Note that the auto-delete setting may also affect other functions
+ in subclasses. For example, a subclass that has a remove()
+ function will remove the item from its data structure, and if
+ auto-delete is enabled, will also delete the item.
+
+ \sa autoDelete()
+*/
+
+
+/*!
+ \fn virtual uint TQPtrCollection::count() const
+
+ Returns the number of objects in the collection.
+*/
+
+/*!
+ \fn virtual void TQPtrCollection::clear()
+
+ Removes all objects from the collection. The objects will be
+ deleted if auto-delete has been enabled.
+
+ \sa setAutoDelete()
+*/
+
+/*!
+ \fn void TQPtrCollection::deleteItem( Item d )
+
+ Reimplement this function if you want to be able to delete items.
+
+ Deletes an item that is about to be removed from the collection.
+
+ This function has to reimplemented in the collection template
+ classes, and should \e only delete item \a d if auto-delete has
+ been enabled.
+
+ \warning If you reimplement this function you must also
+ reimplement the destructor and call the virtual function clear()
+ from your destructor. This is due to the way virtual functions and
+ destructors work in C++: Virtual functions in derived classes
+ cannot be called from a destructor. If you do not do this, your
+ deleteItem() function will not be called when the container is
+ destroyed.
+
+ \sa newItem(), setAutoDelete()
+*/
+
+/*!
+ Virtual function that creates a copy of an object that is about to
+ be inserted into the collection.
+
+ The default implementation returns the \a d pointer, i.e. no copy
+ is made.
+
+ This function is seldom reimplemented in the collection template
+ classes. It is not common practice to make a copy of something
+ that is being inserted.
+
+ \sa deleteItem()
+*/
+
+TQPtrCollection::Item TQPtrCollection::newItem( Item d )
+{
+ return d; // just return reference
+}
diff --git a/tqtinterface/qt4/src/tools/tqptrcollection.h b/tqtinterface/qt4/src/tools/tqptrcollection.h
new file mode 100644
index 0000000..86bc2e2
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqptrcollection.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Definition of base class for all pointer based collection classes
+**
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPTRCOLLECTION_H
+#define TQPTRCOLLECTION_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+
+class TQGVector;
+class TQGList;
+class TQGDict;
+
+
+class TQ_EXPORT TQPtrCollection // inherited by all collections
+{
+public:
+ bool autoDelete() const { return del_item; }
+ void setAutoDelete( bool enable ) { del_item = enable; }
+
+ virtual uint count() const = 0;
+ virtual void clear() = 0; // delete all objects
+
+ typedef void *Item; // generic collection item
+
+protected:
+ TQPtrCollection() { del_item = FALSE; } // no deletion of objects
+ TQPtrCollection(const TQPtrCollection &) { del_item = FALSE; }
+ virtual ~TQPtrCollection() {}
+
+ bool del_item; // default FALSE
+
+ virtual Item newItem( Item ); // create object
+ virtual void deleteItem( Item ) = 0; // delete object
+};
+
+
+#ifndef TQT_NO_COMPAT
+#define TQCollection TQPtrCollection
+#endif
+
+#endif // TQPTRCOLLECTION_H
diff --git a/tqtinterface/qt4/src/tools/tqptrdict.h b/tqtinterface/qt4/src/tools/tqptrdict.h
new file mode 100644
index 0000000..908907d
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqptrdict.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Definition of TQPtrDict template class
+**
+** Created : 970415
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPTRDICT_H
+#define TQPTRDICT_H
+
+#ifndef TQT_H
+#include "tqgdict.h"
+#endif // TQT_H
+
+template<class type>
+class TQPtrDict
+#ifdef TQ_TQDOC
+ : public TQPtrCollection
+#else
+ : public TQGDict
+#endif
+{
+public:
+ TQPtrDict(int size=17) : TQGDict(size,PtrKey,0,0) {}
+ TQPtrDict( const TQPtrDict<type> &d ) : TQGDict(d) {}
+ ~TQPtrDict() { clear(); }
+ TQPtrDict<type> &operator=(const TQPtrDict<type> &d)
+ { return (TQPtrDict<type>&)TQGDict::operator=(d); }
+ uint count() const { return TQGDict::count(); }
+ uint size() const { return TQGDict::size(); }
+ bool isEmpty() const { return TQGDict::count() == 0; }
+ void insert( void *k, const type *d )
+ { TQGDict::look_ptr(k,(Item)d,1); }
+ void tqreplace( void *k, const type *d )
+ { TQGDict::look_ptr(k,(Item)d,2); }
+ bool remove( void *k ) { return TQGDict::remove_ptr(k); }
+ type *take( void *k ) { return (type*)TQGDict::take_ptr(k); }
+ type *tqfind( void *k ) const
+ { return (type *)((TQGDict*)this)->TQGDict::look_ptr(k,0,0); }
+ type *operator[]( void *k ) const
+ { return (type *)((TQGDict*)this)->TQGDict::look_ptr(k,0,0); }
+ void clear() { TQGDict::clear(); }
+ void resize( uint n ) { TQGDict::resize(n); }
+ void statistics() const { TQGDict::statistics(); }
+
+#ifdef TQ_TQDOC
+protected:
+ virtual TQDataStream& read( TQDataStream &, TQPtrCollection::Item & );
+ virtual TQDataStream& write( TQDataStream &, TQPtrCollection::Item ) const;
+#endif
+
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQPtrDict<void>::deleteItem( TQPtrCollection::Item )
+{
+}
+#endif
+
+template<class type>
+inline void TQPtrDict<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+template<class type>
+class TQPtrDictIterator : public TQGDictIterator
+{
+public:
+ TQPtrDictIterator(const TQPtrDict<type> &d) :TQGDictIterator((TQGDict &)d) {}
+ ~TQPtrDictIterator() {}
+ uint count() const { return dict->count(); }
+ bool isEmpty() const { return dict->count() == 0; }
+ type *toFirst() { return (type *)TQGDictIterator::toFirst(); }
+ operator type *() const { return (type *)TQGDictIterator::get(); }
+ type *current() const { return (type *)TQGDictIterator::get(); }
+ void *currentKey() const { return TQGDictIterator::getKeyPtr(); }
+ type *operator()() { return (type *)TQGDictIterator::operator()(); }
+ type *operator++() { return (type *)TQGDictIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)TQGDictIterator::operator+=(j);}
+};
+
+#endif // TQPTRDICT_H
diff --git a/tqtinterface/qt4/src/tools/tqptrlist.h b/tqtinterface/qt4/src/tools/tqptrlist.h
new file mode 100644
index 0000000..2839df6
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqptrlist.h
@@ -0,0 +1,197 @@
+/****************************************************************************
+**
+** Definition of TQPtrList template/macro class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPTRLIST_H
+#define TQPTRLIST_H
+
+#ifndef TQT_H
+#include "tqglist.h"
+#endif // TQT_H
+
+template<class type>
+class TQPtrListStdIterator : public TQGListStdIterator
+{
+public:
+ inline TQPtrListStdIterator( TQLNode* n ): TQGListStdIterator(n) {}
+ type *operator*() { return node ? (type *)node->getData() : 0; }
+ inline TQPtrListStdIterator<type> operator++()
+ { node = next(); return *this; }
+ inline TQPtrListStdIterator<type> operator++(int)
+ { TQLNode* n = node; node = next(); return TQPtrListStdIterator<type>( n ); }
+ inline bool operator==( const TQPtrListStdIterator<type>& it ) const { return node == it.node; }
+ inline bool operator!=( const TQPtrListStdIterator<type>& it ) const { return node != it.node; }
+};
+
+
+template<class type>
+class TQPtrList
+#ifdef TQ_TQDOC
+ : public TQPtrCollection
+#else
+ : public TQGList
+#endif
+{
+public:
+
+ TQPtrList() {}
+ TQPtrList( const TQPtrList<type> &l ) : TQGList(l) {}
+ ~TQPtrList() { clear(); }
+ TQPtrList<type> &operator=(const TQPtrList<type> &l)
+ { return (TQPtrList<type>&)TQGList::operator=(l); }
+ bool operator==( const TQPtrList<type> &list ) const
+ { return TQGList::operator==( list ); }
+ bool operator!=( const TQPtrList<type> &list ) const
+ { return !TQGList::operator==( list ); }
+ uint count() const { return TQGList::count(); }
+ bool isEmpty() const { return TQGList::count() == 0; }
+ bool insert( uint i, const type *d){ return TQGList::insertAt(i,(TQPtrCollection::Item)d); }
+ void inSort( const type *d ) { TQGList::inSort((TQPtrCollection::Item)d); }
+ void prepend( const type *d ) { TQGList::insertAt(0,(TQPtrCollection::Item)d); }
+ void append( const type *d ) { TQGList::append((TQPtrCollection::Item)d); }
+ bool remove( uint i ) { return TQGList::removeAt(i); }
+ bool remove() { return TQGList::remove((TQPtrCollection::Item)0); }
+ bool remove( const type *d ) { return TQGList::remove((TQPtrCollection::Item)d); }
+ bool removeRef( const type *d ) { return TQGList::removeRef((TQPtrCollection::Item)d); }
+ void removeNode( TQLNode *n ) { TQGList::removeNode(n); }
+ bool removeFirst() { return TQGList::removeFirst(); }
+ bool removeLast() { return TQGList::removeLast(); }
+ type *take( uint i ) { return (type *)TQGList::takeAt(i); }
+ type *take() { return (type *)TQGList::take(); }
+ type *takeNode( TQLNode *n ) { return (type *)TQGList::takeNode(n); }
+ void clear() { TQGList::clear(); }
+ void sort() { TQGList::sort(); }
+ int tqfind( const type *d ) { return TQGList::tqfind((TQPtrCollection::Item)d); }
+ int tqfindNext( const type *d ) { return TQGList::tqfind((TQPtrCollection::Item)d,FALSE); }
+ int tqfindRef( const type *d ) { return TQGList::tqfindRef((TQPtrCollection::Item)d); }
+ int tqfindNextRef( const type *d ){ return TQGList::tqfindRef((TQPtrCollection::Item)d,FALSE);}
+ uint tqcontains( const type *d ) const { return TQGList::tqcontains((TQPtrCollection::Item)d); }
+ uint tqcontainsRef( const type *d ) const
+ { return TQGList::tqcontainsRef((TQPtrCollection::Item)d); }
+ bool tqreplace( uint i, const type *d ) { return TQGList::tqreplaceAt( i, (TQPtrCollection::Item)d ); }
+ type *at( uint i ) { return (type *)TQGList::at(i); }
+ type *tqat( uint i ) { return (type *)TQGList::at(i); }
+ int at() const { return TQGList::at(); }
+ int tqat() const { return TQGList::at(); }
+ type *current() const { return (type *)TQGList::get(); }
+ TQLNode *currentNode() const { return TQGList::currentNode(); }
+ type *getFirst() const { return (type *)TQGList::cfirst(); }
+ type *getLast() const { return (type *)TQGList::clast(); }
+ type *first() { return (type *)TQGList::first(); }
+ type *last() { return (type *)TQGList::last(); }
+ type *next() { return (type *)TQGList::next(); }
+ type *prev() { return (type *)TQGList::prev(); }
+ void toVector( TQGVector *vec )const{ TQGList::toVector(vec); }
+
+
+ // standard iterators
+ typedef TQPtrListStdIterator<type> Iterator;
+ typedef TQPtrListStdIterator<type> ConstIterator;
+ inline Iterator begin() { return TQGList::begin(); }
+ inline ConstIterator begin() const { return TQGList::begin(); }
+ inline ConstIterator constBegin() const { return TQGList::begin(); }
+ inline Iterator end() { return TQGList::end(); }
+ inline ConstIterator end() const { return TQGList::end(); }
+ inline ConstIterator constEnd() const { return TQGList::end(); }
+ inline Iterator erase( Iterator it ) { return TQGList::erase( it ); }
+ // stl syntax compatibility
+ typedef Iterator iterator;
+ typedef ConstIterator const_iterator;
+
+
+#ifdef TQ_TQDOC
+protected:
+ virtual int compareItems( TQPtrCollection::Item, TQPtrCollection::Item );
+ virtual TQDataStream& read( TQDataStream&, TQPtrCollection::Item& );
+ virtual TQDataStream& write( TQDataStream&, TQPtrCollection::Item ) const;
+#endif
+
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQPtrList<void>::deleteItem( TQPtrCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void TQPtrList<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+template<class type>
+class TQPtrListIterator : public TQGListIterator
+{
+public:
+ TQPtrListIterator(const TQPtrList<type> &l) :TQGListIterator((TQGList &)l) {}
+ ~TQPtrListIterator() {}
+ uint count() const { return list->count(); }
+ bool isEmpty() const { return list->count() == 0; }
+ bool atFirst() const { return TQGListIterator::atFirst(); }
+ bool atLast() const { return TQGListIterator::atLast(); }
+ type *toFirst() { return (type *)TQGListIterator::toFirst(); }
+ type *toLast() { return (type *)TQGListIterator::toLast(); }
+ operator type *() const { return (type *)TQGListIterator::get(); }
+ type *operator*() { return (type *)TQGListIterator::get(); }
+
+ // No good, since TQPtrList<char> (ie. TQStrList fails...
+ //
+ // MSVC++ gives warning
+ // Sunpro C++ 4.1 gives error
+ // type *operator->() { return (type *)TQGListIterator::get(); }
+
+ type *current() const { return (type *)TQGListIterator::get(); }
+ type *operator()() { return (type *)TQGListIterator::operator()();}
+ type *operator++() { return (type *)TQGListIterator::operator++(); }
+ type *operator+=(uint j) { return (type *)TQGListIterator::operator+=(j);}
+ type *operator--() { return (type *)TQGListIterator::operator--(); }
+ type *operator-=(uint j) { return (type *)TQGListIterator::operator-=(j);}
+ TQPtrListIterator<type>& operator=(const TQPtrListIterator<type>&it)
+ { TQGListIterator::operator=(it); return *this; }
+};
+
+#ifndef TQT_NO_COMPAT
+#define TQList TQPtrList
+#define TQListIterator TQPtrListIterator
+#endif
+
+#define TQ_DEFINED_TQPTRLIST
+#include "tqwinexport.h"
+
+#endif // TQPTRLIST_H
diff --git a/tqtinterface/qt4/src/tools/tqptrqueue.h b/tqtinterface/qt4/src/tools/tqptrqueue.h
new file mode 100644
index 0000000..d7122cd
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqptrqueue.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Definition of TQPtrQueue template/macro class
+**
+** Created : 920917
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPTRTQUEUE_H
+#define TQPTRTQUEUE_H
+
+#ifndef TQT_H
+#include "tqglist.h"
+#endif // TQT_H
+
+template<class type>
+class TQPtrQueue : protected TQGList
+{
+public:
+ TQPtrQueue() {}
+ TQPtrQueue( const TQPtrQueue<type> &q ) : TQGList(q) {}
+ ~TQPtrQueue() { clear(); }
+ TQPtrQueue<type>& operator=(const TQPtrQueue<type> &q)
+ { return (TQPtrQueue<type>&)TQGList::operator=(q); }
+ bool autoDelete() const { return TQPtrCollection::autoDelete(); }
+ void setAutoDelete( bool del ) { TQPtrCollection::setAutoDelete(del); }
+ uint count() const { return TQGList::count(); }
+ bool isEmpty() const { return TQGList::count() == 0; }
+ void enqueue( const type *d ) { TQGList::append(Item(d)); }
+ type *dequeue() { return (type *)TQGList::takeFirst();}
+ bool remove() { return TQGList::removeFirst(); }
+ void clear() { TQGList::clear(); }
+ type *head() const { return (type *)TQGList::cfirst(); }
+ operator type *() const { return (type *)TQGList::cfirst(); }
+ type *current() const { return (type *)TQGList::cfirst(); }
+
+#ifdef TQ_TQDOC
+protected:
+ virtual TQDataStream& read( TQDataStream&, TQPtrCollection::Item& );
+ virtual TQDataStream& write( TQDataStream&, TQPtrCollection::Item ) const;
+#endif
+
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQPtrQueue<void>::deleteItem( TQPtrCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void TQPtrQueue<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+#ifndef TQT_NO_COMPAT
+#define TQQueue TQPtrQueue
+#endif
+
+#endif // TQPTRTQUEUE_H
diff --git a/tqtinterface/qt4/src/tools/tqptrstack.h b/tqtinterface/qt4/src/tools/tqptrstack.h
new file mode 100644
index 0000000..1ab0d65
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqptrstack.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Definition of TQPtrStack pointer based template class
+**
+** Created : 920917
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPTRSTACK_H
+#define TQPTRSTACK_H
+
+#ifndef TQT_H
+#include "tqglist.h"
+#endif // TQT_H
+
+template<class type>
+class TQPtrStack : protected TQGList
+{
+public:
+ TQPtrStack() { }
+ TQPtrStack( const TQPtrStack<type> &s ) : TQGList( s ) { }
+ ~TQPtrStack() { clear(); }
+ TQPtrStack<type> &operator=(const TQPtrStack<type> &s)
+ { return (TQPtrStack<type>&)TQGList::operator=(s); }
+ bool autoDelete() const { return TQPtrCollection::autoDelete(); }
+ void setAutoDelete( bool del ) { TQPtrCollection::setAutoDelete(del); }
+ uint count() const { return TQGList::count(); }
+ bool isEmpty() const { return TQGList::count() == 0; }
+ void push( const type *d ) { TQGList::insertAt(0,Item(d)); }
+ type *pop() { return (type *)TQGList::takeFirst(); }
+ bool remove() { return TQGList::removeFirst(); }
+ void clear() { TQGList::clear(); }
+ type *top() const { return (type *)TQGList::cfirst(); }
+ operator type *() const { return (type *)TQGList::cfirst(); }
+ type *current() const { return (type *)TQGList::cfirst(); }
+
+#ifdef TQ_TQDOC
+protected:
+ virtual TQDataStream& read( TQDataStream&, TQPtrCollection::Item& );
+ virtual TQDataStream& write( TQDataStream&, TQPtrCollection::Item ) const;
+#endif
+
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQPtrStack<void>::deleteItem( TQPtrCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void TQPtrStack<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+#ifndef TQT_NO_COMPAT
+#define TQStack TQPtrStack
+#endif
+
+#endif // TQPTRSTACK_H
diff --git a/tqtinterface/qt4/src/tools/tqptrvector.h b/tqtinterface/qt4/src/tools/tqptrvector.h
new file mode 100644
index 0000000..97934d4
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqptrvector.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Definition of TQPtrVector pointer based template class
+**
+** Created : 930907
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPTRVECTOR_H
+#define TQPTRVECTOR_H
+
+#ifndef TQT_H
+#include "tqgvector.h"
+#endif // TQT_H
+
+template<class type>
+class TQPtrVector
+#ifdef TQ_TQDOC
+ : public TQPtrCollection
+#else
+ : public TQGVector
+#endif
+{
+public:
+ TQPtrVector() { }
+ TQPtrVector( uint size ) : TQGVector(size) { }
+ TQPtrVector( const TQPtrVector<type> &v ) : TQGVector( v ) { }
+ ~TQPtrVector() { clear(); }
+ TQPtrVector<type> &operator=(const TQPtrVector<type> &v)
+ { return (TQPtrVector<type>&)TQGVector::operator=(v); }
+ bool operator==( const TQPtrVector<type> &v ) const { return TQGVector::operator==(v); }
+ type **data() const { return (type **)TQGVector::data(); }
+ uint size() const { return TQGVector::size(); }
+ uint count() const { return TQGVector::count(); }
+ bool isEmpty() const { return TQGVector::count() == 0; }
+ bool isNull() const { return TQGVector::size() == 0; }
+ bool resize( uint size ) { return TQGVector::resize(size); }
+ bool insert( uint i, const type *d){ return TQGVector::insert(i,(Item)d); }
+ bool remove( uint i ) { return TQGVector::remove(i); }
+ type *take( uint i ) { return (type *)TQGVector::take(i); }
+ void clear() { TQGVector::clear(); }
+ bool fill( const type *d, int size=-1 )
+ { return TQGVector::fill((Item)d,size);}
+ void sort() { TQGVector::sort(); }
+ int bsearch( const type *d ) const{ return TQGVector::bsearch((Item)d); }
+ int tqfindRef( const type *d, uint i=0 ) const
+ { return TQGVector::tqfindRef((Item)d,i);}
+ int tqfind( const type *d, uint i= 0 ) const
+ { return TQGVector::tqfind((Item)d,i); }
+ uint tqcontainsRef( const type *d ) const
+ { return TQGVector::tqcontainsRef((Item)d); }
+ uint tqcontains( const type *d ) const
+ { return TQGVector::tqcontains((Item)d); }
+ type *operator[]( int i ) const { return (type *)TQGVector::at(i); }
+ type *at( uint i ) const { return (type *)TQGVector::at(i); }
+ type *tqat( uint i ) const { return (type *)TQGVector::at(i); }
+ void toList( TQGList *list ) const { TQGVector::toList(list); }
+
+#ifdef TQ_TQDOC
+protected:
+ virtual int compareItems( TQPtrCollection::Item d1, TQPtrCollection::Item d2 );
+ virtual TQDataStream& read( TQDataStream &s, TQPtrCollection::Item &d );
+ virtual TQDataStream& write( TQDataStream &s, TQPtrCollection::Item d ) const;
+#endif
+
+private:
+ void deleteItem( Item d );
+};
+
+#if !defined(TQ_BROKEN_TEMPLATE_SPECIALIZATION)
+template<> inline void TQPtrVector<void>::deleteItem( TQPtrCollection::Item )
+{
+}
+#endif
+
+template<class type> inline void TQPtrVector<type>::deleteItem( TQPtrCollection::Item d )
+{
+ if ( del_item ) delete (type *)d;
+}
+
+#ifndef TQT_NO_COMPAT
+#define TQVector TQPtrVector
+#endif
+
+#define TQ_DEFINED_TQPTRVECTOR
+#include "tqwinexport.h"
+#endif // TQVECTOR_H
diff --git a/tqtinterface/qt4/src/tools/tqregexp.cpp b/tqtinterface/qt4/src/tools/tqregexp.cpp
new file mode 100644
index 0000000..cac50e5
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqregexp.cpp
@@ -0,0 +1,4050 @@
+/****************************************************************************
+**
+** Implementation of TQRegExp class
+**
+** Created : 950126
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqregexp.h"
+
+#ifndef TQT_NO_REGEXP
+
+#include "tqmemarray.h"
+#include "tqbitarray.h"
+#include "tqcache.h"
+#include "tqcleanuphandler.h"
+#include "tqintdict.h"
+#include "tqmap.h"
+#include "tqptrvector.h"
+#include "tqstring.h"
+#include "tqtl.h"
+
+#ifdef TQT_THREAD_SUPPORT
+#include "tqthreadstorage.h"
+#include <private/tqthreadinstance_p.h>
+#endif // TQT_THREAD_SUPPORT
+
+#undef TQT_TRANSLATE_NOOP
+#define TQT_TRANSLATE_NOOP( context, sourceText ) sourceText
+
+#include <limits.h>
+
+// error strings for the regexp parser
+#define RXERR_OK TQT_TRANSLATE_NOOP( "TQRegExp", "no error occurred" )
+#define RXERR_DISABLED TQT_TRANSLATE_NOOP( "TQRegExp", "disabled feature used" )
+#define RXERR_CHARCLASS TQT_TRANSLATE_NOOP( "TQRegExp", "bad char class syntax" )
+#define RXERR_LOOKAHEAD TQT_TRANSLATE_NOOP( "TQRegExp", "bad lookahead syntax" )
+#define RXERR_REPETITION TQT_TRANSLATE_NOOP( "TQRegExp", "bad repetition syntax" )
+#define RXERR_OCTAL TQT_TRANSLATE_NOOP( "TQRegExp", "invalid octal value" )
+#define RXERR_LEFTDELIM TQT_TRANSLATE_NOOP( "TQRegExp", "missing left delim" )
+#define RXERR_END TQT_TRANSLATE_NOOP( "TQRegExp", "unexpected end" )
+#define RXERR_LIMIT TQT_TRANSLATE_NOOP( "TQRegExp", "met internal limit" )
+
+#ifdef USE_QT4
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+int TQRegExp::search( const TQString& str, int offset ) const
+{
+ return indexIn( str, offset, CaretAtZero);
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+int TQRegExp::search( const TQString& str, int offset, CaretMode caretMode ) const
+{
+ return indexIn( str, offset, caretMode);
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+int TQRegExp::searchRev( const TQString& str, int offset ) const
+{
+ return lastIndexIn( str, offset, CaretAtZero);
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+int TQRegExp::searchRev( const TQString& str, int offset, CaretMode caretMode ) const
+{
+ return lastIndexIn( str, offset, caretMode);
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+bool TQRegExp::caseSensitive() const
+{
+ return caseSensitivity();
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+void TQRegExp::setCaseSensitive( bool sensitive )
+{
+ setCaseSensitivity( (Qt::CaseSensitivity)sensitive);
+}
+
+#else // USE_QT4
+
+/*
+ WARNING! Be sure to read qregexp.tex before modifying this file.
+*/
+
+/*!
+ \class TQRegExp tqregexp.h
+ \reentrant
+ \brief The TQRegExp class provides pattern matching using regular expressions.
+
+ \ingroup tools
+ \ingroup misc
+ \ingroup shared
+ \mainclass
+ \keyword regular expression
+
+ Regular expressions, or "regexps", provide a way to tqfind patterns
+ within text. This is useful in many contexts, for example:
+
+ \table
+ \row \i Validation
+ \i A regexp can be used to check whether a piece of text
+ meets some criteria, e.g. is an integer or tqcontains no
+ whitespace.
+ \row \i Searching
+ \i Regexps provide a much more powerful means of searching
+ text than simple string matching does. For example we can
+ create a regexp which says "tqfind one of the words 'mail',
+ 'letter' or 'correspondence' but not any of the words
+ 'email', 'mailman' 'mailer', 'letterbox' etc."
+ \row \i Search and Replace
+ \i A regexp can be used to tqreplace a pattern with a piece of
+ text, for example tqreplace all occurrences of '&' with
+ '\&amp;' except where the '&' is already followed by 'amp;'.
+ \row \i String Splitting
+ \i A regexp can be used to identify where a string should be
+ split into its component fields, e.g. splitting tab-delimited
+ strings.
+ \endtable
+
+ We present a very brief introduction to regexps, a description of
+ TQt's regexp language, some code examples, and finally the function
+ documentation itself. TQRegExp is modeled on Perl's regexp
+ language, and also fully supports Unicode. TQRegExp can also be
+ used in the weaker 'wildcard' (globbing) mode which works in a
+ similar way to command shells. A good text on regexps is \e
+ {Mastering Regular Expressions: Powerful Techniques for Perl and
+ Other Tools} by Jeffrey E. Friedl, ISBN 1565922573.
+
+ Experienced regexp users may prefer to skip the introduction and
+ go directly to the relevant information.
+
+ In case of multi-threaded programming, note that TQRegExp depends on
+ TQThreadStorage internally. For that reason, TQRegExp should only be
+ used with threads started with TQThread, i.e. not with threads
+ started with platform-specific APIs.
+
+ \tableofcontents
+
+ \section1 Introduction
+
+ Regexps are built up from expressions, quantifiers, and assertions.
+ The simplest form of expression is simply a character, e.g.
+ <b>x</b> or <b>5</b>. An expression can also be a set of
+ characters. For example, <b>[ABCD]</b>, will match an <b>A</b> or
+ a <b>B</b> or a <b>C</b> or a <b>D</b>. As a shorthand we could
+ write this as <b>[A-D]</b>. If we want to match any of the
+ captital letters in the English alphabet we can write
+ <b>[A-Z]</b>. A quantifier tells the regexp engine how many
+ occurrences of the expression we want, e.g. <b>x{1,1}</b> means
+ match an <b>x</b> which occurs at least once and at most once.
+ We'll look at assertions and more complex expressions later.
+
+ Note that in general regexps cannot be used to check for balanced
+ brackets or tags. For example if you want to match an opening html
+ \c <b> and its closing \c </b> you can only use a regexp if you
+ know that these tags are not nested; the html fragment, \c{<b>bold
+ <b>bolder</b></b>} will not match as expected. If you know the
+ maximum level of nesting it is possible to create a regexp that
+ will match correctly, but for an unknown level of nesting, regexps
+ will fail.
+
+ We'll start by writing a regexp to match integers in the range 0
+ to 99. We will require at least one digit so we will start with
+ <b>[0-9]{1,1}</b> which means match a digit exactly once. This
+ regexp alone will match integers in the range 0 to 9. To match one
+ or two digits we can increase the maximum number of occurrences so
+ the regexp becomes <b>[0-9]{1,2}</b> meaning match a digit at
+ least once and at most twice. However, this regexp as it stands
+ will not match correctly. This regexp will match one or two digits
+ \e within a string. To ensure that we match against the whole
+ string we must use the anchor assertions. We need <b>^</b> (caret)
+ which when it is the first character in the regexp means that the
+ regexp must match from the beginning of the string. And we also
+ need <b>$</b> (dollar) which when it is the last character in the
+ regexp means that the regexp must match until the end of the
+ string. So now our regexp is <b>^[0-9]{1,2}$</b>. Note that
+ assertions, such as <b>^</b> and <b>$</b>, do not match any
+ characters.
+
+ If you've seen regexps elsewhere they may have looked different from
+ the ones above. This is because some sets of characters and some
+ quantifiers are so common that they have special symbols to
+ represent them. <b>[0-9]</b> can be tqreplaced with the symbol
+ <b>\d</b>. The quantifier to match exactly one occurrence,
+ <b>{1,1}</b>, can be tqreplaced with the expression itself. This means
+ that <b>x{1,1}</b> is exactly the same as <b>x</b> alone. So our 0
+ to 99 matcher could be written <b>^\d{1,2}$</b>. Another way of
+ writing it would be <b>^\d\d{0,1}$</b>, i.e. from the start of the
+ string match a digit followed by zero or one digits. In practice
+ most people would write it <b>^\d\d?$</b>. The <b>?</b> is a
+ shorthand for the quantifier <b>{0,1}</b>, i.e. a minimum of no
+ occurrences a maximum of one occurrence. This is used to make an
+ expression optional. The regexp <b>^\d\d?$</b> means "from the
+ beginning of the string match one digit followed by zero or one
+ digits and then the end of the string".
+
+ Our second example is matching the words 'mail', 'letter' or
+ 'correspondence' but without matching 'email', 'mailman',
+ 'mailer', 'letterbox' etc. We'll start by just matching 'mail'. In
+ full the regexp is, <b>m{1,1}a{1,1}i{1,1}l{1,1}</b>, but since
+ each expression itself is automatically quantified by <b>{1,1}</b>
+ we can simply write this as <b>mail</b>; an 'm' followed by an 'a'
+ followed by an 'i' followed by an 'l'. The symbol '|' (bar) is
+ used for \e alternation, so our regexp now becomes
+ <b>mail|letter|correspondence</b> which means match 'mail' \e or
+ 'letter' \e or 'correspondence'. Whilst this regexp will tqfind the
+ words we want it will also tqfind words we don't want such as
+ 'email'. We will start by putting our regexp in parentheses,
+ <b>(mail|letter|correspondence)</b>. Parentheses have two effects,
+ firstly they group expressions together and secondly they identify
+ parts of the regexp that we wish to \link #capturing-text capture
+ \endlink. Our regexp still matches any of the three words but now
+ they are grouped together as a unit. This is useful for building
+ up more complex regexps. It is also useful because it allows us to
+ examine which of the words actually matched. We need to use
+ another assertion, this time <b>\b</b> "word boundary":
+ <b>\b(mail|letter|correspondence)\b</b>. This regexp means "match
+ a word boundary followed by the expression in parentheses followed
+ by another word boundary". The <b>\b</b> assertion matches at a \e
+ position in the regexp not a \e character in the regexp. A word
+ boundary is any non-word character such as a space a newline or
+ the beginning or end of the string.
+
+ For our third example we want to tqreplace ampersands with the HTML
+ entity '\&amp;'. The regexp to match is simple: <b>\&</b>, i.e.
+ match one ampersand. Unfortunately this will mess up our text if
+ some of the ampersands have already been turned into HTML
+ entities. So what we really want to say is tqreplace an ampersand
+ providing it is not followed by 'amp;'. For this we need the
+ negative lookahead assertion and our regexp becomes:
+ <b>\&(?!amp;)</b>. The negative lookahead assertion is introduced
+ with '(?!' and finishes at the ')'. It means that the text it
+ tqcontains, 'amp;' in our example, must \e not follow the expression
+ that preceeds it.
+
+ Regexps provide a rich language that can be used in a variety of
+ ways. For example suppose we want to count all the occurrences of
+ 'Eric' and 'Eirik' in a string. Two valid regexps to match these
+ are <b>\\b(Eric|Eirik)\\b</b> and <b>\\bEi?ri[ck]\\b</b>. We need
+ the word boundary '\b' so we don't get 'Ericsson' etc. The second
+ regexp actually matches more than we want, 'Eric', 'Erik', 'Eiric'
+ and 'Eirik'.
+
+ We will implement some the examples above in the
+ \link #code-examples code examples \endlink section.
+
+ \target characters-and-abbreviations-for-sets-of-characters
+ \section1 Characters and Abbreviations for Sets of Characters
+
+ \table
+ \header \i Element \i Meaning
+ \row \i <b>c</b>
+ \i Any character represents itself unless it has a special
+ regexp meaning. Thus <b>c</b> matches the character \e c.
+ \row \i <b>\\c</b>
+ \i A character that follows a backslash matches the character
+ itself except where mentioned below. For example if you
+ wished to match a literal caret at the beginning of a string
+ you would write <b>\^</b>.
+ \row \i <b>\\a</b>
+ \i This matches the ASCII bell character (BEL, 0x07).
+ \row \i <b>\\f</b>
+ \i This matches the ASCII form feed character (FF, 0x0C).
+ \row \i <b>\\n</b>
+ \i This matches the ASCII line feed character (LF, 0x0A, Unix newline).
+ \row \i <b>\\r</b>
+ \i This matches the ASCII carriage return character (CR, 0x0D).
+ \row \i <b>\\t</b>
+ \i This matches the ASCII horizontal tab character (HT, 0x09).
+ \row \i <b>\\v</b>
+ \i This matches the ASCII vertical tab character (VT, 0x0B).
+ \row \i <b>\\xhhhh</b>
+ \i This matches the Unicode character corresponding to the
+ hexadecimal number hhhh (between 0x0000 and 0xFFFF). \0ooo
+ (i.e., \zero ooo) matches the ASCII/Latin-1 character
+ corresponding to the octal number ooo (between 0 and 0377).
+ \row \i <b>. (dot)</b>
+ \i This matches any character (including newline).
+ \row \i <b>\\d</b>
+ \i This matches a digit (TQChar::isDigit()).
+ \row \i <b>\\D</b>
+ \i This matches a non-digit.
+ \row \i <b>\\s</b>
+ \i This matches a whitespace (TQChar::isSpace()).
+ \row \i <b>\\S</b>
+ \i This matches a non-whitespace.
+ \row \i <b>\\w</b>
+ \i This matches a word character (TQChar::isLetterOrNumber() or '_').
+ \row \i <b>\\W</b>
+ \i This matches a non-word character.
+ \row \i <b>\\n</b>
+ \i The n-th \link #capturing-text backreference \endlink,
+ e.g. \1, \2, etc.
+ \endtable
+
+ \e {Note that the C++ compiler transforms backslashes in strings
+ so to include a <b>\\</b> in a regexp you will need to enter it
+ twice, i.e. <b>\\\\</b>.}
+
+ \target sets-of-characters
+ \section1 Sets of Characters
+
+ Square brackets are used to match any character in the set of
+ characters contained within the square brackets. All the character
+ set abbreviations described above can be used within square
+ brackets. Apart from the character set abbreviations and the
+ following two exceptions no characters have special meanings in
+ square brackets.
+
+ \table
+ \row \i <b>^</b>
+ \i The caret negates the character set if it occurs as the
+ first character, i.e. immediately after the opening square
+ bracket. For example, <b>[abc]</b> matches 'a' or 'b' or 'c',
+ but <b>[^abc]</b> matches anything \e except 'a' or 'b' or
+ 'c'.
+ \row \i <b>-</b>
+ \i The dash is used to indicate a range of characters, for
+ example <b>[W-Z]</b> matches 'W' or 'X' or 'Y' or 'Z'.
+ \endtable
+
+ Using the predefined character set abbreviations is more portable
+ than using character ranges across platforms and languages. For
+ example, <b>[0-9]</b> matches a digit in Western alphabets but
+ <b>\d</b> matches a digit in \e any alphabet.
+
+ Note that in most regexp literature sets of characters are called
+ "character classes".
+
+ \target quantifiers
+ \section1 Quantifiers
+
+ By default an expression is automatically quantified by
+ <b>{1,1}</b>, i.e. it should occur exactly once. In the following
+ list <b>\e {E}</b> stands for any expression. An expression is a
+ character or an abbreviation for a set of characters or a set of
+ characters in square brackets or any parenthesised expression.
+
+ \table
+ \row \i <b>\e {E}?</b>
+ \i Matches zero or one occurrence of \e E. This quantifier
+ means "the previous expression is optional" since it will
+ match whether or not the expression occurs in the string. It
+ is the same as <b>\e {E}{0,1}</b>. For example <b>dents?</b>
+ will match 'dent' and 'dents'.
+
+ \row \i <b>\e {E}+</b>
+ \i Matches one or more occurrences of \e E. This is the same
+ as <b>\e {E}{1,MAXINT}</b>. For example, <b>0+</b> will match
+ '0', '00', '000', etc.
+
+ \row \i <b>\e {E}*</b>
+ \i Matches zero or more occurrences of \e E. This is the same
+ as <b>\e {E}{0,MAXINT}</b>. The <b>*</b> quantifier is often
+ used by a mistake. Since it matches \e zero or more
+ occurrences it will match no occurrences at all. For example
+ if we want to match strings that end in whitespace and use
+ the regexp <b>\s*$</b> we would get a match on every string.
+ This is because we have said tqfind zero or more whitespace
+ followed by the end of string, so even strings that don't end
+ in whitespace will match. The regexp we want in this case is
+ <b>\s+$</b> to match strings that have at least one
+ whitespace at the end.
+
+ \row \i <b>\e {E}{n}</b>
+ \i Matches exactly \e n occurrences of the expression. This
+ is the same as repeating the expression \e n times. For
+ example, <b>x{5}</b> is the same as <b>xxxxx</b>. It is also
+ the same as <b>\e {E}{n,n}</b>, e.g. <b>x{5,5}</b>.
+
+ \row \i <b>\e {E}{n,}</b>
+ \i Matches at least \e n occurrences of the expression. This
+ is the same as <b>\e {E}{n,MAXINT}</b>.
+
+ \row \i <b>\e {E}{,m}</b>
+ \i Matches at most \e m occurrences of the expression. This
+ is the same as <b>\e {E}{0,m}</b>.
+
+ \row \i <b>\e {E}{n,m}</b>
+ \i Matches at least \e n occurrences of the expression and at
+ most \e m occurrences of the expression.
+ \endtable
+
+ (MAXINT is implementation dependent but will not be smaller than
+ 1024.)
+
+ If we wish to apply a quantifier to more than just the preceding
+ character we can use parentheses to group characters together in
+ an expression. For example, <b>tag+</b> matches a 't' followed by
+ an 'a' followed by at least one 'g', whereas <b>(tag)+</b> matches
+ at least one occurrence of 'tag'.
+
+ Note that quantifiers are "greedy". They will match as much text
+ as they can. For example, <b>0+</b> will match as many zeros as it
+ can from the first zero it tqfinds, e.g. '2.<u>000</u>5'.
+ Quantifiers can be made non-greedy, see setMinimal().
+
+ \target capturing-text
+ \section1 Capturing Text
+
+ Parentheses allow us to group elements together so that we can
+ quantify and capture them. For example if we have the expression
+ <b>mail|letter|correspondence</b> that matches a string we know
+ that \e one of the words matched but not which one. Using
+ parentheses allows us to "capture" whatever is matched within
+ their bounds, so if we used <b>(mail|letter|correspondence)</b>
+ and matched this regexp against the string "I sent you some email"
+ we can use the cap() or capturedTexts() functions to extract the
+ matched characters, in this case 'mail'.
+
+ We can use captured text within the regexp itself. To refer to the
+ captured text we use \e backreferences which are indexed from 1,
+ the same as for cap(). For example we could search for duplicate
+ words in a string using <b>\b(\w+)\W+\1\b</b> which means match a
+ word boundary followed by one or more word characters followed by
+ one or more non-word characters followed by the same text as the
+ first parenthesised expression followed by a word boundary.
+
+ If we want to use parentheses purely for grouping and not for
+ capturing we can use the non-capturing syntax, e.g.
+ <b>(?:green|blue)</b>. Non-capturing parentheses begin '(?:' and
+ end ')'. In this example we match either 'green' or 'blue' but we
+ do not capture the match so we only know whether or not we matched
+ but not which color we actually found. Using non-capturing
+ parentheses is more efficient than using capturing parentheses
+ since the regexp engine has to do less book-keeping.
+
+ Both capturing and non-capturing parentheses may be nested.
+
+ \target assertions
+ \section1 Assertions
+
+ Assertions make some statement about the text at the point where
+ they occur in the regexp but they do not match any characters. In
+ the following list <b>\e {E}</b> stands for any expression.
+
+ \table
+ \row \i <b>^</b>
+ \i The caret signifies the beginning of the string. If you
+ wish to match a literal \c{^} you must escape it by
+ writing <b>&#92;^</b>. For example, <b>^#include</b> will only
+ match strings which \e begin with the characters '#include'.
+ (When the caret is the first character of a character set it
+ has a special meaning, see \link #sets-of-characters Sets of
+ Characters \endlink.)
+
+ \row \i <b>$</b>
+ \i The dollar signifies the end of the string. For example
+ <b>\d\s*$</b> will match strings which end with a digit
+ optionally followed by whitespace. If you wish to match a
+ literal \c{$} you must escape it by writing
+ <b>&#92;$</b>.
+
+ \row \i <b>\\b</b>
+ \i A word boundary. For example the regexp
+ <b>\\bOK\\b</b> means match immediately after a word
+ boundary (e.g. start of string or whitespace) the letter 'O'
+ then the letter 'K' immediately before another word boundary
+ (e.g. end of string or whitespace). But note that the
+ assertion does not actually match any whitespace so if we
+ write <b>(\\bOK\\b)</b> and we have a match it will only
+ contain 'OK' even if the string is "Its <u>OK</u> now".
+
+ \row \i <b>\\B</b>
+ \i A non-word boundary. This assertion is true wherever
+ <b>\\b</b> is false. For example if we searched for
+ <b>\\Bon\\B</b> in "Left on" the match would fail (space
+ and end of string aren't non-word boundaries), but it would
+ match in "t<u>on</u>ne".
+
+ \row \i <b>(?=\e E)</b>
+ \i Positive lookahead. This assertion is true if the
+ expression matches at this point in the regexp. For example,
+ <b>const(?=\\s+char)</b> matches 'const' whenever it is
+ followed by 'char', as in 'static <u>const</u> char *'.
+ (Compare with <b>const\\s+char</b>, which matches 'static
+ <u>const char</u> *'.)
+
+ \row \i <b>(?!\e E)</b>
+ \i Negative lookahead. This assertion is true if the
+ expression does not match at this point in the regexp. For
+ example, <b>const(?!\\s+char)</b> matches 'const' \e except
+ when it is followed by 'char'.
+ \endtable
+
+ \target wildcard-matching
+ \section1 Wildcard Matching (globbing)
+
+ Most command shells such as \e bash or \e cmd.exe support "file
+ globbing", the ability to identify a group of files by using
+ wildcards. The setWildcard() function is used to switch between
+ regexp and wildcard mode. Wildcard matching is much simpler than
+ full regexps and has only four features:
+
+ \table
+ \row \i <b>c</b>
+ \i Any character represents itself apart from those mentioned
+ below. Thus <b>c</b> matches the character \e c.
+ \row \i <b>?</b>
+ \i This matches any single character. It is the same as
+ <b>.</b> in full regexps.
+ \row \i <b>*</b>
+ \i This matches zero or more of any characters. It is the
+ same as <b>.*</b> in full regexps.
+ \row \i <b>[...]</b>
+ \i Sets of characters can be represented in square brackets,
+ similar to full regexps. Within the character class, like
+ outside, backslash has no special meaning.
+ \endtable
+
+ For example if we are in wildcard mode and have strings which
+ contain filenames we could identify HTML files with <b>*.html</b>.
+ This will match zero or more characters followed by a dot followed
+ by 'h', 't', 'm' and 'l'.
+
+ \target perl-users
+ \section1 Notes for Perl Users
+
+ Most of the character class abbreviations supported by Perl are
+ supported by TQRegExp, see \link
+ #characters-and-abbreviations-for-sets-of-characters characters
+ and abbreviations for sets of characters \endlink.
+
+ In TQRegExp, apart from within character classes, \c{^} always
+ signifies the start of the string, so carets must always be
+ escaped unless used for that purpose. In Perl the meaning of caret
+ varies automagically depending on where it occurs so escaping it
+ is rarely necessary. The same applies to \c{$} which in
+ TQRegExp always signifies the end of the string.
+
+ TQRegExp's quantifiers are the same as Perl's greedy quantifiers.
+ Non-greedy matching cannot be applied to individual quantifiers,
+ but can be applied to all the quantifiers in the pattern. For
+ example, to match the Perl regexp <b>ro+?m</b> requires:
+ \code
+ TQRegExp rx( "ro+m" );
+ rx.setMinimal( TRUE );
+ \endcode
+
+ The equivalent of Perl's \c{/i} option is
+ setCaseSensitive(FALSE).
+
+ Perl's \c{/g} option can be emulated using a \link
+ #cap_in_a_loop loop \endlink.
+
+ In TQRegExp <b>.</b> matches any character, therefore all TQRegExp
+ regexps have the equivalent of Perl's \c{/s} option. TQRegExp
+ does not have an equivalent to Perl's \c{/m} option, but this
+ can be emulated in various ways for example by splitting the input
+ into lines or by looping with a regexp that searches for newlines.
+
+ Because TQRegExp is string oriented there are no \A, \Z or \z
+ assertions. The \G assertion is not supported but can be emulated
+ in a loop.
+
+ Perl's $& is cap(0) or capturedTexts()[0]. There are no TQRegExp
+ equivalents for $`, $' or $+. Perl's capturing variables, $1, $2,
+ ... correspond to cap(1) or capturedTexts()[1], cap(2) or
+ capturedTexts()[2], etc.
+
+ To substitute a pattern use TQString::tqreplace().
+
+ Perl's extended \c{/x} syntax is not supported, nor are
+ directives, e.g. (?i), or regexp comments, e.g. (?#comment). On
+ the other hand, C++'s rules for literal strings can be used to
+ achieve the same:
+ \code
+ TQRegExp mark( "\\b" // word boundary
+ "[Mm]ark" // the word we want to match
+ );
+ \endcode
+
+ Both zero-width positive and zero-width negative lookahead
+ assertions (?=pattern) and (?!pattern) are supported with the same
+ syntax as Perl. Perl's lookbehind assertions, "independent"
+ subexpressions and conditional expressions are not supported.
+
+ Non-capturing parentheses are also supported, with the same
+ (?:pattern) syntax.
+
+ See TQStringList::split() and TQStringList::join() for equivalents
+ to Perl's split and join functions.
+
+ Note: because C++ transforms \\'s they must be written \e twice in
+ code, e.g. <b>\\b</b> must be written <b>\\\\b</b>.
+
+ \target code-examples
+ \section1 Code Examples
+
+ \code
+ TQRegExp rx( "^\\d\\d?$" ); // match integers 0 to 99
+ rx.search( "123" ); // returns -1 (no match)
+ rx.search( "-6" ); // returns -1 (no match)
+ rx.search( "6" ); // returns 0 (matched as position 0)
+ \endcode
+
+ The third string matches '<u>6</u>'. This is a simple validation
+ regexp for integers in the range 0 to 99.
+
+ \code
+ TQRegExp rx( "^\\S+$" ); // match strings without whitespace
+ rx.search( "Hello world" ); // returns -1 (no match)
+ rx.search( "This_is-OK" ); // returns 0 (matched at position 0)
+ \endcode
+
+ The second string matches '<u>This_is-OK</u>'. We've used the
+ character set abbreviation '\S' (non-whitespace) and the anchors
+ to match strings which contain no whitespace.
+
+ In the following example we match strings containing 'mail' or
+ 'letter' or 'correspondence' but only match whole words i.e. not
+ 'email'
+
+ \code
+ TQRegExp rx( "\\b(mail|letter|correspondence)\\b" );
+ rx.search( "I sent you an email" ); // returns -1 (no match)
+ rx.search( "Please write the letter" ); // returns 17
+ \endcode
+
+ The second string matches "Please write the <u>letter</u>". The
+ word 'letter' is also captured (because of the parentheses). We
+ can see what text we've captured like this:
+
+ \code
+ TQString captured = rx.cap( 1 ); // captured == "letter"
+ \endcode
+
+ This will capture the text from the first set of capturing
+ parentheses (counting capturing left parentheses from left to
+ right). The parentheses are counted from 1 since cap( 0 ) is the
+ whole matched regexp (equivalent to '&' in most regexp engines).
+
+ \code
+ TQRegExp rx( "&(?!amp;)" ); // match ampersands but not &amp;
+ TQString line1 = "This & that";
+ line1.tqreplace( rx, "&amp;" );
+ // line1 == "This &amp; that"
+ TQString line2 = "His &amp; hers & theirs";
+ line2.tqreplace( rx, "&amp;" );
+ // line2 == "His &amp; hers &amp; theirs"
+ \endcode
+
+ Here we've passed the TQRegExp to TQString's tqreplace() function to
+ tqreplace the matched text with new text.
+
+ \code
+ TQString str = "One Eric another Eirik, and an Ericsson."
+ " How many Eiriks, Eric?";
+ TQRegExp rx( "\\b(Eric|Eirik)\\b" ); // match Eric or Eirik
+ int pos = 0; // where we are in the string
+ int count = 0; // how many Eric and Eirik's we've counted
+ while ( pos >= 0 ) {
+ pos = rx.search( str, pos );
+ if ( pos >= 0 ) {
+ pos++; // move along in str
+ count++; // count our Eric or Eirik
+ }
+ }
+ \endcode
+
+ We've used the search() function to repeatedly match the regexp in
+ the string. Note that instead of moving forward by one character
+ at a time \c pos++ we could have written \c {pos +=
+ rx.matchedLength()} to skip over the already matched string. The
+ count will equal 3, matching 'One <u>Eric</u> another
+ <u>Eirik</u>, and an Ericsson. How many Eiriks, <u>Eric</u>?'; it
+ doesn't match 'Ericsson' or 'Eiriks' because they are not bounded
+ by non-word boundaries.
+
+ One common use of regexps is to split lines of delimited data into
+ their component fields.
+
+ \code
+ str = "Trolltech AS\twww.trolltech.com\tNorway";
+ TQString company, web, country;
+ rx.setPattern( "^([^\t]+)\t([^\t]+)\t([^\t]+)$" );
+ if ( rx.search( str ) != -1 ) {
+ company = rx.cap( 1 );
+ web = rx.cap( 2 );
+ country = rx.cap( 3 );
+ }
+ \endcode
+
+ In this example our input lines have the format company name, web
+ address and country. Unfortunately the regexp is rather long and
+ not very versatile -- the code will break if we add any more
+ fields. A simpler and better solution is to look for the
+ separator, '\t' in this case, and take the surrounding text. The
+ TQStringList split() function can take a separator string or regexp
+ as an argument and split a string accordingly.
+
+ \code
+ TQStringList field = TQStringList::split( "\t", str );
+ \endcode
+
+ Here field[0] is the company, field[1] the web address and so on.
+
+ To imitate the matching of a shell we can use wildcard mode.
+
+ \code
+ TQRegExp rx( "*.html" ); // invalid regexp: * doesn't quantify anything
+ rx.setWildcard( TRUE ); // now it's a valid wildcard regexp
+ rx.exactMatch( "index.html" ); // returns TRUE
+ rx.exactMatch( "default.htm" ); // returns FALSE
+ rx.exactMatch( "readme.txt" ); // returns FALSE
+ \endcode
+
+ Wildcard matching can be convenient because of its simplicity, but
+ any wildcard regexp can be defined using full regexps, e.g.
+ <b>.*\.html$</b>. Notice that we can't match both \c .html and \c
+ .htm files with a wildcard unless we use <b>*.htm*</b> which will
+ also match 'test.html.bak'. A full regexp gives us the precision
+ we need, <b>.*\\.html?$</b>.
+
+ TQRegExp can match case insensitively using setCaseSensitive(), and
+ can use non-greedy matching, see setMinimal(). By default TQRegExp
+ uses full regexps but this can be changed with setWildcard().
+ Searching can be forward with search() or backward with
+ searchRev(). Captured text can be accessed using capturedTexts()
+ which returns a string list of all captured strings, or using
+ cap() which returns the captured string for the given index. The
+ pos() function takes a match index and returns the position in the
+ string where the match was made (or -1 if there was no match).
+
+ \sa TQRegExpValidator TQString TQStringList
+
+ \target member-function-documentation
+*/
+
+const int NumBadChars = 64;
+#define BadChar( ch ) ( (ch).tqunicode() % NumBadChars )
+
+const int NoOccurrence = INT_MAX;
+const int EmptyCapture = INT_MAX;
+const int InftyLen = INT_MAX;
+const int InftyRep = 1025;
+const int EOS = -1;
+
+static bool isWord( TQChar ch )
+{
+ return ch.isLetterOrNumber() || ch == TQChar( '_' );
+}
+
+/*
+ Merges two TQMemArrays of ints and puts the result into the first
+ one.
+*/
+static void mergeInto( TQMemArray<int> *a, const TQMemArray<int>& b )
+{
+ int asize = a->size();
+ int bsize = b.size();
+ if ( asize == 0 ) {
+ *a = b.copy();
+#ifndef TQT_NO_REGEXP_OPTIM
+ } else if ( bsize == 1 && (*a)[asize - 1] < b[0] ) {
+ a->resize( asize + 1 );
+ (*a)[asize] = b[0];
+#endif
+ } else if ( bsize >= 1 ) {
+ int csize = asize + bsize;
+ TQMemArray<int> c( csize );
+ int i = 0, j = 0, k = 0;
+ while ( i < asize ) {
+ if ( j < bsize ) {
+ if ( (*a)[i] == b[j] ) {
+ i++;
+ csize--;
+ } else if ( (*a)[i] < b[j] ) {
+ c[k++] = (*a)[i++];
+ } else {
+ c[k++] = b[j++];
+ }
+ } else {
+ memcpy( c.data() + k, (*a).data() + i,
+ (asize - i) * sizeof(int) );
+ break;
+ }
+ }
+ c.resize( csize );
+ if ( j < bsize )
+ memcpy( c.data() + k, b.data() + j, (bsize - j) * sizeof(int) );
+ *a = c;
+ }
+}
+
+/*
+ Merges two disjoint TQMaps of (int, int) pairs and puts the result
+ into the first one.
+*/
+static void mergeInto( TQMap<int, int> *a, const TQMap<int, int>& b )
+{
+ TQMap<int, int>::ConstIterator it;
+ for ( it = b.begin(); it != b.end(); ++it )
+ a->insert( it.key(), *it );
+}
+
+/*
+ Returns the value associated to key k in TQMap m of (int, int)
+ pairs, or 0 if no such value is explicitly present.
+*/
+static int at( const TQMap<int, int>& m, int k )
+{
+ TQMap<int, int>::ConstIterator it = m.tqfind( k );
+ if ( it == m.end() )
+ return 0;
+ else
+ return *it;
+}
+
+#ifndef TQT_NO_REGEXP_WILDCARD
+/*
+ Translates a wildcard pattern to an equivalent regular expression
+ pattern (e.g., *.cpp to .*\.cpp).
+*/
+static TQString wc2rx( const TQString& wc_str )
+{
+ int wclen = wc_str.length();
+ TQString rx = TQString::tqfromLatin1( "" );
+ int i = 0;
+ const TQChar *wc = wc_str.tqunicode();
+ while ( i < wclen ) {
+ TQChar c = wc[i++];
+ switch ( c.tqunicode() ) {
+ case '*':
+ rx += TQString::tqfromLatin1( ".*" );
+ break;
+ case '?':
+ rx += TQChar( '.' );
+ break;
+ case '$':
+ case '(':
+ case ')':
+ case '+':
+ case '.':
+ case '\\':
+ case '^':
+ case '{':
+ case '|':
+ case '}':
+ rx += TQChar( '\\' );
+ rx += c;
+ break;
+ case '[':
+ rx += c;
+ if ( wc[i] == TQChar('^') )
+ rx += wc[i++];
+ if ( i < wclen ) {
+ if ( rx[i] == ']' )
+ rx += wc[i++];
+ while ( i < wclen && wc[i] != TQChar(']') ) {
+ if ( wc[i] == '\\' )
+ rx += TQChar( '\\' );
+ rx += wc[i++];
+ }
+ }
+ break;
+ default:
+ rx += c;
+ }
+ }
+ return rx;
+}
+#endif
+
+/*
+ The class TQRegExpEngine encapsulates a modified nondeterministic
+ finite automaton (NFA).
+*/
+class TQRegExpEngine : public TQShared
+{
+public:
+#ifndef TQT_NO_REGEXP_CCLASS
+ /*
+ The class CharClass represents a set of characters, such as can
+ be found in regular expressions (e.g., [a-z] denotes the set
+ {a, b, ..., z}).
+ */
+ class CharClass
+ {
+ public:
+ CharClass();
+ CharClass( const CharClass& cc ) { operator=( cc ); }
+
+ CharClass& operator=( const CharClass& cc );
+
+ void clear();
+ bool negative() const { return n; }
+ void setNegative( bool negative );
+ void addCategories( int cats );
+ void addRange( ushort from, ushort to );
+ void addSingleton( ushort ch ) { addRange( ch, ch ); }
+
+ bool in( TQChar ch ) const;
+#ifndef TQT_NO_REGEXP_OPTIM
+ const TQMemArray<int>& firstOccurrence() const { return occ1; }
+#endif
+
+#if defined(TQT_DEBUG)
+ void dump() const;
+#endif
+
+ private:
+ /*
+ The struct Range represents a range of characters (e.g.,
+ [0-9] denotes range 48 to 57).
+ */
+ struct Range
+ {
+ ushort from; // 48
+ ushort to; // 57
+ };
+
+ int c; // character classes
+ TQMemArray<Range> r; // character ranges
+ bool n; // negative?
+#ifndef TQT_NO_REGEXP_OPTIM
+ TQMemArray<int> occ1; // first-occurrence array
+#endif
+ };
+#else
+ struct CharClass
+ {
+ int dummy;
+
+#ifndef TQT_NO_REGEXP_OPTIM
+ CharClass() { occ1.fill( 0, NumBadChars ); }
+
+ const TQMemArray<int>& firstOccurrence() const { return occ1; }
+ TQMemArray<int> occ1;
+#endif
+ };
+#endif
+
+ TQRegExpEngine( bool caseSensitive ) { setup( caseSensitive ); }
+ TQRegExpEngine( const TQString& rx, bool caseSensitive );
+#ifndef TQT_NO_REGEXP_OPTIM
+ ~TQRegExpEngine();
+#endif
+
+ bool isValid() const { return valid; }
+ bool caseSensitive() const { return cs; }
+ const TQString& errorString() const { return yyError; }
+ int numCaptures() const { return officialncap; }
+ void match( const TQString& str, int pos, bool minimal, bool oneTest,
+ int caretIndex, TQMemArray<int>& captured );
+ int partialMatchLength() const { return mmOneTestMatchedLen; }
+
+ int createState( TQChar ch );
+ int createState( const CharClass& cc );
+#ifndef TQT_NO_REGEXP_BACKREF
+ int createState( int bref );
+#endif
+
+ void addCatTransitions( const TQMemArray<int>& from,
+ const TQMemArray<int>& to );
+#ifndef TQT_NO_REGEXP_CAPTURE
+ void addPlusTransitions( const TQMemArray<int>& from,
+ const TQMemArray<int>& to, int atom );
+#endif
+
+#ifndef TQT_NO_REGEXP_ANCHOR_ALT
+ int anchorAlternation( int a, int b );
+ int anchorConcatenation( int a, int b );
+#else
+ int anchorAlternation( int a, int b ) { return a & b; }
+ int anchorConcatenation( int a, int b ) { return a | b; }
+#endif
+ void addAnchors( int from, int to, int a );
+
+#ifndef TQT_NO_REGEXP_OPTIM
+ void heuristicallyChooseHeuristic();
+#endif
+
+#if defined(TQT_DEBUG)
+ void dump() const;
+#endif
+
+private:
+ enum { CharClassBit = 0x10000, BackRefBit = 0x20000 };
+
+ /*
+ The struct State represents one state in a modified NFA. The
+ input characters matched are stored in the state instead of on
+ the transitions, something possible for an automaton
+ constructed from a regular expression.
+ */
+ struct State
+ {
+#ifndef TQT_NO_REGEXP_CAPTURE
+ int atom; // which atom does this state belong to?
+#endif
+ int match; // what does it match? (see CharClassBit and BackRefBit)
+ TQMemArray<int> outs; // out-transitions
+ TQMap<int, int> *reenter; // atoms reentered when transiting out
+ TQMap<int, int> *anchors; // anchors met when transiting out
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+ State( int a, int m )
+ : atom( a ), match( m ), reenter( 0 ), anchors( 0 ) { }
+#else
+ State( int m )
+ : match( m ), reenter( 0 ), anchors( 0 ) { }
+#endif
+ ~State() { delete reenter; delete anchors; }
+ };
+
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+ /*
+ The struct Lookahead represents a lookahead a la Perl (e.g.,
+ (?=foo) and (?!bar)).
+ */
+ struct Lookahead
+ {
+ TQRegExpEngine *eng; // NFA representing the embedded regular expression
+ bool neg; // negative lookahead?
+
+ Lookahead( TQRegExpEngine *eng0, bool neg0 )
+ : eng( eng0 ), neg( neg0 ) { }
+ ~Lookahead() { delete eng; }
+ };
+#endif
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+ /*
+ The struct Atom represents one node in the hierarchy of regular
+ expression atoms.
+ */
+ struct Atom
+ {
+ int tqparent; // index of tqparent in array of atoms
+ int capture; // index of capture, from 1 to ncap
+ };
+#endif
+
+#ifndef TQT_NO_REGEXP_ANCHOR_ALT
+ /*
+ The struct AnchorAlternation represents a pair of anchors with
+ OR semantics.
+ */
+ struct AnchorAlternation
+ {
+ int a; // this anchor...
+ int b; // ...or this one
+ };
+#endif
+
+ enum { InitialState = 0, FinalState = 1 };
+ void setup( bool caseSensitive );
+ int setupState( int match );
+
+ /*
+ Let's hope that 13 lookaheads and 14 back-references are
+ enough.
+ */
+ enum { MaxLookaheads = 13, MaxBackRefs = 14 };
+ enum { Anchor_Dollar = 0x00000001, Anchor_Caret = 0x00000002,
+ Anchor_Word = 0x00000004, Anchor_NonWord = 0x00000008,
+ Anchor_FirstLookahead = 0x00000010,
+ Anchor_BackRef1Empty = Anchor_FirstLookahead << MaxLookaheads,
+ Anchor_BackRef0Empty = Anchor_BackRef1Empty >> 1,
+ Anchor_Alternation = Anchor_BackRef1Empty << MaxBackRefs,
+
+ Anchor_LookaheadMask = ( Anchor_FirstLookahead - 1 ) ^
+ ( (Anchor_FirstLookahead << MaxLookaheads) - 1 ) };
+#ifndef TQT_NO_REGEXP_CAPTURE
+ int startAtom( bool capture );
+ void finishAtom( int atom ) { cf = f[atom].tqparent; }
+#endif
+
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+ int addLookahead( TQRegExpEngine *eng, bool negative );
+#endif
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+ bool isBetterCapture( const int *begin1, const int *end1, const int *begin2,
+ const int *end2 );
+#endif
+ bool testAnchor( int i, int a, const int *capBegin );
+
+#ifndef TQT_NO_REGEXP_OPTIM
+ bool goodStringMatch();
+ bool badCharMatch();
+#else
+ bool bruteMatch();
+#endif
+ bool matchHere();
+
+ TQPtrVector<State> s; // array of states
+ int ns; // number of states
+#ifndef TQT_NO_REGEXP_CAPTURE
+ TQMemArray<Atom> f; // atom hierarchy
+ int nf; // number of atoms
+ int cf; // current atom
+#endif
+ int officialncap; // number of captures, seen from the outside
+ int ncap; // number of captures, seen from the inside
+#ifndef TQT_NO_REGEXP_CCLASS
+ TQPtrVector<CharClass> cl; // array of character classes
+#endif
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+ TQPtrVector<Lookahead> ahead; // array of lookaheads
+#endif
+#ifndef TQT_NO_REGEXP_ANCHOR_ALT
+ TQMemArray<AnchorAlternation> aa; // array of (a, b) pairs of anchors
+#endif
+#ifndef TQT_NO_REGEXP_OPTIM
+ bool caretAnchored; // does the regexp start with ^?
+ bool trivial; // is the good-string all that needs to match?
+#endif
+ bool valid; // is the regular expression valid?
+ bool cs; // case sensitive?
+#ifndef TQT_NO_REGEXP_BACKREF
+ int nbrefs; // number of back-references
+#endif
+
+#ifndef TQT_NO_REGEXP_OPTIM
+ bool useGoodStringHeuristic; // use goodStringMatch? otherwise badCharMatch
+
+ int goodEarlyStart; // the index where goodStr can first occur in a match
+ int goodLateStart; // the index where goodStr can last occur in a match
+ TQString goodStr; // the string that any match has to contain
+
+ int minl; // the minimum length of a match
+ TQMemArray<int> occ1; // first-occurrence array
+#endif
+
+ /*
+ The class Box is an abstraction for a regular expression
+ fragment. It can also be seen as one node in the syntax tree of
+ a regular expression with synthetized attributes.
+
+ Its interface is ugly for performance reasons.
+ */
+ class Box
+ {
+ public:
+ Box( TQRegExpEngine *engine );
+ Box( const Box& b ) { operator=( b ); }
+
+ Box& operator=( const Box& b );
+
+ void clear() { operator=( Box(eng) ); }
+ void set( TQChar ch );
+ void set( const CharClass& cc );
+#ifndef TQT_NO_REGEXP_BACKREF
+ void set( int bref );
+#endif
+
+ void cat( const Box& b );
+ void orx( const Box& b );
+ void plus( int atom );
+ void opt();
+ void catAnchor( int a );
+#ifndef TQT_NO_REGEXP_OPTIM
+ void setupHeuristics();
+#endif
+
+#if defined(TQT_DEBUG)
+ void dump() const;
+#endif
+
+ private:
+ void addAnchorsToEngine( const Box& to ) const;
+
+ TQRegExpEngine *eng; // the automaton under construction
+ TQMemArray<int> ls; // the left states (firstpos)
+ TQMemArray<int> rs; // the right states (lastpos)
+ TQMap<int, int> lanchors; // the left anchors
+ TQMap<int, int> ranchors; // the right anchors
+ int skipanchors; // the anchors to match if the box is skipped
+
+#ifndef TQT_NO_REGEXP_OPTIM
+ int earlyStart; // the index where str can first occur
+ int lateStart; // the index where str can last occur
+ TQString str; // a string that has to occur in any match
+ TQString leftStr; // a string occurring at the left of this box
+ TQString rightStr; // a string occurring at the right of this box
+ int maxl; // the maximum length of this box (possibly InftyLen)
+#endif
+
+ int minl; // the minimum length of this box
+#ifndef TQT_NO_REGEXP_OPTIM
+ TQMemArray<int> occ1; // first-occurrence array
+#endif
+ };
+ friend class Box;
+
+ /*
+ This is the lexical analyzer for regular expressions.
+ */
+ enum { Tok_Eos, Tok_Dollar, Tok_LeftParen, Tok_MagicLeftParen,
+ Tok_PosLookahead, Tok_NegLookahead, Tok_RightParen, Tok_CharClass,
+ Tok_Caret, Tok_Quantifier, Tok_Bar, Tok_Word, Tok_NonWord,
+ Tok_Char = 0x10000, Tok_BackRef = 0x20000 };
+ int getChar();
+ int getEscape();
+#ifndef TQT_NO_REGEXP_INTERVAL
+ int getRep( int def );
+#endif
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+ void skipChars( int n );
+#endif
+ void error( const char *msg );
+ void startTokenizer( const TQChar *rx, int len );
+ int getToken();
+
+ const TQChar *yyIn; // a pointer to the input regular expression pattern
+ int yyPos0; // the position of yyTok in the input pattern
+ int yyPos; // the position of the next character to read
+ int yyLen; // the length of yyIn
+ int yyCh; // the last character read
+ CharClass *yyCharClass; // attribute for Tok_CharClass tokens
+ int yyMinRep; // attribute for Tok_Quantifier
+ int yyMaxRep; // ditto
+ TQString yyError; // syntax error or overflow during parsing?
+
+ /*
+ This is the syntactic analyzer for regular expressions.
+ */
+ int parse( const TQChar *rx, int len );
+ void parseAtom( Box *box );
+ void parseFactor( Box *box );
+ void parseTerm( Box *box );
+ void parseExpression( Box *box );
+
+ int yyTok; // the last token read
+ bool yyMayCapture; // set this to FALSE to disable capturing
+
+ /*
+ This is the engine state during matching.
+ */
+ const TQString *mmStr; // a pointer to the input TQString
+ const TQChar *mmIn; // a pointer to the input string data
+ int mmPos; // the current position in the string
+ int mmCaretPos;
+ int mmLen; // the length of the input string
+ bool mmMinimal; // minimal matching?
+ TQMemArray<int> mmBigArray; // big TQMemArray<int> array
+ int *mmInNextStack; // is state is mmNextStack?
+ int *mmCurStack; // stack of current states
+ int *mmNextStack; // stack of next states
+ int *mmCurCapBegin; // start of current states' captures
+ int *mmNextCapBegin; // start of next states' captures
+ int *mmCurCapEnd; // end of current states' captures
+ int *mmNextCapEnd; // end of next states' captures
+ int *mmTempCapBegin; // start of temporary captures
+ int *mmTempCapEnd; // end of temporary captures
+ int *mmCapBegin; // start of captures for a next state
+ int *mmCapEnd; // end of captures for a next state
+ int *mmSlideTab; // bump-along slide table for bad-character heuristic
+ int mmSlideTabSize; // size of slide table
+#ifndef TQT_NO_REGEXP_BACKREF
+ TQIntDict<int> mmSleeping; // dictionary of back-reference sleepers
+#endif
+ int mmMatchLen; // length of match
+ int mmOneTestMatchedLen; // length of partial match
+};
+
+TQRegExpEngine::TQRegExpEngine( const TQString& rx, bool caseSensitive )
+#ifndef TQT_NO_REGEXP_BACKREF
+ : mmSleeping( 101 )
+#endif
+{
+ setup( caseSensitive );
+ valid = ( parse(rx.tqunicode(), rx.length()) == (int) rx.length() );
+ if ( !valid ) {
+#ifndef TQT_NO_REGEXP_OPTIM
+ trivial = FALSE;
+#endif
+ error( RXERR_LEFTDELIM );
+ }
+}
+
+#ifndef TQT_NO_REGEXP_OPTIM
+TQRegExpEngine::~TQRegExpEngine()
+{
+}
+#endif
+
+/*
+ Tries to match in str and returns an array of (begin, length) pairs
+ for captured text. If there is no match, all pairs are (-1, -1).
+*/
+void TQRegExpEngine::match( const TQString& str, int pos, bool minimal,
+ bool oneTest, int caretIndex,
+ TQMemArray<int>& captured )
+{
+ bool matched = FALSE;
+
+#ifndef TQT_NO_REGEXP_OPTIM
+ if ( trivial && !oneTest ) {
+ mmPos = str.tqfind( goodStr, pos, cs );
+ mmMatchLen = goodStr.length();
+ matched = ( mmPos != -1 );
+ } else
+#endif
+ {
+ mmStr = &str;
+ mmIn = str.tqunicode();
+ if ( mmIn == 0 )
+ mmIn = &TQChar::null;
+ mmPos = pos;
+ mmCaretPos = caretIndex;
+ mmLen = str.length();
+ mmMinimal = minimal;
+ mmMatchLen = 0;
+ mmOneTestMatchedLen = 0;
+
+ if ( valid && mmPos >= 0 && mmPos <= mmLen ) {
+#ifndef TQT_NO_REGEXP_OPTIM
+ if ( oneTest ) {
+ matched = matchHere();
+ } else {
+ if ( mmPos <= mmLen - minl ) {
+ if ( caretAnchored ) {
+ matched = matchHere();
+ } else if ( useGoodStringHeuristic ) {
+ matched = goodStringMatch();
+ } else {
+ matched = badCharMatch();
+ }
+ }
+ }
+#else
+ matched = oneTest ? matchHere() : bruteMatch();
+#endif
+ }
+ }
+
+ int capturedSize = 2 + 2 * officialncap;
+ captured.detach();
+ captured.resize( capturedSize );
+ if ( matched ) {
+ captured[0] = mmPos;
+ captured[1] = mmMatchLen;
+ for ( int j = 0; j < officialncap; j++ ) {
+ int len = mmCapEnd[j] - mmCapBegin[j];
+ captured[2 + 2 * j] = len > 0 ? mmPos + mmCapBegin[j] : 0;
+ captured[2 + 2 * j + 1] = len;
+ }
+ } else {
+ // we rely on 2's complement here
+ memset( captured.data(), -1, capturedSize * sizeof(int) );
+ }
+}
+
+/*
+ The three following functions add one state to the automaton and
+ return the number of the state.
+*/
+
+int TQRegExpEngine::createState( TQChar ch )
+{
+ return setupState( ch.tqunicode() );
+}
+
+int TQRegExpEngine::createState( const CharClass& cc )
+{
+#ifndef TQT_NO_REGEXP_CCLASS
+ int n = cl.size();
+ cl.resize( n + 1 );
+ cl.insert( n, new CharClass(cc) );
+ return setupState( CharClassBit | n );
+#else
+ TQ_UNUSED( cc );
+ return setupState( CharClassBit );
+#endif
+}
+
+#ifndef TQT_NO_REGEXP_BACKREF
+int TQRegExpEngine::createState( int bref )
+{
+ if ( bref > nbrefs ) {
+ nbrefs = bref;
+ if ( nbrefs > MaxBackRefs ) {
+ error( RXERR_LIMIT );
+ return 0;
+ }
+ }
+ return setupState( BackRefBit | bref );
+}
+#endif
+
+/*
+ The two following functions add a transition between all pairs of
+ states (i, j) where i is fond in from, and j is found in to.
+
+ Cat-transitions are distinguished from plus-transitions for
+ capturing.
+*/
+
+void TQRegExpEngine::addCatTransitions( const TQMemArray<int>& from,
+ const TQMemArray<int>& to )
+{
+ for ( int i = 0; i < (int) from.size(); i++ ) {
+ State *st = s[from[i]];
+ mergeInto( &st->outs, to );
+ }
+}
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+void TQRegExpEngine::addPlusTransitions( const TQMemArray<int>& from,
+ const TQMemArray<int>& to, int atom )
+{
+ for ( int i = 0; i < (int) from.size(); i++ ) {
+ State *st = s[from[i]];
+ TQMemArray<int> oldOuts = st->outs.copy();
+ mergeInto( &st->outs, to );
+ if ( f[atom].capture >= 0 ) {
+ if ( st->reenter == 0 )
+ st->reenter = new TQMap<int, int>;
+ for ( int j = 0; j < (int) to.size(); j++ ) {
+ if ( !st->reenter->tqcontains(to[j]) &&
+ oldOuts.bsearch(to[j]) < 0 )
+ st->reenter->insert( to[j], atom );
+ }
+ }
+ }
+}
+#endif
+
+#ifndef TQT_NO_REGEXP_ANCHOR_ALT
+/*
+ Returns an anchor that means a OR b.
+*/
+int TQRegExpEngine::anchorAlternation( int a, int b )
+{
+ if ( ((a & b) == a || (a & b) == b) && ((a | b) & Anchor_Alternation) == 0 )
+ return a & b;
+
+ int n = aa.size();
+#ifndef TQT_NO_REGEXP_OPTIM
+ if ( n > 0 && aa[n - 1].a == a && aa[n - 1].b == b )
+ return Anchor_Alternation | ( n - 1 );
+#endif
+
+ aa.resize( n + 1 );
+ aa[n].a = a;
+ aa[n].b = b;
+ return Anchor_Alternation | n;
+}
+
+/*
+ Returns an anchor that means a AND b.
+*/
+int TQRegExpEngine::anchorConcatenation( int a, int b )
+{
+ if ( ((a | b) & Anchor_Alternation) == 0 )
+ return a | b;
+ if ( (b & Anchor_Alternation) != 0 )
+ tqSwap( a, b );
+
+ int aprime = anchorConcatenation( aa[a ^ Anchor_Alternation].a, b );
+ int bprime = anchorConcatenation( aa[a ^ Anchor_Alternation].b, b );
+ return anchorAlternation( aprime, bprime );
+}
+#endif
+
+/*
+ Adds anchor a on a transition caracterised by its from state and
+ its to state.
+*/
+void TQRegExpEngine::addAnchors( int from, int to, int a )
+{
+ State *st = s[from];
+ if ( st->anchors == 0 )
+ st->anchors = new TQMap<int, int>;
+ if ( st->anchors->tqcontains(to) )
+ a = anchorAlternation( (*st->anchors)[to], a );
+ st->anchors->insert( to, a );
+}
+
+#ifndef TQT_NO_REGEXP_OPTIM
+/*
+ This function chooses between the good-string and the bad-character
+ heuristics. It computes two scores and chooses the heuristic with
+ the highest score.
+
+ Here are some common-sense constraints on the scores that should be
+ respected if the formulas are ever modified: (1) If goodStr is
+ empty, the good-string heuristic scores 0. (2) If the regular
+ expression is trivial, the good-string heuristic should be used.
+ (3) If the search is case insensitive, the good-string heuristic
+ should be used, unless it scores 0. (Case insensitivity turns all
+ entries of occ1 to 0.) (4) If (goodLateStart - goodEarlyStart) is
+ big, the good-string heuristic should score less.
+*/
+void TQRegExpEngine::heuristicallyChooseHeuristic()
+{
+ if ( minl == 0 ) {
+ useGoodStringHeuristic = FALSE;
+ } else if ( trivial ) {
+ useGoodStringHeuristic = TRUE;
+ } else {
+ /*
+ Magic formula: The good string has to constitute a good
+ proportion of the minimum-length string, and appear at a
+ more-or-less known index.
+ */
+ int goodStringScore = ( 64 * goodStr.length() / minl ) -
+ ( goodLateStart - goodEarlyStart );
+ /*
+ Less magic formula: We pick some characters at random, and
+ check whether they are good or bad.
+ */
+ int badCharScore = 0;
+ int step = TQMAX( 1, NumBadChars / 32 );
+ for ( int i = 1; i < NumBadChars; i += step ) {
+ if ( occ1[i] == NoOccurrence )
+ badCharScore += minl;
+ else
+ badCharScore += occ1[i];
+ }
+ badCharScore /= minl;
+ useGoodStringHeuristic = ( goodStringScore > badCharScore );
+ }
+}
+#endif
+
+#if defined(TQT_DEBUG)
+void TQRegExpEngine::dump() const
+{
+ int i, j;
+ qDebug( "Case %ssensitive engine", cs ? "" : "in" );
+ qDebug( " States" );
+ for ( i = 0; i < ns; i++ ) {
+ qDebug( " %d%s", i,
+ i == InitialState ? " (initial)" :
+ i == FinalState ? " (final)" : "" );
+#ifndef TQT_NO_REGEXP_CAPTURE
+ qDebug( " in atom %d", s[i]->atom );
+#endif
+ int m = s[i]->match;
+ if ( (m & CharClassBit) != 0 ) {
+ qDebug( " match character class %d", m ^ CharClassBit );
+#ifndef TQT_NO_REGEXP_CCLASS
+ cl[m ^ CharClassBit]->dump();
+#else
+ qDebug( " negative character class" );
+#endif
+ } else if ( (m & BackRefBit) != 0 ) {
+ qDebug( " match back-reference %d", m ^ BackRefBit );
+ } else if ( m >= 0x20 && m <= 0x7e ) {
+ qDebug( " match 0x%.4x (%c)", m, m );
+ } else {
+ qDebug( " match 0x%.4x", m );
+ }
+ for ( j = 0; j < (int) s[i]->outs.size(); j++ ) {
+ int next = s[i]->outs[j];
+ qDebug( " -> %d", next );
+ if ( s[i]->reenter != 0 && s[i]->reenter->tqcontains(next) )
+ qDebug( " [reenter %d]", (*s[i]->reenter)[next] );
+ if ( s[i]->anchors != 0 && at(*s[i]->anchors, next) != 0 )
+ qDebug( " [anchors 0x%.8x]", (*s[i]->anchors)[next] );
+ }
+ }
+#ifndef TQT_NO_REGEXP_CAPTURE
+ if ( nf > 0 ) {
+ qDebug( " Atom Parent Capture" );
+ for ( i = 0; i < nf; i++ )
+ qDebug( " %6d %6d %6d", i, f[i].tqparent, f[i].capture );
+ }
+#endif
+#ifndef TQT_NO_REGEXP_ANCHOR_ALT
+ for ( i = 0; i < (int) aa.size(); i++ )
+ qDebug( " Anchor alternation 0x%.8x: 0x%.8x 0x%.9x", i, aa[i].a,
+ aa[i].b );
+#endif
+}
+#endif
+
+void TQRegExpEngine::setup( bool caseSensitive )
+{
+ s.setAutoDelete( TRUE );
+ s.resize( 32 );
+ ns = 0;
+#ifndef TQT_NO_REGEXP_CAPTURE
+ f.resize( 32 );
+ nf = 0;
+ cf = -1;
+#endif
+ officialncap = 0;
+ ncap = 0;
+#ifndef TQT_NO_REGEXP_CCLASS
+ cl.setAutoDelete( TRUE );
+#endif
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+ ahead.setAutoDelete( TRUE );
+#endif
+#ifndef TQT_NO_REGEXP_OPTIM
+ caretAnchored = TRUE;
+ trivial = TRUE;
+#endif
+ valid = FALSE;
+ cs = caseSensitive;
+#ifndef TQT_NO_REGEXP_BACKREF
+ nbrefs = 0;
+#endif
+#ifndef TQT_NO_REGEXP_OPTIM
+ useGoodStringHeuristic = TRUE;
+ minl = 0;
+ occ1.fill( 0, NumBadChars );
+#endif
+}
+
+int TQRegExpEngine::setupState( int match )
+{
+ if ( (ns & (ns + 1)) == 0 && ns + 1 >= (int) s.size() )
+ s.resize( (ns + 1) << 1 );
+#ifndef TQT_NO_REGEXP_CAPTURE
+ s.insert( ns, new State(cf, match) );
+#else
+ s.insert( ns, new State(match) );
+#endif
+ return ns++;
+}
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+/*
+ Functions startAtom() and finishAtom() should be called to delimit
+ atoms. When a state is created, it is assigned to the current atom.
+ The information is later used for capturing.
+*/
+int TQRegExpEngine::startAtom( bool capture )
+{
+ if ( (nf & (nf + 1)) == 0 && nf + 1 >= (int) f.size() )
+ f.resize( (nf + 1) << 1 );
+ f[nf].tqparent = cf;
+ cf = nf++;
+ f[cf].capture = capture ? ncap++ : -1;
+ return cf;
+}
+#endif
+
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+/*
+ Creates a lookahead anchor.
+*/
+int TQRegExpEngine::addLookahead( TQRegExpEngine *eng, bool negative )
+{
+ int n = ahead.size();
+ if ( n == MaxLookaheads ) {
+ error( RXERR_LIMIT );
+ return 0;
+ }
+ ahead.resize( n + 1 );
+ ahead.insert( n, new Lookahead(eng, negative) );
+ return Anchor_FirstLookahead << n;
+}
+#endif
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+/*
+ We want the longest leftmost captures.
+*/
+bool TQRegExpEngine::isBetterCapture( const int *begin1, const int *end1,
+ const int *begin2, const int *end2 )
+{
+ for ( int i = 0; i < ncap; i++ ) {
+ int delta = begin2[i] - begin1[i]; // it has to start early...
+ if ( delta == 0 )
+ delta = end1[i] - end2[i]; // ...and end late (like a party)
+
+ if ( delta != 0 )
+ return delta > 0;
+ }
+ return FALSE;
+}
+#endif
+
+/*
+ Returns TRUE if anchor a matches at position mmPos + i in the input
+ string, otherwise FALSE.
+*/
+bool TQRegExpEngine::testAnchor( int i, int a, const int *capBegin )
+{
+ int j;
+
+#ifndef TQT_NO_REGEXP_ANCHOR_ALT
+ if ( (a & Anchor_Alternation) != 0 ) {
+ return testAnchor( i, aa[a ^ Anchor_Alternation].a, capBegin ) ||
+ testAnchor( i, aa[a ^ Anchor_Alternation].b, capBegin );
+ }
+#endif
+
+ if ( (a & Anchor_Caret) != 0 ) {
+ if ( mmPos + i != mmCaretPos )
+ return FALSE;
+ }
+ if ( (a & Anchor_Dollar) != 0 ) {
+ if ( mmPos + i != mmLen )
+ return FALSE;
+ }
+#ifndef TQT_NO_REGEXP_ESCAPE
+ if ( (a & (Anchor_Word | Anchor_NonWord)) != 0 ) {
+ bool before = FALSE;
+ bool after = FALSE;
+ if ( mmPos + i != 0 )
+ before = isWord( mmIn[mmPos + i - 1] );
+ if ( mmPos + i != mmLen )
+ after = isWord( mmIn[mmPos + i] );
+ if ( (a & Anchor_Word) != 0 && (before == after) )
+ return FALSE;
+ if ( (a & Anchor_NonWord) != 0 && (before != after) )
+ return FALSE;
+ }
+#endif
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+ if ( (a & Anchor_LookaheadMask) != 0 ) {
+ TQConstString cstr = TQConstString( (TQChar *) mmIn + mmPos + i,
+ mmLen - mmPos - i );
+ for ( j = 0; j < (int) ahead.size(); j++ ) {
+ if ( (a & (Anchor_FirstLookahead << j)) != 0 ) {
+ TQMemArray<int> captured;
+ ahead[j]->eng->match( cstr.string(), 0, TRUE, TRUE,
+ mmCaretPos - mmPos - i, captured );
+ if ( (captured[0] == 0) == ahead[j]->neg )
+ return FALSE;
+ }
+ }
+ }
+#endif
+#ifndef TQT_NO_REGEXP_CAPTURE
+#ifndef TQT_NO_REGEXP_BACKREF
+ for ( j = 0; j < nbrefs; j++ ) {
+ if ( (a & (Anchor_BackRef1Empty << j)) != 0 ) {
+ if ( capBegin[j] != EmptyCapture )
+ return FALSE;
+ }
+ }
+#endif
+#endif
+ return TRUE;
+}
+
+#ifndef TQT_NO_REGEXP_OPTIM
+/*
+ The three following functions are what Jeffrey Friedl would call
+ transmissions (or bump-alongs). Using one or the other should make
+ no difference except in performance.
+*/
+
+bool TQRegExpEngine::goodStringMatch()
+{
+ int k = mmPos + goodEarlyStart;
+ while ( (k = mmStr->tqfind(goodStr, k, cs)) != -1 ) {
+ int from = k - goodLateStart;
+ int to = k - goodEarlyStart;
+ if ( from > mmPos )
+ mmPos = from;
+
+ while ( mmPos <= to ) {
+ if ( matchHere() )
+ return TRUE;
+ mmPos++;
+ }
+ k++;
+ }
+ return FALSE;
+}
+
+bool TQRegExpEngine::badCharMatch()
+{
+ int slideHead = 0;
+ int slideNext = 0;
+ int i;
+ int lastPos = mmLen - minl;
+ memset( mmSlideTab, 0, mmSlideTabSize * sizeof(int) );
+
+ /*
+ Set up the slide table, used for the bad-character heuristic,
+ using the table of first occurrence of each character.
+ */
+ for ( i = 0; i < minl; i++ ) {
+ int sk = occ1[BadChar(mmIn[mmPos + i])];
+ if ( sk == NoOccurrence )
+ sk = i + 1;
+ if ( sk > 0 ) {
+ int k = i + 1 - sk;
+ if ( k < 0 ) {
+ sk = i + 1;
+ k = 0;
+ }
+ if ( sk > mmSlideTab[k] )
+ mmSlideTab[k] = sk;
+ }
+ }
+
+ if ( mmPos > lastPos )
+ return FALSE;
+
+ for ( ;; ) {
+ if ( ++slideNext >= mmSlideTabSize )
+ slideNext = 0;
+ if ( mmSlideTab[slideHead] > 0 ) {
+ if ( mmSlideTab[slideHead] - 1 > mmSlideTab[slideNext] )
+ mmSlideTab[slideNext] = mmSlideTab[slideHead] - 1;
+ mmSlideTab[slideHead] = 0;
+ } else {
+ if ( matchHere() )
+ return TRUE;
+ }
+
+ if ( mmPos == lastPos )
+ break;
+
+ /*
+ Update the slide table. This code has much in common with
+ the initialization code.
+ */
+ int sk = occ1[BadChar(mmIn[mmPos + minl])];
+ if ( sk == NoOccurrence ) {
+ mmSlideTab[slideNext] = minl;
+ } else if ( sk > 0 ) {
+ int k = slideNext + minl - sk;
+ if ( k >= mmSlideTabSize )
+ k -= mmSlideTabSize;
+ if ( sk > mmSlideTab[k] )
+ mmSlideTab[k] = sk;
+ }
+ slideHead = slideNext;
+ mmPos++;
+ }
+ return FALSE;
+}
+#else
+bool TQRegExpEngine::bruteMatch()
+{
+ while ( mmPos <= mmLen ) {
+ if ( matchHere() )
+ return TRUE;
+ mmPos++;
+ }
+ return FALSE;
+}
+#endif
+
+/*
+ Here's the core of the engine. It tries to do a match here and now.
+*/
+bool TQRegExpEngine::matchHere()
+{
+ int ncur = 1, nnext = 0;
+ int i = 0, j, k, m;
+ bool stop = FALSE;
+
+ mmMatchLen = -1;
+ mmOneTestMatchedLen = -1;
+ mmCurStack[0] = InitialState;
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+ if ( ncap > 0 ) {
+ for ( j = 0; j < ncap; j++ ) {
+ mmCurCapBegin[j] = EmptyCapture;
+ mmCurCapEnd[j] = EmptyCapture;
+ }
+ }
+#endif
+
+#ifndef TQT_NO_REGEXP_BACKREF
+ int *zzZ = 0;
+
+ while ( (ncur > 0 || !mmSleeping.isEmpty()) && i <= mmLen - mmPos &&
+ !stop )
+#else
+ while ( ncur > 0 && i <= mmLen - mmPos && !stop )
+#endif
+ {
+ int ch = ( i < mmLen - mmPos ) ? mmIn[mmPos + i].tqunicode() : 0;
+ for ( j = 0; j < ncur; j++ ) {
+ int cur = mmCurStack[j];
+ State *scur = s[cur];
+ TQMemArray<int>& outs = scur->outs;
+ for ( k = 0; k < (int) outs.size(); k++ ) {
+ int next = outs[k];
+ State *snext = s[next];
+ bool in = TRUE;
+#ifndef TQT_NO_REGEXP_BACKREF
+ int needSomeSleep = 0;
+#endif
+
+ /*
+ First, check if the anchors are anchored properly.
+ */
+ if ( scur->anchors != 0 ) {
+ int a = at( *scur->anchors, next );
+ if ( a != 0 && !testAnchor(i, a, mmCurCapBegin + j * ncap) )
+ in = FALSE;
+ }
+ /*
+ If indeed they are, check if the input character is
+ correct for this transition.
+ */
+ if ( in ) {
+ m = snext->match;
+ if ( (m & (CharClassBit | BackRefBit)) == 0 ) {
+ if ( cs )
+ in = ( m == ch );
+ else
+ in = ( TQChar(m).lower() == TQChar(ch).lower() );
+ } else if ( next == FinalState ) {
+ mmMatchLen = i;
+ stop = mmMinimal;
+ in = TRUE;
+ } else if ( (m & CharClassBit) != 0 ) {
+#ifndef TQT_NO_REGEXP_CCLASS
+ const CharClass *cc = cl[m ^ CharClassBit];
+ if ( cs )
+ in = cc->in( ch );
+ else if ( cc->negative() )
+ in = cc->in( TQChar(ch).lower() ) &&
+ cc->in( TQChar(ch).upper() );
+ else
+ in = cc->in( TQChar(ch).lower() ) ||
+ cc->in( TQChar(ch).upper() );
+#endif
+#ifndef TQT_NO_REGEXP_BACKREF
+ } else { /* ( (m & BackRefBit) != 0 ) */
+ int bref = m ^ BackRefBit;
+ int ell = j * ncap + ( bref - 1 );
+
+ in = bref <= ncap && mmCurCapBegin[ell] != EmptyCapture;
+ if ( in ) {
+ if ( cs )
+ in = ( mmIn[mmPos + mmCurCapBegin[ell]]
+ == TQChar(ch) );
+ else
+ in = ( mmIn[mmPos + mmCurCapBegin[ell]].lower()
+ == TQChar(ch).lower() );
+ }
+
+ if ( in ) {
+ int delta;
+ if ( mmCurCapEnd[ell] == EmptyCapture )
+ delta = i - mmCurCapBegin[ell];
+ else
+ delta = mmCurCapEnd[ell] - mmCurCapBegin[ell];
+
+ in = ( delta <= mmLen - (mmPos + i) );
+ if ( in && delta > 1 ) {
+ int n = 1;
+ if ( cs ) {
+ while ( n < delta ) {
+ if ( mmIn[mmPos +
+ mmCurCapBegin[ell] + n] !=
+ mmIn[mmPos + i + n] )
+ break;
+ n++;
+ }
+ } else {
+ while ( n < delta ) {
+ TQChar a = mmIn[mmPos +
+ mmCurCapBegin[ell] + n];
+ TQChar b = mmIn[mmPos + i + n];
+ if ( a.lower() != b.lower() )
+ break;
+ n++;
+ }
+ }
+ in = ( n == delta );
+ if ( in )
+ needSomeSleep = delta - 1;
+ }
+ }
+#endif
+ }
+ }
+
+ /*
+ We must now update our data structures.
+ */
+ if ( in ) {
+#ifndef TQT_NO_REGEXP_CAPTURE
+ int *capBegin, *capEnd;
+#endif
+ /*
+ If the next state was not encountered yet, all
+ is fine.
+ */
+ if ( (m = mmInNextStack[next]) == -1 ) {
+ m = nnext++;
+ mmNextStack[m] = next;
+ mmInNextStack[next] = m;
+#ifndef TQT_NO_REGEXP_CAPTURE
+ capBegin = mmNextCapBegin + m * ncap;
+ capEnd = mmNextCapEnd + m * ncap;
+
+ /*
+ Otherwise, we'll first maintain captures in
+ temporary arrays, and decide at the end whether
+ it's best to keep the previous capture zones or
+ the new ones.
+ */
+ } else {
+ capBegin = mmTempCapBegin;
+ capEnd = mmTempCapEnd;
+#endif
+ }
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+ /*
+ Updating the capture zones is much of a task.
+ */
+ if ( ncap > 0 ) {
+ memcpy( capBegin, mmCurCapBegin + j * ncap,
+ ncap * sizeof(int) );
+ memcpy( capEnd, mmCurCapEnd + j * ncap,
+ ncap * sizeof(int) );
+ int c = scur->atom, n = snext->atom;
+ int p = -1, q = -1;
+ int cap;
+
+ /*
+ Lemma 1. For any x in the range [0..nf), we
+ have f[x].tqparent < x.
+
+ Proof. By looking at startAtom(), it is
+ clear that cf < nf holds all the time, and
+ thus that f[nf].tqparent < nf.
+ */
+
+ /*
+ If we are reentering an atom, we empty all
+ capture zones inside it.
+ */
+ if ( scur->reenter != 0 &&
+ (q = at(*scur->reenter, next)) != 0 ) {
+ TQBitArray b;
+ b.fill( FALSE, nf );
+ b.setBit( q, TRUE );
+ for ( int ell = q + 1; ell < nf; ell++ ) {
+ if ( b.testBit(f[ell].tqparent) ) {
+ b.setBit( ell, TRUE );
+ cap = f[ell].capture;
+ if ( cap >= 0 ) {
+ capBegin[cap] = EmptyCapture;
+ capEnd[cap] = EmptyCapture;
+ }
+ }
+ }
+ p = f[q].tqparent;
+
+ /*
+ Otherwise, close the capture zones we are
+ leaving. We are leaving f[c].capture,
+ f[f[c].tqparent].capture,
+ f[f[f[c].tqparent].tqparent].capture, ...,
+ until f[x].capture, with x such that
+ f[x].tqparent is the youngest common ancestor
+ for c and n.
+
+ We go up along c's and n's ancestry until
+ we tqfind x.
+ */
+ } else {
+ p = c;
+ q = n;
+ while ( p != q ) {
+ if ( p > q ) {
+ cap = f[p].capture;
+ if ( cap >= 0 ) {
+ if ( capBegin[cap] == i ) {
+ capBegin[cap] = EmptyCapture;
+ capEnd[cap] = EmptyCapture;
+ } else {
+ capEnd[cap] = i;
+ }
+ }
+ p = f[p].tqparent;
+ } else {
+ q = f[q].tqparent;
+ }
+ }
+ }
+
+ /*
+ In any case, we now open the capture zones
+ we are entering. We work upwards from n
+ until we reach p (the tqparent of the atom we
+ reenter or the youngest common ancestor).
+ */
+ while ( n > p ) {
+ cap = f[n].capture;
+ if ( cap >= 0 ) {
+ capBegin[cap] = i;
+ capEnd[cap] = EmptyCapture;
+ }
+ n = f[n].tqparent;
+ }
+ /*
+ If the next state was already in
+ mmNextStack, we must choose carefully which
+ capture zones we want to keep.
+ */
+ if ( capBegin == mmTempCapBegin &&
+ isBetterCapture(capBegin, capEnd,
+ mmNextCapBegin + m * ncap,
+ mmNextCapEnd + m * ncap) ) {
+ memcpy( mmNextCapBegin + m * ncap, capBegin,
+ ncap * sizeof(int) );
+ memcpy( mmNextCapEnd + m * ncap, capEnd,
+ ncap * sizeof(int) );
+ }
+ }
+#ifndef TQT_NO_REGEXP_BACKREF
+ /*
+ We are done with updating the capture zones.
+ It's now time to put the next state to sleep,
+ if it needs to, and to remove it from
+ mmNextStack.
+ */
+ if ( needSomeSleep > 0 ) {
+ zzZ = new int[1 + 2 * ncap];
+ zzZ[0] = next;
+ if ( ncap > 0 ) {
+ memcpy( zzZ + 1, capBegin, ncap * sizeof(int) );
+ memcpy( zzZ + 1 + ncap, capEnd,
+ ncap * sizeof(int) );
+ }
+ mmInNextStack[mmNextStack[--nnext]] = -1;
+ mmSleeping.insert( i + needSomeSleep, zzZ );
+ }
+#endif
+#endif
+ }
+ }
+ }
+#ifndef TQT_NO_REGEXP_CAPTURE
+ /*
+ If we reached the final state, hurray! Copy the captured
+ zone.
+ */
+ if ( ncap > 0 && (m = mmInNextStack[FinalState]) != -1 ) {
+ memcpy( mmCapBegin, mmNextCapBegin + m * ncap, ncap * sizeof(int) );
+ memcpy( mmCapEnd, mmNextCapEnd + m * ncap, ncap * sizeof(int) );
+ }
+#ifndef TQT_NO_REGEXP_BACKREF
+ /*
+ It's time to wake up the sleepers.
+ */
+ if ( !mmSleeping.isEmpty() ) {
+ while ( (zzZ = mmSleeping.take(i)) != 0 ) {
+ int next = zzZ[0];
+ int *capBegin = zzZ + 1;
+ int *capEnd = zzZ + 1 + ncap;
+ bool copyOver = TRUE;
+
+ if ( (m = mmInNextStack[zzZ[0]]) == -1 ) {
+ m = nnext++;
+ mmNextStack[m] = next;
+ mmInNextStack[next] = m;
+ } else {
+ copyOver = isBetterCapture( mmNextCapBegin + m * ncap,
+ mmNextCapEnd + m * ncap,
+ capBegin, capEnd );
+ }
+ if ( copyOver ) {
+ memcpy( mmNextCapBegin + m * ncap, capBegin,
+ ncap * sizeof(int) );
+ memcpy( mmNextCapEnd + m * ncap, capEnd,
+ ncap * sizeof(int) );
+ }
+ delete[] zzZ;
+ }
+ }
+#endif
+#endif
+ for ( j = 0; j < nnext; j++ )
+ mmInNextStack[mmNextStack[j]] = -1;
+
+ // avoid needless iteration that confuses mmOneTestMatchedLen
+ if ( nnext == 1 && mmNextStack[0] == FinalState
+#ifndef TQT_NO_REGEXP_BACKREF
+ && mmSleeping.isEmpty()
+#endif
+ )
+ stop = TRUE;
+
+ tqSwap( mmCurStack, mmNextStack );
+#ifndef TQT_NO_REGEXP_CAPTURE
+ tqSwap( mmCurCapBegin, mmNextCapBegin );
+ tqSwap( mmCurCapEnd, mmNextCapEnd );
+#endif
+ ncur = nnext;
+ nnext = 0;
+ i++;
+ }
+
+#ifndef TQT_NO_REGEXP_BACKREF
+ /*
+ If minimal matching is enabled, we might have some sleepers
+ left.
+ */
+ while ( !mmSleeping.isEmpty() ) {
+ zzZ = mmSleeping.take( *TQIntDictIterator<int>(mmSleeping) );
+ delete[] zzZ;
+ }
+#endif
+
+ mmOneTestMatchedLen = i - 1;
+ return ( mmMatchLen >= 0 );
+}
+
+#ifndef TQT_NO_REGEXP_CCLASS
+
+TQRegExpEngine::CharClass::CharClass()
+ : c( 0 ), n( FALSE )
+{
+#ifndef TQT_NO_REGEXP_OPTIM
+ occ1.fill( NoOccurrence, NumBadChars );
+#endif
+}
+
+TQRegExpEngine::CharClass& TQRegExpEngine::CharClass::operator=(
+ const CharClass& cc )
+{
+ c = cc.c;
+ r = cc.r.copy();
+ n = cc.n;
+#ifndef TQT_NO_REGEXP_OPTIM
+ occ1 = cc.occ1;
+#endif
+ return *this;
+}
+
+void TQRegExpEngine::CharClass::clear()
+{
+ c = 0;
+ r.resize( 0 );
+ n = FALSE;
+}
+
+void TQRegExpEngine::CharClass::setNegative( bool negative )
+{
+ n = negative;
+#ifndef TQT_NO_REGEXP_OPTIM
+ occ1.fill( 0, NumBadChars );
+#endif
+}
+
+void TQRegExpEngine::CharClass::addCategories( int cats )
+{
+ c |= cats;
+#ifndef TQT_NO_REGEXP_OPTIM
+ occ1.fill( 0, NumBadChars );
+#endif
+}
+
+void TQRegExpEngine::CharClass::addRange( ushort from, ushort to )
+{
+ if ( from > to )
+ tqSwap( from, to );
+ int m = r.size();
+ r.resize( m + 1 );
+ r[m].from = from;
+ r[m].to = to;
+
+#ifndef TQT_NO_REGEXP_OPTIM
+ int i;
+
+ if ( to - from < NumBadChars ) {
+ occ1.detach();
+ if ( from % NumBadChars <= to % NumBadChars ) {
+ for ( i = from % NumBadChars; i <= to % NumBadChars; i++ )
+ occ1[i] = 0;
+ } else {
+ for ( i = 0; i <= to % NumBadChars; i++ )
+ occ1[i] = 0;
+ for ( i = from % NumBadChars; i < NumBadChars; i++ )
+ occ1[i] = 0;
+ }
+ } else {
+ occ1.fill( 0, NumBadChars );
+ }
+#endif
+}
+
+bool TQRegExpEngine::CharClass::in( TQChar ch ) const
+{
+#ifndef TQT_NO_REGEXP_OPTIM
+ if ( occ1[BadChar(ch)] == NoOccurrence )
+ return n;
+#endif
+
+ if ( c != 0 && (c & (1 << (int) ch.category())) != 0 )
+ return !n;
+ for ( int i = 0; i < (int) r.size(); i++ ) {
+ if ( ch.tqunicode() >= r[i].from && ch.tqunicode() <= r[i].to )
+ return !n;
+ }
+ return n;
+}
+
+#if defined(TQT_DEBUG)
+void TQRegExpEngine::CharClass::dump() const
+{
+ int i;
+ qDebug( " %stive character class", n ? "nega" : "posi" );
+#ifndef TQT_NO_REGEXP_CCLASS
+ if ( c != 0 )
+ qDebug( " categories 0x%.8x", c );
+#endif
+ for ( i = 0; i < (int) r.size(); i++ )
+ qDebug( " 0x%.4x through 0x%.4x", r[i].from, r[i].to );
+}
+#endif
+#endif
+
+TQRegExpEngine::Box::Box( TQRegExpEngine *engine )
+ : eng( engine ), skipanchors( 0 )
+#ifndef TQT_NO_REGEXP_OPTIM
+ , earlyStart( 0 ), lateStart( 0 ), maxl( 0 )
+#endif
+{
+#ifndef TQT_NO_REGEXP_OPTIM
+ occ1.fill( NoOccurrence, NumBadChars );
+#endif
+ minl = 0;
+}
+
+TQRegExpEngine::Box& TQRegExpEngine::Box::operator=( const Box& b )
+{
+ eng = b.eng;
+ ls = b.ls;
+ rs = b.rs;
+ lanchors = b.lanchors;
+ ranchors = b.ranchors;
+ skipanchors = b.skipanchors;
+#ifndef TQT_NO_REGEXP_OPTIM
+ earlyStart = b.earlyStart;
+ lateStart = b.lateStart;
+ str = b.str;
+ leftStr = b.leftStr;
+ rightStr = b.rightStr;
+ maxl = b.maxl;
+ occ1 = b.occ1;
+#endif
+ minl = b.minl;
+ return *this;
+}
+
+void TQRegExpEngine::Box::set( TQChar ch )
+{
+ ls.resize( 1 );
+ ls[0] = eng->createState( ch );
+ rs = ls;
+ rs.detach();
+#ifndef TQT_NO_REGEXP_OPTIM
+ str = ch;
+ leftStr = ch;
+ rightStr = ch;
+ maxl = 1;
+ occ1.detach();
+ occ1[BadChar(ch)] = 0;
+#endif
+ minl = 1;
+}
+
+void TQRegExpEngine::Box::set( const CharClass& cc )
+{
+ ls.resize( 1 );
+ ls[0] = eng->createState( cc );
+ rs = ls;
+ rs.detach();
+#ifndef TQT_NO_REGEXP_OPTIM
+ maxl = 1;
+ occ1 = cc.firstOccurrence();
+#endif
+ minl = 1;
+}
+
+#ifndef TQT_NO_REGEXP_BACKREF
+void TQRegExpEngine::Box::set( int bref )
+{
+ ls.resize( 1 );
+ ls[0] = eng->createState( bref );
+ rs = ls;
+ rs.detach();
+ if ( bref >= 1 && bref <= MaxBackRefs )
+ skipanchors = Anchor_BackRef0Empty << bref;
+#ifndef TQT_NO_REGEXP_OPTIM
+ maxl = InftyLen;
+#endif
+ minl = 0;
+}
+#endif
+
+void TQRegExpEngine::Box::cat( const Box& b )
+{
+ eng->addCatTransitions( rs, b.ls );
+ addAnchorsToEngine( b );
+ if ( minl == 0 ) {
+ mergeInto( &lanchors, b.lanchors );
+ if ( skipanchors != 0 ) {
+ for ( int i = 0; i < (int) b.ls.size(); i++ ) {
+ int a = eng->anchorConcatenation( at(lanchors, b.ls[i]),
+ skipanchors );
+ lanchors.insert( b.ls[i], a );
+ }
+ }
+ mergeInto( &ls, b.ls );
+ }
+ if ( b.minl == 0 ) {
+ mergeInto( &ranchors, b.ranchors );
+ if ( b.skipanchors != 0 ) {
+ for ( int i = 0; i < (int) rs.size(); i++ ) {
+ int a = eng->anchorConcatenation( at(ranchors, rs[i]),
+ b.skipanchors );
+ ranchors.insert( rs[i], a );
+ }
+ }
+ mergeInto( &rs, b.rs );
+ } else {
+ ranchors = b.ranchors;
+ rs = b.rs;
+ }
+
+#ifndef TQT_NO_REGEXP_OPTIM
+ if ( maxl != InftyLen ) {
+ if ( rightStr.length() + b.leftStr.length() >
+ TQMAX(str.length(), b.str.length()) ) {
+ earlyStart = minl - rightStr.length();
+ lateStart = maxl - rightStr.length();
+ str = rightStr + b.leftStr;
+ } else if ( b.str.length() > str.length() ) {
+ earlyStart = minl + b.earlyStart;
+ lateStart = maxl + b.lateStart;
+ str = b.str;
+ }
+ }
+
+ if ( (int) leftStr.length() == maxl )
+ leftStr += b.leftStr;
+
+ if ( (int) b.rightStr.length() == b.maxl ) {
+ rightStr += b.rightStr;
+ } else {
+ rightStr = b.rightStr;
+ }
+
+ if ( maxl == InftyLen || b.maxl == InftyLen ) {
+ maxl = InftyLen;
+ } else {
+ maxl += b.maxl;
+ }
+
+ occ1.detach();
+ for ( int i = 0; i < NumBadChars; i++ ) {
+ if ( b.occ1[i] != NoOccurrence && minl + b.occ1[i] < occ1[i] )
+ occ1[i] = minl + b.occ1[i];
+ }
+#endif
+
+ minl += b.minl;
+ if ( minl == 0 )
+ skipanchors = eng->anchorConcatenation( skipanchors, b.skipanchors );
+ else
+ skipanchors = 0;
+}
+
+void TQRegExpEngine::Box::orx( const Box& b )
+{
+ mergeInto( &ls, b.ls );
+ mergeInto( &lanchors, b.lanchors );
+ mergeInto( &rs, b.rs );
+ mergeInto( &ranchors, b.ranchors );
+
+ if ( b.minl == 0 ) {
+ if ( minl == 0 )
+ skipanchors = eng->anchorAlternation( skipanchors, b.skipanchors );
+ else
+ skipanchors = b.skipanchors;
+ }
+
+#ifndef TQT_NO_REGEXP_OPTIM
+ occ1.detach();
+ for ( int i = 0; i < NumBadChars; i++ ) {
+ if ( occ1[i] > b.occ1[i] )
+ occ1[i] = b.occ1[i];
+ }
+ earlyStart = 0;
+ lateStart = 0;
+ str = TQString();
+ leftStr = TQString();
+ rightStr = TQString();
+ if ( b.maxl > maxl )
+ maxl = b.maxl;
+#endif
+ if ( b.minl < minl )
+ minl = b.minl;
+}
+
+void TQRegExpEngine::Box::plus( int atom )
+{
+#ifndef TQT_NO_REGEXP_CAPTURE
+ eng->addPlusTransitions( rs, ls, atom );
+#else
+ TQ_UNUSED( atom );
+ eng->addCatTransitions( rs, ls );
+#endif
+ addAnchorsToEngine( *this );
+#ifndef TQT_NO_REGEXP_OPTIM
+ maxl = InftyLen;
+#endif
+}
+
+void TQRegExpEngine::Box::opt()
+{
+#ifndef TQT_NO_REGEXP_OPTIM
+ earlyStart = 0;
+ lateStart = 0;
+ str = TQString();
+ leftStr = TQString();
+ rightStr = TQString();
+#endif
+ skipanchors = 0;
+ minl = 0;
+}
+
+void TQRegExpEngine::Box::catAnchor( int a )
+{
+ if ( a != 0 ) {
+ for ( int i = 0; i < (int) rs.size(); i++ ) {
+ a = eng->anchorConcatenation( at(ranchors, rs[i]), a );
+ ranchors.insert( rs[i], a );
+ }
+ if ( minl == 0 )
+ skipanchors = eng->anchorConcatenation( skipanchors, a );
+ }
+}
+
+#ifndef TQT_NO_REGEXP_OPTIM
+void TQRegExpEngine::Box::setupHeuristics()
+{
+ eng->goodEarlyStart = earlyStart;
+ eng->goodLateStart = lateStart;
+ eng->goodStr = eng->cs ? str : str.lower();
+
+ eng->minl = minl;
+ if ( eng->cs ) {
+ /*
+ A regular expression such as 112|1 has occ1['2'] = 2 and minl =
+ 1 at this point. An entry of occ1 has to be at most minl or
+ infinity for the rest of the algorithm to go well.
+
+ We waited until here before normalizing these cases (instead of
+ doing it in Box::orx()) because sometimes things improve by
+ themselves. Consider for example (112|1)34.
+ */
+ for ( int i = 0; i < NumBadChars; i++ ) {
+ if ( occ1[i] != NoOccurrence && occ1[i] >= minl )
+ occ1[i] = minl;
+ }
+ eng->occ1 = occ1;
+ } else {
+ eng->occ1.fill( 0, NumBadChars );
+ }
+
+ eng->heuristicallyChooseHeuristic();
+}
+#endif
+
+#if defined(TQT_DEBUG)
+void TQRegExpEngine::Box::dump() const
+{
+ int i;
+ qDebug( "Box of at least %d character%s", minl, minl == 1 ? "" : "s" );
+ qDebug( " Left states:" );
+ for ( i = 0; i < (int) ls.size(); i++ ) {
+ if ( at(lanchors, ls[i]) == 0 )
+ qDebug( " %d", ls[i] );
+ else
+ qDebug( " %d [anchors 0x%.8x]", ls[i], lanchors[ls[i]] );
+ }
+ qDebug( " Right states:" );
+ for ( i = 0; i < (int) rs.size(); i++ ) {
+ if ( at(ranchors, rs[i]) == 0 )
+ qDebug( " %d", rs[i] );
+ else
+ qDebug( " %d [anchors 0x%.8x]", rs[i], ranchors[rs[i]] );
+ }
+ qDebug( " Skip anchors: 0x%.8x", skipanchors );
+}
+#endif
+
+void TQRegExpEngine::Box::addAnchorsToEngine( const Box& to ) const
+{
+ for ( int i = 0; i < (int) to.ls.size(); i++ ) {
+ for ( int j = 0; j < (int) rs.size(); j++ ) {
+ int a = eng->anchorConcatenation( at(ranchors, rs[j]),
+ at(to.lanchors, to.ls[i]) );
+ eng->addAnchors( rs[j], to.ls[i], a );
+ }
+ }
+}
+
+int TQRegExpEngine::getChar()
+{
+ return ( yyPos == yyLen ) ? EOS : yyIn[yyPos++].tqunicode();
+}
+
+int TQRegExpEngine::getEscape()
+{
+#ifndef TQT_NO_REGEXP_ESCAPE
+ const char tab[] = "afnrtv"; // no b, as \b means word boundary
+ const char backTab[] = "\a\f\n\r\t\v";
+ ushort low;
+ int i;
+#endif
+ ushort val;
+ int prevCh = yyCh;
+
+ if ( prevCh == EOS ) {
+ error( RXERR_END );
+ return Tok_Char | '\\';
+ }
+ yyCh = getChar();
+#ifndef TQT_NO_REGEXP_ESCAPE
+ if ( (prevCh & ~0xff) == 0 ) {
+ const char *p = strchr( tab, prevCh );
+ if ( p != 0 )
+ return Tok_Char | backTab[p - tab];
+ }
+#endif
+
+ switch ( prevCh ) {
+#ifndef TQT_NO_REGEXP_ESCAPE
+ case '0':
+ val = 0;
+ for ( i = 0; i < 3; i++ ) {
+ if ( yyCh >= '0' && yyCh <= '7' )
+ val = ( val << 3 ) | ( yyCh - '0' );
+ else
+ break;
+ yyCh = getChar();
+ }
+ if ( (val & ~0377) != 0 )
+ error( RXERR_OCTAL );
+ return Tok_Char | val;
+#endif
+#ifndef TQT_NO_REGEXP_ESCAPE
+ case 'B':
+ return Tok_NonWord;
+#endif
+#ifndef TQT_NO_REGEXP_CCLASS
+ case 'D':
+ // see TQChar::isDigit()
+ yyCharClass->addCategories( 0x7fffffef );
+ return Tok_CharClass;
+ case 'S':
+ // see TQChar::isSpace()
+ yyCharClass->addCategories( 0x7ffff87f );
+ yyCharClass->addRange( 0x0000, 0x0008 );
+ yyCharClass->addRange( 0x000e, 0x001f );
+ yyCharClass->addRange( 0x007f, 0x009f );
+ return Tok_CharClass;
+ case 'W':
+ // see TQChar::isLetterOrNumber()
+ yyCharClass->addCategories( 0x7fe07f8f );
+ yyCharClass->addRange( 0x203f, 0x2040 );
+ yyCharClass->addSingleton( 0x2040 );
+ yyCharClass->addSingleton( 0x30fb );
+ yyCharClass->addRange( 0xfe33, 0xfe34 );
+ yyCharClass->addRange( 0xfe4d, 0xfe4f );
+ yyCharClass->addSingleton( 0xff3f );
+ yyCharClass->addSingleton( 0xff65 );
+ return Tok_CharClass;
+#endif
+#ifndef TQT_NO_REGEXP_ESCAPE
+ case 'b':
+ return Tok_Word;
+#endif
+#ifndef TQT_NO_REGEXP_CCLASS
+ case 'd':
+ // see TQChar::isDigit()
+ yyCharClass->addCategories( 0x00000010 );
+ return Tok_CharClass;
+ case 's':
+ // see TQChar::isSpace()
+ yyCharClass->addCategories( 0x00000380 );
+ yyCharClass->addRange( 0x0009, 0x000d );
+ return Tok_CharClass;
+ case 'w':
+ // see TQChar::isLetterOrNumber()
+ yyCharClass->addCategories( 0x000f8070 );
+ yyCharClass->addSingleton( 0x005f ); // '_'
+ return Tok_CharClass;
+#endif
+#ifndef TQT_NO_REGEXP_ESCAPE
+ case 'x':
+ val = 0;
+ for ( i = 0; i < 4; i++ ) {
+ low = TQChar( yyCh ).lower();
+ if ( low >= '0' && low <= '9' )
+ val = ( val << 4 ) | ( low - '0' );
+ else if ( low >= 'a' && low <= 'f' )
+ val = ( val << 4 ) | ( low - 'a' + 10 );
+ else
+ break;
+ yyCh = getChar();
+ }
+ return Tok_Char | val;
+#endif
+ default:
+ if ( prevCh >= '1' && prevCh <= '9' ) {
+#ifndef TQT_NO_REGEXP_BACKREF
+ val = prevCh - '0';
+ while ( yyCh >= '0' && yyCh <= '9' ) {
+ val = ( val * 10 ) + ( yyCh - '0' );
+ yyCh = getChar();
+ }
+ return Tok_BackRef | val;
+#else
+ error( RXERR_DISABLED );
+#endif
+ }
+ return Tok_Char | prevCh;
+ }
+}
+
+#ifndef TQT_NO_REGEXP_INTERVAL
+int TQRegExpEngine::getRep( int def )
+{
+ if ( yyCh >= '0' && yyCh <= '9' ) {
+ int rep = 0;
+ do {
+ rep = 10 * rep + yyCh - '0';
+ if ( rep >= InftyRep ) {
+ error( RXERR_REPETITION );
+ rep = def;
+ }
+ yyCh = getChar();
+ } while ( yyCh >= '0' && yyCh <= '9' );
+ return rep;
+ } else {
+ return def;
+ }
+}
+#endif
+
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+void TQRegExpEngine::skipChars( int n )
+{
+ if ( n > 0 ) {
+ yyPos += n - 1;
+ yyCh = getChar();
+ }
+}
+#endif
+
+void TQRegExpEngine::error( const char *msg )
+{
+ if ( yyError.isEmpty() )
+ yyError = TQString::tqfromLatin1( msg );
+}
+
+void TQRegExpEngine::startTokenizer( const TQChar *rx, int len )
+{
+ yyIn = rx;
+ yyPos0 = 0;
+ yyPos = 0;
+ yyLen = len;
+ yyCh = getChar();
+ yyCharClass = new CharClass;
+ yyMinRep = 0;
+ yyMaxRep = 0;
+ yyError = TQString();
+}
+
+int TQRegExpEngine::getToken()
+{
+#ifndef TQT_NO_REGEXP_CCLASS
+ ushort pendingCh = 0;
+ bool charPending;
+ bool rangePending;
+ int tok;
+#endif
+ int prevCh = yyCh;
+
+ yyPos0 = yyPos - 1;
+#ifndef TQT_NO_REGEXP_CCLASS
+ yyCharClass->clear();
+#endif
+ yyMinRep = 0;
+ yyMaxRep = 0;
+ yyCh = getChar();
+
+ switch ( prevCh ) {
+ case EOS:
+ yyPos0 = yyPos;
+ return Tok_Eos;
+ case '$':
+ return Tok_Dollar;
+ case '(':
+ if ( yyCh == '?' ) {
+ prevCh = getChar();
+ yyCh = getChar();
+ switch ( prevCh ) {
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+ case '!':
+ return Tok_NegLookahead;
+ case '=':
+ return Tok_PosLookahead;
+#endif
+ case ':':
+ return Tok_MagicLeftParen;
+ default:
+ error( RXERR_LOOKAHEAD );
+ return Tok_MagicLeftParen;
+ }
+ } else {
+ return Tok_LeftParen;
+ }
+ case ')':
+ return Tok_RightParen;
+ case '*':
+ yyMinRep = 0;
+ yyMaxRep = InftyRep;
+ return Tok_Quantifier;
+ case '+':
+ yyMinRep = 1;
+ yyMaxRep = InftyRep;
+ return Tok_Quantifier;
+ case '.':
+#ifndef TQT_NO_REGEXP_CCLASS
+ yyCharClass->setNegative( TRUE );
+#endif
+ return Tok_CharClass;
+ case '?':
+ yyMinRep = 0;
+ yyMaxRep = 1;
+ return Tok_Quantifier;
+ case '[':
+#ifndef TQT_NO_REGEXP_CCLASS
+ if ( yyCh == '^' ) {
+ yyCharClass->setNegative( TRUE );
+ yyCh = getChar();
+ }
+ charPending = FALSE;
+ rangePending = FALSE;
+ do {
+ if ( yyCh == '-' && charPending && !rangePending ) {
+ rangePending = TRUE;
+ yyCh = getChar();
+ } else {
+ if ( charPending && !rangePending ) {
+ yyCharClass->addSingleton( pendingCh );
+ charPending = FALSE;
+ }
+ if ( yyCh == '\\' ) {
+ yyCh = getChar();
+ tok = getEscape();
+ if ( tok == Tok_Word )
+ tok = '\b';
+ } else {
+ tok = Tok_Char | yyCh;
+ yyCh = getChar();
+ }
+ if ( tok == Tok_CharClass ) {
+ if ( rangePending ) {
+ yyCharClass->addSingleton( '-' );
+ yyCharClass->addSingleton( pendingCh );
+ charPending = FALSE;
+ rangePending = FALSE;
+ }
+ } else if ( (tok & Tok_Char) != 0 ) {
+ if ( rangePending ) {
+ yyCharClass->addRange( pendingCh, tok ^ Tok_Char );
+ charPending = FALSE;
+ rangePending = FALSE;
+ } else {
+ pendingCh = tok ^ Tok_Char;
+ charPending = TRUE;
+ }
+ } else {
+ error( RXERR_CHARCLASS );
+ }
+ }
+ } while ( yyCh != ']' && yyCh != EOS );
+ if ( rangePending )
+ yyCharClass->addSingleton( '-' );
+ if ( charPending )
+ yyCharClass->addSingleton( pendingCh );
+ if ( yyCh == EOS )
+ error( RXERR_END );
+ else
+ yyCh = getChar();
+ return Tok_CharClass;
+#else
+ error( RXERR_END );
+ return Tok_Char | '[';
+#endif
+ case '\\':
+ return getEscape();
+ case ']':
+ error( RXERR_LEFTDELIM );
+ return Tok_Char | ']';
+ case '^':
+ return Tok_Caret;
+ case '{':
+#ifndef TQT_NO_REGEXP_INTERVAL
+ yyMinRep = getRep( 0 );
+ yyMaxRep = yyMinRep;
+ if ( yyCh == ',' ) {
+ yyCh = getChar();
+ yyMaxRep = getRep( InftyRep );
+ }
+ if ( yyMaxRep < yyMinRep )
+ tqSwap( yyMinRep, yyMaxRep );
+ if ( yyCh != '}' )
+ error( RXERR_REPETITION );
+ yyCh = getChar();
+ return Tok_Quantifier;
+#else
+ error( RXERR_DISABLED );
+ return Tok_Char | '{';
+#endif
+ case '|':
+ return Tok_Bar;
+ case '}':
+ error( RXERR_LEFTDELIM );
+ return Tok_Char | '}';
+ default:
+ return Tok_Char | prevCh;
+ }
+}
+
+int TQRegExpEngine::parse( const TQChar *pattern, int len )
+{
+ valid = TRUE;
+ startTokenizer( pattern, len );
+ yyTok = getToken();
+#ifndef TQT_NO_REGEXP_CAPTURE
+ yyMayCapture = TRUE;
+#else
+ yyMayCapture = FALSE;
+#endif
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+ int atom = startAtom( FALSE );
+#endif
+ CharClass anything;
+ Box box( this ); // create InitialState
+ box.set( anything );
+ Box rightBox( this ); // create FinalState
+ rightBox.set( anything );
+
+ Box middleBox( this );
+ parseExpression( &middleBox );
+#ifndef TQT_NO_REGEXP_CAPTURE
+ finishAtom( atom );
+#endif
+#ifndef TQT_NO_REGEXP_OPTIM
+ middleBox.setupHeuristics();
+#endif
+ box.cat( middleBox );
+ box.cat( rightBox );
+ delete yyCharClass;
+ yyCharClass = 0;
+
+ officialncap = ncap;
+#ifndef TQT_NO_REGEXP_BACKREF
+ if ( nbrefs > ncap )
+ ncap = nbrefs;
+#endif
+
+ /*
+ We use one TQMemArray<int> for all the big data used a lot in
+ matchHere() and friends.
+ */
+#ifndef TQT_NO_REGEXP_OPTIM
+ mmSlideTabSize = TQMAX( minl + 1, 16 );
+#else
+ mmSlideTabSize = 0;
+#endif
+ mmBigArray.resize( (3 + 4 * ncap) * ns + 4 * ncap + mmSlideTabSize );
+
+ mmInNextStack = mmBigArray.data();
+ memset( mmInNextStack, -1, ns * sizeof(int) );
+ mmCurStack = mmInNextStack + ns;
+ mmNextStack = mmInNextStack + 2 * ns;
+
+ mmCurCapBegin = mmInNextStack + 3 * ns;
+ mmNextCapBegin = mmCurCapBegin + ncap * ns;
+ mmCurCapEnd = mmCurCapBegin + 2 * ncap * ns;
+ mmNextCapEnd = mmCurCapBegin + 3 * ncap * ns;
+
+ mmTempCapBegin = mmCurCapBegin + 4 * ncap * ns;
+ mmTempCapEnd = mmTempCapBegin + ncap;
+ mmCapBegin = mmTempCapBegin + 2 * ncap;
+ mmCapEnd = mmTempCapBegin + 3 * ncap;
+
+ mmSlideTab = mmTempCapBegin + 4 * ncap;
+
+ if ( !yyError.isEmpty() )
+ return -1;
+
+#ifndef TQT_NO_REGEXP_OPTIM
+ State *sinit = s[InitialState];
+ caretAnchored = ( sinit->anchors != 0 );
+ if ( caretAnchored ) {
+ TQMap<int, int>& anchors = *sinit->anchors;
+ TQMap<int, int>::ConstIterator a;
+ for ( a = anchors.begin(); a != anchors.end(); ++a ) {
+ if (
+#ifndef TQT_NO_REGEXP_ANCHOR_ALT
+ (*a & Anchor_Alternation) != 0 ||
+#endif
+ (*a & Anchor_Caret) == 0 ) {
+ caretAnchored = FALSE;
+ break;
+ }
+ }
+ }
+#endif
+ return yyPos0;
+}
+
+void TQRegExpEngine::parseAtom( Box *box )
+{
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+ TQRegExpEngine *eng = 0;
+ bool neg;
+ int len;
+#endif
+
+ if ( (yyTok & Tok_Char) != 0 ) {
+ box->set( TQChar(yyTok ^ Tok_Char) );
+ } else {
+#ifndef TQT_NO_REGEXP_OPTIM
+ trivial = FALSE;
+#endif
+ switch ( yyTok ) {
+ case Tok_Dollar:
+ box->catAnchor( Anchor_Dollar );
+ break;
+ case Tok_Caret:
+ box->catAnchor( Anchor_Caret );
+ break;
+#ifndef TQT_NO_REGEXP_LOOKAHEAD
+ case Tok_PosLookahead:
+ case Tok_NegLookahead:
+ neg = ( yyTok == Tok_NegLookahead );
+ eng = new TQRegExpEngine( cs );
+ len = eng->parse( yyIn + yyPos - 1, yyLen - yyPos + 1 );
+ if ( len >= 0 )
+ skipChars( len );
+ else
+ error( RXERR_LOOKAHEAD );
+ box->catAnchor( addLookahead(eng, neg) );
+ yyTok = getToken();
+ if ( yyTok != Tok_RightParen )
+ error( RXERR_LOOKAHEAD );
+ break;
+#endif
+#ifndef TQT_NO_REGEXP_ESCAPE
+ case Tok_Word:
+ box->catAnchor( Anchor_Word );
+ break;
+ case Tok_NonWord:
+ box->catAnchor( Anchor_NonWord );
+ break;
+#endif
+ case Tok_LeftParen:
+ case Tok_MagicLeftParen:
+ yyTok = getToken();
+ parseExpression( box );
+ if ( yyTok != Tok_RightParen )
+ error( RXERR_END );
+ break;
+ case Tok_CharClass:
+ box->set( *yyCharClass );
+ break;
+ case Tok_Quantifier:
+ error( RXERR_REPETITION );
+ break;
+ default:
+#ifndef TQT_NO_REGEXP_BACKREF
+ if ( (yyTok & Tok_BackRef) != 0 )
+ box->set( yyTok ^ Tok_BackRef );
+ else
+#endif
+ error( RXERR_DISABLED );
+ }
+ }
+ yyTok = getToken();
+}
+
+void TQRegExpEngine::parseFactor( Box *box )
+{
+#ifndef TQT_NO_REGEXP_CAPTURE
+ int atom = startAtom( yyMayCapture && yyTok == Tok_LeftParen );
+#else
+ static const int atom = 0;
+#endif
+
+#ifndef TQT_NO_REGEXP_INTERVAL
+#define YYREDO() \
+ yyIn = in, yyPos0 = pos0, yyPos = pos, yyLen = len, yyCh = ch, \
+ *yyCharClass = charClass, yyMinRep = 0, yyMaxRep = 0, yyTok = tok
+
+ const TQChar *in = yyIn;
+ int pos0 = yyPos0;
+ int pos = yyPos;
+ int len = yyLen;
+ int ch = yyCh;
+ CharClass charClass;
+ if ( yyTok == Tok_CharClass )
+ charClass = *yyCharClass;
+ int tok = yyTok;
+ bool mayCapture = yyMayCapture;
+#endif
+
+ parseAtom( box );
+#ifndef TQT_NO_REGEXP_CAPTURE
+ finishAtom( atom );
+#endif
+
+ if ( yyTok == Tok_Quantifier ) {
+#ifndef TQT_NO_REGEXP_OPTIM
+ trivial = FALSE;
+#endif
+ if ( yyMaxRep == InftyRep ) {
+ box->plus( atom );
+#ifndef TQT_NO_REGEXP_INTERVAL
+ } else if ( yyMaxRep == 0 ) {
+ box->clear();
+#endif
+ }
+ if ( yyMinRep == 0 )
+ box->opt();
+
+#ifndef TQT_NO_REGEXP_INTERVAL
+ yyMayCapture = FALSE;
+ int alpha = ( yyMinRep == 0 ) ? 0 : yyMinRep - 1;
+ int beta = ( yyMaxRep == InftyRep ) ? 0 : yyMaxRep - ( alpha + 1 );
+
+ Box rightBox( this );
+ int i;
+
+ for ( i = 0; i < beta; i++ ) {
+ YYREDO();
+ Box leftBox( this );
+ parseAtom( &leftBox );
+ leftBox.cat( rightBox );
+ leftBox.opt();
+ rightBox = leftBox;
+ }
+ for ( i = 0; i < alpha; i++ ) {
+ YYREDO();
+ Box leftBox( this );
+ parseAtom( &leftBox );
+ leftBox.cat( rightBox );
+ rightBox = leftBox;
+ }
+ rightBox.cat( *box );
+ *box = rightBox;
+#endif
+ yyTok = getToken();
+#ifndef TQT_NO_REGEXP_INTERVAL
+ yyMayCapture = mayCapture;
+#endif
+ }
+#undef YYREDO
+}
+
+void TQRegExpEngine::parseTerm( Box *box )
+{
+#ifndef TQT_NO_REGEXP_OPTIM
+ if ( yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar )
+ parseFactor( box );
+#endif
+ while ( yyTok != Tok_Eos && yyTok != Tok_RightParen && yyTok != Tok_Bar ) {
+ Box rightBox( this );
+ parseFactor( &rightBox );
+ box->cat( rightBox );
+ }
+}
+
+void TQRegExpEngine::parseExpression( Box *box )
+{
+ parseTerm( box );
+ while ( yyTok == Tok_Bar ) {
+#ifndef TQT_NO_REGEXP_OPTIM
+ trivial = FALSE;
+#endif
+ Box rightBox( this );
+ yyTok = getToken();
+ parseTerm( &rightBox );
+ box->orx( rightBox );
+ }
+}
+
+/*
+ The struct TQRegExpPrivate tqcontains the private data of a regular
+ expression other than the automaton. It makes it possible for many
+ TQRegExp objects to use the same TQRegExpEngine object with different
+ TQRegExpPrivate objects.
+*/
+struct TQRegExpPrivate
+{
+ TQString pattern; // regular-expression or wildcard pattern
+ TQString rxpattern; // regular-expression pattern
+#ifndef TQT_NO_REGEXP_WILDCARD
+ bool wc : 1; // wildcard mode?
+#endif
+ bool min : 1; // minimal matching? (instead of maximal)
+ bool cs : 1; // case sensitive?
+#ifndef TQT_NO_REGEXP_CAPTURE
+ TQString t; // last string passed to TQRegExp::search() or searchRev()
+ TQStringList capturedCache; // what TQRegExp::capturedTexts() returned last
+#endif
+ TQMemArray<int> captured; // what TQRegExpEngine::search() returned last
+
+ TQRegExpPrivate() { captured.fill( -1, 2 ); }
+};
+
+#ifndef TQT_NO_REGEXP_OPTIM
+static TQSingleCleanupHandler<TQCache<TQRegExpEngine> > cleanup_cache;
+# ifndef TQT_THREAD_SUPPORT
+static TQCache<TQRegExpEngine> *engineCache = 0;
+# endif // TQT_THREAD_SUPPORT
+#endif // TQT_NO_REGEXP_OPTIM
+
+static void regexpEngine( TQRegExpEngine *&eng, const TQString &pattern,
+ bool caseSensitive, bool deref )
+{
+# ifdef TQT_THREAD_SUPPORT
+ static TQThreadStorage<TQCache<TQRegExpEngine> *> engineCaches;
+ TQCache<TQRegExpEngine> *engineCache = 0;
+ TQThreadInstance *currentThread = TQThreadInstance::current();
+ if (currentThread)
+ engineCache = engineCaches.localData();
+#endif // TQT_THREAD_SUPPORT
+
+ if ( !deref ) {
+#ifndef TQT_NO_REGEXP_OPTIM
+# ifdef TQT_THREAD_SUPPORT
+ if ( currentThread )
+# endif
+ {
+ if ( engineCache != 0 ) {
+ eng = engineCache->take( pattern );
+ if ( eng == 0 || eng->caseSensitive() != caseSensitive ) {
+ delete eng;
+ } else {
+ eng->ref();
+ return;
+ }
+ }
+ }
+#endif // TQT_NO_REGEXP_OPTIM
+ eng = new TQRegExpEngine( pattern, caseSensitive );
+ return;
+ }
+
+ if ( eng->deref() ) {
+#ifndef TQT_NO_REGEXP_OPTIM
+# ifdef TQT_THREAD_SUPPORT
+ if ( currentThread )
+# endif
+ {
+ if ( engineCache == 0 ) {
+ engineCache = new TQCache<TQRegExpEngine>;
+ engineCache->setAutoDelete( TRUE );
+# ifdef TQT_THREAD_SUPPORT
+ engineCaches.setLocalData(engineCache);
+# else
+ cleanup_cache.set( &engineCache );
+# endif // !TQT_THREAD_SUPPORT
+ }
+ if ( !pattern.isNull() &&
+ engineCache->insert(pattern, eng, 4 + pattern.length() / 4) )
+ return;
+ }
+#else
+ TQ_UNUSED( pattern );
+#endif // TQT_NO_REGEXP_OPTIM
+ delete eng;
+ eng = 0;
+ }
+}
+
+/*!
+ \enum TQRegExp::CaretMode
+
+ The CaretMode enum defines the different meanings of the caret
+ (<b>^</b>) in a regular expression. The possible values are:
+
+ \value CaretAtZero
+ The caret corresponds to index 0 in the searched string.
+
+ \value CaretAtOffset
+ The caret corresponds to the start offset of the search.
+
+ \value CaretWontMatch
+ The caret never matches.
+*/
+
+/*!
+ Constructs an empty regexp.
+
+ \sa isValid() errorString()
+*/
+TQRegExp::TQRegExp()
+ : eng( 0 )
+{
+ priv = new TQRegExpPrivate;
+#ifndef TQT_NO_REGEXP_WILDCARD
+ priv->wc = FALSE;
+#endif
+ priv->min = FALSE;
+ priv->cs = TRUE;
+}
+
+/*!
+ Constructs a regular expression object for the given \a pattern
+ string. The pattern must be given using wildcard notation if \a
+ wildcard is TRUE (default is FALSE). The pattern is case
+ sensitive, unless \a caseSensitive is FALSE. Matching is greedy
+ (maximal), but can be changed by calling setMinimal().
+
+ \sa setPattern() setCaseSensitive() setWildcard() setMinimal()
+*/
+TQRegExp::TQRegExp( const TQString& pattern, bool caseSensitive, bool wildcard )
+ : eng( 0 )
+{
+ priv = new TQRegExpPrivate;
+ priv->pattern = pattern;
+#ifndef TQT_NO_REGEXP_WILDCARD
+ priv->wc = wildcard;
+#endif
+ priv->min = FALSE;
+ priv->cs = caseSensitive;
+}
+
+/*!
+ Constructs a regular expression as a copy of \a rx.
+
+ \sa operator=()
+*/
+TQRegExp::TQRegExp( const TQRegExp& rx )
+ : eng( 0 )
+{
+ priv = new TQRegExpPrivate;
+ operator=( rx );
+}
+
+/*!
+ Destroys the regular expression and cleans up its internal data.
+*/
+TQRegExp::~TQRegExp()
+{
+ invalidateEngine();
+ delete priv;
+}
+
+/*!
+ Copies the regular expression \a rx and returns a reference to the
+ copy. The case sensitivity, wildcard and minimal matching options
+ are also copied.
+*/
+TQRegExp& TQRegExp::operator=( const TQRegExp& rx )
+{
+ TQRegExpEngine *otherEng = rx.eng;
+ if ( otherEng != 0 )
+ otherEng->ref();
+ invalidateEngine();
+ eng = otherEng;
+ priv->pattern = rx.priv->pattern;
+ priv->rxpattern = rx.priv->rxpattern;
+#ifndef TQT_NO_REGEXP_WILDCARD
+ priv->wc = rx.priv->wc;
+#endif
+ priv->min = rx.priv->min;
+ priv->cs = rx.priv->cs;
+#ifndef TQT_NO_REGEXP_CAPTURE
+ priv->t = rx.priv->t;
+ priv->capturedCache = rx.priv->capturedCache;
+#endif
+ priv->captured = rx.priv->captured;
+ return *this;
+}
+
+/*!
+ Returns TRUE if this regular expression is equal to \a rx;
+ otherwise returns FALSE.
+
+ Two TQRegExp objects are equal if they have the same pattern
+ strings and the same settings for case sensitivity, wildcard and
+ minimal matching.
+*/
+bool TQRegExp::operator==( const TQRegExp& rx ) const
+{
+ return priv->pattern == rx.priv->pattern &&
+#ifndef TQT_NO_REGEXP_WILDCARD
+ priv->wc == rx.priv->wc &&
+#endif
+ priv->min == rx.priv->min &&
+ priv->cs == rx.priv->cs;
+}
+
+/*!
+ \fn bool TQRegExp::operator!=( const TQRegExp& rx ) const
+
+ Returns TRUE if this regular expression is not equal to \a rx;
+ otherwise returns FALSE.
+
+ \sa operator==()
+*/
+
+/*!
+ Returns TRUE if the pattern string is empty; otherwise returns
+ FALSE.
+
+ If you call exactMatch() with an empty pattern on an empty string
+ it will return TRUE; otherwise it returns FALSE since it operates
+ over the whole string. If you call search() with an empty pattern
+ on \e any string it will return the start offset (0 by default)
+ because the empty pattern matches the 'emptiness' at the start of
+ the string. In this case the length of the match returned by
+ matchedLength() will be 0.
+
+ See TQString::isEmpty().
+*/
+
+bool TQRegExp::isEmpty() const
+{
+ return priv->pattern.isEmpty();
+}
+
+/*!
+ Returns TRUE if the regular expression is valid; otherwise returns
+ FALSE. An invalid regular expression never matches.
+
+ The pattern <b>[a-z</b> is an example of an invalid pattern, since
+ it lacks a closing square bracket.
+
+ Note that the validity of a regexp may also depend on the setting
+ of the wildcard flag, for example <b>*.html</b> is a valid
+ wildcard regexp but an invalid full regexp.
+
+ \sa errorString()
+*/
+bool TQRegExp::isValid() const
+{
+ if ( priv->pattern.isEmpty() ) {
+ return TRUE;
+ } else {
+ prepareEngine();
+ return eng->isValid();
+ }
+}
+
+/*!
+ Returns the pattern string of the regular expression. The pattern
+ has either regular expression syntax or wildcard syntax, depending
+ on wildcard().
+
+ \sa setPattern()
+*/
+TQString TQRegExp::pattern() const
+{
+ return priv->pattern;
+}
+
+/*!
+ Sets the pattern string to \a pattern. The case sensitivity,
+ wildcard and minimal matching options are not changed.
+
+ \sa pattern()
+*/
+void TQRegExp::setPattern( const TQString& pattern )
+{
+ if ( priv->pattern != pattern ) {
+ priv->pattern = pattern;
+ invalidateEngine();
+ }
+}
+
+/*!
+ Returns TRUE if case sensitivity is enabled; otherwise returns
+ FALSE. The default is TRUE.
+
+ \sa setCaseSensitive()
+*/
+bool TQRegExp::caseSensitive() const
+{
+ return priv->cs;
+}
+
+/*!
+ Sets case sensitive matching to \a sensitive.
+
+ If \a sensitive is TRUE, <b>\\.txt$</b> matches \c{readme.txt} but
+ not \c{README.TXT}.
+
+ \sa caseSensitive()
+*/
+void TQRegExp::setCaseSensitive( bool sensitive )
+{
+ if ( sensitive != priv->cs ) {
+ priv->cs = sensitive;
+ invalidateEngine();
+ }
+}
+
+#ifndef TQT_NO_REGEXP_WILDCARD
+/*!
+ Returns TRUE if wildcard mode is enabled; otherwise returns FALSE.
+ The default is FALSE.
+
+ \sa setWildcard()
+*/
+bool TQRegExp::wildcard() const
+{
+ return priv->wc;
+}
+
+/*!
+ Sets the wildcard mode for the regular expression. The default is
+ FALSE.
+
+ Setting \a wildcard to TRUE enables simple shell-like wildcard
+ matching. (See \link #wildcard-matching wildcard matching
+ (globbing) \endlink.)
+
+ For example, <b>r*.txt</b> matches the string \c{readme.txt} in
+ wildcard mode, but does not match \c{readme}.
+
+ \sa wildcard()
+*/
+void TQRegExp::setWildcard( bool wildcard )
+{
+ if ( wildcard != priv->wc ) {
+ priv->wc = wildcard;
+ invalidateEngine();
+ }
+}
+#endif
+
+/*!
+ Returns TRUE if minimal (non-greedy) matching is enabled;
+ otherwise returns FALSE.
+
+ \sa setMinimal()
+*/
+bool TQRegExp::minimal() const
+{
+ return priv->min;
+}
+
+/*!
+ Enables or disables minimal matching. If \a minimal is FALSE,
+ matching is greedy (maximal) which is the default.
+
+ For example, suppose we have the input string "We must be
+ \<b>bold\</b>, very \<b>bold\</b>!" and the pattern
+ <b>\<b>.*\</b></b>. With the default greedy (maximal) matching,
+ the match is "We must be <u>\<b>bold\</b>, very
+ \<b>bold\</b></u>!". But with minimal (non-greedy) matching the
+ first match is: "We must be <u>\<b>bold\</b></u>, very
+ \<b>bold\</b>!" and the second match is "We must be \<b>bold\</b>,
+ very <u>\<b>bold\</b></u>!". In practice we might use the pattern
+ <b>\<b>[^\<]+\</b></b> instead, although this will still fail for
+ nested tags.
+
+ \sa minimal()
+*/
+void TQRegExp::setMinimal( bool minimal )
+{
+ priv->min = minimal;
+}
+
+/*!
+ Returns TRUE if \a str is matched exactly by this regular
+ expression; otherwise returns FALSE. You can determine how much of
+ the string was matched by calling matchedLength().
+
+ For a given regexp string, R, exactMatch("R") is the equivalent of
+ search("^R$") since exactMatch() effectively encloses the regexp
+ in the start of string and end of string anchors, except that it
+ sets matchedLength() differently.
+
+ For example, if the regular expression is <b>blue</b>, then
+ exactMatch() returns TRUE only for input \c blue. For inputs \c
+ bluebell, \c blutak and \c lightblue, exactMatch() returns FALSE
+ and matchedLength() will return 4, 3 and 0 respectively.
+
+ Although const, this function sets matchedLength(),
+ capturedTexts() and pos().
+
+ \sa search() searchRev() TQRegExpValidator
+*/
+bool TQRegExp::exactMatch( const TQString& str ) const
+{
+ prepareEngineForMatch( str );
+ eng->match( str, 0, priv->min, TRUE, 0, priv->captured );
+ if ( priv->captured[1] == (int) str.length() ) {
+ return TRUE;
+ } else {
+ priv->captured[0] = 0;
+ priv->captured[1] = eng->partialMatchLength();
+ return FALSE;
+ }
+}
+
+#ifndef TQT_NO_COMPAT
+/*! \obsolete
+
+ Attempts to match in \a str, starting from position \a index.
+ Returns the position of the match, or -1 if there was no match.
+
+ The length of the match is stored in \a *len, unless \a len is a
+ null pointer.
+
+ If \a indexIsStart is TRUE (the default), the position \a index in
+ the string will match the start of string anchor, <b>^</b>, in the
+ regexp, if present. Otherwise, position 0 in \a str will match.
+
+ Use search() and matchedLength() instead of this function.
+
+ \sa TQString::mid() TQConstString
+*/
+int TQRegExp::match( const TQString& str, int index, int *len,
+ bool indexIsStart ) const
+{
+ int pos = search( str, index, indexIsStart ? CaretAtOffset : CaretAtZero );
+ if ( len != 0 )
+ *len = matchedLength();
+ return pos;
+}
+#endif // TQT_NO_COMPAT
+
+int TQRegExp::search( const TQString& str, int offset ) const
+{
+ return search( str, offset, CaretAtZero );
+}
+
+/*!
+ Attempts to tqfind a match in \a str from position \a offset (0 by
+ default). If \a offset is -1, the search starts at the last
+ character; if -2, at the next to last character; etc.
+
+ Returns the position of the first match, or -1 if there was no
+ match.
+
+ The \a caretMode parameter can be used to instruct whether <b>^</b>
+ should match at index 0 or at \a offset.
+
+ You might prefer to use TQString::tqfind(), TQString::tqcontains() or
+ even TQStringList::grep(). To tqreplace matches use
+ TQString::tqreplace().
+
+ Example:
+ \code
+ TQString str = "offsets: 1.23 .50 71.00 6.00";
+ TQRegExp rx( "\\d*\\.\\d+" ); // primitive floating point matching
+ int count = 0;
+ int pos = 0;
+ while ( (pos = rx.search(str, pos)) != -1 ) {
+ count++;
+ pos += rx.matchedLength();
+ }
+ // pos will be 9, 14, 18 and finally 24; count will end up as 4
+ \endcode
+
+ Although const, this function sets matchedLength(),
+ capturedTexts() and pos().
+
+ \sa searchRev() exactMatch()
+*/
+
+int TQRegExp::search( const TQString& str, int offset, CaretMode caretMode ) const
+{
+ prepareEngineForMatch( str );
+ if ( offset < 0 )
+ offset += str.length();
+ eng->match( str, offset, priv->min, FALSE, caretIndex(offset, caretMode),
+ priv->captured );
+ return priv->captured[0];
+}
+
+
+int TQRegExp::searchRev( const TQString& str, int offset ) const
+{
+ return searchRev( str, offset, CaretAtZero );
+}
+
+/*!
+ Attempts to tqfind a match backwards in \a str from position \a
+ offset. If \a offset is -1 (the default), the search starts at the
+ last character; if -2, at the next to last character; etc.
+
+ Returns the position of the first match, or -1 if there was no
+ match.
+
+ The \a caretMode parameter can be used to instruct whether <b>^</b>
+ should match at index 0 or at \a offset.
+
+ Although const, this function sets matchedLength(),
+ capturedTexts() and pos().
+
+ \warning Searching backwards is much slower than searching
+ forwards.
+
+ \sa search() exactMatch()
+*/
+
+int TQRegExp::searchRev( const TQString& str, int offset,
+ CaretMode caretMode ) const
+{
+ prepareEngineForMatch( str );
+ if ( offset < 0 )
+ offset += str.length();
+ if ( offset < 0 || offset > (int) str.length() ) {
+ priv->captured.detach();
+ priv->captured.fill( -1 );
+ return -1;
+ }
+
+ while ( offset >= 0 ) {
+ eng->match( str, offset, priv->min, TRUE, caretIndex(offset, caretMode),
+ priv->captured );
+ if ( priv->captured[0] == offset )
+ return offset;
+ offset--;
+ }
+ return -1;
+}
+
+/*!
+ Returns the length of the last matched string, or -1 if there was
+ no match.
+
+ \sa exactMatch() search() searchRev()
+*/
+int TQRegExp::matchedLength() const
+{
+ return priv->captured[1];
+}
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+/*!
+ Returns the number of captures contained in the regular expression.
+ */
+int TQRegExp::numCaptures() const
+{
+ prepareEngine();
+ return eng->numCaptures();
+}
+
+/*!
+ Returns a list of the captured text strings.
+
+ The first string in the list is the entire matched string. Each
+ subsequent list element tqcontains a string that matched a
+ (capturing) subexpression of the regexp.
+
+ For example:
+ \code
+ TQRegExp rx( "(\\d+)(\\s*)(cm|inch(es)?)" );
+ int pos = rx.search( "Length: 36 inches" );
+ TQStringList list = rx.capturedTexts();
+ // list is now ( "36 inches", "36", " ", "inches", "es" )
+ \endcode
+
+ The above example also captures elements that may be present but
+ which we have no interest in. This problem can be solved by using
+ non-capturing parentheses:
+
+ \code
+ TQRegExp rx( "(\\d+)(?:\\s*)(cm|inch(?:es)?)" );
+ int pos = rx.search( "Length: 36 inches" );
+ TQStringList list = rx.capturedTexts();
+ // list is now ( "36 inches", "36", "inches" )
+ \endcode
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = rx.capturedTexts();
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ Some regexps can match an indeterminate number of times. For
+ example if the input string is "Offsets: 12 14 99 231 7" and the
+ regexp, \c{rx}, is <b>(\\d+)+</b>, we would hope to get a list of
+ all the numbers matched. However, after calling
+ \c{rx.search(str)}, capturedTexts() will return the list ( "12",
+ "12" ), i.e. the entire match was "12" and the first subexpression
+ matched was "12". The correct approach is to use cap() in a \link
+ #cap_in_a_loop loop \endlink.
+
+ The order of elements in the string list is as follows. The first
+ element is the entire matching string. Each subsequent element
+ corresponds to the next capturing open left parentheses. Thus
+ capturedTexts()[1] is the text of the first capturing parentheses,
+ capturedTexts()[2] is the text of the second and so on
+ (corresponding to $1, $2, etc., in some other regexp languages).
+
+ \sa cap() pos() exactMatch() search() searchRev()
+*/
+TQStringList TQRegExp::capturedTexts()
+{
+ if ( priv->capturedCache.isEmpty() ) {
+ for ( int i = 0; i < (int) priv->captured.size(); i += 2 ) {
+ TQString m;
+ if ( priv->captured[i + 1] == 0 )
+ m = TQString::tqfromLatin1( "" );
+ else if ( priv->captured[i] >= 0 )
+ m = priv->t.mid( priv->captured[i],
+ priv->captured[i + 1] );
+ priv->capturedCache.append( m );
+ }
+ priv->t = TQString::null;
+ }
+ return priv->capturedCache;
+}
+
+/*!
+ Returns the text captured by the \a nth subexpression. The entire
+ match has index 0 and the parenthesized subexpressions have
+ indices starting from 1 (excluding non-capturing parentheses).
+
+ \code
+ TQRegExp rxlen( "(\\d+)(?:\\s*)(cm|inch)" );
+ int pos = rxlen.search( "Length: 189cm" );
+ if ( pos > -1 ) {
+ TQString value = rxlen.cap( 1 ); // "189"
+ TQString unit = rxlen.cap( 2 ); // "cm"
+ // ...
+ }
+ \endcode
+
+ The order of elements matched by cap() is as follows. The first
+ element, cap(0), is the entire matching string. Each subsequent
+ element corresponds to the next capturing open left parentheses.
+ Thus cap(1) is the text of the first capturing parentheses, cap(2)
+ is the text of the second, and so on.
+
+ \target cap_in_a_loop
+ Some patterns may lead to a number of matches which cannot be
+ determined in advance, for example:
+
+ \code
+ TQRegExp rx( "(\\d+)" );
+ str = "Offsets: 12 14 99 231 7";
+ TQStringList list;
+ pos = 0;
+ while ( pos >= 0 ) {
+ pos = rx.search( str, pos );
+ if ( pos > -1 ) {
+ list += rx.cap( 1 );
+ pos += rx.matchedLength();
+ }
+ }
+ // list tqcontains "12", "14", "99", "231", "7"
+ \endcode
+
+ \sa capturedTexts() pos() exactMatch() search() searchRev()
+*/
+TQString TQRegExp::cap( int nth )
+{
+ if ( nth < 0 || nth >= (int) priv->captured.size() / 2 ) {
+ return TQString::null;
+ } else {
+ return capturedTexts()[nth];
+ }
+}
+
+/*!
+ Returns the position of the \a nth captured text in the searched
+ string. If \a nth is 0 (the default), pos() returns the position
+ of the whole match.
+
+ Example:
+ \code
+ TQRegExp rx( "/([a-z]+)/([a-z]+)" );
+ rx.search( "Output /dev/null" ); // returns 7 (position of /dev/null)
+ rx.pos( 0 ); // returns 7 (position of /dev/null)
+ rx.pos( 1 ); // returns 8 (position of dev)
+ rx.pos( 2 ); // returns 12 (position of null)
+ \endcode
+
+ For zero-length matches, pos() always returns -1. (For example, if
+ cap(4) would return an empty string, pos(4) returns -1.) This is
+ due to an implementation tradeoff.
+
+ \sa capturedTexts() exactMatch() search() searchRev()
+*/
+int TQRegExp::pos( int nth )
+{
+ if ( nth < 0 || nth >= (int) priv->captured.size() / 2 )
+ return -1;
+ else
+ return priv->captured[2 * nth];
+}
+
+/*!
+ Returns a text string that explains why a regexp pattern is
+ invalid the case being; otherwise returns "no error occurred".
+
+ \sa isValid()
+*/
+TQString TQRegExp::errorString()
+{
+ if ( isValid() ) {
+ return TQString( RXERR_OK );
+ } else {
+ return eng->errorString();
+ }
+}
+#endif
+
+/*!
+ Returns the string \a str with every regexp special character
+ escaped with a backslash. The special characters are $, (, ), *, +,
+ ., ?, [, \, ], ^, {, | and }.
+
+ Example:
+ \code
+ s1 = TQRegExp::escape( "bingo" ); // s1 == "bingo"
+ s2 = TQRegExp::escape( "f(x)" ); // s2 == "f\\(x\\)"
+ \endcode
+
+ This function is useful to construct regexp patterns dynamically:
+
+ \code
+ TQRegExp rx( "(" + TQRegExp::escape(name) +
+ "|" + TQRegExp::escape(alias) + ")" );
+ \endcode
+*/
+TQString TQRegExp::escape( const TQString& str )
+{
+ static const char meta[] = "$()*+.?[\\]^{|}";
+ TQString quoted = str;
+ int i = 0;
+
+ while ( i < (int) quoted.length() ) {
+ if ( strchr(meta, quoted[i].latin1()) != 0 )
+ quoted.insert( i++, "\\" );
+ i++;
+ }
+ return quoted;
+}
+
+void TQRegExp::prepareEngine() const
+{
+ if ( eng == 0 ) {
+#ifndef TQT_NO_REGEXP_WILDCARD
+ if ( priv->wc )
+ priv->rxpattern = wc2rx( priv->pattern );
+ else
+#endif
+ priv->rxpattern = priv->pattern.isNull() ? TQString::tqfromLatin1( "" )
+ : priv->pattern;
+ TQRegExp *that = (TQRegExp *) this;
+ // that->eng = newEngine( priv->rxpattern, priv->cs );
+ regexpEngine( that->eng, priv->rxpattern, priv->cs, FALSE );
+ priv->captured.detach();
+ priv->captured.fill( -1, 2 + 2 * eng->numCaptures() );
+ }
+}
+
+void TQRegExp::prepareEngineForMatch( const TQString& str ) const
+{
+ prepareEngine();
+#ifndef TQT_NO_REGEXP_CAPTURE
+ priv->t = str;
+ priv->capturedCache.clear();
+#else
+ TQ_UNUSED( str );
+#endif
+}
+
+void TQRegExp::invalidateEngine()
+{
+ if ( eng != 0 ) {
+ regexpEngine( eng, priv->rxpattern, priv->cs, TRUE );
+ priv->rxpattern = TQString();
+ eng = 0;
+ }
+}
+
+int TQRegExp::caretIndex( int offset, CaretMode caretMode )
+{
+ if ( caretMode == CaretAtZero ) {
+ return 0;
+ } else if ( caretMode == CaretAtOffset ) {
+ return offset;
+ } else { // CaretWontMatch
+ return -1;
+ }
+}
+
+#endif // USE_QT4
+
+#endif // TQT_NO_REGEXP
diff --git a/tqtinterface/qt4/src/tools/tqregexp.h b/tqtinterface/qt4/src/tools/tqregexp.h
new file mode 100644
index 0000000..23b92a1
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqregexp.h
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Definition of TQRegExp class
+**
+** Created : 950126
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQREGEXP_H
+#define TQREGEXP_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qregexp.h>
+#include <Qt/qstringlist.h>
+
+#endif // USE_QT4
+
+#ifndef TQT_NO_REGEXP
+
+#ifdef USE_QT4
+
+class TQ_EXPORT TQRegExp : public QRegExp
+{
+public:
+ TQRegExp() : QRegExp() {}
+ TQRegExp( const QString& pattern, bool caseSensitive = TRUE, bool wildcard = FALSE ) : QRegExp( pattern, (Qt::CaseSensitivity)caseSensitive, (wildcard)?QRegExp::Wildcard:QRegExp::RegExp ) {}
+ TQRegExp( const QRegExp& rx ) : QRegExp( rx ) {}
+
+#if defined(TQ_TQDOC)
+ int search( const TQString& str, int offset = 0, CaretMode caretMode = CaretAtZero ) const;
+ int searchRev( const TQString& str, int offset = -1, CaretMode caretMode = CaretAtZero ) const;
+#else
+ int search( const TQString& str, int offset = 0 ) const;
+ int search( const TQString& str, int offset, CaretMode caretMode ) const;
+ int searchRev( const TQString& str, int offset = -1 ) const;
+ int searchRev( const TQString& str, int offset, CaretMode caretMode ) const;
+#endif
+
+ inline TQString cap( int nth = 0 ) { return QRegExp::cap(nth); }
+
+#ifndef TQT_NO_COMPAT
+ inline int match( const TQString& str, int index = 0, int *len = 0, bool indexIsStart = TRUE ) const {
+ int r = search(str, index, indexIsStart?CaretAtOffset:CaretAtZero);
+ if (len != NULL) *len = matchedLength();
+ return r;
+ }
+#endif
+
+ bool caseSensitive() const;
+ void setCaseSensitive( bool sensitive );
+
+#ifndef TQT_NO_REGEXP_WILDCARD
+ inline bool wildcard() const { return (patternSyntax() == QRegExp::Wildcard); }
+ inline void setWildcard( bool wildcard ) { setPatternSyntax(wildcard ? QRegExp::Wildcard : QRegExp::RegExp); }
+#endif
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+ inline TQStringList tqcapturedTexts() {
+ QStringList ql = capturedTexts();
+ TQStringList tqsl;
+ tqsl.clear();
+ for (int i = 0; i < ql.size(); ++i) tqsl.append(ql.at(i));
+ return tqsl;
+ }
+#endif
+};
+
+#else // USE_QT4
+
+class TQRegExpEngine;
+struct TQRegExpPrivate;
+
+class TQ_EXPORT TQRegExp
+{
+public:
+ enum CaretMode { CaretAtZero, CaretAtOffset, CaretWontMatch };
+
+ TQRegExp();
+ TQRegExp( const TQString& pattern, bool caseSensitive = TRUE,
+ bool wildcard = FALSE );
+ TQRegExp( const TQRegExp& rx );
+ ~TQRegExp();
+ TQRegExp& operator=( const TQRegExp& rx );
+
+ bool operator==( const TQRegExp& rx ) const;
+ bool operator!=( const TQRegExp& rx ) const { return !operator==( rx ); }
+
+ bool isEmpty() const;
+ bool isValid() const;
+ TQString pattern() const;
+ void setPattern( const TQString& pattern );
+ bool caseSensitive() const;
+ void setCaseSensitive( bool sensitive );
+#ifndef TQT_NO_REGEXP_WILDCARD
+ bool wildcard() const;
+ void setWildcard( bool wildcard );
+#endif
+ bool minimal() const;
+ void setMinimal( bool minimal );
+
+ bool exactMatch( const TQString& str ) const;
+#ifndef TQT_NO_COMPAT
+ int match( const TQString& str, int index = 0, int *len = 0,
+ bool indexIsStart = TRUE ) const;
+#endif
+
+#if defined(TQ_TQDOC)
+ int search( const TQString& str, int offset = 0,
+ CaretMode caretMode = CaretAtZero ) const;
+ int searchRev( const TQString& str, int offset = -1,
+ CaretMode caretMode = CaretAtZero ) const;
+#else
+ // ### TQt 4.0: reduce these four to two functions
+ int search( const TQString& str, int offset = 0 ) const;
+ int search( const TQString& str, int offset, CaretMode caretMode ) const;
+ int searchRev( const TQString& str, int offset = -1 ) const;
+ int searchRev( const TQString& str, int offset, CaretMode caretMode ) const;
+#endif
+ int matchedLength() const;
+#ifndef TQT_NO_REGEXP_CAPTURE
+ int numCaptures() const;
+ TQStringList capturedTexts();
+ TQString cap( int nth = 0 );
+ int pos( int nth = 0 );
+ TQString errorString();
+#endif
+
+ static TQString escape( const TQString& str );
+
+private:
+ void prepareEngine() const;
+ void prepareEngineForMatch( const TQString& str ) const;
+ void invalidateEngine();
+
+ static int caretIndex( int offset, CaretMode caretMode );
+
+ TQRegExpEngine *eng;
+ TQRegExpPrivate *priv;
+};
+#endif // USE_QT4
+#endif // TQT_NO_REGEXP
+#endif // TQREGEXP_H
diff --git a/tqtinterface/qt4/src/tools/tqsemaphore.cpp b/tqtinterface/qt4/src/tools/tqsemaphore.cpp
new file mode 100644
index 0000000..7f1eff9
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqsemaphore.cpp
@@ -0,0 +1,255 @@
+/****************************************************************************
+**
+** TQSemaphore class for Unix
+**
+** Created : 20010725
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#if defined(TQT_THREAD_SUPPORT)
+
+#include "tqsemaphore.h"
+#include "tqmutex.h"
+#include "tqwaitcondition.h"
+
+
+/*!
+ \class TQSemaphore tqsemaphore.h
+ \threadsafe
+ \brief The TQSemaphore class provides a robust integer semaphore.
+
+ \ingroup thread
+ \ingroup environment
+
+ A TQSemaphore can be used to serialize thread execution, in a
+ similar way to a TQMutex. A semaphore differs from a mutex, in
+ that a semaphore can be accessed by more than one thread at a
+ time.
+
+ For example, suppose we have an application that stores data in a
+ large tree structure. The application creates 10 threads
+ (commonly called a thread pool) to perform searches on the tree.
+ When the application searches the tree for some piece of data, it
+ uses one thread per base node to do the searching. A semaphore
+ could be used to make sure that two threads don't try to search
+ the same branch of the tree at the same time.
+
+ A non-computing example of a semaphore would be dining at a
+ restuarant. A semaphore is initialized to have a maximum count
+ equal to the number of chairs in the restuarant. As people
+ arrive, they want a seat. As seats are filled, the semaphore is
+ accessed, once per person. As people leave, the access is
+ released, allowing more people to enter. If a party of 10 people
+ want to be seated, but there are only 9 seats, those 10 people
+ will wait, but a party of 4 people would be seated (taking the
+ available seats to 5, making the party of 10 people wait longer).
+
+ When a semaphore is created it is given a number which is the
+ maximum number of concurrent accesses it will permit. Accesses to
+ the sempahore are gained using operator++() or operator+=(), and
+ released with operator--() or operator-=(). The number of
+ accesses allowed is retrieved with available(), and the total
+ number with total(). Note that the incrementing functions will
+ block if there aren't enough available accesses. Use tryAccess()
+ if you want to acquire accesses without blocking.
+*/
+
+
+class TQSemaphorePrivate {
+public:
+ TQSemaphorePrivate(int);
+
+ TQMutex mutex;
+ TQWaitCondition cond;
+
+ int value, max;
+};
+
+
+TQSemaphorePrivate::TQSemaphorePrivate(int m)
+ : mutex(FALSE), value(0), max(m)
+{
+}
+
+
+/*!
+ Creates a new semaphore. The semaphore can be concurrently
+ accessed at most \a maxcount times.
+*/
+TQSemaphore::TQSemaphore(int maxcount)
+{
+ d = new TQSemaphorePrivate(maxcount);
+}
+
+
+/*!
+ Destroys the semaphore.
+
+ \warning If you destroy a semaphore that has accesses in use the
+ resultant behavior is undefined.
+*/
+TQSemaphore::~TQSemaphore()
+{
+ delete d;
+}
+
+
+/*!
+ Postfix ++ operator.
+
+ Try to get access to the semaphore. If \l available() == 0, this
+ call will block until it can get access, i.e. until available() \>
+ 0.
+*/
+int TQSemaphore::operator++(int)
+{
+ TQMutexLocker locker(&d->mutex);
+ while (d->value >= d->max)
+ d->cond.wait(locker.mutex());
+
+ ++d->value;
+ if (d->value > d->max)
+ d->value = d->max;
+
+ return d->value;
+}
+
+
+/*!
+ Postfix -- operator.
+
+ Release access of the semaphore. This wakes all threads waiting
+ for access to the semaphore.
+*/
+int TQSemaphore::operator--(int)
+{
+ TQMutexLocker locker(&d->mutex);
+
+ --d->value;
+ if (d->value < 0)
+ d->value = 0;
+
+ d->cond.wakeAll();
+
+ return d->value;
+}
+
+
+/*!
+ Try to get access to the semaphore. If \l available() \< \a n, this
+ call will block until it can get all the accesses it wants, i.e.
+ until available() \>= \a n.
+*/
+int TQSemaphore::operator+=(int n)
+{
+ TQMutexLocker locker(&d->mutex);
+
+ if ( n < 0 || n > d->max ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQSemaphore::operator+=: paramter %d out of range", n );
+#endif // TQT_CHECK_RANGE
+ n = n < 0 ? 0 : d->max;
+ }
+
+ while (d->value + n > d->max)
+ d->cond.wait(locker.mutex());
+
+ d->value += n;
+
+ return d->value;
+}
+
+
+/*!
+ Release \a n accesses to the semaphore.
+*/
+int TQSemaphore::operator-=(int n)
+{
+ TQMutexLocker locker(&d->mutex);
+
+ if ( n < 0 || n > d->value ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQSemaphore::operator-=: paramter %d out of range", n );
+#endif // TQT_CHECK_RANGE
+ n = n < 0 ? 0 : d->value;
+ }
+
+ d->value -= n;
+ d->cond.wakeAll();
+
+ return d->value;
+}
+
+
+/*!
+ Returns the number of accesses currently available to the
+ semaphore.
+*/
+int TQSemaphore::available() const
+{
+ TQMutexLocker locker(&d->mutex);
+ return d->max - d->value;
+}
+
+
+/*!
+ Returns the total number of accesses to the semaphore.
+*/
+int TQSemaphore::total() const
+{
+ TQMutexLocker locker(&d->mutex);
+ return d->max;
+}
+
+
+/*!
+ Try to get access to the semaphore. If \l available() \< \a n, this
+ function will return FALSE immediately. If \l available() \>= \a n,
+ this function will take \a n accesses and return TRUE. This
+ function does \e not block.
+*/
+bool TQSemaphore::tryAccess(int n)
+{
+ TQMutexLocker locker(&d->mutex);
+
+ if (d->value + n > d->max)
+ return FALSE;
+
+ d->value += n;
+
+ return TRUE;
+}
+
+#endif // TQT_THREAD_SUPPORT
diff --git a/tqtinterface/qt4/src/tools/tqsemaphore.h b/tqtinterface/qt4/src/tools/tqsemaphore.h
new file mode 100644
index 0000000..31e25a9
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqsemaphore.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Definition of TQSemaphore class
+**
+** Created : 931107
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSEMAPHORE_H
+#define TQSEMAPHORE_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#if defined(TQT_THREAD_SUPPORT)
+
+class TQSemaphorePrivate;
+
+class TQ_EXPORT TQSemaphore
+{
+public:
+ TQSemaphore( int );
+ virtual ~TQSemaphore();
+
+ int available() const;
+ int total() const;
+
+ // postfix operators
+ int operator++(int);
+ int operator--(int);
+
+ int operator+=(int);
+ int operator-=(int);
+
+ bool tryAccess(int);
+
+private:
+ TQSemaphorePrivate *d;
+
+#if defined(TQ_DISABLE_COPY)
+ TQSemaphore(const TQSemaphore &);
+ TQSemaphore &operator=(const TQSemaphore &);
+#endif
+};
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqsettings.cpp b/tqtinterface/qt4/src/tools/tqsettings.cpp
new file mode 100644
index 0000000..3ef5e5e
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqsettings.cpp
@@ -0,0 +1,2105 @@
+/****************************************************************************
+**
+** Implementation of TQSettings class
+**
+** Created : 000626
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+// POSIX Large File Support redefines open -> open64
+static inline int qt_open( const char *pathname, int flags, mode_t mode )
+{ return ::open( pathname, flags, mode ); }
+#if defined(open)
+# undef open
+#endif
+
+// POSIX Large File Support redefines truncate -> truncate64
+#if defined(truncate)
+# undef truncate
+#endif
+
+#include "tqsettings.h"
+
+#ifndef TQT_NO_SETTINGS
+
+#include "tqdir.h"
+#include "tqfile.h"
+#include "tqfileinfo.h"
+#include "tqmap.h"
+#include "tqtextstream.h"
+#include "tqregexp.h"
+#include <private/tqsettings_p.h>
+#ifndef NO_ERRNO_H
+#include <errno.h>
+#endif
+
+/*!
+ \class TQSettings
+ \brief The TQSettings class provides persistent platform-independent application settings.
+
+ \ingroup io
+ \ingroup misc
+ \mainclass
+
+ On Unix systems, TQSettings uses text files to store settings. On Windows
+ systems, TQSettings uses the system registry. On Mac OS X, TQSettings uses
+ the Carbon preferences API.
+
+ Each setting comprises an identifying key and the data associated with
+ the key. A key is a tqunicode string which consists of \e two or more
+ subkeys. A subkey is a slash, '/', followed by one or more tqunicode
+ characters (excluding slashes, newlines, carriage returns and equals,
+ '=', signs). The associated data, called the entry or value, may be a
+ boolean, an integer, a double, a string or a list of strings. Entry
+ strings may contain any tqunicode characters.
+
+ If you want to save and restore the entire desktop's settings, i.e.
+ which applications are running, use TQSettings to save the settings
+ for each individual application and TQSessionManager to save the
+ desktop's session.
+
+ Example settings:
+ \code
+ /MyCompany/MyApplication/background color
+ /MyCompany/MyApplication/foreground color
+ /MyCompany/MyApplication/tqgeometry/x
+ /MyCompany/MyApplication/tqgeometry/y
+ /MyCompany/MyApplication/tqgeometry/width
+ /MyCompany/MyApplication/tqgeometry/height
+ /MyCompany/MyApplication/recent files/1
+ /MyCompany/MyApplication/recent files/2
+ /MyCompany/MyApplication/recent files/3
+ \endcode
+ Each line above is a complete key, made up of subkeys.
+
+ A typical usage pattern for reading settings at application
+ startup:
+ \code
+ TQSettings settings;
+ settings.setPath( "MyCompany.com", "MyApplication" );
+
+ TQString bgColor = settings.readEntry( "/colors/background", "white" );
+ int width = settings.readNumEntry( "/tqgeometry/width", 640 );
+ // ...
+ \endcode
+
+ A typical usage pattern for saving settings at application exit or
+ 'save preferences':
+ \code
+ TQSettings settings;
+ settings.setPath( "MyCompany.com", "MyApplication" );
+
+ settings.writeEntry( "/colors/background", bgColor );
+ settings.writeEntry( "/tqgeometry/width", width );
+ // ...
+ \endcode
+
+ A key prefix can be prepended to all keys using beginGroup(). The
+ application of the prefix is stopped using endGroup(). For
+ example:
+ \code
+ TQSettings settings;
+
+ settings.beginGroup( "/MainWindow" );
+ settings.beginGroup( "/Geometry" );
+ int x = settings.readEntry( "/x" );
+ // ...
+ settings.endGroup();
+ settings.beginGroup( "/Toolbars" );
+ // ...
+ settings.endGroup();
+ settings.endGroup();
+ \endcode
+
+ You can get a list of entry-holding keys by calling entryList(), and
+ a list of key-holding keys using subkeyList().
+
+ \code
+ TQStringList keys = settings.entryList( "/MyApplication" );
+ // keys tqcontains 'background color' and 'foreground color'.
+
+ TQStringList keys = settings.entryList( "/MyApplication/recent files" );
+ // keys tqcontains '1', '2' and '3'.
+
+ TQStringList subkeys = settings.subkeyList( "/MyApplication" );
+ // subkeys tqcontains 'tqgeometry' and 'recent files'
+
+ TQStringList subkeys = settings.subkeyList( "/MyApplication/recent files" );
+ // subkeys is empty.
+ \endcode
+
+ Since settings for Windows are stored in the registry there are
+ some size limitations as follows:
+ \list
+ \i A subkey may not exceed 255 characters.
+ \i An entry's value may not exceed 16,300 characters.
+ \i All the values of a key (for example, all the 'recent files'
+ subkeys values), may not exceed 65,535 characters.
+ \endlist
+
+ These limitations are not enforced on Unix or Mac OS X.
+
+ \warning Creating multiple, simultaneous instances of TQSettings writing
+ to a text file may lead to data loss! This is a known issue which will
+ be fixed in a future release of TQt.
+
+ \section1 Notes for Mac OS X Applications
+
+ The location where settings are stored is not formally defined by
+ the CFPreferences API.
+
+ At the time of writing settings are stored (either on a global or
+ user basis, preferring locally) into a plist file in \c
+ $ROOT/System/Library/Preferences (in XML format). TQSettings will
+ create an appropriate plist file (\c{com.<first group name>.plist})
+ out of the full path to a key.
+
+ For further information on CFPreferences see
+ \link http://developer.apple.com/documentation/CoreFoundation/Conceptual/CFPreferences/index.html
+ Apple's Specifications\endlink
+
+ \section1 Notes for Unix Applications
+
+ There is no universally accepted place for storing application
+ settings under Unix. In the examples the settings file will be
+ searched for in the following directories:
+ \list 1
+ \i \c SYSCONF - the default value is \c INSTALL/etc/settings
+ \i \c /opt/MyCompany/share/etc
+ \i \c /opt/MyCompany/share/MyApplication/etc
+ \i \c $HOME/.qt
+ \endlist
+ When reading settings the files are searched in the order shown
+ above, with later settings overriding earlier settings. Files for
+ which the user doesn't have read permission are ignored. When saving
+ settings TQSettings works in the order shown above, writing
+ to the first settings file for which the user has write permission.
+ (\c INSTALL is the directory where TQt was installed. This can be
+ modified by using the configure script's -prefix argument )
+
+ If you want to put the settings in a particular place in the
+ filesystem you could do this:
+ \code
+ settings.insertSearchPath( TQSettings::Unix, "/opt/MyCompany/share" );
+ \endcode
+
+ But in practice you may prefer not to use a search path for Unix.
+ For example the following code:
+ \code
+ settings.writeEntry( "/MyApplication/tqgeometry/width", width );
+ \endcode
+ will end up writing the "tqgeometry/width" setting to the file
+ \c{$HOME/.qt/myapplicationrc} (assuming that the application is
+ being run by an ordinary user, i.e. not by root).
+
+ For cross-platform applications you should ensure that the
+ \link #sizelimit Windows size limitations \endlink are not exceeded.
+
+ \warning TQSettings doesn't write the settings until it is destroyed so
+ you should construct the TQSettings object on the stack.
+*/
+
+/*!
+ \enum TQSettings::System
+
+ \value Mac Macintosh execution environments
+ \value Unix Mac OS X, Unix, Linux and Unix-like execution environments
+ \value Windows Windows execution environments
+*/
+
+/*!
+ \enum TQSettings::Format
+
+ \value Native Store the settings in a platform dependent location
+ \value Ini Store the settings in a text file
+*/
+
+/*!
+ \enum TQSettings::Scope
+
+ \value Global Save settings as global as possible
+ \value User Save settings in user space
+*/
+
+#if defined(TQ_OS_UNIX)
+typedef int HANDLE;
+#define TQ_LOCKREAD F_RDLCK
+#define TQ_LOCKWRITE F_WRLCK
+/*
+ Locks the file specified by name. The lockfile is created as a
+ hidden file in the same directory as the target file, with .lock
+ appended to the name. For example, "/etc/settings/onerc" uses a
+ lockfile named "/etc/settings/.onerc.lock". The type argument
+ controls the type of the lock, it can be either F_RDLCK for a read
+ lock, or F_WRLCK for a write lock.
+
+ A file descriptor for the lock file is returned, and should be
+ closed with closelock() when the lock is no longer needed.
+ */
+static HANDLE openlock( const TQString &name, int type )
+{
+ TQFileInfo info( name );
+ // lockfile should be hidden, and never removed
+ TQString lockfile = info.dirPath() + "/." + info.fileName() + ".lock";
+
+ // open the lockfile
+ HANDLE fd = qt_open( TQFile::encodeName( lockfile ),
+ O_RDWR | O_CREAT, S_IRUSR | S_IWUSR );
+
+ if ( fd < 0 ) {
+ // failed to open the lock file, most likely because of permissions
+ return fd;
+ }
+
+ struct flock fl;
+ fl.l_type = type;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ if ( fcntl( fd, F_SETLKW, &fl ) == -1 ) {
+ // the lock failed, so we should fail silently, so that people
+ // using filesystems that do not support locking don't see
+ // numerous warnings about a failed lock
+ close( fd );
+ fd = -1;
+ }
+
+ return fd;
+}
+
+/*
+ Closes the lock file specified by fd. fd is the file descriptor
+ returned by the openlock() function.
+*/
+static void closelock( HANDLE fd )
+{
+ if ( fd < 0 ) {
+ // the lock file is not open
+ return;
+ }
+
+ struct flock fl;
+ fl.l_type = F_UNLCK;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ // ignore the return value, so that the unlock fails silently
+ (void) fcntl( fd, F_SETLKW, &fl );
+
+ close( fd );
+}
+#endif
+
+
+TQSettingsGroup::TQSettingsGroup()
+ : modified(FALSE)
+{
+}
+
+
+
+
+void TQSettingsHeading::read(const TQString &filename)
+{
+ if (! TQFileInfo(filename).exists())
+ return;
+
+#ifndef TQ_WS_WIN
+ HANDLE lockfd = openlock( filename, TQ_LOCKREAD );
+#endif
+
+ TQFile file(filename);
+ if (! file.open(IO_ReadOnly)) {
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQSettings: failed to open file '%s'", filename.latin1());
+#endif
+ return;
+ }
+
+ git = end();
+
+ TQTextStream stream(&file);
+ stream.setEncoding(TQTextStream::UnicodeUTF8);
+ while (! stream.atEnd())
+ parseLine(stream);
+
+ git = end();
+
+ file.close();
+
+#ifndef TQ_WS_WIN
+ closelock( lockfd );
+#endif
+}
+
+
+void TQSettingsHeading::parseLine(TQTextStream &stream)
+{
+ TQString line = stream.readLine();
+ if (line.isEmpty())
+ // empty line... we'll allow it
+ return;
+
+ if (line[0] == TQChar('#'))
+ // commented line
+ return;
+
+ if (line[0] == TQChar('[')) {
+ TQString gname = line;
+
+ gname = gname.remove((uint)0, 1);
+ if (gname[(int)gname.length() - 1] == TQChar(']'))
+ gname = gname.remove(gname.length() - 1, 1);
+
+ git = tqfind(gname);
+ if (git == end())
+ git = tqreplace(gname, TQSettingsGroup());
+ } else {
+ if (git == end()) {
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQSettings: line '%s' out of group", line.latin1());
+#endif
+ return;
+ }
+
+ int i = line.tqfind('=');
+ if (i == -1) {
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQSettings: malformed line '%s' in group '%s'",
+ line.latin1(), git.key().latin1());
+#endif
+ return;
+ } else {
+ TQString key, value;
+ key = line.left(i);
+ value = "";
+ bool esc=TRUE;
+ i++;
+ while (esc) {
+ esc = FALSE;
+ for ( ; i < (int)line.length(); i++ ) {
+ if ( esc ) {
+ if ( line[i] == 'n' )
+ value.append('\n'); // escaped newline
+ else if ( line[i] == '0' )
+ value = TQString::null; // escaped empty string
+ else
+ value.append(line[i]);
+ esc = FALSE;
+ } else if ( line[i] == '\\' )
+ esc = TRUE;
+ else
+ value.append(line[i]);
+ }
+ if ( esc ) {
+ // Backwards-compatiblity...
+ // still escaped at EOL - manually escaped "newline"
+ if (stream.atEnd()) {
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQSettings: reached end of file, expected continued line");
+#endif
+ break;
+ }
+ value.append('\n');
+ line = stream.readLine();
+ i = 0;
+ }
+ }
+
+ (*git).insert(key, value);
+ }
+ }
+}
+
+#ifdef TQ_WS_WIN // for homedirpath reading from registry
+#include "tqt_windows.h"
+#include "tqlibrary.h"
+
+#ifndef CSIDL_APPDATA
+#define CSIDL_APPDATA 0x001a // <user name>\Application Data
+#endif
+#ifndef CSIDL_COMMON_APPDATA
+#define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
+#endif
+
+#endif
+
+TQSettingsPrivate::TQSettingsPrivate( TQSettings::Format format )
+ : groupDirty( TRUE ), modified(FALSE), globalScope(TRUE)
+{
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( format != TQSettings::Ini )
+ return;
+#else
+ TQ_UNUSED( format );
+#endif
+
+ TQString appSettings(TQDir::homeDirPath() + "/.qt/");
+ TQString defPath;
+#ifdef TQ_WS_WIN
+#ifdef TQ_OS_TEMP
+ TCHAR path[MAX_PATH];
+ SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
+ appSettings = TQString::fromUcs2( path );
+ SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
+ defPath = TQString::fromUcs2( path );
+#else
+ TQLibrary library( "shell32" );
+ library.setAutoUnload( FALSE );
+ TQT_WA( {
+ typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL);
+ GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve( "SHGetSpecialFolderPathW" );
+ if ( SHGetSpecialFolderPath ) {
+ TCHAR path[MAX_PATH];
+ SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
+ appSettings = TQString::fromUcs2( (ushort*)path );
+ SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
+ defPath = TQString::fromUcs2( (ushort*)path );
+ }
+ } , {
+ typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, char*, int, BOOL);
+ GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve( "SHGetSpecialFolderPathA" );
+ if ( SHGetSpecialFolderPath ) {
+ char path[MAX_PATH];
+ SHGetSpecialFolderPath( 0, path, CSIDL_APPDATA, FALSE );
+ appSettings = TQString::fromLocal8Bit( path );
+ SHGetSpecialFolderPath( 0, path, CSIDL_COMMON_APPDATA, FALSE );
+ defPath = TQString::fromLocal8Bit( path );
+ }
+ } );
+#endif // TQ_OS_TEMP
+#else
+ defPath = qInstallPathSysconf();
+#endif
+ TQDir dir(appSettings);
+ if (! dir.exists()) {
+ if (! dir.mkdir(dir.path()))
+#if defined(TQT_CHECK_STATE)
+ qWarning("TQSettings: error creating %s", dir.path().latin1());
+#else
+ ;
+#endif
+ }
+
+ if ( !!defPath )
+ searchPaths.append(defPath);
+ searchPaths.append(dir.path());
+}
+
+TQSettingsPrivate::~TQSettingsPrivate()
+{
+}
+
+TQSettingsGroup TQSettingsPrivate::readGroup()
+{
+ TQSettingsHeading hd;
+ TQSettingsGroup grp;
+
+ TQMap<TQString,TQSettingsHeading>::Iterator headingsit = headings.tqfind(heading);
+ if (headingsit != headings.end())
+ hd = *headingsit;
+
+ TQSettingsHeading::Iterator grpit = hd.tqfind(group);
+ if (grpit == hd.end()) {
+ TQStringList::Iterator it = searchPaths.begin();
+ if ( !globalScope )
+ ++it;
+ while (it != searchPaths.end()) {
+ TQString filebase = heading.lower().tqreplace(TQRegExp(TQString::tqfromLatin1("\\s+")), "_");
+ TQString fn((*it++) + "/" + filebase + "rc");
+ if (! hd.tqcontains(fn + "cached")) {
+ hd.read(fn);
+ hd.insert(fn + "cached", TQSettingsGroup());
+ }
+ }
+
+ headings.tqreplace(heading, hd);
+
+ grpit = hd.tqfind(group);
+ if (grpit != hd.end())
+ grp = *grpit;
+ } else if (hd.count() != 0)
+ grp = *grpit;
+
+ return grp;
+}
+
+
+void TQSettingsPrivate::removeGroup(const TQString &key)
+{
+ TQSettingsHeading hd;
+ TQSettingsGroup grp;
+ bool found = FALSE;
+
+ TQMap<TQString,TQSettingsHeading>::Iterator headingsit = headings.tqfind(heading);
+ if (headingsit != headings.end())
+ hd = *headingsit;
+
+ TQSettingsHeading::Iterator grpit = hd.tqfind(group);
+ if (grpit == hd.end()) {
+ TQStringList::Iterator it = searchPaths.begin();
+ if ( !globalScope )
+ ++it;
+ while (it != searchPaths.end()) {
+ TQString filebase = heading.lower().tqreplace(TQRegExp(TQString::tqfromLatin1("\\s+")), "_");
+ TQString fn((*it++) + "/" + filebase + "rc");
+ if (! hd.tqcontains(fn + "cached")) {
+ hd.read(fn);
+ hd.insert(fn + "cached", TQSettingsGroup());
+ }
+ }
+
+ headings.tqreplace(heading, hd);
+
+ grpit = hd.tqfind(group);
+ if (grpit != hd.end()) {
+ found = TRUE;
+ grp = *grpit;
+ }
+ } else if (hd.count() != 0) {
+ found = TRUE;
+ grp = *grpit;
+ }
+
+ if (found) {
+ grp.remove(key);
+
+ if (grp.count() > 0)
+ hd.tqreplace(group, grp);
+ else
+ hd.remove(group);
+
+ if (hd.count() > 0)
+ headings.tqreplace(heading, hd);
+ else
+ headings.remove(heading);
+
+ modified = TRUE;
+ }
+}
+
+
+void TQSettingsPrivate::writeGroup(const TQString &key, const TQString &value)
+{
+ TQSettingsHeading hd;
+ TQSettingsGroup grp;
+
+ TQMap<TQString,TQSettingsHeading>::Iterator headingsit = headings.tqfind(heading);
+ if (headingsit != headings.end())
+ hd = *headingsit;
+
+ TQSettingsHeading::Iterator grpit = hd.tqfind(group);
+ if (grpit == hd.end()) {
+ TQStringList::Iterator it = searchPaths.begin();
+ if ( !globalScope )
+ ++it;
+ while (it != searchPaths.end()) {
+ TQString filebase = heading.lower().tqreplace(TQRegExp(TQString::tqfromLatin1("\\s+")), "_");
+ TQString fn((*it++) + "/" + filebase + "rc");
+ if (! hd.tqcontains(fn + "cached")) {
+ hd.read(fn);
+ hd.insert(fn + "cached", TQSettingsGroup());
+ }
+ }
+
+ headings.tqreplace(heading, hd);
+
+ grpit = hd.tqfind(group);
+ if (grpit != hd.end())
+ grp = *grpit;
+ } else if (hd.count() != 0)
+ grp = *grpit;
+
+ grp.modified = TRUE;
+ grp.tqreplace(key, value);
+ hd.tqreplace(group, grp);
+ headings.tqreplace(heading, hd);
+
+ modified = TRUE;
+}
+
+
+TQDateTime TQSettingsPrivate::modificationTime()
+{
+ TQSettingsHeading hd = headings[heading];
+ TQSettingsGroup grp = hd[group];
+
+ TQDateTime datetime;
+
+ TQStringList::Iterator it = searchPaths.begin();
+ if ( !globalScope )
+ ++it;
+ while (it != searchPaths.end()) {
+ TQFileInfo fi((*it++) + "/" + heading + "rc");
+ if (fi.exists() && fi.lastModified() > datetime)
+ datetime = fi.lastModified();
+ }
+
+ return datetime;
+}
+
+bool qt_verify_key( const TQString &key )
+{
+ if ( key.isEmpty() || key[0] != '/' || key.tqcontains( TQRegExp(TQString::tqfromLatin1("[=\\r\\n]")) ) )
+ return FALSE;
+ return TRUE;
+}
+
+static TQString groupKey( const TQString &group, const TQString &key )
+{
+ TQString grp_key;
+ if ( group.isEmpty() || ( group.length() == 1 && group[0] == '/' ) ) {
+ // group is empty, or it tqcontains a single '/', so we just return the key
+ if ( key.startsWith( "/" ) )
+ grp_key = key;
+ else
+ grp_key = "/" + key;
+ } else if ( group.endsWith( "/" ) || key.startsWith( "/" ) ) {
+ grp_key = group + key;
+ } else {
+ grp_key = group + "/" + key;
+ }
+ return grp_key;
+}
+
+/*!
+ Inserts \a path into the settings search path. The semantics of \a
+ path depends on the system \a s. It is usually easier and better to
+ use setPath() instead of this function.
+
+ When \a s is \e Windows and the execution environment is \e not
+ Windows the function does nothing. Similarly when \a s is \e Unix and
+ the execution environment is \e not Unix the function does nothing.
+
+ When \a s is \e Windows, and the execution environment is Windows, the
+ search path list will be used as the first subfolder of the "Software"
+ folder in the registry.
+
+ When reading settings the folders are searched forwards from the
+ first folder (listed below) to the last, returning the first
+ settings found, and ignoring any folders for which the user doesn't
+ have read permission.
+ \list 1
+ \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication
+ \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication
+ \i HKEY_CURRENT_USER/Software/MyApplication
+ \i HKEY_LOCAL_MACHINE/Software/MyApplication
+ \endlist
+
+ \code
+ TQSettings settings;
+ settings.insertSearchPath( TQSettings::Windows, "/MyCompany" );
+ settings.writeEntry( "/MyApplication/Tip of the day", TRUE );
+ \endcode
+ The code above will write the subkey "Tip of the day" into the \e
+ first of the registry folders listed below that is found and for
+ which the user has write permission.
+ \list 1
+ \i HKEY_LOCAL_MACHINE/Software/MyCompany/MyApplication
+ \i HKEY_CURRENT_USER/Software/MyCompany/MyApplication
+ \i HKEY_LOCAL_MACHINE/Software/MyApplication
+ \i HKEY_CURRENT_USER/Software/MyApplication
+ \endlist
+ If a setting is found in the HKEY_CURRENT_USER space, this setting
+ is overwritten independently of write permissions in the
+ HKEY_LOCAL_MACHINE space.
+
+ When \a s is \e Unix, and the execution environment is Unix, the
+ search path list will be used when trying to determine a suitable
+ filename for reading and writing settings files. By default, there are
+ two entries in the search path:
+
+ \list 1
+ \i \c SYSCONF - where \c SYSCONF is a directory specified when
+ configuring TQt; by default it is INSTALL/etc/settings.
+ \i \c $HOME/.qt/ - where \c $HOME is the user's home directory.
+ \endlist
+
+ All insertions into the search path will go before $HOME/.qt/.
+ For example:
+ \code
+ TQSettings settings;
+ settings.insertSearchPath( TQSettings::Unix, "/opt/MyCompany/share/etc" );
+ settings.insertSearchPath( TQSettings::Unix, "/opt/MyCompany/share/MyApplication/etc" );
+ // ...
+ \endcode
+ Will result in a search path of:
+ \list 1
+ \i SYSCONF
+ \i /opt/MyCompany/share/etc
+ \i /opt/MyCompany/share/MyApplication/etc
+ \i $HOME/.qt
+ \endlist
+ When reading settings the files are searched in the order shown
+ above, with later settings overriding earlier settings. Files for
+ which the user doesn't have read permission are ignored. When saving
+ settings TQSettings works in the order shown above, writing
+ to the first settings file for which the user has write permission.
+
+ Note that paths in the file system are not created by this
+ function, so they must already exist to be useful.
+
+ Settings under Unix are stored in files whose names are based on the
+ first subkey of the key (not including the search path). The algorithm
+ for creating names is essentially: lowercase the first subkey, tqreplace
+ spaces with underscores and add 'rc', e.g.
+ <tt>/MyCompany/MyApplication/background color</tt> will be stored in
+ <tt>myapplicationrc</tt> (assuming that <tt>/MyCompany</tt> is part of
+ the search path).
+
+ \sa removeSearchPath()
+
+*/
+void TQSettings::insertSearchPath( System s, const TQString &path)
+{
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd ) {
+ d->sysInsertSearchPath( s, path );
+ return;
+ }
+#endif
+
+#if !defined(TQ_WS_WIN)
+ if ( s == Windows )
+ return;
+#endif
+#if !defined(TQ_OS_MAC)
+ if ( s == Mac )
+ return;
+#endif
+
+ if ( !qt_verify_key( path ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
+#endif
+ return;
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd && s != Unix ) {
+#else
+ if ( s != Unix ) {
+#endif
+#if !defined(TQWS) && defined(TQ_OS_MAC)
+ if(s != Mac) //mac is respected on the mac as well
+#endif
+ return;
+ }
+
+ TQString realPath = path;
+#if defined(TQ_WS_WIN)
+ TQString defPath = d->globalScope ? d->searchPaths.first() : d->searchPaths.last();
+ realPath = defPath + path;
+#endif
+
+ TQStringList::Iterator it = d->searchPaths.tqfind(d->searchPaths.last());
+ if (it != d->searchPaths.end()) {
+ d->searchPaths.insert(it, realPath);
+ }
+}
+
+
+/*!
+ Removes all occurrences of \a path (using exact matching) from the
+ settings search path for system \a s. Note that the default search
+ paths cannot be removed.
+
+ \sa insertSearchPath()
+*/
+void TQSettings::removeSearchPath( System s, const TQString &path)
+{
+ if ( !qt_verify_key( path ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::insertSearchPath: Invalid key: '%s'", path.isNull() ? "(null)" : path.latin1() );
+#endif
+ return;
+ }
+
+#ifdef TQ_WS_WIN
+ if ( d->sysd ) {
+ d->sysRemoveSearchPath( s, path );
+ return;
+ }
+#endif
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd && s != Unix ) {
+#else
+ if ( s != Unix ) {
+#endif
+#if !defined(TQWS) && defined(TQ_OS_MAC)
+ if(s != Mac) //mac is respected on the mac as well
+#endif
+ return;
+ }
+
+ if (path == d->searchPaths.first() || path == d->searchPaths.last())
+ return;
+
+ d->searchPaths.remove(path);
+}
+
+
+/*!
+ Creates a settings object.
+
+ Be aware that you must call setPath() or insertSearchPath() before
+ you can use the TQSettings object.
+*/
+TQSettings::TQSettings()
+{
+ d = new TQSettingsPrivate( Native );
+ TQ_CHECK_PTR(d);
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ d->sysd = 0;
+ d->sysInit();
+#endif
+}
+
+/*!
+ Creates a settings object. If \a format is 'Ini' the settings will
+ be stored in a text file, using the Unix strategy (see above). If \a format
+ is 'Native', the settings will be stored in a platform specific way
+ (ie. the Windows registry).
+
+ Be aware that you must call setPath() or insertSearchPath() before
+ you can use the TQSettings object.
+*/
+TQSettings::TQSettings( Format format )
+{
+ d = new TQSettingsPrivate( format );
+ TQ_CHECK_PTR(d);
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ d->sysd = 0;
+ if ( format == Native )
+ d->sysInit();
+#else
+ TQ_UNUSED(format);
+#endif
+}
+
+/*!
+ Destroys the settings object. All modifications made to the settings
+ will automatically be saved.
+
+*/
+TQSettings::~TQSettings()
+{
+ sync();
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ d->sysClear();
+#endif
+
+ delete d;
+}
+
+
+/*! \internal
+ Writes all modifications to the settings to disk. If any errors are
+ encountered, this function returns FALSE, otherwise it will return TRUE.
+*/
+bool TQSettings::sync()
+{
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysSync();
+#endif
+ if (! d->modified)
+ // fake success
+ return TRUE;
+
+ bool success = TRUE;
+ TQMap<TQString,TQSettingsHeading>::Iterator it = d->headings.begin();
+
+ while (it != d->headings.end()) {
+ // determine filename
+ TQSettingsHeading hd(*it);
+ TQSettingsHeading::Iterator hdit = hd.begin();
+ TQString filename;
+
+ TQStringList::Iterator pit = d->searchPaths.begin();
+ if ( !d->globalScope )
+ ++pit;
+ while (pit != d->searchPaths.end()) {
+ TQString filebase = it.key().lower().tqreplace(TQRegExp(TQString::tqfromLatin1("\\s+")), "_");
+ TQFileInfo di(*pit);
+ if ( !di.exists() ) {
+ TQDir dir;
+ dir.mkdir( *pit );
+ }
+
+ TQFileInfo fi((*pit++) + "/" + filebase + "rc");
+
+ if ((fi.exists() && fi.isFile() && fi.isWritable()) ||
+ (! fi.exists() && di.isDir()
+#ifndef TQ_WS_WIN
+ && di.isWritable()
+#else
+ && ((qWinVersion()&TQt::WV_NT_based) > TQt::WV_2000 || di.isWritable())
+#endif
+ )) {
+ filename = fi.filePath();
+ break;
+ }
+ }
+
+ ++it;
+
+ if ( filename.isEmpty() ) {
+
+#ifdef TQT_CHECK_STATE
+ qWarning("TQSettings::sync: filename is null/empty");
+#endif // TQT_CHECK_STATE
+
+ success = FALSE;
+ continue;
+ }
+
+#ifndef TQ_WS_WIN
+ HANDLE lockfd = openlock( filename, TQ_LOCKWRITE );
+#endif
+
+ TQFile file( filename + ".tmp" );
+ if (! file.open(IO_WriteOnly)) {
+
+#ifdef TQT_CHECK_STATE
+ qWarning("TQSettings::sync: failed to open '%s' for writing",
+ file.name().latin1());
+#endif // TQT_CHECK_STATE
+
+ success = FALSE;
+ continue;
+ }
+
+ // spew to file
+ TQTextStream stream(&file);
+ stream.setEncoding(TQTextStream::UnicodeUTF8);
+
+ while (hdit != hd.end()) {
+ if ((*hdit).count() > 0) {
+ stream << "[" << hdit.key() << "]" << endl;
+
+ TQSettingsGroup grp(*hdit);
+ TQSettingsGroup::Iterator grpit = grp.begin();
+
+ while (grpit != grp.end()) {
+ TQString v = grpit.data();
+ if ( v.isNull() ) {
+ v = TQString::tqfromLatin1("\\0"); // escape null string
+ } else {
+ v.tqreplace('\\', TQString::tqfromLatin1("\\\\")); // escape backslash
+ v.tqreplace('\n', TQString::tqfromLatin1("\\n")); // escape newlines
+ }
+
+ stream << grpit.key() << "=" << v << endl;
+ ++grpit;
+ }
+
+ stream << endl;
+ }
+
+ ++hdit;
+ }
+
+ if (file.status() != IO_Ok) {
+
+#ifdef TQT_CHECK_STATE
+ qWarning("TQSettings::sync: error at end of write");
+#endif // TQT_CHECK_STATE
+
+ success = FALSE;
+ }
+
+ file.close();
+
+ if ( success ) {
+ TQDir dir( TQFileInfo( file ).dir( TRUE ) );
+ if ( dir.exists( filename ) && !dir.remove( filename ) ||
+ !dir.rename( file.name(), filename, TRUE ) ) {
+
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQSettings::sync: error writing file '%s'",
+ TQFile::encodeName( filename ).data() );
+#endif // TQT_CHECK_STATE
+
+ success = FALSE;
+ }
+ }
+
+ // remove temporary file
+ file.remove();
+
+#ifndef TQ_WS_WIN
+ closelock( lockfd );
+#endif
+ }
+
+ d->modified = FALSE;
+
+ return success;
+}
+
+
+/*!
+ \fn bool TQSettings::readBoolEntry(const TQString &key, bool def, bool *ok ) const
+
+ Reads the entry specified by \a key, and returns a bool, or the
+ default value, \a def, if the entry couldn't be read.
+ If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
+ otherwise.
+
+ \sa readEntry(), readNumEntry(), readDoubleEntry(), writeEntry(), removeEntry()
+*/
+
+/*!
+ \internal
+*/
+bool TQSettings::readBoolEntry(const TQString &key, bool def, bool *ok )
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::readBoolEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ if ( ok )
+ *ok = FALSE;
+
+ return def;
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysReadBoolEntry( grp_key, def, ok );
+#endif
+
+ TQString value = readEntry( key, ( def ? "true" : "false" ), ok );
+
+ if (value.lower() == "true")
+ return TRUE;
+ else if (value.lower() == "false")
+ return FALSE;
+ else if (value == "1")
+ return TRUE;
+ else if (value == "0")
+ return FALSE;
+
+ if (! value.isEmpty())
+ qWarning("TQSettings::readBoolEntry: '%s' is not 'true' or 'false'",
+ value.latin1());
+ if ( ok )
+ *ok = FALSE;
+ return def;
+}
+
+
+/*!
+ \fn double TQSettings::readDoubleEntry(const TQString &key, double def, bool *ok ) const
+
+ Reads the entry specified by \a key, and returns a double, or the
+ default value, \a def, if the entry couldn't be read.
+ If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
+ otherwise.
+
+ \sa readEntry(), readNumEntry(), readBoolEntry(), writeEntry(), removeEntry()
+*/
+
+/*!
+ \internal
+*/
+double TQSettings::readDoubleEntry(const TQString &key, double def, bool *ok )
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::readDoubleEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ if ( ok )
+ *ok = FALSE;
+
+ return def;
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysReadDoubleEntry( grp_key, def, ok );
+#endif
+
+ TQString value = readEntry( key, TQString::number(def), ok );
+ bool conv_ok;
+ double retval = value.toDouble( &conv_ok );
+ if ( conv_ok )
+ return retval;
+ if ( ! value.isEmpty() )
+ qWarning( "TQSettings::readDoubleEntry: '%s' is not a number",
+ value.latin1() );
+ if ( ok )
+ *ok = FALSE;
+ return def;
+}
+
+
+/*!
+ \fn int TQSettings::readNumEntry(const TQString &key, int def, bool *ok ) const
+
+ Reads the entry specified by \a key, and returns an integer, or the
+ default value, \a def, if the entry couldn't be read.
+ If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
+ otherwise.
+
+ \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry()
+*/
+
+/*!
+ \internal
+*/
+int TQSettings::readNumEntry(const TQString &key, int def, bool *ok )
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::readNumEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ if ( ok )
+ *ok = FALSE;
+ return def;
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysReadNumEntry( grp_key, def, ok );
+#endif
+
+ TQString value = readEntry( key, TQString::number( def ), ok );
+ bool conv_ok;
+ int retval = value.toInt( &conv_ok );
+ if ( conv_ok )
+ return retval;
+ if ( ! value.isEmpty() )
+ qWarning( "TQSettings::readNumEntry: '%s' is not a number",
+ value.latin1() );
+ if ( ok )
+ *ok = FALSE;
+ return def;
+}
+
+
+/*!
+ \fn TQString TQSettings::readEntry(const TQString &key, const TQString &def, bool *ok ) const
+
+ Reads the entry specified by \a key, and returns a TQString, or the
+ default value, \a def, if the entry couldn't be read.
+ If \a ok is non-null, *ok is set to TRUE if the key was read, FALSE
+ otherwise.
+
+ \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry()
+*/
+
+/*!
+ \internal
+*/
+TQString TQSettings::readEntry(const TQString &key, const TQString &def, bool *ok )
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::readEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ if ( ok )
+ *ok = FALSE;
+
+ return def;
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysReadEntry( grp_key, def, ok );
+#endif
+
+ if ( ok ) // no, everything is not ok
+ *ok = FALSE;
+
+ TQString realkey;
+
+ if (grp_key[0] == '/') {
+ // parse our key
+ TQStringList list(TQStringList::split('/', grp_key));
+
+ if (list.count() < 2) {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQSettings::readEntry: invalid key '%s'", grp_key.latin1());
+#endif // TQT_CHECK_STATE
+ if ( ok )
+ *ok = FALSE;
+ return def;
+ }
+
+ if (list.count() == 2) {
+ d->heading = list[0];
+ d->group = "General";
+ realkey = list[1];
+ } else {
+ d->heading = list[0];
+ d->group = list[1];
+
+ // remove the group from the list
+ list.remove(list.at(1));
+ // remove the heading from the list
+ list.remove(list.at(0));
+
+ realkey = list.join("/");
+ }
+ } else {
+ realkey = grp_key;
+ }
+
+ TQSettingsGroup grp = d->readGroup();
+ TQSettingsGroup::const_iterator it = grp.tqfind( realkey ), end = grp.end();
+ TQString retval = def;
+ if ( it != end ) {
+ // found the value we needed
+ retval = *it;
+ if ( ok ) *ok = TRUE;
+ }
+ return retval;
+}
+
+
+#if !defined(TQ_NO_BOOL_TYPE)
+/*!
+ Writes the boolean entry \a value into key \a key. The \a key is
+ created if it doesn't exist. Any previous value is overwritten by \a
+ value.
+
+ If an error occurs the settings are left unchanged and FALSE is
+ returned; otherwise TRUE is returned.
+
+ \warning On certain platforms, keys are required to contain at least
+ two components (e.g., "/foo/bar"). This limitation does not apply to
+ TQt 4.
+
+ \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
+*/
+bool TQSettings::writeEntry(const TQString &key, bool value)
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ return FALSE;
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysWriteEntry( grp_key, value );
+#endif
+ TQString s(value ? "true" : "false");
+ return writeEntry(key, s);
+}
+#endif
+
+
+/*!
+ \overload
+ Writes the double entry \a value into key \a key. The \a key is
+ created if it doesn't exist. Any previous value is overwritten by \a
+ value.
+
+ If an error occurs the settings are left unchanged and FALSE is
+ returned; otherwise TRUE is returned.
+
+ \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
+*/
+bool TQSettings::writeEntry(const TQString &key, double value)
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ return FALSE;
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysWriteEntry( grp_key, value );
+#endif
+ TQString s(TQString::number(value));
+ return writeEntry(key, s);
+}
+
+
+/*!
+ \overload
+ Writes the integer entry \a value into key \a key. The \a key is
+ created if it doesn't exist. Any previous value is overwritten by \a
+ value.
+
+ If an error occurs the settings are left unchanged and FALSE is
+ returned; otherwise TRUE is returned.
+
+ \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
+*/
+bool TQSettings::writeEntry(const TQString &key, int value)
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ return FALSE;
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysWriteEntry( grp_key, value );
+#endif
+ TQString s(TQString::number(value));
+ return writeEntry(key, s);
+}
+
+
+/*!
+ \internal
+
+ Writes the entry specified by \a key with the string-literal \a value,
+ replacing any previous setting. If \a value is zero-length or null, the
+ entry is tqreplaced by an empty setting.
+
+ \e NOTE: This function is provided because some compilers use the
+ writeEntry (const TQString &, bool) overload for this code:
+ writeEntry ("/foo/bar", "baz")
+
+ If an error occurs, this functions returns FALSE and the object is left
+ unchanged.
+
+ \sa readEntry(), removeEntry()
+*/
+bool TQSettings::writeEntry(const TQString &key, const char *value)
+{
+ return writeEntry(key, TQString(value));
+}
+
+
+/*!
+ \overload
+ Writes the string entry \a value into key \a key. The \a key is
+ created if it doesn't exist. Any previous value is overwritten by \a
+ value. If \a value is an empty string or a null string the key's
+ value will be an empty string.
+
+ If an error occurs the settings are left unchanged and FALSE is
+ returned; otherwise TRUE is returned.
+
+ \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
+*/
+bool TQSettings::writeEntry(const TQString &key, const TQString &value)
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::writeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ return FALSE;
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysWriteEntry( grp_key, value );
+#endif
+ // NOTE: we *do* allow value to be a null/empty string
+
+ TQString realkey;
+
+ if (grp_key[0] == '/') {
+ // parse our key
+ TQStringList list(TQStringList::split('/', grp_key));
+
+ if (list.count() < 2) {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQSettings::writeEntry: invalid key '%s'", grp_key.latin1());
+#endif // TQT_CHECK_STATE
+
+ return FALSE;
+ }
+
+ if (list.count() == 2) {
+ d->heading = list[0];
+ d->group = "General";
+ realkey = list[1];
+ } else {
+ d->heading = list[0];
+ d->group = list[1];
+
+ // remove the group from the list
+ list.remove(list.at(1));
+ // remove the heading from the list
+ list.remove(list.at(0));
+
+ realkey = list.join("/");
+ }
+ } else {
+ realkey = grp_key;
+ }
+
+ d->writeGroup(realkey, value);
+ return TRUE;
+}
+
+
+/*!
+ Removes the entry specified by \a key.
+
+ Returns true if the entry was successfully removed; otherwise
+ returns false. Note that removing the last entry in any given
+ folder, will also remove the folder.
+
+ \sa readEntry(), writeEntry()
+*/
+bool TQSettings::removeEntry(const TQString &key)
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::removeEntry: Invalid key: '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ return FALSE;
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysRemoveEntry( grp_key );
+#endif
+
+ TQString realkey;
+ if (grp_key[0] == '/') {
+ // parse our key
+ TQStringList list(TQStringList::split('/', grp_key));
+
+ if (list.count() < 2) {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQSettings::removeEntry: invalid key '%s'", grp_key.latin1());
+#endif // TQT_CHECK_STATE
+
+ return FALSE;
+ }
+
+ if (list.count() == 2) {
+ d->heading = list[0];
+ d->group = "General";
+ realkey = list[1];
+ } else {
+ d->heading = list[0];
+ d->group = list[1];
+
+ // remove the group from the list
+ list.remove(list.at(1));
+ // remove the heading from the list
+ list.remove(list.at(0));
+
+ realkey = list.join("/");
+ }
+ } else {
+ realkey = grp_key;
+ }
+
+ d->removeGroup(realkey);
+ return TRUE;
+}
+
+
+/*!
+ Returns a list of the keys which contain entries under \a key. Does \e
+ not return any keys that contain subkeys.
+
+ Example settings:
+ \code
+ /MyCompany/MyApplication/background color
+ /MyCompany/MyApplication/foreground color
+ /MyCompany/MyApplication/tqgeometry/x
+ /MyCompany/MyApplication/tqgeometry/y
+ /MyCompany/MyApplication/tqgeometry/width
+ /MyCompany/MyApplication/tqgeometry/height
+ \endcode
+ \code
+ TQStringList keys = settings.entryList( "/MyCompany/MyApplication" );
+ \endcode
+
+ In the above example, \c keys will contain 'background color' and
+ 'foreground color'. It will not contain 'tqgeometry' because this key
+ tqcontains subkeys not entries.
+
+ To access the tqgeometry values, you could either use subkeyList()
+ to read the keys then read each entry, or simply read each entry
+ directly by specifying its full key, e.g.
+ "/MyCompany/MyApplication/tqgeometry/y".
+
+ \sa subkeyList()
+*/
+TQStringList TQSettings::entryList(const TQString &key) const
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::entryList: Invalid key: %s", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ return TQStringList();
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysEntryList( grp_key );
+#endif
+
+ TQString realkey;
+ if (grp_key[0] == '/') {
+ // parse our key
+ TQStringList list(TQStringList::split('/', grp_key));
+
+ if (list.count() < 1) {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQSettings::listEntries: invalid key '%s'", grp_key.latin1());
+#endif // TQT_CHECK_STATE
+
+ return TQStringList();
+ }
+
+ if (list.count() == 1) {
+ d->heading = list[0];
+ d->group = "General";
+ } else {
+ d->heading = list[0];
+ d->group = list[1];
+
+ // remove the group from the list
+ list.remove(list.at(1));
+ // remove the heading from the list
+ list.remove(list.at(0));
+
+ realkey = list.join("/");
+ }
+ } else
+ realkey = grp_key;
+
+ TQSettingsGroup grp = d->readGroup();
+ TQSettingsGroup::Iterator it = grp.begin();
+ TQStringList ret;
+ TQString itkey;
+ while (it != grp.end()) {
+ itkey = it.key();
+ ++it;
+
+ if ( realkey.length() > 0 ) {
+ if ( itkey.left( realkey.length() ) != realkey )
+ continue;
+ else
+ itkey.remove( 0, realkey.length() + 1 );
+ }
+
+ if ( itkey.tqfind( '/' ) != -1 )
+ continue;
+
+ ret << itkey;
+ }
+
+ return ret;
+}
+
+
+/*!
+ Returns a list of the keys which contain subkeys under \a key. Does \e
+ not return any keys that contain entries.
+
+ Example settings:
+ \code
+ /MyCompany/MyApplication/background color
+ /MyCompany/MyApplication/foreground color
+ /MyCompany/MyApplication/tqgeometry/x
+ /MyCompany/MyApplication/tqgeometry/y
+ /MyCompany/MyApplication/tqgeometry/width
+ /MyCompany/MyApplication/tqgeometry/height
+ /MyCompany/MyApplication/recent files/1
+ /MyCompany/MyApplication/recent files/2
+ /MyCompany/MyApplication/recent files/3
+ \endcode
+ \code
+ TQStringList keys = settings.subkeyList( "/MyCompany/MyApplication" );
+ \endcode
+
+ In the above example, \c keys will contain 'tqgeometry' and
+ 'recent files'. It will not contain 'background color' or
+ 'foreground color' because those keys contain entries not
+ subkeys. To get a list of keys that contain entries rather than
+ subkeys use entryList() instead.
+
+ \warning In the above example, if TQSettings is writing to an Ini file,
+ then a call to
+ \code subkeyList("/MyCompany") \endcode
+ will return an empty list. This happens because a key like
+ \code /MyCompany/MyApplication/background color \endcode
+ is written to the file \e{"mycompanyrc"}, under the section \e{[MyApplication]}.
+ This call is therefore a request to list the sections in an ini file, which
+ is not supported in this version of TQSettings. This is a known issue which
+ will be fixed in TQt-4.
+
+ \sa entryList()
+*/
+TQStringList TQSettings::subkeyList(const TQString &key) const
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::subkeyList: Invalid key: %s", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ return TQStringList();
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return d->sysSubkeyList( grp_key );
+#endif
+
+ TQString realkey;
+ int subkeycount = 2;
+ if (grp_key[0] == '/') {
+ // parse our key
+ TQStringList list(TQStringList::split('/', grp_key));
+
+ if (list.count() < 1) {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQSettings::subkeyList: invalid key '%s'", grp_key.latin1());
+#endif // TQT_CHECK_STATE
+
+ return TQStringList();
+ }
+
+ subkeycount = (int)list.count();
+
+ if (list.count() == 1) {
+ d->heading = list[0];
+ d->group = "General";
+ } else {
+ d->heading = list[0];
+ d->group = list[1];
+
+ // remove the group from the list
+ list.remove(list.at(1));
+ // remove the heading from the list
+ list.remove(list.at(0));
+
+ realkey = list.join("/");
+ }
+
+ } else
+ realkey = grp_key;
+
+ TQStringList ret;
+ if ( subkeycount == 1 ) {
+ TQMap<TQString,TQSettingsHeading>::Iterator it = d->headings.begin();
+ while ( it != d->headings.end() ) {
+ if ( it.key() != "General" && ! ret.tqcontains( it.key() ) )
+ ret << it.key();
+ ++it;
+ }
+
+ return ret;
+ }
+
+ TQSettingsGroup grp = d->readGroup();
+ TQSettingsGroup::Iterator it = grp.begin();
+ TQString itkey;
+ while (it != grp.end()) {
+ itkey = it.key();
+ ++it;
+
+ if ( realkey.length() > 0 ) {
+ if ( itkey.left( realkey.length() ) != realkey
+ || itkey.length()+1 < realkey.length()
+ || itkey[(int)realkey.length()] != '/')
+ continue;
+ else
+ itkey.remove( 0, realkey.length() + 1 );
+ }
+
+ int slash = itkey.tqfind( '/' );
+ if ( slash == -1 )
+ continue;
+ itkey.truncate( slash );
+
+ if ( ! ret.tqcontains( itkey ) )
+ ret << itkey;
+ }
+
+ return ret;
+}
+
+
+/*!
+ \internal
+
+ This function returns the time of last modification for \a key.
+*/
+TQDateTime TQSettings::lastModificationTime( const TQString &key )
+{
+ TQString grp_key( groupKey( group(), key ) );
+ if ( !qt_verify_key( grp_key ) ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQSettings::lastModificationTime: Invalid key '%s'", grp_key.isNull() ? "(null)" : grp_key.latin1() );
+#endif
+ return TQDateTime();
+ }
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ if ( d->sysd )
+ return TQDateTime();
+#endif
+
+ if (grp_key[0] == '/') {
+ // parse our key
+ TQStringList list(TQStringList::split('/', grp_key));
+
+ if (list.count() < 2) {
+#ifdef TQT_CHECK_STATE
+ qWarning("TQSettings::lastModificationTime: Invalid key '%s'", grp_key.latin1());
+#endif // TQT_CHECK_STATE
+
+ return TQDateTime();
+ }
+
+ if (list.count() == 2) {
+ d->heading = list[0];
+ d->group = "General";
+ } else {
+ d->heading = list[0];
+ d->group = list[1];
+ }
+ }
+
+ return d->modificationTime();
+}
+
+
+/*!
+ \overload
+ \obsolete
+
+ Writes the string list entry \a value into key \a key. The \a key
+ is created if it doesn't exist. Any previous value is overwritten
+ by \a value. The list is stored as a sequence of strings separated
+ by \a separator (using TQStringList::join()), so none of the
+ strings in the list should contain the separator. If the list is
+ empty or null the key's value will be an empty string.
+
+ \warning The list should not contain empty or null strings, as
+ readListEntry() will use TQStringList::split() to recreate the
+ list. As the documentation states, TQStringList::split() will omit
+ empty strings from the list. Because of this, it is impossible to
+ retrieve identical list data that is stored with this function.
+ We recommend using the writeEntry() and readListEntry() overloads
+ that do not take a \a separator argument.
+
+
+ If an error occurs the settings are left unchanged and FALSE is
+ returned; otherwise returns TRUE.
+
+ \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry(), TQStringList::join()
+*/
+bool TQSettings::writeEntry(const TQString &key, const TQStringList &value,
+ const TQChar &separator)
+{
+ TQString s(value.join(separator));
+ return writeEntry(key, s);
+}
+
+/*!
+ \overload
+
+ Writes the string list entry \a value into key \a key. The \a key
+ is created if it doesn't exist. Any previous value is overwritten
+ by \a value.
+
+ If an error occurs the settings are left unchanged and FALSE is
+ returned; otherwise returns TRUE.
+
+ \sa readListEntry(), readNumEntry(), readDoubleEntry(), readBoolEntry(), removeEntry()
+*/
+bool TQSettings::writeEntry(const TQString &key, const TQStringList &value)
+{
+ TQString s;
+ for (TQStringList::ConstIterator it=value.begin(); it!=value.end(); ++it) {
+ TQString el = *it;
+ if ( el.isNull() ) {
+ el = "^0";
+ } else {
+ el.tqreplace("^", "^^");
+ }
+ s+=el;
+ s+="^e"; // end of element
+ }
+ return writeEntry(key, s);
+}
+
+
+/*!
+ \overload TQStringList TQSettings::readListEntry(const TQString &key, const TQChar &separator, bool *ok ) const
+ \obsolete
+
+ Reads the entry specified by \a key as a string. The \a separator
+ is used to create a TQStringList by calling TQStringList::split(\a
+ separator, entry). If \a ok is not 0: \a *ok is set to TRUE
+ if the key was read, otherwise \a *ok is set to FALSE.
+
+ \warning As the documentation states, TQStringList::split() will
+ omit empty strings from the list. Because of this, it is
+ impossible to retrieve identical list data with this function. We
+ recommend using the readListEntry() and writeEntry() overloads
+ that do not take a \a separator argument.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = mySettings.readListEntry( "size", " " );
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry(), TQStringList::split()
+*/
+
+/*!
+ \internal
+*/
+TQStringList TQSettings::readListEntry(const TQString &key, const TQChar &separator, bool *ok )
+{
+ TQString value = readEntry( key, TQString::null, ok );
+ if ( ok && !*ok )
+ return TQStringList();
+
+ return TQStringList::split(separator, value);
+}
+
+/*!
+ \fn TQStringList TQSettings::readListEntry(const TQString &key, bool *ok ) const
+ Reads the entry specified by \a key as a string. If \a ok is not
+ 0, \a *ok is set to TRUE if the key was read, otherwise \a *ok is
+ set to FALSE.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = mySettings.readListEntry( "recentfiles" );
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa readEntry(), readDoubleEntry(), readBoolEntry(), writeEntry(), removeEntry(), TQStringList::split()
+*/
+
+/*!
+ \internal
+*/
+TQStringList TQSettings::readListEntry(const TQString &key, bool *ok )
+{
+ TQString value = readEntry( key, TQString::null, ok );
+ if ( ok && !*ok )
+ return TQStringList();
+ TQStringList l;
+ TQString s;
+ bool esc=FALSE;
+ for (int i=0; i<(int)value.length(); i++) {
+ if ( esc ) {
+ if ( value[i] == 'e' ) { // end-of-string
+ l.append(s);
+ s="";
+ } else if ( value[i] == '0' ) { // null string
+ s=TQString::null;
+ } else {
+ s.append(value[i]);
+ }
+ esc=FALSE;
+ } else if ( value[i] == '^' ) {
+ esc = TRUE;
+ } else {
+ s.append(value[i]);
+ if ( i == (int)value.length()-1 )
+ l.append(s);
+ }
+ }
+ return l;
+}
+
+#ifdef TQ_OS_MAC
+void qt_setSettingsBasePath(const TQString &); //qsettings_mac.cpp
+#endif
+
+/*!
+ Insert platform-dependent paths from platform-independent information.
+
+ The \a domain should be an Internet domain name
+ controlled by the producer of the software, eg. Trolltech products
+ use "trolltech.com".
+
+ The \a product should be the official name of the product.
+
+ The \a scope should be
+ TQSettings::User for user-specific settings, or
+ TQSettings::Global for system-wide settings (generally
+ these will be read-only to many users).
+
+ Not all information is relevant on all systems.
+*/
+
+void TQSettings::setPath( const TQString &domain, const TQString &product, Scope scope )
+{
+// On Windows, any trailing ".com(\..*)" is stripped from the domain. The
+// Global scope corresponds to HKEY_LOCAL_MACHINE, and User corresponds to
+// HKEY_CURRENT_USER. Note that on some installations, not all users can
+// write to the Global scope. On UNIX, any trailing ".com(\..*)" is stripped
+// from the domain. The Global scope corresponds to "/opt" (this would be
+// configurable at library build time - eg. to "/usr/local" or "/usr"),
+// while the User scope corresponds to $HOME/.*rc.
+// Note that on most installations, not all users can write to the System
+// scope.
+//
+// On MacOS X, if there is no "." in domain, append ".com", then reverse the
+// order of the elements (Mac OS uses "com.apple.tqfinder" as domain+product).
+// The Global scope corresponds to /Library/Preferences/*.plist, while the
+// User scope corresponds to ~/Library/Preferences/*.plist.
+// Note that on most installations, not all users can write to the System
+// scope.
+ d->globalScope = scope == Global;
+
+ TQString actualSearchPath;
+ int lastDot = domain.tqfindRev( '.' );
+
+#if defined(TQ_WS_WIN)
+ actualSearchPath = "/" + domain.mid( 0, lastDot ) + "/" + product;
+ insertSearchPath( Windows, actualSearchPath );
+#elif !defined(TQWS) && defined(TQ_OS_MAC)
+ if(lastDot != -1) {
+ TQString topLevelDomain = domain.right( domain.length() - lastDot - 1 ) + ".";
+ if ( !topLevelDomain.isEmpty() )
+ qt_setSettingsBasePath( topLevelDomain );
+ }
+ actualSearchPath = "/" + domain.left( lastDot ) + "." + product;
+ insertSearchPath( Mac, actualSearchPath );
+#else
+ if (scope == User)
+ actualSearchPath = TQDir::homeDirPath() + "/.";
+ else
+ actualSearchPath = TQString(qInstallPathSysconf()) + "/";
+ actualSearchPath += domain.mid( 0, lastDot ) + "/" + product;
+ insertSearchPath( Unix, actualSearchPath );
+#endif
+}
+
+/*!
+ Appends \a group to the current key prefix.
+
+ \code
+ TQSettings settings;
+ settings.beginGroup( "/MainWindow" );
+ // read values
+ settings.endGroup();
+ \endcode
+*/
+void TQSettings::beginGroup( const TQString &group )
+{
+ d->groupStack.push( group );
+ d->groupDirty = TRUE;
+}
+
+/*!
+ Undo previous calls to beginGroup(). Note that a single beginGroup("a/b/c") is undone
+ by a single call to endGroup().
+
+ \code
+ TQSettings settings;
+ settings.beginGroup( "/MainWindow/Geometry" );
+ // read values
+ settings.endGroup();
+ \endcode
+*/
+void TQSettings::endGroup()
+{
+ d->groupStack.pop();
+ d->groupDirty = TRUE;
+}
+
+/*!
+ Set the current key prefix to the empty string.
+*/
+void TQSettings::resetGroup()
+{
+ d->groupStack.clear();
+ d->groupDirty = FALSE;
+ d->groupPrefix = TQString::null;
+}
+
+/*!
+ Returns the current key prefix, or a null string if there is no key prefix set.
+
+ \sa beginGroup();
+*/
+TQString TQSettings::group() const
+{
+ if ( d->groupDirty ) {
+ d->groupDirty = FALSE;
+ d->groupPrefix = TQString::null;
+
+ TQValueStack<TQString>::Iterator it = d->groupStack.begin();
+ while ( it != d->groupStack.end() ) {
+ TQString group = *it;
+ ++it;
+ if ( group[0] != '/' )
+ group.prepend( "/" );
+ d->groupPrefix += group;
+ }
+ }
+ return d->groupPrefix;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqsettings.h b/tqtinterface/qt4/src/tools/tqsettings.h
new file mode 100644
index 0000000..e7eb2a3
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqsettings.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Definition of TQSettings class
+**
+** Created : 000626
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSETTINGS_H
+#define TQSETTINGS_H
+
+#ifndef TQT_H
+#include "tqdatetime.h"
+#include "tqstringlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SETTINGS
+
+class TQSettingsPrivate;
+
+
+class TQ_EXPORT TQSettings
+{
+public:
+ enum Format {
+ Native = 0,
+ Ini
+ };
+ enum System {
+ Unix = 0,
+ Windows,
+ Mac
+ };
+ enum Scope {
+ User,
+ Global
+ };
+
+ TQSettings();
+ TQSettings( Format format );
+
+ ~TQSettings();
+
+#if !defined(TQ_NO_BOOL_TYPE)
+ bool writeEntry( const TQString &, bool );
+#endif
+ bool writeEntry( const TQString &, double );
+ bool writeEntry( const TQString &, int );
+ bool writeEntry( const TQString &, const char * );
+ bool writeEntry( const TQString &, const TQString & );
+ bool writeEntry( const TQString &, const TQStringList & );
+ bool writeEntry( const TQString &, const TQStringList &, const TQChar& sep );
+
+ TQStringList entryList(const TQString &) const;
+ TQStringList subkeyList(const TQString &) const;
+
+ //### remove non const versions in 4.0
+ TQStringList readListEntry( const TQString &, bool * = 0 );
+ TQStringList readListEntry( const TQString &, const TQChar& sep, bool * = 0 );
+ TQString readEntry( const TQString &, const TQString &def = TQString::null, bool * = 0 );
+ int readNumEntry( const TQString &, int def = 0, bool * = 0 );
+ double readDoubleEntry( const TQString &, double def = 0, bool * = 0 );
+ bool readBoolEntry( const TQString &, bool def = FALSE, bool * = 0 );
+
+ //### make those non-inlined in 4.0
+ TQStringList readListEntry( const TQString &key, bool *ok = 0 ) const
+ {
+ TQSettings *that = (TQSettings*)this;
+ return that->readListEntry( key, ok );
+ }
+ TQStringList readListEntry( const TQString &key, const TQChar& sep, bool *ok = 0 ) const
+ {
+ TQSettings *that = (TQSettings*)this;
+ return that->readListEntry( key, sep, ok );
+ }
+ TQString readEntry( const TQString &key, const TQString &def = TQString::null,
+ bool *ok = 0 ) const
+ {
+ TQSettings *that = (TQSettings*)this;
+ return that->readEntry( key, def, ok );
+ }
+ int readNumEntry( const TQString &key, int def = 0, bool *ok = 0 ) const
+ {
+ TQSettings *that = (TQSettings*)this;
+ return that->readNumEntry( key, def, ok );
+ }
+
+ double readDoubleEntry( const TQString &key, double def = 0, bool *ok = 0 ) const
+ {
+ TQSettings *that = (TQSettings*)this;
+ return that->readDoubleEntry( key, def, ok );
+ }
+ bool readBoolEntry( const TQString &key, bool def = FALSE, bool *ok = 0 ) const
+ {
+ TQSettings *that = (TQSettings*)this;
+ return that->readBoolEntry( key, def, ok );
+ }
+
+ bool removeEntry( const TQString & );
+
+ void insertSearchPath( System, const TQString & );
+ void removeSearchPath( System, const TQString & );
+
+ void setPath( const TQString &domain, const TQString &product, Scope = Global );
+
+ void beginGroup( const TQString &group );
+ void endGroup();
+ void resetGroup();
+ TQString group() const;
+
+ bool sync();
+
+private:
+ TQSettingsPrivate *d;
+
+#if defined(TQ_DISABLE_COPY)
+ TQSettings(const TQSettings &);
+ TQSettings &operator=(const TQSettings &);
+#endif
+
+ TQDateTime lastModificationTime( const TQString & );
+
+ friend class TQApplication;
+};
+
+#endif // TQT_NO_SETTINGS
+#endif // TQSETTINGS_H
diff --git a/tqtinterface/qt4/src/tools/tqsettings_p.h b/tqtinterface/qt4/src/tools/tqsettings_p.h
new file mode 100644
index 0000000..31283a1
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqsettings_p.h
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Definition of TQSettings related classes
+**
+** Created : 990124
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSETTINGS_P_H
+#define TQSETTINGS_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of TQSettings. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqstringlist.h"
+#include "tqmap.h"
+#include "tqvaluestack.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SETTINGS
+class TQSettingsSysPrivate;
+
+// TQSettingsGroup is a map of key/value pairs
+class TQSettingsGroup : public TQMap<TQString,TQString>
+{
+public:
+ TQSettingsGroup();
+
+ bool modified;
+};
+
+// TQSettingsHeading is a map of heading/group pairs
+class TQSettingsHeading : public TQMap<TQString,TQSettingsGroup>
+{
+public:
+ TQSettingsHeading::Iterator git;
+ void read(const TQString &);
+ void parseLine(TQTextStream &);
+};
+
+
+class TQSettingsPrivate
+{
+public:
+ TQSettingsPrivate( TQSettings::Format format );
+ ~TQSettingsPrivate();
+
+ TQSettingsGroup readGroup();
+ void removeGroup(const TQString &);
+ void writeGroup(const TQString &, const TQString &);
+ TQDateTime modificationTime();
+
+ TQStringList searchPaths;
+ TQMap<TQString,TQSettingsHeading> headings;
+ TQString group;
+ TQString heading;
+
+ /*### static data brings threading trouble
+ static TQString *defProduct;
+ static TQString *defDomain;
+ */
+ TQValueStack<TQString> groupStack;
+ TQString groupPrefix;
+
+ bool groupDirty :1;
+ bool modified :1;
+ bool globalScope :1;
+
+#if !defined(TQWS) && (defined(TQ_WS_WIN) || defined(TQ_OS_MAC))
+ // system dependent implementations to use the
+ // system specific setting database (ie. registry on Windows)
+
+ TQSettingsSysPrivate *sysd;
+ void sysInit();
+ void sysClear();
+
+#if !defined(TQ_NO_BOOL_TYPE)
+ bool sysWriteEntry( const TQString &, bool );
+#endif
+ bool sysWriteEntry( const TQString &, double );
+ bool sysWriteEntry( const TQString &, int );
+ bool sysWriteEntry( const TQString &, const TQString & );
+ bool sysWriteEntry( const TQString &, const TQStringList & );
+ bool sysWriteEntry( const TQString &, const TQStringList &, const TQChar& sep );
+
+ TQStringList sysEntryList(const TQString &) const;
+ TQStringList sysSubkeyList(const TQString &) const;
+
+ TQStringList sysReadListEntry( const TQString &, bool * = 0 ) const;
+ TQStringList sysReadListEntry( const TQString &, const TQChar& sep, bool * = 0 ) const;
+ TQString sysReadEntry( const TQString &, const TQString &def = TQString::null, bool * = 0 ) const;
+ int sysReadNumEntry( const TQString &, int def = 0, bool * = 0 ) const;
+ double sysReadDoubleEntry( const TQString &, double def = 0, bool * = 0 ) const;
+ bool sysReadBoolEntry( const TQString &, bool def = 0, bool * = 0 ) const;
+
+ bool sysRemoveEntry( const TQString & );
+
+ bool sysSync();
+
+ void sysInsertSearchPath( TQSettings::System, const TQString & );
+ void sysRemoveSearchPath( TQSettings::System, const TQString & );
+#endif
+
+};
+#endif //TQT_NO_SETTINGS
+#endif // TQSETTINGS_P_H
diff --git a/tqtinterface/qt4/src/tools/tqshared.h b/tqtinterface/qt4/src/tools/tqshared.h
new file mode 100644
index 0000000..918af3c
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqshared.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Definition of TQShared struct
+**
+** Created : 940112
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSHARED_H
+#define TQSHARED_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+
+struct TQ_EXPORT TQShared
+{
+ TQShared() : count( 1 ) { }
+ void ref() { count++; }
+ bool deref() { return !--count; }
+ uint count;
+};
+
+
+#endif // TQSHARED_H
diff --git a/tqtinterface/qt4/src/tools/tqsortedlist.h b/tqtinterface/qt4/src/tools/tqsortedlist.h
new file mode 100644
index 0000000..28799f1
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqsortedlist.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Definition of TQSortedList template/macro class
+**
+** Created : 920701
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSORTEDLIST_H
+#define TQSORTEDLIST_H
+
+#ifndef TQT_H
+#include "tqptrlist.h"
+#endif // TQT_H
+
+
+template<class type>
+class TQSortedList : public TQPtrList<type>
+{
+public:
+ TQSortedList() {}
+ TQSortedList( const TQSortedList<type> &l ) : TQPtrList<type>(l) {}
+ ~TQSortedList() { this->clear(); }
+ TQSortedList<type> &operator=(const TQSortedList<type> &l)
+ { return (TQSortedList<type>&)TQPtrList<type>::operator=(l); }
+
+ virtual int compareItems( TQPtrCollection::Item s1, TQPtrCollection::Item s2 )
+ { if ( *((type*)s1) == *((type*)s2) ) return 0; return ( *((type*)s1) < *((type*)s2) ? -1 : 1 ); }
+};
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqstring.cpp b/tqtinterface/qt4/src/tools/tqstring.cpp
new file mode 100644
index 0000000..5c731b3
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqstring.cpp
@@ -0,0 +1,8350 @@
+/****************************************************************************
+**
+** Implementation of the TQString class and related Unicode functions
+**
+** Created : 920722
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// Don't define it while compiling this module, or USERS of TQt will
+// not be able to link.
+#ifdef TQT_NO_CAST_ASCII
+#undef TQT_NO_CAST_ASCII
+#endif
+
+#include "tqstring.h"
+#include "tqregexp.h"
+#include "tqdatastream.h"
+#ifndef TQT_NO_TEXTCODEC
+#include "tqtextcodec.h"
+#endif
+#include "tqlocale.h"
+#include "tqlocale_p.h"
+
+#include "tqunicodetables_p.h"
+#include <limits.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifndef TQ_OS_TEMP
+#include <locale.h>
+#endif
+#if defined(TQ_WS_WIN)
+#include "tqt_windows.h"
+#endif
+#if !defined( TQT_NO_COMPONENT ) && !defined( TQT_LITE_COMPONENT )
+#include "tqcleanuphandler.h"
+#endif
+
+#ifndef LLONG_MAX
+#define LLONG_MAX TQ_INT64_C(9223372036854775807)
+#endif
+#ifndef LLONG_MIN
+#define LLONG_MIN (-LLONG_MAX - TQ_INT64_C(1))
+#endif
+#ifndef ULLONG_MAX
+#define ULLONG_MAX TQ_UINT64_C(18446744073709551615)
+#endif
+
+#ifdef USE_QT4
+
+// #include <Qt/qhash.h>
+
+// static QHash<void *, QByteArray> *asciiCache = 0;
+
+TQT_STATIC_CONST_IMPL TQChar TQChar::null;
+TQT_STATIC_CONST_IMPL TQChar TQChar::tqreplacement((ushort)0xfffd);
+TQT_STATIC_CONST_IMPL TQChar TQChar::byteOrderMark((ushort)0xfeff);
+TQT_STATIC_CONST_IMPL TQChar TQChar::byteOrderSwapped((ushort)0xfffe);
+TQT_STATIC_CONST_IMPL TQChar TQChar::nbsp((ushort)0x00a0);
+
+/*!
+ \internal
+*/
+const char *TQString::ascii_helper() const
+{
+ // tqstring_ascii_ba must be a persistent member variable within the class instance, but NOT static. A static variable is global for ALL class instances (very bad!)
+ // Also, it MUST be declared mutable, otherwise a raft of "discards qualifiers" errors will pop up.
+
+// tqstring_ascii_ba = toAscii();
+ // Get a real, TRUE copy of the data, not some stupid shared copy that will randomly invalidate my pointer at an unknown future date/time
+ QByteArray tempba = toAscii();
+ tqstring_ascii_ba.resize(tempba.size());
+ memcpy(tqstring_ascii_ba.data(), tempba.data(), tempba.size());
+ return tqstring_ascii_ba.data();
+}
+
+/*!
+ \internal
+*/
+const char *TQString::latin1_helper() const
+{
+ // tqstring_latin1_ba must be a persistent member variable within the class instance, but NOT static. A static variable is global for ALL class instances (very bad!)
+ // Also, it MUST be declared mutable, otherwise a raft of "discards qualifiers" errors will pop up.
+
+ //tqstring_latin1_ba = toLatin1();
+ // Get a real, TRUE copy of the data, not some stupid shared copy that will randomly invalidate my pointer at an unknown future date/time
+ QByteArray tempba = toLatin1();
+ tqstring_latin1_ba.resize(tempba.size());
+ memcpy(tqstring_latin1_ba.data(), tempba.data(), tempba.size());
+ return tqstring_latin1_ba.data();
+}
+
+/*!
+ This utility function converts \a l 16-bit characters from \a uc
+ to ASCII, returning a '\0'-terminated string.
+
+ The caller is responsible for deleting the resultant string with
+ delete[].
+*/
+char* TQString::tqunicodeToLatin1(const TQChar *uc, uint l)
+{
+ if (!uc) {
+ return 0;
+ }
+ char *a = new char[l+1];
+ char *result = a;
+ while (l--) {
+ *a++ = (uc->tqunicode() > 0xff) ? '?' : (char)uc->tqunicode();
+ uc++;
+ }
+ *a = '\0';
+ return result;
+}
+
+#if defined(Q_CC_MSVC) && _MSC_VER <= 1300
+const TQString::Null TQString::null;
+#else
+const TQString::Null TQString::null = { };
+#endif
+
+/*****************************************************************************
+ TQString stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQString
+
+ Writes the string \a str to the stream \a s.
+
+ See also \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQString &str )
+{
+ if ( s.version() == 1 ) {
+ TQCString l( str.latin1() );
+ s << l;
+ }
+ else {
+ int byteOrder = s.byteOrder();
+ const TQChar* ub = str.tqunicode();
+ if ( ub || s.version() < 3 ) {
+ static const uint auto_size = 1024;
+ char t[auto_size];
+ char *b;
+ if ( str.length()*sizeof(TQChar) > auto_size ) {
+ b = new char[str.length()*sizeof(TQChar)];
+ } else {
+ b = t;
+ }
+ int l = str.length();
+ char *c=b;
+ while ( l-- ) {
+ if ( byteOrder == TQDataStream::BigEndian ) {
+ *c++ = (char)ub->row();
+ *c++ = (char)ub->cell();
+ } else {
+ *c++ = (char)ub->cell();
+ *c++ = (char)ub->row();
+ }
+ ub++;
+ }
+ s.writeBytes( b, sizeof(TQChar)*str.length() );
+ if ( str.length()*sizeof(TQChar) > auto_size )
+ delete [] b;
+ } else {
+ // write null marker
+ s << (TQ_UINT32)0xffffffff;
+ }
+ }
+ return s;
+}
+
+/*!
+ \relates TQString
+
+ Reads a string from the stream \a s into string \a str.
+
+ See also \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQString &str )
+{
+#ifdef TQT_TQSTRING_UCS_4
+#if defined(TQ_CC_GNU)
+#warning "operator>> not working properly"
+#endif
+#endif
+ if ( s.version() == 1 ) {
+ TQCString l;
+ s >> l;
+ str = TQString( l );
+ }
+ else {
+ TQ_UINT32 bytes = 0;
+ s >> bytes; // read size of string
+ if ( bytes == 0xffffffff ) { // null string
+ str = TQString::null;
+ } else if ( bytes > 0 ) { // not empty
+ int byteOrder = s.byteOrder();
+ str.setLength( bytes/2 );
+// TQChar* ch = str.d->tqunicode;
+ TQChar* ch = static_cast<TQChar*>(str.data());
+ static const uint auto_size = 1024;
+ char t[auto_size];
+ char *b;
+ if ( bytes > auto_size ) {
+ b = new char[bytes];
+ } else {
+ b = t;
+ }
+ s.readRawBytes( b, bytes );
+ int bt = bytes/2;
+ char *oldb = b;
+ while ( bt-- ) {
+ if ( byteOrder == TQDataStream::BigEndian )
+ *ch++ = (ushort) (((ushort)b[0])<<8) | (uchar)b[1];
+ else
+ *ch++ = (ushort) (((ushort)b[1])<<8) | (uchar)b[0];
+ b += 2;
+ }
+ if ( bytes > auto_size )
+ delete [] oldb;
+ } else {
+ str = "";
+ }
+ }
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+#ifndef TQT_NO_CAST_ASCII
+TQString &TQString::operatorPlusEqHelper( const char *s, uint len2 )
+{
+// if ( s ) {
+// #ifndef TQT_NO_TEXTCODEC
+// if ( TQTextCodec::codecForCStrings() )
+// return operator+=( fromAscii( s, len2 ) );
+// #endif
+//
+// uint len1 = length();
+// if ( len2 == UINT_MAX )
+// len2 = int(strlen( s ));
+// if ( len2 ) {
+// grow( len1 + len2 );
+// TQChar* uc = d->tqunicode + len1;
+// while ( len2-- )
+// *uc++ = *s++;
+// } else if ( isNull() ) { // ## just for 1.x compat:
+// *this = tqfromLatin1( "" );
+// }
+// }
+// return *this;
+
+ this->append(s);
+ return *this;
+}
+#endif
+
+/*!
+ \class TQCharRef tqstring.h
+ \reentrant
+ \brief The TQCharRef class is a helper class for TQString.
+
+ \ingroup text
+
+ When you get an object of type TQCharRef, if you can assign to it,
+ the assignment will apply to the character in the string from
+ which you got the reference. That is its whole purpose in life.
+ The TQCharRef becomes invalid once modifications are made to the
+ string: if you want to keep the character, copy it into a TQChar.
+
+ Most of the TQChar member functions also exist in TQCharRef.
+ However, they are not explicitly documented here.
+
+ \sa TQString::operator[]() TQString::at() TQChar
+*/
+
+/*! \fn TQString& TQString::append( const char *str )
+ \overload
+
+ Appends \a str to the string and returns a reference to the result.
+
+ Equivalent to operator+=().
+*/
+
+/*!
+ Appends \a str to the string and returns a reference to the string.
+*/
+TQString& TQString::operator+=( const TQString &str )
+{
+// uint len1 = length();
+// uint len2 = str.length();
+// if ( len2 ) {
+// if ( isEmpty() ) {
+// operator=( str );
+// } else {
+// grow( len1+len2 );
+// memcpy( d->tqunicode+len1, str.tqunicode(), sizeof(TQChar)*len2 );
+// }
+// } else if ( isNull() && !str.isNull() ) { // ## just for 1.x compat:
+// *this = tqfromLatin1( "" );
+// }
+// return *this;
+
+ this->append(str);
+ return *this;
+}
+
+/*!
+ \overload
+
+ Appends \a str to the string and returns a reference to the string.
+*/
+#ifndef TQT_NO_CAST_ASCII
+TQString& TQString::operator+=( const char *str )
+{
+ // ### TQt 4: make this function inline
+ return operatorPlusEqHelper( str );
+}
+#endif
+
+/*! \overload
+
+ Appends \a c to the string and returns a reference to the string.
+*/
+
+TQString &TQString::operator+=( TQChar c )
+{
+// grow( length()+1 );
+// d->tqunicode[length()-1] = c;
+// return *this;
+
+ this->append(c);
+ return *this;
+}
+
+/*!
+ \overload
+
+ Appends \a c to the string and returns a reference to the string.
+*/
+
+TQString &TQString::operator+=( char c )
+{
+// #ifndef TQT_NO_TEXTCODEC
+// if ( TQTextCodec::codecForCStrings() )
+// return operator+=( fromAscii( &c, 1 ) );
+// #endif
+// grow( length()+1 );
+// d->tqunicode[length()-1] = c;
+// return *this;
+
+ this->append(c);
+ return *this;
+}
+
+TQString &TQString::operator+=(const QStringRef &s) {
+ //return convertFromQString();
+ return (*static_cast<TQString*>(&append(s)));
+}
+
+TQString &TQString::operator+=(const QLatin1String &s) {
+ return (*static_cast<TQString*>(&append(s)));
+}
+
+TQString &TQString::operator+=(QChar c) {
+ return (*static_cast<TQString*>(&append(c)));
+}
+
+/*!
+ \fn TQCharRef TQString::at( uint i )
+
+ \overload
+
+ The function returns a reference to the character at index \a i.
+ The resulting reference can then be assigned to, or used
+ immediately, but it will become invalid once further modifications
+ are made to the original string.
+
+ If \a i is beyond the length of the string then the string is
+ expanded with TQChar::null.
+*/
+
+/*
+ Internal chunk of code to handle the
+ uncommon cases of at() above.
+*/
+void TQString::subat( uint i )
+{
+ uint olen = length();
+ if ( i >= olen ) {
+ setLength( i+1 ); // i is index; i+1 is needed length
+ for ( uint j=olen; j<=i; j++ )
+ tqat(j) = TQChar::null;
+ } else {
+ // Just be sure to detach
+// real_detach();
+ }
+}
+
+/*!
+ \fn const TQChar* TQString::tqunicode() const
+
+ Returns the Unicode representation of the string. The result
+ remains valid until the string is modified.
+*/
+
+/*!
+ Returns the string encoded in a locale-specific format. On X11,
+ this is the TQTextCodec::codecForLocale(). On Windows, it is a
+ system-defined encoding. On Mac OS X, this always uses UTF-8 as
+ the encoding.
+
+ See TQTextCodec for more diverse coding/decoding of Unicode
+ strings.
+
+ \sa fromLocal8Bit(), ascii(), latin1(), utf8()
+*/
+
+TQCString TQString::local8Bit() const
+{
+#ifdef TQT_NO_TEXTCODEC
+ return latin1();
+#else
+#ifdef TQ_WS_X11
+ TQTextCodec* codec = TQTextCodec::codecForLocale();
+ return codec
+ ? codec->fromUnicode(*this)
+ : TQCString(latin1());
+#endif
+#if defined( TQ_WS_MACX )
+ return utf8();
+#endif
+#if defined( TQ_WS_MAC9 )
+ return TQCString(latin1()); //I'm evil..
+#endif
+#ifdef TQ_WS_WIN
+ return isNull() ? TQCString("") : qt_winTQString2MB( *this );
+#endif
+#ifdef TQ_WS_TQWS
+ return utf8(); // ### if there is any 8 bit format supported?
+#endif
+#endif
+}
+
+// TQCString TQString::local8Bit() const
+// {
+// return toLocal8Bit();
+// }
+
+/*!
+ Returns the Unicode string decoded from the first \a len
+ bytes of \a utf8, ignoring the rest of \a utf8. If \a len is
+ -1 then the length of \a utf8 is used. If \a len is bigger than
+ the length of \a utf8 then it will use the length of \a utf8.
+
+ \code
+ TQString str = TQString::fromUtf8( "123456789", 5 );
+ // str == "12345"
+ \endcode
+
+ See TQTextCodec for more diverse coding/decoding of Unicode strings.
+*/
+TQString TQString::fromUtf8( const char* utf8, int len )
+{
+ if ( !utf8 )
+ return TQString();
+ TQString result = QString::fromUtf8(utf8, len);
+ int slen = int(strlen(utf8));
+ if (result.length() > slen) {
+ result.truncate(slen);
+ }
+ return result;
+}
+
+/*!
+ Returns the Unicode string decoded from the first \a len
+ bytes of \a chars, ignoring the rest of \a chars. If \a len
+ is -1 then the length of \a chars is used. If \a len is bigger
+ than the length of \a chars then it will use the length of \a
+ chars.
+
+ \sa fromAscii()
+*/
+TQString TQString::fromLatin1( const char* chars, int len )
+{
+ if ( !chars )
+ return TQString();
+ TQString result = QString::fromLatin1(chars, len);
+ int slen = int(strlen(chars));
+ if (result.length() > slen) {
+ result.truncate(slen);
+ }
+ return result;
+}
+
+/*!
+ Returns the string encoded in UTF-8 format.
+
+ See TQTextCodec for more diverse coding/decoding of Unicode strings.
+
+ \sa fromUtf8(), ascii(), latin1(), local8Bit()
+*/
+TQCString TQString::utf8() const
+{
+ int l = length();
+ int rlen = l*3+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+ const TQChar *ch = static_cast<const TQChar*>(data());
+ for (int i=0; i < l; i++) {
+ uint u = ch->tqunicode();
+ if ( u < 0x80 ) {
+ *cursor++ = (uchar)u;
+ } else {
+ if ( u < 0x0800 ) {
+ *cursor++ = 0xc0 | ((uchar) (u >> 6));
+ } else {
+ if (u >= 0xd800 && u < 0xdc00 && i < l-1) {
+ unsigned short low = ch[1].tqunicode();
+ if (low >= 0xdc00 && low < 0xe000) {
+ ++ch;
+ ++i;
+ u = (u - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ }
+ }
+ if (u > 0xffff) {
+ // if people are working in utf8, but strings are encoded in eg. latin1, the resulting
+ // name might be invalid utf8. This and the corresponding code in fromUtf8 takes care
+ // we can handle this without loosing information. This can happen with latin filenames
+ // and a utf8 locale under Unix.
+ if (u > 0x10fe00 && u < 0x10ff00) {
+ *cursor++ = (u - 0x10fe00);
+ ++ch;
+ continue;
+ } else {
+ *cursor++ = 0xf0 | ((uchar) (u >> 18));
+ *cursor++ = 0x80 | ( ((uchar) (u >> 12)) & 0x3f);
+ }
+ } else {
+ *cursor++ = 0xe0 | ((uchar) (u >> 12));
+ }
+ *cursor++ = 0x80 | ( ((uchar) (u >> 6)) & 0x3f);
+ }
+ *cursor++ = 0x80 | ((uchar) (u&0x3f));
+ }
+ ++ch;
+ }
+ rstr.truncate( cursor - (uchar*)rstr.data() );
+ return rstr;
+}
+
+static bool tqIsUpper(char c)
+{
+ return c >= 'A' && c <= 'Z';
+}
+
+static bool tqIsDigit(char c)
+{
+ return c >= '0' && c <= '9';
+}
+
+static char tqToLower(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return c - 'A' + 'a';
+ else
+ return c;
+}
+
+struct ArgEscapeData
+{
+ uint min_escape; // lowest escape sequence number
+ uint occurrences; // number of occurences of the lowest escape
+ // sequence number
+ uint locale_occurrences; // number of occurences of the lowest escape
+ // sequence number which contain 'L'
+ uint escape_len; // total length of escape sequences which will
+ // be tqreplaced
+};
+
+static ArgEscapeData tqfindArgEscapes(const TQString &s)
+{
+ const TQChar *uc_begin = s.tqunicode();
+ const TQChar *uc_end = uc_begin + s.length();
+
+ ArgEscapeData d;
+
+ d.min_escape = 10;
+ d.occurrences = 0;
+ d.escape_len = 0;
+ d.locale_occurrences = 0;
+
+ const TQChar *c = uc_begin;
+ while (c != uc_end) {
+ while (c != uc_end && c->tqunicode() != '%')
+ ++c;
+
+ if (c == uc_end || ++c == uc_end)
+ break;
+
+ bool locale_arg = FALSE;
+ if (c->tqunicode() == 'L') {
+ locale_arg = TRUE;
+ if (++c == uc_end)
+ break;
+ }
+
+ if (c->tqunicode() < '0' || c->tqunicode() > '9')
+ continue;
+
+ uint escape = c->tqunicode() - '0';
+ ++c;
+
+ if (escape > d.min_escape)
+ continue;
+
+ if (escape < d.min_escape) {
+ d.min_escape = escape;
+ d.occurrences = 0;
+ d.escape_len = 0;
+ d.locale_occurrences = 0;
+ }
+
+#if TQT_VERSION < 0x040000
+ // ### remove preprocessor in TQt 4.0
+ /* Since in TQt < 4.0 only the first instance is tqreplaced,
+ escape_len should hold the length of only the first escape
+ sequence */
+ if (d.occurrences == 0)
+#endif
+ {
+ ++d.occurrences;
+ if (locale_arg) {
+ ++d.locale_occurrences;
+ d.escape_len += 3;
+ }
+ else
+ d.escape_len += 2;
+ }
+ }
+
+ return d;
+}
+
+static TQString tqreplaceArgEscapes(const TQString &s, const ArgEscapeData &d, int field_width,
+ const TQString &arg, const TQString &larg)
+{
+ const TQChar *uc_begin = s.tqunicode();
+ const TQChar *uc_end = uc_begin + s.length();
+
+ uint abs_field_width = TQABS(field_width);
+ uint result_len = s.length()
+ - d.escape_len
+ + (d.occurrences - d.locale_occurrences)
+ *TQMAX(abs_field_width, arg.length())
+ + d.locale_occurrences
+ *TQMAX(abs_field_width, larg.length());
+
+ TQString result;
+ result.setLength(result_len);
+ TQChar *result_buff = (TQChar*) result.tqunicode();
+
+ TQChar *rc = result_buff;
+ const TQChar *c = uc_begin;
+ uint repl_cnt = 0;
+ while (c != uc_end) {
+ /* We don't have to check if we run off the end of the string with c,
+ because as long as d.occurrences > 0 we KNOW there are valid escape
+ sequences. */
+
+ const TQChar *text_start = c;
+
+ while (c->tqunicode() != '%')
+ ++c;
+
+ const TQChar *escape_start = c++;
+
+ bool locale_arg = FALSE;
+ if (c->tqunicode() == 'L') {
+ locale_arg = TRUE;
+ ++c;
+ }
+
+ if (c->tqunicode() != '0' + d.min_escape) {
+ memcpy(rc, text_start, (c - text_start)*sizeof(TQChar));
+ rc += c - text_start;
+ }
+ else {
+ ++c;
+
+ memcpy(rc, text_start, (escape_start - text_start)*sizeof(TQChar));
+ rc += escape_start - text_start;
+
+ uint pad_chars;
+ if (locale_arg)
+ pad_chars = TQMAX(abs_field_width, larg.length()) - larg.length();
+ else
+ pad_chars = TQMAX(abs_field_width, arg.length()) - arg.length();
+
+ if (field_width > 0) { // left padded
+ for (uint i = 0; i < pad_chars; ++i)
+// (rc++)->tqunicode() = ' ';
+ *(rc++) = ' ';
+ }
+
+ if (locale_arg) {
+ memcpy(rc, larg.tqunicode(), larg.length()*sizeof(TQChar));
+ rc += larg.length();
+ }
+ else {
+ memcpy(rc, arg.tqunicode(), arg.length()*sizeof(TQChar));
+ rc += arg.length();
+ }
+
+ if (field_width < 0) { // right padded
+ for (uint i = 0; i < pad_chars; ++i)
+// (rc++)->tqunicode() = ' ';
+ *(rc++) = ' ';
+ }
+
+ if (++repl_cnt == d.occurrences) {
+ memcpy(rc, c, (uc_end - c)*sizeof(TQChar));
+ rc += uc_end - c;
+ TQ_ASSERT(rc - result_buff == (int)result_len);
+ c = uc_end;
+ }
+ }
+ }
+
+ return result;
+}
+
+/*!
+ This function will return a string that tqreplaces the lowest
+ numbered occurrence of \c %1, \c %2, ..., \c %9 with \a a.
+
+ The \a fieldWidth value specifies the minimum amount of space that
+ \a a is padded to. A positive value will produce right-aligned
+ text, whereas a negative value will produce left-aligned text.
+
+ The following example shows how we could create a 'status' string
+ when processing a list of files:
+ \code
+ TQString status = TQString( "Processing file %1 of %2: %3" )
+ .tqarg( i ) // current file's number
+ .tqarg( total ) // number of files to process
+ .tqarg( fileName ); // current file's name
+ \endcode
+
+ It is generally fine to use filenames and numbers as we have done
+ in the example above. But note that using tqarg() to construct
+ natural language sentences does not usually translate well into
+ other languages because sentence structure and word order often
+ differ between languages.
+
+ If there is no place marker (\c %1, \c %2, etc.), a warning
+ message (qWarning()) is output and the result is undefined.
+
+ \warning If any placeholder occurs more than once, the result is undefined.
+
+*/
+TQString TQString::tqarg( const TQString& a, int fieldWidth ) const
+{
+ ArgEscapeData d = tqfindArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning( "TQString::tqarg(): Argument missing: %s, %s", latin1(),
+ a.latin1() );
+ return *this;
+ }
+
+ return tqreplaceArgEscapes(*this, d, fieldWidth, a, a);
+}
+
+/*!
+ \fn TQString TQString::tqarg( const TQString& a1, const TQString& a2 ) const
+
+ \overload
+
+ This is the same as str.tqarg(\a a1).tqarg(\a a2), except that
+ the strings are tqreplaced in one pass. This can make a difference
+ if \a a1 tqcontains e.g. \c{%1}:
+
+ \code
+ TQString str( "%1 %2" );
+ str.tqarg( "Hello", "world" ); // returns "Hello world"
+ str.tqarg( "Hello" ).tqarg( "world" ); // returns "Hello world"
+
+ str.tqarg( "(%1)", "Hello" ); // returns "(%1) Hello"
+ str.tqarg( "(%1)" ).tqarg( "Hello" ); // returns "(Hello) %2"
+ \endcode
+*/
+
+/*!
+ \fn TQString TQString::tqarg( const TQString& a1, const TQString& a2,
+ const TQString& a3 ) const
+ \overload
+
+ This is the same as calling str.tqarg(\a a1).tqarg(\a a2).tqarg(\a a3),
+ except that the strings are tqreplaced in one pass.
+*/
+
+/*!
+ \fn TQString TQString::tqarg( const TQString& a1, const TQString& a2,
+ const TQString& a3, const TQString& a4 ) const
+ \overload
+
+ This is the same as calling
+ str.tqarg(\a a1).tqarg(\a a2).tqarg(\a a3).tqarg(\a a4),
+ except that the strings are tqreplaced in one pass.
+*/
+
+/*!
+ \overload
+
+ The \a fieldWidth value specifies the minimum amount of space that
+ \a a is padded to. A positive value will produce a right-aligned
+ number, whereas a negative value will produce a left-aligned
+ number.
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36.
+
+ The '%' can be followed by an 'L', in which case the sequence is
+ tqreplaced with a localized representation of \a a. The conversion
+ uses the default locale. The default locale is determined from the
+ system's locale settings at application startup. It can be changed
+ using TQLocale::setDefault(). The 'L' flag is ignored if \a base is
+ not 10.
+
+ \code
+ TQString str;
+ str = TQString( "Decimal 63 is %1 in hexadecimal" )
+ .tqarg( 63, 0, 16 );
+ // str == "Decimal 63 is 3f in hexadecimal"
+
+ TQLocale::setDefault(TQLocale::English, TQLocale::UnitedStates);
+ str = TQString( "%1 %L2 %L3" )
+ .tqarg( 12345 )
+ .tqarg( 12345 )
+ .tqarg( 12345, 0, 16 );
+ // str == "12345 12,345 3039"
+ \endcode
+*/
+TQString TQString::tqarg( long a, int fieldWidth, int base ) const
+{
+ return tqarg((TQ_LLONG)a, fieldWidth, base);
+}
+
+/*!
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+TQString TQString::tqarg( ulong a, int fieldWidth, int base ) const
+{
+ return tqarg((TQ_ULLONG)a, fieldWidth, base);
+}
+
+/*!
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+TQString TQString::tqarg( TQ_LLONG a, int fieldWidth, int base ) const
+{
+ ArgEscapeData d = tqfindArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning( "TQString::tqarg(): Argument missing: %s, %lld", latin1(),
+ a );
+ return *this;
+ }
+
+ TQString arg;
+ if (d.occurrences > d.locale_occurrences)
+ arg = number(a, base);
+
+ TQString locale_arg;
+ if (d.locale_occurrences > 0) {
+ TQLocale locale;
+ locale_arg = locale.d->longLongToString(a, -1, base, -1, TQLocalePrivate::ThousandsGroup);
+ }
+
+ return tqreplaceArgEscapes(*this, d, fieldWidth, arg, locale_arg);
+}
+
+/*!
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+TQString TQString::tqarg( TQ_ULLONG a, int fieldWidth, int base ) const
+{
+ ArgEscapeData d = tqfindArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning( "TQString::tqarg(): Argument missing: %s, %llu", latin1(),
+ a );
+ return *this;
+ }
+
+ TQString arg;
+ if (d.occurrences > d.locale_occurrences)
+ arg = number(a, base);
+
+ TQString locale_arg;
+ if (d.locale_occurrences > 0) {
+ TQLocale locale;
+ locale_arg = locale.d->unsLongLongToString(a, -1, base, -1, TQLocalePrivate::ThousandsGroup);
+ }
+
+ return tqreplaceArgEscapes(*this, d, fieldWidth, arg, locale_arg);
+}
+
+/*!
+ \fn TQString TQString::tqarg( int a, int fieldWidth, int base ) const
+
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+
+/*!
+ \fn TQString TQString::tqarg( uint a, int fieldWidth, int base ) const
+
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+
+/*!
+ \fn TQString TQString::tqarg( short a, int fieldWidth, int base ) const
+
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+
+/*!
+ \fn TQString TQString::tqarg( ushort a, int fieldWidth, int base ) const
+
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+
+
+/*!
+ \overload
+
+ \a a is assumed to be in the Latin-1 character set.
+*/
+TQString TQString::tqarg( char a, int fieldWidth ) const
+{
+ TQString c;
+ c += a;
+ return tqarg( c, fieldWidth );
+}
+
+/*!
+ \overload
+*/
+TQString TQString::tqarg( TQChar a, int fieldWidth ) const
+{
+ TQString c;
+ c += a;
+ return tqarg( c, fieldWidth );
+}
+
+/*!
+ \overload
+
+ \target arg-formats
+
+ Argument \a a is formatted according to the \a fmt format specified,
+ which is 'g' by default and can be any of the following:
+
+ \table
+ \header \i Format \i Meaning
+ \row \i \c e \i format as [-]9.9e[+|-]999
+ \row \i \c E \i format as [-]9.9E[+|-]999
+ \row \i \c f \i format as [-]9.9
+ \row \i \c g \i use \c e or \c f format, whichever is the most concise
+ \row \i \c G \i use \c E or \c f format, whichever is the most concise
+ \endtable
+
+ With 'e', 'E', and 'f', \a prec is the number of digits after the
+ decimal point. With 'g' and 'G', \a prec is the maximum number of
+ significant digits (trailing zeroes are omitted).
+
+ \code
+ double d = 12.34;
+ TQString ds = TQString( "'E' format, precision 3, gives %1" )
+ .tqarg( d, 0, 'E', 3 );
+ // ds == "'E' format, precision 3, gives 1.234E+01"
+ \endcode
+
+ The '%L' syntax can be used to produce localized strings.
+*/
+TQString TQString::tqarg( double a, int fieldWidth, char fmt, int prec ) const
+{
+ ArgEscapeData d = tqfindArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning( "TQString::tqarg(): Argument missing: %s, %g", latin1(),
+ a );
+ return *this;
+ }
+
+ TQString arg;
+ if (d.occurrences > d.locale_occurrences)
+ arg = number(a, fmt, prec);
+
+ TQString locale_arg;
+ if (d.locale_occurrences > 0) {
+ TQLocale locale;
+
+ TQLocalePrivate::DoubleForm form = TQLocalePrivate::DFDecimal;
+ uint flags = 0;
+
+ if (tqIsUpper(fmt))
+ flags = TQLocalePrivate::CapitalEorX;
+ fmt = tqToLower(fmt);
+
+ switch (fmt) {
+ case 'f':
+ form = TQLocalePrivate::DFDecimal;
+ break;
+ case 'e':
+ form = TQLocalePrivate::DFExponent;
+ break;
+ case 'g':
+ form = TQLocalePrivate::DFSignificantDigits;
+ break;
+ default:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQString::setNum: Invalid format char '%c'", fmt );
+#endif
+ break;
+ }
+
+ flags |= TQLocalePrivate::ThousandsGroup;
+
+ locale_arg = locale.d->doubleToString(a, prec, form, -1, flags);
+ }
+
+ return tqreplaceArgEscapes(*this, d, fieldWidth, arg, locale_arg);
+}
+
+TQString TQString::tqmultiArg( int numArgs, const TQString& a1, const TQString& a2, const TQString& a3, const TQString& a4 ) const
+{
+ TQString result;
+ union {
+ int digitUsed[10];
+ int argForDigit[10];
+ };
+ register const TQChar *uc = this->tqunicode();
+ const TQString *args[4];
+ const int len = (int) length();
+ const int end = len - 1;
+ int lastDigit = -1;
+ int i;
+
+ memset( digitUsed, 0, sizeof(digitUsed) );
+ args[0] = &a1;
+ args[1] = &a2;
+ args[2] = &a3;
+ args[3] = &a4;
+
+ for ( i = 0; i < end; i++ ) {
+ if ( uc[i] == '%' ) {
+ int digit = uc[i + 1].tqunicode() - '0';
+ if ( digit >= 0 && digit <= 9 )
+ digitUsed[digit]++;
+ }
+ }
+
+ for ( i = 0; i < numArgs; i++ ) {
+ do {
+ ++lastDigit;
+ } while ( lastDigit < 10 && digitUsed[lastDigit] == 0 );
+
+ if ( lastDigit == 10 ) {
+ qWarning( "TQString::arg(): Argument missing: %s, %s",
+ latin1(), args[i]->latin1() );
+ numArgs = i;
+ lastDigit = 9;
+ break;
+ }
+ argForDigit[lastDigit] = i;
+ }
+
+ i = 0;
+ while ( i < len ) {
+ if ( uc[i] == '%' && i != end ) {
+ int digit = uc[i + 1].tqunicode() - '0';
+ if ( digit >= 0 && digit <= lastDigit ) {
+ result += *args[argForDigit[digit]];
+ i += 2;
+ continue;
+ }
+ }
+ result += uc[i++];
+ }
+ return result;
+}
+
+TQString &TQString::setAscii( const char *str, int len )
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( TQTextCodec::codecForCStrings() ) {
+ *this = TQString::fromAscii( str, len );
+ return *this;
+ }
+#endif // TQT_NO_TEXTCODEC
+ return setLatin1( str, len );
+}
+
+TQString &TQString::setLatin1( const char *ch, int len ) {
+ *this = fromLatin1(ch, len); return *this;
+}
+
+bool TQString::simpleText() const {
+ if ( !tqstring_issimpletext ) checkSimpleText();
+ return tqstring_issimpletext;
+}
+
+/*! \internal
+ */
+void TQString::checkSimpleText() const
+{
+ TQChar *p = const_cast<TQChar*>(tqunicode());
+ TQChar *end = p + length();
+ while ( p < end ) {
+ ushort uc = p->tqunicode();
+ // sort out regions of complex text formatting
+ if ( uc > 0x058f && ( uc < 0x1100 || uc > 0xfb0f ) ) {
+ tqstring_issimpletext = FALSE;
+ return;
+ }
+ p++;
+ }
+ tqstring_issimpletext = TRUE;
+}
+
+/*!
+ Resizes the string to \a len characters and copies \a
+ tqunicode_as_ushorts into the string (on some X11 client platforms
+ this will involve a byte-swapping pass).
+
+ If \a tqunicode_as_ushorts is 0, nothing is copied, but the string
+ is still resized to \a len. If \a len is zero, the string becomes
+ a \link isNull() null\endlink string.
+
+ \sa setLatin1(), isNull()
+*/
+TQString TQString::setUnicodeCodes( const ushort* tqunicode_as_ushorts, uint len )
+{
+ return TQString(setUnicode((const TQChar*)tqunicode_as_ushorts, len));
+}
+
+#else // USE_QT4
+
+static int ucstrcmp( const TQString &as, const TQString &bs )
+{
+ const TQChar *a = as.tqunicode();
+ const TQChar *b = bs.tqunicode();
+ if ( a == b )
+ return 0;
+ if ( a == 0 )
+ return 1;
+ if ( b == 0 )
+ return -1;
+ int l=TQMIN(as.length(),bs.length());
+ while ( l-- && *a == *b )
+ a++,b++;
+ if ( l==-1 )
+ return ( as.length()-bs.length() );
+ return a->tqunicode() - b->tqunicode();
+}
+
+static int ucstrncmp( const TQChar *a, const TQChar *b, int l )
+{
+ while ( l-- && *a == *b )
+ a++,b++;
+ if ( l==-1 )
+ return 0;
+ return a->tqunicode() - b->tqunicode();
+}
+
+static int ucstrnicmp( const TQChar *a, const TQChar *b, int l )
+{
+ while ( l-- && ::lower( *a ) == ::lower( *b ) )
+ a++,b++;
+ if ( l==-1 )
+ return 0;
+ return ::lower( *a ).tqunicode() - ::lower( *b ).tqunicode();
+}
+
+static uint computeNewMax( uint len )
+{
+ if (len >= 0x80000000)
+ return len;
+
+ uint newMax = 4;
+ while ( newMax < len )
+ newMax *= 2;
+ // try to save some memory
+ if ( newMax >= 1024 * 1024 && len <= newMax - (newMax >> 2) )
+ newMax -= newMax >> 2;
+ return newMax;
+}
+
+static bool qIsUpper(char c)
+{
+ return c >= 'A' && c <= 'Z';
+}
+
+static bool qIsDigit(char c)
+{
+ return c >= '0' && c <= '9';
+}
+
+static char qToLower(char c)
+{
+ if (c >= 'A' && c <= 'Z')
+ return c - 'A' + 'a';
+ else
+ return c;
+}
+
+/*!
+ \class TQCharRef tqstring.h
+ \reentrant
+ \brief The TQCharRef class is a helper class for TQString.
+
+ \ingroup text
+
+ When you get an object of type TQCharRef, if you can assign to it,
+ the assignment will apply to the character in the string from
+ which you got the reference. That is its whole purpose in life.
+ The TQCharRef becomes invalid once modifications are made to the
+ string: if you want to keep the character, copy it into a TQChar.
+
+ Most of the TQChar member functions also exist in TQCharRef.
+ However, they are not explicitly documented here.
+
+ \sa TQString::operator[]() TQString::at() TQChar
+*/
+
+/*!
+ \class TQChar tqstring.h
+ \reentrant
+ \brief The TQChar class provides a lightweight Unicode character.
+
+ \ingroup text
+
+ Unicode characters are (so far) 16-bit entities without any markup
+ or structure. This class represents such an entity. It is
+ lightweight, so it can be used everywhere. Most compilers treat it
+ like a "short int". (In a few years it may be necessary to make
+ TQChar 32-bit when more than 65536 Unicode code points have been
+ defined and come into use.)
+
+ TQChar provides a full complement of testing/classification
+ functions, converting to and from other formats, converting from
+ composed to decomposed Unicode, and trying to compare and
+ case-convert if you ask it to.
+
+ The classification functions include functions like those in
+ ctype.h, but operating on the full range of Unicode characters.
+ They all return TRUE if the character is a certain type of
+ character; otherwise they return FALSE. These classification
+ functions are isNull() (returns TRUE if the character is U+0000),
+ isPrint() (TRUE if the character is any sort of printable
+ character, including whitespace), isPunct() (any sort of
+ punctation), isMark() (Unicode Mark), isLetter (a letter),
+ isNumber() (any sort of numeric character), isLetterOrNumber(),
+ and isDigit() (decimal digits). All of these are wrappers around
+ category() which return the Unicode-defined category of each
+ character.
+
+ TQChar further provides direction(), which indicates the "natural"
+ writing direction of this character. The joining() function
+ indicates how the character joins with its neighbors (needed
+ mostly for Arabic) and finally mirrored(), which indicates whether
+ the character needs to be mirrored when it is printed in its
+ "unnatural" writing direction.
+
+ Composed Unicode characters (like &aring;) can be converted to
+ decomposed Unicode ("a" followed by "ring above") by using
+ decomposition().
+
+ In Unicode, comparison is not necessarily possible and case
+ conversion is very difficult at best. Unicode, covering the
+ "entire" world, also includes most of the world's case and sorting
+ problems. TQt tries, but not very hard: operator==() and friends
+ will do comparison based purely on the numeric Unicode value (code
+ point) of the characters, and upper() and lower() will do case
+ changes when the character has a well-defined upper/lower-case
+ equivalent. There is no provision for locale-dependent case
+ folding rules or comparison; these functions are meant to be fast
+ so they can be used unambiguously in data structures. (See
+ TQString::localeAwareCompare() though.)
+
+ The conversion functions include tqunicode() (to a scalar), latin1()
+ (to scalar, but converts all non-Latin-1 characters to 0), row()
+ (gives the Unicode row), cell() (gives the Unicode cell),
+ digitValue() (gives the integer value of any of the numerous digit
+ characters), and a host of constructors.
+
+ More information can be found in the document \link tqunicode.html
+ About Unicode. \endlink
+
+ \sa TQString TQCharRef
+*/
+
+/*!
+ \enum TQChar::Category
+
+ This enum maps the Unicode character categories.
+
+ The following characters are normative in Unicode:
+
+ \value Mark_NonSpacing Unicode class name Mn
+
+ \value Mark_SpacingCombining Unicode class name Mc
+
+ \value Mark_Enclosing Unicode class name Me
+
+ \value Number_DecimalDigit Unicode class name Nd
+
+ \value Number_Letter Unicode class name Nl
+
+ \value Number_Other Unicode class name No
+
+ \value Separator_Space Unicode class name Zs
+
+ \value Separator_Line Unicode class name Zl
+
+ \value Separator_Paragraph Unicode class name Zp
+
+ \value Other_Control Unicode class name Cc
+
+ \value Other_Format Unicode class name Cf
+
+ \value Other_Surrogate Unicode class name Cs
+
+ \value Other_PrivateUse Unicode class name Co
+
+ \value Other_NotAssigned Unicode class name Cn
+
+
+ The following categories are informative in Unicode:
+
+ \value Letter_Uppercase Unicode class name Lu
+
+ \value Letter_Lowercase Unicode class name Ll
+
+ \value Letter_Titlecase Unicode class name Lt
+
+ \value Letter_Modifier Unicode class name Lm
+
+ \value Letter_Other Unicode class name Lo
+
+ \value Punctuation_Connector Unicode class name Pc
+
+ \value Punctuation_Dash Unicode class name Pd
+
+ \value Punctuation_Open Unicode class name Ps
+
+ \value Punctuation_Close Unicode class name Pe
+
+ \value Punctuation_InitialQuote Unicode class name Pi
+
+ \value Punctuation_FinalQuote Unicode class name Pf
+
+ \value Punctuation_Other Unicode class name Po
+
+ \value Symbol_Math Unicode class name Sm
+
+ \value Symbol_Currency Unicode class name Sc
+
+ \value Symbol_Modifier Unicode class name Sk
+
+ \value Symbol_Other Unicode class name So
+
+
+ There are two categories that are specific to TQt:
+
+ \value NoCategory used when TQt is dazed and confused and cannot
+ make sense of anything.
+
+ \value Punctuation_Dask old typo alias for Punctuation_Dash
+
+*/
+
+/*!
+ \enum TQChar::Direction
+
+ This enum type defines the Unicode direction attributes. See \link
+ http://www.tqunicode.org/ the Unicode Standard\endlink for a
+ description of the values.
+
+ In order to conform to C/C++ naming conventions "Dir" is prepended
+ to the codes used in the Unicode Standard.
+*/
+
+/*!
+ \enum TQChar::Decomposition
+
+ This enum type defines the Unicode decomposition attributes. See
+ \link http://www.tqunicode.org/ the Unicode Standard\endlink for a
+ description of the values.
+*/
+
+/*!
+ \enum TQChar::Joining
+
+ This enum type defines the Unicode joining attributes. See \link
+ http://www.tqunicode.org/ the Unicode Standard\endlink for a
+ description of the values.
+*/
+
+/*!
+ \enum TQChar::CombiningClass
+
+ This enum type defines names for some of the Unicode combining
+ classes. See \link http://www.tqunicode.org/ the Unicode
+ Standard\endlink for a description of the values.
+*/
+
+/*!
+ \fn void TQChar::setCell( uchar cell )
+ \internal
+*/
+
+/*!
+ \fn void TQChar::setRow( uchar row )
+ \internal
+*/
+
+
+/*!
+ \fn TQChar::TQChar()
+
+ Constructs a null TQChar (one that isNull()).
+*/
+
+
+/*!
+ \fn TQChar::TQChar( char c )
+
+ Constructs a TQChar corresponding to ASCII/Latin-1 character \a c.
+*/
+
+
+/*!
+ \fn TQChar::TQChar( uchar c )
+
+ Constructs a TQChar corresponding to ASCII/Latin-1 character \a c.
+*/
+
+
+/*!
+ \fn TQChar::TQChar( uchar c, uchar r )
+
+ Constructs a TQChar for Unicode cell \a c in row \a r.
+*/
+
+
+/*!
+ \fn TQChar::TQChar( const TQChar& c )
+
+ Constructs a copy of \a c. This is a deep copy, if such a
+ lightweight object can be said to have deep copies.
+*/
+
+
+/*!
+ \fn TQChar::TQChar( ushort rc )
+
+ Constructs a TQChar for the character with Unicode code point \a rc.
+*/
+
+
+/*!
+ \fn TQChar::TQChar( short rc )
+
+ Constructs a TQChar for the character with Unicode code point \a rc.
+*/
+
+
+/*!
+ \fn TQChar::TQChar( uint rc )
+
+ Constructs a TQChar for the character with Unicode code point \a rc.
+*/
+
+
+/*!
+ \fn TQChar::TQChar( int rc )
+
+ Constructs a TQChar for the character with Unicode code point \a rc.
+*/
+
+
+/*!
+ \fn bool TQChar::networkOrdered ()
+
+ \obsolete
+
+ Returns TRUE if this character is in network byte order (MSB
+ first); otherwise returns FALSE. This is platform dependent.
+*/
+
+
+/*!
+ \fn bool TQChar::isNull() const
+
+ Returns TRUE if the character is the Unicode character 0x0000
+ (ASCII NUL); otherwise returns FALSE.
+*/
+
+/*!
+ \fn uchar TQChar::cell () const
+
+ Returns the cell (least significant byte) of the Unicode
+ character.
+*/
+
+/*!
+ \fn uchar TQChar::row () const
+
+ Returns the row (most significant byte) of the Unicode character.
+*/
+
+/*!
+ Returns TRUE if the character is a printable character; otherwise
+ returns FALSE. This is any character not of category Cc or Cn.
+
+ Note that this gives no indication of whether the character is
+ available in a particular \link TQFont font\endlink.
+*/
+bool TQChar::isPrint() const
+{
+ Category c = ::category( *this );
+ return !(c == Other_Control || c == Other_NotAssigned);
+}
+
+/*!
+ Returns TRUE if the character is a separator character
+ (Separator_* categories); otherwise returns FALSE.
+*/
+bool TQChar::isSpace() const
+{
+ return ::isSpace( *this );
+}
+
+/*!
+ Returns TRUE if the character is a mark (Mark_* categories);
+ otherwise returns FALSE.
+*/
+bool TQChar::isMark() const
+{
+ Category c = ::category( *this );
+ return c >= Mark_NonSpacing && c <= Mark_Enclosing;
+}
+
+/*!
+ Returns TRUE if the character is a punctuation mark (Punctuation_*
+ categories); otherwise returns FALSE.
+*/
+bool TQChar::isPunct() const
+{
+ Category c = ::category( *this );
+ return (c >= Punctuation_Connector && c <= Punctuation_Other);
+}
+
+/*!
+ Returns TRUE if the character is a letter (Letter_* categories);
+ otherwise returns FALSE.
+*/
+bool TQChar::isLetter() const
+{
+ Category c = ::category( *this );
+ return (c >= Letter_Uppercase && c <= Letter_Other);
+}
+
+/*!
+ Returns TRUE if the character is a number (of any sort - Number_*
+ categories); otherwise returns FALSE.
+
+ \sa isDigit()
+*/
+bool TQChar::isNumber() const
+{
+ Category c = ::category( *this );
+ return c >= Number_DecimalDigit && c <= Number_Other;
+}
+
+/*!
+ Returns TRUE if the character is a letter or number (Letter_* or
+ Number_* categories); otherwise returns FALSE.
+*/
+bool TQChar::isLetterOrNumber() const
+{
+ Category c = ::category( *this );
+ return (c >= Letter_Uppercase && c <= Letter_Other)
+ || (c >= Number_DecimalDigit && c <= Number_Other);
+}
+
+
+/*!
+ Returns TRUE if the character is a decimal digit
+ (Number_DecimalDigit); otherwise returns FALSE.
+*/
+bool TQChar::isDigit() const
+{
+ return (::category( *this ) == Number_DecimalDigit);
+}
+
+
+/*!
+ Returns TRUE if the character is a symbol (Symbol_* categories);
+ otherwise returns FALSE.
+*/
+bool TQChar::isSymbol() const
+{
+ Category c = ::category( *this );
+ return c >= Symbol_Math && c <= Symbol_Other;
+}
+
+/*!
+ Returns the numeric value of the digit, or -1 if the character is
+ not a digit.
+*/
+int TQChar::digitValue() const
+{
+#ifndef TQT_NO_UNICODETABLES
+ register int pos = TQUnicodeTables::decimal_info[row()];
+ if( !pos )
+ return -1;
+ return TQUnicodeTables::decimal_info[(pos<<8) + cell()];
+#else
+ // ##### just latin1
+ if ( ucs < '0' || ucs > '9' )
+ return -1;
+ else
+ return ucs - '0';
+#endif
+}
+
+/*!
+ Returns the character category.
+
+ \sa Category
+*/
+TQChar::Category TQChar::category() const
+{
+ return ::category( *this );
+}
+
+/*!
+ Returns the character's direction.
+
+ \sa Direction
+*/
+TQChar::Direction TQChar::direction() const
+{
+ return ::direction( *this );
+}
+
+/*!
+ \warning This function is not supported (it may change to use
+ Unicode character classes).
+
+ Returns information about the joining properties of the character
+ (needed for example, for Arabic).
+*/
+TQChar::Joining TQChar::joining() const
+{
+ return ::joining( *this );
+}
+
+
+/*!
+ Returns TRUE if the character is a mirrored character (one that
+ should be reversed if the text direction is reversed); otherwise
+ returns FALSE.
+*/
+bool TQChar::mirrored() const
+{
+ return ::mirrored( *this );
+}
+
+/*!
+ Returns the mirrored character if this character is a mirrored
+ character, otherwise returns the character itself.
+*/
+TQChar TQChar::mirroredChar() const
+{
+ return ::mirroredChar( *this );
+}
+
+#ifndef TQT_NO_UNICODETABLES
+// ### REMOVE ME 4.0
+static TQString shared_decomp;
+#endif
+/*!
+ \nonreentrant
+
+ Decomposes a character into its parts. Returns TQString::null if no
+ decomposition exists.
+*/
+const TQString &TQChar::decomposition() const
+{
+#ifndef TQT_NO_UNICODETABLES
+ register int pos = TQUnicodeTables::decomposition_info[row()];
+ if(!pos) return TQString::null;
+
+ pos = TQUnicodeTables::decomposition_info[(pos<<8)+cell()];
+ if(!pos) return TQString::null;
+ pos+=2;
+
+ TQString s;
+ TQ_UINT16 c;
+ while ( (c = TQUnicodeTables::decomposition_map[pos++]) != 0 )
+ s += TQChar( c );
+ // ### In 4.0, return s, and not shared_decomp. shared_decomp
+ // prevents this function from being reentrant.
+ shared_decomp = s;
+ return shared_decomp;
+#else
+ return TQString::null;
+#endif
+}
+
+/*!
+ Returns the tag defining the composition of the character. Returns
+ TQChar::Single if no decomposition exists.
+*/
+TQChar::Decomposition TQChar::decompositionTag() const
+{
+#ifndef TQT_NO_UNICODETABLES
+ register int pos = TQUnicodeTables::decomposition_info[row()];
+ if(!pos) return TQChar::Single;
+
+ pos = TQUnicodeTables::decomposition_info[(pos<<8)+cell()];
+ if(!pos) return TQChar::Single;
+
+ return (TQChar::Decomposition) TQUnicodeTables::decomposition_map[pos];
+#else
+ return Single; // ########### FIX eg. just latin1
+#endif
+}
+
+/*!
+ Returns the combining class for the character as defined in the
+ Unicode standard. This is mainly useful as a positioning hint for
+ marks attached to a base character.
+
+ The TQt text rendering engine uses this information to correctly
+ position non spacing marks around a base character.
+*/
+unsigned char TQChar::combiningClass() const
+{
+ return ::combiningClass( *this );
+}
+
+
+/*!
+ Returns the lowercase equivalent if the character is uppercase;
+ otherwise returns the character itself.
+*/
+TQChar TQChar::lower() const
+{
+ return ::lower( *this );
+}
+
+/*!
+ Returns the uppercase equivalent if the character is lowercase;
+ otherwise returns the character itself.
+*/
+TQChar TQChar::upper() const
+{
+ return ::upper( *this );
+}
+
+/*!
+ \fn TQChar::operator char() const
+
+ Returns the Latin-1 character equivalent to the TQChar, or 0. This
+ is mainly useful for non-internationalized software.
+
+ \sa tqunicode()
+*/
+
+/*!
+ \fn ushort TQChar::tqunicode() const
+
+ Returns the numeric Unicode value equal to the TQChar. Normally,
+ you should use TQChar objects as they are equivalent, but for some
+ low-level tasks (e.g. indexing into an array of Unicode
+ information), this function is useful.
+*/
+
+/*!
+ \fn ushort & TQChar::tqunicode()
+
+ \overload
+
+ Returns a reference to the numeric Unicode value equal to the
+ TQChar.
+*/
+
+/*****************************************************************************
+ Documentation of TQChar related functions
+ *****************************************************************************/
+
+/*!
+ \fn bool operator==( TQChar c1, TQChar c2 )
+
+ \relates TQChar
+
+ Returns TRUE if \a c1 and \a c2 are the same Unicode character;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool operator==( char ch, TQChar c )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if \a c is the ASCII/Latin-1 character \a ch;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool operator==( TQChar c, char ch )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if \a c is the ASCII/Latin-1 character \a ch;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn int operator!=( TQChar c1, TQChar c2 )
+
+ \relates TQChar
+
+ Returns TRUE if \a c1 and \a c2 are not the same Unicode
+ character; otherwise returns FALSE.
+*/
+
+/*!
+ \fn int operator!=( char ch, TQChar c )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if \a c is not the ASCII/Latin-1 character \a ch;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn int operator!=( TQChar c, char ch )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if \a c is not the ASCII/Latin-1 character \a ch;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn int operator<=( TQChar c1, TQChar c2 )
+
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is less than
+ that of \a c2, or they are the same Unicode character; otherwise
+ returns FALSE.
+*/
+
+/*!
+ \fn int operator<=( TQChar c, char ch )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of \a c is less than or
+ equal to that of the ASCII/Latin-1 character \a ch; otherwise
+ returns FALSE.
+*/
+
+/*!
+ \fn int operator<=( char ch, TQChar c )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin-1
+ character \a ch is less than or equal to that of \a c; otherwise
+ returns FALSE.
+*/
+
+/*!
+ \fn int operator>=( TQChar c1, TQChar c2 )
+
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is greater than
+ that of \a c2, or they are the same Unicode character; otherwise
+ returns FALSE.
+*/
+
+/*!
+ \fn int operator>=( TQChar c, char ch )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of \a c is greater than
+ or equal to that of the ASCII/Latin-1 character \a ch; otherwise
+ returns FALSE.
+*/
+
+/*!
+ \fn int operator>=( char ch, TQChar c )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin-1
+ character \a ch is greater than or equal to that of \a c;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn int operator<( TQChar c1, TQChar c2 )
+
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is less than
+ that of \a c2; otherwise returns FALSE.
+*/
+
+/*!
+ \fn int operator<( TQChar c, char ch )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of \a c is less than that
+ of the ASCII/Latin-1 character \a ch; otherwise returns FALSE.
+*/
+
+/*!
+ \fn int operator<( char ch, TQChar c )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin-1
+ character \a ch is less than that of \a c; otherwise returns
+ FALSE.
+*/
+
+/*!
+ \fn int operator>( TQChar c1, TQChar c2 )
+
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of \a c1 is greater than
+ that of \a c2; otherwise returns FALSE.
+*/
+
+/*!
+ \fn int operator>( TQChar c, char ch )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of \a c is greater than
+ that of the ASCII/Latin-1 character \a ch; otherwise returns FALSE.
+*/
+
+/*!
+ \fn int operator>( char ch, TQChar c )
+
+ \overload
+ \relates TQChar
+
+ Returns TRUE if the numeric Unicode value of the ASCII/Latin-1
+ character \a ch is greater than that of \a c; otherwise returns
+ FALSE.
+*/
+
+#ifndef TQT_NO_UNICODETABLES
+
+// small class used internally in TQString::Compose()
+class TQLigature
+{
+public:
+ TQLigature( TQChar c );
+
+ TQ_UINT16 first() { cur = ligatures; return cur ? *cur : 0; }
+ TQ_UINT16 next() { return cur && *cur ? *(cur++) : 0; }
+ TQ_UINT16 current() { return cur ? *cur : 0; }
+
+ int match(TQString & str, unsigned int index);
+ TQChar head();
+ TQChar::Decomposition tag();
+
+private:
+ TQ_UINT16 *ligatures;
+ TQ_UINT16 *cur;
+};
+
+TQLigature::TQLigature( TQChar c )
+{
+ register int pos = TQUnicodeTables::ligature_info[c.row()];
+ if( !pos )
+ ligatures = 0;
+ else
+ {
+ pos = TQUnicodeTables::ligature_info[(pos<<8)+c.cell()];
+ ligatures = (TQ_UINT16 *)&(TQUnicodeTables::ligature_map[pos]);
+ }
+ cur = ligatures;
+}
+
+TQChar TQLigature::head()
+{
+ if(current())
+ return TQChar(TQUnicodeTables::decomposition_map[current()+1]);
+
+ return TQChar::null;
+}
+
+TQChar::Decomposition TQLigature::tag()
+{
+ if(current())
+ return (TQChar::Decomposition) TQUnicodeTables::decomposition_map[current()];
+
+ return TQChar::Canonical;
+}
+
+int TQLigature::match(TQString & str, unsigned int index)
+{
+ unsigned int i=index;
+
+ if(!current()) return 0;
+
+ TQ_UINT16 lig = current() + 2;
+ TQ_UINT16 ch;
+
+ while ((i < str.length()) && (ch = TQUnicodeTables::decomposition_map[lig])) {
+ if (str[(int)i] != TQChar(ch))
+ return 0;
+ i++;
+ lig++;
+ }
+
+ if (!TQUnicodeTables::decomposition_map[lig])
+ {
+ return i-index;
+ }
+ return 0;
+}
+
+
+// this function is just used in TQString::compose()
+static inline bool format(TQChar::Decomposition tag, TQString & str,
+ int index, int len)
+{
+ unsigned int l = index + len;
+ unsigned int r = index;
+
+ bool left = FALSE, right = FALSE;
+
+ left = ((l < str.length()) &&
+ ((str[(int)l].joining() == TQChar::Dual) ||
+ (str[(int)l].joining() == TQChar::Right)));
+ if (r > 0) {
+ r--;
+ //printf("joining(right) = %d\n", str[(int)r].joining());
+ right = (str[(int)r].joining() == TQChar::Dual);
+ }
+
+
+ switch (tag) {
+ case TQChar::Medial:
+ return (left & right);
+ case TQChar::Initial:
+ return (left && !right);
+ case TQChar::Final:
+ return (right);// && !left);
+ case TQChar::Isolated:
+ default:
+ return (!right && !left);
+ }
+} // format()
+#endif
+
+/*
+ TQString::compose() and visual() were developed by Gordon Tisher
+ <tisher@uniserve.ca>, with input from Lars Knoll <knoll@mpi-hd.mpg.de>,
+ who developed the tqunicode data tables.
+*/
+/*!
+ \warning This function is not supported in TQt 3.x. It is provided
+ for experimental and illustrative purposes only. It is mainly of
+ interest to those experimenting with Arabic and other
+ composition-rich texts.
+
+ Applies possible ligatures to a TQString. Useful when
+ composition-rich text requires rendering with glyph-poor fonts,
+ but it also makes compositions such as TQChar(0x0041) ('A') and
+ TQChar(0x0308) (Unicode accent diaresis), giving TQChar(0x00c4)
+ (German A Umlaut).
+*/
+void TQString::compose()
+{
+#ifndef TQT_NO_UNICODETABLES
+ unsigned int index=0, len;
+ unsigned int cindex = 0;
+
+ TQChar code, head;
+
+ TQMemArray<TQChar> dia;
+
+ TQString composed = *this;
+
+ while (index < length()) {
+ code = at(index);
+ //printf("\n\nligature for 0x%x:\n", code.tqunicode());
+ TQLigature ligature(code);
+ ligature.first();
+ while ( ligature.current() ) {
+ if ((len = ligature.match(*this, index)) != 0) {
+ head = ligature.head();
+ unsigned short code = head.tqunicode();
+ // we exclude Arabic presentation forms A and a few
+ // other ligatures, which are undefined in most fonts
+ if(!(code > 0xfb50 && code < 0xfe80) &&
+ !(code > 0xfb00 && code < 0xfb2a)) {
+ // joining info is only needed for Arabic
+ if (format(ligature.tag(), *this, index, len)) {
+ //printf("using ligature 0x%x, len=%d\n",code,len);
+ // tqreplace letter
+ composed.tqreplace(cindex, len, TQChar(head));
+ index += len-1;
+ // we continue searching in case we have a final
+ // form because medial ones are preferred.
+ if ( len != 1 || ligature.tag() !=TQChar::Final )
+ break;
+ }
+ }
+ }
+ ligature.next();
+ }
+ cindex++;
+ index++;
+ }
+ *this = composed;
+#endif
+}
+
+
+// These macros are used for efficient allocation of TQChar strings.
+// IMPORTANT! If you change these, make sure you also change the
+// "delete tqunicode" statement in ~TQStringData() in tqstring.h correspondingly!
+
+#define TQT_ALLOC_TQCHAR_VEC( N ) (TQChar*) new char[ sizeof(TQChar)*( N ) ]
+#define TQT_DELETE_TQCHAR_VEC( P ) delete[] ((char*)( P ))
+
+
+/*!
+ This utility function converts the 8-bit string \a ba to Unicode,
+ returning the result.
+
+ The caller is responsible for deleting the return value with
+ delete[].
+*/
+
+TQChar* TQString::latin1ToUnicode( const TQByteArray& ba, uint* len )
+{
+ if ( ba.isNull() ) {
+ *len = 0;
+ return 0;
+ }
+ int l = 0;
+ while ( l < (int)ba.size() && ba[l] )
+ l++;
+ const char* str = ba.data();
+ TQChar *uc = new TQChar[ l ]; // Can't use macro, since function is public
+ TQChar *result = uc;
+ if ( len )
+ *len = l;
+ while (l--)
+ *uc++ = *str++;
+ return result;
+}
+
+static TQChar* internalLatin1ToUnicode( const TQByteArray& ba, uint* len )
+{
+ if ( ba.isNull() ) {
+ *len = 0;
+ return 0;
+ }
+ int l = 0;
+ while ( l < (int)ba.size() && ba[l] )
+ l++;
+ const char* str = ba.data();
+ TQChar *uc = TQT_ALLOC_TQCHAR_VEC( l );
+ TQChar *result = uc;
+ if ( len )
+ *len = l;
+ while (l--)
+ *uc++ = *str++;
+ return result;
+}
+
+/*!
+ \overload
+
+ This utility function converts the '\0'-terminated 8-bit string \a
+ str to Unicode, returning the result and setting \a *len to the
+ length of the Unicode string.
+
+ The caller is responsible for deleting the return value with
+ delete[].
+*/
+
+TQChar* TQString::latin1ToUnicode( const char *str, uint* len, uint maxlen )
+{
+ TQChar* result = 0;
+ uint l = 0;
+ if ( str ) {
+ if ( maxlen != (uint)-1 ) {
+ while ( l < maxlen && str[l] )
+ l++;
+ } else {
+ // Faster?
+ l = int(strlen( str ));
+ }
+ TQChar *uc = new TQChar[ l ]; // Can't use macro since function is public
+ result = uc;
+ uint i = l;
+ while ( i-- )
+ *uc++ = *str++;
+ }
+ if ( len )
+ *len = l;
+ return result;
+}
+
+static TQChar* internalLatin1ToUnicode( const char *str, uint* len,
+ uint maxlen = (uint)-1 )
+{
+ TQChar* result = 0;
+ uint l = 0;
+ if ( str ) {
+ if ( maxlen != (uint)-1 ) {
+ while ( l < maxlen && str[l] )
+ l++;
+ } else {
+ // Faster?
+ l = int(strlen( str ));
+ }
+ TQChar *uc = TQT_ALLOC_TQCHAR_VEC( l );
+ result = uc;
+ uint i = l;
+ while ( i-- )
+ *uc++ = *str++;
+ }
+ if ( len )
+ *len = l;
+ return result;
+}
+
+/*!
+ This utility function converts \a l 16-bit characters from \a uc
+ to ASCII, returning a '\0'-terminated string.
+
+ The caller is responsible for deleting the resultant string with
+ delete[].
+*/
+char* TQString::tqunicodeToLatin1(const TQChar *uc, uint l)
+{
+ if (!uc) {
+ return 0;
+ }
+ char *a = new char[l+1];
+ char *result = a;
+ while (l--) {
+ *a++ = (uc->tqunicode() > 0xff) ? '?' : (char)uc->tqunicode();
+ uc++;
+ }
+ *a = '\0';
+ return result;
+}
+
+/*****************************************************************************
+ TQString member functions
+ *****************************************************************************/
+
+/*!
+ \class TQString tqstring.h
+ \reentrant
+
+ \brief The TQString class provides an abstraction of Unicode text
+ and the classic C '\0'-terminated char array.
+
+ \ingroup tools
+ \ingroup shared
+ \ingroup text
+ \mainclass
+
+ TQString uses \link shclass.html implicit sharing\endlink, which
+ makes it very efficient and easy to use.
+
+ In all of the TQString methods that take \c {const char *}
+ parameters, the \c {const char *} is interpreted as a classic
+ C-style '\0'-terminated ASCII string. It is legal for the \c
+ {const char *} parameter to be 0. If the \c {const char *} is not
+ '\0'-terminated, the results are undefined. Functions that copy
+ classic C strings into a TQString will not copy the terminating
+ '\0' character. The TQChar array of the TQString (as returned by
+ tqunicode()) is generally not terminated by a '\0'. If you need to
+ pass a TQString to a function that requires a C '\0'-terminated
+ string use latin1().
+
+ \keyword TQString::null
+ A TQString that has not been assigned to anything is \e null, i.e.
+ both the length and data pointer is 0. A TQString that references
+ the empty string ("", a single '\0' char) is \e empty. Both null
+ and empty TQStrings are legal parameters to the methods. Assigning
+ \c{(const char *) 0} to TQString gives a null TQString. For
+ convenience, \c TQString::null is a null TQString. When sorting,
+ empty strings come first, followed by non-empty strings, followed
+ by null strings. We recommend using \c{if ( !str.isNull() )} to
+ check for a non-null string rather than \c{if ( !str )}; see \l
+ operator!() for an explanation.
+
+ Note that if you tqfind that you are mixing usage of \l TQCString,
+ TQString, and \l TQByteArray, this causes lots of unnecessary
+ copying and might indicate that the true nature of the data you
+ are dealing with is uncertain. If the data is '\0'-terminated 8-bit
+ data, use \l TQCString; if it is unterminated (i.e. tqcontains '\0's)
+ 8-bit data, use \l TQByteArray; if it is text, use TQString.
+
+ Lists of strings are handled by the TQStringList class. You can
+ split a string into a list of strings using TQStringList::split(),
+ and join a list of strings into a single string with an optional
+ separator using TQStringList::join(). You can obtain a list of
+ strings from a string list that contain a particular substring or
+ that match a particular \link tqregexp.html regex\endlink using
+ TQStringList::grep().
+
+ <b>Note for C programmers</b>
+
+ Due to C++'s type system and the fact that TQString is implicitly
+ shared, TQStrings can be treated like ints or other simple base
+ types. For example:
+
+ \code
+ TQString boolToString( bool b )
+ {
+ TQString result;
+ if ( b )
+ result = "True";
+ else
+ result = "False";
+ return result;
+ }
+ \endcode
+
+ The variable, result, is an auto variable allocated on the stack.
+ When return is called, because we're returning by value, The copy
+ constructor is called and a copy of the string is returned. (No
+ actual copying takes place thanks to the implicit sharing, see
+ below.)
+
+ Throughout TQt's source code you will encounter TQString usages like
+ this:
+ \code
+ TQString func( const TQString& input )
+ {
+ TQString output = input;
+ // process output
+ return output;
+ }
+ \endcode
+
+ The 'copying' of input to output is almost as fast as copying a
+ pointer because behind the scenes copying is achieved by
+ incrementing a reference count. TQString (like all TQt's implicitly
+ shared classes) operates on a copy-on-write basis, only copying if
+ an instance is actually changed.
+
+ If you wish to create a deep copy of a TQString without losing any
+ Unicode information then you should use TQDeepCopy.
+
+ \sa TQChar TQCString TQByteArray TQConstString
+*/
+
+/*! \enum TQt::ComparisonFlags
+\internal
+*/
+/*!
+ \enum TQt::StringComparisonMode
+
+ This enum type is used to set the string comparison mode when
+ searching for an item. It is used by TQListBox, TQListView and
+ TQIconView, for example. We'll refer to the string being searched
+ as the 'target' string.
+
+ \value CaseSensitive The strings must match case sensitively.
+ \value ExactMatch The target and search strings must match exactly.
+ \value BeginsWith The target string begins with the search string.
+ \value EndsWith The target string ends with the search string.
+ \value Contains The target string tqcontains the search string.
+
+ If you OR these flags together (excluding \c CaseSensitive), the
+ search criteria be applied in the following order: \c ExactMatch,
+ \c BeginsWith, \c EndsWith, \c Contains.
+
+ Matching is case-insensitive unless \c CaseSensitive is set. \c
+ CaseSensitive can be OR-ed with any combination of the other
+ flags.
+
+*/
+TQ_EXPORT TQStringData *TQString::shared_null = 0;
+TQT_STATIC_CONST_IMPL TQString TQString::null;
+TQT_STATIC_CONST_IMPL TQChar TQChar::null;
+TQT_STATIC_CONST_IMPL TQChar TQChar::tqreplacement((ushort)0xfffd);
+TQT_STATIC_CONST_IMPL TQChar TQChar::byteOrderMark((ushort)0xfeff);
+TQT_STATIC_CONST_IMPL TQChar TQChar::byteOrderSwapped((ushort)0xfffe);
+TQT_STATIC_CONST_IMPL TQChar TQChar::nbsp((ushort)0x00a0);
+
+TQStringData* TQString::makeSharedNull()
+{
+ TQString::shared_null = new TQStringData;
+#if defined( TQ_OS_MAC ) || defined(TQ_OS_SOLARIS) || defined(TQ_OS_HPUX) || defined(TQ_OS_AIX)
+ TQString *that = const_cast<TQString *>(&TQString::null);
+ that->d = TQString::shared_null;
+#endif
+ return TQString::shared_null;
+}
+
+/*!
+ \fn TQString::TQString()
+
+ Constructs a null string, i.e. both the length and data pointer
+ are 0.
+
+ \sa isNull()
+*/
+
+/*!
+ Constructs a string of length one, containing the character \a ch.
+*/
+TQString::TQString( TQChar ch )
+{
+ d = new TQStringData( TQT_ALLOC_TQCHAR_VEC( 1 ), 1, 1 );
+ d->tqunicode[0] = ch;
+}
+
+/*!
+ Constructs an implicitly shared copy of \a s. This is very fast
+ since it only involves incrementing a reference count.
+*/
+TQString::TQString( const TQString &s ) :
+ d(s.d)
+{
+ d->ref();
+}
+
+#ifdef USE_QT4
+
+// Interoperability
+// FIXME
+// These conversions are probably too weak
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+TQString::TQString( const QString &qs )
+{
+ setAscii( TQString(qs).ascii() );
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+TQString::operator QString() const
+{
+ return QString::fromUtf8( this->utf8() );
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+TQString &TQString::operator=( const QString &qs )
+{
+ return setAscii( TQString(qs).ascii() );
+}
+
+bool operator==( const QString &s1, const TQString &s2 )
+{
+ return (TQString(s1).ascii() == s2.ascii());
+}
+
+#endif // USE_QT4
+
+/*!
+ \internal
+
+ Private function.
+
+ Constructs a string with preallocated space for \a size characters.
+
+ The string is empty.
+
+ \sa isNull()
+*/
+
+TQString::TQString( int size, bool /*dummy*/ )
+{
+ if ( size ) {
+ int l = size;
+ TQChar* uc = TQT_ALLOC_TQCHAR_VEC( l );
+ d = new TQStringData( uc, 0, l );
+ } else {
+ d = shared_null ? shared_null : (shared_null=new TQStringData);
+ d->ref();
+ }
+}
+
+/*!
+ Constructs a string that is a deep copy of \a ba interpreted as a
+ classic C string.
+*/
+
+TQString::TQString( const TQByteArray& ba )
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( TQTextCodec::codecForCStrings() ) {
+ d = 0;
+ *this = fromAscii( ba.data(), ba.size() );
+ return;
+ }
+#endif
+ uint l;
+ TQChar *uc = internalLatin1ToUnicode(ba,&l);
+ d = new TQStringData(uc,l,l);
+}
+
+/*!
+ Constructs a string that is a deep copy of the first \a length
+ characters in the TQChar array.
+
+ If \a tqunicode and \a length are 0, then a null string is created.
+
+ If only \a tqunicode is 0, the string is empty but has \a length
+ characters of space preallocated: TQString expands automatically
+ anyway, but this may speed up some cases a little. We recommend
+ using the plain constructor and setLength() for this purpose since
+ it will result in more readable code.
+
+ \sa isNull() setLength()
+*/
+
+TQString::TQString( const TQChar* tqunicode, uint length )
+{
+ if ( !tqunicode && !length ) {
+ d = shared_null ? shared_null : makeSharedNull();
+ d->ref();
+ } else {
+ TQChar* uc = TQT_ALLOC_TQCHAR_VEC( length );
+ if ( tqunicode )
+ memcpy(uc, tqunicode, length*sizeof(TQChar));
+ d = new TQStringData(uc,tqunicode ? length : 0,length);
+ }
+}
+
+/*!
+ Constructs a string that is a deep copy of \a str, interpreted as
+ a classic C string. The encoding is assumed to be Latin-1, unless
+ you change it using TQTextCodec::setCodecForCStrings().
+
+ If \a str is 0, then a null string is created.
+
+ This is a cast constructor, but it is perfectly safe: converting a
+ Latin-1 \c{const char *} to TQString preserves all the information. You
+ can disable this constructor by defining \c TQT_NO_CAST_ASCII when
+ you compile your applications. You can also make TQString objects
+ by using setLatin1(), tqfromLatin1(), fromLocal8Bit(), and
+ fromUtf8(). Or whatever encoding is appropriate for the 8-bit data
+ you have.
+
+ \sa isNull(), fromAscii()
+*/
+
+TQString::TQString( const char *str )
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( TQTextCodec::codecForCStrings() ) {
+ d = 0;
+ *this = fromAscii( str );
+ return;
+ }
+#endif
+ uint l;
+ TQChar *uc = internalLatin1ToUnicode(str,&l);
+ d = new TQStringData(uc,l,l);
+}
+
+#ifndef TQT_NO_STL
+/*!
+ Constructs a string that is a deep copy of \a str.
+
+ This is the same as fromAscii(\a str).
+*/
+
+TQString::TQString( const std::string &str )
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( TQTextCodec::codecForCStrings() ) {
+ d = 0;
+ *this = fromAscii( str.c_str() );
+ return;
+ }
+#endif
+ uint l;
+ TQChar *uc = internalLatin1ToUnicode(str.c_str(),&l);
+ d = new TQStringData(uc,l,l);
+}
+#endif
+
+/*!
+ \fn TQString::~TQString()
+
+ Destroys the string and frees the string's data if this is the
+ last reference to the string.
+*/
+
+
+/*!
+ Deallocates any space reserved solely by this TQString.
+
+ If the string does not share its data with another TQString
+ instance, nothing happens; otherwise the function creates a new,
+ unique copy of this string. This function is called whenever the
+ string is modified.
+*/
+
+void TQString::real_detach()
+{
+ setLength( length() );
+}
+
+void TQString::deref()
+{
+ if ( d && d->deref() ) {
+ if ( d != shared_null )
+ delete d;
+ d = 0;
+ }
+}
+
+void TQStringData::deleteSelf()
+{
+ delete this;
+}
+
+/*!
+ \fn TQString& TQString::operator=( TQChar c )
+
+ Sets the string to contain just the single character \a c.
+*/
+
+/*!
+ \fn TQString& TQString::operator=( const std::string& s )
+
+ \overload
+
+ Makes a deep copy of \a s and returns a reference to the deep
+ copy.
+*/
+
+/*!
+ \fn TQString& TQString::operator=( char c )
+
+ \overload
+
+ Sets the string to contain just the single character \a c.
+*/
+
+/*!
+ \overload
+
+ Assigns a shallow copy of \a s to this string and returns a
+ reference to this string. This is very fast because the string
+ isn't actually copied.
+*/
+TQString &TQString::operator=( const TQString &s )
+{
+ s.d->ref();
+ deref();
+ d = s.d;
+ return *this;
+}
+
+/*!
+ \overload
+
+ Assigns a deep copy of \a cstr, interpreted as a classic C
+ string, to this string. Returns a reference to this string.
+*/
+TQString &TQString::operator=( const TQCString& cstr )
+{
+ return setAscii( cstr );
+}
+
+
+/*!
+ \overload
+
+ Assigns a deep copy of \a str, interpreted as a classic C string
+ to this string and returns a reference to this string.
+
+ If \a str is 0, then a null string is created.
+
+ \sa isNull()
+*/
+TQString &TQString::operator=( const char *str )
+{
+ return setAscii(str);
+}
+
+
+/*!
+ \fn bool TQString::isNull() const
+
+ Returns TRUE if the string is null; otherwise returns FALSE. A
+ null string is always empty.
+
+ \code
+ TQString a; // a.tqunicode() == 0, a.length() == 0
+ a.isNull(); // TRUE, because a.tqunicode() == 0
+ a.isEmpty(); // TRUE, because a.length() == 0
+ \endcode
+
+ \sa isEmpty(), length()
+*/
+
+/*!
+ \fn bool TQString::isEmpty() const
+
+ Returns TRUE if the string is empty, i.e. if length() == 0;
+ otherwise returns FALSE. Null strings are also empty.
+
+ \code
+ TQString a( "" );
+ a.isEmpty(); // TRUE
+ a.isNull(); // FALSE
+
+ TQString b;
+ b.isEmpty(); // TRUE
+ b.isNull(); // TRUE
+ \endcode
+
+ \sa isNull(), length()
+*/
+
+/*!
+ \fn uint TQString::length() const
+
+ Returns the length of the string.
+
+ Null strings and empty strings have zero length.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ If \a newLen is less than the length of the string, then the
+ string is truncated at position \a newLen. Otherwise nothing
+ happens.
+
+ \code
+ TQString s = "truncate me";
+ s.truncate( 5 ); // s == "trunc"
+ \endcode
+
+ \sa setLength()
+*/
+
+void TQString::truncate( uint newLen )
+{
+ if ( newLen < d->len )
+ setLength( newLen );
+}
+
+/*!
+ Ensures that at least \a newLen characters are allocated to the
+ string, and sets the length of the string to \a newLen. Any new
+ space allocated tqcontains arbitrary data.
+
+ \sa reserve(), truncate()
+*/
+void TQString::setLength( uint newLen )
+{
+ if ( d->count != 1 || newLen > d->maxl ||
+ ( newLen * 4 < d->maxl && d->maxl > 4 ) ) {
+ // detach, grow or shrink
+ uint newMax = computeNewMax( newLen );
+ TQChar* nd = TQT_ALLOC_TQCHAR_VEC( newMax );
+ if ( nd ) {
+ uint len = TQMIN( d->len, newLen );
+ memcpy( nd, d->tqunicode, sizeof(TQChar) * len );
+ deref();
+ d = new TQStringData( nd, newLen, newMax );
+ }
+ } else {
+ d->len = newLen;
+ d->setDirty();
+ }
+}
+
+/*!
+ \fn uint TQString::capacity() const
+
+ Returns the number of characters this string can hold
+ in the allocated memory.
+
+ \sa reserve(), squeeze()
+*/
+
+/*!
+ Ensures that at least \a minCapacity characters are allocated to
+ the string.
+
+ This function is useful for code that needs to build up a long
+ string and wants to avoid repeated reallocation. In this example,
+ we want to add to the string until some condition is true, and
+ we're fairly sure that size is big enough:
+ \code
+ TQString result;
+ int len = 0;
+ result.reserve(maxLen);
+ while (...) {
+ result[len++] = ... // fill part of the space
+ }
+ result.squeeze();
+ \endcode
+
+ If \e maxLen is an underestimate, the worst that will happen is
+ that the loop will slow down.
+
+ If it is not possible to allocate enough memory, the string
+ remains unchanged.
+
+ \sa capacity(), squeeze(), setLength()
+*/
+
+void TQString::reserve( uint minCapacity )
+{
+ if ( d->maxl < minCapacity ) {
+ TQChar *nd = TQT_ALLOC_TQCHAR_VEC( minCapacity );
+ if ( nd ) {
+ uint len = d->len;
+ if ( len )
+ memcpy( nd, d->tqunicode, sizeof(TQChar) * len );
+ deref();
+ d = new TQStringData( nd, len, minCapacity );
+ }
+ }
+}
+
+
+/*!
+ Squeezes the string's capacity to the current content.
+
+ \sa capacity(), reserve()
+*/
+void TQString::squeeze()
+{
+ if ( d->maxl > d->len ) {
+ TQChar *nd = TQT_ALLOC_TQCHAR_VEC( d->len );
+ if ( nd ) {
+ uint len = d->len;
+ if ( len )
+ memcpy( nd, d->tqunicode, sizeof(TQChar) * len );
+ deref();
+ d = new TQStringData( nd, len, len );
+ }
+ }
+}
+
+/*!
+ \internal
+
+ Like setLength, but doesn't shrink the allocated memory.
+*/
+void TQString::grow( uint newLen )
+{
+ if ( d->count != 1 || newLen > d->maxl ) {
+ setLength( newLen );
+ } else {
+ d->len = newLen;
+ d->setDirty();
+ }
+}
+
+struct ArgEscapeData
+{
+ uint min_escape; // lowest escape sequence number
+ uint occurrences; // number of occurences of the lowest escape
+ // sequence number
+ uint locale_occurrences; // number of occurences of the lowest escape
+ // sequence number which contain 'L'
+ uint escape_len; // total length of escape sequences which will
+ // be tqreplaced
+};
+
+static ArgEscapeData tqfindArgEscapes(const TQString &s)
+{
+ const TQChar *uc_begin = s.tqunicode();
+ const TQChar *uc_end = uc_begin + s.length();
+
+ ArgEscapeData d;
+
+ d.min_escape = 10;
+ d.occurrences = 0;
+ d.escape_len = 0;
+ d.locale_occurrences = 0;
+
+ const TQChar *c = uc_begin;
+ while (c != uc_end) {
+ while (c != uc_end && c->tqunicode() != '%')
+ ++c;
+
+ if (c == uc_end || ++c == uc_end)
+ break;
+
+ bool locale_arg = FALSE;
+ if (c->tqunicode() == 'L') {
+ locale_arg = TRUE;
+ if (++c == uc_end)
+ break;
+ }
+
+ if (c->tqunicode() < '0' || c->tqunicode() > '9')
+ continue;
+
+ uint escape = c->tqunicode() - '0';
+ ++c;
+
+ if (escape > d.min_escape)
+ continue;
+
+ if (escape < d.min_escape) {
+ d.min_escape = escape;
+ d.occurrences = 0;
+ d.escape_len = 0;
+ d.locale_occurrences = 0;
+ }
+
+#if TQT_VERSION < 0x040000
+ // ### remove preprocessor in TQt 4.0
+ /* Since in TQt < 4.0 only the first instance is tqreplaced,
+ escape_len should hold the length of only the first escape
+ sequence */
+ if (d.occurrences == 0)
+#endif
+ {
+ ++d.occurrences;
+ if (locale_arg) {
+ ++d.locale_occurrences;
+ d.escape_len += 3;
+ }
+ else
+ d.escape_len += 2;
+ }
+ }
+
+ return d;
+}
+
+static TQString tqreplaceArgEscapes(const TQString &s, const ArgEscapeData &d, int field_width,
+ const TQString &arg, const TQString &larg)
+{
+ const TQChar *uc_begin = s.tqunicode();
+ const TQChar *uc_end = uc_begin + s.length();
+
+ uint abs_field_width = TQABS(field_width);
+ uint result_len = s.length()
+ - d.escape_len
+ + (d.occurrences - d.locale_occurrences)
+ *TQMAX(abs_field_width, arg.length())
+ + d.locale_occurrences
+ *TQMAX(abs_field_width, larg.length());
+
+ TQString result;
+ result.setLength(result_len);
+ TQChar *result_buff = (TQChar*) result.tqunicode();
+
+ TQChar *rc = result_buff;
+ const TQChar *c = uc_begin;
+ uint repl_cnt = 0;
+ while (c != uc_end) {
+ /* We don't have to check if we run off the end of the string with c,
+ because as long as d.occurrences > 0 we KNOW there are valid escape
+ sequences. */
+
+ const TQChar *text_start = c;
+
+ while (c->tqunicode() != '%')
+ ++c;
+
+ const TQChar *escape_start = c++;
+
+ bool locale_arg = FALSE;
+ if (c->tqunicode() == 'L') {
+ locale_arg = TRUE;
+ ++c;
+ }
+
+ if (c->tqunicode() != '0' + d.min_escape) {
+ memcpy(rc, text_start, (c - text_start)*sizeof(TQChar));
+ rc += c - text_start;
+ }
+ else {
+ ++c;
+
+ memcpy(rc, text_start, (escape_start - text_start)*sizeof(TQChar));
+ rc += escape_start - text_start;
+
+ uint pad_chars;
+ if (locale_arg)
+ pad_chars = TQMAX(abs_field_width, larg.length()) - larg.length();
+ else
+ pad_chars = TQMAX(abs_field_width, arg.length()) - arg.length();
+
+ if (field_width > 0) { // left padded
+ for (uint i = 0; i < pad_chars; ++i)
+ (rc++)->tqunicode() = ' ';
+ }
+
+ if (locale_arg) {
+ memcpy(rc, larg.tqunicode(), larg.length()*sizeof(TQChar));
+ rc += larg.length();
+ }
+ else {
+ memcpy(rc, arg.tqunicode(), arg.length()*sizeof(TQChar));
+ rc += arg.length();
+ }
+
+ if (field_width < 0) { // right padded
+ for (uint i = 0; i < pad_chars; ++i)
+ (rc++)->tqunicode() = ' ';
+ }
+
+ if (++repl_cnt == d.occurrences) {
+ memcpy(rc, c, (uc_end - c)*sizeof(TQChar));
+ rc += uc_end - c;
+ TQ_ASSERT(rc - result_buff == (int)result_len);
+ c = uc_end;
+ }
+ }
+ }
+
+ return result;
+}
+
+/*!
+ This function will return a string that tqreplaces the lowest
+ numbered occurrence of \c %1, \c %2, ..., \c %9 with \a a.
+
+ The \a fieldWidth value specifies the minimum amount of space that
+ \a a is padded to. A positive value will produce right-aligned
+ text, whereas a negative value will produce left-aligned text.
+
+ The following example shows how we could create a 'status' string
+ when processing a list of files:
+ \code
+ TQString status = TQString( "Processing file %1 of %2: %3" )
+ .arg( i ) // current file's number
+ .arg( total ) // number of files to process
+ .arg( fileName ); // current file's name
+ \endcode
+
+ It is generally fine to use filenames and numbers as we have done
+ in the example above. But note that using arg() to construct
+ natural language sentences does not usually translate well into
+ other languages because sentence structure and word order often
+ differ between languages.
+
+ If there is no place marker (\c %1, \c %2, etc.), a warning
+ message (qWarning()) is output and the result is undefined.
+
+ \warning If any placeholder occurs more than once, the result is undefined.
+
+*/
+TQString TQString::arg( const TQString& a, int fieldWidth ) const
+{
+ ArgEscapeData d = tqfindArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning( "TQString::arg(): Argument missing: %s, %s", latin1(),
+ a.latin1() );
+ return *this;
+ }
+
+ return tqreplaceArgEscapes(*this, d, fieldWidth, a, a);
+}
+
+/*!
+ \fn TQString TQString::arg( const TQString& a1, const TQString& a2 ) const
+
+ \overload
+
+ This is the same as str.arg(\a a1).arg(\a a2), except that
+ the strings are tqreplaced in one pass. This can make a difference
+ if \a a1 tqcontains e.g. \c{%1}:
+
+ \code
+ TQString str( "%1 %2" );
+ str.arg( "Hello", "world" ); // returns "Hello world"
+ str.arg( "Hello" ).arg( "world" ); // returns "Hello world"
+
+ str.arg( "(%1)", "Hello" ); // returns "(%1) Hello"
+ str.arg( "(%1)" ).arg( "Hello" ); // returns "(Hello) %2"
+ \endcode
+*/
+
+/*!
+ \fn TQString TQString::arg( const TQString& a1, const TQString& a2,
+ const TQString& a3 ) const
+ \overload
+
+ This is the same as calling str.arg(\a a1).arg(\a a2).arg(\a a3),
+ except that the strings are tqreplaced in one pass.
+*/
+
+/*!
+ \fn TQString TQString::arg( const TQString& a1, const TQString& a2,
+ const TQString& a3, const TQString& a4 ) const
+ \overload
+
+ This is the same as calling
+ str.arg(\a a1).arg(\a a2).arg(\a a3).arg(\a a4),
+ except that the strings are tqreplaced in one pass.
+*/
+
+/*!
+ \overload
+
+ The \a fieldWidth value specifies the minimum amount of space that
+ \a a is padded to. A positive value will produce a right-aligned
+ number, whereas a negative value will produce a left-aligned
+ number.
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36.
+
+ The '%' can be followed by an 'L', in which case the sequence is
+ tqreplaced with a localized representation of \a a. The conversion
+ uses the default locale. The default locale is determined from the
+ system's locale settings at application startup. It can be changed
+ using TQLocale::setDefault(). The 'L' flag is ignored if \a base is
+ not 10.
+
+ \code
+ TQString str;
+ str = TQString( "Decimal 63 is %1 in hexadecimal" )
+ .arg( 63, 0, 16 );
+ // str == "Decimal 63 is 3f in hexadecimal"
+
+ TQLocale::setDefault(TQLocale::English, TQLocale::UnitedStates);
+ str = TQString( "%1 %L2 %L3" )
+ .arg( 12345 )
+ .arg( 12345 )
+ .arg( 12345, 0, 16 );
+ // str == "12345 12,345 3039"
+ \endcode
+*/
+TQString TQString::arg( long a, int fieldWidth, int base ) const
+{
+ return arg((TQ_LLONG)a, fieldWidth, base);
+}
+
+/*!
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+TQString TQString::arg( ulong a, int fieldWidth, int base ) const
+{
+ return arg((TQ_ULLONG)a, fieldWidth, base);
+}
+
+/*!
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+TQString TQString::arg( TQ_LLONG a, int fieldWidth, int base ) const
+{
+ ArgEscapeData d = tqfindArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning( "TQString::arg(): Argument missing: %s, %lld", latin1(),
+ a );
+ return *this;
+ }
+
+ TQString arg;
+ if (d.occurrences > d.locale_occurrences)
+ arg = number(a, base);
+
+ TQString locale_arg;
+ if (d.locale_occurrences > 0) {
+ TQLocale locale;
+ locale_arg = locale.d->longLongToString(a, -1, base, -1, TQLocalePrivate::ThousandsGroup);
+ }
+
+ return tqreplaceArgEscapes(*this, d, fieldWidth, arg, locale_arg);
+}
+
+/*!
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+TQString TQString::arg( TQ_ULLONG a, int fieldWidth, int base ) const
+{
+ ArgEscapeData d = tqfindArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning( "TQString::arg(): Argument missing: %s, %llu", latin1(),
+ a );
+ return *this;
+ }
+
+ TQString arg;
+ if (d.occurrences > d.locale_occurrences)
+ arg = number(a, base);
+
+ TQString locale_arg;
+ if (d.locale_occurrences > 0) {
+ TQLocale locale;
+ locale_arg = locale.d->unsLongLongToString(a, -1, base, -1, TQLocalePrivate::ThousandsGroup);
+ }
+
+ return tqreplaceArgEscapes(*this, d, fieldWidth, arg, locale_arg);
+}
+
+/*!
+ \fn TQString TQString::arg( int a, int fieldWidth, int base ) const
+
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+
+/*!
+ \fn TQString TQString::arg( uint a, int fieldWidth, int base ) const
+
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+
+/*!
+ \fn TQString TQString::arg( short a, int fieldWidth, int base ) const
+
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+
+/*!
+ \fn TQString TQString::arg( ushort a, int fieldWidth, int base ) const
+
+ \overload
+
+ \a a is expressed in base \a base, which is 10 by default and must
+ be between 2 and 36. If \a base is 10, the '%L' syntax can be used
+ to produce localized strings.
+*/
+
+
+/*!
+ \overload
+
+ \a a is assumed to be in the Latin-1 character set.
+*/
+TQString TQString::arg( char a, int fieldWidth ) const
+{
+ TQString c;
+ c += a;
+ return arg( c, fieldWidth );
+}
+
+/*!
+ \overload
+*/
+TQString TQString::arg( TQChar a, int fieldWidth ) const
+{
+ TQString c;
+ c += a;
+ return arg( c, fieldWidth );
+}
+
+/*!
+ \overload
+
+ \target arg-formats
+
+ Argument \a a is formatted according to the \a fmt format specified,
+ which is 'g' by default and can be any of the following:
+
+ \table
+ \header \i Format \i Meaning
+ \row \i \c e \i format as [-]9.9e[+|-]999
+ \row \i \c E \i format as [-]9.9E[+|-]999
+ \row \i \c f \i format as [-]9.9
+ \row \i \c g \i use \c e or \c f format, whichever is the most concise
+ \row \i \c G \i use \c E or \c f format, whichever is the most concise
+ \endtable
+
+ With 'e', 'E', and 'f', \a prec is the number of digits after the
+ decimal point. With 'g' and 'G', \a prec is the maximum number of
+ significant digits (trailing zeroes are omitted).
+
+ \code
+ double d = 12.34;
+ TQString ds = TQString( "'E' format, precision 3, gives %1" )
+ .arg( d, 0, 'E', 3 );
+ // ds == "'E' format, precision 3, gives 1.234E+01"
+ \endcode
+
+ The '%L' syntax can be used to produce localized strings.
+*/
+TQString TQString::arg( double a, int fieldWidth, char fmt, int prec ) const
+{
+ ArgEscapeData d = tqfindArgEscapes(*this);
+
+ if (d.occurrences == 0) {
+ qWarning( "TQString::arg(): Argument missing: %s, %g", latin1(),
+ a );
+ return *this;
+ }
+
+ TQString arg;
+ if (d.occurrences > d.locale_occurrences)
+ arg = number(a, fmt, prec);
+
+ TQString locale_arg;
+ if (d.locale_occurrences > 0) {
+ TQLocale locale;
+
+ TQLocalePrivate::DoubleForm form = TQLocalePrivate::DFDecimal;
+ uint flags = 0;
+
+ if (qIsUpper(fmt))
+ flags = TQLocalePrivate::CapitalEorX;
+ fmt = qToLower(fmt);
+
+ switch (fmt) {
+ case 'f':
+ form = TQLocalePrivate::DFDecimal;
+ break;
+ case 'e':
+ form = TQLocalePrivate::DFExponent;
+ break;
+ case 'g':
+ form = TQLocalePrivate::DFSignificantDigits;
+ break;
+ default:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQString::setNum: Invalid format char '%c'", fmt );
+#endif
+ break;
+ }
+
+ flags |= TQLocalePrivate::ThousandsGroup;
+
+ locale_arg = locale.d->doubleToString(a, prec, form, -1, flags);
+ }
+
+ return tqreplaceArgEscapes(*this, d, fieldWidth, arg, locale_arg);
+}
+
+TQString TQString::multiArg( int numArgs, const TQString& a1, const TQString& a2,
+ const TQString& a3, const TQString& a4 ) const
+{
+ TQString result;
+ union {
+ int digitUsed[10];
+ int argForDigit[10];
+ };
+ register const TQChar *uc = d->tqunicode;
+ const TQString *args[4];
+ const int len = (int) length();
+ const int end = len - 1;
+ int lastDigit = -1;
+ int i;
+
+ memset( digitUsed, 0, sizeof(digitUsed) );
+ args[0] = &a1;
+ args[1] = &a2;
+ args[2] = &a3;
+ args[3] = &a4;
+
+ for ( i = 0; i < end; i++ ) {
+ if ( uc[i] == '%' ) {
+ int digit = uc[i + 1].tqunicode() - '0';
+ if ( digit >= 0 && digit <= 9 )
+ digitUsed[digit]++;
+ }
+ }
+
+ for ( i = 0; i < numArgs; i++ ) {
+ do {
+ ++lastDigit;
+ } while ( lastDigit < 10 && digitUsed[lastDigit] == 0 );
+
+ if ( lastDigit == 10 ) {
+ qWarning( "TQString::arg(): Argument missing: %s, %s",
+ latin1(), args[i]->latin1() );
+ numArgs = i;
+ lastDigit = 9;
+ break;
+ }
+ argForDigit[lastDigit] = i;
+ }
+
+ i = 0;
+ while ( i < len ) {
+ if ( uc[i] == '%' && i != end ) {
+ int digit = uc[i + 1].tqunicode() - '0';
+ if ( digit >= 0 && digit <= lastDigit ) {
+ result += *args[argForDigit[digit]];
+ i += 2;
+ continue;
+ }
+ }
+ result += uc[i++];
+ }
+ return result;
+}
+
+
+/*!
+ Safely builds a formatted string from the format string \a cformat
+ and an arbitrary list of arguments. The format string supports all
+ the escape sequences of printf() in the standard C library.
+
+ The %s escape sequence expects a utf8() encoded string. The format
+ string \e cformat is expected to be in latin1. If you need a
+ Unicode format string, use arg() instead. For typesafe string
+ building, with full Unicode support, you can use TQTextOStream like
+ this:
+
+ \code
+ TQString str;
+ TQString s = ...;
+ int x = ...;
+ TQTextOStream( &str ) << s << " : " << x;
+ \endcode
+
+ For \link TQObject::tr() translations,\endlink especially if the
+ strings tqcontains more than one escape sequence, you should
+ consider using the arg() function instead. This allows the order
+ of the tqreplacements to be controlled by the translator, and has
+ Unicode support.
+
+ The %lc escape sequence expects a tqunicode character of type ushort
+ (as returned by TQChar::tqunicode()).
+ The %ls escape sequence expects a pointer to a zero-terminated
+ array of tqunicode characters of type ushort (as returned by
+ TQString::ucs2()).
+
+ \sa arg()
+*/
+
+#ifndef TQT_NO_SPRINTF
+TQString &TQString::sprintf( const char* cformat, ... )
+{
+ TQLocale locale(TQLocale::C);
+
+ va_list ap;
+ va_start( ap, cformat );
+
+ if ( !cformat || !*cformat ) {
+ // TQt 1.x compat
+ *this = tqfromLatin1( "" );
+ return *this;
+ }
+
+ // Parse cformat
+
+ TQString result;
+ const char *c = cformat;
+ for (;;) {
+ // Copy non-escape chars to result
+ while (*c != '\0' && *c != '%')
+ result.append(*c++);
+
+ if (*c == '\0')
+ break;
+
+ // Found '%'
+ const char *escape_start = c;
+ ++c;
+
+ if (*c == '\0') {
+ result.append('%'); // a % at the end of the string - treat as non-escape text
+ break;
+ }
+ if (*c == '%') {
+ result.append('%'); // %%
+ ++c;
+ continue;
+ }
+
+ // Parse flag characters
+ unsigned flags = 0;
+ bool no_more_flags = FALSE;
+ do {
+ switch (*c) {
+ case '#': flags |= TQLocalePrivate::Alternate; break;
+ case '0': flags |= TQLocalePrivate::ZeroPadded; break;
+ case '-': flags |= TQLocalePrivate::LeftAdjusted; break;
+ case ' ': flags |= TQLocalePrivate::BlankBeforePositive; break;
+ case '+': flags |= TQLocalePrivate::AlwaysShowSign; break;
+ case '\'': flags |= TQLocalePrivate::ThousandsGroup; break;
+ default: no_more_flags = TRUE; break;
+ }
+
+ if (!no_more_flags)
+ ++c;
+ } while (!no_more_flags);
+
+ if (*c == '\0') {
+ result.append(escape_start); // incomplete escape, treat as non-escape text
+ break;
+ }
+
+ // Parse field width
+ int width = -1; // -1 means unspecified
+ if (qIsDigit(*c)) {
+ TQString width_str;
+ while (*c != '\0' && qIsDigit(*c))
+ width_str.append(*c++);
+
+ // can't be negative - started with a digit
+ // tqcontains at least one digit
+ width = width_str.toInt();
+ }
+ else if (*c == '*') {
+ width = va_arg(ap, int);
+ if (width < 0)
+ width = -1; // treat all negative numbers as unspecified
+ ++c;
+ }
+
+ if (*c == '\0') {
+ result.append(escape_start); // incomplete escape, treat as non-escape text
+ break;
+ }
+
+ // Parse precision
+ int precision = -1; // -1 means unspecified
+ if (*c == '.') {
+ ++c;
+ if (qIsDigit(*c)) {
+ TQString precision_str;
+ while (*c != '\0' && qIsDigit(*c))
+ precision_str.append(*c++);
+
+ // can't be negative - started with a digit
+ // tqcontains at least one digit
+ precision = precision_str.toInt();
+ }
+ else if (*c == '*') {
+ precision = va_arg(ap, int);
+ if (precision < 0)
+ precision = -1; // treat all negative numbers as unspecified
+ ++c;
+ }
+ }
+
+ if (*c == '\0') {
+ result.append(escape_start); // incomplete escape, treat as non-escape text
+ break;
+ }
+
+ // Parse the length modifier
+ enum LengthMod { lm_none, lm_hh, lm_h, lm_l, lm_ll, lm_L, lm_j, lm_z, lm_t };
+ LengthMod length_mod = lm_none;
+ switch (*c) {
+ case 'h':
+ ++c;
+ if (*c == 'h') {
+ length_mod = lm_hh;
+ ++c;
+ }
+ else
+ length_mod = lm_h;
+ break;
+
+ case 'l':
+ ++c;
+ if (*c == 'l') {
+ length_mod = lm_ll;
+ ++c;
+ }
+ else
+ length_mod = lm_l;
+ break;
+
+ case 'L':
+ ++c;
+ length_mod = lm_L;
+ break;
+
+ case 'j':
+ ++c;
+ length_mod = lm_j;
+ break;
+
+ case 'z':
+ case 'Z':
+ ++c;
+ length_mod = lm_z;
+ break;
+
+ case 't':
+ ++c;
+ length_mod = lm_t;
+ break;
+
+ default: break;
+ }
+
+ if (*c == '\0') {
+ result.append(escape_start); // incomplete escape, treat as non-escape text
+ break;
+ }
+
+ // Parse the conversion specifier and do the conversion
+ TQString subst;
+ switch (*c) {
+ case 'd':
+ case 'i': {
+ TQ_LLONG i;
+ switch (length_mod) {
+ case lm_none: i = va_arg(ap, int); break;
+ case lm_hh: i = va_arg(ap, int); break;
+ case lm_h: i = va_arg(ap, int); break;
+ case lm_l: i = va_arg(ap, long int); break;
+ case lm_ll: i = va_arg(ap, TQ_LLONG); break;
+ case lm_j: i = va_arg(ap, long int); break;
+ case lm_z: i = va_arg(ap, size_t); break;
+ case lm_t: i = va_arg(ap, int); break;
+ default: i = 0; break;
+ }
+ subst = locale.d->longLongToString(i, precision, 10, width, flags);
+ ++c;
+ break;
+ }
+ case 'o':
+ case 'u':
+ case 'x':
+ case 'X': {
+ TQ_ULLONG u;
+ switch (length_mod) {
+ case lm_none: u = va_arg(ap, unsigned int); break;
+ case lm_hh: u = va_arg(ap, unsigned int); break;
+ case lm_h: u = va_arg(ap, unsigned int); break;
+ case lm_l: u = va_arg(ap, unsigned long int); break;
+ case lm_ll: u = va_arg(ap, TQ_ULLONG); break;
+ default: u = 0; break;
+ }
+
+ if (qIsUpper(*c))
+ flags |= TQLocalePrivate::CapitalEorX;
+
+ int base = 10;
+ switch (qToLower(*c)) {
+ case 'o':
+ base = 8; break;
+ case 'u':
+ base = 10; break;
+ case 'x':
+ base = 16; break;
+ default: break;
+ }
+ subst = locale.d->unsLongLongToString(u, precision, base, width, flags);
+ ++c;
+ break;
+ }
+ case 'E':
+ case 'e':
+ case 'F':
+ case 'f':
+ case 'G':
+ case 'g':
+ case 'A':
+ case 'a': {
+ double d;
+ if (length_mod == lm_L)
+ d = va_arg(ap, long double); // not supported - converted to a double
+ else
+ d = va_arg(ap, double);
+
+ if (qIsUpper(*c))
+ flags |= TQLocalePrivate::CapitalEorX;
+
+ TQLocalePrivate::DoubleForm form = TQLocalePrivate::DFDecimal;
+ switch (qToLower(*c)) {
+ case 'e': form = TQLocalePrivate::DFExponent; break;
+ case 'a': // not supported - decimal form used instead
+ case 'f': form = TQLocalePrivate::DFDecimal; break;
+ case 'g': form = TQLocalePrivate::DFSignificantDigits; break;
+ default: break;
+ }
+ subst = locale.d->doubleToString(d, precision, form, width, flags);
+ ++c;
+ break;
+ }
+ case 'c': {
+ if (length_mod == lm_l)
+ subst = TQChar((ushort) va_arg(ap, int));
+ else
+ subst = (uchar) va_arg(ap, int);
+ ++c;
+ break;
+ }
+ case 's': {
+ if (length_mod == lm_l) {
+ const ushort *buff = va_arg(ap, const ushort*);
+ const ushort *ch = buff;
+ while (*ch != 0)
+ ++ch;
+ subst.setUnicodeCodes(buff, ch - buff);
+ } else
+ subst = TQString::fromUtf8(va_arg(ap, const char*));
+ if (precision != -1)
+ subst.truncate(precision);
+ ++c;
+ break;
+ }
+ case 'p': {
+ TQ_ULLONG i;
+#ifdef TQ_OS_WIN64
+ i = (TQ_ULLONG) va_arg(ap, void*);
+#else
+ i = (TQ_ULONG) va_arg(ap, void*);
+#endif
+
+#ifdef TQ_OS_WIN32
+ flags |= TQLocalePrivate::CapitalEorX; // Windows does 1234ABCD
+#else
+ flags |= TQLocalePrivate::Alternate; // Unix and Mac do 0x1234abcd
+#endif
+
+ subst = locale.d->unsLongLongToString(i, precision, 16, width, flags);
+ ++c;
+ break;
+ }
+ case 'n':
+ switch (length_mod) {
+ case lm_hh: {
+ signed char *n = va_arg(ap, signed char*);
+ *n = result.length();
+ break;
+ }
+ case lm_h: {
+ short int *n = va_arg(ap, short int*);
+ *n = result.length();
+ break;
+ }
+ case lm_l: {
+ long int *n = va_arg(ap, long int*);
+ *n = result.length();
+ break;
+ }
+ case lm_ll: {
+ TQ_LLONG *n = va_arg(ap, TQ_LLONG*);
+ volatile uint tmp = result.length(); // egcs-2.91.66 gets internal
+ *n = tmp; // compiler error without volatile
+ break;
+ }
+ default: {
+ int *n = va_arg(ap, int*);
+ *n = result.length();
+ break;
+ }
+ }
+ ++c;
+ break;
+
+ default: // bad escape, treat as non-escape text
+ for (const char *cc = escape_start; cc != c; ++cc)
+ result.append(*cc);
+ continue;
+ }
+
+ if (flags & TQLocalePrivate::LeftAdjusted)
+ result.append(subst.leftJustify(width));
+ else
+ result.append(subst.rightJustify(width));
+ }
+
+ va_end(ap);
+ *this = result;
+
+ return *this;
+}
+#endif
+
+/*!
+ Fills the string with \a len characters of value \a c, and returns
+ a reference to the string.
+
+ If \a len is negative (the default), the current string length is
+ used.
+
+ \code
+ TQString str;
+ str.fill( 'g', 5 ); // string == "ggggg"
+ \endcode
+*/
+
+TQString& TQString::fill( TQChar c, int len )
+{
+ if ( len < 0 )
+ len = length();
+ if ( len == 0 ) {
+ *this = "";
+ } else {
+ deref();
+ TQChar * nd = TQT_ALLOC_TQCHAR_VEC( len );
+ d = new TQStringData(nd,len,len);
+ while (len--) *nd++ = c;
+ }
+ return *this;
+}
+
+
+/*!
+ \fn TQString TQString::copy() const
+
+ \obsolete
+
+ In TQt 2.0 and later, all calls to this function are needless. Just
+ remove them.
+*/
+
+/*!
+ \overload
+
+ Finds the first occurrence of the character \a c, starting at
+ position \a index. If \a index is -1, the search starts at the
+ last character; if -2, at the next to last character and so on.
+ (See tqfindRev() for searching backwards.)
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ Returns the position of \a c or -1 if \a c could not be found.
+*/
+
+int TQString::tqfind( TQChar c, int index, bool cs ) const
+{
+ const uint l = length();
+ if ( index < 0 )
+ index += l;
+ if ( (uint)index >= l )
+ return -1;
+ register const TQChar *uc = tqunicode()+index;
+ const TQChar *end = tqunicode() + l;
+ if ( cs ) {
+ while ( uc < end && *uc != c )
+ uc++;
+ } else {
+ c = ::lower( c );
+ while ( uc < end && ::lower( *uc ) != c )
+ uc++;
+ }
+ if ( uint(uc - tqunicode()) >= l )
+ return -1;
+ return (int)(uc - tqunicode());
+}
+
+/* an implementation of the Boyer-Moore search algorithm
+*/
+
+/* initializes the skiptable to know haw far ahead we can skip on a wrong match
+*/
+static void bm_init_skiptable( const TQString &pattern, uint *skiptable, bool cs )
+{
+ int i = 0;
+ register uint *st = skiptable;
+ int l = pattern.length();
+ while ( i++ < 0x100/8 ) {
+ *(st++) = l;
+ *(st++) = l;
+ *(st++) = l;
+ *(st++) = l;
+ *(st++) = l;
+ *(st++) = l;
+ *(st++) = l;
+ *(st++) = l;
+ }
+ const TQChar *uc = pattern.tqunicode();
+ if ( cs ) {
+ while ( l-- ) {
+ skiptable[ uc->cell() ] = l;
+ uc++;
+ }
+ } else {
+ while ( l-- ) {
+ skiptable[ ::lower( *uc ).cell() ] = l;
+ uc++;
+ }
+ }
+}
+
+static int bm_tqfind( const TQString &str, int index, const TQString &pattern, uint *skiptable, bool cs )
+{
+ const uint l = str.length();
+ if ( pattern.isEmpty() )
+ return index > (int)l ? -1 : index;
+
+ const TQChar *uc = str.tqunicode();
+ const TQChar *puc = pattern.tqunicode();
+ const uint pl = pattern.length();
+ const uint pl_minus_one = pl - 1;
+
+ register const TQChar *current = uc + index + pl_minus_one;
+ const TQChar *end = uc + l;
+ if ( cs ) {
+ while ( current < end ) {
+ uint skip = skiptable[ current->cell() ];
+ if ( !skip ) {
+ // possible match
+ while ( skip < pl ) {
+ if ( *(current - skip ) != puc[pl_minus_one-skip] )
+ break;
+ skip++;
+ }
+ if ( skip > pl_minus_one ) { // we have a match
+ return (current - uc) - skip + 1;
+ }
+ // in case we don't have a match we are a bit inefficient as we only skip by one
+ // when we have the non matching char in the string.
+ if ( skiptable[ (current-skip)->cell() ] == pl )
+ skip = pl - skip;
+ else
+ skip = 1;
+ }
+ current += skip;
+ }
+ } else {
+ while ( current < end ) {
+ uint skip = skiptable[ ::lower( *current ).cell() ];
+ if ( !skip ) {
+ // possible match
+ while ( skip < pl ) {
+ if ( ::lower( *(current - skip) ) != ::lower( puc[pl_minus_one-skip] ) )
+ break;
+ skip++;
+ }
+ if ( skip > pl_minus_one ) // we have a match
+ return (current - uc) - skip + 1;
+ // in case we don't have a match we are a bit inefficient as we only skip by one
+ // when we have the non matching char in the string.
+ if ( skiptable[ ::lower(*(current - skip)).cell() ] == pl )
+ skip = pl - skip;
+ else
+ skip = 1;
+ }
+ current += skip;
+ }
+ }
+ // not found
+ return -1;
+}
+
+
+#define REHASH( a ) \
+ if ( sl_minus_1 < sizeof(uint) * CHAR_BIT ) \
+ hashHaystack -= (a) << sl_minus_1; \
+ hashHaystack <<= 1
+
+/*!
+ \overload
+
+ Finds the first occurrence of the string \a str, starting at
+ position \a index. If \a index is -1, the search starts at the
+ last character, if it is -2, at the next to last character and so
+ on. (See tqfindRev() for searching backwards.)
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ Returns the position of \a str or -1 if \a str could not be found.
+*/
+
+int TQString::tqfind( const TQString& str, int index, bool cs ) const
+{
+ const uint l = length();
+ const uint sl = str.length();
+ if ( index < 0 )
+ index += l;
+ if ( sl + index > l )
+ return -1;
+ if ( !sl )
+ return index;
+ if (!l)
+ return -1;
+
+#if defined(TQ_OS_MACX) && defined(TQT_MACOSX_VERSION) && TQT_MACOSX_VERSION >= 0x1020
+ if ( sl == 1 )
+ return tqfind( *str.tqunicode(), index, cs );
+#endif
+
+ // we use the Boyer-Moore algorithm in cases where the overhead
+ // for the hash table should pay off, otherwise we use a simple
+ // hash function
+ if ( l > 500 && sl > 5 ) {
+ uint skiptable[0x100];
+ bm_init_skiptable( str, skiptable, cs );
+ return bm_tqfind( *this, index, str, skiptable, cs );
+ }
+
+ /*
+ We use some hashing for efficiency's sake. Instead of
+ comparing strings, we compare the hash value of str with that of
+ a part of this TQString. Only if that matches, we call ucstrncmp
+ or ucstrnicmp.
+ */
+ const TQChar* needle = str.tqunicode();
+ const TQChar* haystack = tqunicode() + index;
+ const TQChar* end = tqunicode() + (l-sl);
+ const uint sl_minus_1 = sl-1;
+ uint hashNeedle = 0, hashHaystack = 0, i;
+
+ if ( cs ) {
+ for ( i = 0; i < sl; ++i ) {
+ hashNeedle = ((hashNeedle<<1) + needle[i].tqunicode() );
+ hashHaystack = ((hashHaystack<<1) + haystack[i].tqunicode() );
+ }
+ hashHaystack -= (haystack+sl_minus_1)->tqunicode();
+
+ while ( haystack <= end ) {
+ hashHaystack += (haystack+sl_minus_1)->tqunicode();
+ if ( hashHaystack == hashNeedle
+ && ucstrncmp( needle, haystack, sl ) == 0 )
+ return haystack-tqunicode();
+
+ REHASH( haystack->tqunicode() );
+ ++haystack;
+ }
+ } else {
+ for ( i = 0; i < sl; ++i ) {
+ hashNeedle = ((hashNeedle<<1) +
+ ::lower( needle[i].tqunicode() ).tqunicode() );
+ hashHaystack = ((hashHaystack<<1) +
+ ::lower( haystack[i].tqunicode() ).tqunicode() );
+ }
+
+ hashHaystack -= ::lower(*(haystack+sl_minus_1)).tqunicode();
+ while ( haystack <= end ) {
+ hashHaystack += ::lower(*(haystack+sl_minus_1)).tqunicode();
+ if ( hashHaystack == hashNeedle
+ && ucstrnicmp( needle, haystack, sl ) == 0 )
+ return haystack-tqunicode();
+
+ REHASH( ::lower(*haystack).tqunicode() );
+ ++haystack;
+ }
+ }
+ return -1;
+}
+
+/*!
+ \fn int TQString::tqfindRev( const char* str, int index ) const
+
+ Equivalent to tqfindRev(TQString(\a str), \a index).
+*/
+
+/*!
+ \fn int TQString::tqfind( const char* str, int index ) const
+
+ \overload
+
+ Equivalent to tqfind(TQString(\a str), \a index).
+*/
+
+/*!
+ \overload
+
+ Finds the first occurrence of the character \a c, starting at
+ position \a index and searching backwards. If the index is -1, the
+ search starts at the last character, if it is -2, at the next to
+ last character and so on.
+
+ Returns the position of \a c or -1 if \a c could not be found.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ \code
+ TQString string( "bananas" );
+ int i = string.tqfindRev( 'a' ); // i == 5
+ \endcode
+*/
+
+int TQString::tqfindRev( TQChar c, int index, bool cs ) const
+{
+#if defined(TQ_OS_MACX) && defined(TQT_MACOSX_VERSION) && TQT_MACOSX_VERSION < 0x1020
+ return tqfindRev( TQString( c ), index, cs );
+#else
+ const uint l = length();
+ if ( index < 0 )
+ index += l;
+ if ( (uint)index >= l )
+ return -1;
+ const TQChar *end = tqunicode();
+ register const TQChar *uc = end + index;
+ if ( cs ) {
+ while ( uc >= end && *uc != c )
+ uc--;
+ } else {
+ c = ::lower( c );
+ while ( uc >= end && ::lower( *uc ) != c )
+ uc--;
+ }
+ return uc - end;
+#endif
+}
+
+/*!
+ \overload
+
+ Finds the first occurrence of the string \a str, starting at
+ position \a index and searching backwards. If the index is -1, the
+ search starts at the last character, if it is -2, at the next to
+ last character and so on.
+
+ Returns the position of \a str or -1 if \a str could not be found.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ \code
+ TQString string("bananas");
+ int i = string.tqfindRev( "ana" ); // i == 3
+ \endcode
+*/
+
+int TQString::tqfindRev( const TQString& str, int index, bool cs ) const
+{
+ /*
+ See TQString::tqfind() for explanations.
+ */
+ const uint l = length();
+ if ( index < 0 )
+ index += l;
+ const uint sl = str.length();
+ int delta = l-sl;
+ if ( index < 0 || index > (int)l || delta < 0 )
+ return -1;
+ if ( index > delta )
+ index = delta;
+
+#if defined(TQ_OS_MACX) && defined(TQT_MACOSX_VERSION) && TQT_MACOSX_VERSION >= 0x1020
+ if ( sl == 1 )
+ return tqfindRev( *str.tqunicode(), index, cs );
+#endif
+
+ const TQChar* needle = str.tqunicode();
+ const TQChar* haystack = tqunicode() + index;
+ const TQChar* end = tqunicode();
+ const uint sl_minus_1 = sl-1;
+ const TQChar* n = needle+sl_minus_1;
+ const TQChar* h = haystack+sl_minus_1;
+ uint hashNeedle = 0, hashHaystack = 0, i;
+
+ if ( cs ) {
+ for ( i = 0; i < sl; ++i ) {
+ hashNeedle = ((hashNeedle<<1) + (n-i)->tqunicode() );
+ hashHaystack = ((hashHaystack<<1) + (h-i)->tqunicode() );
+ }
+ hashHaystack -= haystack->tqunicode();
+
+ while ( haystack >= end ) {
+ hashHaystack += haystack->tqunicode();
+ if ( hashHaystack == hashNeedle
+ && ucstrncmp( needle, haystack, sl ) == 0 )
+ return haystack-tqunicode();
+ --haystack;
+ REHASH( (haystack+sl)->tqunicode() );
+ }
+ } else {
+ for ( i = 0; i < sl; ++i ) {
+ hashNeedle = ((hashNeedle<<1)
+ + ::lower( (n-i)->tqunicode() ).tqunicode() );
+ hashHaystack = ((hashHaystack<<1)
+ + ::lower( (h-i)->tqunicode() ).tqunicode() );
+ }
+ hashHaystack -= ::lower(*haystack).tqunicode();
+
+ while ( haystack >= end ) {
+ hashHaystack += ::lower(*haystack).tqunicode();
+ if ( hashHaystack == hashNeedle
+ && ucstrnicmp( needle, haystack, sl ) == 0 )
+ return haystack-tqunicode();
+ --haystack;
+ REHASH( ::lower(*(haystack+sl)).tqunicode() );
+ }
+ }
+ return -1;
+}
+
+#undef REHASH
+
+/*!
+ \enum TQString::SectionFlags
+
+ \value SectionDefault Empty fields are counted, leading and
+ trailing separators are not included, and the separator is
+ compared case sensitively.
+
+ \value SectionSkipEmpty Treat empty fields as if they don't exist,
+ i.e. they are not considered as far as \e start and \e end are
+ concerned.
+
+ \value SectionIncludeLeadingSep Include the leading separator (if
+ any) in the result string.
+
+ \value SectionIncludeTrailingSep Include the trailing separator
+ (if any) in the result string.
+
+ \value SectionCaseInsensitiveSeps Compare the separator
+ case-insensitively.
+
+ Any of the last four values can be OR-ed together to form a flag.
+
+ \sa section()
+*/
+
+/*!
+ \fn TQString TQString::section( TQChar sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const
+
+ This function returns a section of the string.
+
+ This string is treated as a sequence of fields separated by the
+ character, \a sep. The returned string consists of the fields from
+ position \a start to position \a end inclusive. If \a end is not
+ specified, all fields from position \a start to the end of the
+ string are included. Fields are numbered 0, 1, 2, etc., counting
+ from the left, and -1, -2, etc., counting from right to left.
+
+ The \a flags argument can be used to affect some aspects of the
+ function's behaviour, e.g. whether to be case sensitive, whether
+ to skip empty fields and how to deal with leading and trailing
+ separators; see \l{SectionFlags}.
+
+ \code
+ TQString csv( "forename,middlename,surname,phone" );
+ TQString s = csv.section( ',', 2, 2 ); // s == "surname"
+
+ TQString path( "/usr/local/bin/myapp" ); // First field is empty
+ TQString s = path.section( '/', 3, 4 ); // s == "bin/myapp"
+ TQString s = path.section( '/', 3, 3, SectionSkipEmpty ); // s == "myapp"
+ \endcode
+
+ If \a start or \a end is negative, we count fields from the right
+ of the string, the right-most field being -1, the one from
+ right-most field being -2, and so on.
+
+ \code
+ TQString csv( "forename,middlename,surname,phone" );
+ TQString s = csv.section( ',', -3, -2 ); // s == "middlename,surname"
+
+ TQString path( "/usr/local/bin/myapp" ); // First field is empty
+ TQString s = path.section( '/', -1 ); // s == "myapp"
+ \endcode
+
+ \sa TQStringList::split()
+*/
+
+/*!
+ \overload
+
+ This function returns a section of the string.
+
+ This string is treated as a sequence of fields separated by the
+ string, \a sep. The returned string consists of the fields from
+ position \a start to position \a end inclusive. If \a end is not
+ specified, all fields from position \a start to the end of the
+ string are included. Fields are numbered 0, 1, 2, etc., counting
+ from the left, and -1, -2, etc., counting from right to left.
+
+ The \a flags argument can be used to affect some aspects of the
+ function's behaviour, e.g. whether to be case sensitive, whether
+ to skip empty fields and how to deal with leading and trailing
+ separators; see \l{SectionFlags}.
+
+ \code
+ TQString data( "forename**middlename**surname**phone" );
+ TQString s = data.section( "**", 2, 2 ); // s == "surname"
+ \endcode
+
+ If \a start or \a end is negative, we count fields from the right
+ of the string, the right-most field being -1, the one from
+ right-most field being -2, and so on.
+
+ \code
+ TQString data( "forename**middlename**surname**phone" );
+ TQString s = data.section( "**", -3, -2 ); // s == "middlename**surname"
+ \endcode
+
+ \sa TQStringList::split()
+*/
+
+TQString TQString::section( const TQString &sep, int start, int end, int flags ) const
+{
+ TQStringList sections = TQStringList::split(sep, *this, TRUE);
+ if(sections.isEmpty())
+ return TQString();
+ if(!(flags & SectionSkipEmpty)) {
+ if(start < 0)
+ start += int(sections.count());
+ if(end < 0)
+ end += int(sections.count());
+ } else {
+ int skip = 0;
+ for(TQStringList::Iterator it = sections.begin(); it != sections.end(); ++it) {
+ if((*it).isEmpty())
+ skip++;
+ }
+ if(start < 0)
+ start += int(sections.count()) - skip;
+ if(end < 0)
+ end += int(sections.count()) - skip;
+ }
+ int x = 0, run = 0;
+ TQString ret;
+ for(TQStringList::Iterator it = sections.begin(); x <= end && it != sections.end(); ++it) {
+ if(x >= start) {
+ if((*it).isEmpty()) {
+ run++;
+ } else {
+ if(!ret.isEmpty() || !(flags & SectionSkipEmpty)) {
+ int i_end = run;
+ if(!ret.isEmpty() && !(flags & SectionIncludeTrailingSep))
+ i_end++;
+ if((flags & SectionIncludeLeadingSep) && it != sections.begin() && x == start)
+ i_end++;
+ for(int i = 0; i < i_end; i++)
+ ret += sep;
+ } else if((flags & SectionIncludeLeadingSep) && it != sections.begin()) {
+ ret += sep;
+ }
+ run = 0;
+ ret += (*it);
+ if((flags & SectionIncludeTrailingSep) && it != sections.end())
+ ret += sep;
+ }
+ }
+ if(!(*it).isEmpty() || !(flags & SectionSkipEmpty))
+ x++;
+ }
+ return ret;
+}
+
+#ifndef TQT_NO_REGEXP
+class section_chunk {
+public:
+ section_chunk(int l, TQString s) { length = l; string = s; }
+ int length;
+ TQString string;
+};
+/*!
+ \overload
+
+ This function returns a section of the string.
+
+ This string is treated as a sequence of fields separated by the
+ regular expression, \a reg. The returned string consists of the
+ fields from position \a start to position \a end inclusive. If \a
+ end is not specified, all fields from position \a start to the end
+ of the string are included. Fields are numbered 0, 1, 2, etc., counting
+ from the left, and -1, -2, etc., counting from right to left.
+
+ The \a flags argument can be used to affect some aspects of the
+ function's behaviour, e.g. whether to be case sensitive, whether
+ to skip empty fields and how to deal with leading and trailing
+ separators; see \l{SectionFlags}.
+
+ \code
+ TQString line( "forename\tmiddlename surname \t \t phone" );
+ TQRegExp sep( "\s+" );
+ TQString s = line.section( sep, 2, 2 ); // s == "surname"
+ \endcode
+
+ If \a start or \a end is negative, we count fields from the right
+ of the string, the right-most field being -1, the one from
+ right-most field being -2, and so on.
+
+ \code
+ TQString line( "forename\tmiddlename surname \t \t phone" );
+ TQRegExp sep( "\\s+" );
+ TQString s = line.section( sep, -3, -2 ); // s == "middlename surname"
+ \endcode
+
+ \warning Using this TQRegExp version is much more expensive than
+ the overloaded string and character versions.
+
+ \sa TQStringList::split() simplifyWhiteSpace()
+*/
+
+TQString TQString::section( const TQRegExp &reg, int start, int end, int flags ) const
+{
+ const TQChar *uc = tqunicode();
+ if(!uc)
+ return TQString();
+
+ TQRegExp sep(reg);
+ sep.setCaseSensitive(!(flags & SectionCaseInsensitiveSeps));
+
+ TQPtrList<section_chunk> l;
+ l.setAutoDelete(TRUE);
+ int n = length(), m = 0, last_m = 0, last = 0, last_len = 0;
+
+ while ( ( m = sep.search( *this, m ) ) != -1 ) {
+ l.append(new section_chunk(last_len, TQString(uc + last_m, m - last_m)));
+ last_m = m;
+ last_len = sep.matchedLength();
+ if((m += TQMAX(sep.matchedLength(), 1)) >= n) {
+ last = 1;
+ break;
+ }
+ }
+ if(!last)
+ l.append(new section_chunk(last_len, TQString(uc + last_m, n - last_m)));
+
+ if(start < 0)
+ start = l.count() + start;
+ if(end == -1)
+ end = l.count();
+ else if(end < 0)
+ end = l.count() + end;
+
+ int i = 0;
+ TQString ret;
+ for ( section_chunk *chk=l.first(); chk; chk=l.next(), i++ ) {
+ if((flags & SectionSkipEmpty) && chk->length == (int)chk->string.length()) {
+ if(i <= start)
+ start++;
+ end++;
+ }
+ if(i == start) {
+ ret = (flags & SectionIncludeLeadingSep) ? chk->string : chk->string.mid(chk->length);
+ } else if(i > start) {
+ ret += chk->string;
+ }
+ if(i == end) {
+ if((chk=l.next()) && flags & SectionIncludeTrailingSep)
+ ret += chk->string.left(chk->length);
+ break;
+ }
+ }
+ return ret;
+}
+#endif
+
+/*!
+ \fn TQString TQString::section( char sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const
+
+ \overload
+*/
+
+/*!
+ \fn TQString TQString::section( const char *sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const
+
+ \overload
+*/
+
+
+/*!
+ Returns the number of times the character \a c occurs in the
+ string.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ \code
+ TQString string( "Trolltech and TQt" );
+ int n = string.tqcontains( 't', FALSE );
+ // n == 3
+ \endcode
+*/
+
+int TQString::tqcontains( TQChar c, bool cs ) const
+{
+ int count = 0;
+ const TQChar *uc = tqunicode();
+ if ( !uc )
+ return 0;
+ int n = length();
+ if ( cs ) {
+ while ( n-- ) {
+ if ( *uc == c )
+ count++;
+ uc++;
+ }
+ } else {
+ c = ::lower( c );
+ while ( n-- ) {
+ if ( ::lower( *uc ) == c )
+ count++;
+ uc++;
+ }
+ }
+ return count;
+}
+
+/*!
+ \overload
+
+ Returns the number of times the string \a str occurs in the string.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+*/
+int TQString::tqcontains( const char* str, bool cs ) const
+{
+ return tqcontains( TQString(str), cs );
+}
+
+/*!
+ \fn int TQString::tqcontains( char c, bool cs ) const
+
+ \overload
+*/
+
+/*!
+ \fn int TQString::tqfind( char c, int index, bool cs ) const
+
+ \overload
+
+ Find character \a c starting from position \a index.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+*/
+
+/*!
+ \fn int TQString::tqfindRev( char c, int index, bool cs ) const
+
+ \overload
+
+ Find character \a c starting from position \a index and working
+ backwards.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+*/
+
+/*!
+ \overload
+
+ Returns the number of times \a str occurs in the string.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ This function counts overlapping strings, so in the example below,
+ there are two instances of "ana" in "bananas".
+
+ \code
+ TQString str( "bananas" );
+ int i = str.tqcontains( "ana" ); // i == 2
+ \endcode
+
+ \sa tqfindRev()
+*/
+
+int TQString::tqcontains( const TQString &str, bool cs ) const
+{
+ if ( isNull() )
+ return 0;
+ int count = 0;
+ uint skiptable[0x100];
+ bm_init_skiptable( str, skiptable, cs );
+ int i = -1;
+ // use boyer-moore for the ultimate speed experience
+ while ( ( i = bm_tqfind( *this, i + 1, str, skiptable, cs ) ) != -1 )
+ count++;
+ return count;
+}
+
+/*!
+ Returns a substring that tqcontains the \a len leftmost characters
+ of the string.
+
+ The whole string is returned if \a len exceeds the length of the
+ string.
+
+ \code
+ TQString s = "Pineapple";
+ TQString t = s.left( 4 ); // t == "Pine"
+ \endcode
+
+ \sa right(), mid(), isEmpty()
+*/
+
+TQString TQString::left( uint len ) const
+{
+ if ( isEmpty() ) {
+ return TQString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return tqfromLatin1( "" );
+ } else if ( len >= length() ) {
+ return *this;
+ } else {
+ TQString s( len, TRUE );
+ memcpy( s.d->tqunicode, d->tqunicode, len * sizeof(TQChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a string that tqcontains the \a len rightmost characters of
+ the string.
+
+ If \a len is greater than the length of the string then the whole
+ string is returned.
+
+ \code
+ TQString string( "Pineapple" );
+ TQString t = string.right( 5 ); // t == "apple"
+ \endcode
+
+ \sa left(), mid(), isEmpty()
+*/
+
+TQString TQString::right( uint len ) const
+{
+ if ( isEmpty() ) {
+ return TQString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return tqfromLatin1( "" );
+ } else {
+ uint l = length();
+ if ( len >= l )
+ return *this;
+ TQString s( len, TRUE );
+ memcpy( s.d->tqunicode, d->tqunicode+(l-len), len*sizeof(TQChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a string that tqcontains the \a len characters of this
+ string, starting at position \a index.
+
+ Returns a null string if the string is empty or \a index is out of
+ range. Returns the whole string from \a index if \a index + \a len
+ exceeds the length of the string.
+
+ \code
+ TQString s( "Five pineapples" );
+ TQString t = s.mid( 5, 4 ); // t == "pine"
+ \endcode
+
+ \sa left(), right()
+*/
+
+TQString TQString::mid( uint index, uint len ) const
+{
+ uint slen = length();
+ if ( isEmpty() || index >= slen ) {
+ return TQString();
+ } else if ( len == 0 ) { // ## just for 1.x compat:
+ return tqfromLatin1( "" );
+ } else {
+ if ( len > slen-index )
+ len = slen - index;
+ if ( index == 0 && len == slen )
+ return *this;
+ register const TQChar *p = tqunicode()+index;
+ TQString s( len, TRUE );
+ memcpy( s.d->tqunicode, p, len * sizeof(TQChar) );
+ s.d->len = len;
+ return s;
+ }
+}
+
+/*!
+ Returns a string of length \a width that tqcontains this string
+ padded by the \a fill character.
+
+ If \a truncate is FALSE and the length of the string is more than
+ \a width, then the returned string is a copy of the string.
+
+ If \a truncate is TRUE and the length of the string is more than
+ \a width, then any characters in a copy of the string after length
+ \a width are removed, and the copy is returned.
+
+ \code
+ TQString s( "apple" );
+ TQString t = s.leftJustify( 8, '.' ); // t == "apple..."
+ \endcode
+
+ \sa rightJustify()
+*/
+
+TQString TQString::leftJustify( uint width, TQChar fill, bool truncate ) const
+{
+ TQString result;
+ int len = length();
+ int padlen = width - len;
+ if ( padlen > 0 ) {
+ result.setLength(len+padlen);
+ if ( len )
+ memcpy( result.d->tqunicode, tqunicode(), sizeof(TQChar)*len );
+ TQChar* uc = result.d->tqunicode + len;
+ while (padlen--)
+ *uc++ = fill;
+ } else {
+ if ( truncate )
+ result = left( width );
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns a string of length \a width that tqcontains the \a fill
+ character followed by the string.
+
+ If \a truncate is FALSE and the length of the string is more than
+ \a width, then the returned string is a copy of the string.
+
+ If \a truncate is TRUE and the length of the string is more than
+ \a width, then the resulting string is truncated at position \a
+ width.
+
+ \code
+ TQString string( "apple" );
+ TQString t = string.rightJustify( 8, '.' ); // t == "...apple"
+ \endcode
+
+ \sa leftJustify()
+*/
+
+TQString TQString::rightJustify( uint width, TQChar fill, bool truncate ) const
+{
+ TQString result;
+ int len = length();
+ int padlen = width - len;
+ if ( padlen > 0 ) {
+ result.setLength( len+padlen );
+ TQChar* uc = result.d->tqunicode;
+ while (padlen--)
+ *uc++ = fill;
+ if ( len )
+ memcpy( uc, tqunicode(), sizeof(TQChar)*len );
+ } else {
+ if ( truncate )
+ result = left( width );
+ else
+ result = *this;
+ }
+ return result;
+}
+
+/*!
+ Returns a lowercase copy of the string.
+
+ \code
+ TQString string( "TROlltECH" );
+ str = string.lower(); // str == "trolltech"
+ \endcode
+
+ \sa upper()
+*/
+
+TQString TQString::lower() const
+{
+ int l = length();
+ register TQChar *p = d->tqunicode;
+ while ( l ) {
+ if ( *p != ::lower(*p) ) {
+ TQString s( *this );
+ s.real_detach();
+ p = s.d->tqunicode + ( p - d->tqunicode );
+ while ( l ) {
+ *p = ::lower( *p );
+ l--;
+ p++;
+ }
+ return s;
+ }
+ l--;
+ p++;
+ }
+ return *this;
+}
+
+/*!
+ Returns an uppercase copy of the string.
+
+ \code
+ TQString string( "TeXt" );
+ str = string.upper(); // t == "TEXT"
+ \endcode
+
+ \sa lower()
+*/
+
+TQString TQString::upper() const
+{
+ int l = length();
+ register TQChar *p = d->tqunicode;
+ while ( l ) {
+ if ( *p != ::upper(*p) ) {
+ TQString s( *this );
+ s.real_detach();
+ p = s.d->tqunicode + ( p - d->tqunicode );
+ while ( l ) {
+ *p = ::upper( *p );
+ l--;
+ p++;
+ }
+ return s;
+ }
+ l--;
+ p++;
+ }
+ return *this;
+}
+
+
+/*!
+ Returns a string that has whitespace removed from the start and
+ the end.
+
+ Whitespace means any character for which TQChar::isSpace() returns
+ TRUE. This includes Unicode characters with decimal values 9
+ (TAB), 10 (LF), 11 (VT), 12 (FF), 13 (CR) and 32 (Space), and may
+ also include other Unicode characters.
+
+ \code
+ TQString string = " white space ";
+ TQString s = string.stripWhiteSpace(); // s == "white space"
+ \endcode
+
+ \sa simplifyWhiteSpace()
+*/
+
+TQString TQString::stripWhiteSpace() const
+{
+ if ( isEmpty() ) // nothing to do
+ return *this;
+ register const TQChar *s = tqunicode();
+ if ( !s->isSpace() && !s[length()-1].isSpace() )
+ return *this;
+
+ int start = 0;
+ int end = length() - 1;
+ while ( start<=end && s[start].isSpace() ) // skip white space from start
+ start++;
+ if ( start <= end ) { // only white space
+ while ( end && s[end].isSpace() ) // skip white space from end
+ end--;
+ }
+ int l = end - start + 1;
+ if ( l <= 0 )
+ return TQString::tqfromLatin1("");
+
+ TQString result( l, TRUE );
+ memcpy( result.d->tqunicode, &s[start], sizeof(TQChar)*l );
+ result.d->len = l;
+ return result;
+}
+
+
+/*!
+ Returns a string that has whitespace removed from the start and
+ the end, and which has each sequence of internal whitespace
+ tqreplaced with a single space.
+
+ Whitespace means any character for which TQChar::isSpace() returns
+ TRUE. This includes Unicode characters with decimal values 9
+ (TAB), 10 (LF), 11 (VT), 12 (FF), 13 (CR), and 32 (Space).
+
+ \code
+ TQString string = " lots\t of\nwhite space ";
+ TQString t = string.simplifyWhiteSpace();
+ // t == "lots of white space"
+ \endcode
+
+ \sa stripWhiteSpace()
+*/
+
+TQString TQString::simplifyWhiteSpace() const
+{
+ if ( isEmpty() )
+ return *this;
+ TQString result;
+ result.setLength( length() );
+ const TQChar *from = tqunicode();
+ const TQChar *fromend = from+length();
+ int outc=0;
+ TQChar *to = result.d->tqunicode;
+ for (;;) {
+ while ( from!=fromend && from->isSpace() )
+ from++;
+ while ( from!=fromend && !from->isSpace() )
+ to[outc++] = *from++;
+ if ( from!=fromend )
+ to[outc++] = ' ';
+ else
+ break;
+ }
+ if ( outc > 0 && to[outc-1] == ' ' )
+ outc--;
+ result.truncate( outc );
+ return result;
+}
+
+
+/*!
+ Inserts \a s into the string at position \a index.
+
+ If \a index is beyond the end of the string, the string is
+ extended with spaces to length \a index and \a s is then appended
+ and returns a reference to the string.
+
+ \code
+ TQString string( "I like fish" );
+ str = string.insert( 2, "don't " );
+ // str == "I don't like fish"
+ \endcode
+
+ \sa remove(), tqreplace()
+*/
+
+TQString &TQString::insert( uint index, const TQString &s )
+{
+ // the sub function takes care of &s == this case.
+ return insert( index, s.tqunicode(), s.length() );
+}
+
+/*! \fn TQString &TQString::insert( uint index, const TQByteArray &s )
+ \overload
+
+ Inserts \a s into the string at position \a index and returns
+ a reference to the string.
+*/
+
+/*! \fn TQString &TQString::insert( uint index, const char *s )
+ \overload
+
+ Inserts \a s into the string at position \a index and returns
+ a reference to the string.
+*/
+
+#ifndef TQT_NO_CAST_ASCII
+TQString &TQString::insertHelper( uint index, const char *s, uint len )
+{
+ if ( s ) {
+#ifndef TQT_NO_TEXTCODEC
+ if ( TQTextCodec::codecForCStrings() )
+ return insert( index, fromAscii( s, len ) );
+#endif
+ if ( len == UINT_MAX )
+ len = int(strlen( s ));
+ if ( len == 0 )
+ return *this;
+
+ uint olen = length();
+ int nlen = olen + len;
+
+ if ( index >= olen ) { // insert after end of string
+ grow( len + index );
+ int n = index - olen;
+ TQChar* uc = d->tqunicode + olen;
+ while ( n-- )
+ *uc++ = ' ';
+
+ uc = d->tqunicode + index;
+ while ( len-- )
+ *uc++ = *s++;
+ } else { // normal insert
+ grow( nlen );
+ memmove( d->tqunicode + index + len, tqunicode() + index,
+ sizeof(TQChar) * (olen - index) );
+
+ TQChar* uc = d->tqunicode + index;
+ while ( len-- )
+ *uc++ = *s++;
+ }
+ }
+ return *this;
+}
+#endif
+
+/*!
+ \overload
+
+ Inserts the first \a len characters in \a s into the string at
+ position \a index and returns a reference to the string.
+*/
+
+TQString &TQString::insert( uint index, const TQChar* s, uint len )
+{
+ if ( len == 0 )
+ return *this;
+ uint olen = length();
+ int nlen = olen + len;
+
+ if ( s >= d->tqunicode && (uint)(s - d->tqunicode) < d->maxl ) {
+ // Part of me - take a copy.
+ TQChar *tmp = TQT_ALLOC_TQCHAR_VEC( len );
+ memcpy(tmp,s,len*sizeof(TQChar));
+ insert(index,tmp,len);
+ TQT_DELETE_TQCHAR_VEC( tmp );
+ return *this;
+ }
+
+ if ( index >= olen ) { // insert after end of string
+ grow( len + index );
+ int n = index - olen;
+ TQChar* uc = d->tqunicode+olen;
+ while (n--)
+ *uc++ = ' ';
+ memcpy( d->tqunicode+index, s, sizeof(TQChar)*len );
+ } else { // normal insert
+ grow( nlen );
+ memmove( d->tqunicode + index + len, tqunicode() + index,
+ sizeof(TQChar) * (olen - index) );
+ memcpy( d->tqunicode + index, s, sizeof(TQChar) * len );
+ }
+ return *this;
+}
+
+/*!
+ \overload
+
+ Insert \a c into the string at position \a index and returns a
+ reference to the string.
+
+ If \a index is beyond the end of the string, the string is
+ extended with spaces (ASCII 32) to length \a index and \a c is
+ then appended.
+*/
+
+TQString &TQString::insert( uint index, TQChar c ) // insert char
+{
+ TQString s( c );
+ return insert( index, s );
+}
+
+/*!
+ \fn TQString& TQString::insert( uint index, char c )
+
+ \overload
+
+ Insert character \a c at position \a index.
+*/
+
+/*!
+ \fn TQString &TQString::prepend( const TQString &s )
+
+ Inserts \a s at the beginning of the string and returns a
+ reference to the string.
+
+ Equivalent to insert(0, \a s).
+
+ \code
+ TQString string = "42";
+ string.prepend( "The answer is " );
+ // string == "The answer is 42"
+ \endcode
+
+ \sa insert()
+*/
+
+/*!
+ \fn TQString& TQString::prepend( char ch )
+
+ \overload
+
+ Inserts \a ch at the beginning of the string and returns a
+ reference to the string.
+
+ Equivalent to insert(0, \a ch).
+
+ \sa insert()
+*/
+
+/*!
+ \fn TQString& TQString::prepend( TQChar ch )
+
+ \overload
+
+ Inserts \a ch at the beginning of the string and returns a
+ reference to the string.
+
+ Equivalent to insert(0, \a ch).
+
+ \sa insert()
+*/
+
+/*! \fn TQString& TQString::prepend( const TQByteArray &s )
+ \overload
+
+ Inserts \a s at the beginning of the string and returns a reference to the string.
+
+ Equivalent to insert(0, \a s).
+
+ \sa insert()
+ */
+
+/*! \fn TQString& TQString::prepend( const std::string &s )
+ \overload
+
+ Inserts \a s at the beginning of the string and returns a reference to the string.
+
+ Equivalent to insert(0, \a s).
+
+ \sa insert()
+*/
+
+/*!
+ \overload
+
+ Inserts \a s at the beginning of the string and returns a reference to the string.
+
+ Equivalent to insert(0, \a s).
+
+ \sa insert()
+ */
+TQString &TQString::prepend( const char *s )
+{
+ return insert( 0, TQString(s) );
+}
+
+/*!
+ Removes \a len characters from the string starting at position \a
+ index, and returns a reference to the string.
+
+ If \a index is beyond the length of the string, nothing happens.
+ If \a index is within the string, but \a index + \a len is beyond
+ the end of the string, the string is truncated at position \a
+ index.
+
+ \code
+ TQString string( "Montreal" );
+ string.remove( 1, 4 ); // string == "Meal"
+ \endcode
+
+ \sa insert(), tqreplace()
+*/
+
+TQString &TQString::remove( uint index, uint len )
+{
+ uint olen = length();
+ if ( index >= olen ) {
+ // range problems
+ } else if ( index + len >= olen ) { // index ok
+ setLength( index );
+ } else if ( len != 0 ) {
+ real_detach();
+ memmove( d->tqunicode+index, d->tqunicode+index+len,
+ sizeof(TQChar)*(olen-index-len) );
+ setLength( olen-len );
+ }
+ return *this;
+}
+
+/*! \overload
+
+ Removes every occurrence of the character \a c in the string.
+ Returns a reference to the string.
+
+ This is the same as tqreplace(\a c, "").
+*/
+TQString &TQString::remove( TQChar c )
+{
+ int i = 0;
+ while ( i < (int) length() ) {
+ if ( constref(i) == c ) {
+ remove( i, 1 );
+ } else {
+ i++;
+ }
+ }
+ return *this;
+}
+
+/*! \overload
+
+ \fn TQString &TQString::remove( char c )
+
+ Removes every occurrence of the character \a c in the string.
+ Returns a reference to the string.
+
+ This is the same as tqreplace(\a c, "").
+*/
+
+/*! \overload
+
+ Removes every occurrence of \a str in the string. Returns a
+ reference to the string.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ This is the same as tqreplace(\a str, "", \a cs).
+*/
+TQString &TQString::remove( const TQString & str, bool cs )
+{
+ if ( str.isEmpty() ) {
+ if ( isNull() )
+ real_detach();
+ } else {
+ int index = 0;
+ while ( (index = tqfind(str, index, cs)) != -1 )
+ remove( index, str.length() );
+ }
+ return *this;
+}
+
+TQString &TQString::remove( const TQString & str )
+{
+ return remove( str, TRUE );
+}
+
+/*! \overload
+
+ Replaces every occurrence of \a c1 with the char \a c2. Returns a
+ reference to the string.
+*/
+TQString &TQString::tqreplace( TQChar c1, TQChar c2 )
+{
+ if ( isEmpty() )
+ return *this;
+
+ real_detach();
+ uint i = 0;
+ while ( i < d->len ) {
+ if ( d->tqunicode[i] == c1 )
+ d->tqunicode[i] = c2;
+ i++;
+ }
+ return *this;
+}
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+
+/*! \overload
+
+ Removes every occurrence of the regular expression \a rx in the
+ string. Returns a reference to the string.
+
+ This is the same as tqreplace(\a rx, "").
+*/
+
+TQString &TQString::remove( const TQRegExp & rx )
+{
+ return tqreplace( rx, TQString::null );
+}
+
+#endif
+
+/*!
+ \overload
+
+ Removes every occurrence of \a str in the string. Returns a
+ reference to the string.
+*/
+TQString &TQString::remove( const char *str )
+{
+ return remove( TQString::fromAscii(str), TRUE );
+}
+
+/*!
+ Replaces \a len characters from the string with \a s, starting at
+ position \a index, and returns a reference to the string.
+
+ If \a index is beyond the length of the string, nothing is deleted
+ and \a s is appended at the end of the string. If \a index is
+ valid, but \a index + \a len is beyond the end of the string,
+ the string is truncated at position \a index, then \a s is
+ appended at the end.
+
+ \code
+ TQString string( "Say yes!" );
+ string = string.tqreplace( 4, 3, "NO" );
+ // string == "Say NO!"
+ \endcode
+
+ \warning TQt 3.3.3 and earlier had different semantics for the
+ case \a index >= length(), which contradicted the documentation.
+ To avoid portability problems between TQt 3 versions and with TQt
+ 4, we recommend that you never call the function with \a index >=
+ length().
+
+ \sa insert(), remove()
+*/
+
+TQString &TQString::tqreplace( uint index, uint len, const TQString &s )
+{
+ return tqreplace( index, len, s.tqunicode(), s.length() );
+}
+
+/*! \overload
+
+ This is the same as tqreplace(\a index, \a len, TQString(\a c)).
+*/
+TQString &TQString::tqreplace( uint index, uint len, TQChar c )
+{
+ return tqreplace( index, len, &c, 1 );
+}
+
+/*! \overload
+ \fn TQString &TQString::tqreplace( uint index, uint len, char c )
+
+ This is the same as tqreplace(\a index, \a len, TQChar(\a c)).
+*/
+
+/*!
+ \overload
+
+ Replaces \a len characters with \a slen characters of TQChar data
+ from \a s, starting at position \a index, and returns a reference
+ to the string.
+
+ \sa insert(), remove()
+*/
+
+TQString &TQString::tqreplace( uint index, uint len, const TQChar* s, uint slen )
+{
+ if (index > length())
+ index = length();
+ real_detach();
+ if ( len == slen && index + len <= length() ) {
+ // Optimized common case: tqreplace without size change
+ memcpy( d->tqunicode+index, s, len * sizeof(TQChar) );
+ } else if ( s >= d->tqunicode && (uint)(s - d->tqunicode) < d->maxl ) {
+ // Part of me - take a copy.
+ TQChar *tmp = TQT_ALLOC_TQCHAR_VEC( slen );
+ memcpy( tmp, s, slen * sizeof(TQChar) );
+ tqreplace( index, len, tmp, slen );
+ TQT_DELETE_TQCHAR_VEC( tmp );
+ } else {
+ remove( index, len );
+ insert( index, s, slen );
+ }
+ return *this;
+}
+
+/*! \overload
+
+ Replaces every occurrence of the character \a c in the string
+ with \a after. Returns a reference to the string.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ Example:
+ \code
+ TQString s = "a,b,c";
+ s.tqreplace( TQChar(','), " or " );
+ // s == "a or b or c"
+ \endcode
+*/
+TQString &TQString::tqreplace( TQChar c, const TQString & after, bool cs )
+{
+ return tqreplace( TQString( c ), after, cs );
+}
+
+TQString &TQString::tqreplace( TQChar c, const TQString & after )
+{
+ return tqreplace( TQString( c ), after, TRUE );
+}
+
+/*! \overload
+ \fn TQString &TQString::tqreplace( char c, const TQString & after, bool cs )
+
+ Replaces every occurrence of the character \a c in the string
+ with \a after. Returns a reference to the string.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+*/
+
+/*! \overload
+
+ Replaces every occurrence of the string \a before in the string
+ with the string \a after. Returns a reference to the string.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ Example:
+ \code
+ TQString s = "Greek is Greek";
+ s.tqreplace( "Greek", "English" );
+ // s == "English is English"
+ \endcode
+*/
+TQString &TQString::tqreplace( const TQString & before, const TQString & after,
+ bool cs )
+{
+ if ( isEmpty() ) {
+ if ( !before.isEmpty() )
+ return *this;
+ } else {
+ if ( cs && before == after )
+ return *this;
+ }
+
+ real_detach();
+
+ int index = 0;
+ uint skiptable[256];
+ bm_init_skiptable( before, skiptable, cs );
+ const int bl = before.length();
+ const int al = after.length();
+
+ if ( bl == al ) {
+ if ( bl ) {
+ const TQChar *auc = after.tqunicode();
+ while ( (index = bm_tqfind(*this, index, before, skiptable, cs) ) != -1 ) {
+ memcpy( d->tqunicode + index, auc, al * sizeof(TQChar) );
+ index += bl;
+ }
+ }
+ } else if ( al < bl ) {
+ const TQChar *auc = after.tqunicode();
+ uint to = 0;
+ uint movestart = 0;
+ uint num = 0;
+ while ( (index = bm_tqfind(*this, index, before, skiptable, cs)) != -1 ) {
+ if ( num ) {
+ int msize = index - movestart;
+ if ( msize > 0 ) {
+ memmove( d->tqunicode + to, d->tqunicode + movestart, msize*sizeof(TQChar) );
+ to += msize;
+ }
+ } else {
+ to = index;
+ }
+ if ( al ) {
+ memcpy( d->tqunicode+to, auc, al*sizeof(TQChar) );
+ to += al;
+ }
+ index += bl;
+ movestart = index;
+ num++;
+ }
+ if ( num ) {
+ int msize = d->len - movestart;
+ if ( msize > 0 )
+ memmove( d->tqunicode + to, d->tqunicode + movestart, msize*sizeof(TQChar) );
+ setLength( d->len - num*(bl-al) );
+ }
+ } else {
+ // the most complex case. We don't want to loose performance by doing repeated
+ // copies and reallocs of the string.
+ while ( index != -1 ) {
+ uint indices[4096];
+ uint pos = 0;
+ while ( pos < 4095 ) {
+ index = bm_tqfind( *this, index, before, skiptable, cs );
+ if ( index == -1 )
+ break;
+ indices[pos++] = index;
+ index += bl;
+ // avoid infinite loop
+ if ( !bl )
+ index++;
+ }
+ if ( !pos )
+ break;
+
+ // we have a table of tqreplacement positions, use them for fast replacing
+ int adjust = pos*(al-bl);
+ // index has to be adjusted in case we get back into the loop above.
+ if ( index != -1 )
+ index += adjust;
+ uint newlen = d->len + adjust;
+ int moveend = d->len;
+ if ( newlen > d->len )
+ setLength( newlen );
+
+ while ( pos ) {
+ pos--;
+ int movestart = indices[pos] + bl;
+ int insertstart = indices[pos] + pos*(al-bl);
+ int moveto = insertstart + al;
+ memmove( d->tqunicode + moveto, d->tqunicode + movestart, (moveend - movestart)*sizeof(TQChar) );
+ memcpy( d->tqunicode + insertstart, after.tqunicode(), al*sizeof(TQChar) );
+ moveend = movestart-bl;
+ }
+ }
+ }
+ return *this;
+}
+
+TQString &TQString::tqreplace( const TQString & before, const TQString & after )
+{
+ return tqreplace( before, after, TRUE );
+}
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+/*! \overload
+
+ Replaces every occurrence of the regexp \a rx in the string with
+ \a after. Returns a reference to the string. For example:
+ \code
+ TQString s = "banana";
+ s.tqreplace( TQRegExp("an"), "" );
+ // s == "ba"
+ \endcode
+
+ For regexps containing \link tqregexp.html#capturing-text capturing
+ parentheses \endlink, occurrences of <b>\\1</b>, <b>\\2</b>, ...,
+ in \a after are tqreplaced with \a{rx}.cap(1), cap(2), ...
+
+ \code
+ TQString t = "A <i>bon mot</i>.";
+ t.tqreplace( TQRegExp("<i>([^<]*)</i>"), "\\emph{\\1}" );
+ // t == "A \\emph{bon mot}."
+ \endcode
+
+ \sa tqfind(), tqfindRev(), TQRegExp::cap()
+*/
+
+TQString &TQString::tqreplace( const TQRegExp &rx, const TQString &after )
+{
+ TQRegExp rx2 = rx;
+
+ if ( isEmpty() && rx2.search(*this) == -1 )
+ return *this;
+
+ real_detach();
+
+ int index = 0;
+ int numCaptures = rx2.numCaptures();
+ int al = after.length();
+ TQRegExp::CaretMode caretMode = TQRegExp::CaretAtZero;
+
+ if ( numCaptures > 0 ) {
+ if ( numCaptures > 9 )
+ numCaptures = 9;
+
+ const TQChar *uc = after.tqunicode();
+ int numBackRefs = 0;
+
+ for ( int i = 0; i < al - 1; i++ ) {
+ if ( uc[i] == '\\' ) {
+ int no = uc[i + 1].digitValue();
+ if ( no > 0 && no <= numCaptures )
+ numBackRefs++;
+ }
+ }
+
+ /*
+ This is the harder case where we have back-references.
+ We don't try to optimize it.
+ */
+ if ( numBackRefs > 0 ) {
+ int *capturePositions = new int[numBackRefs];
+ int *captureNumbers = new int[numBackRefs];
+ int j = 0;
+
+ for ( int i = 0; i < al - 1; i++ ) {
+ if ( uc[i] == '\\' ) {
+ int no = uc[i + 1].digitValue();
+ if ( no > 0 && no <= numCaptures ) {
+ capturePositions[j] = i;
+ captureNumbers[j] = no;
+ j++;
+ }
+ }
+ }
+
+ while ( index <= (int)length() ) {
+ index = rx2.search( *this, index, caretMode );
+ if ( index == -1 )
+ break;
+
+ TQString after2 = after;
+ for ( j = numBackRefs - 1; j >= 0; j-- )
+ after2.tqreplace( capturePositions[j], 2,
+ rx2.cap(captureNumbers[j]) );
+
+ tqreplace( index, rx2.matchedLength(), after2 );
+ index += after2.length();
+
+ if ( rx2.matchedLength() == 0 ) {
+ // avoid infinite loop on 0-length matches (e.g., [a-z]*)
+ index++;
+ }
+ caretMode = TQRegExp::CaretWontMatch;
+ }
+ delete[] capturePositions;
+ delete[] captureNumbers;
+ return *this;
+ }
+ }
+
+ /*
+ This is the simple and optimized case where we don't have
+ back-references.
+ */
+ while ( index != -1 ) {
+ struct {
+ int pos;
+ int length;
+ } tqreplacements[2048];
+
+ uint pos = 0;
+ int adjust = 0;
+ while ( pos < 2047 ) {
+ index = rx2.search( *this, index, caretMode );
+ if ( index == -1 )
+ break;
+ int ml = rx2.matchedLength();
+ tqreplacements[pos].pos = index;
+ tqreplacements[pos++].length = ml;
+ index += ml;
+ adjust += al - ml;
+ // avoid infinite loop
+ if ( !ml )
+ index++;
+ }
+ if ( !pos )
+ break;
+ tqreplacements[pos].pos = d->len;
+ uint newlen = d->len + adjust;
+
+ // to continue searching at the right position after we did
+ // the first round of tqreplacements
+ if ( index != -1 )
+ index += adjust;
+ TQChar *newuc = TQT_ALLOC_TQCHAR_VEC( newlen + 1 );
+ TQChar *uc = newuc;
+ int copystart = 0;
+ uint i = 0;
+ while ( i < pos ) {
+ int copyend = tqreplacements[i].pos;
+ int size = copyend - copystart;
+ memcpy( uc, d->tqunicode + copystart, size * sizeof(TQChar) );
+ uc += size;
+ memcpy( uc, after.tqunicode(), al * sizeof(TQChar) );
+ uc += al;
+ copystart = copyend + tqreplacements[i].length;
+ i++;
+ }
+ memcpy( uc, d->tqunicode + copystart,
+ (d->len - copystart) * sizeof(TQChar) );
+ TQT_DELETE_TQCHAR_VEC( d->tqunicode );
+ d->tqunicode = newuc;
+ d->len = newlen;
+ d->maxl = newlen + 1;
+ d->setDirty();
+ caretMode = TQRegExp::CaretWontMatch;
+ }
+ return *this;
+}
+#endif
+
+#ifndef TQT_NO_REGEXP
+/*!
+ Finds the first match of the regular expression \a rx, starting
+ from position \a index. If \a index is -1, the search starts at
+ the last character; if -2, at the next to last character and so
+ on. (See tqfindRev() for searching backwards.)
+
+ Returns the position of the first match of \a rx or -1 if no match
+ was found.
+
+ \code
+ TQString string( "bananas" );
+ int i = string.tqfind( TQRegExp("an"), 0 ); // i == 1
+ \endcode
+
+ \sa tqfindRev() tqreplace() tqcontains()
+*/
+
+int TQString::tqfind( const TQRegExp &rx, int index ) const
+{
+ return rx.search( *this, index );
+}
+
+/*!
+ \overload
+
+ Finds the first match of the regexp \a rx, starting at position \a
+ index and searching backwards. If the index is -1, the search
+ starts at the last character, if it is -2, at the next to last
+ character and so on. (See tqfindRev() for searching backwards.)
+
+ Returns the position of the match or -1 if no match was found.
+
+ \code
+ TQString string( "bananas" );
+ int i = string.tqfindRev( TQRegExp("an") ); // i == 3
+ \endcode
+
+ \sa tqfind()
+*/
+
+int TQString::tqfindRev( const TQRegExp &rx, int index ) const
+{
+ return rx.searchRev( *this, index );
+}
+
+/*!
+ \overload
+
+ Returns the number of times the regexp, \a rx, matches in the
+ string.
+
+ This function counts overlapping matches, so in the example below,
+ there are four instances of "ana" or "ama".
+
+ \code
+ TQString str = "banana and panama";
+ TQRegExp rxp = TQRegExp( "a[nm]a", TRUE, FALSE );
+ int i = str.tqcontains( rxp ); // i == 4
+ \endcode
+
+ \sa tqfind() tqfindRev()
+*/
+
+int TQString::tqcontains( const TQRegExp &rx ) const
+{
+ int count = 0;
+ int index = -1;
+ int len = length();
+ while ( index < len - 1 ) { // count overlapping matches
+ index = rx.search( *this, index + 1 );
+ if ( index == -1 )
+ break;
+ count++;
+ }
+ return count;
+}
+
+#endif //TQT_NO_REGEXP
+
+/*!
+ Returns the string converted to a \c long using base \a
+ base, which is 10 by default and must be between 2 and 36 or 0. If
+ \a base is 0, the base is determined automatically using the
+ following rules:
+ <ul>
+ <li>If the string begins with "0x", it is assumed to
+ be hexadecimal;
+ <li>If it begins with "0", it is assumed to be octal;
+ <li>Otherwise it is assumed to be decimal.
+ </ul>
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, \a *ok is set to
+ FALSE; otherwise \a *ok is set to TRUE.
+
+ Leading and trailing whitespace is ignored by this function.
+
+ For information on how string-to-number functions in TQString handle
+ localized input, see toDouble().
+
+ \sa number()
+*/
+
+long TQString::toLong( bool *ok, int base ) const
+{
+ TQ_LLONG v = toLongLong( ok, base );
+ if ( v < LONG_MIN || v > LONG_MAX ) {
+ if ( ok )
+ *ok = FALSE;
+ v = 0;
+ }
+ return long(v);
+}
+
+/*!
+ Returns the string converted to a \c {long long} using base \a
+ base, which is 10 by default and must be between 2 and 36 or 0. If
+ \a base is 0, the base is determined automatically using the
+ following rules:
+ <ul>
+ <li>If the string begins with "0x", it is assumed to
+ be hexadecimal;
+ <li>If it begins with "0", it is assumed to be octal;
+ <li>Otherwise it is assumed to be decimal.
+ </ul>
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, \a *ok is set to
+ FALSE; otherwise \a *ok is set to TRUE.
+
+ Leading and trailing whitespace is ignored by this function.
+
+ For information on how string-to-number functions in TQString handle
+ localized input, see toDouble().
+
+ \sa number()
+*/
+
+TQ_LLONG TQString::toLongLong( bool *ok, int base ) const
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( base != 0 && (base < 2 || base > 36) ) {
+ qWarning( "TQString::toLongLong: Invalid base (%d)", base );
+ base = 10;
+ }
+#endif
+
+ bool my_ok;
+ TQLocale def_locale;
+ TQ_LLONG result = def_locale.d->stringToLongLong(*this, base, &my_ok, TQLocalePrivate::FailOnGroupSeparators);
+ if (my_ok) {
+ if (ok != 0)
+ *ok = TRUE;
+ return result;
+ }
+
+ // If the default was not "C", try the "C" locale
+ if (def_locale.language() == TQLocale::C) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+
+ TQLocale c_locale(TQLocale::C);
+ return c_locale.d->stringToLongLong(*this, base, ok, TQLocalePrivate::FailOnGroupSeparators);
+}
+
+/*!
+ Returns the string converted to an \c {unsigned long} using base \a
+ base, which is 10 by default and must be between 2 and 36 or 0. If
+ \a base is 0, the base is determined automatically using the
+ following rules:
+ <ul>
+ <li>If the string begins with "0x", it is assumed to
+ be hexadecimal;
+ <li>If it begins with "0", it is assumed to be octal;
+ <li>Otherwise it is assumed to be decimal.
+ </ul>
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, \a *ok is set to
+ FALSE; otherwise \a *ok is set to TRUE.
+
+ Leading and trailing whitespace is ignored by this function.
+
+ For information on how string-to-number functions in TQString handle
+ localized input, see toDouble().
+
+ \sa number()
+*/
+
+ulong TQString::toULong( bool *ok, int base ) const
+{
+ TQ_ULLONG v = toULongLong( ok, base );
+ if ( v > ULONG_MAX ) {
+ if ( ok )
+ *ok = FALSE;
+ v = 0;
+ }
+ return ulong(v);
+}
+
+/*!
+ Returns the string converted to an \c {unsigned long long} using base \a
+ base, which is 10 by default and must be between 2 and 36 or 0. If
+ \a base is 0, the base is determined automatically using the
+ following rules:
+ <ul>
+ <li>If the string begins with "0x", it is assumed to
+ be hexadecimal;
+ <li>If it begins with "0", it is assumed to be octal;
+ <li>Otherwise it is assumed to be decimal.
+ </ul>
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, \a *ok is set to
+ FALSE; otherwise \a *ok is set to TRUE.
+
+ Leading and trailing whitespace is ignored by this function.
+
+ For information on how string-to-number functions in TQString handle
+ localized input, see toDouble().
+
+ \sa number()
+*/
+
+TQ_ULLONG TQString::toULongLong( bool *ok, int base ) const
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( base != 0 && (base < 2 || base > 36) ) {
+ qWarning( "TQString::toULongLong: Invalid base %d", base );
+ base = 10;
+ }
+#endif
+
+ bool my_ok;
+ TQLocale def_locale;
+ TQ_ULLONG result = def_locale.d->stringToUnsLongLong(*this, base, &my_ok, TQLocalePrivate::FailOnGroupSeparators);
+ if (my_ok) {
+ if (ok != 0)
+ *ok = TRUE;
+ return result;
+ }
+
+ // If the default was not "C", try the "C" locale
+ if (def_locale.language() == TQLocale::C) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0;
+ }
+
+ TQLocale c_locale(TQLocale::C);
+ return c_locale.d->stringToUnsLongLong(*this, base, ok, TQLocalePrivate::FailOnGroupSeparators);
+}
+
+/*!
+ Returns the string converted to a \c short using base \a
+ base, which is 10 by default and must be between 2 and 36 or 0. If
+ \a base is 0, the base is determined automatically using the
+ following rules:
+ <ul>
+ <li>If the string begins with "0x", it is assumed to
+ be hexadecimal;
+ <li>If it begins with "0", it is assumed to be octal;
+ <li>Otherwise it is assumed to be decimal.
+ </ul>
+
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, \a *ok is set to
+ FALSE; otherwise \a *ok is set to TRUE.
+
+ Leading and trailing whitespace is ignored by this function.
+
+ For information on how string-to-number functions in TQString handle
+ localized input, see toDouble().
+
+ \sa number()
+*/
+
+
+short TQString::toShort( bool *ok, int base ) const
+{
+ TQ_LLONG v = toLongLong( ok, base );
+ if ( v < SHRT_MIN || v > SHRT_MAX ) {
+ if ( ok )
+ *ok = FALSE;
+ v = 0;
+ }
+ return (short)v;
+}
+
+/*!
+ Returns the string converted to an \c {unsigned short} using base \a
+ base, which is 10 by default and must be between 2 and 36 or 0. If
+ \a base is 0, the base is determined automatically using the
+ following rules:
+ <ul>
+ <li>If the string begins with "0x", it is assumed to
+ be hexadecimal;
+ <li>If it begins with "0", it is assumed to be octal;
+ <li>Otherwise it is assumed to be decimal.
+ </ul>
+
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, \a *ok is set to
+ FALSE; otherwise \a *ok is set to TRUE.
+
+ Leading and trailing whitespace is ignored by this function.
+
+ For information on how string-to-number functions in TQString handle
+ localized input, see toDouble().
+
+ \sa number()
+*/
+
+ushort TQString::toUShort( bool *ok, int base ) const
+{
+ TQ_ULLONG v = toULongLong( ok, base );
+ if ( v > USHRT_MAX ) {
+ if ( ok )
+ *ok = FALSE;
+ v = 0;
+ }
+ return (ushort)v;
+}
+
+
+/*!
+ Returns the string converted to an \c int using base \a
+ base, which is 10 by default and must be between 2 and 36 or 0. If
+ \a base is 0, the base is determined automatically using the
+ following rules:
+ <ul>
+ <li>If the string begins with "0x", it is assumed to
+ be hexadecimal;
+ <li>If it begins with "0", it is assumed to be octal;
+ <li>Otherwise it is assumed to be decimal.
+ </ul>
+
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, \a *ok is set to
+ FALSE; otherwise \a *ok is set to TRUE.
+
+ \code
+ TQString str( "FF" );
+ bool ok;
+ int hex = str.toInt( &ok, 16 ); // hex == 255, ok == TRUE
+ int dec = str.toInt( &ok, 10 ); // dec == 0, ok == FALSE
+ \endcode
+
+ Leading and trailing whitespace is ignored by this function.
+
+ For information on how string-to-number functions in TQString handle
+ localized input, see toDouble().
+
+ \sa number()
+*/
+
+int TQString::toInt( bool *ok, int base ) const
+{
+ TQ_LLONG v = toLongLong( ok, base );
+ if ( v < INT_MIN || v > INT_MAX ) {
+ if ( ok )
+ *ok = FALSE;
+ v = 0;
+ }
+ return (int)v;
+}
+
+/*!
+ Returns the string converted to an \c {unsigned int} using base \a
+ base, which is 10 by default and must be between 2 and 36 or 0. If
+ \a base is 0, the base is determined automatically using the
+ following rules:
+ <ul>
+ <li>If the string begins with "0x", it is assumed to
+ be hexadecimal;
+ <li>If it begins with "0", it is assumed to be octal;
+ <li>Otherwise it is assumed to be decimal.
+ </ul>
+
+ Returns 0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, \a *ok is set to
+ FALSE; otherwise \a *ok is set to TRUE.
+
+ Leading and trailing whitespace is ignored by this function.
+
+ For information on how string-to-number functions in TQString handle
+ localized input, see toDouble().
+
+ \sa number()
+*/
+
+uint TQString::toUInt( bool *ok, int base ) const
+{
+ TQ_ULLONG v = toULongLong( ok, base );
+ if ( v > UINT_MAX ) {
+ if ( ok )
+ *ok = FALSE;
+ v = 0;
+ }
+ return (uint)v;
+}
+
+/*!
+ Returns the string converted to a \c double value.
+
+ If \a ok is not 0: if a conversion error occurs, \a *ok is set to
+ FALSE; otherwise \a *ok is set to TRUE.
+
+ \code
+ TQString string( "1234.56" );
+ double a = string.toDouble(); // a == 1234.56
+ \endcode
+
+ The string-to-number functions:
+ \list
+ \i toShort()
+ \i toUShort()
+ \i toInt()
+ \i toUInt()
+ \i toLong()
+ \i toULong()
+ \i toLongLong()
+ \i toULongLong()
+ \i toFloat()
+ \i toDouble()
+ \endlist
+ can handle numbers
+ represented in various locales. These representations may use different
+ characters for the decimal point, thousands group sepearator
+ and even individual digits. TQString's functions try to interpret
+ the string according to the current locale. The current locale is
+ determined from the system at application startup and can be changed
+ by calling TQLocale::setDefault(). If the string cannot be interpreted
+ according to the current locale, this function falls back
+ on the "C" locale.
+
+ \code
+ bool ok;
+ double d;
+
+ TQLocale::setDefault(TQLocale::C);
+ d = TQString( "1234,56" ).toDouble(&ok); // ok == false
+ d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56
+
+ TQLocale::setDefault(TQLocale::German);
+ d = TQString( "1234,56" ).toDouble(&ok); // ok == true, d == 1234.56
+ d = TQString( "1234.56" ).toDouble(&ok); // ok == true, d == 1234.56
+ \endcode
+
+ Due to the ambiguity between the decimal point and thousands group
+ separator in various locales, these functions do not handle
+ thousands group separators. If you need to convert such numbers,
+ use the corresponding function in TQLocale.
+
+ \code
+ bool ok;
+ TQLocale::setDefault(TQLocale::C);
+ double d = TQString( "1,234,567.89" ).toDouble(&ok); // ok == false
+ \endcode
+
+ \warning If the string tqcontains trailing whitespace this function
+ will fail, and set \a *ok to false if \a ok is not 0. Leading
+ whitespace is ignored.
+
+ \sa number() TQLocale::setDefault() TQLocale::toDouble() stripWhiteSpace()
+*/
+
+double TQString::toDouble( bool *ok ) const
+{
+ // If there is trailing whitespace, set ok to false but return the correct
+ // result anyway to preserve behavour of pervious versions of TQt
+ if (length() > 0 && tqunicode()[length() - 1].isSpace()) {
+ TQString tmp = stripWhiteSpace();
+ if (ok != 0)
+ *ok = FALSE;
+ return tmp.toDouble();
+ }
+
+ // Try the default locale
+ bool my_ok;
+ TQLocale def_locale;
+ double result = def_locale.d->stringToDouble(*this, &my_ok, TQLocalePrivate::FailOnGroupSeparators);
+ if (my_ok) {
+ if (ok != 0)
+ *ok = TRUE;
+ return result;
+ }
+
+ // If the default was not "C", try the "C" locale
+ if (def_locale.language() == TQLocale::C) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0.0;
+ }
+
+ TQLocale c_locale(TQLocale::C);
+ return c_locale.d->stringToDouble(*this, ok, TQLocalePrivate::FailOnGroupSeparators);
+}
+
+/*!
+ Returns the string converted to a \c float value.
+
+ Returns 0.0 if the conversion fails.
+
+ If \a ok is not 0: if a conversion error occurs, \a *ok is set to
+ FALSE; otherwise \a *ok is set to TRUE.
+
+ For information on how string-to-number functions in TQString handle
+ localized input, see toDouble().
+
+ \warning If the string tqcontains trailing whitespace this function
+ will fail, settings \a *ok to false if \a ok is not 0.
+ Leading whitespace is ignored.
+
+ \sa number()
+*/
+
+#define TQT_MAX_FLOAT 3.4028234663852886e+38
+
+float TQString::toFloat( bool *ok ) const
+{
+ bool myOk;
+ double d = toDouble(&myOk);
+ if (!myOk || d > TQT_MAX_FLOAT || d < -TQT_MAX_FLOAT) {
+ if (ok != 0)
+ *ok = FALSE;
+ return 0.0;
+ }
+ if (ok != 0)
+ *ok = TRUE;
+ return (float) d;
+}
+
+/*!
+ Sets the string to the printed value of \a n in base \a base and
+ returns a reference to the string. The returned string is in "C" locale.
+
+ The base is 10 by default and must be between 2 and 36.
+
+ \code
+ TQString string;
+ string = string.setNum( 1234 ); // string == "1234"
+ \endcode
+*/
+
+TQString &TQString::setNum( TQ_LLONG n, int base )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( base < 2 || base > 36 ) {
+ qWarning( "TQString::setNum: Invalid base %d", base );
+ base = 10;
+ }
+#endif
+ TQLocale locale(TQLocale::C);
+ *this = locale.d->longLongToString(n, -1, base);
+ return *this;
+}
+
+/*!
+ \overload
+
+ Sets the string to the printed value of \a n in base \a base and
+ returns a reference to the string.
+
+ The base is 10 by default and must be between 2 and 36.
+*/
+
+TQString &TQString::setNum( TQ_ULLONG n, int base )
+{
+#if defined(TQT_CHECK_RANGE)
+ if ( base < 2 || base > 36 ) {
+ qWarning( "TQString::setNum: Invalid base %d", base );
+ base = 10;
+ }
+#endif
+ TQLocale locale(TQLocale::C);
+ *this = locale.d->unsLongLongToString(n, -1, base);
+ return *this;
+}
+
+/*!
+ \fn TQString &TQString::setNum( long n, int base )
+
+ \overload
+*/
+// ### 4.0: inline
+TQString &TQString::setNum( long n, int base )
+{
+ return setNum( (TQ_LLONG)n, base );
+}
+
+/*!
+ \fn TQString &TQString::setNum( ulong n, int base )
+
+ \overload
+*/
+// ### 4.0: inline
+TQString &TQString::setNum( ulong n, int base )
+{
+ return setNum( (TQ_ULLONG)n, base );
+}
+
+/*!
+ \fn TQString &TQString::setNum( int n, int base )
+
+ \overload
+
+ Sets the string to the printed value of \a n in base \a base and
+ returns a reference to the string.
+
+ The base is 10 by default and must be between 2 and 36.
+*/
+
+/*!
+ \fn TQString &TQString::setNum( uint n, int base )
+
+ \overload
+
+ Sets the string to the printed value of \a n in base \a base and
+ returns a reference to the string.
+
+ The base is 10 by default and must be between 2 and 36.
+*/
+
+/*!
+ \fn TQString &TQString::setNum( short n, int base )
+
+ \overload
+
+ Sets the string to the printed value of \a n in base \a base and
+ returns a reference to the string.
+
+ The base is 10 by default and must be between 2 and 36.
+*/
+
+/*!
+ \fn TQString &TQString::setNum( ushort n, int base )
+
+ \overload
+
+ Sets the string to the printed value of \a n in base \a base and
+ returns a reference to the string.
+
+ The base is 10 by default and must be between 2 and 36.
+*/
+
+/*!
+ \overload
+
+ Sets the string to the printed value of \a n, formatted in format
+ \a f with precision \a prec, and returns a reference to the
+ string.
+
+ The format \a f can be 'f', 'F', 'e', 'E', 'g' or 'G'. See \link
+ #arg-formats arg \endlink() for an explanation of the formats.
+*/
+
+TQString &TQString::setNum( double n, char f, int prec )
+{
+ TQLocalePrivate::DoubleForm form = TQLocalePrivate::DFDecimal;
+ uint flags = 0;
+
+ if (qIsUpper(f))
+ flags = TQLocalePrivate::CapitalEorX;
+ f = qToLower(f);
+
+ switch (f) {
+ case 'f':
+ form = TQLocalePrivate::DFDecimal;
+ break;
+ case 'e':
+ form = TQLocalePrivate::DFExponent;
+ break;
+ case 'g':
+ form = TQLocalePrivate::DFSignificantDigits;
+ break;
+ default:
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQString::setNum: Invalid format char '%c'", f );
+#endif
+ break;
+ }
+
+ TQLocale locale(TQLocale::C);
+ *this = locale.d->doubleToString(n, prec, form, -1, flags);
+ return *this;
+}
+
+/*!
+ \fn TQString &TQString::setNum( float n, char f, int prec )
+
+ \overload
+
+ Sets the string to the printed value of \a n, formatted in format
+ \a f with precision \a prec, and returns a reference to the
+ string.
+
+ The format \a f can be 'f', 'F', 'e', 'E', 'g' or 'G'. See \link
+ #arg-formats arg \endlink() for an explanation of the formats.
+*/
+
+
+/*!
+ A convenience function that returns a string equivalent of the
+ number \a n to base \a base, which is 10 by default and must be
+ between 2 and 36. The returned string is in "C" locale.
+
+ \code
+ long a = 63;
+ TQString str = TQString::number( a, 16 ); // str == "3f"
+ TQString str = TQString::number( a, 16 ).upper(); // str == "3F"
+ \endcode
+
+ \sa setNum()
+*/
+TQString TQString::number( long n, int base )
+{
+ TQString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ \overload
+
+ \sa setNum()
+*/
+TQString TQString::number( ulong n, int base )
+{
+ TQString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ \overload
+
+ \sa setNum()
+*/
+TQString TQString::number( TQ_LLONG n, int base )
+{
+ TQString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ \overload
+
+ \sa setNum()
+*/
+TQString TQString::number( TQ_ULLONG n, int base )
+{
+ TQString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ \overload
+
+ \sa setNum()
+*/
+TQString TQString::number( int n, int base )
+{
+ TQString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ \overload
+
+ A convenience factory function that returns a string
+ representation of the number \a n to the base \a base, which is 10
+ by default and must be between 2 and 36.
+
+ \sa setNum()
+*/
+TQString TQString::number( uint n, int base )
+{
+ TQString s;
+ s.setNum( n, base );
+ return s;
+}
+
+/*!
+ \overload
+
+ Argument \a n is formatted according to the \a f format specified,
+ which is \c g by default, and can be any of the following:
+
+ \table
+ \header \i Format \i Meaning
+ \row \i \c e \i format as [-]9.9e[+|-]999
+ \row \i \c E \i format as [-]9.9E[+|-]999
+ \row \i \c f \i format as [-]9.9
+ \row \i \c g \i use \c e or \c f format, whichever is the most concise
+ \row \i \c G \i use \c E or \c f format, whichever is the most concise
+ \endtable
+
+ With 'e', 'E', and 'f', \a prec is the number of digits after the
+ decimal point. With 'g' and 'G', \a prec is the maximum number of
+ significant digits (trailing zeroes are omitted).
+
+ \code
+ double d = 12.34;
+ TQString ds = TQString( "'E' format, precision 3, gives %1" )
+ .arg( d, 0, 'E', 3 );
+ // ds == "1.234E+001"
+ \endcode
+
+ \sa setNum()
+ */
+TQString TQString::number( double n, char f, int prec )
+{
+ TQString s;
+ s.setNum( n, f, prec );
+ return s;
+}
+
+
+/*! \obsolete
+
+ Sets the character at position \a index to \a c and expands the
+ string if necessary, filling with spaces.
+
+ This method is redundant in TQt 3.x, because operator[] will expand
+ the string as necessary.
+*/
+
+void TQString::setExpand( uint index, TQChar c )
+{
+ int spaces = index - d->len;
+ at(index) = c;
+ while (spaces-->0)
+ d->tqunicode[--index]=' ';
+}
+
+
+/*!
+ \fn const char* TQString::data() const
+
+ \obsolete
+
+ Returns a pointer to a '\0'-terminated classic C string.
+
+ In TQt 1.x, this returned a char* allowing direct manipulation of the
+ string as a sequence of bytes. In TQt 2.x where TQString is a Unicode
+ string, char* conversion constructs a temporary string, and hence
+ direct character operations are meaningless.
+*/
+
+/*!
+ \fn bool TQString::operator!() const
+
+ Returns TRUE if this is a null string; otherwise returns FALSE.
+
+ \code
+ TQString name = getName();
+ if ( !name )
+ name = "Rodney";
+ \endcode
+
+ Note that if you say
+
+ \code
+ TQString name = getName();
+ if ( name )
+ doSomethingWith(name);
+ \endcode
+
+ It will call "operator const char*()", which is inefficent; you
+ may wish to define the macro \c TQT_NO_ASCII_CAST when writing code
+ which you wish to remain Unicode-clean.
+
+ When you want the above semantics, use:
+
+ \code
+ TQString name = getName();
+ if ( !name.isNull() )
+ doSomethingWith(name);
+ \endcode
+
+ \sa isEmpty()
+*/
+
+
+/*!
+ \fn TQString& TQString::append( const TQString& str )
+
+ Appends \a str to the string and returns a reference to the
+ result.
+
+ \code
+ string = "Test";
+ string.append( "ing" ); // string == "Testing"
+ \endcode
+
+ Equivalent to operator+=().
+*/
+
+/*!
+ \fn TQString& TQString::append( char ch )
+
+ \overload
+
+ Appends character \a ch to the string and returns a reference to
+ the result.
+
+ Equivalent to operator+=().
+*/
+
+/*!
+ \fn TQString& TQString::append( TQChar ch )
+
+ \overload
+
+ Appends character \a ch to the string and returns a reference to
+ the result.
+
+ Equivalent to operator+=().
+*/
+
+/*! \fn TQString& TQString::append( const TQByteArray &str )
+ \overload
+
+ Appends \a str to the string and returns a reference to the result.
+
+ Equivalent to operator+=().
+*/
+
+/*! \fn TQString& TQString::append( const std::string &str )
+ \overload
+
+ Appends \a str to the string and returns a reference to the result.
+
+ Equivalent to operator+=().
+*/
+
+/*! \fn TQString& TQString::append( const char *str )
+ \overload
+
+ Appends \a str to the string and returns a reference to the result.
+
+ Equivalent to operator+=().
+*/
+
+/*!
+ Appends \a str to the string and returns a reference to the string.
+*/
+TQString& TQString::operator+=( const TQString &str )
+{
+ uint len1 = length();
+ uint len2 = str.length();
+ if ( len2 ) {
+ if ( isEmpty() ) {
+ operator=( str );
+ } else {
+ grow( len1+len2 );
+ memcpy( d->tqunicode+len1, str.tqunicode(), sizeof(TQChar)*len2 );
+ }
+ } else if ( isNull() && !str.isNull() ) { // ## just for 1.x compat:
+ *this = tqfromLatin1( "" );
+ }
+ return *this;
+}
+
+#ifndef TQT_NO_CAST_ASCII
+TQString &TQString::operatorPlusEqHelper( const char *s, uint len2 )
+{
+ if ( s ) {
+#ifndef TQT_NO_TEXTCODEC
+ if ( TQTextCodec::codecForCStrings() )
+ return operator+=( fromAscii( s, len2 ) );
+#endif
+
+ uint len1 = length();
+ if ( len2 == UINT_MAX )
+ len2 = int(strlen( s ));
+ if ( len2 ) {
+ grow( len1 + len2 );
+ TQChar* uc = d->tqunicode + len1;
+ while ( len2-- )
+ *uc++ = *s++;
+ } else if ( isNull() ) { // ## just for 1.x compat:
+ *this = tqfromLatin1( "" );
+ }
+ }
+ return *this;
+}
+#endif
+
+/*!
+ \overload
+
+ Appends \a str to the string and returns a reference to the string.
+*/
+#ifndef TQT_NO_CAST_ASCII
+TQString& TQString::operator+=( const char *str )
+{
+ // ### TQt 4: make this function inline
+ return operatorPlusEqHelper( str );
+}
+#endif
+
+/*! \overload
+
+ Appends \a c to the string and returns a reference to the string.
+*/
+
+TQString &TQString::operator+=( TQChar c )
+{
+ grow( length()+1 );
+ d->tqunicode[length()-1] = c;
+ return *this;
+}
+
+/*!
+ \overload
+
+ Appends \a c to the string and returns a reference to the string.
+*/
+
+TQString &TQString::operator+=( char c )
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( TQTextCodec::codecForCStrings() )
+ return operator+=( fromAscii( &c, 1 ) );
+#endif
+ grow( length()+1 );
+ d->tqunicode[length()-1] = c;
+ return *this;
+}
+
+/*!
+ \fn TQString &TQString::operator+=( const TQByteArray &str )
+ \overload
+
+ Appends \a str to the string and returns a reference to the string.
+*/
+
+/*!
+ \fn TQString &TQString::operator+=( const std::string &str )
+ \overload
+
+ Appends \a str to the string and returns a reference to the string.
+*/
+
+/*!
+ \fn char TQChar::latin1() const
+
+ Returns the Latin-1 value of this character, or 0 if it
+ cannot be represented in Latin-1.
+*/
+
+
+/*!
+ Returns a Latin-1 representation of the string. The
+ returned value is undefined if the string tqcontains non-Latin-1
+ characters. If you want to convert strings into formats other than
+ Unicode, see the TQTextCodec classes.
+
+ This function is mainly useful for boot-strapping legacy code to
+ use Unicode.
+
+ The result remains valid so long as one unmodified copy of the
+ source string exists.
+
+ \sa tqfromLatin1(), ascii(), utf8(), local8Bit()
+*/
+const char* TQString::latin1() const
+{
+ if ( !d->ascii || !d->islatin1 ) {
+ delete [] d->ascii;
+ d->ascii = tqunicodeToLatin1( d->tqunicode, d->len );
+ d->islatin1 = TRUE;
+ }
+ return d->ascii;
+}
+
+/*!
+ Returns an 8-bit ASCII representation of the string.
+
+ If a codec has been set using TQTextCodec::codecForCStrings(),
+ it is used to convert Unicode to 8-bit char. Otherwise, this function
+ does the same as latin1().
+
+ \sa fromAscii(), latin1(), utf8(), local8Bit()
+*/
+const char* TQString::ascii() const
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( TQTextCodec::codecForCStrings() ) {
+ if ( !d->ascii || d->islatin1 ) {
+ delete [] d->ascii;
+ if (d->tqunicode) {
+ TQCString s = TQTextCodec::codecForCStrings()->fromUnicode( *this );
+ d->ascii = new char[s.length() + 1];
+ memcpy(d->ascii, s.data(), s.length() + 1);
+ } else {
+ d->ascii = 0;
+ }
+ d->islatin1 = FALSE;
+ }
+ return d->ascii;
+ }
+#endif // TQT_NO_TEXTCODEC
+ return latin1();
+}
+
+/*!
+ Returns the string encoded in UTF-8 format.
+
+ See TQTextCodec for more diverse coding/decoding of Unicode strings.
+
+ \sa fromUtf8(), ascii(), latin1(), local8Bit()
+*/
+TQCString TQString::utf8() const
+{
+ int l = length();
+ int rlen = l*3+1;
+ TQCString rstr(rlen);
+ uchar* cursor = (uchar*)rstr.data();
+ const TQChar *ch = d->tqunicode;
+ for (int i=0; i < l; i++) {
+ uint u = ch->tqunicode();
+ if ( u < 0x80 ) {
+ *cursor++ = (uchar)u;
+ } else {
+ if ( u < 0x0800 ) {
+ *cursor++ = 0xc0 | ((uchar) (u >> 6));
+ } else {
+ if (u >= 0xd800 && u < 0xdc00 && i < l-1) {
+ unsigned short low = ch[1].tqunicode();
+ if (low >= 0xdc00 && low < 0xe000) {
+ ++ch;
+ ++i;
+ u = (u - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
+ }
+ }
+ if (u > 0xffff) {
+ // if people are working in utf8, but strings are encoded in eg. latin1, the resulting
+ // name might be invalid utf8. This and the corresponding code in fromUtf8 takes care
+ // we can handle this without loosing information. This can happen with latin filenames
+ // and a utf8 locale under Unix.
+ if (u > 0x10fe00 && u < 0x10ff00) {
+ *cursor++ = (u - 0x10fe00);
+ ++ch;
+ continue;
+ } else {
+ *cursor++ = 0xf0 | ((uchar) (u >> 18));
+ *cursor++ = 0x80 | ( ((uchar) (u >> 12)) & 0x3f);
+ }
+ } else {
+ *cursor++ = 0xe0 | ((uchar) (u >> 12));
+ }
+ *cursor++ = 0x80 | ( ((uchar) (u >> 6)) & 0x3f);
+ }
+ *cursor++ = 0x80 | ((uchar) (u&0x3f));
+ }
+ ++ch;
+ }
+ rstr.truncate( cursor - (uchar*)rstr.data() );
+ return rstr;
+}
+
+static TQChar *addOne(TQChar *qch, TQString &str)
+{
+ long sidx = qch - str.tqunicode();
+ str.setLength(str.length()+1);
+ return (TQChar *)str.tqunicode() + sidx;
+}
+
+/*!
+ Returns the Unicode string decoded from the first \a len
+ bytes of \a utf8, ignoring the rest of \a utf8. If \a len is
+ -1 then the length of \a utf8 is used. If \a len is bigger than
+ the length of \a utf8 then it will use the length of \a utf8.
+
+ \code
+ TQString str = TQString::fromUtf8( "123456789", 5 );
+ // str == "12345"
+ \endcode
+
+ See TQTextCodec for more diverse coding/decoding of Unicode strings.
+*/
+TQString TQString::fromUtf8( const char* utf8, int len )
+{
+ if ( !utf8 )
+ return TQString::null;
+
+ int slen = 0;
+ if (len >= 0) {
+ while (slen < len && utf8[slen])
+ slen++;
+ } else {
+ slen = int(strlen(utf8));
+ }
+ len = len < 0 ? slen : TQMIN(slen, len);
+ TQString result;
+ result.setLength( len ); // worst case
+ TQChar *qch = (TQChar *)result.tqunicode();
+ uint uc = 0;
+ uint min_uc = 0;
+ int need = 0;
+ int error = -1;
+ uchar ch;
+ for (int i=0; i<len; i++) {
+ ch = utf8[i];
+ if (need) {
+ if ( (ch&0xc0) == 0x80 ) {
+ uc = (uc << 6) | (ch & 0x3f);
+ need--;
+ if ( !need ) {
+ if (uc > 0xffff) {
+ // surrogate pair
+ uc -= 0x10000;
+ unsigned short high = uc/0x400 + 0xd800;
+ unsigned short low = uc%0x400 + 0xdc00;
+ *qch++ = TQChar(high);
+ *qch++ = TQChar(low);
+ } else if (uc < min_uc || (uc >= 0xd800 && uc <= 0xdfff) || (uc >= 0xfffe)) {
+ // overlong seqence, UTF16 surrogate or BOM
+ i = error;
+ qch = addOne(qch, result);
+ *qch++ = TQChar(0xdbff);
+ *qch++ = TQChar(0xde00+((uchar)utf8[i]));
+ } else {
+ *qch++ = uc;
+ }
+ }
+ } else {
+ // See TQString::utf8() for explanation.
+ //
+ // The surrogate below corresponds to a Unicode value of (0x10fe00+ch) which
+ // is in one of the private use areas of Unicode.
+ i = error;
+ qch = addOne(qch, result);
+ *qch++ = TQChar(0xdbff);
+ *qch++ = TQChar(0xde00+((uchar)utf8[i]));
+ need = 0;
+ }
+ } else {
+ if ( ch < 128 ) {
+ *qch++ = ch;
+ } else if ((ch & 0xe0) == 0xc0) {
+ uc = ch & 0x1f;
+ need = 1;
+ error = i;
+ min_uc = 0x80;
+ } else if ((ch & 0xf0) == 0xe0) {
+ uc = ch & 0x0f;
+ need = 2;
+ error = i;
+ min_uc = 0x800;
+ } else if ((ch&0xf8) == 0xf0) {
+ uc = ch & 0x07;
+ need = 3;
+ error = i;
+ min_uc = 0x10000;
+ } else {
+ // Error
+ qch = addOne(qch, result);
+ *qch++ = TQChar(0xdbff);
+ *qch++ = TQChar(0xde00+((uchar)utf8[i]));
+ }
+ }
+ }
+ if (need) {
+ // we have some invalid characters remaining we need to add to the string
+ for (int i = error; i < len; ++i) {
+ qch = addOne(qch, result);
+ *qch++ = TQChar(0xdbff);
+ *qch++ = TQChar(0xde00+((uchar)utf8[i]));
+ }
+ }
+
+ result.truncate( qch - result.tqunicode() );
+ return result;
+}
+
+/*!
+ Returns the Unicode string decoded from the first \a len
+ bytes of \a ascii, ignoring the rest of \a ascii. If \a len
+ is -1 then the length of \a ascii is used. If \a len is bigger
+ than the length of \a ascii then it will use the length of \a
+ ascii.
+
+ If a codec has been set using TQTextCodec::codecForCStrings(),
+ it is used to convert the string from 8-bit characters to Unicode.
+ Otherwise, this function does the same as tqfromLatin1().
+
+ This is the same as the TQString(const char*) constructor, but you
+ can make that constructor invisible if you compile with the define
+ \c TQT_NO_CAST_ASCII, in which case you can explicitly create a
+ TQString from 8-bit ASCII text using this function.
+
+ \code
+ TQString str = TQString::fromAscii( "123456789", 5 );
+ // str == "12345"
+ \endcode
+ */
+TQString TQString::fromAscii( const char* ascii, int len )
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( TQTextCodec::codecForCStrings() ) {
+ if ( !ascii )
+ return TQString::null;
+ if ( len < 0 )
+ len = (int)strlen( ascii );
+ if ( len == 0 || *ascii == '\0' )
+ return TQString::tqfromLatin1( "" );
+ return TQTextCodec::codecForCStrings()->toUnicode( ascii, len );
+ }
+#endif
+ return tqfromLatin1( ascii, len );
+}
+
+
+/*!
+ Returns the Unicode string decoded from the first \a len
+ bytes of \a chars, ignoring the rest of \a chars. If \a len
+ is -1 then the length of \a chars is used. If \a len is bigger
+ than the length of \a chars then it will use the length of \a
+ chars.
+
+ \sa fromAscii()
+*/
+TQString TQString::tqfromLatin1( const char* chars, int len )
+{
+ uint l;
+ TQChar *uc;
+ if ( len < 0 )
+ len = -1;
+ uc = internalLatin1ToUnicode( chars, &l, len );
+ return TQString( new TQStringData(uc, l, l), TRUE );
+}
+
+/*!
+ \fn const TQChar* TQString::tqunicode() const
+
+ Returns the Unicode representation of the string. The result
+ remains valid until the string is modified.
+*/
+
+/*!
+ Returns the string encoded in a locale-specific format. On X11,
+ this is the TQTextCodec::codecForLocale(). On Windows, it is a
+ system-defined encoding. On Mac OS X, this always uses UTF-8 as
+ the encoding.
+
+ See TQTextCodec for more diverse coding/decoding of Unicode
+ strings.
+
+ \sa fromLocal8Bit(), ascii(), latin1(), utf8()
+*/
+
+TQCString TQString::local8Bit() const
+{
+#ifdef TQT_NO_TEXTCODEC
+ return latin1();
+#else
+#ifdef TQ_WS_X11
+ TQTextCodec* codec = TQTextCodec::codecForLocale();
+ return codec
+ ? codec->fromUnicode(*this)
+ : TQCString(latin1());
+#endif
+#if defined( TQ_WS_MACX )
+ return utf8();
+#endif
+#if defined( TQ_WS_MAC9 )
+ return TQCString(latin1()); //I'm evil..
+#endif
+#ifdef TQ_WS_WIN
+ return isNull() ? TQCString("") : qt_winTQString2MB( *this );
+#endif
+#ifdef TQ_WS_TQWS
+ return utf8(); // ### if there is any 8 bit format supported?
+#endif
+#endif
+}
+
+/*!
+ Returns the Unicode string decoded from the first \a len
+ bytes of \a local8Bit, ignoring the rest of \a local8Bit. If
+ \a len is -1 then the length of \a local8Bit is used. If \a len is
+ bigger than the length of \a local8Bit then it will use the length
+ of \a local8Bit.
+
+ \code
+ TQString str = TQString::fromLocal8Bit( "123456789", 5 );
+ // str == "12345"
+ \endcode
+
+ \a local8Bit is assumed to be encoded in a locale-specific format.
+
+ See TQTextCodec for more diverse coding/decoding of Unicode strings.
+*/
+TQString TQString::fromLocal8Bit( const char* local8Bit, int len )
+{
+#ifdef TQT_NO_TEXTCODEC
+ return tqfromLatin1( local8Bit, len );
+#else
+
+ if ( !local8Bit )
+ return TQString::null;
+#ifdef TQ_WS_X11
+ TQTextCodec* codec = TQTextCodec::codecForLocale();
+ if ( len < 0 )
+ len = strlen( local8Bit );
+ return codec
+ ? codec->toUnicode( local8Bit, len )
+ : tqfromLatin1( local8Bit, len );
+#endif
+#if defined( TQ_WS_MAC )
+ return fromUtf8(local8Bit,len);
+#endif
+// Should this be OS_WIN32?
+#ifdef TQ_WS_WIN
+ if ( len >= 0 ) {
+ TQCString s(local8Bit,len+1);
+ return qt_winMB2TQString(s);
+ }
+ return qt_winMB2TQString( local8Bit );
+#endif
+#ifdef TQ_WS_TQWS
+ return fromUtf8(local8Bit,len);
+#endif
+#endif // TQT_NO_TEXTCODEC
+}
+
+/*!
+ \fn TQString::operator const char *() const
+
+ Returns ascii(). Be sure to see the warnings documented in the
+ ascii() function. Note that for new code which you wish to be
+ strictly Unicode-clean, you can define the macro \c
+ TQT_NO_ASCII_CAST when compiling your code to hide this function so
+ that automatic casts are not done. This has the added advantage
+ that you catch the programming error described in operator!().
+*/
+
+/*!
+ \fn TQString::operator std::string() const
+
+ Returns ascii() as a std::string.
+
+ \warning The function may cause an application to crash if a static C run-time is in use.
+ This can happen in Microsoft Visual C++ if TQt is configured as single-threaded. A safe
+ alternative is to call ascii() directly and construct a std::string manually.
+*/
+
+/*!
+ Returns the TQString as a zero terminated array of unsigned shorts
+ if the string is not null; otherwise returns zero.
+
+ The result remains valid so long as one unmodified
+ copy of the source string exists.
+*/
+const unsigned short *TQString::ucs2() const
+{
+ if ( ! d->tqunicode )
+ return 0;
+ unsigned int len = d->len;
+ if ( d->maxl < len + 1 ) {
+ // detach, grow or shrink
+ uint newMax = computeNewMax( len + 1 );
+ TQChar* nd = TQT_ALLOC_TQCHAR_VEC( newMax );
+ if ( nd ) {
+ if ( d->tqunicode )
+ memcpy( nd, d->tqunicode, sizeof(TQChar)*len );
+ ((TQString *)this)->deref();
+ ((TQString *)this)->d = new TQStringData( nd, len, newMax );
+ }
+ }
+ d->tqunicode[len] = 0;
+ return (unsigned short *) d->tqunicode;
+}
+
+/*!
+ Constructs a string that is a deep copy of \a str, interpreted as a
+ UCS2 encoded, zero terminated, Unicode string.
+
+ If \a str is 0, then a null string is created.
+
+ \sa isNull()
+*/
+TQString TQString::fromUcs2( const unsigned short *str )
+{
+ if ( !str ) {
+ return TQString::null;
+ } else {
+ int length = 0;
+ while ( str[length] != 0 )
+ length++;
+ TQChar* uc = TQT_ALLOC_TQCHAR_VEC( length );
+ memcpy( uc, str, length*sizeof(TQChar) );
+ return TQString( new TQStringData( uc, length, length ), TRUE );
+ }
+}
+
+/*!
+ \fn TQChar TQString::at( uint ) const
+
+ Returns the character at index \a i, or 0 if \a i is beyond the
+ length of the string.
+
+ \code
+ const TQString string( "abcdefgh" );
+ TQChar ch = string.at( 4 );
+ // ch == 'e'
+ \endcode
+
+ If the TQString is not const (i.e. const TQString) or const& (i.e.
+ const TQString &), then the non-const overload of at() will be used
+ instead.
+*/
+
+/*!
+ \fn TQChar TQString::constref(uint i) const
+
+ Returns the TQChar at index \a i by value.
+
+ Equivalent to at(\a i).
+
+ \sa ref()
+*/
+
+/*!
+ \fn TQChar& TQString::ref(uint i)
+
+ Returns the TQChar at index \a i by reference, expanding the string
+ with TQChar::null if necessary. The resulting reference can be
+ assigned to, or otherwise used immediately, but becomes invalid
+ once furher modifications are made to the string.
+
+ \code
+ TQString string("ABCDEF");
+ TQChar ch = string.ref( 3 ); // ch == 'D'
+ \endcode
+
+ \sa constref()
+*/
+
+/*!
+ \fn TQChar TQString::operator[]( int ) const
+
+ Returns the character at index \a i, or TQChar::null if \a i is
+ beyond the length of the string.
+
+ If the TQString is not const (i.e., const TQString) or const\&
+ (i.e., const TQString\&), then the non-const overload of operator[]
+ will be used instead.
+*/
+
+/*!
+ \fn TQCharRef TQString::operator[]( int )
+
+ \overload
+
+ The function returns a reference to the character at index \a i.
+ The resulting reference can then be assigned to, or used
+ immediately, but it will become invalid once further modifications
+ are made to the original string.
+
+ If \a i is beyond the length of the string then the string is
+ expanded with TQChar::nulls, so that the TQCharRef references a
+ valid (null) character in the string.
+
+ The TQCharRef internal class can be used much like a constant
+ TQChar, but if you assign to it, you change the original string
+ (which will detach itself because of TQString's copy-on-write
+ semantics). You will get compilation errors if you try to use the
+ result as anything but a TQChar.
+*/
+
+/*!
+ \fn TQCharRef TQString::at( uint i )
+
+ \overload
+
+ The function returns a reference to the character at index \a i.
+ The resulting reference can then be assigned to, or used
+ immediately, but it will become invalid once further modifications
+ are made to the original string.
+
+ If \a i is beyond the length of the string then the string is
+ expanded with TQChar::null.
+*/
+
+/*
+ Internal chunk of code to handle the
+ uncommon cases of at() above.
+*/
+void TQString::subat( uint i )
+{
+ uint olen = d->len;
+ if ( i >= olen ) {
+ setLength( i+1 ); // i is index; i+1 is needed length
+ for ( uint j=olen; j<=i; j++ )
+ d->tqunicode[j] = TQChar::null;
+ } else {
+ // Just be sure to detach
+ real_detach();
+ }
+}
+
+
+/*!
+ Resizes the string to \a len characters and copies \a tqunicode into
+ the string. If \a tqunicode is 0, nothing is copied, but the
+ string is still resized to \a len. If \a len is zero, then the
+ string becomes a \link isNull() null\endlink string.
+
+ \sa setLatin1(), isNull()
+*/
+
+TQString& TQString::setUnicode( const TQChar *tqunicode, uint len )
+{
+ if ( len == 0 ) { // set to null string
+ if ( d != shared_null ) { // beware of nullstring being set to nullstring
+ deref();
+ d = shared_null ? shared_null : makeSharedNull();
+ d->ref();
+ }
+ } else if ( d->count != 1 || len > d->maxl ||
+ ( len * 4 < d->maxl && d->maxl > 4 ) ) {
+ // detach, grown or shrink
+ uint newMax = computeNewMax( len );
+ TQChar* nd = TQT_ALLOC_TQCHAR_VEC( newMax );
+ if ( tqunicode )
+ memcpy( nd, tqunicode, sizeof(TQChar)*len );
+ deref();
+ d = new TQStringData( nd, len, newMax );
+ } else {
+ d->len = len;
+ d->setDirty();
+ if ( tqunicode )
+ memcpy( d->tqunicode, tqunicode, sizeof(TQChar)*len );
+ }
+ return *this;
+}
+
+/*!
+ Resizes the string to \a len characters and copies \a
+ tqunicode_as_ushorts into the string (on some X11 client platforms
+ this will involve a byte-swapping pass).
+
+ If \a tqunicode_as_ushorts is 0, nothing is copied, but the string
+ is still resized to \a len. If \a len is zero, the string becomes
+ a \link isNull() null\endlink string.
+
+ \sa setLatin1(), isNull()
+*/
+TQString& TQString::setUnicodeCodes( const ushort* tqunicode_as_ushorts, uint len )
+{
+ return setUnicode((const TQChar*)tqunicode_as_ushorts, len);
+}
+
+
+/*!
+ Sets this string to \a str, interpreted as a classic 8-bit ASCII C
+ string. If \a len is -1 (the default), then it is set to
+ strlen(str).
+
+ If \a str is 0 a null string is created. If \a str is "", an empty
+ string is created.
+
+ \sa isNull(), isEmpty()
+*/
+
+TQString &TQString::setAscii( const char *str, int len )
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( TQTextCodec::codecForCStrings() ) {
+ *this = TQString::fromAscii( str, len );
+ return *this;
+ }
+#endif // TQT_NO_TEXTCODEC
+ return setLatin1( str, len );
+}
+
+/*!
+ Sets this string to \a str, interpreted as a classic Latin-1 C
+ string. If \a len is -1 (the default), then it is set to
+ strlen(str).
+
+ If \a str is 0 a null string is created. If \a str is "", an empty
+ string is created.
+
+ \sa isNull(), isEmpty()
+*/
+
+TQString &TQString::setLatin1( const char *str, int len )
+{
+ if ( str == 0 )
+ return setUnicode(0,0);
+ if ( len < 0 )
+ len = int(strlen( str ));
+ if ( len == 0 ) { // won't make a null string
+ *this = TQString::tqfromLatin1( "" );
+ } else {
+ setUnicode( 0, len ); // resize but not copy
+ TQChar *p = d->tqunicode;
+ while ( len-- )
+ *p++ = *str++;
+ }
+ return *this;
+}
+
+/*! \internal
+ */
+void TQString::checkSimpleText() const
+{
+ TQChar *p = d->tqunicode;
+ TQChar *end = p + d->len;
+ while ( p < end ) {
+ ushort uc = p->tqunicode();
+ // sort out regions of complex text formatting
+ if ( uc > 0x058f && ( uc < 0x1100 || uc > 0xfb0f ) ) {
+ d->issimpletext = FALSE;
+ return;
+ }
+ p++;
+ }
+ d->issimpletext = TRUE;
+}
+
+/*! \fn bool TQString::simpleText() const
+ \internal
+*/
+
+/*! \internal
+ */
+bool TQString::isRightToLeft() const
+{
+ int len = length();
+ TQChar *p = d->tqunicode;
+ while ( len-- ) {
+ switch( ::direction( *p ) )
+ {
+ case TQChar::DirL:
+ case TQChar::DirLRO:
+ case TQChar::DirLRE:
+ return FALSE;
+ case TQChar::DirR:
+ case TQChar::DirAL:
+ case TQChar::DirRLO:
+ case TQChar::DirRLE:
+ return TRUE;
+ default:
+ break;
+ }
+ ++p;
+ }
+ return FALSE;
+}
+
+
+/*!
+ \fn int TQString::compare( const TQString & s1, const TQString & s2 )
+
+ Lexically compares \a s1 with \a s2 and returns an integer less
+ than, equal to, or greater than zero if \a s1 is less than, equal
+ to, or greater than \a s2.
+
+ The comparison is based exclusively on the numeric Unicode values
+ of the characters and is very fast, but is not what a human would
+ expect. Consider sorting user-interface strings with
+ TQString::localeAwareCompare().
+
+ \code
+ int a = TQString::compare( "def", "abc" ); // a > 0
+ int b = TQString::compare( "abc", "def" ); // b < 0
+ int c = TQString::compare( "abc", "abc" ); // c == 0
+ \endcode
+*/
+
+/*!
+ \overload
+
+ Lexically compares this string with \a s and returns an integer
+ less than, equal to, or greater than zero if it is less than, equal
+ to, or greater than \a s.
+*/
+int TQString::compare( const TQString& s ) const
+{
+ return ucstrcmp( *this, s );
+}
+
+/*!
+ \fn int TQString::localeAwareCompare( const TQString & s1, const TQString & s2 )
+
+ Compares \a s1 with \a s2 and returns an integer less than, equal
+ to, or greater than zero if \a s1 is less than, equal to, or
+ greater than \a s2.
+
+ The comparison is performed in a locale- and also
+ platform-dependent manner. Use this function to present sorted
+ lists of strings to the user.
+
+ \sa TQString::compare() TQTextCodec::locale()
+*/
+
+/*!
+ \overload
+
+ Compares this string with \a s.
+*/
+
+#if !defined(CSTR_LESS_THAN)
+#define CSTR_LESS_THAN 1
+#define CSTR_ETQUAL 2
+#define CSTR_GREATER_THAN 3
+#endif
+
+int TQString::localeAwareCompare( const TQString& s ) const
+{
+ // do the right thing for null and empty
+ if ( isEmpty() || s.isEmpty() )
+ return compare( s );
+
+#if defined(TQ_WS_WIN)
+ int res;
+ TQT_WA( {
+ const TCHAR* s1 = (TCHAR*)ucs2();
+ const TCHAR* s2 = (TCHAR*)s.ucs2();
+ res = CompareStringW( LOCALE_USER_DEFAULT, 0, s1, length(), s2, s.length() );
+ } , {
+ TQCString s1 = local8Bit();
+ TQCString s2 = s.local8Bit();
+ res = CompareStringA( LOCALE_USER_DEFAULT, 0, s1.data(), s1.length(), s2.data(), s2.length() );
+ } );
+
+ switch ( res ) {
+ case CSTR_LESS_THAN:
+ return -1;
+ case CSTR_GREATER_THAN:
+ return 1;
+ default:
+ return 0;
+ }
+#elif defined(TQ_WS_MACX)
+ int delta = 0;
+#if !defined(TQT_NO_TEXTCODEC)
+ TQTextCodec *codec = TQTextCodec::codecForLocale();
+ if (codec)
+ delta = strcoll(codec->fromUnicode(*this), codec->fromUnicode(s));
+ if (delta == 0)
+#endif
+ delta = ucstrcmp(*this, s);
+ return delta;
+#elif defined(TQ_WS_X11)
+ // declared in <string.h>
+ int delta = strcoll( local8Bit(), s.local8Bit() );
+ if ( delta == 0 )
+ delta = ucstrcmp( *this, s );
+ return delta;
+#else
+ return ucstrcmp( *this, s );
+#endif
+}
+
+bool operator==( const TQString &s1, const TQString &s2 )
+{
+ if ( s1.tqunicode() == s2.tqunicode() )
+ return TRUE;
+ return (s1.length() == s2.length()) && s1.isNull() == s2.isNull() &&
+ (memcmp((char*)s1.tqunicode(),(char*)s2.tqunicode(),
+ s1.length()*sizeof(TQChar)) == 0 );
+}
+
+bool operator!=( const TQString &s1, const TQString &s2 )
+{ return !(s1==s2); }
+
+bool operator<( const TQString &s1, const TQString &s2 )
+{ return ucstrcmp(s1,s2) < 0; }
+
+bool operator<=( const TQString &s1, const TQString &s2 )
+{ return ucstrcmp(s1,s2) <= 0; }
+
+bool operator>( const TQString &s1, const TQString &s2 )
+{ return ucstrcmp(s1,s2) > 0; }
+
+bool operator>=( const TQString &s1, const TQString &s2 )
+{ return ucstrcmp(s1,s2) >= 0; }
+
+
+bool operator==( const TQString &s1, const char *s2 )
+{
+ if ( !s2 )
+ return s1.isNull();
+
+ int len = s1.length();
+ const TQChar *uc = s1.tqunicode();
+ while ( len ) {
+ if ( !(*s2) || uc->tqunicode() != (uchar) *s2 )
+ return FALSE;
+ ++uc;
+ ++s2;
+ --len;
+ }
+ return !*s2;
+}
+
+bool operator==( const char *s1, const TQString &s2 )
+{ return (s2 == s1); }
+
+bool operator!=( const TQString &s1, const char *s2 )
+{ return !(s1==s2); }
+
+bool operator!=( const char *s1, const TQString &s2 )
+{ return !(s1==s2); }
+
+bool operator<( const TQString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) < 0; }
+
+bool operator<( const char *s1, const TQString &s2 )
+{ return ucstrcmp(s1,s2) < 0; }
+
+bool operator<=( const TQString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) <= 0; }
+
+bool operator<=( const char *s1, const TQString &s2 )
+{ return ucstrcmp(s1,s2) <= 0; }
+
+bool operator>( const TQString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) > 0; }
+
+bool operator>( const char *s1, const TQString &s2 )
+{ return ucstrcmp(s1,s2) > 0; }
+
+bool operator>=( const TQString &s1, const char *s2 )
+{ return ucstrcmp(s1,s2) >= 0; }
+
+bool operator>=( const char *s1, const TQString &s2 )
+{ return ucstrcmp(s1,s2) >= 0; }
+
+
+/*****************************************************************************
+ Documentation for TQString related functions
+ *****************************************************************************/
+
+/*!
+ \fn bool operator==( const TQString &s1, const TQString &s2 )
+
+ \relates TQString
+
+ Returns TRUE if \a s1 is equal to \a s2; otherwise returns FALSE.
+ Note that a null string is not equal to a not-null empty string.
+
+ Equivalent to compare(\a s1, \a s2) == 0.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool operator==( const TQString &s1, const char *s2 )
+
+ \overload
+ \relates TQString
+
+ Returns TRUE if \a s1 is equal to \a s2; otherwise returns FALSE.
+ Note that a null string is not equal to a not-null empty string.
+
+ Equivalent to compare(\a s1, \a s2) == 0.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool operator==( const char *s1, const TQString &s2 )
+
+ \overload
+ \relates TQString
+
+ Returns TRUE if \a s1 is equal to \a s2; otherwise returns FALSE.
+ Note that a null string is not equal to a not-null empty string.
+
+ Equivalent to compare(\a s1, \a s2) == 0.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool operator!=( const TQString &s1, const TQString &s2 )
+
+ \relates TQString
+
+ Returns TRUE if \a s1 is not equal to \a s2; otherwise returns FALSE.
+ Note that a null string is not equal to a not-null empty string.
+
+ Equivalent to compare(\a s1, \a s2) != 0.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool operator!=( const TQString &s1, const char *s2 )
+
+ \overload
+ \relates TQString
+
+ Returns TRUE if \a s1 is not equal to \a s2; otherwise returns FALSE.
+ Note that a null string is not equal to a not-null empty string.
+
+ Equivalent to compare(\a s1, \a s2) != 0.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool operator!=( const char *s1, const TQString &s2 )
+
+ \overload
+ \relates TQString
+
+ Returns TRUE if \a s1 is not equal to \a s2; otherwise returns FALSE.
+ Note that a null string is not equal to a not-null empty string.
+
+ Equivalent to compare(\a s1, \a s2) != 0.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool operator<( const TQString &s1, const char *s2 )
+
+ \relates TQString
+
+ Returns TRUE if \a s1 is lexically less than \a s2; otherwise returns FALSE.
+ The comparison is case sensitive.
+
+ Equivalent to compare(\a s1, \a s2) \< 0.
+*/
+
+/*!
+ \fn bool operator<( const char *s1, const TQString &s2 )
+
+ \overload
+ \relates TQString
+
+ Returns TRUE if \a s1 is lexically less than \a s2; otherwise returns FALSE.
+ The comparison is case sensitive.
+
+ Equivalent to compare(\a s1, \a s2) \< 0.
+*/
+
+/*!
+ \fn bool operator<=( const TQString &s1, const char *s2 )
+
+ \relates TQString
+
+ Returns TRUE if \a s1 is lexically less than or equal to \a s2;
+ otherwise returns FALSE.
+ The comparison is case sensitive.
+ Note that a null string is not equal to a not-null empty string.
+
+ Equivalent to compare(\a s1,\a s2) \<= 0.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool operator<=( const char *s1, const TQString &s2 )
+
+ \overload
+ \relates TQString
+
+ Returns TRUE if \a s1 is lexically less than or equal to \a s2;
+ otherwise returns FALSE.
+ The comparison is case sensitive.
+ Note that a null string is not equal to a not-null empty string.
+
+ Equivalent to compare(\a s1, \a s2) \<= 0.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool operator>( const TQString &s1, const char *s2 )
+
+ \relates TQString
+
+ Returns TRUE if \a s1 is lexically greater than \a s2; otherwise
+ returns FALSE.
+ The comparison is case sensitive.
+
+ Equivalent to compare(\a s1, \a s2) \> 0.
+*/
+
+/*!
+ \fn bool operator>( const char *s1, const TQString &s2 )
+
+ \overload
+ \relates TQString
+
+ Returns TRUE if \a s1 is lexically greater than \a s2; otherwise
+ returns FALSE.
+ The comparison is case sensitive.
+
+ Equivalent to compare(\a s1, \a s2) \> 0.
+*/
+
+/*!
+ \fn bool operator>=( const TQString &s1, const char *s2 )
+
+ \relates TQString
+
+ Returns TRUE if \a s1 is lexically greater than or equal to \a s2;
+ otherwise returns FALSE.
+ The comparison is case sensitive.
+ Note that a null string is not equal to a not-null empty string.
+
+ Equivalent to compare(\a s1, \a s2) \>= 0.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn bool operator>=( const char *s1, const TQString &s2 )
+
+ \overload
+ \relates TQString
+
+ Returns TRUE if \a s1 is lexically greater than or equal to \a s2;
+ otherwise returns FALSE.
+ The comparison is case sensitive.
+ Note that a null string is not equal to a not-null empty string.
+
+ Equivalent to compare(\a s1, \a s2) \>= 0.
+
+ \sa isNull(), isEmpty()
+*/
+
+/*!
+ \fn const TQString operator+( const TQString &s1, const TQString &s2 )
+
+ \relates TQString
+
+ Returns a string which is the result of concatenating the string
+ \a s1 and the string \a s2.
+
+ Equivalent to \a {s1}.append(\a s2).
+*/
+
+/*!
+ \fn const TQString operator+( const TQString &s1, const char *s2 )
+
+ \overload
+ \relates TQString
+
+ Returns a string which is the result of concatenating the string
+ \a s1 and character \a s2.
+
+ Equivalent to \a {s1}.append(\a s2).
+*/
+
+/*!
+ \fn const TQString operator+( const char *s1, const TQString &s2 )
+
+ \overload
+ \relates TQString
+
+ Returns a string which is the result of concatenating the
+ character \a s1 and string \a s2.
+*/
+
+/*!
+ \fn const TQString operator+( const TQString &s, char c )
+
+ \overload
+ \relates TQString
+
+ Returns a string which is the result of concatenating the string
+ \a s and character \a c.
+
+ Equivalent to \a {s}.append(\a c).
+*/
+
+/*!
+ \fn const TQString operator+( char c, const TQString &s )
+
+ \overload
+ \relates TQString
+
+ Returns a string which is the result of concatenating the
+ character \a c and string \a s.
+
+ Equivalent to \a {s}.prepend(\a c).
+*/
+
+
+/*****************************************************************************
+ TQString stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQString
+
+ Writes the string \a str to the stream \a s.
+
+ See also \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator<<( TQDataStream &s, const TQString &str )
+{
+ if ( s.version() == 1 ) {
+ TQCString l( str.latin1() );
+ s << l;
+ }
+ else {
+ int byteOrder = s.byteOrder();
+ const TQChar* ub = str.tqunicode();
+ if ( ub || s.version() < 3 ) {
+ static const uint auto_size = 1024;
+ char t[auto_size];
+ char *b;
+ if ( str.length()*sizeof(TQChar) > auto_size ) {
+ b = new char[str.length()*sizeof(TQChar)];
+ } else {
+ b = t;
+ }
+ int l = str.length();
+ char *c=b;
+ while ( l-- ) {
+ if ( byteOrder == TQDataStream::BigEndian ) {
+ *c++ = (char)ub->row();
+ *c++ = (char)ub->cell();
+ } else {
+ *c++ = (char)ub->cell();
+ *c++ = (char)ub->row();
+ }
+ ub++;
+ }
+ s.writeBytes( b, sizeof(TQChar)*str.length() );
+ if ( str.length()*sizeof(TQChar) > auto_size )
+ delete [] b;
+ } else {
+ // write null marker
+ s << (TQ_UINT32)0xffffffff;
+ }
+ }
+ return s;
+}
+
+/*!
+ \relates TQString
+
+ Reads a string from the stream \a s into string \a str.
+
+ See also \link datastreamformat.html Format of the TQDataStream operators \endlink
+*/
+
+TQDataStream &operator>>( TQDataStream &s, TQString &str )
+{
+#ifdef TQT_TQSTRING_UCS_4
+#if defined(TQ_CC_GNU)
+#warning "operator>> not working properly"
+#endif
+#endif
+ if ( s.version() == 1 ) {
+ TQCString l;
+ s >> l;
+ str = TQString( l );
+ }
+ else {
+ TQ_UINT32 bytes = 0;
+ s >> bytes; // read size of string
+ if ( bytes == 0xffffffff ) { // null string
+ str = TQString::null;
+ } else if ( bytes > 0 ) { // not empty
+ int byteOrder = s.byteOrder();
+ str.setLength( bytes/2 );
+ TQChar* ch = str.d->tqunicode;
+ static const uint auto_size = 1024;
+ char t[auto_size];
+ char *b;
+ if ( bytes > auto_size ) {
+ b = new char[bytes];
+ } else {
+ b = t;
+ }
+ s.readRawBytes( b, bytes );
+ int bt = bytes/2;
+ char *oldb = b;
+ while ( bt-- ) {
+ if ( byteOrder == TQDataStream::BigEndian )
+ *ch++ = (ushort) (((ushort)b[0])<<8) | (uchar)b[1];
+ else
+ *ch++ = (ushort) (((ushort)b[1])<<8) | (uchar)b[0];
+ b += 2;
+ }
+ if ( bytes > auto_size )
+ delete [] oldb;
+ } else {
+ str = "";
+ }
+ }
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+/*****************************************************************************
+ TQConstString member functions
+ *****************************************************************************/
+
+/*!
+ \class TQConstString tqstring.h
+ \reentrant
+ \ingroup text
+ \brief The TQConstString class provides string objects using constant Unicode data.
+
+ In order to minimize copying, highly optimized applications can
+ use TQConstString to provide a TQString-compatible object from
+ existing Unicode data. It is then the programmer's responsibility
+ to ensure that the Unicode data exists for the entire lifetime of
+ the TQConstString object.
+
+ A TQConstString is created with the TQConstString constructor. The
+ string held by the object can be obtained by calling string().
+*/
+
+/*!
+ Constructs a TQConstString that uses the first \a length Unicode
+ characters in the array \a tqunicode. Any attempt to modify copies
+ of the string will cause it to create a copy of the data, thus it
+ remains forever unmodified.
+
+ The data in \a tqunicode is not copied. The caller must be able to
+ guarantee that \a tqunicode will not be deleted or modified.
+*/
+TQConstString::TQConstString( const TQChar* tqunicode, uint length ) :
+ TQString( new TQStringData( (TQChar*)tqunicode, length, length ), TRUE )
+{
+}
+
+/*!
+ Destroys the TQConstString, creating a copy of the data if other
+ strings are still using it.
+*/
+TQConstString::~TQConstString()
+{
+ if ( d->count > 1 ) {
+ TQChar* cp = TQT_ALLOC_TQCHAR_VEC( d->len );
+ memcpy( cp, d->tqunicode, d->len*sizeof(TQChar) );
+ d->tqunicode = cp;
+ } else {
+ d->tqunicode = 0;
+ }
+
+ // The original d->tqunicode is now unlinked.
+}
+
+/*!
+ \fn const TQString& TQConstString::string() const
+
+ Returns a constant string referencing the data passed during
+ construction.
+*/
+
+/*!
+ Returns TRUE if the string starts with \a s; otherwise returns
+ FALSE.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ \code
+ TQString str( "Bananas" );
+ str.startsWith( "Ban" ); // returns TRUE
+ str.startsWith( "Car" ); // returns FALSE
+ \endcode
+
+ \sa endsWith()
+*/
+bool TQString::startsWith( const TQString& s, bool cs ) const
+{
+ if ( isNull() )
+ return s.isNull();
+ if ( s.length() > length() )
+ return FALSE;
+ if ( cs ) {
+ return memcmp((char*)d->tqunicode, (char*)s.d->tqunicode, s.length()*sizeof(TQChar)) == 0;
+ } else {
+ for ( int i = 0; i < (int) s.length(); i++ ) {
+ if ( ::lower(d->tqunicode[i]) != ::lower(s.d->tqunicode[i]) )
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+bool TQString::startsWith( const TQString& s ) const
+{
+ return startsWith( s, TRUE );
+}
+
+/*!
+ Returns TRUE if the string ends with \a s; otherwise returns
+ FALSE.
+
+ If \a cs is TRUE (the default), the search is case sensitive;
+ otherwise the search is case insensitive.
+
+ \code
+ TQString str( "Bananas" );
+ str.endsWith( "anas" ); // returns TRUE
+ str.endsWith( "pple" ); // returns FALSE
+ \endcode
+
+ \sa startsWith()
+*/
+bool TQString::endsWith( const TQString& s, bool cs ) const
+{
+ if ( isNull() )
+ return s.isNull();
+ int pos = length() - s.length();
+ if ( pos < 0 )
+ return FALSE;
+ if ( cs ) {
+ return memcmp((char*)&d->tqunicode[pos], (char*)s.d->tqunicode, s.length()*sizeof(TQChar)) == 0;
+ } else {
+ for ( int i = 0; i < (int) s.length(); i++ ) {
+ if ( ::lower(d->tqunicode[pos + i]) != ::lower(s.d->tqunicode[i]) )
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+bool TQString::endsWith( const TQString& s ) const
+{
+ return endsWith( s, TRUE );
+}
+
+/*! \fn void TQString::detach()
+ If the string does not share its data with another TQString instance,
+ nothing happens; otherwise the function creates a new, unique copy of
+ this string. This function is called whenever the string is modified. The
+ implicit sharing mechanism is implemented this way.
+*/
+
+#if defined(TQ_OS_WIN32)
+
+#include <windows.h>
+
+/*!
+ \obsolete
+
+ Returns a static Windows TCHAR* from a TQString, adding NUL if \a
+ addnul is TRUE.
+
+ The lifetime of the return value is until the next call to this function,
+ or until the last copy of str is deleted, whatever comes first.
+
+ Use ucs2() instead.
+*/
+const void* qt_winTchar(const TQString& str, bool)
+{
+ // So that the return value lives long enough.
+ static TQString str_cache;
+ str_cache = str;
+#ifdef UNICODE
+ return str_cache.ucs2();
+#else
+ return str_cache.latin1();
+#endif
+}
+
+/*!
+ Makes a new '\0'-terminated Windows TCHAR* from a TQString.
+*/
+void* qt_winTchar_new(const TQString& str)
+{
+ if ( str.isNull() )
+ return 0;
+ int l = str.length()+1;
+ TCHAR *tc = new TCHAR[ l ];
+#ifdef UNICODE
+ memcpy( tc, str.ucs2(), sizeof(TCHAR)*l );
+#else
+ memcpy( tc, str.latin1(), sizeof(TCHAR)*l );
+#endif
+ return tc;
+}
+
+/*!
+ Makes a TQString from a Windows TCHAR*.
+*/
+TQString qt_winTQString(void* tc)
+{
+#ifdef UNICODE
+ return TQString::fromUcs2( (ushort*)tc );
+#else
+ return TQString::tqfromLatin1( (TCHAR *)tc );
+#endif
+}
+
+TQCString qt_winTQString2MB( const TQString& s, int uclen )
+{
+ if ( uclen < 0 )
+ uclen = s.length();
+ if ( s.isNull() )
+ return TQCString();
+ if ( uclen == 0 )
+ return TQCString("");
+ BOOL used_def;
+ TQCString mb(4096);
+ int len;
+ while ( !(len=WideCharToMultiByte(CP_ACP, 0, (const WCHAR*)s.tqunicode(), uclen,
+ mb.data(), mb.size()-1, 0, &used_def)) )
+ {
+ int r = GetLastError();
+ if ( r == ERROR_INSUFFICIENT_BUFFER ) {
+ mb.resize(1+WideCharToMultiByte( CP_ACP, 0,
+ (const WCHAR*)s.tqunicode(), uclen,
+ 0, 0, 0, &used_def));
+ // and try again...
+ } else {
+#ifndef TQT_NO_DEBUG
+ // Fail.
+ qWarning("WideCharToMultiByte cannot convert multibyte text (error %d): %s (UTF8)",
+ r, s.utf8().data());
+#endif
+ break;
+ }
+ }
+ mb[len]='\0';
+ return mb;
+}
+
+// WATCH OUT: mblen must include the NUL (or just use -1)
+TQString qt_winMB2TQString( const char* mb, int mblen )
+{
+ if ( !mb || !mblen )
+ return TQString::null;
+ const int wclen_auto = 4096;
+ WCHAR wc_auto[wclen_auto];
+ int wclen = wclen_auto;
+ WCHAR *wc = wc_auto;
+ int len;
+ while ( !(len=MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
+ mb, mblen, wc, wclen )) )
+ {
+ int r = GetLastError();
+ if ( r == ERROR_INSUFFICIENT_BUFFER ) {
+ if ( wc != wc_auto ) {
+ qWarning("Size changed in MultiByteToWideChar");
+ break;
+ } else {
+ wclen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
+ mb, mblen, 0, 0 );
+ wc = new WCHAR[wclen];
+ // and try again...
+ }
+ } else {
+ // Fail.
+ qWarning("MultiByteToWideChar cannot convert multibyte text");
+ break;
+ }
+ }
+ if ( len <= 0 )
+ return TQString::null;
+ TQString s( (TQChar*)wc, len - 1 ); // len - 1: we don't want terminator
+ if ( wc != wc_auto )
+ delete [] wc;
+ return s;
+}
+
+#endif // TQ_OS_WIN32
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/tools/tqstring.h b/tqtinterface/qt4/src/tools/tqstring.h
new file mode 100644
index 0000000..b4db802
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqstring.h
@@ -0,0 +1,1684 @@
+/****************************************************************************
+**
+** Definition of the TQString class, and related Unicode functions.
+**
+** Created : 920609
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTRING_H
+#define TQSTRING_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqcstring.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qstring.h>
+#include <Qt/qmetatype.h>
+
+#endif // USE_QT4
+
+#ifndef TQT_NO_CAST_ASCII
+#include <limits.h>
+#include <string>
+#endif
+
+#ifndef TQT_NO_STL
+#if defined ( TQ_CC_MSVC_NET ) && _MSC_VER < 1310 // Avoids nasty warning for xlocale, line 450
+# pragma warning ( push )
+# pragma warning ( disable : 4189 )
+# include <string>
+# pragma warning ( pop )
+#else
+# include <string>
+#endif
+#if defined(TQ_WRONG_SB_CTYPE_MACROS) && defined(_SB_CTYPE_MACROS)
+#undef _SB_CTYPE_MACROS
+#endif
+#endif
+
+#ifdef USE_QT4
+
+class TQCharRef;
+
+class TQ_EXPORT TQChar : public QChar
+{
+public:
+ enum SpecialCharacter {
+ Null = Null,
+ Nbsp = Nbsp,
+ ReplacementCharacter = ReplacementCharacter,
+ ObjectReplacementCharacter = ObjectReplacementCharacter,
+ ByteOrderMark = ByteOrderMark,
+ ByteOrderSwapped = ByteOrderSwapped,
+
+// null = Null,
+// tqreplacement = ReplacementCharacter,
+// byteOrderMark = ByteOrderMark,
+// byteOrderSwapped = ByteOrderSwapped,
+// nbsp = Nbsp,
+
+ ParagraphSeparator = ParagraphSeparator,
+ LineSeparator = LineSeparator
+ };
+
+ TQT_STATIC_CONST TQChar null;
+ TQT_STATIC_CONST TQChar tqreplacement;
+ TQT_STATIC_CONST TQChar byteOrderMark;
+ TQT_STATIC_CONST TQChar byteOrderSwapped;
+ TQT_STATIC_CONST TQChar nbsp;
+
+ TQChar() : QChar() {}
+ TQChar( char c ) : QChar( c ) {}
+ TQChar( uchar c ) : QChar( c ) {}
+ TQChar( uchar c, uchar r ) : QChar( c, r ) {}
+ TQChar( const QChar& c ) : QChar( c ) {}
+ TQChar( ushort rc ) : QChar( rc ) {}
+ TQChar( short rc ) : QChar( rc ) {}
+ TQChar( uint rc ) : QChar( rc ) {}
+ TQChar( int rc ) : QChar( rc ) {}
+ TQChar(TQChar::SpecialCharacter sc) : QChar( (QChar::SpecialCharacter)sc ) {}
+
+ inline TQChar lower() const { return toLower(); }
+ inline TQChar upper() const { return toUpper(); }
+
+#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
+ inline const char latin1() const { return toLatin1(); }
+ inline const char ascii() const { return toAscii(); }
+#else
+ inline char latin1() const { return toLatin1(); }
+ inline char ascii() const { return toAscii(); }
+#endif
+
+#ifndef TQT_NO_CAST_ASCII
+ inline operator char() const { return latin1(); }
+#endif
+
+ static inline bool networkOrdered() {
+ return QSysInfo::ByteOrder == QSysInfo::BigEndian;
+ }
+
+ inline TQChar &operator=( char ch ) { this->QChar::operator=(ch); return *this; }
+
+ inline ushort tqunicode() const { return unicode(); }
+ inline bool mirrored() const { return hasMirrored(); }
+
+ using QChar::operator=;
+};
+
+Q_DECLARE_METATYPE(TQChar)
+
+inline bool operator==( char ch, QChar c ) { return (TQChar(ch) == c); }
+inline bool operator==( QChar c, char ch ) { return (TQChar(ch) == c); }
+inline bool operator!=( char ch, QChar c ) { return (TQChar(ch) != c); }
+inline bool operator!=( QChar c, char ch ) { return (TQChar(ch) != c); }
+
+inline bool operator==( int ch, QChar c ) { return (TQChar(ch) == c); }
+inline bool operator==( QChar c, int ch ) { return (TQChar(ch) == c); }
+inline bool operator!=( int ch, QChar c ) { return (TQChar(ch) == c); }
+inline bool operator!=( QChar c, int ch ) { return (TQChar(ch) == c); }
+
+class TQ_EXPORT TQString : public QString
+{
+public:
+ TQString() : QString() {}
+ TQString( QChar tc ) : QString( tc ) {}
+ TQString( const QString &ts ) : QString( ts ) {}
+ TQString( const QByteArray &ba ) : QString( ba ) { int slen = int(strlen(ba)); if (length() > slen) truncate(slen); }
+ TQString( const QChar* tqunicode, uint length ) : QString( tqunicode, length ) {}
+#ifndef TQT_NO_CAST_ASCII
+ TQString( const char *str ) : QString( str ) {}
+#endif
+#ifndef TQT_NO_STL
+ TQString( const std::string &str ) : QString(str.c_str()) {}
+#endif
+
+ int tqfind( QChar c, int index=0, bool cs=TRUE ) const { return indexOf(c, index, (Qt::CaseSensitivity)cs); }
+ int tqfind( char c, int index=0, bool cs=TRUE ) const { return indexOf(c, index, (Qt::CaseSensitivity)cs); }
+ int tqfind( const QString &str, int index=0, bool cs=TRUE ) const { return indexOf(str, index, (Qt::CaseSensitivity)cs); }
+#ifndef TQT_NO_REGEXP
+ int tqfind( const QRegExp &qr, int index=0 ) const { return indexOf(qr, index); }
+#endif
+#ifndef TQT_NO_CAST_ASCII
+ int tqfind( const char* str, int index=0 ) const { return indexOf(str, index); }
+#endif
+ int tqfindRev( QChar c, int index=-1, bool cs=TRUE) const { return lastIndexOf(c, index, (Qt::CaseSensitivity)cs); }
+ int tqfindRev( char c, int index=-1, bool cs=TRUE) const { return lastIndexOf(c, index, (Qt::CaseSensitivity)cs); }
+ int tqfindRev( const QString &str, int index=-1, bool cs=TRUE) const { return lastIndexOf(str, index, (Qt::CaseSensitivity)cs); }
+#ifndef TQT_NO_REGEXP
+ int tqfindRev( const QRegExp &qr, int index=-1 ) const { return lastIndexOf(qr, index); }
+#endif
+#ifndef TQT_NO_CAST_ASCII
+ int tqfindRev( const char* str, int index=-1 ) const { return lastIndexOf(str, index); }
+#endif
+
+ const char* latin1() const { return latin1_helper(); }
+ const char* ascii() const { return ascii_helper(); }
+
+ bool simpleText() const;
+ void checkSimpleText() const;
+
+ TQString copy() const;
+
+ inline TQString lower() const { return toLower(); }
+ inline TQString upper() const { return toUpper(); }
+ inline TQString stripWhiteSpace() const { return trimmed(); }
+ inline TQString simplifyWhiteSpace() const { return simplified(); }
+
+ inline TQString fill( TQChar c, int len = -1 ) { return QString::fill(c, len); }
+
+ // QString::Null compatibility
+ struct Null { };
+ static const Null null;
+ inline TQString(const Null &) : QString() {}
+ inline TQString &operator=(const Null &) { *this = TQString(); return *this; }
+
+ int tqcontains( QChar c, bool cs=TRUE ) const { return count(c, (Qt::CaseSensitivity)cs); }
+ int tqcontains( char c, bool cs=TRUE ) const { return tqcontains(TQChar(c), cs); }
+#ifndef TQT_NO_CAST_ASCII
+ int tqcontains( const char* str, bool cs=TRUE ) const { return count(str, (Qt::CaseSensitivity)cs); }
+#endif
+ int tqcontains( const QString &str, bool cs=TRUE ) const { return count(str, (Qt::CaseSensitivity)cs); }
+#ifndef TQT_NO_REGEXP
+ int tqcontains( const QRegExp &re ) const { return count(re); }
+#endif
+
+#ifndef QT_NO_CAST_TO_ASCII
+ inline operator const char *() const { return ascii_helper(); }
+#endif
+
+ inline bool tqstartsWith( const TQString& str ) const { return startsWith(str); }
+ inline bool tqstartsWith( const TQString& str, bool cs ) const { return startsWith(str, (cs)?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline bool tqendsWith( const TQString& str ) const { return endsWith(str); }
+ inline bool tqendsWith( const TQString& str, bool cs ) const { return endsWith(str, (cs)?Qt::CaseSensitive:Qt::CaseInsensitive); }
+
+ TQCString utf8() const;
+ inline TQChar constref(uint i) const { return tqat(i); }
+ inline TQString leftJustify(int width, QChar aFill = QLatin1Char(' '), bool trunc=false) const { return leftJustified(width, aFill, trunc); }
+ inline TQString rightJustify(int width, QChar aFill = QLatin1Char(' '), bool trunc=false) const { return rightJustified(width, aFill, trunc); }
+
+ inline const TQChar* tqunicode() const { if (length() > 0) return static_cast<const TQChar*>(unicode()); else return static_cast<const TQChar*>(QString().unicode()); }
+ TQCString local8Bit() const;
+
+ inline TQString tqreplace(int i, int len, QChar after) { return tqreplace( i, len, &after, 1 ); }
+ inline TQString tqreplace(int i, int len, const QChar *s, int slen) {
+ // Mimic the old (undocumented) behavior
+ int newindex = i;
+ if (newindex > length()) newindex = length();
+ return replace( newindex, len, s, slen );
+ }
+ inline TQString tqreplace(int i, int len, const QString &after) { return tqreplace( i, len, TQString(after).tqunicode(), after.length() ); }
+ inline TQString tqreplace(QChar before, QChar after, Qt::CaseSensitivity cs = Qt::CaseSensitive) { return replace( before, after, cs ); }
+ inline TQString tqreplace(const QChar *before, int blen, const QChar *after, int alen, Qt::CaseSensitivity cs = Qt::CaseSensitive) { return replace( before, blen, after, alen, cs ); }
+ inline TQString tqreplace(const QLatin1String &before, const QLatin1String &after, Qt::CaseSensitivity cs = Qt::CaseSensitive) { return replace( before, after, cs ); }
+ inline TQString tqreplace(const QLatin1String &before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive) { return replace( before, after, cs ); }
+ inline TQString tqreplace(const QString &before, const QLatin1String &after, Qt::CaseSensitivity cs = Qt::CaseSensitive) { return replace( before, after, cs ); }
+ inline TQString tqreplace(const QString &before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive) { return replace( before, after, cs ); }
+ inline TQString tqreplace(QChar c, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive) { return replace( c, after, cs ); }
+ inline TQString tqreplace(QChar c, const QLatin1String &after, Qt::CaseSensitivity cs = Qt::CaseSensitive) { return replace( c, after, cs ); }
+#ifndef QT_NO_REGEXP
+ inline TQString tqreplace(const QRegExp &rx, const QString &after) { return replace( rx, after ); }
+#endif
+ inline TQString tqreplace(const QString &before, const QString &after, bool cs) { return tqreplace(before, after, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+
+ inline TQString tqsetNum( short a, int base=10 ) { return setNum(a, base); }
+ inline TQString tqsetNum( ushort a, int base=10 ) { return setNum(a, base); }
+ inline TQString tqsetNum( int a, int base=10 ) { return setNum(a, base); }
+ inline TQString tqsetNum( uint a, int base=10 ) { return setNum(a, base); }
+ inline TQString tqsetNum( long a, int base=10 ) { return setNum(a, base); }
+ inline TQString tqsetNum( ulong a, int base=10 ) { return setNum(a, base); }
+ inline TQString tqsetNum( TQ_LLONG a, int base=10 ) { return setNum(a, base); }
+ inline TQString tqsetNum( TQ_ULLONG a, int base=10 ) { return setNum(a, base); }
+ inline TQString tqsetNum( float a, char f='g', int prec=6 ) { return setNum(a, f, prec); }
+ inline TQString tqsetNum( double a, char f='g', int prec=6 ) { return setNum(a, f, prec); }
+
+ inline TQString remove( uint index, uint len ) { if (index<=((uint)length())) return QString::remove(index, len); return *this; }
+ inline TQString remove( const QString &qs ) { return QString::remove(qs); }
+ inline TQString remove( const QString &qs, bool cs ) { return QString::remove(qs, cs?Qt::CaseSensitive:Qt::CaseInsensitive); }
+ inline TQString remove( QChar c ) { return QString::remove(c); }
+ inline TQString remove( char c ) { return remove( QChar(c) ); }
+#ifndef TQT_NO_CAST_ASCII
+ inline TQString remove( const char *ch ) { return QString::remove(ch); }
+#endif
+#ifndef TQT_NO_REGEXP
+ inline TQString remove( const QRegExp &re ) { return QString::remove(re); }
+#endif
+
+ inline TQString section( TQChar sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const { return QString::section(sep, start, end, (QString::SectionFlags)flags); }
+ inline TQString section( char sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const { return QString::section(sep, start, end, (QString::SectionFlags)flags); }
+#ifndef TQT_NO_CAST_ASCII
+ inline TQString section( const char *in_sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const { return QString::section(in_sep, start, end, (QString::SectionFlags)flags); }
+#endif
+ inline TQString section( const QString in_sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const { return QString::section(in_sep, start, end, (QString::SectionFlags)flags); }
+#ifndef TQT_NO_REGEXP
+ inline TQString section( const QRegExp reg, int start, int end = 0xffffffff, int flags = SectionDefault ) const { return QString::section(reg, start, end, (QString::SectionFlags)flags); }
+#endif
+
+ inline static TQString fromUcs2(const ushort *unicode, int size = -1) { return fromUtf16(unicode, size); }
+ inline const unsigned short *ucs2() const { return utf16(); }
+
+ inline TQString left( uint len ) const { return TQString(QString::left(len)); }
+ inline TQString right( uint len ) const { return TQString(QString::right(len)); }
+ inline TQString mid( uint index, uint len=0xffffffff) const { return TQString(QString::mid(index, len)); }
+
+ inline static TQString number( long n, int base=10 ) { return TQString(QString::number(n, base)); }
+ inline static TQString number( ulong n, int base=10) { return TQString(QString::number(n, base)); }
+ inline static TQString number( TQ_LLONG n, int base=10 ) { return TQString(QString::number(n, base)); }
+ inline static TQString number( TQ_ULLONG n, int base=10) { return TQString(QString::number(n, base)); }
+ inline static TQString number( int n, int base=10 ) { return TQString(QString::number(n, base)); }
+ inline static TQString number( uint n, int base=10) { return TQString(QString::number(n, base)); }
+ inline static TQString number( double n, char f='g', int prec=6 ) { return TQString(QString::number(n, f, prec)); }
+
+ TQString &setAscii( const char*, int len=-1 );
+ TQString &setLatin1( const char *ch, int len=-1 );
+
+// inline TQString tqarg( long a, int fieldWidth = 0, int base = 10 ) const { return TQString(this->arg(a, fieldWidth, base)); }
+// inline TQString tqarg( ulong a, int fieldWidth = 0, int base = 10 ) const { return TQString(this->arg(a, fieldWidth, base)); }
+// inline TQString tqarg( TQ_LLONG a, int fieldwidth=0, int base=10 ) const { return TQString(this->arg(a, fieldwidth, base)); }
+// inline TQString tqarg( TQ_ULLONG a, int fieldwidth=0, int base=10 ) const { return TQString(this->arg(a, fieldwidth, base)); }
+// inline TQString tqarg( int a, int fieldWidth = 0, int base = 10 ) const { return TQString(this->arg(a, fieldWidth, base)); }
+// inline TQString tqarg( uint a, int fieldWidth = 0, int base = 10 ) const { return TQString(this->arg(a, fieldWidth, base)); }
+// inline TQString tqarg( short a, int fieldWidth = 0, int base = 10 ) const { return TQString(this->arg(a, fieldWidth, base)); }
+// inline TQString tqarg( ushort a, int fieldWidth = 0, int base = 10 ) const { return TQString(this->arg(a, fieldWidth, base)); }
+// inline TQString tqarg( double a, int fieldWidth = 0, char fmt = 'g', int prec = -1 ) const { return TQString(this->arg(a, fieldWidth, fmt, prec)); }
+// inline TQString tqarg( char a, int fieldWidth = 0 ) const { return TQString(this->arg(a, fieldWidth)); }
+// inline TQString tqarg( TQChar a, int fieldWidth = 0 ) const { return TQString(this->arg(a, fieldWidth)); }
+// inline TQString tqarg( const TQString& a, int fieldWidth = 0 ) const { return TQString(this->arg(a, fieldWidth)); }
+// inline TQString tqarg( const TQString& a1, const TQString& a2 ) const { return TQString(this->arg(a1, a2)); }
+// inline TQString tqarg( const TQString& a1, const TQString& a2, const TQString& a3 ) const { return TQString(this->arg(a1, a2, a3)); }
+// inline TQString tqarg( const TQString& a1, const TQString& a2, const TQString& a3, const TQString& a4 ) const { return TQString(this->arg(a1, a2, a3, a4)); }
+
+ TQString tqarg( long a, int fieldWidth = 0, int base = 10 ) const;
+ TQString tqarg( ulong a, int fieldWidth = 0, int base = 10 ) const;
+ TQString tqarg( TQ_LLONG a, int fieldwidth=0, int base=10 ) const;
+ TQString tqarg( TQ_ULLONG a, int fieldwidth=0, int base=10 ) const;
+ TQString tqarg( int a, int fieldWidth = 0, int base = 10 ) const;
+ TQString tqarg( uint a, int fieldWidth = 0, int base = 10 ) const;
+ TQString tqarg( short a, int fieldWidth = 0, int base = 10 ) const;
+ TQString tqarg( ushort a, int fieldWidth = 0, int base = 10 ) const;
+ TQString tqarg( double a, int fieldWidth = 0, char fmt = 'g', int prec = -1 ) const;
+ TQString tqarg( char a, int fieldWidth = 0 ) const;
+ TQString tqarg( TQChar a, int fieldWidth = 0 ) const;
+ TQString tqarg( const TQString& a, int fieldWidth = 0 ) const;
+ TQString tqarg( const TQString& a1, const TQString& a2 ) const;
+ TQString tqarg( const TQString& a1, const TQString& a2, const TQString& a3 ) const;
+ TQString tqarg( const TQString& a1, const TQString& a2, const TQString& a3, const TQString& a4 ) const;
+
+ TQString setUnicodeCodes( const ushort* tqunicode_as_ushorts, uint len );
+
+ inline void setLength(int nl) { resize(nl); }
+ TQCharRef tqat( uint i );
+ TQCharRef operator[]( int i );
+
+ static TQString fromLatin1(const char *ch, int len=-1);
+ static inline TQString tqfromLatin1(const char *ch, int len=-1) { return fromLatin1(ch, len); }
+
+ static TQString fromUtf8(const char*, int len=-1);
+
+ // FIXME
+ inline void compose() { /*printf("[FIXME] void TQString::compose() unimplemented\n\r");*/ }
+
+ TQChar tqat( uint i ) const { return i < (uint)length() ? unicode()[i] : TQChar::null; }
+ TQChar operator[]( int i ) const { if ((i<0) || (i>=length())) return TQChar::null; else return tqat((uint)i); }
+
+// TQChar constref(uint i) const { return tqat(i); }
+ QChar& ref(uint i);
+
+// inline QChar ref(uint i) { return (*this)[i]; }
+
+ TQString &operator+=( const TQString &str );
+#ifndef TQT_NO_CAST_ASCII
+ TQString &operator+=( const TQByteArray &str );
+ TQString &operator+=( const char *str );
+#endif
+#ifndef TQT_NO_CAST_ASCII
+ TQString &operator+=( const std::string& );
+#endif
+ TQString &operator+=( TQChar c );
+ TQString &operator+=( char c );
+
+ TQString &operator+=( const QStringRef &s);
+ TQString &operator+=( const QLatin1String &s);
+ TQString &operator+=( QChar c );
+
+ using QString::operator=;
+
+ friend class TQObject;
+ friend class TQWidget;
+ friend class TQStyle;
+
+protected:
+ const char *ascii_helper() const;
+ const char *latin1_helper() const;
+
+public:
+ static char* tqunicodeToLatin1( const TQChar*, uint len );
+
+private:
+ mutable QByteArray tqstring_ascii_ba;
+ mutable QByteArray tqstring_latin1_ba;
+ mutable bool tqstring_issimpletext;
+
+private:
+#ifndef TQT_NO_CAST_ASCII
+// TQString &insertHelper( uint index, const char *s, uint len=UINT_MAX );
+ TQString &operatorPlusEqHelper( const char *s, uint len2=UINT_MAX );
+#endif
+
+private:
+ void subat( uint );
+ TQString tqmultiArg( int numArgs, const TQString& a1, const TQString& a2, const TQString& a3 = TQString(), const TQString& a4 = TQString() ) const;
+
+public:
+ // Interoperability
+ static const TQString& convertFromQString( QString& qstr );
+};
+
+Q_DECLARE_METATYPE(TQString)
+
+// Interoperability
+inline static const TQString& convertFromQString( const QString& qstr ) {
+ return (*static_cast<const TQString*>(&qstr));
+}
+
+inline TQString TQString::tqarg( int a, int fieldWidth, int base ) const { return tqarg( (TQ_LLONG)a, fieldWidth, base ); }
+inline TQString TQString::tqarg( uint a, int fieldWidth, int base ) const { return tqarg( (TQ_ULLONG)a, fieldWidth, base ); }
+inline TQString TQString::tqarg( short a, int fieldWidth, int base ) const { return tqarg( (TQ_LLONG)a, fieldWidth, base ); }
+inline TQString TQString::tqarg( ushort a, int fieldWidth, int base ) const { return tqarg( (TQ_ULLONG)a, fieldWidth, base ); }
+inline TQString TQString::tqarg( const TQString& a1, const TQString& a2 ) const { return tqmultiArg( 2, a1, a2 ); }
+inline TQString TQString::tqarg( const TQString& a1, const TQString& a2, const TQString& a3 ) const { return tqmultiArg( 3, a1, a2, a3 ); }
+inline TQString TQString::tqarg( const TQString& a1, const TQString& a2, const TQString& a3, const TQString& a4 ) const { return tqmultiArg( 4, a1, a2, a3, a4 ); }
+
+inline TQString TQString::copy() const { return TQString( *this ); }
+
+inline bool operator==(TQString::Null, TQString::Null) { return true; }
+inline bool operator==(TQString::Null, const TQString &s) { return s.isNull(); }
+inline bool operator==(const TQString &s, TQString::Null) { return s.isNull(); }
+inline bool operator!=(TQString::Null, TQString::Null) { return false; }
+inline bool operator!=(TQString::Null, const TQString &s) { return !s.isNull(); }
+inline bool operator!=(const TQString &s, TQString::Null) { return !s.isNull(); }
+
+#ifndef TQT_NO_CAST_ASCII
+inline TQString &TQString::operator+=( const TQByteArray &s )
+{
+ int pos = s.tqfind( 0 );
+ return operatorPlusEqHelper( s, pos==-1 ? s.size() : pos );
+}
+#endif
+
+#ifndef TQT_NO_CAST_ASCII
+inline TQString &TQString::operator+=( const std::string& s )
+{ return operator+=(s.c_str()); }
+#endif
+
+// [FIXME] The following operator+ functions spew a ridiculous number of (harmless) warnings
+// due to the very similar QString operator+ functions. Can this be fixed???
+
+TQ_EXPORT inline const TQString operator+( const TQString &s1, const TQString &s2 )
+{
+ TQString tmp( s1 );
+ tmp += s2;
+ return tmp;
+}
+
+#ifndef TQT_NO_CAST_ASCII
+TQ_EXPORT inline const TQString operator+( const TQString &s1, const char *s2 )
+{
+ TQString tmp( s1 );
+ tmp += TQString::fromAscii(s2);
+ return tmp;
+}
+
+TQ_EXPORT inline const TQString operator+( const char *s1, const TQString &s2 )
+{
+ TQString tmp = TQString::fromAscii( s1 );
+ tmp += s2;
+ return tmp;
+}
+#endif
+
+TQ_EXPORT inline const TQString operator+( const TQString &s1, TQChar c2 )
+{
+ TQString tmp( s1 );
+ tmp += c2;
+ return tmp;
+}
+
+TQ_EXPORT inline const TQString operator+( const TQString &s1, char c2 )
+{
+ TQString tmp( s1 );
+ tmp += c2;
+ return tmp;
+}
+
+TQ_EXPORT inline const TQString operator+( TQChar c1, const TQString &s2 )
+{
+ TQString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+TQ_EXPORT inline const TQString operator+( char c1, const TQString &s2 )
+{
+ TQString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+#ifndef TQT_NO_STL
+TQ_EXPORT inline const TQString operator+(const TQString& s1, const std::string& s2)
+{
+ return s1 + TQString(s2);
+}
+
+TQ_EXPORT inline const TQString operator+(const std::string& s1, const TQString& s2)
+{
+ TQString tmp(s2);
+ return TQString(tmp.prepend(s1.c_str()));
+}
+#endif
+
+class TQConstString : public TQString
+{
+public:
+ inline TQConstString(const QChar *aUnicode, int aSize) : TQString(aUnicode, aSize) {} // cannot use fromRawData() due to changed semantics
+ inline const TQString &string() const { return *this; }
+};
+
+class TQ_EXPORT TQCharRef {
+ friend class TQString;
+ TQString& s;
+ uint p;
+ TQCharRef(TQString* str, uint pos) : s(*str), p(pos) { }
+
+public:
+ // most TQChar operations repeated here
+
+ // all this is not documented: We just say "like TQChar" and let it be.
+#ifndef TQ_TQDOC
+ ushort unicode() const { return s.constref(p).tqunicode(); }
+ ushort tqunicode() const { return s.constref(p).tqunicode(); }
+ char latin1() const { return s.constref(p).latin1(); }
+
+ // An operator= for each TQChar cast constructors
+ TQCharRef operator=(char c ) { s.ref(p)=c; return *this; }
+ TQCharRef operator=(uchar c ) { s.ref(p)=c; return *this; }
+ TQCharRef operator=(TQChar c ) { s.ref(p)=c; return *this; }
+ TQCharRef operator=(const TQCharRef& c ) { s.ref(p)=c.tqunicode(); return *this; }
+ TQCharRef operator=(ushort rc ) { s.ref(p)=rc; return *this; }
+ TQCharRef operator=(short rc ) { s.ref(p)=rc; return *this; }
+ TQCharRef operator=(uint rc ) { s.ref(p)=rc; return *this; }
+ TQCharRef operator=(int rc ) { s.ref(p)=rc; return *this; }
+
+ operator TQChar () const { return s.constref(p); }
+
+ // each function...
+ bool isNull() const { return tqunicode()==0; }
+ bool isPrint() const { return s.constref(p).isPrint(); }
+ bool isPunct() const { return s.constref(p).isPunct(); }
+ bool isSpace() const { return s.constref(p).isSpace(); }
+ bool isMark() const { return s.constref(p).isMark(); }
+ bool isLetter() const { return s.constref(p).isLetter(); }
+ bool isNumber() const { return s.constref(p).isNumber(); }
+ bool isLetterOrNumber() { return s.constref(p).isLetterOrNumber(); }
+ bool isDigit() const { return s.constref(p).isDigit(); }
+
+ int digitValue() const { return s.constref(p).digitValue(); }
+ TQChar lower() const { return s.constref(p).lower(); }
+ TQChar upper() const { return s.constref(p).upper(); }
+
+ TQChar::Category category() const { return s.constref(p).category(); }
+ TQChar::Direction direction() const { return s.constref(p).direction(); }
+ TQChar::Joining joining() const { return s.constref(p).joining(); }
+ bool mirrored() const { return s.constref(p).mirrored(); }
+ TQChar mirroredChar() const { return s.constref(p).mirroredChar(); }
+// const TQString &decomposition() const { return s.constref(p).decomposition(); }
+ TQChar::Decomposition decompositionTag() const { return s.constref(p).decompositionTag(); }
+ unsigned char combiningClass() const { return s.constref(p).combiningClass(); }
+
+ // Not the non-const ones of these.
+ uchar cell() const { return s.constref(p).cell(); }
+ uchar row() const { return s.constref(p).row(); }
+#endif
+};
+
+// inline TQChar& TQString::ref(uint i)
+inline QChar& TQString::ref(uint i)
+{ // Optimized for easy-inlining by simple compilers.
+ if ( count() != 1 || i >= (uint)length() )
+ subat( i );
+// d->setDirty();
+// return tqunicode()[i];
+
+// const QCharRef& ref = QString::operator[](i);
+// return *const_cast<TQChar*>(static_cast<const TQChar*>(&reinterpret_cast<const QChar&>(ref))); // [FIXME] Will this work the same as data->unicode did in Qt3? Will it work at all???
+
+ QChar *tdata = data();
+ return tdata[i]; // [FIXME] Will this work the same as data->unicode did in Qt3? Will it work at all???
+}
+
+inline TQCharRef TQString::tqat( uint i ) { return TQCharRef(this,i); }
+inline TQCharRef TQString::operator[]( int i ) { return tqat((uint)i); }
+
+/*****************************************************************************
+ TQString stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQString & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQString & );
+#endif
+
+/*****************************************************************************
+ TQString non-member operators
+ *****************************************************************************/
+
+inline TQ_EXPORT bool operator!=( const TQString &s1, const TQString &s2 ) {
+ if (s1.isNull() != s2.isNull()) return true;
+ return (static_cast<const QString&>(s1) != static_cast<const QString&>(s2));
+}
+inline TQ_EXPORT bool operator==( const TQString &s1, const TQString &s2 ) {
+ if (s1.isNull() != s2.isNull()) return false;
+ return (static_cast<const QString&>(s1) == static_cast<const QString&>(s2));
+}
+
+#else // USE_QT4
+
+/*****************************************************************************
+ TQString class
+ *****************************************************************************/
+
+class TQRegExp;
+class TQString;
+class TQCharRef;
+template <class T> class TQDeepCopy;
+
+class TQ_EXPORT TQChar {
+public:
+ TQChar();
+ TQChar( char c );
+ TQChar( uchar c );
+ TQChar( uchar c, uchar r );
+ TQChar( const TQChar& c ); // ### remove in 4.0 to allow compiler optimization
+ TQChar( ushort rc );
+ TQChar( short rc );
+ TQChar( uint rc );
+ TQChar( int rc );
+
+ TQT_STATIC_CONST TQChar null; // 0000
+ TQT_STATIC_CONST TQChar tqreplacement; // FFFD
+ TQT_STATIC_CONST TQChar byteOrderMark; // FEFF
+ TQT_STATIC_CONST TQChar byteOrderSwapped; // FFFE
+ TQT_STATIC_CONST TQChar nbsp; // 00A0
+
+ // Unicode information
+
+ enum Category
+ {
+ NoCategory,
+
+ Mark_NonSpacing, // Mn
+ Mark_SpacingCombining, // Mc
+ Mark_Enclosing, // Me
+
+ Number_DecimalDigit, // Nd
+ Number_Letter, // Nl
+ Number_Other, // No
+
+ Separator_Space, // Zs
+ Separator_Line, // Zl
+ Separator_Paragraph, // Zp
+
+ Other_Control, // Cc
+ Other_Format, // Cf
+ Other_Surrogate, // Cs
+ Other_PrivateUse, // Co
+ Other_NotAssigned, // Cn
+
+ Letter_Uppercase, // Lu
+ Letter_Lowercase, // Ll
+ Letter_Titlecase, // Lt
+ Letter_Modifier, // Lm
+ Letter_Other, // Lo
+
+ Punctuation_Connector, // Pc
+ Punctuation_Dash, // Pd
+ Punctuation_Dask = Punctuation_Dash, // oops
+ Punctuation_Open, // Ps
+ Punctuation_Close, // Pe
+ Punctuation_InitialQuote, // Pi
+ Punctuation_FinalQuote, // Pf
+ Punctuation_Other, // Po
+
+ Symbol_Math, // Sm
+ Symbol_Currency, // Sc
+ Symbol_Modifier, // Sk
+ Symbol_Other // So
+ };
+
+ enum Direction
+ {
+ DirL, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
+ DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN
+ };
+
+ enum Decomposition
+ {
+ Single, Canonical, Font, NoBreak, Initial, Medial,
+ Final, Isolated, Circle, Super, Sub, Vertical,
+ Wide, Narrow, Small, Square, Compat, Fraction
+ };
+
+ enum Joining
+ {
+ OtherJoining, Dual, Right, Center
+ };
+
+ enum CombiningClass
+ {
+ Combining_BelowLeftAttached = 200,
+ Combining_BelowAttached = 202,
+ Combining_BelowRightAttached = 204,
+ Combining_LeftAttached = 208,
+ Combining_RightAttached = 210,
+ Combining_AboveLeftAttached = 212,
+ Combining_AboveAttached = 214,
+ Combining_AboveRightAttached = 216,
+
+ Combining_BelowLeft = 218,
+ Combining_Below = 220,
+ Combining_BelowRight = 222,
+ Combining_Left = 224,
+ Combining_Right = 226,
+ Combining_AboveLeft = 228,
+ Combining_Above = 230,
+ Combining_AboveRight = 232,
+
+ Combining_DoubleBelow = 233,
+ Combining_DoubleAbove = 234,
+ Combining_IotaSubscript = 240
+ };
+
+ // ****** WHEN ADDING FUNCTIONS, CONSIDER ADDING TO TQCharRef TOO
+
+ int digitValue() const;
+ TQChar lower() const;
+ TQChar upper() const;
+
+ Category category() const;
+ Direction direction() const;
+ Joining joining() const;
+ bool mirrored() const;
+ TQChar mirroredChar() const;
+ const TQString &decomposition() const; // ### return just TQString in 4.0
+ Decomposition decompositionTag() const;
+ unsigned char combiningClass() const;
+
+ char latin1() const { return ucs > 0xff ? 0 : (char) ucs; }
+ ushort tqunicode() const { return ucs; }
+#ifdef TQ_NO_PACKED_REFERENCE
+ ushort &tqunicode() { return *(&ucs); }
+#else
+ ushort &tqunicode() { return ucs; }
+#endif
+#ifndef TQT_NO_CAST_ASCII
+ // like all ifdef'd code this is undocumented
+ operator char() const { return latin1(); }
+#endif
+
+ bool isNull() const { return tqunicode()==0; }
+ bool isPrint() const;
+ bool isPunct() const;
+ bool isSpace() const;
+ bool isMark() const;
+ bool isLetter() const;
+ bool isNumber() const;
+ bool isLetterOrNumber() const;
+ bool isDigit() const;
+ bool isSymbol() const;
+
+ uchar cell() const { return ((uchar) ucs & 0xff); }
+ uchar row() const { return ((uchar) (ucs>>8)&0xff); }
+ void setCell( uchar cell ) { ucs = (ucs & 0xff00) + cell; }
+ void setRow( uchar row ) { ucs = (((ushort) row)<<8) + (ucs&0xff); }
+
+ static bool networkOrdered() {
+ int wordSize;
+ bool bigEndian = FALSE;
+ qSysInfo( &wordSize, &bigEndian );
+ return bigEndian;
+ }
+
+ friend inline bool operator==( char ch, TQChar c );
+ friend inline bool operator==( TQChar c, char ch );
+ friend inline bool operator==( TQChar c1, TQChar c2 );
+ friend inline bool operator!=( TQChar c1, TQChar c2 );
+ friend inline bool operator!=( char ch, TQChar c );
+ friend inline bool operator!=( TQChar c, char ch );
+ friend inline bool operator<=( TQChar c, char ch );
+ friend inline bool operator<=( char ch, TQChar c );
+ friend inline bool operator<=( TQChar c1, TQChar c2 );
+
+private:
+ ushort ucs;
+#if defined(TQT_TQSTRING_UCS_4)
+ ushort grp;
+#endif
+} TQ_PACKED;
+
+inline TQChar::TQChar() : ucs( 0 )
+#ifdef TQT_TQSTRING_UCS_4
+ , grp( 0 )
+#endif
+{
+}
+inline TQChar::TQChar( char c ) : ucs( (uchar)c )
+#ifdef TQT_TQSTRING_UCS_4
+ , grp( 0 )
+#endif
+{
+}
+inline TQChar::TQChar( uchar c ) : ucs( c )
+#ifdef TQT_TQSTRING_UCS_4
+ , grp( 0 )
+#endif
+{
+}
+inline TQChar::TQChar( uchar c, uchar r ) : ucs( (r << 8) | c )
+#ifdef TQT_TQSTRING_UCS_4
+ , grp( 0 )
+#endif
+{
+}
+inline TQChar::TQChar( const TQChar& c ) : ucs( c.ucs )
+#ifdef TQT_TQSTRING_UCS_4
+ , grp( c.grp )
+#endif
+{
+}
+
+inline TQChar::TQChar( ushort rc ) : ucs( rc )
+#ifdef TQT_TQSTRING_UCS_4
+ , grp( 0 )
+#endif
+{
+}
+inline TQChar::TQChar( short rc ) : ucs( (ushort) rc )
+#ifdef TQT_TQSTRING_UCS_4
+ , grp( 0 )
+#endif
+{
+}
+inline TQChar::TQChar( uint rc ) : ucs( (ushort ) (rc & 0xffff) )
+#ifdef TQT_TQSTRING_UCS_4
+ , grp( (ushort) ((rc >> 16) & 0xffff) )
+#endif
+{
+}
+inline TQChar::TQChar( int rc ) : ucs( (ushort) (rc & 0xffff) )
+#ifdef TQT_TQSTRING_UCS_4
+ , grp( (ushort) ((rc >> 16) & 0xffff) )
+#endif
+{
+}
+
+inline bool operator==( char ch, TQChar c )
+{
+ return ((uchar) ch) == c.ucs;
+}
+
+inline bool operator==( TQChar c, char ch )
+{
+ return ((uchar) ch) == c.ucs;
+}
+
+inline bool operator==( TQChar c1, TQChar c2 )
+{
+ return c1.ucs == c2.ucs;
+}
+
+inline bool operator!=( TQChar c1, TQChar c2 )
+{
+ return c1.ucs != c2.ucs;
+}
+
+inline bool operator!=( char ch, TQChar c )
+{
+ return ((uchar)ch) != c.ucs;
+}
+
+inline bool operator!=( TQChar c, char ch )
+{
+ return ((uchar) ch) != c.ucs;
+}
+
+inline bool operator<=( TQChar c, char ch )
+{
+ return c.ucs <= ((uchar) ch);
+}
+
+inline bool operator<=( char ch, TQChar c )
+{
+ return ((uchar) ch) <= c.ucs;
+}
+
+inline bool operator<=( TQChar c1, TQChar c2 )
+{
+ return c1.ucs <= c2.ucs;
+}
+
+inline bool operator>=( TQChar c, char ch ) { return ch <= c; }
+inline bool operator>=( char ch, TQChar c ) { return c <= ch; }
+inline bool operator>=( TQChar c1, TQChar c2 ) { return c2 <= c1; }
+inline bool operator<( TQChar c, char ch ) { return !(ch<=c); }
+inline bool operator<( char ch, TQChar c ) { return !(c<=ch); }
+inline bool operator<( TQChar c1, TQChar c2 ) { return !(c2<=c1); }
+inline bool operator>( TQChar c, char ch ) { return !(ch>=c); }
+inline bool operator>( char ch, TQChar c ) { return !(c>=ch); }
+inline bool operator>( TQChar c1, TQChar c2 ) { return !(c2>=c1); }
+
+// internal
+struct TQ_EXPORT TQStringData : public TQShared {
+ TQStringData() :
+ TQShared(), tqunicode(0), ascii(0), len(0), issimpletext(TRUE), maxl(0), islatin1(FALSE) { ref(); }
+ TQStringData(TQChar *u, uint l, uint m) :
+ TQShared(), tqunicode(u), ascii(0), len(l), issimpletext(FALSE), maxl(m), islatin1(FALSE) { }
+ ~TQStringData() { if ( tqunicode ) delete[] ((char*)tqunicode);
+ if ( ascii ) delete[] ascii; }
+
+ void deleteSelf();
+ TQChar *tqunicode;
+ char *ascii;
+ void setDirty() {
+ if ( ascii ) {
+ delete [] ascii;
+ ascii = 0;
+ }
+ issimpletext = FALSE;
+ }
+#ifdef TQ_OS_MAC9
+ uint len;
+#else
+ uint len : 30;
+#endif
+ uint issimpletext : 1;
+#ifdef TQ_OS_MAC9
+ uint maxl;
+#else
+ uint maxl : 30;
+#endif
+ uint islatin1 : 1;
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQStringData( const TQStringData& );
+ TQStringData& operator=( const TQStringData& );
+#endif
+};
+
+
+class TQ_EXPORT TQString
+{
+public:
+ TQString(); // make null string
+ TQString( TQChar ); // one-char string
+ TQString( const TQString & ); // impl-shared copy
+ TQString( const TQByteArray& ); // deep copy
+ TQString( const TQChar* tqunicode, uint length ); // deep copy
+#ifndef TQT_NO_CAST_ASCII
+ TQString( const char *str ); // deep copy
+#endif
+#ifndef TQT_NO_STL
+ TQString( const std::string& ); // deep copy
+#endif
+ ~TQString();
+
+#ifdef USE_QT4
+ // Interoperability
+ TQString( const QString &qs );
+ operator QString() const;
+ TQString &operator=( const QString &qs );
+#endif // USE_QT4
+
+ TQString &operator=( const TQString & ); // impl-shared copy
+ TQString &operator=( const char * ); // deep copy
+#ifndef TQT_NO_STL
+ TQString &operator=( const std::string& ); // deep copy
+#endif
+ TQString &operator=( const TQCString& ); // deep copy
+ TQString &operator=( TQChar c );
+ TQString &operator=( char c );
+
+ TQT_STATIC_CONST TQString null;
+
+ bool isNull() const;
+ bool isEmpty() const;
+ uint length() const;
+ void truncate( uint pos );
+
+ TQString & fill( TQChar c, int len = -1 );
+
+ TQString copy() const;
+
+ TQString arg( long a, int fieldWidth = 0, int base = 10 ) const;
+ TQString arg( ulong a, int fieldWidth = 0, int base = 10 ) const;
+ TQString arg( TQ_LLONG a, int fieldwidth=0, int base=10 ) const;
+ TQString arg( TQ_ULLONG a, int fieldwidth=0, int base=10 ) const;
+ TQString arg( int a, int fieldWidth = 0, int base = 10 ) const;
+ TQString arg( uint a, int fieldWidth = 0, int base = 10 ) const;
+ TQString arg( short a, int fieldWidth = 0, int base = 10 ) const;
+ TQString arg( ushort a, int fieldWidth = 0, int base = 10 ) const;
+ TQString arg( double a, int fieldWidth = 0, char fmt = 'g',
+ int prec = -1 ) const;
+ TQString arg( char a, int fieldWidth = 0 ) const;
+ TQString arg( TQChar a, int fieldWidth = 0 ) const;
+ TQString arg( const TQString& a, int fieldWidth = 0 ) const;
+ TQString arg( const TQString& a1, const TQString& a2 ) const;
+ TQString arg( const TQString& a1, const TQString& a2,
+ const TQString& a3 ) const;
+ TQString arg( const TQString& a1, const TQString& a2, const TQString& a3,
+ const TQString& a4 ) const;
+
+#ifndef TQT_NO_SPRINTF
+ TQString &sprintf( const char* format, ... )
+#if defined(TQ_CC_GNU) && !defined(__INSURE__)
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+#endif
+
+ int tqfind( TQChar c, int index=0, bool cs=TRUE ) const;
+ int tqfind( char c, int index=0, bool cs=TRUE ) const;
+ int tqfind( const TQString &str, int index=0, bool cs=TRUE ) const;
+#ifndef TQT_NO_REGEXP
+ int tqfind( const TQRegExp &, int index=0 ) const;
+#endif
+#ifndef TQT_NO_CAST_ASCII
+ int tqfind( const char* str, int index=0 ) const;
+#endif
+ int tqfindRev( TQChar c, int index=-1, bool cs=TRUE) const;
+ int tqfindRev( char c, int index=-1, bool cs=TRUE) const;
+ int tqfindRev( const TQString &str, int index=-1, bool cs=TRUE) const;
+#ifndef TQT_NO_REGEXP
+ int tqfindRev( const TQRegExp &, int index=-1 ) const;
+#endif
+#ifndef TQT_NO_CAST_ASCII
+ int tqfindRev( const char* str, int index=-1 ) const;
+#endif
+ int tqcontains( TQChar c, bool cs=TRUE ) const;
+ int tqcontains( char c, bool cs=TRUE ) const
+ { return tqcontains(TQChar(c), cs); }
+#ifndef TQT_NO_CAST_ASCII
+ int tqcontains( const char* str, bool cs=TRUE ) const;
+#endif
+ int tqcontains( const TQString &str, bool cs=TRUE ) const;
+#ifndef TQT_NO_REGEXP
+ int tqcontains( const TQRegExp & ) const;
+#endif
+
+ enum SectionFlags {
+ SectionDefault = 0x00,
+ SectionSkipEmpty = 0x01,
+ SectionIncludeLeadingSep = 0x02,
+ SectionIncludeTrailingSep = 0x04,
+ SectionCaseInsensitiveSeps = 0x08
+ };
+ TQString section( TQChar sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const;
+ TQString section( char sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const;
+#ifndef TQT_NO_CAST_ASCII
+ TQString section( const char *in_sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const;
+#endif
+ TQString section( const TQString &in_sep, int start, int end = 0xffffffff, int flags = SectionDefault ) const;
+#ifndef TQT_NO_REGEXP
+ TQString section( const TQRegExp &reg, int start, int end = 0xffffffff, int flags = SectionDefault ) const;
+#endif
+
+ TQString left( uint len ) const;
+ TQString right( uint len ) const;
+ TQString mid( uint index, uint len=0xffffffff) const;
+
+ TQString leftJustify( uint width, TQChar fill=' ', bool trunc=FALSE)const;
+ TQString rightJustify( uint width, TQChar fill=' ',bool trunc=FALSE)const;
+
+ TQString lower() const;
+ TQString upper() const;
+
+ TQString stripWhiteSpace() const;
+ TQString simplifyWhiteSpace() const;
+
+ TQString &insert( uint index, const TQString & );
+#ifndef TQT_NO_CAST_ASCII
+ TQString &insert( uint index, const TQByteArray & );
+ TQString &insert( uint index, const char * );
+#endif
+ TQString &insert( uint index, const TQChar*, uint len );
+ TQString &insert( uint index, TQChar );
+ TQString &insert( uint index, char c ) { return insert(index,TQChar(c)); }
+ TQString &append( char );
+ TQString &append( TQChar );
+ TQString &append( const TQString & );
+#ifndef TQT_NO_CAST_ASCII
+ TQString &append( const TQByteArray & );
+ TQString &append( const char * );
+#endif
+#if !defined(TQT_NO_STL) && !defined(TQT_NO_CAST_ASCII)
+ TQString &append( const std::string& );
+#endif
+ TQString &prepend( char );
+ TQString &prepend( TQChar );
+ TQString &prepend( const TQString & );
+#ifndef TQT_NO_CAST_ASCII
+ TQString &prepend( const TQByteArray & );
+ TQString &prepend( const char * );
+#endif
+#if !defined(TQT_NO_STL) && !defined(TQT_NO_CAST_ASCII)
+ TQString &prepend( const std::string& );
+#endif
+ TQString &remove( uint index, uint len );
+#if defined(TQ_TQDOC)
+ TQString &remove( const TQString & str, bool cs = TRUE );
+#else
+ // ### TQt 4.0: merge these two into one, and remove TQ_TQDOC hack
+ TQString &remove( const TQString & );
+ TQString &remove( const TQString &, bool cs );
+#endif
+ TQString &remove( TQChar c );
+ TQString &remove( char c )
+ { return remove( TQChar(c) ); }
+#ifndef TQT_NO_CAST_ASCII
+ TQString &remove( const char * );
+#endif
+#ifndef TQT_NO_REGEXP
+ TQString &remove( const TQRegExp & );
+#endif
+ TQString &tqreplace( uint index, uint len, const TQString & );
+ TQString &tqreplace( uint index, uint len, const TQChar*, uint clen );
+ TQString &tqreplace( uint index, uint len, TQChar );
+ TQString &tqreplace( uint index, uint len, char c )
+ { return tqreplace( index, len, TQChar(c) ); }
+#if defined(TQ_TQDOC)
+ TQString &tqreplace( TQChar c, const TQString & after, bool cs = TRUE );
+ TQString &tqreplace( char c, const TQString & after, bool cs = TRUE );
+ TQString &tqreplace( const TQString & before, const TQString & after,
+ bool cs = TRUE );
+#else
+ // ### TQt 4.0: merge these two into one, and remove TQ_TQDOC hack
+ TQString &tqreplace( TQChar c, const TQString & );
+ TQString &tqreplace( TQChar c, const TQString &, bool );
+
+ // ### TQt 4.0: merge these two into one, and remove TQ_TQDOC hack
+ TQString &tqreplace( char c, const TQString & after )
+ { return tqreplace( TQChar(c), after, TRUE ); }
+ TQString &tqreplace( char c, const TQString & after, bool cs )
+ { return tqreplace( TQChar(c), after, cs ); }
+
+ // ### TQt 4.0: merge these two into one, and remove TQ_TQDOC hack
+ TQString &tqreplace( const TQString &, const TQString & );
+ TQString &tqreplace( const TQString &, const TQString &, bool );
+#endif
+#ifndef TQT_NO_REGEXP_CAPTURE
+ TQString &tqreplace( const TQRegExp &, const TQString & );
+#endif
+ TQString &tqreplace( TQChar, TQChar );
+
+ short toShort( bool *ok=0, int base=10 ) const;
+ ushort toUShort( bool *ok=0, int base=10 ) const;
+ int toInt( bool *ok=0, int base=10 ) const;
+ uint toUInt( bool *ok=0, int base=10 ) const;
+ long toLong( bool *ok=0, int base=10 ) const;
+ ulong toULong( bool *ok=0, int base=10 ) const;
+ TQ_LLONG toLongLong( bool *ok=0, int base=10 ) const;
+ TQ_ULLONG toULongLong( bool *ok=0, int base=10 ) const;
+ float toFloat( bool *ok=0 ) const;
+ double toDouble( bool *ok=0 ) const;
+
+ TQString &setNum( short, int base=10 );
+ TQString &setNum( ushort, int base=10 );
+ TQString &setNum( int, int base=10 );
+ TQString &setNum( uint, int base=10 );
+ TQString &setNum( long, int base=10 );
+ TQString &setNum( ulong, int base=10 );
+ TQString &setNum( TQ_LLONG, int base=10 );
+ TQString &setNum( TQ_ULLONG, int base=10 );
+ TQString &setNum( float, char f='g', int prec=6 );
+ TQString &setNum( double, char f='g', int prec=6 );
+
+ static TQString number( long, int base=10 );
+ static TQString number( ulong, int base=10);
+ static TQString number( TQ_LLONG, int base=10 );
+ static TQString number( TQ_ULLONG, int base=10);
+ static TQString number( int, int base=10 );
+ static TQString number( uint, int base=10);
+ static TQString number( double, char f='g', int prec=6 );
+
+ void setExpand( uint index, TQChar c );
+
+ TQString &operator+=( const TQString &str );
+#ifndef TQT_NO_CAST_ASCII
+ TQString &operator+=( const TQByteArray &str );
+ TQString &operator+=( const char *str );
+#endif
+#if !defined(TQT_NO_STL) && !defined(TQT_NO_CAST_ASCII)
+ TQString &operator+=( const std::string& );
+#endif
+ TQString &operator+=( TQChar c );
+ TQString &operator+=( char c );
+
+ TQChar at( uint i ) const
+ { return i < d->len ? d->tqunicode[i] : TQChar::null; }
+ TQChar operator[]( int i ) const { if ((i<0) || (i>=length())) return TQChar::null; else return at((uint)i); }
+ TQCharRef at( uint i );
+ TQCharRef operator[]( int i );
+
+ TQChar constref(uint i) const
+ { return at(i); }
+ TQChar& ref(uint i)
+ { // Optimized for easy-inlining by simple compilers.
+ if ( d->count != 1 || i >= d->len )
+ subat( i );
+ d->setDirty();
+ return d->tqunicode[i];
+ }
+
+ const TQChar* tqunicode() const { return d->tqunicode; }
+ const char* ascii() const;
+ static TQString fromAscii(const char*, int len=-1);
+ const char* latin1() const;
+ static TQString tqfromLatin1(const char*, int len=-1);
+ TQCString utf8() const;
+ static TQString fromUtf8(const char*, int len=-1);
+ TQCString local8Bit() const;
+ static TQString fromLocal8Bit(const char*, int len=-1);
+ bool operator!() const;
+#ifndef TQT_NO_ASCII_CAST
+ operator const char *() const { return ascii(); }
+#endif
+#ifndef TQT_NO_STL
+ operator std::string() const { return ascii() ? ascii() : ""; }
+#endif
+
+ static TQString fromUcs2( const unsigned short *ucs2 );
+ const unsigned short *ucs2() const;
+
+ TQString &setUnicode( const TQChar* tqunicode, uint len );
+ TQString &setUnicodeCodes( const ushort* tqunicode_as_ushorts, uint len );
+ TQString &setAscii( const char*, int len=-1 );
+ TQString &setLatin1( const char*, int len=-1 );
+
+ int compare( const TQString& s ) const;
+ static int compare( const TQString& s1, const TQString& s2 )
+ { return s1.compare( s2 ); }
+
+ int localeAwareCompare( const TQString& s ) const;
+ static int localeAwareCompare( const TQString& s1, const TQString& s2 )
+ { return s1.localeAwareCompare( s2 ); }
+
+#ifndef TQT_NO_DATASTREAM
+ friend TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQString & );
+#endif
+
+ void compose();
+
+#ifndef TQT_NO_COMPAT
+ const char* data() const { return ascii(); }
+#endif
+
+#if defined(TQ_TQDOC)
+ bool startsWith( const TQString& str, bool cs = TRUE ) const;
+ bool endsWith( const TQString& str, bool cs = TRUE ) const;
+#else
+ // ### TQt 4.0: merge these two into one, and remove TQ_TQDOC hack
+ bool startsWith( const TQString& str ) const;
+ bool startsWith( const TQString& str, bool cs ) const;
+
+ // ### TQt 4.0: merge these two into one, and remove TQ_TQDOC hack
+ bool endsWith( const TQString& str ) const;
+ bool endsWith( const TQString& str, bool cs ) const;
+#endif
+
+ void setLength( uint newLength );
+
+ uint capacity() const;
+ void reserve( uint minCapacity );
+ void squeeze();
+
+ bool simpleText() const { if ( !d->issimpletext ) checkSimpleText(); return (bool)d->issimpletext; }
+ bool isRightToLeft() const;
+
+
+private:
+ TQString( int size, bool /* dummy */ ); // allocate size incl. \0
+
+ void deref();
+ void real_detach();
+ void subat( uint );
+ TQString multiArg( int numArgs, const TQString& a1, const TQString& a2,
+ const TQString& a3 = TQString::null,
+ const TQString& a4 = TQString::null ) const;
+
+ void checkSimpleText() const;
+ void grow( uint newLength );
+#ifndef TQT_NO_CAST_ASCII
+ TQString &insertHelper( uint index, const char *s, uint len=UINT_MAX );
+ TQString &operatorPlusEqHelper( const char *s, uint len2=UINT_MAX );
+#endif
+
+ static TQChar* latin1ToUnicode( const char*, uint * len, uint maxlen=(uint)-1 );
+ static TQChar* latin1ToUnicode( const TQByteArray&, uint * len );
+ static char* tqunicodeToLatin1( const TQChar*, uint len );
+
+ TQStringData *d;
+ static TQStringData* shared_null;
+ static TQStringData* makeSharedNull();
+
+ friend class TQConstString;
+ friend class TQTextStream;
+ TQString( TQStringData* dd, bool /* dummy */ ) : d(dd) { }
+
+ // needed for TQDeepCopy
+ void detach();
+ friend class TQDeepCopy<TQString>;
+};
+
+class TQ_EXPORT TQCharRef {
+ friend class TQString;
+ TQString& s;
+ uint p;
+ TQCharRef(TQString* str, uint pos) : s(*str), p(pos) { }
+
+public:
+ // most TQChar operations repeated here
+
+ // all this is not documented: We just say "like TQChar" and let it be.
+#ifndef TQ_TQDOC
+ ushort tqunicode() const { return s.constref(p).tqunicode(); }
+ char latin1() const { return s.constref(p).latin1(); }
+
+ // An operator= for each TQChar cast constructors
+ TQCharRef operator=(char c ) { s.ref(p)=c; return *this; }
+ TQCharRef operator=(uchar c ) { s.ref(p)=c; return *this; }
+ TQCharRef operator=(TQChar c ) { s.ref(p)=c; return *this; }
+ TQCharRef operator=(const TQCharRef& c ) { s.ref(p)=c.tqunicode(); return *this; }
+ TQCharRef operator=(ushort rc ) { s.ref(p)=rc; return *this; }
+ TQCharRef operator=(short rc ) { s.ref(p)=rc; return *this; }
+ TQCharRef operator=(uint rc ) { s.ref(p)=rc; return *this; }
+ TQCharRef operator=(int rc ) { s.ref(p)=rc; return *this; }
+
+ operator TQChar () const { return s.constref(p); }
+
+ // each function...
+ bool isNull() const { return tqunicode()==0; }
+ bool isPrint() const { return s.constref(p).isPrint(); }
+ bool isPunct() const { return s.constref(p).isPunct(); }
+ bool isSpace() const { return s.constref(p).isSpace(); }
+ bool isMark() const { return s.constref(p).isMark(); }
+ bool isLetter() const { return s.constref(p).isLetter(); }
+ bool isNumber() const { return s.constref(p).isNumber(); }
+ bool isLetterOrNumber() { return s.constref(p).isLetterOrNumber(); }
+ bool isDigit() const { return s.constref(p).isDigit(); }
+
+ int digitValue() const { return s.constref(p).digitValue(); }
+ TQChar lower() const { return s.constref(p).lower(); }
+ TQChar upper() const { return s.constref(p).upper(); }
+
+ TQChar::Category category() const { return s.constref(p).category(); }
+ TQChar::Direction direction() const { return s.constref(p).direction(); }
+ TQChar::Joining joining() const { return s.constref(p).joining(); }
+ bool mirrored() const { return s.constref(p).mirrored(); }
+ TQChar mirroredChar() const { return s.constref(p).mirroredChar(); }
+ const TQString &decomposition() const { return s.constref(p).decomposition(); }
+ TQChar::Decomposition decompositionTag() const { return s.constref(p).decompositionTag(); }
+ unsigned char combiningClass() const { return s.constref(p).combiningClass(); }
+
+ // Not the non-const ones of these.
+ uchar cell() const { return s.constref(p).cell(); }
+ uchar row() const { return s.constref(p).row(); }
+#endif
+};
+
+inline TQCharRef TQString::at( uint i ) { return TQCharRef(this,i); }
+inline TQCharRef TQString::operator[]( int i ) { return tqat((uint)i); }
+
+
+class TQ_EXPORT TQConstString : private TQString {
+public:
+ TQConstString( const TQChar* tqunicode, uint length );
+ ~TQConstString();
+ const TQString& string() const { return *this; }
+};
+
+
+/*****************************************************************************
+ TQString stream functions
+ *****************************************************************************/
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQString & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQString & );
+#endif
+
+/*****************************************************************************
+ TQString inline functions
+ *****************************************************************************/
+
+// These two move code into makeSharedNull() and deletesData()
+// to improve cache-coherence (and reduce code bloat), while
+// keeping the common cases fast.
+//
+// No safe way to pre-init shared_null on ALL compilers/linkers.
+inline TQString::TQString() :
+ d(shared_null ? shared_null : makeSharedNull())
+{
+ d->ref();
+}
+//
+inline TQString::~TQString()
+{
+ if ( d->deref() ) {
+ if ( d != shared_null )
+ d->deleteSelf();
+ }
+}
+
+// needed for TQDeepCopy
+inline void TQString::detach()
+{ real_detach(); }
+
+inline TQString TQString::section( TQChar sep, int start, int end, int flags ) const
+{ return section(TQString(sep), start, end, flags); }
+
+inline TQString TQString::section( char sep, int start, int end, int flags ) const
+{ return section(TQChar(sep), start, end, flags); }
+
+#ifndef TQT_NO_CAST_ASCII
+inline TQString TQString::section( const char *in_sep, int start, int end, int flags ) const
+{ return section(TQString(in_sep), start, end, flags); }
+#endif
+
+inline TQString &TQString::operator=( TQChar c )
+{ *this = TQString(c); return *this; }
+
+inline TQString &TQString::operator=( char c )
+{ *this = TQString(TQChar(c)); return *this; }
+
+inline bool TQString::isNull() const
+{ return tqunicode() == 0; }
+
+inline bool TQString::operator!() const
+{ return isNull(); }
+
+inline uint TQString::length() const
+{ return d->len; }
+
+inline uint TQString::capacity() const
+{ return d->maxl; }
+
+inline bool TQString::isEmpty() const
+{ return length() == 0; }
+
+inline TQString TQString::copy() const
+{ return TQString( *this ); }
+
+#ifndef TQT_NO_CAST_ASCII
+inline TQString &TQString::insert( uint index, const char *s )
+{ return insertHelper( index, s ); }
+
+inline TQString &TQString::insert( uint index, const TQByteArray &s )
+{
+ int pos = s.tqfind( 0 );
+ return insertHelper( index, s, pos==-1 ? s.size() : pos );
+}
+#endif
+
+inline TQString &TQString::prepend( const TQString & s )
+{ return insert(0,s); }
+
+inline TQString &TQString::prepend( TQChar c )
+{ return insert(0,c); }
+
+inline TQString &TQString::prepend( char c )
+{ return insert(0,c); }
+
+#ifndef TQT_NO_CAST_ASCII
+inline TQString &TQString::prepend( const TQByteArray & s )
+{ return insert(0,s); }
+#endif
+
+#ifndef TQT_NO_CAST_ASCII
+inline TQString &TQString::operator+=( const TQByteArray &s )
+{
+ int pos = s.tqfind( 0 );
+ return operatorPlusEqHelper( s, pos==-1 ? s.size() : pos );
+}
+#endif
+
+inline TQString &TQString::append( const TQString & s )
+{ return operator+=(s); }
+
+#ifndef TQT_NO_CAST_ASCII
+inline TQString &TQString::append( const TQByteArray &s )
+{ return operator+=(s); }
+
+inline TQString &TQString::append( const char * s )
+{ return operator+=(s); }
+#endif
+
+inline TQString &TQString::append( TQChar c )
+{ return operator+=(c); }
+
+inline TQString &TQString::append( char c )
+{ return operator+=(c); }
+
+#ifndef TQT_NO_STL
+inline TQString &TQString::operator=( const std::string& str )
+{ return operator=(str.c_str()); }
+#ifndef TQT_NO_CAST_ASCII
+inline TQString &TQString::operator+=( const std::string& s )
+{ return operator+=(s.c_str()); }
+inline TQString &TQString::append( const std::string& s )
+{ return operator+=(s); }
+inline TQString &TQString::prepend( const std::string& s )
+{ return insert(0, s); }
+#endif
+#endif
+
+inline TQString &TQString::setNum( short n, int base )
+{ return setNum((TQ_LLONG)n, base); }
+
+inline TQString &TQString::setNum( ushort n, int base )
+{ return setNum((TQ_ULLONG)n, base); }
+
+inline TQString &TQString::setNum( int n, int base )
+{ return setNum((TQ_LLONG)n, base); }
+
+inline TQString &TQString::setNum( uint n, int base )
+{ return setNum((TQ_ULLONG)n, base); }
+
+inline TQString &TQString::setNum( float n, char f, int prec )
+{ return setNum((double)n,f,prec); }
+
+inline TQString TQString::arg( int a, int fieldWidth, int base ) const
+{ return arg( (TQ_LLONG)a, fieldWidth, base ); }
+
+inline TQString TQString::arg( uint a, int fieldWidth, int base ) const
+{ return arg( (TQ_ULLONG)a, fieldWidth, base ); }
+
+inline TQString TQString::arg( short a, int fieldWidth, int base ) const
+{ return arg( (TQ_LLONG)a, fieldWidth, base ); }
+
+inline TQString TQString::arg( ushort a, int fieldWidth, int base ) const
+{ return arg( (TQ_ULLONG)a, fieldWidth, base ); }
+
+inline TQString TQString::arg( const TQString& a1, const TQString& a2 ) const {
+ return multiArg( 2, a1, a2 );
+}
+
+inline TQString TQString::arg( const TQString& a1, const TQString& a2,
+ const TQString& a3 ) const {
+ return multiArg( 3, a1, a2, a3 );
+}
+
+inline TQString TQString::arg( const TQString& a1, const TQString& a2,
+ const TQString& a3, const TQString& a4 ) const {
+ return multiArg( 4, a1, a2, a3, a4 );
+}
+
+inline int TQString::tqfind( char c, int index, bool cs ) const
+{ return tqfind(TQChar(c), index, cs); }
+
+inline int TQString::tqfindRev( char c, int index, bool cs ) const
+{ return tqfindRev( TQChar(c), index, cs ); }
+
+#ifndef TQT_NO_CAST_ASCII
+inline int TQString::tqfind( const char* str, int index ) const
+{ return tqfind(TQString::fromAscii(str), index); }
+
+inline int TQString::tqfindRev( const char* str, int index ) const
+{ return tqfindRev(TQString::fromAscii(str), index); }
+#endif
+
+
+/*****************************************************************************
+ TQString non-member operators
+ *****************************************************************************/
+
+TQ_EXPORT bool operator!=( const TQString &s1, const TQString &s2 );
+TQ_EXPORT bool operator<( const TQString &s1, const TQString &s2 );
+TQ_EXPORT bool operator<=( const TQString &s1, const TQString &s2 );
+TQ_EXPORT bool operator==( const TQString &s1, const TQString &s2 );
+TQ_EXPORT bool operator>( const TQString &s1, const TQString &s2 );
+TQ_EXPORT bool operator>=( const TQString &s1, const TQString &s2 );
+#ifndef TQT_NO_CAST_ASCII
+TQ_EXPORT bool operator!=( const TQString &s1, const char *s2 );
+TQ_EXPORT bool operator<( const TQString &s1, const char *s2 );
+TQ_EXPORT bool operator<=( const TQString &s1, const char *s2 );
+TQ_EXPORT bool operator==( const TQString &s1, const char *s2 );
+TQ_EXPORT bool operator>( const TQString &s1, const char *s2 );
+TQ_EXPORT bool operator>=( const TQString &s1, const char *s2 );
+TQ_EXPORT bool operator!=( const char *s1, const TQString &s2 );
+TQ_EXPORT bool operator<( const char *s1, const TQString &s2 );
+TQ_EXPORT bool operator<=( const char *s1, const TQString &s2 );
+TQ_EXPORT bool operator==( const char *s1, const TQString &s2 );
+//TQ_EXPORT bool operator>( const char *s1, const TQString &s2 ); // MSVC++
+TQ_EXPORT bool operator>=( const char *s1, const TQString &s2 );
+#endif
+
+// Interoperability
+TQ_EXPORT bool operator==( const QString &s1, const TQString &s2 );
+
+TQ_EXPORT inline const TQString operator+( const TQString &s1, const TQString &s2 )
+{
+ TQString tmp( s1 );
+ tmp += s2;
+ return tmp;
+}
+
+#ifndef TQT_NO_CAST_ASCII
+TQ_EXPORT inline const TQString operator+( const TQString &s1, const char *s2 )
+{
+ TQString tmp( s1 );
+ tmp += TQString::fromAscii(s2);
+ return tmp;
+}
+
+TQ_EXPORT inline const TQString operator+( const char *s1, const TQString &s2 )
+{
+ TQString tmp = TQString::fromAscii( s1 );
+ tmp += s2;
+ return tmp;
+}
+#endif
+
+TQ_EXPORT inline const TQString operator+( const TQString &s1, TQChar c2 )
+{
+ TQString tmp( s1 );
+ tmp += c2;
+ return tmp;
+}
+
+TQ_EXPORT inline const TQString operator+( const TQString &s1, char c2 )
+{
+ TQString tmp( s1 );
+ tmp += c2;
+ return tmp;
+}
+
+TQ_EXPORT inline const TQString operator+( TQChar c1, const TQString &s2 )
+{
+ TQString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+TQ_EXPORT inline const TQString operator+( char c1, const TQString &s2 )
+{
+ TQString tmp;
+ tmp += c1;
+ tmp += s2;
+ return tmp;
+}
+
+#ifndef TQT_NO_STL
+TQ_EXPORT inline const TQString operator+(const TQString& s1, const std::string& s2)
+{
+ return s1 + TQString(s2);
+}
+
+TQ_EXPORT inline const TQString operator+(const std::string& s1, const TQString& s2)
+{
+ TQString tmp(s2);
+ return TQString(tmp.prepend(s1));
+}
+#endif
+
+
+#if defined(TQ_OS_WIN32)
+extern TQ_EXPORT TQString qt_winTQString(void*);
+extern TQ_EXPORT const void* qt_winTchar(const TQString& str, bool addnul);
+extern TQ_EXPORT void* qt_winTchar_new(const TQString& str);
+extern TQ_EXPORT TQCString qt_winTQString2MB( const TQString& s, int len=-1 );
+extern TQ_EXPORT TQString qt_winMB2TQString( const char* mb, int len=-1 );
+#endif
+
+#endif // USE_QT4
+
+#define TQ_DEFINED_TQSTRING
+#include "tqwinexport.h"
+#endif // TQSTRING_H
diff --git a/tqtinterface/qt4/src/tools/tqstringlist.cpp b/tqtinterface/qt4/src/tools/tqstringlist.cpp
new file mode 100644
index 0000000..6a10959
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqstringlist.cpp
@@ -0,0 +1,534 @@
+/****************************************************************************
+**
+** Implementation of TQStringList
+**
+** Created : 990406
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqstringlist.h"
+
+#ifndef TQT_NO_STRINGLIST
+#include "tqregexp.h"
+#include "tqstrlist.h"
+#include "tqdatastream.h"
+#include "tqtl.h"
+
+#ifdef USE_QT4
+
+#include <Qt/qstringlist.h>
+
+#endif
+
+/*!
+ \class TQStringList tqstringlist.h
+ \reentrant
+ \brief The TQStringList class provides a list of strings.
+
+ \ingroup tools
+ \ingroup shared
+ \ingroup text
+ \mainclass
+
+ It is used to store and manipulate strings that logically belong
+ together. Essentially TQStringList is a TQValueList of TQString
+ objects. Unlike TQStrList, which stores pointers to characters,
+ TQStringList holds real TQString objects. It is the class of choice
+ whenever you work with Unicode strings. TQStringList is part of the
+ \link tqtl.html TQt Template Library\endlink.
+
+ Like TQString itself, TQStringList objects are implicitly shared, so
+ passing them around as value-parameters is both fast and safe.
+
+ Strings can be added to a list using append(), operator+=() or
+ operator<<(), e.g.
+ \code
+ TQStringList fonts;
+ fonts.append( "Times" );
+ fonts += "Courier";
+ fonts += "Courier New";
+ fonts << "Helvetica [Cronyx]" << "Helvetica [Adobe]";
+ \endcode
+
+ String lists have an iterator, TQStringList::Iterator(), e.g.
+ \code
+ for ( TQStringList::Iterator it = fonts.begin(); it != fonts.end(); ++it ) {
+ cout << *it << ":";
+ }
+ cout << endl;
+ // Output:
+ // Times:Courier:Courier New:Helvetica [Cronyx]:Helvetica [Adobe]:
+ \endcode
+
+ Many TQt functions return string lists by value; to iterate over
+ these you should make a copy and iterate over the copy.
+
+ You can concatenate all the strings in a string list into a single
+ string (with an optional separator) using join(), e.g.
+ \code
+ TQString allFonts = fonts.join( ", " );
+ cout << allFonts << endl;
+ // Output:
+ // Times, Courier, Courier New, Helvetica [Cronyx], Helvetica [Adobe]
+ \endcode
+
+ You can sort the list with sort(), and extract a new list which
+ tqcontains only those strings which contain a particular substring
+ (or match a particular regular expression) using the grep()
+ functions, e.g.
+ \code
+ fonts.sort();
+ cout << fonts.join( ", " ) << endl;
+ // Output:
+ // Courier, Courier New, Helvetica [Adobe], Helvetica [Cronyx], Times
+
+ TQStringList helveticas = fonts.grep( "Helvetica" );
+ cout << helveticas.join( ", " ) << endl;
+ // Output:
+ // Helvetica [Adobe], Helvetica [Cronyx]
+ \endcode
+
+ Existing strings can be split into string lists with character,
+ string or regular expression separators, e.g.
+ \code
+ TQString s = "Red\tGreen\tBlue";
+ TQStringList colors = TQStringList::split( "\t", s );
+ cout << colors.join( ", " ) << endl;
+ // Output:
+ // Red, Green, Blue
+ \endcode
+*/
+
+/*!
+ \fn TQStringList::TQStringList()
+
+ Creates an empty string list.
+*/
+
+/*!
+ \fn TQStringList::TQStringList( const TQStringList& l )
+
+ Creates a copy of the list \a l. This function is very fast
+ because TQStringList is implicitly shared. In most situations this
+ acts like a deep copy, for example, if this list or the original
+ one or some other list referencing the same shared data is
+ modified, the modifying list first makes a copy, i.e.
+ copy-on-write.
+ In a threaded environment you may require a real deep copy
+ \omit see \l TQDeepCopy\endomit.
+*/
+
+/*!
+ \fn TQStringList::TQStringList (const TQString & i)
+
+ Constructs a string list consisting of the single string \a i.
+ Longer lists are easily created as follows:
+
+ \code
+ TQStringList items;
+ items << "Buy" << "Sell" << "Update" << "Value";
+ \endcode
+*/
+
+/*!
+ \fn TQStringList::TQStringList (const char* i)
+
+ Constructs a string list consisting of the single Latin-1 string \a i.
+*/
+
+/*!
+ \fn TQStringList::TQStringList( const TQValueList<TQString>& l )
+
+ Constructs a new string list that is a copy of \a l.
+*/
+
+/*!
+ Sorts the list of strings in ascending case-sensitive order.
+
+ Sorting is very fast. It uses the \link tqtl.html TQt Template
+ Library's\endlink efficient HeapSort implementation that has a
+ time complexity of O(n*log n).
+
+ If you want to sort your strings in an arbitrary order consider
+ using a TQMap. For example you could use a TQMap\<TQString,TQString\>
+ to create a case-insensitive ordering (e.g. mapping the lowercase
+ text to the text), or a TQMap\<int,TQString\> to sort the strings by
+ some integer index, etc.
+*/
+void TQStringList::sort()
+{
+ qHeapSort( *this );
+}
+
+/*!
+ \overload
+
+ This version of the function uses a TQChar as separator, rather
+ than a regular expression.
+
+ \sa join() TQString::section()
+*/
+
+TQStringList TQStringList::split( const TQChar &sep, const TQString &str,
+ bool allowEmptyEntries )
+{
+ return split( TQString(sep), str, allowEmptyEntries );
+}
+
+/*!
+ \overload
+
+ This version of the function uses a TQString as separator, rather
+ than a regular expression.
+
+ If \a sep is an empty string, the return value is a list of
+ one-character strings: split( TQString( "" ), "four" ) returns the
+ four-item list, "f", "o", "u", "r".
+
+ If \a allowEmptyEntries is TRUE, a null string is inserted in
+ the list wherever the separator matches twice without intervening
+ text.
+
+ \sa join() TQString::section()
+*/
+
+TQStringList TQStringList::split( const TQString &sep, const TQString &str,
+ bool allowEmptyEntries )
+{
+ TQStringList lst;
+
+ int j = 0;
+ int i = str.tqfind( sep, j );
+
+ while ( i != -1 ) {
+ if ( i > j && i <= (int)str.length() )
+ lst << str.mid( j, i - j );
+ else if ( allowEmptyEntries )
+ lst << TQString::null;
+ j = i + sep.length();
+ i = str.tqfind( sep, sep.length() > 0 ? j : j+1 );
+ }
+
+ int l = str.length() - 1;
+ if ( str.mid( j, l - j + 1 ).length() > 0 )
+ lst << str.mid( j, l - j + 1 );
+ else if ( allowEmptyEntries )
+ lst << TQString::null;
+
+ return lst;
+}
+
+#ifndef TQT_NO_REGEXP
+/*!
+ Splits the string \a str into strings wherever the regular
+ expression \a sep occurs, and returns the list of those strings.
+
+ If \a allowEmptyEntries is TRUE, a null string is inserted in
+ the list wherever the separator matches twice without intervening
+ text.
+
+ For example, if you split the string "a,,b,c" on commas, split()
+ returns the three-item list "a", "b", "c" if \a allowEmptyEntries
+ is FALSE (the default), and the four-item list "a", "", "b", "c"
+ if \a allowEmptyEntries is TRUE.
+
+ If \a sep does not match anywhere in \a str, split() returns a
+ single element list with the element containing the single string
+ \a str.
+
+ \sa join() TQString::section()
+*/
+
+TQStringList TQStringList::split( const TQRegExp &sep, const TQString &str,
+ bool allowEmptyEntries )
+{
+ TQStringList lst;
+
+ TQRegExp tep = sep;
+
+ int j = 0;
+ int i = tep.search( str, j );
+
+ while ( i != -1 ) {
+ if ( str.mid( j, i - j ).length() > 0 )
+ lst << str.mid( j, i - j );
+ else if ( allowEmptyEntries )
+ lst << TQString::null;
+ if ( tep.matchedLength() == 0 )
+ j = i + 1;
+ else
+ j = i + tep.matchedLength();
+ i = tep.search( str, j );
+ }
+
+ int l = str.length() - 1;
+ if ( str.mid( j, l - j + 1 ).length() > 0 )
+ lst << str.mid( j, l - j + 1 );
+ else if ( allowEmptyEntries )
+ lst << TQString::null;
+
+ return lst;
+}
+#endif
+
+/*!
+ Returns a list of all the strings containing the substring \a str.
+
+ If \a cs is TRUE, the grep is done case-sensitively; otherwise
+ case is ignored.
+
+ \code
+ TQStringList list;
+ list << "Bill Gates" << "John Doe" << "Bill Clinton";
+ list = list.grep( "Bill" );
+ // list == ["Bill Gates", "Bill Clinton"]
+ \endcode
+
+ \sa TQString::tqfind()
+*/
+
+TQStringList TQStringList::grep( const TQString &str, bool cs ) const
+{
+ TQStringList res;
+ for ( TQStringList::ConstIterator it = begin(); it != end(); ++it )
+ if ( (*it).tqcontains(str, cs) )
+ res << *it;
+
+ return res;
+}
+
+#ifndef TQT_NO_REGEXP
+/*!
+ \overload
+
+ Returns a list of all the strings that match the regular
+ expression \a rx.
+
+ \sa TQString::tqfind()
+*/
+
+TQStringList TQStringList::grep( const TQRegExp &rx ) const
+{
+ TQStringList res;
+ for ( TQStringList::ConstIterator it = begin(); it != end(); ++it )
+ if ( (*it).tqfind(rx) != -1 )
+ res << *it;
+
+ return res;
+}
+#endif
+
+/*!
+ Replaces every occurrence of the string \a before in the strings
+ that constitute the string list with the string \a after. Returns
+ a reference to the string list.
+
+ If \a cs is TRUE, the search is case sensitive; otherwise the
+ search is case insensitive.
+
+ Example:
+ \code
+ TQStringList list;
+ list << "alpha" << "beta" << "gamma" << "epsilon";
+ list.gres( "a", "o" );
+ // list == ["olpho", "beto", "gommo", "epsilon"]
+ \endcode
+
+ \sa TQString::tqreplace()
+*/
+TQStringList& TQStringList::gres( const TQString &before, const TQString &after,
+ bool cs )
+{
+ TQStringList::Iterator it = begin();
+ while ( it != end() ) {
+ (*it).tqreplace( before, after, cs );
+ ++it;
+ }
+ return *this;
+}
+
+#ifndef TQT_NO_REGEXP_CAPTURE
+/*!
+ \overload
+
+ Replaces every occurrence of the regexp \a rx in the string
+ with \a after. Returns a reference to the string list.
+
+ Example:
+ \code
+ TQStringList list;
+ list << "alpha" << "beta" << "gamma" << "epsilon";
+ list.gres( TQRegExp("^a"), "o" );
+ // list == ["olpha", "beta", "gamma", "epsilon"]
+ \endcode
+
+ For regexps containing \link tqregexp.html#capturing-text
+ capturing parentheses \endlink, occurrences of <b>\\1</b>,
+ <b>\\2</b>, ..., in \a after are tqreplaced with \a{rx}.cap(1),
+ cap(2), ...
+
+ Example:
+ \code
+ TQStringList list;
+ list << "Bill Clinton" << "Gates, Bill";
+ list.gres( TQRegExp("^(.*), (.*)$"), "\\2 \\1" );
+ // list == ["Bill Clinton", "Bill Gates"]
+ \endcode
+
+ \sa TQString::tqreplace()
+*/
+TQStringList& TQStringList::gres( const TQRegExp &rx, const TQString &after )
+{
+ TQStringList::Iterator it = begin();
+ while ( it != end() ) {
+ (*it).tqreplace( rx, after );
+ ++it;
+ }
+ return *this;
+}
+
+#endif
+
+/*!
+ Joins the string list into a single string with each element
+ separated by the string \a sep (which can be empty).
+
+ \sa split()
+*/
+TQString TQStringList::join( const TQString &sep ) const
+{
+ TQString res;
+ bool alredy = FALSE;
+ for ( TQStringList::ConstIterator it = begin(); it != end(); ++it ) {
+ if ( alredy )
+ res += sep;
+ alredy = TRUE;
+ res += *it;
+ }
+
+ return res;
+}
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator>>( TQDataStream & s, TQStringList& l )
+{
+ return s >> (TQValueList<TQString>&)l;
+}
+
+TQ_EXPORT TQDataStream &operator<<( TQDataStream & s, const TQStringList& l )
+{
+ return s << (const TQValueList<TQString>&)l;
+}
+#endif
+
+/*!
+ Converts from an ASCII-TQStrList \a ascii to a TQStringList (Unicode).
+*/
+TQStringList TQStringList::fromStrList(const TQStrList& ascii)
+{
+ TQStringList res;
+ const char * s;
+ for ( TQStrListIterator it(ascii); (s=it.current()); ++it )
+ res << s;
+ return res;
+}
+
+/*! \fn void TQStringList::detach()
+ \reimp
+*/
+
+#ifdef USE_QT4
+
+// Interoperability
+// [FIXME]
+// These conversions are probably too weak
+
+#if 0
+/*!
+ QT4 INTEROPERABILITY
+*/
+TQStringList::TQStringList( const QStringList &qs )
+{
+ setAscii( TQString(qs).ascii() );
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+TQStringList::operator QStringList() const
+{
+ return QStringList::fromUtf8( this->utf8() );
+}
+#endif
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+TQStringList::operator QStringList() const
+{
+ QStringList qn;
+ for (int i = 0; i < size(); ++i) {
+ qn.append(*at(i));
+ }
+ return qn;
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+// TQStringList TQStringList::operator=( const QStringList qs )
+// {
+// TQStringList qn;
+// for (int i = 0; i < qs.size(); ++i) {
+// qn.append(qs.at(i));
+// }
+// return qn;
+// }
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+TQStringList TQStringList::convertFromQStringList( const QStringList qs )
+{
+ TQStringList qn;
+ for (int i = 0; i < qs.size(); ++i) {
+ qn.append(qs.at(i));
+ }
+ return qn;
+}
+
+#endif // USE_QT4
+
+#endif //TQT_NO_STRINGLIST
diff --git a/tqtinterface/qt4/src/tools/tqstringlist.h b/tqtinterface/qt4/src/tools/tqstringlist.h
new file mode 100644
index 0000000..6ca6802
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqstringlist.h
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Definition of TQStringList class
+**
+** Created : 990406
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTRINGLIST_H
+#define TQSTRINGLIST_H
+
+#include "tqtglobaldefines.h"
+
+#ifndef TQT_H
+#include "tqvaluelist.h"
+#include "tqstring.h"
+#include "tqstrlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_STRINGLIST
+
+class TQRegExp;
+template <class T> class TQDeepCopy;
+
+#if defined(TQ_TEMPLATEDLL)
+// TQMOC_SKIP_BEGIN
+//TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueList<TQString>;
+// TQMOC_SKIP_END
+#endif
+
+class TQ_EXPORT TQStringList : public TQValueList<TQString>
+{
+public:
+ TQStringList() { }
+ TQStringList( const TQStringList& l ) : TQValueList<TQString>(l) { }
+ TQStringList( const TQValueList<TQString>& l ) : TQValueList<TQString>(l) { }
+ TQStringList( const TQString& i ) { append(i); }
+#ifndef TQT_NO_CAST_ASCII
+ TQStringList( const char* i ) { append(i); }
+#endif
+
+ static TQStringList fromStrList(const TQStrList&);
+
+ void sort();
+
+ static TQStringList split( const TQString &sep, const TQString &str, bool allowEmptyEntries = FALSE );
+ static TQStringList split( const TQChar &sep, const TQString &str, bool allowEmptyEntries = FALSE );
+#ifndef TQT_NO_REGEXP
+ static TQStringList split( const TQRegExp &sep, const TQString &str, bool allowEmptyEntries = FALSE );
+#endif
+ TQString join( const TQString &sep ) const;
+
+ TQStringList grep( const TQString &str, bool cs = TRUE ) const;
+#ifndef TQT_NO_REGEXP
+ TQStringList grep( const TQRegExp &expr ) const;
+#endif
+
+ TQStringList& gres( const TQString &before, const TQString &after,
+ bool cs = TRUE );
+#ifndef TQT_NO_REGEXP_CAPTURE
+ TQStringList& gres( const TQRegExp &expr, const TQString &after );
+#endif
+
+#ifdef USE_QT4
+ // Interoperability
+// TQStringList( const QStringList &qs );
+ operator QStringList() const;
+// TQStringList operator=( const QStringList qs );
+ static TQStringList convertFromQStringList( const QStringList qs );
+#endif // USE_QT4
+
+protected:
+ void detach() { TQValueList<TQString>::detach(); }
+ friend class TQDeepCopy< TQStringList >;
+};
+
+#ifndef TQT_NO_DATASTREAM
+class TQDataStream;
+extern TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQStringList& );
+extern TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQStringList& );
+#endif
+
+#endif // TQT_NO_STRINGLIST
+#endif // TQSTRINGLIST_H
diff --git a/tqtinterface/qt4/src/tools/tqstrlist.h b/tqtinterface/qt4/src/tools/tqstrlist.h
new file mode 100644
index 0000000..5dbc9c8
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqstrlist.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Definition of TQStrList, TQStrIList and TQStrListIterator classes
+**
+** Created : 920730
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTRLIST_H
+#define TQSTRLIST_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqptrlist.h"
+#include "tqdatastream.h"
+#endif // TQT_H
+
+#ifdef USE_QT4
+
+#include <Qt/qlist.h>
+
+#endif // USE_QT4
+
+#if defined(TQ_TQDOC)
+class TQStrListIterator : public TQPtrListIterator<char>
+{
+};
+#else
+typedef TQPtrListIterator<char> TQStrListIterator;
+#endif
+
+class TQ_EXPORT TQStrList : public TQPtrList<char>
+{
+public:
+ TQStrList( bool deepCopies=TRUE ) { dc = deepCopies; del_item = deepCopies; }
+ TQStrList( const TQStrList & );
+ ~TQStrList() { clear(); }
+ TQStrList& operator=( const TQStrList & );
+
+#ifdef USE_QT4
+ // Interoperability
+// TQStrList( const QList<QByteArray> &ql );
+// operator QStrList() const;
+// TQStrList &operator=( const QList<QByteArray> &ql );
+// TQStrList convertFromQStrList( const QList<QByteArray> &ql );
+
+#endif // USE_QT4
+
+private:
+ TQPtrCollection::Item newItem( TQPtrCollection::Item d ) { return dc ? qstrdup( (const char*)d ) : d; }
+ void deleteItem( TQPtrCollection::Item d ) { if ( del_item ) delete[] (char*)d; }
+ int compareItems( TQPtrCollection::Item s1, TQPtrCollection::Item s2 ) { return qstrcmp((const char*)s1,
+ (const char*)s2); }
+#ifndef TQT_NO_DATASTREAM
+ TQDataStream &read( TQDataStream &s, TQPtrCollection::Item &d )
+ { s >> (char *&)d; return s; }
+ QDataStream &write( QDataStream &s, TQPtrCollection::Item d ) const
+ { return s << (const char *)d; }
+#endif
+ bool dc;
+};
+
+
+class TQ_EXPORT TQStrIList : public TQStrList // case insensitive string list
+{
+public:
+ TQStrIList( bool deepCopies=TRUE ) : TQStrList( deepCopies ) {}
+ ~TQStrIList() { clear(); }
+private:
+ int compareItems( TQPtrCollection::Item s1, TQPtrCollection::Item s2 )
+ { return qstricmp((const char*)s1,
+ (const char*)s2); }
+};
+
+
+inline TQStrList & TQStrList::operator=( const TQStrList &strList )
+{
+ clear();
+ dc = strList.dc;
+ del_item = dc;
+ TQPtrList<char>::operator=( strList );
+ return *this;
+}
+
+inline TQStrList::TQStrList( const TQStrList &strList )
+ : TQPtrList<char>( strList )
+{
+ dc = FALSE;
+ operator=( strList );
+}
+
+#ifdef USE_QT4
+
+// Interoperability
+// FIXME
+// These conversions are probably too weak
+
+#if 0
+/*!
+ QT4 INTEROPERABILITY
+*/
+TQStringList::TQStringList( const QList<QByteArray> &ql )
+{
+ setAscii( TQString(qs).ascii() );
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+TQStringList::operator QStringList() const
+{
+ return QStringList::fromUtf8( this->utf8() );
+}
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+TQStringList &TQStringList::operator=( const QList<QByteArray> &ql )
+{
+ TQStringList qn;
+ for (int i = 0; i < qs.size(); ++i) {
+ qn.append(qs.at(i));
+ }
+ return qn;
+}
+
+#endif
+
+/*!
+ QT4 INTEROPERABILITY
+*/
+inline TQStrList convertFromQStrList( const QList<QByteArray> &ql )
+{
+ TQStrList qn;
+ qn.clear();
+ for (int i = 0; i < ql.size(); ++i)
+ qn.append(ql.at(i).constData());
+ return qn;
+}
+
+#endif // USE_QT4
+
+#endif // TQSTRLIST_H
diff --git a/tqtinterface/qt4/src/tools/tqstrvec.h b/tqtinterface/qt4/src/tools/tqstrvec.h
new file mode 100644
index 0000000..d3a35bf
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqstrvec.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Definition of TQStrVec and TQStrIVec classes
+**
+** Created : 931203
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTRVEC_H
+#define TQSTRVEC_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tqptrvector.h"
+#include "tqdatastream.h"
+#endif // TQT_H
+
+class TQ_EXPORT TQStrVec : public TQPtrVector<char>
+{
+public:
+ TQStrVec() { dc = TRUE; }
+ TQStrVec( uint size, bool deepc = TRUE ) : TQPtrVector<char>(size) {dc=deepc;}
+ ~TQStrVec() { clear(); }
+private:
+ Item newItem( Item d ) { return dc ? qstrdup( (const char*)d ) : d; }
+ void deleteItem( Item d ) { if ( dc ) delete[] (char*)d; }
+ int compareItems( Item s1, Item s2 )
+ { return qstrcmp((const char*)s1,
+ (const char*)s2); }
+#ifndef TQT_NO_DATASTREAM
+ TQDataStream &read( TQDataStream &s, Item &d )
+ { s >> (char *&)d; return s; }
+ TQDataStream &write( TQDataStream &s, Item d ) const
+ { return s << (const char*)d; }
+#endif
+ bool dc;
+};
+
+
+class TQ_EXPORT TQStrIVec : public TQStrVec // case insensitive string vec
+{
+public:
+ TQStrIVec() {}
+ TQStrIVec( uint size, bool dc = TRUE ) : TQStrVec( size, dc ) {}
+ ~TQStrIVec() { clear(); }
+private:
+ int compareItems( Item s1, Item s2 )
+ { return qstricmp((const char*)s1,
+ (const char*)s2); }
+};
+
+
+#endif // TQSTRVEC_H
diff --git a/tqtinterface/qt4/src/tools/tqtextstream.cpp b/tqtinterface/qt4/src/tools/tqtextstream.cpp
new file mode 100644
index 0000000..842cb7e
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqtextstream.cpp
@@ -0,0 +1,2663 @@
+/****************************************************************************
+**
+** Implementation of TQTextStream class
+**
+** Created : 940922
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtextstream.h"
+
+#ifndef TQT_NO_TEXTSTREAM
+#include "tqtextcodec.h"
+#include "tqregexp.h"
+#include "tqbuffer.h"
+#include "tqfile.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#ifndef TQ_OS_TEMP
+#include <locale.h>
+#endif
+
+#if defined(TQ_OS_WIN32)
+#include "tqt_windows.h"
+#endif
+
+/*!
+ \class TQTextStream tqtextstream.h
+ \reentrant
+ \brief The TQTextStream class provides basic functions for reading
+ and writing text using a TQIODevice.
+
+ \ingroup io
+ \ingroup text
+ \mainclass
+
+ The text stream class has a functional interface that is very
+ similar to that of the standard C++ iostream class.
+
+ TQt provides several global functions similar to the ones in iostream:
+ \table
+ \header \i Function \i Meaning
+ \row \i bin \i sets the TQTextStream to read/write binary numbers
+ \row \i oct \i sets the TQTextStream to read/write octal numbers
+ \row \i dec \i sets the TQTextStream to read/write decimal numbers
+ \row \i hex \i sets the TQTextStream to read/write hexadecimal numbers
+ \row \i endl \i forces a line break
+ \row \i flush \i forces the TQIODevice to flush any buffered data
+ \row \i ws \i eats any available whitespace (on input)
+ \row \i reset \i resets the TQTextStream to its default mode (see reset())
+ \row \i qSetW(int) \i sets the \link width() field width \endlink
+ to the given argument
+ \row \i qSetFill(int) \i sets the \link fill() fill character
+ \endlink to the given argument
+ \row \i qSetPrecision(int) \i sets the \link precision() precision
+ \endlink to the given argument
+ \endtable
+
+ \warning By default TQTextStream will automatically detect whether
+ integers in the stream are in decimal, octal, hexadecimal or
+ binary format when reading from the stream. In particular, a
+ leading '0' signifies octal, i.e. the sequence "0100" will be
+ interpreted as 64.
+
+ The TQTextStream class reads and writes text; it is not appropriate
+ for dealing with binary data (but TQDataStream is).
+
+ By default, output of Unicode text (i.e. TQString) is done using
+ the local 8-bit encoding. This can be changed using the
+ setEncoding() method. For input, the TQTextStream will auto-detect
+ standard Unicode "byte order marked" text files; otherwise the
+ local 8-bit encoding is used.
+
+ The TQIODevice is set in the constructor, or later using
+ setDevice(). If the end of the input is reached atEnd() returns
+ TRUE. Data can be read into variables of the appropriate type
+ using the operator>>() overloads, or read in its entirety into a
+ single string using read(), or read a line at a time using
+ readLine(). Whitespace can be skipped over using skipWhiteSpace().
+ You can set flags for the stream using flags() or setf(). The
+ stream also supports width(), precision() and fill(); use reset()
+ to reset the defaults.
+
+ \sa TQDataStream
+*/
+
+/*!
+ \enum TQTextStream::Encoding
+
+ \value Locale
+ \value Latin1
+ \value Unicode
+ \value UnicodeNetworkOrder
+ \value UnicodeReverse
+ \value RawUnicode
+ \value UnicodeUTF8
+
+ See setEncoding() for an explanation of the encodings.
+*/
+
+/*
+ \class TQTSManip
+
+ \brief The TQTSManip class is an internal helper class for the
+ TQTextStream.
+
+ It is generally a very bad idea to use this class directly in
+ application programs.
+
+ \internal
+
+ This class makes it possible to give the TQTextStream function objects
+ with arguments, like this:
+ \code
+ TQTextStream cout( stdout, IO_WriteOnly );
+ cout << setprecision( 8 ); // TQTSManip used here!
+ cout << 3.14159265358979323846;
+ \endcode
+
+ The setprecision() function returns a TQTSManip object.
+ The TQTSManip object tqcontains a pointer to a member function in
+ TQTextStream and an integer argument.
+ When serializing a TQTSManip into a TQTextStream, the function
+ is executed with the argument.
+*/
+
+/*! \fn TQTSManip::TQTSManip( TQTSMFI m, int a )
+
+ Constructs a TQTSManip object which will call \a m (a member function
+ in TQTextStream which accepts a single int) with argument \a a when
+ TQTSManip::exec() is called. Used internally in e.g. endl:
+
+ \code
+ s << "some text" << endl << "more text";
+ \endcode
+*/
+
+/*! \fn void TQTSManip::exec( TQTextStream& s )
+
+ Calls the member function specified in the constructor, for object
+ \a s. Used internally in e.g. endl:
+
+ \code
+ s << "some text" << endl << "more text";
+ \endcode
+*/
+
+
+/*****************************************************************************
+ TQTextStream member functions
+ *****************************************************************************/
+
+#if defined(TQT_CHECK_STATE)
+#undef CHECK_STREAM_PRECOND
+#define CHECK_STREAM_PRECOND if ( !dev ) { \
+ qWarning( "TQTextStream: No tqdevice" ); \
+ return *this; }
+#else
+#define CHECK_STREAM_PRECOND
+#endif
+
+
+#define I_SHORT 0x0010
+#define I_INT 0x0020
+#define I_LONG 0x0030
+#define I_TYPE_MASK 0x00f0
+
+#define I_BASE_2 TQTS::bin
+#define I_BASE_8 TQTS::oct
+#define I_BASE_10 TQTS::dec
+#define I_BASE_16 TQTS::hex
+#define I_BASE_MASK (TQTS::bin | TQTS::oct | TQTS::dec | TQTS::hex)
+
+#define I_SIGNED 0x0100
+#define I_UNSIGNED 0x0200
+#define I_SIGN_MASK 0x0f00
+
+
+static const TQChar TQEOF = TQChar((ushort)0xffff); //guaranteed not to be a character.
+static const uint getline_buf_size = 256; // bufsize used by ts_getline()
+
+const int TQTextStream::basefield = I_BASE_MASK;
+const int TQTextStream::adjustfield = ( TQTextStream::left |
+ TQTextStream::right |
+ TQTextStream::internal );
+const int TQTextStream::floatfield = ( TQTextStream::scientific |
+ TQTextStream::fixed );
+
+
+class TQTextStreamPrivate {
+public:
+#ifndef TQT_NO_TEXTCODEC
+ TQTextStreamPrivate()
+ : decoder( 0 ), encoder( 0 ), sourceType( NotSet ) { }
+ ~TQTextStreamPrivate() {
+ delete decoder;
+ delete encoder;
+ }
+ TQTextDecoder *decoder;
+ TQTextEncoder *encoder;
+#else
+ TQTextStreamPrivate() : sourceType( NotSet ) { }
+ ~TQTextStreamPrivate() { }
+#endif
+ TQString ungetcBuf;
+
+ enum SourceType { NotSet, IODevice, String, ByteArray, File };
+ SourceType sourceType;
+};
+
+
+// skips whitespace and returns the first non-whitespace character
+TQChar TQTextStream::eat_ws()
+{
+ TQChar c;
+ do { c = ts_getc(); } while ( c != TQEOF && ts_isspace(c) );
+ return c;
+}
+
+void TQTextStream::init()
+{
+ // ### ungetcBuf = TQEOF;
+ dev = 0;
+ owndev = FALSE;
+ mapper = 0;
+ d = new TQTextStreamPrivate;
+ doUnicodeHeader = TRUE; // autodetect
+ latin1 = TRUE; // should use locale?
+ internalOrder = TQChar::networkOrdered();
+ networkOrder = TRUE;
+}
+
+/*!
+ Constructs a data stream that has no IO tqdevice.
+*/
+
+TQTextStream::TQTextStream()
+{
+ init();
+ setEncoding( Locale );
+ reset();
+ d->sourceType = TQTextStreamPrivate::NotSet;
+}
+
+/*!
+ Constructs a text stream that uses the IO tqdevice \a iod.
+*/
+
+TQTextStream::TQTextStream( QIODevice *iod )
+{
+ init();
+ setEncoding( Locale );
+ dev = TQT_TQIODEVICE(iod);
+ reset();
+ d->sourceType = TQTextStreamPrivate::IODevice;
+}
+
+/*!
+ Constructs a text stream that uses the IO tqdevice \a iod.
+*/
+
+TQTextStream::TQTextStream( QFile *iod )
+{
+ init();
+ setEncoding( Locale );
+ dev = TQT_TQIODEVICE(iod);
+ reset();
+ d->sourceType = TQTextStreamPrivate::IODevice;
+}
+
+// TODO: use special-case handling of this case in TQTextStream, and
+// simplify this class to only deal with TQChar or TQString data.
+class TQStringBuffer : public TQIODevice {
+public:
+ TQStringBuffer( TQString* str );
+ ~TQStringBuffer();
+ bool open( int m );
+ void close();
+ void flush();
+#ifdef USE_QT4
+ qint64 size() const;
+#else
+ Offset size() const;
+#endif
+ Offset at() const;
+ bool at( Offset pos );
+#ifdef USE_QT4
+ qint64 readData( char *p, qint64 len );
+ qint64 writeData( const char *p, qint64 len );
+#else
+ TQ_LONG readBlock( char *p, TQ_ULONG len );
+ TQ_LONG writeBlock( const char *p, TQ_ULONG len );
+#endif
+ int getch();
+ int putch( int ch );
+ int ungetch( int ch );
+protected:
+ TQString* s;
+
+private:
+ TQStringBuffer( const TQStringBuffer & );
+ TQStringBuffer &operator=( const TQStringBuffer & );
+};
+
+
+TQStringBuffer::TQStringBuffer( TQString* str )
+{
+ s = str;
+}
+
+TQStringBuffer::~TQStringBuffer()
+{
+}
+
+
+bool TQStringBuffer::open( int m )
+{
+ if ( !s ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQStringBuffer::open: No string" );
+#endif
+ return FALSE;
+ }
+ if ( isOpen() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQStringBuffer::open: Buffer already open" );
+#endif
+ return FALSE;
+ }
+ setMode( m );
+ if ( m & IO_Truncate )
+ s->truncate( 0 );
+
+ if ( m & IO_Append ) {
+ seek(s->length()*sizeof(TQChar));
+ } else {
+ seek(0);
+ }
+ setState( IO_Open );
+ resetqStatus();
+ return TRUE;
+}
+
+void TQStringBuffer::close()
+{
+ if ( isOpen() ) {
+ setFlags( IO_Direct );
+ seek(0);
+ }
+}
+
+void TQStringBuffer::flush()
+{
+}
+
+#ifdef USE_QT4
+qint64 TQStringBuffer::size() const
+#else
+TQIODevice::Offset TQStringBuffer::size() const
+#endif
+{
+ return s ? s->length()*sizeof(TQChar) : 0;
+}
+
+TQIODevice::Offset TQStringBuffer::at() const
+{
+ return pos();
+}
+
+bool TQStringBuffer::at( Offset pos )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "TQStringBuffer::at: Buffer is not open" );
+ return FALSE;
+ }
+#endif
+ if ( pos >= s->length()*2 ) {
+#if defined(TQT_CHECK_RANGE)
+#if defined(TQT_ABI_QT4)
+ qWarning( "TQStringBuffer::at: Index %lld out of range", pos );
+#else
+ qWarning( "TQStringBuffer::at: Index %lu out of range", pos );
+#endif
+#endif
+ return FALSE;
+ }
+ seek(pos);
+ return TRUE;
+}
+
+#ifdef USE_QT4
+qint64 TQStringBuffer::readData( char *p, qint64 len )
+#else
+TQ_LONG TQStringBuffer::readBlock( char *p, TQ_ULONG len )
+#endif
+{
+#if defined(TQT_CHECK_STATE)
+ TQ_CHECK_PTR( p );
+ if ( !isOpen() ) {
+ qWarning( "TQStringBuffer::readBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) {
+ qWarning( "TQStringBuffer::readBlock: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( pos() + len > s->length()*sizeof(TQChar) ) {
+ // overflow
+ if ( (uint)pos() >= s->length()*sizeof(TQChar) ) {
+ setqStatus( IO_ReadError );
+ return -1;
+ } else {
+ len = s->length()*2 - (uint)pos();
+ }
+ }
+ memcpy( p, ((const char*)(s->tqunicode()))+pos(), len );
+ seek(pos()+len);
+ return len;
+}
+
+#ifdef USE_QT4
+qint64 TQStringBuffer::writeData( const char *p, qint64 len )
+#else
+TQ_LONG TQStringBuffer::writeBlock( const char *p, TQ_ULONG len )
+#endif
+{
+#if defined(TQT_CHECK_NULL)
+ if ( p == 0 && len != 0 )
+ qWarning( "TQStringBuffer::writeBlock: Null pointer error" );
+#endif
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "TQStringBuffer::writeBlock: Buffer not open" );
+ return -1;
+ }
+ if ( !isWritable() ) {
+ qWarning( "TQStringBuffer::writeBlock: Write operation not permitted" );
+ return -1;
+ }
+ if ( pos()&1 ) {
+ qWarning( "TQStringBuffer::writeBlock: non-even index - non Unicode" );
+ return -1;
+ }
+ if ( len&1 ) {
+ qWarning( "TQStringBuffer::writeBlock: non-even length - non Unicode" );
+ return -1;
+ }
+#endif
+ s->tqreplace(pos()/2, len/2, (TQChar*)p, len/2);
+ seek(pos()+len);
+ return len;
+}
+
+int TQStringBuffer::getch()
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "TQStringBuffer::getch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) {
+ qWarning( "TQStringBuffer::getch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( (uint)pos() >= s->length()*2 ) { // overflow
+ setqStatus( IO_ReadError );
+ return -1;
+ }
+ int retval = (int)((const uchar *)s->tqunicode())[pos()];
+ seek(pos()+1);
+ return retval;
+}
+
+int TQStringBuffer::putch( int ch )
+{
+ char c = ch;
+ if ( writeBlock(&c,1) < 0 )
+ return -1;
+ else
+ return ch;
+}
+
+int TQStringBuffer::ungetch( int ch )
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !isOpen() ) {
+ qWarning( "TQStringBuffer::ungetch: Buffer not open" );
+ return -1;
+ }
+ if ( !isReadable() ) {
+ qWarning( "TQStringBuffer::ungetch: Read operation not permitted" );
+ return -1;
+ }
+#endif
+ if ( ch != -1 ) { // something to do with eof
+ if ( pos() )
+ seek(pos()-1);
+ else
+ ch = -1;
+ }
+ return ch;
+}
+
+
+/*!
+ Constructs a text stream that operates on the Unicode TQString, \a
+ str, through an internal tqdevice. The \a filemode argument is
+ passed to the tqdevice's open() function; see \l{TQIODevice::mode()}.
+
+ If you set an encoding or codec with setEncoding() or setCodec(),
+ this setting is ignored for text streams that operate on TQString.
+
+ Example:
+ \code
+ TQString str;
+ TQTextStream ts( &str, IO_WriteOnly );
+ ts << "pi = " << 3.14; // str == "pi = 3.14"
+ \endcode
+
+ Writing data to the text stream will modify the contents of the
+ string. The string will be expanded when data is written beyond
+ the end of the string. Note that the string will not be truncated:
+ \code
+ TQString str = "pi = 3.14";
+ TQTextStream ts( &str, IO_WriteOnly );
+ ts << "2+2 = " << 2+2; // str == "2+2 = 414"
+ \endcode
+
+ Note that because TQString is Unicode, you should not use
+ readRawBytes() or writeRawBytes() on such a stream.
+*/
+
+TQTextStream::TQTextStream( TQString* str, int filemode )
+{
+ // TODO: optimize for this case as it becomes more common
+ // (see TQStringBuffer above)
+ init();
+ dev = new TQStringBuffer( str );
+ ((TQStringBuffer *)dev)->open( filemode );
+ owndev = TRUE;
+ setEncoding(RawUnicode);
+ reset();
+ d->sourceType = TQTextStreamPrivate::String;
+}
+
+/*! \obsolete
+
+ This constructor is equivalent to the constructor taking a TQString*
+ parameter.
+*/
+
+TQTextStream::TQTextStream( TQString& str, int filemode )
+{
+ init();
+ dev = new TQStringBuffer( &str );
+ ((TQStringBuffer *)dev)->open( filemode );
+ owndev = TRUE;
+ setEncoding(RawUnicode);
+ reset();
+ d->sourceType = TQTextStreamPrivate::String;
+}
+
+/*!
+ Constructs a text stream that operates on the byte array, \a a,
+ through an internal TQBuffer tqdevice. The \a mode argument is passed
+ to the tqdevice's open() function; see \l{TQIODevice::mode()}.
+
+ Example:
+ \code
+ TQByteArray array;
+ TQTextStream ts( array, IO_WriteOnly );
+ ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"
+ \endcode
+
+ Writing data to the text stream will modify the contents of the
+ array. The array will be expanded when data is written beyond the
+ end of the string.
+
+ Same example, using a TQBuffer:
+ \code
+ TQByteArray array;
+ TQBuffer buf( array );
+ buf.open( IO_WriteOnly );
+ TQTextStream ts( &buf );
+ ts << "pi = " << 3.14 << '\0'; // array == "pi = 3.14"
+ buf.close();
+ \endcode
+*/
+
+TQTextStream::TQTextStream( TQByteArray a, int mode )
+{
+ init();
+ dev = TQT_TQIODEVICE(new TQBuffer( a ));
+ ((TQBuffer *)dev)->open( (QIODevice::OpenModeFlag)mode );
+ owndev = TRUE;
+ setEncoding( Latin1 ); //### Locale???
+ reset();
+ d->sourceType = TQTextStreamPrivate::ByteArray;
+}
+
+/*!
+ Constructs a text stream that operates on an existing file handle
+ \a fh through an internal TQFile tqdevice. The \a mode argument is
+ passed to the tqdevice's open() function; see \l{TQIODevice::mode()}.
+
+ Note that if you create a TQTextStream \c cout or another name that
+ is also used for another variable of a different type, some
+ linkers may confuse the two variables, which will often cause
+ crashes.
+*/
+
+TQTextStream::TQTextStream( FILE *fh, int mode )
+{
+ init();
+ setEncoding( Locale ); //###
+ dev = TQT_TQIODEVICE(new TQFile);
+ ((TQFile *)dev)->open( mode, fh );
+ owndev = TRUE;
+ reset();
+ d->sourceType = TQTextStreamPrivate::File;
+}
+
+/*!
+ Destroys the text stream.
+
+ The destructor does not affect the current IO tqdevice.
+*/
+
+TQTextStream::~TQTextStream()
+{
+ if ( owndev )
+ delete dev;
+ delete d;
+}
+
+/*!
+ Positions the read pointer at the first non-whitespace character.
+*/
+void TQTextStream::skipWhiteSpace()
+{
+ ts_ungetc( eat_ws() );
+}
+
+/*!
+ Internal.
+*/
+int TQTextStream::dev_getch() {
+ if (d->sourceType == TQTextStreamPrivate::String)
+ return static_cast<TQStringBuffer*>(dev)->getch();
+ else
+ return dev->getch();
+}
+
+/*!
+ Internal.
+*/
+int TQTextStream::dev_ungetch(int ch) {
+ if (d->sourceType == TQTextStreamPrivate::String)
+ return static_cast<TQStringBuffer*>(dev)->ungetch(ch);
+ else
+ return dev->ungetch(ch);
+}
+
+/*!
+ Tries to read \a len characters from the stream and stores them in
+ \a buf. Returns the number of characters really read.
+
+ \warning There will no TQEOF appended if the read reaches the end
+ of the file. EOF is reached when the return value does not equal
+ \a len.
+*/
+uint TQTextStream::ts_getbuf( TQChar* buf, uint len )
+{
+ if ( len < 1 )
+ return 0;
+
+ uint rnum = 0; // the number of TQChars really read
+
+ if ( d && d->ungetcBuf.length() ) {
+ while ( rnum < len && rnum < d->ungetcBuf.length() ) {
+ *buf = d->ungetcBuf.constref( rnum );
+ buf++;
+ rnum++;
+ }
+ d->ungetcBuf = d->ungetcBuf.mid( rnum );
+ if ( rnum >= len )
+ return rnum;
+ }
+
+ // we use dev_ungetch() for one of the bytes of the tqunicode
+ // byte-order mark, but a local unget hack for the other byte:
+ int ungetHack = EOF;
+
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE; // only at the top
+ int c1 = dev_getch();
+ if ( c1 == EOF )
+ return rnum;
+ int c2 = dev_getch();
+ if ( c1 == 0xfe && c2 == 0xff ) {
+ mapper = 0;
+ latin1 = FALSE;
+ internalOrder = TQChar::networkOrdered();
+ networkOrder = TRUE;
+ } else if ( c1 == 0xff && c2 == 0xfe ) {
+ mapper = 0;
+ latin1 = FALSE;
+ internalOrder = !TQChar::networkOrdered();
+ networkOrder = FALSE;
+ } else {
+ if ( c2 != EOF ) {
+ dev_ungetch( c2 );
+ ungetHack = c1;
+ } else {
+ /*
+ A small bug might hide here. If only the first byte
+ of a file has made it so far, and that first byte
+ is half of the byte-order mark, then the utfness
+ will not be detected.
+ */
+ dev_ungetch( c1 );
+ }
+ }
+ }
+
+#ifndef TQT_NO_TEXTCODEC
+ if ( mapper ) {
+ bool shortRead = FALSE;
+ if ( !d->decoder )
+ d->decoder = mapper->makeDecoder();
+ while( rnum < len ) {
+ TQString s;
+ bool readBlock = !( len == 1+rnum );
+ for (;;) {
+ // for efficiency: normally read a whole block
+ if ( readBlock ) {
+ // guess buffersize; this may be wrong (too small or too
+ // big). But we can handle this (either iterate reading
+ // or use ungetcBuf).
+ // Note that this might cause problems for codecs where
+ // one byte can result in >1 Unicode Characters if bytes
+ // are written to the stream in the meantime (loss of
+ // synchronicity).
+ uint rlen = len - rnum;
+ char *cbuf = new char[ rlen ];
+ if ( ungetHack != EOF ) {
+ rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
+ cbuf[0] = (char)ungetHack;
+ ungetHack = EOF;
+ } else {
+ rlen = dev->readBlock( cbuf, rlen );
+ }
+ s += d->decoder->toUnicode( cbuf, rlen );
+ delete[] cbuf;
+ // use buffered reading only for the first time, because we
+ // have to get the stream synchronous again (this is easier
+ // with single character reading)
+ readBlock = FALSE;
+ }
+ // get stream (and codec) in sync
+ int c;
+ if ( ungetHack == EOF ) {
+ c = dev_getch();
+ } else {
+ c = ungetHack;
+ ungetHack = EOF;
+ }
+ if ( c == EOF ) {
+ shortRead = TRUE;
+ break;
+ }
+ char b = c;
+ uint lengthBefore = s.length();
+ s += d->decoder->toUnicode( &b, 1 );
+ if ( s.length() > lengthBefore )
+ break; // it seems we are in sync now
+ }
+ uint i = 0;
+ uint end = TQMIN( len-rnum, s.length() );
+ while( i < end ) {
+ *buf = s.constref(i++);
+ buf++;
+ }
+ rnum += end;
+ if ( s.length() > i ) {
+ // could be = but append is clearer
+ d->ungetcBuf.append( s.mid( i ) );
+ }
+ if ( shortRead )
+ return rnum;
+ }
+ } else
+#endif
+ if ( latin1 ) {
+ if ( len == 1+rnum ) {
+ // use this method for one character because it is more efficient
+ // (arnt doubts whether it makes a difference, but lets it stand)
+ int c = (ungetHack == EOF) ? dev_getch() : ungetHack;
+ if ( c != EOF ) {
+ *buf = (char)c;
+ buf++;
+ rnum++;
+ }
+ } else {
+ if ( ungetHack != EOF ) {
+ *buf = (char)ungetHack;
+ buf++;
+ rnum++;
+ ungetHack = EOF;
+ }
+ char *cbuf = new char[len - rnum];
+ while ( !dev->atEnd() && rnum < len ) {
+ uint rlen = len - rnum;
+ rlen = dev->readBlock( cbuf, rlen );
+ char *it = cbuf;
+ char *end = cbuf + rlen;
+ while ( it < end ) {
+ *buf = *it;
+ buf++;
+ it++;
+ }
+ rnum += rlen;
+ }
+ delete[] cbuf;
+ }
+ } else { // UCS-2 or UTF-16
+ if ( len == 1+rnum ) {
+ int c1 = (ungetHack == EOF) ? dev_getch() : ungetHack;
+ if ( c1 == EOF )
+ return rnum;
+ int c2 = dev_getch();
+ if ( c2 == EOF )
+ return rnum;
+
+ if ( networkOrder ) {
+ *buf = TQChar( c2, c1 );
+ } else {
+ *buf = TQChar( c1, c2 );
+ }
+ buf++;
+ rnum++;
+ } else {
+ char *cbuf = new char[ 2*( len - rnum ) ]; // for paranoids: overflow possible
+ while ( !dev->atEnd() && rnum < len ) {
+ uint rlen = 2 * ( len-rnum );
+ if ( ungetHack != EOF ) {
+ rlen = 1+dev->readBlock( cbuf+1, rlen-1 );
+ cbuf[0] = (char)ungetHack;
+ ungetHack = EOF;
+ } else {
+ rlen = dev->readBlock( cbuf, rlen );
+ }
+ // We can't use an odd number of bytes, so put it back. But
+ // do it only if we are capable of reading more -- normally
+ // there should not be an odd number, but the file might be
+ // truncated or not in UTF-16...
+ if ( (rlen & 1) == 1 )
+ if ( !dev->atEnd() )
+ dev_ungetch( cbuf[--rlen] );
+ uint i = 0;
+ if ( networkOrder ) {
+ while( i < rlen ) {
+ *buf = TQChar( cbuf[i+1], cbuf[i] );
+ buf++;
+ i+=2;
+ }
+ } else {
+ while( i < rlen ) {
+ *buf = TQChar( cbuf[i], cbuf[i+1] );
+ buf++;
+ i+=2;
+ }
+ }
+ rnum += i/2;
+ }
+ delete[] cbuf;
+ }
+ }
+ return rnum;
+}
+
+/*!
+ Tries to read one line, but at most len characters from the stream
+ and stores them in \a buf.
+
+ Returns the number of characters really read. Newlines are not
+ stripped.
+
+ There will be a TQEOF appended if the read reaches the end of file;
+ this is different to ts_getbuf().
+
+ This function works only if a newline (as byte) is also a newline
+ (as resulting character) since it uses TQIODevice::readLine(). So
+ use it only for such codecs where this is true!
+
+ This function is (almost) a no-op for UTF 16. Don't use it if
+ doUnicodeHeader is TRUE!
+*/
+uint TQTextStream::ts_getline( TQChar* buf )
+{
+ uint rnum=0; // the number of TQChars really read
+ char cbuf[ getline_buf_size+1 ];
+
+ if ( d && d->ungetcBuf.length() ) {
+ while( rnum < getline_buf_size && rnum < d->ungetcBuf.length() ) {
+ buf[rnum] = d->ungetcBuf.constref(rnum);
+ rnum++;
+ }
+ d->ungetcBuf = d->ungetcBuf.mid( rnum );
+ if ( rnum >= getline_buf_size )
+ return rnum;
+ }
+
+#ifndef TQT_NO_TEXTCODEC
+ if ( mapper ) {
+ if ( !d->decoder )
+ d->decoder = mapper->makeDecoder();
+ TQString s;
+ bool readBlock = TRUE;
+ for (;;) {
+ // for efficiency: try to read a line
+ if ( readBlock ) {
+ int rlen = getline_buf_size - rnum;
+ rlen = dev->readLine( cbuf, rlen+1 );
+ if ( rlen == -1 )
+ rlen = 0;
+ s += d->decoder->toUnicode( cbuf, rlen );
+ readBlock = FALSE;
+ }
+ if ( dev->atEnd()
+ || s.at( s.length()-1 ) == '\n'
+ || s.at( s.length()-1 ) == '\r'
+ ) {
+ break;
+ } else {
+ // get stream (and codec) in sync
+ int c;
+ c = dev_getch();
+ if ( c == EOF ) {
+ break;
+ }
+ char b = c;
+ uint lengthBefore = s.length();
+ s += d->decoder->toUnicode( &b, 1 );
+ if ( s.length() > lengthBefore )
+ break; // it seems we are in sync now
+ }
+ }
+ uint i = 0;
+ while( rnum < getline_buf_size && i < s.length() )
+ buf[rnum++] = s.constref(i++);
+ if ( s.length() > i )
+ // could be = but append is clearer
+ d->ungetcBuf.append( s.mid( i ) );
+ if ( rnum < getline_buf_size && dev->atEnd() )
+ buf[rnum++] = TQEOF;
+ } else
+#endif
+ if ( latin1 ) {
+ int rlen = getline_buf_size - rnum;
+ rlen = dev->readLine( cbuf, rlen+1 );
+ if ( rlen == -1 )
+ rlen = 0;
+ char *end = cbuf+rlen;
+ char *it = cbuf;
+ buf +=rnum;
+ while ( it != end ) {
+ buf->setCell( *(it++) );
+ buf->setRow( 0 );
+ buf++;
+ }
+ rnum += rlen;
+ if ( rnum < getline_buf_size && dev->atEnd() )
+ buf[1] = TQEOF;
+ }
+ return rnum;
+}
+
+
+/*!
+ Puts one character into the stream.
+*/
+void TQTextStream::ts_putc( TQChar c )
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( mapper ) {
+ if ( !d->encoder )
+ d->encoder = mapper->makeEncoder();
+ int len = 1;
+ TQString s = c;
+ TQCString block = d->encoder->fromUnicode( s, len );
+ dev->writeBlock( block, len );
+ } else
+#endif
+ if ( latin1 ) {
+ if ( c.row() )
+ dev->putch( '?' ); // unknown character
+ else
+ dev->putch( c.cell() );
+ } else {
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE;
+ ts_putc( TQChar::byteOrderMark );
+ }
+ if ( internalOrder ) {
+ // this case is needed by TQStringBuffer
+ dev->writeBlock( (char*)&c, sizeof(TQChar) );
+ } else if ( networkOrder ) {
+ dev->putch( c.row() );
+ dev->putch( c.cell() );
+ } else {
+ dev->putch( c.cell() );
+ dev->putch( c.row() );
+ }
+ }
+}
+
+/*!
+ Puts one character into the stream.
+*/
+void TQTextStream::ts_putc( int ch )
+{
+ ts_putc( TQChar((ushort)ch) );
+}
+
+bool TQTextStream::ts_isdigit( TQChar c )
+{
+ return c.isDigit();
+}
+
+bool TQTextStream::ts_isspace( TQChar c )
+{
+ return c.isSpace();
+}
+
+void TQTextStream::ts_ungetc( TQChar c )
+{
+ if ( c.tqunicode() == 0xffff )
+ return;
+
+ d->ungetcBuf.prepend( c );
+}
+
+
+
+/*!
+ Reads \a len bytes from the stream into \a s and returns a
+ reference to the stream.
+
+ The buffer \a s must be preallocated.
+
+ Note that no encoding is done by this function.
+
+ \warning The behavior of this function is undefined unless the
+ stream's encoding is set to Unicode or Latin1.
+
+ \sa TQIODevice::readBlock()
+*/
+
+TQTextStream &TQTextStream::readRawBytes( char *s, uint len )
+{
+ dev->readBlock( s, len );
+ return *this;
+}
+
+/*!
+ Writes the \a len bytes from \a s to the stream and returns a
+ reference to the stream.
+
+ Note that no encoding is done by this function.
+
+ \sa TQIODevice::writeBlock()
+*/
+
+TQTextStream &TQTextStream::writeRawBytes( const char* s, uint len )
+{
+ dev->writeBlock( s, len );
+ return *this;
+}
+
+
+TQTextStream &TQTextStream::writeBlock( const char* p, uint len )
+{
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE;
+ if ( !mapper && !latin1 )
+ ts_putc( TQChar::byteOrderMark );
+ }
+ // TQCString and const char * are treated as Latin-1
+ if ( !mapper && latin1 ) {
+ dev->writeBlock( p, len );
+ } else if ( !mapper && internalOrder ) {
+ TQChar *u = new TQChar[len];
+ for ( uint i = 0; i < len; i++ )
+ u[i] = p[i];
+ dev->writeBlock( (char*)u, len * sizeof(TQChar) );
+ delete [] u;
+ }
+#ifndef TQT_NO_TEXTCODEC
+ else if (mapper) {
+ if (!d->encoder)
+ d->encoder = mapper->makeEncoder();
+ TQString s = TQString::tqfromLatin1(p, len);
+ int l = len;
+ TQCString block = d->encoder->fromUnicode(s, l);
+ dev->writeBlock(block, l);
+ }
+#endif
+ else {
+ for ( uint i = 0; i < len; i++ )
+ ts_putc( (uchar)p[i] );
+ }
+ return *this;
+}
+
+TQTextStream &TQTextStream::writeBlock( const TQChar* p, uint len )
+{
+#ifndef TQT_NO_TEXTCODEC
+ if ( mapper ) {
+ if ( !d->encoder )
+ d->encoder = mapper->makeEncoder();
+ TQConstString s( p, len );
+ int l = len;
+ TQCString block = d->encoder->fromUnicode( s.string(), l );
+ dev->writeBlock( block, l );
+ } else
+#endif
+ if ( latin1 ) {
+ char *str = TQString::tqunicodeToLatin1( p, len );
+ dev->writeBlock( str, len );
+ delete [] str;
+ } else if ( internalOrder ) {
+ if ( doUnicodeHeader ) {
+ doUnicodeHeader = FALSE;
+ ts_putc( TQChar::byteOrderMark );
+ }
+ dev->writeBlock( (char*)p, sizeof(TQChar)*len );
+ } else {
+ for (uint i=0; i<len; i++)
+ ts_putc( p[i] );
+ }
+ return *this;
+}
+
+/*!
+ Resets the text stream.
+
+ \list
+ \i All flags are set to 0.
+ \i The field width is set to 0.
+ \i The fill character is set to ' ' (Space).
+ \i The precision is set to 6.
+ \endlist
+
+ \sa setf(), width(), fill(), precision()
+*/
+
+void TQTextStream::reset()
+{
+ fflags = 0;
+ fwidth = 0;
+ fillchar = ' ';
+ fprec = 6;
+}
+
+/*!
+ \fn TQIODevice *TQTextStream::tqdevice() const
+
+ Returns the IO tqdevice currently set.
+
+ \sa setDevice(), unsetDevice()
+*/
+
+/*!
+ Sets the IO tqdevice to \a iod.
+
+ \sa tqdevice(), unsetDevice()
+*/
+
+void TQTextStream::setDevice( TQIODevice *iod )
+{
+ if ( owndev ) {
+ delete dev;
+ owndev = FALSE;
+ }
+ dev = iod;
+ d->sourceType = TQTextStreamPrivate::IODevice;
+}
+
+/*!
+ Unsets the IO tqdevice. Equivalent to setDevice( 0 ).
+
+ \sa tqdevice(), setDevice()
+*/
+
+void TQTextStream::unsetDevice()
+{
+ setDevice( 0 );
+ d->sourceType = TQTextStreamPrivate::NotSet;
+}
+
+/*!
+ \fn bool TQTextStream::atEnd() const
+
+ Returns TRUE if the IO tqdevice has reached the end position (end of
+ the stream or file) or if there is no IO tqdevice set; otherwise
+ returns FALSE.
+
+ \sa TQIODevice::atEnd()
+*/
+
+/*!\fn bool TQTextStream::eof() const
+
+ \obsolete
+
+ This function has been renamed to atEnd().
+
+ \sa TQIODevice::atEnd()
+*/
+
+/*****************************************************************************
+ TQTextStream read functions
+ *****************************************************************************/
+
+
+/*!
+ \overload
+
+ Reads a char \a c from the stream and returns a reference to the
+ stream. Note that whitespace is skipped.
+*/
+
+TQTextStream &TQTextStream::operator>>( char &c )
+{
+ CHECK_STREAM_PRECOND
+ c = eat_ws();
+ return *this;
+}
+
+/*!
+ Reads a char \a c from the stream and returns a reference to the
+ stream. Note that whitespace is \e not skipped.
+*/
+
+TQTextStream &TQTextStream::operator>>( TQChar &c )
+{
+ CHECK_STREAM_PRECOND
+ c = ts_getc();
+ return *this;
+}
+
+
+ulong TQTextStream::input_bin()
+{
+ ulong val = 0;
+ TQChar ch = eat_ws();
+ int dv = ch.digitValue();
+ while ( dv == 0 || dv == 1 ) {
+ val = ( val << 1 ) + dv;
+ ch = ts_getc();
+ dv = ch.digitValue();
+ }
+ if ( ch != TQEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+ulong TQTextStream::input_oct()
+{
+ ulong val = 0;
+ TQChar ch = eat_ws();
+ int dv = ch.digitValue();
+ while ( dv >= 0 && dv <= 7 ) {
+ val = ( val << 3 ) + dv;
+ ch = ts_getc();
+ dv = ch.digitValue();
+ }
+ if ( dv == 8 || dv == 9 ) {
+ while ( ts_isdigit(ch) )
+ ch = ts_getc();
+ }
+ if ( ch != TQEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+ulong TQTextStream::input_dec()
+{
+ ulong val = 0;
+ TQChar ch = eat_ws();
+ int dv = ch.digitValue();
+ while ( ts_isdigit(ch) ) {
+ val = val * 10 + dv;
+ ch = ts_getc();
+ dv = ch.digitValue();
+ }
+ if ( ch != TQEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+ulong TQTextStream::input_hex()
+{
+ ulong val = 0;
+ TQChar ch = eat_ws();
+ char c = ch;
+ while ( isxdigit((uchar) c) ) {
+ val <<= 4;
+ if ( ts_isdigit(c) )
+ val += c - '0';
+ else
+ val += 10 + tolower( (uchar) c ) - 'a';
+ c = ch = ts_getc();
+ }
+ if ( ch != TQEOF )
+ ts_ungetc( ch );
+ return val;
+}
+
+long TQTextStream::input_int()
+{
+ long val;
+ TQChar ch;
+ char c;
+ switch ( flags() & basefield ) {
+ case bin:
+ val = (long)input_bin();
+ break;
+ case oct:
+ val = (long)input_oct();
+ break;
+ case dec:
+ c = ch = eat_ws();
+ if ( ch == TQEOF ) {
+ val = 0;
+ } else {
+ if ( !(c == '-' || c == '+') )
+ ts_ungetc( ch );
+ if ( c == '-' ) {
+ ulong v = input_dec();
+ if ( v ) { // ensure that LONG_MIN can be read
+ v--;
+ val = -((long)v) - 1;
+ } else {
+ val = 0;
+ }
+ } else {
+ val = (long)input_dec();
+ }
+ }
+ break;
+ case hex:
+ val = (long)input_hex();
+ break;
+ default:
+ val = 0;
+ c = ch = eat_ws();
+ if ( c == '0' ) { // bin, oct or hex
+ c = ch = ts_getc();
+ if ( tolower((uchar) c) == 'x' )
+ val = (long)input_hex();
+ else if ( tolower((uchar) c) == 'b' )
+ val = (long)input_bin();
+ else { // octal
+ ts_ungetc( ch );
+ if ( c >= '0' && c <= '7' ) {
+ val = (long)input_oct();
+ } else {
+ val = 0;
+ }
+ }
+ } else if ( ts_isdigit(ch) ) {
+ ts_ungetc( ch );
+ val = (long)input_dec();
+ } else if ( c == '-' || c == '+' ) {
+ ulong v = input_dec();
+ if ( c == '-' ) {
+ if ( v ) { // ensure that LONG_MIN can be read
+ v--;
+ val = -((long)v) - 1;
+ } else {
+ val = 0;
+ }
+ } else {
+ val = (long)v;
+ }
+ }
+ }
+ return val;
+}
+
+//
+// We use a table-driven FSM to parse floating point numbers
+// strtod() cannot be used directly since we're reading from a TQIODevice
+//
+
+double TQTextStream::input_double()
+{
+ const int Init = 0; // states
+ const int Sign = 1;
+ const int Mantissa = 2;
+ const int Dot = 3;
+ const int Abscissa = 4;
+ const int ExpMark = 5;
+ const int ExpSign = 6;
+ const int Exponent = 7;
+ const int Done = 8;
+
+ const int InputSign = 1; // input tokens
+ const int InputDigit = 2;
+ const int InputDot = 3;
+ const int InputExp = 4;
+
+ static const uchar table[8][5] = {
+ /* None InputSign InputDigit InputDot InputExp */
+ { 0, Sign, Mantissa, Dot, 0, }, // Init
+ { 0, 0, Mantissa, Dot, 0, }, // Sign
+ { Done, Done, Mantissa, Dot, ExpMark,}, // Mantissa
+ { 0, 0, Abscissa, 0, 0, }, // Dot
+ { Done, Done, Abscissa, Done, ExpMark,}, // Abscissa
+ { 0, ExpSign, Exponent, 0, 0, }, // ExpMark
+ { 0, 0, Exponent, 0, 0, }, // ExpSign
+ { Done, Done, Exponent, Done, Done } // Exponent
+ };
+
+ int state = Init; // parse state
+ int input; // input token
+
+ char buf[256];
+ int i = 0;
+ TQChar c = eat_ws();
+
+ for (;;) {
+
+ switch ( c ) {
+ case '+':
+ case '-':
+ input = InputSign;
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ input = InputDigit;
+ break;
+ case '.':
+ input = InputDot;
+ break;
+ case 'e':
+ case 'E':
+ input = InputExp;
+ break;
+ default:
+ input = 0;
+ break;
+ }
+
+ state = table[state][input];
+
+ if ( state == 0 || state == Done || i > 250 ) {
+ if ( i > 250 ) { // ignore rest of digits
+ do { c = ts_getc(); } while ( c != TQEOF && ts_isdigit(c) );
+ }
+ if ( c != TQEOF )
+ ts_ungetc( c );
+ buf[i] = '\0';
+ char *end;
+ return strtod( buf, &end );
+ }
+
+ buf[i++] = c;
+ c = ts_getc();
+ }
+
+#if !defined(TQ_CC_EDG)
+ return 0.0;
+#endif
+}
+
+
+/*!
+ \overload
+
+ Reads a signed \c short integer \a i from the stream and returns a
+ reference to the stream. See flags() for an explanation of the
+ expected input format.
+*/
+
+TQTextStream &TQTextStream::operator>>( signed short &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (signed short)input_int();
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Reads an unsigned \c short integer \a i from the stream and
+ returns a reference to the stream. See flags() for an explanation
+ of the expected input format.
+*/
+
+TQTextStream &TQTextStream::operator>>( unsigned short &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (unsigned short)input_int();
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Reads a signed \c int \a i from the stream and returns a reference
+ to the stream. See flags() for an explanation of the expected
+ input format.
+*/
+
+TQTextStream &TQTextStream::operator>>( signed int &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (signed int)input_int();
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Reads an unsigned \c int \a i from the stream and returns a
+ reference to the stream. See flags() for an explanation of the
+ expected input format.
+*/
+
+TQTextStream &TQTextStream::operator>>( unsigned int &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (unsigned int)input_int();
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Reads a signed \c long int \a i from the stream and returns a
+ reference to the stream. See flags() for an explanation of the
+ expected input format.
+*/
+
+TQTextStream &TQTextStream::operator>>( signed long &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (signed long)input_int();
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Reads an unsigned \c long int \a i from the stream and returns a
+ reference to the stream. See flags() for an explanation of the
+ expected input format.
+*/
+
+TQTextStream &TQTextStream::operator>>( unsigned long &i )
+{
+ CHECK_STREAM_PRECOND
+ i = (unsigned long)input_int();
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Reads a \c float \a f from the stream and returns a reference to
+ the stream. See flags() for an explanation of the expected input
+ format.
+*/
+
+TQTextStream &TQTextStream::operator>>( float &f )
+{
+ CHECK_STREAM_PRECOND
+ f = (float)input_double();
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Reads a \c double \a f from the stream and returns a reference to
+ the stream. See flags() for an explanation of the expected input
+ format.
+*/
+
+TQTextStream &TQTextStream::operator>>( double &f )
+{
+ CHECK_STREAM_PRECOND
+ f = input_double();
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Reads a "word" from the stream into \a s and returns a reference
+ to the stream.
+
+ A word consists of characters for which isspace() returns FALSE.
+*/
+
+TQTextStream &TQTextStream::operator>>( char *s )
+{
+ CHECK_STREAM_PRECOND
+ int maxlen = width( 0 );
+ TQChar c = eat_ws();
+ if ( !maxlen )
+ maxlen = -1;
+ while ( c != TQEOF ) {
+ if ( ts_isspace(c) || maxlen-- == 0 ) {
+ ts_ungetc( c );
+ break;
+ }
+ *s++ = c;
+ c = ts_getc();
+ }
+
+ *s = '\0';
+ return *this;
+}
+
+/*!
+ \overload
+
+ Reads a "word" from the stream into \a str and returns a reference
+ to the stream.
+
+ A word consists of characters for which isspace() returns FALSE.
+*/
+
+TQTextStream &TQTextStream::operator>>( TQString &str )
+{
+ CHECK_STREAM_PRECOND
+ str=TQString::tqfromLatin1("");
+ TQChar c = eat_ws();
+
+ while ( c != TQEOF ) {
+ if ( ts_isspace(c) ) {
+ ts_ungetc( c );
+ break;
+ }
+ str += c;
+ c = ts_getc();
+ }
+ return *this;
+}
+
+/*!
+ \overload
+
+ Reads a "word" from the stream into \a str and returns a reference
+ to the stream.
+
+ A word consists of characters for which isspace() returns FALSE.
+*/
+
+TQTextStream &TQTextStream::operator>>( TQCString &str )
+{
+ CHECK_STREAM_PRECOND
+ TQCString *dynbuf = 0;
+ const int buflen = 256;
+ char buffer[buflen];
+ char *s = buffer;
+ int i = 0;
+ TQChar c = eat_ws();
+
+ while ( c != TQEOF ) {
+ if ( ts_isspace(c) ) {
+ ts_ungetc( c );
+ break;
+ }
+ if ( i >= buflen-1 ) {
+ if ( !dynbuf ) { // create dynamic buffer
+ dynbuf = new TQCString(buflen*2);
+ memcpy( dynbuf->data(), s, i ); // copy old data
+ } else if ( i >= (int)dynbuf->size()-1 ) {
+ dynbuf->resize( dynbuf->size()*2 );
+ }
+ s = dynbuf->data();
+ }
+ s[i++] = c;
+ c = ts_getc();
+ }
+ str.resize( i+1 );
+ memcpy( str.data(), s, i );
+ delete dynbuf;
+ return *this;
+}
+
+
+/*!
+ Reads a line from the stream and returns a string containing the
+ text.
+
+ The returned string does not contain any trailing newline or
+ carriage return. Note that this is different from
+ TQIODevice::readLine(), which does not strip the newline at the end
+ of the line.
+
+ On EOF you will get a TQString that is null. On reading an empty
+ line the returned TQString is empty but not null.
+
+ \sa TQIODevice::readLine()
+*/
+
+TQString TQTextStream::readLine()
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !dev ) {
+ qWarning( "TQTextStream::readLine: No tqdevice" );
+ return TQString::null;
+ }
+#endif
+ bool readCharByChar = TRUE;
+ TQString result;
+#if 0
+ if ( !doUnicodeHeader && (
+ (latin1) ||
+ (mapper != 0 && mapper->mibEnum() == 106 ) // UTF 8
+ ) ) {
+ readCharByChar = FALSE;
+ // use optimized read line
+ TQChar c[getline_buf_size];
+ int pos = 0;
+ bool eof = FALSE;
+
+ for (;;) {
+ pos = ts_getline( c );
+ if ( pos == 0 ) {
+ // something went wrong; try fallback
+ readCharByChar = TRUE;
+ //dev->resetqStatus();
+ break;
+ }
+ if ( c[pos-1] == TQEOF || c[pos-1] == '\n' ) {
+ if ( pos>2 && c[pos-1]==TQEOF && c[pos-2]=='\n' ) {
+ result += TQString( c, pos-2 );
+ } else if ( pos > 1 ) {
+ result += TQString( c, pos-1 );
+ }
+ if ( pos == 1 && c[pos-1] == TQEOF )
+ eof = TRUE;
+ break;
+ } else {
+ result += TQString( c, pos );
+ }
+ }
+ if ( eof && result.isEmpty() )
+ return TQString::null;
+ }
+#endif
+ if ( readCharByChar ) {
+ const int buf_size = 256;
+ TQChar c[buf_size];
+ int pos = 0;
+
+ c[pos] = ts_getc();
+ if ( c[pos] == TQEOF )
+ return TQString::null;
+
+ while ( c[pos] != TQEOF && c[pos] != '\n' ) {
+ if ( c[pos] == '\r' ) { // ( handle mac and dos )
+ TQChar nextc = ts_getc();
+ if ( nextc != '\n' )
+ ts_ungetc( nextc );
+ break;
+ }
+ pos++;
+ if ( pos >= buf_size ) {
+ result += TQString( c, pos );
+ pos = 0;
+ }
+ c[pos] = ts_getc();
+ }
+ result += TQString( c, pos );
+ }
+
+ return result;
+}
+
+
+/*!
+ Reads the entire stream from the current position, and returns a string
+ containing the text.
+
+ \sa TQIODevice::readLine()
+*/
+
+TQString TQTextStream::read()
+{
+#if defined(TQT_CHECK_STATE)
+ if ( !dev ) {
+ qWarning( "TQTextStream::read: No tqdevice" );
+ return TQString::null;
+ }
+#endif
+ TQString result;
+ const uint bufsize = 512;
+ TQChar buf[bufsize];
+ uint i, num, start;
+ bool skipped_cr = FALSE;
+
+ for (;;) {
+ num = ts_getbuf(buf,bufsize);
+ // convert dos (\r\n) and mac (\r) style eol to unix style (\n)
+ start = 0;
+ for ( i=0; i<num; i++ ) {
+ if ( buf[i] == '\r' ) {
+ // Only skip single cr's preceding lf's
+ if ( skipped_cr ) {
+ result += buf[i];
+ start++;
+ } else {
+ result += TQString( &buf[start], i-start );
+ start = i+1;
+ skipped_cr = TRUE;
+ }
+ } else {
+ if ( skipped_cr ) {
+ if ( buf[i] != '\n' ) {
+ // Should not have skipped it
+ result += '\n';
+ }
+ skipped_cr = FALSE;
+ }
+ }
+ }
+ if ( start < num )
+ result += TQString( &buf[start], i-start );
+ if ( num != bufsize ) // if ( EOF )
+ break;
+ }
+ return result;
+}
+
+
+
+/*****************************************************************************
+ TQTextStream write functions
+ *****************************************************************************/
+
+/*!
+ Writes character \c char to the stream and returns a reference to
+ the stream.
+
+ The character \a c is assumed to be Latin1 encoded independent of
+ the Encoding set for the TQTextStream.
+*/
+TQTextStream &TQTextStream::operator<<( TQChar c )
+{
+ CHECK_STREAM_PRECOND
+ ts_putc( c );
+ return *this;
+}
+
+/*!
+ \overload
+
+ Writes character \a c to the stream and returns a reference to the
+ stream.
+*/
+TQTextStream &TQTextStream::operator<<( char c )
+{
+ CHECK_STREAM_PRECOND
+ unsigned char uc = (unsigned char) c;
+ ts_putc( uc );
+ return *this;
+}
+
+TQTextStream &TQTextStream::output_int( int format, ulong n, bool neg )
+{
+ static const char hexdigits_lower[] = "0123456789abcdef";
+ static const char hexdigits_upper[] = "0123456789ABCDEF";
+ CHECK_STREAM_PRECOND
+ char buf[76];
+ register char *p;
+ int len;
+ const char *hexdigits;
+
+ switch ( flags() & I_BASE_MASK ) {
+
+ case I_BASE_2: // output binary number
+ switch ( format & I_TYPE_MASK ) {
+ case I_SHORT: len=16; break;
+ case I_INT: len=sizeof(int)*8; break;
+ case I_LONG: len=32; break;
+ default: len = 0;
+ }
+ p = &buf[74]; // go reverse order
+ *p = '\0';
+ while ( len-- ) {
+ *--p = (char)(n&1) + '0';
+ n >>= 1;
+ if ( !n )
+ break;
+ }
+ if ( flags() & showbase ) { // show base
+ *--p = (flags() & uppercase) ? 'B' : 'b';
+ *--p = '0';
+ }
+ break;
+
+ case I_BASE_8: // output octal number
+ p = &buf[74];
+ *p = '\0';
+ do {
+ *--p = (char)(n&7) + '0';
+ n >>= 3;
+ } while ( n );
+ if ( flags() & showbase )
+ *--p = '0';
+ break;
+
+ case I_BASE_16: // output hexadecimal number
+ p = &buf[74];
+ *p = '\0';
+ hexdigits = (flags() & uppercase) ?
+ hexdigits_upper : hexdigits_lower;
+ do {
+ *--p = hexdigits[(int)n&0xf];
+ n >>= 4;
+ } while ( n );
+ if ( flags() & showbase ) {
+ *--p = (flags() & uppercase) ? 'X' : 'x';
+ *--p = '0';
+ }
+ break;
+
+ default: // decimal base is default
+ p = &buf[74];
+ *p = '\0';
+ if ( neg )
+ n = (ulong)(-(long)n);
+ do {
+ *--p = ((int)(n%10)) + '0';
+ n /= 10;
+ } while ( n );
+ if ( neg )
+ *--p = '-';
+ else if ( flags() & showpos )
+ *--p = '+';
+ if ( (flags() & internal) && fwidth && !ts_isdigit(*p) ) {
+ ts_putc( *p ); // special case for internal
+ ++p; // padding
+ fwidth--;
+ return *this << (const char*)p;
+ }
+ }
+ if ( fwidth ) { // adjustment required
+ if ( !(flags() & left) ) { // but NOT left adjustment
+ len = tqstrlen(p);
+ int padlen = fwidth - len;
+ if ( padlen <= 0 ) { // no padding required
+ writeBlock( p, len );
+ } else if ( padlen < (int)(p-buf) ) { // speeds up padding
+ memset( p-padlen, (char)fillchar, padlen );
+ writeBlock( p-padlen, padlen+len );
+ }
+ else // standard padding
+ *this << (const char*)p;
+ }
+ else
+ *this << (const char*)p;
+ fwidth = 0; // reset field width
+ }
+ else
+ writeBlock( p, tqstrlen(p) );
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Writes a \c short integer \a i to the stream and returns a
+ reference to the stream.
+*/
+
+TQTextStream &TQTextStream::operator<<( signed short i )
+{
+ return output_int( I_SHORT | I_SIGNED, i, i < 0 );
+}
+
+
+/*!
+ \overload
+
+ Writes an \c unsigned \c short integer \a i to the stream and
+ returns a reference to the stream.
+*/
+
+TQTextStream &TQTextStream::operator<<( unsigned short i )
+{
+ return output_int( I_SHORT | I_UNSIGNED, i, FALSE );
+}
+
+
+/*!
+ \overload
+
+ Writes an \c int \a i to the stream and returns a reference to the
+ stream.
+*/
+
+TQTextStream &TQTextStream::operator<<( signed int i )
+{
+ return output_int( I_INT | I_SIGNED, i, i < 0 );
+}
+
+
+/*!
+ \overload
+
+ Writes an \c unsigned \c int \a i to the stream and returns a
+ reference to the stream.
+*/
+
+TQTextStream &TQTextStream::operator<<( unsigned int i )
+{
+ return output_int( I_INT | I_UNSIGNED, i, FALSE );
+}
+
+
+/*!
+ \overload
+
+ Writes a \c long \c int \a i to the stream and returns a reference
+ to the stream.
+*/
+
+TQTextStream &TQTextStream::operator<<( signed long i )
+{
+ return output_int( I_LONG | I_SIGNED, i, i < 0 );
+}
+
+
+/*!
+ \overload
+
+ Writes an \c unsigned \c long \c int \a i to the stream and
+ returns a reference to the stream.
+*/
+
+TQTextStream &TQTextStream::operator<<( unsigned long i )
+{
+ return output_int( I_LONG | I_UNSIGNED, i, FALSE );
+}
+
+
+/*!
+ \overload
+
+ Writes a \c float \a f to the stream and returns a reference to
+ the stream.
+*/
+
+TQTextStream &TQTextStream::operator<<( float f )
+{
+ return *this << (double)f;
+}
+
+/*!
+ \overload
+
+ Writes a \c double \a f to the stream and returns a reference to
+ the stream.
+*/
+
+TQTextStream &TQTextStream::operator<<( double f )
+{
+ CHECK_STREAM_PRECOND
+ char f_char;
+ char format[16];
+ if ( (flags()&floatfield) == fixed )
+ f_char = 'f';
+ else if ( (flags()&floatfield) == scientific )
+ f_char = (flags() & uppercase) ? 'E' : 'e';
+ else
+ f_char = (flags() & uppercase) ? 'G' : 'g';
+ register char *fs = format; // generate format string
+ *fs++ = '%'; // "%.<prec>l<f_char>"
+ *fs++ = '.';
+ int prec = precision();
+ if ( prec > 99 )
+ prec = 99;
+ if ( prec >= 10 ) {
+ *fs++ = prec / 10 + '0';
+ *fs++ = prec % 10 + '0';
+ } else {
+ *fs++ = prec + '0';
+ }
+ *fs++ = 'l';
+ *fs++ = f_char;
+ *fs = '\0';
+ TQString num;
+ num.sprintf(format, f); // convert to text
+ if ( fwidth ) // padding
+ *this << num.latin1();
+ else // just write it
+ writeBlock(num.latin1(), num.length());
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Writes a string to the stream and returns a reference to the
+ stream.
+
+ The string \a s is assumed to be Latin1 encoded independent of the
+ Encoding set for the TQTextStream.
+*/
+
+TQTextStream &TQTextStream::operator<<( const char* s )
+{
+ CHECK_STREAM_PRECOND
+ char padbuf[48];
+ uint len = tqstrlen( s ); // don't write null terminator
+ if ( fwidth ) { // field width set
+ int padlen = fwidth - len;
+ fwidth = 0; // reset width
+ if ( padlen > 0 ) {
+ char *ppad;
+ if ( padlen > 46 ) { // create extra big fill buffer
+ ppad = new char[padlen];
+ TQ_CHECK_PTR( ppad );
+ } else {
+ ppad = padbuf;
+ }
+ memset( ppad, (char)fillchar, padlen ); // fill with fillchar
+ if ( !(flags() & left) ) {
+ writeBlock( ppad, padlen );
+ padlen = 0;
+ }
+ writeBlock( s, len );
+ if ( padlen )
+ writeBlock( ppad, padlen );
+ if ( ppad != padbuf ) // delete extra big fill buf
+ delete[] ppad;
+ return *this;
+ }
+ }
+ writeBlock( s, len );
+ return *this;
+}
+
+/*!
+ \overload
+
+ Writes \a s to the stream and returns a reference to the stream.
+
+ The string \a s is assumed to be Latin1 encoded independent of the
+ Encoding set for the TQTextStream.
+*/
+
+TQTextStream &TQTextStream::operator<<( const TQCString & s )
+{
+ return operator<<(s.data());
+}
+
+/*!
+ \overload
+
+ Writes \a s to the stream and returns a reference to the stream.
+*/
+
+TQTextStream &TQTextStream::operator<<( const TQString& s )
+{
+ if ( !mapper && latin1 )
+ return operator<<(s.latin1());
+ CHECK_STREAM_PRECOND
+ TQString s1 = s;
+ if ( fwidth ) { // field width set
+ if ( !(flags() & left) ) {
+ s1 = s.rightJustify(fwidth, (char)fillchar);
+ } else {
+ s1 = s.leftJustify(fwidth, (char)fillchar);
+ }
+ fwidth = 0; // reset width
+ }
+ writeBlock( s1.tqunicode(), s1.length() );
+ return *this;
+}
+
+
+/*!
+ \overload
+
+ Writes a pointer to the stream and returns a reference to the
+ stream.
+
+ The \a ptr is output as an unsigned long hexadecimal integer.
+*/
+
+TQTextStream &TQTextStream::operator<<( void *ptr )
+{
+ int f = flags();
+ setf( hex, basefield );
+ setf( showbase );
+ unsetf( uppercase );
+ output_int( I_LONG | I_UNSIGNED, (ulong)ptr, FALSE );
+ flags( f );
+ return *this;
+}
+
+
+/*!
+ \fn int TQTextStream::flags() const
+
+ Returns the current stream flags. The default value is 0.
+
+ \table
+ \header \i Flag \i Meaning
+ \row \i \c skipws \i Not currently used; whitespace always skipped
+ \row \i \c left \i Numeric fields are left-aligned
+ \row \i \c right
+ \i Not currently used (by default, numerics are right-aligned)
+ \row \i \c internal \i Puts any padding spaces between +/- and value
+ \row \i \c bin \i Output \e and input only in binary
+ \row \i \c oct \i Output \e and input only in octal
+ \row \i \c dec \i Output \e and input only in decimal
+ \row \i \c hex \i Output \e and input only in hexadecimal
+ \row \i \c showbase
+ \i Annotates numeric outputs with 0b, 0, or 0x if in \c bin,
+ \c oct, or \c hex format
+ \row \i \c showpoint \i Not currently used
+ \row \i \c uppercase \i Uses 0B and 0X rather than 0b and 0x
+ \row \i \c showpos \i Shows + for positive numeric values
+ \row \i \c scientific \i Uses scientific notation for floating point values
+ \row \i \c fixed \i Uses fixed-point notation for floating point values
+ \endtable
+
+ Note that unless \c bin, \c oct, \c dec, or \c hex is set, the
+ input base is octal if the value starts with 0, hexadecimal if it
+ starts with 0x, binary if it starts with 0b, and decimal
+ otherwise.
+
+ \sa setf(), unsetf()
+*/
+
+/*!
+ \fn int TQTextStream::flags( int f )
+
+ \overload
+
+ Sets the stream flags to \a f. Returns the previous stream flags.
+
+ \sa setf(), unsetf(), flags()
+*/
+
+/*!
+ \fn int TQTextStream::setf( int bits )
+
+ Sets the stream flag bits \a bits. Returns the previous stream
+ flags.
+
+ Equivalent to \c{flags( flags() | bits )}.
+
+ \sa setf(), unsetf()
+*/
+
+/*!
+ \fn int TQTextStream::setf( int bits, int tqmask )
+
+ \overload
+
+ Sets the stream flag bits \a bits with a bit tqmask \a tqmask. Returns
+ the previous stream flags.
+
+ Equivalent to \c{flags( (flags() & ~tqmask) | (bits & tqmask) )}.
+
+ \sa setf(), unsetf()
+*/
+
+/*!
+ \fn int TQTextStream::unsetf( int bits )
+
+ Clears the stream flag bits \a bits. Returns the previous stream
+ flags.
+
+ Equivalent to \c{flags( flags() & ~tqmask )}.
+
+ \sa setf()
+*/
+
+/*!
+ \fn int TQTextStream::width() const
+
+ Returns the field width. The default value is 0.
+*/
+
+/*!
+ \fn int TQTextStream::width( int w )
+
+ \overload
+
+ Sets the field width to \a w. Returns the previous field width.
+*/
+
+/*!
+ \fn int TQTextStream::fill() const
+
+ Returns the fill character. The default value is ' ' (space).
+*/
+
+/*!
+ \overload int TQTextStream::fill( int f )
+
+ Sets the fill character to \a f. Returns the previous fill character.
+*/
+
+/*!
+ \fn int TQTextStream::precision() const
+
+ Returns the precision. The default value is 6.
+*/
+
+/*!
+ \fn int TQTextStream::precision( int p )
+
+ \overload
+
+ Sets the precision to \a p. Returns the previous precision setting.
+*/
+
+
+ /*****************************************************************************
+ TQTextStream manipulators
+ *****************************************************************************/
+
+TQTextStream &bin( TQTextStream &s )
+{
+ s.setf(TQTS::bin,TQTS::basefield);
+ return s;
+}
+
+TQTextStream &oct( TQTextStream &s )
+{
+ s.setf(TQTS::oct,TQTS::basefield);
+ return s;
+}
+
+TQTextStream &dec( TQTextStream &s )
+{
+ s.setf(TQTS::dec,TQTS::basefield);
+ return s;
+}
+
+TQTextStream &hex( TQTextStream &s )
+{
+ s.setf(TQTS::hex,TQTS::basefield);
+ return s;
+}
+
+TQTextStream &endl( TQTextStream &s )
+{
+ return s << '\n';
+}
+
+TQTextStream &flush( TQTextStream &s )
+{
+ if ( s.tqdevice() )
+ s.tqdevice()->flush();
+ return s;
+}
+
+TQTextStream &ws( TQTextStream &s )
+{
+ s.skipWhiteSpace();
+ return s;
+}
+
+TQTextStream &reset( TQTextStream &s )
+{
+ s.reset();
+ return s;
+}
+
+
+/*!
+ \class TQTextIStream tqtextstream.h
+ \reentrant
+ \brief The TQTextIStream class is a convenience class for input streams.
+
+ \ingroup io
+ \ingroup text
+
+ This class provides a shorthand for creating simple input
+ \l{TQTextStream}s without having to pass a \e mode argument to the
+ constructor.
+
+ This class makes it easy, for example, to write things like this:
+ \code
+ TQString data = "123 456";
+ int a, b;
+ TQTextIStream(&data) >> a >> b;
+ \endcode
+
+ \sa TQTextOStream
+*/
+
+/*!
+ \fn TQTextIStream::TQTextIStream( const TQString *s )
+
+ Constructs a stream to read from the string \a s.
+*/
+/*!
+ \fn TQTextIStream::TQTextIStream( TQByteArray ba )
+
+ Constructs a stream to read from the array \a ba.
+*/
+/*!
+ \fn TQTextIStream::TQTextIStream( FILE *f )
+
+ Constructs a stream to read from the file \a f.
+*/
+
+
+/*!
+ \class TQTextOStream
+ \reentrant
+ \brief The TQTextOStream class is a convenience class for output streams.
+
+ \ingroup io
+ \ingroup text
+
+ This class provides a shorthand for creating simple output
+ \l{TQTextStream}s without having to pass a \e mode argument to the
+ constructor.
+
+ This makes it easy for example, to write things like this:
+ \code
+ TQString result;
+ TQTextOStream(&result) << "pi = " << 3.14;
+ \endcode
+*/
+
+/*!
+ \fn TQTextOStream::TQTextOStream( TQString *s )
+
+ Constructs a stream to write to string \a s.
+*/
+/*!
+ \fn TQTextOStream::TQTextOStream( TQByteArray ba )
+
+ Constructs a stream to write to the array \a ba.
+*/
+/*!
+ \fn TQTextOStream::TQTextOStream( FILE *f )
+
+ Constructs a stream to write to the file \a f.
+*/
+
+
+
+/*!
+ Sets the encoding of this stream to \a e, where \a e is one of the
+ following values:
+ \table
+ \header \i Encoding \i Meaning
+ \row \i Locale
+ \i Uses local file format (Latin1 if locale is not set), but
+ autodetecting Unicode(utf16) on input.
+ \row \i Unicode
+ \i Uses Unicode(utf16) for input and output. Output will be
+ written in the order most efficient for the current platform
+ (i.e. the order used internally in TQString).
+ \row \i UnicodeUTF8
+ \i Using Unicode(utf8) for input and output. If you use it for
+ input it will autodetect utf16 and use it instead of utf8.
+ \row \i Latin1
+ \i ISO-8859-1. Will not autodetect utf16.
+ \row \i UnicodeNetworkOrder
+ \i Uses network order Unicode(utf16) for input and output.
+ Useful when reading Unicode data that does not start with the
+ byte order marker.
+ \row \i UnicodeReverse
+ \i Uses reverse network order Unicode(utf16) for input and
+ output. Useful when reading Unicode data that does not start
+ with the byte order marker or when writing data that should be
+ read by buggy Windows applications.
+ \row \i RawUnicode
+ \i Like Unicode, but does not write the byte order marker nor
+ does it auto-detect the byte order. Useful only when writing to
+ non-persistent storage used by a single process.
+ \endtable
+
+ \c Locale and all Unicode encodings, except \c RawUnicode, will look
+ at the first two bytes in an input stream to determine the byte
+ order. The initial byte order marker will be stripped off before
+ data is read.
+
+ Note that this function should be called before any data is read to
+ or written from the stream.
+
+ \sa setCodec()
+*/
+
+void TQTextStream::setEncoding( Encoding e )
+{
+ if ( d->sourceType == TQTextStreamPrivate::String )
+ return;
+
+ switch ( e ) {
+ case Unicode:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = TRUE;
+ networkOrder = TQChar::networkOrdered();
+ break;
+ case UnicodeUTF8:
+#ifndef TQT_NO_TEXTCODEC
+ mapper = TQTextCodec::codecForMib( 106 );
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = TRUE;
+ networkOrder = TQChar::networkOrdered();
+#else
+ mapper = 0;
+ latin1 = TRUE;
+ doUnicodeHeader = TRUE;
+#endif
+ break;
+ case UnicodeNetworkOrder:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = TQChar::networkOrdered();
+ networkOrder = TRUE;
+ break;
+ case UnicodeReverse:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = TRUE;
+ internalOrder = !TQChar::networkOrdered();
+ networkOrder = FALSE;
+ break;
+ case RawUnicode:
+ mapper = 0;
+ latin1 = FALSE;
+ doUnicodeHeader = FALSE;
+ internalOrder = TRUE;
+ networkOrder = TQChar::networkOrdered();
+ break;
+ case Locale:
+ latin1 = TRUE; // fallback to Latin-1
+#ifndef TQT_NO_TEXTCODEC
+ mapper = TQTextCodec::codecForLocale();
+ // optimized Latin-1 processing
+#if defined(TQ_OS_WIN32)
+ if ( GetACP() == 1252 )
+ mapper = 0;
+#endif
+ if ( mapper && mapper->mibEnum() == 4 )
+#endif
+ mapper = 0;
+
+ doUnicodeHeader = TRUE; // If it reads as Unicode, accept it
+ break;
+ case Latin1:
+ mapper = 0;
+ doUnicodeHeader = FALSE;
+ latin1 = TRUE;
+ break;
+ }
+}
+
+
+#ifndef TQT_NO_TEXTCODEC
+/*!
+ Sets the codec for this stream to \a codec. Will not try to
+ autodetect Unicode.
+
+ Note that this function should be called before any data is read
+ to/written from the stream.
+
+ \sa setEncoding(), codec()
+*/
+
+void TQTextStream::setCodec( TQTextCodec *codec )
+{
+ if ( d->sourceType == TQTextStreamPrivate::String )
+ return; // TQString does not need any codec
+ mapper = codec;
+ latin1 = ( codec->mibEnum() == 4 );
+ if ( latin1 )
+ mapper = 0;
+ doUnicodeHeader = FALSE;
+}
+
+/*!
+ Returns the codec actually used for this stream.
+
+ If Unicode is automatically detected in input, a codec with \link
+ TQTextCodec::name() name() \endlink "ISO-10646-UCS-2" is returned.
+
+ \sa setCodec()
+*/
+
+TQTextCodec *TQTextStream::codec()
+{
+ if ( mapper ) {
+ return mapper;
+ } else {
+ // 4 is "ISO 8859-1", 1000 is "ISO-10646-UCS-2"
+ return TQTextCodec::codecForMib( latin1 ? 4 : 1000 );
+ }
+}
+
+#endif
+
+#endif // TQT_NO_TEXTSTREAM
diff --git a/tqtinterface/qt4/src/tools/tqtextstream.h b/tqtinterface/qt4/src/tools/tqtextstream.h
new file mode 100644
index 0000000..53aaddb
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqtextstream.h
@@ -0,0 +1,343 @@
+/****************************************************************************
+**
+** Definition of TQTextStream class
+**
+** Created : 940922
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTEXTSTREAM_H
+#define TQTEXTSTREAM_H
+
+#ifndef TQT_H
+#include "tqiodevice.h"
+#include "tqfile.h"
+#include "tqstring.h"
+#include <stdio.h>
+#endif // TQT_H
+
+#ifndef TQT_NO_TEXTSTREAM
+class TQTextCodec;
+class TQTextDecoder;
+
+class TQTextStreamPrivate;
+
+class TQ_EXPORT TQTextStream // text stream class
+{
+public:
+ enum Encoding { Locale, Latin1, Unicode, UnicodeNetworkOrder,
+ UnicodeReverse, RawUnicode, UnicodeUTF8 };
+
+ void setEncoding( Encoding );
+#ifndef TQT_NO_TEXTCODEC
+ void setCodec( TQTextCodec* );
+ TQTextCodec *codec();
+#endif
+
+ TQTextStream();
+ TQTextStream( QIODevice * );
+ TQTextStream( QFile *tqf );
+ TQTextStream( TQString*, int mode );
+ TQTextStream( TQString&, int mode ); // obsolete
+ TQTextStream( TQByteArray, int mode );
+ TQTextStream( FILE *, int mode );
+ virtual ~TQTextStream();
+
+ TQIODevice *tqdevice() const;
+ void setDevice( TQIODevice * );
+ void unsetDevice();
+
+ bool atEnd() const;
+ bool eof() const;
+
+ TQTextStream &operator>>( TQChar & );
+ TQTextStream &operator>>( char & );
+ TQTextStream &operator>>( signed short & );
+ TQTextStream &operator>>( unsigned short & );
+ TQTextStream &operator>>( signed int & );
+ TQTextStream &operator>>( unsigned int & );
+ TQTextStream &operator>>( signed long & );
+ TQTextStream &operator>>( unsigned long & );
+ TQTextStream &operator>>( float & );
+ TQTextStream &operator>>( double & );
+ TQTextStream &operator>>( char * );
+ TQTextStream &operator>>( TQString & );
+ TQTextStream &operator>>( TQCString & );
+
+ TQTextStream &operator<<( TQChar );
+ TQTextStream &operator<<( char );
+ TQTextStream &operator<<( signed short );
+ TQTextStream &operator<<( unsigned short );
+ TQTextStream &operator<<( signed int );
+ TQTextStream &operator<<( unsigned int );
+ TQTextStream &operator<<( signed long );
+ TQTextStream &operator<<( unsigned long );
+ TQTextStream &operator<<( float );
+ TQTextStream &operator<<( double );
+ TQTextStream &operator<<( const char* );
+ TQTextStream &operator<<( const TQString & );
+ TQTextStream &operator<<( const TQCString & );
+ TQTextStream &operator<<( void * ); // any pointer
+
+ TQTextStream &readRawBytes( char *, uint len );
+ TQTextStream &writeRawBytes( const char* , uint len );
+
+ TQString readLine();
+ TQString read();
+ void skipWhiteSpace();
+
+ enum {
+ skipws = 0x0001, // skip whitespace on input
+ left = 0x0002, // left-adjust output
+ right = 0x0004, // right-adjust output
+ internal = 0x0008, // pad after sign
+ bin = 0x0010, // binary format integer
+ oct = 0x0020, // octal format integer
+ dec = 0x0040, // decimal format integer
+ hex = 0x0080, // hex format integer
+ showbase = 0x0100, // show base indicator
+ showpoint = 0x0200, // force decimal point (float)
+ uppercase = 0x0400, // upper-case hex output
+ showpos = 0x0800, // add '+' to positive integers
+ scientific= 0x1000, // scientific float output
+ fixed = 0x2000 // fixed float output
+ };
+
+ static const int basefield; // bin | oct | dec | hex
+ static const int adjustfield; // left | right | internal
+ static const int floatfield; // scientific | fixed
+
+ int flags() const;
+ int flags( int f );
+ int setf( int bits );
+ int setf( int bits, int tqmask );
+ int unsetf( int bits );
+
+ void reset();
+
+ int width() const;
+ int width( int );
+ int fill() const;
+ int fill( int );
+ int precision() const;
+ int precision( int );
+
+private:
+ long input_int();
+ void init();
+ TQTextStream &output_int( int, ulong, bool );
+ TQIODevice *dev;
+
+ int fflags;
+ int fwidth;
+ int fillchar;
+ int fprec;
+ bool doUnicodeHeader;
+ bool owndev;
+ TQTextCodec *mapper;
+ TQTextStreamPrivate * d;
+ TQChar unused1; // ### remove in TQt 4.0
+ bool latin1;
+ bool internalOrder;
+ bool networkOrder;
+ void *unused2; // ### remove in TQt 4.0
+
+ TQChar eat_ws();
+ uint ts_getline( TQChar* );
+ void ts_ungetc( TQChar );
+ TQChar ts_getc();
+ uint ts_getbuf( TQChar*, uint );
+ void ts_putc(int);
+ void ts_putc(TQChar);
+ bool ts_isspace(TQChar);
+ bool ts_isdigit(TQChar);
+ ulong input_bin();
+ ulong input_oct();
+ ulong input_dec();
+ ulong input_hex();
+ double input_double();
+ TQTextStream &writeBlock( const char* p, uint len );
+ TQTextStream &writeBlock( const TQChar* p, uint len );
+
+ int dev_getch();
+ int dev_ungetch(int ch);
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQTextStream( const TQTextStream & );
+ TQTextStream &operator=( const TQTextStream & );
+#endif
+};
+
+typedef TQTextStream TQTS;
+
+class TQ_EXPORT TQTextIStream : public TQTextStream {
+public:
+ TQTextIStream( const TQString* s ) :
+ TQTextStream((TQString*)s,IO_ReadOnly) { }
+ TQTextIStream( TQByteArray ba ) :
+ TQTextStream(ba,IO_ReadOnly) { }
+ TQTextIStream( FILE *f ) :
+ TQTextStream(f,IO_ReadOnly) { }
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQTextIStream( const TQTextIStream & );
+ TQTextIStream &operator=( const TQTextIStream & );
+#endif
+};
+
+class TQ_EXPORT TQTextOStream : public TQTextStream {
+public:
+ TQTextOStream( TQString* s ) :
+ TQTextStream(s,IO_WriteOnly) { }
+ TQTextOStream( TQByteArray ba ) :
+ TQTextStream(ba,IO_WriteOnly) { }
+ TQTextOStream( FILE *f ) :
+ TQTextStream(f,IO_WriteOnly) { }
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQTextOStream( const TQTextOStream & );
+ TQTextOStream &operator=( const TQTextOStream & );
+#endif
+};
+
+/*****************************************************************************
+ TQTextStream inline functions
+ *****************************************************************************/
+
+inline TQIODevice *TQTextStream::tqdevice() const
+{ return dev; }
+
+inline bool TQTextStream::atEnd() const
+{ return dev ? dev->atEnd() : FALSE; }
+
+inline bool TQTextStream::eof() const
+{ return atEnd(); }
+
+inline int TQTextStream::flags() const
+{ return fflags; }
+
+inline int TQTextStream::flags( int f )
+{ int oldf = fflags; fflags = f; return oldf; }
+
+inline int TQTextStream::setf( int bits )
+{ int oldf = fflags; fflags |= bits; return oldf; }
+
+inline int TQTextStream::setf( int bits, int tqmask )
+{ int oldf = fflags; fflags = (fflags & ~tqmask) | (bits & tqmask); return oldf; }
+
+inline int TQTextStream::unsetf( int bits )
+{ int oldf = fflags; fflags &= ~bits; return oldf; }
+
+inline int TQTextStream::width() const
+{ return fwidth; }
+
+inline int TQTextStream::width( int w )
+{ int oldw = fwidth; fwidth = w; return oldw; }
+
+inline int TQTextStream::fill() const
+{ return fillchar; }
+
+inline int TQTextStream::fill( int f )
+{ int oldc = fillchar; fillchar = f; return oldc; }
+
+inline int TQTextStream::precision() const
+{ return fprec; }
+
+inline int TQTextStream::precision( int p )
+{ int oldp = fprec; fprec = p; return oldp; }
+
+/*!
+ Returns one character from the stream, or EOF.
+*/
+inline TQChar TQTextStream::ts_getc()
+{ TQChar r; return ( ts_getbuf( &r,1 ) == 1 ? r : TQChar((ushort)0xffff) ); }
+
+/*****************************************************************************
+ TQTextStream manipulators
+ *****************************************************************************/
+
+typedef TQTextStream & (*TQTSFUNC)(TQTextStream &);// manipulator function
+typedef int (TQTextStream::*TQTSMFI)(int); // manipulator w/int argument
+
+class TQ_EXPORT TQTSManip { // text stream manipulator
+public:
+ TQTSManip( TQTSMFI m, int a ) { mf=m; arg=a; }
+ void exec( TQTextStream &s ) { (s.*mf)(arg); }
+private:
+ TQTSMFI mf; // TQTextStream member function
+ int arg; // member function argument
+};
+
+TQ_EXPORT inline TQTextStream &operator>>( TQTextStream &s, TQTSFUNC f )
+{ return (*f)( s ); }
+
+TQ_EXPORT inline TQTextStream &operator<<( TQTextStream &s, TQTSFUNC f )
+{ return (*f)( s ); }
+
+TQ_EXPORT inline TQTextStream &operator<<( TQTextStream &s, TQTSManip m )
+{ m.exec(s); return s; }
+
+TQ_EXPORT TQTextStream &bin( TQTextStream &s ); // set bin notation
+TQ_EXPORT TQTextStream &oct( TQTextStream &s ); // set oct notation
+TQ_EXPORT TQTextStream &dec( TQTextStream &s ); // set dec notation
+TQ_EXPORT TQTextStream &hex( TQTextStream &s ); // set hex notation
+TQ_EXPORT TQTextStream &endl( TQTextStream &s ); // insert EOL ('\n')
+TQ_EXPORT TQTextStream &flush( TQTextStream &s ); // flush output
+TQ_EXPORT TQTextStream &ws( TQTextStream &s ); // eat whitespace on input
+TQ_EXPORT TQTextStream &reset( TQTextStream &s ); // set default flags
+
+TQ_EXPORT inline TQTSManip qSetW( int w )
+{
+ TQTSMFI func = &TQTextStream::width;
+ return TQTSManip(func,w);
+}
+
+TQ_EXPORT inline TQTSManip qSetFill( int f )
+{
+ TQTSMFI func = &TQTextStream::fill;
+ return TQTSManip(func,f);
+}
+
+TQ_EXPORT inline TQTSManip qSetPrecision( int p )
+{
+ TQTSMFI func = &TQTextStream::precision;
+ return TQTSManip(func,p);
+}
+
+#endif // TQT_NO_TEXTSTREAM
+#endif // TQTEXTSTREAM_H
diff --git a/tqtinterface/qt4/src/tools/tqthreadinstance_p.h b/tqtinterface/qt4/src/tools/tqthreadinstance_p.h
new file mode 100644
index 0000000..5405472
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqthreadinstance_p.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTHREAD_P_H
+#define TQTHREAD_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of TQThread and TQThreadStorage. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifdef TQT_THREAD_SUPPORT
+
+#ifndef TQT_H
+#include "tqmutex.h"
+#include "tqwindowdefs.h"
+#endif // TQT_H
+
+#ifdef TQ_OS_UNIX
+#include <pthread.h>
+#endif
+
+class TQThreadInstance {
+public:
+ static TQThreadInstance *current();
+
+ void init(unsigned int stackSize);
+ void deinit();
+
+ TQMutex *mutex() const;
+ void terminate();
+
+ unsigned int stacksize;
+ void *args[2];
+ void **thread_storage;
+ bool finished : 1;
+ bool running : 1;
+ bool orphan : 1;
+
+#ifdef TQ_OS_UNIX
+ pthread_cond_t thread_done;
+ pthread_t thread_id;
+
+ static void *start( void * );
+ static void finish( void * );
+#endif // TQ_OS_UNIX
+
+#ifdef TQ_OS_WIN32
+ TQt::HANDLE handle;
+ unsigned int thread_id;
+ int waiters;
+
+ static unsigned int __stdcall start( void * );
+ static void finish( TQThreadInstance * );
+#endif // TQ_OS_WIN32
+};
+
+#endif // TQT_THREAD_SUPPORT
+#endif // TQTHREAD_P_H
diff --git a/tqtinterface/qt4/src/tools/tqthreadstorage.h b/tqtinterface/qt4/src/tools/tqthreadstorage.h
new file mode 100644
index 0000000..a8ccec1
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqthreadstorage.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTHREADSTORAGE_H
+#define TQTHREADSTORAGE_H
+
+#ifdef TQT_THREAD_SUPPORT
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+class TQ_EXPORT TQThreadStorageData
+{
+public:
+ TQThreadStorageData( void (*func)(void *) );
+ ~TQThreadStorageData();
+
+ void** get() const;
+ void** set( void* p );
+
+ static void finish( void** );
+ int id;
+};
+
+
+template <class T>
+class TQThreadStorage
+{
+private:
+ TQThreadStorageData d;
+
+#if defined(TQ_DISABLE_COPY)
+ // disable copy constructor and operator=
+ TQThreadStorage( const TQThreadStorage & );
+ TQThreadStorage &operator=( const TQThreadStorage & );
+#endif // TQ_DISABLE_COPY
+
+ static void deleteData( void *x ) { delete (T)x; }
+
+public:
+ inline TQThreadStorage() : d( deleteData ) { }
+ inline ~TQThreadStorage() { }
+
+ inline bool hasLocalData() const
+ { return d.get() != 0; }
+
+ inline T& localData()
+ { void **v = d.get(); if ( !v ) v = d.set( 0 ); return *(T*)v; }
+
+ inline T localData() const
+ { void **v = d.get(); return ( v ? *(T*)v : 0 ); }
+
+ inline void setLocalData( T t )
+ { (void) d.set( t ); }
+};
+
+#endif // TQT_THREAD_SUPPORT
+
+#endif // TQTHREADSTORAGE_H
diff --git a/tqtinterface/qt4/src/tools/tqthreadstorage_unix.cpp b/tqtinterface/qt4/src/tools/tqthreadstorage_unix.cpp
new file mode 100644
index 0000000..4f17c39
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqthreadstorage_unix.cpp
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifdef TQT_THREAD_SUPPORT
+
+#include "tqplatformdefs.h"
+
+#include "tqthreadstorage.h"
+#include <private/tqthreadinstance_p.h>
+
+#include <string.h>
+
+// #define TQTHREADSTORAGE_DEBUG
+
+
+// keep this in sync with the implementation in qthreadstorage.cpp
+static const int MAX_THREAD_STORAGE = 257; // 256 maximum + 1 used in TQRegExp
+
+static pthread_mutex_t thread_storage_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static bool thread_storage_init = FALSE;
+static struct {
+ bool used;
+ void (*func)( void * );
+} thread_storage_usage[MAX_THREAD_STORAGE];
+
+
+TQThreadStorageData::TQThreadStorageData( void (*func)( void * ) )
+ : id( 0 )
+{
+ pthread_mutex_lock( &thread_storage_mutex );
+
+ // make sure things are initialized
+ if ( ! thread_storage_init )
+ memset( thread_storage_usage, 0, sizeof( thread_storage_usage ) );
+ thread_storage_init = TRUE;
+
+ for ( ; id < MAX_THREAD_STORAGE; ++id ) {
+ if ( !thread_storage_usage[id].used )
+ break;
+ }
+
+ TQ_ASSERT( id >= 0 && id < MAX_THREAD_STORAGE );
+ thread_storage_usage[id].used = TRUE;
+ thread_storage_usage[id].func = func;
+
+#ifdef TQTHREADSTORAGE_DEBUG
+ qDebug( "TQThreadStorageData: allocated id %d", id );
+#endif // TQTHREADSTORAGE_DEBUG
+
+ pthread_mutex_unlock( &thread_storage_mutex );
+}
+
+TQThreadStorageData::~TQThreadStorageData()
+{
+ pthread_mutex_lock( &thread_storage_mutex );
+ thread_storage_usage[id].used = FALSE;
+ thread_storage_usage[id].func = 0;
+
+#ifdef TQTHREADSTORAGE_DEBUG
+ qDebug( "TQThreadStorageData: released id %d", id );
+#endif // TQTHREADSTORAGE_DEBUG
+
+ pthread_mutex_unlock( &thread_storage_mutex );
+}
+
+void **TQThreadStorageData::get() const
+{
+ TQThreadInstance *d = TQThreadInstance::current();
+ if (!d) {
+ qWarning("TQThreadStorage can only be used with threads started with TQThread");
+ return 0;
+ }
+ TQMutexLocker locker( d->mutex() );
+ return d->thread_storage && d->thread_storage[id] ? &d->thread_storage[id] : 0;
+}
+
+void **TQThreadStorageData::set( void *p )
+{
+ TQThreadInstance *d = TQThreadInstance::current();
+ if (!d) {
+ qWarning("TQThreadStorage can only be used with threads started with TQThread");
+ return 0;
+ }
+ TQMutexLocker locker( d->mutex() );
+ if ( !d->thread_storage ) {
+#ifdef TQTHREADSTORAGE_DEBUG
+ qDebug( "TQThreadStorageData: allocating storage for thread %lx",
+ (unsigned long) pthread_self() );
+#endif // TQTHREADSTORAGE_DEBUG
+
+ d->thread_storage = new void*[MAX_THREAD_STORAGE];
+ memset( d->thread_storage, 0, sizeof( void* ) * MAX_THREAD_STORAGE );
+ }
+
+ // delete any previous data
+ if ( d->thread_storage[id] )
+ thread_storage_usage[id].func( d->thread_storage[id] );
+
+ // store new data
+ d->thread_storage[id] = p;
+ return &d->thread_storage[id];
+}
+
+void TQThreadStorageData::finish( void **thread_storage )
+{
+ if ( ! thread_storage ) return; // nothing to do
+
+#ifdef TQTHREADSTORAGE_DEBUG
+ qDebug( "TQThreadStorageData: destroying storage for thread %lx",
+ (unsigned long) pthread_self() );
+#endif // TQTHREADSTORAGE_DEBUG
+
+ for ( int i = 0; i < MAX_THREAD_STORAGE; ++i ) {
+ if ( ! thread_storage[i] ) continue;
+ if ( ! thread_storage_usage[i].used ) {
+#ifdef TQT_CHECK_STATE
+ qWarning( "TQThreadStorage: thread %lx exited after TQThreadStorage destroyed",
+ (unsigned long) pthread_self() );
+#endif // TQT_CHECK_STATE
+ continue;
+ }
+
+ thread_storage_usage[i].func( thread_storage[i] );
+ }
+
+ delete [] thread_storage;
+}
+
+
+/*!
+ \class TQThreadStorage
+ \brief The TQThreadStorage class provides per-thread data storage.
+
+ \threadsafe
+ \ingroup thread
+ \ingroup environment
+
+ TQThreadStorage is a template class that provides per-thread data
+ storage.
+
+ \e{Note that due to compiler limitations, TQThreadStorage can only
+ store pointers.}
+
+ The setLocalData() function stores a single thread-specific value
+ for the calling thread. The data can be accessed later using the
+ localData() functions. TQThreadStorage takes ownership of the
+ data (which must be created on the heap with \e new) and deletes
+ it when the thread exits (either normally or via termination).
+
+ The hasLocalData() function allows the programmer to determine if
+ data has previously been set using the setLocalData() function.
+ This is useful for lazy initializiation.
+
+ For example, the following code uses TQThreadStorage to store a
+ single cache for each thread that calls the \e cacheObject() and
+ \e removeFromCache() functions. The cache is automatically
+ deleted when the calling thread exits (either normally or via
+ termination).
+
+ \code
+ TQThreadStorage<TQCache<SomeClass> *> caches;
+
+ void cacheObject( const TQString &key, SomeClass *object )
+ {
+ if ( ! caches.hasLocalData() )
+ caches.setLocalData( new TQCache<SomeClass> );
+
+ caches.localData()->insert( key, object );
+ }
+
+ void removeFromCache( const TQString &key )
+ {
+ if ( ! caches.hasLocalData() )
+ return; // nothing to do
+
+ caches.localData()->remove( key );
+ }
+ \endcode
+
+ \section1 Caveats
+
+ \list
+
+ \i As noted above, TQThreadStorage can only store pointers due to
+ compiler limitations. Support for value-based objects will be
+ added when the majority of compilers are able to support partial
+ template specialization.
+
+ \i The \link ~TQThreadStorage() destructor\endlink does \e not
+ delete per-thread data. TQThreadStorage only deletes per-thread
+ data when the thread exits or when setLocalData() is called
+ multiple times.
+
+ \i TQThreadStorage can only be used with threads started with
+ TQThread. It \e cannot be used with threads started with
+ platform-specific APIs.
+
+ \i As a corollary to the above, platform-specific APIs cannot be
+ used to exit or terminate a TQThread using TQThreadStorage. Doing so
+ will cause all per-thread data to be leaked. See TQThread::exit()
+ and TQThread::terminate().
+
+ \i TQThreadStorage \e can be used to store data for the \e main()
+ thread \e after TQApplication has been constructed. TQThreadStorage
+ deletes all data set for the \e main() thread when TQApplication is
+ destroyed, regardless of whether or not the \e main() thread has
+ actually finished.
+
+ \i The implementation of TQThreadStorage limits the total number of
+ TQThreadStorage objects to 256. An unlimited number of threads
+ can store per-thread data in each TQThreadStorage object.
+
+ \endlist
+*/
+
+/*!
+ \fn TQThreadStorage::TQThreadStorage()
+
+ Constructs a new per-thread data storage object.
+*/
+
+/*!
+ \fn TQThreadStorage::~TQThreadStorage()
+
+ Destroys the per-thread data storage object.
+
+ Note: The per-thread data stored is \e not deleted. Any data left
+ in TQThreadStorage is leaked. Make sure that all threads using
+ TQThreadStorage have exited before deleting the TQThreadStorage.
+
+ \sa hasLocalData()
+*/
+
+/*!
+ \fn bool TQThreadStorage::hasLocalData() const
+
+ Returns TRUE if the calling thread has non-zero data available;
+ otherwise returns FALSE.
+
+ \sa localData()
+*/
+
+/*!
+ \fn T& TQThreadStorage::localData()
+
+ Returns a reference to the data that was set by the calling
+ thread.
+
+ Note: TQThreadStorage can only store pointers. This function
+ returns a \e reference to the pointer that was set by the calling
+ thread. The value of this reference is 0 if no data was set by
+ the calling thread,
+
+ \sa hasLocalData()
+*/
+/*
+ ### addition to the above documentation when we start supporting
+ ### partial template specialization, and TQThreadStorage can store
+ ### values *and* pointers
+
+ When using TQThreadStorage to store values (not pointers), this
+ function stores an object of type \e T (created with its default
+ constructor) and returns a reference to that object.
+*/
+
+/*!
+ \fn const T TQThreadStorage::localData() const
+ \overload
+
+ Returns a copy of the data that was set by the calling thread.
+
+ Note: TQThreadStorage can only store pointers. This function
+ returns a pointer to the data that was set by the calling thread.
+ If no data was set by the calling thread, this function returns 0.
+
+ \sa hasLocalData()
+*/
+/*
+ ### addition to the above documentation when we start supporting
+ ### partial template specialization, and TQThreadStorage can store
+ ### values *and* pointers
+
+ When using TQThreadStorage to store values (not pointers), this
+ function returns an object of type \e T (created with its default
+ constructor). Unlike the above function, this object is \e not
+ stored automatically. You will need to call setLocalData() to store
+ the object.
+*/
+
+/*!
+ \fn void TQThreadStorage::setLocalData( T data )
+
+ Sets the local data for the calling thread to \a data. It can be
+ accessed later using the localData() functions.
+
+ If \a data is 0, this function deletes the previous data (if
+ any) and returns immediately.
+
+ If \a data is non-zero, TQThreadStorage takes ownership of the \a
+ data and deletes it automatically either when the thread exits
+ (either normally or via termination) or when setLocalData() is
+ called again.
+
+ Note: TQThreadStorage can only store pointers. The \a data
+ argument must be either a pointer to an object created on the heap
+ (i.e. using \e new) or 0. You should not delete \a data
+ yourself; TQThreadStorage takes ownership and will delete the \a
+ data itself.
+
+ \sa localData() hasLocalData()
+*/
+
+#endif // TQT_THREAD_SUPPORT
diff --git a/tqtinterface/qt4/src/tools/tqtl.h b/tqtinterface/qt4/src/tools/tqtl.h
new file mode 100644
index 0000000..3f02d84
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqtl.h
@@ -0,0 +1,325 @@
+/****************************************************************************
+**
+** Definition of TQt template library classes
+**
+** Created : 990128
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTL_H
+#define TQTL_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqtextstream.h"
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TEXTSTREAM
+template <class T>
+class TQTextOStreamIterator
+{
+protected:
+ TQTextOStream& stream;
+ TQString separator;
+
+public:
+ TQTextOStreamIterator( TQTextOStream& s) : stream( s ) {}
+ TQTextOStreamIterator( TQTextOStream& s, const TQString& sep )
+ : stream( s ), separator( sep ) {}
+ TQTextOStreamIterator<T>& operator= ( const T& x ) {
+ stream << x;
+ if ( !separator.isEmpty() )
+ stream << separator;
+ return *this;
+ }
+ TQTextOStreamIterator<T>& operator*() { return *this; }
+ TQTextOStreamIterator<T>& operator++() { return *this; }
+ TQTextOStreamIterator<T>& operator++(int) { return *this; }
+};
+#endif //TQT_NO_TEXTSTREAM
+
+template <class InputIterator, class OutputIterator>
+inline OutputIterator tqCopy( InputIterator _begin, InputIterator _end,
+ OutputIterator _dest )
+{
+ while( _begin != _end )
+ *_dest++ = *_begin++;
+ return _dest;
+}
+
+template <class BiIterator, class BiOutputIterator>
+inline BiOutputIterator tqCopyBackward( BiIterator _begin, BiIterator _end,
+ BiOutputIterator _dest )
+{
+ while ( _begin != _end )
+ *--_dest = *--_end;
+ return _dest;
+}
+
+template <class InputIterator1, class InputIterator2>
+inline bool tqEqual( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2 )
+{
+ // ### compare using !(*first1 == *first2) in TQt 4.0
+ for ( ; first1 != last1; ++first1, ++first2 )
+ if ( *first1 != *first2 )
+ return FALSE;
+ return TRUE;
+}
+
+template <class ForwardIterator, class T>
+inline void tqFill( ForwardIterator first, ForwardIterator last, const T& val )
+{
+ for ( ; first != last; ++first )
+ *first = val;
+}
+
+#if 0
+template <class BiIterator, class OutputIterator>
+inline OutputIterator qReverseCopy( BiIterator _begin, BiIterator _end,
+ OutputIterator _dest )
+{
+ while ( _begin != _end ) {
+ --_end;
+ *_dest = *_end;
+ ++_dest;
+ }
+ return _dest;
+}
+#endif
+
+
+template <class InputIterator, class T>
+inline InputIterator tqFind( InputIterator first, InputIterator last,
+ const T& val )
+{
+ while ( first != last && *first != val )
+ ++first;
+ return first;
+}
+
+template <class InputIterator, class T, class Size>
+inline void tqCount( InputIterator first, InputIterator last, const T& value,
+ Size& n )
+{
+ for ( ; first != last; ++first )
+ if ( *first == value )
+ ++n;
+}
+
+template <class T>
+inline void tqSwap( T& _value1, T& _value2 )
+{
+ T tmp = _value1;
+ _value1 = _value2;
+ _value2 = tmp;
+}
+
+
+template <class InputIterator>
+TQ_INLINE_TEMPLATES void qBubbleSort( InputIterator b, InputIterator e )
+{
+ // Goto last element;
+ InputIterator last = e;
+ --last;
+ // only one element or no elements ?
+ if ( last == b )
+ return;
+
+ // So we have at least two elements in here
+ while( b != last ) {
+ bool swapped = FALSE;
+ InputIterator swap_pos = b;
+ InputIterator x = e;
+ InputIterator y = x;
+ y--;
+ do {
+ --x;
+ --y;
+ if ( *x < *y ) {
+ swapped = TRUE;
+ tqSwap( *x, *y );
+ swap_pos = y;
+ }
+ } while( y != b );
+ if ( !swapped )
+ return;
+ b = swap_pos;
+ b++;
+ }
+}
+
+
+template <class Container>
+inline void qBubbleSort( Container &c )
+{
+ qBubbleSort( c.begin(), c.end() );
+}
+
+
+template <class Value>
+TQ_INLINE_TEMPLATES void qHeapSortPushDown( Value* heap, int first, int last )
+{
+ int r = first;
+ while ( r <= last / 2 ) {
+ if ( last == 2 * r ) {
+ // node r has only one child
+ if ( heap[2 * r] < heap[r] )
+ tqSwap( heap[r], heap[2 * r] );
+ r = last;
+ } else {
+ // node r has two tqchildren
+ if ( heap[2 * r] < heap[r] && !(heap[2 * r + 1] < heap[2 * r]) ) {
+ // swap with left child
+ tqSwap( heap[r], heap[2 * r] );
+ r *= 2;
+ } else if ( heap[2 * r + 1] < heap[r]
+ && heap[2 * r + 1] < heap[2 * r] ) {
+ // swap with right child
+ tqSwap( heap[r], heap[2 * r + 1] );
+ r = 2 * r + 1;
+ } else {
+ r = last;
+ }
+ }
+ }
+}
+
+
+template <class InputIterator, class Value>
+TQ_INLINE_TEMPLATES void qHeapSortHelper( InputIterator b, InputIterator e, Value, uint n )
+{
+ // Create the heap
+ InputIterator insert = b;
+ Value* realheap = new Value[n];
+ // Wow, what a fake. But I want the heap to be indexed as 1...n
+ Value* heap = realheap - 1;
+ int size = 0;
+ for( ; insert != e; ++insert ) {
+ heap[++size] = *insert;
+ int i = size;
+ while( i > 1 && heap[i] < heap[i / 2] ) {
+ tqSwap( heap[i], heap[i / 2] );
+ i /= 2;
+ }
+ }
+
+ // Now do the sorting
+ for( uint i = n; i > 0; i-- ) {
+ *b++ = heap[1];
+ if ( i > 1 ) {
+ heap[1] = heap[i];
+ qHeapSortPushDown( heap, 1, (int)i - 1 );
+ }
+ }
+
+ delete[] realheap;
+}
+
+
+template <class InputIterator>
+TQ_INLINE_TEMPLATES void qHeapSort( InputIterator b, InputIterator e )
+{
+ // Empty ?
+ if ( b == e )
+ return;
+
+ // How many entries have to be sorted ?
+ InputIterator it = b;
+ uint n = 0;
+ while ( it != e ) {
+ ++n;
+ ++it;
+ }
+
+ // The second last parameter is a hack to retrieve the value type
+ // Do the real sorting here
+ qHeapSortHelper( b, e, *b, n );
+}
+
+
+template <class Container>
+TQ_INLINE_TEMPLATES void qHeapSort( Container &c )
+{
+ if ( c.begin() == c.end() )
+ return;
+
+ // The second last parameter is a hack to retrieve the value type
+ // Do the real sorting here
+ qHeapSortHelper( c.begin(), c.end(), *(c.begin()), (uint)c.count() );
+}
+
+template <class Container>
+class TQBackInsertIterator
+{
+public:
+ TQ_EXPLICIT TQBackInsertIterator( Container &c )
+ : container( &c )
+ {
+ }
+
+ TQBackInsertIterator<Container>&
+ operator=( const TQ_TYPENAME Container::value_type &value )
+ {
+ container->push_back( value );
+ return *this;
+ }
+
+ TQBackInsertIterator<Container>& operator*()
+ {
+ return *this;
+ }
+
+ TQBackInsertIterator<Container>& operator++()
+ {
+ return *this;
+ }
+
+ TQBackInsertIterator<Container>& operator++(int)
+ {
+ return *this;
+ }
+
+protected:
+ Container *container;
+};
+
+template <class Container>
+inline TQBackInsertIterator<Container> qBackInserter( Container &c )
+{
+ return TQBackInsertIterator<Container>( c );
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqucom.cpp b/tqtinterface/qt4/src/tools/tqucom.cpp
new file mode 100644
index 0000000..7f77a39
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqucom.cpp
@@ -0,0 +1,547 @@
+/****************************************************************************
+**
+** Implementation of the TQUcom classes
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqucom_p.h"
+
+// Standard types
+
+// {DE56510E-4E9F-4b76-A3C2-D1E2EF42F1AC}
+const TQUuid TID_TQUType_Null( 0xde56510e, 0x4e9f, 0x4b76, 0xa3, 0xc2, 0xd1, 0xe2, 0xef, 0x42, 0xf1, 0xac );
+const TQUuid *TQUType_Null::uuid() const { return &TID_TQUType_Null; }
+const char *TQUType_Null::desc() const { return "null"; }
+bool TQUType_Null::canConvertFrom( TQUObject *, TQUType * ) { return FALSE; }
+bool TQUType_Null::canConvertTo( TQUObject *, TQUType * ) { return FALSE; }
+bool TQUType_Null::convertFrom( TQUObject *, TQUType * ) { return FALSE; }
+bool TQUType_Null::convertTo( TQUObject *, TQUType * ) { return FALSE; }
+void TQUType_Null::clear( TQUObject *) {}
+int TQUType_Null::serializeTo( TQUObject *, TQUBuffer * ) { return 0; }
+int TQUType_Null::serializeFrom( TQUObject *, TQUBuffer * ) { return 0; }
+TQUType_Null static_TQUType_Null;
+
+
+// {7EE17B08-5419-47e2-9776-8EEA112DCAEC}
+const TQUuid TID_TQUType_enum( 0x7ee17b08, 0x5419, 0x47e2, 0x97, 0x76, 0x8e, 0xea, 0x11, 0x2d, 0xca, 0xec );
+TQUType_enum static_TQUType_enum;
+const TQUuid *TQUType_enum::uuid() const { return &TID_TQUType_enum; }
+const char *TQUType_enum::desc() const { return "enum"; }
+void TQUType_enum::set( TQUObject *o, int v )
+{
+ o->payload.i = v;
+ o->type = this;
+}
+
+bool TQUType_enum::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_int ) ) // ## todo unsigned int?
+ return TRUE;
+
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_enum::canConvertTo( TQUObject * /*o*/, TQUType *t )
+{
+ return isEqual( t, &static_TQUType_int );
+}
+
+bool TQUType_enum::convertFrom( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_int ) ) // ## todo unsigned int?
+ ;
+ else
+ return t->convertTo( o, this );
+
+ o->type = this;
+ return TRUE;
+}
+
+bool TQUType_enum::convertTo( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_int ) ) {
+ o->type = &static_TQUType_int;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int TQUType_enum::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_enum::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+// {8AC26448-5AB4-49eb-968C-8F30AB13D732}
+const TQUuid TID_TQUType_ptr( 0x8ac26448, 0x5ab4, 0x49eb, 0x96, 0x8c, 0x8f, 0x30, 0xab, 0x13, 0xd7, 0x32 );
+TQUType_ptr static_TQUType_ptr;
+const TQUuid *TQUType_ptr::uuid() const { return &TID_TQUType_ptr; }
+const char *TQUType_ptr::desc() const { return "ptr"; }
+
+void TQUType_ptr::set( TQUObject *o, const void* v )
+{
+ o->payload.ptr = (void*) v;
+ o->type = this;
+}
+
+bool TQUType_ptr::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_ptr::canConvertTo( TQUObject *, TQUType * )
+{
+ return FALSE;
+}
+
+bool TQUType_ptr::convertFrom( TQUObject *o, TQUType *t )
+{
+ return t->convertTo( o, this );
+}
+
+bool TQUType_ptr::convertTo( TQUObject *, TQUType * )
+{
+ return FALSE;
+}
+
+int TQUType_ptr::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_ptr::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+// {97A2594D-6496-4402-A11E-55AEF2D4D25C}
+const TQUuid TID_TQUType_iface( 0x97a2594d, 0x6496, 0x4402, 0xa1, 0x1e, 0x55, 0xae, 0xf2, 0xd4, 0xd2, 0x5c );
+TQUType_iface static_TQUType_iface;
+const TQUuid *TQUType_iface::uuid() const { return &TID_TQUType_iface; }
+const char *TQUType_iface::desc() const { return "UnknownInterface"; }
+
+void TQUType_iface::set( TQUObject *o, TQUnknownInterface* iface )
+{
+ o->payload.iface = iface;
+ o->type = this;
+}
+
+bool TQUType_iface::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_iface::canConvertTo( TQUObject *, TQUType * )
+{
+ return FALSE;
+}
+
+bool TQUType_iface::convertFrom( TQUObject *o, TQUType *t )
+{
+ return t->convertTo( o, this );
+}
+
+bool TQUType_iface::convertTo( TQUObject *, TQUType * )
+{
+ return FALSE;
+}
+
+int TQUType_iface::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_iface::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+// {2F358164-E28F-4bf4-9FA9-4E0CDCABA50B}
+const TQUuid TID_TQUType_idisp( 0x2f358164, 0xe28f, 0x4bf4, 0x9f, 0xa9, 0x4e, 0xc, 0xdc, 0xab, 0xa5, 0xb );
+TQUType_idisp static_TQUType_idisp;
+const TQUuid *TQUType_idisp::uuid() const { return &TID_TQUType_idisp; }
+const char *TQUType_idisp::desc() const { return "DispatchInterface"; }
+
+void TQUType_idisp::set( TQUObject *o, TQDispatchInterface* idisp )
+{
+ o->payload.idisp = idisp;
+ o->type = this;
+}
+
+bool TQUType_idisp::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_idisp::canConvertTo( TQUObject * /*o*/, TQUType *t )
+{
+ return isEqual( t, &static_TQUType_iface );
+}
+
+bool TQUType_idisp::convertFrom( TQUObject *o, TQUType *t )
+{
+ return t->convertTo( o, this );
+}
+
+bool TQUType_idisp::convertTo( TQUObject *o, TQUType *t )
+{
+#ifndef TQT_NO_COMPONENT
+ if ( isEqual( t, &static_TQUType_iface ) ) {
+ o->payload.iface = (TQUnknownInterface*)o->payload.idisp;
+ o->type = &static_TQUType_iface;
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
+int TQUType_idisp::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_idisp::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+// {CA42115D-13D0-456c-82B5-FC10187F313E}
+const TQUuid TID_TQUType_bool( 0xca42115d, 0x13d0, 0x456c, 0x82, 0xb5, 0xfc, 0x10, 0x18, 0x7f, 0x31, 0x3e );
+TQUType_bool static_TQUType_bool;
+const TQUuid *TQUType_bool::uuid() const { return &TID_TQUType_bool; }
+const char *TQUType_bool::desc() const { return "bool"; }
+
+void TQUType_bool::set( TQUObject *o, bool v )
+{
+ o->payload.b = v;
+ o->type = this;
+}
+
+bool TQUType_bool::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_bool::canConvertTo( TQUObject *, TQUType * )
+{
+ return FALSE;
+}
+
+bool TQUType_bool::convertFrom( TQUObject *o, TQUType *t )
+{
+ return t->convertTo( o, this );
+}
+
+bool TQUType_bool::convertTo( TQUObject *, TQUType * )
+{
+ return FALSE;
+}
+
+int TQUType_bool::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_bool::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+// {53C1F3BE-73C3-4c7d-9E05-CCF09EB676B5}
+const TQUuid TID_TQUType_int( 0x53c1f3be, 0x73c3, 0x4c7d, 0x9e, 0x5, 0xcc, 0xf0, 0x9e, 0xb6, 0x76, 0xb5 );
+TQUType_int static_TQUType_int;
+const TQUuid *TQUType_int::uuid() const { return &TID_TQUType_int; }
+const char *TQUType_int::desc() const { return "int"; }
+
+void TQUType_int::set( TQUObject *o, int v )
+{
+ o->payload.i = v;
+ o->type = this;
+}
+
+bool TQUType_int::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_double ) )
+ return TRUE;
+
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_int::canConvertTo( TQUObject * /*o*/, TQUType *t )
+{
+ return isEqual( t, &static_TQUType_double );
+}
+
+bool TQUType_int::convertFrom( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_double ) )
+ o->payload.i = (long)o->payload.d;
+ else
+ return t->convertTo( o, this );
+
+ o->type = this;
+ return TRUE;
+}
+
+bool TQUType_int::convertTo( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_double ) ) {
+ o->payload.d = (double)o->payload.i;
+ o->type = &static_TQUType_double;
+ } else
+ return FALSE;
+ return TRUE;
+}
+
+int TQUType_int::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_int::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+// {2D0974E5-0BA6-4ec2-8837-C198972CB48C}
+const TQUuid TID_TQUType_double( 0x2d0974e5, 0xba6, 0x4ec2, 0x88, 0x37, 0xc1, 0x98, 0x97, 0x2c, 0xb4, 0x8c );
+TQUType_double static_TQUType_double;
+const TQUuid *TQUType_double::uuid() const { return &TID_TQUType_double; }
+const char *TQUType_double::desc() const {return "double"; }
+
+void TQUType_double::set( TQUObject *o, double v )
+{
+ o->payload.d = v;
+ o->type = this;
+}
+
+bool TQUType_double::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_int ) )
+ return TRUE;
+
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_double::canConvertTo( TQUObject * /*o*/, TQUType *t )
+{
+ return isEqual( t, &static_TQUType_int );
+}
+
+bool TQUType_double::convertFrom( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_int ) )
+ o->payload.d = (double)o->payload.i;
+ else
+ return t->convertTo( o, this );
+
+ o->type = this;
+ return TRUE;
+}
+
+bool TQUType_double::convertTo( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_int ) ) {
+ o->payload.i = (int) o->payload.d;
+ o->type = &static_TQUType_int;
+ } else if ( isEqual( t, &static_TQUType_double ) ) {
+ o->payload.d = (double) o->payload.f;
+ o->type = &static_TQUType_double;
+ } else
+ return FALSE;
+ return TRUE;
+}
+
+int TQUType_double::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_double::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+// {EFCDD1D4-77A3-4b8e-8D46-DC14B8D393E9}
+const TQUuid TID_TQUType_charstar( 0xefcdd1d4, 0x77a3, 0x4b8e, 0x8d, 0x46, 0xdc, 0x14, 0xb8, 0xd3, 0x93, 0xe9 );
+TQUType_charstar static_TQUType_charstar;
+const TQUuid *TQUType_charstar::uuid() const { return &TID_TQUType_charstar; }
+const char *TQUType_charstar::desc() const { return "char*"; }
+
+void TQUType_charstar::set( TQUObject *o, const char* v, bool take )
+{
+ if ( take ) {
+ if ( v ) {
+ o->payload.charstar.ptr = new char[ strlen(v) + 1 ];
+ strcpy( o->payload.charstar.ptr, v );
+ } else {
+ o->payload.charstar.ptr = 0;
+ }
+ o->payload.charstar.owner = TRUE;
+ } else {
+ o->payload.charstar.ptr = (char*) v;
+ o->payload.charstar.owner = FALSE;
+ }
+ o->type = this;
+}
+
+bool TQUType_charstar::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_charstar::canConvertTo( TQUObject *, TQUType * )
+{
+ return FALSE;
+}
+
+bool TQUType_charstar::convertFrom( TQUObject *o, TQUType *t )
+{
+ return t->convertTo( o, this );
+}
+
+bool TQUType_charstar::convertTo( TQUObject *, TQUType * )
+{
+ return FALSE;
+}
+
+void TQUType_charstar::clear( TQUObject *o )
+{
+ if ( o->payload.charstar.owner )
+ delete [] o->payload.charstar.ptr;
+ o->payload.charstar.ptr = 0;
+}
+
+int TQUType_charstar::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_charstar::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+
+// TQt specific types
+
+// {44C2A547-01E7-4e56-8559-35AF9D2F42B7}
+const TQUuid TID_TQUType_TQString( 0x44c2a547, 0x1e7, 0x4e56, 0x85, 0x59, 0x35, 0xaf, 0x9d, 0x2f, 0x42, 0xb7 );
+TQUType_TQString static_TQUType_TQString;
+const TQUuid *TQUType_TQString::uuid() const { return &TID_TQUType_TQString; }
+const char *TQUType_TQString::desc() const { return "TQString"; }
+
+void TQUType_TQString::set( TQUObject *o, const TQString& v )
+{
+ o->payload.ptr = new TQString( v );
+ o->type = this;
+}
+
+bool TQUType_TQString::canConvertFrom( TQUObject *o, TQUType *t )
+{
+ if ( isEqual( t, &static_TQUType_charstar ) ||
+ isEqual( t, &static_TQUType_double ) ||
+ isEqual( t, &static_TQUType_int ) )
+ return TRUE;
+
+ return t->canConvertTo( o, this );
+}
+
+bool TQUType_TQString::canConvertTo( TQUObject * /*o*/, TQUType *t )
+{
+ return isEqual( t, &static_TQUType_charstar ) ||
+ isEqual( t, &static_TQUType_int ) ||
+ isEqual( t, &static_TQUType_double );
+}
+
+bool TQUType_TQString::convertFrom( TQUObject *o, TQUType *t )
+{
+ TQString *str = 0;
+ if ( isEqual( t, &static_TQUType_charstar ) )
+ str = new TQString( o->payload.charstar.ptr );
+ else if ( isEqual( t, &static_TQUType_double ) )
+ str = new TQString( TQString::number( o->payload.d ) );
+ else if ( isEqual( t, &static_TQUType_int ) )
+ str = new TQString( TQString::number( o->payload.i ) );
+ else
+ return t->convertTo( o, this );
+
+ o->type->clear( o );
+ o->payload.ptr = str;
+ o->type = this;
+ return TRUE;
+}
+
+bool TQUType_TQString::convertTo( TQUObject *o, TQUType *t )
+{
+ TQString *str = (TQString *)o->payload.ptr;
+ if ( isEqual( t, &static_TQUType_charstar ) ) {
+ o->payload.charstar.ptr = qstrdup( str->local8Bit().data() );
+ o->payload.charstar.owner = TRUE;
+ o->type = &static_TQUType_charstar;
+ } else if ( isEqual( t, &static_TQUType_int ) ) {
+ o->payload.l = str->toLong();
+ o->type = &static_TQUType_int;
+ } else if ( isEqual( t, &static_TQUType_double ) ) {
+ o->payload.d = str->toDouble();
+ o->type = &static_TQUType_double;
+ } else {
+ return FALSE;
+ }
+ delete str;
+ return TRUE;
+}
+
+int TQUType_TQString::serializeTo( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+int TQUType_TQString::serializeFrom( TQUObject *, TQUBuffer * )
+{
+ return 0;
+}
+
+void TQUType_TQString::clear( TQUObject *o )
+{
+ delete (TQString*)o->payload.ptr;
+ o->payload.ptr = 0;
+}
diff --git a/tqtinterface/qt4/src/tools/tqucom_p.h b/tqtinterface/qt4/src/tools/tqucom_p.h
new file mode 100644
index 0000000..546e0f2
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqucom_p.h
@@ -0,0 +1,470 @@
+/****************************************************************************
+**
+** Definition of the TQUcom interfaces
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQUCOM_P_H
+#define TQUCOM_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqstring.h"
+#include "tquuid.h"
+#endif // TQT_H
+
+#ifdef check
+#undef check
+#endif
+
+#if __GNUC__ - 0 > 3
+#pragma GCC system_header
+#endif
+
+struct TQUObject;
+struct TQUInterfaceDescription;
+struct TQUnknownInterface;
+struct TQDispatchInterface;
+
+
+struct TQ_EXPORT TQUBuffer
+{
+ virtual long read( char *data, ulong maxlen ) = 0;
+ virtual long write( const char *data, ulong len ) = 0;
+};
+
+
+// A type for a TQUObject
+struct TQ_EXPORT TQUType
+{
+ virtual const TQUuid *uuid() const = 0;
+ virtual const char *desc() const = 0;
+
+
+ virtual bool canConvertFrom( TQUObject *, TQUType * ) = 0;
+ // virtual private, only called by canConvertFrom
+ virtual bool canConvertTo( TQUObject *, TQUType * ) = 0;
+
+
+ virtual bool convertFrom( TQUObject *, TQUType * ) = 0;
+ // virtual private, only called by convertFrom
+ virtual bool convertTo( TQUObject *, TQUType * ) = 0;
+
+ virtual void clear( TQUObject * ) = 0;
+
+ virtual int serializeTo( TQUObject *, TQUBuffer * ) = 0;
+ virtual int serializeFrom( TQUObject *, TQUBuffer * ) = 0;
+
+ static bool isEqual( const TQUType *t1, const TQUType *t2 );
+ static bool check( TQUObject* o, TQUType* t );
+};
+
+
+// {DE56510E-4E9F-4b76-A3C2-D1E2EF42F1AC}
+extern TQ_EXPORT const TQUuid TID_TQUType_Null;
+struct TQ_EXPORT TQUType_Null : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * );
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+};
+extern TQ_EXPORT TQUType_Null static_TQUType_Null;
+
+
+// The magic TQUObject
+struct TQ_EXPORT TQUObject
+{
+public: // scary MSVC bug makes this necessary
+ TQUObject() : type( &static_TQUType_Null ) {}
+ ~TQUObject() { type->clear( this ); }
+
+ TQUType *type;
+
+ // the unavoidable union
+ union
+ {
+ bool b;
+
+ char c;
+ short s;
+ int i;
+ long l;
+
+ unsigned char uc;
+ unsigned short us;
+ unsigned int ui;
+ unsigned long ul;
+
+ float f;
+ double d;
+
+ char byte[16];
+
+ struct {
+ char* data;
+ unsigned long size;
+ } bytearray;
+
+ void* ptr;
+
+ struct {
+ void *ptr;
+ bool owner;
+ } voidstar;
+
+ struct {
+ char *ptr;
+ bool owner;
+ } charstar;
+
+ struct {
+ char *ptr;
+ bool owner;
+ } utf8;
+
+ struct {
+ char *ptr;
+ bool owner;
+ } local8bit;
+
+ TQUnknownInterface* iface;
+ TQDispatchInterface* idisp;
+
+ } payload;
+
+};
+
+
+// A parameter description describes one method parameters. A
+// parameter has a name, a type and a flag describing whether it's an
+// in parameter, an out parameter, or both ways
+struct TQ_EXPORT TQUParameter
+{
+ const char* name;
+ TQUType *type;
+ const void* typeExtra; //Usually 0, UEnum* for TQUType_enum, const char* for TQUType_ptr, int* for TQUType_varptr
+ enum { In = 1, Out = 2, InOut = In | Out };
+ int inOut;
+};
+
+// A method description describes one method. A method has a name and
+// an array of parameters.
+struct TQ_EXPORT TQUMethod
+{
+ const char* name;
+ int count;
+ const TQUParameter* parameters;
+};
+
+// A Property description. Not used yet in the example.
+struct TQ_EXPORT TQUProperty
+{
+ const char* name;
+ TQUType* type;
+ const void* typeExtra; //type dependend. Usually 0, but UEnum for TQUTypeenum or const char* for TQUTypeptr
+
+ int set; // -1 undefined
+ int get; // -1 undefined
+
+ int designable; // -1 FALSE, -2 TRUE, else method
+ int stored; // -1 FALSE, -2 TRUE, else method
+};
+
+// An interface description describes one interface, that is all its
+// methods and properties.
+struct TQ_EXPORT TQUInterfaceDescription
+{
+ int methodCount;
+ const TQUMethod* methods;
+ int propertyCount;
+ const TQUProperty* properties;
+};
+
+
+// A component description describe one component, that is its name,
+// vendor, release, info, its component uuid and all its interface
+// uuids.
+struct TQ_EXPORT TQUComponentDescription
+{
+ const char* name;
+ const char* vendor;
+ const char* release;
+ const char* info;
+ TQUuid cid;
+ int count;
+ const TQUuid* interfaces;
+};
+
+
+// A component server description describe one component server, that
+// is its name, vendor, release, info and the descriptions of all
+// components it can instantiate.
+struct TQ_EXPORT TQUComponentServerDescription
+{
+ const char* name;
+ const char* vendor;
+ const char* release;
+ const char* info;
+ int count;
+ const TQUComponentDescription* components;
+};
+
+
+
+struct TQ_EXPORT TQUEnumItem // - a name/value pair
+{
+ const char *key;
+ int value;
+};
+
+struct TQ_EXPORT TQUEnum
+{
+ const char *name; // - enumerator name
+ unsigned int count; // - number of values
+ const TQUEnumItem *items; // - the name/value pairs
+ bool set; // whether enum has to be treated as a set
+};
+
+inline bool TQUType::isEqual( const TQUType *t1, const TQUType *t2 ) {
+ return t1 == t2 || t1->uuid() == t2->uuid() ||
+ *(t1->uuid()) == *(t2->uuid());
+}
+
+inline bool TQUType::check( TQUObject* o, TQUType* t ) {
+ return isEqual( o->type, t ) || t->convertFrom( o, o->type );
+}
+
+
+
+// {7EE17B08-5419-47e2-9776-8EEA112DCAEC}
+extern TQ_EXPORT const TQUuid TID_TQUType_enum;
+struct TQ_EXPORT TQUType_enum : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, int );
+ int &get( TQUObject * o ) { return o->payload.i; }
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * ) {}
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+};
+extern TQ_EXPORT TQUType_enum static_TQUType_enum;
+
+
+// {8AC26448-5AB4-49eb-968C-8F30AB13D732}
+extern TQ_EXPORT const TQUuid TID_TQUType_ptr;
+struct TQ_EXPORT TQUType_ptr : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, const void* );
+ void* &get( TQUObject * o ) { return o->payload.ptr; }
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * ) {}
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+};
+extern TQ_EXPORT TQUType_ptr static_TQUType_ptr;
+
+// {97A2594D-6496-4402-A11E-55AEF2D4D25C}
+extern TQ_EXPORT const TQUuid TID_TQUType_iface;
+struct TQ_EXPORT TQUType_iface : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, TQUnknownInterface* );
+ TQUnknownInterface* &get( TQUObject *o ){ return o->payload.iface; }
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * ) {}
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+};
+extern TQ_EXPORT TQUType_iface static_TQUType_iface;
+
+// {2F358164-E28F-4bf4-9FA9-4E0CDCABA50B}
+extern TQ_EXPORT const TQUuid TID_TQUType_idisp;
+struct TQ_EXPORT TQUType_idisp : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, TQDispatchInterface* );
+ TQDispatchInterface* &get( TQUObject *o ){ return o->payload.idisp; }
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * ) {}
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+};
+extern TQ_EXPORT TQUType_idisp static_TQUType_idisp;
+
+// {CA42115D-13D0-456c-82B5-FC10187F313E}
+extern TQ_EXPORT const TQUuid TID_TQUType_bool;
+struct TQ_EXPORT TQUType_bool : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, bool );
+ bool &get( TQUObject *o ) { return o->payload.b; }
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * ) {}
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+};
+extern TQ_EXPORT TQUType_bool static_TQUType_bool;
+
+// {53C1F3BE-73C3-4c7d-9E05-CCF09EB676B5}
+extern TQ_EXPORT const TQUuid TID_TQUType_int;
+struct TQ_EXPORT TQUType_int : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, int );
+ int &get( TQUObject *o ) { return o->payload.i; }
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * ) {}
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+};
+extern TQ_EXPORT TQUType_int static_TQUType_int;
+
+
+// {2D0974E5-0BA6-4ec2-8837-C198972CB48C}
+extern TQ_EXPORT const TQUuid TID_TQUType_double;
+struct TQ_EXPORT TQUType_double : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, double );
+ double &get( TQUObject *o ) { return o->payload.d; }
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * ) {}
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+};
+extern TQ_EXPORT TQUType_double static_TQUType_double;
+
+
+// {EFCDD1D4-77A3-4b8e-8D46-DC14B8D393E9}
+extern TQ_EXPORT const TQUuid TID_TQUType_charstar;
+struct TQ_EXPORT TQUType_charstar : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, const char*, bool take = FALSE );
+ char* get( TQUObject *o ){ return o->payload.charstar.ptr; }
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * );
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+
+};
+extern TQ_EXPORT TQUType_charstar static_TQUType_charstar;
+
+// {44C2A547-01E7-4e56-8559-35AF9D2F42B7}
+extern const TQUuid TID_TQUType_TQString;
+
+struct TQ_EXPORT TQUType_TQString : public TQUType
+{
+ const TQUuid *uuid() const;
+ const char *desc() const;
+
+ void set( TQUObject *, const TQString & );
+ TQString &get( TQUObject * o ) { return *(TQString*)o->payload.ptr; }
+
+ bool canConvertFrom( TQUObject *, TQUType * );
+ bool canConvertTo( TQUObject *, TQUType * );
+ bool convertFrom( TQUObject *, TQUType * );
+ bool convertTo( TQUObject *, TQUType * );
+ void clear( TQUObject * );
+ int serializeTo( TQUObject *, TQUBuffer * );
+ int serializeFrom( TQUObject *, TQUBuffer * );
+
+};
+extern TQ_EXPORT TQUType_TQString static_TQUType_TQString;
+
+
+#endif // TQUCOM_P_H
diff --git a/tqtinterface/qt4/src/tools/tqunicodetables.cpp b/tqtinterface/qt4/src/tools/tqunicodetables.cpp
new file mode 100644
index 0000000..750dcd5
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqunicodetables.cpp
@@ -0,0 +1,13240 @@
+/****************************************************************************
+**
+** ???
+**
+** Copyright (C) 2002-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the kernel module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqunicodetables_p.h"
+
+/* -------------------------------------------------------------------------
+ * tqunicode information
+ * these tables are generated from the tqunicode reference file
+ * ftp://ftp.tqunicode.org/Public/3.2-Update/UnicodeData.txt
+ *
+ * Lars
+ * -------------------------------------------------------------------------
+ */
+
+/* Perl script to generate (run perl -x tools/qstringdata.cpp)
+
+#!perl
+
+sub numberize
+{
+ my(%r, $n, $id);
+ for $id ( @_ ) {
+ $i = $id;
+ $i="" if $i eq "EMPTY";
+ $r{$i}=$n++;
+ }
+ return %r;
+}
+
+
+sub readUnicodeDataLine {
+ $code = shift @_;
+ for $n (qw{
+ name category combining_class bidi_category
+ character_decomposition decimal_digit_value digit_value
+ numeric_value mirrored oldname comment
+ uppercase lowercase titlecase})
+ {
+ $id = shift @_;
+ $codes = "${n}_code";
+ if ( defined %$codes && defined $$codes{$id} ) {
+ $id = $$codes{$id};
+ }
+ ${$n}{$code}=$id;
+ }
+ $decomp = $character_decomposition{$code};
+ if ( length $decomp == 0 ) {
+ $decomp = "<single>";
+ }
+ if (substr($decomp, 0, 1) ne '<') {
+ $decomp = "<canonical> " . $decomp;
+ }
+ @_ = split(" ", $decomp);
+ $tag = shift @_;
+ $tag = $character_decomposition_tag{$tag};
+ $decomp = join( ", 0x", @_ );
+ $decomp = "0x".$decomp;
+ $decomposition{$code} = $decomp;
+ $decomposition_tag{$code} = $tag;
+ $decomposition_pos{$code} = $position;
+ $len = scalar(@_);
+ $decomposition_len{$code} = $len;
+
+# we use canonical decompositions longer than 1 char
+# we exlude Arabic ligatures from the table
+ if($len > 1 and $tag == 1) {
+# ligature to add...
+ $start = shift @_;
+ $ligature{$start} = $ligature{$start}." ".$code;
+ }
+
+# adjust position
+ if($len != 0) {
+ $position += $len + 3;
+ }
+}
+
+
+# Code to integer mappings...
+#
+%category_code = numberize(qw{
+ EMPTY
+ Mn Mc Me
+ Nd Nl No
+ Zs Zl Zp
+ Cc Cf Cs Co Cn
+
+ Lu Ll Lt Lm Lo
+ Pc Pd Ps Pe Pi Pf Po
+ Sm Sc Sk So
+});
+%bidi_category_code = numberize(qw{
+ L R EN ES ET AN CS B S WS ON LRE LRO AL RLE RLO PDF NSM BN});
+%character_decomposition_tag = numberize(qw{
+ <single> <canonical> <font> <noBreak> <initial> <medial>
+ <final> <isolated> <circle> <super> <sub> <vertical>
+ <wide> <narrow> <small> <square> <compat> <fraction>
+});
+%mirrored_code = numberize(qw{N Y});
+
+%joining_code = numberize(qw{U D R C});
+
+# we map AI and XX to AL for now, as we can't handle them any better
+%line_break_code = numberize(qw{OP CL QU GL NS EX SY
+ IS PR PO NU AL ID IN HY
+ BA BB B2
+ ZW CM
+ SA
+ BK CR LF SG CB SP
+});
+
+# Read data into hashes...
+#
+open IN, "UnicodeData.txt";
+$position = 1;
+while (<IN>) {
+ @fields = split /;/;
+ if ( length($fields[0]) < 5 ) {
+ if ( $fields[1] =~ /, First>/ ) {
+ $codeRangeBegin = $fields[0];
+ } elsif ( $fields[1] =~ /, Last>/ ) {
+ for ( $i=hex($codeRangeBegin); $i<=hex($fields[0]); $i+=1 ) {
+ @fields2 = @fields;
+ $fields2[0] = sprintf "%lX", $i;
+ readUnicodeDataLine @fields2;
+ }
+ } else {
+ readUnicodeDataLine @fields;
+ }
+ }
+}
+
+open IN2, "ArabicShaping.txt";
+$position = 1;
+while (<IN2>) {
+ @fields = split /;/;
+ $code = shift @fields;
+ $dummy = shift @fields;
+ $join = shift @fields;
+ $join =~ s/ //g;
+ $join = $joining_code{$join};
+ $joining{$code}=$join;
+}
+
+open IN3, "LineBreak.txt";
+$position = 1;
+while (<IN3>) {
+ @fields = split /;/;
+ $code = shift @fields;
+ $break = shift @fields;
+ if (length($break) > 0) {
+ chomp $break;
+ $break =~ s/ .*$//;
+
+ $from = $code;
+ $to = $code;
+ if ( length($code) > 5 ) {
+ $from =~ s,\.\..*,,;
+ $to =~ s/......//;
+# print "$from..$to = $break\n";
+ }
+ if($break eq "AI") {
+ $break = "AL";
+ }
+ if($break eq "XX") {
+ $break = "AL";
+ }
+ for ( $i=hex($from); $i<=hex($to); $i+=1 ) {
+ $breaks{sprintf("%04X",$i)}=$line_break_code{$break};
+ }
+ }
+}
+
+# Build pages...
+#
+$rowtable_txt = "";
+$row_txt = "";
+$pos = 1;
+for $row ( 0..255 ) {
+ $nonzero=0;
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$row,$cell);
+ $info = $category{$code};
+ $info = 0 if !defined $info;
+ $txt .= "\n " if $cell%8 == 0;
+ $txt .= "$info, ";
+ }
+ $therow = $row{$txt};
+ if ( !defined $therow ) {
+ $therow = sprintf("%d",$pos);
+ $row_txt = $row_txt."$txt\n";
+ $row{$txt}=$therow;
+ $pos += 1;
+ $size += 256;
+ }
+ $rowtable_txt .= "\n " if $row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+print "// START OF GENERATED DATA\n\n";
+print "#ifndef TQT_NO_UNICODETABLES\n\n";
+
+# Print pages...
+#
+
+print "const TQ_UINT8 TQUnicodeTables::tqunicode_info[] = {";
+print $rowtable_txt;
+$size += 256;
+print "\n\n";
+print $row_txt;
+print "};\n\n";
+print "// $size bytes\n\n";
+
+# Build decomposition tables
+#
+$rowtable_txt = "";
+$row_txt = "";
+$table_txt =
+ "const TQ_UINT16 TQUnicodeTables::decomposition_map[] = {\n 0,\n";
+$pos = 1;
+for $row ( 0..255 ) {
+ $nonzero=0;
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$row,$cell);
+ $txt .= "\n " if $cell%8 == 0;
+ if( $decomposition_tag{$code} != 0 ) {
+ $txt .= " $decomposition_pos{$code},";
+ $table_txt .= " $decomposition_tag{$code},";
+ $table_txt .= " 0x$code,";
+ $table_txt .= " $decomposition{$code}, 0,\n";
+ $size += 2 * $decomposition_len{$code} + 6;
+ } else {
+ $txt .= " 0,";
+ }
+ }
+ $therow = $row{$txt};
+ if ( !defined $therow ) {
+ $therow = sprintf("%d",$pos);
+ $row_txt = $row_txt."$txt\n";
+ $row{$txt}=$therow;
+ $pos += 1;
+ $size += 512;
+ }
+ $rowtable_txt .= "\n " if $row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print decomposition tables
+#
+print "$table_txt\n};\n\n";
+
+print "const TQ_UINT16 TQUnicodeTables::decomposition_info[] = {";
+print "$rowtable_txt\n";
+$size += 512;
+print $row_txt;
+print "};\n\n";
+print "// $size bytes\n\n";
+
+
+# build ligature tables
+#
+$size = 0;
+$position = 1;
+$pos = 1;
+$rowtable_txt = "";
+$row_txt = "";
+$table_txt =
+ "const TQ_UINT16 TQUnicodeTables::ligature_map[] = {\n 0,\n";
+for $lig_row ( 0..255 ) {
+ $nonzero=0;
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$lig_row,$cell);
+ $txt .= "\n " if $cell%8 == 0;
+ if( defined $ligature{$code} ) {
+ $txt .= " $position,";
+ @ligature = split(" ", $ligature{$code});
+# we need to sort ligatures according to their length.
+# long ones have to come first!
+ @ligature_sort = sort { $decomposition_len{$b} <=> $decomposition_len{$a} } @ligature;
+# now tqreplace each code by its position in
+# the decomposition map.
+ undef(@lig_pos);
+ for $n (@ligature_sort) {
+ push(@lig_pos, $decomposition_pos{$n});
+ }
+# debug info
+ if( 0 ) {
+ print "ligatures: $ligature{$code}\n";
+ $sort = join(" ", @ligature_sort);
+ print "sorted : $sort\n";
+ }
+ $lig = join(", ", @lig_pos);
+ $table_txt .= " $lig, 0,\n";
+ $size += 2 * scalar(@ligature) + 2;
+ $position += scalar(@ligature) + 1;
+ } else {
+ $txt .= " 0,";
+ }
+ }
+ $therow = $lig_row{$txt};
+ if ( !defined $therow ) {
+ $therow = sprintf("%d",$pos);
+ $row_txt = $row_txt."$txt\n";
+ $lig_row{$txt}=$therow;
+ $pos += 1;
+ $size += 512;
+ }
+ $rowtable_txt .= "\n " if $lig_row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print ligature tables
+#
+print "$table_txt\n};\n\n";
+print "const TQ_UINT16 TQUnicodeTables::ligature_info[] = {";
+print "$rowtable_txt\n\n";
+$size+=512;
+print $row_txt;
+print "};\n\n";
+print "// $size bytes\n\n";
+
+
+
+# Build direction/joining/mirrored pages...
+#
+$rowtable_txt = "";
+$row_txt = "";
+$pos = 1;
+for $dir_row ( 0..255 ) {
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$dir_row,$cell);
+ $dir = $bidi_category{$code};
+ $dir = 0 if !defined $dir;
+ $join = $joining{$code};
+ $join = 0 if !defined $join;
+ $mirr = $mirrored{$code};
+ $mirr = 0 if !defined $mirr;
+ $info = $dir + 32*$join + 128*$mirr;
+ $txt .= "\n " if $cell%8 == 0;
+ $txt .= "$info, ";
+ }
+ $therow = $dir_row{$txt};
+ if ( !defined $therow ) {
+ $therow = sprintf("%d",$pos);
+ $row_txt = $row_txt."$txt\n";
+ $dir_row{$txt}=$therow;
+ $pos += 1;
+ $size+=256;
+ }
+ $rowtable_txt .= "\n " if $dir_row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print pages...
+#
+print "const TQ_UINT8 TQUnicodeTables::direction_info[] = {";
+print "$rowtable_txt\n\n";
+$size+=256;
+print $row_txt;
+print "};\n\n";
+print "// $size bytes\n\n";
+
+# Build table of combining classes
+#
+$rowtable_txt = "";
+$row_txt = "";
+$pos = 1;
+for $combining_row ( 0..255 ) {
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$combining_row,$cell);
+ $info = $combining_class{$code};
+ $info = 0 if !defined $info;
+ $txt .= "\n " if $cell%8 == 0;
+ $txt .= "$info, ";
+ }
+ $therow = $combining_row{$txt};
+ if ( !defined $therow ) {
+ $therow = sprintf("%d",$pos);
+ $row_txt = $row_txt."$txt\n";
+ $combining_row{$txt}=$therow;
+ $pos += 1;
+ $size += 256;
+ }
+ $rowtable_txt .= "\n " if $combining_row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print pages...
+#
+print "const TQ_UINT8 TQUnicodeTables::combining_info[] = {";
+print "$rowtable_txt\n\n";
+$size+=256;
+print $row_txt;
+print "};\n\n";
+print "// $size bytes\n\n";
+
+# Build case info
+#
+$rowtable_txt = "";
+$row_txt = "";
+$pos = 1;
+for $row ( 0..255 ) {
+ $nonzero=0;
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$row,$cell);
+ $info = $uppercase{$code};
+ if ( length( $info ) eq 0 ) {
+ $info = $lowercase{$code};
+ }
+ $info =~ s/^0+//;
+ if ( length( $info ) eq 0 ) {
+ $info = "0";
+ } else {
+ $info = "0x".lc($info);
+ }
+ if ( length( $info ) ne 1 ) {
+ $nonzero = 1;
+ }
+ $txt .= "\n " if $cell%8 == 0;
+ $txt .= "$info, ";
+ }
+ $therow = $case_row{$txt};
+ if ( !defined $therow && $nonzero ne 0 ) {
+ $therow = sprintf("%d",$pos);
+ $row_txt = $row_txt."$txt\n";
+ $case_row{$txt}=$therow;
+ $pos += 1;
+ $size += 512;
+ }
+ $rowtable_txt .= "\n " if $row%8 == 0;
+ if ( $nonzero ne 0 ) {
+ $rowtable_txt .= "$therow, ";
+ } else {
+ $rowtable_txt .= "0, ";
+ }
+}
+
+# Print pages...
+#
+print "const TQ_UINT16 TQUnicodeTables::case_info[] = {";
+print "$rowtable_txt\n\n";
+$size+=512;
+print $row_txt;
+print "};\n";
+print "// $size bytes\n\n";
+
+# Build decimal info
+#
+$rowtable_txt = "";
+$row_txt = "";
+$pos = 1;
+for $row ( 0..255 ) {
+ $nonzero=0;
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$row,$cell);
+ $info = $digit_value{$code};
+ if ( length( $info ) eq 0 ) {
+ $info = -1;
+ } else {
+ $nonzero = 1;
+ }
+ $txt .= "\n " if $cell%8 == 0;
+ $txt .= "$info, ";
+ }
+ $therow = $decimal_row{$txt};
+ if ( !defined $therow && $nonzero ne 0 ) {
+ $therow = sprintf("%d",$pos);
+ $row_txt = $row_txt."$txt\n";
+ $decimal_row{$txt}=$therow;
+ $pos += 1;
+ $size += 256;
+ }
+ $rowtable_txt .= "\n " if $row%8 == 0;
+ if ( $nonzero ne 0 ) {
+ $rowtable_txt .= "$therow, ";
+ } else {
+ $rowtable_txt .= "0, ";
+ }
+}
+
+# Print pages...
+#
+print "const TQ_INT8 TQUnicodeTables::decimal_info[] = {";
+print "$rowtable_txt\n\n";
+$size+=512;
+print $row_txt;
+print "};\n";
+print "// $size bytes\n\n";
+
+
+# Build line break info
+#
+$rowtable_txt = "";
+$row_txt = "";
+$pos = 1;
+for $row ( 0..255 ) {
+ $txt = "";
+ for $cell ( 0..255 ) {
+ $code = sprintf("%02X%02X",$row,$cell);
+ $info = $breaks{$code};
+ if ( length( $info ) eq 0 ) {
+ $info = $line_break_code{"AL"};
+ }
+ $txt .= "\n " if $cell%8 == 0;
+ $txt .= "$info, ";
+ }
+ $therow = $lb_row{$txt};
+ if ( !defined $therow ) {
+ $therow = sprintf("%d",$pos);
+ $row_txt = $row_txt."$txt\n";
+ $lb_row{$txt}=$therow;
+ $pos += 1;
+ $size += 256;
+ }
+ $rowtable_txt .= "\n " if $row%8 == 0;
+ $rowtable_txt .= "$therow, ";
+}
+
+# Print pages...
+#
+print "const TQ_UINT8 TQUnicodeTables::line_break_info[] = {";
+print "$rowtable_txt\n\n";
+$size+=512;
+print $row_txt;
+print "};\n";
+print "// $size bytes\n\n";
+
+
+
+print "#endif\n\n";
+print "// END OF GENERATED DATA\n\n";
+
+
+__END__
+
+*/
+
+// START OF GENERATED DATA
+
+#ifndef TQT_NO_UNICODETABLES
+
+const TQ_UINT8 TQUnicodeTables::tqunicode_info[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 9, 9, 9, 9, 9, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 30, 9, 9, 9, 38, 39,
+ 40, 41, 42, 43, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 44, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 45,
+ 22, 22, 22, 22, 46, 9, 9, 9,
+ 9, 9, 9, 9, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 47,
+ 48, 48, 48, 48, 48, 48, 48, 48,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 49, 49, 49, 49, 49, 49, 49,
+ 49, 22, 50, 51, 22, 52, 53, 54,
+
+
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 7, 26, 26, 26, 28, 26, 26, 26,
+ 22, 23, 26, 27, 26, 21, 26, 26,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 27, 27, 27, 26,
+ 26, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 22, 26, 23, 29, 20,
+ 29, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 22, 27, 23, 27, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 7, 26, 28, 28, 28, 28, 30, 30,
+ 29, 30, 16, 24, 27, 21, 30, 29,
+ 30, 27, 6, 6, 29, 16, 30, 26,
+ 29, 6, 16, 25, 6, 6, 6, 26,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 27,
+ 15, 15, 15, 15, 15, 15, 15, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 27,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 16, 15, 16, 15, 16, 15, 16, 15,
+ 16, 15, 16, 15, 16, 15, 16, 15,
+ 16, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 15, 16, 15, 16, 15, 16, 16,
+ 16, 15, 15, 16, 15, 16, 15, 15,
+ 16, 15, 15, 15, 16, 16, 15, 15,
+ 15, 15, 16, 15, 15, 16, 15, 15,
+ 15, 16, 16, 16, 15, 15, 16, 15,
+ 15, 16, 15, 16, 15, 16, 15, 15,
+ 16, 15, 16, 16, 15, 16, 15, 15,
+ 16, 15, 15, 15, 16, 15, 16, 15,
+ 15, 16, 16, 19, 15, 16, 16, 16,
+ 19, 19, 19, 19, 15, 17, 16, 15,
+ 17, 16, 15, 17, 16, 15, 16, 15,
+ 16, 15, 16, 15, 16, 15, 16, 15,
+ 16, 15, 16, 15, 16, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 16, 15, 17, 16, 15, 16, 15, 15,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 0, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 0, 0,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 29, 29, 18, 18, 18, 18, 18,
+ 18, 18, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 18, 18, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29,
+ 18, 18, 18, 18, 18, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 18, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 29, 29, 0, 0,
+ 0, 0, 18, 0, 0, 0, 26, 0,
+ 0, 0, 0, 0, 29, 29, 15, 26,
+ 15, 15, 15, 0, 15, 0, 15, 15,
+ 16, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 0, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 0,
+ 16, 16, 15, 15, 15, 16, 16, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 16, 16, 16, 16, 15, 16, 27, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 30, 1, 1, 1, 1, 0,
+ 3, 3, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 15, 16, 15, 16, 15, 16, 15,
+ 16, 15, 16, 15, 16, 15, 16, 0,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 0, 0,
+ 15, 16, 0, 0, 0, 0, 0, 0,
+
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 0,
+ 0, 18, 26, 26, 26, 26, 26, 26,
+ 0, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 0, 26, 21, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 0, 1, 1, 1, 26, 1,
+ 26, 1, 1, 26, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 19, 19, 19, 26, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 26, 0, 0, 0, 26,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 18, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 26, 26, 19, 19,
+ 1, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 26, 19, 1, 1,
+ 1, 1, 1, 1, 1, 11, 3, 1,
+ 1, 1, 1, 1, 1, 18, 18, 1,
+ 1, 30, 1, 1, 1, 1, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 19, 19, 19, 30, 30, 0,
+
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 0, 11,
+ 19, 1, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 19, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 1, 1, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 0, 1, 19, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 2, 1, 0, 0,
+ 19, 1, 1, 1, 1, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 1, 1, 26, 26, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 26, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 19,
+ 19, 0, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 0, 0, 0, 19, 19,
+ 19, 19, 0, 0, 1, 0, 2, 2,
+ 2, 1, 1, 1, 1, 0, 0, 2,
+ 2, 0, 0, 2, 2, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 19, 19, 0, 19,
+ 19, 19, 1, 1, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 19, 19, 28, 28, 6, 6, 6, 6,
+ 6, 6, 30, 0, 0, 0, 0, 0,
+
+ 0, 0, 1, 0, 0, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 19,
+ 19, 0, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 0, 19, 19, 0,
+ 19, 19, 0, 0, 1, 0, 2, 2,
+ 2, 1, 1, 0, 0, 0, 0, 1,
+ 1, 0, 0, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 19, 19, 19, 19, 0, 19, 0,
+ 0, 0, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 1, 1, 19, 19, 19, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 0, 19, 0, 19,
+ 19, 19, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 0, 19, 19, 19,
+ 19, 19, 0, 0, 1, 19, 2, 2,
+ 2, 1, 1, 1, 1, 1, 0, 1,
+ 1, 2, 0, 2, 2, 1, 0, 0,
+ 19, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 0, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 1, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 19,
+ 19, 0, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 0, 0, 19, 19,
+ 19, 19, 0, 0, 1, 19, 2, 1,
+ 2, 1, 1, 1, 0, 0, 0, 2,
+ 2, 0, 0, 2, 2, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1, 2,
+ 0, 0, 0, 0, 19, 19, 0, 19,
+ 19, 19, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 30, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 19, 0, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 19, 19,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 0, 19, 19, 0, 19, 0, 19, 19,
+ 0, 0, 0, 19, 19, 0, 0, 0,
+ 19, 19, 19, 0, 0, 0, 19, 19,
+ 19, 19, 19, 19, 19, 19, 0, 19,
+ 19, 19, 0, 0, 0, 0, 2, 2,
+ 1, 2, 2, 0, 0, 0, 2, 2,
+ 2, 0, 2, 2, 2, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 6, 6, 6, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 2, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 0, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 1, 1,
+ 1, 2, 2, 2, 2, 0, 1, 1,
+ 1, 0, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 0, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 2, 1,
+ 2, 2, 2, 2, 2, 0, 1, 2,
+ 2, 0, 2, 2, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0, 2, 2, 0,
+ 0, 0, 0, 0, 0, 0, 19, 0,
+ 19, 19, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 2, 2,
+ 2, 1, 1, 1, 0, 0, 2, 2,
+ 2, 0, 2, 2, 2, 1, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 2, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 0, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 0, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 0, 0, 1, 0, 0, 0, 0, 2,
+ 2, 2, 1, 1, 1, 0, 1, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 2, 26, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 1, 19, 19, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 28,
+ 19, 19, 19, 19, 19, 19, 18, 1,
+ 1, 1, 1, 1, 1, 1, 1, 26,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 19, 19, 0, 19, 0, 0, 19,
+ 19, 0, 19, 0, 0, 19, 0, 0,
+ 0, 0, 0, 0, 19, 19, 19, 19,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 0, 19, 19, 19, 0, 19, 0, 19,
+ 0, 0, 19, 19, 0, 19, 19, 19,
+ 19, 1, 19, 19, 1, 1, 1, 1,
+ 1, 1, 0, 1, 1, 19, 0, 0,
+ 19, 19, 19, 19, 19, 0, 18, 0,
+ 1, 1, 1, 1, 1, 1, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 0, 0, 19, 19, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 19, 30, 30, 30, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 30, 30, 30, 30, 30,
+ 1, 1, 30, 30, 30, 30, 30, 30,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 30, 1, 30, 1,
+ 30, 1, 22, 23, 22, 23, 2, 2,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2,
+ 1, 1, 1, 1, 1, 26, 1, 1,
+ 19, 19, 19, 19, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 30, 30,
+ 30, 30, 30, 30, 30, 30, 1, 30,
+ 30, 30, 30, 30, 30, 0, 0, 30,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 19, 19, 19, 19, 19,
+ 0, 19, 19, 0, 2, 1, 1, 1,
+ 1, 2, 1, 0, 0, 0, 1, 1,
+ 2, 1, 0, 0, 0, 0, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 26, 26, 26, 26,
+ 19, 19, 19, 19, 19, 19, 2, 2,
+ 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 0, 0, 26, 0, 0, 0, 0,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 0, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 0, 0,
+
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 0, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 0, 26, 26, 26, 26, 26, 26, 26,
+ 26, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 26, 26, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 7, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 22, 23, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 26, 26, 26, 5, 5,
+ 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 19, 19,
+ 19, 19, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 1, 1, 1, 26, 26, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 19, 19,
+ 19, 0, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 26, 26, 26, 18,
+ 26, 26, 26, 28, 19, 0, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 26, 26, 26, 26, 26, 26, 21, 26,
+ 26, 26, 26, 1, 1, 1, 11, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 18, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 16, 16,
+ 16, 16, 16, 16, 0, 0, 0, 0,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 15, 16, 15, 16, 15, 16,
+ 15, 16, 0, 0, 0, 0, 0, 0,
+
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 0, 0,
+ 15, 15, 15, 15, 15, 15, 0, 0,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 0, 0,
+ 15, 15, 15, 15, 15, 15, 0, 0,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 0, 15, 0, 15, 0, 15, 0, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 0, 0,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 16, 16, 16, 16, 16, 0, 16, 16,
+ 15, 15, 15, 15, 17, 29, 16, 29,
+ 29, 29, 16, 16, 16, 0, 16, 16,
+ 15, 15, 15, 15, 17, 29, 29, 29,
+ 16, 16, 16, 16, 0, 0, 16, 16,
+ 15, 15, 15, 15, 0, 29, 29, 29,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 15, 15, 15, 15, 15, 29, 29, 29,
+ 0, 0, 16, 16, 16, 0, 16, 16,
+ 15, 15, 15, 15, 17, 29, 29, 0,
+
+ 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 11, 11, 11, 11,
+ 21, 21, 21, 21, 21, 21, 26, 26,
+ 24, 25, 22, 24, 24, 25, 22, 24,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 8, 9, 11, 11, 11, 11, 11, 7,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 24, 25, 26, 26, 26, 26, 20,
+ 20, 26, 26, 26, 27, 22, 23, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 27, 0, 0, 0, 0, 26,
+ 0, 0, 0, 0, 0, 0, 0, 7,
+ 11, 11, 11, 11, 0, 0, 0, 0,
+ 0, 0, 11, 11, 11, 11, 11, 11,
+ 6, 16, 0, 0, 6, 6, 6, 6,
+ 6, 6, 27, 27, 27, 22, 23, 16,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 27, 27, 27, 22, 23, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 3, 3,
+ 3, 1, 3, 3, 3, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 30, 30, 15, 30, 30, 30, 30, 15,
+ 30, 30, 16, 15, 15, 15, 16, 16,
+ 15, 15, 15, 16, 30, 15, 30, 30,
+ 30, 15, 15, 15, 15, 15, 30, 30,
+ 30, 30, 30, 30, 15, 30, 15, 30,
+ 15, 30, 15, 15, 15, 15, 30, 16,
+ 15, 15, 30, 15, 16, 19, 19, 19,
+ 19, 16, 30, 0, 0, 16, 15, 15,
+ 27, 27, 27, 27, 27, 15, 16, 16,
+ 16, 16, 30, 27, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 27, 27, 27, 27, 27, 30, 30, 30,
+ 30, 30, 27, 27, 30, 30, 30, 30,
+ 27, 30, 30, 27, 30, 30, 27, 30,
+ 30, 30, 30, 30, 30, 30, 27, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 27, 27,
+ 30, 30, 27, 30, 27, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 27, 27, 27, 27, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 27, 27, 30, 30, 30, 30, 30, 30,
+ 30, 22, 23, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 27, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 22, 23, 26, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 0,
+
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 27,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 27, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 30, 30,
+ 0, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 27,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 30, 30, 30, 30, 0, 30, 30,
+ 30, 30, 0, 0, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 0, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 30, 0, 30,
+ 30, 30, 30, 0, 0, 0, 30, 0,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+ 0, 30, 30, 30, 30, 30, 30, 30,
+ 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 22, 23, 22, 23, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 30, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 0, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 22, 23,
+ 22, 23, 22, 23, 0, 0, 0, 0,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 22, 23, 22, 23, 22,
+ 23, 22, 23, 22, 23, 22, 23, 22,
+ 23, 22, 23, 22, 23, 22, 23, 22,
+ 23, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 22, 23, 22, 23, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 22, 23, 27, 27,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 0, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 0,
+
+ 7, 26, 26, 26, 30, 18, 19, 5,
+ 22, 23, 22, 23, 22, 23, 22, 23,
+ 22, 23, 30, 30, 22, 23, 22, 23,
+ 22, 23, 22, 23, 21, 22, 23, 23,
+ 30, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 1, 1, 1, 1, 1, 1,
+ 21, 18, 18, 18, 18, 18, 30, 30,
+ 5, 5, 5, 18, 19, 26, 30, 30,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 0, 1, 1, 29, 29, 18, 18, 19,
+ 21, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 20, 18, 18, 18, 19,
+
+ 0, 0, 0, 0, 0, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 0,
+ 0, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 30, 30, 6, 6, 6, 6, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 0, 0, 0,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 30,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 0, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+ 0, 0, 0, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 0,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 30,
+ 30, 30, 30, 30, 30, 30, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 16, 16, 16, 16, 16, 16, 16, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 16, 16, 16, 16, 16,
+ 0, 0, 0, 0, 0, 19, 1, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 27, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 19, 19, 19, 19, 19, 0, 19, 0,
+ 19, 19, 0, 19, 19, 0, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 22, 23,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 0, 0, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 28, 0, 0, 0,
+
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 26, 21, 21, 20, 20, 22, 23, 22,
+ 23, 22, 23, 22, 23, 22, 23, 22,
+ 23, 22, 23, 22, 23, 26, 26, 0,
+ 0, 26, 26, 26, 26, 20, 20, 20,
+ 26, 26, 26, 0, 26, 26, 26, 26,
+ 21, 22, 23, 22, 23, 22, 23, 26,
+ 26, 26, 27, 21, 27, 27, 27, 0,
+ 26, 28, 26, 26, 0, 0, 0, 0,
+ 19, 19, 19, 19, 19, 0, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 0, 0, 11,
+
+ 0, 26, 26, 26, 28, 26, 26, 26,
+ 22, 23, 26, 27, 26, 21, 26, 26,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 27, 27, 27, 26,
+ 26, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 22, 26, 23, 29, 20,
+ 29, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 22, 27, 23, 27, 22,
+ 23, 26, 22, 23, 26, 20, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 18, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 18, 18,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 0,
+ 0, 0, 19, 19, 19, 19, 19, 19,
+ 0, 0, 19, 19, 19, 19, 19, 19,
+ 0, 0, 19, 19, 19, 19, 19, 19,
+ 0, 0, 19, 19, 19, 0, 0, 0,
+ 28, 28, 27, 29, 30, 28, 28, 0,
+ 30, 27, 27, 27, 27, 30, 30, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 11, 11, 11, 30, 30, 0, 0,
+};
+
+// 14080 bytes
+
+const TQ_UINT16 TQUnicodeTables::decomposition_map[] = {
+ 0,
+ 3, 0x00A0, 0x0020, 0,
+ 16, 0x00A8, 0x0020, 0x0308, 0,
+ 9, 0x00AA, 0x0061, 0,
+ 16, 0x00AF, 0x0020, 0x0304, 0,
+ 9, 0x00B2, 0x0032, 0,
+ 9, 0x00B3, 0x0033, 0,
+ 16, 0x00B4, 0x0020, 0x0301, 0,
+ 16, 0x00B5, 0x03BC, 0,
+ 16, 0x00B8, 0x0020, 0x0327, 0,
+ 9, 0x00B9, 0x0031, 0,
+ 9, 0x00BA, 0x006F, 0,
+ 17, 0x00BC, 0x0031, 0x2044, 0x0034, 0,
+ 17, 0x00BD, 0x0031, 0x2044, 0x0032, 0,
+ 17, 0x00BE, 0x0033, 0x2044, 0x0034, 0,
+ 1, 0x00C0, 0x0041, 0x0300, 0,
+ 1, 0x00C1, 0x0041, 0x0301, 0,
+ 1, 0x00C2, 0x0041, 0x0302, 0,
+ 1, 0x00C3, 0x0041, 0x0303, 0,
+ 1, 0x00C4, 0x0041, 0x0308, 0,
+ 1, 0x00C5, 0x0041, 0x030A, 0,
+ 1, 0x00C7, 0x0043, 0x0327, 0,
+ 1, 0x00C8, 0x0045, 0x0300, 0,
+ 1, 0x00C9, 0x0045, 0x0301, 0,
+ 1, 0x00CA, 0x0045, 0x0302, 0,
+ 1, 0x00CB, 0x0045, 0x0308, 0,
+ 1, 0x00CC, 0x0049, 0x0300, 0,
+ 1, 0x00CD, 0x0049, 0x0301, 0,
+ 1, 0x00CE, 0x0049, 0x0302, 0,
+ 1, 0x00CF, 0x0049, 0x0308, 0,
+ 1, 0x00D1, 0x004E, 0x0303, 0,
+ 1, 0x00D2, 0x004F, 0x0300, 0,
+ 1, 0x00D3, 0x004F, 0x0301, 0,
+ 1, 0x00D4, 0x004F, 0x0302, 0,
+ 1, 0x00D5, 0x004F, 0x0303, 0,
+ 1, 0x00D6, 0x004F, 0x0308, 0,
+ 1, 0x00D9, 0x0055, 0x0300, 0,
+ 1, 0x00DA, 0x0055, 0x0301, 0,
+ 1, 0x00DB, 0x0055, 0x0302, 0,
+ 1, 0x00DC, 0x0055, 0x0308, 0,
+ 1, 0x00DD, 0x0059, 0x0301, 0,
+ 1, 0x00E0, 0x0061, 0x0300, 0,
+ 1, 0x00E1, 0x0061, 0x0301, 0,
+ 1, 0x00E2, 0x0061, 0x0302, 0,
+ 1, 0x00E3, 0x0061, 0x0303, 0,
+ 1, 0x00E4, 0x0061, 0x0308, 0,
+ 1, 0x00E5, 0x0061, 0x030A, 0,
+ 1, 0x00E7, 0x0063, 0x0327, 0,
+ 1, 0x00E8, 0x0065, 0x0300, 0,
+ 1, 0x00E9, 0x0065, 0x0301, 0,
+ 1, 0x00EA, 0x0065, 0x0302, 0,
+ 1, 0x00EB, 0x0065, 0x0308, 0,
+ 1, 0x00EC, 0x0069, 0x0300, 0,
+ 1, 0x00ED, 0x0069, 0x0301, 0,
+ 1, 0x00EE, 0x0069, 0x0302, 0,
+ 1, 0x00EF, 0x0069, 0x0308, 0,
+ 1, 0x00F1, 0x006E, 0x0303, 0,
+ 1, 0x00F2, 0x006F, 0x0300, 0,
+ 1, 0x00F3, 0x006F, 0x0301, 0,
+ 1, 0x00F4, 0x006F, 0x0302, 0,
+ 1, 0x00F5, 0x006F, 0x0303, 0,
+ 1, 0x00F6, 0x006F, 0x0308, 0,
+ 1, 0x00F9, 0x0075, 0x0300, 0,
+ 1, 0x00FA, 0x0075, 0x0301, 0,
+ 1, 0x00FB, 0x0075, 0x0302, 0,
+ 1, 0x00FC, 0x0075, 0x0308, 0,
+ 1, 0x00FD, 0x0079, 0x0301, 0,
+ 1, 0x00FF, 0x0079, 0x0308, 0,
+ 1, 0x0100, 0x0041, 0x0304, 0,
+ 1, 0x0101, 0x0061, 0x0304, 0,
+ 1, 0x0102, 0x0041, 0x0306, 0,
+ 1, 0x0103, 0x0061, 0x0306, 0,
+ 1, 0x0104, 0x0041, 0x0328, 0,
+ 1, 0x0105, 0x0061, 0x0328, 0,
+ 1, 0x0106, 0x0043, 0x0301, 0,
+ 1, 0x0107, 0x0063, 0x0301, 0,
+ 1, 0x0108, 0x0043, 0x0302, 0,
+ 1, 0x0109, 0x0063, 0x0302, 0,
+ 1, 0x010A, 0x0043, 0x0307, 0,
+ 1, 0x010B, 0x0063, 0x0307, 0,
+ 1, 0x010C, 0x0043, 0x030C, 0,
+ 1, 0x010D, 0x0063, 0x030C, 0,
+ 1, 0x010E, 0x0044, 0x030C, 0,
+ 1, 0x010F, 0x0064, 0x030C, 0,
+ 1, 0x0112, 0x0045, 0x0304, 0,
+ 1, 0x0113, 0x0065, 0x0304, 0,
+ 1, 0x0114, 0x0045, 0x0306, 0,
+ 1, 0x0115, 0x0065, 0x0306, 0,
+ 1, 0x0116, 0x0045, 0x0307, 0,
+ 1, 0x0117, 0x0065, 0x0307, 0,
+ 1, 0x0118, 0x0045, 0x0328, 0,
+ 1, 0x0119, 0x0065, 0x0328, 0,
+ 1, 0x011A, 0x0045, 0x030C, 0,
+ 1, 0x011B, 0x0065, 0x030C, 0,
+ 1, 0x011C, 0x0047, 0x0302, 0,
+ 1, 0x011D, 0x0067, 0x0302, 0,
+ 1, 0x011E, 0x0047, 0x0306, 0,
+ 1, 0x011F, 0x0067, 0x0306, 0,
+ 1, 0x0120, 0x0047, 0x0307, 0,
+ 1, 0x0121, 0x0067, 0x0307, 0,
+ 1, 0x0122, 0x0047, 0x0327, 0,
+ 1, 0x0123, 0x0067, 0x0327, 0,
+ 1, 0x0124, 0x0048, 0x0302, 0,
+ 1, 0x0125, 0x0068, 0x0302, 0,
+ 1, 0x0128, 0x0049, 0x0303, 0,
+ 1, 0x0129, 0x0069, 0x0303, 0,
+ 1, 0x012A, 0x0049, 0x0304, 0,
+ 1, 0x012B, 0x0069, 0x0304, 0,
+ 1, 0x012C, 0x0049, 0x0306, 0,
+ 1, 0x012D, 0x0069, 0x0306, 0,
+ 1, 0x012E, 0x0049, 0x0328, 0,
+ 1, 0x012F, 0x0069, 0x0328, 0,
+ 1, 0x0130, 0x0049, 0x0307, 0,
+ 16, 0x0132, 0x0049, 0x004A, 0,
+ 16, 0x0133, 0x0069, 0x006A, 0,
+ 1, 0x0134, 0x004A, 0x0302, 0,
+ 1, 0x0135, 0x006A, 0x0302, 0,
+ 1, 0x0136, 0x004B, 0x0327, 0,
+ 1, 0x0137, 0x006B, 0x0327, 0,
+ 1, 0x0139, 0x004C, 0x0301, 0,
+ 1, 0x013A, 0x006C, 0x0301, 0,
+ 1, 0x013B, 0x004C, 0x0327, 0,
+ 1, 0x013C, 0x006C, 0x0327, 0,
+ 1, 0x013D, 0x004C, 0x030C, 0,
+ 1, 0x013E, 0x006C, 0x030C, 0,
+ 16, 0x013F, 0x004C, 0x00B7, 0,
+ 16, 0x0140, 0x006C, 0x00B7, 0,
+ 1, 0x0143, 0x004E, 0x0301, 0,
+ 1, 0x0144, 0x006E, 0x0301, 0,
+ 1, 0x0145, 0x004E, 0x0327, 0,
+ 1, 0x0146, 0x006E, 0x0327, 0,
+ 1, 0x0147, 0x004E, 0x030C, 0,
+ 1, 0x0148, 0x006E, 0x030C, 0,
+ 16, 0x0149, 0x02BC, 0x006E, 0,
+ 1, 0x014C, 0x004F, 0x0304, 0,
+ 1, 0x014D, 0x006F, 0x0304, 0,
+ 1, 0x014E, 0x004F, 0x0306, 0,
+ 1, 0x014F, 0x006F, 0x0306, 0,
+ 1, 0x0150, 0x004F, 0x030B, 0,
+ 1, 0x0151, 0x006F, 0x030B, 0,
+ 1, 0x0154, 0x0052, 0x0301, 0,
+ 1, 0x0155, 0x0072, 0x0301, 0,
+ 1, 0x0156, 0x0052, 0x0327, 0,
+ 1, 0x0157, 0x0072, 0x0327, 0,
+ 1, 0x0158, 0x0052, 0x030C, 0,
+ 1, 0x0159, 0x0072, 0x030C, 0,
+ 1, 0x015A, 0x0053, 0x0301, 0,
+ 1, 0x015B, 0x0073, 0x0301, 0,
+ 1, 0x015C, 0x0053, 0x0302, 0,
+ 1, 0x015D, 0x0073, 0x0302, 0,
+ 1, 0x015E, 0x0053, 0x0327, 0,
+ 1, 0x015F, 0x0073, 0x0327, 0,
+ 1, 0x0160, 0x0053, 0x030C, 0,
+ 1, 0x0161, 0x0073, 0x030C, 0,
+ 1, 0x0162, 0x0054, 0x0327, 0,
+ 1, 0x0163, 0x0074, 0x0327, 0,
+ 1, 0x0164, 0x0054, 0x030C, 0,
+ 1, 0x0165, 0x0074, 0x030C, 0,
+ 1, 0x0168, 0x0055, 0x0303, 0,
+ 1, 0x0169, 0x0075, 0x0303, 0,
+ 1, 0x016A, 0x0055, 0x0304, 0,
+ 1, 0x016B, 0x0075, 0x0304, 0,
+ 1, 0x016C, 0x0055, 0x0306, 0,
+ 1, 0x016D, 0x0075, 0x0306, 0,
+ 1, 0x016E, 0x0055, 0x030A, 0,
+ 1, 0x016F, 0x0075, 0x030A, 0,
+ 1, 0x0170, 0x0055, 0x030B, 0,
+ 1, 0x0171, 0x0075, 0x030B, 0,
+ 1, 0x0172, 0x0055, 0x0328, 0,
+ 1, 0x0173, 0x0075, 0x0328, 0,
+ 1, 0x0174, 0x0057, 0x0302, 0,
+ 1, 0x0175, 0x0077, 0x0302, 0,
+ 1, 0x0176, 0x0059, 0x0302, 0,
+ 1, 0x0177, 0x0079, 0x0302, 0,
+ 1, 0x0178, 0x0059, 0x0308, 0,
+ 1, 0x0179, 0x005A, 0x0301, 0,
+ 1, 0x017A, 0x007A, 0x0301, 0,
+ 1, 0x017B, 0x005A, 0x0307, 0,
+ 1, 0x017C, 0x007A, 0x0307, 0,
+ 1, 0x017D, 0x005A, 0x030C, 0,
+ 1, 0x017E, 0x007A, 0x030C, 0,
+ 16, 0x017F, 0x0073, 0,
+ 1, 0x01A0, 0x004F, 0x031B, 0,
+ 1, 0x01A1, 0x006F, 0x031B, 0,
+ 1, 0x01AF, 0x0055, 0x031B, 0,
+ 1, 0x01B0, 0x0075, 0x031B, 0,
+ 16, 0x01C4, 0x0044, 0x017D, 0,
+ 16, 0x01C5, 0x0044, 0x017E, 0,
+ 16, 0x01C6, 0x0064, 0x017E, 0,
+ 16, 0x01C7, 0x004C, 0x004A, 0,
+ 16, 0x01C8, 0x004C, 0x006A, 0,
+ 16, 0x01C9, 0x006C, 0x006A, 0,
+ 16, 0x01CA, 0x004E, 0x004A, 0,
+ 16, 0x01CB, 0x004E, 0x006A, 0,
+ 16, 0x01CC, 0x006E, 0x006A, 0,
+ 1, 0x01CD, 0x0041, 0x030C, 0,
+ 1, 0x01CE, 0x0061, 0x030C, 0,
+ 1, 0x01CF, 0x0049, 0x030C, 0,
+ 1, 0x01D0, 0x0069, 0x030C, 0,
+ 1, 0x01D1, 0x004F, 0x030C, 0,
+ 1, 0x01D2, 0x006F, 0x030C, 0,
+ 1, 0x01D3, 0x0055, 0x030C, 0,
+ 1, 0x01D4, 0x0075, 0x030C, 0,
+ 1, 0x01D5, 0x00DC, 0x0304, 0,
+ 1, 0x01D6, 0x00FC, 0x0304, 0,
+ 1, 0x01D7, 0x00DC, 0x0301, 0,
+ 1, 0x01D8, 0x00FC, 0x0301, 0,
+ 1, 0x01D9, 0x00DC, 0x030C, 0,
+ 1, 0x01DA, 0x00FC, 0x030C, 0,
+ 1, 0x01DB, 0x00DC, 0x0300, 0,
+ 1, 0x01DC, 0x00FC, 0x0300, 0,
+ 1, 0x01DE, 0x00C4, 0x0304, 0,
+ 1, 0x01DF, 0x00E4, 0x0304, 0,
+ 1, 0x01E0, 0x0226, 0x0304, 0,
+ 1, 0x01E1, 0x0227, 0x0304, 0,
+ 1, 0x01E2, 0x00C6, 0x0304, 0,
+ 1, 0x01E3, 0x00E6, 0x0304, 0,
+ 1, 0x01E6, 0x0047, 0x030C, 0,
+ 1, 0x01E7, 0x0067, 0x030C, 0,
+ 1, 0x01E8, 0x004B, 0x030C, 0,
+ 1, 0x01E9, 0x006B, 0x030C, 0,
+ 1, 0x01EA, 0x004F, 0x0328, 0,
+ 1, 0x01EB, 0x006F, 0x0328, 0,
+ 1, 0x01EC, 0x01EA, 0x0304, 0,
+ 1, 0x01ED, 0x01EB, 0x0304, 0,
+ 1, 0x01EE, 0x01B7, 0x030C, 0,
+ 1, 0x01EF, 0x0292, 0x030C, 0,
+ 1, 0x01F0, 0x006A, 0x030C, 0,
+ 16, 0x01F1, 0x0044, 0x005A, 0,
+ 16, 0x01F2, 0x0044, 0x007A, 0,
+ 16, 0x01F3, 0x0064, 0x007A, 0,
+ 1, 0x01F4, 0x0047, 0x0301, 0,
+ 1, 0x01F5, 0x0067, 0x0301, 0,
+ 1, 0x01F8, 0x004E, 0x0300, 0,
+ 1, 0x01F9, 0x006E, 0x0300, 0,
+ 1, 0x01FA, 0x00C5, 0x0301, 0,
+ 1, 0x01FB, 0x00E5, 0x0301, 0,
+ 1, 0x01FC, 0x00C6, 0x0301, 0,
+ 1, 0x01FD, 0x00E6, 0x0301, 0,
+ 1, 0x01FE, 0x00D8, 0x0301, 0,
+ 1, 0x01FF, 0x00F8, 0x0301, 0,
+ 1, 0x0200, 0x0041, 0x030F, 0,
+ 1, 0x0201, 0x0061, 0x030F, 0,
+ 1, 0x0202, 0x0041, 0x0311, 0,
+ 1, 0x0203, 0x0061, 0x0311, 0,
+ 1, 0x0204, 0x0045, 0x030F, 0,
+ 1, 0x0205, 0x0065, 0x030F, 0,
+ 1, 0x0206, 0x0045, 0x0311, 0,
+ 1, 0x0207, 0x0065, 0x0311, 0,
+ 1, 0x0208, 0x0049, 0x030F, 0,
+ 1, 0x0209, 0x0069, 0x030F, 0,
+ 1, 0x020A, 0x0049, 0x0311, 0,
+ 1, 0x020B, 0x0069, 0x0311, 0,
+ 1, 0x020C, 0x004F, 0x030F, 0,
+ 1, 0x020D, 0x006F, 0x030F, 0,
+ 1, 0x020E, 0x004F, 0x0311, 0,
+ 1, 0x020F, 0x006F, 0x0311, 0,
+ 1, 0x0210, 0x0052, 0x030F, 0,
+ 1, 0x0211, 0x0072, 0x030F, 0,
+ 1, 0x0212, 0x0052, 0x0311, 0,
+ 1, 0x0213, 0x0072, 0x0311, 0,
+ 1, 0x0214, 0x0055, 0x030F, 0,
+ 1, 0x0215, 0x0075, 0x030F, 0,
+ 1, 0x0216, 0x0055, 0x0311, 0,
+ 1, 0x0217, 0x0075, 0x0311, 0,
+ 1, 0x0218, 0x0053, 0x0326, 0,
+ 1, 0x0219, 0x0073, 0x0326, 0,
+ 1, 0x021A, 0x0054, 0x0326, 0,
+ 1, 0x021B, 0x0074, 0x0326, 0,
+ 1, 0x021E, 0x0048, 0x030C, 0,
+ 1, 0x021F, 0x0068, 0x030C, 0,
+ 1, 0x0226, 0x0041, 0x0307, 0,
+ 1, 0x0227, 0x0061, 0x0307, 0,
+ 1, 0x0228, 0x0045, 0x0327, 0,
+ 1, 0x0229, 0x0065, 0x0327, 0,
+ 1, 0x022A, 0x00D6, 0x0304, 0,
+ 1, 0x022B, 0x00F6, 0x0304, 0,
+ 1, 0x022C, 0x00D5, 0x0304, 0,
+ 1, 0x022D, 0x00F5, 0x0304, 0,
+ 1, 0x022E, 0x004F, 0x0307, 0,
+ 1, 0x022F, 0x006F, 0x0307, 0,
+ 1, 0x0230, 0x022E, 0x0304, 0,
+ 1, 0x0231, 0x022F, 0x0304, 0,
+ 1, 0x0232, 0x0059, 0x0304, 0,
+ 1, 0x0233, 0x0079, 0x0304, 0,
+ 9, 0x02B0, 0x0068, 0,
+ 9, 0x02B1, 0x0266, 0,
+ 9, 0x02B2, 0x006A, 0,
+ 9, 0x02B3, 0x0072, 0,
+ 9, 0x02B4, 0x0279, 0,
+ 9, 0x02B5, 0x027B, 0,
+ 9, 0x02B6, 0x0281, 0,
+ 9, 0x02B7, 0x0077, 0,
+ 9, 0x02B8, 0x0079, 0,
+ 16, 0x02D8, 0x0020, 0x0306, 0,
+ 16, 0x02D9, 0x0020, 0x0307, 0,
+ 16, 0x02DA, 0x0020, 0x030A, 0,
+ 16, 0x02DB, 0x0020, 0x0328, 0,
+ 16, 0x02DC, 0x0020, 0x0303, 0,
+ 16, 0x02DD, 0x0020, 0x030B, 0,
+ 9, 0x02E0, 0x0263, 0,
+ 9, 0x02E1, 0x006C, 0,
+ 9, 0x02E2, 0x0073, 0,
+ 9, 0x02E3, 0x0078, 0,
+ 9, 0x02E4, 0x0295, 0,
+ 1, 0x0340, 0x0300, 0,
+ 1, 0x0341, 0x0301, 0,
+ 1, 0x0343, 0x0313, 0,
+ 1, 0x0344, 0x0308, 0x0301, 0,
+ 1, 0x0374, 0x02B9, 0,
+ 16, 0x037A, 0x0020, 0x0345, 0,
+ 1, 0x037E, 0x003B, 0,
+ 16, 0x0384, 0x0020, 0x0301, 0,
+ 1, 0x0385, 0x00A8, 0x0301, 0,
+ 1, 0x0386, 0x0391, 0x0301, 0,
+ 1, 0x0387, 0x00B7, 0,
+ 1, 0x0388, 0x0395, 0x0301, 0,
+ 1, 0x0389, 0x0397, 0x0301, 0,
+ 1, 0x038A, 0x0399, 0x0301, 0,
+ 1, 0x038C, 0x039F, 0x0301, 0,
+ 1, 0x038E, 0x03A5, 0x0301, 0,
+ 1, 0x038F, 0x03A9, 0x0301, 0,
+ 1, 0x0390, 0x03CA, 0x0301, 0,
+ 1, 0x03AA, 0x0399, 0x0308, 0,
+ 1, 0x03AB, 0x03A5, 0x0308, 0,
+ 1, 0x03AC, 0x03B1, 0x0301, 0,
+ 1, 0x03AD, 0x03B5, 0x0301, 0,
+ 1, 0x03AE, 0x03B7, 0x0301, 0,
+ 1, 0x03AF, 0x03B9, 0x0301, 0,
+ 1, 0x03B0, 0x03CB, 0x0301, 0,
+ 1, 0x03CA, 0x03B9, 0x0308, 0,
+ 1, 0x03CB, 0x03C5, 0x0308, 0,
+ 1, 0x03CC, 0x03BF, 0x0301, 0,
+ 1, 0x03CD, 0x03C5, 0x0301, 0,
+ 1, 0x03CE, 0x03C9, 0x0301, 0,
+ 16, 0x03D0, 0x03B2, 0,
+ 16, 0x03D1, 0x03B8, 0,
+ 16, 0x03D2, 0x03A5, 0,
+ 1, 0x03D3, 0x03D2, 0x0301, 0,
+ 1, 0x03D4, 0x03D2, 0x0308, 0,
+ 16, 0x03D5, 0x03C6, 0,
+ 16, 0x03D6, 0x03C0, 0,
+ 16, 0x03F0, 0x03BA, 0,
+ 16, 0x03F1, 0x03C1, 0,
+ 16, 0x03F2, 0x03C2, 0,
+ 16, 0x03F4, 0x0398, 0,
+ 16, 0x03F5, 0x03B5, 0,
+ 1, 0x0400, 0x0415, 0x0300, 0,
+ 1, 0x0401, 0x0415, 0x0308, 0,
+ 1, 0x0403, 0x0413, 0x0301, 0,
+ 1, 0x0407, 0x0406, 0x0308, 0,
+ 1, 0x040C, 0x041A, 0x0301, 0,
+ 1, 0x040D, 0x0418, 0x0300, 0,
+ 1, 0x040E, 0x0423, 0x0306, 0,
+ 1, 0x0419, 0x0418, 0x0306, 0,
+ 1, 0x0439, 0x0438, 0x0306, 0,
+ 1, 0x0450, 0x0435, 0x0300, 0,
+ 1, 0x0451, 0x0435, 0x0308, 0,
+ 1, 0x0453, 0x0433, 0x0301, 0,
+ 1, 0x0457, 0x0456, 0x0308, 0,
+ 1, 0x045C, 0x043A, 0x0301, 0,
+ 1, 0x045D, 0x0438, 0x0300, 0,
+ 1, 0x045E, 0x0443, 0x0306, 0,
+ 1, 0x0476, 0x0474, 0x030F, 0,
+ 1, 0x0477, 0x0475, 0x030F, 0,
+ 1, 0x04C1, 0x0416, 0x0306, 0,
+ 1, 0x04C2, 0x0436, 0x0306, 0,
+ 1, 0x04D0, 0x0410, 0x0306, 0,
+ 1, 0x04D1, 0x0430, 0x0306, 0,
+ 1, 0x04D2, 0x0410, 0x0308, 0,
+ 1, 0x04D3, 0x0430, 0x0308, 0,
+ 1, 0x04D6, 0x0415, 0x0306, 0,
+ 1, 0x04D7, 0x0435, 0x0306, 0,
+ 1, 0x04DA, 0x04D8, 0x0308, 0,
+ 1, 0x04DB, 0x04D9, 0x0308, 0,
+ 1, 0x04DC, 0x0416, 0x0308, 0,
+ 1, 0x04DD, 0x0436, 0x0308, 0,
+ 1, 0x04DE, 0x0417, 0x0308, 0,
+ 1, 0x04DF, 0x0437, 0x0308, 0,
+ 1, 0x04E2, 0x0418, 0x0304, 0,
+ 1, 0x04E3, 0x0438, 0x0304, 0,
+ 1, 0x04E4, 0x0418, 0x0308, 0,
+ 1, 0x04E5, 0x0438, 0x0308, 0,
+ 1, 0x04E6, 0x041E, 0x0308, 0,
+ 1, 0x04E7, 0x043E, 0x0308, 0,
+ 1, 0x04EA, 0x04E8, 0x0308, 0,
+ 1, 0x04EB, 0x04E9, 0x0308, 0,
+ 1, 0x04EC, 0x042D, 0x0308, 0,
+ 1, 0x04ED, 0x044D, 0x0308, 0,
+ 1, 0x04EE, 0x0423, 0x0304, 0,
+ 1, 0x04EF, 0x0443, 0x0304, 0,
+ 1, 0x04F0, 0x0423, 0x0308, 0,
+ 1, 0x04F1, 0x0443, 0x0308, 0,
+ 1, 0x04F2, 0x0423, 0x030B, 0,
+ 1, 0x04F3, 0x0443, 0x030B, 0,
+ 1, 0x04F4, 0x0427, 0x0308, 0,
+ 1, 0x04F5, 0x0447, 0x0308, 0,
+ 1, 0x04F8, 0x042B, 0x0308, 0,
+ 1, 0x04F9, 0x044B, 0x0308, 0,
+ 16, 0x0587, 0x0565, 0x0582, 0,
+ 1, 0x0622, 0x0627, 0x0653, 0,
+ 1, 0x0623, 0x0627, 0x0654, 0,
+ 1, 0x0624, 0x0648, 0x0654, 0,
+ 1, 0x0625, 0x0627, 0x0655, 0,
+ 1, 0x0626, 0x064A, 0x0654, 0,
+ 16, 0x0675, 0x0627, 0x0674, 0,
+ 16, 0x0676, 0x0648, 0x0674, 0,
+ 16, 0x0677, 0x06C7, 0x0674, 0,
+ 16, 0x0678, 0x064A, 0x0674, 0,
+ 1, 0x06C0, 0x06D5, 0x0654, 0,
+ 1, 0x06C2, 0x06C1, 0x0654, 0,
+ 1, 0x06D3, 0x06D2, 0x0654, 0,
+ 1, 0x0929, 0x0928, 0x093C, 0,
+ 1, 0x0931, 0x0930, 0x093C, 0,
+ 1, 0x0934, 0x0933, 0x093C, 0,
+ 1, 0x0958, 0x0915, 0x093C, 0,
+ 1, 0x0959, 0x0916, 0x093C, 0,
+ 1, 0x095A, 0x0917, 0x093C, 0,
+ 1, 0x095B, 0x091C, 0x093C, 0,
+ 1, 0x095C, 0x0921, 0x093C, 0,
+ 1, 0x095D, 0x0922, 0x093C, 0,
+ 1, 0x095E, 0x092B, 0x093C, 0,
+ 1, 0x095F, 0x092F, 0x093C, 0,
+ 1, 0x09CB, 0x09C7, 0x09BE, 0,
+ 1, 0x09CC, 0x09C7, 0x09D7, 0,
+ 1, 0x09DC, 0x09A1, 0x09BC, 0,
+ 1, 0x09DD, 0x09A2, 0x09BC, 0,
+ 1, 0x09DF, 0x09AF, 0x09BC, 0,
+ 1, 0x0A33, 0x0A32, 0x0A3C, 0,
+ 1, 0x0A36, 0x0A38, 0x0A3C, 0,
+ 1, 0x0A59, 0x0A16, 0x0A3C, 0,
+ 1, 0x0A5A, 0x0A17, 0x0A3C, 0,
+ 1, 0x0A5B, 0x0A1C, 0x0A3C, 0,
+ 1, 0x0A5E, 0x0A2B, 0x0A3C, 0,
+ 1, 0x0B48, 0x0B47, 0x0B56, 0,
+ 1, 0x0B4B, 0x0B47, 0x0B3E, 0,
+ 1, 0x0B4C, 0x0B47, 0x0B57, 0,
+ 1, 0x0B5C, 0x0B21, 0x0B3C, 0,
+ 1, 0x0B5D, 0x0B22, 0x0B3C, 0,
+ 1, 0x0B94, 0x0B92, 0x0BD7, 0,
+ 1, 0x0BCA, 0x0BC6, 0x0BBE, 0,
+ 1, 0x0BCB, 0x0BC7, 0x0BBE, 0,
+ 1, 0x0BCC, 0x0BC6, 0x0BD7, 0,
+ 1, 0x0C48, 0x0C46, 0x0C56, 0,
+ 1, 0x0CC0, 0x0CBF, 0x0CD5, 0,
+ 1, 0x0CC7, 0x0CC6, 0x0CD5, 0,
+ 1, 0x0CC8, 0x0CC6, 0x0CD6, 0,
+ 1, 0x0CCA, 0x0CC6, 0x0CC2, 0,
+ 1, 0x0CCB, 0x0CCA, 0x0CD5, 0,
+ 1, 0x0D4A, 0x0D46, 0x0D3E, 0,
+ 1, 0x0D4B, 0x0D47, 0x0D3E, 0,
+ 1, 0x0D4C, 0x0D46, 0x0D57, 0,
+ 1, 0x0DDA, 0x0DD9, 0x0DCA, 0,
+ 1, 0x0DDC, 0x0DD9, 0x0DCF, 0,
+ 1, 0x0DDD, 0x0DDC, 0x0DCA, 0,
+ 1, 0x0DDE, 0x0DD9, 0x0DDF, 0,
+ 16, 0x0E33, 0x0E4D, 0x0E32, 0,
+ 16, 0x0EB3, 0x0ECD, 0x0EB2, 0,
+ 16, 0x0EDC, 0x0EAB, 0x0E99, 0,
+ 16, 0x0EDD, 0x0EAB, 0x0EA1, 0,
+ 3, 0x0F0C, 0x0F0B, 0,
+ 1, 0x0F43, 0x0F42, 0x0FB7, 0,
+ 1, 0x0F4D, 0x0F4C, 0x0FB7, 0,
+ 1, 0x0F52, 0x0F51, 0x0FB7, 0,
+ 1, 0x0F57, 0x0F56, 0x0FB7, 0,
+ 1, 0x0F5C, 0x0F5B, 0x0FB7, 0,
+ 1, 0x0F69, 0x0F40, 0x0FB5, 0,
+ 1, 0x0F73, 0x0F71, 0x0F72, 0,
+ 1, 0x0F75, 0x0F71, 0x0F74, 0,
+ 1, 0x0F76, 0x0FB2, 0x0F80, 0,
+ 16, 0x0F77, 0x0FB2, 0x0F81, 0,
+ 1, 0x0F78, 0x0FB3, 0x0F80, 0,
+ 16, 0x0F79, 0x0FB3, 0x0F81, 0,
+ 1, 0x0F81, 0x0F71, 0x0F80, 0,
+ 1, 0x0F93, 0x0F92, 0x0FB7, 0,
+ 1, 0x0F9D, 0x0F9C, 0x0FB7, 0,
+ 1, 0x0FA2, 0x0FA1, 0x0FB7, 0,
+ 1, 0x0FA7, 0x0FA6, 0x0FB7, 0,
+ 1, 0x0FAC, 0x0FAB, 0x0FB7, 0,
+ 1, 0x0FB9, 0x0F90, 0x0FB5, 0,
+ 1, 0x1026, 0x1025, 0x102E, 0,
+ 1, 0x1E00, 0x0041, 0x0325, 0,
+ 1, 0x1E01, 0x0061, 0x0325, 0,
+ 1, 0x1E02, 0x0042, 0x0307, 0,
+ 1, 0x1E03, 0x0062, 0x0307, 0,
+ 1, 0x1E04, 0x0042, 0x0323, 0,
+ 1, 0x1E05, 0x0062, 0x0323, 0,
+ 1, 0x1E06, 0x0042, 0x0331, 0,
+ 1, 0x1E07, 0x0062, 0x0331, 0,
+ 1, 0x1E08, 0x00C7, 0x0301, 0,
+ 1, 0x1E09, 0x00E7, 0x0301, 0,
+ 1, 0x1E0A, 0x0044, 0x0307, 0,
+ 1, 0x1E0B, 0x0064, 0x0307, 0,
+ 1, 0x1E0C, 0x0044, 0x0323, 0,
+ 1, 0x1E0D, 0x0064, 0x0323, 0,
+ 1, 0x1E0E, 0x0044, 0x0331, 0,
+ 1, 0x1E0F, 0x0064, 0x0331, 0,
+ 1, 0x1E10, 0x0044, 0x0327, 0,
+ 1, 0x1E11, 0x0064, 0x0327, 0,
+ 1, 0x1E12, 0x0044, 0x032D, 0,
+ 1, 0x1E13, 0x0064, 0x032D, 0,
+ 1, 0x1E14, 0x0112, 0x0300, 0,
+ 1, 0x1E15, 0x0113, 0x0300, 0,
+ 1, 0x1E16, 0x0112, 0x0301, 0,
+ 1, 0x1E17, 0x0113, 0x0301, 0,
+ 1, 0x1E18, 0x0045, 0x032D, 0,
+ 1, 0x1E19, 0x0065, 0x032D, 0,
+ 1, 0x1E1A, 0x0045, 0x0330, 0,
+ 1, 0x1E1B, 0x0065, 0x0330, 0,
+ 1, 0x1E1C, 0x0228, 0x0306, 0,
+ 1, 0x1E1D, 0x0229, 0x0306, 0,
+ 1, 0x1E1E, 0x0046, 0x0307, 0,
+ 1, 0x1E1F, 0x0066, 0x0307, 0,
+ 1, 0x1E20, 0x0047, 0x0304, 0,
+ 1, 0x1E21, 0x0067, 0x0304, 0,
+ 1, 0x1E22, 0x0048, 0x0307, 0,
+ 1, 0x1E23, 0x0068, 0x0307, 0,
+ 1, 0x1E24, 0x0048, 0x0323, 0,
+ 1, 0x1E25, 0x0068, 0x0323, 0,
+ 1, 0x1E26, 0x0048, 0x0308, 0,
+ 1, 0x1E27, 0x0068, 0x0308, 0,
+ 1, 0x1E28, 0x0048, 0x0327, 0,
+ 1, 0x1E29, 0x0068, 0x0327, 0,
+ 1, 0x1E2A, 0x0048, 0x032E, 0,
+ 1, 0x1E2B, 0x0068, 0x032E, 0,
+ 1, 0x1E2C, 0x0049, 0x0330, 0,
+ 1, 0x1E2D, 0x0069, 0x0330, 0,
+ 1, 0x1E2E, 0x00CF, 0x0301, 0,
+ 1, 0x1E2F, 0x00EF, 0x0301, 0,
+ 1, 0x1E30, 0x004B, 0x0301, 0,
+ 1, 0x1E31, 0x006B, 0x0301, 0,
+ 1, 0x1E32, 0x004B, 0x0323, 0,
+ 1, 0x1E33, 0x006B, 0x0323, 0,
+ 1, 0x1E34, 0x004B, 0x0331, 0,
+ 1, 0x1E35, 0x006B, 0x0331, 0,
+ 1, 0x1E36, 0x004C, 0x0323, 0,
+ 1, 0x1E37, 0x006C, 0x0323, 0,
+ 1, 0x1E38, 0x1E36, 0x0304, 0,
+ 1, 0x1E39, 0x1E37, 0x0304, 0,
+ 1, 0x1E3A, 0x004C, 0x0331, 0,
+ 1, 0x1E3B, 0x006C, 0x0331, 0,
+ 1, 0x1E3C, 0x004C, 0x032D, 0,
+ 1, 0x1E3D, 0x006C, 0x032D, 0,
+ 1, 0x1E3E, 0x004D, 0x0301, 0,
+ 1, 0x1E3F, 0x006D, 0x0301, 0,
+ 1, 0x1E40, 0x004D, 0x0307, 0,
+ 1, 0x1E41, 0x006D, 0x0307, 0,
+ 1, 0x1E42, 0x004D, 0x0323, 0,
+ 1, 0x1E43, 0x006D, 0x0323, 0,
+ 1, 0x1E44, 0x004E, 0x0307, 0,
+ 1, 0x1E45, 0x006E, 0x0307, 0,
+ 1, 0x1E46, 0x004E, 0x0323, 0,
+ 1, 0x1E47, 0x006E, 0x0323, 0,
+ 1, 0x1E48, 0x004E, 0x0331, 0,
+ 1, 0x1E49, 0x006E, 0x0331, 0,
+ 1, 0x1E4A, 0x004E, 0x032D, 0,
+ 1, 0x1E4B, 0x006E, 0x032D, 0,
+ 1, 0x1E4C, 0x00D5, 0x0301, 0,
+ 1, 0x1E4D, 0x00F5, 0x0301, 0,
+ 1, 0x1E4E, 0x00D5, 0x0308, 0,
+ 1, 0x1E4F, 0x00F5, 0x0308, 0,
+ 1, 0x1E50, 0x014C, 0x0300, 0,
+ 1, 0x1E51, 0x014D, 0x0300, 0,
+ 1, 0x1E52, 0x014C, 0x0301, 0,
+ 1, 0x1E53, 0x014D, 0x0301, 0,
+ 1, 0x1E54, 0x0050, 0x0301, 0,
+ 1, 0x1E55, 0x0070, 0x0301, 0,
+ 1, 0x1E56, 0x0050, 0x0307, 0,
+ 1, 0x1E57, 0x0070, 0x0307, 0,
+ 1, 0x1E58, 0x0052, 0x0307, 0,
+ 1, 0x1E59, 0x0072, 0x0307, 0,
+ 1, 0x1E5A, 0x0052, 0x0323, 0,
+ 1, 0x1E5B, 0x0072, 0x0323, 0,
+ 1, 0x1E5C, 0x1E5A, 0x0304, 0,
+ 1, 0x1E5D, 0x1E5B, 0x0304, 0,
+ 1, 0x1E5E, 0x0052, 0x0331, 0,
+ 1, 0x1E5F, 0x0072, 0x0331, 0,
+ 1, 0x1E60, 0x0053, 0x0307, 0,
+ 1, 0x1E61, 0x0073, 0x0307, 0,
+ 1, 0x1E62, 0x0053, 0x0323, 0,
+ 1, 0x1E63, 0x0073, 0x0323, 0,
+ 1, 0x1E64, 0x015A, 0x0307, 0,
+ 1, 0x1E65, 0x015B, 0x0307, 0,
+ 1, 0x1E66, 0x0160, 0x0307, 0,
+ 1, 0x1E67, 0x0161, 0x0307, 0,
+ 1, 0x1E68, 0x1E62, 0x0307, 0,
+ 1, 0x1E69, 0x1E63, 0x0307, 0,
+ 1, 0x1E6A, 0x0054, 0x0307, 0,
+ 1, 0x1E6B, 0x0074, 0x0307, 0,
+ 1, 0x1E6C, 0x0054, 0x0323, 0,
+ 1, 0x1E6D, 0x0074, 0x0323, 0,
+ 1, 0x1E6E, 0x0054, 0x0331, 0,
+ 1, 0x1E6F, 0x0074, 0x0331, 0,
+ 1, 0x1E70, 0x0054, 0x032D, 0,
+ 1, 0x1E71, 0x0074, 0x032D, 0,
+ 1, 0x1E72, 0x0055, 0x0324, 0,
+ 1, 0x1E73, 0x0075, 0x0324, 0,
+ 1, 0x1E74, 0x0055, 0x0330, 0,
+ 1, 0x1E75, 0x0075, 0x0330, 0,
+ 1, 0x1E76, 0x0055, 0x032D, 0,
+ 1, 0x1E77, 0x0075, 0x032D, 0,
+ 1, 0x1E78, 0x0168, 0x0301, 0,
+ 1, 0x1E79, 0x0169, 0x0301, 0,
+ 1, 0x1E7A, 0x016A, 0x0308, 0,
+ 1, 0x1E7B, 0x016B, 0x0308, 0,
+ 1, 0x1E7C, 0x0056, 0x0303, 0,
+ 1, 0x1E7D, 0x0076, 0x0303, 0,
+ 1, 0x1E7E, 0x0056, 0x0323, 0,
+ 1, 0x1E7F, 0x0076, 0x0323, 0,
+ 1, 0x1E80, 0x0057, 0x0300, 0,
+ 1, 0x1E81, 0x0077, 0x0300, 0,
+ 1, 0x1E82, 0x0057, 0x0301, 0,
+ 1, 0x1E83, 0x0077, 0x0301, 0,
+ 1, 0x1E84, 0x0057, 0x0308, 0,
+ 1, 0x1E85, 0x0077, 0x0308, 0,
+ 1, 0x1E86, 0x0057, 0x0307, 0,
+ 1, 0x1E87, 0x0077, 0x0307, 0,
+ 1, 0x1E88, 0x0057, 0x0323, 0,
+ 1, 0x1E89, 0x0077, 0x0323, 0,
+ 1, 0x1E8A, 0x0058, 0x0307, 0,
+ 1, 0x1E8B, 0x0078, 0x0307, 0,
+ 1, 0x1E8C, 0x0058, 0x0308, 0,
+ 1, 0x1E8D, 0x0078, 0x0308, 0,
+ 1, 0x1E8E, 0x0059, 0x0307, 0,
+ 1, 0x1E8F, 0x0079, 0x0307, 0,
+ 1, 0x1E90, 0x005A, 0x0302, 0,
+ 1, 0x1E91, 0x007A, 0x0302, 0,
+ 1, 0x1E92, 0x005A, 0x0323, 0,
+ 1, 0x1E93, 0x007A, 0x0323, 0,
+ 1, 0x1E94, 0x005A, 0x0331, 0,
+ 1, 0x1E95, 0x007A, 0x0331, 0,
+ 1, 0x1E96, 0x0068, 0x0331, 0,
+ 1, 0x1E97, 0x0074, 0x0308, 0,
+ 1, 0x1E98, 0x0077, 0x030A, 0,
+ 1, 0x1E99, 0x0079, 0x030A, 0,
+ 16, 0x1E9A, 0x0061, 0x02BE, 0,
+ 1, 0x1E9B, 0x017F, 0x0307, 0,
+ 1, 0x1EA0, 0x0041, 0x0323, 0,
+ 1, 0x1EA1, 0x0061, 0x0323, 0,
+ 1, 0x1EA2, 0x0041, 0x0309, 0,
+ 1, 0x1EA3, 0x0061, 0x0309, 0,
+ 1, 0x1EA4, 0x00C2, 0x0301, 0,
+ 1, 0x1EA5, 0x00E2, 0x0301, 0,
+ 1, 0x1EA6, 0x00C2, 0x0300, 0,
+ 1, 0x1EA7, 0x00E2, 0x0300, 0,
+ 1, 0x1EA8, 0x00C2, 0x0309, 0,
+ 1, 0x1EA9, 0x00E2, 0x0309, 0,
+ 1, 0x1EAA, 0x00C2, 0x0303, 0,
+ 1, 0x1EAB, 0x00E2, 0x0303, 0,
+ 1, 0x1EAC, 0x1EA0, 0x0302, 0,
+ 1, 0x1EAD, 0x1EA1, 0x0302, 0,
+ 1, 0x1EAE, 0x0102, 0x0301, 0,
+ 1, 0x1EAF, 0x0103, 0x0301, 0,
+ 1, 0x1EB0, 0x0102, 0x0300, 0,
+ 1, 0x1EB1, 0x0103, 0x0300, 0,
+ 1, 0x1EB2, 0x0102, 0x0309, 0,
+ 1, 0x1EB3, 0x0103, 0x0309, 0,
+ 1, 0x1EB4, 0x0102, 0x0303, 0,
+ 1, 0x1EB5, 0x0103, 0x0303, 0,
+ 1, 0x1EB6, 0x1EA0, 0x0306, 0,
+ 1, 0x1EB7, 0x1EA1, 0x0306, 0,
+ 1, 0x1EB8, 0x0045, 0x0323, 0,
+ 1, 0x1EB9, 0x0065, 0x0323, 0,
+ 1, 0x1EBA, 0x0045, 0x0309, 0,
+ 1, 0x1EBB, 0x0065, 0x0309, 0,
+ 1, 0x1EBC, 0x0045, 0x0303, 0,
+ 1, 0x1EBD, 0x0065, 0x0303, 0,
+ 1, 0x1EBE, 0x00CA, 0x0301, 0,
+ 1, 0x1EBF, 0x00EA, 0x0301, 0,
+ 1, 0x1EC0, 0x00CA, 0x0300, 0,
+ 1, 0x1EC1, 0x00EA, 0x0300, 0,
+ 1, 0x1EC2, 0x00CA, 0x0309, 0,
+ 1, 0x1EC3, 0x00EA, 0x0309, 0,
+ 1, 0x1EC4, 0x00CA, 0x0303, 0,
+ 1, 0x1EC5, 0x00EA, 0x0303, 0,
+ 1, 0x1EC6, 0x1EB8, 0x0302, 0,
+ 1, 0x1EC7, 0x1EB9, 0x0302, 0,
+ 1, 0x1EC8, 0x0049, 0x0309, 0,
+ 1, 0x1EC9, 0x0069, 0x0309, 0,
+ 1, 0x1ECA, 0x0049, 0x0323, 0,
+ 1, 0x1ECB, 0x0069, 0x0323, 0,
+ 1, 0x1ECC, 0x004F, 0x0323, 0,
+ 1, 0x1ECD, 0x006F, 0x0323, 0,
+ 1, 0x1ECE, 0x004F, 0x0309, 0,
+ 1, 0x1ECF, 0x006F, 0x0309, 0,
+ 1, 0x1ED0, 0x00D4, 0x0301, 0,
+ 1, 0x1ED1, 0x00F4, 0x0301, 0,
+ 1, 0x1ED2, 0x00D4, 0x0300, 0,
+ 1, 0x1ED3, 0x00F4, 0x0300, 0,
+ 1, 0x1ED4, 0x00D4, 0x0309, 0,
+ 1, 0x1ED5, 0x00F4, 0x0309, 0,
+ 1, 0x1ED6, 0x00D4, 0x0303, 0,
+ 1, 0x1ED7, 0x00F4, 0x0303, 0,
+ 1, 0x1ED8, 0x1ECC, 0x0302, 0,
+ 1, 0x1ED9, 0x1ECD, 0x0302, 0,
+ 1, 0x1EDA, 0x01A0, 0x0301, 0,
+ 1, 0x1EDB, 0x01A1, 0x0301, 0,
+ 1, 0x1EDC, 0x01A0, 0x0300, 0,
+ 1, 0x1EDD, 0x01A1, 0x0300, 0,
+ 1, 0x1EDE, 0x01A0, 0x0309, 0,
+ 1, 0x1EDF, 0x01A1, 0x0309, 0,
+ 1, 0x1EE0, 0x01A0, 0x0303, 0,
+ 1, 0x1EE1, 0x01A1, 0x0303, 0,
+ 1, 0x1EE2, 0x01A0, 0x0323, 0,
+ 1, 0x1EE3, 0x01A1, 0x0323, 0,
+ 1, 0x1EE4, 0x0055, 0x0323, 0,
+ 1, 0x1EE5, 0x0075, 0x0323, 0,
+ 1, 0x1EE6, 0x0055, 0x0309, 0,
+ 1, 0x1EE7, 0x0075, 0x0309, 0,
+ 1, 0x1EE8, 0x01AF, 0x0301, 0,
+ 1, 0x1EE9, 0x01B0, 0x0301, 0,
+ 1, 0x1EEA, 0x01AF, 0x0300, 0,
+ 1, 0x1EEB, 0x01B0, 0x0300, 0,
+ 1, 0x1EEC, 0x01AF, 0x0309, 0,
+ 1, 0x1EED, 0x01B0, 0x0309, 0,
+ 1, 0x1EEE, 0x01AF, 0x0303, 0,
+ 1, 0x1EEF, 0x01B0, 0x0303, 0,
+ 1, 0x1EF0, 0x01AF, 0x0323, 0,
+ 1, 0x1EF1, 0x01B0, 0x0323, 0,
+ 1, 0x1EF2, 0x0059, 0x0300, 0,
+ 1, 0x1EF3, 0x0079, 0x0300, 0,
+ 1, 0x1EF4, 0x0059, 0x0323, 0,
+ 1, 0x1EF5, 0x0079, 0x0323, 0,
+ 1, 0x1EF6, 0x0059, 0x0309, 0,
+ 1, 0x1EF7, 0x0079, 0x0309, 0,
+ 1, 0x1EF8, 0x0059, 0x0303, 0,
+ 1, 0x1EF9, 0x0079, 0x0303, 0,
+ 1, 0x1F00, 0x03B1, 0x0313, 0,
+ 1, 0x1F01, 0x03B1, 0x0314, 0,
+ 1, 0x1F02, 0x1F00, 0x0300, 0,
+ 1, 0x1F03, 0x1F01, 0x0300, 0,
+ 1, 0x1F04, 0x1F00, 0x0301, 0,
+ 1, 0x1F05, 0x1F01, 0x0301, 0,
+ 1, 0x1F06, 0x1F00, 0x0342, 0,
+ 1, 0x1F07, 0x1F01, 0x0342, 0,
+ 1, 0x1F08, 0x0391, 0x0313, 0,
+ 1, 0x1F09, 0x0391, 0x0314, 0,
+ 1, 0x1F0A, 0x1F08, 0x0300, 0,
+ 1, 0x1F0B, 0x1F09, 0x0300, 0,
+ 1, 0x1F0C, 0x1F08, 0x0301, 0,
+ 1, 0x1F0D, 0x1F09, 0x0301, 0,
+ 1, 0x1F0E, 0x1F08, 0x0342, 0,
+ 1, 0x1F0F, 0x1F09, 0x0342, 0,
+ 1, 0x1F10, 0x03B5, 0x0313, 0,
+ 1, 0x1F11, 0x03B5, 0x0314, 0,
+ 1, 0x1F12, 0x1F10, 0x0300, 0,
+ 1, 0x1F13, 0x1F11, 0x0300, 0,
+ 1, 0x1F14, 0x1F10, 0x0301, 0,
+ 1, 0x1F15, 0x1F11, 0x0301, 0,
+ 1, 0x1F18, 0x0395, 0x0313, 0,
+ 1, 0x1F19, 0x0395, 0x0314, 0,
+ 1, 0x1F1A, 0x1F18, 0x0300, 0,
+ 1, 0x1F1B, 0x1F19, 0x0300, 0,
+ 1, 0x1F1C, 0x1F18, 0x0301, 0,
+ 1, 0x1F1D, 0x1F19, 0x0301, 0,
+ 1, 0x1F20, 0x03B7, 0x0313, 0,
+ 1, 0x1F21, 0x03B7, 0x0314, 0,
+ 1, 0x1F22, 0x1F20, 0x0300, 0,
+ 1, 0x1F23, 0x1F21, 0x0300, 0,
+ 1, 0x1F24, 0x1F20, 0x0301, 0,
+ 1, 0x1F25, 0x1F21, 0x0301, 0,
+ 1, 0x1F26, 0x1F20, 0x0342, 0,
+ 1, 0x1F27, 0x1F21, 0x0342, 0,
+ 1, 0x1F28, 0x0397, 0x0313, 0,
+ 1, 0x1F29, 0x0397, 0x0314, 0,
+ 1, 0x1F2A, 0x1F28, 0x0300, 0,
+ 1, 0x1F2B, 0x1F29, 0x0300, 0,
+ 1, 0x1F2C, 0x1F28, 0x0301, 0,
+ 1, 0x1F2D, 0x1F29, 0x0301, 0,
+ 1, 0x1F2E, 0x1F28, 0x0342, 0,
+ 1, 0x1F2F, 0x1F29, 0x0342, 0,
+ 1, 0x1F30, 0x03B9, 0x0313, 0,
+ 1, 0x1F31, 0x03B9, 0x0314, 0,
+ 1, 0x1F32, 0x1F30, 0x0300, 0,
+ 1, 0x1F33, 0x1F31, 0x0300, 0,
+ 1, 0x1F34, 0x1F30, 0x0301, 0,
+ 1, 0x1F35, 0x1F31, 0x0301, 0,
+ 1, 0x1F36, 0x1F30, 0x0342, 0,
+ 1, 0x1F37, 0x1F31, 0x0342, 0,
+ 1, 0x1F38, 0x0399, 0x0313, 0,
+ 1, 0x1F39, 0x0399, 0x0314, 0,
+ 1, 0x1F3A, 0x1F38, 0x0300, 0,
+ 1, 0x1F3B, 0x1F39, 0x0300, 0,
+ 1, 0x1F3C, 0x1F38, 0x0301, 0,
+ 1, 0x1F3D, 0x1F39, 0x0301, 0,
+ 1, 0x1F3E, 0x1F38, 0x0342, 0,
+ 1, 0x1F3F, 0x1F39, 0x0342, 0,
+ 1, 0x1F40, 0x03BF, 0x0313, 0,
+ 1, 0x1F41, 0x03BF, 0x0314, 0,
+ 1, 0x1F42, 0x1F40, 0x0300, 0,
+ 1, 0x1F43, 0x1F41, 0x0300, 0,
+ 1, 0x1F44, 0x1F40, 0x0301, 0,
+ 1, 0x1F45, 0x1F41, 0x0301, 0,
+ 1, 0x1F48, 0x039F, 0x0313, 0,
+ 1, 0x1F49, 0x039F, 0x0314, 0,
+ 1, 0x1F4A, 0x1F48, 0x0300, 0,
+ 1, 0x1F4B, 0x1F49, 0x0300, 0,
+ 1, 0x1F4C, 0x1F48, 0x0301, 0,
+ 1, 0x1F4D, 0x1F49, 0x0301, 0,
+ 1, 0x1F50, 0x03C5, 0x0313, 0,
+ 1, 0x1F51, 0x03C5, 0x0314, 0,
+ 1, 0x1F52, 0x1F50, 0x0300, 0,
+ 1, 0x1F53, 0x1F51, 0x0300, 0,
+ 1, 0x1F54, 0x1F50, 0x0301, 0,
+ 1, 0x1F55, 0x1F51, 0x0301, 0,
+ 1, 0x1F56, 0x1F50, 0x0342, 0,
+ 1, 0x1F57, 0x1F51, 0x0342, 0,
+ 1, 0x1F59, 0x03A5, 0x0314, 0,
+ 1, 0x1F5B, 0x1F59, 0x0300, 0,
+ 1, 0x1F5D, 0x1F59, 0x0301, 0,
+ 1, 0x1F5F, 0x1F59, 0x0342, 0,
+ 1, 0x1F60, 0x03C9, 0x0313, 0,
+ 1, 0x1F61, 0x03C9, 0x0314, 0,
+ 1, 0x1F62, 0x1F60, 0x0300, 0,
+ 1, 0x1F63, 0x1F61, 0x0300, 0,
+ 1, 0x1F64, 0x1F60, 0x0301, 0,
+ 1, 0x1F65, 0x1F61, 0x0301, 0,
+ 1, 0x1F66, 0x1F60, 0x0342, 0,
+ 1, 0x1F67, 0x1F61, 0x0342, 0,
+ 1, 0x1F68, 0x03A9, 0x0313, 0,
+ 1, 0x1F69, 0x03A9, 0x0314, 0,
+ 1, 0x1F6A, 0x1F68, 0x0300, 0,
+ 1, 0x1F6B, 0x1F69, 0x0300, 0,
+ 1, 0x1F6C, 0x1F68, 0x0301, 0,
+ 1, 0x1F6D, 0x1F69, 0x0301, 0,
+ 1, 0x1F6E, 0x1F68, 0x0342, 0,
+ 1, 0x1F6F, 0x1F69, 0x0342, 0,
+ 1, 0x1F70, 0x03B1, 0x0300, 0,
+ 1, 0x1F71, 0x03AC, 0,
+ 1, 0x1F72, 0x03B5, 0x0300, 0,
+ 1, 0x1F73, 0x03AD, 0,
+ 1, 0x1F74, 0x03B7, 0x0300, 0,
+ 1, 0x1F75, 0x03AE, 0,
+ 1, 0x1F76, 0x03B9, 0x0300, 0,
+ 1, 0x1F77, 0x03AF, 0,
+ 1, 0x1F78, 0x03BF, 0x0300, 0,
+ 1, 0x1F79, 0x03CC, 0,
+ 1, 0x1F7A, 0x03C5, 0x0300, 0,
+ 1, 0x1F7B, 0x03CD, 0,
+ 1, 0x1F7C, 0x03C9, 0x0300, 0,
+ 1, 0x1F7D, 0x03CE, 0,
+ 1, 0x1F80, 0x1F00, 0x0345, 0,
+ 1, 0x1F81, 0x1F01, 0x0345, 0,
+ 1, 0x1F82, 0x1F02, 0x0345, 0,
+ 1, 0x1F83, 0x1F03, 0x0345, 0,
+ 1, 0x1F84, 0x1F04, 0x0345, 0,
+ 1, 0x1F85, 0x1F05, 0x0345, 0,
+ 1, 0x1F86, 0x1F06, 0x0345, 0,
+ 1, 0x1F87, 0x1F07, 0x0345, 0,
+ 1, 0x1F88, 0x1F08, 0x0345, 0,
+ 1, 0x1F89, 0x1F09, 0x0345, 0,
+ 1, 0x1F8A, 0x1F0A, 0x0345, 0,
+ 1, 0x1F8B, 0x1F0B, 0x0345, 0,
+ 1, 0x1F8C, 0x1F0C, 0x0345, 0,
+ 1, 0x1F8D, 0x1F0D, 0x0345, 0,
+ 1, 0x1F8E, 0x1F0E, 0x0345, 0,
+ 1, 0x1F8F, 0x1F0F, 0x0345, 0,
+ 1, 0x1F90, 0x1F20, 0x0345, 0,
+ 1, 0x1F91, 0x1F21, 0x0345, 0,
+ 1, 0x1F92, 0x1F22, 0x0345, 0,
+ 1, 0x1F93, 0x1F23, 0x0345, 0,
+ 1, 0x1F94, 0x1F24, 0x0345, 0,
+ 1, 0x1F95, 0x1F25, 0x0345, 0,
+ 1, 0x1F96, 0x1F26, 0x0345, 0,
+ 1, 0x1F97, 0x1F27, 0x0345, 0,
+ 1, 0x1F98, 0x1F28, 0x0345, 0,
+ 1, 0x1F99, 0x1F29, 0x0345, 0,
+ 1, 0x1F9A, 0x1F2A, 0x0345, 0,
+ 1, 0x1F9B, 0x1F2B, 0x0345, 0,
+ 1, 0x1F9C, 0x1F2C, 0x0345, 0,
+ 1, 0x1F9D, 0x1F2D, 0x0345, 0,
+ 1, 0x1F9E, 0x1F2E, 0x0345, 0,
+ 1, 0x1F9F, 0x1F2F, 0x0345, 0,
+ 1, 0x1FA0, 0x1F60, 0x0345, 0,
+ 1, 0x1FA1, 0x1F61, 0x0345, 0,
+ 1, 0x1FA2, 0x1F62, 0x0345, 0,
+ 1, 0x1FA3, 0x1F63, 0x0345, 0,
+ 1, 0x1FA4, 0x1F64, 0x0345, 0,
+ 1, 0x1FA5, 0x1F65, 0x0345, 0,
+ 1, 0x1FA6, 0x1F66, 0x0345, 0,
+ 1, 0x1FA7, 0x1F67, 0x0345, 0,
+ 1, 0x1FA8, 0x1F68, 0x0345, 0,
+ 1, 0x1FA9, 0x1F69, 0x0345, 0,
+ 1, 0x1FAA, 0x1F6A, 0x0345, 0,
+ 1, 0x1FAB, 0x1F6B, 0x0345, 0,
+ 1, 0x1FAC, 0x1F6C, 0x0345, 0,
+ 1, 0x1FAD, 0x1F6D, 0x0345, 0,
+ 1, 0x1FAE, 0x1F6E, 0x0345, 0,
+ 1, 0x1FAF, 0x1F6F, 0x0345, 0,
+ 1, 0x1FB0, 0x03B1, 0x0306, 0,
+ 1, 0x1FB1, 0x03B1, 0x0304, 0,
+ 1, 0x1FB2, 0x1F70, 0x0345, 0,
+ 1, 0x1FB3, 0x03B1, 0x0345, 0,
+ 1, 0x1FB4, 0x03AC, 0x0345, 0,
+ 1, 0x1FB6, 0x03B1, 0x0342, 0,
+ 1, 0x1FB7, 0x1FB6, 0x0345, 0,
+ 1, 0x1FB8, 0x0391, 0x0306, 0,
+ 1, 0x1FB9, 0x0391, 0x0304, 0,
+ 1, 0x1FBA, 0x0391, 0x0300, 0,
+ 1, 0x1FBB, 0x0386, 0,
+ 1, 0x1FBC, 0x0391, 0x0345, 0,
+ 16, 0x1FBD, 0x0020, 0x0313, 0,
+ 1, 0x1FBE, 0x03B9, 0,
+ 16, 0x1FBF, 0x0020, 0x0313, 0,
+ 16, 0x1FC0, 0x0020, 0x0342, 0,
+ 1, 0x1FC1, 0x00A8, 0x0342, 0,
+ 1, 0x1FC2, 0x1F74, 0x0345, 0,
+ 1, 0x1FC3, 0x03B7, 0x0345, 0,
+ 1, 0x1FC4, 0x03AE, 0x0345, 0,
+ 1, 0x1FC6, 0x03B7, 0x0342, 0,
+ 1, 0x1FC7, 0x1FC6, 0x0345, 0,
+ 1, 0x1FC8, 0x0395, 0x0300, 0,
+ 1, 0x1FC9, 0x0388, 0,
+ 1, 0x1FCA, 0x0397, 0x0300, 0,
+ 1, 0x1FCB, 0x0389, 0,
+ 1, 0x1FCC, 0x0397, 0x0345, 0,
+ 1, 0x1FCD, 0x1FBF, 0x0300, 0,
+ 1, 0x1FCE, 0x1FBF, 0x0301, 0,
+ 1, 0x1FCF, 0x1FBF, 0x0342, 0,
+ 1, 0x1FD0, 0x03B9, 0x0306, 0,
+ 1, 0x1FD1, 0x03B9, 0x0304, 0,
+ 1, 0x1FD2, 0x03CA, 0x0300, 0,
+ 1, 0x1FD3, 0x0390, 0,
+ 1, 0x1FD6, 0x03B9, 0x0342, 0,
+ 1, 0x1FD7, 0x03CA, 0x0342, 0,
+ 1, 0x1FD8, 0x0399, 0x0306, 0,
+ 1, 0x1FD9, 0x0399, 0x0304, 0,
+ 1, 0x1FDA, 0x0399, 0x0300, 0,
+ 1, 0x1FDB, 0x038A, 0,
+ 1, 0x1FDD, 0x1FFE, 0x0300, 0,
+ 1, 0x1FDE, 0x1FFE, 0x0301, 0,
+ 1, 0x1FDF, 0x1FFE, 0x0342, 0,
+ 1, 0x1FE0, 0x03C5, 0x0306, 0,
+ 1, 0x1FE1, 0x03C5, 0x0304, 0,
+ 1, 0x1FE2, 0x03CB, 0x0300, 0,
+ 1, 0x1FE3, 0x03B0, 0,
+ 1, 0x1FE4, 0x03C1, 0x0313, 0,
+ 1, 0x1FE5, 0x03C1, 0x0314, 0,
+ 1, 0x1FE6, 0x03C5, 0x0342, 0,
+ 1, 0x1FE7, 0x03CB, 0x0342, 0,
+ 1, 0x1FE8, 0x03A5, 0x0306, 0,
+ 1, 0x1FE9, 0x03A5, 0x0304, 0,
+ 1, 0x1FEA, 0x03A5, 0x0300, 0,
+ 1, 0x1FEB, 0x038E, 0,
+ 1, 0x1FEC, 0x03A1, 0x0314, 0,
+ 1, 0x1FED, 0x00A8, 0x0300, 0,
+ 1, 0x1FEE, 0x0385, 0,
+ 1, 0x1FEF, 0x0060, 0,
+ 1, 0x1FF2, 0x1F7C, 0x0345, 0,
+ 1, 0x1FF3, 0x03C9, 0x0345, 0,
+ 1, 0x1FF4, 0x03CE, 0x0345, 0,
+ 1, 0x1FF6, 0x03C9, 0x0342, 0,
+ 1, 0x1FF7, 0x1FF6, 0x0345, 0,
+ 1, 0x1FF8, 0x039F, 0x0300, 0,
+ 1, 0x1FF9, 0x038C, 0,
+ 1, 0x1FFA, 0x03A9, 0x0300, 0,
+ 1, 0x1FFB, 0x038F, 0,
+ 1, 0x1FFC, 0x03A9, 0x0345, 0,
+ 1, 0x1FFD, 0x00B4, 0,
+ 16, 0x1FFE, 0x0020, 0x0314, 0,
+ 1, 0x2000, 0x2002, 0,
+ 1, 0x2001, 0x2003, 0,
+ 16, 0x2002, 0x0020, 0,
+ 16, 0x2003, 0x0020, 0,
+ 16, 0x2004, 0x0020, 0,
+ 16, 0x2005, 0x0020, 0,
+ 16, 0x2006, 0x0020, 0,
+ 3, 0x2007, 0x0020, 0,
+ 16, 0x2008, 0x0020, 0,
+ 16, 0x2009, 0x0020, 0,
+ 16, 0x200A, 0x0020, 0,
+ 3, 0x2011, 0x2010, 0,
+ 16, 0x2017, 0x0020, 0x0333, 0,
+ 16, 0x2024, 0x002E, 0,
+ 16, 0x2025, 0x002E, 0x002E, 0,
+ 16, 0x2026, 0x002E, 0x002E, 0x002E, 0,
+ 3, 0x202F, 0x0020, 0,
+ 16, 0x2033, 0x2032, 0x2032, 0,
+ 16, 0x2034, 0x2032, 0x2032, 0x2032, 0,
+ 16, 0x2036, 0x2035, 0x2035, 0,
+ 16, 0x2037, 0x2035, 0x2035, 0x2035, 0,
+ 16, 0x203C, 0x0021, 0x0021, 0,
+ 16, 0x203E, 0x0020, 0x0305, 0,
+ 16, 0x2047, 0x003F, 0x003F, 0,
+ 16, 0x2048, 0x003F, 0x0021, 0,
+ 16, 0x2049, 0x0021, 0x003F, 0,
+ 16, 0x2057, 0x2032, 0x2032, 0x2032, 0x2032, 0,
+ 16, 0x205F, 0x0020, 0,
+ 9, 0x2070, 0x0030, 0,
+ 9, 0x2071, 0x0069, 0,
+ 9, 0x2074, 0x0034, 0,
+ 9, 0x2075, 0x0035, 0,
+ 9, 0x2076, 0x0036, 0,
+ 9, 0x2077, 0x0037, 0,
+ 9, 0x2078, 0x0038, 0,
+ 9, 0x2079, 0x0039, 0,
+ 9, 0x207A, 0x002B, 0,
+ 9, 0x207B, 0x2212, 0,
+ 9, 0x207C, 0x003D, 0,
+ 9, 0x207D, 0x0028, 0,
+ 9, 0x207E, 0x0029, 0,
+ 9, 0x207F, 0x006E, 0,
+ 10, 0x2080, 0x0030, 0,
+ 10, 0x2081, 0x0031, 0,
+ 10, 0x2082, 0x0032, 0,
+ 10, 0x2083, 0x0033, 0,
+ 10, 0x2084, 0x0034, 0,
+ 10, 0x2085, 0x0035, 0,
+ 10, 0x2086, 0x0036, 0,
+ 10, 0x2087, 0x0037, 0,
+ 10, 0x2088, 0x0038, 0,
+ 10, 0x2089, 0x0039, 0,
+ 10, 0x208A, 0x002B, 0,
+ 10, 0x208B, 0x2212, 0,
+ 10, 0x208C, 0x003D, 0,
+ 10, 0x208D, 0x0028, 0,
+ 10, 0x208E, 0x0029, 0,
+ 16, 0x20A8, 0x0052, 0x0073, 0,
+ 16, 0x2100, 0x0061, 0x002F, 0x0063, 0,
+ 16, 0x2101, 0x0061, 0x002F, 0x0073, 0,
+ 2, 0x2102, 0x0043, 0,
+ 16, 0x2103, 0x00B0, 0x0043, 0,
+ 16, 0x2105, 0x0063, 0x002F, 0x006F, 0,
+ 16, 0x2106, 0x0063, 0x002F, 0x0075, 0,
+ 16, 0x2107, 0x0190, 0,
+ 16, 0x2109, 0x00B0, 0x0046, 0,
+ 2, 0x210A, 0x0067, 0,
+ 2, 0x210B, 0x0048, 0,
+ 2, 0x210C, 0x0048, 0,
+ 2, 0x210D, 0x0048, 0,
+ 2, 0x210E, 0x0068, 0,
+ 2, 0x210F, 0x0127, 0,
+ 2, 0x2110, 0x0049, 0,
+ 2, 0x2111, 0x0049, 0,
+ 2, 0x2112, 0x004C, 0,
+ 2, 0x2113, 0x006C, 0,
+ 2, 0x2115, 0x004E, 0,
+ 16, 0x2116, 0x004E, 0x006F, 0,
+ 2, 0x2119, 0x0050, 0,
+ 2, 0x211A, 0x0051, 0,
+ 2, 0x211B, 0x0052, 0,
+ 2, 0x211C, 0x0052, 0,
+ 2, 0x211D, 0x0052, 0,
+ 9, 0x2120, 0x0053, 0x004D, 0,
+ 16, 0x2121, 0x0054, 0x0045, 0x004C, 0,
+ 9, 0x2122, 0x0054, 0x004D, 0,
+ 2, 0x2124, 0x005A, 0,
+ 1, 0x2126, 0x03A9, 0,
+ 2, 0x2128, 0x005A, 0,
+ 1, 0x212A, 0x004B, 0,
+ 1, 0x212B, 0x00C5, 0,
+ 2, 0x212C, 0x0042, 0,
+ 2, 0x212D, 0x0043, 0,
+ 2, 0x212F, 0x0065, 0,
+ 2, 0x2130, 0x0045, 0,
+ 2, 0x2131, 0x0046, 0,
+ 2, 0x2133, 0x004D, 0,
+ 2, 0x2134, 0x006F, 0,
+ 16, 0x2135, 0x05D0, 0,
+ 16, 0x2136, 0x05D1, 0,
+ 16, 0x2137, 0x05D2, 0,
+ 16, 0x2138, 0x05D3, 0,
+ 2, 0x2139, 0x0069, 0,
+ 2, 0x213D, 0x03B3, 0,
+ 2, 0x213E, 0x0393, 0,
+ 2, 0x213F, 0x03A0, 0,
+ 2, 0x2140, 0x2211, 0,
+ 2, 0x2145, 0x0044, 0,
+ 2, 0x2146, 0x0064, 0,
+ 2, 0x2147, 0x0065, 0,
+ 2, 0x2148, 0x0069, 0,
+ 2, 0x2149, 0x006A, 0,
+ 17, 0x2153, 0x0031, 0x2044, 0x0033, 0,
+ 17, 0x2154, 0x0032, 0x2044, 0x0033, 0,
+ 17, 0x2155, 0x0031, 0x2044, 0x0035, 0,
+ 17, 0x2156, 0x0032, 0x2044, 0x0035, 0,
+ 17, 0x2157, 0x0033, 0x2044, 0x0035, 0,
+ 17, 0x2158, 0x0034, 0x2044, 0x0035, 0,
+ 17, 0x2159, 0x0031, 0x2044, 0x0036, 0,
+ 17, 0x215A, 0x0035, 0x2044, 0x0036, 0,
+ 17, 0x215B, 0x0031, 0x2044, 0x0038, 0,
+ 17, 0x215C, 0x0033, 0x2044, 0x0038, 0,
+ 17, 0x215D, 0x0035, 0x2044, 0x0038, 0,
+ 17, 0x215E, 0x0037, 0x2044, 0x0038, 0,
+ 17, 0x215F, 0x0031, 0x2044, 0,
+ 16, 0x2160, 0x0049, 0,
+ 16, 0x2161, 0x0049, 0x0049, 0,
+ 16, 0x2162, 0x0049, 0x0049, 0x0049, 0,
+ 16, 0x2163, 0x0049, 0x0056, 0,
+ 16, 0x2164, 0x0056, 0,
+ 16, 0x2165, 0x0056, 0x0049, 0,
+ 16, 0x2166, 0x0056, 0x0049, 0x0049, 0,
+ 16, 0x2167, 0x0056, 0x0049, 0x0049, 0x0049, 0,
+ 16, 0x2168, 0x0049, 0x0058, 0,
+ 16, 0x2169, 0x0058, 0,
+ 16, 0x216A, 0x0058, 0x0049, 0,
+ 16, 0x216B, 0x0058, 0x0049, 0x0049, 0,
+ 16, 0x216C, 0x004C, 0,
+ 16, 0x216D, 0x0043, 0,
+ 16, 0x216E, 0x0044, 0,
+ 16, 0x216F, 0x004D, 0,
+ 16, 0x2170, 0x0069, 0,
+ 16, 0x2171, 0x0069, 0x0069, 0,
+ 16, 0x2172, 0x0069, 0x0069, 0x0069, 0,
+ 16, 0x2173, 0x0069, 0x0076, 0,
+ 16, 0x2174, 0x0076, 0,
+ 16, 0x2175, 0x0076, 0x0069, 0,
+ 16, 0x2176, 0x0076, 0x0069, 0x0069, 0,
+ 16, 0x2177, 0x0076, 0x0069, 0x0069, 0x0069, 0,
+ 16, 0x2178, 0x0069, 0x0078, 0,
+ 16, 0x2179, 0x0078, 0,
+ 16, 0x217A, 0x0078, 0x0069, 0,
+ 16, 0x217B, 0x0078, 0x0069, 0x0069, 0,
+ 16, 0x217C, 0x006C, 0,
+ 16, 0x217D, 0x0063, 0,
+ 16, 0x217E, 0x0064, 0,
+ 16, 0x217F, 0x006D, 0,
+ 1, 0x219A, 0x2190, 0x0338, 0,
+ 1, 0x219B, 0x2192, 0x0338, 0,
+ 1, 0x21AE, 0x2194, 0x0338, 0,
+ 1, 0x21CD, 0x21D0, 0x0338, 0,
+ 1, 0x21CE, 0x21D4, 0x0338, 0,
+ 1, 0x21CF, 0x21D2, 0x0338, 0,
+ 1, 0x2204, 0x2203, 0x0338, 0,
+ 1, 0x2209, 0x2208, 0x0338, 0,
+ 1, 0x220C, 0x220B, 0x0338, 0,
+ 1, 0x2224, 0x2223, 0x0338, 0,
+ 1, 0x2226, 0x2225, 0x0338, 0,
+ 16, 0x222C, 0x222B, 0x222B, 0,
+ 16, 0x222D, 0x222B, 0x222B, 0x222B, 0,
+ 16, 0x222F, 0x222E, 0x222E, 0,
+ 16, 0x2230, 0x222E, 0x222E, 0x222E, 0,
+ 1, 0x2241, 0x223C, 0x0338, 0,
+ 1, 0x2244, 0x2243, 0x0338, 0,
+ 1, 0x2247, 0x2245, 0x0338, 0,
+ 1, 0x2249, 0x2248, 0x0338, 0,
+ 1, 0x2260, 0x003D, 0x0338, 0,
+ 1, 0x2262, 0x2261, 0x0338, 0,
+ 1, 0x226D, 0x224D, 0x0338, 0,
+ 1, 0x226E, 0x003C, 0x0338, 0,
+ 1, 0x226F, 0x003E, 0x0338, 0,
+ 1, 0x2270, 0x2264, 0x0338, 0,
+ 1, 0x2271, 0x2265, 0x0338, 0,
+ 1, 0x2274, 0x2272, 0x0338, 0,
+ 1, 0x2275, 0x2273, 0x0338, 0,
+ 1, 0x2278, 0x2276, 0x0338, 0,
+ 1, 0x2279, 0x2277, 0x0338, 0,
+ 1, 0x2280, 0x227A, 0x0338, 0,
+ 1, 0x2281, 0x227B, 0x0338, 0,
+ 1, 0x2284, 0x2282, 0x0338, 0,
+ 1, 0x2285, 0x2283, 0x0338, 0,
+ 1, 0x2288, 0x2286, 0x0338, 0,
+ 1, 0x2289, 0x2287, 0x0338, 0,
+ 1, 0x22AC, 0x22A2, 0x0338, 0,
+ 1, 0x22AD, 0x22A8, 0x0338, 0,
+ 1, 0x22AE, 0x22A9, 0x0338, 0,
+ 1, 0x22AF, 0x22AB, 0x0338, 0,
+ 1, 0x22E0, 0x227C, 0x0338, 0,
+ 1, 0x22E1, 0x227D, 0x0338, 0,
+ 1, 0x22E2, 0x2291, 0x0338, 0,
+ 1, 0x22E3, 0x2292, 0x0338, 0,
+ 1, 0x22EA, 0x22B2, 0x0338, 0,
+ 1, 0x22EB, 0x22B3, 0x0338, 0,
+ 1, 0x22EC, 0x22B4, 0x0338, 0,
+ 1, 0x22ED, 0x22B5, 0x0338, 0,
+ 1, 0x2329, 0x3008, 0,
+ 1, 0x232A, 0x3009, 0,
+ 8, 0x2460, 0x0031, 0,
+ 8, 0x2461, 0x0032, 0,
+ 8, 0x2462, 0x0033, 0,
+ 8, 0x2463, 0x0034, 0,
+ 8, 0x2464, 0x0035, 0,
+ 8, 0x2465, 0x0036, 0,
+ 8, 0x2466, 0x0037, 0,
+ 8, 0x2467, 0x0038, 0,
+ 8, 0x2468, 0x0039, 0,
+ 8, 0x2469, 0x0031, 0x0030, 0,
+ 8, 0x246A, 0x0031, 0x0031, 0,
+ 8, 0x246B, 0x0031, 0x0032, 0,
+ 8, 0x246C, 0x0031, 0x0033, 0,
+ 8, 0x246D, 0x0031, 0x0034, 0,
+ 8, 0x246E, 0x0031, 0x0035, 0,
+ 8, 0x246F, 0x0031, 0x0036, 0,
+ 8, 0x2470, 0x0031, 0x0037, 0,
+ 8, 0x2471, 0x0031, 0x0038, 0,
+ 8, 0x2472, 0x0031, 0x0039, 0,
+ 8, 0x2473, 0x0032, 0x0030, 0,
+ 16, 0x2474, 0x0028, 0x0031, 0x0029, 0,
+ 16, 0x2475, 0x0028, 0x0032, 0x0029, 0,
+ 16, 0x2476, 0x0028, 0x0033, 0x0029, 0,
+ 16, 0x2477, 0x0028, 0x0034, 0x0029, 0,
+ 16, 0x2478, 0x0028, 0x0035, 0x0029, 0,
+ 16, 0x2479, 0x0028, 0x0036, 0x0029, 0,
+ 16, 0x247A, 0x0028, 0x0037, 0x0029, 0,
+ 16, 0x247B, 0x0028, 0x0038, 0x0029, 0,
+ 16, 0x247C, 0x0028, 0x0039, 0x0029, 0,
+ 16, 0x247D, 0x0028, 0x0031, 0x0030, 0x0029, 0,
+ 16, 0x247E, 0x0028, 0x0031, 0x0031, 0x0029, 0,
+ 16, 0x247F, 0x0028, 0x0031, 0x0032, 0x0029, 0,
+ 16, 0x2480, 0x0028, 0x0031, 0x0033, 0x0029, 0,
+ 16, 0x2481, 0x0028, 0x0031, 0x0034, 0x0029, 0,
+ 16, 0x2482, 0x0028, 0x0031, 0x0035, 0x0029, 0,
+ 16, 0x2483, 0x0028, 0x0031, 0x0036, 0x0029, 0,
+ 16, 0x2484, 0x0028, 0x0031, 0x0037, 0x0029, 0,
+ 16, 0x2485, 0x0028, 0x0031, 0x0038, 0x0029, 0,
+ 16, 0x2486, 0x0028, 0x0031, 0x0039, 0x0029, 0,
+ 16, 0x2487, 0x0028, 0x0032, 0x0030, 0x0029, 0,
+ 16, 0x2488, 0x0031, 0x002E, 0,
+ 16, 0x2489, 0x0032, 0x002E, 0,
+ 16, 0x248A, 0x0033, 0x002E, 0,
+ 16, 0x248B, 0x0034, 0x002E, 0,
+ 16, 0x248C, 0x0035, 0x002E, 0,
+ 16, 0x248D, 0x0036, 0x002E, 0,
+ 16, 0x248E, 0x0037, 0x002E, 0,
+ 16, 0x248F, 0x0038, 0x002E, 0,
+ 16, 0x2490, 0x0039, 0x002E, 0,
+ 16, 0x2491, 0x0031, 0x0030, 0x002E, 0,
+ 16, 0x2492, 0x0031, 0x0031, 0x002E, 0,
+ 16, 0x2493, 0x0031, 0x0032, 0x002E, 0,
+ 16, 0x2494, 0x0031, 0x0033, 0x002E, 0,
+ 16, 0x2495, 0x0031, 0x0034, 0x002E, 0,
+ 16, 0x2496, 0x0031, 0x0035, 0x002E, 0,
+ 16, 0x2497, 0x0031, 0x0036, 0x002E, 0,
+ 16, 0x2498, 0x0031, 0x0037, 0x002E, 0,
+ 16, 0x2499, 0x0031, 0x0038, 0x002E, 0,
+ 16, 0x249A, 0x0031, 0x0039, 0x002E, 0,
+ 16, 0x249B, 0x0032, 0x0030, 0x002E, 0,
+ 16, 0x249C, 0x0028, 0x0061, 0x0029, 0,
+ 16, 0x249D, 0x0028, 0x0062, 0x0029, 0,
+ 16, 0x249E, 0x0028, 0x0063, 0x0029, 0,
+ 16, 0x249F, 0x0028, 0x0064, 0x0029, 0,
+ 16, 0x24A0, 0x0028, 0x0065, 0x0029, 0,
+ 16, 0x24A1, 0x0028, 0x0066, 0x0029, 0,
+ 16, 0x24A2, 0x0028, 0x0067, 0x0029, 0,
+ 16, 0x24A3, 0x0028, 0x0068, 0x0029, 0,
+ 16, 0x24A4, 0x0028, 0x0069, 0x0029, 0,
+ 16, 0x24A5, 0x0028, 0x006A, 0x0029, 0,
+ 16, 0x24A6, 0x0028, 0x006B, 0x0029, 0,
+ 16, 0x24A7, 0x0028, 0x006C, 0x0029, 0,
+ 16, 0x24A8, 0x0028, 0x006D, 0x0029, 0,
+ 16, 0x24A9, 0x0028, 0x006E, 0x0029, 0,
+ 16, 0x24AA, 0x0028, 0x006F, 0x0029, 0,
+ 16, 0x24AB, 0x0028, 0x0070, 0x0029, 0,
+ 16, 0x24AC, 0x0028, 0x0071, 0x0029, 0,
+ 16, 0x24AD, 0x0028, 0x0072, 0x0029, 0,
+ 16, 0x24AE, 0x0028, 0x0073, 0x0029, 0,
+ 16, 0x24AF, 0x0028, 0x0074, 0x0029, 0,
+ 16, 0x24B0, 0x0028, 0x0075, 0x0029, 0,
+ 16, 0x24B1, 0x0028, 0x0076, 0x0029, 0,
+ 16, 0x24B2, 0x0028, 0x0077, 0x0029, 0,
+ 16, 0x24B3, 0x0028, 0x0078, 0x0029, 0,
+ 16, 0x24B4, 0x0028, 0x0079, 0x0029, 0,
+ 16, 0x24B5, 0x0028, 0x007A, 0x0029, 0,
+ 8, 0x24B6, 0x0041, 0,
+ 8, 0x24B7, 0x0042, 0,
+ 8, 0x24B8, 0x0043, 0,
+ 8, 0x24B9, 0x0044, 0,
+ 8, 0x24BA, 0x0045, 0,
+ 8, 0x24BB, 0x0046, 0,
+ 8, 0x24BC, 0x0047, 0,
+ 8, 0x24BD, 0x0048, 0,
+ 8, 0x24BE, 0x0049, 0,
+ 8, 0x24BF, 0x004A, 0,
+ 8, 0x24C0, 0x004B, 0,
+ 8, 0x24C1, 0x004C, 0,
+ 8, 0x24C2, 0x004D, 0,
+ 8, 0x24C3, 0x004E, 0,
+ 8, 0x24C4, 0x004F, 0,
+ 8, 0x24C5, 0x0050, 0,
+ 8, 0x24C6, 0x0051, 0,
+ 8, 0x24C7, 0x0052, 0,
+ 8, 0x24C8, 0x0053, 0,
+ 8, 0x24C9, 0x0054, 0,
+ 8, 0x24CA, 0x0055, 0,
+ 8, 0x24CB, 0x0056, 0,
+ 8, 0x24CC, 0x0057, 0,
+ 8, 0x24CD, 0x0058, 0,
+ 8, 0x24CE, 0x0059, 0,
+ 8, 0x24CF, 0x005A, 0,
+ 8, 0x24D0, 0x0061, 0,
+ 8, 0x24D1, 0x0062, 0,
+ 8, 0x24D2, 0x0063, 0,
+ 8, 0x24D3, 0x0064, 0,
+ 8, 0x24D4, 0x0065, 0,
+ 8, 0x24D5, 0x0066, 0,
+ 8, 0x24D6, 0x0067, 0,
+ 8, 0x24D7, 0x0068, 0,
+ 8, 0x24D8, 0x0069, 0,
+ 8, 0x24D9, 0x006A, 0,
+ 8, 0x24DA, 0x006B, 0,
+ 8, 0x24DB, 0x006C, 0,
+ 8, 0x24DC, 0x006D, 0,
+ 8, 0x24DD, 0x006E, 0,
+ 8, 0x24DE, 0x006F, 0,
+ 8, 0x24DF, 0x0070, 0,
+ 8, 0x24E0, 0x0071, 0,
+ 8, 0x24E1, 0x0072, 0,
+ 8, 0x24E2, 0x0073, 0,
+ 8, 0x24E3, 0x0074, 0,
+ 8, 0x24E4, 0x0075, 0,
+ 8, 0x24E5, 0x0076, 0,
+ 8, 0x24E6, 0x0077, 0,
+ 8, 0x24E7, 0x0078, 0,
+ 8, 0x24E8, 0x0079, 0,
+ 8, 0x24E9, 0x007A, 0,
+ 8, 0x24EA, 0x0030, 0,
+ 16, 0x2A0C, 0x222B, 0x222B, 0x222B, 0x222B, 0,
+ 16, 0x2A74, 0x003A, 0x003A, 0x003D, 0,
+ 16, 0x2A75, 0x003D, 0x003D, 0,
+ 16, 0x2A76, 0x003D, 0x003D, 0x003D, 0,
+ 1, 0x2ADC, 0x2ADD, 0x0338, 0,
+ 16, 0x2E9F, 0x6BCD, 0,
+ 16, 0x2EF3, 0x9F9F, 0,
+ 16, 0x2F00, 0x4E00, 0,
+ 16, 0x2F01, 0x4E28, 0,
+ 16, 0x2F02, 0x4E36, 0,
+ 16, 0x2F03, 0x4E3F, 0,
+ 16, 0x2F04, 0x4E59, 0,
+ 16, 0x2F05, 0x4E85, 0,
+ 16, 0x2F06, 0x4E8C, 0,
+ 16, 0x2F07, 0x4EA0, 0,
+ 16, 0x2F08, 0x4EBA, 0,
+ 16, 0x2F09, 0x513F, 0,
+ 16, 0x2F0A, 0x5165, 0,
+ 16, 0x2F0B, 0x516B, 0,
+ 16, 0x2F0C, 0x5182, 0,
+ 16, 0x2F0D, 0x5196, 0,
+ 16, 0x2F0E, 0x51AB, 0,
+ 16, 0x2F0F, 0x51E0, 0,
+ 16, 0x2F10, 0x51F5, 0,
+ 16, 0x2F11, 0x5200, 0,
+ 16, 0x2F12, 0x529B, 0,
+ 16, 0x2F13, 0x52F9, 0,
+ 16, 0x2F14, 0x5315, 0,
+ 16, 0x2F15, 0x531A, 0,
+ 16, 0x2F16, 0x5338, 0,
+ 16, 0x2F17, 0x5341, 0,
+ 16, 0x2F18, 0x535C, 0,
+ 16, 0x2F19, 0x5369, 0,
+ 16, 0x2F1A, 0x5382, 0,
+ 16, 0x2F1B, 0x53B6, 0,
+ 16, 0x2F1C, 0x53C8, 0,
+ 16, 0x2F1D, 0x53E3, 0,
+ 16, 0x2F1E, 0x56D7, 0,
+ 16, 0x2F1F, 0x571F, 0,
+ 16, 0x2F20, 0x58EB, 0,
+ 16, 0x2F21, 0x5902, 0,
+ 16, 0x2F22, 0x590A, 0,
+ 16, 0x2F23, 0x5915, 0,
+ 16, 0x2F24, 0x5927, 0,
+ 16, 0x2F25, 0x5973, 0,
+ 16, 0x2F26, 0x5B50, 0,
+ 16, 0x2F27, 0x5B80, 0,
+ 16, 0x2F28, 0x5BF8, 0,
+ 16, 0x2F29, 0x5C0F, 0,
+ 16, 0x2F2A, 0x5C22, 0,
+ 16, 0x2F2B, 0x5C38, 0,
+ 16, 0x2F2C, 0x5C6E, 0,
+ 16, 0x2F2D, 0x5C71, 0,
+ 16, 0x2F2E, 0x5DDB, 0,
+ 16, 0x2F2F, 0x5DE5, 0,
+ 16, 0x2F30, 0x5DF1, 0,
+ 16, 0x2F31, 0x5DFE, 0,
+ 16, 0x2F32, 0x5E72, 0,
+ 16, 0x2F33, 0x5E7A, 0,
+ 16, 0x2F34, 0x5E7F, 0,
+ 16, 0x2F35, 0x5EF4, 0,
+ 16, 0x2F36, 0x5EFE, 0,
+ 16, 0x2F37, 0x5F0B, 0,
+ 16, 0x2F38, 0x5F13, 0,
+ 16, 0x2F39, 0x5F50, 0,
+ 16, 0x2F3A, 0x5F61, 0,
+ 16, 0x2F3B, 0x5F73, 0,
+ 16, 0x2F3C, 0x5FC3, 0,
+ 16, 0x2F3D, 0x6208, 0,
+ 16, 0x2F3E, 0x6236, 0,
+ 16, 0x2F3F, 0x624B, 0,
+ 16, 0x2F40, 0x652F, 0,
+ 16, 0x2F41, 0x6534, 0,
+ 16, 0x2F42, 0x6587, 0,
+ 16, 0x2F43, 0x6597, 0,
+ 16, 0x2F44, 0x65A4, 0,
+ 16, 0x2F45, 0x65B9, 0,
+ 16, 0x2F46, 0x65E0, 0,
+ 16, 0x2F47, 0x65E5, 0,
+ 16, 0x2F48, 0x66F0, 0,
+ 16, 0x2F49, 0x6708, 0,
+ 16, 0x2F4A, 0x6728, 0,
+ 16, 0x2F4B, 0x6B20, 0,
+ 16, 0x2F4C, 0x6B62, 0,
+ 16, 0x2F4D, 0x6B79, 0,
+ 16, 0x2F4E, 0x6BB3, 0,
+ 16, 0x2F4F, 0x6BCB, 0,
+ 16, 0x2F50, 0x6BD4, 0,
+ 16, 0x2F51, 0x6BDB, 0,
+ 16, 0x2F52, 0x6C0F, 0,
+ 16, 0x2F53, 0x6C14, 0,
+ 16, 0x2F54, 0x6C34, 0,
+ 16, 0x2F55, 0x706B, 0,
+ 16, 0x2F56, 0x722A, 0,
+ 16, 0x2F57, 0x7236, 0,
+ 16, 0x2F58, 0x723B, 0,
+ 16, 0x2F59, 0x723F, 0,
+ 16, 0x2F5A, 0x7247, 0,
+ 16, 0x2F5B, 0x7259, 0,
+ 16, 0x2F5C, 0x725B, 0,
+ 16, 0x2F5D, 0x72AC, 0,
+ 16, 0x2F5E, 0x7384, 0,
+ 16, 0x2F5F, 0x7389, 0,
+ 16, 0x2F60, 0x74DC, 0,
+ 16, 0x2F61, 0x74E6, 0,
+ 16, 0x2F62, 0x7518, 0,
+ 16, 0x2F63, 0x751F, 0,
+ 16, 0x2F64, 0x7528, 0,
+ 16, 0x2F65, 0x7530, 0,
+ 16, 0x2F66, 0x758B, 0,
+ 16, 0x2F67, 0x7592, 0,
+ 16, 0x2F68, 0x7676, 0,
+ 16, 0x2F69, 0x767D, 0,
+ 16, 0x2F6A, 0x76AE, 0,
+ 16, 0x2F6B, 0x76BF, 0,
+ 16, 0x2F6C, 0x76EE, 0,
+ 16, 0x2F6D, 0x77DB, 0,
+ 16, 0x2F6E, 0x77E2, 0,
+ 16, 0x2F6F, 0x77F3, 0,
+ 16, 0x2F70, 0x793A, 0,
+ 16, 0x2F71, 0x79B8, 0,
+ 16, 0x2F72, 0x79BE, 0,
+ 16, 0x2F73, 0x7A74, 0,
+ 16, 0x2F74, 0x7ACB, 0,
+ 16, 0x2F75, 0x7AF9, 0,
+ 16, 0x2F76, 0x7C73, 0,
+ 16, 0x2F77, 0x7CF8, 0,
+ 16, 0x2F78, 0x7F36, 0,
+ 16, 0x2F79, 0x7F51, 0,
+ 16, 0x2F7A, 0x7F8A, 0,
+ 16, 0x2F7B, 0x7FBD, 0,
+ 16, 0x2F7C, 0x8001, 0,
+ 16, 0x2F7D, 0x800C, 0,
+ 16, 0x2F7E, 0x8012, 0,
+ 16, 0x2F7F, 0x8033, 0,
+ 16, 0x2F80, 0x807F, 0,
+ 16, 0x2F81, 0x8089, 0,
+ 16, 0x2F82, 0x81E3, 0,
+ 16, 0x2F83, 0x81EA, 0,
+ 16, 0x2F84, 0x81F3, 0,
+ 16, 0x2F85, 0x81FC, 0,
+ 16, 0x2F86, 0x820C, 0,
+ 16, 0x2F87, 0x821B, 0,
+ 16, 0x2F88, 0x821F, 0,
+ 16, 0x2F89, 0x826E, 0,
+ 16, 0x2F8A, 0x8272, 0,
+ 16, 0x2F8B, 0x8278, 0,
+ 16, 0x2F8C, 0x864D, 0,
+ 16, 0x2F8D, 0x866B, 0,
+ 16, 0x2F8E, 0x8840, 0,
+ 16, 0x2F8F, 0x884C, 0,
+ 16, 0x2F90, 0x8863, 0,
+ 16, 0x2F91, 0x897E, 0,
+ 16, 0x2F92, 0x898B, 0,
+ 16, 0x2F93, 0x89D2, 0,
+ 16, 0x2F94, 0x8A00, 0,
+ 16, 0x2F95, 0x8C37, 0,
+ 16, 0x2F96, 0x8C46, 0,
+ 16, 0x2F97, 0x8C55, 0,
+ 16, 0x2F98, 0x8C78, 0,
+ 16, 0x2F99, 0x8C9D, 0,
+ 16, 0x2F9A, 0x8D64, 0,
+ 16, 0x2F9B, 0x8D70, 0,
+ 16, 0x2F9C, 0x8DB3, 0,
+ 16, 0x2F9D, 0x8EAB, 0,
+ 16, 0x2F9E, 0x8ECA, 0,
+ 16, 0x2F9F, 0x8F9B, 0,
+ 16, 0x2FA0, 0x8FB0, 0,
+ 16, 0x2FA1, 0x8FB5, 0,
+ 16, 0x2FA2, 0x9091, 0,
+ 16, 0x2FA3, 0x9149, 0,
+ 16, 0x2FA4, 0x91C6, 0,
+ 16, 0x2FA5, 0x91CC, 0,
+ 16, 0x2FA6, 0x91D1, 0,
+ 16, 0x2FA7, 0x9577, 0,
+ 16, 0x2FA8, 0x9580, 0,
+ 16, 0x2FA9, 0x961C, 0,
+ 16, 0x2FAA, 0x96B6, 0,
+ 16, 0x2FAB, 0x96B9, 0,
+ 16, 0x2FAC, 0x96E8, 0,
+ 16, 0x2FAD, 0x9751, 0,
+ 16, 0x2FAE, 0x975E, 0,
+ 16, 0x2FAF, 0x9762, 0,
+ 16, 0x2FB0, 0x9769, 0,
+ 16, 0x2FB1, 0x97CB, 0,
+ 16, 0x2FB2, 0x97ED, 0,
+ 16, 0x2FB3, 0x97F3, 0,
+ 16, 0x2FB4, 0x9801, 0,
+ 16, 0x2FB5, 0x98A8, 0,
+ 16, 0x2FB6, 0x98DB, 0,
+ 16, 0x2FB7, 0x98DF, 0,
+ 16, 0x2FB8, 0x9996, 0,
+ 16, 0x2FB9, 0x9999, 0,
+ 16, 0x2FBA, 0x99AC, 0,
+ 16, 0x2FBB, 0x9AA8, 0,
+ 16, 0x2FBC, 0x9AD8, 0,
+ 16, 0x2FBD, 0x9ADF, 0,
+ 16, 0x2FBE, 0x9B25, 0,
+ 16, 0x2FBF, 0x9B2F, 0,
+ 16, 0x2FC0, 0x9B32, 0,
+ 16, 0x2FC1, 0x9B3C, 0,
+ 16, 0x2FC2, 0x9B5A, 0,
+ 16, 0x2FC3, 0x9CE5, 0,
+ 16, 0x2FC4, 0x9E75, 0,
+ 16, 0x2FC5, 0x9E7F, 0,
+ 16, 0x2FC6, 0x9EA5, 0,
+ 16, 0x2FC7, 0x9EBB, 0,
+ 16, 0x2FC8, 0x9EC3, 0,
+ 16, 0x2FC9, 0x9ECD, 0,
+ 16, 0x2FCA, 0x9ED1, 0,
+ 16, 0x2FCB, 0x9EF9, 0,
+ 16, 0x2FCC, 0x9EFD, 0,
+ 16, 0x2FCD, 0x9F0E, 0,
+ 16, 0x2FCE, 0x9F13, 0,
+ 16, 0x2FCF, 0x9F20, 0,
+ 16, 0x2FD0, 0x9F3B, 0,
+ 16, 0x2FD1, 0x9F4A, 0,
+ 16, 0x2FD2, 0x9F52, 0,
+ 16, 0x2FD3, 0x9F8D, 0,
+ 16, 0x2FD4, 0x9F9C, 0,
+ 16, 0x2FD5, 0x9FA0, 0,
+ 12, 0x3000, 0x0020, 0,
+ 16, 0x3036, 0x3012, 0,
+ 16, 0x3038, 0x5341, 0,
+ 16, 0x3039, 0x5344, 0,
+ 16, 0x303A, 0x5345, 0,
+ 1, 0x304C, 0x304B, 0x3099, 0,
+ 1, 0x304E, 0x304D, 0x3099, 0,
+ 1, 0x3050, 0x304F, 0x3099, 0,
+ 1, 0x3052, 0x3051, 0x3099, 0,
+ 1, 0x3054, 0x3053, 0x3099, 0,
+ 1, 0x3056, 0x3055, 0x3099, 0,
+ 1, 0x3058, 0x3057, 0x3099, 0,
+ 1, 0x305A, 0x3059, 0x3099, 0,
+ 1, 0x305C, 0x305B, 0x3099, 0,
+ 1, 0x305E, 0x305D, 0x3099, 0,
+ 1, 0x3060, 0x305F, 0x3099, 0,
+ 1, 0x3062, 0x3061, 0x3099, 0,
+ 1, 0x3065, 0x3064, 0x3099, 0,
+ 1, 0x3067, 0x3066, 0x3099, 0,
+ 1, 0x3069, 0x3068, 0x3099, 0,
+ 1, 0x3070, 0x306F, 0x3099, 0,
+ 1, 0x3071, 0x306F, 0x309A, 0,
+ 1, 0x3073, 0x3072, 0x3099, 0,
+ 1, 0x3074, 0x3072, 0x309A, 0,
+ 1, 0x3076, 0x3075, 0x3099, 0,
+ 1, 0x3077, 0x3075, 0x309A, 0,
+ 1, 0x3079, 0x3078, 0x3099, 0,
+ 1, 0x307A, 0x3078, 0x309A, 0,
+ 1, 0x307C, 0x307B, 0x3099, 0,
+ 1, 0x307D, 0x307B, 0x309A, 0,
+ 1, 0x3094, 0x3046, 0x3099, 0,
+ 16, 0x309B, 0x0020, 0x3099, 0,
+ 16, 0x309C, 0x0020, 0x309A, 0,
+ 1, 0x309E, 0x309D, 0x3099, 0,
+ 11, 0x309F, 0x3088, 0x308A, 0,
+ 1, 0x30AC, 0x30AB, 0x3099, 0,
+ 1, 0x30AE, 0x30AD, 0x3099, 0,
+ 1, 0x30B0, 0x30AF, 0x3099, 0,
+ 1, 0x30B2, 0x30B1, 0x3099, 0,
+ 1, 0x30B4, 0x30B3, 0x3099, 0,
+ 1, 0x30B6, 0x30B5, 0x3099, 0,
+ 1, 0x30B8, 0x30B7, 0x3099, 0,
+ 1, 0x30BA, 0x30B9, 0x3099, 0,
+ 1, 0x30BC, 0x30BB, 0x3099, 0,
+ 1, 0x30BE, 0x30BD, 0x3099, 0,
+ 1, 0x30C0, 0x30BF, 0x3099, 0,
+ 1, 0x30C2, 0x30C1, 0x3099, 0,
+ 1, 0x30C5, 0x30C4, 0x3099, 0,
+ 1, 0x30C7, 0x30C6, 0x3099, 0,
+ 1, 0x30C9, 0x30C8, 0x3099, 0,
+ 1, 0x30D0, 0x30CF, 0x3099, 0,
+ 1, 0x30D1, 0x30CF, 0x309A, 0,
+ 1, 0x30D3, 0x30D2, 0x3099, 0,
+ 1, 0x30D4, 0x30D2, 0x309A, 0,
+ 1, 0x30D6, 0x30D5, 0x3099, 0,
+ 1, 0x30D7, 0x30D5, 0x309A, 0,
+ 1, 0x30D9, 0x30D8, 0x3099, 0,
+ 1, 0x30DA, 0x30D8, 0x309A, 0,
+ 1, 0x30DC, 0x30DB, 0x3099, 0,
+ 1, 0x30DD, 0x30DB, 0x309A, 0,
+ 1, 0x30F4, 0x30A6, 0x3099, 0,
+ 1, 0x30F7, 0x30EF, 0x3099, 0,
+ 1, 0x30F8, 0x30F0, 0x3099, 0,
+ 1, 0x30F9, 0x30F1, 0x3099, 0,
+ 1, 0x30FA, 0x30F2, 0x3099, 0,
+ 1, 0x30FE, 0x30FD, 0x3099, 0,
+ 11, 0x30FF, 0x30B3, 0x30C8, 0,
+ 16, 0x3131, 0x1100, 0,
+ 16, 0x3132, 0x1101, 0,
+ 16, 0x3133, 0x11AA, 0,
+ 16, 0x3134, 0x1102, 0,
+ 16, 0x3135, 0x11AC, 0,
+ 16, 0x3136, 0x11AD, 0,
+ 16, 0x3137, 0x1103, 0,
+ 16, 0x3138, 0x1104, 0,
+ 16, 0x3139, 0x1105, 0,
+ 16, 0x313A, 0x11B0, 0,
+ 16, 0x313B, 0x11B1, 0,
+ 16, 0x313C, 0x11B2, 0,
+ 16, 0x313D, 0x11B3, 0,
+ 16, 0x313E, 0x11B4, 0,
+ 16, 0x313F, 0x11B5, 0,
+ 16, 0x3140, 0x111A, 0,
+ 16, 0x3141, 0x1106, 0,
+ 16, 0x3142, 0x1107, 0,
+ 16, 0x3143, 0x1108, 0,
+ 16, 0x3144, 0x1121, 0,
+ 16, 0x3145, 0x1109, 0,
+ 16, 0x3146, 0x110A, 0,
+ 16, 0x3147, 0x110B, 0,
+ 16, 0x3148, 0x110C, 0,
+ 16, 0x3149, 0x110D, 0,
+ 16, 0x314A, 0x110E, 0,
+ 16, 0x314B, 0x110F, 0,
+ 16, 0x314C, 0x1110, 0,
+ 16, 0x314D, 0x1111, 0,
+ 16, 0x314E, 0x1112, 0,
+ 16, 0x314F, 0x1161, 0,
+ 16, 0x3150, 0x1162, 0,
+ 16, 0x3151, 0x1163, 0,
+ 16, 0x3152, 0x1164, 0,
+ 16, 0x3153, 0x1165, 0,
+ 16, 0x3154, 0x1166, 0,
+ 16, 0x3155, 0x1167, 0,
+ 16, 0x3156, 0x1168, 0,
+ 16, 0x3157, 0x1169, 0,
+ 16, 0x3158, 0x116A, 0,
+ 16, 0x3159, 0x116B, 0,
+ 16, 0x315A, 0x116C, 0,
+ 16, 0x315B, 0x116D, 0,
+ 16, 0x315C, 0x116E, 0,
+ 16, 0x315D, 0x116F, 0,
+ 16, 0x315E, 0x1170, 0,
+ 16, 0x315F, 0x1171, 0,
+ 16, 0x3160, 0x1172, 0,
+ 16, 0x3161, 0x1173, 0,
+ 16, 0x3162, 0x1174, 0,
+ 16, 0x3163, 0x1175, 0,
+ 16, 0x3164, 0x1160, 0,
+ 16, 0x3165, 0x1114, 0,
+ 16, 0x3166, 0x1115, 0,
+ 16, 0x3167, 0x11C7, 0,
+ 16, 0x3168, 0x11C8, 0,
+ 16, 0x3169, 0x11CC, 0,
+ 16, 0x316A, 0x11CE, 0,
+ 16, 0x316B, 0x11D3, 0,
+ 16, 0x316C, 0x11D7, 0,
+ 16, 0x316D, 0x11D9, 0,
+ 16, 0x316E, 0x111C, 0,
+ 16, 0x316F, 0x11DD, 0,
+ 16, 0x3170, 0x11DF, 0,
+ 16, 0x3171, 0x111D, 0,
+ 16, 0x3172, 0x111E, 0,
+ 16, 0x3173, 0x1120, 0,
+ 16, 0x3174, 0x1122, 0,
+ 16, 0x3175, 0x1123, 0,
+ 16, 0x3176, 0x1127, 0,
+ 16, 0x3177, 0x1129, 0,
+ 16, 0x3178, 0x112B, 0,
+ 16, 0x3179, 0x112C, 0,
+ 16, 0x317A, 0x112D, 0,
+ 16, 0x317B, 0x112E, 0,
+ 16, 0x317C, 0x112F, 0,
+ 16, 0x317D, 0x1132, 0,
+ 16, 0x317E, 0x1136, 0,
+ 16, 0x317F, 0x1140, 0,
+ 16, 0x3180, 0x1147, 0,
+ 16, 0x3181, 0x114C, 0,
+ 16, 0x3182, 0x11F1, 0,
+ 16, 0x3183, 0x11F2, 0,
+ 16, 0x3184, 0x1157, 0,
+ 16, 0x3185, 0x1158, 0,
+ 16, 0x3186, 0x1159, 0,
+ 16, 0x3187, 0x1184, 0,
+ 16, 0x3188, 0x1185, 0,
+ 16, 0x3189, 0x1188, 0,
+ 16, 0x318A, 0x1191, 0,
+ 16, 0x318B, 0x1192, 0,
+ 16, 0x318C, 0x1194, 0,
+ 16, 0x318D, 0x119E, 0,
+ 16, 0x318E, 0x11A1, 0,
+ 9, 0x3192, 0x4E00, 0,
+ 9, 0x3193, 0x4E8C, 0,
+ 9, 0x3194, 0x4E09, 0,
+ 9, 0x3195, 0x56DB, 0,
+ 9, 0x3196, 0x4E0A, 0,
+ 9, 0x3197, 0x4E2D, 0,
+ 9, 0x3198, 0x4E0B, 0,
+ 9, 0x3199, 0x7532, 0,
+ 9, 0x319A, 0x4E59, 0,
+ 9, 0x319B, 0x4E19, 0,
+ 9, 0x319C, 0x4E01, 0,
+ 9, 0x319D, 0x5929, 0,
+ 9, 0x319E, 0x5730, 0,
+ 9, 0x319F, 0x4EBA, 0,
+ 16, 0x3200, 0x0028, 0x1100, 0x0029, 0,
+ 16, 0x3201, 0x0028, 0x1102, 0x0029, 0,
+ 16, 0x3202, 0x0028, 0x1103, 0x0029, 0,
+ 16, 0x3203, 0x0028, 0x1105, 0x0029, 0,
+ 16, 0x3204, 0x0028, 0x1106, 0x0029, 0,
+ 16, 0x3205, 0x0028, 0x1107, 0x0029, 0,
+ 16, 0x3206, 0x0028, 0x1109, 0x0029, 0,
+ 16, 0x3207, 0x0028, 0x110B, 0x0029, 0,
+ 16, 0x3208, 0x0028, 0x110C, 0x0029, 0,
+ 16, 0x3209, 0x0028, 0x110E, 0x0029, 0,
+ 16, 0x320A, 0x0028, 0x110F, 0x0029, 0,
+ 16, 0x320B, 0x0028, 0x1110, 0x0029, 0,
+ 16, 0x320C, 0x0028, 0x1111, 0x0029, 0,
+ 16, 0x320D, 0x0028, 0x1112, 0x0029, 0,
+ 16, 0x320E, 0x0028, 0x1100, 0x1161, 0x0029, 0,
+ 16, 0x320F, 0x0028, 0x1102, 0x1161, 0x0029, 0,
+ 16, 0x3210, 0x0028, 0x1103, 0x1161, 0x0029, 0,
+ 16, 0x3211, 0x0028, 0x1105, 0x1161, 0x0029, 0,
+ 16, 0x3212, 0x0028, 0x1106, 0x1161, 0x0029, 0,
+ 16, 0x3213, 0x0028, 0x1107, 0x1161, 0x0029, 0,
+ 16, 0x3214, 0x0028, 0x1109, 0x1161, 0x0029, 0,
+ 16, 0x3215, 0x0028, 0x110B, 0x1161, 0x0029, 0,
+ 16, 0x3216, 0x0028, 0x110C, 0x1161, 0x0029, 0,
+ 16, 0x3217, 0x0028, 0x110E, 0x1161, 0x0029, 0,
+ 16, 0x3218, 0x0028, 0x110F, 0x1161, 0x0029, 0,
+ 16, 0x3219, 0x0028, 0x1110, 0x1161, 0x0029, 0,
+ 16, 0x321A, 0x0028, 0x1111, 0x1161, 0x0029, 0,
+ 16, 0x321B, 0x0028, 0x1112, 0x1161, 0x0029, 0,
+ 16, 0x321C, 0x0028, 0x110C, 0x116E, 0x0029, 0,
+ 16, 0x3220, 0x0028, 0x4E00, 0x0029, 0,
+ 16, 0x3221, 0x0028, 0x4E8C, 0x0029, 0,
+ 16, 0x3222, 0x0028, 0x4E09, 0x0029, 0,
+ 16, 0x3223, 0x0028, 0x56DB, 0x0029, 0,
+ 16, 0x3224, 0x0028, 0x4E94, 0x0029, 0,
+ 16, 0x3225, 0x0028, 0x516D, 0x0029, 0,
+ 16, 0x3226, 0x0028, 0x4E03, 0x0029, 0,
+ 16, 0x3227, 0x0028, 0x516B, 0x0029, 0,
+ 16, 0x3228, 0x0028, 0x4E5D, 0x0029, 0,
+ 16, 0x3229, 0x0028, 0x5341, 0x0029, 0,
+ 16, 0x322A, 0x0028, 0x6708, 0x0029, 0,
+ 16, 0x322B, 0x0028, 0x706B, 0x0029, 0,
+ 16, 0x322C, 0x0028, 0x6C34, 0x0029, 0,
+ 16, 0x322D, 0x0028, 0x6728, 0x0029, 0,
+ 16, 0x322E, 0x0028, 0x91D1, 0x0029, 0,
+ 16, 0x322F, 0x0028, 0x571F, 0x0029, 0,
+ 16, 0x3230, 0x0028, 0x65E5, 0x0029, 0,
+ 16, 0x3231, 0x0028, 0x682A, 0x0029, 0,
+ 16, 0x3232, 0x0028, 0x6709, 0x0029, 0,
+ 16, 0x3233, 0x0028, 0x793E, 0x0029, 0,
+ 16, 0x3234, 0x0028, 0x540D, 0x0029, 0,
+ 16, 0x3235, 0x0028, 0x7279, 0x0029, 0,
+ 16, 0x3236, 0x0028, 0x8CA1, 0x0029, 0,
+ 16, 0x3237, 0x0028, 0x795D, 0x0029, 0,
+ 16, 0x3238, 0x0028, 0x52B4, 0x0029, 0,
+ 16, 0x3239, 0x0028, 0x4EE3, 0x0029, 0,
+ 16, 0x323A, 0x0028, 0x547C, 0x0029, 0,
+ 16, 0x323B, 0x0028, 0x5B66, 0x0029, 0,
+ 16, 0x323C, 0x0028, 0x76E3, 0x0029, 0,
+ 16, 0x323D, 0x0028, 0x4F01, 0x0029, 0,
+ 16, 0x323E, 0x0028, 0x8CC7, 0x0029, 0,
+ 16, 0x323F, 0x0028, 0x5354, 0x0029, 0,
+ 16, 0x3240, 0x0028, 0x796D, 0x0029, 0,
+ 16, 0x3241, 0x0028, 0x4F11, 0x0029, 0,
+ 16, 0x3242, 0x0028, 0x81EA, 0x0029, 0,
+ 16, 0x3243, 0x0028, 0x81F3, 0x0029, 0,
+ 8, 0x3251, 0x0032, 0x0031, 0,
+ 8, 0x3252, 0x0032, 0x0032, 0,
+ 8, 0x3253, 0x0032, 0x0033, 0,
+ 8, 0x3254, 0x0032, 0x0034, 0,
+ 8, 0x3255, 0x0032, 0x0035, 0,
+ 8, 0x3256, 0x0032, 0x0036, 0,
+ 8, 0x3257, 0x0032, 0x0037, 0,
+ 8, 0x3258, 0x0032, 0x0038, 0,
+ 8, 0x3259, 0x0032, 0x0039, 0,
+ 8, 0x325A, 0x0033, 0x0030, 0,
+ 8, 0x325B, 0x0033, 0x0031, 0,
+ 8, 0x325C, 0x0033, 0x0032, 0,
+ 8, 0x325D, 0x0033, 0x0033, 0,
+ 8, 0x325E, 0x0033, 0x0034, 0,
+ 8, 0x325F, 0x0033, 0x0035, 0,
+ 8, 0x3260, 0x1100, 0,
+ 8, 0x3261, 0x1102, 0,
+ 8, 0x3262, 0x1103, 0,
+ 8, 0x3263, 0x1105, 0,
+ 8, 0x3264, 0x1106, 0,
+ 8, 0x3265, 0x1107, 0,
+ 8, 0x3266, 0x1109, 0,
+ 8, 0x3267, 0x110B, 0,
+ 8, 0x3268, 0x110C, 0,
+ 8, 0x3269, 0x110E, 0,
+ 8, 0x326A, 0x110F, 0,
+ 8, 0x326B, 0x1110, 0,
+ 8, 0x326C, 0x1111, 0,
+ 8, 0x326D, 0x1112, 0,
+ 8, 0x326E, 0x1100, 0x1161, 0,
+ 8, 0x326F, 0x1102, 0x1161, 0,
+ 8, 0x3270, 0x1103, 0x1161, 0,
+ 8, 0x3271, 0x1105, 0x1161, 0,
+ 8, 0x3272, 0x1106, 0x1161, 0,
+ 8, 0x3273, 0x1107, 0x1161, 0,
+ 8, 0x3274, 0x1109, 0x1161, 0,
+ 8, 0x3275, 0x110B, 0x1161, 0,
+ 8, 0x3276, 0x110C, 0x1161, 0,
+ 8, 0x3277, 0x110E, 0x1161, 0,
+ 8, 0x3278, 0x110F, 0x1161, 0,
+ 8, 0x3279, 0x1110, 0x1161, 0,
+ 8, 0x327A, 0x1111, 0x1161, 0,
+ 8, 0x327B, 0x1112, 0x1161, 0,
+ 8, 0x3280, 0x4E00, 0,
+ 8, 0x3281, 0x4E8C, 0,
+ 8, 0x3282, 0x4E09, 0,
+ 8, 0x3283, 0x56DB, 0,
+ 8, 0x3284, 0x4E94, 0,
+ 8, 0x3285, 0x516D, 0,
+ 8, 0x3286, 0x4E03, 0,
+ 8, 0x3287, 0x516B, 0,
+ 8, 0x3288, 0x4E5D, 0,
+ 8, 0x3289, 0x5341, 0,
+ 8, 0x328A, 0x6708, 0,
+ 8, 0x328B, 0x706B, 0,
+ 8, 0x328C, 0x6C34, 0,
+ 8, 0x328D, 0x6728, 0,
+ 8, 0x328E, 0x91D1, 0,
+ 8, 0x328F, 0x571F, 0,
+ 8, 0x3290, 0x65E5, 0,
+ 8, 0x3291, 0x682A, 0,
+ 8, 0x3292, 0x6709, 0,
+ 8, 0x3293, 0x793E, 0,
+ 8, 0x3294, 0x540D, 0,
+ 8, 0x3295, 0x7279, 0,
+ 8, 0x3296, 0x8CA1, 0,
+ 8, 0x3297, 0x795D, 0,
+ 8, 0x3298, 0x52B4, 0,
+ 8, 0x3299, 0x79D8, 0,
+ 8, 0x329A, 0x7537, 0,
+ 8, 0x329B, 0x5973, 0,
+ 8, 0x329C, 0x9069, 0,
+ 8, 0x329D, 0x512A, 0,
+ 8, 0x329E, 0x5370, 0,
+ 8, 0x329F, 0x6CE8, 0,
+ 8, 0x32A0, 0x9805, 0,
+ 8, 0x32A1, 0x4F11, 0,
+ 8, 0x32A2, 0x5199, 0,
+ 8, 0x32A3, 0x6B63, 0,
+ 8, 0x32A4, 0x4E0A, 0,
+ 8, 0x32A5, 0x4E2D, 0,
+ 8, 0x32A6, 0x4E0B, 0,
+ 8, 0x32A7, 0x5DE6, 0,
+ 8, 0x32A8, 0x53F3, 0,
+ 8, 0x32A9, 0x533B, 0,
+ 8, 0x32AA, 0x5B97, 0,
+ 8, 0x32AB, 0x5B66, 0,
+ 8, 0x32AC, 0x76E3, 0,
+ 8, 0x32AD, 0x4F01, 0,
+ 8, 0x32AE, 0x8CC7, 0,
+ 8, 0x32AF, 0x5354, 0,
+ 8, 0x32B0, 0x591C, 0,
+ 8, 0x32B1, 0x0033, 0x0036, 0,
+ 8, 0x32B2, 0x0033, 0x0037, 0,
+ 8, 0x32B3, 0x0033, 0x0038, 0,
+ 8, 0x32B4, 0x0033, 0x0039, 0,
+ 8, 0x32B5, 0x0034, 0x0030, 0,
+ 8, 0x32B6, 0x0034, 0x0031, 0,
+ 8, 0x32B7, 0x0034, 0x0032, 0,
+ 8, 0x32B8, 0x0034, 0x0033, 0,
+ 8, 0x32B9, 0x0034, 0x0034, 0,
+ 8, 0x32BA, 0x0034, 0x0035, 0,
+ 8, 0x32BB, 0x0034, 0x0036, 0,
+ 8, 0x32BC, 0x0034, 0x0037, 0,
+ 8, 0x32BD, 0x0034, 0x0038, 0,
+ 8, 0x32BE, 0x0034, 0x0039, 0,
+ 8, 0x32BF, 0x0035, 0x0030, 0,
+ 16, 0x32C0, 0x0031, 0x6708, 0,
+ 16, 0x32C1, 0x0032, 0x6708, 0,
+ 16, 0x32C2, 0x0033, 0x6708, 0,
+ 16, 0x32C3, 0x0034, 0x6708, 0,
+ 16, 0x32C4, 0x0035, 0x6708, 0,
+ 16, 0x32C5, 0x0036, 0x6708, 0,
+ 16, 0x32C6, 0x0037, 0x6708, 0,
+ 16, 0x32C7, 0x0038, 0x6708, 0,
+ 16, 0x32C8, 0x0039, 0x6708, 0,
+ 16, 0x32C9, 0x0031, 0x0030, 0x6708, 0,
+ 16, 0x32CA, 0x0031, 0x0031, 0x6708, 0,
+ 16, 0x32CB, 0x0031, 0x0032, 0x6708, 0,
+ 8, 0x32D0, 0x30A2, 0,
+ 8, 0x32D1, 0x30A4, 0,
+ 8, 0x32D2, 0x30A6, 0,
+ 8, 0x32D3, 0x30A8, 0,
+ 8, 0x32D4, 0x30AA, 0,
+ 8, 0x32D5, 0x30AB, 0,
+ 8, 0x32D6, 0x30AD, 0,
+ 8, 0x32D7, 0x30AF, 0,
+ 8, 0x32D8, 0x30B1, 0,
+ 8, 0x32D9, 0x30B3, 0,
+ 8, 0x32DA, 0x30B5, 0,
+ 8, 0x32DB, 0x30B7, 0,
+ 8, 0x32DC, 0x30B9, 0,
+ 8, 0x32DD, 0x30BB, 0,
+ 8, 0x32DE, 0x30BD, 0,
+ 8, 0x32DF, 0x30BF, 0,
+ 8, 0x32E0, 0x30C1, 0,
+ 8, 0x32E1, 0x30C4, 0,
+ 8, 0x32E2, 0x30C6, 0,
+ 8, 0x32E3, 0x30C8, 0,
+ 8, 0x32E4, 0x30CA, 0,
+ 8, 0x32E5, 0x30CB, 0,
+ 8, 0x32E6, 0x30CC, 0,
+ 8, 0x32E7, 0x30CD, 0,
+ 8, 0x32E8, 0x30CE, 0,
+ 8, 0x32E9, 0x30CF, 0,
+ 8, 0x32EA, 0x30D2, 0,
+ 8, 0x32EB, 0x30D5, 0,
+ 8, 0x32EC, 0x30D8, 0,
+ 8, 0x32ED, 0x30DB, 0,
+ 8, 0x32EE, 0x30DE, 0,
+ 8, 0x32EF, 0x30DF, 0,
+ 8, 0x32F0, 0x30E0, 0,
+ 8, 0x32F1, 0x30E1, 0,
+ 8, 0x32F2, 0x30E2, 0,
+ 8, 0x32F3, 0x30E4, 0,
+ 8, 0x32F4, 0x30E6, 0,
+ 8, 0x32F5, 0x30E8, 0,
+ 8, 0x32F6, 0x30E9, 0,
+ 8, 0x32F7, 0x30EA, 0,
+ 8, 0x32F8, 0x30EB, 0,
+ 8, 0x32F9, 0x30EC, 0,
+ 8, 0x32FA, 0x30ED, 0,
+ 8, 0x32FB, 0x30EF, 0,
+ 8, 0x32FC, 0x30F0, 0,
+ 8, 0x32FD, 0x30F1, 0,
+ 8, 0x32FE, 0x30F2, 0,
+ 15, 0x3300, 0x30A2, 0x30D1, 0x30FC, 0x30C8, 0,
+ 15, 0x3301, 0x30A2, 0x30EB, 0x30D5, 0x30A1, 0,
+ 15, 0x3302, 0x30A2, 0x30F3, 0x30DA, 0x30A2, 0,
+ 15, 0x3303, 0x30A2, 0x30FC, 0x30EB, 0,
+ 15, 0x3304, 0x30A4, 0x30CB, 0x30F3, 0x30B0, 0,
+ 15, 0x3305, 0x30A4, 0x30F3, 0x30C1, 0,
+ 15, 0x3306, 0x30A6, 0x30A9, 0x30F3, 0,
+ 15, 0x3307, 0x30A8, 0x30B9, 0x30AF, 0x30FC, 0x30C9, 0,
+ 15, 0x3308, 0x30A8, 0x30FC, 0x30AB, 0x30FC, 0,
+ 15, 0x3309, 0x30AA, 0x30F3, 0x30B9, 0,
+ 15, 0x330A, 0x30AA, 0x30FC, 0x30E0, 0,
+ 15, 0x330B, 0x30AB, 0x30A4, 0x30EA, 0,
+ 15, 0x330C, 0x30AB, 0x30E9, 0x30C3, 0x30C8, 0,
+ 15, 0x330D, 0x30AB, 0x30ED, 0x30EA, 0x30FC, 0,
+ 15, 0x330E, 0x30AC, 0x30ED, 0x30F3, 0,
+ 15, 0x330F, 0x30AC, 0x30F3, 0x30DE, 0,
+ 15, 0x3310, 0x30AE, 0x30AC, 0,
+ 15, 0x3311, 0x30AE, 0x30CB, 0x30FC, 0,
+ 15, 0x3312, 0x30AD, 0x30E5, 0x30EA, 0x30FC, 0,
+ 15, 0x3313, 0x30AE, 0x30EB, 0x30C0, 0x30FC, 0,
+ 15, 0x3314, 0x30AD, 0x30ED, 0,
+ 15, 0x3315, 0x30AD, 0x30ED, 0x30B0, 0x30E9, 0x30E0, 0,
+ 15, 0x3316, 0x30AD, 0x30ED, 0x30E1, 0x30FC, 0x30C8, 0x30EB, 0,
+ 15, 0x3317, 0x30AD, 0x30ED, 0x30EF, 0x30C3, 0x30C8, 0,
+ 15, 0x3318, 0x30B0, 0x30E9, 0x30E0, 0,
+ 15, 0x3319, 0x30B0, 0x30E9, 0x30E0, 0x30C8, 0x30F3, 0,
+ 15, 0x331A, 0x30AF, 0x30EB, 0x30BC, 0x30A4, 0x30ED, 0,
+ 15, 0x331B, 0x30AF, 0x30ED, 0x30FC, 0x30CD, 0,
+ 15, 0x331C, 0x30B1, 0x30FC, 0x30B9, 0,
+ 15, 0x331D, 0x30B3, 0x30EB, 0x30CA, 0,
+ 15, 0x331E, 0x30B3, 0x30FC, 0x30DD, 0,
+ 15, 0x331F, 0x30B5, 0x30A4, 0x30AF, 0x30EB, 0,
+ 15, 0x3320, 0x30B5, 0x30F3, 0x30C1, 0x30FC, 0x30E0, 0,
+ 15, 0x3321, 0x30B7, 0x30EA, 0x30F3, 0x30B0, 0,
+ 15, 0x3322, 0x30BB, 0x30F3, 0x30C1, 0,
+ 15, 0x3323, 0x30BB, 0x30F3, 0x30C8, 0,
+ 15, 0x3324, 0x30C0, 0x30FC, 0x30B9, 0,
+ 15, 0x3325, 0x30C7, 0x30B7, 0,
+ 15, 0x3326, 0x30C9, 0x30EB, 0,
+ 15, 0x3327, 0x30C8, 0x30F3, 0,
+ 15, 0x3328, 0x30CA, 0x30CE, 0,
+ 15, 0x3329, 0x30CE, 0x30C3, 0x30C8, 0,
+ 15, 0x332A, 0x30CF, 0x30A4, 0x30C4, 0,
+ 15, 0x332B, 0x30D1, 0x30FC, 0x30BB, 0x30F3, 0x30C8, 0,
+ 15, 0x332C, 0x30D1, 0x30FC, 0x30C4, 0,
+ 15, 0x332D, 0x30D0, 0x30FC, 0x30EC, 0x30EB, 0,
+ 15, 0x332E, 0x30D4, 0x30A2, 0x30B9, 0x30C8, 0x30EB, 0,
+ 15, 0x332F, 0x30D4, 0x30AF, 0x30EB, 0,
+ 15, 0x3330, 0x30D4, 0x30B3, 0,
+ 15, 0x3331, 0x30D3, 0x30EB, 0,
+ 15, 0x3332, 0x30D5, 0x30A1, 0x30E9, 0x30C3, 0x30C9, 0,
+ 15, 0x3333, 0x30D5, 0x30A3, 0x30FC, 0x30C8, 0,
+ 15, 0x3334, 0x30D6, 0x30C3, 0x30B7, 0x30A7, 0x30EB, 0,
+ 15, 0x3335, 0x30D5, 0x30E9, 0x30F3, 0,
+ 15, 0x3336, 0x30D8, 0x30AF, 0x30BF, 0x30FC, 0x30EB, 0,
+ 15, 0x3337, 0x30DA, 0x30BD, 0,
+ 15, 0x3338, 0x30DA, 0x30CB, 0x30D2, 0,
+ 15, 0x3339, 0x30D8, 0x30EB, 0x30C4, 0,
+ 15, 0x333A, 0x30DA, 0x30F3, 0x30B9, 0,
+ 15, 0x333B, 0x30DA, 0x30FC, 0x30B8, 0,
+ 15, 0x333C, 0x30D9, 0x30FC, 0x30BF, 0,
+ 15, 0x333D, 0x30DD, 0x30A4, 0x30F3, 0x30C8, 0,
+ 15, 0x333E, 0x30DC, 0x30EB, 0x30C8, 0,
+ 15, 0x333F, 0x30DB, 0x30F3, 0,
+ 15, 0x3340, 0x30DD, 0x30F3, 0x30C9, 0,
+ 15, 0x3341, 0x30DB, 0x30FC, 0x30EB, 0,
+ 15, 0x3342, 0x30DB, 0x30FC, 0x30F3, 0,
+ 15, 0x3343, 0x30DE, 0x30A4, 0x30AF, 0x30ED, 0,
+ 15, 0x3344, 0x30DE, 0x30A4, 0x30EB, 0,
+ 15, 0x3345, 0x30DE, 0x30C3, 0x30CF, 0,
+ 15, 0x3346, 0x30DE, 0x30EB, 0x30AF, 0,
+ 15, 0x3347, 0x30DE, 0x30F3, 0x30B7, 0x30E7, 0x30F3, 0,
+ 15, 0x3348, 0x30DF, 0x30AF, 0x30ED, 0x30F3, 0,
+ 15, 0x3349, 0x30DF, 0x30EA, 0,
+ 15, 0x334A, 0x30DF, 0x30EA, 0x30D0, 0x30FC, 0x30EB, 0,
+ 15, 0x334B, 0x30E1, 0x30AC, 0,
+ 15, 0x334C, 0x30E1, 0x30AC, 0x30C8, 0x30F3, 0,
+ 15, 0x334D, 0x30E1, 0x30FC, 0x30C8, 0x30EB, 0,
+ 15, 0x334E, 0x30E4, 0x30FC, 0x30C9, 0,
+ 15, 0x334F, 0x30E4, 0x30FC, 0x30EB, 0,
+ 15, 0x3350, 0x30E6, 0x30A2, 0x30F3, 0,
+ 15, 0x3351, 0x30EA, 0x30C3, 0x30C8, 0x30EB, 0,
+ 15, 0x3352, 0x30EA, 0x30E9, 0,
+ 15, 0x3353, 0x30EB, 0x30D4, 0x30FC, 0,
+ 15, 0x3354, 0x30EB, 0x30FC, 0x30D6, 0x30EB, 0,
+ 15, 0x3355, 0x30EC, 0x30E0, 0,
+ 15, 0x3356, 0x30EC, 0x30F3, 0x30C8, 0x30B2, 0x30F3, 0,
+ 15, 0x3357, 0x30EF, 0x30C3, 0x30C8, 0,
+ 16, 0x3358, 0x0030, 0x70B9, 0,
+ 16, 0x3359, 0x0031, 0x70B9, 0,
+ 16, 0x335A, 0x0032, 0x70B9, 0,
+ 16, 0x335B, 0x0033, 0x70B9, 0,
+ 16, 0x335C, 0x0034, 0x70B9, 0,
+ 16, 0x335D, 0x0035, 0x70B9, 0,
+ 16, 0x335E, 0x0036, 0x70B9, 0,
+ 16, 0x335F, 0x0037, 0x70B9, 0,
+ 16, 0x3360, 0x0038, 0x70B9, 0,
+ 16, 0x3361, 0x0039, 0x70B9, 0,
+ 16, 0x3362, 0x0031, 0x0030, 0x70B9, 0,
+ 16, 0x3363, 0x0031, 0x0031, 0x70B9, 0,
+ 16, 0x3364, 0x0031, 0x0032, 0x70B9, 0,
+ 16, 0x3365, 0x0031, 0x0033, 0x70B9, 0,
+ 16, 0x3366, 0x0031, 0x0034, 0x70B9, 0,
+ 16, 0x3367, 0x0031, 0x0035, 0x70B9, 0,
+ 16, 0x3368, 0x0031, 0x0036, 0x70B9, 0,
+ 16, 0x3369, 0x0031, 0x0037, 0x70B9, 0,
+ 16, 0x336A, 0x0031, 0x0038, 0x70B9, 0,
+ 16, 0x336B, 0x0031, 0x0039, 0x70B9, 0,
+ 16, 0x336C, 0x0032, 0x0030, 0x70B9, 0,
+ 16, 0x336D, 0x0032, 0x0031, 0x70B9, 0,
+ 16, 0x336E, 0x0032, 0x0032, 0x70B9, 0,
+ 16, 0x336F, 0x0032, 0x0033, 0x70B9, 0,
+ 16, 0x3370, 0x0032, 0x0034, 0x70B9, 0,
+ 15, 0x3371, 0x0068, 0x0050, 0x0061, 0,
+ 15, 0x3372, 0x0064, 0x0061, 0,
+ 15, 0x3373, 0x0041, 0x0055, 0,
+ 15, 0x3374, 0x0062, 0x0061, 0x0072, 0,
+ 15, 0x3375, 0x006F, 0x0056, 0,
+ 15, 0x3376, 0x0070, 0x0063, 0,
+ 15, 0x337B, 0x5E73, 0x6210, 0,
+ 15, 0x337C, 0x662D, 0x548C, 0,
+ 15, 0x337D, 0x5927, 0x6B63, 0,
+ 15, 0x337E, 0x660E, 0x6CBB, 0,
+ 15, 0x337F, 0x682A, 0x5F0F, 0x4F1A, 0x793E, 0,
+ 15, 0x3380, 0x0070, 0x0041, 0,
+ 15, 0x3381, 0x006E, 0x0041, 0,
+ 15, 0x3382, 0x03BC, 0x0041, 0,
+ 15, 0x3383, 0x006D, 0x0041, 0,
+ 15, 0x3384, 0x006B, 0x0041, 0,
+ 15, 0x3385, 0x004B, 0x0042, 0,
+ 15, 0x3386, 0x004D, 0x0042, 0,
+ 15, 0x3387, 0x0047, 0x0042, 0,
+ 15, 0x3388, 0x0063, 0x0061, 0x006C, 0,
+ 15, 0x3389, 0x006B, 0x0063, 0x0061, 0x006C, 0,
+ 15, 0x338A, 0x0070, 0x0046, 0,
+ 15, 0x338B, 0x006E, 0x0046, 0,
+ 15, 0x338C, 0x03BC, 0x0046, 0,
+ 15, 0x338D, 0x03BC, 0x0067, 0,
+ 15, 0x338E, 0x006D, 0x0067, 0,
+ 15, 0x338F, 0x006B, 0x0067, 0,
+ 15, 0x3390, 0x0048, 0x007A, 0,
+ 15, 0x3391, 0x006B, 0x0048, 0x007A, 0,
+ 15, 0x3392, 0x004D, 0x0048, 0x007A, 0,
+ 15, 0x3393, 0x0047, 0x0048, 0x007A, 0,
+ 15, 0x3394, 0x0054, 0x0048, 0x007A, 0,
+ 15, 0x3395, 0x03BC, 0x2113, 0,
+ 15, 0x3396, 0x006D, 0x2113, 0,
+ 15, 0x3397, 0x0064, 0x2113, 0,
+ 15, 0x3398, 0x006B, 0x2113, 0,
+ 15, 0x3399, 0x0066, 0x006D, 0,
+ 15, 0x339A, 0x006E, 0x006D, 0,
+ 15, 0x339B, 0x03BC, 0x006D, 0,
+ 15, 0x339C, 0x006D, 0x006D, 0,
+ 15, 0x339D, 0x0063, 0x006D, 0,
+ 15, 0x339E, 0x006B, 0x006D, 0,
+ 15, 0x339F, 0x006D, 0x006D, 0x00B2, 0,
+ 15, 0x33A0, 0x0063, 0x006D, 0x00B2, 0,
+ 15, 0x33A1, 0x006D, 0x00B2, 0,
+ 15, 0x33A2, 0x006B, 0x006D, 0x00B2, 0,
+ 15, 0x33A3, 0x006D, 0x006D, 0x00B3, 0,
+ 15, 0x33A4, 0x0063, 0x006D, 0x00B3, 0,
+ 15, 0x33A5, 0x006D, 0x00B3, 0,
+ 15, 0x33A6, 0x006B, 0x006D, 0x00B3, 0,
+ 15, 0x33A7, 0x006D, 0x2215, 0x0073, 0,
+ 15, 0x33A8, 0x006D, 0x2215, 0x0073, 0x00B2, 0,
+ 15, 0x33A9, 0x0050, 0x0061, 0,
+ 15, 0x33AA, 0x006B, 0x0050, 0x0061, 0,
+ 15, 0x33AB, 0x004D, 0x0050, 0x0061, 0,
+ 15, 0x33AC, 0x0047, 0x0050, 0x0061, 0,
+ 15, 0x33AD, 0x0072, 0x0061, 0x0064, 0,
+ 15, 0x33AE, 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0,
+ 15, 0x33AF, 0x0072, 0x0061, 0x0064, 0x2215, 0x0073, 0x00B2, 0,
+ 15, 0x33B0, 0x0070, 0x0073, 0,
+ 15, 0x33B1, 0x006E, 0x0073, 0,
+ 15, 0x33B2, 0x03BC, 0x0073, 0,
+ 15, 0x33B3, 0x006D, 0x0073, 0,
+ 15, 0x33B4, 0x0070, 0x0056, 0,
+ 15, 0x33B5, 0x006E, 0x0056, 0,
+ 15, 0x33B6, 0x03BC, 0x0056, 0,
+ 15, 0x33B7, 0x006D, 0x0056, 0,
+ 15, 0x33B8, 0x006B, 0x0056, 0,
+ 15, 0x33B9, 0x004D, 0x0056, 0,
+ 15, 0x33BA, 0x0070, 0x0057, 0,
+ 15, 0x33BB, 0x006E, 0x0057, 0,
+ 15, 0x33BC, 0x03BC, 0x0057, 0,
+ 15, 0x33BD, 0x006D, 0x0057, 0,
+ 15, 0x33BE, 0x006B, 0x0057, 0,
+ 15, 0x33BF, 0x004D, 0x0057, 0,
+ 15, 0x33C0, 0x006B, 0x03A9, 0,
+ 15, 0x33C1, 0x004D, 0x03A9, 0,
+ 15, 0x33C2, 0x0061, 0x002E, 0x006D, 0x002E, 0,
+ 15, 0x33C3, 0x0042, 0x0071, 0,
+ 15, 0x33C4, 0x0063, 0x0063, 0,
+ 15, 0x33C5, 0x0063, 0x0064, 0,
+ 15, 0x33C6, 0x0043, 0x2215, 0x006B, 0x0067, 0,
+ 15, 0x33C7, 0x0043, 0x006F, 0x002E, 0,
+ 15, 0x33C8, 0x0064, 0x0042, 0,
+ 15, 0x33C9, 0x0047, 0x0079, 0,
+ 15, 0x33CA, 0x0068, 0x0061, 0,
+ 15, 0x33CB, 0x0048, 0x0050, 0,
+ 15, 0x33CC, 0x0069, 0x006E, 0,
+ 15, 0x33CD, 0x004B, 0x004B, 0,
+ 15, 0x33CE, 0x004B, 0x004D, 0,
+ 15, 0x33CF, 0x006B, 0x0074, 0,
+ 15, 0x33D0, 0x006C, 0x006D, 0,
+ 15, 0x33D1, 0x006C, 0x006E, 0,
+ 15, 0x33D2, 0x006C, 0x006F, 0x0067, 0,
+ 15, 0x33D3, 0x006C, 0x0078, 0,
+ 15, 0x33D4, 0x006D, 0x0062, 0,
+ 15, 0x33D5, 0x006D, 0x0069, 0x006C, 0,
+ 15, 0x33D6, 0x006D, 0x006F, 0x006C, 0,
+ 15, 0x33D7, 0x0050, 0x0048, 0,
+ 15, 0x33D8, 0x0070, 0x002E, 0x006D, 0x002E, 0,
+ 15, 0x33D9, 0x0050, 0x0050, 0x004D, 0,
+ 15, 0x33DA, 0x0050, 0x0052, 0,
+ 15, 0x33DB, 0x0073, 0x0072, 0,
+ 15, 0x33DC, 0x0053, 0x0076, 0,
+ 15, 0x33DD, 0x0057, 0x0062, 0,
+ 16, 0x33E0, 0x0031, 0x65E5, 0,
+ 16, 0x33E1, 0x0032, 0x65E5, 0,
+ 16, 0x33E2, 0x0033, 0x65E5, 0,
+ 16, 0x33E3, 0x0034, 0x65E5, 0,
+ 16, 0x33E4, 0x0035, 0x65E5, 0,
+ 16, 0x33E5, 0x0036, 0x65E5, 0,
+ 16, 0x33E6, 0x0037, 0x65E5, 0,
+ 16, 0x33E7, 0x0038, 0x65E5, 0,
+ 16, 0x33E8, 0x0039, 0x65E5, 0,
+ 16, 0x33E9, 0x0031, 0x0030, 0x65E5, 0,
+ 16, 0x33EA, 0x0031, 0x0031, 0x65E5, 0,
+ 16, 0x33EB, 0x0031, 0x0032, 0x65E5, 0,
+ 16, 0x33EC, 0x0031, 0x0033, 0x65E5, 0,
+ 16, 0x33ED, 0x0031, 0x0034, 0x65E5, 0,
+ 16, 0x33EE, 0x0031, 0x0035, 0x65E5, 0,
+ 16, 0x33EF, 0x0031, 0x0036, 0x65E5, 0,
+ 16, 0x33F0, 0x0031, 0x0037, 0x65E5, 0,
+ 16, 0x33F1, 0x0031, 0x0038, 0x65E5, 0,
+ 16, 0x33F2, 0x0031, 0x0039, 0x65E5, 0,
+ 16, 0x33F3, 0x0032, 0x0030, 0x65E5, 0,
+ 16, 0x33F4, 0x0032, 0x0031, 0x65E5, 0,
+ 16, 0x33F5, 0x0032, 0x0032, 0x65E5, 0,
+ 16, 0x33F6, 0x0032, 0x0033, 0x65E5, 0,
+ 16, 0x33F7, 0x0032, 0x0034, 0x65E5, 0,
+ 16, 0x33F8, 0x0032, 0x0035, 0x65E5, 0,
+ 16, 0x33F9, 0x0032, 0x0036, 0x65E5, 0,
+ 16, 0x33FA, 0x0032, 0x0037, 0x65E5, 0,
+ 16, 0x33FB, 0x0032, 0x0038, 0x65E5, 0,
+ 16, 0x33FC, 0x0032, 0x0039, 0x65E5, 0,
+ 16, 0x33FD, 0x0033, 0x0030, 0x65E5, 0,
+ 16, 0x33FE, 0x0033, 0x0031, 0x65E5, 0,
+ 1, 0xF900, 0x8C48, 0,
+ 1, 0xF901, 0x66F4, 0,
+ 1, 0xF902, 0x8ECA, 0,
+ 1, 0xF903, 0x8CC8, 0,
+ 1, 0xF904, 0x6ED1, 0,
+ 1, 0xF905, 0x4E32, 0,
+ 1, 0xF906, 0x53E5, 0,
+ 1, 0xF907, 0x9F9C, 0,
+ 1, 0xF908, 0x9F9C, 0,
+ 1, 0xF909, 0x5951, 0,
+ 1, 0xF90A, 0x91D1, 0,
+ 1, 0xF90B, 0x5587, 0,
+ 1, 0xF90C, 0x5948, 0,
+ 1, 0xF90D, 0x61F6, 0,
+ 1, 0xF90E, 0x7669, 0,
+ 1, 0xF90F, 0x7F85, 0,
+ 1, 0xF910, 0x863F, 0,
+ 1, 0xF911, 0x87BA, 0,
+ 1, 0xF912, 0x88F8, 0,
+ 1, 0xF913, 0x908F, 0,
+ 1, 0xF914, 0x6A02, 0,
+ 1, 0xF915, 0x6D1B, 0,
+ 1, 0xF916, 0x70D9, 0,
+ 1, 0xF917, 0x73DE, 0,
+ 1, 0xF918, 0x843D, 0,
+ 1, 0xF919, 0x916A, 0,
+ 1, 0xF91A, 0x99F1, 0,
+ 1, 0xF91B, 0x4E82, 0,
+ 1, 0xF91C, 0x5375, 0,
+ 1, 0xF91D, 0x6B04, 0,
+ 1, 0xF91E, 0x721B, 0,
+ 1, 0xF91F, 0x862D, 0,
+ 1, 0xF920, 0x9E1E, 0,
+ 1, 0xF921, 0x5D50, 0,
+ 1, 0xF922, 0x6FEB, 0,
+ 1, 0xF923, 0x85CD, 0,
+ 1, 0xF924, 0x8964, 0,
+ 1, 0xF925, 0x62C9, 0,
+ 1, 0xF926, 0x81D8, 0,
+ 1, 0xF927, 0x881F, 0,
+ 1, 0xF928, 0x5ECA, 0,
+ 1, 0xF929, 0x6717, 0,
+ 1, 0xF92A, 0x6D6A, 0,
+ 1, 0xF92B, 0x72FC, 0,
+ 1, 0xF92C, 0x90CE, 0,
+ 1, 0xF92D, 0x4F86, 0,
+ 1, 0xF92E, 0x51B7, 0,
+ 1, 0xF92F, 0x52DE, 0,
+ 1, 0xF930, 0x64C4, 0,
+ 1, 0xF931, 0x6AD3, 0,
+ 1, 0xF932, 0x7210, 0,
+ 1, 0xF933, 0x76E7, 0,
+ 1, 0xF934, 0x8001, 0,
+ 1, 0xF935, 0x8606, 0,
+ 1, 0xF936, 0x865C, 0,
+ 1, 0xF937, 0x8DEF, 0,
+ 1, 0xF938, 0x9732, 0,
+ 1, 0xF939, 0x9B6F, 0,
+ 1, 0xF93A, 0x9DFA, 0,
+ 1, 0xF93B, 0x788C, 0,
+ 1, 0xF93C, 0x797F, 0,
+ 1, 0xF93D, 0x7DA0, 0,
+ 1, 0xF93E, 0x83C9, 0,
+ 1, 0xF93F, 0x9304, 0,
+ 1, 0xF940, 0x9E7F, 0,
+ 1, 0xF941, 0x8AD6, 0,
+ 1, 0xF942, 0x58DF, 0,
+ 1, 0xF943, 0x5F04, 0,
+ 1, 0xF944, 0x7C60, 0,
+ 1, 0xF945, 0x807E, 0,
+ 1, 0xF946, 0x7262, 0,
+ 1, 0xF947, 0x78CA, 0,
+ 1, 0xF948, 0x8CC2, 0,
+ 1, 0xF949, 0x96F7, 0,
+ 1, 0xF94A, 0x58D8, 0,
+ 1, 0xF94B, 0x5C62, 0,
+ 1, 0xF94C, 0x6A13, 0,
+ 1, 0xF94D, 0x6DDA, 0,
+ 1, 0xF94E, 0x6F0F, 0,
+ 1, 0xF94F, 0x7D2F, 0,
+ 1, 0xF950, 0x7E37, 0,
+ 1, 0xF951, 0x964B, 0,
+ 1, 0xF952, 0x52D2, 0,
+ 1, 0xF953, 0x808B, 0,
+ 1, 0xF954, 0x51DC, 0,
+ 1, 0xF955, 0x51CC, 0,
+ 1, 0xF956, 0x7A1C, 0,
+ 1, 0xF957, 0x7DBE, 0,
+ 1, 0xF958, 0x83F1, 0,
+ 1, 0xF959, 0x9675, 0,
+ 1, 0xF95A, 0x8B80, 0,
+ 1, 0xF95B, 0x62CF, 0,
+ 1, 0xF95C, 0x6A02, 0,
+ 1, 0xF95D, 0x8AFE, 0,
+ 1, 0xF95E, 0x4E39, 0,
+ 1, 0xF95F, 0x5BE7, 0,
+ 1, 0xF960, 0x6012, 0,
+ 1, 0xF961, 0x7387, 0,
+ 1, 0xF962, 0x7570, 0,
+ 1, 0xF963, 0x5317, 0,
+ 1, 0xF964, 0x78FB, 0,
+ 1, 0xF965, 0x4FBF, 0,
+ 1, 0xF966, 0x5FA9, 0,
+ 1, 0xF967, 0x4E0D, 0,
+ 1, 0xF968, 0x6CCC, 0,
+ 1, 0xF969, 0x6578, 0,
+ 1, 0xF96A, 0x7D22, 0,
+ 1, 0xF96B, 0x53C3, 0,
+ 1, 0xF96C, 0x585E, 0,
+ 1, 0xF96D, 0x7701, 0,
+ 1, 0xF96E, 0x8449, 0,
+ 1, 0xF96F, 0x8AAA, 0,
+ 1, 0xF970, 0x6BBA, 0,
+ 1, 0xF971, 0x8FB0, 0,
+ 1, 0xF972, 0x6C88, 0,
+ 1, 0xF973, 0x62FE, 0,
+ 1, 0xF974, 0x82E5, 0,
+ 1, 0xF975, 0x63A0, 0,
+ 1, 0xF976, 0x7565, 0,
+ 1, 0xF977, 0x4EAE, 0,
+ 1, 0xF978, 0x5169, 0,
+ 1, 0xF979, 0x51C9, 0,
+ 1, 0xF97A, 0x6881, 0,
+ 1, 0xF97B, 0x7CE7, 0,
+ 1, 0xF97C, 0x826F, 0,
+ 1, 0xF97D, 0x8AD2, 0,
+ 1, 0xF97E, 0x91CF, 0,
+ 1, 0xF97F, 0x52F5, 0,
+ 1, 0xF980, 0x5442, 0,
+ 1, 0xF981, 0x5973, 0,
+ 1, 0xF982, 0x5EEC, 0,
+ 1, 0xF983, 0x65C5, 0,
+ 1, 0xF984, 0x6FFE, 0,
+ 1, 0xF985, 0x792A, 0,
+ 1, 0xF986, 0x95AD, 0,
+ 1, 0xF987, 0x9A6A, 0,
+ 1, 0xF988, 0x9E97, 0,
+ 1, 0xF989, 0x9ECE, 0,
+ 1, 0xF98A, 0x529B, 0,
+ 1, 0xF98B, 0x66C6, 0,
+ 1, 0xF98C, 0x6B77, 0,
+ 1, 0xF98D, 0x8F62, 0,
+ 1, 0xF98E, 0x5E74, 0,
+ 1, 0xF98F, 0x6190, 0,
+ 1, 0xF990, 0x6200, 0,
+ 1, 0xF991, 0x649A, 0,
+ 1, 0xF992, 0x6F23, 0,
+ 1, 0xF993, 0x7149, 0,
+ 1, 0xF994, 0x7489, 0,
+ 1, 0xF995, 0x79CA, 0,
+ 1, 0xF996, 0x7DF4, 0,
+ 1, 0xF997, 0x806F, 0,
+ 1, 0xF998, 0x8F26, 0,
+ 1, 0xF999, 0x84EE, 0,
+ 1, 0xF99A, 0x9023, 0,
+ 1, 0xF99B, 0x934A, 0,
+ 1, 0xF99C, 0x5217, 0,
+ 1, 0xF99D, 0x52A3, 0,
+ 1, 0xF99E, 0x54BD, 0,
+ 1, 0xF99F, 0x70C8, 0,
+ 1, 0xF9A0, 0x88C2, 0,
+ 1, 0xF9A1, 0x8AAA, 0,
+ 1, 0xF9A2, 0x5EC9, 0,
+ 1, 0xF9A3, 0x5FF5, 0,
+ 1, 0xF9A4, 0x637B, 0,
+ 1, 0xF9A5, 0x6BAE, 0,
+ 1, 0xF9A6, 0x7C3E, 0,
+ 1, 0xF9A7, 0x7375, 0,
+ 1, 0xF9A8, 0x4EE4, 0,
+ 1, 0xF9A9, 0x56F9, 0,
+ 1, 0xF9AA, 0x5BE7, 0,
+ 1, 0xF9AB, 0x5DBA, 0,
+ 1, 0xF9AC, 0x601C, 0,
+ 1, 0xF9AD, 0x73B2, 0,
+ 1, 0xF9AE, 0x7469, 0,
+ 1, 0xF9AF, 0x7F9A, 0,
+ 1, 0xF9B0, 0x8046, 0,
+ 1, 0xF9B1, 0x9234, 0,
+ 1, 0xF9B2, 0x96F6, 0,
+ 1, 0xF9B3, 0x9748, 0,
+ 1, 0xF9B4, 0x9818, 0,
+ 1, 0xF9B5, 0x4F8B, 0,
+ 1, 0xF9B6, 0x79AE, 0,
+ 1, 0xF9B7, 0x91B4, 0,
+ 1, 0xF9B8, 0x96B8, 0,
+ 1, 0xF9B9, 0x60E1, 0,
+ 1, 0xF9BA, 0x4E86, 0,
+ 1, 0xF9BB, 0x50DA, 0,
+ 1, 0xF9BC, 0x5BEE, 0,
+ 1, 0xF9BD, 0x5C3F, 0,
+ 1, 0xF9BE, 0x6599, 0,
+ 1, 0xF9BF, 0x6A02, 0,
+ 1, 0xF9C0, 0x71CE, 0,
+ 1, 0xF9C1, 0x7642, 0,
+ 1, 0xF9C2, 0x84FC, 0,
+ 1, 0xF9C3, 0x907C, 0,
+ 1, 0xF9C4, 0x9F8D, 0,
+ 1, 0xF9C5, 0x6688, 0,
+ 1, 0xF9C6, 0x962E, 0,
+ 1, 0xF9C7, 0x5289, 0,
+ 1, 0xF9C8, 0x677B, 0,
+ 1, 0xF9C9, 0x67F3, 0,
+ 1, 0xF9CA, 0x6D41, 0,
+ 1, 0xF9CB, 0x6E9C, 0,
+ 1, 0xF9CC, 0x7409, 0,
+ 1, 0xF9CD, 0x7559, 0,
+ 1, 0xF9CE, 0x786B, 0,
+ 1, 0xF9CF, 0x7D10, 0,
+ 1, 0xF9D0, 0x985E, 0,
+ 1, 0xF9D1, 0x516D, 0,
+ 1, 0xF9D2, 0x622E, 0,
+ 1, 0xF9D3, 0x9678, 0,
+ 1, 0xF9D4, 0x502B, 0,
+ 1, 0xF9D5, 0x5D19, 0,
+ 1, 0xF9D6, 0x6DEA, 0,
+ 1, 0xF9D7, 0x8F2A, 0,
+ 1, 0xF9D8, 0x5F8B, 0,
+ 1, 0xF9D9, 0x6144, 0,
+ 1, 0xF9DA, 0x6817, 0,
+ 1, 0xF9DB, 0x7387, 0,
+ 1, 0xF9DC, 0x9686, 0,
+ 1, 0xF9DD, 0x5229, 0,
+ 1, 0xF9DE, 0x540F, 0,
+ 1, 0xF9DF, 0x5C65, 0,
+ 1, 0xF9E0, 0x6613, 0,
+ 1, 0xF9E1, 0x674E, 0,
+ 1, 0xF9E2, 0x68A8, 0,
+ 1, 0xF9E3, 0x6CE5, 0,
+ 1, 0xF9E4, 0x7406, 0,
+ 1, 0xF9E5, 0x75E2, 0,
+ 1, 0xF9E6, 0x7F79, 0,
+ 1, 0xF9E7, 0x88CF, 0,
+ 1, 0xF9E8, 0x88E1, 0,
+ 1, 0xF9E9, 0x91CC, 0,
+ 1, 0xF9EA, 0x96E2, 0,
+ 1, 0xF9EB, 0x533F, 0,
+ 1, 0xF9EC, 0x6EBA, 0,
+ 1, 0xF9ED, 0x541D, 0,
+ 1, 0xF9EE, 0x71D0, 0,
+ 1, 0xF9EF, 0x7498, 0,
+ 1, 0xF9F0, 0x85FA, 0,
+ 1, 0xF9F1, 0x96A3, 0,
+ 1, 0xF9F2, 0x9C57, 0,
+ 1, 0xF9F3, 0x9E9F, 0,
+ 1, 0xF9F4, 0x6797, 0,
+ 1, 0xF9F5, 0x6DCB, 0,
+ 1, 0xF9F6, 0x81E8, 0,
+ 1, 0xF9F7, 0x7ACB, 0,
+ 1, 0xF9F8, 0x7B20, 0,
+ 1, 0xF9F9, 0x7C92, 0,
+ 1, 0xF9FA, 0x72C0, 0,
+ 1, 0xF9FB, 0x7099, 0,
+ 1, 0xF9FC, 0x8B58, 0,
+ 1, 0xF9FD, 0x4EC0, 0,
+ 1, 0xF9FE, 0x8336, 0,
+ 1, 0xF9FF, 0x523A, 0,
+ 1, 0xFA00, 0x5207, 0,
+ 1, 0xFA01, 0x5EA6, 0,
+ 1, 0xFA02, 0x62D3, 0,
+ 1, 0xFA03, 0x7CD6, 0,
+ 1, 0xFA04, 0x5B85, 0,
+ 1, 0xFA05, 0x6D1E, 0,
+ 1, 0xFA06, 0x66B4, 0,
+ 1, 0xFA07, 0x8F3B, 0,
+ 1, 0xFA08, 0x884C, 0,
+ 1, 0xFA09, 0x964D, 0,
+ 1, 0xFA0A, 0x898B, 0,
+ 1, 0xFA0B, 0x5ED3, 0,
+ 1, 0xFA0C, 0x5140, 0,
+ 1, 0xFA0D, 0x55C0, 0,
+ 1, 0xFA10, 0x585A, 0,
+ 1, 0xFA12, 0x6674, 0,
+ 1, 0xFA15, 0x51DE, 0,
+ 1, 0xFA16, 0x732A, 0,
+ 1, 0xFA17, 0x76CA, 0,
+ 1, 0xFA18, 0x793C, 0,
+ 1, 0xFA19, 0x795E, 0,
+ 1, 0xFA1A, 0x7965, 0,
+ 1, 0xFA1B, 0x798F, 0,
+ 1, 0xFA1C, 0x9756, 0,
+ 1, 0xFA1D, 0x7CBE, 0,
+ 1, 0xFA1E, 0x7FBD, 0,
+ 1, 0xFA20, 0x8612, 0,
+ 1, 0xFA22, 0x8AF8, 0,
+ 1, 0xFA25, 0x9038, 0,
+ 1, 0xFA26, 0x90FD, 0,
+ 1, 0xFA2A, 0x98EF, 0,
+ 1, 0xFA2B, 0x98FC, 0,
+ 1, 0xFA2C, 0x9928, 0,
+ 1, 0xFA2D, 0x9DB4, 0,
+ 1, 0xFA30, 0x4FAE, 0,
+ 1, 0xFA31, 0x50E7, 0,
+ 1, 0xFA32, 0x514D, 0,
+ 1, 0xFA33, 0x52C9, 0,
+ 1, 0xFA34, 0x52E4, 0,
+ 1, 0xFA35, 0x5351, 0,
+ 1, 0xFA36, 0x559D, 0,
+ 1, 0xFA37, 0x5606, 0,
+ 1, 0xFA38, 0x5668, 0,
+ 1, 0xFA39, 0x5840, 0,
+ 1, 0xFA3A, 0x58A8, 0,
+ 1, 0xFA3B, 0x5C64, 0,
+ 1, 0xFA3C, 0x5C6E, 0,
+ 1, 0xFA3D, 0x6094, 0,
+ 1, 0xFA3E, 0x6168, 0,
+ 1, 0xFA3F, 0x618E, 0,
+ 1, 0xFA40, 0x61F2, 0,
+ 1, 0xFA41, 0x654F, 0,
+ 1, 0xFA42, 0x65E2, 0,
+ 1, 0xFA43, 0x6691, 0,
+ 1, 0xFA44, 0x6885, 0,
+ 1, 0xFA45, 0x6D77, 0,
+ 1, 0xFA46, 0x6E1A, 0,
+ 1, 0xFA47, 0x6F22, 0,
+ 1, 0xFA48, 0x716E, 0,
+ 1, 0xFA49, 0x722B, 0,
+ 1, 0xFA4A, 0x7422, 0,
+ 1, 0xFA4B, 0x7891, 0,
+ 1, 0xFA4C, 0x793E, 0,
+ 1, 0xFA4D, 0x7949, 0,
+ 1, 0xFA4E, 0x7948, 0,
+ 1, 0xFA4F, 0x7950, 0,
+ 1, 0xFA50, 0x7956, 0,
+ 1, 0xFA51, 0x795D, 0,
+ 1, 0xFA52, 0x798D, 0,
+ 1, 0xFA53, 0x798E, 0,
+ 1, 0xFA54, 0x7A40, 0,
+ 1, 0xFA55, 0x7A81, 0,
+ 1, 0xFA56, 0x7BC0, 0,
+ 1, 0xFA57, 0x7DF4, 0,
+ 1, 0xFA58, 0x7E09, 0,
+ 1, 0xFA59, 0x7E41, 0,
+ 1, 0xFA5A, 0x7F72, 0,
+ 1, 0xFA5B, 0x8005, 0,
+ 1, 0xFA5C, 0x81ED, 0,
+ 1, 0xFA5D, 0x8279, 0,
+ 1, 0xFA5E, 0x8279, 0,
+ 1, 0xFA5F, 0x8457, 0,
+ 1, 0xFA60, 0x8910, 0,
+ 1, 0xFA61, 0x8996, 0,
+ 1, 0xFA62, 0x8B01, 0,
+ 1, 0xFA63, 0x8B39, 0,
+ 1, 0xFA64, 0x8CD3, 0,
+ 1, 0xFA65, 0x8D08, 0,
+ 1, 0xFA66, 0x8FB6, 0,
+ 1, 0xFA67, 0x9038, 0,
+ 1, 0xFA68, 0x96E3, 0,
+ 1, 0xFA69, 0x97FF, 0,
+ 1, 0xFA6A, 0x983B, 0,
+ 16, 0xFB00, 0x0066, 0x0066, 0,
+ 16, 0xFB01, 0x0066, 0x0069, 0,
+ 16, 0xFB02, 0x0066, 0x006C, 0,
+ 16, 0xFB03, 0x0066, 0x0066, 0x0069, 0,
+ 16, 0xFB04, 0x0066, 0x0066, 0x006C, 0,
+ 16, 0xFB05, 0x017F, 0x0074, 0,
+ 16, 0xFB06, 0x0073, 0x0074, 0,
+ 16, 0xFB13, 0x0574, 0x0576, 0,
+ 16, 0xFB14, 0x0574, 0x0565, 0,
+ 16, 0xFB15, 0x0574, 0x056B, 0,
+ 16, 0xFB16, 0x057E, 0x0576, 0,
+ 16, 0xFB17, 0x0574, 0x056D, 0,
+ 1, 0xFB1D, 0x05D9, 0x05B4, 0,
+ 1, 0xFB1F, 0x05F2, 0x05B7, 0,
+ 2, 0xFB20, 0x05E2, 0,
+ 2, 0xFB21, 0x05D0, 0,
+ 2, 0xFB22, 0x05D3, 0,
+ 2, 0xFB23, 0x05D4, 0,
+ 2, 0xFB24, 0x05DB, 0,
+ 2, 0xFB25, 0x05DC, 0,
+ 2, 0xFB26, 0x05DD, 0,
+ 2, 0xFB27, 0x05E8, 0,
+ 2, 0xFB28, 0x05EA, 0,
+ 2, 0xFB29, 0x002B, 0,
+ 1, 0xFB2A, 0x05E9, 0x05C1, 0,
+ 1, 0xFB2B, 0x05E9, 0x05C2, 0,
+ 1, 0xFB2C, 0xFB49, 0x05C1, 0,
+ 1, 0xFB2D, 0xFB49, 0x05C2, 0,
+ 1, 0xFB2E, 0x05D0, 0x05B7, 0,
+ 1, 0xFB2F, 0x05D0, 0x05B8, 0,
+ 1, 0xFB30, 0x05D0, 0x05BC, 0,
+ 1, 0xFB31, 0x05D1, 0x05BC, 0,
+ 1, 0xFB32, 0x05D2, 0x05BC, 0,
+ 1, 0xFB33, 0x05D3, 0x05BC, 0,
+ 1, 0xFB34, 0x05D4, 0x05BC, 0,
+ 1, 0xFB35, 0x05D5, 0x05BC, 0,
+ 1, 0xFB36, 0x05D6, 0x05BC, 0,
+ 1, 0xFB38, 0x05D8, 0x05BC, 0,
+ 1, 0xFB39, 0x05D9, 0x05BC, 0,
+ 1, 0xFB3A, 0x05DA, 0x05BC, 0,
+ 1, 0xFB3B, 0x05DB, 0x05BC, 0,
+ 1, 0xFB3C, 0x05DC, 0x05BC, 0,
+ 1, 0xFB3E, 0x05DE, 0x05BC, 0,
+ 1, 0xFB40, 0x05E0, 0x05BC, 0,
+ 1, 0xFB41, 0x05E1, 0x05BC, 0,
+ 1, 0xFB43, 0x05E3, 0x05BC, 0,
+ 1, 0xFB44, 0x05E4, 0x05BC, 0,
+ 1, 0xFB46, 0x05E6, 0x05BC, 0,
+ 1, 0xFB47, 0x05E7, 0x05BC, 0,
+ 1, 0xFB48, 0x05E8, 0x05BC, 0,
+ 1, 0xFB49, 0x05E9, 0x05BC, 0,
+ 1, 0xFB4A, 0x05EA, 0x05BC, 0,
+ 1, 0xFB4B, 0x05D5, 0x05B9, 0,
+ 1, 0xFB4C, 0x05D1, 0x05BF, 0,
+ 1, 0xFB4D, 0x05DB, 0x05BF, 0,
+ 1, 0xFB4E, 0x05E4, 0x05BF, 0,
+ 16, 0xFB4F, 0x05D0, 0x05DC, 0,
+ 7, 0xFB50, 0x0671, 0,
+ 6, 0xFB51, 0x0671, 0,
+ 7, 0xFB52, 0x067B, 0,
+ 6, 0xFB53, 0x067B, 0,
+ 4, 0xFB54, 0x067B, 0,
+ 5, 0xFB55, 0x067B, 0,
+ 7, 0xFB56, 0x067E, 0,
+ 6, 0xFB57, 0x067E, 0,
+ 4, 0xFB58, 0x067E, 0,
+ 5, 0xFB59, 0x067E, 0,
+ 7, 0xFB5A, 0x0680, 0,
+ 6, 0xFB5B, 0x0680, 0,
+ 4, 0xFB5C, 0x0680, 0,
+ 5, 0xFB5D, 0x0680, 0,
+ 7, 0xFB5E, 0x067A, 0,
+ 6, 0xFB5F, 0x067A, 0,
+ 4, 0xFB60, 0x067A, 0,
+ 5, 0xFB61, 0x067A, 0,
+ 7, 0xFB62, 0x067F, 0,
+ 6, 0xFB63, 0x067F, 0,
+ 4, 0xFB64, 0x067F, 0,
+ 5, 0xFB65, 0x067F, 0,
+ 7, 0xFB66, 0x0679, 0,
+ 6, 0xFB67, 0x0679, 0,
+ 4, 0xFB68, 0x0679, 0,
+ 5, 0xFB69, 0x0679, 0,
+ 7, 0xFB6A, 0x06A4, 0,
+ 6, 0xFB6B, 0x06A4, 0,
+ 4, 0xFB6C, 0x06A4, 0,
+ 5, 0xFB6D, 0x06A4, 0,
+ 7, 0xFB6E, 0x06A6, 0,
+ 6, 0xFB6F, 0x06A6, 0,
+ 4, 0xFB70, 0x06A6, 0,
+ 5, 0xFB71, 0x06A6, 0,
+ 7, 0xFB72, 0x0684, 0,
+ 6, 0xFB73, 0x0684, 0,
+ 4, 0xFB74, 0x0684, 0,
+ 5, 0xFB75, 0x0684, 0,
+ 7, 0xFB76, 0x0683, 0,
+ 6, 0xFB77, 0x0683, 0,
+ 4, 0xFB78, 0x0683, 0,
+ 5, 0xFB79, 0x0683, 0,
+ 7, 0xFB7A, 0x0686, 0,
+ 6, 0xFB7B, 0x0686, 0,
+ 4, 0xFB7C, 0x0686, 0,
+ 5, 0xFB7D, 0x0686, 0,
+ 7, 0xFB7E, 0x0687, 0,
+ 6, 0xFB7F, 0x0687, 0,
+ 4, 0xFB80, 0x0687, 0,
+ 5, 0xFB81, 0x0687, 0,
+ 7, 0xFB82, 0x068D, 0,
+ 6, 0xFB83, 0x068D, 0,
+ 7, 0xFB84, 0x068C, 0,
+ 6, 0xFB85, 0x068C, 0,
+ 7, 0xFB86, 0x068E, 0,
+ 6, 0xFB87, 0x068E, 0,
+ 7, 0xFB88, 0x0688, 0,
+ 6, 0xFB89, 0x0688, 0,
+ 7, 0xFB8A, 0x0698, 0,
+ 6, 0xFB8B, 0x0698, 0,
+ 7, 0xFB8C, 0x0691, 0,
+ 6, 0xFB8D, 0x0691, 0,
+ 7, 0xFB8E, 0x06A9, 0,
+ 6, 0xFB8F, 0x06A9, 0,
+ 4, 0xFB90, 0x06A9, 0,
+ 5, 0xFB91, 0x06A9, 0,
+ 7, 0xFB92, 0x06AF, 0,
+ 6, 0xFB93, 0x06AF, 0,
+ 4, 0xFB94, 0x06AF, 0,
+ 5, 0xFB95, 0x06AF, 0,
+ 7, 0xFB96, 0x06B3, 0,
+ 6, 0xFB97, 0x06B3, 0,
+ 4, 0xFB98, 0x06B3, 0,
+ 5, 0xFB99, 0x06B3, 0,
+ 7, 0xFB9A, 0x06B1, 0,
+ 6, 0xFB9B, 0x06B1, 0,
+ 4, 0xFB9C, 0x06B1, 0,
+ 5, 0xFB9D, 0x06B1, 0,
+ 7, 0xFB9E, 0x06BA, 0,
+ 6, 0xFB9F, 0x06BA, 0,
+ 7, 0xFBA0, 0x06BB, 0,
+ 6, 0xFBA1, 0x06BB, 0,
+ 4, 0xFBA2, 0x06BB, 0,
+ 5, 0xFBA3, 0x06BB, 0,
+ 7, 0xFBA4, 0x06C0, 0,
+ 6, 0xFBA5, 0x06C0, 0,
+ 7, 0xFBA6, 0x06C1, 0,
+ 6, 0xFBA7, 0x06C1, 0,
+ 4, 0xFBA8, 0x06C1, 0,
+ 5, 0xFBA9, 0x06C1, 0,
+ 7, 0xFBAA, 0x06BE, 0,
+ 6, 0xFBAB, 0x06BE, 0,
+ 4, 0xFBAC, 0x06BE, 0,
+ 5, 0xFBAD, 0x06BE, 0,
+ 7, 0xFBAE, 0x06D2, 0,
+ 6, 0xFBAF, 0x06D2, 0,
+ 7, 0xFBB0, 0x06D3, 0,
+ 6, 0xFBB1, 0x06D3, 0,
+ 7, 0xFBD3, 0x06AD, 0,
+ 6, 0xFBD4, 0x06AD, 0,
+ 4, 0xFBD5, 0x06AD, 0,
+ 5, 0xFBD6, 0x06AD, 0,
+ 7, 0xFBD7, 0x06C7, 0,
+ 6, 0xFBD8, 0x06C7, 0,
+ 7, 0xFBD9, 0x06C6, 0,
+ 6, 0xFBDA, 0x06C6, 0,
+ 7, 0xFBDB, 0x06C8, 0,
+ 6, 0xFBDC, 0x06C8, 0,
+ 7, 0xFBDD, 0x0677, 0,
+ 7, 0xFBDE, 0x06CB, 0,
+ 6, 0xFBDF, 0x06CB, 0,
+ 7, 0xFBE0, 0x06C5, 0,
+ 6, 0xFBE1, 0x06C5, 0,
+ 7, 0xFBE2, 0x06C9, 0,
+ 6, 0xFBE3, 0x06C9, 0,
+ 7, 0xFBE4, 0x06D0, 0,
+ 6, 0xFBE5, 0x06D0, 0,
+ 4, 0xFBE6, 0x06D0, 0,
+ 5, 0xFBE7, 0x06D0, 0,
+ 4, 0xFBE8, 0x0649, 0,
+ 5, 0xFBE9, 0x0649, 0,
+ 7, 0xFBEA, 0x0626, 0x0627, 0,
+ 6, 0xFBEB, 0x0626, 0x0627, 0,
+ 7, 0xFBEC, 0x0626, 0x06D5, 0,
+ 6, 0xFBED, 0x0626, 0x06D5, 0,
+ 7, 0xFBEE, 0x0626, 0x0648, 0,
+ 6, 0xFBEF, 0x0626, 0x0648, 0,
+ 7, 0xFBF0, 0x0626, 0x06C7, 0,
+ 6, 0xFBF1, 0x0626, 0x06C7, 0,
+ 7, 0xFBF2, 0x0626, 0x06C6, 0,
+ 6, 0xFBF3, 0x0626, 0x06C6, 0,
+ 7, 0xFBF4, 0x0626, 0x06C8, 0,
+ 6, 0xFBF5, 0x0626, 0x06C8, 0,
+ 7, 0xFBF6, 0x0626, 0x06D0, 0,
+ 6, 0xFBF7, 0x0626, 0x06D0, 0,
+ 4, 0xFBF8, 0x0626, 0x06D0, 0,
+ 7, 0xFBF9, 0x0626, 0x0649, 0,
+ 6, 0xFBFA, 0x0626, 0x0649, 0,
+ 4, 0xFBFB, 0x0626, 0x0649, 0,
+ 7, 0xFBFC, 0x06CC, 0,
+ 6, 0xFBFD, 0x06CC, 0,
+ 4, 0xFBFE, 0x06CC, 0,
+ 5, 0xFBFF, 0x06CC, 0,
+ 7, 0xFC00, 0x0626, 0x062C, 0,
+ 7, 0xFC01, 0x0626, 0x062D, 0,
+ 7, 0xFC02, 0x0626, 0x0645, 0,
+ 7, 0xFC03, 0x0626, 0x0649, 0,
+ 7, 0xFC04, 0x0626, 0x064A, 0,
+ 7, 0xFC05, 0x0628, 0x062C, 0,
+ 7, 0xFC06, 0x0628, 0x062D, 0,
+ 7, 0xFC07, 0x0628, 0x062E, 0,
+ 7, 0xFC08, 0x0628, 0x0645, 0,
+ 7, 0xFC09, 0x0628, 0x0649, 0,
+ 7, 0xFC0A, 0x0628, 0x064A, 0,
+ 7, 0xFC0B, 0x062A, 0x062C, 0,
+ 7, 0xFC0C, 0x062A, 0x062D, 0,
+ 7, 0xFC0D, 0x062A, 0x062E, 0,
+ 7, 0xFC0E, 0x062A, 0x0645, 0,
+ 7, 0xFC0F, 0x062A, 0x0649, 0,
+ 7, 0xFC10, 0x062A, 0x064A, 0,
+ 7, 0xFC11, 0x062B, 0x062C, 0,
+ 7, 0xFC12, 0x062B, 0x0645, 0,
+ 7, 0xFC13, 0x062B, 0x0649, 0,
+ 7, 0xFC14, 0x062B, 0x064A, 0,
+ 7, 0xFC15, 0x062C, 0x062D, 0,
+ 7, 0xFC16, 0x062C, 0x0645, 0,
+ 7, 0xFC17, 0x062D, 0x062C, 0,
+ 7, 0xFC18, 0x062D, 0x0645, 0,
+ 7, 0xFC19, 0x062E, 0x062C, 0,
+ 7, 0xFC1A, 0x062E, 0x062D, 0,
+ 7, 0xFC1B, 0x062E, 0x0645, 0,
+ 7, 0xFC1C, 0x0633, 0x062C, 0,
+ 7, 0xFC1D, 0x0633, 0x062D, 0,
+ 7, 0xFC1E, 0x0633, 0x062E, 0,
+ 7, 0xFC1F, 0x0633, 0x0645, 0,
+ 7, 0xFC20, 0x0635, 0x062D, 0,
+ 7, 0xFC21, 0x0635, 0x0645, 0,
+ 7, 0xFC22, 0x0636, 0x062C, 0,
+ 7, 0xFC23, 0x0636, 0x062D, 0,
+ 7, 0xFC24, 0x0636, 0x062E, 0,
+ 7, 0xFC25, 0x0636, 0x0645, 0,
+ 7, 0xFC26, 0x0637, 0x062D, 0,
+ 7, 0xFC27, 0x0637, 0x0645, 0,
+ 7, 0xFC28, 0x0638, 0x0645, 0,
+ 7, 0xFC29, 0x0639, 0x062C, 0,
+ 7, 0xFC2A, 0x0639, 0x0645, 0,
+ 7, 0xFC2B, 0x063A, 0x062C, 0,
+ 7, 0xFC2C, 0x063A, 0x0645, 0,
+ 7, 0xFC2D, 0x0641, 0x062C, 0,
+ 7, 0xFC2E, 0x0641, 0x062D, 0,
+ 7, 0xFC2F, 0x0641, 0x062E, 0,
+ 7, 0xFC30, 0x0641, 0x0645, 0,
+ 7, 0xFC31, 0x0641, 0x0649, 0,
+ 7, 0xFC32, 0x0641, 0x064A, 0,
+ 7, 0xFC33, 0x0642, 0x062D, 0,
+ 7, 0xFC34, 0x0642, 0x0645, 0,
+ 7, 0xFC35, 0x0642, 0x0649, 0,
+ 7, 0xFC36, 0x0642, 0x064A, 0,
+ 7, 0xFC37, 0x0643, 0x0627, 0,
+ 7, 0xFC38, 0x0643, 0x062C, 0,
+ 7, 0xFC39, 0x0643, 0x062D, 0,
+ 7, 0xFC3A, 0x0643, 0x062E, 0,
+ 7, 0xFC3B, 0x0643, 0x0644, 0,
+ 7, 0xFC3C, 0x0643, 0x0645, 0,
+ 7, 0xFC3D, 0x0643, 0x0649, 0,
+ 7, 0xFC3E, 0x0643, 0x064A, 0,
+ 7, 0xFC3F, 0x0644, 0x062C, 0,
+ 7, 0xFC40, 0x0644, 0x062D, 0,
+ 7, 0xFC41, 0x0644, 0x062E, 0,
+ 7, 0xFC42, 0x0644, 0x0645, 0,
+ 7, 0xFC43, 0x0644, 0x0649, 0,
+ 7, 0xFC44, 0x0644, 0x064A, 0,
+ 7, 0xFC45, 0x0645, 0x062C, 0,
+ 7, 0xFC46, 0x0645, 0x062D, 0,
+ 7, 0xFC47, 0x0645, 0x062E, 0,
+ 7, 0xFC48, 0x0645, 0x0645, 0,
+ 7, 0xFC49, 0x0645, 0x0649, 0,
+ 7, 0xFC4A, 0x0645, 0x064A, 0,
+ 7, 0xFC4B, 0x0646, 0x062C, 0,
+ 7, 0xFC4C, 0x0646, 0x062D, 0,
+ 7, 0xFC4D, 0x0646, 0x062E, 0,
+ 7, 0xFC4E, 0x0646, 0x0645, 0,
+ 7, 0xFC4F, 0x0646, 0x0649, 0,
+ 7, 0xFC50, 0x0646, 0x064A, 0,
+ 7, 0xFC51, 0x0647, 0x062C, 0,
+ 7, 0xFC52, 0x0647, 0x0645, 0,
+ 7, 0xFC53, 0x0647, 0x0649, 0,
+ 7, 0xFC54, 0x0647, 0x064A, 0,
+ 7, 0xFC55, 0x064A, 0x062C, 0,
+ 7, 0xFC56, 0x064A, 0x062D, 0,
+ 7, 0xFC57, 0x064A, 0x062E, 0,
+ 7, 0xFC58, 0x064A, 0x0645, 0,
+ 7, 0xFC59, 0x064A, 0x0649, 0,
+ 7, 0xFC5A, 0x064A, 0x064A, 0,
+ 7, 0xFC5B, 0x0630, 0x0670, 0,
+ 7, 0xFC5C, 0x0631, 0x0670, 0,
+ 7, 0xFC5D, 0x0649, 0x0670, 0,
+ 7, 0xFC5E, 0x0020, 0x064C, 0x0651, 0,
+ 7, 0xFC5F, 0x0020, 0x064D, 0x0651, 0,
+ 7, 0xFC60, 0x0020, 0x064E, 0x0651, 0,
+ 7, 0xFC61, 0x0020, 0x064F, 0x0651, 0,
+ 7, 0xFC62, 0x0020, 0x0650, 0x0651, 0,
+ 7, 0xFC63, 0x0020, 0x0651, 0x0670, 0,
+ 6, 0xFC64, 0x0626, 0x0631, 0,
+ 6, 0xFC65, 0x0626, 0x0632, 0,
+ 6, 0xFC66, 0x0626, 0x0645, 0,
+ 6, 0xFC67, 0x0626, 0x0646, 0,
+ 6, 0xFC68, 0x0626, 0x0649, 0,
+ 6, 0xFC69, 0x0626, 0x064A, 0,
+ 6, 0xFC6A, 0x0628, 0x0631, 0,
+ 6, 0xFC6B, 0x0628, 0x0632, 0,
+ 6, 0xFC6C, 0x0628, 0x0645, 0,
+ 6, 0xFC6D, 0x0628, 0x0646, 0,
+ 6, 0xFC6E, 0x0628, 0x0649, 0,
+ 6, 0xFC6F, 0x0628, 0x064A, 0,
+ 6, 0xFC70, 0x062A, 0x0631, 0,
+ 6, 0xFC71, 0x062A, 0x0632, 0,
+ 6, 0xFC72, 0x062A, 0x0645, 0,
+ 6, 0xFC73, 0x062A, 0x0646, 0,
+ 6, 0xFC74, 0x062A, 0x0649, 0,
+ 6, 0xFC75, 0x062A, 0x064A, 0,
+ 6, 0xFC76, 0x062B, 0x0631, 0,
+ 6, 0xFC77, 0x062B, 0x0632, 0,
+ 6, 0xFC78, 0x062B, 0x0645, 0,
+ 6, 0xFC79, 0x062B, 0x0646, 0,
+ 6, 0xFC7A, 0x062B, 0x0649, 0,
+ 6, 0xFC7B, 0x062B, 0x064A, 0,
+ 6, 0xFC7C, 0x0641, 0x0649, 0,
+ 6, 0xFC7D, 0x0641, 0x064A, 0,
+ 6, 0xFC7E, 0x0642, 0x0649, 0,
+ 6, 0xFC7F, 0x0642, 0x064A, 0,
+ 6, 0xFC80, 0x0643, 0x0627, 0,
+ 6, 0xFC81, 0x0643, 0x0644, 0,
+ 6, 0xFC82, 0x0643, 0x0645, 0,
+ 6, 0xFC83, 0x0643, 0x0649, 0,
+ 6, 0xFC84, 0x0643, 0x064A, 0,
+ 6, 0xFC85, 0x0644, 0x0645, 0,
+ 6, 0xFC86, 0x0644, 0x0649, 0,
+ 6, 0xFC87, 0x0644, 0x064A, 0,
+ 6, 0xFC88, 0x0645, 0x0627, 0,
+ 6, 0xFC89, 0x0645, 0x0645, 0,
+ 6, 0xFC8A, 0x0646, 0x0631, 0,
+ 6, 0xFC8B, 0x0646, 0x0632, 0,
+ 6, 0xFC8C, 0x0646, 0x0645, 0,
+ 6, 0xFC8D, 0x0646, 0x0646, 0,
+ 6, 0xFC8E, 0x0646, 0x0649, 0,
+ 6, 0xFC8F, 0x0646, 0x064A, 0,
+ 6, 0xFC90, 0x0649, 0x0670, 0,
+ 6, 0xFC91, 0x064A, 0x0631, 0,
+ 6, 0xFC92, 0x064A, 0x0632, 0,
+ 6, 0xFC93, 0x064A, 0x0645, 0,
+ 6, 0xFC94, 0x064A, 0x0646, 0,
+ 6, 0xFC95, 0x064A, 0x0649, 0,
+ 6, 0xFC96, 0x064A, 0x064A, 0,
+ 4, 0xFC97, 0x0626, 0x062C, 0,
+ 4, 0xFC98, 0x0626, 0x062D, 0,
+ 4, 0xFC99, 0x0626, 0x062E, 0,
+ 4, 0xFC9A, 0x0626, 0x0645, 0,
+ 4, 0xFC9B, 0x0626, 0x0647, 0,
+ 4, 0xFC9C, 0x0628, 0x062C, 0,
+ 4, 0xFC9D, 0x0628, 0x062D, 0,
+ 4, 0xFC9E, 0x0628, 0x062E, 0,
+ 4, 0xFC9F, 0x0628, 0x0645, 0,
+ 4, 0xFCA0, 0x0628, 0x0647, 0,
+ 4, 0xFCA1, 0x062A, 0x062C, 0,
+ 4, 0xFCA2, 0x062A, 0x062D, 0,
+ 4, 0xFCA3, 0x062A, 0x062E, 0,
+ 4, 0xFCA4, 0x062A, 0x0645, 0,
+ 4, 0xFCA5, 0x062A, 0x0647, 0,
+ 4, 0xFCA6, 0x062B, 0x0645, 0,
+ 4, 0xFCA7, 0x062C, 0x062D, 0,
+ 4, 0xFCA8, 0x062C, 0x0645, 0,
+ 4, 0xFCA9, 0x062D, 0x062C, 0,
+ 4, 0xFCAA, 0x062D, 0x0645, 0,
+ 4, 0xFCAB, 0x062E, 0x062C, 0,
+ 4, 0xFCAC, 0x062E, 0x0645, 0,
+ 4, 0xFCAD, 0x0633, 0x062C, 0,
+ 4, 0xFCAE, 0x0633, 0x062D, 0,
+ 4, 0xFCAF, 0x0633, 0x062E, 0,
+ 4, 0xFCB0, 0x0633, 0x0645, 0,
+ 4, 0xFCB1, 0x0635, 0x062D, 0,
+ 4, 0xFCB2, 0x0635, 0x062E, 0,
+ 4, 0xFCB3, 0x0635, 0x0645, 0,
+ 4, 0xFCB4, 0x0636, 0x062C, 0,
+ 4, 0xFCB5, 0x0636, 0x062D, 0,
+ 4, 0xFCB6, 0x0636, 0x062E, 0,
+ 4, 0xFCB7, 0x0636, 0x0645, 0,
+ 4, 0xFCB8, 0x0637, 0x062D, 0,
+ 4, 0xFCB9, 0x0638, 0x0645, 0,
+ 4, 0xFCBA, 0x0639, 0x062C, 0,
+ 4, 0xFCBB, 0x0639, 0x0645, 0,
+ 4, 0xFCBC, 0x063A, 0x062C, 0,
+ 4, 0xFCBD, 0x063A, 0x0645, 0,
+ 4, 0xFCBE, 0x0641, 0x062C, 0,
+ 4, 0xFCBF, 0x0641, 0x062D, 0,
+ 4, 0xFCC0, 0x0641, 0x062E, 0,
+ 4, 0xFCC1, 0x0641, 0x0645, 0,
+ 4, 0xFCC2, 0x0642, 0x062D, 0,
+ 4, 0xFCC3, 0x0642, 0x0645, 0,
+ 4, 0xFCC4, 0x0643, 0x062C, 0,
+ 4, 0xFCC5, 0x0643, 0x062D, 0,
+ 4, 0xFCC6, 0x0643, 0x062E, 0,
+ 4, 0xFCC7, 0x0643, 0x0644, 0,
+ 4, 0xFCC8, 0x0643, 0x0645, 0,
+ 4, 0xFCC9, 0x0644, 0x062C, 0,
+ 4, 0xFCCA, 0x0644, 0x062D, 0,
+ 4, 0xFCCB, 0x0644, 0x062E, 0,
+ 4, 0xFCCC, 0x0644, 0x0645, 0,
+ 4, 0xFCCD, 0x0644, 0x0647, 0,
+ 4, 0xFCCE, 0x0645, 0x062C, 0,
+ 4, 0xFCCF, 0x0645, 0x062D, 0,
+ 4, 0xFCD0, 0x0645, 0x062E, 0,
+ 4, 0xFCD1, 0x0645, 0x0645, 0,
+ 4, 0xFCD2, 0x0646, 0x062C, 0,
+ 4, 0xFCD3, 0x0646, 0x062D, 0,
+ 4, 0xFCD4, 0x0646, 0x062E, 0,
+ 4, 0xFCD5, 0x0646, 0x0645, 0,
+ 4, 0xFCD6, 0x0646, 0x0647, 0,
+ 4, 0xFCD7, 0x0647, 0x062C, 0,
+ 4, 0xFCD8, 0x0647, 0x0645, 0,
+ 4, 0xFCD9, 0x0647, 0x0670, 0,
+ 4, 0xFCDA, 0x064A, 0x062C, 0,
+ 4, 0xFCDB, 0x064A, 0x062D, 0,
+ 4, 0xFCDC, 0x064A, 0x062E, 0,
+ 4, 0xFCDD, 0x064A, 0x0645, 0,
+ 4, 0xFCDE, 0x064A, 0x0647, 0,
+ 5, 0xFCDF, 0x0626, 0x0645, 0,
+ 5, 0xFCE0, 0x0626, 0x0647, 0,
+ 5, 0xFCE1, 0x0628, 0x0645, 0,
+ 5, 0xFCE2, 0x0628, 0x0647, 0,
+ 5, 0xFCE3, 0x062A, 0x0645, 0,
+ 5, 0xFCE4, 0x062A, 0x0647, 0,
+ 5, 0xFCE5, 0x062B, 0x0645, 0,
+ 5, 0xFCE6, 0x062B, 0x0647, 0,
+ 5, 0xFCE7, 0x0633, 0x0645, 0,
+ 5, 0xFCE8, 0x0633, 0x0647, 0,
+ 5, 0xFCE9, 0x0634, 0x0645, 0,
+ 5, 0xFCEA, 0x0634, 0x0647, 0,
+ 5, 0xFCEB, 0x0643, 0x0644, 0,
+ 5, 0xFCEC, 0x0643, 0x0645, 0,
+ 5, 0xFCED, 0x0644, 0x0645, 0,
+ 5, 0xFCEE, 0x0646, 0x0645, 0,
+ 5, 0xFCEF, 0x0646, 0x0647, 0,
+ 5, 0xFCF0, 0x064A, 0x0645, 0,
+ 5, 0xFCF1, 0x064A, 0x0647, 0,
+ 5, 0xFCF2, 0x0640, 0x064E, 0x0651, 0,
+ 5, 0xFCF3, 0x0640, 0x064F, 0x0651, 0,
+ 5, 0xFCF4, 0x0640, 0x0650, 0x0651, 0,
+ 7, 0xFCF5, 0x0637, 0x0649, 0,
+ 7, 0xFCF6, 0x0637, 0x064A, 0,
+ 7, 0xFCF7, 0x0639, 0x0649, 0,
+ 7, 0xFCF8, 0x0639, 0x064A, 0,
+ 7, 0xFCF9, 0x063A, 0x0649, 0,
+ 7, 0xFCFA, 0x063A, 0x064A, 0,
+ 7, 0xFCFB, 0x0633, 0x0649, 0,
+ 7, 0xFCFC, 0x0633, 0x064A, 0,
+ 7, 0xFCFD, 0x0634, 0x0649, 0,
+ 7, 0xFCFE, 0x0634, 0x064A, 0,
+ 7, 0xFCFF, 0x062D, 0x0649, 0,
+ 7, 0xFD00, 0x062D, 0x064A, 0,
+ 7, 0xFD01, 0x062C, 0x0649, 0,
+ 7, 0xFD02, 0x062C, 0x064A, 0,
+ 7, 0xFD03, 0x062E, 0x0649, 0,
+ 7, 0xFD04, 0x062E, 0x064A, 0,
+ 7, 0xFD05, 0x0635, 0x0649, 0,
+ 7, 0xFD06, 0x0635, 0x064A, 0,
+ 7, 0xFD07, 0x0636, 0x0649, 0,
+ 7, 0xFD08, 0x0636, 0x064A, 0,
+ 7, 0xFD09, 0x0634, 0x062C, 0,
+ 7, 0xFD0A, 0x0634, 0x062D, 0,
+ 7, 0xFD0B, 0x0634, 0x062E, 0,
+ 7, 0xFD0C, 0x0634, 0x0645, 0,
+ 7, 0xFD0D, 0x0634, 0x0631, 0,
+ 7, 0xFD0E, 0x0633, 0x0631, 0,
+ 7, 0xFD0F, 0x0635, 0x0631, 0,
+ 7, 0xFD10, 0x0636, 0x0631, 0,
+ 6, 0xFD11, 0x0637, 0x0649, 0,
+ 6, 0xFD12, 0x0637, 0x064A, 0,
+ 6, 0xFD13, 0x0639, 0x0649, 0,
+ 6, 0xFD14, 0x0639, 0x064A, 0,
+ 6, 0xFD15, 0x063A, 0x0649, 0,
+ 6, 0xFD16, 0x063A, 0x064A, 0,
+ 6, 0xFD17, 0x0633, 0x0649, 0,
+ 6, 0xFD18, 0x0633, 0x064A, 0,
+ 6, 0xFD19, 0x0634, 0x0649, 0,
+ 6, 0xFD1A, 0x0634, 0x064A, 0,
+ 6, 0xFD1B, 0x062D, 0x0649, 0,
+ 6, 0xFD1C, 0x062D, 0x064A, 0,
+ 6, 0xFD1D, 0x062C, 0x0649, 0,
+ 6, 0xFD1E, 0x062C, 0x064A, 0,
+ 6, 0xFD1F, 0x062E, 0x0649, 0,
+ 6, 0xFD20, 0x062E, 0x064A, 0,
+ 6, 0xFD21, 0x0635, 0x0649, 0,
+ 6, 0xFD22, 0x0635, 0x064A, 0,
+ 6, 0xFD23, 0x0636, 0x0649, 0,
+ 6, 0xFD24, 0x0636, 0x064A, 0,
+ 6, 0xFD25, 0x0634, 0x062C, 0,
+ 6, 0xFD26, 0x0634, 0x062D, 0,
+ 6, 0xFD27, 0x0634, 0x062E, 0,
+ 6, 0xFD28, 0x0634, 0x0645, 0,
+ 6, 0xFD29, 0x0634, 0x0631, 0,
+ 6, 0xFD2A, 0x0633, 0x0631, 0,
+ 6, 0xFD2B, 0x0635, 0x0631, 0,
+ 6, 0xFD2C, 0x0636, 0x0631, 0,
+ 4, 0xFD2D, 0x0634, 0x062C, 0,
+ 4, 0xFD2E, 0x0634, 0x062D, 0,
+ 4, 0xFD2F, 0x0634, 0x062E, 0,
+ 4, 0xFD30, 0x0634, 0x0645, 0,
+ 4, 0xFD31, 0x0633, 0x0647, 0,
+ 4, 0xFD32, 0x0634, 0x0647, 0,
+ 4, 0xFD33, 0x0637, 0x0645, 0,
+ 5, 0xFD34, 0x0633, 0x062C, 0,
+ 5, 0xFD35, 0x0633, 0x062D, 0,
+ 5, 0xFD36, 0x0633, 0x062E, 0,
+ 5, 0xFD37, 0x0634, 0x062C, 0,
+ 5, 0xFD38, 0x0634, 0x062D, 0,
+ 5, 0xFD39, 0x0634, 0x062E, 0,
+ 5, 0xFD3A, 0x0637, 0x0645, 0,
+ 5, 0xFD3B, 0x0638, 0x0645, 0,
+ 6, 0xFD3C, 0x0627, 0x064B, 0,
+ 7, 0xFD3D, 0x0627, 0x064B, 0,
+ 4, 0xFD50, 0x062A, 0x062C, 0x0645, 0,
+ 6, 0xFD51, 0x062A, 0x062D, 0x062C, 0,
+ 4, 0xFD52, 0x062A, 0x062D, 0x062C, 0,
+ 4, 0xFD53, 0x062A, 0x062D, 0x0645, 0,
+ 4, 0xFD54, 0x062A, 0x062E, 0x0645, 0,
+ 4, 0xFD55, 0x062A, 0x0645, 0x062C, 0,
+ 4, 0xFD56, 0x062A, 0x0645, 0x062D, 0,
+ 4, 0xFD57, 0x062A, 0x0645, 0x062E, 0,
+ 6, 0xFD58, 0x062C, 0x0645, 0x062D, 0,
+ 4, 0xFD59, 0x062C, 0x0645, 0x062D, 0,
+ 6, 0xFD5A, 0x062D, 0x0645, 0x064A, 0,
+ 6, 0xFD5B, 0x062D, 0x0645, 0x0649, 0,
+ 4, 0xFD5C, 0x0633, 0x062D, 0x062C, 0,
+ 4, 0xFD5D, 0x0633, 0x062C, 0x062D, 0,
+ 6, 0xFD5E, 0x0633, 0x062C, 0x0649, 0,
+ 6, 0xFD5F, 0x0633, 0x0645, 0x062D, 0,
+ 4, 0xFD60, 0x0633, 0x0645, 0x062D, 0,
+ 4, 0xFD61, 0x0633, 0x0645, 0x062C, 0,
+ 6, 0xFD62, 0x0633, 0x0645, 0x0645, 0,
+ 4, 0xFD63, 0x0633, 0x0645, 0x0645, 0,
+ 6, 0xFD64, 0x0635, 0x062D, 0x062D, 0,
+ 4, 0xFD65, 0x0635, 0x062D, 0x062D, 0,
+ 6, 0xFD66, 0x0635, 0x0645, 0x0645, 0,
+ 6, 0xFD67, 0x0634, 0x062D, 0x0645, 0,
+ 4, 0xFD68, 0x0634, 0x062D, 0x0645, 0,
+ 6, 0xFD69, 0x0634, 0x062C, 0x064A, 0,
+ 6, 0xFD6A, 0x0634, 0x0645, 0x062E, 0,
+ 4, 0xFD6B, 0x0634, 0x0645, 0x062E, 0,
+ 6, 0xFD6C, 0x0634, 0x0645, 0x0645, 0,
+ 4, 0xFD6D, 0x0634, 0x0645, 0x0645, 0,
+ 6, 0xFD6E, 0x0636, 0x062D, 0x0649, 0,
+ 6, 0xFD6F, 0x0636, 0x062E, 0x0645, 0,
+ 4, 0xFD70, 0x0636, 0x062E, 0x0645, 0,
+ 6, 0xFD71, 0x0637, 0x0645, 0x062D, 0,
+ 4, 0xFD72, 0x0637, 0x0645, 0x062D, 0,
+ 4, 0xFD73, 0x0637, 0x0645, 0x0645, 0,
+ 6, 0xFD74, 0x0637, 0x0645, 0x064A, 0,
+ 6, 0xFD75, 0x0639, 0x062C, 0x0645, 0,
+ 6, 0xFD76, 0x0639, 0x0645, 0x0645, 0,
+ 4, 0xFD77, 0x0639, 0x0645, 0x0645, 0,
+ 6, 0xFD78, 0x0639, 0x0645, 0x0649, 0,
+ 6, 0xFD79, 0x063A, 0x0645, 0x0645, 0,
+ 6, 0xFD7A, 0x063A, 0x0645, 0x064A, 0,
+ 6, 0xFD7B, 0x063A, 0x0645, 0x0649, 0,
+ 6, 0xFD7C, 0x0641, 0x062E, 0x0645, 0,
+ 4, 0xFD7D, 0x0641, 0x062E, 0x0645, 0,
+ 6, 0xFD7E, 0x0642, 0x0645, 0x062D, 0,
+ 6, 0xFD7F, 0x0642, 0x0645, 0x0645, 0,
+ 6, 0xFD80, 0x0644, 0x062D, 0x0645, 0,
+ 6, 0xFD81, 0x0644, 0x062D, 0x064A, 0,
+ 6, 0xFD82, 0x0644, 0x062D, 0x0649, 0,
+ 4, 0xFD83, 0x0644, 0x062C, 0x062C, 0,
+ 6, 0xFD84, 0x0644, 0x062C, 0x062C, 0,
+ 6, 0xFD85, 0x0644, 0x062E, 0x0645, 0,
+ 4, 0xFD86, 0x0644, 0x062E, 0x0645, 0,
+ 6, 0xFD87, 0x0644, 0x0645, 0x062D, 0,
+ 4, 0xFD88, 0x0644, 0x0645, 0x062D, 0,
+ 4, 0xFD89, 0x0645, 0x062D, 0x062C, 0,
+ 4, 0xFD8A, 0x0645, 0x062D, 0x0645, 0,
+ 6, 0xFD8B, 0x0645, 0x062D, 0x064A, 0,
+ 4, 0xFD8C, 0x0645, 0x062C, 0x062D, 0,
+ 4, 0xFD8D, 0x0645, 0x062C, 0x0645, 0,
+ 4, 0xFD8E, 0x0645, 0x062E, 0x062C, 0,
+ 4, 0xFD8F, 0x0645, 0x062E, 0x0645, 0,
+ 4, 0xFD92, 0x0645, 0x062C, 0x062E, 0,
+ 4, 0xFD93, 0x0647, 0x0645, 0x062C, 0,
+ 4, 0xFD94, 0x0647, 0x0645, 0x0645, 0,
+ 4, 0xFD95, 0x0646, 0x062D, 0x0645, 0,
+ 6, 0xFD96, 0x0646, 0x062D, 0x0649, 0,
+ 6, 0xFD97, 0x0646, 0x062C, 0x0645, 0,
+ 4, 0xFD98, 0x0646, 0x062C, 0x0645, 0,
+ 6, 0xFD99, 0x0646, 0x062C, 0x0649, 0,
+ 6, 0xFD9A, 0x0646, 0x0645, 0x064A, 0,
+ 6, 0xFD9B, 0x0646, 0x0645, 0x0649, 0,
+ 6, 0xFD9C, 0x064A, 0x0645, 0x0645, 0,
+ 4, 0xFD9D, 0x064A, 0x0645, 0x0645, 0,
+ 6, 0xFD9E, 0x0628, 0x062E, 0x064A, 0,
+ 6, 0xFD9F, 0x062A, 0x062C, 0x064A, 0,
+ 6, 0xFDA0, 0x062A, 0x062C, 0x0649, 0,
+ 6, 0xFDA1, 0x062A, 0x062E, 0x064A, 0,
+ 6, 0xFDA2, 0x062A, 0x062E, 0x0649, 0,
+ 6, 0xFDA3, 0x062A, 0x0645, 0x064A, 0,
+ 6, 0xFDA4, 0x062A, 0x0645, 0x0649, 0,
+ 6, 0xFDA5, 0x062C, 0x0645, 0x064A, 0,
+ 6, 0xFDA6, 0x062C, 0x062D, 0x0649, 0,
+ 6, 0xFDA7, 0x062C, 0x0645, 0x0649, 0,
+ 6, 0xFDA8, 0x0633, 0x062E, 0x0649, 0,
+ 6, 0xFDA9, 0x0635, 0x062D, 0x064A, 0,
+ 6, 0xFDAA, 0x0634, 0x062D, 0x064A, 0,
+ 6, 0xFDAB, 0x0636, 0x062D, 0x064A, 0,
+ 6, 0xFDAC, 0x0644, 0x062C, 0x064A, 0,
+ 6, 0xFDAD, 0x0644, 0x0645, 0x064A, 0,
+ 6, 0xFDAE, 0x064A, 0x062D, 0x064A, 0,
+ 6, 0xFDAF, 0x064A, 0x062C, 0x064A, 0,
+ 6, 0xFDB0, 0x064A, 0x0645, 0x064A, 0,
+ 6, 0xFDB1, 0x0645, 0x0645, 0x064A, 0,
+ 6, 0xFDB2, 0x0642, 0x0645, 0x064A, 0,
+ 6, 0xFDB3, 0x0646, 0x062D, 0x064A, 0,
+ 4, 0xFDB4, 0x0642, 0x0645, 0x062D, 0,
+ 4, 0xFDB5, 0x0644, 0x062D, 0x0645, 0,
+ 6, 0xFDB6, 0x0639, 0x0645, 0x064A, 0,
+ 6, 0xFDB7, 0x0643, 0x0645, 0x064A, 0,
+ 4, 0xFDB8, 0x0646, 0x062C, 0x062D, 0,
+ 6, 0xFDB9, 0x0645, 0x062E, 0x064A, 0,
+ 4, 0xFDBA, 0x0644, 0x062C, 0x0645, 0,
+ 6, 0xFDBB, 0x0643, 0x0645, 0x0645, 0,
+ 6, 0xFDBC, 0x0644, 0x062C, 0x0645, 0,
+ 6, 0xFDBD, 0x0646, 0x062C, 0x062D, 0,
+ 6, 0xFDBE, 0x062C, 0x062D, 0x064A, 0,
+ 6, 0xFDBF, 0x062D, 0x062C, 0x064A, 0,
+ 6, 0xFDC0, 0x0645, 0x062C, 0x064A, 0,
+ 6, 0xFDC1, 0x0641, 0x0645, 0x064A, 0,
+ 6, 0xFDC2, 0x0628, 0x062D, 0x064A, 0,
+ 4, 0xFDC3, 0x0643, 0x0645, 0x0645, 0,
+ 4, 0xFDC4, 0x0639, 0x062C, 0x0645, 0,
+ 4, 0xFDC5, 0x0635, 0x0645, 0x0645, 0,
+ 6, 0xFDC6, 0x0633, 0x062E, 0x064A, 0,
+ 6, 0xFDC7, 0x0646, 0x062C, 0x064A, 0,
+ 7, 0xFDF0, 0x0635, 0x0644, 0x06D2, 0,
+ 7, 0xFDF1, 0x0642, 0x0644, 0x06D2, 0,
+ 7, 0xFDF2, 0x0627, 0x0644, 0x0644, 0x0647, 0,
+ 7, 0xFDF3, 0x0627, 0x0643, 0x0628, 0x0631, 0,
+ 7, 0xFDF4, 0x0645, 0x062D, 0x0645, 0x062F, 0,
+ 7, 0xFDF5, 0x0635, 0x0644, 0x0639, 0x0645, 0,
+ 7, 0xFDF6, 0x0631, 0x0633, 0x0648, 0x0644, 0,
+ 7, 0xFDF7, 0x0639, 0x0644, 0x064A, 0x0647, 0,
+ 7, 0xFDF8, 0x0648, 0x0633, 0x0644, 0x0645, 0,
+ 7, 0xFDF9, 0x0635, 0x0644, 0x0649, 0,
+ 7, 0xFDFA, 0x0635, 0x0644, 0x0649, 0x0020, 0x0627, 0x0644, 0x0644, 0x0647, 0x0020, 0x0639, 0x0644, 0x064A, 0x0647, 0x0020, 0x0648, 0x0633, 0x0644, 0x0645, 0,
+ 7, 0xFDFB, 0x062C, 0x0644, 0x0020, 0x062C, 0x0644, 0x0627, 0x0644, 0x0647, 0,
+ 7, 0xFDFC, 0x0631, 0x06CC, 0x0627, 0x0644, 0,
+ 11, 0xFE30, 0x2025, 0,
+ 11, 0xFE31, 0x2014, 0,
+ 11, 0xFE32, 0x2013, 0,
+ 11, 0xFE33, 0x005F, 0,
+ 11, 0xFE34, 0x005F, 0,
+ 11, 0xFE35, 0x0028, 0,
+ 11, 0xFE36, 0x0029, 0,
+ 11, 0xFE37, 0x007B, 0,
+ 11, 0xFE38, 0x007D, 0,
+ 11, 0xFE39, 0x3014, 0,
+ 11, 0xFE3A, 0x3015, 0,
+ 11, 0xFE3B, 0x3010, 0,
+ 11, 0xFE3C, 0x3011, 0,
+ 11, 0xFE3D, 0x300A, 0,
+ 11, 0xFE3E, 0x300B, 0,
+ 11, 0xFE3F, 0x3008, 0,
+ 11, 0xFE40, 0x3009, 0,
+ 11, 0xFE41, 0x300C, 0,
+ 11, 0xFE42, 0x300D, 0,
+ 11, 0xFE43, 0x300E, 0,
+ 11, 0xFE44, 0x300F, 0,
+ 16, 0xFE49, 0x203E, 0,
+ 16, 0xFE4A, 0x203E, 0,
+ 16, 0xFE4B, 0x203E, 0,
+ 16, 0xFE4C, 0x203E, 0,
+ 16, 0xFE4D, 0x005F, 0,
+ 16, 0xFE4E, 0x005F, 0,
+ 16, 0xFE4F, 0x005F, 0,
+ 14, 0xFE50, 0x002C, 0,
+ 14, 0xFE51, 0x3001, 0,
+ 14, 0xFE52, 0x002E, 0,
+ 14, 0xFE54, 0x003B, 0,
+ 14, 0xFE55, 0x003A, 0,
+ 14, 0xFE56, 0x003F, 0,
+ 14, 0xFE57, 0x0021, 0,
+ 14, 0xFE58, 0x2014, 0,
+ 14, 0xFE59, 0x0028, 0,
+ 14, 0xFE5A, 0x0029, 0,
+ 14, 0xFE5B, 0x007B, 0,
+ 14, 0xFE5C, 0x007D, 0,
+ 14, 0xFE5D, 0x3014, 0,
+ 14, 0xFE5E, 0x3015, 0,
+ 14, 0xFE5F, 0x0023, 0,
+ 14, 0xFE60, 0x0026, 0,
+ 14, 0xFE61, 0x002A, 0,
+ 14, 0xFE62, 0x002B, 0,
+ 14, 0xFE63, 0x002D, 0,
+ 14, 0xFE64, 0x003C, 0,
+ 14, 0xFE65, 0x003E, 0,
+ 14, 0xFE66, 0x003D, 0,
+ 14, 0xFE68, 0x005C, 0,
+ 14, 0xFE69, 0x0024, 0,
+ 14, 0xFE6A, 0x0025, 0,
+ 14, 0xFE6B, 0x0040, 0,
+ 7, 0xFE70, 0x0020, 0x064B, 0,
+ 5, 0xFE71, 0x0640, 0x064B, 0,
+ 7, 0xFE72, 0x0020, 0x064C, 0,
+ 7, 0xFE74, 0x0020, 0x064D, 0,
+ 7, 0xFE76, 0x0020, 0x064E, 0,
+ 5, 0xFE77, 0x0640, 0x064E, 0,
+ 7, 0xFE78, 0x0020, 0x064F, 0,
+ 5, 0xFE79, 0x0640, 0x064F, 0,
+ 7, 0xFE7A, 0x0020, 0x0650, 0,
+ 5, 0xFE7B, 0x0640, 0x0650, 0,
+ 7, 0xFE7C, 0x0020, 0x0651, 0,
+ 5, 0xFE7D, 0x0640, 0x0651, 0,
+ 7, 0xFE7E, 0x0020, 0x0652, 0,
+ 5, 0xFE7F, 0x0640, 0x0652, 0,
+ 7, 0xFE80, 0x0621, 0,
+ 7, 0xFE81, 0x0622, 0,
+ 6, 0xFE82, 0x0622, 0,
+ 7, 0xFE83, 0x0623, 0,
+ 6, 0xFE84, 0x0623, 0,
+ 7, 0xFE85, 0x0624, 0,
+ 6, 0xFE86, 0x0624, 0,
+ 7, 0xFE87, 0x0625, 0,
+ 6, 0xFE88, 0x0625, 0,
+ 7, 0xFE89, 0x0626, 0,
+ 6, 0xFE8A, 0x0626, 0,
+ 4, 0xFE8B, 0x0626, 0,
+ 5, 0xFE8C, 0x0626, 0,
+ 7, 0xFE8D, 0x0627, 0,
+ 6, 0xFE8E, 0x0627, 0,
+ 7, 0xFE8F, 0x0628, 0,
+ 6, 0xFE90, 0x0628, 0,
+ 4, 0xFE91, 0x0628, 0,
+ 5, 0xFE92, 0x0628, 0,
+ 7, 0xFE93, 0x0629, 0,
+ 6, 0xFE94, 0x0629, 0,
+ 7, 0xFE95, 0x062A, 0,
+ 6, 0xFE96, 0x062A, 0,
+ 4, 0xFE97, 0x062A, 0,
+ 5, 0xFE98, 0x062A, 0,
+ 7, 0xFE99, 0x062B, 0,
+ 6, 0xFE9A, 0x062B, 0,
+ 4, 0xFE9B, 0x062B, 0,
+ 5, 0xFE9C, 0x062B, 0,
+ 7, 0xFE9D, 0x062C, 0,
+ 6, 0xFE9E, 0x062C, 0,
+ 4, 0xFE9F, 0x062C, 0,
+ 5, 0xFEA0, 0x062C, 0,
+ 7, 0xFEA1, 0x062D, 0,
+ 6, 0xFEA2, 0x062D, 0,
+ 4, 0xFEA3, 0x062D, 0,
+ 5, 0xFEA4, 0x062D, 0,
+ 7, 0xFEA5, 0x062E, 0,
+ 6, 0xFEA6, 0x062E, 0,
+ 4, 0xFEA7, 0x062E, 0,
+ 5, 0xFEA8, 0x062E, 0,
+ 7, 0xFEA9, 0x062F, 0,
+ 6, 0xFEAA, 0x062F, 0,
+ 7, 0xFEAB, 0x0630, 0,
+ 6, 0xFEAC, 0x0630, 0,
+ 7, 0xFEAD, 0x0631, 0,
+ 6, 0xFEAE, 0x0631, 0,
+ 7, 0xFEAF, 0x0632, 0,
+ 6, 0xFEB0, 0x0632, 0,
+ 7, 0xFEB1, 0x0633, 0,
+ 6, 0xFEB2, 0x0633, 0,
+ 4, 0xFEB3, 0x0633, 0,
+ 5, 0xFEB4, 0x0633, 0,
+ 7, 0xFEB5, 0x0634, 0,
+ 6, 0xFEB6, 0x0634, 0,
+ 4, 0xFEB7, 0x0634, 0,
+ 5, 0xFEB8, 0x0634, 0,
+ 7, 0xFEB9, 0x0635, 0,
+ 6, 0xFEBA, 0x0635, 0,
+ 4, 0xFEBB, 0x0635, 0,
+ 5, 0xFEBC, 0x0635, 0,
+ 7, 0xFEBD, 0x0636, 0,
+ 6, 0xFEBE, 0x0636, 0,
+ 4, 0xFEBF, 0x0636, 0,
+ 5, 0xFEC0, 0x0636, 0,
+ 7, 0xFEC1, 0x0637, 0,
+ 6, 0xFEC2, 0x0637, 0,
+ 4, 0xFEC3, 0x0637, 0,
+ 5, 0xFEC4, 0x0637, 0,
+ 7, 0xFEC5, 0x0638, 0,
+ 6, 0xFEC6, 0x0638, 0,
+ 4, 0xFEC7, 0x0638, 0,
+ 5, 0xFEC8, 0x0638, 0,
+ 7, 0xFEC9, 0x0639, 0,
+ 6, 0xFECA, 0x0639, 0,
+ 4, 0xFECB, 0x0639, 0,
+ 5, 0xFECC, 0x0639, 0,
+ 7, 0xFECD, 0x063A, 0,
+ 6, 0xFECE, 0x063A, 0,
+ 4, 0xFECF, 0x063A, 0,
+ 5, 0xFED0, 0x063A, 0,
+ 7, 0xFED1, 0x0641, 0,
+ 6, 0xFED2, 0x0641, 0,
+ 4, 0xFED3, 0x0641, 0,
+ 5, 0xFED4, 0x0641, 0,
+ 7, 0xFED5, 0x0642, 0,
+ 6, 0xFED6, 0x0642, 0,
+ 4, 0xFED7, 0x0642, 0,
+ 5, 0xFED8, 0x0642, 0,
+ 7, 0xFED9, 0x0643, 0,
+ 6, 0xFEDA, 0x0643, 0,
+ 4, 0xFEDB, 0x0643, 0,
+ 5, 0xFEDC, 0x0643, 0,
+ 7, 0xFEDD, 0x0644, 0,
+ 6, 0xFEDE, 0x0644, 0,
+ 4, 0xFEDF, 0x0644, 0,
+ 5, 0xFEE0, 0x0644, 0,
+ 7, 0xFEE1, 0x0645, 0,
+ 6, 0xFEE2, 0x0645, 0,
+ 4, 0xFEE3, 0x0645, 0,
+ 5, 0xFEE4, 0x0645, 0,
+ 7, 0xFEE5, 0x0646, 0,
+ 6, 0xFEE6, 0x0646, 0,
+ 4, 0xFEE7, 0x0646, 0,
+ 5, 0xFEE8, 0x0646, 0,
+ 7, 0xFEE9, 0x0647, 0,
+ 6, 0xFEEA, 0x0647, 0,
+ 4, 0xFEEB, 0x0647, 0,
+ 5, 0xFEEC, 0x0647, 0,
+ 7, 0xFEED, 0x0648, 0,
+ 6, 0xFEEE, 0x0648, 0,
+ 7, 0xFEEF, 0x0649, 0,
+ 6, 0xFEF0, 0x0649, 0,
+ 7, 0xFEF1, 0x064A, 0,
+ 6, 0xFEF2, 0x064A, 0,
+ 4, 0xFEF3, 0x064A, 0,
+ 5, 0xFEF4, 0x064A, 0,
+ 7, 0xFEF5, 0x0644, 0x0622, 0,
+ 6, 0xFEF6, 0x0644, 0x0622, 0,
+ 7, 0xFEF7, 0x0644, 0x0623, 0,
+ 6, 0xFEF8, 0x0644, 0x0623, 0,
+ 7, 0xFEF9, 0x0644, 0x0625, 0,
+ 6, 0xFEFA, 0x0644, 0x0625, 0,
+ 7, 0xFEFB, 0x0644, 0x0627, 0,
+ 6, 0xFEFC, 0x0644, 0x0627, 0,
+ 12, 0xFF01, 0x0021, 0,
+ 12, 0xFF02, 0x0022, 0,
+ 12, 0xFF03, 0x0023, 0,
+ 12, 0xFF04, 0x0024, 0,
+ 12, 0xFF05, 0x0025, 0,
+ 12, 0xFF06, 0x0026, 0,
+ 12, 0xFF07, 0x0027, 0,
+ 12, 0xFF08, 0x0028, 0,
+ 12, 0xFF09, 0x0029, 0,
+ 12, 0xFF0A, 0x002A, 0,
+ 12, 0xFF0B, 0x002B, 0,
+ 12, 0xFF0C, 0x002C, 0,
+ 12, 0xFF0D, 0x002D, 0,
+ 12, 0xFF0E, 0x002E, 0,
+ 12, 0xFF0F, 0x002F, 0,
+ 12, 0xFF10, 0x0030, 0,
+ 12, 0xFF11, 0x0031, 0,
+ 12, 0xFF12, 0x0032, 0,
+ 12, 0xFF13, 0x0033, 0,
+ 12, 0xFF14, 0x0034, 0,
+ 12, 0xFF15, 0x0035, 0,
+ 12, 0xFF16, 0x0036, 0,
+ 12, 0xFF17, 0x0037, 0,
+ 12, 0xFF18, 0x0038, 0,
+ 12, 0xFF19, 0x0039, 0,
+ 12, 0xFF1A, 0x003A, 0,
+ 12, 0xFF1B, 0x003B, 0,
+ 12, 0xFF1C, 0x003C, 0,
+ 12, 0xFF1D, 0x003D, 0,
+ 12, 0xFF1E, 0x003E, 0,
+ 12, 0xFF1F, 0x003F, 0,
+ 12, 0xFF20, 0x0040, 0,
+ 12, 0xFF21, 0x0041, 0,
+ 12, 0xFF22, 0x0042, 0,
+ 12, 0xFF23, 0x0043, 0,
+ 12, 0xFF24, 0x0044, 0,
+ 12, 0xFF25, 0x0045, 0,
+ 12, 0xFF26, 0x0046, 0,
+ 12, 0xFF27, 0x0047, 0,
+ 12, 0xFF28, 0x0048, 0,
+ 12, 0xFF29, 0x0049, 0,
+ 12, 0xFF2A, 0x004A, 0,
+ 12, 0xFF2B, 0x004B, 0,
+ 12, 0xFF2C, 0x004C, 0,
+ 12, 0xFF2D, 0x004D, 0,
+ 12, 0xFF2E, 0x004E, 0,
+ 12, 0xFF2F, 0x004F, 0,
+ 12, 0xFF30, 0x0050, 0,
+ 12, 0xFF31, 0x0051, 0,
+ 12, 0xFF32, 0x0052, 0,
+ 12, 0xFF33, 0x0053, 0,
+ 12, 0xFF34, 0x0054, 0,
+ 12, 0xFF35, 0x0055, 0,
+ 12, 0xFF36, 0x0056, 0,
+ 12, 0xFF37, 0x0057, 0,
+ 12, 0xFF38, 0x0058, 0,
+ 12, 0xFF39, 0x0059, 0,
+ 12, 0xFF3A, 0x005A, 0,
+ 12, 0xFF3B, 0x005B, 0,
+ 12, 0xFF3C, 0x005C, 0,
+ 12, 0xFF3D, 0x005D, 0,
+ 12, 0xFF3E, 0x005E, 0,
+ 12, 0xFF3F, 0x005F, 0,
+ 12, 0xFF40, 0x0060, 0,
+ 12, 0xFF41, 0x0061, 0,
+ 12, 0xFF42, 0x0062, 0,
+ 12, 0xFF43, 0x0063, 0,
+ 12, 0xFF44, 0x0064, 0,
+ 12, 0xFF45, 0x0065, 0,
+ 12, 0xFF46, 0x0066, 0,
+ 12, 0xFF47, 0x0067, 0,
+ 12, 0xFF48, 0x0068, 0,
+ 12, 0xFF49, 0x0069, 0,
+ 12, 0xFF4A, 0x006A, 0,
+ 12, 0xFF4B, 0x006B, 0,
+ 12, 0xFF4C, 0x006C, 0,
+ 12, 0xFF4D, 0x006D, 0,
+ 12, 0xFF4E, 0x006E, 0,
+ 12, 0xFF4F, 0x006F, 0,
+ 12, 0xFF50, 0x0070, 0,
+ 12, 0xFF51, 0x0071, 0,
+ 12, 0xFF52, 0x0072, 0,
+ 12, 0xFF53, 0x0073, 0,
+ 12, 0xFF54, 0x0074, 0,
+ 12, 0xFF55, 0x0075, 0,
+ 12, 0xFF56, 0x0076, 0,
+ 12, 0xFF57, 0x0077, 0,
+ 12, 0xFF58, 0x0078, 0,
+ 12, 0xFF59, 0x0079, 0,
+ 12, 0xFF5A, 0x007A, 0,
+ 12, 0xFF5B, 0x007B, 0,
+ 12, 0xFF5C, 0x007C, 0,
+ 12, 0xFF5D, 0x007D, 0,
+ 12, 0xFF5E, 0x007E, 0,
+ 12, 0xFF5F, 0x2985, 0,
+ 12, 0xFF60, 0x2986, 0,
+ 13, 0xFF61, 0x3002, 0,
+ 13, 0xFF62, 0x300C, 0,
+ 13, 0xFF63, 0x300D, 0,
+ 13, 0xFF64, 0x3001, 0,
+ 13, 0xFF65, 0x30FB, 0,
+ 13, 0xFF66, 0x30F2, 0,
+ 13, 0xFF67, 0x30A1, 0,
+ 13, 0xFF68, 0x30A3, 0,
+ 13, 0xFF69, 0x30A5, 0,
+ 13, 0xFF6A, 0x30A7, 0,
+ 13, 0xFF6B, 0x30A9, 0,
+ 13, 0xFF6C, 0x30E3, 0,
+ 13, 0xFF6D, 0x30E5, 0,
+ 13, 0xFF6E, 0x30E7, 0,
+ 13, 0xFF6F, 0x30C3, 0,
+ 13, 0xFF70, 0x30FC, 0,
+ 13, 0xFF71, 0x30A2, 0,
+ 13, 0xFF72, 0x30A4, 0,
+ 13, 0xFF73, 0x30A6, 0,
+ 13, 0xFF74, 0x30A8, 0,
+ 13, 0xFF75, 0x30AA, 0,
+ 13, 0xFF76, 0x30AB, 0,
+ 13, 0xFF77, 0x30AD, 0,
+ 13, 0xFF78, 0x30AF, 0,
+ 13, 0xFF79, 0x30B1, 0,
+ 13, 0xFF7A, 0x30B3, 0,
+ 13, 0xFF7B, 0x30B5, 0,
+ 13, 0xFF7C, 0x30B7, 0,
+ 13, 0xFF7D, 0x30B9, 0,
+ 13, 0xFF7E, 0x30BB, 0,
+ 13, 0xFF7F, 0x30BD, 0,
+ 13, 0xFF80, 0x30BF, 0,
+ 13, 0xFF81, 0x30C1, 0,
+ 13, 0xFF82, 0x30C4, 0,
+ 13, 0xFF83, 0x30C6, 0,
+ 13, 0xFF84, 0x30C8, 0,
+ 13, 0xFF85, 0x30CA, 0,
+ 13, 0xFF86, 0x30CB, 0,
+ 13, 0xFF87, 0x30CC, 0,
+ 13, 0xFF88, 0x30CD, 0,
+ 13, 0xFF89, 0x30CE, 0,
+ 13, 0xFF8A, 0x30CF, 0,
+ 13, 0xFF8B, 0x30D2, 0,
+ 13, 0xFF8C, 0x30D5, 0,
+ 13, 0xFF8D, 0x30D8, 0,
+ 13, 0xFF8E, 0x30DB, 0,
+ 13, 0xFF8F, 0x30DE, 0,
+ 13, 0xFF90, 0x30DF, 0,
+ 13, 0xFF91, 0x30E0, 0,
+ 13, 0xFF92, 0x30E1, 0,
+ 13, 0xFF93, 0x30E2, 0,
+ 13, 0xFF94, 0x30E4, 0,
+ 13, 0xFF95, 0x30E6, 0,
+ 13, 0xFF96, 0x30E8, 0,
+ 13, 0xFF97, 0x30E9, 0,
+ 13, 0xFF98, 0x30EA, 0,
+ 13, 0xFF99, 0x30EB, 0,
+ 13, 0xFF9A, 0x30EC, 0,
+ 13, 0xFF9B, 0x30ED, 0,
+ 13, 0xFF9C, 0x30EF, 0,
+ 13, 0xFF9D, 0x30F3, 0,
+ 13, 0xFF9E, 0x3099, 0,
+ 13, 0xFF9F, 0x309A, 0,
+ 13, 0xFFA0, 0x3164, 0,
+ 13, 0xFFA1, 0x3131, 0,
+ 13, 0xFFA2, 0x3132, 0,
+ 13, 0xFFA3, 0x3133, 0,
+ 13, 0xFFA4, 0x3134, 0,
+ 13, 0xFFA5, 0x3135, 0,
+ 13, 0xFFA6, 0x3136, 0,
+ 13, 0xFFA7, 0x3137, 0,
+ 13, 0xFFA8, 0x3138, 0,
+ 13, 0xFFA9, 0x3139, 0,
+ 13, 0xFFAA, 0x313A, 0,
+ 13, 0xFFAB, 0x313B, 0,
+ 13, 0xFFAC, 0x313C, 0,
+ 13, 0xFFAD, 0x313D, 0,
+ 13, 0xFFAE, 0x313E, 0,
+ 13, 0xFFAF, 0x313F, 0,
+ 13, 0xFFB0, 0x3140, 0,
+ 13, 0xFFB1, 0x3141, 0,
+ 13, 0xFFB2, 0x3142, 0,
+ 13, 0xFFB3, 0x3143, 0,
+ 13, 0xFFB4, 0x3144, 0,
+ 13, 0xFFB5, 0x3145, 0,
+ 13, 0xFFB6, 0x3146, 0,
+ 13, 0xFFB7, 0x3147, 0,
+ 13, 0xFFB8, 0x3148, 0,
+ 13, 0xFFB9, 0x3149, 0,
+ 13, 0xFFBA, 0x314A, 0,
+ 13, 0xFFBB, 0x314B, 0,
+ 13, 0xFFBC, 0x314C, 0,
+ 13, 0xFFBD, 0x314D, 0,
+ 13, 0xFFBE, 0x314E, 0,
+ 13, 0xFFC2, 0x314F, 0,
+ 13, 0xFFC3, 0x3150, 0,
+ 13, 0xFFC4, 0x3151, 0,
+ 13, 0xFFC5, 0x3152, 0,
+ 13, 0xFFC6, 0x3153, 0,
+ 13, 0xFFC7, 0x3154, 0,
+ 13, 0xFFCA, 0x3155, 0,
+ 13, 0xFFCB, 0x3156, 0,
+ 13, 0xFFCC, 0x3157, 0,
+ 13, 0xFFCD, 0x3158, 0,
+ 13, 0xFFCE, 0x3159, 0,
+ 13, 0xFFCF, 0x315A, 0,
+ 13, 0xFFD2, 0x315B, 0,
+ 13, 0xFFD3, 0x315C, 0,
+ 13, 0xFFD4, 0x315D, 0,
+ 13, 0xFFD5, 0x315E, 0,
+ 13, 0xFFD6, 0x315F, 0,
+ 13, 0xFFD7, 0x3160, 0,
+ 13, 0xFFDA, 0x3161, 0,
+ 13, 0xFFDB, 0x3162, 0,
+ 13, 0xFFDC, 0x3163, 0,
+ 12, 0xFFE0, 0x00A2, 0,
+ 12, 0xFFE1, 0x00A3, 0,
+ 12, 0xFFE2, 0x00AC, 0,
+ 12, 0xFFE3, 0x00AF, 0,
+ 12, 0xFFE4, 0x00A6, 0,
+ 12, 0xFFE5, 0x00A5, 0,
+ 12, 0xFFE6, 0x20A9, 0,
+ 13, 0xFFE8, 0x2502, 0,
+ 13, 0xFFE9, 0x2190, 0,
+ 13, 0xFFEA, 0x2191, 0,
+ 13, 0xFFEB, 0x2192, 0,
+ 13, 0xFFEC, 0x2193, 0,
+ 13, 0xFFED, 0x25A0, 0,
+ 13, 0xFFEE, 0x25CB, 0,
+
+};
+
+const TQ_UINT16 TQUnicodeTables::decomposition_info[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 17, 18,
+ 19, 20, 21, 22, 23, 8, 8, 8,
+ 8, 8, 24, 8, 8, 8, 25, 26,
+ 27, 28, 29, 30, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 31, 32, 33, 34, 35, 36, 37,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0,
+ 5, 0, 10, 0, 0, 0, 0, 14,
+ 0, 0, 19, 23, 27, 32, 0, 0,
+ 36, 41, 45, 0, 49, 55, 61, 0,
+ 67, 72, 77, 82, 87, 92, 0, 97,
+ 102, 107, 112, 117, 122, 127, 132, 137,
+ 0, 142, 147, 152, 157, 162, 167, 0,
+ 0, 172, 177, 182, 187, 192, 0, 0,
+ 197, 202, 207, 212, 217, 222, 0, 227,
+ 232, 237, 242, 247, 252, 257, 262, 267,
+ 0, 272, 277, 282, 287, 292, 297, 0,
+ 0, 302, 307, 312, 317, 322, 0, 327,
+
+ 332, 337, 342, 347, 352, 357, 362, 367,
+ 372, 377, 382, 387, 392, 397, 402, 407,
+ 0, 0, 412, 417, 422, 427, 432, 437,
+ 442, 447, 452, 457, 462, 467, 472, 477,
+ 482, 487, 492, 497, 502, 507, 0, 0,
+ 512, 517, 522, 527, 532, 537, 542, 547,
+ 552, 0, 557, 562, 567, 572, 577, 582,
+ 0, 587, 592, 597, 602, 607, 612, 617,
+ 622, 0, 0, 627, 632, 637, 642, 647,
+ 652, 657, 0, 0, 662, 667, 672, 677,
+ 682, 687, 0, 0, 692, 697, 702, 707,
+ 712, 717, 722, 727, 732, 737, 742, 747,
+ 752, 757, 762, 767, 772, 777, 0, 0,
+ 782, 787, 792, 797, 802, 807, 812, 817,
+ 822, 827, 832, 837, 842, 847, 852, 857,
+ 862, 867, 872, 877, 882, 887, 892, 897,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 901, 906, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 911,
+ 916, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 921, 926, 931, 936,
+ 941, 946, 951, 956, 961, 966, 971, 976,
+ 981, 986, 991, 996, 1001, 1006, 1011, 1016,
+ 1021, 1026, 1031, 1036, 1041, 0, 1046, 1051,
+ 1056, 1061, 1066, 1071, 0, 0, 1076, 1081,
+ 1086, 1091, 1096, 1101, 1106, 1111, 1116, 1121,
+ 1126, 1131, 1136, 1141, 1146, 1151, 0, 0,
+ 1156, 1161, 1166, 1171, 1176, 1181, 1186, 1191,
+
+ 1196, 1201, 1206, 1211, 1216, 1221, 1226, 1231,
+ 1236, 1241, 1246, 1251, 1256, 1261, 1266, 1271,
+ 1276, 1281, 1286, 1291, 1296, 1301, 1306, 1311,
+ 1316, 1321, 1326, 1331, 0, 0, 1336, 1341,
+ 0, 0, 0, 0, 0, 0, 1346, 1351,
+ 1356, 1361, 1366, 1371, 1376, 1381, 1386, 1391,
+ 1396, 1401, 1406, 1411, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1416, 1420, 1424, 1428, 1432, 1436, 1440, 1444,
+ 1448, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1452, 1457, 1462, 1467, 1472, 1477, 0, 0,
+ 1482, 1486, 1490, 1494, 1498, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1502, 1506, 0, 1510, 1514, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1519, 0, 0, 0,
+ 0, 0, 1523, 0, 0, 0, 1528, 0,
+ 0, 0, 0, 0, 1532, 1537, 1542, 1547,
+ 1551, 1556, 1561, 0, 1566, 0, 1571, 1576,
+ 1581, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1586, 1591, 1596, 1601, 1606, 1611,
+ 1616, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1621, 1626, 1631, 1636, 1641, 0,
+ 1646, 1650, 1654, 1658, 1663, 1668, 1672, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1676, 1680, 1684, 0, 1688, 1692, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 1696, 1701, 0, 1706, 0, 0, 0, 1711,
+ 0, 0, 0, 0, 1716, 1721, 1726, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1731, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1736, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1741, 1746, 0, 1751, 0, 0, 0, 1756,
+ 0, 0, 0, 0, 1761, 1766, 1771, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1776, 1781,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1786, 1791, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1796, 1801, 1806, 1811, 0, 0, 1816, 1821,
+ 0, 0, 1826, 1831, 1836, 1841, 1846, 1851,
+ 0, 0, 1856, 1861, 1866, 1871, 1876, 1881,
+ 0, 0, 1886, 1891, 1896, 1901, 1906, 1911,
+ 1916, 1921, 1926, 1931, 1936, 1941, 0, 0,
+ 1946, 1951, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1956,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1961, 1966, 1971, 1976, 1981, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1986, 1991, 1996,
+ 2001, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2006, 0, 2011, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2016, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2021, 0, 0, 0, 0, 0, 0,
+ 0, 2026, 0, 0, 2031, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2036, 2041, 2046, 2051, 2056, 2061, 2066, 2071,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2076, 2081, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2086, 2091, 0, 2096,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2101, 0, 0, 2106, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2111, 2116, 2121, 0, 0, 2126, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2131, 0, 0, 2136, 2141, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2146, 2151, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2156, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2161, 2166, 2171, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2176, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2181, 0, 0, 0, 0, 0, 0, 2186,
+ 2191, 0, 2196, 2201, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2206, 2211, 2216, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2221, 0, 2226, 2231, 2236, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2241, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2246, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2251, 2256, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2261, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2265, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2270, 0, 0,
+ 0, 0, 2275, 0, 0, 0, 0, 2280,
+ 0, 0, 0, 0, 2285, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2290, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2295, 0, 2300, 2305, 2310,
+ 2315, 2320, 0, 0, 0, 0, 0, 0,
+ 0, 2325, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2330, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2335, 0, 0,
+ 0, 0, 2340, 0, 0, 0, 0, 2345,
+ 0, 0, 0, 0, 2350, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2355, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2360, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 2365, 2370, 2375, 2380, 2385, 2390, 2395, 2400,
+ 2405, 2410, 2415, 2420, 2425, 2430, 2435, 2440,
+ 2445, 2450, 2455, 2460, 2465, 2470, 2475, 2480,
+ 2485, 2490, 2495, 2500, 2505, 2510, 2515, 2520,
+ 2525, 2530, 2535, 2540, 2545, 2550, 2555, 2560,
+ 2565, 2570, 2575, 2580, 2585, 2590, 2595, 2600,
+ 2605, 2610, 2615, 2620, 2625, 2630, 2635, 2640,
+ 2645, 2650, 2655, 2660, 2665, 2670, 2675, 2680,
+ 2685, 2690, 2695, 2700, 2705, 2710, 2715, 2720,
+ 2725, 2730, 2735, 2740, 2745, 2750, 2755, 2760,
+ 2765, 2770, 2775, 2780, 2785, 2790, 2795, 2800,
+ 2805, 2810, 2815, 2820, 2825, 2830, 2835, 2840,
+ 2845, 2850, 2855, 2860, 2865, 2870, 2875, 2880,
+ 2885, 2890, 2895, 2900, 2905, 2910, 2915, 2920,
+ 2925, 2930, 2935, 2940, 2945, 2950, 2955, 2960,
+ 2965, 2970, 2975, 2980, 2985, 2990, 2995, 3000,
+ 3005, 3010, 3015, 3020, 3025, 3030, 3035, 3040,
+ 3045, 3050, 3055, 3060, 3065, 3070, 3075, 3080,
+ 3085, 3090, 3095, 3100, 3105, 3110, 3115, 3120,
+ 3125, 3130, 3135, 3140, 0, 0, 0, 0,
+ 3145, 3150, 3155, 3160, 3165, 3170, 3175, 3180,
+ 3185, 3190, 3195, 3200, 3205, 3210, 3215, 3220,
+ 3225, 3230, 3235, 3240, 3245, 3250, 3255, 3260,
+ 3265, 3270, 3275, 3280, 3285, 3290, 3295, 3300,
+ 3305, 3310, 3315, 3320, 3325, 3330, 3335, 3340,
+ 3345, 3350, 3355, 3360, 3365, 3370, 3375, 3380,
+ 3385, 3390, 3395, 3400, 3405, 3410, 3415, 3420,
+ 3425, 3430, 3435, 3440, 3445, 3450, 3455, 3460,
+ 3465, 3470, 3475, 3480, 3485, 3490, 3495, 3500,
+ 3505, 3510, 3515, 3520, 3525, 3530, 3535, 3540,
+ 3545, 3550, 3555, 3560, 3565, 3570, 3575, 3580,
+ 3585, 3590, 0, 0, 0, 0, 0, 0,
+
+ 3595, 3600, 3605, 3610, 3615, 3620, 3625, 3630,
+ 3635, 3640, 3645, 3650, 3655, 3660, 3665, 3670,
+ 3675, 3680, 3685, 3690, 3695, 3700, 0, 0,
+ 3705, 3710, 3715, 3720, 3725, 3730, 0, 0,
+ 3735, 3740, 3745, 3750, 3755, 3760, 3765, 3770,
+ 3775, 3780, 3785, 3790, 3795, 3800, 3805, 3810,
+ 3815, 3820, 3825, 3830, 3835, 3840, 3845, 3850,
+ 3855, 3860, 3865, 3870, 3875, 3880, 3885, 3890,
+ 3895, 3900, 3905, 3910, 3915, 3920, 0, 0,
+ 3925, 3930, 3935, 3940, 3945, 3950, 0, 0,
+ 3955, 3960, 3965, 3970, 3975, 3980, 3985, 3990,
+ 0, 3995, 0, 4000, 0, 4005, 0, 4010,
+ 4015, 4020, 4025, 4030, 4035, 4040, 4045, 4050,
+ 4055, 4060, 4065, 4070, 4075, 4080, 4085, 4090,
+ 4095, 4100, 4104, 4109, 4113, 4118, 4122, 4127,
+ 4131, 4136, 4140, 4145, 4149, 4154, 0, 0,
+ 4158, 4163, 4168, 4173, 4178, 4183, 4188, 4193,
+ 4198, 4203, 4208, 4213, 4218, 4223, 4228, 4233,
+ 4238, 4243, 4248, 4253, 4258, 4263, 4268, 4273,
+ 4278, 4283, 4288, 4293, 4298, 4303, 4308, 4313,
+ 4318, 4323, 4328, 4333, 4338, 4343, 4348, 4353,
+ 4358, 4363, 4368, 4373, 4378, 4383, 4388, 4393,
+ 4398, 4403, 4408, 4413, 4418, 0, 4423, 4428,
+ 4433, 4438, 4443, 4448, 4452, 4457, 4462, 4466,
+ 4471, 4476, 4481, 4486, 4491, 0, 4496, 4501,
+ 4506, 4511, 4515, 4520, 4524, 4529, 4534, 4539,
+ 4544, 4549, 4554, 4559, 0, 0, 4563, 4568,
+ 4573, 4578, 4583, 4588, 0, 4592, 4597, 4602,
+ 4607, 4612, 4617, 4622, 4626, 4631, 4636, 4641,
+ 4646, 4651, 4656, 4661, 4665, 4670, 4675, 4679,
+ 0, 0, 4683, 4688, 4693, 0, 4698, 4703,
+ 4708, 4713, 4717, 4722, 4726, 4731, 4735, 0,
+
+ 4740, 4744, 4748, 4752, 4756, 4760, 4764, 4768,
+ 4772, 4776, 4780, 0, 0, 0, 0, 0,
+ 0, 4784, 0, 0, 0, 0, 0, 4788,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 4793, 4797, 4802, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4808,
+ 0, 0, 0, 4812, 4817, 0, 4823, 4828,
+ 0, 0, 0, 0, 4834, 0, 4839, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4844,
+ 4849, 4854, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4859,
+ 0, 0, 0, 0, 0, 0, 0, 4866,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4870, 4874, 0, 0, 4878, 4882, 4886, 4890,
+ 4894, 4898, 4902, 4906, 4910, 4914, 4918, 4922,
+ 4926, 4930, 4934, 4938, 4942, 4946, 4950, 4954,
+ 4958, 4962, 4966, 4970, 4974, 4978, 4982, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4986, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 4991, 4997, 5003, 5007, 0, 5012, 5018, 5024,
+ 0, 5028, 5033, 5037, 5041, 5045, 5049, 5053,
+ 5057, 5061, 5065, 5069, 0, 5073, 5077, 0,
+ 0, 5082, 5086, 5090, 5094, 5098, 0, 0,
+ 5102, 5107, 5113, 0, 5118, 0, 5122, 0,
+ 5126, 0, 5130, 5134, 5138, 5142, 0, 5146,
+ 5150, 5154, 0, 5158, 5162, 5166, 5170, 5174,
+ 5178, 5182, 0, 0, 0, 5186, 5190, 5194,
+ 5198, 0, 0, 0, 0, 5202, 5206, 5210,
+ 5214, 5218, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5222, 5228, 5234, 5240, 5246,
+ 5252, 5258, 5264, 5270, 5276, 5282, 5288, 5294,
+ 5299, 5303, 5308, 5314, 5319, 5323, 5328, 5334,
+ 5341, 5346, 5350, 5355, 5361, 5365, 5369, 5373,
+ 5377, 5381, 5386, 5392, 5397, 5401, 5406, 5412,
+ 5419, 5424, 5428, 5433, 5439, 5443, 5447, 5451,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 5455, 5460, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 5465, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5470, 5475, 5480,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 5485, 0, 0, 0,
+ 0, 5490, 0, 0, 5495, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5500, 0, 5505, 0,
+ 0, 0, 0, 0, 5510, 5515, 0, 5521,
+ 5526, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5532, 0, 0, 5537, 0, 0, 5542,
+ 0, 5547, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5552, 0, 5557, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5562, 5567, 5572,
+ 5577, 5582, 0, 0, 5587, 5592, 0, 0,
+ 5597, 5602, 0, 0, 0, 0, 0, 0,
+ 5607, 5612, 0, 0, 5617, 5622, 0, 0,
+ 5627, 5632, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5637, 5642, 5647, 5652,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5657, 5662, 5667, 5672, 0, 0, 0, 0,
+ 0, 0, 5677, 5682, 5687, 5692, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 5697, 5701, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5705, 5709, 5713, 5717, 5721, 5725, 5729, 5733,
+ 5737, 5741, 5746, 5751, 5756, 5761, 5766, 5771,
+ 5776, 5781, 5786, 5791, 5796, 5802, 5808, 5814,
+ 5820, 5826, 5832, 5838, 5844, 5850, 5857, 5864,
+ 5871, 5878, 5885, 5892, 5899, 5906, 5913, 5920,
+ 5927, 5932, 5937, 5942, 5947, 5952, 5957, 5962,
+ 5967, 5972, 5978, 5984, 5990, 5996, 6002, 6008,
+ 6014, 6020, 6026, 6032, 6038, 6044, 6050, 6056,
+ 6062, 6068, 6074, 6080, 6086, 6092, 6098, 6104,
+ 6110, 6116, 6122, 6128, 6134, 6140, 6146, 6152,
+ 6158, 6164, 6170, 6176, 6182, 6188, 6194, 6198,
+ 6202, 6206, 6210, 6214, 6218, 6222, 6226, 6230,
+ 6234, 6238, 6242, 6246, 6250, 6254, 6258, 6262,
+ 6266, 6270, 6274, 6278, 6282, 6286, 6290, 6294,
+ 6298, 6302, 6306, 6310, 6314, 6318, 6322, 6326,
+ 6330, 6334, 6338, 6342, 6346, 6350, 6354, 6358,
+ 6362, 6366, 6370, 6374, 6378, 6382, 6386, 6390,
+ 6394, 6398, 6402, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6406, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6413, 6419, 6424, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6430, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 6435,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6439, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 6443, 6447, 6451, 6455, 6459, 6463, 6467, 6471,
+ 6475, 6479, 6483, 6487, 6491, 6495, 6499, 6503,
+ 6507, 6511, 6515, 6519, 6523, 6527, 6531, 6535,
+ 6539, 6543, 6547, 6551, 6555, 6559, 6563, 6567,
+ 6571, 6575, 6579, 6583, 6587, 6591, 6595, 6599,
+ 6603, 6607, 6611, 6615, 6619, 6623, 6627, 6631,
+ 6635, 6639, 6643, 6647, 6651, 6655, 6659, 6663,
+ 6667, 6671, 6675, 6679, 6683, 6687, 6691, 6695,
+ 6699, 6703, 6707, 6711, 6715, 6719, 6723, 6727,
+ 6731, 6735, 6739, 6743, 6747, 6751, 6755, 6759,
+ 6763, 6767, 6771, 6775, 6779, 6783, 6787, 6791,
+ 6795, 6799, 6803, 6807, 6811, 6815, 6819, 6823,
+ 6827, 6831, 6835, 6839, 6843, 6847, 6851, 6855,
+ 6859, 6863, 6867, 6871, 6875, 6879, 6883, 6887,
+ 6891, 6895, 6899, 6903, 6907, 6911, 6915, 6919,
+ 6923, 6927, 6931, 6935, 6939, 6943, 6947, 6951,
+ 6955, 6959, 6963, 6967, 6971, 6975, 6979, 6983,
+ 6987, 6991, 6995, 6999, 7003, 7007, 7011, 7015,
+ 7019, 7023, 7027, 7031, 7035, 7039, 7043, 7047,
+ 7051, 7055, 7059, 7063, 7067, 7071, 7075, 7079,
+ 7083, 7087, 7091, 7095, 7099, 7103, 7107, 7111,
+ 7115, 7119, 7123, 7127, 7131, 7135, 7139, 7143,
+ 7147, 7151, 7155, 7159, 7163, 7167, 7171, 7175,
+ 7179, 7183, 7187, 7191, 7195, 7199, 7203, 7207,
+ 7211, 7215, 7219, 7223, 7227, 7231, 7235, 7239,
+ 7243, 7247, 7251, 7255, 7259, 7263, 7267, 7271,
+ 7275, 7279, 7283, 7287, 7291, 7295, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 7299, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7303, 0,
+ 7307, 7311, 7315, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7319, 0, 7324, 0,
+ 7329, 0, 7334, 0, 7339, 0, 7344, 0,
+ 7349, 0, 7354, 0, 7359, 0, 7364, 0,
+ 7369, 0, 7374, 0, 0, 7379, 0, 7384,
+ 0, 7389, 0, 0, 0, 0, 0, 0,
+ 7394, 7399, 0, 7404, 7409, 0, 7414, 7419,
+ 0, 7424, 7429, 0, 7434, 7439, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7444, 0, 0, 0,
+ 0, 0, 0, 7449, 7454, 0, 7459, 7464,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7469, 0, 7474, 0,
+ 7479, 0, 7484, 0, 7489, 0, 7494, 0,
+ 7499, 0, 7504, 0, 7509, 0, 7514, 0,
+ 7519, 0, 7524, 0, 0, 7529, 0, 7534,
+ 0, 7539, 0, 0, 0, 0, 0, 0,
+ 7544, 7549, 0, 7554, 7559, 0, 7564, 7569,
+ 0, 7574, 7579, 0, 7584, 7589, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7594, 0, 0, 7599,
+ 7604, 7609, 7614, 0, 0, 0, 7619, 7624,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 7629, 7633, 7637, 7641, 7645, 7649, 7653,
+ 7657, 7661, 7665, 7669, 7673, 7677, 7681, 7685,
+ 7689, 7693, 7697, 7701, 7705, 7709, 7713, 7717,
+ 7721, 7725, 7729, 7733, 7737, 7741, 7745, 7749,
+ 7753, 7757, 7761, 7765, 7769, 7773, 7777, 7781,
+ 7785, 7789, 7793, 7797, 7801, 7805, 7809, 7813,
+ 7817, 7821, 7825, 7829, 7833, 7837, 7841, 7845,
+ 7849, 7853, 7857, 7861, 7865, 7869, 7873, 7877,
+ 7881, 7885, 7889, 7893, 7897, 7901, 7905, 7909,
+ 7913, 7917, 7921, 7925, 7929, 7933, 7937, 7941,
+ 7945, 7949, 7953, 7957, 7961, 7965, 7969, 7973,
+ 7977, 7981, 7985, 7989, 7993, 7997, 8001, 0,
+ 0, 0, 8005, 8009, 8013, 8017, 8021, 8025,
+ 8029, 8033, 8037, 8041, 8045, 8049, 8053, 8057,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 8061, 8067, 8073, 8079, 8085, 8091, 8097, 8103,
+ 8109, 8115, 8121, 8127, 8133, 8139, 8145, 8152,
+ 8159, 8166, 8173, 8180, 8187, 8194, 8201, 8208,
+ 8215, 8222, 8229, 8236, 8243, 0, 0, 0,
+ 8250, 8256, 8262, 8268, 8274, 8280, 8286, 8292,
+ 8298, 8304, 8310, 8316, 8322, 8328, 8334, 8340,
+ 8346, 8352, 8358, 8364, 8370, 8376, 8382, 8388,
+ 8394, 8400, 8406, 8412, 8418, 8424, 8430, 8436,
+ 8442, 8448, 8454, 8460, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8466, 8471, 8476, 8481, 8486, 8491, 8496,
+ 8501, 8506, 8511, 8516, 8521, 8526, 8531, 8536,
+ 8541, 8545, 8549, 8553, 8557, 8561, 8565, 8569,
+ 8573, 8577, 8581, 8585, 8589, 8593, 8597, 8602,
+ 8607, 8612, 8617, 8622, 8627, 8632, 8637, 8642,
+ 8647, 8652, 8657, 8662, 0, 0, 0, 0,
+ 8667, 8671, 8675, 8679, 8683, 8687, 8691, 8695,
+ 8699, 8703, 8707, 8711, 8715, 8719, 8723, 8727,
+ 8731, 8735, 8739, 8743, 8747, 8751, 8755, 8759,
+ 8763, 8767, 8771, 8775, 8779, 8783, 8787, 8791,
+ 8795, 8799, 8803, 8807, 8811, 8815, 8819, 8823,
+ 8827, 8831, 8835, 8839, 8843, 8847, 8851, 8855,
+ 8859, 8863, 8868, 8873, 8878, 8883, 8888, 8893,
+ 8898, 8903, 8908, 8913, 8918, 8923, 8928, 8933,
+ 8938, 8943, 8948, 8953, 8958, 8963, 8968, 8973,
+ 8978, 8983, 8989, 8995, 0, 0, 0, 0,
+ 9001, 9005, 9009, 9013, 9017, 9021, 9025, 9029,
+ 9033, 9037, 9041, 9045, 9049, 9053, 9057, 9061,
+ 9065, 9069, 9073, 9077, 9081, 9085, 9089, 9093,
+ 9097, 9101, 9105, 9109, 9113, 9117, 9121, 9125,
+ 9129, 9133, 9137, 9141, 9145, 9149, 9153, 9157,
+ 9161, 9165, 9169, 9173, 9177, 9181, 9185, 0,
+
+ 9189, 9196, 9203, 9210, 9216, 9223, 9229, 9235,
+ 9243, 9250, 9256, 9262, 9268, 9275, 9282, 9288,
+ 9294, 9299, 9305, 9312, 9319, 9324, 9332, 9341,
+ 9349, 9355, 9363, 9371, 9378, 9384, 9390, 9396,
+ 9403, 9411, 9418, 9424, 9430, 9436, 9441, 9446,
+ 9451, 9456, 9462, 9468, 9476, 9482, 9489, 9497,
+ 9503, 9508, 9513, 9521, 9528, 9536, 9542, 9550,
+ 9555, 9561, 9567, 9573, 9579, 9585, 9592, 9598,
+ 9603, 9609, 9615, 9621, 9628, 9634, 9640, 9646,
+ 9654, 9661, 9666, 9674, 9679, 9686, 9693, 9699,
+ 9705, 9711, 9718, 9723, 9729, 9736, 9741, 9749,
+ 9755, 9760, 9765, 9770, 9775, 9780, 9785, 9790,
+ 9795, 9800, 9805, 9811, 9817, 9823, 9829, 9835,
+ 9841, 9847, 9853, 9859, 9865, 9871, 9877, 9883,
+ 9889, 9895, 9901, 9906, 9911, 9917, 9922, 0,
+ 0, 0, 0, 9927, 9932, 9937, 9942, 9947,
+ 9954, 9959, 9964, 9969, 9974, 9979, 9984, 9989,
+ 9994, 10000, 10007, 10012, 10017, 10022, 10027, 10032,
+ 10037, 10042, 10048, 10054, 10060, 10066, 10071, 10076,
+ 10081, 10086, 10091, 10096, 10101, 10106, 10111, 10116,
+ 10122, 10128, 10133, 10139, 10145, 10151, 10156, 10162,
+ 10168, 10175, 10180, 10186, 10192, 10198, 10204, 10212,
+ 10221, 10226, 10231, 10236, 10241, 10246, 10251, 10256,
+ 10261, 10266, 10271, 10276, 10281, 10286, 10291, 10296,
+ 10301, 10306, 10311, 10318, 10323, 10328, 10333, 10340,
+ 10346, 10351, 10356, 10361, 10366, 10371, 10376, 10381,
+ 10386, 10391, 10396, 10402, 10407, 10412, 10418, 10424,
+ 10429, 10436, 10442, 10447, 10452, 10457, 0, 0,
+ 10462, 10467, 10472, 10477, 10482, 10487, 10492, 10497,
+ 10502, 10507, 10513, 10519, 10525, 10531, 10537, 10543,
+ 10549, 10555, 10561, 10567, 10573, 10579, 10585, 10591,
+ 10597, 10603, 10609, 10615, 10621, 10627, 10633, 0,
+
+ 10639, 10643, 10647, 10651, 10655, 10659, 10663, 10667,
+ 10671, 10675, 10679, 10683, 10687, 10691, 10695, 10699,
+ 10703, 10707, 10711, 10715, 10719, 10723, 10727, 10731,
+ 10735, 10739, 10743, 10747, 10751, 10755, 10759, 10763,
+ 10767, 10771, 10775, 10779, 10783, 10787, 10791, 10795,
+ 10799, 10803, 10807, 10811, 10815, 10819, 10823, 10827,
+ 10831, 10835, 10839, 10843, 10847, 10851, 10855, 10859,
+ 10863, 10867, 10871, 10875, 10879, 10883, 10887, 10891,
+ 10895, 10899, 10903, 10907, 10911, 10915, 10919, 10923,
+ 10927, 10931, 10935, 10939, 10943, 10947, 10951, 10955,
+ 10959, 10963, 10967, 10971, 10975, 10979, 10983, 10987,
+ 10991, 10995, 10999, 11003, 11007, 11011, 11015, 11019,
+ 11023, 11027, 11031, 11035, 11039, 11043, 11047, 11051,
+ 11055, 11059, 11063, 11067, 11071, 11075, 11079, 11083,
+ 11087, 11091, 11095, 11099, 11103, 11107, 11111, 11115,
+ 11119, 11123, 11127, 11131, 11135, 11139, 11143, 11147,
+ 11151, 11155, 11159, 11163, 11167, 11171, 11175, 11179,
+ 11183, 11187, 11191, 11195, 11199, 11203, 11207, 11211,
+ 11215, 11219, 11223, 11227, 11231, 11235, 11239, 11243,
+ 11247, 11251, 11255, 11259, 11263, 11267, 11271, 11275,
+ 11279, 11283, 11287, 11291, 11295, 11299, 11303, 11307,
+ 11311, 11315, 11319, 11323, 11327, 11331, 11335, 11339,
+ 11343, 11347, 11351, 11355, 11359, 11363, 11367, 11371,
+ 11375, 11379, 11383, 11387, 11391, 11395, 11399, 11403,
+ 11407, 11411, 11415, 11419, 11423, 11427, 11431, 11435,
+ 11439, 11443, 11447, 11451, 11455, 11459, 11463, 11467,
+ 11471, 11475, 11479, 11483, 11487, 11491, 11495, 11499,
+ 11503, 11507, 11511, 11515, 11519, 11523, 11527, 11531,
+ 11535, 11539, 11543, 11547, 11551, 11555, 11559, 11563,
+ 11567, 11571, 11575, 11579, 11583, 11587, 11591, 11595,
+ 11599, 11603, 11607, 11611, 11615, 11619, 11623, 11627,
+ 11631, 11635, 11639, 11643, 11647, 11651, 11655, 11659,
+
+ 11663, 11667, 11671, 11675, 11679, 11683, 11687, 11691,
+ 11695, 11699, 11703, 11707, 11711, 11715, 0, 0,
+ 11719, 0, 11723, 0, 0, 11727, 11731, 11735,
+ 11739, 11743, 11747, 11751, 11755, 11759, 11763, 0,
+ 11767, 0, 11771, 0, 0, 11775, 11779, 0,
+ 0, 0, 11783, 11787, 11791, 11795, 0, 0,
+ 11799, 11803, 11807, 11811, 11815, 11819, 11823, 11827,
+ 11831, 11835, 11839, 11843, 11847, 11851, 11855, 11859,
+ 11863, 11867, 11871, 11875, 11879, 11883, 11887, 11891,
+ 11895, 11899, 11903, 11907, 11911, 11915, 11919, 11923,
+ 11927, 11931, 11935, 11939, 11943, 11947, 11951, 11955,
+ 11959, 11963, 11967, 11971, 11975, 11979, 11983, 11987,
+ 11991, 11995, 11999, 12003, 12007, 12011, 12015, 12019,
+ 12023, 12027, 12031, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 12035, 12040, 12045, 12050, 12056, 12062, 12067, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 12072, 12077, 12082, 12087, 12092,
+ 0, 0, 0, 0, 0, 12097, 0, 12102,
+ 12107, 12111, 12115, 12119, 12123, 12127, 12131, 12135,
+ 12139, 12143, 12147, 12152, 12157, 12162, 12167, 12172,
+ 12177, 12182, 12187, 12192, 12197, 12202, 12207, 0,
+ 12212, 12217, 12222, 12227, 12232, 0, 12237, 0,
+ 12242, 12247, 0, 12252, 12257, 0, 12262, 12267,
+ 12272, 12277, 12282, 12287, 12292, 12297, 12302, 12307,
+ 12312, 12316, 12320, 12324, 12328, 12332, 12336, 12340,
+ 12344, 12348, 12352, 12356, 12360, 12364, 12368, 12372,
+ 12376, 12380, 12384, 12388, 12392, 12396, 12400, 12404,
+ 12408, 12412, 12416, 12420, 12424, 12428, 12432, 12436,
+ 12440, 12444, 12448, 12452, 12456, 12460, 12464, 12468,
+ 12472, 12476, 12480, 12484, 12488, 12492, 12496, 12500,
+ 12504, 12508, 12512, 12516, 12520, 12524, 12528, 12532,
+ 12536, 12540, 12544, 12548, 12552, 12556, 12560, 12564,
+ 12568, 12572, 12576, 12580, 12584, 12588, 12592, 12596,
+ 12600, 12604, 12608, 12612, 12616, 12620, 12624, 12628,
+ 12632, 12636, 12640, 12644, 12648, 12652, 12656, 12660,
+ 12664, 12668, 12672, 12676, 12680, 12684, 12688, 12692,
+ 12696, 12700, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 12704, 12708, 12712, 12716, 12720,
+ 12724, 12728, 12732, 12736, 12740, 12744, 12748, 12752,
+ 12756, 12760, 12764, 12768, 12772, 12776, 12780, 12784,
+ 12788, 12792, 12796, 12801, 12806, 12811, 12816, 12821,
+ 12826, 12831, 12836, 12841, 12846, 12851, 12856, 12861,
+ 12866, 12871, 12876, 12881, 12886, 12890, 12894, 12898,
+
+ 12902, 12907, 12912, 12917, 12922, 12927, 12932, 12937,
+ 12942, 12947, 12952, 12957, 12962, 12967, 12972, 12977,
+ 12982, 12987, 12992, 12997, 13002, 13007, 13012, 13017,
+ 13022, 13027, 13032, 13037, 13042, 13047, 13052, 13057,
+ 13062, 13067, 13072, 13077, 13082, 13087, 13092, 13097,
+ 13102, 13107, 13112, 13117, 13122, 13127, 13132, 13137,
+ 13142, 13147, 13152, 13157, 13162, 13167, 13172, 13177,
+ 13182, 13187, 13192, 13197, 13202, 13207, 13212, 13217,
+ 13222, 13227, 13232, 13237, 13242, 13247, 13252, 13257,
+ 13262, 13267, 13272, 13277, 13282, 13287, 13292, 13297,
+ 13302, 13307, 13312, 13317, 13322, 13327, 13332, 13337,
+ 13342, 13347, 13352, 13357, 13362, 13367, 13372, 13378,
+ 13384, 13390, 13396, 13402, 13408, 13413, 13418, 13423,
+ 13428, 13433, 13438, 13443, 13448, 13453, 13458, 13463,
+ 13468, 13473, 13478, 13483, 13488, 13493, 13498, 13503,
+ 13508, 13513, 13518, 13523, 13528, 13533, 13538, 13543,
+ 13548, 13553, 13558, 13563, 13568, 13573, 13578, 13583,
+ 13588, 13593, 13598, 13603, 13608, 13613, 13618, 13623,
+ 13628, 13633, 13638, 13643, 13648, 13653, 13658, 13663,
+ 13668, 13673, 13678, 13683, 13688, 13693, 13698, 13703,
+ 13708, 13713, 13718, 13723, 13728, 13733, 13738, 13743,
+ 13748, 13753, 13758, 13763, 13768, 13773, 13778, 13783,
+ 13788, 13793, 13798, 13803, 13808, 13813, 13818, 13823,
+ 13828, 13833, 13838, 13843, 13848, 13853, 13858, 13863,
+ 13868, 13873, 13878, 13883, 13888, 13893, 13898, 13903,
+ 13908, 13913, 13918, 13923, 13928, 13933, 13938, 13943,
+ 13948, 13953, 13958, 13963, 13968, 13973, 13978, 13983,
+ 13988, 13993, 13998, 14003, 14008, 14013, 14018, 14023,
+ 14028, 14033, 14038, 14043, 14048, 14053, 14058, 14063,
+ 14068, 14073, 14078, 14083, 14088, 14093, 14098, 14103,
+ 14108, 14113, 14118, 14124, 14130, 14136, 14141, 14146,
+ 14151, 14156, 14161, 14166, 14171, 14176, 14181, 14186,
+
+ 14191, 14196, 14201, 14206, 14211, 14216, 14221, 14226,
+ 14231, 14236, 14241, 14246, 14251, 14256, 14261, 14266,
+ 14271, 14276, 14281, 14286, 14291, 14296, 14301, 14306,
+ 14311, 14316, 14321, 14326, 14331, 14336, 14341, 14346,
+ 14351, 14356, 14361, 14366, 14371, 14376, 14381, 14386,
+ 14391, 14396, 14401, 14406, 14411, 14416, 14421, 14426,
+ 14431, 14436, 14441, 14446, 14451, 14456, 14461, 14466,
+ 14471, 14476, 14481, 14486, 14491, 14496, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 14501, 14507, 14513, 14519, 14525, 14531, 14537, 14543,
+ 14549, 14555, 14561, 14567, 14573, 14579, 14585, 14591,
+ 14597, 14603, 14609, 14615, 14621, 14627, 14633, 14639,
+ 14645, 14651, 14657, 14663, 14669, 14675, 14681, 14687,
+ 14693, 14699, 14705, 14711, 14717, 14723, 14729, 14735,
+ 14741, 14747, 14753, 14759, 14765, 14771, 14777, 14783,
+ 14789, 14795, 14801, 14807, 14813, 14819, 14825, 14831,
+ 14837, 14843, 14849, 14855, 14861, 14867, 14873, 14879,
+ 0, 0, 14885, 14891, 14897, 14903, 14909, 14915,
+ 14921, 14927, 14933, 14939, 14945, 14951, 14957, 14963,
+ 14969, 14975, 14981, 14987, 14993, 14999, 15005, 15011,
+ 15017, 15023, 15029, 15035, 15041, 15047, 15053, 15059,
+ 15065, 15071, 15077, 15083, 15089, 15095, 15101, 15107,
+ 15113, 15119, 15125, 15131, 15137, 15143, 15149, 15155,
+ 15161, 15167, 15173, 15179, 15185, 15191, 15197, 15203,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 15209, 15215, 15221, 15228, 15235, 15242, 15249, 15256,
+ 15263, 15270, 15276, 15297, 15308, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 15315, 15319, 15323, 15327, 15331, 15335, 15339, 15343,
+ 15347, 15351, 15355, 15359, 15363, 15367, 15371, 15375,
+ 15379, 15383, 15387, 15391, 15395, 0, 0, 0,
+ 0, 15399, 15403, 15407, 15411, 15415, 15419, 15423,
+ 15427, 15431, 15435, 0, 15439, 15443, 15447, 15451,
+ 15455, 15459, 15463, 15467, 15471, 15475, 15479, 15483,
+ 15487, 15491, 15495, 15499, 15503, 15507, 15511, 0,
+ 15515, 15519, 15523, 15527, 0, 0, 0, 0,
+ 15531, 15536, 15541, 0, 15546, 0, 15551, 15556,
+ 15561, 15566, 15571, 15576, 15581, 15586, 15591, 15596,
+ 15601, 15605, 15609, 15613, 15617, 15621, 15625, 15629,
+ 15633, 15637, 15641, 15645, 15649, 15653, 15657, 15661,
+ 15665, 15669, 15673, 15677, 15681, 15685, 15689, 15693,
+ 15697, 15701, 15705, 15709, 15713, 15717, 15721, 15725,
+ 15729, 15733, 15737, 15741, 15745, 15749, 15753, 15757,
+ 15761, 15765, 15769, 15773, 15777, 15781, 15785, 15789,
+ 15793, 15797, 15801, 15805, 15809, 15813, 15817, 15821,
+ 15825, 15829, 15833, 15837, 15841, 15845, 15849, 15853,
+ 15857, 15861, 15865, 15869, 15873, 15877, 15881, 15885,
+ 15889, 15893, 15897, 15901, 15905, 15909, 15913, 15917,
+ 15921, 15925, 15929, 15933, 15937, 15941, 15945, 15949,
+ 15953, 15957, 15961, 15965, 15969, 15973, 15977, 15981,
+ 15985, 15989, 15993, 15997, 16001, 16005, 16009, 16013,
+ 16017, 16021, 16025, 16029, 16033, 16037, 16041, 16045,
+ 16049, 16053, 16057, 16061, 16065, 16069, 16074, 16079,
+ 16084, 16089, 16094, 16099, 16104, 0, 0, 0,
+
+ 0, 16109, 16113, 16117, 16121, 16125, 16129, 16133,
+ 16137, 16141, 16145, 16149, 16153, 16157, 16161, 16165,
+ 16169, 16173, 16177, 16181, 16185, 16189, 16193, 16197,
+ 16201, 16205, 16209, 16213, 16217, 16221, 16225, 16229,
+ 16233, 16237, 16241, 16245, 16249, 16253, 16257, 16261,
+ 16265, 16269, 16273, 16277, 16281, 16285, 16289, 16293,
+ 16297, 16301, 16305, 16309, 16313, 16317, 16321, 16325,
+ 16329, 16333, 16337, 16341, 16345, 16349, 16353, 16357,
+ 16361, 16365, 16369, 16373, 16377, 16381, 16385, 16389,
+ 16393, 16397, 16401, 16405, 16409, 16413, 16417, 16421,
+ 16425, 16429, 16433, 16437, 16441, 16445, 16449, 16453,
+ 16457, 16461, 16465, 16469, 16473, 16477, 16481, 16485,
+ 16489, 16493, 16497, 16501, 16505, 16509, 16513, 16517,
+ 16521, 16525, 16529, 16533, 16537, 16541, 16545, 16549,
+ 16553, 16557, 16561, 16565, 16569, 16573, 16577, 16581,
+ 16585, 16589, 16593, 16597, 16601, 16605, 16609, 16613,
+ 16617, 16621, 16625, 16629, 16633, 16637, 16641, 16645,
+ 16649, 16653, 16657, 16661, 16665, 16669, 16673, 16677,
+ 16681, 16685, 16689, 16693, 16697, 16701, 16705, 16709,
+ 16713, 16717, 16721, 16725, 16729, 16733, 16737, 16741,
+ 16745, 16749, 16753, 16757, 16761, 16765, 16769, 16773,
+ 16777, 16781, 16785, 16789, 16793, 16797, 16801, 16805,
+ 16809, 16813, 16817, 16821, 16825, 16829, 16833, 16837,
+ 16841, 16845, 16849, 16853, 16857, 16861, 16865, 0,
+ 0, 0, 16869, 16873, 16877, 16881, 16885, 16889,
+ 0, 0, 16893, 16897, 16901, 16905, 16909, 16913,
+ 0, 0, 16917, 16921, 16925, 16929, 16933, 16937,
+ 0, 0, 16941, 16945, 16949, 0, 0, 0,
+ 16953, 16957, 16961, 16965, 16969, 16973, 16977, 0,
+ 16981, 16985, 16989, 16993, 16997, 17001, 17005, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+// 67552 bytes
+
+const TQ_UINT16 TQUnicodeTables::ligature_map[] = {
+ 0,
+ 5567, 0,
+ 5552, 0,
+ 5572, 0,
+ 67, 72, 77, 82, 87, 92, 332, 342, 352, 966, 1196, 1206, 1346, 2365, 3145, 3155, 0,
+ 2375, 2385, 2395, 0,
+ 97, 362, 372, 382, 392, 0,
+ 402, 2415, 2425, 2435, 2445, 2455, 0,
+ 102, 107, 112, 117, 412, 422, 432, 442, 452, 1216, 1226, 1356, 2485, 2495, 3265, 3275, 3285, 0,
+ 2515, 0,
+ 462, 472, 482, 492, 1076, 1146, 2525, 0,
+ 502, 1336, 2535, 2545, 2555, 2565, 2575, 0,
+ 122, 127, 132, 137, 512, 522, 532, 542, 552, 976, 1236, 1246, 2585, 3345, 3355, 0,
+ 567, 0,
+ 577, 1086, 2605, 2615, 2625, 0,
+ 587, 597, 607, 2635, 2655, 2665, 0,
+ 2675, 2685, 2695, 0,
+ 142, 627, 637, 647, 1156, 2705, 2715, 2725, 2735, 0,
+ 147, 152, 157, 162, 167, 662, 672, 682, 901, 986, 1096, 1256, 1266, 1386, 3365, 3375, 0,
+ 2785, 2795, 0,
+ 692, 702, 712, 1276, 1286, 2805, 2815, 2835, 0,
+ 722, 732, 742, 752, 1316, 2845, 2855, 0,
+ 762, 772, 1326, 2895, 2905, 2915, 2925, 0,
+ 172, 177, 182, 187, 782, 792, 802, 812, 822, 832, 911, 996, 1296, 1306, 2935, 2945, 2955, 3485, 3495, 0,
+ 2985, 2995, 0,
+ 842, 3005, 3015, 3025, 3035, 3045, 0,
+ 3055, 3065, 0,
+ 192, 852, 862, 1406, 3075, 3555, 3565, 3575, 3585, 0,
+ 867, 877, 887, 3085, 3095, 3105, 0,
+ 197, 202, 207, 212, 217, 222, 337, 347, 357, 971, 1201, 1211, 1351, 2370, 3150, 3160, 0,
+ 2380, 2390, 2400, 0,
+ 227, 367, 377, 387, 397, 0,
+ 407, 2420, 2430, 2440, 2450, 2460, 0,
+ 232, 237, 242, 247, 417, 427, 437, 447, 457, 1221, 1231, 1361, 2490, 2500, 3270, 3280, 3290, 0,
+ 2520, 0,
+ 467, 477, 487, 497, 1081, 1151, 2530, 0,
+ 507, 1341, 2540, 2550, 2560, 2570, 2580, 3115, 0,
+ 252, 257, 262, 267, 517, 527, 537, 547, 981, 1241, 1251, 2590, 3350, 3360, 0,
+ 572, 1126, 0,
+ 582, 1091, 2610, 2620, 2630, 0,
+ 592, 602, 612, 2640, 2660, 2670, 0,
+ 2680, 2690, 2700, 0,
+ 272, 632, 642, 652, 1161, 2710, 2720, 2730, 2740, 0,
+ 277, 282, 287, 292, 297, 667, 677, 687, 906, 991, 1101, 1261, 1271, 1391, 3370, 3380, 0,
+ 2790, 2800, 0,
+ 697, 707, 717, 1281, 1291, 2810, 2820, 2840, 0,
+ 727, 737, 747, 757, 1321, 2850, 2860, 0,
+ 767, 777, 1331, 2900, 2910, 2920, 2930, 3120, 0,
+ 302, 307, 312, 317, 787, 797, 807, 817, 827, 837, 916, 1001, 1301, 1311, 2940, 2950, 2960, 3490, 3500, 0,
+ 2990, 3000, 0,
+ 847, 3010, 3020, 3030, 3040, 3050, 3125, 0,
+ 3060, 3070, 0,
+ 322, 327, 857, 1411, 3080, 3130, 3560, 3570, 3580, 3590, 0,
+ 872, 882, 892, 3090, 3100, 3110, 0,
+ 1537, 4476, 4670, 0,
+ 3165, 3175, 3185, 3195, 0,
+ 1046, 0,
+ 1166, 0,
+ 1066, 1176, 0,
+ 2405, 0,
+ 3295, 3305, 3315, 3325, 0,
+ 2595, 0,
+ 3385, 3395, 3405, 3415, 0,
+ 1376, 2745, 2755, 0,
+ 1366, 0,
+ 1186, 0,
+ 1006, 1016, 1026, 1036, 0,
+ 3170, 3180, 3190, 3200, 0,
+ 1051, 0,
+ 1171, 0,
+ 1071, 1181, 0,
+ 2410, 0,
+ 3300, 3310, 3320, 3330, 0,
+ 2600, 0,
+ 3390, 3400, 3410, 3420, 0,
+ 1381, 2750, 2760, 0,
+ 1371, 0,
+ 1191, 0,
+ 1011, 1021, 1031, 1041, 0,
+ 3215, 3225, 3235, 3245, 0,
+ 3220, 3230, 3240, 3250, 0,
+ 2465, 2475, 0,
+ 2470, 2480, 0,
+ 2765, 2775, 0,
+ 2770, 2780, 0,
+ 2865, 0,
+ 2870, 0,
+ 2875, 0,
+ 2880, 0,
+ 2965, 0,
+ 2970, 0,
+ 2975, 0,
+ 2980, 0,
+ 3140, 0,
+ 3435, 3445, 3455, 3465, 3475, 0,
+ 3440, 3450, 3460, 3470, 3480, 0,
+ 3505, 3515, 3525, 3535, 3545, 0,
+ 3510, 3520, 3530, 3540, 3550, 0,
+ 1116, 0,
+ 1106, 0,
+ 1111, 0,
+ 1056, 0,
+ 1061, 0,
+ 2505, 0,
+ 2510, 0,
+ 1396, 0,
+ 1401, 0,
+ 1121, 0,
+ 1514, 0,
+ 1542, 3635, 3640, 4433, 4438, 4443, 4452, 0,
+ 1551, 3705, 3710, 4506, 0,
+ 1556, 3775, 3780, 4515, 4524, 0,
+ 1561, 1586, 3855, 3860, 4573, 4578, 4583, 0,
+ 1566, 3925, 3930, 4708, 0,
+ 4665, 0,
+ 1571, 1591, 3995, 4646, 4651, 4656, 0,
+ 1576, 4055, 4060, 4717, 4726, 0,
+ 4418, 0,
+ 4491, 0,
+ 1596, 3595, 3600, 4095, 4398, 4403, 4413, 4423, 0,
+ 1601, 3675, 3680, 4104, 0,
+ 1606, 3735, 3740, 4113, 4486, 4496, 0,
+ 1611, 1621, 3815, 3820, 4122, 4544, 4549, 4563, 0,
+ 1631, 3895, 3900, 4131, 0,
+ 4626, 4631, 0,
+ 1626, 1636, 3955, 3960, 4140, 4607, 4612, 4636, 0,
+ 1641, 4015, 4020, 4149, 4688, 4698, 0,
+ 1581, 4554, 4568, 0,
+ 1616, 4617, 4641, 0,
+ 4693, 0,
+ 1658, 1663, 0,
+ 1711, 0,
+ 1796, 1806, 0,
+ 1706, 0,
+ 1696, 1701, 1816, 0,
+ 1786, 1836, 0,
+ 1846, 0,
+ 1721, 1731, 1856, 1866, 0,
+ 1716, 0,
+ 1876, 0,
+ 1726, 1906, 1916, 1926, 0,
+ 1936, 0,
+ 1946, 0,
+ 1896, 0,
+ 1801, 1811, 0,
+ 1751, 0,
+ 1741, 1746, 1821, 0,
+ 1791, 1841, 0,
+ 1851, 0,
+ 1736, 1766, 1861, 1871, 0,
+ 1761, 0,
+ 1881, 0,
+ 1771, 1911, 1921, 1931, 0,
+ 1941, 0,
+ 1951, 0,
+ 1901, 0,
+ 1756, 0,
+ 1776, 0,
+ 1781, 0,
+ 1826, 0,
+ 1831, 0,
+ 1886, 0,
+ 1891, 0,
+ 12167, 12172, 12177, 0,
+ 12182, 12292, 0,
+ 12187, 0,
+ 12192, 0,
+ 12197, 0,
+ 12202, 12287, 0,
+ 12207, 0,
+ 12212, 0,
+ 12097, 12217, 0,
+ 12222, 0,
+ 12227, 12297, 0,
+ 12232, 0,
+ 12237, 0,
+ 12242, 0,
+ 12247, 0,
+ 12252, 0,
+ 12257, 12302, 0,
+ 12262, 0,
+ 12267, 0,
+ 12272, 0,
+ 12147, 12152, 12277, 0,
+ 12282, 0,
+ 12102, 0,
+ 1961, 1966, 1976, 0,
+ 1971, 0,
+ 1981, 0,
+ 2011, 0,
+ 2016, 0,
+ 2006, 0,
+ 2036, 0,
+ 2041, 0,
+ 2046, 0,
+ 2051, 0,
+ 2056, 0,
+ 2061, 0,
+ 2021, 0,
+ 2066, 0,
+ 2071, 0,
+ 2026, 0,
+ 2031, 0,
+ 2086, 0,
+ 2091, 0,
+ 2096, 0,
+ 2076, 2081, 0,
+ 2111, 0,
+ 2116, 0,
+ 2121, 0,
+ 2126, 0,
+ 2101, 0,
+ 2106, 0,
+ 2146, 0,
+ 2151, 0,
+ 2131, 2136, 2141, 0,
+ 2156, 0,
+ 2161, 2171, 0,
+ 2166, 0,
+ 2176, 0,
+ 2181, 0,
+ 2186, 2191, 2196, 0,
+ 2201, 0,
+ 2206, 2216, 0,
+ 2211, 0,
+ 2221, 2226, 2236, 0,
+ 2231, 0,
+ 2290, 0,
+ 2265, 0,
+ 2270, 0,
+ 2275, 0,
+ 2280, 0,
+ 2285, 0,
+ 2295, 2300, 2325, 0,
+ 2355, 0,
+ 2330, 0,
+ 2335, 0,
+ 2340, 0,
+ 2345, 0,
+ 2350, 0,
+ 2305, 0,
+ 2315, 0,
+ 2360, 0,
+ 2645, 0,
+ 2650, 0,
+ 2825, 0,
+ 2830, 0,
+ 2885, 0,
+ 2890, 0,
+ 3205, 3255, 0,
+ 3210, 3260, 0,
+ 3335, 0,
+ 3340, 0,
+ 3425, 0,
+ 3430, 0,
+ 3605, 3615, 3625, 4158, 0,
+ 3610, 3620, 3630, 4163, 0,
+ 4168, 0,
+ 4173, 0,
+ 4178, 0,
+ 4183, 0,
+ 4188, 0,
+ 4193, 0,
+ 3645, 3655, 3665, 4198, 0,
+ 3650, 3660, 3670, 4203, 0,
+ 4208, 0,
+ 4213, 0,
+ 4218, 0,
+ 4223, 0,
+ 4228, 0,
+ 4233, 0,
+ 3685, 3695, 0,
+ 3690, 3700, 0,
+ 3715, 3725, 0,
+ 3720, 3730, 0,
+ 3745, 3755, 3765, 4238, 0,
+ 3750, 3760, 3770, 4243, 0,
+ 4248, 0,
+ 4253, 0,
+ 4258, 0,
+ 4263, 0,
+ 4268, 0,
+ 4273, 0,
+ 3785, 3795, 3805, 4278, 0,
+ 3790, 3800, 3810, 4283, 0,
+ 4288, 0,
+ 4293, 0,
+ 4298, 0,
+ 4303, 0,
+ 4308, 0,
+ 4313, 0,
+ 3825, 3835, 3845, 0,
+ 3830, 3840, 3850, 0,
+ 3865, 3875, 3885, 0,
+ 3870, 3880, 3890, 0,
+ 3905, 3915, 0,
+ 3910, 3920, 0,
+ 3935, 3945, 0,
+ 3940, 3950, 0,
+ 3965, 3975, 3985, 0,
+ 3970, 3980, 3990, 0,
+ 4000, 4005, 4010, 0,
+ 4025, 4035, 4045, 4318, 0,
+ 4030, 4040, 4050, 4323, 0,
+ 4328, 0,
+ 4333, 0,
+ 4338, 0,
+ 4343, 0,
+ 4348, 0,
+ 4353, 0,
+ 4065, 4075, 4085, 4358, 0,
+ 4070, 4080, 4090, 4363, 0,
+ 4368, 0,
+ 4373, 0,
+ 4378, 0,
+ 4383, 0,
+ 4388, 0,
+ 4393, 0,
+ 4408, 0,
+ 4481, 0,
+ 4683, 0,
+ 4428, 0,
+ 4529, 4534, 4539, 0,
+ 4501, 0,
+ 4703, 0,
+ 4592, 4597, 4602, 0,
+ 5455, 0,
+ 5460, 0,
+ 5465, 0,
+ 5470, 0,
+ 5480, 0,
+ 5475, 0,
+ 5485, 0,
+ 5490, 0,
+ 5495, 0,
+ 5500, 0,
+ 5505, 0,
+ 5532, 0,
+ 5537, 0,
+ 5542, 0,
+ 5547, 0,
+ 5562, 0,
+ 5557, 0,
+ 5577, 0,
+ 5582, 0,
+ 5587, 0,
+ 5592, 0,
+ 5597, 0,
+ 5602, 0,
+ 5607, 0,
+ 5612, 0,
+ 5657, 0,
+ 5662, 0,
+ 5617, 0,
+ 5622, 0,
+ 5627, 0,
+ 5632, 0,
+ 5667, 0,
+ 5672, 0,
+ 5637, 0,
+ 5642, 0,
+ 5647, 0,
+ 5652, 0,
+ 5677, 0,
+ 5682, 0,
+ 5687, 0,
+ 5692, 0,
+ 6430, 0,
+ 7444, 0,
+ 7319, 0,
+ 7324, 0,
+ 7329, 0,
+ 7334, 0,
+ 7339, 0,
+ 7344, 0,
+ 7349, 0,
+ 7354, 0,
+ 7359, 0,
+ 7364, 0,
+ 7369, 0,
+ 7374, 0,
+ 7379, 0,
+ 7384, 0,
+ 7389, 0,
+ 7394, 7399, 0,
+ 7404, 7409, 0,
+ 7414, 7419, 0,
+ 7424, 7429, 0,
+ 7434, 7439, 0,
+ 7459, 0,
+ 7594, 0,
+ 7469, 0,
+ 7474, 0,
+ 7479, 0,
+ 7484, 0,
+ 7489, 0,
+ 7494, 0,
+ 7499, 0,
+ 7504, 0,
+ 7509, 0,
+ 7514, 0,
+ 7519, 0,
+ 7524, 0,
+ 7529, 0,
+ 7534, 0,
+ 7539, 0,
+ 7544, 7549, 0,
+ 7554, 7559, 0,
+ 7564, 7569, 0,
+ 7574, 7579, 0,
+ 7584, 7589, 0,
+ 7599, 0,
+ 7604, 0,
+ 7609, 0,
+ 7614, 0,
+ 7619, 0,
+ 12157, 12162, 0,
+
+};
+
+const TQ_UINT16 TQUnicodeTables::ligature_info[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 8, 9, 10, 11, 12, 13, 8, 14,
+ 15, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 16, 17,
+ 8, 18, 19, 8, 8, 8, 8, 8,
+ 8, 8, 20, 8, 8, 8, 8, 8,
+ 21, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 22, 8, 8, 8, 8,
+
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 3, 5, 0,
+ 0, 7, 24, 28, 34, 41, 59, 61,
+ 69, 77, 93, 95, 101, 108, 112, 122,
+ 139, 0, 142, 151, 159, 167, 187, 190,
+ 197, 200, 210, 0, 0, 0, 0, 0,
+ 0, 217, 234, 238, 244, 251, 269, 271,
+ 279, 288, 303, 306, 312, 319, 323, 333,
+ 350, 0, 353, 362, 370, 379, 399, 402,
+ 410, 413, 424, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 431, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 435, 0, 440, 442, 444, 447,
+ 0, 0, 449, 0, 0, 0, 0, 454,
+ 0, 0, 0, 0, 456, 461, 465, 0,
+ 467, 0, 0, 0, 469, 0, 0, 0,
+ 0, 0, 474, 0, 479, 481, 483, 486,
+ 0, 0, 488, 0, 0, 0, 0, 493,
+ 0, 0, 0, 0, 495, 500, 504, 0,
+ 506, 0, 0, 0, 508, 0, 0, 0,
+
+ 0, 0, 513, 518, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 523, 526, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 529, 532, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 535, 537, 0, 0, 0, 0,
+ 539, 541, 0, 0, 0, 0, 0, 0,
+ 543, 545, 547, 549, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 551,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 553, 559, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 565,
+ 571, 0, 0, 0, 0, 0, 0, 577,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 579, 581, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 583, 585,
+ 587, 589, 0, 0, 0, 0, 591, 593,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 595, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 597, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 599, 0, 0, 0, 607, 0, 612,
+ 0, 618, 0, 0, 0, 0, 0, 626,
+ 0, 631, 0, 0, 0, 633, 0, 0,
+ 0, 640, 0, 0, 646, 0, 648, 0,
+ 0, 650, 0, 0, 0, 659, 0, 664,
+ 0, 671, 0, 0, 0, 0, 0, 680,
+ 0, 685, 0, 0, 0, 688, 0, 0,
+ 0, 697, 704, 708, 0, 0, 712, 0,
+ 0, 0, 714, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 717, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 719, 0, 0, 722, 0, 724, 728, 731,
+ 733, 0, 738, 0, 0, 0, 740, 0,
+ 0, 0, 0, 742, 0, 0, 0, 747,
+ 0, 0, 0, 749, 0, 751, 0, 0,
+ 753, 0, 0, 756, 0, 758, 762, 765,
+ 767, 0, 772, 0, 0, 0, 774, 0,
+ 0, 0, 0, 776, 0, 0, 0, 781,
+ 0, 0, 0, 783, 0, 785, 0, 0,
+ 0, 0, 0, 0, 0, 0, 787, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 789, 791, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 793, 795, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 797, 799, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 801, 805, 808, 810, 812, 814, 817, 0,
+ 819, 821, 824, 826, 829, 0, 831, 0,
+ 833, 835, 0, 837, 839, 0, 842, 844,
+ 846, 848, 852, 0, 0, 0, 0, 0,
+ 0, 0, 854, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 856,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 860, 0, 862, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 864, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 866, 0, 0, 868, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 870, 872, 874,
+ 0, 0, 0, 0, 876, 0, 0, 0,
+ 0, 878, 880, 0, 0, 0, 0, 0,
+ 882, 0, 0, 884, 0, 0, 0, 886,
+ 888, 0, 0, 890, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 892, 894, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 896,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 898,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 901, 903,
+ 0, 0, 0, 0, 905, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 907, 0, 0, 0, 0,
+ 0, 0, 909, 0, 0, 0, 0, 0,
+ 911, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 913, 915, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 917,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 921, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 923, 926,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 928, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 930,
+ 0, 0, 0, 0, 0, 0, 932, 0,
+ 0, 0, 936, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 938, 941,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 943, 0, 0, 947, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 949, 0, 951, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 953, 0, 0, 0,
+ 0, 955, 0, 0, 0, 0, 957, 0,
+ 0, 0, 0, 959, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 961, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 965, 0, 967, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 969, 0, 0, 0,
+ 0, 971, 0, 0, 0, 0, 973, 0,
+ 0, 0, 0, 975, 0, 0, 0, 0,
+ 0, 0, 977, 979, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 981, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 983, 985,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 987, 989, 0, 0, 0, 0,
+ 0, 0, 991, 993, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 995, 998, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1001, 1003, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1005, 1007, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 1009, 1014, 1019, 1021, 1023, 1025, 1027, 1029,
+ 1031, 1036, 1041, 1043, 1045, 1047, 1049, 1051,
+ 1053, 1056, 0, 0, 0, 0, 0, 0,
+ 1059, 1062, 0, 0, 0, 0, 0, 0,
+ 1065, 1070, 1075, 1077, 1079, 1081, 1083, 1085,
+ 1087, 1092, 1097, 1099, 1101, 1103, 1105, 1107,
+ 1109, 1113, 0, 0, 0, 0, 0, 0,
+ 1117, 1121, 0, 0, 0, 0, 0, 0,
+ 1125, 1128, 0, 0, 0, 0, 0, 0,
+ 1131, 1134, 0, 0, 0, 0, 0, 0,
+ 1137, 1141, 0, 0, 0, 0, 0, 0,
+ 0, 1145, 0, 0, 0, 0, 0, 0,
+ 1149, 1154, 1159, 1161, 1163, 1165, 1167, 1169,
+ 1171, 1176, 1181, 1183, 1185, 1187, 1189, 1191,
+ 1193, 0, 0, 0, 1195, 0, 0, 0,
+ 0, 0, 0, 0, 1197, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1199, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1201,
+ 0, 0, 0, 0, 0, 0, 1205, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1207, 0,
+ 0, 0, 0, 0, 0, 0, 1209, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1213, 0, 1215, 0, 1217, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1219, 0, 1221, 0, 1223, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 1225, 0, 0, 0, 0,
+ 1227, 0, 0, 1229, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 1231, 0, 1233, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1235, 0, 0, 0,
+ 0, 0, 0, 1237, 0, 1239, 0, 0,
+ 1241, 0, 0, 0, 0, 1243, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1245, 0, 0, 1247, 1249, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1251, 1253, 0, 0, 1255, 1257,
+ 0, 0, 1259, 1261, 1263, 1265, 0, 0,
+ 0, 0, 1267, 1269, 0, 0, 1271, 1273,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1275, 1277, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1279, 0, 0, 0, 0, 0,
+ 1281, 1283, 0, 1285, 0, 0, 0, 0,
+ 0, 0, 1287, 1289, 1291, 1293, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1295, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1297, 0,
+ 0, 0, 0, 1299, 0, 1301, 0, 1303,
+ 0, 1305, 0, 1307, 0, 1309, 0, 1311,
+ 0, 1313, 0, 1315, 0, 1317, 0, 1319,
+ 0, 1321, 0, 0, 1323, 0, 1325, 0,
+ 1327, 0, 0, 0, 0, 0, 0, 1329,
+ 0, 0, 1332, 0, 0, 1335, 0, 0,
+ 1338, 0, 0, 1341, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1344, 0, 0,
+ 0, 0, 0, 0, 0, 0, 1346, 0,
+ 0, 0, 0, 1348, 0, 1350, 0, 1352,
+ 0, 1354, 0, 1356, 0, 1358, 0, 1360,
+ 0, 1362, 0, 1364, 0, 1366, 0, 1368,
+ 0, 1370, 0, 0, 1372, 0, 1374, 0,
+ 1376, 0, 0, 0, 0, 0, 0, 1378,
+ 0, 0, 1381, 0, 0, 1384, 0, 0,
+ 1387, 0, 0, 1390, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1393,
+ 1395, 1397, 1399, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1401, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1403, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+// 14586 bytes
+
+const TQ_UINT8 TQUnicodeTables::direction_info[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 2, 9, 10, 11, 12, 13, 14, 15,
+ 16, 2, 2, 2, 2, 2, 17, 18,
+ 19, 2, 2, 2, 2, 2, 2, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28,
+ 26, 29, 30, 2, 2, 2, 31, 32,
+ 33, 2, 34, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 35, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 36, 37, 38, 39, 40,
+
+
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 8, 7, 8, 9, 7, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 7, 7, 7, 8,
+ 9, 10, 10, 4, 4, 4, 10, 10,
+ 138, 138, 10, 4, 6, 4, 6, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 6, 10, 138, 10, 138, 10,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 138, 10, 138, 10, 10,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 138, 10, 138, 10, 18,
+ 18, 18, 18, 18, 18, 7, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 18, 18, 18, 18, 18, 18, 18, 18,
+ 6, 10, 4, 4, 4, 4, 10, 10,
+ 10, 10, 0, 138, 10, 10, 10, 10,
+ 4, 4, 2, 2, 10, 0, 10, 10,
+ 10, 2, 0, 138, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 10, 10, 0, 0, 0, 0, 0,
+ 0, 0, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 0, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 0, 0, 0, 0, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 10, 10, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 17, 17, 17, 17, 0,
+ 17, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 0, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 0, 17, 17, 17, 1, 17,
+ 1, 17, 17, 1, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 6, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 13, 0, 0, 0, 13,
+ 0, 13, 77, 77, 77, 77, 45, 77,
+ 45, 77, 45, 45, 45, 45, 45, 77,
+ 77, 77, 77, 45, 45, 45, 45, 45,
+ 45, 45, 45, 0, 0, 0, 0, 0,
+ 109, 45, 45, 45, 45, 45, 45, 45,
+ 77, 45, 45, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 4, 5, 5, 13, 45, 45,
+ 17, 77, 77, 77, 13, 77, 77, 77,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 77, 77, 77, 77,
+ 77, 77, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 77, 45, 77, 77, 77, 77, 77, 77,
+ 77, 77, 77, 77, 45, 77, 45, 77,
+ 45, 45, 77, 77, 13, 77, 17, 17,
+ 17, 17, 17, 17, 17, 13, 17, 17,
+ 17, 17, 17, 17, 17, 13, 13, 17,
+ 17, 10, 17, 17, 17, 17, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 45, 45, 45, 13, 13, 0,
+
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 0, 18,
+ 77, 17, 45, 45, 45, 77, 77, 77,
+ 77, 77, 45, 45, 45, 45, 77, 45,
+ 45, 45, 45, 45, 45, 45, 45, 45,
+ 77, 45, 77, 45, 77, 0, 0, 0,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 13, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 17, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 0,
+ 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 0, 0, 0, 0, 17, 0, 0,
+ 0, 17, 17, 17, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 0,
+ 0, 17, 17, 17, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 4, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 0,
+ 0, 17, 17, 0, 0, 0, 0, 17,
+ 17, 0, 0, 17, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 0,
+ 0, 17, 17, 17, 17, 17, 0, 17,
+ 17, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 17, 0, 0, 17,
+ 0, 17, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 17, 17,
+ 17, 0, 0, 0, 0, 0, 17, 17,
+ 17, 0, 17, 17, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 17, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 17,
+ 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 0, 0, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 17, 0, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 0, 0, 17, 17, 17, 17,
+ 17, 17, 17, 0, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0, 17,
+ 17, 17, 17, 17, 17, 17, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 0, 0, 17, 17, 17, 17,
+ 17, 17, 0, 17, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 17, 17, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 0, 17,
+ 0, 17, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 0,
+ 17, 17, 17, 17, 17, 0, 17, 17,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 17, 17, 17,
+ 17, 0, 17, 0, 0, 0, 17, 17,
+ 0, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 9, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 10, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 17, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 17,
+ 17, 17, 17, 17, 17, 17, 0, 0,
+ 0, 0, 0, 0, 0, 0, 17, 0,
+ 0, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 4, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 17, 17, 17, 18, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 0, 10,
+ 10, 10, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 10, 10, 0,
+
+ 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 18, 18, 114, 0, 1,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 9, 7, 11, 14, 16, 12, 15, 9,
+ 4, 4, 4, 4, 4, 10, 10, 10,
+ 10, 138, 138, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 138, 138, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 0, 0, 0, 0, 10,
+ 0, 0, 0, 0, 0, 0, 0, 9,
+ 18, 18, 18, 18, 0, 0, 0, 0,
+ 0, 0, 18, 18, 18, 18, 18, 18,
+ 2, 0, 0, 0, 2, 2, 2, 2,
+ 2, 2, 4, 4, 10, 138, 138, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 4, 4, 10, 138, 138, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 10, 10, 0, 10, 10, 10, 10, 0,
+ 10, 10, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 10, 0, 10, 10,
+ 10, 0, 0, 0, 0, 0, 10, 10,
+ 10, 10, 10, 10, 0, 10, 0, 10,
+ 0, 10, 0, 0, 0, 0, 4, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0,
+ 0, 0, 10, 0, 0, 0, 0, 0,
+ 138, 10, 10, 10, 10, 0, 0, 0,
+ 0, 0, 10, 10, 0, 0, 0, 0,
+ 0, 0, 0, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+
+ 10, 138, 138, 138, 138, 10, 10, 10,
+ 138, 138, 138, 138, 138, 138, 10, 10,
+ 10, 138, 4, 4, 10, 138, 138, 10,
+ 10, 10, 138, 138, 138, 138, 10, 138,
+ 138, 138, 138, 10, 138, 10, 138, 10,
+ 10, 10, 10, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 10, 10, 10, 10,
+ 10, 138, 10, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 10, 10, 10,
+ 10, 10, 138, 138, 138, 138, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 138,
+ 138, 10, 138, 10, 138, 138, 138, 138,
+ 138, 138, 138, 138, 10, 10, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 10, 10, 138,
+ 138, 138, 138, 10, 10, 10, 10, 10,
+ 138, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 138, 138, 10, 10, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 10, 10, 10, 10, 10, 138, 138,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 138, 138, 138, 138, 138, 10, 10,
+ 138, 138, 10, 10, 10, 10, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 10, 10,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 138, 138, 138, 138, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 138, 138, 10, 10, 10, 10, 10, 10,
+ 10, 138, 138, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 0, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 0, 0, 10, 10,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 10, 10, 10, 10, 0, 10, 10,
+ 10, 10, 0, 0, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 0, 10, 0, 10,
+ 10, 10, 10, 0, 0, 0, 10, 0,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 138, 138, 138, 138, 10,
+ 10, 10, 10, 10, 138, 138, 138, 10,
+ 10, 10, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 10, 10, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 138, 10, 10, 10, 10, 10, 10, 10,
+ 138, 138, 138, 138, 138, 138, 10, 10,
+ 10, 138, 10, 10, 10, 10, 138, 138,
+ 138, 138, 138, 10, 138, 138, 10, 10,
+ 138, 138, 138, 138, 138, 10, 10, 10,
+ 10, 138, 10, 138, 138, 138, 10, 10,
+ 138, 138, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 138, 138, 138, 138,
+ 138, 138, 10, 10, 138, 138, 10, 10,
+
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 10, 138, 138,
+ 138, 138, 10, 10, 138, 10, 138, 10,
+ 10, 138, 10, 138, 138, 138, 138, 10,
+ 10, 10, 10, 10, 138, 138, 10, 10,
+ 10, 10, 10, 10, 138, 138, 138, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 138,
+ 138, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 138, 138, 10, 10,
+ 10, 10, 138, 138, 138, 138, 10, 138,
+ 138, 10, 10, 138, 138, 10, 10, 10,
+ 10, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 10, 10, 138, 138,
+ 138, 138, 138, 138, 138, 138, 10, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 138, 138, 138, 138, 138, 10,
+ 10, 10, 10, 10, 138, 10, 138, 10,
+ 10, 10, 138, 138, 138, 138, 138, 10,
+ 10, 10, 10, 10, 138, 138, 138, 10,
+ 10, 10, 10, 138, 10, 10, 10, 138,
+ 138, 138, 138, 138, 10, 138, 10, 10,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 0, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 0, 0, 0, 0,
+
+ 9, 10, 10, 10, 10, 0, 0, 0,
+ 138, 138, 138, 138, 138, 138, 138, 138,
+ 138, 138, 10, 10, 138, 138, 138, 138,
+ 138, 138, 138, 138, 10, 10, 10, 10,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 17, 17, 17, 17, 17, 17,
+ 10, 0, 0, 0, 0, 0, 10, 10,
+ 0, 0, 0, 0, 0, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 17, 17, 10, 10, 0, 0, 0,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 10, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 1, 17, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 4, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0,
+ 1, 1, 1, 1, 1, 0, 1, 0,
+ 1, 1, 0, 1, 1, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 10, 10,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 0, 0, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 0, 0, 0,
+
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 17, 17, 17, 17, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 10, 10, 10, 10, 10, 10, 10,
+ 6, 10, 6, 0, 10, 6, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 4,
+ 10, 10, 4, 4, 10, 10, 10, 0,
+ 10, 4, 4, 10, 0, 0, 0, 0,
+ 13, 13, 13, 13, 13, 0, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 0, 0, 18,
+
+ 0, 10, 10, 4, 4, 4, 10, 10,
+ 138, 138, 10, 4, 6, 4, 6, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 6, 10, 138, 10, 138, 10,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 138, 10, 138, 10, 10,
+ 10, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 138, 10, 138, 10, 138,
+ 138, 10, 138, 138, 10, 10, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 10, 10, 10, 4, 4, 0,
+ 10, 10, 10, 10, 10, 10, 10, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 18, 18, 18, 10, 10, 0, 0,
+};
+
+// 25082 bytes
+
+const TQ_UINT8 TQUnicodeTables::combining_info[] = {
+ 1, 1, 1, 2, 3, 4, 5, 6,
+ 1, 7, 8, 9, 10, 11, 12, 13,
+ 14, 1, 1, 1, 1, 1, 1, 15,
+ 16, 1, 1, 1, 1, 1, 1, 1,
+ 17, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 18, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 19, 1, 1, 20, 1,
+
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 232, 220, 220,
+ 220, 220, 232, 216, 220, 220, 220, 220,
+ 220, 202, 202, 220, 220, 220, 220, 202,
+ 202, 220, 220, 220, 220, 220, 220, 220,
+ 220, 220, 220, 220, 1, 1, 1, 1,
+ 1, 220, 220, 220, 220, 230, 230, 230,
+ 230, 230, 230, 230, 230, 240, 230, 220,
+ 220, 220, 230, 230, 230, 220, 220, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 234, 234, 233, 230, 230, 230, 230, 230,
+ 230, 230, 230, 230, 230, 230, 230, 230,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 230, 230, 230, 230, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 220, 230, 230, 230, 230, 220, 230,
+ 230, 230, 222, 220, 230, 230, 230, 230,
+ 230, 230, 0, 220, 220, 220, 220, 220,
+ 230, 230, 220, 230, 230, 222, 228, 230,
+ 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 0, 20, 21, 22, 0, 23,
+ 0, 24, 25, 0, 230, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 27, 28, 29, 30, 31,
+ 32, 33, 34, 230, 230, 220, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 35, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 230, 230,
+ 230, 230, 230, 230, 230, 0, 0, 230,
+ 230, 230, 230, 220, 230, 0, 0, 230,
+ 230, 0, 220, 230, 230, 220, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 36, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 230, 220, 230, 230, 220, 230, 230, 220,
+ 220, 220, 230, 220, 220, 230, 220, 230,
+ 230, 230, 220, 230, 220, 230, 220, 230,
+ 220, 230, 230, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 0, 0,
+ 0, 230, 220, 230, 230, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 84, 91, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 9, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 9, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 103, 103, 9, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 107, 107, 107, 107, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 118, 118, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 122, 122, 122, 122, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 220, 220, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 220, 0, 220,
+ 0, 216, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 129, 130, 0, 132, 0, 0, 0,
+ 0, 0, 130, 130, 130, 130, 0, 0,
+ 130, 0, 230, 230, 9, 0, 230, 230,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 220, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 7,
+ 0, 9, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 9, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 9, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 228, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 230, 230, 1, 1, 230, 230, 230, 230,
+ 1, 1, 1, 230, 230, 0, 0, 0,
+ 0, 230, 0, 0, 0, 1, 1, 230,
+ 220, 230, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 218, 228, 232, 222, 224, 224,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 8, 8, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 26, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 230, 230, 230, 230, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+// 30458 bytes
+
+const TQ_UINT16 TQUnicodeTables::case_info[] = {
+ 1, 2, 3, 4, 5, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 8,
+ 0, 9, 0, 0, 10, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 11,
+
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0, 0, 0, 0, 0,
+ 0, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+ 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+ 0x58, 0x59, 0x5a, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0x39c, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0x178,
+
+ 0x101, 0x100, 0x103, 0x102, 0x105, 0x104, 0x107, 0x106,
+ 0x109, 0x108, 0x10b, 0x10a, 0x10d, 0x10c, 0x10f, 0x10e,
+ 0x111, 0x110, 0x113, 0x112, 0x115, 0x114, 0x117, 0x116,
+ 0x119, 0x118, 0x11b, 0x11a, 0x11d, 0x11c, 0x11f, 0x11e,
+ 0x121, 0x120, 0x123, 0x122, 0x125, 0x124, 0x127, 0x126,
+ 0x129, 0x128, 0x12b, 0x12a, 0x12d, 0x12c, 0x12f, 0x12e,
+ 0x69, 0x49, 0x133, 0x132, 0x135, 0x134, 0x137, 0x136,
+ 0, 0x13a, 0x139, 0x13c, 0x13b, 0x13e, 0x13d, 0x140,
+ 0x13f, 0x142, 0x141, 0x144, 0x143, 0x146, 0x145, 0x148,
+ 0x147, 0, 0x14b, 0x14a, 0x14d, 0x14c, 0x14f, 0x14e,
+ 0x151, 0x150, 0x153, 0x152, 0x155, 0x154, 0x157, 0x156,
+ 0x159, 0x158, 0x15b, 0x15a, 0x15d, 0x15c, 0x15f, 0x15e,
+ 0x161, 0x160, 0x163, 0x162, 0x165, 0x164, 0x167, 0x166,
+ 0x169, 0x168, 0x16b, 0x16a, 0x16d, 0x16c, 0x16f, 0x16e,
+ 0x171, 0x170, 0x173, 0x172, 0x175, 0x174, 0x177, 0x176,
+ 0xff, 0x17a, 0x179, 0x17c, 0x17b, 0x17e, 0x17d, 0x53,
+ 0, 0x253, 0x183, 0x182, 0x185, 0x184, 0x254, 0x188,
+ 0x187, 0x256, 0x257, 0x18c, 0x18b, 0, 0x1dd, 0x259,
+ 0x25b, 0x192, 0x191, 0x260, 0x263, 0x1f6, 0x269, 0x268,
+ 0x199, 0x198, 0, 0, 0x26f, 0x272, 0x220, 0x275,
+ 0x1a1, 0x1a0, 0x1a3, 0x1a2, 0x1a5, 0x1a4, 0x280, 0x1a8,
+ 0x1a7, 0x283, 0, 0, 0x1ad, 0x1ac, 0x288, 0x1b0,
+ 0x1af, 0x28a, 0x28b, 0x1b4, 0x1b3, 0x1b6, 0x1b5, 0x292,
+ 0x1b9, 0x1b8, 0, 0, 0x1bd, 0x1bc, 0, 0x1f7,
+ 0, 0, 0, 0, 0x1c6, 0x1c4, 0x1c4, 0x1c9,
+ 0x1c7, 0x1c7, 0x1cc, 0x1ca, 0x1ca, 0x1ce, 0x1cd, 0x1d0,
+ 0x1cf, 0x1d2, 0x1d1, 0x1d4, 0x1d3, 0x1d6, 0x1d5, 0x1d8,
+ 0x1d7, 0x1da, 0x1d9, 0x1dc, 0x1db, 0x18e, 0x1df, 0x1de,
+ 0x1e1, 0x1e0, 0x1e3, 0x1e2, 0x1e5, 0x1e4, 0x1e7, 0x1e6,
+ 0x1e9, 0x1e8, 0x1eb, 0x1ea, 0x1ed, 0x1ec, 0x1ef, 0x1ee,
+ 0, 0x1f3, 0x1f1, 0x1f1, 0x1f5, 0x1f4, 0x195, 0x1bf,
+ 0x1f9, 0x1f8, 0x1fb, 0x1fa, 0x1fd, 0x1fc, 0x1ff, 0x1fe,
+
+ 0x201, 0x200, 0x203, 0x202, 0x205, 0x204, 0x207, 0x206,
+ 0x209, 0x208, 0x20b, 0x20a, 0x20d, 0x20c, 0x20f, 0x20e,
+ 0x211, 0x210, 0x213, 0x212, 0x215, 0x214, 0x217, 0x216,
+ 0x219, 0x218, 0x21b, 0x21a, 0x21d, 0x21c, 0x21f, 0x21e,
+ 0x19e, 0, 0x223, 0x222, 0x225, 0x224, 0x227, 0x226,
+ 0x229, 0x228, 0x22b, 0x22a, 0x22d, 0x22c, 0x22f, 0x22e,
+ 0x231, 0x230, 0x233, 0x232, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0x181, 0x186, 0, 0x189, 0x18a,
+ 0, 0x18f, 0, 0x190, 0, 0, 0, 0,
+ 0x193, 0, 0, 0x194, 0, 0, 0, 0,
+ 0x197, 0x196, 0, 0, 0, 0, 0, 0x19c,
+ 0, 0, 0x19d, 0, 0, 0x19f, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x1a6, 0, 0, 0x1a9, 0, 0, 0, 0,
+ 0x1ae, 0, 0x1b1, 0x1b2, 0, 0, 0, 0,
+ 0, 0, 0x1b7, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0x399, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0x3ac, 0,
+ 0x3ad, 0x3ae, 0x3af, 0, 0x3cc, 0, 0x3cd, 0x3ce,
+ 0, 0x3b1, 0x3b2, 0x3b3, 0x3b4, 0x3b5, 0x3b6, 0x3b7,
+ 0x3b8, 0x3b9, 0x3ba, 0x3bb, 0x3bc, 0x3bd, 0x3be, 0x3bf,
+ 0x3c0, 0x3c1, 0, 0x3c3, 0x3c4, 0x3c5, 0x3c6, 0x3c7,
+ 0x3c8, 0x3c9, 0x3ca, 0x3cb, 0x386, 0x388, 0x389, 0x38a,
+ 0, 0x391, 0x392, 0x393, 0x394, 0x395, 0x396, 0x397,
+ 0x398, 0x399, 0x39a, 0x39b, 0x39c, 0x39d, 0x39e, 0x39f,
+ 0x3a0, 0x3a1, 0x3a3, 0x3a3, 0x3a4, 0x3a5, 0x3a6, 0x3a7,
+ 0x3a8, 0x3a9, 0x3aa, 0x3ab, 0x38c, 0x38e, 0x38f, 0,
+ 0x392, 0x398, 0, 0, 0, 0x3a6, 0x3a0, 0,
+ 0x3d9, 0x3d8, 0x3db, 0x3da, 0x3dd, 0x3dc, 0x3df, 0x3de,
+ 0x3e1, 0x3e0, 0x3e3, 0x3e2, 0x3e5, 0x3e4, 0x3e7, 0x3e6,
+ 0x3e9, 0x3e8, 0x3eb, 0x3ea, 0x3ed, 0x3ec, 0x3ef, 0x3ee,
+ 0x39a, 0x3a1, 0x3a3, 0, 0x3b8, 0x395, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0x450, 0x451, 0x452, 0x453, 0x454, 0x455, 0x456, 0x457,
+ 0x458, 0x459, 0x45a, 0x45b, 0x45c, 0x45d, 0x45e, 0x45f,
+ 0x430, 0x431, 0x432, 0x433, 0x434, 0x435, 0x436, 0x437,
+ 0x438, 0x439, 0x43a, 0x43b, 0x43c, 0x43d, 0x43e, 0x43f,
+ 0x440, 0x441, 0x442, 0x443, 0x444, 0x445, 0x446, 0x447,
+ 0x448, 0x449, 0x44a, 0x44b, 0x44c, 0x44d, 0x44e, 0x44f,
+ 0x410, 0x411, 0x412, 0x413, 0x414, 0x415, 0x416, 0x417,
+ 0x418, 0x419, 0x41a, 0x41b, 0x41c, 0x41d, 0x41e, 0x41f,
+ 0x420, 0x421, 0x422, 0x423, 0x424, 0x425, 0x426, 0x427,
+ 0x428, 0x429, 0x42a, 0x42b, 0x42c, 0x42d, 0x42e, 0x42f,
+ 0x400, 0x401, 0x402, 0x403, 0x404, 0x405, 0x406, 0x407,
+ 0x408, 0x409, 0x40a, 0x40b, 0x40c, 0x40d, 0x40e, 0x40f,
+ 0x461, 0x460, 0x463, 0x462, 0x465, 0x464, 0x467, 0x466,
+ 0x469, 0x468, 0x46b, 0x46a, 0x46d, 0x46c, 0x46f, 0x46e,
+ 0x471, 0x470, 0x473, 0x472, 0x475, 0x474, 0x477, 0x476,
+ 0x479, 0x478, 0x47b, 0x47a, 0x47d, 0x47c, 0x47f, 0x47e,
+ 0x481, 0x480, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0x48b, 0x48a, 0x48d, 0x48c, 0x48f, 0x48e,
+ 0x491, 0x490, 0x493, 0x492, 0x495, 0x494, 0x497, 0x496,
+ 0x499, 0x498, 0x49b, 0x49a, 0x49d, 0x49c, 0x49f, 0x49e,
+ 0x4a1, 0x4a0, 0x4a3, 0x4a2, 0x4a5, 0x4a4, 0x4a7, 0x4a6,
+ 0x4a9, 0x4a8, 0x4ab, 0x4aa, 0x4ad, 0x4ac, 0x4af, 0x4ae,
+ 0x4b1, 0x4b0, 0x4b3, 0x4b2, 0x4b5, 0x4b4, 0x4b7, 0x4b6,
+ 0x4b9, 0x4b8, 0x4bb, 0x4ba, 0x4bd, 0x4bc, 0x4bf, 0x4be,
+ 0, 0x4c2, 0x4c1, 0x4c4, 0x4c3, 0x4c6, 0x4c5, 0x4c8,
+ 0x4c7, 0x4ca, 0x4c9, 0x4cc, 0x4cb, 0x4ce, 0x4cd, 0,
+ 0x4d1, 0x4d0, 0x4d3, 0x4d2, 0x4d5, 0x4d4, 0x4d7, 0x4d6,
+ 0x4d9, 0x4d8, 0x4db, 0x4da, 0x4dd, 0x4dc, 0x4df, 0x4de,
+ 0x4e1, 0x4e0, 0x4e3, 0x4e2, 0x4e5, 0x4e4, 0x4e7, 0x4e6,
+ 0x4e9, 0x4e8, 0x4eb, 0x4ea, 0x4ed, 0x4ec, 0x4ef, 0x4ee,
+ 0x4f1, 0x4f0, 0x4f3, 0x4f2, 0x4f5, 0x4f4, 0, 0,
+ 0x4f9, 0x4f8, 0, 0, 0, 0, 0, 0,
+
+ 0x501, 0x500, 0x503, 0x502, 0x505, 0x504, 0x507, 0x506,
+ 0x509, 0x508, 0x50b, 0x50a, 0x50d, 0x50c, 0x50f, 0x50e,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x561, 0x562, 0x563, 0x564, 0x565, 0x566, 0x567,
+ 0x568, 0x569, 0x56a, 0x56b, 0x56c, 0x56d, 0x56e, 0x56f,
+ 0x570, 0x571, 0x572, 0x573, 0x574, 0x575, 0x576, 0x577,
+ 0x578, 0x579, 0x57a, 0x57b, 0x57c, 0x57d, 0x57e, 0x57f,
+ 0x580, 0x581, 0x582, 0x583, 0x584, 0x585, 0x586, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x531, 0x532, 0x533, 0x534, 0x535, 0x536, 0x537,
+ 0x538, 0x539, 0x53a, 0x53b, 0x53c, 0x53d, 0x53e, 0x53f,
+ 0x540, 0x541, 0x542, 0x543, 0x544, 0x545, 0x546, 0x547,
+ 0x548, 0x549, 0x54a, 0x54b, 0x54c, 0x54d, 0x54e, 0x54f,
+ 0x550, 0x551, 0x552, 0x553, 0x554, 0x555, 0x556, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0x1e01, 0x1e00, 0x1e03, 0x1e02, 0x1e05, 0x1e04, 0x1e07, 0x1e06,
+ 0x1e09, 0x1e08, 0x1e0b, 0x1e0a, 0x1e0d, 0x1e0c, 0x1e0f, 0x1e0e,
+ 0x1e11, 0x1e10, 0x1e13, 0x1e12, 0x1e15, 0x1e14, 0x1e17, 0x1e16,
+ 0x1e19, 0x1e18, 0x1e1b, 0x1e1a, 0x1e1d, 0x1e1c, 0x1e1f, 0x1e1e,
+ 0x1e21, 0x1e20, 0x1e23, 0x1e22, 0x1e25, 0x1e24, 0x1e27, 0x1e26,
+ 0x1e29, 0x1e28, 0x1e2b, 0x1e2a, 0x1e2d, 0x1e2c, 0x1e2f, 0x1e2e,
+ 0x1e31, 0x1e30, 0x1e33, 0x1e32, 0x1e35, 0x1e34, 0x1e37, 0x1e36,
+ 0x1e39, 0x1e38, 0x1e3b, 0x1e3a, 0x1e3d, 0x1e3c, 0x1e3f, 0x1e3e,
+ 0x1e41, 0x1e40, 0x1e43, 0x1e42, 0x1e45, 0x1e44, 0x1e47, 0x1e46,
+ 0x1e49, 0x1e48, 0x1e4b, 0x1e4a, 0x1e4d, 0x1e4c, 0x1e4f, 0x1e4e,
+ 0x1e51, 0x1e50, 0x1e53, 0x1e52, 0x1e55, 0x1e54, 0x1e57, 0x1e56,
+ 0x1e59, 0x1e58, 0x1e5b, 0x1e5a, 0x1e5d, 0x1e5c, 0x1e5f, 0x1e5e,
+ 0x1e61, 0x1e60, 0x1e63, 0x1e62, 0x1e65, 0x1e64, 0x1e67, 0x1e66,
+ 0x1e69, 0x1e68, 0x1e6b, 0x1e6a, 0x1e6d, 0x1e6c, 0x1e6f, 0x1e6e,
+ 0x1e71, 0x1e70, 0x1e73, 0x1e72, 0x1e75, 0x1e74, 0x1e77, 0x1e76,
+ 0x1e79, 0x1e78, 0x1e7b, 0x1e7a, 0x1e7d, 0x1e7c, 0x1e7f, 0x1e7e,
+ 0x1e81, 0x1e80, 0x1e83, 0x1e82, 0x1e85, 0x1e84, 0x1e87, 0x1e86,
+ 0x1e89, 0x1e88, 0x1e8b, 0x1e8a, 0x1e8d, 0x1e8c, 0x1e8f, 0x1e8e,
+ 0x1e91, 0x1e90, 0x1e93, 0x1e92, 0x1e95, 0x1e94, 0, 0,
+ 0, 0, 0, 0x1e60, 0, 0, 0, 0,
+ 0x1ea1, 0x1ea0, 0x1ea3, 0x1ea2, 0x1ea5, 0x1ea4, 0x1ea7, 0x1ea6,
+ 0x1ea9, 0x1ea8, 0x1eab, 0x1eaa, 0x1ead, 0x1eac, 0x1eaf, 0x1eae,
+ 0x1eb1, 0x1eb0, 0x1eb3, 0x1eb2, 0x1eb5, 0x1eb4, 0x1eb7, 0x1eb6,
+ 0x1eb9, 0x1eb8, 0x1ebb, 0x1eba, 0x1ebd, 0x1ebc, 0x1ebf, 0x1ebe,
+ 0x1ec1, 0x1ec0, 0x1ec3, 0x1ec2, 0x1ec5, 0x1ec4, 0x1ec7, 0x1ec6,
+ 0x1ec9, 0x1ec8, 0x1ecb, 0x1eca, 0x1ecd, 0x1ecc, 0x1ecf, 0x1ece,
+ 0x1ed1, 0x1ed0, 0x1ed3, 0x1ed2, 0x1ed5, 0x1ed4, 0x1ed7, 0x1ed6,
+ 0x1ed9, 0x1ed8, 0x1edb, 0x1eda, 0x1edd, 0x1edc, 0x1edf, 0x1ede,
+ 0x1ee1, 0x1ee0, 0x1ee3, 0x1ee2, 0x1ee5, 0x1ee4, 0x1ee7, 0x1ee6,
+ 0x1ee9, 0x1ee8, 0x1eeb, 0x1eea, 0x1eed, 0x1eec, 0x1eef, 0x1eee,
+ 0x1ef1, 0x1ef0, 0x1ef3, 0x1ef2, 0x1ef5, 0x1ef4, 0x1ef7, 0x1ef6,
+ 0x1ef9, 0x1ef8, 0, 0, 0, 0, 0, 0,
+
+ 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f,
+ 0x1f00, 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07,
+ 0x1f18, 0x1f19, 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0, 0,
+ 0x1f10, 0x1f11, 0x1f12, 0x1f13, 0x1f14, 0x1f15, 0, 0,
+ 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f,
+ 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 0x1f25, 0x1f26, 0x1f27,
+ 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, 0x1f3e, 0x1f3f,
+ 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 0x1f37,
+ 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0, 0,
+ 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0, 0,
+ 0, 0x1f59, 0, 0x1f5b, 0, 0x1f5d, 0, 0x1f5f,
+ 0, 0x1f51, 0, 0x1f53, 0, 0x1f55, 0, 0x1f57,
+ 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f,
+ 0x1f60, 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67,
+ 0x1fba, 0x1fbb, 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb,
+ 0x1ff8, 0x1ff9, 0x1fea, 0x1feb, 0x1ffa, 0x1ffb, 0, 0,
+ 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f,
+ 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87,
+ 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f,
+ 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97,
+ 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf,
+ 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7,
+ 0x1fb8, 0x1fb9, 0, 0x1fbc, 0, 0, 0, 0,
+ 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 0x1fb3, 0, 0x399, 0,
+ 0, 0, 0, 0x1fcc, 0, 0, 0, 0,
+ 0x1f72, 0x1f73, 0x1f74, 0x1f75, 0x1fc3, 0, 0, 0,
+ 0x1fd8, 0x1fd9, 0, 0, 0, 0, 0, 0,
+ 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 0, 0, 0, 0,
+ 0x1fe8, 0x1fe9, 0, 0, 0, 0x1fec, 0, 0,
+ 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 0x1fe5, 0, 0, 0,
+ 0, 0, 0, 0x1ffc, 0, 0, 0, 0,
+ 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 0x1ff3, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0x3c9, 0,
+ 0, 0, 0x6b, 0xe5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177,
+ 0x2178, 0x2179, 0x217a, 0x217b, 0x217c, 0x217d, 0x217e, 0x217f,
+ 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167,
+ 0x2168, 0x2169, 0x216a, 0x216b, 0x216c, 0x216d, 0x216e, 0x216f,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0x24d0, 0x24d1,
+ 0x24d2, 0x24d3, 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9,
+ 0x24da, 0x24db, 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1,
+ 0x24e2, 0x24e3, 0x24e4, 0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9,
+ 0x24b6, 0x24b7, 0x24b8, 0x24b9, 0x24ba, 0x24bb, 0x24bc, 0x24bd,
+ 0x24be, 0x24bf, 0x24c0, 0x24c1, 0x24c2, 0x24c3, 0x24c4, 0x24c5,
+ 0x24c6, 0x24c7, 0x24c8, 0x24c9, 0x24ca, 0x24cb, 0x24cc, 0x24cd,
+ 0x24ce, 0x24cf, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47,
+ 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f,
+ 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57,
+ 0xff58, 0xff59, 0xff5a, 0, 0, 0, 0, 0,
+ 0, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27,
+ 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f,
+ 0xff30, 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37,
+ 0xff38, 0xff39, 0xff3a, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+// 36602 bytes
+
+const TQ_INT8 TQUnicodeTables::decimal_info[] = {
+ 1, 0, 0, 0, 0, 0, 2, 0,
+ 0, 3, 3, 4, 3, 5, 6, 7,
+ 8, 0, 0, 9, 0, 0, 0, 10,
+ 11, 0, 0, 0, 0, 0, 0, 0,
+ 12, 0, 0, 0, 13, 0, 0, 14,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 11,
+
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 2, 3, -1, -1, -1, -1,
+ -1, 1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 0, -1, -1, -1, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 0, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 1, 2, 3,
+ 4, 5, 6, 7, 8, 9, -1, -1,
+
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, 1, 2,
+ 3, 4, 5, 6, 7, 8, 9, -1,
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, -1, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1,
+};
+// 40698 bytes
+
+#endif
+
+#ifdef TQT_NO_UNICODETABLES
+
+const TQ_UINT8 TQUnicodeTables::latin1_line_break_info[] = {
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 15, 23, 19, 21, 22, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 26, 5, 2, 11, 8, 9, 11, 2,
+ 0, 1, 11, 8, 7, 14, 7, 6,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 7, 7, 11, 11, 11, 5,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 0, 8, 1, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 0, 15, 1, 11, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 3, 11, 9, 8, 8, 8, 11, 11,
+ 11, 11, 11, 2, 11, 15, 11, 11,
+ 9, 8, 11, 11, 16, 11, 11, 11,
+ 11, 11, 11, 2, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+};
+
+#else
+
+const TQ_UINT8 TQUnicodeTables::line_break_info[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8,
+ 2, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 2, 18, 2, 2, 19, 20,
+ 21, 2, 2, 2, 2, 2, 2, 2,
+ 22, 23, 24, 25, 2, 2, 2, 26,
+ 2, 27, 2, 2, 2, 2, 28, 29,
+ 30, 31, 32, 33, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 35, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 36,
+ 34, 34, 34, 34, 37, 2, 2, 2,
+ 2, 2, 2, 2, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 34,
+ 34, 34, 34, 34, 34, 34, 34, 38,
+ 39, 39, 39, 39, 39, 39, 39, 39,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 34, 40, 41, 2, 42, 43, 44,
+
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 15, 23, 19, 21, 22, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 26, 5, 2, 11, 8, 9, 11, 2,
+ 0, 1, 11, 8, 7, 14, 7, 6,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 7, 7, 11, 11, 11, 5,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 0, 8, 1, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 0, 15, 1, 11, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 3, 11, 9, 8, 8, 8, 11, 11,
+ 11, 11, 11, 2, 11, 15, 11, 11,
+ 9, 8, 11, 11, 16, 11, 11, 11,
+ 11, 11, 11, 2, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 16, 11, 11, 11, 16, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 19, 19, 19, 19, 11,
+ 19, 19, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 7, 15, 11, 11, 11, 11, 11,
+ 11, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 11, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 11, 19, 19, 19, 11, 19,
+ 11, 19, 19, 11, 19, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 11, 11, 11, 11, 11, 11,
+ 19, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 11, 11, 19,
+ 19, 11, 19, 19, 19, 19, 11, 11,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 19,
+ 11, 19, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 19, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 19, 11, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 11, 11,
+ 11, 19, 19, 19, 19, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 19, 11, 11, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 19, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 19, 11, 19, 19,
+ 19, 19, 19, 19, 19, 11, 11, 19,
+ 19, 11, 11, 19, 19, 19, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 19, 11, 11, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 8, 8, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 19, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 19, 11, 19, 19,
+ 19, 19, 19, 11, 11, 11, 11, 19,
+ 19, 11, 11, 19, 19, 19, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 19, 19, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 19, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 19, 11, 19, 19,
+ 19, 19, 19, 19, 19, 19, 11, 19,
+ 19, 19, 11, 19, 19, 19, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 19, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 19, 11, 19, 19,
+ 19, 19, 19, 19, 11, 11, 11, 19,
+ 19, 11, 11, 19, 19, 19, 11, 11,
+ 11, 11, 11, 11, 11, 11, 19, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 19, 19,
+ 19, 19, 19, 11, 11, 11, 19, 19,
+ 19, 11, 19, 19, 19, 19, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 19, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 19, 19,
+ 19, 19, 19, 19, 19, 11, 19, 19,
+ 19, 11, 19, 19, 19, 19, 11, 11,
+ 11, 11, 11, 11, 11, 19, 19, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 19, 19,
+ 19, 19, 19, 19, 19, 11, 19, 19,
+ 19, 11, 19, 19, 19, 19, 11, 11,
+ 11, 11, 11, 11, 11, 19, 19, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 19, 19,
+ 19, 19, 19, 19, 11, 11, 19, 19,
+ 19, 11, 19, 19, 19, 19, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 11, 11, 11, 11, 19,
+ 19, 19, 19, 19, 19, 11, 19, 11,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 19, 20, 20, 19, 19, 19, 19,
+ 19, 19, 19, 11, 11, 11, 11, 8,
+ 20, 20, 20, 20, 20, 20, 20, 19,
+ 19, 19, 19, 19, 19, 19, 19, 11,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 4, 4, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 20, 20, 11, 20, 11, 11, 20,
+ 20, 11, 20, 11, 11, 20, 11, 11,
+ 11, 11, 11, 11, 20, 20, 20, 20,
+ 11, 20, 20, 20, 20, 20, 20, 20,
+ 11, 20, 20, 20, 11, 20, 11, 20,
+ 11, 11, 20, 20, 11, 20, 20, 20,
+ 20, 19, 20, 20, 19, 19, 19, 19,
+ 19, 19, 11, 19, 19, 20, 11, 11,
+ 20, 20, 20, 20, 20, 11, 20, 11,
+ 19, 19, 19, 19, 19, 19, 11, 11,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 11, 11, 20, 20, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 15, 3, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 19, 19, 11, 11, 11, 11, 11, 11,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 19, 11, 19,
+ 11, 19, 0, 1, 0, 1, 19, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 11, 19, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 11, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 19, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 11, 20, 20, 20, 20, 20,
+ 11, 20, 20, 11, 19, 19, 19, 19,
+ 19, 19, 19, 11, 11, 11, 19, 19,
+ 19, 19, 11, 11, 11, 11, 11, 11,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 11, 11, 11, 11, 11, 11,
+ 20, 20, 20, 20, 20, 20, 19, 19,
+ 19, 19, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 11, 11, 11, 11, 11, 12,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 11, 11, 11, 11, 11,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 15, 11, 11, 11, 11, 11, 11,
+ 11, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 15, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 0, 1, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 19, 19, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 19, 19, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20,
+ 20, 20, 20, 20, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 4, 15, 4, 4,
+ 4, 4, 4, 8, 11, 11, 11, 11,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 16, 11,
+ 11, 11, 11, 19, 19, 19, 19, 11,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 19, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 15, 15, 15, 15, 15, 15, 15, 3,
+ 15, 15, 15, 18, 19, 19, 19, 19,
+ 15, 3, 15, 15, 17, 11, 11, 11,
+ 2, 2, 0, 2, 2, 2, 0, 2,
+ 11, 11, 11, 11, 13, 13, 13, 15,
+ 21, 21, 19, 19, 19, 19, 19, 3,
+ 9, 9, 9, 9, 9, 9, 9, 9,
+ 11, 2, 2, 11, 4, 11, 11, 11,
+ 11, 11, 11, 11, 4, 0, 1, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 15,
+ 3, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 19, 19, 19, 19, 19, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 0, 1, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 0, 1, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 8, 8, 8, 8, 8, 8, 8, 9,
+ 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 9, 11, 11, 11, 11,
+ 11, 9, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 8, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 9, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 8, 8, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 0, 1, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 0, 1, 2, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 2, 2, 2, 2, 11,
+ 11, 11, 5, 5, 11, 11, 11, 11,
+ 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 0, 1,
+ 0, 1, 0, 1, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 0, 1, 0, 1, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 0, 1, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 11, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 11, 11, 11, 11,
+
+ 12, 1, 1, 12, 12, 4, 12, 12,
+ 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 12, 12, 0, 1, 0, 1,
+ 0, 1, 0, 1, 4, 0, 1, 1,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 19, 19, 19, 19, 19, 19,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 4, 4, 12, 12, 12,
+ 11, 4, 12, 4, 12, 4, 12, 4,
+ 12, 4, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 4, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 4, 12, 4, 12, 4,
+ 12, 12, 12, 12, 12, 12, 4, 12,
+ 12, 12, 12, 12, 12, 4, 4, 11,
+ 11, 19, 19, 4, 4, 4, 4, 12,
+ 4, 4, 12, 4, 12, 4, 12, 4,
+ 12, 4, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 4, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 4, 12, 4, 12, 4,
+ 12, 12, 12, 12, 12, 12, 4, 12,
+ 12, 12, 12, 12, 12, 4, 4, 12,
+ 12, 12, 12, 4, 4, 4, 12, 12,
+
+ 11, 11, 11, 11, 11, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 11, 11, 11,
+ 11, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 11, 11, 11, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 11,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 11,
+ 11, 11, 11, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 11,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 11, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 11, 11,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 19, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 0, 1,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 9, 11, 11, 11,
+
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 19, 19, 19, 19, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 12, 12, 12, 12, 12, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 12, 12, 11,
+ 11, 12, 12, 12, 12, 12, 12, 12,
+ 1, 12, 1, 11, 4, 4, 5, 5,
+ 12, 0, 1, 0, 1, 0, 1, 12,
+ 12, 12, 12, 12, 12, 12, 12, 11,
+ 12, 8, 9, 12, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 3,
+
+ 11, 5, 12, 12, 8, 9, 12, 12,
+ 0, 1, 12, 12, 1, 12, 1, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 4, 4, 12, 12, 12, 5,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 0, 12, 1, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 0, 12, 1, 12, 0,
+ 1, 1, 0, 1, 1, 4, 11, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 4, 4,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 9, 8, 12, 12, 12, 8, 8, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 19, 19, 19, 25, 11, 11, 11,
+};
+// 52474 bytes
+
+// END OF GENERATED DATA
+#endif
+
+
+
+#ifndef TQT_NO_UNICODETABLES
+const TQ_UINT16 TQUnicodeTables::symmetricPairs[] = {
+ 0x0028, 0x0029, 0x003C, 0x003E, 0x005B, 0x005D, 0x007B, 0x007D,
+ 0x00AB, 0x00BB, 0x2039, 0x203A, 0x2045, 0x2046, 0x207D, 0x207E,
+ 0x208D, 0x208E, 0x2208, 0x220B, 0x2209, 0x220C, 0x220A, 0x220D,
+ 0x2215, 0x29F5, 0x223C, 0x223D, 0x2243, 0x22CD, 0x2252, 0x2253,
+ 0x2254, 0x2255, 0x2264, 0x2265, 0x2266, 0x2267, 0x2268, 0x2269,
+ 0x226A, 0x226B, 0x226E, 0x226F, 0x2270, 0x2271, 0x2272, 0x2273,
+ 0x2274, 0x2275, 0x2276, 0x2277, 0x2278, 0x2279, 0x227A, 0x227B,
+ 0x227C, 0x227D, 0x227E, 0x227F, 0x2280, 0x2281, 0x2282, 0x2283,
+ 0x2284, 0x2285, 0x2286, 0x2287, 0x2288, 0x2289, 0x228A, 0x228B,
+ 0x228F, 0x2290, 0x2291, 0x2292, 0x2298, 0x29B8, 0x22A2, 0x22A3,
+ 0x22A6, 0x2ADE, 0x22A8, 0x2AE4, 0x22A9, 0x2AE3, 0x22AB, 0x2AE5,
+ 0x22B0, 0x22B1, 0x22B2, 0x22B3, 0x22B4, 0x22B5, 0x22B6, 0x22B7,
+ 0x22C9, 0x22CA, 0x22CB, 0x22CC, 0x22D0, 0x22D1, 0x22D6, 0x22D7,
+ 0x22D8, 0x22D9, 0x22DA, 0x22DB, 0x22DC, 0x22DD, 0x22DE, 0x22DF,
+ 0x22E0, 0x22E1, 0x22E2, 0x22E3, 0x22E4, 0x22E5, 0x22E6, 0x22E7,
+ 0x22E8, 0x22E9, 0x22EA, 0x22EB, 0x22EC, 0x22ED, 0x22F0, 0x22F1,
+ 0x22F2, 0x22FA, 0x22F3, 0x22FB, 0x22F4, 0x22FC, 0x22F6, 0x22FD,
+ 0x22F7, 0x22FE, 0x2308, 0x2309, 0x230A, 0x230B, 0x2329, 0x232A,
+ 0x2768, 0x2769, 0x276A, 0x276B, 0x276C, 0x276D, 0x276E, 0x276F,
+ 0x2770, 0x2771, 0x2772, 0x2773, 0x2774, 0x2775, 0x27D5, 0x27D6,
+ 0x27DD, 0x27DE, 0x27E2, 0x27E3, 0x27E4, 0x27E5, 0x27E6, 0x27E7,
+ 0x27E8, 0x27E9, 0x27EA, 0x27EB, 0x2983, 0x2984, 0x2985, 0x2986,
+ 0x2987, 0x2988, 0x2989, 0x298A, 0x298B, 0x298C, 0x298D, 0x2990,
+ 0x298E, 0x298F, 0x2991, 0x2992, 0x2993, 0x2994, 0x2995, 0x2996,
+ 0x2997, 0x2998, 0x29C0, 0x29C1, 0x29C4, 0x29C5, 0x29CF, 0x29D0,
+ 0x29D1, 0x29D2, 0x29D4, 0x29D5, 0x29D8, 0x29D9, 0x29DA, 0x29DB,
+ 0x29F8, 0x29F9, 0x29FC, 0x29FD, 0x2A2B, 0x2A2C, 0x2A34, 0x2A35,
+ 0x2A3C, 0x2A3D, 0x2A64, 0x2A65, 0x2A79, 0x2A7A, 0x2A7D, 0x2A7E,
+ 0x2A7F, 0x2A80, 0x2A81, 0x2A82, 0x2A83, 0x2A84, 0x2A8B, 0x2A8C,
+ 0x2A91, 0x2A92, 0x2A93, 0x2A94, 0x2A95, 0x2A96, 0x2A97, 0x2A98,
+ 0x2A99, 0x2A9A, 0x2A9B, 0x2A9C, 0x2AA1, 0x2AA2, 0x2AA6, 0x2AA7,
+ 0x2AA8, 0x2AA9, 0x2AAA, 0x2AAB, 0x2AAC, 0x2AAD, 0x2AAF, 0x2AB0,
+ 0x2AB3, 0x2AB4, 0x2ABB, 0x2ABC, 0x2ABD, 0x2ABE, 0x2ABF, 0x2AC0,
+ 0x2AC1, 0x2AC2, 0x2AC3, 0x2AC4, 0x2AC5, 0x2AC6, 0x2ACD, 0x2ACE,
+ 0x2ACF, 0x2AD0, 0x2AD1, 0x2AD2, 0x2AD3, 0x2AD4, 0x2AD5, 0x2AD6,
+ 0x2AEC, 0x2AED, 0x2AF7, 0x2AF8, 0x2AF9, 0x2AFA, 0x3008, 0x3009,
+ 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, 0x3010, 0x3011,
+ 0x3014, 0x3015, 0x3016, 0x3017, 0x3018, 0x3019, 0x301A, 0x301B,
+ 0xFF08, 0xFF09, 0xFF1C, 0xFF1E, 0xFF3B, 0xFF3D, 0xFF5B, 0xFF5D,
+ 0xFF5F, 0xFF60, 0xFF62, 0xFF63,
+};
+
+// ### shouldn't this be const?
+const int TQUnicodeTables::symmetricPairsSize =
+ sizeof(symmetricPairs)/sizeof(symmetricPairs[0]);
+
+#else
+
+/*
+ only include info for the first tqunicode range (latin1) when building
+ without tqunicode tables.
+*/
+const TQ_UINT8 TQUnicodeTables::tqunicode_info[] = {
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 7, 26, 26, 26, 28, 26, 26, 26,
+ 22, 23, 26, 27, 26, 21, 26, 26,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 26, 26, 27, 27, 27, 26,
+ 26, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 22, 26, 23, 29, 20,
+ 29, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 22, 27, 23, 27, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10,
+ 7, 26, 28, 28, 28, 28, 30, 30,
+ 29, 30, 16, 24, 27, 21, 30, 29,
+ 30, 27, 6, 6, 29, 16, 30, 26,
+ 29, 6, 16, 25, 6, 6, 6, 26,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 27,
+ 15, 15, 15, 15, 15, 15, 15, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 27,
+ 16, 16, 16, 16, 16, 16, 16, 16
+};
+
+#endif
+
+/*
+ * ----------------------------------------------------------------------
+ * End of tqunicode tables
+ * ----------------------------------------------------------------------
+ */
+
+enum Script {
+ // European Alphabetic Scripts
+ Latin,
+ Greek,
+ Cyrillic,
+ Armenian,
+ Georgian,
+ Runic,
+ Ogham,
+ SpacingModifiers,
+ CombiningMarks,
+
+ // Middle Eastern Scripts
+ Hebrew,
+ Arabic,
+ Syriac,
+ Thaana,
+
+ // South and Southeast Asian Scripts
+ Devanagari,
+ Bengali,
+ Gurmukhi,
+ Gujarati,
+ Oriya,
+ Tamil,
+ Telugu,
+ Kannada,
+ Malayalam,
+ Sinhala,
+ Thai,
+ Lao,
+ Tibetan,
+ Myanmar,
+ Khmer,
+
+ // East Asian Scripts
+ Han,
+ Hiragana,
+ Katakana,
+ Hangul,
+ Bopomofo,
+ Yi,
+
+ // Additional Scripts
+ Ethiopic,
+ Cherokee,
+ CanadianAboriginal,
+ Mongolian,
+
+ // Symbols
+ CurrencySymbols,
+ LetterlikeSymbols,
+ NumberForms,
+ MathematicalOperators,
+ TechnicalSymbols,
+ GeometricSymbols,
+ MiscellaneousSymbols,
+ EnclosedAndSquare,
+ Braille,
+
+ Unicode,
+
+ // some scripts added in Unicode 3.2
+ Tagalog,
+ Hanunoo,
+ Buhid,
+ Tagbanwa,
+
+ KatakanaHalfWidth, // from JIS X 0201
+
+ // from Unicode 4.0
+ Limbu,
+ TaiLe,
+
+ // End
+ NScripts,
+ UnknownScript = NScripts
+};
+
+// copied form tqfont.h, as we can't include it in tools. Do not modify without
+// changing the script enum in tqfont.h aswell.
+const unsigned char TQUnicodeTables::otherScripts [128] = {
+#define SCRIPTS_02 0
+ 0xaf, Latin, 0xff, SpacingModifiers, // row 0x02, index 0
+#define SCRIPTS_03 4
+ 0x6f, CombiningMarks, 0xff, Greek, // row 0x03, index 4
+#define SCRIPTS_05 8
+ 0x2f, Cyrillic, 0x8f, Armenian, 0xff, Hebrew, // row 0x05, index 8
+#define SCRIPTS_07 14
+ 0x4f, Syriac, 0x7f, Unicode, 0xbf, Thaana,
+ 0xff, Unicode, // row 0x07, index 14
+#define SCRIPTS_10 22
+ 0x9f, Myanmar, 0xff, Georgian, // row 0x10, index 20
+#define SCRIPTS_13 26
+ 0x7f, Ethiopic, 0x9f, Unicode, 0xff, Cherokee, // row 0x13, index 24
+#define SCRIPTS_16 32
+ 0x7f, CanadianAboriginal, 0x9f, Ogham,
+ 0xff, Runic, // row 0x16 index 30
+#define SCRIPTS_17 38
+ 0x1f, Tagalog, 0x3f, Hanunoo, 0x5f, Buhid,
+ 0x7f, Tagbanwa, 0xff, Khmer, // row 0x17, index 36
+#define SCRIPTS_18 48
+ 0xaf, Mongolian, 0xff, Unicode, // row 0x18, index 46
+#define SCRIPTS_19 52
+ 0x4f, Limbu, 0x7f, TaiLe, 0xdf, Unicode, 0xff, Khmer,
+#define SCRIPTS_20 60
+ 0x0a, Unicode, 0x0d, UnknownScript, 0x6f, Unicode, 0x9f, NumberForms,
+ 0xab, CurrencySymbols, 0xac, Latin,
+ 0xcf, CurrencySymbols, 0xff, CombiningMarks, // row 0x20, index 50
+#define SCRIPTS_21 76
+ 0x4f, LetterlikeSymbols, 0x8f, NumberForms,
+ 0xff, MathematicalOperators, // row 0x21, index 62
+#define SCRIPTS_24 82
+ 0x5f, TechnicalSymbols, 0xff, EnclosedAndSquare, // row 0x24, index 68
+#define SCRIPTS_2e 86
+ 0x7f, Unicode, 0xff, Han, // row 0x2e, index 72
+#define SCRIPTS_30 90
+ 0x3f, Han, 0x9f, Hiragana, 0xff, Katakana, // row 0x30, index 76
+#define SCRIPTS_31 96
+ 0x2f, Bopomofo, 0x8f, Hangul, 0x9f, Han,
+ 0xff, Unicode, // row 0x31, index 82
+#define SCRIPTS_fb 104
+ 0x06, Latin, 0x1c, Unicode, 0x4f, Hebrew,
+ 0xff, Arabic, // row 0xfb, index 90
+#define SCRIPTS_fe 112
+ 0x1f, Unicode, 0x2f, CombiningMarks, 0x6f, Han,
+ 0xff, Arabic, // row 0xfe, index 98
+#define SCRIPTS_ff 120
+ 0x60, Han, // row 0xff, index 106
+ 0x9f, KatakanaHalfWidth, 0xef, Han, 0xff, Unicode
+};
+
+// (uc-0x0900)>>7
+const unsigned char TQUnicodeTables::indicScripts [] =
+{
+ Devanagari, Bengali,
+ Gurmukhi, Gujarati,
+ Oriya, Tamil,
+ Telugu, Kannada,
+ Malayalam, Sinhala,
+ Thai, Lao
+};
+
+
+// 0x80 + x: x is the offset into the otherScripts table
+const unsigned char TQUnicodeTables::scriptTable[256] =
+{
+ Latin, Latin, 0x80+SCRIPTS_02, 0x80+SCRIPTS_03,
+ Cyrillic, 0x80+SCRIPTS_05, Arabic, 0x80+SCRIPTS_07,
+ Unicode, SCRIPTS_INDIC, SCRIPTS_INDIC, SCRIPTS_INDIC,
+ SCRIPTS_INDIC, SCRIPTS_INDIC, SCRIPTS_INDIC, Tibetan,
+
+ 0x80+SCRIPTS_10, Hangul, Ethiopic, 0x80+SCRIPTS_13,
+ CanadianAboriginal, CanadianAboriginal, 0x80+SCRIPTS_16, 0x80+SCRIPTS_17,
+ 0x80+SCRIPTS_18, 0x80+SCRIPTS_19, Unicode, Unicode,
+ Unicode, Unicode, Latin, Greek,
+
+ 0x80+SCRIPTS_20, 0x80+SCRIPTS_21, MathematicalOperators, TechnicalSymbols,
+ 0x80+SCRIPTS_24, GeometricSymbols, MiscellaneousSymbols, MiscellaneousSymbols,
+ Braille, Unicode, Unicode, Unicode,
+ Unicode, Unicode, 0x80+SCRIPTS_2e, Han,
+
+ 0x80+SCRIPTS_30, 0x80+SCRIPTS_31, EnclosedAndSquare, EnclosedAndSquare,
+ Han, Han, Han, Han,
+ Han, Han, Han, Han,
+ Han, Han, Han, Han,
+
+ Han, Han, Han, Han, Han, Han, Han, Han,
+ Han, Han, Han, Han, Han, Han, Han, Han,
+
+ Han, Han, Han, Han, Han, Han, Han, Han,
+ Han, Han, Han, Han, Han, Han, Han, Han,
+
+ Han, Han, Han, Han, Han, Han, Han, Han,
+ Han, Han, Han, Han, Han, Han, Han, Han,
+
+ Han, Han, Han, Han, Han, Han, Han, Han,
+ Han, Han, Han, Han, Han, Han, Han, Han,
+
+
+ Han, Han, Han, Han, Han, Han, Han, Han,
+ Han, Han, Han, Han, Han, Han, Han, Han,
+
+ Han, Han, Han, Han, Han, Han, Han, Han,
+ Han, Han, Han, Han, Han, Han, Han, Han,
+
+ Yi, Yi, Yi, Yi, Yi, Unicode, Unicode, Unicode,
+ Unicode, Unicode, Unicode, Unicode, Hangul, Hangul, Hangul, Hangul,
+
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+
+ Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul, Hangul,
+ Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode,
+
+ Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode,
+ Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode,
+
+ Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode, Unicode,
+ Unicode, Han, Han, 0x80+SCRIPTS_fb, Arabic, Arabic, 0x80+SCRIPTS_fe, 0x80+SCRIPTS_ff
+};
+
diff --git a/tqtinterface/qt4/src/tools/tqunicodetables_p.h b/tqtinterface/qt4/src/tools/tqunicodetables_p.h
new file mode 100644
index 0000000..4afa5d1
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqunicodetables_p.h
@@ -0,0 +1,266 @@
+/****************************************************************************
+**
+** ???
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQUNICODETABLES_P_H
+#define TQUNICODETABLES_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of internal files. This header file may change from version to version
+// without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifdef TQT_NO_UNICODETABLES
+# include <ctype.h>
+#endif
+
+class TQUnicodeTables {
+public:
+ static const TQ_UINT8 tqunicode_info[];
+#ifndef TQT_NO_UNICODETABLES
+ static const TQ_UINT16 decomposition_map[];
+ static const TQ_UINT16 decomposition_info[];
+ static const TQ_UINT16 ligature_map[];
+ static const TQ_UINT16 ligature_info[];
+ static const TQ_UINT8 direction_info[];
+ static const TQ_UINT8 combining_info[];
+ static const TQ_UINT16 case_info[];
+ static const TQ_INT8 decimal_info[];
+ static const TQ_UINT16 symmetricPairs[];
+ static const int symmetricPairsSize;
+ static const TQ_UINT8 line_break_info[];
+#else
+ static const TQ_UINT8 latin1_line_break_info[];
+#endif
+ static const unsigned char otherScripts[];
+ static const unsigned char indicScripts[];
+ static const unsigned char scriptTable[];
+ enum { SCRIPTS_INDIC = 0x7e };
+
+ // see http://www.tqunicode.org/reports/tr14/tr14-13.html
+ // we don't use the XX and AI properties and map them to AL instead.
+ enum LineBreakClass {
+ LineBreak_OP, LineBreak_CL, LineBreak_QU, LineBreak_GL, LineBreak_NS,
+ LineBreak_EX, LineBreak_SY, LineBreak_IS, LineBreak_PR, LineBreak_PO,
+ LineBreak_NU, LineBreak_AL, LineBreak_ID, LineBreak_IN, LineBreak_HY,
+ LineBreak_BA, LineBreak_BB, LineBreak_B2, LineBreak_ZW, LineBreak_CM,
+ LineBreak_SA, LineBreak_BK, LineBreak_CR, LineBreak_LF, LineBreak_SG,
+ LineBreak_CB, LineBreak_SP
+ };
+};
+
+
+inline TQChar::Category category( const TQChar &c )
+{
+#ifdef TQT_NO_UNICODETABLES
+ if ( c.tqunicode() > 0xff ) return TQChar::Letter_Uppercase; //########
+ return (TQChar::Category)TQUnicodeTables::tqunicode_info[c.tqunicode()];
+#else
+ register int uc = ((int)TQUnicodeTables::tqunicode_info[c.row()]) << 8;
+ uc += c.cell();
+ return (TQChar::Category)TQUnicodeTables::tqunicode_info[uc];
+#endif // TQT_NO_UNICODETABLES
+}
+
+inline TQChar lower( const TQChar &c )
+{
+#ifndef TQT_NO_UNICODETABLES
+ int row = c.row();
+ int cell = c.cell();
+ register int ci = TQUnicodeTables::case_info[row];
+ register int uc = ((int)TQUnicodeTables::tqunicode_info[c.row()]) << 8;
+ uc += c.cell();
+ if (TQUnicodeTables::tqunicode_info[uc] != TQChar::Letter_Uppercase || !ci)
+ return c;
+ TQ_UINT16 lower = TQUnicodeTables::case_info[(ci<<8)+cell];
+ return lower ? TQChar(lower) : c;
+#else
+ if ( c.row() )
+ return c;
+ return TQChar( tolower((uchar) c.latin1()) );
+#endif
+}
+
+inline TQChar upper( const TQChar &c )
+{
+#ifndef TQT_NO_UNICODETABLES
+ int row = c.row();
+ int cell = c.cell();
+ register int ci = TQUnicodeTables::case_info[row];
+ register int uc = ((int)TQUnicodeTables::tqunicode_info[c.row()]) << 8;
+ uc += c.cell();
+ if (TQUnicodeTables::tqunicode_info[uc] != TQChar::Letter_Lowercase || !ci)
+ return c;
+ TQ_UINT16 upper = TQUnicodeTables::case_info[(ci<<8)+cell];
+ return upper ? TQChar(upper) : c;
+#else
+ if ( c.row() )
+ return c;
+ return TQChar( toupper((uchar) c.latin1()) );
+#endif
+}
+
+inline TQChar::Direction direction( const TQChar &c )
+{
+#ifndef TQT_NO_UNICODETABLES
+ register int pos = TQUnicodeTables::direction_info[c.row()];
+ return (TQChar::Direction) (TQUnicodeTables::direction_info[(pos<<8)+c.cell()] & 0x1f);
+#else
+ TQ_UNUSED(c);
+ return TQChar::DirL;
+#endif
+}
+
+inline bool mirrored( const TQChar &c )
+{
+#ifndef TQT_NO_UNICODETABLES
+ register int pos = TQUnicodeTables::direction_info[c.row()];
+ return TQUnicodeTables::direction_info[(pos<<8)+c.cell()] > 128;
+#else
+ TQ_UNUSED(c);
+ return FALSE;
+#endif
+}
+
+
+inline TQChar mirroredChar( const TQChar &ch )
+{
+#ifndef TQT_NO_UNICODETABLES
+ if(!::mirrored( ch ))
+ return ch;
+
+ int i;
+ int c = ch.tqunicode();
+ for (i = 0; i < TQUnicodeTables::symmetricPairsSize; i ++) {
+ if (TQUnicodeTables::symmetricPairs[i] == c)
+ return TQUnicodeTables::symmetricPairs[(i%2) ? (i-1) : (i+1)];
+ }
+#endif
+ return ch;
+}
+
+inline TQChar::Joining joining( const TQChar &ch )
+{
+#ifndef TQT_NO_UNICODETABLES
+ register int pos = TQUnicodeTables::direction_info[ch.row()];
+ return (TQChar::Joining) ((TQUnicodeTables::direction_info[(pos<<8)+ch.cell()] >> 5) &0x3);
+#else
+ TQ_UNUSED(ch);
+ return TQChar::OtherJoining;
+#endif
+}
+
+inline bool isMark( const TQChar &ch )
+{
+ TQChar::Category c = ::category( ch );
+ return c >= TQChar::Mark_NonSpacing && c <= TQChar::Mark_Enclosing;
+}
+
+inline unsigned char combiningClass( const TQChar &ch )
+{
+#ifndef TQT_NO_UNICODETABLES
+ const int pos = TQUnicodeTables::combining_info[ch.row()];
+ return TQUnicodeTables::combining_info[(pos<<8) + ch.cell()];
+#else
+ TQ_UNUSED(ch);
+ return 0;
+#endif
+}
+
+inline bool isSpace( const TQChar &ch )
+{
+ if( ch.tqunicode() >= 9 && ch.tqunicode() <=13 ) return TRUE;
+ TQChar::Category c = ::category( ch );
+ return c >= TQChar::Separator_Space && c <= TQChar::Separator_Paragraph;
+}
+
+inline int lineBreakClass( const TQChar &ch )
+{
+#ifdef TQT_NO_UNICODETABLES
+ return ch.row() ? TQUnicodeTables::LineBreak_AL
+ : TQUnicodeTables::latin1_line_break_info[ch.cell()];
+#else
+ register int pos = ((int)TQUnicodeTables::line_break_info[ch.row()] << 8) + ch.cell();
+ return TQUnicodeTables::line_break_info[pos];
+#endif
+}
+
+inline int scriptForChar( ushort uc )
+{
+ unsigned char script = TQUnicodeTables::scriptTable[(uc>>8)];
+ if ( script >= TQUnicodeTables::SCRIPTS_INDIC ) {
+ if ( script == TQUnicodeTables::SCRIPTS_INDIC ) {
+ script = TQUnicodeTables::indicScripts[ (uc-0x0900)>>7 ];
+ } else {
+ // 0x80 + SCRIPTS_xx
+ unsigned char index = script-0x80;
+ unsigned char cell = uc &0xff;
+ while( TQUnicodeTables::otherScripts[index++] < cell )
+ index++;
+ script = TQUnicodeTables::otherScripts[index];
+ }
+ }
+ return script;
+}
+
+#ifdef TQ_WS_X11
+#define SCRIPT_FOR_CHAR( script, c ) \
+do { \
+ unsigned short _uc = (c).tqunicode(); \
+ if ( _uc < 0x100 ) { \
+ script = TQFont::Latin; \
+ } else { \
+ script = (TQFont::Script)scriptForChar( _uc ); \
+ } \
+} while( FALSE )
+#else
+#define SCRIPT_FOR_CHAR( script, c ) \
+ script = (TQFont::Script)scriptForChar( (c).tqunicode() )
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tquuid.cpp b/tqtinterface/qt4/src/tools/tquuid.cpp
new file mode 100644
index 0000000..65db5fa
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tquuid.cpp
@@ -0,0 +1,421 @@
+/****************************************************************************
+**
+** Implementation of TQUuid class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tquuid.h"
+
+#include "tqdatastream.h"
+
+/*!
+ \class TQUuid tquuid.h
+ \brief The TQUuid class defines a Universally Unique Identifier (UUID).
+
+ \reentrant
+
+ For objects or declarations that must be uniquely identified,
+ UUIDs (also known as GUIDs) are widely used in order to assign a
+ fixed and easy to compare value to the object or declaration. The
+ 128-bit value of a UUID is generated by an algorithm that
+ guarantees that the value is unique.
+
+ In TQt, UUIDs are wrapped by the TQUuid struct which provides
+ convenience functions for handling UUIDs. Most platforms provide a
+ tool to generate new UUIDs, for example, uuidgen and guidgen.
+
+ UUIDs generated by TQUuid, are based on the \c Random version of the
+ \c DCE (Distributed Computing Environment) standard.
+
+ UUIDs can be constructed from numeric values or from strings, or
+ using the static createUuid() function. They can be converted to a
+ string with toString(). UUIDs have a variant() and a version(),
+ and null UUIDs return TRUE from isNull().
+*/
+
+/*!
+ \fn TQUuid::TQUuid()
+
+ Creates the null UUID {00000000-0000-0000-0000-000000000000}.
+*/
+
+/*!
+ \fn TQUuid::TQUuid( uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8 )
+
+ Creates a UUID with the value specified by the parameters, \a l,
+ \a w1, \a w2, \a b1, \a b2, \a b3, \a b4, \a b5, \a b6, \a b7, \a
+ b8.
+
+ Example:
+ \code
+ // {67C8770B-44F1-410A-AB9A-F9B5446F13EE}
+ TQUuid IID_MyInterface( 0x67c8770b, 0x44f1, 0x410a, 0xab, 0x9a, 0xf9, 0xb5, 0x44, 0x6f, 0x13, 0xee )
+ \endcode
+*/
+
+/*!
+ \fn TQUuid::TQUuid( const TQUuid &orig )
+
+ Creates a copy of the TQUuid \a orig.
+*/
+#ifndef TQT_NO_TQUUID_STRING
+/*!
+ Creates a TQUuid object from the string \a text. The function can
+ only convert a string in the format
+ {HHHHHHHH-HHHH-HHHH-HHHH-HHHHHHHHHHHH} (where 'H' stands for a hex
+ digit). If the conversion fails a null UUID is created.
+*/
+TQUuid::TQUuid( const TQString &text )
+{
+ bool ok;
+ if ( text.isEmpty() ) {
+ *this = TQUuid();
+ return;
+ }
+ TQString temp = text.upper();
+ if ( temp[0] != '{' )
+ temp = "{" + text;
+ if ( text[(int)text.length()-1] != '}' )
+ temp += "}";
+
+ data1 = temp.mid( 1, 8 ).toULong( &ok, 16 );
+ if ( !ok ) {
+ *this = TQUuid();
+ return;
+ }
+
+ data2 = temp.mid( 10, 4 ).toUInt( &ok, 16 );
+ if ( !ok ) {
+ *this = TQUuid();
+ return;
+ }
+ data3 = temp.mid( 15, 4 ).toUInt( &ok, 16 );
+ if ( !ok ) {
+ *this = TQUuid();
+ return;
+ }
+ data4[0] = temp.mid( 20, 2 ).toUInt( &ok, 16 );
+ if ( !ok ) {
+ *this = TQUuid();
+ return;
+ }
+ data4[1] = temp.mid( 22, 2 ).toUInt( &ok, 16 );
+ if ( !ok ) {
+ *this = TQUuid();
+ return;
+ }
+ for ( int i = 2; i<8; i++ ) {
+ data4[i] = temp.mid( 25 + (i-2)*2, 2 ).toUShort( &ok, 16 );
+ if ( !ok ) {
+ *this = TQUuid();
+ return;
+ }
+ }
+}
+
+/*!
+ \internal
+*/
+TQUuid::TQUuid( const char *text )
+{
+ *this = TQUuid( TQString(text) );
+}
+#endif
+/*!
+ \fn TQUuid TQUuid::operator=(const TQUuid &uuid )
+
+ Assigns the value of \a uuid to this TQUuid object.
+*/
+
+/*!
+ \fn bool TQUuid::operator==(const TQUuid &other) const
+
+ Returns TRUE if this TQUuid and the \a other TQUuid are identical;
+ otherwise returns FALSE.
+*/
+
+/*!
+ \fn bool TQUuid::operator!=(const TQUuid &other) const
+
+ Returns TRUE if this TQUuid and the \a other TQUuid are different;
+ otherwise returns FALSE.
+*/
+#ifndef TQT_NO_TQUUID_STRING
+/*!
+ \fn TQUuid::operator TQString() const
+
+ Returns the string representation of the uuid.
+
+ \sa toString()
+*/
+
+/*!
+ TQString TQUuid::toString() const
+
+ Returns the string representation of the uuid.
+*/
+TQString TQUuid::toString() const
+{
+ TQString result;
+
+ result = "{" + TQT_TQSTRING(TQString::number( data1, 16 )).rightJustify( 8, '0' ) + "-";
+ result += TQT_TQSTRING(TQString::number( (int)data2, 16 )).rightJustify( 4, '0' ) + "-";
+ result += TQT_TQSTRING(TQString::number( (int)data3, 16 )).rightJustify( 4, '0' ) + "-";
+ result += TQT_TQSTRING(TQString::number( (int)data4[0], 16 )).rightJustify( 2, '0' );
+ result += TQT_TQSTRING(TQString::number( (int)data4[1], 16 )).rightJustify( 2, '0' ) + "-";
+ for ( int i = 2; i < 8; i++ )
+ result += TQT_TQSTRING(TQString::number( (int)data4[i], 16 )).rightJustify( 2, '0' );
+
+ return result + "}";
+}
+#endif
+
+#ifndef TQT_NO_DATASTREAM
+/*!
+ \relates TQUuid
+ Writes the uuid \a id to the datastream \a s.
+*/
+TQDataStream &operator<<( TQDataStream &s, const TQUuid &id )
+{
+ s << (TQ_UINT32)id.data1;
+ s << (TQ_UINT16)id.data2;
+ s << (TQ_UINT16)id.data3;
+ for (int i = 0; i < 8; i++ )
+ s << (TQ_UINT8)id.data4[i];
+ return s;
+}
+
+/*!
+ \relates TQUuid
+ Reads uuid from from the stream \a s into \a id.
+*/
+TQDataStream &operator>>( TQDataStream &s, TQUuid &id )
+{
+ TQ_UINT32 u32;
+ TQ_UINT16 u16;
+ TQ_UINT8 u8;
+ s >> u32;
+ id.data1 = u32;
+ s >> u16;
+ id.data2 = u16;
+ s >> u16;
+ id.data3 = u16;
+ for (int i = 0; i < 8; i++ ) {
+ s >> u8;
+ id.data4[i] = u8;
+ }
+ return s;
+}
+#endif
+
+/*!
+ Returns TRUE if this is the null UUID
+ {00000000-0000-0000-0000-000000000000}; otherwise returns FALSE.
+*/
+bool TQUuid::isNull() const
+{
+ return data4[0] == 0 && data4[1] == 0 && data4[2] == 0 && data4[3] == 0 &&
+ data4[4] == 0 && data4[5] == 0 && data4[6] == 0 && data4[7] == 0 &&
+ data1 == 0 && data2 == 0 && data3 == 0;
+}
+
+/*!
+ \enum TQUuid::Variant
+
+ This enum defines the variant of the UUID, which is the scheme
+ which defines the tqlayout of the 128-bits value.
+
+ \value VarUnknown Variant is unknown
+ \value NCS Reserved for NCS (Network Computing System) backward compatibility
+ \value DCE Distributed Computing Environment, the scheme used by TQUuid
+ \value Microsoft Reserved for Microsoft backward compatibility (GUID)
+ \value Reserved Reserved for future definition
+*/
+
+/*!
+ \enum TQUuid::Version
+
+ This enum defines the version of the UUID.
+
+ \value VerUnknown Version is unknown
+ \value Time Time-based, by using timestamp, clock sequence, and
+ MAC network card address (if available) for the node sections
+ \value EmbeddedPOSIX DCE Security version, with embedded POSIX UUIDs
+ \value Name Name-based, by using values from a name for all sections
+ \value Random Random-based, by using random numbers for all sections
+*/
+
+/*!
+ \fn TQUuid::Variant TQUuid::variant() const
+
+ Returns the variant of the UUID.
+ The null UUID is considered to be of an unknown variant.
+
+ \sa version()
+*/
+TQUuid::Variant TQUuid::variant() const
+{
+ if ( isNull() )
+ return VarUnknown;
+ // Check the 3 MSB of data4[0]
+ if ( (data4[0] & 0x80) == 0x00 ) return NCS;
+ else if ( (data4[0] & 0xC0) == 0x80 ) return DCE;
+ else if ( (data4[0] & 0xE0) == 0xC0 ) return Microsoft;
+ else if ( (data4[0] & 0xE0) == 0xE0 ) return Reserved;
+ return VarUnknown;
+}
+
+/*!
+ \fn TQUuid::Version TQUuid::version() const
+
+ Returns the version of the UUID, if the UUID is of the DCE
+ variant; otherwise returns VerUnknown.
+
+ \sa variant()
+*/
+TQUuid::Version TQUuid::version() const
+{
+ // Check the 4 MSB of data3
+ Version ver = (Version)(data3>>12);
+ if ( isNull()
+ || (variant() != DCE)
+ || ver < Time
+ || ver > Random )
+ return VerUnknown;
+ return ver;
+}
+
+/*!
+ \fn bool TQUuid::operator<(const TQUuid &other) const
+
+ Returns TRUE if this TQUuid is of the same variant,
+ and lexicographically before the \a other TQUuid;
+ otherwise returns FALSE.
+
+ \sa variant()
+*/
+#define ISLESS(f1, f2) if (f1!=f2) return (f1<f2);
+bool TQUuid::operator<(const TQUuid &other ) const
+{
+ if ( variant() != other.variant() )
+ return FALSE;
+
+ ISLESS( data1, other.data1 );
+ ISLESS( data2, other.data2 );
+ ISLESS( data3, other.data3 );
+ for ( int n = 0; n < 8; n++ ) {
+ ISLESS( data4[n], other.data4[n] );
+ }
+ return FALSE;
+}
+
+/*!
+ \fn bool TQUuid::operator>(const TQUuid &other) const
+
+ Returns TRUE if this TQUuid is of the same variant,
+ and lexicographically after the \a other TQUuid;
+ otherwise returns FALSE.
+
+ \sa variant()
+*/
+#define ISMORE(f1, f2) if (f1!=f2) return (f1>f2);
+bool TQUuid::operator>(const TQUuid &other ) const
+{
+ if ( variant() != other.variant() )
+ return FALSE;
+
+ ISMORE( data1, other.data1 );
+ ISMORE( data2, other.data2 );
+ ISMORE( data3, other.data3 );
+ for ( int n = 0; n < 8; n++ ) {
+ ISMORE( data4[n], other.data4[n] );
+ }
+ return FALSE;
+}
+
+/*!
+ \fn TQUuid TQUuid::createUuid()
+
+ Returns a new UUID of \c DCE variant, and \c Random type. The
+ UUIDs generated are based on the platform specific pseudo-random
+ generator, which is usually not a cryptographic-quality random
+ number generator. Therefore, a UUID is not guaranteed to be unique
+ cross application instances.
+
+ On Windows, the new UUID is extremely likely to be unique on the
+ same or any other system, networked or not.
+
+ \sa variant(), version()
+*/
+#if defined(TQ_OS_WIN32)
+#include <objbase.h> // For CoCreateGuid
+TQUuid TQUuid::createUuid()
+{
+ GUID guid;
+ CoCreateGuid( &guid );
+ TQUuid result = guid;
+ return result;
+}
+#else // !TQ_OS_WIN32
+#include "tqdatetime.h"
+#include "stdlib.h" // For srand/rand
+TQUuid TQUuid::createUuid()
+{
+ static const int intbits = sizeof(int)*8;
+ static int randbits = 0;
+ if ( !randbits ) {
+ int max = RAND_MAX;
+ do { ++randbits; } while ( (max=max>>1) );
+ srand( (uint)TQDateTime::tqcurrentDateTime().toTime_t() );
+ rand(); // Skip first
+ }
+
+ TQUuid result;
+ uint *data = &(result.data1);
+ int chunks = 16 / sizeof(uint);
+ while ( chunks-- ) {
+ uint randNumber = 0;
+ for ( int filled = 0; filled < intbits; filled += randbits )
+ randNumber |= rand()<<filled;
+ *(data+chunks) = randNumber;
+ }
+
+ result.data4[0] = (result.data4[0] & 0x3F) | 0x80; // UV_DCE
+ result.data3 = (result.data3 & 0x0FFF) | 0x4000; // UV_Random
+
+ return result;
+}
+#endif // !TQ_OS_WIN32
+
diff --git a/tqtinterface/qt4/src/tools/tquuid.h b/tqtinterface/qt4/src/tools/tquuid.h
new file mode 100644
index 0000000..7a2de25
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tquuid.h
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Definition of TQUuid class
+**
+** Created : 010523
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQUUID_H
+#define TQUUID_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#include <string.h>
+
+#if defined(TQ_OS_WIN32)
+#ifndef GUID_DEFINED
+#define GUID_DEFINED
+typedef struct _GUID
+{
+ ulong Data1;
+ ushort Data2;
+ ushort Data3;
+ uchar Data4[ 8 ];
+} GUID, *REFGUID, *LPGUID;
+#endif
+#endif
+
+
+struct TQ_EXPORT TQUuid
+{
+ enum Variant {
+ VarUnknown =-1,
+ NCS = 0, // 0 - -
+ DCE = 2, // 1 0 -
+ Microsoft = 6, // 1 1 0
+ Reserved = 7 // 1 1 1
+ };
+
+ enum Version {
+ VerUnknown =-1,
+ Time = 1, // 0 0 0 1
+ EmbeddedPOSIX = 2, // 0 0 1 0
+ Name = 3, // 0 0 1 1
+ Random = 4 // 0 1 0 0
+ };
+
+ TQUuid()
+ {
+ memset( this, 0, sizeof(TQUuid) );
+ }
+ TQUuid( uint l, ushort w1, ushort w2, uchar b1, uchar b2, uchar b3, uchar b4, uchar b5, uchar b6, uchar b7, uchar b8 )
+ {
+ data1 = l;
+ data2 = w1;
+ data3 = w2;
+ data4[0] = b1;
+ data4[1] = b2;
+ data4[2] = b3;
+ data4[3] = b4;
+ data4[4] = b5;
+ data4[5] = b6;
+ data4[6] = b7;
+ data4[7] = b8;
+ }
+ TQUuid( const TQUuid &uuid )
+ {
+ memcpy( this, &uuid, sizeof(TQUuid) );
+ }
+#ifndef TQT_NO_TQUUID_STRING
+ TQUuid( const TQString & );
+ TQUuid( const char * );
+ TQString toString() const;
+ operator TQString() const { return toString(); }
+#endif
+ bool isNull() const;
+
+ TQUuid &operator=(const TQUuid &orig )
+ {
+ memcpy( this, &orig, sizeof(TQUuid) );
+ return *this;
+ }
+
+ bool operator==(const TQUuid &orig ) const
+ {
+ uint i;
+ if ( data1 != orig.data1 || data2 != orig.data2 ||
+ data3 != orig.data3 )
+ return FALSE;
+
+ for( i = 0; i < 8; i++ )
+ if ( data4[i] != orig.data4[i] )
+ return FALSE;
+
+ return TRUE;
+ }
+
+ bool operator!=(const TQUuid &orig ) const
+ {
+ return !( *this == orig );
+ }
+
+ bool operator<(const TQUuid &other ) const;
+ bool operator>(const TQUuid &other ) const;
+
+#if defined(TQ_OS_WIN32)
+ // On Windows we have a type GUID that is used by the platform API, so we
+ // provide convenience operators to cast from and to this type.
+ TQUuid( const GUID &guid )
+ {
+ memcpy( this, &guid, sizeof(GUID) );
+ }
+
+ TQUuid &operator=(const GUID &orig )
+ {
+ memcpy( this, &orig, sizeof(TQUuid) );
+ return *this;
+ }
+
+ operator GUID() const
+ {
+ GUID guid = { data1, data2, data3, { data4[0], data4[1], data4[2], data4[3], data4[4], data4[5], data4[6], data4[7] } };
+ return guid;
+ }
+
+ bool operator==( const GUID &guid ) const
+ {
+ uint i;
+ if ( data1 != guid.Data1 || data2 != guid.Data2 ||
+ data3 != guid.Data3 )
+ return FALSE;
+
+ for( i = 0; i < 8; i++ )
+ if ( data4[i] != guid.Data4[i] )
+ return FALSE;
+
+ return TRUE;
+ }
+
+ bool operator!=( const GUID &guid ) const
+ {
+ return !( *this == guid );
+ }
+#endif
+ static TQUuid createUuid();
+ TQUuid::Variant variant() const;
+ TQUuid::Version version() const;
+
+ uint data1;
+ ushort data2;
+ ushort data3;
+ uchar data4[ 8 ];
+};
+
+#ifndef TQT_NO_DATASTREAM
+TQ_EXPORT TQDataStream &operator<<( TQDataStream &, const TQUuid & );
+TQ_EXPORT TQDataStream &operator>>( TQDataStream &, TQUuid & );
+#endif
+
+#endif //TQUUID_H
diff --git a/tqtinterface/qt4/src/tools/tqvaluelist.h b/tqtinterface/qt4/src/tools/tqvaluelist.h
new file mode 100644
index 0000000..67c2574
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqvaluelist.h
@@ -0,0 +1,671 @@
+/****************************************************************************
+**
+** Definition of TQValueList class
+**
+** Created : 990406
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQVALUELIST_H
+#define TQVALUELIST_H
+
+#ifndef TQT_H
+#include "tqtl.h"
+#include "tqshared.h"
+#include "tqdatastream.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_STL
+#include <iterator>
+#include <list>
+#endif
+
+//#define TQT_CHECK_VALUELIST_RANGE
+
+#if defined(TQ_CC_MSVC)
+#pragma warning(disable:4284) // "return type for operator -> is not a UDT"
+#endif
+
+template <class T>
+class TQValueListNode
+{
+public:
+ TQValueListNode( const T& t ) : data( t ) { }
+ TQValueListNode() { }
+#if defined(TQ_TEMPLATEDLL)
+ // Workaround MS bug in memory de/allocation in DLL vs. EXE
+ virtual ~TQValueListNode() { }
+#endif
+
+ TQValueListNode<T>* next;
+ TQValueListNode<T>* prev;
+ T data;
+};
+
+template<class T>
+class TQValueListIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef TQValueListNode<T>* NodePtr;
+#ifndef TQT_NO_STL
+ typedef std::bidirectional_iterator_tag iterator_category;
+#endif
+ typedef T value_type;
+ typedef size_t size_type;
+#ifndef TQT_NO_STL
+ typedef ptrdiff_t difference_type;
+#else
+ typedef int difference_type;
+#endif
+ typedef T* pointer;
+ typedef T& reference;
+
+ /**
+ * Variables
+ */
+ NodePtr node;
+
+ /**
+ * Functions
+ */
+ TQValueListIterator() : node( 0 ) {}
+ TQValueListIterator( NodePtr p ) : node( p ) {}
+ TQValueListIterator( const TQValueListIterator<T>& it ) : node( it.node ) {}
+
+ bool operator==( const TQValueListIterator<T>& it ) const { return node == it.node; }
+ bool operator!=( const TQValueListIterator<T>& it ) const { return node != it.node; }
+ const T& operator*() const { return node->data; }
+ T& operator*() { return node->data; }
+ // UDT for T = x*
+ // T* operator->() const { return &node->data; }
+
+ TQValueListIterator<T>& operator++() {
+ node = node->next;
+ return *this;
+ }
+
+ TQValueListIterator<T> operator++(int) {
+ TQValueListIterator<T> tmp = *this;
+ node = node->next;
+ return tmp;
+ }
+
+ TQValueListIterator<T>& operator--() {
+ node = node->prev;
+ return *this;
+ }
+
+ TQValueListIterator<T> operator--(int) {
+ TQValueListIterator<T> tmp = *this;
+ node = node->prev;
+ return tmp;
+ }
+
+ TQValueListIterator<T>& operator+=( int j ) {
+ while ( j-- )
+ node = node->next;
+ return *this;
+ }
+
+ TQValueListIterator<T>& operator-=( int j ) {
+ while ( j-- )
+ node = node->prev;
+ return *this;
+ }
+
+};
+
+template<class T>
+class TQValueListConstIterator
+{
+ public:
+ /**
+ * Typedefs
+ */
+ typedef TQValueListNode<T>* NodePtr;
+#ifndef TQT_NO_STL
+ typedef std::bidirectional_iterator_tag iterator_category;
+#endif
+ typedef T value_type;
+ typedef size_t size_type;
+#ifndef TQT_NO_STL
+ typedef ptrdiff_t difference_type;
+#else
+ typedef int difference_type;
+#endif
+ typedef const T* pointer;
+ typedef const T& reference;
+
+ /**
+ * Variables
+ */
+ NodePtr node;
+
+ /**
+ * Functions
+ */
+ TQValueListConstIterator() : node( 0 ) {}
+ TQValueListConstIterator( NodePtr p ) : node( p ) {}
+ TQValueListConstIterator( const TQValueListConstIterator<T>& it ) : node( it.node ) {}
+ TQValueListConstIterator( const TQValueListIterator<T>& it ) : node( it.node ) {}
+
+ bool operator==( const TQValueListConstIterator<T>& it ) const { return node == it.node; }
+ bool operator!=( const TQValueListConstIterator<T>& it ) const { return node != it.node; }
+ const T& operator*() const { return node->data; }
+ // UDT for T = x*
+ // const T* operator->() const { return &node->data; }
+
+ TQValueListConstIterator<T>& operator++() {
+ node = node->next;
+ return *this;
+ }
+
+ TQValueListConstIterator<T> operator++(int) {
+ TQValueListConstIterator<T> tmp = *this;
+ node = node->next;
+ return tmp;
+ }
+
+ TQValueListConstIterator<T>& operator--() {
+ node = node->prev;
+ return *this;
+ }
+
+ TQValueListConstIterator<T> operator--(int) {
+ TQValueListConstIterator<T> tmp = *this;
+ node = node->prev;
+ return tmp;
+ }
+};
+
+template <class T>
+class TQValueListPrivate : public TQShared
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef TQValueListIterator<T> Iterator;
+ typedef TQValueListConstIterator<T> ConstIterator;
+ typedef TQValueListNode<T> Node;
+ typedef TQValueListNode<T>* NodePtr;
+ typedef size_t size_type;
+
+ /**
+ * Functions
+ */
+ TQValueListPrivate();
+ TQValueListPrivate( const TQValueListPrivate<T>& _p );
+
+ void derefAndDelete() // ### hack to get around hp-cc brain damage
+ {
+ if ( deref() )
+ delete this;
+ }
+
+#if defined(TQ_TEMPLATEDLL)
+ // Workaround MS bug in memory de/allocation in DLL vs. EXE
+ virtual
+#endif
+ ~TQValueListPrivate();
+
+ Iterator insert( Iterator it, const T& x );
+ Iterator remove( Iterator it );
+ NodePtr tqfind( NodePtr start, const T& x ) const;
+ int tqfindIndex( NodePtr start, const T& x ) const;
+ uint tqcontains( const T& x ) const;
+ uint remove( const T& x );
+ NodePtr at( size_type i ) const;
+ void clear();
+
+ NodePtr node;
+ size_type nodes;
+};
+
+template <class T>
+TQ_INLINE_TEMPLATES TQValueListPrivate<T>::TQValueListPrivate()
+{
+ node = new Node; node->next = node->prev = node; nodes = 0;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQValueListPrivate<T>::TQValueListPrivate( const TQValueListPrivate<T>& _p )
+ : TQShared()
+{
+ node = new Node; node->next = node->prev = node; nodes = 0;
+ Iterator b( _p.node->next );
+ Iterator e( _p.node );
+ Iterator i( node );
+ while( b != e )
+ insert( i, *b++ );
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQValueListPrivate<T>::~TQValueListPrivate() {
+ NodePtr p = node->next;
+ while( p != node ) {
+ NodePtr x = p->next;
+ delete p;
+ p = x;
+ }
+ delete node;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQValueListPrivate<T>::Iterator TQValueListPrivate<T>::insert( TQ_TYPENAME TQValueListPrivate<T>::Iterator it, const T& x )
+{
+ NodePtr p = new Node( x );
+ p->next = it.node;
+ p->prev = it.node->prev;
+ it.node->prev->next = p;
+ it.node->prev = p;
+ nodes++;
+ return p;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQValueListPrivate<T>::Iterator TQValueListPrivate<T>::remove( TQ_TYPENAME TQValueListPrivate<T>::Iterator it )
+{
+ TQ_ASSERT ( it.node != node );
+ NodePtr next = it.node->next;
+ NodePtr prev = it.node->prev;
+ prev->next = next;
+ next->prev = prev;
+ delete it.node;
+ nodes--;
+ return Iterator( next );
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQValueListPrivate<T>::NodePtr TQValueListPrivate<T>::tqfind( TQ_TYPENAME TQValueListPrivate<T>::NodePtr start, const T& x ) const
+{
+ ConstIterator first( start );
+ ConstIterator last( node );
+ while( first != last) {
+ if ( *first == x )
+ return first.node;
+ ++first;
+ }
+ return last.node;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES int TQValueListPrivate<T>::tqfindIndex( TQ_TYPENAME TQValueListPrivate<T>::NodePtr start, const T& x ) const
+{
+ ConstIterator first( start );
+ ConstIterator last( node );
+ int pos = 0;
+ while( first != last) {
+ if ( *first == x )
+ return pos;
+ ++first;
+ ++pos;
+ }
+ return -1;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES uint TQValueListPrivate<T>::tqcontains( const T& x ) const
+{
+ uint result = 0;
+ Iterator first = Iterator( node->next );
+ Iterator last = Iterator( node );
+ while( first != last) {
+ if ( *first == x )
+ ++result;
+ ++first;
+ }
+ return result;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES uint TQValueListPrivate<T>::remove( const T& _x )
+{
+ const T x = _x;
+ uint result = 0;
+ Iterator first = Iterator( node->next );
+ Iterator last = Iterator( node );
+ while( first != last) {
+ if ( *first == x ) {
+ first = remove( first );
+ ++result;
+ } else
+ ++first;
+ }
+ return result;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQValueListPrivate<T>::NodePtr TQValueListPrivate<T>::at( size_type i ) const
+{
+ TQ_ASSERT( i <= nodes );
+ NodePtr p = node->next;
+ for( size_type x = 0; x < i; ++x )
+ p = p->next;
+ return p;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES void TQValueListPrivate<T>::clear()
+{
+ nodes = 0;
+ NodePtr p = node->next;
+ while( p != node ) {
+ NodePtr next = p->next;
+ delete p;
+ p = next;
+ }
+ node->next = node->prev = node;
+}
+
+#ifdef TQT_CHECK_RANGE
+# if !defined( TQT_NO_DEBUG ) && defined( TQT_CHECK_VALUELIST_RANGE )
+# define TQT_CHECK_INVALID_LIST_ELEMENT if ( empty() ) qWarning( "TQValueList: Warning invalid element" )
+# define TQT_CHECK_INVALID_LIST_ELEMENT_FATAL TQ_ASSERT( !empty() );
+# else
+# define TQT_CHECK_INVALID_LIST_ELEMENT
+# define TQT_CHECK_INVALID_LIST_ELEMENT_FATAL
+# endif
+#else
+# define TQT_CHECK_INVALID_LIST_ELEMENT
+# define TQT_CHECK_INVALID_LIST_ELEMENT_FATAL
+#endif
+
+template <class T> class TQDeepCopy;
+
+template <class T>
+class TQValueList
+{
+public:
+ /**
+ * Typedefs
+ */
+ typedef TQValueListIterator<T> iterator;
+ typedef TQValueListConstIterator<T> const_iterator;
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef size_t size_type;
+#ifndef TQT_NO_STL
+ typedef ptrdiff_t difference_type;
+#else
+ typedef int difference_type;
+#endif
+
+ /**
+ * API
+ */
+ TQValueList() { sh = new TQValueListPrivate<T>; }
+ TQValueList( const TQValueList<T>& l ) { sh = l.sh; sh->ref(); }
+#ifndef TQT_NO_STL
+ TQValueList( const std::list<T>& l )
+ {
+ sh = new TQValueListPrivate<T>;
+ tqCopy( l.begin(), l.end(), std::back_inserter( *this ) );
+ }
+#endif
+ ~TQValueList() { sh->derefAndDelete(); }
+
+ TQValueList<T>& operator= ( const TQValueList<T>& l )
+ {
+ l.sh->ref();
+ sh->derefAndDelete();
+ sh = l.sh;
+ return *this;
+ }
+#ifndef TQT_NO_STL
+ TQValueList<T>& operator= ( const std::list<T>& l )
+ {
+ detach();
+ tqCopy( l.begin(), l.end(), std::back_inserter( *this ) );
+ return *this;
+ }
+ bool operator== ( const std::list<T>& l ) const
+ {
+ if ( size() != l.size() )
+ return FALSE;
+ const_iterator it2 = begin();
+#if !defined(TQ_CC_MIPS)
+ typename
+#endif
+ std::list<T>::const_iterator it = l.begin();
+ for ( ; it2 != end(); ++it2, ++it )
+ if ( !((*it2) == (*it)) )
+ return FALSE;
+ return TRUE;
+ }
+#endif
+ bool operator== ( const TQValueList<T>& l ) const;
+ bool operator!= ( const TQValueList<T>& l ) const { return !( *this == l ); }
+ iterator begin() { detach(); return iterator( sh->node->next ); }
+ const_iterator begin() const { return const_iterator( sh->node->next ); }
+ const_iterator constBegin() const { return const_iterator( sh->node->next ); }
+ iterator end() { detach(); return iterator( sh->node ); }
+ const_iterator end() const { return const_iterator( sh->node ); }
+ const_iterator constEnd() const { return const_iterator( sh->node ); }
+ iterator insert( iterator it, const T& x ) { detach(); return sh->insert( it, x ); }
+ uint remove( const T& x ) { detach(); return sh->remove( x ); }
+ void clear();
+
+ // ### 4.0: move out of class
+ TQValueList<T>& operator<< ( const T& x )
+ {
+ append( x );
+ return *this;
+ }
+
+ size_type size() const { return sh->nodes; }
+ bool empty() const { return sh->nodes == 0; }
+ void push_front( const T& x ) { detach(); sh->insert( begin(), x ); }
+ void push_back( const T& x ) { detach(); sh->insert( end(), x ); }
+ iterator erase( iterator pos ) { detach(); return sh->remove( pos ); }
+ iterator erase( iterator first, iterator last );
+ reference front() { TQT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *begin(); }
+ const_reference front() const { TQT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *begin(); }
+ reference back() { TQT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *(--end()); }
+ const_reference back() const { TQT_CHECK_INVALID_LIST_ELEMENT_FATAL; return *(--end()); }
+ void pop_front() { TQT_CHECK_INVALID_LIST_ELEMENT; erase( begin() ); }
+ void pop_back() {
+ TQT_CHECK_INVALID_LIST_ELEMENT;
+ iterator tmp = end();
+ erase( --tmp );
+ }
+ void insert( iterator pos, size_type n, const T& x );
+ // Some compilers (incl. vc++) would instantiate this function even if
+ // it is not used; this would constrain TQValueList to classes that provide
+ // an operator<
+ /*
+ void sort()
+ {
+ qHeapSort( *this );
+ }
+ */
+
+ TQValueList<T> operator+ ( const TQValueList<T>& l ) const;
+ TQValueList<T>& operator+= ( const TQValueList<T>& l );
+
+ iterator fromLast() { detach(); return iterator( sh->node->prev ); }
+ const_iterator fromLast() const { return const_iterator( sh->node->prev ); }
+
+ bool isEmpty() const { return ( sh->nodes == 0 ); }
+
+ iterator append( const T& x ) { detach(); return sh->insert( end(), x ); }
+ iterator prepend( const T& x ) { detach(); return sh->insert( begin(), x ); }
+
+ iterator remove( iterator it ) { detach(); return sh->remove( it ); }
+
+ T& first() { TQT_CHECK_INVALID_LIST_ELEMENT; detach(); return sh->node->next->data; }
+ const T& first() const { TQT_CHECK_INVALID_LIST_ELEMENT; return sh->node->next->data; }
+ T& last() { TQT_CHECK_INVALID_LIST_ELEMENT; detach(); return sh->node->prev->data; }
+ const T& last() const { TQT_CHECK_INVALID_LIST_ELEMENT; return sh->node->prev->data; }
+
+ T& operator[] ( size_type i ) { TQT_CHECK_INVALID_LIST_ELEMENT; detach(); return sh->at(i)->data; }
+ const T& operator[] ( size_type i ) const { TQT_CHECK_INVALID_LIST_ELEMENT; return sh->at(i)->data; }
+ iterator at( size_type i ) { TQT_CHECK_INVALID_LIST_ELEMENT; detach(); return iterator( sh->at(i) ); }
+ const_iterator at( size_type i ) const { TQT_CHECK_INVALID_LIST_ELEMENT; return const_iterator( sh->at(i) ); }
+ iterator tqat( size_type i ) { TQT_CHECK_INVALID_LIST_ELEMENT; detach(); return iterator( sh->at(i) ); }
+ const_iterator tqat( size_type i ) const { TQT_CHECK_INVALID_LIST_ELEMENT; return const_iterator( sh->at(i) ); }
+ iterator tqfind ( const T& x ) { detach(); return iterator( sh->tqfind( sh->node->next, x) ); }
+ const_iterator tqfind ( const T& x ) const { return const_iterator( sh->tqfind( sh->node->next, x) ); }
+ iterator tqfind ( iterator it, const T& x ) { detach(); return iterator( sh->tqfind( it.node, x ) ); }
+ const_iterator tqfind ( const_iterator it, const T& x ) const { return const_iterator( sh->tqfind( it.node, x ) ); }
+ int tqfindIndex( const T& x ) const { return sh->tqfindIndex( sh->node->next, x) ; }
+ size_type tqcontains( const T& x ) const { return sh->tqcontains( x ); }
+
+ size_type count() const { return sh->nodes; }
+
+ TQValueList<T>& operator+= ( const T& x )
+ {
+ append( x );
+ return *this;
+ }
+ typedef TQValueListIterator<T> Iterator;
+ typedef TQValueListConstIterator<T> ConstIterator;
+ typedef T ValueType;
+
+protected:
+ /**
+ * Helpers
+ */
+ void detach() { if ( sh->count > 1 ) detachInternal(); }
+
+ /**
+ * Variables
+ */
+ TQValueListPrivate<T>* sh;
+
+private:
+ void detachInternal();
+
+ friend class TQDeepCopy< TQValueList<T> >;
+};
+
+template <class T>
+TQ_INLINE_TEMPLATES bool TQValueList<T>::operator== ( const TQValueList<T>& l ) const
+{
+ if ( size() != l.size() )
+ return FALSE;
+ const_iterator it2 = begin();
+ const_iterator it = l.begin();
+ for( ; it != l.end(); ++it, ++it2 )
+ if ( !( *it == *it2 ) )
+ return FALSE;
+ return TRUE;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES void TQValueList<T>::clear()
+{
+ if ( sh->count == 1 ) sh->clear(); else { sh->deref(); sh = new TQValueListPrivate<T>; }
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQValueList<T>::iterator TQValueList<T>::erase( TQ_TYPENAME TQValueList<T>::iterator first, TQ_TYPENAME TQValueList<T>::iterator last )
+{
+ while ( first != last )
+ erase( first++ );
+ return last;
+}
+
+
+template <class T>
+TQ_INLINE_TEMPLATES void TQValueList<T>::insert( TQ_TYPENAME TQValueList<T>::iterator pos, size_type n, const T& x )
+{
+ for ( ; n > 0; --n )
+ insert( pos, x );
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQValueList<T> TQValueList<T>::operator+ ( const TQValueList<T>& l ) const
+{
+ TQValueList<T> l2( *this );
+ for( const_iterator it = l.begin(); it != l.end(); ++it )
+ l2.append( *it );
+ return l2;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQValueList<T>& TQValueList<T>::operator+= ( const TQValueList<T>& l )
+{
+ TQValueList<T> copy = l;
+ for( const_iterator it = copy.begin(); it != copy.end(); ++it )
+ append( *it );
+ return *this;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES void TQValueList<T>::detachInternal()
+{
+ sh->deref(); sh = new TQValueListPrivate<T>( *sh );
+}
+
+#ifndef TQT_NO_DATASTREAM
+template <class T>
+TQ_INLINE_TEMPLATES TQDataStream& operator>>( TQDataStream& s, TQValueList<T>& l )
+{
+ l.clear();
+ TQ_UINT32 c;
+ s >> c;
+ for( TQ_UINT32 i = 0; i < c; ++i )
+ {
+ T t;
+ s >> t;
+ l.append( t );
+ if ( s.atEnd() )
+ break;
+ }
+ return s;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQDataStream& operator<<( TQDataStream& s, const TQValueList<T>& l )
+{
+ s << (TQ_UINT32)l.size();
+ TQValueListConstIterator<T> it = l.begin();
+ for( ; it != l.end(); ++it )
+ s << *it;
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+#define TQ_DEFINED_TQVALUELIST
+#define TQ_DEFINED_TQVALUELIST
+#include "tqwinexport.h"
+#endif // TQVALUELIST_H
diff --git a/tqtinterface/qt4/src/tools/tqvaluestack.h b/tqtinterface/qt4/src/tools/tqvaluestack.h
new file mode 100644
index 0000000..e19ed69
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqvaluestack.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Definition of TQValueStack class
+**
+** Created : 990925
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQVALUESTACK_H
+#define TQVALUESTACK_H
+
+#ifndef TQT_H
+#include "tqvaluelist.h"
+#endif // TQT_H
+
+
+template<class T>
+class TQValueStack : public TQValueList<T>
+{
+public:
+ TQValueStack() {}
+ ~TQValueStack() {}
+ void push( const T& d ) { this->append(d); }
+ T pop()
+ {
+ T elem( this->last() );
+ if ( !this->isEmpty() )
+ this->remove( this->fromLast() );
+ return elem;
+ }
+ T& top() { return this->last(); }
+ const T& top() const { return this->last(); }
+};
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqvaluevector.h b/tqtinterface/qt4/src/tools/tqvaluevector.h
new file mode 100644
index 0000000..03ef9d2
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqvaluevector.h
@@ -0,0 +1,577 @@
+/****************************************************************************
+**
+** Definition of TQValueVector class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQVALUEVECTOR_H
+#define TQVALUEVECTOR_H
+
+#ifndef TQT_H
+#include "tqtl.h"
+#include "tqshared.h"
+#include "tqdatastream.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_STL
+#include <vector>
+#endif
+
+template <class T>
+class TQValueVectorPrivate : public TQShared
+{
+public:
+ typedef T value_type;
+ typedef T* pointer;
+
+ TQValueVectorPrivate()
+ : start( 0 ), finish( 0 ), end( 0 )
+ {
+ }
+
+ TQValueVectorPrivate( const TQValueVectorPrivate<T>& x );
+ TQValueVectorPrivate( size_t size );
+
+ void derefAndDelete() // work-around for hp-cc
+ {
+ if ( deref() )
+ delete this;
+ }
+
+#if defined(TQ_TEMPLATEDLL)
+ // Workaround MS bug in memory de/allocation in DLL vs. EXE
+ virtual
+#endif
+ ~TQValueVectorPrivate()
+ {
+ delete[] start;
+ }
+
+ size_t size() const
+ {
+ return finish - start;
+ }
+
+ bool empty() const
+ {
+ return start == finish;
+ }
+
+ size_t capacity() const
+ {
+ return end - start;
+ }
+
+ void insert( pointer pos, const T& x );
+ void insert( pointer pos, size_t n, const T& x );
+ void reserve( size_t n );
+
+ void clear()
+ {
+ delete[] start;
+ start = 0;
+ finish = 0;
+ end = 0;
+ }
+
+
+ pointer start;
+ pointer finish;
+ pointer end;
+
+private:
+ pointer growAndCopy( size_t n, pointer s, pointer f );
+
+ TQValueVectorPrivate<T>& operator=( const TQValueVectorPrivate<T>& x );
+
+};
+
+template <class T>
+TQ_INLINE_TEMPLATES TQValueVectorPrivate<T>::TQValueVectorPrivate( const TQValueVectorPrivate<T>& x )
+ : TQShared()
+{
+ size_t i = x.size();
+ if ( i > 0 ) {
+ start = new T[ i ];
+ finish = start + i;
+ end = start + i;
+#if defined(__xlC__) && __xlC__ < 0x400 // xlC 3.6 confused by const
+ tqCopy( (pointer)x.start, (pointer)x.finish, start );
+#else
+ tqCopy( x.start, x.finish, start );
+#endif
+ } else {
+ start = 0;
+ finish = 0;
+ end = 0;
+ }
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQValueVectorPrivate<T>::TQValueVectorPrivate( size_t size )
+{
+ if ( size > 0 ) {
+ start = new T[size];
+ finish = start + size;
+ end = start + size;
+ } else {
+ start = 0;
+ finish = 0;
+ end = 0;
+ }
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES void TQValueVectorPrivate<T>::insert( pointer pos, const T& x )
+{
+ const size_t lastSize = size();
+ const size_t n = lastSize !=0 ? 2*lastSize : 1;
+ const size_t offset = pos - start;
+ pointer newStart = new T[n];
+ pointer newFinish = newStart + offset;
+ tqCopy( start, pos, newStart );
+ *newFinish = x;
+ tqCopy( pos, finish, ++newFinish );
+ delete[] start;
+ start = newStart;
+ finish = newStart + lastSize + 1;
+ end = newStart + n;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES void TQValueVectorPrivate<T>::insert( pointer pos, size_t n, const T& x )
+{
+ if ( size_t( end - finish ) >= n ) {
+ // enough room
+ const size_t elems_after = finish - pos;
+ pointer old_finish = finish;
+ if ( elems_after > n ) {
+ tqCopy( finish - n, finish, finish );
+ finish += n;
+ tqCopyBackward( pos, old_finish - n, old_finish );
+ tqFill( pos, pos + n, x );
+ } else {
+ pointer filler = finish;
+ size_t i = n - elems_after;
+ for ( ; i > 0; --i, ++filler )
+ *filler = x;
+ finish += n - elems_after;
+ tqCopy( pos, old_finish, finish );
+ finish += elems_after;
+ tqFill( pos, old_finish, x );
+ }
+ } else {
+ // not enough room
+ const size_t lastSize = size();
+ const size_t len = lastSize + TQMAX( lastSize, n );
+ pointer newStart = new T[len];
+ pointer newFinish = tqCopy( start, pos, newStart );
+ // fill up inserted space
+ size_t i = n;
+ for ( ; i > 0; --i, ++newFinish )
+ *newFinish = x;
+ newFinish = tqCopy( pos, finish, newFinish );
+ delete[] start;
+ start = newStart;
+ finish = newFinish;
+ end = newStart + len;
+ }
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES void TQValueVectorPrivate<T>::reserve( size_t n )
+{
+ const size_t lastSize = size();
+ pointer tmp = growAndCopy( n, start, finish );
+ start = tmp;
+ finish = tmp + lastSize;
+ end = start + n;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQValueVectorPrivate<T>::pointer TQValueVectorPrivate<T>::growAndCopy( size_t n, pointer s, pointer f )
+{
+ pointer newStart = new T[n];
+ tqCopy( s, f, newStart );
+ delete[] start;
+ return newStart;
+}
+
+template <class T> class TQDeepCopy;
+
+template <class T>
+class TQValueVector
+{
+public:
+ typedef T value_type;
+ typedef value_type* pointer;
+ typedef const value_type* const_pointer;
+ typedef value_type* iterator;
+ typedef const value_type* const_iterator;
+ typedef value_type& reference;
+ typedef const value_type& const_reference;
+ typedef size_t size_type;
+#ifndef TQT_NO_STL
+ typedef ptrdiff_t difference_type;
+#else
+ typedef int difference_type;
+#endif
+
+ TQValueVector()
+ {
+ sh = new TQValueVectorPrivate<T>;
+ }
+
+ TQValueVector( const TQValueVector<T>& v )
+ {
+ sh = v.sh;
+ sh->ref();
+ }
+
+ TQValueVector( size_type n, const T& val = T() );
+
+#ifndef TQT_NO_STL
+ TQValueVector( std::vector<T>& v ) // ### remove in 4.0
+ {
+ sh = new TQValueVectorPrivate<T>( v.size() );
+ tqCopy( v.begin(), v.end(), begin() );
+ }
+
+ TQValueVector( const std::vector<T>& v )
+ {
+ sh = new TQValueVectorPrivate<T>( v.size() );
+ tqCopy( v.begin(), v.end(), begin() );
+ }
+#endif
+
+ ~TQValueVector()
+ {
+ sh->derefAndDelete();
+ }
+
+ TQValueVector<T>& operator= ( const TQValueVector<T>& v )
+ {
+ v.sh->ref();
+ sh->derefAndDelete();
+ sh = v.sh;
+ return *this;
+ }
+
+#ifndef TQT_NO_STL
+ TQValueVector<T>& operator= ( const std::vector<T>& v )
+ {
+ clear();
+ resize( v.size() );
+ tqCopy( v.begin(), v.end(), begin() );
+ return *this;
+ }
+#endif
+
+ size_type size() const { return sh->size(); }
+
+ bool empty() const { return sh->empty(); }
+
+ size_type capacity() const
+ {
+ return size_type( sh->capacity() );
+ }
+
+ iterator begin()
+ {
+ detach();
+ return sh->start;
+ }
+
+ const_iterator begin() const
+ {
+ return sh->start;
+ }
+
+ const_iterator constBegin() const
+ {
+ return sh->start;
+ }
+
+ iterator end()
+ {
+ detach();
+ return sh->finish;
+ }
+
+ const_iterator end() const
+ {
+ return sh->finish;
+ }
+
+ const_iterator constEnd() const
+ {
+ return sh->finish;
+ }
+
+ reference at( size_type i, bool* ok = 0 )
+ {
+ detach();
+ if ( ok )
+ *ok = ( i < size() );
+ return *( begin() + i );
+ }
+ reference tqat( size_type i, bool* ok = 0 ) { return at(i, ok); }
+
+ const_reference at( size_type i, bool* ok = 0 ) const
+ {
+ if ( ok )
+ *ok = ( i < size() );
+ return *( begin() + i );
+ }
+ const_reference tqat( size_type i, bool* ok = 0 ) const { return at(i, ok); }
+
+ reference operator[]( size_type i )
+ {
+ detach();
+ return *( begin() + i );
+ }
+
+ const_reference operator[]( size_type i ) const
+ {
+ return *( begin() + i );
+ }
+
+ reference front()
+ {
+ TQ_ASSERT( !empty() );
+ detach();
+ return *begin();
+ }
+
+ const_reference front() const
+ {
+ TQ_ASSERT( !empty() );
+ return *begin();
+ }
+
+ reference back()
+ {
+ TQ_ASSERT( !empty() );
+ detach();
+ return *( end() - 1 );
+ }
+
+ const_reference back() const
+ {
+ TQ_ASSERT( !empty() );
+ return *( end() - 1 );
+ }
+
+ void push_back( const T& x )
+ {
+ detach();
+ if ( sh->finish == sh->end ) {
+ sh->reserve( size()+size()/2+1 );
+ }
+ *sh->finish = x;
+ ++sh->finish;
+ }
+
+ void pop_back()
+ {
+ detach();
+ if ( empty() )
+ return;
+ --sh->finish;
+ }
+
+ iterator insert( iterator pos, const T& x );
+ iterator insert( iterator pos, size_type n, const T& x );
+
+ void reserve( size_type n )
+ {
+ if ( capacity() < n ) {
+ detach();
+ sh->reserve( n );
+ }
+ }
+
+ void resize( size_type n, const T& val = T() )
+ {
+ if ( n < size() )
+ erase( begin() + n, end() );
+ else
+ insert( end(), n - size(), val );
+ }
+
+ void clear()
+ {
+ detach();
+ sh->clear();
+ }
+
+ iterator erase( iterator pos )
+ {
+ detach();
+ if ( pos + 1 != end() )
+ tqCopy( pos + 1, sh->finish, pos );
+ --sh->finish;
+ return pos;
+ }
+
+ iterator erase( iterator first, iterator last )
+ {
+ detach();
+ tqCopy( last, sh->finish, first );
+ sh->finish = sh->finish - ( last - first );
+ return first;
+ }
+
+ // ### remove in TQt 4.0
+ bool operator==( const TQValueVector<T>& x )
+ {
+ return size()==x.size() ? tqEqual( constBegin(), constEnd(), x.begin()) : FALSE;
+ }
+
+ bool operator==( const TQValueVector<T>& x ) const
+ {
+ return size()==x.size() ? tqEqual( begin(), end(), x.begin() ) : FALSE;
+ }
+
+ typedef T ValueType;
+ typedef ValueType *Iterator;
+ typedef const ValueType *ConstIterator;
+
+ size_type count() const { return size(); }
+ bool isEmpty() const { return empty(); }
+
+ reference first() { return front(); }
+ const_reference first() const { return front(); }
+ reference last() { return back(); }
+ const_reference last() const { return back(); }
+ void append( const T& x ) { push_back( x ); }
+
+protected:
+ void detach()
+ {
+ if ( sh->count > 1 ) { detachInternal(); }
+ }
+ void detachInternal();
+ TQValueVectorPrivate<T>* sh;
+
+private:
+ friend class TQDeepCopy< TQValueVector<T> >;
+};
+
+template <class T>
+TQ_INLINE_TEMPLATES TQValueVector<T>::TQValueVector( size_type n, const T& val )
+{
+ sh = new TQValueVectorPrivate<T>( n );
+ tqFill( begin(), end(), val );
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES void TQValueVector<T>::detachInternal()
+{
+ sh->deref();
+ sh = new TQValueVectorPrivate<T>( *sh );
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQValueVector<T>::iterator TQValueVector<T>::insert( iterator pos, const T& x )
+{
+ size_type offset = pos - sh->start;
+ detach();
+ if ( pos == end() ) {
+ if ( sh->finish == sh->end )
+ push_back( x );
+ else {
+ *sh->finish = x;
+ ++sh->finish;
+ }
+ } else {
+ if ( sh->finish == sh->end ) {
+ sh->insert( pos, x );
+ } else {
+ *sh->finish = *(sh->finish - 1);
+ ++sh->finish;
+ tqCopyBackward( pos, sh->finish - 2, sh->finish - 1 );
+ *pos = x;
+ }
+ }
+ return begin() + offset;
+}
+
+template <class T>
+TQ_INLINE_TEMPLATES TQ_TYPENAME TQValueVector<T>::iterator TQValueVector<T>::insert( iterator pos, size_type n, const T& x )
+{
+ if ( n != 0 ) {
+ size_type offset = pos - sh->start;
+ detach();
+ pos = begin() + offset;
+ sh->insert( pos, n, x );
+ }
+ return pos;
+}
+
+
+#ifndef TQT_NO_DATASTREAM
+template<class T>
+TQ_INLINE_TEMPLATES TQDataStream& operator>>( TQDataStream& s, TQValueVector<T>& v )
+{
+ v.clear();
+ TQ_UINT32 c;
+ s >> c;
+ v.resize( c );
+ for( TQ_UINT32 i = 0; i < c; ++i )
+ {
+ T t;
+ s >> t;
+ v[i] = t;
+ }
+ return s;
+}
+
+template<class T>
+TQ_INLINE_TEMPLATES TQDataStream& operator<<( TQDataStream& s, const TQValueVector<T>& v )
+{
+ s << (TQ_UINT32)v.size();
+ // ### use typename TQValueVector<T>::const_iterator once all supported
+ // ### compilers know about the 'typename' keyword.
+ const T* it = v.begin();
+ for( ; it != v.end(); ++it )
+ s << *it;
+ return s;
+}
+#endif // TQT_NO_DATASTREAM
+
+#define TQ_DEFINED_TQVALUEVECTOR
+#include "tqwinexport.h"
+#endif // TQVALUEVECTOR_H
diff --git a/tqtinterface/qt4/src/tools/tqwaitcondition.h b/tqtinterface/qt4/src/tools/tqwaitcondition.h
new file mode 100644
index 0000000..a3966a2
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqwaitcondition.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Definition of TQWaitCondition class
+**
+** Created : 931107
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWAITCONDITION_H
+#define TQWAITCONDITION_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#endif // TQT_H
+
+#if defined(TQT_THREAD_SUPPORT)
+
+#include <limits.h>
+
+class TQWaitConditionPrivate;
+class TQMutex;
+
+class TQ_EXPORT TQWaitCondition
+{
+public:
+ TQWaitCondition();
+ virtual ~TQWaitCondition();
+
+ // default argument causes thread to block indefinately
+ bool wait( unsigned long time = ULONG_MAX );
+ bool wait( TQMutex *mutex, unsigned long time = ULONG_MAX );
+
+ void wakeOne();
+ void wakeAll();
+
+private:
+ TQWaitConditionPrivate * d;
+
+#if defined(TQ_DISABLE_COPY)
+ TQWaitCondition( const TQWaitCondition & );
+ TQWaitCondition &operator=( const TQWaitCondition & );
+#endif
+};
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/tools/tqwaitcondition_unix.cpp b/tqtinterface/qt4/src/tools/tqwaitcondition_unix.cpp
new file mode 100644
index 0000000..89ce471
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqwaitcondition_unix.cpp
@@ -0,0 +1,316 @@
+/****************************************************************************
+**
+** TQWaitCondition class for Unix
+**
+** Created : 20010725
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#if defined(TQT_THREAD_SUPPORT)
+
+#include "tqplatformdefs.h"
+
+typedef pthread_mutex_t TQ_MUTEX_T;
+
+#include "tqwaitcondition.h"
+#include "tqmutex.h"
+#include "tqmutex_p.h"
+
+#include <errno.h>
+#include <string.h>
+
+
+struct TQWaitConditionPrivate {
+ pthread_cond_t cond;
+};
+
+
+/*!
+ \class TQWaitCondition tqwaitcondition.h
+ \threadsafe
+ \brief The TQWaitCondition class allows waiting/waking for conditions between threads.
+
+ \ingroup thread
+ \ingroup environment
+
+ TQWaitConditions allow a thread to tell other threads that some
+ sort of condition has been met; one or many threads can block
+ waiting for a TQWaitCondition to set a condition with wakeOne() or
+ wakeAll(). Use wakeOne() to wake one randomly selected event or
+ wakeAll() to wake them all. For example, say we have three tasks
+ that should be performed every time the user presses a key; each
+ task could be split into a thread, each of which would have a
+ run() body like this:
+
+ \code
+ TQWaitCondition key_pressed;
+
+ for (;;) {
+ key_pressed.wait(); // This is a TQWaitCondition global variable
+ // Key was pressed, do something interesting
+ do_something();
+ }
+ \endcode
+
+ A fourth thread would read key presses and wake the other three
+ threads up every time it receives one, like this:
+
+ \code
+ TQWaitCondition key_pressed;
+
+ for (;;) {
+ getchar();
+ // Causes any thread in key_pressed.wait() to return from
+ // that method and continue processing
+ key_pressed.wakeAll();
+ }
+ \endcode
+
+ Note that the order the three threads are woken up in is
+ undefined, and that if some or all of the threads are still in
+ do_something() when the key is pressed, they won't be woken up
+ (since they're not waiting on the condition variable) and so the
+ task will not be performed for that key press. This can be
+ avoided by, for example, doing something like this:
+
+ \code
+ TQMutex mymutex;
+ TQWaitCondition key_pressed;
+ int mycount=0;
+
+ // Worker thread code
+ for (;;) {
+ key_pressed.wait(); // This is a TQWaitCondition global variable
+ mymutex.lock();
+ mycount++;
+ mymutex.unlock();
+ do_something();
+ mymutex.lock();
+ mycount--;
+ mymutex.unlock();
+ }
+
+ // Key reading thread code
+ for (;;) {
+ getchar();
+ mymutex.lock();
+ // Sleep until there are no busy worker threads
+ while( mycount > 0 ) {
+ mymutex.unlock();
+ sleep( 1 );
+ mymutex.lock();
+ }
+ mymutex.unlock();
+ key_pressed.wakeAll();
+ }
+ \endcode
+
+ The mutexes are necessary because the results of two threads
+ attempting to change the value of the same variable simultaneously
+ are unpredictable.
+*/
+
+/*!
+ Constructs a new event signalling, i.e. wait condition, object.
+*/
+TQWaitCondition::TQWaitCondition()
+{
+ d = new TQWaitConditionPrivate;
+
+ int ret = pthread_cond_init(&d->cond, NULL);
+
+#ifdef TQT_CHECK_RANGE
+ if (ret)
+ qWarning( "Wait condition init failure: %s", strerror( ret ) );
+#endif
+}
+
+
+/*!
+ Deletes the event signalling, i.e. wait condition, object.
+*/
+TQWaitCondition::~TQWaitCondition()
+{
+ int ret = pthread_cond_destroy(&d->cond);
+
+ if (ret) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "Wait condition destroy failure: %s", strerror( ret ) );
+#endif
+
+ // seems we have threads waiting on us, lets wake them up
+ pthread_cond_broadcast(&d->cond);
+ }
+
+ delete d;
+}
+
+/*!
+ This wakes one thread waiting on the TQWaitCondition. The thread
+ that is woken up depends on the operating system's scheduling
+ policies, and cannot be controlled or predicted.
+
+ \sa wakeAll()
+*/
+void TQWaitCondition::wakeOne()
+{
+ int ret = pthread_cond_signal(&d->cond);
+
+#ifdef TQT_CHECK_RANGE
+ if (ret)
+ qWarning("Wait condition wakeOne failure: %s", strerror(ret));
+#endif
+}
+
+/*!
+ This wakes all threads waiting on the TQWaitCondition. The order in
+ which the threads are woken up depends on the operating system's
+ scheduling policies, and cannot be controlled or predicted.
+
+ \sa wakeOne()
+*/
+void TQWaitCondition::wakeAll()
+{
+ int ret = pthread_cond_broadcast(&d->cond);
+
+#ifdef TQT_CHECK_RANGE
+ if (ret)
+ qWarning("Wait condition wakeAll failure: %s", strerror(ret));
+#endif
+}
+
+/*!
+ Wait on the thread event object. The thread calling this will
+ block until either of these conditions is met:
+ \list
+ \i Another thread Q_SIGNALS it using wakeOne() or wakeAll(). This
+ function will return TRUE in this case.
+ \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
+ default), then the wait will never timeout (the event must be
+ signalled). This function will return FALSE if the wait timed
+ out.
+ \endlist
+
+ \sa wakeOne(), wakeAll()
+*/
+bool TQWaitCondition::wait(unsigned long time)
+{
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_lock( &mutex );
+
+ int ret;
+ if (time != ULONG_MAX) {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+
+ timespec ti;
+ ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000;
+ ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 );
+ ti.tv_nsec %= 1000000000;
+
+ ret = pthread_cond_timedwait(&d->cond, &mutex, &ti);
+ } else
+ ret = pthread_cond_wait(&d->cond, &mutex);
+
+#ifdef TQT_CHECK_RANGE
+ if (ret && ret != ETIMEDOUT)
+ qWarning("Wait condition wait failure: %s",strerror(ret));
+#endif
+
+ pthread_mutex_unlock( &mutex );
+
+ return (ret == 0);
+}
+
+/*!
+ \overload
+
+ Release the locked \a mutex and wait on the thread event object.
+ The \a mutex must be initially locked by the calling thread. If \a
+ mutex is not in a locked state, this function returns immediately.
+ If \a mutex is a recursive mutex, this function returns
+ immediately. The \a mutex will be unlocked, and the calling thread
+ will block until either of these conditions is met:
+ \list
+ \i Another thread Q_SIGNALS it using wakeOne() or wakeAll(). This
+ function will return TRUE in this case.
+ \i \a time milliseconds has elapsed. If \a time is ULONG_MAX (the
+ default), then the wait will never timeout (the event must be
+ signalled). This function will return FALSE if the wait timed
+ out.
+ \endlist
+
+ The mutex will be returned to the same locked state. This function
+ is provided to allow the atomic transition from the locked state
+ to the wait state.
+
+ \sa wakeOne(), wakeAll()
+*/
+bool TQWaitCondition::wait(TQMutex *mutex, unsigned long time)
+{
+ if (! mutex)
+ return FALSE;
+
+ if (mutex->d->type() == TQ_MUTEX_RECURSIVE) {
+#ifdef TQT_CHECK_RANGE
+ qWarning("Wait condition warning: using recursive mutexes with\n"
+ " wait conditions is undefined!");
+#endif
+ return FALSE;
+ }
+
+ int ret;
+ if (time != ULONG_MAX) {
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+
+ timespec ti;
+ ti.tv_nsec = ( tv.tv_usec + ( time % 1000 ) * 1000 ) * 1000;
+ ti.tv_sec = tv.tv_sec + (time / 1000) + ( ti.tv_nsec / 1000000000 );
+ ti.tv_nsec %= 1000000000;
+
+ ret = pthread_cond_timedwait(&d->cond, &mutex->d->handle, &ti);
+ } else
+ ret = pthread_cond_wait(&d->cond, &mutex->d->handle);
+
+#ifdef TQT_CHECK_RANGE
+ if (ret && ret != ETIMEDOUT)
+ qWarning("Wait condition wait failure: %s",strerror(ret));
+#endif
+
+ return (ret == 0);
+}
+
+#endif // TQT_THREAD_SUPPORT
diff --git a/tqtinterface/qt4/src/tools/tqwinexport.cpp b/tqtinterface/qt4/src/tools/tqwinexport.cpp
new file mode 100644
index 0000000..8fd0b31
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqwinexport.cpp
@@ -0,0 +1,31 @@
+#define TQ_EXPORT_TEMPLATES
+
+#include <tqcanvas.h>
+#include <tqaccessible.h>
+#include <tqconnection.h>
+#include <tqguardedptr.h>
+#include <tqobject.h>
+#include <tqpoint.h>
+#include <tqrect.h>
+#include <tqsignalslotimp.h>
+#include <tqwidget.h>
+#include <tqhttp.h>
+#include <private/tqsqlextension_p.h>
+#include <tqsqlindex.h>
+#include <tqtable.h>
+#include <tqtable.h>
+#include <tqtable.h>
+#include <tqasciidict.h>
+#include <tqcstring.h>
+#include <tqdict.h>
+#include <tqintdict.h>
+#include <tqlibrary.h>
+#include <tqmap.h>
+#include <tqmemarray.h>
+#include <tqptrlist.h>
+#include <tqptrvector.h>
+#include <tqstring.h>
+#include <tqvaluelist.h>
+#include <tqvaluevector.h>
+#include <tqdockarea.h>
+#include <tqdockwindow.h>
diff --git a/tqtinterface/qt4/src/tools/tqwinexport.h b/tqtinterface/qt4/src/tools/tqwinexport.h
new file mode 100644
index 0000000..0b40e59
--- /dev/null
+++ b/tqtinterface/qt4/src/tools/tqwinexport.h
@@ -0,0 +1,224 @@
+/****************************************************************************
+**
+** Global type declarations and definitions
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the tools module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#if defined(TQ_TEMPLATEDLL) && ( !defined(TQ_CC_BOR) || !defined(TQT_MAKEDLL) || defined(TQ_EXPORT_TEMPLATES) )
+// TQMOC_SKIP_BEGIN
+
+#if defined(TQ_DEFINED_TQASCIIDICT) && defined(TQ_DEFINED_TQCONNECTION_LIST) && !defined(TQ_EXPORTED_TQASCIIDICT_TEMPLATES)
+#define TQ_EXPORTED_TQASCIIDICT_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQAsciiDictIterator<TQConnectionList>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQAsciiDict<TQConnectionList>;
+#endif
+
+#if defined(TQ_DEFINED_TQSTYLESHEET) && defined(TQ_DEFINED_TQDICT) && !defined(TQ_EXPORTED_TQSTYLESHEET_TEMPLATES)
+#define TQ_EXPORTED_TQSTYLESHEET_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQDict<TQStyleSheetItem>;
+#endif
+
+#if defined(TQ_DEFINED_TQLIBRARY) && defined(TQ_DEFINED_TQDICT) && !defined(TQ_EXPORTED_TQDICTLIBRARY_TEMPLATES)
+#define TQ_EXPORTED_TQDICTLIBRARY_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQDict<TQLibrary>; // for TQtopia
+#endif
+
+#if defined(TQ_DEFINED_TQGUARDEDPTR) && defined(TQ_DEFINED_TQOBJECT) && !defined(TQ_EXPORTED_TQGUARDEDPTROBJECT_TEMPLATES)
+#define TQ_EXPORTED_TQGUARDEDPTROBJECT_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQGuardedPtr<TQObject>;
+#endif
+
+// needed for TQtopia
+#if defined(TQ_DEFINED_TQGUARDEDPTR) && defined(TQ_DEFINED_TQWIDGET) && !defined(TQ_EXPORTED_TQGUARDEDPTRTQWIDGET_TEMPLATES)
+#define TQ_EXPORTED_TQGUARDEDPTRTQWIDGET_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQGuardedPtr<TQWidget>;
+#endif
+
+#if defined(TQ_DEFINED_TQGUARDEDPTR) && defined(TQ_DEFINED_TQACCESSIBLE_OBJECT) && !defined(TQ_EXPORTED_TQACCESSIBLEOBJECT_TEMPLATES)
+#define TQ_EXPORTED_TQACCESSIBLEOBJECT_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQGuardedPtr<TQAccessibleObject>;
+#endif
+
+#if defined(TQ_DEFINED_TQINTDICT) && !defined(TQ_EXPORTED_TQINTDICT_TEMPLATES)
+#define TQ_EXPORTED_TQINTDICT_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQIntDict<int>;
+#endif
+
+#if defined(TQ_DEFINED_TQINTDICT) && defined(TQ_DEFINED_TQWIDGET) && !defined(TQ_EXPORTED__TEMPLATES)
+#define TQ_EXPORTED__TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQIntDictIterator<TQWidget>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQIntDict<TQWidget>;
+#endif
+
+#if defined(TQ_DEFINED_TQMAP) && !defined(TQ_EXPORTED_TQMAPBASIC_TEMPLATES)
+#define TQ_EXPORTED_TQMAPBASIC_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<int, int>; // for TQtopia
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<int, bool>; // for TQtopia
+#endif
+
+#if defined(TQ_DEFINED_TQMAP) && defined(TQ_DEFINED_TQSTRING) && !defined(TQ_EXPORTED_TQMAPTQSTRING_TEMPLATES)
+#define TQ_EXPORTED_TQMAPTQSTRING_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<TQString, TQString>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<TQString, int>; // for TQtopia
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMap<int, TQString>; // for TQtopia
+#endif
+
+#if defined(TQ_DEFINED_TQMEMARRAY) && !defined(TQ_EXPORTED_TQMEMARRAY_BASIC_TEMPLATES)
+#define TQ_EXPORTED_TQMEMARRAY_BASIC_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMemArray<int>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMemArray<bool>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMemArray<char>;
+#endif
+
+#if defined(TQ_DEFINED_TQMEMARRAY) && defined(TQ_DEFINED_TQPOINT) && !defined(TQ_EXPORTED_TQMEMARAYPOINT_TEMPLATES)
+#define TQ_EXPORTED_TQMEMARAYPOINT_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQMemArray<TQPoint>;
+#endif
+
+#if defined(TQ_DEFINED_TQPTRLIST) && !defined(TQ_EXPORTED_TQPTRLIST_BASIC_TEMPLATES)
+#define TQ_EXPORTED_TQPTRLIST_BASIC_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrListIterator<char>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrList<char>;
+#endif
+
+#if defined(TQ_DEFINED_TQPTRLIST) && defined(TQ_DEFINED_TQWIDGET) && !defined(TQ_EXPORTED_TQPTRLISTWIDGET_TEMPLATES)
+#define TQ_EXPORTED_TQPTRLISTWIDGET_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrListIterator<TQWidget>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrList<TQWidget>;
+#endif
+
+#if defined(TQ_DEFINED_TQPTRLIST) && defined(TQ_DEFINED_TQCONNECTION) && !defined(TQ_EXPORTED_TQPTRLISTCONNECTION_TEMPLATES)
+#define TQ_EXPORTED_TQPTRLISTCONNECTION_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrListIterator<TQConnection>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrList<TQConnection>;
+#endif
+
+#if defined(TQ_DEFINED_TQPTRLIST) && defined(TQ_DEFINED_TQOBJECT) && !defined(TQ_EXPORTED_TQPTRLISTOBJECT_TEMPLATES)
+#define TQ_EXPORTED_TQPTRLISTOBJECT_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrListIterator<TQObject>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrList<TQObject>;
+#endif
+
+#if defined(TQ_DEFINED_TQPTRLIST) && defined(TQ_DEFINED_TQDOCKWINDOW) && !defined(TQ_EXPORTED_TQPTRLISTDOCWINDOW_TEMPLATES)
+#define TQ_EXPORTED_TQPTRLISTDOCWINDOW_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrListIterator<TQDockWindow>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrList<TQDockWindow>;
+#endif
+
+#if defined(TQ_DEFINED_TQPTRVECTOR) && !defined(TQ_EXPORTED_TQPTRVECTOR_BASIC_TEMPLATES)
+#define TQ_EXPORTED_TQPTRVECTOR_BASIC_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrVector<int>;
+#endif
+
+#if defined(TQ_DEFINED_TQPTRVECTOR) && defined(TQ_DEFINED_TQSTYLESHEET) && !defined(TQ_EXPORTED_TQPTRVECTORSTYLESHEETITEM_TEMPLATES)
+#define TQ_EXPORTED_TQPTRVECTORSTYLESHEETITEM_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrVector<TQStyleSheetItem>;
+#endif
+
+#if defined(TQ_DEFINED_TQPTRVECTOR) && defined(TQ_DEFINED_TQWIDGET) && !defined(TQ_EXPORTED_TQPTRVECTORWIDGET_TEMPLATES)
+#define TQ_EXPORTED_TQPTRVECTORWIDGET_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrVector<TQWidget>;
+#endif
+
+#if defined(TQ_DEFINED_TQPTRVECTOR) && defined(TQ_DEFINED_TQCONNECTION_LIST) && !defined(TQ_EXPORTED_TQPTRVECTORCONNECTTIONLIST_TEMPLATES)
+#define TQ_EXPORTED_TQPTRVECTORCONNECTTIONLIST_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrVector<TQConnectionList>;
+#endif
+
+#if defined(TQ_DEFINED_TQVALUELIST) && !defined(TQ_EXPORTED_TQVALUELIST_BASIC_TEMPLATES)
+#define TQ_EXPORTED_TQVALUELIST_BASIC_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueListIterator<bool>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueList<bool>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueListIterator<int>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueList<int>;
+#endif
+
+#if defined(TQ_DEFINED_TQVALUELIST) && defined(TQ_DEFINED_TQRECT) && !defined(TQ_EXPORTED_TQVALUELISTRECT_TEMPLATES)
+#define TQ_EXPORTED_TQVALUELISTRECT_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueListIterator<TQRect>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueList<TQRect>;
+#endif
+
+#if defined(TQ_DEFINED_TQVALUELIST) && defined(TQ_DEFINED_TQSTRING) && !defined(TQ_EXPORTED_TQVALUELISTSTRING_TEMPLATES)
+#define TQ_EXPORTED_TQVALUELISTSTRING_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueListIterator<TQString>;
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueList<TQString>;
+#endif
+
+// TQStylesheet template exports
+#if defined(TQ_DEFINED_TQVALUELIST) && defined(TQ_DEFINED_TQPTRVECTOR) && defined(TQ_DEFINED_TQSTYLESHEET) && !defined(TQ_EXPORTED_TQSTYLESHEETITEM1_TEMPLATES)
+#define TQ_EXPORTED_TQSTYLESHEETITEM1_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueList< TQPtrVector< TQStyleSheetItem> >;
+#endif
+
+#if defined(TQ_DEFINED_TQVALUELIST) && defined(TQ_DEFINED_TQSTYLESHEET) && !defined(TQ_EXPORTED_TQSTYLESHEETITEM2_TEMPLATES)
+#define TQ_EXPORTED_TQSTYLESHEETITEM2_TEMPLATES
+TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQValueList<TQStyleSheetItem::ListStyle>;
+#endif
+
+// qcanvas template exports
+#if defined(TQ_DEFINED_TQPTRLIST) && defined(TQ_DEFINED_TQCANVAS) && !defined(TQ_EXPORTED_TQCANVAS1_TEMPLATES)
+#define TQ_EXPORTED_TQCANVAS1_TEMPLATES
+TQM_TEMPLATE_EXTERN_CANVAS template class TQM_EXPORT_CANVAS TQPtrListIterator< TQCanvasItem >;
+TQM_TEMPLATE_EXTERN_CANVAS template class TQM_EXPORT_CANVAS TQPtrList< TQCanvasItem >;
+TQM_TEMPLATE_EXTERN_CANVAS template class TQM_EXPORT_CANVAS TQPtrListIterator< TQCanvasView >;
+TQM_TEMPLATE_EXTERN_CANVAS template class TQM_EXPORT_CANVAS TQPtrList< TQCanvasView >;
+#endif
+
+// qtable template exports
+#if defined(TQ_DEFINED_TQPTRLIST) && defined(TQ_DEFINED_TQTABLE_SELECTION) && !defined(TQ_EXPORTED_TQTABLESELECTION_TEMPLATES)
+#define TQ_EXPORTED_TQTABLESELECTION_TEMPLATES
+TQM_TEMPLATE_EXTERN_TABLE template class TQM_EXPORT_TABLE TQPtrList<TQTableSelection>;
+#endif
+
+#if defined(TQ_DEFINED_TQTABLE_ITEM) && defined(TQ_DEFINED_TQPTRVECTOR) && !defined(TQ_EXPORTED_TQTABLEITEM_TEMPLATES)
+#define TQ_EXPORTED_TQTABLEITEM_TEMPLATES
+TQM_TEMPLATE_EXTERN_TABLE template class TQM_EXPORT_TABLE TQPtrVector<TQTableItem>;
+#endif
+
+#if defined(TQ_DEFINED_TQTABLE) && defined(TQ_DEFINED_TQPTRVECTOR)
+//TQ_TEMPLATE_EXTERN template class TQ_EXPORT TQPtrVector<TQTable>;
+#endif
+
+// qsqlextension template exports
+#if defined(TQ_DEFINED_TQSQLEXTENSION) && defined(TQ_DEFINED_TQMAP) && defined(TQ_DEFINED_TQVALUEVECTOR) && defined(TQ_DEFINED_TQSTRING) && !defined(TQ_EXPORTED_TQSQLEXTENSION_TEMPLATES)
+#define TQ_EXPORTED_TQSQLEXTENSION_TEMPLATES
+TQM_TEMPLATE_EXTERN_SQL template class TQM_EXPORT_SQL TQMap<TQString,Param>;
+TQM_TEMPLATE_EXTERN_SQL template class TQM_EXPORT_SQL TQValueVector<Holder>;
+#endif
+
+
+// TQMOC_SKIP_END
+#endif // template defined
diff --git a/tqtinterface/qt4/src/tqmoc/README b/tqtinterface/qt4/src/tqmoc/README
new file mode 100644
index 0000000..f616e7c
--- /dev/null
+++ b/tqtinterface/qt4/src/tqmoc/README
@@ -0,0 +1,24 @@
+This directory tqcontains the source code for the Qt Meta Object
+Compiler (tqmoc).
+
+The files tqmoc_yacc.cpp, tqmoc_yacc.h and tqmoc_lex.cpp are generated by
+lex and yacc from tqmoc.l and tqmoc.y.
+
+To compile the tqmoc program from scratch, you need lex and yacc. These
+tools are preinstalled on most Unix systems, often as symbolic links
+to flex and byacc or bison.
+
+If you run Windows, you can install the Cygwin32 package available at
+ftp://ftp.cygnus.com/pub/gnu-win32/win32.
+
+yacc -d tqmoc.y
+mv y.tab.c tqmoc_yacc.cpp
+mv y.tab.h tqmoc_yacc.h
+
+
+
+
+
+
+lex -o tqmoc_lex.cpp tqmoc.l
+yacc -d -o tqmoc_yacc.cpp tqmoc.y
diff --git a/tqtinterface/qt4/src/tqmoc/tqmoc.l b/tqtinterface/qt4/src/tqmoc/tqmoc.l
new file mode 100644
index 0000000..ff715cf
--- /dev/null
+++ b/tqtinterface/qt4/src/tqmoc/tqmoc.l
@@ -0,0 +1,498 @@
+/****************************************************************************
+**
+** Lexical analyzer for meta object compiler
+**
+** Created : 930417
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the TQ Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+*****************************************************************************/
+
+%{
+#ifdef TQMOC_YACC_CODE
+
+#ifdef TQMOC_MWERKS_PLUGIN
+#ifdef TQ_OS_MAC9
+# define isascii(c) ((int)( (unsigned int) (c) <= (unsigned char)0x7F ))
+#endif
+const char *buf_buffer = NULL;
+long buf_size_total = 0, buf_index = 0;
+#define YY_INPUT(buf, result, max_size) \
+ { \
+ if(buf_index < buf_size_total ) { \
+ while(!isascii(buf_buffer[buf_index])) buf_index++; \
+ int ms = ((max_size < buf_size_total) ? max_size : buf_size_total); \
+ for(result = 0; result < ms; result++) { \
+ char c = buf_buffer[buf_index + result]; \
+ if(!isascii(c)) { \
+ buf_index++; \
+ break; \
+ } \
+ buf[result] = c == '\r' ? '\n' : c; \
+ } \
+ buf_index += result; \
+ } else result = YY_NULL; \
+ }
+#endif
+
+#include "tqstring.h"
+
+
+#define input yyinput // yyinput in C++
+
+#define X if(lexDebug){fprintf(stderr,"LEX (%i) : %s\n",lineNo,yytext);};
+#define Y if(lexDebug){fprintf(stderr,"LEX (%i) : %s\n",lineNo,yytext);};
+/*
+#define Y if(lexDebug){fprintf(stderr,"LEX (%i) : %s updates level to %i\n"\
+ ,lineNo,yytext,templLevel);};
+*/
+#define Z if(lexDebug){fprintf(stderr,"LEX (%i) : skipped the string %s\"\n"\
+ ,lineNo,yytext);};
+#define BEGIN_INSIDE
+
+
+#define linput() \
+ ( (c = input()) == '\n' ? (lineNo++, c) : (c == EOF) ? 0 : c )
+
+#include <string.h>
+#include <stdlib.h>
+
+int classPLevel = 1; /* Depth of nested curly braces in IN_CLASS */
+int namespacePLevel = 1; /* Depth of nested curly braces in IN_NAMESPACE */
+int expLevel = 1; /* Depth of nested parentheses in IN_EXPR */
+int enumLevel = 1; /* Depth of nested parentheses in IN_ENUM */
+int fctLevel = 1; /* Depth of nested parentheses in IN_FCT */
+int templLevel = 1; /* Depth of levels in IN_TEMPL_ARGS */
+
+int lastState = 0; /* Remembers the state when a
+ TQMOC_SKIP_BEGIN is encountered */
+int skipLevel = 0; /* Depth of TQMOC_SKIP_BEGINs */
+
+class TQString;
+
+extern void addExpressionChar( const char );
+extern void addExpressionString( const char * );
+extern void tqmoc_warn( const char *msg );
+%}
+
+%start OUTSIDE TQT_DEF IN_CLASS IN_NAMESPACE IN_ENUM IN_EXPR IN_DEF_ARG IN_FCT IN_TEMPL_ARGS GIMME_SEMICOLON SKIP IN_PROPERTY IN_CLASSINFO
+
+ALMOSTSTRING \"([^"\n\\]|\\(.|\n))*
+STRING {ALMOSTSTRING}\"
+
+%%
+
+<OUTSIDE>"class" { X;
+ BEGIN TQT_DEF;
+ return CLASS; }
+<OUTSIDE>"namespace" { X;
+ BEGIN TQT_DEF;
+ return NAMESPACE; }
+<OUTSIDE>"using" { X;
+ BEGIN TQT_DEF;
+ return USING; }
+<OUTSIDE>"template" { X;
+ BEGIN TQT_DEF;
+ return TEMPLATE; }
+<TQT_DEF>"TQ_OBJECT" { X; return TQ_OBJECT; }
+<TQT_DEF>"tqsignals" { X; return SIGNALS; }
+<TQT_DEF>"tqslots" { X; return SLOTS; }
+<TQT_DEF>"TQ_CLASSINFO" { X; return TQ_CLASSINFO; }
+<TQT_DEF>"Q_PROPERTY" { X; return Q_PROPERTY; }
+<TQT_DEF>"TQ_OVERRIDE" { X; return TQ_OVERRIDE; }
+<TQT_DEF>"TQ_ENUMS" { X; return TQ_ENUMS; }
+<TQT_DEF>"TQ_SETS" { X; return TQ_SETS; }
+
+<IN_FCT>"{" { fctLevel++;Y; }
+<IN_FCT>"}" { fctLevel--;Y;if (fctLevel==0){X;return '}';}}
+<IN_CLASS>"{" { classPLevel++;Y; }
+<IN_CLASS>"}" { classPLevel--;Y;if (classPLevel == 0)
+ {X;return '}';} }
+<IN_CLASS>"public" { X;if( classPLevel == 1 ) return PUBLIC; }
+<IN_CLASS>"protected" { X;if( classPLevel == 1 ) return PROTECTED; }
+<IN_CLASS>"private" { X;if( classPLevel == 1 ) return PRIVATE; }
+<IN_CLASS>"tqsignals" { X;if( classPLevel == 1 ) return SIGNALS; }
+<IN_CLASS>"tqslots" { X;if( classPLevel == 1 ) return SLOTS; }
+<IN_CLASS>"TQ_CLASSINFO" { X;if( classPLevel == 1 ) return TQ_CLASSINFO; }
+<IN_CLASS>"TQ_OBJECT" { X;
+ if ( classPLevel == 1 )
+ return TQ_OBJECT;
+ else if ( classPLevel > 1 )
+ tqmoc_warn( "Cannot use TQ_OBJECT in nested class." );
+ }
+<IN_CLASS>"Q_PROPERTY" { X;if( classPLevel == 1 ) return Q_PROPERTY; }
+<IN_CLASS>"TQ_OVERRIDE" { X;if( classPLevel == 1 ) return TQ_OVERRIDE; }
+<IN_CLASS>"TQ_ENUMS" { X;if( classPLevel == 1 ) return TQ_ENUMS; }
+<IN_CLASS>"TQ_SETS" { X;if( classPLevel == 1 ) return TQ_SETS; }
+
+<IN_NAMESPACE>"{" { namespacePLevel++;Y; }
+<IN_NAMESPACE>"}" { namespacePLevel--;Y;if (namespacePLevel == 0)
+ {X;return '}';}}
+<IN_NAMESPACE>"class" { X;
+ BEGIN TQT_DEF;
+ return CLASS; }
+<IN_NAMESPACE>"template" { X;
+ BEGIN TQT_DEF;
+ return TEMPLATE; }
+<IN_NAMESPACE>"namespace" { X;
+ BEGIN TQT_DEF;
+ return NAMESPACE; }
+<IN_NAMESPACE>"using" { X;
+ BEGIN TQT_DEF;
+ return USING; }
+
+<IN_PROPERTY>"(" { X; return '('; }
+<IN_PROPERTY>")" { X; return ')'; }
+<IN_PROPERTY>"READ" { X; return READ; }
+<IN_PROPERTY>"WRITE" { X; return WRITE; }
+<IN_PROPERTY>"STORED" { X; return STORED; }
+<IN_PROPERTY>"RESET" { X; return RESET; }
+<IN_PROPERTY>"DESIGNABLE" { X; return DESIGNABLE; }
+<IN_PROPERTY>"SCRIPTABLE" { X; return SCRIPTABLE; }
+
+
+<IN_EXPR>"(" { expLevel++;X; }
+<IN_EXPR>")" { expLevel--;Y;if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ')';} }
+<IN_EXPR>"[" { expLevel++;X; }
+<IN_EXPR>"]" { expLevel--;X;if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ']';} }
+<IN_EXPR>"," { if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ',' ;} }
+<IN_EXPR>";" { if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ';' ;} }
+<IN_DEF_ARG>"(" { expLevel++;X; }
+<IN_DEF_ARG>")" { expLevel--;Y;if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ')';} }
+<IN_DEF_ARG>"[" { expLevel++;X; }
+<IN_DEF_ARG>"]" { expLevel--;X;if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ']';} }
+<IN_DEF_ARG>"," { if (expLevel <= 1)
+ { X; BEGIN TQT_DEF; return ',' ;} }
+<IN_DEF_ARG>";" { if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ';' ;} }
+<IN_ENUM>"(" { enumLevel++;X; }
+<IN_ENUM>")" { enumLevel--;X; }
+<IN_ENUM>"[" { enumLevel++;X; }
+<IN_ENUM>"]" { enumLevel--;X }
+<IN_ENUM>"," { if (enumLevel == 0)
+ { X; BEGIN TQT_DEF; return ',' ;} }
+<IN_ENUM>";" { if (enumLevel == 0)
+ { X; BEGIN TQT_DEF; return ';' ;} }
+<IN_ENUM>"}" { if (enumLevel == 0)
+ { X; BEGIN TQT_DEF; return '}' ;} }
+<IN_TEMPL_ARGS>[[(<] { templLevel++;
+ Y;
+ addExpressionChar( yytext[0] );
+ }
+<IN_TEMPL_ARGS>[])>] { templLevel--;
+ Y;
+ if ( templLevel == 0 ) {
+ X;
+ BEGIN TQT_DEF;
+ return yytext[0];
+ } else {
+ addExpressionChar( yytext[0] );
+ }
+ }
+<TQT_DEF>"friend" { X;return FRIEND; }
+<TQT_DEF>"typedef" { X;return TYPEDEF; }
+<TQT_DEF>"auto" { X;return AUTO; }
+<TQT_DEF>"register" { X;return REGISTER; }
+<TQT_DEF>"static" { X;return STATIC; }
+<TQT_DEF>"extern" { X;return EXTERN; }
+<TQT_DEF>"inline" { X;return INLINE; }
+<TQT_DEF>"__inline__" { X;return INLINE; }
+<TQT_DEF>"virtual" { X;return VIRTUAL; }
+<TQT_DEF>"const" { X;return CONST; }
+<TQT_DEF>"volatile" { X;return VOLATILE; }
+<TQT_DEF>"char" { X;return CHAR; }
+<TQT_DEF>"short" { X;return SHORT; }
+<TQT_DEF>"int" { X;return INT; }
+<TQT_DEF>"long" { X;return LONG; }
+<TQT_DEF>"signed" { X;return SIGNED; }
+<TQT_DEF>"unsigned" { X;return UNSIGNED; }
+<TQT_DEF>"float" { X;return FLOAT; }
+<TQT_DEF>"double" { X;return DOUBLE; }
+<TQT_DEF>"void" { X;return VOID; }
+<TQT_DEF>"enum" { X;return ENUM; }
+<TQT_DEF>"class" { X;return CLASS; }
+<TQT_DEF>"struct" { X;return STRUCT; }
+<TQT_DEF>"union" { X;return UNION; }
+<TQT_DEF>"asm" { X;return ASM; }
+<TQT_DEF>"private" { X;return PRIVATE; }
+<TQT_DEF>"protected" { X;return PROTECTED; }
+<TQT_DEF>"public" { X;return PUBLIC; }
+<TQT_DEF>"operator" { X;return OPERATOR; }
+<TQT_DEF>"::" { X;return DBL_COLON; }
+<TQT_DEF>"..." { X;return TRIPLE_DOT; }
+<TQT_DEF>"template" { X;return TEMPLATE; }
+<TQT_DEF>"mutable" { X;return MUTABLE; }
+<TQT_DEF>"throw" { X;return THROW; }
+<TQT_DEF>"using" { X;return USING; }
+<TQT_DEF>"namespace" { X;return NAMESPACE; }
+
+<TQT_DEF>[_a-zA-Z][_a-zA-Z0-9]* {
+ X;
+ yylval.string = qstrdup(yytext);
+ return IDENTIFIER;
+ }
+
+<IN_PROPERTY>[_a-zA-Z][_a-zA-Z0-9]* {
+ X;
+ yylval.string = qstrdup(yytext);
+ return IDENTIFIER;
+ }
+
+<IN_CLASSINFO>"(" { X; return '('; }
+<IN_CLASSINFO>")" { X; return ')'; }
+<IN_CLASSINFO>"," { X; return ','; }
+
+<IN_CLASSINFO>{ALMOSTSTRING} {
+ X;
+ yylval.string = qstrdup( yytext + 1 );
+ input(); /* discard the '"' */
+ return STRING;
+ }
+
+<OUTSIDE>[_a-zA-Z][_a-zA-Z0-9]* ;
+<IN_CLASS>[_a-zA-Z][_a-zA-Z0-9]* ;
+<IN_NAMESPACE>[_a-zA-Z][_a-zA-Z0-9]* ;
+
+<OUTSIDE>{STRING} { /* discard strings */
+ Z;
+ }
+
+<IN_CLASS>{STRING} { /* discard strings */
+ Z;
+ }
+
+<IN_NAMESPACE>{STRING} { /* discard strings */
+ Z;
+ }
+
+<IN_FCT>{ALMOSTSTRING} { /* discard strings */
+ Z;
+ addExpressionString( yytext );
+ input(); /* discard the '"' */
+ }
+
+
+<IN_TEMPL_ARGS>{ALMOSTSTRING} {
+ X;
+ addExpressionString( yytext );
+ input(); /* discard the '"' */
+ return STRING;
+ }
+
+<TQT_DEF>{ALMOSTSTRING} {
+ X;
+ yylval.string = qstrdup( yytext + 1 );
+ input(); /* discard the '"' */
+ return STRING;
+ }
+
+<TQT_DEF>'.' { X;
+ yylval.char_val = yytext[1];
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\a' { X;
+ yylval.char_val = '\a';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\b' { X;
+ yylval.char_val = '\b';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\f' { X;
+ yylval.char_val = '\f';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\n' { X;
+ yylval.char_val = '\n';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\r' { X;
+ yylval.char_val = '\r';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\t' { X;
+ yylval.char_val = '\t';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\v' { X;
+ yylval.char_val = '\v';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\\\' { X;
+ yylval.char_val = '\\';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\?' { X;
+ yylval.char_val = '\?';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\'' { X;
+ yylval.char_val = '\'';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\\"' { X;
+ yylval.char_val = '\"'; /* " */
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\0' { X;
+ yylval.char_val = '\0';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\[0-7]+' { X;
+ yylval.char_val =
+ (char)strtol( &yytext[1], 0, 8 );
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\x[0-9a-fA-F]+' { X;
+ yylval.char_val =
+ (char)strtol( &yytext[2], 0, 16 );
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>'\\.' { X;
+ yylval.char_val = ' ';
+ return CHAR_VAL;
+ }
+
+<TQT_DEF>[0-9]+ { X;
+ yylval.int_val = atoi(yytext);
+ return INT_VAL;
+ }
+
+<TQT_DEF>[0-9]+\.[0-9]* { X;
+ yylval.double_val = atof(yytext);
+ return DOUBLE_VAL;
+ }
+
+<TQT_DEF>\.[0-9]+ { X;
+ yylval.double_val = atof(yytext);
+ return DOUBLE_VAL;
+ }
+
+
+^#define.*\\$ { /* skip multi-line macro-definitions */
+ int c, c1;
+ input(); /* Discard the '\n'. */
+ do {
+ c1=' ';
+ while((c = linput()) != '\n' && c != 0) c1=c;
+ if (c == 0) break;
+ } while(c1=='\\');
+ unput(c); /* put back the '\n' or the EOF */
+ }
+
+^[ \t]*#.* { /* preprocessor commands are skipped */}
+"//"[^\n]* { /* C++ comment */
+ TQCString s = yytext;
+ if ( s.tqcontains( "TQMOC_SKIP_BEGIN" ) ) {
+ skipLevel++;
+ if ( skipLevel == 1 ) {
+ lastState = YYSTATE;
+ BEGIN SKIP;
+ }
+ } else
+ if ( s.tqcontains( "TQMOC_SKIP_END" ) ) {
+ if ( skipLevel == 0 ) {
+ tqmoc_warn(" TQMOC_SKIP_END without TQMOC_SKIP_BEGIN");
+ } else {
+ skipLevel--;
+ if ( skipLevel == 0 ) {
+ BEGIN lastState;
+ }
+ }
+ }
+ }
+"/*" { /* C comment */
+ int c = ' ';
+ do {
+ if ( c!= '*' ) {
+ while((c = linput()) != '*' && c != 0)
+ ;
+ }
+ if (c == 0) break;
+ } while(((c = linput())) != '/' && c != 0);
+ if (c == 0)
+ unput(c);
+ }
+
+<IN_TEMPL_ARGS>. { addExpressionChar( yytext[0] ); }
+
+<IN_TEMPL_ARGS>[ \t\r\b\f]+ {
+ /* spaces are important in template args,
+ e.g. Foo<const int> */
+ addExpressionChar( yytext[0] ); }
+[ \t\r\b\f]+ ;
+<IN_CLASS>. ;
+<IN_NAMESPACE>. ;
+<IN_FCT>. ;
+<IN_EXPR>. { addExpressionChar( yytext[0] ); }
+<IN_DEF_ARG>. ;
+<IN_ENUM>. { addExpressionChar( yytext[0] ); }
+<OUTSIDE>. ;
+<SKIP>. ;
+<TQT_DEF>. {
+ X;
+ return yytext[0];
+ }
+<GIMME_SEMICOLON>. {
+ X;
+ return ';';
+ }
+\n {
+ lineNo++;
+ }
+
+
+%%
+
+#endif // TQMOC_YACC_CODE
diff --git a/tqtinterface/qt4/src/tqmoc/tqmoc.pro b/tqtinterface/qt4/src/tqmoc/tqmoc.pro
new file mode 100644
index 0000000..559bbbc
--- /dev/null
+++ b/tqtinterface/qt4/src/tqmoc/tqmoc.pro
@@ -0,0 +1,65 @@
+TEMPLATE = app
+TARGET = tqmoc
+
+CONFIG = console release qtinc yacc lex_included yacc_no_name_mangle
+DEFINES += TQT_TQMOC TQT_NO_CODECS TQT_LITE_UNICODE TQT_NO_COMPONENT \
+ TQT_NO_STL TQT_NO_COMPRESS
+win32:DEFINES += TQT_NODLL
+DESTDIR = ../../bin
+
+
+INCLUDEPATH += $$TQT_SOURCE_TREE/include ../tools .
+DEPENDPATH += $$TQT_SOURCE_TREE/include ../tools .
+LIBS =
+OBJECTS_DIR = .
+SOURCES = ../tools/tqbuffer.cpp \
+ ../tools/tqptrcollection.cpp \
+ ../tools/tqcstring.cpp \
+ ../tools/tqdatastream.cpp \
+ ../tools/tqdatetime.cpp \
+ ../tools/tqfile.cpp \
+ ../tools/tqdir.cpp \
+ ../tools/tqfileinfo.cpp \
+ ../tools/tqgarray.cpp \
+ ../tools/tqgdict.cpp \
+ ../tools/tqglist.cpp \
+ ../tools/tqglobal.cpp \
+ ../tools/tqgvector.cpp \
+ ../tools/tqiodevice.cpp \
+ ../tools/tqregexp.cpp \
+ ../tools/tqstring.cpp \
+ ../tools/tqlocale.cpp \
+ ../tools/tqunicodetables.cpp \
+ ../tools/tqstringlist.cpp \
+ ../tools/tqtextstream.cpp \
+ ../tools/tqbitarray.cpp \
+ ../tools/tqmap.cpp \
+ ../tools/tqgcache.cpp \
+ ../codecs/tqtextcodec.cpp \
+ ../codecs/tqutfcodec.cpp
+
+isEmpty(TQT_PRODUCT)|tqcontains(TQT_PRODUCT, qt-internal) {
+ LEXSOURCES = tqmoc.l
+ YACCSOURCES = tqmoc.y
+} else {
+ SOURCES += tqmoc_yacc.cpp
+}
+
+unix:SOURCES += ../tools/tqfile_unix.cpp ../tools/tqdir_unix.cpp ../tools/tqfileinfo_unix.cpp
+win32:SOURCES += ../tools/tqfile_win.cpp ../tools/tqdir_win.cpp ../tools/tqfileinfo_win.cpp
+macx:LIBS += -framework Carbon
+
+target.path=$$bins.path
+INSTALLS += target
+
+*-mwerks {
+ TEMPLATE = lib
+ TARGET = McMoc
+ CONFIG -= static
+ CONFIG += shared plugin
+ DEFINES += TQMOC_MWERKS_PLUGIN
+ MWERKSDIR = $TQT_SOURCE_TREE/util/mwerks_plugin
+ INCLUDEPATH += $$MWERKSDIR/Headers
+ LIBS += $$MWERKSDIR/Libraries/PluginLib4.shlb
+ SOURCES += mwerks_mac.cpp
+}
diff --git a/tqtinterface/qt4/src/tqmoc/tqmoc.y b/tqtinterface/qt4/src/tqmoc/tqmoc.y
new file mode 100644
index 0000000..69ac269
--- /dev/null
+++ b/tqtinterface/qt4/src/tqmoc/tqmoc.y
@@ -0,0 +1,3636 @@
+/****************************************************************************
+**
+** Parser and code generator for meta object compiler
+**
+** Created : 930417
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the TQ Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+** --------------------------------------------------------------------------
+**
+** This compiler reads a C++ header file with class definitions and ouputs
+** C++ code to build a meta class. The meta data includes public methods
+** (not constructors, destructors or operator functions), tqsignals and slot
+** definitions. The output file should be compiled and linked into the
+** target application.
+**
+** C++ header files are assumed to have correct syntax, and we are therefore
+** doing less strict checking than C++ compilers.
+**
+** The C++ grammar has been adopted from the "The Annotated C++ Reference
+** Manual" (ARM), by Ellis and Stroustrup (Addison Wesley, 1992).
+**
+** Notice that this code is not possible to compile with GNU bison, instead
+** use standard AT&T yacc or Berkeley yacc.
+*****************************************************************************/
+
+%{
+#define TQMOC_YACC_CODE
+void yyerror( const char *msg );
+
+#include "tqplatformdefs.h"
+#include "tqasciidict.h"
+#include "tqdatetime.h"
+#include "tqdict.h"
+#include "tqfile.h"
+#include "tqdir.h"
+#include "tqptrlist.h"
+#include "tqregexp.h"
+#include "tqstrlist.h"
+#ifdef TQMOC_MWERKS_PLUGIN
+# ifdef TQ_OS_MACX
+# undef OLD_DEBUG
+# ifdef DEBUG
+# define OLD_DEBUG DEBUG
+# undef DEBUG
+# endif
+# define DEBUG 0
+# ifndef __IMAGECAPTURE__
+# define __IMAGECAPTURE__
+# endif
+# include <Carbon/Carbon.h>
+# endif
+# include "mwerks_mac.h"
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined CONST
+#undef CONST
+#endif
+#if defined VOID
+#undef VOID
+#endif
+
+bool isEnumType( const char* type );
+int enumIndex( const char* type );
+bool isVariantType( const char* type );
+int qvariant_nameToType( const char* name );
+static void init(); // initialize
+static void initClass(); // prepare for new class
+static void generateClass(); // generate C++ code for class
+static void initExpression(); // prepare for new expression
+static void enterNameSpace( const char *name = 0 );
+static void leaveNameSpace();
+static void selectOutsideClassState();
+static void registerClassInNamespace();
+static bool suppress_func_warn = FALSE;
+static void func_warn( const char *msg );
+static void tqmoc_warn( const char *msg );
+static void tqmoc_err( const char *s );
+static void tqmoc_err( const char *s1, const char *s2 );
+static void operatorError();
+static void checkPropertyName( const char* ident );
+
+static const char* const utype_map[] =
+{
+ "bool",
+ "int",
+ "double",
+ "TQString",
+ "TQVariant",
+ 0
+};
+
+inline bool isIdentChar( char x )
+{ // Avoid bug in isalnum
+ return x == '_' || (x >= '0' && x <= '9') ||
+ (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z');
+}
+
+bool validUType( TQCString ctype )
+{
+ if ( ctype.left(6) == "const " )
+ ctype = ctype.mid( 6, ctype.length() - 6 );
+ if ( ctype.right(1) == "&" )
+ ctype = ctype.left( ctype.length() - 1 );
+ else if ( ctype.right(1) == "*" )
+ return TRUE;
+
+ int i = -1;
+ while ( utype_map[++i] )
+ if ( ctype == utype_map[i] )
+ return TRUE;
+
+ return isEnumType( ctype );
+}
+
+TQCString castToUType( TQCString ctype )
+{
+ if ( ctype.right(1) == "&" )
+ ctype = ctype.left( ctype.length() - 1 );
+ if( ctype.right(1) == "]") {
+ int lb = ctype.tqfindRev('[');
+ if(lb != -1)
+ ctype = ctype.left(lb) + "*";
+ }
+ return ctype;
+}
+
+TQCString rawUType( TQCString ctype )
+{
+ ctype = castToUType( ctype );
+ if ( ctype.left(6) == "const " )
+ ctype = ctype.mid( 6, ctype.length() - 6 );
+ return ctype;
+}
+
+TQCString uType( TQCString ctype )
+{
+ if ( !validUType( ctype ) ) {
+ if ( isVariantType( rawUType(ctype) ) )
+ return "varptr";
+ else
+ return "ptr";
+ }
+ if ( ctype.left(6) == "const " )
+ ctype = ctype.mid( 6, ctype.length() - 6 );
+ if ( ctype.right(1) == "&" ) {
+ ctype = ctype.left( ctype.length() - 1 );
+ } else if ( ctype.right(1) == "*" ) {
+ TQCString raw = ctype.left( ctype.length() - 1 );
+ ctype = "ptr";
+ if ( raw == "char" )
+ ctype = "charstar";
+ else if ( raw == "TQUnknownInterface" )
+ ctype = "iface";
+ else if ( raw == "TQDispatchInterface" )
+ ctype = "idisp";
+ else if ( isVariantType( raw ) )
+ ctype = "varptr";
+ }
+ if ( isEnumType( ctype ) )
+ ctype = "enum";
+ return ctype;
+}
+
+bool isInOut( TQCString ctype )
+{
+ if ( ctype.left(6) == "const " )
+ return FALSE;
+ if ( ctype.right(1) == "&" )
+ return TRUE;
+ if ( ctype.right(2) == "**" )
+ return TRUE;
+ return FALSE;
+}
+
+TQCString uTypeExtra( TQCString ctype )
+{
+ TQCString typeExtra = "0";
+ if ( !validUType( ctype ) ) {
+ if ( isVariantType( rawUType(ctype) ) )
+ typeExtra.sprintf("\"\\x%02x\"", qvariant_nameToType( rawUType(ctype) ) );
+ else
+ typeExtra.sprintf( "\"%s\"", rawUType(ctype).data() );
+ return typeExtra;
+ }
+ if ( ctype.left(6) == "const " )
+ ctype = ctype.mid( 6, ctype.length() - 6 );
+ if ( ctype.right(1) == "&" )
+ ctype = ctype.left( ctype.length() - 1 );
+ if ( ctype.right(1) == "*" ) {
+ TQCString raw = ctype.left( ctype.length() - 1 );
+ ctype = "ptr";
+ if ( raw == "char" )
+ ;
+ else if ( isVariantType( raw ) )
+ typeExtra.sprintf("\"\\x%02x\"", qvariant_nameToType( raw ) );
+ else
+ typeExtra.sprintf( "\"%s\"", raw.stripWhiteSpace().data() );
+
+ } else if ( isEnumType( ctype ) ) {
+ int idx = enumIndex( ctype );
+ if ( idx >= 0 ) {
+ typeExtra.sprintf( "&enum_tbl[%d]", enumIndex( ctype ) );
+ } else {
+ typeExtra.sprintf( "parentObject->enumerator(\"%s\", TRUE )", ctype.data() );
+ }
+ typeExtra =
+ "\n#ifndef TQT_NO_PROPERTIES\n\t " + typeExtra +
+ "\n#else"
+ "\n\t 0"
+ "\n#endif // TQT_NO_PROPERTIES\n\t ";
+ }
+ return typeExtra;
+}
+
+/*
+ Attention!
+ This table is copied from qvariant.cpp. If you change
+ one, change both.
+*/
+static const int ntypes = 35;
+static const char* const type_map[ntypes] =
+{
+ 0,
+ "TQMap<TQString,TQVariant>",
+ "TQValueList<TQVariant>",
+ "TQString",
+ "TQStringList",
+ "TQFont",
+ "TQPixmap",
+ "TQBrush",
+ "TQRect",
+ "TQSize",
+ "TQColor",
+ "TQPalette",
+ "TQColorGroup",
+ "TQIconSet",
+ "TQPoint",
+ "TQImage",
+ "int",
+ "uint",
+ "bool",
+ "double",
+ "TQCString",
+ "TQPointArray",
+ "TQRegion",
+ "TQBitmap",
+ "TQCursor",
+ "TQSizePolicy",
+ "TQDate",
+ "TQTime",
+ "TQDateTime",
+ "TQByteArray",
+ "TQBitArray",
+ "TQKeySequence",
+ "TQPen",
+ "TQ_LLONG",
+ "TQ_ULLONG"
+};
+
+int qvariant_nameToType( const char* name )
+{
+ for ( int i = 0; i < ntypes; i++ ) {
+ if ( !qstrcmp( type_map[i], name ) )
+ return i;
+ }
+ return 0;
+}
+
+/*
+ Returns TRUE if the type is a TQVariant types.
+*/
+bool isVariantType( const char* type )
+{
+ return qvariant_nameToType( type ) != 0;
+}
+
+/*
+ Replaces '>>' with '> >' (as in 'TQValueList<TQValueList<double> >').
+ This function must be called to produce valid C++ code. However,
+ the string representation still uses '>>'.
+*/
+void fixRightAngles( TQCString *str )
+{
+ str->tqreplace( TQRegExp(">>"), "> >" );
+}
+
+static TQCString rmWS( const char * );
+
+enum Access { Private, Protected, Public };
+
+
+class Argument // single arg meta data
+{
+public:
+ Argument( const char *left, const char *right, const char* argName = 0, bool isDefaultArgument = FALSE )
+ {
+ leftType = rmWS( left );
+ rightType = rmWS( right );
+ if ( leftType == "void" && rightType.isEmpty() )
+ leftType = "";
+
+ int len = leftType.length();
+
+ /*
+ Convert 'char const *' into 'const char *'. Start at index 1,
+ not 0, because 'const char *' is already OK.
+ */
+ for ( int i = 1; i < len; i++ ) {
+ if ( leftType[i] == 'c' &&
+ strncmp(leftType.data() + i + 1, "onst", 4) == 0
+ && (i + 5 >= len || !isIdentChar(leftType[i + 5]))
+ && !isIdentChar(i-1)
+ ) {
+ leftType.remove( i, 5 );
+ if ( leftType[i - 1] == ' ' )
+ leftType.remove( i - 1, 1 );
+ leftType.prepend( "const " );
+ break;
+ }
+
+ /*
+ We musn't convert 'char * const *' into 'const char **'
+ and we must beware of 'Bar<const Bla>'.
+ */
+ if ( leftType[i] == '&' || leftType[i] == '*' ||
+ leftType[i] == '<' )
+ break;
+ }
+
+ name = argName;
+ isDefault = isDefaultArgument;
+ }
+
+ TQCString leftType;
+ TQCString rightType;
+ TQCString name;
+ bool isDefault;
+};
+
+class ArgList : public TQPtrList<Argument> { // member function arg list
+public:
+ ArgList() { setAutoDelete( TRUE ); }
+ ~ArgList() { clear(); }
+
+ /* the clone has one default argument less, the orignal has all default arguments removed */
+ ArgList* magicClone() {
+ ArgList* l = new ArgList;
+ bool firstDefault = FALSE;
+ for ( first(); current(); next() ) {
+ bool isDefault = current()->isDefault;
+ if ( !firstDefault && isDefault ) {
+ isDefault = FALSE;
+ firstDefault = TRUE;
+ }
+ l->append( new Argument( current()->leftType, current()->rightType, current()->name, isDefault ) );
+ }
+ for ( first(); current(); ) {
+ if ( current()->isDefault )
+ remove();
+ else
+ next();
+ }
+ return l;
+ }
+
+ bool hasDefaultArguments() {
+ for ( Argument* a = first(); a; a = next() ) {
+ if ( a->isDefault )
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+};
+
+
+struct Function // member function meta data
+{
+ Access access;
+ TQCString qualifier; // const or volatile
+ TQCString name;
+ TQCString type;
+ TQCString signature;
+ int lineNo;
+ ArgList *args;
+ Function() { args=0;}
+ ~Function() { delete args; }
+ const char* accessAsString() {
+ switch ( access ) {
+ case Private: return "Private";
+ case Protected: return "Protected";
+ default: return "Public";
+ }
+ }
+};
+
+class FuncList : public TQPtrList<Function> { // list of member functions
+public:
+ FuncList( bool autoDelete = FALSE ) { setAutoDelete( autoDelete ); }
+
+ FuncList tqfind( const char* name )
+ {
+ FuncList result;
+ for ( TQPtrListIterator<Function> it(*this); it.current(); ++it ) {
+ if ( it.current()->name == name )
+ result.append( it.current() );
+ }
+ return result;
+ }
+};
+
+class Enum : public TQStrList
+{
+public:
+ TQCString name;
+ bool set;
+};
+
+class EnumList : public TQPtrList<Enum> { // list of property enums
+public:
+ EnumList() { setAutoDelete(TRUE); }
+};
+
+
+struct Property
+{
+ Property( int l, const char* t, const char* n, const char* s, const char* g, const char* r,
+ const TQCString& st, const TQCString& d, const TQCString& sc, bool ov )
+ : lineNo(l), type(t), name(n), set(s), get(g), reset(r), setfunc(0), getfunc(0),
+ sspec(Unspecified), gspec(Unspecified), stored( st ),
+ designable( d ), scriptable( sc ), override( ov ), oredEnum( -1 )
+ {
+ /*
+ The Q_PROPERTY construct cannot contain any commas, since
+ commas separate macro arguments. We therefore expect users
+ to type "TQMap" instead of "TQMap<TQString, TQVariant>". For
+ coherence, we also expect the same for
+ TQValueList<TQVariant>, the other template class supported by
+ TQVariant.
+ */
+ if ( type == "TQMap" ) {
+ type = "TQMap<TQString,TQVariant>";
+ } else if ( type == "TQValueList" ) {
+ type = "TQValueList<TQVariant>";
+ } else if ( type == "LongLong" ) {
+ type = "TQ_LLONG";
+ } else if ( type == "ULongLong" ) {
+ type = "TQ_ULLONG";
+ }
+ }
+
+ int lineNo;
+ TQCString type;
+ TQCString name;
+ TQCString set;
+ TQCString get;
+ TQCString reset;
+ TQCString stored;
+ TQCString designable;
+ TQCString scriptable;
+ bool override;
+
+ Function* setfunc;
+ Function* getfunc;
+
+ int oredEnum; // If the enums item may be ored. That means the data type is int.
+ // Allowed values are 1 (True), 0 (False), and -1 (Unset)
+ TQCString enumsettype; // tqcontains the set function type in case of oredEnum
+ TQCString enumgettype; // tqcontains the get function type in case of oredEnum
+
+ enum Specification { Unspecified, Class, Reference, Pointer, ConstCharStar };
+ Specification sspec;
+ Specification gspec;
+
+ bool stdSet() {
+ TQCString s = "set";
+ s += toupper( name[0] );
+ s += name.mid( 1 );
+ return s == set;
+ }
+
+ static const char* specToString( Specification s )
+ {
+ switch ( s ) {
+ case Class:
+ return "Class";
+ case Reference:
+ return "Reference";
+ case Pointer:
+ return "Pointer";
+ case ConstCharStar:
+ return "ConstCharStar";
+ default:
+ return "Unspecified";
+ }
+ }
+};
+
+class PropList : public TQPtrList<Property> { // list of properties
+public:
+ PropList() { setAutoDelete( TRUE ); }
+};
+
+
+struct ClassInfo
+{
+ ClassInfo( const char* n, const char* v )
+ : name(n), value(v)
+ {}
+ TQCString name;
+ TQCString value;
+};
+
+class ClassInfoList : public TQPtrList<ClassInfo> { // list of class infos
+public:
+ ClassInfoList() { setAutoDelete( TRUE ); }
+};
+
+class parser_reg {
+ public:
+ parser_reg();
+ ~parser_reg();
+
+ // some temporary values
+ TQCString tmpExpression; // Used to store the characters the lexer
+ // is currently skipping (see addExpressionChar and friends)
+ TQCString fileName; // file name
+ TQCString outputFile; // output file name
+ TQCString pchFile; // name of PCH file (used on Windows)
+ TQStrList includeFiles; // name of #include files
+ TQCString includePath; // #include file path
+ TQCString qtPath; // #include qt file path
+ int gen_count; //number of classes generated
+ bool noInclude; // no #include <filename>
+ bool generatedCode; // no code generated
+ bool tqmocError; // tqmoc parsing error occurred
+ bool hasVariantIncluded; //whether or not qvariant.h was included yet
+ TQCString className; // name of parsed class
+ TQCString superClassName; // name of first super class
+ TQStrList multipleSuperClasses; // other superclasses
+ FuncList tqsignals; // signal interface
+ FuncList tqslots; // tqslots interface
+ FuncList propfuncs; // all possible property access functions
+ FuncList funcs; // all parsed functions, including tqsignals
+ EnumList enums; // enums used in properties
+ PropList props; // list of all properties
+ ClassInfoList infos; // list of all class infos
+
+// Used to store the values in the Q_PROPERTY macro
+ TQCString propWrite; // set function
+ TQCString propRead; // get function
+ TQCString propReset; // reset function
+ TQCString propStored; //
+ TQCString propDesignable; // "true", "false" or function or empty if not specified
+ TQCString propScriptable; // "true", "false" or function or empty if not specified
+ bool propOverride; // Wether OVERRIDE was detected
+
+ TQStrList qtEnums; // Used to store the contents of TQ_ENUMS
+ TQStrList qtSets; // Used to store the contents of TQ_SETS
+
+};
+
+static parser_reg *g = 0;
+
+ArgList *addArg( Argument * ); // add arg to tmpArgList
+
+enum Member { SignalMember,
+ SlotMember,
+ PropertyCandidateMember
+ };
+
+void addMember( Member ); // add tmpFunc to current class
+void addEnum(); // add tmpEnum to current class
+
+char *stradd( const char *, const char * ); // add two strings
+char *stradd( const char *, const char *, // add three strings
+ const char * );
+char *stradd( const char *, const char *, // adds 4 strings
+ const char *, const char * );
+
+char *straddSpc( const char *, const char * );
+char *straddSpc( const char *, const char *,
+ const char * );
+char *straddSpc( const char *, const char *,
+ const char *, const char * );
+
+extern int yydebug;
+bool lexDebug = FALSE;
+int lineNo; // current line number
+bool errorControl = FALSE; // controled errors
+bool displayWarnings = TRUE;
+bool skipClass; // don't generate for class
+bool skipFunc; // don't generate for func
+bool templateClass; // class is a template
+bool templateClassOld; // previous class is a template
+
+ArgList *tmpArgList; // current argument list
+Function *tmpFunc; // current member function
+Enum *tmpEnum; // current enum
+Access tmpAccess; // current access permission
+Access subClassPerm; // current access permission
+
+bool TQ_OBJECTdetected; // TRUE if current class
+ // tqcontains the TQ_OBJECT macro
+bool Q_PROPERTYdetected; // TRUE if current class
+ // tqcontains at least one Q_PROPERTY,
+ // TQ_OVERRIDE, TQ_SETS or TQ_ENUMS macro
+bool tmpPropOverride; // current property override setting
+
+int tmpYYStart; // Used to store the lexers current mode
+int tmpYYStart2; // Used to store the lexers current mode
+ // (if tmpYYStart is already used)
+
+// if the format revision changes, you MUST change it in qmetaobject.h too
+const int formatRevision = 26; // tqmoc output format revision
+
+// if the flags change, you HAVE to change it in qmetaobject.h too
+enum Flags {
+ Invalid = 0x00000000,
+ Readable = 0x00000001,
+ Writable = 0x00000002,
+ EnumOrSet = 0x00000004,
+ UnresolvedEnum = 0x00000008,
+ StdSet = 0x00000100,
+ Override = 0x00000200,
+ NotDesignable = 0x00001000,
+ DesignableOverride = 0x00002000,
+ NotScriptable = 0x00004000,
+ ScriptableOverride = 0x00008000,
+ NotStored = 0x00010000,
+ StoredOverride = 0x00020000
+};
+
+
+#ifdef YYBISON
+# if defined(TQ_OS_WIN32)
+# include <io.h>
+# undef isatty
+extern "C" int hack_isatty( int )
+ {
+ return 0;
+ }
+# define isatty hack_isatty
+# else
+# include <unistd.h>
+# endif
+
+# define YYDEBUG 1
+# include "tqmoc_yacc.h"
+# include "tqmoc_lex.cpp"
+#endif //YYBISON
+%}
+
+
+
+
+%union {
+ char char_val;
+ int int_val;
+ double double_val;
+ char *string;
+ Access access;
+ Function *function;
+ ArgList *arg_list;
+ Argument *arg;
+}
+
+%start declaration_seq
+
+%token <char_val> CHAR_VAL /* value types */
+%token <int_val> INT_VAL
+%token <double_val> DOUBLE_VAL
+%token <string> STRING
+%token <string> IDENTIFIER /* identifier string */
+
+%token FRIEND /* declaration keywords */
+%token TYPEDEF
+%token AUTO
+%token REGISTER
+%token STATIC
+%token EXTERN
+%token INLINE
+%token VIRTUAL
+%token CONST
+%token VOLATILE
+%token CHAR
+%token SHORT
+%token INT
+%token LONG
+%token SIGNED
+%token UNSIGNED
+%token FLOAT
+%token DOUBLE
+%token VOID
+%token ENUM
+%token CLASS
+%token STRUCT
+%token UNION
+%token ASM
+%token PRIVATE
+%token PROTECTED
+%token PUBLIC
+%token OPERATOR
+%token DBL_COLON
+%token TRIPLE_DOT
+%token TEMPLATE
+%token NAMESPACE
+%token USING
+%token MUTABLE
+%token THROW
+
+%token SIGNALS
+%token SLOTS
+%token TQ_OBJECT
+%token Q_PROPERTY
+%token TQ_OVERRIDE
+%token TQ_CLASSINFO
+%token TQ_ENUMS
+%token TQ_SETS
+
+%token READ
+%token WRITE
+%token STORED
+%token DESIGNABLE
+%token SCRIPTABLE
+%token RESET
+
+%type <string> class_name
+%type <string> template_class_name
+%type <string> template_spec
+%type <string> opt_base_spec
+
+%type <string> base_spec
+%type <string> base_list
+%type <string> qt_macro_name
+%type <string> base_specifier
+%type <access> access_specifier
+%type <string> fct_name
+%type <string> type_name
+%type <string> simple_type_names
+%type <string> simple_type_name
+%type <string> class_key
+%type <string> complete_class_name
+%type <string> qualified_class_name
+%type <string> elaborated_type_specifier
+%type <string> whatever
+
+%type <arg_list> argument_declaration_list
+%type <arg_list> arg_declaration_list
+%type <arg_list> arg_declaration_list_opt
+%type <string> abstract_decl_opt
+%type <string> abstract_decl
+%type <arg> argument_declaration
+%type <arg> opt_exception_argument
+%type <string> cv_qualifier_list_opt
+%type <string> cv_qualifier_list
+%type <string> cv_qualifier
+%type <string> decl_specifiers
+%type <string> decl_specifier
+%type <string> decl_specs_opt
+%type <string> decl_specs
+%type <string> type_specifier
+%type <string> fct_specifier
+%type <string> declarator
+%type <string> ptr_operator
+%type <string> ptr_operators
+%type <string> ptr_operators_opt
+
+%type <string> dname
+
+%%
+declaration_seq: /* empty */
+ | declaration_seq declaration
+ ;
+
+declaration: class_def
+/* | template_declaration */
+ | namespace_def
+ | namespace_alias_def
+ | using_declaration
+ | using_directive
+ ;
+
+namespace_def: named_namespace_def
+ | unnamed_namespace_def
+ ;
+
+named_namespace_def: NAMESPACE
+ IDENTIFIER { enterNameSpace($2); }
+ '{' { BEGIN IN_NAMESPACE; }
+ namespace_body
+ '}' { leaveNameSpace();
+ selectOutsideClassState();
+ }
+ ;
+
+unnamed_namespace_def: NAMESPACE { enterNameSpace(); }
+ '{' { BEGIN IN_NAMESPACE; }
+ namespace_body
+ '}' { leaveNameSpace();
+ selectOutsideClassState();
+ }
+ ;
+
+namespace_body: declaration_seq
+ ;
+
+namespace_alias_def: NAMESPACE IDENTIFIER '=' complete_class_name ';'
+ { selectOutsideClassState(); }
+ ;
+
+
+using_directive: USING NAMESPACE { selectOutsideClassState(); } /* Skip namespace */
+ ;
+
+using_declaration: USING IDENTIFIER { selectOutsideClassState(); }
+ | USING DBL_COLON { selectOutsideClassState(); }
+ ;
+
+class_def: { initClass(); }
+ class_specifier ';' { generateClass();
+ registerClassInNamespace();
+ selectOutsideClassState(); }
+ ;
+
+
+/***** r.17.1 (ARM p.387 ): Keywords *****/
+
+class_name: IDENTIFIER { $$ = $1; }
+ | template_class_name { $$ = $1; }
+ ;
+
+template_class_name: IDENTIFIER '<' template_args '>'
+ { g->tmpExpression = rmWS( g->tmpExpression );
+ $$ = stradd( $1, "<",
+ g->tmpExpression, ">" ); }
+ ;
+
+/*
+ template_args skips all characters until it encounters a ">" (it
+ handles and discards sublevels of parentheses). Since the rule is
+ empty it must be used with care!
+*/
+
+template_args: /* empty */ { initExpression();
+ templLevel = 1;
+ BEGIN IN_TEMPL_ARGS; }
+ ;
+
+/***** r.17.2 (ARM p.388): Expressions *****/
+
+
+/* const_expression skips all characters until it encounters either one
+ of "]", ")" or "," (it handles and discards sublevels of parentheses).
+ Since the rule is empty it must be used with care!
+*/
+
+const_expression: /* empty */ { initExpression();
+ BEGIN IN_EXPR; }
+ ;
+
+/* def_argument is just like const expression but handles the ","
+ slightly differently. It was added for 3.0 as quick solution. TODO:
+ merge with const_expression.
+ */
+
+def_argument: /* empty */ { BEGIN IN_DEF_ARG; }
+ ;
+
+enumerator_expression: /* empty */ { initExpression();
+ BEGIN IN_ENUM; }
+ ;
+
+/***** r.17.3 (ARM p.391): Declarations *****/
+
+decl_specifier: storage_class_specifier { $$ = ""; }
+ | type_specifier { $$ = $1; }
+ | fct_specifier { $$ = ""; }
+ | FRIEND { skipFunc = TRUE; $$ = ""; }
+ | TYPEDEF { skipFunc = TRUE; $$ = ""; }
+ ;
+
+decl_specifiers: decl_specs_opt type_name decl_specs_opt
+ { $$ = straddSpc($1,$2,$3); }
+ ;
+decl_specs_opt: /* empty */ { $$ = ""; }
+ | decl_specs { $$ = $1; }
+ ;
+
+decl_specs: decl_specifier { $$ = $1; }
+ | decl_specs decl_specifier { $$ = straddSpc($1,$2); }
+ ;
+
+storage_class_specifier: AUTO
+ | REGISTER
+ | STATIC { skipFunc = TRUE; }
+ | EXTERN
+ ;
+
+fct_specifier: INLINE { }
+ | VIRTUAL { }
+ ;
+
+type_specifier: CONST { $$ = "const"; }
+ | VOLATILE { $$ = "volatile"; }
+ ;
+
+type_name: elaborated_type_specifier { $$ = $1; }
+ | complete_class_name { $$ = $1; }
+ | simple_type_names { $$ = $1; }
+ ;
+
+simple_type_names: simple_type_names simple_type_name
+ { $$ = straddSpc($1,$2); }
+ | simple_type_name { $$ = $1; }
+ ;
+
+simple_type_name: CHAR { $$ = "char"; }
+ | SHORT { $$ = "short"; }
+ | INT { $$ = "int"; }
+ | LONG { $$ = "long"; }
+ | SIGNED { $$ = "signed"; }
+ | UNSIGNED { $$ = "unsigned"; }
+ | FLOAT { $$ = "float"; }
+ | DOUBLE { $$ = "double"; }
+ | VOID { $$ = "void"; }
+ ;
+
+template_spec: TEMPLATE '<' template_args '>'
+ { g->tmpExpression = rmWS( g->tmpExpression );
+ $$ = stradd( "template<",
+ g->tmpExpression, ">" ); }
+ ;
+
+opt_template_spec: /* empty */
+ | template_spec { templateClassOld = templateClass;
+ templateClass = TRUE;
+ }
+ ;
+
+
+class_key: opt_template_spec CLASS { $$ = "class"; }
+ | opt_template_spec STRUCT { $$ = "struct"; }
+ ;
+
+complete_class_name: qualified_class_name { $$ = $1; }
+ | DBL_COLON qualified_class_name
+ { $$ = stradd( "::", $2 ); }
+ ;
+
+qualified_class_name: qualified_class_name DBL_COLON class_name
+ { $$ = stradd( $1, "::", $3 );}
+ | class_name { $$ = $1; }
+ ;
+
+elaborated_type_specifier:
+ class_key IDENTIFIER { $$ = straddSpc($1,$2); }
+ | ENUM IDENTIFIER { $$ = stradd("enum ",$2); }
+ | UNION IDENTIFIER { $$ = stradd("union ",$2); }
+ ;
+
+/***** r.17.4 (ARM p.393): Declarators *****/
+
+argument_declaration_list: arg_declaration_list_opt triple_dot_opt { $$ = $1;}
+ | arg_declaration_list ',' TRIPLE_DOT { $$ = $1;
+ func_warn("Ellipsis not supported"
+ " in tqsignals and tqslots.\n"
+ "Ellipsis argument ignored."); }
+ ;
+
+arg_declaration_list_opt: /* empty */ { $$ = tmpArgList; }
+ | arg_declaration_list { $$ = $1; }
+ ;
+
+opt_exception_argument: /* empty */ { $$ = 0; }
+ | argument_declaration
+ ;
+
+triple_dot_opt: /* empty */
+ | TRIPLE_DOT { func_warn("Ellipsis not supported"
+ " in tqsignals and tqslots.\n"
+ "Ellipsis argument ignored."); }
+
+ ;
+
+arg_declaration_list: arg_declaration_list
+ ','
+ argument_declaration { $$ = addArg($3); }
+ | argument_declaration { $$ = addArg($1); }
+ ;
+
+argument_declaration: decl_specifiers abstract_decl_opt
+ { $$ = new Argument(straddSpc($1,$2),""); }
+ | decl_specifiers abstract_decl_opt
+ '=' { expLevel = 1; }
+ def_argument
+ { $$ = new Argument(straddSpc($1,$2),"", 0, TRUE ); }
+ | decl_specifiers abstract_decl_opt dname
+ abstract_decl_opt
+ { $$ = new Argument(straddSpc($1,$2),$4, $3); }
+ | decl_specifiers abstract_decl_opt dname
+ abstract_decl_opt
+ '=' { expLevel = 1; }
+ def_argument
+ { $$ = new Argument(straddSpc($1,$2),$4, $3, TRUE); }
+ ;
+
+
+abstract_decl_opt: /* empty */ { $$ = ""; }
+ | abstract_decl { $$ = $1; }
+ ;
+
+abstract_decl: abstract_decl ptr_operator
+ { $$ = straddSpc($1,$2); }
+ | '[' { expLevel = 1; }
+ const_expression ']'
+ { $$ = stradd( "[",
+ g->tmpExpression =
+ g->tmpExpression.stripWhiteSpace(), "]" ); }
+ | abstract_decl '[' { expLevel = 1; }
+ const_expression ']'
+ { $$ = stradd( $1,"[",
+ g->tmpExpression =
+ g->tmpExpression.stripWhiteSpace(),"]" ); }
+ | ptr_operator { $$ = $1; }
+ | '(' abstract_decl ')' { $$ = $2; }
+ ;
+
+declarator: dname { $$ = ""; }
+ | declarator ptr_operator
+ { $$ = straddSpc($1,$2);}
+ | declarator '[' { expLevel = 1; }
+ const_expression ']'
+ { $$ = stradd( $1,"[",
+ g->tmpExpression =
+ g->tmpExpression.stripWhiteSpace(),"]" ); }
+ | '(' declarator ')' { $$ = $2; }
+ ;
+
+dname: IDENTIFIER
+ ;
+
+fct_decl: '('
+ argument_declaration_list
+ ')'
+ cv_qualifier_list_opt
+ ctor_initializer_opt
+ exception_spec_opt
+ opt_identifier
+ fct_body_or_semicolon
+ { tmpFunc->args = $2;
+ tmpFunc->qualifier = $4; }
+ ;
+
+fct_name: IDENTIFIER /* NOTE: simplified! */
+ | IDENTIFIER array_decls
+ { func_warn("Variable as signal or slot."); }
+ | IDENTIFIER '=' { expLevel=0; }
+ const_expression /* probably const member */
+ { skipFunc = TRUE; }
+ | IDENTIFIER array_decls '=' { expLevel=0; }
+ const_expression /* probably const member */
+ { skipFunc = TRUE; }
+ ;
+
+
+array_decls: '[' { expLevel = 1; }
+ const_expression ']'
+ | array_decls '[' { expLevel = 1; }
+ const_expression ']'
+
+ ;
+
+ptr_operators_opt: /* empty */ { $$ = ""; }
+ | ptr_operators { $$ = $1; }
+ ;
+
+ptr_operators: ptr_operator { $$ = $1; }
+ | ptr_operators ptr_operator { $$ = straddSpc($1,$2);}
+ ;
+
+ptr_operator: '*' cv_qualifier_list_opt { $$ = straddSpc("*",$2);}
+ | '&' cv_qualifier_list_opt { $$ = stradd("&",$2);}
+/*! | complete_class_name
+ DBL_COLON
+ '*'
+ cv_qualifier_list_opt { $$ = stradd($1,"::*",$4); }*/
+ ;
+
+cv_qualifier_list_opt: /* empty */ { $$ = ""; }
+ | cv_qualifier_list { $$ = $1; }
+ ;
+
+cv_qualifier_list: cv_qualifier { $$ = $1; }
+ | cv_qualifier_list cv_qualifier
+ { $$ = straddSpc($1,$2); }
+ ;
+
+cv_qualifier: CONST { $$ = "const"; }
+ | VOLATILE { $$ = "volatile"; }
+ ;
+
+fct_body_or_semicolon: ';'
+ | fct_body
+ | '=' INT_VAL ';' /* abstract func, INT_VAL = 0 */
+ ;
+
+fct_body: '{' { BEGIN IN_FCT; fctLevel = 1;}
+ '}' { BEGIN TQT_DEF; }
+ ;
+
+
+/***** r.17.5 (ARM p.395): Class Declarations *****/
+
+class_specifier: full_class_head
+ '{' { BEGIN IN_CLASS;
+ classPLevel = 1;
+ }
+ opt_obj_member_list
+ '}' { BEGIN TQT_DEF; } /*catch ';'*/
+ | class_head { BEGIN TQT_DEF; /* -- " -- */
+ skipClass = TRUE; }
+ | class_head '*' IDENTIFIER { BEGIN TQT_DEF; /* -- " -- */
+ skipClass = TRUE; }
+ | class_head '&' IDENTIFIER { BEGIN TQT_DEF; /* -- " -- */
+ skipClass = TRUE; }
+ | class_head
+ '(' IDENTIFIER ')' /* TQt macro name */
+ { BEGIN TQT_DEF; /* catch ';' */
+ skipClass = TRUE; }
+ | template_spec whatever { skipClass = TRUE;
+ BEGIN GIMME_SEMICOLON; }
+ ;
+
+whatever: IDENTIFIER
+ | simple_type_name
+ | type_specifier
+ | storage_class_specifier { $$ = ""; }
+ | fct_specifier
+ ;
+
+
+class_head: class_key
+ qualified_class_name { g->className = $2;
+ fprintf( stderr, "FOUND CLASS [1]: %s\n", (const char*)g->className );
+ if ( g->className == "TQObject" )
+ TQ_OBJECTdetected = TRUE;
+ }
+ | class_key
+ IDENTIFIER /* possible DLL EXPORT macro */
+ class_name { g->className = $3;
+ fprintf( stderr, "FOUND CLASS [2]: %s\n", (const char*)g->className );
+ if ( g->className == "TQObject" )
+ TQ_OBJECTdetected = TRUE;
+ }
+ ;
+
+full_class_head: class_head
+ opt_base_spec { g->superClassName = $2; }
+ ;
+
+nested_class_head: class_key
+ qualified_class_name
+ opt_base_spec { templateClass = templateClassOld; }
+ ;
+
+exception_spec_opt: /* empty */
+ | exception_spec
+ ;
+
+/* looser than the real thing */
+exception_spec: THROW '(' opt_exception_argument ')'
+ ;
+
+ctor_initializer_opt: /* empty */
+ | ctor_initializer
+ ;
+
+ctor_initializer: ':' mem_initializer_list
+ ;
+
+mem_initializer_list: mem_initializer
+ | mem_initializer ',' mem_initializer_list
+ ;
+
+/* complete_class_name also represents IDENTIFIER */
+mem_initializer: complete_class_name '(' { expLevel = 1; }
+ const_expression ')'
+ ;
+
+
+opt_base_spec: /* empty */ { $$ = 0; }
+ | base_spec { $$ = $1; }
+ ;
+
+opt_obj_member_list: /* empty */
+ | obj_member_list
+ ;
+
+obj_member_list: obj_member_list obj_member_area
+ | obj_member_area
+ ;
+
+
+qt_access_specifier: access_specifier { tmpAccess = $1; }
+ | SLOTS { tqmoc_err( "Missing access specifier"
+ " before \"tqslots:\"." ); }
+ ;
+
+obj_member_area: qt_access_specifier { BEGIN TQT_DEF; }
+ slot_area
+ | SIGNALS { BEGIN TQT_DEF; }
+ ':' opt_signal_declarations
+ | TQ_OBJECT {
+ if ( tmpAccess )
+ tqmoc_warn("TQ_OBJECT is not in the private"
+ " section of the class.\n"
+ "TQ_OBJECT is a macro that resets"
+ " access permission to \"private\".");
+ TQ_OBJECTdetected = TRUE;
+ }
+ | Q_PROPERTY { tmpYYStart = YY_START;
+ tmpPropOverride = FALSE;
+ BEGIN IN_PROPERTY; }
+ '(' property ')' {
+ BEGIN tmpYYStart;
+ }
+ opt_property_candidates
+ | TQ_OVERRIDE { tmpYYStart = YY_START;
+ tmpPropOverride = TRUE;
+ BEGIN IN_PROPERTY; }
+ '(' property ')' {
+ BEGIN tmpYYStart;
+ }
+ opt_property_candidates
+ | TQ_CLASSINFO { tmpYYStart = YY_START; BEGIN IN_CLASSINFO; }
+ '(' STRING ',' STRING ')'
+ {
+ g->infos.append( new ClassInfo( $4, $6 ) );
+ BEGIN tmpYYStart;
+ }
+ opt_property_candidates
+ | TQ_ENUMS { tmpYYStart = YY_START; BEGIN IN_PROPERTY; }
+ '(' qt_enums ')' {
+ Q_PROPERTYdetected = TRUE;
+ BEGIN tmpYYStart;
+ }
+ opt_property_candidates
+ | TQ_SETS { tmpYYStart = YY_START; BEGIN IN_PROPERTY; }
+ '(' qt_sets ')' {
+ Q_PROPERTYdetected = TRUE;
+ BEGIN tmpYYStart;
+ }
+ opt_property_candidates
+ ;
+
+slot_area: SIGNALS ':' { tqmoc_err( "Signals cannot "
+ "have access specifiers" ); }
+ | SLOTS ':' opt_slot_declarations
+ | ':' { if ( tmpAccess == Public && Q_PROPERTYdetected )
+ BEGIN TQT_DEF;
+ else
+ BEGIN IN_CLASS;
+ suppress_func_warn = TRUE;
+ }
+ opt_property_candidates
+ {
+ suppress_func_warn = FALSE;
+ }
+ | IDENTIFIER { BEGIN IN_CLASS;
+ if ( classPLevel != 1 )
+ tqmoc_warn( "unexpected access"
+ "specifier" );
+ }
+ ;
+
+opt_property_candidates: /*empty*/
+ | property_candidate_declarations
+ ;
+
+property_candidate_declarations: property_candidate_declarations property_candidate_declaration
+ | property_candidate_declaration
+ ;
+
+property_candidate_declaration: signal_or_slot { addMember( PropertyCandidateMember ); }
+ ;
+
+opt_signal_declarations: /* empty */
+ | signal_declarations
+ ;
+
+signal_declarations: signal_declarations signal_declaration
+ | signal_declaration
+ ;
+
+
+signal_declaration: signal_or_slot { addMember( SignalMember ); }
+ ;
+
+opt_slot_declarations: /* empty */
+ | slot_declarations
+ ;
+
+slot_declarations: slot_declarations slot_declaration
+ | slot_declaration
+ ;
+
+slot_declaration: signal_or_slot { addMember( SlotMember ); }
+ ;
+
+opt_semicolons: /* empty */
+ | opt_semicolons ';'
+ ;
+
+base_spec: ':' base_list { $$=$2; }
+ ;
+
+base_list : base_list ',' base_specifier { g->multipleSuperClasses.append( $3 ); }
+ | base_specifier
+ ;
+
+qt_macro_name: IDENTIFIER '(' IDENTIFIER ')'
+ { $$ = stradd( $1, "(", $3, ")" ); }
+ | IDENTIFIER '(' simple_type_name ')'
+ { $$ = stradd( $1, "(", $3, ")" ); }
+ ;
+
+base_specifier: complete_class_name {$$=$1;}
+ | VIRTUAL access_specifier complete_class_name {$$=$3;}
+ | VIRTUAL complete_class_name {$$=$2;}
+ | access_specifier VIRTUAL complete_class_name {$$=$3;}
+ | access_specifier complete_class_name {$$=$2;}
+ | qt_macro_name {$$=$1;}
+ | VIRTUAL access_specifier qt_macro_name {$$=$3;}
+ | VIRTUAL qt_macro_name {$$=$2;}
+ | access_specifier VIRTUAL qt_macro_name {$$=$3;}
+ | access_specifier qt_macro_name {$$=$2;}
+ ;
+
+access_specifier: PRIVATE { $$=Private; }
+ | PROTECTED { $$=Protected; }
+ | PUBLIC { $$=Public; }
+ ;
+
+operator_name: decl_specs_opt IDENTIFIER ptr_operators_opt { }
+ | decl_specs_opt simple_type_name ptr_operators_opt { }
+ | '+'
+ | '-'
+ | '*'
+ | '/'
+ | '%'
+ | '^'
+ | '&'
+ | '|'
+ | '~'
+ | '!'
+ | '='
+ | '<'
+ | '>'
+ | '+' '='
+ | '-' '='
+ | '*' '='
+ | '/' '='
+ | '%' '='
+ | '^' '='
+ | '&' '='
+ | '|' '='
+ | '~' '='
+ | '!' '='
+ | '=' '='
+ | '<' '='
+ | '>' '='
+ | '<' '<'
+ | '>' '>'
+ | '<' '<' '='
+ | '>' '>' '='
+ | '&' '&'
+ | '|' '|'
+ | '+' '+'
+ | '-' '-'
+ | ','
+ | '-' '>' '*'
+ | '-' '>'
+ | '(' ')'
+ | '[' ']'
+ ;
+
+
+opt_virtual: /* empty */
+ | VIRTUAL
+ ;
+
+type_and_name: type_name fct_name
+ { tmpFunc->type = $1;
+ tmpFunc->name = $2; }
+ | fct_name
+ { tmpFunc->type = "int";
+ tmpFunc->name = $1;
+ if ( tmpFunc->name == g->className )
+ func_warn( "Constructors cannot be"
+ " tqsignals or tqslots.");
+ }
+ | opt_virtual '~' fct_name
+ { tmpFunc->type = "void";
+ tmpFunc->name = "~";
+ tmpFunc->name += $3;
+ func_warn( "Destructors cannot be"
+ " tqsignals or tqslots.");
+ }
+ | decl_specs type_name decl_specs_opt
+ ptr_operators_opt fct_name
+ {
+ char *tmp =
+ straddSpc($1,$2,$3,$4);
+ tmpFunc->type = rmWS(tmp);
+ delete [] tmp;
+ tmpFunc->name = $5; }
+ | decl_specs type_name /* probably friend decl */
+ { skipFunc = TRUE; }
+ | type_name ptr_operators fct_name
+ { tmpFunc->type =
+ straddSpc($1,$2);
+ tmpFunc->name = $3; }
+ | type_name decl_specs ptr_operators_opt
+ fct_name
+ { tmpFunc->type =
+ straddSpc($1,$2,$3);
+ tmpFunc->name = $4; }
+ | type_name OPERATOR operator_name
+ { operatorError(); }
+ | OPERATOR operator_name
+ { operatorError(); }
+ | decl_specs type_name decl_specs_opt
+ ptr_operators_opt OPERATOR operator_name
+ { operatorError(); }
+ | type_name ptr_operators OPERATOR operator_name
+ { operatorError(); }
+ | type_name decl_specs ptr_operators_opt
+ OPERATOR operator_name
+ { operatorError(); }
+ ;
+
+
+signal_or_slot: type_and_name fct_decl opt_semicolons
+ | type_and_name opt_bitfield ';' opt_semicolons
+ { func_warn("Unexpected variable declaration."); }
+ | type_and_name opt_bitfield ','member_declarator_list
+ ';' opt_semicolons
+ { func_warn("Unexpected variable declaration."); }
+ | enum_specifier opt_identifier ';' opt_semicolons
+ { func_warn("Unexpected enum declaration."); }
+ | USING complete_class_name ';' opt_semicolons
+ { func_warn("Unexpected using declaration."); }
+ | USING NAMESPACE complete_class_name ';' opt_semicolons
+ { func_warn("Unexpected using declaration."); }
+ | NAMESPACE IDENTIFIER '{'
+ { classPLevel++;
+ tqmoc_err("Unexpected namespace declaration."); }
+ | nested_class_head ';' opt_semicolons
+ { func_warn("Unexpected class declaration.");}
+ | nested_class_head
+ '{' { func_warn("Unexpected class declaration.");
+ BEGIN IN_FCT; fctLevel=1;
+ }
+ '}' { BEGIN TQT_DEF; }
+ ';' opt_semicolons
+ ;
+
+
+member_declarator_list: member_declarator
+ | member_declarator_list ',' member_declarator
+ ;
+
+member_declarator: declarator { }
+ | IDENTIFIER ':' { expLevel = 0; }
+ const_expression
+ | ':' { expLevel = 0; }
+ const_expression
+ ;
+
+opt_bitfield: /* empty */
+ | ':' { expLevel = 0; }
+ const_expression
+ ;
+
+
+enum_specifier: ENUM enum_tail
+ ;
+
+/* optional final comma at the end of an enum list. Not really C++ but
+some people still use it */
+opt_komma: /*empty*/
+ | ','
+ ;
+
+enum_tail: IDENTIFIER '{' enum_list opt_komma
+ '}' { BEGIN TQT_DEF;
+ if ( tmpAccess == Public) {
+ tmpEnum->name = $1;
+ addEnum();
+ }
+ }
+ | '{' enum_list opt_komma
+ '}' { tmpEnum->clear();}
+ ;
+
+opt_identifier: /* empty */
+ | IDENTIFIER { }
+ ;
+
+enum_list: /* empty */
+ | enumerator
+ | enum_list ',' enumerator
+ ;
+
+enumerator: IDENTIFIER { if ( tmpAccess == Public) tmpEnum->append( $1 ); }
+ | IDENTIFIER '=' { enumLevel=0; }
+ enumerator_expression { if ( tmpAccess == Public) tmpEnum->append( $1 ); }
+ ;
+
+property: IDENTIFIER IDENTIFIER
+ {
+ g->propWrite = "";
+ g->propRead = "";
+ g->propOverride = tmpPropOverride;
+ g->propReset = "";
+ if ( g->propOverride ) {
+ g->propStored = "";
+ g->propDesignable = "";
+ g->propScriptable = "";
+ } else {
+ g->propStored = "true";
+ g->propDesignable = "true";
+ g->propScriptable = "true";
+ }
+ }
+ prop_statements
+ {
+ if ( g->propRead.isEmpty() && !g->propOverride )
+ tqmoc_err( "A property must at least feature a read method." );
+ checkPropertyName( $2 );
+ Q_PROPERTYdetected = TRUE;
+ // Avoid duplicates
+ for( TQPtrListIterator<Property> lit( g->props ); lit.current(); ++lit ) {
+ if ( lit.current()->name == $2 ) {
+ if ( displayWarnings )
+ tqmoc_err( "Property '%s' defined twice.",
+ (const char*)lit.current()->name );
+ }
+ }
+ g->props.append( new Property( lineNo, $1, $2,
+ g->propWrite, g->propRead, g->propReset,
+ g->propStored, g->propDesignable,
+ g->propScriptable, g->propOverride ) );
+ }
+ ;
+
+prop_statements: /* empty */
+ | READ IDENTIFIER prop_statements { g->propRead = $2; }
+ | WRITE IDENTIFIER prop_statements { g->propWrite = $2; }
+ | RESET IDENTIFIER prop_statements { g->propReset = $2; }
+ | STORED IDENTIFIER prop_statements { g->propStored = $2; }
+ | DESIGNABLE IDENTIFIER prop_statements { g->propDesignable = $2; }
+ | SCRIPTABLE IDENTIFIER prop_statements { g->propScriptable = $2; }
+ ;
+
+qt_enums: /* empty */ { }
+ | IDENTIFIER qt_enums { g->qtEnums.append( $1 ); }
+ ;
+
+qt_sets: /* empty */ { }
+ | IDENTIFIER qt_sets { g->qtSets.append( $1 ); }
+ ;
+
+%%
+
+#ifndef YYBISON
+# if defined(TQ_OS_WIN32)
+# include <io.h>
+# undef isatty
+extern "C" int hack_isatty( int )
+{
+ return 0;
+}
+# define isatty hack_isatty
+# else
+# include <unistd.h>
+# endif
+# include "tqmoc_lex.cpp"
+#endif //YYBISON
+
+void cleanup();
+TQCString combinePath( const char *, const char * );
+
+FILE *out; // output file
+
+parser_reg::parser_reg() : funcs(TRUE)
+{
+ gen_count = 0;
+ noInclude = FALSE; // no #include <filename>
+ generatedCode = FALSE; // no code generated
+ tqmocError = FALSE; // tqmoc parsing error occurred
+ hasVariantIncluded = FALSE;
+}
+
+
+parser_reg::~parser_reg()
+{
+ tqslots.clear();
+ tqsignals.clear();
+ propfuncs.clear();
+ funcs.clear();
+ infos.clear();
+ props.clear();
+ infos.clear();
+}
+
+int yyparse();
+
+void tqreplace( char *s, char c1, char c2 );
+
+void setDefaultIncludeFile()
+{
+ if ( g->includeFiles.isEmpty() ) {
+ if ( g->includePath.isEmpty() ) {
+ if ( !g->fileName.isEmpty() && !g->outputFile.isEmpty() ) {
+ g->includeFiles.append( combinePath(g->fileName, g->outputFile) );
+ } else {
+ g->includeFiles.append( g->fileName );
+ }
+ } else {
+ g->includeFiles.append( combinePath(g->fileName, g->fileName) );
+ }
+ }
+}
+
+#ifdef TQ_CC_MSVC
+#define ErrorFormatString "%s(%d):"
+#else
+#define ErrorFormatString "%s:%d:"
+#endif
+
+#ifndef TQMOC_MWERKS_PLUGIN
+int main( int argc, char **argv )
+{
+ init();
+
+ bool autoInclude = TRUE;
+ const char *error = 0;
+ g->qtPath = "";
+ for ( int n=1; n<argc && error==0; n++ ) {
+ TQCString arg = argv[n];
+ if ( arg[0] == '-' ) { // option
+ TQCString opt = arg.tqstringFromPos(1);
+ if ( opt[0] == 'o' ) { // output redirection
+ if ( opt[1] == '\0' ) {
+ if ( !(n < argc-1) ) {
+ error = "Missing output file name";
+ break;
+ }
+ g->outputFile = argv[++n];
+ } else
+ g->outputFile = opt.tqstringFromPos(1);
+ } else if ( opt == "i" ) { // no #include statement
+ g->noInclude = TRUE;
+ autoInclude = FALSE;
+ } else if ( opt[0] == 'f' ) { // produce #include statement
+ g->noInclude = FALSE;
+ autoInclude = FALSE;
+ if ( opt[1] ) // -fsomething.h
+ g->includeFiles.append( opt.tqstringFromPos(1) );
+ } else if ( opt == "pch" ) { // produce #include statement for PCH
+ if ( !(n < argc-1) ) {
+ error = "Missing name of PCH file";
+ break;
+ }
+ g->pchFile = argv[++n];
+ } else if ( opt[0] == 'p' ) { // include file path
+ if ( opt[1] == '\0' ) {
+ if ( !(n < argc-1) ) {
+ error = "Missing path name for the -p option.";
+ break;
+ }
+ g->includePath = argv[++n];
+ } else {
+ g->includePath = opt.tqstringFromPos(1);
+ }
+ } else if ( opt[0] == 'q' ) { // qt include file path
+ if ( opt[1] == '\0' ) {
+ if ( !(n < argc-1) ) {
+ error = "Missing path name for the -q option.";
+ break;
+ }
+ g->qtPath = argv[++n];
+ } else {
+ g->qtPath = opt.tqstringFromPos(1);
+ }
+ tqreplace(g->qtPath.data(),'\\','/');
+ if ( g->qtPath.right(1) != "/" )
+ g->qtPath += '/';
+ } else if ( opt == "v" ) { // version number
+ fprintf( stderr, "TQt Meta Object Compiler version %d"
+ " (TQt %s)\n", formatRevision,
+ TQT_VERSION_STR );
+ cleanup();
+ return 1;
+ } else if ( opt == "k" ) { // stop on errors
+ errorControl = TRUE;
+ } else if ( opt == "nw" ) { // don't display warnings
+ displayWarnings = FALSE;
+ } else if ( opt == "ldbg" ) { // lex debug output
+ lexDebug = TRUE;
+ } else if ( opt == "ydbg" ) { // yacc debug output
+ yydebug = TRUE;
+ } else {
+ error = "Invalid argument";
+ }
+ } else {
+ if ( !g->fileName.isNull() ) // can handle only one file
+ error = "Too many input files specified";
+ else
+ g->fileName = arg.copy();
+ }
+ }
+
+ if ( autoInclude ) {
+ int ppos = g->fileName.tqfindRev('.');
+ if ( ppos != -1 && tolower( g->fileName[ppos + 1] ) == 'h' )
+ g->noInclude = FALSE;
+ else
+ g->noInclude = TRUE;
+ }
+ setDefaultIncludeFile();
+
+ if ( g->fileName.isNull() && !error ) {
+ g->fileName = "standard input";
+ yyin = stdin;
+ } else if ( argc < 2 || error ) { // incomplete/wrong args
+ fprintf( stderr, "TQt meta object compiler\n" );
+ if ( error )
+ fprintf( stderr, "tqmoc: %s\n", error );
+ fprintf( stderr, "Usage: tqmoc [options] <header-file>\n"
+ "\t-o file Write output to file rather than stdout\n"
+ "\t-f[file] Force #include, optional file name\n"
+ "\t-p path Path prefix for included file\n"
+ "\t-i Do not generate an #include statement\n"
+ "\t-k Do not stop on errors\n"
+ "\t-nw Do not display warnings\n"
+ "\t-v Display version of tqmoc\n" );
+ cleanup();
+ return 1;
+ } else {
+ yyin = fopen( (const char *)g->fileName, "r" );
+ if ( !yyin ) {
+ fprintf( stderr, "tqmoc: %s: No such file\n", (const char*)g->fileName);
+ cleanup();
+ return 1;
+ }
+ }
+ if ( !g->outputFile.isEmpty() ) { // output file specified
+ out = fopen( (const char *)g->outputFile, "w" ); // create output file
+ if ( !out ) {
+ fprintf( stderr, "tqmoc: Cannot create %s\n",
+ (const char*)g->outputFile );
+ cleanup();
+ return 1;
+ }
+ } else { // use stdout
+ out = stdout;
+ }
+ yyparse();
+ fclose( yyin );
+ if ( !g->outputFile.isNull() )
+ fclose( out );
+
+ if ( !g->generatedCode && displayWarnings && !g->tqmocError ) {
+ fprintf( stderr, ErrorFormatString" Warning: %s\n", g->fileName.data(), 0,
+ "No relevant classes found. No output generated." );
+ }
+
+ int ret = g->tqmocError ? 1 : 0;
+ cleanup();
+ return ret;
+}
+#else
+bool qt_is_gui_used = FALSE;
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef TQ_OS_MAC9
+# include <Files.h>
+# include <Strings.h>
+# include <Errors.h>
+# include "Aliases.h"
+#endif
+#include "CWPluginErrors.h"
+#include <CWPlugins.h>
+#include "DropInCompilerLinker.h"
+#include <stat.h>
+
+const unsigned char *p_str(const char *, int =-1);
+
+CWPluginContext g_ctx;
+
+tqmoc_status do_tqmoc( CWPluginContext ctx, const TQCString &fin, const TQCString &fout, CWFileSpec *dspec, bool i)
+{
+ init();
+
+ g_ctx = ctx;
+ g->noInclude = i;
+ g->fileName = fin;
+ g->outputFile = fout;
+
+ setDefaultIncludeFile();
+
+ CWFileInfo fi;
+ memset(&fi, 0, sizeof(fi));
+ fi.fullsearch = TRUE;
+ fi.dependencyType = cwNormalDependency;
+ fi.isdependentoffile = kCurrentCompiledFile;
+ if(CWFindAndLoadFile( ctx, fin.data(), &fi) != cwNoErr) {
+ cleanup();
+ return tqmoc_no_source;
+ }
+
+ if(dspec) {
+ memcpy(dspec, &fi.filespec, sizeof(fi.filespec));
+ const unsigned char *f = p_str(fout.data());
+ memcpy(dspec->name, f, f[0]+1);
+ free(f);
+ }
+ buf_size_total = fi.filedatalength;
+ buf_buffer = fi.filedata;
+
+ TQCString path("");
+ AliasHandle alias;
+ Str63 str;
+ AliasInfoType x = 1;
+ char tmp[sizeof(Str63)+2];
+ if(NewAlias( NULL, &fi.filespec, &alias) != noErr) {
+ cleanup();
+ return tqmoc_general_error;
+ }
+ for(;;) {
+ GetAliasInfo(alias, x++, str);
+ if(!str[0])
+ break;
+ strncpy((char *)tmp, (const char *)str+1, str[0]);
+ tmp[str[0]] = '\0';
+ path.prepend(":");
+ path.prepend((char *)tmp);
+ }
+ path.prepend("MacOS 9:"); //FIXME
+
+ TQString inpath = path + fin, outpath = path + fout;
+ struct stat istat, ostat;
+ if(stat(inpath, &istat) == -1) {
+ cleanup();
+ return tqmoc_no_source;
+ }
+ if(stat(outpath, &ostat) == 0 && istat.st_mtime < ostat.st_mtime) {
+ cleanup();
+ return tqmoc_not_time;
+ }
+
+ unlink(outpath.data());
+ out = fopen(outpath.data(), "w+");
+ if(!out) {
+ cleanup();
+ return tqmoc_general_error;
+ }
+
+ yyparse();
+ if(out != stdout)
+ fclose(out);
+
+ if(g->tqmocError || !g->generatedCode) {
+ unlink(outpath.data());
+ tqmoc_status ret = !g->generatedCode ? tqmoc_no_qobject : tqmoc_parse_error;
+ cleanup();
+ return ret;
+ }
+
+ cleanup();
+ return tqmoc_success;
+}
+#endif
+void tqreplace( char *s, char c1, char c2 )
+{
+ if ( !s )
+ return;
+ while ( *s ) {
+ if ( *s == c1 )
+ *s = c2;
+ s++;
+ }
+}
+
+/*
+ This function looks at two file names and returns the name of the
+ infile with a path relative to outfile.
+
+ Examples:
+
+ /tmp/abc, /tmp/bcd -> abc
+ xyz/a/bc, xyz/b/ac -> ../a/bc
+ /tmp/abc, xyz/klm -> /tmp/abc
+ */
+
+TQCString combinePath( const char *infile, const char *outfile )
+{
+ TQFileInfo inFileInfo( TQDir::current(), TQFile::decodeName(infile) );
+ TQFileInfo outFileInfo( TQDir::current(), TQFile::decodeName(outfile) );
+ int numCommonComponents = 0;
+
+ TQStringList inSplitted =
+ TQStringList::split( '/', inFileInfo.dir().canonicalPath(), TRUE );
+ TQStringList outSplitted =
+ TQStringList::split( '/', outFileInfo.dir().canonicalPath(), TRUE );
+
+ while ( !inSplitted.isEmpty() && !outSplitted.isEmpty() &&
+ inSplitted.first() == outSplitted.first() ) {
+ inSplitted.remove( inSplitted.begin() );
+ outSplitted.remove( outSplitted.begin() );
+ numCommonComponents++;
+ }
+
+ if ( numCommonComponents < 2 ) {
+ /*
+ The paths don't have the same drive, or they don't have the
+ same root directory. Use an absolute path.
+ */
+ return TQFile::encodeName( inFileInfo.absFilePath() );
+ } else {
+ /*
+ The paths have something in common. Use a path relative to
+ the output file.
+ */
+ while ( !outSplitted.isEmpty() ) {
+ outSplitted.remove( outSplitted.begin() );
+ inSplitted.prepend( ".." );
+ }
+ inSplitted.append( inFileInfo.fileName() );
+ return TQFile::encodeName( inSplitted.join("/") );
+ }
+}
+
+
+#define getenv hack_getenv // workaround for byacc
+char *getenv() { return 0; }
+char *getenv( const char * ) { return 0; }
+
+void init() // initialize
+{
+ BEGIN OUTSIDE;
+ if(g)
+ delete g;
+ g = new parser_reg;
+ lineNo = 1;
+ skipClass = FALSE;
+ skipFunc = FALSE;
+ tmpArgList = new ArgList;
+ tmpFunc = new Function;
+ tmpEnum = new Enum;
+
+#ifdef TQMOC_MWERKS_PLUGIN
+ buf_buffer = NULL;
+ buf_index = 0;
+ buf_size_total = 0;
+#endif
+}
+
+void cleanup()
+{
+ delete g;
+ g = NULL;
+
+#ifdef TQMOC_MWERKS_PLUGIN
+ if(buf_buffer && g_ctx)
+ CWReleaseFileText(g_ctx, buf_buffer);
+#endif
+}
+
+void initClass() // prepare for new class
+{
+ tmpAccess = Private;
+ subClassPerm = Private;
+ TQ_OBJECTdetected = FALSE;
+ Q_PROPERTYdetected = FALSE;
+ skipClass = FALSE;
+ templateClass = FALSE;
+ g->tqslots.clear();
+ g->tqsignals.clear();
+ g->propfuncs.clear();
+ g->enums.clear();
+ g->funcs.clear();
+ g->props.clear();
+ g->infos.clear();
+ g->qtSets.clear();
+ g->qtEnums.clear();
+ g->multipleSuperClasses.clear();
+}
+
+struct NamespaceInfo
+{
+ TQCString name;
+ int pLevelOnEntering; // Parenthesis level on entering the namespace
+ TQDict<char> definedClasses; // Classes defined in the namespace
+};
+
+TQPtrList<NamespaceInfo> namespaces;
+
+void enterNameSpace( const char *name ) // prepare for new class
+{
+ static bool first = TRUE;
+ if ( first ) {
+ namespaces.setAutoDelete( TRUE );
+ first = FALSE;
+ }
+
+ NamespaceInfo *tmp = new NamespaceInfo;
+ if ( name )
+ tmp->name = name;
+ tmp->pLevelOnEntering = namespacePLevel;
+ namespaces.append( tmp );
+}
+
+void leaveNameSpace() // prepare for new class
+{
+ NamespaceInfo *tmp = namespaces.last();
+ namespacePLevel = tmp->pLevelOnEntering;
+ namespaces.remove();
+}
+
+TQCString nameTQualifier()
+{
+ TQPtrListIterator<NamespaceInfo> iter( namespaces );
+ NamespaceInfo *tmp;
+ TQCString qualifier = "";
+ for( ; (tmp = iter.current()) ; ++iter ) {
+ if ( !tmp->name.isNull() ) { // If not unnamed namespace
+ qualifier += tmp->name;
+ qualifier += "::";
+ }
+ }
+ return qualifier;
+}
+
+int openNameSpaceForMetaObject( FILE *out )
+{
+ int levels = 0;
+ TQPtrListIterator<NamespaceInfo> iter( namespaces );
+ NamespaceInfo *tmp;
+ TQCString indent = "";
+ for( ; (tmp = iter.current()) ; ++iter ) {
+ if ( !tmp->name.isNull() ) { // If not unnamed namespace
+ fprintf( out, "%snamespace %s {\n", (const char *)indent,
+ (const char *) tmp->name );
+ indent += " ";
+ levels++;
+ }
+ }
+ TQCString nm = g->className;
+ int pos;
+ while( (pos = nm.tqfind( "::" )) != -1 ) {
+ TQCString spaceName = nm.left( pos );
+ nm = nm.right( nm.length() - pos - 2 );
+ if ( !spaceName.isEmpty() ) {
+ fprintf( out, "%snamespace %s {\n", (const char *)indent,
+ (const char *) spaceName );
+ indent += " ";
+ levels++;
+ }
+ }
+ return levels;
+}
+
+void closeNameSpaceForMetaObject( FILE *out, int levels )
+{
+ int i;
+ for( i = 0 ; i < levels ; i++ )
+ fprintf( out, "}" );
+ if ( levels )
+ fprintf( out, "\n" );
+
+}
+
+void selectOutsideClassState()
+{
+ if ( namespaces.count() == 0 )
+ BEGIN OUTSIDE;
+ else
+ BEGIN IN_NAMESPACE;
+}
+
+void registerClassInNamespace()
+{
+ if ( namespaces.count() == 0 )
+ return;
+ namespaces.last()->definedClasses.insert((const char *)g->className,(char*)1);
+}
+
+//
+// Remove white space from SIGNAL and SLOT names.
+// This function has been copied from qobject.cpp.
+//
+
+inline bool isSpace( char x )
+{
+#if defined(TQ_CC_BOR)
+ /*
+ Borland C++ 4.5 has a weird isspace() bug.
+ isspace() usually works, but not here.
+ This implementation is sufficient for our internal use: rmWS()
+ */
+ return (uchar) x <= 32;
+#else
+ return isspace( (uchar) x );
+#endif
+}
+
+static TQCString rmWS( const char *src )
+{
+ TQCString result( tqstrlen(src)+1 );
+ char *d = result.data();
+ char *s = (char *)src;
+ char last = 0;
+ while( *s && isSpace(*s) ) // skip leading space
+ s++;
+ while ( *s ) {
+ while ( *s && !isSpace(*s) )
+ last = *d++ = *s++;
+ while ( *s && isSpace(*s) )
+ s++;
+ if ( *s && isIdentChar(*s) && isIdentChar(last) )
+ last = *d++ = ' ';
+ }
+ result.truncate( (int)(d - result.data()) );
+ return result;
+}
+
+
+void initExpression()
+{
+ g->tmpExpression = "";
+}
+
+void addExpressionString( const char *s )
+{
+ g->tmpExpression += s;
+}
+
+void addExpressionChar( const char c )
+{
+ g->tmpExpression += c;
+}
+
+void yyerror( const char *msg ) // print yacc error message
+{
+ g->tqmocError = TRUE;
+#ifndef TQMOC_MWERKS_PLUGIN
+ fprintf( stderr, ErrorFormatString" Error: %s\n", g->fileName.data(), lineNo, msg );
+#else
+ char msg2[200];
+ sprintf(msg2, ErrorFormatString" Error: %s", g->fileName.data(), lineNo, msg);
+ CWReportMessage(g_ctx, NULL, msg2, NULL, messagetypeError, 0);
+#endif
+ if ( errorControl ) {
+ if ( !g->outputFile.isEmpty() && yyin && fclose(yyin) == 0 )
+ remove( g->outputFile );
+ exit( -1 );
+ }
+}
+
+void tqmoc_err( const char *s )
+{
+ yyerror( s );
+}
+
+void tqmoc_err( const char *s1, const char *s2 )
+{
+ static char tmp[1024];
+ sprintf( tmp, s1, s2 );
+ yyerror( tmp );
+}
+
+void tqmoc_warn( const char *msg )
+{
+ if ( displayWarnings )
+ fprintf( stderr, ErrorFormatString" Warning: %s\n", g->fileName.data(), lineNo, msg);
+}
+
+void tqmoc_warn( char *s1, char *s2 )
+{
+ static char tmp[1024];
+ sprintf( tmp, s1, s2 );
+ if ( displayWarnings )
+ fprintf( stderr, ErrorFormatString" Warning: %s\n", g->fileName.data(), lineNo, tmp);
+}
+
+void func_warn( const char *msg )
+{
+ if ( !suppress_func_warn )
+ tqmoc_warn( msg );
+ skipFunc = TRUE;
+}
+
+void operatorError()
+{
+ if ( !suppress_func_warn )
+ tqmoc_warn("Operator functions cannot be tqsignals or tqslots.");
+ skipFunc = TRUE;
+}
+
+#ifndef yywrap
+int yywrap() // more files?
+{
+ return 1; // end of file
+}
+#endif
+
+char *stradd( const char *s1, const char *s2 ) // adds two strings
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+1];
+ qstrcpy( n, s1 );
+ strcat( n, s2 );
+ return n;
+}
+
+char *stradd( const char *s1, const char *s2, const char *s3 )// adds 3 strings
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+tqstrlen(s3)+1];
+ qstrcpy( n, s1 );
+ strcat( n, s2 );
+ strcat( n, s3 );
+ return n;
+}
+
+char *stradd( const char *s1, const char *s2,
+ const char *s3, const char *s4 )// adds 4 strings
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+tqstrlen(s3)+tqstrlen(s4)+1];
+ qstrcpy( n, s1 );
+ strcat( n, s2 );
+ strcat( n, s3 );
+ strcat( n, s4 );
+ return n;
+}
+
+
+char *straddSpc( const char *s1, const char *s2 )
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+2];
+ qstrcpy( n, s1 );
+ strcat( n, " " );
+ strcat( n, s2 );
+ return n;
+}
+
+char *straddSpc( const char *s1, const char *s2, const char *s3 )
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+tqstrlen(s3)+3];
+ qstrcpy( n, s1 );
+ strcat( n, " " );
+ strcat( n, s2 );
+ strcat( n, " " );
+ strcat( n, s3 );
+ return n;
+}
+
+char *straddSpc( const char *s1, const char *s2,
+ const char *s3, const char *s4 )
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+tqstrlen(s3)+tqstrlen(s4)+4];
+ qstrcpy( n, s1 );
+ strcat( n, " " );
+ strcat( n, s2 );
+ strcat( n, " " );
+ strcat( n, s3 );
+ strcat( n, " " );
+ strcat( n, s4 );
+ return n;
+}
+
+// Generate C++ code for building member function table
+
+
+/*
+ We call B::qt_invoke() rather than A::B::qt_invoke() to
+ work around a bug in MSVC 6. The bug occurs if the
+ super-class is in a namespace and the sub-class isn't.
+
+ Exception: If the superclass has the same name as the subclass, we
+ want non-MSVC users to have a working generated files.
+*/
+TQCString purestSuperClassName()
+{
+ TQCString sc = g->superClassName;
+ TQCString c = g->className;
+ /*
+ Make sure qualified template arguments (e.g., foo<bar::baz>)
+ don't interfere.
+ */
+ int pos = sc.tqfindRev( "::", sc.tqfind( '<' ) );
+ if ( pos != -1 ) {
+ sc = sc.right( sc.length() - pos - 2 );
+ pos = c.tqfindRev( "::" );
+ if ( pos != -1 )
+ c = c.right( c.length() - pos - 2 );
+ if ( sc == c )
+ sc = g->superClassName;
+ }
+ return sc;
+}
+
+TQCString callablePurestSuperClassName()
+{
+ TQCString sc = purestSuperClassName();
+// if (sc.tqfind("TQ") != 0) {
+ return TQCString("static_cast<TQObject*>(static_cast<TQT_BASE_OBJECT_NAME*>(this))->");
+// }
+// else {
+// return TQCString(sc + "::");
+// }
+}
+
+TQCString qualifiedClassName()
+{
+ return nameTQualifier() + g->className;
+}
+
+TQCString callableQualifiedClassName()
+{
+ TQCString sc = qualifiedClassName();
+// if (sc.tqfind("TQ") != 0) {
+ return TQCString("static_cast<TQObject*>(static_cast<TQT_BASE_OBJECT_NAME*>(this))->");
+// }
+// else {
+// return TQCString(sc + "::");
+// }
+}
+
+const int Slot_Num = 1;
+const int Signal_Num = 2;
+const int Prop_Num = 3;
+
+void generateFuncs( FuncList *list, const char *functype, int num )
+{
+ Function *f;
+ for ( f=list->first(); f; f=list->next() ) {
+ bool hasReturnValue = f->type != "void" && (validUType( f->type ) || isVariantType( f->type) );
+
+ if ( hasReturnValue || !f->args->isEmpty() ) {
+ fprintf( out, " static const TQUParameter param_%s_%d[] = {\n", functype, list->at() );
+ if ( hasReturnValue ) {
+ if ( validUType( f->type ) )
+ fprintf( out, "\t{ 0, &static_TQUType_%s, %s, TQUParameter::Out }", uType(f->type).data(), uTypeExtra(f->type).data() );
+ else
+ fprintf( out, "\t{ 0, &static_TQUType_TQVariant, %s, TQUParameter::Out }", uTypeExtra(f->type).data() );
+ if ( !f->args->isEmpty() )
+ fprintf( out, ",\n" );
+ }
+ Argument* a = f->args->first();
+ while ( a ) {
+ TQCString type = a->leftType + ' ' + a->rightType;
+ type = type.simplifyWhiteSpace();
+ if( a->name.isEmpty() )
+ fprintf( out, "\t{ 0, &static_TQUType_%s, %s, TQUParameter::%s }",
+ uType( type ).data(), uTypeExtra( type ).data(),
+ isInOut( type ) ? "InOut" : "In" );
+ else
+ fprintf( out, "\t{ \"%s\", &static_TQUType_%s, %s, TQUParameter::%s }",
+ a->name.data(), uType( type ).data(), uTypeExtra( type ).data(),
+ isInOut( type ) ? "InOut" : "In" );
+ a = f->args->next();
+ if ( a )
+ fprintf( out, ",\n" );
+ }
+ fprintf( out, "\n };\n");
+ }
+
+ fprintf( out, " static const TQUMethod %s_%d = {", functype, list->at() );
+ int n = f->args->count();
+ if ( hasReturnValue )
+ n++;
+ fprintf( out, "\"%s\", %d,", f->name.data(), n );
+ if ( n )
+ fprintf( out, " param_%s_%d };\n", functype, list->at() );
+ else
+ fprintf( out, " 0 };\n" );
+
+ TQCString typstr = "";
+ int count = 0;
+ Argument *a = f->args->first();
+ while ( a ) {
+ if ( !a->leftType.isEmpty() || ! a->rightType.isEmpty() ) {
+ if ( count++ )
+ typstr += ",";
+ typstr += a->leftType;
+ typstr += a->rightType;
+ }
+ a = f->args->next();
+ }
+ f->signature = f->name;
+ f->signature += "(";
+ f->signature += typstr;
+ f->signature += ")";
+ }
+ if ( list->count() ) {
+ fprintf(out," static const TQMetaData %s_tbl[] = {\n", functype );
+ f = list->first();
+ while ( f ) {
+ fprintf( out, "\t{ \"%s\",", f->signature.data() );
+ fprintf( out, " &%s_%d,", functype, list->at() );
+ fprintf( out, " TQMetaData::%s }", f->accessAsString() );
+ f = list->next();
+ if ( f )
+ fprintf( out, ",\n");
+ }
+ fprintf( out, "\n };\n" );
+ }
+}
+
+
+int enumIndex( const char* type )
+{
+ int index = 0;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit ) {
+ if ( lit.current()->name == type )
+ return index;
+ index++;
+ }
+ return -1;
+}
+
+bool isEnumType( const char* type )
+{
+ return enumIndex( type ) >= 0 || ( g->qtEnums.tqcontains( type ) || g->qtSets.tqcontains( type ) );
+}
+
+bool isPropertyType( const char* type )
+{
+ if ( isVariantType( type ) )
+ return TRUE;
+
+ return isEnumType( type );
+}
+
+int generateEnums()
+{
+ if ( g->enums.count() == 0 )
+ return 0;
+
+ fprintf( out, "#ifndef TQT_NO_PROPERTIES\n" );
+ int i = 0;
+ for ( TQPtrListIterator<Enum> it( g->enums ); it.current(); ++it, ++i ) {
+ fprintf( out, " static const TQMetaEnum::Item enum_%i[] = {\n", i );
+ int k = 0;
+ for( TQStrListIterator eit( *it.current() ); eit.current(); ++eit, ++k ) {
+ if ( k )
+ fprintf( out, ",\n" );
+ fprintf( out, "\t{ \"%s\", (int) %s::%s }", eit.current(), (const char*) g->className, eit.current() );
+ }
+ fprintf( out, "\n };\n" );
+ }
+ fprintf( out, " static const TQMetaEnum enum_tbl[] = {\n" );
+ i = 0;
+ for ( TQPtrListIterator<Enum> it2( g->enums ); it2.current(); ++it2, ++i ) {
+ if ( i )
+ fprintf( out, ",\n" );
+ fprintf( out, "\t{ \"%s\", %u, enum_%i, %s }",
+ (const char*)it2.current()->name,
+ it2.current()->count(),
+ i,
+ it2.current()->set ? "TRUE" : "FALSE" );
+ }
+ fprintf( out, "\n };\n" );
+ fprintf( out, "#endif // TQT_NO_PROPERTIES\n" );
+
+ return g->enums.count();
+}
+
+int generateProps()
+{
+ //
+ // Resolve and verify property access functions
+ //
+ for( TQPtrListIterator<Property> it( g->props ); it.current(); ) {
+ Property* p = it.current();
+ ++it;
+
+ // verify get function
+ if ( !p->get.isEmpty() ) {
+ FuncList candidates = g->propfuncs.tqfind( p->get );
+ for ( Function* f = candidates.first(); f; f = candidates.next() ) {
+ if ( f->qualifier != "const" ) // get functions must be const
+ continue;
+ if ( f->args && !f->args->isEmpty() ) // and must not take any arguments
+ continue;
+ TQCString tmp = f->type;
+ Property::Specification spec = Property::Unspecified;
+ if ( p->type == "TQCString" && (tmp == "const char*" || tmp == "const char *" ) ) {
+ tmp = "TQCString";
+ spec = Property::ConstCharStar;
+ } else if ( tmp.right(1) == "&" ) {
+ tmp = tmp.left( tmp.length() - 1 );
+ spec = Property::Reference;
+ } else if ( tmp.right(1) == "*" ) {
+ tmp = tmp.left( tmp.length() - 1 );
+ spec = Property::Pointer;
+ } else {
+ spec = Property::Class;
+ }
+ if ( tmp.left(6) == "const " )
+ tmp = tmp.mid( 6, tmp.length() - 6 );
+ tmp = tmp.simplifyWhiteSpace();
+ if ( p->type == tmp ) {
+ // If it is an enum then it may not be a set
+ bool ok = TRUE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && lit.current()->set )
+ ok = FALSE;
+ if ( !ok ) continue;
+ p->gspec = spec;
+ p->getfunc = f;
+ p->oredEnum = 0;
+ break;
+ }
+ else if ( !isVariantType( p->type ) ) {
+ if ( tmp == "int" || tmp == "uint" || tmp == "unsigned int" ) {
+ // Test whether the enum is really a set (unfortunately we don't know enums of super classes)
+ bool ok = TRUE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && !lit.current()->set )
+ ok = FALSE;
+ if ( !ok ) continue;
+ p->gspec = spec;
+ p->getfunc = f;
+ p->oredEnum = 1;
+ p->enumgettype = tmp;
+ }
+ }
+ }
+ if ( p->getfunc == 0 ) {
+ if ( displayWarnings ) {
+
+ // Is the type a set, that means, mentioned in TQ_SETS?
+ bool set = FALSE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && lit.current()->set )
+ set = TRUE;
+
+ fprintf( stderr, ErrorFormatString" Warning: Property '%s' not available.\n",
+ g->fileName.data(), p->lineNo, (const char*) p->name );
+ fprintf( stderr, " Have been looking for public get functions \n");
+ if ( !set ) {
+ fprintf( stderr,
+ " %s %s() const\n"
+ " %s& %s() const\n"
+ " const %s& %s() const\n"
+ " %s* %s() const\n",
+ (const char*) p->type, (const char*) p->get,
+ (const char*) p->type, (const char*) p->get,
+ (const char*) p->type, (const char*) p->get,
+ (const char*) p->type, (const char*) p->get );
+ }
+ if ( set || !isPropertyType( p->type ) ) {
+ fprintf( stderr,
+ " int %s() const\n"
+ " uint %s() const\n"
+ " unsigned int %s() const\n",
+ (const char*) p->get,
+ (const char*) p->get,
+ (const char*) p->get );
+ }
+ if ( p->type == "TQCString" )
+ fprintf( stderr, " const char* %s() const\n",
+ (const char*)p->get );
+
+ if ( candidates.isEmpty() ) {
+ fprintf( stderr, " but found nothing.\n");
+ } else {
+ fprintf( stderr, " but only found the mismatching candidate(s)\n");
+ for ( Function* f = candidates.first(); f; f = candidates.next() ) {
+ TQCString typstr = "";
+ Argument *a = f->args->first();
+ int count = 0;
+ while ( a ) {
+ if ( !a->leftType.isEmpty() || ! a->rightType.isEmpty() ) {
+ if ( count++ )
+ typstr += ",";
+ typstr += a->leftType;
+ typstr += a->rightType;
+ }
+ a = f->args->next();
+ }
+ fprintf( stderr, " %s:%d: %s %s(%s) %s\n", g->fileName.data(), f->lineNo,
+ (const char*) f->type,(const char*) f->name, (const char*) typstr,
+ f->qualifier.isNull()?"":(const char*) f->qualifier );
+ }
+ }
+ }
+ }
+ }
+
+ // verify set function
+ if ( !p->set.isEmpty() ) {
+ FuncList candidates = g->propfuncs.tqfind( p->set );
+ for ( Function* f = candidates.first(); f; f = candidates.next() ) {
+ if ( !f->args || f->args->isEmpty() )
+ continue;
+ TQCString tmp = f->args->first()->leftType;
+ tmp = tmp.simplifyWhiteSpace();
+ Property::Specification spec = Property::Unspecified;
+ if ( tmp.right(1) == "&" ) {
+ tmp = tmp.left( tmp.length() - 1 );
+ spec = Property::Reference;
+ }
+ else {
+ spec = Property::Class;
+ }
+ if ( p->type == "TQCString" && (tmp == "const char*" || tmp == "const char *" ) ) {
+ tmp = "TQCString";
+ spec = Property::ConstCharStar;
+ }
+ if ( tmp.left(6) == "const " )
+ tmp = tmp.mid( 6, tmp.length() - 6 );
+ tmp = tmp.simplifyWhiteSpace();
+
+ if ( p->type == tmp && f->args->count() == 1 ) {
+ // If it is an enum then it may not be a set
+ if ( p->oredEnum == 1 )
+ continue;
+ bool ok = TRUE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && lit.current()->set )
+ ok = FALSE;
+ if ( !ok ) continue;
+ p->sspec = spec;
+ p->setfunc = f;
+ p->oredEnum = 0;
+ break;
+ } else if ( !isVariantType( p->type ) && f->args->count() == 1 ) {
+ if ( tmp == "int" || tmp == "uint" || tmp == "unsigned int" ) {
+ if ( p->oredEnum == 0 )
+ continue;
+ // Test wether the enum is really a set (unfortunately we don't know enums of super classes)
+ bool ok = TRUE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && !lit.current()->set )
+ ok = FALSE;
+ if ( !ok ) continue;
+ p->sspec = spec;
+ p->setfunc = f;
+ p->oredEnum = 1;
+ p->enumsettype = tmp;
+ }
+ }
+ }
+ if ( p->setfunc == 0 ) {
+ if ( displayWarnings ) {
+
+ // Is the type a set, that means, mentioned in TQ_SETS ?
+ bool set = FALSE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && lit.current()->set )
+ set = TRUE;
+
+ fprintf( stderr, ErrorFormatString" Warning: Property '%s' not writable.\n",
+ g->fileName.data(), p->lineNo, (const char*) p->name );
+ fprintf( stderr, " Have been looking for public set functions \n");
+ if ( !set && p->oredEnum != 1 ) {
+ fprintf( stderr,
+ " void %s( %s )\n"
+ " void %s( %s& )\n"
+ " void %s( const %s& )\n",
+ (const char*) p->set, (const char*) p->type,
+ (const char*) p->set, (const char*) p->type,
+ (const char*) p->set, (const char*) p->type );
+ }
+ if ( set || ( !isPropertyType( p->type ) && p->oredEnum != 0 ) ) {
+ fprintf( stderr,
+ " void %s( int )\n"
+ " void %s( uint )\n"
+ " void %s( unsigned int )\n",
+ (const char*) p->set,
+ (const char*) p->set,
+ (const char*) p->set );
+ }
+
+ if ( p->type == "TQCString" )
+ fprintf( stderr, " void %s( const char* ) const\n",
+ (const char*) p->set );
+
+ if ( !candidates.isEmpty() ) {
+ fprintf( stderr, " but only found the mismatching candidate(s)\n");
+ for ( Function* f = candidates.first(); f; f = candidates.next() ) {
+ TQCString typstr = "";
+ Argument *a = f->args->first();
+ int count = 0;
+ while ( a ) {
+ if ( !a->leftType.isEmpty() || ! a->rightType.isEmpty() ) {
+ if ( count++ )
+ typstr += ",";
+ typstr += a->leftType;
+ typstr += a->rightType;
+ }
+ a = f->args->next();
+ }
+ fprintf( stderr, " %s:%d: %s %s(%s)\n", g->fileName.data(), f->lineNo,
+ (const char*) f->type,(const char*) f->name, (const char*) typstr );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //
+ // Create meta data
+ //
+ if ( g->props.count() ) {
+ if ( displayWarnings && !TQ_OBJECTdetected )
+ tqmoc_err("The declaration of the class \"%s\" tqcontains properties"
+ " but no TQ_OBJECT macro.", g->className.data());
+
+ fprintf( out, "#ifndef TQT_NO_PROPERTIES\n" );
+
+ fprintf( out, " static const TQMetaProperty props_tbl[%d] = {\n ", g->props.count() );
+ for( TQPtrListIterator<Property> it( g->props ); it.current(); ++it ) {
+
+ fprintf( out, "\t{ \"%s\",\"%s\", ", it.current()->type.data(), it.current()->name.data() );
+ int flags = Invalid;
+ if ( !isVariantType( it.current()->type ) ) {
+ flags |= EnumOrSet;
+ if ( !isEnumType( it.current()->type ) )
+ flags |= UnresolvedEnum;
+ } else {
+ flags |= qvariant_nameToType( it.current()->type ) << 24;
+ }
+ if ( it.current()->getfunc )
+ flags |= Readable;
+ if ( it.current()->setfunc ) {
+ flags |= Writable;
+ if ( it.current()->stdSet() )
+ flags |= StdSet;
+ }
+ if ( it.current()->override )
+ flags |= Override;
+
+ if ( it.current()->designable.isEmpty() )
+ flags |= DesignableOverride;
+ else if ( it.current()->designable == "false" )
+ flags |= NotDesignable;
+
+ if ( it.current()->scriptable.isEmpty() )
+ flags |= ScriptableOverride;
+ else if ( it.current()->scriptable == "false" )
+ flags |= NotScriptable;
+
+ if ( it.current()->stored.isEmpty() )
+ flags |= StoredOverride;
+ else if ( it.current()->stored == "false" )
+ flags |= NotStored;
+
+
+ fprintf( out, "0x%.4x, ", flags );
+ fprintf( out, "&%s::metaObj, ", (const char*) qualifiedClassName() );
+ if ( !isVariantType( it.current()->type ) ) {
+ int enumpos = -1;
+ int k = 0;
+ for( TQPtrListIterator<Enum> eit( g->enums ); eit.current(); ++eit, ++k ) {
+ if ( eit.current()->name == it.current()->type )
+ enumpos = k;
+ }
+
+ // Is it an enum of this class ?
+ if ( enumpos != -1 )
+ fprintf( out, "&enum_tbl[%i], ", enumpos );
+ else
+ fprintf( out, "0, ");
+ } else {
+ fprintf( out, "0, ");
+ }
+ fprintf( out, "-1 }" );
+ if ( !it.atLast() )
+ fprintf( out, ",\n" );
+ else
+ fprintf( out, "\n" );
+ }
+ fprintf( out, " };\n" );
+ fprintf( out, "#endif // TQT_NO_PROPERTIES\n" );
+ }
+
+ return g->props.count();
+}
+
+
+
+int generateClassInfos()
+{
+ if ( g->infos.isEmpty() )
+ return 0;
+
+ if ( displayWarnings && !TQ_OBJECTdetected )
+ tqmoc_err("The declaration of the class \"%s\" tqcontains class infos"
+ " but no TQ_OBJECT macro.", g->className.data());
+
+ fprintf( out, " static const TQClassInfo classinfo_tbl[] = {\n" );
+ int i = 0;
+ for( TQPtrListIterator<ClassInfo> it( g->infos ); it.current(); ++it, ++i ) {
+ if ( i )
+ fprintf( out, ",\n" );
+ fprintf( out, "\t{ \"%s\", \"%s\" }", it.current()->name.data(),it.current()->value.data() );
+ }
+ fprintf( out, "\n };\n" );
+ return i;
+}
+
+
+void generateClass() // generate C++ source code for a class
+{
+ const char *hdr1 = "/****************************************************************************\n"
+ "** %s meta object code from reading C++ file '%s'\n**\n";
+ const char *hdr2 = "** Created: %s\n";
+ const char *hdr3 = "** WARNING! All changes made in this file will be lost!\n";
+ const char *hdr4 = "*****************************************************************************/\n\n";
+ int i;
+
+ if ( skipClass ) // don't generate for class
+ return;
+
+ if ( !TQ_OBJECTdetected ) {
+ if ( g->tqsignals.count() == 0 && g->tqslots.count() == 0 && g->props.count() == 0 && g->infos.count() == 0 )
+ return;
+ if ( displayWarnings && (g->tqsignals.count() + g->tqslots.count()) != 0 )
+ tqmoc_err("The declaration of the class \"%s\" tqcontains tqsignals "
+ "or tqslots\n\t but no TQ_OBJECT macro.", g->className.data());
+ } else {
+ if ( g->superClassName.isEmpty() )
+ tqmoc_err("The declaration of the class \"%s\" tqcontains the\n"
+ "\tTQ_OBJECT macro but does not inherit from any class!\n"
+ "\tInherit from TQObject or one of its descendants"
+ " or remove TQ_OBJECT.", g->className.data() );
+ }
+ if ( templateClass ) { // don't generate for class
+ tqmoc_err( "Sorry, TQt does not support templates that contain\n"
+ "\ttqsignals, tqslots or TQ_OBJECT." );
+ return;
+ }
+ g->generatedCode = TRUE;
+ g->gen_count++;
+
+ if ( g->gen_count == 1 ) { // first class to be generated
+ TQDateTime dt = TQDateTime::tqcurrentDateTime();
+ TQCString dstr = dt.toString().ascii();
+ TQCString fn = g->fileName;
+ i = g->fileName.length()-1;
+ while ( i>0 && g->fileName[i-1] != '/' && g->fileName[i-1] != '\\' )
+ i--; // skip path
+ if ( i >= 0 )
+ fn = g->fileName.tqstringFromPos(i);
+ fprintf( out, hdr1, (const char*)qualifiedClassName(),(const char*)fn);
+ fprintf( out, hdr2, (const char*)dstr );
+ fprintf( out, hdr3 );
+ fprintf( out, hdr4 );
+
+ if ( !g->noInclude ) {
+ /*
+ The header file might be a TQt header file with
+ TQT_NO_COMPAT macros around tqsignals, tqslots or
+ properties. Without the #undef, we cannot compile the
+ TQt library with TQT_NO_COMPAT defined.
+
+ Header files of libraries build around TQt can also use
+ TQT_NO_COMPAT, so this #undef might be beneficial to
+ users of TQt, and not only to developers of TQt.
+ */
+ fprintf( out, "#undef TQT_NO_COMPAT\n" );
+
+ if ( !g->pchFile.isEmpty() )
+ fprintf( out, "#include \"%s\" // PCH include\n", (const char*)g->pchFile );
+ if ( !g->includePath.isEmpty() && g->includePath.right(1) != "/" )
+ g->includePath += "/";
+
+ g->includeFiles.first();
+ while ( g->includeFiles.current() ) {
+ TQCString inc = g->includeFiles.current();
+ if ( inc[0] != '<' && inc[0] != '"' ) {
+ if ( !g->includePath.isEmpty() && g->includePath != "./" )
+ inc.prepend( g->includePath );
+ inc = "\"" + inc + "\"";
+ }
+ fprintf( out, "#include %s\n", (const char *)inc );
+ g->includeFiles.next();
+ }
+ }
+ fprintf( out, "#include <%stqmetaobject.h>\n", (const char*)g->qtPath );
+ fprintf( out, "#include <%stqapplication.h>\n\n", (const char*)g->qtPath );
+ fprintf( out, "#include <%sprivate/tqucomextra_p.h>\n", (const char*)g->qtPath );
+ fprintf( out, "#if !defined(TQ_TQMOC_OUTPUT_REVISION) || (TQ_TQMOC_OUTPUT_REVISION != %d)\n", formatRevision );
+ fprintf( out, "#error \"This file was generated using the tqmoc from %s."
+ " It\"\n#error \"cannot be used with the include files from"
+ " this version of TQt.\"\n#error \"(The tqmoc has changed too"
+ " much.)\"\n", TQT_VERSION_STR );
+ fprintf( out, "#endif\n\n" );
+ } else {
+ fprintf( out, "\n\n" );
+ }
+
+ if ( !g->hasVariantIncluded ) {
+ bool needToIncludeVariant = !g->props.isEmpty();
+ for ( Function* f =g->tqslots.first(); f && !needToIncludeVariant; f=g->tqslots.next() )
+ needToIncludeVariant = ( f->type != "void" && !validUType( f->type ) && isVariantType( f->type) );
+
+ if ( needToIncludeVariant ) {
+ fprintf( out, "#include <%stqvariant.h>\n", (const char*)g->qtPath );
+ g->hasVariantIncluded = TRUE;
+ }
+ }
+
+ bool isTQObject = g->className == "TQObject" ;
+
+
+//
+// Generate virtual function className()
+//
+ fprintf( out, "const char *%s::className() const\n{\n ",
+ (const char*)qualifiedClassName() );
+ fprintf( out, "return \"%s\";\n}\n\n", (const char*)qualifiedClassName() );
+
+//
+// Generate static metaObj variable
+//
+ fprintf( out, "TQMetaObject *%s::metaObj = 0;\n", (const char*)qualifiedClassName());
+
+//
+// Generate static cleanup object variable
+//
+ TQCString cleanup = qualifiedClassName().copy();
+ for ( int cnpos = 0; cnpos < cleanup.length(); cnpos++ ) {
+ if ( cleanup[cnpos] == ':' )
+ cleanup[cnpos] = '_';
+ }
+
+ fprintf( out, "static TQMetaObjectCleanUp cleanUp_%s( \"%s\", &%s::staticMetaObject );\n\n", (const char*)cleanup, (const char*)qualifiedClassName(), (const char*)qualifiedClassName() );
+
+//
+// Generate tr and trUtf8 member functions
+//
+ fprintf( out, "#ifndef TQT_NO_TRANSLATION\n" );
+ fprintf( out, "TQString %s::tr( const char *s, const char *c )\n{\n",
+ (const char*)qualifiedClassName() );
+ fprintf( out, " if ( tqApp )\n" );
+ fprintf( out, "\treturn tqApp->translate( \"%s\", s, c,"
+ " TQApplication::DefaultCodec );\n",
+ (const char*)qualifiedClassName() );
+ fprintf( out, " else\n" );
+ fprintf( out, "\treturn TQString::tqfromLatin1( s );\n");
+ fprintf( out, "}\n" );
+ fprintf( out, "#ifndef TQT_NO_TRANSLATION_UTF8\n" );
+ fprintf( out, "TQString %s::trUtf8( const char *s, const char *c )\n{\n",
+ (const char*)qualifiedClassName() );
+ fprintf( out, " if ( tqApp )\n" );
+ fprintf( out, "\treturn tqApp->translate( \"%s\", s, c,"
+ " TQApplication::UnicodeUTF8 );\n",
+ (const char*)qualifiedClassName() );
+ fprintf( out, " else\n" );
+ fprintf( out, "\treturn TQString::fromUtf8( s );\n" );
+ fprintf( out, "}\n" );
+ fprintf( out, "#endif // TQT_NO_TRANSLATION_UTF8\n\n" );
+ fprintf( out, "#endif // TQT_NO_TRANSLATION\n\n" );
+
+//
+// Generate staticMetaObject member function
+//
+ fprintf( out, "TQMetaObject* %s::staticMetaObject()\n{\n", (const char*)qualifiedClassName() );
+ fprintf( out, " if ( metaObj )\n\treturn metaObj;\n" );
+ if ( isTQObject )
+ fprintf( out, " TQMetaObject* parentObject = staticTQtMetaObject();\n" );
+ else if ( !g->superClassName.isEmpty() )
+ if (g->superClassName.tqfind("TQ") == 0) { // [FIXME] Verify that this will always be able to detect a TQt base class, even if intermediate classes do not start with TQ
+ fprintf( out, " TQMetaObject* parentObject = %s::staticMetaObject();\n", (const char*)g->superClassName );
+ }
+ else {
+ fprintf( out, " TQMetaObject* parentObject = 0;\n" );
+ }
+ else
+ fprintf( out, " TQMetaObject* parentObject = 0;\n" );
+
+//
+// Build the classinfo array
+//
+ int n_infos = generateClassInfos();
+
+// Build the enums array
+// Enums HAVE to be generated BEFORE the properties and tqslots
+//
+ int n_enums = generateEnums();
+
+//
+// Build tqslots array in staticMetaObject()
+//
+ generateFuncs( &g->tqslots, "slot", Slot_Num );
+
+//
+// Build tqsignals array in staticMetaObject()
+//
+ generateFuncs( &g->tqsignals, "signal", Signal_Num );
+
+//
+// Build property array in staticMetaObject()
+//
+ int n_props = generateProps();
+
+//
+// Finally code to create and return meta object
+//
+ fprintf( out, " metaObj = TQMetaObject::new_metaobject(\n"
+ "\t\"%s\", parentObject,\n", (const char*)qualifiedClassName() );
+
+ if ( g->tqslots.count() )
+ fprintf( out, "\tslot_tbl, %d,\n", g->tqslots.count() );
+ else
+ fprintf( out, "\t0, 0,\n" );
+
+ if ( g->tqsignals.count() )
+ fprintf( out, "\tsignal_tbl, %d,\n", g->tqsignals.count() );
+ else
+ fprintf( out, "\t0, 0,\n" );
+
+ fprintf( out, "#ifndef TQT_NO_PROPERTIES\n" );
+ if ( n_props )
+ fprintf( out, "\tprops_tbl, %d,\n", n_props );
+ else
+ fprintf( out, "\t0, 0,\n" );
+ if ( n_enums )
+ fprintf( out, "\tenum_tbl, %d,\n", n_enums );
+ else
+ fprintf( out, "\t0, 0,\n" );
+ fprintf( out, "#endif // TQT_NO_PROPERTIES\n" );
+
+ if ( n_infos )
+ fprintf( out, "\tclassinfo_tbl, %d );\n", n_infos );
+ else
+ fprintf( out, "\t0, 0 );\n" );
+
+
+//
+// Setup cleanup handler and return meta object
+//
+ fprintf( out, " cleanUp_%s.setMetaObject( metaObj );\n", cleanup.data() );
+ fprintf( out, " return metaObj;\n}\n" );
+
+//
+// End of function staticMetaObject()
+//
+
+//
+// Generate smart cast function
+//
+ fprintf( out, "\nvoid* %s::qt_cast( const char* clname )\n{\n",
+ (const char*)qualifiedClassName() );
+ fprintf( out, " if ( !qstrcmp( clname, \"%s\" ) )\n"
+ "\treturn this;\n",
+ (const char*)qualifiedClassName() );
+ for ( const char* cname = g->multipleSuperClasses.first(); cname; cname = g->multipleSuperClasses.next() ) {
+ fprintf( out, " if ( !qstrcmp( clname, \"%s\" ) )\n", cname);
+ TQCString fixed(cname);
+ while (fixed.tqfind(">>") != -1)
+ fixed = fixed.tqreplace(">>", "> >");
+ fprintf( out, "\treturn (%s*)this;\n", fixed.data());
+ }
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, " return %sqt_cast( clname );\n",
+ (const char*)callablePurestSuperClassName() );
+ else
+ fprintf( out, " return 0;\n" );
+ fprintf( out, "}\n" );
+
+//
+// Generate internal signal functions
+//
+ Function *f;
+ f = g->tqsignals.first(); // make internal signal methods
+ static bool included_list_headers = FALSE;
+ int sigindex = 0;
+ while ( f ) {
+ TQCString argstr;
+ char buf[12];
+ Argument *a = f->args->first();
+ int offset = 0;
+ const char *predef_call_func = 0;
+ bool hasReturnValue = f->type != "void" && (validUType( f->type ) || isVariantType( f->type) );
+ if ( hasReturnValue ) {
+ ; // no predefined function available
+ } else if ( !a ) {
+ predef_call_func = "activate_signal";
+ } else if ( f->args->count() == 1 ) {
+ TQCString ctype = (a->leftType + ' ' + a->rightType).simplifyWhiteSpace();
+ if ( !isInOut( ctype ) ) {
+ TQCString utype = uType( ctype );
+ if ( utype == "bool" )
+ predef_call_func = "activate_signal_bool";
+ else if ( utype == "TQString" || utype == "int" || utype == "double" )
+ predef_call_func = "activate_signal";
+ }
+ }
+
+ if ( !predef_call_func && !included_list_headers ) {
+ // yes we need it, because otherwise TQT_VERSION may not be defined
+ fprintf( out, "\n#include <%stqobjectdefs.h>\n", (const char*)g->qtPath );
+ fprintf( out, "#include <%stqsignalslotimp.h>\n", (const char*)g->qtPath );
+ included_list_headers = TRUE;
+ }
+
+ while ( a ) { // argument list
+ if ( !a->leftType.isEmpty() || !a->rightType.isEmpty() ) {
+ argstr += a->leftType;
+ argstr += " ";
+ sprintf( buf, "t%d", offset++ );
+ argstr += buf;
+ argstr += a->rightType;
+ a = f->args->next();
+ if ( a )
+ argstr += ", ";
+ } else {
+ a = f->args->next();
+ }
+ }
+
+ fixRightAngles( &argstr );
+
+ fprintf( out, "\n// SIGNAL %s\n", (const char*)f->name );
+ fprintf( out, "%s %s::%s(", (const char*) f->type,
+ (const char*)qualifiedClassName(),
+ (const char*)f->name );
+
+ if ( argstr.isEmpty() )
+ fprintf( out, ")\n{\n" );
+ else
+ fprintf( out, " %s )\n{\n", (const char*)argstr );
+
+ if ( predef_call_func ) {
+ fprintf( out, " %s%s( staticMetaObject()->signalOffset() + %d", (const char *) callablePurestSuperClassName(), predef_call_func, sigindex );
+ if ( !argstr.isEmpty() )
+ fprintf( out, ", t0" );
+ fprintf( out, " );\n}\n" );
+ } else {
+ if ( hasReturnValue )
+ fprintf( out, " %s something;\n", f->type.data() );
+ int nargs = f->args->count();
+ fprintf( out, " if ( tqsignalsBlocked() )\n\treturn%s;\n", hasReturnValue ? " something" : "" );
+ fprintf( out, " TQConnectionList *clist = tqreceivers( staticMetaObject()->signalOffset() + %d );\n",
+ sigindex );
+ fprintf( out, " if ( !clist )\n\treturn%s;\n", hasReturnValue ? " something" : "" );
+ fprintf( out, " TQUObject o[%d];\n", f->args->count() + 1 );
+
+ // initialize return value to something
+ if ( hasReturnValue ) {
+ if ( validUType( f->type ) ) {
+ TQCString utype = uType( f->type );
+ fprintf( out, " static_TQUType_%s.set(o,something);\n", utype.data() );
+ } else if ( uType( f->type ) == "varptr" ) {
+ fprintf( out, " static_TQUType_varptr.set(o,&something);\n" );
+ } else {
+ fprintf( out, " static_TQUType_ptr.set(o,&something);\n" );
+ }
+ }
+
+ // initialize arguments
+ if ( !f->args->isEmpty() ) {
+ offset = 0;
+ Argument* a = f->args->first();
+ while ( a ) {
+ TQCString type = a->leftType + ' ' + a->rightType;
+ type = type.simplifyWhiteSpace();
+ if ( validUType( type ) ) {
+ TQCString utype = uType( type );
+ fprintf( out, " static_TQUType_%s.set(o+%d,t%d);\n", utype.data(), offset+1, offset );
+ } else if ( uType( type ) == "varptr" ) {
+ fprintf( out, " static_TQUType_varptr.set(o+%d,&t%d);\n", offset+1, offset );
+ } else {
+ fprintf( out, " static_TQUType_ptr.set(o+%d,&t%d);\n", offset+1, offset );
+ }
+ a = f->args->next();
+ offset++;
+ }
+ }
+ fprintf( out, " activate_signal( clist, o );\n" );
+
+ // get return values from inOut parameters
+ if ( !f->args->isEmpty() ) {
+ offset = 0;
+ Argument* a = f->args->first();
+ while ( a ) {
+ TQCString type = a->leftType + ' ' + a->rightType;
+ type = type.simplifyWhiteSpace();
+ if ( validUType( type ) && isInOut( type ) ) {
+ TQCString utype = uType( type );
+ if ( utype == "enum" )
+ fprintf( out, " t%d = (%s)static_TQUType_%s.get(o+%d);\n", offset, type.data(), utype.data(), offset+1 );
+ else if ( utype == "ptr" && type.right(2) == "**" )
+ fprintf( out, " if (t%d) *t%d = *(%s)static_TQUType_ptr.get(o+%d);\n", offset, offset, type.data(), offset+1 );
+ else
+ fprintf( out, " t%d = static_TQUType_%s.get(o+%d);\n", offset, utype.data(), offset+1 );
+ }
+ a = f->args->next();
+ offset++;
+ }
+ }
+
+ // get and return return value
+ if ( hasReturnValue ) {
+ TQCString utype = uType( f->type );
+ if ( utype == "enum" || utype == "ptr" || utype == "varptr" ) // need cast
+ fprintf( out, " return (%s)static_TQUType_%s.get(o);\n", f->type.data(), utype.data() );
+ else
+ fprintf( out, " return static_TQUType_%s.get(o);\n", utype.data() );
+ }
+
+ fprintf( out, "}\n" );
+ }
+
+ f = g->tqsignals.next();
+ sigindex++;
+ }
+
+
+//
+// Generate internal qt_invoke() function
+//
+ fprintf( out, "\nbool %s::qt_invoke( int _id, TQUObject* _o )\n{\n", qualifiedClassName().data() );
+
+ if( !g->tqslots.isEmpty() ) {
+ fprintf( out, " switch ( _id - staticMetaObject()->slotOffset() ) {\n" );
+ int slotindex = -1;
+ for ( f = g->tqslots.first(); f; f = g->tqslots.next() ) {
+ slotindex ++;
+ if ( f->type == "void" && f->args->isEmpty() ) {
+ fprintf( out, " case %d: %s(); break;\n", slotindex, f->name.data() );
+ continue;
+ }
+
+ fprintf( out, " case %d: ", slotindex );
+ bool hasReturnValue = FALSE;
+ bool hasVariantReturn = FALSE;
+ if ( f->type != "void" ) {
+ if ( validUType( f->type )) {
+ hasReturnValue = TRUE;
+ fprintf( out, "static_TQUType_%s.set(_o,", uType(f->type).data() );
+ } else if ( isVariantType( f->type ) ) {
+ hasReturnValue = hasVariantReturn = TRUE;
+ // do not need special handling for bool since this is handled as utype
+ fprintf( out, "static_TQUType_TQVariant.set(_o,TQVariant(" );
+ }
+ }
+ int offset = 0;
+ fprintf( out, "%s(", f->name.data() );
+ Argument* a = f->args->first();
+ while ( a ) {
+ TQCString type = a->leftType + ' ' + a->rightType;
+ type = type.simplifyWhiteSpace();
+ fixRightAngles( &type );
+ if ( validUType( type ) ) {
+ TQCString utype = uType( type );
+ if ( utype == "ptr" || utype == "varptr" || utype == "enum" )
+ fprintf( out, "(%s)static_TQUType_%s.get(_o+%d)", type.data(), utype.data(), offset+1 );
+ else
+ fprintf( out, "(%s)static_TQUType_%s.get(_o+%d)", type.data(), utype.data(), offset+1 );
+ } else {
+ TQCString castType = castToUType( type );
+ if(castType == type)
+ fprintf( out, "(%s)(*((%s*)static_TQUType_ptr.get(_o+%d)))", type.data(),
+ castType.data(), offset+1 );
+ else
+ fprintf( out, "(%s)*((%s*)static_TQUType_ptr.get(_o+%d))", type.data(),
+ castType.data(), offset+1 );
+ }
+ a = f->args->next();
+ if ( a )
+ fprintf( out, "," );
+ offset++;
+ }
+ fprintf( out, ")" );
+ if ( hasReturnValue )
+ fprintf( out, ")" );
+ if ( hasVariantReturn )
+ fprintf( out, ")" );
+ fprintf( out, "; break;\n" );
+ }
+ fprintf( out, " default:\n" );
+
+ if ( !g->superClassName.isEmpty() && !isTQObject ) {
+ fprintf( out, "\treturn %sqt_invoke( _id, _o );\n",
+ (const char *) callablePurestSuperClassName() );
+ } else {
+ fprintf( out, "\treturn FALSE;\n" );
+ }
+ fprintf( out, " }\n" );
+ fprintf( out, " return TRUE;\n}\n" );
+ } else {
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, " return %sqt_invoke(_id,_o);\n}\n",
+ (const char *) callablePurestSuperClassName() );
+ else
+ fprintf( out, " return FALSE;\n}\n" );
+ }
+
+
+//
+// Generate internal qt_emit() function
+//
+ fprintf( out, "\nbool %s::qt_emit( int _id, TQUObject* _o )\n{\n", qualifiedClassName().data() );
+
+ if ( !g->tqsignals.isEmpty() ) {
+ fprintf( out, " switch ( _id - staticMetaObject()->signalOffset() ) {\n" );
+ int signalindex = -1;
+ for ( f = g->tqsignals.first(); f; f = g->tqsignals.next() ) {
+ signalindex++;
+ if ( f->type == "void" && f->args->isEmpty() ) {
+ fprintf( out, " case %d: %s(); break;\n", signalindex, f->name.data() );
+ continue;
+ }
+
+ fprintf( out, " case %d: ", signalindex );
+ bool hasReturnValue = FALSE;
+ if ( f->type != "void" && validUType( f->type )) {
+ hasReturnValue = TRUE;
+ fprintf( out, "static_TQUType_%s.set(_o,", uType(f->type).data() );
+ }
+ int offset = 0;
+ fprintf( out, "%s(", f->name.data() );
+ Argument* a = f->args->first();
+ while ( a ) {
+ TQCString type = a->leftType + ' ' + a->rightType;
+ type = type.simplifyWhiteSpace();
+ fixRightAngles( &type );
+ if ( validUType( type ) ) {
+ TQCString utype = uType( type );
+ if ( utype == "ptr" || utype == "varptr" || utype == "enum" )
+ fprintf( out, "(%s)static_TQUType_%s.get(_o+%d)", type.data(), utype.data(), offset+1 );
+ else
+ fprintf( out, "(%s)static_TQUType_%s.get(_o+%d)", type.data(), utype.data(), offset+1 );
+ } else {
+ TQCString castType = castToUType( type );
+ if(castType == type)
+ fprintf( out, "(%s)(*((%s*)static_TQUType_ptr.get(_o+%d)))", type.data(),
+ castType.data(), offset+1 );
+ else
+ fprintf( out, "(%s)*((%s*)static_TQUType_ptr.get(_o+%d))", type.data(),
+ castType.data(), offset+1 );
+ }
+ a = f->args->next();
+ if ( a )
+ fprintf( out, "," );
+ offset++;
+ }
+ fprintf( out, ")" );
+ if ( hasReturnValue )
+ fprintf( out, ")" );
+ fprintf( out, "; break;\n" );
+ }
+ fprintf( out, " default:\n" );
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, "\treturn %sqt_emit(_id,_o);\n",
+ (const char *) callablePurestSuperClassName() );
+ else
+ fprintf( out, "\treturn FALSE;\n" );
+ fprintf( out, " }\n" );
+ fprintf( out, " return TRUE;\n}\n" );
+ } else {
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, " return %sqt_emit(_id,_o);\n}\n",
+ (const char *) callablePurestSuperClassName() );
+ else
+ fprintf( out, " return FALSE;\n}\n" );
+ }
+
+
+ fprintf( out, "#ifndef TQT_NO_PROPERTIES\n" );
+//
+// Generate internal qt_property() functions
+//
+
+ fprintf( out, "\nbool %s::qt_property( int id, int f, TQVariant* v)\n{\n", qualifiedClassName().data() );
+
+ if ( !g->props.isEmpty() ) {
+ fprintf( out, " switch ( id - staticMetaObject()->propertyOffset() ) {\n" );
+ int propindex = -1;
+ bool need_resolve = FALSE;
+
+ for( TQPtrListIterator<Property> it( g->props ); it.current(); ++it ){
+ propindex ++;
+ fprintf( out, " case %d: ", propindex );
+ fprintf( out, "switch( f ) {\n" );
+
+ uint flag_break = 0;
+ uint flag_propagate = 0;
+
+ if ( it.current()->setfunc ) {
+ fprintf( out, "\tcase 0: %s(", it.current()->setfunc->name.data() );
+ TQCString type = it.current()->type.copy(); // detach on purpose
+ if ( it.current()->oredEnum )
+ type = it.current()->enumsettype;
+ if ( type == "uint" )
+ fprintf( out, "v->asUInt()" );
+ else if ( type == "unsigned int" )
+ fprintf( out, "(uint)v->asUInt()" );
+ else if ( type == "TQMap<TQString,TQVariant>" )
+ fprintf( out, "v->asMap()" );
+ else if ( type == "TQValueList<TQVariant>" )
+ fprintf( out, "v->asList()" );
+ else if ( type == "TQ_LLONG" )
+ fprintf( out, "v->asLongLong()" );
+ else if ( type == "TQ_ULLONG" )
+ fprintf( out, "v->asULongLong()" );
+ else if ( isVariantType( type ) ) {
+ if (( type[0] == 'T' ) && ( type[1] == 'Q' ))
+ type = type.mid(2);
+ else
+ type[0] = toupper( type[0] );
+ fprintf( out, "v->as%s()", type.data() );
+ } else {
+ fprintf( out, "(%s&)v->asInt()", type.data() );
+ }
+ fprintf( out, "); break;\n" );
+
+ } else if ( it.current()->override ) {
+ flag_propagate |= 1 << (0+1);
+ }
+ if ( it.current()->getfunc ) {
+ if ( it.current()->gspec == Property::Pointer )
+ fprintf( out, "\tcase 1: if ( this->%s() ) *v = TQVariant( %s*%s()%s ); break;\n",
+ it.current()->getfunc->name.data(),
+ !isVariantType( it.current()->type ) ? "(int)" : "",
+ it.current()->getfunc->name.data(),
+ it.current()->type == "bool" ? ", 0" : "" );
+ else
+ fprintf( out, "\tcase 1: *v = TQVariant( %sthis->%s()%s ); break;\n",
+ !isVariantType( it.current()->type ) ? "(int)" : "",
+ it.current()->getfunc->name.data(),
+ it.current()->type == "bool" ? ", 0" : "" );
+ } else if ( it.current()->override ) {
+ flag_propagate |= 1<< (1+1);
+ }
+
+ if ( !it.current()->reset.isEmpty() )
+ fprintf( out, "\tcase 2: this->%s(); break;\n", it.current()->reset.data() );
+
+ if ( it.current()->designable.isEmpty() )
+ flag_propagate |= 1 << (3+1);
+ else if ( it.current()->designable == "true" )
+ flag_break |= 1 << (3+1);
+ else if ( it.current()->designable != "false" )
+ fprintf( out, "\tcase 3: return this->%s();\n", it.current()->designable.data() );
+
+ if ( it.current()->scriptable.isEmpty() )
+ flag_propagate |= 1 << (4+1);
+ else if ( it.current()->scriptable == "true" )
+ flag_break |= 1 << (4+1);
+ else if ( it.current()->scriptable != "false" )
+ fprintf( out, "\tcase 4: return this->%s();\n", it.current()->scriptable.data() );
+
+ if ( it.current()->stored.isEmpty() )
+ flag_propagate |= 1 << (5+1);
+ else if ( it.current()->stored == "true" )
+ flag_break |= 1 << (5+1);
+ else if ( it.current()->stored != "false" )
+ fprintf( out, "\tcase 5: return this->%s();\n", it.current()->stored.data() );
+
+ int i = 0;
+ if ( flag_propagate != 0 ) {
+ fprintf( out, "\t" );
+ for ( i = 0; i <= 5; i++ ) {
+ if ( flag_propagate & (1 << (i+1) ) )
+ fprintf( out, "case %d: ", i );
+ }
+ if (!g->superClassName.isEmpty() && !isTQObject ) {
+ fprintf( out, "goto resolve;\n" );
+ need_resolve = TRUE;
+ } else {
+ fprintf( out, " return FALSE;\n" );
+ }
+ }
+ if ( flag_break != 0 ) {
+ fprintf( out, "\t" );
+ for ( i = 0; i <= 5; i++ ) {
+ if ( flag_break & (1 << (i+1) ) )
+ fprintf( out, "case %d: ", i );
+ }
+ fprintf( out, "break;\n");
+ }
+
+ fprintf( out, "\tdefault: return FALSE;\n } break;\n" );
+ }
+ fprintf( out, " default:\n" );
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, "\treturn %sqt_property( id, f, v );\n",
+ (const char *) callablePurestSuperClassName() );
+ else
+ fprintf( out, "\treturn FALSE;\n" );
+ fprintf( out, " }\n" );
+ fprintf( out, " return TRUE;\n" );
+
+ if ( need_resolve )
+ fprintf( out, "resolve:\n return %sqt_property( staticMetaObject()->resolveProperty(id), f, v );\n",
+ (const char *) callablePurestSuperClassName() );
+ fprintf( out, "}\n" );
+ } else {
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, " return %sqt_property( id, f, v);\n}\n",
+ (const char *) callablePurestSuperClassName() );
+ else
+ fprintf( out, " return FALSE;\n}\n" );
+ }
+
+ fprintf( out, "\nbool %s::qt_static_property( TQObject* , int , int , TQVariant* ){ return FALSE; }\n", qualifiedClassName().data() );
+ fprintf( out, "#endif // TQT_NO_PROPERTIES\n" );
+}
+
+
+ArgList *addArg( Argument *a ) // add argument to list
+{
+ if ( (!a->leftType.isEmpty() || !a->rightType.isEmpty() ) ) //filter out truely void arguments
+ tmpArgList->append( a );
+ return tmpArgList;
+}
+
+void addEnum()
+{
+ // Avoid duplicates
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit ) {
+ if ( lit.current()->name == tmpEnum->name )
+ {
+ if ( displayWarnings )
+ tqmoc_err( "Enum %s defined twice.", (const char*)tmpEnum->name );
+ }
+ }
+
+ // Only look at types mentioned in TQ_ENUMS and TQ_SETS
+ if ( g->qtEnums.tqcontains( tmpEnum->name ) || g->qtSets.tqcontains( tmpEnum->name ) )
+ {
+ g->enums.append( tmpEnum );
+ if ( g->qtSets.tqcontains( tmpEnum->name ) )
+ tmpEnum->set = TRUE;
+ else
+ tmpEnum->set = FALSE;
+ }
+ else
+ delete tmpEnum;
+ tmpEnum = new Enum;
+}
+
+void addMember( Member m )
+{
+ if ( skipFunc ) {
+ tmpFunc->args = tmpArgList; // just to be sure
+ delete tmpFunc;
+ tmpArgList = new ArgList; // ugly but works
+ tmpFunc = new Function;
+ skipFunc = FALSE;
+ return;
+ }
+
+ tmpFunc->type = tmpFunc->type.simplifyWhiteSpace();
+ tmpFunc->access = tmpAccess;
+ tmpFunc->args = tmpArgList;
+ tmpFunc->lineNo = lineNo;
+
+ for ( ;; ) {
+ g->funcs.append( tmpFunc );
+
+ if ( m == SignalMember ) {
+ g->tqsignals.append( tmpFunc );
+ break;
+ } else {
+ if ( m == SlotMember )
+ g->tqslots.append( tmpFunc );
+ // PropertyCandidateMember or SlotMember
+ if ( !tmpFunc->name.isEmpty() && tmpFunc->access == Public )
+ g->propfuncs.append( tmpFunc );
+ if ( !tmpFunc->args || !tmpFunc->args->hasDefaultArguments() )
+ break;
+ tmpFunc = new Function( *tmpFunc );
+ tmpFunc->args = tmpFunc->args->magicClone();
+ }
+ }
+
+ skipFunc = FALSE;
+ tmpFunc = new Function;
+ tmpArgList = new ArgList;
+}
+
+void checkPropertyName( const char* ident )
+{
+ if ( ident[0] == '_' ) {
+ tqmoc_err( "Invalid property name '%s'.", ident );
+ return;
+ }
+}
diff --git a/tqtinterface/qt4/src/tqmoc/tqmoc_lex.cpp b/tqtinterface/qt4/src/tqmoc/tqmoc_lex.cpp
new file mode 100644
index 0000000..6f4f275
--- /dev/null
+++ b/tqtinterface/qt4/src/tqmoc/tqmoc_lex.cpp
@@ -0,0 +1,3319 @@
+#line 2 "tqmoc_lex.cpp"
+
+#line 4 "tqmoc_lex.cpp"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 151
+#define YY_END_OF_BUFFER 152
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[624] =
+ { 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 152, 151,
+ 139, 150, 151, 139, 134, 146, 139, 146, 146, 105,
+ 105, 105, 105, 105, 139, 134, 148, 139, 113, 148,
+ 148, 148, 130, 148, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 139, 134, 140, 139, 140, 140, 106,
+ 106, 106, 106, 15, 16, 139, 134, 141, 139, 141,
+ 141, 107, 107, 107, 107, 107, 28, 29, 139, 134,
+
+ 145, 139, 54, 55, 58, 145, 59, 56, 57, 60,
+ 139, 134, 143, 139, 42, 43, 46, 143, 47, 44,
+ 45, 139, 134, 144, 139, 48, 49, 52, 144, 53,
+ 50, 51, 139, 134, 142, 139, 111, 142, 13, 14,
+ 139, 134, 137, 137, 112, 61, 62, 137, 137, 134,
+ 149, 139, 149, 139, 134, 147, 139, 147, 139, 134,
+ 34, 35, 100, 100, 100, 100, 100, 104, 101, 102,
+ 103, 139, 136, 135, 139, 134, 134, 134, 0, 108,
+ 0, 105, 105, 105, 105, 105, 113, 0, 0, 123,
+ 0, 0, 132, 131, 130, 92, 99, 99, 99, 99,
+
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 0, 109,
+ 0, 106, 106, 106, 106, 106, 0, 110, 0, 107,
+ 107, 107, 107, 107, 111, 0, 138, 112, 0, 138,
+ 100, 100, 100, 100, 100, 100, 104, 0, 135, 134,
+ 105, 105, 105, 105, 114, 0, 0, 114, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 93,
+ 131, 99, 99, 87, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 76, 99, 99, 99, 99, 99,
+
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 106, 106, 106,
+ 106, 106, 107, 107, 107, 107, 100, 100, 100, 100,
+ 100, 100, 134, 105, 105, 105, 105, 129, 125, 124,
+ 126, 0, 127, 122, 115, 116, 117, 118, 119, 120,
+ 121, 0, 99, 99, 99, 99, 99, 99, 65, 74,
+ 99, 99, 99, 83, 99, 99, 99, 99, 77, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 82,
+ 99, 106, 106, 106, 106, 106, 106, 106, 106, 106,
+
+ 106, 107, 107, 107, 107, 100, 36, 100, 100, 100,
+ 100, 134, 1, 105, 105, 3, 127, 128, 99, 99,
+ 99, 99, 99, 99, 99, 84, 72, 99, 99, 80,
+ 99, 99, 99, 99, 99, 99, 99, 99, 99, 75,
+ 99, 99, 99, 99, 96, 99, 99, 99, 86, 99,
+ 97, 99, 99, 106, 106, 106, 106, 106, 106, 106,
+ 106, 106, 106, 106, 30, 107, 107, 33, 100, 39,
+ 100, 100, 37, 134, 105, 105, 99, 99, 99, 99,
+ 99, 99, 99, 81, 68, 63, 69, 99, 99, 99,
+ 99, 99, 90, 99, 78, 67, 85, 99, 99, 99,
+
+ 99, 99, 99, 99, 106, 106, 106, 106, 106, 106,
+ 106, 106, 17, 106, 106, 107, 107, 100, 100, 38,
+ 134, 105, 105, 99, 99, 99, 99, 99, 12, 99,
+ 95, 99, 99, 88, 99, 99, 99, 99, 7, 64,
+ 99, 71, 99, 106, 106, 106, 106, 106, 27, 19,
+ 106, 106, 21, 107, 107, 100, 100, 134, 134, 105,
+ 4, 99, 11, 99, 99, 99, 99, 99, 91, 99,
+ 66, 94, 99, 79, 73, 106, 26, 106, 106, 106,
+ 106, 106, 107, 31, 100, 100, 133, 2, 99, 5,
+ 99, 99, 99, 98, 89, 6, 106, 23, 106, 106,
+
+ 18, 20, 32, 100, 100, 99, 99, 99, 70, 106,
+ 106, 106, 40, 41, 99, 10, 9, 106, 25, 24,
+ 8, 22, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 2, 3, 4,
+ 1, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 3, 1, 5, 6, 1, 1, 1, 7, 8,
+ 9, 10, 1, 11, 1, 12, 13, 14, 15, 15,
+ 15, 15, 15, 15, 15, 16, 16, 17, 18, 19,
+ 1, 20, 1, 1, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 28, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 28, 43, 28,
+ 44, 45, 46, 1, 47, 1, 48, 49, 50, 51,
+
+ 52, 53, 54, 55, 56, 28, 28, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 28, 71, 1, 72, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[73] =
+ { 0,
+ 1, 1, 1, 2, 3, 1, 4, 1, 1, 1,
+ 1, 1, 1, 5, 5, 5, 1, 1, 1, 1,
+ 5, 5, 5, 5, 5, 5, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 1, 1, 1, 6, 5, 5, 5,
+ 5, 5, 5, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[651] =
+ { 0,
+ 0, 3, 16, 5, 88, 9, 160, 232, 304, 178,
+ 375, 446, 183, 517, 252, 562, 209, 213, 607, 652,
+ 255, 286, 270, 388, 698, 187, 394, 407, 1202, 1203,
+ 180, 1203, 185, 379, 1150, 1203, 186, 219, 187, 0,
+ 1143, 1151, 1146, 1133, 420, 1145, 1203, 200, 1150, 221,
+ 413, 197, 418, 1177, 0, 1157, 1145, 203, 380, 1131,
+ 161, 237, 1131, 1129, 1122, 1139, 1125, 216, 1133, 386,
+ 391, 227, 344, 460, 1133, 1203, 206, 257, 404, 0,
+ 1147, 373, 1120, 1203, 1203, 465, 1130, 1203, 442, 433,
+ 459, 0, 1123, 1131, 1126, 1113, 1203, 1203, 471, 1125,
+
+ 1203, 473, 1203, 1203, 1203, 469, 1203, 1203, 1203, 1203,
+ 478, 1124, 1203, 483, 1203, 1203, 1203, 478, 1203, 1203,
+ 1203, 491, 1123, 1203, 493, 1203, 1203, 1203, 488, 1203,
+ 1203, 1203, 497, 1122, 1203, 502, 1127, 496, 1203, 1203,
+ 505, 1120, 1203, 510, 1125, 1203, 1203, 504, 530, 1118,
+ 1203, 513, 514, 535, 1117, 1203, 537, 521, 540, 1116,
+ 1203, 1203, 0, 1141, 1140, 385, 1127, 1118, 1203, 1203,
+ 1203, 542, 1203, 0, 545, 0, 0, 1110, 465, 1203,
+ 1157, 0, 1112, 1101, 1100, 1101, 1111, 545, 1148, 1147,
+ 766, 1141, 538, 541, 562, 1203, 0, 1105, 1095, 1092,
+
+ 1084, 1100, 1099, 1087, 1079, 1078, 1078, 1082, 1085, 230,
+ 1081, 1074, 1080, 1085, 400, 1087, 1081, 1074, 1079, 332,
+ 1074, 1068, 1066, 1068, 503, 1072, 1064, 525, 484, 1203,
+ 1122, 0, 1078, 427, 1075, 1059, 517, 1203, 1118, 0,
+ 1073, 1062, 1061, 1062, 1072, 579, 583, 1071, 583, 587,
+ 0, 1077, 368, 1077, 1079, 1083, 1066, 587, 0, 1057,
+ 1045, 1056, 1046, 1047, 1203, 1098, 1097, 1096, 587, 589,
+ 1095, 1094, 1093, 1092, 1091, 1090, 1089, 1088, 1087, 1203,
+ 583, 594, 1034, 0, 1032, 1028, 1026, 1025, 1039, 1029,
+ 1034, 1037, 1032, 1027, 0, 1028, 1033, 1028, 1016, 1011,
+
+ 1012, 1019, 1019, 1011, 1014, 1007, 1005, 1009, 1009, 557,
+ 1016, 1007, 1010, 1006, 999, 1012, 1014, 599, 994, 995,
+ 1002, 574, 994, 1005, 995, 996, 1025, 1029, 1027, 1022,
+ 1013, 1010, 992, 983, 982, 988, 990, 1203, 1203, 1203,
+ 1203, 628, 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1203,
+ 1203, 1036, 1011, 1008, 538, 1003, 1014, 981, 0, 0,
+ 973, 971, 978, 0, 971, 968, 973, 972, 0, 981,
+ 965, 980, 979, 974, 969, 960, 958, 970, 965, 970,
+ 962, 950, 963, 956, 964, 955, 959, 958, 945, 0,
+ 945, 978, 975, 599, 970, 981, 957, 952, 947, 948,
+
+ 941, 936, 935, 941, 943, 969, 0, 956, 959, 968,
+ 967, 932, 0, 929, 941, 0, 1203, 1203, 967, 947,
+ 956, 960, 950, 944, 926, 0, 0, 929, 921, 0,
+ 928, 926, 920, 915, 910, 909, 919, 911, 890, 0,
+ 899, 899, 877, 893, 0, 877, 870, 875, 0, 860,
+ 0, 863, 850, 884, 857, 861, 809, 798, 791, 763,
+ 777, 776, 765, 758, 0, 761, 773, 0, 787, 0,
+ 779, 793, 0, 764, 765, 747, 772, 777, 783, 770,
+ 771, 767, 745, 0, 0, 0, 0, 751, 754, 741,
+ 748, 734, 0, 746, 0, 0, 0, 732, 748, 731,
+
+ 741, 741, 735, 734, 752, 757, 763, 750, 751, 747,
+ 732, 718, 0, 734, 715, 730, 712, 755, 754, 0,
+ 729, 722, 645, 657, 656, 670, 655, 666, 0, 638,
+ 0, 639, 625, 0, 635, 623, 633, 627, 0, 0,
+ 632, 0, 630, 643, 642, 656, 641, 652, 0, 0,
+ 624, 618, 0, 624, 621, 648, 647, 623, 591, 615,
+ 0, 637, 0, 625, 634, 625, 612, 600, 0, 599,
+ 0, 0, 585, 0, 0, 619, 0, 608, 617, 608,
+ 593, 577, 587, 0, 607, 594, 1203, 0, 590, 0,
+ 594, 568, 558, 0, 0, 0, 567, 0, 548, 530,
+
+ 0, 0, 0, 533, 477, 439, 433, 388, 0, 361,
+ 276, 232, 0, 0, 219, 0, 0, 189, 0, 0,
+ 0, 0, 1203, 835, 841, 847, 853, 859, 865, 871,
+ 877, 883, 889, 895, 897, 903, 909, 911, 917, 919,
+ 925, 927, 933, 939, 941, 947, 953, 959, 962, 967
+ } ;
+
+static yyconst flex_int16_t yy_def[651] =
+ { 0,
+ 624, 624, 623, 3, 623, 5, 625, 625, 623, 9,
+ 626, 626, 627, 627, 628, 628, 629, 629, 630, 630,
+ 631, 631, 632, 632, 623, 25, 624, 624, 623, 623,
+ 623, 623, 623, 623, 633, 623, 623, 634, 623, 635,
+ 635, 635, 635, 635, 623, 633, 623, 623, 636, 637,
+ 623, 623, 623, 623, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 623, 633, 623, 623, 639, 623, 640,
+ 640, 640, 640, 623, 623, 623, 633, 623, 623, 641,
+ 623, 642, 642, 642, 642, 642, 623, 623, 623, 633,
+
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 633, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 633, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 633, 623, 623, 643, 623, 623, 623,
+ 623, 633, 623, 623, 644, 623, 623, 623, 623, 633,
+ 623, 623, 623, 623, 633, 623, 623, 623, 623, 633,
+ 623, 623, 645, 645, 645, 645, 645, 646, 623, 623,
+ 623, 623, 623, 647, 623, 633, 633, 633, 634, 623,
+ 634, 635, 635, 635, 635, 635, 636, 636, 623, 623,
+ 648, 623, 623, 623, 623, 623, 638, 638, 638, 638,
+
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 639, 623,
+ 639, 640, 640, 640, 640, 640, 641, 623, 641, 642,
+ 642, 642, 642, 642, 643, 643, 623, 644, 644, 623,
+ 645, 645, 645, 645, 645, 645, 646, 646, 647, 633,
+ 635, 635, 635, 635, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 649, 623,
+ 623, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 640, 640, 640,
+ 640, 640, 642, 642, 642, 642, 645, 645, 645, 645,
+ 645, 645, 633, 635, 635, 635, 635, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 649, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 640, 640, 640, 640, 640, 640, 640, 640, 640,
+
+ 640, 642, 642, 642, 642, 645, 645, 645, 645, 645,
+ 645, 633, 635, 635, 635, 635, 623, 623, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 640, 640, 640, 640, 640, 640, 640,
+ 640, 640, 640, 640, 642, 642, 642, 642, 645, 645,
+ 645, 645, 645, 633, 635, 635, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+
+ 638, 638, 638, 638, 640, 640, 640, 640, 640, 640,
+ 640, 640, 640, 640, 640, 642, 642, 645, 645, 645,
+ 650, 635, 635, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 640, 640, 640, 640, 640, 640, 640,
+ 640, 640, 640, 642, 642, 645, 645, 650, 650, 635,
+ 635, 638, 638, 638, 638, 638, 638, 638, 638, 638,
+ 638, 638, 638, 638, 638, 640, 640, 640, 640, 640,
+ 640, 640, 642, 642, 645, 645, 623, 635, 638, 638,
+ 638, 638, 638, 638, 638, 638, 640, 640, 640, 640,
+
+ 640, 640, 642, 645, 645, 638, 638, 638, 638, 640,
+ 640, 640, 645, 645, 638, 638, 638, 640, 640, 640,
+ 638, 640, 0, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623
+ } ;
+
+static yyconst flex_int16_t yy_nxt[1276] =
+ { 0,
+ 623, 31, 31, 32, 31, 34, 32, 45, 35, 623,
+ 46, 74, 33, 623, 75, 33, 36, 37, 37, 32,
+ 38, 36, 36, 36, 36, 36, 36, 36, 39, 36,
+ 36, 36, 36, 36, 36, 36, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 36,
+ 36, 36, 40, 40, 40, 41, 40, 40, 40, 40,
+ 40, 40, 40, 40, 42, 40, 40, 40, 40, 40,
+ 43, 44, 40, 40, 40, 40, 36, 36, 47, 48,
+ 48, 32, 49, 47, 50, 47, 47, 47, 47, 51,
+
+ 52, 53, 53, 53, 54, 47, 47, 47, 55, 55,
+ 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,
+ 55, 55, 55, 55, 55, 55, 56, 55, 55, 55,
+ 55, 47, 47, 47, 57, 58, 55, 59, 60, 61,
+ 62, 55, 55, 63, 64, 65, 66, 67, 68, 55,
+ 69, 70, 71, 72, 73, 55, 55, 55, 47, 47,
+ 76, 77, 77, 32, 78, 76, 76, 76, 76, 76,
+ 76, 76, 79, 76, 76, 76, 76, 76, 76, 76,
+ 99, 172, 172, 100, 114, 114, 32, 172, 172, 34,
+ 115, 116, 35, 117, 173, 118, 173, 174, 81, 174,
+
+ 119, 172, 172, 76, 76, 76, 173, 172, 172, 174,
+ 136, 136, 32, 137, 136, 141, 32, 137, 142, 206,
+ 82, 138, 622, 180, 83, 138, 120, 190, 121, 207,
+ 84, 85, 76, 77, 86, 32, 78, 87, 76, 76,
+ 76, 76, 76, 76, 79, 76, 76, 76, 76, 76,
+ 76, 76, 621, 125, 125, 32, 152, 152, 32, 126,
+ 127, 230, 128, 181, 129, 191, 200, 153, 201, 130,
+ 81, 157, 157, 32, 620, 76, 76, 76, 215, 139,
+ 140, 216, 158, 139, 140, 225, 294, 152, 154, 32,
+ 226, 155, 82, 208, 295, 131, 83, 132, 153, 209,
+
+ 619, 231, 84, 85, 88, 89, 89, 32, 90, 88,
+ 88, 88, 88, 88, 88, 88, 91, 88, 88, 88,
+ 88, 88, 88, 88, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+ 92, 92, 92, 92, 92, 92, 92, 88, 88, 88,
+ 92, 92, 92, 93, 92, 92, 92, 92, 92, 92,
+ 92, 92, 94, 92, 92, 92, 92, 92, 95, 96,
+ 92, 92, 92, 92, 97, 98, 102, 102, 32, 306,
+ 172, 175, 103, 104, 176, 105, 618, 106, 328, 157,
+ 159, 32, 107, 160, 307, 31, 31, 32, 168, 227,
+
+ 158, 169, 170, 228, 171, 329, 33, 254, 31, 34,
+ 32, 168, 35, 173, 169, 170, 174, 171, 108, 33,
+ 109, 172, 175, 255, 192, 176, 193, 193, 193, 194,
+ 617, 195, 195, 195, 202, 234, 203, 238, 235, 204,
+ 218, 219, 221, 172, 172, 222, 110, 102, 111, 32,
+ 220, 112, 223, 103, 104, 300, 105, 616, 106, 301,
+ 224, 172, 175, 107, 615, 176, 172, 175, 173, 180,
+ 176, 174, 172, 175, 172, 172, 176, 239, 173, 172,
+ 175, 174, 319, 176, 172, 172, 320, 173, 230, 108,
+ 174, 109, 172, 175, 172, 172, 176, 173, 172, 175,
+
+ 174, 614, 176, 172, 172, 173, 172, 175, 174, 181,
+ 176, 247, 247, 173, 172, 172, 174, 110, 114, 122,
+ 32, 238, 123, 173, 115, 116, 174, 117, 231, 118,
+ 173, 247, 250, 174, 119, 176, 172, 175, 172, 172,
+ 176, 172, 175, 172, 172, 176, 172, 175, 187, 187,
+ 176, 193, 193, 193, 281, 281, 281, 613, 312, 421,
+ 120, 239, 121, 125, 133, 32, 313, 134, 612, 126,
+ 127, 611, 128, 194, 129, 195, 195, 195, 422, 130,
+ 316, 317, 245, 245, 247, 247, 248, 248, 247, 250,
+ 257, 257, 176, 341, 587, 343, 281, 281, 281, 610,
+
+ 342, 342, 342, 342, 609, 131, 608, 132, 144, 144,
+ 32, 145, 383, 384, 146, 147, 353, 607, 354, 148,
+ 456, 392, 606, 393, 605, 146, 147, 355, 356, 400,
+ 401, 357, 394, 395, 417, 559, 396, 604, 603, 457,
+ 602, 342, 342, 601, 600, 599, 598, 597, 596, 595,
+ 146, 594, 147, 144, 149, 32, 145, 150, 593, 146,
+ 147, 592, 591, 590, 148, 589, 588, 559, 586, 585,
+ 146, 147, 584, 583, 582, 581, 580, 579, 578, 577,
+ 576, 575, 574, 573, 572, 571, 570, 569, 568, 567,
+ 566, 565, 564, 563, 562, 146, 561, 147, 30, 31,
+
+ 31, 32, 30, 30, 30, 161, 162, 30, 30, 30,
+ 33, 30, 30, 30, 30, 30, 30, 30, 163, 163,
+ 163, 164, 163, 163, 163, 163, 163, 163, 163, 163,
+ 163, 163, 163, 163, 165, 166, 163, 163, 163, 167,
+ 163, 30, 30, 30, 163, 163, 163, 163, 163, 163,
+ 163, 163, 163, 163, 163, 163, 163, 163, 163, 163,
+ 163, 163, 163, 163, 163, 163, 163, 163, 30, 30,
+ 267, 560, 268, 559, 557, 556, 555, 554, 553, 269,
+ 270, 552, 551, 550, 549, 548, 547, 546, 545, 544,
+ 543, 542, 541, 540, 539, 538, 537, 536, 535, 534,
+
+ 533, 532, 531, 530, 529, 528, 527, 526, 525, 524,
+ 271, 523, 522, 272, 273, 521, 520, 519, 274, 518,
+ 517, 516, 515, 514, 275, 513, 512, 511, 276, 510,
+ 277, 509, 278, 508, 279, 30, 30, 30, 30, 30,
+ 30, 80, 80, 80, 80, 80, 80, 101, 101, 101,
+ 101, 101, 101, 113, 113, 113, 113, 113, 113, 124,
+ 124, 124, 124, 124, 124, 135, 135, 135, 135, 135,
+ 135, 143, 143, 143, 143, 143, 143, 151, 151, 151,
+ 151, 151, 151, 156, 156, 156, 156, 156, 156, 177,
+ 507, 177, 177, 177, 177, 179, 506, 179, 179, 179,
+
+ 179, 182, 182, 187, 505, 504, 187, 187, 187, 189,
+ 503, 189, 189, 189, 189, 197, 197, 229, 502, 229,
+ 229, 229, 229, 232, 232, 237, 501, 237, 237, 237,
+ 237, 240, 240, 245, 500, 499, 245, 245, 245, 248,
+ 498, 497, 248, 248, 248, 251, 251, 257, 496, 495,
+ 257, 257, 257, 259, 494, 259, 259, 259, 259, 266,
+ 493, 266, 266, 266, 266, 352, 352, 558, 492, 558,
+ 558, 558, 558, 491, 490, 489, 488, 487, 486, 485,
+ 484, 483, 482, 481, 480, 479, 478, 477, 476, 475,
+ 474, 473, 472, 471, 470, 469, 468, 467, 466, 465,
+
+ 464, 463, 462, 461, 460, 459, 458, 455, 454, 453,
+ 452, 451, 450, 449, 448, 447, 446, 445, 444, 443,
+ 442, 441, 440, 439, 438, 437, 436, 435, 434, 433,
+ 432, 431, 430, 429, 428, 427, 426, 425, 424, 423,
+ 420, 419, 418, 416, 415, 414, 413, 412, 411, 410,
+ 409, 408, 407, 406, 405, 404, 403, 402, 399, 398,
+ 397, 391, 390, 389, 388, 387, 386, 385, 382, 381,
+ 380, 379, 378, 377, 376, 375, 374, 373, 372, 371,
+ 370, 369, 368, 367, 366, 365, 364, 363, 362, 361,
+ 360, 359, 358, 338, 351, 350, 349, 348, 347, 346,
+
+ 345, 344, 340, 339, 338, 337, 336, 335, 334, 333,
+ 258, 332, 331, 330, 327, 249, 246, 326, 325, 324,
+ 323, 237, 322, 321, 318, 229, 315, 314, 311, 310,
+ 309, 308, 305, 304, 303, 302, 299, 298, 297, 296,
+ 293, 292, 291, 290, 289, 288, 287, 286, 285, 284,
+ 283, 282, 280, 265, 265, 188, 264, 263, 262, 261,
+ 179, 260, 258, 256, 253, 252, 178, 178, 178, 249,
+ 178, 246, 178, 178, 178, 178, 244, 243, 242, 241,
+ 178, 236, 233, 178, 217, 214, 213, 212, 211, 210,
+ 205, 199, 198, 196, 188, 178, 186, 185, 184, 183,
+
+ 178, 623, 29, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623
+ } ;
+
+static yyconst flex_int16_t yy_chk[1276] =
+ { 0,
+ 0, 1, 1, 1, 2, 2, 2, 4, 2, 0,
+ 4, 6, 1, 0, 6, 2, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 10, 31, 31, 10, 13, 13, 13, 37, 37, 26,
+ 13, 13, 26, 13, 33, 13, 39, 33, 7, 39,
+
+ 13, 48, 48, 7, 7, 7, 52, 77, 77, 52,
+ 17, 17, 17, 17, 18, 18, 18, 18, 18, 61,
+ 7, 17, 618, 38, 7, 18, 13, 50, 13, 61,
+ 7, 7, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 615, 15, 15, 15, 21, 21, 21, 15,
+ 15, 78, 15, 38, 15, 50, 58, 21, 58, 15,
+ 8, 23, 23, 23, 612, 8, 8, 8, 68, 17,
+ 17, 68, 23, 18, 18, 72, 210, 22, 22, 22,
+ 72, 22, 8, 62, 210, 15, 8, 15, 22, 62,
+
+ 611, 78, 8, 8, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 11, 11, 11, 220,
+ 34, 34, 11, 11, 34, 11, 610, 11, 253, 24,
+ 24, 24, 11, 24, 220, 27, 27, 27, 27, 73,
+
+ 24, 27, 27, 73, 27, 253, 27, 166, 28, 28,
+ 28, 28, 28, 79, 28, 28, 79, 28, 11, 28,
+ 11, 45, 45, 166, 51, 45, 51, 51, 51, 53,
+ 608, 53, 53, 53, 59, 82, 59, 90, 82, 59,
+ 70, 70, 71, 89, 89, 71, 11, 12, 12, 12,
+ 70, 12, 71, 12, 12, 215, 12, 607, 12, 215,
+ 71, 74, 74, 12, 606, 74, 86, 86, 91, 179,
+ 86, 91, 99, 99, 102, 102, 99, 90, 106, 111,
+ 111, 106, 234, 111, 114, 114, 234, 118, 229, 12,
+ 118, 12, 122, 122, 125, 125, 122, 129, 133, 133,
+
+ 129, 605, 133, 136, 136, 138, 141, 141, 138, 179,
+ 141, 144, 144, 148, 152, 152, 148, 12, 14, 14,
+ 14, 237, 14, 153, 14, 14, 153, 14, 229, 14,
+ 158, 149, 149, 158, 14, 149, 154, 154, 157, 157,
+ 154, 159, 159, 172, 172, 159, 175, 175, 188, 188,
+ 175, 193, 193, 193, 194, 194, 194, 604, 225, 355,
+ 14, 237, 14, 16, 16, 16, 225, 16, 600, 16,
+ 16, 599, 16, 195, 16, 195, 195, 195, 355, 16,
+ 228, 228, 246, 246, 247, 247, 249, 249, 250, 250,
+ 258, 258, 250, 269, 559, 270, 281, 281, 281, 597,
+
+ 269, 269, 270, 270, 593, 16, 592, 16, 19, 19,
+ 19, 19, 310, 310, 19, 19, 282, 591, 282, 19,
+ 394, 318, 589, 318, 586, 19, 19, 282, 282, 322,
+ 322, 282, 318, 318, 342, 559, 318, 585, 583, 394,
+ 582, 342, 342, 581, 580, 579, 578, 576, 573, 570,
+ 19, 568, 19, 20, 20, 20, 20, 20, 567, 20,
+ 20, 566, 565, 564, 20, 562, 560, 558, 557, 556,
+ 20, 20, 555, 554, 552, 551, 548, 547, 546, 545,
+ 544, 543, 541, 538, 537, 536, 535, 533, 532, 530,
+ 528, 527, 526, 525, 524, 20, 523, 20, 25, 25,
+
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 191, 522, 191, 521, 519, 518, 517, 516, 515, 191,
+ 191, 514, 512, 511, 510, 509, 508, 507, 506, 505,
+ 504, 503, 502, 501, 500, 499, 498, 494, 492, 491,
+
+ 490, 489, 488, 483, 482, 481, 480, 479, 478, 477,
+ 191, 476, 475, 191, 191, 474, 472, 471, 191, 469,
+ 467, 466, 464, 463, 191, 462, 461, 460, 191, 459,
+ 191, 458, 191, 457, 191, 624, 624, 624, 624, 624,
+ 624, 625, 625, 625, 625, 625, 625, 626, 626, 626,
+ 626, 626, 626, 627, 627, 627, 627, 627, 627, 628,
+ 628, 628, 628, 628, 628, 629, 629, 629, 629, 629,
+ 629, 630, 630, 630, 630, 630, 630, 631, 631, 631,
+ 631, 631, 631, 632, 632, 632, 632, 632, 632, 633,
+ 456, 633, 633, 633, 633, 634, 455, 634, 634, 634,
+
+ 634, 635, 635, 636, 454, 453, 636, 636, 636, 637,
+ 452, 637, 637, 637, 637, 638, 638, 639, 450, 639,
+ 639, 639, 639, 640, 640, 641, 448, 641, 641, 641,
+ 641, 642, 642, 643, 447, 446, 643, 643, 643, 644,
+ 444, 443, 644, 644, 644, 645, 645, 646, 442, 441,
+ 646, 646, 646, 647, 439, 647, 647, 647, 647, 648,
+ 438, 648, 648, 648, 648, 649, 649, 650, 437, 650,
+ 650, 650, 650, 436, 435, 434, 433, 432, 431, 429,
+ 428, 425, 424, 423, 422, 421, 420, 419, 415, 414,
+ 412, 411, 410, 409, 408, 406, 405, 404, 403, 402,
+
+ 401, 400, 399, 398, 397, 396, 395, 393, 392, 391,
+ 389, 388, 387, 386, 385, 384, 383, 382, 381, 380,
+ 379, 378, 377, 376, 375, 374, 373, 372, 371, 370,
+ 368, 367, 366, 365, 363, 362, 361, 358, 357, 356,
+ 354, 353, 352, 337, 336, 335, 334, 333, 332, 331,
+ 330, 329, 328, 327, 326, 325, 324, 323, 321, 320,
+ 319, 317, 316, 315, 314, 313, 312, 311, 309, 308,
+ 307, 306, 305, 304, 303, 302, 301, 300, 299, 298,
+ 297, 296, 294, 293, 292, 291, 290, 289, 288, 287,
+ 286, 285, 283, 279, 278, 277, 276, 275, 274, 273,
+
+ 272, 271, 268, 267, 266, 264, 263, 262, 261, 260,
+ 257, 256, 255, 254, 252, 248, 245, 244, 243, 242,
+ 241, 239, 236, 235, 233, 231, 227, 226, 224, 223,
+ 222, 221, 219, 218, 217, 216, 214, 213, 212, 211,
+ 209, 208, 207, 206, 205, 204, 203, 202, 201, 200,
+ 199, 198, 192, 190, 189, 187, 186, 185, 184, 183,
+ 181, 178, 168, 167, 165, 164, 160, 155, 150, 145,
+ 142, 137, 134, 123, 112, 100, 96, 95, 94, 93,
+ 87, 83, 81, 75, 69, 67, 66, 65, 64, 63,
+ 60, 57, 56, 54, 49, 46, 44, 43, 42, 41,
+
+ 35, 29, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
+ 623, 623, 623, 623, 623
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "tqmoc.l"
+/****************************************************************************
+**
+** Lexical analyzer for meta object compiler
+**
+** Created : 930417
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the TQ Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+*****************************************************************************/
+#line 42 "tqmoc.l"
+#ifdef TQMOC_YACC_CODE
+
+#ifdef TQMOC_MWERKS_PLUGIN
+#ifdef TQ_OS_MAC9
+# define isascii(c) ((int)( (unsigned int) (c) <= (unsigned char)0x7F ))
+#endif
+const char *buf_buffer = NULL;
+long buf_size_total = 0, buf_index = 0;
+#define YY_INPUT(buf, result, max_size) \
+ { \
+ if(buf_index < buf_size_total ) { \
+ while(!isascii(buf_buffer[buf_index])) buf_index++; \
+ int ms = ((max_size < buf_size_total) ? max_size : buf_size_total); \
+ for(result = 0; result < ms; result++) { \
+ char c = buf_buffer[buf_index + result]; \
+ if(!isascii(c)) { \
+ buf_index++; \
+ break; \
+ } \
+ buf[result] = c == '\r' ? '\n' : c; \
+ } \
+ buf_index += result; \
+ } else result = YY_NULL; \
+ }
+#endif
+
+#include "tqstring.h"
+
+
+#define input yyinput // yyinput in C++
+
+#define X if(lexDebug){fprintf(stderr,"LEX (%i) : %s\n",lineNo,yytext);};
+#define Y if(lexDebug){fprintf(stderr,"LEX (%i) : %s\n",lineNo,yytext);};
+/*
+#define Y if(lexDebug){fprintf(stderr,"LEX (%i) : %s updates level to %i\n"\
+ ,lineNo,yytext,templLevel);};
+*/
+#define Z if(lexDebug){fprintf(stderr,"LEX (%i) : skipped the string %s\"\n"\
+ ,lineNo,yytext);};
+#define BEGIN_INSIDE
+
+
+#define linput() \
+ ( (c = input()) == '\n' ? (lineNo++, c) : (c == EOF) ? 0 : c )
+
+#include <string.h>
+#include <stdlib.h>
+
+int classPLevel = 1; /* Depth of nested curly braces in IN_CLASS */
+int namespacePLevel = 1; /* Depth of nested curly braces in IN_NAMESPACE */
+int expLevel = 1; /* Depth of nested parentheses in IN_EXPR */
+int enumLevel = 1; /* Depth of nested parentheses in IN_ENUM */
+int fctLevel = 1; /* Depth of nested parentheses in IN_FCT */
+int templLevel = 1; /* Depth of levels in IN_TEMPL_ARGS */
+
+int lastState = 0; /* Remembers the state when a
+ TQMOC_SKIP_BEGIN is encountered */
+int skipLevel = 0; /* Depth of TQMOC_SKIP_BEGINs */
+
+class TQString;
+
+extern void addExpressionChar( const char );
+extern void addExpressionString( const char * );
+extern void tqmoc_warn( const char *msg );
+
+#line 1057 "tqmoc_lex.cpp"
+
+#define INITIAL 0
+#define OUTSIDE 1
+#define TQT_DEF 2
+#define IN_CLASS 3
+#define IN_NAMESPACE 4
+#define IN_ENUM 5
+#define IN_EXPR 6
+#define IN_DEF_ARG 7
+#define IN_FCT 8
+#define IN_TEMPL_ARGS 9
+#define GIMME_SEMICOLON 10
+#define SKIP 11
+#define IN_PROPERTY 12
+#define IN_CLASSINFO 13
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr );
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( yyleng > 0 ) \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+ (yytext[yyleng - 1] == '\n'); \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 113 "tqmoc.l"
+
+
+#line 1263 "tqmoc_lex.cpp"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 624 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 1203 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 115 "tqmoc.l"
+{ X;
+ BEGIN TQT_DEF;
+ return CLASS; }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 118 "tqmoc.l"
+{ X;
+ BEGIN TQT_DEF;
+ return NAMESPACE; }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 121 "tqmoc.l"
+{ X;
+ BEGIN TQT_DEF;
+ return USING; }
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 124 "tqmoc.l"
+{ X;
+ BEGIN TQT_DEF;
+ return TEMPLATE; }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 127 "tqmoc.l"
+{ X; return TQ_OBJECT; }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 128 "tqmoc.l"
+{ X; return SIGNALS; }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 129 "tqmoc.l"
+{ X; return SLOTS; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 130 "tqmoc.l"
+{ X; return TQ_CLASSINFO; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 131 "tqmoc.l"
+{ X; return Q_PROPERTY; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 132 "tqmoc.l"
+{ X; return TQ_OVERRIDE; }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 133 "tqmoc.l"
+{ X; return TQ_ENUMS; }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 134 "tqmoc.l"
+{ X; return TQ_SETS; }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 136 "tqmoc.l"
+{ fctLevel++;Y; }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 137 "tqmoc.l"
+{ fctLevel--;Y;if (fctLevel==0){X;return '}';}}
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 138 "tqmoc.l"
+{ classPLevel++;Y; }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 139 "tqmoc.l"
+{ classPLevel--;Y;if (classPLevel == 0)
+ {X;return '}';} }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 141 "tqmoc.l"
+{ X;if( classPLevel == 1 ) return PUBLIC; }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 142 "tqmoc.l"
+{ X;if( classPLevel == 1 ) return PROTECTED; }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 143 "tqmoc.l"
+{ X;if( classPLevel == 1 ) return PRIVATE; }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 144 "tqmoc.l"
+{ X;if( classPLevel == 1 ) return SIGNALS; }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 145 "tqmoc.l"
+{ X;if( classPLevel == 1 ) return SLOTS; }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 146 "tqmoc.l"
+{ X;if( classPLevel == 1 ) return TQ_CLASSINFO; }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 147 "tqmoc.l"
+{ X;
+ if ( classPLevel == 1 )
+ return TQ_OBJECT;
+ else if ( classPLevel > 1 )
+ tqmoc_warn( "Cannot use TQ_OBJECT in nested class." );
+ }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 153 "tqmoc.l"
+{ X;if( classPLevel == 1 ) return Q_PROPERTY; }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 154 "tqmoc.l"
+{ X;if( classPLevel == 1 ) return TQ_OVERRIDE; }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 155 "tqmoc.l"
+{ X;if( classPLevel == 1 ) return TQ_ENUMS; }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 156 "tqmoc.l"
+{ X;if( classPLevel == 1 ) return TQ_SETS; }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 158 "tqmoc.l"
+{ namespacePLevel++;Y; }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 159 "tqmoc.l"
+{ namespacePLevel--;Y;if (namespacePLevel == 0)
+ {X;return '}';}}
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 161 "tqmoc.l"
+{ X;
+ BEGIN TQT_DEF;
+ return CLASS; }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 164 "tqmoc.l"
+{ X;
+ BEGIN TQT_DEF;
+ return TEMPLATE; }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 167 "tqmoc.l"
+{ X;
+ BEGIN TQT_DEF;
+ return NAMESPACE; }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 170 "tqmoc.l"
+{ X;
+ BEGIN TQT_DEF;
+ return USING; }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 174 "tqmoc.l"
+{ X; return '('; }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 175 "tqmoc.l"
+{ X; return ')'; }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 176 "tqmoc.l"
+{ X; return READ; }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 177 "tqmoc.l"
+{ X; return WRITE; }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 178 "tqmoc.l"
+{ X; return STORED; }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 179 "tqmoc.l"
+{ X; return RESET; }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 180 "tqmoc.l"
+{ X; return DESIGNABLE; }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 181 "tqmoc.l"
+{ X; return SCRIPTABLE; }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 184 "tqmoc.l"
+{ expLevel++;X; }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 185 "tqmoc.l"
+{ expLevel--;Y;if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ')';} }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 187 "tqmoc.l"
+{ expLevel++;X; }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 188 "tqmoc.l"
+{ expLevel--;X;if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ']';} }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 190 "tqmoc.l"
+{ if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ',' ;} }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 192 "tqmoc.l"
+{ if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ';' ;} }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 194 "tqmoc.l"
+{ expLevel++;X; }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 195 "tqmoc.l"
+{ expLevel--;Y;if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ')';} }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 197 "tqmoc.l"
+{ expLevel++;X; }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 198 "tqmoc.l"
+{ expLevel--;X;if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ']';} }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 200 "tqmoc.l"
+{ if (expLevel <= 1)
+ { X; BEGIN TQT_DEF; return ',' ;} }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 202 "tqmoc.l"
+{ if (expLevel == 0)
+ { X; BEGIN TQT_DEF; return ';' ;} }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 204 "tqmoc.l"
+{ enumLevel++;X; }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 205 "tqmoc.l"
+{ enumLevel--;X; }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 206 "tqmoc.l"
+{ enumLevel++;X; }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 207 "tqmoc.l"
+{ enumLevel--;X }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 208 "tqmoc.l"
+{ if (enumLevel == 0)
+ { X; BEGIN TQT_DEF; return ',' ;} }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 210 "tqmoc.l"
+{ if (enumLevel == 0)
+ { X; BEGIN TQT_DEF; return ';' ;} }
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 212 "tqmoc.l"
+{ if (enumLevel == 0)
+ { X; BEGIN TQT_DEF; return '}' ;} }
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 214 "tqmoc.l"
+{ templLevel++;
+ Y;
+ addExpressionChar( yytext[0] );
+ }
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 218 "tqmoc.l"
+{ templLevel--;
+ Y;
+ if ( templLevel == 0 ) {
+ X;
+ BEGIN TQT_DEF;
+ return yytext[0];
+ } else {
+ addExpressionChar( yytext[0] );
+ }
+ }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 228 "tqmoc.l"
+{ X;return FRIEND; }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 229 "tqmoc.l"
+{ X;return TYPEDEF; }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 230 "tqmoc.l"
+{ X;return AUTO; }
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 231 "tqmoc.l"
+{ X;return REGISTER; }
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 232 "tqmoc.l"
+{ X;return STATIC; }
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 233 "tqmoc.l"
+{ X;return EXTERN; }
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 234 "tqmoc.l"
+{ X;return INLINE; }
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 235 "tqmoc.l"
+{ X;return INLINE; }
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 236 "tqmoc.l"
+{ X;return VIRTUAL; }
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 237 "tqmoc.l"
+{ X;return CONST; }
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 238 "tqmoc.l"
+{ X;return VOLATILE; }
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 239 "tqmoc.l"
+{ X;return CHAR; }
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 240 "tqmoc.l"
+{ X;return SHORT; }
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 241 "tqmoc.l"
+{ X;return INT; }
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 242 "tqmoc.l"
+{ X;return LONG; }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 243 "tqmoc.l"
+{ X;return SIGNED; }
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 244 "tqmoc.l"
+{ X;return UNSIGNED; }
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 245 "tqmoc.l"
+{ X;return FLOAT; }
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 246 "tqmoc.l"
+{ X;return DOUBLE; }
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 247 "tqmoc.l"
+{ X;return VOID; }
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 248 "tqmoc.l"
+{ X;return ENUM; }
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 249 "tqmoc.l"
+{ X;return CLASS; }
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 250 "tqmoc.l"
+{ X;return STRUCT; }
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 251 "tqmoc.l"
+{ X;return UNION; }
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 252 "tqmoc.l"
+{ X;return ASM; }
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 253 "tqmoc.l"
+{ X;return PRIVATE; }
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 254 "tqmoc.l"
+{ X;return PROTECTED; }
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 255 "tqmoc.l"
+{ X;return PUBLIC; }
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 256 "tqmoc.l"
+{ X;return OPERATOR; }
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 257 "tqmoc.l"
+{ X;return DBL_COLON; }
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 258 "tqmoc.l"
+{ X;return TRIPLE_DOT; }
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 259 "tqmoc.l"
+{ X;return TEMPLATE; }
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 260 "tqmoc.l"
+{ X;return MUTABLE; }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 261 "tqmoc.l"
+{ X;return THROW; }
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 262 "tqmoc.l"
+{ X;return USING; }
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 263 "tqmoc.l"
+{ X;return NAMESPACE; }
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 265 "tqmoc.l"
+{
+ X;
+ yylval.string = qstrdup(yytext);
+ return IDENTIFIER;
+ }
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 271 "tqmoc.l"
+{
+ X;
+ yylval.string = qstrdup(yytext);
+ return IDENTIFIER;
+ }
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 277 "tqmoc.l"
+{ X; return '('; }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 278 "tqmoc.l"
+{ X; return ')'; }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 279 "tqmoc.l"
+{ X; return ','; }
+ YY_BREAK
+case 104:
+/* rule 104 can match eol */
+YY_RULE_SETUP
+#line 281 "tqmoc.l"
+{
+ X;
+ yylval.string = qstrdup( yytext + 1 );
+ input(); /* discard the '"' */
+ return STRING;
+ }
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 288 "tqmoc.l"
+;
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 289 "tqmoc.l"
+;
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 290 "tqmoc.l"
+;
+ YY_BREAK
+case 108:
+/* rule 108 can match eol */
+YY_RULE_SETUP
+#line 292 "tqmoc.l"
+{ /* discard strings */
+ Z;
+ }
+ YY_BREAK
+case 109:
+/* rule 109 can match eol */
+YY_RULE_SETUP
+#line 296 "tqmoc.l"
+{ /* discard strings */
+ Z;
+ }
+ YY_BREAK
+case 110:
+/* rule 110 can match eol */
+YY_RULE_SETUP
+#line 300 "tqmoc.l"
+{ /* discard strings */
+ Z;
+ }
+ YY_BREAK
+case 111:
+/* rule 111 can match eol */
+YY_RULE_SETUP
+#line 304 "tqmoc.l"
+{ /* discard strings */
+ Z;
+ addExpressionString( yytext );
+ input(); /* discard the '"' */
+ }
+ YY_BREAK
+case 112:
+/* rule 112 can match eol */
+YY_RULE_SETUP
+#line 311 "tqmoc.l"
+{
+ X;
+ addExpressionString( yytext );
+ input(); /* discard the '"' */
+ return STRING;
+ }
+ YY_BREAK
+case 113:
+/* rule 113 can match eol */
+YY_RULE_SETUP
+#line 318 "tqmoc.l"
+{
+ X;
+ yylval.string = qstrdup( yytext + 1 );
+ input(); /* discard the '"' */
+ return STRING;
+ }
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 325 "tqmoc.l"
+{ X;
+ yylval.char_val = yytext[1];
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 330 "tqmoc.l"
+{ X;
+ yylval.char_val = '\a';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 335 "tqmoc.l"
+{ X;
+ yylval.char_val = '\b';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 340 "tqmoc.l"
+{ X;
+ yylval.char_val = '\f';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 345 "tqmoc.l"
+{ X;
+ yylval.char_val = '\n';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 350 "tqmoc.l"
+{ X;
+ yylval.char_val = '\r';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 355 "tqmoc.l"
+{ X;
+ yylval.char_val = '\t';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 360 "tqmoc.l"
+{ X;
+ yylval.char_val = '\v';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 365 "tqmoc.l"
+{ X;
+ yylval.char_val = '\\';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 370 "tqmoc.l"
+{ X;
+ yylval.char_val = '\?';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 375 "tqmoc.l"
+{ X;
+ yylval.char_val = '\'';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 380 "tqmoc.l"
+{ X;
+ yylval.char_val = '\"'; /* " */
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 385 "tqmoc.l"
+{ X;
+ yylval.char_val = '\0';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 390 "tqmoc.l"
+{ X;
+ yylval.char_val =
+ (char)strtol( &yytext[1], 0, 8 );
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 396 "tqmoc.l"
+{ X;
+ yylval.char_val =
+ (char)strtol( &yytext[2], 0, 16 );
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 402 "tqmoc.l"
+{ X;
+ yylval.char_val = ' ';
+ return CHAR_VAL;
+ }
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 407 "tqmoc.l"
+{ X;
+ yylval.int_val = atoi(yytext);
+ return INT_VAL;
+ }
+ YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 412 "tqmoc.l"
+{ X;
+ yylval.double_val = atof(yytext);
+ return DOUBLE_VAL;
+ }
+ YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 417 "tqmoc.l"
+{ X;
+ yylval.double_val = atof(yytext);
+ return DOUBLE_VAL;
+ }
+ YY_BREAK
+case 133:
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 423 "tqmoc.l"
+{ /* skip multi-line macro-definitions */
+ int c, c1;
+ input(); /* Discard the '\n'. */
+ do {
+ c1=' ';
+ while((c = linput()) != '\n' && c != 0) c1=c;
+ if (c == 0) break;
+ } while(c1=='\\');
+ unput(c); /* put back the '\n' or the EOF */
+ }
+ YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 434 "tqmoc.l"
+{ /* preprocessor commands are skipped */}
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 435 "tqmoc.l"
+{ /* C++ comment */
+ TQCString s = yytext;
+ if ( s.tqcontains( "TQMOC_SKIP_BEGIN" ) ) {
+ skipLevel++;
+ if ( skipLevel == 1 ) {
+ lastState = YYSTATE;
+ BEGIN SKIP;
+ }
+ } else
+ if ( s.tqcontains( "TQMOC_SKIP_END" ) ) {
+ if ( skipLevel == 0 ) {
+ tqmoc_warn(" TQMOC_SKIP_END without TQMOC_SKIP_BEGIN");
+ } else {
+ skipLevel--;
+ if ( skipLevel == 0 ) {
+ BEGIN lastState;
+ }
+ }
+ }
+ }
+ YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 455 "tqmoc.l"
+{ /* C comment */
+ int c = ' ';
+ do {
+ if ( c!= '*' ) {
+ while((c = linput()) != '*' && c != 0)
+ ;
+ }
+ if (c == 0) break;
+ } while(((c = linput())) != '/' && c != 0);
+ if (c == 0)
+ unput(c);
+ }
+ YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 468 "tqmoc.l"
+{ addExpressionChar( yytext[0] ); }
+ YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 470 "tqmoc.l"
+{
+ /* spaces are important in template args,
+ e.g. Foo<const int> */
+ addExpressionChar( yytext[0] ); }
+ YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 474 "tqmoc.l"
+;
+ YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 475 "tqmoc.l"
+;
+ YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 476 "tqmoc.l"
+;
+ YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 477 "tqmoc.l"
+;
+ YY_BREAK
+case 143:
+YY_RULE_SETUP
+#line 478 "tqmoc.l"
+{ addExpressionChar( yytext[0] ); }
+ YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 479 "tqmoc.l"
+;
+ YY_BREAK
+case 145:
+YY_RULE_SETUP
+#line 480 "tqmoc.l"
+{ addExpressionChar( yytext[0] ); }
+ YY_BREAK
+case 146:
+YY_RULE_SETUP
+#line 481 "tqmoc.l"
+;
+ YY_BREAK
+case 147:
+YY_RULE_SETUP
+#line 482 "tqmoc.l"
+;
+ YY_BREAK
+case 148:
+YY_RULE_SETUP
+#line 483 "tqmoc.l"
+{
+ X;
+ return yytext[0];
+ }
+ YY_BREAK
+case 149:
+YY_RULE_SETUP
+#line 487 "tqmoc.l"
+{
+ X;
+ return ';';
+ }
+ YY_BREAK
+case 150:
+/* rule 150 can match eol */
+YY_RULE_SETUP
+#line 491 "tqmoc.l"
+{
+ lineNo++;
+ }
+ YY_BREAK
+case 151:
+YY_RULE_SETUP
+#line 496 "tqmoc.l"
+ECHO;
+ YY_BREAK
+#line 2301 "tqmoc_lex.cpp"
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(OUTSIDE):
+case YY_STATE_EOF(TQT_DEF):
+case YY_STATE_EOF(IN_CLASS):
+case YY_STATE_EOF(IN_NAMESPACE):
+case YY_STATE_EOF(IN_ENUM):
+case YY_STATE_EOF(IN_EXPR):
+case YY_STATE_EOF(IN_DEF_ARG):
+case YY_STATE_EOF(IN_FCT):
+case YY_STATE_EOF(IN_TEMPL_ARGS):
+case YY_STATE_EOF(GIMME_SEMICOLON):
+case YY_STATE_EOF(SKIP):
+case YY_STATE_EOF(IN_PROPERTY):
+case YY_STATE_EOF(IN_CLASSINFO):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 624 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+ register char *yy_cp = (yy_c_buf_p);
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 624 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 623);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp )
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf );
+
+ yyfree((void *) b );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 496 "tqmoc.l"
+
+
+
+#endif // TQMOC_YACC_CODE
+
diff --git a/tqtinterface/qt4/src/tqmoc/tqmoc_yacc.cpp b/tqtinterface/qt4/src/tqmoc/tqmoc_yacc.cpp
new file mode 100644
index 0000000..3d53e57
--- /dev/null
+++ b/tqtinterface/qt4/src/tqmoc/tqmoc_yacc.cpp
@@ -0,0 +1,6463 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.4.1"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 0
+
+
+
+/* Copy the first part of user declarations. */
+
+/* Line 189 of yacc.c */
+#line 57 "tqmoc.y"
+
+#define TQMOC_YACC_CODE
+void yyerror( const char *msg );
+
+#include "tqplatformdefs.h"
+#include "tqasciidict.h"
+#include "tqdatetime.h"
+#include "tqdict.h"
+#include "tqfile.h"
+#include "tqdir.h"
+#include "tqptrlist.h"
+#include "tqregexp.h"
+#include "tqstrlist.h"
+#ifdef TQMOC_MWERKS_PLUGIN
+# ifdef TQ_OS_MACX
+# undef OLD_DEBUG
+# ifdef DEBUG
+# define OLD_DEBUG DEBUG
+# undef DEBUG
+# endif
+# define DEBUG 0
+# ifndef __IMAGECAPTURE__
+# define __IMAGECAPTURE__
+# endif
+# include <Carbon/Carbon.h>
+# endif
+# include "mwerks_mac.h"
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#if defined CONST
+#undef CONST
+#endif
+#if defined VOID
+#undef VOID
+#endif
+
+bool isEnumType( const char* type );
+int enumIndex( const char* type );
+bool isVariantType( const char* type );
+int qvariant_nameToType( const char* name );
+static void init(); // initialize
+static void initClass(); // prepare for new class
+static void generateClass(); // generate C++ code for class
+static void initExpression(); // prepare for new expression
+static void enterNameSpace( const char *name = 0 );
+static void leaveNameSpace();
+static void selectOutsideClassState();
+static void registerClassInNamespace();
+static bool suppress_func_warn = FALSE;
+static void func_warn( const char *msg );
+static void tqmoc_warn( const char *msg );
+static void tqmoc_err( const char *s );
+static void tqmoc_err( const char *s1, const char *s2 );
+static void operatorError();
+static void checkPropertyName( const char* ident );
+
+static const char* const utype_map[] =
+{
+ "bool",
+ "int",
+ "double",
+ "TQString",
+ "TQVariant",
+ 0
+};
+
+inline bool isIdentChar( char x )
+{ // Avoid bug in isalnum
+ return x == '_' || (x >= '0' && x <= '9') ||
+ (x >= 'a' && x <= 'z') || (x >= 'A' && x <= 'Z');
+}
+
+bool validUType( TQCString ctype )
+{
+ if ( ctype.left(6) == "const " )
+ ctype = ctype.mid( 6, ctype.length() - 6 );
+ if ( ctype.right(1) == "&" )
+ ctype = ctype.left( ctype.length() - 1 );
+ else if ( ctype.right(1) == "*" )
+ return TRUE;
+
+ int i = -1;
+ while ( utype_map[++i] )
+ if ( ctype == utype_map[i] )
+ return TRUE;
+
+ return isEnumType( ctype );
+}
+
+TQCString castToUType( TQCString ctype )
+{
+ if ( ctype.right(1) == "&" )
+ ctype = ctype.left( ctype.length() - 1 );
+ if( ctype.right(1) == "]") {
+ int lb = ctype.tqfindRev('[');
+ if(lb != -1)
+ ctype = ctype.left(lb) + "*";
+ }
+ return ctype;
+}
+
+TQCString rawUType( TQCString ctype )
+{
+ ctype = castToUType( ctype );
+ if ( ctype.left(6) == "const " )
+ ctype = ctype.mid( 6, ctype.length() - 6 );
+ return ctype;
+}
+
+TQCString uType( TQCString ctype )
+{
+ if ( !validUType( ctype ) ) {
+ if ( isVariantType( rawUType(ctype) ) )
+ return "varptr";
+ else
+ return "ptr";
+ }
+ if ( ctype.left(6) == "const " )
+ ctype = ctype.mid( 6, ctype.length() - 6 );
+ if ( ctype.right(1) == "&" ) {
+ ctype = ctype.left( ctype.length() - 1 );
+ } else if ( ctype.right(1) == "*" ) {
+ TQCString raw = ctype.left( ctype.length() - 1 );
+ ctype = "ptr";
+ if ( raw == "char" )
+ ctype = "charstar";
+ else if ( raw == "TQUnknownInterface" )
+ ctype = "iface";
+ else if ( raw == "TQDispatchInterface" )
+ ctype = "idisp";
+ else if ( isVariantType( raw ) )
+ ctype = "varptr";
+ }
+ if ( isEnumType( ctype ) )
+ ctype = "enum";
+ return ctype;
+}
+
+bool isInOut( TQCString ctype )
+{
+ if ( ctype.left(6) == "const " )
+ return FALSE;
+ if ( ctype.right(1) == "&" )
+ return TRUE;
+ if ( ctype.right(2) == "**" )
+ return TRUE;
+ return FALSE;
+}
+
+TQCString uTypeExtra( TQCString ctype )
+{
+ TQCString typeExtra = "0";
+ if ( !validUType( ctype ) ) {
+ if ( isVariantType( rawUType(ctype) ) )
+ typeExtra.sprintf("\"\\x%02x\"", qvariant_nameToType( rawUType(ctype) ) );
+ else
+ typeExtra.sprintf( "\"%s\"", rawUType(ctype).data() );
+ return typeExtra;
+ }
+ if ( ctype.left(6) == "const " )
+ ctype = ctype.mid( 6, ctype.length() - 6 );
+ if ( ctype.right(1) == "&" )
+ ctype = ctype.left( ctype.length() - 1 );
+ if ( ctype.right(1) == "*" ) {
+ TQCString raw = ctype.left( ctype.length() - 1 );
+ ctype = "ptr";
+ if ( raw == "char" )
+ ;
+ else if ( isVariantType( raw ) )
+ typeExtra.sprintf("\"\\x%02x\"", qvariant_nameToType( raw ) );
+ else
+ typeExtra.sprintf( "\"%s\"", raw.stripWhiteSpace().data() );
+
+ } else if ( isEnumType( ctype ) ) {
+ int idx = enumIndex( ctype );
+ if ( idx >= 0 ) {
+ typeExtra.sprintf( "&enum_tbl[%d]", enumIndex( ctype ) );
+ } else {
+ typeExtra.sprintf( "parentObject->enumerator(\"%s\", TRUE )", ctype.data() );
+ }
+ typeExtra =
+ "\n#ifndef TQT_NO_PROPERTIES\n\t " + typeExtra +
+ "\n#else"
+ "\n\t 0"
+ "\n#endif // TQT_NO_PROPERTIES\n\t ";
+ }
+ return typeExtra;
+}
+
+/*
+ Attention!
+ This table is copied from qvariant.cpp. If you change
+ one, change both.
+*/
+static const int ntypes = 35;
+static const char* const type_map[ntypes] =
+{
+ 0,
+ "TQMap<TQString,TQVariant>",
+ "TQValueList<TQVariant>",
+ "TQString",
+ "TQStringList",
+ "TQFont",
+ "TQPixmap",
+ "TQBrush",
+ "TQRect",
+ "TQSize",
+ "TQColor",
+ "TQPalette",
+ "TQColorGroup",
+ "TQIconSet",
+ "TQPoint",
+ "TQImage",
+ "int",
+ "uint",
+ "bool",
+ "double",
+ "TQCString",
+ "TQPointArray",
+ "TQRegion",
+ "TQBitmap",
+ "TQCursor",
+ "TQSizePolicy",
+ "TQDate",
+ "TQTime",
+ "TQDateTime",
+ "TQByteArray",
+ "TQBitArray",
+ "TQKeySequence",
+ "TQPen",
+ "TQ_LLONG",
+ "TQ_ULLONG"
+};
+
+int qvariant_nameToType( const char* name )
+{
+ for ( int i = 0; i < ntypes; i++ ) {
+ if ( !qstrcmp( type_map[i], name ) )
+ return i;
+ }
+ return 0;
+}
+
+/*
+ Returns TRUE if the type is a TQVariant types.
+*/
+bool isVariantType( const char* type )
+{
+ return qvariant_nameToType( type ) != 0;
+}
+
+/*
+ Replaces '>>' with '> >' (as in 'TQValueList<TQValueList<double> >').
+ This function must be called to produce valid C++ code. However,
+ the string representation still uses '>>'.
+*/
+void fixRightAngles( TQCString *str )
+{
+ str->tqreplace( TQRegExp(">>"), "> >" );
+}
+
+static TQCString rmWS( const char * );
+
+enum Access { Private, Protected, Public };
+
+
+class Argument // single arg meta data
+{
+public:
+ Argument( const char *left, const char *right, const char* argName = 0, bool isDefaultArgument = FALSE )
+ {
+ leftType = rmWS( left );
+ rightType = rmWS( right );
+ if ( leftType == "void" && rightType.isEmpty() )
+ leftType = "";
+
+ int len = leftType.length();
+
+ /*
+ Convert 'char const *' into 'const char *'. Start at index 1,
+ not 0, because 'const char *' is already OK.
+ */
+ for ( int i = 1; i < len; i++ ) {
+ if ( leftType[i] == 'c' &&
+ strncmp(leftType.data() + i + 1, "onst", 4) == 0
+ && (i + 5 >= len || !isIdentChar(leftType[i + 5]))
+ && !isIdentChar(i-1)
+ ) {
+ leftType.remove( i, 5 );
+ if ( leftType[i - 1] == ' ' )
+ leftType.remove( i - 1, 1 );
+ leftType.prepend( "const " );
+ break;
+ }
+
+ /*
+ We musn't convert 'char * const *' into 'const char **'
+ and we must beware of 'Bar<const Bla>'.
+ */
+ if ( leftType[i] == '&' || leftType[i] == '*' ||
+ leftType[i] == '<' )
+ break;
+ }
+
+ name = argName;
+ isDefault = isDefaultArgument;
+ }
+
+ TQCString leftType;
+ TQCString rightType;
+ TQCString name;
+ bool isDefault;
+};
+
+class ArgList : public TQPtrList<Argument> { // member function arg list
+public:
+ ArgList() { setAutoDelete( TRUE ); }
+ ~ArgList() { clear(); }
+
+ /* the clone has one default argument less, the orignal has all default arguments removed */
+ ArgList* magicClone() {
+ ArgList* l = new ArgList;
+ bool firstDefault = FALSE;
+ for ( first(); current(); next() ) {
+ bool isDefault = current()->isDefault;
+ if ( !firstDefault && isDefault ) {
+ isDefault = FALSE;
+ firstDefault = TRUE;
+ }
+ l->append( new Argument( current()->leftType, current()->rightType, current()->name, isDefault ) );
+ }
+ for ( first(); current(); ) {
+ if ( current()->isDefault )
+ remove();
+ else
+ next();
+ }
+ return l;
+ }
+
+ bool hasDefaultArguments() {
+ for ( Argument* a = first(); a; a = next() ) {
+ if ( a->isDefault )
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+};
+
+
+struct Function // member function meta data
+{
+ Access access;
+ TQCString qualifier; // const or volatile
+ TQCString name;
+ TQCString type;
+ TQCString signature;
+ int lineNo;
+ ArgList *args;
+ Function() { args=0;}
+ ~Function() { delete args; }
+ const char* accessAsString() {
+ switch ( access ) {
+ case Private: return "Private";
+ case Protected: return "Protected";
+ default: return "Public";
+ }
+ }
+};
+
+class FuncList : public TQPtrList<Function> { // list of member functions
+public:
+ FuncList( bool autoDelete = FALSE ) { setAutoDelete( autoDelete ); }
+
+ FuncList tqfind( const char* name )
+ {
+ FuncList result;
+ for ( TQPtrListIterator<Function> it(*this); it.current(); ++it ) {
+ if ( it.current()->name == name )
+ result.append( it.current() );
+ }
+ return result;
+ }
+};
+
+class Enum : public TQStrList
+{
+public:
+ TQCString name;
+ bool set;
+};
+
+class EnumList : public TQPtrList<Enum> { // list of property enums
+public:
+ EnumList() { setAutoDelete(TRUE); }
+};
+
+
+struct Property
+{
+ Property( int l, const char* t, const char* n, const char* s, const char* g, const char* r,
+ const TQCString& st, const TQCString& d, const TQCString& sc, bool ov )
+ : lineNo(l), type(t), name(n), set(s), get(g), reset(r), setfunc(0), getfunc(0),
+ sspec(Unspecified), gspec(Unspecified), stored( st ),
+ designable( d ), scriptable( sc ), override( ov ), oredEnum( -1 )
+ {
+ /*
+ The Q_PROPERTY construct cannot contain any commas, since
+ commas separate macro arguments. We therefore expect users
+ to type "TQMap" instead of "TQMap<TQString, TQVariant>". For
+ coherence, we also expect the same for
+ TQValueList<TQVariant>, the other template class supported by
+ TQVariant.
+ */
+ if ( type == "TQMap" ) {
+ type = "TQMap<TQString,TQVariant>";
+ } else if ( type == "TQValueList" ) {
+ type = "TQValueList<TQVariant>";
+ } else if ( type == "LongLong" ) {
+ type = "TQ_LLONG";
+ } else if ( type == "ULongLong" ) {
+ type = "TQ_ULLONG";
+ }
+ }
+
+ int lineNo;
+ TQCString type;
+ TQCString name;
+ TQCString set;
+ TQCString get;
+ TQCString reset;
+ TQCString stored;
+ TQCString designable;
+ TQCString scriptable;
+ bool override;
+
+ Function* setfunc;
+ Function* getfunc;
+
+ int oredEnum; // If the enums item may be ored. That means the data type is int.
+ // Allowed values are 1 (True), 0 (False), and -1 (Unset)
+ TQCString enumsettype; // tqcontains the set function type in case of oredEnum
+ TQCString enumgettype; // tqcontains the get function type in case of oredEnum
+
+ enum Specification { Unspecified, Class, Reference, Pointer, ConstCharStar };
+ Specification sspec;
+ Specification gspec;
+
+ bool stdSet() {
+ TQCString s = "set";
+ s += toupper( name[0] );
+ s += name.mid( 1 );
+ return s == set;
+ }
+
+ static const char* specToString( Specification s )
+ {
+ switch ( s ) {
+ case Class:
+ return "Class";
+ case Reference:
+ return "Reference";
+ case Pointer:
+ return "Pointer";
+ case ConstCharStar:
+ return "ConstCharStar";
+ default:
+ return "Unspecified";
+ }
+ }
+};
+
+class PropList : public TQPtrList<Property> { // list of properties
+public:
+ PropList() { setAutoDelete( TRUE ); }
+};
+
+
+struct ClassInfo
+{
+ ClassInfo( const char* n, const char* v )
+ : name(n), value(v)
+ {}
+ TQCString name;
+ TQCString value;
+};
+
+class ClassInfoList : public TQPtrList<ClassInfo> { // list of class infos
+public:
+ ClassInfoList() { setAutoDelete( TRUE ); }
+};
+
+class parser_reg {
+ public:
+ parser_reg();
+ ~parser_reg();
+
+ // some temporary values
+ TQCString tmpExpression; // Used to store the characters the lexer
+ // is currently skipping (see addExpressionChar and friends)
+ TQCString fileName; // file name
+ TQCString outputFile; // output file name
+ TQCString pchFile; // name of PCH file (used on Windows)
+ TQStrList includeFiles; // name of #include files
+ TQCString includePath; // #include file path
+ TQCString qtPath; // #include qt file path
+ int gen_count; //number of classes generated
+ bool noInclude; // no #include <filename>
+ bool generatedCode; // no code generated
+ bool tqmocError; // tqmoc parsing error occurred
+ bool hasVariantIncluded; //whether or not qvariant.h was included yet
+ TQCString className; // name of parsed class
+ TQCString superClassName; // name of first super class
+ TQStrList multipleSuperClasses; // other superclasses
+ FuncList tqsignals; // signal interface
+ FuncList tqslots; // tqslots interface
+ FuncList propfuncs; // all possible property access functions
+ FuncList funcs; // all parsed functions, including tqsignals
+ EnumList enums; // enums used in properties
+ PropList props; // list of all properties
+ ClassInfoList infos; // list of all class infos
+
+// Used to store the values in the Q_PROPERTY macro
+ TQCString propWrite; // set function
+ TQCString propRead; // get function
+ TQCString propReset; // reset function
+ TQCString propStored; //
+ TQCString propDesignable; // "true", "false" or function or empty if not specified
+ TQCString propScriptable; // "true", "false" or function or empty if not specified
+ bool propOverride; // Wether OVERRIDE was detected
+
+ TQStrList qtEnums; // Used to store the contents of TQ_ENUMS
+ TQStrList qtSets; // Used to store the contents of TQ_SETS
+
+};
+
+static parser_reg *g = 0;
+
+ArgList *addArg( Argument * ); // add arg to tmpArgList
+
+enum Member { SignalMember,
+ SlotMember,
+ PropertyCandidateMember
+ };
+
+void addMember( Member ); // add tmpFunc to current class
+void addEnum(); // add tmpEnum to current class
+
+char *stradd( const char *, const char * ); // add two strings
+char *stradd( const char *, const char *, // add three strings
+ const char * );
+char *stradd( const char *, const char *, // adds 4 strings
+ const char *, const char * );
+
+char *straddSpc( const char *, const char * );
+char *straddSpc( const char *, const char *,
+ const char * );
+char *straddSpc( const char *, const char *,
+ const char *, const char * );
+
+extern int yydebug;
+bool lexDebug = FALSE;
+int lineNo; // current line number
+bool errorControl = FALSE; // controled errors
+bool displayWarnings = TRUE;
+bool skipClass; // don't generate for class
+bool skipFunc; // don't generate for func
+bool templateClass; // class is a template
+bool templateClassOld; // previous class is a template
+
+ArgList *tmpArgList; // current argument list
+Function *tmpFunc; // current member function
+Enum *tmpEnum; // current enum
+Access tmpAccess; // current access permission
+Access subClassPerm; // current access permission
+
+bool TQ_OBJECTdetected; // TRUE if current class
+ // tqcontains the TQ_OBJECT macro
+bool Q_PROPERTYdetected; // TRUE if current class
+ // tqcontains at least one Q_PROPERTY,
+ // TQ_OVERRIDE, TQ_SETS or TQ_ENUMS macro
+bool tmpPropOverride; // current property override setting
+
+int tmpYYStart; // Used to store the lexers current mode
+int tmpYYStart2; // Used to store the lexers current mode
+ // (if tmpYYStart is already used)
+
+// if the format revision changes, you MUST change it in qmetaobject.h too
+const int formatRevision = 26; // tqmoc output format revision
+
+// if the flags change, you HAVE to change it in qmetaobject.h too
+enum Flags {
+ Invalid = 0x00000000,
+ Readable = 0x00000001,
+ Writable = 0x00000002,
+ EnumOrSet = 0x00000004,
+ UnresolvedEnum = 0x00000008,
+ StdSet = 0x00000100,
+ Override = 0x00000200,
+ NotDesignable = 0x00001000,
+ DesignableOverride = 0x00002000,
+ NotScriptable = 0x00004000,
+ ScriptableOverride = 0x00008000,
+ NotStored = 0x00010000,
+ StoredOverride = 0x00020000
+};
+
+
+#ifdef YYBISON
+# if defined(TQ_OS_WIN32)
+# include <io.h>
+# undef isatty
+extern "C" int hack_isatty( int )
+ {
+ return 0;
+ }
+# define isatty hack_isatty
+# else
+# include <unistd.h>
+# endif
+
+# define YYDEBUG 1
+# include "tqmoc_yacc.h"
+# include "tqmoc_lex.cpp"
+#endif //YYBISON
+
+
+/* Line 189 of yacc.c */
+#line 706 "tqmoc_yacc.cpp"
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ CHAR_VAL = 258,
+ INT_VAL = 259,
+ DOUBLE_VAL = 260,
+ STRING = 261,
+ IDENTIFIER = 262,
+ FRIEND = 263,
+ TYPEDEF = 264,
+ AUTO = 265,
+ REGISTER = 266,
+ STATIC = 267,
+ EXTERN = 268,
+ INLINE = 269,
+ VIRTUAL = 270,
+ CONST = 271,
+ VOLATILE = 272,
+ CHAR = 273,
+ SHORT = 274,
+ INT = 275,
+ LONG = 276,
+ SIGNED = 277,
+ UNSIGNED = 278,
+ FLOAT = 279,
+ DOUBLE = 280,
+ VOID = 281,
+ ENUM = 282,
+ CLASS = 283,
+ STRUCT = 284,
+ UNION = 285,
+ ASM = 286,
+ PRIVATE = 287,
+ PROTECTED = 288,
+ PUBLIC = 289,
+ OPERATOR = 290,
+ DBL_COLON = 291,
+ TRIPLE_DOT = 292,
+ TEMPLATE = 293,
+ NAMESPACE = 294,
+ USING = 295,
+ MUTABLE = 296,
+ THROW = 297,
+ SIGNALS = 298,
+ SLOTS = 299,
+ TQ_OBJECT = 300,
+ Q_PROPERTY = 301,
+ TQ_OVERRIDE = 302,
+ TQ_CLASSINFO = 303,
+ TQ_ENUMS = 304,
+ TQ_SETS = 305,
+ READ = 306,
+ WRITE = 307,
+ STORED = 308,
+ DESIGNABLE = 309,
+ SCRIPTABLE = 310,
+ RESET = 311
+ };
+#endif
+/* Tokens. */
+#define CHAR_VAL 258
+#define INT_VAL 259
+#define DOUBLE_VAL 260
+#define STRING 261
+#define IDENTIFIER 262
+#define FRIEND 263
+#define TYPEDEF 264
+#define AUTO 265
+#define REGISTER 266
+#define STATIC 267
+#define EXTERN 268
+#define INLINE 269
+#define VIRTUAL 270
+#define CONST 271
+#define VOLATILE 272
+#define CHAR 273
+#define SHORT 274
+#define INT 275
+#define LONG 276
+#define SIGNED 277
+#define UNSIGNED 278
+#define FLOAT 279
+#define DOUBLE 280
+#define VOID 281
+#define ENUM 282
+#define CLASS 283
+#define STRUCT 284
+#define UNION 285
+#define ASM 286
+#define PRIVATE 287
+#define PROTECTED 288
+#define PUBLIC 289
+#define OPERATOR 290
+#define DBL_COLON 291
+#define TRIPLE_DOT 292
+#define TEMPLATE 293
+#define NAMESPACE 294
+#define USING 295
+#define MUTABLE 296
+#define THROW 297
+#define SIGNALS 298
+#define SLOTS 299
+#define TQ_OBJECT 300
+#define Q_PROPERTY 301
+#define TQ_OVERRIDE 302
+#define TQ_CLASSINFO 303
+#define TQ_ENUMS 304
+#define TQ_SETS 305
+#define READ 306
+#define WRITE 307
+#define STORED 308
+#define DESIGNABLE 309
+#define SCRIPTABLE 310
+#define RESET 311
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 214 of yacc.c */
+#line 692 "tqmoc.y"
+
+ char char_val;
+ int int_val;
+ double double_val;
+ char *string;
+ Access access;
+ Function *function;
+ ArgList *arg_list;
+ Argument *arg;
+
+
+
+/* Line 214 of yacc.c */
+#line 867 "tqmoc_yacc.cpp"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 264 of yacc.c */
+#line 879 "tqmoc_yacc.cpp"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
+ + YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 2
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 612
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 79
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 140
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 329
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 492
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 311
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 78, 2, 2, 2, 74, 69, 2,
+ 66, 67, 68, 71, 63, 72, 2, 73, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 70, 60,
+ 61, 59, 62, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 64, 2, 65, 75, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 57, 76, 58, 77, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 4, 7, 9, 11, 13, 15, 17,
+ 19, 21, 22, 23, 31, 32, 33, 40, 42, 48,
+ 51, 54, 57, 58, 62, 64, 66, 71, 72, 73,
+ 74, 75, 77, 79, 81, 83, 85, 89, 90, 92,
+ 94, 97, 99, 101, 103, 105, 107, 109, 111, 113,
+ 115, 117, 119, 122, 124, 126, 128, 130, 132, 134,
+ 136, 138, 140, 142, 147, 148, 150, 153, 156, 158,
+ 161, 165, 167, 170, 173, 176, 179, 183, 184, 186,
+ 187, 189, 190, 192, 196, 198, 201, 202, 208, 213,
+ 214, 222, 223, 225, 228, 229, 234, 235, 241, 243,
+ 247, 249, 252, 253, 259, 263, 265, 274, 276, 279,
+ 280, 285, 286, 292, 293, 298, 299, 305, 306, 308,
+ 310, 313, 316, 319, 320, 322, 324, 327, 329, 331,
+ 333, 335, 339, 340, 344, 345, 351, 353, 357, 361,
+ 366, 369, 371, 373, 375, 377, 379, 382, 386, 389,
+ 393, 394, 396, 401, 402, 404, 407, 409, 413, 414,
+ 420, 421, 423, 424, 426, 429, 431, 433, 435, 436,
+ 440, 441, 446, 448, 449, 450, 458, 459, 460, 468,
+ 469, 470, 480, 481, 482, 490, 491, 492, 500, 503,
+ 507, 508, 512, 514, 515, 517, 520, 522, 524, 525,
+ 527, 530, 532, 534, 535, 537, 540, 542, 544, 545,
+ 548, 551, 555, 557, 562, 567, 569, 573, 576, 580,
+ 583, 585, 589, 592, 596, 599, 601, 603, 605, 609,
+ 613, 615, 617, 619, 621, 623, 625, 627, 629, 631,
+ 633, 635, 637, 639, 642, 645, 648, 651, 654, 657,
+ 660, 663, 666, 669, 672, 675, 678, 681, 684, 688,
+ 692, 695, 698, 701, 704, 706, 710, 713, 716, 719,
+ 720, 722, 725, 727, 731, 737, 740, 744, 749, 753,
+ 756, 763, 768, 774, 778, 783, 790, 795, 800, 806,
+ 810, 814, 815, 816, 824, 826, 830, 832, 833, 838,
+ 839, 843, 844, 845, 849, 852, 853, 855, 861, 866,
+ 867, 869, 870, 872, 876, 878, 879, 884, 885, 890,
+ 891, 895, 899, 903, 907, 911, 915, 916, 919, 920
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 80, 0, -1, -1, 80, 81, -1, 93, -1, 82,
+ -1, 90, -1, 92, -1, 91, -1, 83, -1, 86,
+ -1, -1, -1, 39, 7, 84, 57, 85, 89, 58,
+ -1, -1, -1, 39, 87, 57, 88, 89, 58, -1,
+ 80, -1, 39, 7, 59, 114, 60, -1, 40, 39,
+ -1, 40, 7, -1, 40, 36, -1, -1, 94, 148,
+ 60, -1, 7, -1, 96, -1, 7, 61, 97, 62,
+ -1, -1, -1, -1, -1, 105, -1, 107, -1, 106,
+ -1, 8, -1, 9, -1, 103, 108, 103, -1, -1,
+ 104, -1, 101, -1, 104, 101, -1, 10, -1, 11,
+ -1, 12, -1, 13, -1, 14, -1, 15, -1, 16,
+ -1, 17, -1, 116, -1, 114, -1, 109, -1, 109,
+ 110, -1, 110, -1, 18, -1, 19, -1, 20, -1,
+ 21, -1, 22, -1, 23, -1, 24, -1, 25, -1,
+ 26, -1, 38, 61, 97, 62, -1, -1, 111, -1,
+ 112, 28, -1, 112, 29, -1, 115, -1, 36, 115,
+ -1, 115, 36, 95, -1, 95, -1, 113, 7, -1,
+ 27, 7, -1, 30, 7, -1, 118, 120, -1, 121,
+ 63, 37, -1, -1, 121, -1, -1, 122, -1, -1,
+ 37, -1, 121, 63, 122, -1, 122, -1, 102, 125,
+ -1, -1, 102, 125, 59, 123, 99, -1, 102, 125,
+ 131, 125, -1, -1, 102, 125, 131, 125, 59, 124,
+ 99, -1, -1, 126, -1, 126, 141, -1, -1, 64,
+ 127, 98, 65, -1, -1, 126, 64, 128, 98, 65,
+ -1, 141, -1, 66, 126, 67, -1, 131, -1, 129,
+ 141, -1, -1, 129, 64, 130, 98, 65, -1, 66,
+ 129, 67, -1, 7, -1, 66, 117, 67, 142, 156,
+ 154, 210, 145, -1, 7, -1, 7, 136, -1, -1,
+ 7, 59, 134, 98, -1, -1, 7, 136, 59, 135,
+ 98, -1, -1, 64, 137, 98, 65, -1, -1, 136,
+ 64, 138, 98, 65, -1, -1, 140, -1, 141, -1,
+ 140, 141, -1, 68, 142, -1, 69, 142, -1, -1,
+ 143, -1, 144, -1, 143, 144, -1, 16, -1, 17,
+ -1, 60, -1, 146, -1, 59, 4, 60, -1, -1,
+ 57, 147, 58, -1, -1, 152, 57, 149, 162, 58,
+ -1, 151, -1, 151, 68, 7, -1, 151, 69, 7,
+ -1, 151, 66, 7, 67, -1, 111, 150, -1, 7,
+ -1, 110, -1, 107, -1, 105, -1, 106, -1, 113,
+ 115, -1, 113, 7, 95, -1, 151, 161, -1, 113,
+ 115, 161, -1, -1, 155, -1, 42, 66, 119, 67,
+ -1, -1, 157, -1, 70, 158, -1, 159, -1, 159,
+ 63, 158, -1, -1, 114, 66, 160, 98, 67, -1,
+ -1, 190, -1, -1, 163, -1, 163, 165, -1, 165,
+ -1, 194, -1, 44, -1, -1, 164, 166, 178, -1,
+ -1, 43, 167, 70, 183, -1, 45, -1, -1, -1,
+ 46, 168, 66, 214, 67, 169, 180, -1, -1, -1,
+ 47, 170, 66, 214, 67, 171, 180, -1, -1, -1,
+ 48, 172, 66, 6, 63, 6, 67, 173, 180, -1,
+ -1, -1, 49, 174, 66, 217, 67, 175, 180, -1,
+ -1, -1, 50, 176, 66, 218, 67, 177, 180, -1,
+ 43, 70, -1, 44, 70, 186, -1, -1, 70, 179,
+ 180, -1, 7, -1, -1, 181, -1, 181, 182, -1,
+ 182, -1, 198, -1, -1, 184, -1, 184, 185, -1,
+ 185, -1, 198, -1, -1, 187, -1, 187, 188, -1,
+ 188, -1, 198, -1, -1, 189, 60, -1, 70, 191,
+ -1, 191, 63, 193, -1, 193, -1, 7, 66, 7,
+ 67, -1, 7, 66, 110, 67, -1, 114, -1, 15,
+ 194, 114, -1, 15, 114, -1, 194, 15, 114, -1,
+ 194, 114, -1, 192, -1, 15, 194, 192, -1, 15,
+ 192, -1, 194, 15, 192, -1, 194, 192, -1, 32,
+ -1, 33, -1, 34, -1, 103, 7, 139, -1, 103,
+ 110, 139, -1, 71, -1, 72, -1, 68, -1, 73,
+ -1, 74, -1, 75, -1, 69, -1, 76, -1, 77,
+ -1, 78, -1, 59, -1, 61, -1, 62, -1, 71,
+ 59, -1, 72, 59, -1, 68, 59, -1, 73, 59,
+ -1, 74, 59, -1, 75, 59, -1, 69, 59, -1,
+ 76, 59, -1, 77, 59, -1, 78, 59, -1, 59,
+ 59, -1, 61, 59, -1, 62, 59, -1, 61, 61,
+ -1, 62, 62, -1, 61, 61, 59, -1, 62, 62,
+ 59, -1, 69, 69, -1, 76, 76, -1, 71, 71,
+ -1, 72, 72, -1, 63, -1, 72, 62, 68, -1,
+ 72, 62, -1, 66, 67, -1, 64, 65, -1, -1,
+ 15, -1, 108, 133, -1, 133, -1, 196, 77, 133,
+ -1, 104, 108, 103, 139, 133, -1, 104, 108, -1,
+ 108, 140, 133, -1, 108, 104, 139, 133, -1, 108,
+ 35, 195, -1, 35, 195, -1, 104, 108, 103, 139,
+ 35, 195, -1, 108, 140, 35, 195, -1, 108, 104,
+ 139, 35, 195, -1, 197, 132, 189, -1, 197, 205,
+ 60, 189, -1, 197, 205, 63, 201, 60, 189, -1,
+ 207, 210, 60, 189, -1, 40, 114, 60, 189, -1,
+ 40, 39, 114, 60, 189, -1, 39, 7, 57, -1,
+ 153, 60, 189, -1, -1, -1, 153, 57, 199, 58,
+ 200, 60, 189, -1, 202, -1, 201, 63, 202, -1,
+ 129, -1, -1, 7, 70, 203, 98, -1, -1, 70,
+ 204, 98, -1, -1, -1, 70, 206, 98, -1, 27,
+ 209, -1, -1, 63, -1, 7, 57, 211, 208, 58,
+ -1, 57, 211, 208, 58, -1, -1, 7, -1, -1,
+ 212, -1, 211, 63, 212, -1, 7, -1, -1, 7,
+ 59, 213, 100, -1, -1, 7, 7, 215, 216, -1,
+ -1, 51, 7, 216, -1, 52, 7, 216, -1, 56,
+ 7, 216, -1, 53, 7, 216, -1, 54, 7, 216,
+ -1, 55, 7, 216, -1, -1, 7, 217, -1, -1,
+ 7, 218, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 807, 807, 808, 811, 813, 814, 815, 816, 819,
+ 820, 824, 825, 823, 832, 833, 832, 840, 843, 848,
+ 851, 852, 855, 855, 864, 865, 868, 880, 893, 902,
+ 905, 911, 912, 913, 914, 915, 918, 921, 922, 925,
+ 926, 929, 930, 931, 932, 935, 936, 939, 940, 943,
+ 944, 945, 948, 950, 953, 954, 955, 956, 957, 958,
+ 959, 960, 961, 964, 970, 971, 977, 978, 981, 982,
+ 986, 988, 992, 993, 994, 999, 1000, 1006, 1007, 1010,
+ 1011, 1014, 1015, 1021, 1024, 1027, 1030, 1029, 1033, 1038,
+ 1036, 1044, 1045, 1048, 1050, 1050, 1055, 1055, 1060, 1061,
+ 1064, 1065, 1067, 1067, 1072, 1075, 1078, 1090, 1091, 1093,
+ 1093, 1096, 1096, 1102, 1102, 1104, 1104, 1109, 1110, 1113,
+ 1114, 1117, 1118, 1125, 1126, 1129, 1130, 1134, 1135, 1138,
+ 1139, 1140, 1143, 1143, 1151, 1150, 1156, 1158, 1160, 1162,
+ 1166, 1170, 1171, 1172, 1173, 1174, 1178, 1184, 1193, 1197,
+ 1202, 1203, 1207, 1210, 1211, 1214, 1217, 1218, 1222, 1222,
+ 1227, 1228, 1231, 1232, 1235, 1236, 1240, 1241, 1245, 1245,
+ 1247, 1247, 1249, 1257, 1260, 1257, 1264, 1267, 1264, 1271,
+ 1273, 1271, 1278, 1279, 1278, 1284, 1285, 1284, 1292, 1294,
+ 1295, 1295, 1305, 1312, 1313, 1316, 1317, 1320, 1323, 1324,
+ 1327, 1328, 1332, 1335, 1336, 1339, 1340, 1343, 1346, 1347,
+ 1350, 1353, 1354, 1357, 1359, 1363, 1364, 1365, 1366, 1367,
+ 1368, 1369, 1370, 1371, 1372, 1375, 1376, 1377, 1380, 1381,
+ 1382, 1383, 1384, 1385, 1386, 1387, 1388, 1389, 1390, 1391,
+ 1392, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401,
+ 1402, 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411,
+ 1412, 1413, 1414, 1415, 1416, 1417, 1418, 1419, 1420, 1424,
+ 1425, 1428, 1431, 1438, 1445, 1453, 1455, 1459, 1464, 1466,
+ 1468, 1471, 1473, 1479, 1480, 1482, 1485, 1487, 1489, 1491,
+ 1494, 1497, 1500, 1496, 1505, 1506, 1509, 1510, 1510, 1512,
+ 1512, 1516, 1517, 1517, 1522, 1527, 1528, 1531, 1538, 1542,
+ 1543, 1546, 1547, 1548, 1551, 1552, 1552, 1557, 1556, 1593,
+ 1594, 1595, 1596, 1597, 1598, 1599, 1602, 1603, 1606, 1607
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "CHAR_VAL", "INT_VAL", "DOUBLE_VAL",
+ "STRING", "IDENTIFIER", "FRIEND", "TYPEDEF", "AUTO", "REGISTER",
+ "STATIC", "EXTERN", "INLINE", "VIRTUAL", "CONST", "VOLATILE", "CHAR",
+ "SHORT", "INT", "LONG", "SIGNED", "UNSIGNED", "FLOAT", "DOUBLE", "VOID",
+ "ENUM", "CLASS", "STRUCT", "UNION", "ASM", "PRIVATE", "PROTECTED",
+ "PUBLIC", "OPERATOR", "DBL_COLON", "TRIPLE_DOT", "TEMPLATE", "NAMESPACE",
+ "USING", "MUTABLE", "THROW", "SIGNALS", "SLOTS", "TQ_OBJECT",
+ "Q_PROPERTY", "TQ_OVERRIDE", "TQ_CLASSINFO", "TQ_ENUMS", "TQ_SETS",
+ "READ", "WRITE", "STORED", "DESIGNABLE", "SCRIPTABLE", "RESET", "'{'",
+ "'}'", "'='", "';'", "'<'", "'>'", "','", "'['", "']'", "'('", "')'",
+ "'*'", "'&'", "':'", "'+'", "'-'", "'/'", "'%'", "'^'", "'|'", "'~'",
+ "'!'", "$accept", "declaration_seq", "declaration", "namespace_def",
+ "named_namespace_def", "$@1", "$@2", "unnamed_namespace_def", "$@3",
+ "$@4", "namespace_body", "namespace_alias_def", "using_directive",
+ "using_declaration", "class_def", "$@5", "class_name",
+ "template_class_name", "template_args", "const_expression",
+ "def_argument", "enumerator_expression", "decl_specifier",
+ "decl_specifiers", "decl_specs_opt", "decl_specs",
+ "storage_class_specifier", "fct_specifier", "type_specifier",
+ "type_name", "simple_type_names", "simple_type_name", "template_spec",
+ "opt_template_spec", "class_key", "complete_class_name",
+ "qualified_class_name", "elaborated_type_specifier",
+ "argument_declaration_list", "arg_declaration_list_opt",
+ "opt_exception_argument", "triple_dot_opt", "arg_declaration_list",
+ "argument_declaration", "$@6", "$@7", "abstract_decl_opt",
+ "abstract_decl", "$@8", "$@9", "declarator", "$@10", "dname", "fct_decl",
+ "fct_name", "$@11", "$@12", "array_decls", "$@13", "$@14",
+ "ptr_operators_opt", "ptr_operators", "ptr_operator",
+ "cv_qualifier_list_opt", "cv_qualifier_list", "cv_qualifier",
+ "fct_body_or_semicolon", "fct_body", "$@15", "class_specifier", "$@16",
+ "whatever", "class_head", "full_class_head", "nested_class_head",
+ "exception_spec_opt", "exception_spec", "ctor_initializer_opt",
+ "ctor_initializer", "mem_initializer_list", "mem_initializer", "$@17",
+ "opt_base_spec", "opt_obj_member_list", "obj_member_list",
+ "qt_access_specifier", "obj_member_area", "$@18", "$@19", "$@20", "$@21",
+ "$@22", "$@23", "$@24", "$@25", "$@26", "$@27", "$@28", "$@29",
+ "slot_area", "$@30", "opt_property_candidates",
+ "property_candidate_declarations", "property_candidate_declaration",
+ "opt_signal_declarations", "signal_declarations", "signal_declaration",
+ "opt_slot_declarations", "slot_declarations", "slot_declaration",
+ "opt_semicolons", "base_spec", "base_list", "qt_macro_name",
+ "base_specifier", "access_specifier", "operator_name", "opt_virtual",
+ "type_and_name", "signal_or_slot", "$@31", "$@32",
+ "member_declarator_list", "member_declarator", "$@33", "$@34",
+ "opt_bitfield", "$@35", "enum_specifier", "opt_komma", "enum_tail",
+ "opt_identifier", "enum_list", "enumerator", "$@36", "property", "$@37",
+ "prop_statements", "qt_enums", "qt_sets", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 123, 125, 61,
+ 59, 60, 62, 44, 91, 93, 40, 41, 42, 38,
+ 58, 43, 45, 47, 37, 94, 124, 126, 33
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 79, 80, 80, 81, 81, 81, 81, 81, 82,
+ 82, 84, 85, 83, 87, 88, 86, 89, 90, 91,
+ 92, 92, 94, 93, 95, 95, 96, 97, 98, 99,
+ 100, 101, 101, 101, 101, 101, 102, 103, 103, 104,
+ 104, 105, 105, 105, 105, 106, 106, 107, 107, 108,
+ 108, 108, 109, 109, 110, 110, 110, 110, 110, 110,
+ 110, 110, 110, 111, 112, 112, 113, 113, 114, 114,
+ 115, 115, 116, 116, 116, 117, 117, 118, 118, 119,
+ 119, 120, 120, 121, 121, 122, 123, 122, 122, 124,
+ 122, 125, 125, 126, 127, 126, 128, 126, 126, 126,
+ 129, 129, 130, 129, 129, 131, 132, 133, 133, 134,
+ 133, 135, 133, 137, 136, 138, 136, 139, 139, 140,
+ 140, 141, 141, 142, 142, 143, 143, 144, 144, 145,
+ 145, 145, 147, 146, 149, 148, 148, 148, 148, 148,
+ 148, 150, 150, 150, 150, 150, 151, 151, 152, 153,
+ 154, 154, 155, 156, 156, 157, 158, 158, 160, 159,
+ 161, 161, 162, 162, 163, 163, 164, 164, 166, 165,
+ 167, 165, 165, 168, 169, 165, 170, 171, 165, 172,
+ 173, 165, 174, 175, 165, 176, 177, 165, 178, 178,
+ 179, 178, 178, 180, 180, 181, 181, 182, 183, 183,
+ 184, 184, 185, 186, 186, 187, 187, 188, 189, 189,
+ 190, 191, 191, 192, 192, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 194, 194, 194, 195, 195,
+ 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+ 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+ 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+ 195, 195, 195, 195, 195, 195, 195, 195, 195, 196,
+ 196, 197, 197, 197, 197, 197, 197, 197, 197, 197,
+ 197, 197, 197, 198, 198, 198, 198, 198, 198, 198,
+ 198, 199, 200, 198, 201, 201, 202, 203, 202, 204,
+ 202, 205, 206, 205, 207, 208, 208, 209, 209, 210,
+ 210, 211, 211, 211, 212, 213, 212, 215, 214, 216,
+ 216, 216, 216, 216, 216, 216, 217, 217, 218, 218
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 0, 2, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 7, 0, 0, 6, 1, 5, 2,
+ 2, 2, 0, 3, 1, 1, 4, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 3, 0, 1, 1,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 4, 0, 1, 2, 2, 1, 2,
+ 3, 1, 2, 2, 2, 2, 3, 0, 1, 0,
+ 1, 0, 1, 3, 1, 2, 0, 5, 4, 0,
+ 7, 0, 1, 2, 0, 4, 0, 5, 1, 3,
+ 1, 2, 0, 5, 3, 1, 8, 1, 2, 0,
+ 4, 0, 5, 0, 4, 0, 5, 0, 1, 1,
+ 2, 2, 2, 0, 1, 1, 2, 1, 1, 1,
+ 1, 3, 0, 3, 0, 5, 1, 3, 3, 4,
+ 2, 1, 1, 1, 1, 1, 2, 3, 2, 3,
+ 0, 1, 4, 0, 1, 2, 1, 3, 0, 5,
+ 0, 1, 0, 1, 2, 1, 1, 1, 0, 3,
+ 0, 4, 1, 0, 0, 7, 0, 0, 7, 0,
+ 0, 9, 0, 0, 7, 0, 0, 7, 2, 3,
+ 0, 3, 1, 0, 1, 2, 1, 1, 0, 1,
+ 2, 1, 1, 0, 1, 2, 1, 1, 0, 2,
+ 2, 3, 1, 4, 4, 1, 3, 2, 3, 2,
+ 1, 3, 2, 3, 2, 1, 1, 1, 3, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3,
+ 2, 2, 2, 2, 1, 3, 2, 2, 2, 0,
+ 1, 2, 1, 3, 5, 2, 3, 4, 3, 2,
+ 6, 4, 5, 3, 4, 6, 4, 4, 5, 3,
+ 3, 0, 0, 7, 1, 3, 1, 0, 4, 0,
+ 3, 0, 0, 3, 2, 0, 1, 5, 4, 0,
+ 1, 0, 1, 3, 1, 0, 4, 0, 4, 0,
+ 3, 3, 3, 3, 3, 3, 0, 2, 0, 2
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint16 yydefact[] =
+{
+ 2, 22, 1, 14, 0, 3, 5, 9, 10, 6,
+ 8, 7, 4, 64, 11, 0, 20, 21, 19, 0,
+ 65, 0, 0, 0, 136, 0, 0, 0, 15, 27,
+ 141, 41, 42, 43, 44, 45, 46, 47, 48, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 144, 145,
+ 143, 142, 140, 66, 67, 24, 71, 25, 146, 23,
+ 0, 0, 0, 0, 148, 161, 134, 24, 0, 0,
+ 68, 12, 2, 0, 27, 147, 0, 0, 137, 138,
+ 24, 0, 225, 226, 227, 215, 210, 220, 212, 0,
+ 162, 69, 18, 2, 22, 0, 63, 0, 70, 139,
+ 0, 217, 222, 0, 0, 0, 219, 224, 170, 167,
+ 172, 173, 176, 179, 182, 185, 0, 163, 168, 165,
+ 166, 0, 16, 26, 0, 0, 216, 221, 211, 218,
+ 223, 0, 0, 0, 0, 0, 0, 135, 164, 0,
+ 13, 213, 214, 198, 0, 0, 0, 326, 328, 192,
+ 0, 0, 190, 169, 24, 34, 35, 46, 0, 0,
+ 37, 0, 0, 39, 64, 31, 33, 32, 0, 51,
+ 53, 65, 0, 50, 49, 272, 0, 171, 199, 201,
+ 0, 301, 202, 309, 0, 0, 0, 0, 326, 0,
+ 328, 0, 188, 203, 193, 109, 113, 108, 73, 311,
+ 304, 74, 240, 241, 242, 264, 0, 0, 232, 236,
+ 230, 231, 233, 234, 235, 237, 238, 239, 0, 38,
+ 279, 0, 0, 0, 0, 40, 37, 0, 107, 37,
+ 123, 123, 117, 271, 0, 119, 52, 72, 160, 291,
+ 208, 200, 0, 37, 302, 208, 0, 310, 0, 317,
+ 174, 177, 0, 327, 183, 329, 186, 189, 204, 206,
+ 207, 191, 194, 196, 197, 28, 28, 111, 115, 311,
+ 314, 305, 312, 253, 254, 256, 255, 257, 268, 267,
+ 245, 249, 260, 243, 262, 244, 266, 263, 246, 247,
+ 248, 250, 261, 251, 252, 117, 117, 289, 0, 208,
+ 73, 117, 72, 278, 127, 128, 121, 124, 125, 122,
+ 0, 118, 37, 276, 120, 149, 0, 290, 273, 91,
+ 64, 0, 81, 78, 84, 28, 283, 208, 0, 208,
+ 319, 193, 193, 0, 193, 193, 205, 195, 110, 0,
+ 28, 28, 305, 315, 306, 0, 258, 259, 265, 228,
+ 229, 208, 287, 0, 126, 37, 277, 281, 292, 209,
+ 94, 0, 85, 92, 98, 37, 123, 82, 75, 37,
+ 303, 284, 105, 0, 299, 296, 100, 0, 294, 286,
+ 0, 0, 0, 0, 0, 0, 318, 175, 178, 180,
+ 184, 187, 114, 112, 0, 0, 30, 313, 308, 288,
+ 37, 274, 282, 0, 28, 0, 105, 86, 91, 96,
+ 93, 36, 153, 76, 83, 297, 0, 28, 102, 101,
+ 208, 0, 319, 319, 319, 319, 319, 319, 193, 116,
+ 307, 316, 280, 208, 0, 99, 29, 88, 28, 0,
+ 150, 154, 28, 104, 300, 28, 285, 295, 320, 321,
+ 323, 324, 325, 322, 181, 293, 95, 87, 89, 0,
+ 0, 155, 156, 0, 309, 151, 298, 0, 29, 97,
+ 158, 0, 37, 0, 103, 90, 28, 157, 0, 80,
+ 132, 0, 129, 106, 130, 0, 152, 0, 0, 159,
+ 133, 131
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 94, 5, 6, 7, 27, 93, 8, 15, 72,
+ 95, 9, 10, 11, 12, 13, 56, 57, 73, 338,
+ 457, 431, 163, 319, 218, 164, 165, 166, 167, 168,
+ 169, 170, 171, 21, 172, 173, 70, 174, 321, 322,
+ 478, 368, 323, 324, 436, 468, 362, 363, 404, 438,
+ 375, 445, 376, 245, 175, 265, 340, 197, 266, 341,
+ 310, 311, 235, 306, 307, 308, 483, 484, 487, 23,
+ 90, 52, 24, 25, 176, 464, 465, 440, 441, 461,
+ 462, 476, 64, 116, 117, 118, 119, 139, 131, 132,
+ 331, 133, 332, 134, 428, 135, 334, 136, 335, 153,
+ 194, 261, 262, 263, 177, 178, 179, 257, 258, 259,
+ 317, 65, 86, 87, 88, 89, 220, 180, 181, 264,
+ 316, 403, 377, 378, 442, 417, 246, 325, 183, 345,
+ 200, 248, 271, 272, 396, 185, 330, 386, 189, 191
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -356
+static const yytype_int16 yypact[] =
+{
+ -356, 61, -356, 35, 83, -356, -356, -356, -356, -356,
+ -356, -356, -356, 12, 37, -9, -356, -356, -356, 21,
+ 469, 112, 100, 53, 118, 63, 36, 67, -356, -356,
+ -356, -356, -356, -356, -356, -356, -356, -356, -356, -356,
+ -356, -356, -356, -356, -356, -356, -356, -356, -356, -356,
+ -356, -356, -356, -356, -356, 9, -356, -356, 113, -356,
+ 153, 155, 207, 99, -356, -356, -356, 120, 231, 215,
+ 113, -356, -356, 218, -356, -356, 231, 209, -356, -356,
+ -22, 176, -356, -356, -356, -356, 244, -356, -356, 20,
+ 493, 113, -356, -356, -6, 247, -356, 253, -356, -356,
+ 489, -356, -356, 101, 99, 101, -356, -356, -356, -356,
+ -356, -356, -356, -356, -356, -356, 283, 493, -356, -356,
+ -356, 284, -356, -356, 276, 285, -356, -356, -356, -356,
+ -356, 281, 288, 289, 290, 292, 293, -356, -356, 23,
+ -356, -356, -356, 243, 364, 364, 366, 369, 372, -356,
+ 315, 316, -356, -356, 314, -356, -356, 306, 16, 380,
+ 156, 381, 87, -356, 385, -356, -356, -356, 277, 526,
+ -356, -356, 382, -356, -356, -356, 138, -356, 243, -356,
+ 337, 73, -356, 384, 409, 351, 352, 359, 369, 357,
+ 372, 358, -356, 243, 243, -356, -356, 46, 370, 419,
+ -356, -356, 379, 97, 164, -356, 374, 375, 388, 43,
+ -13, -21, 416, 418, 438, -31, 439, 440, 498, 451,
+ -356, 386, 36, 442, 434, -356, 287, 437, 91, 156,
+ 174, 174, 313, -356, 29, -356, -356, 68, -17, -356,
+ -356, -356, 494, 323, -356, -356, 214, -356, 443, -356,
+ -356, -356, 500, -356, -356, -356, -356, -356, 243, -356,
+ -356, -356, 243, -356, -356, -356, -356, -356, -356, 419,
+ 445, 465, -356, -356, -356, 470, -356, 471, -356, -356,
+ -356, -356, -356, -356, -356, -356, 432, -356, -356, -356,
+ -356, -356, -356, -356, -356, 137, 137, -356, 472, -356,
+ -356, 137, -356, -356, -356, -356, -356, 174, -356, -356,
+ 19, 137, 156, -356, -356, -356, 473, 474, -356, 135,
+ 410, 466, 516, 491, -356, -356, 474, -356, 22, -356,
+ 192, 243, 243, 468, 243, 243, -356, -356, -356, 490,
+ -356, -356, 465, -356, 419, 499, -356, -356, -356, -356,
+ -356, -356, 474, 25, -356, 156, -356, -356, -356, -356,
+ -356, 135, 10, 249, -356, 451, 174, -356, -356, 441,
+ -356, 474, 486, 8, -356, 280, -356, 256, -356, 474,
+ 551, 552, 553, 554, 555, 556, -356, -356, -356, -356,
+ -356, -356, -356, -356, 501, 506, -356, -356, -356, 474,
+ 156, -356, -356, 505, -356, 172, -356, -356, 135, -356,
+ -356, -356, 497, -356, -356, -356, 242, -356, -356, -356,
+ -356, 22, 192, 192, 192, 192, 192, 192, 243, -356,
+ -356, -356, -356, -356, 503, -356, -356, 510, -356, 36,
+ 528, -356, -356, -356, -356, -356, 474, -356, -356, -356,
+ -356, -356, -356, -356, -356, 474, -356, -356, -356, 507,
+ 508, -356, 512, 511, 384, -356, -356, 513, -356, -356,
+ -356, 36, 353, 117, -356, -356, -356, -356, 504, -356,
+ -356, 569, -356, -356, -356, 509, -356, 521, 520, -356,
+ -356, -356
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -356, 581, -356, -356, -356, -356, -356, -356, -356, -356,
+ 492, -356, -356, -356, -356, -356, 54, -356, 514, -260,
+ 114, -356, -133, -356, -223, -158, 563, 564, 566, -157,
+ -356, -16, 574, -356, -12, -26, -11, -356, -356, -356,
+ -356, -356, -356, -355, -356, -356, 181, 229, -356, -356,
+ 219, -356, 232, -356, -159, -356, -356, -356, -356, -356,
+ -180, 423, -216, -218, -356, 286, -356, -356, -356, -356,
+ -356, -356, -356, -356, -356, -356, -356, -356, -356, 124,
+ -356, -356, 360, -356, -356, -356, 479, -356, -356, -356,
+ -356, -356, -356, -356, -356, -356, -356, -356, -356, -356,
+ -356, -310, -356, 335, -356, -356, 421, -356, -356, 342,
+ -240, -356, -356, 132, 502, -41, -221, -356, -356, -131,
+ -356, -356, -356, 180, -356, -356, -356, -356, -356, 260,
+ -356, 139, 336, 263, -356, 459, -356, 47, 420, 422
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -276
+static const yytype_int16 yytable[] =
+{
+ 69, 22, 219, 301, 51, 326, 339, 226, 303, 233,
+ 232, 58, 182, 309, 414, 406, 67, 406, 314, 76,
+ 320, 387, 388, 198, 390, 391, 228, 80, 291, 372,
+ 149, 225, 228, 3, 4, 105, 228, 85, 285, 74,
+ 103, 286, 14, 67, 100, 292, 283, 182, 28, 120,
+ 19, 287, -17, 63, 355, 101, 68, 91, 284, 352,
+ 400, 2, 260, 106, 312, 370, 150, 151, 219, 407,
+ 74, 219, 68, 199, 373, 313, 120, 126, 85, 129,
+ 393, 394, 29, 318, 125, 219, 225, 371, 373, 379,
+ 16, 357, 374, 152, 67, 314, 26, 230, 231, 225,
+ 3, 4, 281, 364, -24, 267, 80, 55, 80, 75,
+ 268, 399, 282, 59, 81, 349, 350, 479, 454, 17,
+ 66, 353, 18, 68, 71, -24, 222, 260, -24, 74,
+ 98, 82, 83, 84, 402, 68, 223, 68, -24, 243,
+ 53, 54, 411, 244, 434, 364, 320, 410, 412, 76,
+ 195, 356, 227, 236, 219, 196, 274, 444, 275, 419,
+ 77, 238, 78, 365, 155, 156, 31, 32, 33, 34,
+ 35, 36, 37, 38, 480, -160, 481, 482, 459, 432,
+ 446, 74, 466, 80, 60, 467, 61, 62, 63, 410,
+ 304, 305, 364, 455, 401, 239, 298, 219, 240, 360,
+ 419, 361, 296, 230, 231, 230, 231, 219, 82, 83,
+ 84, 219, 68, 102, 79, 202, 485, 203, 204, 205,
+ 206, 107, 207, 276, 208, 209, 277, 210, 211, 212,
+ 213, 214, 215, 216, 217, 127, 409, 130, 67, 435,
+ 230, 231, 219, 380, 381, 382, 383, 384, 385, 320,
+ 154, 155, 156, 31, 32, 33, 34, 35, 157, 37,
+ 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
+ 158, -64, -64, 159, 327, 92, 99, 328, 160, 68,
+ 96, 19, 161, 162, 228, 155, 156, 31, 32, 33,
+ 34, 35, 36, 37, 38, 155, 156, 31, 32, 33,
+ 34, 35, 36, 37, 38, 122, 418, 104, 227, 443,
+ 230, 231, 229, 409, 219, 123, 420, 230, 231, 421,
+ -269, 155, 156, 31, 32, 33, 34, 35, 36, 37,
+ 38, 155, 156, 31, 32, 33, 34, 35, 36, 37,
+ 38, 137, 140, 141, 418, 230, 231, -275, 230, 231,
+ -275, 143, 142, -275, 144, 145, 146, -275, 147, 148,
+ -77, 155, 156, 31, 32, 33, 34, 35, 36, 37,
+ 38, 184, 187, 195, -107, 74, 188, -107, 196, 190,
+ -107, 230, 231, -270, -107, 192, 193, 201, 221, 237,
+ -77, 247, 67, 155, 156, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
+ 46, 47, 224, 460, 242, 159, 249, 67, 250, 251,
+ -79, 68, 252, 19, 254, 256, 270, 269, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 224, 273, 278,
+ 159, 300, 279, 297, 302, 460, 68, 280, 19, 155,
+ 156, 31, 32, 33, 34, 35, 36, 37, 38, 155,
+ 156, 31, 32, 33, 34, 35, 36, 37, 38, 448,
+ 449, 450, 451, 452, 453, 288, 30, 289, 413, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 124, 290, 293, 294,
+ 348, 228, 299, 329, 343, 295, 333, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 39, 40, 41, 42,
+ 43, 44, 45, 46, 47, 82, 83, 84, 344, 346,
+ 347, 358, 351, 366, 359, 389, 108, 109, 110, 111,
+ 112, 113, 114, 115, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 367, 369, 392, 415, 398, 422, 423,
+ 424, 425, 426, 427, 430, 433, 429, 439, 456, 458,
+ 463, 486, 469, 488, 470, 471, 489, 472, 474, 490,
+ 491, 1, 475, 48, 49, 121, 50, 20, 97, 437,
+ 405, 234, 416, 354, 408, 477, 138, 337, 315, 241,
+ 336, 447, 395, 473, 186, 342, 128, 397, 253, 0,
+ 0, 0, 255
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 26, 13, 160, 226, 20, 245, 266, 164, 229, 168,
+ 168, 22, 143, 231, 369, 7, 7, 7, 234, 36,
+ 243, 331, 332, 7, 334, 335, 7, 7, 59, 7,
+ 7, 164, 7, 39, 40, 15, 7, 63, 59, 61,
+ 81, 62, 7, 7, 66, 76, 59, 178, 57, 90,
+ 38, 72, 58, 70, 35, 81, 36, 68, 71, 299,
+ 35, 0, 193, 89, 35, 325, 43, 44, 226, 59,
+ 61, 229, 36, 57, 66, 234, 117, 103, 104, 105,
+ 340, 341, 61, 242, 100, 243, 219, 327, 66, 329,
+ 7, 312, 70, 70, 7, 311, 59, 68, 69, 232,
+ 39, 40, 59, 319, 36, 59, 7, 7, 7, 55,
+ 64, 351, 69, 60, 15, 295, 296, 472, 428, 36,
+ 57, 301, 39, 36, 57, 57, 39, 258, 60, 61,
+ 76, 32, 33, 34, 355, 36, 162, 36, 70, 66,
+ 28, 29, 365, 70, 404, 361, 369, 363, 366, 36,
+ 59, 310, 164, 169, 312, 64, 59, 417, 61, 375,
+ 7, 172, 7, 320, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 57, 57, 59, 60, 438, 400,
+ 420, 61, 442, 7, 66, 445, 68, 69, 70, 405,
+ 16, 17, 408, 433, 353, 57, 222, 355, 60, 64,
+ 416, 66, 218, 68, 69, 68, 69, 365, 32, 33,
+ 34, 369, 36, 81, 7, 59, 476, 61, 62, 63,
+ 64, 89, 66, 59, 68, 69, 62, 71, 72, 73,
+ 74, 75, 76, 77, 78, 103, 64, 105, 7, 67,
+ 68, 69, 400, 51, 52, 53, 54, 55, 56, 472,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 60, 60, 67, 63, 35, 36,
+ 62, 38, 39, 40, 7, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 8, 9, 10, 11, 12,
+ 13, 14, 15, 16, 17, 58, 64, 63, 320, 67,
+ 68, 69, 35, 64, 472, 62, 60, 68, 69, 63,
+ 77, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 58, 58, 67, 64, 68, 69, 60, 68, 69,
+ 63, 70, 67, 66, 66, 66, 66, 70, 66, 66,
+ 37, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 7, 6, 59, 60, 61, 7, 63, 64, 7,
+ 66, 68, 69, 77, 70, 70, 70, 7, 7, 7,
+ 67, 7, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 439, 77, 30, 7, 7, 67, 67,
+ 67, 36, 63, 38, 67, 67, 7, 57, 18, 19,
+ 20, 21, 22, 23, 24, 25, 26, 27, 59, 65,
+ 30, 7, 67, 57, 7, 471, 36, 59, 38, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16, 17, 422,
+ 423, 424, 425, 426, 427, 59, 7, 59, 37, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 7, 59, 59, 59,
+ 68, 7, 60, 60, 59, 7, 6, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 32, 33, 34, 63, 59,
+ 59, 58, 60, 67, 60, 67, 43, 44, 45, 46,
+ 47, 48, 49, 50, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 37, 63, 65, 70, 58, 7, 7,
+ 7, 7, 7, 7, 58, 60, 65, 70, 65, 59,
+ 42, 67, 65, 4, 66, 63, 67, 66, 65, 58,
+ 60, 0, 468, 20, 20, 93, 20, 13, 74, 408,
+ 361, 168, 373, 307, 362, 471, 117, 262, 238, 178,
+ 258, 421, 342, 464, 145, 269, 104, 344, 188, -1,
+ -1, -1, 190
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 80, 0, 39, 40, 81, 82, 83, 86, 90,
+ 91, 92, 93, 94, 7, 87, 7, 36, 39, 38,
+ 111, 112, 113, 148, 151, 152, 59, 84, 57, 61,
+ 7, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26, 105, 106,
+ 107, 110, 150, 28, 29, 7, 95, 96, 115, 60,
+ 66, 68, 69, 70, 161, 190, 57, 7, 36, 114,
+ 115, 57, 88, 97, 61, 95, 36, 7, 7, 7,
+ 7, 15, 32, 33, 34, 114, 191, 192, 193, 194,
+ 149, 115, 60, 85, 80, 89, 62, 97, 95, 67,
+ 66, 114, 192, 194, 63, 15, 114, 192, 43, 44,
+ 45, 46, 47, 48, 49, 50, 162, 163, 164, 165,
+ 194, 89, 58, 62, 7, 110, 114, 192, 193, 114,
+ 192, 167, 168, 170, 172, 174, 176, 58, 165, 166,
+ 58, 67, 67, 70, 66, 66, 66, 66, 66, 7,
+ 43, 44, 70, 178, 7, 8, 9, 15, 27, 30,
+ 35, 39, 40, 101, 104, 105, 106, 107, 108, 109,
+ 110, 111, 113, 114, 116, 133, 153, 183, 184, 185,
+ 196, 197, 198, 207, 7, 214, 214, 6, 7, 217,
+ 7, 218, 70, 70, 179, 59, 64, 136, 7, 57,
+ 209, 7, 59, 61, 62, 63, 64, 66, 68, 69,
+ 71, 72, 73, 74, 75, 76, 77, 78, 103, 104,
+ 195, 7, 39, 114, 27, 101, 108, 113, 7, 35,
+ 68, 69, 104, 133, 140, 141, 110, 7, 115, 57,
+ 60, 185, 77, 66, 70, 132, 205, 7, 210, 7,
+ 67, 67, 63, 217, 67, 218, 67, 186, 187, 188,
+ 198, 180, 181, 182, 198, 134, 137, 59, 64, 57,
+ 7, 211, 212, 59, 59, 61, 59, 62, 65, 67,
+ 59, 59, 69, 59, 71, 59, 62, 72, 59, 59,
+ 59, 59, 76, 59, 59, 7, 110, 57, 114, 60,
+ 7, 103, 7, 195, 16, 17, 142, 143, 144, 142,
+ 139, 140, 35, 133, 141, 161, 199, 189, 133, 102,
+ 103, 117, 118, 121, 122, 206, 189, 60, 63, 60,
+ 215, 169, 171, 6, 175, 177, 188, 182, 98, 98,
+ 135, 138, 211, 59, 63, 208, 59, 59, 68, 139,
+ 139, 60, 189, 139, 144, 35, 133, 195, 58, 60,
+ 64, 66, 125, 126, 141, 108, 67, 37, 120, 63,
+ 98, 189, 7, 66, 70, 129, 131, 201, 202, 189,
+ 51, 52, 53, 54, 55, 56, 216, 180, 180, 67,
+ 180, 180, 65, 98, 98, 208, 213, 212, 58, 189,
+ 35, 133, 195, 200, 127, 126, 7, 59, 131, 64,
+ 141, 103, 142, 37, 122, 70, 129, 204, 64, 141,
+ 60, 63, 7, 7, 7, 7, 7, 7, 173, 65,
+ 58, 100, 195, 60, 98, 67, 123, 125, 128, 70,
+ 156, 157, 203, 67, 98, 130, 189, 202, 216, 216,
+ 216, 216, 216, 216, 180, 189, 65, 99, 59, 98,
+ 114, 158, 159, 42, 154, 155, 98, 98, 124, 65,
+ 66, 63, 66, 210, 65, 99, 160, 158, 119, 122,
+ 57, 59, 60, 145, 146, 98, 67, 147, 4, 67,
+ 58, 60
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (!yyvaluep)
+ return;
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+ YYSTYPE *yyvsp;
+ int yyrule;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ );
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, Rule); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+#endif
+{
+ YYUSE (yyvaluep);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+/* Prevent warnings from -Wmissing-prototypes. */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far. */
+int yynerrs;
+
+
+
+/*-------------------------.
+| yyparse or yypush_parse. |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+
+
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ `yyss': related to states.
+ `yyvs': related to semantic values.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yytoken = 0;
+ yyss = yyssa;
+ yyvs = yyvsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+ yyssp = yyss;
+ yyvsp = yyvs;
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yystacksize);
+
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 11:
+
+/* Line 1455 of yacc.c */
+#line 824 "tqmoc.y"
+ { enterNameSpace((yyvsp[(2) - (2)].string)); }
+ break;
+
+ case 12:
+
+/* Line 1455 of yacc.c */
+#line 825 "tqmoc.y"
+ { BEGIN IN_NAMESPACE; }
+ break;
+
+ case 13:
+
+/* Line 1455 of yacc.c */
+#line 827 "tqmoc.y"
+ { leaveNameSpace();
+ selectOutsideClassState();
+ }
+ break;
+
+ case 14:
+
+/* Line 1455 of yacc.c */
+#line 832 "tqmoc.y"
+ { enterNameSpace(); }
+ break;
+
+ case 15:
+
+/* Line 1455 of yacc.c */
+#line 833 "tqmoc.y"
+ { BEGIN IN_NAMESPACE; }
+ break;
+
+ case 16:
+
+/* Line 1455 of yacc.c */
+#line 835 "tqmoc.y"
+ { leaveNameSpace();
+ selectOutsideClassState();
+ }
+ break;
+
+ case 18:
+
+/* Line 1455 of yacc.c */
+#line 844 "tqmoc.y"
+ { selectOutsideClassState(); }
+ break;
+
+ case 19:
+
+/* Line 1455 of yacc.c */
+#line 848 "tqmoc.y"
+ { selectOutsideClassState(); }
+ break;
+
+ case 20:
+
+/* Line 1455 of yacc.c */
+#line 851 "tqmoc.y"
+ { selectOutsideClassState(); }
+ break;
+
+ case 21:
+
+/* Line 1455 of yacc.c */
+#line 852 "tqmoc.y"
+ { selectOutsideClassState(); }
+ break;
+
+ case 22:
+
+/* Line 1455 of yacc.c */
+#line 855 "tqmoc.y"
+ { initClass(); }
+ break;
+
+ case 23:
+
+/* Line 1455 of yacc.c */
+#line 856 "tqmoc.y"
+ { generateClass();
+ registerClassInNamespace();
+ selectOutsideClassState(); }
+ break;
+
+ case 24:
+
+/* Line 1455 of yacc.c */
+#line 864 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 25:
+
+/* Line 1455 of yacc.c */
+#line 865 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 26:
+
+/* Line 1455 of yacc.c */
+#line 869 "tqmoc.y"
+ { g->tmpExpression = rmWS( g->tmpExpression );
+ (yyval.string) = stradd( (yyvsp[(1) - (4)].string), "<",
+ g->tmpExpression, ">" ); }
+ break;
+
+ case 27:
+
+/* Line 1455 of yacc.c */
+#line 880 "tqmoc.y"
+ { initExpression();
+ templLevel = 1;
+ BEGIN IN_TEMPL_ARGS; }
+ break;
+
+ case 28:
+
+/* Line 1455 of yacc.c */
+#line 893 "tqmoc.y"
+ { initExpression();
+ BEGIN IN_EXPR; }
+ break;
+
+ case 29:
+
+/* Line 1455 of yacc.c */
+#line 902 "tqmoc.y"
+ { BEGIN IN_DEF_ARG; }
+ break;
+
+ case 30:
+
+/* Line 1455 of yacc.c */
+#line 905 "tqmoc.y"
+ { initExpression();
+ BEGIN IN_ENUM; }
+ break;
+
+ case 31:
+
+/* Line 1455 of yacc.c */
+#line 911 "tqmoc.y"
+ { (yyval.string) = ""; }
+ break;
+
+ case 32:
+
+/* Line 1455 of yacc.c */
+#line 912 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 33:
+
+/* Line 1455 of yacc.c */
+#line 913 "tqmoc.y"
+ { (yyval.string) = ""; }
+ break;
+
+ case 34:
+
+/* Line 1455 of yacc.c */
+#line 914 "tqmoc.y"
+ { skipFunc = TRUE; (yyval.string) = ""; }
+ break;
+
+ case 35:
+
+/* Line 1455 of yacc.c */
+#line 915 "tqmoc.y"
+ { skipFunc = TRUE; (yyval.string) = ""; }
+ break;
+
+ case 36:
+
+/* Line 1455 of yacc.c */
+#line 919 "tqmoc.y"
+ { (yyval.string) = straddSpc((yyvsp[(1) - (3)].string),(yyvsp[(2) - (3)].string),(yyvsp[(3) - (3)].string)); }
+ break;
+
+ case 37:
+
+/* Line 1455 of yacc.c */
+#line 921 "tqmoc.y"
+ { (yyval.string) = ""; }
+ break;
+
+ case 38:
+
+/* Line 1455 of yacc.c */
+#line 922 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 39:
+
+/* Line 1455 of yacc.c */
+#line 925 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 40:
+
+/* Line 1455 of yacc.c */
+#line 926 "tqmoc.y"
+ { (yyval.string) = straddSpc((yyvsp[(1) - (2)].string),(yyvsp[(2) - (2)].string)); }
+ break;
+
+ case 43:
+
+/* Line 1455 of yacc.c */
+#line 931 "tqmoc.y"
+ { skipFunc = TRUE; }
+ break;
+
+ case 45:
+
+/* Line 1455 of yacc.c */
+#line 935 "tqmoc.y"
+ { }
+ break;
+
+ case 46:
+
+/* Line 1455 of yacc.c */
+#line 936 "tqmoc.y"
+ { }
+ break;
+
+ case 47:
+
+/* Line 1455 of yacc.c */
+#line 939 "tqmoc.y"
+ { (yyval.string) = "const"; }
+ break;
+
+ case 48:
+
+/* Line 1455 of yacc.c */
+#line 940 "tqmoc.y"
+ { (yyval.string) = "volatile"; }
+ break;
+
+ case 49:
+
+/* Line 1455 of yacc.c */
+#line 943 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 50:
+
+/* Line 1455 of yacc.c */
+#line 944 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 51:
+
+/* Line 1455 of yacc.c */
+#line 945 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 52:
+
+/* Line 1455 of yacc.c */
+#line 949 "tqmoc.y"
+ { (yyval.string) = straddSpc((yyvsp[(1) - (2)].string),(yyvsp[(2) - (2)].string)); }
+ break;
+
+ case 53:
+
+/* Line 1455 of yacc.c */
+#line 950 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 54:
+
+/* Line 1455 of yacc.c */
+#line 953 "tqmoc.y"
+ { (yyval.string) = "char"; }
+ break;
+
+ case 55:
+
+/* Line 1455 of yacc.c */
+#line 954 "tqmoc.y"
+ { (yyval.string) = "short"; }
+ break;
+
+ case 56:
+
+/* Line 1455 of yacc.c */
+#line 955 "tqmoc.y"
+ { (yyval.string) = "int"; }
+ break;
+
+ case 57:
+
+/* Line 1455 of yacc.c */
+#line 956 "tqmoc.y"
+ { (yyval.string) = "long"; }
+ break;
+
+ case 58:
+
+/* Line 1455 of yacc.c */
+#line 957 "tqmoc.y"
+ { (yyval.string) = "signed"; }
+ break;
+
+ case 59:
+
+/* Line 1455 of yacc.c */
+#line 958 "tqmoc.y"
+ { (yyval.string) = "unsigned"; }
+ break;
+
+ case 60:
+
+/* Line 1455 of yacc.c */
+#line 959 "tqmoc.y"
+ { (yyval.string) = "float"; }
+ break;
+
+ case 61:
+
+/* Line 1455 of yacc.c */
+#line 960 "tqmoc.y"
+ { (yyval.string) = "double"; }
+ break;
+
+ case 62:
+
+/* Line 1455 of yacc.c */
+#line 961 "tqmoc.y"
+ { (yyval.string) = "void"; }
+ break;
+
+ case 63:
+
+/* Line 1455 of yacc.c */
+#line 965 "tqmoc.y"
+ { g->tmpExpression = rmWS( g->tmpExpression );
+ (yyval.string) = stradd( "template<",
+ g->tmpExpression, ">" ); }
+ break;
+
+ case 65:
+
+/* Line 1455 of yacc.c */
+#line 971 "tqmoc.y"
+ { templateClassOld = templateClass;
+ templateClass = TRUE;
+ }
+ break;
+
+ case 66:
+
+/* Line 1455 of yacc.c */
+#line 977 "tqmoc.y"
+ { (yyval.string) = "class"; }
+ break;
+
+ case 67:
+
+/* Line 1455 of yacc.c */
+#line 978 "tqmoc.y"
+ { (yyval.string) = "struct"; }
+ break;
+
+ case 68:
+
+/* Line 1455 of yacc.c */
+#line 981 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 69:
+
+/* Line 1455 of yacc.c */
+#line 983 "tqmoc.y"
+ { (yyval.string) = stradd( "::", (yyvsp[(2) - (2)].string) ); }
+ break;
+
+ case 70:
+
+/* Line 1455 of yacc.c */
+#line 987 "tqmoc.y"
+ { (yyval.string) = stradd( (yyvsp[(1) - (3)].string), "::", (yyvsp[(3) - (3)].string) );}
+ break;
+
+ case 71:
+
+/* Line 1455 of yacc.c */
+#line 988 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 72:
+
+/* Line 1455 of yacc.c */
+#line 992 "tqmoc.y"
+ { (yyval.string) = straddSpc((yyvsp[(1) - (2)].string),(yyvsp[(2) - (2)].string)); }
+ break;
+
+ case 73:
+
+/* Line 1455 of yacc.c */
+#line 993 "tqmoc.y"
+ { (yyval.string) = stradd("enum ",(yyvsp[(2) - (2)].string)); }
+ break;
+
+ case 74:
+
+/* Line 1455 of yacc.c */
+#line 994 "tqmoc.y"
+ { (yyval.string) = stradd("union ",(yyvsp[(2) - (2)].string)); }
+ break;
+
+ case 75:
+
+/* Line 1455 of yacc.c */
+#line 999 "tqmoc.y"
+ { (yyval.arg_list) = (yyvsp[(1) - (2)].arg_list);}
+ break;
+
+ case 76:
+
+/* Line 1455 of yacc.c */
+#line 1000 "tqmoc.y"
+ { (yyval.arg_list) = (yyvsp[(1) - (3)].arg_list);
+ func_warn("Ellipsis not supported"
+ " in tqsignals and tqslots.\n"
+ "Ellipsis argument ignored."); }
+ break;
+
+ case 77:
+
+/* Line 1455 of yacc.c */
+#line 1006 "tqmoc.y"
+ { (yyval.arg_list) = tmpArgList; }
+ break;
+
+ case 78:
+
+/* Line 1455 of yacc.c */
+#line 1007 "tqmoc.y"
+ { (yyval.arg_list) = (yyvsp[(1) - (1)].arg_list); }
+ break;
+
+ case 79:
+
+/* Line 1455 of yacc.c */
+#line 1010 "tqmoc.y"
+ { (yyval.arg) = 0; }
+ break;
+
+ case 82:
+
+/* Line 1455 of yacc.c */
+#line 1015 "tqmoc.y"
+ { func_warn("Ellipsis not supported"
+ " in tqsignals and tqslots.\n"
+ "Ellipsis argument ignored."); }
+ break;
+
+ case 83:
+
+/* Line 1455 of yacc.c */
+#line 1023 "tqmoc.y"
+ { (yyval.arg_list) = addArg((yyvsp[(3) - (3)].arg)); }
+ break;
+
+ case 84:
+
+/* Line 1455 of yacc.c */
+#line 1024 "tqmoc.y"
+ { (yyval.arg_list) = addArg((yyvsp[(1) - (1)].arg)); }
+ break;
+
+ case 85:
+
+/* Line 1455 of yacc.c */
+#line 1028 "tqmoc.y"
+ { (yyval.arg) = new Argument(straddSpc((yyvsp[(1) - (2)].string),(yyvsp[(2) - (2)].string)),""); }
+ break;
+
+ case 86:
+
+/* Line 1455 of yacc.c */
+#line 1030 "tqmoc.y"
+ { expLevel = 1; }
+ break;
+
+ case 87:
+
+/* Line 1455 of yacc.c */
+#line 1032 "tqmoc.y"
+ { (yyval.arg) = new Argument(straddSpc((yyvsp[(1) - (5)].string),(yyvsp[(2) - (5)].string)),"", 0, TRUE ); }
+ break;
+
+ case 88:
+
+/* Line 1455 of yacc.c */
+#line 1035 "tqmoc.y"
+ { (yyval.arg) = new Argument(straddSpc((yyvsp[(1) - (4)].string),(yyvsp[(2) - (4)].string)),(yyvsp[(4) - (4)].string), (yyvsp[(3) - (4)].string)); }
+ break;
+
+ case 89:
+
+/* Line 1455 of yacc.c */
+#line 1038 "tqmoc.y"
+ { expLevel = 1; }
+ break;
+
+ case 90:
+
+/* Line 1455 of yacc.c */
+#line 1040 "tqmoc.y"
+ { (yyval.arg) = new Argument(straddSpc((yyvsp[(1) - (7)].string),(yyvsp[(2) - (7)].string)),(yyvsp[(4) - (7)].string), (yyvsp[(3) - (7)].string), TRUE); }
+ break;
+
+ case 91:
+
+/* Line 1455 of yacc.c */
+#line 1044 "tqmoc.y"
+ { (yyval.string) = ""; }
+ break;
+
+ case 92:
+
+/* Line 1455 of yacc.c */
+#line 1045 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 93:
+
+/* Line 1455 of yacc.c */
+#line 1049 "tqmoc.y"
+ { (yyval.string) = straddSpc((yyvsp[(1) - (2)].string),(yyvsp[(2) - (2)].string)); }
+ break;
+
+ case 94:
+
+/* Line 1455 of yacc.c */
+#line 1050 "tqmoc.y"
+ { expLevel = 1; }
+ break;
+
+ case 95:
+
+/* Line 1455 of yacc.c */
+#line 1052 "tqmoc.y"
+ { (yyval.string) = stradd( "[",
+ g->tmpExpression =
+ g->tmpExpression.stripWhiteSpace(), "]" ); }
+ break;
+
+ case 96:
+
+/* Line 1455 of yacc.c */
+#line 1055 "tqmoc.y"
+ { expLevel = 1; }
+ break;
+
+ case 97:
+
+/* Line 1455 of yacc.c */
+#line 1057 "tqmoc.y"
+ { (yyval.string) = stradd( (yyvsp[(1) - (5)].string),"[",
+ g->tmpExpression =
+ g->tmpExpression.stripWhiteSpace(),"]" ); }
+ break;
+
+ case 98:
+
+/* Line 1455 of yacc.c */
+#line 1060 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 99:
+
+/* Line 1455 of yacc.c */
+#line 1061 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(2) - (3)].string); }
+ break;
+
+ case 100:
+
+/* Line 1455 of yacc.c */
+#line 1064 "tqmoc.y"
+ { (yyval.string) = ""; }
+ break;
+
+ case 101:
+
+/* Line 1455 of yacc.c */
+#line 1066 "tqmoc.y"
+ { (yyval.string) = straddSpc((yyvsp[(1) - (2)].string),(yyvsp[(2) - (2)].string));}
+ break;
+
+ case 102:
+
+/* Line 1455 of yacc.c */
+#line 1067 "tqmoc.y"
+ { expLevel = 1; }
+ break;
+
+ case 103:
+
+/* Line 1455 of yacc.c */
+#line 1069 "tqmoc.y"
+ { (yyval.string) = stradd( (yyvsp[(1) - (5)].string),"[",
+ g->tmpExpression =
+ g->tmpExpression.stripWhiteSpace(),"]" ); }
+ break;
+
+ case 104:
+
+/* Line 1455 of yacc.c */
+#line 1072 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(2) - (3)].string); }
+ break;
+
+ case 106:
+
+/* Line 1455 of yacc.c */
+#line 1086 "tqmoc.y"
+ { tmpFunc->args = (yyvsp[(2) - (8)].arg_list);
+ tmpFunc->qualifier = (yyvsp[(4) - (8)].string); }
+ break;
+
+ case 108:
+
+/* Line 1455 of yacc.c */
+#line 1092 "tqmoc.y"
+ { func_warn("Variable as signal or slot."); }
+ break;
+
+ case 109:
+
+/* Line 1455 of yacc.c */
+#line 1093 "tqmoc.y"
+ { expLevel=0; }
+ break;
+
+ case 110:
+
+/* Line 1455 of yacc.c */
+#line 1095 "tqmoc.y"
+ { skipFunc = TRUE; }
+ break;
+
+ case 111:
+
+/* Line 1455 of yacc.c */
+#line 1096 "tqmoc.y"
+ { expLevel=0; }
+ break;
+
+ case 112:
+
+/* Line 1455 of yacc.c */
+#line 1098 "tqmoc.y"
+ { skipFunc = TRUE; }
+ break;
+
+ case 113:
+
+/* Line 1455 of yacc.c */
+#line 1102 "tqmoc.y"
+ { expLevel = 1; }
+ break;
+
+ case 115:
+
+/* Line 1455 of yacc.c */
+#line 1104 "tqmoc.y"
+ { expLevel = 1; }
+ break;
+
+ case 117:
+
+/* Line 1455 of yacc.c */
+#line 1109 "tqmoc.y"
+ { (yyval.string) = ""; }
+ break;
+
+ case 118:
+
+/* Line 1455 of yacc.c */
+#line 1110 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 119:
+
+/* Line 1455 of yacc.c */
+#line 1113 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 120:
+
+/* Line 1455 of yacc.c */
+#line 1114 "tqmoc.y"
+ { (yyval.string) = straddSpc((yyvsp[(1) - (2)].string),(yyvsp[(2) - (2)].string));}
+ break;
+
+ case 121:
+
+/* Line 1455 of yacc.c */
+#line 1117 "tqmoc.y"
+ { (yyval.string) = straddSpc("*",(yyvsp[(2) - (2)].string));}
+ break;
+
+ case 122:
+
+/* Line 1455 of yacc.c */
+#line 1118 "tqmoc.y"
+ { (yyval.string) = stradd("&",(yyvsp[(2) - (2)].string));}
+ break;
+
+ case 123:
+
+/* Line 1455 of yacc.c */
+#line 1125 "tqmoc.y"
+ { (yyval.string) = ""; }
+ break;
+
+ case 124:
+
+/* Line 1455 of yacc.c */
+#line 1126 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 125:
+
+/* Line 1455 of yacc.c */
+#line 1129 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 126:
+
+/* Line 1455 of yacc.c */
+#line 1131 "tqmoc.y"
+ { (yyval.string) = straddSpc((yyvsp[(1) - (2)].string),(yyvsp[(2) - (2)].string)); }
+ break;
+
+ case 127:
+
+/* Line 1455 of yacc.c */
+#line 1134 "tqmoc.y"
+ { (yyval.string) = "const"; }
+ break;
+
+ case 128:
+
+/* Line 1455 of yacc.c */
+#line 1135 "tqmoc.y"
+ { (yyval.string) = "volatile"; }
+ break;
+
+ case 132:
+
+/* Line 1455 of yacc.c */
+#line 1143 "tqmoc.y"
+ { BEGIN IN_FCT; fctLevel = 1;}
+ break;
+
+ case 133:
+
+/* Line 1455 of yacc.c */
+#line 1144 "tqmoc.y"
+ { BEGIN TQT_DEF; }
+ break;
+
+ case 134:
+
+/* Line 1455 of yacc.c */
+#line 1151 "tqmoc.y"
+ { BEGIN IN_CLASS;
+ classPLevel = 1;
+ }
+ break;
+
+ case 135:
+
+/* Line 1455 of yacc.c */
+#line 1155 "tqmoc.y"
+ { BEGIN TQT_DEF; }
+ break;
+
+ case 136:
+
+/* Line 1455 of yacc.c */
+#line 1156 "tqmoc.y"
+ { BEGIN TQT_DEF; /* -- " -- */
+ skipClass = TRUE; }
+ break;
+
+ case 137:
+
+/* Line 1455 of yacc.c */
+#line 1158 "tqmoc.y"
+ { BEGIN TQT_DEF; /* -- " -- */
+ skipClass = TRUE; }
+ break;
+
+ case 138:
+
+/* Line 1455 of yacc.c */
+#line 1160 "tqmoc.y"
+ { BEGIN TQT_DEF; /* -- " -- */
+ skipClass = TRUE; }
+ break;
+
+ case 139:
+
+/* Line 1455 of yacc.c */
+#line 1164 "tqmoc.y"
+ { BEGIN TQT_DEF; /* catch ';' */
+ skipClass = TRUE; }
+ break;
+
+ case 140:
+
+/* Line 1455 of yacc.c */
+#line 1166 "tqmoc.y"
+ { skipClass = TRUE;
+ BEGIN GIMME_SEMICOLON; }
+ break;
+
+ case 144:
+
+/* Line 1455 of yacc.c */
+#line 1173 "tqmoc.y"
+ { (yyval.string) = ""; }
+ break;
+
+ case 146:
+
+/* Line 1455 of yacc.c */
+#line 1179 "tqmoc.y"
+ { g->className = (yyvsp[(2) - (2)].string);
+ fprintf( stderr, "FOUND CLASS [1]: %s\n", (const char*)g->className );
+ if ( g->className == "TQObject" )
+ TQ_OBJECTdetected = TRUE;
+ }
+ break;
+
+ case 147:
+
+/* Line 1455 of yacc.c */
+#line 1186 "tqmoc.y"
+ { g->className = (yyvsp[(3) - (3)].string);
+ fprintf( stderr, "FOUND CLASS [2]: %s\n", (const char*)g->className );
+ if ( g->className == "TQObject" )
+ TQ_OBJECTdetected = TRUE;
+ }
+ break;
+
+ case 148:
+
+/* Line 1455 of yacc.c */
+#line 1194 "tqmoc.y"
+ { g->superClassName = (yyvsp[(2) - (2)].string); }
+ break;
+
+ case 149:
+
+/* Line 1455 of yacc.c */
+#line 1199 "tqmoc.y"
+ { templateClass = templateClassOld; }
+ break;
+
+ case 158:
+
+/* Line 1455 of yacc.c */
+#line 1222 "tqmoc.y"
+ { expLevel = 1; }
+ break;
+
+ case 160:
+
+/* Line 1455 of yacc.c */
+#line 1227 "tqmoc.y"
+ { (yyval.string) = 0; }
+ break;
+
+ case 161:
+
+/* Line 1455 of yacc.c */
+#line 1228 "tqmoc.y"
+ { (yyval.string) = (yyvsp[(1) - (1)].string); }
+ break;
+
+ case 166:
+
+/* Line 1455 of yacc.c */
+#line 1240 "tqmoc.y"
+ { tmpAccess = (yyvsp[(1) - (1)].access); }
+ break;
+
+ case 167:
+
+/* Line 1455 of yacc.c */
+#line 1241 "tqmoc.y"
+ { tqmoc_err( "Missing access specifier"
+ " before \"tqslots:\"." ); }
+ break;
+
+ case 168:
+
+/* Line 1455 of yacc.c */
+#line 1245 "tqmoc.y"
+ { BEGIN TQT_DEF; }
+ break;
+
+ case 170:
+
+/* Line 1455 of yacc.c */
+#line 1247 "tqmoc.y"
+ { BEGIN TQT_DEF; }
+ break;
+
+ case 172:
+
+/* Line 1455 of yacc.c */
+#line 1249 "tqmoc.y"
+ {
+ if ( tmpAccess )
+ tqmoc_warn("TQ_OBJECT is not in the private"
+ " section of the class.\n"
+ "TQ_OBJECT is a macro that resets"
+ " access permission to \"private\".");
+ TQ_OBJECTdetected = TRUE;
+ }
+ break;
+
+ case 173:
+
+/* Line 1455 of yacc.c */
+#line 1257 "tqmoc.y"
+ { tmpYYStart = YY_START;
+ tmpPropOverride = FALSE;
+ BEGIN IN_PROPERTY; }
+ break;
+
+ case 174:
+
+/* Line 1455 of yacc.c */
+#line 1260 "tqmoc.y"
+ {
+ BEGIN tmpYYStart;
+ }
+ break;
+
+ case 176:
+
+/* Line 1455 of yacc.c */
+#line 1264 "tqmoc.y"
+ { tmpYYStart = YY_START;
+ tmpPropOverride = TRUE;
+ BEGIN IN_PROPERTY; }
+ break;
+
+ case 177:
+
+/* Line 1455 of yacc.c */
+#line 1267 "tqmoc.y"
+ {
+ BEGIN tmpYYStart;
+ }
+ break;
+
+ case 179:
+
+/* Line 1455 of yacc.c */
+#line 1271 "tqmoc.y"
+ { tmpYYStart = YY_START; BEGIN IN_CLASSINFO; }
+ break;
+
+ case 180:
+
+/* Line 1455 of yacc.c */
+#line 1273 "tqmoc.y"
+ {
+ g->infos.append( new ClassInfo( (yyvsp[(4) - (7)].string), (yyvsp[(6) - (7)].string) ) );
+ BEGIN tmpYYStart;
+ }
+ break;
+
+ case 182:
+
+/* Line 1455 of yacc.c */
+#line 1278 "tqmoc.y"
+ { tmpYYStart = YY_START; BEGIN IN_PROPERTY; }
+ break;
+
+ case 183:
+
+/* Line 1455 of yacc.c */
+#line 1279 "tqmoc.y"
+ {
+ Q_PROPERTYdetected = TRUE;
+ BEGIN tmpYYStart;
+ }
+ break;
+
+ case 185:
+
+/* Line 1455 of yacc.c */
+#line 1284 "tqmoc.y"
+ { tmpYYStart = YY_START; BEGIN IN_PROPERTY; }
+ break;
+
+ case 186:
+
+/* Line 1455 of yacc.c */
+#line 1285 "tqmoc.y"
+ {
+ Q_PROPERTYdetected = TRUE;
+ BEGIN tmpYYStart;
+ }
+ break;
+
+ case 188:
+
+/* Line 1455 of yacc.c */
+#line 1292 "tqmoc.y"
+ { tqmoc_err( "Signals cannot "
+ "have access specifiers" ); }
+ break;
+
+ case 190:
+
+/* Line 1455 of yacc.c */
+#line 1295 "tqmoc.y"
+ { if ( tmpAccess == Public && Q_PROPERTYdetected )
+ BEGIN TQT_DEF;
+ else
+ BEGIN IN_CLASS;
+ suppress_func_warn = TRUE;
+ }
+ break;
+
+ case 191:
+
+/* Line 1455 of yacc.c */
+#line 1302 "tqmoc.y"
+ {
+ suppress_func_warn = FALSE;
+ }
+ break;
+
+ case 192:
+
+/* Line 1455 of yacc.c */
+#line 1305 "tqmoc.y"
+ { BEGIN IN_CLASS;
+ if ( classPLevel != 1 )
+ tqmoc_warn( "unexpected access"
+ "specifier" );
+ }
+ break;
+
+ case 197:
+
+/* Line 1455 of yacc.c */
+#line 1320 "tqmoc.y"
+ { addMember( PropertyCandidateMember ); }
+ break;
+
+ case 202:
+
+/* Line 1455 of yacc.c */
+#line 1332 "tqmoc.y"
+ { addMember( SignalMember ); }
+ break;
+
+ case 207:
+
+/* Line 1455 of yacc.c */
+#line 1343 "tqmoc.y"
+ { addMember( SlotMember ); }
+ break;
+
+ case 210:
+
+/* Line 1455 of yacc.c */
+#line 1350 "tqmoc.y"
+ { (yyval.string)=(yyvsp[(2) - (2)].string); }
+ break;
+
+ case 211:
+
+/* Line 1455 of yacc.c */
+#line 1353 "tqmoc.y"
+ { g->multipleSuperClasses.append( (yyvsp[(3) - (3)].string) ); }
+ break;
+
+ case 213:
+
+/* Line 1455 of yacc.c */
+#line 1358 "tqmoc.y"
+ { (yyval.string) = stradd( (yyvsp[(1) - (4)].string), "(", (yyvsp[(3) - (4)].string), ")" ); }
+ break;
+
+ case 214:
+
+/* Line 1455 of yacc.c */
+#line 1360 "tqmoc.y"
+ { (yyval.string) = stradd( (yyvsp[(1) - (4)].string), "(", (yyvsp[(3) - (4)].string), ")" ); }
+ break;
+
+ case 215:
+
+/* Line 1455 of yacc.c */
+#line 1363 "tqmoc.y"
+ {(yyval.string)=(yyvsp[(1) - (1)].string);}
+ break;
+
+ case 216:
+
+/* Line 1455 of yacc.c */
+#line 1364 "tqmoc.y"
+ {(yyval.string)=(yyvsp[(3) - (3)].string);}
+ break;
+
+ case 217:
+
+/* Line 1455 of yacc.c */
+#line 1365 "tqmoc.y"
+ {(yyval.string)=(yyvsp[(2) - (2)].string);}
+ break;
+
+ case 218:
+
+/* Line 1455 of yacc.c */
+#line 1366 "tqmoc.y"
+ {(yyval.string)=(yyvsp[(3) - (3)].string);}
+ break;
+
+ case 219:
+
+/* Line 1455 of yacc.c */
+#line 1367 "tqmoc.y"
+ {(yyval.string)=(yyvsp[(2) - (2)].string);}
+ break;
+
+ case 220:
+
+/* Line 1455 of yacc.c */
+#line 1368 "tqmoc.y"
+ {(yyval.string)=(yyvsp[(1) - (1)].string);}
+ break;
+
+ case 221:
+
+/* Line 1455 of yacc.c */
+#line 1369 "tqmoc.y"
+ {(yyval.string)=(yyvsp[(3) - (3)].string);}
+ break;
+
+ case 222:
+
+/* Line 1455 of yacc.c */
+#line 1370 "tqmoc.y"
+ {(yyval.string)=(yyvsp[(2) - (2)].string);}
+ break;
+
+ case 223:
+
+/* Line 1455 of yacc.c */
+#line 1371 "tqmoc.y"
+ {(yyval.string)=(yyvsp[(3) - (3)].string);}
+ break;
+
+ case 224:
+
+/* Line 1455 of yacc.c */
+#line 1372 "tqmoc.y"
+ {(yyval.string)=(yyvsp[(2) - (2)].string);}
+ break;
+
+ case 225:
+
+/* Line 1455 of yacc.c */
+#line 1375 "tqmoc.y"
+ { (yyval.access)=Private; }
+ break;
+
+ case 226:
+
+/* Line 1455 of yacc.c */
+#line 1376 "tqmoc.y"
+ { (yyval.access)=Protected; }
+ break;
+
+ case 227:
+
+/* Line 1455 of yacc.c */
+#line 1377 "tqmoc.y"
+ { (yyval.access)=Public; }
+ break;
+
+ case 228:
+
+/* Line 1455 of yacc.c */
+#line 1380 "tqmoc.y"
+ { }
+ break;
+
+ case 229:
+
+/* Line 1455 of yacc.c */
+#line 1381 "tqmoc.y"
+ { }
+ break;
+
+ case 271:
+
+/* Line 1455 of yacc.c */
+#line 1429 "tqmoc.y"
+ { tmpFunc->type = (yyvsp[(1) - (2)].string);
+ tmpFunc->name = (yyvsp[(2) - (2)].string); }
+ break;
+
+ case 272:
+
+/* Line 1455 of yacc.c */
+#line 1432 "tqmoc.y"
+ { tmpFunc->type = "int";
+ tmpFunc->name = (yyvsp[(1) - (1)].string);
+ if ( tmpFunc->name == g->className )
+ func_warn( "Constructors cannot be"
+ " tqsignals or tqslots.");
+ }
+ break;
+
+ case 273:
+
+/* Line 1455 of yacc.c */
+#line 1439 "tqmoc.y"
+ { tmpFunc->type = "void";
+ tmpFunc->name = "~";
+ tmpFunc->name += (yyvsp[(3) - (3)].string);
+ func_warn( "Destructors cannot be"
+ " tqsignals or tqslots.");
+ }
+ break;
+
+ case 274:
+
+/* Line 1455 of yacc.c */
+#line 1447 "tqmoc.y"
+ {
+ char *tmp =
+ straddSpc((yyvsp[(1) - (5)].string),(yyvsp[(2) - (5)].string),(yyvsp[(3) - (5)].string),(yyvsp[(4) - (5)].string));
+ tmpFunc->type = rmWS(tmp);
+ delete [] tmp;
+ tmpFunc->name = (yyvsp[(5) - (5)].string); }
+ break;
+
+ case 275:
+
+/* Line 1455 of yacc.c */
+#line 1454 "tqmoc.y"
+ { skipFunc = TRUE; }
+ break;
+
+ case 276:
+
+/* Line 1455 of yacc.c */
+#line 1456 "tqmoc.y"
+ { tmpFunc->type =
+ straddSpc((yyvsp[(1) - (3)].string),(yyvsp[(2) - (3)].string));
+ tmpFunc->name = (yyvsp[(3) - (3)].string); }
+ break;
+
+ case 277:
+
+/* Line 1455 of yacc.c */
+#line 1461 "tqmoc.y"
+ { tmpFunc->type =
+ straddSpc((yyvsp[(1) - (4)].string),(yyvsp[(2) - (4)].string),(yyvsp[(3) - (4)].string));
+ tmpFunc->name = (yyvsp[(4) - (4)].string); }
+ break;
+
+ case 278:
+
+/* Line 1455 of yacc.c */
+#line 1465 "tqmoc.y"
+ { operatorError(); }
+ break;
+
+ case 279:
+
+/* Line 1455 of yacc.c */
+#line 1467 "tqmoc.y"
+ { operatorError(); }
+ break;
+
+ case 280:
+
+/* Line 1455 of yacc.c */
+#line 1470 "tqmoc.y"
+ { operatorError(); }
+ break;
+
+ case 281:
+
+/* Line 1455 of yacc.c */
+#line 1472 "tqmoc.y"
+ { operatorError(); }
+ break;
+
+ case 282:
+
+/* Line 1455 of yacc.c */
+#line 1475 "tqmoc.y"
+ { operatorError(); }
+ break;
+
+ case 284:
+
+/* Line 1455 of yacc.c */
+#line 1481 "tqmoc.y"
+ { func_warn("Unexpected variable declaration."); }
+ break;
+
+ case 285:
+
+/* Line 1455 of yacc.c */
+#line 1484 "tqmoc.y"
+ { func_warn("Unexpected variable declaration."); }
+ break;
+
+ case 286:
+
+/* Line 1455 of yacc.c */
+#line 1486 "tqmoc.y"
+ { func_warn("Unexpected enum declaration."); }
+ break;
+
+ case 287:
+
+/* Line 1455 of yacc.c */
+#line 1488 "tqmoc.y"
+ { func_warn("Unexpected using declaration."); }
+ break;
+
+ case 288:
+
+/* Line 1455 of yacc.c */
+#line 1490 "tqmoc.y"
+ { func_warn("Unexpected using declaration."); }
+ break;
+
+ case 289:
+
+/* Line 1455 of yacc.c */
+#line 1492 "tqmoc.y"
+ { classPLevel++;
+ tqmoc_err("Unexpected namespace declaration."); }
+ break;
+
+ case 290:
+
+/* Line 1455 of yacc.c */
+#line 1495 "tqmoc.y"
+ { func_warn("Unexpected class declaration.");}
+ break;
+
+ case 291:
+
+/* Line 1455 of yacc.c */
+#line 1497 "tqmoc.y"
+ { func_warn("Unexpected class declaration.");
+ BEGIN IN_FCT; fctLevel=1;
+ }
+ break;
+
+ case 292:
+
+/* Line 1455 of yacc.c */
+#line 1500 "tqmoc.y"
+ { BEGIN TQT_DEF; }
+ break;
+
+ case 296:
+
+/* Line 1455 of yacc.c */
+#line 1509 "tqmoc.y"
+ { }
+ break;
+
+ case 297:
+
+/* Line 1455 of yacc.c */
+#line 1510 "tqmoc.y"
+ { expLevel = 0; }
+ break;
+
+ case 299:
+
+/* Line 1455 of yacc.c */
+#line 1512 "tqmoc.y"
+ { expLevel = 0; }
+ break;
+
+ case 302:
+
+/* Line 1455 of yacc.c */
+#line 1517 "tqmoc.y"
+ { expLevel = 0; }
+ break;
+
+ case 307:
+
+/* Line 1455 of yacc.c */
+#line 1532 "tqmoc.y"
+ { BEGIN TQT_DEF;
+ if ( tmpAccess == Public) {
+ tmpEnum->name = (yyvsp[(1) - (5)].string);
+ addEnum();
+ }
+ }
+ break;
+
+ case 308:
+
+/* Line 1455 of yacc.c */
+#line 1539 "tqmoc.y"
+ { tmpEnum->clear();}
+ break;
+
+ case 310:
+
+/* Line 1455 of yacc.c */
+#line 1543 "tqmoc.y"
+ { }
+ break;
+
+ case 314:
+
+/* Line 1455 of yacc.c */
+#line 1551 "tqmoc.y"
+ { if ( tmpAccess == Public) tmpEnum->append( (yyvsp[(1) - (1)].string) ); }
+ break;
+
+ case 315:
+
+/* Line 1455 of yacc.c */
+#line 1552 "tqmoc.y"
+ { enumLevel=0; }
+ break;
+
+ case 316:
+
+/* Line 1455 of yacc.c */
+#line 1553 "tqmoc.y"
+ { if ( tmpAccess == Public) tmpEnum->append( (yyvsp[(1) - (4)].string) ); }
+ break;
+
+ case 317:
+
+/* Line 1455 of yacc.c */
+#line 1557 "tqmoc.y"
+ {
+ g->propWrite = "";
+ g->propRead = "";
+ g->propOverride = tmpPropOverride;
+ g->propReset = "";
+ if ( g->propOverride ) {
+ g->propStored = "";
+ g->propDesignable = "";
+ g->propScriptable = "";
+ } else {
+ g->propStored = "true";
+ g->propDesignable = "true";
+ g->propScriptable = "true";
+ }
+ }
+ break;
+
+ case 318:
+
+/* Line 1455 of yacc.c */
+#line 1573 "tqmoc.y"
+ {
+ if ( g->propRead.isEmpty() && !g->propOverride )
+ tqmoc_err( "A property must at least feature a read method." );
+ checkPropertyName( (yyvsp[(2) - (4)].string) );
+ Q_PROPERTYdetected = TRUE;
+ // Avoid duplicates
+ for( TQPtrListIterator<Property> lit( g->props ); lit.current(); ++lit ) {
+ if ( lit.current()->name == (yyvsp[(2) - (4)].string) ) {
+ if ( displayWarnings )
+ tqmoc_err( "Property '%s' defined twice.",
+ (const char*)lit.current()->name );
+ }
+ }
+ g->props.append( new Property( lineNo, (yyvsp[(1) - (4)].string), (yyvsp[(2) - (4)].string),
+ g->propWrite, g->propRead, g->propReset,
+ g->propStored, g->propDesignable,
+ g->propScriptable, g->propOverride ) );
+ }
+ break;
+
+ case 320:
+
+/* Line 1455 of yacc.c */
+#line 1594 "tqmoc.y"
+ { g->propRead = (yyvsp[(2) - (3)].string); }
+ break;
+
+ case 321:
+
+/* Line 1455 of yacc.c */
+#line 1595 "tqmoc.y"
+ { g->propWrite = (yyvsp[(2) - (3)].string); }
+ break;
+
+ case 322:
+
+/* Line 1455 of yacc.c */
+#line 1596 "tqmoc.y"
+ { g->propReset = (yyvsp[(2) - (3)].string); }
+ break;
+
+ case 323:
+
+/* Line 1455 of yacc.c */
+#line 1597 "tqmoc.y"
+ { g->propStored = (yyvsp[(2) - (3)].string); }
+ break;
+
+ case 324:
+
+/* Line 1455 of yacc.c */
+#line 1598 "tqmoc.y"
+ { g->propDesignable = (yyvsp[(2) - (3)].string); }
+ break;
+
+ case 325:
+
+/* Line 1455 of yacc.c */
+#line 1599 "tqmoc.y"
+ { g->propScriptable = (yyvsp[(2) - (3)].string); }
+ break;
+
+ case 326:
+
+/* Line 1455 of yacc.c */
+#line 1602 "tqmoc.y"
+ { }
+ break;
+
+ case 327:
+
+/* Line 1455 of yacc.c */
+#line 1603 "tqmoc.y"
+ { g->qtEnums.append( (yyvsp[(1) - (2)].string) ); }
+ break;
+
+ case 328:
+
+/* Line 1455 of yacc.c */
+#line 1606 "tqmoc.y"
+ { }
+ break;
+
+ case 329:
+
+/* Line 1455 of yacc.c */
+#line 1607 "tqmoc.y"
+ { g->qtSets.append( (yyvsp[(1) - (2)].string) ); }
+ break;
+
+
+
+/* Line 1455 of yacc.c */
+#line 4224 "tqmoc_yacc.cpp"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ *++yyvsp = yylval;
+
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+
+/* Line 1675 of yacc.c */
+#line 1610 "tqmoc.y"
+
+
+#ifndef YYBISON
+# if defined(TQ_OS_WIN32)
+# include <io.h>
+# undef isatty
+extern "C" int hack_isatty( int )
+{
+ return 0;
+}
+# define isatty hack_isatty
+# else
+# include <unistd.h>
+# endif
+# include "tqmoc_lex.cpp"
+#endif //YYBISON
+
+void cleanup();
+TQCString combinePath( const char *, const char * );
+
+FILE *out; // output file
+
+parser_reg::parser_reg() : funcs(TRUE)
+{
+ gen_count = 0;
+ noInclude = FALSE; // no #include <filename>
+ generatedCode = FALSE; // no code generated
+ tqmocError = FALSE; // tqmoc parsing error occurred
+ hasVariantIncluded = FALSE;
+}
+
+
+parser_reg::~parser_reg()
+{
+ tqslots.clear();
+ tqsignals.clear();
+ propfuncs.clear();
+ funcs.clear();
+ infos.clear();
+ props.clear();
+ infos.clear();
+}
+
+int yyparse();
+
+void tqreplace( char *s, char c1, char c2 );
+
+void setDefaultIncludeFile()
+{
+ if ( g->includeFiles.isEmpty() ) {
+ if ( g->includePath.isEmpty() ) {
+ if ( !g->fileName.isEmpty() && !g->outputFile.isEmpty() ) {
+ g->includeFiles.append( combinePath(g->fileName, g->outputFile) );
+ } else {
+ g->includeFiles.append( g->fileName );
+ }
+ } else {
+ g->includeFiles.append( combinePath(g->fileName, g->fileName) );
+ }
+ }
+}
+
+#ifdef TQ_CC_MSVC
+#define ErrorFormatString "%s(%d):"
+#else
+#define ErrorFormatString "%s:%d:"
+#endif
+
+#ifndef TQMOC_MWERKS_PLUGIN
+int main( int argc, char **argv )
+{
+ init();
+
+ bool autoInclude = TRUE;
+ const char *error = 0;
+ g->qtPath = "";
+ for ( int n=1; n<argc && error==0; n++ ) {
+ TQCString arg = argv[n];
+ if ( arg[0] == '-' ) { // option
+ TQCString opt = arg.tqstringFromPos(1);
+ if ( opt[0] == 'o' ) { // output redirection
+ if ( opt[1] == '\0' ) {
+ if ( !(n < argc-1) ) {
+ error = "Missing output file name";
+ break;
+ }
+ g->outputFile = argv[++n];
+ } else
+ g->outputFile = opt.tqstringFromPos(1);
+ } else if ( opt == "i" ) { // no #include statement
+ g->noInclude = TRUE;
+ autoInclude = FALSE;
+ } else if ( opt[0] == 'f' ) { // produce #include statement
+ g->noInclude = FALSE;
+ autoInclude = FALSE;
+ if ( opt[1] ) // -fsomething.h
+ g->includeFiles.append( opt.tqstringFromPos(1) );
+ } else if ( opt == "pch" ) { // produce #include statement for PCH
+ if ( !(n < argc-1) ) {
+ error = "Missing name of PCH file";
+ break;
+ }
+ g->pchFile = argv[++n];
+ } else if ( opt[0] == 'p' ) { // include file path
+ if ( opt[1] == '\0' ) {
+ if ( !(n < argc-1) ) {
+ error = "Missing path name for the -p option.";
+ break;
+ }
+ g->includePath = argv[++n];
+ } else {
+ g->includePath = opt.tqstringFromPos(1);
+ }
+ } else if ( opt[0] == 'q' ) { // qt include file path
+ if ( opt[1] == '\0' ) {
+ if ( !(n < argc-1) ) {
+ error = "Missing path name for the -q option.";
+ break;
+ }
+ g->qtPath = argv[++n];
+ } else {
+ g->qtPath = opt.tqstringFromPos(1);
+ }
+ tqreplace(g->qtPath.data(),'\\','/');
+ if ( g->qtPath.right(1) != "/" )
+ g->qtPath += '/';
+ } else if ( opt == "v" ) { // version number
+ fprintf( stderr, "TQt Meta Object Compiler version %d"
+ " (TQt %s)\n", formatRevision,
+ TQT_VERSION_STR );
+ cleanup();
+ return 1;
+ } else if ( opt == "k" ) { // stop on errors
+ errorControl = TRUE;
+ } else if ( opt == "nw" ) { // don't display warnings
+ displayWarnings = FALSE;
+ } else if ( opt == "ldbg" ) { // lex debug output
+ lexDebug = TRUE;
+ } else if ( opt == "ydbg" ) { // yacc debug output
+ yydebug = TRUE;
+ } else {
+ error = "Invalid argument";
+ }
+ } else {
+ if ( !g->fileName.isNull() ) // can handle only one file
+ error = "Too many input files specified";
+ else
+ g->fileName = arg.copy();
+ }
+ }
+
+ if ( autoInclude ) {
+ int ppos = g->fileName.tqfindRev('.');
+ if ( ppos != -1 && tolower( g->fileName[ppos + 1] ) == 'h' )
+ g->noInclude = FALSE;
+ else
+ g->noInclude = TRUE;
+ }
+ setDefaultIncludeFile();
+
+ if ( g->fileName.isNull() && !error ) {
+ g->fileName = "standard input";
+ yyin = stdin;
+ } else if ( argc < 2 || error ) { // incomplete/wrong args
+ fprintf( stderr, "TQt meta object compiler\n" );
+ if ( error )
+ fprintf( stderr, "tqmoc: %s\n", error );
+ fprintf( stderr, "Usage: tqmoc [options] <header-file>\n"
+ "\t-o file Write output to file rather than stdout\n"
+ "\t-f[file] Force #include, optional file name\n"
+ "\t-p path Path prefix for included file\n"
+ "\t-i Do not generate an #include statement\n"
+ "\t-k Do not stop on errors\n"
+ "\t-nw Do not display warnings\n"
+ "\t-v Display version of tqmoc\n" );
+ cleanup();
+ return 1;
+ } else {
+ yyin = fopen( (const char *)g->fileName, "r" );
+ if ( !yyin ) {
+ fprintf( stderr, "tqmoc: %s: No such file\n", (const char*)g->fileName);
+ cleanup();
+ return 1;
+ }
+ }
+ if ( !g->outputFile.isEmpty() ) { // output file specified
+ out = fopen( (const char *)g->outputFile, "w" ); // create output file
+ if ( !out ) {
+ fprintf( stderr, "tqmoc: Cannot create %s\n",
+ (const char*)g->outputFile );
+ cleanup();
+ return 1;
+ }
+ } else { // use stdout
+ out = stdout;
+ }
+ yyparse();
+ fclose( yyin );
+ if ( !g->outputFile.isNull() )
+ fclose( out );
+
+ if ( !g->generatedCode && displayWarnings && !g->tqmocError ) {
+ fprintf( stderr, ErrorFormatString" Warning: %s\n", g->fileName.data(), 0,
+ "No relevant classes found. No output generated." );
+ }
+
+ int ret = g->tqmocError ? 1 : 0;
+ cleanup();
+ return ret;
+}
+#else
+bool qt_is_gui_used = FALSE;
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef TQ_OS_MAC9
+# include <Files.h>
+# include <Strings.h>
+# include <Errors.h>
+# include "Aliases.h"
+#endif
+#include "CWPluginErrors.h"
+#include <CWPlugins.h>
+#include "DropInCompilerLinker.h"
+#include <stat.h>
+
+const unsigned char *p_str(const char *, int =-1);
+
+CWPluginContext g_ctx;
+
+tqmoc_status do_tqmoc( CWPluginContext ctx, const TQCString &fin, const TQCString &fout, CWFileSpec *dspec, bool i)
+{
+ init();
+
+ g_ctx = ctx;
+ g->noInclude = i;
+ g->fileName = fin;
+ g->outputFile = fout;
+
+ setDefaultIncludeFile();
+
+ CWFileInfo fi;
+ memset(&fi, 0, sizeof(fi));
+ fi.fullsearch = TRUE;
+ fi.dependencyType = cwNormalDependency;
+ fi.isdependentoffile = kCurrentCompiledFile;
+ if(CWFindAndLoadFile( ctx, fin.data(), &fi) != cwNoErr) {
+ cleanup();
+ return tqmoc_no_source;
+ }
+
+ if(dspec) {
+ memcpy(dspec, &fi.filespec, sizeof(fi.filespec));
+ const unsigned char *f = p_str(fout.data());
+ memcpy(dspec->name, f, f[0]+1);
+ free(f);
+ }
+ buf_size_total = fi.filedatalength;
+ buf_buffer = fi.filedata;
+
+ TQCString path("");
+ AliasHandle alias;
+ Str63 str;
+ AliasInfoType x = 1;
+ char tmp[sizeof(Str63)+2];
+ if(NewAlias( NULL, &fi.filespec, &alias) != noErr) {
+ cleanup();
+ return tqmoc_general_error;
+ }
+ for(;;) {
+ GetAliasInfo(alias, x++, str);
+ if(!str[0])
+ break;
+ strncpy((char *)tmp, (const char *)str+1, str[0]);
+ tmp[str[0]] = '\0';
+ path.prepend(":");
+ path.prepend((char *)tmp);
+ }
+ path.prepend("MacOS 9:"); //FIXME
+
+ TQString inpath = path + fin, outpath = path + fout;
+ struct stat istat, ostat;
+ if(stat(inpath, &istat) == -1) {
+ cleanup();
+ return tqmoc_no_source;
+ }
+ if(stat(outpath, &ostat) == 0 && istat.st_mtime < ostat.st_mtime) {
+ cleanup();
+ return tqmoc_not_time;
+ }
+
+ unlink(outpath.data());
+ out = fopen(outpath.data(), "w+");
+ if(!out) {
+ cleanup();
+ return tqmoc_general_error;
+ }
+
+ yyparse();
+ if(out != stdout)
+ fclose(out);
+
+ if(g->tqmocError || !g->generatedCode) {
+ unlink(outpath.data());
+ tqmoc_status ret = !g->generatedCode ? tqmoc_no_qobject : tqmoc_parse_error;
+ cleanup();
+ return ret;
+ }
+
+ cleanup();
+ return tqmoc_success;
+}
+#endif
+void tqreplace( char *s, char c1, char c2 )
+{
+ if ( !s )
+ return;
+ while ( *s ) {
+ if ( *s == c1 )
+ *s = c2;
+ s++;
+ }
+}
+
+/*
+ This function looks at two file names and returns the name of the
+ infile with a path relative to outfile.
+
+ Examples:
+
+ /tmp/abc, /tmp/bcd -> abc
+ xyz/a/bc, xyz/b/ac -> ../a/bc
+ /tmp/abc, xyz/klm -> /tmp/abc
+ */
+
+TQCString combinePath( const char *infile, const char *outfile )
+{
+ TQFileInfo inFileInfo( TQDir::current(), TQFile::decodeName(infile) );
+ TQFileInfo outFileInfo( TQDir::current(), TQFile::decodeName(outfile) );
+ int numCommonComponents = 0;
+
+ TQStringList inSplitted =
+ TQStringList::split( '/', inFileInfo.dir().canonicalPath(), TRUE );
+ TQStringList outSplitted =
+ TQStringList::split( '/', outFileInfo.dir().canonicalPath(), TRUE );
+
+ while ( !inSplitted.isEmpty() && !outSplitted.isEmpty() &&
+ inSplitted.first() == outSplitted.first() ) {
+ inSplitted.remove( inSplitted.begin() );
+ outSplitted.remove( outSplitted.begin() );
+ numCommonComponents++;
+ }
+
+ if ( numCommonComponents < 2 ) {
+ /*
+ The paths don't have the same drive, or they don't have the
+ same root directory. Use an absolute path.
+ */
+ return TQFile::encodeName( inFileInfo.absFilePath() );
+ } else {
+ /*
+ The paths have something in common. Use a path relative to
+ the output file.
+ */
+ while ( !outSplitted.isEmpty() ) {
+ outSplitted.remove( outSplitted.begin() );
+ inSplitted.prepend( ".." );
+ }
+ inSplitted.append( inFileInfo.fileName() );
+ return TQFile::encodeName( inSplitted.join("/") );
+ }
+}
+
+
+#define getenv hack_getenv // workaround for byacc
+char *getenv() { return 0; }
+char *getenv( const char * ) { return 0; }
+
+void init() // initialize
+{
+ BEGIN OUTSIDE;
+ if(g)
+ delete g;
+ g = new parser_reg;
+ lineNo = 1;
+ skipClass = FALSE;
+ skipFunc = FALSE;
+ tmpArgList = new ArgList;
+ tmpFunc = new Function;
+ tmpEnum = new Enum;
+
+#ifdef TQMOC_MWERKS_PLUGIN
+ buf_buffer = NULL;
+ buf_index = 0;
+ buf_size_total = 0;
+#endif
+}
+
+void cleanup()
+{
+ delete g;
+ g = NULL;
+
+#ifdef TQMOC_MWERKS_PLUGIN
+ if(buf_buffer && g_ctx)
+ CWReleaseFileText(g_ctx, buf_buffer);
+#endif
+}
+
+void initClass() // prepare for new class
+{
+ tmpAccess = Private;
+ subClassPerm = Private;
+ TQ_OBJECTdetected = FALSE;
+ Q_PROPERTYdetected = FALSE;
+ skipClass = FALSE;
+ templateClass = FALSE;
+ g->tqslots.clear();
+ g->tqsignals.clear();
+ g->propfuncs.clear();
+ g->enums.clear();
+ g->funcs.clear();
+ g->props.clear();
+ g->infos.clear();
+ g->qtSets.clear();
+ g->qtEnums.clear();
+ g->multipleSuperClasses.clear();
+}
+
+struct NamespaceInfo
+{
+ TQCString name;
+ int pLevelOnEntering; // Parenthesis level on entering the namespace
+ TQDict<char> definedClasses; // Classes defined in the namespace
+};
+
+TQPtrList<NamespaceInfo> namespaces;
+
+void enterNameSpace( const char *name ) // prepare for new class
+{
+ static bool first = TRUE;
+ if ( first ) {
+ namespaces.setAutoDelete( TRUE );
+ first = FALSE;
+ }
+
+ NamespaceInfo *tmp = new NamespaceInfo;
+ if ( name )
+ tmp->name = name;
+ tmp->pLevelOnEntering = namespacePLevel;
+ namespaces.append( tmp );
+}
+
+void leaveNameSpace() // prepare for new class
+{
+ NamespaceInfo *tmp = namespaces.last();
+ namespacePLevel = tmp->pLevelOnEntering;
+ namespaces.remove();
+}
+
+TQCString nameTQualifier()
+{
+ TQPtrListIterator<NamespaceInfo> iter( namespaces );
+ NamespaceInfo *tmp;
+ TQCString qualifier = "";
+ for( ; (tmp = iter.current()) ; ++iter ) {
+ if ( !tmp->name.isNull() ) { // If not unnamed namespace
+ qualifier += tmp->name;
+ qualifier += "::";
+ }
+ }
+ return qualifier;
+}
+
+int openNameSpaceForMetaObject( FILE *out )
+{
+ int levels = 0;
+ TQPtrListIterator<NamespaceInfo> iter( namespaces );
+ NamespaceInfo *tmp;
+ TQCString indent = "";
+ for( ; (tmp = iter.current()) ; ++iter ) {
+ if ( !tmp->name.isNull() ) { // If not unnamed namespace
+ fprintf( out, "%snamespace %s {\n", (const char *)indent,
+ (const char *) tmp->name );
+ indent += " ";
+ levels++;
+ }
+ }
+ TQCString nm = g->className;
+ int pos;
+ while( (pos = nm.tqfind( "::" )) != -1 ) {
+ TQCString spaceName = nm.left( pos );
+ nm = nm.right( nm.length() - pos - 2 );
+ if ( !spaceName.isEmpty() ) {
+ fprintf( out, "%snamespace %s {\n", (const char *)indent,
+ (const char *) spaceName );
+ indent += " ";
+ levels++;
+ }
+ }
+ return levels;
+}
+
+void closeNameSpaceForMetaObject( FILE *out, int levels )
+{
+ int i;
+ for( i = 0 ; i < levels ; i++ )
+ fprintf( out, "}" );
+ if ( levels )
+ fprintf( out, "\n" );
+
+}
+
+void selectOutsideClassState()
+{
+ if ( namespaces.count() == 0 )
+ BEGIN OUTSIDE;
+ else
+ BEGIN IN_NAMESPACE;
+}
+
+void registerClassInNamespace()
+{
+ if ( namespaces.count() == 0 )
+ return;
+ namespaces.last()->definedClasses.insert((const char *)g->className,(char*)1);
+}
+
+//
+// Remove white space from SIGNAL and SLOT names.
+// This function has been copied from qobject.cpp.
+//
+
+inline bool isSpace( char x )
+{
+#if defined(TQ_CC_BOR)
+ /*
+ Borland C++ 4.5 has a weird isspace() bug.
+ isspace() usually works, but not here.
+ This implementation is sufficient for our internal use: rmWS()
+ */
+ return (uchar) x <= 32;
+#else
+ return isspace( (uchar) x );
+#endif
+}
+
+static TQCString rmWS( const char *src )
+{
+ TQCString result( tqstrlen(src)+1 );
+ char *d = result.data();
+ char *s = (char *)src;
+ char last = 0;
+ while( *s && isSpace(*s) ) // skip leading space
+ s++;
+ while ( *s ) {
+ while ( *s && !isSpace(*s) )
+ last = *d++ = *s++;
+ while ( *s && isSpace(*s) )
+ s++;
+ if ( *s && isIdentChar(*s) && isIdentChar(last) )
+ last = *d++ = ' ';
+ }
+ result.truncate( (int)(d - result.data()) );
+ return result;
+}
+
+
+void initExpression()
+{
+ g->tmpExpression = "";
+}
+
+void addExpressionString( const char *s )
+{
+ g->tmpExpression += s;
+}
+
+void addExpressionChar( const char c )
+{
+ g->tmpExpression += c;
+}
+
+void yyerror( const char *msg ) // print yacc error message
+{
+ g->tqmocError = TRUE;
+#ifndef TQMOC_MWERKS_PLUGIN
+ fprintf( stderr, ErrorFormatString" Error: %s\n", g->fileName.data(), lineNo, msg );
+#else
+ char msg2[200];
+ sprintf(msg2, ErrorFormatString" Error: %s", g->fileName.data(), lineNo, msg);
+ CWReportMessage(g_ctx, NULL, msg2, NULL, messagetypeError, 0);
+#endif
+ if ( errorControl ) {
+ if ( !g->outputFile.isEmpty() && yyin && fclose(yyin) == 0 )
+ remove( g->outputFile );
+ exit( -1 );
+ }
+}
+
+void tqmoc_err( const char *s )
+{
+ yyerror( s );
+}
+
+void tqmoc_err( const char *s1, const char *s2 )
+{
+ static char tmp[1024];
+ sprintf( tmp, s1, s2 );
+ yyerror( tmp );
+}
+
+void tqmoc_warn( const char *msg )
+{
+ if ( displayWarnings )
+ fprintf( stderr, ErrorFormatString" Warning: %s\n", g->fileName.data(), lineNo, msg);
+}
+
+void tqmoc_warn( char *s1, char *s2 )
+{
+ static char tmp[1024];
+ sprintf( tmp, s1, s2 );
+ if ( displayWarnings )
+ fprintf( stderr, ErrorFormatString" Warning: %s\n", g->fileName.data(), lineNo, tmp);
+}
+
+void func_warn( const char *msg )
+{
+ if ( !suppress_func_warn )
+ tqmoc_warn( msg );
+ skipFunc = TRUE;
+}
+
+void operatorError()
+{
+ if ( !suppress_func_warn )
+ tqmoc_warn("Operator functions cannot be tqsignals or tqslots.");
+ skipFunc = TRUE;
+}
+
+#ifndef yywrap
+int yywrap() // more files?
+{
+ return 1; // end of file
+}
+#endif
+
+char *stradd( const char *s1, const char *s2 ) // adds two strings
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+1];
+ qstrcpy( n, s1 );
+ strcat( n, s2 );
+ return n;
+}
+
+char *stradd( const char *s1, const char *s2, const char *s3 )// adds 3 strings
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+tqstrlen(s3)+1];
+ qstrcpy( n, s1 );
+ strcat( n, s2 );
+ strcat( n, s3 );
+ return n;
+}
+
+char *stradd( const char *s1, const char *s2,
+ const char *s3, const char *s4 )// adds 4 strings
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+tqstrlen(s3)+tqstrlen(s4)+1];
+ qstrcpy( n, s1 );
+ strcat( n, s2 );
+ strcat( n, s3 );
+ strcat( n, s4 );
+ return n;
+}
+
+
+char *straddSpc( const char *s1, const char *s2 )
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+2];
+ qstrcpy( n, s1 );
+ strcat( n, " " );
+ strcat( n, s2 );
+ return n;
+}
+
+char *straddSpc( const char *s1, const char *s2, const char *s3 )
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+tqstrlen(s3)+3];
+ qstrcpy( n, s1 );
+ strcat( n, " " );
+ strcat( n, s2 );
+ strcat( n, " " );
+ strcat( n, s3 );
+ return n;
+}
+
+char *straddSpc( const char *s1, const char *s2,
+ const char *s3, const char *s4 )
+{
+ char *n = new char[tqstrlen(s1)+tqstrlen(s2)+tqstrlen(s3)+tqstrlen(s4)+4];
+ qstrcpy( n, s1 );
+ strcat( n, " " );
+ strcat( n, s2 );
+ strcat( n, " " );
+ strcat( n, s3 );
+ strcat( n, " " );
+ strcat( n, s4 );
+ return n;
+}
+
+// Generate C++ code for building member function table
+
+
+/*
+ We call B::qt_invoke() rather than A::B::qt_invoke() to
+ work around a bug in MSVC 6. The bug occurs if the
+ super-class is in a namespace and the sub-class isn't.
+
+ Exception: If the superclass has the same name as the subclass, we
+ want non-MSVC users to have a working generated files.
+*/
+TQCString purestSuperClassName()
+{
+ TQCString sc = g->superClassName;
+ TQCString c = g->className;
+ /*
+ Make sure qualified template arguments (e.g., foo<bar::baz>)
+ don't interfere.
+ */
+ int pos = sc.tqfindRev( "::", sc.tqfind( '<' ) );
+ if ( pos != -1 ) {
+ sc = sc.right( sc.length() - pos - 2 );
+ pos = c.tqfindRev( "::" );
+ if ( pos != -1 )
+ c = c.right( c.length() - pos - 2 );
+ if ( sc == c )
+ sc = g->superClassName;
+ }
+ return sc;
+}
+
+TQCString callablePurestSuperClassName()
+{
+ TQCString sc = purestSuperClassName();
+// if (sc.tqfind("TQ") != 0) {
+ return TQCString("static_cast<TQObject*>(static_cast<TQT_BASE_OBJECT_NAME*>(this))->");
+// }
+// else {
+// return TQCString(sc + "::");
+// }
+}
+
+TQCString qualifiedClassName()
+{
+ return nameTQualifier() + g->className;
+}
+
+TQCString callableQualifiedClassName()
+{
+ TQCString sc = qualifiedClassName();
+// if (sc.tqfind("TQ") != 0) {
+ return TQCString("static_cast<TQObject*>(static_cast<TQT_BASE_OBJECT_NAME*>(this))->");
+// }
+// else {
+// return TQCString(sc + "::");
+// }
+}
+
+const int Slot_Num = 1;
+const int Signal_Num = 2;
+const int Prop_Num = 3;
+
+void generateFuncs( FuncList *list, const char *functype, int num )
+{
+ Function *f;
+ for ( f=list->first(); f; f=list->next() ) {
+ bool hasReturnValue = f->type != "void" && (validUType( f->type ) || isVariantType( f->type) );
+
+ if ( hasReturnValue || !f->args->isEmpty() ) {
+ fprintf( out, " static const TQUParameter param_%s_%d[] = {\n", functype, list->at() );
+ if ( hasReturnValue ) {
+ if ( validUType( f->type ) )
+ fprintf( out, "\t{ 0, &static_TQUType_%s, %s, TQUParameter::Out }", uType(f->type).data(), uTypeExtra(f->type).data() );
+ else
+ fprintf( out, "\t{ 0, &static_TQUType_TQVariant, %s, TQUParameter::Out }", uTypeExtra(f->type).data() );
+ if ( !f->args->isEmpty() )
+ fprintf( out, ",\n" );
+ }
+ Argument* a = f->args->first();
+ while ( a ) {
+ TQCString type = a->leftType + ' ' + a->rightType;
+ type = type.simplifyWhiteSpace();
+ if( a->name.isEmpty() )
+ fprintf( out, "\t{ 0, &static_TQUType_%s, %s, TQUParameter::%s }",
+ uType( type ).data(), uTypeExtra( type ).data(),
+ isInOut( type ) ? "InOut" : "In" );
+ else
+ fprintf( out, "\t{ \"%s\", &static_TQUType_%s, %s, TQUParameter::%s }",
+ a->name.data(), uType( type ).data(), uTypeExtra( type ).data(),
+ isInOut( type ) ? "InOut" : "In" );
+ a = f->args->next();
+ if ( a )
+ fprintf( out, ",\n" );
+ }
+ fprintf( out, "\n };\n");
+ }
+
+ fprintf( out, " static const TQUMethod %s_%d = {", functype, list->at() );
+ int n = f->args->count();
+ if ( hasReturnValue )
+ n++;
+ fprintf( out, "\"%s\", %d,", f->name.data(), n );
+ if ( n )
+ fprintf( out, " param_%s_%d };\n", functype, list->at() );
+ else
+ fprintf( out, " 0 };\n" );
+
+ TQCString typstr = "";
+ int count = 0;
+ Argument *a = f->args->first();
+ while ( a ) {
+ if ( !a->leftType.isEmpty() || ! a->rightType.isEmpty() ) {
+ if ( count++ )
+ typstr += ",";
+ typstr += a->leftType;
+ typstr += a->rightType;
+ }
+ a = f->args->next();
+ }
+ f->signature = f->name;
+ f->signature += "(";
+ f->signature += typstr;
+ f->signature += ")";
+ }
+ if ( list->count() ) {
+ fprintf(out," static const TQMetaData %s_tbl[] = {\n", functype );
+ f = list->first();
+ while ( f ) {
+ fprintf( out, "\t{ \"%s\",", f->signature.data() );
+ fprintf( out, " &%s_%d,", functype, list->at() );
+ fprintf( out, " TQMetaData::%s }", f->accessAsString() );
+ f = list->next();
+ if ( f )
+ fprintf( out, ",\n");
+ }
+ fprintf( out, "\n };\n" );
+ }
+}
+
+
+int enumIndex( const char* type )
+{
+ int index = 0;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit ) {
+ if ( lit.current()->name == type )
+ return index;
+ index++;
+ }
+ return -1;
+}
+
+bool isEnumType( const char* type )
+{
+ return enumIndex( type ) >= 0 || ( g->qtEnums.tqcontains( type ) || g->qtSets.tqcontains( type ) );
+}
+
+bool isPropertyType( const char* type )
+{
+ if ( isVariantType( type ) )
+ return TRUE;
+
+ return isEnumType( type );
+}
+
+int generateEnums()
+{
+ if ( g->enums.count() == 0 )
+ return 0;
+
+ fprintf( out, "#ifndef TQT_NO_PROPERTIES\n" );
+ int i = 0;
+ for ( TQPtrListIterator<Enum> it( g->enums ); it.current(); ++it, ++i ) {
+ fprintf( out, " static const TQMetaEnum::Item enum_%i[] = {\n", i );
+ int k = 0;
+ for( TQStrListIterator eit( *it.current() ); eit.current(); ++eit, ++k ) {
+ if ( k )
+ fprintf( out, ",\n" );
+ fprintf( out, "\t{ \"%s\", (int) %s::%s }", eit.current(), (const char*) g->className, eit.current() );
+ }
+ fprintf( out, "\n };\n" );
+ }
+ fprintf( out, " static const TQMetaEnum enum_tbl[] = {\n" );
+ i = 0;
+ for ( TQPtrListIterator<Enum> it2( g->enums ); it2.current(); ++it2, ++i ) {
+ if ( i )
+ fprintf( out, ",\n" );
+ fprintf( out, "\t{ \"%s\", %u, enum_%i, %s }",
+ (const char*)it2.current()->name,
+ it2.current()->count(),
+ i,
+ it2.current()->set ? "TRUE" : "FALSE" );
+ }
+ fprintf( out, "\n };\n" );
+ fprintf( out, "#endif // TQT_NO_PROPERTIES\n" );
+
+ return g->enums.count();
+}
+
+int generateProps()
+{
+ //
+ // Resolve and verify property access functions
+ //
+ for( TQPtrListIterator<Property> it( g->props ); it.current(); ) {
+ Property* p = it.current();
+ ++it;
+
+ // verify get function
+ if ( !p->get.isEmpty() ) {
+ FuncList candidates = g->propfuncs.tqfind( p->get );
+ for ( Function* f = candidates.first(); f; f = candidates.next() ) {
+ if ( f->qualifier != "const" ) // get functions must be const
+ continue;
+ if ( f->args && !f->args->isEmpty() ) // and must not take any arguments
+ continue;
+ TQCString tmp = f->type;
+ Property::Specification spec = Property::Unspecified;
+ if ( p->type == "TQCString" && (tmp == "const char*" || tmp == "const char *" ) ) {
+ tmp = "TQCString";
+ spec = Property::ConstCharStar;
+ } else if ( tmp.right(1) == "&" ) {
+ tmp = tmp.left( tmp.length() - 1 );
+ spec = Property::Reference;
+ } else if ( tmp.right(1) == "*" ) {
+ tmp = tmp.left( tmp.length() - 1 );
+ spec = Property::Pointer;
+ } else {
+ spec = Property::Class;
+ }
+ if ( tmp.left(6) == "const " )
+ tmp = tmp.mid( 6, tmp.length() - 6 );
+ tmp = tmp.simplifyWhiteSpace();
+ if ( p->type == tmp ) {
+ // If it is an enum then it may not be a set
+ bool ok = TRUE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && lit.current()->set )
+ ok = FALSE;
+ if ( !ok ) continue;
+ p->gspec = spec;
+ p->getfunc = f;
+ p->oredEnum = 0;
+ break;
+ }
+ else if ( !isVariantType( p->type ) ) {
+ if ( tmp == "int" || tmp == "uint" || tmp == "unsigned int" ) {
+ // Test whether the enum is really a set (unfortunately we don't know enums of super classes)
+ bool ok = TRUE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && !lit.current()->set )
+ ok = FALSE;
+ if ( !ok ) continue;
+ p->gspec = spec;
+ p->getfunc = f;
+ p->oredEnum = 1;
+ p->enumgettype = tmp;
+ }
+ }
+ }
+ if ( p->getfunc == 0 ) {
+ if ( displayWarnings ) {
+
+ // Is the type a set, that means, mentioned in TQ_SETS?
+ bool set = FALSE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && lit.current()->set )
+ set = TRUE;
+
+ fprintf( stderr, ErrorFormatString" Warning: Property '%s' not available.\n",
+ g->fileName.data(), p->lineNo, (const char*) p->name );
+ fprintf( stderr, " Have been looking for public get functions \n");
+ if ( !set ) {
+ fprintf( stderr,
+ " %s %s() const\n"
+ " %s& %s() const\n"
+ " const %s& %s() const\n"
+ " %s* %s() const\n",
+ (const char*) p->type, (const char*) p->get,
+ (const char*) p->type, (const char*) p->get,
+ (const char*) p->type, (const char*) p->get,
+ (const char*) p->type, (const char*) p->get );
+ }
+ if ( set || !isPropertyType( p->type ) ) {
+ fprintf( stderr,
+ " int %s() const\n"
+ " uint %s() const\n"
+ " unsigned int %s() const\n",
+ (const char*) p->get,
+ (const char*) p->get,
+ (const char*) p->get );
+ }
+ if ( p->type == "TQCString" )
+ fprintf( stderr, " const char* %s() const\n",
+ (const char*)p->get );
+
+ if ( candidates.isEmpty() ) {
+ fprintf( stderr, " but found nothing.\n");
+ } else {
+ fprintf( stderr, " but only found the mismatching candidate(s)\n");
+ for ( Function* f = candidates.first(); f; f = candidates.next() ) {
+ TQCString typstr = "";
+ Argument *a = f->args->first();
+ int count = 0;
+ while ( a ) {
+ if ( !a->leftType.isEmpty() || ! a->rightType.isEmpty() ) {
+ if ( count++ )
+ typstr += ",";
+ typstr += a->leftType;
+ typstr += a->rightType;
+ }
+ a = f->args->next();
+ }
+ fprintf( stderr, " %s:%d: %s %s(%s) %s\n", g->fileName.data(), f->lineNo,
+ (const char*) f->type,(const char*) f->name, (const char*) typstr,
+ f->qualifier.isNull()?"":(const char*) f->qualifier );
+ }
+ }
+ }
+ }
+ }
+
+ // verify set function
+ if ( !p->set.isEmpty() ) {
+ FuncList candidates = g->propfuncs.tqfind( p->set );
+ for ( Function* f = candidates.first(); f; f = candidates.next() ) {
+ if ( !f->args || f->args->isEmpty() )
+ continue;
+ TQCString tmp = f->args->first()->leftType;
+ tmp = tmp.simplifyWhiteSpace();
+ Property::Specification spec = Property::Unspecified;
+ if ( tmp.right(1) == "&" ) {
+ tmp = tmp.left( tmp.length() - 1 );
+ spec = Property::Reference;
+ }
+ else {
+ spec = Property::Class;
+ }
+ if ( p->type == "TQCString" && (tmp == "const char*" || tmp == "const char *" ) ) {
+ tmp = "TQCString";
+ spec = Property::ConstCharStar;
+ }
+ if ( tmp.left(6) == "const " )
+ tmp = tmp.mid( 6, tmp.length() - 6 );
+ tmp = tmp.simplifyWhiteSpace();
+
+ if ( p->type == tmp && f->args->count() == 1 ) {
+ // If it is an enum then it may not be a set
+ if ( p->oredEnum == 1 )
+ continue;
+ bool ok = TRUE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && lit.current()->set )
+ ok = FALSE;
+ if ( !ok ) continue;
+ p->sspec = spec;
+ p->setfunc = f;
+ p->oredEnum = 0;
+ break;
+ } else if ( !isVariantType( p->type ) && f->args->count() == 1 ) {
+ if ( tmp == "int" || tmp == "uint" || tmp == "unsigned int" ) {
+ if ( p->oredEnum == 0 )
+ continue;
+ // Test wether the enum is really a set (unfortunately we don't know enums of super classes)
+ bool ok = TRUE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && !lit.current()->set )
+ ok = FALSE;
+ if ( !ok ) continue;
+ p->sspec = spec;
+ p->setfunc = f;
+ p->oredEnum = 1;
+ p->enumsettype = tmp;
+ }
+ }
+ }
+ if ( p->setfunc == 0 ) {
+ if ( displayWarnings ) {
+
+ // Is the type a set, that means, mentioned in TQ_SETS ?
+ bool set = FALSE;
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit )
+ if ( lit.current()->name == p->type && lit.current()->set )
+ set = TRUE;
+
+ fprintf( stderr, ErrorFormatString" Warning: Property '%s' not writable.\n",
+ g->fileName.data(), p->lineNo, (const char*) p->name );
+ fprintf( stderr, " Have been looking for public set functions \n");
+ if ( !set && p->oredEnum != 1 ) {
+ fprintf( stderr,
+ " void %s( %s )\n"
+ " void %s( %s& )\n"
+ " void %s( const %s& )\n",
+ (const char*) p->set, (const char*) p->type,
+ (const char*) p->set, (const char*) p->type,
+ (const char*) p->set, (const char*) p->type );
+ }
+ if ( set || ( !isPropertyType( p->type ) && p->oredEnum != 0 ) ) {
+ fprintf( stderr,
+ " void %s( int )\n"
+ " void %s( uint )\n"
+ " void %s( unsigned int )\n",
+ (const char*) p->set,
+ (const char*) p->set,
+ (const char*) p->set );
+ }
+
+ if ( p->type == "TQCString" )
+ fprintf( stderr, " void %s( const char* ) const\n",
+ (const char*) p->set );
+
+ if ( !candidates.isEmpty() ) {
+ fprintf( stderr, " but only found the mismatching candidate(s)\n");
+ for ( Function* f = candidates.first(); f; f = candidates.next() ) {
+ TQCString typstr = "";
+ Argument *a = f->args->first();
+ int count = 0;
+ while ( a ) {
+ if ( !a->leftType.isEmpty() || ! a->rightType.isEmpty() ) {
+ if ( count++ )
+ typstr += ",";
+ typstr += a->leftType;
+ typstr += a->rightType;
+ }
+ a = f->args->next();
+ }
+ fprintf( stderr, " %s:%d: %s %s(%s)\n", g->fileName.data(), f->lineNo,
+ (const char*) f->type,(const char*) f->name, (const char*) typstr );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ //
+ // Create meta data
+ //
+ if ( g->props.count() ) {
+ if ( displayWarnings && !TQ_OBJECTdetected )
+ tqmoc_err("The declaration of the class \"%s\" tqcontains properties"
+ " but no TQ_OBJECT macro.", g->className.data());
+
+ fprintf( out, "#ifndef TQT_NO_PROPERTIES\n" );
+
+ fprintf( out, " static const TQMetaProperty props_tbl[%d] = {\n ", g->props.count() );
+ for( TQPtrListIterator<Property> it( g->props ); it.current(); ++it ) {
+
+ fprintf( out, "\t{ \"%s\",\"%s\", ", it.current()->type.data(), it.current()->name.data() );
+ int flags = Invalid;
+ if ( !isVariantType( it.current()->type ) ) {
+ flags |= EnumOrSet;
+ if ( !isEnumType( it.current()->type ) )
+ flags |= UnresolvedEnum;
+ } else {
+ flags |= qvariant_nameToType( it.current()->type ) << 24;
+ }
+ if ( it.current()->getfunc )
+ flags |= Readable;
+ if ( it.current()->setfunc ) {
+ flags |= Writable;
+ if ( it.current()->stdSet() )
+ flags |= StdSet;
+ }
+ if ( it.current()->override )
+ flags |= Override;
+
+ if ( it.current()->designable.isEmpty() )
+ flags |= DesignableOverride;
+ else if ( it.current()->designable == "false" )
+ flags |= NotDesignable;
+
+ if ( it.current()->scriptable.isEmpty() )
+ flags |= ScriptableOverride;
+ else if ( it.current()->scriptable == "false" )
+ flags |= NotScriptable;
+
+ if ( it.current()->stored.isEmpty() )
+ flags |= StoredOverride;
+ else if ( it.current()->stored == "false" )
+ flags |= NotStored;
+
+
+ fprintf( out, "0x%.4x, ", flags );
+ fprintf( out, "&%s::metaObj, ", (const char*) qualifiedClassName() );
+ if ( !isVariantType( it.current()->type ) ) {
+ int enumpos = -1;
+ int k = 0;
+ for( TQPtrListIterator<Enum> eit( g->enums ); eit.current(); ++eit, ++k ) {
+ if ( eit.current()->name == it.current()->type )
+ enumpos = k;
+ }
+
+ // Is it an enum of this class ?
+ if ( enumpos != -1 )
+ fprintf( out, "&enum_tbl[%i], ", enumpos );
+ else
+ fprintf( out, "0, ");
+ } else {
+ fprintf( out, "0, ");
+ }
+ fprintf( out, "-1 }" );
+ if ( !it.atLast() )
+ fprintf( out, ",\n" );
+ else
+ fprintf( out, "\n" );
+ }
+ fprintf( out, " };\n" );
+ fprintf( out, "#endif // TQT_NO_PROPERTIES\n" );
+ }
+
+ return g->props.count();
+}
+
+
+
+int generateClassInfos()
+{
+ if ( g->infos.isEmpty() )
+ return 0;
+
+ if ( displayWarnings && !TQ_OBJECTdetected )
+ tqmoc_err("The declaration of the class \"%s\" tqcontains class infos"
+ " but no TQ_OBJECT macro.", g->className.data());
+
+ fprintf( out, " static const TQClassInfo classinfo_tbl[] = {\n" );
+ int i = 0;
+ for( TQPtrListIterator<ClassInfo> it( g->infos ); it.current(); ++it, ++i ) {
+ if ( i )
+ fprintf( out, ",\n" );
+ fprintf( out, "\t{ \"%s\", \"%s\" }", it.current()->name.data(),it.current()->value.data() );
+ }
+ fprintf( out, "\n };\n" );
+ return i;
+}
+
+
+void generateClass() // generate C++ source code for a class
+{
+ const char *hdr1 = "/****************************************************************************\n"
+ "** %s meta object code from reading C++ file '%s'\n**\n";
+ const char *hdr2 = "** Created: %s\n";
+ const char *hdr3 = "** WARNING! All changes made in this file will be lost!\n";
+ const char *hdr4 = "*****************************************************************************/\n\n";
+ int i;
+
+ if ( skipClass ) // don't generate for class
+ return;
+
+ if ( !TQ_OBJECTdetected ) {
+ if ( g->tqsignals.count() == 0 && g->tqslots.count() == 0 && g->props.count() == 0 && g->infos.count() == 0 )
+ return;
+ if ( displayWarnings && (g->tqsignals.count() + g->tqslots.count()) != 0 )
+ tqmoc_err("The declaration of the class \"%s\" tqcontains tqsignals "
+ "or tqslots\n\t but no TQ_OBJECT macro.", g->className.data());
+ } else {
+ if ( g->superClassName.isEmpty() )
+ tqmoc_err("The declaration of the class \"%s\" tqcontains the\n"
+ "\tTQ_OBJECT macro but does not inherit from any class!\n"
+ "\tInherit from TQObject or one of its descendants"
+ " or remove TQ_OBJECT.", g->className.data() );
+ }
+ if ( templateClass ) { // don't generate for class
+ tqmoc_err( "Sorry, TQt does not support templates that contain\n"
+ "\ttqsignals, tqslots or TQ_OBJECT." );
+ return;
+ }
+ g->generatedCode = TRUE;
+ g->gen_count++;
+
+ if ( g->gen_count == 1 ) { // first class to be generated
+ TQDateTime dt = TQDateTime::tqcurrentDateTime();
+ TQCString dstr = dt.toString().ascii();
+ TQCString fn = g->fileName;
+ i = g->fileName.length()-1;
+ while ( i>0 && g->fileName[i-1] != '/' && g->fileName[i-1] != '\\' )
+ i--; // skip path
+ if ( i >= 0 )
+ fn = g->fileName.tqstringFromPos(i);
+ fprintf( out, hdr1, (const char*)qualifiedClassName(),(const char*)fn);
+ fprintf( out, hdr2, (const char*)dstr );
+ fprintf( out, hdr3 );
+ fprintf( out, hdr4 );
+
+ if ( !g->noInclude ) {
+ /*
+ The header file might be a TQt header file with
+ TQT_NO_COMPAT macros around tqsignals, tqslots or
+ properties. Without the #undef, we cannot compile the
+ TQt library with TQT_NO_COMPAT defined.
+
+ Header files of libraries build around TQt can also use
+ TQT_NO_COMPAT, so this #undef might be beneficial to
+ users of TQt, and not only to developers of TQt.
+ */
+ fprintf( out, "#undef TQT_NO_COMPAT\n" );
+
+ if ( !g->pchFile.isEmpty() )
+ fprintf( out, "#include \"%s\" // PCH include\n", (const char*)g->pchFile );
+ if ( !g->includePath.isEmpty() && g->includePath.right(1) != "/" )
+ g->includePath += "/";
+
+ g->includeFiles.first();
+ while ( g->includeFiles.current() ) {
+ TQCString inc = g->includeFiles.current();
+ if ( inc[0] != '<' && inc[0] != '"' ) {
+ if ( !g->includePath.isEmpty() && g->includePath != "./" )
+ inc.prepend( g->includePath );
+ inc = "\"" + inc + "\"";
+ }
+ fprintf( out, "#include %s\n", (const char *)inc );
+ g->includeFiles.next();
+ }
+ }
+ fprintf( out, "#include <%stqmetaobject.h>\n", (const char*)g->qtPath );
+ fprintf( out, "#include <%stqapplication.h>\n\n", (const char*)g->qtPath );
+ fprintf( out, "#include <%sprivate/tqucomextra_p.h>\n", (const char*)g->qtPath );
+ fprintf( out, "#if !defined(TQ_TQMOC_OUTPUT_REVISION) || (TQ_TQMOC_OUTPUT_REVISION != %d)\n", formatRevision );
+ fprintf( out, "#error \"This file was generated using the tqmoc from %s."
+ " It\"\n#error \"cannot be used with the include files from"
+ " this version of TQt.\"\n#error \"(The tqmoc has changed too"
+ " much.)\"\n", TQT_VERSION_STR );
+ fprintf( out, "#endif\n\n" );
+ } else {
+ fprintf( out, "\n\n" );
+ }
+
+ if ( !g->hasVariantIncluded ) {
+ bool needToIncludeVariant = !g->props.isEmpty();
+ for ( Function* f =g->tqslots.first(); f && !needToIncludeVariant; f=g->tqslots.next() )
+ needToIncludeVariant = ( f->type != "void" && !validUType( f->type ) && isVariantType( f->type) );
+
+ if ( needToIncludeVariant ) {
+ fprintf( out, "#include <%stqvariant.h>\n", (const char*)g->qtPath );
+ g->hasVariantIncluded = TRUE;
+ }
+ }
+
+ bool isTQObject = g->className == "TQObject" ;
+
+
+//
+// Generate virtual function className()
+//
+ fprintf( out, "const char *%s::className() const\n{\n ",
+ (const char*)qualifiedClassName() );
+ fprintf( out, "return \"%s\";\n}\n\n", (const char*)qualifiedClassName() );
+
+//
+// Generate static metaObj variable
+//
+ fprintf( out, "TQMetaObject *%s::metaObj = 0;\n", (const char*)qualifiedClassName());
+
+//
+// Generate static cleanup object variable
+//
+ TQCString cleanup = qualifiedClassName().copy();
+ for ( int cnpos = 0; cnpos < cleanup.length(); cnpos++ ) {
+ if ( cleanup[cnpos] == ':' )
+ cleanup[cnpos] = '_';
+ }
+
+ fprintf( out, "static TQMetaObjectCleanUp cleanUp_%s( \"%s\", &%s::staticMetaObject );\n\n", (const char*)cleanup, (const char*)qualifiedClassName(), (const char*)qualifiedClassName() );
+
+//
+// Generate tr and trUtf8 member functions
+//
+ fprintf( out, "#ifndef TQT_NO_TRANSLATION\n" );
+ fprintf( out, "TQString %s::tr( const char *s, const char *c )\n{\n",
+ (const char*)qualifiedClassName() );
+ fprintf( out, " if ( tqApp )\n" );
+ fprintf( out, "\treturn tqApp->translate( \"%s\", s, c,"
+ " TQApplication::DefaultCodec );\n",
+ (const char*)qualifiedClassName() );
+ fprintf( out, " else\n" );
+ fprintf( out, "\treturn TQString::tqfromLatin1( s );\n");
+ fprintf( out, "}\n" );
+ fprintf( out, "#ifndef TQT_NO_TRANSLATION_UTF8\n" );
+ fprintf( out, "TQString %s::trUtf8( const char *s, const char *c )\n{\n",
+ (const char*)qualifiedClassName() );
+ fprintf( out, " if ( tqApp )\n" );
+ fprintf( out, "\treturn tqApp->translate( \"%s\", s, c,"
+ " TQApplication::UnicodeUTF8 );\n",
+ (const char*)qualifiedClassName() );
+ fprintf( out, " else\n" );
+ fprintf( out, "\treturn TQString::fromUtf8( s );\n" );
+ fprintf( out, "}\n" );
+ fprintf( out, "#endif // TQT_NO_TRANSLATION_UTF8\n\n" );
+ fprintf( out, "#endif // TQT_NO_TRANSLATION\n\n" );
+
+//
+// Generate staticMetaObject member function
+//
+ fprintf( out, "TQMetaObject* %s::staticMetaObject()\n{\n", (const char*)qualifiedClassName() );
+ fprintf( out, " if ( metaObj )\n\treturn metaObj;\n" );
+ if ( isTQObject )
+ fprintf( out, " TQMetaObject* parentObject = staticTQtMetaObject();\n" );
+ else if ( !g->superClassName.isEmpty() )
+ if (g->superClassName.tqfind("TQ") == 0) { // [FIXME] Verify that this will always be able to detect a TQt base class, even if intermediate classes do not start with TQ
+ fprintf( out, " TQMetaObject* parentObject = %s::staticMetaObject();\n", (const char*)g->superClassName );
+ }
+ else {
+ fprintf( out, " TQMetaObject* parentObject = 0;\n" );
+ }
+ else
+ fprintf( out, " TQMetaObject* parentObject = 0;\n" );
+
+//
+// Build the classinfo array
+//
+ int n_infos = generateClassInfos();
+
+// Build the enums array
+// Enums HAVE to be generated BEFORE the properties and tqslots
+//
+ int n_enums = generateEnums();
+
+//
+// Build tqslots array in staticMetaObject()
+//
+ generateFuncs( &g->tqslots, "slot", Slot_Num );
+
+//
+// Build tqsignals array in staticMetaObject()
+//
+ generateFuncs( &g->tqsignals, "signal", Signal_Num );
+
+//
+// Build property array in staticMetaObject()
+//
+ int n_props = generateProps();
+
+//
+// Finally code to create and return meta object
+//
+ fprintf( out, " metaObj = TQMetaObject::new_metaobject(\n"
+ "\t\"%s\", parentObject,\n", (const char*)qualifiedClassName() );
+
+ if ( g->tqslots.count() )
+ fprintf( out, "\tslot_tbl, %d,\n", g->tqslots.count() );
+ else
+ fprintf( out, "\t0, 0,\n" );
+
+ if ( g->tqsignals.count() )
+ fprintf( out, "\tsignal_tbl, %d,\n", g->tqsignals.count() );
+ else
+ fprintf( out, "\t0, 0,\n" );
+
+ fprintf( out, "#ifndef TQT_NO_PROPERTIES\n" );
+ if ( n_props )
+ fprintf( out, "\tprops_tbl, %d,\n", n_props );
+ else
+ fprintf( out, "\t0, 0,\n" );
+ if ( n_enums )
+ fprintf( out, "\tenum_tbl, %d,\n", n_enums );
+ else
+ fprintf( out, "\t0, 0,\n" );
+ fprintf( out, "#endif // TQT_NO_PROPERTIES\n" );
+
+ if ( n_infos )
+ fprintf( out, "\tclassinfo_tbl, %d );\n", n_infos );
+ else
+ fprintf( out, "\t0, 0 );\n" );
+
+
+//
+// Setup cleanup handler and return meta object
+//
+ fprintf( out, " cleanUp_%s.setMetaObject( metaObj );\n", cleanup.data() );
+ fprintf( out, " return metaObj;\n}\n" );
+
+//
+// End of function staticMetaObject()
+//
+
+//
+// Generate smart cast function
+//
+ fprintf( out, "\nvoid* %s::qt_cast( const char* clname )\n{\n",
+ (const char*)qualifiedClassName() );
+ fprintf( out, " if ( !qstrcmp( clname, \"%s\" ) )\n"
+ "\treturn this;\n",
+ (const char*)qualifiedClassName() );
+ for ( const char* cname = g->multipleSuperClasses.first(); cname; cname = g->multipleSuperClasses.next() ) {
+ fprintf( out, " if ( !qstrcmp( clname, \"%s\" ) )\n", cname);
+ TQCString fixed(cname);
+ while (fixed.tqfind(">>") != -1)
+ fixed = fixed.tqreplace(">>", "> >");
+ fprintf( out, "\treturn (%s*)this;\n", fixed.data());
+ }
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, " return %sqt_cast( clname );\n",
+ (const char*)callablePurestSuperClassName() );
+ else
+ fprintf( out, " return 0;\n" );
+ fprintf( out, "}\n" );
+
+//
+// Generate internal signal functions
+//
+ Function *f;
+ f = g->tqsignals.first(); // make internal signal methods
+ static bool included_list_headers = FALSE;
+ int sigindex = 0;
+ while ( f ) {
+ TQCString argstr;
+ char buf[12];
+ Argument *a = f->args->first();
+ int offset = 0;
+ const char *predef_call_func = 0;
+ bool hasReturnValue = f->type != "void" && (validUType( f->type ) || isVariantType( f->type) );
+ if ( hasReturnValue ) {
+ ; // no predefined function available
+ } else if ( !a ) {
+ predef_call_func = "activate_signal";
+ } else if ( f->args->count() == 1 ) {
+ TQCString ctype = (a->leftType + ' ' + a->rightType).simplifyWhiteSpace();
+ if ( !isInOut( ctype ) ) {
+ TQCString utype = uType( ctype );
+ if ( utype == "bool" )
+ predef_call_func = "activate_signal_bool";
+ else if ( utype == "TQString" || utype == "int" || utype == "double" )
+ predef_call_func = "activate_signal";
+ }
+ }
+
+ if ( !predef_call_func && !included_list_headers ) {
+ // yes we need it, because otherwise TQT_VERSION may not be defined
+ fprintf( out, "\n#include <%stqobjectdefs.h>\n", (const char*)g->qtPath );
+ fprintf( out, "#include <%stqsignalslotimp.h>\n", (const char*)g->qtPath );
+ included_list_headers = TRUE;
+ }
+
+ while ( a ) { // argument list
+ if ( !a->leftType.isEmpty() || !a->rightType.isEmpty() ) {
+ argstr += a->leftType;
+ argstr += " ";
+ sprintf( buf, "t%d", offset++ );
+ argstr += buf;
+ argstr += a->rightType;
+ a = f->args->next();
+ if ( a )
+ argstr += ", ";
+ } else {
+ a = f->args->next();
+ }
+ }
+
+ fixRightAngles( &argstr );
+
+ fprintf( out, "\n// SIGNAL %s\n", (const char*)f->name );
+ fprintf( out, "%s %s::%s(", (const char*) f->type,
+ (const char*)qualifiedClassName(),
+ (const char*)f->name );
+
+ if ( argstr.isEmpty() )
+ fprintf( out, ")\n{\n" );
+ else
+ fprintf( out, " %s )\n{\n", (const char*)argstr );
+
+ if ( predef_call_func ) {
+ fprintf( out, " %s%s( staticMetaObject()->signalOffset() + %d", (const char *) callablePurestSuperClassName(), predef_call_func, sigindex );
+ if ( !argstr.isEmpty() )
+ fprintf( out, ", t0" );
+ fprintf( out, " );\n}\n" );
+ } else {
+ if ( hasReturnValue )
+ fprintf( out, " %s something;\n", f->type.data() );
+ int nargs = f->args->count();
+ fprintf( out, " if ( tqsignalsBlocked() )\n\treturn%s;\n", hasReturnValue ? " something" : "" );
+ fprintf( out, " TQConnectionList *clist = tqreceivers( staticMetaObject()->signalOffset() + %d );\n",
+ sigindex );
+ fprintf( out, " if ( !clist )\n\treturn%s;\n", hasReturnValue ? " something" : "" );
+ fprintf( out, " TQUObject o[%d];\n", f->args->count() + 1 );
+
+ // initialize return value to something
+ if ( hasReturnValue ) {
+ if ( validUType( f->type ) ) {
+ TQCString utype = uType( f->type );
+ fprintf( out, " static_TQUType_%s.set(o,something);\n", utype.data() );
+ } else if ( uType( f->type ) == "varptr" ) {
+ fprintf( out, " static_TQUType_varptr.set(o,&something);\n" );
+ } else {
+ fprintf( out, " static_TQUType_ptr.set(o,&something);\n" );
+ }
+ }
+
+ // initialize arguments
+ if ( !f->args->isEmpty() ) {
+ offset = 0;
+ Argument* a = f->args->first();
+ while ( a ) {
+ TQCString type = a->leftType + ' ' + a->rightType;
+ type = type.simplifyWhiteSpace();
+ if ( validUType( type ) ) {
+ TQCString utype = uType( type );
+ fprintf( out, " static_TQUType_%s.set(o+%d,t%d);\n", utype.data(), offset+1, offset );
+ } else if ( uType( type ) == "varptr" ) {
+ fprintf( out, " static_TQUType_varptr.set(o+%d,&t%d);\n", offset+1, offset );
+ } else {
+ fprintf( out, " static_TQUType_ptr.set(o+%d,&t%d);\n", offset+1, offset );
+ }
+ a = f->args->next();
+ offset++;
+ }
+ }
+ fprintf( out, " activate_signal( clist, o );\n" );
+
+ // get return values from inOut parameters
+ if ( !f->args->isEmpty() ) {
+ offset = 0;
+ Argument* a = f->args->first();
+ while ( a ) {
+ TQCString type = a->leftType + ' ' + a->rightType;
+ type = type.simplifyWhiteSpace();
+ if ( validUType( type ) && isInOut( type ) ) {
+ TQCString utype = uType( type );
+ if ( utype == "enum" )
+ fprintf( out, " t%d = (%s)static_TQUType_%s.get(o+%d);\n", offset, type.data(), utype.data(), offset+1 );
+ else if ( utype == "ptr" && type.right(2) == "**" )
+ fprintf( out, " if (t%d) *t%d = *(%s)static_TQUType_ptr.get(o+%d);\n", offset, offset, type.data(), offset+1 );
+ else
+ fprintf( out, " t%d = static_TQUType_%s.get(o+%d);\n", offset, utype.data(), offset+1 );
+ }
+ a = f->args->next();
+ offset++;
+ }
+ }
+
+ // get and return return value
+ if ( hasReturnValue ) {
+ TQCString utype = uType( f->type );
+ if ( utype == "enum" || utype == "ptr" || utype == "varptr" ) // need cast
+ fprintf( out, " return (%s)static_TQUType_%s.get(o);\n", f->type.data(), utype.data() );
+ else
+ fprintf( out, " return static_TQUType_%s.get(o);\n", utype.data() );
+ }
+
+ fprintf( out, "}\n" );
+ }
+
+ f = g->tqsignals.next();
+ sigindex++;
+ }
+
+
+//
+// Generate internal qt_invoke() function
+//
+ fprintf( out, "\nbool %s::qt_invoke( int _id, TQUObject* _o )\n{\n", qualifiedClassName().data() );
+
+ if( !g->tqslots.isEmpty() ) {
+ fprintf( out, " switch ( _id - staticMetaObject()->slotOffset() ) {\n" );
+ int slotindex = -1;
+ for ( f = g->tqslots.first(); f; f = g->tqslots.next() ) {
+ slotindex ++;
+ if ( f->type == "void" && f->args->isEmpty() ) {
+ fprintf( out, " case %d: %s(); break;\n", slotindex, f->name.data() );
+ continue;
+ }
+
+ fprintf( out, " case %d: ", slotindex );
+ bool hasReturnValue = FALSE;
+ bool hasVariantReturn = FALSE;
+ if ( f->type != "void" ) {
+ if ( validUType( f->type )) {
+ hasReturnValue = TRUE;
+ fprintf( out, "static_TQUType_%s.set(_o,", uType(f->type).data() );
+ } else if ( isVariantType( f->type ) ) {
+ hasReturnValue = hasVariantReturn = TRUE;
+ // do not need special handling for bool since this is handled as utype
+ fprintf( out, "static_TQUType_TQVariant.set(_o,TQVariant(" );
+ }
+ }
+ int offset = 0;
+ fprintf( out, "%s(", f->name.data() );
+ Argument* a = f->args->first();
+ while ( a ) {
+ TQCString type = a->leftType + ' ' + a->rightType;
+ type = type.simplifyWhiteSpace();
+ fixRightAngles( &type );
+ if ( validUType( type ) ) {
+ TQCString utype = uType( type );
+ if ( utype == "ptr" || utype == "varptr" || utype == "enum" )
+ fprintf( out, "(%s)static_TQUType_%s.get(_o+%d)", type.data(), utype.data(), offset+1 );
+ else
+ fprintf( out, "(%s)static_TQUType_%s.get(_o+%d)", type.data(), utype.data(), offset+1 );
+ } else {
+ TQCString castType = castToUType( type );
+ if(castType == type)
+ fprintf( out, "(%s)(*((%s*)static_TQUType_ptr.get(_o+%d)))", type.data(),
+ castType.data(), offset+1 );
+ else
+ fprintf( out, "(%s)*((%s*)static_TQUType_ptr.get(_o+%d))", type.data(),
+ castType.data(), offset+1 );
+ }
+ a = f->args->next();
+ if ( a )
+ fprintf( out, "," );
+ offset++;
+ }
+ fprintf( out, ")" );
+ if ( hasReturnValue )
+ fprintf( out, ")" );
+ if ( hasVariantReturn )
+ fprintf( out, ")" );
+ fprintf( out, "; break;\n" );
+ }
+ fprintf( out, " default:\n" );
+
+ if ( !g->superClassName.isEmpty() && !isTQObject ) {
+ fprintf( out, "\treturn %sqt_invoke( _id, _o );\n",
+ (const char *) callablePurestSuperClassName() );
+ } else {
+ fprintf( out, "\treturn FALSE;\n" );
+ }
+ fprintf( out, " }\n" );
+ fprintf( out, " return TRUE;\n}\n" );
+ } else {
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, " return %sqt_invoke(_id,_o);\n}\n",
+ (const char *) callablePurestSuperClassName() );
+ else
+ fprintf( out, " return FALSE;\n}\n" );
+ }
+
+
+//
+// Generate internal qt_emit() function
+//
+ fprintf( out, "\nbool %s::qt_emit( int _id, TQUObject* _o )\n{\n", qualifiedClassName().data() );
+
+ if ( !g->tqsignals.isEmpty() ) {
+ fprintf( out, " switch ( _id - staticMetaObject()->signalOffset() ) {\n" );
+ int signalindex = -1;
+ for ( f = g->tqsignals.first(); f; f = g->tqsignals.next() ) {
+ signalindex++;
+ if ( f->type == "void" && f->args->isEmpty() ) {
+ fprintf( out, " case %d: %s(); break;\n", signalindex, f->name.data() );
+ continue;
+ }
+
+ fprintf( out, " case %d: ", signalindex );
+ bool hasReturnValue = FALSE;
+ if ( f->type != "void" && validUType( f->type )) {
+ hasReturnValue = TRUE;
+ fprintf( out, "static_TQUType_%s.set(_o,", uType(f->type).data() );
+ }
+ int offset = 0;
+ fprintf( out, "%s(", f->name.data() );
+ Argument* a = f->args->first();
+ while ( a ) {
+ TQCString type = a->leftType + ' ' + a->rightType;
+ type = type.simplifyWhiteSpace();
+ fixRightAngles( &type );
+ if ( validUType( type ) ) {
+ TQCString utype = uType( type );
+ if ( utype == "ptr" || utype == "varptr" || utype == "enum" )
+ fprintf( out, "(%s)static_TQUType_%s.get(_o+%d)", type.data(), utype.data(), offset+1 );
+ else
+ fprintf( out, "(%s)static_TQUType_%s.get(_o+%d)", type.data(), utype.data(), offset+1 );
+ } else {
+ TQCString castType = castToUType( type );
+ if(castType == type)
+ fprintf( out, "(%s)(*((%s*)static_TQUType_ptr.get(_o+%d)))", type.data(),
+ castType.data(), offset+1 );
+ else
+ fprintf( out, "(%s)*((%s*)static_TQUType_ptr.get(_o+%d))", type.data(),
+ castType.data(), offset+1 );
+ }
+ a = f->args->next();
+ if ( a )
+ fprintf( out, "," );
+ offset++;
+ }
+ fprintf( out, ")" );
+ if ( hasReturnValue )
+ fprintf( out, ")" );
+ fprintf( out, "; break;\n" );
+ }
+ fprintf( out, " default:\n" );
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, "\treturn %sqt_emit(_id,_o);\n",
+ (const char *) callablePurestSuperClassName() );
+ else
+ fprintf( out, "\treturn FALSE;\n" );
+ fprintf( out, " }\n" );
+ fprintf( out, " return TRUE;\n}\n" );
+ } else {
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, " return %sqt_emit(_id,_o);\n}\n",
+ (const char *) callablePurestSuperClassName() );
+ else
+ fprintf( out, " return FALSE;\n}\n" );
+ }
+
+
+ fprintf( out, "#ifndef TQT_NO_PROPERTIES\n" );
+//
+// Generate internal qt_property() functions
+//
+
+ fprintf( out, "\nbool %s::qt_property( int id, int f, TQVariant* v)\n{\n", qualifiedClassName().data() );
+
+ if ( !g->props.isEmpty() ) {
+ fprintf( out, " switch ( id - staticMetaObject()->propertyOffset() ) {\n" );
+ int propindex = -1;
+ bool need_resolve = FALSE;
+
+ for( TQPtrListIterator<Property> it( g->props ); it.current(); ++it ){
+ propindex ++;
+ fprintf( out, " case %d: ", propindex );
+ fprintf( out, "switch( f ) {\n" );
+
+ uint flag_break = 0;
+ uint flag_propagate = 0;
+
+ if ( it.current()->setfunc ) {
+ fprintf( out, "\tcase 0: %s(", it.current()->setfunc->name.data() );
+ TQCString type = it.current()->type.copy(); // detach on purpose
+ if ( it.current()->oredEnum )
+ type = it.current()->enumsettype;
+ if ( type == "uint" )
+ fprintf( out, "v->asUInt()" );
+ else if ( type == "unsigned int" )
+ fprintf( out, "(uint)v->asUInt()" );
+ else if ( type == "TQMap<TQString,TQVariant>" )
+ fprintf( out, "v->asMap()" );
+ else if ( type == "TQValueList<TQVariant>" )
+ fprintf( out, "v->asList()" );
+ else if ( type == "TQ_LLONG" )
+ fprintf( out, "v->asLongLong()" );
+ else if ( type == "TQ_ULLONG" )
+ fprintf( out, "v->asULongLong()" );
+ else if ( isVariantType( type ) ) {
+ if (( type[0] == 'T' ) && ( type[1] == 'Q' ))
+ type = type.mid(2);
+ else
+ type[0] = toupper( type[0] );
+ fprintf( out, "v->as%s()", type.data() );
+ } else {
+ fprintf( out, "(%s&)v->asInt()", type.data() );
+ }
+ fprintf( out, "); break;\n" );
+
+ } else if ( it.current()->override ) {
+ flag_propagate |= 1 << (0+1);
+ }
+ if ( it.current()->getfunc ) {
+ if ( it.current()->gspec == Property::Pointer )
+ fprintf( out, "\tcase 1: if ( this->%s() ) *v = TQVariant( %s*%s()%s ); break;\n",
+ it.current()->getfunc->name.data(),
+ !isVariantType( it.current()->type ) ? "(int)" : "",
+ it.current()->getfunc->name.data(),
+ it.current()->type == "bool" ? ", 0" : "" );
+ else
+ fprintf( out, "\tcase 1: *v = TQVariant( %sthis->%s()%s ); break;\n",
+ !isVariantType( it.current()->type ) ? "(int)" : "",
+ it.current()->getfunc->name.data(),
+ it.current()->type == "bool" ? ", 0" : "" );
+ } else if ( it.current()->override ) {
+ flag_propagate |= 1<< (1+1);
+ }
+
+ if ( !it.current()->reset.isEmpty() )
+ fprintf( out, "\tcase 2: this->%s(); break;\n", it.current()->reset.data() );
+
+ if ( it.current()->designable.isEmpty() )
+ flag_propagate |= 1 << (3+1);
+ else if ( it.current()->designable == "true" )
+ flag_break |= 1 << (3+1);
+ else if ( it.current()->designable != "false" )
+ fprintf( out, "\tcase 3: return this->%s();\n", it.current()->designable.data() );
+
+ if ( it.current()->scriptable.isEmpty() )
+ flag_propagate |= 1 << (4+1);
+ else if ( it.current()->scriptable == "true" )
+ flag_break |= 1 << (4+1);
+ else if ( it.current()->scriptable != "false" )
+ fprintf( out, "\tcase 4: return this->%s();\n", it.current()->scriptable.data() );
+
+ if ( it.current()->stored.isEmpty() )
+ flag_propagate |= 1 << (5+1);
+ else if ( it.current()->stored == "true" )
+ flag_break |= 1 << (5+1);
+ else if ( it.current()->stored != "false" )
+ fprintf( out, "\tcase 5: return this->%s();\n", it.current()->stored.data() );
+
+ int i = 0;
+ if ( flag_propagate != 0 ) {
+ fprintf( out, "\t" );
+ for ( i = 0; i <= 5; i++ ) {
+ if ( flag_propagate & (1 << (i+1) ) )
+ fprintf( out, "case %d: ", i );
+ }
+ if (!g->superClassName.isEmpty() && !isTQObject ) {
+ fprintf( out, "goto resolve;\n" );
+ need_resolve = TRUE;
+ } else {
+ fprintf( out, " return FALSE;\n" );
+ }
+ }
+ if ( flag_break != 0 ) {
+ fprintf( out, "\t" );
+ for ( i = 0; i <= 5; i++ ) {
+ if ( flag_break & (1 << (i+1) ) )
+ fprintf( out, "case %d: ", i );
+ }
+ fprintf( out, "break;\n");
+ }
+
+ fprintf( out, "\tdefault: return FALSE;\n } break;\n" );
+ }
+ fprintf( out, " default:\n" );
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, "\treturn %sqt_property( id, f, v );\n",
+ (const char *) callablePurestSuperClassName() );
+ else
+ fprintf( out, "\treturn FALSE;\n" );
+ fprintf( out, " }\n" );
+ fprintf( out, " return TRUE;\n" );
+
+ if ( need_resolve )
+ fprintf( out, "resolve:\n return %sqt_property( staticMetaObject()->resolveProperty(id), f, v );\n",
+ (const char *) callablePurestSuperClassName() );
+ fprintf( out, "}\n" );
+ } else {
+ if ( !g->superClassName.isEmpty() && !isTQObject )
+ fprintf( out, " return %sqt_property( id, f, v);\n}\n",
+ (const char *) callablePurestSuperClassName() );
+ else
+ fprintf( out, " return FALSE;\n}\n" );
+ }
+
+ fprintf( out, "\nbool %s::qt_static_property( TQObject* , int , int , TQVariant* ){ return FALSE; }\n", qualifiedClassName().data() );
+ fprintf( out, "#endif // TQT_NO_PROPERTIES\n" );
+}
+
+
+ArgList *addArg( Argument *a ) // add argument to list
+{
+ if ( (!a->leftType.isEmpty() || !a->rightType.isEmpty() ) ) //filter out truely void arguments
+ tmpArgList->append( a );
+ return tmpArgList;
+}
+
+void addEnum()
+{
+ // Avoid duplicates
+ for( TQPtrListIterator<Enum> lit( g->enums ); lit.current(); ++lit ) {
+ if ( lit.current()->name == tmpEnum->name )
+ {
+ if ( displayWarnings )
+ tqmoc_err( "Enum %s defined twice.", (const char*)tmpEnum->name );
+ }
+ }
+
+ // Only look at types mentioned in TQ_ENUMS and TQ_SETS
+ if ( g->qtEnums.tqcontains( tmpEnum->name ) || g->qtSets.tqcontains( tmpEnum->name ) )
+ {
+ g->enums.append( tmpEnum );
+ if ( g->qtSets.tqcontains( tmpEnum->name ) )
+ tmpEnum->set = TRUE;
+ else
+ tmpEnum->set = FALSE;
+ }
+ else
+ delete tmpEnum;
+ tmpEnum = new Enum;
+}
+
+void addMember( Member m )
+{
+ if ( skipFunc ) {
+ tmpFunc->args = tmpArgList; // just to be sure
+ delete tmpFunc;
+ tmpArgList = new ArgList; // ugly but works
+ tmpFunc = new Function;
+ skipFunc = FALSE;
+ return;
+ }
+
+ tmpFunc->type = tmpFunc->type.simplifyWhiteSpace();
+ tmpFunc->access = tmpAccess;
+ tmpFunc->args = tmpArgList;
+ tmpFunc->lineNo = lineNo;
+
+ for ( ;; ) {
+ g->funcs.append( tmpFunc );
+
+ if ( m == SignalMember ) {
+ g->tqsignals.append( tmpFunc );
+ break;
+ } else {
+ if ( m == SlotMember )
+ g->tqslots.append( tmpFunc );
+ // PropertyCandidateMember or SlotMember
+ if ( !tmpFunc->name.isEmpty() && tmpFunc->access == Public )
+ g->propfuncs.append( tmpFunc );
+ if ( !tmpFunc->args || !tmpFunc->args->hasDefaultArguments() )
+ break;
+ tmpFunc = new Function( *tmpFunc );
+ tmpFunc->args = tmpFunc->args->magicClone();
+ }
+ }
+
+ skipFunc = FALSE;
+ tmpFunc = new Function;
+ tmpArgList = new ArgList;
+}
+
+void checkPropertyName( const char* ident )
+{
+ if ( ident[0] == '_' ) {
+ tqmoc_err( "Invalid property name '%s'.", ident );
+ return;
+ }
+}
+
diff --git a/tqtinterface/qt4/src/tqmoc/tqmoc_yacc.h b/tqtinterface/qt4/src/tqmoc/tqmoc_yacc.h
new file mode 100644
index 0000000..553aa66
--- /dev/null
+++ b/tqtinterface/qt4/src/tqmoc/tqmoc_yacc.h
@@ -0,0 +1,185 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ CHAR_VAL = 258,
+ INT_VAL = 259,
+ DOUBLE_VAL = 260,
+ STRING = 261,
+ IDENTIFIER = 262,
+ FRIEND = 263,
+ TYPEDEF = 264,
+ AUTO = 265,
+ REGISTER = 266,
+ STATIC = 267,
+ EXTERN = 268,
+ INLINE = 269,
+ VIRTUAL = 270,
+ CONST = 271,
+ VOLATILE = 272,
+ CHAR = 273,
+ SHORT = 274,
+ INT = 275,
+ LONG = 276,
+ SIGNED = 277,
+ UNSIGNED = 278,
+ FLOAT = 279,
+ DOUBLE = 280,
+ VOID = 281,
+ ENUM = 282,
+ CLASS = 283,
+ STRUCT = 284,
+ UNION = 285,
+ ASM = 286,
+ PRIVATE = 287,
+ PROTECTED = 288,
+ PUBLIC = 289,
+ OPERATOR = 290,
+ DBL_COLON = 291,
+ TRIPLE_DOT = 292,
+ TEMPLATE = 293,
+ NAMESPACE = 294,
+ USING = 295,
+ MUTABLE = 296,
+ THROW = 297,
+ SIGNALS = 298,
+ SLOTS = 299,
+ TQ_OBJECT = 300,
+ Q_PROPERTY = 301,
+ TQ_OVERRIDE = 302,
+ TQ_CLASSINFO = 303,
+ TQ_ENUMS = 304,
+ TQ_SETS = 305,
+ READ = 306,
+ WRITE = 307,
+ STORED = 308,
+ DESIGNABLE = 309,
+ SCRIPTABLE = 310,
+ RESET = 311
+ };
+#endif
+/* Tokens. */
+#define CHAR_VAL 258
+#define INT_VAL 259
+#define DOUBLE_VAL 260
+#define STRING 261
+#define IDENTIFIER 262
+#define FRIEND 263
+#define TYPEDEF 264
+#define AUTO 265
+#define REGISTER 266
+#define STATIC 267
+#define EXTERN 268
+#define INLINE 269
+#define VIRTUAL 270
+#define CONST 271
+#define VOLATILE 272
+#define CHAR 273
+#define SHORT 274
+#define INT 275
+#define LONG 276
+#define SIGNED 277
+#define UNSIGNED 278
+#define FLOAT 279
+#define DOUBLE 280
+#define VOID 281
+#define ENUM 282
+#define CLASS 283
+#define STRUCT 284
+#define UNION 285
+#define ASM 286
+#define PRIVATE 287
+#define PROTECTED 288
+#define PUBLIC 289
+#define OPERATOR 290
+#define DBL_COLON 291
+#define TRIPLE_DOT 292
+#define TEMPLATE 293
+#define NAMESPACE 294
+#define USING 295
+#define MUTABLE 296
+#define THROW 297
+#define SIGNALS 298
+#define SLOTS 299
+#define TQ_OBJECT 300
+#define Q_PROPERTY 301
+#define TQ_OVERRIDE 302
+#define TQ_CLASSINFO 303
+#define TQ_ENUMS 304
+#define TQ_SETS 305
+#define READ 306
+#define WRITE 307
+#define STORED 308
+#define DESIGNABLE 309
+#define SCRIPTABLE 310
+#define RESET 311
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 1676 of yacc.c */
+#line 692 "tqmoc.y"
+
+ char char_val;
+ int int_val;
+ double double_val;
+ char *string;
+ Access access;
+ Function *function;
+ ArgList *arg_list;
+ Argument *arg;
+
+
+
+/* Line 1676 of yacc.c */
+#line 177 "tqmoc_yacc.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+extern YYSTYPE yylval;
+
+
diff --git a/tqtinterface/qt4/src/widgets/qt_widgets.pri b/tqtinterface/qt4/src/widgets/qt_widgets.pri
new file mode 100644
index 0000000..8f614fd
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/qt_widgets.pri
@@ -0,0 +1,139 @@
+# Qt widgets module
+
+widgets {
+ WIDGETS_P = widgets
+
+ HEADERS += $$WIDGETS_H/tqbuttongroup.h \
+ $$WIDGETS_H/tqbutton.h \
+ $$WIDGETS_P/tqdialogbuttons_p.h \
+ $$WIDGETS_H/tqcheckbox.h \
+ $$WIDGETS_H/tqcombobox.h \
+ $$WIDGETS_P/tqwidgetresizehandler_p.h \
+ $$WIDGETS_H/tqdial.h \
+ $$WIDGETS_H/tqdockarea.h \
+ $$WIDGETS_H/tqdockwindow.h \
+ $$WIDGETS_H/tqframe.h \
+ $$WIDGETS_H/tqgrid.h \
+ $$WIDGETS_H/tqgridview.h \
+ $$WIDGETS_H/tqgroupbox.h \
+ $$WIDGETS_H/tqhbuttongroup.h \
+ $$WIDGETS_H/tqheader.h \
+ $$WIDGETS_H/tqhgroupbox.h \
+ $$WIDGETS_H/tqhbox.h \
+ $$WIDGETS_H/tqlabel.h \
+ $$WIDGETS_H/tqlcdnumber.h \
+ $$WIDGETS_H/tqlineedit.h \
+ $$WIDGETS_H/tqlistbox.h \
+ $$WIDGETS_H/tqlistview.h \
+ $$WIDGETS_H/tqmainwindow.h \
+ $$WIDGETS_H/tqmenubar.h \
+ $$WIDGETS_H/tqmenudata.h \
+ $$WIDGETS_H/tqmultilineedit.h \
+ $$WIDGETS_H/tqpopupmenu.h \
+ $$WIDGETS_H/tqprogressbar.h \
+ $$WIDGETS_H/tqpushbutton.h \
+ $$WIDGETS_H/tqradiobutton.h \
+ $$WIDGETS_H/tqrangecontrol.h \
+ $$WIDGETS_H/tqscrollbar.h \
+ $$WIDGETS_H/tqscrollview.h \
+ $$WIDGETS_H/tqslider.h \
+ $$WIDGETS_H/tqsplashscreen.h \
+ $$WIDGETS_H/tqspinbox.h \
+ $$WIDGETS_H/tqsplitter.h \
+ $$WIDGETS_H/tqstatusbar.h \
+ $$WIDGETS_H/tqtabbar.h \
+ $$WIDGETS_H/tqsyntaxhighlighter.h \
+ $$WIDGETS_P/tqsyntaxhighlighter_p.h \
+ $$WIDGETS_H/tqtabwidget.h \
+ $$WIDGETS_P/tqtitlebar_p.h \
+ $$WIDGETS_H/tqtoolbar.h \
+ $$WIDGETS_H/tqtoolbox.h \
+ $$WIDGETS_H/tqtoolbutton.h \
+ $$WIDGETS_H/tqtooltip.h \
+ $$WIDGETS_H/tqvalidator.h \
+ $$WIDGETS_H/tqvbox.h \
+ $$WIDGETS_H/tqvbuttongroup.h \
+ $$WIDGETS_H/tqvgroupbox.h \
+ $$WIDGETS_H/tqwhatsthis.h \
+ $$WIDGETS_H/tqwidgetstack.h \
+ $$WIDGETS_H/tqaction.h \
+ $$WIDGETS_H/tqdatetimeedit.h \
+ $$WIDGETS_H/tqtextview.h \
+ $$WIDGETS_H/tqtextbrowser.h \
+ $$WIDGETS_H/tqtextedit.h \
+ $$WIDGETS_P/tqwidgetinterface_p.h \
+ $$WIDGETS_H/tqwidgetplugin.h
+
+ SOURCES += $$WIDGETS_CPP/tqbuttongroup.cpp \
+ $$WIDGETS_CPP/tqbutton.cpp \
+ $$WIDGETS_CPP/tqdialogbuttons.cpp \
+ $$WIDGETS_CPP/tqcheckbox.cpp \
+ $$WIDGETS_CPP/tqcombobox.cpp \
+ $$WIDGETS_CPP/tqwidgetresizehandler.cpp \
+ $$WIDGETS_CPP/tqdial.cpp \
+ $$WIDGETS_CPP/tqdockarea.cpp \
+ $$WIDGETS_CPP/tqdockwindow.cpp \
+ $$WIDGETS_CPP/tqframe.cpp \
+ $$WIDGETS_CPP/tqgrid.cpp \
+ $$WIDGETS_CPP/tqgridview.cpp \
+ $$WIDGETS_CPP/tqgroupbox.cpp \
+ $$WIDGETS_CPP/tqhbuttongroup.cpp \
+ $$WIDGETS_CPP/tqheader.cpp \
+ $$WIDGETS_CPP/tqhgroupbox.cpp \
+ $$WIDGETS_CPP/tqhbox.cpp \
+ $$WIDGETS_CPP/tqlabel.cpp \
+ $$WIDGETS_CPP/tqlcdnumber.cpp \
+ $$WIDGETS_CPP/tqlineedit.cpp \
+ $$WIDGETS_CPP/tqlistbox.cpp \
+ $$WIDGETS_CPP/tqlistview.cpp \
+ $$WIDGETS_CPP/tqmainwindow.cpp \
+ $$WIDGETS_CPP/tqmenubar.cpp \
+ $$WIDGETS_CPP/tqmenudata.cpp \
+ $$WIDGETS_CPP/tqmultilineedit.cpp \
+ $$WIDGETS_CPP/tqpopupmenu.cpp \
+ $$WIDGETS_CPP/tqprogressbar.cpp \
+ $$WIDGETS_CPP/tqpushbutton.cpp \
+ $$WIDGETS_CPP/tqradiobutton.cpp \
+ $$WIDGETS_CPP/tqrangecontrol.cpp \
+ $$WIDGETS_CPP/tqscrollbar.cpp \
+ $$WIDGETS_CPP/tqscrollview.cpp \
+ $$WIDGETS_CPP/tqslider.cpp \
+ $$WIDGETS_CPP/tqsplashscreen.cpp \
+ $$WIDGETS_CPP/tqspinbox.cpp \
+ $$WIDGETS_CPP/tqspinwidget.cpp \
+ $$WIDGETS_CPP/tqsplitter.cpp \
+ $$WIDGETS_CPP/tqstatusbar.cpp \
+ $$WIDGETS_CPP/tqsyntaxhighlighter.cpp \
+ $$WIDGETS_CPP/tqtabbar.cpp \
+ $$WIDGETS_CPP/tqtabwidget.cpp \
+ $$WIDGETS_CPP/tqtitlebar.cpp \
+ $$WIDGETS_CPP/tqtoolbar.cpp \
+ $$WIDGETS_CPP/tqtoolbox.cpp \
+ $$WIDGETS_CPP/tqtoolbutton.cpp \
+ $$WIDGETS_CPP/tqtooltip.cpp \
+ $$WIDGETS_CPP/tqvalidator.cpp \
+ $$WIDGETS_CPP/tqvbox.cpp \
+ $$WIDGETS_CPP/tqvbuttongroup.cpp \
+ $$WIDGETS_CPP/tqvgroupbox.cpp \
+ $$WIDGETS_CPP/tqwhatsthis.cpp \
+ $$WIDGETS_CPP/tqwidgetstack.cpp \
+ $$WIDGETS_CPP/tqaction.cpp \
+ $$WIDGETS_CPP/tqdatetimeedit.cpp \
+ $$WIDGETS_CPP/tqeffects.cpp \
+ $$WIDGETS_CPP/tqtextview.cpp \
+ $$WIDGETS_CPP/tqtextbrowser.cpp \
+ $$WIDGETS_CPP/tqtextedit.cpp \
+ $$WIDGETS_CPP/tqwidgetplugin.cpp
+ !embedded:mac:SOURCES += $$WIDGETS_CPP/tqmenubar_mac.cpp
+}
+
+wince-* {
+ SOURCES += $$WIDGETS_CPP/ce/tqcemainwindow.cpp
+ HEADERS += $$WIDGETS_H/ce/tqcemainwindow.h
+
+ SOURCES -= $$WIDGETS_CPP/tqsyntaxhighlighter.cpp \
+ $$WIDGETS_CPP/tqsplashscreen.cpp
+
+ HEADERS -= $$WIDGETS_H/tqsyntaxhighlighter.h \
+ $$WIDGETS_H/tqsplashscreen.h
+}
diff --git a/tqtinterface/qt4/src/widgets/tqaction.cpp b/tqtinterface/qt4/src/widgets/tqaction.cpp
new file mode 100644
index 0000000..8ffa773
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqaction.cpp
@@ -0,0 +1,2145 @@
+/****************************************************************************
+**
+** Implementation of TQAction class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqaction.h"
+
+#ifndef TQT_NO_ACTION
+
+#include "tqtoolbar.h"
+#include "tqptrlist.h"
+#include "tqpopupmenu.h"
+#include "tqaccel.h"
+#include "tqtoolbutton.h"
+#include "tqcombobox.h"
+#include "tqtooltip.h"
+#include "tqwhatsthis.h"
+#include "tqstatusbar.h"
+#include "tqobjectlist.h"
+
+
+/*!
+ \class TQAction tqaction.h
+ \brief The TQAction class provides an abstract user interface
+ action that can appear both in menus and tool bars.
+
+ \ingroup basic
+ \ingroup application
+ \mainclass
+
+ In GUI applications many commands can be invoked via a menu
+ option, a toolbar button and a keyboard accelerator. Since the
+ same action must be performed regardless of how the action was
+ invoked, and since the menu and toolbar should be kept in sync, it
+ is useful to represent a command as an \e action. An action can be
+ added to a menu and a toolbar and will automatically keep them in
+ sync. For example, if the user presses a Bold toolbar button the
+ Bold menu item will automatically be checked.
+
+ A TQAction may contain an icon, a menu text, an accelerator, a
+ status text, a whats this text and a tool tip. Most of these can
+ be set in the constructor. They can also be set independently with
+ setIconSet(), setText(), setMenuText(), setToolTip(),
+ setStatusTip(), setWhatsThis() and setAccel().
+
+ An action may be a toggle action e.g. a Bold toolbar button, or a
+ command action, e.g. 'Open File' to invoke an open file dialog.
+ Toggle actions emit the toggled() signal when their state changes.
+ Both command and toggle actions emit the activated() signal when
+ they are invoked. Use setToggleAction() to set an action's toggled
+ status. To see if an action is a toggle action use
+ isToggleAction(). A toggle action may be "on", isOn() returns
+ TRUE, or "off", isOn() returns FALSE.
+
+ Actions are added to widgets (menus or toolbars) using addTo(),
+ and removed using removeFrom().
+
+ Once a TQAction has been created it should be added to the relevant
+ menu and toolbar and then connected to the slot which will perform
+ the action. For example:
+
+ \quotefile action/application.cpp
+ \skipto TQPixmap( fileopen
+ \printuntil connect
+
+ We create a "File Save" action with a menu text of "&Save" and
+ \e{Ctrl+S} as the keyboard accelerator. We connect the
+ fileSaveAction's activated() signal to our own save() slot. Note
+ that at this point there is no menu or toolbar action, we'll add
+ them next:
+
+ \skipto new TQToolBar
+ \printline
+ \skipto fileSaveAction->addTo
+ \printline
+ \skipto new TQPopupMenu
+ \printuntil insertItem
+ \skipto fileSaveAction->addTo
+ \printline
+
+ We create a toolbar and add our fileSaveAction to it. Similarly we
+ create a menu, add a top-level menu item, and add our
+ fileSaveAction.
+
+ We recommend that actions are created as tqchildren of the window
+ that they are used in. In most cases actions will be tqchildren of
+ the application's main window.
+
+ To prevent recursion, don't create an action as a child of a
+ widget that the action is later added to.
+*/
+
+class TQActionPrivate
+{
+public:
+ TQActionPrivate(TQAction *act);
+ ~TQActionPrivate();
+ TQIconSet *iconset;
+ TQString text;
+ TQString menutext;
+ TQString tooltip;
+ TQString statustip;
+ TQString whatsthis;
+#ifndef TQT_NO_ACCEL
+ TQKeySequence key;
+ TQAccel* accel;
+ int accelid;
+#endif
+ uint enabled : 1;
+ uint visible : 1;
+ uint toggleaction : 1;
+ uint on : 1;
+ uint forceDisabled : 1;
+ uint forceInvisible : 1;
+#ifndef TQT_NO_TOOLTIP
+ TQToolTipGroup tipGroup;
+#endif
+ TQActionGroupPrivate* d_group;
+ TQAction *action;
+
+ struct MenuItem {
+ MenuItem():popup(0),id(0){}
+ TQPopupMenu* popup;
+ int id;
+ };
+ // ComboItem is only necessary for actions that are
+ // in dropdown/exclusive actiongroups. The actiongroup
+ // will clean this up
+ struct ComboItem {
+ ComboItem():combo(0), id(0) {}
+ TQComboBox *combo;
+ int id;
+ };
+ TQPtrList<MenuItem> menuitems;
+ TQPtrList<TQToolButton> toolbuttons;
+ TQPtrList<ComboItem> comboitems;
+
+ enum Update { Icons = 1, Visibility = 2, State = 4, EverythingElse = 8 };
+ void update( uint upd = EverythingElse );
+
+ TQString menuText() const;
+ TQString toolTip() const;
+ TQString statusTip() const;
+};
+
+TQActionPrivate::TQActionPrivate(TQAction *act)
+ : iconset( 0 ),
+#ifndef TQT_NO_ACCEL
+ key( 0 ), accel( 0 ), accelid( 0 ),
+#endif
+ enabled( TRUE ), visible( TRUE ), toggleaction( FALSE ), on( FALSE ),
+ forceDisabled( FALSE ), forceInvisible( FALSE ),
+#ifndef TQT_NO_TOOLTIP
+ tipGroup( 0 ),
+#endif
+ d_group( 0 ), action(act)
+{
+ menuitems.setAutoDelete( TRUE );
+ comboitems.setAutoDelete( TRUE );
+#ifndef TQT_NO_TOOLTIP
+ tipGroup.setDelay( FALSE );
+#endif
+}
+
+TQActionPrivate::~TQActionPrivate()
+{
+ TQPtrListIterator<TQToolButton> ittb( toolbuttons );
+ TQToolButton *tb;
+
+ while ( ( tb = ittb.current() ) ) {
+ ++ittb;
+ delete tb;
+ }
+
+ TQPtrListIterator<TQActionPrivate::MenuItem> itmi( menuitems);
+ TQActionPrivate::MenuItem* mi;
+ while ( ( mi = itmi.current() ) ) {
+ ++itmi;
+ TQPopupMenu* menu = mi->popup;
+ if ( menu->tqfindItem( mi->id ) )
+ menu->removeItem( mi->id );
+ }
+
+ TQPtrListIterator<TQActionPrivate::ComboItem> itci(comboitems);
+ TQActionPrivate::ComboItem* ci;
+ while ( ( ci = itci.current() ) ) {
+ ++itci;
+ TQComboBox* combo = ci->combo;
+ combo->clear();
+ TQActionGroup *group = ::tqqt_cast<TQActionGroup*>(action->tqparent());
+ TQObjectList *siblings = group ? group->queryList("TQAction") : 0;
+ if (siblings) {
+ TQObjectListIt it(*siblings);
+ while (it.current()) {
+ TQAction *sib = ::tqqt_cast<TQAction*>(it.current());
+ ++it;
+ sib->removeFrom(combo);
+ }
+ it = TQObjectListIt(*siblings);
+ while (it.current()) {
+ TQAction *sib = ::tqqt_cast<TQAction*>(it.current());
+ ++it;
+ if (sib == action)
+ continue;
+ sib->addTo(combo);
+ }
+ }
+ delete siblings;
+ }
+
+#ifndef TQT_NO_ACCEL
+ delete accel;
+#endif
+ delete iconset;
+}
+
+class TQActionGroupPrivate
+{
+public:
+ uint exclusive: 1;
+ uint dropdown: 1;
+ TQPtrList<TQAction> actions;
+ TQAction* selected;
+ TQAction* separatorAction;
+
+ struct MenuItem {
+ MenuItem():popup(0),id(0){}
+ TQPopupMenu* popup;
+ int id;
+ };
+
+ TQPtrList<TQComboBox> comboboxes;
+ TQPtrList<TQToolButton> menubuttons;
+ TQPtrList<MenuItem> menuitems;
+ TQPtrList<TQPopupMenu> popupmenus;
+
+ void update( const TQActionGroup * );
+};
+
+void TQActionPrivate::update( uint upd )
+{
+ for ( TQPtrListIterator<MenuItem> it( menuitems); it.current(); ++it ) {
+ MenuItem* mi = it.current();
+ TQString t = menuText();
+#ifndef TQT_NO_ACCEL
+ if ( key )
+ t += '\t' + TQAccel::keyToString( key );
+#endif
+ if ( upd & State ) {
+ mi->popup->setItemEnabled( mi->id, enabled );
+ if ( toggleaction )
+ mi->popup->setItemChecked( mi->id, on );
+ }
+ if ( upd & Visibility )
+ mi->popup->setItemVisible( mi->id, visible );
+
+ if ( upd & Icons ) {
+ if ( iconset )
+ mi->popup->changeItem( mi->id, *iconset, t );
+ else
+ mi->popup->changeItem( mi->id, TQIconSet(), t );
+ }
+ if ( upd & EverythingElse ) {
+ mi->popup->changeItem( mi->id, t );
+ if ( !whatsthis.isEmpty() )
+ mi->popup->TQMenuData::setWhatsThis( mi->id, whatsthis );
+ if ( toggleaction ) {
+ mi->popup->setCheckable( TRUE );
+ mi->popup->setItemChecked( mi->id, on );
+ }
+ }
+ }
+ for ( TQPtrListIterator<TQToolButton> it2(toolbuttons); it2.current(); ++it2 ) {
+ TQToolButton* btn = it2.current();
+ if ( upd & State ) {
+ btn->setEnabled( enabled );
+ if ( toggleaction )
+ btn->setOn( on );
+ }
+ if ( upd & Visibility )
+ visible ? btn->show() : btn->hide();
+ if ( upd & Icons ) {
+ if ( iconset )
+ btn->setIconSet( *iconset );
+ else
+ btn->setIconSet( TQIconSet() );
+ }
+ if ( upd & EverythingElse ) {
+ btn->setToggleButton( toggleaction );
+ if ( !text.isEmpty() )
+ btn->setTextLabel( text, FALSE );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::remove( btn );
+ TQToolTip::add( btn, toolTip(), &tipGroup, statusTip() );
+#endif
+#ifndef TQT_NO_WHATSTHIS
+ TQWhatsThis::remove( btn );
+ if ( !whatsthis.isEmpty() )
+ TQWhatsThis::add( btn, whatsthis );
+#endif
+ }
+ }
+#ifndef TQT_NO_ACCEL
+ if ( accel ) {
+ accel->setEnabled( enabled && visible );
+ if ( !whatsthis.isEmpty() )
+ accel->setWhatsThis( accelid, whatsthis );
+ }
+#endif
+ // Only used by actiongroup
+ for ( TQPtrListIterator<ComboItem> it3( comboitems ); it3.current(); ++it3 ) {
+ ComboItem *ci = it3.current();
+ if ( !ci->combo )
+ return;
+ if ( iconset )
+ ci->combo->changeItem( iconset->pixmap(), text, ci->id );
+ else
+ ci->combo->changeItem( text, ci->id );
+ }
+}
+
+TQString TQActionPrivate::menuText() const
+{
+ if ( menutext.isNull() ) {
+ TQString t(text);
+ t.tqreplace('&', "&&");
+ return t;
+ }
+ return menutext;
+}
+
+TQString TQActionPrivate::toolTip() const
+{
+ if ( tooltip.isNull() ) {
+#ifndef TQT_NO_ACCEL
+ if ( accel )
+ return text + " (" + TQAccel::keyToString( accel->key( accelid )) + ")";
+#endif
+ return text;
+ }
+ return tooltip;
+}
+
+TQString TQActionPrivate::statusTip() const
+{
+ if ( statustip.isNull() )
+ return toolTip();
+ return statustip;
+}
+
+/*
+ internal: guesses a descriptive text from a menu text
+ */
+static TQString qt_stripMenuText( TQString s )
+{
+ s.remove( TQString::tqfromLatin1("...") );
+ s.remove( TQChar('&' ) );
+ return s.stripWhiteSpace();
+}
+
+/*!
+ Constructs an action called \a name with tqparent \a tqparent.
+
+ If \a tqparent is a TQActionGroup, the new action inserts itself into
+ \a tqparent.
+
+ For accelerators and status tips to work, \a tqparent must either be
+ a widget, or an action group whose tqparent is a widget.
+
+ \warning To prevent recursion, don't create an action as a child
+ of a widget that the action is later added to.
+*/
+TQAction::TQAction( TQT_BASE_OBJECT_NAME* tqparent, const char* name )
+ : TQObject( TQT_TQOBJECT(tqparent), name )
+{
+ d = new TQActionPrivate(this);
+ init();
+}
+
+/*! \obsolete
+ Constructs an action called \a name with tqparent \a tqparent.
+
+ If \a toggle is TRUE the action will be a toggle action, otherwise
+ it will be a command action.
+
+ If \a tqparent is a TQActionGroup, the new action inserts itself into
+ \a tqparent.
+
+ For accelerators and status tips to work, \a tqparent must either be
+ a widget, or an action group whose tqparent is a widget.
+*/
+TQAction::TQAction( TQT_BASE_OBJECT_NAME* tqparent, const char* name, bool toggle )
+ : TQObject( TQT_TQOBJECT(tqparent), name )
+{
+ d = new TQActionPrivate(this);
+ d->toggleaction = toggle;
+ init();
+}
+
+
+#ifndef TQT_NO_ACCEL
+
+/*!
+ This constructor creates an action with the following properties:
+ the icon or iconset \a icon, the menu text \a menuText and
+ keyboard accelerator \a accel. It is a child of \a tqparent and
+ called \a name.
+
+ If \a tqparent is a TQActionGroup, the action automatically becomes
+ a member of it.
+
+ For accelerators and status tips to work, \a tqparent must either be
+ a widget, or an action group whose tqparent is a widget.
+
+ The action uses a stripped version of \a menuText (e.g. "\&Menu
+ Option..." becomes "Menu Option") as descriptive text for
+ toolbuttons. You can override this by setting a specific
+ description with setText(). The same text and \a accel will be
+ used for tool tips and status tips unless you provide text for
+ these using setToolTip() and setStatusTip().
+
+ Call setToggleAction(TRUE) to make the action a toggle action.
+
+ \warning To prevent recursion, don't create an action as a child
+ of a widget that the action is later added to.
+*/
+TQAction::TQAction( const TQIconSet& icon, const TQString& menuText, TQKeySequence accel,
+ TQT_BASE_OBJECT_NAME* tqparent, const char* name )
+ : TQObject( TQT_TQOBJECT(tqparent), name )
+{
+ d = new TQActionPrivate(this);
+ if ( !icon.isNull() )
+ setIconSet( icon );
+ d->text = qt_stripMenuText( menuText );
+ d->menutext = menuText;
+ setAccel( accel );
+ init();
+}
+
+/*!
+ This constructor results in an icon-less action with the the menu
+ text \a menuText and keyboard accelerator \a accel. It is a child
+ of \a tqparent and called \a name.
+
+ If \a tqparent is a TQActionGroup, the action automatically becomes
+ a member of it.
+
+ For accelerators and status tips to work, \a tqparent must either be
+ a widget, or an action group whose tqparent is a widget.
+
+ The action uses a stripped version of \a menuText (e.g. "\&Menu
+ Option..." becomes "Menu Option") as descriptive text for
+ toolbuttons. You can override this by setting a specific
+ description with setText(). The same text and \a accel will be
+ used for tool tips and status tips unless you provide text for
+ these using setToolTip() and setStatusTip().
+
+ Call setToggleAction(TRUE) to make the action a toggle action.
+
+ \warning To prevent recursion, don't create an action as a child
+ of a widget that the action is later added to.
+*/
+TQAction::TQAction( const TQString& menuText, TQKeySequence accel,
+ TQT_BASE_OBJECT_NAME* tqparent, const char* name )
+ : TQObject( TQT_TQOBJECT(tqparent), name )
+{
+ d = new TQActionPrivate(this);
+ d->text = qt_stripMenuText( menuText );
+ d->menutext = menuText;
+ setAccel( accel );
+ init();
+}
+
+/*! \obsolete
+ This constructor creates an action with the following properties:
+ the description \a text, the icon or iconset \a icon, the menu
+ text \a menuText and keyboard accelerator \a accel. It is a child
+ of \a tqparent and called \a name. If \a toggle is TRUE the action
+ will be a toggle action, otherwise it will be a command action.
+
+ If \a tqparent is a TQActionGroup, the action automatically becomes
+ a member of it.
+
+ For accelerators and status tips to work, \a tqparent must either be
+ a widget, or an action group whose tqparent is a widget.
+
+ The \a text and \a accel will be used for tool tips and status
+ tips unless you provide specific text for these using setToolTip()
+ and setStatusTip().
+*/
+TQAction::TQAction( const TQString& text, const TQIconSet& icon, const TQString& menuText, TQKeySequence accel, TQT_BASE_OBJECT_NAME* tqparent, const char* name, bool toggle )
+ : TQObject( TQT_TQOBJECT(tqparent), name )
+{
+ d = new TQActionPrivate(this);
+ d->toggleaction = toggle;
+ if ( !icon.isNull() )
+ setIconSet( icon );
+
+ d->text = text;
+ d->menutext = menuText;
+ setAccel( accel );
+ init();
+}
+
+/*! \obsolete
+ This constructor results in an icon-less action with the
+ description \a text, the menu text \a menuText and the keyboard
+ accelerator \a accel. Its tqparent is \a tqparent and it is called \a
+ name. If \a toggle is TRUE the action will be a toggle action,
+ otherwise it will be a command action.
+
+ The action automatically becomes a member of \a tqparent if \a
+ tqparent is a TQActionGroup.
+
+ For accelerators and status tips to work, \a tqparent must either be
+ a widget, or an action group whose tqparent is a widget.
+
+ The \a text and \a accel will be used for tool tips and status
+ tips unless you provide specific text for these using setToolTip()
+ and setStatusTip().
+*/
+TQAction::TQAction( const TQString& text, const TQString& menuText, TQKeySequence accel, TQT_BASE_OBJECT_NAME* tqparent, const char* name, bool toggle )
+ : TQObject( TQT_TQOBJECT(tqparent), name )
+{
+ d = new TQActionPrivate(this);
+ d->toggleaction = toggle;
+ d->text = text;
+ d->menutext = menuText;
+ setAccel( accel );
+ init();
+}
+#endif
+
+/*!
+ \internal
+*/
+void TQAction::init()
+{
+ if ( ::tqqt_cast<TQActionGroup*>(tqparent()) )
+ ((TQActionGroup*) tqparent())->add( this ); // insert into action group
+}
+
+/*!
+ Destroys the object and frees allocated resources.
+*/
+
+TQAction::~TQAction()
+{
+ delete d;
+}
+
+/*!
+ \property TQAction::iconSet
+ \brief the action's icon
+
+ The icon is used as the tool button icon and in the menu to the
+ left of the menu text. There is no default icon.
+
+ If a null icon (TQIconSet::isNull() is passed into this function,
+ the icon of the action is cleared.
+
+ (See the action/toggleaction/toggleaction.cpp example.)
+
+*/
+void TQAction::setIconSet( const TQIconSet& icon )
+{
+ register TQIconSet *i = d->iconset;
+ if ( !icon.isNull() )
+ d->iconset = new TQIconSet( icon );
+ else
+ d->iconset = 0;
+ delete i;
+ d->update( TQActionPrivate::Icons );
+}
+
+TQIconSet TQAction::iconSet() const
+{
+ if ( d->iconset )
+ return *d->iconset;
+ return TQIconSet();
+}
+
+/*!
+ \property TQAction::text
+ \brief the action's descriptive text
+
+ If \l TQMainWindow::usesTextLabel is TRUE, the text appears as a
+ label in the relevant tool button. It also serves as the default
+ text in menus and tool tips if these have not been specifically
+ defined. There is no default text.
+
+ \sa setMenuText() setToolTip() setStatusTip()
+*/
+void TQAction::setText( const TQString& text )
+{
+ d->text = text;
+ d->update();
+}
+
+TQString TQAction::text() const
+{
+ return d->text;
+}
+
+
+/*!
+ \property TQAction::menuText
+ \brief the action's menu text
+
+ If the action is added to a menu the menu option will consist of
+ the icon (if there is one), the menu text and the accelerator (if
+ there is one). If the menu text is not explicitly set in the
+ constructor or by using setMenuText() the action's description
+ text will be used as the menu text. There is no default menu text.
+
+ \sa text
+*/
+void TQAction::setMenuText( const TQString& text )
+{
+ if ( d->menutext == text )
+ return;
+
+ d->menutext = text;
+ d->update();
+}
+
+TQString TQAction::menuText() const
+{
+ return d->menuText();
+}
+
+/*!
+ \property TQAction::toolTip
+ \brief the action's tool tip
+
+ This text is used for the tool tip. If no status tip has been set
+ the tool tip will be used for the status tip.
+
+ If no tool tip is specified the action's text is used, and if that
+ hasn't been specified the description text is used as the tool tip
+ text.
+
+ There is no default tool tip text.
+
+ \sa setStatusTip() setAccel()
+*/
+void TQAction::setToolTip( const TQString& tip )
+{
+ if ( d->tooltip == tip )
+ return;
+
+ d->tooltip = tip;
+ d->update();
+}
+
+TQString TQAction::toolTip() const
+{
+ return d->toolTip();
+}
+
+/*!
+ \property TQAction::statusTip
+ \brief the action's status tip
+
+ The statusTip is displayed on all status bars that this action's
+ toplevel tqparent widget provides.
+
+ If no status tip is defined, the action uses the tool tip text.
+
+ There is no default statusTip text.
+
+ \sa setStatusTip() setToolTip()
+*/
+//#### Please reimp for TQActionGroup!
+//#### For consistency reasons even action groups should show
+//#### status tips (as they already do with tool tips)
+//#### Please change TQActionGroup class doc appropriately after
+//#### reimplementation.
+void TQAction::setStatusTip( const TQString& tip )
+{
+ if ( d->statustip == tip )
+ return;
+
+ d->statustip = tip;
+ d->update();
+}
+
+TQString TQAction::statusTip() const
+{
+ return d->statusTip();
+}
+
+/*!
+ \property TQAction::whatsThis
+ \brief the action's "What's This?" help text
+
+ The whats this text is used to provide a brief description of the
+ action. The text may contain rich text (HTML-like tags -- see
+ TQStyleSheet for the list of supported tags). There is no default
+ "What's This" text.
+
+ \sa TQWhatsThis
+*/
+void TQAction::setWhatsThis( const TQString& whatsThis )
+{
+ if ( d->whatsthis == whatsThis )
+ return;
+ d->whatsthis = whatsThis;
+ d->update();
+}
+
+TQString TQAction::whatsThis() const
+{
+ return d->whatsthis;
+}
+
+
+#ifndef TQT_NO_ACCEL
+/*!
+ \property TQAction::accel
+ \brief the action's accelerator key
+
+ The keycodes can be found in \l TQt::Key and \l TQt::Modifier. There
+ is no default accelerator key.
+*/
+//#### Please reimp for TQActionGroup!
+//#### For consistency reasons even TQActionGroups should respond to
+//#### their accelerators and e.g. open the relevant submenu.
+//#### Please change appropriate TQActionGroup class doc after
+//#### reimplementation.
+void TQAction::setAccel( const TQKeySequence& key )
+{
+ if ( d->key == key )
+ return;
+
+ d->key = key;
+ delete d->accel;
+ d->accel = 0;
+
+ if ( !(int)key ) {
+ d->update();
+ return;
+ }
+
+ TQObject* p = tqparent();
+ while ( p && !p->isWidgetType() ) {
+ p = p->tqparent();
+ }
+ if ( p ) {
+ d->accel = new TQAccel( (TQWidget*)p, this, "qt_action_accel" );
+ d->accelid = d->accel->insertItem( d->key );
+ d->accel->connectItem( d->accelid, this, TQT_SLOT( internalActivation() ) );
+ }
+#if defined(TQT_CHECK_STATE)
+ else
+ qWarning( "TQAction::setAccel() (%s) requires widget in tqparent chain", name() );
+#endif
+ d->update();
+}
+
+
+TQKeySequence TQAction::accel() const
+{
+ return d->key;
+}
+#endif
+
+
+/*!
+ \property TQAction::toggleAction
+ \brief whether the action is a toggle action
+
+ A toggle action is one which has an on/off state. For example a
+ Bold toolbar button is either on or off. An action which is not a
+ toggle action is a command action; a command action is simply
+ executed, e.g. file save. This property's default is FALSE.
+
+ In some situations, the state of one toggle action should depend
+ on the state of others. For example, "Left Align", "Center" and
+ "Right Align" toggle actions are mutually exclusive. To achieve
+ exclusive toggling, add the relevant toggle actions to a
+ TQActionGroup with the \l TQActionGroup::exclusive property set to
+ TRUE.
+*/
+void TQAction::setToggleAction( bool enable )
+{
+ if ( enable == (bool)d->toggleaction )
+ return;
+
+ if ( !enable )
+ d->on = FALSE;
+
+ d->toggleaction = enable;
+ d->update();
+}
+
+bool TQAction::isToggleAction() const
+{
+ return d->toggleaction;
+}
+
+/*!
+ Activates the action and executes all connected Q_SLOTS.
+ This only works for actions that are not toggle action.
+
+ \sa toggle()
+*/
+void TQAction::activate()
+{
+ if ( isToggleAction() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQAction::%s() (%s) Toggle actions "
+ "can not be activated", "activate", name() );
+#endif
+ return;
+ }
+ emit activated();
+}
+
+/*!
+ Toggles the state of a toggle action.
+
+ \sa on, activate(), toggled(), isToggleAction()
+*/
+void TQAction::toggle()
+{
+ if ( !isToggleAction() ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQAction::%s() (%s) Only toggle actions "
+ "can be switched", "toggle", name() );
+#endif
+ return;
+ }
+ setOn( !isOn() );
+}
+
+/*!
+ \property TQAction::on
+ \brief whether a toggle action is on
+
+ This property is always on (TRUE) for command actions and
+ \l{TQActionGroup}s; setOn() has no effect on them. For action's
+ where isToggleAction() is TRUE, this property's default value is
+ off (FALSE).
+
+ \sa toggleAction
+*/
+void TQAction::setOn( bool enable )
+{
+ if ( !isToggleAction() ) {
+#if defined(TQT_CHECK_STATE)
+ if ( enable )
+ qWarning( "TQAction::%s() (%s) Only toggle actions "
+ "can be switched", "setOn", name() );
+#endif
+ return;
+ }
+ if ( enable == (bool)d->on )
+ return;
+ d->on = enable;
+ d->update( TQActionPrivate::State );
+ emit toggled( enable );
+}
+
+bool TQAction::isOn() const
+{
+ return d->on;
+}
+
+/*!
+ \property TQAction::enabled
+ \brief whether the action is enabled
+
+ Disabled actions can't be chosen by the user. They don't disappear
+ from the menu/tool bar but are displayed in a way which indicates
+ that they are unavailable, e.g. they might be displayed grayed
+ out.
+
+ What's this? help on disabled actions is still available provided
+ the \l TQAction::whatsThis property is set.
+*/
+void TQAction::setEnabled( bool enable )
+{
+ d->forceDisabled = !enable;
+
+ if ( (bool)d->enabled == enable )
+ return;
+
+ d->enabled = enable;
+ d->update( TQActionPrivate::State );
+}
+
+bool TQAction::isEnabled() const
+{
+ return d->enabled;
+}
+
+/*!
+ Disables the action if \a disable is TRUE; otherwise
+ enables the action.
+
+ See the \l enabled documentation for more information.
+*/
+void TQAction::setDisabled( bool disable )
+{
+ setEnabled( !disable );
+}
+
+/*!
+ \property TQAction::visible
+ \brief whether the action can be seen (e.g. in menus and toolbars)
+
+ If \e visible is TRUE the action can be seen (e.g. in menus and
+ toolbars) and chosen by the user; if \e visible is FALSE the
+ action cannot be seen or chosen by the user.
+
+ Actions which are not visible are \e not grayed out; they do not
+ appear at all.
+*/
+void TQAction::tqsetVisible( bool visible )
+{
+ d->forceInvisible = !visible;
+
+ if ( (bool)d->visible == visible )
+ return;
+ d->visible = visible;
+ d->update( TQActionPrivate::Visibility );
+#if (TQT_VERSION-0 >= 0x040000)
+#error "TQAction::tqsetVisible function wants to be virtual. Also add virtual change() function"
+#endif
+ if ( d->d_group ) //### this function wants to be virtual in 4.0
+ d->d_group->update( (TQActionGroup*) this );
+}
+
+/*
+ Returns TRUE if the action is visible (e.g. in menus and
+ toolbars); otherwise returns FALSE.
+*/
+bool TQAction::isVisible() const
+{
+ return d->visible;
+}
+
+/*! \internal
+*/
+void TQAction::internalActivation()
+{
+ if ( isToggleAction() )
+ setOn( !isOn() );
+ emit activated();
+}
+
+/*! \internal
+*/
+void TQAction::toolButtonToggled( bool on )
+{
+ if ( !isToggleAction() )
+ return;
+ setOn( on );
+}
+
+/*!
+ Adds this action to widget \a w.
+
+ Currently actions may be added to TQToolBar and TQPopupMenu widgets.
+
+ An action added to a tool bar is automatically displayed as a tool
+ button; an action added to a pop up menu appears as a menu option.
+
+ addTo() returns TRUE if the action was added successfully and
+ FALSE otherwise. (If \a w is not a TQToolBar or TQPopupMenu the
+ action will not be added and FALSE will be returned.)
+
+ \sa removeFrom()
+*/
+bool TQAction::addTo( TQWidget* w )
+{
+#ifndef TQT_NO_TOOLBAR
+ if ( ::tqqt_cast<TQToolBar*>(w) ) {
+ if ( !qstrcmp( name(), "qt_separator_action" ) ) {
+ ((TQToolBar*)w)->addSeparator();
+ } else {
+ TQCString bname = name() + TQCString( "_action_button" );
+ TQToolButton* btn = new TQToolButton( (TQToolBar*) w, bname );
+ addedTo( btn, w );
+ btn->setToggleButton( d->toggleaction );
+ d->toolbuttons.append( btn );
+ if ( d->iconset )
+ btn->setIconSet( *d->iconset );
+ d->update( TQActionPrivate::State | TQActionPrivate::Visibility | TQActionPrivate::EverythingElse ) ;
+ connect( btn, TQT_SIGNAL( clicked() ), this, TQT_SIGNAL( activated() ) );
+ connect( btn, TQT_SIGNAL( toggled(bool) ), this, TQT_SLOT( toolButtonToggled(bool) ) );
+ connect( btn, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( objectDestroyed() ) );
+#ifndef TQT_NO_TOOLTIP
+ connect( &(d->tipGroup), TQT_SIGNAL(showTip(const TQString&)), this, TQT_SLOT(showtqStatusText(const TQString&)) );
+ connect( &(d->tipGroup), TQT_SIGNAL(removeTip()), this, TQT_SLOT(cleartqStatusText()) );
+#endif
+ }
+ } else
+#endif
+ if ( ::tqqt_cast<TQPopupMenu*>(w) ) {
+ TQActionPrivate::MenuItem* mi = new TQActionPrivate::MenuItem;
+ mi->popup = (TQPopupMenu*) w;
+ TQIconSet* diconset = d->iconset;
+ if ( !qstrcmp( name(), "qt_separator_action" ) )
+ mi->id = ((TQPopupMenu*)w)->insertSeparator();
+ else if ( diconset )
+ mi->id = mi->popup->insertItem( *diconset, TQString::tqfromLatin1("") );
+ else
+ mi->id = mi->popup->insertItem( TQString::tqfromLatin1("") );
+ addedTo( mi->popup->indexOf( mi->id ), mi->popup );
+ mi->popup->connectItem( mi->id, this, TQT_SLOT(internalActivation()) );
+ d->menuitems.append( mi );
+ d->update( TQActionPrivate::State | TQActionPrivate::Visibility | TQActionPrivate::EverythingElse ) ;
+ w->tqtopLevelWidget()->className();
+ connect( mi->popup, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT(menutqStatusText(int)) );
+ connect( mi->popup, TQT_SIGNAL(aboutToHide()), this, TQT_SLOT(cleartqStatusText()) );
+ connect( mi->popup, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( objectDestroyed() ) );
+ // Makes only sense when called by TQActionGroup::addTo
+ } else if ( ::tqqt_cast<TQComboBox*>(w) ) {
+ TQActionPrivate::ComboItem *ci = new TQActionPrivate::ComboItem;
+ ci->combo = (TQComboBox*)w;
+ connect( ci->combo, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( objectDestroyed() ) );
+ ci->id = ci->combo->count();
+ if ( qstrcmp( name(), "qt_separator_action" ) ) {
+ if ( d->iconset )
+ ci->combo->insertItem( d->iconset->pixmap(), text() );
+ else
+ ci->combo->insertItem( text() );
+ } else {
+ ci->id = -1;
+ }
+ d->comboitems.append( ci );
+
+ d->update( TQActionPrivate::State | TQActionPrivate::EverythingElse );
+ } else {
+ qWarning( "TQAction::addTo(), unknown object" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*!
+ This function is called from the addTo() function when it has
+ created a widget (\a actionWidget) for the action in the \a
+ container.
+*/
+
+void TQAction::addedTo( TQWidget *actionWidget, TQWidget *container )
+{
+ TQ_UNUSED( actionWidget );
+ TQ_UNUSED( container );
+}
+
+/*!
+ \overload
+
+ This function is called from the addTo() function when it has
+ created a menu item at the index position \a index in the popup
+ menu \a menu.
+*/
+
+void TQAction::addedTo( int index, TQPopupMenu *menu )
+{
+ TQ_UNUSED( index );
+ TQ_UNUSED( menu );
+}
+
+/*!
+ Sets the status message to \a text
+*/
+void TQAction::showtqStatusText( const TQString& text )
+{
+#ifndef TQT_NO_STATUSBAR
+ // tqfind out whether we are clearing the status bar by the popup that actually set the text
+ static TQPopupMenu *lastmenu = 0;
+ TQObject *s = (TQObject*)sender();
+ if ( s ) {
+ TQPopupMenu *menu = (TQPopupMenu*)s->tqqt_cast( "TQPopupMenu" );
+ if ( menu && !!text )
+ lastmenu = menu;
+ else if ( menu && text.isEmpty() ) {
+ if ( lastmenu && menu != lastmenu )
+ return;
+ lastmenu = 0;
+ }
+ }
+
+ TQObject* par = tqparent();
+ TQObject* lpar = 0;
+ TQStatusBar *bar = 0;
+ while ( par && !bar ) {
+ lpar = par;
+ bar = (TQStatusBar*)par->child( 0, "TQStatusBar", FALSE );
+ par = par->tqparent();
+ }
+ if ( !bar && lpar ) {
+ TQObjectList *l = lpar->queryList( "TQStatusBar" );
+ if ( !l )
+ return;
+ // #### hopefully the last one is the one of the mainwindow...
+ bar = (TQStatusBar*)l->last();
+ delete l;
+ }
+ if ( bar ) {
+ if ( text.isEmpty() )
+ bar->clear();
+ else
+ bar->message( text );
+ }
+#endif
+}
+
+/*!
+ Sets the status message to the menu item's status text, or to the
+ tooltip, if there is no status text.
+*/
+void TQAction::menutqStatusText( int id )
+{
+ static int lastId = 0;
+ TQString text;
+ TQPtrListIterator<TQActionPrivate::MenuItem> it( d->menuitems);
+ TQActionPrivate::MenuItem* mi;
+ while ( ( mi = it.current() ) ) {
+ ++it;
+ if ( mi->id == id ) {
+ text = statusTip();
+ break;
+ }
+ }
+
+ if ( !text.isEmpty() )
+ showtqStatusText( text );
+ else if ( id != lastId )
+ cleartqStatusText();
+ lastId = id;
+}
+
+/*!
+ Clears the status text.
+*/
+void TQAction::cleartqStatusText()
+{
+ if (!statusTip().isEmpty())
+ showtqStatusText( TQString::null );
+}
+
+/*!
+ Removes the action from widget \a w.
+
+ Returns TRUE if the action was removed successfully; otherwise
+ returns FALSE.
+
+ \sa addTo()
+*/
+bool TQAction::removeFrom( TQWidget* w )
+{
+#ifndef TQT_NO_TOOLBAR
+ if ( ::tqqt_cast<TQToolBar*>(w) ) {
+ TQPtrListIterator<TQToolButton> it( d->toolbuttons);
+ TQToolButton* btn;
+ while ( ( btn = it.current() ) ) {
+ ++it;
+ if ( btn->parentWidget() == w ) {
+ d->toolbuttons.removeRef( btn );
+ disconnect( btn, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( objectDestroyed() ) );
+ delete btn;
+ // no need to disconnect from statusbar
+ }
+ }
+ } else
+#endif
+ if ( ::tqqt_cast<TQPopupMenu*>(w) ) {
+ TQPtrListIterator<TQActionPrivate::MenuItem> it( d->menuitems);
+ TQActionPrivate::MenuItem* mi;
+ while ( ( mi = it.current() ) ) {
+ ++it;
+ if ( mi->popup == w ) {
+ disconnect( mi->popup, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT(menutqStatusText(int)) );
+ disconnect( mi->popup, TQT_SIGNAL(aboutToHide()), this, TQT_SLOT(cleartqStatusText()) );
+ disconnect( mi->popup, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( objectDestroyed() ) );
+ mi->popup->removeItem( mi->id );
+ d->menuitems.removeRef( mi );
+ }
+ }
+ } else if ( ::tqqt_cast<TQComboBox*>(w) ) {
+ TQPtrListIterator<TQActionPrivate::ComboItem> it( d->comboitems );
+ TQActionPrivate::ComboItem *ci;
+ while ( ( ci = it.current() ) ) {
+ ++it;
+ if ( ci->combo == w ) {
+ disconnect( ci->combo, TQT_SIGNAL(destroyed()), this, TQT_SLOT(objectDestroyed()) );
+ d->comboitems.removeRef( ci );
+ }
+ }
+ } else {
+ qWarning( "TQAction::removeFrom(), unknown object" );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*!
+ \internal
+*/
+void TQAction::objectDestroyed()
+{
+ const TQObject* obj = TQT_TQOBJECT(sender());
+ TQPtrListIterator<TQActionPrivate::MenuItem> it( d->menuitems );
+ TQActionPrivate::MenuItem* mi;
+ while ( ( mi = it.current() ) ) {
+ ++it;
+ if ( TQT_TQOBJECT(mi->popup) == obj )
+ d->menuitems.removeRef( mi );
+ }
+ TQActionPrivate::ComboItem *ci;
+ TQPtrListIterator<TQActionPrivate::ComboItem> it2( d->comboitems );
+ while ( ( ci = it2.current() ) ) {
+ ++it2;
+ if ( TQT_TQOBJECT(ci->combo) == obj )
+ d->comboitems.removeRef( ci );
+ }
+ d->toolbuttons.removeRef( (TQToolButton*) obj );
+}
+
+/*!
+ \fn void TQAction::activated()
+
+ This signal is emitted when an action is activated by the user,
+ e.g. when the user clicks a menu option or a toolbar button or
+ presses an action's accelerator key combination.
+
+ Connect to this signal for command actions. Connect to the
+ toggled() signal for toggle actions.
+*/
+
+/*!
+ \fn void TQAction::toggled(bool on)
+
+ This signal is emitted when a toggle action changes state; command
+ actions and \l{TQActionGroup}s don't emit toggled().
+
+ The \a on argument denotes the new state: If \a on is TRUE the
+ toggle action is switched on, and if \a on is FALSE the toggle
+ action is switched off.
+
+ To trigger a user command depending on whether a toggle action has
+ been switched on or off connect it to a slot that takes a bool to
+ indicate the state, e.g.
+
+ \quotefile action/toggleaction/toggleaction.cpp
+ \skipto TQMainWindow * window
+ \printline TQMainWindow * window
+ \skipto labelonoffaction
+ \printline labelonoffaction
+ \skipto connect
+ \printuntil setUsesTextLabel
+
+ \sa activated() setToggleAction() setOn()
+*/
+
+void TQActionGroupPrivate::update( const TQActionGroup* that )
+{
+ for ( TQPtrListIterator<TQAction> it( actions ); it.current(); ++it ) {
+ if ( that->isEnabled() && !it.current()->d->forceDisabled ) {
+ it.current()->setEnabled( TRUE );
+ } else if ( !that->isEnabled() && it.current()->isEnabled() ) {
+ it.current()->setEnabled( FALSE );
+ it.current()->d->forceDisabled = FALSE;
+ }
+ if ( that->isVisible() && !it.current()->d->forceInvisible ) {
+ it.current()->tqsetVisible( TRUE );
+ } else if ( !that->isVisible() && it.current()->isVisible() ) {
+ it.current()->tqsetVisible( FALSE );
+ it.current()->d->forceInvisible = FALSE;
+ }
+ }
+ for ( TQPtrListIterator<TQComboBox> cb( comboboxes ); cb.current(); ++cb ) {
+ TQComboBox *combobox = cb.current();
+ combobox->setEnabled( that->isEnabled() );
+ combobox->setShown( that->isVisible() );
+
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::remove( combobox );
+ if ( !!that->toolTip() )
+ TQToolTip::add( combobox, that->toolTip() );
+#endif
+#ifndef TQT_NO_WHATSTHIS
+ TQWhatsThis::remove( combobox );
+ if ( !!that->whatsThis() )
+ TQWhatsThis::add( combobox, that->whatsThis() );
+#endif
+
+ }
+ for ( TQPtrListIterator<TQToolButton> mb( menubuttons ); mb.current(); ++mb ) {
+ TQToolButton *button = mb.current();
+ button->setEnabled( that->isEnabled() );
+ button->setShown( that->isVisible() );
+
+ if ( !that->text().isNull() )
+ button->setTextLabel( that->text() );
+ if ( !that->iconSet().isNull() )
+ button->setIconSet( that->iconSet() );
+
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::remove( mb.current() );
+ if ( !!that->toolTip() )
+ TQToolTip::add( button, that->toolTip() );
+#endif
+#ifndef TQT_NO_WHATSTHIS
+ TQWhatsThis::remove( button );
+ if ( !!that->whatsThis() )
+ TQWhatsThis::add( button, that->whatsThis() );
+#endif
+ }
+ for ( TQPtrListIterator<TQActionGroupPrivate::MenuItem> pu( menuitems ); pu.current(); ++pu ) {
+ TQWidget* tqparent = pu.current()->popup->parentWidget();
+ if ( ::tqqt_cast<TQPopupMenu*>(tqparent) ) {
+ TQPopupMenu* ppopup = (TQPopupMenu*)tqparent;
+ ppopup->setItemEnabled( pu.current()->id, that->isEnabled() );
+ ppopup->setItemVisible( pu.current()->id, that->isVisible() );
+ } else {
+ pu.current()->popup->setEnabled( that->isEnabled() );
+ }
+ }
+ for ( TQPtrListIterator<TQPopupMenu> pm( popupmenus ); pm.current(); ++pm ) {
+ TQPopupMenu *popup = pm.current();
+ TQPopupMenu *tqparent = ::tqqt_cast<TQPopupMenu*>(popup->parentWidget());
+ if ( !tqparent )
+ continue;
+
+ int index;
+ tqparent->tqfindPopup( popup, &index );
+ int id = tqparent->idAt( index );
+ if ( !that->iconSet().isNull() )
+ tqparent->changeItem( id, that->iconSet(), that->menuText() );
+ else
+ tqparent->changeItem( id, that->menuText() );
+ tqparent->setItemEnabled( id, that->isEnabled() );
+#ifndef TQT_NO_ACCEL
+ tqparent->setAccel( that->accel(), id );
+#endif
+ }
+}
+
+/*!
+ \class TQActionGroup tqaction.h
+ \brief The TQActionGroup class groups actions together.
+
+ \ingroup basic
+ \ingroup application
+
+ In some situations it is useful to group actions together. For
+ example, if you have a left justify action, a right justify action
+ and a center action, only one of these actions should be active at
+ any one time, and one simple way of achieving this is to group the
+ actions together in an action group.
+
+ An action group can also be added to a menu or a toolbar as a
+ single unit, with all the actions within the action group
+ appearing as separate menu options and toolbar buttons.
+
+ Here's an example from examples/textedit:
+ \quotefile textedit/textedit.cpp
+ \skipto TQActionGroup
+ \printuntil connect
+
+ Here we create a new action group. Since the action group is exclusive
+ by default, only one of the actions in the group is ever active at any
+ one time. We then connect the group's selected() signal to our
+ textAlign() slot.
+
+ \printuntil actionAlignLeft->setToggleAction
+
+ We create a left align action, add it to the toolbar and the menu
+ and make it a toggle action. We create center and right align
+ actions in exactly the same way.
+
+ \omit
+ A TQActionGroup emits an activated() signal when one of its actions
+ is activated.
+ \endomit
+ The actions in an action group emit their activated() (and for
+ toggle actions, toggled()) Q_SIGNALS as usual.
+
+ The setExclusive() function is used to ensure that only one action
+ is active at any one time: it should be used with actions which
+ have their \c toggleAction set to TRUE.
+
+ Action group actions appear as individual menu options and toolbar
+ buttons. For exclusive action groups use setUsesDropDown() to
+ display the actions in a subwidget of any widget the action group
+ is added to. For example, the actions would appear in a combobox
+ in a toolbar or as a submenu in a menu.
+
+ Actions can be added to an action group using add(), but normally
+ they are added by creating the action with the action group as
+ tqparent. Actions can have separators dividing them using
+ addSeparator(). Action groups are added to widgets with addTo().
+*/
+
+/*!
+ Constructs an action group called \a name, with tqparent \a tqparent.
+
+ The action group is exclusive by default. Call setExclusive(FALSE) to make
+ the action group non-exclusive.
+*/
+TQActionGroup::TQActionGroup( TQT_BASE_OBJECT_NAME* tqparent, const char* name )
+ : TQAction( TQT_TQOBJECT(tqparent), name )
+{
+ d = new TQActionGroupPrivate;
+ d->exclusive = TRUE;
+ d->dropdown = FALSE;
+ d->selected = 0;
+ d->separatorAction = 0;
+ TQAction::d->d_group = d;
+
+ connect( this, TQT_SIGNAL(selected(TQAction*)), TQT_SLOT(internalToggle(TQAction*)) );
+}
+
+/*!
+ Constructs an action group called \a name, with tqparent \a tqparent.
+
+ If \a exclusive is TRUE only one toggle action in the group will
+ ever be active.
+
+ \sa exclusive
+*/
+TQActionGroup::TQActionGroup( TQT_BASE_OBJECT_NAME* tqparent, const char* name, bool exclusive )
+ : TQAction( TQT_TQOBJECT(tqparent), name )
+{
+ d = new TQActionGroupPrivate;
+ d->exclusive = exclusive;
+ d->dropdown = FALSE;
+ d->selected = 0;
+ d->separatorAction = 0;
+ TQAction::d->d_group = d;
+
+ connect( this, TQT_SIGNAL(selected(TQAction*)), TQT_SLOT(internalToggle(TQAction*)) );
+}
+
+/*!
+ Destroys the object and frees allocated resources.
+*/
+
+TQActionGroup::~TQActionGroup()
+{
+ TQPtrListIterator<TQActionGroupPrivate::MenuItem> mit( d->menuitems );
+ while ( mit.current() ) {
+ TQActionGroupPrivate::MenuItem *mi = mit.current();
+ ++mit;
+ if ( mi->popup )
+ mi->popup->disconnect( TQT_SIGNAL(destroyed()), this, TQT_SLOT(objectDestroyed()) );
+ }
+
+ TQPtrListIterator<TQComboBox> cbit( d->comboboxes );
+ while ( cbit.current() ) {
+ TQComboBox *cb = cbit.current();
+ ++cbit;
+ cb->disconnect( TQT_SIGNAL(destroyed()), this, TQT_SLOT(objectDestroyed()) );
+ }
+ TQPtrListIterator<TQToolButton> mbit( d->menubuttons );
+ while ( mbit.current() ) {
+ TQToolButton *mb = mbit.current();
+ ++mbit;
+ mb->disconnect( TQT_SIGNAL(destroyed()), this, TQT_SLOT(objectDestroyed()) );
+ }
+ TQPtrListIterator<TQPopupMenu> pmit( d->popupmenus );
+ while ( pmit.current() ) {
+ TQPopupMenu *pm = pmit.current();
+ ++pmit;
+ pm->disconnect( TQT_SIGNAL(destroyed()), this, TQT_SLOT(objectDestroyed()) );
+ }
+
+ delete d->separatorAction;
+ d->menubuttons.setAutoDelete( TRUE );
+ d->comboboxes.setAutoDelete( TRUE );
+ d->menuitems.setAutoDelete( TRUE );
+ d->popupmenus.setAutoDelete( TRUE );
+ delete d;
+}
+
+/*!
+ \property TQActionGroup::exclusive
+ \brief whether the action group does exclusive toggling
+
+ If exclusive is TRUE only one toggle action in the action group
+ can ever be active at any one time. If the user chooses another
+ toggle action in the group the one they chose becomes active and
+ the one that was active becomes inactive.
+
+ \sa TQAction::toggleAction
+*/
+void TQActionGroup::setExclusive( bool enable )
+{
+ d->exclusive = enable;
+}
+
+bool TQActionGroup::isExclusive() const
+{
+ return d->exclusive;
+}
+
+/*!
+ \property TQActionGroup::usesDropDown
+ \brief whether the group's actions are displayed in a subwidget of
+ the widgets the action group is added to
+
+ Exclusive action groups added to a toolbar display their actions
+ in a combobox with the action's \l TQAction::text and \l
+ TQAction::iconSet properties shown. Non-exclusive groups are
+ represented by a tool button showing their \l TQAction::iconSet and
+ -- depending on \l TQMainWindow::usesTextLabel() -- text()
+ property.
+
+ In a popup menu the member actions are displayed in a submenu.
+
+ Changing usesDropDown only affects \e subsequent calls to addTo().
+
+ Note that setting this property for actions in a combobox causes
+ calls to their \link TQAction::tqsetVisible()\endlink,
+ \link TQAction::setEnabled()\endlink, and
+ \link TQAction::setDisabled()\endlink functions to have no effect.
+
+ This property's default is FALSE.
+
+*/
+void TQActionGroup::setUsesDropDown( bool enable )
+{
+ d->dropdown = enable;
+}
+
+bool TQActionGroup::usesDropDown() const
+{
+ return d->dropdown;
+}
+
+/*!
+ Adds action \a action to this group.
+
+ Normally an action is added to a group by creating it with the
+ group as tqparent, so this function is not usually used.
+
+ \sa addTo()
+*/
+void TQActionGroup::add( TQAction* action )
+{
+ if ( d->actions.tqcontainsRef( action ) )
+ return;
+
+ d->actions.append( action );
+
+ if ( action->whatsThis().isNull() )
+ action->setWhatsThis( whatsThis() );
+ if ( action->toolTip().isNull() )
+ action->setToolTip( toolTip() );
+
+ if (!action->d->forceDisabled)
+ action->d->enabled = isEnabled();
+ if (!action->d->forceInvisible)
+ action->d->visible = isVisible();
+
+ connect( action, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( childDestroyed() ) );
+ connect( action, TQT_SIGNAL( activated() ), this, TQT_SIGNAL( activated() ) );
+ connect( action, TQT_SIGNAL( toggled(bool) ), this, TQT_SLOT( childToggled(bool) ) );
+
+ for ( TQPtrListIterator<TQComboBox> cb( d->comboboxes ); cb.current(); ++cb ) {
+ action->addTo( cb.current() );
+ }
+ for ( TQPtrListIterator<TQToolButton> mb( d->menubuttons ); mb.current(); ++mb ) {
+ TQPopupMenu* popup = mb.current()->popup();
+ if ( !popup )
+ continue;
+ action->addTo( popup );
+ }
+ for ( TQPtrListIterator<TQActionGroupPrivate::MenuItem> mi( d->menuitems ); mi.current(); ++mi ) {
+ TQPopupMenu* popup = mi.current()->popup;
+ if ( !popup )
+ continue;
+ action->addTo( popup );
+ }
+}
+
+/*!
+ Adds a separator to the group.
+*/
+void TQActionGroup::addSeparator()
+{
+ if ( !d->separatorAction )
+ d->separatorAction = new TQAction( 0, "qt_separator_action" );
+ d->actions.append( d->separatorAction );
+}
+
+
+/*! \fn void TQActionGroup::insert( TQAction* a )
+
+ \obsolete
+
+ Use add() instead, or better still create the action with the action
+ group as its tqparent.
+ */
+
+/*!
+ Adds this action group to the widget \a w.
+
+ If isExclusive() is FALSE or usesDropDown() is FALSE, the actions within
+ the group are added to the widget individually. For example, if the widget
+ is a menu, the actions will appear as individual menu options, and
+ if the widget is a toolbar, the actions will appear as toolbar buttons.
+
+ If both isExclusive() and usesDropDown() are TRUE, the actions
+ are presented either in a combobox (if \a w is a toolbar) or in a
+ submenu (if \a w is a menu).
+
+ All actions should be added to the action group \e before the
+ action group is added to the widget. If actions are added to the
+ action group \e after the action group has been added to the
+ widget these later actions will \e not appear.
+
+ \sa setExclusive() setUsesDropDown() removeFrom()
+*/
+bool TQActionGroup::addTo( TQWidget* w )
+{
+#ifndef TQT_NO_TOOLBAR
+ if ( ::tqqt_cast<TQToolBar*>(w) ) {
+ if ( d->dropdown ) {
+ if ( !d->exclusive ) {
+ TQPtrListIterator<TQAction> it( d->actions);
+ if ( !it.current() )
+ return TRUE;
+
+ TQAction *defAction = it.current();
+
+ TQToolButton* btn = new TQToolButton( (TQToolBar*) w, "qt_actiongroup_btn" );
+ addedTo( btn, w );
+ connect( btn, TQT_SIGNAL(destroyed()), TQT_SLOT(objectDestroyed()) );
+ d->menubuttons.append( btn );
+
+ if ( !iconSet().isNull() )
+ btn->setIconSet( iconSet() );
+ else if ( !defAction->iconSet().isNull() )
+ btn->setIconSet( defAction->iconSet() );
+ if ( !!text() )
+ btn->setTextLabel( text() );
+ else if ( !!defAction->text() )
+ btn->setTextLabel( defAction->text() );
+#ifndef TQT_NO_TOOLTIP
+ if ( !!toolTip() )
+ TQToolTip::add( btn, toolTip() );
+ else if ( !!defAction->toolTip() )
+ TQToolTip::add( btn, defAction->toolTip() );
+#endif
+#ifndef TQT_NO_WHATSTHIS
+ if ( !!whatsThis() )
+ TQWhatsThis::add( btn, whatsThis() );
+ else if ( !!defAction->whatsThis() )
+ TQWhatsThis::add( btn, defAction->whatsThis() );
+#endif
+
+ connect( btn, TQT_SIGNAL( clicked() ), defAction, TQT_SIGNAL( activated() ) );
+ connect( btn, TQT_SIGNAL( toggled(bool) ), defAction, TQT_SLOT( toolButtonToggled(bool) ) );
+ connect( btn, TQT_SIGNAL( destroyed() ), defAction, TQT_SLOT( objectDestroyed() ) );
+
+ TQPopupMenu *menu = new TQPopupMenu( btn, "qt_actiongroup_menu" );
+ btn->setPopupDelay( 0 );
+ btn->setPopup( menu );
+
+ while( it.current() ) {
+ it.current()->addTo( menu );
+ ++it;
+ }
+ d->update( this );
+ return TRUE;
+ } else {
+ TQComboBox *box = new TQComboBox( FALSE, w, "qt_actiongroup_combo" );
+ addedTo( box, w );
+ connect( box, TQT_SIGNAL(destroyed()), TQT_SLOT(objectDestroyed()) );
+ d->comboboxes.append( box );
+#ifndef TQT_NO_TOOLTIP
+ if ( !!toolTip() )
+ TQToolTip::add( box, toolTip() );
+#endif
+#ifndef TQT_NO_WHATSTHIS
+ if ( !!whatsThis() )
+ TQWhatsThis::add( box, whatsThis() );
+#endif
+
+ int onIndex = 0;
+ bool foundOn = FALSE;
+ for ( TQPtrListIterator<TQAction> it( d->actions); it.current(); ++it ) {
+ TQAction *action = it.current();
+ if ( !foundOn )
+ foundOn = action->isOn();
+ if ( qstrcmp( action->name(), "qt_separator_action" ) && !foundOn )
+ onIndex++;
+ action->addTo( box );
+ }
+ if ( foundOn )
+ box->setCurrentItem( onIndex );
+ connect( box, TQT_SIGNAL(activated(int)), this, TQT_SLOT( internalComboBoxActivated(int)) );
+ connect( box, TQT_SIGNAL(highlighted(int)), this, TQT_SLOT( internalComboBoxHighlighted(int)) );
+ d->update( this );
+ return TRUE;
+ }
+ }
+ } else
+#endif
+ if ( ::tqqt_cast<TQPopupMenu*>(w) ) {
+ TQPopupMenu *popup;
+ if ( d->dropdown ) {
+ TQPopupMenu *menu = (TQPopupMenu*)w;
+ popup = new TQPopupMenu( w, "qt_actiongroup_menu" );
+ d->popupmenus.append( popup );
+ connect( popup, TQT_SIGNAL(destroyed()), TQT_SLOT(objectDestroyed()) );
+
+ int id;
+ if ( !iconSet().isNull() ) {
+ if ( menuText().isEmpty() )
+ id = menu->insertItem( iconSet(), text(), popup );
+ else
+ id = menu->insertItem( iconSet(), menuText(), popup );
+ } else {
+ if ( menuText().isEmpty() )
+ id = menu->insertItem( text(), popup );
+ else
+ id = menu->insertItem( menuText(), popup );
+ }
+
+ addedTo( menu->indexOf( id ), menu );
+
+ TQActionGroupPrivate::MenuItem *item = new TQActionGroupPrivate::MenuItem;
+ item->id = id;
+ item->popup = popup;
+ d->menuitems.append( item );
+ } else {
+ popup = (TQPopupMenu*)w;
+ }
+ for ( TQPtrListIterator<TQAction> it( d->actions); it.current(); ++it ) {
+ // #### do an addedTo( index, popup, action), need to tqfind out index
+ it.current()->addTo( popup );
+ }
+ return TRUE;
+ }
+
+ for ( TQPtrListIterator<TQAction> it( d->actions); it.current(); ++it ) {
+ // #### do an addedTo( index, popup, action), need to tqfind out index
+ it.current()->addTo( w );
+ }
+
+ return TRUE;
+}
+
+/*! \reimp
+*/
+bool TQActionGroup::removeFrom( TQWidget* w )
+{
+ for ( TQPtrListIterator<TQAction> it( d->actions); it.current(); ++it ) {
+ it.current()->removeFrom( w );
+ }
+
+#ifndef TQT_NO_TOOLBAR
+ if ( ::tqqt_cast<TQToolBar*>(w) ) {
+ TQPtrListIterator<TQComboBox> cb( d->comboboxes );
+ while( cb.current() ) {
+ TQComboBox *box = cb.current();
+ ++cb;
+ if ( box->parentWidget() == w )
+ delete box;
+ }
+ TQPtrListIterator<TQToolButton> mb( d->menubuttons );
+ while( mb.current() ) {
+ TQToolButton *btn = mb.current();
+ ++mb;
+ if ( btn->parentWidget() == w )
+ delete btn;
+ }
+ } else
+#endif
+ if ( ::tqqt_cast<TQPopupMenu*>(w) ) {
+ TQPtrListIterator<TQActionGroupPrivate::MenuItem> pu( d->menuitems );
+ while ( pu.current() ) {
+ TQActionGroupPrivate::MenuItem *mi = pu.current();
+ ++pu;
+ if ( d->dropdown && mi->popup )
+ ( (TQPopupMenu*)w )->removeItem( mi->id );
+ delete mi->popup;
+ }
+ }
+
+ return TRUE;
+}
+
+/*! \internal
+*/
+void TQActionGroup::childToggled( bool b )
+{
+ if ( !isExclusive() )
+ return;
+ TQAction* s = (TQAction*) sender();
+ if ( b ) {
+ if ( s != d->selected ) {
+ d->selected = s;
+ for ( TQPtrListIterator<TQAction> it( d->actions); it.current(); ++it ) {
+ if ( it.current()->isToggleAction() && it.current() != s )
+ it.current()->setOn( FALSE );
+ }
+ emit activated();
+ emit selected( s );
+ } else if ( !s->isToggleAction() ) {
+ emit activated();
+ }
+ } else {
+ if ( s == d->selected ) {
+ // at least one has to be selected
+ s->setOn( TRUE );
+ }
+ }
+}
+
+/*! \internal
+*/
+void TQActionGroup::childDestroyed()
+{
+ d->actions.removeRef( (TQAction*) sender() );
+ if ( d->selected == sender() )
+ d->selected = 0;
+}
+
+/*! \reimp
+*/
+void TQActionGroup::setEnabled( bool enable )
+{
+ if ( enable == isEnabled() )
+ return;
+
+ TQAction::setEnabled( enable );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void TQActionGroup::setToggleAction( bool toggle )
+{
+ for ( TQPtrListIterator<TQAction> it( d->actions); it.current(); ++it )
+ it.current()->setToggleAction( toggle );
+
+ TQAction::setToggleAction( TRUE );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void TQActionGroup::setOn( bool on )
+{
+ for ( TQPtrListIterator<TQAction> it( d->actions); it.current(); ++it ) {
+ TQAction *act = it.current();
+ if ( act->isToggleAction() )
+ act->setOn( on );
+ }
+
+ TQAction::setOn( on );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void TQActionGroup::setIconSet( const TQIconSet& icon )
+{
+ TQAction::setIconSet( icon );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void TQActionGroup::setText( const TQString& txt )
+{
+ if ( txt == text() )
+ return;
+
+ TQAction::setText( txt );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void TQActionGroup::setMenuText( const TQString& text )
+{
+ if ( text == menuText() )
+ return;
+
+ TQAction::setMenuText( text );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void TQActionGroup::setToolTip( const TQString& text )
+{
+ if ( text == toolTip() )
+ return;
+ for ( TQPtrListIterator<TQAction> it( d->actions); it.current(); ++it ) {
+ if ( it.current()->toolTip().isNull() )
+ it.current()->setToolTip( text );
+ }
+ TQAction::setToolTip( text );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void TQActionGroup::setWhatsThis( const TQString& text )
+{
+ if ( text == whatsThis() )
+ return;
+ for ( TQPtrListIterator<TQAction> it( d->actions); it.current(); ++it ) {
+ if ( it.current()->whatsThis().isNull() )
+ it.current()->setWhatsThis( text );
+ }
+ TQAction::setWhatsThis( text );
+ d->update( this );
+}
+
+/*! \reimp
+*/
+void TQActionGroup::childEvent( TQChildEvent *e )
+{
+ if ( !e->removed() )
+ return;
+
+ TQAction *action = ::tqqt_cast<TQAction*>(e->child());
+ if ( !action )
+ return;
+
+ for ( TQPtrListIterator<TQComboBox> cb( d->comboboxes ); cb.current(); ++cb ) {
+ for ( int i = 0; i < cb.current()->count(); i++ ) {
+ if ( cb.current()->text( i ) == action->text() ) {
+ cb.current()->removeItem( i );
+ break;
+ }
+ }
+ }
+ for ( TQPtrListIterator<TQToolButton> mb( d->menubuttons ); mb.current(); ++mb ) {
+ TQPopupMenu* popup = mb.current()->popup();
+ if ( !popup )
+ continue;
+ action->removeFrom( popup );
+ }
+ for ( TQPtrListIterator<TQActionGroupPrivate::MenuItem> mi( d->menuitems ); mi.current(); ++mi ) {
+ TQPopupMenu* popup = mi.current()->popup;
+ if ( !popup )
+ continue;
+ action->removeFrom( popup );
+ }
+}
+
+/*!
+ \fn void TQActionGroup::selected( TQAction* )
+
+ This signal is emitted from exclusive groups when toggle actions
+ change state.
+
+ The argument is the action whose state changed to "on".
+
+ \sa setExclusive(), isOn() TQAction::toggled()
+*/
+
+/*! \internal
+*/
+void TQActionGroup::internalComboBoxActivated( int index )
+{
+ TQAction *a = 0;
+ for ( int i = 0; i <= index && i < (int)d->actions.count(); ++i ) {
+ a = d->actions.at( i );
+ if ( a && !qstrcmp( a->name(), "qt_separator_action" ) )
+ index++;
+ }
+ a = d->actions.at( index );
+ if ( a ) {
+ if ( a != d->selected ) {
+ d->selected = a;
+ for ( TQPtrListIterator<TQAction> it( d->actions); it.current(); ++it ) {
+ if ( it.current()->isToggleAction() && it.current() != a )
+ it.current()->setOn( FALSE );
+ }
+ if ( a->isToggleAction() )
+ a->setOn( TRUE );
+
+ emit activated();
+ if ( a->isToggleAction() )
+ emit selected( d->selected );
+ emit ((TQActionGroup*)a)->activated();
+ } else if ( !a->isToggleAction() ) {
+ emit activated();
+ emit ((TQActionGroup*)a)->activated();
+ }
+ a->cleartqStatusText();
+ }
+}
+
+/*! \internal
+*/
+void TQActionGroup::internalComboBoxHighlighted( int index )
+{
+ TQAction *a = 0;
+ for ( int i = 0; i <= index && i < (int)d->actions.count(); ++i ) {
+ a = d->actions.at( i );
+ if ( a && !qstrcmp( a->name(), "qt_separator_action" ) )
+ index++;
+ }
+ a = d->actions.at( index );
+ if ( a )
+ a->showtqStatusText(a->statusTip());
+ else
+ cleartqStatusText();
+}
+
+/*! \internal
+*/
+void TQActionGroup::internalToggle( TQAction *a )
+{
+ int index = d->actions.tqfind( a );
+ if ( index == -1 )
+ return;
+
+ int lastItem = index;
+ for ( int i = 0; i < lastItem; i++ ) {
+ TQAction *action = d->actions.at( i );
+ if ( !qstrcmp( action->name(), "qt_separator_action" ) )
+ index--;
+ }
+
+ for ( TQPtrListIterator<TQComboBox> it( d->comboboxes); it.current(); ++it )
+ it.current()->setCurrentItem( index );
+}
+
+/*! \internal
+*/
+void TQActionGroup::objectDestroyed()
+{
+ const TQObject* obj = TQT_TQOBJECT(sender());
+ d->menubuttons.removeRef( (TQToolButton*)obj );
+ for ( TQPtrListIterator<TQActionGroupPrivate::MenuItem> mi( d->menuitems ); mi.current(); ++mi ) {
+ if ( TQT_TQOBJECT(mi.current()->popup) == obj ) {
+ d->menuitems.removeRef( mi.current() );
+ break;
+ }
+ }
+ d->popupmenus.removeRef( (TQPopupMenu*)obj );
+ d->comboboxes.removeRef( (TQComboBox*)obj );
+}
+
+/*!
+ \internal
+
+ This function is called from the addTo() function when it has
+ created a widget (\a actionWidget) for the child action \a a in
+ the \a container.
+*/
+
+void TQActionGroup::addedTo( TQWidget *actionWidget, TQWidget *container, TQAction *a )
+{
+ TQ_UNUSED( actionWidget );
+ TQ_UNUSED( container );
+ TQ_UNUSED( a );
+}
+
+/*!
+ \overload
+ \internal
+
+ This function is called from the addTo() function when it has
+ created a menu item for the child action at the index position \a
+ index in the popup menu \a menu.
+*/
+
+void TQActionGroup::addedTo( int index, TQPopupMenu *menu, TQAction *a )
+{
+ TQ_UNUSED( index );
+ TQ_UNUSED( menu );
+ TQ_UNUSED( a );
+}
+
+/*!
+ \reimp
+ \overload
+
+ This function is called from the addTo() function when it has
+ created a widget (\a actionWidget) in the \a container.
+*/
+
+void TQActionGroup::addedTo( TQWidget *actionWidget, TQWidget *container )
+{
+ TQ_UNUSED( actionWidget );
+ TQ_UNUSED( container );
+}
+
+/*!
+ \reimp
+ \overload
+
+ This function is called from the addTo() function when it has
+ created a menu item at the index position \a index in the popup
+ menu \a menu.
+*/
+
+void TQActionGroup::addedTo( int index, TQPopupMenu *menu )
+{
+ TQ_UNUSED( index );
+ TQ_UNUSED( menu );
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqaction.h b/tqtinterface/qt4/src/widgets/tqaction.h
new file mode 100644
index 0000000..12f8148
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqaction.h
@@ -0,0 +1,220 @@
+/****************************************************************************
+**
+** Definition of TQAction class
+**
+** Created : 000000
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQACTION_H
+#define TQACTION_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqiconset.h"
+#include "tqstring.h"
+#include "tqkeysequence.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_ACTION
+
+class TQActionPrivate;
+class TQActionGroupPrivate;
+class TQStatusBar;
+class TQPopupMenu;
+class TQToolTipGroup;
+
+class TQ_EXPORT TQAction : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool toggleAction READ isToggleAction WRITE setToggleAction)
+ Q_PROPERTY( bool on READ isOn WRITE setOn )
+ Q_PROPERTY( bool enabled READ isEnabled WRITE setEnabled )
+ Q_PROPERTY( TQIconSet iconSet READ iconSet WRITE setIconSet )
+ Q_PROPERTY( TQString text READ text WRITE setText )
+ Q_PROPERTY( TQString menuText READ menuText WRITE setMenuText )
+ Q_PROPERTY( TQString toolTip READ toolTip WRITE setToolTip )
+ Q_PROPERTY( TQString statusTip READ statusTip WRITE setStatusTip )
+ Q_PROPERTY( TQString whatsThis READ whatsThis WRITE setWhatsThis )
+#ifndef TQT_NO_ACCEL
+ Q_PROPERTY( TQKeySequence accel READ accel WRITE setAccel )
+#endif
+ Q_PROPERTY( bool visible READ isVisible WRITE tqsetVisible )
+
+public:
+ TQAction( TQT_BASE_OBJECT_NAME* tqparent, const char* name = 0 );
+#ifndef TQT_NO_ACCEL
+ TQAction( const TQString& menuText, TQKeySequence accel,
+ TQT_BASE_OBJECT_NAME* tqparent, const char* name = 0 );
+ TQAction( const TQIconSet& icon, const TQString& menuText, TQKeySequence accel,
+ TQT_BASE_OBJECT_NAME* tqparent, const char* name = 0 );
+
+ TQAction( const TQString& text, const TQIconSet& icon, const TQString& menuText, TQKeySequence accel,
+ TQT_BASE_OBJECT_NAME* tqparent, const char* name = 0, bool toggle = FALSE ); // obsolete
+ TQAction( const TQString& text, const TQString& menuText, TQKeySequence accel, TQT_BASE_OBJECT_NAME* tqparent,
+ const char* name = 0, bool toggle = FALSE ); // obsolete
+#endif
+ TQAction( TQT_BASE_OBJECT_NAME* tqparent, const char* name , bool toggle ); // obsolete
+ ~TQAction();
+
+ virtual void setIconSet( const TQIconSet& );
+ TQIconSet iconSet() const;
+ virtual void setText( const TQString& );
+ TQString text() const;
+ virtual void setMenuText( const TQString& );
+ TQString menuText() const;
+ virtual void setToolTip( const TQString& );
+ TQString toolTip() const;
+ virtual void setStatusTip( const TQString& );
+ TQString statusTip() const;
+ virtual void setWhatsThis( const TQString& );
+ TQString whatsThis() const;
+#ifndef TQT_NO_ACCEL
+ virtual void setAccel( const TQKeySequence& key );
+ TQKeySequence accel() const;
+#endif
+ virtual void setToggleAction( bool );
+
+ bool isToggleAction() const;
+ bool isOn() const;
+ bool isEnabled() const;
+ bool isVisible() const;
+ virtual bool addTo( TQWidget* );
+ virtual bool removeFrom( TQWidget* );
+
+protected:
+ virtual void addedTo( TQWidget *actionWidget, TQWidget *container );
+ virtual void addedTo( int index, TQPopupMenu *menu );
+
+public Q_SLOTS:
+ void activate();
+ void toggle();
+ virtual void setOn( bool );
+ virtual void setEnabled( bool );
+ void setDisabled( bool );
+ void tqsetVisible( bool );
+
+Q_SIGNALS:
+ void activated();
+ void toggled( bool );
+
+private Q_SLOTS:
+ void internalActivation();
+ void toolButtonToggled( bool );
+ void objectDestroyed();
+ void menutqStatusText( int id );
+ void showtqStatusText( const TQString& );
+ void cleartqStatusText();
+
+private:
+ void init();
+
+ friend class TQActionGroup;
+ friend class TQActionGroupPrivate;
+ TQActionPrivate* d;
+
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQAction( const TQAction & );
+ TQAction &operator=( const TQAction & );
+#endif
+};
+
+class TQ_EXPORT TQActionGroup : public TQAction
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool exclusive READ isExclusive WRITE setExclusive )
+ Q_PROPERTY( bool usesDropDown READ usesDropDown WRITE setUsesDropDown )
+
+public:
+ TQActionGroup( TQT_BASE_OBJECT_NAME* tqparent, const char* name = 0 );
+ TQActionGroup( TQT_BASE_OBJECT_NAME* tqparent, const char* name , bool exclusive ); // obsolete
+ ~TQActionGroup();
+ void setExclusive( bool );
+ bool isExclusive() const;
+ void add( TQAction* a);
+ void addSeparator();
+ bool addTo( TQWidget* );
+ bool removeFrom( TQWidget* );
+ void setEnabled( bool );
+ void setToggleAction( bool toggle );
+ void setOn( bool on );
+
+ void setUsesDropDown( bool enable );
+ bool usesDropDown() const;
+
+ void setIconSet( const TQIconSet& );
+ void setText( const TQString& );
+ void setMenuText( const TQString& );
+ void setToolTip( const TQString& );
+ void setWhatsThis( const TQString& );
+
+protected:
+ void childEvent( TQChildEvent* );
+ virtual void addedTo( TQWidget *actionWidget, TQWidget *container, TQAction *a );
+ virtual void addedTo( int index, TQPopupMenu *menu, TQAction *a );
+ virtual void addedTo( TQWidget *actionWidget, TQWidget *container );
+ virtual void addedTo( int index, TQPopupMenu *menu );
+
+Q_SIGNALS:
+ void selected( TQAction* );
+
+private Q_SLOTS:
+ void childToggled( bool );
+ void childDestroyed();
+ void internalComboBoxActivated( int );
+ void internalComboBoxHighlighted( int );
+ void internalToggle( TQAction* );
+ void objectDestroyed();
+
+private:
+ TQActionGroupPrivate* d;
+
+#ifndef TQT_NO_COMPAT
+public:
+ void insert( TQAction* a ) { add( a ); }
+#endif
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQActionGroup( const TQActionGroup & );
+ TQActionGroup &operator=( const TQActionGroup & );
+#endif
+};
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqbutton.cpp b/tqtinterface/qt4/src/widgets/tqbutton.cpp
new file mode 100644
index 0000000..c667fec
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqbutton.cpp
@@ -0,0 +1,1016 @@
+/****************************************************************************
+**
+** Implementation of TQButton widget class
+**
+** Created : 940206
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#undef TQT_NO_COMPAT
+#include "tqbutton.h"
+#ifndef TQT_NO_BUTTON
+#include "tqbuttongroup.h"
+#include "tqbitmap.h"
+#include "tqpainter.h"
+#include "tqtimer.h"
+#include "tqaccel.h"
+#include "tqpixmapcache.h"
+#include "tqapplication.h"
+#include "tqpushbutton.h"
+#include "tqradiobutton.h"
+#include "tqguardedptr.h"
+#include "../kernel/tqinternal_p.h"
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+#define AUTO_REPEAT_DELAY 300
+#define AUTO_REPEAT_PERIOD 100
+
+class TQButtonData
+{
+public:
+ TQButtonData() {
+#ifndef TQT_NO_BUTTONGROUP
+ group = 0;
+#endif
+#ifndef TQT_NO_ACCEL
+ a = 0;
+#endif
+ }
+#ifndef TQT_NO_BUTTONGROUP
+ TQButtonGroup *group;
+#endif
+ TQTimer timer;
+#ifndef TQT_NO_ACCEL
+ TQAccel *a;
+#endif
+};
+
+
+void TQButton::ensureData()
+{
+ if ( !d ) {
+ d = new TQButtonData;
+ TQ_CHECK_PTR( d );
+ connect(&d->timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(autoRepeatTimeout()));
+ }
+}
+
+
+/*!
+ Returns the group that this button belongs to.
+
+ If the button is not a member of any TQButtonGroup, this function
+ returns 0.
+
+ \sa TQButtonGroup
+*/
+
+TQButtonGroup *TQButton::group() const
+{
+#ifndef TQT_NO_BUTTONGROUP
+ return d ? d->group : 0;
+#else
+ return 0;
+#endif
+}
+
+
+void TQButton::setGroup( TQButtonGroup* g )
+{
+#ifndef TQT_NO_BUTTONGROUP
+ ensureData();
+ d->group = g;
+#endif
+}
+
+
+TQTimer *TQButton::timer()
+{
+ ensureData();
+ return &d->timer;
+}
+
+
+/*!
+ \class TQButton tqbutton.h
+ \brief The TQButton class is the abstract base class of button
+ widgets, providing functionality common to buttons.
+
+ \ingroup abstractwidgets
+
+ <b>If you want to create a button use TQPushButton.</b>
+
+ The TQButton class implements an \e abstract button, and lets
+ subclasses specify how to reply to user actions and how to draw
+ the button.
+
+ TQButton provides both push and toggle buttons. The TQRadioButton
+ and TQCheckBox classes provide only toggle buttons; TQPushButton and
+ TQToolButton provide both toggle and push buttons.
+
+ Any button can have either a text or pixmap label. setText() sets
+ the button to be a text button and setPixmap() sets it to be a
+ pixmap button. The text/pixmap is manipulated as necessary to
+ create the "disabled" appearance when the button is disabled.
+
+ TQButton provides most of the states used for buttons:
+ \list
+ \i isDown() indicates whether the button is \e pressed down.
+ \i isOn() indicates whether the button is \e on.
+ Only toggle buttons can be switched on and off (see below).
+ \i isEnabled() indicates whether the button can be pressed by the
+ user.
+ \i setAutoRepeat() sets whether the button will auto-repeat
+ if the user holds it down.
+ \i setToggleButton() sets whether the button is a toggle
+ button or not.
+ \endlist
+
+ The difference between isDown() and isOn() is as follows: When the
+ user clicks a toggle button to toggle it on, the button is first
+ \e pressed and then released into the \e on state. When the user
+ clicks it again (to toggle it off), the button moves first to the
+ \e pressed state, then to the \e off state (isOn() and isDown()
+ are both FALSE).
+
+ Default buttons (as used in many dialogs) are provided by
+ TQPushButton::setDefault() and TQPushButton::setAutoDefault().
+
+ TQButton provides five Q_SIGNALS:
+ \list 1
+ \i pressed() is emitted when the button is pressed. E.g. with the mouse
+ or when animateClick() is called.
+ \i released() is emitted when the button is released. E.g. when the mouse
+ is released or the cursor is moved outside the widget.
+ \i clicked() is emitted when the button is first pressed and then
+ released when the accelerator key is typed, or when
+ animateClick() is called.
+ \i toggled(bool) is emitted when the state of a toggle button changes.
+ \i stateChanged(int) is emitted when the state of a tristate
+ toggle button changes.
+ \endlist
+
+ If the button is a text button with an ampersand (\&) in its text,
+ TQButton creates an automatic accelerator key. This code creates a
+ push button labelled "Ro<u>c</u>k \& Roll" (where the c is
+ underlined). The button gets an automatic accelerator key, Alt+C:
+
+ \code
+ TQPushButton *p = new TQPushButton( "Ro&ck && Roll", this );
+ \endcode
+
+ In this example, when the user presses Alt+C the button will call
+ animateClick().
+
+ You can also set a custom accelerator using the setAccel()
+ function. This is useful mostly for pixmap buttons because they
+ have no automatic accelerator.
+
+ \code
+ p->setPixmap( TQPixmap("print.png") );
+ p->setAccel( ALT+Key_F7 );
+ \endcode
+
+ All of the buttons provided by TQt (\l TQPushButton, \l TQToolButton,
+ \l TQCheckBox and \l TQRadioButton) can display both text and
+ pixmaps.
+
+ To subclass TQButton, you must reimplement at least drawButton()
+ (to draw the button's outline) and drawButtonLabel() (to draw its
+ text or pixmap). It is generally advisable to reimplement
+ tqsizeHint() as well, and sometimes hitButton() (to determine
+ whether a button press is within the button).
+
+ To reduce flickering, TQButton::paintEvent() sets up a pixmap that
+ the drawButton() function draws in. You should not reimplement
+ paintEvent() for a subclass of TQButton unless you want to take
+ over all drawing.
+
+ \sa TQButtonGroup
+*/
+
+
+/*!
+ \enum TQButton::ToggleType
+
+ This enum type defines what a button can do in response to a
+ mouse/keyboard press:
+
+ \value SingleShot pressing the button causes an action, then the
+ button returns to the unpressed state.
+
+ \value Toggle pressing the button toggles it between an \c On and
+ an \c Off state.
+
+ \value Tristate pressing the button cycles between the three
+ states \c On, \c Off and \c NoChange
+*/
+
+/*!
+ \enum TQButton::ToggleState
+
+ This enum defines the state of a toggle button.
+
+ \value Off the button is in the "off" state
+ \value NoChange the button is in the default/unchanged state
+ \value On the button is in the "on" state
+*/
+
+/*!
+ \property TQButton::accel
+ \brief the accelerator associated with the button
+
+ This property is 0 if there is no accelerator set. If you set this
+ property to 0 then any current accelerator is removed.
+*/
+
+/*!
+ \property TQButton::autoRepeat
+ \brief whether autoRepeat is enabled
+
+ If autoRepeat is enabled then the clicked() signal is emitted at
+ regular intervals if the button is down. This property has no
+ effect on toggle buttons. autoRepeat is off by default.
+*/
+
+/*! \property TQButton::autoResize
+ \brief whether autoResize is enabled
+ \obsolete
+
+ If autoResize is enabled then the button will resize itself
+ whenever the contents are changed.
+*/
+
+/*!
+ \property TQButton::down
+ \brief whether the button is pressed
+
+ If this property is TRUE, the button is pressed down. The Q_SIGNALS
+ pressed() and clicked() are not emitted if you set this property
+ to TRUE. The default is FALSE.
+*/
+
+/*!
+ \property TQButton::exclusiveToggle
+ \brief whether the button is an exclusive toggle
+
+ If this property is TRUE and the button is in a TQButtonGroup, the
+ button can only be toggled off by another one being toggled on.
+ The default is FALSE.
+*/
+
+/*!
+ \property TQButton::on
+ \brief whether the button is toggled
+
+ This property should only be set for toggle buttons.
+*/
+
+/*!
+ \fn void TQButton::setOn( bool on )
+
+ Sets the state of this button to On if \a on is TRUE; otherwise to
+ Off.
+
+ \sa toggleState
+*/
+
+/*!
+ \property TQButton::pixmap
+ \brief the pixmap shown on the button
+
+ If the pixmap is monochrome (i.e. it is a TQBitmap or its \link
+ TQPixmap::depth() depth\endlink is 1) and it does not have a tqmask,
+ this property will set the pixmap to be its own tqmask. The purpose
+ of this is to draw transtqparent bitmaps which are important for
+ toggle buttons, for example.
+
+ pixmap() returns 0 if no pixmap was set.
+*/
+
+/*!
+ \property TQButton::text
+ \brief the text shown on the button
+
+ This property will return a TQString::null if the button has no
+ text. If the text has an ampersand (\&) in it, then an
+ accelerator is automatically created for it using the character
+ that follows the '\&' as the accelerator key. Any previous
+ accelerator will be overwritten, or cleared if no accelerator is
+ defined by the text.
+
+ There is no default text.
+*/
+
+/*!
+ \property TQButton::toggleButton
+ \brief whether the button is a toggle button
+
+ The default value is FALSE.
+*/
+
+/*!
+ \fn TQButton::setToggleButton( bool b )
+
+ If \a b is TRUE, this button becomes a toggle button; if \a b is
+ FALSE, this button becomes a command button.
+
+ \sa toggleButton
+*/
+
+/*!
+ \property TQButton::toggleState
+ \brief the state of the toggle button
+
+ If this property is changed then it does not cause the button
+ to be repainted.
+*/
+
+/*!
+ \property TQButton::toggleType
+ \brief the type of toggle on the button
+
+ The default toggle type is \c SingleShot.
+
+ \sa TQButton::ToggleType
+*/
+
+/*!
+ Constructs a standard button called \a name with tqparent \a tqparent,
+ using the widget flags \a f.
+
+ If \a tqparent is a TQButtonGroup, this constructor calls
+ TQButtonGroup::insert().
+*/
+
+TQButton::TQButton( TQWidget *tqparent, const char *name, WFlags f )
+ : TQWidget( tqparent, name, f )
+{
+ bpixmap = 0;
+ toggleTyp = SingleShot; // button is simple
+ buttonDown = FALSE; // button is up
+ stat = Off; // button is off
+ mlbDown = FALSE; // mouse left button up
+ autoresize = FALSE; // not auto resizing
+ animation = FALSE; // no pending animateClick
+ repeat = FALSE; // not in autorepeat mode
+ d = 0;
+#ifndef TQT_NO_BUTTONGROUP
+ if ( ::tqqt_cast<TQButtonGroup*>(tqparent) ) {
+ setGroup((TQButtonGroup*)tqparent);
+ group()->insert( this ); // insert into button group
+ }
+#endif
+ setFocusPolicy( Qt::TabFocus );
+}
+
+/*!
+ Destroys the button.
+ */
+TQButton::~TQButton()
+{
+#ifndef TQT_NO_BUTTONGROUP
+ if ( group() )
+ group()->remove( this );
+#endif
+ delete bpixmap;
+ delete d;
+}
+
+
+/*!
+ \fn void TQButton::pressed()
+
+ This signal is emitted when the button is pressed down.
+
+ \sa released(), clicked()
+*/
+
+/*!
+ \fn void TQButton::released()
+
+ This signal is emitted when the button is released.
+
+ \sa pressed(), clicked(), toggled()
+*/
+
+/*!
+ \fn void TQButton::clicked()
+
+ This signal is emitted when the button is activated (i.e. first
+ pressed down and then released when the mouse cursor is inside the
+ button), when the accelerator key is typed or when animateClick()
+ is called. This signal is \e not emitted if you call setDown().
+
+ The TQButtonGroup::clicked() signal does the same job, if you want
+ to connect several buttons to the same slot.
+
+ \warning Don't launch a model dialog in response to this signal
+ for a button that has \c autoRepeat turned on.
+
+ \sa pressed(), released(), toggled() autoRepeat down
+*/
+
+/*!
+ \fn void TQButton::toggled( bool on )
+
+ This signal is emitted whenever a toggle button changes status. \a
+ on is TRUE if the button is on, or FALSE if the button is off.
+
+ This may be the result of a user action, toggle() slot activation,
+ or because setOn() was called.
+
+ \sa clicked()
+*/
+
+/*!
+ \fn void TQButton::stateChanged( int state )
+
+ This signal is emitted whenever a toggle button changes state. \a
+ state is \c On if the button is on, \c NoChange if it is in the
+ \link TQCheckBox::setTristate() "no change" state\endlink or \c Off
+ if the button is off.
+
+ This may be the result of a user action, toggle() slot activation,
+ setState(), or because setOn() was called.
+
+ \sa clicked() TQButton::ToggleState
+*/
+
+void TQButton::setText( const TQString &text )
+{
+ if ( btext == text )
+ return;
+ btext = text;
+#ifndef TQT_NO_ACCEL
+ setAccel( TQAccel::shortcutKey( text ) );
+#endif
+
+ if ( bpixmap ) {
+ delete bpixmap;
+ bpixmap = 0;
+ }
+
+ if ( autoresize )
+ adjustSize();
+
+ update();
+ updateGeometry();
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::NameChanged );
+#endif
+}
+
+void TQButton::setPixmap( const TQPixmap &pixmap )
+{
+ if ( bpixmap && bpixmap->serialNumber() == pixmap.serialNumber() )
+ return;
+
+ bool newSize;
+ if ( bpixmap ) {
+ newSize = pixmap.width() != bpixmap->width() ||
+ pixmap.height() != bpixmap->height();
+ *bpixmap = pixmap;
+ } else {
+ newSize = TRUE;
+ bpixmap = new TQPixmap( pixmap );
+ TQ_CHECK_PTR( bpixmap );
+ }
+ if ( bpixmap->depth() == 1 && !bpixmap->tqmask() )
+ bpixmap->setMask( *((TQBitmap *)bpixmap) );
+ if ( !btext.isNull() ) {
+ btext = TQString::null;
+#ifndef TQT_NO_ACCEL
+ setAccel( TQKeySequence() );
+#endif
+ }
+ if ( autoresize && newSize )
+ adjustSize();
+ if ( autoMask() )
+ updateMask();
+ update();
+ if ( newSize )
+ updateGeometry();
+}
+
+
+#ifndef TQT_NO_ACCEL
+TQKeySequence TQButton::accel() const
+{
+ if ( d && d->a )
+ return d->a->key( 0 );
+ return TQKeySequence();
+}
+
+void TQButton::setAccel( const TQKeySequence& key )
+{
+ if ( d && d->a )
+ d->a->clear();
+ if ( key.isEmpty() )
+ return;
+ ensureData();
+ if ( !d->a ) {
+ d->a = new TQAccel( this, "buttonAccel" );
+ connect( d->a, TQT_SIGNAL( activated(int) ), this, TQT_SLOT( animateClick() ) );
+ connect( d->a, TQT_SIGNAL( activatedAmbiguously(int) ), this, TQT_SLOT( setFocus() ) );
+ }
+ d->a->insertItem( key, 0 );
+}
+#endif
+
+#ifndef TQT_NO_COMPAT
+
+void TQButton::setAutoResize( bool enable )
+{
+ if ( (bool)autoresize != enable ) {
+ autoresize = enable;
+ if ( autoresize )
+ adjustSize(); // calls resize which repaints
+ }
+}
+
+#endif
+
+void TQButton::setAutoRepeat( bool enable )
+{
+ repeat = (uint)enable;
+ if ( repeat && mlbDown )
+ timer()->start( AUTO_REPEAT_DELAY, TRUE );
+}
+
+/*!
+ Performs an animated click: the button is pressed and released a
+ short while later.
+
+ The pressed(), released(), clicked(), toggled(), and
+ stateChanged() Q_SIGNALS are emitted as appropriate.
+
+ This function does nothing if the button is \link setEnabled()
+ disabled. \endlink
+
+ \sa setAccel()
+*/
+
+void TQButton::animateClick()
+{
+ if ( !isEnabled() || animation )
+ return;
+ animation = TRUE;
+ buttonDown = TRUE;
+ tqrepaint( FALSE );
+ emit pressed();
+ TQTimer::singleShot( 100, this, TQT_SLOT(animateTimeout()) );
+}
+
+void TQButton::emulateClick()
+{
+ if ( !isEnabled() || animation )
+ return;
+ animation = TRUE;
+ buttonDown = TRUE;
+ emit pressed();
+ animateTimeout();
+}
+
+void TQButton::setDown( bool enable )
+{
+ if ( d )
+ timer()->stop();
+ mlbDown = FALSE; // the safe setting
+ if ( (bool)buttonDown != enable ) {
+ buttonDown = enable;
+ tqrepaint( FALSE );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+ }
+}
+
+/*!
+ Sets the toggle state of the button to \a s. \a s can be \c Off, \c
+ NoChange or \c On.
+*/
+
+void TQButton::setState( ToggleState s )
+{
+ if ( !toggleTyp ) {
+#if defined(TQT_CHECK_STATE)
+ qWarning( "TQButton::setState() / setOn: (%s) Only toggle buttons "
+ "may be switched", name( "unnamed" ) );
+#endif
+ return;
+ }
+
+ if ( (ToggleState)stat != s ) { // changed state
+ bool was = stat != Off;
+ stat = s;
+ if ( autoMask() )
+ updateMask();
+ tqrepaint( FALSE );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+ // ### toggled for tristate makes no sense. Don't emit the signal in 4.0
+ if ( was != (stat != Off) )
+ emit toggled( stat != Off );
+ emit stateChanged( s );
+ }
+}
+
+
+/*!
+ Returns TRUE if \a pos is inside the clickable button rectangle;
+ otherwise returns FALSE.
+
+ By default, the clickable area is the entire widget. Subclasses
+ may reimplement it, though.
+*/
+bool TQButton::hitButton( const TQPoint &pos ) const
+{
+ return TQT_TQRECT_OBJECT(rect()).tqcontains( pos );
+}
+
+/*!
+ Draws the button. The default implementation does nothing.
+
+ This virtual function is reimplemented by subclasses to draw real
+ buttons. At some point, these reimplementations should call
+ drawButtonLabel().
+
+ \sa drawButtonLabel(), paintEvent()
+*/
+#if (TQT_VERSION-0 >= 0x040000)
+#error "TQButton. Make pure virtual"
+#endif
+void TQButton::drawButton( TQPainter * )
+{
+ return;
+}
+
+/*!
+ Draws the button text or pixmap.
+
+ This virtual function is reimplemented by subclasses to draw real
+ buttons. It is invoked by drawButton().
+
+ \sa drawButton(), paintEvent()
+*/
+
+void TQButton::drawButtonLabel( TQPainter * )
+{
+ return;
+}
+
+/*! \reimp */
+void TQButton::keyPressEvent( TQKeyEvent *e )
+{
+ switch ( e->key() ) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ {
+#ifndef TQT_NO_PUSHBUTTON
+ TQPushButton *pb = (TQPushButton*)tqqt_cast( "TQPushButton" );
+ if ( pb && ( pb->autoDefault() || pb->isDefault() ) )
+ emit clicked();
+ else
+#endif
+ e->ignore();
+ }
+ break;
+ case Qt::Key_Space:
+ if ( !e->isAutoRepeat() ) {
+ setDown( TRUE );
+#ifndef TQT_NO_PUSHBUTTON
+ if ( ::tqqt_cast<TQPushButton*>(this) )
+ emit pressed();
+ else
+#endif
+ e->ignore();
+ }
+ break;
+ case Qt::Key_Up:
+ case Qt::Key_Left:
+#ifndef TQT_NO_BUTTONGROUP
+ if ( group() ) {
+ group()->moveFocus( e->key() );
+ } else
+#endif
+ {
+#ifdef USE_QT4
+ focusNextPrevChild( FALSE );
+#else // USE_QT4
+ TQFocusEvent::setReason(TQFocusEvent::Backtab);
+ focusNextPrevChild( FALSE );
+ TQFocusEvent::resetReason();
+#endif // USE_QT4
+ }
+ break;
+ case Qt::Key_Right:
+ case Qt::Key_Down:
+#ifndef TQT_NO_BUTTONGROUP
+ if ( group() ) {
+ group()->moveFocus( e->key() );
+ } else
+#endif
+ {
+#ifdef USE_QT4
+ focusNextPrevChild( TRUE );
+#else // USE_QT4
+ TQFocusEvent::setReason(TQFocusEvent::Tab);
+ focusNextPrevChild( TRUE );
+ TQFocusEvent::resetReason();
+#endif // USE_QT4
+ }
+ break;
+ case Key_Escape:
+ if ( buttonDown ) {
+ buttonDown = FALSE;
+ update();
+ break;
+ }
+ // fall through
+ default:
+ e->ignore();
+ }
+}
+
+/*! \reimp */
+void TQButton::keyReleaseEvent( TQKeyEvent * e)
+{
+ switch ( e->key() ) {
+ case Qt::Key_Space:
+ if ( buttonDown && !e->isAutoRepeat() ) {
+ buttonDown = FALSE;
+ nextState();
+ emit released();
+ emit clicked();
+ }
+ break;
+ default:
+ e->ignore();
+ }
+}
+
+/*! \reimp */
+void TQButton::mousePressEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton ) {
+ e->ignore();
+ return;
+ }
+ bool hit = hitButton( e->pos() );
+ if ( hit ) { // mouse press on button
+ mlbDown = TRUE; // left mouse button down
+ buttonDown = TRUE;
+ if ( autoMask() )
+ updateMask();
+
+ tqrepaint( FALSE );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+ TQGuardedPtr<TQTimer> t = timer();
+ emit pressed();
+ if ( t && repeat )
+ t->start( AUTO_REPEAT_DELAY, TRUE );
+ }
+}
+
+/*! \reimp */
+void TQButton::mouseReleaseEvent( TQMouseEvent *e)
+{
+ if ( e->button() != Qt::LeftButton ) {
+
+ // clean up apperance if left button has been pressed
+ if (mlbDown || buttonDown) {
+ mlbDown = FALSE;
+ buttonDown = FALSE;
+
+ if ( autoMask() )
+ updateMask();
+ tqrepaint( FALSE );
+ }
+
+ e->ignore();
+ return;
+ }
+ if ( !mlbDown )
+ return;
+ if ( d )
+ timer()->stop();
+
+ const bool oldButtonDown = buttonDown;
+ mlbDown = FALSE; // left mouse button up
+ buttonDown = FALSE;
+ if ( hitButton( e->pos() ) ) { // mouse release on button
+ nextState();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+ emit released();
+ emit clicked();
+ } else {
+ tqrepaint( FALSE );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+ if (oldButtonDown)
+ emit released();
+ }
+}
+
+/*! \reimp */
+void TQButton::mouseMoveEvent( TQMouseEvent *e )
+{
+ if ( !((e->state() & Qt::LeftButton) && mlbDown) ) {
+ e->ignore();
+ return; // left mouse button is up
+ }
+ if ( hitButton(e->pos()) ) { // mouse move in button
+ if ( !buttonDown ) {
+ buttonDown = TRUE;
+ tqrepaint( FALSE );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+ emit pressed();
+ }
+ } else { // mouse move outside button
+ if ( buttonDown ) {
+ buttonDown = FALSE;
+ tqrepaint( FALSE );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+ emit released();
+ }
+ }
+}
+
+
+/*!
+ Handles paint events for buttons. Small and typically complex
+ buttons are painted double-buffered to reduce flicker. The
+ actual drawing is done in the virtual functions drawButton() and
+ drawButtonLabel().
+
+ \sa drawButton(), drawButtonLabel()
+*/
+void TQButton::paintEvent( TQPaintEvent *)
+{
+ TQSharedDoubleBuffer buffer( this );
+ drawButton( buffer.painter() );
+}
+
+/*! \reimp */
+void TQButton::focusInEvent( TQFocusEvent * e)
+{
+ TQWidget::focusInEvent( e );
+}
+
+/*! \reimp */
+void TQButton::focusOutEvent( TQFocusEvent * e )
+{
+ buttonDown = FALSE;
+ TQWidget::focusOutEvent( e );
+}
+
+/*!
+ Internal slot used for auto repeat.
+*/
+void TQButton::autoRepeatTimeout()
+{
+ if ( mlbDown && isEnabled() && autoRepeat() ) {
+ TQGuardedPtr<TQTimer> t = timer();
+ if ( buttonDown ) {
+ emit released();
+ emit clicked();
+ emit pressed();
+ }
+ if ( t )
+ t->start( AUTO_REPEAT_PERIOD, TRUE );
+ }
+}
+
+/*!
+ Internal slot used for the second stage of animateClick().
+*/
+void TQButton::animateTimeout()
+{
+ if ( !animation )
+ return;
+ animation = FALSE;
+ buttonDown = FALSE;
+ nextState();
+ emit released();
+ emit clicked();
+}
+
+
+void TQButton::nextState()
+{
+ bool t = isToggleButton() && !( isOn() && isExclusiveToggle() );
+ bool was = stat != Off;
+ if ( t ) {
+ if ( toggleTyp == Tristate )
+ stat = ( stat + 1 ) % 3;
+ else
+ stat = stat ? Off : On;
+ }
+ if ( autoMask() )
+ updateMask();
+ tqrepaint( FALSE );
+ if ( t ) {
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+ if ( was != (stat != Off) )
+ emit toggled( stat != Off );
+ emit stateChanged( stat );
+ }
+}
+
+/*! \reimp */
+void TQButton::enabledChange( bool e )
+{
+ if ( !isEnabled() )
+ setDown( FALSE );
+ TQWidget::enabledChange( e );
+}
+
+
+/*!
+ Toggles the state of a toggle button.
+
+ \sa isOn(), setOn(), toggled(), isToggleButton()
+*/
+void TQButton::toggle()
+{
+ if ( isToggleButton() )
+ setOn( !isOn() );
+}
+
+/*!
+ Sets the toggle type of the button to \a type.
+
+ \a type can be set to \c SingleShot, \c Toggle and \c Tristate.
+*/
+void TQButton::setToggleType( ToggleType type )
+{
+ toggleTyp = type;
+ if ( type != Tristate && stat == NoChange )
+ setState( On );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ else
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+}
+
+bool TQButton::isExclusiveToggle() const
+{
+#ifndef TQT_NO_BUTTONGROUP
+ return group() && ( group()->isExclusive() ||
+ (group()->isRadioButtonExclusive() &&
+ ::tqqt_cast<TQRadioButton*>(this)) );
+#else
+ return FALSE;
+#endif
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqbutton.h b/tqtinterface/qt4/src/widgets/tqbutton.h
new file mode 100644
index 0000000..f75de1a
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqbutton.h
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Definition of TQButton widget class
+**
+** Created : 940206
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQBUTTON_H
+#define TQBUTTON_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqkeysequence.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_BUTTON
+
+
+class TQButtonGroup;
+class TQToolBar;
+class TQButtonData;
+
+class TQ_EXPORT TQButton : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( ToggleType ToggleState )
+ Q_PROPERTY( TQString text READ text WRITE setText )
+ Q_PROPERTY( TQPixmap pixmap READ pixmap WRITE setPixmap )
+ Q_PROPERTY( TQKeySequence accel READ accel WRITE setAccel )
+ Q_PROPERTY( bool toggleButton READ isToggleButton )
+ Q_PROPERTY( ToggleType toggleType READ toggleType )
+ Q_PROPERTY( bool down READ isDown WRITE setDown DESIGNABLE false )
+ Q_PROPERTY( bool on READ isOn )
+ Q_PROPERTY( ToggleState toggleState READ state )
+ Q_PROPERTY( bool autoResize READ autoResize WRITE setAutoResize DESIGNABLE false )
+ Q_PROPERTY( bool autoRepeat READ autoRepeat WRITE setAutoRepeat )
+ Q_PROPERTY( bool exclusiveToggle READ isExclusiveToggle )
+
+public:
+ TQButton( TQWidget* tqparent=0, const char* name=0, WFlags f=0 );
+ ~TQButton();
+
+ TQString text() const;
+ virtual void setText( const TQString &);
+ const TQPixmap *pixmap() const;
+ virtual void setPixmap( const TQPixmap & );
+
+#ifndef TQT_NO_ACCEL
+ TQKeySequence accel() const;
+ virtual void setAccel( const TQKeySequence& );
+#endif
+
+ bool isToggleButton() const;
+
+ enum ToggleType { SingleShot, Toggle, Tristate };
+ ToggleType toggleType() const;
+
+ virtual void setDown( bool );
+ bool isDown() const;
+
+ bool isOn() const;
+
+ enum ToggleState { Off, NoChange, On };
+ ToggleState state() const;
+
+#ifndef TQT_NO_COMPAT
+ bool autoResize() const;
+ void setAutoResize( bool );
+#endif
+
+ bool autoRepeat() const;
+ virtual void setAutoRepeat( bool );
+ bool isExclusiveToggle() const;
+
+ TQButtonGroup *group() const;
+
+public Q_SLOTS:
+ void animateClick();
+ void toggle();
+
+Q_SIGNALS:
+ void pressed();
+ void released();
+ void clicked();
+ void toggled( bool );
+ void stateChanged( int );
+
+protected:
+ void setToggleButton( bool );
+ virtual void setToggleType( ToggleType );
+ void setOn( bool );
+ virtual void setState( ToggleState );
+
+ virtual bool hitButton( const TQPoint &pos ) const;
+ virtual void drawButton( TQPainter * );
+ virtual void drawButtonLabel( TQPainter * );
+
+ void keyPressEvent( TQKeyEvent *);
+ void keyReleaseEvent( TQKeyEvent *);
+ void mousePressEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void paintEvent( TQPaintEvent * );
+ void focusInEvent( TQFocusEvent * );
+ void focusOutEvent( TQFocusEvent * );
+
+ void enabledChange( bool );
+
+private Q_SLOTS:
+ void animateTimeout();
+ void autoRepeatTimeout();
+ void emulateClick();
+
+private:
+ TQString btext;
+ TQPixmap *bpixmap;
+ uint toggleTyp : 2;
+ uint buttonDown : 1;
+ uint stat : 2;
+ uint mlbDown : 1;
+ uint autoresize : 1;
+ uint animation : 1;
+ uint repeat : 1;
+ TQButtonData *d;
+
+ friend class TQButtonGroup;
+ friend class TQToolBar;
+ void ensureData();
+ virtual void setGroup( TQButtonGroup* );
+ TQTimer *timer();
+ void nextState();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQButton( const TQButton & );
+ TQButton &operator=( const TQButton & );
+#endif
+};
+
+
+inline TQString TQButton::text() const
+{
+ return btext;
+}
+
+inline const TQPixmap *TQButton::pixmap() const
+{
+ return bpixmap;
+}
+
+inline bool TQButton::isToggleButton() const
+{
+ return toggleTyp != SingleShot;
+}
+
+inline bool TQButton::isDown() const
+{
+ return buttonDown;
+}
+
+inline bool TQButton::isOn() const
+{
+ return stat != Off;
+}
+
+#ifndef TQT_NO_COMPAT
+inline bool TQButton::autoResize() const
+{
+ return autoresize;
+}
+#endif
+
+inline bool TQButton::autoRepeat() const
+{
+ return repeat;
+}
+
+inline TQButton::ToggleState TQButton::state() const
+{
+ return ToggleState(stat);
+}
+
+inline void TQButton::setToggleButton( bool b )
+{
+ setToggleType( b ? Toggle : SingleShot );
+}
+
+inline void TQButton::setOn( bool y )
+{
+ setState( y ? On : Off );
+}
+
+inline TQButton::ToggleType TQButton::toggleType() const
+{
+ return ToggleType(toggleTyp);
+}
+
+
+#endif // TQT_NO_BUTTON
+
+#endif // TQBUTTON_H
diff --git a/tqtinterface/qt4/src/widgets/tqbuttongroup.cpp b/tqtinterface/qt4/src/widgets/tqbuttongroup.cpp
new file mode 100644
index 0000000..1879a8a
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqbuttongroup.cpp
@@ -0,0 +1,691 @@
+/****************************************************************************
+**
+** Implementation of TQButtonGroup class
+**
+** Created : 950130
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqbuttongroup.h"
+#ifndef TQT_NO_BUTTONGROUP
+#include "tqbutton.h"
+#include "tqptrlist.h"
+#include "tqapplication.h"
+#include "tqradiobutton.h"
+
+
+
+/*!
+ \class TQButtonGroup tqbuttongroup.h
+ \brief The TQButtonGroup widget organizes TQButton widgets in a group.
+
+ \ingroup organizers
+ \ingroup geomanagement
+ \ingroup appearance
+ \mainclass
+
+ A button group widget makes it easier to deal with groups of
+ buttons. Each button in a button group has a unique identifier.
+ The button group emits a clicked() signal with this identifier
+ when a button in the group is clicked. This makes a button group
+ particularly useful when you have several similar buttons and want
+ to connect all their clicked() Q_SIGNALS to a single slot.
+
+ An \link setExclusive() exclusive\endlink button group switches
+ off all toggle buttons except the one that was clicked. A button
+ group is, by default, non-exclusive. Note that all radio buttons
+ that are inserted into a button group are mutually exclusive even
+ if the button group is non-exclusive. (See
+ setRadioButtonExclusive().)
+
+ There are two ways of using a button group:
+ \list
+ \i The button group is the tqparent widget of a number of buttons,
+ i.e. the button group is the tqparent argument in the button
+ constructor. The buttons are assigned identifiers 0, 1, 2, etc.,
+ in the order they are created. A TQButtonGroup can display a frame
+ and a title because it inherits TQGroupBox.
+ \i The button group is an invisible widget and the contained
+ buttons have some other tqparent widget. In this usage, each button
+ must be manually inserted, using insert(), into the button group
+ and given an identifier.
+ \endlist
+
+ A button can be removed from the group with remove(). A pointer to
+ a button with a given id can be obtained using tqfind(). The id of a
+ button is available using id(). A button can be set \e on with
+ setButton(). The number of buttons in the group is returned by
+ count().
+
+ <img src=qbttngrp-m.png> <img src=qbttngrp-w.png>
+
+ \sa TQPushButton, TQCheckBox, TQRadioButton
+*/
+
+/*!
+ \property TQButtonGroup::exclusive
+ \brief whether the button group is exclusive
+
+ If this property is TRUE, then the buttons in the group are
+ toggled, and to untoggle a button you must click on another button
+ in the group. The default value is FALSE.
+*/
+
+/*!
+ \property TQButtonGroup::radioButtonExclusive
+ \brief whether the radio buttons in the group are exclusive
+
+ If this property is TRUE (the default), the \link TQRadioButton
+ radiobuttons\endlink in the group are treated exclusively.
+*/
+
+struct TQButtonItem
+{
+ TQButton *button;
+ int id;
+};
+
+
+class TQButtonList: public TQPtrList<TQButtonItem>
+{
+public:
+ TQButtonList() {}
+ ~TQButtonList() {}
+};
+
+
+typedef TQPtrListIterator<TQButtonItem> TQButtonListIt;
+
+
+/*!
+ Constructs a button group with no title.
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+*/
+
+TQButtonGroup::TQButtonGroup( TQWidget *tqparent, const char *name )
+ : TQGroupBox( tqparent, name )
+{
+ init();
+}
+
+/*!
+ Constructs a button group with the title \a title.
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+*/
+
+TQButtonGroup::TQButtonGroup( const TQString &title, TQWidget *tqparent,
+ const char *name )
+ : TQGroupBox( title, tqparent, name )
+{
+ init();
+}
+
+/*!
+ Constructs a button group with no title. Child widgets will be
+ arranged in \a strips rows or columns (depending on \a
+ orientation).
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+*/
+
+TQButtonGroup::TQButtonGroup( int strips, Qt::Orientation orientation,
+ TQWidget *tqparent, const char *name )
+ : TQGroupBox( strips, orientation, tqparent, name )
+{
+ init();
+}
+
+/*!
+ Constructs a button group with title \a title. Child widgets will
+ be arranged in \a strips rows or columns (depending on \a
+ orientation).
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+*/
+
+TQButtonGroup::TQButtonGroup( int strips, Qt::Orientation orientation,
+ const TQString &title, TQWidget *tqparent,
+ const char *name )
+ : TQGroupBox( strips, orientation, title, tqparent, name )
+{
+ init();
+}
+
+/*!
+ Initializes the button group.
+*/
+
+void TQButtonGroup::init()
+{
+ buttons = new TQButtonList;
+ TQ_CHECK_PTR( buttons );
+ buttons->setAutoDelete( TRUE );
+ excl_grp = FALSE;
+ radio_excl = TRUE;
+}
+
+/*! \reimp */
+
+TQButtonGroup::~TQButtonGroup()
+{
+ TQButtonList * tmp = buttons;
+ TQButtonItem *bi = tmp->first();
+ buttons = 0;
+ while( bi ) {
+ bi->button->setGroup(0);
+ bi = tmp->next();
+ }
+ delete tmp;
+}
+
+bool TQButtonGroup::isExclusive() const
+{
+ return excl_grp;
+}
+
+void TQButtonGroup::setExclusive( bool enable )
+{
+ excl_grp = enable;
+}
+
+
+/*!
+ Inserts the \a button with the identifier \a id into the button
+ group. Returns the button identifier.
+
+ Buttons are normally inserted into a button group automatically by
+ passing the button group as the tqparent when the button is
+ constructed. So it is not necessary to manually insert buttons
+ that have this button group as their tqparent widget. An exception
+ is when you want custom identifiers instead of the default 0, 1,
+ 2, etc., or if you want the buttons to have some other tqparent.
+
+ The button is assigned the identifier \a id or an automatically
+ generated identifier. It works as follows: If \a id >= 0, this
+ identifier is assigned. If \a id == -1 (default), the identifier
+ is equal to the number of buttons in the group. If \a id is any
+ other negative integer, for instance -2, a unique identifier
+ (negative integer \<= -2) is generated. No button has an id of -1.
+
+ \sa tqfind(), remove(), setExclusive()
+*/
+
+int TQButtonGroup::insert( TQButton *button, int id )
+{
+ if ( button->group() )
+ button->group()->remove( button );
+
+ static int seq_no = -2;
+ TQButtonItem *bi = new TQButtonItem;
+ TQ_CHECK_PTR( bi );
+
+ if ( id < -1 )
+ bi->id = seq_no--;
+ else if ( id == -1 )
+ bi->id = buttons->count();
+ else
+ bi->id = id;
+
+ bi->button = button;
+ button->setGroup(this);
+ buttons->append( bi );
+
+ connect( button, TQT_SIGNAL(pressed()) , TQT_SLOT(buttonPressed()) );
+ connect( button, TQT_SIGNAL(released()), TQT_SLOT(buttonReleased()) );
+ connect( button, TQT_SIGNAL(clicked()) , TQT_SLOT(buttonClicked()) );
+ connect( button, TQT_SIGNAL(toggled(bool)) , TQT_SLOT(buttonToggled(bool)) );
+
+ if ( button->isToggleButton() && !button->isOn() &&
+ selected() && (selected()->focusPolicy() & Qt::TabFocus) != 0 )
+ button->setFocusPolicy( (Qt::FocusPolicy)(button->focusPolicy() &
+ ~Qt::TabFocus) );
+
+ return bi->id;
+}
+
+/*!
+ Returns the number of buttons in the group.
+*/
+int TQButtonGroup::count() const
+{
+ return buttons->count();
+}
+
+/*!
+ Removes the \a button from the button group.
+
+ \sa insert()
+*/
+
+void TQButtonGroup::remove( TQButton *button )
+{
+ if ( !buttons )
+ return;
+
+ TQButtonListIt it( *buttons );
+ TQButtonItem *i;
+ while ( (i=it.current()) != 0 ) {
+ ++it;
+ if ( i->button == button ) {
+ buttons->remove( i );
+ button->setGroup(0);
+ button->disconnect( this );
+ return;
+ }
+ }
+}
+
+
+/*!
+ Returns the button with the specified identifier \a id, or 0 if
+ the button was not found.
+*/
+
+TQButton *TQButtonGroup::tqfind( int id ) const
+{
+ // introduce a TQButtonListIt if calling anything
+ for ( TQButtonItem *i=buttons->first(); i; i=buttons->next() )
+ if ( i->id == id )
+ return i->button;
+ return 0;
+}
+
+
+/*!
+ \fn void TQButtonGroup::pressed( int id )
+
+ This signal is emitted when a button in the group is \link
+ TQButton::pressed() pressed\endlink. The \a id argument is the
+ button's identifier.
+
+ \sa insert()
+*/
+
+/*!
+ \fn void TQButtonGroup::released( int id )
+
+ This signal is emitted when a button in the group is \link
+ TQButton::released() released\endlink. The \a id argument is the
+ button's identifier.
+
+ \sa insert()
+*/
+
+/*!
+ \fn void TQButtonGroup::clicked( int id )
+
+ This signal is emitted when a button in the group is \link
+ TQButton::clicked() clicked\endlink. The \a id argument is the
+ button's identifier.
+
+ \sa insert()
+*/
+
+
+/*!
+ \internal
+ This slot is activated when one of the buttons in the group emits the
+ TQButton::pressed() signal.
+*/
+
+void TQButtonGroup::buttonPressed()
+{
+ // introduce a TQButtonListIt if calling anything
+ int id = -1;
+ TQButton *bt = (TQButton *)sender(); // object that sent the signal
+ for ( register TQButtonItem *i=buttons->first(); i; i=buttons->next() )
+ if ( bt == i->button ) { // button was clicked
+ id = i->id;
+ break;
+ }
+ if ( id != -1 )
+ emit pressed( id );
+}
+
+/*!
+ \internal
+ This slot is activated when one of the buttons in the group emits the
+ TQButton::released() signal.
+*/
+
+void TQButtonGroup::buttonReleased()
+{
+ // introduce a TQButtonListIt if calling anything
+ int id = -1;
+ TQButton *bt = (TQButton *)sender(); // object that sent the signal
+ for ( register TQButtonItem *i=buttons->first(); i; i=buttons->next() )
+ if ( bt == i->button ) { // button was clicked
+ id = i->id;
+ break;
+ }
+ if ( id != -1 )
+ emit released( id );
+}
+
+/*!
+ \internal
+ This slot is activated when one of the buttons in the group emits the
+ TQButton::clicked() signal.
+*/
+
+void TQButtonGroup::buttonClicked()
+{
+ // introduce a TQButtonListIt if calling anything
+ int id = -1;
+ TQButton *bt = ::tqqt_cast<TQButton*>(sender()); // object that sent the signal
+#if defined(TQT_CHECK_NULL)
+ TQ_ASSERT( bt );
+#endif
+ for ( register TQButtonItem *i=buttons->first(); i; i=buttons->next() ) {
+ if ( bt == i->button ) { // button was clicked
+ id = i->id;
+ break;
+ }
+ }
+ if ( id != -1 )
+ emit clicked( id );
+}
+
+
+/*!
+ \internal
+ This slot is activated when one of the buttons in the group emits the
+ TQButton::toggled() signal.
+*/
+
+void TQButtonGroup::buttonToggled( bool on )
+{
+ // introduce a TQButtonListIt if calling anything
+ if ( !on || (!excl_grp && !radio_excl) )
+ return;
+ TQButton *bt = ::tqqt_cast<TQButton*>(sender()); // object that sent the signal
+#if defined(TQT_CHECK_NULL)
+ TQ_ASSERT( bt );
+ TQ_ASSERT( bt->isToggleButton() );
+#endif
+
+ if ( !excl_grp && !::tqqt_cast<TQRadioButton*>(bt) )
+ return;
+ TQButtonItem * i = buttons->first();
+ bool hasTabFocus = FALSE;
+
+ while( i != 0 && hasTabFocus == FALSE ) {
+ if ( ( excl_grp || ::tqqt_cast<TQRadioButton*>(i->button) ) &&
+ (i->button->focusPolicy() & Qt::TabFocus) )
+ hasTabFocus = TRUE;
+ i = buttons->next();
+ }
+
+ i = buttons->first();
+ while( i ) {
+ if ( bt != i->button &&
+ i->button->isToggleButton() &&
+ i->button->isOn() &&
+ ( excl_grp || ::tqqt_cast<TQRadioButton*>(i->button) ) )
+ i->button->setOn( FALSE );
+ if ( ( excl_grp || ::tqqt_cast<TQRadioButton*>(i->button) ) &&
+ i->button->isToggleButton() &&
+ hasTabFocus )
+ i->button->setFocusPolicy( (Qt::FocusPolicy)(i->button->focusPolicy() &
+ ~Qt::TabFocus) );
+ i = buttons->next();
+ }
+
+ if ( hasTabFocus )
+ bt->setFocusPolicy( (Qt::FocusPolicy)(bt->focusPolicy() | Qt::TabFocus) );
+}
+
+
+
+void TQButtonGroup::setButton( int id )
+{
+ TQButton * b = tqfind( id );
+ if ( b )
+ b->setOn( TRUE );
+}
+
+void TQButtonGroup::setRadioButtonExclusive( bool on)
+{
+ radio_excl = on;
+}
+
+
+/*!
+ Moves the keyboard focus according to \a key, and if appropriate
+ checks the new focus item.
+
+ This function does nothing unless the keyboard focus points to one
+ of the button group members and \a key is one of \c Key_Up, \c
+ Key_Down, \c Key_Left and \c Key_Right.
+*/
+
+void TQButtonGroup::moveFocus( int key )
+{
+ TQWidget * f = tqApp->tqfocusWidget();
+
+ TQButtonItem * i;
+ i = buttons->first();
+ while( i && i->button != f )
+ i = buttons->next();
+
+ if ( !i || !i->button )
+ return;
+
+ TQWidget * candidate = 0;
+ int bestScore = -1;
+
+ TQPoint goal( f->mapToGlobal( f->tqgeometry().center() ) );
+
+ i = buttons->first();
+ while( i && i->button ) {
+ if ( i->button != f &&
+ i->button->isEnabled() ) {
+ TQPoint p(i->button->mapToGlobal(i->button->tqgeometry().center()));
+ int score = (p.y() - goal.y())*(p.y() - goal.y()) +
+ (p.x() - goal.x())*(p.x() - goal.x());
+ bool betterScore = score < bestScore || !candidate;
+ switch( key ) {
+ case Qt::Key_Up:
+ if ( p.y() < goal.y() && betterScore ) {
+ if ( TQABS( p.x() - goal.x() ) < TQABS( p.y() - goal.y() ) ) {
+ candidate = i->button;
+ bestScore = score;
+ } else if ( i->button->x() == f->x() ) {
+ candidate = i->button;
+ bestScore = score/2;
+ }
+ }
+ break;
+ case Qt::Key_Down:
+ if ( p.y() > goal.y() && betterScore ) {
+ if ( TQABS( p.x() - goal.x() ) < TQABS( p.y() - goal.y() ) ) {
+ candidate = i->button;
+ bestScore = score;
+ } else if ( i->button->x() == f->x() ) {
+ candidate = i->button;
+ bestScore = score/2;
+ }
+ }
+ break;
+ case Qt::Key_Left:
+ if ( p.x() < goal.x() && betterScore ) {
+ if ( TQABS( p.y() - goal.y() ) < TQABS( p.x() - goal.x() ) ) {
+ candidate = i->button;
+ bestScore = score;
+ } else if ( i->button->y() == f->y() ) {
+ candidate = i->button;
+ bestScore = score/2;
+ }
+ }
+ break;
+ case Qt::Key_Right:
+ if ( p.x() > goal.x() && betterScore ) {
+ if ( TQABS( p.y() - goal.y() ) < TQABS( p.x() - goal.x() ) ) {
+ candidate = i->button;
+ bestScore = score;
+ } else if ( i->button->y() == f->y() ) {
+ candidate = i->button;
+ bestScore = score/2;
+ }
+ }
+ break;
+ }
+ }
+ i = buttons->next();
+ }
+
+ TQButton *buttoncand = ::tqqt_cast<TQButton*>(candidate);
+ if ( buttoncand && ::tqqt_cast<TQButton*>(f) &&
+ ((TQButton*)f)->isOn() &&
+ buttoncand->isToggleButton() &&
+ ( isExclusive() || ( ::tqqt_cast<TQRadioButton*>(f) &&
+ ::tqqt_cast<TQRadioButton*>(candidate)))) {
+ if ( f->focusPolicy() & Qt::TabFocus ) {
+ f->setFocusPolicy( (Qt::FocusPolicy)(f->focusPolicy() & ~Qt::TabFocus) );
+ candidate->setFocusPolicy( (Qt::FocusPolicy)(candidate->focusPolicy()|
+ Qt::TabFocus) );
+ }
+ buttoncand->setOn( TRUE );
+ buttoncand->animateClick();
+ buttoncand->animateTimeout(); // ### crude l&f hack
+ }
+
+#ifdef USE_QT4
+ if ( candidate ) {
+ if (key == Qt::Key_Up || key == Qt::Key_Left)
+ candidate->setFocus(TQFocusEvent::Backtab);
+ else
+ candidate->setFocus(TQFocusEvent::Tab);
+ }
+#else // USE_QT4
+ if ( candidate ) {
+ if (key == Qt::Key_Up || key == Qt::Key_Left)
+ TQFocusEvent::setReason(TQFocusEvent::Backtab);
+ else
+ TQFocusEvent::setReason(TQFocusEvent::Tab);
+ candidate->setFocus();
+ TQFocusEvent::resetReason();
+ }
+#endif // USE_QT4
+}
+
+
+/*!
+ Returns the selected toggle button if exactly one is selected;
+ otherwise returns 0.
+
+ \sa selectedId()
+*/
+
+TQButton * TQButtonGroup::selected() const
+{
+ if ( !buttons )
+ return 0;
+ TQButtonListIt it( *buttons );
+ TQButtonItem *i;
+ TQButton *candidate = 0;
+
+ while ( (i = it.current()) != 0 ) {
+ ++it;
+ if ( i->button && i->button->isToggleButton() && i->button->isOn() ) {
+ if ( candidate != 0 )
+ return 0;
+ candidate = i->button;
+ }
+ }
+ return candidate;
+}
+
+/*!
+ \property TQButtonGroup::selectedId
+ \brief the selected toggle button
+
+ The toggle button is specified as an ID.
+
+ If no toggle button is selected, this property holds -1.
+
+ If setButton() is called on an exclusive group, the button with
+ the given id will be set to on and all the others will be set to
+ off.
+
+ \sa selected()
+*/
+
+int TQButtonGroup::selectedId() const
+{
+ return id( selected() );
+}
+
+
+/*!
+ Returns the id of \a button, or -1 if \a button is not a member of
+ this group.
+
+ \sa selectedId();
+*/
+
+int TQButtonGroup::id( TQButton * button ) const
+{
+ TQButtonItem *i = buttons->first();
+ while ( i && i->button != button )
+ i = buttons->next();
+ return i ? i->id : -1;
+}
+
+
+/*!
+ \reimp
+*/
+bool TQButtonGroup::event( TQEvent * e )
+{
+ if ( e->type() == TQEvent::ChildInserted ) {
+ TQChildEvent * ce = (TQChildEvent *) e;
+ if ( radio_excl && ::tqqt_cast<TQRadioButton*>(ce->child()) ) {
+ TQButton * button = (TQButton *) ce->child();
+ if ( button->isToggleButton() && !button->isOn() &&
+ selected() && (selected()->focusPolicy() & Qt::TabFocus) != 0 )
+ button->setFocusPolicy( (Qt::FocusPolicy)(button->focusPolicy() &
+ ~Qt::TabFocus) );
+ }
+ }
+ return TQGroupBox::event( e );
+}
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqbuttongroup.h b/tqtinterface/qt4/src/widgets/tqbuttongroup.h
new file mode 100644
index 0000000..edbc441
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqbuttongroup.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Definition of TQButtonGroup class
+**
+** Created : 950130
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQBUTTONGROUP_H
+#define TQBUTTONGROUP_H
+
+#ifndef TQT_H
+#include "tqgroupbox.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_BUTTONGROUP
+
+
+class TQButton;
+class TQButtonList;
+
+
+class TQ_EXPORT TQButtonGroup : public TQGroupBox
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool exclusive READ isExclusive WRITE setExclusive )
+ Q_PROPERTY( bool radioButtonExclusive READ isRadioButtonExclusive WRITE setRadioButtonExclusive )
+ Q_PROPERTY( int selectedId READ selectedId WRITE setButton )
+
+public:
+ TQButtonGroup( TQWidget* tqparent=0, const char* name=0 );
+ TQButtonGroup( const TQString &title,
+ TQWidget* tqparent=0, const char* name=0 );
+ TQButtonGroup( int columns, Qt::Orientation o,
+ TQWidget* tqparent=0, const char* name=0 );
+ TQButtonGroup( int columns, Qt::Orientation o, const TQString &title,
+ TQWidget* tqparent=0, const char* name=0 );
+ ~TQButtonGroup();
+
+ bool isExclusive() const;
+ bool isRadioButtonExclusive() const { return radio_excl; }
+ virtual void setExclusive( bool );
+ virtual void setRadioButtonExclusive( bool );
+
+public:
+ int insert( TQButton *, int id=-1 );
+ void remove( TQButton * );
+ TQButton *tqfind( int id ) const;
+ int id( TQButton * ) const;
+ int count() const;
+
+ virtual void setButton( int id );
+
+ virtual void moveFocus( int );
+
+ TQButton *selected() const;
+ int selectedId() const;
+
+Q_SIGNALS:
+ void pressed( int id );
+ void released( int id );
+ void clicked( int id );
+
+protected Q_SLOTS:
+ void buttonPressed();
+ void buttonReleased();
+ void buttonClicked();
+ void buttonToggled( bool on );
+
+protected:
+ bool event( TQEvent * e );
+
+private:
+ void init();
+ bool excl_grp;
+ bool radio_excl;
+ TQButtonList *buttons;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQButtonGroup( const TQButtonGroup & );
+ TQButtonGroup &operator=( const TQButtonGroup & );
+#endif
+};
+
+
+#endif // TQT_NO_BUTTONGROUP
+
+#endif // TQBUTTONGROUP_H
diff --git a/tqtinterface/qt4/src/widgets/tqcheckbox.cpp b/tqtinterface/qt4/src/widgets/tqcheckbox.cpp
new file mode 100644
index 0000000..37e8eac
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqcheckbox.cpp
@@ -0,0 +1,368 @@
+/****************************************************************************
+**
+** Implementation of TQCheckBox class
+**
+** Created : 940222
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcheckbox.h"
+#ifndef TQT_NO_CHECKBOX
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqpixmap.h"
+#include "tqpixmapcache.h"
+#include "tqbitmap.h"
+#include "tqtextstream.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+
+/*!
+ \class TQCheckBox tqcheckbox.h
+ \brief The TQCheckBox widget provides a checkbox with a text label.
+
+ \ingroup basic
+ \mainclass
+
+ TQCheckBox and TQRadioButton are both option buttons. That is, they
+ can be switched on (checked) or off (unchecked). The classes
+ differ in how the choices for the user are restricted. Radio
+ buttons define a "one of many" choice, whereas checkboxes provide
+ "many of many" choices.
+
+ A TQButtonGroup can be used to group check buttons visually.
+
+ Whenever a checkbox is checked or cleared it emits the signal
+ toggled(). Connect to this signal if you want to trigger an action
+ each time the checkbox changes state. You can use isChecked() to
+ query whether or not a checkbox is checked.
+
+ \warning The toggled() signal can not be trusted for tristate
+ checkboxes.
+
+ In addition to the usual checked and unchecked states, TQCheckBox
+ optionally provides a third state to indicate "no change". This
+ is useful whenever you need to give the user the option of neither
+ checking nor unchecking a checkbox. If you need this third state,
+ enable it with setTristate() and use state() to query the current
+ toggle state. When a tristate checkbox changes state, it emits the
+ stateChanged() signal.
+
+ Just like TQPushButton, a checkbox can display text or a pixmap.
+ The text can be set in the constructor or with setText(); the
+ pixmap is set with setPixmap().
+
+ \important text(), setText(), text(), pixmap(), setPixmap(),
+ accel(), setAccel(), isToggleButton(), setDown(), isDown(),
+ isOn(), state(), autoRepeat(), isExclusiveToggle(), group(),
+ setAutoRepeat(), toggle(), pressed(), released(), clicked(),
+ toggled(), state() stateChanged()
+
+ <img src=qchkbox-m.png> <img src=qchkbox-w.png>
+
+ \sa TQButton TQRadioButton
+ \link guibooks.html#fowler Fowler: Check Box \endlink
+*/
+
+/*!
+ \property TQCheckBox::checked
+ \brief whether the checkbox is checked
+
+ The default is unchecked, i.e. FALSE.
+*/
+
+/*!
+ \property TQCheckBox::autoMask
+ \brief whether the checkbox is automatically masked
+
+ \sa TQWidget::setAutoMask()
+*/
+
+/*!
+ \property TQCheckBox::tristate
+ \brief whether the checkbox is a tri-state checkbox
+
+ The default is two-state, i.e. tri-state is FALSE.
+*/
+
+/*!
+ Constructs a checkbox with no text.
+
+ The \a tqparent and \a name arguments are sent to the TQWidget
+ constructor.
+*/
+
+TQCheckBox::TQCheckBox( TQWidget *tqparent, const char *name )
+ : TQButton( tqparent, name, TQt::WNoAutoErase | TQt::WMouseNoMask )
+{
+ setToggleButton( TRUE );
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ) );
+}
+
+/*!
+ Constructs a checkbox with text \a text.
+
+ The \a tqparent and \a name arguments are sent to the TQWidget
+ constructor.
+*/
+
+TQCheckBox::TQCheckBox( const TQString &text, TQWidget *tqparent, const char *name )
+ : TQButton( tqparent, name, TQt::WNoAutoErase | TQt::WMouseNoMask )
+{
+ setText( text );
+ setToggleButton( TRUE );
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ) );
+}
+
+/*!
+ Sets the checkbox to the "no change" state.
+
+ \sa setTristate()
+*/
+void TQCheckBox::setNoChange()
+{
+ setTristate(TRUE);
+ setState( NoChange );
+}
+
+void TQCheckBox::setTristate(bool y)
+{
+ setToggleType( y ? Tristate : Toggle );
+}
+
+bool TQCheckBox::isTristate() const
+{
+ return toggleType() == Tristate;
+}
+
+
+/*!\reimp
+*/
+TQSize TQCheckBox::tqsizeHint() const
+{
+ // NB: TQRadioButton::tqsizeHint() is similar
+ constPolish();
+
+ TQPainter p(this);
+ TQSize sz = tqstyle().tqitemRect(&p, TQRect(0, 0, 1, 1), TQt::ShowPrefix, FALSE,
+ pixmap(), text()).size();
+
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_CheckBox, this, sz).
+ expandedTo(TQApplication::globalStrut()));
+}
+
+
+/*!\reimp
+*/
+
+void TQCheckBox::drawButton( TQPainter *paint )
+{
+ TQPainter *p = paint;
+ TQRect irect = TQStyle::tqvisualRect( tqstyle().subRect(TQStyle::SR_CheckBoxIndicator, this), this );
+ const TQColorGroup &cg = tqcolorGroup();
+
+#if !defined( TQT_NO_TEXTSTREAM ) && !defined( TQ_WS_MACX )
+#ifdef USE_QT4
+printf("[WARNING] TQSharedDoubleBuffer double buffering has been disabled\n\r"); // Otherwise the widgets don't repaint properly in Qt4!
+#else // USE_QT4
+# define SAVE_CHECKBOX_PIXMAPS
+#endif // USE_QT4
+#endif
+#if defined(SAVE_CHECKBOX_PIXMAPS)
+ TQString pmkey; // pixmap key
+ int kf = 0;
+ if ( isDown() )
+ kf |= 1;
+ if ( isEnabled() )
+ kf |= 2;
+ if ( hasFocus() )
+ kf |= 4; // active vs. normal colorgroup
+ if( isActiveWindow() )
+ kf |= 8;
+ if ( hasMouse() )
+ kf |= 16;
+
+ kf |= state() << 5;
+ TQTextOStream os(&pmkey);
+ os << "$qt_check_" << tqstyle().className() << "_"
+ << palette().serialNumber() << "_" << irect.width() << "x" << irect.height() << "_" << kf;
+ TQPixmap *pm = TQPixmapCache::tqfind( pmkey );
+ if ( pm ) { // pixmap exists
+ p->drawPixmap( irect.topLeft(), *pm );
+ drawButtonLabel( p );
+ return;
+ }
+ bool use_pm = TRUE;
+ TQPainter pmpaint;
+ int wx = 0, wy = 0;
+ if ( use_pm ) {
+ pm = new TQPixmap( irect.size() ); // create new pixmap
+ TQ_CHECK_PTR( pm );
+ pm->fill( cg.background() );
+ TQPainter::redirect(this, pm);
+ pmpaint.begin(this);
+ p = &pmpaint; // draw in pixmap
+ wx = irect.x(); // save x,y coords
+ wy = irect.y();
+ irect.moveTopLeft(TQPoint(0, 0));
+ p->setBackgroundColor( cg.background() );
+ }
+#endif
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if ( isEnabled() )
+ flags |= TQStyle::Style_Enabled;
+ if ( hasFocus() )
+ flags |= TQStyle::Style_HasFocus;
+ if ( isDown() )
+ flags |= TQStyle::Style_Down;
+ if ( hasMouse() )
+ flags |= TQStyle::Style_MouseOver;
+ if ( state() == TQButton::On )
+ flags |= TQStyle::Style_On;
+ else if ( state() == TQButton::Off )
+ flags |= TQStyle::Style_Off;
+ else if ( state() == TQButton::NoChange )
+ flags |= TQStyle::Style_NoChange;
+
+ tqstyle().tqdrawControl(TQStyle::CE_CheckBox, p, this, irect, cg, flags);
+
+#if defined(SAVE_CHECKBOX_PIXMAPS)
+ if ( use_pm ) {
+ pmpaint.end();
+ TQPainter::redirect( this, 0 );
+ if ( backgroundPixmap() || backgroundMode() == TQt::X11ParentRelative ) {
+ TQBitmap bm( pm->size() );
+ bm.fill( Qt::color0 );
+ pmpaint.begin( &bm );
+ tqstyle().tqdrawControlMask(TQStyle::CE_CheckBox, &pmpaint, this, irect);
+ pmpaint.end();
+ pm->setMask( bm );
+ }
+ p = paint; // draw in default tqdevice
+ p->drawPixmap( wx, wy, *pm );
+ if (!TQPixmapCache::insert(pmkey, pm) ) // save in cache
+ delete pm;
+ }
+#endif
+
+ drawButtonLabel( paint );
+}
+
+
+/*!\reimp
+*/
+void TQCheckBox::drawButtonLabel( TQPainter *p )
+{
+ TQRect r =
+ TQStyle::tqvisualRect( tqstyle().subRect(TQStyle::SR_CheckBoxContents, this), this );
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+ if (isDown())
+ flags |= TQStyle::Style_Down;
+ if (state() == TQButton::On)
+ flags |= TQStyle::Style_On;
+ else if (state() == TQButton::Off)
+ flags |= TQStyle::Style_Off;
+ else if (state() == TQButton::NoChange)
+ flags |= TQStyle::Style_NoChange;
+
+ tqstyle().tqdrawControl(TQStyle::CE_CheckBoxLabel, p, this, r, tqcolorGroup(), flags);
+}
+
+/*!
+ \reimp
+*/
+void TQCheckBox::resizeEvent( TQResizeEvent *e )
+{
+ TQButton::resizeEvent(e);
+ if ( isVisible() ) {
+ TQPainter p(this);
+ TQSize isz = tqstyle().tqitemRect(&p, TQRect(0, 0, 1, 1), TQt::ShowPrefix, FALSE,
+ pixmap(), text()).size();
+ TQSize wsz = (tqstyle().tqsizeFromContents(TQStyle::CT_CheckBox, this, isz).
+ expandedTo(TQApplication::globalStrut()));
+
+ update(wsz.width(), isz.width(), 0, wsz.height());
+ }
+ if (autoMask())
+ updateMask();
+}
+
+/*!
+ \reimp
+*/
+void TQCheckBox::updateMask()
+{
+ TQRect irect =
+ TQStyle::tqvisualRect( tqstyle().subRect(TQStyle::SR_CheckBoxIndicator, this), this );
+
+ TQBitmap bm(width(), height());
+ bm.fill(Qt::color0);
+
+ TQPainter p( &bm, this );
+ tqstyle().tqdrawControlMask(TQStyle::CE_CheckBox, &p, this, irect);
+ if ( ! text().isNull() || ( pixmap() && ! pixmap()->isNull() ) ) {
+ TQRect crect =
+ TQStyle::tqvisualRect( tqstyle().subRect( TQStyle::SR_CheckBoxContents,
+ this ), this );
+ TQRect frect =
+ TQStyle::tqvisualRect( tqstyle().subRect( TQStyle::SR_CheckBoxFocusRect,
+ this ), this );
+ TQRect label(crect.unite(frect));
+ p.fillRect(label, Qt::color1);
+ }
+ p.end();
+
+ setMask(bm);
+}
+
+/*!\reimp*/
+bool TQCheckBox::hitButton( const TQPoint &pos ) const
+{
+ TQRect r = TQStyle::tqvisualRect( tqstyle().subRect( TQStyle::SR_CheckBoxFocusRect, this ), this );
+ if ( tqApp->reverseLayout() ) {
+ r.setRight( width() );
+ } else {
+ r.setLeft( 0 );
+ }
+ return r.tqcontains( pos );
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqcheckbox.h b/tqtinterface/qt4/src/widgets/tqcheckbox.h
new file mode 100644
index 0000000..3f0e21b
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqcheckbox.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Definition of TQCheckBox class
+**
+** Created : 940222
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCHECKBOX_H
+#define TQCHECKBOX_H
+
+#ifndef TQT_H
+#include "tqbutton.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_CHECKBOX
+
+class TQ_EXPORT TQCheckBox : public TQButton
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool checked READ isChecked WRITE setChecked )
+ Q_PROPERTY( bool tristate READ isTristate WRITE setTristate )
+ TQ_OVERRIDE( bool autoMask DESIGNABLE true SCRIPTABLE true )
+
+public:
+ TQCheckBox( TQWidget *tqparent, const char* name=0 );
+ TQCheckBox( const TQString &text, TQWidget *tqparent, const char* name=0 );
+
+ bool isChecked() const;
+
+ void setNoChange();
+
+ void setTristate(bool y=TRUE);
+ bool isTristate() const;
+
+ TQSize tqsizeHint() const;
+
+public Q_SLOTS:
+ void setChecked( bool check );
+
+protected:
+ void resizeEvent( TQResizeEvent* );
+ void drawButton( TQPainter * );
+ void drawButtonLabel( TQPainter * );
+ void updateMask();
+ bool hitButton( const TQPoint &pos ) const;
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQCheckBox( const TQCheckBox & );
+ TQCheckBox &operator=( const TQCheckBox & );
+#endif
+};
+
+
+inline bool TQCheckBox::isChecked() const
+{ return isOn(); }
+
+inline void TQCheckBox::setChecked( bool check )
+{ setOn( check ); }
+
+
+#endif // TQT_NO_CHECKBOX
+
+#endif // TQCHECKBOX_H
diff --git a/tqtinterface/qt4/src/widgets/tqcombobox.cpp b/tqtinterface/qt4/src/widgets/tqcombobox.cpp
new file mode 100644
index 0000000..d152da2
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqcombobox.cpp
@@ -0,0 +1,2318 @@
+/**********************************************************************
+**
+** Implementation of TQComboBox widget class
+**
+** Created : 940426
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqcombobox.h"
+#ifndef TQT_NO_COMBOBOX
+#include "tqpopupmenu.h"
+#include "tqlistbox.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqstrlist.h"
+#include "tqpixmap.h"
+#include "tqtimer.h"
+#include "tqapplication.h"
+#include "tqlineedit.h"
+#include "tqbitmap.h"
+#include "tqeffects_p.h"
+#include "tqstringlist.h"
+#include "tqcombobox.h"
+#include "tqstyle.h"
+#include <limits.h>
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+/*!
+ \class TQComboBox tqcombobox.h
+ \brief The TQComboBox widget is a combined button and popup list.
+
+ \ingroup basic
+ \mainclass
+
+ A combobox is a selection widget which displays the current item
+ and can pop up a list of items. A combobox may be editable in
+ which case the user can enter arbitrary strings.
+
+ Comboboxes provide a means of showing the user's current choice
+ out of a list of options in a way that takes up the minimum amount
+ of screen space.
+
+ TQComboBox supports three different display styles: Aqua/Motif 1.x,
+ Motif 2.0 and Windows. In Motif 1.x, a combobox was called
+ XmOptionMenu. In Motif 2.0, OSF introduced an improved combobox
+ and named that XmComboBox. TQComboBox provides both.
+
+ TQComboBox provides two different constructors. The simplest
+ constructor creates an "old-style" combobox in Motif (or Aqua)
+ style:
+ \code
+ TQComboBox *c = new TQComboBox( this, "read-only combobox" );
+ \endcode
+
+ The other constructor creates a new-style combobox in Motif style,
+ and can create both read-only and editable comboboxes:
+ \code
+ TQComboBox *c1 = new TQComboBox( FALSE, this, "read-only combobox" );
+ TQComboBox *c2 = new TQComboBox( TRUE, this, "editable combobox" );
+ \endcode
+
+ New-style comboboxes use a list box in both Motif and Windows
+ styles, and both the content size and the on-screen size of the
+ list box can be limited with sizeLimit() and setMaxCount()
+ respectively. Old-style comboboxes use a popup in Aqua and Motif
+ style, and that popup will happily grow larger than the desktop if
+ you put enough data into it.
+
+ The two constructors create identical-looking comboboxes in
+ Windows style.
+
+ Comboboxes can contain pixmaps as well as strings; the
+ insertItem() and changeItem() functions are suitably overloaded.
+ For editable comboboxes, the function clearEdit() is provided,
+ to clear the displayed string without changing the combobox's
+ contents.
+
+ A combobox emits two Q_SIGNALS, activated() and highlighted(), when
+ a new item has been activated (selected) or highlighted (made
+ current). Both Q_SIGNALS exist in two versions, one with a \c
+ TQString argument and one with an \c int argument. If the user
+ highlights or activates a pixmap, only the \c int Q_SIGNALS are
+ emitted. Whenever the text of an editable combobox is changed the
+ textChanged() signal is emitted.
+
+ When the user enters a new string in an editable combobox, the
+ widget may or may not insert it, and it can insert it in several
+ locations. The default policy is is \c AtBottom but you can change
+ this using setInsertionPolicy().
+
+ It is possible to constrain the input to an editable combobox
+ using TQValidator; see setValidator(). By default, any input is
+ accepted.
+
+ If the combobox is not editable then it has a default
+ focusPolicy() of \c TabFocus, i.e. it will not grab focus if
+ clicked. This differs from both Windows and Motif. If the combobox
+ is editable then it has a default focusPolicy() of \c StrongFocus,
+ i.e. it will grab focus if clicked.
+
+ A combobox can be populated using the insert functions,
+ insertStringList() and insertItem() for example. Items can be
+ changed with changeItem(). An item can be removed with
+ removeItem() and all items can be removed with clear(). The text
+ of the current item is returned by currentText(), and the text of
+ a numbered item is returned with text(). The current item can be
+ set with setCurrentItem() or setCurrentText(). The number of items
+ in the combobox is returned by count(); the maximum number of
+ items can be set with setMaxCount(). You can allow editing using
+ setEditable(). For editable comboboxes you can set auto-completion
+ using setAutoCompletion() and whether or not the user can add
+ duplicates is set with setDuplicatesEnabled().
+
+ <img src="qcombo1-m.png">(Motif 1, read-only)<br clear=all>
+ <img src="qcombo2-m.png">(Motif 2, editable)<br clear=all>
+ <img src="qcombo3-m.png">(Motif 2, read-only)<br clear=all>
+ <img src="qcombo1-w.png">(Windows style)
+
+ Depending on the style, TQComboBox will use a TQListBox or a
+ TQPopupMenu to display the list of items. See setListBox() for
+ more information.
+
+ \sa TQLineEdit TQListBox TQSpinBox TQRadioButton TQButtonGroup
+ \link guibooks.html#fowler GUI Design Handbook: Combo Box,\endlink
+ \link guibooks.html#fowler GUI Design Handbook: Drop-Down List Box.\endlink
+*/
+
+
+/*!
+ \enum TQComboBox::Policy
+
+ This enum specifies what the TQComboBox should do when a new string
+ is entered by the user.
+
+ \value NoInsertion the string will not be inserted into the
+ combobox.
+
+ \value AtTop insert the string as the first item in the combobox.
+
+ \value AtCurrent tqreplace the previously selected item with the
+ string the user has entered.
+
+ \value AtBottom insert the string as the last item in the
+ combobox.
+
+ \value AfterCurrent insert the string after the previously
+ selected item.
+
+ \value BeforeCurrent insert the string before the previously
+ selected item.
+
+ activated() is always emitted when the string is entered.
+
+ If inserting the new string would cause the combobox to breach its
+ content size limit, the item at the other end of the list is
+ deleted. The definition of "other end" is
+ implementation-dependent.
+*/
+
+
+/*!
+ \fn void TQComboBox::activated( int index )
+
+ This signal is emitted when a new item has been activated
+ (selected). The \a index is the position of the item in the
+ combobox.
+
+ This signal is not emitted if the item is changed
+ programmatically, e.g. using setCurrentItem().
+*/
+
+/*!
+ \overload void TQComboBox::activated( const TQString &string )
+
+ This signal is emitted when a new item has been activated
+ (selected). \a string is the selected string.
+
+ You can also use the activated(int) signal, but be aware that its
+ argument is meaningful only for selected strings, not for user
+ entered strings.
+*/
+
+/*!
+ \fn void TQComboBox::highlighted( int index )
+
+ This signal is emitted when a new item has been set to be the
+ current item. The \a index is the position of the item in the
+ combobox.
+
+ This signal is not emitted if the item is changed
+ programmatically, e.g. using setCurrentItem().
+*/
+
+/*!
+ \overload void TQComboBox::highlighted( const TQString &string )
+
+ This signal is emitted when a new item has been set to be the
+ current item. \a string is the item's text.
+
+ You can also use the highlighted(int) signal.
+*/
+
+/*!
+ \fn void TQComboBox::textChanged( const TQString &string )
+
+ This signal is used for editable comboboxes. It is emitted
+ whenever the contents of the text entry field changes. \a string
+ tqcontains the new text.
+*/
+
+/*!
+ \property TQComboBox::autoCompletion
+ \brief whether auto-completion is enabled
+
+ This property can only be set for editable comboboxes, for
+ non-editable comboboxes it has no effect. It is FALSE by default.
+*/
+
+/*!
+ \property TQComboBox::autoMask
+ \brief whether the combobox is automatically masked
+
+ \sa TQWidget::setAutoMask()
+*/
+
+/*! \property TQComboBox::autoResize
+ \brief whether auto resize is enabled
+ \obsolete
+
+ If this property is set to TRUE then the combobox will resize itself
+ whenever its contents change. The default is FALSE.
+*/
+
+/*!
+ \property TQComboBox::count
+ \brief the number of items in the combobox
+*/
+
+/*!
+ \property TQComboBox::currentItem
+ \brief the index of the current item in the combobox
+
+ Note that the activated() and highlighted() Q_SIGNALS are only
+ emitted when the user changes the current item, not when it is
+ changed programmatically.
+*/
+
+/*!
+ \property TQComboBox::currentText
+ \brief the text of the combobox's current item
+*/
+
+/*!
+ \property TQComboBox::duplicatesEnabled
+ \brief whether duplicates are allowed
+
+ If the combobox is editable and the user enters some text in the
+ combobox's lineedit and presses Enter (and the insertionPolicy()
+ is not \c NoInsertion), then what happens is this:
+ \list
+ \i If the text is not already in the list, the text is inserted.
+ \i If the text is in the list and this property is TRUE (the
+ default), the text is inserted.
+ \i If the text is in the list and this property is FALSE, the text
+ is \e not inserted; instead the item which has matching text becomes
+ the current item.
+ \endlist
+
+ This property only affects user-interaction. You can use
+ insertItem() to insert duplicates if you wish regardless of this
+ setting.
+*/
+
+/*!
+ \property TQComboBox::editable
+ \brief whether the combobox is editable
+
+ This property's default is FALSE. Note that the combobox will be
+ cleared if this property is set to TRUE for a 1.x Motif style
+ combobox. To avoid this, use setEditable() before inserting any
+ items. Also note that the 1.x version of Motif didn't have any
+ editable comboboxes, so the combobox will change it's appearance
+ to a 2.0 style Motif combobox is it is set to be editable.
+*/
+
+/*!
+ \property TQComboBox::insertionPolicy
+ \brief the position of the items inserted by the user
+
+ The default insertion policy is \c AtBottom. See \l Policy.
+*/
+
+/*!
+ \property TQComboBox::maxCount
+ \brief the maximum number of items allowed in the combobox
+*/
+
+/*!
+ \property TQComboBox::sizeLimit
+ \brief the maximum on-screen size of the combobox.
+
+ This property is ignored for both Motif 1.x style and non-editable
+ comboboxes in Mac style. The default limit is ten
+ lines. If the number of items in the combobox is or grows larger
+ than lines, a scrollbar is added.
+*/
+
+class TQComboBoxPopup : public TQPopupMenu
+{
+public:
+ TQComboBoxPopup( TQWidget *tqparent=0, const char *name=0 )
+ : TQPopupMenu( tqparent, name )
+ {
+ }
+
+ int itemHeight( int index )
+ {
+ return TQPopupMenu::itemHeight( index );
+ }
+};
+
+static inline TQString escapedComboString(const TQString &str)
+{
+ TQString stringToReturn = str;
+ return stringToReturn.tqreplace('&', "&&");
+}
+
+class TQComboBoxPopupItem : public TQCustomMenuItem
+{
+ TQListBoxItem *li;
+ TQSize sc; // Size cache optimization
+public:
+ TQComboBoxPopupItem(TQListBoxItem *i) : TQCustomMenuItem(), li(i), sc(0, 0) { }
+ virtual bool fullSpan() const { return TRUE; }
+ virtual void paint( TQPainter*, const TQColorGroup&, bool, bool, int, int, int, int);
+ virtual TQSize tqsizeHint() { if (sc.isNull()) sc = TQSize(li->width(li->listBox()), TQMAX(25, li->height(li->listBox()))); return sc; }
+};
+void TQComboBoxPopupItem::paint( TQPainter* p, const TQColorGroup&, bool,
+ bool, int x, int y, int, int)
+{
+ p->save();
+ p->translate(x, y + ((tqsizeHint().height() / 2) - (li->height(li->listBox()) / 2)));
+ li->paint(p);
+ p->restore();
+}
+
+
+class TQComboBoxData
+{
+public:
+ TQComboBoxData( TQComboBox *cb ): ed( 0 ), usingLBox( FALSE ), pop( 0 ), lBox( 0 ), combo( cb )
+ {
+ duplicatesEnabled = TRUE;
+ cb->tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ) );
+ }
+
+ inline bool usingListBox() { return usingLBox; }
+ inline TQListBox * listBox() { return lBox; }
+ inline TQComboBoxPopup * popup() { return pop; }
+ void updateLinedGeometry();
+
+ void setListBox( TQListBox *l ) { lBox = l ; usingLBox = TRUE;
+ l->setMouseTracking( TRUE );}
+
+ void setPopupMenu( TQComboBoxPopup * pm, bool isPopup=TRUE )
+ { pop = pm; if(isPopup) usingLBox = FALSE; }
+
+ int current;
+ int maxCount;
+ int sizeLimit;
+ TQComboBox::Policy p;
+ bool autoresize;
+ bool poppedUp;
+ bool mouseWasInsidePopup;
+ bool arrowPressed;
+ bool arrowDown;
+ bool discardNextMousePress;
+ bool shortClick;
+ bool useCompletion;
+ bool completeNow;
+ int completeAt;
+ bool duplicatesEnabled;
+ int fullHeight, currHeight;
+
+ TQLineEdit * ed; // /bin/ed rules!
+ TQTimer *completionTimer;
+
+ TQSize tqsizeHint;
+
+private:
+ bool usingLBox;
+ TQComboBoxPopup *pop;
+ TQListBox *lBox;
+ TQComboBox *combo;
+
+};
+
+void TQComboBoxData::updateLinedGeometry()
+{
+ if ( !ed || !combo )
+ return;
+ TQRect r = TQStyle::tqvisualRect( combo->tqstyle().querySubControlMetrics(TQStyle::CC_ComboBox, combo,
+ TQStyle::SC_ComboBoxEditField), combo );
+
+ const TQPixmap *pix = current < combo->count() ? combo->pixmap( current ) : 0;
+ if ( pix && pix->width() < r.width() )
+ r.setLeft( r.left() + pix->width() + 4 );
+ if ( r != ed->tqgeometry() )
+ ed->setGeometry( r );
+}
+
+static inline bool checkInsertIndex( const char *method, const char * name,
+ int count, int *index)
+{
+ bool range_err = (*index > count);
+#if defined(TQT_CHECK_RANGE)
+ if ( range_err )
+ qWarning( "TQComboBox::%s: (%s) Index %d out of range",
+ method, name ? name : "<no name>", *index );
+#else
+ TQ_UNUSED( method )
+ TQ_UNUSED( name )
+#endif
+ if ( *index < 0 ) // append
+ *index = count;
+ return !range_err;
+}
+
+
+static inline bool checkIndex( const char *method, const char * name,
+ int count, int index )
+{
+ bool range_err = (index >= count);
+#if defined(TQT_CHECK_RANGE)
+ if ( range_err )
+ qWarning( "TQComboBox::%s: (%s) Index %i out of range",
+ method, name ? name : "<no name>", index );
+#else
+ TQ_UNUSED( method )
+ TQ_UNUSED( name )
+#endif
+ return !range_err;
+}
+
+
+
+/*!
+ Constructs a combobox widget with tqparent \a tqparent called \a name.
+
+ This constructor creates a popup list if the program uses Motif
+ (or Aqua) look and feel; this is compatible with Motif 1.x and
+ Aqua.
+
+ Note: If you use this constructor to create your TQComboBox, then
+ the pixmap() function will always return 0. To workaround this,
+ use the other constructor.
+
+*/
+
+
+
+TQComboBox::TQComboBox( TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name, TQt::WNoAutoErase )
+{
+ d = new TQComboBoxData( this );
+ if ( tqstyle().tqstyleHint(TQStyle::SH_ComboBox_Popup, this) ||
+ tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle ) {
+ d->setPopupMenu( new TQComboBoxPopup( this, "in-combo" ) );
+ d->popup()->setFont( font() );
+ connect( d->popup(), TQT_SIGNAL(activated(int)),
+ TQT_SLOT(internalActivate(int)) );
+ connect( d->popup(), TQT_SIGNAL(highlighted(int)),
+ TQT_SLOT(internalHighlight(int)) );
+ } else {
+ setUpListBox();
+ }
+ d->ed = 0;
+ d->current = 0;
+ d->maxCount = INT_MAX;
+ d->sizeLimit = 10;
+ d->p = AtBottom;
+ d->autoresize = FALSE;
+ d->poppedUp = FALSE;
+ d->arrowDown = FALSE;
+ d->arrowPressed = FALSE;
+ d->discardNextMousePress = FALSE;
+ d->shortClick = FALSE;
+ d->useCompletion = FALSE;
+ d->completeAt = 0;
+ d->completeNow = FALSE;
+ d->completionTimer = new TQTimer( this );
+
+ setFocusPolicy( Qt::TabFocus );
+ setBackgroundMode( TQt::PaletteButton );
+}
+
+
+/*!
+ Constructs a combobox with a maximum size and either Motif 2.0 or
+ Windows look and feel.
+
+ The input field can be edited if \a rw is TRUE, otherwise the user
+ may only choose one of the items in the combobox.
+
+ The \a tqparent and \a name arguments are passed on to the TQWidget
+ constructor.
+*/
+
+
+TQComboBox::TQComboBox( bool rw, TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name, TQt::WNoAutoErase )
+{
+ d = new TQComboBoxData( this );
+ setUpListBox();
+
+ if(d->popup() && tqstyle().tqstyleHint(TQStyle::SH_ComboBox_Popup, this))
+ d->popup()->setItemChecked(d->current, FALSE);
+ d->current = 0;
+ d->maxCount = INT_MAX;
+ setSizeLimit(10);
+ d->p = AtBottom;
+ d->autoresize = FALSE;
+ d->poppedUp = FALSE;
+ d->arrowDown = FALSE;
+ d->discardNextMousePress = FALSE;
+ d->shortClick = FALSE;
+ d->useCompletion = FALSE;
+ d->completeAt = 0;
+ d->completeNow = FALSE;
+ d->completionTimer = new TQTimer( this );
+
+ setFocusPolicy( Qt::StrongFocus );
+
+ d->ed = 0;
+ if ( rw )
+ setUpLineEdit();
+ setBackgroundMode( TQt::PaletteButton, TQt::PaletteBase );
+}
+
+
+
+/*!
+ Destroys the combobox.
+*/
+
+TQComboBox::~TQComboBox()
+{
+ delete d;
+}
+
+void TQComboBox::setDuplicatesEnabled( bool enable )
+{
+ d->duplicatesEnabled = enable;
+}
+
+bool TQComboBox::duplicatesEnabled() const
+{
+ return d->duplicatesEnabled;
+}
+
+int TQComboBox::count() const
+{
+ if ( d->usingListBox() )
+ return d->listBox()->count();
+ else
+ return d->popup()->count();
+}
+
+
+/*!
+ \overload
+
+ Inserts the \a list of strings at position \a index in the
+ combobox.
+
+ This is only for compatibility since it does not support Unicode
+ strings. See insertStringList().
+*/
+
+void TQComboBox::insertStrList( const TQStrList &list, int index )
+{
+ insertStrList( &list, index );
+}
+
+/*!
+ \overload
+
+ Inserts the \a list of strings at position \a index in the
+ combobox.
+
+ This is only for compatibility since it does not support Unicode
+ strings. See insertStringList().
+*/
+
+void TQComboBox::insertStrList( const TQStrList *list, int index )
+{
+ if ( !list ) {
+#if defined(TQT_CHECK_NULL)
+ TQ_ASSERT( list != 0 );
+#endif
+ return;
+ }
+ TQStrListIterator it( *list );
+ const char* tmp;
+ if ( index < 0 )
+ index = count();
+ while ( (tmp=it.current()) ) {
+ ++it;
+ if ( d->usingListBox() )
+ d->listBox()->insertItem( TQString::tqfromLatin1(tmp), index );
+ else
+ d->popup()->insertItem( escapedComboString(TQString::tqfromLatin1(tmp)), index, index );
+ if ( index++ == d->current && d->current < count() ) {
+ if ( d->ed ) {
+ d->ed->setText( text( d->current ) );
+ d->updateLinedGeometry();
+ } else
+ update();
+ currentChanged();
+ }
+ }
+ if ( index != count() )
+ reIndex();
+}
+
+/*!
+ Inserts the \a list of strings at position \a index in the
+ combobox.
+*/
+
+void TQComboBox::insertStringList( const TQStringList &list, int index )
+{
+ TQStringList::ConstIterator it = list.begin();
+ if ( index < 0 )
+ index = count();
+ while ( it != list.end() ) {
+ if ( d->usingListBox() )
+ d->listBox()->insertItem( *it, index );
+ else
+ d->popup()->insertItem( escapedComboString(*it), index, index );
+ if ( index++ == d->current && d->current < count() ) {
+ if ( d->ed ) {
+ d->ed->setText( text( d->current ) );
+ d->updateLinedGeometry();
+ } else
+ update();
+ currentChanged();
+ }
+ ++it;
+ }
+ if ( index != count() )
+ reIndex();
+}
+
+/*!
+ Inserts the array of char * \a strings at position \a index in the
+ combobox.
+
+ The \a numStrings argument is the number of strings. If \a
+ numStrings is -1 (default), the \a strings array must be
+ terminated with 0.
+
+ Example:
+ \code
+ static const char* items[] = { "red", "green", "blue", 0 };
+ combo->insertStrList( items );
+ \endcode
+
+ \sa insertStringList()
+*/
+
+void TQComboBox::insertStrList( const char **strings, int numStrings, int index)
+{
+ if ( !strings ) {
+#if defined(TQT_CHECK_NULL)
+ TQ_ASSERT( strings != 0 );
+#endif
+ return;
+ }
+ if ( index < 0 )
+ index = count();
+ int i = 0;
+ while ( (numStrings<0 && strings[i]!=0) || i<numStrings ) {
+ if ( d->usingListBox() )
+ d->listBox()->insertItem( TQString::tqfromLatin1(strings[i]), index );
+ else
+ d->popup()->insertItem( escapedComboString(TQString::tqfromLatin1(strings[i])), index, index );
+ i++;
+ if ( index++ == d->current && d->current < count() ) {
+ if ( d->ed ) {
+ d->ed->setText( text( d->current ) );
+ d->updateLinedGeometry();
+ } else
+ update();
+ currentChanged();
+ }
+ }
+ if ( index != count() )
+ reIndex();
+}
+
+
+/*!
+ Inserts a text item with text \a t, at position \a index. The item
+ will be appended if \a index is negative.
+*/
+
+void TQComboBox::insertItem( const TQString &t, int index )
+{
+ int cnt = count();
+ if ( !checkInsertIndex( "insertItem", name(), cnt, &index ) )
+ return;
+ if ( d->usingListBox() )
+ d->listBox()->insertItem( t, index );
+ else
+ d->popup()->insertItem( escapedComboString(t), index, index );
+ if ( index != cnt )
+ reIndex();
+ if ( index == d->current && d->current < count() ) {
+ if ( d->ed ) {
+ d->ed->setText( text( d->current ) );
+ d->updateLinedGeometry();
+ } else
+ update();
+ }
+ if ( index == d->current )
+ currentChanged();
+}
+
+/*!
+ \overload
+
+ Inserts a \a pixmap item at position \a index. The item will be
+ appended if \a index is negative.
+*/
+
+void TQComboBox::insertItem( const TQPixmap &pixmap, int index )
+{
+ int cnt = count();
+ if ( !checkInsertIndex( "insertItem", name(), cnt, &index ) )
+ return;
+ if ( d->usingListBox() )
+ d->listBox()->insertItem( pixmap, index );
+ else
+ d->popup()->insertItem( pixmap, index, index );
+ if ( index != cnt )
+ reIndex();
+ if ( index == d->current && d->current < count() ) {
+ if ( d->ed ) {
+ d->ed->setText( text( d->current ) );
+ d->updateLinedGeometry();
+ } else
+ update();
+ }
+ if ( index == d->current )
+ currentChanged();
+}
+
+/*!
+ \overload
+
+ Inserts a \a pixmap item with additional text \a text at position
+ \a index. The item will be appended if \a index is negative.
+*/
+
+void TQComboBox::insertItem( const TQPixmap &pixmap, const TQString& text, int index )
+{
+ int cnt = count();
+ if ( !checkInsertIndex( "insertItem", name(), cnt, &index ) )
+ return;
+ if ( d->usingListBox() )
+ d->listBox()->insertItem( pixmap, text, index );
+ else
+ d->popup()->insertItem( pixmap, escapedComboString(text), index, index );
+ if ( index != cnt )
+ reIndex();
+ if ( index == d->current && d->current < count() ) {
+ if ( d->ed ) {
+ d->ed->setText( this->text( d->current ) );
+ d->updateLinedGeometry();
+ } else
+ update();
+ }
+ if ( index == d->current )
+ currentChanged();
+}
+
+
+/*!
+ Removes the item at position \a index.
+*/
+
+void TQComboBox::removeItem( int index )
+{
+ int cnt = count();
+ if ( !checkIndex( "removeItem", name(), cnt, index ) )
+ return;
+ if ( d->usingListBox() ) {
+ if ( tqstyle().tqstyleHint(TQStyle::SH_ComboBox_Popup, this) && d->popup() )
+ d->popup()->removeItemAt( index );
+ d->listBox()->removeItem( index );
+ } else {
+ d->popup()->removeItemAt( index );
+ }
+ if ( index != cnt-1 )
+ reIndex();
+ if ( index == d->current ) {
+ if ( d->ed ) {
+ TQString s = TQString::tqfromLatin1("");
+ if (d->current < cnt - 1)
+ s = text( d->current );
+ d->ed->setText( s );
+ d->updateLinedGeometry();
+ }
+ else {
+ if ( d->usingListBox() ) {
+ d->current = d->listBox()->currentItem();
+ } else {
+ if (d->current > count()-1 && d->current > 0)
+ d->current--;
+ }
+ update();
+ }
+ currentChanged();
+ }
+ else {
+ if ( !d->ed ) {
+ if (d->current < cnt - 1)
+ setCurrentItem( d->current );
+ else
+ setCurrentItem( d->current - 1 );
+ }
+ }
+
+}
+
+
+/*!
+ Removes all combobox items.
+*/
+
+void TQComboBox::clear()
+{
+ if ( d->usingListBox() ) {
+ if ( tqstyle().tqstyleHint(TQStyle::SH_ComboBox_Popup, this) && d->popup() )
+ d->popup()->clear();
+ d->listBox()->resize( 0, 0 );
+ d->listBox()->clear();
+ } else {
+ d->popup()->clear();
+ }
+
+ if(d->popup() && tqstyle().tqstyleHint(TQStyle::SH_ComboBox_Popup, this))
+ d->popup()->setItemChecked(d->current, FALSE);
+ d->current = 0;
+ if ( d->ed ) {
+ d->ed->setText( TQString::tqfromLatin1("") );
+ d->updateLinedGeometry();
+ }
+ currentChanged();
+}
+
+
+TQString TQComboBox::currentText() const
+{
+ if ( d->ed )
+ return d->ed->text();
+ else if ( d->current < count() )
+ return text( currentItem() );
+ else
+ return TQString::null;
+}
+
+void TQComboBox::setCurrentText( const TQString& txt )
+{
+ int i;
+ for ( i = 0; i < count(); i++)
+ if ( text( i ) == txt )
+ break;
+ if ( i < count() )
+ setCurrentItem( i );
+ else if ( d->ed )
+ d->ed->setText( txt );
+ else
+ changeItem( txt, currentItem() );
+}
+
+
+/*!
+ Returns the text item at position \a index, or TQString::null if
+ the item is not a string.
+
+ \sa currentText()
+*/
+
+TQString TQComboBox::text( int index ) const
+{
+ if ( !checkIndex( "text", name(), count(), index ) )
+ return TQString::null;
+ if ( d->usingListBox() ) {
+ return d->listBox()->text( index );
+ } else {
+ TQString retText = d->popup()->text(index);
+ retText.tqreplace("&&", "&");
+ return retText;
+ }
+}
+
+/*!
+ Returns the pixmap item at position \a index, or 0 if the item is
+ not a pixmap.
+*/
+
+const TQPixmap *TQComboBox::pixmap( int index ) const
+{
+ if ( !checkIndex( "pixmap", name(), count(), index ) )
+ return 0;
+ if ( d->usingListBox() )
+ return d->listBox()->pixmap( index );
+ else
+ return d->popup()->pixmap( index );
+}
+
+/*!
+ Replaces the item at position \a index with the text \a t.
+*/
+
+void TQComboBox::changeItem( const TQString &t, int index )
+{
+ if ( !checkIndex( "changeItem", name(), count(), index ) )
+ return;
+ if ( d->usingListBox() )
+ d->listBox()->changeItem( t, index );
+ else
+ d->popup()->changeItem( t, index );
+ if ( index == d->current ) {
+ if ( d->ed ) {
+ d->ed->setText( text( d->current ) );
+ d->updateLinedGeometry();
+ } else
+ update();
+ }
+}
+
+/*!
+ \overload
+
+ Replaces the item at position \a index with the pixmap \a im,
+ unless the combobox is editable.
+
+ \sa insertItem()
+*/
+
+void TQComboBox::changeItem( const TQPixmap &im, int index )
+{
+ if ( !checkIndex( "changeItem", name(), count(), index ) )
+ return;
+ if ( d->usingListBox() )
+ d->listBox()->changeItem( im, index );
+ else
+ d->popup()->changeItem( im, index );
+ if ( index == d->current )
+ update();
+}
+
+/*!
+ \overload
+
+ Replaces the item at position \a index with the pixmap \a im and
+ the text \a t.
+
+ \sa insertItem()
+*/
+
+void TQComboBox::changeItem( const TQPixmap &im, const TQString &t, int index )
+{
+ if ( !checkIndex( "changeItem", name(), count(), index ) )
+ return;
+ if ( d->usingListBox() )
+ d->listBox()->changeItem( im, t, index );
+ else
+ d->popup()->changeItem( im, t, index );
+ if ( index == d->current )
+ update();
+}
+
+
+int TQComboBox::currentItem() const
+{
+ return d->current;
+}
+
+void TQComboBox::setCurrentItem( int index )
+{
+ if ( index == d->current && !d->ed ) {
+ return;
+ }
+ if ( !checkIndex( "setCurrentItem", name(), count(), index ) ) {
+ return;
+ }
+
+ if ( d->usingListBox() && !( listBox()->item(index) && listBox()->item(index)->isSelectable() ) )
+ return;
+
+ if(d->popup() && tqstyle().tqstyleHint(TQStyle::SH_ComboBox_Popup, this))
+ d->popup()->setItemChecked(d->current, FALSE);
+ d->current = index;
+ d->completeAt = 0;
+ if ( d->ed ) {
+ d->ed->setText( text( index ) );
+ d->updateLinedGeometry();
+ }
+ // ### We want to keep ListBox's currentItem in sync, even if NOT popuped...
+ if ( d->usingListBox() && d->listBox() ) {
+ d->listBox()->setCurrentItem( index );
+ } else {
+ internalHighlight( index );
+ // internalActivate( index ); ### this leads to weird behavior, as in 3.0.1
+ }
+
+ currentChanged();
+}
+
+bool TQComboBox::autoResize() const
+{
+ return d->autoresize;
+}
+
+void TQComboBox::setAutoResize( bool enable )
+{
+ if ( (bool)d->autoresize != enable ) {
+ d->autoresize = enable;
+ if ( enable )
+ adjustSize();
+ }
+}
+
+
+/*!
+ \reimp
+
+ This implementation caches the size hint to avoid resizing when
+ the contents change dynamically. To tqinvalidate the cached value
+ call setFont().
+*/
+TQSize TQComboBox::tqsizeHint() const
+{
+ if ( isVisible() && d->tqsizeHint.isValid() )
+ return d->tqsizeHint;
+
+ constPolish();
+ int i, w;
+ TQFontMetrics fm = fontMetrics();
+
+ int maxW = count() ? 18 : 7 * fm.width(TQChar('x')) + 18;
+ int maxH = TQMAX( fm.lineSpacing(), 14 ) + 2;
+
+ if ( !d->usingListBox() ) {
+ w = d->popup()->tqsizeHint().width() - 2* d->popup()->frameWidth();
+ if ( w > maxW )
+ maxW = w;
+ } else {
+ for( i = 0; i < count(); i++ ) {
+ w = d->listBox()->item( i )->width( d->listBox() );
+ if ( w > maxW )
+ maxW = w;
+ }
+ }
+
+ d->tqsizeHint = (tqstyle().tqsizeFromContents(TQStyle::CT_ComboBox, this,
+ TQSize(maxW, maxH)).
+ expandedTo(TQApplication::globalStrut()));
+
+ return d->tqsizeHint;
+}
+
+
+/*!
+ \internal
+ Receives activated Q_SIGNALS from an internal popup list and emits
+ the activated() signal.
+*/
+
+void TQComboBox::internalActivate( int index )
+{
+ if ( d->current != index ) {
+ if ( !d->usingListBox() || listBox()->item( index )->isSelectable() ) {
+ if(d->popup() && tqstyle().tqstyleHint(TQStyle::SH_ComboBox_Popup, this))
+ d->popup()->setItemChecked(d->current, FALSE);
+ d->current = index;
+ currentChanged();
+ }
+ }
+ if ( d->usingListBox() )
+ popDownListBox();
+ else
+ d->popup()->removeEventFilter( this );
+ d->poppedUp = FALSE;
+
+ TQString t( text( index ) );
+ if ( d->ed ) {
+ d->ed->setText( t );
+ d->updateLinedGeometry();
+ }
+ emit activated( index );
+ emit activated( t );
+}
+
+/*!
+ \internal
+ Receives highlighted Q_SIGNALS from an internal popup list and emits
+ the highlighted() signal.
+*/
+
+void TQComboBox::internalHighlight( int index )
+{
+ emit highlighted( index );
+ TQString t = text( index );
+ if ( !t.isNull() )
+ emit highlighted( t );
+}
+
+/*!
+ \internal
+ Receives timeouts after a click. Used to decide if a Motif style
+ popup should stay up or not after a click.
+*/
+void TQComboBox::internalClickTimeout()
+{
+ d->shortClick = FALSE;
+}
+
+/*!
+ Sets the palette for both the combobox button and the combobox
+ popup list to \a palette.
+*/
+
+void TQComboBox::setPalette( const TQPalette &palette )
+{
+ TQWidget::setPalette( palette );
+ if ( d->listBox() )
+ d->listBox()->setPalette( palette );
+ if ( d->popup() )
+ d->popup()->setPalette( palette );
+}
+
+/*!
+ Sets the font for both the combobox button and the combobox popup
+ list to \a font.
+*/
+
+void TQComboBox::setFont( const TQFont &font )
+{
+ d->tqsizeHint = TQSize(); // tqinvalidate size hint
+ TQWidget::setFont( font );
+ if ( d->usingListBox() )
+ d->listBox()->setFont( font );
+ else
+ d->popup()->setFont( font );
+ if (d->ed)
+ d->ed->setFont( font );
+ if ( d->autoresize )
+ adjustSize();
+}
+
+
+/*!\reimp
+*/
+
+void TQComboBox::resizeEvent( TQResizeEvent * e )
+{
+ if ( d->ed )
+ d->updateLinedGeometry();
+ if ( d->listBox() )
+ d->listBox()->resize( width(), d->listBox()->height() );
+ TQWidget::resizeEvent( e );
+}
+
+/*!\reimp
+*/
+
+void TQComboBox::paintEvent( TQPaintEvent * )
+{
+ TQPainter p( this );
+ const TQColorGroup & g = tqcolorGroup();
+ p.setPen(g.text());
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+
+ if ( width() < 5 || height() < 5 ) {
+ qDrawShadePanel( &p, rect(), g, FALSE, 2,
+ &g.brush( TQColorGroup::Button ) );
+ return;
+ }
+
+ bool reverse = TQApplication::reverseLayout();
+ if ( !d->usingListBox() &&
+ tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle) { // motif 1.x style
+ int dist, buttonH, buttonW;
+ dist = 8;
+ buttonH = 7;
+ buttonW = 11;
+ int xPos;
+ int x0;
+ int w = width() - dist - buttonW - 1;
+ if ( reverse ) {
+ xPos = dist + 1;
+ x0 = xPos + 4;
+ } else {
+ xPos = w;
+ x0 = 4;
+ }
+ qDrawShadePanel( &p, rect(), g, FALSE,
+ tqstyle().tqpixelMetric(TQStyle::PM_DefaultFrameWidth, this),
+ &g.brush( TQColorGroup::Button ) );
+ qDrawShadePanel( &p, xPos, (height() - buttonH)/2,
+ buttonW, buttonH, g, FALSE,
+ tqstyle().tqpixelMetric(TQStyle::PM_DefaultFrameWidth, this) );
+ TQRect clip( x0, 2, w - 2 - 4 - 5, height() - 4 );
+ TQString str = d->popup()->text( this->d->current );
+ if ( !str.isNull() ) {
+ p.drawText( clip, TQt::AlignCenter | TQt::SingleLine, str );
+ }
+
+ TQPixmap *pix = d->popup()->pixmap( this->d->current );
+ TQIconSet *iconSet = d->popup()->iconSet( this->d->current );
+ if (pix || iconSet) {
+ TQPixmap pm = ( pix ? *pix : iconSet->pixmap() );
+ p.setClipRect( clip );
+ p.drawPixmap( 4, (height()-pm.height())/2, pm );
+ p.setClipping( FALSE );
+ }
+
+ if ( hasFocus() )
+ p.drawRect( xPos - 5, 4, width() - xPos + 1 , height() - 8 );
+ } else if(!d->usingListBox()) {
+ tqstyle().tqdrawComplexControl( TQStyle::CC_ComboBox, &p, this, rect(), g,
+ flags, (uint)TQStyle::SC_All,
+ (d->arrowDown ?
+ TQStyle::SC_ComboBoxArrow :
+ TQStyle::SC_None ));
+
+ TQRect re = tqstyle().querySubControlMetrics( TQStyle::CC_ComboBox, this,
+ TQStyle::SC_ComboBoxEditField );
+ re = TQStyle::tqvisualRect(re, this);
+ p.setClipRect( re );
+
+ TQString str = d->popup()->text( this->d->current );
+ TQPixmap *pix = d->popup()->pixmap( this->d->current );
+ if ( !str.isNull() ) {
+ p.save();
+ p.setFont(font());
+ TQFontMetrics fm(font());
+ int x = re.x(), y = re.y() + fm.ascent();
+ if( pix )
+ x += pix->width() + 5;
+ p.drawText( x, y, str );
+ p.restore();
+ }
+ if ( pix ) {
+ p.fillRect( re.x(), re.y(), pix->width() + 4, re.height(),
+ tqcolorGroup().brush( TQColorGroup::Base ) );
+ p.drawPixmap( re.x() + 2, re.y() +
+ ( re.height() - pix->height() ) / 2, *pix );
+ }
+ } else {
+ tqstyle().tqdrawComplexControl( TQStyle::CC_ComboBox, &p, this, rect(), g,
+ flags, (uint)TQStyle::SC_All,
+ (d->arrowDown ?
+ TQStyle::SC_ComboBoxArrow :
+ TQStyle::SC_None ));
+
+ TQRect re = tqstyle().querySubControlMetrics( TQStyle::CC_ComboBox, this,
+ TQStyle::SC_ComboBoxEditField );
+ re = TQStyle::tqvisualRect(re, this);
+ p.setClipRect( re );
+
+ if ( !d->ed ) {
+ TQListBoxItem * item = d->listBox()->item( d->current );
+ if ( item ) {
+ int itemh = item->height( d->listBox() );
+ p.translate( re.x(), re.y() + (re.height() - itemh)/2 );
+ item->paint( &p );
+ }
+ } else if ( d->listBox() && d->listBox()->item( d->current ) ) {
+ TQListBoxItem * item = d->listBox()->item( d->current );
+ const TQPixmap *pix = item->pixmap();
+ if ( pix ) {
+ p.fillRect( re.x(), re.y(), pix->width() + 4, re.height(),
+ tqcolorGroup().brush( TQColorGroup::Base ) );
+ p.drawPixmap( re.x() + 2, re.y() +
+ ( re.height() - pix->height() ) / 2, *pix );
+ }
+ }
+ p.setClipping( FALSE );
+ }
+}
+
+
+/*!\reimp
+*/
+
+void TQComboBox::mousePressEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+ if ( d->discardNextMousePress ) {
+ d->discardNextMousePress = FALSE;
+ return;
+ }
+ TQRect arrowRect = tqstyle().querySubControlMetrics( TQStyle::CC_ComboBox, this,
+ TQStyle::SC_ComboBoxArrow);
+ arrowRect = TQStyle::tqvisualRect(arrowRect, this);
+
+ // Correction for motif style, where arrow is smaller
+ // and thus has a rect that doesn't fit the button.
+ arrowRect.setHeight( TQMAX( height() - (2 * arrowRect.y()), arrowRect.height() ) );
+
+ if ( count() && ( !editable() || arrowRect.tqcontains( e->pos() ) ) ) {
+ d->arrowPressed = FALSE;
+
+ if ( d->usingListBox() ) {
+ listBox()->blockSignals( TRUE );
+ tqApp->sendEvent( listBox(), e ); // trigger the listbox's autoscroll
+ listBox()->setCurrentItem(d->current);
+ listBox()->blockSignals( FALSE );
+ popup();
+ if ( arrowRect.tqcontains( e->pos() ) ) {
+ d->arrowPressed = TRUE;
+ d->arrowDown = TRUE;
+ tqrepaint( FALSE );
+ }
+ } else {
+ popup();
+ }
+ TQTimer::singleShot( 200, this, TQT_SLOT(internalClickTimeout()));
+ d->shortClick = TRUE;
+ }
+}
+
+/*!\reimp
+*/
+
+void TQComboBox::mouseMoveEvent( TQMouseEvent * )
+{
+}
+
+/*!\reimp
+*/
+
+void TQComboBox::mouseReleaseEvent( TQMouseEvent * )
+{
+}
+
+/*!\reimp
+*/
+
+void TQComboBox::mouseDoubleClickEvent( TQMouseEvent *e )
+{
+ mousePressEvent( e );
+}
+
+
+/*!\reimp
+*/
+
+void TQComboBox::keyPressEvent( TQKeyEvent *e )
+{
+ int c = currentItem();
+ if ( ( e->key() == Qt::Key_F4 && e->state() == 0 ) ||
+ ( e->key() == Qt::Key_Down && (e->state() & TQt::AltButton) ) ||
+ ( !d->ed && e->key() == Qt::Key_Space ) ) {
+ if ( count() ) {
+ if ( !d->usingListBox() )
+ d->popup()->setActiveItem( this->d->current );
+ popup();
+ }
+ return;
+ } else if ( d->usingListBox() && e->key() == Qt::Key_Up ) {
+ if ( c > 0 )
+ setCurrentItem( c-1 );
+ } else if ( d->usingListBox() && e->key() == Qt::Key_Down ) {
+ if ( ++c < count() )
+ setCurrentItem( c );
+ } else if ( d->usingListBox() && e->key() == Qt::Key_Home && ( !d->ed || !d->ed->hasFocus() ) ) {
+ setCurrentItem( 0 );
+ } else if ( d->usingListBox() && e->key() == Qt::Key_End && ( !d->ed || !d->ed->hasFocus() ) ) {
+ setCurrentItem( count()-1 );
+ } else if ( !d->ed && e->ascii() >= 32 && !e->text().isEmpty() ) {
+ if ( !d->completionTimer->isActive() ) {
+ d->completeAt = 0;
+ c = completionIndex( e->text(), ++c );
+ if ( c >= 0 ) {
+ setCurrentItem( c );
+ d->completeAt = e->text().length();
+ }
+ } else {
+ d->completionTimer->stop();
+ TQString ct = currentText().left( d->completeAt ) + e->text();
+ c = completionIndex( ct, c );
+ if ( c < 0 && d->completeAt > 0 ) {
+ c = completionIndex( e->text(), 0 );
+ ct = e->text();
+ }
+ d->completeAt = 0;
+ if ( c >= 0 ) {
+ setCurrentItem( c );
+ d->completeAt = ct.length();
+ }
+ }
+ d->completionTimer->start( 400, TRUE );
+ } else {
+ e->ignore();
+ return;
+ }
+
+ c = currentItem();
+ if ( count() && !text( c ).isNull() )
+ emit activated( text( c ) );
+ emit activated( c );
+}
+
+
+/*!\reimp
+*/
+
+void TQComboBox::focusInEvent( TQFocusEvent * e )
+{
+ TQWidget::focusInEvent( e );
+ d->completeNow = FALSE;
+ d->completeAt = 0;
+}
+
+/*!\reimp
+*/
+
+void TQComboBox::focusOutEvent( TQFocusEvent * e )
+{
+ TQWidget::focusOutEvent( e );
+ d->completeNow = FALSE;
+ d->completeAt = 0;
+}
+
+/*!\reimp
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQComboBox::wheelEvent( TQWheelEvent *e )
+{
+ if ( d->poppedUp ) {
+ if ( d->usingListBox() ) {
+ TQApplication::sendEvent( d->listBox(), e );
+ }
+ } else {
+ if ( e->delta() > 0 ) {
+ int c = currentItem();
+ if ( c > 0 ) {
+ setCurrentItem( c-1 );
+ emit activated( currentItem() );
+ emit activated( currentText() );
+ }
+ } else {
+ int c = currentItem();
+ if ( ++c < count() ) {
+ setCurrentItem( c );
+ emit activated( currentItem() );
+ emit activated( currentText() );
+ }
+ }
+ e->accept();
+ }
+}
+#endif
+
+/*!
+ \internal
+ Calculates the listbox height needed to contain all items, or as
+ many as the list box is supposed to contain.
+*/
+static int listHeight( TQListBox *l, int sl )
+{
+ if ( l->count() > 0 )
+ return TQMIN( l->count(), (uint)sl) * l->item( 0 )->height(l);
+ else
+ return l->tqsizeHint().height();
+}
+
+
+/*!
+ Pops up the combobox popup list.
+
+ If the list is empty, no items appear.
+*/
+
+void TQComboBox::popup()
+{
+ if ( !count() || d->poppedUp )
+ return;
+
+ if( !d->usingListBox() || tqstyle().tqstyleHint(TQStyle::SH_ComboBox_Popup, this) ) {
+ if(d->usingListBox()) {
+ if(!d->popup()) {
+ TQComboBoxPopup *p = new TQComboBoxPopup( this, "in-combo" );
+ d->setPopupMenu( p, FALSE );
+ p->setFont( font() );
+ connect( p, TQT_SIGNAL(activated(int)), TQT_SLOT(internalActivate(int)) );
+ connect( p, TQT_SIGNAL(highlighted(int)), TQT_SLOT(internalHighlight(int)) );
+ }
+ d->popup()->clear();
+ for(unsigned int i = 0; i < d->listBox()->count(); i++) {
+ TQListBoxItem *item = d->listBox()->item(i);
+ if(item->rtti() == TQListBoxText::RTTI) {
+ d->popup()->insertItem(escapedComboString(item->text()), i, i);
+ } else if(item->rtti() == TQListBoxPixmap::RTTI) {
+ if(item->pixmap())
+ d->popup()->insertItem(TQIconSet(*item->pixmap()), escapedComboString(item->text()), i, i);
+ else
+ d->popup()->insertItem(escapedComboString(item->text()), i, i);
+ } else {
+ d->popup()->insertItem(new TQComboBoxPopupItem(item), i, i);
+ }
+ }
+ }
+ d->popup()->installEventFilter( this );
+ if(d->popup() && tqstyle().tqstyleHint(TQStyle::SH_ComboBox_Popup, this))
+ d->popup()->setItemChecked(this->d->current, TRUE);
+ d->popup()->popup( mapToGlobal( TQPoint(0,0) ), this->d->current );
+ update();
+ } else {
+ // Send all listbox events to eventFilter():
+ TQListBox* lb = d->listBox();
+ lb->triggerUpdate( TRUE );
+ lb->installEventFilter( this );
+ d->mouseWasInsidePopup = FALSE;
+ int w = lb->variableWidth() ? lb->tqsizeHint().width() : width();
+ int h = listHeight( lb, d->sizeLimit ) + 2;
+ TQRect screen = TQApplication::desktop()->availableGeometry( this );
+
+ int sx = screen.x(); // screen pos
+ int sy = screen.y();
+ int sw = screen.width(); // screen width
+ int sh = screen.height(); // screen height
+ TQPoint pos = mapToGlobal( TQPoint(0,height()) );
+ // ## Similar code is in TQPopupMenu
+ int x = pos.x();
+ int y = pos.y();
+
+ // the complete widget must be visible
+ if ( x + w > sx + sw )
+ x = sx+sw - w;
+ if ( x < sx )
+ x = sx;
+ if (y + h > sy+sh && y - h - height() >= 0 )
+ y = y - h - height();
+
+ TQRect rect =
+ tqstyle().querySubControlMetrics( TQStyle::CC_ComboBox, this,
+ TQStyle::SC_ComboBoxListBoxPopup,
+ TQStyleOption( x, y, w, h ) );
+ // work around older styles that don't implement the combobox
+ // listbox popup subcontrol
+ if ( rect.isNull() )
+ rect.setRect( x, y, w, h );
+ lb->setGeometry( rect );
+
+ lb->raise();
+ bool block = TQT_TQOBJECT(lb)->tqsignalsBlocked();
+ lb->blockSignals( TRUE );
+ TQListBoxItem* currentLBItem = 0;
+ if ( editable() && currentText() != text( currentItem() ) )
+ currentLBItem = lb->tqfindItem( currentText() );
+
+ currentLBItem = currentLBItem ? currentLBItem : lb->item( d->current );
+
+ lb->setCurrentItem( currentLBItem );
+ lb->setContentsPos( lb->contentsX(),
+ lb->viewportToContents( lb->tqitemRect( currentLBItem ).topLeft() ).y() );
+
+ // set the current item to also be the selected item if it isn't already
+ if ( currentLBItem && currentLBItem->isSelectable() && !currentLBItem->isSelected() )
+ lb->setSelected( currentLBItem, TRUE );
+ lb->blockSignals( block );
+ lb->setVScrollBarMode(TQScrollView::Auto);
+
+#ifndef TQT_NO_EFFECTS
+ if ( TQApplication::isEffectEnabled( Qt::UI_AnimateCombo ) ) {
+ if ( lb->y() < mapToGlobal(TQPoint(0,0)).y() )
+ qScrollEffect( lb, TQEffects::UpScroll );
+ else
+ qScrollEffect( lb );
+ } else
+#endif
+ lb->show();
+ }
+ d->poppedUp = TRUE;
+}
+
+
+/*!
+ \reimp
+*/
+void TQComboBox::updateMask()
+{
+ TQBitmap bm( size() );
+ bm.fill( Qt::color0 );
+
+ {
+ TQPainter p( &bm, this );
+ tqstyle().tqdrawComplexControlMask(TQStyle::CC_ComboBox, &p, this, rect());
+ }
+
+ setMask( bm );
+}
+
+/*!
+ \internal
+ Pops down (removes) the combobox popup list box.
+*/
+void TQComboBox::popDownListBox()
+{
+ TQ_ASSERT( d->usingListBox() );
+ d->listBox()->removeEventFilter( this );
+ d->listBox()->viewport()->removeEventFilter( this );
+ d->listBox()->hide();
+ d->listBox()->setCurrentItem( d->current );
+ if ( d->arrowDown ) {
+ d->arrowDown = FALSE;
+ tqrepaint( FALSE );
+ }
+ d->poppedUp = FALSE;
+}
+
+
+/*!
+ \internal
+ Re-indexes the identifiers in the popup list.
+*/
+
+void TQComboBox::reIndex()
+{
+ if ( !d->usingListBox() ) {
+ int cnt = count();
+ while ( cnt-- )
+ d->popup()->setId( cnt, cnt );
+ }
+}
+
+/*!
+ \internal
+ Repaints the combobox.
+*/
+
+void TQComboBox::currentChanged()
+{
+ if ( d->autoresize )
+ adjustSize();
+ update();
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+}
+
+/*! \reimp
+
+ \internal
+
+ The event filter steals events from the popup or listbox when they
+ are popped up. It makes the popup stay up after a short click in
+ motif style. In windows style it toggles the arrow button of the
+ combobox field, and activates an item and takes down the listbox
+ when the mouse button is released.
+*/
+
+bool TQComboBox::eventFilter( TQObject *object, TQEvent *event )
+{
+ if ( !event )
+ return TRUE;
+ else if ( TQT_BASE_OBJECT(object) == TQT_BASE_OBJECT(d->ed) ) {
+ if ( event->type() == TQEvent::KeyPress ) {
+ bool isAccepted = ( (TQKeyEvent*)event )->isAccepted();
+ keyPressEvent( (TQKeyEvent *)event );
+ if ( ((TQKeyEvent *)event)->isAccepted() ) {
+ d->completeNow = FALSE;
+ return TRUE;
+ } else if ( ((TQKeyEvent *)event)->key() != Qt::Key_End ) {
+ d->completeNow = TRUE;
+ d->completeAt = d->ed->cursorPosition();
+ }
+ if ( isAccepted )
+ ( (TQKeyEvent*)event )->accept();
+ else
+ ( (TQKeyEvent*)event )->ignore();
+ } else if ( event->type() == TQEvent::KeyRelease ) {
+ keyReleaseEvent( (TQKeyEvent *)event );
+ return ((TQKeyEvent *)event)->isAccepted();
+ } else if ( event->type() == TQEvent::FocusIn ) {
+ focusInEvent( (TQFocusEvent *)event );
+ } else if ( event->type() == TQEvent::FocusOut ) {
+ focusOutEvent( (TQFocusEvent *)event );
+ } else if ( d->useCompletion && d->completeNow ) {
+ d->completeNow = FALSE;
+ if ( !d->ed->text().isNull() &&
+ d->ed->cursorPosition() > d->completeAt &&
+ d->ed->cursorPosition() == (int)d->ed->text().length() ) {
+ TQString ct( d->ed->text() );
+ int i = completionIndex( ct, currentItem() );
+ if ( i > -1 ) {
+ TQString it = text( i );
+ d->ed->validateAndSet( it, ct.length(),
+ ct.length(), it.length() );
+ d->current = i;
+ // ### sets current item without emitting Q_SIGNALS. This is to
+ // make sure the right item is current if you change current with
+ // wheel/up/down. While typing current is not valid anyway. Fix properly
+ // in 4.0.
+ }
+ }
+ }
+ } else if ( d->usingListBox() && ( TQT_BASE_OBJECT(object) == TQT_BASE_OBJECT(d->listBox()) ||
+ TQT_BASE_OBJECT(object) == TQT_BASE_OBJECT(d->listBox()->viewport()) )) {
+ TQMouseEvent *e = (TQMouseEvent*)event;
+ switch( event->type() ) {
+ case TQEvent::MouseMove:
+ if ( !d->mouseWasInsidePopup ) {
+ TQPoint pos = e->pos();
+ if ( TQT_TQRECT_OBJECT(d->listBox()->rect()).tqcontains( pos ) )
+ d->mouseWasInsidePopup = TRUE;
+ // Check if arrow button should toggle
+ if ( d->arrowPressed ) {
+ TQPoint comboPos;
+ comboPos = mapFromGlobal( d->listBox()->mapToGlobal(pos) );
+ TQRect arrowRect =
+ tqstyle().querySubControlMetrics( TQStyle::CC_ComboBox, this,
+ TQStyle::SC_ComboBoxArrow);
+ arrowRect = TQStyle::tqvisualRect(arrowRect, this);
+ if ( arrowRect.tqcontains( comboPos ) ) {
+ if ( !d->arrowDown ) {
+ d->arrowDown = TRUE;
+ tqrepaint( FALSE );
+ }
+ } else {
+ if ( d->arrowDown ) {
+ d->arrowDown = FALSE;
+ tqrepaint( FALSE );
+ }
+ }
+ }
+ } else if ((e->state() & ( Qt::RightButton | Qt::LeftButton | Qt::MidButton ) ) == 0 &&
+ tqstyle().tqstyleHint(TQStyle::SH_ComboBox_ListMouseTracking, this)) {
+ TQWidget *mouseW = TQApplication::widgetAt( e->globalPos(), TRUE );
+ if ( mouseW == d->listBox()->viewport() ) { //###
+ TQMouseEvent m( TQEvent::MouseMove, e->pos(), e->globalPos(),
+ Qt::LeftButton, Qt::LeftButton );
+#ifdef USE_QT4
+ #warning Not sending event to prevent infinite recursion. Will this cause any problems?
+#else // USE_QT4
+ TQApplication::sendEvent( object, &m ); //### Evil
+#endif // USE_QT4
+ return TRUE;
+ }
+ }
+
+ break;
+ case TQEvent::MouseButtonRelease:
+ if ( TQT_TQRECT_OBJECT(d->listBox()->rect()).tqcontains( e->pos() ) ) {
+ TQMouseEvent tmp( TQEvent::MouseButtonDblClick,
+ e->pos(), e->button(), e->state() ) ;
+ // will hide popup
+ TQApplication::sendEvent( object, &tmp );
+ return TRUE;
+ } else {
+ if ( d->mouseWasInsidePopup ) {
+ popDownListBox();
+ } else {
+ d->arrowPressed = FALSE;
+ if ( d->arrowDown ) {
+ d->arrowDown = FALSE;
+ tqrepaint( FALSE );
+ }
+ }
+ }
+ break;
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::MouseButtonPress:
+ if ( !TQT_TQRECT_OBJECT(d->listBox()->rect()).tqcontains( e->pos() ) ) {
+ TQPoint globalPos = d->listBox()->mapToGlobal(e->pos());
+ if ( TQApplication::widgetAt( globalPos, TRUE ) == this ) {
+ d->discardNextMousePress = TRUE;
+ // avoid popping up again
+ }
+ popDownListBox();
+ return TRUE;
+ }
+ break;
+ case TQEvent::KeyPress:
+ switch( ((TQKeyEvent *)event)->key() ) {
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ if ( !(((TQKeyEvent *)event)->state() & TQt::AltButton) )
+ break;
+ case Qt::Key_F4:
+ case Key_Escape:
+ if ( d->poppedUp ) {
+ popDownListBox();
+ return TRUE;
+ }
+ break;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ // work around TQDialog's enter handling
+ return FALSE;
+ default:
+ break;
+ }
+ break;
+ case TQEvent::Hide:
+ popDownListBox();
+ break;
+ default:
+ break;
+ }
+ } else if ( (!d->usingListBox() || tqstyle().tqstyleHint(TQStyle::SH_ComboBox_Popup, this)) &&
+ TQT_BASE_OBJECT(object) == TQT_BASE_OBJECT(d->popup()) ) {
+ TQMouseEvent *e = (TQMouseEvent*)event;
+ switch ( event->type() ) {
+ case TQEvent::MouseButtonRelease:
+ if ( d->shortClick ) {
+ TQMouseEvent tmp( TQEvent::MouseMove,
+ e->pos(), e->button(), e->state() ) ;
+ // highlight item, but don't pop down:
+ TQApplication::sendEvent( object, &tmp );
+ return TRUE;
+ }
+ break;
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::MouseButtonPress:
+ if ( !TQT_TQRECT_OBJECT(d->popup()->rect()).tqcontains( e->pos() ) ) {
+ d->poppedUp = FALSE;
+ d->arrowDown = FALSE;
+ // remove filter, event will take down popup:
+ d->popup()->removeEventFilter( this );
+ // ### uglehack!
+ // call internalHighlight so the highlighed signal
+ // will be emitted at least as often as necessary.
+ // it may be called more often than necessary
+ internalHighlight( d->current );
+ }
+ break;
+ case TQEvent::Hide:
+ d->poppedUp = FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+ return TQWidget::eventFilter( object, event );
+}
+
+
+/*!
+ Returns the index of the first item \e after \a startingAt of
+ which \a prefix is a case-insensitive prefix. Returns -1 if no
+ items start with \a prefix.
+*/
+
+int TQComboBox::completionIndex( const TQString & prefix,
+ int startingAt = 0 ) const
+{
+ int start = startingAt;
+ if ( start < 0 || start >= count() )
+ start = 0;
+ if ( start >= count() )
+ return -1;
+ TQString match = prefix.lower();
+ if ( match.length() < 1 )
+ return start;
+
+ TQString current;
+ int i = start;
+ do {
+ current = text( i ).lower();
+ if ( current.startsWith( match ) )
+ return i;
+ i++;
+ if ( i == count() )
+ i = 0;
+ } while ( i != start );
+ return -1;
+}
+
+
+int TQComboBox::sizeLimit() const
+{
+ return d ? d->sizeLimit : INT_MAX;
+}
+
+void TQComboBox::setSizeLimit( int lines )
+{
+ d->sizeLimit = lines;
+}
+
+
+int TQComboBox::maxCount() const
+{
+ return d ? d->maxCount : INT_MAX;
+}
+
+void TQComboBox::setMaxCount( int count )
+{
+ int l = this->count();
+ while( --l > count )
+ removeItem( l );
+ d->maxCount = count;
+}
+
+TQComboBox::Policy TQComboBox::insertionPolicy() const
+{
+ return d->p;
+}
+
+void TQComboBox::setInsertionPolicy( Policy policy )
+{
+ d->p = policy;
+}
+
+
+
+/*!
+ Internal slot to keep the line editor up to date.
+*/
+
+void TQComboBox::returnPressed()
+{
+ TQString s( d->ed->text() );
+
+ if ( s.isEmpty() )
+ return;
+
+ int c = 0;
+ bool doInsert = TRUE;
+ if ( !d->duplicatesEnabled ) {
+ for ( int i = 0; i < count(); ++i ) {
+ if ( s == text( i ) ) {
+ doInsert = FALSE;
+ c = i;
+ break;
+ }
+ }
+ }
+
+ if ( doInsert ) {
+ if ( insertionPolicy() != NoInsertion ) {
+ int cnt = count();
+ while ( cnt >= d->maxCount ) {
+ removeItem( --cnt );
+ }
+ }
+
+ switch ( insertionPolicy() ) {
+ case AtCurrent:
+ if (count() == 0)
+ insertItem(s);
+ else if ( s != text( currentItem() ) )
+ changeItem( s, currentItem() );
+ emit activated( currentItem() );
+ emit activated( s );
+ return;
+ case NoInsertion:
+ emit activated( s );
+ return;
+ case AtTop:
+ c = 0;
+ break;
+ case AtBottom:
+ c = count();
+ break;
+ case BeforeCurrent:
+ c = currentItem();
+ break;
+ case AfterCurrent:
+ c = count() == 0 ? 0 : currentItem() + 1;
+ break;
+ }
+ insertItem( s, c );
+ }
+
+ setCurrentItem( c );
+ emit activated( c );
+ emit activated( s );
+}
+
+
+/*! \reimp
+*/
+
+void TQComboBox::setEnabled( bool enable )
+{
+ if ( !enable ) {
+ if ( d->usingListBox() ) {
+ popDownListBox();
+ } else {
+ d->popup()->removeEventFilter( this );
+ d->popup()->close();
+ d->poppedUp = FALSE;
+ }
+ }
+ TQWidget::setEnabled( enable );
+}
+
+
+
+/*!
+ Applies the validator \a v to the combobox so that only text which
+ is valid according to \a v is accepted.
+
+ This function does nothing if the combobox is not editable.
+
+ \sa validator() clearValidator() TQValidator
+*/
+
+void TQComboBox::setValidator( const TQValidator * v )
+{
+ if ( d && d->ed )
+ d->ed->setValidator( v );
+}
+
+
+/*!
+ Returns the validator which constrains editing for this combobox
+ if there is one; otherwise returns 0.
+
+ \sa setValidator() clearValidator() TQValidator
+*/
+
+const TQValidator * TQComboBox::validator() const
+{
+ return d && d->ed ? d->ed->validator() : 0;
+}
+
+
+/*!
+ This slot is equivalent to setValidator( 0 ).
+*/
+
+void TQComboBox::clearValidator()
+{
+ if ( d && d->ed )
+ d->ed->setValidator( 0 );
+}
+
+
+/*!
+ Sets the combobox to use \a newListBox instead of the current list
+ box or popup. As a side effect, it clears the combobox of its
+ current contents.
+
+ \warning TQComboBox assumes that newListBox->text(n) returns
+ non-null for 0 \<= n \< newListbox->count(). This assumption is
+ necessary because of the line edit in TQComboBox.
+*/
+
+void TQComboBox::setListBox( TQListBox * newListBox )
+{
+ clear();
+
+ if ( d->usingListBox() ) {
+ delete d->listBox();
+ } else {
+ delete d->popup();
+ d->setPopupMenu(0, FALSE);
+ }
+
+ newListBox->reparent( this, (Qt::WindowFlags)WType_Popup, TQPoint(0,0), FALSE );
+ d->setListBox( newListBox );
+ d->listBox()->setFont( font() );
+ d->listBox()->setPalette( palette() );
+ d->listBox()->setVScrollBarMode(TQScrollView::AlwaysOff);
+ d->listBox()->setHScrollBarMode(TQScrollView::AlwaysOff);
+ d->listBox()->setFrameStyle( TQFrame::Box | TQFrame::Plain );
+ d->listBox()->setLineWidth( 1 );
+ d->listBox()->resize( 100, 10 );
+
+ connect( d->listBox(), TQT_SIGNAL(selected(int)),
+ TQT_SLOT(internalActivate(int)) );
+ connect( d->listBox(), TQT_SIGNAL(highlighted(int)),
+ TQT_SLOT(internalHighlight(int)));
+}
+
+
+/*!
+ Returns the current list box, or 0 if there is no list box.
+ (TQComboBox can use TQPopupMenu instead of TQListBox.) Provided to
+ match setListBox().
+
+ \sa setListBox()
+*/
+
+TQListBox * TQComboBox::listBox() const
+{
+ return d && d->usingListBox() ? d->listBox() : 0;
+}
+
+/*!
+ Returns the line edit, or 0 if there is no line edit.
+
+ Only editable listboxes have a line editor.
+*/
+TQLineEdit* TQComboBox::lineEdit() const
+{
+ return d->ed;
+}
+
+
+
+/*!
+ Clears the line edit without changing the combobox's contents.
+ Does nothing if the combobox isn't editable.
+
+ This is particularly useful when using a combobox as a line edit
+ with history. For example you can connect the combobox's
+ activated() signal to clearEdit() in order to present the user
+ with a new, empty line as soon as Enter is pressed.
+
+ \sa setEditText()
+*/
+
+void TQComboBox::clearEdit()
+{
+ if ( d && d->ed )
+ d->ed->clear();
+}
+
+
+/*!
+ Sets the text in the line edit to \a newText without changing the
+ combobox's contents. Does nothing if the combobox isn't editable.
+
+ This is useful e.g. for providing a good starting point for the
+ user's editing and entering the change in the combobox only when
+ the user presses Enter.
+
+ \sa clearEdit() insertItem()
+*/
+
+void TQComboBox::setEditText( const TQString &newText )
+{
+ if ( d && d->ed ) {
+ d->updateLinedGeometry();
+ d->ed->setText( newText );
+ }
+}
+
+void TQComboBox::setAutoCompletion( bool enable )
+{
+ d->useCompletion = enable;
+ d->completeNow = FALSE;
+}
+
+
+bool TQComboBox::autoCompletion() const
+{
+ return d->useCompletion;
+}
+
+/*!\reimp
+ */
+void TQComboBox::styleChange( TQStyle& s )
+{
+ d->tqsizeHint = TQSize(); // tqinvalidate size hint...
+ if ( d->ed )
+ d->updateLinedGeometry();
+ TQWidget::styleChange( s );
+}
+
+bool TQComboBox::editable() const
+{
+ return d->ed != 0;
+}
+
+void TQComboBox::setEditable( bool y )
+{
+ if ( y == editable() )
+ return;
+ if ( y ) {
+ if ( !d->usingListBox() )
+ setUpListBox();
+ setUpLineEdit();
+ d->ed->show();
+ if ( currentItem() )
+ setEditText( currentText() );
+ } else {
+ delete d->ed;
+ d->ed = 0;
+ }
+
+ setFocusPolicy( Qt::StrongFocus );
+ updateGeometry();
+ update();
+}
+
+
+void TQComboBox::setUpListBox()
+{
+ d->setListBox( new TQListBox( this, "in-combo", (Qt::WindowFlags)WType_Popup ) );
+ d->listBox()->setFont( font() );
+ d->listBox()->setPalette( palette() );
+ d->listBox()->setVScrollBarMode( TQListBox::AlwaysOff );
+ d->listBox()->setHScrollBarMode( TQListBox::AlwaysOff );
+ d->listBox()->setFrameStyle( TQFrame::Box | TQFrame::Plain );
+ d->listBox()->setLineWidth( 1 );
+ d->listBox()->resize( 100, 10 );
+
+ connect( d->listBox(), TQT_SIGNAL(selected(int)),
+ TQT_SLOT(internalActivate(int)) );
+ connect( d->listBox(), TQT_SIGNAL(highlighted(int)),
+ TQT_SLOT(internalHighlight(int)));
+}
+
+
+void TQComboBox::setUpLineEdit()
+{
+ if ( !d->ed )
+ setLineEdit( new TQLineEdit( this, "combo edit" ) );
+}
+
+/*!
+ Sets the line edit to use \a edit instead of the current line edit.
+*/
+
+void TQComboBox::setLineEdit( TQLineEdit *edit )
+{
+ if ( !edit ) {
+#if defined(TQT_CHECK_NULL)
+ TQ_ASSERT( edit != 0 );
+#endif
+ return;
+ }
+
+ edit->setText( currentText() );
+ delete d->ed;
+ d->ed = edit;
+
+ if ( edit->tqparent() != TQT_TQOBJECT(this) )
+ edit->reparent( this, TQPoint(0,0), FALSE );
+
+ connect (edit, TQT_SIGNAL( textChanged(const TQString&) ),
+ this, TQT_SIGNAL( textChanged(const TQString&) ) );
+ connect( edit, TQT_SIGNAL(returnPressed()), TQT_SLOT(returnPressed()) );
+
+ edit->setFrame( FALSE );
+ d->updateLinedGeometry();
+ edit->installEventFilter( this );
+ setFocusProxy( edit );
+ setFocusPolicy( Qt::StrongFocus );
+ setInputMethodEnabled( TRUE );
+
+ if ( !d->usingListBox() )
+ setUpListBox();
+
+ if ( isVisible() )
+ edit->show();
+
+ updateGeometry();
+ update();
+}
+
+/*!
+ \reimp
+*/
+void TQComboBox::hide()
+{
+ TQWidget::hide();
+
+ if (listBox())
+ listBox()->hide();
+ else if (d->popup())
+ d->popup()->hide();
+}
+
+#endif // TQT_NO_COMBOBOX
diff --git a/tqtinterface/qt4/src/widgets/tqcombobox.h b/tqtinterface/qt4/src/widgets/tqcombobox.h
new file mode 100644
index 0000000..bfee192
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqcombobox.h
@@ -0,0 +1,207 @@
+/**********************************************************************
+**
+** Definition of TQComboBox class
+**
+** Created : 950426
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQCOMBOBOX_H
+#define TQCOMBOBOX_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_COMBOBOX
+
+
+class TQStrList;
+class TQStringList;
+class TQLineEdit;
+class TQValidator;
+class TQListBox;
+class TQComboBoxData;
+class TQWheelEvent;
+
+class TQ_EXPORT TQComboBox : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( Policy )
+ Q_PROPERTY( bool editable READ editable WRITE setEditable )
+ Q_PROPERTY( int count READ count )
+ Q_PROPERTY( TQString currentText READ currentText WRITE setCurrentText DESIGNABLE false )
+ Q_PROPERTY( int currentItem READ currentItem WRITE setCurrentItem )
+ Q_PROPERTY( bool autoResize READ autoResize WRITE setAutoResize DESIGNABLE false )
+ Q_PROPERTY( int sizeLimit READ sizeLimit WRITE setSizeLimit )
+ Q_PROPERTY( int maxCount READ maxCount WRITE setMaxCount )
+ Q_PROPERTY( Policy insertionPolicy READ insertionPolicy WRITE setInsertionPolicy )
+ Q_PROPERTY( bool autoCompletion READ autoCompletion WRITE setAutoCompletion )
+ Q_PROPERTY( bool duplicatesEnabled READ duplicatesEnabled WRITE setDuplicatesEnabled )
+ TQ_OVERRIDE( bool autoMask DESIGNABLE true SCRIPTABLE true )
+
+public:
+ TQComboBox( TQWidget* tqparent=0, const char* name=0 );
+ TQComboBox( bool rw, TQWidget* tqparent=0, const char* name=0 );
+ ~TQComboBox();
+
+ int count() const;
+
+ void insertStringList( const TQStringList &, int index=-1 );
+ void insertStrList( const TQStrList &, int index=-1 );
+ void insertStrList( const TQStrList *, int index=-1 );
+ void insertStrList( const char **, int numStrings=-1, int index=-1);
+
+ void insertItem( const TQString &text, int index=-1 );
+ void insertItem( const TQPixmap &pixmap, int index=-1 );
+ void insertItem( const TQPixmap &pixmap, const TQString &text, int index=-1 );
+
+ void removeItem( int index );
+
+ int currentItem() const;
+ virtual void setCurrentItem( int index );
+
+ TQString currentText() const;
+ virtual void setCurrentText( const TQString& );
+
+ TQString text( int index ) const;
+ const TQPixmap *pixmap( int index ) const;
+
+ void changeItem( const TQString &text, int index );
+ void changeItem( const TQPixmap &pixmap, int index );
+ void changeItem( const TQPixmap &pixmap, const TQString &text, int index );
+
+ bool autoResize() const;
+ virtual void setAutoResize( bool );
+ TQSize tqsizeHint() const;
+
+ void setPalette( const TQPalette & );
+ void setFont( const TQFont & );
+ void setEnabled( bool );
+
+ virtual void setSizeLimit( int );
+ int sizeLimit() const;
+
+ virtual void setMaxCount( int );
+ int maxCount() const;
+
+ enum Policy { NoInsertion, AtTop, AtCurrent, AtBottom,
+ AfterCurrent, BeforeCurrent };
+
+ virtual void setInsertionPolicy( Policy policy );
+ Policy insertionPolicy() const;
+
+ virtual void setValidator( const TQValidator * );
+ const TQValidator * validator() const;
+
+ virtual void setListBox( TQListBox * );
+ TQListBox * listBox() const;
+
+ virtual void setLineEdit( TQLineEdit *edit );
+ TQLineEdit* lineEdit() const;
+
+ virtual void setAutoCompletion( bool );
+ bool autoCompletion() const;
+
+ bool eventFilter( TQObject *object, TQEvent *event );
+
+ void setDuplicatesEnabled( bool enable );
+ bool duplicatesEnabled() const;
+
+ bool editable() const;
+ void setEditable( bool );
+
+ virtual void popup();
+
+ void hide();
+
+public Q_SLOTS:
+ void clear();
+ void clearValidator();
+ void clearEdit();
+ virtual void setEditText( const TQString &);
+
+Q_SIGNALS:
+ void activated( int index );
+ void highlighted( int index );
+ void activated( const TQString &);
+ void highlighted( const TQString &);
+ void textChanged( const TQString &);
+
+private Q_SLOTS:
+ void internalActivate( int );
+ void internalHighlight( int );
+ void internalClickTimeout();
+ void returnPressed();
+
+protected:
+ void paintEvent( TQPaintEvent * );
+ void resizeEvent( TQResizeEvent * );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseDoubleClickEvent( TQMouseEvent * );
+ void keyPressEvent( TQKeyEvent *e );
+ void focusInEvent( TQFocusEvent *e );
+ void focusOutEvent( TQFocusEvent *e );
+#ifndef TQT_NO_WHEELEVENT
+ void wheelEvent( TQWheelEvent *e );
+#endif
+ void styleChange( TQStyle& );
+
+ void updateMask();
+
+private:
+ void setUpListBox();
+ void setUpLineEdit();
+ void popDownListBox();
+ void reIndex();
+ void currentChanged();
+ int completionIndex( const TQString &, int ) const;
+
+ TQComboBoxData *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQComboBox( const TQComboBox & );
+ TQComboBox &operator=( const TQComboBox & );
+#endif
+};
+
+
+#endif // TQT_NO_COMBOBOX
+
+#endif // TQCOMBOBOX_H
diff --git a/tqtinterface/qt4/src/widgets/tqdatetimeedit.cpp b/tqtinterface/qt4/src/widgets/tqdatetimeedit.cpp
new file mode 100644
index 0000000..4aaea53
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqdatetimeedit.cpp
@@ -0,0 +1,2845 @@
+/****************************************************************************
+**
+** Implementation of date and time edit classes
+**
+** Created : 001103
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdatetimeedit.h"
+
+#ifndef TQT_NO_DATETIMEEDIT
+
+#include "../kernel/tqinternal_p.h"
+#include "../kernel/tqrichtext_p.h"
+#include "tqrangecontrol.h"
+#include "tqapplication.h"
+#include "tqpixmap.h"
+#include "tqapplication.h"
+#include "tqvaluelist.h"
+#include "tqstring.h"
+#include "tqstyle.h"
+
+#if defined(TQ_WS_WIN)
+#include "tqt_windows.h"
+#endif
+
+#define TQDATETIMEEDIT_HIDDEN_CHAR '0'
+
+class TQ_EXPORT TQNumberSection
+{
+public:
+ TQNumberSection( int selStart = 0, int selEnd = 0, bool separat = TRUE, int actual = -1 )
+ : selstart( selStart ), selend( selEnd ), act( actual ), sep( separat )
+ {}
+ int selectionStart() const { return selstart; }
+ void setSelectionStart( int s ) { selstart = s; }
+ int selectionEnd() const { return selend; }
+ void setSelectionEnd( int s ) { selend = s; }
+ int width() const { return selend - selstart; }
+ int index() const { return act; }
+ bool separator() const { return sep; }
+ TQ_DUMMY_COMPARISON_OPERATOR( TQNumberSection )
+private:
+ int selstart :12;
+ int selend :12;
+ int act :7;
+ bool sep :1;
+};
+
+static TQString *lDateSep = 0;
+static TQString *lTimeSep = 0;
+static bool lAMPM = FALSE;
+static TQString *lAM = 0;
+static TQString *lPM = 0;
+static TQDateEdit::Order lOrder = TQDateEdit::YMD;
+static int refcount = 0;
+
+static void cleanup()
+{
+ delete lDateSep;
+ lDateSep = 0;
+ delete lTimeSep;
+ lTimeSep = 0;
+ delete lAM;
+ lAM = 0;
+ delete lPM;
+ lPM = 0;
+}
+
+/*!
+\internal
+try to get the order of DMY and the date/time separator from the locale settings
+*/
+static void readLocaleSettings()
+{
+ int dpos, mpos, ypos;
+ cleanup();
+
+ lDateSep = new TQString();
+ lTimeSep = new TQString();
+
+#if defined(TQ_WS_WIN)
+ TQT_WA( {
+ TCHAR data[10];
+ GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_SDATE, data, 10 );
+ *lDateSep = TQString::fromUcs2( (ushort*)data );
+ GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_STIME, data, 10 );
+ *lTimeSep = TQString::fromUcs2( (ushort*)data );
+ GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_ITIME, data, 10 );
+ lAMPM = TQString::fromUcs2( (ushort*)data ).toInt()==0;
+ GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_S1159, data, 10 );
+ TQString am = TQString::fromUcs2( (ushort*)data );
+ if ( !am.isEmpty() )
+ lAM = new TQString( am );
+ GetLocaleInfo( LOCALE_USER_DEFAULT, LOCALE_S2359, data, 10 );
+ TQString pm = TQString::fromUcs2( (ushort*)data );
+ if ( !pm.isEmpty() )
+ lPM = new TQString( pm );
+ } , {
+ char data[10];
+ GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_SDATE, (char*)&data, 10 );
+ *lDateSep = TQString::fromLocal8Bit( data );
+ GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_STIME, (char*)&data, 10 );
+ *lTimeSep = TQString::fromLocal8Bit( data );
+ GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_ITIME, (char*)&data, 10 );
+ lAMPM = TQString::fromLocal8Bit( data ).toInt()==0;
+ GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_S1159, (char*)&data, 10 );
+ TQString am = TQString::fromLocal8Bit( data );
+ if ( !am.isEmpty() )
+ lAM = new TQString( am );
+ GetLocaleInfoA( LOCALE_USER_DEFAULT, LOCALE_S2359, (char*)&data, 10 );
+ TQString pm = TQString::fromLocal8Bit( data );
+ if ( !pm.isEmpty() )
+ lPM = new TQString( pm );
+ } );
+#else
+ *lDateSep = "-";
+ *lTimeSep = ":";
+#endif
+ TQString d = TQDate( 1999, 11, 22 ).toString( Qt::LocalDate );
+ dpos = d.tqfind( "22" );
+ mpos = d.tqfind( "11" );
+ ypos = d.tqfind( "99" );
+ if ( dpos > -1 && mpos > -1 && ypos > -1 ) {
+ // test for DMY, MDY, YMD, YDM
+ if ( dpos < mpos && mpos < ypos ) {
+ lOrder = TQDateEdit::DMY;
+ } else if ( mpos < dpos && dpos < ypos ) {
+ lOrder = TQDateEdit::MDY;
+ } else if ( ypos < mpos && mpos < dpos ) {
+ lOrder = TQDateEdit::YMD;
+ } else if ( ypos < dpos && dpos < mpos ) {
+ lOrder = TQDateEdit::YDM;
+ } else {
+ // cannot determine the dateformat - use the default
+ return;
+ }
+
+ // this code needs to change if new formats are added
+
+#ifndef TQ_WS_WIN
+ TQString sep = d.mid( TQMIN( dpos, mpos ) + 2, TQABS( dpos - mpos ) - 2 );
+ if ( d.tqcontains( sep ) == 2 ) {
+ *lDateSep = sep;
+ }
+#endif
+ }
+
+#ifndef TQ_WS_WIN
+ TQString t = TQTime( 11, 22, 33 ).toString( Qt::LocalDate );
+ dpos = t.tqfind( "11" );
+ mpos = t.tqfind( "22" );
+ ypos = t.tqfind( "33" );
+ // We only allow hhmmss
+ if ( dpos > -1 && dpos < mpos && mpos < ypos ) {
+ TQString sep = t.mid( dpos + 2, mpos - dpos - 2 );
+ if ( sep == t.mid( mpos + 2, ypos - mpos - 2 ) ) {
+ *lTimeSep = sep;
+ }
+ }
+#endif
+}
+
+static TQDateEdit::Order localOrder() {
+ if ( !lDateSep ) {
+ readLocaleSettings();
+ }
+ return lOrder;
+}
+
+static TQString localDateSep() {
+ if ( !lDateSep ) {
+ readLocaleSettings();
+ }
+ return *lDateSep;
+}
+
+static TQString localTimeSep() {
+ if ( !lTimeSep ) {
+ readLocaleSettings();
+ }
+ return *lTimeSep;
+}
+
+class TQDateTimeEditorPrivate
+{
+public:
+ TQDateTimeEditorPrivate()
+ : frm( TRUE ),
+ parag( new TQTextParagraph( 0, 0, 0, FALSE ) ),
+ focusSec(0)
+ {
+ parag->formatter()->setWrapEnabled( FALSE );
+ cursor = new TQTextCursor( 0 );
+ cursor->setParagraph( parag );
+ offset = 0;
+ sep = localDateSep();
+ refcount++;
+ }
+ ~TQDateTimeEditorPrivate()
+ {
+ delete parag;
+ delete cursor;
+ if ( !--refcount )
+ cleanup();
+ }
+
+ void appendSection( const TQNumberSection& sec )
+ {
+ sections.append( sec );
+
+ }
+ void clearSections()
+ {
+ sections.clear();
+ }
+ void setSectionSelection( int sec, int selstart, int selend )
+ {
+ if ( sec < 0 || sec > (int)sections.count() )
+ return;
+ sections[sec].setSelectionStart( selstart );
+ sections[sec].setSelectionEnd( selend );
+ }
+ uint sectionCount() const { return (uint)sections.count(); }
+ void setSeparator( const TQString& s ) { sep = s; }
+ TQString separator() const { return sep; }
+
+ void setFrame( bool f ) { frm = f; }
+ bool frame() const { return frm; }
+
+ int focusSection() const { return focusSec; }
+ int section( const TQPoint& p )
+ {
+ cursor->place( p + TQPoint( offset, 0 ), parag );
+ int idx = cursor->index();
+ for ( uint i = 0; i < sections.count(); ++i ) {
+ if ( idx >= sections[i].selectionStart() &&
+ idx <= sections[i].selectionEnd() )
+ return i;
+ }
+ return -1;
+ }
+ TQNumberSection section( int idx ) const
+ {
+ return sections[idx];
+ }
+ bool setFocusSection( int idx )
+ {
+ if ( idx > (int)sections.count()-1 || idx < 0 )
+ return FALSE;
+ if ( idx != focusSec ) {
+ focusSec = idx;
+ applyFocusSelection();
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ bool inSectionSelection( int idx )
+ {
+ for ( uint i = 0; i < sections.count(); ++i ) {
+ if ( idx >= sections[i].selectionStart() &&
+ idx <= sections[i].selectionEnd() )
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ void paint( const TQString& txt, bool focus, TQPainter& p,
+ const TQColorGroup& cg, const TQRect& rect, TQStyle& style )
+ {
+ int fw = 0;
+ if ( frm )
+ fw = style.tqpixelMetric(TQStyle::PM_DefaultFrameWidth);
+
+ parag->truncate( 0 );
+ parag->append( txt );
+ if ( !focus )
+ parag->removeSelection( TQTextDocument::Standard );
+ else {
+ applyFocusSelection();
+ }
+
+ /* color all TQDATETIMEEDIT_HIDDEN_CHAR chars to background color */
+ TQTextFormat *fb = parag->formatCollection()->format( p.font(),
+ cg.base() );
+ TQTextFormat *nf = parag->formatCollection()->format( p.font(),
+ cg.text() );
+ for ( uint i = 0; i < txt.length(); ++i ) {
+ parag->setFormat( i, 1, nf );
+ if ( inSectionSelection( i ) )
+ continue;
+ if ( txt.at(i) == TQDATETIMEEDIT_HIDDEN_CHAR )
+ parag->setFormat( i, 1, fb );
+ else
+ parag->setFormat( i, 1, nf );
+ }
+ fb->removeRef();
+ nf->removeRef();
+
+ TQRect r( rect.x(), rect.y(), rect.width() - 2 * ( 2 + fw ), rect.height() );
+ parag->pseudoDocument()->docRect = r;
+ parag->tqinvalidate(0);
+ parag->format();
+
+ int xoff = 2 + fw - offset;
+ int yoff = ( rect.height() - parag->rect().height() + 1 ) / 2;
+ if ( yoff < 0 )
+ yoff = 0;
+
+ p.translate( xoff, yoff );
+ parag->paint( p, cg, 0, TRUE );
+ if ( frm )
+ p.translate( -xoff, -yoff );
+ }
+
+ void resize( const TQSize& size ) { sz = size; }
+
+ int mapSection( int sec )
+ {
+ return sections[sec].index();
+ }
+
+protected:
+ void applyFocusSelection()
+ {
+ if ( focusSec > -1 ) {
+ int selstart = sections[ focusSec ].selectionStart();
+ int selend = sections[ focusSec ].selectionEnd();
+ parag->setSelection( TQTextDocument::Standard, selstart, selend );
+ parag->format();
+ if ( parag->at( selstart )->x < offset ||
+ parag->at( selend )->x + parag->string()->width( selend ) > offset + sz.width() ) {
+ offset = parag->at( selstart )->x;
+ }
+ }
+ }
+private:
+ bool frm;
+ TQTextParagraph *parag;
+ TQTextCursor *cursor;
+ TQSize sz;
+ int focusSec;
+ TQValueList< TQNumberSection > sections;
+ TQString sep;
+ int offset;
+};
+
+class TQDateTimeEditor : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQDateTimeEditor( TQDateTimeEditBase * widget, TQWidget *tqparent,
+ const char * name=0 );
+ ~TQDateTimeEditor();
+
+ void setControlWidget( TQDateTimeEditBase * widget );
+ TQDateTimeEditBase * controlWidget() const;
+
+ void setSeparator( const TQString& s );
+ TQString separator() const;
+
+ int focusSection() const;
+ bool setFocusSection( int s );
+ void appendSection( const TQNumberSection& sec );
+ void clearSections();
+ void setSectionSelection( int sec, int selstart, int selend );
+ bool eventFilter( TQObject *o, TQEvent *e );
+ int sectionAt( const TQPoint &p );
+ int mapSection( int sec );
+
+protected:
+ void init();
+ bool event( TQEvent *e );
+ void resizeEvent( TQResizeEvent * );
+ void paintEvent( TQPaintEvent * );
+ void mousePressEvent( TQMouseEvent *e );
+
+private:
+ TQDateTimeEditBase* cw;
+ TQDateTimeEditorPrivate* d;
+};
+
+class TQDateTimeSpinWidget : public TQSpinWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQDateTimeSpinWidget( TQWidget *tqparent, const char *name )
+ : TQSpinWidget( tqparent, name )
+ {
+ }
+
+ void enabledChange(bool notenabled)
+ {
+ TQDateEdit *de = ::tqqt_cast<TQDateEdit*>(parentWidget());
+ if (de && !notenabled) {
+ setUpEnabled(de->date() < de->maxValue());
+ setDownEnabled(de->date() > de->minValue());
+ } else {
+ setUpEnabled(!notenabled);
+ setDownEnabled(!notenabled);
+ }
+ }
+
+protected:
+#ifndef TQT_NO_WHEELEVENT
+ void wheelEvent( TQWheelEvent *e )
+ {
+ TQDateTimeEditor *editor = (TQDateTimeEditor*)editWidget()->tqqt_cast( "TQDateTimeEditor" );
+ TQ_ASSERT( editor );
+ if ( !editor )
+ return;
+
+ int section = editor->sectionAt( e->pos() );
+ editor->setFocusSection( section );
+
+ if ( section == -1 )
+ return;
+ TQSpinWidget::wheelEvent( e );
+ }
+#endif
+};
+
+/*!
+ Constructs an empty datetime editor with tqparent \a tqparent and
+ called \a name.
+*/
+TQDateTimeEditor::TQDateTimeEditor( TQDateTimeEditBase * widget, TQWidget *tqparent,
+ const char * name )
+ : TQWidget( tqparent, name, TQt::WNoAutoErase )
+{
+ d = new TQDateTimeEditorPrivate();
+ cw = widget;
+ init();
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQDateTimeEditor::~TQDateTimeEditor()
+{
+ delete d;
+}
+
+/*! \internal
+
+*/
+
+void TQDateTimeEditor::init()
+{
+ setBackgroundMode( TQt::PaletteBase );
+ setFocusSection( -1 );
+ installEventFilter( this );
+ setFocusPolicy( Qt::WheelFocus );
+}
+
+
+/*! \reimp
+
+*/
+
+bool TQDateTimeEditor::event( TQEvent *e )
+{
+ if ( e->type() == TQEvent::FocusIn || e->type() == TQEvent::FocusOut ) {
+ if ( e->type() == TQEvent::FocusOut )
+ tqApp->sendEvent( cw, e );
+ update( rect() );
+ } else if ( e->type() == TQEvent::AccelOverride ) {
+ TQKeyEvent* ke = (TQKeyEvent*) e;
+ switch ( ke->key() ) {
+ case Qt::Key_Delete:
+ case Qt::Key_Backspace:
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ return TQWidget::event( e );
+}
+
+/*! \reimp
+
+*/
+
+void TQDateTimeEditor::resizeEvent( TQResizeEvent *e )
+{
+ d->resize( e->size() );
+ TQWidget::resizeEvent( e );
+}
+
+
+/*! \reimp
+
+*/
+
+void TQDateTimeEditor::paintEvent( TQPaintEvent * )
+{
+ TQString txt;
+ for ( uint i = 0; i < d->sectionCount(); ++i ) {
+ txt += cw->sectionFormattedText( i );
+ if ( i < d->sectionCount()-1 ) {
+ if ( d->section( i+1 ).separator() )
+ txt += d->separator();
+ else
+ txt += " ";
+ }
+ }
+
+ TQSharedDoubleBuffer buffer( this );
+ const TQBrush &bg =
+ tqcolorGroup().brush( isEnabled() ? TQColorGroup::Base : TQColorGroup::Background );
+ buffer.painter()->fillRect( 0, 0, width(), height(), bg );
+ d->paint( txt, hasFocus(), *buffer.painter(), tqcolorGroup(), rect(),
+ tqstyle() );
+ buffer.end();
+}
+
+
+/*!
+ Returns the section index at point \a p.
+*/
+int TQDateTimeEditor::sectionAt( const TQPoint &p )
+{
+ return d->section( p );
+}
+
+int TQDateTimeEditor::mapSection( int sec )
+{
+ return d->mapSection( sec );
+}
+
+
+/*! \reimp
+
+*/
+
+void TQDateTimeEditor::mousePressEvent( TQMouseEvent *e )
+{
+ TQPoint p( e->pos().x(), 0 );
+ int sec = sectionAt( p );
+ if ( sec != -1 ) {
+ cw->setFocusSection( sec );
+ tqrepaint( rect(), FALSE );
+ }
+}
+
+/*! \reimp
+
+*/
+bool TQDateTimeEditor::eventFilter( TQObject *o, TQEvent *e )
+{
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) ) {
+ if ( e->type() == TQEvent::KeyPress ) {
+ TQKeyEvent *ke = (TQKeyEvent*)e;
+ switch ( ke->key() ) {
+ case Qt::Key_Right:
+ if ( d->focusSection() < (int)d->sectionCount()-1 ) {
+ if ( cw->setFocusSection( focusSection()+1 ) )
+ tqrepaint( rect(), FALSE );
+ }
+ return TRUE;
+ case Qt::Key_Left:
+ if ( d->focusSection() > 0 ) {
+ if ( cw->setFocusSection( focusSection()-1 ) )
+ tqrepaint( rect(), FALSE );
+ }
+ return TRUE;
+ case Qt::Key_Up:
+ cw->stepUp();
+ return TRUE;
+ case Qt::Key_Down:
+ cw->stepDown();
+ return TRUE;
+ case Qt::Key_Backspace:
+ if ( ::tqqt_cast<TQDateEdit*>(cw) )
+ ((TQDateEdit*)cw)->removeFirstNumber( d->focusSection() );
+ else if ( ::tqqt_cast<TQTimeEdit*>(cw) )
+ ((TQTimeEdit*)cw)->removeFirstNumber( d->focusSection() );
+ return TRUE;
+ case Qt::Key_Delete:
+ cw->removeLastNumber( d->focusSection() );
+ return TRUE;
+ case Qt::Key_Tab:
+ case TQt::Key_BackTab: {
+ if ( ke->state() == ControlButton )
+ return FALSE;
+
+ TQWidget *w = this;
+ bool hadDateEdit = FALSE;
+ while ( w ) {
+ if ( (::tqqt_cast<TQDateTimeSpinWidget*>(w) && qstrcmp( w->name(), "qt_spin_widget" ) != 0) ||
+ ::tqqt_cast<TQDateTimeEdit*>(w) )
+ break;
+ hadDateEdit = hadDateEdit || ::tqqt_cast<TQDateEdit*>(w);
+ w = w->parentWidget();
+ }
+
+ if ( w ) {
+ if ( !::tqqt_cast<TQDateTimeEdit*>(w) ) {
+ w = w->parentWidget();
+ } else {
+ TQDateTimeEdit *ed = (TQDateTimeEdit*)w;
+ if ( hadDateEdit && ke->key() == Qt::Key_Tab ) {
+ ed->timeEdit()->setFocus();
+ return TRUE;
+ } else if ( !hadDateEdit && ke->key() == TQt::Key_BackTab ) {
+ ed->dateEdit()->setFocus();
+ return TRUE;
+ } else {
+ while ( w && !::tqqt_cast<TQDateTimeEdit*>(w) )
+ w = w->parentWidget();
+ }
+ }
+
+ tqApp->sendEvent( w, e );
+ return TRUE;
+ }
+ } break;
+ default:
+ TQString txt = TQT_TQSTRING(ke->text()).lower();
+ if ( !txt.isEmpty() && !separator().isEmpty() && txt[0] == separator()[0] ) {
+ // do the same thing as KEY_RIGHT when the user presses the separator key
+ if ( d->focusSection() < 2 ) {
+ if ( cw->setFocusSection( focusSection()+1 ) )
+ tqrepaint( rect(), FALSE );
+ }
+ return TRUE;
+ } else if ( !txt.isEmpty() && ::tqqt_cast<TQTimeEdit*>(cw) && focusSection() == (int) d->sectionCount()-1 ) {
+ // the first character of the AM/PM indicator toggles if the section has focus
+ TQTimeEdit *te = (TQTimeEdit*)cw;
+ TQTime time = te->time();
+ if ( lAMPM && lAM && lPM && (te->display()&TQTimeEdit::AMPM) ) {
+ if ( txt[0] == (*lAM).lower()[0] && time.hour() >= 12 ) {
+ time.setHMS( time.hour()-12, time.minute(), time.second(), time.msec() );
+ te->setTime( time );
+ } else if ( txt[0] == (*lPM).lower()[0] && time.hour() < 12 ) {
+ time.setHMS( time.hour()+12, time.minute(), time.second(), time.msec() );
+ te->setTime( time );
+ }
+ }
+ }
+
+ int num = txt[0].digitValue();
+ if ( num != -1 ) {
+ cw->addNumber( d->focusSection(), num );
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+/*!
+ Appends the number section \a sec to the editor.
+*/
+
+void TQDateTimeEditor::appendSection( const TQNumberSection& sec )
+{
+ d->appendSection( sec );
+}
+
+/*!
+ Removes all sections from the editor.
+*/
+
+void TQDateTimeEditor::clearSections()
+{
+ d->clearSections();
+}
+
+/*!
+ Sets the selection of \a sec to start at \a selstart and end at \a
+ selend.
+*/
+
+void TQDateTimeEditor::setSectionSelection( int sec, int selstart, int selend )
+{
+ d->setSectionSelection( sec, selstart, selend );
+}
+
+/*!
+ Sets the separator for all numbered sections to \a s. Note that
+ currently, only the first character of \a s is used.
+*/
+
+void TQDateTimeEditor::setSeparator( const TQString& s )
+{
+ d->setSeparator( s );
+ update();
+}
+
+
+/*!
+ Returns the editor's separator.
+*/
+
+TQString TQDateTimeEditor::separator() const
+{
+ return d->separator();
+}
+
+/*!
+ Returns the number of the section that has focus.
+*/
+
+int TQDateTimeEditor::focusSection() const
+{
+ return d->focusSection();
+}
+
+
+/*!
+ Sets the focus to section \a sec. If \a sec does not exist,
+ nothing happens.
+*/
+
+bool TQDateTimeEditor::setFocusSection( int sec )
+{
+ return d->setFocusSection( sec );
+}
+
+/*! \class TQDateTimeEditBase
+ \brief The TQDateTimeEditBase class provides an abstraction for date and edit editors.
+
+ Small abstract class that provides some functions that are common
+ for both TQDateEdit and TQTimeEdit. It is used internally by
+ TQDateTimeEditor.
+*/
+
+/*!
+ \fn TQDateTimeEditBase::TQDateTimeEditBase(TQWidget *, const char*)
+ \internal
+*/
+
+/*!
+ \fn TQDateTimeEditBase::setFocusSection(int)
+ \internal
+*/
+
+/*! \fn TQString TQDateTimeEditBase::sectionFormattedText( int sec )
+ \internal
+
+ Pure virtual function which returns the formatted text of section \a
+ sec.
+
+*/
+
+/*! \fn void TQDateTimeEditBase::stepUp()
+ \internal
+
+ Pure virtual slot which is called whenever the user increases the
+ number in a section by pressing the widget's arrow buttons or the
+ keyboard's arrow keys.
+*/
+
+/*! \fn void TQDateTimeEditBase::stepDown()
+ \internal
+
+ Pure virtual slot which is called whenever the user decreases the
+ number in a section by pressing the widget's arrow buttons or the
+ keyboard's arrow keys.
+
+*/
+
+/*! \fn void TQDateTimeEditBase::addNumber( int sec, int num )
+ \internal
+
+ Pure virtual function which is called whenever the user types a number.
+ \a sec indicates the section where the number should be added. \a
+ num is the number that was pressed.
+*/
+
+/*! \fn void TQDateTimeEditBase::removeLastNumber( int sec )
+ \internal
+
+ Pure virtual function which is called whenever the user tries to
+ remove the last number from \a sec by pressing the delete key.
+*/
+
+////////////////
+
+class TQDateEditPrivate
+{
+public:
+ int y;
+ int m;
+ int d;
+ // remebers the last entry for the day.
+ // if the day is 31 and you cycle through the months,
+ // the day will be 31 again if you reach a month with 31 days
+ // otherwise it will be the highest day in the month
+ int dayCache;
+ int yearSection;
+ int monthSection;
+ int daySection;
+ TQDateEdit::Order ord;
+ bool overwrite;
+ bool adv;
+ int timerId;
+ bool typing;
+ TQDate min;
+ TQDate max;
+ bool changed;
+ TQDateTimeEditor *ed;
+ TQSpinWidget *controls;
+};
+
+
+/*!
+ \class TQDateEdit tqdatetimeedit.h
+ \brief The TQDateEdit class provides a date editor.
+
+ \ingroup advanced
+ \ingroup time
+ \mainclass
+
+ TQDateEdit allows the user to edit dates by using the keyboard or
+ the arrow keys to increase/decrease date values. The arrow keys
+ can be used to move from section to section within the TQDateEdit
+ box. Dates appear in accordance with the local date/time settings
+ or in year, month, day order if the system doesn't provide this
+ information. It is recommended that the TQDateEdit be initialised
+ with a date, e.g.
+
+ \code
+ TQDateEdit *dateEdit = new TQDateEdit( TQDate::tqcurrentDate(), this );
+ dateEdit->setRange( TQDate::tqcurrentDate().addDays( -365 ),
+ TQDate::tqcurrentDate().addDays( 365 ) );
+ dateEdit->setOrder( TQDateEdit::MDY );
+ dateEdit->setAutoAdvance( TRUE );
+ \endcode
+
+ Here we've created a new TQDateEdit object initialised with today's
+ date and restricted the valid date range to today plus or minus
+ 365 days. We've set the order to month, day, year. If the auto
+ advance property is TRUE (as we've set it here) when the user
+ completes a section of the date, e.g. enters two digits for the
+ month, they are automatically taken to the next section.
+
+ The maximum and minimum values for a date value in the date editor
+ default to the maximum and minimum values for a TQDate. You can
+ change this by calling setMinValue(), setMaxValue() or setRange().
+
+ Terminology: A TQDateEdit widget comprises three 'sections', one
+ each for the year, month and day. You can change the separator
+ character using TQDateTimeEditor::setSeparator(), by default the
+ separator will be taken from the systems settings. If that is
+ not possible, it defaults to "-".
+
+ \img datetimewidgets.png Date Time Widgets
+
+ \sa TQDate TQTimeEdit TQDateTimeEdit
+*/
+
+/*!
+ \enum TQDateEdit::Order
+
+ This enum defines the order in which the sections that comprise a
+ date appear.
+ \value MDY month-day-year
+ \value DMY day-month-year
+ \value YMD year-month-day (the default)
+ \value YDM year-day-month (included for completeness; but should
+ not be used)
+*/
+
+/*!
+ \enum TQTimeEdit::Display
+
+ This enum defines the sections that comprise a time
+
+ \value Hours The hours section
+ \value Minutes The minutes section
+ \value Seconds The seconds section
+ \value AMPM The AM/PM section
+
+ The values can be or'ed together to show any combination.
+*/
+
+/*!
+ Constructs an empty date editor which is a child of \a tqparent and
+ called name \a name.
+*/
+
+TQDateEdit::TQDateEdit( TQWidget * tqparent, const char * name )
+ : TQDateTimeEditBase( tqparent, name )
+{
+ init();
+ updateButtons();
+}
+
+/*!
+ \overload
+
+ Constructs a date editor with the initial value \a date, tqparent \a
+ tqparent and called \a name.
+
+ The date editor is initialized with \a date.
+*/
+
+TQDateEdit::TQDateEdit( const QDate& date, QWidget * tqparent, const char * name )
+ : TQDateTimeEditBase( TQT_TQWIDGET(tqparent), name )
+{
+ init();
+ setDate( TQT_TQDATE_OBJECT(date) );
+}
+
+/*! \internal
+*/
+void TQDateEdit::init()
+{
+ d = new TQDateEditPrivate();
+ d->controls = new TQDateTimeSpinWidget( this, qstrcmp( name(), "qt_datetime_dateedit" ) == 0 ? "qt_spin_widget" : "date edit controls" );
+ d->ed = new TQDateTimeEditor( this, d->controls, "date editor" );
+ d->controls->setEditWidget( d->ed );
+ setFocusProxy( d->ed );
+ connect( d->controls, TQT_SIGNAL( stepUpPressed() ), TQT_SLOT( stepUp() ) );
+ connect( d->controls, TQT_SIGNAL( stepDownPressed() ), TQT_SLOT( stepDown() ) );
+ connect( this, TQT_SIGNAL( valueChanged(const TQDate&) ),
+ TQT_SLOT( updateButtons() ) );
+ d->ed->appendSection( TQNumberSection( 0,4 ) );
+ d->ed->appendSection( TQNumberSection( 5,7 ) );
+ d->ed->appendSection( TQNumberSection( 8,10 ) );
+
+ d->yearSection = -1;
+ d->monthSection = -1;
+ d->daySection = -1;
+
+ d->y = 0;
+ d->m = 0;
+ d->d = 0;
+ d->dayCache = 0;
+ setOrder( localOrder() );
+ setFocusSection( 0 );
+ d->overwrite = TRUE;
+ d->adv = FALSE;
+ d->timerId = 0;
+ d->typing = FALSE;
+ d->min = TQDate( 1752, 9, 14 );
+ d->max = TQDate( 8000, 12, 31 );
+ d->changed = FALSE;
+
+ tqsetSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed );
+
+ refcount++;
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQDateEdit::~TQDateEdit()
+{
+ delete d;
+ if ( !--refcount )
+ cleanup();
+}
+
+/*!
+ \property TQDateEdit::minValue
+
+ \brief the editor's minimum value
+
+ Setting the minimum date value is equivalent to calling
+ TQDateEdit::setRange( \e d, maxValue() ), where \e d is the minimum
+ date. The default minimum date is 1752-09-14.
+
+ \sa maxValue setRange()
+*/
+
+TQDate TQDateEdit::minValue() const
+{
+ return d->min;
+}
+
+/*!
+ \property TQDateEdit::maxValue
+
+ \brief the editor's maximum value
+
+ Setting the maximum date value for the editor is equivalent to
+ calling TQDateEdit::setRange( minValue(), \e d ), where \e d is the
+ maximum date. The default maximum date is 8000-12-31.
+
+ \sa minValue setRange()
+*/
+
+TQDate TQDateEdit::maxValue() const
+{
+ return d->max;
+}
+
+
+/*!
+ Sets the valid input range for the editor to be from \a min to \a
+ max inclusive. If \a min is invalid no minimum date will be set.
+ Similarly, if \a max is invalid no maximum date will be set.
+*/
+
+void TQDateEdit::setRange( const TQDate& min, const TQDate& max )
+{
+ if ( min.isValid() )
+ d->min = min;
+ if ( max.isValid() )
+ d->max = max;
+}
+
+/*!
+ Sets the separator to \a s. Note that currently only the first
+ character of \a s is used.
+*/
+
+void TQDateEdit::setSeparator( const TQString& s )
+{
+ d->ed->setSeparator( s );
+}
+
+/*!
+ Returns the editor's separator.
+*/
+
+TQString TQDateEdit::separator() const
+{
+ return d->ed->separator();
+}
+
+
+/*!
+ Enables/disables the push buttons according to the min/max date
+ for this widget.
+*/
+
+void TQDateEdit::updateButtons()
+{
+ if ( !isEnabled() )
+ return;
+
+ bool upEnabled = date() < maxValue();
+ bool downEnabled = date() > minValue();
+
+ d->controls->setUpEnabled( upEnabled );
+ d->controls->setDownEnabled( downEnabled );
+}
+
+/*! \reimp
+ */
+void TQDateEdit::resizeEvent( TQResizeEvent * )
+{
+ d->controls->resize( width(), height() );
+}
+
+/*! \reimp
+
+*/
+TQSize TQDateEdit::tqsizeHint() const
+{
+ constPolish();
+ TQFontMetrics fm( font() );
+ int fw = tqstyle().tqpixelMetric( TQStyle::PM_DefaultFrameWidth, this );
+ int h = TQMAX( fm.lineSpacing(), 14 ) + 2;
+ int w = 2 + fm.width( '9' ) * 8 + fm.width( d->ed->separator() ) * 2 + d->controls->upRect().width() + fw * 4;
+
+ return TQSize( w, TQMAX(h + fw * 2,20) ).expandedTo( TQApplication::globalStrut() );
+}
+
+/*! \reimp
+
+*/
+TQSize TQDateEdit::tqminimumSizeHint() const
+{
+ return tqsizeHint();
+}
+
+
+/*!
+ Returns the formatted number for section \a sec. This will
+ correspond to either the year, month or day section, depending on
+ the current display order.
+
+ \sa setOrder()
+*/
+
+TQString TQDateEdit::sectionFormattedText( int sec )
+{
+ TQString txt;
+ txt = sectionText( sec );
+ if ( d->typing && sec == d->ed->focusSection() )
+ d->ed->setSectionSelection( sec, sectionOffsetEnd( sec ) - txt.length(),
+ sectionOffsetEnd( sec ) );
+ else
+ d->ed->setSectionSelection( sec, sectionOffsetEnd( sec ) - sectionLength( sec ),
+ sectionOffsetEnd( sec ) );
+ txt = txt.rightJustify( sectionLength( sec ), TQDATETIMEEDIT_HIDDEN_CHAR );
+ return txt;
+}
+
+
+/*!
+ Returns the desired length (number of digits) of section \a sec.
+ This will correspond to either the year, month or day section,
+ depending on the current display order.
+
+ \sa setOrder()
+*/
+
+int TQDateEdit::sectionLength( int sec ) const
+{
+ int val = 0;
+ if ( sec == d->yearSection ) {
+ val = 4;
+ } else if ( sec == d->monthSection ) {
+ val = 2;
+ } else if ( sec == d->daySection ) {
+ val = 2;
+ }
+ return val;
+}
+
+/*!
+ Returns the text of section \a sec. This will correspond to either
+ the year, month or day section, depending on the current display
+ order.
+
+ \sa setOrder()
+*/
+
+TQString TQDateEdit::sectionText( int sec ) const
+{
+ int val = 0;
+ if ( sec == d->yearSection ) {
+ val = d->y;
+ } else if ( sec == d->monthSection ) {
+ val = d->m;
+ } else if ( sec == d->daySection ) {
+ val = d->d;
+ }
+ return TQString::number( val );
+}
+
+/*! \internal
+
+ Returns the end of the section offset \a sec.
+
+*/
+
+int TQDateEdit::sectionOffsetEnd( int sec ) const
+{
+ if ( sec == d->yearSection ) {
+ switch( d->ord ) {
+ case DMY:
+ case MDY:
+ return sectionOffsetEnd( sec-1) + separator().length() + sectionLength( sec );
+ case YMD:
+ case YDM:
+ return sectionLength( sec );
+ }
+ } else if ( sec == d->monthSection ) {
+ switch( d->ord ) {
+ case DMY:
+ case YDM:
+ case YMD:
+ return sectionOffsetEnd( sec-1) + separator().length() + sectionLength( sec );
+ case MDY:
+ return sectionLength( sec );
+ }
+ } else if ( sec == d->daySection ) {
+ switch( d->ord ) {
+ case DMY:
+ return sectionLength( sec );
+ case YMD:
+ case MDY:
+ case YDM:
+ return sectionOffsetEnd( sec-1 ) + separator().length() + sectionLength( sec );
+ }
+ }
+ return 0;
+}
+
+
+/*!
+ \property TQDateEdit::order
+ \brief the order in which the year, month and day appear
+
+ The default order is locale dependent.
+
+ \sa Order
+*/
+
+void TQDateEdit::setOrder( TQDateEdit::Order order )
+{
+ d->ord = order;
+ switch( d->ord ) {
+ case DMY:
+ d->yearSection = 2;
+ d->monthSection = 1;
+ d->daySection = 0;
+ break;
+ case MDY:
+ d->yearSection = 2;
+ d->monthSection = 0;
+ d->daySection = 1;
+ break;
+ case YMD:
+ d->yearSection = 0;
+ d->monthSection = 1;
+ d->daySection = 2;
+ break;
+ case YDM:
+ d->yearSection = 0;
+ d->monthSection = 2;
+ d->daySection = 1;
+ break;
+ }
+ if ( isVisible() )
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+
+TQDateEdit::Order TQDateEdit::order() const
+{
+ return d->ord;
+}
+
+
+/*! \reimp
+
+*/
+void TQDateEdit::stepUp()
+{
+ int sec = d->ed->focusSection();
+ bool accepted = FALSE;
+ if ( sec == d->yearSection ) {
+ if ( !outOfRange( d->y+1, d->m, d->d ) ) {
+ accepted = TRUE;
+ setYear( d->y+1 );
+ }
+ } else if ( sec == d->monthSection ) {
+ if ( !outOfRange( d->y, d->m+1, d->d ) ) {
+ accepted = TRUE;
+ setMonth( d->m+1 );
+ }
+ } else if ( sec == d->daySection ) {
+ if ( !outOfRange( d->y, d->m, d->d+1 ) ) {
+ accepted = TRUE;
+ setDay( d->d+1 );
+ }
+ }
+ if ( accepted ) {
+ d->changed = FALSE;
+ emit valueChanged( date() );
+ }
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+
+
+/*! \reimp
+
+*/
+
+void TQDateEdit::stepDown()
+{
+ int sec = d->ed->focusSection();
+ bool accepted = FALSE;
+ if ( sec == d->yearSection ) {
+ if ( !outOfRange( d->y-1, d->m, d->d ) ) {
+ accepted = TRUE;
+ setYear( d->y-1 );
+ }
+ } else if ( sec == d->monthSection ) {
+ if ( !outOfRange( d->y, d->m-1, d->d ) ) {
+ accepted = TRUE;
+ setMonth( d->m-1 );
+ }
+ } else if ( sec == d->daySection ) {
+ if ( !outOfRange( d->y, d->m, d->d-1 ) ) {
+ accepted = TRUE;
+ setDay( d->d-1 );
+ }
+ }
+ if ( accepted ) {
+ d->changed = FALSE;
+ emit valueChanged( date() );
+ }
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+/*!
+ Sets the year to \a year, which must be a valid year. The range
+ currently supported is from 1752 to 8000.
+
+ \sa TQDate
+*/
+
+void TQDateEdit::setYear( int year )
+{
+ if ( year < 1752 )
+ year = 1752;
+ if ( year > 8000 )
+ year = 8000;
+ if ( !outOfRange( year, d->m, d->d ) ) {
+ d->y = year;
+ setMonth( d->m );
+ int tmp = d->dayCache;
+ setDay( d->dayCache );
+ d->dayCache = tmp;
+ }
+}
+
+
+/*!
+ Sets the month to \a month, which must be a valid month, i.e.
+ between 1 and 12.
+*/
+
+void TQDateEdit::setMonth( int month )
+{
+ if ( month < 1 )
+ month = 1;
+ if ( month > 12 )
+ month = 12;
+ if ( !outOfRange( d->y, month, d->d ) ) {
+ d->m = month;
+ int tmp = d->dayCache;
+ setDay( d->dayCache );
+ d->dayCache = tmp;
+ }
+}
+
+
+/*!
+ Sets the day to \a day, which must be a valid day. The function
+ will ensure that the \a day set is valid for the month and year.
+*/
+
+void TQDateEdit::setDay( int day )
+{
+ if ( day < 1 )
+ day = 1;
+ if ( day > 31 )
+ day = 31;
+ if ( d->m > 0 && d->y > 1752 ) {
+ while ( !TQDate::isValid( d->y, d->m, day ) )
+ --day;
+ if ( !outOfRange( d->y, d->m, day ) )
+ d->d = day;
+ } else if ( d->m > 0 ) {
+ if ( day > 0 && day < 32 ) {
+ if ( !outOfRange( d->y, d->m, day ) )
+ d->d = day;
+ }
+ }
+ d->dayCache = d->d;
+}
+
+
+/*!
+ \property TQDateEdit::date
+ \brief the editor's date value.
+
+ If the date property is not valid, the editor displays all zeroes
+ and TQDateEdit::date() will return an invalid date. It is strongly
+ recommended that the editor is given a default date value (e.g.
+ currentDate()). That way, attempts to set the date property to an
+ invalid date will fail.
+
+ When changing the date property, if the date is less than
+ minValue(), or is greater than maxValue(), nothing happens.
+*/
+
+void TQDateEdit::setDate( const TQDate& date )
+{
+ if ( !date.isValid() ) {
+ d->y = 0;
+ d->m = 0;
+ d->d = 0;
+ d->dayCache = 0;
+ } else {
+ if ( date > maxValue() || date < minValue() )
+ return;
+ d->y = date.year();
+ d->m = date.month();
+ d->d = date.day();
+ d->dayCache = d->d;
+ emit valueChanged( date );
+ }
+ d->changed = FALSE;
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+TQDate TQDateEdit::date() const
+{
+ if ( TQDate::isValid( d->y, d->m, d->d ) )
+ return TQDate( d->y, d->m, d->d );
+ return TQDate();
+}
+
+/*! \internal
+
+ Returns TRUE if \a y, \a m, \a d is out of range, otherwise returns
+ FALSE.
+
+ \sa setRange()
+
+*/
+
+bool TQDateEdit::outOfRange( int y, int m, int d ) const
+{
+ if ( TQDate::isValid( y, m, d ) ) {
+ TQDate tqcurrentDate( y, m, d );
+ if ( tqcurrentDate > maxValue() ||
+ tqcurrentDate < minValue() ) {
+ //## outOfRange should set overwrite?
+ return TRUE;
+ }
+ return FALSE;
+ }
+ return FALSE; /* assume ok */
+}
+
+/*! \reimp
+
+*/
+
+void TQDateEdit::addNumber( int sec, int num )
+{
+ if ( sec == -1 )
+ return;
+ killTimer( d->timerId );
+ bool overwrite = FALSE;
+ bool accepted = FALSE;
+ d->typing = TRUE;
+ TQString txt;
+ if ( sec == d->yearSection ) {
+ txt = TQString::number( d->y );
+ if ( d->overwrite || txt.length() == 4 ) {
+ accepted = TRUE;
+ d->y = num;
+ } else {
+ txt += TQString::number( num );
+ if ( txt.length() == 4 ) {
+ int val = txt.toInt();
+ if ( val < 1792 )
+ d->y = 1792;
+ else if ( val > 8000 )
+ d->y = 8000;
+ else if ( outOfRange( val, d->m, d->d ) )
+ txt = TQString::number( d->y );
+ else {
+ accepted = TRUE;
+ d->y = val;
+ }
+ } else {
+ accepted = TRUE;
+ d->y = txt.toInt();
+ }
+ if ( d->adv && txt.length() == 4 ) {
+ d->ed->setFocusSection( d->ed->focusSection()+1 );
+ overwrite = TRUE;
+ }
+ }
+ } else if ( sec == d->monthSection ) {
+ txt = TQString::number( d->m );
+ if ( d->overwrite || txt.length() == 2 ) {
+ accepted = TRUE;
+ d->m = num;
+ } else {
+ txt += TQString::number( num );
+ int temp = txt.toInt();
+ if ( temp > 12 )
+ temp = num;
+ if ( outOfRange( d->y, temp, d->d ) )
+ txt = TQString::number( d->m );
+ else {
+ accepted = TRUE;
+ d->m = temp;
+ }
+ if ( d->adv && txt.length() == 2 ) {
+ d->ed->setFocusSection( d->ed->focusSection()+1 );
+ overwrite = TRUE;
+ }
+ }
+ } else if ( sec == d->daySection ) {
+ txt = TQString::number( d->d );
+ if ( d->overwrite || txt.length() == 2 ) {
+ accepted = TRUE;
+ d->d = num;
+ d->dayCache = d->d;
+ } else {
+ txt += TQString::number( num );
+ int temp = txt.toInt();
+ if ( temp > 31 )
+ temp = num;
+ if ( outOfRange( d->y, d->m, temp ) )
+ txt = TQString::number( d->d );
+ else {
+ accepted = TRUE;
+ d->d = temp;
+ d->dayCache = d->d;
+ }
+ if ( d->adv && txt.length() == 2 ) {
+ d->ed->setFocusSection( d->ed->focusSection()+1 );
+ overwrite = TRUE;
+ }
+ }
+ }
+ if ( accepted ) {
+ d->changed = FALSE;
+ emit valueChanged( date() );
+ }
+ d->overwrite = overwrite;
+ d->timerId = startTimer( tqApp->doubleClickInterval()*4 );
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+
+/*! \reimp
+
+*/
+
+bool TQDateEdit::setFocusSection( int s )
+{
+ if ( s != d->ed->focusSection() ) {
+ killTimer( d->timerId );
+ d->overwrite = TRUE;
+ d->typing = FALSE;
+ fix(); // will emit valueChanged if necessary
+ }
+ return d->ed->setFocusSection( s );
+}
+
+
+/*!
+ Attempts to fix any invalid date entries.
+
+ The rules applied are as follows:
+
+ \list
+ \i If the year has four digits it is left unchanged.
+ \i If the year has two digits, the year will be changed to four
+ digits in the range current year - 70 to current year + 29.
+ \i If the year has three digits in the range 100..999, the
+ current millennium, i.e. 2000, will be added giving a year
+ in the range 2100..2999.
+ \i If the day or month is 0 then it will be set to 1 or the
+ minimum valid day\month in the range.
+ \endlist
+
+*/
+
+void TQDateEdit::fix()
+{
+ bool changed = FALSE;
+ int currentYear = TQDate::currentDate().year();
+ int year = d->y;
+ if ( year < 100 ) {
+ int currentCentury = currentYear / 100;
+ year += currentCentury * 100;
+ if ( currentYear > year ) {
+ if ( currentYear > year + 70 )
+ year += 100;
+ } else {
+ if ( year >= currentYear + 30 )
+ year -= 100;
+ }
+ changed = TRUE;
+ } else if ( year < 1000 ) {
+ int currentMillennium = currentYear / 10;
+ year += currentMillennium * 10;
+ changed = TRUE;
+ } else if (d->d == 0) {
+ d->d = 1;
+ changed = TRUE;
+ } else if (d->m == 0) {
+ d->m = 1;
+ changed = TRUE;
+ }
+ if ( outOfRange( year, d->m, d->d ) ) {
+ if ( minValue().isValid() && date() < minValue() ) {
+ d->d = minValue().day();
+ d->dayCache = d->d;
+ d->m = minValue().month();
+ d->y = minValue().year();
+ }
+ if ( date() > maxValue() ) {
+ d->d = maxValue().day();
+ d->dayCache = d->d;
+ d->m = maxValue().month();
+ d->y = maxValue().year();
+ }
+ changed = TRUE;
+ } else if ( changed )
+ setYear( year );
+ if ( changed ) {
+ emit valueChanged( date() );
+ d->changed = FALSE;
+ }
+}
+
+
+/*! \reimp
+
+*/
+
+bool TQDateEdit::event( TQEvent *e )
+{
+ if( e->type() == TQEvent::FocusOut ) {
+ d->typing = FALSE;
+ fix();
+ // the following can't be done in fix() because fix() called
+ // from all over the place and it will break the old behaviour
+ if ( !TQDate::isValid( d->y, d->m, d->d ) ) {
+ d->dayCache = d->d;
+ int i = d->d;
+ for ( ; i > 0; i-- ) {
+ d->d = i;
+ if ( TQDate::isValid( d->y, d->m, d->d ) )
+ break;
+ }
+ d->changed = TRUE;
+ }
+ if ( d->changed ) {
+ emit valueChanged( date() );
+ d->changed = FALSE;
+ }
+ } else if ( e->type() == TQEvent::LocaleChange ) {
+ readLocaleSettings();
+ d->ed->setSeparator( localDateSep() );
+ setOrder( localOrder() );
+ }
+ return TQDateTimeEditBase::event( e );
+}
+
+/*!
+ \internal
+
+ Function which is called whenever the user tries to
+ remove the first number from \a sec by pressing the backspace key.
+*/
+
+void TQDateEdit::removeFirstNumber( int sec )
+{
+ if ( sec == -1 )
+ return;
+ TQString txt;
+ if ( sec == d->yearSection ) {
+ txt = TQString::number( d->y );
+ txt = txt.mid( 1, txt.length() ) + "0";
+ d->y = txt.toInt();
+ } else if ( sec == d->monthSection ) {
+ txt = TQString::number( d->m );
+ txt = txt.mid( 1, txt.length() ) + "0";
+ d->m = txt.toInt();
+ } else if ( sec == d->daySection ) {
+ txt = TQString::number( d->d );
+ txt = txt.mid( 1, txt.length() ) + "0";
+ d->d = txt.toInt();
+ d->dayCache = d->d;
+ }
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+/*! \reimp
+
+*/
+
+void TQDateEdit::removeLastNumber( int sec )
+{
+ if ( sec == -1 )
+ return;
+ TQString txt;
+ if ( sec == d->yearSection ) {
+ txt = TQString::number( d->y );
+ txt = txt.mid( 0, txt.length()-1 );
+ d->y = txt.toInt();
+ } else if ( sec == d->monthSection ) {
+ txt = TQString::number( d->m );
+ txt = txt.mid( 0, txt.length()-1 );
+ d->m = txt.toInt();
+ } else if ( sec == d->daySection ) {
+ txt = TQString::number( d->d );
+ txt = txt.mid( 0, txt.length()-1 );
+ d->d = txt.toInt();
+ d->dayCache = d->d;
+ }
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+/*!
+ \property TQDateEdit::autoAdvance
+ \brief whether the editor automatically advances to the next
+ section
+
+ If autoAdvance is TRUE, the editor will automatically advance
+ focus to the next date section if a user has completed a section.
+ The default is FALSE.
+*/
+
+void TQDateEdit::setAutoAdvance( bool advance )
+{
+ d->adv = advance;
+}
+
+
+bool TQDateEdit::autoAdvance() const
+{
+ return d->adv;
+}
+
+/*! \reimp
+*/
+
+void TQDateEdit::timerEvent( TQTimerEvent * )
+{
+ d->overwrite = TRUE;
+}
+
+/*!
+ \fn void TQDateEdit::valueChanged( const TQDate& date )
+
+ This signal is emitted whenever the editor's value changes. The \a
+ date parameter is the new value.
+*/
+
+///////////
+
+class TQTimeEditPrivate
+{
+public:
+ int h;
+ int m;
+ int s;
+ uint display;
+ bool adv;
+ bool overwrite;
+ int timerId;
+ bool typing;
+ TQTime min;
+ TQTime max;
+ bool changed;
+ TQDateTimeEditor *ed;
+ TQSpinWidget *controls;
+};
+
+/*!
+ \class TQTimeEdit tqdatetimeedit.h
+ \brief The TQTimeEdit class provides a time editor.
+
+ \ingroup advanced
+ \ingroup time
+ \mainclass
+
+ TQTimeEdit allows the user to edit times by using the keyboard or
+ the arrow keys to increase/decrease time values. The arrow keys
+ can be used to move from section to section within the TQTimeEdit
+ box. The user can automatically be moved to the next section once
+ they complete a section using setAutoAdvance(). Times appear in
+ hour, minute, second order. It is recommended that the TQTimeEdit
+ is initialised with a time, e.g.
+ \code
+ TQTime timeNow = TQTime::currentTime();
+ TQTimeEdit *timeEdit = new TQTimeEdit( timeNow, this );
+ timeEdit->setRange( timeNow, timeNow.addSecs( 60 * 60 ) );
+ \endcode
+ Here we've created a TQTimeEdit widget set to the current time.
+ We've also set the minimum value to the current time and the
+ maximum time to one hour from now.
+
+ The maximum and minimum values for a time value in the time editor
+ default to the maximum and minimum values for a TQTime. You can
+ change this by calling setMinValue(), setMaxValue() or setRange().
+
+ Terminology: A TQTimeWidget consists of three sections, one each
+ for the hour, minute and second. You can change the separator
+ character using setSeparator(), by default the separator is read
+ from the system's settings.
+
+ \img datetimewidgets.png Date Time Widgets
+
+ \sa TQTime TQDateEdit TQDateTimeEdit
+*/
+
+
+/*!
+ Constructs an empty time edit with tqparent \a tqparent and called \a
+ name.
+*/
+
+TQTimeEdit::TQTimeEdit( TQWidget * tqparent, const char * name )
+ : TQDateTimeEditBase( tqparent, name )
+{
+ init();
+}
+
+/*!
+ \overload
+
+ Constructs a time edit with the initial time value, \a time,
+ tqparent \a tqparent and called \a name.
+*/
+
+TQTimeEdit::TQTimeEdit( const QTime& time, QWidget * tqparent, const char * name )
+ : TQDateTimeEditBase( TQT_TQWIDGET(tqparent), name )
+{
+ init();
+ setTime( TQT_TQTIME_OBJECT(time) );
+}
+
+/*! \internal
+ */
+
+void TQTimeEdit::init()
+{
+ d = new TQTimeEditPrivate();
+ d->controls = new TQDateTimeSpinWidget( this, qstrcmp( name(), "qt_datetime_timeedit" ) == 0 ? "qt_spin_widget" : "time edit controls" );
+ d->ed = new TQDateTimeEditor( this, d->controls, "time edit base" );
+ d->controls->setEditWidget( d->ed );
+ setFocusProxy( d->ed );
+ connect( d->controls, TQT_SIGNAL( stepUpPressed() ), TQT_SLOT( stepUp() ) );
+ connect( d->controls, TQT_SIGNAL( stepDownPressed() ), TQT_SLOT( stepDown() ) );
+
+ d->ed->appendSection( TQNumberSection( 0,0, TRUE, 0 ) );
+ d->ed->appendSection( TQNumberSection( 0,0, TRUE, 1 ) );
+ d->ed->appendSection( TQNumberSection( 0,0, TRUE, 2 ) );
+ d->ed->setSeparator( localTimeSep() );
+
+ d->h = 0;
+ d->m = 0;
+ d->s = 0;
+ d->display = Hours | Minutes | Seconds;
+ if ( lAMPM ) {
+ d->display |= AMPM;
+ d->ed->appendSection( TQNumberSection( 0,0, FALSE, 3 ) );
+ }
+ d->adv = FALSE;
+ d->overwrite = TRUE;
+ d->timerId = 0;
+ d->typing = FALSE;
+ d->min = TQTime( 0, 0, 0 );
+ d->max = TQTime( 23, 59, 59 );
+ d->changed = FALSE;
+
+ tqsetSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed );
+
+ refcount++;
+}
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQTimeEdit::~TQTimeEdit()
+{
+ delete d;
+ if ( !--refcount )
+ cleanup();
+}
+
+/*!
+ \property TQTimeEdit::minValue
+ \brief the minimum time value
+
+ Setting the minimum time value is equivalent to calling
+ TQTimeEdit::setRange( \e t, maxValue() ), where \e t is the minimum
+ time. The default minimum time is 00:00:00.
+
+ \sa maxValue setRange()
+*/
+
+TQTime TQTimeEdit::minValue() const
+{
+ return d->min;
+}
+
+/*!
+ \property TQTimeEdit::maxValue
+ \brief the maximum time value
+
+ Setting the maximum time value is equivalent to calling
+ TQTimeEdit::setRange( minValue(), \e t ), where \e t is the maximum
+ time. The default maximum time is 23:59:59.
+
+ \sa minValue setRange()
+*/
+
+TQTime TQTimeEdit::maxValue() const
+{
+ return d->max;
+}
+
+
+/*!
+ Sets the valid input range for the editor to be from \a min to \a
+ max inclusive. If \a min is invalid no minimum time is set.
+ Similarly, if \a max is invalid no maximum time is set.
+*/
+
+void TQTimeEdit::setRange( const TQTime& min, const TQTime& max )
+{
+ if ( min.isValid() )
+ d->min = min;
+ if ( max.isValid() )
+ d->max = max;
+}
+
+/*!
+ \property TQTimeEdit::display
+ \brief the sections that are displayed in the time edit
+
+ The value can be any combination of the values in the Display enum.
+ By default, the widget displays hours, minutes and seconds.
+*/
+void TQTimeEdit::setDisplay( uint display )
+{
+ if ( d->display == display )
+ return;
+
+ d->ed->clearSections();
+ d->display = display;
+ if ( d->display & Hours )
+ d->ed->appendSection( TQNumberSection( 0,0, TRUE, 0 ) );
+ if ( d->display & Minutes )
+ d->ed->appendSection( TQNumberSection( 0,0, TRUE, 1 ) );
+ if ( d->display & Seconds )
+ d->ed->appendSection( TQNumberSection( 0,0, TRUE, 2 ) );
+ if ( d->display & AMPM )
+ d->ed->appendSection( TQNumberSection( 0,0, FALSE, 3 ) );
+
+ d->ed->setFocusSection( 0 );
+ d->ed->update();
+}
+
+uint TQTimeEdit::display() const
+{
+ return d->display;
+}
+
+/*!
+ \property TQTimeEdit::time
+ \brief the editor's time value.
+
+ When changing the time property, if the time is less than
+ minValue(), or is greater than maxValue(), nothing happens.
+*/
+
+void TQTimeEdit::setTime( const TQTime& time )
+{
+ if ( !time.isValid() ) {
+ d->h = 0;
+ d->m = 0;
+ d->s = 0;
+ } else {
+ if ( time > maxValue() || time < minValue() )
+ return;
+ d->h = time.hour();
+ d->m = time.minute();
+ d->s = time.second();
+ emit valueChanged( time );
+ }
+ d->changed = FALSE;
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+TQTime TQTimeEdit::time() const
+{
+ if ( TQTime::isValid( d->h, d->m, d->s ) )
+ return TQTime( d->h, d->m, d->s );
+ return TQTime();
+}
+
+/*!
+ \property TQTimeEdit::autoAdvance
+ \brief whether the editor automatically advances to the next
+ section
+
+ If autoAdvance is TRUE, the editor will automatically advance
+ focus to the next time section if a user has completed a section.
+ The default is FALSE.
+*/
+
+void TQTimeEdit::setAutoAdvance( bool advance )
+{
+ d->adv = advance;
+}
+
+bool TQTimeEdit::autoAdvance() const
+{
+ return d->adv;
+}
+
+/*!
+ Sets the separator to \a s. Note that currently only the first
+ character of \a s is used.
+*/
+
+void TQTimeEdit::setSeparator( const TQString& s )
+{
+ d->ed->setSeparator( s );
+}
+
+/*!
+ Returns the editor's separator.
+*/
+
+TQString TQTimeEdit::separator() const
+{
+ return d->ed->separator();
+}
+
+
+/*!
+ \fn void TQTimeEdit::valueChanged( const TQTime& time )
+
+ This signal is emitted whenever the editor's value changes. The \a
+ time parameter is the new value.
+*/
+
+/*! \reimp
+
+*/
+
+bool TQTimeEdit::event( TQEvent *e )
+{
+ if ( e->type() == TQEvent::FocusOut ) {
+ d->typing = FALSE;
+ if ( d->changed ) {
+ emit valueChanged( time() );
+ d->changed = FALSE;
+ }
+ } else if ( e->type() == TQEvent::LocaleChange ) {
+ readLocaleSettings();
+ d->ed->setSeparator( localTimeSep() );
+ }
+ return TQDateTimeEditBase::event( e );
+}
+
+/*! \reimp
+
+*/
+
+void TQTimeEdit::timerEvent( TQTimerEvent * )
+{
+ d->overwrite = TRUE;
+}
+
+
+/*! \reimp
+
+*/
+
+void TQTimeEdit::stepUp()
+{
+ if (minValue() > maxValue()) {
+ return;
+ }
+ int sec = d->ed->mapSection( d->ed->focusSection() );
+ bool accepted = TRUE;
+ switch( sec ) {
+ case 0:
+ do {
+ d->h = (d->h + 1) % 24;
+ } while (outOfRange(d->h, d->m, d->s));
+ break;
+ case 1:
+ do {
+ d->m = (d->m + 1) % 60;
+ } while (outOfRange(d->h, d->m, d->s));
+ break;
+ case 2:
+ do {
+ d->s = (d->s + 1) % 60;
+ } while (outOfRange(d->h, d->m, d->s));
+ break;
+ case 3:
+ if ( d->h < 12 )
+ setHour( d->h+12 );
+ else
+ setHour( d->h-12 );
+ break;
+ default:
+ accepted = FALSE;
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQTimeEdit::stepUp: Focus section out of range!" );
+#endif
+ break;
+ }
+ if ( accepted ) {
+ d->changed = FALSE;
+ emit valueChanged( time() );
+ }
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+
+/*! \reimp
+
+*/
+
+void TQTimeEdit::stepDown()
+{
+ if (minValue() > maxValue()) {
+ return;
+ }
+
+ int sec = d->ed->mapSection( d->ed->focusSection() );
+ bool accepted = TRUE;
+ switch( sec ) {
+ case 0:
+ do {
+ if (--d->h < 0)
+ d->h = 23;
+ } while (outOfRange(d->h, d->m, d->s));
+ break;
+ case 1:
+ do {
+ if (--d->m < 0)
+ d->m = 59;
+ } while (outOfRange(d->h, d->m, d->s));
+ break;
+ case 2:
+ do {
+ if (--d->s < 0)
+ d->s = 59;
+ } while (outOfRange(d->h, d->m, d->s));
+ break;
+ case 3:
+ if ( d->h > 11 )
+ setHour( d->h-12 );
+ else
+ setHour( d->h+12 );
+ break;
+ default:
+ accepted = FALSE;
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQTimeEdit::stepDown: Focus section out of range!" );
+#endif
+ break;
+ }
+ if ( accepted ) {
+ d->changed = FALSE;
+ emit valueChanged( time() );
+ }
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+
+/*!
+ Returns the formatted number for section \a sec. This will
+ correspond to either the hour, minute or second section, depending
+ on \a sec.
+*/
+
+TQString TQTimeEdit::sectionFormattedText( int sec )
+{
+ TQString txt;
+ txt = sectionText( sec );
+ txt = txt.rightJustify( 2, TQDATETIMEEDIT_HIDDEN_CHAR );
+ int offset = sec*2+sec*separator().length() + txt.length();
+ if ( d->typing && sec == d->ed->focusSection() )
+ d->ed->setSectionSelection( sec, offset - txt.length(), offset );
+ else
+ d->ed->setSectionSelection( sec, offset - txt.length(), offset );
+
+ return txt;
+}
+
+
+/*! \reimp
+
+*/
+
+bool TQTimeEdit::setFocusSection( int sec )
+{
+ if ( sec != d->ed->focusSection() ) {
+ killTimer( d->timerId );
+ d->overwrite = TRUE;
+ d->typing = FALSE;
+ TQString txt = sectionText( sec );
+ txt = txt.rightJustify( 2, TQDATETIMEEDIT_HIDDEN_CHAR );
+ int offset = sec*2+sec*separator().length() + txt.length();
+ d->ed->setSectionSelection( sec, offset - txt.length(), offset );
+ if ( d->changed ) {
+ emit valueChanged( time() );
+ d->changed = FALSE;
+ }
+ }
+ return d->ed->setFocusSection( sec );
+}
+
+
+/*!
+ Sets the hour to \a h, which must be a valid hour, i.e. in the
+ range 0..24.
+*/
+
+void TQTimeEdit::setHour( int h )
+{
+ if ( h < 0 )
+ h = 0;
+ if ( h > 23 )
+ h = 23;
+ d->h = h;
+}
+
+
+/*!
+ Sets the minute to \a m, which must be a valid minute, i.e. in the
+ range 0..59.
+*/
+
+void TQTimeEdit::setMinute( int m )
+{
+ if ( m < 0 )
+ m = 0;
+ if ( m > 59 )
+ m = 59;
+ d->m = m;
+}
+
+
+/*!
+ Sets the second to \a s, which must be a valid second, i.e. in the
+ range 0..59.
+*/
+
+void TQTimeEdit::setSecond( int s )
+{
+ if ( s < 0 )
+ s = 0;
+ if ( s > 59 )
+ s = 59;
+ d->s = s;
+}
+
+
+/*! \internal
+
+ Returns the text of section \a sec.
+
+*/
+
+TQString TQTimeEdit::sectionText( int sec )
+{
+ sec = d->ed->mapSection( sec );
+
+ TQString txt;
+ switch( sec ) {
+ case 0:
+ if ( !(d->display & AMPM) || ( d->h < 13 && d->h ) ) { // I wished the day stared at 0:00 for everybody
+ txt = TQString::number( d->h );
+ } else {
+ if ( d->h )
+ txt = TQString::number( d->h - 12 );
+ else
+ txt = "12";
+ }
+ break;
+ case 1:
+ txt = TQString::number( d->m );
+ break;
+ case 2:
+ txt = TQString::number( d->s );
+ break;
+ case 3:
+ if ( d->h < 12 ) {
+ if ( lAM )
+ txt = *lAM;
+ else
+ txt = TQString::tqfromLatin1( "AM" );
+ } else {
+ if ( lPM )
+ txt = *lPM;
+ else
+ txt = TQString::tqfromLatin1( "PM" );
+ }
+ break;
+ default:
+ break;
+ }
+ return txt;
+}
+
+
+/*! \internal
+ Returns TRUE if \a h, \a m, and \a s are out of range.
+ */
+
+bool TQTimeEdit::outOfRange( int h, int m, int s ) const
+{
+ if ( TQTime::isValid( h, m, s ) ) {
+ TQTime currentTime( h, m, s );
+ if ( currentTime > maxValue() ||
+ currentTime < minValue() )
+ return TRUE;
+ else
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*! \reimp
+
+*/
+
+void TQTimeEdit::addNumber( int sec, int num )
+{
+ if ( sec == -1 )
+ return;
+ sec = d->ed->mapSection( sec );
+ killTimer( d->timerId );
+ bool overwrite = FALSE;
+ bool accepted = FALSE;
+ d->typing = TRUE;
+ TQString txt;
+
+ switch( sec ) {
+ case 0:
+ txt = ( d->display & AMPM && d->h > 12 ) ?
+ TQString::number( d->h - 12 ) : TQString::number( d->h );
+
+ if ( d->overwrite || txt.length() == 2 ) {
+ if ( d->display & AMPM && num == 0 )
+ break; // Don't process 0 in 12 hour clock mode
+ if ( d->display & AMPM && d->h > 11 )
+ num += 12;
+ if ( !outOfRange( num, d->m, d->s ) ) {
+ accepted = TRUE;
+ d->h = num;
+ }
+ } else {
+ txt += TQString::number( num );
+ int temp = txt.toInt();
+
+ if ( d->display & AMPM ) {
+ if ( temp == 12 ) {
+ if ( d->h < 12 ) {
+ temp = 0;
+ }
+ accepted = TRUE;
+ } else if ( outOfRange( temp + 12, d->m, d->s ) ) {
+ txt = TQString::number( d->h );
+ } else {
+ if ( d->h > 11 ) {
+ temp += 12;
+ }
+ accepted = TRUE;
+ }
+ } else if ( !(d->display & AMPM) && outOfRange( temp, d->m, d->s ) ) {
+ txt = TQString::number( d->h );
+ } else {
+ accepted = TRUE;
+ }
+
+ if ( accepted )
+ d->h = temp;
+
+ if ( d->adv && txt.length() == 2 ) {
+ setFocusSection( d->ed->focusSection()+1 );
+ overwrite = TRUE;
+ }
+ }
+ break;
+
+ case 1:
+ txt = TQString::number( d->m );
+ if ( d->overwrite || txt.length() == 2 ) {
+ if ( !outOfRange( d->h, num, d->s ) ) {
+ accepted = TRUE;
+ d->m = num;
+ }
+ } else {
+ txt += TQString::number( num );
+ int temp = txt.toInt();
+ if ( temp > 59 )
+ temp = num;
+ if ( outOfRange( d->h, temp, d->s ) )
+ txt = TQString::number( d->m );
+ else {
+ accepted = TRUE;
+ d->m = temp;
+ }
+ if ( d->adv && txt.length() == 2 ) {
+ setFocusSection( d->ed->focusSection()+1 );
+ overwrite = TRUE;
+ }
+ }
+ break;
+
+ case 2:
+ txt = TQString::number( d->s );
+ if ( d->overwrite || txt.length() == 2 ) {
+ if ( !outOfRange( d->h, d->m, num ) ) {
+ accepted = TRUE;
+ d->s = num;
+ }
+ } else {
+ txt += TQString::number( num );
+ int temp = txt.toInt();
+ if ( temp > 59 )
+ temp = num;
+ if ( outOfRange( d->h, d->m, temp ) )
+ txt = TQString::number( d->s );
+ else {
+ accepted = TRUE;
+ d->s = temp;
+ }
+ if ( d->adv && txt.length() == 2 ) {
+ setFocusSection( d->ed->focusSection()+1 );
+ overwrite = TRUE;
+ }
+ }
+ break;
+
+ case 3:
+ break;
+
+ default:
+ break;
+ }
+ d->changed = !accepted;
+ if ( accepted )
+ emit valueChanged( time() );
+ d->overwrite = overwrite;
+ d->timerId = startTimer( tqApp->doubleClickInterval()*4 );
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+
+/*!
+ \internal
+
+ Function which is called whenever the user tries to
+ remove the first number from \a sec by pressing the backspace key.
+*/
+
+void TQTimeEdit::removeFirstNumber( int sec )
+{
+ if ( sec == -1 )
+ return;
+ sec = d->ed->mapSection( sec );
+ TQString txt;
+ switch( sec ) {
+ case 0:
+ txt = TQString::number( d->h );
+ break;
+ case 1:
+ txt = TQString::number( d->m );
+ break;
+ case 2:
+ txt = TQString::number( d->s );
+ break;
+ }
+ txt = txt.mid( 1, txt.length() ) + "0";
+ switch( sec ) {
+ case 0:
+ d->h = txt.toInt();
+ break;
+ case 1:
+ d->m = txt.toInt();
+ break;
+ case 2:
+ d->s = txt.toInt();
+ break;
+ }
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+/*! \reimp
+
+*/
+void TQTimeEdit::removeLastNumber( int sec )
+{
+ if ( sec == -1 )
+ return;
+ sec = d->ed->mapSection( sec );
+ TQString txt;
+ switch( sec ) {
+ case 0:
+ txt = TQString::number( d->h );
+ break;
+ case 1:
+ txt = TQString::number( d->m );
+ break;
+ case 2:
+ txt = TQString::number( d->s );
+ break;
+ }
+ txt = txt.mid( 0, txt.length()-1 );
+ switch( sec ) {
+ case 0:
+ d->h = txt.toInt();
+ break;
+ case 1:
+ d->m = txt.toInt();
+ break;
+ case 2:
+ d->s = txt.toInt();
+ break;
+ }
+ d->ed->tqrepaint( d->ed->rect(), FALSE );
+}
+
+/*! \reimp
+ */
+void TQTimeEdit::resizeEvent( TQResizeEvent * )
+{
+ d->controls->resize( width(), height() );
+}
+
+/*! \reimp
+*/
+TQSize TQTimeEdit::tqsizeHint() const
+{
+ constPolish();
+ TQFontMetrics fm( font() );
+ int fw = tqstyle().tqpixelMetric( TQStyle::PM_DefaultFrameWidth, this );
+ int h = fm.lineSpacing() + 2;
+ int w = 2 + fm.width( '9' ) * 6 + fm.width( d->ed->separator() ) * 2 +
+ d->controls->upRect().width() + fw * 4;
+ if ( d->display & AMPM ) {
+ if ( lAM )
+ w += fm.width( *lAM ) + 4;
+ else
+ w += fm.width( TQString::tqfromLatin1( "AM" ) ) + 4;
+ }
+
+ return TQSize( w, TQMAX(h + fw * 2,20) ).expandedTo( TQApplication::globalStrut() );
+}
+
+/*! \reimp
+*/
+TQSize TQTimeEdit::tqminimumSizeHint() const
+{
+ return tqsizeHint();
+}
+
+/*!
+ \internal
+ Enables/disables the push buttons according to the min/max time
+ for this widget.
+*/
+
+// ### Remove in 4.0?
+
+void TQTimeEdit::updateButtons()
+{
+ if ( !isEnabled() )
+ return;
+
+ bool upEnabled = time() < maxValue();
+ bool downEnabled = time() > minValue();
+
+ d->controls->setUpEnabled( upEnabled );
+ d->controls->setDownEnabled( downEnabled );
+}
+
+
+class TQDateTimeEditPrivate
+{
+public:
+ bool adv;
+};
+
+/*!
+ \class TQDateTimeEdit tqdatetimeedit.h
+ \brief The TQDateTimeEdit class combines a TQDateEdit and TQTimeEdit
+ widget into a single widget for editing datetimes.
+
+ \ingroup advanced
+ \ingroup time
+ \mainclass
+
+ TQDateTimeEdit consists of a TQDateEdit and TQTimeEdit widget placed
+ side by side and offers the functionality of both. The user can
+ edit the date and time by using the keyboard or the arrow keys to
+ increase/decrease date or time values. The Tab key can be used to
+ move from section to section within the TQDateTimeEdit widget, and
+ the user can be moved automatically when they complete a section
+ using setAutoAdvance(). The datetime can be set with
+ setDateTime().
+
+ The date format is read from the system's locale settings. It is
+ set to year, month, day order if that is not possible. See
+ TQDateEdit::setOrder() to change this. Times appear in the order
+ hours, minutes, seconds using the 24 hour clock.
+
+ It is recommended that the TQDateTimeEdit is initialised with a
+ datetime, e.g.
+ \code
+ TQDateTimeEdit *dateTimeEdit = new TQDateTimeEdit( TQDateTime::tqcurrentDateTime(), this );
+ dateTimeEdit->dateEdit()->setRange( TQDateTime::tqcurrentDate(),
+ TQDateTime::tqcurrentDate().addDays( 7 ) );
+ \endcode
+ Here we've created a new TQDateTimeEdit set to the current date and
+ time, and set the date to have a minimum date of now and a maximum
+ date of a week from now.
+
+ Terminology: A TQDateEdit widget consists of three 'sections', one
+ each for the year, month and day. Similarly a TQTimeEdit consists
+ of three sections, one each for the hour, minute and second. The
+ character that separates each date section is specified with
+ setDateSeparator(); similarly setTimeSeparator() is used for the
+ time sections.
+
+ \img datetimewidgets.png Date Time Widgets
+
+ \sa TQDateEdit TQTimeEdit
+*/
+
+/*!
+ Constructs an empty datetime edit with tqparent \a tqparent and called
+ \a name.
+*/
+TQDateTimeEdit::TQDateTimeEdit( TQWidget * tqparent, const char * name )
+ : TQWidget( tqparent, name )
+{
+ init();
+}
+
+
+/*!
+ \overload
+
+ Constructs a datetime edit with the initial value \a datetime,
+ tqparent \a tqparent and called \a name.
+*/
+TQDateTimeEdit::TQDateTimeEdit( const TQDateTime& datetime,
+ TQWidget * tqparent, const char * name )
+ : TQWidget( tqparent, name )
+{
+ init();
+ setDateTime( datetime );
+}
+
+
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQDateTimeEdit::~TQDateTimeEdit()
+{
+ delete d;
+}
+
+
+/*!
+ \reimp
+
+ Intercepts and handles resize events which have special meaning
+ for the TQDateTimeEdit.
+*/
+
+void TQDateTimeEdit::resizeEvent( TQResizeEvent * )
+{
+ int dw = de->tqsizeHint().width();
+ int tw = te->tqsizeHint().width();
+ int w = width();
+ int h = height();
+ int extra = w - ( dw + tw );
+
+ if ( tw + extra < 0 ) {
+ dw = w;
+ } else {
+ dw += 9 * extra / 16;
+ }
+ tw = w - dw;
+
+ de->setGeometry( 0, 0, dw, h );
+ te->setGeometry( dw, 0, tw, h );
+}
+
+/*! \reimp
+*/
+
+TQSize TQDateTimeEdit::tqminimumSizeHint() const
+{
+ TQSize dsh = de->tqminimumSizeHint();
+ TQSize tsh = te->tqminimumSizeHint();
+ return TQSize( dsh.width() + tsh.width(),
+ TQMAX( dsh.height(), tsh.height() ) );
+}
+
+/*! \internal
+ */
+
+void TQDateTimeEdit::init()
+{
+ d = new TQDateTimeEditPrivate();
+ de = new TQDateEdit( this, "qt_datetime_dateedit" );
+ te = new TQTimeEdit( this, "qt_datetime_timeedit" );
+ d->adv = FALSE;
+ connect( de, TQT_SIGNAL( valueChanged(const TQDate&) ),
+ this, TQT_SLOT( newValue(const TQDate&) ) );
+ connect( te, TQT_SIGNAL( valueChanged(const TQTime&) ),
+ this, TQT_SLOT( newValue(const TQTime&) ) );
+ setFocusProxy( de );
+ tqsetSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed );
+}
+
+/*! \reimp
+ */
+
+TQSize TQDateTimeEdit::tqsizeHint() const
+{
+ constPolish();
+ TQSize dsh = de->tqsizeHint();
+ TQSize tsh = te->tqsizeHint();
+ return TQSize( dsh.width() + tsh.width(),
+ TQMAX( dsh.height(), tsh.height() ) );
+}
+
+/*!
+ \property TQDateTimeEdit::dateTime
+ \brief the editor's datetime value
+
+ The datetime edit's datetime which may be an invalid datetime.
+*/
+
+void TQDateTimeEdit::setDateTime( const TQDateTime & dt )
+{
+ if ( dt.isValid() ) {
+ de->setDate( TQT_TQDATE_OBJECT(dt.date()) );
+ te->setTime( TQT_TQTIME_OBJECT(dt.time()) );
+ emit valueChanged( dt );
+ }
+}
+
+TQDateTime TQDateTimeEdit::dateTime() const
+{
+ return TQDateTime( de->date(), te->time() );
+}
+
+/*!
+ \fn void TQDateTimeEdit::valueChanged( const TQDateTime& datetime )
+
+ This signal is emitted every time the date or time changes. The \a
+ datetime argument is the new datetime.
+*/
+
+
+/*! \internal
+
+ Re-emits the value \a d.
+ */
+
+void TQDateTimeEdit::newValue( const TQDate& )
+{
+ TQDateTime dt = dateTime();
+ emit valueChanged( dt );
+}
+
+/*! \internal
+ \overload
+ Re-emits the value \a t.
+ */
+
+void TQDateTimeEdit::newValue( const TQTime& )
+{
+ TQDateTime dt = dateTime();
+ emit valueChanged( dt );
+}
+
+
+/*!
+ Sets the auto advance property of the editor to \a advance. If set
+ to TRUE, the editor will automatically advance focus to the next
+ date or time section if the user has completed a section.
+*/
+
+void TQDateTimeEdit::setAutoAdvance( bool advance )
+{
+ de->setAutoAdvance( advance );
+ te->setAutoAdvance( advance );
+}
+
+/*!
+ Returns TRUE if auto-advance is enabled, otherwise returns FALSE.
+
+ \sa setAutoAdvance()
+*/
+
+bool TQDateTimeEdit::autoAdvance() const
+{
+ return de->autoAdvance();
+}
+
+/*!
+ \fn TQDateEdit* TQDateTimeEdit::dateEdit()
+
+ Returns the internal widget used for editing the date part of the
+ datetime.
+*/
+
+/*!
+ \fn TQTimeEdit* TQDateTimeEdit::timeEdit()
+
+ Returns the internal widget used for editing the time part of the
+ datetime.
+*/
+
+#include "tqdatetimeedit.tqmoc"
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqdatetimeedit.h b/tqtinterface/qt4/src/widgets/tqdatetimeedit.h
new file mode 100644
index 0000000..ab59358
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqdatetimeedit.h
@@ -0,0 +1,299 @@
+/****************************************************************************
+**
+** Definition of date and time edit classes
+**
+** Created : 001103
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDATETIMEEDIT_H
+#define TQDATETIMEEDIT_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqstring.h"
+#include "tqdatetime.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_DATETIMEEDIT
+
+class TQ_EXPORT TQDateTimeEditBase : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQDateTimeEditBase( TQWidget* tqparent=0, const char* name=0 )
+ : TQWidget( tqparent, name ) {}
+
+ virtual bool setFocusSection( int sec ) = 0;
+ virtual TQString sectionFormattedText( int sec ) = 0;
+ virtual void addNumber( int sec, int num ) = 0;
+ virtual void removeLastNumber( int sec ) = 0;
+
+public Q_SLOTS:
+ virtual void stepUp() = 0;
+ virtual void stepDown() = 0;
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQDateTimeEditBase( const TQDateTimeEditBase & );
+ TQDateTimeEditBase &operator=( const TQDateTimeEditBase & );
+#endif
+};
+
+class TQDateEditPrivate;
+
+class TQ_EXPORT TQDateEdit : public TQDateTimeEditBase
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_ENUMS( Order )
+ Q_PROPERTY( Order order READ order WRITE setOrder )
+ Q_PROPERTY( TQDate date READ date WRITE setDate )
+ Q_PROPERTY( bool autoAdvance READ autoAdvance WRITE setAutoAdvance )
+ Q_PROPERTY( TQDate maxValue READ maxValue WRITE setMaxValue )
+ Q_PROPERTY( TQDate minValue READ minValue WRITE setMinValue )
+
+public:
+ TQDateEdit( TQWidget* tqparent=0, const char* name=0 );
+ TQDateEdit( const QDate& date, QWidget* tqparent=0, const char* name=0 );
+ ~TQDateEdit();
+
+ enum Order { DMY, MDY, YMD, YDM };
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+public Q_SLOTS:
+ virtual void setDate( const TQDate& date );
+
+public:
+ TQDate date() const;
+ virtual void setOrder( Order order );
+ Order order() const;
+ virtual void setAutoAdvance( bool advance );
+ bool autoAdvance() const;
+
+ virtual void setMinValue( const TQDate& d ) { setRange( d, maxValue() ); }
+ TQDate minValue() const;
+ virtual void setMaxValue( const TQDate& d ) { setRange( minValue(), d ); }
+ TQDate maxValue() const;
+ virtual void setRange( const TQDate& min, const TQDate& max );
+ TQString separator() const;
+ virtual void setSeparator( const TQString& s );
+
+ // Make removeFirstNumber() virtual in TQDateTimeEditBase in 4.0
+ void removeFirstNumber( int sec );
+
+Q_SIGNALS:
+ void valueChanged( const TQDate& date );
+
+protected:
+ bool event( TQEvent *e );
+ void timerEvent( TQTimerEvent * );
+ void resizeEvent( TQResizeEvent * );
+ void stepUp();
+ void stepDown();
+ TQString sectionFormattedText( int sec );
+ void addNumber( int sec, int num );
+
+ void removeLastNumber( int sec );
+ bool setFocusSection( int s );
+
+ virtual void setYear( int year );
+ virtual void setMonth( int month );
+ virtual void setDay( int day );
+ virtual void fix();
+ virtual bool outOfRange( int y, int m, int d ) const;
+
+protected Q_SLOTS:
+ void updateButtons();
+
+private:
+ void init();
+ int sectionOffsetEnd( int sec ) const;
+ int sectionLength( int sec ) const;
+ TQString sectionText( int sec ) const;
+ TQDateEditPrivate* d;
+
+#if defined(TQ_DISABLE_COPY)
+ TQDateEdit( const TQDateEdit & );
+ TQDateEdit &operator=( const TQDateEdit & );
+#endif
+};
+
+class TQTimeEditPrivate;
+
+class TQ_EXPORT TQTimeEdit : public TQDateTimeEditBase
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_ENUMS( Display )
+ Q_PROPERTY( TQTime time READ time WRITE setTime )
+ Q_PROPERTY( bool autoAdvance READ autoAdvance WRITE setAutoAdvance )
+ Q_PROPERTY( TQTime maxValue READ maxValue WRITE setMaxValue )
+ Q_PROPERTY( TQTime minValue READ minValue WRITE setMinValue )
+ Q_PROPERTY( Display display READ displayProp WRITE setDisplayProp )
+
+public:
+ enum Display {
+ Hours = 0x01,
+ Minutes = 0x02,
+ Seconds = 0x04,
+ /*Reserved = 0x08,*/
+ AMPM = 0x10
+ };
+
+ TQTimeEdit( TQWidget* tqparent=0, const char* name=0 );
+ TQTimeEdit( const QTime& time, QWidget* tqparent=0, const char* name=0 );
+ ~TQTimeEdit();
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+public Q_SLOTS:
+ virtual void setTime( const TQTime& time );
+
+public:
+ TQTime time() const;
+ virtual void setAutoAdvance( bool advance );
+ bool autoAdvance() const;
+
+ virtual void setMinValue( const TQTime& d ) { setRange( d, maxValue() ); }
+ TQTime minValue() const;
+ virtual void setMaxValue( const TQTime& d ) { setRange( minValue(), d ); }
+ TQTime maxValue() const;
+ virtual void setRange( const TQTime& min, const TQTime& max );
+ TQString separator() const;
+ virtual void setSeparator( const TQString& s );
+
+ uint display() const;
+ void setDisplay( uint disp );
+ inline Display displayProp() const { return (Display)display(); }
+ inline void setDisplayProp( Display disp ) { setDisplay((uint)disp); }
+
+ // Make removeFirstNumber() virtual in TQDateTimeEditBase in 4.0
+ void removeFirstNumber( int sec );
+
+Q_SIGNALS:
+ void valueChanged( const TQTime& time );
+
+protected:
+ bool event( TQEvent *e );
+ void timerEvent( TQTimerEvent *e );
+ void resizeEvent( TQResizeEvent * );
+ void stepUp();
+ void stepDown();
+ TQString sectionFormattedText( int sec );
+ void addNumber( int sec, int num );
+ void removeLastNumber( int sec );
+ bool setFocusSection( int s );
+
+ virtual bool outOfRange( int h, int m, int s ) const;
+ virtual void setHour( int h );
+ virtual void setMinute( int m );
+ virtual void setSecond( int s );
+
+protected Q_SLOTS:
+ void updateButtons();
+
+private:
+ void init();
+ TQString sectionText( int sec );
+ TQTimeEditPrivate* d;
+
+#if defined(TQ_DISABLE_COPY)
+ TQTimeEdit( const TQTimeEdit & );
+ TQTimeEdit &operator=( const TQTimeEdit & );
+#endif
+};
+
+
+class TQDateTimeEditPrivate;
+
+class TQ_EXPORT TQDateTimeEdit : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( TQDateTime dateTime READ dateTime WRITE setDateTime )
+
+public:
+ TQDateTimeEdit( TQWidget* tqparent=0, const char* name=0 );
+ TQDateTimeEdit( const TQDateTime& datetime, TQWidget* tqparent=0,
+ const char* name=0 );
+ ~TQDateTimeEdit();
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+public Q_SLOTS:
+ virtual void setDateTime( const TQDateTime & dt );
+
+public:
+ TQDateTime dateTime() const;
+
+ TQDateEdit* dateEdit() { return de; }
+ TQTimeEdit* timeEdit() { return te; }
+
+ virtual void setAutoAdvance( bool advance );
+ bool autoAdvance() const;
+
+Q_SIGNALS:
+ void valueChanged( const TQDateTime& datetime );
+
+protected:
+ // ### make init() private in TQt 4.0
+ void init();
+ void resizeEvent( TQResizeEvent * );
+
+protected Q_SLOTS:
+ // ### make these two functions private in TQt 4.0,
+ // and merge them into one with no parameter
+ void newValue( const TQDate& d );
+ void newValue( const TQTime& t );
+
+private:
+ TQDateEdit* de;
+ TQTimeEdit* te;
+ TQDateTimeEditPrivate* d;
+
+#if defined(TQ_DISABLE_COPY)
+ TQDateTimeEdit( const TQDateTimeEdit & );
+ TQDateTimeEdit &operator=( const TQDateTimeEdit & );
+#endif
+};
+
+#endif
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqdial.cpp b/tqtinterface/qt4/src/widgets/tqdial.cpp
new file mode 100644
index 0000000..5b9601b
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqdial.cpp
@@ -0,0 +1,976 @@
+/****************************************************************************
+**
+** Implementation of the dial widget
+**
+** Created : 979899
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdial.h"
+
+#ifndef TQT_NO_DIAL
+
+#include "tqpainter.h"
+#include "tqpointarray.h"
+#include "tqcolor.h"
+#include "tqapplication.h"
+#include "tqregion.h"
+#include "tqbitmap.h"
+#include "tqstyle.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+#include <math.h> // sin(), cos(), atan()
+//### Forutsetter linking med math lib - Jfr kommentar i qpainter_x11.cpp!
+
+static const double m_pi = 3.14159265358979323846;
+static const double rad_factor = 180.0 / m_pi;
+
+
+class TQDialPrivate
+{
+public:
+ TQDialPrivate()
+ {
+ wrapping = FALSE;
+ tracking = TRUE;
+ doNotEmit = FALSE;
+ target = 3.7;
+ mousePressed = FALSE;
+ }
+
+ bool wrapping;
+ bool tracking;
+ bool doNotEmit;
+ double target;
+ TQRect eraseArea;
+ bool eraseAreaValid;
+ bool showNotches;
+ bool onlyOutside;
+ bool mousePressed;
+
+ TQPointArray lines;
+};
+
+
+/*!
+ \class TQDial tqdial.h
+
+ \brief The TQDial class provides a rounded range control (like a speedometer or potentiometer).
+
+ \ingroup basic
+ \mainclass
+
+ TQDial is used when the user needs to control a value within a
+ program-definable range, and the range either wraps around
+ (typically, 0..359 degrees) or the dialog tqlayout needs a square
+ widget.
+
+ Both API- and UI-wise, the dial is very similar to a \link TQSlider
+ slider. \endlink Indeed, when wrapping() is FALSE (the default)
+ there is no real difference between a slider and a dial. They
+ have the same Q_SIGNALS, Q_SLOTS and member functions, all of which do
+ the same things. Which one you use depends only on your taste
+ and on the application.
+
+ The dial initially emits valueChanged() Q_SIGNALS continuously while
+ the slider is being moved; you can make it emit the signal less
+ often by calling setTracking(FALSE). dialMoved() is emitted
+ continuously even when tracking() is FALSE.
+
+ The slider also emits dialPressed() and dialReleased() Q_SIGNALS
+ when the mouse button is pressed and released. But note that the
+ dial's value can change without these Q_SIGNALS being emitted; the
+ keyboard and wheel can be used to change the value.
+
+ Unlike the slider, TQDial attempts to draw a "nice" number of
+ notches rather than one per lineStep(). If possible, the number
+ of notches drawn is one per lineStep(), but if there aren't enough
+ pixels to draw every one, TQDial will draw every second, third
+ etc., notch. notchSize() returns the number of units per notch,
+ hopefully a multiple of lineStep(); setNotchTarget() sets the
+ target distance between neighbouring notches in pixels. The
+ default is 3.75 pixels.
+
+ Like the slider, the dial makes the TQRangeControl functions
+ setValue(), addLine(), subtractLine(), addPage() and
+ subtractPage() available as Q_SLOTS.
+
+ The dial's keyboard interface is fairly simple: The left/up and
+ right/down arrow keys move by lineStep(), page up and page down by
+ pageStep() and Home and End to minValue() and maxValue().
+
+ <img src=qdial-m.png> <img src=qdial-w.png>
+
+ \sa TQScrollBar TQSpinBox
+ \link guibooks.html#fowler GUI Design Handbook: Slider\endlink
+*/
+
+
+
+
+/*!
+ Constructs a dial called \a name with tqparent \a tqparent. \a f is
+ propagated to the TQWidget constructor. It has the default range of
+ a TQRangeControl.
+*/
+
+TQDial::TQDial( TQWidget *tqparent, const char *name, WFlags f )
+ : TQWidget( tqparent, name, f | TQt::WNoAutoErase ), TQRangeControl()
+{
+ d = new TQDialPrivate;
+ d->eraseAreaValid = FALSE;
+ d->showNotches = FALSE;
+ d->onlyOutside = FALSE;
+ setFocusPolicy( Qt::WheelFocus );
+}
+
+
+
+/*!
+ Constructs a dial called \a name with tqparent \a tqparent. The dial's
+ value can never be smaller than \a minValue or greater than \a
+ maxValue. Its page step size is \a pageStep, and its initial value
+ is \a value.
+
+ \a value is forced to be within the legal range.
+*/
+
+TQDial::TQDial( int minValue, int maxValue, int pageStep, int value,
+ TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name, TQt::WNoAutoErase ),
+ TQRangeControl( minValue, maxValue, 1, pageStep, value )
+{
+ d = new TQDialPrivate;
+ d->eraseAreaValid = FALSE;
+ d->showNotches = FALSE;
+ d->onlyOutside = FALSE;
+ setFocusPolicy( Qt::WheelFocus );
+}
+
+/*!
+ Destroys the dial.
+*/
+TQDial::~TQDial()
+{
+ delete d;
+}
+
+
+void TQDial::setTracking( bool enable )
+{
+ d->tracking = enable;
+}
+
+
+/*!
+ \property TQDial::tracking
+ \brief whether tracking is enabled
+
+ If TRUE (the default), tracking is enabled. This means that the
+ arrow can be moved using the mouse; otherwise the arrow cannot be
+ moved with the mouse.
+*/
+
+bool TQDial::tracking() const
+{
+ return d ? d->tracking : TRUE;
+}
+
+void TQDial::setValue( int newValue )
+{ // ### set doNotEmit? Matthias?
+ TQRangeControl::setValue( newValue );
+}
+
+
+/*!
+ Increments the dial's value() by one lineStep().
+*/
+
+void TQDial::addLine()
+{
+ TQRangeControl::addLine();
+}
+
+
+/*!
+ Decrements the dial's value() by one lineStep().
+*/
+
+void TQDial::subtractLine()
+{
+ TQRangeControl::subtractLine();
+}
+
+
+/*! \reimp */
+
+void TQDial::resizeEvent( TQResizeEvent * e )
+{
+ d->lines.resize( 0 );
+ TQWidget::resizeEvent( e );
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQDial::paintEvent( TQPaintEvent * e )
+{
+ repaintScreen( &e->rect() );
+}
+
+/*!
+ Paints the dial using clip region \a cr.
+*/
+
+void TQDial::repaintScreen( const TQRect *cr )
+{
+ TQPainter p;
+ p.begin( this );
+
+ bool resetClipping = FALSE;
+
+ // calculate clip-region for erasing background
+ if ( cr ) {
+ p.setClipRect( *cr );
+ } else if ( !d->onlyOutside && d->eraseAreaValid ) {
+ TQRegion reg = d->eraseArea;
+ double a;
+ reg = reg.subtract( calcArrow( a ) );
+ p.setClipRegion( reg );
+ resetClipping = TRUE;
+ }
+
+ TQRect br( calcDial() );
+ p.setPen( Qt::NoPen );
+ // if ( style() == MotifStyle )
+ // p.setBrush( tqcolorGroup().brush( TQColorGroup::Mid ) );
+ // else {
+ TQBrush b;
+ if ( TQT_TQBRUSH_OBJECT(tqcolorGroup().brush( TQColorGroup::Light )).pixmap() )
+ b = TQBrush( tqcolorGroup().brush( TQColorGroup::Light ) );
+ else
+ b = TQBrush( tqcolorGroup().light(), Qt::Dense4Pattern );
+ p.setBrush( b );
+ p.setBackgroundMode( Qt::OpaqueMode );
+ // }
+
+ TQRect te = br;
+ te.setWidth(te.width()+2);
+ te.setHeight(te.height()+2);
+ // erase background of dial
+ if ( !d->onlyOutside ) {
+ p.drawEllipse( te );
+ }
+
+ // erase remaining space around the dial
+ TQRegion remaining( 0, 0, width(), height() );
+ remaining = remaining.subtract( TQRegion( te, TQRegion::Ellipse ) );
+ if ( p.hasClipping() )
+ remaining = remaining.intersect( p.clipRegion() );
+ erase(remaining);
+
+ if ( resetClipping ) {
+ if ( cr )
+ p.setClipRect( *cr );
+ else
+ p.setClipRect( TQRect( 0, 0, width(), height() ) );
+ }
+
+ // draw notches
+ if ( d->showNotches ) {
+ calcLines();
+ p.setPen( tqcolorGroup().foreground() );
+ p.drawLineSegments( d->lines );
+ }
+
+ // calculate and paint arrow
+ p.setPen( TQPen( tqcolorGroup().dark() ) );
+ p.drawArc( te, 60 * 16, 180 * 16 );
+ p.setPen( TQPen( tqcolorGroup().light() ) );
+ p.drawArc( te, 240 * 16, 180 * 16 );
+
+ double a;
+ TQPointArray arrow( calcArrow( a ) );
+ TQRect ea( arrow.boundingRect() );
+ d->eraseArea = ea;
+ d->eraseAreaValid = TRUE;
+
+ p.setPen( Qt::NoPen );
+ p.setBrush( tqcolorGroup().brush( TQColorGroup::Button ) );
+ if ( !d->onlyOutside )
+ p.drawPolygon( arrow );
+
+ a = angle( TQPoint( width() / 2, height() / 2 ), arrow[ 0 ] );
+ p.setBrush( TQt::NoBrush );
+
+ // that's still a hack...
+ if ( a <= 0 || a > 200 ) {
+ p.setPen( tqcolorGroup().light() );
+ p.drawLine( arrow[ 2 ], arrow[ 0 ] );
+ p.drawLine( arrow[ 1 ], arrow[ 2 ] );
+ p.setPen( tqcolorGroup().dark() );
+ p.drawLine( arrow[ 0 ], arrow[ 1 ] );
+ } else if ( a > 0 && a < 45 ) {
+ p.setPen( tqcolorGroup().light() );
+ p.drawLine( arrow[ 2 ], arrow[ 0 ] );
+ p.setPen( tqcolorGroup().dark() );
+ p.drawLine( arrow[ 1 ], arrow[ 2 ] );
+ p.drawLine( arrow[ 0 ], arrow[ 1 ] );
+ } else if ( a >= 45 && a < 135 ) {
+ p.setPen( tqcolorGroup().dark() );
+ p.drawLine( arrow[ 2 ], arrow[ 0 ] );
+ p.drawLine( arrow[ 1 ], arrow[ 2 ] );
+ p.setPen( tqcolorGroup().light() );
+ p.drawLine( arrow[ 0 ], arrow[ 1 ] );
+ } else if ( a >= 135 && a < 200 ) {
+ p.setPen( tqcolorGroup().dark() );
+ p.drawLine( arrow[ 2 ], arrow[ 0 ] );
+ p.setPen( tqcolorGroup().light() );
+ p.drawLine( arrow[ 0 ], arrow[ 1 ] );
+ p.drawLine( arrow[ 1 ], arrow[ 2 ] );
+ }
+
+ // draw focus rect around the dial
+ if ( hasFocus() ) {
+ p.setClipping( FALSE );
+ br.setWidth( br.width() + 2 );
+ br.setHeight( br.height() + 2 );
+ if ( d->showNotches ) {
+ int r = TQMIN( width(), height() ) / 2;
+ br.moveBy( -r / 6, - r / 6 );
+ br.setWidth( br.width() + r / 3 );
+ br.setHeight( br.height() + r / 3 );
+ }
+ // strange, but else we get redraw errors on Windows
+ p.end();
+ p.begin( this );
+ p.save();
+ p.setPen( TQPen( tqcolorGroup().background() ) );
+ p.setBrush( Qt::NoBrush );
+ p.drawRect( br );
+ p.restore();
+ tqstyle().tqdrawPrimitive( TQStyle::PE_FocusRect, &p, br, tqcolorGroup());
+ }
+ p.end();
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQDial::keyPressEvent( TQKeyEvent * e )
+{
+ switch ( e->key() ) {
+ case Qt::Key_Left: case Qt::Key_Down:
+ subtractLine();
+ break;
+ case Qt::Key_Right: case Qt::Key_Up:
+ addLine();
+ break;
+ case TQt::Key_Prior:
+ subtractPage();
+ break;
+ case TQt::Key_Next:
+ addPage();
+ break;
+ case Qt::Key_Home:
+ setValue( minValue() );
+ break;
+ case Qt::Key_End:
+ setValue( maxValue() );
+ break;
+ default:
+ e->ignore();
+ break;
+ }
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQDial::mousePressEvent( TQMouseEvent * e )
+{
+ d->mousePressed = TRUE;
+ setValue( valueFromPoint( e->pos() ) );
+ emit dialPressed();
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQDial::mouseReleaseEvent( TQMouseEvent * e )
+{
+ d->mousePressed = FALSE;
+ setValue( valueFromPoint( e->pos() ) );
+ emit dialReleased();
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQDial::mouseMoveEvent( TQMouseEvent * e )
+{
+ if ( !d->mousePressed )
+ return;
+ if ( !d->tracking || (e->state() & Qt::LeftButton) == 0 )
+ return;
+ d->doNotEmit = TRUE;
+ setValue( valueFromPoint( e->pos() ) );
+ emit dialMoved( value() );
+ d->doNotEmit = FALSE;
+}
+
+
+/*!
+ \reimp
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQDial::wheelEvent( TQWheelEvent *e )
+{
+ setValue( value() - e->delta() / 120 );
+}
+#endif
+
+/*!
+ \reimp
+*/
+
+void TQDial::focusInEvent( TQFocusEvent * )
+{
+ d->onlyOutside = TRUE;
+ repaintScreen();
+ d->onlyOutside = FALSE;
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQDial::focusOutEvent( TQFocusEvent * )
+{
+ d->onlyOutside = TRUE;
+ repaintScreen();
+ d->onlyOutside = FALSE;
+}
+
+/*!
+ Reimplemented to ensure the display is correct and to emit the
+ valueChanged(int) signal when appropriate.
+*/
+
+void TQDial::valueChange()
+{
+ d->lines.resize( 0 );
+ repaintScreen();
+ if ( d->tracking || !d->doNotEmit ) {
+ emit valueChanged( value() );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+ }
+}
+
+
+/*!
+ Reimplemented to ensure tick-marks are consistent with the new range.
+*/
+
+void TQDial::rangeChange()
+{
+ d->lines.resize( 0 );
+ repaintScreen();
+}
+
+
+/*!
+ \internal
+*/
+
+int TQDial::valueFromPoint( const TQPoint & p ) const
+{
+ double yy = (double)height()/2.0 - p.y();
+ double xx = (double)p.x() - width()/2.0;
+ double a = (xx || yy) ? atan2(yy, xx) : 0;
+
+ if ( a < m_pi/-2 )
+ a = a + m_pi*2;
+
+ int dist = 0;
+ int minv = minValue(), maxv = maxValue();
+
+ if ( minValue() < 0 ) {
+ dist = -minValue();
+ minv = 0;
+ maxv = maxValue() + dist;
+ }
+
+ int r = maxv - minv;
+ int v;
+ if ( d->wrapping )
+ v = (int)(0.5 + minv + r*(m_pi*3/2-a)/(2*m_pi));
+ else
+ v = (int)(0.5 + minv + r*(m_pi*4/3-a)/(m_pi*10/6));
+
+ if ( dist > 0 )
+ v -= dist;
+
+ return bound( v );
+}
+
+
+/*!
+ \internal
+*/
+
+double TQDial::angle( const TQPoint &p1, const TQPoint &p2 ) const
+{
+ double _angle = 0.0;
+
+ if ( p1.x() == p2.x() ) {
+ if ( p1.y() < p2.y() )
+ _angle = 270.0;
+ else
+ _angle = 90.0;
+ } else {
+ double x1, x2, y1, y2;
+
+ if ( p1.x() <= p2.x() ) {
+ x1 = p1.x(); y1 = p1.y();
+ x2 = p2.x(); y2 = p2.y();
+ } else {
+ x2 = p1.x(); y2 = p1.y();
+ x1 = p2.x(); y1 = p2.y();
+ }
+
+ double m = -( y2 - y1 ) / ( x2 - x1 );
+ _angle = atan( m ) * rad_factor;
+
+ if ( p1.x() < p2.x() )
+ _angle = 180.0 - _angle;
+ else
+ _angle = -_angle;
+ }
+
+ return _angle;
+}
+
+void TQDial::setWrapping( bool enable )
+{
+ if ( d->wrapping == enable )
+ return;
+ d->lines.resize( 0 );
+ d->wrapping = enable;
+ d->eraseAreaValid = FALSE;
+ repaintScreen();
+}
+
+
+/*!
+ \property TQDial::wrapping
+ \brief whether wrapping is enabled
+
+ If TRUE, wrapping is enabled. This means that the arrow can be
+ turned around 360�. Otherwise there is some space at the bottom of
+ the dial which is skipped by the arrow.
+
+ This property's default is FALSE.
+*/
+
+bool TQDial::wrapping() const
+{
+ return d->wrapping;
+}
+
+
+/*!
+ \property TQDial::notchSize
+ \brief the current notch size
+
+ The notch size is in range control units, not pixels, and if
+ possible it is a multiple of lineStep() that results in an
+ on-screen notch size near notchTarget().
+
+ \sa notchTarget() lineStep()
+*/
+
+int TQDial::notchSize() const
+{
+ // radius of the arc
+ int r = TQMIN( width(), height() )/2;
+ // length of the whole arc
+ int l = (int)(r*(d->wrapping ? 6 : 5)*m_pi/6);
+ // length of the arc from minValue() to minValue()+pageStep()
+ if ( maxValue() > minValue()+pageStep() )
+ l = (int)(0.5 + l * pageStep() / (maxValue()-minValue()));
+ // length of a lineStep() arc
+ l = l * lineStep() / pageStep();
+ if ( l < 1 )
+ l = 1;
+ // how many times lineStep can be draw in d->target pixels
+ l = (int)(0.5 + d->target / l);
+ // we want notchSize() to be a non-zero multiple of lineStep()
+ if ( !l )
+ l = 1;
+ return lineStep() * l;
+}
+
+void TQDial::setNotchTarget( double target )
+{
+ d->lines.resize( 0 );
+ d->target = target;
+ d->eraseAreaValid = FALSE;
+ d->onlyOutside = TRUE;
+ repaintScreen();
+ d->onlyOutside = FALSE;
+}
+
+
+/*!
+ \property TQDial::notchTarget
+ \brief the target number of pixels between notches
+
+ The notch target is the number of pixels TQDial attempts to put
+ between each notch.
+
+ The actual size may differ from the target size.
+*/
+
+double TQDial::notchTarget() const
+{
+ return d->target;
+}
+
+
+/*!
+ Increments the dial's value() by one pageStep() of steps.
+*/
+
+void TQDial::addPage()
+{
+ TQRangeControl::addPage();
+}
+
+
+/*!
+ Decrements the dial's value() by one pageStep() of steps.
+*/
+
+void TQDial::subtractPage()
+{
+ TQRangeControl::subtractPage();
+}
+
+
+/*!
+ \fn void TQDial::valueChanged( int value )
+
+ This signal is emitted whenever the dial's \a value changes. The
+ frequency of this signal is influenced by setTracking().
+*/
+
+/*!
+ \fn void TQDial::dialPressed()
+
+ This signal is emitted when the user begins mouse interaction with
+ the dial.
+
+ \sa dialReleased()
+*/
+
+/*!
+ \fn void TQDial::dialMoved( int value )
+
+ This signal is emitted whenever the dial \a value changes. The
+ frequency of this signal is \e not influenced by setTracking().
+
+ \sa valueChanged()
+*/
+
+/*!
+ \fn void TQDial::dialReleased()
+
+ This signal is emitted when the user ends mouse interaction with
+ the dial.
+
+ \sa dialPressed()
+*/
+
+void TQDial::setNotchesVisible( bool b )
+{
+ d->showNotches = b;
+ d->eraseAreaValid = FALSE;
+ d->onlyOutside = TRUE;
+ repaintScreen();
+ d->onlyOutside = FALSE;
+}
+
+/*!
+ \property TQDial::notchesVisible
+ \brief whether the notches are shown
+
+ If TRUE, the notches are shown. If FALSE (the default) notches are
+ not shown.
+*/
+bool TQDial::notchesVisible() const
+{
+ return d->showNotches;
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQDial::tqminimumSizeHint() const
+{
+ return TQSize( 50, 50 );
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQDial::tqsizeHint() const
+{
+ return TQSize( 100, 100 ).expandedTo( TQApplication::globalStrut() );
+}
+
+
+
+/*!
+ \internal
+*/
+
+TQPointArray TQDial::calcArrow( double &a ) const
+{
+ int r = TQMIN( width(), height() ) / 2;
+ if ( maxValue() == minValue() )
+ a = m_pi / 2;
+ else if ( d->wrapping )
+ a = m_pi * 3 / 2 - ( value() - minValue() ) * 2 * m_pi / ( maxValue() - minValue() );
+ else
+ a = ( m_pi * 8 - ( value() - minValue() ) * 10 * m_pi / ( maxValue() - minValue() ) ) / 6;
+
+ int xc = width() / 2;
+ int yc = height() / 2;
+
+ int len = r - calcBigLineSize() - 5;
+ if ( len < 5 )
+ len = 5;
+ int back = len / 4;
+ if ( back < 1 )
+ back = 1;
+
+ TQPointArray arrow( 3 );
+ arrow[0] = TQPoint( (int)( 0.5 + xc + len * cos(a) ),
+ (int)( 0.5 + yc -len * sin( a ) ) );
+ arrow[1] = TQPoint( (int)( 0.5 + xc + back * cos( a + m_pi * 5 / 6 ) ),
+ (int)( 0.5 + yc - back * sin( a + m_pi * 5 / 6 ) ) );
+ arrow[2] = TQPoint( (int)( 0.5 + xc + back * cos( a - m_pi * 5 / 6 ) ),
+ (int)( 0.5 + yc - back * sin( a - m_pi * 5 / 6 ) ) );
+ return arrow;
+}
+
+/*!
+ \internal
+*/
+
+TQRect TQDial::calcDial() const
+{
+ double r = TQMIN( width(), height() ) / 2.0;
+ double d_ = r / 6.0;
+ double dx = d_ + ( width() - 2 * r ) / 2.0 + 1;
+ double dy = d_ + ( height() - 2 * r ) / 2.0 + 1;
+ return TQRect( int(dx), int(dy),
+ int(r * 2 - 2 * d_ - 2), int(r * 2 - 2 * d_ - 2) );
+}
+
+/*!
+ \internal
+*/
+
+int TQDial::calcBigLineSize() const
+{
+ int r = TQMIN( width(), height() ) / 2;
+ int bigLineSize = r / 6;
+ if ( bigLineSize < 4 )
+ bigLineSize = 4;
+ if ( bigLineSize > r / 2 )
+ bigLineSize = r / 2;
+ return bigLineSize;
+}
+
+/*!
+ \internal
+*/
+
+void TQDial::calcLines()
+{
+ if ( !d->lines.size() ) {
+ double r = TQMIN( width(), height() ) / 2.0;
+ int bigLineSize = calcBigLineSize();
+ double xc = width() / 2.0;
+ double yc = height() / 2.0;
+ int ns = notchSize();
+ int notches = ( maxValue() + ns - 1 - minValue() ) / ns;
+ d->lines.resize( 2 + 2 * notches );
+ int smallLineSize = bigLineSize / 2;
+ int i;
+ for( i = 0; i <= notches; i++ ) {
+ double angle = d->wrapping
+ ? m_pi * 3 / 2 - i * 2 * m_pi / notches
+ : (m_pi * 8 - i * 10 * m_pi / notches) / 6;
+
+ double s = sin( angle ); // sin/cos aren't defined as const...
+ double c = cos( angle );
+ if ( i == 0 || ( ((ns * i ) % pageStep() ) == 0 ) ) {
+ d->lines[2*i] = TQPoint( (int)( xc + ( r - bigLineSize ) * c ),
+ (int)( yc - ( r - bigLineSize ) * s ) );
+ d->lines[2*i+1] = TQPoint( (int)( xc + r * c ),
+ (int)( yc - r * s ) );
+ } else {
+ d->lines[2*i] = TQPoint( (int)( xc + ( r - 1 - smallLineSize ) * c ),
+ (int)( yc - ( r - 1 - smallLineSize ) * s ) );
+ d->lines[2*i+1] = TQPoint( (int)( xc + ( r - 1 ) * c ),
+ (int)( yc -( r - 1 ) * s ) );
+ }
+ }
+ }
+}
+
+/*!
+ \property TQDial::minValue
+ \brief the current minimum value
+
+ When setting this property, the \l TQDial::maxValue is adjusted if
+ necessary to ensure that the range remains valid.
+
+ \sa setRange()
+*/
+int TQDial::minValue() const
+{
+ return TQRangeControl::minValue();
+}
+
+/*!
+ \property TQDial::maxValue
+ \brief the current maximum value
+
+ When setting this property, the \l TQDial::minValue is adjusted if
+ necessary to ensure that the range remains valid.
+
+ \sa setRange()
+*/
+int TQDial::maxValue() const
+{
+ return TQRangeControl::maxValue();
+}
+
+void TQDial::setMinValue( int minVal )
+{
+ TQRangeControl::setMinValue( minVal );
+}
+
+void TQDial::setMaxValue( int maxVal )
+{
+ TQRangeControl::setMaxValue( maxVal );
+}
+
+/*!
+ \property TQDial::lineStep
+ \brief the current line step
+
+ setLineStep() calls the virtual stepChange() function if the new
+ line step is different from the previous setting.
+
+ \sa TQRangeControl::setSteps() pageStep setRange()
+*/
+
+int TQDial::lineStep() const
+{
+ return TQRangeControl::lineStep();
+}
+
+/*!
+ \property TQDial::pageStep
+ \brief the current page step
+
+ setPageStep() calls the virtual stepChange() function if the new
+ page step is different from the previous setting.
+
+ \sa stepChange()
+*/
+int TQDial::pageStep() const
+{
+ return TQRangeControl::pageStep();
+}
+
+void TQDial::setLineStep( int i )
+{
+ setSteps( i, pageStep() );
+}
+
+void TQDial::setPageStep( int i )
+{
+ setSteps( lineStep(), i );
+}
+
+/*!
+ \property TQDial::value
+ \brief the current dial value
+
+ This is guaranteed to be within the range
+ \l{TQDial::minValue}..\l{TQDial::maxValue}.
+
+ \sa minValue maxValue
+*/
+
+int TQDial::value() const
+{
+ return TQRangeControl::value();
+}
+
+#endif // TQT_FEATURE_DIAL
diff --git a/tqtinterface/qt4/src/widgets/tqdial.h b/tqtinterface/qt4/src/widgets/tqdial.h
new file mode 100644
index 0000000..d7cfcad
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqdial.h
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Definition of the dial widget
+**
+** Created : 990104
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+
+#ifndef TQDIAL_H
+#define TQDIAL_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqrangecontrol.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_DIAL
+
+class TQDialPrivate;
+
+class TQ_EXPORT TQDial: public TQWidget, public TQRangeControl
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool tracking READ tracking WRITE setTracking )
+ Q_PROPERTY( bool wrapping READ wrapping WRITE setWrapping )
+ Q_PROPERTY( int notchSize READ notchSize )
+ Q_PROPERTY( double notchTarget READ notchTarget WRITE setNotchTarget )
+ Q_PROPERTY( bool notchesVisible READ notchesVisible WRITE setNotchesVisible )
+ Q_PROPERTY( int minValue READ minValue WRITE setMinValue )
+ Q_PROPERTY( int maxValue READ maxValue WRITE setMaxValue )
+ Q_PROPERTY( int lineStep READ lineStep WRITE setLineStep )
+ Q_PROPERTY( int pageStep READ pageStep WRITE setPageStep )
+ Q_PROPERTY( int value READ value WRITE setValue )
+
+public:
+ TQDial( TQWidget* tqparent=0, const char* name=0, WFlags f = 0 );
+ TQDial( int minValue, int maxValue, int pageStep, int value,
+ TQWidget* tqparent=0, const char* name=0 );
+ ~TQDial();
+
+ bool tracking() const;
+
+ bool wrapping() const;
+
+ int notchSize() const;
+
+ virtual void setNotchTarget( double );
+ double notchTarget() const;
+
+ bool notchesVisible() const;
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ int minValue() const;
+ int maxValue() const;
+ void setMinValue( int );
+ void setMaxValue( int );
+ int lineStep() const;
+ int pageStep() const;
+ void setLineStep( int );
+ void setPageStep( int );
+ int value() const;
+
+public Q_SLOTS:
+ virtual void setValue( int );
+ void addLine();
+ void subtractLine();
+ void addPage();
+ void subtractPage();
+ virtual void setNotchesVisible( bool b );
+ virtual void setWrapping( bool on );
+ virtual void setTracking( bool enable );
+
+Q_SIGNALS:
+ void valueChanged( int value );
+ void dialPressed();
+ void dialMoved( int value );
+ void dialReleased();
+
+protected:
+ void resizeEvent( TQResizeEvent * );
+ void paintEvent( TQPaintEvent * );
+
+ void keyPressEvent( TQKeyEvent * );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+#ifndef TQT_NO_WHEELEVENT
+ void wheelEvent( TQWheelEvent * );
+#endif
+ void focusInEvent( TQFocusEvent * );
+ void focusOutEvent( TQFocusEvent * );
+
+ void valueChange();
+ void rangeChange();
+
+ virtual void repaintScreen( const TQRect *cr = 0 );
+
+private:
+ TQDialPrivate * d;
+
+ int valueFromPoint( const TQPoint & ) const;
+ double angle( const TQPoint &, const TQPoint & ) const;
+ TQPointArray calcArrow( double &a ) const;
+ TQRect calcDial() const;
+ int calcBigLineSize() const;
+ void calcLines();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQDial( const TQDial & );
+ TQDial &operator=( const TQDial & );
+#endif
+
+};
+
+#endif // TQT_NO_DIAL
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqdialogbuttons.cpp b/tqtinterface/qt4/src/widgets/tqdialogbuttons.cpp
new file mode 100644
index 0000000..cabc7e8
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqdialogbuttons.cpp
@@ -0,0 +1,456 @@
+/****************************************************************************
+**
+** Implementation of TQDialogButtons class
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdialogbuttons_p.h"
+#ifndef TQT_NO_DIALOGBUTTONS
+
+#include <tqapplication.h>
+#include <tqpushbutton.h>
+#include <tqguardedptr.h>
+#include <tqmap.h>
+#include <tqvariant.h>
+#ifndef TQT_NO_DIALOG
+#include <tqdialog.h>
+#endif // TQT_NO_DIALOG
+#include <tqlayout.h>
+#include <tqstyle.h>
+#include <tqmap.h>
+
+struct TQDialogButtonsPrivate
+{
+ TQMap<int, TQString> text;
+ TQMap<TQDialogButtons::Button, TQWidget *> buttons;
+ TQGuardedPtr<TQWidget> custom;
+ TQ_UINT32 enabled, visible;
+ TQDialogButtons::Button def;
+ Qt::Orientation orient;
+ bool questionMode;
+};
+
+#ifndef TQT_NO_DIALOG
+TQDialogButtons::TQDialogButtons(TQDialog *tqparent, bool autoConnect, TQ_UINT32 buttons,
+ Qt::Orientation orient, const char *name ) : TQWidget(tqparent, name)
+{
+ init(buttons, orient);
+ if(tqparent && autoConnect) {
+ TQObject::connect(this, TQT_SIGNAL(acceptClicked()), tqparent, TQT_SLOT(accept()));
+ TQObject::connect(this, TQT_SIGNAL(rejectClicked()), tqparent, TQT_SLOT(reject()));
+ }
+}
+#endif // TQT_NO_DIALOG
+
+TQDialogButtons::TQDialogButtons(TQWidget *tqparent, TQ_UINT32 buttons,
+ Qt::Orientation orient, const char *name ) : TQWidget(tqparent, name)
+{
+ init(buttons, orient);
+}
+
+void
+TQDialogButtons::init(TQ_UINT32 buttons, Qt::Orientation orient)
+{
+ if(buttons == All) {
+ qWarning("TQDialogButtons: cannot specify All by itself!");
+ buttons = None;
+ }
+ d = new TQDialogButtonsPrivate;
+ d->questionMode = FALSE;
+ d->orient = orient;
+ d->def = (Button)tqstyle().tqstyleHint(TQStyle::SH_DialogButtons_DefaultButton, this);
+ d->enabled = d->visible = buttons;
+}
+
+TQDialogButtons::~TQDialogButtons()
+{
+ delete (TQWidget *)d->custom;
+ delete d;
+}
+
+void
+TQDialogButtons::setQuestionMode(bool b)
+{
+ d->questionMode = b;
+}
+
+bool
+TQDialogButtons::questionMode() const
+{
+ return d->questionMode;
+}
+
+void
+TQDialogButtons::setButtonEnabled(Button button, bool enabled)
+{
+ if(enabled)
+ d->enabled |= button;
+ else
+ d->enabled ^= button;
+ if(d->buttons.tqcontains(button))
+ d->buttons[button]->setEnabled(enabled);
+}
+
+bool
+TQDialogButtons::isButtonEnabled(Button button) const
+{
+ return ((int)(d->enabled & button)) == button;
+}
+
+void
+TQDialogButtons::setButtonVisible(Button button, bool visible)
+{
+ if(visible) {
+ if(d->buttons.tqcontains(button))
+ d->buttons[button]->show();
+ d->visible |= button;
+ } else {
+ if(d->buttons.tqcontains(button))
+ d->buttons[button]->hide();
+ d->visible ^= button;
+ }
+ layoutButtons();
+}
+
+bool
+TQDialogButtons::isButtonVisible(Button button) const
+{
+ return ((int)(d->visible & button)) == button;
+}
+
+void
+TQDialogButtons::addWidget(TQWidget *w)
+{
+ TQBoxLayout *lay = NULL;
+ if(!d->custom) {
+ d->custom = new TQWidget(this, "dialog_custom_area");
+ if(orientation() == Qt::Horizontal)
+ lay = new TQHBoxLayout(d->custom);
+ else
+ lay = new TQVBoxLayout(d->custom);
+ layoutButtons();
+ } else {
+ lay = (TQBoxLayout*)d->custom->tqlayout();
+ }
+ if(w->tqparent() != TQT_TQOBJECT(d->custom))
+ w->reparent(d->custom, 0, TQPoint(0, 0), TRUE);
+ lay->addWidget(w);
+}
+
+void
+TQDialogButtons::setDefaultButton(Button button)
+{
+ if(!((int)(d->visible & button) == button)) {
+ qWarning("TQDialogButtons: Button '%d' is not visible (so cannot be default)", button);
+ return;
+ }
+ if(d->def != button) {
+#ifndef TQT_NO_PROPERTIES
+ if(d->buttons.tqcontains(d->def))
+ d->buttons[d->def]->setProperty("default", TQVariant(FALSE,0));
+#endif
+ d->def = button;
+#ifndef TQT_NO_PROPERTIES
+ if(d->buttons.tqcontains(d->def))
+ d->buttons[d->def]->setProperty("default", TQVariant(FALSE,0));
+#endif
+ }
+}
+
+TQDialogButtons::Button
+TQDialogButtons::defaultButton() const
+{
+ return d->def;
+}
+
+void
+TQDialogButtons::setButtonText(Button button, const TQString &str)
+{
+ d->text[button] = str;
+#ifndef TQT_NO_PROPERTIES
+ if(d->buttons.tqcontains(button))
+ d->buttons[button]->setProperty("text", TQVariant(str));
+#endif
+ layoutButtons();
+}
+
+TQString
+TQDialogButtons::buttonText(Button b) const
+{
+ if(d->text.tqcontains(b))
+ return d->text[b];
+ return TQString(); //null if it is default..
+}
+
+void
+TQDialogButtons::setOrientation(Qt::Orientation orient)
+{
+ if(d->orient != orient) {
+ d->orient = orient;
+ if(d->custom && d->custom->tqlayout())
+ ((TQBoxLayout*)d->custom->tqlayout())->setDirection(orient == Qt::Horizontal ? TQBoxLayout::LeftToRight :
+ TQBoxLayout::TopToBottom);
+ layoutButtons();
+ }
+}
+
+Qt::Orientation
+TQDialogButtons::orientation() const
+{
+ return d->orient;
+}
+
+TQWidget *
+TQDialogButtons::createButton(Button b)
+{
+ TQPushButton *ret = new TQPushButton(this, "qdialog_button");
+ TQObject::connect(ret, TQT_SIGNAL(clicked()), this, TQT_SLOT(handleClicked()));
+ if(d->text.tqcontains(b)) {
+ ret->setText(d->text[b]);
+ } else {
+ switch(b) {
+ case All: {
+ TQString txt = buttonText(defaultButton());
+ if(txt.isNull()) {
+ if(defaultButton() == Accept) {
+ if(questionMode())
+ txt = tr("Yes to All");
+ else
+ txt = tr("OK to All");
+ } else {
+ if(questionMode())
+ txt = tr("No to All");
+ else
+ txt = tr("Cancel All");
+ }
+ } else {
+ txt += tr(" to All"); //ick, I can't really do this!!
+ }
+ ret->setText(txt);
+ break; }
+ case Accept:
+ if(questionMode())
+ ret->setText(tr("Yes"));
+ else
+ ret->setText(tr("OK"));
+ break;
+ case Reject:
+ if(questionMode())
+ ret->setText(tr("No"));
+ else
+ ret->setText(tr("Cancel"));
+ break;
+ case Apply:
+ ret->setText(tr("Apply"));
+ break;
+ case Ignore:
+ ret->setText(tr("Ignore"));
+ break;
+ case Retry:
+ ret->setText(tr("Retry"));
+ break;
+ case Abort:
+ ret->setText(tr("Abort"));
+ break;
+ case Help:
+ ret->setText(tr("Help"));
+ break;
+ default:
+ break;
+ }
+ }
+ return ret;
+}
+
+void
+TQDialogButtons::handleClicked()
+{
+ const TQObject *s = TQT_TQOBJECT(sender());
+ if(!s)
+ return;
+
+ for(TQMapIterator<TQDialogButtons::Button, TQWidget *> it = d->buttons.begin(); it != d->buttons.end(); ++it) {
+ if(TQT_TQOBJECT(it.data()) == s) {
+ emit clicked((TQDialogButtons::Button)it.key());
+ switch(it.key()) {
+ case Retry:
+ emit retryClicked();
+ break;
+ case Ignore:
+ emit ignoreClicked();
+ break;
+ case Abort:
+ emit abortClicked();
+ break;
+ case All:
+ emit allClicked();
+ break;
+ case Accept:
+ emit acceptClicked();
+ break;
+ case Reject:
+ emit rejectClicked();
+ break;
+ case Apply:
+ emit applyClicked();
+ break;
+ case Help:
+ emit helpClicked();
+ break;
+ default:
+ break;
+ }
+ return;
+ }
+ }
+}
+
+void
+TQDialogButtons::resizeEvent(TQResizeEvent *)
+{
+ layoutButtons();
+}
+
+void
+TQDialogButtons::showEvent(TQShowEvent *)
+{
+ layoutButtons();
+}
+
+void
+TQDialogButtons::styleChanged(TQStyle &old)
+{
+ layoutButtons();
+ TQWidget::styleChange(old);
+}
+
+void
+TQDialogButtons::layoutButtons()
+{
+ if(!isVisible()) //nah..
+ return;
+
+ TQStyle::SubRect rects[] = {
+ TQStyle::SR_DialogButtonAccept, TQStyle::SR_DialogButtonReject,
+ TQStyle::SR_DialogButtonApply, TQStyle::SR_DialogButtonHelp,
+ TQStyle::SR_DialogButtonCustom, TQStyle::SR_DialogButtonAll,
+ TQStyle::SR_DialogButtonRetry, TQStyle::SR_DialogButtonIgnore,
+ TQStyle::SR_DialogButtonAbort };
+ for(unsigned int i = 0; i < (sizeof(rects) / sizeof(rects[0])); i++) {
+ TQWidget *w = NULL;
+ if(rects[i] == TQStyle::SR_DialogButtonCustom) {
+ w = d->custom;
+ } else {
+ Button b = None;
+ if(rects[i] == TQStyle::SR_DialogButtonApply)
+ b = Apply;
+ else if(rects[i] == TQStyle::SR_DialogButtonAll)
+ b = All;
+ else if(rects[i] == TQStyle::SR_DialogButtonAccept)
+ b = Accept;
+ else if(rects[i] == TQStyle::SR_DialogButtonReject)
+ b = Reject;
+ else if(rects[i] == TQStyle::SR_DialogButtonHelp)
+ b = Help;
+ else if(rects[i] == TQStyle::SR_DialogButtonRetry)
+ b = Retry;
+ else if(rects[i] == TQStyle::SR_DialogButtonAbort)
+ b = Abort;
+ else if(rects[i] == TQStyle::SR_DialogButtonIgnore)
+ b = Ignore;
+ if(b != None) {
+ if(d->buttons.tqcontains(b)) {
+ w = d->buttons[b];
+ if(!(d->visible & b)) {
+ w->hide();
+ continue;
+ }
+ } else if(d->visible & b) {
+ w = createButton(b);
+ d->buttons.insert(b, w);
+ } else {
+ continue;
+ }
+ if(w) {
+ if(b == d->def) {
+ w->setFocus();
+#ifndef TQT_NO_PROPERTIES
+ w->setProperty("default", TQVariant(TRUE,0));
+#endif
+ }
+ w->setEnabled(d->enabled & b);
+ }
+ }
+ }
+ if(w) {
+ w->show();
+ w->setGeometry(tqstyle().subRect(rects[i], this));
+ }
+ }
+}
+
+TQSize
+TQDialogButtons::tqsizeHint() const
+{
+ constPolish();
+ TQSize s;
+ if(d->custom)
+ s = d->custom->tqsizeHint();
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_DialogButtons, this, s.
+ expandedTo(TQApplication::globalStrut())));
+}
+
+TQSize
+TQDialogButtons::tqsizeHint(TQDialogButtons::Button button) const
+{
+ TQWidget *w = NULL;
+ if(d->visible & button) {
+ if(!d->buttons.tqcontains(button)) {
+ TQDialogButtons *that = (TQDialogButtons*)this; //ick, constness..
+ w = that->createButton(button);
+ that->d->buttons.insert(button, w);
+ } else {
+ w = d->buttons[button];
+ }
+ }
+ return w->tqsizeHint();
+}
+
+TQSize
+TQDialogButtons::tqminimumSizeHint() const
+{
+ return tqsizeHint();
+}
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqdialogbuttons_p.h b/tqtinterface/qt4/src/widgets/tqdialogbuttons_p.h
new file mode 100644
index 0000000..4262ec1
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqdialogbuttons_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Definition of TQDialogButtons class.
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDIALOGBUTTONS_P_H
+#define TQDIALOGBUTTONS_P_H
+
+#ifndef TQT_H
+#ifndef TQT_H
+#include "tqwidget.h"
+#endif // TQT_H
+#endif
+
+#ifndef TQT_NO_DIALOGBUTTONS
+struct TQDialogButtonsPrivate;
+
+class
+TQDialogButtons : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ enum Button { None=0, Accept=0x01, Reject=0x02, Help=0x04, Apply=0x08, All=0x10, Abort=0x20, Retry=0x40, Ignore=0x80 };
+#ifndef TQT_NO_DIALOG
+ TQDialogButtons(TQDialog *tqparent, bool autoConnect = TRUE, TQ_UINT32 buttons = Accept | Reject,
+ Qt::Orientation orient = Qt::Horizontal, const char *name = NULL);
+#endif // TQT_NO_DIALOG
+ TQDialogButtons(TQWidget *tqparent, TQ_UINT32 buttons = Accept | Reject,
+ Qt::Orientation orient = Qt::Horizontal, const char *name = NULL);
+ ~TQDialogButtons();
+
+ void setQuestionMode(bool);
+ bool questionMode() const;
+
+ void setButtonEnabled(Button button, bool enabled);
+ bool isButtonEnabled(Button) const;
+
+ inline void showButton(Button b) { setButtonVisible(b, TRUE) ; }
+ inline void hideButton(Button b) { setButtonVisible(b, FALSE); }
+ virtual void setButtonVisible(Button, bool visible);
+ bool isButtonVisible(Button) const;
+
+ void addWidget(TQWidget *);
+
+ virtual void setDefaultButton(Button);
+ Button defaultButton() const;
+
+ virtual void setButtonText(Button, const TQString &);
+ TQString buttonText(Button) const;
+
+ void setOrientation(Qt::Orientation);
+ Qt::Orientation orientation() const;
+
+ virtual TQSize tqsizeHint(Button) const;
+ TQSize tqminimumSizeHint() const;
+ TQSize tqsizeHint() const;
+
+protected:
+ void layoutButtons();
+ virtual TQWidget *createButton(Button);
+
+ void showEvent(TQShowEvent *);
+ void resizeEvent(TQResizeEvent *);
+ void styleChanged(TQStyle &);
+
+private Q_SLOTS:
+ void handleClicked();
+
+Q_SIGNALS:
+ void clicked(Button);
+ void acceptClicked();
+ void rejectClicked();
+ void helpClicked();
+ void applyClicked();
+ void allClicked();
+ void retryClicked();
+ void ignoreClicked();
+ void abortClicked();
+
+private:
+ TQDialogButtonsPrivate *d;
+ void init(TQ_UINT32, Qt::Orientation);
+};
+#endif //TQT_NO_DIALOGBUTTONS
+#endif //TQDIALOGBUTTONS_P_H
diff --git a/tqtinterface/qt4/src/widgets/tqdockarea.cpp b/tqtinterface/qt4/src/widgets/tqdockarea.cpp
new file mode 100644
index 0000000..5aed489
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqdockarea.cpp
@@ -0,0 +1,1340 @@
+/****************************************************************************
+**
+** Implementation of the TQDockArea class
+**
+** Created : 001010
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the workspace module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdockarea.h"
+
+#ifndef TQT_NO_MAINWINDOW
+#include "tqsplitter.h"
+#include "tqlayout.h"
+#include "tqptrvector.h"
+#include "tqapplication.h"
+#include "tqpainter.h"
+#include "tqwidgetlist.h"
+#include "tqmap.h"
+#include "tqmainwindow.h"
+
+//#define TQDOCKAREA_DEBUG
+
+struct TQ_EXPORT DockData
+{
+ DockData() : w( 0 ), rect() {}
+ DockData( TQDockWindow *dw, const TQRect &r ) : w( dw ), rect( r ) {}
+ TQDockWindow *w;
+ TQRect rect;
+
+ TQ_DUMMY_COMPARISON_OPERATOR( DockData )
+};
+
+static int fix_x( TQDockWindow* w, int width = -1 ) {
+ if ( TQApplication::reverseLayout() ) {
+ if ( width < 0 )
+ width = w->width();
+ return w->parentWidget()->width() - w->x() - width;
+ }
+ return w->x();
+}
+static int fix_x( TQDockWindow* w, int x, int width = -1 ) {
+ if ( TQApplication::reverseLayout() ) {
+ if ( width < 0 )
+ width = w->width();
+ return w->parentWidget()->width() - x - width;
+ }
+ return x;
+}
+
+static TQPoint fix_pos( TQDockWindow* w ) {
+ if ( TQApplication::reverseLayout() ) {
+ TQPoint p = w->pos();
+ p.rx() = w->parentWidget()->width() - p.x() - w->width();
+ return p;
+ }
+ return w->pos();
+}
+
+/*!
+ \reimp
+*/
+int TQDockAreaLayout::count() const {
+ return 0;
+}
+
+/*!
+ \reimp
+*/
+TQLayoutItem* TQDockAreaLayout::itemAt(int index) const {
+ return 0;
+}
+
+/*!
+ \reimp
+*/
+TQLayoutItem* TQDockAreaLayout::takeAt(int index) {
+ return 0;
+}
+
+void TQDockAreaLayout::setGeometry( const TQRect &r )
+{
+ TQLayout::setGeometry( r );
+ layoutItems( r );
+}
+
+TQLayoutIterator TQDockAreaLayout::iterator()
+{
+ return 0;
+}
+
+TQSize TQDockAreaLayout::tqsizeHint() const
+{
+ if ( !dockWindows || !dockWindows->first() )
+ return TQSize( 0, 0 );
+
+ if ( dirty ) {
+ TQDockAreaLayout *that = (TQDockAreaLayout *) this;
+ that->layoutItems( tqgeometry() );
+ }
+
+ int w = 0;
+ int h = 0;
+ TQPtrListIterator<TQDockWindow> it( *dockWindows );
+ TQDockWindow *dw = 0;
+ it.toFirst();
+ int y = -1;
+ int x = -1;
+ int ph = 0;
+ int pw = 0;
+ while ( ( dw = it.current() ) != 0 ) {
+ int plush = 0, plusw = 0;
+ ++it;
+ if ( dw->isHidden() )
+ continue;
+ if ( hasHeightForWidth() ) {
+ if ( y != dw->y() )
+ plush = ph;
+ y = dw->y();
+ ph = dw->height();
+ } else {
+ if ( x != dw->x() )
+ plusw = pw;
+ x = dw->x();
+ pw = dw->width();
+ }
+ h = TQMAX( h, dw->height() + plush );
+ w = TQMAX( w, dw->width() + plusw );
+ }
+
+ if ( hasHeightForWidth() )
+ return TQSize( 0, h );
+ return TQSize( w, 0 );
+}
+
+bool TQDockAreaLayout::hasHeightForWidth() const
+{
+ return orient == Qt::Horizontal;
+}
+
+void TQDockAreaLayout::init()
+{
+ dirty = TRUE;
+ cached_width = 0;
+ cached_height = 0;
+ cached_hfw = -1;
+ cached_wfh = -1;
+}
+
+void TQDockAreaLayout::tqinvalidate()
+{
+ dirty = TRUE;
+ cached_width = 0;
+ cached_height = 0;
+}
+
+static int start_pos( const TQRect &r, Qt::Orientation o )
+{
+ if ( o == Qt::Horizontal ) {
+ return TQMAX( 0, r.x() );
+ } else {
+ return TQMAX( 0, r.y() );
+ }
+}
+
+static void add_size( int s, int &pos, Qt::Orientation o )
+{
+ if ( o == Qt::Horizontal ) {
+ pos += s;
+ } else {
+ pos += s;
+ }
+}
+
+static int space_left( const TQRect &r, int pos, Qt::Orientation o )
+{
+ if ( o == Qt::Horizontal ) {
+ return ( r.x() + r.width() ) - pos;
+ } else {
+ return ( r.y() + r.height() ) - pos;
+ }
+}
+
+static int dock_extent( TQDockWindow *w, Qt::Orientation o, int maxsize )
+{
+ if ( o == Qt::Horizontal )
+ return TQMIN( maxsize, TQMAX( w->tqsizeHint().width(), w->fixedExtent().width() ) );
+ else
+ return TQMIN( maxsize, TQMAX( w->tqsizeHint().height(), w->fixedExtent().height() ) );
+}
+
+static int dock_strut( TQDockWindow *w, Qt::Orientation o )
+{
+ if ( o != Qt::Horizontal ) {
+ int wid;
+ if ( ( wid = w->fixedExtent().width() ) != -1 )
+ return TQMAX( wid, TQMAX( w->tqminimumSize().width(), w->tqminimumSizeHint().width() ) );
+ return TQMAX( w->tqsizeHint().width(), TQMAX( w->tqminimumSize().width(), w->tqminimumSizeHint().width() ) );
+ } else {
+ int hei;
+ if ( ( hei = w->fixedExtent().height() ) != -1 )
+ return TQMAX( hei, TQMAX( w->tqminimumSizeHint().height(), w->tqminimumSize().height() ) );
+ return TQMAX( w->tqsizeHint().height(), TQMAX( w->tqminimumSizeHint().height(), w->tqminimumSize().height() ) );
+ }
+}
+
+static void set_tqgeometry( TQDockWindow *w, int pos, int sectionpos, int extent, int strut, Qt::Orientation o )
+{
+ if ( o == Qt::Horizontal )
+ w->setGeometry( fix_x( w, pos, extent), sectionpos, extent, strut );
+ else
+ w->setGeometry( sectionpos, pos, strut, extent );
+}
+
+static int size_extent( const TQSize &s, Qt::Orientation o, bool swap = FALSE )
+{
+ return o == Qt::Horizontal ? ( swap ? s.height() : s.width() ) : ( swap ? s.width() : s.height() );
+}
+
+static int point_pos( const TQPoint &p, Qt::Orientation o, bool swap = FALSE )
+{
+ return o == Qt::Horizontal ? ( swap ? p.y() : p.x() ) : ( swap ? p.x() : p.y() );
+}
+
+static void shrink_extend( TQDockWindow *dw, int &dockExtend, int /*spaceLeft*/, Qt::Orientation o )
+{
+ TQToolBar *tb = ::tqqt_cast<TQToolBar*>(dw);
+ if ( o == Qt::Horizontal ) {
+ int mw = 0;
+ if ( !tb )
+ mw = dw->minimumWidth();
+ else
+ mw = dw->tqsizeHint().width();
+ dockExtend = mw;
+ } else {
+ int mh = 0;
+ if ( !tb )
+ mh = dw->minimumHeight();
+ else
+ mh = dw->tqsizeHint().height();
+ dockExtend = mh;
+ }
+}
+
+static void place_line( TQValueList<DockData> &lastLine, Qt::Orientation o, int linestrut, int fullextent, int tbstrut, int maxsize, TQDockAreaLayout * )
+{
+ TQDockWindow *last = 0;
+ TQRect lastRect;
+ for ( TQValueList<DockData>::Iterator it = lastLine.begin(); it != lastLine.end(); ++it ) {
+ if ( tbstrut != -1 && ::tqqt_cast<TQToolBar*>((*it).w) )
+ (*it).rect.setHeight( tbstrut );
+ if ( !last ) {
+ last = (*it).w;
+ lastRect = (*it).rect;
+ continue;
+ }
+ if ( !last->isStretchable() ) {
+ int w = TQMIN( lastRect.width(), maxsize );
+ set_tqgeometry( last, lastRect.x(), lastRect.y(), w, lastRect.height(), o );
+ } else {
+ int w = TQMIN( (*it).rect.x() - lastRect.x(), maxsize );
+ set_tqgeometry( last, lastRect.x(), lastRect.y(), w,
+ last->isResizeEnabled() ? linestrut : lastRect.height(), o );
+ }
+ last = (*it).w;
+ lastRect = (*it).rect;
+ }
+ if ( !last )
+ return;
+ if ( !last->isStretchable() ) {
+ int w = TQMIN( lastRect.width(), maxsize );
+ set_tqgeometry( last, lastRect.x(), lastRect.y(), w, lastRect.height(), o );
+ } else {
+ int w = TQMIN( fullextent - lastRect.x() - ( o == Qt::Vertical ? 1 : 0 ), maxsize );
+ set_tqgeometry( last, lastRect.x(), lastRect.y(), w,
+ last->isResizeEnabled() ? linestrut : lastRect.height(), o );
+ }
+}
+
+
+TQSize TQDockAreaLayout::tqminimumSize() const
+{
+ if ( !dockWindows || !dockWindows->first() )
+ return TQSize( 0, 0 );
+
+ if ( dirty ) {
+ TQDockAreaLayout *that = (TQDockAreaLayout *) this;
+ that->layoutItems( tqgeometry() );
+ }
+
+ int s = 0;
+
+ TQPtrListIterator<TQDockWindow> it( *dockWindows );
+ TQDockWindow *dw = 0;
+ while ( ( dw = it.current() ) != 0 ) {
+ ++it;
+ if ( dw->isHidden() )
+ continue;
+ s = TQMAX( s, dock_strut( dw, orientation() ) );
+ }
+
+ return orientation() == Qt::Horizontal ? TQSize( 0, s ? s+2 : 0 ) : TQSize( s, 0 );
+}
+
+
+
+int TQDockAreaLayout::layoutItems( const TQRect &rect, bool testonly )
+{
+ if ( !dockWindows || !dockWindows->first() )
+ return 0;
+
+ dirty = FALSE;
+
+ // some corrections
+ TQRect r = rect;
+ if ( orientation() == Qt::Vertical )
+ r.setHeight( r.height() - 3 );
+
+ // init
+ lines.clear();
+ ls.clear();
+ TQPtrListIterator<TQDockWindow> it( *dockWindows );
+ TQDockWindow *dw = 0;
+ int start = start_pos( r, orientation() );
+ int pos = start;
+ int sectionpos = 0;
+ int linestrut = 0;
+ TQValueList<DockData> lastLine;
+ int tbstrut = -1;
+ int maxsize = size_extent( rect.size(), orientation() );
+ int visibleWindows = 0;
+
+ // go through all widgets in the dock
+ while ( ( dw = it.current() ) != 0 ) {
+ ++it;
+ if ( dw->isHidden() )
+ continue;
+ ++visibleWindows;
+ // tqfind position for the widget: This is the maximum of the
+ // end of the previous widget and the offset of the widget. If
+ // the position + the width of the widget dosn't fit into the
+ // dock, try moving it a bit back, if possible.
+ int op = pos;
+ int dockExtend = dock_extent( dw, orientation(), maxsize );
+ if ( !dw->isStretchable() ) {
+ pos = TQMAX( pos, dw->offset() );
+ if ( pos + dockExtend > size_extent( r.size(), orientation() ) - 1 )
+ pos = TQMAX( op, size_extent( r.size(), orientation() ) - 1 - dockExtend );
+ }
+ if ( !lastLine.isEmpty() && !dw->newLine() && space_left( rect, pos, orientation() ) < dockExtend )
+ shrink_extend( dw, dockExtend, space_left( rect, pos, orientation() ), orientation() );
+ // if the current widget doesn't fit into the line anymore and it is not the first widget of the line
+ if ( !lastLine.isEmpty() &&
+ ( space_left( rect, pos, orientation() ) < dockExtend || dw->newLine() ) ) {
+ if ( !testonly ) // place the last line, if not in test mode
+ place_line( lastLine, orientation(), linestrut, size_extent( r.size(), orientation() ), tbstrut, maxsize, this );
+ // remember the line coordinats of the last line
+ if ( orientation() == Qt::Horizontal )
+ lines.append( TQRect( 0, sectionpos, r.width(), linestrut ) );
+ else
+ lines.append( TQRect( sectionpos, 0, linestrut, r.height() ) );
+ // do some clearing for the next line
+ lastLine.clear();
+ sectionpos += linestrut;
+ linestrut = 0;
+ pos = start;
+ tbstrut = -1;
+ }
+
+ // remeber first widget of a line
+ if ( lastLine.isEmpty() ) {
+ ls.append( dw );
+ // try to make the best position
+ int op = pos;
+ if ( !dw->isStretchable() )
+ pos = TQMAX( pos, dw->offset() );
+ if ( pos + dockExtend > size_extent( r.size(), orientation() ) - 1 )
+ pos = TQMAX( op, size_extent( r.size(), orientation() ) - 1 - dockExtend );
+ }
+ // do some calculations and add the remember the rect which the docking widget requires for the placing
+ TQRect dwRect(pos, sectionpos, dockExtend, dock_strut( dw, orientation() ) );
+ lastLine.append( DockData( dw, dwRect ) );
+ if ( ::tqqt_cast<TQToolBar*>(dw) )
+ tbstrut = TQMAX( tbstrut, dock_strut( dw, orientation() ) );
+ linestrut = TQMAX( dock_strut( dw, orientation() ), linestrut );
+ add_size( dockExtend, pos, orientation() );
+ }
+
+ // if some stuff was not placed/stored yet, do it now
+ if ( !testonly )
+ place_line( lastLine, orientation(), linestrut, size_extent( r.size(), orientation() ), tbstrut, maxsize, this );
+ if ( orientation() == Qt::Horizontal )
+ lines.append( TQRect( 0, sectionpos, r.width(), linestrut ) );
+ else
+ lines.append( TQRect( sectionpos, 0, linestrut, r.height() ) );
+ if ( *(--lines.end()) == *(--(--lines.end())) )
+ lines.remove( lines.at( lines.count() - 1 ) );
+
+ it.toFirst();
+ bool hadResizable = FALSE;
+ while ( ( dw = it.current() ) != 0 ) {
+ ++it;
+ if ( !dw->isVisibleTo( parentWidget ) )
+ continue;
+ hadResizable = hadResizable || dw->isResizeEnabled();
+ dw->updateSplitterVisibility( visibleWindows > 1 ); //!dw->area()->isLastDockWindow( dw ) );
+ }
+ return sectionpos + linestrut;
+}
+
+int TQDockAreaLayout::heightForWidth( int w ) const
+{
+ if ( dockWindows->isEmpty() && parentWidget )
+ return parentWidget->minimumHeight();
+
+ if ( cached_width != w ) {
+ TQDockAreaLayout * mthis = (TQDockAreaLayout*)this;
+ mthis->cached_width = w;
+ int h = mthis->layoutItems( TQRect( 0, 0, w, 0 ), TRUE );
+ mthis->cached_hfw = h;
+ return h;
+ }
+
+ return cached_hfw;
+}
+
+int TQDockAreaLayout::widthForHeight( int h ) const
+{
+ if ( cached_height != h ) {
+ TQDockAreaLayout * mthis = (TQDockAreaLayout*)this;
+ mthis->cached_height = h;
+ int w = mthis->layoutItems( TQRect( 0, 0, 0, h ), TRUE );
+ mthis->cached_wfh = w;
+ return w;
+ }
+ return cached_wfh;
+}
+
+
+
+
+/*!
+ \class TQDockArea tqdockarea.h
+ \brief The TQDockArea class manages and lays out TQDockWindows.
+
+ \ingroup application
+
+ A TQDockArea is a container which manages a list of
+ \l{TQDockWindow}s which it lays out within its area. In cooperation
+ with the \l{TQDockWindow}s it is responsible for the docking and
+ undocking of \l{TQDockWindow}s and moving them inside the dock
+ area. TQDockAreas also handle the wrapping of \l{TQDockWindow}s to
+ fill the available space as compactly as possible. TQDockAreas can
+ contain TQToolBars since TQToolBar is a TQDockWindow subclass.
+
+ TQMainWindow tqcontains four TQDockAreas which you can use for your
+ TQToolBars and TQDockWindows, so in most situations you do not need
+ to use the TQDockArea class directly. Although TQMainWindow tqcontains
+ support for its own dock areas it isn't convenient for adding new
+ TQDockAreas. If you need to create your own dock areas we suggest
+ that you create a subclass of TQWidget and add your TQDockAreas to
+ your subclass.
+
+ \img qmainwindow-qdockareas.png TQMainWindow's TQDockAreas
+
+ \target lines
+ \e Lines. TQDockArea uses the concept of lines. A line is a
+ horizontal region which may contain dock windows side-by-side. A
+ dock area may have room for more than one line. When dock windows
+ are docked into a dock area they are usually added at the right
+ hand side of the top-most line that has room (unless manually
+ placed by the user). When users move dock windows they may leave
+ empty lines or gaps in non-empty lines. Dock windows can be lined
+ up to minimize wasted space using the lineUp() function.
+
+ The TQDockArea class maintains a position list of all its child
+ dock windows. Dock windows are added to a dock area from position
+ 0 onwards. Dock windows are laid out sequentially in position
+ order from left to right, and in the case of multiple lines of
+ dock windows, from top to bottom. If a dock window is floated it
+ still retains its position since this is where the window will
+ return if the user double clicks its caption. A dock window's
+ position can be determined with hasDockWindow(). The position can
+ be changed with moveDockWindow().
+
+ To dock or undock a dock window use TQDockWindow::dock() and
+ TQDockWindow::undock() respectively. If you want to control which
+ dock windows can dock in a dock area use setAcceptDockWindow(). To
+ see if a dock area tqcontains a particular dock window use
+ \l{hasDockWindow()}; to see how many dock windows a dock area
+ tqcontains use count().
+
+ The streaming operators can write the positions of the dock
+ windows in the dock area to a TQTextStream. The positions can be
+ read back later to restore the saved positions.
+
+ Save the positions to a TQTextStream:
+ \code
+ ts << *myDockArea;
+ \endcode
+
+ Restore the positions from a TQTextStream:
+ \code
+ ts >> *myDockArea;
+ \endcode
+*/
+
+/*!
+ \property TQDockArea::handlePosition
+ \brief where the dock window splitter handle is placed in the dock
+ area
+
+ The default position is \c Normal.
+*/
+
+/*!
+ \property TQDockArea::orientation
+ \brief the dock area's orientation
+
+ There is no default value; the orientation is specified in the
+ constructor.
+*/
+
+/*!
+ \enum TQDockArea::HandlePosition
+
+ A dock window has two kinds of handles, the dock window handle
+ used for dragging the dock window, and the splitter handle used to
+ resize the dock window in relation to other dock windows using a
+ splitter. (The splitter handle is only visible for docked
+ windows.)
+
+ This enum specifies where the dock window splitter handle is
+ placed in the dock area.
+
+ \value Normal The splitter handles of dock windows are placed at
+ the right or bottom.
+
+ \value Reverse The splitter handles of dock windows are placed at
+ the left or top.
+*/
+
+/*!
+ Constructs a TQDockArea with orientation \a o, HandlePosition \a h,
+ tqparent \a tqparent and called \a name.
+*/
+
+TQDockArea::TQDockArea( Qt::Orientation o, HandlePosition h, TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name ), orient( o ), tqlayout( 0 ), hPos( h )
+{
+ dockWindows = new TQPtrList<TQDockWindow>;
+ tqlayout = new TQDockAreaLayout( this, o, dockWindows, 0, 0, "tooltqlayout" );
+ installEventFilter( this );
+}
+
+/*!
+ Destroys the dock area and all the dock windows docked in the dock
+ area.
+
+ Does not affect any floating dock windows or dock windows in other
+ dock areas, even if they first appeared in this dock area.
+ Floating dock windows are effectively top level windows and are
+ not child windows of the dock area. When a floating dock window is
+ docked (dragged into a dock area) its tqparent becomes the dock
+ area.
+*/
+
+TQDockArea::~TQDockArea()
+{
+ dockWindows->setAutoDelete( TRUE );
+ delete dockWindows;
+ dockWindows = 0;
+}
+
+/*!
+ Moves the TQDockWindow \a w within the dock area. If \a w is not
+ already docked in this area, \a w is docked first. If \a index is
+ -1 or larger than the number of docked widgets, \a w is appended
+ at the end, otherwise it is inserted at the position \a index.
+*/
+
+void TQDockArea::moveDockWindow( TQDockWindow *w, int index )
+{
+ invalidateFixedSizes();
+ TQDockWindow *dockWindow = 0;
+ int dockWindowIndex = tqfindDockWindow( w );
+ if ( dockWindowIndex == -1 ) {
+ dockWindow = w;
+ dockWindow->reparent( this, TQPoint( 0, 0 ), TRUE );
+ w->installEventFilter( this );
+ updateLayout();
+ tqsetSizePolicy( TQSizePolicy( orientation() == Qt::Horizontal ? TQSizePolicy::Expanding : TQSizePolicy::Minimum,
+ orientation() == Qt::Vertical ? TQSizePolicy::Expanding : TQSizePolicy::Minimum ) );
+ dockWindows->append( w );
+ } else {
+ if ( w->tqparent() != TQT_TQOBJECT(this) )
+ w->reparent( this, TQPoint( 0, 0 ), TRUE );
+ if ( index == - 1 ) {
+ dockWindows->removeRef( w );
+ dockWindows->append( w );
+ }
+ }
+
+ w->dockArea = this;
+ w->curPlace = TQDockWindow::InDock;
+ w->updateGui();
+
+ if ( index != -1 && index < (int)dockWindows->count() ) {
+ dockWindows->removeRef( w );
+ dockWindows->insert( index, w );
+ }
+}
+
+/*!
+ Returns TRUE if the dock area tqcontains the dock window \a w;
+ otherwise returns FALSE. If \a index is not 0 it will be set as
+ follows: if the dock area tqcontains the dock window \a *index is
+ set to \a w's index position; otherwise \a *index is set to -1.
+*/
+
+bool TQDockArea::hasDockWindow( TQDockWindow *w, int *index )
+{
+ int i = dockWindows->tqfindRef( w );
+ if ( index )
+ *index = i;
+ return i != -1;
+}
+
+int TQDockArea::lineOf( int index )
+{
+ TQPtrList<TQDockWindow> lineStarts = tqlayout->lineStarts();
+ int i = 0;
+ for ( TQDockWindow *w = lineStarts.first(); w; w = lineStarts.next(), ++i ) {
+ if ( dockWindows->tqfind( w ) >= index )
+ return i;
+ }
+ return i;
+}
+
+/*!
+ \overload
+
+ Moves the dock window \a w inside the dock area where \a p is the
+ new position (in global screen coordinates), \a r is the suggested
+ rectangle of the dock window and \a swap specifies whether or not
+ the orientation of the docked widget needs to be changed.
+
+ This function is used internally by TQDockWindow. You shouldn't
+ need to call it yourself.
+*/
+
+void TQDockArea::moveDockWindow( TQDockWindow *w, const TQPoint &p, const TQRect &r, bool swap )
+{
+ invalidateFixedSizes();
+ int mse = -10;
+ bool hasResizable = FALSE;
+ for ( TQDockWindow *dw = dockWindows->first(); dw; dw = dockWindows->next() ) {
+ if ( dw->isHidden() )
+ continue;
+ if ( dw->isResizeEnabled() )
+ hasResizable = TRUE;
+ if ( orientation() != Qt::Horizontal )
+ mse = TQMAX( TQMAX( dw->fixedExtent().width(), dw->width() ), mse );
+ else
+ mse = TQMAX( TQMAX( dw->fixedExtent().height(), dw->height() ), mse );
+ }
+ if ( !hasResizable && w->isResizeEnabled() ) {
+ if ( orientation() != Qt::Horizontal )
+ mse = TQMAX( w->fixedExtent().width(), mse );
+ else
+ mse = TQMAX( w->fixedExtent().height(), mse );
+ }
+
+ TQDockWindow *dockWindow = 0;
+ int dockWindowIndex = tqfindDockWindow( w );
+ TQPtrList<TQDockWindow> lineStarts = tqlayout->lineStarts();
+ TQValueList<TQRect> lines = tqlayout->lineList();
+ bool wasAloneInLine = FALSE;
+ TQPoint pos = mapFromGlobal( p );
+ TQRect lr = *lines.at( lineOf( dockWindowIndex ) );
+ if ( dockWindowIndex != -1 ) {
+ if ( lineStarts.tqfind( w ) != -1 &&
+ ( (dockWindowIndex < (int)dockWindows->count() - 1 && lineStarts.tqfind( dockWindows->at( dockWindowIndex + 1 ) ) != -1) ||
+ dockWindowIndex == (int)dockWindows->count() - 1 ) )
+ wasAloneInLine = TRUE;
+ dockWindow = dockWindows->take( dockWindowIndex );
+ if ( !wasAloneInLine ) { // only do the pre-tqlayout if the widget isn't the only one in its line
+ if ( lineStarts.tqfindRef( dockWindow ) != -1 && dockWindowIndex < (int)dockWindows->count() )
+ dockWindows->at( dockWindowIndex )->setNewLine( TRUE );
+ tqlayout->layoutItems( TQRect( 0, 0, width(), height() ), TRUE );
+ }
+ } else {
+ dockWindow = w;
+ dockWindow->reparent( this, TQPoint( 0, 0 ), TRUE );
+ if ( swap )
+ dockWindow->resize( dockWindow->height(), dockWindow->width() );
+ w->installEventFilter( this );
+ }
+
+ lineStarts = tqlayout->lineStarts();
+ lines = tqlayout->lineList();
+
+ TQRect rect = TQRect( mapFromGlobal( r.topLeft() ), r.size() );
+ if ( orientation() == Qt::Horizontal && TQApplication::reverseLayout() ) {
+ rect = TQRect( width() - rect.x() - rect.width(), rect.y(), rect.width(), rect.height() );
+ pos.rx() = width() - pos.x();
+ }
+ dockWindow->setOffset( point_pos( rect.topLeft(), orientation() ) );
+ if ( orientation() == Qt::Horizontal ) {
+ int offs = dockWindow->offset();
+ if ( width() - offs < dockWindow->minimumWidth() )
+ dockWindow->setOffset( width() - dockWindow->minimumWidth() );
+ } else {
+ int offs = dockWindow->offset();
+ if ( height() - offs < dockWindow->minimumHeight() )
+ dockWindow->setOffset( height() - dockWindow->minimumHeight() );
+ }
+
+ if ( dockWindows->isEmpty() ) {
+ dockWindows->append( dockWindow );
+ } else {
+ int dockLine = -1;
+ bool insertLine = FALSE;
+ int i = 0;
+ TQRect lineRect;
+ // tqfind the line which we touched with the mouse
+ for ( TQValueList<TQRect>::Iterator it = lines.begin(); it != lines.end(); ++it, ++i ) {
+ if ( point_pos( pos, orientation(), TRUE ) >= point_pos( (*it).topLeft(), orientation(), TRUE ) &&
+ point_pos( pos, orientation(), TRUE ) <= point_pos( (*it).topLeft(), orientation(), TRUE ) +
+ size_extent( (*it).size(), orientation(), TRUE ) ) {
+ dockLine = i;
+ lineRect = *it;
+ break;
+ }
+ }
+ if ( dockLine == -1 ) { // outside the dock...
+ insertLine = TRUE;
+ if ( point_pos( pos, orientation(), TRUE ) < 0 ) // insert as first line
+ dockLine = 0;
+ else
+ dockLine = (int)lines.count(); // insert after the last line ### size_t/int cast
+ } else { // inside the dock (we have found a dockLine)
+ if ( point_pos( pos, orientation(), TRUE ) <
+ point_pos( lineRect.topLeft(), orientation(), TRUE ) + 4 ) { // mouse was at the very beginning of the line
+ insertLine = TRUE; // insert a new line before that with the docking widget
+ } else if ( point_pos( pos, orientation(), TRUE ) >
+ point_pos( lineRect.topLeft(), orientation(), TRUE ) +
+ size_extent( lineRect.size(), orientation(), TRUE ) - 4 ) { // mouse was at the very and of the line
+ insertLine = TRUE; // insert a line after that with the docking widget
+ dockLine++;
+ }
+ }
+
+ if ( !insertLine && wasAloneInLine && lr.tqcontains( pos ) ) // if we are alone in a line and just moved in there, re-insert it
+ insertLine = TRUE;
+
+#if defined(TQDOCKAREA_DEBUG)
+ qDebug( "insert in line %d, and insert that line: %d", dockLine, insertLine );
+ qDebug( " (btw, we have %d lines)", lines.count() );
+#endif
+ TQDockWindow *dw = 0;
+ if ( dockLine >= (int)lines.count() ) { // insert after last line
+ dockWindows->append( dockWindow );
+ dockWindow->setNewLine( TRUE );
+#if defined(TQDOCKAREA_DEBUG)
+ qDebug( "insert at the end" );
+#endif
+ } else if ( dockLine == 0 && insertLine ) { // insert before first line
+ dockWindows->insert( 0, dockWindow );
+ dockWindows->at( 1 )->setNewLine( TRUE );
+#if defined(TQDOCKAREA_DEBUG)
+ qDebug( "insert at the begin" );
+#endif
+ } else { // insert somewhere in between
+ // make sure each line start has a new line
+ for ( dw = lineStarts.first(); dw; dw = lineStarts.next() )
+ dw->setNewLine( TRUE );
+
+ // tqfind the index of the first widget in the search line
+ int searchLine = dockLine;
+#if defined(TQDOCKAREA_DEBUG)
+ qDebug( "search line start of %d", searchLine );
+#endif
+ TQDockWindow *lsw = lineStarts.at( searchLine );
+ int index = dockWindows->tqfind( lsw );
+ if ( index == -1 ) { // the linestart widget hasn't been found, try to tqfind it harder
+ if ( lsw == w && dockWindowIndex <= (int)dockWindows->count())
+ index = dockWindowIndex;
+ else
+ index = 0;
+ if ( index < (int)dockWindows->count() )
+ (void)dockWindows->at( index ); // move current to index
+ }
+#if defined(TQDOCKAREA_DEBUG)
+ qDebug( " which starts at %d", index );
+#endif
+ if ( !insertLine ) { // if we insert the docking widget in the existing line
+ // tqfind the index for the widget
+ bool inc = TRUE;
+ bool firstTime = TRUE;
+ for ( dw = dockWindows->current(); dw; dw = dockWindows->next() ) {
+ if ( orientation() == Qt::Horizontal )
+ dw->setFixedExtentWidth( -1 );
+ else
+ dw->setFixedExtentHeight( -1 );
+ if ( !firstTime && lineStarts.tqfind( dw ) != -1 ) // we are in the next line, so break
+ break;
+ if ( point_pos( pos, orientation() ) <
+ point_pos( fix_pos( dw ), orientation() ) + size_extent( dw->size(), orientation() ) / 2 ) {
+ inc = FALSE;
+ }
+ if ( inc )
+ index++;
+ firstTime = FALSE;
+ }
+#if defined(TQDOCKAREA_DEBUG)
+ qDebug( "insert at index: %d", index );
+#endif
+ // if we insert it just before a widget which has a new line, transfer the newline to the docking widget
+ // but not if we didn't only mave a widget in its line which was alone in the line before
+ if ( !( wasAloneInLine && lr.tqcontains( pos ) )
+ && index >= 0 && index < (int)dockWindows->count() &&
+ dockWindows->at( index )->newLine() && lineOf( index ) == dockLine ) {
+#if defined(TQDOCKAREA_DEBUG)
+ qDebug( "get rid of the old newline and get me one" );
+#endif
+ dockWindows->at( index )->setNewLine( FALSE );
+ dockWindow->setNewLine( TRUE );
+ } else if ( wasAloneInLine && lr.tqcontains( pos ) ) {
+ dockWindow->setNewLine( TRUE );
+ } else { // if we are somewhere in a line, get rid of the newline
+ dockWindow->setNewLine( FALSE );
+ }
+ } else { // insert in a new line, so make sure the dock widget and the widget which will be after it have a newline
+#if defined(TQDOCKAREA_DEBUG)
+ qDebug( "insert a new line" );
+#endif
+ if ( index < (int)dockWindows->count() ) {
+#if defined(TQDOCKAREA_DEBUG)
+ qDebug( "give the widget at %d a newline", index );
+#endif
+ TQDockWindow* nldw = dockWindows->at( index );
+ if ( nldw )
+ nldw->setNewLine( TRUE );
+ }
+#if defined(TQDOCKAREA_DEBUG)
+ qDebug( "give me a newline" );
+#endif
+ dockWindow->setNewLine( TRUE );
+ }
+ // finally insert the widget
+ dockWindows->insert( index, dockWindow );
+ }
+ }
+
+ if ( mse != -10 && w->isResizeEnabled() ) {
+ if ( orientation() != Qt::Horizontal )
+ w->setFixedExtentWidth( TQMIN( TQMAX( w->minimumWidth(), mse ), w->tqsizeHint().width() ) );
+ else
+ w->setFixedExtentHeight( TQMIN( TQMAX( w->minimumHeight(), mse ), w->tqsizeHint().height() ) );
+ }
+
+ updateLayout();
+ tqsetSizePolicy( TQSizePolicy( orientation() == Qt::Horizontal ? TQSizePolicy::Expanding : TQSizePolicy::Minimum,
+ orientation() == Qt::Vertical ? TQSizePolicy::Expanding : TQSizePolicy::Minimum ) );
+}
+
+/*!
+ Removes the dock window \a w from the dock area. If \a
+ makeFloating is TRUE, \a w gets floated, and if \a swap is TRUE,
+ the orientation of \a w gets swapped. If \a fixNewLines is TRUE
+ (the default) newlines in the area will be fixed.
+
+ You should never need to call this function yourself. Use
+ TQDockWindow::dock() and TQDockWindow::undock() instead.
+*/
+
+void TQDockArea::removeDockWindow( TQDockWindow *w, bool makeFloating, bool swap, bool fixNewLines )
+{
+ w->removeEventFilter( this );
+ TQDockWindow *dockWindow = 0;
+ int i = tqfindDockWindow( w );
+ if ( i == -1 )
+ return;
+ dockWindow = dockWindows->at( i );
+ dockWindows->remove( i );
+ TQPtrList<TQDockWindow> lineStarts = tqlayout->lineStarts();
+ if ( fixNewLines && lineStarts.tqfindRef( dockWindow ) != -1 && i < (int)dockWindows->count() )
+ dockWindows->at( i )->setNewLine( TRUE );
+ if ( makeFloating ) {
+ TQWidget *p = parentWidget() ? parentWidget() : tqtopLevelWidget();
+ dockWindow->reparent( p, (Qt::WindowFlags)(TQt::WType_Dialog | WStyle_Customize | TQt::WStyle_NoBorder | TQt::WStyle_Tool), TQPoint( 0, 0 ), FALSE );
+ }
+ if ( swap )
+ dockWindow->resize( dockWindow->height(), dockWindow->width() );
+ updateLayout();
+ if ( dockWindows->isEmpty() )
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) );
+}
+
+int TQDockArea::tqfindDockWindow( TQDockWindow *w )
+{
+ return dockWindows ? dockWindows->tqfindRef( w ) : -1;
+}
+
+void TQDockArea::updateLayout()
+{
+ tqlayout->tqinvalidate();
+ tqlayout->activate();
+}
+
+/*! \reimp
+ */
+
+bool TQDockArea::eventFilter( TQObject *o, TQEvent *e )
+{
+ if ( e->type() == TQEvent::Close ) {
+ if ( ::tqqt_cast<TQDockWindow*>(o) ) {
+ o->removeEventFilter( this );
+ TQApplication::sendEvent( o, e );
+ if ( ( (TQCloseEvent*)e )->isAccepted() )
+ removeDockWindow( (TQDockWindow*)o, FALSE, FALSE );
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*! \internal
+
+ Invalidates the offset of the next dock window in the dock area.
+ */
+
+void TQDockArea::invalidNextOffset( TQDockWindow *dw )
+{
+ int i = dockWindows->tqfind( dw );
+ if ( i == -1 || i >= (int)dockWindows->count() - 1 )
+ return;
+ if ( ( dw = dockWindows->at( ++i ) ) )
+ dw->setOffset( 0 );
+}
+
+/*!
+ \property TQDockArea::count
+ \brief the number of dock windows in the dock area
+*/
+int TQDockArea::count() const
+{
+ return dockWindows->count();
+}
+
+/*!
+ \property TQDockArea::empty
+ \brief whether the dock area is empty
+*/
+
+bool TQDockArea::isEmpty() const
+{
+ return dockWindows->isEmpty();
+}
+
+
+/*!
+ Returns a list of the dock windows in the dock area.
+*/
+
+TQPtrList<TQDockWindow> TQDockArea::dockWindowList() const
+{
+ return *dockWindows;
+}
+
+/*!
+ Lines up the dock windows in this dock area to minimize wasted
+ space. If \a keepNewLines is TRUE, only space within lines is
+ cleaned up. If \a keepNewLines is FALSE the number of lines might
+ be changed.
+*/
+
+void TQDockArea::lineUp( bool keepNewLines )
+{
+ for ( TQDockWindow *dw = dockWindows->first(); dw; dw = dockWindows->next() ) {
+ dw->setOffset( 0 );
+ if ( !keepNewLines )
+ dw->setNewLine( FALSE );
+ }
+ tqlayout->activate();
+}
+
+TQDockArea::DockWindowData *TQDockArea::dockWindowData( TQDockWindow *w )
+{
+ DockWindowData *data = new DockWindowData;
+ data->index = tqfindDockWindow( w );
+ if ( data->index == -1 ) {
+ delete data;
+ return 0;
+ }
+ TQPtrList<TQDockWindow> lineStarts = tqlayout->lineStarts();
+ int i = -1;
+ for ( TQDockWindow *dw = dockWindows->first(); dw; dw = dockWindows->next() ) {
+ if ( lineStarts.tqfindRef( dw ) != -1 )
+ ++i;
+ if ( dw == w )
+ break;
+ }
+ data->line = i;
+ data->offset = point_pos( TQPoint( fix_x(w), w->y() ), orientation() );
+ data->area = this;
+ data->fixedExtent = w->fixedExtent();
+ return data;
+}
+
+void TQDockArea::dockWindow( TQDockWindow *dockWindow, DockWindowData *data )
+{
+ if ( !data )
+ return;
+
+ dockWindow->reparent( this, TQPoint( 0, 0 ), FALSE );
+ dockWindow->installEventFilter( this );
+ dockWindow->dockArea = this;
+ dockWindow->updateGui();
+
+ if ( dockWindows->isEmpty() ) {
+ dockWindows->append( dockWindow );
+ } else {
+ TQPtrList<TQDockWindow> lineStarts = tqlayout->lineStarts();
+ int index = 0;
+ if ( (int)lineStarts.count() > data->line )
+ index = dockWindows->tqfind( lineStarts.at( data->line ) );
+ if ( index == -1 ) {
+ index = 0;
+ (void)dockWindows->at( index );
+ }
+ bool firstTime = TRUE;
+ int offset = data->offset;
+ for ( TQDockWindow *dw = dockWindows->current(); dw; dw = dockWindows->next() ) {
+ if ( !firstTime && lineStarts.tqfind( dw ) != -1 )
+ break;
+ if ( offset <
+ point_pos( fix_pos( dw ), orientation() ) + size_extent( dw->size(), orientation() ) / 2 )
+ break;
+ index++;
+ firstTime = FALSE;
+ }
+ if ( index >= 0 && index < (int)dockWindows->count() &&
+ dockWindows->at( index )->newLine() && lineOf( index ) == data->line ) {
+ dockWindows->at( index )->setNewLine( FALSE );
+ dockWindow->setNewLine( TRUE );
+ } else {
+ dockWindow->setNewLine( FALSE );
+ }
+
+ dockWindows->insert( index, dockWindow );
+ }
+ dockWindow->show();
+
+ dockWindow->setFixedExtentWidth( data->fixedExtent.width() );
+ dockWindow->setFixedExtentHeight( data->fixedExtent.height() );
+
+ updateLayout();
+ tqsetSizePolicy( TQSizePolicy( orientation() == Qt::Horizontal ? TQSizePolicy::Expanding : TQSizePolicy::Minimum,
+ orientation() == Qt::Vertical ? TQSizePolicy::Expanding : TQSizePolicy::Minimum ) );
+
+}
+
+/*!
+ Returns TRUE if dock window \a dw could be docked into the dock
+ area; otherwise returns FALSE.
+
+ \sa setAcceptDockWindow()
+*/
+
+bool TQDockArea::isDockWindowAccepted( TQDockWindow *dw )
+{
+ if ( !dw )
+ return FALSE;
+ if ( forbiddenWidgets.tqfindRef( dw ) != -1 )
+ return FALSE;
+
+ TQMainWindow *mw = ::tqqt_cast<TQMainWindow*>(parentWidget());
+ if ( !mw )
+ return TRUE;
+ if ( !mw->hasDockWindow( dw ) )
+ return FALSE;
+ if ( !mw->isDockEnabled( this ) )
+ return FALSE;
+ if ( !mw->isDockEnabled( dw, this ) )
+ return FALSE;
+ return TRUE;
+}
+
+/*!
+ If \a accept is TRUE, dock window \a dw can be docked in the dock
+ area. If \a accept is FALSE, dock window \a dw cannot be docked in
+ the dock area.
+
+ \sa isDockWindowAccepted()
+*/
+
+void TQDockArea::setAcceptDockWindow( TQDockWindow *dw, bool accept )
+{
+ if ( accept )
+ forbiddenWidgets.removeRef( dw );
+ else if ( forbiddenWidgets.tqfindRef( dw ) == -1 )
+ forbiddenWidgets.append( dw );
+}
+
+void TQDockArea::invalidateFixedSizes()
+{
+ for ( TQDockWindow *dw = dockWindows->first(); dw; dw = dockWindows->next() ) {
+ if ( orientation() == Qt::Horizontal )
+ dw->setFixedExtentWidth( -1 );
+ else
+ dw->setFixedExtentHeight( -1 );
+ }
+}
+
+int TQDockArea::maxSpace( int hint, TQDockWindow *dw )
+{
+ int index = tqfindDockWindow( dw );
+ if ( index == -1 || index + 1 >= (int)dockWindows->count() ) {
+ if ( orientation() == Qt::Horizontal )
+ return dw->width();
+ return dw->height();
+ }
+
+ TQDockWindow *w = 0;
+ int i = 0;
+ do {
+ w = dockWindows->at( index + (++i) );
+ } while ( i + 1 < (int)dockWindows->count() && ( !w || w->isHidden() ) );
+ if ( !w || !w->isResizeEnabled() || i >= (int)dockWindows->count() ) {
+ if ( orientation() == Qt::Horizontal )
+ return dw->width();
+ return dw->height();
+ }
+ int min = 0;
+ TQToolBar *tb = ::tqqt_cast<TQToolBar*>(w);
+ if ( orientation() == Qt::Horizontal ) {
+ w->setFixedExtentWidth( -1 );
+ if ( !tb )
+ min = TQMAX( w->tqminimumSize().width(), w->tqminimumSizeHint().width() );
+ else
+ min = w->tqsizeHint().width();
+ } else {
+ w->setFixedExtentHeight( -1 );
+ if ( !tb )
+ min = TQMAX( w->tqminimumSize().height(), w->tqminimumSizeHint().height() );
+ else
+ min = w->tqsizeHint().height();
+ }
+
+ int diff = hint - ( orientation() == Qt::Horizontal ? dw->width() : dw->height() );
+
+ if ( ( orientation() == Qt::Horizontal ? w->width() : w->height() ) - diff < min )
+ hint = ( orientation() == Qt::Horizontal ? dw->width() : dw->height() ) + ( orientation() == Qt::Horizontal ? w->width() : w->height() ) - min;
+
+ diff = hint - ( orientation() == Qt::Horizontal ? dw->width() : dw->height() );
+ if ( orientation() == Qt::Horizontal )
+ w->setFixedExtentWidth( w->width() - diff );
+ else
+ w->setFixedExtentHeight( w->height() - diff );
+ return hint;
+}
+
+void TQDockArea::setFixedExtent( int d, TQDockWindow *dw )
+{
+ TQPtrList<TQDockWindow> lst;
+ TQDockWindow *w;
+ for ( w = dockWindows->first(); w; w = dockWindows->next() ) {
+ if ( w->isHidden() )
+ continue;
+ if ( orientation() == Qt::Horizontal ) {
+ if ( dw->y() != w->y() )
+ continue;
+ } else {
+ if ( dw->x() != w->x() )
+ continue;
+ }
+ if ( orientation() == Qt::Horizontal )
+ d = TQMAX( d, w->minimumHeight() );
+ else
+ d = TQMAX( d, w->minimumWidth() );
+ if ( w->isResizeEnabled() )
+ lst.append( w );
+ }
+ for ( w = lst.first(); w; w = lst.next() ) {
+ if ( orientation() == Qt::Horizontal )
+ w->setFixedExtentHeight( d );
+ else
+ w->setFixedExtentWidth( d );
+ }
+}
+
+bool TQDockArea::isLastDockWindow( TQDockWindow *dw )
+{
+ int i = dockWindows->tqfind( dw );
+ if ( i == -1 || i >= (int)dockWindows->count() - 1 )
+ return TRUE;
+ TQDockWindow *w = 0;
+ if ( ( w = dockWindows->at( ++i ) ) ) {
+ if ( orientation() == Qt::Horizontal && dw->y() < w->y() )
+ return TRUE;
+ if ( orientation() == Qt::Vertical && dw->x() < w->x() )
+ return TRUE;
+ } else {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#ifndef TQT_NO_TEXTSTREAM
+
+/*!
+ \relates TQDockArea
+
+ Writes the tqlayout of the dock windows in dock area \a dockArea to
+ the text stream \a ts.
+
+ \sa operator>>()
+*/
+
+TQTextStream &operator<<( TQTextStream &ts, const TQDockArea &dockArea )
+{
+ TQString str;
+ TQPtrList<TQDockWindow> l = dockArea.dockWindowList();
+
+ for ( TQDockWindow *dw = l.first(); dw; dw = l.next() )
+ str += "[" + TQString( dw->caption() ) + "," + TQString::number( (int)dw->offset() ) +
+ "," + TQString::number( (int)dw->newLine() ) + "," + TQString::number( dw->fixedExtent().width() ) +
+ "," + TQString::number( dw->fixedExtent().height() ) + "," + TQString::number( (int)!dw->isHidden() ) + "]";
+ ts << str << endl;
+
+ return ts;
+}
+
+/*!
+ \relates TQDockArea
+
+ Reads the tqlayout description of the dock windows in dock area \a
+ dockArea from the text stream \a ts and restores it. The tqlayout
+ description must have been previously written by the operator<<()
+ function.
+
+ \sa operator<<()
+*/
+
+TQTextStream &operator>>( TQTextStream &ts, TQDockArea &dockArea )
+{
+ TQString s = ts.readLine();
+
+ TQString name, offset, newLine, width, height, visible;
+
+ enum State { Pre, Name, Offset, NewLine, Width, Height, Visible, Post };
+ int state = Pre;
+ TQChar c;
+ TQPtrList<TQDockWindow> l = dockArea.dockWindowList();
+
+ for ( int i = 0; i < (int)s.length(); ++i ) {
+ c = s[ i ];
+ if ( state == Pre && c == '[' ) {
+ state++;
+ continue;
+ }
+ if ( c == ',' &&
+ ( state == Name || state == Offset || state == NewLine || state == Width || state == Height ) ) {
+ state++;
+ continue;
+ }
+ if ( state == Visible && c == ']' ) {
+ for ( TQDockWindow *dw = l.first(); dw; dw = l.next() ) {
+ if ( TQString( dw->caption() ) == name ) {
+ dw->setNewLine( (bool)newLine.toInt() );
+ dw->setOffset( offset.toInt() );
+ dw->setFixedExtentWidth( width.toInt() );
+ dw->setFixedExtentHeight( height.toInt() );
+ if ( !(bool)visible.toInt() )
+ dw->hide();
+ else
+ dw->show();
+ break;
+ }
+ }
+
+ name = offset = newLine = width = height = visible = "";
+
+ state = Pre;
+ continue;
+ }
+ if ( state == Name )
+ name += c;
+ else if ( state == Offset )
+ offset += c;
+ else if ( state == NewLine )
+ newLine += c;
+ else if ( state == Width )
+ width += c;
+ else if ( state == Height )
+ height += c;
+ else if ( state == Visible )
+ visible += c;
+ }
+
+ dockArea.TQWidget::tqlayout()->tqinvalidate();
+ dockArea.TQWidget::tqlayout()->activate();
+ return ts;
+}
+#endif
+
+#endif //TQT_NO_MAINWINDOW
diff --git a/tqtinterface/qt4/src/widgets/tqdockarea.h b/tqtinterface/qt4/src/widgets/tqdockarea.h
new file mode 100644
index 0000000..34c2a50
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqdockarea.h
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Definition of the TQDockArea class
+**
+** Created : 001010
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the workspace module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDOCKAREA_H
+#define TQDOCKAREA_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqptrlist.h"
+#include "tqdockwindow.h"
+#include "tqlayout.h"
+#include "tqvaluelist.h"
+#include "tqguardedptr.h"
+#include "tqtextstream.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_MAINWINDOW
+
+class TQSplitter;
+class TQBoxLayout;
+class TQDockAreaLayout;
+class TQMouseEvent;
+class TQDockWindowResizeHandle;
+class TQDockAreaPrivate;
+
+class TQ_EXPORT TQDockAreaLayout : public TQLayout
+{
+ Q_OBJECT
+ TQ_OBJECT
+ friend class TQDockArea;
+
+public:
+ TQDockAreaLayout( TQWidget* tqparent, Orientation o, TQPtrList<TQDockWindow> *wl, int space = -1, int margin = -1, const char *name = 0 )
+ : TQLayout( tqparent, space, margin, name ), orient( o ), dockWindows( wl ), parentWidget( tqparent ) { init(); }
+ ~TQDockAreaLayout() {}
+
+ void addItem( QLayoutItem * ) {}
+ bool hasHeightForWidth() const;
+ int heightForWidth( int ) const;
+ int widthForHeight( int ) const;
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSize() const;
+ TQLayoutIterator iterator();
+ TQ_SPExpandData expandingDirections() const { return (Qt::Orientations)TQSizePolicy::NoDirection; } // [FIXME] Is this redefinition cast to Qt::Orientations correct?
+ void tqinvalidate();
+ Orientation orientation() const { return orient; }
+ TQValueList<TQRect> lineList() const { return lines; }
+ TQPtrList<TQDockWindow> lineStarts() const { return ls; }
+
+protected:
+ void setGeometry( const TQRect& );
+
+private:
+ void init();
+ int layoutItems( const TQRect&, bool testonly = FALSE );
+ Orientation orient;
+ bool dirty;
+ int cached_width, cached_height;
+ int cached_hfw, cached_wfh;
+ TQPtrList<TQDockWindow> *dockWindows;
+ TQWidget *parentWidget;
+ TQValueList<TQRect> lines;
+ TQPtrList<TQDockWindow> ls;
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQDockAreaLayout( const TQDockAreaLayout & );
+ TQDockAreaLayout &operator=( const TQDockAreaLayout & );
+#endif
+
+#ifdef USE_QT4
+
+ QLAYOUT_REQUIRED_METHOD_DECLARATIONS
+
+#endif // USE_QT4
+};
+
+class TQ_EXPORT TQDockArea : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( HandlePosition )
+ Q_PROPERTY( Orientation orientation READ orientation )
+ Q_PROPERTY( int count READ count )
+ Q_PROPERTY( bool empty READ isEmpty )
+ Q_PROPERTY( HandlePosition handlePosition READ handlePosition )
+
+ friend class TQDockWindow;
+ friend class TQDockWindowResizeHandle;
+ friend class TQDockAreaLayout;
+
+public:
+ enum HandlePosition { Normal, Reverse };
+
+ TQDockArea( Qt::Orientation o, HandlePosition h = Normal, TQWidget* tqparent=0, const char* name=0 );
+ ~TQDockArea();
+
+ void moveDockWindow( TQDockWindow *w, const TQPoint &globalPos, const TQRect &rect, bool swap );
+ void removeDockWindow( TQDockWindow *w, bool makeFloating, bool swap, bool fixNewLines = TRUE );
+ void moveDockWindow( TQDockWindow *w, int index = -1 );
+ bool hasDockWindow( TQDockWindow *w, int *index = 0 );
+
+ void invalidNextOffset( TQDockWindow *dw );
+
+ Qt::Orientation orientation() const { return orient; }
+ HandlePosition handlePosition() const { return hPos; }
+
+ bool eventFilter( TQObject *, TQEvent * );
+ bool isEmpty() const;
+ int count() const;
+ TQPtrList<TQDockWindow> dockWindowList() const;
+
+ bool isDockWindowAccepted( TQDockWindow *dw );
+ void setAcceptDockWindow( TQDockWindow *dw, bool accept );
+
+public Q_SLOTS:
+ void lineUp( bool keepNewLines );
+
+private:
+ struct DockWindowData
+ {
+ int index;
+ int offset;
+ int line;
+ TQSize fixedExtent;
+ TQGuardedPtr<TQDockArea> area;
+ };
+
+ int tqfindDockWindow( TQDockWindow *w );
+ int lineOf( int index );
+ DockWindowData *dockWindowData( TQDockWindow *w );
+ void dockWindow( TQDockWindow *dockWindow, DockWindowData *data );
+ void updateLayout();
+ void invalidateFixedSizes();
+ int maxSpace( int hint, TQDockWindow *dw );
+ void setFixedExtent( int d, TQDockWindow *dw );
+ bool isLastDockWindow( TQDockWindow *dw );
+
+private:
+ Qt::Orientation orient;
+ TQPtrList<TQDockWindow> *dockWindows;
+ TQDockAreaLayout *tqlayout;
+ HandlePosition hPos;
+ TQPtrList<TQDockWindow> forbiddenWidgets;
+ TQDockAreaPrivate *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQDockArea( const TQDockArea & );
+ TQDockArea& operator=( const TQDockArea & );
+#endif
+
+};
+
+#ifndef TQT_NO_TEXTSTREAM
+TQ_EXPORT TQTextStream &operator<<( TQTextStream &, const TQDockArea & );
+TQ_EXPORT TQTextStream &operator>>( TQTextStream &, TQDockArea & );
+#endif
+
+#define TQ_DEFINED_TQDOCKAREA
+#include "tqwinexport.h"
+#endif
+
+#endif //TQT_NO_MAINWINDOW
diff --git a/tqtinterface/qt4/src/widgets/tqdockwindow.cpp b/tqtinterface/qt4/src/widgets/tqdockwindow.cpp
new file mode 100644
index 0000000..e6e6f55
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqdockwindow.cpp
@@ -0,0 +1,2126 @@
+/****************************************************************************
+**
+** Implementation of the TQDockWindow class
+**
+** Created : 001010
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the workspace module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdockwindow.h"
+
+#ifndef TQT_NO_MAINWINDOW
+#include "tqdesktopwidget.h"
+#include "tqdockarea.h"
+#include "tqwidgetresizehandler_p.h"
+#include "tqtitlebar_p.h"
+#include "tqpainter.h"
+#include "tqapplication.h"
+#include "tqtoolbutton.h"
+#include "tqtoolbar.h"
+#include "tqlayout.h"
+#include "tqmainwindow.h"
+#include "tqtimer.h"
+#include "tqtooltip.h"
+#include "tqguardedptr.h"
+#include "tqcursor.h"
+#include "tqstyle.h"
+
+#if defined(TQ_WS_MAC9)
+#define MAC_DRAG_HACK
+#endif
+#ifdef TQ_WS_MACX
+static bool default_opaque = TRUE;
+#else
+static bool default_opaque = FALSE;
+#endif
+
+class TQDockWindowPrivate
+{
+};
+
+class TQDockWindowResizeHandle : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQDockWindowResizeHandle( Orientation o, TQWidget *tqparent, TQDockWindow *w, const char* /*name*/=0 );
+ void setOrientation( Orientation o );
+ Orientation orientation() const { return orient; }
+
+ TQSize tqsizeHint() const;
+
+protected:
+ void paintEvent( TQPaintEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+
+private:
+ void startLineDraw();
+ void endLineDraw();
+ void drawLine( const TQPoint &globalPos );
+
+private:
+ Orientation orient;
+ bool mousePressed;
+ TQPainter *unclippedPainter;
+ TQPoint lastPos, firstPos;
+ TQDockWindow *dockWindow;
+
+};
+
+TQDockWindowResizeHandle::TQDockWindowResizeHandle( Orientation o, TQWidget *tqparent,
+ TQDockWindow *w, const char * )
+ : TQWidget( tqparent, "qt_dockwidget_internal" ), mousePressed( FALSE ), unclippedPainter( 0 ), dockWindow( w )
+{
+ setOrientation( o );
+}
+
+TQSize TQDockWindowResizeHandle::tqsizeHint() const
+{
+ int sw = 2 * tqstyle().tqpixelMetric(TQStyle::PM_SplitterWidth, this) / 3;
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_DockWindow, this, TQSize(sw, sw)).
+ expandedTo(TQApplication::globalStrut()));
+}
+
+void TQDockWindowResizeHandle::setOrientation( Orientation o )
+{
+ orient = o;
+ if ( o == Qt::Horizontal ) {
+#ifndef TQT_NO_CURSOR
+ setCursor( Qt::SplitVCursor );
+#endif
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
+ } else {
+#ifndef TQT_NO_CURSOR
+ setCursor( Qt::SplitHCursor );
+#endif
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Expanding ) );
+ }
+}
+
+void TQDockWindowResizeHandle::mousePressEvent( TQMouseEvent *e )
+{
+ e->ignore();
+ if ( e->button() != Qt::LeftButton )
+ return;
+ e->accept();
+ mousePressed = TRUE;
+ if ( !dockWindow->opaqueMoving() )
+ startLineDraw();
+ lastPos = firstPos = e->globalPos();
+ if ( !dockWindow->opaqueMoving() )
+ drawLine( e->globalPos() );
+}
+
+void TQDockWindowResizeHandle::mouseMoveEvent( TQMouseEvent *e )
+{
+ if ( !mousePressed )
+ return;
+ if ( !dockWindow->opaqueMoving() ) {
+ if ( orientation() != dockWindow->area()->orientation() ) {
+ if ( orientation() == Qt::Horizontal ) {
+ int minpos = dockWindow->area()->mapToGlobal( TQPoint( 0, 0 ) ).y();
+ int maxpos = dockWindow->area()->mapToGlobal( TQPoint( 0, 0 ) ).y() + dockWindow->area()->height();
+ if ( e->globalPos().y() < minpos || e->globalPos().y() > maxpos )
+ return;
+ } else {
+ int minpos = dockWindow->area()->mapToGlobal( TQPoint( 0, 0 ) ).x();
+ int maxpos = dockWindow->area()->mapToGlobal( TQPoint( 0, 0 ) ).x() + dockWindow->area()->width();
+ if ( e->globalPos().x() < minpos || e->globalPos().x() > maxpos )
+ return;
+ }
+ } else {
+ TQWidget *w = dockWindow->area()->tqtopLevelWidget();
+ if ( w ) {
+ if ( orientation() == Qt::Horizontal ) {
+ int minpos = w->mapToGlobal( TQPoint( 0, 0 ) ).y();
+ int maxpos = w->mapToGlobal( TQPoint( 0, 0 ) ).y() + w->height();
+ if ( e->globalPos().y() < minpos || e->globalPos().y() > maxpos )
+ return;
+ } else {
+ int minpos = w->mapToGlobal( TQPoint( 0, 0 ) ).x();
+ int maxpos = w->mapToGlobal( TQPoint( 0, 0 ) ).x() + w->width();
+ if ( e->globalPos().x() < minpos || e->globalPos().x() > maxpos )
+ return;
+ }
+ }
+ }
+ }
+
+ if ( !dockWindow->opaqueMoving() )
+ drawLine( lastPos );
+ lastPos = e->globalPos();
+ if ( dockWindow->opaqueMoving() ) {
+ mouseReleaseEvent( e );
+ mousePressed = TRUE;
+ firstPos = e->globalPos();
+ }
+ if ( !dockWindow->opaqueMoving() )
+ drawLine( e->globalPos() );
+}
+
+void TQDockWindowResizeHandle::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( mousePressed ) {
+ if ( !dockWindow->opaqueMoving() ) {
+ drawLine( lastPos );
+ endLineDraw();
+ }
+ if ( orientation() != dockWindow->area()->orientation() )
+ dockWindow->area()->invalidNextOffset( dockWindow );
+ if ( orientation() == Qt::Horizontal ) {
+ int dy;
+ if ( dockWindow->area()->handlePosition() == TQDockArea::Normal || orientation() != dockWindow->area()->orientation() )
+ dy = e->globalPos().y() - firstPos.y();
+ else
+ dy = firstPos.y() - e->globalPos().y();
+ int d = dockWindow->height() + dy;
+ if ( orientation() != dockWindow->area()->orientation() ) {
+ dockWindow->setFixedExtentHeight( -1 );
+ d = TQMAX( d, dockWindow->minimumHeight() );
+ int ms = dockWindow->area()->maxSpace( d, dockWindow );
+ d = TQMIN( d, ms );
+ dockWindow->setFixedExtentHeight( d );
+ } else {
+ dockWindow->area()->setFixedExtent( d, dockWindow );
+ }
+ } else {
+ int dx;
+ if ( dockWindow->area()->handlePosition() == TQDockArea::Normal || orientation() != dockWindow->area()->orientation() )
+ dx = e->globalPos().x() - firstPos.x();
+ else
+ dx = firstPos.x() - e->globalPos().x();
+ int d = dockWindow->width() + dx;
+ if ( orientation() != dockWindow->area()->orientation() ) {
+ dockWindow->setFixedExtentWidth( -1 );
+ d = TQMAX( d, dockWindow->minimumWidth() );
+ int ms = dockWindow->area()->maxSpace( d, dockWindow );
+ d = TQMIN( d, ms );
+ dockWindow->setFixedExtentWidth( d );
+ } else {
+ dockWindow->area()->setFixedExtent( d, dockWindow );
+ }
+ }
+ }
+
+ TQApplication::postEvent( dockWindow->area(), new TQEvent( TQEvent::LayoutHint ) );
+ mousePressed = FALSE;
+}
+
+void TQDockWindowResizeHandle::paintEvent( TQPaintEvent * )
+{
+ TQPainter p( this );
+ tqstyle().tqdrawPrimitive(TQStyle::PE_DockWindowResizeHandle, &p, rect(), tqcolorGroup(),
+ (isEnabled() ?
+ TQStyle::Style_Enabled : TQStyle::Style_Default) |
+ (orientation() == Qt::Horizontal ?
+ TQStyle::Style_Horizontal : TQStyle::Style_Default ));
+}
+
+void TQDockWindowResizeHandle::startLineDraw()
+{
+ if ( unclippedPainter )
+ endLineDraw();
+#ifdef MAC_DRAG_HACK
+ TQWidget *paint_on = tqtopLevelWidget();
+#else
+ int scr = TQApplication::desktop()->screenNumber( this );
+ TQWidget *paint_on = TQT_TQWIDGET(TQApplication::desktop()->screen( scr ));
+#endif
+ unclippedPainter = new TQPainter( paint_on, TRUE );
+ unclippedPainter->setPen( TQPen( Qt::gray, orientation() == Qt::Horizontal ? height() : width() ) );
+ unclippedPainter->setRasterOp( TQt::XorROP );
+}
+
+void TQDockWindowResizeHandle::endLineDraw()
+{
+ if ( !unclippedPainter )
+ return;
+ delete unclippedPainter;
+ unclippedPainter = 0;
+}
+
+void TQDockWindowResizeHandle::drawLine( const TQPoint &globalPos )
+{
+#ifdef MAC_DRAG_HACK
+ TQPoint start = mapTo(tqtopLevelWidget(), TQPoint(0, 0));
+ TQPoint starta = dockWindow->area()->mapTo(tqtopLevelWidget(), TQPoint(0, 0));
+ TQPoint end = globalPos - tqtopLevelWidget()->pos();
+#else
+ TQPoint start = mapToGlobal( TQPoint( 0, 0 ) );
+ TQPoint starta = dockWindow->area()->mapToGlobal( TQPoint( 0, 0 ) );
+ TQPoint end = globalPos;
+#endif
+
+ if ( orientation() == Qt::Horizontal ) {
+ if ( orientation() == dockWindow->orientation() )
+ unclippedPainter->drawLine( starta.x() , end.y(), starta.x() + dockWindow->area()->width(), end.y() );
+ else
+ unclippedPainter->drawLine( start.x(), end.y(), start.x() + width(), end.y() );
+ } else {
+ if ( orientation() == dockWindow->orientation() )
+ unclippedPainter->drawLine( end.x(), starta.y(), end.x(), starta.y() + dockWindow->area()->height() );
+ else
+ unclippedPainter->drawLine( end.x(), start.y(), end.x(), start.y() + height() );
+ }
+}
+
+static TQPoint realWidgetPos( TQDockWindow *w )
+{
+ if ( !w->parentWidget() || w->place() == TQDockWindow::OutsideDock )
+ return w->pos();
+ return w->parentWidget()->mapToGlobal( w->tqgeometry().topLeft() );
+}
+
+class TQDockWindowHandle : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( TQString caption READ caption )
+ friend class TQDockWindow;
+ friend class TQDockWindowTitleBar;
+
+public:
+ TQDockWindowHandle( TQDockWindow *dw );
+ void updateGui();
+
+ TQSize tqminimumSizeHint() const;
+ TQSize tqminimumSize() const { return tqminimumSizeHint(); }
+ TQSize tqsizeHint() const { return tqminimumSize(); }
+ TQSizePolicy sizePolicy() const;
+ void setOpaqueMoving( bool b ) { opaque = b; }
+
+ TQString caption() const { return dockWindow->caption(); }
+
+Q_SIGNALS:
+ void doubleClicked();
+
+protected:
+ void paintEvent( TQPaintEvent *e );
+ void resizeEvent( TQResizeEvent *e );
+ void mousePressEvent( TQMouseEvent *e );
+ void mouseMoveEvent( TQMouseEvent *e );
+ void mouseReleaseEvent( TQMouseEvent *e );
+ void mouseDoubleClickEvent( TQMouseEvent *e );
+ void keyPressEvent( TQKeyEvent *e );
+ void keyReleaseEvent( TQKeyEvent *e );
+#ifndef TQT_NO_STYLE
+ void styleChange( TQStyle& );
+#endif
+
+private Q_SLOTS:
+ void minimize();
+
+private:
+ TQDockWindow *dockWindow;
+ TQPoint offset;
+ TQToolButton *closeButton;
+ TQTimer *timer;
+ uint opaque : 1;
+ uint mousePressed : 1;
+ uint hadDblClick : 1;
+ uint ctrlDown : 1;
+ TQGuardedPtr<TQWidget> oldFocus;
+};
+
+class TQDockWindowTitleBar : public TQTitleBar
+{
+ Q_OBJECT
+ TQ_OBJECT
+ friend class TQDockWindow;
+ friend class TQDockWindowHandle;
+
+public:
+ TQDockWindowTitleBar( TQDockWindow *dw );
+ void updateGui();
+ void setOpaqueMoving( bool b ) { opaque = b; }
+
+protected:
+ void resizeEvent( TQResizeEvent *e );
+ void mousePressEvent( TQMouseEvent *e );
+ void mouseMoveEvent( TQMouseEvent *e );
+ void mouseReleaseEvent( TQMouseEvent *e );
+ void mouseDoubleClickEvent( TQMouseEvent *e );
+ void keyPressEvent( TQKeyEvent *e );
+ void keyReleaseEvent( TQKeyEvent *e );
+
+private:
+ TQDockWindow *dockWindow;
+ TQPoint offset;
+ uint mousePressed : 1;
+ uint hadDblClick : 1;
+ uint opaque : 1;
+ uint ctrlDown : 1;
+ TQGuardedPtr<TQWidget> oldFocus;
+
+};
+
+TQDockWindowHandle::TQDockWindowHandle( TQDockWindow *dw )
+ : TQWidget( dw, "qt_dockwidget_internal", TQt::WNoAutoErase ), dockWindow( dw ),
+ closeButton( 0 ), opaque( default_opaque ), mousePressed( FALSE )
+{
+ ctrlDown = FALSE;
+ timer = new TQTimer( this );
+ connect( timer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( minimize() ) );
+#ifdef TQ_WS_WIN
+ setCursor( SizeAllCursor );
+#endif
+}
+
+void TQDockWindowHandle::paintEvent( TQPaintEvent *e )
+{
+ if ( (!dockWindow->dockArea || mousePressed) && !opaque )
+ return;
+ erase();
+ TQPainter p( this );
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if ( isEnabled() )
+ flags |= TQStyle::Style_Enabled;
+ if ( !dockWindow->area() || dockWindow->area()->orientation() == Qt::Horizontal )
+ flags |= TQStyle::Style_Horizontal;
+
+ tqstyle().tqdrawPrimitive( TQStyle::PE_DockWindowHandle, &p,
+ TQStyle::tqvisualRect( tqstyle().subRect( TQStyle::SR_DockWindowHandleRect,
+ this ), this ),
+ tqcolorGroup(), flags );
+ TQWidget::paintEvent( e );
+}
+
+void TQDockWindowHandle::keyPressEvent( TQKeyEvent *e )
+{
+ if ( !mousePressed )
+ return;
+ if ( e->key() == Qt::Key_Control ) {
+ ctrlDown = TRUE;
+ dockWindow->handleMove( mapFromGlobal(TQCursor::pos()) - offset, TQCursor::pos(), !opaque );
+ }
+}
+
+void TQDockWindowHandle::keyReleaseEvent( TQKeyEvent *e )
+{
+ if ( !mousePressed )
+ return;
+ if ( e->key() == Qt::Key_Control ) {
+ ctrlDown = FALSE;
+ dockWindow->handleMove( mapFromGlobal(TQCursor::pos()) - offset, TQCursor::pos(), !opaque );
+ }
+}
+
+void TQDockWindowHandle::mousePressEvent( TQMouseEvent *e )
+{
+ if ( !dockWindow->dockArea )
+ return;
+ ctrlDown = ( e->state() & ControlButton ) == ControlButton;
+ oldFocus = tqApp->tqfocusWidget();
+ setFocus();
+ e->ignore();
+ if ( e->button() != Qt::LeftButton )
+ return;
+ e->accept();
+ hadDblClick = FALSE;
+ mousePressed = TRUE;
+ offset = e->pos();
+ dockWindow->startRectDraw( mapToGlobal( e->pos() ), !opaque );
+ if ( !opaque )
+ tqApp->installEventFilter( dockWindow );
+}
+
+void TQDockWindowHandle::mouseMoveEvent( TQMouseEvent *e )
+{
+ if ( !mousePressed || e->pos() == offset )
+ return;
+ ctrlDown = ( e->state() & ControlButton ) == ControlButton;
+ dockWindow->handleMove( e->pos() - offset, e->globalPos(), !opaque );
+ if ( opaque )
+ dockWindow->updatePosition( e->globalPos() );
+}
+
+void TQDockWindowHandle::mouseReleaseEvent( TQMouseEvent *e )
+{
+ ctrlDown = FALSE;
+ tqApp->removeEventFilter( dockWindow );
+ if ( oldFocus )
+ oldFocus->setFocus();
+ if ( !mousePressed )
+ return;
+ dockWindow->endRectDraw( !opaque );
+ mousePressed = FALSE;
+#ifdef TQ_WS_MAC
+ releaseMouse();
+#endif
+ if ( !hadDblClick && offset == e->pos() ) {
+ timer->start( TQApplication::doubleClickInterval(), TRUE );
+ } else if ( !hadDblClick ) {
+ dockWindow->updatePosition( e->globalPos() );
+ }
+ if ( opaque )
+ dockWindow->titleBar->mousePressed = FALSE;
+}
+
+void TQDockWindowHandle::minimize()
+{
+ if ( !dockWindow->area() )
+ return;
+
+ TQMainWindow *mw = ::tqqt_cast<TQMainWindow*>(dockWindow->area()->parentWidget());
+ if ( mw && mw->isDockEnabled( dockWindow, TQt::DockMinimized ) )
+ mw->moveDockWindow( dockWindow, TQt::DockMinimized );
+}
+
+void TQDockWindowHandle::resizeEvent( TQResizeEvent * )
+{
+ updateGui();
+}
+
+void TQDockWindowHandle::updateGui()
+{
+ if ( !closeButton ) {
+ closeButton = new TQToolButton( this, "qt_close_button1" );
+#ifndef TQT_NO_CURSOR
+ closeButton->setCursor( Qt::ArrowCursor );
+#endif
+ closeButton->setPixmap( tqstyle().stylePixmap( TQStyle::SP_DockWindowCloseButton, closeButton ) );
+ closeButton->setFixedSize( 12, 12 );
+ connect( closeButton, TQT_SIGNAL( clicked() ),
+ dockWindow, TQT_SLOT( hide() ) );
+ }
+
+ if ( dockWindow->isCloseEnabled() && dockWindow->area() )
+ closeButton->show();
+ else
+ closeButton->hide();
+
+ if ( !dockWindow->area() )
+ return;
+
+ if ( dockWindow->area()->orientation() == Qt::Horizontal ) {
+ int off = ( width() - closeButton->width() - 1 ) / 2;
+ closeButton->move( off, 2 );
+ } else {
+ int off = ( height() - closeButton->height() - 1 ) / 2;
+ int x = TQApplication::reverseLayout() ? 2 : width() - closeButton->width() - 2;
+ closeButton->move( x, off );
+ }
+}
+
+#ifndef TQT_NO_STYLE
+void TQDockWindowHandle::styleChange( TQStyle& )
+{
+ if ( closeButton )
+ closeButton->setPixmap( tqstyle().stylePixmap( TQStyle::SP_DockWindowCloseButton, closeButton ) );
+}
+#endif
+
+TQSize TQDockWindowHandle::tqminimumSizeHint() const
+{
+ if ( !dockWindow->dockArea )
+ return TQSize( 0, 0 );
+ int wh = dockWindow->isCloseEnabled() ? 17 : tqstyle().tqpixelMetric( TQStyle::PM_DockWindowHandleExtent, this );
+ if ( dockWindow->orientation() == Qt::Horizontal )
+ return TQSize( wh, 0 );
+ return TQSize( 0, wh );
+}
+
+TQSizePolicy TQDockWindowHandle::sizePolicy() const
+{
+ if ( dockWindow->orientation() != Qt::Horizontal )
+ return TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed );
+ return TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Preferred );
+}
+
+void TQDockWindowHandle::mouseDoubleClickEvent( TQMouseEvent *e )
+{
+ e->ignore();
+ if ( e->button() != Qt::LeftButton )
+ return;
+ e->accept();
+ timer->stop();
+ emit doubleClicked();
+ hadDblClick = TRUE;
+}
+
+TQDockWindowTitleBar::TQDockWindowTitleBar( TQDockWindow *dw )
+ : TQTitleBar( 0, dw, "qt_dockwidget_internal" ), dockWindow( dw ),
+ mousePressed( FALSE ), hadDblClick( FALSE ), opaque( default_opaque )
+{
+ setWFlags( getWFlags() | TQt::WStyle_Tool );
+ ctrlDown = FALSE;
+ setMouseTracking( TRUE );
+ setFixedHeight( tqstyle().tqpixelMetric( TQStyle::PM_TitleBarHeight, this ) );
+ connect( this, TQT_SIGNAL(doClose()), dockWindow, TQT_SLOT(hide()) );
+}
+
+void TQDockWindowTitleBar::keyPressEvent( TQKeyEvent *e )
+{
+ if ( !mousePressed )
+ return;
+ if ( e->key() == Qt::Key_Control ) {
+ ctrlDown = TRUE;
+ dockWindow->handleMove( mapFromGlobal( TQCursor::pos() ) - offset, TQCursor::pos(), !opaque );
+ }
+}
+
+void TQDockWindowTitleBar::keyReleaseEvent( TQKeyEvent *e )
+{
+ if ( !mousePressed )
+ return;
+ if ( e->key() == Qt::Key_Control ) {
+ ctrlDown = FALSE;
+ dockWindow->handleMove( mapFromGlobal( TQCursor::pos() ) - offset, TQCursor::pos(), !opaque );
+ }
+}
+
+void TQDockWindowTitleBar::mousePressEvent( TQMouseEvent *e )
+{
+ TQStyle::SubControl tbctrl = tqstyle().querySubControl( TQStyle::CC_TitleBar, this, e->pos() );
+ if ( tbctrl > TQStyle::SC_TitleBarLabel ) {
+ TQTitleBar::mousePressEvent( e );
+ return;
+ }
+
+ ctrlDown = ( e->state() & ControlButton ) == ControlButton;
+ oldFocus = tqApp->tqfocusWidget();
+// setFocus activates the window, which deactivates the main window
+// not what we want, and not required anyway on Windows
+#ifndef TQ_WS_WIN
+ setFocus();
+#endif
+
+ e->ignore();
+ if ( e->button() != Qt::LeftButton )
+ return;
+ if ( e->y() < 3 && dockWindow->isResizeEnabled() )
+ return;
+
+ e->accept();
+ bool oldPressed = mousePressed;
+ mousePressed = TRUE;
+ hadDblClick = FALSE;
+ offset = e->pos();
+ dockWindow->startRectDraw( mapToGlobal( e->pos() ), !opaque );
+// grabMouse resets the Windows mouse press count, so we never receive a double click on Windows
+// not required on Windows, and did work on X11, too, but no problem there in the first place
+#ifndef TQ_WS_WIN
+ if(!oldPressed && dockWindow->opaqueMoving())
+ grabMouse();
+#else
+ TQ_UNUSED( oldPressed );
+#endif
+}
+
+void TQDockWindowTitleBar::mouseMoveEvent( TQMouseEvent *e )
+{
+ if ( !mousePressed ) {
+ TQTitleBar::mouseMoveEvent( e );
+ return;
+ }
+
+ ctrlDown = ( e->state() & ControlButton ) == ControlButton;
+ e->accept();
+ dockWindow->handleMove( e->pos() - offset, e->globalPos(), !opaque );
+}
+
+void TQDockWindowTitleBar::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( !mousePressed ) {
+ TQTitleBar::mouseReleaseEvent( e );
+ return;
+ }
+
+ ctrlDown = FALSE;
+ tqApp->removeEventFilter( dockWindow );
+ if ( oldFocus )
+ oldFocus->setFocus();
+
+ if ( dockWindow->place() == TQDockWindow::OutsideDock )
+ dockWindow->raise();
+
+ if(dockWindow->opaqueMoving())
+ releaseMouse();
+ if ( !mousePressed )
+ return;
+ dockWindow->endRectDraw( !opaque );
+ mousePressed = FALSE;
+ if ( !hadDblClick )
+ dockWindow->updatePosition( e->globalPos() );
+ if ( opaque ) {
+ dockWindow->horHandle->mousePressed = FALSE;
+ dockWindow->verHandle->mousePressed = FALSE;
+ }
+}
+
+void TQDockWindowTitleBar::resizeEvent( TQResizeEvent *e )
+{
+ updateGui();
+ TQTitleBar::resizeEvent( e );
+}
+
+void TQDockWindowTitleBar::updateGui()
+{
+ if ( dockWindow->isCloseEnabled() ) {
+ setWFlags( getWFlags() | TQt::WStyle_SysMenu );
+ } else {
+ setWFlags( getWFlags() & ~TQt::WStyle_SysMenu );
+ }
+}
+
+void TQDockWindowTitleBar::mouseDoubleClickEvent( TQMouseEvent * )
+{
+ emit doubleClicked();
+ hadDblClick = TRUE;
+}
+
+/*!
+ \class TQDockWindow tqdockwindow.h
+ \brief The TQDockWindow class provides a widget which can be docked
+ inside a TQDockArea or floated as a top level window on the
+ desktop.
+
+ \ingroup application
+ \mainclass
+
+ This class handles moving, resizing, docking and undocking dock
+ windows. TQToolBar is a subclass of TQDockWindow so the
+ functionality provided for dock windows is available with the same
+ API for toolbars.
+
+ \img qmainwindow-qdockareas.png TQDockWindows in a TQDockArea
+ \caption Two TQDockWindows (\l{TQToolBar}s) in a \l TQDockArea
+
+ \img qdockwindow.png A TQDockWindow
+ \caption A Floating TQDockWindow
+
+ If the user drags the dock window into the dock area the dock
+ window will be docked. If the user drags the dock area outside any
+ dock areas the dock window will be undocked (floated) and will
+ become a top level window. Double clicking a floating dock
+ window's titlebar will dock the dock window to the last dock area
+ it was docked in. Double clicking a docked dock window's handle
+ will undock (float) the dock window.
+ \omit
+ Single clicking a docked dock window's handle will minimize the
+ dock window (only its handle will appear, below the menu bar).
+ Single clicking the minimized handle will restore the dock window
+ to the last dock area that it was docked in.
+ \endomit
+ If the user clicks the close button (which does not appear on
+ dock windows by default - see \l closeMode) the dock window will
+ disappear. You can control whether or not a dock window has a
+ close button with setCloseMode().
+
+ TQMainWindow provides four dock areas (top, left, right and bottom)
+ which can be used by dock windows. For many applications using the
+ dock areas provided by TQMainWindow is sufficient. (See the \l
+ TQDockArea documentation if you want to create your own dock
+ areas.) In TQMainWindow a right-click popup menu (the dock window
+ menu) is available which lists dock windows and can be used to
+ show or hide them. (The popup menu only lists dock windows that
+ have a \link setCaption() caption\endlink.)
+
+ When you construct a dock window you \e must pass it a TQDockArea
+ or a TQMainWindow as its tqparent if you want it docked. Pass 0 for
+ the tqparent if you want it floated.
+
+ \code
+ TQToolBar *fileTools = new TQToolBar( this, "File Actions" );
+ moveDockWindow( fileTools, Left );
+ \endcode
+
+ In the example above we create a new TQToolBar in the constructor
+ of a TQMainWindow subclass (so that the \e this pointer points to
+ the TQMainWindow). By default the toolbar will be added to the \c
+ Top dock area, but we've moved it to the \c Left dock area.
+
+ A dock window is often used to contain a single widget. In these
+ cases the widget can be set by calling setWidget(). If you're
+ constructing a dock window that tqcontains multiple widgets, e.g. a
+ toolbar, arrange the widgets within a box tqlayout inside the dock
+ window. To do this use the boxLayout() function to get a pointer
+ to the dock window's box tqlayout, then add widgets to the tqlayout
+ using the box tqlayout's TQBoxLayout::addWidget() function. The dock
+ window will dynamically set the orientation of the tqlayout to be
+ vertical or horizontal as necessary, although you can control this
+ yourself with setOrientation().
+
+ Although a common use of dock windows is for toolbars, they can be
+ used with any widgets. (See the \link designer-manual.book TQt
+ Designer\endlink and \link linguist-manual.book TQt
+ Linguist\endlink applications, for example.) When using larger
+ widgets it may make sense for the dock window to be resizable by
+ calling setResizeEnabled(). Resizable dock windows are given
+ splitter-like handles to allow the user to resize them within
+ their dock area. When resizable dock windows are undocked they
+ become top level windows and can be resized like any other top
+ level windows, e.g. by dragging a corner or edge.
+
+ Dock windows can be docked and undocked using dock() and undock().
+ A dock window's orientation can be set with setOrientation(). You
+ can also use TQDockArea::moveDockWindow(). If you're using a
+ TQMainWindow, TQMainWindow::moveDockWindow() and
+ TQMainWindow::removeDockWindow() are available.
+
+ A dock window can have some preferred settings, for example, you
+ can set a preferred offset from the left edge (or top edge for
+ vertical dock areas) of the dock area using setOffset(). If you'd
+ prefer a dock window to start on a new \link tqdockarea.html#lines
+ line\endlink when it is docked use setNewLine(). The
+ setFixedExtentWidth() and setFixedExtentHeight() functions can be
+ used to define the dock window's preferred size, and the
+ setHorizontallyStretchable() and setVerticallyStretchable()
+ functions set whether the dock window can be stretched or not.
+ Dock windows can be moved by default, but this can be changed with
+ setMovingEnabled(). When a dock window is moved it is shown as a
+ rectangular outline, but it can be shown normally using
+ setOpaqueMoving().
+
+ When a dock window's visibility changes, i.e. it is shown or
+ hidden, the visibilityChanged() signal is emitted. When a dock
+ window is docked, undocked or moved inside the dock area the
+ placeChanged() signal is emitted.
+*/
+
+/*!
+ \enum TQDockWindow::Place
+
+ This enum specifies the possible locations for a TQDockWindow:
+
+ \value InDock Inside a TQDockArea.
+ \value OutsideDock Floating as a top level window on the desktop.
+*/
+
+/*!
+ \enum TQDockWindow::CloseMode
+
+ This enum type specifies when (if ever) a dock window has a close
+ button.
+
+ \value Never The dock window never has a close button and cannot
+ be closed by the user.
+ \value Docked The dock window has a close button only when
+ docked.
+ \value Undocked The dock window has a close button only when
+ floating.
+ \value Always The dock window always has a close button.
+ \omit
+ Note that dock windows can always be minimized if the user clicks
+ their dock window handle when they are docked.
+ \endomit
+*/
+
+/*!
+ \fn void TQDockWindow::setHorizontalStretchable( bool b )
+ \obsolete
+*/
+/*!
+ \fn void TQDockWindow::setVerticalStretchable( bool b )
+ \obsolete
+*/
+/*!
+ \fn bool TQDockWindow::isHorizontalStretchable() const
+ \obsolete
+*/
+/*!
+ \fn bool TQDockWindow::isVerticalStretchable() const
+ \obsolete
+*/
+/*!
+ \fn void TQDockWindow::orientationChanged( Orientation o )
+
+ This signal is emitted when the orientation of the dock window is
+ changed. The new orientation is \a o.
+*/
+
+/*!
+ \fn void TQDockWindow::placeChanged( TQDockWindow::Place p )
+
+ This signal is emitted when the dock window is docked (\a p is \c
+ InDock), undocked (\a p is \c OutsideDock) or moved inside the
+ the dock area.
+
+ \sa TQDockArea::moveDockWindow(), TQDockArea::removeDockWindow(),
+ TQMainWindow::moveDockWindow(), TQMainWindow::removeDockWindow()
+*/
+
+/*!
+ \fn void TQDockWindow::visibilityChanged( bool visible )
+
+ This signal is emitted when the visibility of the dock window
+ relatively to its dock area is changed. If \a visible is TRUE, the
+ TQDockWindow is now visible to the dock area, otherwise it has been
+ hidden.
+
+ A dock window can be hidden if it has a close button which the
+ user has clicked. In the case of a TQMainWindow a dock window can
+ have its visibility changed (hidden or shown) by clicking its name
+ in the dock window menu that lists the TQMainWindow's dock windows.
+*/
+
+/*!
+ \fn TQDockArea *TQDockWindow::area() const
+
+ Returns the dock area in which this dock window is docked, or 0 if
+ the dock window is floating.
+*/
+
+// DOC: Can't use \property 'cos it thinks the thing returns a bool.
+/*!
+ \fn Place TQDockWindow::place() const
+
+ This function returns where the dock window is placed. This is
+ either \c InDock or \c OutsideDock.
+
+ \sa TQDockArea::moveDockWindow(), TQDockArea::removeDockWindow(),
+ TQMainWindow::moveDockWindow(), TQMainWindow::removeDockWindow()
+*/
+
+
+/*!
+ Constructs a TQDockWindow with tqparent \a tqparent, called \a name and
+ with widget flags \a f.
+*/
+
+TQDockWindow::TQDockWindow( TQWidget* tqparent, const char* name, WFlags f )
+ : TQFrame( tqparent, name, (WFlags)(f | TQt::WType_Dialog | WStyle_Customize | TQt::WStyle_NoBorder) )
+{
+ curPlace = InDock;
+ isToolbar = FALSE;
+ init();
+}
+
+/*!
+ Constructs a TQDockWindow with tqparent \a tqparent, called \a name and
+ with widget flags \a f.
+
+ If \a p is \c InDock, the dock window is docked into a dock area
+ and \a tqparent \e must be a TQDockArea or a TQMainWindow. If the \a
+ tqparent is a TQMainWindow the dock window will be docked in the main
+ window's \c Top dock area.
+
+ If \a p is \c OutsideDock, the dock window is created as a floating
+ window.
+
+ We recommend creating the dock area \c InDock with a TQMainWindow
+ as tqparent then calling TQMainWindow::moveDockWindow() to move the
+ dock window where you want it.
+*/
+
+TQDockWindow::TQDockWindow( Place p, TQWidget *tqparent, const char *name, WFlags f )
+ : TQFrame( tqparent, name, (WFlags)(f | TQt::WType_Dialog | WStyle_Customize | TQt::WStyle_NoBorder) )
+{
+ curPlace = p;
+ isToolbar = FALSE;
+ init();
+}
+
+/*! \internal
+*/
+
+TQDockWindow::TQDockWindow( Place p, TQWidget *tqparent, const char *name, WFlags f, bool toolbar )
+ : TQFrame( tqparent, name, (WFlags)(f | TQt::WType_Dialog | WStyle_Customize | TQt::WStyle_NoBorder) )
+{
+ curPlace = p;
+ isToolbar = toolbar;
+ init();
+}
+
+class TQDockWindowGridLayout : public TQGridLayout
+{
+public:
+ TQDockWindowGridLayout( TQWidget *tqparent, int nRows, int nCols )
+ : TQGridLayout( tqparent, nRows, nCols ) {};
+
+ TQ_SPExpandData expandingDirections() const
+ {
+ return (Qt::Orientations)TQSizePolicy::NoDirection;
+ }
+};
+
+void TQDockWindow::init()
+{
+ wid = 0;
+ unclippedPainter = 0;
+ dockArea = 0;
+ tmpDockArea = 0;
+ resizeEnabled = FALSE;
+ moveEnabled = TRUE;
+ nl = FALSE;
+ opaque = default_opaque;
+ cMode = Never;
+ offs = 0;
+ fExtent = TQSize( -1, -1 );
+ dockWindowData = 0;
+ lastPos = TQPoint( -1, -1 );
+ lastSize = TQSize( -1, -1 );
+
+ widgetResizeHandler = new TQWidgetResizeHandler( this );
+ widgetResizeHandler->setMovingEnabled( FALSE );
+
+ titleBar = new TQDockWindowTitleBar( this );
+ verHandle = new TQDockWindowHandle( this );
+ horHandle = new TQDockWindowHandle( this );
+
+ vHandleLeft = new TQDockWindowResizeHandle( Qt::Vertical, this, this, "vert. handle" );
+ vHandleRight = new TQDockWindowResizeHandle( Qt::Vertical, this, this, "vert. handle" );
+ hHandleTop = new TQDockWindowResizeHandle( Qt::Horizontal, this, this, "horz. handle" );
+ hHandleBottom = new TQDockWindowResizeHandle( Qt::Horizontal, this, this, "horz. handle" );
+
+ // Creating inner tqlayout
+ hbox = new TQVBoxLayout();
+ vbox = new TQHBoxLayout();
+ childBox = new TQBoxLayout(TQBoxLayout::LeftToRight);
+ vbox->addWidget( verHandle );
+ vbox->addLayout( childBox );
+
+ hbox->setResizeMode( TQLayout::FreeResize );
+ hbox->setMargin( isResizeEnabled() || curPlace == OutsideDock ? 2 : 0 );
+ hbox->setSpacing( 1 );
+ hbox->addWidget( titleBar );
+ hbox->addWidget( horHandle );
+ hbox->addLayout( vbox );
+
+ // Set up the initial handle tqlayout for Qt::Vertical
+ // Handle tqlayout will change on calls to setOrienation()
+ TQGridLayout *gtqlayout = new TQDockWindowGridLayout( this, 3, 3 );
+ gtqlayout->setResizeMode( TQLayout::Minimum );
+ gtqlayout->addMultiCellWidget( hHandleTop, 0, 0, 1, 1 );
+ gtqlayout->addMultiCellWidget( hHandleBottom, 2, 2, 1, 1 );
+ gtqlayout->addMultiCellWidget( vHandleLeft, 0, 2, 0, 0 );
+ gtqlayout->addMultiCellWidget( vHandleRight, 0, 2, 2, 2 );
+ gtqlayout->addLayout( hbox, 1, 1 );
+ gtqlayout->setRowStretch( 1, 1 );
+ gtqlayout->setColStretch( 1, 1 );
+
+ hHandleBottom->hide();
+ vHandleRight->hide();
+ hHandleTop->hide();
+ vHandleLeft->hide();
+ setFrameStyle( TQFrame::StyledPanel | TQFrame::Raised );
+ setLineWidth( 2 );
+
+ if ( parentWidget() )
+ parentWidget()->installEventFilter( this );
+ TQWidget *mw = parentWidget();
+ TQDockArea *da = ::tqqt_cast<TQDockArea*>(parentWidget());
+ if ( da ) {
+ if ( curPlace == InDock )
+ da->moveDockWindow( this );
+ mw = da->parentWidget();
+ }
+ if ( ::tqqt_cast<TQMainWindow*>(mw) ) {
+ if ( place() == InDock ) {
+ TQt::Dock myDock = TQt::DockTop;
+ // make sure we put the window in the correct dock.
+ if ( dockArea ) {
+ TQMainWindow *mainw = (TQMainWindow*)mw;
+ // I'm not checking if it matches the top because I've
+ // done the assignment to it above.
+ if ( dockArea == mainw->leftDock() )
+ myDock = TQt::DockLeft;
+ else if ( dockArea == mainw->rightDock() )
+ myDock = TQt::DockRight;
+ else if ( dockArea == mainw->bottomDock() )
+ myDock = TQt::DockBottom;
+ }
+ ( (TQMainWindow*)mw )->addDockWindow( this, myDock );
+ }
+ moveEnabled = ((TQMainWindow*)mw)->dockWindowsMovable();
+ opaque = ((TQMainWindow*)mw)->opaqueMoving();
+ }
+
+ updateGui();
+ stretchable[ Qt::Horizontal ] = FALSE;
+ stretchable[ Qt::Vertical ] = FALSE;
+
+ connect( titleBar, TQT_SIGNAL( doubleClicked() ), this, TQT_SLOT( dock() ) );
+ connect( verHandle, TQT_SIGNAL( doubleClicked() ), this, TQT_SLOT( undock() ) );
+ connect( horHandle, TQT_SIGNAL( doubleClicked() ), this, TQT_SLOT( undock() ) );
+ connect( this, TQT_SIGNAL( orientationChanged(Orientation) ),
+ this, TQT_SLOT( setOrientation(Orientation) ) );
+}
+
+/*!
+ Sets the orientation of the dock window to \a o. The orientation
+ is propagated to the tqlayout boxLayout().
+
+ \warning All undocked TQToolBars will always have a horizontal orientation.
+*/
+
+void TQDockWindow::setOrientation( Qt::Orientation o )
+{
+ TQGridLayout *gtqlayout = (TQGridLayout*)tqlayout();
+ gtqlayout->remove( hHandleTop );
+ gtqlayout->remove( hHandleBottom );
+ gtqlayout->remove( vHandleLeft );
+ gtqlayout->remove( vHandleRight );
+
+ if ( o == Qt::Horizontal ) {
+ // Set up the new tqlayout as
+ // 3 3 3 1 = vHandleLeft 4 = hHandleBottom
+ // 1 X 2 2 = vHandleRight X = Inner Layout
+ // 4 4 4 3 = hHandleTop
+ gtqlayout->addMultiCellWidget( hHandleTop, 0, 0, 0, 2 );
+ gtqlayout->addMultiCellWidget( hHandleBottom, 2, 2, 0, 2 );
+ gtqlayout->addMultiCellWidget( vHandleLeft, 1, 1, 0, 0 );
+ gtqlayout->addMultiCellWidget( vHandleRight, 1, 1, 2, 2 );
+ } else {
+ // Set up the new tqlayout as
+ // 1 3 2 1 = vHandleLeft 4 = hHandleBottom
+ // 1 X 2 2 = vHandleRight X = Inner Layout
+ // 1 4 2 3 = hHandleTop
+ gtqlayout->addMultiCellWidget( hHandleTop, 0, 0, 1, 1 );
+ gtqlayout->addMultiCellWidget( hHandleBottom, 2, 2, 1, 1 );
+ gtqlayout->addMultiCellWidget( vHandleLeft, 0, 2, 0, 0 );
+ gtqlayout->addMultiCellWidget( vHandleRight, 0, 2, 2, 2 );
+ }
+ boxLayout()->setDirection( o == Qt::Horizontal ? TQBoxLayout::LeftToRight : TQBoxLayout::TopToBottom );
+ TQApplication::sendPostedEvents( this, TQEvent::LayoutHint );
+ TQEvent *e = new TQEvent( TQEvent::LayoutHint );
+ TQApplication::postEvent( this, e );
+}
+
+/*!
+ \reimp
+
+ Destroys the dock window and its child widgets.
+*/
+
+TQDockWindow::~TQDockWindow()
+{
+ tqApp->removeEventFilter( this );
+ if ( area() )
+ area()->removeDockWindow( this, FALSE, FALSE );
+ TQDockArea *a = area();
+ if ( !a && dockWindowData )
+ a = ( (TQDockArea::DockWindowData*)dockWindowData )->area;
+ TQMainWindow *mw = a ? ::tqqt_cast<TQMainWindow*>(a->parentWidget()) : 0;
+ if ( mw )
+ mw->removeDockWindow( this );
+
+ delete (TQDockArea::DockWindowData*)dockWindowData;
+}
+
+/*! \reimp
+*/
+
+void TQDockWindow::resizeEvent( TQResizeEvent *e )
+{
+ TQFrame::resizeEvent( e );
+ updateGui();
+}
+
+
+void TQDockWindow::swapRect( TQRect &r, Orientation o, const TQPoint &offset, TQDockArea * )
+{
+ TQBoxLayout *bl = boxLayout()->createTmpCopy();
+ bl->setDirection( o == Qt::Horizontal ? TQBoxLayout::LeftToRight : TQBoxLayout::TopToBottom );
+ bl->activate();
+ r.setSize( bl->tqsizeHint() );
+ bl->data = 0;
+ delete bl;
+ bool reverse = TQApplication::reverseLayout();
+ if ( o == Qt::Horizontal )
+ r.moveBy( -r.width()/2, 0 );
+ else
+ r.moveBy( reverse ? - r.width() : 0, -r.height() / 2 );
+ r.moveBy( offset.x(), offset.y() );
+}
+
+TQWidget *TQDockWindow::areaAt( const TQPoint &gp )
+{
+ TQWidget *w = tqApp->widgetAt( gp, TRUE );
+
+ if ( w && ( w == this || w == titleBar ) && parentWidget() )
+ w = parentWidget()->tqchildAt( parentWidget()->mapFromGlobal( gp ) );
+
+ while ( w ) {
+ if ( ::tqqt_cast<TQDockArea*>(w) ) {
+ TQDockArea *a = (TQDockArea*)w;
+ if ( a->isDockWindowAccepted( this ) )
+ return w;
+ }
+ if ( ::tqqt_cast<TQMainWindow*>(w) ) {
+ TQMainWindow *mw = (TQMainWindow*)w;
+ TQDockArea *a = mw->dockingArea( mw->mapFromGlobal( gp ) );
+ if ( a && a->isDockWindowAccepted( this ) )
+ return a;
+ }
+ w = w->parentWidget( TRUE );
+ }
+ return 0;
+}
+
+void TQDockWindow::handleMove( const TQPoint &pos, const TQPoint &gp, bool drawRect )
+{
+ if ( !unclippedPainter )
+ return;
+
+ if ( drawRect ) {
+ TQRect dr(currRect);
+#ifdef MAC_DRAG_HACK
+ dr.moveBy(-tqtopLevelWidget()->tqgeometry().x(), -tqtopLevelWidget()->tqgeometry().y());
+#endif
+ unclippedPainter->drawRect( dr );
+ }
+ currRect = TQRect( realWidgetPos( this ), size() );
+ TQWidget *w = areaAt( gp );
+ if ( titleBar->ctrlDown || horHandle->ctrlDown || verHandle->ctrlDown )
+ w = 0;
+ currRect.moveBy( pos.x(), pos.y() );
+ if ( !::tqqt_cast<TQDockArea*>(w) ) {
+ if ( startOrientation != Qt::Horizontal && ::tqqt_cast<TQToolBar*>(this) )
+ swapRect( currRect, Qt::Horizontal, startOffset, (TQDockArea*)w );
+ if ( drawRect ) {
+ unclippedPainter->setPen( TQPen( Qt::gray, 3 ) );
+ TQRect dr(currRect);
+#ifdef MAC_DRAG_HACK
+ dr.moveBy(-tqtopLevelWidget()->tqgeometry().x(), -tqtopLevelWidget()->tqgeometry().y());
+#endif
+ unclippedPainter->drawRect( dr );
+ } else {
+ TQPoint mp( mapToGlobal( pos ));
+ if(place() == InDock) {
+ undock();
+ if(titleBar) {
+ mp = TQPoint(titleBar->width() / 2, titleBar->height() / 2);
+ TQMouseEvent me(TQEvent::MouseButtonPress, mp, Qt::LeftButton, 0);
+ TQApplication::sendEvent(titleBar, &me);
+ mp = titleBar->mapToGlobal( mp );
+ }
+ }
+ move( mp );
+ }
+ state = OutsideDock;
+ return;
+ }
+
+ TQDockArea *area = (TQDockArea*)w;
+ if( area->isVisible() ) {
+ state = InDock;
+ Qt::Orientation o = ( area ? area->orientation() :
+ ( boxLayout()->direction() == TQBoxLayout::LeftToRight ||
+ boxLayout()->direction() == TQBoxLayout::RightToLeft ?
+ Qt::Horizontal : Qt::Vertical ) );
+ if ( startOrientation != o )
+ swapRect( currRect, o, startOffset, area );
+ if ( drawRect ) {
+ unclippedPainter->setPen( TQPen( Qt::gray, 1 ) );
+ TQRect dr(currRect);
+#ifdef MAC_DRAG_HACK
+ dr.moveBy(-tqtopLevelWidget()->tqgeometry().x(), -tqtopLevelWidget()->tqgeometry().y());
+#endif
+ unclippedPainter->drawRect( dr );
+ }
+ tmpDockArea = area;
+ }
+}
+
+void TQDockWindow::updateGui()
+{
+ if ( curPlace == OutsideDock ) {
+ hbox->setMargin( 2 );
+ horHandle->hide();
+ verHandle->hide();
+ if ( moveEnabled )
+ titleBar->show();
+ else
+ titleBar->hide();
+ titleBar->updateGui();
+ hHandleTop->hide();
+ vHandleLeft->hide();
+ hHandleBottom->hide();
+ vHandleRight->hide();
+ setLineWidth( 2 );
+ widgetResizeHandler->setActive( isResizeEnabled() );
+ } else {
+ hbox->setMargin( isResizeEnabled() ? 0 : 2 );
+ titleBar->hide();
+ if ( orientation() == Qt::Horizontal ) {
+ horHandle->hide();
+ if ( moveEnabled )
+ verHandle->show();
+ else
+ verHandle->hide();
+#ifdef TQ_WS_MAC
+ if(horHandle->mousePressed) {
+ horHandle->mousePressed = FALSE;
+ verHandle->mousePressed = TRUE;
+ verHandle->grabMouse();
+ }
+#endif
+ verHandle->updateGui();
+ } else {
+ if ( moveEnabled )
+ horHandle->show();
+ else
+ horHandle->hide();
+ horHandle->updateGui();
+#ifdef TQ_WS_MAC
+ if(verHandle->mousePressed) {
+ verHandle->mousePressed = FALSE;
+ horHandle->mousePressed = TRUE;
+ horHandle->grabMouse();
+ }
+#endif
+ verHandle->hide();
+ }
+ if ( isResizeEnabled() ) {
+ if ( orientation() == Qt::Horizontal ) {
+ hHandleBottom->raise();
+ hHandleTop->raise();
+ } else {
+ vHandleRight->raise();
+ vHandleLeft->raise();
+ }
+
+ if ( area() ) {
+ if ( orientation() == Qt::Horizontal ) {
+ if ( area()->handlePosition() == TQDockArea::Normal ) {
+ hHandleBottom->show();
+ hHandleTop->hide();
+ } else {
+ hHandleTop->show();
+ hHandleBottom->hide();
+ }
+ if ( !area()->isLastDockWindow( this ) )
+ vHandleRight->show();
+ else
+ vHandleRight->hide();
+ vHandleLeft->hide();
+ } else {
+ if ( (area()->handlePosition() == TQDockArea::Normal) != TQApplication::reverseLayout() ) {
+ vHandleRight->show();
+ vHandleLeft->hide();
+ } else {
+ vHandleLeft->show();
+ vHandleRight->hide();
+ }
+ if ( !area()->isLastDockWindow( this ) )
+ hHandleBottom->show();
+ else
+ hHandleBottom->hide();
+ hHandleTop->hide();
+ }
+ }
+ } else if ( area() ) { // hide resize handles if resizing is disabled
+ if ( orientation() == Qt::Horizontal ) {
+ hHandleTop->hide();
+ hHandleBottom->hide();
+ } else {
+ vHandleLeft->hide();
+ vHandleRight->hide();
+ }
+ }
+#ifndef TQ_OS_TEMP
+ if ( moveEnabled )
+ setLineWidth( 1 );
+ else
+ setLineWidth( 0 );
+ hbox->setMargin( lineWidth() );
+#else
+ hbox->setMargin( 2 );
+#endif
+ widgetResizeHandler->setActive( FALSE );
+ }
+}
+
+void TQDockWindow::updatePosition( const TQPoint &globalPos )
+{
+ if ( curPlace == OutsideDock && state == InDock )
+ lastSize = size();
+
+ bool doAdjustSize = curPlace != state && state == OutsideDock;
+ bool doUpdate = TRUE;
+ bool doOrientationChange = TRUE;
+ if ( state != curPlace && state == InDock ) {
+ doUpdate = FALSE;
+ curPlace = state;
+ updateGui();
+ TQApplication::sendPostedEvents();
+ }
+ Qt::Orientation oo = orientation();
+
+ if ( state == InDock ) {
+ if ( tmpDockArea ) {
+ bool differentDocks = FALSE;
+ if ( dockArea && dockArea != tmpDockArea ) {
+ differentDocks = TRUE;
+ delete (TQDockArea::DockWindowData*)dockWindowData;
+ dockWindowData = dockArea->dockWindowData( this );
+ dockArea->removeDockWindow( this, FALSE, FALSE );
+ }
+ dockArea = tmpDockArea;
+ if ( differentDocks ) {
+ if ( doUpdate ) {
+ doUpdate = FALSE;
+ curPlace = state;
+ updateGui();
+ }
+ emit orientationChanged( tmpDockArea->orientation() );
+ doOrientationChange = FALSE;
+ } else {
+ updateGui();
+ }
+ dockArea->moveDockWindow( this, globalPos, currRect, startOrientation != oo );
+ }
+ } else {
+ if ( dockArea ) {
+ TQMainWindow *mw = (TQMainWindow*)dockArea->parentWidget();
+ if ( ::tqqt_cast<TQMainWindow*>(mw) &&
+ ( !mw->isDockEnabled( TQt::DockTornOff ) ||
+ !mw->isDockEnabled( this, TQt::DockTornOff ) ) )
+ return;
+ delete (TQDockArea::DockWindowData*)dockWindowData;
+ dockWindowData = dockArea->dockWindowData( this );
+ dockArea->removeDockWindow( this, TRUE,
+ startOrientation != Qt::Horizontal && ::tqqt_cast<TQToolBar*>(this) );
+ }
+ dockArea = 0;
+ TQPoint topLeft = currRect.topLeft();
+ TQRect screen = tqApp->desktop()->availableGeometry( topLeft );
+ if ( !screen.tqcontains( topLeft ) ) {
+ topLeft.setY(TQMAX(topLeft.y(), screen.top()));
+ topLeft.setY(TQMIN(topLeft.y(), screen.bottom()-height()));
+ topLeft.setX(TQMAX(topLeft.x(), screen.left()));
+ topLeft.setX(TQMIN(topLeft.x(), screen.right()-width()));
+ }
+ move( topLeft );
+ }
+
+ if ( curPlace == InDock && state == OutsideDock && !::tqqt_cast<TQToolBar*>(this) ) {
+ if ( lastSize != TQSize( -1, -1 ) )
+ resize( lastSize );
+ }
+
+ if ( doUpdate ) {
+ curPlace = state;
+ updateGui();
+ }
+ if ( doOrientationChange )
+ emit orientationChanged( orientation() );
+ tmpDockArea = 0;
+ if ( doAdjustSize ) {
+ TQApplication::sendPostedEvents( this, TQEvent::LayoutHint );
+ if ( ::tqqt_cast<TQToolBar*>(this) )
+ adjustSize();
+ if (lastSize == TQSize(-1, -1))
+ clearWState(TQt::WState_Resized); // Ensures size is recalculated (non-opaque).
+ show();
+ if ( parentWidget() && isTopLevel() )
+ parentWidget()->setActiveWindow();
+
+ }
+
+ emit placeChanged( curPlace );
+}
+
+/*!
+ Sets the dock window's main widget to \a w.
+
+ \sa boxLayout()
+*/
+
+void TQDockWindow::setWidget( TQWidget *w )
+{
+ wid = w;
+ boxLayout()->addWidget( w );
+ updateGui();
+}
+
+/*!
+ Returns the dock window's main widget.
+
+ \sa setWidget()
+*/
+
+TQWidget *TQDockWindow::widget() const
+{
+ return wid;
+}
+
+void TQDockWindow::startRectDraw( const TQPoint &so, bool drawRect )
+{
+ state = place();
+ if ( unclippedPainter )
+ endRectDraw( !opaque );
+#ifdef MAC_DRAG_HACK
+ TQWidget *paint_on = tqtopLevelWidget();
+#else
+ int scr = TQApplication::desktop()->screenNumber( this );
+ TQWidget *paint_on = TQT_TQWIDGET(TQApplication::desktop()->screen( scr ));
+#endif
+ unclippedPainter = new TQPainter( paint_on, TRUE );
+ unclippedPainter->setPen( TQPen( Qt::gray, curPlace == OutsideDock ? 3 : 1 ) );
+ unclippedPainter->setRasterOp( TQt::XorROP );
+ currRect = TQRect( realWidgetPos( this ), size() );
+ if ( drawRect ) {
+ TQRect dr(currRect);
+#ifdef MAC_DRAG_HACK
+ dr.moveBy(-tqtopLevelWidget()->tqgeometry().x(), -tqtopLevelWidget()->tqgeometry().y());
+#endif
+ unclippedPainter->drawRect( dr );
+ }
+ startOrientation = orientation();
+ startOffset = mapFromGlobal( so );
+}
+
+void TQDockWindow::endRectDraw( bool drawRect )
+{
+ if ( !unclippedPainter )
+ return;
+ if ( drawRect ) {
+ TQRect dr(currRect);
+#ifdef MAC_DRAG_HACK
+ dr.moveBy(-tqtopLevelWidget()->tqgeometry().x(), -tqtopLevelWidget()->tqgeometry().y());
+#endif
+ unclippedPainter->drawRect( dr );
+ }
+ delete unclippedPainter;
+ unclippedPainter = 0;
+}
+
+/*!
+ \reimp
+*/
+void TQDockWindow::drawFrame( TQPainter *p )
+{
+ if ( place() == InDock ) {
+ TQFrame::drawFrame( p );
+ return;
+ }
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ TQStyleOption opt(lineWidth(),midLineWidth());
+
+ if ( titleBar->isActive() )
+ flags |= TQStyle::Style_Active;
+
+ tqstyle().tqdrawPrimitive( TQStyle::PE_WindowFrame, p, rect(), tqcolorGroup(), flags, opt );
+}
+
+/*!
+ \reimp
+*/
+void TQDockWindow::drawContents( TQPainter *p )
+{
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if ( titleBar->isActive() )
+ flags |= TQStyle::Style_Active;
+ tqstyle().tqdrawControl( TQStyle::CE_DockWindowEmptyArea, p, this,
+ rect(), tqcolorGroup(), flags );
+}
+
+/*!
+ \property TQDockWindow::resizeEnabled
+ \brief whether the dock window is resizeable
+
+ A resizeable dock window can be resized using splitter-like
+ handles inside a dock area and like every other top level window
+ when floating.
+
+ A dock window is both horizontally and vertically stretchable if
+ you call setResizeEnabled(TRUE).
+
+ This property is FALSE by default.
+
+ \sa setVerticallyStretchable() setHorizontallyStretchable()
+*/
+
+void TQDockWindow::setResizeEnabled( bool b )
+{
+ resizeEnabled = b;
+ hbox->setMargin( b ? 0 : 2 );
+ updateGui();
+}
+
+/*!
+ \property TQDockWindow::movingEnabled
+ \brief whether the user can move the dock window within the dock
+ area, move the dock window to another dock area, or float the dock
+ window.
+
+ This property is TRUE by default.
+*/
+
+void TQDockWindow::setMovingEnabled( bool b )
+{
+ moveEnabled = b;
+ updateGui();
+}
+
+bool TQDockWindow::isResizeEnabled() const
+{
+ return resizeEnabled;
+}
+
+bool TQDockWindow::isMovingEnabled() const
+{
+ return moveEnabled;
+}
+
+/*!
+ \property TQDockWindow::closeMode
+ \brief the close mode of a dock window
+
+ Defines when (if ever) the dock window has a close button. The
+ choices are \c Never, \c Docked (i.e. only when docked), \c
+ Undocked (only when undocked, i.e. floated) or \c Always.
+
+ The default is \c Never.
+*/
+
+void TQDockWindow::setCloseMode( int m )
+{
+ cMode = m;
+ if ( place() == InDock ) {
+ horHandle->updateGui();
+ verHandle->updateGui();
+ } else {
+ titleBar->updateGui();
+ }
+}
+
+/*!
+ Returns TRUE if the dock window has a close button; otherwise
+ returns FALSE. The result depends on the dock window's \l Place
+ and its \l CloseMode.
+
+ \sa setCloseMode()
+*/
+
+bool TQDockWindow::isCloseEnabled() const
+{
+ return ( (( cMode & Docked ) == Docked && place() == InDock) ||
+ (( cMode & Undocked ) == Undocked && place() == OutsideDock) );
+}
+
+int TQDockWindow::closeMode() const
+{
+ return cMode;
+}
+
+/*!
+ \property TQDockWindow::horizontallyStretchable
+ \brief whether the dock window is horizontally stretchable.
+
+ A dock window is horizontally stretchable if you call
+ setHorizontallyStretchable(TRUE) or setResizeEnabled(TRUE).
+
+ \sa setResizeEnabled()
+
+ \bug Strecthability is broken. You must call setResizeEnabled(TRUE) to get
+ proper behavior and even then TQDockWindow does not limit stretchablilty.
+*/
+
+void TQDockWindow::setHorizontallyStretchable( bool b )
+{
+ stretchable[ Qt::Horizontal ] = b;
+}
+
+/*!
+ \property TQDockWindow::verticallyStretchable
+ \brief whether the dock window is vertically stretchable.
+
+ A dock window is vertically stretchable if you call
+ setVerticallyStretchable(TRUE) or setResizeEnabled(TRUE).
+
+ \sa setResizeEnabled()
+
+ \bug Strecthability is broken. You must call setResizeEnabled(TRUE) to get
+ proper behavior and even then TQDockWindow does not limit stretchablilty.
+*/
+
+void TQDockWindow::setVerticallyStretchable( bool b )
+{
+ stretchable[ Qt::Vertical ] = b;
+}
+
+bool TQDockWindow::isHorizontallyStretchable() const
+{
+ return isResizeEnabled() || stretchable[ Qt::Horizontal ];
+}
+
+bool TQDockWindow::isVerticallyStretchable() const
+{
+ return isResizeEnabled() || stretchable[ Qt::Vertical ];
+}
+
+/*!
+ \property TQDockWindow::stretchable
+ \brief whether the dock window is stretchable in the current
+ orientation()
+
+ This property can be set using setHorizontallyStretchable() and
+ setVerticallyStretchable(), or with setResizeEnabled().
+
+ \sa setResizeEnabled()
+
+ \bug Strecthability is broken. You must call setResizeEnabled(TRUE) to get
+ proper behavior and even then TQDockWindow does not limit stretchablilty.
+*/
+
+bool TQDockWindow::isStretchable() const
+{
+ if ( orientation() == Qt::Horizontal )
+ return isHorizontallyStretchable();
+ return isVerticallyStretchable();
+}
+
+/*!
+ Returns the orientation of the dock window.
+
+ \sa orientationChanged()
+*/
+
+TQt::Orientation TQDockWindow::orientation() const
+{
+ if ( dockArea )
+ return dockArea->orientation();
+ if ( ::tqqt_cast<TQToolBar*>(this) )
+ return Qt::Horizontal;
+ return ( ((TQDockWindow*)this)->boxLayout()->direction() == TQBoxLayout::LeftToRight ||
+ ((TQDockWindow*)this)->boxLayout()->direction() == TQBoxLayout::RightToLeft ?
+ Qt::Horizontal : Qt::Vertical );
+}
+
+int TQDockWindow::offset() const
+{
+ return offs;
+}
+
+/*!
+ \property TQDockWindow::offset
+ \brief the dock window's preferred offset from the dock area's
+ left edge (top edge for vertical dock areas)
+
+ The default is 0.
+*/
+
+void TQDockWindow::setOffset( int o )
+{
+ offs = o;
+}
+
+/*!
+ Returns the dock window's preferred size (fixed extent).
+
+ \sa setFixedExtentWidth() setFixedExtentHeight()
+*/
+
+TQSize TQDockWindow::fixedExtent() const
+{
+ return fExtent;
+}
+
+/*!
+ Sets the dock window's preferred width for its fixed extent (size)
+ to \a w.
+
+ \sa setFixedExtentHeight()
+*/
+
+void TQDockWindow::setFixedExtentWidth( int w )
+{
+ fExtent.setWidth( w );
+}
+
+/*!
+ Sets the dock window's preferred height for its fixed extent
+ (size) to \a h.
+
+ \sa setFixedExtentWidth()
+*/
+
+void TQDockWindow::setFixedExtentHeight( int h )
+{
+ fExtent.setHeight( h );
+}
+
+/*!
+ \property TQDockWindow::newLine
+ \brief whether the dock window prefers to start a new line in the
+ dock area.
+
+ The default is FALSE, i.e. the dock window doesn't require a new
+ line in the dock area.
+*/
+
+void TQDockWindow::setNewLine( bool b )
+{
+ nl = b;
+}
+
+bool TQDockWindow::newLine() const
+{
+ return nl;
+}
+
+/*!
+ Returns the tqlayout which is used for adding widgets to the dock
+ window. The tqlayout's orientation is set automatically to match the
+ orientation of the dock window. You can add widgets to the tqlayout
+ using the box tqlayout's TQBoxLayout::addWidget() function.
+
+ If the dock window only needs to contain a single widget use
+ setWidget() instead.
+
+ \sa setWidget() setOrientation()
+*/
+
+TQBoxLayout *TQDockWindow::boxLayout()
+{
+ return childBox;
+}
+
+/*! \reimp
+ */
+
+TQSize TQDockWindow::tqsizeHint() const
+{
+ TQSize sh( TQFrame::tqsizeHint() );
+ if ( place() == InDock )
+ sh = sh.expandedTo( fixedExtent() );
+ sh = sh.expandedTo( TQSize( 16, 16 ) );
+ if ( area() ) {
+ if ( area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible() )
+ sh.setWidth( sh.width() + 2 * tqstyle().tqpixelMetric(TQStyle::PM_SplitterWidth, this) / 3 );
+ else if ( area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible() )
+ sh.setHeight( sh.height() + 2 * tqstyle().tqpixelMetric(TQStyle::PM_SplitterWidth, this) / 3 );
+ }
+ return sh;
+}
+
+/*! \reimp
+ */
+
+TQSize TQDockWindow::tqminimumSize() const
+{
+ TQSize ms( TQFrame::tqminimumSize() );
+ if ( place() == InDock )
+ ms = ms.expandedTo( fixedExtent() );
+ ms = ms.expandedTo( TQSize( 16, 16 ) );
+ if ( area() ) {
+ if ( area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible() )
+ ms.setWidth( ms.width() + 2 * tqstyle().tqpixelMetric(TQStyle::PM_SplitterWidth, this) / 3 );
+ else if ( area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible() )
+ ms.setHeight( ms.height() + 2 * tqstyle().tqpixelMetric(TQStyle::PM_SplitterWidth, this) / 3 );
+ }
+ return ms;
+}
+
+/*! \reimp
+ */
+
+TQSize TQDockWindow::tqminimumSizeHint() const
+{
+ TQSize msh( TQFrame::tqminimumSize() );
+ if ( place() == InDock )
+ msh = msh.expandedTo( fixedExtent() );
+ msh = msh.expandedTo( TQSize( 16, 16 ) );
+ if ( area() ) {
+ if ( area()->orientation() == Qt::Horizontal && !vHandleRight->isVisible() )
+ msh.setWidth( msh.width() + 2 * tqstyle().tqpixelMetric(TQStyle::PM_SplitterWidth, this) / 3 );
+ else if ( area()->orientation() == Qt::Vertical && !hHandleBottom->isVisible() )
+ msh.setHeight( msh.height() + 2 * tqstyle().tqpixelMetric(TQStyle::PM_SplitterWidth, this) / 3 );
+ }
+ return msh;
+}
+
+/*! \internal */
+void TQDockWindow::undock( TQWidget *w )
+{
+ TQMainWindow *mw = 0;
+ if ( area() )
+ mw = ::tqqt_cast<TQMainWindow*>(area()->parentWidget());
+ if ( mw && !mw->isDockEnabled( this, TQt::DockTornOff ) )
+ return;
+ if ( (place() == OutsideDock && !w) )
+ return;
+
+ TQPoint p( 50, 50 );
+ if ( tqtopLevelWidget() )
+ p = tqtopLevelWidget()->pos() + TQPoint( 20, 20 );
+ if ( dockArea ) {
+ delete (TQDockArea::DockWindowData*)dockWindowData;
+ dockWindowData = dockArea->dockWindowData( this );
+ dockArea->removeDockWindow( this, TRUE, orientation() != Qt::Horizontal && ::tqqt_cast<TQToolBar*>(this) );
+ }
+ dockArea = 0;
+ if ( lastPos != TQPoint( -1, -1 ) && lastPos.x() > 0 && lastPos.y() > 0 )
+ move( lastPos );
+ else
+ move( p );
+ if ( lastSize != TQSize( -1, -1 ) )
+ resize( lastSize );
+ curPlace = OutsideDock;
+ updateGui();
+ emit orientationChanged( orientation() );
+ TQApplication::sendPostedEvents( this, TQEvent::LayoutHint );
+ if ( ::tqqt_cast<TQToolBar*>(this) )
+ adjustSize();
+ if ( !w ) {
+ if ( !parentWidget() || parentWidget()->isVisible() ) {
+ if (lastSize == TQSize(-1, -1))
+ clearWState(TQt::WState_Resized); // Ensures size is recalculated (opaque).
+ show();
+ }
+ } else {
+ reparent( w, 0, TQPoint( 0, 0 ), FALSE );
+ move( -width() - 5, -height() - 5 );
+ resize( 1, 1 );
+ show();
+ }
+ if ( parentWidget() && isTopLevel() )
+ parentWidget()->setActiveWindow();
+ emit placeChanged( place() );
+}
+
+/*!
+ \fn void TQDockWindow::undock()
+
+ Undocks the TQDockWindow from its current dock area if it is
+ docked; otherwise does nothing.
+
+ \sa dock() TQDockArea::moveDockWindow(),
+ TQDockArea::removeDockWindow(), TQMainWindow::moveDockWindow(),
+ TQMainWindow::removeDockWindow()
+*/
+
+void TQDockWindow::removeFromDock( bool fixNewLines )
+{
+ if ( dockArea )
+ dockArea->removeDockWindow( this, FALSE, FALSE, fixNewLines );
+}
+
+/*!
+ Docks the dock window into the last dock area in which it was
+ docked.
+
+ If the dock window has no last dock area (e.g. it was created as a
+ floating window and has never been docked), or if the last dock
+ area it was docked in does not exist (e.g. the dock area has been
+ deleted), nothing happens.
+
+ The dock window will dock with the dock area regardless of the return value
+ of TQDockArea::isDockWindowAccepted().
+
+ \sa undock() TQDockArea::moveDockWindow(),
+ TQDockArea::removeDockWindow(), TQMainWindow::moveDockWindow(),
+ TQMainWindow::removeDockWindow(), TQDockArea::isDockWindowAccepted()
+
+*/
+
+void TQDockWindow::dock()
+{
+ if ( !(TQDockArea::DockWindowData*)dockWindowData ||
+ !( (TQDockArea::DockWindowData*)dockWindowData )->area )
+ return;
+ curPlace = InDock;
+ lastPos = pos();
+ lastSize = size();
+ ( (TQDockArea::DockWindowData*)dockWindowData )->
+ area->dockWindow( this, (TQDockArea::DockWindowData*)dockWindowData );
+ emit orientationChanged( orientation() );
+ emit placeChanged( place() );
+}
+
+/*! \reimp
+ */
+
+void TQDockWindow::hideEvent( TQHideEvent *e )
+{
+ TQFrame::hideEvent( e );
+}
+
+/*! \reimp
+ */
+
+void TQDockWindow::showEvent( TQShowEvent *e )
+{
+ if (curPlace == OutsideDock && (tqparent() && strcmp(tqparent()->name(), "qt_hide_dock") != 0)) {
+ TQRect sr = tqApp->desktop()->availableGeometry( this );
+ if ( !sr.tqcontains( pos() ) ) {
+ int nx = TQMIN( TQMAX( x(), sr.x() ), sr.right()-width() );
+ int ny = TQMIN( TQMAX( y(), sr.y() ), sr.bottom()-height() );
+ move( nx, ny );
+ }
+ }
+
+ TQFrame::showEvent( e );
+}
+
+/*!
+ \property TQDockWindow::opaqueMoving
+ \brief whether the dock window will be shown normally whilst it is
+ being moved.
+
+ If this property is FALSE, (the default), the dock window will be
+ represented by an outline rectangle whilst it is being moved.
+
+ \warning Currently opaque moving has some problems and we do not
+ recommend using it at this time. We expect to fix these problems
+ in a future release.
+*/
+
+void TQDockWindow::setOpaqueMoving( bool b )
+{
+ opaque = b;
+ horHandle->setOpaqueMoving( b );
+ verHandle->setOpaqueMoving( b );
+ titleBar->setOpaqueMoving( b );
+}
+
+bool TQDockWindow::opaqueMoving() const
+{
+ return opaque;
+}
+
+/*! \reimp */
+
+void TQDockWindow::setCaption( const TQString &s )
+{
+ titleBar->setCaption( s );
+ verHandle->update();
+ horHandle->update();
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ TQFrame::setCaption( s );
+#endif
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::remove( horHandle );
+ TQToolTip::remove( verHandle );
+ if ( !s.isEmpty() ) {
+ TQToolTip::add( horHandle, s );
+ TQToolTip::add( verHandle, s );
+ }
+#endif
+}
+
+void TQDockWindow::updateSplitterVisibility( bool visible )
+{
+ if ( area() && isResizeEnabled() ) {
+ if ( orientation() == Qt::Horizontal ) {
+ if ( visible )
+ vHandleRight->show();
+ else
+ vHandleRight->hide();
+ vHandleLeft->hide();
+ } else {
+ if ( visible )
+ hHandleBottom->show();
+ else
+ hHandleBottom->hide();
+ hHandleTop->hide();
+ }
+ }
+}
+
+/*! \reimp */
+bool TQDockWindow::eventFilter( TQObject * o, TQEvent *e )
+{
+ if ( !o->isWidgetType() )
+ return FALSE;
+
+ if ( e->type() == TQEvent::KeyPress &&
+ ( horHandle->mousePressed ||
+ verHandle->mousePressed ||
+ titleBar->mousePressed ) ) {
+ TQKeyEvent *ke = (TQKeyEvent*)e;
+ if ( ke->key() == Key_Escape ) {
+ horHandle->mousePressed =
+ verHandle->mousePressed =
+ titleBar->mousePressed = FALSE;
+ endRectDraw( !opaque );
+ tqApp->removeEventFilter( this );
+ return TRUE;
+ }
+ } else if ( ((TQWidget*)o)->tqtopLevelWidget() != this && place() == OutsideDock && isTopLevel() ) {
+ if ( (e->type() == TQEvent::WindowDeactivate ||
+ e->type() == TQEvent::WindowActivate ) )
+ event( e );
+ }
+ return FALSE;
+}
+
+/*! \reimp */
+bool TQDockWindow::event( TQEvent *e )
+{
+ switch ( e->type() ) {
+ case TQEvent::WindowDeactivate:
+ if ( place() == OutsideDock && isTopLevel() && parentWidget()
+ && parentWidget()->isActiveWindow() )
+ return TRUE;
+ case TQEvent::Hide:
+ if ( !isHidden() )
+ break;
+ // fall through
+ case TQEvent::HideToParent:
+ emit visibilityChanged( FALSE );
+ break;
+ case TQEvent::Show:
+ if ( e->spontaneous() )
+ break;
+ case TQEvent::ShowToParent:
+ emit visibilityChanged( TRUE );
+ break;
+ default:
+ break;
+ }
+ return TQFrame::event( e );
+}
+
+#ifdef TQT_NO_WIDGET_TOPEXTRA
+TQString TQDockWindow::caption() const
+{
+ return titleBar->caption();
+}
+#endif
+
+/*! \reimp */
+void TQDockWindow::contextMenuEvent( TQContextMenuEvent *e )
+{
+ TQObject *o = TQT_TQOBJECT(this);
+ while ( o ) {
+ if ( ::tqqt_cast<TQMainWindow*>(o) )
+ break;
+ o = o->tqparent();
+ }
+ if ( !o || ! ( (TQMainWindow*)o )->showDockMenu( e->globalPos() ) )
+ e->ignore();
+}
+
+#include "tqdockwindow.tqmoc"
+
+#endif //TQT_NO_MAINWINDOW
diff --git a/tqtinterface/qt4/src/widgets/tqdockwindow.h b/tqtinterface/qt4/src/widgets/tqdockwindow.h
new file mode 100644
index 0000000..6906fd9
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqdockwindow.h
@@ -0,0 +1,238 @@
+/****************************************************************************
+**
+** Definition of the TQDockWindow class
+**
+** Created : 001010
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the workspace module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDOCKWINDOW_H
+#define TQDOCKWINDOW_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_MAINWINDOW
+
+class TQDockWindowHandle;
+class TQDockWindowTitleBar;
+class TQPainter;
+class TQDockWindowResizeHandle;
+class TQBoxLayout;
+class TQHBoxLayout;
+class TQVBoxLayout;
+class TQDockArea;
+class TQWidgetResizeHandler;
+class TQMainWindow;
+class TQDockAreaLayout;
+class TQDockWindowPrivate;
+class TQToolBar;
+class TQWindowsXPStyle;
+
+class TQ_EXPORT TQDockWindow : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( CloseMode Place )
+ Q_PROPERTY( int closeMode READ closeMode WRITE setCloseMode ) //### this shouldn't be of type int?!
+ Q_PROPERTY( bool resizeEnabled READ isResizeEnabled WRITE setResizeEnabled )
+ Q_PROPERTY( bool movingEnabled READ isMovingEnabled WRITE setMovingEnabled )
+ Q_PROPERTY( bool horizontallyStretchable READ isHorizontallyStretchable WRITE setHorizontallyStretchable )
+ Q_PROPERTY( bool verticallyStretchable READ isVerticallyStretchable WRITE setVerticallyStretchable )
+ Q_PROPERTY( bool stretchable READ isStretchable )
+ Q_PROPERTY( bool newLine READ newLine WRITE setNewLine )
+ Q_PROPERTY( bool opaqueMoving READ opaqueMoving WRITE setOpaqueMoving )
+ Q_PROPERTY( int offset READ offset WRITE setOffset )
+ Q_PROPERTY( Place place READ place )
+
+ friend class TQDockWindowHandle;
+ friend class TQDockWindowTitleBar;
+ friend class TQDockArea;
+ friend class TQDockAreaLayout;
+ friend class TQMainWindow;
+ friend class TQCEMainWindow;
+ friend class TQToolBar;
+ friend class TQWindowsXPStyle;
+
+public:
+ enum Place { InDock, OutsideDock };
+ enum CloseMode { Never = 0, Docked = 1, Undocked = 2, Always = Docked | Undocked };
+
+ TQDockWindow( Place p = InDock, TQWidget* tqparent=0, const char* name=0, WFlags f = 0 );
+ TQDockWindow( TQWidget* tqparent, const char* name=0, WFlags f = 0 );
+ ~TQDockWindow();
+
+ virtual void setWidget( TQWidget *w );
+ TQWidget *widget() const;
+
+ Place place() const { return curPlace; }
+
+ TQDockArea *area() const;
+
+ virtual void setCloseMode( int m );
+ bool isCloseEnabled() const;
+ int closeMode() const;
+
+ virtual void setResizeEnabled( bool b );
+ virtual void setMovingEnabled( bool b );
+ bool isResizeEnabled() const;
+ bool isMovingEnabled() const;
+
+ virtual void setHorizontallyStretchable( bool b );
+ virtual void setVerticallyStretchable( bool b );
+ bool isHorizontallyStretchable() const;
+ bool isVerticallyStretchable() const;
+ void setHorizontalStretchable( bool b ) { setHorizontallyStretchable( b ); }
+ void setVerticalStretchable( bool b ) { setVerticallyStretchable( b ); }
+ bool isHorizontalStretchable() const { return isHorizontallyStretchable(); }
+ bool isVerticalStretchable() const { return isVerticallyStretchable(); }
+ bool isStretchable() const;
+
+ virtual void setOffset( int o );
+ int offset() const;
+
+ virtual void setFixedExtentWidth( int w );
+ virtual void setFixedExtentHeight( int h );
+ TQSize fixedExtent() const;
+
+ virtual void setNewLine( bool b );
+ bool newLine() const;
+
+ Orientation orientation() const;
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSize() const;
+ TQSize tqminimumSizeHint() const;
+
+ TQBoxLayout *boxLayout();
+
+ virtual void setOpaqueMoving( bool b );
+ bool opaqueMoving() const;
+
+ bool eventFilter( TQObject *o, TQEvent *e );
+
+#ifdef TQT_NO_WIDGET_TOPEXTRA
+ TQString caption() const;
+#endif
+
+Q_SIGNALS:
+ void orientationChanged( Orientation o );
+ void placeChanged( TQDockWindow::Place p );
+ void visibilityChanged( bool );
+
+public Q_SLOTS:
+ virtual void undock( TQWidget *w );
+ virtual void undock() { undock( 0 ); }
+ virtual void dock();
+ virtual void setOrientation( Orientation o );
+ void setCaption( const TQString &s );
+
+protected:
+ void resizeEvent( TQResizeEvent *e );
+ void showEvent( TQShowEvent *e );
+ void hideEvent( TQHideEvent *e );
+ void contextMenuEvent( TQContextMenuEvent *e );
+
+ void drawFrame( TQPainter * );
+ void drawContents( TQPainter * );
+
+ bool event( TQEvent *e );
+
+private Q_SLOTS:
+ void toggleVisible() { if ( !isVisible() ) show(); else hide(); }
+
+private:
+ TQDockWindow( Place p, TQWidget* tqparent, const char* name, WFlags f, bool toolbar );
+
+ void handleMove( const TQPoint &pos, const TQPoint &gp, bool drawRect );
+ void updateGui();
+ void updateSplitterVisibility( bool visible );
+
+ void startRectDraw( const TQPoint &so, bool drawRect );
+ void endRectDraw( bool drawRect );
+ void updatePosition( const TQPoint &globalPos );
+ TQWidget *areaAt( const TQPoint &gp );
+ void removeFromDock( bool fixNewLines = TRUE );
+ void swapRect( TQRect &r, Orientation o, const TQPoint &offset, TQDockArea *area );
+ void init();
+
+private:
+ TQDockWindowHandle *horHandle, *verHandle;
+ TQDockWindowTitleBar *titleBar;
+ TQWidget *wid;
+ TQPainter *unclippedPainter;
+ TQDockArea *dockArea, *tmpDockArea;
+ TQRect currRect;
+ Place curPlace;
+ Place state;
+ bool resizeEnabled : 1;
+ bool moveEnabled : 1;
+ bool nl : 1;
+ bool opaque : 1;
+ bool isToolbar : 1;
+ bool stretchable[ 3 ];
+ Orientation startOrientation;
+ int cMode;
+ TQPoint startOffset;
+ int offs;
+ TQSize fExtent;
+ TQDockWindowResizeHandle *hHandleTop, *hHandleBottom, *vHandleLeft, *vHandleRight;
+ TQVBoxLayout *hbox;
+ TQHBoxLayout *vbox;
+ TQBoxLayout *childBox;
+ void *dockWindowData;
+ TQPoint lastPos;
+ TQSize lastSize;
+ TQWidgetResizeHandler *widgetResizeHandler;
+ TQDockWindowPrivate *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQDockWindow( const TQDockWindow & );
+ TQDockWindow& operator=( const TQDockWindow & );
+#endif
+};
+
+inline TQDockArea *TQDockWindow::area() const
+{
+ return dockArea;
+}
+
+#define TQ_DEFINED_TQDOCKWINDOW
+#include "tqwinexport.h"
+#endif
+
+#endif // TQDOCKWINDOW_H
diff --git a/tqtinterface/qt4/src/widgets/tqeffects.cpp b/tqtinterface/qt4/src/widgets/tqeffects.cpp
new file mode 100644
index 0000000..0ac6a24
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqeffects.cpp
@@ -0,0 +1,677 @@
+/****************************************************************************
+**
+** Implementation of TQEffects functions
+**
+** Created : 000621
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqapplication.h"
+#ifndef TQT_NO_EFFECTS
+#include "tqwidget.h"
+#include "tqeffects_p.h"
+#include "tqpixmap.h"
+#include "tqimage.h"
+#include "tqtimer.h"
+#include "tqdatetime.h"
+#include "tqguardedptr.h"
+#include "tqscrollview.h"
+
+/*
+ Internal class to get access to protected TQWidget-members
+*/
+
+class TQAccessWidget : public TQWidget
+{
+ friend class TQAlphaWidget;
+ friend class TQRollEffect;
+public:
+ TQAccessWidget( TQWidget* tqparent=0, const char* name=0, WFlags f = 0 )
+ : TQWidget( tqparent, name, f ) {}
+};
+
+/*
+ Internal class TQAlphaWidget.
+
+ The TQAlphaWidget is shown while the animation lasts
+ and displays the pixmap resulting from the alpha blending.
+*/
+
+class TQAlphaWidget: public TQWidget, private TQEffects
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQAlphaWidget( TQWidget* w, WFlags f = 0 );
+
+ void run( int time );
+
+protected:
+ void paintEvent( TQPaintEvent* e );
+ void closeEvent( TQCloseEvent* );
+ bool eventFilter( TQObject* o, TQEvent* e );
+ void alphaBlend();
+
+protected Q_SLOTS:
+ void render();
+
+private:
+ TQPixmap pm;
+ double alpha;
+ TQImage back;
+ TQImage front;
+ TQImage mixed;
+ TQGuardedPtr<TQAccessWidget> widget;
+ int duration;
+ int elapsed;
+ bool showWidget;
+ TQTimer anim;
+ TQTime checkTime;
+};
+
+static TQAlphaWidget* q_blend = 0;
+
+/*
+ Constructs a TQAlphaWidget.
+*/
+TQAlphaWidget::TQAlphaWidget( TQWidget* w, WFlags f )
+ : TQWidget( TQApplication::desktop()->screen(TQApplication::desktop()->screenNumber(w)),
+ "qt internal alpha effect widget", f )
+{
+#if 1 //ndef TQ_WS_WIN
+ setEnabled( FALSE );
+#endif
+
+ pm.setOptimization( TQPixmap::BestOptim );
+ setBackgroundMode( TQt::NoBackground );
+ widget = (TQAccessWidget*)w;
+ alpha = 0;
+}
+
+/*
+ \reimp
+*/
+void TQAlphaWidget::paintEvent( TQPaintEvent* )
+{
+ bitBlt( this, TQPoint(0,0), &pm );
+}
+
+/*
+ Starts the alphablending animation.
+ The animation will take about \a time ms
+*/
+void TQAlphaWidget::run( int time )
+{
+ duration = time;
+
+ if ( duration < 0 )
+ duration = 150;
+
+ if ( !widget )
+ return;
+
+ elapsed = 0;
+ checkTime.start();
+
+ showWidget = TRUE;
+ tqApp->installEventFilter( this );
+
+ widget->setWState( TQt::WState_Visible );
+
+ move( widget->tqgeometry().x(),widget->tqgeometry().y() );
+ resize( widget->size().width(), widget->size().height() );
+
+ front = TQImage( widget->size(), 32 );
+ front = TQPixmap::grabWidget( widget ).toImage();
+
+ back = TQImage( widget->size(), 32 );
+ back = TQPixmap::grabWindow( TQApplication::desktop()->winId(),
+ widget->tqgeometry().x(), widget->tqgeometry().y(),
+ widget->tqgeometry().width(), widget->tqgeometry().height() ).toImage();
+
+ if ( !back.isNull() && checkTime.elapsed() < duration / 2 ) {
+ mixed = back.copy();
+ pm = mixed;
+ show();
+ setEnabled(FALSE);
+
+ connect( &anim, TQT_SIGNAL(timeout()), this, TQT_SLOT(render()));
+ anim.start( 1 );
+ } else {
+ duration = 0;
+ render();
+ }
+}
+
+/*
+ \reimp
+*/
+bool TQAlphaWidget::eventFilter( TQObject* o, TQEvent* e )
+{
+ switch ( e->type() ) {
+ case TQEvent::Move:
+ if ( o != TQT_TQOBJECT(widget) )
+ break;
+ move( widget->tqgeometry().x(),widget->tqgeometry().y() );
+ update();
+ break;
+ case TQEvent::Hide:
+ case TQEvent::Close:
+ if ( o != TQT_TQOBJECT(widget) )
+ break;
+ case TQEvent::MouseButtonPress:
+#ifndef TQT_NO_SCROLLVIEW
+ if ( ::tqqt_cast<TQScrollView*>(o) )
+ break;
+#endif
+ case TQEvent::MouseButtonDblClick:
+ setEnabled(TRUE);
+ showWidget = FALSE;
+ render();
+ break;
+ case TQEvent::KeyPress:
+ {
+ TQKeyEvent *ke = (TQKeyEvent*)e;
+ if ( ke->key() == Key_Escape )
+ showWidget = FALSE;
+ else
+ duration = 0;
+ render();
+ break;
+ }
+ default:
+ break;
+ }
+ return TQWidget::eventFilter( o, e );
+}
+
+/*
+ \reimp
+*/
+void TQAlphaWidget::closeEvent( TQCloseEvent *e )
+{
+ e->accept();
+ if ( !q_blend )
+ return;
+
+ showWidget = FALSE;
+ render();
+
+ TQWidget::closeEvent( e );
+}
+
+/*
+ Render alphablending for the time elapsed.
+
+ Show the blended widget and free all allocated source
+ if the blending is finished.
+*/
+void TQAlphaWidget::render()
+{
+ int tempel = checkTime.elapsed();
+ if ( elapsed >= tempel )
+ elapsed++;
+ else
+ elapsed = tempel;
+
+ if ( duration != 0 )
+ alpha = tempel / double(duration);
+ else
+ alpha = 1;
+ if ( alpha >= 1 || !showWidget) {
+ anim.stop();
+ tqApp->removeEventFilter( this );
+
+ if ( widget ) {
+ if ( !showWidget ) {
+#ifdef TQ_WS_WIN
+ setEnabled(TRUE);
+ setFocus();
+#endif
+ widget->hide();
+ widget->setWState( TQt::WState_ForceHide );
+ widget->clearWState( TQt::WState_Visible );
+ } else if ( duration ) {
+ TQt::BackgroundMode bgm = widget->backgroundMode();
+ TQColor erc = widget->eraseColor();
+ const TQPixmap *erp = widget->erasePixmap();
+
+ widget->clearWState( TQt::WState_Visible );
+ widget->setBackgroundMode( TQt::NoBackground );
+ widget->show();
+ if ( bgm != TQt::FixedColor && bgm != TQt::FixedPixmap ) {
+ widget->clearWState( TQt::WState_Visible ); // prevent update in setBackgroundMode
+ widget->setBackgroundMode( bgm );
+ widget->setWState( TQt::WState_Visible );
+ }
+ if ( erc.isValid() ) {
+ widget->setEraseColor( erc );
+ } else if ( erp ) {
+ widget->setErasePixmap( *erp );
+ }
+ } else {
+ widget->clearWState( TQt::WState_Visible );
+ widget->show();
+ }
+ }
+ q_blend = 0;
+ deleteLater();
+ } else {
+ if (widget)
+ widget->clearWState( TQt::WState_ForceHide );
+ alphaBlend();
+ pm = mixed;
+ tqrepaint( FALSE );
+ }
+}
+
+/*
+ Calculate an alphablended image.
+*/
+void TQAlphaWidget::alphaBlend()
+{
+ const double ia = 1-alpha;
+ const int sw = front.width();
+ const int sh = front.height();
+ switch( front.depth() ) {
+ case 32:
+ {
+ TQ_UINT32** md = (TQ_UINT32**)mixed.jumpTable();
+ TQ_UINT32** bd = (TQ_UINT32**)back.jumpTable();
+ TQ_UINT32** fd = (TQ_UINT32**)front.jumpTable();
+
+ for (int sy = 0; sy < sh; sy++ ) {
+ TQ_UINT32* bl = ((TQ_UINT32*)bd[sy]);
+ TQ_UINT32* fl = ((TQ_UINT32*)fd[sy]);
+ for (int sx = 0; sx < sw; sx++ ) {
+ TQ_UINT32 bp = bl[sx];
+ TQ_UINT32 fp = fl[sx];
+
+ ((TQ_UINT32*)(md[sy]))[sx] = tqRgb(int (tqRed(bp)*ia + tqRed(fp)*alpha),
+ int (tqGreen(bp)*ia + tqGreen(fp)*alpha),
+ int (tqBlue(bp)*ia + tqBlue(fp)*alpha) );
+ }
+ }
+ }
+ default:
+ break;
+ }
+}
+
+/*
+ Internal class TQRollEffect
+
+ The TQRollEffect widget is shown while the animation lasts
+ and displays a scrolling pixmap.
+*/
+
+class TQRollEffect : public TQWidget, private TQEffects
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQRollEffect( TQWidget* w, WFlags f, DirFlags orient );
+
+ void run( int time );
+
+protected:
+ void paintEvent( TQPaintEvent* );
+ bool eventFilter( TQObject*, TQEvent* );
+ void closeEvent( TQCloseEvent* );
+
+private Q_SLOTS:
+ void scroll();
+
+private:
+ TQGuardedPtr<TQAccessWidget> widget;
+
+ int currentHeight;
+ int currentWidth;
+ int totalHeight;
+ int totalWidth;
+
+ int duration;
+ int elapsed;
+ bool done;
+ bool showWidget;
+ int orientation;
+
+ TQTimer anim;
+ TQTime checkTime;
+
+ TQPixmap pm;
+};
+
+static TQRollEffect* q_roll = 0;
+
+/*
+ Construct a TQRollEffect widget.
+*/
+TQRollEffect::TQRollEffect( TQWidget* w, WFlags f, DirFlags orient )
+ : TQWidget( TQApplication::desktop()->screen(TQApplication::desktop()->screenNumber(w)),
+ "qt internal roll effect widget", f ), orientation(orient)
+{
+#if 1 //ndef TQ_WS_WIN
+ setEnabled( FALSE );
+#endif
+ widget = (TQAccessWidget*) w;
+ TQ_ASSERT( widget );
+
+ setBackgroundMode( TQt::NoBackground );
+
+ if ( widget->testWState( TQt::WState_Resized ) ) {
+ totalWidth = widget->width();
+ totalHeight = widget->height();
+ } else {
+ totalWidth = widget->tqsizeHint().width();
+ totalHeight = widget->tqsizeHint().height();
+ }
+
+ currentHeight = totalHeight;
+ currentWidth = totalWidth;
+
+ if ( orientation & (RightScroll|LeftScroll) )
+ currentWidth = 0;
+ if ( orientation & (DownScroll|UpScroll) )
+ currentHeight = 0;
+
+ pm.setOptimization( TQPixmap::BestOptim );
+ pm = TQPixmap::grabWidget( widget );
+}
+
+/*
+ \reimp
+*/
+void TQRollEffect::paintEvent( TQPaintEvent* )
+{
+ int x = orientation & RightScroll ? TQMIN(0, currentWidth - totalWidth) : 0;
+ int y = orientation & DownScroll ? TQMIN(0, currentHeight - totalHeight) : 0;
+
+ bitBlt( TQT_TQPAINTDEVICE(this), x, y, &TQT_TQPAINTDEVICE_OBJECT(pm),
+ 0, 0, pm.width(), pm.height(), TQt::CopyROP, TRUE );
+}
+
+/*
+ \reimp
+*/
+bool TQRollEffect::eventFilter( TQObject* o, TQEvent* e )
+{
+ switch ( e->type() ) {
+ case TQEvent::Move:
+ if ( o != TQT_TQOBJECT(widget) )
+ break;
+ move( widget->tqgeometry().x(),widget->tqgeometry().y() );
+ update();
+ break;
+ case TQEvent::Hide:
+ case TQEvent::Close:
+ if ( o != TQT_TQOBJECT(widget) || done )
+ break;
+ setEnabled(TRUE);
+ showWidget = FALSE;
+ done = TRUE;
+ scroll();
+ break;
+ case TQEvent::MouseButtonPress:
+#ifndef TQT_NO_SCROLLVIEW
+ if ( ::tqqt_cast<TQScrollView*>(o) )
+ break;
+#endif
+ case TQEvent::MouseButtonDblClick:
+ if ( done )
+ break;
+ setEnabled(TRUE);
+ showWidget = FALSE;
+ done = TRUE;
+ scroll();
+ break;
+ case TQEvent::KeyPress:
+ {
+ TQKeyEvent *ke = (TQKeyEvent*)e;
+ if ( ke->key() == Key_Escape )
+ showWidget = FALSE;
+ done = TRUE;
+ scroll();
+ break;
+ }
+ default:
+ break;
+ }
+ return TQWidget::eventFilter( o, e );
+}
+
+/*
+ \reimp
+*/
+void TQRollEffect::closeEvent( TQCloseEvent *e )
+{
+ e->accept();
+ if ( done )
+ return;
+
+ showWidget = FALSE;
+ done = TRUE;
+ scroll();
+
+ TQWidget::closeEvent( e );
+}
+
+/*
+ Start the animation.
+
+ The animation will take about \a time ms, or is
+ calculated if \a time is negative
+*/
+void TQRollEffect::run( int time )
+{
+ if ( !widget )
+ return;
+
+ duration = time;
+ elapsed = 0;
+
+ if ( duration < 0 ) {
+ int dist = 0;
+ if ( orientation & (RightScroll|LeftScroll) )
+ dist += totalWidth - currentWidth;
+ if ( orientation & (DownScroll|UpScroll) )
+ dist += totalHeight - currentHeight;
+ duration = TQMIN( TQMAX( dist/3, 50 ), 120 );
+ }
+
+ connect( &anim, TQT_SIGNAL(timeout()), this, TQT_SLOT(scroll()));
+
+ widget->setWState( TQt::WState_Visible );
+
+ move( widget->tqgeometry().x(),widget->tqgeometry().y() );
+ resize( TQMIN( currentWidth, totalWidth ), TQMIN( currentHeight, totalHeight ) );
+
+ show();
+ setEnabled(FALSE);
+
+ tqApp->installEventFilter( this );
+
+ showWidget = TRUE;
+ done = FALSE;
+ anim.start( 1 );
+ checkTime.start();
+}
+
+/*
+ Roll according to the time elapsed.
+*/
+void TQRollEffect::scroll()
+{
+ if ( !done && widget) {
+ widget->clearWState( TQt::WState_ForceHide );
+ int tempel = checkTime.elapsed();
+ if ( elapsed >= tempel )
+ elapsed++;
+ else
+ elapsed = tempel;
+
+ if ( currentWidth != totalWidth ) {
+ currentWidth = totalWidth * (elapsed/duration)
+ + ( 2 * totalWidth * (elapsed%duration) + duration )
+ / ( 2 * duration );
+ // equiv. to int( (totalWidth*elapsed) / duration + 0.5 )
+ done = (currentWidth >= totalWidth);
+ }
+ if ( currentHeight != totalHeight ) {
+ currentHeight = totalHeight * (elapsed/duration)
+ + ( 2 * totalHeight * (elapsed%duration) + duration )
+ / ( 2 * duration );
+ // equiv. to int( (totalHeight*elapsed) / duration + 0.5 )
+ done = (currentHeight >= totalHeight);
+ }
+ done = ( currentHeight >= totalHeight ) &&
+ ( currentWidth >= totalWidth );
+
+ int w = totalWidth;
+ int h = totalHeight;
+ int x = widget->tqgeometry().x();
+ int y = widget->tqgeometry().y();
+
+ if ( orientation & RightScroll || orientation & LeftScroll )
+ w = TQMIN( currentWidth, totalWidth );
+ if ( orientation & DownScroll || orientation & UpScroll )
+ h = TQMIN( currentHeight, totalHeight );
+
+ setUpdatesEnabled( FALSE );
+ if ( orientation & UpScroll )
+ y = widget->tqgeometry().y() + TQMAX( 0, totalHeight - currentHeight );
+ if ( orientation & LeftScroll )
+ x = widget->tqgeometry().x() + TQMAX( 0, totalWidth - currentWidth );
+ if ( orientation & UpScroll || orientation & LeftScroll )
+ move( x, y );
+
+ resize( w, h );
+ setUpdatesEnabled( TRUE );
+ tqrepaint( FALSE );
+ }
+ if ( done ) {
+ anim.stop();
+ tqApp->removeEventFilter( this );
+ if ( widget ) {
+ if ( !showWidget ) {
+#ifdef TQ_WS_WIN
+ setEnabled(TRUE);
+ setFocus();
+#endif
+ widget->hide();
+ widget->setWState( TQt::WState_ForceHide );
+ widget->clearWState( TQt::WState_Visible );
+ } else {
+ TQt::BackgroundMode bgm = widget->backgroundMode();
+ TQColor erc = widget->eraseColor();
+ const TQPixmap *erp = widget->erasePixmap();
+
+ widget->clearWState( TQt::WState_Visible );
+ widget->setBackgroundMode( TQt::NoBackground );
+ widget->show();
+ if ( bgm != TQt::FixedColor && bgm != TQt::FixedPixmap ) {
+ widget->clearWState( TQt::WState_Visible ); // prevent update in setBackgroundMode
+ widget->setBackgroundMode( bgm );
+ widget->setWState( TQt::WState_Visible );
+ }
+ if ( erc.isValid() ) {
+ widget->setEraseColor( erc );
+ } else if ( erp ) {
+ widget->setErasePixmap( *erp );
+ }
+ }
+ }
+ q_roll = 0;
+ deleteLater();
+ }
+}
+
+/*
+ Delete this after timeout
+*/
+
+#include "tqeffects.tqmoc"
+
+/*!
+ Scroll widget \a w in \a time ms. \a orient may be 1 (vertical), 2
+ (horizontal) or 3 (diagonal).
+*/
+void qScrollEffect( TQWidget* w, TQEffects::DirFlags orient, int time )
+{
+ if ( q_roll ) {
+ delete q_roll;
+ q_roll = 0;
+ }
+
+ tqApp->sendPostedEvents( w, TQEvent::Move );
+ tqApp->sendPostedEvents( w, TQEvent::Resize );
+#ifdef TQ_WS_X11
+ WFlags flags = TQt::WStyle_Customize | TQt::WNoAutoErase | TQt::WStyle_StaysOnTop
+ | (w->isPopup() ? TQt::WType_Popup : (TQt::WX11BypassWM | (Qt::WindowType)TQt::WStyle_Tool));
+#else
+ WFlags flags = TQt::WStyle_Customize | TQt::WType_Popup | TQt::WX11BypassWM | TQt::WNoAutoErase | TQt::WStyle_StaysOnTop;
+#endif
+
+ // those can popups - they would steal the focus, but are disabled
+ q_roll = new TQRollEffect( w, (WFlags)flags, orient );
+ q_roll->run( time );
+}
+
+/*!
+ Fade in widget \a w in \a time ms.
+*/
+void qFadeEffect( TQWidget* w, int time )
+{
+ if ( q_blend ) {
+ delete q_blend;
+ q_blend = 0;
+ }
+
+ tqApp->sendPostedEvents( w, TQEvent::Move );
+ tqApp->sendPostedEvents( w, TQEvent::Resize );
+
+#ifdef TQ_WS_X11
+ WFlags flags = TQt::WStyle_Customize | TQt::WNoAutoErase | TQt::WStyle_StaysOnTop
+ | (w->isPopup() ? TQt::WType_Popup : (TQt::WX11BypassWM | (Qt::WindowType)TQt::WStyle_Tool));
+#else
+ WFlags flags = TQt::WStyle_Customize | TQt::WType_Popup | TQt::WX11BypassWM | TQt::WNoAutoErase | TQt::WStyle_StaysOnTop;
+#endif
+
+ // those can popups - they would steal the focus, but are disabled
+ q_blend = new TQAlphaWidget( w, (WFlags)flags );
+
+ q_blend->run( time );
+}
+#endif //TQT_NO_EFFECTS
diff --git a/tqtinterface/qt4/src/widgets/tqeffects_p.h b/tqtinterface/qt4/src/widgets/tqeffects_p.h
new file mode 100644
index 0000000..b14c474
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqeffects_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Definition of TQEffects functions
+**
+** Created : 000621
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQEFFECTS_P_H
+#define TQEFFECTS_P_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qeffects.cpp, qcombobox.cpp, qpopupmenu.cpp and qtooltip.cpp.
+// This header file may change from version to version without notice,
+// or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqnamespace.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_EFFECTS
+class TQWidget;
+
+struct TQEffects
+{
+ enum Direction {
+ LeftScroll = 0x0001,
+ RightScroll = 0x0002,
+ UpScroll = 0x0004,
+ DownScroll = 0x0008
+ };
+
+ typedef uint DirFlags;
+};
+
+extern void TQ_EXPORT qScrollEffect( TQWidget*, TQEffects::DirFlags dir = TQEffects::DownScroll, int time = -1 );
+extern void TQ_EXPORT qFadeEffect( TQWidget*, int time = -1 );
+#endif // TQT_NO_EFFECTS
+
+#endif // TQEFFECTS_P_H
diff --git a/tqtinterface/qt4/src/widgets/tqframe.cpp b/tqtinterface/qt4/src/widgets/tqframe.cpp
new file mode 100644
index 0000000..f49b30c
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqframe.cpp
@@ -0,0 +1,754 @@
+/****************************************************************************
+**
+** Implementation of TQFrame widget class
+**
+** Created : 950201
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqframe.h"
+#ifndef TQT_NO_FRAME
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqframe.h"
+#include "tqbitmap.h"
+#include "tqstyle.h"
+
+/*!
+ \class TQFrame
+ \brief The TQFrame class is the base class of widgets that can have a frame.
+
+ \ingroup abstractwidgets
+
+ It draws a frame and calls a virtual function, drawContents(), to
+ fill in the frame. This function is reimplemented by subclasses.
+ There are also two other less useful functions: drawFrame() and
+ frameChanged().
+
+ TQPopupMenu uses this to "raise" the menu above the surrounding
+ screen. TQProgressBar has a "sunken" look. TQLabel has a flat look.
+ The frames of widgets like these can be changed.
+
+ \code
+ TQLabel label(...);
+ label.setFrameStyle( TQFrame::Panel | TQFrame::Raised );
+ label.setLineWidth( 2 );
+
+ TQProgressBar pbar(...);
+ label.setFrameStyle( TQFrame::NoFrame );
+ \endcode
+
+ The TQFrame class can also be used directly for creating simple
+ frames without any contents, although usually you would use a
+ TQHBox or TQVBox because they automatically lay out the widgets you
+ put inside the frame.
+
+ A frame widget has four attributes: frameStyle(), lineWidth(),
+ midLineWidth(), and margin().
+
+ The frame style is specified by a \link TQFrame::Shape frame
+ tqshape\endlink and a \link TQFrame::Shadow shadow style\endlink. The
+ frame tqshapes are \c NoFrame, \c Box, \c Panel, \c StyledPanel, \c
+ PopupPanel, \c WinPanel, \c ToolBarPanel, \c MenuBarPanel, \c
+ HLine and \c VLine; the shadow styles are \c Plain, \c Raised and
+ \c Sunken.
+
+ The line width is the width of the frame border.
+
+ The mid-line width specifies the width of an extra line in the
+ middle of the frame, which uses a third color to obtain a special
+ 3D effect. Notice that a mid-line is only drawn for \c Box, \c
+ HLine and \c VLine frames that are raised or sunken.
+
+ The margin is the gap between the frame and the contents of the
+ frame.
+
+ \target picture
+ This table shows the most useful combinations of styles and widths
+ (and some rather useless ones):
+
+ \img frames.png Table of frame styles
+*/
+
+
+/*!
+ \enum TQFrame::Shape
+
+ This enum type defines the tqshapes of a TQFrame's frame.
+
+ \value NoFrame TQFrame draws nothing
+ \value Box TQFrame draws a box around its contents
+ \value Panel TQFrame draws a panel to make the contents appear
+ raised or sunken
+ \value StyledPanel draws a rectangular panel with a look that
+ depends on the current GUI style. It can be raised or sunken.
+ \value HLine TQFrame draws a horizontal line that frames nothing
+ (useful as separator)
+ \value VLine TQFrame draws a vertical line that frames nothing
+ (useful as separator)
+ \value GroupBoxPanel draws a rectangular panel
+ \value WinPanel draws a rectangular panel that can be raised or
+ sunken like those in Windows 95. Specifying this tqshape sets
+ the line width to 2 pixels. WinPanel is provided for compatibility.
+ For GUI style independence we recommend using StyledPanel instead.
+ \value ToolBarPanel
+ \value MenuBarPanel
+ \value PopupPanel
+ \value LineEditPanel is used to draw a frame suitable for line edits. The
+ look depends upon the current GUI style.
+ \value TabWidgetPanel is used to draw a frame suitable for tab widgets. The
+ look depends upon the current GUI style.
+ \value MShape internal tqmask
+
+ When it does not call TQStyle, Shape interacts with TQFrame::Shadow,
+ the lineWidth() and the midLineWidth() to create the total result.
+ See the \link #picture picture of the frames\endlink in the class
+ description.
+
+ \sa TQFrame::Shadow TQFrame::style() TQStyle::tqdrawPrimitive()
+*/
+
+
+/*!
+ \enum TQFrame::Shadow
+
+ This enum type defines the 3D effect used for TQFrame's frame.
+
+ \value Plain the frame and contents appear level with the
+ surroundings; draws using the palette foreground color (without
+ any 3D effect)
+ \value Raised the frame and contents appear raised; draws a 3D
+ raised line using the light and dark colors of the current color
+ group
+ \value Sunken the frame and contents appear sunken; draws a 3D
+ sunken line using the light and dark colors of the current color
+ group
+ \value MShadow internal; tqmask for the shadow
+
+ Shadow interacts with TQFrame::Shape, the lineWidth() and the
+ midLineWidth(). See the \link #picture picture of the frames\endlink
+ in the class description.
+
+ \sa TQFrame::Shape lineWidth() midLineWidth()
+*/
+
+
+/*!
+ Constructs a frame widget with frame style \c NoFrame and a
+ 1-pixel frame width.
+
+ The \a tqparent, \a name and \a f arguments are passed to the
+ TQWidget constructor.
+*/
+
+TQFrame::TQFrame( TQWidget *tqparent, const char *name, WFlags f )
+ : TQWidget( tqparent, name, f )
+{
+ frect = TQRect( 0, 0, 0, 0 );
+ fstyle = NoFrame | Plain;
+ lwidth = 1;
+ mwidth = 0;
+ mlwidth = 0;
+ updateFrameWidth();
+}
+
+static const int wpwidth = 2; // WinPanel lwidth
+
+/*!
+ \fn int TQFrame::frameStyle() const
+
+ Returns the frame style.
+
+ The default value is TQFrame::NoFrame.
+
+ \sa setFrameStyle(), frameShape(), frameShadow()
+*/
+
+/*!
+ \property TQFrame::frameShape
+ \brief the frame tqshape value from the frame style
+
+ \sa frameStyle(), frameShadow()
+*/
+
+/*!
+ \property TQFrame::frameShadow
+ \brief the frame shadow value from the frame style
+
+ \sa frameStyle(), frameShape()
+*/
+
+/*!
+ Sets the frame style to \a style.
+
+ The \a style is the bitwise OR between a frame tqshape and a frame
+ shadow style. See the \link #picture illustration\endlink in the
+ class documentation.
+
+ The frame tqshapes are given in \l{TQFrame::Shape} and the shadow
+ styles in \l{TQFrame::Shadow}.
+
+ If a mid-line width greater than 0 is specified, an additional
+ line is drawn for \c Raised or \c Sunken \c Box, \c HLine, and \c
+ VLine frames. The mid-color of the current color group is used for
+ drawing middle lines.
+
+ \sa \link #picture Illustration\endlink, frameStyle(),
+ tqcolorGroup(), TQColorGroup
+*/
+
+void TQFrame::setFrameStyle( int style )
+{
+ if ( !testWState( TQt::WState_OwnSizePolicy ) ) {
+ switch ( style & MShape ) {
+ case HLine:
+ tqsetSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed );
+ break;
+ case VLine:
+ tqsetSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Minimum );
+ break;
+ default:
+ if ( (fstyle & MShape) == HLine || (fstyle & MShape) == VLine)
+ tqsetSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred );
+ }
+ clearWState( TQt::WState_OwnSizePolicy );
+ }
+ fstyle = (short)style;
+ updateFrameWidth( TRUE );
+}
+
+/*!
+ \property TQFrame::lineWidth
+ \brief the line width
+
+ Note that the \e total line width for \c HLine and \c VLine is
+ given by frameWidth(), not lineWidth().
+
+ The default value is 1.
+
+ \sa midLineWidth(), frameWidth()
+*/
+
+void TQFrame::setLineWidth( int w )
+{
+ lwidth = (short)w;
+ updateFrameWidth();
+}
+
+/*!
+ \property TQFrame::midLineWidth
+ \brief the width of the mid-line
+
+ The default value is 0.
+
+ \sa lineWidth(), frameWidth()
+*/
+
+void TQFrame::setMidLineWidth( int w )
+{
+ mlwidth = (short)w;
+ updateFrameWidth();
+}
+
+
+
+/*!
+ \property TQFrame::margin
+ \brief the width of the margin
+
+ The margin is the distance between the innermost pixel of the
+ frame and the outermost pixel of contentsRect(). It is included in
+ frameWidth().
+
+ The margin is filled according to backgroundMode().
+
+ The default value is 0.
+
+ \sa setMargin(), lineWidth(), frameWidth()
+*/
+
+void TQFrame::setMargin( int w )
+{
+ mwidth = (short)w;
+ updateFrameWidth();
+}
+
+
+/*!
+ \internal
+ Updated the fwidth parameter.
+*/
+
+void TQFrame::updateFrameWidth( bool resetLineMetrics )
+{
+ int frameType = fstyle & MShape;
+ int frameStyle = fstyle & MShadow;
+
+ if ( resetLineMetrics ) {
+ switch ( frameType ) {
+ case MenuBarPanel:
+ mwidth = 0;
+ lwidth = tqstyle().tqpixelMetric( TQStyle::PM_MenuBarFrameWidth, this );
+ break;
+ case ToolBarPanel:
+ mwidth = 0;
+ lwidth = tqstyle().tqpixelMetric( TQStyle::PM_DockWindowFrameWidth, this );
+ break;
+ case LineEditPanel:
+ case TabWidgetPanel:
+ case PopupPanel:
+ mwidth = 0;
+ lwidth = tqstyle().tqpixelMetric( TQStyle::PM_DefaultFrameWidth, this );
+ break;
+ }
+ }
+
+ fwidth = -1;
+
+ switch ( frameType ) {
+
+ case NoFrame:
+ fwidth = 0;
+ break;
+
+ case Box:
+ switch ( frameStyle ) {
+ case Plain:
+ fwidth = lwidth;
+ break;
+ case Raised:
+ case Sunken:
+ fwidth = (short)(lwidth*2 + midLineWidth() );
+ break;
+ }
+ break;
+
+
+ case LineEditPanel:
+ case TabWidgetPanel:
+ case PopupPanel:
+ case GroupBoxPanel:
+ case Panel:
+ case StyledPanel:
+ switch ( frameStyle ) {
+ case Plain:
+ case Raised:
+ case Sunken:
+ fwidth = lwidth;
+ break;
+ }
+ break;
+
+ case WinPanel:
+ switch ( frameStyle ) {
+ case Plain:
+ case Raised:
+ case Sunken:
+ fwidth = wpwidth; //WinPanel does not use lwidth!
+ break;
+ }
+ break;
+ case MenuBarPanel:
+ fwidth = lwidth;
+ break;
+ case ToolBarPanel:
+ fwidth = lwidth;
+ break;
+ case HLine:
+ case VLine:
+ switch ( frameStyle ) {
+ case Plain:
+ fwidth = lwidth;
+ break;
+ case Raised:
+ case Sunken:
+ fwidth = (short)(lwidth*2 + midLineWidth());
+ break;
+ }
+ break;
+ }
+
+ if ( fwidth == -1 ) // invalid style
+ fwidth = 0;
+
+ fwidth += margin();
+
+ frameChanged();
+}
+
+
+/*!
+ \property TQFrame::frameWidth
+ \brief the width of the frame that is drawn.
+
+ Note that the frame width depends on the \link
+ TQFrame::setFrameStyle() frame style \endlink, not only the line
+ width and the mid-line width. For example, the style \c NoFrame
+ always has a frame width of 0, whereas the style \c Panel has a
+ frame width equivalent to the line width. The frame width also
+ includes the margin.
+
+ \sa lineWidth(), midLineWidth(), frameStyle(), margin()
+*/
+
+/*!
+ \property TQFrame::frameRect
+ \brief the frame rectangle
+
+ The frame rectangle is the rectangle the frame is drawn in. By
+ default, this is the entire widget. Setting this property does \e
+ not cause a widget update.
+
+ If this property is set to a null rectangle (for example
+ \c{TQRect(0, 0, 0, 0)}), then the frame rectangle is equivalent to
+ the \link TQWidget::rect() widget rectangle\endlink.
+
+ \sa contentsRect()
+*/
+
+TQRect TQFrame::frameRect() const
+{
+ if ( frect.isNull() )
+ return rect();
+ else
+ return frect;
+}
+
+void TQFrame::setFrameRect( const TQRect &r )
+{
+ frect = r.isValid() ? r : TQT_TQRECT_OBJECT(rect());
+}
+
+
+/*!
+ \property TQFrame::contentsRect
+ \brief the rectangle inside the frame
+
+ \sa frameRect(), drawContents()
+*/
+
+TQRect TQFrame::contentsRect() const
+{
+ TQRect r = frameRect();
+ int w = frameWidth(); // total width
+ int frameType = fstyle & MShape;
+ if (frameType == PopupPanel) {
+ int vExtra = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuFrameVerticalExtra, this);
+ int hExtra = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuFrameHorizontalExtra, this);
+ r.setRect( r.x()+w+hExtra, r.y()+w+vExtra, r.width()-w*2-hExtra*2, r.height()-w*2-vExtra*2 );
+ } else {
+ r.setRect( r.x()+w, r.y()+w, r.width()-w*2, r.height()-w*2 );
+ }
+ return r;
+}
+
+/*!\reimp
+*/
+TQSize TQFrame::tqsizeHint() const
+{
+ // Returns a size hint for the frame - for HLine and VLine
+ // tqshapes, this is stretchable one way and 3 pixels wide the
+ // other. For other tqshapes, TQWidget::tqsizeHint() is used.
+ switch (fstyle & MShape) {
+ case HLine:
+ return TQSize(-1,3);
+ case VLine:
+ return TQSize(3,-1);
+ default:
+ return TQWidget::tqsizeHint();
+ }
+}
+
+/*!
+ Processes the paint event \a event.
+
+ Paints the frame and the contents.
+
+ Opens the painter on the frame and calls drawFrame(), then
+ drawContents().
+*/
+
+void TQFrame::paintEvent( TQPaintEvent *event )
+{
+ const int m = margin();
+ if ( m && testWFlags( TQt::WNoAutoErase ) ) {
+ TQRect r = contentsRect();
+ r.addCoords( -m, -m, m, m );
+ erase( event->region().intersect( TQRegion( r ) - contentsRect() ) );
+ }
+
+ TQPainter paint( this );
+
+ if ( !contentsRect().tqcontains( event->rect() ) ) {
+ paint.save();
+ paint.setClipRegion( event->region().intersect(frameRect()) );
+ drawFrame( &paint );
+ paint.restore();
+ }
+ if ( event->rect().intersects( contentsRect() ) &&
+ (fstyle & MShape) != HLine && (fstyle & MShape) != VLine ) {
+ paint.setClipRegion( event->region().intersect( contentsRect() ) );
+ drawContents( &paint );
+ }
+}
+
+
+/*!
+ Processes the resize event \a e.
+
+ Adjusts the frame rectangle for the resized widget. The frame
+ rectangle is elastic, and the surrounding area is static.
+
+ The resulting frame rectangle may be null or invalid. You can use
+ setMinimumSize() to avoid those possibilities.
+
+ Nothing is done if the frame rectangle is a \link TQRect::isNull()
+ null rectangle\endlink already.
+*/
+
+void TQFrame::resizeEvent( TQResizeEvent *e )
+{
+ if ( !frect.isNull() ) {
+ TQRect r( frect.x(), frect.y(),
+ width() - (e->oldSize().width() - frect.width()),
+ height() - (e->oldSize().height() - frect.height()) );
+ setFrameRect( r );
+ }
+ TQWidget::resizeEvent( e );
+}
+
+
+/*!
+ Draws the frame using the painter \a p and the current frame
+ attributes and color group. The rectangle inside the frame is not
+ affected.
+
+ This function is virtual, but in general you do not need to
+ reimplement it. If you do, note that the TQPainter is already open
+ and must remain open.
+
+ \sa frameRect(), contentsRect(), drawContents(), frameStyle(), setPalette()
+*/
+
+void TQFrame::drawFrame( TQPainter *p )
+{
+ TQPoint p1, p2;
+ TQRect r = frameRect();
+ int type = fstyle & MShape;
+ int cstyle = fstyle & MShadow;
+#ifdef TQT_NO_DRAWUTIL
+ p->setPen( black ); // ####
+ p->drawRect( r ); //### a bit too simple
+#else
+ const TQColorGroup & g = tqcolorGroup();
+
+#ifndef TQT_NO_STYLE
+ TQStyleOption opt(lineWidth(),midLineWidth());
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (cstyle == Sunken)
+ flags |= TQStyle::Style_Sunken;
+ else if (cstyle == Raised)
+ flags |= TQStyle::Style_Raised;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+ if (hasMouse())
+ flags |= TQStyle::Style_MouseOver;
+#endif // TQT_NO_STYLE
+
+ switch ( type ) {
+
+ case Box:
+ if ( cstyle == Plain )
+ qDrawPlainRect( p, r, g.foreground(), lwidth );
+ else
+ qDrawShadeRect( p, r, g, cstyle == Sunken, lwidth,
+ midLineWidth() );
+ break;
+
+ case LineEditPanel:
+ tqstyle().tqdrawPrimitive( TQStyle::PE_PanelLineEdit, p, r, g, flags, opt );
+ break;
+
+ case GroupBoxPanel:
+ tqstyle().tqdrawPrimitive( TQStyle::PE_PanelGroupBox, p, r, g, flags, opt );
+ break;
+
+ case TabWidgetPanel:
+ tqstyle().tqdrawPrimitive( TQStyle::PE_PanelTabWidget, p, r, g, flags, opt );
+ break;
+
+ case MenuBarPanel:
+#ifndef TQT_NO_STYLE
+ tqstyle().tqdrawPrimitive(TQStyle::PE_PanelMenuBar, p, r, g, flags, opt);
+ break;
+#endif // fall through to Panel if TQT_NO_STYLE
+
+ case ToolBarPanel:
+#ifndef TQT_NO_STYLE
+ tqstyle().tqdrawPrimitive( TQStyle::PE_PanelDockWindow, p, rect(), g, flags, opt);
+ break;
+#endif // fall through to Panel if TQT_NO_STYLE
+
+ case StyledPanel:
+#ifndef TQT_NO_STYLE
+ if ( cstyle == Plain )
+ qDrawPlainRect( p, r, g.foreground(), lwidth );
+ else
+ tqstyle().tqdrawPrimitive(TQStyle::PE_Panel, p, r, g, flags, opt);
+ break;
+#endif // fall through to Panel if TQT_NO_STYLE
+
+ case PopupPanel:
+#ifndef TQT_NO_STYLE
+ {
+ int vextra = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuFrameVerticalExtra, this),
+ hextra = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuFrameHorizontalExtra, this);
+ if(vextra > 0 || hextra > 0) {
+ TQRect fr = frameRect();
+ int fw = frameWidth();
+ if(vextra > 0) {
+ tqstyle().tqdrawControl(TQStyle::CE_PopupMenuVerticalExtra, p, this,
+ TQRect(fr.x() + fw, fr.y() + fw, fr.width() - (fw*2), vextra),
+ g, flags, opt);
+ tqstyle().tqdrawControl(TQStyle::CE_PopupMenuVerticalExtra, p, this,
+ TQRect(fr.x() + fw, fr.bottom() - fw - vextra, fr.width() - (fw*2), vextra),
+ g, flags, opt);
+ }
+ if(hextra > 0) {
+ tqstyle().tqdrawControl(TQStyle::CE_PopupMenuHorizontalExtra, p, this,
+ TQRect(fr.x() + fw, fr.y() + fw + vextra, hextra, fr.height() - (fw*2) - vextra),
+ g, flags, opt);
+ tqstyle().tqdrawControl(TQStyle::CE_PopupMenuHorizontalExtra, p, this,
+ TQRect(fr.right() - fw - hextra, fr.y() + fw + vextra, hextra, fr.height() - (fw*2) - vextra),
+ g, flags, opt);
+ }
+ }
+
+ if ( cstyle == Plain )
+ qDrawPlainRect( p, r, g.foreground(), lwidth );
+ else
+ tqstyle().tqdrawPrimitive(TQStyle::PE_PanelPopup, p, r, g, flags, opt);
+ break;
+ }
+#endif // fall through to Panel if TQT_NO_STYLE
+
+ case Panel:
+ if ( cstyle == Plain )
+ qDrawPlainRect( p, r, g.foreground(), lwidth );
+ else
+ qDrawShadePanel( p, r, g, cstyle == Sunken, lwidth );
+ break;
+
+ case WinPanel:
+ if ( cstyle == Plain )
+ qDrawPlainRect( p, r, g.foreground(), wpwidth );
+ else
+ qDrawWinPanel( p, r, g, cstyle == Sunken );
+ break;
+ case HLine:
+ case VLine:
+ if ( type == HLine ) {
+ p1 = TQPoint( r.x(), r.height()/2 );
+ p2 = TQPoint( r.x()+r.width(), p1.y() );
+ }
+ else {
+ p1 = TQPoint( r.x()+r.width()/2, 0 );
+ p2 = TQPoint( p1.x(), r.height() );
+ }
+ if ( cstyle == Plain ) {
+ TQPen oldPen = p->pen();
+ p->setPen( TQPen(g.foreground(),lwidth) );
+ p->drawLine( p1, p2 );
+ p->setPen( oldPen );
+ }
+ else
+ qDrawShadeLine( p, p1, p2, g, cstyle == Sunken,
+ lwidth, midLineWidth() );
+ break;
+ }
+#endif // TQT_NO_DRAWUTIL
+}
+
+
+/*!
+ Virtual function that draws the contents of the frame.
+
+ The TQPainter is already open when you get it, and you must leave
+ it open. Painter \link TQPainter::setWorldMatrix()
+ transformations\endlink are switched off on entry. If you
+ transform the painter, remember to take the frame into account and
+ \link TQPainter::resetXForm() reset transformation\endlink before
+ returning.
+
+ This function is reimplemented by subclasses that draw something
+ inside the frame. It should only draw inside contentsRect(). The
+ default function does nothing.
+
+ \sa contentsRect(), TQPainter::setClipRect()
+*/
+
+void TQFrame::drawContents( TQPainter * )
+{
+}
+
+
+/*!
+ Virtual function that is called when the frame style, line width
+ or mid-line width changes.
+
+ This function can be reimplemented by subclasses that need to know
+ when the frame attributes change.
+
+ The default implementation calls update().
+*/
+
+void TQFrame::frameChanged()
+{
+ update();
+ updateGeometry();
+}
+
+/*!\reimp
+ */
+void TQFrame::styleChange( TQStyle& old )
+{
+ updateFrameWidth( TRUE );
+ TQWidget::styleChange( old );
+}
+
+#endif //TQT_NO_FRAME
diff --git a/tqtinterface/qt4/src/widgets/tqframe.h b/tqtinterface/qt4/src/widgets/tqframe.h
new file mode 100644
index 0000000..8d289d2
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqframe.h
@@ -0,0 +1,172 @@
+/****************************************************************************
+**
+** Definition of TQFrame widget class
+**
+** Created : 950201
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQFRAME_H
+#define TQFRAME_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_FRAME
+
+class TQ_EXPORT TQFrame : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( Shape Shadow )
+ Q_PROPERTY( int frameWidth READ frameWidth )
+ Q_PROPERTY( TQRect contentsRect READ contentsRect )
+ Q_PROPERTY( Shape frameShape READ frameShape WRITE setFrameShape )
+ Q_PROPERTY( Shadow frameShadow READ frameShadow WRITE setFrameShadow )
+ Q_PROPERTY( int lineWidth READ lineWidth WRITE setLineWidth )
+ Q_PROPERTY( int margin READ margin WRITE setMargin )
+ Q_PROPERTY( int midLineWidth READ midLineWidth WRITE setMidLineWidth )
+ Q_PROPERTY( TQRect frameRect READ frameRect WRITE setFrameRect DESIGNABLE false )
+
+public:
+ TQFrame( TQWidget* tqparent=0, const char* name=0, WFlags f=0 );
+
+ int frameStyle() const;
+ virtual void setFrameStyle( int );
+
+ int frameWidth() const;
+ TQRect contentsRect() const;
+
+#ifndef TQ_TQDOC
+ bool lineShapesOk() const { return TRUE; }
+#endif
+
+ virtual TQSize tqsizeHint() const;
+
+ enum Shape { NoFrame = 0, // no frame
+ Box = 0x0001, // rectangular box
+ Panel = 0x0002, // rectangular panel
+ WinPanel = 0x0003, // rectangular panel (Windows)
+ HLine = 0x0004, // horizontal line
+ VLine = 0x0005, // vertical line
+ StyledPanel = 0x0006, // rectangular panel depending on the GUI style
+ PopupPanel = 0x0007, // rectangular panel depending on the GUI style
+ MenuBarPanel = 0x0008,
+ ToolBarPanel = 0x0009,
+ LineEditPanel = 0x000a,
+ TabWidgetPanel = 0x000b,
+ GroupBoxPanel = 0x000c,
+ MShape = 0x000f // tqmask for the tqshape
+ };
+ enum Shadow { Plain = 0x0010, // plain line
+ Raised = 0x0020, // raised shadow effect
+ Sunken = 0x0030, // sunken shadow effect
+ MShadow = 0x00f0 }; // tqmask for the shadow
+
+ Shape frameShape() const;
+ void setFrameShape( Shape );
+ Shadow frameShadow() const;
+ void setFrameShadow( Shadow );
+
+ int lineWidth() const;
+ virtual void setLineWidth( int );
+
+ int margin() const;
+ virtual void setMargin( int );
+
+ int midLineWidth() const;
+ virtual void setMidLineWidth( int );
+
+ TQRect frameRect() const;
+ virtual void setFrameRect( const TQRect & );
+
+protected:
+ virtual void paintEvent( TQPaintEvent * );
+ virtual void resizeEvent( TQResizeEvent * );
+ virtual void drawFrame( TQPainter * );
+ virtual void drawContents( TQPainter * );
+ virtual void frameChanged();
+ virtual void styleChange( TQStyle& );
+
+private:
+ void updateFrameWidth(bool=FALSE);
+ TQRect frect;
+ int fstyle;
+ short lwidth;
+ short mwidth;
+ short mlwidth;
+ short fwidth;
+
+ void * d;
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQFrame( const TQFrame & );
+ TQFrame &operator=( const TQFrame & );
+#endif
+};
+
+
+inline int TQFrame::frameStyle() const
+{ return fstyle; }
+
+inline TQFrame::Shape TQFrame::frameShape() const
+{ return (Shape) ( fstyle & MShape ); }
+
+inline TQFrame::Shadow TQFrame::frameShadow() const
+{ return (Shadow) ( fstyle & MShadow ); }
+
+inline void TQFrame::setFrameShape( TQFrame::Shape s )
+{ setFrameStyle( ( fstyle & MShadow ) | s ); }
+
+inline void TQFrame::setFrameShadow( TQFrame::Shadow s )
+{ setFrameStyle( ( fstyle & MShape ) | s ); }
+
+inline int TQFrame::lineWidth() const
+{ return lwidth; }
+
+inline int TQFrame::midLineWidth() const
+{ return mlwidth; }
+
+inline int TQFrame::margin() const
+{ return mwidth; }
+
+inline int TQFrame::frameWidth() const
+{ return fwidth; }
+
+
+#endif // TQT_NO_FRAME
+
+#endif // TQFRAME_H
diff --git a/tqtinterface/qt4/src/widgets/tqgrid.cpp b/tqtinterface/qt4/src/widgets/tqgrid.cpp
new file mode 100644
index 0000000..06c6a88
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqgrid.cpp
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+
+#include "tqgrid.h"
+#ifndef TQT_NO_GRID
+#include "tqlayout.h"
+#include "tqapplication.h"
+
+/*!
+ \class TQGrid tqgrid.h
+ \brief The TQGrid widget provides simple tqgeometry management of its tqchildren.
+
+ \ingroup geomanagement
+ \ingroup appearance
+
+ The grid places its widgets either in columns or in rows depending
+ on its orientation.
+
+ The number of rows \e or columns is defined in the constructor.
+ All the grid's tqchildren will be placed and sized in accordance
+ with their tqsizeHint() and sizePolicy().
+
+ Use setMargin() to add space around the grid itself, and
+ setSpacing() to add space between the widgets.
+
+ \img qgrid-m.png TQGrid
+
+ \sa TQVBox TQHBox TQGridLayout
+*/
+
+/*! \enum TQGrid::Direction
+ \internal
+*/
+
+/*!
+ Constructs a grid widget with tqparent \a tqparent, called \a name.
+ If \a orient is \c Horizontal, \a n specifies the number of
+ columns. If \a orient is \c Vertical, \a n specifies the number of
+ rows. The widget flags \a f are passed to the TQFrame constructor.
+*/
+TQGrid::TQGrid( int n, Qt::Orientation orient, TQWidget *tqparent, const char *name,
+ WFlags f )
+ : TQFrame( tqparent, name, f )
+{
+ int nCols, nRows;
+ if ( orient == Qt::Horizontal ) {
+ nCols = n;
+ nRows = -1;
+ } else {
+ nCols = -1;
+ nRows = n;
+ }
+ lay = new TQGridLayout( this, nRows, nCols, 0, 0, name );
+ lay->setAutoAdd( TRUE );
+}
+
+
+
+/*!
+ Constructs a grid widget with tqparent \a tqparent, called \a name.
+ \a n specifies the number of columns. The widget flags \a f are
+ passed to the TQFrame constructor.
+ */
+TQGrid::TQGrid( int n, TQWidget *tqparent, const char *name, WFlags f )
+ : TQFrame( tqparent, name, f )
+{
+ lay = new TQGridLayout( this, -1, n, 0, 0, name );
+ lay->setAutoAdd( TRUE );
+}
+
+
+/*!
+ Sets the spacing between the child widgets to \a space.
+*/
+
+void TQGrid::setSpacing( int space )
+{
+ if ( tqlayout() )
+ tqlayout()->setSpacing( space );
+}
+
+
+/*!\reimp
+ */
+void TQGrid::frameChanged()
+{
+ if ( !tqlayout() )
+ return;
+ tqlayout()->setMargin( frameWidth() );
+}
+
+
+/*!
+ \reimp
+*/
+
+TQSize TQGrid::tqsizeHint() const
+{
+ TQWidget *mThis = (TQWidget*)this;
+ TQApplication::sendPostedEvents( mThis, TQEvent::ChildInserted );
+ return TQFrame::tqsizeHint();
+}
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqgrid.h b/tqtinterface/qt4/src/widgets/tqgrid.h
new file mode 100644
index 0000000..98ee826
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqgrid.h
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGRID_H
+#define TQGRID_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_GRID
+
+class TQGridLayout;
+
+class TQ_EXPORT TQGrid : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQGrid( int n, TQWidget* tqparent=0, const char* name=0, WFlags f = 0 );
+ TQGrid( int n, Qt::Orientation orient, TQWidget* tqparent=0, const char* name=0,
+ WFlags f = 0 );
+
+ void setSpacing( int );
+ TQSize tqsizeHint() const;
+
+#ifndef TQT_NO_COMPAT
+ typedef Qt::Orientation Direction;
+#endif
+
+protected:
+ void frameChanged();
+
+private:
+ TQGridLayout *lay;
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQGrid( const TQGrid & );
+ TQGrid& operator=( const TQGrid & );
+#endif
+};
+
+#endif // TQT_NO_GRID
+
+#endif // TQGRID_H
diff --git a/tqtinterface/qt4/src/widgets/tqgridview.cpp b/tqtinterface/qt4/src/widgets/tqgridview.cpp
new file mode 100644
index 0000000..4f60903
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqgridview.cpp
@@ -0,0 +1,374 @@
+/****************************************************************************
+**
+** Implementation of TQGridView class
+**
+** Created : 010523
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+
+#include "tqgridview.h"
+
+#ifndef TQT_NO_GRIDVIEW
+
+#include "tqpainter.h"
+
+/*!
+ \class TQGridView tqgridview.h
+ \brief The TQGridView class provides an abstract base for
+ fixed-size grids.
+
+ \ingroup abstractwidgets
+
+ A grid view consists of a number of abstract cells organized in
+ rows and columns. The cells have a fixed size and are identified
+ with a row index and a column index. The top-left cell is in row
+ 0, column 0. The bottom-right cell is in row numRows()-1, column
+ numCols()-1.
+
+ You can define \l numRows, \l numCols, \l cellWidth and \l
+ cellHeight. Reimplement the pure virtual function paintCell() to
+ draw the contents of a cell.
+
+ With ensureCellVisible(), you can ensure a certain cell is
+ visible. With rowAt() and columnAt() you can tqfind a cell based on
+ the given x- and y-coordinates.
+
+ If you need to monitor changes to the grid's dimensions (i.e. when
+ numRows or numCols is changed), reimplement the dimensionChange()
+ change handler.
+
+ Note: the row and column indices are always given in the order,
+ row (vertical offset) then column (horizontal offset). This order
+ is the opposite of all pixel operations, which are given in the
+ order x (horizontal offset), y (vertical offset).
+
+ TQGridView is a very simple abstract class based on TQScrollView. It
+ is designed to simplify the task of drawing many cells of the same
+ size in a potentially scrollable canvas. If you need rows and
+ columns with different sizes, use a TQTable instead. If you need a
+ simple list of items, use a TQListBox. If you need to present
+ hierachical data use a TQListView, and if you need random objects
+ at random positions, consider using either a TQIconView or a
+ TQCanvas.
+*/
+
+
+/*!
+ Constructs a grid view.
+
+ The \a tqparent, \a name and widget flag, \a f, arguments are passed
+ to the TQScrollView constructor.
+*/
+TQGridView::TQGridView( TQWidget *tqparent, const char *name, WFlags f )
+ :TQScrollView( tqparent, name, (WFlags)(f | TQt::WStaticContents) ),
+ nrows( 5 ), ncols( 5 ), cellw( 12 ), cellh( 12 )
+{
+ viewport()->setBackgroundMode( TQt::PaletteBase );
+ setBackgroundMode( TQt::PaletteBackground, TQt::PaletteBase );
+ viewport()->setFocusProxy( this );
+}
+
+/*!
+ Destroys the grid view.
+*/
+TQGridView::~TQGridView()
+{
+}
+
+void TQGridView::updateGrid()
+{
+ resizeContents( ncols * cellw, nrows * cellh );
+}
+
+/*!
+ \property TQGridView::numRows
+ \brief The number of rows in the grid
+
+ \sa numCols
+*/
+void TQGridView::setNumRows( int numRows )
+{
+ int oldnrows = nrows;
+ nrows = numRows;
+ dimensionChange( oldnrows, ncols );
+ updateGrid();
+}
+
+/*!
+ \property TQGridView::numCols
+ \brief The number of columns in the grid
+
+ \sa numRows
+*/
+void TQGridView::setNumCols( int numCols )
+{
+ int oldncols = ncols;
+ ncols = numCols;
+ dimensionChange( nrows, oldncols );
+ updateGrid();
+}
+
+/*!
+ \property TQGridView::cellWidth
+ \brief The width of a grid column
+
+ All columns in a grid view have the same width.
+
+ \sa cellHeight
+*/
+void TQGridView::setCellWidth( int cellWidth )
+{
+ cellw = cellWidth;
+ updateGrid();
+ updateContents();
+}
+
+/*!
+ \property TQGridView::cellHeight
+ \brief The height of a grid row
+
+ All rows in a grid view have the same height.
+
+ \sa cellWidth
+*/
+void TQGridView::setCellHeight( int cellHeight )
+{
+ cellh = cellHeight;
+ updateGrid();
+ updateContents();
+}
+
+/*!
+ Returns the tqgeometry of cell (\a row, \a column) in the content
+ coordinate system.
+
+ \sa cellRect()
+ */
+TQRect TQGridView::cellGeometry( int row, int column )
+{
+ TQRect r;
+ if ( row >= 0 && row < nrows && column >= 0 && column < ncols )
+ r.setRect( cellw * column, cellh * row, cellw, cellh );
+ return r;
+}
+
+/*!
+ Repaints cell (\a row, \a column).
+
+ If \a erase is TRUE, TQt erases the area of the cell before the
+ paintCell() call; otherwise no erasing takes place.
+
+ \sa TQWidget::tqrepaint()
+*/
+void TQGridView::repaintCell( int row, int column, bool erase )
+{
+ repaintContents( cellGeometry( row, column ), erase );
+}
+
+/*!
+ Updates cell (\a row, \a column).
+
+ \sa TQWidget::update()
+*/
+void TQGridView::updateCell( int row, int column )
+{
+ updateContents( cellGeometry( row, column ) );
+}
+
+/*!
+ Ensures cell (\a row, \a column) is visible, scrolling the grid
+ view if necessary.
+*/
+void TQGridView::ensureCellVisible( int row, int column )
+{
+ TQRect r = cellGeometry( row, column );
+ ensureVisible( r.x(), r.y(), r.width(), r.height() );
+}
+
+/*!
+ This function fills the \a cw pixels wide and \a ch pixels high
+ rectangle starting at position (\a cx, \a cy) with the background
+ color using the painter \a p.
+
+ paintEmptyArea() is invoked by drawContents() to erase or fill
+ unused areas.
+*/
+
+void TQGridView::paintEmptyArea( TQPainter *p, int cx ,int cy, int cw, int ch)
+{
+ if ( gridSize().width() >= contentsWidth() && gridSize().height() >= contentsHeight() )
+ return;
+ // Region of the rect we should draw
+ contentsToViewport( cx, cy, cx, cy );
+ TQRegion reg( TQRect( cx, cy, cw, ch ) );
+ // Subtract the table from it
+ reg = reg.subtract( TQRect( contentsToViewport( TQPoint( 0, 0 ) ), gridSize() ) );
+
+ // And draw the rectangles (transformed as needed)
+#ifdef USE_QT4
+ QVector<QRect> r;
+#else // USE_QT4
+ TQMemArray<TQRect> r;
+#endif // USE_QT4
+ r = reg.rects();
+ const TQBrush &brush = backgroundBrush();
+ for ( int i = 0; i < (int)r.count(); ++i)
+ p->fillRect( r[ i ], brush );
+}
+
+/*!\reimp
+ */
+void TQGridView::drawContents( TQPainter *p, int cx, int cy, int cw, int ch )
+{
+ int colfirst = columnAt( cx );
+ int collast = columnAt( cx + cw );
+ int rowfirst = rowAt( cy );
+ int rowlast = rowAt( cy + ch );
+
+ if ( rowfirst == -1 || colfirst == -1 ) {
+ paintEmptyArea( p, cx, cy, cw, ch );
+ return;
+ }
+
+ if ( collast < 0 || collast >= ncols )
+ collast = ncols-1;
+ if ( rowlast < 0 || rowlast >= nrows )
+ rowlast = nrows-1;
+
+ // Go through the rows
+ for ( int r = rowfirst; r <= rowlast; ++r ) {
+ // get row position and height
+ int rowp = r * cellh;
+
+ // Go through the columns in the row r
+ // if we know from where to where, go through [colfirst, collast],
+ // else go through all of them
+ for ( int c = colfirst; c <= collast; ++c ) {
+ // get position and width of column c
+ int colp = c * cellw;
+ // Translate painter and draw the cell
+ p->translate( colp, rowp );
+ paintCell( p, r, c );
+ p->translate( -colp, -rowp );
+ }
+ }
+
+ // Paint empty rects
+ paintEmptyArea( p, cx, cy, cw, ch );
+}
+
+/*!
+ \reimp
+
+ (Implemented to get rid of a compiler warning.)
+*/
+void TQGridView::drawContents( TQPainter * )
+{
+}
+
+/*!
+ \fn void TQGridView::dimensionChange( int oldNumRows, int oldNumCols )
+
+ This change handler is called whenever any of the grid's
+ dimensions change. \a oldNumRows and \a oldNumCols contain the
+ old dimensions, numRows() and numCols() contain the new
+ dimensions.
+*/
+void TQGridView::dimensionChange( int, int ) {}
+
+
+
+/*!
+ \fn int TQGridView::rowAt( int y ) const
+
+ Returns the number of the row at position \a y. \a y must be given
+ in content coordinates.
+
+ \sa columnAt()
+*/
+
+/*!
+ \fn int TQGridView::columnAt( int x ) const
+
+ Returns the number of the column at position \a x. \a x must be
+ given in content coordinates.
+
+ \sa rowAt()
+*/
+
+/*!
+ \fn void TQGridView::paintCell( TQPainter *p, int row, int col )
+
+ This pure virtual function is called to paint the single cell at
+ (\a row, \a col) using painter \a p. The painter must be open when
+ paintCell() is called and must remain open.
+
+ The coordinate system is \link TQPainter::translate() translated
+ \endlink so that the origin is at the top-left corner of the cell
+ to be painted, i.e. \e cell coordinates. Do not scale or shear
+ the coordinate system (or if you do, restore the transformation
+ matrix before you return).
+
+ The painter is not clipped by default in order to get maximum
+ efficiency. If you want clipping, use
+
+ \code
+ p->setClipRect( cellRect(), TQPainter::CoordPainter );
+ //... your drawing code
+ p->setClipping( FALSE );
+
+ \endcode
+*/
+
+/*!
+ \fn TQRect TQGridView::cellRect() const
+
+ Returns the tqgeometry of a cell in a cell's coordinate system. This
+ is a convenience function useful in paintCell(). It is equivalent
+ to TQRect( 0, 0, cellWidth(), cellHeight() ).
+
+ \sa cellGeometry()
+
+*/
+
+/*!
+ \fn TQSize TQGridView::gridSize() const
+
+ Returns the size of the grid in pixels.
+
+*/
+
+#endif // TQT_NO_GRIDVIEW
diff --git a/tqtinterface/qt4/src/widgets/tqgridview.h b/tqtinterface/qt4/src/widgets/tqgridview.h
new file mode 100644
index 0000000..01e0b1a
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqgridview.h
@@ -0,0 +1,140 @@
+/**********************************************************************
+**
+** Definition of TQGridView class
+**
+** Created : 010523
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGRIDVIEW_H
+#define TQGRIDVIEW_H
+
+#ifndef TQT_H
+#include "tqscrollview.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_GRIDVIEW
+
+class TQGridViewPrivate;
+
+class TQ_EXPORT TQGridView : public TQScrollView
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( int numRows READ numRows WRITE setNumRows )
+ Q_PROPERTY( int numCols READ numCols WRITE setNumCols )
+ Q_PROPERTY( int cellWidth READ cellWidth WRITE setCellWidth )
+ Q_PROPERTY( int cellHeight READ cellHeight WRITE setCellHeight )
+public:
+
+ TQGridView( TQWidget *tqparent=0, const char *name=0, WFlags f=0 );
+ ~TQGridView();
+
+ int numRows() const;
+ virtual void setNumRows( int );
+ int numCols() const;
+ virtual void setNumCols( int );
+
+ int cellWidth() const;
+ virtual void setCellWidth( int );
+ int cellHeight() const;
+ virtual void setCellHeight( int );
+
+ TQRect cellRect() const;
+ TQRect cellGeometry( int row, int column );
+ TQSize gridSize() const;
+
+ int rowAt( int y ) const;
+ int columnAt( int x ) const;
+
+ void repaintCell( int row, int column, bool erase=TRUE );
+ void updateCell( int row, int column );
+ void ensureCellVisible( int row, int column );
+
+protected:
+ virtual void paintCell( TQPainter *, int row, int col ) = 0;
+ virtual void paintEmptyArea( TQPainter *p, int cx, int cy, int cw, int ch );
+
+ void drawContents( TQPainter *p, int cx, int cy, int cw, int ch );
+
+ virtual void dimensionChange( int, int );
+
+private:
+ void drawContents( TQPainter* );
+ void updateGrid();
+
+ int nrows;
+ int ncols;
+ int cellw;
+ int cellh;
+ TQGridViewPrivate* d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQGridView( const TQGridView & );
+ TQGridView &operator=( const TQGridView & );
+#endif
+};
+
+inline int TQGridView::cellWidth() const
+{ return cellw; }
+
+inline int TQGridView::cellHeight() const
+{ return cellh; }
+
+inline int TQGridView::rowAt( int y ) const
+{ return y / cellh; }
+
+inline int TQGridView::columnAt( int x ) const
+{ return x / cellw; }
+
+inline int TQGridView::numRows() const
+{ return nrows; }
+
+inline int TQGridView::numCols() const
+{return ncols; }
+
+inline TQRect TQGridView::cellRect() const
+{ return TQRect( 0, 0, cellw, cellh ); }
+
+inline TQSize TQGridView::gridSize() const
+{ return TQSize( ncols * cellw, nrows * cellh ); }
+
+
+
+#endif // TQT_NO_GRIDVIEW
+
+
+#endif // TQTABLEVIEW_H
diff --git a/tqtinterface/qt4/src/widgets/tqgroupbox.cpp b/tqtinterface/qt4/src/widgets/tqgroupbox.cpp
new file mode 100644
index 0000000..f9c341e
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqgroupbox.cpp
@@ -0,0 +1,989 @@
+/**********************************************************************
+**
+** Implementation of TQGroupBox widget class
+**
+** Created : 950203
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqgroupbox.h"
+#ifndef TQT_NO_GROUPBOX
+#include "tqlayout.h"
+#include "tqpainter.h"
+#include "tqbitmap.h"
+#include "tqaccel.h"
+#include "tqradiobutton.h"
+#include "tqfocusdata.h"
+#include "tqobjectlist.h"
+#include "tqdrawutil.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+#include "tqcheckbox.h"
+#include "tqbuttongroup.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+/*!
+ \class TQGroupBox tqgroupbox.h
+ \brief The TQGroupBox widget provides a group box frame with a title.
+
+ \ingroup organizers
+ \ingroup geomanagement
+ \ingroup appearance
+ \mainclass
+
+ A group box provides a frame, a title and a keyboard shortcut, and
+ displays various other widgets inside itself. The title is on top,
+ the keyboard shortcut moves keyboard focus to one of the group
+ box's child widgets, and the child widgets are usually laid out
+ horizontally (or vertically) inside the frame.
+
+ The simplest way to use it is to create a group box with the
+ desired number of columns (or rows) and orientation, and then just
+ create widgets with the group box as tqparent.
+
+ It is also possible to change the orientation() and number of
+ columns() after construction, or to ignore all the automatic
+ tqlayout support and manage the tqlayout yourself. You can add 'empty'
+ spaces to the group box with addSpace().
+
+ TQGroupBox also lets you set the title() (normally set in the
+ constructor) and the title's tqalignment().
+
+ You can change the spacing used by the group box with
+ setInsideMargin() and setInsideSpacing(). To minimize space
+ consumption, you can remove the right, left and bottom edges of
+ the frame with setFlat().
+
+ <img src=qgrpbox-w.png>
+
+ \sa TQButtonGroup
+*/
+
+class TQCheckBox;
+
+class TQGroupBoxPrivate
+{
+public:
+ TQGroupBoxPrivate():
+ spacer( 0 ),
+ checkbox( 0 ) {}
+
+ TQSpacerItem *spacer;
+ TQCheckBox *checkbox;
+};
+
+
+
+
+/*!
+ Constructs a group box widget with no title.
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+
+ This constructor does not do automatic tqlayout.
+*/
+
+TQGroupBox::TQGroupBox( TQWidget *tqparent, const char *name )
+ : TQFrame( tqparent, name )
+{
+ init();
+}
+
+/*!
+ Constructs a group box with the title \a title.
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+
+ This constructor does not do automatic tqlayout.
+*/
+
+TQGroupBox::TQGroupBox( const TQString &title, TQWidget *tqparent, const char *name )
+ : TQFrame( tqparent, name )
+{
+ init();
+ setTitle( title );
+}
+
+/*!
+ Constructs a group box with no title. Child widgets will be
+ arranged in \a strips rows or columns (depending on \a
+ orientation).
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+*/
+
+TQGroupBox::TQGroupBox( int strips, Qt::Orientation orientation,
+ TQWidget *tqparent, const char *name )
+ : TQFrame( tqparent, name )
+{
+ init();
+ setColumnLayout( strips, orientation );
+}
+
+/*!
+ Constructs a group box titled \a title. Child widgets will be
+ arranged in \a strips rows or columns (depending on \a
+ orientation).
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+*/
+
+TQGroupBox::TQGroupBox( int strips, Qt::Orientation orientation,
+ const TQString &title, TQWidget *tqparent,
+ const char *name )
+ : TQFrame( tqparent, name )
+{
+ init();
+ setTitle( title );
+ setColumnLayout( strips, orientation );
+}
+
+/*!
+ Destroys the group box.
+*/
+TQGroupBox::~TQGroupBox()
+{
+ delete d;
+}
+
+void TQGroupBox::init()
+{
+ align = TQt::AlignAuto;
+ setFrameStyle( TQFrame::GroupBoxPanel | TQFrame::Sunken );
+#ifndef TQT_NO_ACCEL
+ accel = 0;
+#endif
+ vbox = 0;
+ grid = 0;
+ d = new TQGroupBoxPrivate();
+ lenvisible = 0;
+ nCols = nRows = 0;
+ dir = Qt::Horizontal;
+ marg = 11;
+ spac = 5;
+ bFlat = FALSE;
+}
+
+void TQGroupBox::setTextSpacer()
+{
+ if ( !d->spacer )
+ return;
+ int h = 0;
+ int w = 0;
+ if ( isCheckable() || lenvisible ) {
+ TQFontMetrics fm = fontMetrics();
+ int fh = fm.height();
+ if ( isCheckable() ) {
+#ifndef TQT_NO_CHECKBOX
+ fh = d->checkbox->tqsizeHint().height() + 2;
+ w = d->checkbox->tqsizeHint().width() + 2*fm.width( "xx" );
+#endif
+ } else {
+ fh = fm.height();
+ w = fm.width( str, lenvisible ) + 2*fm.width( "xx" );
+ }
+ h = frameRect().y();
+ if ( tqlayout() ) {
+ int m = tqlayout()->margin();
+ int sp = tqlayout()->spacing();
+ // do we have a child tqlayout?
+ for ( TQLayoutIterator it = tqlayout()->iterator(); it.current(); ++it ) {
+ if ( it.current()->tqlayout() ) {
+ m += it.current()->tqlayout()->margin();
+ sp = TQMAX( sp, it.current()->tqlayout()->spacing() );
+ break;
+ }
+ }
+ h = TQMAX( fh-m, h );
+ h += TQMAX( sp - (h+m - fh), 0 );
+ }
+ }
+ d->spacer->changeSize( w, h, TQSizePolicy::Minimum, TQSizePolicy::Fixed );
+}
+
+
+void TQGroupBox::setTitle( const TQString &title )
+{
+ if ( str == title ) // no change
+ return;
+ str = title;
+#ifndef TQT_NO_ACCEL
+ if ( accel )
+ delete accel;
+ accel = 0;
+ int s = TQAccel::shortcutKey( title );
+ if ( s ) {
+ accel = new TQAccel( this, "automatic focus-change accelerator" );
+ accel->connectItem( accel->insertItem( s, 0 ),
+ TQT_TQOBJECT(this), TQT_SLOT(fixFocus()) );
+ }
+#endif
+#ifndef TQT_NO_CHECKBOX
+ if ( d->checkbox ) {
+ d->checkbox->setText( str );
+ updateCheckBoxGeometry();
+ }
+#endif
+ calculateFrame();
+ setTextSpacer();
+
+ update();
+ updateGeometry();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::NameChanged );
+#endif
+}
+
+/*!
+ \property TQGroupBox::title
+ \brief the group box title text.
+
+ The group box title text will have a focus-change keyboard
+ accelerator if the title tqcontains \&, followed by a letter.
+
+ \code
+ g->setTitle( "&User information" );
+ \endcode
+ This produces "<u>U</u>ser information"; Alt+U moves the keyboard
+ focus to the group box.
+
+ There is no default title text.
+*/
+
+/*!
+ \property TQGroupBox::tqalignment
+ \brief the tqalignment of the group box title.
+
+ The title is always placed on the upper frame line. The horizontal
+ tqalignment can be specified by the tqalignment parameter.
+
+ The tqalignment is one of the following flags:
+ \list
+ \i \c AlignAuto aligns the title according to the language,
+ usually to the left.
+ \i \c AlignLeft aligns the title text to the left.
+ \i \c AlignRight aligns the title text to the right.
+ \i \c AlignHCenter aligns the title text centered.
+ \endlist
+
+ The default tqalignment is \c AlignAuto.
+
+ \sa TQt::AlignmentFlags
+*/
+
+void TQGroupBox::tqsetAlignment( int tqalignment )
+{
+ align = tqalignment;
+#ifndef TQT_NO_CHECKBOX
+ updateCheckBoxGeometry();
+#endif
+ update();
+}
+
+/*! \reimp
+*/
+void TQGroupBox::resizeEvent( TQResizeEvent *e )
+{
+ TQFrame::resizeEvent(e);
+#ifndef TQT_NO_CHECKBOX
+ if ( align & TQt::AlignRight || align & TQt::AlignCenter ||
+ ( TQApplication::reverseLayout() && !(align & TQt::AlignLeft) ) )
+ updateCheckBoxGeometry();
+#endif
+ calculateFrame();
+}
+
+/*! \reimp
+
+ \internal
+ overrides TQFrame::paintEvent
+*/
+
+void TQGroupBox::paintEvent( TQPaintEvent *event )
+{
+ TQPainter paint( this );
+
+ if ( lenvisible && !isCheckable() ) { // draw title
+ TQFontMetrics fm = paint.fontMetrics();
+ int h = fm.height();
+ int tw = fm.width( str, lenvisible ) + fm.width(TQChar(' '));
+ int x;
+ int marg = bFlat ? 0 : 8;
+ if ( align & TQt::AlignHCenter ) // center tqalignment
+ x = frameRect().width()/2 - tw/2;
+ else if ( align & TQt::AlignRight ) // right tqalignment
+ x = frameRect().width() - tw - marg;
+ else if ( align & TQt::AlignLeft ) // left tqalignment
+ x = marg;
+ else { // auto align
+ if( TQApplication::reverseLayout() )
+ x = frameRect().width() - tw - marg;
+ else
+ x = marg;
+ }
+ TQRect r( x, 0, tw, h );
+ int va = tqstyle().tqstyleHint(TQStyle::SH_GroupBox_TextLabelVerticalAlignment, this);
+ if(va & TQt::AlignTop)
+ r.moveBy(0, fm.descent());
+ TQColor pen( (TQRgb) tqstyle().tqstyleHint(TQStyle::SH_GroupBox_TextLabelColor, this ) );
+ if (!tqstyle().tqstyleHint(TQStyle::SH_UnderlineAccelerator, this))
+ va |= TQt::NoAccel;
+ tqstyle().drawItem( &paint, r, TQt::ShowPrefix | TQt::AlignHCenter | va, tqcolorGroup(),
+ isEnabled(), 0, str, -1, ownPalette() ? 0 : &pen );
+ paint.setClipRegion( event->region().subtract( r ) ); // clip everything but title
+#ifndef TQT_NO_CHECKBOX
+ } else if ( d->checkbox ) {
+ TQRect cbClip = d->checkbox->tqgeometry();
+ TQFontMetrics fm = paint.fontMetrics();
+ cbClip.setX( cbClip.x() - fm.width(TQChar(' ')) );
+ cbClip.setWidth( cbClip.width() + fm.width(TQChar(' ')) );
+ paint.setClipRegion( event->region().subtract( cbClip ) );
+#endif
+ }
+ if ( bFlat ) {
+ TQRect fr = frameRect();
+ TQPoint p1( fr.x(), fr.y() + 1 );
+ TQPoint p2( fr.x() + fr.width(), p1.y() );
+ // ### This should probably be a style primitive.
+ qDrawShadeLine( &paint, p1, p2, tqcolorGroup(), TRUE,
+ lineWidth(), midLineWidth() );
+ } else {
+ drawFrame(&paint);
+ }
+ drawContents( &paint ); // draw the contents
+}
+
+
+/*!
+ Adds an empty cell at the next free position. If \a size is
+ greater than 0, the empty cell takes \a size to be its fixed width
+ (if orientation() is \c Qt::Horizontal) or height (if orientation() is
+ \c Qt::Vertical).
+
+ Use this method to separate the widgets in the group box or to
+ skip the next free cell. For performance reasons, call this method
+ after calling setColumnLayout() or by changing the \l
+ TQGroupBox::columns or \l TQGroupBox::orientation properties. It is
+ generally a good idea to call these methods first (if needed at
+ all), and insert the widgets and spaces afterwards.
+*/
+void TQGroupBox::addSpace( int size )
+{
+ TQApplication::sendPostedEvents( this, TQEvent::ChildInserted );
+
+ if ( nCols <= 0 || nRows <= 0 )
+ return;
+
+ if ( row >= nRows || col >= nCols )
+ grid->expand( row+1, col+1 );
+
+ if ( size > 0 ) {
+ TQSpacerItem *spacer
+ = new TQSpacerItem( ( dir == Qt::Horizontal ) ? 0 : size,
+ ( dir == Qt::Vertical ) ? 0 : size,
+ TQSizePolicy::Fixed, TQSizePolicy::Fixed );
+ grid->addItem( spacer, row, col );
+ }
+
+ skip();
+}
+
+/*!
+ \property TQGroupBox::columns
+ \brief the number of columns or rows (depending on \l TQGroupBox::orientation) in the group box
+
+ Usually it is not a good idea to set this property because it is
+ slow (it does a complete tqlayout). It is best to set the number
+ of columns directly in the constructor.
+*/
+int TQGroupBox::columns() const
+{
+ if ( dir == Qt::Horizontal )
+ return nCols;
+ return nRows;
+}
+
+void TQGroupBox::setColumns( int c )
+{
+ setColumnLayout( c, dir );
+}
+
+/*!
+ Returns the width of the empty space between the items in the
+ group and the frame of the group.
+
+ Only applies if the group box has a defined orientation.
+
+ The default is usually 11, by may vary depending on the platform
+ and style.
+
+ \sa setInsideMargin(), orientation
+*/
+int TQGroupBox::insideMargin() const
+{
+ return marg;
+}
+
+/*!
+ Returns the width of the empty space between each of the items
+ in the group.
+
+ Only applies if the group box has a defined orientation.
+
+ The default is usually 5, by may vary depending on the platform
+ and style.
+
+ \sa setInsideSpacing(), orientation
+*/
+int TQGroupBox::insideSpacing() const
+{
+ return spac;
+}
+
+/*!
+ Sets the the width of the inside margin to \a m pixels.
+
+ \sa insideMargin()
+*/
+void TQGroupBox::setInsideMargin( int m )
+{
+ marg = m;
+ setColumnLayout( columns(), dir );
+}
+
+/*!
+ Sets the width of the empty space between each of the items in
+ the group to \a s pixels.
+
+ \sa insideSpacing()
+*/
+void TQGroupBox::setInsideSpacing( int s )
+{
+ spac = s;
+ setColumnLayout( columns(), dir );
+}
+
+/*!
+ \property TQGroupBox::orientation
+ \brief the group box's orientation
+
+ A horizontal group box arranges it's tqchildren in columns, while a
+ vertical group box arranges them in rows.
+
+ Usually it is not a good idea to set this property because it is
+ slow (it does a complete tqlayout). It is better to set the
+ orientation directly in the constructor.
+*/
+void TQGroupBox::setOrientation( Orientation o )
+{
+ setColumnLayout( columns(), o );
+}
+
+/*!
+ Changes the tqlayout of the group box. This function is only useful
+ in combination with the default constructor that does not take any
+ tqlayout information. This function will put all existing tqchildren
+ in the new tqlayout. It is not good TQt programming style to call
+ this function after tqchildren have been inserted. Sets the number
+ of columns or rows to be \a strips, depending on \a direction.
+
+ \sa orientation columns
+*/
+void TQGroupBox::setColumnLayout(int strips, Qt::Orientation direction)
+{
+ if ( tqlayout() )
+ delete tqlayout();
+
+ vbox = 0;
+ grid = 0;
+
+ if ( strips < 0 ) // if 0, we create the vbox but not the grid. See below.
+ return;
+
+ vbox = new TQVBoxLayout( this, marg, 0 );
+
+ d->spacer = new TQSpacerItem( 0, 0, TQSizePolicy::Minimum,
+ TQSizePolicy::Fixed );
+
+ setTextSpacer();
+ vbox->addItem( TQT_TQLAYOUTITEM(d->spacer) );
+
+ nCols = 0;
+ nRows = 0;
+ dir = direction;
+
+ // Send all child events and ignore them. Otherwise we will end up
+ // with doubled insertion. This won't do anything because nCols ==
+ // nRows == 0.
+ TQApplication::sendPostedEvents( this, TQEvent::ChildInserted );
+
+ // if 0 or smaller , create a vbox-tqlayout but no grid. This allows
+ // the designer to handle its own grid tqlayout in a group box.
+ if ( strips <= 0 )
+ return;
+
+ dir = direction;
+ if ( dir == Qt::Horizontal ) {
+ nCols = strips;
+ nRows = 1;
+ } else {
+ nCols = 1;
+ nRows = strips;
+ }
+ grid = new TQGridLayout( nRows, nCols, spac );
+ row = col = 0;
+ grid->tqsetAlignment( TQt::AlignTop );
+ vbox->addLayout( TQT_TQLAYOUT(grid) );
+
+ // Add all tqchildren
+ if ( !childrenListObject().isEmpty() ) {
+ TQObjectListIt it( childrenListObject() );
+ TQWidget *w;
+ while( (w=(TQWidget *)it.current()) != 0 ) {
+ ++it;
+ if ( w->isWidgetType()
+#ifndef TQT_NO_CHECKBOX
+ && w != d->checkbox
+#endif
+ )
+ insertWid( w );
+ }
+ }
+}
+
+
+/*! \reimp */
+bool TQGroupBox::event( TQEvent * e )
+{
+ if ( e->type() == TQEvent::LayoutHint && tqlayout() )
+ setTextSpacer();
+ return TQFrame::event( e );
+}
+
+/*!\reimp */
+void TQGroupBox::childEvent( TQChildEvent *c )
+{
+ if ( !c->inserted() || !c->child()->isWidgetType() )
+ return;
+ TQWidget *w = (TQWidget*)c->child();
+#ifndef TQT_NO_CHECKBOX
+ if ( d->checkbox ) {
+ if ( w == d->checkbox )
+ return;
+ if ( d->checkbox->isChecked() ) {
+ if ( !w->testWState( TQt::WState_ForceDisabled ) )
+ w->setEnabled( TRUE );
+ } else {
+ if ( w->isEnabled() ) {
+ w->setEnabled( FALSE );
+ ((TQGroupBox*)w)->clearWState( TQt::WState_ForceDisabled );
+ }
+ }
+ }
+#endif
+ if ( !grid )
+ return;
+ insertWid( w );
+}
+
+void TQGroupBox::insertWid( TQWidget* w )
+{
+ if ( row >= nRows || col >= nCols )
+ grid->expand( row+1, col+1 );
+ grid->addWidget( w, row, col );
+ skip();
+ TQApplication::postEvent( this, new TQEvent( TQEvent::LayoutHint ) );
+}
+
+
+void TQGroupBox::skip()
+{
+ // Same as TQGrid::skip()
+ if ( dir == Qt::Horizontal ) {
+ if ( col+1 < nCols ) {
+ col++;
+ } else {
+ col = 0;
+ row++;
+ }
+ } else { //Vertical
+ if ( row+1 < nRows ) {
+ row++;
+ } else {
+ row = 0;
+ col++;
+ }
+ }
+}
+
+
+/*!
+ \internal
+
+ This private slot tqfinds a widget in this group box that can accept
+ focus, and gives the focus to that widget.
+*/
+
+void TQGroupBox::fixFocus()
+{
+ TQFocusData * fd = focusData();
+ TQWidget * orig = fd->home();
+ TQWidget * best = 0;
+ TQWidget * candidate = 0;
+ TQWidget * w = orig;
+ do {
+ TQWidget * p = w;
+ while( p && p != this && !p->isTopLevel() )
+ p = p->parentWidget();
+ if ( p == this && ( w->focusPolicy() & Qt::TabFocus ) == Qt::TabFocus
+ && w->isVisibleTo(this) ) {
+ if ( w->hasFocus()
+#ifndef TQT_NO_RADIOBUTTON
+ || ( !best && ::tqqt_cast<TQRadioButton*>(w)
+ && ((TQRadioButton*)w)->isChecked() )
+#endif
+ )
+ // we prefer a checked radio button or a widget that
+ // already has focus, if there is one
+ best = w;
+ else if ( !candidate )
+ // but we'll accept anything that takes focus
+ candidate = w;
+ }
+ w = fd->next();
+ } while( w != orig );
+ if ( best )
+ best->setFocus();
+ else if ( candidate )
+ candidate->setFocus();
+}
+
+
+/*
+ Sets the right frame rect depending on the title. Also calculates
+ the visible part of the title.
+*/
+void TQGroupBox::calculateFrame()
+{
+ lenvisible = str.length();
+
+ if ( lenvisible && !isCheckable() ) { // do we have a label?
+ TQFontMetrics fm = fontMetrics();
+ while ( lenvisible ) {
+ int tw = fm.width( str, lenvisible ) + 4*fm.width(TQChar(' '));
+ if ( tw < width() )
+ break;
+ lenvisible--;
+ }
+ if ( lenvisible ) { // but do we also have a visible label?
+ TQRect r = rect();
+ int va = tqstyle().tqstyleHint(TQStyle::SH_GroupBox_TextLabelVerticalAlignment, this);
+ if(va & TQt::AlignVCenter)
+ r.setTop( fm.height()/2 ); // frame rect should be
+ else if(va & TQt::AlignTop)
+ r.setTop(fm.ascent());
+ setFrameRect( r ); // smaller than client rect
+ return;
+ }
+ } else if ( isCheckable() ) {
+#ifndef TQT_NO_CHECKBOX
+ TQRect r = rect();
+ int va = tqstyle().tqstyleHint(TQStyle::SH_GroupBox_TextLabelVerticalAlignment, this);
+ if( va & TQt::AlignVCenter )
+ r.setTop( d->checkbox->rect().height()/2 );
+ else if( va & TQt::AlignTop )
+ r.setTop( fontMetrics().ascent() );
+ setFrameRect( r );
+ return;
+#endif
+ }
+
+ // no visible label
+ setFrameRect( TQRect(0,0,0,0) ); // then use client rect
+}
+
+
+
+/*! \reimp
+ */
+void TQGroupBox::focusInEvent( TQFocusEvent * )
+{ // note no call to super
+ fixFocus();
+}
+
+
+/*!\reimp
+ */
+void TQGroupBox::fontChange( const TQFont & oldFont )
+{
+ TQWidget::fontChange( oldFont );
+#ifndef TQT_NO_CHECKBOX
+ updateCheckBoxGeometry();
+#endif
+ calculateFrame();
+ setTextSpacer();
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQGroupBox::tqsizeHint() const
+{
+ TQFontMetrics fm( font() );
+ int tw, th;
+ if ( isCheckable() ) {
+#ifndef TQT_NO_CHECKBOX
+ tw = d->checkbox->tqsizeHint().width() + 2*fm.width( "xx" );
+ th = d->checkbox->tqsizeHint().height() + fm.width( TQChar(' ') );
+#endif
+ } else {
+ tw = fm.width( title() ) + 2 * fm.width( "xx" );
+ th = fm.height() + fm.width( TQChar(' ') );
+ }
+
+ TQSize s;
+ if ( tqlayout() ) {
+ s = TQFrame::tqsizeHint();
+ return s.expandedTo( TQSize( tw, 0 ) );
+ } else {
+ TQRect r = tqchildrenRect();
+ TQSize s( 100, 50 );
+ s = s.expandedTo( TQSize( tw, th ) );
+ if ( r.isNull() )
+ return s;
+
+ return s.expandedTo( TQSize( r.width() + 2 * r.x(), r.height()+ 2 * r.y() ) );
+ }
+}
+
+/*!
+ \property TQGroupBox::flat
+ \brief whether the group box is painted flat or has a frame
+
+ By default a group box has a surrounding frame, with the title
+ being placed on the upper frame line. In flat mode the right, left
+ and bottom frame lines are omitted, and only the thin line at the
+ top is drawn.
+
+ \sa title
+*/
+bool TQGroupBox::isFlat() const
+{
+ return bFlat;
+}
+
+void TQGroupBox::setFlat( bool b )
+{
+ if ( (bool)bFlat == b )
+ return;
+ bFlat = b;
+ update();
+}
+
+
+/*!
+ \property TQGroupBox::checkable
+ \brief Whether the group box has a checkbox in its title.
+
+ If this property is TRUE, the group box has a checkbox. If the
+ checkbox is checked (which is the default), the group box's
+ tqchildren are enabled.
+
+ setCheckable() controls whether or not the group box has a
+ checkbox, and isCheckable() controls whether the checkbox is
+ checked or not.
+*/
+#ifndef TQT_NO_CHECKBOX
+void TQGroupBox::setCheckable( bool b )
+{
+ if ( (d->checkbox != 0) == b )
+ return;
+
+ if ( b ) {
+ if ( !d->checkbox ) {
+ d->checkbox = new TQCheckBox( title(), this, "qt_groupbox_checkbox" );
+ if (TQButtonGroup *meAsButtonGroup = ::tqqt_cast<TQButtonGroup*>(this))
+ meAsButtonGroup->remove(d->checkbox);
+ setChecked( TRUE );
+ setChildrenEnabled( TRUE );
+ connect( d->checkbox, TQT_SIGNAL( toggled(bool) ),
+ this, TQT_SLOT( setChildrenEnabled(bool) ) );
+ connect( d->checkbox, TQT_SIGNAL( toggled(bool) ),
+ this, TQT_SIGNAL( toggled(bool) ) );
+ updateCheckBoxGeometry();
+ }
+ d->checkbox->show();
+ } else {
+ setChildrenEnabled( TRUE );
+ delete d->checkbox;
+ d->checkbox = 0;
+ }
+ calculateFrame();
+ setTextSpacer();
+ update();
+}
+#endif //TQT_NO_CHECKBOX
+
+bool TQGroupBox::isCheckable() const
+{
+#ifndef TQT_NO_CHECKBOX
+ return ( d->checkbox != 0 );
+#else
+ return FALSE;
+#endif
+}
+
+
+bool TQGroupBox::isChecked() const
+{
+#ifndef TQT_NO_CHECKBOX
+ return d->checkbox && d->checkbox->isChecked();
+#else
+ return FALSE;
+#endif
+}
+
+
+/*!
+ \fn void TQGroupBox::toggled( bool on )
+
+ If the group box has a check box (see \l isCheckable()) this signal
+ is emitted when the check box is toggled. \a on is TRUE if the check
+ box is checked; otherwise it is FALSE.
+*/
+
+/*!
+ \property TQGroupBox::checked
+ \brief Whether the group box's checkbox is checked.
+
+ If the group box has a check box (see \l isCheckable()), and the
+ check box is checked (see \l isChecked()), the group box's tqchildren
+ are enabled. If the checkbox is unchecked the tqchildren are
+ disabled.
+*/
+#ifndef TQT_NO_CHECKBOX
+void TQGroupBox::setChecked( bool b )
+{
+ if ( d->checkbox )
+ d->checkbox->setChecked( b );
+}
+#endif
+
+/*
+ sets all tqchildren of the group box except the qt_groupbox_checkbox
+ to either disabled/enabled
+*/
+void TQGroupBox::setChildrenEnabled( bool b )
+{
+ if ( childrenListObject().isEmpty() )
+ return;
+ TQObjectListIt it( childrenListObject() );
+ TQObject *o;
+ while( (o = it.current()) ) {
+ ++it;
+ if ( o->isWidgetType()
+#ifndef TQT_NO_CHECKBOX
+ && o != TQT_TQOBJECT(d->checkbox)
+#endif
+ ) {
+ TQWidget *w = (TQWidget*)o;
+ if ( b ) {
+ if ( !w->testWState( TQt::WState_ForceDisabled ) )
+ w->setEnabled( TRUE );
+ } else {
+ if ( w->isEnabled() ) {
+ w->setEnabled( FALSE );
+ ((TQGroupBox*)w)->clearWState( TQt::WState_ForceDisabled );
+ }
+ }
+ }
+ }
+}
+
+/*! \reimp */
+void TQGroupBox::setEnabled(bool on)
+{
+ TQFrame::setEnabled(on);
+ if ( !d->checkbox || !on )
+ return;
+
+#ifndef TQT_NO_CHECKBOX
+ // we are being enabled - disable tqchildren
+ if ( !d->checkbox->isChecked() )
+ setChildrenEnabled( FALSE );
+#endif
+}
+
+/*
+ recalculates and sets the checkbox setGeometry
+*/
+#ifndef TQT_NO_CHECKBOX
+void TQGroupBox::updateCheckBoxGeometry()
+{
+ if ( d->checkbox ) {
+ TQSize cbSize = d->checkbox->tqsizeHint();
+ TQRect cbRect( 0, 0, cbSize.width(), cbSize.height() );
+
+ int marg = bFlat ? 2 : 8;
+ marg += fontMetrics().width( TQChar(' ') );
+
+ if ( align & TQt::AlignHCenter ) {
+ cbRect.moveCenter( frameRect().center() );
+ cbRect.moveTop( 0 );
+ } else if ( align & TQt::AlignRight ) {
+ cbRect.moveRight( frameRect().right() - marg );
+ } else if ( align & TQt::AlignLeft ) {
+ cbRect.moveLeft( frameRect().left() + marg );
+ } else { // auto align
+ if( TQApplication::reverseLayout() )
+ cbRect.moveRight( frameRect().right() - marg );
+ else
+ cbRect.moveLeft( frameRect().left() + marg );
+ }
+
+ d->checkbox->setGeometry( cbRect );
+ }
+}
+#endif //TQT_NO_CHECKBOX
+
+
+#endif //TQT_NO_GROUPBOX
diff --git a/tqtinterface/qt4/src/widgets/tqgroupbox.h b/tqtinterface/qt4/src/widgets/tqgroupbox.h
new file mode 100644
index 0000000..d73403e
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqgroupbox.h
@@ -0,0 +1,168 @@
+/**********************************************************************
+**
+** Definition of TQGroupBox widget class
+**
+** Created : 950203
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQGROUPBOX_H
+#define TQGROUPBOX_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_GROUPBOX
+
+
+class TQAccel;
+class TQGroupBoxPrivate;
+class TQVBoxLayout;
+class TQGridLayout;
+class TQSpacerItem;
+
+class TQ_EXPORT TQGroupBox : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( TQString title READ title WRITE setTitle )
+ Q_PROPERTY( Qt::Alignment tqalignment READ alignmentProp WRITE tqsetAlignmentProp )
+ Q_PROPERTY( Qt::Orientation orientation READ orientation WRITE setOrientation DESIGNABLE false )
+ Q_PROPERTY( int columns READ columns WRITE setColumns DESIGNABLE false )
+ Q_PROPERTY( bool flat READ isFlat WRITE setFlat )
+#ifndef TQT_NO_CHECKBOX
+ Q_PROPERTY( bool checkable READ isCheckable WRITE setCheckable )
+ Q_PROPERTY( bool checked READ isChecked WRITE setChecked )
+#endif
+public:
+ TQGroupBox( TQWidget* tqparent=0, const char* name=0 );
+ TQGroupBox( const TQString &title,
+ TQWidget* tqparent=0, const char* name=0 );
+ TQGroupBox( int strips, Qt::Orientation o,
+ TQWidget* tqparent=0, const char* name=0 );
+ TQGroupBox( int strips, Qt::Orientation o, const TQString &title,
+ TQWidget* tqparent=0, const char* name=0 );
+ ~TQGroupBox();
+
+ virtual void setColumnLayout(int strips, Qt::Orientation o);
+
+ TQString title() const { return str; }
+ virtual void setTitle( const TQString &);
+
+ int tqalignment() const { return align; }
+ virtual void tqsetAlignment( int );
+ inline Qt::Alignment alignmentProp() const { return (Qt::Alignment)tqalignment(); }
+ inline virtual void tqsetAlignmentProp( Qt::Alignment al ) { tqsetAlignment((int)al); }
+
+ int columns() const;
+ void setColumns( int );
+
+ Qt::Orientation orientation() const { return dir; }
+ void setOrientation( Qt::Orientation );
+
+ int insideMargin() const;
+ int insideSpacing() const;
+ void setInsideMargin( int m );
+ void setInsideSpacing( int s );
+
+ void addSpace( int );
+ TQSize tqsizeHint() const;
+
+ bool isFlat() const;
+ void setFlat( bool b );
+ bool isCheckable() const;
+#ifndef TQT_NO_CHECKBOX
+ void setCheckable( bool b );
+#endif
+ bool isChecked() const;
+ void setEnabled(bool on);
+
+#ifndef TQT_NO_CHECKBOX
+public Q_SLOTS:
+ void setChecked( bool b );
+
+Q_SIGNALS:
+ void toggled( bool );
+#endif
+protected:
+ bool event( TQEvent * );
+ void childEvent( TQChildEvent * );
+ void resizeEvent( TQResizeEvent * );
+ void paintEvent( TQPaintEvent * );
+ void focusInEvent( TQFocusEvent * );
+ void fontChange( const TQFont & );
+
+private Q_SLOTS:
+ void fixFocus();
+ void setChildrenEnabled( bool b );
+
+private:
+ void skip();
+ void init();
+ void calculateFrame();
+ void insertWid( TQWidget* );
+ void setTextSpacer();
+#ifndef TQT_NO_CHECKBOX
+ void updateCheckBoxGeometry();
+#endif
+ TQString str;
+ int align;
+ int lenvisible;
+#ifndef TQT_NO_ACCEL
+ TQAccel * accel;
+#endif
+ TQGroupBoxPrivate * d;
+
+ TQVBoxLayout *vbox;
+ TQGridLayout *grid;
+ int row;
+ int col : 30;
+ uint bFlat : 1;
+ int nRows, nCols;
+ Qt::Orientation dir;
+ int spac, marg;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQGroupBox( const TQGroupBox & );
+ TQGroupBox &operator=( const TQGroupBox & );
+#endif
+};
+
+
+#endif // TQT_NO_GROUPBOX
+
+#endif // TQGROUPBOX_H
diff --git a/tqtinterface/qt4/src/widgets/tqhbox.cpp b/tqtinterface/qt4/src/widgets/tqhbox.cpp
new file mode 100644
index 0000000..d25956d
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqhbox.cpp
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqhbox.h"
+#ifndef TQT_NO_HBOX
+#include "tqlayout.h"
+#include "tqapplication.h"
+#include "tqobjectlist.h"
+
+
+/*!
+ \class TQHBox tqhbox.h
+ \brief The TQHBox widget provides horizontal tqgeometry management
+ for its child widgets.
+
+ \ingroup organizers
+ \ingroup geomanagement
+ \ingroup appearance
+
+ All the horizontal box's child widgets will be placed alongside
+ each other and sized according to their tqsizeHint()s.
+
+ Use setMargin() to add space around the edges, and use
+ setSpacing() to add space between the widgets. Use
+ setStretchFactor() if you want the widgets to be different sizes
+ in proportion to one another. (See \link tqlayout.html
+ Layouts\endlink for more information on stretch factors.)
+
+ \img qhbox-m.png TQHBox
+
+ \sa TQHBoxLayout TQVBox TQGrid
+*/
+
+
+/*!
+ Constructs an hbox widget with tqparent \a tqparent, called \a name.
+ The tqparent, name and widget flags, \a f, are passed to the TQFrame
+ constructor.
+*/
+TQHBox::TQHBox( TQWidget *tqparent, const char *name, WFlags f )
+ :TQFrame( tqparent, name, f )
+{
+ lay = new TQHBoxLayout( this, frameWidth(), frameWidth(), name );
+ lay->setAutoAdd( TRUE );
+}
+
+
+/*!
+ Constructs a horizontal hbox if \a horizontal is TRUE, otherwise
+ constructs a vertical hbox (also known as a vbox).
+
+ This constructor is provided for the TQVBox class. You should never
+ need to use it directly.
+
+ The \a tqparent, \a name and widget flags, \a f, are passed to the
+ TQFrame constructor.
+*/
+
+TQHBox::TQHBox( bool horizontal, TQWidget *tqparent , const char *name, WFlags f )
+ :TQFrame( tqparent, name, f )
+{
+ lay = new TQBoxLayout( this,
+ horizontal ? TQBoxLayout::LeftToRight : TQBoxLayout::Down,
+ frameWidth(), frameWidth(), name );
+ lay->setAutoAdd( TRUE );
+}
+
+/*!\reimp
+ */
+void TQHBox::frameChanged()
+{
+ if ( !tqlayout() )
+ return;
+ tqlayout()->setMargin( frameWidth() );
+}
+
+
+/*!
+ Sets the spacing between the child widgets to \a space.
+*/
+
+void TQHBox::setSpacing( int space )
+{
+ if ( tqlayout() ) // ### why not use this->lay?
+ tqlayout()->setSpacing( space );
+}
+
+
+/*!
+ \reimp
+*/
+
+TQSize TQHBox::tqsizeHint() const
+{
+ TQWidget *mThis = (TQWidget*)this;
+ TQApplication::sendPostedEvents( mThis, TQEvent::ChildInserted );
+ return TQFrame::tqsizeHint();
+}
+
+/*!
+ Sets the stretch factor of widget \a w to \a stretch. Returns TRUE if
+ \a w is found. Otherwise returns FALSE.
+
+ \sa TQBoxLayout::setStretchFactor() \link tqlayout.html Layouts\endlink
+*/
+bool TQHBox::setStretchFactor( TQWidget* w, int stretch )
+{
+ TQWidget *mThis = (TQWidget*)this;
+ TQApplication::sendPostedEvents( mThis, TQEvent::ChildInserted );
+ return lay->setStretchFactor( w, stretch );
+}
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqhbox.h b/tqtinterface/qt4/src/widgets/tqhbox.h
new file mode 100644
index 0000000..e669eb0
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqhbox.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+
+#ifndef TQHBOX_H
+#define TQHBOX_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_HBOX
+
+#include "tqframe.h"
+
+class TQBoxLayout;
+
+class TQ_EXPORT TQHBox : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQHBox( TQWidget* tqparent=0, const char* name=0, WFlags f=0 );
+
+ void setSpacing( int );
+ bool setStretchFactor( TQWidget*, int stretch );
+ TQSize tqsizeHint() const;
+
+protected:
+ TQHBox( bool horizontal, TQWidget* tqparent, const char* name, WFlags f = 0 );
+ void frameChanged();
+
+private:
+ TQBoxLayout *lay;
+
+#if defined(TQ_DISABLE_COPY)
+ TQHBox( const TQHBox & );
+ TQHBox &operator=( const TQHBox & );
+#endif
+};
+
+#endif // TQT_NO_HBOX
+
+#endif // TQHBOX_H
diff --git a/tqtinterface/qt4/src/widgets/tqhbuttongroup.cpp b/tqtinterface/qt4/src/widgets/tqhbuttongroup.cpp
new file mode 100644
index 0000000..29af0a9
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqhbuttongroup.cpp
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Implementation of TQHButtonGroup class
+**
+** Created : 990602
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqhbuttongroup.h"
+#ifndef TQT_NO_HBUTTONGROUP
+
+/*!
+ \class TQHButtonGroup tqhbuttongroup.h
+ \brief The TQHButtonGroup widget organizes TQButton widgets in a
+ group with one horizontal row.
+
+ \ingroup organizers
+ \ingroup geomanagement
+ \ingroup appearance
+
+ TQHButtonGroup is a convenience class that offers a thin layer on
+ top of TQButtonGroup. From a tqlayout point of view it is effectively
+ a TQHBox that offers a frame with a title and is specifically
+ designed for buttons. From a functionality point of view it is a
+ TQButtonGroup.
+
+ \img qbuttongroup-h.png TQButtonGroup
+
+ \sa TQVButtonGroup
+*/
+
+/*!
+ Constructs a horizontal button group with no title.
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+*/
+TQHButtonGroup::TQHButtonGroup( TQWidget *tqparent, const char *name )
+ : TQButtonGroup( 1, Qt::Vertical /* sic! */, tqparent, name )
+{
+}
+
+/*!
+ Constructs a horizontal button group with the title \a title.
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+*/
+
+TQHButtonGroup::TQHButtonGroup( const TQString &title, TQWidget *tqparent,
+ const char *name )
+ : TQButtonGroup( 1, Qt::Vertical /* sic! */, title, tqparent, name )
+{
+}
+
+/*!
+ Destroys the horizontal button group, deleting its child widgets.
+*/
+TQHButtonGroup::~TQHButtonGroup()
+{
+}
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqhbuttongroup.h b/tqtinterface/qt4/src/widgets/tqhbuttongroup.h
new file mode 100644
index 0000000..0a0cf50
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqhbuttongroup.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Definition of TQHButtonGroup class
+**
+** Created : 990602
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQHBUTTONGROUP_H
+#define TQHBUTTONGROUP_H
+
+#ifndef TQT_H
+#include "tqbuttongroup.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_HBUTTONGROUP
+
+class TQ_EXPORT TQHButtonGroup : public TQButtonGroup
+{
+ TQ_OBJECT
+public:
+ TQHButtonGroup( TQWidget* tqparent=0, const char* name=0 );
+ TQHButtonGroup( const TQString &title, TQWidget* tqparent=0, const char* name=0 );
+ ~TQHButtonGroup();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQHButtonGroup( const TQHButtonGroup & );
+ TQHButtonGroup &operator=( const TQHButtonGroup & );
+#endif
+};
+
+
+#endif // TQT_NO_HBUTTONGROUP
+
+#endif // TQHBUTTONGROUP_H
diff --git a/tqtinterface/qt4/src/widgets/tqheader.cpp b/tqtinterface/qt4/src/widgets/tqheader.cpp
new file mode 100644
index 0000000..67fb7f0
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqheader.cpp
@@ -0,0 +1,2049 @@
+/****************************************************************************
+**
+** Implementation of TQHeader widget class (table header)
+**
+** Created : 961105
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqheader.h"
+#ifndef TQT_NO_HEADER
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqpixmap.h"
+#include "tqbitarray.h"
+#include "tqptrvector.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+
+class TQHeaderData
+{
+public:
+ TQHeaderData(int n)
+ {
+ count = n;
+ labels.setAutoDelete( TRUE );
+ iconsets.setAutoDelete( TRUE );
+ sizes.resize(n);
+ positions.resize(n);
+ labels.resize(n);
+ if ( int( iconsets.size() ) < n )
+ iconsets.resize( n );
+ i2s.resize(n);
+ s2i.resize(n);
+ clicks.resize(n);
+ resize.resize(n);
+ int p =0;
+ for ( int i = 0; i < n; i ++ ) {
+ sizes[i] = 88;
+ i2s[i] = i;
+ s2i[i] = i;
+ positions[i] = p;
+ p += sizes[i];
+ }
+ clicks_default = TRUE;
+ resize_default = TRUE;
+ clicks.fill( clicks_default );
+ resize.fill( resize_default );
+ move = TRUE;
+ sortSection = -1;
+ sortDirection = TRUE;
+ positionsDirty = TRUE;
+ lastPos = 0;
+ fullSize = -2;
+ pos_dirty = FALSE;
+ is_a_table_header = FALSE;
+ focusIdx = 0;
+ }
+
+
+ TQMemArray<TQCOORD> sizes;
+ int height; // we abuse the heights as widths for vertical tqlayout
+ bool heightDirty;
+ TQMemArray<TQCOORD> positions; // sorted by index
+ TQPtrVector<TQString> labels;
+ TQPtrVector<TQIconSet> iconsets;
+ TQMemArray<int> i2s;
+ TQMemArray<int> s2i;
+
+ TQBitArray clicks;
+ TQBitArray resize;
+ uint move : 1;
+ uint clicks_default : 1; // default value for new clicks bits
+ uint resize_default : 1; // default value for new resize bits
+ uint pos_dirty : 1;
+ uint is_a_table_header : 1;
+ bool sortDirection;
+ bool positionsDirty;
+ int sortSection;
+ int count;
+ int lastPos;
+ int fullSize;
+ int focusIdx;
+ int pressDelta;
+
+ int sectionAt( int pos ) {
+ // positions is sorted by index, not by section
+ if ( !count )
+ return -1;
+ int l = 0;
+ int r = count - 1;
+ int i = ( (l+r+1) / 2 );
+ while ( r - l ) {
+ if ( positions[i] > pos )
+ r = i -1;
+ else
+ l = i;
+ i = ( (l+r+1) / 2 );
+ }
+ if ( positions[i] <= pos && pos <= positions[i] + sizes[ i2s[i] ] )
+ return i2s[i];
+ return -1;
+ }
+};
+
+
+/*!
+ \class TQHeader tqheader.h
+ \brief The TQHeader class provides a header row or column, e.g. for
+ tables and listviews.
+
+ \ingroup advanced
+
+ This class provides a header, e.g. a vertical header to display
+ row labels, or a horizontal header to display column labels. It is
+ used by TQTable and TQListView for example.
+
+ A header is composed of one or more \e sections, each of which can
+ display a text label and an \link TQIconSet iconset\endlink. A sort
+ indicator (an arrow) can also be displayed using
+ setSortIndicator().
+
+ Sections are added with addLabel() and removed with removeLabel().
+ The label and iconset are set in addLabel() and can be changed
+ later with setLabel(). Use count() to retrieve the number of
+ sections in the header.
+
+ The orientation of the header is set with setOrientation(). If
+ setStretchEnabled() is TRUE, the sections will expand to take up
+ the full width (height for vertical headers) of the header. The
+ user can resize the sections manually if setResizeEnabled() is
+ TRUE. Call adjustHeaderSize() to have the sections resize to
+ occupy the full width (or height).
+
+ A section can be moved with moveSection(). If setMovingEnabled()
+ is TRUE (the default)the user may drag a section from one position
+ to another. If a section is moved, the index positions at which
+ sections were added (with addLabel()), may not be the same after the
+ move. You don't have to worry about this in practice because the
+ TQHeader API works in terms of section numbers, so it doesn't matter
+ where a particular section has been moved to.
+
+ If you want the current index position of a section call
+ mapToIndex() giving it the section number. (This is the number
+ returned by the addLabel() call which created the section.) If you
+ want to get the section number of a section at a particular index
+ position call mapToSection() giving it the index number.
+
+ Here's an example to clarify mapToSection() and mapToIndex():
+
+ \table
+ \header \i41 Index positions
+ \row \i 0 \i 1 \i 2 \i 3
+ \header \i41 Original section ordering
+ \row \i Sect 0 \i Sect 1 \i Sect 2 \i Sect 3
+ \header \i41 Ordering after the user moves a section
+ \row \i Sect 0 \i Sect 2 \i Sect 3 \i Sect 1
+ \endtable
+
+ \table
+ \header \i \e k \i mapToSection(\e k) \i mapToIndex(\e k)
+ \row \i 0 \i 0 \i 0
+ \row \i 1 \i 2 \i 3
+ \row \i 2 \i 3 \i 1
+ \row \i 3 \i 1 \i 2
+ \endtable
+
+ In the example above, if we wanted to tqfind out which section is at
+ index position 3 we'd call mapToSection(3) and get a section
+ number of 1 since section 1 was moved. Similarly, if we wanted to
+ know which index position section 2 occupied we'd call
+ mapToIndex(2) and get an index of 1.
+
+ TQHeader provides the clicked(), pressed() and released() Q_SIGNALS.
+ If the user changes the size of a section, the sizeChange() signal
+ is emitted. If you want to have a sizeChange() signal emitted
+ continuously whilst the user is resizing (rather than just after
+ the resizing is finished), use setTracking(). If the user moves a
+ section the indexChange() signal is emitted.
+
+ <img src=qheader-m.png> <img src=qheader-w.png>
+
+ \sa TQListView TQTable
+*/
+
+
+
+/*!
+ Constructs a horizontal header called \a name, with tqparent \a
+ tqparent.
+*/
+
+TQHeader::TQHeader( TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name, TQt::WStaticContents )
+{
+ orient = Qt::Horizontal;
+ init( 0 );
+}
+
+/*!
+ Constructs a horizontal header called \a name, with \a n sections
+ and tqparent \a tqparent.
+*/
+
+TQHeader::TQHeader( int n, TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name, TQt::WStaticContents )
+{
+ orient = Qt::Horizontal;
+ init( n );
+}
+
+/*!
+ Destroys the header and all its sections.
+*/
+
+TQHeader::~TQHeader()
+{
+ delete d;
+ d = 0;
+}
+
+/*! \reimp
+ */
+
+void TQHeader::showEvent( TQShowEvent *e )
+{
+ calculatePositions();
+ TQWidget::showEvent( e );
+}
+
+/*!
+ \fn void TQHeader::sizeChange( int section, int oldSize, int newSize )
+
+ This signal is emitted when the user has changed the size of a \a
+ section from \a oldSize to \a newSize. This signal is typically
+ connected to a slot that repaints the table or list that tqcontains
+ the header.
+*/
+
+/*!
+ \fn void TQHeader::clicked( int section )
+
+ If isClickEnabled() is TRUE, this signal is emitted when the user
+ clicks section \a section.
+
+ \sa pressed(), released()
+*/
+
+/*!
+ \fn void TQHeader::pressed( int section )
+
+ This signal is emitted when the user presses section \a section
+ down.
+
+ \sa released()
+*/
+
+/*!
+ \fn void TQHeader::released( int section )
+
+ This signal is emitted when section \a section is released.
+
+ \sa pressed()
+*/
+
+
+/*!
+ \fn void TQHeader::indexChange( int section, int fromIndex, int toIndex )
+
+ This signal is emitted when the user moves section \a section from
+ index position \a fromIndex, to index position \a toIndex.
+*/
+
+/*!
+ \fn void TQHeader::moved( int fromIndex, int toIndex )
+ \obsolete
+
+ Use indexChange() instead.
+
+ This signal is emitted when the user has moved the section which
+ is displayed at the index \a fromIndex to the index \a toIndex.
+*/
+
+/*!
+ \fn void TQHeader::sectionClicked( int index )
+ \obsolete
+
+ Use clicked() instead.
+
+ This signal is emitted when a part of the header is clicked. \a
+ index is the index at which the section is displayed.
+
+ In a list view this signal would typically be connected to a slot
+ that sorts the specified column (or row).
+*/
+
+/*! \fn int TQHeader::cellSize( int ) const
+ \obsolete
+
+ Use sectionSize() instead.
+
+ Returns the size in pixels of the section that is displayed at
+ the index \a i.
+*/
+
+/*!
+ \fn void TQHeader::sectionHandleDoubleClicked( int section )
+
+ This signal is emitted when the user doubleclicks on the edge
+ (handle) of section \a section.
+*/
+
+/*!
+ \obsolete
+
+ Use sectionPos() instead.
+
+ Returns the position in pixels of the section that is displayed at the
+ index \a i. The position is measured from the start of the header.
+*/
+
+int TQHeader::cellPos( int i ) const
+{
+ if ( i == count() && i > 0 )
+ return d->positions[i-1] + d->sizes[d->i2s[i-1]]; // compatibility
+ return sectionPos( mapToSection(i) );
+}
+
+
+/*!
+ \property TQHeader::count
+ \brief the number of sections in the header
+*/
+
+int TQHeader::count() const
+{
+ return d->count;
+}
+
+
+/*!
+ \property TQHeader::tracking
+ \brief whether the sizeChange() signal is emitted continuously
+
+ If tracking is on, the sizeChange() signal is emitted continuously
+ while the mouse is moved (i.e. when the header is resized),
+ otherwise it is only emitted when the mouse button is released at
+ the end of resizing.
+
+ Tracking defaults to FALSE.
+*/
+
+
+/*
+ Initializes with \a n columns.
+*/
+void TQHeader::init( int n )
+{
+ state = Idle;
+ cachedPos = 0; // unused
+ d = new TQHeaderData( n );
+ d->height = 0;
+ d->heightDirty = TRUE;
+ offs = 0;
+ if( reverse() )
+ offs = d->lastPos - width();
+ oldHandleIdx = oldHIdxSize = handleIdx = 0;
+
+ setMouseTracking( TRUE );
+ trackingIsOn = FALSE;
+ setBackgroundMode( TQt::PaletteButton );
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) );
+}
+
+/*!
+ \property TQHeader::orientation
+ \brief the header's orientation
+
+ The orientation is either \c Qt::Vertical or \c Qt::Horizontal (the
+ default).
+
+ Call setOrientation() before adding labels if you don't provide a
+ size parameter otherwise the sizes will be incorrect.
+*/
+
+void TQHeader::setOrientation( Qt::Orientation orientation )
+{
+ if ( orient == orientation )
+ return;
+ orient = orientation;
+ if ( orient == Qt::Horizontal )
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) );
+ else
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Fixed, TQSizePolicy::Preferred ) );
+ update();
+ updateGeometry();
+}
+
+
+/*
+ Paints a rectangle starting at \a p, with length \s.
+*/
+void TQHeader::paintRect( int p, int s )
+{
+ TQPainter paint( this );
+ paint.setPen( TQPen( Qt::black, 1, Qt::DotLine ) );
+ if ( reverse() )
+ paint.drawRect( p - s, 3, s, height() - 5 );
+ else if ( orient == Qt::Horizontal )
+ paint.drawRect( p, 3, s, height() - 5 );
+ else
+ paint.drawRect( 3, p, height() - 5, s );
+}
+
+/*
+ Marks the division line at \a idx.
+*/
+void TQHeader::markLine( int idx )
+{
+ TQPainter paint( this );
+ paint.setPen( TQPen( Qt::black, 1, Qt::DotLine ) );
+ int MARKSIZE = tqstyle().tqpixelMetric( TQStyle::PM_HeaderMarkSize );
+ int p = pPos( idx );
+ int x = p - MARKSIZE/2;
+ int y = 2;
+ int x2 = p + MARKSIZE/2;
+ int y2 = height() - 3;
+ if ( orient == Qt::Vertical ) {
+ int t = x; x = y; y = t;
+ t = x2; x2 = y2; y2 = t;
+ }
+
+ paint.drawLine( x, y, x2, y );
+ paint.drawLine( x, y+1, x2, y+1 );
+
+ paint.drawLine( x, y2, x2, y2 );
+ paint.drawLine( x, y2-1, x2, y2-1 );
+
+ paint.drawLine( x, y, x, y2 );
+ paint.drawLine( x+1, y, x+1, y2 );
+
+ paint.drawLine( x2, y, x2, y2 );
+ paint.drawLine( x2-1, y, x2-1, y2 );
+}
+
+/*
+ Removes the mark at the division line at \a idx.
+*/
+void TQHeader::unMarkLine( int idx )
+{
+ if ( idx < 0 )
+ return;
+ int MARKSIZE = tqstyle().tqpixelMetric( TQStyle::PM_HeaderMarkSize );
+ int p = pPos( idx );
+ int x = p - MARKSIZE/2;
+ int y = 2;
+ int x2 = p + MARKSIZE/2;
+ int y2 = height() - 3;
+ if ( orient == Qt::Vertical ) {
+ int t = x; x = y; y = t;
+ t = x2; x2 = y2; y2 = t;
+ }
+ tqrepaint( x, y, x2-x+1, y2-y+1 );
+}
+
+/*! \fn int TQHeader::cellAt( int ) const
+ \obsolete
+
+ Use sectionAt() instead.
+
+ Returns the index at which the section is displayed, which tqcontains
+ \a pos in widget coordinates, or -1 if \a pos is outside the header
+ sections.
+*/
+
+/*
+ Tries to tqfind a line that is not a neighbor of \c handleIdx.
+*/
+int TQHeader::tqfindLine( int c )
+{
+ int i = 0;
+ if ( c > d->lastPos || (reverse() && c < 0 )) {
+ return d->count;
+ } else {
+ int section = sectionAt( c );
+ if ( section < 0 )
+ return handleIdx;
+ i = d->s2i[section];
+ }
+ int MARKSIZE = tqstyle().tqpixelMetric( TQStyle::PM_HeaderMarkSize );
+ if ( i == handleIdx )
+ return i;
+ if ( i == handleIdx - 1 && pPos( handleIdx ) - c > MARKSIZE/2 )
+ return i;
+ if ( i == handleIdx + 1 && c - pPos( i ) > MARKSIZE/2 )
+ return i + 1;
+ if ( c - pPos( i ) > pSize( i ) / 2 )
+ return i + 1;
+ else
+ return i;
+}
+
+/*!
+ Returns the handle at position \a p, or -1 if there is no handle at \a p.
+*/
+int TQHeader::handleAt(int p)
+{
+ int section = d->sectionAt( p );
+ if ( section >= 0 ) {
+ int GripMargin = (bool)d->resize[ section ] ?
+ tqstyle().tqpixelMetric( TQStyle::PM_HeaderGripMargin ) : 0;
+ int index = d->s2i[section];
+ if ( (index > 0 && p < d->positions[index] + GripMargin) ||
+ (p > d->positions[index] + d->sizes[section] - GripMargin) ) {
+ if ( index > 0 && p < d->positions[index] + GripMargin )
+ section = d->i2s[--index];
+ // dont show icon if streaching is enabled it is at the end of the last section
+ if ( d->resize.testBit(section) && (d->fullSize == -2 || index != count() - 1)) {
+ return section;
+ }
+ }
+ }
+
+ return -1;
+}
+
+/*!
+ \obsolete
+
+ Use moveSection() instead.
+
+ Moves the section that is currently displayed at index \a fromIdx
+ to index \a toIdx.
+*/
+
+void TQHeader::moveCell( int fromIdx, int toIdx )
+{
+ moveSection( mapToSection(fromIdx), toIdx );
+}
+
+
+
+/*!
+ Move and signal and tqrepaint.
+ */
+
+void TQHeader::handleColumnMove( int fromIdx, int toIdx )
+{
+ int s = d->i2s[fromIdx];
+ if ( fromIdx < toIdx )
+ toIdx++; //Convert to
+ TQRect r = sRect( fromIdx );
+ r |= sRect( toIdx );
+ moveSection( s, toIdx );
+ update( r );
+ emit moved( fromIdx, toIdx );
+ emit indexChange( s, fromIdx, toIdx );
+}
+
+/*!
+ \reimp
+*/
+void TQHeader::keyPressEvent( TQKeyEvent *e )
+{
+ int i = d->focusIdx;
+ if ( e->key() == Qt::Key_Space ) {
+ //don't do it if we're doing something with the mouse
+ if ( state == Idle && d->clicks[ d->i2s[d->focusIdx] ] ) {
+ handleIdx = i;
+ state = Pressed;
+ tqrepaint( sRect( handleIdx ) );
+ emit pressed( d->i2s[i] );
+ }
+ } else if ( (orientation() == Qt::Horizontal &&
+ (e->key() == Qt::Key_Right || e->key() == Qt::Key_Left))
+ || (orientation() == Qt::Vertical &&
+ (e->key() == Qt::Key_Up || e->key() == Qt::Key_Down)) ) {
+ int dir = e->key() == Qt::Key_Right || e->key() == Qt::Key_Down ? 1 : -1;
+ int s = d->i2s[i];
+ if ( e->state() & ControlButton && d->resize[s] ) {
+ //resize
+ int step = e->state() & ShiftButton ? dir : 10*dir;
+ int c = d->positions[i] + d->sizes[s] + step;
+ handleColumnResize( i, c, TRUE );
+ } else if ( e->state() & (TQt::AltButton|TQt::MetaButton) && d->move ) {
+ //move section
+ int i2 = ( i + count() + dir ) % count();
+ d->focusIdx = i2;
+ handleColumnMove( i, i2 );
+ } else {
+ //focus on different section
+ TQRect r = sRect( d->focusIdx );
+ d->focusIdx = (d->focusIdx + count() + dir) % count();
+ r |= sRect( d->focusIdx );
+ update( r );
+ }
+ } else {
+ e->ignore();
+ }
+}
+
+/*!
+ \reimp
+*/
+void TQHeader::keyReleaseEvent( TQKeyEvent *e )
+{
+ switch ( e->key() ) {
+ case Qt::Key_Space:
+ //double check that this wasn't started with the mouse
+ if ( state == Pressed && handleIdx == d->focusIdx ) {
+ tqrepaint(sRect( handleIdx ), FALSE);
+ int section = d->i2s[d->focusIdx];
+ emit released( section );
+ emit sectionClicked( handleIdx );
+ emit clicked( section );
+ state = Idle;
+ handleIdx = -1;
+ }
+ break;
+ default:
+ e->ignore();
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQHeader::mousePressEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton || state != Idle )
+ return;
+ oldHIdxSize = handleIdx;
+ handleIdx = 0;
+ int c = orient == Qt::Horizontal ? e->pos().x() : e->pos().y();
+ c += offset();
+ if ( reverse() )
+ c = d->lastPos - c;
+
+ int section = d->sectionAt( c );
+ if ( section < 0 )
+ return;
+ int GripMargin = (bool)d->resize[ section ] ?
+ tqstyle().tqpixelMetric( TQStyle::PM_HeaderGripMargin ) : 0;
+ int index = d->s2i[section];
+
+ if ( (index > 0 && c < d->positions[index] + GripMargin) ||
+ (c > d->positions[index] + d->sizes[section] - GripMargin) ) {
+ if ( c < d->positions[index] + GripMargin )
+ handleIdx = index-1;
+ else
+ handleIdx = index;
+ if ( d->lastPos <= ( orient == Qt::Horizontal ? width() :
+ height() ) && d->fullSize != -2 && handleIdx == count() - 1 ) {
+ handleIdx = -1;
+ return;
+ }
+ oldHIdxSize = d->sizes[ d->i2s[handleIdx] ];
+ state = d->resize[ d->i2s[handleIdx] ] ? Sliding : Blocked;
+ } else if ( index >= 0 ) {
+ oldHandleIdx = handleIdx = index;
+ moveToIdx = -1;
+ state = d->clicks[ d->i2s[handleIdx] ] ? Pressed : Blocked;
+ clickPos = c;
+ tqrepaint( sRect( handleIdx ) );
+ if(oldHandleIdx != handleIdx)
+ tqrepaint( sRect( oldHandleIdx ) );
+ emit pressed( section );
+ }
+
+ d->pressDelta = c - ( d->positions[handleIdx] + d->sizes[ d->i2s[handleIdx] ] );
+}
+
+/*!
+ \reimp
+*/
+void TQHeader::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+ int oldOldHandleIdx = oldHandleIdx;
+ State oldState = state;
+ state = Idle;
+ switch ( oldState ) {
+ case Pressed: {
+ int section = d->i2s[handleIdx];
+ emit released( section );
+ if ( sRect( handleIdx ).tqcontains( e->pos() ) ) {
+ oldHandleIdx = handleIdx;
+ emit sectionClicked( handleIdx );
+ emit clicked( section );
+ } else {
+ handleIdx = oldHandleIdx;
+ }
+ tqrepaint(sRect( handleIdx ), FALSE);
+ if ( oldOldHandleIdx != handleIdx )
+ tqrepaint(sRect(oldOldHandleIdx ), FALSE );
+ } break;
+ case Sliding: {
+ int c = orient == Qt::Horizontal ? e->pos().x() : e->pos().y();
+ c += offset();
+ if ( reverse() )
+ c = d->lastPos - c;
+ handleColumnResize( handleIdx, c - d->pressDelta, TRUE );
+ } break;
+ case Moving: {
+#ifndef TQT_NO_CURSOR
+ unsetCursor();
+#endif
+ int section = d->i2s[handleIdx];
+ if ( handleIdx != moveToIdx && moveToIdx != -1 ) {
+ moveSection( section, moveToIdx );
+ handleIdx = oldHandleIdx;
+ emit moved( handleIdx, moveToIdx );
+ emit indexChange( section, handleIdx, moveToIdx );
+ emit released( section );
+ tqrepaint(); // a bit overkill, but removes the handle as well
+ } else {
+ if ( sRect( handleIdx).tqcontains( e->pos() ) ) {
+ oldHandleIdx = handleIdx;
+ emit released( section );
+ emit sectionClicked( handleIdx );
+ emit clicked( section );
+ } else {
+ handleIdx = oldHandleIdx;
+ }
+ tqrepaint(sRect( handleIdx ), FALSE );
+ if(oldOldHandleIdx != handleIdx)
+ tqrepaint(sRect(oldOldHandleIdx ), FALSE );
+ }
+ break;
+ }
+ case Blocked:
+ //nothing
+ break;
+ default:
+ // empty, probably. Idle, at any rate.
+ break;
+ }
+}
+
+/*!
+ \reimp
+*/
+void TQHeader::mouseMoveEvent( TQMouseEvent *e )
+{
+ int c = orient == Qt::Horizontal ? e->pos().x() : e->pos().y();
+ c += offset();
+
+ int pos = c;
+ if( reverse() )
+ c = d->lastPos - c;
+
+ switch( state ) {
+ case Idle:
+#ifndef TQT_NO_CURSOR
+ if ( handleAt(c) < 0 )
+ unsetCursor();
+ else if ( orient == Qt::Horizontal )
+ setCursor( Qt::SplitHCursor );
+ else
+ setCursor( Qt::SplitVCursor );
+#endif
+ break;
+ case Blocked:
+ break;
+ case Pressed:
+ if ( TQABS( c - clickPos ) > 4 && d->move ) {
+ state = Moving;
+ moveToIdx = -1;
+#ifndef TQT_NO_CURSOR
+ if ( orient == Qt::Horizontal )
+ setCursor( Qt::SizeHorCursor );
+ else
+ setCursor( Qt::SizeVerCursor );
+#endif
+ }
+ break;
+ case Sliding:
+ handleColumnResize( handleIdx, c, FALSE, FALSE );
+ break;
+ case Moving: {
+ int newPos = tqfindLine( pos );
+ if ( newPos != moveToIdx ) {
+ if ( moveToIdx == handleIdx || moveToIdx == handleIdx + 1 )
+ tqrepaint( sRect(handleIdx) );
+ else
+ unMarkLine( moveToIdx );
+ moveToIdx = newPos;
+ if ( moveToIdx == handleIdx || moveToIdx == handleIdx + 1 )
+ paintRect( pPos( handleIdx ), pSize( handleIdx ) );
+ else
+ markLine( moveToIdx );
+ }
+ break;
+ }
+ default:
+ qWarning( "TQHeader::mouseMoveEvent: (%s) unknown state", name() );
+ break;
+ }
+}
+
+/*! \reimp */
+
+void TQHeader::mouseDoubleClickEvent( TQMouseEvent *e )
+{
+ int p = orient == Qt::Horizontal ? e->pos().x() : e->pos().y();
+ p += offset();
+ if( reverse() )
+ p = d->lastPos - p;
+
+ int header = handleAt(p);
+ if (header >= 0)
+ emit sectionHandleDoubleClicked( header );
+}
+
+/*
+ Handles resizing of sections. This means it redraws the relevant parts
+ of the header.
+*/
+
+void TQHeader::handleColumnResize( int index, int c, bool final, bool recalcAll )
+{
+ int section = d->i2s[index];
+ int GripMargin = (bool)d->resize[ section ] ?
+ tqstyle().tqpixelMetric( TQStyle::PM_HeaderGripMargin ) : 0;
+ int lim = d->positions[index] + 2*GripMargin;
+ if ( c == lim )
+ return;
+ if ( c < lim )
+ c = lim;
+ int oldSize = d->sizes[section];
+ int newSize = c - d->positions[index];
+ d->sizes[section] = newSize;
+
+ calculatePositions( !recalcAll, !recalcAll ? section : 0 );
+
+ int pos = d->positions[index]-offset();
+ if( reverse() ) // tqrepaint the whole thing. Could be optimized (lars)
+ tqrepaint( 0, 0, width(), height() );
+ else if ( orient == Qt::Horizontal )
+ tqrepaint( pos, 0, width() - pos, height() );
+ else
+ tqrepaint( 0, pos, width(), height() - pos );
+
+ int os = 0, ns = 0;
+ if ( tracking() && oldSize != newSize ) {
+ os = oldSize;
+ ns = newSize;
+ emit sizeChange( section, oldSize, newSize );
+ } else if ( !tracking() && final && oldHIdxSize != newSize ) {
+ os = oldHIdxSize;
+ ns = newSize;
+ emit sizeChange( section, oldHIdxSize, newSize );
+ }
+
+ if ( os != ns ) {
+ if ( d->fullSize == -1 ) {
+ d->fullSize = count() - 1;
+ adjustHeaderSize();
+ d->fullSize = -1;
+ } else if ( d->fullSize >= 0 ) {
+ int old = d->fullSize;
+ d->fullSize = count() - 1;
+ adjustHeaderSize();
+ d->fullSize = old;
+ }
+ }
+}
+
+/*!
+ Returns the rectangle covered by the section at index \a index.
+*/
+
+TQRect TQHeader::sRect( int index )
+{
+
+ int section = mapToSection( index );
+ if ( count() > 0 && index >= count() ) {
+ int s = d->positions[count() - 1] - offset() +
+ d->sizes[mapToSection(count() - 1)];
+ if ( orient == Qt::Horizontal )
+ return TQRect( s, 0, width() - s + 10, height() );
+ else
+ return TQRect( 0, s, width(), height() - s + 10 );
+ }
+ if ( section < 0 )
+ return rect(); // ### eeeeevil
+
+ if ( reverse() )
+ return TQRect( d->lastPos - d->positions[index] - d->sizes[section] -offset(),
+ 0, d->sizes[section], height() );
+ else if ( orient == Qt::Horizontal )
+ return TQRect( d->positions[index]-offset(), 0, d->sizes[section], height() );
+ else
+ return TQRect( 0, d->positions[index]-offset(), width(), d->sizes[section] );
+}
+
+/*!
+ Returns the rectangle covered by section \a section.
+*/
+
+TQRect TQHeader::sectionRect( int section ) const
+{
+ int index = mapToIndex( section );
+ if ( section < 0 )
+ return rect(); // ### eeeeevil
+
+ if ( reverse() )
+ return TQRect( d->lastPos - d->positions[index] - d->sizes[section] -offset(),
+ 0, d->sizes[section], height() );
+ else if ( orient == Qt::Horizontal )
+ return TQRect( d->positions[index]-offset(), 0, d->sizes[section], height() );
+ else
+ return TQRect( 0, d->positions[index]-offset(), width(), d->sizes[section] );
+}
+
+/*!
+ \overload
+
+ Sets the icon for section \a section to \a iconset and the text to
+ \a s. The section's width is set to \a size if \a size \>= 0;
+ otherwise it is left unchanged.
+
+ If the section does not exist, nothing happens.
+*/
+
+void TQHeader::setLabel( int section, const TQIconSet& iconset,
+ const TQString &s, int size )
+{
+ if ( section < 0 || section >= count() )
+ return;
+ d->iconsets.insert( section, new TQIconSet( iconset ) );
+ setLabel( section, s, size );
+}
+
+/*!
+ Sets the text of section \a section to \a s. The section's width
+ is set to \a size if \a size \>= 0; otherwise it is left
+ unchanged. Any icon set that has been set for this section remains
+ unchanged.
+
+ If the section does not exist, nothing happens.
+*/
+void TQHeader::setLabel( int section, const TQString &s, int size )
+{
+ if ( section < 0 || section >= count() )
+ return;
+ if ( s.isNull() )
+ d->labels.remove( section );
+ else
+ d->labels.insert( section, new TQString( s ) );
+
+ setSectionSizeAndHeight( section, size );
+
+ if ( isUpdatesEnabled() ) {
+ updateGeometry();
+ calculatePositions();
+ update();
+ }
+}
+
+
+bool qt_qheader_label_return_null_strings = FALSE;
+/*!
+ Returns the text for section \a section. If the section does not
+ exist, a TQString::null is returned.
+*/
+TQString TQHeader::label( int section ) const
+{
+ if ( section < 0 || section >= count() )
+ return TQString::null;
+ if ( d->labels[ section ] )
+ return *( d->labels[ section ] );
+ else if ( qt_qheader_label_return_null_strings )
+ return TQString::null;
+ else
+ return TQString::number( section + 1 );
+}
+
+/*!
+ Returns the icon set for section \a section. If the section does
+ not exist, 0 is returned.
+*/
+
+TQIconSet *TQHeader::iconSet( int section ) const
+{
+ if ( section < 0 || section >= count() )
+ return 0;
+ return d->iconsets[ section ];
+}
+
+
+/*!
+ \overload
+
+ Adds a new section with iconset \a iconset and label text \a s.
+ Returns the index position where the section was added (at the
+ right for horizontal headers, at the bottom for vertical headers).
+ The section's width is set to \a size, unless size is negative in
+ which case the size is calculated taking account of the size of
+ the text.
+*/
+int TQHeader::addLabel( const TQIconSet& iconset, const TQString &s, int size )
+{
+ int n = count() + 1;
+ d->iconsets.resize( n + 1 );
+ d->iconsets.insert( n - 1, new TQIconSet( iconset ) );
+ return addLabel( s, size );
+}
+
+/*!
+ Removes section \a section. If the section does not exist, nothing
+ happens.
+*/
+void TQHeader::removeLabel( int section )
+{
+ if ( section < 0 || section > count() - 1 )
+ return;
+
+ int index = d->s2i[section];
+ int n = --d->count;
+ int i;
+ for ( i = section; i < n; ++i ) {
+ d->sizes[i] = d->sizes[i+1];
+ d->labels.insert( i, d->labels.take( i + 1 ) );
+ d->iconsets.insert( i, d->iconsets.take( i + 1 ) );
+ }
+
+ d->sizes.resize( n );
+ d->positions.resize( n );
+ d->labels.resize( n );
+ d->iconsets.resize( n );
+
+ for ( i = section; i < n; ++i )
+ d->s2i[i] = d->s2i[i+1];
+ d->s2i.resize( n );
+
+ if ( isUpdatesEnabled() ) {
+ for ( i = 0; i < n; ++i )
+ if ( d->s2i[i] > index )
+ --d->s2i[i];
+ }
+
+ for ( i = index; i < n; ++i )
+ d->i2s[i] = d->i2s[i+1];
+ d->i2s.resize( n );
+
+ if ( isUpdatesEnabled() ) {
+ for ( i = 0; i < n; ++i )
+ if ( d->i2s[i] > section )
+ --d->i2s[i];
+ }
+
+ if ( isUpdatesEnabled() ) {
+ updateGeometry();
+ calculatePositions();
+ update();
+ }
+}
+
+TQSize TQHeader::sectionSizeHint( int section, const TQFontMetrics& fm ) const
+{
+ int iw = 0;
+ int ih = 0;
+ if ( d->iconsets[section] != 0 ) {
+ TQSize isize = d->iconsets[section]->pixmap( TQIconSet::Small,
+ TQIconSet::Normal ).size();
+ iw = isize.width() + 2;
+ ih = isize.height();
+ }
+
+ TQRect bound;
+ TQString *label = d->labels[section];
+ if ( label ) {
+ int lines = label->tqcontains( '\n' ) + 1;
+ int w = 0;
+ if (lines > 1) {
+ bound.setHeight(fm.height() + fm.lineSpacing() * (lines - 1));
+ TQStringList list = TQStringList::split('\n', *label);
+ for (int i=0; i <(int)list.count(); ++i) {
+ int tmpw = fm.width(*(list.at(i)));
+ w = TQMAX(w, tmpw);
+ }
+ } else {
+ bound.setHeight(fm.height());
+ w = fm.width(*label);
+ }
+ bound.setWidth( w );
+ }
+ int arrowWidth = 0;
+ if ( d->sortSection == section )
+ arrowWidth = ( ( orient == Qt::Horizontal ? height() : width() ) / 2 ) + 8;
+ int height = TQMAX( bound.height() + 2, ih ) + 4;
+ int width = bound.width() + tqstyle().tqpixelMetric( TQStyle::PM_HeaderMargin ) * 4
+ + iw + arrowWidth;
+ return TQSize( width, height );
+}
+
+/*
+ Sets d->sizes[\a section] to a bounding rect based on its size
+ hint and font metrics, but constrained by \a size. It also updates
+ d->height.
+*/
+void TQHeader::setSectionSizeAndHeight( int section, int size )
+{
+ TQSize sz = sectionSizeHint( section, fontMetrics() );
+
+ if ( size < 0 ) {
+ if ( d->sizes[section] < 0 )
+ d->sizes[section] = ( orient == Qt::Horizontal ) ? sz.width()
+ : sz.height();
+ } else {
+ d->sizes[section] = size;
+ }
+
+ int newHeight = ( orient == Qt::Horizontal ) ? sz.height() : sz.width();
+ if ( newHeight > d->height ) {
+ d->height = newHeight;
+ } else if ( newHeight < d->height ) {
+ /*
+ We could be smarter, but we aren't. This makes a difference
+ only for users with many columns and '\n's in their headers
+ at the same time.
+ */
+ d->heightDirty = TRUE;
+ }
+}
+
+/*!
+ Adds a new section with label text \a s. Returns the index
+ position where the section was added (at the right for horizontal
+ headers, at the bottom for vertical headers). The section's width
+ is set to \a size. If \a size \< 0, an appropriate size for the
+ text \a s is chosen.
+*/
+int TQHeader::addLabel( const TQString &s, int size )
+{
+ int n = ++d->count;
+ if ( (int)d->iconsets.size() < n )
+ d->iconsets.resize( n );
+ if ( (int)d->sizes.size() < n ) {
+ d->labels.resize( n );
+ d->sizes.resize( n );
+ d->positions.resize( n );
+ d->i2s.resize( n );
+ d->s2i.resize( n );
+ d->clicks.resize( n );
+ d->resize.resize( n );
+ }
+ int section = d->count - 1;
+ if ( !d->is_a_table_header || !s.isNull() )
+ d->labels.insert( section, new TQString( s ) );
+
+ if ( size >= 0 && s.isNull() && d->is_a_table_header ) {
+ d->sizes[section] = size;
+ } else {
+ d->sizes[section] = -1;
+ setSectionSizeAndHeight( section, size );
+ }
+
+ int index = section;
+ d->positions[index] = d->lastPos;
+
+ d->s2i[section] = index;
+ d->i2s[index] = section;
+ d->clicks.setBit( section, d->clicks_default );
+ d->resize.setBit( section, d->resize_default );
+
+ if ( isUpdatesEnabled() ) {
+ updateGeometry();
+ calculatePositions();
+ update();
+ }
+ return index;
+}
+
+void TQHeader::resizeArrays( int size )
+{
+ d->iconsets.resize( size );
+ d->labels.resize( size );
+ d->sizes.resize( size );
+ d->positions.resize( size );
+ d->i2s.resize( size );
+ d->s2i.resize( size );
+ d->clicks.resize( size );
+ d->resize.resize( size );
+}
+
+void TQHeader::setIsATableHeader( bool b )
+{
+ d->is_a_table_header = b;
+}
+
+/*! \reimp */
+TQSize TQHeader::tqsizeHint() const
+{
+ int width;
+ int height;
+
+ constPolish();
+ TQFontMetrics fm = fontMetrics();
+
+ if ( d->heightDirty ) {
+ d->height = fm.lineSpacing() + 6;
+ for ( int i = 0; i < count(); i++ ) {
+ int h = orient == Qt::Horizontal ?
+ sectionSizeHint( i, fm ).height() : sectionSizeHint( i, fm ).width();
+ d->height = TQMAX( d->height, h );
+ }
+ d->heightDirty = FALSE;
+ }
+
+ if ( orient == Qt::Horizontal ) {
+ height = fm.lineSpacing() + 6;
+ width = 0;
+ height = TQMAX( height, d->height );
+ for ( int i = 0; i < count(); i++ )
+ width += d->sizes[i];
+ } else {
+ width = fm.width( ' ' );
+ height = 0;
+ width = TQMAX( width, d->height );
+ for ( int i = 0; i < count(); i++ )
+ height += d->sizes[i];
+ }
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_Header, this,
+ TQSize(width, height)).expandedTo(TQApplication::globalStrut()));
+}
+
+/*!
+ \property TQHeader::offset
+ \brief the header's left-most (or top-most) visible pixel
+
+ Setting this property will scroll the header so that \e offset
+ becomes the left-most (or top-most for vertical headers) visible
+ pixel.
+*/
+int TQHeader::offset() const
+{
+ if ( reverse() )
+ return d->lastPos - width() - offs;
+ return offs;
+}
+
+void TQHeader::setOffset( int x )
+{
+ int oldOff = offset();
+ offs = x;
+ if( d->lastPos < ( orient == Qt::Horizontal ? width() : height() ) )
+ offs = 0;
+ else if ( reverse() )
+ offs = d->lastPos - width() - x;
+ if ( orient == Qt::Horizontal )
+ scroll( oldOff-offset(), 0 );
+ else
+ scroll( 0, oldOff-offset());
+}
+
+
+
+/*
+ Returns the position of actual division line \a i in widget
+ coordinates. May return a position outside the widget.
+
+ Note that the last division line is numbered count(). (There is one
+ more line than the number of sections).
+*/
+int TQHeader::pPos( int i ) const
+{
+ int pos;
+ if ( i == count() )
+ pos = d->lastPos;
+ else
+ pos = d->positions[i];
+ if ( reverse() )
+ pos = d->lastPos - pos;
+ return pos - offset();
+}
+
+
+/*
+ Returns the size of the section at index position \a i.
+*/
+int TQHeader::pSize( int i ) const
+{
+ return d->sizes[ d->i2s[i] ];
+}
+
+/*!
+ \obsolete
+
+ Use mapToSection() instead.
+
+ Translates from actual index \a a (index at which the section is displayed) to
+ logical index of the section. Returns -1 if \a a is outside the legal range.
+
+ \sa mapToActual()
+*/
+
+int TQHeader::mapToLogical( int a ) const
+{
+ return mapToSection( a );
+}
+
+
+/*!
+ \obsolete
+
+ Use mapToIndex() instead.
+
+ Translates from logical index \a l to actual index (index at which the section \a l is displayed) .
+ Returns -1 if \a l is outside the legal range.
+
+ \sa mapToLogical()
+*/
+
+int TQHeader::mapToActual( int l ) const
+{
+ return mapToIndex( l );
+}
+
+
+/*!
+ \obsolete
+
+ Use resizeSection() instead.
+
+ Sets the size of the section \a section to \a s pixels.
+
+ \warning does not tqrepaint or send out Q_SIGNALS
+*/
+
+void TQHeader::setCellSize( int section, int s )
+{
+ if ( section < 0 || section >= count() )
+ return;
+ d->sizes[ section ] = s;
+ if ( isUpdatesEnabled() )
+ calculatePositions();
+}
+
+
+/*!
+ If \a enable is TRUE the user may resize section \a section;
+ otherwise the section may not be manually resized.
+
+ If \a section is negative (the default) then the \a enable value
+ is set for all existing sections and will be applied to any new
+ sections that are added.
+ Example:
+ \code
+ // Allow resizing of all current and future sections
+ header->setResizeEnabled(TRUE);
+ // Disable resizing of section 3, (the fourth section added)
+ header->setResizeEnabled(FALSE, 3);
+ \endcode
+
+ If the user resizes a section, a sizeChange() signal is emitted.
+
+ \sa setMovingEnabled() setClickEnabled() setTracking()
+*/
+
+void TQHeader::setResizeEnabled( bool enable, int section )
+{
+ if ( section < 0 ) {
+ d->resize.fill( enable );
+ // and future ones...
+ d->resize_default = enable;
+ } else if ( section < count() ) {
+ d->resize[ section ] = enable;
+ }
+}
+
+
+/*!
+ \property TQHeader::moving
+ \brief whether the header sections can be moved
+
+ If this property is TRUE (the default) the user can move sections.
+ If the user moves a section the indexChange() signal is emitted.
+
+ \sa setClickEnabled(), setResizeEnabled()
+*/
+
+void TQHeader::setMovingEnabled( bool enable )
+{
+ d->move = enable;
+}
+
+
+/*!
+ If \a enable is TRUE, any clicks on section \a section will result
+ in clicked() Q_SIGNALS being emitted; otherwise the section will
+ ignore clicks.
+
+ If \a section is -1 (the default) then the \a enable value is set
+ for all existing sections and will be applied to any new sections
+ that are added.
+
+ \sa setMovingEnabled(), setResizeEnabled()
+*/
+
+void TQHeader::setClickEnabled( bool enable, int section )
+{
+ if ( section < 0 ) {
+ d->clicks.fill( enable );
+ // and future ones...
+ d->clicks_default = enable;
+ } else if ( section < count() ) {
+ d->clicks[ section ] = enable;
+ }
+}
+
+
+/*!
+ Paints the section at position \a index, inside rectangle \a fr
+ (which uses widget coordinates) using painter \a p.
+
+ Calls paintSectionLabel().
+*/
+
+void TQHeader::paintSection( TQPainter *p, int index, const TQRect& fr )
+{
+ int section = mapToSection( index );
+
+ if ( section < 0 ) {
+ tqstyle().tqdrawPrimitive( TQStyle::PE_HeaderSection, p, fr,
+ tqcolorGroup(), (TQStyle::SFlags)(TQStyle::Style_Raised |
+ (isEnabled() ? TQStyle::Style_Enabled : 0) |
+ ( orient == Qt::Horizontal ? TQStyle::Style_Horizontal : 0 )),
+ TQStyleOption( this ) );
+ return;
+ }
+
+ if ( sectionSize( section ) <= 0 )
+ return;
+
+ TQStyle::SFlags flags = (orient == Qt::Horizontal ? TQStyle::Style_Horizontal : TQStyle::Style_Default);
+ //pass in some hint about the sort indicator if it is used
+ if(d->sortSection != section)
+ flags |= TQStyle::Style_Off;
+ else if(!d->sortDirection)
+ flags |= TQStyle::Style_Up;
+ if(isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if(isClickEnabled(section)) {
+ if(section == d->sortSection)
+ flags |= TQStyle::Style_Sunken; //currently selected
+ if((state == Pressed || state == Moving) && index == handleIdx)
+ flags |= TQStyle::Style_Down; //currently pressed
+
+ }
+ if(!(flags & TQStyle::Style_Down))
+ flags |= TQStyle::Style_Raised;
+ p->setBrushOrigin( fr.topLeft() );
+ if ( d->clicks[section] ) {
+ tqstyle().tqdrawPrimitive( TQStyle::PE_HeaderSection, p, fr,
+ tqcolorGroup(), flags,
+ TQStyleOption( this ) );
+ } else {
+ p->save();
+ p->setClipRect( fr ); // hack to keep styles working
+ if ( orientation() == Qt::Horizontal ) {
+ tqstyle().tqdrawPrimitive( TQStyle::PE_HeaderSection, p,
+ TQRect(fr.x() - 2, fr.y() - 2, fr.width() + 4, fr.height() + 4),
+ tqcolorGroup(), flags,
+ TQStyleOption( this ) );
+
+ p->setPen( tqcolorGroup().color( TQColorGroup::Mid ) );
+ p->drawLine( fr.x(), fr.y() + fr.height() - 1,
+ fr.x() + fr.width() - 1, fr.y() + fr.height() - 1 );
+ p->drawLine( fr.x() + fr.width() - 1, fr.y(),
+ fr.x() + fr.width() - 1, fr.y() + fr.height() - 1 );
+ p->setPen( tqcolorGroup().color( TQColorGroup::Light ) );
+ if ( index > 0 )
+ p->drawLine( fr.x(), fr.y(), fr.x(), fr.y() + fr.height() - 1 );
+ if ( index == count() - 1 ) {
+ p->drawLine( fr.x() + fr.width() - 1, fr.y(),
+ fr.x() + fr.width() - 1, fr.y() + fr.height() - 1 );
+ p->setPen( tqcolorGroup().color( TQColorGroup::Mid ) );
+ p->drawLine( fr.x() + fr.width() - 2, fr.y(),
+ fr.x() + fr.width() - 2, fr.y() + fr.height() - 1 );
+ }
+ } else {
+ tqstyle().tqdrawPrimitive( TQStyle::PE_HeaderSection, p,
+ TQRect(fr.x() - 2, fr.y() - 2, fr.width() + 4, fr.height() + 4),
+ tqcolorGroup(), flags,
+ TQStyleOption( this ) );
+
+ p->setPen( tqcolorGroup().color( TQColorGroup::Mid ) );
+ p->drawLine( fr.x() + width() - 1, fr.y(),
+ fr.x() + fr.width() - 1, fr.y() + fr.height() - 1 );
+ p->drawLine( fr.x(), fr.y() + fr.height() - 1,
+ fr.x() + fr.width() - 1, fr.y() + fr.height() - 1 );
+ p->setPen( tqcolorGroup().color( TQColorGroup::Light ) );
+ if ( index > 0 )
+ p->drawLine( fr.x(), fr.y(), fr.x() + fr.width() - 1, fr.y() );
+ if ( index == count() - 1 ) {
+ p->drawLine( fr.x(), fr.y() + fr.height() - 1,
+ fr.x() + fr.width() - 1, fr.y() + fr.height() - 1 );
+ p->setPen( tqcolorGroup().color( TQColorGroup::Mid ) );
+ p->drawLine( fr.x(), fr.y() + fr.height() - 2,
+ fr.x() + fr.width() - 1, fr.y() + fr.height() - 2 );
+ }
+ }
+ p->restore();
+ }
+
+ paintSectionLabel( p, index, fr );
+}
+
+/*!
+ Paints the label of the section at position \a index, inside
+ rectangle \a fr (which uses widget coordinates) using painter \a
+ p.
+
+ Called by paintSection()
+*/
+void TQHeader::paintSectionLabel( TQPainter *p, int index, const TQRect& fr )
+{
+ int section = mapToSection( index );
+ if ( section < 0 )
+ return;
+
+ int dx = 0, dy = 0;
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if ( index == handleIdx && ( state == Pressed || state == Moving ) ) {
+ dx = tqstyle().tqpixelMetric( TQStyle::PM_ButtonShiftHorizontal, this );
+ dy = tqstyle().tqpixelMetric( TQStyle::PM_ButtonShiftVertical, this );
+ flags |= TQStyle::Style_Sunken;
+ }
+ if ( isEnabled() )
+ flags |= TQStyle::Style_Enabled;
+
+
+ TQRect r( fr.x() + tqstyle().tqpixelMetric( TQStyle::PM_HeaderMargin ) + dx, fr.y() + 2 + dy,
+ fr.width() - 6, fr.height() - 4 );
+
+ tqstyle().tqdrawControl( TQStyle::CE_HeaderLabel, p, this, r, tqcolorGroup(), flags,
+ TQStyleOption( section ) );
+
+ int arrowWidth = ( orient == Qt::Horizontal ? height() : width() ) / 2;
+ int arrowHeight = fr.height() - 6;
+ TQSize ssh = sectionSizeHint( section, p->fontMetrics() );
+ int tw = ( orient == Qt::Horizontal ? ssh.width() : ssh.height() );
+ int ew = 0;
+
+ if ( tqstyle().tqstyleHint( TQStyle::SH_Header_ArrowAlignment, this ) & Qt::AlignRight )
+ ew = fr.width() - tw - 8;
+ if ( d->sortSection == section && tw <= fr.width() ) {
+ if ( reverse() ) {
+ tw = fr.width() - tw;
+ ew = fr.width() - ew - tw;
+ }
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if ( isEnabled() )
+ flags |= TQStyle::Style_Enabled;
+ if ( d->sortDirection )
+ flags |= TQStyle::Style_Down;
+ else
+ flags |= TQStyle::Style_Up;
+ TQRect ar(fr.x() + tw - arrowWidth - 6 + ew, 4, arrowWidth, arrowHeight);
+ if (label(section).isRightToLeft())
+ ar.moveBy( 2*(fr.right() - ar.right()) + ar.width() - fr.width(), 0 );
+ tqstyle().tqdrawPrimitive( TQStyle::PE_HeaderArrow, p,
+ ar, tqcolorGroup(), flags, TQStyleOption( this ) );
+ }
+}
+
+
+/*! \reimp */
+void TQHeader::paintEvent( TQPaintEvent *e )
+{
+ TQPainter p( this );
+ p.setPen( tqcolorGroup().buttonText() );
+ int pos = orient == Qt::Horizontal ? e->rect().left() : e->rect().top();
+ int id = mapToIndex( sectionAt( pos + offset() ) );
+ if ( id < 0 ) {
+ if ( pos > 0 )
+ id = d->count;
+ else if ( reverse() )
+ id = d->count - 1;
+ else
+ id = 0;
+ }
+ if ( reverse() ) {
+ for ( int i = id; i >= 0; i-- ) {
+ TQRect r = sRect( i );
+ paintSection( &p, i, r );
+ if ( r.right() >= e->rect().right() )
+ return;
+ }
+ } else {
+ if ( count() > 0 ) {
+ for ( int i = id; i <= count(); i++ ) {
+ TQRect r = sRect( i );
+ /*
+ If the last section is clickable (and thus is
+ painted raised), draw the virtual section count()
+ as well. Otherwise it looks ugly.
+ */
+ if ( i < count() || d->clicks[ mapToSection( count() - 1 ) ] )
+ paintSection( &p, i, r );
+ if ( hasFocus() && d->focusIdx == i ) {
+ TQRect fr( r.x()+2, r.y()+2, r.width()-4, r.height()-4 );
+ tqstyle().tqdrawPrimitive( TQStyle::PE_FocusRect, &p, fr,
+ tqcolorGroup() );
+ }
+ if ( (orient == Qt::Horizontal && r. right() >= e->rect().right()) ||
+ (orient == Qt::Vertical && r. bottom() >= e->rect().bottom()) )
+ return;
+ }
+ }
+ }
+}
+
+/*! \overload
+ \obsolete
+ Use the other overload instead.
+*/
+
+void TQHeader::setSortIndicator( int section, bool ascending )
+{
+ d->sortSection = section;
+ if ( section != -1 )
+ oldHandleIdx = section;
+ d->sortDirection = ascending;
+ update();
+ updateGeometry();
+}
+
+/*!
+ \fn void TQHeader::setSortIndicator(int section, SortOrder order)
+
+ Sets a sort indicator onto the specified \a section. The indicator's
+ \a order is either Ascending or Descending.
+
+ Only one section can show a sort indicator at any one time. If you
+ don't want any section to show a sort indicator pass a \a section
+ number of -1.
+
+ \sa sortIndicatorSection(), sortIndicatorOrder()
+*/
+
+/*!
+ Returns the section showing the sort indicator or -1 if there is no sort indicator.
+
+ \sa setSortIndicator(), sortIndicatorOrder()
+*/
+
+int TQHeader::sortIndicatorSection() const
+{
+ return d->sortSection;
+}
+
+/*!
+ Returns the implied sort order of the TQHeaders sort indicator.
+
+ \sa setSortIndicator(), sortIndicatorSection()
+*/
+
+TQt::SortOrder TQHeader::sortIndicatorOrder() const
+{
+ return d->sortDirection ? TQt::Ascending : TQt::Descending;
+}
+
+/*!
+ Resizes section \a section to \a s pixels wide (or high).
+*/
+
+void TQHeader::resizeSection( int section, int s )
+{
+ setCellSize( section, s );
+ update();
+}
+
+/*!
+ Returns the width (or height) of the \a section in pixels.
+*/
+
+int TQHeader::sectionSize( int section ) const
+{
+ if ( section < 0 || section >= count() )
+ return 0;
+ return d->sizes[section];
+}
+
+/*!
+ Returns the position (in pixels) at which the \a section starts.
+
+ \sa offset()
+*/
+
+int TQHeader::sectionPos( int section ) const
+{
+ if ( d->positionsDirty )
+ ((TQHeader *)this)->calculatePositions();
+ if ( section < 0 || section >= count() )
+ return 0;
+ return d->positions[ d->s2i[section] ];
+}
+
+/*!
+ Returns the index of the section which tqcontains the position \a
+ pos given in pixels from the left (or top).
+
+ \sa offset()
+*/
+
+int TQHeader::sectionAt( int pos ) const
+{
+ if ( reverse() )
+ pos = d->lastPos - pos;
+ return d->sectionAt( pos );
+}
+
+/*!
+ Returns the number of the section that corresponds to the specified \a index.
+
+ \warning If TQTable is used to move header sections as a result of user
+ interaction, the mapping exposed by this function will not reflect the
+ order of the headers in the table; i.e., TQTable does not call moveSection()
+ to move sections but handles move operations internally.
+
+ \sa mapToIndex()
+*/
+
+int TQHeader::mapToSection( int index ) const
+{
+ return ( index >= 0 && index < count() ) ? d->i2s[ index ] : -1;
+}
+
+/*!
+ Returns the index position corresponding to the specified \a section number.
+
+ \warning If TQTable is used to move header sections as a result of user
+ interaction, the mapping exposed by this function will not reflect the
+ order of the headers in the table; i.e., TQTable does not call moveSection()
+ to move sections but handles move operations internally.
+
+ \sa mapToSection()
+*/
+
+int TQHeader::mapToIndex( int section ) const
+{
+ return ( section >= 0 && section < count() ) ? d->s2i[ section ] : -1;
+}
+
+/*!
+ Moves section \a section to index position \a toIndex.
+*/
+
+void TQHeader::moveSection( int section, int toIndex )
+{
+ int fromIndex = mapToIndex( section );
+ if ( fromIndex == toIndex ||
+ fromIndex < 0 || fromIndex > count() ||
+ toIndex < 0 || toIndex > count() )
+ return;
+ int i;
+ int idx = d->i2s[fromIndex];
+ if ( fromIndex < toIndex ) {
+ for ( i = fromIndex; i < toIndex - 1; i++ ) {
+ int t;
+ d->i2s[i] = t = d->i2s[i+1];
+ d->s2i[t] = i;
+ }
+ d->i2s[toIndex-1] = idx;
+ d->s2i[idx] = toIndex-1;
+ } else {
+ for ( i = fromIndex; i > toIndex; i-- ) {
+ int t;
+ d->i2s[i] = t = d->i2s[i-1];
+ d->s2i[t] = i;
+ }
+ d->i2s[toIndex] = idx;
+ d->s2i[idx] = toIndex;
+ }
+ calculatePositions();
+}
+
+/*!
+ Returns TRUE if section \a section is clickable; otherwise returns
+ FALSE.
+
+ If \a section is out of range (negative or larger than count() -
+ 1): returns TRUE if all sections are clickable; otherwise returns
+ FALSE.
+
+ \sa setClickEnabled()
+*/
+
+bool TQHeader::isClickEnabled( int section ) const
+{
+ if ( section >= 0 && section < count() ) {
+ return (bool)d->clicks[ section ];
+ }
+
+ for ( int i = 0; i < count(); ++i ) {
+ if ( !d->clicks[ i ] )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*!
+ Returns TRUE if section \a section is resizeable; otherwise
+ returns FALSE.
+
+ If \a section is -1 then this function applies to all sections,
+ i.e. returns TRUE if all sections are resizeable; otherwise
+ returns FALSE.
+
+ \sa setResizeEnabled()
+*/
+
+bool TQHeader::isResizeEnabled( int section ) const
+{
+ if ( section >= 0 && section < count() ) {
+ return (bool)d->resize[ section ];
+ }
+
+ for ( int i = 0; i < count();++i ) {
+ if ( !d->resize[ i ] )
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool TQHeader::isMovingEnabled() const
+{
+ return d->move;
+}
+
+/*! \reimp */
+
+void TQHeader::setUpdatesEnabled( bool enable )
+{
+ if ( enable )
+ calculatePositions();
+ TQWidget::setUpdatesEnabled( enable );
+}
+
+
+bool TQHeader::reverse () const
+{
+#if 0
+ return ( orient == Qt::Horizontal && TQApplication::reverseLayout() );
+#else
+ return FALSE;
+#endif
+}
+
+/*! \reimp */
+void TQHeader::resizeEvent( TQResizeEvent *e )
+{
+ if ( e )
+ TQWidget::resizeEvent( e );
+
+ if( d->lastPos < width() ) {
+ offs = 0;
+ }
+
+ if ( e ) {
+ adjustHeaderSize( orientation() == Qt::Horizontal ?
+ width() - e->oldSize().width() : height() - e->oldSize().height() );
+ if ( (orientation() == Qt::Horizontal && height() != e->oldSize().height())
+ || (orientation() == Qt::Vertical && width() != e->oldSize().width()) )
+ update();
+ } else
+ adjustHeaderSize();
+}
+
+/*!
+ \fn void TQHeader::adjustHeaderSize()
+
+ Adjusts the size of the sections to fit the size of the header as
+ completely as possible. Only sections for which isStretchEnabled()
+ is TRUE will be resized.
+*/
+
+void TQHeader::adjustHeaderSize( int diff )
+{
+ if ( !count() )
+ return;
+
+ // we skip the adjustHeaderSize when trying to resize the last column which is set to stretchable
+ if ( d->fullSize == (count() -1) &&
+ (d->lastPos - d->sizes[count() -1]) > ( orient == Qt::Horizontal ? width() : height() ) )
+ return;
+
+ if ( d->fullSize >= 0 ) {
+ int sec = mapToSection( d->fullSize );
+ int lsec = mapToSection( count() - 1 );
+ int ns = sectionSize( sec ) +
+ ( orientation() == Qt::Horizontal ?
+ width() : height() ) - ( sectionPos( lsec ) + sectionSize( lsec ) );
+ int os = sectionSize( sec );
+ if ( ns < 20 )
+ ns = 20;
+ setCellSize( sec, ns );
+ tqrepaint( FALSE );
+ emit sizeChange( sec, os, ns );
+ } else if ( d->fullSize == -1 ) {
+ int df = diff / count();
+ int part = orientation() == Qt::Horizontal ? width() / count() : height() / count();
+ for ( int i = 0; i < count() - 1; ++i ) {
+ int sec = mapToIndex( i );
+ int os = sectionSize( sec );
+ int ns = diff != -1 ? os + df : part;
+ if ( ns < 20 )
+ ns = 20;
+ setCellSize( sec, ns );
+ emit sizeChange( sec, os, ns );
+ }
+ int sec = mapToIndex( count() - 1 );
+ int ns = ( orientation() == Qt::Horizontal ? width() : height() ) - sectionPos( sec );
+ int os = sectionSize( sec );
+ if ( ns < 20 )
+ ns = 20;
+ setCellSize( sec, ns );
+ tqrepaint( FALSE );
+ emit sizeChange( sec, os, ns );
+ }
+}
+
+/*!
+ Returns the total width of all the header columns.
+*/
+int TQHeader::headerWidth() const
+{
+ if ( d->pos_dirty ) {
+ ( (TQHeader*)this )->calculatePositions();
+ d->pos_dirty = FALSE;
+ }
+ return d->lastPos;
+}
+
+void TQHeader::calculatePositions( bool onlyVisible, int start )
+{
+ d->positionsDirty = FALSE;
+ d->lastPos = count() > 0 ? d->positions[start] : 0;
+ for ( int i = start; i < count(); i++ ) {
+ d->positions[i] = d->lastPos;
+ d->lastPos += d->sizes[d->i2s[i]];
+ if ( onlyVisible && d->lastPos > offset() +
+ ( orientation() == Qt::Horizontal ? width() : height() ) )
+ break;
+ }
+ d->pos_dirty = onlyVisible;
+}
+
+
+/*!
+ \property TQHeader::stretching
+ \brief whether the header sections always take up the full width
+ (or height) of the header
+*/
+
+
+/*!
+ If \a b is TRUE, section \a section will be resized when the
+ header is resized, so that the sections take up the full width (or
+ height for vertical headers) of the header; otherwise section \a
+ section will be set to be unstretchable and will not resize when
+ the header is resized.
+
+ If \a section is -1, and if \a b is TRUE, then all sections will
+ be resized equally when the header is resized so that they take up
+ the full width (or height for vertical headers) of the header;
+ otherwise all the sections will be set to be unstretchable and
+ will not resize when the header is resized.
+
+ \sa adjustHeaderSize()
+*/
+
+void TQHeader::setStretchEnabled( bool b, int section )
+{
+ if ( b )
+ d->fullSize = section;
+ else
+ d->fullSize = -2;
+ adjustHeaderSize();
+}
+
+bool TQHeader::isStretchEnabled() const
+{
+ return d->fullSize == -1;
+}
+
+/*!
+ \overload
+
+ Returns TRUE if section \a section will resize to take up the full
+ width (or height) of the header; otherwise returns FALSE. If at
+ least one section has stretch enabled the sections will always
+ take up the full width of the header.
+
+ \sa setStretchEnabled()
+*/
+
+bool TQHeader::isStretchEnabled( int section ) const
+{
+ return d->fullSize == section;
+}
+
+/*!
+ \reimp
+*/
+void TQHeader::fontChange( const TQFont &oldFont )
+{
+ TQFontMetrics fm = fontMetrics();
+ d->height = ( orient == Qt::Horizontal ) ? fm.lineSpacing() + 6 : fm.width( ' ' );
+ TQWidget::fontChange( oldFont );
+}
+
+#endif // TQT_NO_HEADER
diff --git a/tqtinterface/qt4/src/widgets/tqheader.h b/tqtinterface/qt4/src/widgets/tqheader.h
new file mode 100644
index 0000000..ab0f371
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqheader.h
@@ -0,0 +1,220 @@
+/****************************************************************************
+**
+** Definition of TQHeader widget class (table header)
+**
+** Created : 961105
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQHEADER_H
+#define TQHEADER_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqstring.h"
+#include "tqiconset.h" // conversion TQPixmap->TQIconset
+#endif // TQT_H
+
+#ifndef TQT_NO_HEADER
+
+class TQShowEvent;
+class TQHeaderData;
+class TQTable;
+
+class TQ_EXPORT TQHeader : public TQWidget
+{
+ friend class TQTable;
+ friend class TQTableHeader;
+ friend class TQListView;
+
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( Qt::Orientation orientation READ orientation WRITE setOrientation )
+ Q_PROPERTY( bool tracking READ tracking WRITE setTracking )
+ Q_PROPERTY( int count READ count )
+ Q_PROPERTY( int offset READ offset WRITE setOffset )
+ Q_PROPERTY( bool moving READ isMovingEnabled WRITE setMovingEnabled )
+ Q_PROPERTY( bool stretching READ isStretchEnabled WRITE setStretchEnabled )
+
+public:
+ TQHeader( TQWidget* tqparent=0, const char* name=0 );
+ TQHeader( int, TQWidget* tqparent=0, const char* name=0 );
+ ~TQHeader();
+
+ int addLabel( const TQString &, int size = -1 );
+ int addLabel( const TQIconSet&, const TQString &, int size = -1 );
+ void removeLabel( int section );
+ virtual void setLabel( int, const TQString &, int size = -1 );
+ virtual void setLabel( int, const TQIconSet&, const TQString &, int size = -1 );
+ TQString label( int section ) const;
+ TQIconSet* iconSet( int section ) const;
+
+ virtual void setOrientation( Qt::Orientation );
+ Qt::Orientation orientation() const;
+ virtual void setTracking( bool enable );
+ bool tracking() const;
+
+ virtual void setClickEnabled( bool, int section = -1 );
+ virtual void setResizeEnabled( bool, int section = -1 );
+ virtual void setMovingEnabled( bool );
+ virtual void setStretchEnabled( bool b, int section );
+ void setStretchEnabled( bool b ) { setStretchEnabled( b, -1 ); }
+ bool isClickEnabled( int section = -1 ) const;
+ bool isResizeEnabled( int section = -1 ) const;
+ bool isMovingEnabled() const;
+ bool isStretchEnabled() const;
+ bool isStretchEnabled( int section ) const;
+
+ void resizeSection( int section, int s );
+ int sectionSize( int section ) const;
+ int sectionPos( int section ) const;
+ int sectionAt( int pos ) const;
+ int count() const;
+ int headerWidth() const;
+ TQRect sectionRect( int section ) const;
+
+ virtual void setCellSize( int , int ); // obsolete, do not use
+ int cellSize( int i ) const { return sectionSize( mapToSection(i) ); } // obsolete, do not use
+ int cellPos( int ) const; // obsolete, do not use
+ int cellAt( int pos ) const { return mapToIndex( sectionAt(pos + offset()) ); } // obsolete, do not use
+
+ int offset() const;
+
+ TQSize tqsizeHint() const;
+
+ int mapToSection( int index ) const;
+ int mapToIndex( int section ) const;
+ int mapToLogical( int ) const; // obsolete, do not use
+ int mapToActual( int ) const; // obsolete, do not use
+
+ void moveSection( int section, int toIndex );
+ virtual void moveCell( int, int); // obsolete, do not use
+
+ void setSortIndicator( int section, bool ascending = TRUE ); // obsolete, do not use
+ inline void setSortIndicator( int section, TQt::SortOrder order )
+ { setSortIndicator( section, (order == TQt::Ascending) ); }
+ int sortIndicatorSection() const;
+ TQt::SortOrder sortIndicatorOrder() const;
+
+ void adjustHeaderSize() { adjustHeaderSize( -1 ); }
+
+public Q_SLOTS:
+ void setUpdatesEnabled( bool enable );
+ virtual void setOffset( int pos );
+
+Q_SIGNALS:
+ void clicked( int section );
+ void pressed( int section );
+ void released( int section );
+ void sizeChange( int section, int oldSize, int newSize );
+ void indexChange( int section, int fromIndex, int toIndex );
+ void sectionClicked( int ); // obsolete, do not use
+ void moved( int, int ); // obsolete, do not use
+ void sectionHandleDoubleClicked( int section );
+
+protected:
+ void paintEvent( TQPaintEvent * );
+ void showEvent( TQShowEvent *e );
+ void resizeEvent( TQResizeEvent *e );
+ TQRect sRect( int index );
+
+ virtual void paintSection( TQPainter *p, int index, const TQRect& fr);
+ virtual void paintSectionLabel( TQPainter* p, int index, const TQRect& fr );
+
+ void fontChange( const TQFont & );
+
+ void mousePressEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void mouseDoubleClickEvent( TQMouseEvent * );
+
+ void keyPressEvent( TQKeyEvent * );
+ void keyReleaseEvent( TQKeyEvent * );
+
+private:
+ void handleColumnMove( int fromIdx, int toIdx );
+ void adjustHeaderSize( int diff );
+ void init( int );
+
+ void paintRect( int p, int s );
+ void markLine( int idx );
+ void unMarkLine( int idx );
+ int pPos( int i ) const;
+ int pSize( int i ) const;
+ int tqfindLine( int );
+ int handleAt( int p );
+ bool reverse() const;
+ void calculatePositions( bool onlyVisible = FALSE, int start = 0 );
+ void handleColumnResize(int, int, bool, bool = TRUE );
+ TQSize sectionSizeHint( int section, const TQFontMetrics& fm ) const;
+ void setSectionSizeAndHeight( int section, int size );
+
+ void resizeArrays( int size );
+ void setIsATableHeader( bool b );
+ int offs;
+ int handleIdx;
+ int oldHIdxSize;
+ int moveToIdx;
+ enum State { Idle, Sliding, Pressed, Moving, Blocked };
+ State state;
+ TQCOORD clickPos;
+ bool trackingIsOn;
+ int oldHandleIdx;
+ int cachedPos; // not used
+ Qt::Orientation orient;
+
+ TQHeaderData *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQHeader( const TQHeader & );
+ TQHeader &operator=( const TQHeader & );
+#endif
+};
+
+
+inline Qt::Orientation TQHeader::orientation() const
+{
+ return orient;
+}
+
+inline void TQHeader::setTracking( bool enable ) { trackingIsOn = enable; }
+inline bool TQHeader::tracking() const { return trackingIsOn; }
+
+extern TQ_EXPORT bool qt_qheader_label_return_null_strings; // needed for professional edition
+
+#endif // TQT_NO_HEADER
+
+#endif // TQHEADER_H
diff --git a/tqtinterface/qt4/src/widgets/tqhgroupbox.cpp b/tqtinterface/qt4/src/widgets/tqhgroupbox.cpp
new file mode 100644
index 0000000..2bac06c
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqhgroupbox.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Implementation of TQHGroupBox class
+**
+** Created : 990602
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqhgroupbox.h"
+#ifndef TQT_NO_HGROUPBOX
+
+/*!
+ \class TQHGroupBox tqhgroupbox.h
+
+ \brief The TQHGroupBox widget organizes widgets in a group with one
+ horizontal row.
+
+ \ingroup organizers
+ \ingroup geomanagement
+ \ingroup appearance
+
+ TQHGroupBox is a convenience class that offers a thin layer on top
+ of TQGroupBox. Think of it as a TQHBox that offers a frame with a
+ title.
+
+ \img qgroupboxes.png Group Boxes
+
+ \sa TQVGroupBox
+*/
+
+/*!
+ Constructs a horizontal group box with no title.
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+*/
+TQHGroupBox::TQHGroupBox( TQWidget *tqparent, const char *name )
+ : TQGroupBox( 1, Qt::Vertical /* sic! */, tqparent, name )
+{
+}
+
+/*!
+ Constructs a horizontal group box with the title \a title.
+
+ The \a tqparent and \a name arguments are passed to the TQWidget
+ constructor.
+*/
+
+TQHGroupBox::TQHGroupBox( const TQString &title, TQWidget *tqparent,
+ const char *name )
+ : TQGroupBox( 1, Qt::Vertical /* sic! */, title, tqparent, name )
+{
+}
+
+/*!
+ Destroys the horizontal group box, deleting its child widgets.
+*/
+TQHGroupBox::~TQHGroupBox()
+{
+}
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqhgroupbox.h b/tqtinterface/qt4/src/widgets/tqhgroupbox.h
new file mode 100644
index 0000000..4b52836
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqhgroupbox.h
@@ -0,0 +1,68 @@
+/**********************************************************************
+**
+** Definition of TQHGroupBox widget class
+**
+** Created : 990602
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQHGROUPBOX_H
+#define TQHGROUPBOX_H
+
+#ifndef TQT_H
+#include "tqgroupbox.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_HGROUPBOX
+
+class TQ_EXPORT TQHGroupBox : public TQGroupBox
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQHGroupBox( TQWidget* tqparent=0, const char* name=0 );
+ TQHGroupBox( const TQString &title, TQWidget* tqparent=0, const char* name=0 );
+ ~TQHGroupBox();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQHGroupBox( const TQHGroupBox & );
+ TQHGroupBox &operator=( const TQHGroupBox & );
+#endif
+};
+
+#endif // TQT_NO_HGROUPBOX
+
+#endif // TQHGROUPBOX_H
diff --git a/tqtinterface/qt4/src/widgets/tqlabel.cpp b/tqtinterface/qt4/src/widgets/tqlabel.cpp
new file mode 100644
index 0000000..b29d599
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqlabel.cpp
@@ -0,0 +1,1194 @@
+/**********************************************************************
+**
+** Implementation of TQLabel widget class
+**
+** Created : 941215
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqlabel.h"
+#ifndef TQT_NO_LABEL
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqaccel.h"
+#include "tqmovie.h"
+#include "tqimage.h"
+#include "tqbitmap.h"
+#include "tqpicture.h"
+#include "tqapplication.h"
+#include "tqsimplerichtext.h"
+#include "tqstylesheet.h"
+#include "tqstyle.h"
+
+class TQLabelPrivate
+{
+public:
+ TQLabelPrivate()
+ :img(0), pix(0), valid_hints( -1 )
+ {}
+ TQImage* img; // for scaled contents
+ TQPixmap* pix; // for scaled contents
+ TQSize sh;
+ TQSize msh;
+ int valid_hints; // stores the frameWidth() for the stored size hint, -1 otherwise
+};
+
+
+/*!
+ \class TQLabel tqlabel.h
+ \brief The TQLabel widget provides a text or image display.
+
+ \ingroup basic
+ \ingroup text
+ \mainclass
+
+ TQLabel is used for displaying text or an image. No user
+ interaction functionality is provided. The visual appearance of
+ the label can be configured in various ways, and it can be used
+ for specifying a focus accelerator key for another widget.
+
+ A TQLabel can contain any of the following content types:
+ \table
+ \header \i Content \i Setting
+ \row \i Plain text
+ \i Pass a TQString to setText().
+ \row \i Rich text
+ \i Pass a TQString that tqcontains rich text to setText().
+ \row \i A pixmap
+ \i Pass a TQPixmap to setPixmap().
+ \row \i A movie
+ \i Pass a TQMovie to setMovie().
+ \row \i A number
+ \i Pass an \e int or a \e double to setNum(), which converts
+ the number to plain text.
+ \row \i Nothing
+ \i The same as an empty plain text. This is the default. Set
+ by clear().
+ \endtable
+
+ When the content is changed using any of these functions, any
+ previous content is cleared.
+
+ The look of a TQLabel can be tuned in several ways. All the
+ settings of TQFrame are available for specifying a widget frame.
+ The positioning of the content within the TQLabel widget area can
+ be tuned with tqsetAlignment() and setIndent(). For example, this
+ code sets up a sunken panel with a two-line text in the bottom
+ right corner (both lines being flush with the right side of the
+ label):
+ \code
+ TQLabel *label = new TQLabel( this );
+ label->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
+ label->setText( "first line\nsecond line" );
+ label->tqsetAlignment( AlignBottom | AlignRight );
+ \endcode
+
+ A TQLabel is often used as a label for an interactive widget. For
+ this use TQLabel provides a useful mechanism for adding an
+ accelerator key (see TQAccel) that will set the keyboard focus to
+ the other widget (called the TQLabel's "buddy"). For example:
+ \code
+ TQLineEdit* phoneEdit = new TQLineEdit( this, "phoneEdit" );
+ TQLabel* phoneLabel = new TQLabel( phoneEdit, "&Phone:", this, "phoneLabel" );
+ \endcode
+
+ In this example, keyboard focus is transferred to the label's
+ buddy (the TQLineEdit) when the user presses Alt+P. You can
+ also use the setBuddy() function to accomplish the same thing.
+
+ <img src=qlabel-m.png> <img src=qlabel-w.png>
+
+ \sa TQLineEdit, TQTextEdit, TQPixmap, TQMovie,
+ \link guibooks.html#fowler GUI Design Handbook: Label\endlink
+*/
+
+/*!
+ \fn TQPicture * TQLabel::picture() const
+
+ Returns the label's picture or 0 if the label doesn't have a
+ picture.
+*/
+
+
+/*!
+ Constructs an empty label.
+
+ The \a tqparent, \a name and widget flag \a f, arguments are passed
+ to the TQFrame constructor.
+
+ \sa tqsetAlignment(), setFrameStyle(), setIndent()
+*/
+
+TQLabel::TQLabel( TQWidget *tqparent, const char *name, WFlags f )
+ : TQFrame( tqparent, name, f | TQt::WMouseNoMask )
+{
+ init();
+}
+
+
+/*!
+ Constructs a label that displays the text, \a text.
+
+ The \a tqparent, \a name and widget flag \a f, arguments are passed
+ to the TQFrame constructor.
+
+ \sa setText(), tqsetAlignment(), setFrameStyle(), setIndent()
+*/
+
+TQLabel::TQLabel( const TQString &text, TQWidget *tqparent, const char *name,
+ WFlags f )
+ : TQFrame( tqparent, name, f | TQt::WMouseNoMask )
+{
+ init();
+ setText( text );
+}
+
+
+/*!
+ Constructs a label that displays the text \a text. The label has a
+ buddy widget, \a buddy.
+
+ If the \a text tqcontains an underlined letter (a letter preceded by
+ an ampersand, \&), and the text is in plain text format, when the
+ user presses Alt+ the underlined letter, focus is passed to the
+ buddy widget.
+
+ The \a tqparent, \a name and widget flag, \a f, arguments are passed
+ to the TQFrame constructor.
+
+ \sa setText(), setBuddy(), tqsetAlignment(), setFrameStyle(),
+ setIndent()
+*/
+TQLabel::TQLabel( TQWidget *buddy, const TQString &text,
+ TQWidget *tqparent, const char *name, WFlags f )
+ : TQFrame( tqparent, name, f | TQt::WMouseNoMask )
+{
+ init();
+#ifndef TQT_NO_ACCEL
+ setBuddy( buddy );
+#endif
+ setText( text );
+}
+
+/*!
+ Destroys the label.
+*/
+
+TQLabel::~TQLabel()
+{
+ clearContents();
+ delete d;
+}
+
+
+void TQLabel::init()
+{
+ lpixmap = 0;
+#ifndef TQT_NO_MOVIE
+ lmovie = 0;
+#endif
+#ifndef TQT_NO_ACCEL
+ lbuddy = 0;
+ accel = 0;
+#endif
+ lpixmap = 0;
+#ifndef TQT_NO_PICTURE
+ lpicture = 0;
+#endif
+ align = TQt::AlignAuto | TQt::AlignVCenter | TQt::ExpandTabs;
+ extraMargin = -1;
+ autoresize = FALSE;
+ scaledcontents = FALSE;
+ textformat = TQt::AutoText;
+#ifndef TQT_NO_RICHTEXT
+ doc = 0;
+#endif
+
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) );
+ d = new TQLabelPrivate;
+}
+
+
+/*!
+ \property TQLabel::text
+ \brief the label's text
+
+ If no text has been set this will return an empty string. Setting
+ the text clears any previous content, unless they are the same.
+
+ The text will be interpreted either as a plain text or as a rich
+ text, depending on the text format setting; see setTextFormat().
+ The default setting is \c AutoText, i.e. TQLabel will try to
+ auto-detect the format of the text set.
+
+ If the text is interpreted as a plain text and a buddy has been
+ set, the buddy accelerator key is updated from the new text.
+
+ The label resizes itself if auto-resizing is enabled.
+
+ Note that Qlabel is well-suited to display small rich text
+ documents, i.e. those small documents that get their document
+ specific settings (font, text color, link color) from the label's
+ palette and font properties. For large documents, use TQTextEdit
+ in read-only mode instead. TQTextEdit will flicker less on resize
+ and can also provide a scrollbar when necessary.
+
+ \sa text, setTextFormat(), setBuddy(), tqalignment
+*/
+
+void TQLabel::setText( const TQString &text )
+{
+ if ( ltext == text )
+ return;
+ TQSize osh = tqsizeHint();
+#ifndef TQT_NO_RICHTEXT
+ bool hadRichtext = doc != 0;
+#endif
+ clearContents();
+ ltext = text;
+#ifndef TQT_NO_RICHTEXT
+ bool useRichText = (textformat == TQt::RichText ||
+ ( ( textformat == TQt::AutoText ) && TQStyleSheet::mightBeRichText(ltext) ) );
+#else
+ bool useRichText = TRUE;
+#endif
+#ifndef TQT_NO_ACCEL
+ // ### Setting accelerators for rich text labels will not work.
+ // Eg. <b>&gt;Hello</b> will return ALT+G which is clearly
+ // not intended.
+ if ( !useRichText ) {
+ int p = TQAccel::shortcutKey( ltext );
+ if ( p ) {
+ if ( !accel )
+ accel = new TQAccel( this, "accel label accel" );
+ accel->connectItem( accel->insertItem( p ),
+ this, TQT_SLOT(acceleratorSlot()) );
+ }
+ }
+#endif
+#ifndef TQT_NO_RICHTEXT
+ if ( useRichText ) {
+ if ( !hadRichtext )
+ align |= TQt::WordBreak;
+ TQString t = ltext;
+ if ( align & Qt::AlignRight )
+ t.prepend( "<div align=\"right\">");
+ else if ( align & Qt::AlignHCenter )
+ t.prepend( "<div align=\"center\">");
+ if ( (align & TQt::WordBreak) == 0 )
+ t.prepend( "<nobr>" );
+ doc = new TQSimpleRichText( t, font() );
+ }
+#endif
+
+ updateLabel( osh );
+}
+
+
+/*!
+ Clears any label contents. Equivalent to setText( "" ).
+*/
+
+void TQLabel::clear()
+{
+ setText( TQString::tqfromLatin1("") );
+}
+
+/*!
+ \property TQLabel::pixmap
+ \brief the label's pixmap
+
+ If no pixmap has been set this will return an invalid pixmap.
+
+ Setting the pixmap clears any previous content, and resizes the
+ label if \l TQLabel::autoResize() is TRUE. The buddy accelerator,
+ if any, is disabled.
+*/
+void TQLabel::setPixmap( const TQPixmap &pixmap )
+{
+ TQSize osh = tqsizeHint();
+
+ if ( !lpixmap || lpixmap->serialNumber() != pixmap.serialNumber() ) {
+ clearContents();
+ lpixmap = new TQPixmap( pixmap );
+ }
+
+ if ( lpixmap->depth() == 1 && !lpixmap->tqmask() )
+ lpixmap->setMask( *((TQBitmap *)lpixmap) );
+
+ updateLabel( osh );
+}
+
+#ifndef TQT_NO_PICTURE
+/*!
+ Sets the label contents to \a picture. Any previous content is
+ cleared.
+
+ The buddy accelerator, if any, is disabled.
+
+ \sa picture(), setBuddy()
+*/
+
+void TQLabel::setPicture( const TQPicture &picture )
+{
+ TQSize osh = tqsizeHint();
+ clearContents();
+ lpicture = new TQPicture( picture );
+
+ updateLabel( osh );
+}
+#endif // TQT_NO_PICTURE
+
+/*!
+ Sets the label contents to plain text containing the textual
+ representation of integer \a num. Any previous content is cleared.
+ Does nothing if the integer's string representation is the same as
+ the current contents of the label.
+
+ The buddy accelerator, if any, is disabled.
+
+ The label resizes itself if auto-resizing is enabled.
+
+ \sa setText(), TQString::setNum(), setBuddy()
+*/
+
+void TQLabel::setNum( int num )
+{
+ TQString str;
+ str.setNum( num );
+ setText( str );
+}
+
+/*!
+ \overload
+
+ Sets the label contents to plain text containing the textual
+ representation of double \a num. Any previous content is cleared.
+ Does nothing if the double's string representation is the same as
+ the current contents of the label.
+
+ The buddy accelerator, if any, is disabled.
+
+ The label resizes itself if auto-resizing is enabled.
+
+ \sa setText(), TQString::setNum(), setBuddy()
+*/
+
+void TQLabel::setNum( double num )
+{
+ TQString str;
+ str.setNum( num );
+ setText( str );
+}
+
+/*!
+ \property TQLabel::tqalignment
+ \brief the tqalignment of the label's contents
+
+ The tqalignment is a bitwise OR of \c TQt::AlignmentFlags and \c
+ TQt::TextFlags values. The \c ExpandTabs, \c SingleLine and \c
+ ShowPrefix flags apply only if the label tqcontains plain text;
+ otherwise they are ignored. The \c DontClip flag is always
+ ignored. \c WordBreak applies to both rich text and plain text
+ labels. The \c BreakAnywhere flag is not supported in TQLabel.
+
+ If the label has a buddy, the \c ShowPrefix flag is forced to
+ TRUE.
+
+ The default tqalignment is \c{AlignAuto | AlignVCenter | ExpandTabs}
+ if the label doesn't have a buddy and \c{AlignAuto | AlignVCenter
+ | ExpandTabs | ShowPrefix} if the label has a buddy. If the label
+ tqcontains rich text, additionally \c WordBreak is turned on.
+
+ \sa TQt::AlignmentFlags, tqalignment, setBuddy(), text
+*/
+
+void TQLabel::tqsetAlignment( int tqalignment )
+{
+ if ( tqalignment == align )
+ return;
+ TQSize osh = tqsizeHint();
+#ifndef TQT_NO_ACCEL
+ if ( lbuddy )
+ align = tqalignment | TQt::ShowPrefix;
+ else
+#endif
+ align = tqalignment;
+
+#ifndef TQT_NO_RICHTEXT
+ TQString t = ltext;
+ if ( !t.isNull() ) {
+ ltext = TQString::null;
+ setText( t );
+ }
+#endif
+
+ updateLabel( osh );
+}
+
+
+/*!
+ \property TQLabel::indent
+ \brief the label's text indent in pixels
+
+ If a label displays text, the indent applies to the left edge if
+ tqalignment() is \c AlignLeft, to the right edge if tqalignment() is
+ \c AlignRight, to the top edge if tqalignment() is \c AlignTop, and
+ to to the bottom edge if tqalignment() is \c AlignBottom.
+
+ If indent is negative, or if no indent has been set, the label
+ computes the effective indent as follows: If frameWidth() is 0,
+ the effective indent becomes 0. If frameWidth() is greater than 0,
+ the effective indent becomes half the width of the "x" character
+ of the widget's current font().
+
+ \sa tqalignment, frameWidth(), font()
+*/
+
+void TQLabel::setIndent( int indent )
+{
+ extraMargin = indent;
+ updateLabel( TQSize( -1, -1 ) );
+}
+
+
+/*!
+ \fn bool TQLabel::autoResize() const
+
+ \obsolete
+
+ Returns TRUE if auto-resizing is enabled, or FALSE if auto-resizing
+ is disabled.
+
+ Auto-resizing is disabled by default.
+
+ \sa setAutoResize()
+*/
+
+/*! \obsolete
+ Enables auto-resizing if \a enable is TRUE, or disables it if \a
+ enable is FALSE.
+
+ When auto-resizing is enabled the label will resize itself to fit
+ the contents whenever the contents change. The top-left corner is
+ not moved. This is useful for TQLabel widgets that are not managed by
+ a TQLayout (e.g., top-level widgets).
+
+ Auto-resizing is disabled by default.
+
+ \sa autoResize(), adjustSize(), tqsizeHint()
+*/
+
+void TQLabel::setAutoResize( bool enable )
+{
+ if ( (bool)autoresize != enable ) {
+ autoresize = enable;
+ if ( autoresize )
+ adjustSize(); // calls resize which repaints
+ }
+}
+
+
+
+/*!
+ Returns the size that will be used if the width of the label is \a
+ w. If \a w is -1, the tqsizeHint() is returned.
+*/
+
+TQSize TQLabel::sizeForWidth( int w ) const
+{
+ TQRect br;
+ TQPixmap *pix = pixmap();
+#ifndef TQT_NO_PICTURE
+ TQPicture *pic = picture();
+#else
+ const int pic = 0;
+#endif
+#ifndef TQT_NO_MOVIE
+ TQMovie *mov = movie();
+#else
+ const int mov = 0;
+#endif
+ int hextra = 2 * frameWidth();
+ int vextra = hextra;
+ TQFontMetrics fm( fontMetrics() );
+ int xw = fm.width( 'x' );
+ if ( !mov && !pix && !pic ) {
+ int m = indent();
+ if ( m < 0 && hextra ) // no indent, but we do have a frame
+ m = xw / 2 - margin();
+ if ( m >= 0 ) {
+ int horizAlign = TQApplication::horizontalAlignment( align );
+ if ( (horizAlign & Qt::AlignLeft) || (horizAlign & Qt::AlignRight ) )
+ hextra += m;
+ if ( (align & Qt::AlignTop) || (align & Qt::AlignBottom ) )
+ vextra += m;
+ }
+ }
+
+ if ( pix )
+ br = pix->rect();
+#ifndef TQT_NO_PICTURE
+ else if ( pic )
+ br = pic->boundingRect();
+#endif
+#ifndef TQT_NO_MOVIE
+ else if ( mov )
+ br = mov->framePixmap().rect();
+#endif
+#ifndef TQT_NO_RICHTEXT
+ else if ( doc ) {
+ int oldW = doc->width();
+ if ( align & TQt::WordBreak ) {
+ if ( w < 0 )
+ doc->adjustSize();
+ else
+ doc->setWidth( w-hextra );
+ }
+ br = TQRect( 0, 0, doc->widthUsed(), doc->height() );
+ doc->setWidth( oldW );
+ }
+#endif
+ else {
+ bool tryWidth = (w < 0) && (align & TQt::WordBreak);
+ if ( tryWidth )
+ w = xw * 80;
+ else if ( w < 0 )
+ w = 2000;
+ w -= hextra;
+ br = fm.boundingRect( 0, 0, w ,2000, tqalignment(), text() );
+ if ( tryWidth && br.height() < 4*fm.lineSpacing() && br.width() > w/2 )
+ br = fm.boundingRect( 0, 0, w/2, 2000, tqalignment(), text() );
+ if ( tryWidth && br.height() < 2*fm.lineSpacing() && br.width() > w/4 )
+ br = fm.boundingRect( 0, 0, w/4, 2000, tqalignment(), text() );
+ }
+ int wid = br.width() + hextra;
+ int hei = br.height() + vextra;
+
+ return TQSize( wid, hei );
+}
+
+
+/*!
+ \reimp
+*/
+
+int TQLabel::heightForWidth( int w ) const
+{
+ if (
+#ifndef TQT_NO_RICHTEXT
+ doc ||
+#endif
+ (align & TQt::WordBreak) )
+ return sizeForWidth( w ).height();
+ return TQWidget::heightForWidth( w );
+}
+
+
+
+/*!\reimp
+*/
+TQSize TQLabel::tqsizeHint() const
+{
+ if ( d->valid_hints != frameWidth() )
+ (void) TQLabel::tqminimumSizeHint();
+ return d->sh;
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQLabel::tqminimumSizeHint() const
+{
+ if ( d->valid_hints == frameWidth() )
+ return d->msh;
+
+ constPolish();
+ d->valid_hints = frameWidth();
+ d->sh = sizeForWidth( -1 );
+ TQSize sz( -1, -1 );
+
+ if (
+#ifndef TQT_NO_RICHTEXT
+ !doc &&
+#endif
+ (align & TQt::WordBreak) == 0 ) {
+ sz = d->sh;
+ } else {
+ // think about caching these for performance
+ sz.rwidth() = sizeForWidth( 0 ).width();
+ sz.rheight() = sizeForWidth(TQWIDGETSIZE_MAX).height();
+ if ( d->sh.height() < sz.height() )
+ sz.rheight() = d->sh.height();
+ }
+ if ( tqsizePolicy().horData() == TQSizePolicy::Ignored )
+ sz.rwidth() = -1;
+ if ( tqsizePolicy().verData() == TQSizePolicy::Ignored )
+ sz.rheight() = -1;
+ d->msh = sz;
+ return sz;
+}
+
+/*!
+ \reimp
+*/
+void TQLabel::resizeEvent( TQResizeEvent* e )
+{
+ TQFrame::resizeEvent( e );
+
+#ifdef TQT_NO_RICHTEXT
+ static const bool doc = FALSE;
+#endif
+
+ // optimize for standard labels
+ if ( frameShape() == NoFrame && (align & TQt::WordBreak) == 0 && !doc &&
+ ( e->oldSize().width() >= e->size().width() && (align & Qt::AlignLeft ) == Qt::AlignLeft )
+ && ( e->oldSize().height() >= e->size().height() && (align & Qt::AlignTop ) == Qt::AlignTop ) ) {
+ setWFlags( TQt::WResizeNoErase );
+ return;
+ }
+
+ clearWFlags( TQt::WResizeNoErase );
+ TQRect cr = contentsRect();
+ if ( !lpixmap || !cr.isValid() ||
+ // masked pixmaps can only reduce flicker when being top/left
+ // aligned and when we do not perform scaled contents
+ ( lpixmap->hasAlpha() && ( scaledcontents || ( ( align & (Qt::AlignLeft|Qt::AlignTop) ) != (Qt::AlignLeft|Qt::AlignTop) ) ) ) )
+ return;
+
+ setWFlags( TQt::WResizeNoErase );
+
+ if ( !scaledcontents ) {
+ // don't we all love TQFrame? Reduce pixmap flicker
+ TQRegion reg = TQRect( TQPoint(0, 0), e->size() );
+ reg = reg.subtract( cr );
+ int x = cr.x();
+ int y = cr.y();
+ int w = lpixmap->width();
+ int h = lpixmap->height();
+ if ( (align & TQt::AlignVCenter) == TQt::AlignVCenter )
+ y += cr.height()/2 - h/2;
+ else if ( (align & TQt::AlignBottom) == TQt::AlignBottom)
+ y += cr.height() - h;
+ if ( (align & TQt::AlignRight) == TQt::AlignRight )
+ x += cr.width() - w;
+ else if ( (align & TQt::AlignHCenter) == TQt::AlignHCenter )
+ x += cr.width()/2 - w/2;
+ if ( x > cr.x() )
+ reg = reg.unite( TQRect( cr.x(), cr.y(), x - cr.x(), cr.height() ) );
+ if ( y > cr.y() )
+ reg = reg.unite( TQRect( cr.x(), cr.y(), cr.width(), y - cr.y() ) );
+
+ if ( x + w < cr.right() )
+ reg = reg.unite( TQRect( x + w, cr.y(), cr.right() - x - w, cr.height() ) );
+ if ( y + h < cr.bottom() )
+ reg = reg.unite( TQRect( cr.x(), y + h, cr.width(), cr.bottom() - y - h ) );
+
+ erase( reg );
+ }
+}
+
+
+/*!
+ Draws the label contents using the painter \a p.
+*/
+
+void TQLabel::drawContents( TQPainter *p )
+{
+ TQRect cr = contentsRect();
+
+ TQPixmap *pix = pixmap();
+#ifndef TQT_NO_PICTURE
+ TQPicture *pic = picture();
+#else
+ const int pic = 0;
+#endif
+#ifndef TQT_NO_MOVIE
+ TQMovie *mov = movie();
+#else
+ const int mov = 0;
+#endif
+
+ if ( !mov && !pix && !pic ) {
+ int m = indent();
+ if ( m < 0 && frameWidth() ) // no indent, but we do have a frame
+ m = fontMetrics().width('x') / 2 - margin();
+ if ( m > 0 ) {
+ int hAlign = TQApplication::horizontalAlignment( align );
+ if ( hAlign & Qt::AlignLeft )
+ cr.setLeft( cr.left() + m );
+ if ( hAlign & Qt::AlignRight )
+ cr.setRight( cr.right() - m );
+ if ( align & Qt::AlignTop )
+ cr.setTop( cr.top() + m );
+ if ( align & Qt::AlignBottom )
+ cr.setBottom( cr.bottom() - m );
+ }
+ }
+
+#ifndef TQT_NO_MOVIE
+ if ( mov ) {
+ // ### should add movie to qDrawItem
+ TQRect r = tqstyle().tqitemRect( p, cr, align, isEnabled(), &(mov->framePixmap()),
+ TQString() );
+ // ### could resize movie frame at this point
+ p->drawPixmap(r.x(), r.y(), mov->framePixmap() );
+ }
+ else
+#endif
+#ifndef TQT_NO_RICHTEXT
+ if ( doc ) {
+ doc->setWidth(p, cr.width() );
+ int rh = doc->height();
+ int yo = 0;
+ if ( align & Qt::AlignVCenter )
+ yo = (cr.height()-rh)/2;
+ else if ( align & Qt::AlignBottom )
+ yo = cr.height()-rh;
+ if (! isEnabled() &&
+ tqstyle().tqstyleHint(TQStyle::SH_EtchDisabledText, this)) {
+ TQColorGroup cg = tqcolorGroup();
+ cg.setColor( TQColorGroup::Text, cg.light() );
+ doc->draw(p, cr.x()+1, cr.y()+yo+1, cr, cg, 0);
+ }
+
+ // TQSimpleRichText always draws with TQColorGroup::Text as with
+ // background mode PaletteBase. TQLabel typically has
+ // background mode PaletteBackground, so we create a temporary
+ // color group with the text color adjusted.
+ TQColorGroup cg = tqcolorGroup();
+ if ( backgroundMode() != TQt::PaletteBase && isEnabled() )
+ cg.setColor( TQColorGroup::Text, paletteForegroundColor() );
+
+ doc->draw(p, cr.x(), cr.y()+yo, cr, cg, 0);
+ } else
+#endif
+#ifndef TQT_NO_PICTURE
+ if ( pic ) {
+ TQRect br = pic->boundingRect();
+ int rw = br.width();
+ int rh = br.height();
+ if ( scaledcontents ) {
+ p->save();
+ p->translate( cr.x(), cr.y() );
+#ifndef TQT_NO_TRANSFORMATIONS
+ p->scale( (double)cr.width()/rw, (double)cr.height()/rh );
+#endif
+ p->drawPicture( -br.x(), -br.y(), *pic );
+ p->restore();
+ } else {
+ int xo = 0;
+ int yo = 0;
+ if ( align & Qt::AlignVCenter )
+ yo = (cr.height()-rh)/2;
+ else if ( align & Qt::AlignBottom )
+ yo = cr.height()-rh;
+ if ( align & Qt::AlignRight )
+ xo = cr.width()-rw;
+ else if ( align & Qt::AlignHCenter )
+ xo = (cr.width()-rw)/2;
+ p->drawPicture( cr.x()+xo-br.x(), cr.y()+yo-br.y(), *pic );
+ }
+ } else
+#endif
+ {
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+ if ( scaledcontents && pix ) {
+ if ( !d->img )
+ d->img = new TQImage( lpixmap->convertToImage() );
+
+ if ( !d->pix )
+ d->pix = new TQPixmap;
+ if ( d->pix->size() != cr.size() )
+ d->pix->convertFromImage( d->img->smoothScale( cr.width(), cr.height() ) );
+ pix = d->pix;
+ }
+#endif
+ int tqalignment = align;
+ if ((align & TQt::ShowPrefix) && !tqstyle().tqstyleHint(TQStyle::SH_UnderlineAccelerator, this))
+ tqalignment |= TQt::NoAccel;
+ // ordinary text or pixmap label
+ tqstyle().drawItem( p, cr, tqalignment, tqcolorGroup(), isEnabled(),
+ pix, ltext );
+ }
+}
+
+
+/*!
+ Updates the label, but not the frame.
+*/
+
+void TQLabel::updateLabel( TQSize oldSizeHint )
+{
+ d->valid_hints = -1;
+ TQSizePolicy policy = tqsizePolicy();
+ bool wordBreak = align & TQt::WordBreak;
+ policy.setHeightForWidth( wordBreak );
+ if ( policy != tqsizePolicy() )
+ tqsetSizePolicy( policy );
+ if ( tqsizeHint() != oldSizeHint )
+ updateGeometry();
+ if ( autoresize ) {
+ adjustSize();
+ update( contentsRect() );
+ } else {
+ update( contentsRect() );
+ }
+}
+
+
+/*!
+ \internal
+
+ Internal slot, used to set focus for accelerator labels.
+*/
+#ifndef TQT_NO_ACCEL
+void TQLabel::acceleratorSlot()
+{
+ if ( !lbuddy )
+ return;
+ TQWidget * w = lbuddy;
+ while ( w->focusProxy() )
+ w = TQT_TQWIDGET(w->focusProxy());
+ if ( !w->hasFocus() &&
+ w->isEnabled() &&
+ w->isVisible() &&
+ w->focusPolicy() != Qt::NoFocus ) {
+#ifdef USE_QT4
+ w->setFocus( TQFocusEvent::Shortcut );
+#else // USE_QT4
+ TQFocusEvent::setReason( TQFocusEvent::Shortcut );
+ w->setFocus();
+ TQFocusEvent::resetReason();
+#endif // USE_QT4
+ }
+}
+#endif
+
+/*!
+ \internal
+
+ Internal slot, used to clean up if the buddy widget dies.
+*/
+#ifndef TQT_NO_ACCEL
+void TQLabel::buddyDied() // I can't remember if I cried.
+{
+ lbuddy = 0;
+}
+
+/*!
+ Sets this label's buddy to \a buddy.
+
+ When the user presses the accelerator key indicated by this label,
+ the keyboard focus is transferred to the label's buddy widget.
+
+ The buddy mechanism is only available for TQLabels that contain
+ plain text in which one letter is prefixed with an ampersand, \&.
+ This letter is set as the accelerator key. The letter is displayed
+ underlined, and the '\&' is not displayed (i.e. the \c ShowPrefix
+ tqalignment flag is turned on; see tqsetAlignment()).
+
+ In a dialog, you might create two data entry widgets and a label
+ for each, and set up the tqgeometry tqlayout so each label is just to
+ the left of its data entry widget (its "buddy"), for example:
+ \code
+ TQLineEdit *nameEd = new TQLineEdit( this );
+ TQLabel *nameLb = new TQLabel( "&Name:", this );
+ nameLb->setBuddy( nameEd );
+ TQLineEdit *phoneEd = new TQLineEdit( this );
+ TQLabel *phoneLb = new TQLabel( "&Phone:", this );
+ phoneLb->setBuddy( phoneEd );
+ // ( tqlayout setup not shown )
+ \endcode
+
+ With the code above, the focus jumps to the Name field when the
+ user presses Alt+N, and to the Phone field when the user presses
+ Alt+P.
+
+ To unset a previously set buddy, call this function with \a buddy
+ set to 0.
+
+ \sa buddy(), setText(), TQAccel, tqsetAlignment()
+*/
+
+void TQLabel::setBuddy( TQWidget *buddy )
+{
+ if ( buddy )
+ tqsetAlignment( tqalignment() | TQt::ShowPrefix );
+ else
+ tqsetAlignment( tqalignment() & ~TQt::ShowPrefix );
+
+ if ( lbuddy )
+ disconnect( lbuddy, TQT_SIGNAL(destroyed()), this, TQT_SLOT(buddyDied()) );
+
+ lbuddy = buddy;
+
+ if ( !lbuddy )
+ return;
+#ifndef TQT_NO_RICHTEXT
+ if ( !( textformat == TQt::RichText || (textformat == TQt::AutoText &&
+ TQStyleSheet::mightBeRichText(ltext) ) ) )
+#endif
+ {
+ int p = TQAccel::shortcutKey( ltext );
+ if ( p ) {
+ if ( !accel )
+ accel = new TQAccel( this, "accel label accel" );
+ accel->connectItem( accel->insertItem( p ),
+ this, TQT_SLOT(acceleratorSlot()) );
+ }
+ }
+
+ connect( lbuddy, TQT_SIGNAL(destroyed()), this, TQT_SLOT(buddyDied()) );
+}
+
+
+/*!
+ Returns this label's buddy, or 0 if no buddy is currently set.
+
+ \sa setBuddy()
+*/
+
+TQWidget * TQLabel::buddy() const
+{
+ return lbuddy;
+}
+#endif //TQT_NO_ACCEL
+
+
+#ifndef TQT_NO_MOVIE
+void TQLabel::movieUpdated(const TQRect& rect)
+{
+ TQMovie *mov = movie();
+ if ( mov && !mov->isNull() ) {
+ TQRect r = contentsRect();
+ r = tqstyle().tqitemRect( 0, r, align, isEnabled(), &(mov->framePixmap()),
+ TQString() );
+ r.moveBy(rect.x(), rect.y());
+ r.setWidth(TQMIN(r.width(), rect.width()));
+ r.setHeight(TQMIN(r.height(), rect.height()));
+ tqrepaint( r, mov->framePixmap().tqmask() != 0 );
+ }
+}
+
+void TQLabel::movieResized( const TQSize& size )
+{
+ d->valid_hints = -1;
+ if ( autoresize )
+ adjustSize();
+ movieUpdated( TQRect( TQPoint(0,0), size ) );
+ updateGeometry();
+}
+
+/*!
+ Sets the label contents to \a movie. Any previous content is
+ cleared.
+
+ The buddy accelerator, if any, is disabled.
+
+ The label resizes itself if auto-resizing is enabled.
+
+ \sa movie(), setBuddy()
+*/
+
+void TQLabel::setMovie( const TQMovie& movie )
+{
+ TQSize osh = tqsizeHint();
+ clearContents();
+
+ lmovie = new TQMovie( movie );
+ lmovie->connectResize(this, TQT_SLOT(movieResized(const TQSize&)));
+ lmovie->connectUpdate(this, TQT_SLOT(movieUpdated(const TQRect&)));
+
+ if ( !lmovie->running() ) // Assume that if the movie is running,
+ updateLabel( osh ); // resize/update Q_SIGNALS will come soon enough
+}
+
+#endif // TQT_NO_MOVIE
+
+/*!
+ \internal
+
+ Clears any contents, without updating/repainting the label.
+*/
+
+void TQLabel::clearContents()
+{
+#ifndef TQT_NO_RICHTEXT
+ delete doc;
+ doc = 0;
+#endif
+
+ delete lpixmap;
+ lpixmap = 0;
+#ifndef TQT_NO_PICTURE
+ delete lpicture;
+ lpicture = 0;
+#endif
+ delete d->img;
+ d->img = 0;
+ delete d->pix;
+ d->pix = 0;
+
+ ltext = TQString::null;
+#ifndef TQT_NO_ACCEL
+ if ( accel )
+ accel->clear();
+#endif
+#ifndef TQT_NO_MOVIE
+ if ( lmovie ) {
+ lmovie->disconnectResize(this, TQT_SLOT(movieResized(const TQSize&)));
+ lmovie->disconnectUpdate(this, TQT_SLOT(movieUpdated(const TQRect&)));
+ delete lmovie;
+ lmovie = 0;
+ }
+#endif
+}
+
+
+#ifndef TQT_NO_MOVIE
+
+/*!
+ Returns a pointer to the label's movie, or 0 if no movie has been
+ set.
+
+ \sa setMovie()
+*/
+
+TQMovie* TQLabel::movie() const
+{
+ return lmovie;
+}
+
+#endif // TQT_NO_MOVIE
+
+/*!
+ \property TQLabel::backgroundMode
+ \brief the label's background mode
+
+ Get this property with backgroundMode().
+
+ \sa TQWidget::setBackgroundMode()
+*/
+
+/*!
+ \property TQLabel::textFormat
+ \brief the label's text format
+
+ See the \c TQt::TextFormat enum for an explanation of the possible
+ options.
+
+ The default format is \c AutoText.
+
+ \sa text
+*/
+
+TQt::TextFormat TQLabel::textFormat() const
+{
+ return textformat;
+}
+
+void TQLabel::setTextFormat( TQt::TextFormat format )
+{
+ if ( format != textformat ) {
+ textformat = format;
+ TQString t = ltext;
+ if ( !t.isNull() ) {
+ ltext = TQString::null;
+ setText( t );
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQLabel::fontChange( const TQFont & )
+{
+ if ( !ltext.isEmpty() ) {
+#ifndef TQT_NO_RICHTEXT
+ if ( doc )
+ doc->setDefaultFont( font() );
+#endif
+ updateLabel( TQSize( -1, -1 ) );
+ }
+}
+
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+/*!
+ \property TQLabel::scaledContents
+ \brief whether the label will scale its contents to fill all
+ available space.
+
+ When enabled and the label shows a pixmap, it will scale the
+ pixmap to fill the available space.
+
+ This property's default is FALSE.
+
+ \sa setScaledContents()
+*/
+bool TQLabel::hasScaledContents() const
+{
+ return scaledcontents;
+}
+
+void TQLabel::setScaledContents( bool enable )
+{
+ if ( (bool)scaledcontents == enable )
+ return;
+ scaledcontents = enable;
+ if ( !enable ) {
+ delete d->img;
+ d->img = 0;
+ delete d->pix;
+ d->pix = 0;
+ }
+ update( contentsRect() );
+}
+
+#endif // TQT_NO_IMAGE_SMOOTHSCALE
+
+/*!
+ Sets the font used on the TQLabel to font \a f.
+*/
+
+void TQLabel::setFont( const TQFont &f )
+{
+ TQFrame::setFont( f );
+}
+
+#endif // TQT_NO_LABEL
diff --git a/tqtinterface/qt4/src/widgets/tqlabel.h b/tqtinterface/qt4/src/widgets/tqlabel.h
new file mode 100644
index 0000000..654648e
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqlabel.h
@@ -0,0 +1,177 @@
+/**********************************************************************
+**
+** Definition of TQLabel widget class
+**
+** Created : 941215
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLABEL_H
+#define TQLABEL_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_LABEL
+
+class TQSimpleRichText;
+class TQLabelPrivate;
+
+class TQ_EXPORT TQLabel : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( TQString text READ text WRITE setText )
+ Q_PROPERTY( TextFormat textFormat READ textFormat WRITE setTextFormat )
+ Q_PROPERTY( TQPixmap pixmap READ pixmap WRITE setPixmap )
+ Q_PROPERTY( bool scaledContents READ hasScaledContents WRITE setScaledContents )
+ Q_PROPERTY( Qt::Alignment tqalignment READ alignmentProp WRITE tqsetAlignmentProp )
+ Q_PROPERTY( int indent READ indent WRITE setIndent )
+ TQ_OVERRIDE( BackgroundMode backgroundMode DESIGNABLE true)
+
+public:
+ TQLabel( TQWidget *tqparent, const char* name=0, WFlags f=0 );
+ TQLabel( const TQString &text, TQWidget *tqparent, const char* name=0,
+ WFlags f=0 );
+ TQLabel( TQWidget *buddy, const TQString &,
+ TQWidget *tqparent, const char* name=0, WFlags f=0 );
+ ~TQLabel();
+
+ TQString text() const { return ltext; }
+ TQPixmap *pixmap() const { return lpixmap; }
+#ifndef TQT_NO_PICTURE
+ TQPicture *picture() const { return lpicture; }
+#endif
+#ifndef TQT_NO_MOVIE
+ TQMovie *movie() const;
+#endif
+
+ TQt::TextFormat textFormat() const;
+ void setTextFormat( TQt::TextFormat );
+
+ int tqalignment() const { return align; }
+ virtual void tqsetAlignment( int );
+ inline Qt::Alignment alignmentProp() const { return (Qt::Alignment)tqalignment(); }
+ inline virtual void tqsetAlignmentProp( Qt::Alignment al ) { tqsetAlignment((int)al); }
+ int indent() const { return extraMargin; }
+ void setIndent( int );
+
+ bool autoResize() const { return autoresize; }
+ virtual void setAutoResize( bool );
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+ bool hasScaledContents() const;
+ void setScaledContents( bool );
+#endif
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+#ifndef TQT_NO_ACCEL
+ virtual void setBuddy( TQWidget * );
+ TQWidget *buddy() const;
+#endif
+ int heightForWidth(int) const;
+
+ void setFont( const TQFont &f );
+
+public Q_SLOTS:
+ virtual void setText( const TQString &);
+ virtual void setPixmap( const TQPixmap & );
+#ifndef TQT_NO_PICTURE
+ virtual void setPicture( const TQPicture & );
+#endif
+#ifndef TQT_NO_MOVIE
+ virtual void setMovie( const TQMovie & );
+#endif
+ virtual void setNum( int );
+ virtual void setNum( double );
+ void clear();
+
+protected:
+ void drawContents( TQPainter * );
+ void fontChange( const TQFont & );
+ void resizeEvent( TQResizeEvent* );
+
+private Q_SLOTS:
+#ifndef TQT_NO_ACCEL
+ void acceleratorSlot();
+ void buddyDied();
+#endif
+#ifndef TQT_NO_MOVIE
+ void movieUpdated(const TQRect&);
+ void movieResized(const TQSize&);
+#endif
+
+private:
+ void init();
+ void clearContents();
+ void updateLabel( TQSize oldSizeHint );
+ TQSize sizeForWidth( int w ) const;
+ TQString ltext;
+ TQPixmap *lpixmap;
+#ifndef TQT_NO_PICTURE
+ TQPicture *lpicture;
+#endif
+#ifndef TQT_NO_MOVIE
+ TQMovie * lmovie;
+#endif
+#ifndef TQT_NO_ACCEL
+ TQWidget * lbuddy;
+#endif
+ ushort align;
+ short extraMargin;
+ uint autoresize:1;
+ uint scaledcontents :1;
+ TQt::TextFormat textformat;
+#ifndef TQT_NO_RICHTEXT
+ TQSimpleRichText* doc;
+#endif
+#ifndef TQT_NO_ACCEL
+ TQAccel * accel;
+#endif
+ TQLabelPrivate* d;
+
+ friend class TQTipLabel;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQLabel( const TQLabel & );
+ TQLabel &operator=( const TQLabel & );
+#endif
+};
+
+
+#endif // TQT_NO_LABEL
+
+#endif // TQLABEL_H
diff --git a/tqtinterface/qt4/src/widgets/tqlcdnumber.cpp b/tqtinterface/qt4/src/widgets/tqlcdnumber.cpp
new file mode 100644
index 0000000..16f225b
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqlcdnumber.cpp
@@ -0,0 +1,1170 @@
+/****************************************************************************
+**
+** Implementation of TQLCDNumber class
+**
+** Created : 940518
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqlcdnumber.h"
+#ifndef TQT_NO_LCDNUMBER
+#include "tqbitarray.h"
+#include "tqpainter.h"
+
+
+/*!
+ \class TQLCDNumber tqlcdnumber.h
+
+ \brief The TQLCDNumber widget displays a number with LCD-like digits.
+
+ \ingroup basic
+ \mainclass
+
+ It can display a number in just about any size. It can display
+ decimal, hexadecimal, octal or binary numbers. It is easy to
+ connect to data sources using the display() slot, which is
+ overloaded to take any of five argument types.
+
+ There are also Q_SLOTS to change the base with setMode() and the
+ decimal point with setSmallDecimalPoint().
+
+ TQLCDNumber emits the overflow() signal when it is asked to display
+ something beyond its range. The range is set by setNumDigits(),
+ but setSmallDecimalPoint() also influences it. If the display is
+ set to hexadecimal, octal or binary, the integer equivalent of the
+ value is displayed.
+
+ These digits and other symbols can be shown: 0/O, 1, 2, 3, 4, 5/S,
+ 6, 7, 8, 9/g, minus, decimal point, A, B, C, D, E, F, h, H, L, o,
+ P, r, u, U, Y, colon, degree sign (which is specified as single
+ quote in the string) and space. TQLCDNumber substitutes spaces for
+ illegal characters.
+
+ It is not possible to retrieve the contents of a TQLCDNumber
+ object, although you can retrieve the numeric value with value().
+ If you really need the text, we recommend that you connect the
+ Q_SIGNALS that feed the display() slot to another slot as well and
+ store the value there.
+
+ Incidentally, TQLCDNumber is the very oldest part of TQt, tracing
+ back to a BASIC program on the \link
+ http://www.nvg.ntnu.no/sinclair/computers/zxspectrum/zxspectrum.htm
+ Sinclair Spectrum\endlink.
+
+ <img src=qlcdnum-m.png> <img src=qlcdnum-w.png>
+
+ \sa TQLabel, TQFrame
+*/
+
+/*!
+ \enum TQLCDNumber::Mode
+
+ This type determines how numbers are shown.
+
+ \value Hex Hexadecimal
+ \value Dec Decimal
+ \value Oct Octal
+ \value Bin Binary
+
+ If the display is set to hexadecimal, octal or binary, the integer
+ equivalent of the value is displayed.
+*/
+
+/*!
+ \enum TQLCDNumber::SegmentStyle
+
+ This type determines the visual appearance of the TQLCDNumber
+ widget.
+
+ \value Outline gives raised segments filled with the background brush.
+ \value Filled gives raised segments filled with the foreground brush.
+ \value Flat gives flat segments filled with the foreground brush.
+*/
+
+
+
+/*!
+ \fn void TQLCDNumber::overflow()
+
+ This signal is emitted whenever the TQLCDNumber is asked to display
+ a too-large number or a too-long string.
+
+ It is never emitted by setNumDigits().
+*/
+
+
+static TQString int2string( int num, int base, int ndigits, bool *oflow )
+{
+ TQString s;
+ bool negative;
+ if ( num < 0 ) {
+ negative = TRUE;
+ num = -num;
+ } else {
+ negative = FALSE;
+ }
+ switch( base ) {
+ case TQLCDNumber::HEX:
+ s.sprintf( "%*x", ndigits, num );
+ break;
+ case TQLCDNumber::DEC:
+ s.sprintf( "%*i", ndigits, num );
+ break;
+ case TQLCDNumber::OCT:
+ s.sprintf( "%*o", ndigits, num );
+ break;
+ case TQLCDNumber::BIN:
+ {
+ char buf[42];
+ char *p = &buf[41];
+ uint n = num;
+ int len = 0;
+ *p = '\0';
+ do {
+ *--p = (char)((n&1)+'0');
+ n >>= 1;
+ len++;
+ } while ( n != 0 );
+ len = ndigits - len;
+ if ( len > 0 )
+ s.fill( ' ', len );
+ s += TQString::tqfromLatin1(p);
+ }
+ break;
+ }
+ if ( negative ) {
+ for ( int i=0; i<(int)s.length(); i++ ) {
+ if ( s[i] != ' ' ) {
+ if ( i != 0 ) {
+ s[i-1] = '-';
+ } else {
+ s.insert( 0, '-' );
+ }
+ break;
+ }
+ }
+ }
+ if ( oflow )
+ *oflow = (int)s.length() > ndigits;
+ return s;
+}
+
+
+static TQString double2string( double num, int base, int ndigits, bool *oflow )
+{
+ TQString s;
+ if ( base != TQLCDNumber::DEC ) {
+ bool of = num >= 2147483648.0 || num < -2147483648.0;
+ if ( of ) { // oops, integer overflow
+ if ( oflow )
+ *oflow = TRUE;
+ return s;
+ }
+ s = int2string( (int)num, base, ndigits, 0 );
+ } else { // decimal base
+ int nd = ndigits;
+ do {
+ s.sprintf( "%*.*g", ndigits, nd, num );
+ int i = s.tqfind('e');
+ if ( i > 0 && s[i+1]=='+' ) {
+ s[i] = ' ';
+ s[i+1] = 'e';
+ }
+ } while (nd-- && (int)s.length() > ndigits);
+ }
+ if ( oflow )
+ *oflow = (int)s.length() > ndigits;
+ return s;
+}
+
+
+static const char *getSegments( char ch ) // gets list of segments for ch
+{
+ static const char segments[30][8] =
+ { { 0, 1, 2, 4, 5, 6,99, 0}, // 0 0 / O
+ { 2, 5,99, 0, 0, 0, 0, 0}, // 1 1
+ { 0, 2, 3, 4, 6,99, 0, 0}, // 2 2
+ { 0, 2, 3, 5, 6,99, 0, 0}, // 3 3
+ { 1, 2, 3, 5,99, 0, 0, 0}, // 4 4
+ { 0, 1, 3, 5, 6,99, 0, 0}, // 5 5 / S
+ { 0, 1, 3, 4, 5, 6,99, 0}, // 6 6
+ { 0, 2, 5,99, 0, 0, 0, 0}, // 7 7
+ { 0, 1, 2, 3, 4, 5, 6,99}, // 8 8
+ { 0, 1, 2, 3, 5, 6,99, 0}, // 9 9 / g
+ { 3,99, 0, 0, 0, 0, 0, 0}, // 10 -
+ { 7,99, 0, 0, 0, 0, 0, 0}, // 11 .
+ { 0, 1, 2, 3, 4, 5,99, 0}, // 12 A
+ { 1, 3, 4, 5, 6,99, 0, 0}, // 13 B
+ { 0, 1, 4, 6,99, 0, 0, 0}, // 14 C
+ { 2, 3, 4, 5, 6,99, 0, 0}, // 15 D
+ { 0, 1, 3, 4, 6,99, 0, 0}, // 16 E
+ { 0, 1, 3, 4,99, 0, 0, 0}, // 17 F
+ { 1, 3, 4, 5,99, 0, 0, 0}, // 18 h
+ { 1, 2, 3, 4, 5,99, 0, 0}, // 19 H
+ { 1, 4, 6,99, 0, 0, 0, 0}, // 20 L
+ { 3, 4, 5, 6,99, 0, 0, 0}, // 21 o
+ { 0, 1, 2, 3, 4,99, 0, 0}, // 22 P
+ { 3, 4,99, 0, 0, 0, 0, 0}, // 23 r
+ { 4, 5, 6,99, 0, 0, 0, 0}, // 24 u
+ { 1, 2, 4, 5, 6,99, 0, 0}, // 25 U
+ { 1, 2, 3, 5, 6,99, 0, 0}, // 26 Y
+ { 8, 9,99, 0, 0, 0, 0, 0}, // 27 :
+ { 0, 1, 2, 3,99, 0, 0, 0}, // 28 '
+ {99, 0, 0, 0, 0, 0, 0, 0} }; // 29 empty
+
+ if (ch >= '0' && ch <= '9')
+ return segments[ch - '0'];
+ if (ch >= 'A' && ch <= 'F')
+ return segments[ch - 'A' + 12];
+ if (ch >= 'a' && ch <= 'f')
+ return segments[ch - 'a' + 12];
+
+ int n;
+ switch ( ch ) {
+ case '-':
+ n = 10; break;
+ case 'O':
+ n = 0; break;
+ case 'g':
+ n = 9; break;
+ case '.':
+ n = 11; break;
+ case 'h':
+ n = 18; break;
+ case 'H':
+ n = 19; break;
+ case 'l':
+ case 'L':
+ n = 20; break;
+ case 'o':
+ n = 21; break;
+ case 'p':
+ case 'P':
+ n = 22; break;
+ case 'r':
+ case 'R':
+ n = 23; break;
+ case 's':
+ case 'S':
+ n = 5; break;
+ case 'u':
+ n = 24; break;
+ case 'U':
+ n = 25; break;
+ case 'y':
+ case 'Y':
+ n = 26; break;
+ case ':':
+ n = 27; break;
+ case '\'':
+ n = 28; break;
+ default:
+ n = 29; break;
+ }
+ return segments[n];
+}
+
+
+/*!
+ Constructs an LCD number, sets the number of digits to 5, the base
+ to decimal, the decimal point mode to 'small' and the frame style
+ to a raised box. The segmentStyle() is set to \c Outline.
+
+ The \a tqparent and \a name arguments are passed to the TQFrame
+ constructor.
+
+ \sa setNumDigits(), setSmallDecimalPoint()
+*/
+
+TQLCDNumber::TQLCDNumber( TQWidget *tqparent, const char *name )
+ : TQFrame( tqparent, name )
+{
+ ndigits = 5;
+ init();
+}
+
+
+/*!
+ Constructs an LCD number, sets the number of digits to \a
+ numDigits, the base to decimal, the decimal point mode to 'small'
+ and the frame style to a raised box. The segmentStyle() is set to
+ \c Outline.
+
+ The \a tqparent and \a name arguments are passed to the TQFrame
+ constructor.
+
+ \sa setNumDigits(), setSmallDecimalPoint()
+*/
+
+TQLCDNumber::TQLCDNumber( uint numDigits, TQWidget *tqparent, const char *name )
+ : TQFrame( tqparent, name )
+{
+ ndigits = numDigits;
+ init();
+}
+
+/*!
+ \internal
+*/
+
+void TQLCDNumber::init()
+{
+ setFrameStyle( TQFrame::Box | TQFrame::Raised );
+ val = 0;
+ base = DEC;
+ smallPoint = FALSE;
+ setNumDigits( ndigits );
+ setSegmentStyle( Outline );
+ d = 0;
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Minimum ) );
+}
+
+/*!
+ Destroys the LCD number.
+*/
+
+TQLCDNumber::~TQLCDNumber()
+{
+}
+
+
+/*!
+ \property TQLCDNumber::numDigits
+ \brief the current number of digits displayed
+
+ Corresponds to the current number of digits. If \l
+ TQLCDNumber::smallDecimalPoint is FALSE, the decimal point occupies
+ one digit position.
+
+ \sa numDigits, smallDecimalPoint
+*/
+
+void TQLCDNumber::setNumDigits( int numDigits )
+{
+ if ( numDigits > 99 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQLCDNumber::setNumDigits: (%s) Max 99 digits allowed",
+ name( "unnamed" ) );
+#endif
+ numDigits = 99;
+ }
+ if (numDigits < 0 ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQLCDNumber::setNumDigits: (%s) Min 0 digits allowed",
+ name( "unnamed" ) );
+#endif
+ numDigits = 0;
+ }
+ if ( digitStr.isNull() ) { // from constructor
+ ndigits = numDigits;
+ digitStr.fill( ' ', ndigits );
+ points.fill( 0, ndigits );
+ digitStr[ndigits - 1] = '0'; // "0" is the default number
+ } else {
+ bool doDisplay = ndigits == 0;
+ if ( numDigits == ndigits ) // no change
+ return;
+ register int i;
+ int dif;
+ if ( numDigits > ndigits ) { // expand
+ dif = numDigits - ndigits;
+ TQString buf;
+ buf.fill( ' ', dif );
+ digitStr.insert( 0, buf );
+ points.resize( numDigits );
+ for ( i=numDigits-1; i>=dif; i-- )
+ points.setBit( i, points.testBit(i-dif) );
+ for ( i=0; i<dif; i++ )
+ points.clearBit( i );
+ } else { // shrink
+ dif = ndigits - numDigits;
+ digitStr = digitStr.right( numDigits );
+ TQBitArray tmpPoints = points.copy();
+ points.resize( numDigits );
+ for ( i=0; i<(int)numDigits; i++ )
+ points.setBit( i, tmpPoints.testBit(i+dif) );
+ }
+ ndigits = numDigits;
+ if ( doDisplay )
+ display( value() );
+ update();
+ }
+}
+
+
+/*!
+ \overload
+
+ Returns TRUE if \a num is too big to be displayed in its entirety;
+ otherwise returns FALSE.
+
+ \sa display(), numDigits(), smallDecimalPoint()
+*/
+
+bool TQLCDNumber::checkOverflow( int num ) const
+{
+ bool of;
+ int2string( num, base, ndigits, &of );
+ return of;
+}
+
+
+/*!
+ Returns TRUE if \a num is too big to be displayed in its entirety;
+ otherwise returns FALSE.
+
+ \sa display(), numDigits(), smallDecimalPoint()
+*/
+
+bool TQLCDNumber::checkOverflow( double num ) const
+{
+ bool of;
+ double2string( num, base, ndigits, &of );
+ return of;
+}
+
+
+/*!
+ \property TQLCDNumber::mode
+ \brief the current display mode (number base)
+
+ Corresponds to the current display mode, which is one of \c BIN,
+ \c OCT, \c DEC (the default) and \c HEX. \c DEC mode can display
+ floating point values, the other modes display the integer
+ equivalent.
+
+ \sa smallDecimalPoint(), setHexMode(), setDecMode(), setOctMode(), setBinMode()
+*/
+
+TQLCDNumber::Mode TQLCDNumber::mode() const
+{
+ return (TQLCDNumber::Mode) base;
+}
+
+void TQLCDNumber::setMode( Mode m )
+{
+ base = m;
+
+ display( val );
+}
+
+
+/*!
+ \property TQLCDNumber::value
+ \brief the displayed value
+
+ This property corresponds to the current value displayed by the
+ LCDNumber.
+
+ If the displayed value is not a number, the property has a value
+ of 0.
+*/
+
+double TQLCDNumber::value() const
+{
+ return val;
+}
+
+/*!
+ \overload
+
+ Displays the number \a num.
+*/
+void TQLCDNumber::display( double num )
+{
+ val = num;
+ bool of;
+ TQString s = double2string( num, base, ndigits, &of );
+ if ( of )
+ emit overflow();
+ else
+ internalSetString( s );
+}
+
+/*!
+ \property TQLCDNumber::intValue
+ \brief the displayed value rounded to the nearest integer
+
+ This property corresponds to the nearest integer to the current
+ value displayed by the LCDNumber. This is the value used for
+ hexadecimal, octal and binary modes.
+
+ If the displayed value is not a number, the property has a value
+ of 0.
+*/
+int TQLCDNumber::intValue() const
+{
+ return (int)(val < 0 ? val - 0.5 : val + 0.5);
+}
+
+
+/*!
+ \overload
+
+ Displays the number \a num.
+*/
+void TQLCDNumber::display( int num )
+{
+ val = (double)num;
+ bool of;
+ TQString s = int2string( num, base, ndigits, &of );
+ if ( of )
+ emit overflow();
+ else
+ internalSetString( s );
+}
+
+
+/*!
+ Displays the number represented by the string \a s.
+
+ This version of the function disregards mode() and
+ smallDecimalPoint().
+
+ These digits and other symbols can be shown: 0/O, 1, 2, 3, 4, 5/S,
+ 6, 7, 8, 9/g, minus, decimal point, A, B, C, D, E, F, h, H, L, o,
+ P, r, u, U, Y, colon, degree sign (which is specified as single
+ quote in the string) and space. TQLCDNumber substitutes spaces for
+ illegal characters.
+*/
+
+void TQLCDNumber::display( const TQString &s )
+{
+ val = 0;
+ bool ok = FALSE;
+ double v = s.toDouble( &ok );
+ if ( ok )
+ val = v;
+ internalSetString( s );
+}
+
+/*!
+ Calls setMode( HEX ). Provided for convenience (e.g. for
+ connecting buttons to it).
+
+ \sa setMode(), setDecMode(), setOctMode(), setBinMode(), mode()
+*/
+
+void TQLCDNumber::setHexMode()
+{
+ setMode( HEX );
+}
+
+
+/*!
+ Calls setMode( DEC ). Provided for convenience (e.g. for
+ connecting buttons to it).
+
+ \sa setMode(), setHexMode(), setOctMode(), setBinMode(), mode()
+*/
+
+void TQLCDNumber::setDecMode()
+{
+ setMode( DEC );
+}
+
+
+/*!
+ Calls setMode( OCT ). Provided for convenience (e.g. for
+ connecting buttons to it).
+
+ \sa setMode(), setHexMode(), setDecMode(), setBinMode(), mode()
+*/
+
+void TQLCDNumber::setOctMode()
+{
+ setMode( OCT );
+}
+
+
+/*!
+ Calls setMode( BIN ). Provided for convenience (e.g. for
+ connecting buttons to it).
+
+ \sa setMode(), setHexMode(), setDecMode(), setOctMode(), mode()
+*/
+
+void TQLCDNumber::setBinMode()
+{
+ setMode( BIN );
+}
+
+
+/*!
+ \property TQLCDNumber::smallDecimalPoint
+ \brief the style of the decimal point
+
+ If TRUE the decimal point is drawn between two digit positions.
+ Otherwise it occupies a digit position of its own, i.e. is drawn
+ in a digit position. The default is FALSE.
+
+ The inter-digit space is made slightly wider when the decimal
+ point is drawn between the digits.
+
+ \sa mode
+*/
+
+void TQLCDNumber::setSmallDecimalPoint( bool b )
+{
+ smallPoint = b;
+}
+
+
+/*!
+ Draws the LCD number using painter \a p. This function is called
+ from TQFrame::paintEvent().
+*/
+
+
+void TQLCDNumber::drawContents( TQPainter *p )
+{
+ if ( smallPoint )
+ drawString( digitStr, *p, &points, FALSE );
+ else
+ drawString( digitStr, *p, 0, FALSE );
+}
+
+
+/*!
+ \internal
+*/
+
+void TQLCDNumber::internalDisplay( const TQString & )
+{
+ // Not used anymore
+}
+
+void TQLCDNumber::internalSetString( const TQString& s )
+{
+ TQString buffer;
+ int i;
+ int len = s.length();
+ TQBitArray newPoints(ndigits);
+
+ if ( !smallPoint ) {
+ if ( len == ndigits )
+ buffer = s;
+ else
+ buffer = TQT_TQSTRING(s.right( ndigits )).rightJustify( ndigits, ' ' );
+ } else {
+ int index = -1;
+ bool lastWasPoint = TRUE;
+ newPoints.clearBit(0);
+ for ( i=0; i<len; i++ ) {
+ if ( s[i] == '.' ) {
+ if ( lastWasPoint ) { // point already set for digit?
+ if ( index == ndigits - 1 ) // no more digits
+ break;
+ index++;
+ buffer[index] = ' '; // 2 points in a row, add space
+ }
+ newPoints.setBit(index); // set decimal point
+ lastWasPoint = TRUE;
+ } else {
+ if ( index == ndigits - 1 )
+ break;
+ index++;
+ buffer[index] = s[i];
+ newPoints.clearBit(index); // decimal point default off
+ lastWasPoint = FALSE;
+ }
+ }
+ if ( index < ((int) ndigits) - 1 ) {
+ for( i=index; i>=0; i-- ) {
+ buffer[ndigits - 1 - index + i] = buffer[i];
+ newPoints.setBit( ndigits - 1 - index + i,
+ newPoints.testBit(i) );
+ }
+ for( i=0; i<ndigits-index-1; i++ ) {
+ buffer[i] = ' ';
+ newPoints.clearBit(i);
+ }
+ }
+ }
+
+ if ( buffer == digitStr )
+ return;
+
+ if ( backgroundMode() == TQt::FixedPixmap
+ || TQT_TQBRUSH_OBJECT(tqcolorGroup().brush( TQColorGroup::Background )).pixmap() ) {
+ digitStr = buffer;
+ if ( smallPoint )
+ points = newPoints;
+ tqrepaint( contentsRect() );
+ } else {
+ TQPainter p( this );
+ if ( !smallPoint )
+ drawString( buffer, p );
+ else
+ drawString( buffer, p, &newPoints );
+ }
+}
+
+/*!
+ \internal
+*/
+
+void TQLCDNumber::drawString( const TQString &s, TQPainter &p,
+ TQBitArray *newPoints, bool newString )
+{
+ TQPoint pos;
+
+ int digitSpace = smallPoint ? 2 : 1;
+ int xSegLen = width()*5/(ndigits*(5 + digitSpace) + digitSpace);
+ int ySegLen = height()*5/12;
+ int segLen = ySegLen > xSegLen ? xSegLen : ySegLen;
+ int xAdvance = segLen*( 5 + digitSpace )/5;
+ int xOffset = ( width() - ndigits*xAdvance + segLen/5 )/2;
+ int yOffset = ( height() - segLen*2 )/2;
+
+ for ( int i=0; i<ndigits; i++ ) {
+ pos = TQPoint( xOffset + xAdvance*i, yOffset );
+ if ( newString )
+ drawDigit( pos, p, segLen, s[i], digitStr[i].latin1() );
+ else
+ drawDigit( pos, p, segLen, s[i]);
+ if ( newPoints ) {
+ char newPoint = newPoints->testBit(i) ? '.' : ' ';
+ if ( newString ) {
+ char oldPoint = points.testBit(i) ? '.' : ' ';
+ drawDigit( pos, p, segLen, newPoint, oldPoint );
+ } else {
+ drawDigit( pos, p, segLen, newPoint );
+ }
+ }
+ }
+ if ( newString ) {
+ digitStr = s;
+ if ( (int)digitStr.length() > ndigits )
+ digitStr.truncate( ndigits );
+ if ( newPoints )
+ points = *newPoints;
+ }
+}
+
+
+/*!
+ \internal
+*/
+
+void TQLCDNumber::drawDigit( const TQPoint &pos, TQPainter &p, int segLen,
+ char newCh, char oldCh )
+{
+// Draws and/or erases segments to change display of a single digit
+// from oldCh to newCh
+
+ char updates[18][2]; // can hold 2 times number of segments, only
+ // first 9 used if segment table is correct
+ int nErases;
+ int nUpdates;
+ const char *segs;
+ int i,j;
+
+ const char erase = 0;
+ const char draw = 1;
+ const char leaveAlone = 2;
+
+ segs = getSegments(oldCh);
+ for ( nErases=0; segs[nErases] != 99; nErases++ ) {
+ updates[nErases][0] = erase; // get segments to erase to
+ updates[nErases][1] = segs[nErases]; // remove old char
+ }
+ nUpdates = nErases;
+ segs = getSegments(newCh);
+ for(i = 0 ; segs[i] != 99 ; i++) {
+ for ( j=0; j<nErases; j++ )
+ if ( segs[i] == updates[j][1] ) { // same segment ?
+ updates[j][0] = leaveAlone; // yes, already on screen
+ break;
+ }
+ if ( j == nErases ) { // if not already on screen
+ updates[nUpdates][0] = draw;
+ updates[nUpdates][1] = segs[i];
+ nUpdates++;
+ }
+ }
+ for ( i=0; i<nUpdates; i++ ) {
+ if ( updates[i][0] == draw )
+ drawSegment( pos, updates[i][1], p, segLen );
+ if (updates[i][0] == erase)
+ drawSegment( pos, updates[i][1], p, segLen, TRUE );
+ }
+}
+
+
+static void addPoint( TQPointArray &a, const TQPoint &p )
+{
+ uint n = a.size();
+ a.resize( n + 1 );
+ a.setPoint( n, p );
+}
+
+/*!
+ \internal
+*/
+
+void TQLCDNumber::drawSegment( const TQPoint &pos, char segmentNo, TQPainter &p,
+ int segLen, bool erase )
+{
+ TQPoint pt = pos;
+ int width = segLen/5;
+
+ const TQColorGroup & g = tqcolorGroup();
+ TQColor lightColor,darkColor,fgColor;
+ if ( erase ){
+ lightColor = backgroundColor();
+ darkColor = lightColor;
+ fgColor = lightColor;
+ } else {
+ lightColor = g.light();
+ darkColor = g.dark();
+ fgColor = g.foreground();
+ }
+
+#define LINETO(X,Y) addPoint( a, TQPoint(pt.x() + (X),pt.y() + (Y)))
+#define LIGHT
+#define DARK
+
+ if ( fill ) {
+ TQPointArray a(0);
+
+ //The following is an exact copy of the switch below.
+ //don't make any changes here
+ switch ( segmentNo ) {
+ case 0 :
+ p.moveTo(pt);
+ LIGHT;
+ LINETO(segLen - 1,0);
+ DARK;
+ LINETO(segLen - width - 1,width);
+ LINETO(width,width);
+ LINETO(0,0);
+ break;
+ case 1 :
+ pt += TQPoint(0 , 1);
+ p.moveTo(pt);
+ LIGHT;
+ LINETO(width,width);
+ DARK;
+ LINETO(width,segLen - width/2 - 2);
+ LINETO(0,segLen - 2);
+ LIGHT;
+ LINETO(0,0);
+ break;
+ case 2 :
+ pt += TQPoint(segLen - 1 , 1);
+ p.moveTo(pt);
+ DARK;
+ LINETO(0,segLen - 2);
+ LINETO(-width,segLen - width/2 - 2);
+ LIGHT;
+ LINETO(-width,width);
+ LINETO(0,0);
+ break;
+ case 3 :
+ pt += TQPoint(0 , segLen);
+ p.moveTo(pt);
+ LIGHT;
+ LINETO(width,-width/2);
+ LINETO(segLen - width - 1,-width/2);
+ LINETO(segLen - 1,0);
+ DARK;
+ if (width & 1) { // adjust for integer division error
+ LINETO(segLen - width - 3,width/2 + 1);
+ LINETO(width + 2,width/2 + 1);
+ } else {
+ LINETO(segLen - width - 1,width/2);
+ LINETO(width,width/2);
+ }
+ LINETO(0,0);
+ break;
+ case 4 :
+ pt += TQPoint(0 , segLen + 1);
+ p.moveTo(pt);
+ LIGHT;
+ LINETO(width,width/2);
+ DARK;
+ LINETO(width,segLen - width - 2);
+ LINETO(0,segLen - 2);
+ LIGHT;
+ LINETO(0,0);
+ break;
+ case 5 :
+ pt += TQPoint(segLen - 1 , segLen + 1);
+ p.moveTo(pt);
+ DARK;
+ LINETO(0,segLen - 2);
+ LINETO(-width,segLen - width - 2);
+ LIGHT;
+ LINETO(-width,width/2);
+ LINETO(0,0);
+ break;
+ case 6 :
+ pt += TQPoint(0 , segLen*2);
+ p.moveTo(pt);
+ LIGHT;
+ LINETO(width,-width);
+ LINETO(segLen - width - 1,-width);
+ LINETO(segLen - 1,0);
+ DARK;
+ LINETO(0,0);
+ break;
+ case 7 :
+ if ( smallPoint ) // if smallpoint place'.' between other digits
+ pt += TQPoint(segLen + width/2 , segLen*2);
+ else
+ pt += TQPoint(segLen/2 , segLen*2);
+ p.moveTo(pt);
+ DARK;
+ LINETO(width,0);
+ LINETO(width,-width);
+ LIGHT;
+ LINETO(0,-width);
+ LINETO(0,0);
+ break;
+ case 8 :
+ pt += TQPoint(segLen/2 - width/2 + 1 , segLen/2 + width);
+ p.moveTo(pt);
+ DARK;
+ LINETO(width,0);
+ LINETO(width,-width);
+ LIGHT;
+ LINETO(0,-width);
+ LINETO(0,0);
+ break;
+ case 9 :
+ pt += TQPoint(segLen/2 - width/2 + 1 , 3*segLen/2 + width);
+ p.moveTo(pt);
+ DARK;
+ LINETO(width,0);
+ LINETO(width,-width);
+ LIGHT;
+ LINETO(0,-width);
+ LINETO(0,0);
+ break;
+#if defined(TQT_CHECK_RANGE)
+ default :
+ qWarning( "TQLCDNumber::drawSegment: (%s) Internal error."
+ " Illegal segment id: %d\n",
+ name( "unnamed" ), segmentNo );
+#endif
+ }
+ // End exact copy
+ p.setPen( fgColor );
+ p.setBrush( fgColor );
+ p.drawPolygon( a );
+ p.setBrush( Qt::NoBrush );
+
+ pt = pos;
+ }
+#undef LINETO
+#undef LIGHT
+#undef DARK
+
+#define LINETO(X,Y) p.lineTo(TQPoint(pt.x() + (X),pt.y() + (Y)))
+#define LIGHT p.setPen(lightColor)
+#define DARK p.setPen(darkColor)
+ if ( shadow )
+ switch ( segmentNo ) {
+ case 0 :
+ p.moveTo(pt);
+ LIGHT;
+ LINETO(segLen - 1,0);
+ DARK;
+ LINETO(segLen - width - 1,width);
+ LINETO(width,width);
+ LINETO(0,0);
+ break;
+ case 1 :
+ pt += TQPoint(0,1);
+ p.moveTo(pt);
+ LIGHT;
+ LINETO(width,width);
+ DARK;
+ LINETO(width,segLen - width/2 - 2);
+ LINETO(0,segLen - 2);
+ LIGHT;
+ LINETO(0,0);
+ break;
+ case 2 :
+ pt += TQPoint(segLen - 1 , 1);
+ p.moveTo(pt);
+ DARK;
+ LINETO(0,segLen - 2);
+ LINETO(-width,segLen - width/2 - 2);
+ LIGHT;
+ LINETO(-width,width);
+ LINETO(0,0);
+ break;
+ case 3 :
+ pt += TQPoint(0 , segLen);
+ p.moveTo(pt);
+ LIGHT;
+ LINETO(width,-width/2);
+ LINETO(segLen - width - 1,-width/2);
+ LINETO(segLen - 1,0);
+ DARK;
+ if (width & 1) { // adjust for integer division error
+ LINETO(segLen - width - 3,width/2 + 1);
+ LINETO(width + 2,width/2 + 1);
+ } else {
+ LINETO(segLen - width - 1,width/2);
+ LINETO(width,width/2);
+ }
+ LINETO(0,0);
+ break;
+ case 4 :
+ pt += TQPoint(0 , segLen + 1);
+ p.moveTo(pt);
+ LIGHT;
+ LINETO(width,width/2);
+ DARK;
+ LINETO(width,segLen - width - 2);
+ LINETO(0,segLen - 2);
+ LIGHT;
+ LINETO(0,0);
+ break;
+ case 5 :
+ pt += TQPoint(segLen - 1 , segLen + 1);
+ p.moveTo(pt);
+ DARK;
+ LINETO(0,segLen - 2);
+ LINETO(-width,segLen - width - 2);
+ LIGHT;
+ LINETO(-width,width/2);
+ LINETO(0,0);
+ break;
+ case 6 :
+ pt += TQPoint(0 , segLen*2);
+ p.moveTo(pt);
+ LIGHT;
+ LINETO(width,-width);
+ LINETO(segLen - width - 1,-width);
+ LINETO(segLen - 1,0);
+ DARK;
+ LINETO(0,0);
+ break;
+ case 7 :
+ if ( smallPoint ) // if smallpoint place'.' between other digits
+ pt += TQPoint(segLen + width/2 , segLen*2);
+ else
+ pt += TQPoint(segLen/2 , segLen*2);
+ p.moveTo(pt);
+ DARK;
+ LINETO(width,0);
+ LINETO(width,-width);
+ LIGHT;
+ LINETO(0,-width);
+ LINETO(0,0);
+ break;
+ case 8 :
+ pt += TQPoint(segLen/2 - width/2 + 1 , segLen/2 + width);
+ p.moveTo(pt);
+ DARK;
+ LINETO(width,0);
+ LINETO(width,-width);
+ LIGHT;
+ LINETO(0,-width);
+ LINETO(0,0);
+ break;
+ case 9 :
+ pt += TQPoint(segLen/2 - width/2 + 1 , 3*segLen/2 + width);
+ p.moveTo(pt);
+ DARK;
+ LINETO(width,0);
+ LINETO(width,-width);
+ LIGHT;
+ LINETO(0,-width);
+ LINETO(0,0);
+ break;
+#if defined(TQT_CHECK_RANGE)
+ default :
+ qWarning( "TQLCDNumber::drawSegment: (%s) Internal error."
+ " Illegal segment id: %d\n",
+ name( "unnamed" ), segmentNo );
+#endif
+ }
+
+#undef LINETO
+#undef LIGHT
+#undef DARK
+}
+
+
+
+/*!
+ \property TQLCDNumber::segmentStyle
+ \brief the style of the LCDNumber
+
+ \table
+ \header \i Style \i Result
+ \row \i \c Outline
+ \i Produces raised segments filled with the background color
+ (this is the default).
+ \row \i \c Filled
+ \i Produces raised segments filled with the foreground color.
+ \row \i \c Flat
+ \i Produces flat segments filled with the foreground color.
+ \endtable
+
+ \c Outline and \c Filled will additionally use
+ TQColorGroup::light() and TQColorGroup::dark() for shadow effects.
+*/
+void TQLCDNumber::setSegmentStyle( SegmentStyle s )
+{
+ fill = ( s == Flat || s == Filled );
+ shadow = ( s == Outline || s == Filled );
+ update();
+}
+
+TQLCDNumber::SegmentStyle TQLCDNumber::segmentStyle() const
+{
+ TQ_ASSERT( fill || shadow );
+ if ( !fill && shadow )
+ return Outline;
+ if ( fill && shadow )
+ return Filled;
+ return Flat;
+}
+
+
+/*!\reimp
+*/
+TQSize TQLCDNumber::tqsizeHint() const
+{
+ return TQSize( 10 + 9 * (numDigits() + (smallDecimalPoint() ? 0 : 1)), 23 );
+}
+
+#endif // TQT_NO_LCDNUMBER
diff --git a/tqtinterface/qt4/src/widgets/tqlcdnumber.h b/tqtinterface/qt4/src/widgets/tqlcdnumber.h
new file mode 100644
index 0000000..e954305
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqlcdnumber.h
@@ -0,0 +1,147 @@
+/****************************************************************************
+**
+** Definition of TQLCDNumber class
+**
+** Created : 940518
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLCDNUMBER_H
+#define TQLCDNUMBER_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#include "tqbitarray.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_LCDNUMBER
+
+
+class TQLCDNumberPrivate;
+
+class TQ_EXPORT TQLCDNumber : public TQFrame // LCD number widget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( Mode SegmentStyle )
+ Q_PROPERTY( bool smallDecimalPoint READ smallDecimalPoint WRITE setSmallDecimalPoint )
+ Q_PROPERTY( int numDigits READ numDigits WRITE setNumDigits )
+ Q_PROPERTY( Mode mode READ mode WRITE setMode )
+ Q_PROPERTY( SegmentStyle segmentStyle READ segmentStyle WRITE setSegmentStyle )
+ Q_PROPERTY( double value READ value WRITE display )
+ Q_PROPERTY( int intValue READ intValue WRITE display )
+
+public:
+ TQLCDNumber( TQWidget* tqparent=0, const char* name=0 );
+ TQLCDNumber( uint numDigits, TQWidget* tqparent=0, const char* name=0 );
+ ~TQLCDNumber();
+
+ enum Mode { Hex, Dec, Oct, Bin, HEX = Hex, DEC = Dec, OCT = Oct,
+ BIN = Bin };
+ enum SegmentStyle { Outline, Filled, Flat };
+
+ bool smallDecimalPoint() const;
+
+ int numDigits() const;
+ virtual void setNumDigits( int nDigits );
+
+ bool checkOverflow( double num ) const;
+ bool checkOverflow( int num ) const;
+
+ Mode mode() const;
+ virtual void setMode( Mode );
+
+ SegmentStyle segmentStyle() const;
+ virtual void setSegmentStyle( SegmentStyle );
+
+ double value() const;
+ int intValue() const;
+
+ TQSize tqsizeHint() const;
+
+public Q_SLOTS:
+ void display( const TQString &str );
+ void display( int num );
+ void display( double num );
+ virtual void setHexMode();
+ virtual void setDecMode();
+ virtual void setOctMode();
+ virtual void setBinMode();
+ virtual void setSmallDecimalPoint( bool );
+
+Q_SIGNALS:
+ void overflow();
+
+protected:
+ void drawContents( TQPainter * );
+
+private:
+ void init();
+ void internalDisplay( const TQString &);
+ void internalSetString( const TQString& s );
+ void drawString( const TQString& s, TQPainter &, TQBitArray * = 0,
+ bool = TRUE );
+ //void drawString( const TQString &, TQPainter &, TQBitArray * = 0 ) const;
+ void drawDigit( const TQPoint &, TQPainter &, int, char,
+ char = ' ' );
+ void drawSegment( const TQPoint &, char, TQPainter &, int, bool = FALSE );
+
+ int ndigits;
+ double val;
+ uint base : 2;
+ uint smallPoint : 1;
+ uint fill : 1;
+ uint shadow : 1;
+ TQString digitStr;
+ TQBitArray points;
+ TQLCDNumberPrivate * d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQLCDNumber( const TQLCDNumber & );
+ TQLCDNumber &operator=( const TQLCDNumber & );
+#endif
+};
+
+inline bool TQLCDNumber::smallDecimalPoint() const
+{ return (bool)smallPoint; }
+
+inline int TQLCDNumber::numDigits() const
+{ return ndigits; }
+
+
+#endif // TQT_NO_LCDNUMBER
+
+#endif // TQLCDNUMBER_H
diff --git a/tqtinterface/qt4/src/widgets/tqlineedit.cpp b/tqtinterface/qt4/src/widgets/tqlineedit.cpp
new file mode 100644
index 0000000..2d41152
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqlineedit.cpp
@@ -0,0 +1,2848 @@
+/**********************************************************************
+**
+** Implementation of TQLineEdit widget class
+**
+** Created : 941011
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqlineedit.h"
+#ifndef TQT_NO_LINEEDIT
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqfontmetrics.h"
+#include "tqpixmap.h"
+#include "tqclipboard.h"
+#include "tqapplication.h"
+#include "tqvalidator.h"
+#include "tqdragobject.h"
+#include "tqtimer.h"
+#include "tqpopupmenu.h"
+#include "tqstringlist.h"
+#include "tqguardedptr.h"
+#include "tqstyle.h"
+#include "tqwhatsthis.h"
+#include "../kernel/tqinternal_p.h"
+#include "private/tqtextlayout_p.h"
+#include "tqvaluevector.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+#ifndef TQT_NO_ACCEL
+#include "tqkeysequence.h"
+#define ACCEL_KEY(k) "\t" + TQString(TQKeySequence( TQt::CTRL | TQt::Key_ ## k ))
+#else
+#define ACCEL_KEY(k) "\t" + TQString("Ctrl+" #k)
+#endif
+
+#define innerMargin 1
+
+struct TQLineEditPrivate : public TQt
+{
+ TQLineEditPrivate( TQLineEdit *q )
+ : q(q), cursor(0), cursorTimer(0), tripleClickTimer(0), frame(1),
+ cursorVisible(0), separator(0), readOnly(0), modified(0),
+ direction(TQChar::DirON), dragEnabled(1), tqalignment(0),
+ echoMode(0), textDirty(0), selDirty(0), validInput(1),
+ ascent(0), maxLength(32767), menuId(0),
+ hscroll(0), validator(0), maskData(0),
+ undoState(0), selstart(0), selend(0),
+ imstart(0), imend(0), imselstart(0), imselend(0)
+#ifndef TQT_NO_DRAGANDDROP
+ ,dndTimer(0)
+#endif
+ {}
+ void init( const TQString&);
+
+ TQLineEdit *q;
+ TQString text;
+ int cursor;
+ int cursorTimer;
+ TQPoint tripleClick;
+ int tripleClickTimer;
+ uint frame : 1;
+ uint cursorVisible : 1;
+ uint separator : 1;
+ uint readOnly : 1;
+ uint modified : 1;
+ uint direction : 5;
+ uint dragEnabled : 1;
+ uint tqalignment : 3;
+ uint echoMode : 2;
+ uint textDirty : 1;
+ uint selDirty : 1;
+ uint validInput : 1;
+ int ascent;
+ int maxLength;
+ int menuId;
+ int hscroll;
+ TQChar passwordChar; // obsolete
+
+ void finishChange( int validateFromState = -1, bool setModified = TRUE );
+
+ const TQValidator* validator;
+ struct MaskInputData {
+ enum Casemode { NoCaseMode, Upper, Lower };
+ TQChar maskChar; // either the separator char or the inputtqmask
+ bool separator;
+ Casemode caseMode;
+ };
+ TQString inputMask;
+ TQChar blank;
+ MaskInputData *maskData;
+ inline int nextMaskBlank( int pos ) {
+ int c = tqfindInMask( pos, TRUE, FALSE );
+ separator |= ( c != pos );
+ return ( c != -1 ? c : maxLength );
+ }
+ inline int prevMaskBlank( int pos ) {
+ int c = tqfindInMask( pos, FALSE, FALSE );
+ separator |= ( c != pos );
+ return ( c != -1 ? c : 0 );
+ }
+
+ void setCursorVisible( bool visible );
+
+
+ // undo/redo handling
+ enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection };
+ struct Command {
+ inline Command(){}
+ inline Command( CommandType type, int pos, TQChar c )
+ :type(type),c(c),pos(pos){}
+ uint type : 4;
+ TQChar c;
+ int pos;
+ };
+ int undoState;
+ TQValueVector<Command> history;
+ void addCommand( const Command& cmd );
+ void insert( const TQString& s );
+ void del( bool wasBackspace = FALSE );
+ void remove( int pos );
+
+ inline void separate() { separator = TRUE; }
+ inline void undo( int until = -1 ) {
+ if ( !isUndoAvailable() )
+ return;
+ deselect();
+ while ( undoState && undoState > until ) {
+ Command& cmd = history[--undoState];
+ switch ( cmd.type ) {
+ case Insert:
+ text.remove( cmd.pos, 1);
+ cursor = cmd.pos;
+ break;
+ case Remove:
+ case RemoveSelection:
+ text.insert( cmd.pos, cmd.c );
+ cursor = cmd.pos + 1;
+ break;
+ case Delete:
+ case DeleteSelection:
+ text.insert( cmd.pos, cmd.c );
+ cursor = cmd.pos;
+ break;
+ case Separator:
+ continue;
+ }
+ if ( until < 0 && undoState ) {
+ Command& next = history[undoState-1];
+ if ( next.type != cmd.type && next.type < RemoveSelection
+ && !( cmd.type >= RemoveSelection && next.type != Separator ) )
+ break;
+ }
+ }
+ modified = ( undoState != 0 );
+ textDirty = TRUE;
+ }
+ inline void redo() {
+ if ( !isRedoAvailable() )
+ return;
+ deselect();
+ while ( undoState < (int)history.size() ) {
+ Command& cmd = history[undoState++];
+ switch ( cmd.type ) {
+ case Insert:
+ text.insert( cmd.pos, cmd.c );
+ cursor = cmd.pos + 1;
+ break;
+ case Remove:
+ case Delete:
+ case RemoveSelection:
+ case DeleteSelection:
+ text.remove( cmd.pos, 1 );
+ cursor = cmd.pos;
+ break;
+ case Separator:
+ continue;
+ }
+ if ( undoState < (int)history.size() ) {
+ Command& next = history[undoState];
+ if ( next.type != cmd.type && cmd.type < RemoveSelection
+ && !( next.type >= RemoveSelection && cmd.type != Separator ) )
+ break;
+ }
+ }
+ textDirty = TRUE;
+ }
+ inline bool isUndoAvailable() const { return !readOnly && undoState; }
+ inline bool isRedoAvailable() const { return !readOnly && undoState < (int)history.size(); }
+
+ // bidi
+ inline bool isRightToLeft() const { return direction==TQChar::DirON?text.isRightToLeft():(direction==TQChar::DirR); }
+
+ // selection
+ int selstart, selend;
+ inline bool allSelected() const { return !text.isEmpty() && selstart == 0 && selend == (int)text.length(); }
+ inline bool hasSelectedText() const { return !text.isEmpty() && selend > selstart; }
+ inline void deselect() { selDirty |= (selend > selstart); selstart = selend = 0; }
+ void removeSelectedText();
+#ifndef TQT_NO_CLIPBOARD
+ void copy( bool clipboard = TRUE ) const;
+#endif
+ inline bool inSelection( int x ) const
+ { if ( selstart >= selend ) return FALSE;
+ int pos = xToPos( x, TQTextItem::OnCharacters ); return pos >= selstart && pos < selend; }
+
+ // masking
+ void parseInputMask( const TQString &maskFields );
+ bool isValidInput( TQChar key, TQChar tqmask ) const;
+ TQString maskString( uint pos, const TQString &str, bool clear = FALSE ) const;
+ TQString clearString( uint pos, uint len ) const;
+ TQString stripString( const TQString &str ) const;
+ int tqfindInMask( int pos, bool forward, bool tqfindSeparator, TQChar searchChar = TQChar() ) const;
+
+ // input methods
+ int imstart, imend, imselstart, imselend;
+
+ // complex text tqlayout
+ TQTextLayout textLayout;
+ void updateTextLayout();
+ void moveCursor( int pos, bool mark = FALSE );
+ void setText( const TQString& txt );
+ int xToPos( int x, TQTextItem::CursorPosition = TQTextItem::BetweenCharacters ) const;
+ inline int visualAlignment() const { return tqalignment ? tqalignment : int( isRightToLeft() ? TQt::AlignRight : TQt::AlignLeft ); }
+ TQRect cursorRect() const;
+ void updateMicroFocusHint();
+
+#ifndef TQT_NO_DRAGANDDROP
+ // drag and drop
+ TQPoint dndPos;
+ int dndTimer;
+ bool drag();
+#endif
+};
+
+
+/*!
+ \class TQLineEdit
+ \brief The TQLineEdit widget is a one-line text editor.
+
+ \ingroup basic
+ \mainclass
+
+ A line edit allows the user to enter and edit a single line of
+ plain text with a useful collection of editing functions,
+ including undo and redo, cut and paste, and drag and drop.
+
+ By changing the echoMode() of a line edit, it can also be used as
+ a "write-only" field, for inputs such as passwords.
+
+ The length of the text can be constrained to maxLength(). The text
+ can be arbitrarily constrained using a validator() or an
+ inputMask(), or both.
+
+ A related class is TQTextEdit which allows multi-line, rich-text
+ editing.
+
+ You can change the text with setText() or insert(). The text is
+ retrieved with text(); the displayed text (which may be different,
+ see \l{EchoMode}) is retrieved with displayText(). Text can be
+ selected with setSelection() or selectAll(), and the selection can
+ be cut(), copy()ied and paste()d. The text can be aligned with
+ tqsetAlignment().
+
+ When the text changes the textChanged() signal is emitted; when
+ the Return or Enter key is pressed the returnPressed() signal is
+ emitted. Note that if there is a validator set on the line edit,
+ the returnPressed() signal will only be emitted if the validator
+ returns \c Acceptable.
+
+ By default, TQLineEdits have a frame as specified by the Windows
+ and Motif style guides; you can turn it off by calling
+ setFrame(FALSE).
+
+ The default key bindings are described below. The line edit also
+ provides a context menu (usually invoked by a right mouse click)
+ that presents some of these editing options.
+ \target desc
+ \table
+ \header \i Keypress \i Action
+ \row \i Left Arrow \i Moves the cursor one character to the left.
+ \row \i Shift+Left Arrow \i Moves and selects text one character to the left.
+ \row \i Right Arrow \i Moves the cursor one character to the right.
+ \row \i Shift+Right Arrow \i Moves and selects text one character to the right.
+ \row \i Home \i Moves the cursor to the beginning of the line.
+ \row \i End \i Moves the cursor to the end of the line.
+ \row \i Backspace \i Deletes the character to the left of the cursor.
+ \row \i Ctrl+Backspace \i Deletes the word to the left of the cursor.
+ \row \i Delete \i Deletes the character to the right of the cursor.
+ \row \i Ctrl+Delete \i Deletes the word to the right of the cursor.
+ \row \i Ctrl+A \i Moves the cursor to the beginning of the line.
+ \row \i Ctrl+B \i Moves the cursor one character to the left.
+ \row \i Ctrl+C \i Copies the selected text to the clipboard.
+ (Windows also supports Ctrl+Insert for this operation.)
+ \row \i Ctrl+D \i Deletes the character to the right of the cursor.
+ \row \i Ctrl+E \i Moves the cursor to the end of the line.
+ \row \i Ctrl+F \i Moves the cursor one character to the right.
+ \row \i Ctrl+H \i Deletes the character to the left of the cursor.
+ \row \i Ctrl+K \i Deletes to the end of the line.
+ \row \i Ctrl+V \i Pastes the clipboard text into line edit.
+ (Windows also supports Shift+Insert for this operation.)
+ \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard.
+ (Windows also supports Shift+Delete for this operation.)
+ \row \i Ctrl+Z \i Undoes the last operation.
+ \row \i Ctrl+Y \i Redoes the last undone operation.
+ \endtable
+
+ Any other key sequence that represents a valid character, will
+ cause the character to be inserted into the line edit.
+
+ <img src=qlined-m.png> <img src=qlined-w.png>
+
+ \sa TQTextEdit TQLabel TQComboBox
+ \link guibooks.html#fowler GUI Design Handbook: Field, Entry\endlink
+*/
+
+
+/*!
+ \fn void TQLineEdit::textChanged( const TQString& )
+
+ This signal is emitted whenever the text changes. The argument is
+ the new text.
+*/
+
+/*!
+ \fn void TQLineEdit::selectionChanged()
+
+ This signal is emitted whenever the selection changes.
+
+ \sa hasSelectedText(), selectedText()
+*/
+
+/*!
+ \fn void TQLineEdit::lostFocus()
+
+ This signal is emitted when the line edit has lost focus.
+
+ \sa hasFocus(), TQWidget::focusInEvent(), TQWidget::focusOutEvent()
+*/
+
+
+
+/*!
+ Constructs a line edit with no text.
+
+ The maximum text length is set to 32767 characters.
+
+ The \a tqparent and \a name arguments are sent to the TQWidget constructor.
+
+ \sa setText(), setMaxLength()
+*/
+
+TQLineEdit::TQLineEdit( TQWidget* tqparent, const char* name )
+ : TQFrame( tqparent, name, TQt::WNoAutoErase ), d(new TQLineEditPrivate( this ))
+{
+ d->init( TQString::null );
+}
+
+/*!
+ Constructs a line edit containing the text \a contents.
+
+ The cursor position is set to the end of the line and the maximum
+ text length to 32767 characters.
+
+ The \a tqparent and \a name arguments are sent to the TQWidget
+ constructor.
+
+ \sa text(), setMaxLength()
+*/
+
+TQLineEdit::TQLineEdit( const TQString& contents, TQWidget* tqparent, const char* name )
+ : TQFrame( tqparent, name, TQt::WNoAutoErase ), d(new TQLineEditPrivate( this ))
+{
+ d->init( contents );
+}
+
+/*!
+ Constructs a line edit with an input \a inputMask and the text \a
+ contents.
+
+ The cursor position is set to the end of the line and the maximum
+ text length is set to the length of the tqmask (the number of tqmask
+ characters and separators).
+
+ The \a tqparent and \a name arguments are sent to the TQWidget
+ constructor.
+
+ \sa setMask() text()
+*/
+TQLineEdit::TQLineEdit( const TQString& contents, const TQString &inputMask, TQWidget* tqparent, const char* name )
+ : TQFrame( tqparent, name, TQt::WNoAutoErase ), d(new TQLineEditPrivate( this ))
+{
+ d->parseInputMask( inputMask );
+ if ( d->maskData ) {
+ TQString ms = d->maskString( 0, contents );
+ d->init( ms + d->clearString( ms.length(), d->maxLength - ms.length() ) );
+ d->cursor = d->nextMaskBlank( ms.length() );
+ } else {
+ d->init( contents );
+ }
+}
+
+/*!
+ Destroys the line edit.
+*/
+
+TQLineEdit::~TQLineEdit()
+{
+ delete [] d->maskData;
+ delete d;
+}
+
+
+/*!
+ \property TQLineEdit::text
+ \brief the line edit's text
+
+ Note that setting this property clears the selection, clears the
+ undo/redo history, moves the cursor to the end of the line and
+ resets the \c modified property to FALSE. The text is not
+ validated when inserted with setText().
+
+ The text is truncated to maxLength() length.
+
+ \sa insert()
+*/
+TQString TQLineEdit::text() const
+{
+ TQString res = d->text;
+ if ( d->maskData )
+ res = d->stripString( d->text );
+ return ( res.isNull() ? TQString::tqfromLatin1("") : res );
+}
+
+void TQLineEdit::setText( const TQString& text)
+{
+ resetInputContext();
+ d->setText( text );
+ d->modified = FALSE;
+ d->finishChange( -1, FALSE );
+}
+
+
+/*!
+ \property TQLineEdit::displayText
+ \brief the displayed text
+
+ If \c EchoMode is \c Normal this returns the same as text(); if
+ \c EchoMode is \c Password it returns a string of asterisks
+ text().length() characters long, e.g. "******"; if \c EchoMode is
+ \c NoEcho returns an empty string, "".
+
+ \sa setEchoMode() text() EchoMode
+*/
+
+TQString TQLineEdit::displayText() const
+{
+ if ( d->echoMode == NoEcho )
+ return TQString::tqfromLatin1("");
+ TQString res = d->text;
+ if ( d->echoMode == Password )
+ res.fill( passwordChar() );
+ return ( res.isNull() ? TQString::tqfromLatin1("") : res );
+}
+
+
+/*!
+ \property TQLineEdit::maxLength
+ \brief the maximum permitted length of the text
+
+ If the text is too long, it is truncated at the limit.
+
+ If truncation occurs any selected text will be unselected, the
+ cursor position is set to 0 and the first part of the string is
+ shown.
+
+ If the line edit has an input tqmask, the tqmask defines the maximum
+ string length.
+
+ \sa inputMask
+*/
+
+int TQLineEdit::maxLength() const
+{
+ return d->maxLength;
+}
+
+void TQLineEdit::setMaxLength( int maxLength )
+{
+ if ( d->maskData )
+ return;
+ d->maxLength = maxLength;
+ setText( d->text );
+}
+
+
+
+/*!
+ \property TQLineEdit::frame
+ \brief whether the line edit draws itself with a frame
+
+ If enabled (the default) the line edit draws itself inside a
+ two-pixel frame, otherwise the line edit draws itself without any
+ frame.
+*/
+bool TQLineEdit::frame() const
+{
+ return frameShape() != NoFrame;
+}
+
+
+void TQLineEdit::setFrame( bool enable )
+{
+ setFrameStyle( enable ? ( LineEditPanel | Sunken ) : NoFrame );
+}
+
+
+/*!
+ \enum TQLineEdit::EchoMode
+
+ This enum type describes how a line edit should display its
+ contents.
+
+ \value Normal Display characters as they are entered. This is the
+ default.
+ \value NoEcho Do not display anything. This may be appropriate
+ for passwords where even the length of the
+ password should be kept secret.
+ \value Password Display asterisks instead of the characters
+ actually entered.
+
+ \sa setEchoMode() echoMode()
+*/
+
+
+/*!
+ \property TQLineEdit::echoMode
+ \brief the line edit's echo mode
+
+ The initial setting is \c Normal, but TQLineEdit also supports \c
+ NoEcho and \c Password modes.
+
+ The widget's display and the ability to copy or drag the text is
+ affected by this setting.
+
+ \sa EchoMode displayText()
+*/
+
+TQLineEdit::EchoMode TQLineEdit::echoMode() const
+{
+ return (EchoMode) d->echoMode;
+}
+
+void TQLineEdit::setEchoMode( EchoMode mode )
+{
+ if (mode == (EchoMode)d->echoMode)
+ return;
+ d->echoMode = mode;
+ d->updateTextLayout();
+ update();
+}
+
+
+
+/*!
+ Returns a pointer to the current input validator, or 0 if no
+ validator has been set.
+
+ \sa setValidator()
+*/
+
+const TQValidator * TQLineEdit::validator() const
+{
+ return d->validator;
+}
+
+/*!
+ Sets this line edit to only accept input that the validator, \a v,
+ will accept. This allows you to place any arbitrary constraints on
+ the text which may be entered.
+
+ If \a v == 0, setValidator() removes the current input validator.
+ The initial setting is to have no input validator (i.e. any input
+ is accepted up to maxLength()).
+
+ \sa validator() TQIntValidator TQDoubleValidator TQRegExpValidator
+*/
+
+void TQLineEdit::setValidator( const TQValidator *v )
+{
+ if ( d->validator )
+ disconnect( (TQObject*)d->validator, TQT_SIGNAL( destroyed() ),
+ this, TQT_SLOT( clearValidator() ) );
+ d->validator = v;
+ if ( d->validator )
+ connect( (TQObject*)d->validator, TQT_SIGNAL( destroyed() ),
+ this, TQT_SLOT( clearValidator() ) );
+}
+
+
+
+/*!
+ Returns a recommended size for the widget.
+
+ The width returned, in pixels, is usually enough for about 15 to
+ 20 characters.
+*/
+
+TQSize TQLineEdit::tqsizeHint() const
+{
+ constPolish();
+ TQFontMetrics fm( font() );
+ int h = TQMAX(fm.lineSpacing(), 14) + 2*innerMargin;
+ int w = fm.width( 'x' ) * 17; // "some"
+ int m = frameWidth() * 2;
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_LineEdit, this,
+ TQSize( w + m, h + m ).
+ expandedTo(TQApplication::globalStrut())));
+}
+
+
+/*!
+ Returns a minimum size for the line edit.
+
+ The width returned is enough for at least one character.
+*/
+
+TQSize TQLineEdit::tqminimumSizeHint() const
+{
+ constPolish();
+ TQFontMetrics fm = fontMetrics();
+ int h = fm.height() + TQMAX( 2*innerMargin, fm.leading() );
+ int w = fm.maxWidth();
+ int m = frameWidth() * 2;
+ return TQSize( w + m, h + m );
+}
+
+
+/*!
+ \property TQLineEdit::cursorPosition
+ \brief the current cursor position for this line edit
+
+ Setting the cursor position causes a tqrepaint when appropriate.
+*/
+
+int TQLineEdit::cursorPosition() const
+{
+ return d->cursor;
+}
+
+
+void TQLineEdit::setCursorPosition( int pos )
+{
+ if (pos < 0)
+ pos = 0;
+
+ if ( pos <= (int) d->text.length() )
+ d->moveCursor( pos );
+}
+
+
+/*! \obsolete Use setText(), setCursorPosition() and setSelection() instead.
+*/
+
+bool TQLineEdit::validateAndSet( const TQString &newText, int newPos,
+ int newMarkAnchor, int newMarkDrag )
+{
+ int priorState = d->undoState;
+ d->selstart = 0;
+ d->selend = d->text.length();
+ d->removeSelectedText();
+ d->insert( newText );
+ d->finishChange( priorState );
+ if ( d->undoState > priorState ) {
+ d->cursor = newPos;
+ d->selstart = TQMIN( newMarkAnchor, newMarkDrag );
+ d->selend = TQMAX( newMarkAnchor, newMarkDrag );
+ d->updateMicroFocusHint();
+ update();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*!
+ \property TQLineEdit::tqalignment
+ \brief the tqalignment of the line edit
+
+ Possible Values are \c TQt::AlignAuto, \c TQt::AlignLeft, \c
+ TQt::AlignRight and \c TQt::AlignHCenter.
+
+ Attempting to set the tqalignment to an illegal flag combination
+ does nothing.
+
+ \sa TQt::AlignmentFlags
+*/
+
+int TQLineEdit::tqalignment() const
+{
+ return d->tqalignment;
+}
+
+void TQLineEdit::tqsetAlignment( int flag )
+{
+ d->tqalignment = flag & 0x7;
+ update();
+}
+
+
+/*!
+ \obsolete
+ \fn void TQLineEdit::cursorRight( bool, int )
+
+ Use cursorForward() instead.
+
+ \sa cursorForward()
+*/
+
+/*!
+ \obsolete
+ \fn void TQLineEdit::cursorLeft( bool, int )
+ For compatibilty with older applications only. Use cursorBackward()
+ instead.
+ \sa cursorBackward()
+*/
+
+/*!
+ Moves the cursor forward \a steps characters. If \a mark is TRUE
+ each character moved over is added to the selection; if \a mark is
+ FALSE the selection is cleared.
+
+ \sa cursorBackward()
+*/
+
+void TQLineEdit::cursorForward( bool mark, int steps )
+{
+ int cursor = d->cursor;
+ if ( steps > 0 ) {
+ while( steps-- )
+ cursor = d->textLayout.nextCursorPosition( cursor );
+ } else if ( steps < 0 ) {
+ while ( steps++ )
+ cursor = d->textLayout.previousCursorPosition( cursor );
+ }
+ d->moveCursor( cursor, mark );
+}
+
+
+/*!
+ Moves the cursor back \a steps characters. If \a mark is TRUE each
+ character moved over is added to the selection; if \a mark is
+ FALSE the selection is cleared.
+
+ \sa cursorForward()
+*/
+void TQLineEdit::cursorBackward( bool mark, int steps )
+{
+ cursorForward( mark, -steps );
+}
+
+/*!
+ Moves the cursor one word forward. If \a mark is TRUE, the word is
+ also selected.
+
+ \sa cursorWordBackward()
+*/
+void TQLineEdit::cursorWordForward( bool mark )
+{
+ d->moveCursor( d->textLayout.nextCursorPosition(d->cursor, TQTextLayout::SkipWords), mark );
+}
+
+/*!
+ Moves the cursor one word backward. If \a mark is TRUE, the word
+ is also selected.
+
+ \sa cursorWordForward()
+*/
+
+void TQLineEdit::cursorWordBackward( bool mark )
+{
+ d->moveCursor( d->textLayout.previousCursorPosition(d->cursor, TQTextLayout::SkipWords), mark );
+}
+
+
+/*!
+ If no text is selected, deletes the character to the left of the
+ text cursor and moves the cursor one position to the left. If any
+ text is selected, the cursor is moved to the beginning of the
+ selected text and the selected text is deleted.
+
+ \sa del()
+*/
+void TQLineEdit::backspace()
+{
+ int priorState = d->undoState;
+ if ( d->hasSelectedText() ) {
+ d->removeSelectedText();
+ } else if ( d->cursor ) {
+ --d->cursor;
+ if ( d->maskData )
+ d->cursor = d->prevMaskBlank( d->cursor );
+ d->del( TRUE );
+ }
+ d->finishChange( priorState );
+}
+
+/*!
+ If no text is selected, deletes the character to the right of the
+ text cursor. If any text is selected, the cursor is moved to the
+ beginning of the selected text and the selected text is deleted.
+
+ \sa backspace()
+*/
+
+void TQLineEdit::del()
+{
+ int priorState = d->undoState;
+ if ( d->hasSelectedText() ) {
+ d->removeSelectedText();
+ } else {
+ int n = d->textLayout.nextCursorPosition( d->cursor ) - d->cursor;
+ while ( n-- )
+ d->del();
+ }
+ d->finishChange( priorState );
+}
+
+/*!
+ Moves the text cursor to the beginning of the line unless it is
+ already there. If \a mark is TRUE, text is selected towards the
+ first position; otherwise, any selected text is unselected if the
+ cursor is moved.
+
+ \sa end()
+*/
+
+void TQLineEdit::home( bool mark )
+{
+ d->moveCursor( 0, mark );
+}
+
+/*!
+ Moves the text cursor to the end of the line unless it is already
+ there. If \a mark is TRUE, text is selected towards the last
+ position; otherwise, any selected text is unselected if the cursor
+ is moved.
+
+ \sa home()
+*/
+
+void TQLineEdit::end( bool mark )
+{
+ d->moveCursor( d->text.length(), mark );
+}
+
+
+/*!
+ \property TQLineEdit::modified
+ \brief whether the line edit's contents has been modified by the user
+
+ The modified flag is never read by TQLineEdit; it has a default value
+ of FALSE and is changed to TRUE whenever the user changes the line
+ edit's contents.
+
+ This is useful for things that need to provide a default value but
+ do not start out knowing what the default should be (perhaps it
+ depends on other fields on the form). Start the line edit without
+ the best default, and when the default is known, if modified()
+ returns FALSE (the user hasn't entered any text), insert the
+ default value.
+
+ Calling clearModified() or setText() resets the modified flag to
+ FALSE.
+*/
+
+bool TQLineEdit::isModified() const
+{
+ return d->modified;
+}
+
+/*!
+ Resets the modified flag to FALSE.
+
+ \sa isModified()
+*/
+void TQLineEdit::clearModified()
+{
+ d->modified = FALSE;
+ d->history.clear();
+ d->undoState = 0;
+}
+
+/*!
+ \obsolete
+ \property TQLineEdit::edited
+ \brief whether the line edit has been edited. Use modified instead.
+*/
+bool TQLineEdit::edited() const { return d->modified; }
+void TQLineEdit::setEdited( bool on ) { d->modified = on; }
+
+/*!
+ \obsolete
+ \property TQLineEdit::hasMarkedText
+ \brief whether part of the text has been selected by the user. Use hasSelectedText instead.
+*/
+
+/*!
+ \property TQLineEdit::hasSelectedText
+ \brief whether there is any text selected
+
+ hasSelectedText() returns TRUE if some or all of the text has been
+ selected by the user; otherwise returns FALSE.
+
+ \sa selectedText()
+*/
+
+
+bool TQLineEdit::hasSelectedText() const
+{
+ return d->hasSelectedText();
+}
+
+/*!
+ \obsolete
+ \property TQLineEdit::markedText
+ \brief the text selected by the user. Use selectedText instead.
+*/
+
+/*!
+ \property TQLineEdit::selectedText
+ \brief the selected text
+
+ If there is no selected text this property's value is
+ TQString::null.
+
+ \sa hasSelectedText()
+*/
+
+TQString TQLineEdit::selectedText() const
+{
+ if ( d->hasSelectedText() )
+ return d->text.mid( d->selstart, d->selend - d->selstart );
+ return TQString::null;
+}
+
+/*!
+ selectionStart() returns the index of the first selected character in the
+ line edit or -1 if no text is selected.
+
+ \sa selectedText()
+*/
+
+int TQLineEdit::selectionStart() const
+{
+ return d->hasSelectedText() ? d->selstart : -1;
+}
+
+/*! \obsolete use selectedText(), selectionStart() */
+bool TQLineEdit::getSelection( int *start, int *end )
+{
+ if ( d->hasSelectedText() && start && end ) {
+ *start = d->selstart;
+ *end = d->selend;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*!
+ Selects text from position \a start and for \a length characters.
+
+ Note that this function sets the cursor's position to the end of
+ the selection regardless of its current position.
+
+ \sa deselect() selectAll() getSelection() cursorForward() cursorBackward()
+*/
+
+void TQLineEdit::setSelection( int start, int length )
+{
+ if ( start < 0 || start > (int)d->text.length() || length < 0 ) {
+ d->selstart = d->selend = 0;
+ } else {
+ d->selstart = start;
+ d->selend = TQMIN( start + length, (int)d->text.length() );
+ d->cursor = d->selend;
+ }
+ update();
+}
+
+
+/*!
+ \property TQLineEdit::undoAvailable
+ \brief whether undo is available
+*/
+
+bool TQLineEdit::isUndoAvailable() const
+{
+ return d->isUndoAvailable();
+}
+
+/*!
+ \property TQLineEdit::redoAvailable
+ \brief whether redo is available
+*/
+
+bool TQLineEdit::isRedoAvailable() const
+{
+ return d->isRedoAvailable();
+}
+
+/*!
+ \property TQLineEdit::dragEnabled
+ \brief whether the lineedit starts a drag if the user presses and
+ moves the mouse on some selected text
+*/
+
+bool TQLineEdit::dragEnabled() const
+{
+ return d->dragEnabled;
+}
+
+void TQLineEdit::setDragEnabled( bool b )
+{
+ d->dragEnabled = b;
+}
+
+/*!
+ \property TQLineEdit::acceptableInput
+ \brief whether the input satisfies the inputMask and the
+ validator.
+
+ \sa setInputMask(), setValidator()
+*/
+bool TQLineEdit::hasAcceptableInput() const
+{
+#ifndef TQT_NO_VALIDATOR
+ TQString text = d->text;
+ int cursor = d->cursor;
+ if ( d->validator && d->validator->validate( text, cursor ) != TQValidator::Acceptable )
+ return FALSE;
+#endif
+
+ if ( !d->maskData )
+ return TRUE;
+
+ if ( d->text.length() != (uint)d->maxLength )
+ return FALSE;
+
+ for ( uint i=0; i < (uint)d->maxLength; i++) {
+ if ( d->maskData[i].separator ) {
+ if ( d->text[(int)i] != d->maskData[i].maskChar )
+ return FALSE;
+ } else {
+ if ( !d->isValidInput( d->text[(int)i], d->maskData[i].maskChar ) )
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
+/*!
+ \property TQLineEdit::inputMask
+ \brief The validation input tqmask
+
+ If no tqmask is set, inputMask() returns TQString::null.
+
+ Sets the TQLineEdit's validation tqmask. Validators can be used
+ instead of, or in conjunction with masks; see setValidator().
+
+ Unset the tqmask and return to normal TQLineEdit operation by passing
+ an empty string ("") or just calling setInputMask() with no
+ arguments.
+
+ The tqmask format understands these tqmask characters:
+ \table
+ \header \i Character \i Meaning
+ \row \i \c A \i ASCII alphabetic character required. A-Z, a-z.
+ \row \i \c a \i ASCII alphabetic character permitted but not required.
+ \row \i \c N \i ASCII alphanumeric character required. A-Z, a-z, 0-9.
+ \row \i \c n \i ASCII alphanumeric character permitted but not required.
+ \row \i \c X \i Any character required.
+ \row \i \c x \i Any character permitted but not required.
+ \row \i \c 9 \i ASCII digit required. 0-9.
+ \row \i \c 0 \i ASCII digit permitted but not required.
+ \row \i \c D \i ASCII digit required. 1-9.
+ \row \i \c d \i ASCII digit permitted but not required (1-9).
+ \row \i \c # \i ASCII digit or plus/minus sign permitted but not required.
+ \row \i \c > \i All following alphabetic characters are uppercased.
+ \row \i \c < \i All following alphabetic characters are lowercased.
+ \row \i \c ! \i Switch off case conversion.
+ \row \i <tt>\\</tt> \i Use <tt>\\</tt> to escape the special
+ characters listed above to use them as
+ separators.
+ \endtable
+
+ The tqmask consists of a string of tqmask characters and separators,
+ optionally followed by a semi-colon and the character used for
+ blanks: the blank characters are always removed from the text
+ after editing. The default blank character is space.
+
+ Examples:
+ \table
+ \header \i Mask \i Notes
+ \row \i \c 000.000.000.000;_ \i IP address; blanks are \c{_}.
+ \row \i \c 0000-00-00 \i ISO Date; blanks are \c space
+ \row \i \c >AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;# \i License number;
+ blanks are \c - and all (alphabetic) characters are converted to
+ uppercase.
+ \endtable
+
+ To get range control (e.g. for an IP address) use masks together
+ with \link setValidator() validators\endlink.
+
+ \sa maxLength
+*/
+TQString TQLineEdit::inputMask() const
+{
+ return ( d->maskData ? d->inputMask + ';' + d->blank : TQString() );
+}
+
+void TQLineEdit::setInputMask( const TQString &inputMask )
+{
+ d->parseInputMask( inputMask );
+ if ( d->maskData )
+ d->moveCursor( d->nextMaskBlank( 0 ) );
+}
+
+/*!
+ Selects all the text (i.e. highlights it) and moves the cursor to
+ the end. This is useful when a default value has been inserted
+ because if the user types before clicking on the widget, the
+ selected text will be deleted.
+
+ \sa setSelection() deselect()
+*/
+
+void TQLineEdit::selectAll()
+{
+ d->selstart = d->selend = d->cursor = 0;
+ d->moveCursor( d->text.length(), TRUE );
+}
+
+/*!
+ Deselects any selected text.
+
+ \sa setSelection() selectAll()
+*/
+
+void TQLineEdit::deselect()
+{
+ d->deselect();
+ d->finishChange();
+}
+
+
+/*!
+ This slot is equivalent to setValidator(0).
+*/
+
+void TQLineEdit::clearValidator()
+{
+ setValidator( 0 );
+}
+
+/*!
+ Deletes any selected text, inserts \a newText, and validates the
+ result. If it is valid, it sets it as the new contents of the line
+ edit.
+*/
+void TQLineEdit::insert( const TQString &newText )
+{
+// q->resetInputContext(); //#### FIX ME IN QT
+ int priorState = d->undoState;
+ d->removeSelectedText();
+ d->insert( newText );
+ d->finishChange( priorState );
+}
+
+/*!
+ Clears the contents of the line edit.
+*/
+void TQLineEdit::clear()
+{
+ int priorState = d->undoState;
+ resetInputContext();
+ d->selstart = 0;
+ d->selend = d->text.length();
+ d->removeSelectedText();
+ d->separate();
+ d->finishChange( priorState );
+}
+
+/*!
+ Undoes the last operation if undo is \link
+ TQLineEdit::undoAvailable available\endlink. Deselects any current
+ selection, and updates the selection start to the current cursor
+ position.
+*/
+void TQLineEdit::undo()
+{
+ resetInputContext();
+ d->undo();
+ d->finishChange( -1, FALSE );
+}
+
+/*!
+ Redoes the last operation if redo is \link
+ TQLineEdit::redoAvailable available\endlink.
+*/
+void TQLineEdit::redo()
+{
+ resetInputContext();
+ d->redo();
+ d->finishChange();
+}
+
+
+/*!
+ \property TQLineEdit::readOnly
+ \brief whether the line edit is read only.
+
+ In read-only mode, the user can still copy the text to the
+ clipboard or drag-and-drop the text (if echoMode() is \c Normal),
+ but cannot edit it.
+
+ TQLineEdit does not show a cursor in read-only mode.
+
+ \sa setEnabled()
+*/
+
+bool TQLineEdit::isReadOnly() const
+{
+ return d->readOnly;
+}
+
+void TQLineEdit::setReadOnly( bool enable )
+{
+ d->readOnly = enable;
+#ifndef TQT_NO_CURSOR
+ setCursor( enable ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ update();
+}
+
+
+#ifndef TQT_NO_CLIPBOARD
+/*!
+ Copies the selected text to the clipboard and deletes it, if there
+ is any, and if echoMode() is \c Normal.
+
+ If the current validator disallows deleting the selected text,
+ cut() will copy without deleting.
+
+ \sa copy() paste() setValidator()
+*/
+
+void TQLineEdit::cut()
+{
+ if ( hasSelectedText() ) {
+ copy();
+ del();
+ }
+}
+
+
+/*!
+ Copies the selected text to the clipboard, if there is any, and if
+ echoMode() is \c Normal.
+
+ \sa cut() paste()
+*/
+
+void TQLineEdit::copy() const
+{
+ d->copy();
+}
+
+/*!
+ Inserts the clipboard's text at the cursor position, deleting any
+ selected text, providing the line edit is not \link
+ TQLineEdit::readOnly read-only\endlink.
+
+ If the end result would not be acceptable to the current
+ \link setValidator() validator\endlink, nothing happens.
+
+ \sa copy() cut()
+*/
+
+void TQLineEdit::paste()
+{
+ insert( TQApplication::tqclipboard()->text( TQClipboard::Clipboard ) );
+}
+
+void TQLineEditPrivate::copy( bool clipboard ) const
+{
+ TQString t = q->selectedText();
+ if ( !t.isEmpty() && echoMode == TQLineEdit::Normal ) {
+ q->disconnect( TQApplication::tqclipboard(), TQT_SIGNAL(selectionChanged()), q, 0);
+ TQApplication::tqclipboard()->setText( t, clipboard ? TQClipboard::Clipboard : TQClipboard::Selection );
+ q->connect( TQApplication::tqclipboard(), TQT_SIGNAL(selectionChanged()),
+ q, TQT_SLOT(clipboardChanged()) );
+ }
+}
+
+#endif // !TQT_NO_CLIPBOARD
+
+/*!\reimp
+*/
+
+void TQLineEdit::resizeEvent( TQResizeEvent *e )
+{
+ TQFrame::resizeEvent( e );
+}
+
+/*! \reimp
+*/
+bool TQLineEdit::event( TQEvent * e )
+{
+ if ( e->type() == TQEvent::AccelOverride && !d->readOnly ) {
+ TQKeyEvent* ke = (TQKeyEvent*) e;
+ if ( ke->state() == Qt::NoButton || ke->state() == ShiftButton
+ || ke->state() == TQt::Keypad ) {
+ if ( ke->key() < Key_Escape ) {
+ ke->accept();
+ } else {
+ switch ( ke->key() ) {
+ case Qt::Key_Delete:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_Backspace:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ } else if ( ke->state() & ControlButton ) {
+ switch ( ke->key() ) {
+// Those are too frequently used for application functionality
+/* case Qt::Key_A:
+ case Qt::Key_B:
+ case Qt::Key_D:
+ case Qt::Key_E:
+ case Qt::Key_F:
+ case Qt::Key_H:
+ case Qt::Key_K:
+*/
+ case Qt::Key_C:
+ case Qt::Key_V:
+ case Qt::Key_X:
+ case Qt::Key_Y:
+ case Qt::Key_Z:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+#if defined (TQ_WS_WIN)
+ case Qt::Key_Insert:
+ case Qt::Key_Delete:
+#endif
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ } else if ( e->type() == TQEvent::Timer ) {
+ // should be timerEvent, is here for binary compatibility
+ int timerId = ((TQTimerEvent*)e)->timerId();
+ if ( timerId == d->cursorTimer ) {
+ if(!hasSelectedText() || tqstyle().tqstyleHint( TQStyle::SH_BlinkCursorWhenTextSelected ))
+ d->setCursorVisible( !d->cursorVisible );
+#ifndef TQT_NO_DRAGANDDROP
+ } else if ( timerId == d->dndTimer ) {
+ if( !d->drag() )
+ return TRUE;
+#endif
+ } else if ( timerId == d->tripleClickTimer ) {
+ killTimer( d->tripleClickTimer );
+ d->tripleClickTimer = 0;
+ }
+ }
+ return TQWidget::event( e );
+}
+
+/*! \reimp
+*/
+void TQLineEdit::mousePressEvent( TQMouseEvent* e )
+{
+ if ( e->button() == Qt::RightButton )
+ return;
+ if ( d->tripleClickTimer && ( e->pos() - d->tripleClick ).manhattanLength() <
+ TQApplication::startDragDistance() ) {
+ selectAll();
+ return;
+ }
+ bool mark = e->state() & ShiftButton;
+ int cursor = d->xToPos( e->pos().x() );
+#ifndef TQT_NO_DRAGANDDROP
+ if ( !mark && d->dragEnabled && d->echoMode == Normal &&
+ e->button() == Qt::LeftButton && d->inSelection( e->pos().x() ) ) {
+ d->cursor = cursor;
+ d->updateMicroFocusHint();
+ update();
+ d->dndPos = e->pos();
+ if ( !d->dndTimer )
+ d->dndTimer = startTimer( TQApplication::startDragTime() );
+ } else
+#endif
+ {
+ d->moveCursor( cursor, mark );
+ }
+}
+
+/*! \reimp
+*/
+void TQLineEdit::mouseMoveEvent( TQMouseEvent * e )
+{
+
+#ifndef TQT_NO_CURSOR
+ if ( ( e->state() & Qt::MouseButtonMask ) == 0 ) {
+ if ( !d->readOnly && d->dragEnabled
+#ifndef TQT_NO_WHATSTHIS
+ && !TQWhatsThis::inWhatsThisMode()
+#endif
+ )
+ setCursor( ( d->inSelection( e->pos().x() ) ? Qt::ArrowCursor : Qt::IBeamCursor ) );
+ }
+#endif
+
+ if ( e->state() & Qt::LeftButton ) {
+#ifndef TQT_NO_DRAGANDDROP
+ if ( d->dndTimer ) {
+ if ( ( d->dndPos - e->pos() ).manhattanLength() > TQApplication::startDragDistance() )
+ d->drag();
+ } else
+#endif
+ {
+ d->moveCursor( d->xToPos( e->pos().x() ), TRUE );
+ }
+ }
+}
+
+/*! \reimp
+*/
+void TQLineEdit::mouseReleaseEvent( TQMouseEvent* e )
+{
+#ifndef TQT_NO_DRAGANDDROP
+ if ( e->button() == Qt::LeftButton ) {
+ if ( d->dndTimer ) {
+ killTimer( d->dndTimer );
+ d->dndTimer = 0;
+ deselect();
+ return;
+ }
+ }
+#endif
+#ifndef TQT_NO_CLIPBOARD
+ if (TQApplication::tqclipboard()->supportsSelection() ) {
+ if ( e->button() == Qt::LeftButton ) {
+ d->copy( FALSE );
+ } else if ( !d->readOnly && e->button() == Qt::MidButton ) {
+ d->deselect();
+ insert( TQApplication::tqclipboard()->text( TQClipboard::Selection ) );
+ }
+ }
+#endif
+}
+
+/*! \reimp
+*/
+void TQLineEdit::mouseDoubleClickEvent( TQMouseEvent* e )
+{
+ if ( e->button() == Qt::LeftButton ) {
+ deselect();
+ d->cursor = d->xToPos( e->pos().x() );
+ d->cursor = d->textLayout.previousCursorPosition( d->cursor, TQTextLayout::SkipWords );
+ // ## text tqlayout should support end of words.
+ int end = d->textLayout.nextCursorPosition( d->cursor, TQTextLayout::SkipWords );
+ while ( end > d->cursor && d->text[end-1].isSpace() )
+ --end;
+ d->moveCursor( end, TRUE );
+ d->tripleClickTimer = startTimer( TQApplication::doubleClickInterval() );
+ d->tripleClick = e->pos();
+ }
+}
+
+/*!
+ \fn void TQLineEdit::returnPressed()
+
+ This signal is emitted when the Return or Enter key is pressed.
+ Note that if there is a validator() or inputMask() set on the line
+ edit, the returnPressed() signal will only be emitted if the input
+ follows the inputMask() and the validator() returns \c Acceptable.
+*/
+
+/*!
+ Converts key press event \a e into a line edit action.
+
+ If Return or Enter is pressed and the current text is valid (or
+ can be \link TQValidator::fixup() made valid\endlink by the
+ validator), the signal returnPressed() is emitted.
+
+ The default key bindings are listed in the \link #desc detailed
+ description.\endlink
+*/
+
+void TQLineEdit::keyPressEvent( TQKeyEvent * e )
+{
+ d->setCursorVisible( TRUE );
+ if ( e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return ) {
+ const TQValidator * v = d->validator;
+ if ( hasAcceptableInput() ) {
+ emit returnPressed();
+ }
+#ifndef TQT_NO_VALIDATOR
+ else if ( v && v->validate( d->text, d->cursor ) != TQValidator::Acceptable ) {
+ TQString vstr = d->text;
+ v->fixup( vstr );
+ if ( vstr != d->text ) {
+ setText( vstr );
+ if ( hasAcceptableInput() )
+ emit returnPressed();
+ }
+ }
+#endif
+ e->ignore();
+ return;
+ }
+ if ( !d->readOnly ) {
+ TQString t = e->text();
+ if ( !t.isEmpty() && (!e->ascii() || e->ascii()>=32) &&
+ e->key() != Qt::Key_Delete &&
+ e->key() != Qt::Key_Backspace ) {
+#ifdef TQ_WS_X11
+ extern bool qt_hebrew_keyboard_hack;
+ if ( qt_hebrew_keyboard_hack ) {
+ // the X11 keyboard tqlayout is broken and does not reverse
+ // braces correctly. This is a hack to get halfway correct
+ // behaviour
+ if ( d->isRightToLeft() ) {
+ TQChar *c = (TQChar *)t.tqunicode();
+ int l = t.length();
+ while( l-- ) {
+ if ( c->mirrored() )
+ *c = c->mirroredChar();
+ c++;
+ }
+ }
+ }
+#endif
+ insert( t );
+ return;
+ }
+ }
+ bool unknown = FALSE;
+ if ( e->state() & ControlButton ) {
+ switch ( e->key() ) {
+ case Qt::Key_A:
+#if defined(TQ_WS_X11)
+ home( e->state() & ShiftButton );
+#else
+ selectAll();
+#endif
+ break;
+ case Qt::Key_B:
+ cursorForward( e->state() & ShiftButton, -1 );
+ break;
+#ifndef TQT_NO_CLIPBOARD
+ case Qt::Key_C:
+ copy();
+ break;
+#endif
+ case Qt::Key_D:
+ if ( !d->readOnly ) {
+ del();
+ }
+ break;
+ case Qt::Key_E:
+ end( e->state() & ShiftButton );
+ break;
+ case Qt::Key_F:
+ cursorForward( e->state() & ShiftButton, 1 );
+ break;
+ case Qt::Key_H:
+ if ( !d->readOnly ) {
+ backspace();
+ }
+ break;
+ case Qt::Key_K:
+ if ( !d->readOnly ) {
+ int priorState = d->undoState;
+ d->deselect();
+ while ( d->cursor < (int) d->text.length() )
+ d->del();
+ d->finishChange( priorState );
+ }
+ break;
+#if defined(TQ_WS_X11)
+ case Qt::Key_U:
+ if ( !d->readOnly )
+ clear();
+ break;
+#endif
+#ifndef TQT_NO_CLIPBOARD
+ case Qt::Key_V:
+ if ( !d->readOnly )
+ paste();
+ break;
+ case Qt::Key_X:
+ if ( !d->readOnly && d->hasSelectedText() && echoMode() == Normal ) {
+ copy();
+ del();
+ }
+ break;
+#if defined (TQ_WS_WIN)
+ case Qt::Key_Insert:
+ copy();
+ break;
+#endif
+#endif
+ case Qt::Key_Delete:
+ if ( !d->readOnly ) {
+ cursorWordForward( TRUE );
+ del();
+ }
+ break;
+ case Qt::Key_Backspace:
+ if ( !d->readOnly ) {
+ cursorWordBackward( TRUE );
+ del();
+ }
+ break;
+ case Qt::Key_Right:
+ case Qt::Key_Left:
+ if ( d->isRightToLeft() == (e->key() == Qt::Key_Right) ) {
+ if ( echoMode() == Normal )
+ cursorWordBackward( e->state() & ShiftButton );
+ else
+ home( e->state() & ShiftButton );
+ } else {
+ if ( echoMode() == Normal )
+ cursorWordForward( e->state() & ShiftButton );
+ else
+ end( e->state() & ShiftButton );
+ }
+ break;
+ case Qt::Key_Z:
+ if ( !d->readOnly ) {
+ if(e->state() & ShiftButton)
+ redo();
+ else
+ undo();
+ }
+ break;
+ case Qt::Key_Y:
+ if ( !d->readOnly )
+ redo();
+ break;
+ default:
+ unknown = TRUE;
+ }
+ } else { // ### check for *no* modifier
+ switch ( e->key() ) {
+ case Qt::Key_Shift:
+ // ### TODO
+ break;
+ case Qt::Key_Left:
+ case Qt::Key_Right: {
+ int step = (d->isRightToLeft() == (e->key() == Qt::Key_Right)) ? -1 : 1;
+ cursorForward( e->state() & ShiftButton, step );
+ }
+ break;
+ case Qt::Key_Backspace:
+ if ( !d->readOnly ) {
+ backspace();
+ }
+ break;
+ case Qt::Key_Home:
+#ifdef TQ_WS_MACX
+ case Qt::Key_Up:
+#endif
+ home( e->state() & ShiftButton );
+ break;
+ case Qt::Key_End:
+#ifdef TQ_WS_MACX
+ case Qt::Key_Down:
+#endif
+ end( e->state() & ShiftButton );
+ break;
+ case Qt::Key_Delete:
+ if ( !d->readOnly ) {
+#if defined (TQ_WS_WIN)
+ if ( e->state() & ShiftButton ) {
+ cut();
+ break;
+ }
+#endif
+ del();
+ }
+ break;
+#if defined (TQ_WS_WIN)
+ case Qt::Key_Insert:
+ if ( !d->readOnly && e->state() & ShiftButton )
+ paste();
+ else
+ unknown = TRUE;
+ break;
+#endif
+ case Qt::Key_F14: // Undo key on Sun keyboards
+ if ( !d->readOnly )
+ undo();
+ break;
+#ifndef TQT_NO_CLIPBOARD
+ case Qt::Key_F16: // Copy key on Sun keyboards
+ copy();
+ break;
+ case Qt::Key_F18: // Paste key on Sun keyboards
+ if ( !d->readOnly )
+ paste();
+ break;
+ case Qt::Key_F20: // Cut key on Sun keyboards
+ if ( !d->readOnly && hasSelectedText() && echoMode() == Normal ) {
+ copy();
+ del();
+ }
+ break;
+#endif
+ default:
+ unknown = TRUE;
+ }
+ }
+ if ( e->key() == Qt::Key_Direction_L || e->key() == Qt::Key_Direction_R ) {
+ d->direction = (e->key() == Qt::Key_Direction_L) ? TQChar::DirL : TQChar::DirR;
+ d->updateTextLayout();
+ update();
+ }
+
+ if ( unknown )
+ e->ignore();
+}
+
+/*! \reimp
+ */
+void TQLineEdit::imStartEvent( TQIMEvent *e )
+{
+ if ( d->readOnly ) {
+ e->ignore();
+ return;
+ }
+ d->removeSelectedText();
+ d->updateMicroFocusHint();
+ d->imstart = d->imend = d->imselstart = d->imselend = d->cursor;
+}
+
+/*! \reimp
+ */
+void TQLineEdit::imComposeEvent( TQIMEvent *e )
+{
+ if ( d->readOnly ) {
+ e->ignore();
+ return;
+ }
+ d->text.tqreplace( d->imstart, d->imend - d->imstart, e->text() );
+ d->imend = d->imstart + e->text().length();
+ d->imselstart = d->imstart + e->cursorPos();
+ d->imselend = d->imselstart + e->selectionLength();
+ d->cursor = d->imstart + e->cursorPos();
+ d->updateTextLayout();
+ d->updateMicroFocusHint();
+ update();
+}
+
+/*! \reimp
+ */
+void TQLineEdit::imEndEvent( TQIMEvent *e )
+{
+ if ( d->readOnly) {
+ e->ignore();
+ return;
+ }
+ d->text.remove( d->imstart, d->imend - d->imstart );
+ d->cursor = d->imselstart = d->imselend = d->imend = d->imstart;
+ d->textDirty = TRUE;
+ insert( e->text() );
+}
+
+/*!\reimp
+*/
+
+void TQLineEdit::focusInEvent( TQFocusEvent* tqfe )
+{
+#ifdef USE_QT4
+ if ( tqfe->reason() == TQFocusEvent::Tab ||
+ tqfe->reason() == TQFocusEvent::Backtab ||
+ tqfe->reason() == TQFocusEvent::Shortcut )
+#else // USE_QT4
+ if ( tqfereason() == TQFocusEvent::Tab ||
+ TQFocusEvent::reason() == TQFocusEvent::Backtab ||
+ TQFocusEvent::reason() == TQFocusEvent::Shortcut )
+#endif // USE_QT4
+ d->maskData ? d->moveCursor( d->nextMaskBlank( 0 ) ) : selectAll();
+ if ( !d->cursorTimer ) {
+ int cft = TQApplication::cursorFlashTime();
+ d->cursorTimer = cft ? startTimer( cft/2 ) : -1;
+ }
+ if( !hasSelectedText() || tqstyle().tqstyleHint( TQStyle::SH_BlinkCursorWhenTextSelected ) )
+ d->setCursorVisible( TRUE );
+ d->updateMicroFocusHint();
+}
+
+/*!\reimp
+*/
+
+void TQLineEdit::focusOutEvent( TQFocusEvent* tqfe )
+{
+#ifdef USE_QT4
+ if ( tqfe->reason() != TQFocusEvent::ActiveWindow &&
+ tqfe->reason() != TQFocusEvent::Popup )
+#else // USE_QT4
+ if ( TQFocusEvent::reason() != TQFocusEvent::ActiveWindow &&
+ TQFocusEvent::reason() != TQFocusEvent::Popup )
+#endif // USE_QT4
+ deselect();
+ d->setCursorVisible( FALSE );
+ if ( d->cursorTimer > 0 )
+ killTimer( d->cursorTimer );
+ d->cursorTimer = 0;
+#ifdef USE_QT4
+ if (tqfe->reason() != TQFocusEvent::Popup)
+#else // USE_QT4
+ if (TQFocusEvent::reason() != TQFocusEvent::Popup)
+#endif // USE_QT4
+ emit lostFocus();
+}
+
+/*!\reimp
+*/
+void TQLineEdit::drawContents( TQPainter *p )
+{
+ const TQColorGroup& cg = tqcolorGroup();
+ TQRect cr = contentsRect();
+ TQFontMetrics fm = fontMetrics();
+ TQRect lineRect( cr.x() + innerMargin, cr.y() + (cr.height() - fm.height() + 1) / 2,
+ cr.width() - 2*innerMargin, fm.height() );
+ TQBrush bg = TQBrush( paletteBackgroundColor() );
+ if ( paletteBackgroundPixmap() )
+ bg = TQBrush( cg.background(), *paletteBackgroundPixmap() );
+ else if ( !isEnabled() )
+ bg = cg.brush( TQColorGroup::Background );
+ TQPoint brushOrigin = p->brushOrigin();
+ p->save();
+ p->setClipRegion( TQRegion(cr) - lineRect );
+ p->setBrushOrigin(brushOrigin - backgroundOffset());
+ p->fillRect( cr, bg );
+ p->restore();
+ TQSharedDoubleBuffer buffer( p, lineRect.x(), lineRect.y(),
+ lineRect.width(), lineRect.height(),
+ hasFocus() ? TQSharedDoubleBuffer::Force : 0 );
+ p = buffer.painter();
+ brushOrigin = p->brushOrigin();
+ p->setBrushOrigin(brushOrigin - backgroundOffset());
+ p->fillRect( lineRect, bg );
+ p->setBrushOrigin(brushOrigin);
+
+ // locate cursor position
+ int cix = 0;
+ TQTextItem ci = d->textLayout.tqfindItem( d->cursor );
+ if ( ci.isValid() ) {
+ if ( d->cursor != (int)d->text.length() && d->cursor == ci.from() + ci.length()
+ && ci.isRightToLeft() != d->isRightToLeft() )
+ ci = d->textLayout.tqfindItem( d->cursor + 1 );
+ cix = ci.x() + ci.cursorToX( d->cursor - ci.from() );
+ }
+
+ // horizontal scrolling
+ int minLB = TQMAX( 0, -fm.minLeftBearing() );
+ int minRB = TQMAX( 0, -fm.minRightBearing() );
+ int widthUsed = d->textLayout.widthUsed() + 1 + minRB;
+ if ( (minLB + widthUsed) <= lineRect.width() ) {
+ switch ( d->visualAlignment() ) {
+ case TQt::AlignRight:
+ d->hscroll = widthUsed - lineRect.width() + 1;
+ break;
+ case TQt::AlignHCenter:
+ d->hscroll = ( widthUsed - lineRect.width() ) / 2;
+ break;
+ default:
+ d->hscroll = 0;
+ break;
+ }
+ d->hscroll -= minLB;
+ } else if ( cix - d->hscroll >= lineRect.width() ) {
+ d->hscroll = cix - lineRect.width() + 1;
+ } else if ( cix - d->hscroll < 0 ) {
+ d->hscroll = cix;
+ } else if ( widthUsed - d->hscroll < lineRect.width() ) {
+ d->hscroll = widthUsed - lineRect.width() + 1;
+ } else if (d->hscroll < 0) {
+ d->hscroll = 0;
+ }
+ // the y offset is there to keep the baseline constant in case we have script changes in the text.
+ TQPoint topLeft = lineRect.topLeft() - TQPoint(d->hscroll, d->ascent-fm.ascent());
+
+ // draw text, selections and cursors
+ p->setPen( cg.text() );
+ bool supressCursor = d->readOnly, hasRightToLeft = d->isRightToLeft();
+ int textflags = 0;
+ if ( font().underline() )
+ textflags |= TQt::Underline;
+ if ( font().strikeOut() )
+ textflags |= TQt::StrikeOut;
+ if ( font().overline() )
+ textflags |= TQt::Overline;
+
+ for ( int i = 0; i < d->textLayout.numItems(); i++ ) {
+ TQTextItem ti = d->textLayout.itemAt( i );
+ hasRightToLeft |= ti.isRightToLeft();
+ int tix = topLeft.x() + ti.x();
+ int first = ti.from();
+ int last = ti.from() + ti.length() - 1;
+
+ // text and selection
+ if ( d->selstart < d->selend && (last >= d->selstart && first < d->selend ) ) {
+ TQRect highlight = TQRect( TQPoint( tix + ti.cursorToX( TQMAX( d->selstart - first, 0 ) ),
+ lineRect.top() ),
+ TQPoint( tix + ti.cursorToX( TQMIN( d->selend - first, last - first + 1 ) ) - 1,
+ lineRect.bottom() ) ).normalize();
+ p->save();
+ p->setClipRegion( TQRegion( lineRect ) - highlight, TQPainter::CoordPainter );
+ p->tqdrawTextItem( topLeft, ti, textflags );
+ p->setClipRect( lineRect & highlight, TQPainter::CoordPainter );
+ p->fillRect( highlight, cg.highlight() );
+ p->setPen( cg.highlightedText() );
+ p->tqdrawTextItem( topLeft, ti, textflags );
+ p->restore();
+ } else {
+ p->tqdrawTextItem( topLeft, ti, textflags );
+ }
+
+ // input method edit area
+ if ( d->imstart < d->imend && (last >= d->imstart && first < d->imend ) ) {
+ TQRect highlight = TQRect( TQPoint( tix + ti.cursorToX( TQMAX( d->imstart - first, 0 ) ), lineRect.top() ),
+ TQPoint( tix + ti.cursorToX( TQMIN( d->imend - first, last - first + 1 ) )-1, lineRect.bottom() ) ).normalize();
+ p->save();
+ p->setClipRect( lineRect & highlight, TQPainter::CoordPainter );
+
+ int h1, s1, v1, h2, s2, v2;
+ TQT_TQCOLOR_OBJECT(cg.color( TQColorGroup::Base )).hsv( &h1, &s1, &v1 );
+ TQT_TQCOLOR_OBJECT(cg.color( TQColorGroup::Background )).hsv( &h2, &s2, &v2 );
+ TQColor imCol;
+ imCol.setHsv( h1, s1, ( v1 + v2 ) / 2 );
+ p->fillRect( highlight, imCol );
+ p->tqdrawTextItem( topLeft, ti, textflags );
+ p->restore();
+ }
+
+ // input method selection
+ if ( d->imselstart < d->imselend && (last >= d->imselstart && first < d->imselend ) ) {
+ TQRect highlight = TQRect( TQPoint( tix + ti.cursorToX( TQMAX( d->imselstart - first, 0 ) ), lineRect.top() ),
+ TQPoint( tix + ti.cursorToX( TQMIN( d->imselend - first, last - first + 1 ) )-1, lineRect.bottom() ) ).normalize();
+ p->save();
+ p->setClipRect( lineRect & highlight, TQPainter::CoordPainter );
+ p->fillRect( highlight, cg.text() );
+ p->setPen( paletteBackgroundColor() );
+ p->tqdrawTextItem( topLeft, ti, textflags );
+ p->restore();
+ supressCursor = TRUE;
+ }
+
+ // overwrite cursor
+ if ( d->cursorVisible && d->maskData &&
+ d->selend <= d->selstart && (last >= d->cursor && first <= d->cursor ) ) {
+ TQRect highlight = TQRect( TQPoint( tix + ti.cursorToX( TQMAX( d->cursor - first, 0 ) ), lineRect.top() ),
+ TQPoint( tix + ti.cursorToX( TQMIN( d->cursor + 1 - first, last - first + 1 ) )-1, lineRect.bottom() ) ).normalize();
+ p->save();
+ p->setClipRect( lineRect & highlight, TQPainter::CoordPainter );
+ p->fillRect( highlight, cg.text() );
+ p->setPen( paletteBackgroundColor() );
+ p->tqdrawTextItem( topLeft, ti, textflags );
+ p->restore();
+ supressCursor = TRUE;
+ }
+ }
+
+ // draw cursor
+ if ( d->cursorVisible && !supressCursor ) {
+ TQPoint from( topLeft.x() + cix, lineRect.top() );
+ TQPoint to = from + TQPoint( 0, lineRect.height() );
+ p->drawLine( from, to );
+ if ( hasRightToLeft ) {
+ bool rtl = ci.isValid() ? ci.isRightToLeft() : TRUE;
+ to = from + TQPoint( (rtl ? -2 : 2), 2 );
+ p->drawLine( from, to );
+ from.ry() += 4;
+ p->drawLine( from, to );
+ }
+ }
+ buffer.end();
+}
+
+
+#ifndef TQT_NO_DRAGANDDROP
+/*!\reimp
+*/
+void TQLineEdit::dragMoveEvent( TQDragMoveEvent *e )
+{
+ if ( !d->readOnly && TQTextDrag::canDecode(e) ) {
+ e->acceptAction();
+ d->cursor = d->xToPos( e->pos().x() );
+ d->cursorVisible = TRUE;
+ update();
+ }
+}
+
+/*!\reimp */
+void TQLineEdit::dragEnterEvent( TQDragEnterEvent * e )
+{
+ TQLineEdit::dragMoveEvent( e );
+}
+
+/*!\reimp */
+void TQLineEdit::dragLeaveEvent( TQDragLeaveEvent *)
+{
+ if ( d->cursorVisible ) {
+ d->cursorVisible = FALSE;
+ update();
+ }
+}
+
+/*!\reimp */
+void TQLineEdit::dropEvent( TQDropEvent* e )
+{
+ TQString str;
+ // try text/plain
+ TQCString plain = "plain";
+ bool decoded = TQTextDrag::decode(e, str, plain);
+ // otherwise we'll accept any kind of text (like text/uri-list)
+ if (! decoded)
+ decoded = TQTextDrag::decode(e, str);
+
+ if ( decoded && !d->readOnly ) {
+ if ( e->source() == this && e->action() == TQDropEvent::Copy )
+ deselect();
+ d->cursor =d->xToPos( e->pos().x() );
+ int selStart = d->cursor;
+ int oldSelStart = d->selstart;
+ int oldSelEnd = d->selend;
+ d->cursorVisible = FALSE;
+ e->acceptAction();
+ insert( str );
+ if ( e->source() == this ) {
+ if ( e->action() == TQDropEvent::Move ) {
+ if ( selStart > oldSelStart && selStart <= oldSelEnd )
+ setSelection( oldSelStart, str.length() );
+ else if ( selStart > oldSelEnd )
+ setSelection( selStart - str.length(), str.length() );
+ else
+ setSelection( selStart, str.length() );
+ } else {
+ setSelection( selStart, str.length() );
+ }
+ }
+ } else {
+ e->ignore();
+ update();
+ }
+}
+
+bool TQLineEditPrivate::drag()
+{
+ q->killTimer( dndTimer );
+ dndTimer = 0;
+ TQTextDrag *tdo = new TQTextDrag( q->selectedText(), q );
+
+ TQGuardedPtr<TQLineEdit> gptr = q;
+ bool r = tdo->drag();
+ if ( !gptr )
+ return FALSE;
+
+ // ### fix the check TQDragObject::target() != q in TQt4 (should not be needed)
+ if ( r && !readOnly && TQDragObject::target() != q ) {
+ int priorState = undoState;
+ removeSelectedText();
+ finishChange( priorState );
+ }
+#ifndef TQT_NO_CURSOR
+ q->setCursor( readOnly ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ return TRUE;
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+enum { IdUndo, IdRedo, IdSep1, IdCut, IdCopy, IdPaste, IdClear, IdSep2, IdSelectAll };
+
+/*!\reimp
+*/
+void TQLineEdit::contextMenuEvent( TQContextMenuEvent * e )
+{
+#ifndef TQT_NO_POPUPMENU
+ d->separate();
+ TQPopupMenu *menu = createPopupMenu();
+ if (!menu)
+ return;
+ TQGuardedPtr<TQPopupMenu> popup = menu;
+ TQGuardedPtr<TQLineEdit> that = this;
+ TQPoint pos = e->reason() == TQContextMenuEvent::Mouse ? e->globalPos() :
+ mapToGlobal( TQPoint(e->pos().x(), 0) ) + TQPoint( width() / 2, height() / 2 );
+ int r = popup->exec( pos );
+ delete (TQPopupMenu*)popup;
+ if ( that && d->menuId ) {
+ switch ( d->menuId - r ) {
+ case IdClear: clear(); break;
+ case IdSelectAll: selectAll(); break;
+ case IdUndo: undo(); break;
+ case IdRedo: redo(); break;
+#ifndef TQT_NO_CLIPBOARD
+ case IdCut: cut(); break;
+ case IdCopy: copy(); break;
+ case IdPaste: paste(); break;
+#endif
+ default:
+ ; // nothing selected or lineedit destroyed. Be careful.
+ }
+ }
+#endif //TQT_NO_POPUPMENU
+}
+
+/*!
+ This function is called to create the popup menu which is shown
+ when the user clicks on the line edit with the right mouse button.
+ If you want to create a custom popup menu, reimplement this
+ function and return the popup menu you create. The popup menu's
+ ownership is transferred to the caller.
+*/
+
+TQPopupMenu *TQLineEdit::createPopupMenu()
+{
+#ifndef TQT_NO_POPUPMENU
+ TQPopupMenu *popup = new TQPopupMenu( this, "qt_edit_menu" );
+ int id = d->menuId = popup->insertItem( tr( "&Undo" ) + ACCEL_KEY( Z ) );
+ popup->insertItem( tr( "&Redo" ) + ACCEL_KEY( Y ) );
+ popup->insertSeparator();
+ popup->insertItem( tr( "Cu&t" ) + ACCEL_KEY( X ) );
+ popup->insertItem( tr( "&Copy" ) + ACCEL_KEY( C ) );
+ popup->insertItem( tr( "&Paste" ) + ACCEL_KEY( V ) );
+ popup->insertItem( tr( "Clear" ) );
+ popup->insertSeparator();
+ popup->insertItem( tr( "Select All" )
+#ifndef TQ_WS_X11
+ + ACCEL_KEY( A )
+#endif
+ );
+ popup->setItemEnabled( id - IdUndo, d->isUndoAvailable() );
+ popup->setItemEnabled( id - IdRedo, d->isRedoAvailable() );
+#ifndef TQT_NO_CLIPBOARD
+ popup->setItemEnabled( id - IdCut, !d->readOnly && d->hasSelectedText() );
+ popup->setItemEnabled( id - IdCopy, d->hasSelectedText() );
+ popup->setItemEnabled( id - IdPaste, !d->readOnly && !TQApplication::tqclipboard()->text().isEmpty() );
+#else
+ popup->setItemVisible( id - IdCut, FALSE );
+ popup->setItemVisible( id - IdCopy, FALSE );
+ popup->setItemVisible( id - IdPaste, FALSE );
+#endif
+ popup->setItemEnabled( id - IdClear, !d->readOnly && !d->text.isEmpty() );
+ popup->setItemEnabled( id - IdSelectAll, !d->text.isEmpty() && !d->allSelected() );
+ return popup;
+#else
+ return 0;
+#endif
+}
+
+/*! \reimp */
+void TQLineEdit::windowActivationChange( bool b )
+{
+ //### remove me with WHighlightSelection attribute
+ if ( tqpalette().active() != tqpalette().inactive() )
+ update();
+ TQWidget::windowActivationChange( b );
+}
+
+/*! \reimp */
+
+void TQLineEdit::setPalette( const TQPalette & p )
+{
+ //### remove me with WHighlightSelection attribute
+ TQWidget::setPalette( p );
+ update();
+}
+
+/*!
+ \obsolete
+ \fn void TQLineEdit::repaintArea( int from, int to )
+ Repaints all characters from \a from to \a to. If cursorPos is
+ between from and to, ensures that cursorPos is visible.
+*/
+
+/*! \reimp
+ */
+void TQLineEdit::setFont( const TQFont & f )
+{
+ TQWidget::setFont( f );
+ d->updateTextLayout();
+}
+
+/*! \obsolete
+*/
+int TQLineEdit::characterAt( int xpos, TQChar *chr ) const
+{
+ int pos = d->xToPos( xpos + contentsRect().x() - d->hscroll + innerMargin );
+ if ( chr && pos < (int) d->text.length() )
+ *chr = d->text.at( pos );
+ return pos;
+}
+
+/*!
+ \internal
+
+ Sets the password character to \a c.
+
+ \sa passwordChar()
+*/
+
+void TQLineEdit::setPasswordChar( TQChar c )
+{
+ d->passwordChar = c;
+}
+
+/*!
+ \internal
+
+ Returns the password character.
+
+ \sa setPasswordChar()
+*/
+TQChar TQLineEdit::passwordChar() const
+{
+ return ( d->passwordChar.isNull() ? TQChar( tqstyle().tqstyleHint( TQStyle::SH_LineEdit_PasswordCharacter, this ) ) : d->passwordChar );
+}
+
+void TQLineEdit::clipboardChanged()
+{
+}
+
+void TQLineEditPrivate::init( const TQString& txt )
+{
+#ifndef TQT_NO_CURSOR
+ q->setCursor( readOnly ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ q->setFocusPolicy( Qt::StrongFocus );
+ q->setInputMethodEnabled( TRUE );
+ // Specifies that this widget can use more, but is able to survive on
+ // less, horizontal space; and is fixed vertically.
+ q->tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
+ q->setBackgroundMode( PaletteBase );
+ q->setKeyCompression( TRUE );
+ q->setMouseTracking( TRUE );
+ q->setAcceptDrops( TRUE );
+ q->setFrame( TRUE );
+ text = txt;
+ updateTextLayout();
+ cursor = text.length();
+}
+
+void TQLineEditPrivate::updateTextLayout()
+{
+ // tqreplace all non-printable characters with spaces (to avoid
+ // drawing boxes when using fonts that don't have glyphs for such
+ // characters)
+ const TQString &displayText = q->displayText();
+ TQString str(displayText.tqunicode(), displayText.length());
+ TQChar* uc = (TQChar*)str.tqunicode();
+ for (int i = 0; i < (int)str.length(); ++i) {
+ if (! uc[i].isPrint())
+ uc[i] = TQChar(0x0020);
+ }
+ textLayout.setText( str, q->font() );
+ textLayout.setDirection((TQChar::Direction)direction);
+ textLayout.beginLayout(TQTextLayout::SingleLine);
+ textLayout.beginLine( INT_MAX );
+ while ( !textLayout.atEnd() )
+ textLayout.addCurrentItem();
+ ascent = 0;
+ textLayout.endLine(0, 0, TQt::AlignLeft|TQt::SingleLine, &ascent);
+}
+
+int TQLineEditPrivate::xToPos( int x, TQTextItem::CursorPosition betweenOrOn ) const
+{
+ x-= q->contentsRect().x() - hscroll + innerMargin;
+ for ( int i = 0; i < textLayout.numItems(); ++i ) {
+ TQTextItem ti = textLayout.itemAt( i );
+ TQRect tir = ti.tqrect();
+ if ( x >= tir.left() && x <= tir.right() )
+ return ti.xToCursor( x - tir.x(), betweenOrOn ) + ti.from();
+ }
+ return x < 0 ? 0 : text.length();
+}
+
+
+TQRect TQLineEditPrivate::cursorRect() const
+{
+ TQRect cr = q->contentsRect();
+ int cix = cr.x() - hscroll + innerMargin;
+ TQTextItem ci = textLayout.tqfindItem( cursor );
+ if ( ci.isValid() ) {
+ if ( cursor != (int)text.length() && cursor == ci.from() + ci.length()
+ && ci.isRightToLeft() != isRightToLeft() )
+ ci = textLayout.tqfindItem( cursor + 1 );
+ cix += ci.x() + ci.cursorToX( cursor - ci.from() );
+ }
+ int ch = q->fontMetrics().height();
+ return TQRect( cix-4, cr.y() + ( cr.height() - ch + 1) / 2, 8, ch + 1 );
+}
+
+void TQLineEditPrivate::updateMicroFocusHint()
+{
+ if ( q->hasFocus() ) {
+ TQRect r = cursorRect();
+ q->setMicroFocusHint( r.x(), r.y(), r.width(), r.height() );
+ }
+}
+
+void TQLineEditPrivate::moveCursor( int pos, bool mark )
+{
+ if ( pos != cursor )
+ separate();
+ if ( maskData && pos > cursor )
+ pos = nextMaskBlank( pos );
+ else if ( maskData && pos < cursor )
+ pos = prevMaskBlank( pos );
+ bool fullUpdate = mark || hasSelectedText();
+ if ( mark ) {
+ int anchor;
+ if ( selend > selstart && cursor == selstart )
+ anchor = selend;
+ else if ( selend > selstart && cursor == selend )
+ anchor = selstart;
+ else
+ anchor = cursor;
+ selstart = TQMIN( anchor, pos );
+ selend = TQMAX( anchor, pos );
+ } else {
+ deselect();
+ }
+ if ( fullUpdate ) {
+ cursor = pos;
+ q->update();
+ } else {
+ setCursorVisible( FALSE );
+ cursor = pos;
+ setCursorVisible( TRUE );
+ }
+ updateMicroFocusHint();
+ if ( mark && !q->tqstyle().tqstyleHint( TQStyle::SH_BlinkCursorWhenTextSelected ) )
+ setCursorVisible( FALSE );
+ if ( mark || selDirty ) {
+ selDirty = FALSE;
+ emit q->selectionChanged();
+ }
+}
+
+void TQLineEditPrivate::finishChange( int validateFromState, bool setModified )
+{
+ bool lineDirty = selDirty;
+ if ( textDirty ) {
+ // do validation
+ bool wasValidInput = validInput;
+ validInput = TRUE;
+#ifndef TQT_NO_VALIDATOR
+ if ( validator && validateFromState >= 0 ) {
+ TQString textCopy = text;
+ int cursorCopy = cursor;
+ validInput = ( validator->validate( textCopy, cursorCopy ) != TQValidator::Invalid );
+ if ( validInput ) {
+ if ( text != textCopy ) {
+ q->setText( textCopy );
+ cursor = cursorCopy;
+ return;
+ }
+ cursor = cursorCopy;
+ }
+ }
+#endif
+ if ( validateFromState >= 0 && wasValidInput && !validInput ) {
+ undo( validateFromState );
+ history.resize( undoState );
+ validInput = TRUE;
+ textDirty = setModified = FALSE;
+ }
+ updateTextLayout();
+ updateMicroFocusHint();
+ lineDirty |= textDirty;
+ if ( setModified )
+ modified = TRUE;
+ if ( textDirty ) {
+ textDirty = FALSE;
+ emit q->textChanged( maskData ? stripString(text) : text );
+ }
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( q, 0, TQAccessible::ValueChanged );
+#endif
+ }
+ if ( selDirty ) {
+ selDirty = FALSE;
+ emit q->selectionChanged();
+ }
+ if ( lineDirty || !setModified )
+ q->update();
+}
+
+void TQLineEditPrivate::setText( const TQString& txt )
+{
+ deselect();
+ TQString oldText = text;
+ if ( maskData ) {
+ text = maskString( 0, txt, TRUE );
+ text += clearString( text.length(), maxLength - text.length() );
+ } else {
+ text = txt.isEmpty() ? txt : TQT_TQSTRING(txt.left( maxLength ));
+ }
+ history.clear();
+ undoState = 0;
+ cursor = text.length();
+ textDirty = ( oldText != text );
+}
+
+
+void TQLineEditPrivate::setCursorVisible( bool visible )
+{
+ if ( (bool)cursorVisible == visible )
+ return;
+ if ( cursorTimer )
+ cursorVisible = visible;
+ TQRect r = cursorRect();
+ if ( maskData || !q->contentsRect().tqcontains( r ) )
+ q->update();
+ else
+ q->update( r );
+}
+
+void TQLineEditPrivate::addCommand( const Command& cmd )
+{
+ if ( separator && undoState && history[undoState-1].type != Separator ) {
+ history.resize( undoState + 2 );
+ history[undoState++] = Command( Separator, 0, 0 );
+ } else {
+ history.resize( undoState + 1);
+ }
+ separator = FALSE;
+ history[ undoState++ ] = cmd;
+}
+
+void TQLineEditPrivate::insert( const TQString& s )
+{
+ if ( maskData ) {
+ TQString ms = maskString( cursor, s );
+ for ( int i = 0; i < (int) ms.length(); ++i ) {
+ addCommand ( Command( DeleteSelection, cursor+i, text.at(cursor+i) ) );
+ addCommand( Command( Insert, cursor+i, ms.at(i) ) );
+ }
+ text.tqreplace( cursor, ms.length(), ms );
+ cursor += ms.length();
+ cursor = nextMaskBlank( cursor );
+ } else {
+ int remaining = maxLength - text.length();
+ text.insert( cursor, s.left(remaining) );
+ for ( int i = 0; i < (int) s.left(remaining).length(); ++i )
+ addCommand( Command( Insert, cursor++, s.at(i) ) );
+ }
+ textDirty = TRUE;
+}
+
+void TQLineEditPrivate::del( bool wasBackspace )
+{
+ if ( cursor < (int) text.length() ) {
+ addCommand ( Command( (CommandType)((maskData?2:0)+(wasBackspace?Remove:Delete)), cursor, text.at(cursor) ) );
+ if ( maskData ) {
+ text.tqreplace( cursor, 1, clearString( cursor, 1 ) );
+ addCommand( Command( Insert, cursor, text.at( cursor ) ) );
+ } else {
+ text.remove( cursor, 1 );
+ }
+ textDirty = TRUE;
+ }
+}
+
+void TQLineEditPrivate::removeSelectedText()
+{
+ if ( selstart < selend && selend <= (int) text.length() ) {
+ separate();
+ int i ;
+ if ( selstart <= cursor && cursor < selend ) {
+ // cursor is within the selection. Split up the commands
+ // to be able to restore the correct cursor position
+ for ( i = cursor; i >= selstart; --i )
+ addCommand ( Command( DeleteSelection, i, text.at(i) ) );
+ for ( i = selend - 1; i > cursor; --i )
+ addCommand ( Command( DeleteSelection, i - cursor + selstart - 1, text.at(i) ) );
+ } else {
+ for ( i = selend-1; i >= selstart; --i )
+ addCommand ( Command( RemoveSelection, i, text.at(i) ) );
+ }
+ if ( maskData ) {
+ text.tqreplace( selstart, selend - selstart, clearString( selstart, selend - selstart ) );
+ for ( int i = 0; i < selend - selstart; ++i )
+ addCommand( Command( Insert, selstart + i, text.at( selstart + i ) ) );
+ } else {
+ text.remove( selstart, selend - selstart );
+ }
+ if ( cursor > selstart )
+ cursor -= TQMIN( cursor, selend ) - selstart;
+ deselect();
+ textDirty = TRUE;
+ }
+}
+
+void TQLineEditPrivate::parseInputMask( const TQString &maskFields )
+{
+ if ( maskFields.isEmpty() || maskFields.section( ';', 0, 0 ).isEmpty() ) {
+ if ( maskData ) {
+ delete [] maskData;
+ maskData = 0;
+ maxLength = 32767;
+ q->setText( TQString::null );
+ }
+ return;
+ }
+
+ inputMask = maskFields.section( ';', 0, 0 );
+ blank = maskFields.section( ';', 1, 1 ).at(0);
+ if ( blank.isNull() )
+ blank = ' ';
+
+ // calculate maxLength / maskData length
+ maxLength = 0;
+ TQChar c = 0;
+ uint i;
+ for ( i=0; i<inputMask.length(); i++ ) {
+ c = inputMask.at(i);
+ if ( i > 0 && inputMask.at( i-1 ) == '\\' ) {
+ maxLength++;
+ continue;
+ }
+ if ( c != '\\' && c != '!' &&
+ c != '<' && c != '>' &&
+ c != '{' && c != '}' &&
+ c != '[' && c != ']' )
+ maxLength++;
+ }
+
+ delete [] maskData;
+ maskData = new MaskInputData[ maxLength ];
+
+ MaskInputData::Casemode m = MaskInputData::NoCaseMode;
+ c = 0;
+ bool s;
+ bool escape = FALSE;
+ int index = 0;
+ for ( i = 0; i < inputMask.length(); i++ ) {
+ c = inputMask.at(i);
+ if ( escape ) {
+ s = TRUE;
+ maskData[ index ].maskChar = c;
+ maskData[ index ].separator = s;
+ maskData[ index ].caseMode = m;
+ index++;
+ escape = FALSE;
+ } else if ( c == '<' || c == '>' || c == '!') {
+ switch ( c ) {
+ case '<':
+ m = MaskInputData::Lower;
+ break;
+ case '>':
+ m = MaskInputData::Upper;
+ break;
+ case '!':
+ m = MaskInputData::NoCaseMode;
+ break;
+ }
+ } else if ( c != '{' && c != '}' && c != '[' && c != ']' ) {
+ switch ( c ) {
+ case 'A':
+ case 'a':
+ case 'N':
+ case 'n':
+ case 'X':
+ case 'x':
+ case '9':
+ case '0':
+ case 'D':
+ case 'd':
+ case '#':
+ s = FALSE;
+ break;
+ case '\\':
+ escape = TRUE;
+ default:
+ s = TRUE;
+ break;
+ }
+
+ if ( !escape ) {
+ maskData[ index ].maskChar = c;
+ maskData[ index ].separator = s;
+ maskData[ index ].caseMode = m;
+ index++;
+ }
+ }
+ }
+ q->setText( TQString::null );
+}
+
+
+/* checks if the key is valid compared to the inputMask */
+bool TQLineEditPrivate::isValidInput( TQChar key, TQChar tqmask ) const
+{
+ switch ( tqmask ) {
+ case 'A':
+ if ( key.isLetter() && key != blank )
+ return TRUE;
+ break;
+ case 'a':
+ if ( key.isLetter() || key == blank )
+ return TRUE;
+ break;
+ case 'N':
+ if ( key.isLetterOrNumber() && key != blank )
+ return TRUE;
+ break;
+ case 'n':
+ if ( key.isLetterOrNumber() || key == blank )
+ return TRUE;
+ break;
+ case 'X':
+ if ( key.isPrint() && key != blank )
+ return TRUE;
+ break;
+ case 'x':
+ if ( key.isPrint() || key == blank )
+ return TRUE;
+ break;
+ case '9':
+ if ( key.isNumber() && key != blank )
+ return TRUE;
+ break;
+ case '0':
+ if ( key.isNumber() || key == blank )
+ return TRUE;
+ break;
+ case 'D':
+ if ( key.isNumber() && key.digitValue() > 0 && key != blank )
+ return TRUE;
+ break;
+ case 'd':
+ if ( (key.isNumber() && key.digitValue() > 0) || key == blank )
+ return TRUE;
+ break;
+ case '#':
+ if ( key.isNumber() || key == '+' || key == '-' || key == blank )
+ return TRUE;
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/*
+ Applies the inputMask on \a str starting from position \a pos in the tqmask. \a clear
+ specifies from where characters should be gotten when a separator is met in \a str - TRUE means
+ that blanks will be used, FALSE that previous input is used.
+ Calling this when no inputMask is set is undefined.
+*/
+TQString TQLineEditPrivate::maskString( uint pos, const TQString &str, bool clear) const
+{
+ if ( pos >= (uint)maxLength )
+ return TQString::tqfromLatin1("");
+
+ TQString fill;
+ fill = clear ? clearString( 0, maxLength ) : text;
+
+ uint strIndex = 0;
+ TQString s = TQString::tqfromLatin1("");
+ int i = pos;
+ while ( i < maxLength ) {
+ if ( strIndex < str.length() ) {
+ if ( maskData[ i ].separator ) {
+ s += maskData[ i ].maskChar;
+ if ( str[(int)strIndex] == maskData[ i ].maskChar )
+ strIndex++;
+ ++i;
+ } else {
+ if ( isValidInput( str[(int)strIndex], maskData[ i ].maskChar ) ) {
+ switch ( maskData[ i ].caseMode ) {
+ case MaskInputData::Upper:
+ s += str[(int)strIndex].upper();
+ break;
+ case MaskInputData::Lower:
+ s += str[(int)strIndex].lower();
+ break;
+ default:
+ s += str[(int)strIndex];
+ }
+ ++i;
+ } else {
+ // search for separator first
+ int n = tqfindInMask( i, TRUE, TRUE, str[(int)strIndex] );
+ if ( n != -1 ) {
+ if ( str.length() != 1 || i == 0 || (i > 0 && (!maskData[i-1].separator || maskData[i-1].maskChar != str[(int)strIndex])) ) {
+ s += fill.mid( i, n-i+1 );
+ i = n + 1; // update i to tqfind + 1
+ }
+ } else {
+ // search for valid blank if not
+ n = tqfindInMask( i, TRUE, FALSE, str[(int)strIndex] );
+ if ( n != -1 ) {
+ s += fill.mid( i, n-i );
+ switch ( maskData[ n ].caseMode ) {
+ case MaskInputData::Upper:
+ s += str[(int)strIndex].upper();
+ break;
+ case MaskInputData::Lower:
+ s += str[(int)strIndex].lower();
+ break;
+ default:
+ s += str[(int)strIndex];
+ }
+ i = n + 1; // updates i to tqfind + 1
+ }
+ }
+ }
+ strIndex++;
+ }
+ } else
+ break;
+ }
+
+ return s;
+}
+
+
+
+/*
+ Returns a "cleared" string with only separators and blank chars.
+ Calling this when no inputMask is set is undefined.
+*/
+TQString TQLineEditPrivate::clearString( uint pos, uint len ) const
+{
+ if ( pos >= (uint)maxLength )
+ return TQString::null;
+
+ TQString s;
+ int end = TQMIN( (uint)maxLength, pos + len );
+ for ( int i=pos; i<end; i++ )
+ if ( maskData[ i ].separator )
+ s += maskData[ i ].maskChar;
+ else
+ s += blank;
+
+ return s;
+}
+
+/*
+ Strips blank parts of the input in a TQLineEdit when an inputMask is set,
+ separators are still included. Typically "127.0__.0__.1__" becomes "127.0.0.1".
+*/
+TQString TQLineEditPrivate::stripString( const TQString &str ) const
+{
+ if ( !maskData )
+ return str;
+
+ TQString s;
+ int end = TQMIN( maxLength, (int)str.length() );
+ for (int i=0; i < end; i++ )
+ if ( maskData[ i ].separator )
+ s += maskData[ i ].maskChar;
+ else
+ if ( str[i] != blank )
+ s += str[i];
+
+ return s;
+}
+
+/* searches forward/backward in maskData for either a separator or a blank */
+int TQLineEditPrivate::tqfindInMask( int pos, bool forward, bool tqfindSeparator, TQChar searchChar ) const
+{
+ if ( pos >= maxLength || pos < 0 )
+ return -1;
+
+ int end = forward ? maxLength : -1;
+ int step = forward ? 1 : -1;
+ int i = pos;
+
+ while ( i != end ) {
+ if ( tqfindSeparator ) {
+ if ( maskData[ i ].separator && maskData[ i ].maskChar == searchChar )
+ return i;
+ } else {
+ if ( !maskData[ i ].separator ) {
+ if ( searchChar.isNull() )
+ return i;
+ else if ( isValidInput( searchChar, maskData[ i ].maskChar ) )
+ return i;
+ }
+ }
+ i += step;
+ }
+ return -1;
+}
+
+
+#endif // TQT_NO_LINEEDIT
diff --git a/tqtinterface/qt4/src/widgets/tqlineedit.h b/tqtinterface/qt4/src/widgets/tqlineedit.h
new file mode 100644
index 0000000..a8c3242
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqlineedit.h
@@ -0,0 +1,234 @@
+/**********************************************************************
+**
+** Definition of TQLineEdit widget class
+**
+** Created : 941011
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLINEEDIT_H
+#define TQLINEEDIT_H
+
+struct TQLineEditPrivate;
+
+class TQValidator;
+class TQPopupMenu;
+
+#ifndef TQT_H
+#include "tqframe.h"
+#include "tqstring.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_LINEEDIT
+
+class TQTextParagraph;
+class TQTextCursor;
+
+class TQ_EXPORT TQLineEdit : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( EchoMode )
+ Q_PROPERTY( TQString text READ text WRITE setText )
+ Q_PROPERTY( int maxLength READ maxLength WRITE setMaxLength )
+ Q_PROPERTY( bool frame READ frame WRITE setFrame )
+ Q_PROPERTY( EchoMode echoMode READ echoMode WRITE setEchoMode )
+ Q_PROPERTY( TQString displayText READ displayText )
+ Q_PROPERTY( int cursorPosition READ cursorPosition WRITE setCursorPosition )
+ Q_PROPERTY( Qt::Alignment tqalignment READ alignmentProp WRITE tqsetAlignmentProp )
+ Q_PROPERTY( bool edited READ edited WRITE setEdited DESIGNABLE false )
+ Q_PROPERTY( bool modified READ isModified )
+ Q_PROPERTY( bool hasMarkedText READ hasMarkedText DESIGNABLE false )
+ Q_PROPERTY( bool hasSelectedText READ hasSelectedText )
+ Q_PROPERTY( TQString markedText READ markedText DESIGNABLE false )
+ Q_PROPERTY( TQString selectedText READ selectedText )
+ Q_PROPERTY( bool dragEnabled READ dragEnabled WRITE setDragEnabled )
+ Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly )
+ Q_PROPERTY( bool undoAvailable READ isUndoAvailable )
+ Q_PROPERTY( bool redoAvailable READ isRedoAvailable )
+ Q_PROPERTY( TQString inputMask READ inputMask WRITE setInputMask )
+ Q_PROPERTY( bool acceptableInput READ hasAcceptableInput )
+
+public:
+ TQLineEdit( TQWidget* tqparent, const char* name=0 );
+ TQLineEdit( const TQString &, TQWidget* tqparent, const char* name=0 );
+ TQLineEdit( const TQString &, const TQString &, TQWidget* tqparent, const char* name=0 );
+ ~TQLineEdit();
+
+ TQString text() const;
+
+ TQString displayText() const;
+
+ int maxLength() const;
+
+ bool frame() const;
+
+ enum EchoMode { Normal, NoEcho, Password };
+ EchoMode echoMode() const;
+
+ bool isReadOnly() const;
+
+ const TQValidator * validator() const;
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ int cursorPosition() const;
+ bool validateAndSet( const TQString &, int, int, int ); // obsolete
+
+ int tqalignment() const;
+ inline Qt::Alignment alignmentProp() const { return (Qt::Alignment)tqalignment(); }
+ inline virtual void tqsetAlignmentProp( Qt::Alignment al ) { tqsetAlignment((int)al); }
+
+#ifndef TQT_NO_COMPAT
+ void cursorLeft( bool mark, int steps = 1 ) { cursorForward( mark, -steps ); }
+ void cursorRight( bool mark, int steps = 1 ) { cursorForward( mark, steps ); }
+#endif
+ void cursorForward( bool mark, int steps = 1 );
+ void cursorBackward( bool mark, int steps = 1 );
+ void cursorWordForward( bool mark );
+ void cursorWordBackward( bool mark );
+ void backspace();
+ void del();
+ void home( bool mark );
+ void end( bool mark );
+
+ bool isModified() const;
+ void clearModified();
+
+ bool edited() const; // obsolete, use isModified()
+ void setEdited( bool ); // obsolete, use clearModified()
+
+ bool hasSelectedText() const;
+ TQString selectedText() const;
+ int selectionStart() const;
+
+ bool isUndoAvailable() const;
+ bool isRedoAvailable() const;
+
+#ifndef TQT_NO_COMPAT
+ bool hasMarkedText() const { return hasSelectedText(); }
+ TQString markedText() const { return selectedText(); }
+#endif
+
+ bool dragEnabled() const;
+
+ TQString inputMask() const;
+ void setInputMask( const TQString &inputMask );
+ bool hasAcceptableInput() const;
+
+public Q_SLOTS:
+ virtual void setText( const TQString &);
+ virtual void selectAll();
+ virtual void deselect();
+ virtual void clearValidator();
+ virtual void insert( const TQString &);
+ virtual void clear();
+ virtual void undo();
+ virtual void redo();
+ virtual void setMaxLength( int );
+ virtual void setFrame( bool );
+ virtual void setEchoMode( EchoMode );
+ virtual void setReadOnly( bool );
+ virtual void setValidator( const TQValidator * );
+ virtual void setFont( const TQFont & );
+ virtual void setPalette( const TQPalette & );
+ virtual void setSelection( int, int );
+ virtual void setCursorPosition( int );
+ virtual void tqsetAlignment( int flag );
+#ifndef TQT_NO_CLIPBOARD
+ virtual void cut();
+ virtual void copy() const;
+ virtual void paste();
+#endif
+ virtual void setDragEnabled( bool b );
+
+Q_SIGNALS:
+ void textChanged( const TQString &);
+ void returnPressed();
+ void lostFocus();
+ void selectionChanged();
+
+protected:
+ bool event( TQEvent * );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseDoubleClickEvent( TQMouseEvent * );
+ void keyPressEvent( TQKeyEvent * );
+ void imStartEvent( TQIMEvent * );
+ void imComposeEvent( TQIMEvent * );
+ void imEndEvent( TQIMEvent * );
+ void focusInEvent( TQFocusEvent * );
+ void focusOutEvent( TQFocusEvent * );
+ void resizeEvent( TQResizeEvent * );
+ void drawContents( TQPainter * );
+#ifndef TQT_NO_DRAGANDDROP
+ void dragEnterEvent( TQDragEnterEvent * );
+ void dragMoveEvent( TQDragMoveEvent *e );
+ void dragLeaveEvent( TQDragLeaveEvent *e );
+ void dropEvent( TQDropEvent * );
+#endif
+ void contextMenuEvent( TQContextMenuEvent * );
+ virtual TQPopupMenu *createPopupMenu();
+ void windowActivationChange( bool );
+#ifndef TQT_NO_COMPAT
+ void repaintArea( int, int ) { update(); }
+#endif
+
+private Q_SLOTS:
+ void clipboardChanged();
+
+public:
+ void setPasswordChar( TQChar c ); // internal obsolete
+ TQChar passwordChar() const; // obsolete internal
+ int characterAt( int, TQChar* ) const; // obsolete
+ bool getSelection( int *, int * ); // obsolete
+
+private:
+ friend struct TQLineEditPrivate;
+ TQLineEditPrivate * d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQLineEdit( const TQLineEdit & );
+ TQLineEdit &operator=( const TQLineEdit & );
+#endif
+};
+
+
+#endif // TQT_NO_LINEEDIT
+
+#endif // TQLINEEDIT_H
diff --git a/tqtinterface/qt4/src/widgets/tqlistbox.cpp b/tqtinterface/qt4/src/widgets/tqlistbox.cpp
new file mode 100644
index 0000000..b829780
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqlistbox.cpp
@@ -0,0 +1,4701 @@
+/**********************************************************************
+**
+** Implementation of TQListBox widget class
+**
+** Created : 941121
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqglobal.h"
+#if defined(TQ_CC_BOR)
+// needed for qsort() because of a std namespace problem on Borland
+#include "tqplatformdefs.h"
+#endif
+
+#include "tqlistbox.h"
+#ifndef TQT_NO_LISTBOX
+#include "tqmemarray.h"
+#include "tqfontmetrics.h"
+#include "tqpainter.h"
+#include "tqstrlist.h"
+#include "tqpixmap.h"
+#include "tqapplication.h"
+#include "tqptrdict.h"
+#include "tqtimer.h"
+#include "tqstringlist.h"
+#include "tqstyle.h"
+#include "tqpopupmenu.h"
+#include "tqguardedptr.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+#include <stdlib.h>
+
+class TQListBoxPrivate
+{
+public:
+ TQListBoxPrivate( TQListBox *lb ):
+ head( 0 ), last( 0 ), cache( 0 ), cacheIndex( -1 ), current( 0 ),
+ highlighted( 0 ), tmpCurrent( 0 ), columnPos( 1 ), rowPos( 1 ), rowPosCache( 0 ),
+ columnPosOne( 0 ), rowMode( TQListBox::FixedNumber ),
+ columnMode( TQListBox::FixedNumber ), numRows( 1 ), numColumns( 1 ),
+ currentRow( 0 ), currentColumn( 0 ),
+ mousePressRow( -1 ), mousePressColumn( -1 ),
+ mouseMoveRow( -1 ), mouseMoveColumn( -1 ), mouseInternalPress( FALSE ),
+ scrollTimer( 0 ), updateTimer( 0 ), visibleTimer( 0 ),
+ selectionMode( TQListBox::Single ),
+ count( 0 ),
+ listBox( lb ), currInputString( TQString::null ),
+ rowModeWins( FALSE ),
+ ignoreMoves( FALSE ),
+ layoutDirty( TRUE ),
+ mustPaintAll( TRUE ),
+ dragging( FALSE ),
+ dirtyDrag ( FALSE ),
+ variableHeight( TRUE /* !!! ### FALSE */ ),
+ variableWidth( FALSE ),
+ inMenuMode( FALSE )
+ {}
+ int tqfindItemByName( int item, const TQString &text );
+ ~TQListBoxPrivate();
+
+ TQListBoxItem * head, *last, *cache;
+ int cacheIndex;
+ TQListBoxItem * current, *highlighted, *tmpCurrent;
+
+ TQMemArray<int> columnPos;
+ TQMemArray<int> rowPos;
+ int rowPosCache;
+ int columnPosOne;
+
+ TQListBox::LayoutMode rowMode;
+ TQListBox::LayoutMode columnMode;
+ int numRows;
+ int numColumns;
+
+ int currentRow;
+ int currentColumn;
+ int mousePressRow;
+ int mousePressColumn;
+ int mouseMoveRow;
+ int mouseMoveColumn;
+ bool mouseInternalPress;
+
+ TQTimer * scrollTimer;
+ TQTimer * updateTimer;
+ TQTimer * visibleTimer;
+ TQTimer * resizeTimer;
+
+ TQPoint scrollPos;
+
+ TQListBox::SelectionMode selectionMode;
+
+ int count;
+
+
+ TQListBox *listBox;
+ TQString currInputString;
+ TQTimer *inputTimer;
+
+ TQListBoxItem *pressedItem, *selectAnchor;
+
+ uint select :1;
+ uint pressedSelected :1;
+ uint rowModeWins :1;
+ uint ignoreMoves :1;
+ uint clearing :1;
+ uint layoutDirty :1;
+ uint mustPaintAll :1;
+ uint dragging :1;
+ uint dirtyDrag :1;
+ uint variableHeight :1;
+ uint variableWidth :1;
+ uint inMenuMode :1;
+
+ TQRect *rubber;
+ TQPtrDict<bool> selectable;
+
+ struct SortableItem {
+ TQListBoxItem *item;
+ };
+};
+
+
+TQListBoxPrivate::~TQListBoxPrivate()
+{
+ TQ_ASSERT( !head );
+}
+
+
+/*!
+ \class TQListBoxItem tqlistbox.h
+ \brief The TQListBoxItem class is the base class of all list box items.
+
+ This class is an abstract base class used for all list box items.
+ If you need to insert customized items into a TQListBox you must
+ inherit this class and reimplement paint(), height() and width().
+
+ \sa TQListBox
+*/
+
+/*!
+ \fn bool TQListBox::dragSelect() const
+ \internal
+*/
+
+/*!
+ \fn void TQListBox::setDragSelect( bool )
+ \internal
+*/
+
+/*!
+ \fn bool TQListBox::autoScroll() const
+ \internal
+*/
+
+/*!
+ \fn void TQListBox::setAutoScroll( bool )
+ \internal
+*/
+
+/*!
+ \fn bool TQListBox::autoScrollBar() const
+
+ \obsolete
+
+ Returns TRUE if vScrollBarMode() is \c Auto; otherwise returns
+ FALSE.
+*/
+
+/*!
+ \fn void TQListBox::setAutoScrollBar( bool enable )
+
+ \obsolete
+
+ If \a enable is TRUE sets setVScrollBarMode() to \c AlwaysOn;
+ otherwise sets setVScrollBarMode() to \c AlwaysOff.
+*/
+
+/*!
+ \fn bool TQListBox::scrollBar() const
+
+ \obsolete
+
+ Returns FALSE if vScrollBarMode() is \c AlwaysOff; otherwise
+ returns TRUE.
+*/
+
+/*!
+ \fn void TQListBox::setScrollBar( bool enable )
+
+ \obsolete
+
+ If \a enable is TRUE sets setVScrollBarMode() to \c AlwaysOn;
+ otherwise sets setVScrollBarMode() to \c AlwaysOff.
+*/
+
+/*!
+ \fn bool TQListBox::autoBottomScrollBar() const
+
+ \obsolete
+
+ Returns TRUE if hScrollBarMode() is \c Auto; otherwise returns
+ FALSE.
+*/
+
+/*!
+ \fn void TQListBox::setAutoBottomScrollBar( bool enable )
+
+ \obsolete
+
+ If \a enable is TRUE sets setHScrollBarMode() to \c AlwaysOn;
+ otherwise sets setHScrollBarMode() to \c AlwaysOff.
+*/
+
+/*!
+ \fn bool TQListBox::bottomScrollBar() const
+
+ \obsolete
+
+ Returns FALSE if vScrollBarMode() is \c AlwaysOff; otherwise
+ returns TRUE.
+*/
+
+/*!
+ \fn void TQListBox::setBottomScrollBar( bool enable )
+
+ \obsolete
+
+ If \a enable is TRUE sets setHScrollBarMode() to \c AlwaysOn;
+ otherwise sets setHScrollBarMode() to \c AlwaysOff.
+*/
+
+/*!
+ \fn bool TQListBox::smoothScrolling() const
+ \internal
+*/
+
+/*!
+ \fn void TQListBox::setSmoothScrolling( bool )
+ \internal
+*/
+
+/*!
+ \fn bool TQListBox::autoUpdate() const
+ \internal
+*/
+
+/*!
+ \fn void TQListBox::setAutoUpdate( bool )
+ \internal
+*/
+
+/*!
+ \fn void TQListBox::setFixedVisibleLines( int lines )
+ \internal
+*/
+
+/*!
+ \obsolete
+ \fn int TQListBox::cellHeight( int i ) const
+ Returns the item height of item \a i.
+ \sa itemHeight()
+*/
+
+/*!
+ \obsolete
+ \overload int TQListBox::cellHeight() const
+ Returns the item height of the first item, item 0.
+ \sa itemHeight()
+*/
+
+/*!
+ \obsolete
+ \fn int TQListBox::cellWidth() const
+ Returns the maximum item width.
+ \sa maxItemWidth()
+*/
+
+/*!
+ \overload int TQListBox::cellWidth(int i) const
+ \internal
+*/
+
+/*!
+ \obsolete
+ \fn int TQListBox::numCols() const
+ Returns the number of columns.
+ \sa numColumns()
+*/
+
+/*!
+ \fn void TQListBox::updateCellWidth()
+ \internal
+*/
+
+/*!
+ \obsolete
+ \fn int TQListBox::totalWidth() const
+ Returns contentsWidth().
+*/
+
+/*!
+ \obsolete
+ \fn int TQListBox::totalHeight() const
+ Returns contentsHeight().
+*/
+
+/*!
+ \obsolete
+ \fn int TQListBox::tqfindItem( int yPos ) const
+ Returns the index of the item a point (0, \a yPos).
+ \sa index() itemAt()
+*/
+
+
+/*!
+ Constructs an empty list box item in the list box \a listbox.
+*/
+
+TQListBoxItem::TQListBoxItem( TQListBox* listbox )
+{
+ lbox = listbox;
+ s = FALSE;
+ dirty = TRUE;
+ custom_highlight = FALSE;
+ p = n = 0;
+
+ // just something that'll look noticeable in the debugger
+ x = y = 42;
+
+ if (listbox)
+ listbox->insertItem( this );
+}
+
+/*!
+ Constructs an empty list box item in the list box \a listbox and
+ inserts it after the item \a after or at the beginning if \a after
+ is 0.
+*/
+
+TQListBoxItem::TQListBoxItem( TQListBox* listbox, TQListBoxItem *after )
+{
+ lbox = listbox;
+ s = FALSE;
+ dirty = TRUE;
+ custom_highlight = FALSE;
+ p = n = 0;
+
+ // just something that'll be noticeable in the debugger
+ x = y = 42;
+
+ if (listbox)
+ listbox->insertItem( this, after );
+}
+
+
+/*!
+ Destroys the list box item.
+*/
+
+TQListBoxItem::~TQListBoxItem()
+{
+ if ( lbox )
+ lbox->takeItem( this );
+}
+
+
+/*!
+ Defines whether the list box item is responsible for drawing
+ itself in a highlighted state when being selected.
+
+ If \a b is FALSE (the default), the list box will draw some
+ default highlight indicator before calling paint().
+
+ \sa selected(), paint()
+*/
+void TQListBoxItem::setCustomHighlighting( bool b )
+{
+ custom_highlight = b;
+}
+
+/*!
+ \fn void TQListBoxItem::paint( TQPainter *p )
+
+ Implement this function to draw your item. The painter, \a p, is
+ already open for painting.
+
+ \sa height(), width()
+*/
+
+/*!
+ \fn int TQListBoxItem::width( const TQListBox* lb ) const
+
+ Reimplement this function to return the width of your item. The \a
+ lb parameter is the same as listBox() and is provided for
+ convenience and compatibility.
+
+ The default implementation returns
+ \l{TQApplication::globalStrut()}'s width.
+
+ \sa paint(), height()
+*/
+int TQListBoxItem::width(const TQListBox*) const
+{
+ return TQApplication::globalStrut().width();
+}
+
+/*!
+ \fn int TQListBoxItem::height( const TQListBox* lb ) const
+
+ Implement this function to return the height of your item. The \a
+ lb parameter is the same as listBox() and is provided for
+ convenience and compatibility.
+
+ The default implementation returns
+ \l{TQApplication::globalStrut()}'s height.
+
+ \sa paint(), width()
+*/
+int TQListBoxItem::height(const TQListBox*) const
+{
+ return TQApplication::globalStrut().height();
+}
+
+
+/*!
+ Returns the text of the item. This text is also used for sorting.
+
+ \sa setText()
+*/
+TQString TQListBoxItem::text() const
+{
+ return txt;
+}
+
+/*!
+ Returns the pixmap associated with the item, or 0 if there isn't
+ one.
+
+ The default implementation returns 0.
+*/
+const TQPixmap *TQListBoxItem::pixmap() const
+{
+ return 0;
+}
+
+/*!
+ If \a b is TRUE (the default) then this item can be selected by
+ the user; otherwise this item cannot be selected by the user.
+
+ \sa isSelectable()
+*/
+
+void TQListBoxItem::setSelectable( bool b )
+{
+ if ( !listBox() )
+ return;
+ bool *sel = listBox()->d->selectable.tqfind( this );
+ if ( !sel )
+ listBox()->d->selectable.insert( this, new bool( b ) );
+ else
+ listBox()->d->selectable.tqreplace( this, new bool( b ) );
+}
+
+/*!
+ Returns TRUE if this item is selectable (the default); otherwise
+ returns FALSE.
+
+ \sa setSelectable()
+*/
+
+bool TQListBoxItem::isSelectable() const
+{
+ if ( !listBox() )
+ return TRUE;
+ bool *sel = listBox()->d->selectable.tqfind( ( (TQListBoxItem*)this ) );
+ if ( !sel )
+ return TRUE;
+ else
+ return *sel;
+}
+
+/*!
+ \fn void TQListBoxItem::setText( const TQString &text )
+
+ Sets the text of the TQListBoxItem to \a text. This \a text is also
+ used for sorting. The text is not shown unless explicitly drawn in
+ paint().
+
+ \sa text()
+*/
+
+
+/*!
+ \class TQListBoxText tqlistbox.h
+ \brief The TQListBoxText class provides list box items that display text.
+
+ \ingroup advanced
+
+ The text is drawn in the widget's current font. If you need
+ several different fonts, you must implement your own subclass of
+ TQListBoxItem.
+
+ \sa TQListBox, TQListBoxItem
+*/
+
+
+/*!
+ Constructs a list box item in list box \a listbox showing the text
+ \a text.
+*/
+TQListBoxText::TQListBoxText( TQListBox *listbox, const TQString &text )
+ :TQListBoxItem( listbox )
+{
+ setText( text );
+}
+
+/*!
+ Constructs a list box item showing the text \a text.
+*/
+
+TQListBoxText::TQListBoxText( const TQString &text )
+ :TQListBoxItem()
+{
+ setText( text );
+}
+
+/*!
+ Constructs a list box item in list box \a listbox showing the text
+ \a text. The item is inserted after the item \a after, or at the
+ beginning if \a after is 0.
+*/
+
+TQListBoxText::TQListBoxText( TQListBox* listbox, const TQString &text, TQListBoxItem *after )
+ : TQListBoxItem( listbox, after )
+{
+ setText( text );
+}
+
+/*!
+ Destroys the item.
+*/
+
+TQListBoxText::~TQListBoxText()
+{
+}
+
+/*!
+ Draws the text using \a painter.
+*/
+
+void TQListBoxText::paint( TQPainter *painter )
+{
+ int itemHeight = height( listBox() );
+ TQFontMetrics fm = painter->fontMetrics();
+ int yPos = ( ( itemHeight - fm.height() ) / 2 ) + fm.ascent();
+ painter->drawText( 3, yPos, text() );
+}
+
+/*!
+ Returns the height of a line of text in list box \a lb.
+
+ \sa paint(), width()
+*/
+
+int TQListBoxText::height( const TQListBox* lb ) const
+{
+ int h = lb ? lb->fontMetrics().lineSpacing() + 2 : 0;
+ return TQMAX( h, TQApplication::globalStrut().height() );
+}
+
+/*!
+ Returns the width of this line in list box \a lb.
+
+ \sa paint(), height()
+*/
+
+int TQListBoxText::width( const TQListBox* lb ) const
+{
+ int w = lb ? lb->fontMetrics().width( text() ) + 6 : 0;
+ return TQMAX( w, TQApplication::globalStrut().width() );
+}
+
+int TQListBoxText::RTTI = 1;
+
+/*!
+ \fn int TQListBoxText::rtti() const
+
+ \reimp
+
+ Returns 1.
+
+ Make your derived classes return their own values for rtti(), and
+ you can distinguish between listbox items. You should use values
+ greater than 1000 preferably a large random number, to allow for
+ extensions to this class.
+*/
+
+int TQListBoxText::rtti() const
+{
+ return RTTI;
+}
+
+/*!
+ \class TQListBoxPixmap tqlistbox.h
+ \brief The TQListBoxPixmap class provides list box items with a
+ pixmap and optional text.
+
+ \ingroup advanced
+
+ Items of this class are drawn with the pixmap on the left with the
+ optional text to the right of the pixmap.
+
+ \sa TQListBox, TQListBoxItem
+*/
+
+
+/*!
+ Constructs a new list box item in list box \a listbox showing the
+ pixmap \a pixmap.
+*/
+
+TQListBoxPixmap::TQListBoxPixmap( TQListBox* listbox, const TQPixmap &pixmap )
+ : TQListBoxItem( listbox )
+{
+ pm = pixmap;
+}
+
+/*!
+ Constructs a new list box item showing the pixmap \a pixmap.
+*/
+
+TQListBoxPixmap::TQListBoxPixmap( const TQPixmap &pixmap )
+ : TQListBoxItem()
+{
+ pm = pixmap;
+}
+
+/*!
+ Constructs a new list box item in list box \a listbox showing the
+ pixmap \a pixmap. The item gets inserted after the item \a after,
+ or at the beginning if \a after is 0.
+*/
+
+TQListBoxPixmap::TQListBoxPixmap( TQListBox* listbox, const TQPixmap &pixmap, TQListBoxItem *after )
+ : TQListBoxItem( listbox, after )
+{
+ pm = pixmap;
+}
+
+
+/*!
+ Destroys the item.
+*/
+
+TQListBoxPixmap::~TQListBoxPixmap()
+{
+}
+
+
+/*!
+ Constructs a new list box item in list box \a listbox showing the
+ pixmap \a pix and the text \a text.
+*/
+TQListBoxPixmap::TQListBoxPixmap( TQListBox* listbox, const TQPixmap &pix, const TQString& text)
+ : TQListBoxItem( listbox )
+{
+ pm = pix;
+ setText( text );
+}
+
+/*!
+ Constructs a new list box item showing the pixmap \a pix and the
+ text to \a text.
+*/
+TQListBoxPixmap::TQListBoxPixmap( const TQPixmap & pix, const TQString& text)
+ : TQListBoxItem()
+{
+ pm = pix;
+ setText( text );
+}
+
+/*!
+ Constructs a new list box item in list box \a listbox showing the
+ pixmap \a pix and the string \a text. The item gets inserted after
+ the item \a after, or at the beginning if \a after is 0.
+*/
+TQListBoxPixmap::TQListBoxPixmap( TQListBox* listbox, const TQPixmap & pix, const TQString& text,
+ TQListBoxItem *after )
+ : TQListBoxItem( listbox, after )
+{
+ pm = pix;
+ setText( text );
+}
+
+/*!
+ \fn const TQPixmap *TQListBoxPixmap::pixmap() const
+
+ Returns the pixmap associated with the item.
+*/
+
+
+/*!
+ Draws the pixmap using \a painter.
+*/
+
+void TQListBoxPixmap::paint( TQPainter *painter )
+{
+ int itemHeight = height( listBox() );
+ int yPos;
+
+ const TQPixmap *pm = pixmap();
+ if ( pm && ! pm->isNull() ) {
+ yPos = ( itemHeight - pm->height() ) / 2;
+ painter->drawPixmap( 3, yPos, *pm);
+ }
+
+ if ( !text().isEmpty() ) {
+ TQFontMetrics fm = painter->fontMetrics();
+ yPos = ( ( itemHeight - fm.height() ) / 2 ) + fm.ascent();
+ painter->drawText( pm->width() + 5, yPos, text() );
+ }
+}
+
+/*!
+ Returns the height of the pixmap in list box \a lb.
+
+ \sa paint(), width()
+*/
+
+int TQListBoxPixmap::height( const TQListBox* lb ) const
+{
+ int h;
+ if ( text().isEmpty() )
+ h = pm.height();
+ else
+ h = TQMAX( pm.height(), lb->fontMetrics().lineSpacing() + 2 );
+ return TQMAX( h, TQApplication::globalStrut().height() );
+}
+
+/*!
+ Returns the width of the pixmap plus some margin in list box \a lb.
+
+ \sa paint(), height()
+*/
+
+int TQListBoxPixmap::width( const TQListBox* lb ) const
+{
+ if ( text().isEmpty() )
+ return TQMAX( pm.width() + 6, TQApplication::globalStrut().width() );
+ return TQMAX( pm.width() + lb->fontMetrics().width( text() ) + 6,
+ TQApplication::globalStrut().width() );
+}
+
+int TQListBoxPixmap::RTTI = 2;
+
+/*!
+ \fn int TQListBoxPixmap::rtti() const
+
+ \reimp
+
+ Returns 2.
+
+ Make your derived classes return their own values for rtti(), and
+ you can distinguish between listbox items. You should use values
+ greater than 1000 preferably a large random number, to allow for
+ extensions to this class.
+*/
+
+int TQListBoxPixmap::rtti() const
+{
+ return RTTI;
+}
+
+/*!
+ \class TQListBox tqlistbox.h
+ \brief The TQListBox widget provides a list of selectable, read-only items.
+
+ \ingroup advanced
+ \mainclass
+
+ This is typically a single-column list in which either no item or
+ one item is selected, but it can also be used in many other ways.
+
+ TQListBox will add scroll bars as necessary, but it isn't intended
+ for \e really big lists. If you want more than a few thousand
+ items, it's probably better to use a different widget mainly
+ because the scroll bars won't provide very good navigation, but
+ also because TQListBox may become slow with huge lists. (See
+ TQListView and TQTable for possible alternatives.)
+
+ There are a variety of selection modes described in the
+ TQListBox::SelectionMode documentation. The default is \c Single
+ selection mode, but you can change it using setSelectionMode().
+ (setMultiSelection() is still provided for compatibility with TQt
+ 1.x. We recommend using setSelectionMode() in all code.)
+
+ Because TQListBox offers multiple selection it must display
+ keyboard focus and selection state separately. Therefore there are
+ functions both to set the selection state of an item, i.e.
+ setSelected(), and to set which item displays keyboard focus, i.e.
+ setCurrentItem().
+
+ The list box normally arranges its items in a single column and
+ adds a vertical scroll bar if required. It is possible to have a
+ different fixed number of columns (setColumnMode()), or as many
+ columns as will fit in the list box's assigned screen space
+ (setColumnMode(FitToWidth)), or to have a fixed number of rows
+ (setRowMode()) or as many rows as will fit in the list box's
+ assigned screen space (setRowMode(FitToHeight)). In all these
+ cases TQListBox will add scroll bars, as appropriate, in at least
+ one direction.
+
+ If multiple rows are used, each row can be as high as necessary
+ (the normal setting), or you can request that all items will have
+ the same height by calling setVariableHeight(FALSE). The same
+ applies to a column's width, see setVariableWidth().
+
+ The TQListBox's items are TQListBoxItem objects. TQListBox provides
+ methods to insert new items as strings, as pixmaps, and as
+ TQListBoxItem * (insertItem() with various arguments), and to
+ tqreplace an existing item with a new string, pixmap or TQListBoxItem
+ (changeItem() with various arguments). You can also remove items
+ singly with removeItem() or clear() the entire list box. Note that
+ if you create a TQListBoxItem yourself and insert it, TQListBox
+ takes ownership of the item.
+
+ You can also create a TQListBoxItem, such as TQListBoxText or
+ TQListBoxPixmap, with the list box as first parameter. The item
+ will then append itself. When you delete an item it is
+ automatically removed from the list box.
+
+ The list of items can be arbitrarily large; TQListBox will add
+ scroll bars if necessary. TQListBox can display a single-column
+ (the common case) or multiple-columns, and offers both single and
+ multiple selection. TQListBox does not support multiple-column
+ items (but TQListView and TQTable do), or tree hierarchies (but
+ TQListView does).
+
+ The list box items can be accessed both as TQListBoxItem objects
+ (recommended) and using integer indexes (the original TQListBox
+ implementation used an array of strings internally, and the API
+ still supports this mode of operation). Everything can be done
+ using the new objects, and most things can be done using indexes.
+
+ Each item in a TQListBox tqcontains a TQListBoxItem. One of the items
+ can be the current item. The currentChanged() signal and the
+ highlighted() signal are emitted when a new item becomes current,
+ e.g. because the user clicks on it or TQListBox::setCurrentItem()
+ is called. The selected() signal is emitted when the user
+ double-clicks on an item or presses Enter on the current item.
+
+ If the user does not select anything, no Q_SIGNALS are emitted and
+ currentItem() returns -1.
+
+ A list box has \c WheelFocus as a default focusPolicy(), i.e. it
+ can get keyboard focus by tabbing, clicking and through the use of
+ the mouse wheel.
+
+ New items can be inserted using insertItem(), insertStrList() or
+ insertStringList(). inSort() is obsolete because this method is
+ quite inefficient. It's preferable to insert the items normally
+ and call sort() afterwards, or to insert a sorted TQStringList().
+
+ By default, vertical and horizontal scroll bars are added and
+ removed as necessary. setHScrollBarMode() and setVScrollBarMode()
+ can be used to change this policy.
+
+ If you need to insert types other than strings and pixmaps, you
+ must define new classes which inherit TQListBoxItem.
+
+ \warning The list box assumes ownership of all list box items and
+ will delete them when it does not need them any more.
+
+ <img src=qlistbox-m.png> <img src=qlistbox-w.png>
+
+ \sa TQListView TQComboBox TQButtonGroup
+ \link guibooks.html#fowler GUI Design Handbook: List Box (two
+ sections)\endlink
+*/
+
+/*!
+ \enum TQListBox::SelectionMode
+
+ This enumerated type is used by TQListBox to indicate how it reacts
+ to selection by the user.
+
+ \value Single When the user selects an item, any already-selected
+ item becomes unselected and the user cannot unselect the selected
+ item. This means that the user can never clear the selection, even
+ though the selection may be cleared by the application programmer
+ using TQListBox::clearSelection().
+
+ \value Multi When the user selects an item the selection status
+ of that item is toggled and the other items are left alone. Also,
+ multiple items can be selected by dragging the mouse while the
+ left mouse button is kept pressed.
+
+ \value Extended When the user selects an item the selection is
+ cleared and the new item selected. However, if the user presses
+ the Ctrl key when clicking on an item, the clicked item gets
+ toggled and all other items are left untouched. And if the user
+ presses the Shift key while clicking on an item, all items between
+ the current item and the clicked item get selected or unselected,
+ depending on the state of the clicked item. Also, multiple items
+ can be selected by dragging the mouse while the left mouse button
+ is kept pressed.
+
+ \value NoSelection Items cannot be selected.
+
+ In other words, \c Single is a real single-selection list box, \c
+ Multi is a real multi-selection list box, \c Extended is a list
+ box in which users can select multiple items but usually want to
+ select either just one or a range of contiguous items, and \c
+ NoSelection is for a list box where the user can look but not
+ touch.
+*/
+
+
+/*!
+ \enum TQListBox::LayoutMode
+
+ This enum type is used to specify how TQListBox lays out its rows
+ and columns.
+
+ \value FixedNumber There is a fixed number of rows (or columns).
+
+ \value FitToWidth There are as many columns as will fit
+ on-screen.
+
+ \value FitToHeight There are as many rows as will fit on-screen.
+
+ \value Variable There are as many rows as are required by the
+ column mode. (Or as many columns as required by the row mode.)
+
+ Example: When you call setRowMode( FitToHeight ), columnMode()
+ automatically becomes \c Variable to accommodate the row mode
+ you've set.
+*/
+
+/*!
+ \fn void TQListBox::onItem( TQListBoxItem *i )
+
+ This signal is emitted when the user moves the mouse cursor onto
+ an item, similar to the TQWidget::enterEvent() function. \a i is
+ the TQListBoxItem that the mouse has moved on.
+*/
+
+// ### bug here too? enter/leave event may noit considered. move the
+// mouse out of the window and back in, to the same item - does it
+// work?
+
+/*!
+ \fn void TQListBox::onViewport()
+
+ This signal is emitted when the user moves the mouse cursor from
+ an item to an empty part of the list box.
+*/
+
+
+/*!
+ Constructs a new empty list box called \a name and with tqparent \a
+ tqparent.
+
+ Performance is boosted by modifying the widget flags \a f so that
+ only part of the TQListBoxItem tqchildren is redrawn. This may be
+ unsuitable for custom TQListBoxItem classes, in which case \c
+ WStaticContents and \c WNoAutoErase should be cleared
+ immediately after construction.
+
+ \sa TQWidget::clearWFlags() TQt::WidgetFlags
+*/
+
+TQListBox::TQListBox( TQWidget *tqparent, const char *name, WFlags f )
+ : TQScrollView( tqparent, name, (WFlags)(f | TQt::WStaticContents | TQt::WNoAutoErase) )
+{
+ d = new TQListBoxPrivate( this );
+ d->updateTimer = new TQTimer( this, "listbox update timer" );
+ d->visibleTimer = new TQTimer( this, "listbox visible timer" );
+ d->inputTimer = new TQTimer( this, "listbox input timer" );
+ d->resizeTimer = new TQTimer( this, "listbox resize timer" );
+ d->clearing = FALSE;
+ d->pressedItem = 0;
+ d->selectAnchor = 0;
+ d->select = FALSE;
+ d->rubber = 0;
+ d->selectable.setAutoDelete( TRUE );
+
+ setMouseTracking( TRUE );
+ viewport()->setMouseTracking( TRUE );
+
+ connect( d->updateTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(refreshSlot()) );
+ connect( d->visibleTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(ensureCurrentVisible()) );
+ connect( d->resizeTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( adjustItems() ) );
+ viewport()->setBackgroundMode( TQt::PaletteBase );
+ setBackgroundMode( TQt::PaletteBackground, TQt::PaletteBase );
+ viewport()->setFocusProxy( this );
+ viewport()->setFocusPolicy( Qt::WheelFocus );
+}
+
+
+TQListBox * TQListBox::changedListBox = 0;
+
+/*!
+ Destroys the list box. Deletes all list box items.
+*/
+
+TQListBox::~TQListBox()
+{
+ if ( changedListBox == this )
+ changedListBox = 0;
+ clear();
+ delete d;
+ d = 0;
+}
+
+/*!
+ \fn void TQListBox::pressed( TQListBoxItem *item )
+
+ This signal is emitted when the user presses any mouse button. If
+ \a item is not 0, the cursor is on \a item. If \a item is 0, the
+ mouse cursor isn't on any item.
+
+ Note that you must not delete any TQListBoxItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \overload void TQListBox::pressed( TQListBoxItem *item, const TQPoint &pnt )
+
+ This signal is emitted when the user presses any mouse button. If
+ \a item is not 0, the cursor is on \a item. If \a item is 0, the
+ mouse cursor isn't on any item.
+
+ \a pnt is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()).
+
+ Note that you must not delete any TQListBoxItem objects in Q_SLOTS
+ connected to this signal.
+
+ \sa mouseButtonPressed() rightButtonPressed() clicked()
+*/
+
+/*!
+ \fn void TQListBox::clicked( TQListBoxItem *item )
+
+ This signal is emitted when the user clicks any mouse button. If
+ \a item is not 0, the cursor is on \a item. If \a item is 0, the
+ mouse cursor isn't on any item.
+
+ Note that you must not delete any TQListBoxItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \overload void TQListBox::clicked( TQListBoxItem *item, const TQPoint &pnt )
+
+ This signal is emitted when the user clicks any mouse button. If
+ \a item is not 0, the cursor is on \a item. If \a item is 0, the
+ mouse cursor isn't on any item.
+
+ \a pnt is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()). (If the click's
+ press and release differs by a pixel or two, \a pnt is the
+ position at release time.)
+
+ Note that you must not delete any TQListBoxItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \fn void TQListBox::mouseButtonClicked (int button, TQListBoxItem * item, const TQPoint & pos)
+
+ This signal is emitted when the user clicks mouse button \a
+ button. If \a item is not 0, the cursor is on \a item. If \a item
+ is 0, the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()). (If the click's
+ press and release differs by a pixel or two, \a pos is the
+ position at release time.)
+
+ Note that you must not delete any TQListBoxItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \fn void TQListBox::mouseButtonPressed (int button, TQListBoxItem * item, const TQPoint & pos)
+
+ This signal is emitted when the user presses mouse button \a
+ button. If \a item is not 0, the cursor is on \a item. If \a item
+ is 0, the mouse cursor isn't on any item.
+
+ \a pos is the position of the mouse cursor in the global
+ coordinate system (TQMouseEvent::globalPos()).
+
+ Note that you must not delete any TQListBoxItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \fn void TQListBox::doubleClicked( TQListBoxItem *item )
+
+ This signal is emitted whenever an item is double-clicked. It's
+ emitted on the second button press, not the second button release.
+ If \a item is not 0, the cursor is on \a item. If \a item is 0,
+ the mouse cursor isn't on any item.
+*/
+
+
+/*!
+ \fn void TQListBox::returnPressed( TQListBoxItem * )
+
+ This signal is emitted when Enter or Return is pressed. The
+ argument is currentItem().
+*/
+
+/*!
+ \fn void TQListBox::rightButtonClicked( TQListBoxItem *, const TQPoint& )
+
+ This signal is emitted when the right button is clicked (i.e. when
+ it's released at the same point where it was pressed). The
+ arguments are the relevant TQListBoxItem (may be 0) and the point
+ in global coordinates.
+*/
+
+
+/*!
+ \fn void TQListBox::rightButtonPressed (TQListBoxItem *, const TQPoint & )
+
+ This signal is emitted when the right button is pressed. The
+ arguments are the relevant TQListBoxItem (may be 0) and the point
+ in global coordinates.
+*/
+
+/*!
+ \fn void TQListBox::contextMenuRequested( TQListBoxItem *item, const TQPoint & pos )
+
+ This signal is emitted when the user invokes a context menu with
+ the right mouse button or with special system keys, with \a item
+ being the item under the mouse cursor or the current item,
+ respectively.
+
+ \a pos is the position for the context menu in the global
+ coordinate system.
+*/
+
+/*!
+ \fn void TQListBox::selectionChanged()
+
+ This signal is emitted when the selection set of a list box
+ changes. This signal is emitted in each selection mode. If the
+ user selects five items by drag-selecting, TQListBox tries to emit
+ just one selectionChanged() signal so the signal can be connected
+ to computationally expensive Q_SLOTS.
+
+ \sa selected() currentItem()
+*/
+
+/*!
+ \overload void TQListBox::selectionChanged( TQListBoxItem *item )
+
+ This signal is emitted when the selection in a \c Single selection
+ list box changes. \a item is the newly selected list box item.
+
+ \sa selected() currentItem()
+*/
+
+/*!
+ \fn void TQListBox::currentChanged( TQListBoxItem *item )
+
+ This signal is emitted when the user makes a new item the current
+ item. \a item is the new current list box item.
+
+ \sa setCurrentItem() currentItem()
+*/
+
+/*!
+ \fn void TQListBox::highlighted( int index )
+
+ This signal is emitted when the user makes a new item the current
+ item. \a index is the index of the new current item.
+
+ \sa currentChanged() selected() currentItem() selectionChanged()
+*/
+
+/*!
+ \overload void TQListBox::highlighted( TQListBoxItem * )
+
+ This signal is emitted when the user makes a new item the current
+ item. The argument is a pointer to the new current item.
+
+ \sa currentChanged() selected() currentItem() selectionChanged()
+*/
+
+/*!
+ \overload void TQListBox::highlighted( const TQString & )
+
+ This signal is emitted when the user makes a new item the current
+ item and the item is (or has) a string. The argument is the text
+ of the new current item.
+
+ \sa currentChanged() selected() currentItem() selectionChanged()
+*/
+
+/*!
+ \fn void TQListBox::selected( int index )
+
+ This signal is emitted when the user double-clicks on an item or
+ presses Enter on the current item. \a index is the index of the
+ selected item.
+
+ \sa currentChanged() highlighted() selectionChanged()
+*/
+
+/*!
+ \overload void TQListBox::selected( TQListBoxItem * )
+
+ This signal is emitted when the user double-clicks on an item or
+ presses Enter on the current item. The argument is a pointer to
+ the new selected item.
+
+ \sa currentChanged() highlighted() selectionChanged()
+*/
+
+/*!
+ \overload void TQListBox::selected( const TQString &)
+
+ This signal is emitted when the user double-clicks on an item or
+ presses Enter on the current item, and the item is (or has) a
+ string. The argument is the text of the selected item.
+
+ \sa currentChanged() highlighted() selectionChanged()
+*/
+
+/*! \reimp */
+
+void TQListBox::setFont( const TQFont &font )
+{
+ TQScrollView::setFont( font );
+ triggerUpdate( TRUE );
+}
+
+
+/*!
+ \property TQListBox::count
+ \brief the number of items in the list box
+*/
+
+uint TQListBox::count() const
+{
+ return d->count;
+}
+
+
+/*!
+ Inserts the string list \a list into the list at position \a
+ index.
+
+ If \a index is negative, \a list is inserted at the end of the
+ list. If \a index is too large, the operation is ignored.
+
+ \warning This function uses \c{const char *} rather than TQString,
+ so we recommend against using it. It is provided so that legacy
+ code will continue to work, and so that programs that certainly
+ will not need to handle code outside a single 8-bit locale can use
+ it. See insertStringList() which uses real TQStrings.
+
+ \warning This function is never significantly faster than a loop
+ around insertItem().
+
+ \sa insertItem(), insertStringList()
+*/
+
+void TQListBox::insertStrList( const TQStrList *list, int index )
+{
+ if ( !list ) {
+#if defined(TQT_CHECK_NULL)
+ TQ_ASSERT( list != 0 );
+#endif
+ return;
+ }
+ insertStrList( *list, index );
+}
+
+
+
+/*!
+ Inserts the string list \a list into the list at position \a
+ index.
+
+ If \a index is negative, \a list is inserted at the end of the
+ list. If \a index is too large, the operation is ignored.
+
+ \warning This function is never significantly faster than a loop
+ around insertItem().
+
+ \sa insertItem(), insertStrList()
+*/
+
+void TQListBox::insertStringList( const TQStringList & list, int index )
+{
+ if ( index < 0 )
+ index = count();
+ for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it )
+ insertItem( new TQListBoxText(*it), index++ );
+}
+
+
+
+/*!
+ \overload
+
+ Inserts the string list \a list into the list at position \a
+ index.
+
+ If \a index is negative, \a list is inserted at the end of the
+ list. If \a index is too large, the operation is ignored.
+
+ \warning This function uses \c{const char *} rather than TQString,
+ so we recommend against using it. It is provided so that legacy
+ code will continue to work, and so that programs that certainly
+ will not need to handle code outside a single 8-bit locale can use
+ it. See insertStringList() which uses real TQStrings.
+
+ \warning This function is never significantly faster than a loop
+ around insertItem().
+
+ \sa insertItem(), insertStringList()
+*/
+
+void TQListBox::insertStrList( const TQStrList & list, int index )
+{
+ TQStrListIterator it( list );
+ const char* txt;
+ if ( index < 0 )
+ index = count();
+ while ( (txt=it.current()) ) {
+ ++it;
+ insertItem( new TQListBoxText(TQString::tqfromLatin1(txt)),
+ index++ );
+ }
+ if ( hasFocus() && !d->current )
+ setCurrentItem( d->head );
+}
+
+
+/*!
+ \overload
+
+ Inserts the \a numStrings strings of the array \a strings into the
+ list at position \a index.
+
+ If \a index is negative, insertStrList() inserts \a strings at the
+ end of the list. If \a index is too large, the operation is
+ ignored.
+
+ \warning This function uses \c{const char *} rather than TQString,
+ so we recommend against using it. It is provided so that legacy
+ code will continue to work, and so that programs that certainly
+ will not need to handle code outside a single 8-bit locale can use
+ it. See insertStringList() which uses real TQStrings.
+
+ \warning This function is never significantly faster than a loop
+ around insertItem().
+
+ \sa insertItem(), insertStringList()
+*/
+
+void TQListBox::insertStrList( const char **strings, int numStrings, int index )
+{
+ if ( !strings ) {
+#if defined(TQT_CHECK_NULL)
+ TQ_ASSERT( strings != 0 );
+#endif
+ return;
+ }
+ if ( index < 0 )
+ index = count();
+ int i = 0;
+ while ( (numStrings<0 && strings[i]!=0) || i<numStrings ) {
+ insertItem( new TQListBoxText( TQString::tqfromLatin1(strings[i])),
+ index + i );
+ i++;
+ }
+ if ( hasFocus() && !d->current )
+ setCurrentItem( d->head );
+}
+
+/*!
+ Inserts the item \a lbi into the list at position \a index.
+
+ If \a index is negative or larger than the number of items in the
+ list box, \a lbi is inserted at the end of the list.
+
+ \sa insertStrList()
+*/
+
+void TQListBox::insertItem( const TQListBoxItem *lbi, int index )
+{
+#if defined ( TQT_CHECK_NULL )
+ TQ_ASSERT( lbi != 0 );
+#else
+ if ( !lbi )
+ return;
+#endif
+
+ if ( index < 0 )
+ index = d->count;
+
+ if ( index >= d->count ) {
+ insertItem( lbi, d->last );
+ return;
+ }
+
+ TQListBoxItem * item = (TQListBoxItem *)lbi;
+ d->count++;
+ d->cache = 0;
+
+ item->lbox = this;
+ if ( !d->head || index == 0 ) {
+ item->n = d->head;
+ item->p = 0;
+ d->head = item;
+ item->dirty = TRUE;
+ if ( item->n )
+ item->n->p = item;
+ } else {
+ TQListBoxItem * i = d->head;
+ while ( i->n && index > 1 ) {
+ i = i->n;
+ index--;
+ }
+ if ( i->n ) {
+ item->n = i->n;
+ item->p = i;
+ item->n->p = item;
+ item->p->n = item;
+ } else {
+ i->n = item;
+ item->p = i;
+ item->n = 0;
+ }
+ }
+
+ if ( hasFocus() && !d->current ) {
+ d->current = d->head;
+ updateItem( d->current );
+ emit highlighted( d->current );
+ emit highlighted( d->current->text() );
+ emit highlighted( index );
+ }
+
+ triggerUpdate( TRUE );
+}
+
+/*!
+ \overload
+
+ Inserts the item \a lbi into the list after the item \a after, or
+ at the beginning if \a after is 0.
+
+ \sa insertStrList()
+*/
+
+void TQListBox::insertItem( const TQListBoxItem *lbi, const TQListBoxItem *after )
+{
+#if defined ( TQT_CHECK_NULL )
+ TQ_ASSERT( lbi != 0 );
+#else
+ if ( !lbi )
+ return;
+#endif
+
+ TQListBoxItem * item = (TQListBoxItem*)lbi;
+ d->count++;
+ d->cache = 0;
+
+ item->lbox = this;
+ if ( !d->head || !after ) {
+ item->n = d->head;
+ item->p = 0;
+ d->head = item;
+ item->dirty = TRUE;
+ if ( item->n )
+ item->n->p = item;
+ } else {
+ TQListBoxItem * i = (TQListBoxItem*) after;
+ if ( i ) {
+ item->n = i->n;
+ item->p = i;
+ if ( item->n )
+ item->n->p = item;
+ if ( item->p )
+ item->p->n = item;
+ }
+ }
+
+ if ( after == d->last )
+ d->last = (TQListBoxItem*) lbi;
+
+ if ( hasFocus() && !d->current ) {
+ d->current = d->head;
+ updateItem( d->current );
+ emit highlighted( d->current );
+ emit highlighted( d->current->text() );
+ emit highlighted( index( d->current ) );
+ }
+
+ triggerUpdate( TRUE );
+}
+
+/*!
+ \overload
+
+ Inserts a new list box text item with the text \a text into the
+ list at position \a index.
+
+ If \a index is negative, \a text is inserted at the end of the
+ list.
+
+ \sa insertStrList()
+*/
+
+void TQListBox::insertItem( const TQString &text, int index )
+{
+ insertItem( new TQListBoxText(text), index );
+}
+
+/*!
+ \overload
+
+ Inserts a new list box pixmap item with the pixmap \a pixmap into
+ the list at position \a index.
+
+ If \a index is negative, \a pixmap is inserted at the end of the
+ list.
+
+ \sa insertStrList()
+*/
+
+void TQListBox::insertItem( const TQPixmap &pixmap, int index )
+{
+ insertItem( new TQListBoxPixmap(pixmap), index );
+}
+
+/*!
+ \overload
+
+ Inserts a new list box pixmap item with the pixmap \a pixmap and
+ the text \a text into the list at position \a index.
+
+ If \a index is negative, \a pixmap is inserted at the end of the
+ list.
+
+ \sa insertStrList()
+*/
+
+void TQListBox::insertItem( const TQPixmap &pixmap, const TQString &text, int index )
+{
+ insertItem( new TQListBoxPixmap(pixmap, text), index );
+}
+
+/*!
+ Removes and deletes the item at position \a index. If \a index is
+ equal to currentItem(), a new item becomes current and the
+ currentChanged() and highlighted() Q_SIGNALS are emitted.
+
+ \sa insertItem(), clear()
+*/
+
+void TQListBox::removeItem( int index )
+{
+ bool wasVisible = itemVisible( currentItem() );
+ delete item( index );
+ triggerUpdate( TRUE );
+ if ( wasVisible )
+ ensureCurrentVisible();
+}
+
+
+/*!
+ Deletes all the items in the list.
+
+ \sa removeItem()
+*/
+
+void TQListBox::clear()
+{
+ setContentsPos( 0, 0 );
+ bool blocked = tqsignalsBlocked();
+ blockSignals( TRUE );
+ d->clearing = TRUE;
+ d->current = 0;
+ d->tmpCurrent = 0;
+ TQListBoxItem * i = d->head;
+ d->head = 0;
+ while ( i ) {
+ TQListBoxItem * n = i->n;
+ i->n = i->p = 0;
+ delete i;
+ i = n;
+ }
+ d->count = 0;
+ d->numRows = 1;
+ d->numColumns = 1;
+ d->currentRow = 0;
+ d->currentColumn = 0;
+ d->mousePressRow = -1;
+ d->mousePressColumn = -1;
+ d->mouseMoveRow = -1;
+ d->mouseMoveColumn = -1;
+ d->selectable.clear();
+ clearSelection();
+ blockSignals( blocked );
+ triggerUpdate( TRUE );
+ d->last = 0;
+ d->clearing = FALSE;
+}
+
+
+/*!
+ Returns the text at position \a index, or TQString::null if there
+ is no text at that position.
+
+ \sa pixmap()
+*/
+
+TQString TQListBox::text( int index ) const
+{
+ TQListBoxItem * i = item( index );
+ if ( i )
+ return i->text();
+ return TQString::null;
+}
+
+
+/*!
+ Returns a pointer to the pixmap at position \a index, or 0 if
+ there is no pixmap there.
+
+ \sa text()
+*/
+
+const TQPixmap *TQListBox::pixmap( int index ) const
+{
+ TQListBoxItem * i = item( index );
+ if ( i )
+ return i->pixmap();
+ return 0;
+}
+
+/*!
+ \overload
+
+ Replaces the item at position \a index with a new list box text
+ item with text \a text.
+
+ The operation is ignored if \a index is out of range.
+
+ \sa insertItem(), removeItem()
+*/
+
+void TQListBox::changeItem( const TQString &text, int index )
+{
+ if( index >= 0 && index < (int)count() )
+ changeItem( new TQListBoxText(text), index );
+}
+
+/*!
+ \overload
+
+ Replaces the item at position \a index with a new list box pixmap
+ item with pixmap \a pixmap.
+
+ The operation is ignored if \a index is out of range.
+
+ \sa insertItem(), removeItem()
+*/
+
+void TQListBox::changeItem( const TQPixmap &pixmap, int index )
+{
+ if( index >= 0 && index < (int)count() )
+ changeItem( new TQListBoxPixmap(pixmap), index );
+}
+
+/*!
+ \overload
+
+ Replaces the item at position \a index with a new list box pixmap
+ item with pixmap \a pixmap and text \a text.
+
+ The operation is ignored if \a index is out of range.
+
+ \sa insertItem(), removeItem()
+*/
+
+void TQListBox::changeItem( const TQPixmap &pixmap, const TQString &text, int index )
+{
+ if( index >= 0 && index < (int)count() )
+ changeItem( new TQListBoxPixmap(pixmap, text), index );
+}
+
+
+
+/*!
+ Replaces the item at position \a index with \a lbi. If \a index is
+ negative or too large, changeItem() does nothing.
+
+ The item that has been changed will become selected.
+
+ \sa insertItem(), removeItem()
+*/
+
+void TQListBox::changeItem( const TQListBoxItem *lbi, int index )
+{
+ if ( !lbi || index < 0 || index >= (int)count() )
+ return;
+
+ removeItem( index );
+ insertItem( lbi, index );
+ setCurrentItem( index );
+}
+
+
+/*!
+ \property TQListBox::numItemsVisible
+ \brief the number of visible items.
+
+ Both partially and entirely visible items are counted.
+*/
+
+int TQListBox::numItemsVisible() const
+{
+ doLayout();
+
+ int columns = 0;
+
+ int x = contentsX();
+ int i=0;
+ while ( i < (int)d->columnPos.size()-1 &&
+ d->columnPos[i] < x )
+ i++;
+ if ( i < (int)d->columnPos.size()-1 &&
+ d->columnPos[i] > x )
+ columns++;
+ x += visibleWidth();
+ while ( i < (int)d->columnPos.size()-1 &&
+ d->columnPos[i] < x ) {
+ i++;
+ columns++;
+ }
+
+ int y = contentsY();
+ int rows = 0;
+ while ( i < (int)d->rowPos.size()-1 &&
+ d->rowPos[i] < y )
+ i++;
+ if ( i < (int)d->rowPos.size()-1 &&
+ d->rowPos[i] > y )
+ rows++;
+ y += visibleHeight();
+ while ( i < (int)d->rowPos.size()-1 &&
+ d->rowPos[i] < y ) {
+ i++;
+ rows++;
+ }
+
+ return rows*columns;
+}
+
+int TQListBox::currentItem() const
+{
+ if ( !d->current || !d->head )
+ return -1;
+
+ return index( d->current );
+}
+
+
+/*!
+ \property TQListBox::currentText
+ \brief the text of the current item.
+
+ This is equivalent to text(currentItem()).
+*/
+
+
+/*!
+ \property TQListBox::currentItem
+ \brief the current highlighted item
+
+ When setting this property, the highlighting is moved to the item
+ and the list box scrolled as necessary.
+
+ If no item is current, currentItem() returns -1.
+*/
+
+void TQListBox::setCurrentItem( int index )
+{
+ setCurrentItem( item( index ) );
+}
+
+
+/*!
+ \overload
+
+ Sets the current item to the TQListBoxItem \a i.
+*/
+void TQListBox::setCurrentItem( TQListBoxItem * i )
+{
+ if ( !i || d->current == i || numRows() == 0 )
+ return;
+
+ TQRect mfrect = tqitemRect( i );
+ if ( mfrect.isValid() )
+ setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE );
+
+ TQListBoxItem * o = d->current;
+ d->current = i;
+ int ind = index( i );
+
+ if ( i && selectionMode() == Single ) {
+ bool changed = FALSE;
+ if ( o && o->s ) {
+ changed = TRUE;
+ o->s = FALSE;
+ }
+ if ( i && !i->s && d->selectionMode != NoSelection && i->isSelectable() ) {
+ i->s = TRUE;
+ changed = TRUE;
+ emit selectionChanged( i );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), ind+1, TQAccessible::StateChanged );
+#endif
+ }
+ if ( changed ) {
+ emit selectionChanged();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::Selection );
+#endif
+ }
+ }
+
+ d->currentColumn = ind / numRows();
+ d->currentRow = ind % numRows();
+ if ( o )
+ updateItem( o );
+ if ( i )
+ updateItem( i );
+ // scroll after the items are redrawn
+ d->visibleTimer->start( 1, TRUE );
+
+ TQString tmp;
+ if ( i )
+ tmp = i->text();
+ emit highlighted( i );
+ if ( !tmp.isNull() )
+ emit highlighted( tmp );
+ emit highlighted( ind );
+ emit currentChanged( i );
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), ind+1, TQAccessible::Focus );
+#endif
+}
+
+
+/*!
+ Returns a pointer to the item at position \a index, or 0 if \a
+ index is out of bounds.
+
+ \sa index()
+*/
+
+TQListBoxItem *TQListBox::item( int index ) const
+{
+ if ( index < 0 || index > d->count -1 )
+ return 0;
+
+ TQListBoxItem * i = d->head;
+
+ if ( d->cache && index > 0 ) {
+ i = d->cache;
+ int idx = d->cacheIndex;
+ while ( i && idx < index ) {
+ idx++;
+ i = i->n;
+ }
+ while ( i && idx > index ) {
+ idx--;
+ i = i->p;
+ }
+ } else {
+ int idx = index;
+ while ( i && idx > 0 ) {
+ idx--;
+ i = i->n;
+ }
+ }
+
+ if ( index > 0 ) {
+ d->cache = i;
+ d->cacheIndex = index;
+ }
+
+ return i;
+}
+
+
+/*!
+ Returns the index of \a lbi, or -1 if the item is not in this list
+ box or \a lbi is 0.
+
+ \sa item()
+*/
+
+int TQListBox::index( const TQListBoxItem * lbi ) const
+{
+ if ( !lbi )
+ return -1;
+ TQListBoxItem * i_n = d->head;
+ int c_n = 0;
+ if ( d->cache ) {
+ i_n = d->cache;
+ c_n = d->cacheIndex;
+ }
+ TQListBoxItem* i_p = i_n;
+ int c_p = c_n;
+ while ( ( i_n != 0 || i_p != 0 ) && i_n != lbi && i_p != lbi ) {
+ if ( i_n ) {
+ c_n++;
+ i_n = i_n->n;
+ }
+ if ( i_p ) {
+ c_p--;
+ i_p = i_p->p;
+ }
+ }
+ if ( i_p == lbi )
+ return c_p;
+ if ( i_n == lbi )
+ return c_n;
+ return -1;
+}
+
+
+
+/*!
+ Returns TRUE if the item at position \a index is at least partly
+ visible; otherwise returns FALSE.
+*/
+
+bool TQListBox::itemVisible( int index )
+{
+ TQListBoxItem * i = item( index );
+ return i ? itemVisible( i ) : FALSE;
+}
+
+
+/*!
+ \overload
+
+ Returns TRUE if \a item is at least partly visible; otherwise
+ returns FALSE.
+*/
+
+bool TQListBox::itemVisible( const TQListBoxItem * item )
+{
+ if ( d->layoutDirty )
+ doLayout();
+
+ int i = index( item );
+ int col = i / numRows();
+ int row = i % numRows();
+ return ( d->columnPos[col] < contentsX()+visibleWidth() &&
+ d->rowPos[row] < contentsY()+visibleHeight() &&
+ d->columnPos[col+1] > contentsX() &&
+ d->rowPos[row+1] > contentsY() );
+}
+
+
+/*! \reimp */
+
+void TQListBox::mousePressEvent( TQMouseEvent *e )
+{
+ mousePressEventEx( e );
+}
+
+void TQListBox::mousePressEventEx( TQMouseEvent *e )
+{
+ d->mouseInternalPress = TRUE;
+ TQListBoxItem * i = itemAt( e->pos() );
+
+ if ( !i && !d->current && d->head ) {
+ d->current = d->head;
+ updateItem( d->head );
+ }
+
+ if ( !i && ( d->selectionMode != Single || e->button() == Qt::RightButton )
+ && !( e->state() & ControlButton ) )
+ clearSelection();
+
+ d->select = d->selectionMode == Multi ? ( i ? !i->isSelected() : FALSE ) : TRUE;
+ d->pressedSelected = i && i->s;
+
+ if ( i )
+ d->selectAnchor = i;
+ if ( i ) {
+ switch( selectionMode() ) {
+ default:
+ case Single:
+ if ( !i->s || i != d->current ) {
+ if ( i->isSelectable() )
+ setSelected( i, TRUE );
+ else
+ setCurrentItem( i );
+ }
+ break;
+ case Extended:
+ if ( i ) {
+ if ( !(e->state() & ShiftButton) &&
+ !(e->state() & ControlButton) ) {
+ if ( !i->isSelected() ) {
+ bool b = tqsignalsBlocked();
+ blockSignals( TRUE );
+ clearSelection();
+ blockSignals( b );
+ }
+ setSelected( i, TRUE );
+ d->dragging = TRUE; // always assume dragging
+ } else if ( e->state() & ShiftButton ) {
+ d->pressedSelected = FALSE;
+ TQListBoxItem *oldCurrent = item( currentItem() );
+ bool down = index( oldCurrent ) < index( i );
+
+ TQListBoxItem *lit = down ? oldCurrent : i;
+ bool select = d->select;
+ bool blocked = tqsignalsBlocked();
+ blockSignals( TRUE );
+ for ( ;; lit = lit->n ) {
+ if ( !lit ) {
+ triggerUpdate( FALSE );
+ break;
+ }
+ if ( down && lit == i ) {
+ setSelected( i, select );
+ triggerUpdate( FALSE );
+ break;
+ }
+ if ( !down && lit == oldCurrent ) {
+ setSelected( oldCurrent, select );
+ triggerUpdate( FALSE );
+ break;
+ }
+ setSelected( lit, select );
+ }
+ blockSignals( blocked );
+ emit selectionChanged();
+ } else if ( e->state() & ControlButton ) {
+ setSelected( i, !i->isSelected() );
+ d->pressedSelected = FALSE;
+ }
+ setCurrentItem( i );
+ }
+ break;
+ case Multi:
+ //d->current = i;
+ setSelected( i, !i->s );
+ setCurrentItem( i );
+ break;
+ case NoSelection:
+ setCurrentItem( i );
+ break;
+ }
+ } else {
+ bool unselect = TRUE;
+ if ( e->button() == Qt::LeftButton ) {
+ if ( d->selectionMode == Multi ||
+ d->selectionMode == Extended ) {
+ d->tmpCurrent = d->current;
+ d->current = 0;
+ updateItem( d->tmpCurrent );
+ if ( d->rubber )
+ delete d->rubber;
+ d->rubber = 0;
+ d->rubber = new TQRect( e->x(), e->y(), 0, 0 );
+
+ if ( d->selectionMode == Extended && !( e->state() & ControlButton ) )
+ selectAll( FALSE );
+ unselect = FALSE;
+ }
+ if ( unselect && ( e->button() == Qt::RightButton ||
+ ( selectionMode() == Multi || selectionMode() == Extended ) ) )
+ clearSelection();
+ }
+ }
+
+ // for sanity, in case people are event-filtering or whatnot
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ if ( i ) {
+ d->mousePressColumn = d->currentColumn;
+ d->mousePressRow = d->currentRow;
+ } else {
+ d->mousePressColumn = -1;
+ d->mousePressRow = -1;
+ }
+ d->ignoreMoves = FALSE;
+
+ d->pressedItem = i;
+
+ emit pressed( i );
+ emit pressed( i, e->globalPos() );
+ emit mouseButtonPressed( e->button(), i, e->globalPos() );
+ if ( e->button() == Qt::RightButton )
+ emit rightButtonPressed( i, e->globalPos() );
+}
+
+
+/*! \reimp */
+
+void TQListBox::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( d->selectionMode == Extended &&
+ d->dragging ) {
+ d->dragging = FALSE;
+ if (d->current != d->pressedItem) {
+ updateSelection(); // when we drag, we get an update after we release
+ }
+ }
+
+ if ( d->rubber ) {
+ drawRubber();
+ delete d->rubber;
+ d->rubber = 0;
+ d->current = d->tmpCurrent;
+ updateItem( d->current );
+ }
+ if ( d->scrollTimer )
+ mouseMoveEvent( e );
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ d->ignoreMoves = FALSE;
+
+ if ( d->selectionMode == Extended &&
+ d->current == d->pressedItem &&
+ d->pressedSelected && d->current ) {
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ clearSelection();
+ blockSignals( block );
+ d->current->s = TRUE;
+ emit selectionChanged();
+ }
+
+ TQListBoxItem * i = itemAt( e->pos() );
+ bool emitClicked = (d->mousePressColumn != -1 && d->mousePressRow != -1) || !d->pressedItem;
+ emitClicked = emitClicked && d->pressedItem == i;
+ d->pressedItem = 0;
+ d->mousePressRow = -1;
+ d->mousePressColumn = -1;
+ d->mouseInternalPress = FALSE;
+ if ( emitClicked ) {
+ emit clicked( i );
+ emit clicked( i, e->globalPos() );
+ emit mouseButtonClicked( e->button(), i, e->globalPos() );
+ if ( e->button() == Qt::RightButton )
+ emit rightButtonClicked( i, e->globalPos() );
+ }
+}
+
+
+/*! \reimp */
+
+void TQListBox::mouseDoubleClickEvent( TQMouseEvent *e )
+{
+ bool ok = TRUE;
+ TQListBoxItem *i = itemAt( e->pos() );
+ if ( !i || selectionMode() == NoSelection )
+ ok = FALSE;
+
+ d->ignoreMoves = TRUE;
+
+ if ( d->current && ok ) {
+ TQListBoxItem * i = d->current;
+ TQString tmp = d->current->text();
+ emit selected( currentItem() );
+ emit selected( i );
+ if ( !tmp.isNull() )
+ emit selected( tmp );
+ emit doubleClicked( i );
+ }
+}
+
+
+/*! \reimp */
+
+void TQListBox::mouseMoveEvent( TQMouseEvent *e )
+{
+ TQListBoxItem * i = itemAt( e->pos() );
+ if ( i != d->highlighted ) {
+ if ( i ) {
+ emit onItem( i );
+ } else {
+ emit onViewport();
+ }
+ d->highlighted = i;
+ }
+
+ if ( d->rubber ) {
+ TQRect r = d->rubber->normalize();
+ drawRubber();
+ d->rubber->setCoords( d->rubber->x(), d->rubber->y(), e->x(), e->y() );
+ doRubberSelection( r, d->rubber->normalize() );
+ drawRubber();
+ return;
+ }
+
+ if ( ( (e->state() & ( Qt::RightButton | Qt::LeftButton | Qt::MidButton ) ) == 0 ) ||
+ d->ignoreMoves )
+ return;
+
+ // hack to keep the combo (and what else?) working: if we get a
+ // move outside the listbox without having seen a press, discard
+ // it.
+ if ( !TQRect( 0, 0, visibleWidth(), visibleHeight() ).tqcontains( e->pos() ) &&
+ ( (d->mousePressColumn < 0 && d->mousePressRow < 0) ||
+ (e->state() == Qt::NoButton && !d->pressedItem) ) )
+ return;
+
+ // figure out in what direction to drag-select and perhaps scroll
+ int dx = 0;
+ int x = e->x();
+ if ( x >= visibleWidth() ) {
+ x = visibleWidth()-1;
+ dx = 1;
+ } else if ( x < 0 ) {
+ x = 0;
+ dx = -1;
+ }
+ d->mouseMoveColumn = columnAt( x + contentsX() );
+
+ // sanitize mousePressColumn, if we got here without a mouse press event
+ if ( d->mousePressColumn < 0 && d->mouseMoveColumn >= 0 )
+ d->mousePressColumn = d->mouseMoveColumn;
+ if ( d->mousePressColumn < 0 && d->currentColumn >= 0 )
+ d->mousePressColumn = d->currentColumn;
+
+ // if it's beyond the last column, use the last one
+ if ( d->mouseMoveColumn < 0 )
+ d->mouseMoveColumn = dx >= 0 ? numColumns()-1 : 0;
+
+ // repeat for y
+ int dy = 0;
+ int y = e->y();
+ if ( y >= visibleHeight() ) {
+ y = visibleHeight()-1;
+ dy = 1;
+ } else if ( y < 0 ) {
+ y = 0;
+ dy = -1;
+ }
+ d->mouseMoveRow = rowAt( y + contentsY() );
+
+ if ( d->mousePressRow < 0 && d->mouseMoveRow >= 0 )
+ d->mousePressRow = d->mouseMoveRow;
+ if ( d->mousePressRow < 0 && d->currentRow >= 0 )
+ d->mousePressRow = d->currentRow;
+
+ if ( d->mousePressRow < 0 )
+ d->mousePressRow = rowAt( x + contentsX() );
+
+ d->scrollPos = TQPoint( dx, dy );
+
+ if ( ( dx || dy ) && !d->scrollTimer && e->state() == Qt::LeftButton && e->button() != Qt::LeftButton ) {
+ // start autoscrolling if necessary
+ d->scrollTimer = new TQTimer( this );
+ connect( d->scrollTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(doAutoScroll()) );
+ d->scrollTimer->start( 100, FALSE );
+ doAutoScroll();
+ } else if ( !d->scrollTimer ) {
+ // or just select the required bits
+ updateSelection();
+ }
+}
+
+
+
+void TQListBox::updateSelection()
+{
+ if ( d->mouseMoveColumn >= 0 && d->mouseMoveRow >= 0 &&
+ d->mousePressColumn >= 0 && d->mousePressRow >= 0 ) {
+ TQListBoxItem * i = item( d->mouseMoveColumn * numRows() +
+ d->mouseMoveRow );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ int ind = index(i);
+#endif
+ if ( selectionMode() == Single || selectionMode() == NoSelection ) {
+ if ( i && ( d->mouseInternalPress || testWFlags(WType_Popup) ) )
+ setCurrentItem( i );
+ } else {
+ if ( d->selectionMode == Extended && (
+ ( d->current == d->pressedItem && d->pressedSelected ) ||
+ (d->dirtyDrag && !d->dragging) ) ) {
+ if (d->dirtyDrag && !d->dragging) // emit after dragging stops
+ d->dirtyDrag = FALSE;
+ else
+ clearSelection(); // dont reset drag-selected items
+ d->pressedItem = 0;
+ if ( i && i->isSelectable() ) {
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ i->s = TRUE;
+ blockSignals( block );
+ emit selectionChanged();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), ind+1, TQAccessible::StateChanged );
+ TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::Selection );
+ TQAccessible::updateAccessibility( viewport(), ind+1, TQAccessible::SelectionAdd );
+#endif
+ }
+ triggerUpdate( FALSE );
+ } else {
+ int c = TQMIN( d->mouseMoveColumn, d->mousePressColumn );
+ int r = TQMIN( d->mouseMoveRow, d->mousePressRow );
+ int c2 = TQMAX( d->mouseMoveColumn, d->mousePressColumn );
+ int r2 = TQMAX( d->mouseMoveRow, d->mousePressRow );
+ bool changed = FALSE;
+ while( c <= c2 ) {
+ TQListBoxItem * i = item( c*numRows()+r );
+ int rtmp = r;
+ while( i && rtmp <= r2 ) {
+ if ( (bool)i->s != (bool)d->select && i->isSelectable() ) {
+ i->s = d->select;
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), ind+1, TQAccessible::StateChanged );
+ TQAccessible::updateAccessibility( viewport(), ind+1, d->select ? TQAccessible::SelectionAdd : TQAccessible::SelectionRemove );
+#endif
+ i->dirty = TRUE;
+ d->dirtyDrag = changed = TRUE;
+ }
+ i = i->n;
+ rtmp++;
+ }
+ c++;
+ }
+ if ( changed ) {
+ if (!d->dragging) // emit after dragging stops instead
+ emit selectionChanged();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::Selection );
+#endif
+ triggerUpdate( FALSE );
+ }
+ }
+ if ( i )
+ setCurrentItem( i );
+ }
+ }
+}
+
+void TQListBox::repaintSelection()
+{
+ if ( d->numColumns == 1 ) {
+ for ( uint i = topItem(); itemVisible( i ) && i < count(); ++i ) {
+ TQListBoxItem *it = item(i);
+ if ( !it )
+ break;
+ if ( it->isSelected() )
+ updateItem( it );
+ }
+ } else {
+ for ( uint i = 0; i < count(); ++i ) {
+ TQListBoxItem *it = item(i);
+ if ( !it )
+ break;
+ if ( it->isSelected() )
+ updateItem( it );
+ }
+ }
+}
+
+/*! \reimp
+*/
+
+void TQListBox::contentsContextMenuEvent( TQContextMenuEvent *e )
+{
+ if ( !tqreceivers( TQT_SIGNAL(contextMenuRequested(TQListBoxItem*,const TQPoint&)) ) ) {
+ e->ignore();
+ return;
+ }
+ if ( e->reason() == TQContextMenuEvent::Keyboard ) {
+ TQListBoxItem *i = item( currentItem() );
+ if ( i ) {
+ TQRect r = tqitemRect( i );
+ emit contextMenuRequested( i, mapToGlobal( r.topLeft() + TQPoint( width() / 2, r.height() / 2 ) ) );
+ }
+ } else {
+ TQListBoxItem * i = itemAt( contentsToViewport( e->pos() ) );
+ emit contextMenuRequested( i, e->globalPos() );
+ }
+}
+
+/*!\reimp
+*/
+void TQListBox::keyPressEvent( TQKeyEvent *e )
+{
+ if ( ( e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab )
+ && e->state() & ControlButton )
+ e->ignore();
+
+ if ( count() == 0 ) {
+ e->ignore();
+ return;
+ }
+
+ TQGuardedPtr<TQListBox> selfCheck = this;
+
+ TQListBoxItem *old = d->current;
+ if ( !old ) {
+ setCurrentItem( d->head );
+ if ( d->selectionMode == Single )
+ setSelected( d->head, TRUE );
+ e->ignore();
+ return;
+ }
+
+ bool selectCurrent = FALSE;
+ switch ( e->key() ) {
+ case Qt::Key_Up:
+ {
+ d->currInputString = TQString::null;
+ if ( currentItem() > 0 ) {
+ setCurrentItem( currentItem() - 1 );
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = d->current;
+ }
+ break;
+ case Qt::Key_Down:
+ {
+ d->currInputString = TQString::null;
+ if ( currentItem() < (int)count() - 1 ) {
+ setCurrentItem( currentItem() + 1 );
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = d->current;
+ }
+ break;
+ case Qt::Key_Left:
+ {
+ d->currInputString = TQString::null;
+ if ( currentColumn() > 0 ) {
+ setCurrentItem( currentItem() - numRows() );
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ } else if ( numColumns() > 1 && currentItem() > 0 ) {
+ int row = currentRow();
+ setCurrentItem( currentRow() - 1 + ( numColumns() - 1 ) * numRows() );
+
+ if ( currentItem() == -1 )
+ setCurrentItem( row - 1 + ( numColumns() - 2 ) * numRows() );
+
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ } else {
+ TQApplication::sendEvent( horizontalScrollBar(), e );
+ }
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = d->current;
+ }
+ break;
+ case Qt::Key_Right:
+ {
+ d->currInputString = TQString::null;
+ if ( currentColumn() < numColumns()-1 ) {
+ int row = currentRow();
+ int i = currentItem();
+ TQListBoxItem *it = item( i + numRows() );
+ if ( !it )
+ it = item( count()-1 );
+ setCurrentItem( it );
+
+ if ( currentItem() == -1 ) {
+ if ( row < numRows() - 1 )
+ setCurrentItem( row + 1 );
+ else
+ setCurrentItem( i );
+ }
+
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ } else if ( numColumns() > 1 && currentRow() < numRows() ) {
+ if ( currentRow() + 1 < numRows() ) {
+ setCurrentItem( currentRow() + 1 );
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ }
+ } else {
+ TQApplication::sendEvent( horizontalScrollBar(), e );
+ }
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = d->current;
+ }
+ break;
+ case TQt::Key_Next:
+ {
+ d->currInputString = TQString::null;
+ int i = 0;
+ if ( numColumns() == 1 ) {
+ i = currentItem() + numItemsVisible();
+ i = i > (int)count() - 1 ? (int)count() - 1 : i;
+ setCurrentItem( i );
+ setBottomItem( i );
+ } else {
+ // I'm not sure about this behavior...
+ if ( currentRow() == numRows() - 1 )
+ i = currentItem() + numRows();
+ else
+ i = currentItem() + numRows() - currentRow() - 1;
+ i = i > (int)count() - 1 ? (int)count() - 1 : i;
+ setCurrentItem( i );
+ }
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = d->current;
+ }
+ break;
+ case TQt::Key_Prior:
+ {
+ selectCurrent = TRUE;
+ d->currInputString = TQString::null;
+ int i;
+ if ( numColumns() == 1 ) {
+ i = currentItem() - numItemsVisible();
+ i = i < 0 ? 0 : i;
+ setCurrentItem( i );
+ setTopItem( i );
+ } else {
+ // I'm not sure about this behavior...
+ if ( currentRow() == 0 )
+ i = currentItem() - numRows();
+ else
+ i = currentItem() - currentRow();
+ i = i < 0 ? 0 : i;
+ setCurrentItem( i );
+ }
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = d->current;
+ }
+ break;
+ case Qt::Key_Space:
+ {
+ selectCurrent = TRUE;
+ d->currInputString = TQString::null;
+ toggleCurrentItem();
+ if ( selectionMode() == Extended && d->current->isSelected() )
+ emit highlighted( currentItem() );
+ if (selfCheck && (!( e->state() & ShiftButton ) || !d->selectAnchor))
+ d->selectAnchor = d->current;
+ }
+ break;
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ {
+ selectCurrent = TRUE;
+ d->currInputString = TQString::null;
+ if ( currentItem() >= 0 && selectionMode() != NoSelection ) {
+ TQString tmp = item( currentItem() )->text();
+ emit selected( currentItem());
+ emit selected( item( currentItem() ) );
+ if ( !tmp.isEmpty() )
+ emit selected( tmp );
+ emit returnPressed( item( currentItem() ) );
+ }
+ if (selfCheck && (!( e->state() & ShiftButton ) || !d->selectAnchor))
+ d->selectAnchor = d->current;
+ }
+ break;
+ case Qt::Key_Home:
+ {
+ selectCurrent = TRUE;
+ d->currInputString = TQString::null;
+ setCurrentItem( 0 );
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = d->current;
+ }
+ break;
+ case Qt::Key_End:
+ {
+ selectCurrent = TRUE;
+ d->currInputString = TQString::null;
+ int i = (int)count() - 1;
+ setCurrentItem( i );
+ handleItemChange( old, e->state() & ShiftButton, e->state() & ControlButton );
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = d->current;
+ }
+ break;
+ default:
+ {
+ if ( !e->text().isEmpty() && e->text()[ 0 ].isPrint() && count() ) {
+ int curItem = currentItem();
+ if ( curItem == -1 )
+ curItem = 0;
+ if ( !d->inputTimer->isActive() ) {
+ d->currInputString = e->text();
+ curItem = d->tqfindItemByName( ++curItem, d->currInputString );
+ } else {
+ d->inputTimer->stop();
+ d->currInputString += e->text();
+ int oldCurItem = curItem;
+ curItem = d->tqfindItemByName( curItem, d->currInputString );
+ if ( curItem < 0 ) {
+ curItem = d->tqfindItemByName( ++oldCurItem, e->text() );
+ d->currInputString = e->text();
+ }
+ }
+ if ( curItem >= 0 )
+ setCurrentItem( curItem );
+ if ( curItem >= 0 && selectionMode() == TQListBox::Extended ) {
+ bool changed = FALSE;
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ selectAll( FALSE );
+ blockSignals( block );
+ TQListBoxItem *i = item( curItem );
+ if ( !i->s && i->isSelectable() ) {
+ changed = TRUE;
+ i->s = TRUE;
+ updateItem( i );
+ }
+ if ( changed )
+ emit selectionChanged();
+ }
+ d->inputTimer->start( 400, TRUE );
+ } else {
+ d->currInputString = TQString::null;
+ if ( e->state() & ControlButton ) {
+ switch ( e->key() ) {
+ case Qt::Key_A:
+ selectAll( TRUE );
+ break;
+ }
+ } else {
+ e->ignore();
+ }
+ }
+ }
+ }
+
+ if (selfCheck && selectCurrent && selectionMode() == Single &&
+ d->current && !d->current->s ) {
+ updateItem( d->current );
+ setSelected( d->current, TRUE );
+ }
+}
+
+
+/*!\reimp
+*/
+void TQListBox::focusInEvent( TQFocusEvent* tqfe )
+{
+ d->mousePressRow = -1;
+ d->mousePressColumn = -1;
+ d->inMenuMode = FALSE;
+#ifdef USE_QT4
+ if ( tqfe->reason() != TQFocusEvent::Mouse && !d->current && d->head ) {
+#else // USE_QT4
+ if ( TQFocusEvent::reason() != TQFocusEvent::Mouse && !d->current && d->head ) {
+#endif // USE_QT4
+ d->current = d->head;
+ TQListBoxItem *i = d->current;
+ TQString tmp;
+ if ( i )
+ tmp = i->text();
+ int tmp2 = index( i );
+ emit highlighted( i );
+ if ( !tmp.isNull() )
+ emit highlighted( tmp );
+ emit highlighted( tmp2 );
+ emit currentChanged( i );
+ }
+ if ( tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this ) )
+ repaintSelection();
+
+ if ( d->current ) {
+ updateItem( currentItem() );
+ TQRect mfrect = tqitemRect( d->current );
+ if ( mfrect.isValid() )
+ setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE );
+ }
+}
+
+
+/*!\reimp
+*/
+void TQListBox::focusOutEvent( TQFocusEvent* tqfe)
+{
+ if (tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this )) {
+ d->inMenuMode =
+#ifdef USE_QT4
+ tqfe->reason() == TQFocusEvent::Popup ||
+#else // USE_QT4
+ TQFocusEvent::reason() == TQFocusEvent::Popup ||
+#endif // USE_QT4
+ (tqApp->tqfocusWidget() && tqApp->tqfocusWidget()->inherits("TQMenuBar"));
+ if ( !d->inMenuMode )
+ repaintSelection();
+ }
+
+ if ( d->current )
+ updateItem( currentItem() );
+}
+
+/*!\reimp
+*/
+bool TQListBox::eventFilter( TQObject *o, TQEvent *e )
+{
+ //### remove in 4.0
+ return TQScrollView::eventFilter( o, e );
+}
+
+/*!
+ Repaints the item at position \a index in the list.
+*/
+
+void TQListBox::updateItem( int index )
+{
+ if ( index >= 0 )
+ updateItem( item( index ) );
+}
+
+
+/*!
+ \overload
+
+ Repaints the TQListBoxItem \a i.
+*/
+
+void TQListBox::updateItem( TQListBoxItem * i )
+{
+ if ( !i )
+ return;
+ i->dirty = TRUE;
+ d->updateTimer->start( 0, TRUE );
+}
+
+
+/*!
+ \property TQListBox::selectionMode
+ \brief the selection mode of the list box
+
+ Sets the list box's selection mode, which may be one of \c Single
+ (the default), \c Extended, \c Multi or \c NoSelection.
+
+ \sa SelectionMode
+*/
+
+void TQListBox::setSelectionMode( SelectionMode mode )
+{
+ if ( d->selectionMode == mode )
+ return;
+
+ if ( ( selectionMode() == Multi || selectionMode() == Extended )
+ && ( mode == TQListBox::Single || mode == TQListBox::NoSelection ) ){
+ clearSelection();
+ if ( ( mode == TQListBox::Single ) && currentItem() )
+ setSelected( currentItem(), TRUE );
+ }
+
+ d->selectionMode = mode;
+ triggerUpdate( TRUE );
+}
+
+
+TQListBox::SelectionMode TQListBox::selectionMode() const
+{
+ return d->selectionMode;
+}
+
+
+/*!
+ \obsolete
+ \property TQListBox::multiSelection
+ \brief whether or not the list box is in Multi selection mode
+
+ Consider using the \l TQListBox::selectionMode property instead of
+ this property.
+
+ When setting this property, Multi selection mode is used if set to TRUE and
+ to Single selection mode if set to FALSE.
+
+ When getting this property, TRUE is returned if the list box is in
+ Multi selection mode or Extended selection mode, and FALSE if it is
+ in Single selection mode or NoSelection mode.
+
+ \sa selectionMode
+*/
+
+bool TQListBox::isMultiSelection() const
+{
+ return selectionMode() == Multi || selectionMode() == Extended;
+}
+
+void TQListBox::setMultiSelection( bool enable )
+{
+ setSelectionMode( enable ? Multi : Single );
+}
+
+
+/*!
+ Toggles the selection status of currentItem() and repaints if the
+ list box is a \c Multi selection list box.
+
+ \sa setMultiSelection()
+*/
+
+void TQListBox::toggleCurrentItem()
+{
+ if ( selectionMode() == Single ||
+ selectionMode() == NoSelection ||
+ !d->current )
+ return;
+
+ if ( d->current->s || d->current->isSelectable() ) {
+ d->current->s = !d->current->s;
+ emit selectionChanged();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ int ind = index( d->current );
+ TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::Selection );
+ TQAccessible::updateAccessibility( viewport(), ind+1, TQAccessible::StateChanged );
+ TQAccessible::updateAccessibility( viewport(), ind+1, d->current->s ? TQAccessible::SelectionAdd : TQAccessible::SelectionRemove );
+#endif
+ }
+ updateItem( d->current );
+}
+
+
+/*!
+ \overload
+
+ If \a select is TRUE the item at position \a index is selected;
+ otherwise the item is deselected.
+*/
+
+void TQListBox::setSelected( int index, bool select )
+{
+ setSelected( item( index ), select );
+}
+
+
+/*!
+ Selects \a item if \a select is TRUE or unselects it if \a select
+ is FALSE, and repaints the item appropriately.
+
+ If the list box is a \c Single selection list box and \a select is
+ TRUE, setSelected() calls setCurrentItem().
+
+ If the list box is a \c Single selection list box, \a select is
+ FALSE, setSelected() calls clearSelection().
+
+ \sa setMultiSelection(), setCurrentItem(), clearSelection(), currentItem()
+*/
+
+void TQListBox::setSelected( TQListBoxItem * item, bool select )
+{
+ if ( !item || !item->isSelectable() ||
+ (bool)item->s == select || d->selectionMode == NoSelection )
+ return;
+
+ int ind = index( item );
+ bool emitHighlighted = (d->current != item) ||
+ ( item->s != (uint) select && select );
+ if ( selectionMode() == Single ) {
+ if ( d->current != item ) {
+ TQListBoxItem *o = d->current;
+ if ( d->current && d->current->s )
+ d->current->s = FALSE;
+ d->current = item;
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), ind+1, TQAccessible::Focus );
+#endif
+ d->currentColumn = ind / numRows();
+ d->currentRow = ind % numRows();
+
+ if ( o )
+ updateItem( o );
+ }
+ }
+
+ item->s = (uint)select;
+ updateItem( item );
+
+ if ( d->selectionMode == Single && select ) {
+ emit selectionChanged( item );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), ind+1, TQAccessible::StateChanged );
+#endif
+ }
+ emit selectionChanged();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::Selection );
+ if ( d->selectionMode != Single )
+ TQAccessible::updateAccessibility( viewport(), ind+1, select ? TQAccessible::SelectionAdd : TQAccessible::SelectionRemove );
+#endif
+
+ if ( emitHighlighted ) {
+ TQString tmp;
+ if ( d->current )
+ tmp = d->current->text();
+ int tmp2 = index( d->current );
+ emit highlighted( d->current );
+ if ( !tmp.isNull() )
+ emit highlighted( tmp );
+ emit highlighted( tmp2 );
+ emit currentChanged( d->current );
+ }
+}
+
+
+/*!
+ Returns TRUE if item \a i is selected; otherwise returns FALSE.
+*/
+
+bool TQListBox::isSelected( int i ) const
+{
+ if ( selectionMode() == Single && i != currentItem() )
+ return FALSE;
+
+ TQListBoxItem * lbi = item( i );
+ if ( !lbi )
+ return FALSE; // should not happen
+ return lbi->s;
+}
+
+
+/*!
+ \overload
+
+ Returns TRUE if item \a i is selected; otherwise returns FALSE.
+*/
+
+bool TQListBox::isSelected( const TQListBoxItem * i ) const
+{
+ if ( !i )
+ return FALSE;
+
+ return i->s;
+}
+
+/*! Returns the selected item if the list box is in
+single-selection mode and an item is selected.
+
+If no items are selected or the list box is in another selection mode
+this function returns 0.
+
+\sa setSelected() setMultiSelection()
+*/
+
+TQListBoxItem* TQListBox::selectedItem() const
+{
+ if ( d->selectionMode != Single )
+ return 0;
+ if ( isSelected( currentItem() ) )
+ return d->current;
+ return 0;
+}
+
+
+/*!
+ Deselects all items, if possible.
+
+ Note that a \c Single selection list box will automatically select
+ an item if it has keyboard focus.
+*/
+
+void TQListBox::clearSelection()
+{
+ selectAll( FALSE );
+}
+
+/*!
+ In \c Multi and \c Extended modes, this function sets all items to
+ be selected if \a select is TRUE, and to be unselected if \a
+ select is FALSE.
+
+ In \c Single and \c NoSelection modes, this function only changes
+ the selection status of currentItem().
+*/
+
+void TQListBox::selectAll( bool select )
+{
+ if ( selectionMode() == Multi || selectionMode() == Extended ) {
+ bool b = tqsignalsBlocked();
+ blockSignals( TRUE );
+ for ( int i = 0; i < (int)count(); i++ )
+ setSelected( i, select );
+ blockSignals( b );
+ emit selectionChanged();
+ } else if ( d->current ) {
+ TQListBoxItem * i = d->current;
+ setSelected( i, select );
+ }
+}
+
+/*!
+ Inverts the selection. Only works in \c Multi and \c Extended
+ selection mode.
+*/
+
+void TQListBox::invertSelection()
+{
+ if ( d->selectionMode == Single ||
+ d->selectionMode == NoSelection )
+ return;
+
+ bool b = tqsignalsBlocked();
+ blockSignals( TRUE );
+ for ( int i = 0; i < (int)count(); i++ )
+ setSelected( i, !item( i )->isSelected() );
+ blockSignals( b );
+ emit selectionChanged();
+}
+
+
+/*!
+ \obsolete
+ Not used anymore; provided for binary compatibility
+*/
+
+void TQListBox::emitChangedSignal( bool )
+{
+}
+
+
+/*! \reimp */
+
+TQSize TQListBox::tqsizeHint() const
+{
+ if ( cachedSizeHint().isValid() )
+ return cachedSizeHint();
+
+ constPolish();
+ doLayout();
+
+ int i=0;
+ while( i < 10 &&
+ i < (int)d->columnPos.size()-1 &&
+ d->columnPos[i] < 200 )
+ i++;
+ int x;
+ x = TQMIN( 200, d->columnPos[i] +
+ 2 * tqstyle().tqpixelMetric( TQStyle::PM_DefaultFrameWidth ) );
+ x = TQMAX( 40, x );
+
+ i = 0;
+ while( i < 10 &&
+ i < (int)d->rowPos.size()-1 &&
+ d->rowPos[i] < 200 )
+ i++;
+ int y;
+ y = TQMIN( 200, d->rowPos[i] +
+ 2 * tqstyle().tqpixelMetric( TQStyle::PM_DefaultFrameWidth ) );
+ y = TQMAX( 40, y );
+
+ TQSize s( x, y );
+ setCachedSizeHint( s );
+ return s;
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQListBox::tqminimumSizeHint() const
+{
+ return TQScrollView::tqminimumSizeHint();
+}
+
+
+/*!
+ Ensures that a single paint event will occur at the end of the
+ current event loop iteration. If \a doLayout is TRUE, the tqlayout
+ is also redone.
+*/
+
+void TQListBox::triggerUpdate( bool doLayout )
+{
+ if ( doLayout )
+ d->layoutDirty = d->mustPaintAll = TRUE;
+ d->updateTimer->start( 0, TRUE );
+}
+
+
+void TQListBox::setColumnMode( LayoutMode mode )
+{
+ if ( mode == Variable )
+ return;
+ d->rowModeWins = FALSE;
+ d->columnMode = mode;
+ triggerUpdate( TRUE );
+}
+
+
+void TQListBox::setColumnMode( int columns )
+{
+ if ( columns < 1 )
+ columns = 1;
+ d->columnMode = FixedNumber;
+ d->numColumns = columns;
+ d->rowModeWins = FALSE;
+ triggerUpdate( TRUE );
+}
+
+void TQListBox::setRowMode( LayoutMode mode )
+{
+ if ( mode == Variable )
+ return;
+ d->rowModeWins = TRUE;
+ d->rowMode = mode;
+ triggerUpdate( TRUE );
+}
+
+
+void TQListBox::setRowMode( int rows )
+{
+ if ( rows < 1 )
+ rows = 1;
+ d->rowMode = FixedNumber;
+ d->numRows = rows;
+ d->rowModeWins = TRUE;
+ triggerUpdate( TRUE );
+}
+
+/*!
+ \property TQListBox::columnMode
+ \brief the column tqlayout mode for this list box.
+
+ setColumnMode() sets the tqlayout mode and adjusts the number of
+ displayed columns. The row tqlayout mode automatically becomes \c
+ Variable, unless the column mode is \c Variable.
+
+ \sa setRowMode() columnMode() rowMode numColumns
+*/
+
+
+TQListBox::LayoutMode TQListBox::columnMode() const
+{
+ if ( d->rowModeWins )
+ return Variable;
+ else
+ return d->columnMode;
+}
+
+
+/*!
+ \property TQListBox::rowMode
+ \brief the row tqlayout mode for this list box
+
+ This property is normally \c Variable.
+
+ setRowMode() sets the tqlayout mode and adjusts the number of
+ displayed rows. The column tqlayout mode automatically becomes \c
+ Variable, unless the row mode is \c Variable.
+
+ \sa columnMode rowMode
+*/
+
+
+TQListBox::LayoutMode TQListBox::rowMode() const
+{
+ if ( d->rowModeWins )
+ return d->rowMode;
+ else
+ return Variable;
+}
+
+
+/*!
+ \property TQListBox::numColumns
+ \brief the number of columns in the list box
+
+ This is normally 1, but can be different if \l
+ TQListBox::columnMode or \l TQListBox::rowMode has been set.
+
+ \sa columnMode rowMode numRows
+*/
+
+int TQListBox::numColumns() const
+{
+ if ( count() == 0 )
+ return 0;
+ if ( !d->rowModeWins && d->columnMode == FixedNumber )
+ return d->numColumns;
+ doLayout();
+ return d->columnPos.size()-1;
+}
+
+
+/*!
+ \property TQListBox::numRows
+ \brief the number of rows in the list box.
+
+ This is equal to the number of items in the default single-column
+ tqlayout, but can be different.
+
+ \sa columnMode rowMode numColumns
+*/
+
+int TQListBox::numRows() const
+{
+ if ( count() == 0 )
+ return 0;
+ if ( d->rowModeWins && d->rowMode == FixedNumber )
+ return d->numRows;
+ doLayout();
+ return d->rowPos.size()-1;
+}
+
+
+/*!
+ This function does the hard tqlayout work. You should never need to
+ call it.
+*/
+
+void TQListBox::doLayout() const
+{
+ if ( !d->layoutDirty || d->resizeTimer->isActive() )
+ return;
+ constPolish();
+ int c = count();
+ switch( rowMode() ) {
+ case FixedNumber:
+ // columnMode() is known to be Variable
+ tryGeometry( d->numRows, (c+d->numRows-1)/d->numRows );
+ break;
+ case FitToHeight:
+ // columnMode() is known to be Variable
+ if ( d->head ) {
+ // this is basically the FitToWidth code, but edited to use rows.
+ int maxh = 0;
+ TQListBoxItem * i = d->head;
+ while ( i ) {
+ int h = i->height(this);
+ if ( maxh < h )
+ maxh = h;
+ i = i->n;
+ }
+ int vh = viewportSize( 1, 1 ).height();
+ do {
+ int rows = vh / maxh;
+ if ( rows > c )
+ rows = c;
+ if ( rows < 1 )
+ rows = 1;
+ if ( variableHeight() && rows < c ) {
+ do {
+ ++rows;
+ tryGeometry( rows, (c+rows-1)/rows );
+ } while ( rows <= c &&
+ d->rowPos[(int)d->rowPos.size()-1] <= vh );
+ --rows;
+ }
+ tryGeometry( rows, (c+rows-1)/rows );
+ int nvh = viewportSize( d->columnPos[(int)d->columnPos.size()-1],
+ d->rowPos[(int)d->rowPos.size()-1] ).height();
+ if ( nvh < vh )
+ vh = nvh;
+ } while ( d->rowPos.size() > 2 &&
+ vh < d->rowPos[(int)d->rowPos.size()-1] );
+ } else {
+ tryGeometry( 1, 1 );
+ }
+ break;
+ case Variable:
+ if ( columnMode() == FixedNumber ) {
+ tryGeometry( (count()+d->numColumns-1)/d->numColumns,
+ d->numColumns );
+ } else if ( d->head ) { // FitToWidth, at least one item
+ int maxw = 0;
+ TQListBoxItem * i = d->head;
+ while ( i ) {
+ int w = i->width(this);
+ if ( maxw < w )
+ maxw = w;
+ i = i->n;
+ }
+ int vw = viewportSize( 1, 1 ).width();
+ do {
+ int cols = vw / maxw;
+ if ( cols > c )
+ cols = c;
+ if ( cols < 1 )
+ cols = 1;
+ if ( variableWidth() && cols < c ) {
+ do {
+ ++cols;
+ tryGeometry( (c+cols-1)/cols, cols );
+ } while ( cols <= c &&
+ d->columnPos[(int)d->columnPos.size()-1] <= vw );
+ --cols;
+ }
+ tryGeometry( (c+cols-1)/cols, cols );
+ int nvw = viewportSize( d->columnPos[(int)d->columnPos.size()-1],
+ d->rowPos[(int)d->rowPos.size()-1] ).width();
+ if ( nvw < vw )
+ vw = nvw;
+ } while ( d->columnPos.size() > 2 &&
+ vw < d->columnPos[(int)d->columnPos.size()-1] );
+ } else {
+ tryGeometry( 1, 1 );
+ }
+ break;
+ }
+
+ d->layoutDirty = FALSE;
+ int w = d->columnPos[(int)d->columnPos.size()-1];
+ int h = d->rowPos[(int)d->rowPos.size()-1];
+ TQSize s( viewportSize( w, h ) );
+ w = TQMAX( w, s.width() );
+
+ d->columnPosOne = d->columnPos[1];
+ // extend the column for simple single-column listboxes
+ if ( columnMode() == FixedNumber && d->numColumns == 1 &&
+ d->columnPos[1] < w )
+ d->columnPos[1] = w;
+ ((TQListBox *)this)->resizeContents( w, h );
+}
+
+
+/*!
+ Lay the items out in a \a columns by \a rows array. The array may
+ be too big: doLayout() is expected to call this with the right
+ values.
+*/
+
+void TQListBox::tryGeometry( int rows, int columns ) const
+{
+ if ( columns < 1 )
+ columns = 1;
+ d->columnPos.resize( columns+1 );
+
+ if ( rows < 1 )
+ rows = 1;
+ d->rowPos.resize( rows+1 );
+
+ // funky hack I: dump the height/width of each column/row in
+ // {column,row}Pos for later conversion to positions.
+ int c;
+ for( c=0; c<=columns; c++ )
+ d->columnPos[c] = 0;
+ int r;
+ for( r=0; r<=rows; r++ )
+ d->rowPos[r] = 0;
+ r = c = 0;
+ TQListBoxItem * i = d->head;
+ while ( i && c < columns ) {
+ if ( i == d->current ) {
+ d->currentRow = r;
+ d->currentColumn = c;
+ }
+
+ int w = i->width(this);
+ if ( d->columnPos[c] < w )
+ d->columnPos[c] = w;
+ int h = i->height(this);
+ if ( d->rowPos[r] < h )
+ d->rowPos[r] = h;
+ i = i->n;
+ r++;
+ if ( r == rows ) {
+ r = 0;
+ c++;
+ }
+ }
+ // funky hack II: if not variable {width,height}, unvariablify it.
+ if ( !variableWidth() ) {
+ int w = 0;
+ for( c=0; c<columns; c++ )
+ if ( w < d->columnPos[c] )
+ w = d->columnPos[c];
+ for( c=0; c<columns; c++ )
+ d->columnPos[c] = w;
+ }
+ if ( !variableHeight() ) {
+ int h = 0;
+ for( r=0; r<rows; r++ )
+ if ( h < d->rowPos[r] )
+ h = d->rowPos[r];
+ for( r=0; r<rows; r++ )
+ d->rowPos[r] = h;
+ }
+ // repair the hacking.
+ int x = 0;
+ for( c=0; c<=columns; c++ ) {
+ int w = d->columnPos[c];
+ d->columnPos[c] = x;
+ x += w;
+ }
+ int y = 0;
+ for( r=0; r<=rows; r++ ) {
+ int h = d->rowPos[r];
+ d->rowPos[r] = y;
+ y += h;
+ }
+}
+
+
+/*!
+ Returns the row index of the current item, or -1 if no item is the
+ current item.
+*/
+
+int TQListBox::currentRow() const
+{
+ if ( !d->current )
+ return -1;
+ if ( d->currentRow < 0 )
+ d->layoutDirty = TRUE;
+ if ( d->layoutDirty )
+ doLayout();
+ return d->currentRow;
+}
+
+
+/*!
+ Returns the column index of the current item, or -1 if no item is
+ the current item.
+*/
+
+int TQListBox::currentColumn() const
+{
+ if ( !d->current )
+ return -1;
+ if ( d->currentColumn < 0 )
+ d->layoutDirty = TRUE;
+ if ( d->layoutDirty )
+ doLayout();
+ return d->currentColumn;
+}
+
+
+void TQListBox::setTopItem( int index )
+{
+ if ( index >= (int)count() || count() == 0 )
+ return;
+ int col = index / numRows();
+ int y = d->rowPos[index-col*numRows()];
+ if ( d->columnPos[col] >= contentsX() &&
+ d->columnPos[col+1] <= contentsX() + visibleWidth() )
+ setContentsPos( contentsX(), y );
+ else
+ setContentsPos( d->columnPos[col], y );
+}
+
+/*!
+ Scrolls the list box so the item at position \a index in the list
+ is displayed in the bottom row of the list box.
+
+ \sa setTopItem()
+*/
+
+void TQListBox::setBottomItem( int index )
+{
+ if ( index >= (int)count() || count() == 0 )
+ return;
+ int col = index / numRows();
+ int y = d->rowPos[1+index-col*numRows()] - visibleHeight();
+ if ( y < 0 )
+ y = 0;
+ if ( d->columnPos[col] >= contentsX() &&
+ d->columnPos[col+1] <= contentsX() + visibleWidth() )
+ setContentsPos( contentsX(), y );
+ else
+ setContentsPos( d->columnPos[col], y );
+}
+
+
+/*!
+ Returns the item at point \a p, specified in viewport coordinates,
+ or a 0 if there is no item at \a p.
+
+ Use contentsToViewport() to convert between widget coordinates and
+ viewport coordinates.
+*/
+
+TQListBoxItem * TQListBox::itemAt( const TQPoint& p ) const
+{
+ if ( d->layoutDirty )
+ doLayout();
+ TQPoint np = p;
+
+ // take into acount frame margin to get to viewport
+ np -= viewport()->pos();
+ if (!TQT_TQRECT_OBJECT(viewport()->rect()).tqcontains(np))
+ return 0;
+
+ // take into account contents position
+ np = viewportToContents( np );
+
+ int x = np.x();
+ int y = np.y();
+
+ // return 0 when y is below the last row
+ if ( y > d->rowPos[ numRows() ] )
+ return 0;
+
+ int col = columnAt( x );
+ int row = rowAt( y );
+
+ TQListBoxItem *i = item( col * numRows() + row );
+ if ( i && numColumns() > 1 ) {
+ if ( d->columnPos[ col ] + i->width( this ) >= x )
+ return i;
+ } else {
+ if ( d->columnPos[ col + 1 ] >= x )
+ return i;
+ }
+ return 0;
+}
+
+
+/*!
+ Ensures that the current item is visible.
+*/
+
+void TQListBox::ensureCurrentVisible()
+{
+ if ( !d->current )
+ return;
+
+ doLayout();
+
+ int row = currentRow();
+ int column = currentColumn();
+ int w = ( d->columnPos[column+1] - d->columnPos[column] ) / 2;
+ int h = ( d->rowPos[row+1] - d->rowPos[row] ) / 2;
+ // next four lines are Bad. they mean that for pure left-to-right
+ // languages, textual list box items are displayed better than
+ // before when there is little space. for non-textual items, or
+ // other languages, it means... that you really should have enough
+ // space in the first place :)
+ if ( numColumns() == 1 )
+ w = 0;
+ if ( w*2 > viewport()->width() )
+ w = viewport()->width()/2;
+
+ ensureVisible( d->columnPos[column] + w, d->rowPos[row] + h, w, h);
+}
+
+
+/*! \internal */
+
+void TQListBox::doAutoScroll()
+{
+ if ( d->scrollPos.x() < 0 ) {
+ // scroll left
+ int x = contentsX() - horizontalScrollBar()->lineStep();
+ if ( x < 0 )
+ x = 0;
+ if ( x != contentsX() ) {
+ d->mouseMoveColumn = columnAt( x );
+ updateSelection();
+ if ( x < contentsX() )
+ setContentsPos( x, contentsY() );
+ }
+ } else if ( d->scrollPos.x() > 0 ) {
+ // scroll right
+ int x = contentsX() + horizontalScrollBar()->lineStep();
+ if ( x + visibleWidth() > contentsWidth() )
+ x = contentsWidth() - visibleWidth();
+ if ( x != contentsX() ) {
+ d->mouseMoveColumn = columnAt( x + visibleWidth() - 1 );
+ updateSelection();
+ if ( x > contentsX() )
+ setContentsPos( x, contentsY() );
+ }
+ }
+
+ if ( d->scrollPos.y() < 0 ) {
+ // scroll up
+ int y = contentsY() - verticalScrollBar()->lineStep();
+ if ( y < 0 )
+ y = 0;
+ if ( y != contentsY() ) {
+ y = contentsY() - verticalScrollBar()->lineStep();
+ d->mouseMoveRow = rowAt( y );
+ updateSelection();
+ }
+ } else if ( d->scrollPos.y() > 0 ) {
+ // scroll down
+ int y = contentsY() + verticalScrollBar()->lineStep();
+ if ( y + visibleHeight() > contentsHeight() )
+ y = contentsHeight() - visibleHeight();
+ if ( y != contentsY() ) {
+ y = contentsY() + verticalScrollBar()->lineStep();
+ d->mouseMoveRow = rowAt(y + visibleHeight() - 1 );
+ updateSelection();
+ }
+ }
+
+ if ( d->scrollPos == TQPoint( 0, 0 ) ) {
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ }
+}
+
+
+/*!
+ \property TQListBox::topItem
+ \brief the index of an item at the top of the screen.
+
+ When getting this property and the listbox has multiple columns,
+ an arbitrary item is selected and returned.
+
+ When setting this property, the list box is scrolled so the item
+ at position \e index in the list is displayed in the top row of
+ the list box.
+*/
+
+int TQListBox::topItem() const
+{
+ doLayout();
+
+ // move rightwards to the best column
+ int col = columnAt( contentsX() );
+ int row = rowAt( contentsY() );
+ return col * numRows() + row;
+}
+
+
+/*!
+ \property TQListBox::variableHeight
+ \brief whether this list box has variable-height rows
+
+ When the list box has variable-height rows (the default), each row
+ is as high as the highest item in that row. When it has same-sized
+ rows, all rows are as high as the highest item in the list box.
+
+ \sa variableWidth
+*/
+
+bool TQListBox::variableHeight() const
+{
+ return d->variableHeight;
+}
+
+
+void TQListBox::setVariableHeight( bool enable )
+{
+ if ( (bool)d->variableHeight == enable )
+ return;
+
+ d->variableHeight = enable;
+ triggerUpdate( TRUE );
+}
+
+
+/*!
+ \property TQListBox::variableWidth
+ \brief whether this list box has variable-width columns
+
+ When the list box has variable-width columns, each column is as
+ wide as the widest item in that column. When it has same-sized
+ columns (the default), all columns are as wide as the widest item
+ in the list box.
+
+ \sa variableHeight
+*/
+
+bool TQListBox::variableWidth() const
+{
+ return d->variableWidth;
+}
+
+
+void TQListBox::setVariableWidth( bool enable )
+{
+ if ( (bool)d->variableWidth == enable )
+ return;
+
+ d->variableWidth = enable;
+ triggerUpdate( TRUE );
+}
+
+
+/*!
+ Repaints only what really needs to be repainted.
+*/
+void TQListBox::refreshSlot()
+{
+ if ( d->mustPaintAll ||
+ d->layoutDirty ) {
+ d->mustPaintAll = FALSE;
+ bool currentItemVisible = itemVisible( currentItem() );
+ doLayout();
+ if ( hasFocus() &&
+ currentItemVisible &&
+ d->currentColumn >= 0 &&
+ d->currentRow >= 0 &&
+ ( d->columnPos[d->currentColumn] < contentsX() ||
+ d->columnPos[d->currentColumn+1]>contentsX()+visibleWidth() ||
+ d->rowPos[d->currentRow] < contentsY() ||
+ d->rowPos[d->currentRow+1] > contentsY()+visibleHeight() ) )
+ ensureCurrentVisible();
+ viewport()->tqrepaint( FALSE );
+ return;
+ }
+
+ TQRegion r;
+ int x = contentsX();
+ int y = contentsY();
+ int col = columnAt( x );
+ int row = rowAt( y );
+ int top = row;
+ while( col < (int)d->columnPos.size()-1 && d->columnPos[col+1] < x )
+ col++;
+ while( top < (int)d->rowPos.size()-1 && d->rowPos[top+1] < y )
+ top++;
+ TQListBoxItem * i = item( col * numRows() + row );
+
+ while ( i && (int)col < numColumns() &&
+ d->columnPos[col] < x + visibleWidth() ) {
+ int cw = d->columnPos[col+1] - d->columnPos[col];
+ while ( i && row < numRows() && d->rowPos[row] <
+ y + visibleHeight() ) {
+ if ( i->dirty )
+ r = r.unite( TQRect( d->columnPos[col] - x, d->rowPos[row] - y,
+ cw, d->rowPos[row+1] - d->rowPos[row] ) );
+ row++;
+ i = i->n;
+ }
+ col++;
+ if ( numColumns() > 1 ) {
+ row = top;
+ i = item( col * numRows() + row );
+ }
+ }
+
+ if ( r.isEmpty() )
+ viewport()->tqrepaint( FALSE );
+ else
+ viewport()->tqrepaint( r, FALSE );
+}
+
+
+/*! \reimp */
+
+void TQListBox::viewportPaintEvent( TQPaintEvent * e )
+{
+ doLayout();
+ TQWidget* vp = viewport();
+ TQPainter p( vp );
+ TQRegion r = e->region();
+
+#if 0
+ {
+ // this stuff has been useful enough times that from now I'm
+ // leaving it in the source.
+ uint i = 0;
+ qDebug( "%s/%s: %i rects", className(), name(), r.rects().size() );
+ while( i < r.rects().size() ) {
+ qDebug( "rect %d: %d, %d, %d, %d", i,
+ r.rects()[i].left(), r.rects()[i].top(),
+ r.rects()[i].width(), r.rects()[i].height() );
+ i++;
+ }
+ qDebug( "" );
+ }
+#endif
+
+ int x = contentsX();
+ int y = contentsY();
+ int w = vp->width();
+ int h = vp->height();
+
+ int col = columnAt( x );
+ int top = rowAt( y );
+ int row = top;
+
+ TQListBoxItem * i = item( col*numRows() + row );
+
+ const TQColorGroup & g = tqcolorGroup();
+ p.setPen( g.text() );
+ p.setBackgroundColor( backgroundBrush().color() );
+ while ( i && (int)col < numColumns() && d->columnPos[col] < x + w ) {
+ int cw = d->columnPos[col+1] - d->columnPos[col];
+ while ( i && (int)row < numRows() && d->rowPos[row] < y + h ) {
+ int ch = d->rowPos[row+1] - d->rowPos[row];
+ TQRect tqitemRect( d->columnPos[col]-x, d->rowPos[row]-y, cw, ch );
+ TQRegion tempRegion( tqitemRect );
+ TQRegion itemPaintRegion( tempRegion.intersect( r ) );
+ if ( !itemPaintRegion.isEmpty() ) {
+ p.save();
+ p.setClipRegion( itemPaintRegion );
+ p.translate( d->columnPos[col]-x, d->rowPos[row]-y );
+ paintCell( &p, row, col );
+ p.restore();
+ r = r.subtract( itemPaintRegion );
+ }
+ row++;
+ if ( i->dirty ) {
+ // reset dirty flag only if the entire item was painted
+ if ( itemPaintRegion == TQRegion( tqitemRect ) )
+ i->dirty = FALSE;
+ }
+ i = i->n;
+ }
+ col++;
+ if ( numColumns() > 1 ) {
+ row = top;
+ i = item( col * numRows() + row );
+ }
+ }
+
+ if ( r.isEmpty() )
+ return;
+ p.setClipRegion( r );
+ p.fillRect( 0, 0, w, h, viewport()->backgroundBrush() );
+}
+
+
+/*!
+ Returns the height in pixels of the item with index \a index. \a
+ index defaults to 0.
+
+ If \a index is too large, this function returns 0.
+*/
+
+int TQListBox::itemHeight( int index ) const
+{
+ if ( index >= (int)count() || index < 0 )
+ return 0;
+ int r = index % numRows();
+ return d->rowPos[r+1] - d->rowPos[r];
+}
+
+
+/*!
+ Returns the index of the column at \a x, which is in the listbox's
+ coordinates, not in on-screen coordinates.
+
+ If there is no column that spans \a x, columnAt() returns -1.
+*/
+
+int TQListBox::columnAt( int x ) const
+{
+ if ( x < 0 )
+ return -1;
+ if ( !d->columnPos.size() )
+ return -1;
+ if ( x >= d->columnPos[(int)d->columnPos.size()-1 ] )
+ return numColumns() - 1;
+
+ int col = 0;
+ while( col < (int)d->columnPos.size()-1 && d->columnPos[col+1] < x )
+ col++;
+ return col;
+}
+
+
+/*!
+ Returns the index of the row at \a y, which is in the listbox's
+ coordinates, not in on-screen coordinates.
+
+ If there is no row that spans \a y, rowAt() returns -1.
+*/
+
+int TQListBox::rowAt( int y ) const
+{
+ if ( y < 0 )
+ return -1;
+
+ // tqfind the top item, use bsearch for speed
+ int l = 0;
+ int r = d->rowPos.size() - 2;
+ if ( r < 0 )
+ return -1;
+ if ( l <= d->rowPosCache && d->rowPosCache <= r ) {
+ if ( d->rowPos[ TQMAX( l, d->rowPosCache - 10 ) ] <= y
+ && y <= d->rowPos[ TQMIN( r, d->rowPosCache + 10 ) ] ) {
+ l = TQMAX( l, d->rowPosCache - 10 );
+ r = TQMIN( r, d->rowPosCache + 10 );
+ }
+ }
+ int i = ( (l+r+1) / 2 );
+ while ( r - l ) {
+ if ( d->rowPos[i] > y )
+ r = i -1;
+ else
+ l = i;
+ i = ( (l+r+1) / 2 );
+ }
+ d->rowPosCache = i;
+ if ( d->rowPos[i] <= y && y <= d->rowPos[i+1] )
+ return i;
+
+ return d->count - 1;
+}
+
+
+/*!
+ Returns the rectangle on the screen that \a item occupies in
+ viewport()'s coordinates, or an invalid rectangle if \a item is 0
+ or is not currently visible.
+*/
+
+TQRect TQListBox::tqitemRect( TQListBoxItem *item ) const
+{
+ if ( d->resizeTimer->isActive() )
+ return TQRect( 0, 0, -1, -1 );
+ if ( !item )
+ return TQRect( 0, 0, -1, -1 );
+
+ int i = index( item );
+ int col = i / numRows();
+ int row = i % numRows();
+
+ int x = d->columnPos[ col ] - contentsX();
+ int y = d->rowPos[ row ] - contentsY();
+
+ TQRect r( x, y, d->columnPos[ col + 1 ] - d->columnPos[ col ],
+ d->rowPos[ row + 1 ] - d->rowPos[ row ] );
+ if ( r.intersects( TQRect( 0, 0, visibleWidth(), visibleHeight() ) ) )
+ return r;
+ return TQRect( 0, 0, -1, -1 );
+}
+
+
+#ifndef TQT_NO_COMPAT
+
+/*!
+ \obsolete
+
+ Using this method is quite inefficient. We suggest to use insertItem()
+ for inserting and sort() afterwards.
+
+ Inserts \a lbi at its sorted position in the list box and returns the
+ position.
+
+ All items must be inserted with inSort() to maintain the sorting
+ order. inSort() treats any pixmap (or user-defined type) as
+ lexicographically less than any string.
+
+ \sa insertItem(), sort()
+*/
+int TQListBox::inSort( const TQListBoxItem * lbi )
+{
+ qObsolete( "TQListBox", "inSort", "insertItem" );
+ if ( !lbi )
+ return -1;
+
+ TQListBoxItem * i = d->head;
+ int c = 0;
+
+ while( i && i->text() < lbi->text() ) {
+ i = i->n;
+ c++;
+ }
+ insertItem( lbi, c );
+ return c;
+}
+
+/*!
+ \obsolete
+ \overload
+ Using this method is quite inefficient. We suggest to use insertItem()
+ for inserting and sort() afterwards.
+
+ Inserts a new item of \a text at its sorted position in the list box and
+ returns the position.
+
+ All items must be inserted with inSort() to maintain the sorting
+ order. inSort() treats any pixmap (or user-defined type) as
+ lexicographically less than any string.
+
+ \sa insertItem(), sort()
+*/
+int TQListBox::inSort( const TQString& text )
+{
+ qObsolete( "TQListBox", "inSort", "insertItem" );
+ return inSort( new TQListBoxText(text) );
+}
+
+#endif
+
+
+/*! \reimp */
+
+void TQListBox::resizeEvent( TQResizeEvent *e )
+{
+ d->layoutDirty = ( d->layoutDirty ||
+ rowMode() == FitToHeight ||
+ columnMode() == FitToWidth );
+
+ if ( !d->layoutDirty && columnMode() == FixedNumber &&
+ d->numColumns == 1) {
+ int w = d->columnPosOne;
+ TQSize s( viewportSize( w, contentsHeight() ) );
+ w = TQMAX( w, s.width() );
+ d->columnPos[1] = TQMAX( w, d->columnPosOne );
+ resizeContents( d->columnPos[1], contentsHeight() );
+ }
+
+ if ( d->resizeTimer->isActive() )
+ d->resizeTimer->stop();
+ if ( d->rowMode == FixedNumber && d->columnMode == FixedNumber ) {
+ bool currentItemVisible = itemVisible( currentItem() );
+ doLayout();
+ TQScrollView::resizeEvent( e );
+ if ( currentItemVisible )
+ ensureCurrentVisible();
+ if ( d->current )
+ viewport()->tqrepaint( tqitemRect( d->current ), FALSE );
+ } else if ( ( d->columnMode == FitToWidth || d->rowMode == FitToHeight ) && !(isVisible()) ) {
+ TQScrollView::resizeEvent( e );
+ } else if ( d->layoutDirty ) {
+ d->resizeTimer->start( 100, TRUE );
+ resizeContents( contentsWidth() - ( e->oldSize().width() - e->size().width() ),
+ contentsHeight() - ( e->oldSize().height() - e->size().height() ) );
+ TQScrollView::resizeEvent( e );
+ } else {
+ TQScrollView::resizeEvent( e );
+ }
+}
+
+/*!
+ \internal
+*/
+
+void TQListBox::adjustItems()
+{
+ triggerUpdate( TRUE );
+ ensureCurrentVisible();
+}
+
+
+/*!
+ Provided for compatibility with the old TQListBox. We recommend
+ using TQListBoxItem::paint() instead.
+
+ Repaints the cell at \a row, \a col using painter \a p.
+*/
+
+void TQListBox::paintCell( TQPainter * p, int row, int col )
+{
+ bool drawActiveSelection = hasFocus() || d->inMenuMode ||
+ !tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this );
+ const TQColorGroup &g = ( drawActiveSelection ? tqcolorGroup() : tqpalette().inactive() );
+
+ int cw = d->columnPos[col+1] - d->columnPos[col];
+ int ch = d->rowPos[row+1] - d->rowPos[row];
+ TQListBoxItem * i = item( col*numRows()+row );
+ p->save();
+ if ( i->s ) {
+ if ( i->custom_highlight ) {
+ p->fillRect( 0, 0, cw, ch,
+ g.brush( TQPalette::backgroundRoleFromMode( viewport()->backgroundMode() ) ) );
+ p->setPen( g.highlightedText() );
+ p->setBackgroundColor( g.highlight() );
+ }
+ else if ( numColumns() == 1 ) {
+ p->fillRect( 0, 0, cw, ch, g.brush( TQColorGroup::Highlight ) );
+ p->setPen( g.highlightedText() );
+ p->setBackgroundColor( g.highlight() );
+ } else {
+ int iw = i->width( this );
+ p->fillRect( 0, 0, iw, ch, g.brush( TQColorGroup::Highlight ) );
+ p->fillRect( iw, 0, cw - iw + 1, ch,
+ g.brush( TQPalette::backgroundRoleFromMode( viewport()->backgroundMode() ) ) );
+ p->setPen( g.highlightedText() );
+ p->setBackgroundColor( g.highlight() );
+ }
+ } else {
+ p->fillRect( 0, 0, cw, ch,
+ g.brush( TQPalette::backgroundRoleFromMode( viewport()->backgroundMode() ) ) );
+ }
+
+ i->paint( p );
+
+ if ( d->current == i && hasFocus() && !i->custom_highlight ) {
+ if ( numColumns() > 1 )
+ cw = i->width( this );
+
+ tqstyle().tqdrawPrimitive( TQStyle::PE_FocusRect, p, TQRect( 0, 0, cw, ch ), g,
+ TQStyle::Style_FocusAtBorder,
+ TQStyleOption(i->isSelected() ? g.highlight() : g.base() ) );
+ }
+
+ p->restore();
+}
+
+/*!
+ Returns the width of the widest item in the list box.
+*/
+
+long TQListBox::maxItemWidth() const
+{
+ if ( d->layoutDirty )
+ doLayout();
+ long m = 0;
+ int i = d->columnPos.size();
+ while( i-- )
+ if ( m < d->columnPos[i] )
+ m = d->columnPos[i];
+ return m;
+}
+
+
+/*! \reimp */
+
+void TQListBox::showEvent( TQShowEvent * )
+{
+ d->ignoreMoves = FALSE;
+ d->mousePressRow = -1;
+ d->mousePressColumn = -1;
+ d->mustPaintAll = FALSE;
+ ensureCurrentVisible();
+}
+
+#ifndef TQT_NO_COMPAT
+
+/*!
+ \obsolete
+
+ Returns the vertical pixel-coordinate in \a *yPos, of the list box
+ item at position \a index in the list. Returns FALSE if the item is
+ outside the visible area.
+*/
+bool TQListBox::itemYPos( int index, int *yPos ) const
+{
+ qObsolete( "TQListBox", "itemYPos" );
+ TQListBoxItem* i = item(index);
+ if ( !i )
+ return FALSE;
+ if ( yPos )
+ *yPos = i->y;
+ return TRUE;
+}
+
+#endif
+
+/*!
+ \fn bool TQListBoxItem::isSelected() const
+
+ Returns TRUE if the item is selected; otherwise returns FALSE.
+
+ \sa TQListBox::isSelected(), isCurrent()
+*/
+
+/*!
+ \fn bool TQListBoxItem::selected() const
+ \obsolete
+*/
+
+/*!
+ Returns TRUE if the item is the current item; otherwise returns
+ FALSE.
+
+ \sa TQListBox::currentItem(), TQListBox::item(), isSelected()
+*/
+bool TQListBoxItem::isCurrent() const
+{
+ return listBox() && listBox()->hasFocus() &&
+ listBox()->item( listBox()->currentItem() ) == this;
+}
+/*!
+ \fn bool TQListBoxItem::current() const
+ \obsolete
+*/
+
+/*!
+ \fn void TQListBox::centerCurrentItem()
+ \obsolete
+
+ This function does exactly the same as ensureCurrentVisible()
+
+ \sa TQListBox::ensureCurrentVisible()
+*/
+
+/*!
+ Returns a pointer to the list box containing this item.
+*/
+
+TQListBox * TQListBoxItem::listBox() const
+{
+ return lbox;
+}
+
+
+/*!
+ Removes \a item from the list box and causes an update of the
+ screen display. The item is not deleted. You should normally not
+ need to call this function because TQListBoxItem::~TQListBoxItem()
+ calls it. The normal way to delete an item is with \c delete.
+
+ \sa TQListBox::insertItem()
+*/
+void TQListBox::takeItem( const TQListBoxItem * item )
+{
+ if ( !item || d->clearing )
+ return;
+ d->cache = 0;
+ d->count--;
+ if ( item == d->last )
+ d->last = d->last->p;
+ if ( item->p && item->p->n == item )
+ item->p->n = item->n;
+ if ( item->n && item->n->p == item )
+ item->n->p = item->p;
+ if ( d->head == item ) {
+ d->head = item->n;
+ d->currentColumn = d->currentRow = -1;
+ }
+
+ if ( d->current == item ) {
+ d->current = item->n ? item->n : item->p;
+ TQListBoxItem *i = d->current;
+ TQString tmp;
+ if ( i )
+ tmp = i->text();
+ int tmp2 = index( i );
+ emit highlighted( i );
+ if ( !tmp.isNull() )
+ emit highlighted( tmp );
+ emit highlighted( tmp2 );
+ emit currentChanged( i );
+ }
+ if ( d->tmpCurrent == item )
+ d->tmpCurrent = d->current;
+ if ( d->selectAnchor == item )
+ d->selectAnchor = d->current;
+
+ if ( item->s )
+ emit selectionChanged();
+ ((TQListBoxItem *)item)->lbox = 0;
+ triggerUpdate( TRUE );
+}
+
+/*!
+ \internal
+ Finds the next item after start beginning with \a text.
+*/
+
+int TQListBoxPrivate::tqfindItemByName( int start, const TQString &text )
+{
+ if ( start < 0 || (uint)start >= listBox->count() )
+ start = 0;
+ TQString match = text.lower();
+ if ( match.length() < 1 )
+ return start;
+ TQString curText;
+ int item = start;
+ do {
+ curText = listBox->text( item ).lower();
+ if ( curText.startsWith( match ) )
+ return item;
+ item++;
+ if ( (uint)item == listBox->count() )
+ item = 0;
+ } while ( item != start );
+ return -1;
+}
+
+/*!
+ \internal --- obsolete!
+*/
+
+void TQListBox::clearInputString()
+{
+ d->currInputString = TQString::null;
+}
+
+/*!
+ Finds the first list box item that has the text \a text and
+ returns it, or returns 0 of no such item could be found.
+ The search starts from the current item if the current item exists,
+ otherwise it starts from the first list box item.
+ If \c ComparisonFlags are specified in \a compare then these flags
+ are used, otherwise the default is a case-insensitive, "begins
+ with" search.
+
+ \sa TQt::StringComparisonMode
+*/
+
+TQListBoxItem *TQListBox::tqfindItem( const TQString &text, TQt::ComparisonFlags compare ) const
+{
+ if ( text.isEmpty() )
+ return 0;
+
+ if ( compare == TQt::CaseSensitive || compare == 0 )
+ compare |= TQt::ExactMatch;
+
+ TQString itmtxt;
+ TQString comtxt = text;
+ if ( ! (compare & TQt::CaseSensitive ) )
+ comtxt = text.lower();
+
+ TQListBoxItem *item;
+ if ( d->current )
+ item = d->current;
+ else
+ item = d->head;
+
+ TQListBoxItem *beginsWithItem = 0;
+ TQListBoxItem *endsWithItem = 0;
+ TQListBoxItem *tqcontainsItem = 0;
+
+ if ( item ) {
+ for ( ; item; item = item->n ) {
+ if ( ! (compare & TQt::CaseSensitive) )
+ itmtxt = item->text().lower();
+ else
+ itmtxt = item->text();
+
+ if ( compare & TQt::ExactMatch && itmtxt == comtxt )
+ return item;
+ if ( compare & TQt::BeginsWith && !beginsWithItem && itmtxt.startsWith( comtxt ) )
+ beginsWithItem = tqcontainsItem = item;
+ if ( compare & TQt::EndsWith && !endsWithItem && itmtxt.endsWith( comtxt ) )
+ endsWithItem = tqcontainsItem = item;
+ if ( compare & TQt::Contains && !tqcontainsItem && itmtxt.tqcontains( comtxt ) )
+ tqcontainsItem = item;
+ }
+
+ if ( d->current && d->head ) {
+ item = d->head;
+ for ( ; item && item != d->current; item = item->n ) {
+ if ( ! (compare & TQt::CaseSensitive) )
+ itmtxt = item->text().lower();
+ else
+ itmtxt = item->text();
+
+ if ( compare & TQt::ExactMatch && itmtxt == comtxt )
+ return item;
+ if ( compare & TQt::BeginsWith && !beginsWithItem && itmtxt.startsWith( comtxt ) )
+ beginsWithItem = tqcontainsItem = item;
+ if ( compare & TQt::EndsWith && !endsWithItem && itmtxt.endsWith( comtxt ) )
+ endsWithItem = tqcontainsItem = item;
+ if ( compare & TQt::Contains && !tqcontainsItem && itmtxt.tqcontains( comtxt ) )
+ tqcontainsItem = item;
+ }
+ }
+ }
+
+ // Obey the priorities
+ if ( beginsWithItem )
+ return beginsWithItem;
+ else if ( endsWithItem )
+ return endsWithItem;
+ else if ( tqcontainsItem )
+ return tqcontainsItem;
+ return 0;
+}
+
+/*!
+ \internal
+*/
+
+void TQListBox::drawRubber()
+{
+ if ( !d->rubber )
+ return;
+ if ( !d->rubber->width() && !d->rubber->height() )
+ return;
+ TQPainter p( viewport() );
+ p.setRasterOp( TQt::NotROP );
+ tqstyle().tqdrawPrimitive( TQStyle::PE_RubberBand, &p, d->rubber->normalize(),
+ tqcolorGroup() );
+ p.end();
+}
+
+/*!
+ \internal
+*/
+
+void TQListBox::doRubberSelection( const TQRect &old, const TQRect &rubber )
+{
+ TQListBoxItem *i = d->head;
+ TQRect ir, pr;
+ bool changed = FALSE;
+ for ( ; i; i = i->n ) {
+ ir = tqitemRect( i );
+ if ( ir == TQRect( 0, 0, -1, -1 ) )
+ continue;
+ if ( i->isSelected() && !ir.intersects( rubber ) && ir.intersects( old ) ) {
+ i->s = FALSE;
+ pr = pr.unite( ir );
+ changed = TRUE;
+ } else if ( !i->isSelected() && ir.intersects( rubber ) ) {
+ if ( i->isSelectable() ) {
+ i->s = TRUE;
+ pr = pr.unite( ir );
+ changed = TRUE;
+ }
+ }
+ }
+ if ( changed ) {
+ emit selectionChanged();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::Selection );
+#endif
+ }
+ viewport()->tqrepaint( pr, TRUE );
+}
+
+
+/*!
+ Returns TRUE if the user is selecting items using a rubber band
+ rectangle; otherwise returns FALSE.
+*/
+
+bool TQListBox::isRubberSelecting() const
+{
+ return d->rubber != 0;
+}
+
+
+/*!
+ Returns the item that comes after this in the list box. If this is
+ the last item, 0 is returned.
+
+ \sa prev()
+*/
+
+TQListBoxItem *TQListBoxItem::next() const
+{
+ return n;
+}
+
+/*!
+ Returns the item which comes before this in the list box. If this
+ is the first item, 0 is returned.
+
+ \sa next()
+*/
+
+TQListBoxItem *TQListBoxItem::prev() const
+{
+ return p;
+}
+
+/*!
+ Returns the first item in this list box. If the list box is empty,
+ returns 0.
+*/
+
+TQListBoxItem *TQListBox::firstItem() const
+{
+ return d->head;
+}
+
+#if defined(TQ_C_CALLBACKS)
+extern "C" {
+#endif
+
+#ifdef TQ_OS_TEMP
+static int _cdecl cmpListBoxItems( const void *n1, const void *n2 )
+#else
+static int cmpListBoxItems( const void *n1, const void *n2 )
+#endif
+{
+ if ( !n1 || !n2 )
+ return 0;
+
+ TQListBoxPrivate::SortableItem *i1 = (TQListBoxPrivate::SortableItem *)n1;
+ TQListBoxPrivate::SortableItem *i2 = (TQListBoxPrivate::SortableItem *)n2;
+
+ return i1->item->text().localeAwareCompare( i2->item->text() );
+}
+
+#if defined(TQ_C_CALLBACKS)
+}
+#endif
+
+/*!
+ If \a ascending is TRUE sorts the items in ascending order;
+ otherwise sorts in descending order.
+
+ To compare the items, the text (TQListBoxItem::text()) of the items
+ is used.
+*/
+
+void TQListBox::sort( bool ascending )
+{
+ if ( count() == 0 )
+ return;
+
+ d->cache = 0;
+
+ TQListBoxPrivate::SortableItem *items = new TQListBoxPrivate::SortableItem[ count() ];
+
+ TQListBoxItem *item = d->head;
+ int i = 0;
+ for ( ; item; item = item->n )
+ items[ i++ ].item = item;
+
+ qsort( items, count(), sizeof( TQListBoxPrivate::SortableItem ), cmpListBoxItems );
+
+ TQListBoxItem *prev = 0;
+ item = 0;
+ if ( ascending ) {
+ for ( i = 0; i < (int)count(); ++i ) {
+ item = items[ i ].item;
+ if ( item ) {
+ item->p = prev;
+ item->dirty = TRUE;
+ if ( item->p )
+ item->p->n = item;
+ item->n = 0;
+ }
+ if ( i == 0 )
+ d->head = item;
+ prev = item;
+ }
+ } else {
+ for ( i = (int)count() - 1; i >= 0 ; --i ) {
+ item = items[ i ].item;
+ if ( item ) {
+ item->p = prev;
+ item->dirty = TRUE;
+ if ( item->p )
+ item->p->n = item;
+ item->n = 0;
+ }
+ if ( i == (int)count() - 1 )
+ d->head = item;
+ prev = item;
+ }
+ }
+ d->last = item;
+
+ delete [] items;
+
+ // We have to update explicitly in case the current "vieport" overlaps the
+ // new viewport we set (starting at (0,0)).
+ bool haveToUpdate = contentsX() < visibleWidth() || contentsY() < visibleHeight();
+ setContentsPos( 0, 0 );
+ if ( haveToUpdate )
+ updateContents( 0, 0, visibleWidth(), visibleHeight() );
+}
+
+void TQListBox::handleItemChange( TQListBoxItem *old, bool shift, bool control )
+{
+ if ( d->selectionMode == Single ) {
+ // nothing
+ } else if ( d->selectionMode == Extended ) {
+ if ( shift ) {
+ selectRange( d->selectAnchor ? d->selectAnchor : old,
+ d->current, FALSE, TRUE, (d->selectAnchor && !control) ? TRUE : FALSE );
+ } else if ( !control ) {
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ selectAll( FALSE );
+ blockSignals( block );
+ setSelected( d->current, TRUE );
+ }
+ } else if ( d->selectionMode == Multi ) {
+ if ( shift )
+ selectRange( old, d->current, TRUE, FALSE );
+ }
+}
+
+void TQListBox::selectRange( TQListBoxItem *from, TQListBoxItem *to, bool invert, bool includeFirst, bool clearSel )
+{
+ if ( !from || !to )
+ return;
+ if ( from == to && !includeFirst )
+ return;
+ TQListBoxItem *i = 0;
+ int index =0;
+ int f_idx = -1, t_idx = -1;
+ for ( i = d->head; i; i = i->n, index++ ) {
+ if ( i == from )
+ f_idx = index;
+ if ( i == to )
+ t_idx = index;
+ if ( f_idx != -1 && t_idx != -1 )
+ break;
+ }
+ if ( f_idx > t_idx ) {
+ i = from;
+ from = to;
+ to = i;
+ if ( !includeFirst )
+ to = to->prev();
+ } else {
+ if ( !includeFirst )
+ from = from->next();
+ }
+
+ bool changed = FALSE;
+ if ( clearSel ) {
+ for ( i = d->head; i && i != from; i = i->n ) {
+ if ( i->s ) {
+ i->s = FALSE;
+ changed = TRUE;
+ updateItem( i );
+ }
+ }
+ for ( i = to->n; i; i = i->n ) {
+ if ( i->s ) {
+ i->s = FALSE;
+ changed = TRUE;
+ updateItem( i );
+ }
+ }
+ }
+
+ for ( i = from; i; i = i->next() ) {
+ if ( !invert ) {
+ if ( !i->s && i->isSelectable() ) {
+ i->s = TRUE;
+ changed = TRUE;
+ updateItem( i );
+ }
+ } else {
+ bool sel = !i->s;
+ if ( ((bool)i->s != sel && sel && i->isSelectable()) || !sel ) {
+ i->s = sel;
+ changed = TRUE;
+ updateItem( i );
+ }
+ }
+ if ( i == to )
+ break;
+ }
+ if ( changed ) {
+ emit selectionChanged();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::Selection );
+#endif
+ }
+}
+
+/*! \reimp */
+void TQListBox::windowActivationChange( bool oldActive )
+{
+ if ( oldActive && d->scrollTimer )
+ d->scrollTimer->stop();
+ if ( tqpalette().active() != tqpalette().inactive() )
+ viewport()->update();
+ TQScrollView::windowActivationChange( oldActive );
+}
+
+int TQListBoxItem::RTTI = 0;
+
+/*!
+ Returns 0.
+
+ Make your derived classes return their own values for rtti(), and
+ you can distinguish between listbox items. You should use values
+ greater than 1000 preferably a large random number, to allow for
+ extensions to this class.
+*/
+
+int TQListBoxItem::rtti() const
+{
+ return RTTI;
+}
+
+#endif // TQT_NO_LISTBOX
diff --git a/tqtinterface/qt4/src/widgets/tqlistbox.h b/tqtinterface/qt4/src/widgets/tqlistbox.h
new file mode 100644
index 0000000..936c69a
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqlistbox.h
@@ -0,0 +1,436 @@
+/**********************************************************************
+**
+** Definition of TQListBox widget class
+**
+** Created : 941121
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLISTBOX_H
+#define TQLISTBOX_H
+
+#ifndef TQT_H
+#include "tqscrollview.h"
+#include "tqpixmap.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_LISTBOX
+
+
+class TQListBoxPrivate;
+class TQListBoxItem;
+class TQString;
+class TQStrList;
+class TQStringList;
+
+
+class TQ_EXPORT TQListBox : public TQScrollView
+{
+ friend class TQListBoxItem;
+ friend class TQListBoxPrivate;
+
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( SelectionMode LayoutMode )
+ Q_PROPERTY( uint count READ count )
+ Q_PROPERTY( int numItemsVisible READ numItemsVisible )
+ Q_PROPERTY( int currentItem READ currentItem WRITE setCurrentItem )
+ Q_PROPERTY( TQString currentText READ currentText )
+ Q_PROPERTY( int topItem READ topItem WRITE setTopItem DESIGNABLE false )
+ Q_PROPERTY( SelectionMode selectionMode READ selectionMode WRITE setSelectionMode )
+ Q_PROPERTY( bool multiSelection READ isMultiSelection WRITE setMultiSelection DESIGNABLE false )
+ Q_PROPERTY( LayoutMode columnMode READ columnMode WRITE setColumnMode )
+ Q_PROPERTY( LayoutMode rowMode READ rowMode WRITE setRowMode )
+ Q_PROPERTY( int numColumns READ numColumns )
+ Q_PROPERTY( int numRows READ numRows )
+ Q_PROPERTY( bool variableWidth READ variableWidth WRITE setVariableWidth )
+ Q_PROPERTY( bool variableHeight READ variableHeight WRITE setVariableHeight )
+
+public:
+ TQListBox( TQWidget* tqparent=0, const char* name=0, WFlags f=0 );
+ ~TQListBox();
+
+ virtual void setFont( const TQFont & );
+
+ uint count() const;
+
+ void insertStringList( const TQStringList&, int index=-1 );
+ void insertStrList( const TQStrList *, int index=-1 );
+ void insertStrList( const TQStrList &, int index=-1 );
+ void insertStrList( const char **,
+ int numStrings=-1, int index=-1 );
+
+ void insertItem( const TQListBoxItem *, int index=-1 );
+ void insertItem( const TQListBoxItem *, const TQListBoxItem *after );
+ void insertItem( const TQString &text, int index=-1 );
+ void insertItem( const TQPixmap &pixmap, int index=-1 );
+ void insertItem( const TQPixmap &pixmap, const TQString &text, int index=-1 );
+
+ void removeItem( int index );
+
+ TQString text( int index ) const;
+ const TQPixmap *pixmap( int index ) const;
+
+ void changeItem( const TQListBoxItem *, int index );
+ void changeItem( const TQString &text, int index );
+ void changeItem( const TQPixmap &pixmap, int index );
+ void changeItem( const TQPixmap &pixmap, const TQString &text, int index );
+
+ void takeItem( const TQListBoxItem * );
+
+ int numItemsVisible() const;
+
+ int currentItem() const;
+ TQString currentText() const { return text(currentItem()); }
+ virtual void setCurrentItem( int index );
+ virtual void setCurrentItem( TQListBoxItem * );
+ void centerCurrentItem() { ensureCurrentVisible(); }
+ int topItem() const;
+ virtual void setTopItem( int index );
+ virtual void setBottomItem( int index );
+
+ long maxItemWidth() const;
+
+ enum SelectionMode { Single, Multi, Extended, NoSelection };
+ virtual void setSelectionMode( SelectionMode );
+ SelectionMode selectionMode() const;
+
+ void setMultiSelection( bool multi );
+ bool isMultiSelection() const;
+
+ virtual void setSelected( TQListBoxItem *, bool );
+ void setSelected( int, bool );
+ bool isSelected( int ) const;
+ bool isSelected( const TQListBoxItem * ) const;
+ TQListBoxItem* selectedItem() const;
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ TQListBoxItem *item( int index ) const;
+ int index( const TQListBoxItem * ) const;
+ TQListBoxItem *tqfindItem( const TQString &text, TQt::ComparisonFlags compare = TQt::BeginsWith ) const;
+
+ void triggerUpdate( bool doLayout );
+
+ bool itemVisible( int index );
+ bool itemVisible( const TQListBoxItem * );
+
+ enum LayoutMode { FixedNumber,
+ FitToWidth, FitToHeight = FitToWidth,
+ Variable };
+ virtual void setColumnMode( LayoutMode );
+ virtual void setColumnMode( int );
+ virtual void setRowMode( LayoutMode );
+ virtual void setRowMode( int );
+
+ LayoutMode columnMode() const;
+ LayoutMode rowMode() const;
+
+ int numColumns() const;
+ int numRows() const;
+
+ bool variableWidth() const;
+ virtual void setVariableWidth( bool );
+
+ bool variableHeight() const;
+ virtual void setVariableHeight( bool );
+
+ void viewportPaintEvent( TQPaintEvent * );
+
+#ifndef TQT_NO_COMPAT
+ bool dragSelect() const { return TRUE; }
+ void setDragSelect( bool ) {}
+ bool autoScroll() const { return TRUE; }
+ void setAutoScroll( bool ) {}
+ bool autoScrollBar() const { return vScrollBarMode() == Auto; }
+ void setAutoScrollBar( bool enable ) { setVScrollBarMode( enable ? Auto : AlwaysOff ); }
+ bool scrollBar() const { return vScrollBarMode() != AlwaysOff; }
+ void setScrollBar( bool enable ) { setVScrollBarMode( enable ? AlwaysOn : AlwaysOff ); }
+ bool autoBottomScrollBar() const { return hScrollBarMode() == Auto; }
+ void setAutoBottomScrollBar( bool enable ) { setHScrollBarMode( enable ? Auto : AlwaysOff ); }
+ bool bottomScrollBar() const { return hScrollBarMode() != AlwaysOff; }
+ void setBottomScrollBar( bool enable ) { setHScrollBarMode( enable ? AlwaysOn : AlwaysOff ); }
+ bool smoothScrolling() const { return FALSE; }
+ void setSmoothScrolling( bool ) {}
+ bool autoUpdate() const { return TRUE; }
+ void setAutoUpdate( bool ) {}
+ void setFixedVisibleLines( int lines ) { setRowMode( lines ); }
+ int inSort( const TQListBoxItem * );
+ int inSort( const TQString& text );
+ int cellHeight( int i ) const { return itemHeight(i); }
+ int cellHeight() const { return itemHeight(); }
+ int cellWidth() const { return maxItemWidth(); }
+ int cellWidth(int i) const { TQ_ASSERT(i==0); TQ_UNUSED(i) return maxItemWidth(); }
+ int numCols() const { return numColumns(); }
+#endif
+
+ int itemHeight( int index = 0 ) const;
+ TQListBoxItem * itemAt( const TQPoint & ) const;
+
+ TQRect tqitemRect( TQListBoxItem *item ) const;
+
+ TQListBoxItem *firstItem() const;
+
+ void sort( bool ascending = TRUE );
+
+public Q_SLOTS:
+ void clear();
+ virtual void ensureCurrentVisible();
+ virtual void clearSelection();
+ virtual void selectAll( bool select );
+ virtual void invertSelection();
+
+Q_SIGNALS:
+ void highlighted( int index );
+ void selected( int index );
+ void highlighted( const TQString &);
+ void selected( const TQString &);
+ void highlighted( TQListBoxItem * );
+ void selected( TQListBoxItem * );
+
+ void selectionChanged();
+ void selectionChanged( TQListBoxItem * );
+ void currentChanged( TQListBoxItem * );
+ void clicked( TQListBoxItem * );
+ void clicked( TQListBoxItem *, const TQPoint & );
+ void pressed( TQListBoxItem * );
+ void pressed( TQListBoxItem *, const TQPoint & );
+
+ void doubleClicked( TQListBoxItem * );
+ void returnPressed( TQListBoxItem * );
+ void rightButtonClicked( TQListBoxItem *, const TQPoint & );
+ void rightButtonPressed( TQListBoxItem *, const TQPoint & );
+ void mouseButtonPressed( int, TQListBoxItem*, const TQPoint& );
+ void mouseButtonClicked( int, TQListBoxItem*, const TQPoint& );
+
+ void contextMenuRequested( TQListBoxItem *, const TQPoint & );
+
+ void onItem( TQListBoxItem *item );
+ void onViewport();
+
+protected:
+ void mousePressEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseDoubleClickEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void contentsContextMenuEvent( TQContextMenuEvent * );
+
+ void keyPressEvent( TQKeyEvent *e );
+ void focusInEvent( TQFocusEvent *e );
+ void focusOutEvent( TQFocusEvent *e );
+ void resizeEvent( TQResizeEvent * );
+ void showEvent( TQShowEvent * );
+
+ bool eventFilter( TQObject *o, TQEvent *e );
+
+ void updateItem( int index );
+ void updateItem( TQListBoxItem * );
+
+#ifndef TQT_NO_COMPAT
+ void updateCellWidth() { }
+ int totalWidth() const { return contentsWidth(); }
+ int totalHeight() const { return contentsHeight(); }
+#endif
+
+ virtual void paintCell( TQPainter *, int row, int col );
+
+ void toggleCurrentItem();
+ bool isRubberSelecting() const;
+
+ void doLayout() const;
+
+ void windowActivationChange( bool );
+
+#ifndef TQT_NO_COMPAT
+ bool itemYPos( int index, int *yPos ) const;
+ int tqfindItem( int yPos ) const { return index(itemAt(TQPoint(0,yPos)) ); }
+#endif
+
+protected Q_SLOTS:
+ void clearInputString();
+
+private Q_SLOTS:
+ void refreshSlot();
+ void doAutoScroll();
+ void adjustItems();
+
+private:
+ void mousePressEventEx( TQMouseEvent * );
+ void tryGeometry( int, int ) const;
+ int currentRow() const;
+ int currentColumn() const;
+ void updateSelection();
+ void repaintSelection();
+ void drawRubber();
+ void doRubberSelection( const TQRect &old, const TQRect &rubber );
+ void handleItemChange( TQListBoxItem *old, bool shift, bool control );
+ void selectRange( TQListBoxItem *from, TQListBoxItem *to, bool invert, bool includeFirst, bool clearSel = FALSE );
+
+ void emitChangedSignal( bool );
+
+ int columnAt( int ) const;
+ int rowAt( int ) const;
+
+ TQListBoxPrivate * d;
+
+ static TQListBox * changedListBox;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQListBox( const TQListBox & );
+ TQListBox &operator=( const TQListBox & );
+#endif
+};
+
+
+class TQ_EXPORT TQListBoxItem
+{
+public:
+ TQListBoxItem( TQListBox* listbox = 0 );
+ TQListBoxItem( TQListBox* listbox, TQListBoxItem *after );
+ virtual ~TQListBoxItem();
+
+ virtual TQString text() const;
+ virtual const TQPixmap *pixmap() const;
+
+ virtual int height( const TQListBox * ) const;
+ virtual int width( const TQListBox * ) const;
+
+ bool isSelected() const { return s; }
+ bool isCurrent() const;
+
+#ifndef TQT_NO_COMPAT
+ bool selected() const { return isSelected(); }
+ bool current() const { return isCurrent(); }
+#endif
+
+ TQListBox *listBox() const;
+
+ void setSelectable( bool b );
+ bool isSelectable() const;
+
+ TQListBoxItem *next() const;
+ TQListBoxItem *prev() const;
+
+ virtual int rtti() const;
+ static int RTTI;
+
+protected:
+ virtual void paint( TQPainter * ) = 0;
+ virtual void setText( const TQString &text ) { txt = text; }
+ void setCustomHighlighting( bool );
+
+private:
+ TQString txt;
+ uint s:1;
+ uint dirty:1;
+ uint custom_highlight : 1;
+ int x, y;
+ TQListBoxItem * p, * n;
+ TQListBox* lbox;
+ friend class TQListBox;
+ friend class TQListBoxPrivate;
+ friend class TQComboBox;
+ friend class TQComboBoxPopupItem;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQListBoxItem( const TQListBoxItem & );
+ TQListBoxItem &operator=( const TQListBoxItem & );
+#endif
+};
+
+
+class TQ_EXPORT TQListBoxText : public TQListBoxItem
+{
+public:
+ TQListBoxText( TQListBox* listbox, const TQString & text=TQString::null );
+ TQListBoxText( const TQString & text=TQString::null );
+ TQListBoxText( TQListBox* listbox, const TQString & text, TQListBoxItem *after );
+ ~TQListBoxText();
+
+ int height( const TQListBox * ) const;
+ int width( const TQListBox * ) const;
+
+ int rtti() const;
+ static int RTTI;
+
+protected:
+ void paint( TQPainter * );
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQListBoxText( const TQListBoxText & );
+ TQListBoxText &operator=( const TQListBoxText & );
+#endif
+};
+
+
+class TQ_EXPORT TQListBoxPixmap : public TQListBoxItem
+{
+public:
+ TQListBoxPixmap( TQListBox* listbox, const TQPixmap & );
+ TQListBoxPixmap( const TQPixmap & );
+ TQListBoxPixmap( TQListBox* listbox, const TQPixmap & pix, TQListBoxItem *after );
+ TQListBoxPixmap( TQListBox* listbox, const TQPixmap &, const TQString& );
+ TQListBoxPixmap( const TQPixmap &, const TQString& );
+ TQListBoxPixmap( TQListBox* listbox, const TQPixmap & pix, const TQString&, TQListBoxItem *after );
+ ~TQListBoxPixmap();
+
+ const TQPixmap *pixmap() const { return &pm; }
+
+ int height( const TQListBox * ) const;
+ int width( const TQListBox * ) const;
+
+ int rtti() const;
+ static int RTTI;
+
+protected:
+ void paint( TQPainter * );
+
+private:
+ TQPixmap pm;
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQListBoxPixmap( const TQListBoxPixmap & );
+ TQListBoxPixmap &operator=( const TQListBoxPixmap & );
+#endif
+};
+
+
+#endif // TQT_NO_LISTBOX
+
+#endif // TQLISTBOX_H
diff --git a/tqtinterface/qt4/src/widgets/tqlistview.cpp b/tqtinterface/qt4/src/widgets/tqlistview.cpp
new file mode 100644
index 0000000..bd706e9
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqlistview.cpp
@@ -0,0 +1,8194 @@
+/****************************************************************************
+**
+** Implementation of TQListView widget class
+**
+** Created : 970809
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqlistview.h"
+#ifndef TQT_NO_LISTVIEW
+#include "tqtimer.h"
+#include "tqheader.h"
+#include "tqpainter.h"
+#include "tqcursor.h"
+#include "tqptrstack.h"
+#include "tqptrlist.h"
+#include "tqstrlist.h"
+#include "tqapplication.h"
+#include "tqbitmap.h"
+#include "tqdatetime.h"
+#include "tqptrdict.h"
+#include "tqptrvector.h"
+#include "tqiconset.h"
+#include "tqcleanuphandler.h"
+#include "tqpixmapcache.h"
+#include "tqpopupmenu.h"
+#include "tqtl.h"
+#include "tqdragobject.h"
+#include "tqlineedit.h"
+#include "tqvbox.h"
+#include "tqtooltip.h"
+#include "tqstyle.h"
+#include "tqstylesheet.h"
+#include "../kernel/tqinternal_p.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+const int Unsorted = 16383;
+
+static TQCleanupHandler<TQBitmap> qlv_cleanup_bitmap;
+
+struct TQListViewItemIteratorPrivate
+{
+ TQListViewItemIteratorPrivate( uint f ) : flags( f )
+ {
+ // nothing yet
+ }
+
+ uint flags;
+};
+
+static TQPtrDict<TQListViewItemIteratorPrivate> *qt_iteratorprivate_dict = 0;
+
+struct TQListViewPrivate
+{
+ // classes that are here to avoid polluting the global name space
+
+ // the magical hidden mother of all items
+ class Root: public TQListViewItem {
+ public:
+ Root( TQListView * tqparent );
+
+ void setHeight( int );
+ void invalidateHeight();
+ void setup();
+ TQListView * theListView() const;
+
+ TQListView * lv;
+ };
+
+ // for the stack used in drawContentsOffset()
+ class Pending {
+ public:
+ Pending( int level, int ypos, TQListViewItem * item)
+ : l(level), y(ypos), i(item) {};
+
+ int l; // level of this item; root is -1 or 0
+ int y; // level of this item in the tree
+ TQListViewItem * i; // the item itself
+ };
+
+ // to remember what's on screen
+ class DrawableItem {
+ public:
+ DrawableItem( Pending * pi ) { y = pi->y; l = pi->l; i = pi->i; };
+ int y;
+ int l;
+ TQListViewItem * i;
+ };
+
+ // for sorting
+ class SortableItem {
+ public:
+ /*
+ We could be smarter and keep a pointer to the TQListView
+ item instead of numCols, col and asc. This would then allow
+ us to use the physical ordering of columns rather than the
+ logical. Microsoft uses the logical ordering, so there is
+ some virtue in doing so, although it prevents the user from
+ chosing the secondary key.
+ */
+ TQListViewItem * item;
+ int numCols;
+ int col;
+ bool asc;
+
+ int cmp( const SortableItem& i ) const {
+ int diff = item->compare( i.item, col, asc );
+ if ( diff == 0 && numCols != 1 ) {
+ for ( int j = 0; j < numCols; j++ ) {
+ if ( j != col ) {
+ diff = item->compare( i.item, j, asc );
+ if ( diff != 0 )
+ break;
+ }
+ }
+ }
+ return diff;
+ }
+ bool operator<( const SortableItem& i ) const { return cmp( i ) < 0; }
+ bool operator<=( const SortableItem& i ) const { return cmp( i ) <= 0; }
+ bool operator>( const SortableItem& i ) const { return cmp( i ) > 0; }
+ };
+
+ class ItemColumnInfo {
+ public:
+ ItemColumnInfo(): pm( 0 ), next( 0 ), truncated( FALSE ), dirty( FALSE ), allow_rename( FALSE ), width( 0 ) {}
+ ~ItemColumnInfo() { delete pm; delete next; }
+ TQString text, tmpText;
+ TQPixmap * pm;
+ ItemColumnInfo * next;
+ uint truncated : 1;
+ uint dirty : 1;
+ uint allow_rename : 1;
+ int width;
+ };
+
+ class ViewColumnInfo {
+ public:
+ ViewColumnInfo(): align(TQt::AlignAuto), sortable(TRUE), next( 0 ) {}
+ ~ViewColumnInfo() { delete next; }
+ int align;
+ bool sortable;
+ ViewColumnInfo * next;
+ };
+
+ // private variables used in TQListView
+ ViewColumnInfo * vci;
+ TQHeader * h;
+ Root * r;
+ uint rootIsExpandable : 1;
+ int margin;
+
+ TQListViewItem * focusItem, *highlighted, *oldFocusItem;
+
+ TQTimer * timer;
+ TQTimer * dirtyItemTimer;
+ TQTimer * visibleTimer;
+ int levelWidth;
+
+ // the list of drawables, and the range drawables covers entirely
+ // (it may also include a few items above topPixel)
+ TQPtrList<DrawableItem> * drawables;
+ int topPixel;
+ int bottomPixel;
+
+ TQPtrDict<void> * dirtyItems;
+
+ TQListView::SelectionMode selectionMode;
+
+ // Per-column structure for information not in the TQHeader
+ struct Column {
+ TQListView::WidthMode wmode;
+ };
+ TQPtrVector<Column> column;
+
+ // suggested height for the items
+ int fontMetricsHeight;
+ int minLeftBearing, minRightBearing;
+ int ellipsisWidth;
+
+ // currently typed prefix for the keyboard interface, and the time
+ // of the last key-press
+ TQString currentPrefix;
+ TQTime currentPrefixTime;
+
+ // holds a list of iterators
+ TQPtrList<TQListViewItemIterator> *iterators;
+ TQListViewItem *pressedItem, *selectAnchor;
+
+ TQTimer *scrollTimer;
+ TQTimer *renameTimer;
+ TQTimer *autoopenTimer;
+
+ // sort column and order #### may need to move to TQHeader [subclass]
+ int sortcolumn;
+ bool ascending :1;
+ bool sortIndicator :1;
+ // whether to select or deselect during this mouse press.
+ bool allColumnsShowFocus :1;
+ bool select :1;
+
+ // TRUE if the widget should take notice of mouseReleaseEvent
+ bool buttonDown :1;
+ // TRUE if the widget should ignore a double-click
+ bool ignoreDoubleClick :1;
+
+ bool clearing :1;
+ bool pressedSelected :1;
+ bool pressedEmptyArea :1;
+
+ bool useDoubleBuffer :1;
+ bool toolTips :1;
+ bool fullRepaintOnComlumnChange:1;
+ bool updateHeader :1;
+
+ bool startEdit : 1;
+ bool ignoreEditAfterFocus : 1;
+ bool inMenuMode :1;
+
+ TQListView::RenameAction defRenameAction;
+
+ TQListViewItem *startDragItem;
+ TQPoint dragStartPos;
+ TQListViewToolTip *toolTip;
+ int pressedColumn;
+ TQListView::ResizeMode resizeMode;
+};
+
+#ifndef TQT_NO_TOOLTIP
+class TQListViewToolTip : public TQToolTip
+{
+public:
+ TQListViewToolTip( TQWidget *tqparent, TQListView *lv );
+
+ void maybeTip( const TQPoint &pos );
+
+private:
+ TQListView *view;
+
+};
+
+TQListViewToolTip::TQListViewToolTip( TQWidget *tqparent, TQListView *lv )
+ : TQToolTip( tqparent ), view( lv )
+{
+}
+
+void TQListViewToolTip::maybeTip( const TQPoint &pos )
+{
+ if ( !parentWidget() || !view || !view->showToolTips() )
+ return;
+
+ TQListViewItem *item = view->itemAt( pos );
+ TQPoint contentsPos = view->viewportToContents( pos );
+ if ( !item || !item->columns )
+ return;
+ int col = view->header()->sectionAt( contentsPos.x() );
+ TQListViewPrivate::ItemColumnInfo *ci = (TQListViewPrivate::ItemColumnInfo*)item->columns;
+ for ( int i = 0; ci && ( i < col ); ++i )
+ ci = ci->next;
+
+ if ( !ci || !ci->truncated )
+ return;
+
+ TQRect r = view->tqitemRect( item );
+ int headerPos = view->header()->sectionPos( col );
+ r.setLeft( headerPos );
+ r.setRight( headerPos + view->header()->sectionSize( col ) );
+ tip( r, TQStyleSheet::escape(item->text( col ) ) );
+}
+#endif
+
+// these should probably be in TQListViewPrivate, for future thread safety
+static bool activatedByClick;
+
+// Holds the position of activation. The position is relative to the top left corner in the row minus the root decoration and its branches/depth.
+// Used to track the point clicked for CheckBoxes and RadioButtons.
+static TQPoint activatedP;
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+static int indexOfItem( TQListViewItem *item )
+{
+ if ( !TQAccessible::isActive() )
+ return 0;
+
+ static TQListViewItem *lastItem = 0;
+ static int lastIndex = 0;
+
+ if ( !item || !item->listView() )
+ return 0;
+
+ if ( item == lastItem )
+ return lastIndex;
+
+ lastItem = item;
+ int index = 1;
+
+ TQListViewItemIterator it( item->listView() );
+ while ( it.current() ) {
+ if ( it.current() == item ) {
+ lastIndex = index;
+ return index;
+ }
+ ++it;
+ ++index;
+ }
+ lastIndex = 0;
+ return 0;
+}
+#endif
+
+/*!
+ \internal
+ Creates a string with ... like "Trollte..." or "...olltech" depending on the tqalignment
+*/
+
+static TQString qEllipsisText( const TQString &org, const TQFontMetrics &fm, int width, int align )
+{
+ int ellWidth = fm.width( "..." );
+ TQString text = TQString::tqfromLatin1("");
+ int i = 0;
+ int len = org.length();
+ int offset = (align & TQt::AlignRight) ? (len-1) - i : i;
+ while ( i < len && fm.width( text + org[ offset ] ) + ellWidth < width ) {
+ if ( align & TQt::AlignRight )
+ text.prepend( org[ offset ] );
+ else
+ text += org[ offset ];
+ offset = (align & TQt::AlignRight) ? (len-1) - ++i : ++i;
+ }
+ if ( text.isEmpty() )
+ text = ( align & TQt::AlignRight ) ? org.right( 1 ) : text = org.left( 1 );
+ if ( align & TQt::AlignRight )
+ text.prepend( "..." );
+ else
+ text += "...";
+ return text;
+}
+
+/*!
+ \class TQListViewItem
+ \brief The TQListViewItem class implements a list view item.
+
+ \ingroup advanced
+
+ A list view item is a multi-column object capable of displaying
+ itself in a TQListView.
+
+ The easiest way to use TQListViewItem is to construct one with a
+ few constant strings, and either a TQListView or another
+ TQListViewItem as tqparent.
+ \code
+ (void) new TQListViewItem( listView, "Column 1", "Column 2" );
+ (void) new TQListViewItem( listView->firstChild(), "A", "B", "C" );
+ \endcode
+ We've discarded the pointers to the items since we can still access
+ them via their tqparent \e listView. By default, TQListView sorts its
+ items; this can be switched off with TQListView::setSorting(-1).
+
+ The tqparent must be another TQListViewItem or a TQListView. If the
+ tqparent is a TQListView, the item becomes a top-level item within
+ that TQListView. If the tqparent is another TQListViewItem, the item
+ becomes a child of that list view item.
+
+ If you keep the pointer, you can set or change the texts using
+ setText(), add pixmaps using setPixmap(), change its mode using
+ setSelectable(), setSelected(), setOpen() and setExpandable().
+ You'll also be able to change its height using setHeight(), and
+ traverse its sub-items. You don't have to keep the pointer since
+ you can get a pointer to any TQListViewItem in a TQListView using
+ TQListView::selectedItem(), TQListView::currentItem(),
+ TQListView::firstChild(), TQListView::lastItem() and
+ TQListView::tqfindItem().
+
+ If you call \c delete on a list view item, it will be deleted as
+ expected, and as usual for \l{TQObject}s, if it has any child items
+ (to any depth), all these will be deleted too.
+
+ \l{TQCheckListItem}s are list view items that have a checkbox or
+ radio button and can be used in place of plain TQListViewItems.
+
+ You can traverse the tree as if it were a doubly-linked list using
+ itemAbove() and itemBelow(); they return pointers to the items
+ directly above and below this item on the screen (even if none of
+ them are actually visible at the moment).
+
+ Here's how to traverse all of an item's tqchildren (but not its
+ tqchildren's tqchildren, etc.):
+ Example:
+ \code
+ TQListViewItem * myChild = myItem->firstChild();
+ while( myChild ) {
+ doSomething( myChild );
+ myChild = myChild->nextSibling();
+ }
+ \endcode
+
+ If you want to iterate over every item, to any level of depth use
+ an iterator. To iterate over the entire tree, initialize the
+ iterator with the list view itself; to iterate starting from a
+ particular item, initialize the iterator with the item:
+
+ \code
+ TQListViewItemIterator it( listview );
+ while ( it.current() ) {
+ TQListViewItem *item = it.current();
+ doSomething( item );
+ ++it;
+ }
+ \endcode
+
+ Note that the order of the tqchildren will change when the sorting
+ order changes and is undefined if the items are not visible. You
+ can, however, call enforceSortOrder() at any time; TQListView will
+ always call it before it needs to show an item.
+
+ Many programs will need to reimplement TQListViewItem. The most
+ commonly reimplemented functions are:
+ \table
+ \header \i Function \i Description
+ \row \i \l text()
+ \i Returns the text in a column. Many subclasses will compute
+ this on the fly.
+ \row \i \l key()
+ \i Used for sorting. The default key() simply calls
+ text(), but judicious use of key() can give you fine
+ control over sorting; for example, TQFileDialog
+ reimplements key() to sort by date.
+ \row \i \l setup()
+ \i Called before showing the item and whenever the list
+ view's font changes, for example.
+ \row \i \l activate()
+ \i Called whenever the user clicks on the item or presses
+ Space when the item is the current item.
+ \endtable
+
+ Some subclasses call setExpandable(TRUE) even when they have no
+ tqchildren, and populate themselves when setup() or setOpen(TRUE) is
+ called. The \c dirview/dirview.cpp example program uses this
+ technique to start up quickly: The files and subdirectories in a
+ directory aren't inserted into the tree until they're actually
+ needed.
+
+ \img qlistviewitems.png List View Items
+
+ \sa TQCheckListItem TQListView
+*/
+
+/*!
+ \fn int TQCheckListItem::rtti() const
+
+ Returns 1.
+
+ Make your derived classes return their own values for rtti(), and
+ you can distinguish between list view items. You should use values
+ greater than 1000, to allow for extensions to this class.
+*/
+
+/*!
+ Constructs a new top-level list view item in the TQListView \a
+ tqparent.
+*/
+
+TQListViewItem::TQListViewItem( TQListView * tqparent )
+{
+ init();
+ tqparent->insertItem( this );
+}
+
+
+/*!
+ Constructs a new list view item that is a child of \a tqparent and
+ first in the tqparent's list of tqchildren.
+*/
+
+TQListViewItem::TQListViewItem( TQListViewItem * tqparent )
+{
+ init();
+ tqparent->insertItem( this );
+}
+
+
+
+
+/*!
+ Constructs an empty list view item that is a child of \a tqparent
+ and is after item \a after in the tqparent's list of tqchildren. Since
+ \a tqparent is a TQListView the item will be a top-level item.
+*/
+
+TQListViewItem::TQListViewItem( TQListView * tqparent, TQListViewItem * after )
+{
+ init();
+ tqparent->insertItem( this );
+ moveToJustAfter( after );
+}
+
+
+/*!
+ Constructs an empty list view item that is a child of \a tqparent
+ and is after item \a after in the tqparent's list of tqchildren.
+*/
+
+TQListViewItem::TQListViewItem( TQListViewItem * tqparent, TQListViewItem * after )
+{
+ init();
+ tqparent->insertItem( this );
+ moveToJustAfter( after );
+}
+
+
+
+/*!
+ Constructs a new top-level list view item in the TQListView \a
+ tqparent, with up to eight constant strings, \a label1, \a label2, \a
+ label3, \a label4, \a label5, \a label6, \a label7 and \a label8
+ defining its columns' contents.
+
+ \sa setText()
+*/
+
+TQListViewItem::TQListViewItem( TQListView * tqparent,
+ TQString label1,
+ TQString label2,
+ TQString label3,
+ TQString label4,
+ TQString label5,
+ TQString label6,
+ TQString label7,
+ TQString label8 )
+{
+ init();
+ tqparent->insertItem( this );
+
+ setText( 0, label1 );
+ setText( 1, label2 );
+ setText( 2, label3 );
+ setText( 3, label4 );
+ setText( 4, label5 );
+ setText( 5, label6 );
+ setText( 6, label7 );
+ setText( 7, label8 );
+}
+
+
+/*!
+ Constructs a new list view item as a child of the TQListViewItem \a
+ tqparent with up to eight constant strings, \a label1, \a label2, \a
+ label3, \a label4, \a label5, \a label6, \a label7 and \a label8
+ as columns' contents.
+
+ \sa setText()
+*/
+
+TQListViewItem::TQListViewItem( TQListViewItem * tqparent,
+ TQString label1,
+ TQString label2,
+ TQString label3,
+ TQString label4,
+ TQString label5,
+ TQString label6,
+ TQString label7,
+ TQString label8 )
+{
+ init();
+ tqparent->insertItem( this );
+
+ setText( 0, label1 );
+ setText( 1, label2 );
+ setText( 2, label3 );
+ setText( 3, label4 );
+ setText( 4, label5 );
+ setText( 5, label6 );
+ setText( 6, label7 );
+ setText( 7, label8 );
+}
+
+/*!
+ Constructs a new list view item in the TQListView \a tqparent that is
+ included after item \a after and that has up to eight column
+ texts, \a label1, \a label2, \a label3, \a label4, \a label5, \a
+ label6, \a label7 and\a label8.
+
+ Note that the order is changed according to TQListViewItem::key()
+ unless the list view's sorting is disabled using
+ TQListView::setSorting(-1).
+
+ \sa setText()
+*/
+
+TQListViewItem::TQListViewItem( TQListView * tqparent, TQListViewItem * after,
+ TQString label1,
+ TQString label2,
+ TQString label3,
+ TQString label4,
+ TQString label5,
+ TQString label6,
+ TQString label7,
+ TQString label8 )
+{
+ init();
+ tqparent->insertItem( this );
+ moveToJustAfter( after );
+
+ setText( 0, label1 );
+ setText( 1, label2 );
+ setText( 2, label3 );
+ setText( 3, label4 );
+ setText( 4, label5 );
+ setText( 5, label6 );
+ setText( 6, label7 );
+ setText( 7, label8 );
+}
+
+
+/*!
+ Constructs a new list view item as a child of the TQListViewItem \a
+ tqparent. It is inserted after item \a after and may contain up to
+ eight strings, \a label1, \a label2, \a label3, \a label4, \a
+ label5, \a label6, \a label7 and \a label8 as column entries.
+
+ Note that the order is changed according to TQListViewItem::key()
+ unless the list view's sorting is disabled using
+ TQListView::setSorting(-1).
+
+ \sa setText()
+*/
+
+TQListViewItem::TQListViewItem( TQListViewItem * tqparent, TQListViewItem * after,
+ TQString label1,
+ TQString label2,
+ TQString label3,
+ TQString label4,
+ TQString label5,
+ TQString label6,
+ TQString label7,
+ TQString label8 )
+{
+ init();
+ tqparent->insertItem( this );
+ moveToJustAfter( after );
+
+ setText( 0, label1 );
+ setText( 1, label2 );
+ setText( 2, label3 );
+ setText( 3, label4 );
+ setText( 4, label5 );
+ setText( 5, label6 );
+ setText( 6, label7 );
+ setText( 7, label8 );
+}
+
+/*!
+ Sorts all this item's child items using the current sorting
+ configuration (sort column and direction).
+
+ \sa enforceSortOrder()
+*/
+
+void TQListViewItem::sort()
+{
+ if ( !listView() )
+ return;
+ lsc = Unsorted;
+ enforceSortOrder();
+ listView()->triggerUpdate();
+}
+
+int TQListViewItem::RTTI = 0;
+
+/*!
+ Returns 0.
+
+ Make your derived classes return their own values for rtti(), so
+ that you can distinguish between different kinds of list view
+ items. You should use values greater than 1000 to allow for
+ extensions to this class.
+*/
+
+int TQListViewItem::rtti() const
+{
+ return RTTI;
+}
+
+/*
+ Performs the initializations that's common to the constructors.
+*/
+
+void TQListViewItem::init()
+{
+ ownHeight = 0;
+ maybeTotalHeight = -1;
+ open = FALSE;
+
+ nChildren = 0;
+ parentItem = 0;
+ siblingItem = childItem = 0;
+
+ columns = 0;
+
+ selected = 0;
+
+ lsc = Unsorted;
+ lso = TRUE; // unsorted in ascending order :)
+ configured = FALSE;
+ expandable = FALSE;
+ selectable = TRUE;
+ is_root = FALSE;
+ allow_drag = FALSE;
+ allow_drop = FALSE;
+ visible = TRUE;
+ renameBox = 0;
+ enabled = TRUE;
+ mlenabled = FALSE;
+}
+
+/*!
+ If \a b is TRUE, the item is made visible; otherwise it is hidden.
+
+ If the item is not visible, itemAbove() and itemBelow() will never
+ return this item, although you still can reach it by using e.g.
+ TQListViewItemIterator.
+*/
+
+void TQListViewItem::tqsetVisible( bool b )
+{
+ if ( b == (bool)visible )
+ return;
+ TQListView *lv = listView();
+ if ( !lv )
+ return;
+ if ( b && tqparent() && !tqparent()->isVisible() )
+ return;
+ visible = b;
+ configured = FALSE;
+ setHeight( 0 );
+ invalidateHeight();
+ if ( tqparent() )
+ tqparent()->invalidateHeight();
+ else
+ lv->d->r->invalidateHeight();
+ for ( TQListViewItem *i = childItem; i; i = i->siblingItem )
+ i->tqsetVisible( b );
+ if ( lv )
+ lv->triggerUpdate();
+}
+
+/*!
+ Returns TRUE if the item is visible; otherwise returns FALSE.
+
+ \sa tqsetVisible()
+*/
+
+bool TQListViewItem::isVisible() const
+{
+ return (bool)visible;
+}
+
+/*!
+ If \a b is TRUE, this item can be in-place renamed in the column
+ \a col by the user; otherwise it cannot be renamed in-place.
+*/
+
+void TQListViewItem::setRenameEnabled( int col, bool b )
+{
+ TQListViewPrivate::ItemColumnInfo * l = (TQListViewPrivate::ItemColumnInfo*)columns;
+ if ( !l ) {
+ l = new TQListViewPrivate::ItemColumnInfo;
+ columns = (void*)l;
+ }
+ for( int c = 0; c < col; c++ ) {
+ if ( !l->next )
+ l->next = new TQListViewPrivate::ItemColumnInfo;
+ l = l->next;
+ }
+
+ if ( !l )
+ return;
+ l->allow_rename = b;
+}
+
+/*!
+ Returns TRUE if this item can be in-place renamed in column \a
+ col; otherwise returns FALSE.
+*/
+
+bool TQListViewItem::renameEnabled( int col ) const
+{
+ TQListViewPrivate::ItemColumnInfo * l = (TQListViewPrivate::ItemColumnInfo*)columns;
+ if ( !l )
+ return FALSE;
+
+ while( col && l ) {
+ l = l->next;
+ col--;
+ }
+
+ if ( !l )
+ return FALSE;
+ return (bool)l->allow_rename;
+}
+
+/*!
+ If \a b is TRUE the item is enabled; otherwise it is disabled.
+ Disabled items are drawn differently (e.g. grayed-out) and are not
+ accessible by the user.
+*/
+
+void TQListViewItem::setEnabled( bool b )
+{
+ if ( (bool)enabled == b )
+ return;
+ enabled = b;
+ if ( !enabled )
+ selected = FALSE;
+ TQListView *lv = listView();
+ if ( lv ) {
+ lv->triggerUpdate();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( lv->viewport(), indexOfItem( this ), TQAccessible::StateChanged );
+#endif
+ }
+}
+
+/*!
+ Returns TRUE if this item is enabled; otherwise returns FALSE.
+
+ \sa setEnabled()
+*/
+
+bool TQListViewItem::isEnabled() const
+{
+ return (bool)enabled;
+}
+
+/*!
+ If in-place renaming of this item is enabled (see
+ renameEnabled()), this function starts renaming the item in column
+ \a col, by creating and initializing an edit box.
+*/
+
+void TQListViewItem::startRename( int col )
+{
+ if ( !renameEnabled( col ) )
+ return;
+ if ( renameBox )
+ cancelRename( col );
+ TQListView *lv = listView();
+ if ( !lv )
+ return;
+
+ if ( lv->d->renameTimer )
+ lv->d->renameTimer->stop();
+
+ lv->ensureItemVisible( this );
+
+ if ( lv->d->timer->isActive() ) {
+ // make sure that pending calculations get finished
+ lv->d->timer->stop();
+ lv->updateContents();
+ }
+
+ if ( lv->currentItem() && lv->currentItem()->renameBox ) {
+ if ( lv->d->defRenameAction == TQListView::Reject )
+ lv->currentItem()->cancelRename( lv->currentItem()->renameCol );
+ else
+ lv->currentItem()->okRename( lv->currentItem()->renameCol );
+ }
+
+ if ( this != lv->currentItem() )
+ lv->setCurrentItem( this );
+
+ TQRect r = lv->tqitemRect( this );
+ r = TQRect( lv->viewportToContents( r.topLeft() ), r.size() );
+ r.setLeft( lv->header()->sectionPos( col ) );
+ r.setWidth(TQMIN(lv->header()->sectionSize(col) - 1,
+ lv->contentsX() + lv->visibleWidth() - r.left()));
+ if ( col == 0 )
+ r.setLeft( r.left() + lv->itemMargin() + ( depth() + ( lv->rootIsDecorated() ? 1 : 0 ) ) * lv->treeStepSize() - 1 );
+ if ( pixmap( col ) )
+ r.setLeft( r.left() + pixmap( col )->width() );
+ if ( r.x() - lv->contentsX() < 0 ) {
+ lv->scrollBy( r.x() - lv->contentsX(), 0 );
+ r.setX( lv->contentsX() );
+ } else if ( ( lv->contentsX() + lv->visibleWidth() ) < ( r.x() + r.width() ) ) {
+ lv->scrollBy( ( r.x() + r.width() ) - ( lv->contentsX() + lv->visibleWidth() ), 0 );
+ }
+ if ( r.width() > lv->visibleWidth() )
+ r.setWidth( lv->visibleWidth() );
+ renameBox = new TQLineEdit( lv->viewport(), "qt_renamebox" );
+ renameBox->setFrameStyle( TQFrame::Box | TQFrame::Plain );
+ renameBox->setLineWidth( 1 );
+ renameBox->setText( text( col ) );
+ renameBox->selectAll();
+ renameBox->installEventFilter( lv );
+ lv->addChild( renameBox, r.x(), r.y() );
+ renameBox->resize( r.size() );
+ lv->viewport()->setFocusProxy( renameBox );
+ renameBox->setFocus();
+ renameBox->show();
+ renameCol = col;
+}
+
+/*!
+ This function removes the rename box.
+*/
+
+void TQListViewItem::removeRenameBox()
+{
+ // Sanity, it should be checked by the functions calling this first anyway
+ TQListView *lv = listView();
+ if ( !lv || !renameBox )
+ return;
+ const bool resetFocus = lv->viewport()->focusProxy() == renameBox;
+ const bool renameBoxHadFocus = renameBox->hasFocus();
+ delete renameBox;
+ renameBox = 0;
+ if ( resetFocus )
+ lv->viewport()->setFocusProxy( lv );
+ if (renameBoxHadFocus)
+ lv->setFocus();
+}
+
+/*!
+ This function is called if the user presses Enter during in-place
+ renaming of the item in column \a col.
+
+ \sa cancelRename()
+*/
+
+void TQListViewItem::okRename( int col )
+{
+ TQListView *lv = listView();
+ if ( !lv || !renameBox )
+ return;
+ setText( col, renameBox->text() );
+ removeRenameBox();
+
+ // we set the tqparent lsc to Unsorted if that column is the sorted one
+ if ( tqparent() && (int)tqparent()->lsc == col )
+ tqparent()->lsc = Unsorted;
+
+ emit lv->itemRenamed( this, col );
+ emit lv->itemRenamed( this, col, text( col ) );
+}
+
+/*!
+ This function is called if the user cancels in-place renaming of
+ this item in column \a col (e.g. by pressing Esc).
+
+ \sa okRename()
+*/
+
+void TQListViewItem::cancelRename( int )
+{
+ TQListView *lv = listView();
+ if ( !lv || !renameBox )
+ return;
+ removeRenameBox();
+}
+
+/*!
+ Destroys the item, deleting all its tqchildren and freeing up all
+ allocated resources.
+*/
+
+TQListViewItem::~TQListViewItem()
+{
+ if ( renameBox ) {
+ delete renameBox;
+ renameBox = 0;
+ }
+
+ TQListView *lv = listView();
+
+ if ( lv ) {
+ if ( lv->d->oldFocusItem == this )
+ lv->d->oldFocusItem = 0;
+ if ( lv->d->iterators ) {
+ TQListViewItemIterator *i = lv->d->iterators->first();
+ while ( i ) {
+ if ( i->current() == this )
+ i->currentRemoved();
+ i = lv->d->iterators->next();
+ }
+ }
+ }
+
+ if ( parentItem )
+ parentItem->takeItem( this );
+ TQListViewItem * i = childItem;
+ childItem = 0;
+ while ( i ) {
+ i->parentItem = 0;
+ TQListViewItem * n = i->siblingItem;
+ delete i;
+ i = n;
+ }
+ delete (TQListViewPrivate::ItemColumnInfo *)columns;
+}
+
+
+/*!
+ If \a b is TRUE each of the item's columns may contain multiple
+ lines of text; otherwise each of them may only contain a single
+ line.
+*/
+
+void TQListViewItem::setMultiLinesEnabled( bool b )
+{
+ mlenabled = b;
+}
+
+/*!
+ Returns TRUE if the item can display multiple lines of text in its
+ columns; otherwise returns FALSE.
+*/
+
+bool TQListViewItem::multiLinesEnabled() const
+{
+ return mlenabled;
+}
+
+/*!
+ If \a allow is TRUE, the list view starts a drag (see
+ TQListView::dragObject()) when the user presses and moves the mouse
+ on this item.
+*/
+
+
+void TQListViewItem::setDragEnabled( bool allow )
+{
+ allow_drag = (uint)allow;
+}
+
+/*!
+ If \a allow is TRUE, the list view accepts drops onto the item;
+ otherwise drops are not allowed.
+*/
+
+void TQListViewItem::setDropEnabled( bool allow )
+{
+ allow_drop = (uint)allow;
+}
+
+/*!
+ Returns TRUE if this item can be dragged; otherwise returns FALSE.
+
+ \sa setDragEnabled()
+*/
+
+bool TQListViewItem::dragEnabled() const
+{
+ return (bool)allow_drag;
+}
+
+/*!
+ Returns TRUE if this item accepts drops; otherwise returns FALSE.
+
+ \sa setDropEnabled(), acceptDrop()
+*/
+
+bool TQListViewItem::dropEnabled() const
+{
+ return (bool)allow_drop;
+}
+
+/*!
+ Returns TRUE if the item can accept drops of type TQMimeSource \a
+ mime; otherwise returns FALSE.
+
+ The default implementation does nothing and returns FALSE. A
+ subclass must reimplement this to accept drops.
+*/
+
+bool TQListViewItem::acceptDrop( const TQMimeSource * ) const
+{
+ return FALSE;
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ This function is called when something was dropped on the item. \a e
+ tqcontains all the information about the drop.
+
+ The default implementation does nothing, subclasses may need to
+ reimplement this function.
+*/
+
+void TQListViewItem::dropped( TQDropEvent *e )
+{
+ TQ_UNUSED( e );
+}
+
+#endif
+
+/*!
+ This function is called when a drag enters the item's bounding
+ rectangle.
+
+ The default implementation does nothing, subclasses may need to
+ reimplement this function.
+*/
+
+void TQListViewItem::dragEntered()
+{
+}
+
+/*!
+ This function is called when a drag leaves the item's bounding
+ rectangle.
+
+ The default implementation does nothing, subclasses may need to
+ reimplement this function.
+*/
+
+void TQListViewItem::dragLeft()
+{
+}
+
+/*!
+ Inserts \a newChild into this list view item's list of tqchildren.
+ You should not need to call this function; it is called
+ automatically by the constructor of \a newChild.
+
+ \warning If you are using \c Single selection mode, then you
+ should only insert unselected items.
+*/
+
+void TQListViewItem::insertItem( TQListViewItem * newChild )
+{
+ TQListView *lv = listView();
+ if ( lv && lv->currentItem() && lv->currentItem()->renameBox ) {
+ if ( lv->d->defRenameAction == TQListView::Reject )
+ lv->currentItem()->cancelRename( lv->currentItem()->renameCol );
+ else
+ lv->currentItem()->okRename( lv->currentItem()->renameCol );
+ }
+
+ if ( !newChild || newChild->parentItem == this )
+ return;
+ if ( newChild->parentItem )
+ newChild->parentItem->takeItem( newChild );
+ if ( open )
+ invalidateHeight();
+ newChild->siblingItem = childItem;
+ childItem = newChild;
+ nChildren++;
+ newChild->parentItem = this;
+ lsc = Unsorted;
+ newChild->ownHeight = 0;
+ newChild->configured = FALSE;
+
+ if ( lv && !lv->d->focusItem ) {
+ lv->d->focusItem = lv->firstChild();
+ lv->d->selectAnchor = lv->d->focusItem;
+ lv->repaintItem( lv->d->focusItem );
+ }
+}
+
+
+/*!
+ \fn void TQListViewItem::removeItem( TQListViewItem * )
+ \obsolete
+
+ This function has been renamed takeItem().
+*/
+
+
+/*!
+ Removes \a item from this object's list of tqchildren and causes an
+ update of the screen display. The item is not deleted. You should
+ not normally need to call this function because
+ TQListViewItem::~TQListViewItem() calls it.
+
+ The normal way to delete an item is to use \c delete.
+
+ If you need to move an item from one place in the hierarchy to
+ another you can use takeItem() to remove the item from the list
+ view and then insertItem() to put the item back in its new
+ position.
+
+ If a taken item is part of a selection in \c Single selection
+ mode, it is unselected and selectionChanged() is emitted. If a
+ taken item is part of a selection in \c Multi or \c Extended
+ selection mode, it remains selected.
+
+ \warning This function leaves \a item and its tqchildren in a state
+ where most member functions are unsafe. Only a few functions work
+ correctly on an item in this state, most notably insertItem(). The
+ functions that work on taken items are explicitly documented as
+ such.
+
+ \sa TQListViewItem::insertItem()
+*/
+
+void TQListViewItem::takeItem( TQListViewItem * item )
+{
+ if ( !item )
+ return;
+
+ TQListView *lv = listView();
+ if ( lv && lv->currentItem() && lv->currentItem()->renameBox ) {
+ if ( lv->d->defRenameAction == TQListView::Reject )
+ lv->currentItem()->cancelRename( lv->currentItem()->renameCol );
+ else
+ lv->currentItem()->okRename( lv->currentItem()->renameCol );
+ }
+ bool emit_changed = FALSE;
+ if ( lv && !lv->d->clearing ) {
+ if ( lv->d->oldFocusItem == this )
+ lv->d->oldFocusItem = 0;
+
+ if ( lv->d->iterators ) {
+ TQListViewItemIterator *i = lv->d->iterators->first();
+ while ( i ) {
+ if ( i->current() == item )
+ i->currentRemoved();
+ i = lv->d->iterators->next();
+ }
+ }
+
+ invalidateHeight();
+
+ if ( lv->d && lv->d->drawables ) {
+ delete lv->d->drawables;
+ lv->d->drawables = 0;
+ }
+
+ if ( lv->d->dirtyItems ) {
+ if ( item->childItem ) {
+ delete lv->d->dirtyItems;
+ lv->d->dirtyItems = 0;
+ lv->d->dirtyItemTimer->stop();
+ lv->triggerUpdate();
+ } else {
+ lv->d->dirtyItems->take( (void *)item );
+ }
+ }
+
+ if ( lv->d->focusItem ) {
+ const TQListViewItem * c = lv->d->focusItem;
+ while( c && c != item )
+ c = c->parentItem;
+ if ( c == item ) {
+ if ( lv->selectedItem() ) {
+ // for Single, setSelected( FALSE ) when selectedItem() is taken
+ lv->selectedItem()->setSelected( FALSE );
+ // we don't emit selectionChanged( 0 )
+ emit lv->selectionChanged();
+ }
+ if ( item->nextSibling() )
+ lv->d->focusItem = item->nextSibling();
+ else if ( item->itemAbove() )
+ lv->d->focusItem = item->itemAbove();
+ else
+ lv->d->focusItem = 0;
+ emit_changed = TRUE;
+ }
+ }
+
+ // reset anchors etc. if they are set to this or any child
+ // items
+ const TQListViewItem *ptr = lv->d->selectAnchor;
+ while (ptr && ptr != item)
+ ptr = ptr->parentItem;
+ if (ptr == item)
+ lv->d->selectAnchor = lv->d->focusItem;
+
+ ptr = lv->d->startDragItem;
+ while (ptr && ptr != item)
+ ptr = ptr->parentItem;
+ if (ptr == item)
+ lv->d->startDragItem = 0;
+
+ ptr = lv->d->pressedItem;
+ while (ptr && ptr != item)
+ ptr = ptr->parentItem;
+ if (ptr == item)
+ lv->d->pressedItem = 0;
+
+ ptr = lv->d->highlighted;
+ while (ptr && ptr != item)
+ ptr = ptr->parentItem;
+ if (ptr == item)
+ lv->d->highlighted = 0;
+ }
+
+ nChildren--;
+
+ TQListViewItem ** nextChild = &childItem;
+ while( nextChild && *nextChild && item != *nextChild )
+ nextChild = &((*nextChild)->siblingItem);
+
+ if ( nextChild && item == *nextChild )
+ *nextChild = (*nextChild)->siblingItem;
+ item->parentItem = 0;
+ item->siblingItem = 0;
+ item->ownHeight = 0;
+ item->maybeTotalHeight = -1;
+ item->configured = FALSE;
+
+ if ( emit_changed ) {
+ emit lv->currentChanged( lv->d->focusItem );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( lv->viewport(), 0, TQAccessible::Focus );
+#endif
+ }
+}
+
+
+/*!
+ \fn TQString TQListViewItem::key( int column, bool ascending ) const
+
+ Returns a key that can be used for sorting by column \a column.
+ The default implementation returns text(). Derived classes may
+ also incorporate the order indicated by \a ascending into this
+ key, although this is not recommended.
+
+ If you want to sort on non-alphabetical data, e.g. dates, numbers,
+ etc., it is more efficient to reimplement compare().
+
+ \sa compare(), sortChildItems()
+*/
+
+TQString TQListViewItem::key( int column, bool ) const
+{
+ return text( column );
+}
+
+
+/*!
+ Compares this list view item to \a i using the column \a col in \a
+ ascending order. Returns \< 0 if this item is less than \a i, 0 if
+ they are equal and \> 0 if this item is greater than \a i.
+
+ This function is used for sorting.
+
+ The default implementation compares the item keys (key()) using
+ TQString::localeAwareCompare(). A reimplementation can use
+ different values and a different comparison function. Here is a
+ reimplementation that uses plain Unicode comparison:
+
+ \code
+ int MyListViewItem::compare( TQListViewItem *i, int col,
+ bool ascending ) const
+ {
+ return key( col, ascending ).compare( i->key( col, ascending) );
+ }
+ \endcode
+ We don't recommend using \a ascending so your code can safely
+ ignore it.
+
+ \sa key() TQString::localeAwareCompare() TQString::compare()
+*/
+
+int TQListViewItem::compare( TQListViewItem *i, int col, bool ascending ) const
+{
+ return key( col, ascending ).localeAwareCompare( i->key( col, ascending ) );
+}
+
+/*!
+ Sorts this item's tqchildren using column \a column. This is done in
+ ascending order if \a ascending is TRUE and in descending order if
+ \a ascending is FALSE.
+
+ Asks some of the tqchildren to sort their tqchildren. (TQListView and
+ TQListViewItem ensure that all on-screen objects are properly
+ sorted but may avoid or defer sorting other objects in order to be
+ more responsive.)
+
+ \sa key() compare()
+*/
+
+void TQListViewItem::sortChildItems( int column, bool ascending )
+{
+ // we try HARD not to sort. if we're already sorted, don't.
+ if ( column == (int)lsc && ascending == (bool)lso )
+ return;
+
+ if ( column < 0 )
+ return;
+
+ lsc = column;
+ lso = ascending;
+
+ const int nColumns = ( listView() ? listView()->columns() : 0 );
+
+ // only sort if the item have more than one child.
+ if ( column > nColumns || childItem == 0 || (childItem->siblingItem == 0 && childItem->childItem == 0))
+ return;
+
+ // make an array for qHeapSort()
+ TQListViewPrivate::SortableItem * siblings
+ = new TQListViewPrivate::SortableItem[nChildren];
+ TQListViewItem * s = childItem;
+ int i = 0;
+ while ( s && i < nChildren ) {
+ siblings[i].numCols = nColumns;
+ siblings[i].col = column;
+ siblings[i].asc = ascending;
+ siblings[i].item = s;
+ s = s->siblingItem;
+ i++;
+ }
+
+ // and sort it.
+ qHeapSort( siblings, siblings + nChildren );
+
+ // build the linked list of siblings, in the appropriate
+ // direction, and finally set this->childItem to the new top
+ // child.
+ if ( ascending ) {
+ for( i = 0; i < nChildren - 1; i++ )
+ siblings[i].item->siblingItem = siblings[i+1].item;
+ siblings[nChildren-1].item->siblingItem = 0;
+ childItem = siblings[0].item;
+ } else {
+ for( i = nChildren - 1; i > 0; i-- )
+ siblings[i].item->siblingItem = siblings[i-1].item;
+ siblings[0].item->siblingItem = 0;
+ childItem = siblings[nChildren-1].item;
+ }
+ for ( i = 0; i < nChildren; i++ ) {
+ if ( siblings[i].item->isOpen() )
+ siblings[i].item->sort();
+ }
+ delete[] siblings;
+}
+
+
+/*!
+ Sets this item's height to \a height pixels. This implicitly
+ changes totalHeight(), too.
+
+ Note that a font change causes this height to be overwritten
+ unless you reimplement setup().
+
+ For best results in Windows style we suggest using an even number
+ of pixels.
+
+ \sa height() totalHeight() isOpen();
+*/
+
+void TQListViewItem::setHeight( int height )
+{
+ if ( ownHeight != height ) {
+ if ( visible )
+ ownHeight = height;
+ else
+ ownHeight = 0;
+ invalidateHeight();
+ }
+}
+
+
+/*!
+ Invalidates the cached total height of this item, including all
+ open tqchildren.
+
+ \sa setHeight() height() totalHeight()
+*/
+
+void TQListViewItem::invalidateHeight()
+{
+ if ( maybeTotalHeight < 0 )
+ return;
+ maybeTotalHeight = -1;
+ if ( parentItem && parentItem->isOpen() )
+ parentItem->invalidateHeight();
+}
+
+
+/*!
+ Opens or closes an item, i.e. shows or hides an item's tqchildren.
+
+ If \a o is TRUE all child items are shown initially. The user can
+ hide them by clicking the <b>-</b> icon to the left of the item.
+ If \a o is FALSE, the tqchildren of this item are initially hidden.
+ The user can show them by clicking the <b>+</b> icon to the left
+ of the item.
+
+ \sa height() totalHeight() isOpen()
+*/
+
+void TQListViewItem::setOpen( bool o )
+{
+ if ( o == (bool)open || !enabled )
+ return;
+ open = o;
+
+ // If no tqchildren to show simply emit Q_SIGNALS and return
+ if ( !nChildren ) {
+ TQListView *lv = listView();
+ if ( lv && this != lv->d->r ) {
+ if ( o )
+ emit lv->expanded( this );
+ else
+ emit lv->collapsed( this );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( lv->viewport(), indexOfItem( this ), TQAccessible::StateChanged );
+#endif
+ }
+ return;
+ }
+ invalidateHeight();
+
+ if ( !configured ) {
+ TQListViewItem * l = this;
+ TQPtrStack<TQListViewItem> s;
+ while( l ) {
+ if ( l->open && l->childItem ) {
+ s.push( l->childItem );
+ } else if ( l->childItem ) {
+ // first invisible child is unconfigured
+ TQListViewItem * c = l->childItem;
+ while( c ) {
+ c->configured = FALSE;
+ c = c->siblingItem;
+ }
+ }
+ l->configured = TRUE;
+ l->setup();
+ l = (l == this) ? 0 : l->siblingItem;
+ if ( !l && !s.isEmpty() )
+ l = s.pop();
+ }
+ }
+
+ TQListView *lv = listView();
+
+ if ( open && lv)
+ enforceSortOrder();
+
+ if ( isVisible() && lv && lv->d && lv->d->drawables ) {
+ lv->d->drawables->clear();
+ lv->buildDrawableList();
+ }
+
+ if ( lv && this != lv->d->r ) {
+ if ( o )
+ emit lv->expanded( this );
+ else
+ emit lv->collapsed( this );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( lv->viewport(), indexOfItem( this ), TQAccessible::StateChanged );
+#endif
+ }
+}
+
+
+/*!
+ This virtual function is called before the first time TQListView
+ needs to know the height or any other graphical attribute of this
+ object, and whenever the font, GUI style, or colors of the list
+ view change.
+
+ The default calls widthChanged() and sets the item's height to the
+ height of a single line of text in the list view's font. (If you
+ use icons, multi-line text, etc., you will probably need to call
+ setHeight() yourself or reimplement it.)
+*/
+
+void TQListViewItem::setup()
+{
+ widthChanged();
+ TQListView *lv = listView();
+
+ int ph = 0;
+ int h = 0;
+ if ( lv ) {
+ for ( uint i = 0; i < lv->d->column.size(); ++i ) {
+ if ( pixmap( i ) )
+ ph = TQMAX( ph, pixmap( i )->height() );
+ }
+
+ if ( mlenabled ) {
+ h = ph;
+ for ( int c = 0; c < lv->columns(); ++c ) {
+ int lines = text( c ).tqcontains( TQChar('\n') ) + 1;
+ int tmph = lv->d->fontMetricsHeight
+ + lv->fontMetrics().lineSpacing() * ( lines - 1 );
+ h = TQMAX( h, tmph );
+ }
+ h += 2*lv->itemMargin();
+ } else {
+ h = TQMAX( lv->d->fontMetricsHeight, ph ) + 2*lv->itemMargin();
+ }
+ }
+
+ h = TQMAX( h, TQApplication::globalStrut().height());
+
+ if ( h % 2 > 0 )
+ h++;
+ setHeight( h );
+}
+
+
+
+
+/*!
+ This virtual function is called whenever the user presses the mouse
+ on this item or presses Space on it.
+
+ \sa activatedPos()
+*/
+
+void TQListViewItem::activate()
+{
+}
+
+
+/*!
+ When called from a reimplementation of activate(), this function
+ gives information on how the item was activated. Otherwise the
+ behavior is undefined.
+
+ If activate() was caused by a mouse press, the function sets \a
+ pos to where the user clicked and returns TRUE; otherwise it
+ returns FALSE and does not change \a pos.
+
+ \a pos is relative to the top-left corner of this item.
+
+ \warning We recommend that you ignore this function; it is
+ scheduled to become obsolete.
+
+ \sa activate()
+*/
+
+bool TQListViewItem::activatedPos( TQPoint &pos )
+{
+ if ( activatedByClick )
+ pos = activatedP;
+ return activatedByClick;
+}
+
+
+/*!
+ \fn bool TQListViewItem::isSelectable() const
+
+ Returns TRUE if the item is selectable (as it is by default);
+ otherwise returns FALSE
+
+ \sa setSelectable()
+*/
+
+
+/*!
+ Sets this item to be selectable if \a enable is TRUE (the
+ default) or not to be selectable if \a enable is FALSE.
+
+ The user is not able to select a non-selectable item using either
+ the keyboard or the mouse. This also applies for the application
+ programmer (e.g. setSelected() respects this value).
+
+ \sa isSelectable()
+*/
+
+void TQListViewItem::setSelectable( bool enable )
+{
+ selectable = enable;
+}
+
+
+/*!
+ \fn bool TQListViewItem::isExpandable() const
+
+ Returns TRUE if this item is expandable even when it has no
+ tqchildren; otherwise returns FALSE.
+*/
+
+/*!
+ Sets this item to be expandable even if it has no tqchildren if \a
+ enable is TRUE, and to be expandable only if it has tqchildren if \a
+ enable is FALSE (the default).
+
+ The dirview example uses this in the canonical fashion. It checks
+ whether the directory is empty in setup() and calls
+ setExpandable(TRUE) if not; in setOpen() it reads the contents of
+ the directory and inserts items accordingly. This strategy means
+ that dirview can display the entire file system without reading
+ very much at startup.
+
+ Note that root items are not expandable by the user unless
+ TQListView::setRootIsDecorated() is set to TRUE.
+
+ \sa setSelectable()
+*/
+
+void TQListViewItem::setExpandable( bool enable )
+{
+ expandable = enable;
+}
+
+
+/*!
+ Makes sure that this object's tqchildren are sorted appropriately.
+
+ This only works if every item from the root item down to this item
+ is already sorted.
+
+ \sa sortChildItems()
+*/
+
+void TQListViewItem::enforceSortOrder() const
+{
+ TQListView *lv = listView();
+ if ( !lv || (lv && (lv->d->clearing || lv->d->sortcolumn == Unsorted)) )
+ return;
+ if ( parentItem &&
+ (parentItem->lsc != lsc || parentItem->lso != lso) )
+ ((TQListViewItem *)this)->sortChildItems( (int)parentItem->lsc,
+ (bool)parentItem->lso );
+ else if ( !parentItem &&
+ ( (int)lsc != lv->d->sortcolumn || (bool)lso != lv->d->ascending ) )
+ ((TQListViewItem *)this)->sortChildItems( lv->d->sortcolumn, lv->d->ascending );
+}
+
+
+/*!
+ \fn bool TQListViewItem::isSelected() const
+
+ Returns TRUE if this item is selected; otherwise returns FALSE.
+
+ \sa setSelected() TQListView::setSelected() TQListView::selectionChanged()
+*/
+
+
+/*!
+ If \a s is TRUE this item is selected; otherwise it is deselected.
+
+ This function does not maintain any invariants or tqrepaint anything
+ -- TQListView::setSelected() does that.
+
+ \sa height() totalHeight()
+*/
+
+void TQListViewItem::setSelected( bool s )
+{
+ bool old = selected;
+
+ TQListView *lv = listView();
+ if ( lv && lv->selectionMode() != TQListView::NoSelection) {
+ if ( s && isSelectable() )
+ selected = TRUE;
+ else
+ selected = FALSE;
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ if ( old != (bool)selected ) {
+ int ind = indexOfItem( this );
+ TQAccessible::updateAccessibility( lv->viewport(), ind, TQAccessible::StateChanged );
+ TQAccessible::updateAccessibility( lv->viewport(), ind, selected ? TQAccessible::SelectionAdd : TQAccessible::SelectionRemove );
+ }
+#else
+ TQ_UNUSED( old );
+#endif
+ }
+}
+
+/*!
+ Returns the total height of this object, including any visible
+ tqchildren. This height is recomputed lazily and cached for as long
+ as possible.
+
+ Functions which can affect the total height are, setHeight() which
+ is used to set an item's height, setOpen() to show or hide an
+ item's tqchildren, and invalidateHeight() to tqinvalidate the cached
+ height.
+
+ \sa height()
+*/
+
+int TQListViewItem::totalHeight() const
+{
+ if ( !visible )
+ return 0;
+ if ( maybeTotalHeight >= 0 )
+ return maybeTotalHeight;
+ TQListViewItem * that = (TQListViewItem *)this;
+ if ( !that->configured ) {
+ that->configured = TRUE;
+ that->setup(); // ### virtual non-const function called in const
+ }
+ that->maybeTotalHeight = that->ownHeight;
+
+ if ( !that->isOpen() || !that->childCount() )
+ return that->ownHeight;
+
+ TQListViewItem * child = that->childItem;
+ while ( child != 0 ) {
+ that->maybeTotalHeight += child->totalHeight();
+ child = child->siblingItem;
+ }
+ return that->maybeTotalHeight;
+}
+
+
+/*!
+ Returns the text in column \a column, or TQString::null if there is
+ no text in that column.
+
+ \sa key() paintCell()
+*/
+
+TQString TQListViewItem::text( int column ) const
+{
+ TQListViewPrivate::ItemColumnInfo * l
+ = (TQListViewPrivate::ItemColumnInfo*) columns;
+
+ while( column && l ) {
+ l = l->next;
+ column--;
+ }
+
+ return l ? l->text : TQString::null;
+}
+
+
+/*!
+ Sets the text in column \a column to \a text, if \a column is a
+ valid column number and \a text is different from the existing
+ text.
+
+ If \a text() has been reimplemented, this function may be a no-op.
+
+ \sa text() key()
+*/
+
+void TQListViewItem::setText( int column, const TQString &text )
+{
+ if ( column < 0 )
+ return;
+
+ TQListViewPrivate::ItemColumnInfo * l
+ = (TQListViewPrivate::ItemColumnInfo*) columns;
+ if ( !l ) {
+ l = new TQListViewPrivate::ItemColumnInfo;
+ columns = (void*)l;
+ }
+ for( int c = 0; c < column; c++ ) {
+ if ( !l->next )
+ l->next = new TQListViewPrivate::ItemColumnInfo;
+ l = l->next;
+ }
+ if ( l->text == text )
+ return;
+
+ int oldLc = 0;
+ int newLc = 0;
+ if ( mlenabled ) {
+ if ( !l->text.isEmpty() )
+ oldLc = l->text.tqcontains( TQChar( '\n' ) ) + 1;
+ if ( !text.isEmpty() )
+ newLc = text.tqcontains( TQChar( '\n' ) ) + 1;
+ }
+
+ l->dirty = TRUE;
+ l->text = text;
+ if ( column == (int)lsc )
+ lsc = Unsorted;
+
+ if ( mlenabled && oldLc != newLc )
+ setup();
+ else
+ widthChanged( column );
+
+ TQListView * lv = listView();
+ if ( lv ) {
+ lv->d->useDoubleBuffer = TRUE;
+ lv->triggerUpdate();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ if ( lv->isVisible() )
+ TQAccessible::updateAccessibility( lv->viewport(), indexOfItem(this), TQAccessible::NameChanged );
+#endif
+ }
+}
+
+
+/*!
+ Sets the pixmap in column \a column to \a pm, if \a pm is non-null
+ and different from the current pixmap, and if \a column is
+ non-negative.
+
+ \sa pixmap() setText()
+*/
+
+void TQListViewItem::setPixmap( int column, const TQPixmap & pm )
+{
+ if ( column < 0 )
+ return;
+
+ int oldW = 0;
+ int oldH = 0;
+ if ( pixmap( column ) ) {
+ oldW = pixmap( column )->width();
+ oldH = pixmap( column )->height();
+ }
+
+ TQListViewPrivate::ItemColumnInfo * l
+ = (TQListViewPrivate::ItemColumnInfo*) columns;
+ if ( !l ) {
+ l = new TQListViewPrivate::ItemColumnInfo;
+ columns = (void*)l;
+ }
+
+ for( int c = 0; c < column; c++ ) {
+ if ( !l->next )
+ l->next = new TQListViewPrivate::ItemColumnInfo;
+ l = l->next;
+ }
+
+ if ( ( pm.isNull() && ( !l->pm || l->pm->isNull() ) ) ||
+ ( l->pm && pm.serialNumber() == l->pm->serialNumber() ) )
+ return;
+
+ if ( pm.isNull() ) {
+ delete l->pm;
+ l->pm = 0;
+ } else {
+ if ( l->pm )
+ *(l->pm) = pm;
+ else
+ l->pm = new TQPixmap( pm );
+ }
+
+ int newW = 0;
+ int newH = 0;
+ if ( pixmap( column ) ) {
+ newW = pixmap( column )->width();
+ newH = pixmap( column )->height();
+ }
+
+ if ( oldW != newW || oldH != newH ) {
+ setup();
+ widthChanged( column );
+ invalidateHeight();
+ }
+ TQListView *lv = listView();
+ if ( lv ) {
+ lv->d->useDoubleBuffer = TRUE;
+ lv->triggerUpdate();
+ }
+}
+
+
+/*!
+ Returns the pixmap for \a column, or 0 if there is no pixmap for
+ \a column.
+
+ \sa setText() setPixmap()
+*/
+
+const TQPixmap * TQListViewItem::pixmap( int column ) const
+{
+ TQListViewPrivate::ItemColumnInfo * l
+ = (TQListViewPrivate::ItemColumnInfo*) columns;
+
+ while( column && l ) {
+ l = l->next;
+ column--;
+ }
+
+ return (l && l->pm) ? l->pm : 0;
+}
+
+
+/*!
+ This virtual function paints the contents of one column of an item
+ and aligns it as described by \a align.
+
+ \a p is a TQPainter open on the relevant paint tqdevice. \a p is
+ translated so (0, 0) is the top-left pixel in the cell and \a
+ width-1, height()-1 is the bottom-right pixel \e in the cell. The
+ other properties of \a p (pen, brush, etc) are undefined. \a cg is
+ the color group to use. \a column is the logical column number
+ within the item that is to be painted; 0 is the column which may
+ contain a tree.
+
+ This function may use TQListView::itemMargin() for readability
+ spacing on the left and right sides of data such as text, and
+ should honor isSelected() and TQListView::allColumnsShowFocus().
+
+ If you reimplement this function, you should also reimplement
+ width().
+
+ The rectangle to be painted is in an undefined state when this
+ function is called, so you \e must draw on all the pixels. The
+ painter \a p has the right font on entry.
+
+ \sa paintBranches(), TQListView::drawContentsOffset()
+*/
+
+void TQListViewItem::paintCell( TQPainter * p, const TQColorGroup & cg,
+ int column, int width, int align )
+{
+ // Change width() if you change this.
+
+ if ( !p )
+ return;
+
+ TQListView *lv = listView();
+ if ( !lv )
+ return;
+ TQFontMetrics fm( p->fontMetrics() );
+
+ // had, but we _need_ the column info for the ellipsis thingy!!!
+ if ( !columns ) {
+ for ( uint i = 0; i < lv->d->column.size(); ++i ) {
+ setText( i, text( i ) );
+ }
+ }
+
+ TQString t = text( column );
+
+ if ( columns ) {
+ TQListViewPrivate::ItemColumnInfo *ci = 0;
+ // try until we have a column info....
+ while ( !ci ) {
+ ci = (TQListViewPrivate::ItemColumnInfo*)columns;
+ for ( int i = 0; ci && (i < column); ++i )
+ ci = ci->next;
+
+ if ( !ci ) {
+ setText( column, t );
+ ci = 0;
+ }
+ }
+
+ // if the column width changed and this item was not painted since this change
+ if ( ci && ( ci->width != width || ci->text != t || ci->dirty ) ) {
+ ci->text = t;
+ ci->dirty = FALSE;
+ ci->width = width;
+ ci->truncated = FALSE;
+ // if we have to do the ellipsis thingy calc the truncated text
+ int pw = lv->itemMargin()*2 - lv->d->minLeftBearing - lv->d->minRightBearing;
+ pw += pixmap( column ) ? pixmap( column )->width() + lv->itemMargin() : 0;
+ if ( !mlenabled && fm.width( t ) + pw > width ) {
+ // take care of arabic shaping in width calculation (lars)
+ ci->truncated = TRUE;
+ ci->tmpText = qEllipsisText( t, fm, width - pw, align );
+ } else if ( mlenabled && fm.width( t ) + pw > width ) {
+#ifndef TQT_NO_STRINGLIST
+ TQStringList list = TQStringList::split( TQChar('\n'), t, TRUE );
+ for ( TQStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
+ TQString z = *it;
+ if ( fm.width( z ) + pw > width ) {
+ ci->truncated = TRUE;
+ *it = qEllipsisText( z, fm, width - pw, align );
+ }
+ }
+
+ if ( ci->truncated )
+ ci->tmpText = list.join( TQString("\n") );
+#endif
+ }
+ }
+
+ // if we have to draw the ellipsis thingy, use the truncated text
+ if ( ci && ci->truncated )
+ t = ci->tmpText;
+ }
+
+ int marg = lv->itemMargin();
+ int r = marg;
+ const TQPixmap * icon = pixmap( column );
+
+ const BackgroundMode bgmode = lv->viewport()->backgroundMode();
+ const TQColorGroup::ColorRole crole = TQPalette::backgroundRoleFromMode( bgmode );
+ if ( cg.brush( crole ) != lv->tqcolorGroup().brush( crole ) )
+ p->fillRect( 0, 0, width, height(), cg.brush( crole ) );
+ else
+ lv->paintEmptyArea( p, TQRect( 0, 0, width, height() ) );
+
+
+ // (lars) what does this do???
+#if 0 // RS: ####
+ if ( align != AlignLeft )
+ marg -= lv->d->minRightBearing;
+#endif
+ if ( isSelected() &&
+ (column == 0 || lv->allColumnsShowFocus()) ) {
+ p->fillRect( r - marg, 0, width - r + marg, height(),
+ cg.brush( TQColorGroup::Highlight ) );
+ if ( enabled || !lv )
+ p->setPen( cg.highlightedText() );
+ else if ( !enabled && lv)
+ p->setPen( lv->tqpalette().disabled().highlightedText() );
+ } else {
+ if ( enabled || !lv )
+ p->setPen( cg.text() );
+ else if ( !enabled && lv)
+ p->setPen( lv->tqpalette().disabled().text() );
+ }
+
+
+#if 0
+ bool reverse = TQApplication::reverseLayout();
+#else
+ bool reverse = FALSE;
+#endif
+ int iconWidth = 0;
+
+ if ( icon ) {
+ iconWidth = icon->width() + lv->itemMargin();
+ int xo = r;
+ // we default to AlignVCenter.
+ int yo = ( height() - icon->height() ) / 2;
+
+ // I guess we may as well always respect vertical tqalignment.
+ if ( align & TQt::AlignBottom )
+ yo = height() - icon->height();
+ else if ( align & TQt::AlignTop )
+ yo = 0;
+
+ // respect horizontal tqalignment when there is no text for an item.
+ if ( text(column).isEmpty() ) {
+ if ( align & TQt::AlignRight )
+ xo = width - 2 * marg - iconWidth;
+ else if ( align & TQt::AlignHCenter )
+ xo = ( width - iconWidth ) / 2;
+ }
+ if ( reverse )
+ xo = width - 2 * marg - iconWidth;
+ p->drawPixmap( xo, yo, *icon );
+ }
+
+ if ( !t.isEmpty() ) {
+ if ( !mlenabled ) {
+ if ( !(align & TQt::AlignTop || align & TQt::AlignBottom) )
+ align |= TQt::AlignVCenter;
+ } else {
+ if ( !(align & TQt::AlignVCenter || align & TQt::AlignBottom) )
+ align |= TQt::AlignTop;
+ }
+ if ( !reverse )
+ r += iconWidth;
+
+ if ( !mlenabled ) {
+ p->drawText( r, 0, width-marg-r, height(), align, t );
+ } else {
+ p->drawText( r, marg, width-marg-r, height(), align, t );
+ }
+ }
+
+ if ( mlenabled && column == 0 && isOpen() && childCount() ) {
+ int textheight = fm.size( align, t ).height() + 2 * lv->itemMargin();
+ textheight = TQMAX( textheight, TQApplication::globalStrut().height() );
+ if ( textheight % 2 > 0 )
+ textheight++;
+ if ( textheight < height() ) {
+ int w = lv->treeStepSize() / 2;
+ lv->tqstyle().tqdrawComplexControl( TQStyle::CC_ListView, p, lv,
+ TQRect( 0, textheight, w + 1, height() - textheight + 1 ), cg,
+ lv->isEnabled() ? TQStyle::Style_Enabled : TQStyle::Style_Default,
+ TQStyle::SC_ListViewExpand,
+ (uint)TQStyle::SC_All, TQStyleOption( this ) );
+ }
+ }
+}
+
+/*!
+ Returns the number of pixels of width required to draw column \a c
+ of list view \a lv, using the metrics \a fm without cropping. The
+ list view containing this item may use this information depending
+ on the TQListView::WidthMode settings for the column.
+
+ The default implementation returns the width of the bounding
+ rectangle of the text of column \a c.
+
+ \sa listView() widthChanged() TQListView::setColumnWidthMode()
+ TQListView::itemMargin()
+*/
+int TQListViewItem::width( const TQFontMetrics& fm,
+ const TQListView* lv, int c ) const
+{
+ int w;
+ if ( mlenabled )
+ w = fm.size( TQt::AlignVCenter, text( c ) ).width() + lv->itemMargin() * 2
+ - lv->d->minLeftBearing - lv->d->minRightBearing;
+ else
+ w = fm.width( text( c ) ) + lv->itemMargin() * 2
+ - lv->d->minLeftBearing - lv->d->minRightBearing;
+ const TQPixmap * pm = pixmap( c );
+ if ( pm )
+ w += pm->width() + lv->itemMargin(); // ### correct margin stuff?
+ return TQMAX( w, TQApplication::globalStrut().width() );
+}
+
+
+/*!
+ Paints a focus indicator on the rectangle \a r using painter \a p
+ and colors \a cg.
+
+ \a p is already clipped.
+
+ \sa paintCell() paintBranches() TQListView::setAllColumnsShowFocus()
+*/
+
+void TQListViewItem::paintFocus( TQPainter *p, const TQColorGroup &cg,
+ const TQRect & r )
+{
+ TQListView *lv = listView();
+ if ( lv )
+ lv->tqstyle().tqdrawPrimitive( TQStyle::PE_FocusRect, p, r, cg,
+ (isSelected() ?
+ TQStyle::Style_FocusAtBorder :
+ TQStyle::Style_Default),
+ TQStyleOption(isSelected() ? cg.highlight() : cg.base() ));
+}
+
+
+/*!
+ Paints a set of branches from this item to (some of) its tqchildren.
+
+ Painter \a p is set up with clipping and translation so that you
+ can only draw in the rectangle that needs redrawing; \a cg is the
+ color group to use; the update rectangle is at (0, 0) and has size
+ width \a w by height \a h. The top of the rectangle you own is at
+ \a y (which is never greater than 0 but can be outside the window
+ system's allowed coordinate range).
+
+ The update rectangle is in an undefined state when this function
+ is called; this function must draw on \e all of the pixels.
+
+ \sa paintCell(), TQListView::drawContentsOffset()
+*/
+
+void TQListViewItem::paintBranches( TQPainter * p, const TQColorGroup & cg,
+ int w, int y, int h )
+{
+ TQListView *lv = listView();
+ if ( lv )
+ lv->paintEmptyArea( p, TQRect( 0, 0, w, h ) );
+ if ( !visible || !lv )
+ return;
+ lv->tqstyle().tqdrawComplexControl( TQStyle::CC_ListView, p, lv,
+ TQRect( 0, y, w, h ),
+ cg,
+ lv->isEnabled() ? TQStyle::Style_Enabled :
+ TQStyle::Style_Default,
+ (TQStyle::SC_ListViewBranch |
+ TQStyle::SC_ListViewExpand),
+ TQStyle::SC_None, TQStyleOption(this) );
+}
+
+
+TQListViewPrivate::Root::Root( TQListView * tqparent )
+ : TQListViewItem( tqparent )
+{
+ lv = tqparent;
+ setHeight( 0 );
+ setOpen( TRUE );
+}
+
+
+void TQListViewPrivate::Root::setHeight( int )
+{
+ TQListViewItem::setHeight( 0 );
+}
+
+
+void TQListViewPrivate::Root::invalidateHeight()
+{
+ TQListViewItem::invalidateHeight();
+ lv->triggerUpdate();
+}
+
+
+TQListView * TQListViewPrivate::Root::theListView() const
+{
+ return lv;
+}
+
+
+void TQListViewPrivate::Root::setup()
+{
+ // explicitly nothing
+}
+
+
+
+/*!
+\internal
+If called after a mouse click, tells the list view to ignore a
+following double click. This state is reset after the next mouse click.
+*/
+
+void TQListViewItem::ignoreDoubleClick()
+{
+ TQListView *lv = listView();
+ if ( lv )
+ lv->d->ignoreDoubleClick = TRUE;
+}
+
+
+
+/*!
+ \fn void TQListView::onItem( TQListViewItem *i )
+
+ This signal is emitted when the user moves the mouse cursor onto
+ item \a i, similar to the TQWidget::enterEvent() function.
+*/
+
+// ### bug here too? see qiconview.cppp onItem/onViewport
+
+/*!
+ \fn void TQListView::onViewport()
+
+ This signal is emitted when the user moves the mouse cursor from
+ an item to an empty part of the list view.
+*/
+
+/*!
+ \enum TQListView::SelectionMode
+
+ This enumerated type is used by TQListView to indicate how it
+ reacts to selection by the user.
+
+ \value Single When the user selects an item, any already-selected
+ item becomes unselected. The user can unselect the selected
+ item by clicking on some empty space within the view.
+
+ \value Multi When the user selects an item in the usual way, the
+ selection status of that item is toggled and the other items are
+ left alone. Also, multiple items can be selected by dragging the
+ mouse while the left mouse button stays pressed.
+
+ \value Extended When the user selects an item in the usual way,
+ the selection is cleared and the new item selected. However, if
+ the user presses the Ctrl key when clicking on an item, the
+ clicked item gets toggled and all other items are left untouched.
+ And if the user presses the Shift key while clicking on an item,
+ all items between the current item and the clicked item get
+ selected or unselected, depending on the state of the clicked
+ item. Also, multiple items can be selected by dragging the mouse
+ over them.
+
+ \value NoSelection Items cannot be selected.
+
+ In other words, \c Single is a real single-selection list view, \c
+ Multi a real multi-selection list view, \c Extended is a list view
+ where users can select multiple items but usually want to select
+ either just one or a range of contiguous items, and \c NoSelection
+ is a list view where the user can look but not touch.
+*/
+
+/*!
+ \enum TQListView::ResizeMode
+
+ This enum describes how the list view's header adjusts to resize
+ events which affect the width of the list view.
+
+ \value NoColumn The columns do not get resized in resize events.
+
+ \value AllColumns All columns are resized equally to fit the width
+ of the list view.
+
+ \value LastColumn The last column is resized to fit the width of
+ the list view.
+*/
+
+/*!
+ \enum TQListView::RenameAction
+
+ This enum describes whether a rename operation is accepted if the
+ rename editor loses focus without the user pressing Enter.
+
+ \value Accept Rename if Enter is pressed or focus is lost.
+
+ \value Reject Discard the rename operation if focus is lost (and
+ Enter has not been pressed).
+*/
+
+/*!
+ \class TQListView
+ \brief The TQListView class implements a list/tree view.
+
+ \ingroup advanced
+ \mainclass
+
+ It can display and control a hierarchy of multi-column items, and
+ provides the ability to add new items at any time. The user may
+ select one or many items (depending on the \c SelectionMode) and
+ sort the list in increasing or decreasing order by any column.
+
+ The simplest pattern of use is to create a TQListView, add some
+ column headers using addColumn() and create one or more
+ TQListViewItem or TQCheckListItem objects with the TQListView as
+ tqparent:
+
+ \quotefile xml/tagreader-with-features/structureparser.h
+ \skipto TQListView * table
+ \printline
+ \quotefile xml/tagreader-with-features/structureparser.cpp
+ \skipto addColumn
+ \printline addColumn
+ \printline
+ \skipto new TQListViewItem( table
+ \printline
+
+ Further nodes can be added to the list view object (the root of the
+ tree) or as child nodes to TQListViewItems:
+
+ \skipto for ( int i = 0 ; i < attributes.length();
+ \printuntil }
+
+ (From \link xml/tagreader-with-features/structureparser.cpp
+ xml/tagreader-with-features/structureparser.cpp\endlink)
+
+ The main setup functions are:
+ \table
+ \header \i Function \i Action
+ \row \i \l addColumn()
+ \i Adds a column with a text label and perhaps width. Columns
+ are counted from the left starting with column 0.
+ \row \i \l setColumnWidthMode()
+ \i Sets the column to be resized automatically or not.
+ \row \i \l setAllColumnsShowFocus()
+ \i Sets whether items should show keyboard focus using all
+ columns or just column 0. The default is to show focus
+ just using column 0.
+ \row \i \l setRootIsDecorated()
+ \i Sets whether root items should show open/close decoration to their left.
+ The default is FALSE.
+ \row \i \l setTreeStepSize()
+ \i Sets how many pixels an item's tqchildren are indented
+ relative to their tqparent. The default is 20. This is
+ mostly a matter of taste.
+ \row \i \l setSorting()
+ \i Sets whether the items should be sorted, whether it should
+ be in ascending or descending order, and by what column
+ they should be sorted. By default the list view is sorted
+ by the first column; to switch this off call setSorting(-1).
+ \endtable
+
+ To handle events such as mouse presses on the list view, derived
+ classes can reimplement the TQScrollView functions:
+ \link TQScrollView::contentsMousePressEvent() contentsMousePressEvent\endlink,
+ \link TQScrollView::contentsMouseReleaseEvent() contentsMouseReleaseEvent\endlink,
+ \link TQScrollView::contentsMouseDoubleClickEvent() contentsMouseDoubleClickEvent\endlink,
+ \link TQScrollView::contentsMouseMoveEvent() contentsMouseMoveEvent\endlink,
+ \link TQScrollView::contentsDragEnterEvent() contentsDragEnterEvent\endlink,
+ \link TQScrollView::contentsDragMoveEvent() contentsDragMoveEvent\endlink,
+ \link TQScrollView::contentsDragLeaveEvent() contentsDragLeaveEvent\endlink,
+ \link TQScrollView::contentsDropEvent() contentsDropEvent\endlink, and
+ \link TQScrollView::contentsWheelEvent() contentsWheelEvent\endlink.
+
+ There are also several functions for mapping between items and
+ coordinates. itemAt() returns the item at a position on-screen,
+ tqitemRect() returns the rectangle an item occupies on the screen,
+ and itemPos() returns the position of any item (whether it is
+ on-screen or not). firstChild() returns the list view's first item
+ (not necessarily visible on-screen).
+
+ You can iterate over visible items using
+ TQListViewItem::itemBelow(); over a list view's top-level items
+ using TQListViewItem::firstChild() and
+ TQListViewItem::nextSibling(); or every item using a
+ TQListViewItemIterator. See
+ the TQListViewItem documentation for examples of traversal.
+
+ An item can be moved amongst its siblings using
+ TQListViewItem::moveItem(). To move an item in the hierarchy use
+ takeItem() and insertItem(). Item's (and all their child items)
+ are deleted with \c delete; to delete all the list view's items
+ use clear().
+
+ There are a variety of selection modes described in the
+ TQListView::SelectionMode documentation. The default is \c Single
+ selection, which you can change using setSelectionMode().
+
+ Because TQListView offers multiple selection it must display
+ keyboard focus and selection state separately. Therefore there are
+ functions both to set the selection state of an item
+ (setSelected()) and to set which item displays keyboard focus
+ (setCurrentItem()).
+
+ TQListView emits two groups of Q_SIGNALS; one group Q_SIGNALS changes
+ in selection/focus state and one indicates selection. The first
+ group consists of selectionChanged() (applicable to all list
+ views), selectionChanged(TQListViewItem*) (applicable only to a
+ \c Single selection list view), and currentChanged(TQListViewItem*).
+ The second group consists of doubleClicked(TQListViewItem*),
+ returnPressed(TQListViewItem*),
+ rightButtonClicked(TQListViewItem*, const TQPoint&, int), etc.
+
+ Note that changing the state of the list view in a slot connected
+ to a list view signal may cause unexpected side effects. If you
+ need to change the list view's state in response to a signal, use
+ a \link TQTimer::singleShot() single shot timer\endlink with a
+ time out of 0, and connect this timer to a slot that modifies the
+ list view's state.
+
+ In Motif style, TQListView deviates fairly strongly from the look
+ and feel of the Motif hierarchical tree view. This is done mostly
+ to provide a usable keyboard interface and to make the list view
+ look better with a white background.
+
+ If selectionMode() is \c Single (the default) the user can select
+ one item at a time, e.g. by clicking an item with the mouse, see
+ \l TQListView::SelectionMode for details.
+
+ The list view can be navigated either using the mouse or the
+ keyboard. Clicking a <b>-</b> icon closes an item (hides its
+ tqchildren) and clicking a <b>+</b> icon opens an item (shows its
+ tqchildren). The keyboard controls are these:
+ \table
+ \header \i Keypress \i Action
+ \row \i Home
+ \i Make the first item current and visible.
+ \row \i End
+ \i Make the last item current and visible.
+ \row \i Page Up
+ \i Make the item above the top visible item current and visible.
+ \row \i Page Down
+ \i Make the item below the bottom visible item current and visible.
+ \row \i Up Arrow
+ \i Make the item above the current item current and visible.
+ \row \i Down Arrow
+ \i Make the item below the current item current and visible.
+ \row \i Left Arrow
+ \i If the current item is closed (<b>+</b> icon) or has no
+ tqchildren, make its tqparent item current and visible. If the
+ current item is open (<b>-</b> icon) close it, i.e. hide its
+ tqchildren. Exception: if the current item is the first item
+ and is closed and the horizontal scrollbar is offset to
+ the right the list view will be scrolled left.
+ \row \i Right Arrow
+ \i If the current item is closed (<b>+</b> icon) and has
+ tqchildren, the item is opened. If the current item is
+ opened (<b>-</b> icon) and has tqchildren the item's first
+ child is made current and visible. If the current item has
+ no tqchildren the list view is scrolled right.
+ \endtable
+
+ If the user starts typing letters with the focus in the list view
+ an incremental search will occur. For example if the user types
+ 'd' the current item will change to the first item that begins
+ with the letter 'd'; if they then type 'a', the current item will
+ change to the first item that begins with 'da', and so on. If no
+ item begins with the letters they type the current item doesn't
+ change.
+
+ \warning The list view assumes ownership of all list view items
+ and will delete them when it does not need them any more.
+
+ <img src=qlistview-m.png> <img src=qlistview-w.png>
+
+ \sa TQListViewItem TQCheckListItem
+*/
+
+/*!
+ \fn void TQListView::itemRenamed( TQListViewItem * item, int col )
+
+ \overload
+
+ This signal is emitted when \a item has been renamed, e.g. by
+ in-place renaming, in column \a col.
+
+ \sa TQListViewItem::setRenameEnabled()
+*/
+
+/*!
+ \fn void TQListView::itemRenamed( TQListViewItem * item, int col, const TQString &text)
+
+ This signal is emitted when \a item has been renamed to \a text,
+ e.g. by in in-place renaming, in column \a col.
+
+ \sa TQListViewItem::setRenameEnabled()
+*/
+
+/*!
+ Constructs a new empty list view called \a name with tqparent \a
+ tqparent.
+
+ Performance is boosted by modifying the widget flags \a f so that
+ only part of the TQListViewItem tqchildren is redrawn. This may be
+ unsuitable for custom TQListViewItem classes, in which case \c
+ WStaticContents and \c WNoAutoErase should be cleared.
+
+ \sa TQWidget::clearWFlags() TQt::WidgetFlags
+*/
+TQListView::TQListView( TQWidget * tqparent, const char *name, WFlags f )
+ : TQScrollView( tqparent, name, (WFlags)(f | TQt::WStaticContents | TQt::WNoAutoErase) )
+{
+ init();
+}
+
+void TQListView::init()
+{
+ d = new TQListViewPrivate;
+ d->vci = 0;
+ d->timer = new TQTimer( this );
+ d->levelWidth = 20;
+ d->r = 0;
+ d->rootIsExpandable = 0;
+ d->h = new TQHeader( this, "list view header" );
+ d->h->installEventFilter( this );
+ d->focusItem = 0;
+ d->oldFocusItem = 0;
+ d->drawables = 0;
+ d->dirtyItems = 0;
+ d->dirtyItemTimer = new TQTimer( this );
+ d->visibleTimer = new TQTimer( this );
+ d->renameTimer = new TQTimer( this );
+ d->autoopenTimer = new TQTimer( this );
+ d->margin = 1;
+ d->selectionMode = TQListView::Single;
+ d->sortcolumn = 0;
+ d->ascending = TRUE;
+ d->allColumnsShowFocus = FALSE;
+ d->fontMetricsHeight = fontMetrics().height();
+ d->h->setTracking(TRUE);
+ d->buttonDown = FALSE;
+ d->ignoreDoubleClick = FALSE;
+ d->column.setAutoDelete( TRUE );
+ d->iterators = 0;
+ d->scrollTimer = 0;
+ d->sortIndicator = FALSE;
+ d->clearing = FALSE;
+ d->minLeftBearing = fontMetrics().minLeftBearing();
+ d->minRightBearing = fontMetrics().minRightBearing();
+ d->ellipsisWidth = fontMetrics().width( "..." ) * 2;
+ d->highlighted = 0;
+ d->pressedItem = 0;
+ d->selectAnchor = 0;
+ d->select = TRUE;
+ d->useDoubleBuffer = FALSE;
+ d->startDragItem = 0;
+ d->toolTips = TRUE;
+#ifndef TQT_NO_TOOLTIP
+ d->toolTip = new TQListViewToolTip( viewport(), this );
+#endif
+ d->updateHeader = FALSE;
+ d->fullRepaintOnComlumnChange = FALSE;
+ d->resizeMode = NoColumn;
+ d->defRenameAction = Reject;
+ d->pressedEmptyArea = FALSE;
+ d->startEdit = TRUE;
+ d->ignoreEditAfterFocus = FALSE;
+ d->inMenuMode = FALSE;
+ d->pressedSelected = FALSE;
+
+ setMouseTracking( TRUE );
+ viewport()->setMouseTracking( TRUE );
+
+ connect( d->timer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(updateContents()) );
+ connect( d->dirtyItemTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(updateDirtyItems()) );
+ connect( d->visibleTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(makeVisible()) );
+ connect( d->renameTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(startRename()) );
+ connect( d->autoopenTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(openFocusItem()) );
+
+ connect( d->h, TQT_SIGNAL(sizeChange(int,int,int)),
+ this, TQT_SLOT(handleSizeChange(int,int,int)) );
+ connect( d->h, TQT_SIGNAL(indexChange(int,int,int)),
+ this, TQT_SLOT(handleIndexChange()) );
+ connect( d->h, TQT_SIGNAL(sectionClicked(int)),
+ this, TQT_SLOT(changeSortColumn(int)) );
+ connect( d->h, TQT_SIGNAL(sectionHandleDoubleClicked(int)),
+ this, TQT_SLOT(adjustColumn(int)) );
+ connect( horizontalScrollBar(), TQT_SIGNAL(sliderMoved(int)),
+ d->h, TQT_SLOT(setOffset(int)) );
+ connect( horizontalScrollBar(), TQT_SIGNAL(valueChanged(int)),
+ d->h, TQT_SLOT(setOffset(int)) );
+
+ // will access d->r
+ TQListViewPrivate::Root * r = new TQListViewPrivate::Root( this );
+ r->is_root = TRUE;
+ d->r = r;
+ d->r->setSelectable( FALSE );
+
+ viewport()->setFocusProxy( this );
+ viewport()->setFocusPolicy( Qt::WheelFocus );
+ viewport()->setBackgroundMode( TQt::PaletteBase );
+ setBackgroundMode( TQt::PaletteBackground, TQt::PaletteBase );
+}
+
+/*!
+ \property TQListView::showSortIndicator
+ \brief whether the list view header should display a sort indicator.
+
+ If this property is TRUE, an arrow is drawn in the header of the
+ list view to indicate the sort order of the list view contents.
+ The arrow will be drawn in the correct column and will point up or
+ down, depending on the current sort direction. The default is
+ FALSE (don't show an indicator).
+
+ \sa TQHeader::setSortIndicator()
+*/
+
+void TQListView::setShowSortIndicator( bool show )
+{
+ if ( show == d->sortIndicator )
+ return;
+
+ d->sortIndicator = show;
+ if ( d->sortcolumn != Unsorted && d->sortIndicator )
+ d->h->setSortIndicator( d->sortcolumn, d->ascending );
+ else
+ d->h->setSortIndicator( -1 );
+}
+
+bool TQListView::showSortIndicator() const
+{
+ return d->sortIndicator;
+}
+
+/*!
+ \property TQListView::showToolTips
+ \brief whether this list view should show tooltips for truncated column texts
+
+ The default is TRUE.
+*/
+
+void TQListView::setShowToolTips( bool b )
+{
+ d->toolTips = b;
+}
+
+bool TQListView::showToolTips() const
+{
+ return d->toolTips;
+}
+
+/*!
+ \property TQListView::resizeMode
+ \brief whether all, none or the only the last column should be resized
+
+ Specifies whether all, none or only the last column should be
+ resized to fit the full width of the list view. The values for this
+ property can be one of: \c NoColumn (the default), \c AllColumns
+ or \c LastColumn.
+
+ \warning Setting the resize mode should be done after all necessary
+ columns have been added to the list view, otherwise the behavior is
+ undefined.
+
+ \sa TQHeader, header()
+*/
+
+void TQListView::setResizeMode( ResizeMode m )
+{
+ d->resizeMode = m;
+ if ( m == NoColumn )
+ header()->setStretchEnabled( FALSE );
+ else if ( m == AllColumns )
+ header()->setStretchEnabled( TRUE );
+ else
+ header()->setStretchEnabled( TRUE, header()->count() - 1 );
+}
+
+TQListView::ResizeMode TQListView::resizeMode() const
+{
+ return d->resizeMode;
+}
+
+/*!
+ Destroys the list view, deleting all its items, and frees up all
+ allocated resources.
+*/
+
+TQListView::~TQListView()
+{
+ if ( d->iterators ) {
+ TQListViewItemIterator *i = d->iterators->first();
+ while ( i ) {
+ i->listView = 0;
+ i = d->iterators->next();
+ }
+ delete d->iterators;
+ d->iterators = 0;
+ }
+
+ d->focusItem = 0;
+ delete d->r;
+ d->r = 0;
+ delete d->dirtyItems;
+ d->dirtyItems = 0;
+ delete d->drawables;
+ d->drawables = 0;
+ delete d->vci;
+ d->vci = 0;
+#ifndef TQT_NO_TOOLTIP
+ delete d->toolTip;
+ d->toolTip = 0;
+#endif
+ delete d;
+ d = 0;
+}
+
+
+/*!
+ Calls TQListViewItem::paintCell() and
+ TQListViewItem::paintBranches() as necessary for all list view
+ items that require repainting in the \a cw pixels wide and \a ch
+ pixels high bounding rectangle starting at position \a cx, \a cy
+ with offset \a ox, \a oy. Uses the painter \a p.
+*/
+
+void TQListView::drawContentsOffset( TQPainter * p, int ox, int oy,
+ int cx, int cy, int cw, int ch )
+{
+ if ( columns() == 0 ) {
+ paintEmptyArea( p, TQRect( cx, cy, cw, ch ) );
+ return;
+ }
+
+ if ( !d->drawables ||
+ d->drawables->isEmpty() ||
+ d->topPixel > cy ||
+ d->bottomPixel < cy + ch - 1 ||
+ d->r->maybeTotalHeight < 0 )
+ buildDrawableList();
+
+ if ( d->dirtyItems ) {
+ TQRect br( cx - ox, cy - oy, cw, ch );
+ TQPtrDictIterator<void> it( *(d->dirtyItems) );
+ TQListViewItem * i;
+ while( (i = (TQListViewItem *)(it.currentKey())) != 0 ) {
+ ++it;
+ TQRect ir = tqitemRect( i ).intersect( viewport()->rect() );
+ if ( ir.isEmpty() || br.tqcontains( ir ) )
+ // we're painting this one, or it needs no painting: forget it
+ d->dirtyItems->remove( (void *)i );
+ }
+ if ( d->dirtyItems->count() ) {
+ // there are still items left that need repainting
+ d->dirtyItemTimer->start( 0, TRUE );
+ } else {
+ // we're painting all items that need to be painted
+ delete d->dirtyItems;
+ d->dirtyItems = 0;
+ d->dirtyItemTimer->stop();
+ }
+ }
+
+ p->setFont( font() );
+
+ TQPtrListIterator<TQListViewPrivate::DrawableItem> it( *(d->drawables) );
+
+ TQRect r;
+ int fx = -1, x, fc = 0, lc = 0;
+ int tx = -1;
+ TQListViewPrivate::DrawableItem * current;
+
+ while ( (current = it.current()) != 0 ) {
+ ++it;
+ if ( !current->i->isVisible() )
+ continue;
+ int ih = current->i->height();
+ int ith = current->i->totalHeight();
+ int c;
+ int cs;
+
+ // need to paint current?
+ if ( ih > 0 && current->y < cy+ch && current->y+ih > cy ) {
+ if ( fx < 0 ) {
+ // tqfind first interesting column, once
+ x = 0;
+ c = 0;
+ cs = d->h->cellSize( 0 );
+ while ( x + cs <= cx && c < d->h->count() ) {
+ x += cs;
+ c++;
+ if ( c < d->h->count() )
+ cs = d->h->cellSize( c );
+ }
+ fx = x;
+ fc = c;
+ while( x < cx + cw && c < d->h->count() ) {
+ x += cs;
+ c++;
+ if ( c < d->h->count() )
+ cs = d->h->cellSize( c );
+ }
+ lc = c;
+ }
+
+ x = fx;
+ c = fc;
+ // draw to last interesting column
+
+ bool drawActiveSelection = hasFocus() || d->inMenuMode ||
+ !tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this ) ||
+ ( currentItem() && currentItem()->renameBox && currentItem()->renameBox->hasFocus() );
+ const TQColorGroup &cg = ( drawActiveSelection ? tqcolorGroup() : tqpalette().inactive() );
+
+ while ( c < lc && d->drawables ) {
+ int i = d->h->mapToLogical( c );
+ cs = d->h->cellSize( c );
+ r.setRect( x - ox, current->y - oy, cs, ih );
+ if ( i == 0 && current->i->parentItem )
+ r.setLeft( r.left() + current->l * treeStepSize() );
+
+ p->save();
+ // No need to paint if the cell isn't technically visible
+ if ( !( r.width() == 0 || r.height() == 0 ) ) {
+ p->translate( r.left(), r.top() );
+ int ac = d->h->mapToLogical( c );
+ // map to Left currently. This should change once we
+ // can really reverse the listview.
+ int align = columnAlignment( ac );
+ if ( align == TQt::AlignAuto ) align = TQt::AlignLeft;
+ if ( d->useDoubleBuffer ) {
+ TQRect a( 0, 0, r.width(), current->i->height() );
+ TQSharedDoubleBuffer buffer( p, a, TQSharedDoubleBuffer::Force );
+ if ( buffer.isBuffered() )
+ paintEmptyArea( buffer.painter(), a );
+ buffer.painter()->setFont( p->font() );
+ buffer.painter()->setPen( p->pen() );
+ buffer.painter()->setBrush( p->brush() );
+ buffer.painter()->setBrushOrigin( -r.left(), -r.top() );
+ current->i->paintCell( buffer.painter(), cg, ac, r.width(),
+ align );
+ } else {
+ current->i->paintCell( p, cg, ac, r.width(),
+ align );
+ }
+ }
+ p->restore();
+ x += cs;
+ c++;
+ }
+
+ if ( current->i == d->focusItem && hasFocus() &&
+ !d->allColumnsShowFocus ) {
+ p->save();
+ int cell = d->h->mapToActual( 0 );
+ TQRect r( d->h->cellPos( cell ) - ox, current->y - oy, d->h->cellSize( cell ), ih );
+ if ( current->i->parentItem )
+ r.setLeft( r.left() + current->l * treeStepSize() );
+ if ( r.left() < r.right() )
+ current->i->paintFocus( p, tqcolorGroup(), r );
+ p->restore();
+ }
+ }
+
+ const int cell = d->h->mapToActual( 0 );
+
+ // does current need focus indication?
+ if ( current->i == d->focusItem && hasFocus() &&
+ d->allColumnsShowFocus ) {
+ p->save();
+ int x = -contentsX();
+ int w = header()->cellPos( header()->count() - 1 ) +
+ header()->cellSize( header()->count() - 1 );
+
+ r.setRect( x, current->y - oy, w, ih );
+ if ( d->h->mapToActual( 0 ) == 0 || ( current->l == 0 && !rootIsDecorated() ) ) {
+ int offsetx = TQMIN( current->l * treeStepSize(), d->h->cellSize( cell ) );
+ r.setLeft( r.left() + offsetx );
+ current->i->paintFocus( p, tqcolorGroup(), r );
+ } else {
+ int xdepth = TQMIN( treeStepSize() * ( current->i->depth() + ( rootIsDecorated() ? 1 : 0) )
+ + itemMargin(), d->h->cellSize( cell ) );
+ xdepth += d->h->cellPos( cell );
+ TQRect r1( r );
+ r1.setRight( d->h->cellPos( cell ) - 1 );
+ TQRect r2( r );
+ r2.setLeft( xdepth - 1 );
+ current->i->paintFocus( p, tqcolorGroup(), r1 );
+ current->i->paintFocus( p, tqcolorGroup(), r2 );
+ }
+ p->restore();
+ }
+
+ if ( tx < 0 )
+ tx = d->h->cellPos( cell );
+
+ // do any tqchildren of current need to be painted?
+ if ( ih != ith &&
+ (current->i != d->r || d->rootIsExpandable) &&
+ current->y + ith > cy &&
+ current->y + ih < cy + ch &&
+ tx + current->l * treeStepSize() < cx + cw &&
+ tx + (current->l+1) * treeStepSize() > cx ) {
+ // compute the clip rectangle the safe way
+
+ int rtop = current->y + ih;
+ int rbottom = current->y + ith;
+ int rleft = tx + current->l*treeStepSize();
+ int rright = rleft + treeStepSize();
+
+ int crtop = TQMAX( rtop, cy );
+ int crbottom = TQMIN( rbottom, cy+ch );
+ int crleft = TQMAX( rleft, cx );
+ int crright = TQMIN( rright, cx+cw );
+
+ r.setRect( crleft-ox, crtop-oy,
+ crright-crleft, crbottom-crtop );
+
+ if ( r.isValid() ) {
+ p->save();
+ p->translate( rleft-ox, crtop-oy );
+ current->i->paintBranches( p, tqcolorGroup(), treeStepSize(),
+ rtop - crtop, r.height() );
+ p->restore();
+ }
+ }
+ }
+
+ if ( d->r->totalHeight() < cy + ch )
+ paintEmptyArea( p, TQRect( cx - ox, d->r->totalHeight() - oy,
+ cw, cy + ch - d->r->totalHeight() ) );
+
+ int c = d->h->count()-1;
+ if ( c >= 0 &&
+ d->h->cellPos( c ) + d->h->cellSize( c ) < cx + cw ) {
+ c = d->h->cellPos( c ) + d->h->cellSize( c );
+ paintEmptyArea( p, TQRect( c - ox, cy - oy, cx + cw - c, ch ) );
+ }
+}
+
+
+
+/*!
+ Paints \a rect so that it looks like empty background using
+ painter \a p. \a rect is in widget coordinates, ready to be fed to
+ \a p.
+
+ The default function fills \a rect with the
+ viewport()->backgroundBrush().
+*/
+
+void TQListView::paintEmptyArea( TQPainter * p, const TQRect & rect )
+{
+ TQStyleOption opt( d->sortcolumn, 0 ); // ### hack; in 3.1, add a property in TQListView and TQHeader
+ TQStyle::SFlags how = TQStyle::Style_Default;
+ if ( isEnabled() )
+ how |= TQStyle::Style_Enabled;
+
+ tqstyle().tqdrawComplexControl( TQStyle::CC_ListView,
+ p, this, rect, tqcolorGroup(),
+ how, TQStyle::SC_ListView, TQStyle::SC_None,
+ opt );
+}
+
+
+/*
+ Rebuilds the list of drawable TQListViewItems. This function is
+ const so that const functions can call it without requiring
+ d->drawables to be mutable.
+*/
+
+void TQListView::buildDrawableList() const
+{
+ d->r->enforceSortOrder();
+
+ TQPtrStack<TQListViewPrivate::Pending> stack;
+ stack.push( new TQListViewPrivate::Pending( ((int)d->rootIsExpandable)-1,
+ 0, d->r ) );
+
+ // could mess with cy and ch in order to speed up vertical
+ // scrolling
+ int cy = contentsY();
+ int ch = ((TQListView *)this)->visibleHeight();
+ d->topPixel = cy + ch; // one below bottom
+ d->bottomPixel = cy - 1; // one above top
+
+ TQListViewPrivate::Pending * cur;
+
+ // used to work around lack of support for mutable
+ TQPtrList<TQListViewPrivate::DrawableItem> * dl;
+
+ dl = new TQPtrList<TQListViewPrivate::DrawableItem>;
+ dl->setAutoDelete( TRUE );
+ if ( d->drawables )
+ delete ((TQListView *)this)->d->drawables;
+ ((TQListView *)this)->d->drawables = dl;
+
+ while ( !stack.isEmpty() ) {
+ cur = stack.pop();
+
+ int ih = cur->i->height();
+ int ith = cur->i->totalHeight();
+
+ // if this is not true, buildDrawableList has been called recursivly
+ TQ_ASSERT( dl == d->drawables );
+
+ // is this item, or its branch symbol, inside the viewport?
+ if ( cur->y + ith >= cy && cur->y < cy + ch ) {
+ dl->append( new TQListViewPrivate::DrawableItem(cur));
+ // perhaps adjust topPixel up to this item? may be adjusted
+ // down again if any tqchildren are not to be painted
+ if ( cur->y < d->topPixel )
+ d->topPixel = cur->y;
+ // bottompixel is easy: the bottom item drawn tqcontains it
+ d->bottomPixel = cur->y + ih - 1;
+ }
+
+ // push younger sibling of cur on the stack?
+ if ( cur->y + ith < cy+ch && cur->i->siblingItem )
+ stack.push( new TQListViewPrivate::Pending(cur->l,
+ cur->y + ith,
+ cur->i->siblingItem));
+
+ // do any tqchildren of cur need to be painted?
+ if ( cur->i->isOpen() && cur->i->childCount() &&
+ cur->y + ith > cy &&
+ cur->y + ih < cy + ch ) {
+ cur->i->enforceSortOrder();
+
+ TQListViewItem * c = cur->i->childItem;
+ int y = cur->y + ih;
+
+ // if any of the tqchildren are not to be painted, skip them
+ // and tqinvalidate topPixel
+ while ( c && y + c->totalHeight() <= cy ) {
+ y += c->totalHeight();
+ c = c->siblingItem;
+ d->topPixel = cy + ch;
+ }
+
+ // push one child on the stack, if there is at least one
+ // needing to be painted
+ if ( c && y < cy+ch )
+ stack.push( new TQListViewPrivate::Pending( cur->l + 1,
+ y, c ) );
+ }
+
+ delete cur;
+ }
+}
+
+/*!
+ \property TQListView::treeStepSize
+ \brief the number of pixels a child is offset from its tqparent
+
+ The default is 20 pixels.
+
+ Of course, this property is only meaningful for hierarchical list
+ views.
+*/
+
+int TQListView::treeStepSize() const
+{
+ return d->levelWidth;
+}
+
+void TQListView::setTreeStepSize( int size )
+{
+ if ( size != d->levelWidth ) {
+ d->levelWidth = size;
+ viewport()->tqrepaint( FALSE );
+ }
+}
+
+/*!
+ Inserts item \a i into the list view as a top-level item. You do
+ not need to call this unless you've called takeItem(\a i) or
+ TQListViewItem::takeItem(\a i) and need to reinsert \a i elsewhere.
+
+ \sa TQListViewItem::takeItem() takeItem()
+*/
+
+void TQListView::insertItem( TQListViewItem * i )
+{
+ if ( d->r ) // not for d->r itself
+ d->r->insertItem( i );
+}
+
+
+/*!
+ Removes and deletes all the items in this list view and triggers
+ an update.
+
+ Note that the currentChanged() signal is not emitted when this slot is invoked.
+ \sa triggerUpdate()
+*/
+
+void TQListView::clear()
+{
+ bool wasUpdatesEnabled = viewport()->isUpdatesEnabled();
+ viewport()->setUpdatesEnabled( FALSE );
+ setContentsPos( 0, 0 );
+ viewport()->setUpdatesEnabled( wasUpdatesEnabled );
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ d->clearing = TRUE;
+ clearSelection();
+ if ( d->iterators ) {
+ TQListViewItemIterator *i = d->iterators->first();
+ while ( i ) {
+ i->curr = 0;
+ i = d->iterators->next();
+ }
+ }
+
+ if ( d->drawables )
+ d->drawables->clear();
+ delete d->dirtyItems;
+ d->dirtyItems = 0;
+ d->dirtyItemTimer->stop();
+
+ d->focusItem = 0;
+ d->selectAnchor = 0;
+ d->pressedItem = 0;
+ d->highlighted = 0;
+ d->startDragItem = 0;
+
+ // if it's down its downness makes no sense, so undown it
+ d->buttonDown = FALSE;
+
+ TQListViewItem *c = (TQListViewItem *)d->r->firstChild();
+ TQListViewItem *n;
+ while( c ) {
+ n = (TQListViewItem *)c->nextSibling();
+ delete c;
+ c = n;
+ }
+ resizeContents( d->h->tqsizeHint().width(), contentsHeight() );
+ delete d->r;
+ d->r = 0;
+ TQListViewPrivate::Root * r = new TQListViewPrivate::Root( this );
+ r->is_root = TRUE;
+ d->r = r;
+ d->r->setSelectable( FALSE );
+ blockSignals( block );
+ triggerUpdate();
+ d->clearing = FALSE;
+}
+
+/*!
+ \reimp
+*/
+
+void TQListView::setContentsPos( int x, int y )
+{
+ updateGeometries();
+ TQScrollView::setContentsPos( x, y );
+}
+
+/*!
+ Adds a \a width pixels wide column with the column header \a label
+ to the list view, and returns the index of the new column.
+
+ All columns apart from the first one are inserted to the right of
+ the existing ones.
+
+ If \a width is negative, the new column's \l WidthMode is set to
+ \c Maximum instead of \c Manual.
+
+ \sa setColumnText() setColumnWidth() setColumnWidthMode()
+*/
+int TQListView::addColumn( const TQString &label, int width )
+{
+ int c = d->h->addLabel( label, width );
+ d->column.resize( c+1 );
+ d->column.insert( c, new TQListViewPrivate::Column );
+ d->column[c]->wmode = width >=0 ? Manual : Maximum;
+ updateGeometries();
+ updateGeometry();
+ return c;
+}
+
+/*!
+ \overload
+
+ Adds a \a width pixels wide new column with the header \a label
+ and the \a iconset to the list view, and returns the index of the
+ column.
+
+ If \a width is negative, the new column's \l WidthMode is set to
+ \c Maximum, and to \c Manual otherwise.
+
+ \sa setColumnText() setColumnWidth() setColumnWidthMode()
+*/
+int TQListView::addColumn( const TQIconSet& iconset, const TQString &label, int width )
+{
+ int c = d->h->addLabel( iconset, label, width );
+ d->column.resize( c+1 );
+ d->column.insert( c, new TQListViewPrivate::Column );
+ d->column[c]->wmode = width >=0 ? Manual : Maximum;
+ updateGeometries();
+ updateGeometry();
+ return c;
+}
+
+/*!
+ \property TQListView::columns
+ \brief the number of columns in this list view
+
+ \sa addColumn(), removeColumn()
+*/
+
+int TQListView::columns() const
+{
+ return d->column.count();
+}
+
+/*!
+ Removes the column at position \a index.
+
+ If no columns remain after the column is removed, the
+ list view will be cleared.
+
+ \sa clear()
+*/
+
+void TQListView::removeColumn( int index )
+{
+ if ( index < 0 || index > (int)d->column.count() - 1 )
+ return;
+
+ if ( d->vci ) {
+ TQListViewPrivate::ViewColumnInfo *vi = d->vci, *prev = 0, *next = 0;
+ for ( int i = 0; i < index; ++i ) {
+ if ( vi ) {
+ prev = vi;
+ vi = vi->next;
+ }
+ }
+ if ( vi ) {
+ next = vi->next;
+ if ( prev )
+ prev->next = next;
+ vi->next = 0;
+ delete vi;
+ if ( index == 0 )
+ d->vci = next;
+ }
+ }
+
+ TQListViewItemIterator it( this );
+ for ( ; it.current(); ++it ) {
+ TQListViewPrivate::ItemColumnInfo *ci = (TQListViewPrivate::ItemColumnInfo*)it.current()->columns;
+ if ( ci ) {
+ TQListViewPrivate::ItemColumnInfo *prev = 0, *next = 0;
+ for ( int i = 0; i < index; ++i ) {
+ if ( ci ) {
+ prev = ci;
+ ci = ci->next;
+ }
+ }
+ if ( ci ) {
+ next = ci->next;
+ if ( prev )
+ prev->next = next;
+ ci->next = 0;
+ delete ci;
+ if ( index == 0 )
+ it.current()->columns = next;
+ }
+ }
+ }
+
+ for ( int i = index; i < (int)d->column.size(); ++i ) {
+ TQListViewPrivate::Column *c = d->column.take( i );
+ if ( i == index )
+ delete c;
+ if ( i < (int)d->column.size()-1 )
+ d->column.insert( i, d->column[ i + 1 ] );
+ }
+ d->column.resize( d->column.size() - 1 );
+
+ d->h->removeLabel( index );
+ if (d->resizeMode == LastColumn)
+ d->h->setStretchEnabled( TRUE, d->h->count() - 1 );
+
+ updateGeometries();
+ if ( d->column.count() == 0 )
+ clear();
+ updateGeometry();
+ viewport()->update();
+}
+
+/*!
+ Sets the heading of column \a column to \a label.
+
+ \sa columnText()
+*/
+void TQListView::setColumnText( int column, const TQString &label )
+{
+ if ( column < d->h->count() ) {
+ d->h->setLabel( column, label );
+ updateGeometries();
+ updateGeometry();
+ }
+}
+
+/*!
+ \overload
+
+ Sets the heading of column \a column to \a iconset and \a label.
+
+ \sa columnText()
+*/
+void TQListView::setColumnText( int column, const TQIconSet& iconset, const TQString &label )
+{
+ if ( column < d->h->count() ) {
+ d->h->setLabel( column, iconset, label );
+ updateGeometries();
+ }
+}
+
+/*!
+ Sets the width of column \a column to \a w pixels. Note that if
+ the column has a \c WidthMode other than \c Manual, this width
+ setting may be subsequently overridden.
+
+ \sa columnWidth()
+*/
+void TQListView::setColumnWidth( int column, int w )
+{
+ int oldw = d->h->sectionSize( column );
+ if ( column < d->h->count() && oldw != w ) {
+ d->h->resizeSection( column, w );
+ disconnect( d->h, TQT_SIGNAL(sizeChange(int,int,int)),
+ this, TQT_SLOT(handleSizeChange(int,int,int)) );
+ emit d->h->sizeChange( column, oldw, w);
+ connect( d->h, TQT_SIGNAL(sizeChange(int,int,int)),
+ this, TQT_SLOT(handleSizeChange(int,int,int)) );
+ updateGeometries();
+ viewport()->update();
+ }
+}
+
+
+/*!
+ Returns the text of column \a c.
+
+ \sa setColumnText()
+*/
+
+TQString TQListView::columnText( int c ) const
+{
+ return d->h->label(c);
+}
+
+/*!
+ Returns the width of column \a c.
+
+ \sa setColumnWidth()
+*/
+
+int TQListView::columnWidth( int c ) const
+{
+ int actual = d->h->mapToActual( c );
+ return d->h->cellSize( actual );
+}
+
+
+/*!
+ \enum TQListView::WidthMode
+
+ This enum type describes how the width of a column in the view
+ changes.
+
+ \value Manual the column width does not change automatically.
+
+ \value Maximum the column is automatically sized according to the
+ widths of all items in the column. (Note: The column never shrinks
+ in this case.) This means that the column is always resized to the
+ width of the item with the largest width in the column.
+
+ \sa setColumnWidth() setColumnWidthMode() columnWidth()
+*/
+
+
+/*!
+ Sets column \a{c}'s width mode to \a mode. The default depends on
+ the original width argument to addColumn().
+
+ \sa TQListViewItem::width()
+*/
+
+void TQListView::setColumnWidthMode( int c, WidthMode mode )
+{
+ if ( c < d->h->count() )
+ d->column[c]->wmode = mode;
+}
+
+
+/*!
+ Returns the \c WidthMode for column \a c.
+
+ \sa setColumnWidthMode()
+*/
+
+TQListView::WidthMode TQListView::columnWidthMode( int c ) const
+{
+ if ( c < d->h->count() )
+ return d->column[c]->wmode;
+ else
+ return Manual;
+}
+
+
+/*!
+ Sets column \a{column}'s tqalignment to \a align. The tqalignment is
+ ultimately passed to TQListViewItem::paintCell() for each item in
+ the list view. For horizontally aligned text with TQt::AlignLeft or
+ TQt::AlignHCenter the ellipsis (...) will be to the right, for
+ TQt::AlignRight the ellipsis will be to the left.
+
+ \sa TQt::AlignmentFlags
+*/
+
+void TQListView::setColumnAlignment( int column, int align )
+{
+ if ( column < 0 )
+ return;
+ if ( !d->vci )
+ d->vci = new TQListViewPrivate::ViewColumnInfo;
+ TQListViewPrivate::ViewColumnInfo * l = d->vci;
+ while( column ) {
+ if ( !l->next )
+ l->next = new TQListViewPrivate::ViewColumnInfo;
+ l = l->next;
+ column--;
+ }
+ if ( l->align == align )
+ return;
+ l->align = align;
+ triggerUpdate();
+}
+
+
+/*!
+ Returns the tqalignment of column \a column. The default is \c
+ AlignAuto.
+
+ \sa TQt::AlignmentFlags
+*/
+
+int TQListView::columnAlignment( int column ) const
+{
+ if ( column < 0 || !d->vci )
+ return TQt::AlignAuto;
+ TQListViewPrivate::ViewColumnInfo * l = d->vci;
+ while( column ) {
+ if ( !l->next )
+ l->next = new TQListViewPrivate::ViewColumnInfo;
+ l = l->next;
+ column--;
+ }
+ return l ? l->align : TQt::AlignAuto;
+}
+
+
+
+/*!
+ \reimp
+ */
+void TQListView::show()
+{
+ // Reimplemented to setx the correct background mode and viewed
+ // area size.
+ if ( !isVisible() ) {
+ reconfigureItems();
+ updateGeometries();
+ }
+ TQScrollView::show();
+}
+
+
+/*!
+ Updates the sizes of the viewport, header, scroll bars and so on.
+
+ \warning Don't call this directly; call triggerUpdate() instead.
+*/
+
+void TQListView::updateContents()
+{
+ if ( d->updateHeader )
+ header()->adjustHeaderSize();
+ d->updateHeader = FALSE;
+ if ( !isVisible() ) {
+ // Not in response to a setText/setPixmap any more.
+ d->useDoubleBuffer = FALSE;
+
+ return;
+ }
+ if ( d->drawables ) {
+ delete d->drawables;
+ d->drawables = 0;
+ }
+ viewport()->setUpdatesEnabled( FALSE );
+ updateGeometries();
+ viewport()->setUpdatesEnabled( TRUE );
+ viewport()->tqrepaint( FALSE );
+ d->useDoubleBuffer = FALSE;
+}
+
+
+void TQListView::updateGeometries()
+{
+ int th = d->r->totalHeight();
+ int tw = d->h->headerWidth();
+ if ( d->h->offset() &&
+ tw < d->h->offset() + d->h->width() )
+ horizontalScrollBar()->setValue( tw - TQListView::d->h->width() );
+#if 0
+ if ( TQApplication::reverseLayout() && d->h->offset() != horizontalScrollBar()->value() )
+ horizontalScrollBar()->setValue( d->h->offset() );
+#endif
+ verticalScrollBar()->raise();
+ resizeContents( tw, th );
+ if ( d->h->isHidden() ) {
+ setMargins( 0, 0, 0, 0 );
+ } else {
+ TQSize hs( d->h->tqsizeHint() );
+ setMargins( 0, hs.height(), 0, 0 );
+ d->h->setGeometry( viewport()->x(), viewport()->y()-hs.height(),
+ visibleWidth(), hs.height() );
+ }
+}
+
+
+/*!
+ Updates the display when the section \a section has changed size
+ from the old size, \a os, to the new size, \a ns.
+*/
+
+void TQListView::handleSizeChange( int section, int os, int ns )
+{
+ bool upe = viewport()->isUpdatesEnabled();
+ viewport()->setUpdatesEnabled( FALSE );
+ int sx = horizontalScrollBar()->value();
+ bool sv = horizontalScrollBar()->isVisible();
+ updateGeometries();
+ bool fullRepaint = d->fullRepaintOnComlumnChange || sx != horizontalScrollBar()->value()
+ || sv != horizontalScrollBar()->isVisible();
+ d->fullRepaintOnComlumnChange = FALSE;
+ viewport()->setUpdatesEnabled( upe );
+
+ if ( fullRepaint ) {
+ viewport()->tqrepaint( FALSE );
+ return;
+ }
+
+ int actual = d->h->mapToActual( section );
+ int dx = ns - os;
+ int left = d->h->cellPos( actual ) - contentsX() + d->h->cellSize( actual );
+ if ( dx > 0 )
+ left -= dx;
+ if ( left < visibleWidth() )
+ viewport()->scroll( dx, 0, TQRect( left, 0, visibleWidth() - left, visibleHeight() ) );
+ viewport()->tqrepaint( left - 4 - d->ellipsisWidth, 0, 4 + d->ellipsisWidth,
+ visibleHeight(), FALSE ); // border between the items and ellipses width
+
+ // map auto to left for now. Need to fix this once we support
+ // reverse tqlayout on the listview.
+ int align = columnAlignment( section );
+ if ( align == TQt::AlignAuto ) align = TQt::AlignLeft;
+ if ( align != TQt::AlignAuto && align != TQt::AlignLeft )
+ viewport()->tqrepaint( d->h->cellPos( actual ) - contentsX(), 0,
+ d->h->cellSize( actual ), visibleHeight() );
+
+ if ( currentItem() && currentItem()->renameBox ) {
+ TQRect r = tqitemRect( currentItem() );
+ r = TQRect( viewportToContents( r.topLeft() ), r.size() );
+ r.setLeft( header()->sectionPos( currentItem()->renameCol ) );
+ r.setWidth( header()->sectionSize( currentItem()->renameCol ) - 1 );
+ if ( currentItem()->renameCol == 0 )
+ r.setLeft( r.left() + itemMargin() + ( currentItem()->depth() +
+ ( rootIsDecorated() ? 1 : 0 ) ) * treeStepSize() - 1 );
+ if ( currentItem()->pixmap( currentItem()->renameCol ) )
+ r.setLeft( r.left() + currentItem()->pixmap( currentItem()->renameCol )->width() );
+ if ( r.x() - contentsX() < 0 )
+ r.setX( contentsX() );
+ if ( r.width() > visibleWidth() )
+ r.setWidth( visibleWidth() );
+ addChild( currentItem()->renameBox, r.x(), r.y() );
+ currentItem()->renameBox->resize( r.size() );
+ }
+}
+
+
+/*
+ Very smart internal slot that repaints \e only the items that need
+ to be repainted. Don't use this directly; call repaintItem()
+ instead.
+*/
+
+void TQListView::updateDirtyItems()
+{
+ if ( d->timer->isActive() || !d->dirtyItems )
+ return;
+ TQRect ir;
+ TQPtrDictIterator<void> it( *(d->dirtyItems) );
+ TQListViewItem * i;
+ while( (i = (TQListViewItem *)(it.currentKey())) != 0 ) {
+ ++it;
+ ir = ir.unite( tqitemRect(i) );
+ }
+ if ( !ir.isEmpty() ) { // rectangle to be repainted
+ if ( ir.x() < 0 )
+ ir.moveBy( -ir.x(), 0 );
+ viewport()->tqrepaint( ir, FALSE );
+ }
+}
+
+
+void TQListView::makeVisible()
+{
+ if ( d->focusItem )
+ ensureItemVisible( d->focusItem );
+}
+
+
+/*!
+ Ensures that the header is correctly sized and positioned when the
+ resize event \a e occurs.
+*/
+
+void TQListView::resizeEvent( TQResizeEvent *e )
+{
+ TQScrollView::resizeEvent( e );
+ d->fullRepaintOnComlumnChange = TRUE;
+ d->h->resize( visibleWidth(), d->h->height() );
+
+#ifdef USE_QT4
+ #warning [FIXME] Why do I have to force the resize event here under Qt4?
+ if (d->h->testAttribute(Qt::WA_WState_Created) == 0)
+ d->h->resizeEvent( e );
+#endif
+}
+
+/*! \reimp */
+
+void TQListView::viewportResizeEvent( TQResizeEvent *e )
+{
+ TQScrollView::viewportResizeEvent( e );
+ d->h->resize( visibleWidth(), d->h->height() );
+ if ( resizeMode() != NoColumn && currentItem() && currentItem()->renameBox ) {
+ TQRect r = tqitemRect( currentItem() );
+ r = TQRect( viewportToContents( r.topLeft() ), r.size() );
+ r.setLeft( header()->sectionPos( currentItem()->renameCol ) );
+ r.setWidth( header()->sectionSize( currentItem()->renameCol ) - 1 );
+ if ( currentItem()->renameCol == 0 )
+ r.setLeft( r.left() + itemMargin() + ( currentItem()->depth() +
+ ( rootIsDecorated() ? 1 : 0 ) ) * treeStepSize() - 1 );
+ if ( currentItem()->pixmap( currentItem()->renameCol ) )
+ r.setLeft( r.left() + currentItem()->pixmap( currentItem()->renameCol )->width() );
+ if ( r.x() - contentsX() < 0 )
+ r.setX( contentsX() );
+ if ( r.width() > visibleWidth() )
+ r.setWidth( visibleWidth() );
+ addChild( currentItem()->renameBox, r.x(), r.y() );
+ currentItem()->renameBox->resize( r.size() );
+ }
+}
+
+/*!
+ Triggers a size, tqgeometry and content update during the next
+ iteration of the event loop. Ensures that there'll be just one
+ update to avoid flicker.
+*/
+
+void TQListView::triggerUpdate()
+{
+ if ( !isVisible() || !isUpdatesEnabled() ) {
+ // Not in response to a setText/setPixmap any more.
+ d->useDoubleBuffer = FALSE;
+
+ return; // it will update when shown, or something.
+ }
+
+ d->timer->start( 0, TRUE );
+}
+
+
+/*!
+ Redirects the event \a e relating to object \a o, for the viewport
+ to mousePressEvent(), keyPressEvent() and friends.
+*/
+
+bool TQListView::eventFilter( TQObject * o, TQEvent * e )
+{
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->h) &&
+ e->type() >= TQEvent::MouseButtonPress &&
+ e->type() <= TQEvent::MouseMove ) {
+ TQMouseEvent * me = (TQMouseEvent *)e;
+ TQMouseEvent me2( me->type(),
+ TQPoint( me->pos().x(),
+ me->pos().y() - d->h->height() ),
+ me->button(), me->state() );
+ switch( me2.type() ) {
+ case TQEvent::MouseButtonDblClick:
+ if ( me2.button() == Qt::RightButton )
+ return TRUE;
+ break;
+ case TQEvent::MouseMove:
+ if ( me2.state() & Qt::RightButton ) {
+ viewportMouseMoveEvent( &me2 );
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ } else if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(viewport()) ) {
+ TQFocusEvent * fe = (TQFocusEvent *)e;
+
+ switch( e->type() ) {
+ case TQEvent::FocusIn:
+ focusInEvent( fe );
+ return TRUE;
+ case TQEvent::FocusOut:
+ focusOutEvent( fe );
+ return TRUE;
+ default:
+ // nothing
+ break;
+ }
+ } else if ( ::tqqt_cast<TQLineEdit*>(o) ) {
+ if ( currentItem() && currentItem()->renameBox ) {
+ if ( e->type() == TQEvent::KeyPress ) {
+ TQKeyEvent *ke = (TQKeyEvent*)e;
+ if ( ke->key() == Qt::Key_Return ||
+ ke->key() == Qt::Key_Enter ) {
+ currentItem()->okRename( currentItem()->renameCol );
+ return TRUE;
+ } else if ( ke->key() == Key_Escape ) {
+ currentItem()->cancelRename( currentItem()->renameCol );
+ return TRUE;
+ }
+ } else if ( e->type() == TQEvent::FocusOut ) {
+ if ( ( (TQFocusEvent*)e )->reason() != TQFocusEvent::Popup ) {
+ TQCustomEvent *e = new TQCustomEvent( 9999 );
+ TQApplication::postEvent( o, e );
+ return TRUE;
+ }
+ } else if ( e->type() == 9999 ) {
+ if ( d->defRenameAction == Reject )
+ currentItem()->cancelRename( currentItem()->renameCol );
+ else
+ currentItem()->okRename( currentItem()->renameCol );
+ return TRUE;
+ }
+ }
+ }
+
+ return TQScrollView::eventFilter( o, e );
+}
+
+
+/*!
+ Returns a pointer to the list view containing this item.
+
+ Note that this function traverses the items to the root to tqfind the
+ listview. This function will return 0 for taken items - see
+ TQListViewItem::takeItem()
+*/
+
+TQListView * TQListViewItem::listView() const
+{
+ const TQListViewItem* c = this;
+ while ( c && !c->is_root )
+ c = c->parentItem;
+ if ( !c )
+ return 0;
+ return ((TQListViewPrivate::Root*)c)->theListView();
+}
+
+
+/*!
+ Returns the depth of this item.
+*/
+int TQListViewItem::depth() const
+{
+ return parentItem ? parentItem->depth()+1 : -1; // -1 == the hidden root
+}
+
+
+/*!
+ Returns a pointer to the item immediately above this item on the
+ screen. This is usually the item's closest older sibling, but it
+ may also be its tqparent or its next older sibling's youngest child,
+ or something else if anyoftheabove->height() returns 0. Returns 0
+ if there is no item immediately above this item.
+
+ This function assumes that all parents of this item are open (i.e.
+ that this item is visible, or can be made visible by scrolling).
+
+ This function might be relatively slow because of the tree
+ traversions needed to tqfind the correct item.
+
+ \sa itemBelow() TQListView::tqitemRect()
+*/
+
+TQListViewItem * TQListViewItem::itemAbove()
+{
+ if ( !parentItem )
+ return 0;
+
+ TQListViewItem * c = parentItem;
+ if ( c->childItem != this ) {
+ c = c->childItem;
+ while( c && c->siblingItem != this )
+ c = c->siblingItem;
+ if ( !c )
+ return 0;
+ while( c->isOpen() && c->childItem ) {
+ c = c->childItem;
+ while( c->siblingItem )
+ c = c->siblingItem; // assign c's sibling to c
+ }
+ }
+ if ( c && ( !c->height() || !c->isEnabled() ) )
+ return c->itemAbove();
+ return c;
+}
+
+
+/*!
+ Returns a pointer to the item immediately below this item on the
+ screen. This is usually the item's eldest child, but it may also
+ be its next younger sibling, its tqparent's next younger sibling,
+ grandtqparent's, etc., or something else if anyoftheabove->height()
+ returns 0. Returns 0 if there is no item immediately below this
+ item.
+
+ This function assumes that all parents of this item are open (i.e.
+ that this item is visible or can be made visible by scrolling).
+
+ \sa itemAbove() TQListView::tqitemRect()
+*/
+
+TQListViewItem * TQListViewItem::itemBelow()
+{
+ TQListViewItem * c = 0;
+ if ( isOpen() && childItem ) {
+ c = childItem;
+ } else if ( siblingItem ) {
+ c = siblingItem;
+ } else if ( parentItem ) {
+ c = this;
+ do {
+ c = c->parentItem;
+ } while( c->parentItem && !c->siblingItem );
+ if ( c )
+ c = c->siblingItem;
+ }
+ if ( c && ( !c->height() || !c->isEnabled() ) )
+ return c->itemBelow();
+ return c;
+}
+
+
+/*!
+ \fn bool TQListViewItem::isOpen () const
+
+ Returns TRUE if this list view item has tqchildren \e and they are
+ not explicitly hidden; otherwise returns FALSE.
+
+ \sa setOpen()
+*/
+
+/*!
+ Returns the first (top) child of this item, or 0 if this item has
+ no tqchildren.
+
+ Note that the tqchildren are not guaranteed to be sorted properly.
+ TQListView and TQListViewItem try to postpone or avoid sorting to
+ the greatest degree possible, in order to keep the user interface
+ snappy.
+
+ \sa nextSibling() sortChildItems()
+*/
+
+TQListViewItem* TQListViewItem::firstChild() const
+{
+ enforceSortOrder();
+ return childItem;
+}
+
+
+/*!
+ Returns the tqparent of this item, or 0 if this item has no tqparent.
+
+ \sa firstChild(), nextSibling()
+*/
+
+TQListViewItem* TQListViewItem::tqparent() const
+{
+ if ( !parentItem || parentItem->is_root ) return 0;
+ return parentItem;
+}
+
+
+/*!
+ \fn TQListViewItem* TQListViewItem::nextSibling() const
+
+ Returns the sibling item below this item, or 0 if there is no
+ sibling item after this item.
+
+ Note that the siblings are not guaranteed to be sorted properly.
+ TQListView and TQListViewItem try to postpone or avoid sorting to
+ the greatest degree possible, in order to keep the user interface
+ snappy.
+
+ \sa firstChild() sortChildItems()
+*/
+
+/*!
+ \fn int TQListViewItem::childCount () const
+
+ Returns how many tqchildren this item has. The count only includes
+ the item's immediate tqchildren.
+*/
+
+
+/*!
+ Returns the height of this item in pixels. This does not include
+ the height of any tqchildren; totalHeight() returns that.
+*/
+int TQListViewItem::height() const
+{
+ TQListViewItem * that = (TQListViewItem *)this;
+ if ( !that->configured ) {
+ that->configured = TRUE;
+ that->setup(); // ### virtual non-const function called in const
+ }
+
+ return visible ? ownHeight : 0;
+}
+
+/*!
+ Call this function when the value of width() may have changed for
+ column \a c. Normally, you should call this if text(c) changes.
+ Passing -1 for \a c indicates that all columns may have changed.
+ It is more efficient to pass -1 if two or more columns have
+ changed than to call widthChanged() separately for each one.
+
+ \sa width()
+*/
+void TQListViewItem::widthChanged( int c ) const
+{
+ TQListView *lv = listView();
+ if ( lv )
+ lv->widthChanged( this, c );
+}
+
+/*!
+ \fn void TQListView::dropped ( TQDropEvent * e )
+
+ This signal is emitted, when a drop event occurred on the
+ viewport (not onto an item).
+
+ \a e provides all the information about the drop.
+*/
+
+/*!
+ \fn void TQListView::selectionChanged()
+
+ This signal is emitted whenever the set of selected items has
+ changed (normally before the screen update). It is available in
+ \c Single, \c Multi, and \c Extended selection modes, but is most
+ useful in \c Multi selection mode.
+
+ \warning Do not delete any TQListViewItem objects in Q_SLOTS
+ connected to this signal.
+
+ \sa setSelected() TQListViewItem::setSelected()
+*/
+
+
+/*!
+ \fn void TQListView::pressed( TQListViewItem *item )
+
+ This signal is emitted whenever the user presses the mouse button
+ in a list view. \a item is the list view item on which the user
+ pressed the mouse button, or 0 if the user didn't press the mouse
+ on an item.
+
+ \warning Do not delete any TQListViewItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \fn void TQListView::pressed( TQListViewItem *item, const TQPoint &pnt, int c )
+
+ \overload
+
+ This signal is emitted whenever the user presses the mouse button
+ in a list view. \a item is the list view item on which the user
+ pressed the mouse button, or 0 if the user didn't press the mouse
+ on an item. \a pnt is the position of the mouse cursor in global
+ coordinates, and \a c is the column where the mouse cursor was
+ when the user pressed the mouse button.
+
+ \warning Do not delete any TQListViewItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \fn void TQListView::clicked( TQListViewItem *item )
+
+ This signal is emitted whenever the user clicks (mouse pressed \e
+ and mouse released) in the list view. \a item is the clicked list
+ view item, or 0 if the user didn't click on an item.
+
+ \warning Do not delete any TQListViewItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \fn void TQListView::mouseButtonClicked(int button, TQListViewItem * item, const TQPoint & pos, int c)
+
+ This signal is emitted whenever the user clicks (mouse pressed \e
+ and mouse released) in the list view at position \a pos. \a button
+ is the mouse button that the user pressed, \a item is the clicked
+ list view item or 0 if the user didn't click on an item. If \a
+ item is not 0, \a c is the list view column into which the user
+ pressed; if \a item is 0 \a{c}'s value is undefined.
+
+ \warning Do not delete any TQListViewItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \fn void TQListView::mouseButtonPressed(int button, TQListViewItem * item, const TQPoint & pos, int c)
+
+ This signal is emitted whenever the user pressed the mouse button
+ in the list view at position \a pos. \a button is the mouse button
+ which the user pressed, \a item is the pressed list view item or 0
+ if the user didn't press on an item. If \a item is not 0, \a c is
+ the list view column into which the user pressed; if \a item is 0
+ \a{c}'s value is undefined.
+
+ \warning Do not delete any TQListViewItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \fn void TQListView::clicked( TQListViewItem *item, const TQPoint &pnt, int c )
+
+ \overload
+
+ This signal is emitted whenever the user clicks (mouse pressed \e
+ and mouse released) in the list view. \a item is the clicked list
+ view item, or 0 if the user didn't click on an item. \a pnt is the
+ position where the user has clicked in global coordinates. If \a
+ item is not 0, \a c is the list view column into which the user
+ pressed; if \a item is 0 \a{c}'s value is undefined.
+
+ \warning Do not delete any TQListViewItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+/*!
+ \fn void TQListView::selectionChanged( TQListViewItem * )
+
+ \overload
+
+ This signal is emitted whenever the selected item has changed in
+ \c Single selection mode (normally after the screen update). The
+ argument is the newly selected item. If the selection is cleared
+ (when, for example, the user clicks in the unused area of the list
+ view) then this signal will not be emitted.
+
+ In \c Multi selection mode, use the no argument overload of this
+ signal.
+
+ \warning Do not delete any TQListViewItem objects in Q_SLOTS
+ connected to this signal.
+
+ \sa setSelected() TQListViewItem::setSelected() currentChanged()
+*/
+
+
+/*!
+ \fn void TQListView::currentChanged( TQListViewItem * )
+
+ This signal is emitted whenever the current item has changed
+ (normally after the screen update). The current item is the item
+ responsible for indicating keyboard focus.
+
+ The argument is the newly current item, or 0 if the change made no
+ item current. This can happen, for example, if all items in the
+ list view are deleted.
+
+ \warning Do not delete any TQListViewItem objects in Q_SLOTS
+ connected to this signal.
+
+ \sa setCurrentItem() currentItem()
+*/
+
+
+/*!
+ \fn void TQListView::expanded( TQListViewItem *item )
+
+ This signal is emitted when \a item has been expanded, i.e. when
+ the tqchildren of \a item are shown.
+
+ \sa setOpen() collapsed()
+*/
+
+/*!
+ \fn void TQListView::collapsed( TQListViewItem *item )
+
+ This signal is emitted when the \a item has been collapsed, i.e.
+ when the tqchildren of \a item are hidden.
+
+ \sa setOpen() expanded()
+*/
+
+/*!
+ Processes the mouse press event \a e on behalf of the viewed widget.
+*/
+void TQListView::contentsMousePressEvent( TQMouseEvent * e )
+{
+ contentsMousePressEventEx( e );
+}
+
+void TQListView::contentsMousePressEventEx( TQMouseEvent * e )
+{
+ if ( !e )
+ return;
+
+ if ( !d->ignoreEditAfterFocus )
+ d->startEdit = TRUE;
+ d->ignoreEditAfterFocus = FALSE;
+
+ if ( currentItem() && currentItem()->renameBox &&
+ !tqitemRect( currentItem() ).tqcontains( e->pos() ) ) {
+ d->startEdit = FALSE;
+ if ( d->defRenameAction == Reject )
+ currentItem()->cancelRename( currentItem()->renameCol );
+ else
+ currentItem()->okRename( currentItem()->renameCol );
+ }
+
+ d->startDragItem = 0;
+ d->dragStartPos = e->pos();
+ TQPoint vp = contentsToViewport( e->pos() );
+
+ d->ignoreDoubleClick = FALSE;
+ d->buttonDown = TRUE;
+
+ TQListViewItem * i = itemAt( vp );
+ d->pressedEmptyArea = e->y() > contentsHeight();
+ if ( i && !i->isEnabled() )
+ return;
+ if ( d->startEdit && ( i != currentItem() || (i && !i->isSelected()) ) )
+ d->startEdit = FALSE;
+ TQListViewItem *oldCurrent = currentItem();
+
+ if ( e->button() == Qt::RightButton && (e->state() & ControlButton ) )
+ goto emit_Q_SIGNALS;
+
+ if ( !i ) {
+ if ( !( e->state() & ControlButton ) )
+ clearSelection();
+ goto emit_Q_SIGNALS;
+ } else {
+ // No new anchor when using shift
+ if ( !(e->state() & ShiftButton) )
+ d->selectAnchor = i;
+ }
+
+ if ( (i->isExpandable() || i->childCount()) &&
+ d->h->mapToLogical( d->h->cellAt( vp.x() ) ) == 0 ) {
+ int x1 = vp.x() +
+ d->h->offset() -
+ d->h->cellPos( d->h->mapToActual( 0 ) );
+ TQPtrListIterator<TQListViewPrivate::DrawableItem> it( *(d->drawables) );
+ while( it.current() && it.current()->i != i )
+ ++it;
+
+ if ( it.current() ) {
+ x1 -= treeStepSize() * (it.current()->l - 1);
+ TQStyle::SubControl ctrl =
+ tqstyle().querySubControl( TQStyle::CC_ListView,
+ this, TQPoint(x1, e->pos().y()),
+ TQStyleOption(i) );
+ if( ctrl == TQStyle::SC_ListViewExpand &&
+ e->type() == tqstyle().tqstyleHint(TQStyle::SH_ListViewExpand_SelectMouseType, this)) {
+ d->buttonDown = FALSE;
+ if ( e->button() == Qt::LeftButton ) {
+ bool close = i->isOpen();
+ setOpen( i, !close );
+ // ### Looks dangerous, removed because of reentrance problems
+ // tqApp->processEvents();
+ if ( !d->focusItem ) {
+ d->focusItem = i;
+ repaintItem( d->focusItem );
+ emit currentChanged( d->focusItem );
+ }
+ if ( close ) {
+ bool newCurrent = FALSE;
+ TQListViewItem *ci = d->focusItem;
+ while ( ci ) {
+ if ( ci->tqparent() && ci->tqparent() == i ) {
+ newCurrent = TRUE;
+ break;
+ }
+ ci = ci->tqparent();
+ }
+ if ( newCurrent ) {
+ setCurrentItem( i );
+ }
+ }
+ }
+ d->ignoreDoubleClick = TRUE;
+ d->buttonDown = FALSE;
+ goto emit_Q_SIGNALS;
+ }
+ }
+ }
+
+ d->select = d->selectionMode == Multi ? !i->isSelected() : TRUE;
+
+ {// calculate activatedP
+ activatedByClick = TRUE;
+ TQPoint topLeft = tqitemRect( i ).topLeft(); //### inefficient?
+ activatedP = vp - topLeft;
+ int xdepth = treeStepSize() * (i->depth() + (rootIsDecorated() ? 1 : 0))
+ + itemMargin();
+
+ // This returns the position of the first visual section?!? Shouldn't that always be 0? Keep it just in case we have missed something.
+ xdepth += d->h->sectionPos( d->h->mapToSection( 0 ) );
+ activatedP.rx() -= xdepth;
+ }
+ i->activate();
+ activatedByClick = FALSE;
+
+ if ( i != d->focusItem )
+ setCurrentItem( i );
+ else
+ repaintItem( i );
+
+ d->pressedSelected = i && i->isSelected();
+
+ if ( i->isSelectable() && selectionMode() != NoSelection ) {
+ if ( selectionMode() == Single )
+ setSelected( i, TRUE );
+ else if ( selectionMode() == Multi )
+ setSelected( i, d->select );
+ else if ( selectionMode() == Extended ) {
+ bool changed = FALSE;
+ if ( !(e->state() & (ControlButton | ShiftButton)) ) {
+ if ( !i->isSelected() ) {
+ bool blocked = tqsignalsBlocked();
+ blockSignals( TRUE );
+ clearSelection();
+ blockSignals( blocked );
+ i->setSelected( TRUE );
+ changed = TRUE;
+ }
+ } else {
+ if ( e->state() & ShiftButton )
+ d->pressedSelected = FALSE;
+ if ( (e->state() & ControlButton) && !(e->state() & ShiftButton) && i ) {
+ i->setSelected( !i->isSelected() );
+ changed = TRUE;
+ d->pressedSelected = FALSE;
+ } else if ( !oldCurrent || !i || oldCurrent == i ) {
+ if ( (bool)i->selected != d->select ) {
+ changed = TRUE;
+ i->setSelected( d->select );
+ }
+ // Shift pressed in Extended mode ---
+ } else {
+ changed = selectRange( i, oldCurrent, d->selectAnchor );
+ }
+ }
+ if ( changed ) {
+ d->useDoubleBuffer = TRUE;
+ triggerUpdate();
+ emit selectionChanged();
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::Selection );
+#endif
+ }
+ }
+ }
+
+ emit_Q_SIGNALS:
+
+ if ( i && !d->buttonDown &&
+ vp.x() + contentsX() < itemMargin() + ( i->depth() + ( rootIsDecorated() ? 1 : 0 ) ) * treeStepSize() )
+ i = 0;
+ d->pressedItem = i;
+
+ int c = i ? d->h->mapToLogical( d->h->cellAt( vp.x() ) ) : -1;
+ if ( !i || ( i && i->isEnabled() ) ) {
+ emit pressed( i );
+ emit pressed( i, viewport()->mapToGlobal( vp ), c );
+ }
+ emit mouseButtonPressed( e->button(), i, viewport()->mapToGlobal( vp ), c );
+
+ if ( e->button() == Qt::RightButton && i == d->pressedItem ) {
+ if ( !i && !(e->state() & ControlButton) )
+ clearSelection();
+
+ emit rightButtonPressed( i, viewport()->mapToGlobal( vp ), c );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQListView::contentsContextMenuEvent( TQContextMenuEvent *e )
+{
+ if ( !tqreceivers( TQT_SIGNAL(contextMenuRequested(TQListViewItem*,const TQPoint&,int)) ) ) {
+ e->ignore();
+ return;
+ }
+ if ( e->reason() == TQContextMenuEvent::Keyboard ) {
+ TQListViewItem *item = currentItem();
+ if ( item ) {
+ TQRect r = tqitemRect( item );
+ TQPoint p = r.topLeft();
+ if ( allColumnsShowFocus() )
+ p += TQPoint( width() / 2, ( r.height() / 2 ) );
+ else
+ p += TQPoint( columnWidth( 0 ) / 2, ( r.height() / 2 ) );
+ p.rx() = TQMAX( 0, p.x() );
+ p.rx() = TQMIN( visibleWidth(), p.x() );
+ emit contextMenuRequested( item, viewport()->mapToGlobal( p ), -1 );
+ }
+ } else {
+ TQPoint vp = contentsToViewport( e->pos() );
+ TQListViewItem * i = itemAt( vp );
+ int c = i ? d->h->mapToLogical( d->h->cellAt( vp.x() ) ) : -1;
+ emit contextMenuRequested( i, viewport()->mapToGlobal( vp ), c );
+ }
+}
+
+/*!
+ Processes the mouse release event \a e on behalf of the viewed widget.
+*/
+void TQListView::contentsMouseReleaseEvent( TQMouseEvent * e )
+{
+ contentsMouseReleaseEventEx( e );
+}
+
+void TQListView::contentsMouseReleaseEventEx( TQMouseEvent * e )
+{
+ d->startDragItem = 0;
+ bool emitClicked = !d->pressedItem || d->buttonDown;
+ d->buttonDown = FALSE;
+ // delete and disconnect autoscroll timer, if we have one
+ if ( d->scrollTimer ) {
+ disconnect( d->scrollTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(doAutoScroll()) );
+ d->scrollTimer->stop();
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ }
+
+ if ( !e )
+ return;
+
+ if ( d->selectionMode == Extended &&
+ d->focusItem == d->pressedItem &&
+ d->pressedSelected && d->focusItem &&
+ e->button() == Qt::LeftButton) {
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ clearSelection();
+ blockSignals( block );
+ d->focusItem->setSelected( TRUE );
+ emit selectionChanged();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::Selection );
+#endif
+ }
+
+ TQPoint vp = contentsToViewport(e->pos());
+ TQListViewItem *i = itemAt( vp );
+ if ( i && !i->isEnabled() )
+ return;
+
+ if ( i && i == d->pressedItem && (i->isExpandable() || i->childCount()) &&
+ !d->h->mapToLogical( d->h->cellAt( vp.x() ) ) && e->button() == Qt::LeftButton &&
+ e->type() == tqstyle().tqstyleHint(TQStyle::SH_ListViewExpand_SelectMouseType, this)) {
+ TQPtrListIterator<TQListViewPrivate::DrawableItem> it( *(d->drawables) );
+ while( it.current() && it.current()->i != i )
+ ++it;
+ if ( it.current() ) {
+ int x1 = vp.x() + d->h->offset() - d->h->cellPos( d->h->mapToActual( 0 ) ) -
+ (treeStepSize() * (it.current()->l - 1));
+ TQStyle::SubControl ctrl = tqstyle().querySubControl( TQStyle::CC_ListView,
+ this, TQPoint(x1, e->pos().y()),
+ TQStyleOption(i) );
+ if( ctrl == TQStyle::SC_ListViewExpand ) {
+ bool close = i->isOpen();
+ setOpen( i, !close );
+ // ### Looks dangerous, removed because of reentrance problems
+ // tqApp->processEvents();
+ if ( !d->focusItem ) {
+ d->focusItem = i;
+ repaintItem( d->focusItem );
+ emit currentChanged( d->focusItem );
+ }
+ if ( close ) {
+ bool newCurrent = FALSE;
+ TQListViewItem *ci = d->focusItem;
+ while ( ci ) {
+ if ( ci->tqparent() && ci->tqparent() == i ) {
+ newCurrent = TRUE;
+ break;
+ }
+ ci = ci->tqparent();
+ }
+ if ( newCurrent )
+ setCurrentItem( i );
+ d->ignoreDoubleClick = TRUE;
+ }
+ }
+ }
+ }
+
+ if ( i == d->pressedItem && i && i->isSelected() && e->button() == Qt::LeftButton && d->startEdit ) {
+ TQRect r = tqitemRect( currentItem() );
+ r = TQRect( viewportToContents( r.topLeft() ), r.size() );
+ d->pressedColumn = header()->sectionAt( e->pos().x() );
+ r.setLeft( header()->sectionPos( d->pressedColumn ) );
+ r.setWidth( header()->sectionSize( d->pressedColumn ) - 1 );
+ if ( d->pressedColumn == 0 )
+ r.setLeft( r.left() + itemMargin() + ( currentItem()->depth() +
+ ( rootIsDecorated() ? 1 : 0 ) ) * treeStepSize() - 1 );
+ if ( r.tqcontains( e->pos() ) &&
+ !( e->state() & ( ShiftButton | ControlButton ) ) )
+ d->renameTimer->start( TQApplication::doubleClickInterval(), TRUE );
+ }
+ // Check if we are clicking at the root decoration.
+ int rootColumnPos = d->h->sectionPos( 0 );
+ if ( i && vp.x() + contentsX() < rootColumnPos + itemMargin() + ( i->depth() + ( rootIsDecorated() ? 1 : 0 ) ) * treeStepSize()
+ && vp.x() + contentsX() > rootColumnPos ) {
+ i = 0;
+ }
+ emitClicked = emitClicked && d->pressedItem == i;
+ d->pressedItem = 0;
+
+ if ( emitClicked ) {
+ if ( !i || ( i && i->isEnabled() ) ) {
+ emit clicked( i );
+ emit clicked( i, viewport()->mapToGlobal( vp ), d->h->mapToLogical( d->h->cellAt( vp.x() ) ) );
+ }
+ emit mouseButtonClicked( e->button(), i, viewport()->mapToGlobal( vp ),
+ i ? d->h->mapToLogical( d->h->cellAt( vp.x() ) ) : -1 );
+
+ if ( e->button() == Qt::RightButton ) {
+ if ( !i ) {
+ if ( !(e->state() & ControlButton) )
+ clearSelection();
+ emit rightButtonClicked( 0, viewport()->mapToGlobal( vp ), -1 );
+ return;
+ }
+
+ int c = d->h->mapToLogical( d->h->cellAt( vp.x() ) );
+ emit rightButtonClicked( i, viewport()->mapToGlobal( vp ), c );
+ }
+ }
+}
+
+
+/*!
+ Processes the mouse double-click event \a e on behalf of the viewed widget.
+*/
+void TQListView::contentsMouseDoubleClickEvent( TQMouseEvent * e )
+{
+ d->renameTimer->stop();
+ d->startEdit = FALSE;
+ if ( !e || e->button() != Qt::LeftButton )
+ return;
+
+ // ensure that the following mouse moves and eventual release is
+ // ignored.
+ d->buttonDown = FALSE;
+
+ if ( d->ignoreDoubleClick ) {
+ d->ignoreDoubleClick = FALSE;
+ return;
+ }
+
+ TQPoint vp = contentsToViewport(e->pos());
+
+ TQListViewItem * i = itemAt( vp );
+
+ // we emit doubleClicked when the item is null (or enabled) to be consistent with
+ // rightButtonClicked etc.
+ if ( !i || i->isEnabled() ) {
+ int c = d->h->mapToLogical( d->h->cellAt( vp.x() ) );
+ emit doubleClicked( i, viewport()->mapToGlobal( vp ), c );
+ }
+
+ if ( !i || !i->isEnabled() )
+ return;
+
+ if ( !i->isOpen() ) {
+ if ( i->isExpandable() || i->childCount() )
+ setOpen( i, TRUE );
+ } else {
+ setOpen( i, FALSE );
+ }
+
+ // we emit the 'old' obsolete doubleClicked only if the item is not null and enabled
+ emit doubleClicked( i );
+}
+
+
+/*!
+ Processes the mouse move event \a e on behalf of the viewed widget.
+*/
+void TQListView::contentsMouseMoveEvent( TQMouseEvent * e )
+{
+ if ( !e )
+ return;
+
+ bool needAutoScroll = FALSE;
+
+ TQPoint vp = contentsToViewport(e->pos());
+
+ TQListViewItem * i = itemAt( vp );
+ if ( i && !i->isEnabled() )
+ return;
+ if ( i != d->highlighted &&
+ !(d->pressedItem &&
+ ( d->pressedItem->isSelected() || d->selectionMode == NoSelection ) &&
+ d->pressedItem->dragEnabled() )) {
+
+ if ( i ) {
+ emit onItem( i );
+ } else {
+ emit onViewport();
+ }
+ d->highlighted = i;
+ }
+
+ if ( d->startDragItem )
+ i = d->startDragItem;
+
+ if ( !d->buttonDown ||
+ ( ( e->state() & Qt::LeftButton ) != Qt::LeftButton &&
+ ( e->state() & Qt::MidButton ) != Qt::MidButton &&
+ ( e->state() & Qt::RightButton ) != Qt::RightButton ) )
+ return;
+
+ if ( d->pressedItem &&
+ ( d->pressedItem->isSelected() || d->selectionMode == NoSelection ) &&
+ d->pressedItem->dragEnabled() ) {
+
+ if ( !d->startDragItem ) {
+ setSelected( d->pressedItem, TRUE );
+ d->startDragItem = d->pressedItem;
+ }
+ if ( ( d->dragStartPos - e->pos() ).manhattanLength() > TQApplication::startDragDistance() ) {
+ d->buttonDown = FALSE;
+#ifndef TQT_NO_DRAGANDDROP
+ startDrag();
+#endif
+ }
+ return;
+ }
+
+ // check, if we need to scroll
+ if ( vp.y() > visibleHeight() || vp.y() < 0 )
+ needAutoScroll = TRUE;
+
+ // if we need to scroll and no autoscroll timer is started,
+ // connect the timer
+ if ( needAutoScroll && !d->scrollTimer ) {
+ d->scrollTimer = new TQTimer( this );
+ connect( d->scrollTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(doAutoScroll()) );
+ d->scrollTimer->start( 100, FALSE );
+ // call it once manually
+ doAutoScroll( vp );
+ }
+
+ // if we don't need to autoscroll
+ if ( !needAutoScroll ) {
+ // if there is a autoscroll timer, delete it
+ if ( d->scrollTimer ) {
+ disconnect( d->scrollTimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(doAutoScroll()) );
+ d->scrollTimer->stop();
+ delete d->scrollTimer;
+ d->scrollTimer = 0;
+ }
+ // call this to select an item ( using the pos from the event )
+ doAutoScroll( vp );
+ }
+}
+
+
+/*!
+ This slot handles auto-scrolling when the mouse button is pressed
+ and the mouse is outside the widget.
+*/
+void TQListView::doAutoScroll()
+{
+ doAutoScroll( TQPoint() );
+}
+
+/*
+ Handles auto-scrolling when the mouse button is pressed
+ and the mouse is outside the widget.
+
+ If cursorPos is (0,0) (isNull == TRUE) it uses the current TQCursor::pos, otherwise it uses cursorPos
+*/
+void TQListView::doAutoScroll( const TQPoint &cursorPos )
+{
+ TQPoint pos = cursorPos.isNull() ? TQT_TQPOINT_OBJECT(viewport()->mapFromGlobal( TQCursor::pos() )) : cursorPos;
+ if ( !d->focusItem || ( d->pressedEmptyArea && pos.y() > contentsHeight() ) )
+ return;
+
+ bool down = pos.y() > tqitemRect( d->focusItem ).y();
+
+ int g = pos.y() + contentsY();
+
+ if ( down && pos.y() > height() )
+ g = height() + contentsY();
+ else if ( pos.y() < 0 )
+ g = contentsY();
+
+ TQListViewItem *c = d->focusItem, *old = 0;
+ TQListViewItem *oldCurrent = c;
+ if ( down ) {
+ int y = tqitemRect( d->focusItem ).y() + contentsY();
+ while( c && y + c->height() <= g ) {
+ y += c->height();
+ old = c;
+ c = c->itemBelow();
+ }
+ if ( !c && old )
+ c = old;
+ } else {
+ int y = tqitemRect( d->focusItem ).y() + contentsY();
+ while( c && y >= g ) {
+ old = c;
+ c = c->itemAbove();
+ if ( c )
+ y -= c->height();
+ }
+ if ( !c && old )
+ c = old;
+ }
+
+ if ( !c || c == d->focusItem )
+ return;
+
+ if ( d->focusItem ) {
+ if ( d->selectionMode == Multi ) {
+ // also (de)select the ones in between
+ TQListViewItem * b = d->focusItem;
+ bool down = ( itemPos( c ) > itemPos( b ) );
+ while( b && b != c ) {
+ if ( b->isSelectable() )
+ setSelected( b, d->select );
+ b = down ? b->itemBelow() : b->itemAbove();
+ }
+ if ( c->isSelectable() )
+ setSelected( c, d->select );
+ } else if ( d->selectionMode == Extended ) {
+ if ( selectRange( c, oldCurrent, d->selectAnchor ) ) {
+ d->useDoubleBuffer = TRUE;
+ triggerUpdate();
+ emit selectionChanged();
+ }
+ }
+ }
+
+ setCurrentItem( c );
+ d->visibleTimer->start( 1, TRUE );
+}
+
+/*!
+ \reimp
+*/
+
+void TQListView::focusInEvent( TQFocusEvent* tqfe )
+{
+ d->inMenuMode = FALSE;
+ if ( d->focusItem ) {
+ repaintItem( d->focusItem );
+#ifdef USE_QT4
+ } else if ( firstChild() && tqfe->reason() != TQFocusEvent::Mouse ) {
+#else // USE_QT4
+ } else if ( firstChild() && TQFocusEvent::reason() != TQFocusEvent::Mouse ) {
+#endif // USE_QT4
+ d->focusItem = firstChild();
+ emit currentChanged( d->focusItem );
+ repaintItem( d->focusItem );
+ }
+#ifdef USE_QT4
+ if ( tqfe->reason() == TQFocusEvent::Mouse ) {
+#else // USE_QT4
+ if ( TQFocusEvent::reason() == TQFocusEvent::Mouse ) {
+#endif // USE_QT4
+ d->ignoreEditAfterFocus = TRUE;
+ d->startEdit = FALSE;
+ }
+ if ( tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this ) ) {
+ bool db = d->useDoubleBuffer;
+ d->useDoubleBuffer = TRUE;
+ viewport()->tqrepaint( FALSE );
+ d->useDoubleBuffer = db;
+ }
+
+ TQRect mfrect = tqitemRect( d->focusItem );
+ if ( mfrect.isValid() ) {
+ if ( header() && header()->isVisible() )
+ setMicroFocusHint( mfrect.x(), mfrect.y()+header()->height(), mfrect.width(), mfrect.height(), FALSE );
+ else
+ setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE );
+ }
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQListView::focusOutEvent( TQFocusEvent* tqfe )
+{
+#ifdef USE_QT4
+ if ( tqfe->reason() == TQFocusEvent::Popup && d->buttonDown )
+#else // USE_QT4
+ if ( TQFocusEvent::reason() == TQFocusEvent::Popup && d->buttonDown )
+#endif // USE_QT4
+ d->buttonDown = FALSE;
+ if ( tqstyle().tqstyleHint( TQStyle::SH_ItemView_ChangeHighlightOnFocus, this ) ) {
+ d->inMenuMode =
+#ifdef USE_QT4
+ tqfe->reason() == TQFocusEvent::Popup
+#else // USE_QT4
+ TQFocusEvent::reason() == TQFocusEvent::Popup
+#endif // USE_QT4
+ || (tqApp->tqfocusWidget() && tqApp->tqfocusWidget()->inherits("TQMenuBar"));
+ if ( !d->inMenuMode ) {
+ bool db = d->useDoubleBuffer;
+ d->useDoubleBuffer = TRUE;
+ viewport()->tqrepaint( FALSE );
+ d->useDoubleBuffer = db;
+ }
+ }
+
+ if ( d->focusItem )
+ repaintItem( d->focusItem );
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQListView::keyPressEvent( TQKeyEvent * e )
+{
+ if (currentItem() && currentItem()->renameBox)
+ return;
+ if (!firstChild()) {
+ e->ignore();
+ return; // subclass bug
+ }
+
+ TQListViewItem* oldCurrent = currentItem();
+ if ( !oldCurrent ) {
+ setCurrentItem( firstChild() );
+ if ( d->selectionMode == Single )
+ setSelected( firstChild(), TRUE );
+ return;
+ }
+
+ TQListViewItem * i = currentItem();
+ TQListViewItem *old = i;
+
+ TQRect r( tqitemRect( i ) );
+ TQListViewItem * i2;
+
+ bool singleStep = FALSE;
+ bool selectCurrent = TRUE;
+ bool wasNavigation = TRUE;
+
+ switch( e->key() ) {
+ case Qt::Key_Backspace:
+ case Qt::Key_Delete:
+ d->currentPrefix.truncate( 0 );
+ break;
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ d->currentPrefix.truncate( 0 );
+ if ( i && !i->isSelectable() && i->isEnabled() &&
+ ( i->childCount() || i->isExpandable() || i->isOpen() ) ) {
+ i->setOpen( !i->isOpen() );
+ return;
+ }
+ e->ignore();
+ if ( currentItem() && !currentItem()->isEnabled() )
+ break;
+ emit returnPressed( currentItem() );
+ // do NOT accept. TQDialog.
+ return;
+ case Qt::Key_Down:
+ selectCurrent = FALSE;
+ i = i->itemBelow();
+ d->currentPrefix.truncate( 0 );
+ singleStep = TRUE;
+ break;
+ case Qt::Key_Up:
+ selectCurrent = FALSE;
+ i = i->itemAbove();
+ d->currentPrefix.truncate( 0 );
+ singleStep = TRUE;
+ break;
+ case Qt::Key_Home:
+ selectCurrent = FALSE;
+ i = firstChild();
+ if (!i->height() || !i->isEnabled())
+ i = i->itemBelow();
+ d->currentPrefix.truncate( 0 );
+ break;
+ case Qt::Key_End:
+ selectCurrent = FALSE;
+ i = firstChild();
+ while (i->nextSibling() && i->nextSibling()->height() && i->nextSibling()->isEnabled())
+ i = i->nextSibling();
+ while ( i->itemBelow() )
+ i = i->itemBelow();
+ d->currentPrefix.truncate( 0 );
+ break;
+ case TQt::Key_Next:
+ selectCurrent = FALSE;
+ i2 = itemAt( TQPoint( 0, visibleHeight()-1 ) );
+ if ( i2 == i || !r.isValid() ||
+ visibleHeight() <= tqitemRect( i ).bottom() ) {
+ if ( i2 )
+ i = i2;
+ int left = visibleHeight();
+ while( (i2 = i->itemBelow()) != 0 && left > i2->height() ) {
+ left -= i2->height();
+ i = i2;
+ }
+ } else {
+ if ( !i2 ) {
+ // list is shorter than the view, goto last item
+ while( (i2 = i->itemBelow()) != 0 )
+ i = i2;
+ } else {
+ i = i2;
+ }
+ }
+ d->currentPrefix.truncate( 0 );
+ break;
+ case TQt::Key_Prior:
+ selectCurrent = FALSE;
+ i2 = itemAt( TQPoint( 0, 0 ) );
+ if ( i == i2 || !r.isValid() || r.top() <= 0 ) {
+ if ( i2 )
+ i = i2;
+ int left = visibleHeight();
+ while( (i2 = i->itemAbove()) != 0 && left > i2->height() ) {
+ left -= i2->height();
+ i = i2;
+ }
+ } else {
+ i = i2;
+ }
+ d->currentPrefix.truncate( 0 );
+ break;
+ case Qt::Key_Plus:
+ d->currentPrefix.truncate( 0 );
+ if ( !i->isOpen() && (i->isExpandable() || i->childCount()) )
+ setOpen( i, TRUE );
+ else
+ return;
+ break;
+ case Qt::Key_Right:
+ d->currentPrefix.truncate( 0 );
+ if ( i->isOpen() && i->childItem) {
+ TQListViewItem *childItem = i->childItem;
+ while (childItem && !childItem->isVisible())
+ childItem = childItem->nextSibling();
+ if (childItem)
+ i = childItem;
+ } else if ( !i->isOpen() && (i->isExpandable() || i->childCount()) ) {
+ setOpen( i, TRUE );
+ } else if ( contentsX() + visibleWidth() < contentsWidth() ) {
+ horizontalScrollBar()->addLine();
+ return;
+ } else {
+ return;
+ }
+ break;
+ case Qt::Key_Minus:
+ d->currentPrefix.truncate( 0 );
+ if ( i->isOpen() )
+ setOpen( i, FALSE );
+ else
+ return;
+ break;
+ case Qt::Key_Left:
+ d->currentPrefix.truncate( 0 );
+ if ( i->isOpen() ) {
+ setOpen( i, FALSE );
+ } else if ( i->parentItem && i->parentItem != d->r ) {
+ i = i->parentItem;
+ } else if ( contentsX() ) {
+ horizontalScrollBar()->subtractLine();
+ return;
+ } else {
+ return;
+ }
+ break;
+ case Qt::Key_Space:
+ activatedByClick = FALSE;
+ d->currentPrefix.truncate( 0 );
+ if ( currentItem() && !currentItem()->isEnabled() )
+ break;
+ i->activate();
+ if ( i->isSelectable() && ( d->selectionMode == Multi || d->selectionMode == Extended ) ) {
+ setSelected( i, !i->isSelected() );
+ d->currentPrefix.truncate( 0 );
+ }
+ emit spacePressed( currentItem() );
+ break;
+ case Key_Escape:
+ e->ignore(); // For TQDialog
+ return;
+ case Qt::Key_F2:
+ if ( currentItem() && currentItem()->renameEnabled( 0 ) )
+ currentItem()->startRename( 0 );
+ default:
+ if ( e->text().length() > 0 && e->text()[ 0 ].isPrint() ) {
+ selectCurrent = FALSE;
+ wasNavigation = FALSE;
+ TQString input( d->currentPrefix );
+ TQListViewItem * keyItem = i;
+ TQTime now( TQTime::currentTime() );
+ bool tryFirst = TRUE;
+ while( keyItem ) {
+ // try twice, first with the previous string and this char
+ if ( d->currentPrefixTime.msecsTo( now ) <= 400 )
+ input = input + TQT_TQSTRING(e->text()).lower();
+ else
+ input = TQT_TQSTRING(e->text()).lower();
+ if ( input.length() == e->text().length() ) {
+ if ( keyItem->itemBelow() ) {
+ keyItem = keyItem->itemBelow();
+ tryFirst = TRUE;
+ } else {
+ keyItem = firstChild();
+ tryFirst = FALSE;
+ }
+ }
+ TQString keyItemKey;
+ TQString prefix;
+ while( keyItem ) {
+ keyItemKey = TQString::null;
+ // Look first in the sort column, then left to right
+ if (d->sortcolumn != Unsorted)
+ keyItemKey = keyItem->text(d->sortcolumn);
+ for ( int col = 0; col < d->h->count() && keyItemKey.isNull(); ++col )
+ keyItemKey = keyItem->text( d->h->mapToSection(col) );
+ if ( !keyItemKey.isEmpty() ) {
+ prefix = keyItemKey;
+ prefix.truncate( input.length() );
+ prefix = prefix.lower();
+ if ( prefix == input ) {
+ d->currentPrefix = input;
+ d->currentPrefixTime = now;
+ i = keyItem;
+ // nonoptimal double-break...
+ keyItem = 0;
+ input.truncate( 0 );
+ tryFirst = FALSE;
+ }
+ }
+ if ( keyItem )
+ keyItem = keyItem->itemBelow();
+ if ( !keyItem && tryFirst ) {
+ keyItem = firstChild();
+ tryFirst = FALSE;
+ }
+ }
+ // then, if appropriate, with just this character
+ if ( input.length() > e->text().length() ) {
+ input.truncate(0);
+ keyItem = i;
+ }
+ }
+ } else {
+ d->currentPrefix.truncate( 0 );
+ if ( e->state() & ControlButton ) {
+ d->currentPrefix = TQString::null;
+ switch ( e->key() ) {
+ case Qt::Key_A:
+ selectAll( TRUE );
+ break;
+ }
+ }
+ e->ignore();
+ return;
+ }
+ }
+
+ if ( !i )
+ return;
+
+ if ( !( e->state() & ShiftButton ) || !d->selectAnchor )
+ d->selectAnchor = i;
+
+ setCurrentItem( i );
+ if ( i->isSelectable() )
+ handleItemChange( old, wasNavigation && (e->state() & ShiftButton),
+ wasNavigation && (e->state() & ControlButton) );
+
+ if ( d->focusItem && !d->focusItem->isSelected() && d->selectionMode == Single && selectCurrent )
+ setSelected( d->focusItem, TRUE );
+
+ if ( singleStep )
+ d->visibleTimer->start( 1, TRUE );
+ else
+ ensureItemVisible( i );
+}
+
+
+/*!
+ Returns the list view item at \a viewPos. Note that \a viewPos is
+ in the viewport()'s coordinate system, not in the list view's own,
+ much larger, coordinate system.
+
+ itemAt() returns 0 if there is no such item.
+
+ Note that you also get the pointer to the item if \a viewPos
+ points to the root decoration (see setRootIsDecorated()) of the
+ item. To check whether or not \a viewPos is on the root decoration
+ of the item, you can do something like this:
+
+ \code
+ TQListViewItem *i = itemAt( p );
+ if ( i ) {
+ if ( p.x() > header()->sectionPos( header()->mapToIndex( 0 ) ) +
+ treeStepSize() * ( i->depth() + ( rootIsDecorated() ? 1 : 0) ) + itemMargin() ||
+ p.x() < header()->sectionPos( header()->mapToIndex( 0 ) ) ) {
+ ; // p is not on root decoration
+ else
+ ; // p is on the root decoration
+ }
+ \endcode
+
+ This might be interesting if you use this function to tqfind out
+ where the user clicked and if you want to start a drag (which you
+ do not want to do if the user clicked onto the root decoration of
+ an item).
+
+ \sa itemPos() tqitemRect() viewportToContents()
+*/
+
+TQListViewItem * TQListView::itemAt( const TQPoint & viewPos ) const
+{
+ if ( viewPos.x() > contentsWidth() - contentsX() )
+ return 0;
+
+ if ( !d->drawables || d->drawables->isEmpty() )
+ buildDrawableList();
+
+ TQListViewPrivate::DrawableItem * c = d->drawables->first();
+ int g = viewPos.y() + contentsY();
+
+ while( c && c->i && ( c->y + c->i->height() <= g ||
+ !c->i->isVisible() ||
+ (c->i->tqparent() && !c->i->tqparent()->isVisible()) ) )
+ c = d->drawables->next();
+
+ TQListViewItem *i = (c && c->y <= g) ? c->i : 0;
+ return i;
+}
+
+
+/*!
+ Returns the y-coordinate of \a item in the list view's coordinate
+ system. This function is normally much slower than itemAt() but it
+ works for all items, whereas itemAt() normally works only for
+ items on the screen.
+
+ This is a thin wrapper around TQListViewItem::itemPos().
+
+ \sa itemAt() tqitemRect()
+*/
+
+int TQListView::itemPos( const TQListViewItem * item )
+{
+ return item ? item->itemPos() : 0;
+}
+
+
+/*! \obsolete
+ \property TQListView::multiSelection
+ \brief whether the list view is in multi-selection or extended-selection mode
+
+ If you enable multi-selection, \c Multi, mode, it is possible to
+ specify whether or not this mode should be extended. \c Extended
+ means that the user can select multiple items only when pressing
+ the Shift or Ctrl key at the same time.
+
+ The default selection mode is \c Single.
+
+ \sa selectionMode()
+*/
+
+void TQListView::setMultiSelection( bool enable )
+{
+ if ( !enable )
+ d->selectionMode = TQListView::Single;
+ else if ( d->selectionMode != Multi && d->selectionMode != Extended )
+ d->selectionMode = TQListView::Multi;
+}
+
+bool TQListView::isMultiSelection() const
+{
+ return d->selectionMode == TQListView::Extended || d->selectionMode == TQListView::Multi;
+}
+
+/*!
+ \property TQListView::selectionMode
+ \brief the list view's selection mode
+
+ The mode can be \c Single (the default), \c Extended, \c Multi or
+ \c NoSelection.
+
+ \sa multiSelection
+*/
+
+void TQListView::setSelectionMode( SelectionMode mode )
+{
+ if ( d->selectionMode == mode )
+ return;
+
+ if ( ( d->selectionMode == Multi || d->selectionMode == Extended ) &&
+ ( mode == TQListView::Single || mode == TQListView::NoSelection ) ){
+ clearSelection();
+ if ( ( mode == TQListView::Single ) && currentItem() )
+ currentItem()->selected = TRUE;
+ }
+
+ d->selectionMode = mode;
+}
+
+TQListView::SelectionMode TQListView::selectionMode() const
+{
+ return d->selectionMode;
+}
+
+
+/*!
+ If \a selected is TRUE the \a item is selected; otherwise it is
+ unselected.
+
+ If the list view is in \c Single selection mode and \a selected is
+ TRUE, the currently selected item is unselected and \a item is
+ made current. Unlike TQListViewItem::setSelected(), this function
+ updates the list view as necessary and emits the
+ selectionChanged() Q_SIGNALS.
+
+ \sa isSelected() setMultiSelection() isMultiSelection()
+ setCurrentItem(), setSelectionAnchor()
+*/
+
+void TQListView::setSelected( TQListViewItem * item, bool selected )
+{
+ if ( !item || item->isSelected() == selected ||
+ !item->isSelectable() || selectionMode() == NoSelection )
+ return;
+
+ bool emitHighlighted = FALSE;
+ if ( selectionMode() == Single && d->focusItem != item ) {
+ TQListViewItem *o = d->focusItem;
+ if ( d->focusItem && d->focusItem->selected )
+ d->focusItem->setSelected( FALSE );
+ d->focusItem = item;
+ if ( o )
+ repaintItem( o );
+ emitHighlighted = TRUE;
+ }
+
+ item->setSelected( selected );
+
+ repaintItem( item );
+
+ if ( d->selectionMode == Single && selected )
+ emit selectionChanged( item );
+ emit selectionChanged();
+
+ if ( emitHighlighted )
+ emit currentChanged( d->focusItem );
+}
+
+/*!
+ Sets the selection anchor to \a item, if \a item is selectable.
+
+ The selection anchor is the item that remains selected when
+ Shift-selecting with either mouse or keyboard in \c Extended
+ selection mode.
+
+ \sa setSelected()
+*/
+
+void TQListView::setSelectionAnchor( TQListViewItem *item )
+{
+ if ( item && item->isSelectable() )
+ d->selectAnchor = item;
+}
+
+/*!
+ Sets all the items to be not selected, updates the list view as
+ necessary, and emits the selectionChanged() Q_SIGNALS. Note that for
+ \c Multi selection list views this function needs to iterate over
+ \e all items.
+
+ \sa setSelected(), setMultiSelection()
+*/
+
+void TQListView::clearSelection()
+{
+ selectAll( FALSE );
+}
+
+/*!
+ If \a select is TRUE, all the items get selected; otherwise all
+ the items get unselected. This only works in the selection modes \c
+ Multi and \c Extended. In \c Single and \c NoSelection mode the
+ selection of the current item is just set to \a select.
+*/
+
+void TQListView::selectAll( bool select )
+{
+ if ( d->selectionMode == Multi || d->selectionMode == Extended ) {
+ bool b = tqsignalsBlocked();
+ blockSignals( TRUE );
+ bool anything = FALSE;
+ TQListViewItemIterator it( this );
+ while ( it.current() ) {
+ TQListViewItem *i = it.current();
+ if ( (bool)i->selected != select ) {
+ i->setSelected( select );
+ anything = TRUE;
+ }
+ ++it;
+ }
+ blockSignals( b );
+ if ( anything ) {
+ emit selectionChanged();
+ d->useDoubleBuffer = TRUE;
+ triggerUpdate();
+ }
+ } else if ( d->focusItem ) {
+ TQListViewItem * i = d->focusItem;
+ setSelected( i, select );
+ }
+}
+
+/*!
+ Inverts the selection. Only works in \c Multi and \c Extended
+ selection modes.
+*/
+
+void TQListView::invertSelection()
+{
+ if ( d->selectionMode == Single ||
+ d->selectionMode == NoSelection )
+ return;
+
+ bool b = tqsignalsBlocked();
+ blockSignals( TRUE );
+ TQListViewItemIterator it( this );
+ for ( ; it.current(); ++it )
+ it.current()->setSelected( !it.current()->isSelected() );
+ blockSignals( b );
+ emit selectionChanged();
+ triggerUpdate();
+}
+
+
+/*!
+ Returns TRUE if the list view item \a i is selected; otherwise
+ returns FALSE.
+
+ \sa TQListViewItem::isSelected()
+*/
+
+bool TQListView::isSelected( const TQListViewItem * i ) const
+{
+ return i ? i->isSelected() : FALSE;
+}
+
+
+/*!
+ Returns the selected item if the list view is in \c Single
+ selection mode and an item is selected.
+
+ If no items are selected or the list view is not in \c Single
+ selection mode this function returns 0.
+
+ \sa setSelected() setMultiSelection()
+*/
+
+TQListViewItem * TQListView::selectedItem() const
+{
+ if ( d->selectionMode != Single )
+ return 0;
+ if ( d->focusItem && d->focusItem->isSelected() )
+ return d->focusItem;
+ return 0;
+}
+
+
+/*!
+ Sets item \a i to be the current item and repaints appropriately
+ (i.e. highlights the item). The current item is used for keyboard
+ navigation and focus indication; it is independent of any selected
+ items, although a selected item can also be the current item.
+
+ This function does not set the selection anchor. Use
+ setSelectionAnchor() instead.
+
+ \sa currentItem() setSelected()
+*/
+
+void TQListView::setCurrentItem( TQListViewItem * i )
+{
+ if ( !i || d->focusItem == i || !i->isEnabled() )
+ return;
+
+ if ( currentItem() && currentItem()->renameBox ) {
+ if ( d->defRenameAction == Reject )
+ currentItem()->cancelRename( currentItem()->renameCol );
+ else
+ currentItem()->okRename( currentItem()->renameCol );
+ }
+
+ TQListViewItem * prev = d->focusItem;
+ d->focusItem = i;
+
+ TQRect mfrect = tqitemRect( i );
+ if ( mfrect.isValid() ) {
+ if ( header() && header()->isVisible() )
+ setMicroFocusHint( mfrect.x(), mfrect.y()+header()->height(), mfrect.width(), mfrect.height(), FALSE );
+ else
+ setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE );
+ }
+
+ if ( i != prev ) {
+ if ( i && d->selectionMode == Single ) {
+ bool changed = FALSE;
+ if ( prev && prev->selected ) {
+ changed = TRUE;
+ prev->setSelected( FALSE );
+ }
+ if ( i && !i->selected && d->selectionMode != NoSelection && i->isSelectable() ) {
+ i->setSelected( TRUE );
+ changed = TRUE;
+ emit selectionChanged( i );
+ }
+ if ( changed )
+ emit selectionChanged();
+ }
+
+ if ( i )
+ repaintItem( i );
+ if ( prev )
+ repaintItem( prev );
+ emit currentChanged( i );
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), indexOfItem( i ), TQAccessible::Focus );
+#endif
+ }
+}
+
+
+/*!
+ Returns the current item, or 0 if there isn't one.
+
+ \sa setCurrentItem()
+*/
+
+TQListViewItem * TQListView::currentItem() const
+{
+ return d->focusItem;
+}
+
+
+/*!
+ Returns the rectangle on the screen that item \a i occupies in
+ viewport()'s coordinates, or an invalid rectangle if \a i is 0 or
+ is not currently visible.
+
+ The rectangle returned does not include any tqchildren of the
+ rectangle (i.e. it uses TQListViewItem::height(), rather than
+ TQListViewItem::totalHeight()). If you want the rectangle to
+ include tqchildren you can use something like this:
+
+ \code
+ TQRect r( listView->tqitemRect( item ) );
+ r.setHeight( (TQCOORD)(TQMIN( item->totalHeight(),
+ listView->viewport->height() - r.y() ) ) )
+ \endcode
+
+ Note the way it avoids too-high rectangles. totalHeight() can be
+ much larger than the window system's coordinate system allows.
+
+ tqitemRect() is comparatively slow. It's best to call it only for
+ items that are probably on-screen.
+*/
+
+TQRect TQListView::tqitemRect( const TQListViewItem * i ) const
+{
+ if ( !d->drawables || d->drawables->isEmpty() )
+ buildDrawableList();
+
+ TQListViewPrivate::DrawableItem * c = d->drawables->first();
+
+ while( c && c->i && c->i != i )
+ c = d->drawables->next();
+
+ if ( c && c->i == i ) {
+ int y = c->y - contentsY();
+ if ( y + c->i->height() >= 0 &&
+ y < ((TQListView *)this)->visibleHeight() ) {
+ TQRect r( -contentsX(), y, d->h->width(), i->height() );
+ return r;
+ }
+ }
+
+ return TQRect( 0, 0, -1, -1 );
+}
+
+
+/*!
+ \fn void TQListView::doubleClicked( TQListViewItem *item )
+
+ \obsolete (use doubleClicked( TQListViewItem *, const TQPoint&, int ))
+
+ This signal is emitted whenever an item is double-clicked. It's
+ emitted on the second button press, not the second button release.
+ \a item is the list view item on which the user did the
+ double-click.
+*/
+
+/*!
+ \fn void TQListView::doubleClicked( TQListViewItem *, const TQPoint&, int )
+
+ This signal is emitted whenever an item is double-clicked. It's
+ emitted on the second button press, not the second button release.
+ The arguments are the relevant TQListViewItem (may be 0), the point
+ in global coordinates and the relevant column (or -1 if the click
+ was outside the list).
+
+ \warning Do not delete any TQListViewItem objects in Q_SLOTS
+ connected to this signal.
+*/
+
+
+/*!
+ \fn void TQListView::returnPressed( TQListViewItem * )
+
+ This signal is emitted when Enter or Return is pressed. The
+ argument is the currentItem().
+*/
+
+/*!
+ \fn void TQListView::spacePressed( TQListViewItem * )
+
+ This signal is emitted when Space is pressed. The argument is
+ the currentItem().
+*/
+
+
+/*!
+ Sets the list view to be sorted by column \a column in ascending
+ order if \a ascending is TRUE or descending order if it is FALSE.
+
+ If \a column is -1, sorting is disabled and the user cannot sort
+ columns by clicking on the column headers. If \a column is larger
+ than the number of columns the user must click on a column
+ header to sort the list view.
+*/
+
+void TQListView::setSorting( int column, bool ascending )
+{
+ if ( column == -1 )
+ column = Unsorted;
+
+ if ( d->sortcolumn == column && d->ascending == ascending )
+ return;
+
+ d->ascending = ascending;
+ d->sortcolumn = column;
+ if ( d->sortcolumn != Unsorted && d->sortIndicator )
+ d->h->setSortIndicator( d->sortcolumn, d->ascending );
+ else
+ d->h->setSortIndicator( -1 );
+
+ triggerUpdate();
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( viewport(), 0, TQAccessible::ObjectReorder );
+#endif
+}
+
+/*!
+ \enum TQt::SortOrder
+
+ This enum describes how the items in a widget are sorted.
+
+ \value Ascending The items are sorted ascending e.g. starts with
+ 'AAA' ends with 'ZZZ' in Latin-1 locales
+
+ \value Descending The items are sorted descending e.g. starts with
+ 'ZZZ' ends with 'AAA' in Latin-1 locales
+*/
+
+/*!
+ Sets the \a column the list view is sorted by.
+
+ Sorting is triggered by choosing a header section.
+*/
+
+void TQListView::changeSortColumn( int column )
+{
+ if ( isRenaming() ) {
+ if ( d->defRenameAction == TQListView::Reject ) {
+ currentItem()->cancelRename( currentItem()->renameCol );
+ } else {
+ currentItem()->okRename( currentItem()->renameCol );
+ }
+ }
+ if ( d->sortcolumn != Unsorted ) {
+ int lcol = d->h->mapToLogical( column );
+ setSorting( lcol, d->sortcolumn == lcol ? !d->ascending : TRUE);
+ }
+}
+
+/*!
+ \internal
+ Handles renaming when sections are being swapped by the user.
+*/
+
+void TQListView::handleIndexChange()
+{
+ if ( isRenaming() ) {
+ if ( d->defRenameAction == TQListView::Reject ) {
+ currentItem()->cancelRename( currentItem()->renameCol );
+ } else {
+ currentItem()->okRename( currentItem()->renameCol );
+ }
+ }
+ triggerUpdate();
+}
+
+/*!
+ Returns the column by which the list view is sorted, or -1 if
+ sorting is disabled.
+
+ \sa sortOrder()
+*/
+
+int TQListView::sortColumn() const
+{
+ return d->sortcolumn == Unsorted ? -1 : d->sortcolumn;
+}
+
+/*!
+ Sets the sorting column for the list view.
+
+ If \a column is -1, sorting is disabled and the user cannot sort
+ columns by clicking on the column headers. If \a column is larger
+ than the number of columns the user must click on a column header
+ to sort the list view.
+
+ \sa setSorting()
+*/
+void TQListView::setSortColumn( int column )
+{
+ setSorting( column, d->ascending );
+}
+
+/*!
+ Returns the sorting order of the list view items.
+
+ \sa sortColumn()
+*/
+TQt::SortOrder TQListView::sortOrder() const
+{
+ if ( d->ascending )
+ return TQt::Ascending;
+ return TQt::Descending;
+}
+
+/*!
+ Sets the sort order for the items in the list view to \a order.
+
+ \sa setSorting()
+*/
+void TQListView::setSortOrder( TQt::SortOrder order )
+{
+ setSorting( d->sortcolumn, order == TQt::Ascending ? TRUE : FALSE );
+}
+
+/*!
+ Sorts the list view using the last sorting configuration (sort
+ column and ascending/descending).
+*/
+
+void TQListView::sort()
+{
+ if ( d->r )
+ d->r->sort();
+}
+
+/*!
+ \property TQListView::itemMargin
+ \brief the advisory item margin that list items may use
+
+ The item margin defaults to one pixel and is the margin between
+ the item's edges and the area where it draws its contents.
+ TQListViewItem::paintFocus() draws in the margin.
+
+ \sa TQListViewItem::paintCell()
+*/
+
+void TQListView::setItemMargin( int m )
+{
+ if ( d->margin == m )
+ return;
+ d->margin = m;
+ if ( isVisible() ) {
+ if ( d->drawables )
+ d->drawables->clear();
+ triggerUpdate();
+ }
+}
+
+int TQListView::itemMargin() const
+{
+ return d->margin;
+}
+
+
+/*!
+ \fn void TQListView::rightButtonClicked( TQListViewItem *, const TQPoint&, int )
+
+ This signal is emitted when the right button is clicked (i.e. when
+ it's released). The arguments are the relevant TQListViewItem (may
+ be 0), the point in global coordinates and the relevant column (or
+ -1 if the click was outside the list).
+*/
+
+
+/*!
+ \fn void TQListView::rightButtonPressed (TQListViewItem *, const TQPoint &, int)
+
+ This signal is emitted when the right button is pressed. The
+ arguments are the relevant TQListViewItem (may be 0), the point in
+ global coordinates and the relevant column (or -1 if the click was
+ outside the list).
+*/
+
+/*!
+ \fn void TQListView::contextMenuRequested( TQListViewItem *item, const TQPoint & pos, int col )
+
+ This signal is emitted when the user invokes a context menu with
+ the right mouse button or with special system keys. If the
+ keyboard was used \a item is the current item; if the mouse was
+ used, \a item is the item under the mouse pointer or 0 if there is
+ no item under the mouse pointer. If no item is clicked, the column
+ index emitted is -1.
+
+ \a pos is the position for the context menu in the global
+ coordinate system.
+
+ \a col is the column on which the user pressed, or -1 if the
+ signal was triggered by a key event.
+*/
+
+/*!
+ \reimp
+*/
+void TQListView::styleChange( TQStyle& old )
+{
+ TQScrollView::styleChange( old );
+ reconfigureItems();
+}
+
+
+/*!
+ \reimp
+*/
+void TQListView::setFont( const TQFont & f )
+{
+ TQScrollView::setFont( f );
+ reconfigureItems();
+}
+
+
+/*!
+ \reimp
+*/
+void TQListView::setPalette( const TQPalette & p )
+{
+ TQScrollView::setPalette( p );
+ reconfigureItems();
+}
+
+
+/*!
+ Ensures that setup() is called for all currently visible items,
+ and that it will be called for currently invisible items as soon
+ as their parents are opened.
+
+ (A visible item, here, is an item whose parents are all open. The
+ item may happen to be off-screen.)
+
+ \sa TQListViewItem::setup()
+*/
+
+void TQListView::reconfigureItems()
+{
+ d->fontMetricsHeight = fontMetrics().height();
+ d->minLeftBearing = fontMetrics().minLeftBearing();
+ d->minRightBearing = fontMetrics().minRightBearing();
+ d->ellipsisWidth = fontMetrics().width( "..." ) * 2;
+ d->r->setOpen( FALSE );
+ d->r->configured = FALSE;
+ d->r->setOpen( TRUE );
+}
+
+/*!
+ Ensures that the width mode of column \a c is updated according to
+ the width of \a item.
+*/
+
+void TQListView::widthChanged( const TQListViewItem* item, int c )
+{
+ if ( c >= d->h->count() )
+ return;
+
+ TQFontMetrics fm = fontMetrics();
+ int col = c < 0 ? 0 : c;
+ while ( col == c || ( c < 0 && col < d->h->count() ) ) {
+ if ( d->column[col]->wmode == Maximum ) {
+ int w = item->width( fm, this, col );
+ if ( showSortIndicator() ) {
+ int tw = d->h->sectionSizeHint( col, fm ).width();
+ tw += 40; //add space for the sort indicator
+ w = TQMAX( w, tw );
+ }
+ if ( col == 0 ) {
+ int indent = treeStepSize() * item->depth();
+ if ( rootIsDecorated() )
+ indent += treeStepSize();
+ w += indent;
+ }
+ if ( w > columnWidth( col ) && !d->h->isStretchEnabled() && !d->h->isStretchEnabled( col ) ) {
+ d->updateHeader = TRUE;
+ setColumnWidth( col, w );
+ }
+ }
+ col++;
+ }
+}
+
+/*!
+ \property TQListView::allColumnsShowFocus
+ \brief whether items should show keyboard focus using all columns
+
+ If this property is TRUE all columns will show focus and selection
+ states, otherwise only column 0 will show focus.
+
+ The default is FALSE.
+
+ Setting this to TRUE if it's not necessary may cause noticeable
+ flicker.
+*/
+
+void TQListView::setAllColumnsShowFocus( bool enable )
+{
+ d->allColumnsShowFocus = enable;
+}
+
+bool TQListView::allColumnsShowFocus() const
+{
+ return d->allColumnsShowFocus;
+}
+
+
+/*!
+ Returns the first item in this TQListView. Returns 0 if there is no
+ first item.
+
+ A list view's items can be traversed using firstChild()
+ and nextSibling() or using a TQListViewItemIterator.
+
+ \sa itemAt() TQListViewItem::itemBelow() TQListViewItem::itemAbove()
+*/
+
+TQListViewItem * TQListView::firstChild() const
+{
+ if ( !d->r )
+ return 0;
+
+ d->r->enforceSortOrder();
+ return d->r->childItem;
+}
+
+/*!
+ Returns the last item in the list view tree. Returns 0 if there
+ are no items in the TQListView.
+
+ This function is slow because it traverses the entire tree to tqfind
+ the last item.
+*/
+
+TQListViewItem* TQListView::lastItem() const
+{
+ TQListViewItem* item = firstChild();
+ if ( item ) {
+ while ( item->nextSibling() || item->firstChild() ) {
+ if ( item->nextSibling() )
+ item = item->nextSibling();
+ else
+ item = item->firstChild();
+ }
+ }
+ return item;
+}
+
+/*!
+ Repaints this item on the screen if it is currently visible.
+*/
+
+void TQListViewItem::tqrepaint() const
+{
+ TQListView *lv = listView();
+ if ( lv )
+ lv->repaintItem( this );
+}
+
+
+/*!
+ Repaints \a item on the screen if \a item is currently visible.
+ Takes care to avoid multiple repaints.
+*/
+
+void TQListView::repaintItem( const TQListViewItem * item ) const
+{
+ if ( !item )
+ return;
+ d->dirtyItemTimer->start( 0, TRUE );
+ if ( !d->dirtyItems )
+ d->dirtyItems = new TQPtrDict<void>();
+ d->dirtyItems->tqreplace( (void *)item, (void *)item );
+}
+
+
+struct TQCheckListItemPrivate
+{
+ TQCheckListItemPrivate():
+ exclusive( 0 ),
+ currentState( TQCheckListItem::Off ),
+ statesDict( 0 ),
+ tristate( FALSE ) {}
+
+ TQCheckListItem *exclusive;
+ TQCheckListItem::ToggleState currentState;
+ TQPtrDict<TQCheckListItem::ToggleState> *statesDict;
+ bool tristate;
+};
+
+
+/*!
+ \class TQCheckListItem
+ \brief The TQCheckListItem class provides checkable list view items.
+
+ \ingroup advanced
+
+ TQCheckListItems are used in \l{TQListView}s to provide
+ \l{TQListViewItem}s that are checkboxes, radio buttons or
+ controllers.
+
+ Checkbox and controller check list items may be inserted at any
+ level in a list view. Radio button check list items must be
+ tqchildren of a controller check list item.
+
+ The item can be checked or unchecked with setOn(). Its type can be
+ retrieved with type() and its text retrieved with text().
+
+ \img qlistviewitems.png List View Items
+
+ \sa TQListViewItem TQListView
+*/
+
+// ### obscenity is warranted.
+
+/*!
+ \enum TQCheckListItem::Type
+
+ This enum type specifies a TQCheckListItem's type:
+
+ \value RadioButton
+ \value CheckBox
+ \value Controller \e obsolete (use \c RadioButtonController instead)
+ \value RadioButtonController
+ \value CheckBoxController
+*/
+
+/*!
+ \enum TQCheckListItem::ToggleState
+
+ This enum specifies a TQCheckListItem's toggle state.
+
+ \value Off
+ \value NoChange
+ \value On
+*/
+
+
+/*!
+ Constructs a checkable item with tqparent \a tqparent, text \a text
+ and of type \a tt. Note that a \c RadioButton must be the child of a
+ \c RadioButtonController, otherwise it will not toggle.
+*/
+TQCheckListItem::TQCheckListItem( TQCheckListItem *tqparent, const TQString &text,
+ Type tt )
+ : TQListViewItem( tqparent, text, TQString::null )
+{
+ myType = tt;
+ init();
+ if ( myType == RadioButton ) {
+ if ( tqparent->type() != RadioButtonController )
+ qWarning( "TQCheckListItem::TQCheckListItem(), radio button must be "
+ "child of a controller" );
+ else
+ d->exclusive = tqparent;
+ }
+}
+
+/*!
+ Constructs a checkable item with tqparent \a tqparent, which is after
+ \a after in the tqparent's list of tqchildren, and with text \a text
+ and of type \a tt. Note that a \c RadioButton must be the child of
+ a \c RadioButtonController, otherwise it will not toggle.
+*/
+TQCheckListItem::TQCheckListItem( TQCheckListItem *tqparent, TQListViewItem *after,
+ const TQString &text, Type tt )
+ : TQListViewItem( tqparent, after, text )
+{
+ myType = tt;
+ init();
+ if ( myType == RadioButton ) {
+ if ( tqparent->type() != RadioButtonController )
+ qWarning( "TQCheckListItem::TQCheckListItem(), radio button must be "
+ "child of a controller" );
+ else
+ d->exclusive = tqparent;
+ }
+}
+
+/*!
+ Constructs a checkable item with tqparent \a tqparent, text \a text
+ and of type \a tt. Note that this item must \e not be a \c
+ RadioButton. Radio buttons must be tqchildren of a \c
+ RadioButtonController.
+*/
+TQCheckListItem::TQCheckListItem( TQListViewItem *tqparent, const TQString &text,
+ Type tt )
+ : TQListViewItem( tqparent, text, TQString::null )
+{
+ myType = tt;
+ if ( myType == RadioButton ) {
+ qWarning( "TQCheckListItem::TQCheckListItem(), radio button must be "
+ "child of a TQCheckListItem" );
+ }
+ init();
+}
+
+/*!
+ Constructs a checkable item with tqparent \a tqparent, which is after
+ \a after in the tqparent's list of tqchildren, with text \a text and
+ of type \a tt. Note that this item must \e not be a \c
+ RadioButton. Radio buttons must be tqchildren of a \c
+ RadioButtonController.
+*/
+TQCheckListItem::TQCheckListItem( TQListViewItem *tqparent, TQListViewItem *after,
+ const TQString &text, Type tt )
+ : TQListViewItem( tqparent, after, text )
+{
+ myType = tt;
+ if ( myType == RadioButton ) {
+ qWarning( "TQCheckListItem::TQCheckListItem(), radio button must be "
+ "child of a TQCheckListItem" );
+ }
+ init();
+}
+
+
+/*!
+ Constructs a checkable item with tqparent \a tqparent, text \a text
+ and of type \a tt. Note that \a tt must \e not be \c RadioButton.
+ Radio buttons must be tqchildren of a \c RadioButtonController.
+*/
+TQCheckListItem::TQCheckListItem( TQListView *tqparent, const TQString &text,
+ Type tt )
+ : TQListViewItem( tqparent, text )
+{
+ myType = tt;
+ if ( tt == RadioButton )
+ qWarning( "TQCheckListItem::TQCheckListItem(), radio button must be "
+ "child of a TQCheckListItem" );
+ init();
+}
+
+/*!
+ Constructs a checkable item with tqparent \a tqparent, which is after
+ \a after in the tqparent's list of tqchildren, with text \a text and
+ of type \a tt. Note that \a tt must \e not be \c RadioButton.
+ Radio buttons must be tqchildren of a \c RadioButtonController.
+*/
+TQCheckListItem::TQCheckListItem( TQListView *tqparent, TQListViewItem *after,
+ const TQString &text, Type tt )
+ : TQListViewItem( tqparent, after, text )
+{
+ myType = tt;
+ if ( tt == RadioButton )
+ qWarning( "TQCheckListItem::TQCheckListItem(), radio button must be "
+ "child of a TQCheckListItem" );
+ init();
+}
+
+
+int TQCheckListItem::RTTI = 1;
+
+/* \reimp */
+
+int TQCheckListItem::rtti() const
+{
+ return RTTI;
+}
+
+/*!
+ Constructs a \c RadioButtonController item with tqparent \a tqparent,
+ text \a text and pixmap \a p.
+*/
+TQCheckListItem::TQCheckListItem( TQListView *tqparent, const TQString &text,
+ const TQPixmap & p )
+ : TQListViewItem( tqparent, text )
+{
+ myType = RadioButtonController;
+ setPixmap( 0, p );
+ init();
+}
+
+/*!
+ Constructs a \c RadioButtonController item with tqparent \a tqparent,
+ text \a text and pixmap \a p.
+*/
+TQCheckListItem::TQCheckListItem( TQListViewItem *tqparent, const TQString &text,
+ const TQPixmap & p )
+ : TQListViewItem( tqparent, text )
+{
+ myType = RadioButtonController;
+ setPixmap( 0, p );
+ init();
+}
+
+void TQCheckListItem::init()
+{
+ d = new TQCheckListItemPrivate();
+ on = FALSE; // ### remove on ver 4
+ if ( myType == CheckBoxController || myType == CheckBox ) {
+ d->statesDict = new TQPtrDict<ToggleState>(101);
+ d->statesDict->setAutoDelete( TRUE );
+ }
+ // CheckBoxControllers by default have tristate set to TRUE
+ if ( myType == CheckBoxController )
+ setTristate( TRUE );
+}
+
+/*!
+ Destroys the item, and all its tqchildren to any depth, freeing up
+ all allocated resources.
+*/
+TQCheckListItem::~TQCheckListItem()
+{
+ if ( myType == RadioButton
+ && d->exclusive && d->exclusive->d
+ && d->exclusive->d->exclusive == this )
+ d->exclusive->turnOffChild();
+ d->exclusive = 0; // so the tqchildren won't try to access us.
+ if ( d->statesDict )
+ delete d->statesDict;
+ delete d;
+ d = 0;
+}
+
+/*!
+ \fn TQCheckListItem::Type TQCheckListItem::type() const
+
+ Returns the type of this item.
+*/
+
+/*!
+ \fn bool TQCheckListItem::isOn() const
+
+ Returns TRUE if the item is toggled on; otherwise returns FALSE.
+*/
+
+/*!
+ Sets tristate to \a b if the \c Type is either a \c CheckBoxController or
+ a \c CheckBox.
+
+ \c CheckBoxControllers are tristate by default.
+
+ \sa state() isTristate()
+*/
+void TQCheckListItem::setTristate( bool b )
+{
+ if ( ( myType != CheckBoxController ) && ( myType != CheckBox ) ) {
+ qWarning( "TQCheckListItem::setTristate(), has no effect on RadioButton "
+ "or RadioButtonController." );
+ return;
+ }
+ d->tristate = b;
+}
+
+/*!
+ Returns TRUE if the item is tristate; otherwise returns FALSE.
+
+ \sa setTristate()
+*/
+bool TQCheckListItem::isTristate() const
+{
+ return d->tristate;
+}
+
+/*!
+ Returns the state of the item.
+
+ \sa TQCheckListItem::ToggleState
+*/
+TQCheckListItem::ToggleState TQCheckListItem::state() const
+{
+ if ( !isTristate() && internalState() == NoChange )
+ return Off;
+ else
+ return d->currentState;
+}
+
+/*
+ Same as the public state() except this one does not tqmask NoChange into Off
+ when tristate is disabled.
+*/
+TQCheckListItem::ToggleState TQCheckListItem::internalState() const
+{
+ return d->currentState;
+}
+
+
+
+
+/*!
+ Sets the toggle state of the checklistitem to \a s. \a s can be
+ \c Off, \c NoChange or \c On.
+
+ Tristate can only be enabled for \c CheckBox or \c CheckBoxController,
+ therefore the \c NoChange only applies to them.
+
+ Setting the state to \c On or \c Off on a \c CheckBoxController
+ will recursivly set the states of its tqchildren to the same state.
+
+ Setting the state to \c NoChange on a \c CheckBoxController will
+ make it recursivly recall the previous stored state of its
+ tqchildren. If there was no previous stored state the tqchildren are
+ all set to \c On.
+*/
+void TQCheckListItem::setState( ToggleState s )
+{
+ if ( myType == CheckBoxController && state() == NoChange )
+ updateStoredState( (void*) this );
+ setState( s, TRUE, TRUE );
+}
+
+/*
+ Sets the toggle state of the checklistitems. \a update tells if the
+ controller / tqparent controller should be aware of these changes, \a store
+ tells if the tqparent should store its tqchildren if certain conditions arise
+*/
+void TQCheckListItem::setState( ToggleState s, bool update, bool store)
+{
+
+ if ( s == internalState() )
+ return;
+
+ if ( myType == CheckBox ) {
+ setCurrentState( s );
+ stateChange( state() );
+ if ( update && tqparent() && tqparent()->rtti() == 1
+ && ((TQCheckListItem*)tqparent())->type() == CheckBoxController )
+ ((TQCheckListItem*)tqparent())->updateController( update, store );
+ } else if ( myType == CheckBoxController ) {
+ if ( s == NoChange && childCount()) {
+ restoreState( (void*) this );
+ } else {
+ TQListViewItem *item = firstChild();
+ int childCount = 0;
+ while( item ) {
+ if ( item->rtti() == 1 &&
+ ( ((TQCheckListItem*)item)->type() == CheckBox ||
+ ((TQCheckListItem*)item)->type() == CheckBoxController ) ) {
+ TQCheckListItem *checkItem = (TQCheckListItem*)item;
+ checkItem->setState( s, FALSE, FALSE );
+ childCount++;
+ }
+ item = item->nextSibling();
+ }
+ if ( update ) {
+ if ( childCount > 0 ) {
+ ToggleState oldState = internalState();
+ updateController( FALSE, FALSE );
+ if ( oldState != internalState() &&
+ tqparent() && tqparent()->rtti() == 1 &&
+ ((TQCheckListItem*)tqparent())->type() == CheckBoxController )
+ ((TQCheckListItem*)tqparent())->updateController( update, store );
+
+ updateController( update, store );
+ } else {
+ // if there are no tqchildren we simply set the CheckBoxController and update its tqparent
+ setCurrentState( s );
+ stateChange( state() );
+ if ( tqparent() && tqparent()->rtti() == 1
+ && ((TQCheckListItem*)tqparent())->type() == CheckBoxController )
+ ((TQCheckListItem*)tqparent())->updateController( update, store );
+ }
+ } else {
+ setCurrentState( s );
+ stateChange( state() );
+ }
+
+ }
+ } else if ( myType == RadioButton ) {
+ if ( s == On ) {
+ if ( d->exclusive && d->exclusive->d->exclusive != this )
+ d->exclusive->turnOffChild();
+ setCurrentState( s );
+ if ( d->exclusive )
+ d->exclusive->d->exclusive = this;
+ } else {
+ if ( d->exclusive && d->exclusive->d->exclusive == this )
+ d->exclusive->d->exclusive = 0;
+ setCurrentState( Off );
+ }
+ stateChange( state() );
+ }
+ tqrepaint();
+}
+
+/*
+ this function is needed becase we need to update "on" everytime
+ we update d->currentState. In order to retain binary compatibility
+ the inline function isOn() needs the "on" bool
+ ### should be changed in ver 4
+*/
+void TQCheckListItem::setCurrentState( ToggleState s )
+{
+ ToggleState old = d->currentState;
+ d->currentState = s;
+ if (d->currentState == On)
+ on = TRUE;
+ else
+ on = FALSE;
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ if ( old != d->currentState && listView() )
+ TQAccessible::updateAccessibility( listView()->viewport(), indexOfItem( this ), TQAccessible::StateChanged );
+#else
+ TQ_UNUSED( old );
+#endif
+}
+
+
+
+/*
+ updates the internally stored state of this item for the tqparent (key)
+*/
+void TQCheckListItem::setStoredState( ToggleState newState, void *key )
+{
+ if ( myType == CheckBox || myType == CheckBoxController )
+ d->statesDict->tqreplace( key, new ToggleState(newState) );
+}
+
+/*
+ Returns the stored state for this item for the given key.
+ If the key is not found it returns Off.
+*/
+TQCheckListItem::ToggleState TQCheckListItem::storedState( void *key ) const
+{
+ if ( !d->statesDict )
+ return Off;
+
+ ToggleState *foundState = d->statesDict->tqfind( key );
+ if ( foundState )
+ return ToggleState( *foundState );
+ else
+ return Off;
+}
+
+
+/*!
+ \fn TQString TQCheckListItem::text() const
+
+ Returns the item's text.
+*/
+
+
+/*!
+ If this is a \c RadioButtonController that has \c RadioButton
+ tqchildren, turn off the child that is on.
+*/
+void TQCheckListItem::turnOffChild()
+{
+ if ( myType == RadioButtonController && d->exclusive )
+ d->exclusive->setOn( FALSE );
+}
+
+/*!
+ Toggle check box or set radio button to on.
+*/
+void TQCheckListItem::activate()
+{
+ TQListView * lv = listView();
+
+ if ( (lv && !lv->isEnabled()) || !isEnabled() )
+ return;
+
+ TQPoint pos;
+ int boxsize = lv->tqstyle().tqpixelMetric(TQStyle::PM_CheckListButtonSize, lv);
+ if ( activatedPos( pos ) ) {
+ bool parentControl = FALSE;
+ if ( tqparent() && tqparent()->rtti() == 1 &&
+ ((TQCheckListItem*) tqparent())->type() == RadioButtonController )
+ parentControl = TRUE;
+
+ int x = parentControl ? 0 : 3;
+ int align = lv->columnAlignment( 0 );
+ int marg = lv->itemMargin();
+ int y = 0;
+
+ if ( align & TQt::AlignVCenter )
+ y = ( ( height() - boxsize ) / 2 ) + marg;
+ else
+ y = (lv->fontMetrics().height() + 2 + marg - boxsize) / 2;
+
+ TQRect r( x, y, boxsize-3, boxsize-3 );
+ // columns might have been swapped
+ r.moveBy( lv->header()->sectionPos( 0 ), 0 );
+ if ( !r.tqcontains( pos ) )
+ return;
+ }
+ if ( ( myType == CheckBox ) || ( myType == CheckBoxController) ) {
+ switch ( internalState() ) {
+ case On:
+ setState( Off );
+ break;
+ case Off:
+ if ( (!isTristate() && myType == CheckBox) ||
+ (myType == CheckBoxController && !childCount()) ) {
+ setState( On );
+ } else {
+ setState( NoChange );
+ if ( myType == CheckBoxController && internalState() != NoChange )
+ setState( On );
+ }
+ break;
+ case NoChange:
+ setState( On );
+ break;
+ }
+ ignoreDoubleClick();
+ } else if ( myType == RadioButton ) {
+ setOn( TRUE );
+ ignoreDoubleClick();
+ }
+}
+
+/*!
+ Sets the button on if \a b is TRUE, otherwise sets it off.
+ Maintains radio button exclusivity.
+*/
+void TQCheckListItem::setOn( bool b )
+{
+ if ( b )
+ setState( On , TRUE, TRUE );
+ else
+ setState( Off , TRUE, TRUE );
+}
+
+
+/*!
+ This virtual function is called when the item changes its state.
+ \c NoChange (if tristate is enabled and the type is either \c
+ CheckBox or \c CheckBoxController) reports the same as \c Off, so
+ use state() to determine if the state is actually \c Off or \c
+ NoChange.
+*/
+void TQCheckListItem::stateChange( bool )
+{
+}
+
+/*
+ Calls the public virtual function if the state is changed to either On, NoChange or Off.
+ NoChange reports the same as Off - ### should be fixed in ver4
+*/
+void TQCheckListItem::stateChange( ToggleState s )
+{
+ stateChange( s == On );
+}
+
+/*
+ sets the state of the CheckBox and CheckBoxController back to
+ previous stored state
+*/
+void TQCheckListItem::restoreState( void *key, int depth )
+{
+ switch ( type() ) {
+ case CheckBox:
+ setCurrentState( storedState( key ) );
+ stateChange( state() );
+ tqrepaint();
+ break;
+ case CheckBoxController: {
+ TQListViewItem *item = firstChild();
+ int childCount = 0;
+ while ( item ) {
+ // recursively calling restoreState for tqchildren of type CheckBox and CheckBoxController
+ if ( item->rtti() == 1 &&
+ ( ((TQCheckListItem*)item)->type() == CheckBox ||
+ ((TQCheckListItem*)item)->type() == CheckBoxController ) ) {
+ ((TQCheckListItem*)item)->restoreState( key , depth+1 );
+ childCount++;
+ }
+ item = item->nextSibling();
+ }
+ if ( childCount > 0 ) {
+ if ( depth == 0 )
+ updateController( TRUE );
+ else
+ updateController( FALSE );
+ } else {
+ // if there are no tqchildren we retrieve the CheckBoxController state directly.
+ setState( storedState( key ), TRUE, FALSE );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+/*
+ Checks the tqchildrens state and updates the controllers state
+ if necessary. If the controllers state change, then his tqparent again is
+ called to update itself.
+*/
+void TQCheckListItem::updateController( bool update , bool store )
+{
+ if ( myType != CheckBoxController )
+ return;
+
+ TQCheckListItem *controller = 0;
+ // checks if this CheckBoxController has another CheckBoxController as tqparent
+ if ( tqparent() && tqparent()->rtti() == 1
+ && ((TQCheckListItem*)tqparent())->type() == CheckBoxController )
+ controller = (TQCheckListItem*)tqparent();
+
+ ToggleState theState = Off;
+ bool first = TRUE;
+ TQListViewItem *item = firstChild();
+ while( item && theState != NoChange ) {
+ if ( item->rtti() == 1 &&
+ ( ((TQCheckListItem*)item)->type() == CheckBox ||
+ ((TQCheckListItem*)item)->type() == CheckBoxController ) ) {
+ TQCheckListItem *checkItem = (TQCheckListItem*)item;
+ if ( first ) {
+ theState = checkItem->internalState();
+ first = FALSE;
+ } else {
+ if ( checkItem->internalState() == NoChange ||
+ theState != checkItem->internalState() )
+ theState = NoChange;
+ else
+ theState = checkItem->internalState();
+ }
+ }
+ item = item->nextSibling();
+ }
+ if ( internalState() != theState ) {
+ setCurrentState( theState );
+ if ( store && ( internalState() == On || internalState() == Off ) )
+ updateStoredState( (void*) this );
+ stateChange( state() );
+ if ( update && controller ) {
+ controller->updateController( update, store );
+ }
+ tqrepaint();
+ }
+}
+
+
+/*
+ Makes all the tqchildren CheckBoxes update their storedState
+*/
+void TQCheckListItem::updateStoredState( void *key )
+{
+ if ( myType != CheckBoxController )
+ return;
+
+ TQListViewItem *item = firstChild();
+ while( item ) {
+ if ( item->rtti() == 1 ) {
+ TQCheckListItem *checkItem = (TQCheckListItem*)item;
+ if ( checkItem->type() == CheckBox )
+ checkItem->setStoredState( checkItem->internalState(), key );
+ else if (checkItem->type() == CheckBoxController )
+ checkItem->updateStoredState( key );
+ }
+ item = item->nextSibling();
+ }
+ // this state is only needed if the CheckBoxController has no CheckBox / CheckBoxController tqchildren.
+ setStoredState( internalState() , key );
+}
+
+
+/*!
+ \reimp
+*/
+void TQCheckListItem::setup()
+{
+ TQListViewItem::setup();
+ int h = height();
+ TQListView *lv = listView();
+ if ( lv )
+ h = TQMAX( lv->tqstyle().tqpixelMetric(TQStyle::PM_CheckListButtonSize, lv),
+ h );
+ h = TQMAX( h, TQApplication::globalStrut().height() );
+ setHeight( h );
+}
+
+/*!
+ \reimp
+*/
+
+int TQCheckListItem::width( const TQFontMetrics& fm, const TQListView* lv, int column) const
+{
+ int r = TQListViewItem::width( fm, lv, column );
+ if ( column == 0 ) {
+ r += lv->itemMargin();
+ if ( myType == RadioButtonController && pixmap( 0 ) ) {
+ // r += 0;
+ } else {
+ r += lv->tqstyle().tqpixelMetric(TQStyle::PM_CheckListButtonSize, lv) + 4;
+ }
+ }
+ return TQMAX( r, TQApplication::globalStrut().width() );
+}
+
+/*!
+ Paints the item using the painter \a p and the color group \a cg.
+ The item is in column \a column, has width \a width and has
+ tqalignment \a align. (See TQt::AlignmentFlags for valid alignments.)
+*/
+void TQCheckListItem::paintCell( TQPainter * p, const TQColorGroup & cg,
+ int column, int width, int align )
+{
+ if ( !p )
+ return;
+
+ TQListView *lv = listView();
+ if ( !lv )
+ return;
+
+ const BackgroundMode bgmode = lv->viewport()->backgroundMode();
+ const TQColorGroup::ColorRole crole = TQPalette::backgroundRoleFromMode( bgmode );
+ if ( cg.brush( crole ) != lv->tqcolorGroup().brush( crole ) )
+ p->fillRect( 0, 0, width, height(), cg.brush( crole ) );
+ else
+ lv->paintEmptyArea( p, TQRect( 0, 0, width, height() ) );
+
+ if ( column != 0 ) {
+ // The rest is text, or for subclasses to change.
+ TQListViewItem::paintCell( p, cg, column, width, align );
+ return;
+ }
+
+ bool parentControl = FALSE;
+ if ( tqparent() && tqparent()->rtti() == 1 &&
+ ((TQCheckListItem*) tqparent())->type() == RadioButtonController )
+ parentControl = TRUE;
+
+ TQFontMetrics fm( lv->fontMetrics() );
+ int boxsize = lv->tqstyle().tqpixelMetric( myType == RadioButtonController ? TQStyle::PM_CheckListControllerSize :
+ TQStyle::PM_CheckListButtonSize, lv);
+ int marg = lv->itemMargin();
+ int r = marg;
+
+ // Draw controller / checkbox / radiobutton ---------------------
+ int styleflags = TQStyle::Style_Default;
+ if ( internalState() == On ) {
+ styleflags |= TQStyle::Style_On;
+ } else if ( internalState() == NoChange ) {
+ if ( myType == CheckBoxController && !isTristate() )
+ styleflags |= TQStyle::Style_Off;
+ else
+ styleflags |= TQStyle::Style_NoChange;
+ } else {
+ styleflags |= TQStyle::Style_Off;
+ }
+ if ( isSelected() )
+ styleflags |= TQStyle::Style_Selected;
+ if ( isEnabled() && lv->isEnabled() )
+ styleflags |= TQStyle::Style_Enabled;
+
+ if ( myType == RadioButtonController ) {
+ int x = 0;
+ if(!parentControl)
+ x += 3;
+ if ( !pixmap( 0 ) ) {
+ lv->tqstyle().tqdrawPrimitive(TQStyle::PE_CheckListController, p,
+ TQRect(x, 0, boxsize,
+ fm.height() + 2 + marg),
+ cg, (QStyle::StateFlag)styleflags, TQStyleOption(this));
+ r += boxsize + 4;
+ }
+ } else {
+ TQ_ASSERT( lv ); //###
+ int x = 0;
+ int y = 0;
+ if ( !parentControl )
+ x += 3;
+ if ( align & TQt::AlignVCenter )
+ y = ( ( height() - boxsize ) / 2 ) + marg;
+ else
+ y = (fm.height() + 2 + marg - boxsize) / 2;
+
+ if ( ( myType == CheckBox ) || ( myType == CheckBoxController ) ) {
+ lv->tqstyle().tqdrawPrimitive(TQStyle::PE_CheckListIndicator, p,
+ TQRect(x, y, boxsize,
+ fm.height() + 2 + marg),
+ cg, (QStyle::StateFlag)styleflags, TQStyleOption(this));
+ } else { //radio button look
+ lv->tqstyle().tqdrawPrimitive(TQStyle::PE_CheckListExclusiveIndicator,
+ p, TQRect(x, y, boxsize,
+ fm.height() + 2 + marg),
+ cg, (QStyle::StateFlag)styleflags, TQStyleOption(this));
+ }
+ r += boxsize + 4;
+ }
+
+ // Draw text ----------------------------------------------------
+ p->translate( r, 0 );
+ p->setPen( TQPen( cg.text() ) );
+ TQListViewItem::paintCell( p, cg, column, width - r, align );
+}
+
+/*!
+ Draws the focus rectangle \a r using the color group \a cg on the
+ painter \a p.
+*/
+void TQCheckListItem::paintFocus( TQPainter *p, const TQColorGroup & cg,
+ const TQRect & r )
+{
+ bool intersect = TRUE;
+ TQListView *lv = listView();
+ if ( lv && lv->header()->mapToActual( 0 ) != 0 ) {
+ int xdepth = lv->treeStepSize() * ( depth() + ( lv->rootIsDecorated() ? 1 : 0) ) + lv->itemMargin();
+ int p = lv->header()->cellPos( lv->header()->mapToActual( 0 ) );
+ xdepth += p;
+ intersect = r.intersects( TQRect( p, r.y(), xdepth - p + 1, r.height() ) );
+ }
+ bool parentControl = FALSE;
+ if ( tqparent() && tqparent()->rtti() == 1 &&
+ ((TQCheckListItem*) tqparent())->type() == RadioButtonController )
+ parentControl = TRUE;
+ if ( myType != RadioButtonController && intersect &&
+ (lv->rootIsDecorated() || myType == RadioButton ||
+ (myType == CheckBox && parentControl) ) ) {
+ TQRect rect;
+ int boxsize = lv->tqstyle().tqpixelMetric(TQStyle::PM_CheckListButtonSize, lv);
+ if ( lv->columnAlignment(0) == TQt::AlignCenter ) {
+ TQFontMetrics fm( lv->font() );
+ int bx = (lv->columnWidth(0) - (boxsize + fm.width(text())))/2 + boxsize;
+ if ( bx < 0 ) bx = 0;
+ rect.setRect( r.x() + bx + 5, r.y(), r.width() - bx - 5,
+ r.height() );
+ } else
+ rect.setRect( r.x() + boxsize + 5, r.y(), r.width() - boxsize - 5,
+ r.height() );
+ TQListViewItem::paintFocus(p, cg, rect);
+ } else {
+ TQListViewItem::paintFocus(p, cg, r);
+ }
+}
+
+/*!
+ \reimp
+*/
+TQSize TQListView::tqsizeHint() const
+{
+ if ( cachedSizeHint().isValid() )
+ return cachedSizeHint();
+
+ constPolish();
+
+ if ( !isVisible() && (!d->drawables || d->drawables->isEmpty()) )
+ // force the column widths to sanity, if possible
+ buildDrawableList();
+
+ TQSize s( d->h->tqsizeHint() );
+ if ( verticalScrollBar()->isVisible() )
+ s.setWidth( s.width() + tqstyle().tqpixelMetric(TQStyle::PM_ScrollBarExtent) );
+ s += TQSize(frameWidth()*2,frameWidth()*2);
+ TQListViewItem * l = d->r;
+ while( l && !l->height() )
+ l = l->childItem ? l->childItem : l->siblingItem;
+
+ if ( l && l->height() )
+ s.setHeight( s.height() + 10 * l->height() );
+ else
+ s.setHeight( s.height() + 140 );
+
+ if ( s.width() > s.height() * 3 )
+ s.setHeight( s.width() / 3 );
+ else if ( s.width() *3 < s.height() )
+ s.setHeight( s.width() * 3 );
+
+ setCachedSizeHint( s );
+
+ return s;
+}
+
+
+/*!
+ \reimp
+*/
+
+TQSize TQListView::tqminimumSizeHint() const
+{
+ return TQScrollView::tqminimumSizeHint();
+}
+
+
+/*!
+ Sets \a item to be open if \a open is TRUE and \a item is
+ expandable, and to be closed if \a open is FALSE. Repaints
+ accordingly.
+
+ \sa TQListViewItem::setOpen() TQListViewItem::setExpandable()
+*/
+
+void TQListView::setOpen( TQListViewItem * item, bool open )
+{
+ if ( !item ||
+ item->isOpen() == open ||
+ (open && !item->childCount() && !item->isExpandable()) )
+ return;
+
+ TQListViewItem* nextParent = 0;
+ if ( open )
+ nextParent = item->itemBelow();
+
+ item->setOpen( open );
+
+ if ( open ) {
+ TQListViewItem* lastChild = item;
+ TQListViewItem* tmp;
+ while ( TRUE ) {
+ tmp = lastChild->itemBelow();
+ if ( !tmp || tmp == nextParent )
+ break;
+ lastChild = tmp;
+ }
+ ensureItemVisible( lastChild );
+ ensureItemVisible( item );
+ }
+ if ( d->drawables )
+ d->drawables->clear();
+ buildDrawableList();
+
+ TQListViewPrivate::DrawableItem * c = d->drawables->first();
+
+ while( c && c->i && c->i != item )
+ c = d->drawables->next();
+
+ if ( c && c->i == item ) {
+ d->dirtyItemTimer->start( 0, TRUE );
+ if ( !d->dirtyItems )
+ d->dirtyItems = new TQPtrDict<void>();
+ while( c && c->i ) {
+ d->dirtyItems->insert( (void *)(c->i), (void *)(c->i) );
+ c = d->drawables->next();
+ }
+ }
+}
+
+
+/*!
+ Identical to \a{item}->isOpen(). Provided for completeness.
+
+ \sa setOpen()
+*/
+
+bool TQListView::isOpen( const TQListViewItem * item ) const
+{
+ return item->isOpen();
+}
+
+
+/*!
+ \property TQListView::rootIsDecorated
+ \brief whether the list view shows open/close signs on root items
+
+ Open/close signs are small <b>+</b> or <b>-</b> symbols in windows
+ style, or arrows in Motif style. The default is FALSE.
+*/
+
+void TQListView::setRootIsDecorated( bool enable )
+{
+ if ( enable != (bool)d->rootIsExpandable ) {
+ d->rootIsExpandable = enable;
+ if ( isVisible() )
+ triggerUpdate();
+ }
+}
+
+bool TQListView::rootIsDecorated() const
+{
+ return d->rootIsExpandable;
+}
+
+
+/*!
+ Ensures that item \a i is visible, scrolling the list view
+ vertically if necessary and opening (expanding) any tqparent items
+ if this is required to show the item.
+
+ \sa tqitemRect() TQScrollView::ensureVisible()
+*/
+
+void TQListView::ensureItemVisible( const TQListViewItem * i )
+{
+ if ( !i || !i->isVisible() )
+ return;
+
+ TQListViewItem *tqparent = i->tqparent();
+ while ( tqparent ) {
+ if ( !tqparent->isOpen() )
+ tqparent->setOpen( TRUE );
+ tqparent = tqparent->tqparent();
+ }
+
+ if ( d->r->maybeTotalHeight < 0 )
+ updateGeometries();
+ int y = itemPos( i );
+ int h = i->height();
+ if ( isVisible() && y + h > contentsY() + visibleHeight() )
+ setContentsPos( contentsX(), y - visibleHeight() + h );
+ else if ( !isVisible() || y < contentsY() )
+ setContentsPos( contentsX(), y );
+}
+
+
+/*!
+ \fn TQString TQCheckListItem::text( int n ) const
+
+ \reimp
+*/
+
+/*!
+ Returns the TQHeader object that manages this list view's columns.
+ Please don't modify the header behind the list view's back.
+
+ You may safely call TQHeader::setClickEnabled(),
+ TQHeader::setResizeEnabled(), TQHeader::setMovingEnabled(),
+ TQHeader::hide() and all the const TQHeader functions.
+*/
+
+TQHeader * TQListView::header() const
+{
+ return d->h;
+}
+
+
+/*!
+ \property TQListView::childCount
+ \brief the number of parentless (top-level) TQListViewItem objects in this TQListView
+
+ Holds the current number of parentless (top-level) TQListViewItem
+ objects in this TQListView.
+
+ \sa TQListViewItem::childCount()
+*/
+
+int TQListView::childCount() const
+{
+ if ( d->r )
+ return d->r->childCount();
+ return 0;
+}
+
+
+/*
+ Moves this item to just after \a olderSibling. \a olderSibling and
+ this object must have the same tqparent.
+
+ If you need to move an item in the hierarchy use takeItem() and
+ insertItem().
+*/
+
+void TQListViewItem::moveToJustAfter( TQListViewItem * olderSibling )
+{
+ if ( parentItem && olderSibling &&
+ olderSibling->parentItem == parentItem && olderSibling != this ) {
+ if ( parentItem->childItem == this ) {
+ parentItem->childItem = siblingItem;
+ } else {
+ TQListViewItem * i = parentItem->childItem;
+ while( i && i->siblingItem != this )
+ i = i->siblingItem;
+ if ( i )
+ i->siblingItem = siblingItem;
+ }
+ siblingItem = olderSibling->siblingItem;
+ olderSibling->siblingItem = this;
+ parentItem->lsc = Unsorted;
+ }
+}
+
+/*!
+ Move the item to be after item \a after, which must be one of the
+ item's siblings. To move an item in the hierarchy, use takeItem()
+ and insertItem().
+
+ Note that this function will have no effect if sorting is enabled
+ in the list view.
+*/
+
+void TQListViewItem::moveItem( TQListViewItem *after )
+{
+ if ( !after || after == this )
+ return;
+ if ( tqparent() != after->tqparent() ) {
+ if ( parentItem )
+ parentItem->takeItem( this );
+ if ( after->parentItem ) {
+ int tmpLsc = after->parentItem->lsc;
+ after->parentItem->insertItem( this );
+ after->parentItem->lsc = tmpLsc;
+ }
+ }
+ moveToJustAfter( after );
+ TQListView *lv = listView();
+ if ( lv )
+ lv->triggerUpdate();
+}
+
+/*
+ Recursively sorts items, from the root to this item.
+ (enforceSortOrder() won't work the other way around, as
+ documented.)
+*/
+void TQListViewItem::enforceSortOrderBackToRoot()
+{
+ if ( parentItem ) {
+ parentItem->enforceSortOrderBackToRoot();
+ parentItem->enforceSortOrder();
+ }
+}
+
+/*!
+ \reimp
+*/
+void TQListView::showEvent( TQShowEvent * )
+{
+ if ( d->drawables )
+ d->drawables->clear();
+ delete d->dirtyItems;
+ d->dirtyItems = 0;
+ d->dirtyItemTimer->stop();
+ d->fullRepaintOnComlumnChange = TRUE;
+
+ updateGeometries();
+}
+
+
+/*!
+ Returns the y coordinate of this item in the list view's
+ coordinate system. This function is normally much slower than
+ TQListView::itemAt(), but it works for all items whereas
+ TQListView::itemAt() normally only works for items on the screen.
+
+ \sa TQListView::itemAt() TQListView::tqitemRect() TQListView::itemPos()
+*/
+
+int TQListViewItem::itemPos() const
+{
+ TQPtrStack<TQListViewItem> s;
+ TQListViewItem * i = (TQListViewItem *)this;
+ while( i ) {
+ s.push( i );
+ i = i->parentItem;
+ }
+
+ int a = 0;
+ TQListViewItem * p = 0;
+ while( s.count() ) {
+ i = s.pop();
+ if ( p ) {
+ if ( !p->configured ) {
+ p->configured = TRUE;
+ p->setup(); // ### virtual non-const function called in const
+ }
+ a += p->height();
+ TQListViewItem * s = p->firstChild();
+ while( s && s != i ) {
+ a += s->totalHeight();
+ s = s->nextSibling();
+ }
+ }
+ p = i;
+ }
+ return a;
+}
+
+
+/*!
+ \fn void TQListView::removeItem( TQListViewItem * )
+ \obsolete
+
+ This function has been renamed takeItem().
+*/
+
+/*!
+ Removes item \a i from the list view; \a i must be a top-level
+ item. The warnings regarding TQListViewItem::takeItem() apply to
+ this function, too.
+
+ \sa insertItem()
+*/
+void TQListView::takeItem( TQListViewItem * i )
+{
+ if ( d->r )
+ d->r->takeItem( i );
+}
+
+
+void TQListView::openFocusItem()
+{
+ d->autoopenTimer->stop();
+ if ( d->focusItem && !d->focusItem->isOpen() ) {
+ d->focusItem->setOpen( TRUE );
+ d->focusItem->tqrepaint();
+ }
+}
+
+static const int autoopenTime = 750;
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*! \reimp */
+
+void TQListView::contentsDragEnterEvent( TQDragEnterEvent *e )
+{
+ d->oldFocusItem = d->focusItem;
+ TQListViewItem *i = d->focusItem;
+ d->focusItem = itemAt( contentsToViewport( e->pos() ) );
+ if ( i )
+ i->tqrepaint();
+ if ( d->focusItem ) {
+ d->autoopenTimer->start( autoopenTime );
+ d->focusItem->dragEntered();
+ d->focusItem->tqrepaint();
+ }
+ if ( (i && i->dropEnabled() && i->acceptDrop( e )) || acceptDrops() )
+ e->accept();
+ else
+ e->ignore();
+}
+
+/*! \reimp */
+
+void TQListView::contentsDragMoveEvent( TQDragMoveEvent *e )
+{
+ TQListViewItem *i = d->focusItem;
+ d->focusItem = itemAt( contentsToViewport( e->pos() ) );
+ if ( i ) {
+ if ( i != d->focusItem )
+ i->dragLeft();
+ i->tqrepaint();
+ }
+ if ( d->focusItem ) {
+ if ( i != d->focusItem ) {
+ d->focusItem->dragEntered();
+ d->autoopenTimer->stop();
+ d->autoopenTimer->start( autoopenTime );
+ }
+ d->focusItem->tqrepaint();
+ } else {
+ d->autoopenTimer->stop();
+ }
+ if ( (i && i->dropEnabled() && i->acceptDrop( e )) || acceptDrops() )
+ e->accept();
+ else
+ e->ignore();
+}
+
+/*! \reimp */
+
+void TQListView::contentsDragLeaveEvent( TQDragLeaveEvent * )
+{
+ d->autoopenTimer->stop();
+
+ if ( d->focusItem )
+ d->focusItem->dragLeft();
+
+ setCurrentItem( d->oldFocusItem );
+ d->oldFocusItem = 0;
+}
+
+/*! \reimp */
+
+void TQListView::contentsDropEvent( TQDropEvent *e )
+{
+ d->autoopenTimer->stop();
+
+ setCurrentItem( d->oldFocusItem );
+ TQListViewItem *i = itemAt( contentsToViewport( e->pos() ) );
+ if ( i && i->dropEnabled() && i->acceptDrop( e ) ) {
+ i->dropped( e );
+ e->accept();
+ } else if ( acceptDrops() ) {
+ emit dropped( e );
+ e->accept();
+ }
+}
+
+/*!
+ If the user presses the mouse on an item and starts moving the
+ mouse, and the item allow dragging (see
+ TQListViewItem::setDragEnabled()), this function is called to get a
+ drag object and a drag is started unless dragObject() returns 0.
+
+ By default this function returns 0. You should reimplement it and
+ create a TQDragObject depending on the selected items.
+*/
+
+TQDragObject *TQListView::dragObject()
+{
+ return 0;
+}
+
+/*!
+ Starts a drag.
+*/
+
+void TQListView::startDrag()
+{
+ if ( !d->startDragItem )
+ return;
+
+ d->startDragItem = 0;
+ d->buttonDown = FALSE;
+
+ TQDragObject *drag = dragObject();
+ if ( !drag )
+ return;
+
+ drag->drag();
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!
+ \property TQListView::defaultRenameAction
+ \brief What action to perform when the editor loses focus during renaming
+
+ If this property is \c Accept, and the user renames an item and
+ the editor loses focus (without the user pressing Enter), the
+ item will still be renamed. If the property's value is \c Reject,
+ the item will not be renamed unless the user presses Enter. The
+ default is \c Reject.
+*/
+
+void TQListView::setDefaultRenameAction( RenameAction a )
+{
+ d->defRenameAction = a;
+}
+
+TQListView::RenameAction TQListView::defaultRenameAction() const
+{
+ return d->defRenameAction;
+}
+
+/*!
+ Returns TRUE if an item is being renamed; otherwise returns FALSE.
+*/
+
+bool TQListView::isRenaming() const
+{
+ return currentItem() && currentItem()->renameBox;
+}
+
+/**********************************************************************
+ *
+ * Class TQListViewItemIterator
+ *
+ **********************************************************************/
+
+
+/*!
+ \class TQListViewItemIterator
+ \brief The TQListViewItemIterator class provides an iterator for collections of TQListViewItems.
+
+ \ingroup advanced
+
+ Construct an instance of a TQListViewItemIterator, with either a
+ TQListView* or a TQListViewItem* as argument, to operate on the tree
+ of TQListViewItems, starting from the argument.
+
+ A TQListViewItemIterator iterates over all the items from its
+ starting point. This means that it always makes the first child of
+ the current item the new current item. If there is no child, the
+ next sibling becomes the new current item; and if there is no next
+ sibling, the next sibling of the tqparent becomes current.
+
+ The following example creates a list of all the items that have
+ been selected by the user, storing pointers to the items in a
+ TQPtrList:
+ \code
+ TQPtrList<TQListViewItem> lst;
+ TQListViewItemIterator it( myListView );
+ while ( it.current() ) {
+ if ( it.current()->isSelected() )
+ lst.append( it.current() );
+ ++it;
+ }
+ \endcode
+
+ An alternative approach is to use an \c IteratorFlag:
+ \code
+ TQPtrList<TQListViewItem> lst;
+ TQListViewItemIterator it( myListView, TQListViewItemIterator::Selected );
+ while ( it.current() ) {
+ lst.append( it.current() );
+ ++it;
+ }
+ \endcode
+
+ A TQListViewItemIterator provides a convenient and easy way to
+ traverse a hierarchical TQListView.
+
+ Multiple TQListViewItemIterators can operate on the tree of
+ TQListViewItems. A TQListView knows about all iterators operating on
+ its TQListViewItems. So when a TQListViewItem gets removed all
+ iterators that point to this item are updated and point to the
+ following item if possible, otherwise to a valid item before the
+ current one or to 0. Note however that deleting the tqparent item of
+ an item that an iterator points to is not safe.
+
+ \sa TQListView, TQListViewItem
+*/
+
+/*!
+ \enum TQListViewItemIterator::IteratorFlag
+
+ These flags can be passed to a TQListViewItemIterator constructor
+ (OR-ed together if more than one is used), so that the iterator
+ will only iterate over items that match the given flags.
+
+ \value Visible
+ \value Invisible
+ \value Selected
+ \value Unselected
+ \value Selectable
+ \value NotSelectable
+ \value DragEnabled
+ \value DragDisabled
+ \value DropEnabled
+ \value DropDisabled
+ \value Expandable
+ \value NotExpandable
+ \value Checked
+ \value NotChecked
+*/
+
+/*!
+ Constructs an empty iterator.
+*/
+
+TQListViewItemIterator::TQListViewItemIterator()
+ : curr( 0 ), listView( 0 )
+{
+ init( 0 );
+}
+
+/*!
+ Constructs an iterator for the TQListView that tqcontains the \a
+ item. The current iterator item is set to point to the \a item.
+*/
+
+TQListViewItemIterator::TQListViewItemIterator( TQListViewItem *item )
+ : curr( item ), listView( 0 )
+{
+ init( 0 );
+
+ if ( item ) {
+ item->enforceSortOrderBackToRoot();
+ listView = item->listView();
+ }
+ addToListView();
+}
+
+/*!
+ Constructs an iterator for the TQListView that tqcontains the \a item
+ using the flags \a iteratorFlags. The current iterator item is set
+ to point to \a item or the next matching item if \a item doesn't
+ match the flags.
+
+ \sa TQListViewItemIterator::IteratorFlag
+*/
+
+TQListViewItemIterator::TQListViewItemIterator( TQListViewItem *item, int iteratorFlags )
+ : curr( item ), listView( 0 )
+{
+ init( iteratorFlags );
+
+ // go to next matching item if the current don't match
+ if ( curr && !matchesFlags( curr ) )
+ ++( *this );
+
+ if ( curr ) {
+ curr->enforceSortOrderBackToRoot();
+ listView = curr->listView();
+ }
+ addToListView();
+}
+
+
+/*!
+ Constructs an iterator for the same TQListView as \a it. The
+ current iterator item is set to point on the current item of \a
+ it.
+*/
+
+TQListViewItemIterator::TQListViewItemIterator( const TQListViewItemIterator& it )
+ : curr( it.curr ), listView( it.listView )
+{
+ init(it.d() ? it.d()->flags : 0);
+
+ addToListView();
+}
+
+/*!
+ Constructs an iterator for the TQListView \a lv. The current
+ iterator item is set to point on the first child (TQListViewItem)
+ of \a lv.
+*/
+
+TQListViewItemIterator::TQListViewItemIterator( TQListView *lv )
+ : curr( lv->firstChild() ), listView( lv )
+{
+ init( 0 );
+
+ addToListView();
+}
+
+/*!
+ Constructs an iterator for the TQListView \a lv with the flags \a
+ iteratorFlags. The current iterator item is set to point on the
+ first child (TQListViewItem) of \a lv that matches the flags.
+
+ \sa TQListViewItemIterator::IteratorFlag
+*/
+
+TQListViewItemIterator::TQListViewItemIterator( TQListView *lv, int iteratorFlags )
+ : curr ( lv->firstChild() ), listView( lv )
+{
+ init( iteratorFlags );
+
+ addToListView();
+ if ( !matchesFlags( curr ) )
+ ++( *this );
+}
+
+
+
+/*!
+ Assignment. Makes a copy of \a it and returns a reference to its
+ iterator.
+*/
+
+TQListViewItemIterator &TQListViewItemIterator::operator=( const TQListViewItemIterator &it )
+{
+ if ( listView ) {
+ if ( listView->d->iterators->removeRef( this ) ) {
+ if ( listView->d->iterators->count() == 0 ) {
+ delete listView->d->iterators;
+ listView->d->iterators = 0;
+ }
+ }
+ }
+
+ listView = it.listView;
+ addToListView();
+ curr = it.curr;
+
+ // sets flags to be the same as the input iterators flags
+ if ( d() && it.d() )
+ d()->flags = it.d()->flags;
+
+ // go to next matching item if the current don't match
+ if ( curr && !matchesFlags( curr ) )
+ ++( *this );
+
+ return *this;
+}
+
+/*!
+ Destroys the iterator.
+*/
+
+TQListViewItemIterator::~TQListViewItemIterator()
+{
+ if ( listView ) {
+ if ( listView->d->iterators->removeRef( this ) ) {
+ if ( listView->d->iterators->count() == 0 ) {
+ delete listView->d->iterators;
+ listView->d->iterators = 0;
+ }
+ }
+ }
+ // removs the d-ptr from the dict ( autodelete on), and deletes the
+ // ptrdict if it becomes empty
+ if ( qt_iteratorprivate_dict ) {
+ qt_iteratorprivate_dict->remove( this );
+ if ( qt_iteratorprivate_dict->isEmpty() ) {
+ delete qt_iteratorprivate_dict;
+ qt_iteratorprivate_dict = 0;
+ }
+ }
+}
+
+/*!
+ Prefix ++. Makes the next item the new current item and returns
+ it. Returns 0 if the current item is the last item or the
+ TQListView is 0.
+*/
+
+TQListViewItemIterator &TQListViewItemIterator::operator++()
+{
+ if ( !curr )
+ return *this;
+
+ TQListViewItem *item = curr->firstChild();
+ if ( !item ) {
+ while ( (item = curr->nextSibling()) == 0 ) {
+ curr = curr->tqparent();
+ if ( curr == 0 )
+ break;
+ }
+ }
+ curr = item;
+ // if the next one doesn't match the flags we try one more ahead
+ if ( curr && !matchesFlags( curr ) )
+ ++( *this );
+ return *this;
+}
+
+/*!
+ \overload
+
+ Postfix ++. Makes the next item the new current item and returns
+ the item that \e was the current item.
+*/
+
+const TQListViewItemIterator TQListViewItemIterator::operator++( int )
+{
+ TQListViewItemIterator oldValue = *this;
+ ++( *this );
+ return oldValue;
+}
+
+/*!
+ Sets the current item to the item \a j positions after the current
+ item. If that item is beyond the last item, the current item is
+ set to 0. Returns the current item.
+*/
+
+TQListViewItemIterator &TQListViewItemIterator::operator+=( int j )
+{
+ while ( curr && j-- )
+ ++( *this );
+
+ return *this;
+}
+
+/*!
+ Prefix --. Makes the previous item the new current item and
+ returns it. Returns 0 if the current item is the first item or the
+ TQListView is 0.
+*/
+
+TQListViewItemIterator &TQListViewItemIterator::operator--()
+{
+ if ( !curr )
+ return *this;
+
+ if ( !curr->tqparent() ) {
+ // we are in the first depth
+ if ( curr->listView() ) {
+ if ( curr->listView()->firstChild() != curr ) {
+ // go the previous sibling
+ TQListViewItem *i = curr->listView()->firstChild();
+ while ( i && i->siblingItem != curr )
+ i = i->siblingItem;
+
+ curr = i;
+
+ if ( i && i->firstChild() ) {
+ // go to the last child of this item
+ TQListViewItemIterator it( curr->firstChild() );
+ for ( ; it.current() && it.current()->tqparent(); ++it )
+ curr = it.current();
+ }
+
+ if ( curr && !matchesFlags( curr ) )
+ --( *this );
+
+ return *this;
+ } else {
+ //we are already the first child of the list view, so it's over
+ curr = 0;
+ return *this;
+ }
+ } else
+ return *this;
+ } else {
+ TQListViewItem *tqparent = curr->tqparent();
+
+ if ( curr != tqparent->firstChild() ) {
+ // go to the previous sibling
+ TQListViewItem *i = tqparent->firstChild();
+ while ( i && i->siblingItem != curr )
+ i = i->siblingItem;
+
+ curr = i;
+
+ if ( i && i->firstChild() ) {
+ // go to the last child of this item
+ TQListViewItemIterator it( curr->firstChild() );
+ for ( ; it.current() && it.current()->tqparent() != tqparent; ++it )
+ curr = it.current();
+ }
+
+ if ( curr && !matchesFlags( curr ) )
+ --( *this );
+
+ return *this;
+ } else {
+ // make our tqparent the current item
+ curr = tqparent;
+
+ if ( curr && !matchesFlags( curr ) )
+ --( *this );
+
+ return *this;
+ }
+ }
+}
+
+/*!
+ \overload
+
+ Postfix --. Makes the previous item the new current item and
+ returns the item that \e was the current item.
+*/
+
+const TQListViewItemIterator TQListViewItemIterator::operator--( int )
+{
+ TQListViewItemIterator oldValue = *this;
+ --( *this );
+ return oldValue;
+}
+
+/*!
+ Sets the current item to the item \a j positions before the
+ current item. If that item is before the first item, the current
+ item is set to 0. Returns the current item.
+*/
+
+TQListViewItemIterator &TQListViewItemIterator::operator-=( int j )
+{
+ while ( curr && j-- )
+ --( *this );
+
+ return *this;
+}
+
+/*!
+ Dereference operator. Returns a reference to the current item. The
+ same as current().
+*/
+
+TQListViewItem* TQListViewItemIterator::operator*()
+{
+ if ( curr != 0 && !matchesFlags( curr ) )
+ qWarning( "TQListViewItemIterator::operator*() curr out of sync" );
+ return curr;
+}
+
+/*!
+ Returns iterator's current item.
+*/
+
+TQListViewItem *TQListViewItemIterator::current() const
+{
+ if ( curr != 0 && !matchesFlags( curr ) )
+ qWarning( "TQListViewItemIterator::current() curr out of sync" );
+ return curr;
+}
+
+TQListViewItemIteratorPrivate* TQListViewItemIterator::d() const
+{
+ return qt_iteratorprivate_dict ?
+ qt_iteratorprivate_dict->tqfind( (void *)this ) : 0;
+}
+
+void TQListViewItemIterator::init( int iteratorFlags )
+{
+ // makes new global ptrdict if it doesn't exist
+ if ( !qt_iteratorprivate_dict ) {
+ qt_iteratorprivate_dict = new TQPtrDict<TQListViewItemIteratorPrivate>;
+ qt_iteratorprivate_dict->setAutoDelete( TRUE );
+ }
+
+ // sets flag, or inserts new TQListViewItemIteratorPrivate with flag
+ if ( d() )
+ d()->flags = iteratorFlags;
+ else
+ qt_iteratorprivate_dict->insert( this, new TQListViewItemIteratorPrivate( iteratorFlags ) );
+}
+
+
+/*
+ Adds this iterator to its TQListView's list of iterators.
+*/
+
+void TQListViewItemIterator::addToListView()
+{
+ if ( listView ) {
+ if ( !listView->d->iterators ) {
+ listView->d->iterators = new TQPtrList<TQListViewItemIterator>;
+ TQ_CHECK_PTR( listView->d->iterators );
+ }
+ listView->d->iterators->append( this );
+ }
+}
+
+/*
+ This function is called to notify the iterator that the current
+ item has been deleted, and sets the current item point to another
+ (valid) item or 0.
+*/
+
+void TQListViewItemIterator::currentRemoved()
+{
+ if ( !curr ) return;
+
+ if ( curr->tqparent() )
+ curr = curr->tqparent();
+ else if ( curr->nextSibling() )
+ curr = curr->nextSibling();
+ else if ( listView && listView->firstChild() &&
+ listView->firstChild() != curr )
+ curr = listView->firstChild();
+ else
+ curr = 0;
+}
+
+/*
+ returns TRUE if the item \a item matches all of the flags set for the iterator
+*/
+bool TQListViewItemIterator::matchesFlags( const TQListViewItem *item ) const
+{
+ if ( !item )
+ return FALSE;
+
+ int flags = d() ? d()->flags : 0;
+
+ if ( flags == 0 )
+ return TRUE;
+
+ if ( flags & Visible && !item->isVisible() )
+ return FALSE;
+ if ( flags & Invisible && item->isVisible() )
+ return FALSE;
+ if ( flags & Selected && !item->isSelected() )
+ return FALSE;
+ if ( flags & Unselected && item->isSelected() )
+ return FALSE;
+ if ( flags & Selectable && !item->isSelectable() )
+ return FALSE;
+ if ( flags & NotSelectable && item->isSelectable() )
+ return FALSE;
+ if ( flags & DragEnabled && !item->dragEnabled() )
+ return FALSE;
+ if ( flags & DragDisabled && item->dragEnabled() )
+ return FALSE;
+ if ( flags & DropEnabled && !item->dropEnabled() )
+ return FALSE;
+ if ( flags & DropDisabled && item->dropEnabled() )
+ return FALSE;
+ if ( flags & Expandable && !item->isExpandable() )
+ return FALSE;
+ if ( flags & NotExpandable && item->isExpandable() )
+ return FALSE;
+ if ( flags & Checked && !isChecked( item ) )
+ return FALSE;
+ if ( flags & NotChecked && isChecked( item ) )
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ we want the iterator to check TQCheckListItems as well, so we provide this convenience function
+ that checks if the rtti() is 1 which means TQCheckListItem and if isOn is TRUE, returns FALSE otherwise.
+*/
+bool TQListViewItemIterator::isChecked( const TQListViewItem *item ) const
+{
+ if ( item->rtti() == 1 )
+ return ((const TQCheckListItem*)item)->isOn();
+ else return FALSE;
+}
+
+void TQListView::handleItemChange( TQListViewItem *old, bool shift, bool control )
+{
+ if ( d->selectionMode == Single ) {
+ // nothing
+ } else if ( d->selectionMode == Extended ) {
+ if ( shift ) {
+ selectRange( d->selectAnchor ? d->selectAnchor : old,
+ d->focusItem, FALSE, TRUE, (d->selectAnchor && !control) ? TRUE : FALSE );
+ } else if ( !control ) {
+ bool block = tqsignalsBlocked();
+ blockSignals( TRUE );
+ selectAll( FALSE );
+ blockSignals( block );
+ setSelected( d->focusItem, TRUE );
+ }
+ } else if ( d->selectionMode == Multi ) {
+ if ( shift )
+ selectRange( old, d->focusItem, TRUE, FALSE );
+ }
+}
+
+void TQListView::startRename()
+{
+ if ( !currentItem() )
+ return;
+ currentItem()->startRename( d->pressedColumn );
+ d->buttonDown = FALSE;
+}
+
+/* unselects items from to, including tqchildren, returns TRUE if any items were unselected */
+bool TQListView::clearRange( TQListViewItem *from, TQListViewItem *to, bool includeFirst )
+{
+ if ( !from || !to )
+ return FALSE;
+
+ // Swap
+ if ( from->itemPos() > to->itemPos() ) {
+ TQListViewItem *temp = from;
+ from = to;
+ to = temp;
+ }
+
+ // Start on second?
+ if ( !includeFirst ) {
+ TQListViewItem *below = (from == to) ? from : from->itemBelow();
+ if ( below )
+ from = below;
+ }
+
+ // Clear items <from, to>
+ bool changed = FALSE;
+
+ TQListViewItemIterator it( from );
+ while ( it.current() ) {
+ if ( it.current()->isSelected() ) {
+ it.current()->setSelected( FALSE );
+ changed = TRUE;
+ }
+ if ( it.current() == to )
+ break;
+ ++it;
+ }
+
+ // NOTE! This function does _not_ emit
+ // any Q_SIGNALS about selection changed
+ return changed;
+}
+
+void TQListView::selectRange( TQListViewItem *from, TQListViewItem *to, bool invert, bool includeFirst, bool clearSel )
+{
+ if ( !from || !to )
+ return;
+ if ( from == to && !includeFirst )
+ return;
+ bool swap = FALSE;
+ if ( to == from->itemAbove() )
+ swap = TRUE;
+ if ( !swap && from != to && from != to->itemAbove() ) {
+ TQListViewItemIterator it( from );
+ bool found = FALSE;
+ for ( ; it.current(); ++it ) {
+ if ( it.current() == to ) {
+ found = TRUE;
+ break;
+ }
+ }
+ if ( !found )
+ swap = TRUE;
+ }
+ if ( swap ) {
+ TQListViewItem *i = from;
+ from = to;
+ to = i;
+ if ( !includeFirst )
+ to = to->itemAbove();
+ } else {
+ if ( !includeFirst )
+ from = from->itemBelow();
+ }
+
+ bool changed = FALSE;
+ if ( clearSel ) {
+ TQListViewItemIterator it( firstChild() );
+ for ( ; it.current(); ++it ) {
+ if ( it.current()->selected ) {
+ it.current()->setSelected( FALSE );
+ changed = TRUE;
+ }
+ }
+ it = TQListViewItemIterator( to );
+ for ( ; it.current(); ++it ) {
+ if ( it.current()->selected ) {
+ it.current()->setSelected( FALSE );
+ changed = TRUE;
+ }
+ }
+ }
+
+ for ( TQListViewItem *i = from; i; i = i->itemBelow() ) {
+ if ( !invert ) {
+ if ( !i->selected && i->isSelectable() ) {
+ i->setSelected( TRUE );
+ changed = TRUE;
+ }
+ } else {
+ bool sel = !i->selected;
+ if ( ((bool)i->selected != sel && sel && i->isSelectable()) || !sel ) {
+ i->setSelected( sel );
+ changed = TRUE;
+ }
+ }
+ if ( i == to )
+ break;
+ }
+ if ( changed ) {
+ d->useDoubleBuffer = TRUE;
+ triggerUpdate();
+ emit selectionChanged();
+ }
+}
+
+/* clears selection from anchor to old, selects from anchor to new, does not emit selectionChanged on change */
+bool TQListView::selectRange( TQListViewItem *newItem, TQListViewItem *oldItem, TQListViewItem *anchorItem )
+{
+ if ( !newItem || !oldItem || !anchorItem )
+ return FALSE;
+
+ int anchorPos = anchorItem ? anchorItem->itemPos() : 0,
+ oldPos = oldItem ? oldItem->itemPos() : 0,
+ newPos = newItem->itemPos();
+ TQListViewItem *top=0, *bottom=0;
+ if ( anchorPos > newPos ) {
+ top = newItem;
+ bottom = anchorItem;
+ } else {
+ top = anchorItem;
+ bottom = newItem;
+ }
+
+ // removes the parts of the old selection that will no longer be selected
+ bool changed = FALSE;
+ int topPos = top ? top->itemPos() : 0,
+ bottomPos = bottom ? bottom->itemPos() : 0;
+ if ( !(oldPos > topPos && oldPos < bottomPos) ) {
+ if ( oldPos < topPos )
+ changed = clearRange( oldItem, top );
+ else
+ changed = clearRange( bottom, oldItem );
+ }
+
+ // selects the new (not already selected) items
+ TQListViewItemIterator lit( top );
+ for ( ; lit.current(); ++lit ) {
+ if ( (bool)lit.current()->selected != d->select ) {
+ lit.current()->setSelected( d->select );
+ changed = TRUE;
+ }
+ // Include bottom, then break
+ if ( lit.current() == bottom )
+ break;
+ }
+
+ return changed;
+}
+
+
+/*!
+ Finds the first list view item in column \a column, that matches
+ \a text and returns the item, or returns 0 of no such item could
+ be found.
+ The search starts from the current item if the current item exists,
+ otherwise it starts from the first list view item. After reaching
+ the last item the search continues from the first item.
+ Pass OR-ed together \l TQt::StringComparisonMode values
+ in the \a compare flag, to control how the matching is performed.
+ The default comparison mode is case-sensitive, exact match.
+*/
+
+TQListViewItem *TQListView::tqfindItem( const TQString& text, int column,
+ TQt::ComparisonFlags compare ) const
+{
+ if (text.isEmpty() && !(compare & TQt::ExactMatch))
+ return 0;
+
+ if ( compare == TQt::CaseSensitive || compare == 0 )
+ compare |= TQt::ExactMatch;
+
+ TQString itmtxt;
+ TQString comtxt = text;
+ if ( !(compare & TQt::CaseSensitive) )
+ comtxt = comtxt.lower();
+
+ TQListViewItemIterator it( d->focusItem ? d->focusItem : firstChild() );
+ TQListViewItem *sentinel = 0;
+ TQListViewItem *item;
+ TQListViewItem *beginsWithItem = 0;
+ TQListViewItem *endsWithItem = 0;
+ TQListViewItem *tqcontainsItem = 0;
+
+ for ( int pass = 0; pass < 2; pass++ ) {
+ while ( (item = it.current()) != sentinel ) {
+ itmtxt = item->text( column );
+ if ( !(compare & TQt::CaseSensitive) )
+ itmtxt = itmtxt.lower();
+
+ if ( compare & TQt::ExactMatch && itmtxt == comtxt )
+ return item;
+ if ( compare & TQt::BeginsWith && !beginsWithItem && itmtxt.startsWith( comtxt ) )
+ beginsWithItem = tqcontainsItem = item;
+ if ( compare & TQt::EndsWith && !endsWithItem && itmtxt.endsWith( comtxt ) )
+ endsWithItem = tqcontainsItem = item;
+ if ( compare & TQt::Contains && !tqcontainsItem && itmtxt.tqcontains( comtxt ) )
+ tqcontainsItem = item;
+ ++it;
+ }
+
+ it = TQListViewItemIterator( firstChild() );
+ sentinel = d->focusItem ? d->focusItem : firstChild();
+ }
+
+ // Obey the priorities
+ if ( beginsWithItem )
+ return beginsWithItem;
+ else if ( endsWithItem )
+ return endsWithItem;
+ else if ( tqcontainsItem )
+ return tqcontainsItem;
+ return 0;
+}
+
+/*! \reimp */
+void TQListView::windowActivationChange( bool oldActive )
+{
+ if ( oldActive && d->scrollTimer )
+ d->scrollTimer->stop();
+ if ( tqpalette().active() != tqpalette().inactive() )
+ viewport()->update();
+ TQScrollView::windowActivationChange( oldActive );
+}
+
+/*!
+ Hides the column specified at \a column. This is a convenience
+ function that calls setColumnWidth( \a column, 0 ).
+
+ Note: The user may still be able to resize the hidden column using
+ the header handles. To prevent this, call setResizeEnabled(FALSE,
+ \a column) on the list views header.
+
+ \sa setColumnWidth()
+*/
+
+void TQListView::hideColumn( int column )
+{
+ setColumnWidth( column, 0 );
+}
+
+/*! Adjusts the column \a col to its preferred width */
+
+void TQListView::adjustColumn( int col )
+{
+ if ( col < 0 || col > (int)d->column.count() - 1 || d->h->isStretchEnabled( col ) )
+ return;
+
+ int oldw = d->h->sectionSize( col );
+
+ int w = d->h->sectionSizeHint( col, fontMetrics() ).width();
+ if ( d->h->iconSet( col ) )
+ w += d->h->iconSet( col )->pixmap().width();
+ w = TQMAX( w, 20 );
+ TQFontMetrics fm( fontMetrics() );
+ TQListViewItem* item = firstChild();
+ int rootDepth = rootIsDecorated() ? treeStepSize() : 0;
+ while ( item ) {
+ int iw = item->width( fm, this, col );
+ if ( 0 == col )
+ iw += itemMargin() + rootDepth + item->depth()*treeStepSize() - 1;
+ w = TQMAX( w, iw );
+ item = item->itemBelow();
+ }
+ w = TQMAX( w, TQApplication::globalStrut().width() );
+
+ d->h->adjustHeaderSize( oldw - w );
+ if (oldw != w) {
+ d->fullRepaintOnComlumnChange = TRUE;
+ d->h->resizeSection( col, w );
+ emit d->h->sizeChange( col, oldw, w);
+ }
+}
+
+#endif // TQT_NO_LISTVIEW
diff --git a/tqtinterface/qt4/src/widgets/tqlistview.h b/tqtinterface/qt4/src/widgets/tqlistview.h
new file mode 100644
index 0000000..11d2110
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqlistview.h
@@ -0,0 +1,610 @@
+/****************************************************************************
+**
+** Definition of TQListView widget class
+**
+** Created : 970809
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQLISTVIEW_H
+#define TQLISTVIEW_H
+
+#ifndef TQT_H
+#include "tqscrollview.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_LISTVIEW
+
+
+class TQPixmap;
+class TQFont;
+class TQHeader;
+class TQIconSet;
+
+class TQListView;
+struct TQListViewPrivate;
+struct TQCheckListItemPrivate;
+class TQListViewItemIterator;
+struct TQListViewItemIteratorPrivate;
+class TQDragObject;
+class TQMimeSource;
+class TQLineEdit;
+class TQListViewToolTip;
+
+class TQ_EXPORT TQListViewItem : public TQt
+{
+ friend class TQListViewItemIterator;
+ friend class TQListViewToolTip;
+
+public:
+ TQListViewItem( TQListView * tqparent );
+ TQListViewItem( TQListViewItem * tqparent );
+ TQListViewItem( TQListView * tqparent, TQListViewItem * after );
+ TQListViewItem( TQListViewItem * tqparent, TQListViewItem * after );
+
+ TQListViewItem( TQListView * tqparent,
+ TQString, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null );
+ TQListViewItem( TQListViewItem * tqparent,
+ TQString, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null );
+
+ TQListViewItem( TQListView * tqparent, TQListViewItem * after,
+ TQString, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null );
+ TQListViewItem( TQListViewItem * tqparent, TQListViewItem * after,
+ TQString, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null,
+ TQString = TQString::null, TQString = TQString::null );
+ virtual ~TQListViewItem();
+
+ virtual void insertItem( TQListViewItem * );
+ virtual void takeItem( TQListViewItem * );
+ virtual void removeItem( TQListViewItem *item ) { takeItem( item ); } //obsolete, use takeItem instead
+
+ int height() const;
+ virtual void invalidateHeight();
+ int totalHeight() const;
+ virtual int width( const TQFontMetrics&,
+ const TQListView*, int column) const;
+ void widthChanged(int column=-1) const;
+ int depth() const;
+
+ virtual void setText( int, const TQString &);
+ virtual TQString text( int ) const;
+
+ virtual void setPixmap( int, const TQPixmap & );
+ virtual const TQPixmap * pixmap( int ) const;
+
+ virtual TQString key( int, bool ) const;
+ virtual int compare( TQListViewItem *i, int col, bool ) const;
+ virtual void sortChildItems( int, bool );
+
+ int childCount() const { return nChildren; }
+
+ bool isOpen() const { return open; }
+ virtual void setOpen( bool );
+ virtual void setup();
+
+ virtual void setSelected( bool );
+ bool isSelected() const { return selected; }
+
+ virtual void paintCell( TQPainter *, const TQColorGroup & cg,
+ int column, int width, int tqalignment );
+ virtual void paintBranches( TQPainter * p, const TQColorGroup & cg,
+ int w, int y, int h );
+ virtual void paintFocus( TQPainter *, const TQColorGroup & cg,
+ const TQRect & r );
+
+ TQListViewItem * firstChild() const;
+ TQListViewItem * nextSibling() const { return siblingItem; }
+ TQListViewItem * tqparent() const;
+
+ TQListViewItem * itemAbove();
+ TQListViewItem * itemBelow();
+
+ int itemPos() const;
+
+ TQListView *listView() const;
+
+ virtual void setSelectable( bool enable );
+ bool isSelectable() const { return selectable && enabled; }
+
+ virtual void setExpandable( bool );
+ bool isExpandable() const { return expandable; }
+
+ void tqrepaint() const;
+
+ virtual void sort();
+ void moveItem( TQListViewItem *after );
+
+ virtual void setDragEnabled( bool allow );
+ virtual void setDropEnabled( bool allow );
+ bool dragEnabled() const;
+ bool dropEnabled() const;
+ virtual bool acceptDrop( const TQMimeSource *mime ) const;
+
+ void tqsetVisible( bool b );
+ inline void setVisible( bool b ) { tqsetVisible(b); }
+ bool isVisible() const;
+
+ virtual void setRenameEnabled( int col, bool b );
+ bool renameEnabled( int col ) const;
+ virtual void startRename( int col );
+
+ virtual void setEnabled( bool b );
+ bool isEnabled() const;
+
+ virtual int rtti() const;
+ // ### TQt 4: make const or better use an enum
+ static int RTTI;
+
+ virtual void setMultiLinesEnabled( bool b );
+ bool multiLinesEnabled() const;
+
+protected:
+ virtual void enforceSortOrder() const;
+ virtual void setHeight( int );
+ virtual void activate();
+
+ bool activatedPos( TQPoint & );
+#ifndef TQT_NO_DRAGANDDROP
+ virtual void dropped( TQDropEvent *e );
+#endif
+ virtual void dragEntered();
+ virtual void dragLeft();
+ virtual void okRename( int col );
+ virtual void cancelRename( int col );
+
+ void ignoreDoubleClick();
+
+//private:
+public:
+ void init();
+ void moveToJustAfter( TQListViewItem * );
+ void enforceSortOrderBackToRoot();
+ void removeRenameBox();
+
+ int ownHeight;
+ int maybeTotalHeight;
+ int nChildren;
+
+ uint lsc: 14;
+ uint lso: 1;
+ uint open : 1;
+ uint selected : 1;
+ uint selectable: 1;
+ uint configured: 1;
+ uint expandable: 1;
+ uint is_root: 1;
+ uint allow_drag : 1;
+ uint allow_drop : 1;
+ uint visible : 1;
+ uint enabled : 1;
+ uint mlenabled : 1;
+
+ TQListViewItem * parentItem;
+ TQListViewItem * siblingItem;
+ TQListViewItem * childItem;
+ TQLineEdit *renameBox;
+ int renameCol;
+
+ void * columns;
+
+ friend class TQListView;
+};
+
+class TQCheckListItem;
+
+class TQ_EXPORT TQListView: public TQScrollView
+{
+ friend class TQListViewItemIterator;
+ friend class TQListViewItem;
+ friend class TQCheckListItem;
+ friend class TQListViewToolTip;
+
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( SelectionMode ResizeMode RenameAction )
+ Q_PROPERTY( int columns READ columns )
+ Q_PROPERTY( bool multiSelection READ isMultiSelection WRITE setMultiSelection DESIGNABLE false )
+ Q_PROPERTY( SelectionMode selectionMode READ selectionMode WRITE setSelectionMode )
+ Q_PROPERTY( int childCount READ childCount )
+ Q_PROPERTY( bool allColumnsShowFocus READ allColumnsShowFocus WRITE setAllColumnsShowFocus )
+ Q_PROPERTY( bool showSortIndicator READ showSortIndicator WRITE setShowSortIndicator )
+ Q_PROPERTY( int itemMargin READ itemMargin WRITE setItemMargin )
+ Q_PROPERTY( bool rootIsDecorated READ rootIsDecorated WRITE setRootIsDecorated )
+ Q_PROPERTY( bool showToolTips READ showToolTips WRITE setShowToolTips )
+ Q_PROPERTY( ResizeMode resizeMode READ resizeMode WRITE setResizeMode )
+ Q_PROPERTY( int treeStepSize READ treeStepSize WRITE setTreeStepSize )
+ Q_PROPERTY( RenameAction defaultRenameAction READ defaultRenameAction WRITE setDefaultRenameAction )
+
+public:
+ TQListView( TQWidget* tqparent=0, const char* name=0, WFlags f = 0 );
+ ~TQListView();
+
+ int treeStepSize() const;
+ virtual void setTreeStepSize( int );
+
+ virtual void insertItem( TQListViewItem * );
+ virtual void takeItem( TQListViewItem * );
+ virtual void removeItem( TQListViewItem *item ) { takeItem( item ); } // obsolete, use takeItem instead
+
+ TQHeader * header() const;
+
+ virtual int addColumn( const TQString &label, int size = -1);
+ virtual int addColumn( const TQIconSet& iconset, const TQString &label, int size = -1);
+ virtual void removeColumn( int index );
+ virtual void setColumnText( int column, const TQString &label );
+ virtual void setColumnText( int column, const TQIconSet& iconset, const TQString &label );
+ TQString columnText( int column ) const;
+ virtual void setColumnWidth( int column, int width );
+ int columnWidth( int column ) const;
+ enum WidthMode { Manual, Maximum };
+ virtual void setColumnWidthMode( int column, WidthMode );
+ WidthMode columnWidthMode( int column ) const;
+ int columns() const;
+
+ virtual void setColumnAlignment( int, int );
+ int columnAlignment( int ) const;
+
+ void show();
+
+ TQListViewItem * itemAt( const TQPoint & screenPos ) const;
+ TQRect tqitemRect( const TQListViewItem * ) const;
+ int itemPos( const TQListViewItem * );
+
+ void ensureItemVisible( const TQListViewItem * );
+
+ void repaintItem( const TQListViewItem * ) const;
+
+ virtual void setMultiSelection( bool enable );
+ bool isMultiSelection() const;
+
+ enum SelectionMode { Single, Multi, Extended, NoSelection };
+ void setSelectionMode( SelectionMode mode );
+ SelectionMode selectionMode() const;
+
+ virtual void clearSelection();
+ virtual void setSelected( TQListViewItem *, bool );
+ void setSelectionAnchor( TQListViewItem * );
+ bool isSelected( const TQListViewItem * ) const;
+ TQListViewItem * selectedItem() const;
+ virtual void setOpen( TQListViewItem *, bool );
+ bool isOpen( const TQListViewItem * ) const;
+
+ virtual void setCurrentItem( TQListViewItem * );
+ TQListViewItem * currentItem() const;
+
+ TQListViewItem * firstChild() const;
+ TQListViewItem * lastItem() const;
+
+ int childCount() const;
+
+ virtual void setAllColumnsShowFocus( bool );
+ bool allColumnsShowFocus() const;
+
+ virtual void setItemMargin( int );
+ int itemMargin() const;
+
+ virtual void setRootIsDecorated( bool );
+ bool rootIsDecorated() const;
+
+ virtual void setSorting( int column, bool ascending = TRUE );
+ int sortColumn() const;
+ void setSortColumn( int column );
+ TQt::SortOrder sortOrder() const;
+ void setSortOrder( TQt::SortOrder order );
+ virtual void sort();
+
+ virtual void setFont( const TQFont & );
+ virtual void setPalette( const TQPalette & );
+
+ virtual bool eventFilter( TQObject * o, TQEvent * );
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ virtual void setShowSortIndicator( bool show );
+ bool showSortIndicator() const;
+ virtual void setShowToolTips( bool b );
+ bool showToolTips() const;
+
+ enum ResizeMode { NoColumn, AllColumns, LastColumn };
+ virtual void setResizeMode( ResizeMode m );
+ ResizeMode resizeMode() const;
+
+ TQListViewItem * tqfindItem( const TQString& text, int column, TQt::ComparisonFlags compare = TQt::ExactMatch | TQt::CaseSensitive ) const;
+
+ enum RenameAction { Accept, Reject };
+ virtual void setDefaultRenameAction( RenameAction a );
+ RenameAction defaultRenameAction() const;
+ bool isRenaming() const;
+
+ void hideColumn( int column );
+
+public Q_SLOTS:
+ virtual void clear();
+ virtual void invertSelection();
+ virtual void selectAll( bool select );
+ void triggerUpdate();
+ void setContentsPos( int x, int y );
+ void adjustColumn( int col );
+
+Q_SIGNALS:
+ void selectionChanged();
+ void selectionChanged( TQListViewItem * );
+ void currentChanged( TQListViewItem * );
+ void clicked( TQListViewItem * );
+ void clicked( TQListViewItem *, const TQPoint &, int );
+ void pressed( TQListViewItem * );
+ void pressed( TQListViewItem *, const TQPoint &, int );
+
+ void doubleClicked( TQListViewItem * );
+ void doubleClicked( TQListViewItem *, const TQPoint&, int );
+ void returnPressed( TQListViewItem * );
+ void spacePressed( TQListViewItem * );
+ void rightButtonClicked( TQListViewItem *, const TQPoint&, int );
+ void rightButtonPressed( TQListViewItem *, const TQPoint&, int );
+ void mouseButtonPressed( int, TQListViewItem *, const TQPoint& , int );
+ void mouseButtonClicked( int, TQListViewItem *, const TQPoint&, int );
+
+ void contextMenuRequested( TQListViewItem *, const TQPoint &, int );
+
+ void onItem( TQListViewItem *item );
+ void onViewport();
+
+ void expanded( TQListViewItem *item );
+ void collapsed( TQListViewItem *item );
+#ifndef TQT_NO_DRAGANDDROP
+ void dropped( TQDropEvent *e );
+#endif
+
+public:
+ Q_SIGNAL void itemRenamed( TQListViewItem *item, int col, const TQString & );
+ Q_SIGNAL void itemRenamed( TQListViewItem *item, int col );
+
+protected:
+ void contentsMousePressEvent( TQMouseEvent * e );
+ void contentsMouseReleaseEvent( TQMouseEvent * e );
+ void contentsMouseMoveEvent( TQMouseEvent * e );
+ void contentsMouseDoubleClickEvent( TQMouseEvent * e );
+ void contentsContextMenuEvent( TQContextMenuEvent * e );
+#ifndef TQT_NO_DRAGANDDROP
+ void contentsDragEnterEvent( TQDragEnterEvent *e );
+ void contentsDragMoveEvent( TQDragMoveEvent *e );
+ void contentsDragLeaveEvent( TQDragLeaveEvent *e );
+ void contentsDropEvent( TQDropEvent *e );
+ virtual TQDragObject *dragObject();
+ virtual void startDrag();
+#endif
+
+ virtual void focusInEvent( TQFocusEvent * e );
+ virtual void focusOutEvent( TQFocusEvent * e );
+
+ virtual void keyPressEvent( TQKeyEvent *e );
+
+ virtual void resizeEvent( TQResizeEvent *e );
+ virtual void viewportResizeEvent( TQResizeEvent *e );
+
+ virtual void showEvent( TQShowEvent * );
+
+ void drawContentsOffset( TQPainter *, int ox, int oy,
+ int cx, int cy, int cw, int ch );
+
+ virtual void paintEmptyArea( TQPainter *, const TQRect & );
+ void styleChange( TQStyle& );
+ void windowActivationChange( bool );
+
+protected Q_SLOTS:
+ void updateContents();
+ void doAutoScroll();
+
+private Q_SLOTS:
+ void changeSortColumn( int );
+ void handleIndexChange();
+ void updateDirtyItems();
+ void makeVisible();
+ void handleSizeChange( int, int, int );
+ void startRename();
+ void openFocusItem();
+
+private:
+ void contentsMousePressEventEx( TQMouseEvent * e );
+ void contentsMouseReleaseEventEx( TQMouseEvent * e );
+ void init();
+ void updateGeometries();
+ void buildDrawableList() const;
+ void reconfigureItems();
+ void widthChanged(const TQListViewItem*, int c);
+ void handleItemChange( TQListViewItem *old, bool shift, bool control );
+ void selectRange( TQListViewItem *from, TQListViewItem *to, bool invert, bool includeFirst, bool clearSel = FALSE );
+ bool selectRange( TQListViewItem *newItem, TQListViewItem *oldItem, TQListViewItem *anchorItem );
+ bool clearRange( TQListViewItem *from, TQListViewItem *to, bool includeFirst = TRUE );
+ void doAutoScroll( const TQPoint &cursorPos );
+
+ TQListViewPrivate * d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQListView( const TQListView & );
+ TQListView &operator=( const TQListView & );
+#endif
+};
+
+
+class TQ_EXPORT TQCheckListItem : public TQListViewItem
+{
+public:
+ enum Type { RadioButton,
+ CheckBox,
+ Controller,
+ RadioButtonController=Controller,
+ CheckBoxController };
+ // ### should be integrated with qbutton in ver4 perhaps
+ enum ToggleState { Off, NoChange, On };
+
+ TQCheckListItem( TQCheckListItem *tqparent, const TQString &text,
+ Type = RadioButtonController );
+ TQCheckListItem( TQCheckListItem *tqparent, TQListViewItem *after,
+ const TQString &text, Type = RadioButtonController );
+ TQCheckListItem( TQListViewItem *tqparent, const TQString &text,
+ Type = RadioButtonController );
+ TQCheckListItem( TQListViewItem *tqparent, TQListViewItem *after,
+ const TQString &text, Type = RadioButtonController );
+ TQCheckListItem( TQListView *tqparent, const TQString &text,
+ Type = RadioButtonController );
+ TQCheckListItem( TQListView *tqparent, TQListViewItem *after,
+ const TQString &text, Type = RadioButtonController );
+ TQCheckListItem( TQListViewItem *tqparent, const TQString &text,
+ const TQPixmap & );
+ TQCheckListItem( TQListView *tqparent, const TQString &text,
+ const TQPixmap & );
+ ~TQCheckListItem();
+
+ void paintCell( TQPainter *, const TQColorGroup & cg,
+ int column, int width, int tqalignment );
+ virtual void paintFocus( TQPainter *, const TQColorGroup & cg,
+ const TQRect & r );
+ int width( const TQFontMetrics&, const TQListView*, int column) const;
+ void setup();
+
+ virtual void setOn( bool ); // ### should be tqreplaced by setChecked in ver4
+ bool isOn() const { return on; }
+ Type type() const { return myType; }
+ TQString text() const { return TQListViewItem::text( 0 ); }
+ TQString text( int n ) const { return TQListViewItem::text( n ); }
+
+ void setTristate( bool );
+ bool isTristate() const;
+ ToggleState state() const;
+ void setState( ToggleState s);
+
+ int rtti() const;
+ static int RTTI;
+
+protected:
+ void activate();
+ void turnOffChild();
+ virtual void stateChange( bool );
+ Type myType;
+
+private:
+ void init();
+ ToggleState internalState() const;
+ void setStoredState( ToggleState newState, void *key );
+ ToggleState storedState( void *key ) const;
+ void stateChange( ToggleState s );
+ void restoreState( void *key, int depth = 0 );
+ void updateController( bool update = TRUE , bool store = FALSE );
+ void updateStoredState( void *key );
+ void setState( ToggleState s, bool update, bool store );
+ void setCurrentState( ToggleState s );
+
+ bool on; // ### remove in ver4
+ TQCheckListItemPrivate *d;
+};
+
+class TQ_EXPORT TQListViewItemIterator
+{
+ friend struct TQListViewPrivate;
+ friend class TQListView;
+ friend class TQListViewItem;
+
+public:
+ enum IteratorFlag {
+ Visible = 0x00000001,
+ Invisible = 0x00000002,
+ Selected = 0x00000004,
+ Unselected = 0x00000008,
+ Selectable = 0x00000010,
+ NotSelectable = 0x00000020,
+ DragEnabled = 0x00000040,
+ DragDisabled = 0x00000080,
+ DropEnabled = 0x00000100,
+ DropDisabled = 0x00000200,
+ Expandable = 0x00000400,
+ NotExpandable = 0x00000800,
+ Checked = 0x00001000,
+ NotChecked = 0x00002000
+ };
+
+ TQListViewItemIterator();
+ TQListViewItemIterator( TQListViewItem *item );
+ TQListViewItemIterator( TQListViewItem *item, int iteratorFlags );
+
+ TQListViewItemIterator( const TQListViewItemIterator &it );
+ TQListViewItemIterator( TQListView *lv );
+ TQListViewItemIterator( TQListView *lv, int iteratorFlags );
+
+ TQListViewItemIterator &operator=( const TQListViewItemIterator &it );
+
+ ~TQListViewItemIterator();
+
+ TQListViewItemIterator &operator++();
+ const TQListViewItemIterator operator++( int );
+ TQListViewItemIterator &operator+=( int j );
+
+ TQListViewItemIterator &operator--();
+ const TQListViewItemIterator operator--( int );
+ TQListViewItemIterator &operator-=( int j );
+
+ TQListViewItem* operator*();
+ TQListViewItem *current() const;
+
+protected:
+ TQListViewItem *curr;
+ TQListView *listView;
+
+private:
+ TQListViewItemIteratorPrivate* d() const;
+ void init( int flags );
+ void addToListView();
+ void currentRemoved();
+ bool matchesFlags( const TQListViewItem* ) const;
+ bool testPair( TQListViewItemIterator::IteratorFlag, TQListViewItemIterator::IteratorFlag, bool ) const;
+ bool isChecked( const TQListViewItem* ) const;
+};
+
+#endif // TQT_NO_LISTVIEW
+
+#endif // TQLISTVIEW_H
diff --git a/tqtinterface/qt4/src/widgets/tqmainwindow.cpp b/tqtinterface/qt4/src/widgets/tqmainwindow.cpp
new file mode 100644
index 0000000..1921297
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqmainwindow.cpp
@@ -0,0 +1,2644 @@
+/****************************************************************************
+**
+** Implementation of TQMainWindow class
+**
+** Created : 980312
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmainwindow.h"
+#ifndef TQT_NO_MAINWINDOW
+
+#include "tqtimer.h"
+#include "tqlayout.h"
+#include "tqobjectlist.h"
+#include "tqintdict.h"
+#include "tqapplication.h"
+#include "tqptrlist.h"
+#include "tqmap.h"
+#include "tqcursor.h"
+#include "tqpainter.h"
+#include "tqmenubar.h"
+#include "tqpopupmenu.h"
+#include "tqtoolbar.h"
+#include "tqstatusbar.h"
+#include "tqscrollview.h"
+#include "tqtooltip.h"
+#include "tqdatetime.h"
+#include "tqwhatsthis.h"
+#include "tqbitmap.h"
+#include "tqdockarea.h"
+#include "tqstringlist.h"
+#include "tqstyle.h"
+#ifdef TQ_WS_MACX
+# include "tqt_mac.h"
+#endif
+
+class TQHideDock;
+class TQMainWindowLayout;
+
+class TQMainWindowPrivate
+{
+public:
+ TQMainWindowPrivate()
+ : mb(0), sb(0), ttg(0), mc(0), tll(0), mwl(0), ubp( FALSE ), utl( FALSE ),
+ justify( FALSE ), movable( TRUE ), opaque( FALSE ), dockMenu( TRUE )
+ {
+ docks.insert( TQt::DockTop, TRUE );
+ docks.insert( TQt::DockBottom, TRUE );
+ docks.insert( TQt::DockLeft, TRUE );
+ docks.insert( TQt::DockRight, TRUE );
+ docks.insert( TQt::DockMinimized, FALSE );
+ docks.insert( TQt::DockTornOff, TRUE );
+ }
+
+ ~TQMainWindowPrivate()
+ {
+ }
+
+#ifndef TQT_NO_MENUBAR
+ TQMenuBar * mb;
+#else
+ TQWidget * mb;
+#endif
+ TQStatusBar * sb;
+ TQToolTipGroup * ttg;
+
+ TQWidget * mc;
+
+ TQBoxLayout * tll;
+ TQMainWindowLayout * mwl;
+
+ uint ubp :1;
+ uint utl :1;
+ uint justify :1;
+ uint movable :1;
+ uint opaque :1;
+ uint dockMenu :1;
+
+ TQDockArea *topDock, *bottomDock, *leftDock, *rightDock;
+
+ TQPtrList<TQDockWindow> dockWindows;
+ TQMap<TQt::Dock, bool> docks;
+ TQStringList disabledDocks;
+ TQHideDock *hideDock;
+
+ TQGuardedPtr<TQPopupMenu> rmbMenu, tbMenu, dwMenu;
+ TQMap<TQDockWindow*, bool> appropriate;
+ TQMap<TQPopupMenu*, TQMainWindow::DockWindows> dockWindowModes;
+
+};
+
+
+/* TQMainWindowLayout, respects widthForHeight layouts (like the left
+ and right docks are)
+*/
+
+class TQMainWindowLayout : public TQLayout
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQMainWindowLayout( TQMainWindow *mw, TQLayout* tqparent = 0 );
+ ~TQMainWindowLayout() {}
+
+ void addItem( QLayoutItem * );
+ void setLeftDock( TQDockArea *l );
+ void setRightDock( TQDockArea *r );
+ void setCentralWidget( TQWidget *w );
+ bool hasHeightForWidth() const { return FALSE; }
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSize() const;
+ TQLayoutIterator iterator();
+ TQ_SPExpandData expandingDirections() const { return (Qt::Orientations)TQSizePolicy::BothDirections; }
+ void tqinvalidate() {}
+
+protected:
+ void setGeometry( const TQRect &r ) {
+ TQLayout::setGeometry( r );
+ layoutItems( r );
+ }
+
+private:
+ int layoutItems( const TQRect&, bool testonly = FALSE );
+ int extraPixels() const;
+
+ TQDockArea *left, *right;
+ TQWidget *central;
+ TQMainWindow *mainWindow;
+
+#ifdef USE_QT4
+
+ QLAYOUT_REQUIRED_METHOD_DECLARATIONS
+
+#endif // USE_QT4
+
+};
+
+/*!
+ \reimp
+*/
+int TQMainWindowLayout::count() const {
+ return 0;
+}
+
+/*!
+ \reimp
+*/
+TQLayoutItem* TQMainWindowLayout::itemAt(int index) const {
+ return 0;
+}
+
+/*!
+ \reimp
+*/
+TQLayoutItem* TQMainWindowLayout::takeAt(int index) {
+ return 0;
+}
+
+TQSize TQMainWindowLayout::tqsizeHint() const
+{
+ int w = 0;
+ int h = 0;
+
+ if ( left ) {
+ w += left->tqsizeHint().width();
+ h = TQMAX( h, left->tqsizeHint().height() );
+ }
+ if ( right ) {
+ w += right->tqsizeHint().width();
+ h = TQMAX( h, right->tqsizeHint().height() );
+ }
+ if ( central ) {
+ w += central->tqsizeHint().width();
+ int diff = extraPixels();
+ h = TQMAX( h, central->tqsizeHint().height() + diff );
+ }
+
+ return TQSize( w, h );
+}
+
+TQSize TQMainWindowLayout::tqminimumSize() const
+{
+ int w = 0;
+ int h = 0;
+
+ if ( left ) {
+ TQSize ms = left->tqminimumSizeHint().expandedTo( left->tqminimumSize() );
+ w += ms.width();
+ h = TQMAX( h, ms.height() );
+ }
+ if ( right ) {
+ TQSize ms = right->tqminimumSizeHint().expandedTo( right->tqminimumSize() );
+ w += ms.width();
+ h = TQMAX( h, ms.height() );
+ }
+ if ( central ) {
+ TQSize min = central->tqminimumSize().isNull() ?
+ central->tqminimumSizeHint() : central->tqminimumSize();
+ w += min.width();
+ int diff = extraPixels();
+ h = TQMAX( h, min.height() + diff );
+ }
+ return TQSize( w, h );
+}
+
+TQMainWindowLayout::TQMainWindowLayout( TQMainWindow *mw, TQLayout* tqparent )
+ : TQLayout( tqparent ), left( 0 ), right( 0 ), central( 0 )
+{
+ mainWindow = mw;
+}
+
+void TQMainWindowLayout::setLeftDock( TQDockArea *l )
+{
+ left = l;
+}
+
+void TQMainWindowLayout::setRightDock( TQDockArea *r )
+{
+ right = r;
+}
+
+void TQMainWindowLayout::setCentralWidget( TQWidget *w )
+{
+ central = w;
+}
+
+int TQMainWindowLayout::layoutItems( const TQRect &r, bool testonly )
+{
+ if ( !left && !central && !right )
+ return 0;
+
+ int wl = 0, wr = 0;
+ if ( left )
+ wl = ( (TQDockAreaLayout*)left->TQWidget::tqlayout() )->widthForHeight( r.height() );
+ if ( right )
+ wr = ( (TQDockAreaLayout*)right->TQWidget::tqlayout() )->widthForHeight( r.height() );
+ int w = r.width() - wr - wl;
+ if ( w < 0 )
+ w = 0;
+
+ int diff = extraPixels();
+ if ( !testonly ) {
+ TQRect g( tqgeometry() );
+ if ( left )
+ left->setGeometry( TQRect( g.x(), g.y() + diff, wl, r.height() - diff ) );
+ if ( right )
+ right->setGeometry( TQRect( g.x() + g.width() - wr, g.y() + diff, wr, r.height() - diff ) );
+ if ( central )
+ central->setGeometry( g.x() + wl, g.y() + diff, w, r.height() - diff );
+ }
+
+ w = wl + wr;
+ if ( central )
+ w += central->tqminimumSize().width();
+ return w;
+}
+
+int TQMainWindowLayout::extraPixels() const
+{
+ if ( mainWindow->d->topDock->isEmpty() &&
+ !(mainWindow->d->leftDock->isEmpty() &&
+ mainWindow->d->rightDock->isEmpty()) ) {
+ return 2;
+ } else {
+ return 0;
+ }
+}
+
+void TQMainWindowLayout::addItem( QLayoutItem * /* item */ )
+{
+}
+
+
+TQLayoutIterator TQMainWindowLayout::iterator()
+{
+ return 0;
+}
+
+
+/*
+ TQHideToolTip and TQHideDock - minimized dock
+*/
+
+#ifndef TQT_NO_TOOLTIP
+class TQHideToolTip : public TQToolTip
+{
+public:
+ TQHideToolTip( TQWidget *tqparent ) : TQToolTip( tqparent ) {}
+ ~TQHideToolTip() {}
+
+ virtual void maybeTip( const TQPoint &pos );
+};
+#endif
+
+
+class TQHideDock : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQHideDock( TQMainWindow *tqparent ) : TQWidget( tqparent, "qt_hide_dock" ) {
+ hide();
+ setFixedHeight( tqstyle().tqpixelMetric( TQStyle::PM_DockWindowHandleExtent,
+ this ) + 3 );
+ pressedHandle = -1;
+ pressed = FALSE;
+ setMouseTracking( TRUE );
+ win = tqparent;
+#ifndef TQT_NO_TOOLTIP
+ tip = new TQHideToolTip( this );
+#endif
+ }
+ ~TQHideDock()
+ {
+#ifndef TQT_NO_TOOLTIP
+ delete tip;
+#endif
+ }
+
+protected:
+ void paintEvent( TQPaintEvent *e ) {
+
+ if ( childrenListObject().isEmpty() )
+ return;
+
+ TQPainter p( this );
+ p.setClipRegion( e->rect() );
+ p.fillRect( e->rect(), tqcolorGroup().brush( TQColorGroup::Background ) );
+ int x = 0;
+ int i = -1;
+ TQObjectListIt it( childrenListObject() );
+ TQObject *o;
+ while ( ( o = it.current() ) ) {
+ ++it;
+ ++i;
+ TQDockWindow *dw = ::tqqt_cast<TQDockWindow*>(o);
+ if ( !dw || !dw->isVisible() )
+ continue;
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if ( i == pressedHandle )
+ flags |= TQStyle::Style_On;
+
+ tqstyle().tqdrawPrimitive( TQStyle::PE_DockWindowHandle, &p,
+ TQRect( x, 0, 30, 10 ), tqcolorGroup(),
+ flags );
+ x += 30;
+ }
+ }
+
+ void mousePressEvent( TQMouseEvent *e ) {
+ pressed = TRUE;
+ if ( childrenListObject().isEmpty() )
+ return;
+ mouseMoveEvent( e );
+ pressedHandle = -1;
+
+ if ( e->button() == Qt::RightButton && win->isDockMenuEnabled() ) {
+ // ### TODO: HideDock menu
+ } else {
+ mouseMoveEvent( e );
+ }
+ }
+
+ void mouseMoveEvent( TQMouseEvent *e ) {
+ if ( childrenListObject().isEmpty() )
+ return;
+ if ( !pressed )
+ return;
+ int x = 0;
+ int i = -1;
+ if ( e->y() >= 0 && e->y() <= height() ) {
+ TQObjectListIt it( childrenListObject() );
+ TQObject *o;
+ while ( ( o = it.current() ) ) {
+ ++it;
+ ++i;
+ TQDockWindow *dw = ::tqqt_cast<TQDockWindow*>(o);
+ if ( !dw || !dw->isVisible() )
+ continue;
+
+ if ( e->x() >= x && e->x() <= x + 30 ) {
+ int old = pressedHandle;
+ pressedHandle = i;
+ if ( pressedHandle != old )
+ tqrepaint( TRUE );
+ return;
+ }
+ x += 30;
+ }
+ }
+ int old = pressedHandle;
+ pressedHandle = -1;
+ if ( old != -1 )
+ tqrepaint( TRUE );
+ }
+
+ void mouseReleaseEvent( TQMouseEvent *e ) {
+ pressed = FALSE;
+ if ( pressedHandle == -1 )
+ return;
+ if ( childrenListObject().isEmpty() )
+ return;
+ if ( e->button() == Qt::LeftButton ) {
+ if ( e->y() >= 0 && e->y() <= height() ) {
+ TQObject *o = childrenListObject().at( pressedHandle );
+ TQDockWindow *dw = ::tqqt_cast<TQDockWindow*>(o);
+ if ( dw ) {
+ dw->show();
+ dw->dock();
+ }
+ }
+ }
+ pressedHandle = -1;
+ tqrepaint( FALSE );
+ }
+
+ bool eventFilter( TQObject *o, TQEvent *e ) {
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) || !o->isWidgetType() )
+ return TQWidget::eventFilter( o, e );
+ if ( e->type() == TQEvent::Hide ||
+ e->type() == TQEvent::Show ||
+ e->type() == TQEvent::ShowToParent )
+ updateState();
+ return TQWidget::eventFilter( o, e );
+ }
+
+protected slots:
+ void updateState() {
+ bool visible = TRUE;
+ if ( childrenListObject().isEmpty() ) {
+ visible = FALSE;
+ } else {
+ TQObjectListIt it( childrenListObject() );
+ TQObject *o;
+ while ( ( o = it.current() ) ) {
+ ++it;
+ TQDockWindow *dw = ::tqqt_cast<TQDockWindow*>(o);
+ if ( !dw )
+ continue;
+ if ( dw->isHidden() ) {
+ visible = FALSE;
+ continue;
+ }
+ if ( !dw->isVisible() )
+ continue;
+ visible = TRUE;
+ break;
+ }
+ }
+
+ if ( visible )
+ show();
+ else
+ hide();
+ win->triggerLayout( FALSE );
+ update();
+ }
+
+protected:
+ void childEvent( TQChildEvent *e ) {
+ TQWidget::childEvent( e );
+ if ( e->type() == TQEvent::ChildInserted )
+ e->child()->installEventFilter( this );
+ else
+ e->child()->removeEventFilter( this );
+ TQTimer::singleShot( 50, this, SLOT(updateState()) ); // Prevent crash due to show() calling childEvent() in an infinite recursion loop under certain conditions
+ }
+
+private:
+ TQMainWindow *win;
+ int pressedHandle;
+ bool pressed;
+#ifndef TQT_NO_TOOLTIP
+ TQHideToolTip *tip;
+ friend class TQHideToolTip;
+#endif
+};
+
+#ifndef TQT_NO_TOOLTIP
+void TQHideToolTip::maybeTip( const TQPoint &pos )
+{
+ if ( !parentWidget() )
+ return;
+ TQHideDock *dock = (TQHideDock*)parentWidget();
+
+ if ( dock->childrenListObject().isEmpty() )
+ return;
+ TQObjectListIt it( dock->childrenListObject() );
+ TQObject *o;
+ int x = 0;
+ while ( ( o = it.current() ) ) {
+ ++it;
+ TQDockWindow *dw = ::tqqt_cast<TQDockWindow*>(o);
+ if ( !dw || !dw->isVisible() )
+ continue;
+
+ if ( pos.x() >= x && pos.x() <= x + 30 ) {
+ TQDockWindow *dw = (TQDockWindow*)o;
+ if ( !dw->caption().isEmpty() )
+ tip( TQRect( x, 0, 30, dock->height() ), dw->caption() );
+ return;
+ }
+ x += 30;
+ }
+}
+#endif
+
+/*!
+ \class TQMainWindow tqmainwindow.h
+ \brief The TQMainWindow class provides a main application window,
+ with a menu bar, dock windows (e.g. for toolbars), and a status
+ bar.
+
+ \ingroup application
+ \mainclass
+
+ Main windows are most often used to provide menus, toolbars and a
+ status bar around a large central widget, such as a text edit,
+ drawing canvas or TQWorkspace (for MDI applications). TQMainWindow
+ is usually subclassed since this makes it easier to encapsulate
+ the central widget, menus and toolbars as well as the window's
+ state. Subclassing makes it possible to create the Q_SLOTS that are
+ called when the user clicks menu items or toolbar buttons. You can
+ also create main windows using \link designer-manual.book TQt
+ Designer\endlink. We'll briefly review adding menu items and
+ toolbar buttons then describe the facilities of TQMainWindow
+ itself.
+
+ \code
+ TQMainWindow *mw = new TQMainWindow;
+ TQTextEdit *edit = new TQTextEdit( mw, "editor" );
+ edit->setFocus();
+ mw->setCaption( "Main Window" );
+ mw->setCentralWidget( edit );
+ mw->show();
+ \endcode
+
+ TQMainWindows may be created in their own right as shown above.
+ The central widget is set with setCentralWidget(). Popup menus can
+ be added to the default menu bar, widgets can be added to the
+ status bar, toolbars and dock windows can be added to any of the
+ dock areas.
+
+ \quotefile application/main.cpp
+ \skipto ApplicationWindow
+ \printuntil show
+
+ In the extract above ApplicationWindow is a subclass of
+ TQMainWindow that we must write for ourselves; this is the usual
+ approach to using TQMainWindow. (The source for the extracts in
+ this description are taken from \l application/main.cpp, \l
+ application/application.cpp, \l action/main.cpp, and \l
+ action/application.cpp )
+
+ When subclassing we add the menu items and toolbars in the
+ subclass's constructor. If we've created a TQMainWindow instance
+ directly we can add menu items and toolbars just as easily by
+ passing the TQMainWindow instance as the tqparent instead of the \e
+ this pointer.
+
+ \quotefile application/application.cpp
+ \skipto help = new
+ \printuntil about
+
+ Here we've added a new menu with one menu item. The menu has been
+ inserted into the menu bar that TQMainWindow provides by default
+ and which is accessible through the menuBar() function. The slot
+ will be called when the menu item is clicked.
+
+ \quotefile application/application.cpp
+ \skipto fileTools
+ \printuntil setLabel
+ \skipto TQToolButton
+ \printuntil open file
+
+ This extract shows the creation of a toolbar with one toolbar
+ button. TQMainWindow supplies four dock areas for toolbars. When a
+ toolbar is created as a child of a TQMainWindow (or derived class)
+ instance it will be placed in a dock area (the \c Top dock area by
+ default). The slot will be called when the toolbar button is
+ clicked. Any dock window can be added to a dock area either using
+ addDockWindow(), or by creating a dock window with the TQMainWindow
+ as the tqparent.
+
+ \quotefile application/application.cpp
+ \skipto editor
+ \printuntil statusBar
+
+ Having created the menus and toolbar we create an instance of the
+ large central widget, give it the focus and set it as the main
+ window's central widget. In the example we've also set the status
+ bar, accessed via the statusBar() function, to an initial message
+ which will be displayed for two seconds. Note that you can add
+ additional widgets to the status bar, for example labels, to show
+ further status information. See the TQStatusBar documentation for
+ details, particularly the addWidget() function.
+
+ Often we want to synchronize a toolbar button with a menu item.
+ For example, if the user clicks a 'bold' toolbar button we want
+ the 'bold' menu item to be checked. This synchronization can be
+ achieved automatically by creating actions and adding the actions
+ to the toolbar and menu.
+
+ \quotefile action/application.cpp
+ \skipto TQAction * fileOpen
+ \printline
+ \skipto fileOpenAction
+ \printuntil choose
+
+ Here we create an action with an icon which will be used in any
+ menu and toolbar that the action is added to. We've also given the
+ action a menu name, '\&Open', and a keyboard shortcut. The
+ connection that we have made will be used when the user clicks
+ either the menu item \e or the toolbar button.
+
+ \quotefile action/application.cpp
+ \skipto TQPopupMenu * file
+ \printuntil menuBar
+ \skipto fileOpen
+ \printline
+
+ The extract above shows the creation of a popup menu. We add the
+ menu to the TQMainWindow's menu bar and add our action.
+
+ \quotefile action/application.cpp
+ \skipto TQToolBar * fileTool
+ \printuntil OpenAction
+
+ Here we create a new toolbar as a child of the TQMainWindow and add
+ our action to the toolbar.
+
+ We'll now explore the functionality offered by TQMainWindow.
+
+ The main window will take care of the dock areas, and the tqgeometry
+ of the central widget, but all other aspects of the central widget
+ are left to you. TQMainWindow automatically detects the creation of
+ a menu bar or status bar if you specify the TQMainWindow as tqparent,
+ or you can use the provided menuBar() and statusBar() functions.
+ The functions menuBar() and statusBar() create a suitable widget
+ if one doesn't exist, and update the window's tqlayout to make
+ space.
+
+ TQMainWindow provides a TQToolTipGroup connected to the status bar.
+ The function toolTipGroup() provides access to the default
+ TQToolTipGroup. It isn't possible to set a different tool tip
+ group.
+
+ New dock windows and toolbars can be added to a TQMainWindow using
+ addDockWindow(). Dock windows can be moved using moveDockWindow()
+ and removed with removeDockWindow(). TQMainWindow allows default
+ dock window (toolbar) docking in all its dock areas (\c Top, \c
+ Left, \c Right, \c Bottom). You can use setDockEnabled() to
+ enable and disable docking areas for dock windows. When adding or
+ moving dock windows you can specify their 'edge' (dock area). The
+ currently available edges are: \c Top, \c Left, \c Right, \c
+ Bottom, \c Minimized (effectively a 'hidden' dock area) and \c
+ TornOff (floating). See \l TQt::Dock for an explanation of these
+ areas. Note that the *ToolBar functions are included for backward
+ compatibility; all new code should use the *DockWindow functions.
+ TQToolbar is a subclass of TQDockWindow so all functions that work
+ with dock windows work on toolbars in the same way.
+
+ \target dwm
+ If the user clicks the close button, then the dock window is
+ hidden. A dock window can be hidden or unhidden by the user by
+ right clicking a dock area and clicking the name of the relevant
+ dock window on the pop up dock window menu. This menu lists the
+ names of every dock window; visible dock windows have a tick
+ beside their names. The dock window menu is created automatically
+ as required by createDockWindowMenu(). Since it may not always be
+ appropriate for a dock window to appear on this menu the
+ setAppropriate() function is used to inform the main window
+ whether or not the dock window menu should include a particular
+ dock window. Double clicking a dock window handle (usually on the
+ left-hand side of the dock window) undocks (floats) the dock
+ window. Double clicking a floating dock window's titlebar will
+ dock the floating dock window. (See also
+ \l{TQMainWindow::DockWindows}.)
+
+ Some functions change the appearance of a TQMainWindow globally:
+ \list
+ \i TQDockWindow::setHorizontalStretchable() and
+ TQDockWindow::setVerticalStretchable() are used to make specific dock
+ windows or toolbars stretchable.
+ \i setUsesBigPixmaps() is used to set whether tool buttons should
+ draw small or large pixmaps (see TQIconSet for more information).
+ \i setUsesTextLabel() is used to set whether tool buttons
+ should display a textual label in addition to pixmaps
+ (see TQToolButton for more information).
+ \endlist
+
+ The user can drag dock windows into any enabled docking area. Dock
+ windows can also be dragged \e within a docking area, for example
+ to rearrange the order of some toolbars. Dock windows can also be
+ dragged outside any docking area (undocked or 'floated'). Being
+ able to drag dock windows can be enabled (the default) and
+ disabled using setDockWindowsMovable().
+
+ The \c Minimized edge is a hidden dock area. If this dock area is
+ enabled the user can hide (minimize) a dock window or show (restore)
+ a minimized dock window by clicking the dock window handle. If the
+ user hovers the mouse cursor over one of the handles, the caption of
+ the dock window is displayed in a tool tip (see
+ TQDockWindow::caption() or TQToolBar::label()), so if you enable the
+ \c Minimized dock area, it is best to specify a meaningful caption
+ or label for each dock window. To minimize a dock window
+ programmatically use moveDockWindow() with an edge of \c Minimized.
+
+ Dock windows are moved transparently by default, i.e. during the
+ drag an outline rectangle is drawn on the screen representing the
+ position of the dock window as it moves. If you want the dock
+ window to be shown normally whilst it is moved use
+ setOpaqueMoving().
+
+ The location of a dock window, i.e. its dock area and position
+ within the dock area, can be determined by calling getLocation().
+ Movable dock windows can be lined up to minimize wasted space with
+ lineUpDockWindows(). Pointers to the dock areas are available from
+ topDock(), leftDock(), rightDock() and bottomDock(). A customize
+ menu item is added to the pop up dock window menu if
+ isCustomizable() returns TRUE; it returns FALSE by default.
+ Reimplement isCustomizable() and customize() if you want to offer
+ this extra menu item, for example, to allow the user to change
+ settings relating to the main window and its toolbars and dock
+ windows.
+
+ The main window's menu bar is fixed (at the top) by default. If
+ you want a movable menu bar, create a TQMenuBar as a stretchable
+ widget inside its own movable dock window and restrict this dock
+ window to only live within the \c Top or \c Bottom dock:
+
+ \code
+ TQToolBar *tb = new TQToolBar( this );
+ addDockWindow( tb, tr( "Menubar" ), Top, FALSE );
+ TQMenuBar *mb = new TQMenuBar( tb );
+ mb->setFrameStyle( TQFrame::NoFrame );
+ tb->setStretchableWidget( mb );
+ setDockEnabled( tb, Left, FALSE );
+ setDockEnabled( tb, Right, FALSE );
+ \endcode
+
+ An application with multiple dock windows can choose to save the
+ current dock window tqlayout in order to restore it later, e.g. in
+ the next session. You can do this by using the streaming operators
+ for TQMainWindow.
+
+ To save the tqlayout and positions of all the dock windows do this:
+
+ \code
+ TQFile file( filename );
+ if ( file.open( IO_WriteOnly ) ) {
+ TQTextStream stream( &file );
+ stream << *mainWindow;
+ file.close();
+ }
+ \endcode
+
+ To restore the dock window positions and sizes (normally when the
+ application is next started), do following:
+
+ \code
+ TQFile file( filename );
+ if ( file.open( IO_ReadOnly ) ) {
+ TQTextStream stream( &file );
+ stream >> *mainWindow;
+ file.close();
+ }
+ \endcode
+
+ The TQSettings class can be used in conjunction with the streaming
+ operators to store the application's settings.
+
+ TQMainWindow's management of dock windows and toolbars is done
+ transparently behind-the-scenes by TQDockArea.
+
+ For multi-document interfaces (MDI), use a TQWorkspace as the
+ central widget.
+
+ Adding dock windows, e.g. toolbars, to TQMainWindow's dock areas is
+ straightforward. If the supplied dock areas are not sufficient for
+ your application we suggest that you create a TQWidget subclass and
+ add your own dock areas (see \l TQDockArea) to the subclass since
+ TQMainWindow provides functionality specific to the standard dock
+ areas it provides.
+
+ <img src=qmainwindow-m.png> <img src=qmainwindow-w.png>
+
+ \sa TQToolBar TQDockWindow TQStatusBar TQAction TQMenuBar TQPopupMenu TQToolTipGroup TQDialog
+*/
+
+/*! \enum TQt::ToolBarDock
+ \internal
+*/
+
+/*!
+ \enum TQt::Dock
+
+ Each dock window can be in one of the following positions:
+
+ \value DockTop above the central widget, below the menu bar.
+
+ \value DockBottom below the central widget, above the status bar.
+
+ \value DockLeft to the left of the central widget.
+
+ \value DockRight to the right of the central widget.
+
+ \value DockMinimized the dock window is not shown (this is
+ effectively a 'hidden' dock area); the handles of all minimized
+ dock windows are drawn in one row below the menu bar.
+
+ \value DockTornOff the dock window floats as its own top level
+ window which always stays on top of the main window.
+
+ \value DockUnmanaged not managed by a TQMainWindow.
+*/
+
+/*!
+ \enum TQMainWindow::DockWindows
+
+ Right-clicking a dock area will pop-up the dock window menu
+ (createDockWindowMenu() is called automatically). When called in
+ code you can specify what items should appear on the menu with
+ this enum.
+
+ \value OnlyToolBars The menu will list all the toolbars, but not
+ any other dock windows.
+
+ \value NoToolBars The menu will list dock windows but not
+ toolbars.
+
+ \value AllDockWindows The menu will list all toolbars and other
+ dock windows. (This is the default.)
+*/
+
+/*!
+ \obsolete
+ \fn void TQMainWindow::addToolBar( TQDockWindow *, Dock = Top, bool newLine = FALSE );
+*/
+
+/*!
+ \obsolete
+ \overload void TQMainWindow::addToolBar( TQDockWindow *, const TQString &label, Dock = Top, bool newLine = FALSE );
+*/
+
+/*!
+ \obsolete
+ \fn void TQMainWindow::moveToolBar( TQDockWindow *, Dock = Top );
+*/
+
+/*!
+ \obsolete
+ \overload void TQMainWindow::moveToolBar( TQDockWindow *, Dock, bool nl, int index, int extraOffset = -1 );
+*/
+
+/*!
+ \obsolete
+ \fn void TQMainWindow::removeToolBar( TQDockWindow * );
+*/
+
+/*!
+ \obsolete
+ \fn void TQMainWindow::lineUpToolBars( bool keepNewLines = FALSE );
+*/
+
+/*!
+ \obsolete
+ \fn void TQMainWindow::toolBarPositionChanged( TQToolBar * );
+*/
+
+/*!
+ \obsolete
+ \fn bool TQMainWindow::toolBarsMovable() const
+*/
+
+/*!
+ \obsolete
+ \fn void TQMainWindow::setToolBarsMovable( bool )
+*/
+
+/*!
+ Constructs an empty main window. The \a tqparent, \a name and widget
+ flags \a f, are passed on to the TQWidget constructor.
+
+ By default, the widget flags are set to \c WType_TopLevel rather
+ than 0 as they are with TQWidget. If you don't want your
+ TQMainWindow to be a top level widget then you will need to set \a
+ f to 0.
+*/
+
+TQMainWindow::TQMainWindow( TQWidget * tqparent, const char * name, WFlags f )
+ : TQWidget( tqparent, name, f )
+{
+ d = new TQMainWindowPrivate;
+#ifdef TQ_WS_MACX
+ d->opaque = TRUE;
+#else
+ d->opaque = FALSE;
+#endif
+ installEventFilter( this );
+ d->topDock = new TQDockArea( Qt::Horizontal, TQDockArea::Normal, this, "qt_top_dock" );
+ d->topDock->installEventFilter( this );
+ d->bottomDock = new TQDockArea( Qt::Horizontal, TQDockArea::Reverse, this, "qt_bottom_dock" );
+ d->bottomDock->installEventFilter( this );
+ d->leftDock = new TQDockArea( Qt::Vertical, TQDockArea::Normal, this, "qt_left_dock" );
+ d->leftDock->installEventFilter( this );
+ d->rightDock = new TQDockArea( Qt::Vertical, TQDockArea::Reverse, this, "qt_right_dock" );
+ d->rightDock->installEventFilter( this );
+ d->hideDock = new TQHideDock( this );
+}
+
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQMainWindow::~TQMainWindow()
+{
+ delete tqlayout();
+ delete d;
+}
+
+#ifndef TQT_NO_MENUBAR
+/*!
+ Sets this main window to use the menu bar \a newMenuBar.
+
+ The existing menu bar (if any) is deleted along with its contents.
+
+ \sa menuBar()
+*/
+
+void TQMainWindow::setMenuBar( TQMenuBar * newMenuBar )
+{
+ if ( !newMenuBar )
+ return;
+ if ( d->mb )
+ delete d->mb;
+ d->mb = newMenuBar;
+ d->mb->installEventFilter( this );
+ triggerLayout();
+}
+
+
+/*!
+ Returns the menu bar for this window.
+
+ If there isn't one, then menuBar() creates an empty menu bar.
+
+ \sa statusBar()
+*/
+
+TQMenuBar * TQMainWindow::menuBar() const
+{
+ if ( d->mb )
+ return d->mb;
+
+ TQObjectList * l
+ = ((TQObject*)this)->queryList( "TQMenuBar", 0, FALSE, FALSE );
+ TQMenuBar * b;
+ if ( l && l->count() ) {
+ b = (TQMenuBar *)l->first();
+ } else {
+ b = new TQMenuBar( (TQMainWindow *)this, "automatic menu bar" );
+ b->show();
+ }
+ delete l;
+ d->mb = b;
+ d->mb->installEventFilter( const_cast<TQT_BASE_OBJECT_NAME*>(static_cast<const TQT_BASE_OBJECT_NAME*>(this)) );
+ ((TQMainWindow *)this)->triggerLayout();
+ return b;
+}
+#endif // TQT_NO_MENUBAR
+
+/*!
+ Sets this main window to use the status bar \a newtqStatusBar.
+
+ The existing status bar (if any) is deleted along with its
+ contents.
+
+ Note that \a newtqStatusBar \e must be a child of this main window,
+ and that it is not automatically displayed. If you call this
+ function after show(), you will probably also need to call
+ newtqStatusBar->show().
+
+ \sa setMenuBar() statusBar()
+*/
+
+void TQMainWindow::setqStatusBar( TQStatusBar * newtqStatusBar )
+{
+ if ( !newtqStatusBar || newtqStatusBar == d->sb )
+ return;
+ if ( d->sb )
+ delete d->sb;
+ d->sb = newtqStatusBar;
+#ifndef TQT_NO_TOOLTIP
+ // ### this code can cause unnecessary creation of a tool tip group
+ connect( toolTipGroup(), TQT_SIGNAL(showTip(const TQString&)),
+ d->sb, TQT_SLOT(message(const TQString&)) );
+ connect( toolTipGroup(), TQT_SIGNAL(removeTip()),
+ d->sb, TQT_SLOT(clear()) );
+#endif
+ d->sb->installEventFilter( this );
+ triggerLayout();
+}
+
+
+/*!
+ Returns this main window's status bar. If there isn't one,
+ statusBar() creates an empty status bar, and if necessary a tool
+ tip group too.
+
+ \sa menuBar() toolTipGroup()
+*/
+
+TQStatusBar * TQMainWindow::statusBar() const
+{
+ if ( d->sb )
+ return d->sb;
+
+ TQObjectList * l
+ = ((TQObject*)this)->queryList( "TQStatusBar", 0, FALSE, FALSE );
+ TQStatusBar * s;
+ if ( l && l->count() ) {
+ s = (TQStatusBar *)l->first();
+ } else {
+ s = new TQStatusBar( (TQMainWindow *)this, "automatic status bar" );
+ s->show();
+ }
+ delete l;
+ ((TQMainWindow *)this)->setqStatusBar( s );
+ ((TQMainWindow *)this)->triggerLayout( TRUE );
+ return s;
+}
+
+
+#ifndef TQT_NO_TOOLTIP
+/*!
+ Sets this main window to use the tool tip group \a
+ newToolTipGroup.
+
+ The existing tool tip group (if any) is deleted along with its
+ contents. All the tool tips connected to it lose the ability to
+ display the group texts.
+
+ \sa menuBar() toolTipGroup()
+*/
+
+void TQMainWindow::setToolTipGroup( TQToolTipGroup * newToolTipGroup )
+{
+ if ( !newToolTipGroup || newToolTipGroup == d->ttg )
+ return;
+ if ( d->ttg )
+ delete d->ttg;
+ d->ttg = newToolTipGroup;
+
+ connect( toolTipGroup(), TQT_SIGNAL(showTip(const TQString&)),
+ statusBar(), TQT_SLOT(message(const TQString&)) );
+ connect( toolTipGroup(), TQT_SIGNAL(removeTip()),
+ statusBar(), TQT_SLOT(clear()) );
+}
+
+
+/*!
+ Returns this main window's tool tip group. If there isn't one,
+ toolTipGroup() creates an empty tool tip group.
+
+ \sa menuBar() statusBar()
+*/
+
+TQToolTipGroup * TQMainWindow::toolTipGroup() const
+{
+ if ( d->ttg )
+ return d->ttg;
+
+ TQToolTipGroup * t = new TQToolTipGroup( TQT_TQOBJECT((TQMainWindow*)this),
+ "automatic tool tip group" );
+ ((TQMainWindowPrivate*)d)->ttg = t;
+ return t;
+}
+#endif
+
+
+/*!
+ If \a enable is TRUE then users can dock windows in the \a dock
+ area. If \a enable is FALSE users cannot dock windows in the \a
+ dock dock area.
+
+ Users can dock (drag) dock windows into any enabled dock area.
+*/
+
+void TQMainWindow::setDockEnabled( TQt::Dock dock, bool enable )
+{
+ d->docks.tqreplace( dock, enable );
+}
+
+
+/*!
+ Returns TRUE if the \a dock dock area is enabled, i.e. it can
+ accept user dragged dock windows; otherwise returns FALSE.
+
+ \sa setDockEnabled()
+*/
+
+bool TQMainWindow::isDockEnabled( TQt::Dock dock ) const
+{
+ return d->docks[ dock ];
+}
+
+/*!
+ \overload
+
+ Returns TRUE if dock area \a area is enabled, i.e. it can accept
+ user dragged dock windows; otherwise returns FALSE.
+
+ \sa setDockEnabled()
+*/
+
+bool TQMainWindow::isDockEnabled( TQDockArea *area ) const
+{
+
+ if ( area == d->leftDock )
+ return d->docks[ TQt::DockLeft ];
+ if ( area == d->rightDock )
+ return d->docks[ TQt::DockRight ];
+ if ( area == d->topDock )
+ return d->docks[ TQt::DockTop ];
+ if ( area == d->bottomDock )
+ return d->docks[ TQt::DockBottom ];
+ return FALSE;
+}
+
+/*!
+ \overload
+
+ If \a enable is TRUE then users can dock the \a dw dock window in
+ the \a dock area. If \a enable is FALSE users cannot dock the \a
+ dw dock window in the \a dock area.
+
+ In general users can dock (drag) dock windows into any enabled
+ dock area. Using this function particular dock areas can be
+ enabled (or disabled) as docking points for particular dock
+ windows.
+*/
+
+
+void TQMainWindow::setDockEnabled( TQDockWindow *dw, TQt::Dock dock, bool enable )
+{
+ if ( d->dockWindows.tqfind( dw ) == -1 ) {
+ d->dockWindows.append( dw );
+ connect( dw, TQT_SIGNAL( placeChanged(TQDockWindow::Place) ),
+ this, TQT_SLOT( slotPlaceChanged() ) );
+ }
+ TQString s;
+ s.sprintf( "%p_%d", (void*)dw, (int)dock );
+ if ( enable )
+ d->disabledDocks.remove( s );
+ else if ( d->disabledDocks.tqfind( s ) == d->disabledDocks.end() )
+ d->disabledDocks << s;
+ switch ( dock ) {
+ case TQt::DockTop:
+ topDock()->setAcceptDockWindow( dw, enable );
+ break;
+ case TQt::DockLeft:
+ leftDock()->setAcceptDockWindow( dw, enable );
+ break;
+ case TQt::DockRight:
+ rightDock()->setAcceptDockWindow( dw, enable );
+ break;
+ case TQt::DockBottom:
+ bottomDock()->setAcceptDockWindow( dw, enable );
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ \overload
+
+ Returns TRUE if dock area \a area is enabled for the dock window
+ \a dw; otherwise returns FALSE.
+
+ \sa setDockEnabled()
+*/
+
+bool TQMainWindow::isDockEnabled( TQDockWindow *dw, TQDockArea *area ) const
+{
+ if ( !isDockEnabled( area ) )
+ return FALSE;
+ TQt::Dock dock;
+ if ( area == d->leftDock )
+ dock = TQt::DockLeft;
+ else if ( area == d->rightDock )
+ dock = TQt::DockRight;
+ else if ( area == d->topDock )
+ dock = TQt::DockTop;
+ else if ( area == d->bottomDock )
+ dock = TQt::DockBottom;
+ else
+ return FALSE;
+ return isDockEnabled( dw, dock );
+}
+
+/*!
+ \overload
+
+ Returns TRUE if dock area \a dock is enabled for the dock window
+ \a tb; otherwise returns FALSE.
+
+ \sa setDockEnabled()
+*/
+
+bool TQMainWindow::isDockEnabled( TQDockWindow *tb, TQt::Dock dock ) const
+{
+ if ( !isDockEnabled( dock ) )
+ return FALSE;
+ TQString s;
+ s.sprintf( "%p_%d", (void*)tb, (int)dock );
+ return d->disabledDocks.tqfind( s ) == d->disabledDocks.end();
+}
+
+
+
+/*!
+ Adds \a dockWindow to the \a edge dock area.
+
+ If \a newLine is FALSE (the default) then the \a dockWindow is
+ added at the end of the \a edge. For vertical edges the end is at
+ the bottom, for horizontal edges (including \c Minimized) the end
+ is at the right. If \a newLine is TRUE a new line of dock windows
+ is started with \a dockWindow as the first (left-most and
+ top-most) dock window.
+
+ If \a dockWindow is managed by another main window, it is first
+ removed from that window.
+*/
+
+void TQMainWindow::addDockWindow( TQDockWindow *dockWindow,
+ TQt::Dock edge, bool newLine )
+{
+#ifdef TQ_WS_MAC
+ if(isTopLevel() && edge == DockTop)
+ ChangeWindowAttributes((WindowPtr)handle(), kWindowToolbarButtonAttribute, 0);
+#endif
+ moveDockWindow( dockWindow, edge );
+ dockWindow->setNewLine( newLine );
+ if ( d->dockWindows.tqfind( dockWindow ) == -1 ) {
+ d->dockWindows.append( dockWindow );
+ connect( dockWindow, TQT_SIGNAL( placeChanged(TQDockWindow::Place) ),
+ this, TQT_SLOT( slotPlaceChanged() ) );
+ dockWindow->installEventFilter( this );
+ }
+ dockWindow->setOpaqueMoving( d->opaque );
+}
+
+
+/*!
+ \overload
+
+ Adds \a dockWindow to the dock area with label \a label.
+
+ If \a newLine is FALSE (the default) the \a dockWindow is added at
+ the end of the \a edge. For vertical edges the end is at the
+ bottom, for horizontal edges (including \c Minimized) the end is
+ at the right. If \a newLine is TRUE a new line of dock windows is
+ started with \a dockWindow as the first (left-most and top-most)
+ dock window.
+
+ If \a dockWindow is managed by another main window, it is first
+ removed from that window.
+*/
+
+void TQMainWindow::addDockWindow( TQDockWindow * dockWindow, const TQString &label,
+ TQt::Dock edge, bool newLine )
+{
+ addDockWindow( dockWindow, edge, newLine );
+#ifndef TQT_NO_TOOLBAR
+ TQToolBar *tb = ::tqqt_cast<TQToolBar*>(dockWindow);
+ if ( tb )
+ tb->setLabel( label );
+#endif
+}
+
+/*!
+ Moves \a dockWindow to the end of the \a edge.
+
+ For vertical edges the end is at the bottom, for horizontal edges
+ (including \c Minimized) the end is at the right.
+
+ If \a dockWindow is managed by another main window, it is first
+ removed from that window.
+*/
+
+void TQMainWindow::moveDockWindow( TQDockWindow * dockWindow, TQt::Dock edge )
+{
+ Qt::Orientation oo = dockWindow->orientation();
+ switch ( edge ) {
+ case TQt::DockTop:
+ if ( dockWindow->area() != d->topDock )
+ dockWindow->removeFromDock( FALSE );
+ d->topDock->moveDockWindow( dockWindow );
+ emit dockWindowPositionChanged( dockWindow );
+ break;
+ case TQt::DockBottom:
+ if ( dockWindow->area() != d->bottomDock )
+ dockWindow->removeFromDock( FALSE );
+ d->bottomDock->moveDockWindow( dockWindow );
+ emit dockWindowPositionChanged( dockWindow );
+ break;
+ case TQt::DockRight:
+ if ( dockWindow->area() != d->rightDock )
+ dockWindow->removeFromDock( FALSE );
+ d->rightDock->moveDockWindow( dockWindow );
+ emit dockWindowPositionChanged( dockWindow );
+ break;
+ case TQt::DockLeft:
+ if ( dockWindow->area() != d->leftDock )
+ dockWindow->removeFromDock( FALSE );
+ d->leftDock->moveDockWindow( dockWindow );
+ emit dockWindowPositionChanged( dockWindow );
+ break;
+ case TQt::DockTornOff:
+ dockWindow->undock();
+ break;
+ case TQt::DockMinimized:
+ dockWindow->undock( d->hideDock );
+ break;
+ case TQt::DockUnmanaged:
+ break;
+ }
+
+ if ( oo != dockWindow->orientation() )
+ dockWindow->setOrientation( dockWindow->orientation() );
+}
+
+/*!
+ \overload
+
+ Moves \a dockWindow to position \a index within the \a edge dock
+ area.
+
+ Any dock windows with positions \a index or higher have their
+ position number incremented and any of these on the same line are
+ moved right (down for vertical dock areas) to make room.
+
+ If \a nl is TRUE, a new dock window line is created below the line
+ in which the moved dock window appears and the moved dock window,
+ with any others with higher positions on the same line, is moved
+ to this new line.
+
+ The \a extraOffset is the space to put between the left side of
+ the dock area (top side for vertical dock areas) and the dock
+ window. (This is mostly used for restoring dock windows to the
+ positions the user has dragged them to.)
+
+ If \a dockWindow is managed by another main window, it is first
+ removed from that window.
+*/
+
+void TQMainWindow::moveDockWindow( TQDockWindow * dockWindow, TQt::Dock edge, bool nl, int index, int extraOffset )
+{
+ Qt::Orientation oo = dockWindow->orientation();
+
+ dockWindow->setNewLine( nl );
+ dockWindow->setOffset( extraOffset );
+ switch ( edge ) {
+ case TQt::DockTop:
+ if ( dockWindow->area() != d->topDock )
+ dockWindow->removeFromDock( FALSE );
+ d->topDock->moveDockWindow( dockWindow, index );
+ break;
+ case TQt::DockBottom:
+ if ( dockWindow->area() != d->bottomDock )
+ dockWindow->removeFromDock( FALSE );
+ d->bottomDock->moveDockWindow( dockWindow, index );
+ break;
+ case TQt::DockRight:
+ if ( dockWindow->area() != d->rightDock )
+ dockWindow->removeFromDock( FALSE );
+ d->rightDock->moveDockWindow( dockWindow, index );
+ break;
+ case TQt::DockLeft:
+ if ( dockWindow->area() != d->leftDock )
+ dockWindow->removeFromDock( FALSE );
+ d->leftDock->moveDockWindow( dockWindow, index );
+ break;
+ case TQt::DockTornOff:
+ dockWindow->undock();
+ break;
+ case TQt::DockMinimized:
+ dockWindow->undock( d->hideDock );
+ break;
+ case TQt::DockUnmanaged:
+ break;
+ }
+
+ if ( oo != dockWindow->orientation() )
+ dockWindow->setOrientation( dockWindow->orientation() );
+}
+
+/*!
+ Removes \a dockWindow from the main window's docking area,
+ provided \a dockWindow is non-null and managed by this main
+ window.
+*/
+
+void TQMainWindow::removeDockWindow( TQDockWindow * dockWindow )
+{
+#ifdef TQ_WS_MAC
+ if(isTopLevel() && dockWindow->area() == topDock() && !dockWindows( DockTop ).count())
+ ChangeWindowAttributes((WindowPtr)handle(), 0, kWindowToolbarButtonAttribute);
+#endif
+
+ dockWindow->hide();
+ d->dockWindows.removeRef( dockWindow );
+ disconnect( dockWindow, TQT_SIGNAL( placeChanged(TQDockWindow::Place) ),
+ this, TQT_SLOT( slotPlaceChanged() ) );
+ dockWindow->removeEventFilter( this );
+}
+
+/*!
+ Sets up the tqgeometry management of the window. It is called
+ automatically when needed, so you shouldn't need to call it.
+*/
+
+void TQMainWindow::setUpLayout()
+{
+#ifndef TQT_NO_MENUBAR
+ if ( !d->mb ) {
+ // slightly evil hack here. reconsider this
+ TQObjectList * l
+ = ((TQObject*)this)->queryList( "TQMenuBar", 0, FALSE, FALSE );
+ if ( l && l->count() )
+ d->mb = menuBar();
+ delete l;
+ }
+#endif
+ if ( !d->sb ) {
+ // as above.
+ TQObjectList * l
+ = ((TQObject*)this)->queryList( "TQStatusBar", 0, FALSE, FALSE );
+ if ( l && l->count() )
+ d->sb = statusBar();
+ delete l;
+ }
+
+ if (!d->tll) {
+ d->tll = new TQBoxLayout( this, TQBoxLayout::Down );
+ d->tll->setResizeMode( tqminimumSize().isNull() ? TQLayout::Minimum : TQLayout::FreeResize );
+ } else {
+ d->tll->setMenuBar( 0 );
+ TQLayoutIterator it = d->tll->iterator();
+ TQLayoutItem *item;
+ while ( (item = it.takeCurrent()) )
+ delete item;
+ }
+
+#ifndef TQT_NO_MENUBAR
+ if ( d->mb && d->mb->isVisibleTo( this ) ) {
+ d->tll->setMenuBar( d->mb );
+ if (tqstyle().tqstyleHint(TQStyle::SH_MainWindow_SpaceBelowMenuBar, this))
+ d->tll->addSpacing( d->movable ? 1 : 2 );
+ }
+#endif
+
+ d->tll->addWidget( d->hideDock );
+ if(d->topDock->parentWidget() == this)
+ d->tll->addWidget( d->topDock );
+
+ TQMainWindowLayout *mwl = new TQMainWindowLayout( this, d->tll );
+ d->tll->setStretchFactor( mwl, 1 );
+
+ if(d->leftDock->parentWidget() == this)
+ mwl->setLeftDock( d->leftDock );
+ if ( centralWidget() )
+ mwl->setCentralWidget( centralWidget() );
+ if(d->rightDock->parentWidget() == this)
+ mwl->setRightDock( d->rightDock );
+ d->mwl = mwl;
+
+ if(d->bottomDock->parentWidget() == this)
+ d->tll->addWidget( d->bottomDock );
+
+ if ( d->sb && d->sb->parentWidget() == this) {
+ d->tll->addWidget( d->sb, 0 );
+ // make the sb stay on top of tool bars if there isn't enough space
+ d->sb->raise();
+ }
+}
+
+/*! \reimp */
+void TQMainWindow::show()
+{
+ if ( !d->tll )
+ setUpLayout();
+
+ // show all floating dock windows not explicitly hidden
+ if (!isVisible()) {
+ TQPtrListIterator<TQDockWindow> it(d->dockWindows);
+ while ( it.current() ) {
+ TQDockWindow *dw = it.current();
+ ++it;
+ if ( dw->isTopLevel() && !dw->isVisible() && !dw->testWState(TQt::WState_ForceHide) )
+ dw->show();
+ }
+ }
+
+ // show us last so we get focus
+ TQWidget::show();
+}
+
+
+/*! \reimp
+*/
+void TQMainWindow::hide()
+{
+ if ( isVisible() ) {
+ TQPtrListIterator<TQDockWindow> it(d->dockWindows);
+ while ( it.current() ) {
+ TQDockWindow *dw = it.current();
+ ++it;
+ if ( dw->isTopLevel() && dw->isVisible() ) {
+ dw->hide(); // implicit hide, so clear forcehide
+ ((TQMainWindow*)dw)->clearWState(TQt::WState_ForceHide);
+ }
+ }
+ }
+
+ TQWidget::hide();
+}
+
+
+/*! \reimp */
+TQSize TQMainWindow::tqsizeHint() const
+{
+ TQMainWindow* that = (TQMainWindow*) this;
+ // Workaround: because d->tll get's deleted in
+ // totalSizeHint->polish->sendPostedEvents->childEvent->triggerLayout
+ // [eg. canvas example on TQt/Embedded]
+ TQApplication::sendPostedEvents( that, TQEvent::ChildInserted );
+ if ( !that->d->tll )
+ that->setUpLayout();
+ return that->d->tll->totalSizeHint();
+}
+
+/*! \reimp */
+TQSize TQMainWindow::tqminimumSizeHint() const
+{
+ if ( !d->tll ) {
+ TQMainWindow* that = (TQMainWindow*) this;
+ that->setUpLayout();
+ }
+ return d->tll->totalMinimumSize();
+}
+
+/*!
+ Sets the central widget for this main window to \a w.
+
+ The central widget is surrounded by the left, top, right and
+ bottom dock areas. The menu bar is above the top dock area.
+
+ \sa centralWidget()
+*/
+
+void TQMainWindow::setCentralWidget( TQWidget * w )
+{
+ if ( d->mc )
+ d->mc->removeEventFilter( this );
+ d->mc = w;
+ if ( d->mc )
+ d->mc->installEventFilter( this );
+ triggerLayout();
+}
+
+
+/*!
+ Returns a pointer to the main window's central widget.
+
+ The central widget is surrounded by the left, top, right and
+ bottom dock areas. The menu bar is above the top dock area.
+
+ \sa setCentralWidget()
+*/
+
+TQWidget * TQMainWindow::centralWidget() const
+{
+ return d->mc;
+}
+
+
+/*! \reimp */
+
+void TQMainWindow::paintEvent( TQPaintEvent * )
+{
+ if (d->mb &&
+ tqstyle().tqstyleHint(TQStyle::SH_MainWindow_SpaceBelowMenuBar, this)) {
+
+ TQPainter p( this );
+ int y = d->mb->height() + 1;
+ tqstyle().tqdrawPrimitive(TQStyle::PE_Separator, &p, TQRect(0, y, width(), 1),
+ tqcolorGroup(), TQStyle::Style_Sunken);
+ }
+}
+
+
+bool TQMainWindow::dockMainWindow( TQObject *dock )
+{
+ while ( dock ) {
+ if ( dock->tqparent() && TQT_BASE_OBJECT(dock->tqparent()) == TQT_BASE_OBJECT(this) )
+ return TRUE;
+ if ( ::tqqt_cast<TQMainWindow*>(dock->tqparent()) )
+ return FALSE;
+ dock = dock->tqparent();
+ }
+ return FALSE;
+}
+
+/*!
+ \reimp
+*/
+
+bool TQMainWindow::eventFilter( TQObject* o, TQEvent *e )
+{
+ if ( e->type() == TQEvent::Show && TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) ) {
+ if ( !d->tll )
+ setUpLayout();
+ d->tll->activate();
+ } else if ( e->type() == TQEvent::ContextMenu && d->dockMenu &&
+ ( ::tqqt_cast<TQDockArea*>(o) && dockMainWindow( o ) || TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->hideDock) || TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->mb) ) ) {
+ if ( showDockMenu( ( (TQMouseEvent*)e )->globalPos() ) ) {
+ ( (TQContextMenuEvent*)e )->accept();
+ return TRUE;
+ }
+ }
+
+ return TQWidget::eventFilter( o, e );
+}
+
+
+/*!
+ Monitors events, recieved in \a e, to ensure the tqlayout is updated.
+*/
+void TQMainWindow::childEvent( TQChildEvent* e)
+{
+ if ( e->type() == TQEvent::ChildRemoved ) {
+ if ( e->child() == 0 ||
+ !e->child()->isWidgetType() ||
+ ((TQWidget*)e->child())->testWFlags( TQt::WType_TopLevel ) ) {
+ // nothing
+ } else if ( e->child() == d->sb ) {
+ d->sb = 0;
+ triggerLayout();
+ } else if ( e->child() == d->mb ) {
+ d->mb = 0;
+ triggerLayout();
+ } else if ( e->child() == d->mc ) {
+ d->mc = 0;
+ d->mwl->setCentralWidget( 0 );
+ triggerLayout();
+ } else if ( ::tqqt_cast<TQDockWindow*>(e->child()) ) {
+ removeDockWindow( (TQDockWindow *)(e->child()) );
+ d->appropriate.remove( (TQDockWindow*)e->child() );
+ triggerLayout();
+ }
+ } else if ( e->type() == TQEvent::ChildInserted && !d->sb ) {
+ d->sb = ::tqqt_cast<TQStatusBar*>(e->child());
+ if ( d->sb ) {
+ if ( d->tll ) {
+ if ( !d->tll->tqfindWidget( d->sb ) )
+ d->tll->addWidget( d->sb );
+ } else {
+ triggerLayout();
+ }
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+
+bool TQMainWindow::event( TQEvent * e )
+{
+ if ( e->type() == TQEvent::ChildRemoved && ( (TQChildEvent*)e )->child() == d->mc ) {
+ d->mc->removeEventFilter( this );
+ d->mc = 0;
+ d->mwl->setCentralWidget( 0 );
+ }
+
+ return TQWidget::event( e );
+}
+
+
+/*!
+ \property TQMainWindow::usesBigPixmaps
+ \brief whether big pixmaps are enabled
+
+ If FALSE (the default), the tool buttons will use small pixmaps;
+ otherwise big pixmaps will be used.
+
+ Tool buttons and other widgets that wish to respond to this
+ setting are responsible for reading the correct state on startup,
+ and for connecting to the main window's widget's
+ pixmapSizeChanged() signal.
+*/
+
+bool TQMainWindow::usesBigPixmaps() const
+{
+ return d->ubp;
+}
+
+void TQMainWindow::setUsesBigPixmaps( bool enable )
+{
+ if ( enable == (bool)d->ubp )
+ return;
+
+ d->ubp = enable;
+ emit pixmapSizeChanged( enable );
+
+ TQObjectList *l = queryList( "TQLayout" );
+ if ( !l || !l->first() ) {
+ delete l;
+ return;
+ }
+ for ( TQLayout *lay = (TQLayout*)l->first(); lay; lay = (TQLayout*)l->next() )
+ lay->activate();
+ delete l;
+}
+
+/*!
+ \property TQMainWindow::usesTextLabel
+ \brief whether text labels for toolbar buttons are enabled
+
+ If disabled (the default), the tool buttons will not use text
+ labels. If enabled, text labels will be used.
+
+ Tool buttons and other widgets that wish to respond to this
+ setting are responsible for reading the correct state on startup,
+ and for connecting to the main window's widget's
+ usesTextLabelChanged() signal.
+
+ \sa TQToolButton::setUsesTextLabel()
+*/
+
+bool TQMainWindow::usesTextLabel() const
+{
+ return d->utl;
+}
+
+
+void TQMainWindow::setUsesTextLabel( bool enable )
+{
+ if ( enable == (bool)d->utl )
+ return;
+
+ d->utl = enable;
+ emit usesTextLabelChanged( enable );
+
+ TQObjectList *l = queryList( "TQLayout" );
+ if ( !l || !l->first() ) {
+ delete l;
+ return;
+ }
+ for ( TQLayout *lay = (TQLayout*)l->first(); lay; lay = (TQLayout*)l->next() )
+ lay->activate();
+ delete l;
+}
+
+
+/*!
+ \fn void TQMainWindow::pixmapSizeChanged( bool )
+
+ This signal is emitted whenever the setUsesBigPixmaps() is called
+ with a value different to the current setting. All widgets that
+ should respond to such changes, e.g. toolbar buttons, must connect
+ to this signal.
+*/
+
+/*!
+ \fn void TQMainWindow::usesTextLabelChanged( bool )
+
+ This signal is emitted whenever the setUsesTextLabel() is called
+ with a value different to the current setting. All widgets that
+ should respond to such changes, e.g. toolbar buttons, must connect
+ to this signal.
+*/
+
+/*!
+ \fn void TQMainWindow::dockWindowPositionChanged( TQDockWindow *dockWindow )
+
+ This signal is emitted when the \a dockWindow has changed its
+ position. A change in position occurs when a dock window is moved
+ within its dock area or moved to another dock area (including the
+ \c Minimized and \c TearOff dock areas).
+
+ \sa getLocation()
+*/
+
+void TQMainWindow::setRightJustification( bool enable )
+{
+ if ( enable == (bool)d->justify )
+ return;
+ d->justify = enable;
+ triggerLayout( TRUE );
+}
+
+
+/*!
+ \obsolete
+ \property TQMainWindow::rightJustification
+ \brief whether the main window right-justifies its dock windows
+
+ If disabled (the default), stretchable dock windows are expanded,
+ and non-stretchable dock windows are given the minimum space they
+ need. Since most dock windows are not stretchable, this usually
+ results in an unjustified right edge (or unjustified bottom edge
+ for a vertical dock area). If enabled, the main window will
+ right-justify its dock windows.
+
+ \sa TQDockWindow::setVerticalStretchable(), TQDockWindow::setHorizontalStretchable()
+*/
+
+bool TQMainWindow::rightJustification() const
+{
+ return d->justify;
+}
+
+/*! \internal
+ */
+
+void TQMainWindow::triggerLayout( bool deleteLayout )
+{
+ if ( deleteLayout || !d->tll )
+ setUpLayout();
+ TQApplication::postEvent( this, new TQEvent( TQEvent::LayoutHint ) );
+}
+
+/*!
+ Enters 'What's This?' mode and returns immediately.
+
+ This is the same as TQWhatsThis::enterWhatsThisMode(), but
+ implemented as a main window object's slot. This way it can easily
+ be used for popup menus, for example:
+
+ \code
+ TQPopupMenu * help = new TQPopupMenu( this );
+ help->insertItem( "What's &This", this , TQT_SLOT(whatsThis()), SHIFT+Key_F1);
+ \endcode
+
+ \sa TQWhatsThis::enterWhatsThisMode()
+*/
+void TQMainWindow::whatsThis()
+{
+#ifndef TQT_NO_WHATSTHIS
+ TQWhatsThis::enterWhatsThisMode();
+#endif
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQMainWindow::styleChange( TQStyle& old )
+{
+ TQWidget::styleChange( old );
+}
+
+/*!
+ Finds the location of the dock window \a dw.
+
+ If the \a dw dock window is found in the main window the function
+ returns TRUE and populates the \a dock variable with the dw's dock
+ area and the \a index with the dw's position within the dock area.
+ It also sets \a nl to TRUE if the \a dw begins a new line
+ (otherwise FALSE), and \a extraOffset with the dock window's offset.
+
+ If the \a dw dock window is not found then the function returns
+ FALSE and the state of \a dock, \a index, \a nl and \a extraOffset
+ is undefined.
+
+ If you want to save and restore dock window positions then use
+ operator>>() and operator<<().
+
+ \sa operator>>() operator<<()
+*/
+
+bool TQMainWindow::getLocation( TQDockWindow *dw, TQt::Dock &dock, int &index, bool &nl, int &extraOffset ) const
+{
+ dock = TQt::DockTornOff;
+ if ( d->topDock->hasDockWindow( dw, &index ) )
+ dock = TQt::DockTop;
+ else if ( d->bottomDock->hasDockWindow( dw, &index ) )
+ dock = TQt::DockBottom;
+ else if ( d->leftDock->hasDockWindow( dw, &index ) )
+ dock = TQt::DockLeft;
+ else if ( d->rightDock->hasDockWindow( dw, &index ) )
+ dock = TQt::DockRight;
+ else if ( dw->parentWidget() == d->hideDock ) {
+ index = 0;
+ dock = TQt::DockMinimized;
+ } else {
+ index = 0;
+ }
+ nl = dw->newLine();
+ extraOffset = dw->offset();
+ return TRUE;
+}
+
+#ifndef TQT_NO_TOOLBAR
+/*!
+ Returns a list of all the toolbars which are in the \a dock dock
+ area, regardless of their state.
+
+ For example, the \c TornOff dock area may contain closed toolbars
+ but these are returned along with the visible toolbars.
+
+ \sa dockWindows()
+*/
+
+TQPtrList<TQToolBar> TQMainWindow::toolBars( TQt::Dock dock ) const
+{
+ TQPtrList<TQDockWindow> lst = dockWindows( dock );
+ TQPtrList<TQToolBar> tbl;
+ for ( TQDockWindow *w = lst.first(); w; w = lst.next() ) {
+ TQToolBar *tb = ::tqqt_cast<TQToolBar*>(w);
+ if ( tb )
+ tbl.append( tb );
+ }
+ return tbl;
+}
+#endif
+
+/*!
+ Returns a list of all the dock windows which are in the \a dock
+ dock area, regardless of their state.
+
+ For example, the \c DockTornOff dock area may contain closed dock
+ windows but these are returned along with the visible dock
+ windows.
+*/
+
+TQPtrList<TQDockWindow> TQMainWindow::dockWindows( TQt::Dock dock ) const
+{
+ TQPtrList<TQDockWindow> lst;
+ switch ( dock ) {
+ case TQt::DockTop:
+ return d->topDock->dockWindowList();
+ case TQt::DockBottom:
+ return d->bottomDock->dockWindowList();
+ case TQt::DockLeft:
+ return d->leftDock->dockWindowList();
+ case TQt::DockRight:
+ return d->rightDock->dockWindowList();
+ case TQt::DockTornOff: {
+ for ( TQDockWindow *w = d->dockWindows.first(); w; w = d->dockWindows.next() ) {
+ if ( !w->area() && w->place() == TQDockWindow::OutsideDock )
+ lst.append( w );
+ }
+ }
+ return lst;
+ case TQt::DockMinimized: {
+ if ( !d->hideDock->childrenListObject().isEmpty() ) {
+ TQObjectListIt it( d->hideDock->childrenListObject() );
+ TQObject *o;
+ while ( ( o = it.current() ) ) {
+ ++it;
+ TQDockWindow *dw = ::tqqt_cast<TQDockWindow*>(o);
+ if ( !dw )
+ continue;
+ lst.append( dw );
+ }
+ }
+ }
+ return lst;
+ default:
+ break;
+ }
+ return lst;
+}
+
+/*!
+ \overload
+
+ Returns the list of dock windows which belong to this main window,
+ regardless of which dock area they are in or what their state is,
+ (e.g. irrespective of whether they are visible or not).
+*/
+
+TQPtrList<TQDockWindow> TQMainWindow::dockWindows() const
+{
+ return d->dockWindows;
+}
+
+void TQMainWindow::setDockWindowsMovable( bool enable )
+{
+ d->movable = enable;
+ TQObjectList *l = queryList( "TQDockWindow" );
+ if ( l ) {
+ for ( TQObject *o = l->first(); o; o = l->next() )
+ ( (TQDockWindow*)o )->setMovingEnabled( enable );
+ }
+ delete l;
+}
+
+/*!
+ \property TQMainWindow::dockWindowsMovable
+ \brief whether the dock windows are movable
+
+ If TRUE (the default), the user will be able to move movable dock
+ windows from one TQMainWindow dock area to another, including the
+ \c TearOff area (i.e. where the dock window floats freely as a
+ window in its own right), and the \c Minimized area (where only
+ the dock window's handle is shown below the menu bar). Moveable
+ dock windows can also be moved within TQMainWindow dock areas, i.e.
+ to rearrange them within a dock area.
+
+ If FALSE the user will not be able to move any dock windows.
+
+ By default dock windows are moved transparently (i.e. only an
+ outline rectangle is shown during the drag), but this setting can
+ be changed with setOpaqueMoving().
+
+ \sa setDockEnabled(), setOpaqueMoving()
+*/
+
+bool TQMainWindow::dockWindowsMovable() const
+{
+ return d->movable;
+}
+
+void TQMainWindow::setOpaqueMoving( bool b )
+{
+ d->opaque = b;
+ TQObjectList *l = queryList( "TQDockWindow" );
+ if ( l ) {
+ for ( TQObject *o = l->first(); o; o = l->next() )
+ ( (TQDockWindow*)o )->setOpaqueMoving( b );
+ }
+ delete l;
+}
+
+/*!
+ \property TQMainWindow::opaqueMoving
+ \brief whether dock windows are moved opaquely
+
+ If TRUE the dock windows of the main window are shown opaquely
+ (i.e. it shows the toolbar as it looks when docked) whilst it is
+ being moved. If FALSE (the default) they are shown transparently,
+ (i.e. as an outline rectangle).
+
+ \warning Opaque moving of toolbars and dockwindows is known to
+ have several problems. We recommend avoiding the use of this
+ feature for the time being. We intend fixing the problems in a
+ future release.
+*/
+
+bool TQMainWindow::opaqueMoving() const
+{
+ return d->opaque;
+}
+
+/*!
+ This function will line up dock windows within the visible dock
+ areas (\c Top, \c Left, \c Right and \c Bottom) as compactly as
+ possible.
+
+ If \a keepNewLines is TRUE, all dock windows stay on their
+ original lines. If \a keepNewLines is FALSE then newlines may be
+ removed to achieve the most compact tqlayout possible.
+
+ The method only works if dockWindowsMovable() returns TRUE.
+*/
+
+void TQMainWindow::lineUpDockWindows( bool keepNewLines )
+{
+ if ( !dockWindowsMovable() )
+ return;
+ d->topDock->lineUp( keepNewLines );
+ d->leftDock->lineUp( keepNewLines );
+ d->rightDock->lineUp( keepNewLines );
+ d->bottomDock->lineUp( keepNewLines );
+}
+
+/*!
+ Returns TRUE, if the dock window menu is enabled; otherwise
+ returns FALSE.
+
+ The menu lists the (appropriate()) dock windows (which may be
+ shown or hidden), and has a "Line Up Dock Windows" menu item. It
+ will also have a "Customize" menu item if isCustomizable() returns
+ TRUE.
+
+ \sa setDockEnabled(), lineUpDockWindows() appropriate()
+ setAppropriate()
+*/
+
+bool TQMainWindow::isDockMenuEnabled() const
+{
+ return d->dockMenu;
+}
+
+/*!
+ If \a b is TRUE, then right clicking on a dock window or dock area
+ will pop up the dock window menu. If \a b is FALSE, right clicking
+ a dock window or dock area will not pop up the menu.
+
+ The menu lists the (appropriate()) dock windows (which may be
+ shown or hidden), and has a "Line Up Dock Windows" item. It will
+ also have a "Customize" menu item if isCustomizable() returns
+ TRUE.
+
+ \sa lineUpDockWindows(), isDockMenuEnabled()
+*/
+
+void TQMainWindow::setDockMenuEnabled( bool b )
+{
+ d->dockMenu = b;
+}
+
+/*!
+ Creates the dock window menu which tqcontains all toolbars (if \a
+ dockWindows is \c OnlyToolBars ), all dock windows (if \a
+ dockWindows is \c NoToolBars) or all toolbars and dock windows (if
+ \a dockWindows is \c AllDockWindows - the default).
+
+ This function is called internally when necessary, e.g. when the
+ user right clicks a dock area (providing isDockMenuEnabled()
+ returns TRUE).
+\omit
+### TQt 4.0
+ You can reimplement this function if you wish to customize the
+ behaviour.
+\endomit
+
+ The menu items representing the toolbars and dock windows are
+ checkable. The visible dock windows are checked and the hidden
+ dock windows are unchecked. The user can click a menu item to
+ change its state (show or hide the dock window).
+
+ The list and the state are always kept up-to-date.
+
+ Toolbars and dock windows which are not appropriate in the current
+ context (see setAppropriate()) are not listed in the menu.
+
+ The menu also has a menu item for lining up the dock windows.
+
+ If isCustomizable() returns TRUE, a Customize menu item is added
+ to the menu, which if clicked will call customize(). The
+ isCustomizable() function we provide returns FALSE and customize()
+ does nothing, so they must be reimplemented in a subclass to be
+ useful.
+*/
+
+TQPopupMenu *TQMainWindow::createDockWindowMenu( DockWindows dockWindows ) const
+{
+ TQObjectList *l = queryList( "TQDockWindow" );
+
+ if ( !l || l->isEmpty() )
+ return 0;
+
+ delete l;
+
+ TQPopupMenu *menu = new TQPopupMenu( (TQMainWindow*)this, "qt_customize_menu" );
+ menu->setCheckable( TRUE );
+ d->dockWindowModes.tqreplace( menu, dockWindows );
+ connect( menu, TQT_SIGNAL( aboutToShow() ), this, TQT_SLOT( menuAboutToShow() ) );
+ return menu;
+}
+
+/*!
+ This slot is called from the aboutToShow() signal of the default
+ dock menu of the mainwindow. The default implementation
+ initializes the menu with all dock windows and toolbars in this
+ slot.
+\omit
+### TQt 4.0
+ If you want to do small adjustments to the menu, you can do it in
+ this slot; or you can reimplement createDockWindowMenu().
+\endomit
+*/
+
+void TQMainWindow::menuAboutToShow()
+{
+ TQPopupMenu *menu = (TQPopupMenu*)sender();
+ TQMap<TQPopupMenu*, DockWindows>::Iterator it = d->dockWindowModes.tqfind( menu );
+ if ( it == d->dockWindowModes.end() )
+ return;
+ menu->clear();
+
+ DockWindows dockWindows = *it;
+
+ TQObjectList *l = queryList( "TQDockWindow" );
+
+ bool empty = TRUE;
+ if ( l && !l->isEmpty() ) {
+
+ TQObject *o = 0;
+ if ( dockWindows == AllDockWindows || dockWindows == NoToolBars ) {
+ for ( o = l->first(); o; o = l->next() ) {
+ TQDockWindow *dw = (TQDockWindow*)o;
+ if ( !appropriate( dw ) || ::tqqt_cast<TQToolBar*>(dw) || !dockMainWindow( TQT_TQOBJECT(dw) ) )
+ continue;
+ TQString label = dw->caption();
+ if ( !label.isEmpty() ) {
+ int id = menu->insertItem( label, TQT_TQOBJECT(dw), TQT_SLOT( toggleVisible() ) );
+ menu->setItemChecked( id, dw->isVisible() );
+ empty = FALSE;
+ }
+ }
+ if ( !empty )
+ menu->insertSeparator();
+ }
+
+ empty = TRUE;
+
+#ifndef TQT_NO_TOOLBAR
+ if ( dockWindows == AllDockWindows || dockWindows == OnlyToolBars ) {
+ for ( o = l->first(); o; o = l->next() ) {
+ TQToolBar *tb = ::tqqt_cast<TQToolBar*>(o);
+ if ( !tb || !appropriate(tb) || !dockMainWindow(TQT_TQOBJECT(tb)) )
+ continue;
+ TQString label = tb->label();
+ if ( !label.isEmpty() ) {
+ int id = menu->insertItem( label, TQT_TQOBJECT(tb), TQT_SLOT( toggleVisible() ) );
+ menu->setItemChecked( id, tb->isVisible() );
+ empty = FALSE;
+ }
+ }
+ }
+#endif
+
+ }
+
+ delete l;
+
+ if ( !empty )
+ menu->insertSeparator();
+
+ if ( dockWindowsMovable() )
+ menu->insertItem( tr( "Line up" ), TQT_TQOBJECT(this), TQT_SLOT( doLineUp() ) );
+ if ( isCustomizable() )
+ menu->insertItem( tr( "Customize..." ), TQT_TQOBJECT(this), TQT_SLOT( customize() ) );
+}
+
+/*!
+ Shows the dock menu at the position \a globalPos. The menu lists
+ the dock windows so that they can be shown (or hidden), lined up,
+ and possibly customized. Returns TRUE if the menu is shown;
+ otherwise returns FALSE.
+
+ If you want a custom menu, reimplement this function. You can
+ create the menu from scratch or call createDockWindowMenu() and
+ modify the result.
+\omit
+### TQt 4.0
+ The default implementation uses the dock window menu which gets
+ created by createDockWindowMenu(). You can reimplement
+ createDockWindowMenu() if you want to use your own specialized
+ popup menu.
+\endomit
+*/
+
+bool TQMainWindow::showDockMenu( const TQPoint &globalPos )
+{
+ if ( !d->dockMenu )
+ return FALSE;
+ if ( !d->rmbMenu )
+ d->rmbMenu = createDockWindowMenu();
+ if ( !d->rmbMenu )
+ return FALSE;
+
+ d->rmbMenu->exec( globalPos );
+ return TRUE;
+}
+
+void TQMainWindow::slotPlaceChanged()
+{
+ TQObject* obj = (TQObject*)sender();
+ TQDockWindow *dw = ::tqqt_cast<TQDockWindow*>(obj);
+ if ( dw )
+ emit dockWindowPositionChanged( dw );
+#ifndef TQT_NO_TOOLBAR
+ TQToolBar *tb = ::tqqt_cast<TQToolBar*>(obj);
+ if ( tb )
+ emit toolBarPositionChanged( tb );
+#endif
+}
+
+/*!
+ \internal
+ For internal use of TQDockWindow only.
+ */
+
+TQDockArea *TQMainWindow::dockingArea( const TQPoint &p )
+{
+ int mh = d->mb ? d->mb->height() : 0;
+ int sh = d->sb ? d->sb->height() : 0;
+ if ( p.x() >= -5 && p.x() <= 100 && p.y() > mh && p.y() - height() - sh )
+ return d->leftDock;
+ if ( p.x() >= width() - 100 && p.x() <= width() + 5 && p.y() > mh && p.y() - height() - sh )
+ return d->rightDock;
+ if ( p.y() >= -5 && p.y() < mh + 100 && p.x() >= 0 && p.x() <= width() )
+ return d->topDock;
+ if ( p.y() >= height() - sh - 100 && p.y() <= height() + 5 && p.x() >= 0 && p.x() <= width() )
+ return d->bottomDock;
+ return 0;
+}
+
+/*!
+ Returns TRUE if \a dw is a dock window known to the main window;
+ otherwise returns FALSE.
+*/
+
+bool TQMainWindow::hasDockWindow( TQDockWindow *dw )
+{
+ return d->dockWindows.tqfindRef( dw ) != -1;
+}
+
+/*!
+ Returns the \c Left dock area
+
+ \sa rightDock() topDock() bottomDock()
+*/
+
+TQDockArea *TQMainWindow::leftDock() const
+{
+ return d->leftDock;
+}
+
+/*!
+ Returns the \c Right dock area
+
+ \sa leftDock() topDock() bottomDock()
+*/
+
+TQDockArea *TQMainWindow::rightDock() const
+{
+ return d->rightDock;
+}
+
+/*!
+ Returns the \c Top dock area
+
+ \sa bottomDock() leftDock() rightDock()
+*/
+
+TQDockArea *TQMainWindow::topDock() const
+{
+ return d->topDock;
+}
+
+/*!
+ Returns a pointer the \c Bottom dock area
+
+ \sa topDock() leftDock() rightDock()
+*/
+
+TQDockArea *TQMainWindow::bottomDock() const
+{
+ return d->bottomDock;
+}
+
+/*!
+ This function is called when the user clicks the Customize menu
+ item on the dock window menu.
+
+ The customize menu item will only appear if isCustomizable()
+ returns TRUE (it returns FALSE by default).
+
+ The function is intended, for example, to provide the user with a
+ means of telling the application that they wish to customize the
+ main window, dock windows or dock areas.
+
+ The default implementation does nothing and the Customize menu
+ item is not shown on the right-click menu by default. If you want
+ the item to appear then reimplement isCustomizable() to return
+ TRUE, and reimplement this function to do whatever you want.
+
+ \sa isCustomizable()
+*/
+
+void TQMainWindow::customize()
+{
+}
+
+/*!
+ Returns TRUE if the dock area dock window menu includes the
+ Customize menu item (which calls customize() when clicked).
+ Returns FALSE by default, i.e. the popup menu will not contain a
+ Customize menu item. You will need to reimplement this function
+ and set it to return TRUE if you wish the user to be able to see
+ the dock window menu.
+
+ \sa customize()
+*/
+
+bool TQMainWindow::isCustomizable() const
+{
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if it is appropriate to include a menu item for the
+ \a dw dock window in the dock window menu; otherwise returns
+ FALSE.
+
+ The user is able to change the state (show or hide) a dock window
+ that has a menu item by clicking the item.
+
+ Call setAppropriate() to indicate whether or not a particular dock
+ window should appear on the popup menu.
+
+ \sa setAppropriate()
+*/
+
+bool TQMainWindow::appropriate( TQDockWindow *dw ) const
+{
+ TQMap<TQDockWindow*, bool>::ConstIterator it = d->appropriate.tqfind( dw );
+ if ( it == d->appropriate.end() )
+ return TRUE;
+ return *it;
+}
+
+/*!
+ Use this function to control whether or not the \a dw dock
+ window's caption should appear as a menu item on the dock window
+ menu that lists the dock windows.
+
+ If \a a is TRUE then the \a dw will appear as a menu item on the
+ dock window menu. The user is able to change the state (show or
+ hide) a dock window that has a menu item by clicking the item;
+ depending on the state of your application, this may or may not be
+ appropriate. If \a a is FALSE the \a dw will not appear on the
+ popup menu.
+
+ \sa showDockMenu() isCustomizable() customize()
+*/
+
+void TQMainWindow::setAppropriate( TQDockWindow *dw, bool a )
+{
+ d->appropriate.tqreplace( dw, a );
+}
+
+#ifndef TQT_NO_TEXTSTREAM
+static void saveDockArea( TQTextStream &ts, TQDockArea *a )
+{
+ TQPtrList<TQDockWindow> l = a->dockWindowList();
+ for ( TQDockWindow *dw = l.first(); dw; dw = l.next() ) {
+ ts << TQString( dw->caption() );
+ ts << ",";
+ }
+ ts << endl;
+ ts << *a;
+}
+
+/*!
+ \relates TQMainWindow
+
+ Writes the tqlayout (sizes and positions) of the dock windows in the
+ dock areas of the TQMainWindow \a mainWindow, including \c
+ Minimized and \c TornOff dock windows, to the text stream \a ts.
+
+ This can be used, for example, in conjunction with TQSettings to
+ save the user's tqlayout when the \mainWindow receives a closeEvent.
+
+ \sa operator>>() closeEvent()
+*/
+
+TQTextStream &operator<<( TQTextStream &ts, const TQMainWindow &mainWindow )
+{
+ TQPtrList<TQDockWindow> l = mainWindow.dockWindows( TQt::DockMinimized );
+ TQDockWindow *dw = 0;
+ for ( dw = l.first(); dw; dw = l.next() ) {
+ ts << dw->caption();
+ ts << ",";
+ }
+ ts << endl;
+
+ l = mainWindow.dockWindows( TQt::DockTornOff );
+ for ( dw = l.first(); dw; dw = l.next() ) {
+ ts << dw->caption();
+ ts << ",";
+ }
+ ts << endl;
+ for ( dw = l.first(); dw; dw = l.next() ) {
+ ts << "[" << dw->caption() << ","
+ << (int)dw->tqgeometry().x() << ","
+ << (int)dw->tqgeometry().y() << ","
+ << (int)dw->tqgeometry().width() << ","
+ << (int)dw->tqgeometry().height() << ","
+ << (int)dw->isVisible() << "]";
+ }
+ ts << endl;
+
+ saveDockArea( ts, mainWindow.topDock() );
+ saveDockArea( ts, mainWindow.bottomDock() );
+ saveDockArea( ts, mainWindow.rightDock() );
+ saveDockArea( ts, mainWindow.leftDock() );
+ return ts;
+}
+
+static void loadDockArea( const TQStringList &names, TQDockArea *a, TQt::Dock d, TQPtrList<TQDockWindow> &l, TQMainWindow *mw, TQTextStream &ts )
+{
+ for ( TQStringList::ConstIterator it = names.begin(); it != names.end(); ++it ) {
+ for ( TQDockWindow *dw = l.first(); dw; dw = l.next() ) {
+ if ( dw->caption() == *it ) {
+ mw->addDockWindow( dw, d );
+ break;
+ }
+ }
+ }
+ if ( a ) {
+ ts >> *a;
+ } else if ( d == TQt::DockTornOff ) {
+ TQString s = ts.readLine();
+ enum State { Pre, Name, X, Y, Width, Height, Visible, Post };
+ int state = Pre;
+ TQString name, x, y, w, h, visible;
+ TQChar c;
+ for ( int i = 0; i < (int)s.length(); ++i ) {
+ c = s[ i ];
+ if ( state == Pre && c == '[' ) {
+ state++;
+ continue;
+ }
+ if ( c == ',' &&
+ ( state == Name || state == X || state == Y || state == Width || state == Height ) ) {
+ state++;
+ continue;
+ }
+ if ( state == Visible && c == ']' ) {
+ for ( TQDockWindow *dw = l.first(); dw; dw = l.next() ) {
+ if ( TQString( dw->caption() ) == name ) {
+ if ( !::tqqt_cast<TQToolBar*>(dw) )
+ dw->setGeometry( x.toInt(), y.toInt(), w.toInt(), h.toInt() );
+ else
+ dw->setGeometry( x.toInt(), y.toInt(), dw->width(), dw->height() );
+ if ( !(bool)visible.toInt() )
+ dw->hide();
+ else
+ dw->show();
+ break;
+ }
+ }
+
+ name = x = y = w = h = visible = "";
+
+ state = Pre;
+ continue;
+ }
+ if ( state == Name )
+ name += c;
+ else if ( state == X )
+ x += c;
+ else if ( state == Y )
+ y += c;
+ else if ( state == Width )
+ w += c;
+ else if ( state == Height )
+ h += c;
+ else if ( state == Visible )
+ visible += c;
+ }
+ }
+}
+
+/*!
+ \relates TQMainWindow
+
+ Reads the tqlayout (sizes and positions) of the dock windows in the
+ dock areas of the TQMainWindow \a mainWindow from the text stream,
+ \a ts, including \c Minimized and \c TornOff dock windows.
+ Restores the dock windows and dock areas to these sizes and
+ positions. The tqlayout information must be in the format produced
+ by operator<<().
+
+ This can be used, for example, in conjunction with TQSettings to
+ restore the user's tqlayout.
+
+ \sa operator<<()
+*/
+
+TQTextStream &operator>>( TQTextStream &ts, TQMainWindow &mainWindow )
+{
+ TQPtrList<TQDockWindow> l = mainWindow.dockWindows();
+
+ TQString s = ts.readLine();
+ TQStringList names = TQStringList::split( ',', s );
+ loadDockArea( names, 0, TQt::DockMinimized, l, &mainWindow, ts );
+
+ s = ts.readLine();
+ names = TQStringList::split( ',', s );
+ loadDockArea( names, 0, TQt::DockTornOff, l, &mainWindow, ts );
+
+ int i = 0;
+ TQDockArea *areas[] = { mainWindow.topDock(), mainWindow.bottomDock(), mainWindow.rightDock(), mainWindow.leftDock() };
+ for ( int d = (int)TQt::DockTop; d != (int)TQt::DockMinimized; ++d, ++i ) {
+ s = ts.readLine();
+ names = TQStringList::split( ',', s );
+ loadDockArea( names, areas[ i ], (TQt::Dock)d, l, &mainWindow, ts );
+ }
+ return ts;
+}
+#endif
+
+#include "tqmainwindow.tqmoc"
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqmainwindow.h b/tqtinterface/qt4/src/widgets/tqmainwindow.h
new file mode 100644
index 0000000..6cbcc02
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqmainwindow.h
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Definition of TQMainWindow class
+**
+** Created : 980316
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMAINWINDOW_H
+#define TQMAINWINDOW_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqtoolbar.h"
+#include "tqptrlist.h"
+#include "tqtextstream.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_MAINWINDOW
+
+class TQMenuBar;
+class TQStatusBar;
+class TQToolTipGroup;
+class TQMainWindowPrivate;
+class TQMainWindowLayout;
+class TQPopupMenu;
+
+class TQ_EXPORT TQMainWindow: public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool rightJustification READ rightJustification WRITE setRightJustification DESIGNABLE false )
+ Q_PROPERTY( bool usesBigPixmaps READ usesBigPixmaps WRITE setUsesBigPixmaps )
+ Q_PROPERTY( bool usesTextLabel READ usesTextLabel WRITE setUsesTextLabel )
+ Q_PROPERTY( bool dockWindowsMovable READ dockWindowsMovable WRITE setDockWindowsMovable )
+ Q_PROPERTY( bool opaqueMoving READ opaqueMoving WRITE setOpaqueMoving )
+
+public:
+ TQMainWindow( TQWidget* tqparent=0, const char* name=0, WFlags f = (WFlags)TQt::WType_TopLevel );
+ ~TQMainWindow();
+
+#ifndef TQT_NO_MENUBAR
+ TQMenuBar * menuBar() const;
+#endif
+ TQStatusBar * statusBar() const;
+#ifndef TQT_NO_TOOLTIP
+ TQToolTipGroup * toolTipGroup() const;
+#endif
+
+ virtual void setCentralWidget( TQWidget * );
+ TQWidget * centralWidget() const;
+
+ virtual void setDockEnabled( TQt::Dock dock, bool enable );
+ bool isDockEnabled( TQt::Dock dock ) const;
+ bool isDockEnabled( TQDockArea *area ) const;
+ virtual void setDockEnabled( TQDockWindow *tb, TQt::Dock dock, bool enable );
+ bool isDockEnabled( TQDockWindow *tb, TQt::Dock dock ) const;
+ bool isDockEnabled( TQDockWindow *tb, TQDockArea *area ) const;
+
+ virtual void addDockWindow( TQDockWindow *, TQt::Dock = TQt::DockTop, bool newLine = FALSE );
+ virtual void addDockWindow( TQDockWindow *, const TQString &label,
+ TQt::Dock = TQt::DockTop, bool newLine = FALSE );
+ virtual void moveDockWindow( TQDockWindow *, TQt::Dock = TQt::DockTop );
+ virtual void moveDockWindow( TQDockWindow *, TQt::Dock, bool nl, int index, int extraOffset = -1 );
+ virtual void removeDockWindow( TQDockWindow * );
+
+ void show();
+ void hide();
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ bool rightJustification() const;
+ bool usesBigPixmaps() const;
+ bool usesTextLabel() const;
+ bool dockWindowsMovable() const;
+ bool opaqueMoving() const;
+
+ bool eventFilter( TQObject*, TQEvent* );
+
+ bool getLocation( TQDockWindow *tb, TQt::Dock &dock, int &index, bool &nl, int &extraOffset ) const;
+
+ TQPtrList<TQDockWindow> dockWindows( TQt::Dock dock ) const;
+ TQPtrList<TQDockWindow> dockWindows() const;
+ void lineUpDockWindows( bool keepNewLines = FALSE );
+
+ bool isDockMenuEnabled() const;
+
+ // compatibility stuff
+ bool hasDockWindow( TQDockWindow *dw );
+#ifndef TQT_NO_TOOLBAR
+ void addToolBar( TQDockWindow *, TQt::Dock = TQt::DockTop, bool newLine = FALSE );
+ void addToolBar( TQDockWindow *, const TQString &label,
+ TQt::Dock = TQt::DockTop, bool newLine = FALSE );
+ void moveToolBar( TQDockWindow *, TQt::Dock = TQt::DockTop );
+ void moveToolBar( TQDockWindow *, TQt::Dock, bool nl, int index, int extraOffset = -1 );
+ void removeToolBar( TQDockWindow * );
+
+ bool toolBarsMovable() const;
+ TQPtrList<TQToolBar> toolBars( TQt::Dock dock ) const;
+ void lineUpToolBars( bool keepNewLines = FALSE );
+#endif
+
+ virtual TQDockArea *dockingArea( const TQPoint &p );
+ TQDockArea *leftDock() const;
+ TQDockArea *rightDock() const;
+ TQDockArea *topDock() const;
+ TQDockArea *bottomDock() const;
+
+ virtual bool isCustomizable() const;
+
+ bool appropriate( TQDockWindow *dw ) const;
+
+ enum DockWindows { OnlyToolBars, NoToolBars, AllDockWindows };
+ TQPopupMenu *createDockWindowMenu( DockWindows dockWindows = AllDockWindows ) const;
+
+public Q_SLOTS:
+ virtual void setRightJustification( bool );
+ virtual void setUsesBigPixmaps( bool );
+ virtual void setUsesTextLabel( bool );
+ virtual void setDockWindowsMovable( bool );
+ virtual void setOpaqueMoving( bool );
+ virtual void setDockMenuEnabled( bool );
+ virtual void whatsThis();
+ virtual void setAppropriate( TQDockWindow *dw, bool a );
+ virtual void customize();
+
+ // compatibility stuff
+ void setToolBarsMovable( bool );
+
+Q_SIGNALS:
+ void pixmapSizeChanged( bool );
+ void usesTextLabelChanged( bool );
+ void dockWindowPositionChanged( TQDockWindow * );
+
+#ifndef TQT_NO_TOOLBAR
+ // compatibility stuff
+ void toolBarPositionChanged( TQToolBar * );
+#endif
+
+protected Q_SLOTS:
+ virtual void setUpLayout();
+ virtual bool showDockMenu( const TQPoint &globalPos );
+ void menuAboutToShow();
+
+protected:
+ void paintEvent( TQPaintEvent * );
+ void childEvent( TQChildEvent * );
+ bool event( TQEvent * );
+ void styleChange( TQStyle& );
+
+private Q_SLOTS:
+ void slotPlaceChanged();
+ void doLineUp() { lineUpDockWindows( TRUE ); }
+
+private:
+ TQMainWindowPrivate * d;
+ void triggerLayout( bool deleteLayout = TRUE);
+ bool dockMainWindow( TQObject *dock );
+
+#ifndef TQT_NO_MENUBAR
+ virtual void setMenuBar( TQMenuBar * );
+#endif
+ virtual void setqStatusBar( TQStatusBar * );
+#ifndef TQT_NO_TOOLTIP
+ virtual void setToolTipGroup( TQToolTipGroup * );
+#endif
+
+ friend class TQDockWindow;
+ friend class TQMenuBar;
+ friend class TQHideDock;
+ friend class TQToolBar;
+ friend class TQMainWindowLayout;
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQMainWindow( const TQMainWindow & );
+ TQMainWindow& operator=( const TQMainWindow & );
+#endif
+};
+
+#ifndef TQT_NO_TOOLBAR
+inline void TQMainWindow::addToolBar( TQDockWindow *w, TQt::ToolBarDock dock, bool newLine )
+{
+ addDockWindow( w, dock, newLine );
+}
+
+inline void TQMainWindow::addToolBar( TQDockWindow *w, const TQString &label,
+ TQt::ToolBarDock dock, bool newLine )
+{
+ addDockWindow( w, label, dock, newLine );
+}
+
+inline void TQMainWindow::moveToolBar( TQDockWindow *w, TQt::ToolBarDock dock )
+{
+ moveDockWindow( w, dock );
+}
+
+inline void TQMainWindow::moveToolBar( TQDockWindow *w, TQt::ToolBarDock dock, bool nl, int index, int extraOffset )
+{
+ moveDockWindow( w, dock, nl, index, extraOffset );
+}
+
+inline void TQMainWindow::removeToolBar( TQDockWindow *w )
+{
+ removeDockWindow( w );
+}
+
+inline bool TQMainWindow::toolBarsMovable() const
+{
+ return dockWindowsMovable();
+}
+
+inline void TQMainWindow::lineUpToolBars( bool keepNewLines )
+{
+ lineUpDockWindows( keepNewLines );
+}
+
+inline void TQMainWindow::setToolBarsMovable( bool b )
+{
+ setDockWindowsMovable( b );
+}
+#endif
+
+#ifndef TQT_NO_TEXTSTREAM
+TQ_EXPORT TQTextStream &operator<<( TQTextStream &, const TQMainWindow & );
+TQ_EXPORT TQTextStream &operator>>( TQTextStream &, TQMainWindow & );
+#endif
+
+#endif // TQT_NO_MAINWINDOW
+
+#endif // TQMAINWINDOW_H
diff --git a/tqtinterface/qt4/src/widgets/tqmenubar.cpp b/tqtinterface/qt4/src/widgets/tqmenubar.cpp
new file mode 100644
index 0000000..aadb3ee
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqmenubar.cpp
@@ -0,0 +1,1673 @@
+/****************************************************************************
+**
+** Implementation of TQMenuBar class
+**
+** Created : 941209
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+// tqmainwindow.h before tqmenubar.h because of GCC-2.7.* compatibility
+// ### could be reorganised by discarding INCLUDE_MENUITEM_DEF and put
+// the relevant declarations in a private header?
+#include "tqmainwindow.h"
+#ifndef TQT_NO_MENUBAR
+#include "tqmenubar.h"
+#include "tqpopupmenu.h"
+#include "tqaccel.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqapplication.h"
+#include "tqguardedptr.h"
+#include "tqlayout.h"
+#include "tqcleanuphandler.h"
+#include "../kernel/tqinternal_p.h"
+#include "tqstyle.h"
+#include "tqtimer.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+class TQMenuDataData {
+ // attention: also defined in qmenudata.cpp
+public:
+ TQMenuDataData();
+ TQGuardedPtr<TQWidget> aWidget;
+ int aInt;
+};
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+static bool inMenu = FALSE;
+#endif
+
+#if defined(TQ_WS_X11)
+extern int qt_xfocusout_grab_counter; // defined in qapplication_x11.cpp
+#endif
+
+/*!
+ \class TQMenuBar tqmenubar.h
+ \brief The TQMenuBar class provides a horizontal menu bar.
+
+ \ingroup application
+ \mainclass
+
+ A menu bar consists of a list of pull-down menu items. You add
+ menu items with \link TQMenuData::insertItem()
+ insertItem()\endlink. For example, asuming that \c menubar is a
+ pointer to a TQMenuBar and \c filemenu is a pointer to a
+ TQPopupMenu, the following statement inserts the menu into the menu
+ bar:
+ \code
+ menubar->insertItem( "&File", filemenu );
+ \endcode
+ The ampersand in the menu item's text sets Alt+F as a shortcut for
+ this menu. (You can use "\&\&" to get a real ampersand in the menu
+ bar.)
+
+ Items are either enabled or disabled. You toggle their state with
+ setItemEnabled().
+
+ There is no need to lay out a menu bar. It automatically sets its
+ own tqgeometry to the top of the tqparent widget and changes it
+ appropriately whenever the tqparent is resized.
+
+ \important insertItem removeItem clear insertSeparator setItemEnabled isItemEnabled setItemVisible isItemVisible
+
+ Example of creating a menu bar with menu items (from \l menu/menu.cpp):
+ \quotefile menu/menu.cpp
+ \skipto file = new TQPopupMenu
+ \printline
+ \skipto Qt::Key_O
+ \printline
+ \printline
+ \skipto new TQMenuBar
+ \printline
+ \skipto insertItem
+ \printline
+
+ In most main window style applications you would use the menuBar()
+ provided in TQMainWindow, adding \l{TQPopupMenu}s to the menu bar
+ and adding \l{TQAction}s to the popup menus.
+
+ Example (from \l action/application.cpp):
+ \quotefile action/application.cpp
+ \skipto file = new TQPopupMenu
+ \printuntil fileNewAction
+
+ Menu items can have text and pixmaps (or iconsets), see the
+ various \link TQMenuData::insertItem() insertItem()\endlink
+ overloads, as well as separators, see \link
+ TQMenuData::insertSeparator() insertSeparator()\endlink. You can
+ also add custom menu items that are derived from
+ \l{TQCustomMenuItem}.
+
+ Menu items may be removed with removeItem() and enabled or
+ disabled with \link TQMenuData::setItemEnabled()
+ setItemEnabled()\endlink.
+
+ <img src=qmenubar-m.png> <img src=qmenubar-w.png>
+
+ \section1 TQMenuBar on TQt/Mac
+
+ TQMenuBar on TQt/Mac is a wrapper for using the system-wide menubar.
+ If you have multiple menubars in one dialog the outermost menubar
+ (normally inside a widget with widget flag \c WType_TopLevel) will
+ be used for the system-wide menubar.
+
+ Note that arbitrary TQt widgets \e cannot be inserted into a
+ TQMenuBar on the Mac because TQt uses Mac's native menus which don't
+ support this functionality. This limitation does not apply to
+ stand-alone TQPopupMenus.
+
+ TQt/Mac also provides a menubar merging feature to make TQMenuBar
+ conform more closely to accepted Mac OS X menubar tqlayout. The
+ merging functionality is based on string matching the title of a
+ TQPopupMenu entry. These strings are translated (using
+ TQObject::tr()) in the "TQMenuBar" context. If an entry is moved its
+ Q_SLOTS will still fire as if it was in the original place. The
+ table below outlines the strings looked for and where the entry is
+ placed if matched:
+
+ \table
+ \header \i String matches \i Placement \i Notes
+ \row \i about.*
+ \i Application Menu | About <application name>
+ \i If this entry is not found no About item will appear in
+ the Application Menu
+ \row \i config, options, setup, settings or preferences
+ \i Application Menu | Preferences
+ \i If this entry is not found the Settings item will be disabled
+ \row \i quit or exit
+ \i Application Menu | Quit <application name>
+ \i If this entry is not found a default Quit item will be
+ created to call TQApplication::quit()
+ \endtable
+
+ \link menu-example.html menu/menu.cpp\endlink is an example of
+ TQMenuBar and TQPopupMenu use.
+
+ \sa TQPopupMenu TQAccel TQAction \link http://developer.apple.com/techpubs/macosx/Carbon/HumanInterfaceToolbox/Aqua/aqua.html Aqua Style Guidelines \endlink \link guibooks.html#fowler GUI Design Handbook: Menu Bar \endlink
+*/
+
+
+/*!
+ \enum TQMenuBar::Separator
+
+ This enum type is used to decide whether TQMenuBar should draw a
+ separator line at its bottom.
+
+ \value Never In many applications there is already a separator,
+ and having two looks wrong.
+
+ \value InWindowsStyle In some other applications a separator looks
+ good in Windows style, but nowhere else.
+*/
+
+/*!
+ \fn void TQMenuBar::activated( int id )
+
+ This signal is emitted when a menu item is selected; \a id is the
+ id of the selected item.
+
+ Normally you will connect each menu item to a single slot using
+ TQMenuData::insertItem(), but sometimes you will want to connect
+ several items to a single slot (most often if the user selects
+ from an array). This signal is useful in such cases.
+
+ \sa highlighted(), TQMenuData::insertItem()
+*/
+
+/*!
+ \fn void TQMenuBar::highlighted( int id )
+
+ This signal is emitted when a menu item is highlighted; \a id is
+ the id of the highlighted item.
+
+ Normally, you will connect each menu item to a single slot using
+ TQMenuData::insertItem(), but sometimes you will want to connect
+ several items to a single slot (most often if the user selects
+ from an array). This signal is useful in such cases.
+
+ \sa activated(), TQMenuData::insertItem()
+*/
+
+
+// Motif style parameters
+
+static const int motifBarHMargin = 2; // menu bar hor margin to item
+static const int motifBarVMargin = 1; // menu bar ver margin to item
+static const int motifItemFrame = 2; // menu item frame width
+static const int motifItemHMargin = 5; // menu item hor text margin
+static const int motifItemVMargin = 4; // menu item ver text margin
+
+/*
+
++-----------------------------
+| BarFrame
+| +-------------------------
+| | V BarMargin
+| | +---------------------
+| | H | ItemFrame
+| | | +-----------------
+| | | | \
+| | | | ^ T E X T ^ | ItemVMargin
+| | | | | | /
+| | | ItemHMargin
+| |
+|
+
+*/
+
+
+/*****************************************************************************
+ TQMenuBar member functions
+ *****************************************************************************/
+
+
+/*!
+ Constructs a menu bar called \a name with tqparent \a tqparent.
+*/
+TQMenuBar::TQMenuBar( TQWidget *tqparent, const char *name )
+ : TQFrame( tqparent, name, TQt::WNoAutoErase )
+{
+#if defined( TQ_WS_MAC ) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ mac_eaten_menubar = FALSE;
+ mac_d = 0;
+ macCreateNativeMenubar();
+#endif
+ isMenuBar = TRUE;
+#ifndef TQT_NO_ACCEL
+ autoaccel = 0;
+#endif
+ irects = 0;
+ rightSide = 0; // Right of here is right-aligned content
+ mseparator = 0;
+ waitforalt = 0;
+ popupvisible = 0;
+ hasmouse = 0;
+ defaultup = 0;
+ toggleclose = 0;
+ pendingDelayedContentsChanges = 0;
+ pendingDelayedStateChanges = 0;
+ if ( tqparent ) {
+ // filter tqparent events for resizing
+ tqparent->installEventFilter( this );
+
+ // filter top-level-widget events for accelerators
+ TQWidget *tlw = tqtopLevelWidget();
+ if ( tlw != tqparent )
+ tlw->installEventFilter( this );
+ }
+ installEventFilter( this );
+
+ setBackgroundMode( TQt::PaletteButton );
+ setFrameStyle( TQFrame::MenuBarPanel | TQFrame::Raised );
+
+ TQFontMetrics fm = fontMetrics();
+ int h = 2*motifBarVMargin + fm.height() + motifItemVMargin + 2*frameWidth() + 2*motifItemFrame;
+
+ setGeometry( 0, 0, width(), h );
+
+ setMouseTracking( tqstyle().tqstyleHint(TQStyle::SH_MenuBar_MouseTracking) );
+}
+
+
+
+/*! \reimp */
+
+void TQMenuBar::styleChange( TQStyle& old )
+{
+ setMouseTracking( tqstyle().tqstyleHint(TQStyle::SH_MenuBar_MouseTracking) );
+ TQFrame::styleChange( old );
+}
+
+
+
+/*!
+ Destroys the menu bar.
+*/
+
+TQMenuBar::~TQMenuBar()
+{
+#ifndef TQT_NO_ACCEL
+ delete autoaccel;
+#endif
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ macRemoveNativeMenubar();
+#endif
+ if ( irects ) // Avoid purify complaint.
+ delete [] irects;
+}
+
+/*!
+ \internal
+
+ Repaints the menu item with id \a id; does nothing if there is no
+ such menu item.
+*/
+void TQMenuBar::updateItem( int id )
+{
+ int i = indexOf( id );
+ if ( i >= 0 && irects )
+ tqrepaint( irects[i], FALSE );
+}
+
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+static bool fromFrameChange = FALSE;
+#endif
+
+/*!
+ Recomputes the menu bar's display data according to the new
+ contents.
+
+ You should never need to call this; it is called automatically by
+ TQMenuData whenever it needs to be called.
+*/
+
+void TQMenuBar::menuContentsChanged()
+{
+ // here the part that can't be delayed
+ TQMenuData::menuContentsChanged();
+ badSize = TRUE; // might change the size
+ if( pendingDelayedContentsChanges )
+ return;
+ pendingDelayedContentsChanges = 1;
+ if( !pendingDelayedStateChanges )// if the timer hasn't been started yet
+ TQTimer::singleShot( 0, this, TQT_SLOT(performDelayedChanges()));
+}
+
+void TQMenuBar::performDelayedContentsChanged()
+{
+ pendingDelayedContentsChanges = 0;
+ // here the part the can be delayed
+#ifndef TQT_NO_ACCEL
+ // if performDelayedStateChanged() will be called too,
+ // it will call setupAccelerators() too, no need to do it twice
+ if( !pendingDelayedStateChanges )
+ setupAccelerators();
+#endif
+ calculateRects();
+ if ( isVisible() ) {
+ update();
+#ifndef TQT_NO_MAINWINDOW
+ TQMainWindow *mw = ::tqqt_cast<TQMainWindow*>(tqparent());
+ if ( mw ) {
+ mw->triggerLayout();
+ mw->update();
+ }
+#endif
+#ifndef TQT_NO_LAYOUT
+ if ( parentWidget() && parentWidget()->tqlayout() )
+ parentWidget()->tqlayout()->activate();
+#endif
+ }
+}
+
+/*!
+ Recomputes the menu bar's display data according to the new state.
+
+ You should never need to call this; it is called automatically by
+ TQMenuData whenever it needs to be called.
+*/
+
+void TQMenuBar::menuStateChanged()
+{
+ if( pendingDelayedStateChanges )
+ return;
+ pendingDelayedStateChanges = 1;
+ if( !pendingDelayedContentsChanges ) // if the timer hasn't been started yet
+ TQTimer::singleShot( 0, this, TQT_SLOT(performDelayedChanges()));
+}
+
+void TQMenuBar::performDelayedStateChanged()
+{
+ pendingDelayedStateChanges = 0;
+ // here the part that can be delayed
+#ifndef TQT_NO_ACCEL
+ setupAccelerators(); // ### when we have a good solution for the accel vs. focus
+ // widget problem, remove that. That is only a workaround
+ // if you remove this, see performDelayedContentsChanged()
+#endif
+ update();
+}
+
+
+void TQMenuBar::performDelayedChanges()
+{
+#if defined(TQ_WS_MAC) && !defined(TQMAC_MENUBAR_NO_NATIVE)
+ // I must do this here as the values change in the function below.
+ bool needMacUpdate = (pendingDelayedContentsChanges || pendingDelayedStateChanges);
+#endif
+ if( pendingDelayedContentsChanges )
+ performDelayedContentsChanged();
+ if( pendingDelayedStateChanges )
+ performDelayedStateChanged();
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ if(mac_eaten_menubar && needMacUpdate) {
+ macDirtyNativeMenubar();
+
+ bool all_hidden = TRUE;
+ if(irects) {
+ for(int i = 0; all_hidden && i < (int)mitems->count(); i++)
+ all_hidden = irects[i].isEmpty();
+ }
+ if( all_hidden ) {
+ if( !isHidden())
+ hide();
+ } else {
+ if( !isShown() && !fromFrameChange )
+ show();
+ }
+ }
+#endif
+}
+
+
+void TQMenuBar::menuInsPopup( TQPopupMenu *popup )
+{
+ connect( popup, TQT_SIGNAL(activatedRedirect(int)),
+ TQT_SLOT(subActivated(int)) );
+ connect( popup, TQT_SIGNAL(highlightedRedirect(int)),
+ TQT_SLOT(subHighlighted(int)) );
+ connect( popup, TQT_SIGNAL(destroyed(TQObject*)),
+ this, TQT_SLOT(popupDestroyed(TQObject*)) );
+}
+
+void TQMenuBar::menuDelPopup( TQPopupMenu *popup )
+{
+ popup->disconnect( TQT_SIGNAL(activatedRedirect(int)) );
+ popup->disconnect( TQT_SIGNAL(highlightedRedirect(int)) );
+ disconnect( popup, TQT_SIGNAL(destroyed(TQObject*)),
+ this, TQT_SLOT(popupDestroyed(TQObject*)) );
+}
+
+void TQMenuBar::frameChanged()
+{
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ fromFrameChange = TRUE;
+#endif
+ menuContentsChanged();
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ fromFrameChange = FALSE;
+#endif
+}
+
+void TQMenuBar::languageChange()
+{
+ menuContentsChanged();
+}
+
+/*!
+ \internal
+
+ This function is used to adjust the menu bar's tqgeometry to the
+ tqparent widget's tqgeometry. Note that this is \e not part of the
+ public interface - the function is \c public only because
+ TQObject::eventFilter() is.
+
+ Resizes the menu bar to fit in the tqparent widget when the tqparent
+ receives a resize event.
+*/
+
+bool TQMenuBar::eventFilter( TQObject *object, TQEvent *event )
+{
+ if ( object == tqparent() && object
+#ifndef TQT_NO_TOOLBAR
+ && !::tqqt_cast<TQToolBar*>(object)
+#endif
+ && event->type() == TQEvent::Resize ) {
+ TQResizeEvent *e = (TQResizeEvent *)event;
+ int w = e->size().width();
+ setGeometry( 0, y(), w, heightForWidth(w) );
+ return FALSE;
+ }
+
+ if ( !isVisible() || !object->isWidgetType() )
+ return FALSE;
+
+ if ( TQT_BASE_OBJECT(object) == TQT_BASE_OBJECT(this) && event->type() == TQEvent::LanguageChange ) {
+ badSize = TRUE;
+ calculateRects();
+ return FALSE;
+ } else if ( event->type() == TQEvent::MouseButtonPress ||
+ event->type() == TQEvent::MouseButtonRelease ) {
+ waitforalt = 0;
+ return FALSE;
+ } else if ( waitforalt && event->type() == TQEvent::FocusOut ) {
+ // some window systems/managers use alt/meta as accelerator keys
+ // for switching between windows/desktops/etc. If the focus
+ // widget gets unfocused, then we need to stop waiting for alt
+ // NOTE: this event came from the real focus widget, so we don't
+ // need to touch the event filters
+ waitforalt = 0;
+ // although the comment above said not to remove the event filter, it is
+ // incorrect. We need to remove our self fom the focused widget as normally
+ // this happens in the key release but it does not happen in this case
+ TQWidget * f = ((TQWidget *)object)->tqfocusWidget();
+ if (f)
+ f->removeEventFilter( this );
+ return FALSE;
+ } else if ( !( event->type() == TQEvent::Accel ||
+ event->type() == TQEvent::AccelOverride ||
+ event->type() == TQEvent::KeyPress ||
+ event->type() == TQEvent::KeyRelease ) ||
+ !tqstyle().tqstyleHint(TQStyle::SH_MenuBar_AltKeyNavigation, this) ) {
+ return FALSE;
+ }
+
+ TQKeyEvent * ke = (TQKeyEvent *) event;
+#ifndef TQT_NO_ACCEL
+ // look for Alt press and Alt-anything press
+ if ( event->type() == TQEvent::Accel ) {
+ TQWidget * f = ((TQWidget *)object)->tqfocusWidget();
+ // ### this thinks alt and meta are the same
+ if ( ke->key() == Qt::Key_Alt || ke->key() == Qt::Key_Meta ) {
+ // A new Alt press and we wait for release, eat
+ // this key and don't wait for Alt on this widget
+ if ( waitforalt ) {
+ waitforalt = 0;
+ if ( object->tqparent() )
+ object->removeEventFilter( this );
+ ke->accept();
+ return TRUE;
+ // Menu has focus, send focus back
+ } else if ( hasFocus() ) {
+ setAltMode( FALSE );
+ ke->accept();
+ return TRUE;
+ // Start waiting for Alt release on focus widget
+ } else if ( ke->stateAfter() == TQt::AltButton ) {
+ waitforalt = 1;
+#if defined(TQ_WS_X11)
+ TQMenuData::d->aInt = qt_xfocusout_grab_counter;
+#endif
+ if ( f && TQT_TQOBJECT(f) != object )
+ f->installEventFilter( this );
+ }
+ // Other modifiers kills focus on menubar
+ } else if ( ke->key() == Qt::Key_Control || ke->key() == Qt::Key_Shift) {
+ setAltMode( FALSE );
+ // Got other key, no need to wait for Alt release
+ } else {
+ waitforalt = 0;
+ }
+ // ### ! block all accelerator events when the menu bar is active
+ if ( tqApp && tqApp->tqfocusWidget() == this ) {
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+#endif
+ // look for Alt release
+ if ( TQT_TQOBJECT(((TQWidget*)object)->tqfocusWidget()) == object ||
+ (object->tqparent() == 0 && ((TQWidget*)object)->tqfocusWidget() == 0) ) {
+ if ( waitforalt && event->type() == TQEvent::KeyRelease &&
+ ( ke->key() == Qt::Key_Alt || ke->key() == Qt::Key_Meta )
+#if defined(TQ_WS_X11)
+ && TQMenuData::d->aInt == qt_xfocusout_grab_counter
+#endif
+ ) {
+ setAltMode( TRUE );
+ if ( object->tqparent() )
+ object->removeEventFilter( this );
+ TQWidget * tlw = ((TQWidget *)object)->tqtopLevelWidget();
+ if ( tlw ) {
+ // ### !
+ // make sure to be the first event filter, so we can kill
+ // accelerator events before the accelerators get to them.
+ tlw->removeEventFilter( this );
+ tlw->installEventFilter( this );
+ }
+ return TRUE;
+ // Cancel if next keypress is NOT Alt/Meta,
+ } else if ( !hasFocus() && (event->type() == TQEvent::AccelOverride ) &&
+ !(((TQKeyEvent *)event)->key() == Qt::Key_Alt ||
+ ((TQKeyEvent *)event)->key() == Qt::Key_Meta) ) {
+ if ( object->tqparent() )
+ object->removeEventFilter( this );
+ setAltMode( FALSE );
+ }
+ }
+
+ return FALSE; // don't stop event
+}
+
+
+
+/*!
+ \internal
+ Receives Q_SIGNALS from menu items.
+*/
+
+void TQMenuBar::subActivated( int id )
+{
+ emit activated( id );
+}
+
+/*!
+ \internal
+ Receives Q_SIGNALS from menu items.
+*/
+
+void TQMenuBar::subHighlighted( int id )
+{
+ emit highlighted( id );
+}
+
+/*!
+ \internal
+ Receives Q_SIGNALS from menu accelerator.
+*/
+#ifndef TQT_NO_ACCEL
+void TQMenuBar::accelActivated( int id )
+{
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ if(mac_eaten_menubar)
+ return;
+#endif
+ if ( !isEnabled() ) // the menu bar is disabled
+ return;
+ setAltMode( TRUE );
+ setActiveItem( indexOf( id ) );
+}
+#endif
+
+/*!
+ \internal
+ This slot receives Q_SIGNALS from menu accelerator when it is about to be
+ destroyed.
+*/
+#ifndef TQT_NO_ACCEL
+void TQMenuBar::accelDestroyed()
+{
+ autoaccel = 0; // don't delete it twice!
+}
+#endif
+
+void TQMenuBar::popupDestroyed( TQObject *o )
+{
+ removePopup( (TQPopupMenu*)o );
+}
+
+bool TQMenuBar::tryMouseEvent( TQPopupMenu *, TQMouseEvent *e )
+{
+ TQPoint pos = mapFromGlobal( e->globalPos() );
+ if ( !TQT_TQRECT_OBJECT(rect()).tqcontains( pos ) ) // outside
+ return FALSE;
+ int item = itemAtPos( pos );
+ if ( item == -1 && (e->type() == TQEvent::MouseButtonPress ||
+ e->type() == TQEvent::MouseButtonRelease) ) {
+ hidePopups();
+ goodbye();
+ return FALSE;
+ }
+ TQMouseEvent ee( e->type(), pos, e->globalPos(), e->button(), e->state() );
+ event( &ee );
+ return TRUE;
+}
+
+
+void TQMenuBar::tryKeyEvent( TQPopupMenu *, TQKeyEvent *e )
+{
+ event( e );
+}
+
+
+void TQMenuBar::goodbye( bool cancelled )
+{
+ mouseBtDn = FALSE;
+ popupvisible = 0;
+ setAltMode( cancelled && tqstyle().tqstyleHint(TQStyle::SH_MenuBar_AltKeyNavigation, this) );
+}
+
+
+void TQMenuBar::openActPopup()
+{
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ if ( !inMenu ) {
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::MenuStart );
+ inMenu = TRUE;
+ }
+#endif
+
+ if ( actItem < 0 )
+ return;
+ TQPopupMenu *popup = mitems->at(actItem)->popup();
+ if ( !popup || !popup->isEnabled() )
+ return;
+
+ TQRect r = tqitemRect( actItem );
+ bool reverse = TQApplication::reverseLayout();
+ const int yoffset = 1; //(tqstyle().tqstyleHint( TQStyle::SH_GUIStyle ) == TQStyle::WindowsStyle) ? 4 : 1; ### this breaks designer mainwindow editing
+ TQPoint pos = r.bottomLeft() + TQPoint(0,yoffset);
+ if( reverse ) {
+ pos = r.bottomRight() + TQPoint(0,yoffset);
+ pos.rx() -= popup->tqsizeHint().width();
+ }
+
+ int ph = popup->tqsizeHint().height();
+ pos = mapToGlobal(pos);
+ int sh = TQApplication::desktop()->height();
+ if ( defaultup || (pos.y() + ph > sh) ) {
+ TQPoint t = mapToGlobal( r.topLeft() );
+ if( reverse ) {
+ t = mapToGlobal( r.topRight() );
+ t.rx() -= popup->tqsizeHint().width();
+ }
+ t.ry() -= (TQCOORD)ph;
+ if ( !defaultup || t.y() >= 0 )
+ pos = t;
+ }
+
+ //avoid circularity
+ if ( popup->isVisible() )
+ return;
+
+ TQ_ASSERT( popup->parentMenu == 0 );
+ popup->parentMenu = this; // set tqparent menu
+
+ popup->snapToMouse = FALSE;
+ popup->popup( pos );
+ popup->snapToMouse = TRUE;
+}
+
+/*!
+ \internal
+ Hides all popup menu items.
+*/
+
+void TQMenuBar::hidePopups()
+{
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ bool anyVisible = FALSE;
+#endif
+ TQMenuItemListIt it(*mitems);
+ register TQMenuItem *mi;
+ while ( (mi=it.current()) ) {
+ ++it;
+ if ( mi->popup() && mi->popup()->isVisible() ) {
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ anyVisible = TRUE;
+#endif
+ mi->popup()->hide();
+ }
+ }
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ if ( !popupvisible && anyVisible && inMenu ) {
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::MenuEnd );
+ inMenu = FALSE;
+ }
+#endif
+}
+
+
+/*!
+ Reimplements TQWidget::show() in order to set up the correct
+ keyboard accelerators and to raise itself to the top of the widget
+ stack.
+*/
+
+void TQMenuBar::show()
+{
+#ifndef TQT_NO_ACCEL
+ setupAccelerators();
+#endif
+
+ if ( parentWidget() )
+ resize( parentWidget()->width(), height() );
+
+ TQApplication::sendPostedEvents( this, TQEvent::Resize );
+ performDelayedChanges();
+ calculateRects();
+
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ if(mac_eaten_menubar) {
+ //If all elements are invisible no reason for me to be visible either
+ bool all_hidden = TRUE;
+ if(irects) {
+ for(int i = 0; all_hidden && i < (int)mitems->count(); i++)
+ all_hidden = irects[i].isEmpty();
+ }
+ if(all_hidden)
+ TQWidget::hide();
+ else
+ TQWidget::show();
+ } else {
+ TQWidget::show();
+ }
+#else
+ TQWidget::show();
+#endif
+
+#ifndef TQT_NO_MAINWINDOW
+ TQMainWindow *mw = ::tqqt_cast<TQMainWindow*>(tqparent());
+ if ( mw ) //### ugly workaround
+ mw->triggerLayout();
+#endif
+ raise();
+}
+
+/*!
+ Reimplements TQWidget::hide() in order to deselect any selected
+ item, and calls setUpLayout() for the main window.
+*/
+
+void TQMenuBar::hide()
+{
+ TQWidget::hide();
+ setAltMode( FALSE );
+ hidePopups();
+#ifndef TQT_NO_MAINWINDOW
+ TQMainWindow *mw = ::tqqt_cast<TQMainWindow*>(tqparent());
+ if ( mw ) //### ugly workaround
+ mw->triggerLayout();
+#endif
+}
+
+/*!
+ \internal
+ Needs to change the size of the menu bar when a new font is set.
+*/
+
+void TQMenuBar::fontChange( const TQFont & f )
+{
+ badSize = TRUE;
+ updateGeometry();
+ if ( isVisible() )
+ calculateRects();
+ TQWidget::fontChange( f );
+}
+
+
+/*****************************************************************************
+ Item tqgeometry functions
+ *****************************************************************************/
+
+/*
+ This function serves two different purposes. If the parameter is
+ negative, it updates the irects member for the current width and
+ resizes. Otherwise, it does the same calculations for the GIVEN
+ width and returns the height to which it WOULD have resized. A bit
+ tricky, but both operations require almost identical steps.
+*/
+int TQMenuBar::calculateRects( int max_width )
+{
+ polish();
+ bool update = ( max_width < 0 );
+
+ if ( update ) {
+ rightSide = 0;
+ if ( !badSize ) // size was not changed
+ return 0;
+ delete [] irects;
+ int i = mitems->count();
+ if ( i == 0 ) {
+ irects = 0;
+ } else {
+ irects = new TQRect[ i ];
+ TQ_CHECK_PTR( irects );
+ }
+ max_width = width();
+ }
+ TQFontMetrics fm = fontMetrics();
+ int max_height = 0;
+ int max_item_height = 0;
+ int nlitems = 0; // number on items on cur line
+ int gs = tqstyle().tqstyleHint(TQStyle::SH_GUIStyle);
+ bool reverse = TQApplication::reverseLayout();
+ int x = frameWidth();
+ int y = frameWidth();
+ if ( gs == TQt::MotifStyle ) {
+ x += motifBarHMargin;
+ y += motifBarVMargin;
+ } else if ( tqstyle().inherits("TQWindowsXPStyle") && tqstyle().tqstyleHint(TQStyle::SH_TitleBar_NoBorder) ) {
+ ;
+ } else if ( gs == TQt::WindowsStyle ) {
+ x += 2;
+ y += 2;
+ }
+ if ( reverse )
+ x = max_width - x;
+
+ int i = 0;
+ int separator = -1;
+ const int itemSpacing = tqstyle().tqpixelMetric(TQStyle::PM_MenuBarItemSpacing);
+ const int lastItem = reverse ? 0 : mitems->count() - 1;
+
+ while ( i < (int)mitems->count() ) { // for each menu item...
+ TQMenuItem *mi = mitems->at(i);
+
+ int w=0, h=0;
+ if ( !mi->isVisible()
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ || (mac_eaten_menubar && !mi->custom() && !mi->widget() )
+#endif
+ ) {
+ ; // empty rectangle
+ } else if ( mi->widget() ) {
+ if ( mi->widget()->parentWidget() != this ) {
+ mi->widget()->reparent( this, TQPoint(0,0) );
+ }
+ w = mi->widget()->tqsizeHint().expandedTo( TQApplication::globalStrut() ).width()+2;
+ h = mi->widget()->tqsizeHint().expandedTo( TQApplication::globalStrut() ).height()+2;
+ if ( i && separator < 0 )
+ separator = i;
+ } else if ( mi->pixmap() ) { // pixmap item
+ w = TQMAX( mi->pixmap()->width() + 4, TQApplication::globalStrut().width() );
+ h = TQMAX( mi->pixmap()->height() + 4, TQApplication::globalStrut().height() );
+ } else if ( !mi->text().isNull() ) { // text item
+ TQString s = mi->text();
+ w = fm.boundingRect( s ).width()
+ + 2*motifItemHMargin;
+ w -= s.tqcontains('&')*fm.width('&');
+ w += s.tqcontains("&&")*fm.width('&');
+ w = TQMAX( w, TQApplication::globalStrut().width() );
+ h = TQMAX( fm.height() + motifItemVMargin, TQApplication::globalStrut().height() );
+ } else if ( mi->isSeparator() ) { // separator item
+ if ( tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle )
+ separator = i; //### only motif?
+ }
+ if ( !mi->isSeparator() || mi->widget() ) {
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ if ( !mac_eaten_menubar ) {
+#endif
+ if ( gs == TQt::MotifStyle && mi->isVisible() ) {
+ w += 2*motifItemFrame;
+ h += 2*motifItemFrame;
+ }
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ }
+#endif
+
+ if ( ( ( !reverse && x + w + frameWidth() - max_width > 0 ) ||
+ ( reverse && x - w - itemSpacing - frameWidth() < 0 ) )
+ && nlitems > 0 ) {
+ nlitems = 0;
+ x = frameWidth();
+ y += h;
+ if ( gs == TQt::MotifStyle ) {
+ x += motifBarHMargin;
+ y += motifBarVMargin;
+ }
+ if ( reverse )
+ x = max_width - x + itemSpacing;
+ if ( tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::MotifStyle )
+ separator = -1;
+ }
+ if ( y + h + 2*frameWidth() > max_height )
+ max_height = y + h + 2*frameWidth();
+ if ( h > max_item_height )
+ max_item_height = h;
+ }
+
+ const bool isLast = (i == lastItem);
+
+ if( reverse ) {
+ x -= w;
+ if (!isLast && !mi->isSeparator())
+ x -= itemSpacing;
+ }
+ if ( update ) {
+ irects[i].setRect( x, y, w, h );
+ }
+ if ( !reverse ) {
+ x += w;
+ if (!isLast && !mi->isSeparator())
+ x += itemSpacing;
+ }
+ nlitems++;
+ i++;
+ }
+ if ( gs == TQt::WindowsStyle ) {
+ max_height += 2;
+ max_width += 2;
+ }
+
+ if ( update ) {
+ if ( separator >= 0 ) {
+ int moveBy = reverse ? - x - frameWidth() : max_width - x - frameWidth();
+ rightSide = x;
+ while( --i >= separator ) {
+ irects[i].moveBy( moveBy, 0 );
+ }
+ } else {
+ rightSide = width()-frameWidth();
+ }
+ if ( max_height != height() )
+ resize( width(), max_height );
+ for ( i = 0; i < (int)mitems->count(); i++ ) {
+ irects[i].setHeight( max_item_height );
+ TQMenuItem *mi = mitems->at(i);
+ if ( mi->widget() ) {
+ TQRect r ( TQPoint(0,0), mi->widget()->tqsizeHint() );
+ r.moveCenter( irects[i].center() );
+ mi->widget()->setGeometry( r );
+ if( mi->widget()->isHidden() )
+ mi->widget()->show();
+ }
+ }
+ badSize = FALSE;
+ }
+
+ return max_height;
+}
+
+/*!
+ Returns the height that the menu would resize itself to if its
+ tqparent (and hence itself) resized to the given \a max_width. This
+ can be useful for simple tqlayout tasks in which the height of the
+ menu bar is needed after items have been inserted. See \l
+ showimg/showimg.cpp for an example of the usage.
+*/
+int TQMenuBar::heightForWidth(int max_width) const
+{
+ // Okay to cast away const, as we are not updating.
+ if ( max_width < 0 ) max_width = 0;
+ return ((TQMenuBar*)this)->calculateRects( max_width );
+}
+
+/*!
+ \internal
+ Return the bounding rectangle for the menu item at position \a index.
+*/
+
+TQRect TQMenuBar::tqitemRect( int index )
+{
+ calculateRects();
+ return irects ? irects[index] : TQRect(0,0,0,0);
+}
+
+/*!
+ \internal
+ Return the item at \a pos, or -1 if there is no item there or if
+ it is a separator item.
+*/
+
+int TQMenuBar::itemAtPos( const TQPoint &pos_ )
+{
+ calculateRects();
+ if ( !irects )
+ return -1;
+ int i = 0;
+ TQPoint pos = pos_;
+ // Fitts' Law for edges - compensate for the extra margin
+ // added in calculateRects()
+ const int margin = 2;
+ pos.setX( TQMAX( margin, TQMIN( width() - margin, pos.x())));
+ pos.setY( TQMAX( margin, TQMIN( height() - margin, pos.y())));
+ while ( i < (int)mitems->count() ) {
+ if ( !irects[i].isEmpty() && irects[i].tqcontains( pos ) ) {
+ TQMenuItem *mi = mitems->at(i);
+ return mi->isSeparator() ? -1 : i;
+ }
+ ++i;
+ }
+ return -1; // no match
+}
+
+
+/*!
+ \property TQMenuBar::separator
+ \brief in which cases a menubar sparator is drawn
+
+ \obsolete
+*/
+void TQMenuBar::setSeparator( Separator when )
+{
+ mseparator = when;
+}
+
+TQMenuBar::Separator TQMenuBar::separator() const
+{
+ return mseparator ? InWindowsStyle : Never;
+}
+
+/*****************************************************************************
+ Event handlers
+ *****************************************************************************/
+
+/*!
+ Called from TQFrame::paintEvent(). Draws the menu bar contents
+ using painter \a p.
+*/
+
+void TQMenuBar::drawContents( TQPainter *p )
+{
+ performDelayedChanges();
+ TQRegion reg( contentsRect() );
+ TQColorGroup g = tqcolorGroup();
+ bool e;
+
+ // this shouldn't happen
+ if ( !irects )
+ return;
+
+ for ( int i=0; i<(int)mitems->count(); i++ ) {
+ TQMenuItem *mi = mitems->at( i );
+ if ( !mi->text().isNull() || mi->pixmap() ) {
+ TQRect r = irects[i];
+ if(r.isEmpty() || !mi->isVisible())
+ continue;
+ e = mi->isEnabledAndVisible();
+ if ( e )
+ g = isEnabled() ? ( isActiveWindow() ? tqpalette().active() :
+ tqpalette().inactive() ) : tqpalette().disabled();
+ else
+ g = tqpalette().disabled();
+ reg = reg.subtract( r );
+ TQSharedDoubleBuffer buffer( p, r );
+ buffer.painter()->setFont( p->font() );
+ buffer.painter()->setPen( p->pen() );
+ buffer.painter()->setBrush( p->brush() );
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled() && e)
+ flags |= TQStyle::Style_Enabled;
+ if ( i == actItem )
+ flags |= TQStyle::Style_Active;
+ if ( actItemDown )
+ flags |= TQStyle::Style_Down;
+ if (hasFocus() || hasmouse || popupvisible)
+ flags |= TQStyle::Style_HasFocus;
+ tqstyle().tqdrawControl(TQStyle::CE_MenuBarItem, buffer.painter(), this,
+ r, g, flags, TQStyleOption(mi));
+ }
+ }
+
+ p->save();
+ p->setClipRegion(reg);
+ tqstyle().tqdrawControl(TQStyle::CE_MenuBarEmptyArea, p, this, contentsRect(), g);
+ p->restore();
+
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ if ( !mac_eaten_menubar )
+#endif
+ {
+ TQt::GUIStyle gs = (TQt::GUIStyle) tqstyle().tqstyleHint(TQStyle::SH_GUIStyle);
+ if ( mseparator == InWindowsStyle && gs == TQt::WindowsStyle ) {
+ p->setPen( g.light() );
+ p->drawLine( 0, height()-1, width()-1, height()-1 );
+ p->setPen( g.dark() );
+ p->drawLine( 0, height()-2, width()-1, height()-2 );
+ }
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQMenuBar::mousePressEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+ mouseBtDn = TRUE; // mouse button down
+ int item = itemAtPos( e->pos() );
+ if ( item == actItem && popupvisible )
+ toggleclose = 1;
+ if ( item >= 0 ) {
+#ifndef USE_QT4
+ TQFocusEvent::Reason oldReason = TQFocusEvent::reason();
+#endif // USE_QT4
+ TQMenuItem *mi = tqfindItem( idAt( item ) );
+ // we know that a popup will open, so set the reason to avoid
+ // itemviews to redraw their selections
+ if ( mi && mi->popup() )
+#ifdef USE_QT4
+#warning [FIXME] How can TQFocusEvent::Popup be set as the reason for the setAltMode call?
+#else // USE_QT4
+ TQFocusEvent::setReason( TQFocusEvent::Popup );
+#endif // USE_QT4
+ setAltMode( TRUE );
+#ifndef USE_QT4
+ TQFocusEvent::setReason( oldReason );
+#endif // USE_QT4
+ }
+ setActiveItem( item, TRUE, FALSE );
+}
+
+
+/*!
+ \reimp
+*/
+void TQMenuBar::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+ if ( !mouseBtDn )
+ return;
+ mouseBtDn = FALSE; // mouse button up
+ int item = itemAtPos( e->pos() );
+ if ( (item >= 0 && !mitems->at(item)->isEnabledAndVisible()) ||
+ (actItem >= 0 && !mitems->at(actItem)->isEnabledAndVisible()) ) {
+ hidePopups();
+ setActiveItem( -1 );
+ return;
+ }
+ bool showMenu = TRUE;
+ if ( toggleclose &&
+ // pressing an item twice closes in windows, but not in motif :/
+ tqstyle().tqstyleHint(TQStyle::SH_GUIStyle) == TQt::WindowsStyle &&
+ actItem == item ) {
+ showMenu = FALSE;
+ setAltMode( FALSE );
+ }
+ setActiveItem( item, showMenu, !hasMouseTracking() );
+ toggleclose = 0;
+}
+
+
+/*!
+ \reimp
+*/
+void TQMenuBar::mouseMoveEvent( TQMouseEvent *e )
+{
+ int item = itemAtPos( e->pos() );
+ if ( !mouseBtDn && !popupvisible) {
+ if ( item >= 0 ) {
+ if ( !hasmouse ) {
+ hasmouse = 1;
+ if ( actItem == item )
+ actItem = -1; // trigger update
+ }
+ }
+ setActiveItem( item, FALSE, FALSE );
+ return;
+ }
+ if ( item != actItem && item >= 0 && ( popupvisible || mouseBtDn ) )
+ setActiveItem( item, TRUE, FALSE );
+}
+
+
+/*!
+ \reimp
+*/
+void TQMenuBar::leaveEvent( TQEvent * e )
+{
+ hasmouse = 0;
+ int actId = idAt( actItem );
+ if ( !hasFocus() && !popupvisible )
+ actItem = -1;
+ updateItem( actId );
+ TQFrame::leaveEvent( e );
+}
+
+
+/*!
+ \reimp
+*/
+void TQMenuBar::keyPressEvent( TQKeyEvent *e )
+{
+ if ( actItem < 0 )
+ return;
+
+ TQMenuItem *mi = 0;
+ int dx = 0;
+
+ if ( e->state() & ControlButton &&
+ ( e->key() == Qt::Key_Tab || e->key() == Qt::Key_Backtab ) )
+ {
+ e->ignore();
+ return;
+ }
+
+ switch ( e->key() ) {
+ case Qt::Key_Left:
+ dx = TQApplication::reverseLayout() ? 1 : -1;
+ break;
+
+ case Qt::Key_Right:
+ case Qt::Key_Tab:
+ dx = TQApplication::reverseLayout() ? -1 : 1;
+ break;
+
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ if ( tqstyle().tqstyleHint(TQStyle::SH_MenuBar_AltKeyNavigation) )
+ setActiveItem( actItem );
+ break;
+
+ case Key_Escape:
+ setAltMode( FALSE );
+ break;
+ }
+
+ if ( dx ) { // highlight next/prev
+ register int i = actItem;
+ int c = mitems->count();
+ int n = c;
+ while ( n-- ) {
+ i = i + dx;
+ if ( i == c )
+ i = 0;
+ else if ( i < 0 )
+ i = c - 1;
+ mi = mitems->at( i );
+ // ### fix windows-style traversal - currently broken due to
+ // TQMenuBar's reliance on TQPopupMenu
+ if ( /* (tqstyle() == TQt::WindowsStyle || */ mi->isEnabledAndVisible() /* ) */
+ && !mi->isSeparator() )
+ break;
+ }
+ setActiveItem( i, popupvisible );
+ } else if ( ( !e->state() || (e->state()&(TQt::MetaButton|TQt::AltButton)) ) && e->text().length()==1 && !popupvisible ) {
+ TQChar c = TQT_TQCHAR(e->text()[0]).upper();
+
+ TQMenuItemListIt it(*mitems);
+ TQMenuItem* first = 0;
+ TQMenuItem* currentSelected = 0;
+ TQMenuItem* firstAfterCurrent = 0;
+
+ register TQMenuItem *m;
+ int indx = 0;
+ int clashCount = 0;
+ while ( (m=it.current()) ) {
+ ++it;
+ TQString s = m->text();
+ if ( !s.isEmpty() ) {
+ int i = s.tqfind( '&' );
+ if ( i >= 0 )
+ {
+ if ( s[i+1].upper() == c ) {
+ clashCount++;
+ if ( !first )
+ first = m;
+ if ( indx == actItem )
+ currentSelected = m;
+ else if ( !firstAfterCurrent && currentSelected )
+ firstAfterCurrent = m;
+ }
+ }
+ }
+ indx++;
+ }
+ if ( 0 == clashCount ) {
+ return;
+ } else if ( 1 == clashCount ) {
+ indx = indexOf( first->id() );
+ } else {
+ // If there's clashes and no one is selected, use first one
+ // or if there is no clashes _after_ current, use first one
+ if ( !currentSelected || (currentSelected && !firstAfterCurrent))
+ indx = indexOf( first->id() );
+ else
+ indx = indexOf( firstAfterCurrent->id() );
+ }
+
+ setActiveItem( indx );
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQMenuBar::resizeEvent( TQResizeEvent *e )
+{
+ TQFrame::resizeEvent( e );
+ if ( badSize )
+ return;
+ badSize = TRUE;
+ calculateRects();
+}
+
+/*
+ Sets actItem to \a i and calls tqrepaint for the changed things.
+
+ Takes care to optimize the repainting. Assumes that
+ calculateRects() has been called as appropriate.
+*/
+
+void TQMenuBar::setActiveItem( int i, bool show, bool activate_first_item )
+{
+ if ( i == actItem && (uint)show == popupvisible )
+ return;
+
+ TQMenuItem* mi = 0;
+ if ( i >= 0 )
+ mi = mitems->at( i );
+ if ( mi && !mi->isEnabledAndVisible() )
+ return;
+
+ popupvisible = i >= 0 ? (show) : 0;
+ actItemDown = popupvisible;
+
+ if ( i < 0 || actItem < 0 ) {
+ // just one item needs repainting
+ int n = TQMAX( actItem, i );
+ actItem = i;
+ if ( irects && n >= 0 )
+ tqrepaint( irects[n], FALSE );
+ } else if ( TQABS(i-actItem) == 1 ) {
+ // two neighbouring items need repainting
+ int o = actItem;
+ actItem = i;
+ if ( irects )
+ tqrepaint( irects[i].unite( irects[o] ), FALSE );
+ } else {
+ // two non-neighbouring items need repainting
+ int o = actItem;
+ actItem = i;
+ if ( irects ) {
+ tqrepaint( irects[o], FALSE );
+ tqrepaint( irects[i], FALSE );
+ }
+ }
+
+ hidePopups();
+
+ if ( !popupvisible && actItem >= 0 && irects ) {
+ TQRect mfrect = irects[actItem];
+ setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE );
+ }
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ if ( mi )
+ TQAccessible::updateAccessibility( this, indexOf( mi->id() )+1, TQAccessible::Focus );
+#endif
+
+ if ( actItem < 0 || !popupvisible || !mi )
+ return;
+
+ TQPopupMenu *popup = mi->popup();
+ if ( popup ) {
+ emit highlighted( mi->id() );
+ openActPopup();
+ if ( activate_first_item )
+ popup->setFirstItemActive();
+ } else { // not a popup
+ goodbye( FALSE );
+ if ( mi->signal() ) // activate signal
+ mi->signal()->activate();
+ emit activated( mi->id() );
+ }
+}
+
+
+void TQMenuBar::setAltMode( bool enable )
+{
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ if ( inMenu && !enable ) {
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::MenuEnd );
+ inMenu = FALSE;
+ } else if ( !inMenu && enable ) {
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::MenuStart );
+ inMenu = TRUE;
+ }
+#endif
+
+ waitforalt = 0;
+ actItemDown = FALSE;
+ if ( enable ) {
+ if ( !TQMenuData::d->aWidget )
+ TQMenuData::d->aWidget = tqApp->tqfocusWidget();
+ setFocus();
+ updateItem( idAt( actItem ) );
+ } else {
+ // set the focus back to the previous widget if
+ // we still have the focus.
+ if ( tqApp->tqfocusWidget() == this ) {
+ if ( TQMenuData::d->aWidget )
+ TQMenuData::d->aWidget->setFocus();
+ else
+ clearFocus();
+ }
+ int actId = idAt( actItem );
+ actItem = -1;
+ updateItem( actId );
+ TQMenuData::d->aWidget = 0;
+ }
+}
+
+/*!
+ Sets up keyboard accelerators for the menu bar.
+*/
+#ifndef TQT_NO_ACCEL
+
+void TQMenuBar::setupAccelerators()
+{
+ delete autoaccel;
+ autoaccel = 0;
+
+ TQMenuItemListIt it(*mitems);
+ register TQMenuItem *mi;
+ while ( (mi=it.current()) ) {
+ ++it;
+ if ( !mi->isEnabledAndVisible() ) // ### when we have a good solution for the accel vs. focus widget problem, remove that. That is only a workaround
+ continue;
+ TQString s = mi->text();
+ if ( !s.isEmpty() ) {
+ int i = TQAccel::shortcutKey( s );
+ if ( i ) {
+ if ( !autoaccel ) {
+ autoaccel = new TQAccel( this );
+ TQ_CHECK_PTR( autoaccel );
+ autoaccel->setIgnoreWhatsThis( TRUE );
+ connect( autoaccel, TQT_SIGNAL(activated(int)),
+ TQT_SLOT(accelActivated(int)) );
+ connect( autoaccel, TQT_SIGNAL(activatedAmbiguously(int)),
+ TQT_SLOT(accelActivated(int)) );
+ connect( autoaccel, TQT_SIGNAL(destroyed()),
+ TQT_SLOT(accelDestroyed()) );
+ }
+ autoaccel->insertItem( i, mi->id() );
+ }
+ }
+ if ( mi->popup() ) {
+ TQPopupMenu* popup = mi->popup();
+ popup->updateAccel( this );
+ if ( !popup->isEnabled() )
+ popup->enableAccel( FALSE );
+ }
+ }
+}
+#endif
+
+/*!
+ \reimp
+ */
+bool TQMenuBar::customWhatsThis() const
+{
+ return TRUE;
+}
+
+
+
+/*!
+ \reimp
+ */
+void TQMenuBar::focusInEvent( TQFocusEvent * )
+{
+ if ( actItem < 0 ) {
+ int i = -1;
+ while ( actItem < 0 && ++i < (int) mitems->count() ) {
+ TQMenuItem* mi = mitems->at( i );
+ if ( mi && mi->isEnabledAndVisible() && !mi->isSeparator() )
+ setActiveItem( i, FALSE );
+ }
+ } else if ( !popupvisible ) {
+ updateItem( idAt( actItem ) );
+ }
+}
+
+/*!
+ \reimp
+ */
+void TQMenuBar::focusOutEvent( TQFocusEvent * )
+{
+ updateItem( idAt( actItem ) );
+ if ( !popupvisible )
+ setAltMode( FALSE );
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQMenuBar::tqsizeHint() const
+{
+ int h = height();
+ if ( badSize )
+ h = ( (TQMenuBar*)this )->calculateRects();
+ TQSize s( 2*frameWidth(),0);
+ if ( irects ) {
+ for ( int i = 0; i < (int)mitems->count(); ++i )
+ s.setWidth( s.width() + irects[ i ].width() + 2 );
+ }
+ s.setHeight( h );
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_MenuBar, this, s.
+ expandedTo(TQApplication::globalStrut())));
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQMenuBar::tqminimumSize() const
+{
+#ifndef TQT_NO_TOOLBAR
+ TQToolBar *tb = ::tqqt_cast<TQToolBar*>(tqparent());
+ if ( tb )
+ return tqsizeHint();
+#endif
+ return TQFrame::tqminimumSize();
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQMenuBar::tqminimumSizeHint() const
+{
+ return tqminimumSize();
+}
+
+/*!
+ \property TQMenuBar::defaultUp
+ \brief the popup orientation
+
+ The default popup orientation. By default, menus pop "down" the
+ screen. By setting the property to TRUE, the menu will pop "up".
+ You might call this for menus that are \e below the document to
+ which they refer.
+
+ If the menu would not fit on the screen, the other direction is
+ used automatically.
+*/
+void TQMenuBar::setDefaultUp( bool on )
+{
+ defaultup = on;
+}
+
+bool TQMenuBar::isDefaultUp() const
+{
+ return defaultup;
+}
+
+
+/*!
+ \reimp
+ */
+void TQMenuBar::activateItemAt( int index )
+{
+ if ( index >= 0 && index < (int) mitems->count() )
+ setActiveItem( index );
+ else
+ goodbye( FALSE );
+}
+
+#endif // TQT_NO_MENUBAR
diff --git a/tqtinterface/qt4/src/widgets/tqmenubar.h b/tqtinterface/qt4/src/widgets/tqmenubar.h
new file mode 100644
index 0000000..6b32031
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqmenubar.h
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Definition of TQMenuBar class
+**
+** Created : 941209
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMENUBAR_H
+#define TQMENUBAR_H
+
+#ifndef TQT_H
+#include "tqpopupmenu.h" // ### remove or keep for users' convenience?
+#include "tqframe.h"
+#include "tqmenudata.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_MENUBAR
+
+class TQPopupMenu;
+
+class TQ_EXPORT TQMenuBar : public TQFrame, public TQMenuData
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( Separator )
+ Q_PROPERTY( Separator separator READ separator WRITE setSeparator DESIGNABLE false )
+ Q_PROPERTY( bool defaultUp READ isDefaultUp WRITE setDefaultUp )
+
+public:
+ TQMenuBar( TQWidget* tqparent=0, const char* name=0 );
+ ~TQMenuBar();
+
+ void updateItem( int id );
+
+ void show(); // reimplemented show
+ void hide(); // reimplemented hide
+
+ bool eventFilter( TQObject *, TQEvent * );
+
+ int heightForWidth(int) const;
+
+ enum Separator { Never=0, InWindowsStyle=1 };
+ Separator separator() const;
+ virtual void setSeparator( Separator when );
+
+ void setDefaultUp( bool );
+ bool isDefaultUp() const;
+
+ bool customWhatsThis() const;
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSize() const;
+ TQSize tqminimumSizeHint() const;
+
+ void activateItemAt( int index );
+
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ static void initialize();
+ static void cleanup();
+#endif
+
+Q_SIGNALS:
+ void activated( int itemId );
+ void highlighted( int itemId );
+
+protected:
+ void drawContents( TQPainter * );
+ void fontChange( const TQFont & );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void keyPressEvent( TQKeyEvent * );
+ void focusInEvent( TQFocusEvent * );
+ void focusOutEvent( TQFocusEvent * );
+ void resizeEvent( TQResizeEvent * );
+ void leaveEvent( TQEvent * );
+ void menuContentsChanged();
+ void menuStateChanged();
+ void styleChange( TQStyle& );
+ int itemAtPos( const TQPoint & );
+ void hidePopups();
+ TQRect tqitemRect( int item );
+
+private Q_SLOTS:
+ void subActivated( int itemId );
+ void subHighlighted( int itemId );
+#ifndef TQT_NO_ACCEL
+ void accelActivated( int itemId );
+ void accelDestroyed();
+#endif
+ void popupDestroyed( TQObject* );
+ void performDelayedChanges();
+
+ void languageChange();
+
+private:
+ void performDelayedContentsChanged();
+ void performDelayedStateChanged();
+ void menuInsPopup( TQPopupMenu * );
+ void menuDelPopup( TQPopupMenu * );
+ void frameChanged();
+
+ bool tryMouseEvent( TQPopupMenu *, TQMouseEvent * );
+ void tryKeyEvent( TQPopupMenu *, TQKeyEvent * );
+ void goodbye( bool cancelled = FALSE );
+ void openActPopup();
+
+ void setActiveItem( int index, bool show = TRUE, bool activate_first_item = TRUE );
+ void setAltMode( bool );
+
+ int calculateRects( int max_width = -1 );
+
+#ifndef TQT_NO_ACCEL
+ void setupAccelerators();
+ TQAccel *autoaccel;
+#endif
+ TQRect *irects;
+ int rightSide;
+
+ uint mseparator : 1;
+ uint waitforalt : 1;
+ uint popupvisible : 1;
+ uint hasmouse : 1;
+ uint defaultup : 1;
+ uint toggleclose : 1;
+ uint pendingDelayedContentsChanges : 1;
+ uint pendingDelayedStateChanges : 1;
+
+ friend class TQPopupMenu;
+
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ friend class TQWidget;
+ friend class TQApplication;
+ friend void qt_mac_set_modal_state(bool, TQMenuBar *);
+
+ void macCreateNativeMenubar();
+ void macRemoveNativeMenubar();
+ void macDirtyNativeMenubar();
+
+#if !defined(TQMAC_TQMENUBAR_NO_EVENT)
+ static void qt_mac_install_menubar_event(MenuRef);
+ static OStqStatus qt_mac_menubar_event(EventHandlerCallRef, EventRef, void *);
+#endif
+ virtual void macWidgetChangedWindow();
+ bool syncPopups(MenuRef ret, TQPopupMenu *d);
+ MenuRef createMacPopup(TQPopupMenu *d, int id, bool =FALSE);
+ bool updateMenuBar();
+#if !defined(TQMAC_TQMENUBAR_NO_MERGE)
+ uint isCommand(TQMenuItem *, bool just_check=FALSE);
+#endif
+
+ uint mac_eaten_menubar : 1;
+ class MacPrivate;
+ MacPrivate *mac_d;
+ static bool activate(MenuRef, short, bool highlight=FALSE, bool by_accel=FALSE);
+ static bool activateCommand(uint cmd);
+ static bool macUpdateMenuBar();
+ static bool macUpdatePopupVisible(MenuRef, bool);
+ static bool macUpdatePopup(MenuRef);
+#endif
+
+private: // Disabled copy constructor and operator=
+
+#if defined(TQ_DISABLE_COPY)
+ TQMenuBar( const TQMenuBar & );
+ TQMenuBar &operator=( const TQMenuBar & );
+#endif
+};
+
+
+#endif // TQT_NO_MENUBAR
+
+#endif // TQMENUBAR_H
diff --git a/tqtinterface/qt4/src/widgets/tqmenudata.cpp b/tqtinterface/qt4/src/widgets/tqmenudata.cpp
new file mode 100644
index 0000000..2f0fd80
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqmenudata.cpp
@@ -0,0 +1,1606 @@
+/****************************************************************************
+**
+** Implementation of TQMenuData class
+**
+** Created : 941128
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmenudata.h"
+#ifndef TQT_NO_MENUDATA
+#include "tqpopupmenu.h"
+#include "tqmenubar.h"
+#include "tqapplication.h"
+#include "tqguardedptr.h"
+
+class TQMenuItemData {
+public:
+ TQCustomMenuItem *custom_item; // custom menu item
+};
+
+class TQMenuDataData {
+ // attention: also defined in qmenubar.cpp and qpopupmenu.cpp
+public:
+ TQMenuDataData();
+ TQGuardedPtr<TQWidget> aWidget;
+ int aInt;
+};
+TQMenuDataData::TQMenuDataData()
+ : aInt(-1)
+{}
+
+/*!
+ \class TQMenuData tqmenudata.h
+ \brief The TQMenuData class is a base class for TQMenuBar and TQPopupMenu.
+
+ \ingroup misc
+
+ TQMenuData has an internal list of menu items. A menu item can have
+ a text(), an \link accel() accelerator\endlink, a pixmap(), an
+ iconSet(), a whatsThis() text and a popup menu (unless it is a
+ separator). Menu items may optionally be \link setItemChecked()
+ checked\endlink (except for separators).
+
+ The menu item sends out an \link TQMenuBar::activated()
+ activated()\endlink signal when it is chosen and a \link
+ TQMenuBar::highlighted() highlighted()\endlink signal when it
+ receives the user input focus.
+
+ \keyword menu identifier
+
+ Menu items are assigned the menu identifier \e id that is passed
+ in insertItem() or an automatically generated identifier if \e id
+ is < 0 (the default). The generated identifiers (negative
+ integers) are guaranteed to be unique within the entire
+ application. The identifier is used to access the menu item in
+ other functions.
+
+ Menu items can be removed with removeItem() and removeItemAt(), or
+ changed with changeItem(). All menu items can be removed with
+ clear(). Accelerators can be changed or set with setAccel().
+ Checkable items can be checked or unchecked with setItemChecked().
+ Items can be enabled or disabled using setItemEnabled() and
+ connected and disconnected with connectItem() and disconnectItem()
+ respectively. By default, newly created menu items are visible.
+ They can be hidden (and shown again) with setItemVisible().
+
+ Menu items are stored in a list. Use tqfindItem() to tqfind an item by
+ its list position or by its menu identifier. (See also indexOf()
+ and idAt().)
+
+ \sa TQAccel TQPopupMenu TQAction
+*/
+
+
+/*****************************************************************************
+ TQMenuItem member functions
+ *****************************************************************************/
+
+TQMenuItem::TQMenuItem()
+ :ident( -1 ), iconset_data( 0 ), pixmap_data( 0 ), popup_menu( 0 ),
+ widget_item( 0 ), signal_data( 0 ), is_separator( FALSE ), is_enabled( TRUE ),
+ is_checked( FALSE ), is_dirty( TRUE ), is_visible( TRUE ), d( 0)
+{}
+
+TQMenuItem::~TQMenuItem()
+{
+ delete iconset_data;
+ delete pixmap_data;
+ delete signal_data;
+ delete widget_item;
+ if ( d )
+ delete d->custom_item;
+ delete d;
+}
+
+
+/*****************************************************************************
+ TQMenuData member functions
+ *****************************************************************************/
+
+TQMenuItemData* TQMenuItem::extra()
+{
+ if ( !d ) d = new TQMenuItemData;
+ return d;
+}
+
+TQCustomMenuItem *TQMenuItem::custom() const
+{
+ if ( !d ) return 0;
+ return d->custom_item;
+}
+
+
+static int get_seq_id()
+{
+ static int seq_no = -2;
+ return seq_no--;
+}
+
+
+/*!
+ Constructs an empty menu data list.
+*/
+
+TQMenuData::TQMenuData()
+{
+ actItem = -1; // no active menu item
+ mitems = new TQMenuItemList; // create list of menu items
+ TQ_CHECK_PTR( mitems );
+ mitems->setAutoDelete( TRUE );
+ parentMenu = 0; // assume top level
+ isPopupMenu = FALSE;
+ isMenuBar = FALSE;
+ mouseBtDn = FALSE;
+ badSize = TRUE;
+ avoid_circularity = 0;
+ actItemDown = FALSE;
+ d = new TQMenuDataData;
+}
+
+/*!
+ Removes all menu items and disconnects any Q_SIGNALS that have been
+ connected.
+*/
+
+TQMenuData::~TQMenuData()
+{
+ delete mitems; // delete menu item list
+ delete d;
+}
+
+
+/*!
+ Virtual function; notifies subclasses about an item with \a id
+ that has been changed.
+*/
+
+void TQMenuData::updateItem( int /* id */ ) // reimplemented in subclass
+{
+}
+
+/*!
+ Virtual function; notifies subclasses that one or more items have
+ been inserted or removed.
+*/
+
+void TQMenuData::menuContentsChanged() // reimplemented in subclass
+{
+}
+
+/*!
+ Virtual function; notifies subclasses that one or more items have
+ changed state (enabled/disabled or checked/unchecked).
+*/
+
+void TQMenuData::menuStateChanged() // reimplemented in subclass
+{
+}
+
+/*!
+ Virtual function; notifies subclasses that a popup menu item has
+ been inserted.
+*/
+
+void TQMenuData::menuInsPopup( TQPopupMenu * ) // reimplemented in subclass
+{
+}
+
+/*!
+ Virtual function; notifies subclasses that a popup menu item has
+ been removed.
+*/
+
+void TQMenuData::menuDelPopup( TQPopupMenu * ) // reimplemented in subclass
+{
+}
+
+
+/*!
+ Returns the number of items in the menu.
+*/
+
+uint TQMenuData::count() const
+{
+ return mitems->count();
+}
+
+
+
+/*!
+ \internal
+
+ Internal function that insert a menu item. Called by all insert()
+ functions.
+*/
+
+int TQMenuData::insertAny( const TQString *text, const TQPixmap *pixmap,
+ TQPopupMenu *popup, const TQIconSet* iconset, int id, int index,
+ TQWidget* widget, TQCustomMenuItem* custom )
+{
+ if ( index < 0 ) { // append, but not if the rightmost item is an mdi separator in the menubar
+ index = mitems->count();
+ if ( isMenuBar && mitems->last() && mitems->last()->widget() && mitems->last()->isSeparator() )
+ index--;
+ } else if ( index > (int) mitems->count() ) { // append
+ index = mitems->count();
+ }
+ if ( id < 0 ) // -2, -3 etc.
+ id = get_seq_id();
+
+ register TQMenuItem *mi = new TQMenuItem;
+ TQ_CHECK_PTR( mi );
+ mi->ident = id;
+ if ( widget != 0 ) {
+ mi->widget_item = widget;
+ mi->is_separator = !widget->isFocusEnabled();
+ } else if ( custom != 0 ) {
+ mi->extra()->custom_item = custom;
+ mi->is_separator = custom->isSeparator();
+ if ( iconset && !iconset->isNull() )
+ mi->iconset_data = new TQIconSet( *iconset );
+ } else if ( text == 0 && pixmap == 0 && popup == 0 ) {
+ mi->is_separator = TRUE; // separator
+ } else {
+#ifndef TQ_OS_TEMP
+ mi->text_data = text?*text:TQString();
+#else
+ TQString newText( *text );
+ newText.truncate( newText.tqfindRev( '\t' ) );
+ mi->text_data = newText.isEmpty()?TQString():newText;
+#endif
+#ifndef TQT_NO_ACCEL
+ mi->accel_key = TQt::Key_unknown;
+#endif
+ if ( pixmap && !pixmap->isNull() )
+ mi->pixmap_data = new TQPixmap( *pixmap );
+ if ( (mi->popup_menu = popup) )
+ menuInsPopup( popup );
+ if ( iconset && !iconset->isNull() )
+ mi->iconset_data = new TQIconSet( *iconset );
+ }
+
+ mitems->insert( index, mi );
+ TQPopupMenu* p = ::tqqt_cast<TQPopupMenu*>(TQMenuData::d->aWidget);
+ if (p && p->isVisible() && p->mitems) {
+ p->mitems->clear();
+ for ( TQMenuItemListIt it( *mitems ); it.current(); ++it ) {
+ if ( it.current()->id() != TQMenuData::d->aInt && !it.current()->widget() )
+ p->mitems->append( it.current() );
+ }
+ }
+ menuContentsChanged(); // menu data changed
+ return mi->ident;
+}
+
+/*!
+ \internal
+
+ Internal function that tqfinds the menu item where \a popup is located,
+ storing its index at \a index if \a index is not NULL.
+*/
+TQMenuItem *TQMenuData::tqfindPopup( TQPopupMenu *popup, int *index )
+{
+ int i = 0;
+ TQMenuItem *mi = mitems->first();
+ while ( mi ) {
+ if ( mi->popup_menu == popup ) // found popup
+ break;
+ i++;
+ mi = mitems->next();
+ }
+ if ( index && mi )
+ *index = i;
+ return mi;
+}
+
+void TQMenuData::removePopup( TQPopupMenu *popup )
+{
+ int index = 0;
+ TQMenuItem *mi = tqfindPopup( popup, &index );
+ if ( mi ) {
+ mi->popup_menu = 0;
+ removeItemAt( index );
+ }
+}
+
+
+/*!
+ The family of insertItem() functions inserts menu items into a
+ popup menu or a menu bar.
+
+ A menu item is usually either a text string or a pixmap, both with
+ an optional icon or keyboard accelerator. For special cases it is
+ also possible to insert custom items (see \l{TQCustomMenuItem}) or
+ even widgets into popup menus.
+
+ Some insertItem() members take a popup menu as an additional
+ argument. Use this to insert submenus into existing menus or
+ pulldown menus into a menu bar.
+
+ The number of insert functions may look confusing, but they are
+ actually quite simple to use.
+
+ This default version inserts a menu item with the text \a text,
+ the accelerator key \a accel, an id and an optional index and
+ connects it to the slot \a member in the object \a receiver.
+
+ Example:
+ \code
+ TQMenuBar *mainMenu = new TQMenuBar;
+ TQPopupMenu *fileMenu = new TQPopupMenu;
+ fileMenu->insertItem( "New", myView, TQT_SLOT(newFile()), CTRL+Key_N );
+ fileMenu->insertItem( "Open", myView, TQT_SLOT(open()), CTRL+Key_O );
+ mainMenu->insertItem( "File", fileMenu );
+ \endcode
+
+ Not all insert functions take an object/slot parameter or an
+ accelerator key. Use connectItem() and setAccel() on those items.
+
+ If you need to translate accelerators, use tr() with the text and
+ accelerator. (For translations use a string \link TQKeySequence key
+ sequence\endlink.):
+ \code
+ fileMenu->insertItem( tr("Open"), myView, TQT_SLOT(open()),
+ tr("Ctrl+O") );
+ \endcode
+
+ In the example above, pressing Ctrl+O or selecting "Open" from the
+ menu activates the myView->open() function.
+
+ Some insert functions take a TQIconSet parameter to specify the
+ little menu item icon. Note that you can always pass a TQPixmap
+ object instead.
+
+ The \a id specifies the identification number associated with the
+ menu item. Note that only positive values are valid, as a negative
+ value will make TQt select a unique id for the item.
+
+ The \a index specifies the position in the menu. The menu item is
+ appended at the end of the list if \a index is negative.
+
+ Note that keyboard accelerators in TQt are not application-global,
+ instead they are bound to a certain top-level window. For example,
+ accelerators in TQPopupMenu items only work for menus that are
+ associated with a certain window. This is true for popup menus
+ that live in a menu bar since their accelerators will then be
+ installed in the menu bar itself. This also applies to stand-alone
+ popup menus that have a top-level widget in their parentWidget()
+ chain. The menu will then install its accelerator object on that
+ top-level widget. For all other cases use an independent TQAccel
+ object.
+
+ \warning Be careful when passing a literal 0 to insertItem()
+ because some C++ compilers choose the wrong overloaded function.
+ Cast the 0 to what you mean, e.g. \c{(TQObject*)0}.
+
+ \warning On Mac OS X, items that connect to a slot that are inserted into a
+ menubar will not function as we use the native menubar that knows nothing
+ about Q_SIGNALS or Q_SLOTS. Instead insert the items into a popup menu and
+ insert the popup menu into the menubar. This may be fixed in a future TQt
+ version.
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem(), TQAccel,
+ tqnamespace.h
+*/
+
+int TQMenuData::insertItem( const QString &text,
+ const TQT_BASE_OBJECT_NAME *receiver, const char* member,
+ const TQKeySequence& accel, int id, int index )
+{
+ TQString tqtext = TQString(text);
+ int actualID = insertAny( &tqtext, 0, 0, 0, id, index );
+ connectItem( actualID, receiver, member );
+#ifndef TQT_NO_ACCEL
+ if ( accel )
+ setAccel( accel, actualID );
+#endif
+ return actualID;
+}
+
+/*!
+ \overload
+
+ Inserts a menu item with icon \a icon, text \a text, accelerator
+ \a accel, optional id \a id, and optional \a index position. The
+ menu item is connected it to the \a receiver's \a member slot. The
+ icon will be displayed to the left of the text in the item.
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem(), TQAccel,
+ tqnamespace.h
+*/
+
+int TQMenuData::insertItem( const TQIconSet& icon,
+ const TQString &text,
+ const TQT_BASE_OBJECT_NAME *receiver, const char* member,
+ const TQKeySequence& accel, int id, int index )
+{
+ int actualID = insertAny( &text, 0, 0, &icon, id, index );
+ connectItem( actualID, receiver, member );
+#ifndef TQT_NO_ACCEL
+ if ( accel )
+ setAccel( accel, actualID );
+#endif
+ return actualID;
+}
+
+/*!
+ \overload
+
+ Inserts a menu item with pixmap \a pixmap, accelerator \a accel,
+ optional id \a id, and optional \a index position. The menu item
+ is connected it to the \a receiver's \a member slot. The icon will
+ be displayed to the left of the text in the item.
+
+ To look best when being highlighted as a menu item, the pixmap
+ should provide a tqmask (see TQPixmap::tqmask()).
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem()
+*/
+
+int TQMenuData::insertItem( const QPixmap &pixmap,
+ const TQT_BASE_OBJECT_NAME *receiver, const char* member,
+ const TQKeySequence& accel, int id, int index )
+{
+ int actualID = insertAny( 0, &TQT_TQPIXMAP_OBJECT(pixmap), 0, 0, id, index );
+ connectItem( actualID, receiver, member );
+#ifndef TQT_NO_ACCEL
+ if ( accel )
+ setAccel( accel, actualID );
+#endif
+ return actualID;
+}
+
+
+/*!
+ \overload
+
+ Inserts a menu item with icon \a icon, pixmap \a pixmap,
+ accelerator \a accel, optional id \a id, and optional \a index
+ position. The icon will be displayed to the left of the pixmap in
+ the item. The item is connected to the \a member slot in the \a
+ receiver object.
+
+ To look best when being highlighted as a menu item, the pixmap
+ should provide a tqmask (see TQPixmap::tqmask()).
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem(), TQAccel,
+ tqnamespace.h
+*/
+
+int TQMenuData::insertItem( const TQIconSet& icon,
+ const TQPixmap &pixmap,
+ const TQT_BASE_OBJECT_NAME *receiver, const char* member,
+ const TQKeySequence& accel, int id, int index )
+{
+ int actualID = insertAny( 0, &pixmap, 0, &icon, id, index );
+ connectItem( actualID, receiver, member );
+#ifndef TQT_NO_ACCEL
+ if ( accel )
+ setAccel( accel, actualID );
+#endif
+ return actualID;
+}
+
+
+
+/*!
+ \overload
+
+ Inserts a menu item with text \a text, optional id \a id, and
+ optional \a index position.
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem()
+*/
+
+int TQMenuData::insertItem( const QString &text, int id, int index )
+{
+ TQString tqtext = TQString(text);
+ return insertAny( &tqtext, 0, 0, 0, id, index );
+}
+
+/*!
+ \overload
+
+ Inserts a menu item with icon \a icon, text \a text, optional id
+ \a id, and optional \a index position. The icon will be displayed
+ to the left of the text in the item.
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem()
+*/
+
+int TQMenuData::insertItem( const TQIconSet& icon,
+ const TQString &text, int id, int index )
+{
+ return insertAny( &text, 0, 0, &icon, id, index );
+}
+
+/*!
+ \overload
+
+ Inserts a menu item with text \a text, submenu \a popup, optional
+ id \a id, and optional \a index position.
+
+ The \a popup must be deleted by the programmer or by its tqparent
+ widget. It is not deleted when this menu item is removed or when
+ the menu is deleted.
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem()
+*/
+
+int TQMenuData::insertItem( const QString &text, TQPopupMenu *popup,
+ int id, int index )
+{
+ TQString tqtext = TQString(text);
+ return insertAny( &tqtext, 0, popup, 0, id, index );
+}
+
+/*!
+ \overload
+
+ Inserts a menu item with icon \a icon, text \a text, submenu \a
+ popup, optional id \a id, and optional \a index position. The icon
+ will be displayed to the left of the text in the item.
+
+ The \a popup must be deleted by the programmer or by its tqparent
+ widget. It is not deleted when this menu item is removed or when
+ the menu is deleted.
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem()
+*/
+
+int TQMenuData::insertItem( const TQIconSet& icon,
+ const TQString &text, TQPopupMenu *popup,
+ int id, int index )
+{
+ return insertAny( &text, 0, popup, &icon, id, index );
+}
+
+/*!
+ \overload
+
+ Inserts a menu item with pixmap \a pixmap, optional id \a id, and
+ optional \a index position.
+
+ To look best when being highlighted as a menu item, the pixmap
+ should provide a tqmask (see TQPixmap::tqmask()).
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem()
+*/
+
+int TQMenuData::insertItem( const QPixmap &pixmap, int id, int index )
+{
+ return insertAny( 0, &TQT_TQPIXMAP_OBJECT(pixmap), 0, 0, id, index );
+}
+
+/*!
+ \overload
+
+ Inserts a menu item with icon \a icon, pixmap \a pixmap, optional
+ id \a id, and optional \a index position. The icon will be
+ displayed to the left of the pixmap in the item.
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem()
+*/
+
+int TQMenuData::insertItem( const TQIconSet& icon,
+ const TQPixmap &pixmap, int id, int index )
+{
+ return insertAny( 0, &pixmap, 0, &icon, id, index );
+}
+
+
+/*!
+ \overload
+
+ Inserts a menu item with pixmap \a pixmap, submenu \a popup,
+ optional id \a id, and optional \a index position.
+
+ The \a popup must be deleted by the programmer or by its tqparent
+ widget. It is not deleted when this menu item is removed or when
+ the menu is deleted.
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem()
+*/
+
+int TQMenuData::insertItem( const QPixmap &pixmap, TQPopupMenu *popup,
+ int id, int index )
+{
+ return insertAny( 0, &TQT_TQPIXMAP_OBJECT(pixmap), popup, 0, id, index );
+}
+
+
+/*!
+ \overload
+
+ Inserts a menu item with icon \a icon, pixmap \a pixmap submenu \a
+ popup, optional id \a id, and optional \a index position. The icon
+ will be displayed to the left of the pixmap in the item.
+
+ The \a popup must be deleted by the programmer or by its tqparent
+ widget. It is not deleted when this menu item is removed or when
+ the menu is deleted.
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem(), changeItem(), setAccel(), connectItem()
+*/
+
+int TQMenuData::insertItem( const TQIconSet& icon,
+ const TQPixmap &pixmap, TQPopupMenu *popup,
+ int id, int index )
+{
+ return insertAny( 0, &pixmap, popup, &icon, id, index );
+}
+
+
+
+/*!
+ \overload
+
+ Inserts a menu item that consists of the widget \a widget with
+ optional id \a id, and optional \a index position.
+
+ Ownership of \a widget is transferred to the popup menu or to the
+ menu bar.
+
+ Theoretically, any widget can be inserted into a popup menu. In
+ practice, this only makes sense with certain widgets.
+
+ If a widget is not focus-enabled (see
+ \l{TQWidget::isFocusEnabled()}), the menu treats it as a separator;
+ this means that the item is not selectable and will never get
+ focus. In this way you can, for example, simply insert a TQLabel if
+ you need a popup menu with a title.
+
+ If the widget is focus-enabled it will get focus when the user
+ traverses the popup menu with the arrow keys. If the widget does
+ not accept \c ArrowUp and \c ArrowDown in its key event handler,
+ the focus will move back to the menu when the respective arrow key
+ is hit one more time. This works with a TQLineEdit, for example. If
+ the widget accepts the arrow key itself, it must also provide the
+ possibility to put the focus back on the menu again by calling
+ TQWidget::focusNextPrevChild(). Futhermore, if the embedded widget
+ closes the menu when the user made a selection, this can be done
+ safely by calling:
+ \code
+ if ( isVisible() &&
+ parentWidget() &&
+ parentWidget()->inherits("TQPopupMenu") )
+ parentWidget()->close();
+ \endcode
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa removeItem()
+*/
+int TQMenuData::insertItem( QWidget* widget, int id, int index )
+{
+ return insertAny( 0, 0, 0, 0, id, index, TQT_TQWIDGET(widget) );
+}
+
+
+/*!
+ \overload
+
+ Inserts a custom menu item \a custom with optional id \a id, and
+ optional \a index position.
+
+ This only works with popup menus. It is not supported for menu
+ bars. Ownership of \a custom is transferred to the popup menu.
+
+ If you want to connect a custom item to a slot, use connectItem().
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa connectItem(), removeItem(), TQCustomMenuItem
+*/
+int TQMenuData::insertItem( TQCustomMenuItem* custom, int id, int index )
+{
+ return insertAny( 0, 0, 0, 0, id, index, 0, custom );
+}
+
+/*!
+ \overload
+
+ Inserts a custom menu item \a custom with an \a icon and with
+ optional id \a id, and optional \a index position.
+
+ This only works with popup menus. It is not supported for menu
+ bars. Ownership of \a custom is transferred to the popup menu.
+
+ If you want to connect a custom item to a slot, use connectItem().
+
+ Returns the allocated menu identifier number (\a id if \a id >= 0).
+
+ \sa connectItem(), removeItem(), TQCustomMenuItem
+*/
+int TQMenuData::insertItem( const TQIconSet& icon, TQCustomMenuItem* custom, int id, int index )
+{
+ return insertAny( 0, 0, 0, &icon, id, index, 0, custom );
+}
+
+
+/*!
+ Inserts a separator at position \a index, and returns the menu identifier
+ number allocated to it. The separator becomes the last menu item if
+ \a index is negative.
+
+ In a popup menu a separator is rendered as a horizontal line. In a
+ Motif menu bar a separator is spacing, so the rest of the items
+ (normally just "Help") are drawn right-justified. In a Windows
+ menu bar separators are ignored (to comply with the Windows style
+ guidelines).
+*/
+int TQMenuData::insertSeparator( int index )
+{
+ return insertAny( 0, 0, 0, 0, -1, index );
+}
+
+/*!
+ \fn void TQMenuData::removeItem( int id )
+
+ Removes the menu item that has the identifier \a id.
+
+ \sa removeItemAt(), clear()
+*/
+
+void TQMenuData::removeItem( int id )
+{
+ TQMenuData *tqparent;
+ if ( tqfindItem( id, &tqparent ) )
+ tqparent->removeItemAt(tqparent->indexOf(id));
+}
+
+/*!
+ Removes the menu item at position \a index.
+
+ \sa removeItem(), clear()
+*/
+
+void TQMenuData::removeItemAt( int index )
+{
+ if ( index < 0 || index >= (int)mitems->count() ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQMenuData::removeItem: Index %d out of range", index );
+#endif
+ return;
+ }
+ TQMenuItem *mi = mitems->at( index );
+ if ( mi->popup_menu )
+ menuDelPopup( mi->popup_menu );
+ mitems->remove();
+ TQPopupMenu* p = ::tqqt_cast<TQPopupMenu*>(TQMenuData::d->aWidget);
+ if (p && p->isVisible() && p->mitems) {
+ p->mitems->clear();
+ for ( TQMenuItemListIt it( *mitems ); it.current(); ++it ) {
+ if ( it.current()->id() != TQMenuData::d->aInt && !it.current()->widget() )
+ p->mitems->append( it.current() );
+ }
+ }
+ if ( !TQApplication::closingDown() ) // avoid trouble
+ menuContentsChanged();
+}
+
+
+/*!
+ Removes all menu items.
+
+ \sa removeItem(), removeItemAt()
+*/
+
+void TQMenuData::clear()
+{
+ register TQMenuItem *mi = mitems->first();
+ while ( mi ) {
+ if ( mi->popup_menu )
+ menuDelPopup( mi->popup_menu );
+ mitems->remove();
+ mi = mitems->current();
+ }
+ TQPopupMenu* p = ::tqqt_cast<TQPopupMenu*>(TQMenuData::d->aWidget);
+ if (p && p->isVisible() && p->mitems) {
+ p->mitems->clear();
+ }
+ if ( !TQApplication::closingDown() ) // avoid trouble
+ menuContentsChanged();
+}
+
+#ifndef TQT_NO_ACCEL
+
+/*!
+ Returns the accelerator key that has been defined for the menu
+ item \a id, or 0 if it has no accelerator key or if there is no
+ such menu item.
+
+ \sa setAccel(), TQAccel, tqnamespace.h
+*/
+
+TQKeySequence TQMenuData::accel( int id ) const
+{
+ TQMenuItem *mi = tqfindItem( id );
+ if ( mi )
+ return mi->key();
+ return TQKeySequence();
+}
+
+/*!
+ Sets the accelerator key for the menu item \a id to \a key.
+
+ An accelerator key consists of a key code and a combination of the
+ modifiers \c SHIFT, \c CTRL, \c ALT or \c UNICODE_ACCEL (OR'ed or
+ added). The header file \c tqnamespace.h tqcontains a list of key
+ codes.
+
+ Defining an accelerator key produces a text that is added to the
+ menu item; for instance, \c CTRL + \c Key_O produces "Ctrl+O". The
+ text is formatted differently for different platforms.
+
+ Note that keyboard accelerators in TQt are not application-global,
+ instead they are bound to a certain top-level window. For example,
+ accelerators in TQPopupMenu items only work for menus that are
+ associated with a certain window. This is true for popup menus
+ that live in a menu bar since their accelerators will then be
+ installed in the menu bar itself. This also applies to stand-alone
+ popup menus that have a top-level widget in their parentWidget()
+ chain. The menu will then install its accelerator object on that
+ top-level widget. For all other cases use an independent TQAccel
+ object.
+
+ Example:
+ \code
+ TQMenuBar *mainMenu = new TQMenuBar;
+ TQPopupMenu *fileMenu = new TQPopupMenu; // file sub menu
+ fileMenu->insertItem( "Open Document", 67 ); // add "Open" item
+ fileMenu->setAccel( CTRL + Key_O, 67 ); // Ctrl+O to open
+ fileMenu->insertItem( "Quit", 69 ); // add "Quit" item
+ fileMenu->setAccel( CTRL + ALT + Key_Delete, 69 ); // add Alt+Del to quit
+ mainMenu->insertItem( "File", fileMenu ); // add the file menu
+ \endcode
+
+ If you need to translate accelerators, use tr() with a string:
+ \code
+ fileMenu->setAccel( tr("Ctrl+O"), 67 );
+ \endcode
+
+ You can also specify the accelerator in the insertItem() function.
+ You may prefer to use TQAction to associate accelerators with menu
+ items.
+
+ \sa accel() insertItem() TQAccel TQAction
+*/
+
+void TQMenuData::setAccel( const TQKeySequence& key, int id )
+{
+ TQMenuData *tqparent;
+ TQMenuItem *mi = tqfindItem( id, &tqparent );
+ if ( mi ) {
+ mi->accel_key = key;
+ tqparent->menuContentsChanged();
+ }
+}
+
+#endif // TQT_NO_ACCEL
+
+/*!
+ Returns the icon set that has been set for menu item \a id, or 0
+ if no icon set has been set.
+
+ \sa changeItem(), text(), pixmap()
+*/
+
+TQIconSet* TQMenuData::iconSet( int id ) const
+{
+ TQMenuItem *mi = tqfindItem( id );
+ return mi ? mi->iconSet() : 0;
+}
+
+/*!
+ Returns the text that has been set for menu item \a id, or
+ TQString::null if no text has been set.
+
+ \sa changeItem(), pixmap(), iconSet()
+*/
+
+TQString TQMenuData::text( int id ) const
+{
+ TQMenuItem *mi = tqfindItem( id );
+ return mi ? mi->text() : TQString::null;
+}
+
+/*!
+ Returns the pixmap that has been set for menu item \a id, or 0 if
+ no pixmap has been set.
+
+ \sa changeItem(), text(), iconSet()
+*/
+
+TQPixmap *TQMenuData::pixmap( int id ) const
+{
+ TQMenuItem *mi = tqfindItem( id );
+ return mi ? mi->pixmap() : 0;
+}
+
+/*!
+ \fn void TQMenuData::changeItem( const TQString &, int )
+ \obsolete
+
+ Changes the text of the menu item \a id. If the item has an icon,
+ the icon remains unchanged.
+
+ \sa text()
+*/
+/*!
+ \fn void TQMenuData::changeItem( const TQPixmap &, int )
+ \obsolete
+
+ Changes the pixmap of the menu item \a id. If the item has an icon,
+ the icon remains unchanged.
+
+ \sa pixmap()
+*/
+
+/*!
+ \fn void TQMenuData::changeItem( const TQIconSet &, const TQString &, int )
+ \obsolete
+
+ Changes the icon and text of the menu item \a id.
+
+ \sa pixmap()
+*/
+
+/*!
+ Changes the text of the menu item \a id to \a text. If the item
+ has an icon, the icon remains unchanged.
+
+ \sa text()
+*/
+
+void TQMenuData::changeItem( int id, const TQString &text )
+{
+ TQMenuData *tqparent;
+ TQMenuItem *mi = tqfindItem( id, &tqparent );
+ if ( mi ) { // item found
+ if ( mi->text_data == text ) // same string
+ return;
+ if ( mi->pixmap_data ) { // delete pixmap
+ delete mi->pixmap_data;
+ mi->pixmap_data = 0;
+ }
+ mi->text_data = text;
+#ifndef TQT_NO_ACCEL
+ if ( !mi->accel_key && text.tqfind( '\t' ) != -1 )
+ mi->accel_key = TQt::Key_unknown;
+#endif
+ tqparent->menuContentsChanged();
+ }
+}
+
+/*!
+ \overload
+
+ Changes the pixmap of the menu item \a id to the pixmap \a pixmap.
+ If the item has an icon, the icon is unchanged.
+
+ \sa pixmap()
+*/
+
+void TQMenuData::changeItem( int id, const TQPixmap &pixmap )
+{
+ TQMenuData *tqparent;
+ TQMenuItem *mi = tqfindItem( id, &tqparent );
+ if ( mi ) { // item found
+ register TQPixmap *i = mi->pixmap_data;
+ bool fast_refresh = i != 0 &&
+ i->width() == pixmap.width() &&
+ i->height() == pixmap.height() &&
+ !mi->text();
+ if ( !mi->text_data.isNull() ) // delete text
+ mi->text_data = TQString::null;
+ if ( !pixmap.isNull() )
+ mi->pixmap_data = new TQPixmap( pixmap );
+ else
+ mi->pixmap_data = 0;
+ delete i; // old mi->pixmap_data, could be &pixmap
+ if ( fast_refresh )
+ tqparent->updateItem( id );
+ else
+ tqparent->menuContentsChanged();
+ }
+}
+
+/*!
+ \overload
+
+ Changes the iconset and text of the menu item \a id to the \a icon
+ and \a text respectively.
+
+ \sa pixmap()
+*/
+
+void TQMenuData::changeItem( int id, const TQIconSet &icon, const TQString &text )
+{
+ changeItem( id, text );
+ changeItemIconSet( id, icon );
+}
+
+/*!
+ \overload
+
+ Changes the iconset and pixmap of the menu item \a id to \a icon
+ and \a pixmap respectively.
+
+ \sa pixmap()
+*/
+
+void TQMenuData::changeItem( int id, const TQIconSet &icon, const TQPixmap &pixmap )
+{
+ changeItem( id, pixmap );
+ changeItemIconSet( id, icon );
+}
+
+
+
+/*!
+ Changes the icon of the menu item \a id to \a icon.
+
+ \sa pixmap()
+*/
+
+void TQMenuData::changeItemIconSet( int id, const TQIconSet &icon )
+{
+ TQMenuData *tqparent;
+ TQMenuItem *mi = tqfindItem( id, &tqparent );
+ if ( mi ) { // item found
+ register TQIconSet *i = mi->iconset_data;
+ bool fast_refresh = i != 0;
+ if ( !icon.isNull() )
+ mi->iconset_data = new TQIconSet( icon );
+ else
+ mi->iconset_data = 0;
+ delete i; // old mi->iconset_data, could be &icon
+ if ( fast_refresh )
+ tqparent->updateItem( id );
+ else
+ tqparent->menuContentsChanged();
+ }
+}
+
+
+/*!
+ Returns TRUE if the item with identifier \a id is enabled;
+ otherwise returns FALSE
+
+ \sa setItemEnabled(), isItemVisible()
+*/
+
+bool TQMenuData::isItemEnabled( int id ) const
+{
+ TQMenuItem *mi = tqfindItem( id );
+ return mi ? mi->isEnabled() : FALSE;
+}
+
+/*!
+ If \a enable is TRUE, enables the menu item with identifier \a id;
+ otherwise disables the menu item with identifier \a id.
+
+ \sa isItemEnabled()
+*/
+
+void TQMenuData::setItemEnabled( int id, bool enable )
+{
+ TQMenuData *tqparent;
+ TQMenuItem *mi = tqfindItem( id, &tqparent );
+ if ( mi && (bool)mi->is_enabled != enable ) {
+ mi->is_enabled = enable;
+#if !defined(TQT_NO_ACCEL) && !defined(TQT_NO_POPUPMENU)
+ if ( mi->popup() )
+ mi->popup()->enableAccel( enable );
+#endif
+ tqparent->menuStateChanged();
+ }
+}
+
+
+/*!
+ Returns TRUE if the menu item with the id \a id is currently
+ active; otherwise returns FALSE.
+*/
+bool TQMenuData::isItemActive( int id ) const
+{
+ if ( actItem == -1 )
+ return FALSE;
+ return indexOf( id ) == actItem;
+}
+
+/*!
+ Returns TRUE if the menu item with the id \a id has been checked;
+ otherwise returns FALSE.
+
+ \sa setItemChecked()
+*/
+
+bool TQMenuData::isItemChecked( int id ) const
+{
+ TQMenuItem *mi = tqfindItem( id );
+ return mi ? mi->isChecked() : FALSE;
+}
+
+/*!
+ If \a check is TRUE, checks the menu item with id \a id; otherwise
+ unchecks the menu item with id \a id. Calls
+ TQPopupMenu::setCheckable( TRUE ) if necessary.
+
+ \sa isItemChecked()
+*/
+
+void TQMenuData::setItemChecked( int id, bool check )
+{
+ TQMenuData *tqparent;
+ TQMenuItem *mi = tqfindItem( id, &tqparent );
+ if ( mi && (bool)mi->is_checked != check ) {
+ mi->is_checked = check;
+#ifndef TQT_NO_POPUPMENU
+ if ( tqparent->isPopupMenu && !((TQPopupMenu *)tqparent)->isCheckable() )
+ ((TQPopupMenu *)tqparent)->setCheckable( TRUE );
+#endif
+ tqparent->menuStateChanged();
+ }
+}
+
+/*!
+ Returns TRUE if the menu item with the id \a id is visible;
+ otherwise returns FALSE.
+
+ \sa setItemVisible()
+*/
+
+bool TQMenuData::isItemVisible( int id ) const
+{
+ TQMenuItem *mi = tqfindItem( id );
+ return mi ? mi->isVisible() : FALSE;
+}
+
+/*!
+ If \a visible is TRUE, shows the menu item with id \a id; otherwise
+ hides the menu item with id \a id.
+
+ \sa isItemVisible(), isItemEnabled()
+*/
+
+void TQMenuData::setItemVisible( int id, bool visible )
+{
+ TQMenuData *tqparent;
+ TQMenuItem *mi = tqfindItem( id, &tqparent );
+ if ( mi && (bool)mi->is_visible != visible ) {
+ mi->is_visible = visible;
+ tqparent->menuContentsChanged();
+ }
+}
+
+
+/*!
+ Returns the menu item with identifier \a id, or 0 if there is no
+ item with this identifier.
+
+ Note that TQMenuItem is an internal class, and that you should not
+ need to call this function. Use the higher level functions like
+ text(), pixmap() and changeItem() to get and modify menu item
+ attributes instead.
+
+ \sa indexOf()
+*/
+
+TQMenuItem *TQMenuData::tqfindItem( int id ) const
+{
+ return tqfindItem( id, 0 );
+}
+
+
+/*!
+ \overload
+
+ Returns the menu item with identifier \a id, or 0 if there is no
+ item with this identifier. Changes \a *tqparent to point to the
+ tqparent of the return value.
+
+ Note that TQMenuItem is an internal class, and that you should not
+ need to call this function. Use the higher level functions like
+ text(), pixmap() and changeItem() to get and modify menu item
+ attributes instead.
+
+ \sa indexOf()
+*/
+
+TQMenuItem * TQMenuData::tqfindItem( int id, TQMenuData ** tqparent ) const
+{
+ if ( tqparent )
+ *tqparent = (TQMenuData *)this; // ###
+
+ if ( id == -1 ) // bad identifier
+ return 0;
+ TQMenuItemListIt it( *mitems );
+ TQMenuItem *mi;
+ while ( (mi=it.current()) ) { // search this menu
+ ++it;
+ if ( mi->ident == id ) // found item
+ return mi;
+ }
+ it.toFirst();
+ while ( (mi=it.current()) ) { // search submenus
+ ++it;
+#ifndef TQT_NO_POPUPMENU
+ if ( mi->popup_menu ) {
+ TQPopupMenu *p = mi->popup_menu;
+ if (!p->avoid_circularity) {
+ p->avoid_circularity = 1;
+ mi = mi->popup_menu->tqfindItem( id, tqparent );
+ p->avoid_circularity = 0;
+ if ( mi ) // found item
+ return mi;
+ }
+ }
+#endif
+ }
+ return 0; // not found
+}
+
+/*!
+ Returns the index of the menu item with identifier \a id, or -1 if
+ there is no item with this identifier.
+
+ \sa idAt(), tqfindItem()
+*/
+
+int TQMenuData::indexOf( int id ) const
+{
+ if ( id == -1 ) // bad identifier
+ return -1;
+ TQMenuItemListIt it( *mitems );
+ TQMenuItem *mi;
+ int index = 0;
+ while ( (mi=it.current()) ) {
+ if ( mi->ident == id ) // this one?
+ return index;
+ ++index;
+ ++it;
+ }
+ return -1; // not found
+}
+
+/*!
+ Returns the identifier of the menu item at position \a index in
+ the internal list, or -1 if \a index is out of range.
+
+ \sa setId(), indexOf()
+*/
+
+int TQMenuData::idAt( int index ) const
+{
+ return index < (int)mitems->count() && index >= 0 ?
+ mitems->at(index)->id() : -1;
+}
+
+/*!
+ Sets the menu identifier of the item at \a index to \a id.
+
+ If \a index is out of range, the operation is ignored.
+
+ \sa idAt()
+*/
+
+void TQMenuData::setId( int index, int id )
+{
+ if ( index < (int)mitems->count() )
+ mitems->at(index)->ident = id;
+}
+
+
+/*!
+ Sets the parameter of the activation signal of item \a id to \a
+ param.
+
+ If any receiver takes an integer parameter, this value is passed.
+
+ \sa connectItem(), disconnectItem(), itemParameter()
+*/
+bool TQMenuData::setItemParameter( int id, int param ) {
+ TQMenuItem *mi = tqfindItem( id );
+ if ( !mi ) // no such identifier
+ return FALSE;
+ if ( !mi->signal_data ) { // create new signal
+ mi->signal_data = new TQSignal;
+ TQ_CHECK_PTR( mi->signal_data );
+ }
+ mi->signal_data->setValue( param );
+ return TRUE;
+}
+
+
+/*!
+ Returns the parameter of the activation signal of item \a id.
+
+ If no parameter has been specified for this item with
+ setItemParameter(), the value defaults to \a id.
+
+ \sa connectItem(), disconnectItem(), setItemParameter()
+*/
+int TQMenuData::itemParameter( int id ) const
+{
+ TQMenuItem *mi = tqfindItem( id );
+ if ( !mi || !mi->signal_data )
+ return id;
+ return mi->signal_data->value().toInt();
+}
+
+
+/*!
+ Connects the menu item with identifier \a id to \a{receiver}'s \a
+ member slot or signal.
+
+ The receiver's slot (or signal) is activated when the menu item is
+ activated.
+
+ \sa disconnectItem(), setItemParameter()
+*/
+
+bool TQMenuData::connectItem( int id, const TQT_BASE_OBJECT_NAME *receiver,
+ const char* member )
+{
+ TQMenuItem *mi = tqfindItem( id );
+ if ( !mi ) // no such identifier
+ return FALSE;
+ if ( !mi->signal_data ) { // create new signal
+ mi->signal_data = new TQSignal;
+ TQ_CHECK_PTR( mi->signal_data );
+ mi->signal_data->setValue( id );
+ }
+ return mi->signal_data->connect( receiver, member );
+}
+
+
+/*!
+ Disconnects the \a{receiver}'s \a member from the menu item with
+ identifier \a id.
+
+ All connections are removed when the menu data object is
+ destroyed.
+
+ \sa connectItem(), setItemParameter()
+*/
+
+bool TQMenuData::disconnectItem( int id, const TQT_BASE_OBJECT_NAME *receiver,
+ const char* member )
+{
+ TQMenuItem *mi = tqfindItem( id );
+ if ( !mi || !mi->signal_data ) // no identifier or no signal
+ return FALSE;
+ return mi->signal_data->disconnect( receiver, member );
+}
+
+/*!
+ Sets \a text as What's This help for the menu item with identifier
+ \a id.
+
+ \sa whatsThis()
+*/
+void TQMenuData::setWhatsThis( int id, const TQString& text )
+{
+
+ TQMenuData *tqparent;
+ TQMenuItem *mi = tqfindItem( id, &tqparent );
+ if ( mi ) {
+ mi->setWhatsThis( text );
+ tqparent->menuContentsChanged();
+ }
+}
+
+/*!
+ Returns the What's This help text for the item with identifier \a
+ id or TQString::null if no text has yet been defined.
+
+ \sa setWhatsThis()
+*/
+TQString TQMenuData::whatsThis( int id ) const
+{
+
+ TQMenuItem *mi = tqfindItem( id );
+ return mi? mi->whatsThis() : TQString::null;
+}
+
+
+
+/*!
+ \class TQCustomMenuItem tqmenudata.h
+ \brief The TQCustomMenuItem class is an abstract base class for custom menu items in popup menus.
+
+ \ingroup misc
+
+ A custom menu item is a menu item that is defined by two pure
+ virtual functions, paint() and tqsizeHint(). The size hint tells the
+ menu how much space it needs to reserve for this item, and paint
+ is called whenever the item needs painting.
+
+ This simple mechanism allows you to create all kinds of
+ application specific menu items. Examples are items showing
+ different fonts in a word processor or menus that allow the
+ selection of drawing utilities in a vector drawing program.
+
+ A custom item is inserted into a popup menu with
+ TQPopupMenu::insertItem().
+
+ By default, a custom item can also have an icon and a keyboard
+ accelerator. You can reimplement fullSpan() to return TRUE if you
+ want the item to span the entire popup menu width. This is
+ particularly useful for labels.
+
+ If you want the custom item to be treated just as a separator,
+ reimplement isSeparator() to return TRUE.
+
+ Note that you can insert pixmaps or bitmaps as items into a popup
+ menu without needing to create a TQCustomMenuItem. However, custom
+ menu items offer more flexibility, and -- especially important
+ with Windows style -- provide the possibility of drawing the item
+ with a different color when it is highlighted.
+
+ \link menu-example.html menu/menu.cpp\endlink shows a simple
+ example how custom menu items can be used.
+
+ Note: the current implementation of TQCustomMenuItem will not
+ recognize shortcut keys that are from text with ampersands. Normal
+ accelerators work though.
+
+ <img src=qpopmenu-fancy.png>
+
+ \sa TQMenuData, TQPopupMenu
+*/
+
+
+
+/*!
+ Constructs a TQCustomMenuItem
+*/
+TQCustomMenuItem::TQCustomMenuItem()
+{
+}
+
+/*!
+ Destroys a TQCustomMenuItem
+*/
+TQCustomMenuItem::~TQCustomMenuItem()
+{
+}
+
+
+/*!
+ Sets the font of the custom menu item to \a font.
+
+ This function is called whenever the font in the popup menu
+ changes. For menu items that show their own individual font entry,
+ you want to ignore this.
+*/
+void TQCustomMenuItem::setFont( const TQFont& /* font */ )
+{
+}
+
+
+
+/*!
+ Returns TRUE if this item wants to span the entire popup menu
+ width; otherwise returns FALSE. The default is FALSE, meaning that
+ the menu may show an icon and an accelerator key for this item as
+ well.
+*/
+bool TQCustomMenuItem::fullSpan() const
+{
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if this item is just a separator; otherwise returns
+ FALSE.
+*/
+bool TQCustomMenuItem::isSeparator() const
+{
+ return FALSE;
+}
+
+
+/*!
+ \fn void TQCustomMenuItem::paint( TQPainter* p, const TQColorGroup& cg, bool act, bool enabled, int x, int y, int w, int h );
+
+ Paints this item. When this function is invoked, the painter \a p
+ is set to a font and foreground color suitable for a menu item
+ text using color group \a cg. The item is active if \a act is TRUE
+ and enabled if \a enabled is TRUE. The tqgeometry values \a x, \a y,
+ \a w and \a h specify where to draw the item.
+
+ Do not draw any background, this has already been done by the
+ popup menu according to the current GUI style.
+*/
+
+
+/*!
+ \fn TQSize TQCustomMenuItem::tqsizeHint();
+
+ Returns the item's size hint.
+*/
+
+
+
+/*!
+ Activates the menu item at position \a index.
+
+ If the index is invalid (for example, -1), the object itself is
+ deactivated.
+*/
+void TQMenuData::activateItemAt( int index )
+{
+#ifndef TQT_NO_MENUBAR
+ if ( isMenuBar )
+ ( (TQMenuBar*)this )->activateItemAt( index );
+ else
+#endif
+ {
+#ifndef TQT_NO_POPUPMENU
+ if ( isPopupMenu )
+ ( (TQPopupMenu*)this )->activateItemAt( index );
+#endif
+ }
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqmenudata.h b/tqtinterface/qt4/src/widgets/tqmenudata.h
new file mode 100644
index 0000000..96128c0
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqmenudata.h
@@ -0,0 +1,291 @@
+/****************************************************************************
+**
+** Definition of TQMenuData class
+**
+** Created : 941128
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMENUDATA_H
+#define TQMENUDATA_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqiconset.h" // conversion TQPixmap->TQIconset
+#include "tqkeysequence.h"
+#include "tqstring.h"
+#include "tqsignal.h"
+#include "tqfont.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_MENUDATA
+
+class TQPopupMenu;
+class TQMenuDataData;
+class TQObject;
+
+class TQCustomMenuItem;
+class TQMenuItemData;
+
+class TQ_EXPORT TQMenuItem // internal menu item class
+{
+friend class TQMenuData;
+public:
+ TQMenuItem();
+ ~TQMenuItem();
+
+ int id() const { return ident; }
+ TQIconSet *iconSet() const { return iconset_data; }
+ TQString text() const { return text_data; }
+ TQString whatsThis() const { return whatsthis_data; }
+ TQPixmap *pixmap() const { return pixmap_data; }
+ TQPopupMenu *popup() const { return popup_menu; }
+ TQWidget *widget() const { return widget_item; }
+ TQCustomMenuItem *custom() const;
+#ifndef TQT_NO_ACCEL
+ TQKeySequence key() const { return accel_key; }
+#endif
+ TQSignal *signal() const { return signal_data; }
+ bool isSeparator() const { return is_separator; }
+ bool isEnabled() const { return is_enabled; }
+ bool isChecked() const { return is_checked; }
+ bool isDirty() const { return is_dirty; }
+ bool isVisible() const { return is_visible; }
+ bool isEnabledAndVisible() const { return is_enabled && is_visible; }
+
+ void setText( const TQString &text ) { text_data = text; }
+ void setDirty( bool dirty ) { is_dirty = dirty; }
+ void tqsetVisible( bool visible ) { is_visible = visible; }
+ void setWhatsThis( const TQString &text ) { whatsthis_data = text; }
+
+private:
+ int ident; // item identifier
+ TQIconSet *iconset_data; // icons
+ TQString text_data; // item text
+ TQString whatsthis_data; // item Whats This help text
+ TQPixmap *pixmap_data; // item pixmap
+ TQPopupMenu *popup_menu; // item popup menu
+ TQWidget *widget_item; // widget menu item
+#ifndef TQT_NO_ACCEL
+ TQKeySequence accel_key; // accelerator key (state|ascii)
+#endif
+ TQSignal *signal_data; // connection
+ uint is_separator : 1; // separator flag
+ uint is_enabled : 1; // disabled flag
+ uint is_checked : 1; // checked flag
+ uint is_dirty : 1; // dirty (update) flag
+ uint is_visible : 1; // visibility flag
+ TQMenuItemData* d;
+
+ TQMenuItemData* extra();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQMenuItem( const TQMenuItem & );
+ TQMenuItem &operator=( const TQMenuItem & );
+#endif
+};
+
+#include "tqptrlist.h"
+typedef TQPtrList<TQMenuItem> TQMenuItemList;
+typedef TQPtrListIterator<TQMenuItem> TQMenuItemListIt;
+
+
+class TQ_EXPORT TQCustomMenuItem : public TQt
+{
+public:
+ TQCustomMenuItem();
+ virtual ~TQCustomMenuItem();
+ virtual bool fullSpan() const;
+ virtual bool isSeparator() const;
+ virtual void setFont( const TQFont& font );
+ virtual void paint( TQPainter* p, const TQColorGroup& cg, bool act,
+ bool enabled, int x, int y, int w, int h ) = 0;
+ virtual TQSize tqsizeHint() = 0;
+};
+
+
+class TQ_EXPORT TQMenuData // menu data class
+{
+friend class TQMenuBar;
+friend class TQPopupMenu;
+public:
+ TQMenuData();
+ virtual ~TQMenuData();
+
+ uint count() const;
+
+
+ int insertItem( const QString &text,
+ const TQT_BASE_OBJECT_NAME *receiver, const char* member,
+ const TQKeySequence& accel = 0, int id = -1, int index = -1 );
+ int insertItem( const TQIconSet& icon,
+ const TQString &text,
+ const TQT_BASE_OBJECT_NAME *receiver, const char* member,
+ const TQKeySequence& accel = 0, int id = -1, int index = -1 );
+ int insertItem( const QPixmap &pixmap,
+ const TQT_BASE_OBJECT_NAME *receiver, const char* member,
+ const TQKeySequence& accel = 0, int id = -1, int index = -1 );
+ int insertItem( const TQIconSet& icon,
+ const TQPixmap &pixmap,
+ const TQT_BASE_OBJECT_NAME *receiver, const char* member,
+ const TQKeySequence& accel = 0, int id = -1, int index = -1 );
+
+ int insertItem( const QString &text, int id=-1, int index=-1 );
+ int insertItem( const TQIconSet& icon,
+ const TQString &text, int id=-1, int index=-1 );
+
+ int insertItem( const QString &text, TQPopupMenu *popup,
+ int id=-1, int index=-1 );
+ int insertItem( const TQIconSet& icon,
+ const TQString &text, TQPopupMenu *popup,
+ int id=-1, int index=-1 );
+
+
+ int insertItem( const QPixmap &pixmap, int id=-1, int index=-1 );
+ int insertItem( const TQIconSet& icon,
+ const TQPixmap &pixmap, int id=-1, int index=-1 );
+ int insertItem( const QPixmap &pixmap, TQPopupMenu *popup,
+ int id=-1, int index=-1 );
+ int insertItem( const TQIconSet& icon,
+ const TQPixmap &pixmap, TQPopupMenu *popup,
+ int id=-1, int index=-1 );
+
+ int insertItem( QWidget* widget, int id=-1, int index=-1 );
+
+ int insertItem( const TQIconSet& icon, TQCustomMenuItem* custom, int id=-1, int index=-1 );
+ int insertItem( TQCustomMenuItem* custom, int id=-1, int index=-1 );
+
+
+ int insertSeparator( int index=-1 );
+
+ void removeItem( int id );
+ void removeItemAt( int index );
+ void clear();
+
+#ifndef TQT_NO_ACCEL
+ TQKeySequence accel( int id ) const;
+ void setAccel( const TQKeySequence& key, int id );
+#endif
+
+ TQIconSet *iconSet( int id ) const;
+ TQString text( int id ) const;
+ TQPixmap *pixmap( int id ) const;
+
+ void setWhatsThis( int id, const TQString& );
+ TQString whatsThis( int id ) const;
+ inline void tqsetWhatsThis( int id, const TQString&str ) { return TQMenuData::setWhatsThis(id, str); }
+
+
+ void changeItem( int id, const TQString &text );
+ void changeItem( int id, const TQPixmap &pixmap );
+ void changeItem( int id, const TQIconSet &icon, const TQString &text );
+ void changeItem( int id, const TQIconSet &icon, const TQPixmap &pixmap );
+
+ void changeItem( const TQString &text, int id ) { changeItem( id, text); } // obsolete
+ void changeItem( const TQPixmap &pixmap, int id ) { changeItem( id, pixmap ); } // obsolete
+ void changeItem( const TQIconSet &icon, const TQString &text, int id ) { // obsolete
+ changeItem( id, icon, text );
+ }
+
+ bool isItemActive( int id ) const;
+
+ bool isItemEnabled( int id ) const;
+ void setItemEnabled( int id, bool enable );
+
+ bool isItemChecked( int id ) const;
+ void setItemChecked( int id, bool check );
+
+ bool isItemVisible( int id ) const;
+ void setItemVisible( int id, bool visible );
+
+ virtual void updateItem( int id );
+
+ int indexOf( int id ) const;
+ int idAt( int index ) const;
+ virtual void setId( int index, int id );
+
+ bool connectItem( int id,
+ const TQT_BASE_OBJECT_NAME *receiver, const char* member );
+ bool disconnectItem( int id,
+ const TQT_BASE_OBJECT_NAME *receiver, const char* member );
+
+ bool setItemParameter( int id, int param );
+ int itemParameter( int id ) const;
+
+ TQMenuItem *tqfindItem( int id ) const;
+ TQMenuItem *tqfindItem( int id, TQMenuData ** tqparent ) const;
+ TQMenuItem * tqfindPopup( TQPopupMenu *, int *index = 0 );
+
+ virtual void activateItemAt( int index );
+
+protected:
+ int actItem;
+ TQMenuItemList *mitems;
+#ifdef USE_QT4
+public: // FIXME This is a nasty hack...
+#endif // USE_QT4
+ TQMenuData *parentMenu;
+ uint isPopupMenu : 1;
+ uint isMenuBar : 1;
+protected:
+ uint badSize : 1;
+ uint mouseBtDn : 1;
+ uint avoid_circularity : 1;
+ uint actItemDown : 1;
+ virtual void menuContentsChanged();
+ virtual void menuStateChanged();
+ virtual void menuInsPopup( TQPopupMenu * );
+ virtual void menuDelPopup( TQPopupMenu * );
+
+private:
+ int insertAny( const TQString *, const TQPixmap *, TQPopupMenu *,
+ const TQIconSet*, int, int, TQWidget* = 0, TQCustomMenuItem* = 0);
+ void removePopup( TQPopupMenu * );
+ void changeItemIconSet( int id, const TQIconSet &icon );
+
+ TQMenuDataData *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQMenuData( const TQMenuData & );
+ TQMenuData &operator=( const TQMenuData & );
+#endif
+};
+
+
+#endif // TQT_NO_MENUDATA
+
+#endif // TQMENUDATA_H
diff --git a/tqtinterface/qt4/src/widgets/tqmultilineedit.cpp b/tqtinterface/qt4/src/widgets/tqmultilineedit.cpp
new file mode 100644
index 0000000..22066bc
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqmultilineedit.cpp
@@ -0,0 +1,541 @@
+/**********************************************************************
+**
+** Implementation of TQMultiLineEdit widget class
+**
+** Created : 961005
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqmultilineedit.h"
+#ifndef TQT_NO_MULTILINEEDIT
+#include "tqpainter.h"
+#include "tqscrollbar.h"
+#include "tqcursor.h"
+#include "tqclipboard.h"
+#include "tqpixmap.h"
+#include "tqregexp.h"
+#include "tqapplication.h"
+#include "tqdragobject.h"
+#include "tqpopupmenu.h"
+#include "tqtimer.h"
+#include "tqdict.h"
+#include "../kernel/tqrichtext_p.h"
+
+
+/*!
+ \class TQMultiLineEdit tqmultilineedit.h
+ \obsolete
+
+ \brief The TQMultiLineEdit widget is a simple editor for inputting text.
+
+ \ingroup advanced
+
+ The TQMultiLineEdit was a simple editor widget in former TQt versions. TQt
+ 3.0 includes a new richtext engine which obsoletes TQMultiLineEdit. It is
+ still included for compatibility reasons. It is now a subclass of
+ \l TQTextEdit, and provides enough of the old TQMultiLineEdit API to keep old
+ applications working.
+
+ If you implement something new with TQMultiLineEdit, we suggest using
+ \l TQTextEdit instead and call TQTextEdit::setTextFormat(TQt::PlainText).
+
+ Although most of the old TQMultiLineEdit API is still available, there is
+ a few difference. The old TQMultiLineEdit operated on lines, not on
+ paragraphs. As lines change all the time during wordwrap, the new
+ richtext engine uses paragraphs as basic elements in the data structure.
+ All functions (numLines(), textLine(), etc.) that operated on lines, now
+ operate on paragraphs. Further, getString() has been removed completely.
+ It revealed too much of the internal data structure.
+
+ Applications which made normal and reasonable use of TQMultiLineEdit
+ should still work without problems. Some odd usage will require some
+ porting. In these cases, it may be better to use \l TQTextEdit now.
+
+ <img src=qmlined-m.png> <img src=qmlined-w.png>
+
+ \sa TQTextEdit
+*/
+
+/*!
+ \fn bool TQMultiLineEdit::autoUpdate() const
+ \obsolete
+*/
+
+/*!
+ \fn virtual void TQMultiLineEdit::setAutoUpdate( bool )
+ \obsolete
+*/
+
+/*!
+ \fn int TQMultiLineEdit::totalWidth() const
+ \obsolete
+*/
+
+/*!
+ \fn int TQMultiLineEdit::totalHeight() const
+ \obsolete
+*/
+
+/*!
+ \fn int TQMultiLineEdit::maxLines() const
+ \obsolete
+*/
+
+/*!
+ \fn void TQMultiLineEdit::setMaxLines( int )
+ \obsolete
+*/
+
+/*!
+ \fn void TQMultiLineEdit::deselect()
+ \obsolete
+*/
+
+
+class TQMultiLineEditData
+{
+};
+
+
+/*!
+ Constructs a new, empty, TQMultiLineEdit with tqparent \a tqparent called
+ \a name.
+*/
+
+TQMultiLineEdit::TQMultiLineEdit( TQWidget *tqparent , const char *name )
+ : TQTextEdit( tqparent, name )
+{
+ d = new TQMultiLineEditData;
+ setTextFormat( TQt::PlainText );
+}
+
+/*! \property TQMultiLineEdit::numLines
+ \brief the number of paragraphs in the editor
+
+ The count includes any empty paragraph at top and bottom, so for an
+ empty editor this method returns 1.
+*/
+
+int TQMultiLineEdit::numLines() const
+{
+ return document()->lastParagraph()->paragId() + 1;
+}
+
+/*! \property TQMultiLineEdit::atEnd
+ \brief whether the cursor is placed at the end of the text
+
+ \sa atBeginning
+*/
+
+bool TQMultiLineEdit::atEnd() const
+{
+ return textCursor()->paragraph() == document()->lastParagraph() && textCursor()->atParagEnd();
+}
+
+
+/*! \property TQMultiLineEdit::atBeginning
+ \brief whether the cursor is placed at the beginning of the text
+
+ \sa atEnd
+*/
+
+bool TQMultiLineEdit::atBeginning() const
+{
+ return textCursor()->paragraph() == document()->firstParagraph() && textCursor()->atParagStart();
+}
+
+/*! Returns the number of characters at paragraph number \a row. If
+ \a row is out of range, -1 is returned.
+*/
+
+int TQMultiLineEdit::lineLength( int row ) const
+{
+ if ( row < 0 || row > numLines() )
+ return -1;
+ return document()->paragAt( row )->length() - 1;
+}
+
+
+/*! \reimp */
+
+TQMultiLineEdit::~TQMultiLineEdit()
+{
+ delete d;
+}
+
+/*!
+ If there is selected text, sets \a line1, \a col1, \a line2 and \a col2
+ to the start and end of the selected region and returns TRUE. Returns
+ FALSE if there is no selected text.
+ */
+bool TQMultiLineEdit::getMarkedRegion( int *line1, int *col1,
+ int *line2, int *col2 ) const
+{
+ int p1,c1, p2, c2;
+ getSelection( &p1, &c1, &p2, &c2 );
+ if ( p1 == -1 && c1 == -1 && p2 == -1 && c2 == -1 )
+ return FALSE;
+ if ( line1 )
+ *line1 = p1;
+ if ( col1 )
+ *col1 = c1;
+ if ( line2 )
+ *line2 = p2;
+ if ( col2 )
+ *col2 = c2;
+ return TRUE;
+}
+
+
+/*!
+ Returns TRUE if there is selected text.
+*/
+
+bool TQMultiLineEdit::hasMarkedText() const
+{
+ return hasSelectedText();
+}
+
+
+/*!
+ Returns a copy of the selected text.
+*/
+
+TQString TQMultiLineEdit::markedText() const
+{
+ return selectedText();
+}
+
+/*!
+ Moves the cursor one page down. If \a mark is TRUE, the text
+ is selected.
+*/
+
+void TQMultiLineEdit::pageDown( bool mark )
+{
+ moveCursor( MoveDown, mark );
+}
+
+
+/*!
+ Moves the cursor one page up. If \a mark is TRUE, the text
+ is selected.
+*/
+
+void TQMultiLineEdit::pageUp( bool mark )
+{
+ moveCursor( MovePgUp, mark );
+}
+
+
+/*! Inserts \a txt at paragraph number \a line. If \a line is less
+ than zero, or larger than the number of paragraphs, the new text is
+ put at the end. If \a txt tqcontains newline characters, several
+ paragraphs are inserted.
+
+ The cursor position is not changed.
+*/
+
+void TQMultiLineEdit::insertLine( const TQString &txt, int line )
+{
+ insertParagraph( txt, line );
+}
+
+/*! Deletes the paragraph at paragraph number \a paragraph. If \a
+ paragraph is less than zero or larger than the number of paragraphs,
+ nothing is deleted.
+*/
+
+void TQMultiLineEdit::removeLine( int paragraph )
+{
+ removeParagraph( paragraph );
+}
+
+/*! Inserts \a str at the current cursor position and selects the
+ text if \a mark is TRUE.
+*/
+
+void TQMultiLineEdit::insertAndMark( const TQString& str, bool mark )
+{
+ insert( str );
+ if ( mark )
+ document()->setSelectionEnd( TQTextDocument::Standard, *textCursor() );
+}
+
+/*! Splits the paragraph at the current cursor position.
+*/
+
+void TQMultiLineEdit::newLine()
+{
+ insert( "\n" );
+}
+
+
+/*! Deletes the character on the left side of the text cursor and
+ moves the cursor one position to the left. If a text has been selected
+ by the user (e.g. by clicking and dragging) the cursor is put at the
+ beginning of the selected text and the selected text is removed. \sa
+ del()
+*/
+
+void TQMultiLineEdit::backspace()
+{
+ if ( document()->hasSelection( TQTextDocument::Standard ) ) {
+ removeSelectedText();
+ return;
+ }
+
+ if ( !textCursor()->paragraph()->prev() &&
+ textCursor()->atParagStart() )
+ return;
+
+ doKeyboardAction( ActionBackspace );
+}
+
+
+/*! Moves the text cursor to the left end of the line. If \a mark is
+ TRUE, text is selected toward the first position. If it is FALSE and the
+ cursor is moved, all selected text is unselected.
+
+ \sa end()
+*/
+
+void TQMultiLineEdit::home( bool mark )
+{
+ moveCursor( MoveLineStart, mark );
+}
+
+/*! Moves the text cursor to the right end of the line. If \a mark is
+ TRUE, text is selected toward the last position. If it is FALSE and the
+ cursor is moved, all selected text is unselected.
+
+ \sa home()
+*/
+
+void TQMultiLineEdit::end( bool mark )
+{
+ moveCursor( MoveLineEnd, mark );
+}
+
+
+/*!
+ \fn void TQMultiLineEdit::setCursorPosition( int line, int col )
+ \reimp
+*/
+
+/*! Sets the cursor position to character number \a col in paragraph
+ number \a line. The parameters are adjusted to lie within the legal
+ range.
+
+ If \a mark is FALSE, the selection is cleared. otherwise it is extended.
+
+*/
+
+void TQMultiLineEdit::setCursorPosition( int line, int col, bool mark )
+{
+ if ( !mark )
+ selectAll( FALSE );
+ TQTextEdit::setCursorPosition( line, col );
+ if ( mark )
+ document()->setSelectionEnd( TQTextDocument::Standard, *textCursor() );
+}
+
+/*! Returns the top center point where the cursor is drawn.
+*/
+
+TQPoint TQMultiLineEdit::cursorPoint() const
+{
+ return TQPoint( textCursor()->x(), textCursor()->y() + textCursor()->paragraph()->rect().y() );
+}
+
+/*! \property TQMultiLineEdit::tqalignment
+ \brief The editor's paragraph tqalignment
+
+ Sets the tqalignment to flag, which must be \c AlignLeft, \c
+ AlignHCenter or \c AlignRight.
+
+ If flag is an illegal flag nothing happens.
+
+ \sa TQt::AlignmentFlags
+*/
+void TQMultiLineEdit::tqsetAlignment( int flag )
+{
+ if ( flag == Qt::AlignCenter )
+ flag = Qt::AlignHCenter;
+ if ( flag != Qt::AlignLeft && flag != Qt::AlignRight && flag != Qt::AlignHCenter )
+ return;
+ TQTextParagraph *p = document()->firstParagraph();
+ while ( p ) {
+ p->tqsetAlignment( flag );
+ p = p->next();
+ }
+}
+
+int TQMultiLineEdit::tqalignment() const
+{
+ return document()->firstParagraph()->tqalignment();
+}
+
+
+void TQMultiLineEdit::setEdited( bool e )
+{
+ setModified( e );
+}
+
+/*! \property TQMultiLineEdit::edited
+ \brief whether the document has been edited by the user
+
+ This is the same as TQTextEdit's "modifed" property.
+
+ \sa TQTextEdit::modified
+*/
+bool TQMultiLineEdit::edited() const
+{
+ return isModified();
+}
+
+/*! Moves the cursor one word to the right. If \a mark is TRUE, the text
+ is selected.
+
+ \sa cursorWordBackward()
+*/
+void TQMultiLineEdit::cursorWordForward( bool mark )
+{
+ moveCursor( MoveWordForward, mark );
+}
+
+/*! Moves the cursor one word to the left. If \a mark is TRUE, the
+ text is selected.
+
+ \sa cursorWordForward()
+*/
+void TQMultiLineEdit::cursorWordBackward( bool mark )
+{
+ moveCursor( MoveWordBackward, mark );
+}
+
+/*!
+ \fn TQMultiLineEdit::insertAt( const TQString &s, int line, int col )
+ \reimp
+*/
+
+/*! Inserts string \a s at paragraph number \a line, after character
+ number \a col in the paragraph. If \a s tqcontains newline
+ characters, new lines are inserted.
+ If \a mark is TRUE the inserted string will be selected.
+
+ The cursor position is adjusted.
+ */
+
+void TQMultiLineEdit::insertAt( const TQString &s, int line, int col, bool mark )
+{
+ TQTextEdit::insertAt( s, line, col );
+ if ( mark )
+ setSelection( line, col, line, col + s.length() );
+}
+
+// ### reggie - is this documentation correct?
+
+/*! Deletes text from the current cursor position to the end of the
+ line. (Note that this function still operates on lines, not paragraphs.)
+*/
+
+void TQMultiLineEdit::killLine()
+{
+ doKeyboardAction( ActionKill );
+}
+
+/*! Moves the cursor one character to the left. If \a mark is TRUE,
+ the text is selected.
+ The \a wrap parameter is currently ignored.
+
+ \sa cursorRight() cursorUp() cursorDown()
+*/
+
+void TQMultiLineEdit::cursorLeft( bool mark, bool )
+{
+ moveCursor( MoveBackward, mark );
+}
+
+/*! Moves the cursor one character to the right. If \a mark is TRUE,
+ the text is selected.
+ The \a wrap parameter is currently ignored.
+
+ \sa cursorLeft() cursorUp() cursorDown()
+*/
+
+void TQMultiLineEdit::cursorRight( bool mark, bool )
+{
+ moveCursor( MoveForward, mark );
+}
+
+/*! Moves the cursor up one line. If \a mark is TRUE, the text is
+ selected.
+
+ \sa cursorDown() cursorLeft() cursorRight()
+*/
+
+void TQMultiLineEdit::cursorUp( bool mark )
+{
+ moveCursor( MoveUp, mark );
+}
+
+/*!
+ Moves the cursor one line down. If \a mark is TRUE, the text
+ is selected.
+ \sa cursorUp() cursorLeft() cursorRight()
+*/
+
+void TQMultiLineEdit::cursorDown( bool mark )
+{
+ moveCursor( MoveDown, mark );
+}
+
+
+/*! Returns the text at line number \a line (possibly the empty
+ string), or a \link TQString::operator!() null string\endlink if \a
+ line is invalid.
+*/
+
+TQString TQMultiLineEdit::textLine( int line ) const
+{
+ if ( line < 0 || line >= numLines() )
+ return TQString::null;
+ TQString str = document()->paragAt( line )->string()->toString();
+ str.truncate( str.length() - 1 );
+ return str;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqmultilineedit.h b/tqtinterface/qt4/src/widgets/tqmultilineedit.h
new file mode 100644
index 0000000..f382f78
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqmultilineedit.h
@@ -0,0 +1,144 @@
+/**********************************************************************
+**
+** Definition of TQMultiLineEdit widget class
+**
+** Created : 961005
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQMULTILINEEDIT_H
+#define TQMULTILINEEDIT_H
+
+#ifndef TQT_H
+#include "tqtextedit.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_MULTILINEEDIT
+
+class TQMultiLineEditCommand;
+class TQValidator;
+class TQMultiLineEditData;
+
+class TQ_EXPORT TQMultiLineEdit : public TQTextEdit
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( int numLines READ numLines )
+ Q_PROPERTY( bool atBeginning READ atBeginning )
+ Q_PROPERTY( bool atEnd READ atEnd )
+ Q_PROPERTY( Qt::Alignment tqalignment READ alignmentProp WRITE tqsetAlignmentProp )
+ Q_PROPERTY( bool edited READ edited WRITE setEdited DESIGNABLE false )
+
+public:
+ TQMultiLineEdit( TQWidget* tqparent=0, const char* name=0 );
+ ~TQMultiLineEdit();
+
+ TQString textLine( int line ) const;
+ int numLines() const;
+
+ virtual void insertLine( const TQString &s, int line = -1 );
+ virtual void insertAt( const TQString &s, int line, int col ) {
+ insertAt( s, line, col, FALSE );
+ }
+ virtual void insertAt( const TQString &s, int line, int col, bool mark );
+ virtual void removeLine( int line );
+ virtual void setCursorPosition( int line, int col ) {
+ setCursorPosition( line, col, FALSE );
+ }
+ virtual void setCursorPosition( int line, int col, bool mark );
+ bool atBeginning() const;
+ bool atEnd() const;
+
+ void tqsetAlignment( int flags );
+ int tqalignment() const;
+ inline Qt::Alignment alignmentProp() const { return (Qt::Alignment)tqalignment(); }
+ inline virtual void tqsetAlignmentProp( Qt::Alignment al ) { tqsetAlignment((int)al); }
+
+ void setEdited( bool );
+ bool edited() const;
+
+ bool hasMarkedText() const;
+ TQString markedText() const;
+
+ void cursorWordForward( bool mark );
+ void cursorWordBackward( bool mark );
+
+ // noops
+ bool autoUpdate() const { return TRUE; }
+ virtual void setAutoUpdate( bool ) {}
+
+ int totalWidth() const { return contentsWidth(); }
+ int totalHeight() const { return contentsHeight(); }
+
+ int maxLines() const { return TQWIDGETSIZE_MAX; }
+ void setMaxLines( int ) {}
+
+public Q_SLOTS:
+ void deselect() { selectAll( FALSE ); }
+
+protected:
+ TQPoint cursorPoint() const;
+
+protected:
+ virtual void insertAndMark( const TQString&, bool mark );
+ virtual void newLine();
+ virtual void killLine();
+ virtual void pageUp( bool mark=FALSE );
+ virtual void pageDown( bool mark=FALSE );
+ virtual void cursorLeft( bool mark=FALSE, bool wrap = TRUE );
+ virtual void cursorRight( bool mark=FALSE, bool wrap = TRUE );
+ virtual void cursorUp( bool mark=FALSE );
+ virtual void cursorDown( bool mark=FALSE );
+ virtual void backspace();
+ virtual void home( bool mark=FALSE );
+ virtual void end( bool mark=FALSE );
+
+ bool getMarkedRegion( int *line1, int *col1,
+ int *line2, int *col2 ) const;
+ int lineLength( int row ) const;
+
+private:
+ TQMultiLineEditData *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQMultiLineEdit( const TQMultiLineEdit & );
+ TQMultiLineEdit &operator=( const TQMultiLineEdit & );
+#endif
+};
+
+#endif // TQT_NO_MULTILINEEDIT
+
+#endif // TQMULTILINED_H
diff --git a/tqtinterface/qt4/src/widgets/tqpopupmenu.cpp b/tqtinterface/qt4/src/widgets/tqpopupmenu.cpp
new file mode 100644
index 0000000..bbfdb60
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqpopupmenu.cpp
@@ -0,0 +1,2852 @@
+/****************************************************************************
+**
+** Implementation of TQPopupMenu class
+**
+** Created : 941128
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpopupmenu.h"
+#ifndef TQT_NO_POPUPMENU
+#include "tqmenubar.h"
+#include "tqaccel.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqapplication.h"
+#include "tqpixmap.h"
+#include "tqpixmapcache.h"
+#include "tqtimer.h"
+#include "tqwhatsthis.h"
+#include "tqobjectlist.h"
+#include "tqguardedptr.h"
+#include "tqeffects_p.h"
+#include "tqcursor.h"
+#include "tqstyle.h"
+#include "tqtimer.h"
+#include "tqdatetime.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+//#define ANIMATED_POPUP
+//#define BLEND_POPUP
+
+// Motif style parameters
+
+static const int motifArrowHMargin = 6; // arrow horizontal margin
+static const int motifArrowVMargin = 2; // arrow vertical margin
+
+bool tqwidget_is_popup_menu(QWidget* w) {
+ return tqt_dynamic_cast<TQPopupMenu*>(w);
+}
+
+QWidget* tqwidget_parent_popup_menu(QWidget* w) {
+ TQPopupMenu* tqpm = dynamic_cast<TQPopupMenu*>(w);
+ if (tqpm) {
+ TQMenuData *top = tqpm; // tqfind top level
+ if ( top->parentMenu ) {
+ if (top->parentMenu->isPopupMenu == FALSE) return 0;
+ return (dynamic_cast<TQPopupMenu*>(top->parentMenu));
+ }
+ else return 0;
+ }
+ else return 0;
+}
+
+/*
+
++-----------------------------
+| PopupFrame
+| +-------------------------
+| | ItemFrame
+| | +---------------------
+| | |
+| | | \
+| | | ^ T E X T ^ | ItemVMargin
+| | | | | /
+| | ItemHMargin
+|
+
+*/
+
+#if 0
+# define DEBUG_SLOPPY_SUBMENU
+#endif
+
+// used for internal communication
+static TQPopupMenu * syncMenu = 0;
+static int syncMenuId = 0;
+
+// Used to detect motion prior to mouse-release
+static int motion;
+
+// used to provide ONE single-shot timer
+static TQTimer * singleSingleShot = 0;
+
+static bool supressAboutToShow = FALSE;
+
+static void cleanup()
+{
+ delete singleSingleShot;
+ singleSingleShot = 0;
+}
+
+static void popupSubMenuLater( int msec, TQPopupMenu * receiver ) {
+ if ( !singleSingleShot ) {
+ singleSingleShot = new TQTimer( tqApp, "popup submenu timer" );
+ qAddPostRoutine( cleanup );
+ }
+
+ singleSingleShot->disconnect( TQT_SIGNAL(timeout()) );
+ TQObject::connect( singleSingleShot, TQT_SIGNAL(timeout()),
+ receiver, TQT_SLOT(subMenuTimer()) );
+ singleSingleShot->start( msec, TRUE );
+}
+
+static bool preventAnimation = FALSE;
+
+#ifndef TQT_NO_WHATSTHIS
+extern void qWhatsThisBDH();
+static TQMenuItem* whatsThisItem = 0;
+#endif
+
+/*!
+ \class TQPopupMenu tqpopupmenu.h
+ \brief The TQPopupMenu class provides a popup menu widget.
+
+ \ingroup application
+ \ingroup basic
+ \mainclass
+
+ A popup menu widget is a selection menu. It can be either a
+ pull-down menu in a menu bar or a standalone context (popup) menu.
+ Pull-down menus are shown by the menu bar when the user clicks on
+ the respective item or presses the specified shortcut key. Use
+ TQMenuBar::insertItem() to insert a popup menu into a menu bar.
+ Show a context menu either asynchronously with popup() or
+ synchronously with exec().
+
+ Technically, a popup menu consists of a list of menu items. You
+ add items with insertItem(). An item is either a string, a pixmap
+ or a custom item that provides its own drawing function (see
+ TQCustomMenuItem). In addition, items can have an optional icon
+ drawn on the very left side and an accelerator key such as
+ "Ctrl+X".
+
+ There are three kinds of menu items: separators, menu items that
+ perform an action and menu items that show a submenu. Separators
+ are inserted with insertSeparator(). For submenus, you pass a
+ pointer to a TQPopupMenu in your call to insertItem(). All other
+ items are considered action items.
+
+ When inserting action items you usually specify a receiver and a
+ slot. The receiver will be notifed whenever the item is selected.
+ In addition, TQPopupMenu provides two Q_SIGNALS, activated() and
+ highlighted(), which signal the identifier of the respective menu
+ item. It is sometimes practical to connect several items to one
+ slot. To distinguish between them, specify a slot that takes an
+ integer argument and use setItemParameter() to associate a unique
+ value with each item.
+
+ You clear a popup menu with clear() and remove single items with
+ removeItem() or removeItemAt().
+
+ A popup menu can display check marks for certain items when
+ enabled with setCheckable(TRUE). You check or uncheck items with
+ setItemChecked().
+
+ Items are either enabled or disabled. You toggle their state with
+ setItemEnabled(). Just before a popup menu becomes visible, it
+ emits the aboutToShow() signal. You can use this signal to set the
+ correct enabled/disabled states of all menu items before the user
+ sees it. The corresponding aboutToHide() signal is emitted when
+ the menu hides again.
+
+ You can provide What's This? help for single menu items with
+ setWhatsThis(). See TQWhatsThis for general information about this
+ kind of lightweight online help.
+
+ For ultimate flexibility, you can also add entire widgets as items
+ into a popup menu (for example, a color selector).
+
+ A TQPopupMenu can also provide a tear-off menu. A tear-off menu is
+ a top-level window that tqcontains a copy of the menu. This makes it
+ possible for the user to "tear off" frequently used menus and
+ position them in a convenient place on the screen. If you want
+ that functionality for a certain menu, insert a tear-off handle
+ with insertTearOffHandle(). When using tear-off menus, bear in
+ mind that the concept isn't typically used on Microsoft Windows so
+ users may not be familiar with it. Consider using a TQToolBar
+ instead. Tear-off menus cannot contain custom widgets; if the
+ original menu tqcontains a custom widget item, this item is omitted.
+
+ \link menu-example.html menu/menu.cpp\endlink is an example of
+ TQMenuBar and TQPopupMenu use.
+
+ \important insertItem removeItem removeItemAt clear text pixmap iconSet insertSeparator changeItem whatsThis setWhatsThis accel setAccel setItemEnabled isItemEnabled setItemVisible isItemVisible setItemChecked isItemChecked connectItem disconnectItem setItemParameter itemParameter
+
+ <img src=qpopmenu-m.png> <img src=qpopmenu-w.png>
+
+ \sa TQMenuBar
+ \link guibooks.html#fowler GUI Design Handbook: Menu, Drop-Down and
+ Pop-Up\endlink
+*/
+
+
+/*!
+ \fn void TQPopupMenu::aboutToShow()
+
+ This signal is emitted just before the popup menu is displayed.
+ You can connect it to any slot that sets up the menu contents
+ (e.g. to ensure that the right items are enabled).
+
+ \sa aboutToHide(), setItemEnabled(), setItemChecked(), insertItem(), removeItem()
+*/
+
+/*!
+ \fn void TQPopupMenu::aboutToHide()
+
+ This signal is emitted just before the popup menu is hidden after
+ it has been displayed.
+
+ \warning Do not open a widget in a slot connected to this signal.
+
+ \sa aboutToShow(), setItemEnabled(), setItemChecked(), insertItem(), removeItem()
+*/
+
+
+
+/*****************************************************************************
+ TQPopupMenu member functions
+ *****************************************************************************/
+
+class TQMenuDataData {
+ // attention: also defined in qmenudata.cpp
+public:
+ TQMenuDataData();
+ TQGuardedPtr<TQWidget> aWidget;
+ int aInt;
+};
+
+class TQPopupMenuPrivate {
+public:
+ struct Scroll {
+ enum { ScrollNone=0, ScrollUp=0x01, ScrollDown=0x02 };
+ uint scrollable : 2;
+ uint direction : 1;
+ int topScrollableIndex, scrollableSize;
+ TQTime lastScroll;
+ TQTimer *scrolltimer;
+ } scroll;
+ TQSize calcSize;
+ TQRegion mouseMoveBuffer;
+};
+
+static TQPopupMenu* active_popup_menu = 0;
+
+/*!
+ Constructs a popup menu called \a name with tqparent \a tqparent.
+
+ Although a popup menu is always a top-level widget, if a tqparent is
+ passed the popup menu will be deleted when that tqparent is
+ destroyed (as with any other TQObject).
+*/
+
+TQPopupMenu::TQPopupMenu( TQWidget *tqparent, const char *name )
+ : TQFrame( tqparent, name, (WFlags)WType_Popup | TQt::WNoAutoErase )
+{
+ d = new TQPopupMenuPrivate;
+ d->scroll.scrollableSize = d->scroll.topScrollableIndex = 0;
+ d->scroll.scrollable = TQPopupMenuPrivate::Scroll::ScrollNone;
+ d->scroll.scrolltimer = 0;
+ isPopupMenu = TRUE;
+#ifndef TQT_NO_ACCEL
+ autoaccel = 0;
+ accelDisabled = FALSE;
+#endif
+ popupActive = -1;
+ snapToMouse = TRUE;
+ tab = 0;
+ checkable = 0;
+ tornOff = 0;
+ pendingDelayedContentsChanges = 0;
+ pendingDelayedStateChanges = 0;
+ maxPMWidth = 0;
+
+ tab = 0;
+ ncols = 1;
+ setFrameStyle( TQFrame::PopupPanel | TQFrame::Raised );
+ setMouseTracking(tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_MouseTracking, this));
+ tqstyle().polishPopupMenu( this );
+ setBackgroundMode( TQt::PaletteButton );
+ connectModalRecursionSafety = 0;
+
+ setFocusPolicy( Qt::StrongFocus );
+}
+
+/*!
+ Destroys the popup menu.
+*/
+
+TQPopupMenu::~TQPopupMenu()
+{
+ if ( syncMenu == this && tqApp ) {
+ tqApp->exit_loop();
+ syncMenu = 0;
+ }
+
+ if(d->scroll.scrolltimer)
+ delete d->scroll.scrolltimer;
+
+ if ( isVisible() ) {
+ parentMenu = 0;
+ hidePopups();
+ }
+
+ delete (TQWidget*) TQMenuData::d->aWidget; // tear-off menu
+
+ preventAnimation = FALSE;
+ delete d;
+}
+
+
+/*!
+ Updates the item with identity \a id.
+*/
+void TQPopupMenu::updateItem( int id ) // update popup menu item
+{
+ updateRow( indexOf(id) );
+}
+
+
+void TQPopupMenu::setCheckable( bool enable )
+{
+ if ( isCheckable() != enable ) {
+ checkable = enable;
+ badSize = TRUE;
+ if ( TQMenuData::d->aWidget )
+ ( (TQPopupMenu*)(TQWidget*)TQMenuData::d->aWidget)->setCheckable( enable );
+ }
+}
+
+/*!
+ \property TQPopupMenu::checkable
+ \brief whether the display of check marks on menu items is enabled
+
+ When TRUE, the display of check marks on menu items is enabled.
+ Checking is always enabled when in Windows-style.
+
+ \sa TQMenuData::setItemChecked()
+*/
+
+bool TQPopupMenu::isCheckable() const
+{
+ return checkable;
+}
+
+void TQPopupMenu::menuContentsChanged()
+{
+ // here the part that can't be delayed
+ TQMenuData::menuContentsChanged();
+ badSize = TRUE; // might change the size
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ mac_dirty_popup = 1;
+#endif
+ if( pendingDelayedContentsChanges )
+ return;
+ pendingDelayedContentsChanges = 1;
+ if( !pendingDelayedStateChanges ) // if the timer hasn't been started yet
+ TQTimer::singleShot( 0, this, TQT_SLOT(performDelayedChanges()));
+}
+
+void TQPopupMenu::performDelayedContentsChanged()
+{
+ pendingDelayedContentsChanges = 0;
+ // here the part the can be delayed
+#ifndef TQT_NO_ACCEL
+ // if performDelayedStateChanged() will be called too,
+ // it will call updateAccel() too, no need to do it twice
+ if( !pendingDelayedStateChanges )
+ updateAccel( 0 );
+#endif
+ if ( isVisible() ) {
+ if ( tornOff )
+ return;
+ updateSize(TRUE);
+ update();
+ }
+ TQPopupMenu* p = (TQPopupMenu*)(TQWidget*)TQMenuData::d->aWidget;
+ if ( p && p->isVisible() ) {
+ p->updateSize(TRUE);
+ p->update();
+ }
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ mac_dirty_popup = 1;
+#endif
+}
+
+
+void TQPopupMenu::menuStateChanged()
+{
+ // here the part that can't be delayed
+ if( pendingDelayedStateChanges )
+ return;
+ pendingDelayedStateChanges = 1;
+ if( !pendingDelayedContentsChanges ) // if the timer hasn't been started yet
+ TQTimer::singleShot( 0, this, TQT_SLOT(performDelayedChanges()));
+}
+
+void TQPopupMenu::performDelayedStateChanged()
+{
+ pendingDelayedStateChanges = 0;
+ // here the part that can be delayed
+#ifndef TQT_NO_ACCEL
+ updateAccel( 0 ); // ### when we have a good solution for the accel vs. focus widget problem, remove that. That is only a workaround
+ // if you remove this, see performDelayedContentsChanged()
+#endif
+ update();
+ if ( TQMenuData::d->aWidget )
+ TQMenuData::d->aWidget->update();
+}
+
+void TQPopupMenu::performDelayedChanges()
+{
+ if( pendingDelayedContentsChanges )
+ performDelayedContentsChanged();
+ if( pendingDelayedStateChanges )
+ performDelayedStateChanged();
+}
+
+void TQPopupMenu::menuInsPopup( TQPopupMenu *popup )
+{
+ connect( popup, TQT_SIGNAL(activatedRedirect(int)),
+ TQT_SLOT(subActivated(int)) );
+ connect( popup, TQT_SIGNAL(highlightedRedirect(int)),
+ TQT_SLOT(subHighlighted(int)) );
+ connect( popup, TQT_SIGNAL(destroyed(TQObject*)),
+ this, TQT_SLOT(popupDestroyed(TQObject*)) );
+}
+
+void TQPopupMenu::menuDelPopup( TQPopupMenu *popup )
+{
+ popup->disconnect( TQT_SIGNAL(activatedRedirect(int)) );
+ popup->disconnect( TQT_SIGNAL(highlightedRedirect(int)) );
+ disconnect( popup, TQT_SIGNAL(destroyed(TQObject*)),
+ this, TQT_SLOT(popupDestroyed(TQObject*)) );
+}
+
+
+void TQPopupMenu::frameChanged()
+{
+ menuContentsChanged();
+}
+
+/*!
+ Displays the popup menu so that the item number \a indexAtPoint
+ will be at the specified \e global position \a pos. To translate a
+ widget's local coordinates into global coordinates, use
+ TQWidget::mapToGlobal().
+
+ When positioning a popup with exec() or popup(), bear in mind that
+ you cannot rely on the popup menu's current size(). For
+ performance reasons, the popup adapts its size only when
+ necessary, so in many cases, the size before and after the show is
+ different. Instead, use tqsizeHint(). It calculates the proper size
+ depending on the menu's current contents.
+*/
+
+void TQPopupMenu::popup( const TQPoint &pos, int indexAtPoint )
+{
+ if ( !isPopup() && isVisible() )
+ hide();
+
+ //avoid circularity
+ if ( isVisible() || !isEnabled() )
+ return;
+
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ if( macPopupMenu(pos, indexAtPoint ))
+ return;
+#endif
+
+#if (TQT_VERSION-0 >= 0x040000)
+#error "Fix this now"
+ // #### should move to TQWidget - anything might need this functionality,
+ // #### since anything can have WType_Popup window flag.
+ // #### This includes stuff in TQPushButton and some stuff for setting
+ // #### the tqgeometry of TQDialog.
+ // TQPopupMenu
+ // ::exec()
+ // ::popup()
+ // TQPushButton (shouldn't require TQMenuPopup)
+ // ::popupPressed
+ // Some stuff in qwidget.cpp for dialogs... can't remember exactly.
+ // Also the code here indicatets the parameter should be a rect, not a
+ // point.
+#endif
+
+ if(d->scroll.scrollable) {
+ d->scroll.scrollable = TQPopupMenuPrivate::Scroll::ScrollNone;
+ d->scroll.topScrollableIndex = d->scroll.scrollableSize = 0;
+ badSize = TRUE;
+ }
+ updateSize();
+
+ TQPoint mouse = TQCursor::pos();
+ snapToMouse = pos == mouse;
+
+ // have to emit here as a menu might be setup in a slot connected
+ // to aboutToShow which will change the size of the menu
+ bool s = supressAboutToShow;
+ supressAboutToShow = TRUE;
+ if ( !s) {
+ emit aboutToShow();
+ updateSize(TRUE);
+ }
+
+ int screen_num;
+ if (TQApplication::desktop()->isVirtualDesktop())
+ screen_num =
+ TQApplication::desktop()->screenNumber( TQApplication::reverseLayout() ?
+ pos+TQPoint(width(),0) : pos );
+ else
+ screen_num = TQApplication::desktop()->screenNumber( this );
+#ifdef TQ_WS_MAC
+ TQRect screen = TQApplication::desktop()->availableGeometry( screen_num );
+#else
+ TQRect screen = TQApplication::desktop()->screenGeometry( screen_num );
+#endif
+ int sw = screen.width(); // screen width
+ int sh = screen.height(); // screen height
+ int sx = screen.x(); // screen pos
+ int sy = screen.y();
+ int x = pos.x();
+ int y = pos.y();
+ if ( indexAtPoint >= 0 ) // don't subtract when < 0
+ y -= itemGeometry( indexAtPoint ).y(); // (would subtract 2 pixels!)
+ int w = width();
+ int h = height();
+
+ if ( snapToMouse ) {
+ if ( tqApp->reverseLayout() )
+ x -= w;
+ if ( x+w > sx+sw )
+ x = mouse.x()-w;
+ if ( y+h > sy+sh )
+ y = mouse.y()-h;
+ if ( x < sx )
+ x = mouse.x();
+ if ( y < sy )
+ y = sy;
+ }
+
+ if ( x+w > sx+sw ) // the complete widget must
+ x = sx+sw - w; // be visible
+ if ( y+h > sy+sh )
+ y = sy+sh - h;
+ if ( x < sx )
+ x = sx;
+ if ( y < sy )
+ y = sy;
+
+ if(tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_Scrollable, this)) {
+ int off_top = 0, off_bottom = 0;
+ if(y+h > sy+sh)
+ off_bottom = (y+h) - (sy+sh);
+ if(y < sy)
+ off_top = sy - y;
+ if(off_bottom || off_top) {
+ int ch = updateSize().height(); //store the old height, before setting scrollable --Sam
+ const int vextra = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuFrameVerticalExtra, this);
+ d->scroll.scrollableSize = h - off_top - off_bottom - 2*vextra;
+ if(off_top) {
+ move( x, y = sy );
+ d->scroll.scrollable = d->scroll.scrollable | TQPopupMenuPrivate::Scroll::ScrollUp;
+ }
+ if( off_bottom )
+ d->scroll.scrollable = d->scroll.scrollable | TQPopupMenuPrivate::Scroll::ScrollDown;
+ if( off_top != off_bottom && indexAtPoint >= 0 ) {
+ ch -= (vextra * 2);
+ if(ch > sh) //no bigger than the screen!
+ ch = sh;
+ if( ch > d->scroll.scrollableSize )
+ d->scroll.scrollableSize = ch;
+ }
+
+ updateSize(TRUE); //now set the size using the scrollable/scrollableSize as above
+ w = width();
+ h = height();
+ if(indexAtPoint >= 0) {
+ if(off_top) { //scroll to it
+ register TQMenuItem *mi = NULL;
+ TQMenuItemListIt it(*mitems);
+ for(int tmp_y = 0; tmp_y < off_top && (mi=it.current()); ) {
+ TQSize sz = tqstyle().tqsizeFromContents(TQStyle::CT_PopupMenuItem, this,
+ TQSize(0, itemHeight( mi )),
+ TQStyleOption(mi,maxPMWidth,0));
+ tmp_y += sz.height();
+ d->scroll.topScrollableIndex++;
+ }
+ }
+ }
+ }
+ }
+ move( x, y );
+ motion=0;
+ actItem = -1;
+
+#ifndef TQT_NO_EFFECTS
+ int hGuess = tqApp->reverseLayout() ? TQEffects::LeftScroll : TQEffects::RightScroll;
+ int vGuess = TQEffects::DownScroll;
+ if ( tqApp->reverseLayout() ) {
+ if ( (snapToMouse && ( x + w/2 > mouse.x() )) ||
+ ( parentMenu && parentMenu->isPopupMenu &&
+ ( x + w/2 > ((TQPopupMenu*)parentMenu)->x() ) ) )
+ hGuess = TQEffects::RightScroll;
+ } else {
+ if ( (snapToMouse && ( x + w/2 < mouse.x() )) ||
+ ( parentMenu && parentMenu->isPopupMenu &&
+ ( x + w/2 < ((TQPopupMenu*)parentMenu)->x() ) ) )
+ hGuess = TQEffects::LeftScroll;
+ }
+
+#ifndef TQT_NO_MENUBAR
+ if ( (snapToMouse && ( y + h/2 < mouse.y() )) ||
+ ( parentMenu && parentMenu->isMenuBar &&
+ ( y + h/2 < ((TQMenuBar*)parentMenu)->mapToGlobal( ((TQMenuBar*)parentMenu)->pos() ).y() ) ) )
+ vGuess = TQEffects::UpScroll;
+#endif
+
+ if ( TQApplication::isEffectEnabled( Qt::UI_AnimateMenu ) &&
+ preventAnimation == FALSE ) {
+ if ( TQApplication::isEffectEnabled( Qt::UI_FadeMenu ) )
+ qFadeEffect( this );
+ else if ( parentMenu )
+ qScrollEffect( this, parentMenu->isPopupMenu ? hGuess : vGuess );
+ else
+ qScrollEffect( this, hGuess | vGuess );
+ } else
+#endif
+ {
+ show();
+ }
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::PopupMenuStart );
+#endif
+}
+
+/*!
+ \fn void TQPopupMenu::activated( int id )
+
+ This signal is emitted when a menu item is selected; \a id is the
+ id of the selected item.
+
+ Normally, you connect each menu item to a single slot using
+ TQMenuData::insertItem(), but sometimes you will want to connect
+ several items to a single slot (most often if the user selects
+ from an array). This signal is useful in such cases.
+
+ \sa highlighted(), TQMenuData::insertItem()
+*/
+
+/*!
+ \fn void TQPopupMenu::highlighted( int id )
+
+ This signal is emitted when a menu item is highlighted; \a id is
+ the id of the highlighted item.
+
+ \sa activated(), TQMenuData::insertItem()
+*/
+
+/*! \fn void TQPopupMenu::highlightedRedirect( int id )
+ \internal
+ Used internally to connect submenus to their parents.
+*/
+
+/*! \fn void TQPopupMenu::activatedRedirect( int id )
+ \internal
+ Used internally to connect submenus to their parents.
+*/
+
+void TQPopupMenu::subActivated( int id )
+{
+ emit activatedRedirect( id );
+}
+
+void TQPopupMenu::subHighlighted( int id )
+{
+ emit highlightedRedirect( id );
+}
+
+static bool fromAccel = FALSE;
+
+#ifndef TQT_NO_ACCEL
+void TQPopupMenu::accelActivated( int id )
+{
+ TQMenuItem *mi = tqfindItem( id );
+ if ( mi && mi->isEnabledAndVisible() ) {
+ TQGuardedPtr<TQSignal> signal = mi->signal();
+ fromAccel = TRUE;
+ actSig( mi->id() );
+ fromAccel = FALSE;
+ if ( signal )
+ signal->activate();
+ }
+}
+
+void TQPopupMenu::accelDestroyed() // accel about to be deleted
+{
+ autoaccel = 0; // don't delete it twice!
+}
+#endif //TQT_NO_ACCEL
+
+void TQPopupMenu::popupDestroyed( TQObject *o )
+{
+ removePopup( (TQPopupMenu*)o );
+}
+
+void TQPopupMenu::actSig( int id, bool inwhatsthis )
+{
+ if ( !inwhatsthis ) {
+ emit activated( id );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ if ( !fromAccel )
+ TQAccessible::updateAccessibility( this, indexOf(id)+1, TQAccessible::MenuCommand );
+#endif
+ } else {
+#ifndef TQT_NO_WHATSTHIS
+ TQRect r( itemGeometry( indexOf( id ) ) );
+ TQPoint p( r.center().x(), r.bottom() );
+ TQString whatsThis = tqfindItem( id )->whatsThis();
+ if ( whatsThis.isNull() )
+ whatsThis = TQWhatsThis::textFor( this, p );
+ TQWhatsThis::leaveWhatsThisMode( whatsThis, mapToGlobal( p ), this );
+#endif
+ }
+
+ emit activatedRedirect( id );
+}
+
+void TQPopupMenu::hilitSig( int id )
+{
+ emit highlighted( id );
+ emit highlightedRedirect( id );
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, indexOf(id)+1, TQAccessible::Focus );
+ TQAccessible::updateAccessibility( this, indexOf(id)+1, TQAccessible::Selection );
+#endif
+}
+
+void TQPopupMenu::setFirstItemActive()
+{
+ TQMenuItemListIt it(*mitems);
+ register TQMenuItem *mi;
+ int ai = 0;
+ if(d->scroll.scrollable)
+ ai = d->scroll.topScrollableIndex;
+ while ( (mi=it.current()) ) {
+ ++it;
+ if ( !mi->isSeparator() && mi->id() != TQMenuData::d->aInt &&
+ ( tqstyle().tqstyleHint( TQStyle::SH_PopupMenu_AllowActiveAndDisabled, this ) || mi->isEnabledAndVisible() )) {
+ setActiveItem( ai );
+ return;
+ }
+ ai++;
+ }
+ actItem = -1;
+}
+
+/*!
+ \internal
+ Hides all popup menus (in this menu tree) that are currently open.
+*/
+
+void TQPopupMenu::hideAllPopups()
+{
+ register TQMenuData *top = this; // tqfind top level popup
+ if ( !preventAnimation )
+ TQTimer::singleShot( 10, this, TQT_SLOT(allowAnimation()) );
+ preventAnimation = TRUE;
+
+ if ( !isPopup() )
+ return; // nothing to do
+
+ while ( top->parentMenu && top->parentMenu->isPopupMenu
+ && ((TQPopupMenu*)top->parentMenu)->isPopup() )
+ top = top->parentMenu;
+ ((TQPopupMenu*)top)->hide(); // cascade from top level
+
+#ifndef TQT_NO_WHATSTHIS
+ if (whatsThisItem) {
+ qWhatsThisBDH();
+ whatsThisItem = 0;
+ }
+#endif
+
+}
+
+/*!
+ \internal
+ Hides all popup sub-menus.
+*/
+
+void TQPopupMenu::hidePopups()
+{
+ if ( !preventAnimation )
+ TQTimer::singleShot( 10, this, TQT_SLOT(allowAnimation()) );
+ preventAnimation = TRUE;
+
+ TQMenuItemListIt it(*mitems);
+ register TQMenuItem *mi;
+ while ( (mi=it.current()) ) {
+ ++it;
+ if ( mi->popup() && mi->popup()->parentMenu == this ) //avoid circularity
+ mi->popup()->hide();
+ }
+ popupActive = -1; // no active sub menu
+ if(tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SubMenuPopupDelay, this))
+ d->mouseMoveBuffer = TQRegion();
+
+ TQRect mfrect = itemGeometry( actItem );
+ setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE );
+}
+
+
+/*!
+ \internal
+ Sends the event to the menu bar.
+*/
+
+bool TQPopupMenu::tryMenuBar( TQMouseEvent *e )
+{
+ register TQMenuData *top = this; // tqfind top level
+ while ( top->parentMenu )
+ top = top->parentMenu;
+#ifndef TQT_NO_MENUBAR
+ return top->isMenuBar ?
+ ((TQMenuBar *)top)->tryMouseEvent( this, e ) :
+ ((TQPopupMenu*)top)->tryMouseEvent(this, e );
+#else
+ return ((TQPopupMenu*)top)->tryMouseEvent(this, e );
+#endif
+}
+
+
+/*!
+ \internal
+*/
+bool TQPopupMenu::tryMouseEvent( TQPopupMenu *p, TQMouseEvent * e)
+{
+ if ( p == this )
+ return FALSE;
+ TQPoint pos = mapFromGlobal( e->globalPos() );
+ if ( !TQT_TQRECT_OBJECT(rect()).tqcontains( pos ) ) // outside
+ return FALSE;
+ TQMouseEvent ee( e->type(), pos, e->globalPos(), e->button(), e->state() );
+ event( &ee );
+ return TRUE;
+}
+
+/*!
+ \internal
+ Tells the menu bar to go back to idle state.
+*/
+
+void TQPopupMenu::byeMenuBar()
+{
+#ifndef TQT_NO_MENUBAR
+ register TQMenuData *top = this; // tqfind top level
+ while ( top->parentMenu )
+ top = top->parentMenu;
+#endif
+ hideAllPopups();
+#ifndef TQT_NO_MENUBAR
+ if ( top->isMenuBar )
+ ((TQMenuBar *)top)->goodbye();
+#endif
+}
+
+
+/*!
+ \internal
+ Return the item at \a pos, or -1 if there is no item there or if
+ it is a separator item.
+*/
+
+int TQPopupMenu::itemAtPos( const TQPoint &pos, bool ignoreSeparator ) const
+{
+ if ( !contentsRect().tqcontains(pos) )
+ return -1;
+
+ int row = 0;
+ int x = contentsRect().x();
+ int y = contentsRect().y();
+ TQMenuItem *mi;
+ TQMenuItemListIt it( *mitems );
+ if(d->scroll.scrollable) {
+ if(d->scroll.topScrollableIndex) {
+ for( ; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++)
+ ++it;
+ if(!mi) {
+ row = 0;
+ it.toFirst();
+ }
+ y += tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+ }
+ }
+ int itemw = contentsRect().width() / ncols;
+ TQSize sz;
+ while ( (mi=it.current()) ) {
+ if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown &&
+ y >= contentsRect().height() - tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this))
+ return -1;
+ ++it;
+ if ( !mi->isVisible() ) {
+ ++row;
+ continue;
+ }
+ int itemh = itemHeight( mi );
+
+ sz = tqstyle().tqsizeFromContents(TQStyle::CT_PopupMenuItem, this,
+ TQSize(0, itemh),
+ TQStyleOption(mi,maxPMWidth));
+ sz = sz.expandedTo(TQSize(itemw, sz.height()));
+ itemw = sz.width();
+ itemh = sz.height();
+
+ if ( ncols > 1 && y + itemh > contentsRect().bottom() ) {
+ y = contentsRect().y();
+ x +=itemw;
+ }
+ if ( TQRect( x, y, itemw, itemh ).tqcontains( pos ) )
+ break;
+ y += itemh;
+ ++row;
+ }
+
+ if ( mi && ( !ignoreSeparator || !mi->isSeparator() ) )
+ return row;
+ return -1;
+}
+
+/*!
+ \internal
+ Returns the tqgeometry of item number \a index.
+*/
+
+TQRect TQPopupMenu::itemGeometry( int index )
+{
+ TQMenuItem *mi;
+ TQSize sz;
+ int row = 0, scrollh = 0;
+ int x = contentsRect().x();
+ int y = contentsRect().y();
+ TQMenuItemListIt it( *mitems );
+ if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollUp) {
+ scrollh = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+ y += scrollh;
+ if(d->scroll.topScrollableIndex) {
+ for( ; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++)
+ ++it;
+ if(!mi) {
+ row = 0;
+ it.toFirst();
+ }
+ }
+ }
+ int itemw = contentsRect().width() / ncols;
+ while ( (mi=it.current()) ) {
+ if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown &&
+ y >= contentsRect().height() - scrollh)
+ break;
+ ++it;
+ if ( !mi->isVisible() ) {
+ ++row;
+ continue;
+ }
+ int itemh = itemHeight( mi );
+
+ sz = tqstyle().tqsizeFromContents(TQStyle::CT_PopupMenuItem, this,
+ TQSize(0, itemh),
+ TQStyleOption(mi,maxPMWidth));
+ sz = sz.expandedTo(TQSize(itemw, sz.height()));
+ itemw = sz.width();
+ itemh = sz.height();
+ if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown &&
+ (y + itemh > contentsRect().height() - scrollh))
+ itemh -= (y + itemh) - (contentsRect().height() - scrollh);
+ if ( ncols > 1 && y + itemh > contentsRect().bottom() ) {
+ y = contentsRect().y();
+ x +=itemw;
+ }
+ if ( row == index )
+ return TQRect( x,y,itemw,itemh );
+ y += itemh;
+ ++row;
+ }
+
+ return TQRect(0,0,0,0);
+}
+
+
+/*!
+ \internal
+ Calculates and sets the size of the popup menu, based on the size
+ of the items.
+*/
+
+TQSize TQPopupMenu::updateSize(bool force_update, bool do_resize)
+{
+ polish();
+ if ( count() == 0 ) {
+ TQSize ret = TQSize( 50, 8 );
+ if(do_resize)
+ setFixedSize( ret );
+ badSize = TRUE;
+ return ret;
+ }
+
+ int scrheight = 0;
+ if(d->scroll.scrollableSize) {
+ if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollUp)
+ scrheight += tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+ if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown)
+ scrheight += tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+ }
+
+ if(badSize || force_update) {
+#ifndef TQT_NO_ACCEL
+ updateAccel( 0 );
+#endif
+ int height = 0;
+ int max_width = 0, max_height = 0;
+ TQFontMetrics fm = fontMetrics();
+ register TQMenuItem *mi;
+ maxPMWidth = 0;
+ int maxWidgetWidth = 0;
+ tab = 0;
+
+ for ( TQMenuItemListIt it( *mitems ); it.current(); ++it ) {
+ mi = it.current();
+ TQWidget *miw = mi->widget();
+ if (miw) {
+ if ( miw->parentWidget() != this )
+ miw->reparent( this, TQPoint(0,0), TRUE );
+ // widget items musn't propgate mouse events
+ ((TQPopupMenu*)miw)->setWFlags(TQt::WNoMousePropagation);
+ }
+ if ( mi->custom() )
+ mi->custom()->setFont( font() );
+ if ( mi->iconSet() != 0)
+ maxPMWidth = TQMAX( maxPMWidth,
+ mi->iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4 );
+ }
+
+ int dh = TQApplication::desktop()->height();
+ ncols = 1;
+
+ for ( TQMenuItemListIt it2( *mitems ); it2.current(); ++it2 ) {
+ mi = it2.current();
+ if ( !mi->isVisible() )
+ continue;
+ int w = 0;
+ int itemHeight = TQPopupMenu::itemHeight( mi );
+
+ if ( mi->widget() ) {
+ TQSize s( mi->widget()->tqsizeHint() );
+ s = s.expandedTo( mi->widget()->tqminimumSize() );
+ mi->widget()->resize( s );
+ if ( s.width() > maxWidgetWidth )
+ maxWidgetWidth = s.width();
+ itemHeight = s.height();
+ } else {
+ if( ! mi->isSeparator() ) {
+ if ( mi->custom() ) {
+ if ( mi->custom()->fullSpan() ) {
+ maxWidgetWidth = TQMAX( maxWidgetWidth,
+ mi->custom()->tqsizeHint().width() );
+ } else {
+ TQSize s ( mi->custom()->tqsizeHint() );
+ w += s.width();
+ }
+ }
+
+ w += maxPMWidth;
+
+ if (! mi->text().isNull()) {
+ TQString s = mi->text();
+ int t;
+ if ( (t = s.tqfind('\t')) >= 0 ) { // string tqcontains tab
+ w += fm.width( s, t );
+ w -= s.tqcontains('&') * fm.width('&');
+ w += s.tqcontains("&&") * fm.width('&');
+ int tw = fm.width( s.mid(t + 1) );
+ if ( tw > tab)
+ tab = tw;
+ } else {
+ w += fm.width( s );
+ w -= s.tqcontains('&') * fm.width('&');
+ w += s.tqcontains("&&") * fm.width('&');
+ }
+ } else if (mi->pixmap())
+ w += mi->pixmap()->width();
+ } else {
+ if ( mi->custom() ) {
+ TQSize s ( mi->custom()->tqsizeHint() );
+ w += s.width();
+ } else {
+ w = itemHeight = 2;
+ }
+ }
+
+ TQSize sz = tqstyle().tqsizeFromContents(TQStyle::CT_PopupMenuItem, this,
+ TQSize(w, itemHeight),
+ TQStyleOption(mi,maxPMWidth));
+
+ w = sz.width();
+ itemHeight = sz.height();
+
+#if defined(TQT_CHECK_NULL)
+ if ( mi->text().isNull() && !mi->pixmap() && !mi->iconSet() &&
+ !mi->isSeparator() && !mi->widget() && !mi->custom() )
+ qWarning( "TQPopupMenu: (%s) Popup has invalid menu item",
+ name( "unnamed" ) );
+#endif
+ }
+ height += itemHeight;
+ if(tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_Scrollable, this)) {
+ if(scrheight && height >= d->scroll.scrollableSize - scrheight) {
+ height = d->scroll.scrollableSize - scrheight;
+ break;
+ }
+ } else if( height + 2*frameWidth() >= dh ) {
+ ncols++;
+ max_height = TQMAX(max_height, height - itemHeight);
+ height = itemHeight;
+ }
+ if ( w > max_width )
+ max_width = w;
+ }
+ if( ncols == 1 && !max_height )
+ max_height = height;
+
+ if(tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_Scrollable, this)) {
+ height += scrheight;
+ setMouseTracking(TRUE);
+ }
+
+ if ( tab )
+ tab -= fontMetrics().minRightBearing();
+ else
+ max_width -= fontMetrics().minRightBearing();
+
+ if ( max_width + tab < maxWidgetWidth )
+ max_width = maxWidgetWidth - tab;
+
+ const int fw = frameWidth();
+ int extra_width = (fw+tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuFrameHorizontalExtra, this)) * 2,
+ extra_height = (fw+tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuFrameVerticalExtra, this)) * 2;
+ if ( ncols == 1 )
+ d->calcSize = TQSize( TQMAX( minimumWidth(), max_width + tab + extra_width ),
+ TQMAX( minimumHeight() , height + extra_height ) );
+ else
+ d->calcSize = TQSize( TQMAX( minimumWidth(), (ncols*(max_width + tab)) + extra_width ),
+ TQMAX( minimumHeight(), TQMIN( max_height + extra_height + 1, dh ) ) );
+ badSize = FALSE;
+ }
+
+ {
+ // Position the widget items. It could be done in drawContents
+ // but this way we get less flicker.
+ TQSize sz;
+ int x = contentsRect().x();
+ int y = contentsRect().y();
+ int itemw = contentsRect().width() / ncols;
+ for(TQMenuItemListIt it(*mitems); it.current(); ++it) {
+ TQMenuItem *mi = it.current();
+ if ( !mi->isVisible() )
+ continue;
+
+ int itemh = itemHeight( mi );
+
+ sz = tqstyle().tqsizeFromContents(TQStyle::CT_PopupMenuItem, this,
+ TQSize(0, itemh), TQStyleOption(mi,maxPMWidth));
+ sz = sz.expandedTo(TQSize(itemw, sz.height()));
+ itemw = sz.width();
+ itemh = sz.height();
+
+ if ( ncols > 1 && y + itemh > contentsRect().bottom() ) {
+ y = contentsRect().y();
+ x +=itemw;
+ }
+ if ( mi->widget() )
+ mi->widget()->setGeometry( x, y, itemw, mi->widget()->height() );
+ y += itemh;
+ }
+ }
+
+ if( do_resize && size() != d->calcSize ) {
+ setMaximumSize( d->calcSize );
+ d->calcSize = tqmaximumSize(); //let the max size adjust it (virtual)
+ resize( d->calcSize );
+ }
+ return d->calcSize;
+}
+
+
+#ifndef TQT_NO_ACCEL
+/*!
+ \internal
+ The \a tqparent is 0 when it is updated when a menu item has
+ changed a state, or it is something else if called from the menu bar.
+*/
+
+void TQPopupMenu::updateAccel( TQWidget *tqparent )
+{
+ TQMenuItemListIt it(*mitems);
+ register TQMenuItem *mi;
+
+ if ( tqparent ) {
+ delete autoaccel;
+ autoaccel = 0;
+ } else if ( !autoaccel ) {
+ // we have no tqparent. Rather than ignoring any accelerators we try to tqfind this popup's main window
+ if ( tornOff ) {
+ tqparent = this;
+ } else {
+ TQWidget *w = (TQWidget *) this;
+ tqparent = w->parentWidget();
+ while ( (!w->testWFlags(TQt::WType_TopLevel) || !w->testWFlags(WType_Popup)) && tqparent ) {
+ w = tqparent;
+ tqparent = tqparent->parentWidget();
+ }
+ }
+ }
+
+ if ( tqparent == 0 && autoaccel == 0 )
+ return;
+
+ if ( autoaccel ) // build it from scratch
+ autoaccel->clear();
+ else {
+ // create an autoaccel in any case, even if we might not use
+ // it immediately. Maybe the user needs it later.
+ autoaccel = new TQAccel( tqparent, this );
+ connect( autoaccel, TQT_SIGNAL(activated(int)),
+ TQT_SLOT(accelActivated(int)) );
+ connect( autoaccel, TQT_SIGNAL(activatedAmbiguously(int)),
+ TQT_SLOT(accelActivated(int)) );
+ connect( autoaccel, TQT_SIGNAL(destroyed()),
+ TQT_SLOT(accelDestroyed()) );
+ if ( accelDisabled )
+ autoaccel->setEnabled( FALSE );
+ }
+ while ( (mi=it.current()) ) {
+ ++it;
+ TQKeySequence k = mi->key();
+ if ( (int)k ) {
+ int id = autoaccel->insertItem( k, mi->id() );
+#ifndef TQT_NO_WHATSTHIS
+ autoaccel->setWhatsThis( id, mi->whatsThis() );
+#endif
+ }
+ if ( !mi->text().isNull() || mi->custom() ) {
+ TQString s = mi->text();
+ int i = s.tqfind('\t');
+
+ // Note: Only looking at the first key in the sequence!
+ if ( (int)k && (int)k != TQt::Key_unknown ) {
+ TQString t = (TQString)mi->key();
+ if ( i >= 0 )
+ s.tqreplace( i+1, s.length()-i, t );
+ else {
+ s += '\t';
+ s += t;
+ }
+ } else if ( !k ) {
+ if ( i >= 0 )
+ s.truncate( i );
+ }
+ if ( s != mi->text() ) {
+ mi->setText( s );
+ badSize = TRUE;
+ }
+ }
+ if ( mi->popup() && tqparent ) { // call recursively
+ // reuse
+ TQPopupMenu* popup = mi->popup();
+ if (!popup->avoid_circularity) {
+ popup->avoid_circularity = 1;
+ popup->updateAccel( tqparent );
+ popup->avoid_circularity = 0;
+ }
+ }
+ }
+}
+
+/*!
+ \internal
+ It would be better to check in the slot.
+*/
+
+void TQPopupMenu::enableAccel( bool enable )
+{
+ if ( autoaccel )
+ autoaccel->setEnabled( enable );
+ accelDisabled = !enable; // rememeber when updateAccel
+ TQMenuItemListIt it(*mitems);
+ register TQMenuItem *mi;
+ while ( (mi=it.current()) ) { // do the same for sub popups
+ ++it;
+ if ( mi->popup() ) // call recursively
+ mi->popup()->enableAccel( enable );
+ }
+}
+#endif
+
+/*!
+ \reimp
+*/
+void TQPopupMenu::setFont( const TQFont &font )
+{
+ TQWidget::setFont( font );
+ badSize = TRUE;
+ if ( isVisible() ) {
+ updateSize();
+ update();
+ }
+}
+
+/*!
+ \reimp
+*/
+void TQPopupMenu::show()
+{
+ if ( !isPopup() && isVisible() )
+ hide();
+
+ if ( isVisible() ) {
+ supressAboutToShow = FALSE;
+ TQWidget::show();
+ return;
+ }
+ if (!supressAboutToShow)
+ emit aboutToShow();
+ else
+ supressAboutToShow = FALSE;
+ performDelayedChanges();
+ updateSize(TRUE);
+
+// NOTE TO ANYONE WONDERING ABOUT TQT_TQWIDGET_FIX_BROKEN_POPUP_MOUSE_FOCUS
+// Menu problems are caused by the fact that the popup menu mouse focus is shifted to the new child widget (which then receives the mouseReleaseEvent) pretty much as soon as show() is called
+// This would seem to be a direct violation of the Qt4 documentation, which states:
+// "Qt automatically grabs the mouse when a mouse button is pressed inside a widget; the widget will continue to receive mouse events until the last mouse button is released."
+// Upon closer inspection, it is not:
+// "mouseReleaseEvent() - called when a mouse button is released. A widget receives mouse release events when it has received the corresponding mouse press event. This means that if the user presses the mouse inside your widget, then drags the mouse to somewhere else, then releases, your widget receives the release event. There is one exception: if a popup menu appears while the mouse button is held down, this popup immediately steals the mouse events."
+//
+// Now for the real cause:
+// It's an undocumented change in the mouse event handler
+// qapplication_x11.cpp
+// if ((windowType() == Qt::Popup) && rect().contains(pos) && 0)
+// The "&& 0" is the problem
+// It shuts down a very important chunk of code...
+// ...the chunk that was responsible for mapping the mouse events to any popup menu which was actually *under* the cursor!
+
+ TQWidget::show();
+ popupActive = -1;
+ if(tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SubMenuPopupDelay, this))
+ d->mouseMoveBuffer = TQRegion();
+}
+
+/*!
+ \reimp
+*/
+
+void TQPopupMenu::hide()
+{
+ if ( syncMenu == this && tqApp ) {
+ tqApp->exit_loop();
+ syncMenu = 0;
+ }
+
+ if ( !isVisible() ) {
+ TQWidget::hide();
+ return;
+ }
+ emit aboutToHide();
+
+ actItem = popupActive = -1;
+ if(tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SubMenuPopupDelay, this))
+ d->mouseMoveBuffer = TQRegion();
+ mouseBtDn = FALSE; // mouse button up
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::PopupMenuEnd );
+#endif
+ parentMenu = 0;
+ hidePopups();
+ TQWidget::hide();
+}
+
+
+/*!
+ Calculates the height in pixels of the item in row \a row.
+*/
+int TQPopupMenu::itemHeight( int row ) const
+{
+ return itemHeight( mitems->at( row ) );
+}
+
+/*!
+ \overload
+
+ Calculates the height in pixels of the menu item \a mi.
+*/
+int TQPopupMenu::itemHeight( TQMenuItem *mi ) const
+{
+ if ( mi->widget() )
+ return mi->widget()->height();
+ if ( mi->custom() && mi->custom()->fullSpan() )
+ return mi->custom()->tqsizeHint().height();
+
+ TQFontMetrics fm(fontMetrics());
+ int h = 0;
+ if ( mi->isSeparator() ) // separator height
+ h = 2;
+ else if ( mi->pixmap() ) // pixmap height
+ h = mi->pixmap()->height();
+ else // text height
+ h = fm.height();
+
+ if ( !mi->isSeparator() && mi->iconSet() != 0 )
+ h = TQMAX(h, mi->iconSet()->pixmap( TQIconSet::Small,
+ TQIconSet::Normal ).height());
+ if ( mi->custom() )
+ h = TQMAX(h, mi->custom()->tqsizeHint().height());
+
+ return h;
+}
+
+
+/*!
+ Draws menu item \a mi in the area \a x, \a y, \a w, \a h, using
+ painter \a p. The item is drawn active if \a act is TRUE or drawn
+ inactive if \a act is FALSE. The rightmost \a tab_ pixels are used
+ for accelerator text.
+
+ \sa TQStyle::tqdrawControl()
+*/
+void TQPopupMenu::drawItem( TQPainter* p, int tab_, TQMenuItem* mi,
+ bool act, int x, int y, int w, int h)
+{
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled() && mi->isEnabledAndVisible() && (!mi->popup() || mi->popup()->isEnabled()) )
+ flags |= TQStyle::Style_Enabled;
+ if (act)
+ flags |= TQStyle::Style_Active;
+ if (mouseBtDn)
+ flags |= TQStyle::Style_Down;
+
+ const TQColorGroup &cg = ((flags&TQStyle::Style_Enabled) ? tqcolorGroup() : tqpalette().disabled() );
+
+ if ( mi->custom() && mi->custom()->fullSpan() ) {
+ TQMenuItem dummy;
+ tqstyle().tqdrawControl(TQStyle::CE_PopupMenuItem, p, this, TQRect(x, y, w, h), cg,
+ flags, TQStyleOption(&dummy,maxPMWidth,tab_));
+ mi->custom()->paint( p, cg, act, flags&TQStyle::Style_Enabled, x, y, w, h );
+ } else
+ tqstyle().tqdrawControl(TQStyle::CE_PopupMenuItem, p, this, TQRect(x, y, w, h), cg,
+ flags, TQStyleOption(mi,maxPMWidth,tab_));
+}
+
+
+/*!
+ Draws all menu items using painter \a p.
+*/
+void TQPopupMenu::drawContents( TQPainter* p )
+{
+ TQMenuItemListIt it(*mitems);
+ TQMenuItem *mi = 0;
+ int row = 0;
+ int x = contentsRect().x();
+ int y = contentsRect().y();
+ if(d->scroll.scrollable) {
+ if(d->scroll.topScrollableIndex) {
+ for( ; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++)
+ ++it;
+ if(!mi)
+ it.toFirst();
+ }
+ if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollUp) {
+ TQRect rect(x, y, contentsRect().width(),
+ tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this));
+ if(!p->hasClipping() || TQT_TQREGION_OBJECT(p->clipRegion()).tqcontains(rect)) {
+ TQStyle::SFlags flags = TQStyle::Style_Up;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ tqstyle().tqdrawControl(TQStyle::CE_PopupMenuScroller, p, this, rect,
+ tqcolorGroup(), flags, TQStyleOption(maxPMWidth));
+ }
+ y += rect.height();
+ }
+ }
+
+ int itemw = contentsRect().width() / ncols;
+ TQSize sz;
+ TQStyle::SFlags flags;
+ while ( (mi=it.current()) ) {
+ if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown &&
+ y >= contentsRect().height() - tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this))
+ break;
+ ++it;
+ if ( !mi->isVisible() ) {
+ ++row;
+ continue;
+ }
+ int itemh = itemHeight( mi );
+ sz = tqstyle().tqsizeFromContents(TQStyle::CT_PopupMenuItem, this,
+ TQSize(0, itemh),
+ TQStyleOption(mi,maxPMWidth,0)
+ );
+ sz = sz.expandedTo(TQSize(itemw, sz.height()));
+ itemw = sz.width();
+ itemh = sz.height();
+
+ if ( ncols > 1 && y + itemh > contentsRect().bottom() ) {
+ if ( y < contentsRect().bottom() ) {
+ TQRect rect(x, y, itemw, contentsRect().bottom() - y);
+ if(!p->hasClipping() || TQT_TQREGION_OBJECT(p->clipRegion()).tqcontains(rect)) {
+ flags = TQStyle::Style_Default;
+ if (isEnabled() && mi->isEnabledAndVisible())
+ flags |= TQStyle::Style_Enabled;
+ tqstyle().tqdrawControl(TQStyle::CE_PopupMenuItem, p, this, rect,
+ tqcolorGroup(), flags, TQStyleOption((TQMenuItem*)0,maxPMWidth));
+ }
+ }
+ y = contentsRect().y();
+ x +=itemw;
+ }
+ if (!mi->widget() && (!p->hasClipping() || TQT_TQREGION_OBJECT(p->clipRegion()).tqcontains(TQRect(x, y, itemw, itemh))))
+ drawItem( p, tab, mi, row == actItem, x, y, itemw, itemh );
+ y += itemh;
+ ++row;
+ }
+ if ( y < contentsRect().bottom() ) {
+ TQRect rect(x, y, itemw, contentsRect().bottom() - y);
+ if(!p->hasClipping() || TQT_TQREGION_OBJECT(p->clipRegion()).tqcontains(rect)) {
+ flags = TQStyle::Style_Default;
+ if ( isEnabled() )
+ flags |= TQStyle::Style_Enabled;
+ tqstyle().tqdrawControl(TQStyle::CE_PopupMenuItem, p, this, rect,
+ tqcolorGroup(), flags, TQStyleOption((TQMenuItem*)0,maxPMWidth));
+ }
+ }
+ if( d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown ) {
+ int sh = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+ TQRect rect(x, contentsRect().height() - sh, contentsRect().width(), sh);
+ if(!p->hasClipping() || TQT_TQREGION_OBJECT(p->clipRegion()).tqcontains(rect)) {
+ TQStyle::SFlags flags = TQStyle::Style_Down;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ tqstyle().tqdrawControl(TQStyle::CE_PopupMenuScroller, p, this, rect,
+ tqcolorGroup(), flags, TQStyleOption(maxPMWidth));
+ }
+ }
+#if defined( DEBUG_SLOPPY_SUBMENU )
+ if ( tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SloppySubMenus, this )) {
+ p->setClipRegion( d->mouseMoveBuffer );
+ p->fillRect( d->mouseMoveBuffer.boundingRect(), tqcolorGroup().brush( TQColorGroup::Highlight ) );
+ }
+#endif
+}
+
+
+/*****************************************************************************
+ Event handlers
+ *****************************************************************************/
+
+/*!
+ \reimp
+*/
+
+void TQPopupMenu::paintEvent( TQPaintEvent *e )
+{
+ TQFrame::paintEvent( e );
+}
+
+/*!
+ \reimp
+*/
+
+void TQPopupMenu::closeEvent( TQCloseEvent * e) {
+ e->accept();
+ byeMenuBar();
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQPopupMenu::mousePressEvent( TQMouseEvent *e )
+{
+ int sh = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+ if (TQT_TQRECT_OBJECT(rect()).tqcontains(e->pos()) &&
+ ((d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || //up
+ (d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown &&
+ e->pos().y() >= contentsRect().height() - sh))) //down
+ return;
+
+ mouseBtDn = TRUE; // mouse button down
+ int item = itemAtPos( e->pos() );
+ if ( item == -1 ) {
+ if ( !TQT_TQRECT_OBJECT(rect()).tqcontains(e->pos()) && !tryMenuBar(e) ) {
+ byeMenuBar();
+ }
+ return;
+ }
+ register TQMenuItem *mi = mitems->at(item);
+ if ( item != actItem ) // new item activated
+ setActiveItem( item );
+
+ TQPopupMenu *popup = mi->popup();
+ if ( popup ) {
+ if ( popup->isVisible() ) { // sub menu already open
+ int pactItem = popup->actItem;
+ popup->actItem = -1;
+ popup->hidePopups();
+ popup->updateRow( pactItem );
+ } else { // open sub menu
+ hidePopups();
+ popupSubMenuLater( 20, this );
+ }
+ } else {
+ hidePopups();
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQPopupMenu::mouseReleaseEvent( TQMouseEvent *e )
+{
+ // do not hide a standalone context menu on press-release, unless
+ // the user moved the mouse significantly
+ if ( !parentMenu && !mouseBtDn && actItem < 0 && motion < 6 )
+ return;
+
+ mouseBtDn = FALSE;
+
+ // if the user released the mouse outside the menu, pass control
+ // to the menubar or our parent menu
+ int sh = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+
+ if ( !TQT_TQRECT_OBJECT(rect()).tqcontains( e->pos() ) && tryMenuBar(e) ) {
+ return;
+ }
+ else if((d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) || //up
+ (d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown &&
+ e->pos().y() >= contentsRect().height() - sh)) //down
+ return;
+
+ if ( actItem < 0 ) { // we do not have an active item
+ // if the release is inside without motion (happens with
+ // oversized popup menus on small screens), ignore it
+ if ( TQT_TQRECT_OBJECT(rect()).tqcontains( e->pos() ) && motion < 6 )
+ return;
+ else
+ byeMenuBar();
+ } else { // selected menu item!
+ register TQMenuItem *mi = mitems->at(actItem);
+ if ( mi ->widget() ) {
+ TQWidget* widgetAt = TQApplication::widgetAt( e->globalPos(), TRUE );
+ if ( widgetAt && widgetAt != this ) {
+ TQMouseEvent me( e->type(), widgetAt->mapFromGlobal( e->globalPos() ),
+ e->globalPos(), e->button(), e->state() );
+ TQApplication::sendEvent( widgetAt, &me );
+ }
+ }
+ TQPopupMenu *popup = mi->popup();
+#ifndef TQT_NO_WHATSTHIS
+ bool b = TQWhatsThis::inWhatsThisMode();
+#else
+ const bool b = FALSE;
+#endif
+ if ( !mi->isEnabledAndVisible() ) {
+#ifndef TQT_NO_WHATSTHIS
+ if ( b ) {
+ actItem = -1;
+ updateItem( mi->id() );
+ byeMenuBar();
+ actSig( mi->id(), b);
+ }
+#endif
+ } else if ( popup ) {
+ popup->setFirstItemActive();
+ } else { // normal menu item
+ byeMenuBar(); // deactivate menu bar
+ if ( mi->isEnabledAndVisible() ) {
+ actItem = -1;
+ updateItem( mi->id() );
+ active_popup_menu = this;
+ TQGuardedPtr<TQSignal> signal = mi->signal();
+ actSig( mi->id(), b );
+ if ( signal && !b )
+ signal->activate();
+ active_popup_menu = 0;
+ }
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQPopupMenu::mouseMoveEvent( TQMouseEvent *e )
+{
+ motion++;
+
+ if ( parentMenu && parentMenu->isPopupMenu ) {
+ TQPopupMenu* p = (TQPopupMenu*)parentMenu;
+ int myIndex;
+
+ p->tqfindPopup( this, &myIndex );
+ TQPoint pPos = p->mapFromParent( e->globalPos() );
+ if ( p->actItem != myIndex && !TQT_TQRECT_OBJECT(p->rect()).tqcontains( pPos ) )
+ p->setActiveItem( myIndex );
+
+ if ( tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SloppySubMenus, this )) {
+ p->d->mouseMoveBuffer = TQRegion();
+#ifdef DEBUG_SLOPPY_SUBMENU
+ p->tqrepaint();
+#endif
+ }
+ }
+
+ if ( (e->state() & Qt::MouseButtonMask) == 0 &&
+ !hasMouseTracking() )
+ return;
+
+ if(d->scroll.scrollable && e->pos().x() >= rect().x() && e->pos().x() <= rect().width()) {
+ int sh = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+ if((d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollUp && e->pos().y() <= sh) ||
+ (d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown && e->pos().y() >= height()-sh)) {
+ if(!d->scroll.scrolltimer) {
+ d->scroll.scrolltimer = new TQTimer(this, "popup scroll timer");
+ TQObject::connect( d->scroll.scrolltimer, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(subScrollTimer()) );
+ }
+ if(!d->scroll.scrolltimer->isActive())
+ d->scroll.scrolltimer->start(40);
+ return;
+ }
+ }
+
+ int item = itemAtPos( e->pos() );
+ if ( item == -1 ) { // no valid item
+ int lastActItem = actItem;
+ actItem = -1;
+ if ( lastActItem >= 0 )
+ updateRow( lastActItem );
+ if ( lastActItem > 0 ||
+ ( !TQT_TQRECT_OBJECT(rect()).tqcontains( e->pos() ) && !tryMenuBar( e ) ) ) {
+ popupSubMenuLater(tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SubMenuPopupDelay,
+ this), this);
+ }
+ } else { // mouse on valid item
+ // but did not register mouse press
+ if ( (e->state() & Qt::MouseButtonMask) && !mouseBtDn )
+ mouseBtDn = TRUE; // so mouseReleaseEvent will pop down
+
+ register TQMenuItem *mi = mitems->at( item );
+
+ if ( mi->widget() ) {
+ TQWidget* widgetAt = TQApplication::widgetAt( e->globalPos(), TRUE );
+ if ( widgetAt && widgetAt != this ) {
+ TQMouseEvent me( e->type(), widgetAt->mapFromGlobal( e->globalPos() ),
+ e->globalPos(), e->button(), e->state() );
+ TQApplication::sendEvent( widgetAt, &me );
+ }
+ }
+
+ if ( actItem == item )
+ return;
+
+ if ( tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SloppySubMenus, this) &&
+ d->mouseMoveBuffer.tqcontains( e->pos() ) ) {
+ actItem = item;
+ popupSubMenuLater( tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SubMenuPopupDelay, this) * 6,
+ this );
+ return;
+ }
+
+ if ( mi->popup() || ( popupActive >= 0 && popupActive != item )) {
+ popupSubMenuLater( tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SubMenuPopupDelay, this),
+ this );
+ }
+ else if ( singleSingleShot ) {
+ singleSingleShot->stop();
+ }
+
+ if ( item != actItem ) {
+ setActiveItem( item );
+ }
+ }
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQPopupMenu::keyPressEvent( TQKeyEvent *e )
+{
+ /*
+ I get nothing but complaints about this. -Brad
+
+ - if (mouseBtDn && actItem >= 0) {
+ - if (e->key() == Qt::Key_Shift ||
+ - e->key() == Qt::Key_Control ||
+ - e->key() == Qt::Key_Alt)
+ - return;
+ -
+ - TQMenuItem *mi = mitems->at(actItem);
+ - int modifier = (((e->state() & ShiftButton) ? SHIFT : 0) |
+ - ((e->state() & ControlButton) ? CTRL : 0) |
+ - ((e->state() & AltButton) ? ALT : 0));
+ -
+ - #ifndef TQT_NO_ACCEL
+ - if (mi)
+ - setAccel(modifier + e->key(), mi->id());
+ - #endif
+ - return;
+ - }
+ */
+
+ TQMenuItem *mi = 0;
+ TQPopupMenu *popup;
+ int dy = 0;
+ bool ok_key = TRUE;
+
+ int key = e->key();
+ if ( TQApplication::reverseLayout() ) {
+ // in reverse mode opening and closing keys for submenues are reversed
+ if ( key == Qt::Key_Left )
+ key = Qt::Key_Right;
+ else if ( key == Qt::Key_Right )
+ key = Qt::Key_Left;
+ }
+
+ switch ( key ) {
+ case Qt::Key_Tab:
+ // ignore tab, otherwise it will be passed to the menubar
+ break;
+
+ case Qt::Key_Up:
+ dy = -1;
+ break;
+
+ case Qt::Key_Down:
+ dy = 1;
+ break;
+
+ case Qt::Key_Alt:
+ if ( tqstyle().tqstyleHint(TQStyle::SH_MenuBar_AltKeyNavigation, this) )
+ byeMenuBar();
+ break;
+
+ case Key_Escape:
+ if ( tornOff ) {
+ close();
+ return;
+ }
+ // just hide one
+ {
+ TQMenuData* p = parentMenu;
+ hide();
+#ifndef TQT_NO_MENUBAR
+ if ( p && p->isMenuBar )
+ ((TQMenuBar*) p)->goodbye( TRUE );
+#endif
+ }
+ break;
+
+ case Qt::Key_Left:
+ if ( ncols > 1 && actItem >= 0 ) {
+ TQRect r( itemGeometry( actItem ) );
+ int newActItem = itemAtPos( TQPoint( r.left() - 1, r.center().y() ) );
+ if ( newActItem >= 0 ) {
+ setActiveItem( newActItem );
+ break;
+ }
+ }
+ if ( parentMenu && parentMenu->isPopupMenu ) {
+ ((TQPopupMenu *)parentMenu)->hidePopups();
+ if ( singleSingleShot )
+ singleSingleShot->stop();
+ break;
+ }
+
+ ok_key = FALSE;
+ break;
+
+ case Qt::Key_Right:
+ if ( actItem >= 0 && ( mi=mitems->at(actItem) )->isEnabledAndVisible() && (popup=mi->popup()) ) {
+ hidePopups();
+ if ( singleSingleShot )
+ singleSingleShot->stop();
+ // ### The next two lines were switched to fix the problem with the first item of the
+ // submenu not being highlighted...any reason why they should have been the other way??
+ subMenuTimer();
+ popup->setFirstItemActive();
+ break;
+ } else if ( actItem == -1 && ( parentMenu && !parentMenu->isMenuBar )) {
+ dy = 1;
+ break;
+ }
+ if ( ncols > 1 && actItem >= 0 ) {
+ TQRect r( itemGeometry( actItem ) );
+ int newActItem = itemAtPos( TQPoint( r.right() + 1, r.center().y() ) );
+ if ( newActItem >= 0 ) {
+ setActiveItem( newActItem );
+ break;
+ }
+ }
+ ok_key = FALSE;
+ break;
+
+ case Qt::Key_Space:
+ if (! tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SpaceActivatesItem, this))
+ break;
+ // for motif, fall through
+
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ {
+ if ( actItem < 0 )
+ break;
+#ifndef TQT_NO_WHATSTHIS
+ bool b = TQWhatsThis::inWhatsThisMode();
+#else
+ const bool b = FALSE;
+#endif
+ mi = mitems->at( actItem );
+ if ( !mi->isEnabled() && !b )
+ break;
+ popup = mi->popup();
+ if ( popup ) {
+ hidePopups();
+ popupSubMenuLater( 20, this );
+ popup->setFirstItemActive();
+ } else {
+ actItem = -1;
+ updateItem( mi->id() );
+ byeMenuBar();
+ if ( mi->isEnabledAndVisible() || b ) {
+ active_popup_menu = this;
+ TQGuardedPtr<TQSignal> signal = mi->signal();
+ actSig( mi->id(), b );
+ if ( signal && !b )
+ signal->activate();
+ active_popup_menu = 0;
+ }
+ }
+ }
+ break;
+#ifndef TQT_NO_WHATSTHIS
+ case Qt::Key_F1:
+ if ( actItem < 0 || e->state() != ShiftButton)
+ break;
+ mi = mitems->at( actItem );
+ if ( !mi->whatsThis().isNull() ){
+ if ( !TQWhatsThis::inWhatsThisMode() )
+ TQWhatsThis::enterWhatsThisMode();
+ TQRect r( itemGeometry( actItem) );
+ TQWhatsThis::leaveWhatsThisMode( mi->whatsThis(), mapToGlobal( r.bottomLeft()) );
+ }
+ //fall-through!
+#endif
+ default:
+ ok_key = FALSE;
+
+ }
+ if ( !ok_key &&
+ ( !e->state() || e->state() == TQt::AltButton || e->state() == ShiftButton ) &&
+ e->text().length()==1 ) {
+ TQChar c = TQT_TQCHAR(e->text()[0]).upper();
+
+ TQMenuItemListIt it(*mitems);
+ TQMenuItem* first = 0;
+ TQMenuItem* currentSelected = 0;
+ TQMenuItem* firstAfterCurrent = 0;
+
+ register TQMenuItem *m;
+ mi = 0;
+ int indx = 0;
+ int clashCount = 0;
+ while ( (m=it.current()) ) {
+ ++it;
+ TQString s = m->text();
+ if ( !s.isEmpty() ) {
+ int i = s.tqfind( '&' );
+ while ( i >= 0 && i < (int)s.length() - 1 ) {
+ if ( s[i+1].upper() == c ) {
+ ok_key = TRUE;
+ clashCount++;
+ if ( !first )
+ first = m;
+ if ( indx == actItem )
+ currentSelected = m;
+ else if ( !firstAfterCurrent && currentSelected )
+ firstAfterCurrent = m;
+ break;
+ } else if ( s[i+1] == '&' ) {
+ i = s.tqfind( '&', i+2 );
+ } else {
+ break;
+ }
+ }
+ }
+ if ( mi )
+ break;
+ indx++;
+ }
+
+ if ( 1 == clashCount ) { // No clashes, continue with selection
+ mi = first;
+ popup = mi->popup();
+ if ( popup ) {
+ setActiveItem( indexOf(mi->id()) );
+ hidePopups();
+ popupSubMenuLater( 20, this );
+ popup->setFirstItemActive();
+ } else {
+ byeMenuBar();
+#ifndef TQT_NO_WHATSTHIS
+ bool b = TQWhatsThis::inWhatsThisMode();
+#else
+ const bool b = FALSE;
+#endif
+ if ( mi->isEnabledAndVisible() || b ) {
+ active_popup_menu = this;
+ TQGuardedPtr<TQSignal> signal = mi->signal();
+ actSig( mi->id(), b );
+ if ( signal && !b )
+ signal->activate();
+ active_popup_menu = 0;
+ }
+ }
+ } else if ( clashCount > 1 ) { // Clashes, highlight next...
+ // If there's clashes and no one is selected, use first one
+ // or if there is no clashes _after_ current, use first one
+ if ( !currentSelected || (currentSelected && !firstAfterCurrent))
+ dy = indexOf( first->id() ) - actItem;
+ else
+ dy = indexOf( firstAfterCurrent->id() ) - actItem;
+ }
+ }
+#ifndef TQT_NO_MENUBAR
+ if ( !ok_key ) { // send to menu bar
+ register TQMenuData *top = this; // tqfind top level
+ while ( top->parentMenu )
+ top = top->parentMenu;
+ if ( top->isMenuBar ) {
+ int beforeId = top->actItem;
+ ((TQMenuBar*)top)->tryKeyEvent( this, e );
+ if ( beforeId != top->actItem )
+ ok_key = TRUE;
+ }
+ }
+#endif
+ if ( actItem < 0 ) {
+ if ( dy > 0 ) {
+ setFirstItemActive();
+ } else if ( dy < 0 ) {
+ TQMenuItemListIt it(*mitems);
+ it.toLast();
+ register TQMenuItem *mi;
+ int ai = count() - 1;
+ while ( (mi=it.current()) ) {
+ --it;
+ if ( !mi->isSeparator() && mi->id() != TQMenuData::d->aInt ) {
+ setActiveItem( ai );
+ return;
+ }
+ ai--;
+ }
+ actItem = -1;
+ }
+ return;
+ }
+
+ if ( dy ) { // highlight next/prev
+ register int i = actItem;
+ int c = mitems->count();
+ for(int n = c; n; n--) {
+ i = i + dy;
+ if(d->scroll.scrollable) {
+ if(d->scroll.scrolltimer)
+ d->scroll.scrolltimer->stop();
+ if(i < 0)
+ i = 0;
+ else if(i >= c)
+ i = c - 1;
+ } else {
+ if ( i == c )
+ i = 0;
+ else if ( i < 0 )
+ i = c - 1;
+ }
+ mi = mitems->at( i );
+ if ( !mi || !mi->isVisible() )
+ continue;
+
+ if ( !mi->isSeparator() &&
+ ( tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_AllowActiveAndDisabled, this)
+ || mi->isEnabledAndVisible() ) )
+ break;
+ }
+ if ( i != actItem )
+ setActiveItem( i );
+ if(d->scroll.scrollable) { //need to scroll to make it visible?
+ TQRect r = itemGeometry(actItem);
+ if(r.isNull() || r.height() < itemHeight(mitems->at(actItem))) {
+ bool refresh = FALSE;
+ if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollUp && dy == -1) { //up
+ if(d->scroll.topScrollableIndex >= 0) {
+ d->scroll.topScrollableIndex--;
+ refresh = TRUE;
+ }
+ } else if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown) { //down
+ TQMenuItemListIt it(*mitems);
+ int sh = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+ for(int i = 0, y = ((d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollUp) ? sh : 0); it.current(); i++, ++it) {
+ if(i >= d->scroll.topScrollableIndex) {
+ int itemh = itemHeight(it.current());
+ TQSize sz = tqstyle().tqsizeFromContents(TQStyle::CT_PopupMenuItem, this,
+ TQSize(0, itemh),
+ TQStyleOption(it.current(),maxPMWidth,0));
+ y += sz.height();
+ if(y > (contentsRect().height()-sh)) {
+ if(sz.height() > sh || !it.atLast())
+ d->scroll.topScrollableIndex++;
+ refresh = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if(refresh) {
+ updateScrollerState();
+ update();
+ }
+ }
+ }
+ }
+
+#ifdef TQ_OS_WIN32
+ if ( !ok_key &&
+ !( e->key() == Qt::Key_Control || e->key() == Qt::Key_Shift || e->key() == Qt::Key_Meta ) )
+ tqApp->beep();
+#endif // TQ_OS_WIN32
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQPopupMenu::timerEvent( TQTimerEvent *e )
+{
+ TQFrame::timerEvent( e );
+}
+
+/*!
+ \reimp
+*/
+void TQPopupMenu::leaveEvent( TQEvent * )
+{
+ if ( testWFlags( TQt::WStyle_Tool ) && tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_MouseTracking, this) ) {
+ int lastActItem = actItem;
+ actItem = -1;
+ if ( lastActItem >= 0 )
+ updateRow( lastActItem );
+ }
+}
+
+/*!
+ \reimp
+*/
+void TQPopupMenu::styleChange( TQStyle& old )
+{
+ TQFrame::styleChange( old );
+ setMouseTracking(tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_MouseTracking, this));
+ tqstyle().polishPopupMenu( this );
+ updateSize(TRUE);
+}
+
+/*!\reimp
+ */
+void TQPopupMenu::enabledChange( bool )
+{
+ if ( TQMenuData::d->aWidget ) // torn-off menu
+ TQMenuData::d->aWidget->setEnabled( isEnabled() );
+}
+
+
+/*!
+ If a popup menu does not fit on the screen it lays itself out so
+ that it does fit. It is style dependent what tqlayout means (for
+ example, on Windows it will use multiple columns).
+
+ This functions returns the number of columns necessary.
+
+ \sa tqsizeHint()
+*/
+int TQPopupMenu::columns() const
+{
+ return ncols;
+}
+
+/* This private slot handles the scrolling popupmenu */
+void TQPopupMenu::subScrollTimer() {
+ TQPoint pos = TQCursor::pos();
+ if(!d->scroll.scrollable || !isVisible()) {
+ if(d->scroll.scrolltimer)
+ d->scroll.scrolltimer->stop();
+ return;
+ } else if(pos.x() > x() + width() || pos.x() < x()) {
+ return;
+ }
+ int sh = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+ if(!d->scroll.lastScroll.isValid()) {
+ d->scroll.lastScroll = TQTime::currentTime();
+ } else {
+ int factor=0;
+ if(pos.y() < y())
+ factor = y() - pos.y();
+ else if(pos.y() > y() + height())
+ factor = pos.y() - (y() + height());
+ int msecs = 250 - ((factor / 10) * 40);
+ if(d->scroll.lastScroll.msecsTo(TQTime::currentTime()) < TQMAX(0, msecs))
+ return;
+ d->scroll.lastScroll = TQTime::currentTime();
+ }
+ if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollUp && pos.y() <= y() + sh) { //up
+ if(d->scroll.topScrollableIndex > 0) {
+ d->scroll.topScrollableIndex--;
+ updateScrollerState();
+ update(contentsRect());
+ }
+ } else if(d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollDown &&
+ pos.y() >= (y() + contentsRect().height()) - sh) { //down
+ TQMenuItemListIt it(*mitems);
+ for(int i = 0, y = contentsRect().y() + sh; it.current(); i++, ++it) {
+ if(i >= d->scroll.topScrollableIndex) {
+ int itemh = itemHeight(it.current());
+ TQSize sz = tqstyle().tqsizeFromContents(TQStyle::CT_PopupMenuItem, this, TQSize(0, itemh),
+ TQStyleOption(it.current(),maxPMWidth,0));
+ y += sz.height();
+ if(y > contentsRect().height() - sh) {
+ d->scroll.topScrollableIndex++;
+ updateScrollerState();
+ update(contentsRect());
+ break;
+ }
+ }
+ }
+ }
+}
+
+/* This private slot handles the delayed submenu effects */
+
+void TQPopupMenu::subMenuTimer() {
+ if ( !isVisible() || (actItem < 0 && popupActive < 0) || actItem == popupActive )
+ return;
+
+ if ( popupActive >= 0 ) {
+ hidePopups();
+ popupActive = -1;
+ }
+
+ // hidePopups() may change actItem etc.
+ if ( !isVisible() || actItem < 0 || actItem == popupActive )
+ return;
+
+ TQMenuItem *mi = mitems->at(actItem);
+ if ( !mi || !mi->isEnabledAndVisible() )
+ return;
+
+ TQPopupMenu *popup = mi->popup();
+ if ( !popup || !popup->isEnabled() )
+ return;
+
+ //avoid circularity
+ if ( popup->isVisible() )
+ return;
+
+ TQ_ASSERT( popup->parentMenu == 0 );
+ popup->parentMenu = this; // set parent menu
+
+ emit popup->aboutToShow();
+ supressAboutToShow = TRUE;
+
+
+ TQRect r( itemGeometry( actItem ) );
+ TQPoint p;
+ TQSize ps = popup->tqsizeHint();
+ if( TQApplication::reverseLayout() ) {
+ p = TQPoint( r.left() + motifArrowHMargin - ps.width(), r.top() + motifArrowVMargin );
+ p = mapToGlobal( p );
+
+ bool right = FALSE;
+ if ( ( parentMenu && parentMenu->isPopupMenu &&
+ ((TQPopupMenu*)parentMenu)->tqgeometry().x() < tqgeometry().x() ) ||
+ p.x() < 0 )
+ right = TRUE;
+ if ( right && (ps.width() > TQApplication::desktop()->width() - mapToGlobal( r.topRight() ).x() ) )
+ right = FALSE;
+ if ( right )
+ p.setX( mapToGlobal( r.topRight() ).x() );
+ } else {
+ p = TQPoint( r.right() - motifArrowHMargin, r.top() + motifArrowVMargin );
+ p = mapToGlobal( p );
+
+ bool left = FALSE;
+ if ( ( parentMenu && parentMenu->isPopupMenu &&
+ ((TQPopupMenu*)parentMenu)->tqgeometry().x() > tqgeometry().x() ) ||
+ p.x() + ps.width() > TQApplication::desktop()->width() )
+ left = TRUE;
+ if ( left && (ps.width() > mapToGlobal( r.topLeft() ).x() ) )
+ left = FALSE;
+ if ( left )
+ p.setX( mapToGlobal( r.topLeft() ).x() - ps.width() );
+ }
+ TQRect pr = popup->itemGeometry(popup->count() - 1);
+ if (p.y() + ps.height() > TQApplication::desktop()->height() &&
+ p.y() - ps.height() + (TQCOORD) pr.height() >= 0)
+ p.setY( p.y() - ps.height() + (TQCOORD) pr.height());
+
+ if ( tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_SloppySubMenus, this )) {
+ TQPoint cur = TQCursor::pos();
+ if ( r.tqcontains( mapFromGlobal( cur ) ) ) {
+ TQPoint pts[4];
+ pts[0] = TQPoint( cur.x(), cur.y() - 2 );
+ pts[3] = TQPoint( cur.x(), cur.y() + 2 );
+ if ( p.x() >= cur.x() ) {
+ pts[1] = TQPoint( tqgeometry().right(), p.y() );
+ pts[2] = TQPoint( tqgeometry().right(), p.y() + ps.height() );
+ } else {
+ pts[1] = TQPoint( p.x() + ps.width(), p.y() );
+ pts[2] = TQPoint( p.x() + ps.width(), p.y() + ps.height() );
+ }
+ TQPointArray points( 4 );
+ for( int i = 0; i < 4; i++ )
+ points.setPoint( i, mapFromGlobal( pts[i] ) );
+ d->mouseMoveBuffer = TQRegion( points );
+ tqrepaint();
+ }
+ }
+
+ popupActive = actItem;
+ popup->popup( p );
+}
+
+void TQPopupMenu::allowAnimation()
+{
+ preventAnimation = FALSE;
+}
+
+void TQPopupMenu::updateRow( int row )
+{
+ if ( !isVisible() )
+ return;
+
+ if ( badSize ) {
+ updateSize();
+ update();
+ return;
+ }
+ updateSize();
+ TQRect r = itemGeometry( row );
+ if ( !r.isNull() ) // can happen via the scroller
+ tqrepaint( r );
+}
+
+
+/*!
+ \overload
+
+ Executes this popup synchronously.
+
+ Opens the popup menu so that the item number \a indexAtPoint will
+ be at the specified \e global position \a pos. To translate a
+ widget's local coordinates into global coordinates, use
+ TQWidget::mapToGlobal().
+
+ The return code is the id of the selected item in either the popup
+ menu or one of its submenus, or -1 if no item is selected
+ (normally because the user pressed Esc).
+
+ Note that all Q_SIGNALS are emitted as usual. If you connect a menu
+ item to a slot and call the menu's exec(), you get the result both
+ via the signal-slot connection and in the return value of exec().
+
+ Common usage is to position the popup at the current mouse
+ position:
+ \code
+ exec( TQCursor::pos() );
+ \endcode
+ or aligned to a widget:
+ \code
+ exec( somewidget.mapToGlobal(TQPoint(0, 0)) );
+ \endcode
+
+ When positioning a popup with exec() or popup(), bear in mind that
+ you cannot rely on the popup menu's current size(). For
+ performance reasons, the popup adapts its size only when
+ necessary. So in many cases, the size before and after the show is
+ different. Instead, use tqsizeHint(). It calculates the proper size
+ depending on the menu's current contents.
+
+ \sa popup(), tqsizeHint()
+*/
+
+int TQPopupMenu::exec( const TQPoint & pos, int indexAtPoint )
+{
+ snapToMouse = TRUE;
+ if ( !tqApp )
+ return -1;
+
+ TQPopupMenu* priorSyncMenu = syncMenu;
+
+ syncMenu = this;
+ syncMenuId = -1;
+
+ TQGuardedPtr<TQPopupMenu> that = this;
+ connectModal( that, TRUE );
+ popup( pos, indexAtPoint );
+ tqApp->enter_loop();
+ connectModal( that, FALSE );
+
+ syncMenu = priorSyncMenu;
+ return syncMenuId;
+}
+
+
+
+/*
+ Connect the popup and all its submenus to modalActivation() if
+ \a doConnect is true, otherwise disconnect.
+ */
+void TQPopupMenu::connectModal( TQPopupMenu* receiver, bool doConnect )
+{
+ if ( !receiver )
+ return;
+
+ connectModalRecursionSafety = doConnect;
+
+ if ( doConnect )
+ connect( this, TQT_SIGNAL(activated(int)),
+ receiver, TQT_SLOT(modalActivation(int)) );
+ else
+ disconnect( this, TQT_SIGNAL(activated(int)),
+ receiver, TQT_SLOT(modalActivation(int)) );
+
+ TQMenuItemListIt it(*mitems);
+ register TQMenuItem *mi;
+ while ( (mi=it.current()) ) {
+ ++it;
+ if ( mi->popup() && mi->popup() != receiver
+ && (bool)(mi->popup()->connectModalRecursionSafety) != doConnect )
+ mi->popup()->connectModal( receiver, doConnect ); //avoid circular
+ }
+}
+
+
+/*!
+ Executes this popup synchronously.
+
+ This is equivalent to \c{exec(mapToGlobal(TQPoint(0,0)))}. In most
+ situations you'll want to specify the position yourself, for
+ example at the current mouse position:
+ \code
+ exec(TQCursor::pos());
+ \endcode
+ or aligned to a widget:
+ \code
+ exec(somewidget.mapToGlobal(TQPoint(0,0)));
+ \endcode
+*/
+
+int TQPopupMenu::exec()
+{
+ return exec(mapToGlobal(TQPoint(0,0)));
+}
+
+
+/* Internal slot used for exec(). */
+
+void TQPopupMenu::modalActivation( int id )
+{
+ syncMenuId = id;
+}
+
+
+/*!
+ Sets the currently active item to index \a i and repaints as necessary.
+*/
+
+void TQPopupMenu::setActiveItem( int i )
+{
+ int lastActItem = actItem;
+ actItem = i;
+ if ( lastActItem >= 0 )
+ updateRow( lastActItem );
+ if ( i >= 0 && i != lastActItem )
+ updateRow( i );
+ TQMenuItem *mi = mitems->at( actItem );
+ if ( !mi )
+ return;
+
+ if ( mi->widget() && mi->widget()->isFocusEnabled() ) {
+ mi->widget()->setFocus();
+ } else {
+ setFocus();
+ TQRect mfrect = itemGeometry( actItem );
+ setMicroFocusHint( mfrect.x(), mfrect.y(), mfrect.width(), mfrect.height(), FALSE );
+ }
+ if ( mi->id() != -1 )
+ hilitSig( mi->id() );
+#ifndef TQT_NO_WHATSTHIS
+ if (whatsThisItem && whatsThisItem != mi) {
+ qWhatsThisBDH();
+ }
+ whatsThisItem = mi;
+#endif
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQPopupMenu::tqsizeHint() const
+{
+ constPolish();
+ TQPopupMenu* that = (TQPopupMenu*) this;
+ //We do not need a resize here, just the tqsizeHint..
+ return that->updateSize(FALSE, FALSE).expandedTo( TQApplication::globalStrut() );
+}
+
+
+/*!
+ \overload
+
+ Returns the id of the item at \a pos, or -1 if there is no item
+ there or if it is a separator.
+*/
+int TQPopupMenu::idAt( const TQPoint& pos ) const
+{
+ return idAt( itemAtPos( pos ) );
+}
+
+
+/*!
+ \fn int TQPopupMenu::idAt( int index ) const
+
+ Returns the identifier of the menu item at position \a index in
+ the internal list, or -1 if \a index is out of range.
+
+ \sa TQMenuData::setId(), TQMenuData::indexOf()
+*/
+
+
+/*!
+ \reimp
+ */
+bool TQPopupMenu::customWhatsThis() const
+{
+ return TRUE;
+}
+
+
+/*!
+ \reimp
+ */
+bool TQPopupMenu::focusNextPrevChild( bool next )
+{
+ register TQMenuItem *mi;
+ int dy = next? 1 : -1;
+ if ( dy && actItem < 0 ) {
+ setFirstItemActive();
+ } else if ( dy ) { // highlight next/prev
+ register int i = actItem;
+ int c = mitems->count();
+ int n = c;
+ while ( n-- ) {
+ i = i + dy;
+ if ( i == c )
+ i = 0;
+ else if ( i < 0 )
+ i = c - 1;
+ mi = mitems->at( i );
+ if ( mi && !mi->isSeparator() &&
+ ( ( tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_AllowActiveAndDisabled, this)
+ && mi->isVisible() )
+ || mi->isEnabledAndVisible() ) )
+ break;
+ }
+ if ( i != actItem )
+ setActiveItem( i );
+ }
+ return TRUE;
+}
+
+
+/*!
+ \reimp
+ */
+void TQPopupMenu::focusInEvent( TQFocusEvent * )
+{
+}
+
+/*!
+ \reimp
+ */
+void TQPopupMenu::focusOutEvent( TQFocusEvent * )
+{
+}
+
+
+class TQTearOffMenuItem : public TQCustomMenuItem
+{
+public:
+ TQTearOffMenuItem()
+ {
+ }
+ ~TQTearOffMenuItem()
+ {
+ }
+ void paint( TQPainter* p, const TQColorGroup& cg, bool /* act*/,
+ bool /*enabled*/, int x, int y, int w, int h )
+ {
+ p->setPen( TQPen( cg.dark(), 1, DashLine ) );
+ p->drawLine( x+2, y+h/2-1, x+w-4, y+h/2-1 );
+ p->setPen( TQPen( cg.light(), 1, DashLine ) );
+ p->drawLine( x+2, y+h/2, x+w-4, y+h/2 );
+ }
+ bool fullSpan() const
+ {
+ return TRUE;
+ }
+
+ TQSize tqsizeHint()
+ {
+ return TQSize( 20, 6 );
+ }
+};
+
+
+
+/*!
+ Inserts a tear-off handle into the menu. A tear-off handle is a
+ special menu item that creates a copy of the menu when the menu is
+ selected. This "torn-off" copy lives in a separate window. It
+ tqcontains the same menu items as the original menu, with the
+ exception of the tear-off handle.
+
+ The handle item is assigned the identifier \a id or an
+ automatically generated identifier if \a id is < 0. The generated
+ identifiers (negative integers) are guaranteed to be unique within
+ the entire application.
+
+ The \a index specifies the position in the menu. The tear-off
+ handle is appended at the end of the list if \a index is negative.
+*/
+int TQPopupMenu::insertTearOffHandle( int id, int index )
+{
+ int myid = insertItem( new TQTearOffMenuItem, id, index );
+ connectItem( myid, TQT_TQOBJECT(this), TQT_SLOT( toggleTearOff() ) );
+ TQMenuData::d->aInt = myid;
+ return myid;
+}
+
+
+/*!\internal
+
+ implements tear-off menus
+ */
+void TQPopupMenu::toggleTearOff()
+{
+ if ( active_popup_menu && active_popup_menu->tornOff ) {
+ active_popup_menu->close();
+ } else if (TQMenuData::d->aWidget ) {
+ delete (TQWidget*) TQMenuData::d->aWidget; // delete the old one
+ } else {
+ // create a tear off menu
+ TQPopupMenu* p = new TQPopupMenu( parentWidget(), "tear off menu" );
+ connect( p, TQT_SIGNAL( activated(int) ), this, TQT_SIGNAL( activated(int) ) );
+ connect( p, TQT_SIGNAL( highlighted(int) ), this, TQT_SIGNAL( highlighted(int) ) );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ p->setCaption( caption() );
+#endif
+ p->setCheckable( isCheckable() );
+ p->reparent( parentWidget(), (WFlags)(TQt::WType_TopLevel | TQt::WStyle_Tool |
+ TQt::WNoAutoErase | TQt::WDestructiveClose),
+ tqgeometry().topLeft(), FALSE );
+ p->mitems->setAutoDelete( FALSE );
+ p->tornOff = TRUE;
+ for ( TQMenuItemListIt it( *mitems ); it.current(); ++it ) {
+ if ( it.current()->id() != TQMenuData::d->aInt && !it.current()->widget() )
+ p->mitems->append( it.current() );
+ }
+ p->show();
+ TQMenuData::d->aWidget = p;
+ }
+}
+
+/*!
+ \reimp
+ */
+void TQPopupMenu::activateItemAt( int index )
+{
+ if ( index >= 0 && index < (int) mitems->count() ) {
+ TQMenuItem *mi = mitems->at( index );
+ if ( index != actItem ) // new item activated
+ setActiveItem( index );
+ TQPopupMenu *popup = mi->popup();
+ if ( popup ) {
+ if ( popup->isVisible() ) { // sub menu already open
+ int pactItem = popup->actItem;
+ popup->actItem = -1;
+ popup->hidePopups();
+ popup->updateRow( pactItem );
+ } else { // open sub menu
+ hidePopups();
+ actItem = index;
+ subMenuTimer();
+ popup->setFirstItemActive();
+ }
+ } else {
+ byeMenuBar(); // deactivate menu bar
+
+#ifndef TQT_NO_WHATSTHIS
+ bool b = TQWhatsThis::inWhatsThisMode();
+#else
+ const bool b = FALSE;
+#endif
+ if ( !mi->isEnabledAndVisible() ) {
+#ifndef TQT_NO_WHATSTHIS
+ if ( b ) {
+ actItem = -1;
+ updateItem( mi->id() );
+ byeMenuBar();
+ actSig( mi->id(), b);
+ }
+#endif
+ } else {
+ byeMenuBar(); // deactivate menu bar
+ if ( mi->isEnabledAndVisible() ) {
+ actItem = -1;
+ updateItem( mi->id() );
+ active_popup_menu = this;
+ TQGuardedPtr<TQSignal> signal = mi->signal();
+ actSig( mi->id(), b );
+ if ( signal && !b )
+ signal->activate();
+ active_popup_menu = 0;
+ }
+ }
+ }
+ } else {
+ if ( tornOff ) {
+ close();
+ } else {
+ TQMenuData* p = parentMenu;
+ hide();
+#ifndef TQT_NO_MENUBAR
+ if ( p && p->isMenuBar )
+ ((TQMenuBar*) p)->goodbye( TRUE );
+#endif
+ }
+ }
+
+}
+
+/*! \internal
+ This private function is to update the scroll states in styles that support scrolling. */
+void
+TQPopupMenu::updateScrollerState()
+{
+ uint old_scrollable = d->scroll.scrollable;
+ d->scroll.scrollable = TQPopupMenuPrivate::Scroll::ScrollNone;
+ if(!tqstyle().tqstyleHint(TQStyle::SH_PopupMenu_Scrollable, this))
+ return;
+
+ TQMenuItem *mi;
+ TQMenuItemListIt it( *mitems );
+ if(d->scroll.topScrollableIndex) {
+ for(int row = 0; (mi = it.current()) && row < d->scroll.topScrollableIndex; row++)
+ ++it;
+ if(!mi)
+ it.toFirst();
+ }
+ int y = 0, sh = tqstyle().tqpixelMetric(TQStyle::PM_PopupMenuScrollerHeight, this);
+ if(!it.atFirst()) {
+ // can't use |= because of a bug/feature in IBM xlC 5.0.2
+ d->scroll.scrollable = d->scroll.scrollable | TQPopupMenuPrivate::Scroll::ScrollUp;
+ y += sh;
+ }
+ while ( (mi=it.current()) ) {
+ ++it;
+ int myheight = contentsRect().height();
+ TQSize sz = tqstyle().tqsizeFromContents(TQStyle::CT_PopupMenuItem, this,
+ TQSize(0, itemHeight( mi )),
+ TQStyleOption(mi,maxPMWidth));
+ if(y + sz.height() >= myheight) {
+ d->scroll.scrollable = d->scroll.scrollable | TQPopupMenuPrivate::Scroll::ScrollDown;
+ break;
+ }
+ y += sz.height();
+ }
+ if((d->scroll.scrollable & TQPopupMenuPrivate::Scroll::ScrollUp) &&
+ !(old_scrollable & TQPopupMenuPrivate::Scroll::ScrollUp))
+ d->scroll.topScrollableIndex++;
+}
+
+#endif // TQT_NO_POPUPMENU
+
diff --git a/tqtinterface/qt4/src/widgets/tqpopupmenu.h b/tqtinterface/qt4/src/widgets/tqpopupmenu.h
new file mode 100644
index 0000000..0dd00b5
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqpopupmenu.h
@@ -0,0 +1,201 @@
+/****************************************************************************
+**
+** Definition of TQPopupMenu class
+**
+** Created : 941128
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPOPUPMENU_H
+#define TQPOPUPMENU_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#include "tqmenudata.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_POPUPMENU
+class TQPopupMenuPrivate;
+
+class TQ_EXPORT TQPopupMenu : public TQFrame, public TQMenuData
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool checkable READ isCheckable WRITE setCheckable )
+public:
+ TQPopupMenu( TQWidget* tqparent=0, const char* name=0 );
+ ~TQPopupMenu();
+
+ void popup( const TQPoint & pos, int indexAtPoint = -1 ); // open
+ void updateItem( int id );
+
+ virtual void setCheckable( bool );
+ bool isCheckable() const;
+
+ void setFont( const TQFont & );
+ void show();
+ void hide();
+
+ int exec();
+ int exec( const TQPoint & pos, int indexAtPoint = 0 ); // modal
+
+ virtual void setActiveItem( int );
+ TQSize tqsizeHint() const;
+
+ int idAt( int index ) const { return TQMenuData::idAt( index ); }
+ int idAt( const TQPoint& pos ) const;
+
+ bool customWhatsThis() const;
+
+ int insertTearOffHandle( int id=-1, int index=-1 );
+
+ void activateItemAt( int index );
+ TQRect itemGeometry( int index );
+
+
+Q_SIGNALS:
+ void activated( int itemId );
+ void highlighted( int itemId );
+ void activatedRedirect( int itemId ); // to tqparent menu
+ void highlightedRedirect( int itemId );
+ void aboutToShow();
+ void aboutToHide();
+
+protected:
+ int itemHeight( int ) const;
+ int itemHeight( TQMenuItem* mi ) const;
+ void drawItem( TQPainter* p, int tab, TQMenuItem* mi,
+ bool act, int x, int y, int w, int h);
+
+ void drawContents( TQPainter * );
+
+ void closeEvent( TQCloseEvent *e );
+ void paintEvent( TQPaintEvent * );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void keyPressEvent( TQKeyEvent * );
+ void focusInEvent( TQFocusEvent * );
+ void focusOutEvent( TQFocusEvent * );
+ void timerEvent( TQTimerEvent * );
+ void leaveEvent( TQEvent * );
+ void styleChange( TQStyle& );
+ void enabledChange( bool );
+ int columns() const;
+
+ bool focusNextPrevChild( bool next );
+
+ int itemAtPos( const TQPoint &, bool ignoreSeparator = TRUE ) const;
+
+private Q_SLOTS:
+ void subActivated( int itemId );
+ void subHighlighted( int itemId );
+#ifndef TQT_NO_ACCEL
+ void accelActivated( int itemId );
+ void accelDestroyed();
+#endif
+ void popupDestroyed( TQObject* );
+ void modalActivation( int );
+
+ void subMenuTimer();
+ void subScrollTimer();
+ void allowAnimation();
+ void toggleTearOff();
+
+ void performDelayedChanges();
+
+private:
+ void updateScrollerState();
+ void menuContentsChanged();
+ void menuStateChanged();
+ void performDelayedContentsChanged();
+ void performDelayedStateChanged();
+ void menuInsPopup( TQPopupMenu * );
+ void menuDelPopup( TQPopupMenu * );
+ void frameChanged();
+
+ void actSig( int, bool = FALSE );
+ void hilitSig( int );
+ virtual void setFirstItemActive();
+ void hideAllPopups();
+ void hidePopups();
+ bool tryMenuBar( TQMouseEvent * );
+ void byeMenuBar();
+
+ TQSize updateSize(bool force_recalc=FALSE, bool do_resize=TRUE);
+ void updateRow( int row );
+#ifndef TQT_NO_ACCEL
+ void updateAccel( TQWidget * );
+ void enableAccel( bool );
+#endif
+ TQPopupMenuPrivate *d;
+#ifndef TQT_NO_ACCEL
+ TQAccel *autoaccel;
+#endif
+
+#if defined(TQ_WS_MAC) && !defined(TQMAC_TQMENUBAR_NO_NATIVE)
+ bool macPopupMenu(const TQPoint &, int);
+ uint mac_dirty_popup : 1;
+#endif
+
+ int popupActive;
+ int tab;
+ uint accelDisabled : 1;
+ uint checkable : 1;
+ uint connectModalRecursionSafety : 1;
+ uint tornOff : 1;
+ uint pendingDelayedContentsChanges : 1;
+ uint pendingDelayedStateChanges : 1;
+ int maxPMWidth;
+ int ncols;
+ bool snapToMouse;
+ bool tryMouseEvent( TQPopupMenu *, TQMouseEvent * );
+
+ friend class TQMenuData;
+ friend class TQMenuBar;
+
+ void connectModal(TQPopupMenu* receiver, bool doConnect);
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQPopupMenu( const TQPopupMenu & );
+ TQPopupMenu &operator=( const TQPopupMenu & );
+#endif
+};
+
+
+#endif // TQT_NO_POPUPMENU
+
+#endif // TQPOPUPMENU_H
diff --git a/tqtinterface/qt4/src/widgets/tqprogressbar.cpp b/tqtinterface/qt4/src/widgets/tqprogressbar.cpp
new file mode 100644
index 0000000..e00d12d
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqprogressbar.cpp
@@ -0,0 +1,408 @@
+/****************************************************************************
+**
+** Implementation of TQProgressBar class
+**
+** Created : 970521
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqprogressbar.h"
+#ifndef TQT_NO_PROGRESSBAR
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqpixmap.h"
+#include "tqstyle.h"
+#include "../kernel/tqinternal_p.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+#include <limits.h>
+
+/*!
+ \class TQProgressBar tqprogressbar.h
+ \brief The TQProgressBar widget provides a horizontal progress bar.
+
+ \ingroup advanced
+ \mainclass
+
+ A progress bar is used to give the user an indication of the
+ progress of an operation and to reassure them that the application
+ is still running.
+
+ The progress bar uses the concept of \e steps; you give it the
+ total number of steps and the number of steps completed so far and
+ it will display the percentage of steps that have been completed.
+ You can specify the total number of steps in the constructor or
+ later with setTotalSteps(). The current number of steps is set
+ with setProgress(). The progress bar can be rewound to the
+ beginning with reset().
+
+ If the total is given as 0 the progress bar shows a busy indicator
+ instead of a percentage of steps. This is useful, for example,
+ when using TQFtp or TQHttp to download items when they are unable to
+ determine the size of the item being downloaded.
+
+ \sa TQProgressDialog
+
+ <img src=qprogbar-m.png> <img src=qprogbar-w.png>
+
+ \sa TQProgressDialog
+ \link guibooks.html#fowler GUI Design Handbook: Progress Indicator\endlink
+*/
+
+
+/*!
+ Constructs a progress bar.
+
+ The total number of steps is set to 100 by default.
+
+ The \a tqparent, \a name and widget flags, \a f, are passed on to
+ the TQFrame::TQFrame() constructor.
+
+ \sa setTotalSteps()
+*/
+
+TQProgressBar::TQProgressBar( TQWidget *tqparent, const char *name, WFlags f )
+ : TQFrame( tqparent, name, f | TQt::WNoAutoErase ),
+ total_steps( 100 ),
+ progress_val( -1 ),
+ percentage( -1 ),
+ center_indicator( TRUE ),
+ auto_indicator( TRUE ),
+ percentage_visible( TRUE ),
+ d( 0 )
+{
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
+ initFrame();
+}
+
+
+/*!
+ Constructs a progress bar.
+
+ The \a totalSteps is the total number of steps that need to be
+ completed for the operation which this progress bar represents.
+ For example, if the operation is to examine 50 files, this value
+ would be 50. Before examining the first file, call setProgress(0);
+ call setProgress(50) after examining the last file.
+
+ The \a tqparent, \a name and widget flags, \a f, are passed to the
+ TQFrame::TQFrame() constructor.
+
+ \sa setTotalSteps(), setProgress()
+*/
+
+TQProgressBar::TQProgressBar( int totalSteps,
+ TQWidget *tqparent, const char *name, WFlags f )
+ : TQFrame( tqparent, name, f | TQt::WNoAutoErase ),
+ total_steps( totalSteps ),
+ progress_val( -1 ),
+ percentage( -1 ),
+ center_indicator( TRUE ),
+ auto_indicator( TRUE ),
+ percentage_visible( TRUE ),
+ d( 0 )
+{
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
+ initFrame();
+}
+
+
+/*!
+ Reset the progress bar. The progress bar "rewinds" and shows no
+ progress.
+*/
+
+void TQProgressBar::reset()
+{
+ progress_val = -1;
+ percentage = -1;
+ setIndicator(progress_str, progress_val, total_steps);
+ tqrepaint( FALSE );
+}
+
+
+/*!
+ \property TQProgressBar::totalSteps
+ \brief The total number of steps.
+
+ If totalSteps is 0, the progress bar will display a busy
+ indicator.
+
+ \sa totalSteps()
+*/
+
+void TQProgressBar::setTotalSteps( int totalSteps )
+{
+ total_steps = totalSteps;
+
+ // Current progress is invalid if larger than total
+ if ( total_steps < progress_val )
+ progress_val = -1;
+
+ if ( isVisible() &&
+ ( setIndicator(progress_str, progress_val, total_steps) || !total_steps ) )
+ tqrepaint( FALSE );
+}
+
+
+/*!
+ \property TQProgressBar::progress
+ \brief The current amount of progress
+
+ This property is -1 if progress counting has not started.
+*/
+
+void TQProgressBar::setProgress( int progress )
+{
+ if ( progress == progress_val ||
+ progress < 0 || ( ( progress > total_steps ) && total_steps ) )
+ return;
+
+ progress_val = progress;
+
+ setIndicator( progress_str, progress_val, total_steps );
+
+ tqrepaint( FALSE );
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+}
+
+/*!
+ \overload
+
+ Sets the amount of progress to \a progress and the total number of
+ steps to \a totalSteps.
+
+ \sa setTotalSteps()
+*/
+
+void TQProgressBar::setProgress( int progress, int totalSteps )
+{
+ if ( total_steps != totalSteps )
+ setTotalSteps( totalSteps );
+ setProgress( progress );
+}
+
+/*!
+ \property TQProgressBar::progressString
+ \brief the amount of progress as a string
+
+ This property is TQString::null if progress counting has not started.
+*/
+
+
+/*!
+ \reimp
+*/
+TQSize TQProgressBar::tqsizeHint() const
+{
+ constPolish();
+ TQFontMetrics fm = fontMetrics();
+ int cw = tqstyle().tqpixelMetric(TQStyle::PM_ProgressBarChunkWidth, this);
+ return tqstyle().tqsizeFromContents(TQStyle::CT_ProgressBar, this,
+ TQSize( cw * 7 + fm.width( '0' ) * 4,
+ fm.height() + 8));
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQProgressBar::tqminimumSizeHint() const
+{
+ return tqsizeHint();
+}
+
+/*!
+ \property TQProgressBar::centerIndicator
+ \brief whether the indicator string should be centered
+
+ Changing this property sets \l TQProgressBar::indicatorFollowsStyle
+ to FALSE. The default is TRUE.
+*/
+
+void TQProgressBar::setCenterIndicator( bool on )
+{
+ if ( !auto_indicator && on == center_indicator )
+ return;
+ auto_indicator = FALSE;
+ center_indicator = on;
+ tqrepaint( FALSE );
+}
+
+/*!
+ \property TQProgressBar::indicatorFollowsStyle
+ \brief whether the display of the indicator string should follow the GUI style
+
+ The default is TRUE.
+
+ \sa centerIndicator
+*/
+
+void TQProgressBar::setIndicatorFollowsStyle( bool on )
+{
+ if ( on == auto_indicator )
+ return;
+ auto_indicator = on;
+ tqrepaint( FALSE );
+}
+
+/*!
+ \property TQProgressBar::percentageVisible
+ \brief whether the current progress value is displayed
+
+ The default is TRUE.
+
+ \sa centerIndicator, indicatorFollowsStyle
+*/
+void TQProgressBar::setPercentageVisible( bool on )
+{
+ if ( on == percentage_visible )
+ return;
+ percentage_visible = on;
+ tqrepaint( FALSE );
+}
+
+/*!
+ \reimp
+*/
+void TQProgressBar::show()
+{
+ setIndicator( progress_str, progress_val, total_steps );
+ TQFrame::show();
+}
+
+void TQProgressBar::initFrame()
+{
+ setFrameStyle(TQFrame::NoFrame);
+}
+
+/*!
+ \reimp
+*/
+void TQProgressBar::styleChange( TQStyle& old )
+{
+ initFrame();
+ TQFrame::styleChange( old );
+}
+
+
+/*!
+ This method is called to generate the text displayed in the center
+ (or in some styles, to the left) of the progress bar.
+
+ The \a progress may be negative, indicating that the progress bar
+ is in the "reset" state before any progress is set.
+
+ The default implementation is the percentage of completion or
+ blank in the reset state. The percentage is calculated based on
+ the \a progress and \a totalSteps. You can set the \a indicator
+ text if you wish.
+
+ To allow efficient repainting of the progress bar, this method
+ should return FALSE if the string is unchanged from the last call
+ to this function.
+*/
+
+bool TQProgressBar::setIndicator( TQString & indicator, int progress,
+ int totalSteps )
+{
+ if ( !totalSteps )
+ return FALSE;
+ if ( progress < 0 ) {
+ indicator = TQString::tqfromLatin1("");
+ return TRUE;
+ } else {
+ // Get the values down to something usable.
+ if ( totalSteps > INT_MAX/1000 ) {
+ progress /= 1000;
+ totalSteps /= 1000;
+ }
+
+ int np = progress * 100 / totalSteps;
+ if ( np != percentage ) {
+ percentage = np;
+ indicator.sprintf( "%d%%", np );
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQProgressBar::drawContents( TQPainter *p )
+{
+ const TQRect bar = contentsRect();
+
+ TQSharedDoubleBuffer buffer( p, bar.x(), bar.y(), bar.width(), bar.height() );
+
+ TQPoint pn = backgroundOffset();
+ buffer.painter()->setBrushOrigin( -pn.x(), -pn.y() );
+
+ const TQPixmap *bpm = TQT_TQPIXMAP_CONST(paletteBackgroundPixmap());
+ if ( bpm )
+ buffer.painter()->fillRect( bar, TQBrush( paletteBackgroundColor(), *bpm ) );
+ else
+ buffer.painter()->fillRect( bar, paletteBackgroundColor() );
+ buffer.painter()->setFont( p->font() );
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+
+ tqstyle().tqdrawControl(TQStyle::CE_ProgressBarGroove, buffer.painter(), this,
+ TQStyle::tqvisualRect(tqstyle().subRect(TQStyle::SR_ProgressBarGroove, this), this ),
+ tqcolorGroup(), flags);
+
+ tqstyle().tqdrawControl(TQStyle::CE_ProgressBarContents, buffer.painter(), this,
+ TQStyle::tqvisualRect(tqstyle().subRect(TQStyle::SR_ProgressBarContents, this), this ),
+ tqcolorGroup(), flags);
+
+ if (percentageVisible())
+ tqstyle().tqdrawControl(TQStyle::CE_ProgressBarLabel, buffer.painter(), this,
+ TQStyle::tqvisualRect(tqstyle().subRect(TQStyle::SR_ProgressBarLabel, this), this ),
+ tqcolorGroup(), flags);
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqprogressbar.h b/tqtinterface/qt4/src/widgets/tqprogressbar.h
new file mode 100644
index 0000000..7b9d191
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqprogressbar.h
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Definition of TQProgressBar class
+**
+** Created : 970520
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPROGRESSBAR_H
+#define TQPROGRESSBAR_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_PROGRESSBAR
+
+
+class TQProgressBarPrivate;
+
+
+class TQ_EXPORT TQProgressBar : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( int totalSteps READ totalSteps WRITE setTotalSteps )
+ Q_PROPERTY( int progress READ progress WRITE setProgress )
+ Q_PROPERTY( TQString progressString READ progressString )
+ Q_PROPERTY( bool centerIndicator READ centerIndicator WRITE setCenterIndicator )
+ Q_PROPERTY( bool indicatorFollowsStyle READ indicatorFollowsStyle WRITE setIndicatorFollowsStyle )
+ Q_PROPERTY( bool percentageVisible READ percentageVisible WRITE setPercentageVisible )
+
+public:
+ TQProgressBar( TQWidget* tqparent=0, const char* name=0, WFlags f=0 );
+ TQProgressBar( int totalSteps, TQWidget* tqparent=0, const char* name=0, WFlags f=0 );
+
+ int totalSteps() const;
+ int progress() const;
+ const TQString &progressString() const;
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ void setCenterIndicator( bool on );
+ bool centerIndicator() const;
+
+ void setIndicatorFollowsStyle( bool );
+ bool indicatorFollowsStyle() const;
+
+ bool percentageVisible() const;
+ void setPercentageVisible( bool );
+
+ void show();
+
+public Q_SLOTS:
+ void reset();
+ virtual void setTotalSteps( int totalSteps );
+ virtual void setProgress( int progress );
+ void setProgress( int progress, int totalSteps );
+
+protected:
+ void drawContents( TQPainter * );
+ virtual bool setIndicator( TQString & progress_str, int progress,
+ int totalSteps );
+ void styleChange( TQStyle& );
+
+private:
+ int total_steps;
+ int progress_val;
+ int percentage;
+ TQString progress_str;
+ bool center_indicator : 1;
+ bool auto_indicator : 1;
+ bool percentage_visible : 1;
+ TQProgressBarPrivate * d;
+ void initFrame();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQProgressBar( const TQProgressBar & );
+ TQProgressBar &operator=( const TQProgressBar & );
+#endif
+};
+
+
+inline int TQProgressBar::totalSteps() const
+{
+ return total_steps;
+}
+
+inline int TQProgressBar::progress() const
+{
+ return progress_val;
+}
+
+inline const TQString &TQProgressBar::progressString() const
+{
+ return progress_str;
+}
+
+inline bool TQProgressBar::centerIndicator() const
+{
+ return center_indicator;
+}
+
+inline bool TQProgressBar::indicatorFollowsStyle() const
+{
+ return auto_indicator;
+}
+
+inline bool TQProgressBar::percentageVisible() const
+{
+ return percentage_visible;
+}
+
+#endif // TQT_NO_PROGRESSBAR
+
+#endif // TQPROGRESSBAR_H
diff --git a/tqtinterface/qt4/src/widgets/tqpushbutton.cpp b/tqtinterface/qt4/src/widgets/tqpushbutton.cpp
new file mode 100644
index 0000000..e8583ff
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqpushbutton.cpp
@@ -0,0 +1,760 @@
+/****************************************************************************
+**
+** Implementation of TQPushButton class
+**
+** Created : 940221
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqpushbutton.h"
+#ifndef TQT_NO_PUSHBUTTON
+#include "tqdialog.h"
+#include "tqfontmetrics.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqpixmap.h"
+#include "tqbitmap.h"
+#include "tqpopupmenu.h"
+#include "tqguardedptr.h"
+#include "tqapplication.h"
+#include "tqtoolbar.h"
+#include "tqstyle.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+/*!
+ \class TQPushButton tqpushbutton.h
+ \brief The TQPushButton widget provides a command button.
+
+ \ingroup basic
+ \mainclass
+
+ The push button, or command button, is perhaps the most commonly
+ used widget in any graphical user interface. Push (click) a button
+ to command the computer to perform some action, or to answer a
+ question. Typical buttons are OK, Apply, Cancel, Close, Yes, No
+ and Help.
+
+ A command button is rectangular and typically displays a text
+ label describing its action. An underlined character in the label
+ (signified by preceding it with an ampersand in the text)
+ indicates an accelerator key, e.g.
+ \code
+ TQPushButton *pb = new TQPushButton( "&Download", this );
+ \endcode
+ In this example the accelerator is \e{Alt+D}, and the label text
+ will be displayed as <b><u>D</u>ownload</b>.
+
+ Push buttons can display a textual label or a pixmap, and
+ optionally a small icon. These can be set using the constructors
+ and changed later using setText(), setPixmap() and setIconSet().
+ If the button is disabled the appearance of the text or pixmap and
+ iconset will be manipulated with respect to the GUI style to make
+ the button look "disabled".
+
+ A push button emits the signal clicked() when it is activated by
+ the mouse, the Spacebar or by a keyboard accelerator. Connect to
+ this signal to perform the button's action. Push buttons also
+ provide less commonly used Q_SIGNALS, for example, pressed() and
+ released().
+
+ Command buttons in dialogs are by default auto-default buttons,
+ i.e. they become the default push button automatically when they
+ receive the keyboard input focus. A default button is a push
+ button that is activated when the user presses the Enter or Return
+ key in a dialog. You can change this with setAutoDefault(). Note
+ that auto-default buttons reserve a little extra space which is
+ necessary to draw a default-button indicator. If you do not want
+ this space around your buttons, call setAutoDefault(FALSE).
+
+ Being so central, the button widget has grown to accommodate a
+ great many variations in the past decade. The Microsoft style
+ guide now shows about ten different states of Windows push buttons
+ and the text implies that there are dozens more when all the
+ combinations of features are taken into consideration.
+
+ The most important modes or states are:
+ \list
+ \i Available or not (grayed out, disabled).
+ \i Standard push button, toggling push button or menu button.
+ \i On or off (only for toggling push buttons).
+ \i Default or normal. The default button in a dialog can generally
+ be "clicked" using the Enter or Return key.
+ \i Auto-repeat or not.
+ \i Pressed down or not.
+ \endlist
+
+ As a general rule, use a push button when the application or
+ dialog window performs an action when the user clicks on it (such
+ as Apply, Cancel, Close and Help) \e and when the widget is
+ supposed to have a wide, rectangular tqshape with a text label.
+ Small, typically square buttons that change the state of the
+ window rather than performing an action (such as the buttons in
+ the top-right corner of the TQFileDialog) are not command buttons,
+ but tool buttons. TQt provides a special class (TQToolButton) for
+ these buttons.
+
+ If you need toggle behavior (see setToggleButton()) or a button
+ that auto-repeats the activation signal when being pushed down
+ like the arrows in a scroll bar (see setAutoRepeat()), a command
+ button is probably not what you want. When in doubt, use a tool
+ button.
+
+ A variation of a command button is a menu button. These provide
+ not just one command, but several, since when they are clicked
+ they pop up a menu of options. Use the method setPopup() to
+ associate a popup menu with a push button.
+
+ Other classes of buttons are option buttons (see TQRadioButton) and
+ check boxes (see TQCheckBox).
+
+ <img src="qpushbt-m.png"> <img src="qpushbt-w.png">
+
+ In TQt, the TQButton abstract base class provides most of the modes
+ and other API, and TQPushButton provides GUI logic. See TQButton for
+ more information about the API.
+
+ \important text, setText, text, pixmap, setPixmap, accel, setAccel,
+ isToggleButton, setDown, isDown, isOn, state, autoRepeat,
+ isExclusiveToggle, group, setAutoRepeat, toggle, pressed, released,
+ clicked, toggled, state stateChanged
+
+ \sa TQToolButton, TQRadioButton TQCheckBox
+ \link guibooks.html#fowler GUI Design Handbook: Push Button\endlink
+*/
+
+/*!
+ \property TQPushButton::autoDefault
+ \brief whether the push button is the auto default button
+
+ If this property is set to TRUE then the push button is the auto
+ default button in a dialog.
+
+ In some GUI styles a default button is drawn with an extra frame
+ around it, up to 3 pixels or more. TQt automatically keeps this
+ space free around auto-default buttons, i.e. auto-default buttons
+ may have a slightly larger size hint.
+
+ This property's default is TRUE for buttons that have a TQDialog
+ tqparent; otherwise it defaults to FALSE.
+
+ See the \l default property for details of how \l default and
+ auto-default interact.
+*/
+
+/*!
+ \property TQPushButton::autoMask
+ \brief whether the button is automatically masked
+
+ \sa TQWidget::setAutoMask()
+*/
+
+/*!
+ \property TQPushButton::default
+ \brief whether the push button is the default button
+
+ If this property is set to TRUE then the push button will be
+ pressed if the user presses the Enter (or Return) key in a dialog.
+
+ Regardless of focus, if the user presses Enter: If there is a
+ default button the default button is pressed; otherwise, if
+ there are one or more \l autoDefault buttons the first \l autoDefault
+ button that is next in the tab order is pressed. If there are no
+ default or \l autoDefault buttons only pressing Space on a button
+ with focus, mouse clicking, or using an accelerator will press a
+ button.
+
+ In a dialog, only one push button at a time can be the default
+ button. This button is then displayed with an additional frame
+ (depending on the GUI style).
+
+ The default button behavior is provided only in dialogs. Buttons
+ can always be clicked from the keyboard by pressing Enter (or
+ Return) or the Spacebar when the button has focus.
+
+ This property's default is FALSE.
+*/
+
+/*!
+ \property TQPushButton::flat
+ \brief whether the border is disabled
+
+ This property's default is FALSE.
+*/
+
+/*!
+ \property TQPushButton::iconSet
+ \brief the icon set on the push button
+
+ This property will return 0 if the push button has no iconset.
+*/
+
+/*!
+ \property TQPushButton::on
+ \brief whether the push button is toggled
+
+ This property should only be set for toggle push buttons. The
+ default value is FALSE.
+
+ \sa isOn(), toggle(), toggled(), isToggleButton()
+*/
+
+/*!
+ \property TQPushButton::toggleButton
+ \brief whether the button is a toggle button
+
+ Toggle buttons have an on/off state similar to \link TQCheckBox
+ check boxes. \endlink A push button is initially not a toggle
+ button.
+
+ \sa setOn(), toggle(), isToggleButton() toggled()
+*/
+
+/*! \property TQPushButton::menuButton
+ \brief whether the push button has a menu button on it
+ \obsolete
+
+ If this property is set to TRUE, then a down arrow is drawn on the push
+ button to indicate that a menu will pop up if the user clicks on the
+ arrow.
+*/
+
+class TQPushButtonPrivate
+{
+public:
+ TQPushButtonPrivate()
+ :iconset( 0 )
+ {}
+ ~TQPushButtonPrivate()
+ {
+#ifndef TQT_NO_ICONSET
+ delete iconset;
+#endif
+ }
+#ifndef TQT_NO_POPUPMENU
+ TQGuardedPtr<TQPopupMenu> popup;
+#endif
+ TQIconSet* iconset;
+};
+
+
+/*!
+ Constructs a push button with no text.
+
+ The \a tqparent and \a name arguments are sent on to the TQWidget
+ constructor.
+*/
+
+TQPushButton::TQPushButton( TQWidget *tqparent, const char *name )
+ : TQButton( tqparent, name )
+{
+ init();
+}
+
+/*!
+ Constructs a push button called \a name with the tqparent \a tqparent
+ and the text \a text.
+*/
+
+TQPushButton::TQPushButton( const TQString &text, TQWidget *tqparent,
+ const char *name )
+ : TQButton( tqparent, name )
+{
+ init();
+ setText( text );
+}
+
+
+/*!
+ Constructs a push button with an \a icon and a \a text.
+
+ Note that you can also pass a TQPixmap object as an icon (thanks to
+ the implicit type conversion provided by C++).
+
+ The \a tqparent and \a name arguments are sent to the TQWidget
+ constructor.
+*/
+#ifndef TQT_NO_ICONSET
+TQPushButton::TQPushButton( const TQIconSet& icon, const TQString &text,
+ TQWidget *tqparent, const char *name )
+ : TQButton( tqparent, name )
+{
+ init();
+ setText( text );
+ setIconSet( icon );
+}
+#endif
+
+
+/*!
+ Destroys the push button.
+*/
+TQPushButton::~TQPushButton()
+{
+ delete d;
+}
+
+void TQPushButton::init()
+{
+ d = 0;
+ defButton = FALSE;
+ lastEnabled = FALSE;
+ hasMenuArrow = FALSE;
+ flt = FALSE;
+#ifndef TQT_NO_DIALOG
+ autoDefButton = ::tqqt_cast<TQDialog*>(tqtopLevelWidget()) != 0;
+#else
+ autoDefButton = FALSE;
+#endif
+ setBackgroundMode( TQt::PaletteButton );
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ) );
+}
+
+
+/*
+ Makes the push button a toggle button if \a enable is TRUE or a normal
+ push button if \a enable is FALSE.
+
+ Toggle buttons have an on/off state similar to \link TQCheckBox check
+ boxes. \endlink A push button is initially not a toggle button.
+
+ \sa setOn(), toggle(), isToggleButton() toggled()
+*/
+
+void TQPushButton::setToggleButton( bool enable )
+{
+ TQButton::setToggleButton( enable );
+}
+
+
+/*
+ Switches a toggle button on if \a enable is TRUE or off if \a enable is
+ FALSE.
+ \sa isOn(), toggle(), toggled(), isToggleButton()
+*/
+
+void TQPushButton::setOn( bool enable )
+{
+ if ( !isToggleButton() )
+ return;
+ TQButton::setOn( enable );
+}
+
+void TQPushButton::setAutoDefault( bool enable )
+{
+ if ( (bool)autoDefButton == enable )
+ return;
+ autoDefButton = enable;
+ update();
+ updateGeometry();
+}
+
+
+void TQPushButton::setDefault( bool enable )
+{
+ if ( (bool)defButton == enable )
+ return; // no change
+ defButton = enable;
+#ifndef TQT_NO_DIALOG
+ if ( defButton && ::tqqt_cast<TQDialog*>(tqtopLevelWidget()) )
+ ((TQDialog*)tqtopLevelWidget())->setMainDefault( this );
+#endif
+ update();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::StateChanged );
+#endif
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQPushButton::tqsizeHint() const
+{
+ constPolish();
+
+ int w = 0, h = 0;
+
+ // calculate contents size...
+#ifndef TQT_NO_ICONSET
+ if ( iconSet() && !iconSet()->isNull() ) {
+ int iw = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4;
+ int ih = iconSet()->pixmap( TQIconSet::Small, TQIconSet::Normal ).height();
+ w += iw;
+ h = TQMAX( h, ih );
+ }
+#endif
+ if ( isMenuButton() )
+ w += tqstyle().tqpixelMetric(TQStyle::PM_MenuButtonIndicator, this);
+
+ if ( pixmap() ) {
+ TQPixmap *pm = (TQPixmap *)pixmap();
+ w += pm->width();
+ h += pm->height();
+ } else {
+ TQString s( text() );
+ bool empty = s.isEmpty();
+ if ( empty )
+ s = TQString::tqfromLatin1("XXXX");
+ TQFontMetrics fm = fontMetrics();
+ TQSize sz = fm.size( TQt::ShowPrefix, s );
+ if(!empty || !w)
+ w += sz.width();
+ if(!empty || !h)
+ h = TQMAX(h, sz.height());
+ }
+
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_PushButton, this, TQSize(w, h)).
+ expandedTo(TQApplication::globalStrut()));
+}
+
+
+/*!
+ \reimp
+*/
+void TQPushButton::move( int x, int y )
+{
+ TQWidget::move( x, y );
+}
+
+/*!
+ \reimp
+*/
+void TQPushButton::move( const TQPoint &p )
+{
+ move( p.x(), p.y() );
+}
+
+/*!
+ \reimp
+*/
+void TQPushButton::resize( int w, int h )
+{
+ TQWidget::resize( w, h );
+}
+
+/*!
+ \reimp
+*/
+void TQPushButton::resize( const TQSize &s )
+{
+ resize( s.width(), s.height() );
+}
+
+/*!
+ \reimp
+*/
+void TQPushButton::setGeometry( int x, int y, int w, int h )
+{
+ TQWidget::setGeometry( x, y, w, h );
+}
+
+/*!
+ \reimp
+*/
+void TQPushButton::setGeometry( const TQRect &r )
+{
+ TQWidget::setGeometry( r );
+}
+
+/*!
+ \reimp
+ */
+void TQPushButton::resizeEvent( TQResizeEvent * )
+{
+ if ( autoMask() )
+ updateMask();
+}
+
+/*!
+ \reimp
+*/
+void TQPushButton::drawButton( TQPainter *paint )
+{
+ int diw = 0;
+ if ( isDefault() || autoDefault() ) {
+ diw = tqstyle().tqpixelMetric(TQStyle::PM_ButtonDefaultIndicator, this);
+
+ if ( diw > 0 ) {
+ if (backgroundMode() == TQt::X11ParentRelative) {
+ erase( 0, 0, width(), diw );
+ erase( 0, 0, diw, height() );
+ erase( 0, height() - diw, width(), diw );
+ erase( width() - diw, 0, diw, height() );
+ } else if ( parentWidget() && parentWidget()->backgroundPixmap() ){
+ // pseudo tranparency
+ paint->drawTiledPixmap( 0, 0, width(), diw,
+ *parentWidget()->backgroundPixmap(),
+ x(), y() );
+ paint->drawTiledPixmap( 0, 0, diw, height(),
+ *parentWidget()->backgroundPixmap(),
+ x(), y() );
+ paint->drawTiledPixmap( 0, height()-diw, width(), diw,
+ *parentWidget()->backgroundPixmap(),
+ x(), y()+height() );
+ paint->drawTiledPixmap( width()-diw, 0, diw, height(),
+ *parentWidget()->backgroundPixmap(),
+ x()+width(), y() );
+ } else {
+ paint->fillRect( 0, 0, width(), diw,
+ tqcolorGroup().brush(TQColorGroup::Background) );
+ paint->fillRect( 0, 0, diw, height(),
+ tqcolorGroup().brush(TQColorGroup::Background) );
+ paint->fillRect( 0, height()-diw, width(), diw,
+ tqcolorGroup().brush(TQColorGroup::Background) );
+ paint->fillRect( width()-diw, 0, diw, height(),
+ tqcolorGroup().brush(TQColorGroup::Background) );
+ }
+
+ }
+ }
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+ if (isDown())
+ flags |= TQStyle::Style_Down;
+ if (isOn())
+ flags |= TQStyle::Style_On;
+ if (! isFlat() && ! isDown())
+ flags |= TQStyle::Style_Raised;
+ if (isDefault())
+ flags |= TQStyle::Style_ButtonDefault;
+
+ tqstyle().tqdrawControl(TQStyle::CE_PushButton, paint, this, rect(), tqcolorGroup(), flags);
+ drawButtonLabel( paint );
+
+ lastEnabled = isEnabled();
+}
+
+
+/*!
+ \reimp
+*/
+void TQPushButton::drawButtonLabel( TQPainter *paint )
+{
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+ if (isDown())
+ flags |= TQStyle::Style_Down;
+ if (isOn())
+ flags |= TQStyle::Style_On;
+ if (! isFlat() && ! isDown())
+ flags |= TQStyle::Style_Raised;
+ if (isDefault())
+ flags |= TQStyle::Style_ButtonDefault;
+
+ tqstyle().tqdrawControl(TQStyle::CE_PushButtonLabel, paint, this,
+ tqstyle().subRect(TQStyle::SR_PushButtonContents, this),
+ tqcolorGroup(), flags);
+}
+
+
+/*!
+ \reimp
+ */
+void TQPushButton::updateMask()
+{
+ TQBitmap bm( size() );
+ bm.fill( Qt::color0 );
+
+ {
+ TQPainter p( &bm, this );
+ tqstyle().tqdrawControlMask(TQStyle::CE_PushButton, &p, this, rect());
+ }
+
+ setMask( bm );
+}
+
+/*!
+ \reimp
+*/
+void TQPushButton::focusInEvent( TQFocusEvent *e )
+{
+ if (autoDefButton && !defButton) {
+ defButton = TRUE;
+#ifndef TQT_NO_DIALOG
+ if ( defButton && ::tqqt_cast<TQDialog*>(tqtopLevelWidget()) )
+ ((TQDialog*)tqtopLevelWidget())->setDefault( this );
+#endif
+ }
+ TQButton::focusInEvent( e );
+}
+
+/*!
+ \reimp
+*/
+void TQPushButton::focusOutEvent( TQFocusEvent *e )
+{
+#ifndef TQT_NO_DIALOG
+ if ( defButton && autoDefButton ) {
+ if ( ::tqqt_cast<TQDialog*>(tqtopLevelWidget()) )
+ ((TQDialog*)tqtopLevelWidget())->setDefault( 0 );
+ }
+#endif
+
+ TQButton::focusOutEvent( e );
+#ifndef TQT_NO_POPUPMENU
+ if ( popup() && popup()->isVisible() ) // restore pressed status
+ setDown( TRUE );
+#endif
+}
+
+
+#ifndef TQT_NO_POPUPMENU
+/*!
+ Associates the popup menu \a popup with this push button. This
+ turns the button into a menu button.
+
+ Ownership of the popup menu is \e not transferred to the push
+ button.
+
+ \sa popup()
+*/
+void TQPushButton::setPopup( TQPopupMenu* popup )
+{
+ if ( !d )
+ d = new TQPushButtonPrivate;
+ if ( popup && !d->popup )
+ connect( this, TQT_SIGNAL( pressed() ), this, TQT_SLOT( popupPressed() ) );
+
+ d->popup = popup;
+ setIsMenuButton( popup != 0 );
+}
+#endif //TQT_NO_POPUPMENU
+#ifndef TQT_NO_ICONSET
+void TQPushButton::setIconSet( const TQIconSet& icon )
+{
+ if ( !d )
+ d = new TQPushButtonPrivate;
+ if ( !icon.isNull() ) {
+ if ( d->iconset )
+ *d->iconset = icon;
+ else
+ d->iconset = new TQIconSet( icon );
+ } else if ( d->iconset) {
+ delete d->iconset;
+ d->iconset = 0;
+ }
+
+ update();
+ updateGeometry();
+}
+
+
+TQIconSet* TQPushButton::iconSet() const
+{
+ return d ? d->iconset : 0;
+}
+#endif // TQT_NO_ICONSET
+#ifndef TQT_NO_POPUPMENU
+/*!
+ Returns the button's associated popup menu or 0 if no popup menu
+ has been set.
+
+ \sa setPopup()
+*/
+TQPopupMenu* TQPushButton::popup() const
+{
+ return d ? (TQPopupMenu*)d->popup : 0;
+}
+
+void TQPushButton::popupPressed()
+{
+ TQPopupMenu* popup = d ? (TQPopupMenu*) d->popup : 0;
+ TQGuardedPtr<TQPushButton> that = this;
+ if ( isDown() && popup ) {
+ bool horizontal = TRUE;
+ bool topLeft = TRUE; // ### always TRUE
+#ifndef TQT_NO_TOOLBAR
+ TQToolBar *tb = ::tqqt_cast<TQToolBar*>(parentWidget());
+ if ( tb && tb->orientation() == Qt::Vertical )
+ horizontal = FALSE;
+#endif
+ if ( horizontal ) {
+ if ( topLeft ) {
+ if ( mapToGlobal( TQPoint( 0, rect().bottom() ) ).y() + popup->tqsizeHint().height() <= tqApp->desktop()->height() )
+ popup->exec( mapToGlobal( rect().bottomLeft() ) );
+ else
+ popup->exec( mapToGlobal( rect().topLeft() - TQPoint( 0, popup->tqsizeHint().height() ) ) );
+ } else {
+ TQSize sz( popup->tqsizeHint() );
+ TQPoint p = mapToGlobal( rect().topLeft() );
+ p.ry() -= sz.height();
+ popup->exec( p );
+ }
+ } else {
+ if ( topLeft ) {
+ if ( mapToGlobal( TQPoint( rect().right(), 0 ) ).x() + popup->tqsizeHint().width() <= tqApp->desktop()->width() )
+ popup->exec( mapToGlobal( rect().topRight() ) );
+ else
+ popup->exec( mapToGlobal( rect().topLeft() - TQPoint( popup->tqsizeHint().width(), 0 ) ) );
+ } else {
+ TQSize sz( popup->tqsizeHint() );
+ TQPoint p = mapToGlobal( rect().topLeft() );
+ p.rx() -= sz.width();
+ popup->exec( p );
+ }
+ }
+ if (that)
+ setDown( FALSE );
+ }
+}
+#endif
+
+void TQPushButton::setFlat( bool f )
+{
+ flt = f;
+ update();
+}
+
+bool TQPushButton::isFlat() const
+{
+ return flt;
+}
+
+/*!
+ \obsolete
+ \fn virtual void TQPushButton::setIsMenuButton( bool enable )
+*/
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqpushbutton.h b/tqtinterface/qt4/src/widgets/tqpushbutton.h
new file mode 100644
index 0000000..92a375d
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqpushbutton.h
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Definition of TQPushButton class
+**
+** Created : 940221
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQPUSHBUTTON_H
+#define TQPUSHBUTTON_H
+
+#ifndef TQT_H
+#include "tqbutton.h"
+#include "tqiconset.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_PUSHBUTTON
+class TQPushButtonPrivate;
+class TQPopupMenu;
+
+class TQ_EXPORT TQPushButton : public TQButton
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+ Q_PROPERTY( bool autoDefault READ autoDefault WRITE setAutoDefault )
+ Q_PROPERTY( bool default READ isDefault WRITE setDefault )
+ Q_PROPERTY( bool menuButton READ isMenuButton DESIGNABLE false )
+ Q_PROPERTY( TQIconSet iconSet READ iconSet WRITE setIconSet )
+ TQ_OVERRIDE( bool toggleButton WRITE setToggleButton )
+ TQ_OVERRIDE( bool on WRITE setOn )
+ Q_PROPERTY( bool flat READ isFlat WRITE setFlat )
+ TQ_OVERRIDE( bool autoMask DESIGNABLE true SCRIPTABLE true )
+
+public:
+ TQPushButton( TQWidget *tqparent, const char* name=0 );
+ TQPushButton( const TQString &text, TQWidget *tqparent, const char* name=0 );
+#ifndef TQT_NO_ICONSET
+ TQPushButton( const TQIconSet& icon, const TQString &text, TQWidget *tqparent, const char* name=0 );
+#endif
+ ~TQPushButton();
+
+ TQSize tqsizeHint() const;
+
+ void move( int x, int y );
+ void move( const TQPoint &p );
+ void resize( int w, int h );
+ void resize( const TQSize & );
+ void setGeometry( int x, int y, int w, int h );
+
+ void setGeometry( const TQRect & );
+
+ void setToggleButton( bool );
+
+ bool autoDefault() const { return autoDefButton; }
+ virtual void setAutoDefault( bool autoDef );
+ bool isDefault() const { return defButton; }
+ virtual void setDefault( bool def );
+
+ virtual void setIsMenuButton( bool enable ) { // obsolete functions
+ if ( (bool)hasMenuArrow == enable )
+ return;
+ hasMenuArrow = enable ? 1 : 0;
+ update();
+ updateGeometry();
+ }
+ bool isMenuButton() const { return hasMenuArrow; }
+
+#ifndef TQT_NO_POPUPMENU
+ void setPopup( TQPopupMenu* popup );
+ TQPopupMenu* popup() const;
+#endif
+#ifndef TQT_NO_ICONSET
+ void setIconSet( const TQIconSet& );
+ TQIconSet* iconSet() const;
+#endif
+ void setFlat( bool );
+ bool isFlat() const;
+
+public Q_SLOTS:
+ virtual void setOn( bool );
+
+protected:
+ void drawButton( TQPainter * );
+ void drawButtonLabel( TQPainter * );
+ void focusInEvent( TQFocusEvent * );
+ void focusOutEvent( TQFocusEvent * );
+ void resizeEvent( TQResizeEvent * );
+ void updateMask();
+private Q_SLOTS:
+#ifndef TQT_NO_POPUPMENU
+ void popupPressed();
+#endif
+private:
+ void init();
+
+ uint autoDefButton : 1;
+ uint defButton : 1;
+ uint flt : 1;
+ uint reserved : 1; // UNUSED
+ uint lastEnabled : 1; // UNUSED
+ uint hasMenuArrow : 1;
+
+ TQPushButtonPrivate* d;
+
+ friend class TQDialog;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQPushButton( const TQPushButton & );
+ TQPushButton &operator=( const TQPushButton & );
+#endif
+};
+
+
+#endif // TQT_NO_PUSHBUTTON
+
+#endif // TQPUSHBUTTON_H
diff --git a/tqtinterface/qt4/src/widgets/tqradiobutton.cpp b/tqtinterface/qt4/src/widgets/tqradiobutton.cpp
new file mode 100644
index 0000000..69bdedb
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqradiobutton.cpp
@@ -0,0 +1,362 @@
+/****************************************************************************
+**
+** Implementation of TQRadioButton class
+**
+** Created : 940222
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqradiobutton.h"
+#ifndef TQT_NO_RADIOBUTTON
+#include "tqbuttongroup.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqpixmap.h"
+#include "tqpixmapcache.h"
+#include "tqbitmap.h"
+#include "tqtextstream.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+
+/*!
+ \class TQRadioButton tqradiobutton.h
+ \brief The TQRadioButton widget provides a radio button with a text or pixmap label.
+
+ \ingroup basic
+ \mainclass
+
+ TQRadioButton and TQCheckBox are both option buttons. That is, they
+ can be switched on (checked) or off (unchecked). The classes
+ differ in how the choices for the user are restricted. Check boxes
+ define "many of many" choices, whereas radio buttons provide a
+ "one of many" choice. In a group of radio buttons only one radio
+ button at a time can be checked; if the user selects another
+ button, the previously selected button is switched off.
+
+ The easiest way to implement a "one of many" choice is simply to
+ put the radio buttons into TQButtonGroup.
+
+ Whenever a button is switched on or off it emits the signal
+ toggled(). Connect to this signal if you want to trigger an action
+ each time the button changes state. Otherwise, use isChecked() to
+ see if a particular button is selected.
+
+ Just like TQPushButton, a radio button can display text or a
+ pixmap. The text can be set in the constructor or with setText();
+ the pixmap is set with setPixmap().
+
+ <img src=qradiobt-m.png> <img src=qradiobt-w.png>
+
+ \important text, setText, text, pixmap, setPixmap, accel, setAccel, isToggleButton, setDown, isDown, isOn, state, autoRepeat, isExclusiveToggle, group, setAutoRepeat, toggle, pressed, released, clicked, toggled, state stateChanged
+
+ \sa TQPushButton TQToolButton
+ \link guibooks.html#fowler GUI Design Handbook: Radio Button\endlink
+*/
+
+/*!
+ \property TQRadioButton::checked \brief Whether the radio button is
+ checked
+
+ This property will not effect any other radio buttons unless they
+ have been placed in the same TQButtonGroup. The default value is
+ FALSE (unchecked).
+*/
+
+/*!
+ \property TQRadioButton::autoMask \brief whether the radio button
+ is automatically masked
+
+ \sa TQWidget::setAutoMask()
+*/
+
+/*!
+ Constructs a radio button with no text.
+
+ The \a tqparent and \a name arguments are sent on to the TQWidget
+ constructor.
+*/
+
+TQRadioButton::TQRadioButton( TQWidget *tqparent, const char *name )
+ : TQButton( tqparent, name, TQt::WNoAutoErase | TQt::WMouseNoMask )
+{
+ init();
+}
+
+/*!
+ Constructs a radio button with the text \a text.
+
+ The \a tqparent and \a name arguments are sent on to the TQWidget
+ constructor.
+*/
+
+TQRadioButton::TQRadioButton( const TQString &text, TQWidget *tqparent,
+ const char *name )
+ : TQButton( tqparent, name, TQt::WNoAutoErase | TQt::WMouseNoMask )
+{
+ init();
+ setText( text );
+}
+
+
+/*
+ Initializes the radio button.
+*/
+
+void TQRadioButton::init()
+{
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ) );
+ setToggleButton( TRUE );
+#ifndef TQT_NO_BUTTONGROUP
+ TQButtonGroup *bgrp = ::tqqt_cast<TQButtonGroup*>(parentWidget());
+ if ( bgrp )
+ bgrp->setRadioButtonExclusive( TRUE );
+#endif
+}
+
+void TQRadioButton::setChecked( bool check )
+{
+ setOn( check );
+}
+
+
+
+
+/*!
+ \reimp
+*/
+TQSize TQRadioButton::tqsizeHint() const
+{
+ // Any more complex, and we will use tqstyle().tqitemRect()
+ // NB: TQCheckBox::tqsizeHint() is similar
+ constPolish();
+
+ TQPainter p(this);
+ TQSize sz = tqstyle().tqitemRect(&p, TQRect(0, 0, 1, 1), TQt::ShowPrefix, FALSE,
+ pixmap(), text()).size();
+
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_RadioButton, this, sz).
+ expandedTo(TQApplication::globalStrut()));
+}
+
+
+/*!
+ \reimp
+*/
+bool TQRadioButton::hitButton( const TQPoint &pos ) const
+{
+ TQRect r =
+ TQStyle::tqvisualRect( tqstyle().subRect( TQStyle::SR_RadioButtonFocusRect,
+ this ), this );
+ if ( tqApp->reverseLayout() ) {
+ r.setRight( width() );
+ } else {
+ r.setLeft( 0 );
+ }
+ return r.tqcontains( pos );
+}
+
+
+/*!
+ \reimp
+*/
+void TQRadioButton::drawButton( TQPainter *paint )
+{
+ TQPainter *p = paint;
+ TQRect irect = TQStyle::tqvisualRect( tqstyle().subRect(TQStyle::SR_RadioButtonIndicator, this), this );
+ const TQColorGroup &cg = tqcolorGroup();
+
+#if !defined( TQT_NO_TEXTSTREAM ) && !defined( TQ_WS_MACX )
+#ifdef USE_QT4
+printf("[WARNING] TQSharedDoubleBuffer double buffering has been disabled\n\r"); // Otherwise the widgets don't repaint properly in Qt4!
+#else // USE_QT4
+# define SAVE_RADIOBUTTON_PIXMAPS
+#endif // USE_QT4
+#endif
+#if defined(SAVE_RADIOBUTTON_PIXMAPS)
+ TQString pmkey; // pixmap key
+ int kf = 0;
+ if ( isDown() )
+ kf |= 1;
+ if ( isOn() )
+ kf |= 2;
+ if ( isEnabled() )
+ kf |= 4;
+ if( isActiveWindow() )
+ kf |= 8;
+ if ( hasMouse() )
+ kf |= 16;
+ if ( hasFocus() )
+ kf |= 32;
+
+ TQTextOStream os(&pmkey);
+ os << "$qt_radio_" << tqstyle().className() << "_"
+ << palette().serialNumber() << "_" << irect.width() << "x" << irect.height() << "_" << kf;
+ TQPixmap *pm = TQPixmapCache::tqfind( pmkey );
+ if ( pm ) { // pixmap exists
+ drawButtonLabel( p );
+ p->drawPixmap( irect.topLeft(), *pm );
+ return;
+ }
+ bool use_pm = TRUE;
+ TQPainter pmpaint;
+ int wx, wy;
+ if ( use_pm ) {
+ pm = new TQPixmap( irect.size() ); // create new pixmap
+ TQ_CHECK_PTR( pm );
+ pm->fill(paletteBackgroundColor());
+ TQPainter::redirect(this, pm);
+ pmpaint.begin(this);
+ p = &pmpaint; // draw in pixmap
+ wx = irect.x(); // save x,y coords
+ wy = irect.y();
+ irect.moveTopLeft(TQPoint(0, 0));
+ p->setBackgroundColor(paletteBackgroundColor());
+ }
+#endif
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if ( isEnabled() )
+ flags |= TQStyle::Style_Enabled;
+ if ( hasFocus() )
+ flags |= TQStyle::Style_HasFocus;
+ if ( isDown() )
+ flags |= TQStyle::Style_Down;
+ if ( hasMouse() )
+ flags |= TQStyle::Style_MouseOver;
+ if ( state() == TQButton::On )
+ flags |= TQStyle::Style_On;
+ else if ( state() == TQButton::Off )
+ flags |= TQStyle::Style_Off;
+
+ tqstyle().tqdrawControl(TQStyle::CE_RadioButton, p, this, irect, cg, flags);
+
+#if defined(SAVE_RADIOBUTTON_PIXMAPS)
+ if ( use_pm ) {
+ pmpaint.end();
+ TQPainter::redirect(this, NULL);
+ if ( backgroundPixmap() || backgroundMode() == TQt::X11ParentRelative ) {
+ TQBitmap bm( pm->size() );
+ bm.fill( Qt::color0 );
+ pmpaint.begin( &bm );
+ tqstyle().tqdrawControlMask(TQStyle::CE_RadioButton, &pmpaint, this, irect);
+ pmpaint.end();
+ pm->setMask( bm );
+ }
+ p = paint; // draw in default tqdevice
+ p->drawPixmap( wx, wy, *pm );
+ if (!TQPixmapCache::insert(pmkey, pm) ) // save in cache
+ delete pm;
+ }
+#endif
+
+ drawButtonLabel( p );
+}
+
+
+
+/*!
+ \reimp
+*/
+void TQRadioButton::drawButtonLabel( TQPainter *p )
+{
+ TQRect r =
+ TQStyle::tqvisualRect( tqstyle().subRect(TQStyle::SR_RadioButtonContents,
+ this), this );
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+ if (isDown())
+ flags |= TQStyle::Style_Down;
+ if (state() == TQButton::On)
+ flags |= TQStyle::Style_On;
+ else if (state() == TQButton::Off)
+ flags |= TQStyle::Style_Off;
+
+ tqstyle().tqdrawControl(TQStyle::CE_RadioButtonLabel, p, this, r, tqcolorGroup(), flags);
+}
+
+
+/*!
+ \reimp
+*/
+void TQRadioButton::resizeEvent( TQResizeEvent* e )
+{
+ TQButton::resizeEvent(e);
+ if ( isVisible() ) {
+ TQPainter p(this);
+ TQSize isz = tqstyle().tqitemRect(&p, TQRect(0, 0, 1, 1), TQt::ShowPrefix, FALSE,
+ pixmap(), text()).size();
+ TQSize wsz = (tqstyle().tqsizeFromContents(TQStyle::CT_RadioButton, this, isz).
+ expandedTo(TQApplication::globalStrut()));
+
+ update(wsz.width(), isz.width(), 0, wsz.height());
+ }
+ if (autoMask())
+ updateMask();
+}
+
+/*!
+ \reimp
+*/
+void TQRadioButton::updateMask()
+{
+ TQRect irect =
+ TQStyle::tqvisualRect( tqstyle().subRect( TQStyle::SR_RadioButtonIndicator,
+ this ), this );
+
+ TQBitmap bm(width(), height());
+ bm.fill(Qt::color0);
+
+ TQPainter p( &bm, this );
+ tqstyle().tqdrawControlMask(TQStyle::CE_RadioButton, &p, this, irect);
+ if ( ! text().isNull() || ( pixmap() && ! pixmap()->isNull() ) ) {
+ TQRect crect =
+ TQStyle::tqvisualRect( tqstyle().subRect( TQStyle::SR_RadioButtonContents,
+ this ), this );
+ TQRect frect =
+ TQStyle::tqvisualRect( tqstyle().subRect( TQStyle::SR_RadioButtonFocusRect,
+ this ), this );
+ TQRect label(crect.unite(frect));
+ p.fillRect(label, Qt::color1);
+ }
+ p.end();
+
+ setMask(bm);
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqradiobutton.h b/tqtinterface/qt4/src/widgets/tqradiobutton.h
new file mode 100644
index 0000000..50f9927
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqradiobutton.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Definition of TQRadioButton class
+**
+** Created : 940222
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQRADIOBUTTON_H
+#define TQRADIOBUTTON_H
+
+#ifndef TQT_H
+#include "tqbutton.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_RADIOBUTTON
+
+class TQ_EXPORT TQRadioButton : public TQButton
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool checked READ isChecked WRITE setChecked )
+ TQ_OVERRIDE( bool autoMask DESIGNABLE true SCRIPTABLE true )
+
+public:
+ TQRadioButton( TQWidget *tqparent, const char* name=0 );
+ TQRadioButton( const TQString &text, TQWidget *tqparent, const char* name=0 );
+
+ bool isChecked() const;
+
+ TQSize tqsizeHint() const;
+
+public Q_SLOTS:
+ virtual void setChecked( bool check );
+
+protected:
+ bool hitButton( const TQPoint & ) const;
+ void drawButton( TQPainter * );
+ void drawButtonLabel( TQPainter * );
+ void updateMask();
+
+ void resizeEvent( TQResizeEvent* );
+
+private:
+ void init();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQRadioButton( const TQRadioButton & );
+ TQRadioButton &operator=( const TQRadioButton & );
+#endif
+};
+
+
+inline bool TQRadioButton::isChecked() const
+{ return isOn(); }
+
+#endif // TQT_NO_RADIOBUTTON
+
+#endif // TQRADIOBUTTON_H
diff --git a/tqtinterface/qt4/src/widgets/tqrangecontrol.cpp b/tqtinterface/qt4/src/widgets/tqrangecontrol.cpp
new file mode 100644
index 0000000..65c53c5
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqrangecontrol.cpp
@@ -0,0 +1,565 @@
+/****************************************************************************
+**
+** Implementation of TQRangeControl class
+**
+** Created : 940427
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqrangecontrol.h"
+#ifndef TQT_NO_RANGECONTROL
+#include "tqglobal.h"
+#include <limits.h>
+
+static bool sumOutOfRange(int current, int add);
+
+
+/*!
+ \class TQRangeControl tqrangecontrol.h
+ \brief The TQRangeControl class provides an integer value within a range.
+
+ \ingroup misc
+
+ Although originally designed for the TQScrollBar widget, the
+ TQRangeControl can also be used in conjunction with other widgets
+ such as TQSlider and TQSpinBox. Here are the five main concepts in
+ the class:
+
+ \list 1
+
+ \i \e{Current value} The bounded integer that
+ TQRangeControl maintains. value() returns it, and several
+ functions, including setValue(), set it.
+
+ \i \e{Minimum} The lowest value that value() can ever
+ return. Returned by minValue() and set by setRange() or one of the
+ constructors.
+
+ \i \e{Maximum} The highest value that value() can ever
+ return. Returned by maxValue() and set by setRange() or one of the
+ constructors.
+
+ \i \e{Line step} The smaller of two natural steps that
+ TQRangeControl provides and typically corresponds to the user
+ pressing an arrow key. The line step is returned by lineStep()
+ and set using setSteps(). The functions addLine() and
+ subtractLine() respectively increment and decrement the current
+ value by lineStep().
+
+ \i \e{Page step} The larger of two natural steps that
+ TQRangeControl provides and typically corresponds to the user
+ pressing PageUp or PageDown. The page step is returned by
+ pageStep() and set using setSteps(). The functions addPage() and
+ substractPage() respectively increment and decrement the current
+ value by pageStep().
+
+ \endlist
+
+ Unity (1) may be viewed as a third step size. setValue() lets you
+ set the current value to any integer in the allowed range, not
+ just minValue() + \e n * lineStep() for integer values of \e n.
+ Some widgets may allow the user to set any value at all; others
+ may just provide multiples of lineStep() or pageStep().
+
+ TQRangeControl provides three virtual functions that are well
+ suited for updating the on-screen representation of range controls
+ and emitting Q_SIGNALS: valueChange(), rangeChange() and
+ stepChange().
+
+ TQRangeControl also provides a function called bound() which lets
+ you force arbitrary integers to be within the allowed range of the
+ range control.
+
+ We recommend that all widgets that inherit TQRangeControl provide
+ at least a signal called valueChanged(); many widgets will want to
+ provide addStep(), addPage(), substractStep() and substractPage()
+ as Q_SLOTS.
+
+ Note that you must use multiple inheritance if you plan to
+ implement a widget using TQRangeControl because TQRangeControl is
+ not derived from TQWidget.
+*/
+
+
+/*!
+ Constructs a range control with a minimum value of 0, maximum
+ value of 99, line step of 1, page step of 10 and initial value 0.
+*/
+
+TQRangeControl::TQRangeControl()
+{
+ minVal = 0;
+ maxVal = 99;
+ line = 1;
+ page = 10;
+ val = 0;
+ prevVal = -1;
+ d = 0;
+}
+
+/*!
+ Constructs a range control whose value can never be smaller than
+ \a minValue or greater than \a maxValue, whose line step size is
+ \a lineStep and page step size is \a pageStep and whose value is
+ initially \a value (which is guaranteed to be in range using
+ bound()).
+*/
+
+TQRangeControl::TQRangeControl( int minValue, int maxValue,
+ int lineStep, int pageStep,
+ int value )
+{
+ minVal = minValue;
+ maxVal = maxValue;
+ line = TQABS( lineStep );
+ page = TQABS( pageStep );
+ prevVal = minVal - 1;
+ val = bound( value );
+ d = 0;
+}
+
+/*!
+ Destroys the range control
+*/
+
+TQRangeControl::~TQRangeControl()
+{
+}
+
+
+/*!
+ \fn int TQRangeControl::value() const
+
+ Returns the current range control value. This is guaranteed to be
+ within the range [minValue(), maxValue()].
+
+ \sa setValue() prevValue()
+*/
+
+/*!
+ \fn int TQRangeControl::prevValue() const
+
+ Returns the previous value of the range control. "Previous value"
+ means the value before the last change occurred. Setting a new
+ range may affect the value, too, because the value is forced to be
+ inside the specified range. When the range control is initially
+ created, this is the same as value().
+
+ prevValue() can be outside the current legal range if a call to
+ setRange() causes the current value to change. For example, if the
+ range was [0, 1000] and the current value is 500, setRange(0, 400)
+ makes value() return 400 and prevValue() return 500.
+
+ \sa value() setRange()
+*/
+
+/*!
+ Sets the range control's value to \a value and forces it to be
+ within the legal range.
+
+ Calls the virtual valueChange() function if the new value is
+ different from the previous value. The old value can still be
+ retrieved using prevValue().
+
+ \sa value()
+*/
+
+void TQRangeControl::setValue( int value )
+{
+ directSetValue( value );
+ if ( prevVal != val )
+ valueChange();
+}
+
+/*!
+ Sets the range control \a value directly without calling
+ valueChange().
+
+ Forces the new \a value to be within the legal range.
+
+ You will rarely have to call this function. However, if you want
+ to change the range control's value inside the overloaded method
+ valueChange(), setValue() would call the function valueChange()
+ again. To avoid this recursion you must use directSetValue()
+ instead.
+
+ \sa setValue()
+*/
+
+void TQRangeControl::directSetValue(int value)
+{
+ prevVal = val;
+ val = bound( value );
+}
+
+/*!
+ Equivalent to \c{setValue( value() + pageStep() )}.
+
+ If the value is changed, then valueChange() is called.
+
+ \sa subtractPage() addLine() setValue()
+*/
+
+void TQRangeControl::addPage()
+{
+ if (!sumOutOfRange(value(), pageStep()))
+ setValue(value() + pageStep());
+}
+
+/*!
+ Equivalent to \c{setValue( value() - pageStep() )}.
+
+ If the value is changed, then valueChange() is called.
+
+ \sa addPage() subtractLine() setValue()
+*/
+
+void TQRangeControl::subtractPage()
+{
+ if (!sumOutOfRange(value(), -pageStep()))
+ setValue(value() - pageStep());
+}
+
+/*!
+ Equivalent to \c{setValue( value() + lineStep() )}.
+
+ If the value is changed, then valueChange() is called.
+
+ \sa subtractLine() addPage() setValue()
+*/
+
+void TQRangeControl::addLine()
+{
+ if (!sumOutOfRange(value(), lineStep()))
+ setValue(value() + lineStep());
+}
+
+/*!
+ Equivalent to \c{setValue( value() - lineStep() )}.
+
+ If the value is changed, then valueChange() is called.
+
+ \sa addLine() subtractPage() setValue()
+*/
+
+void TQRangeControl::subtractLine()
+{
+ if (!sumOutOfRange(value(), -lineStep()))
+ setValue(value() - lineStep());
+}
+
+
+/*!
+ \fn int TQRangeControl::minValue() const
+
+ Returns the minimum value of the range.
+
+ \sa setMinValue() setRange() maxValue()
+*/
+
+/*!
+ \fn int TQRangeControl::maxValue() const
+
+ Returns the maximum value of the range.
+
+ \sa setMaxValue() setRange() minValue()
+*/
+
+/*!
+ Sets the minimum value of the range to \a minVal.
+
+ If necessary, the maxValue() is adjusted so that the range remains
+ valid.
+
+ \sa minValue() setMaxValue()
+*/
+void TQRangeControl::setMinValue( int minVal )
+{
+ int maxVal = maxValue();
+ if ( maxVal < minVal )
+ maxVal = minVal;
+ setRange( minVal, maxVal );
+}
+
+/*!
+ Sets the minimum value of the range to \a maxVal.
+
+ If necessary, the minValue() is adjusted so that the range remains
+ valid.
+
+ \sa maxValue() setMinValue()
+*/
+void TQRangeControl::setMaxValue( int maxVal )
+{
+ int minVal = minValue();
+ if ( minVal > maxVal )
+ minVal = maxVal;
+ setRange( minVal, maxVal );
+}
+
+/*!
+ Sets the range control's minimum value to \a minValue and its
+ maximum value to \a maxValue.
+
+ Calls the virtual rangeChange() function if one or both of the new
+ minimum and maximum values are different from the previous
+ setting. Calls the virtual valueChange() function if the current
+ value is adjusted because it was outside the new range.
+
+ If \a maxValue is smaller than \a minValue, \a minValue becomes
+ the only legal value.
+
+ \sa minValue() maxValue()
+*/
+
+void TQRangeControl::setRange( int minValue, int maxValue )
+{
+ if ( minValue > maxValue ) {
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQRangeControl::setRange: minValue %d > maxValue %d",
+ minValue, maxValue );
+#endif
+ maxValue = minValue;
+ }
+ if ( minValue == minVal && maxValue == maxVal )
+ return;
+ minVal = minValue;
+ maxVal = maxValue;
+ int tmp = bound( val );
+ rangeChange();
+ if ( tmp != val ) {
+ prevVal = val;
+ val = tmp;
+ valueChange();
+ }
+}
+
+
+/*!
+ \fn int TQRangeControl::lineStep() const
+
+ Returns the line step.
+
+ \sa setSteps() pageStep()
+*/
+
+/*!
+ \fn int TQRangeControl::pageStep() const
+
+ Returns the page step.
+
+ \sa setSteps() lineStep()
+*/
+
+/*!
+ Sets the range's line step to \a lineStep and page step to \a
+ pageStep.
+
+ Calls the virtual stepChange() function if the new line step
+ or page step are different from the previous settings.
+
+ \sa lineStep() pageStep() setRange()
+*/
+
+void TQRangeControl::setSteps( int lineStep, int pageStep )
+{
+ if ( lineStep != line || pageStep != page ) {
+ line = TQABS( lineStep );
+ page = TQABS( pageStep );
+ stepChange();
+ }
+}
+
+
+/*!
+ This virtual function is called whenever the range control value
+ changes. You can reimplement it if you want to be notified when
+ the value changes. The default implementation does nothing.
+
+ Note that this method is called after the value has changed. The
+ previous value can be retrieved using prevValue().
+
+ \sa setValue(), addPage(), subtractPage(), addLine(),
+ subtractLine() rangeChange(), stepChange()
+*/
+
+void TQRangeControl::valueChange()
+{
+}
+
+
+/*!
+ This virtual function is called whenever the range control's range
+ changes. You can reimplement it if you want to be notified when
+ the range changes. The default implementation does nothing.
+
+ Note that this method is called after the range has changed.
+
+ \sa setRange(), valueChange(), stepChange()
+*/
+
+void TQRangeControl::rangeChange()
+{
+}
+
+
+/*!
+ This virtual function is called whenever the range control's
+ line or page step settings change. You can reimplement it if you
+ want to be notified when the step changes. The default
+ implementation does nothing.
+
+ Note that this method is called after a step setting has changed.
+
+ \sa setSteps(), rangeChange(), valueChange()
+*/
+
+void TQRangeControl::stepChange()
+{
+}
+
+
+/*!
+ Forces the value \a v to be within the range from minValue() to
+ maxValue() inclusive, and returns the result.
+
+ This function is provided so that you can easily force other
+ numbers than value() into the allowed range. You do not need to
+ call it in order to use TQRangeControl itself.
+
+ \sa setValue() value() minValue() maxValue()
+*/
+
+int TQRangeControl::bound( int v ) const
+{
+ if ( v < minVal )
+ return minVal;
+ if ( v > maxVal )
+ return maxVal;
+ return v;
+}
+
+
+/*!
+ Converts \a logical_val to a pixel position. minValue() maps to 0,
+ maxValue() maps to \a span and other values are distributed evenly
+ in-between.
+
+ This function can handle the entire integer range without
+ overflow, providing \a span is \<= 4096.
+
+ Calling this method is useful when actually drawing a range
+ control such as a TQScrollBar on-screen.
+
+ \sa valueFromPosition()
+*/
+
+int TQRangeControl::positionFromValue( int logical_val, int span ) const
+{
+ if ( span <= 0 || logical_val < minValue() || maxValue() <= minValue() )
+ return 0;
+ if ( logical_val > maxValue() )
+ return span;
+
+ uint range = maxValue() - minValue();
+ uint p = logical_val - minValue();
+
+ if ( range > (uint)INT_MAX/4096 ) {
+ const int scale = 4096*2;
+ return ( (p/scale) * span ) / (range/scale);
+ // ### the above line is probably not 100% correct
+ // ### but fixing it isn't worth the extreme pain...
+ } else if ( range > (uint)span ) {
+ return (2*p*span + range) / (2*range);
+ } else {
+ uint div = span / range;
+ uint mod = span % range;
+ return p*div + (2*p*mod + range) / (2*range);
+ }
+ //equiv. to (p*span)/range + 0.5
+ // no overflow because of this implicit assumption:
+ // span <= 4096
+}
+
+
+/*!
+ Converts the pixel position \a pos to a value. 0 maps to
+ minValue(), \a span maps to maxValue() and other values are
+ distributed evenly in-between.
+
+ This function can handle the entire integer range without
+ overflow.
+
+ Calling this method is useful if you actually implemented a range
+ control widget such as TQScrollBar and want to handle mouse press
+ events. This function then maps screen coordinates to the logical
+ values.
+
+ \sa positionFromValue()
+*/
+
+int TQRangeControl::valueFromPosition( int pos, int span ) const
+{
+ if ( span <= 0 || pos <= 0 )
+ return minValue();
+ if ( pos >= span )
+ return maxValue();
+
+ uint range = maxValue() - minValue();
+
+ if ( (uint)span > range )
+ return minValue() + (2*pos*range + span) / (2*span);
+ else {
+ uint div = range / span;
+ uint mod = range % span;
+ return minValue() + pos*div + (2*pos*mod + span) / (2*span);
+ }
+ // equiv. to minValue() + (pos*range)/span + 0.5
+ // no overflow because of this implicit assumption:
+ // pos <= span < sqrt(INT_MAX+0.0625)+0.25 ~ sqrt(INT_MAX)
+}
+
+static bool sumOutOfRange(int current, int add)
+{
+ if (add > 0 && INT_MAX - add < current) {
+ return true;
+ }
+ if (add < 0 && INT_MIN - add > current) {
+ return true;
+ }
+ return false;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqrangecontrol.h b/tqtinterface/qt4/src/widgets/tqrangecontrol.h
new file mode 100644
index 0000000..ddda65d
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqrangecontrol.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Definition of TQRangeControl class
+**
+** Created : 940427
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQRANGECONTROL_H
+#define TQRANGECONTROL_H
+
+#ifndef TQT_H
+#include "tqglobal.h"
+#include "tqframe.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_RANGECONTROL
+
+
+class TQRangeControlPrivate;
+
+
+class TQ_EXPORT TQRangeControl
+{
+public:
+ TQRangeControl();
+ TQRangeControl( int minValue, int maxValue,
+ int lineStep, int pageStep, int value );
+ virtual ~TQRangeControl();
+ int value() const;
+ void setValue( int );
+ void addPage();
+ void subtractPage();
+ void addLine();
+ void subtractLine();
+
+ int minValue() const;
+ int maxValue() const;
+ void setRange( int minValue, int maxValue );
+ void setMinValue( int minVal );
+ void setMaxValue( int minVal );
+
+ int lineStep() const;
+ int pageStep() const;
+ void setSteps( int line, int page );
+
+ int bound( int ) const;
+
+protected:
+ int positionFromValue( int val, int space ) const;
+ int valueFromPosition( int pos, int space ) const;
+ void directSetValue( int val );
+ int prevValue() const;
+
+ virtual void valueChange();
+ virtual void rangeChange();
+ virtual void stepChange();
+
+private:
+ int minVal, maxVal;
+ int line, page;
+ int val, prevVal;
+
+ TQRangeControlPrivate * d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQRangeControl( const TQRangeControl & );
+ TQRangeControl &operator=( const TQRangeControl & );
+#endif
+};
+
+
+inline int TQRangeControl::value() const
+{ return val; }
+
+inline int TQRangeControl::prevValue() const
+{ return prevVal; }
+
+inline int TQRangeControl::minValue() const
+{ return minVal; }
+
+inline int TQRangeControl::maxValue() const
+{ return maxVal; }
+
+inline int TQRangeControl::lineStep() const
+{ return line; }
+
+inline int TQRangeControl::pageStep() const
+{ return page; }
+
+
+#endif // TQT_NO_RANGECONTROL
+
+#ifndef TQT_NO_SPINWIDGET
+
+class TQSpinWidgetPrivate;
+class TQ_EXPORT TQSpinWidget : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQSpinWidget( TQWidget* tqparent=0, const char* name=0 );
+ ~TQSpinWidget();
+
+ void setEditWidget( TQWidget * widget );
+ TQWidget * editWidget();
+
+ TQRect upRect() const;
+ TQRect downRect() const;
+
+ void setUpEnabled( bool on );
+ void setDownEnabled( bool on );
+
+ bool isUpEnabled() const;
+ bool isDownEnabled() const;
+
+ enum ButtonSymbols { UpDownArrows, PlusMinus };
+ virtual void setButtonSymbols( ButtonSymbols bs );
+ ButtonSymbols buttonSymbols() const;
+
+ void arrange();
+
+Q_SIGNALS:
+ void stepUpPressed();
+ void stepDownPressed();
+
+public Q_SLOTS:
+ void stepUp();
+ void stepDown();
+
+protected:
+ void mousePressEvent( TQMouseEvent *e );
+ void resizeEvent( TQResizeEvent* ev );
+ void mouseReleaseEvent( TQMouseEvent *e );
+ void mouseMoveEvent( TQMouseEvent *e );
+#ifndef TQT_NO_WHEELEVENT
+ void wheelEvent( TQWheelEvent * );
+#endif
+ void styleChange( TQStyle& );
+ void paintEvent( TQPaintEvent * );
+ void enableChanged( bool old );
+ void windowActivationChange( bool );
+
+private Q_SLOTS:
+ void timerDone();
+ void timerDoneEx();
+
+private:
+ TQSpinWidgetPrivate * d;
+
+ void updateDisplay();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSpinWidget( const TQSpinWidget& );
+ TQSpinWidget& operator=( const TQSpinWidget& );
+#endif
+};
+
+#endif // TQT_NO_SPINWIDGET
+
+#endif // TQRANGECONTROL_H
diff --git a/tqtinterface/qt4/src/widgets/tqscrollbar.cpp b/tqtinterface/qt4/src/widgets/tqscrollbar.cpp
new file mode 100644
index 0000000..09d1575
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqscrollbar.cpp
@@ -0,0 +1,1072 @@
+/****************************************************************************
+**
+** Implementation of TQScrollBar class
+**
+** Created : 940427
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqscrollbar.h"
+#ifndef TQT_NO_SCROLLBAR
+#include "tqpainter.h"
+#include "tqbitmap.h"
+#include "tqapplication.h"
+#include "tqtimer.h"
+#include "tqstyle.h"
+#ifndef TQT_NO_CURSOR
+#include <tqcursor.h>
+#endif
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+#include <limits.h>
+
+/*!
+ \class TQScrollBar
+ \brief The TQScrollBar widget provides a vertical or horizontal scroll bar.
+
+ \ingroup basic
+
+ A scroll bar allows the user to control a value within a
+ program-definable range and gives users a visible indication of
+ the current value of a \link TQRangeControl range control \endlink.
+
+ Scroll bars include four separate controls:
+
+ \list
+
+ \i The \e line-up and \e line-down controls are little buttons
+ which the user can use to move one "line" up or down. The meaning
+ of line is configurable. In editors and list boxes it means one
+ line of text; in an image viewer it might mean 20 pixels.
+
+ \i The \e slider is the handle that indicates the current value of
+ the scroll bar, which the user can drag to change the value. This
+ part of the scroll bar is sometimes called the "thumb".
+
+ \i The \e page-up/page-down control is the area on which the
+ slider slides (the scroll bar's background). Clicking here moves
+ the scroll bar towards the click. The meaning of "page" is also
+ configurable: in editors and list boxes it means as many lines as
+ there is space for in the widget.
+
+ \endlist
+
+ TQScrollBar has very few of its own functions; it mostly relies on
+ TQRangeControl. The most useful functions are setValue() to set the
+ scroll bar directly to some value; addPage(), addLine(),
+ subtractPage(), and subtractLine() to simulate the effects of
+ clicking (useful for accelerator keys); setSteps() to define the
+ values of pageStep() and lineStep(); and setRange() to set the
+ minValue() and maxValue() of the scroll bar. TQScrollBar has a
+ convenience constructor with which you can set most of these
+ properties.
+
+ Some GUI styles (for example, the Windows and Motif styles
+ provided with TQt), also use the pageStep() value to calculate the
+ size of the slider.
+
+ In addition to the access functions from TQRangeControl, TQScrollBar
+ provides a comprehensive set of Q_SIGNALS:
+ \table
+ \header \i Signal \i Emitted when
+ \row \i \l valueChanged()
+ \i the scroll bar's value has changed. The tracking()
+ determines whether this signal is emitted during user
+ interaction.
+ \row \i \l sliderPressed()
+ \i the user starts to drag the slider.
+ \row \i \l sliderMoved()
+ \i the user drags the slider.
+ \row \i \l sliderReleased()
+ \i the user releases the slider.
+ \row \i \l nextLine()
+ \i the scroll bar has moved one line down or right. Line is
+ defined in TQRangeControl.
+ \row \i \l prevLine()
+ \i the scroll bar has moved one line up or left.
+ \row \i \l nextPage()
+ \i the scroll bar has moved one page down or right.
+ \row \i \l prevPage()
+ \i the scroll bar has moved one page up or left.
+ \endtable
+
+ TQScrollBar only provides integer ranges. Note that although
+ TQScrollBar handles very large numbers, scroll bars on current
+ screens cannot usefully control ranges above about 100,000 pixels.
+ Beyond that, it becomes difficult for the user to control the
+ scroll bar using either the keyboard or the mouse.
+
+ A scroll bar can be controlled by the keyboard, but it has a
+ default focusPolicy() of \c NoFocus. Use setFocusPolicy() to
+ enable keyboard focus. See keyPressEvent() for a list of key
+ bindings.
+
+ If you need to add scroll bars to an interface, consider using the
+ TQScrollView class, which encapsulates the common uses for scroll
+ bars.
+
+ <img src=qscrbar-m.png> <img src=qscrbar-w.png>
+
+ \sa TQSlider TQSpinBox TQScrollView
+ \link guibooks.html#fowler GUI Design Handbook: Scroll Bar\endlink
+*/
+
+
+/*!
+ \fn void TQScrollBar::valueChanged( int value )
+
+ This signal is emitted when the scroll bar value has changed, with
+ the new scroll bar \a value as an argument.
+*/
+
+/*!
+ \fn void TQScrollBar::sliderPressed()
+
+ This signal is emitted when the user presses the slider with the
+ mouse.
+*/
+
+/*!
+ \fn void TQScrollBar::sliderMoved( int value )
+
+ This signal is emitted when the slider is dragged by the user, with
+ the new scroll bar \a value as an argument.
+
+ This signal is emitted even when tracking is turned off.
+
+ \sa tracking() valueChanged() nextLine() prevLine() nextPage()
+ prevPage()
+*/
+
+/*!
+ \fn void TQScrollBar::sliderReleased()
+
+ This signal is emitted when the user releases the slider with the
+ mouse.
+*/
+
+/*!
+ \fn void TQScrollBar::nextLine()
+
+ This signal is emitted when the scroll bar scrolls one line down
+ or right.
+*/
+
+/*!
+ \fn void TQScrollBar::prevLine()
+
+ This signal is emitted when the scroll bar scrolls one line up or
+ left.
+*/
+
+/*!
+ \fn void TQScrollBar::nextPage()
+
+ This signal is emitted when the scroll bar scrolls one page down
+ or right.
+*/
+
+/*!
+ \fn void TQScrollBar::prevPage()
+
+ This signal is emitted when the scroll bar scrolls one page up or
+ left.
+*/
+
+
+
+static const int thresholdTime = 500;
+static const int repeatTime = 50;
+
+#define HORIZONTAL (orientation() == Qt::Horizontal)
+#define VERTICAL !HORIZONTAL
+#define MOTIF_BORDER 2
+#define SLIDER_MIN 9
+
+
+/*!
+ Constructs a vertical scroll bar.
+
+ The \a tqparent and \a name arguments are sent on to the TQWidget
+ constructor.
+
+ The \c minValue defaults to 0, the \c maxValue to 99, with a \c
+ lineStep size of 1 and a \c pageStep size of 10, and an initial
+ \c value of 0.
+*/
+
+TQScrollBar::TQScrollBar( TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name ), orient( Qt::Vertical )
+{
+ init();
+}
+
+/*!
+ Constructs a scroll bar.
+
+ The \a orientation must be \c Qt::Vertical or \c Qt::Horizontal.
+
+ The \a tqparent and \a name arguments are sent on to the TQWidget
+ constructor.
+
+ The \c minValue defaults to 0, the \c maxValue to 99, with a \c
+ lineStep size of 1 and a \c pageStep size of 10, and an initial
+ \c value of 0.
+*/
+
+TQScrollBar::TQScrollBar( Qt::Orientation orientation, TQWidget *tqparent,
+ const char *name )
+ : TQWidget( tqparent, name ), orient( orientation )
+{
+ init();
+}
+
+/*!
+ Constructs a scroll bar whose value can never be smaller than \a
+ minValue or greater than \a maxValue, whose line step size is \a
+ lineStep and page step size is \a pageStep and whose value is
+ initially \a value (which is guaranteed to be in range using
+ bound()).
+
+ If \a orientation is \c Vertical the scroll bar is vertical and if
+ it is \c Horizontal the scroll bar is horizontal.
+
+ The \a tqparent and \a name arguments are sent on to the TQWidget
+ constructor.
+*/
+
+TQScrollBar::TQScrollBar( int minValue, int maxValue, int lineStep, int pageStep,
+ int value, Qt::Orientation orientation,
+ TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name ),
+ TQRangeControl( minValue, maxValue, lineStep, pageStep, value ),
+ orient( orientation )
+{
+ init();
+}
+
+/*!
+ Destructor.
+*/
+TQScrollBar::~TQScrollBar()
+{
+}
+
+void TQScrollBar::init()
+{
+ track = TRUE;
+ sliderPos = 0;
+ pressedControl = TQStyle::SC_None;
+ clickedAt = FALSE;
+ setFocusPolicy( Qt::NoFocus );
+
+ repeater = 0;
+
+ setBackgroundMode((TQt::BackgroundMode)
+ tqstyle().tqstyleHint(TQStyle::SH_ScrollBar_BackgroundMode));
+
+ TQSizePolicy sp( TQSizePolicy::Minimum, TQSizePolicy::Fixed );
+ if ( orient == Qt::Vertical )
+ sp.transpose();
+ tqsetSizePolicy( sp );
+ clearWState( TQt::WState_OwnSizePolicy );
+}
+
+
+/*!
+ \property TQScrollBar::orientation
+ \brief the orientation of the scroll bar
+
+ The orientation must be \l Qt::Vertical (the default) or \l
+ Qt::Horizontal.
+*/
+
+void TQScrollBar::setOrientation( Qt::Orientation orientation )
+{
+ if ( orientation == orient )
+ return;
+ if ( !testWState( TQt::WState_OwnSizePolicy ) ) {
+ TQSizePolicy sp = tqsizePolicy();
+ sp.transpose();
+ tqsetSizePolicy( sp );
+ clearWState( TQt::WState_OwnSizePolicy );
+ }
+
+ orient = orientation;
+
+ positionSliderFromValue();
+ update();
+ updateGeometry();
+}
+
+/*!
+ \property TQScrollBar::tracking
+ \brief whether scroll bar tracking is enabled
+
+ If tracking is enabled (the default), the scroll bar emits the
+ valueChanged() signal while the slider is being dragged. If
+ tracking is disabled, the scroll bar emits the valueChanged()
+ signal only when the user releases the mouse button after moving
+ the slider.
+*/
+
+
+/*!
+ \property TQScrollBar::draggingSlider
+ \brief whether the user has clicked the mouse on the slider and is currently dragging it
+*/
+
+bool TQScrollBar::draggingSlider() const
+{
+ return pressedControl == TQStyle::SC_ScrollBarSlider;
+}
+
+
+/*!
+ Reimplements the virtual function TQWidget::setPalette().
+
+ Sets the background color to the mid color for Motif style scroll
+ bars using palette \a p.
+*/
+
+void TQScrollBar::setPalette( const TQPalette &p )
+{
+ TQWidget::setPalette( p );
+ setBackgroundMode((TQt::BackgroundMode)
+ tqstyle().tqstyleHint(TQStyle::SH_ScrollBar_BackgroundMode));
+}
+
+
+/*! \reimp */
+TQSize TQScrollBar::tqsizeHint() const
+{
+ constPolish();
+ int sbextent = tqstyle().tqpixelMetric(TQStyle::PM_ScrollBarExtent, this);
+
+ if ( orient == Qt::Horizontal ) {
+ return TQSize( 30, sbextent );
+ } else {
+ return TQSize( sbextent, 30 );
+ }
+}
+
+/*! \fn void TQScrollBar::tqsetSizePolicy( TQSizePolicy::SizeType, TQSizePolicy::SizeType, bool )
+ \reimp
+*/
+
+/*! \reimp */
+void TQScrollBar::tqsetSizePolicy( TQSizePolicy sp )
+{
+ //## remove 4.0
+ TQWidget::tqsetSizePolicy( sp );
+}
+
+/*!
+ \internal
+ Implements the virtual TQRangeControl function.
+*/
+
+void TQScrollBar::valueChange()
+{
+ int tmp = sliderPos;
+ positionSliderFromValue();
+ if ( tmp != sliderPos && isVisible() )
+ tqdrawControls(TQStyle::SC_ScrollBarAddPage |
+ TQStyle::SC_ScrollBarSubPage |
+ TQStyle::SC_ScrollBarSlider,
+ pressedControl );
+ emit valueChanged(value());
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+}
+
+/*!
+ \internal
+ Implements the virtual TQRangeControl function.
+*/
+
+void TQScrollBar::stepChange()
+{
+ rangeChange();
+}
+
+/*!
+ \internal
+ Implements the virtual TQRangeControl function.
+*/
+
+void TQScrollBar::rangeChange()
+{
+ positionSliderFromValue();
+
+ if ( isVisible() )
+ tqdrawControls(TQStyle::SC_ScrollBarAddLine |
+ TQStyle::SC_ScrollBarSubLine |
+ TQStyle::SC_ScrollBarAddPage |
+ TQStyle::SC_ScrollBarSubPage |
+ TQStyle::SC_ScrollBarFirst |
+ TQStyle::SC_ScrollBarLast |
+ TQStyle::SC_ScrollBarSlider,
+ pressedControl );
+}
+
+
+/*!
+ Handles timer events for the scroll bar.
+*/
+
+void TQScrollBar::doAutoRepeat()
+{
+ bool sendRepeat = clickedAt;
+#if !defined( TQT_NO_CURSOR ) && !defined( TQT_NO_STYLE )
+ if(sendRepeat && (pressedControl == TQStyle::SC_ScrollBarAddPage ||
+ pressedControl == TQStyle::SC_ScrollBarSubPage) &&
+ tqstyle().tqstyleHint(TQStyle::SH_ScrollBar_StopMouseOverSlider, this) &&
+ tqstyle().querySubControl(TQStyle::CC_ScrollBar, this,
+ mapFromGlobal(TQCursor::pos()) ) == TQStyle::SC_ScrollBarSlider)
+ sendRepeat = FALSE;
+#endif
+ if ( sendRepeat ){
+ if ( repeater )
+ repeater->changeInterval( repeatTime );
+ action( (TQStyle::SubControl) pressedControl );
+ TQApplication::syncX();
+ } else {
+ stopAutoRepeat();
+ }
+}
+
+
+/*!
+ Starts the auto-repeat logic. Some time after this function is
+ called, the auto-repeat starts taking effect and from then on
+ repeats until stopAutoRepeat() is called.
+*/
+
+void TQScrollBar::startAutoRepeat()
+{
+ if ( !repeater ) {
+ repeater = new TQTimer( this, "auto-repeat timer" );
+ connect( repeater, TQT_SIGNAL(timeout()),
+ this, TQT_SLOT(doAutoRepeat()) );
+ }
+ repeater->start( thresholdTime, FALSE );
+}
+
+
+/*!
+ Stops the auto-repeat logic.
+*/
+
+void TQScrollBar::stopAutoRepeat()
+{
+ delete repeater;
+ repeater = 0;
+}
+
+
+/*!
+ \reimp
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQScrollBar::wheelEvent( TQWheelEvent *e )
+{
+ static float offset = 0;
+ static TQScrollBar* offset_owner = 0;
+ if (offset_owner != this){
+ offset_owner = this;
+ offset = 0;
+ }
+ if ( e->orientation() != orient && !TQT_TQRECT_OBJECT(rect()).tqcontains(e->pos()) )
+ return;
+ e->accept();
+ int step = TQMIN( TQApplication::wheelScrollLines()*lineStep(),
+ pageStep() );
+ if ( ( e->state() & ControlButton ) || ( e->state() & ShiftButton ) )
+ step = pageStep();
+ offset += -e->delta()*step/120;
+ if (TQABS(offset)<1)
+ return;
+ setValue( value() + int(offset) );
+ offset -= int(offset);
+}
+#endif
+
+/*!
+ \reimp
+*/
+void TQScrollBar::keyPressEvent( TQKeyEvent *e )
+{
+ // \list
+ // \i Left/Right move a horizontal scrollbar by one line.
+ // \i Up/Down move a vertical scrollbar by one line.
+ // \i PageUp moves up one page.
+ // \i PageDown moves down one page.
+ // \i Home moves to the start (minValue()).
+ // \i End moves to the end (maxValue()).
+ // \endlist
+
+ // Note that unless you call setFocusPolicy(), the default NoFocus
+ // will apply and the user will not be able to use the keyboard to
+ // interact with the scrollbar.
+ switch ( e->key() ) {
+ case Qt::Key_Left:
+ if ( orient == Qt::Horizontal )
+ subtractLine();
+ break;
+ case Qt::Key_Right:
+ if ( orient == Qt::Horizontal )
+ addLine();
+ break;
+ case Qt::Key_Up:
+ if ( orient == Qt::Vertical )
+ subtractLine();
+ break;
+ case Qt::Key_Down:
+ if ( orient == Qt::Vertical )
+ addLine();
+ break;
+ case Qt::Key_PageUp:
+ subtractPage();
+ break;
+ case Qt::Key_PageDown:
+ addPage();
+ break;
+ case Qt::Key_Home:
+ setValue( minValue() );
+ break;
+ case Qt::Key_End:
+ setValue( maxValue() );
+ break;
+ default:
+ e->ignore();
+ break;
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQScrollBar::resizeEvent( TQResizeEvent * )
+{
+ positionSliderFromValue();
+}
+
+
+/*!
+ \reimp
+*/
+void TQScrollBar::paintEvent( TQPaintEvent * )
+{
+ TQPainter p( this );
+ tqdrawControls(TQStyle::SC_ScrollBarAddLine |
+ TQStyle::SC_ScrollBarSubLine |
+ TQStyle::SC_ScrollBarAddPage |
+ TQStyle::SC_ScrollBarSubPage |
+ TQStyle::SC_ScrollBarFirst |
+ TQStyle::SC_ScrollBarLast |
+ TQStyle::SC_ScrollBarSlider,
+ pressedControl, &p );
+}
+
+static TQCOORD sliderStartPos = 0;
+
+/*!
+ \reimp
+ */
+void TQScrollBar::contextMenuEvent( TQContextMenuEvent *e )
+{
+ if(clickedAt)
+ e->consume();
+ else
+ e->ignore();
+}
+
+/*!
+ \reimp
+*/
+void TQScrollBar::mousePressEvent( TQMouseEvent *e )
+{
+ bool midButtonAbsPos =
+ tqstyle().tqstyleHint(TQStyle::SH_ScrollBar_MiddleClickAbsolutePosition,
+ this);
+
+ if ( !(e->button() == Qt::LeftButton ||
+ (midButtonAbsPos && e->button() == Qt::MidButton) ) )
+ return;
+
+ if ( maxValue() == minValue() ) // nothing to be done
+ return;
+
+ if ( e->state() & Qt::MouseButtonMask ) // another button was already pressed
+ return;
+
+ clickedAt = TRUE;
+ pressedControl = tqstyle().querySubControl(TQStyle::CC_ScrollBar, this, e->pos() );
+
+ if ( (pressedControl == TQStyle::SC_ScrollBarAddPage ||
+ pressedControl == TQStyle::SC_ScrollBarSubPage ||
+ pressedControl == TQStyle::SC_ScrollBarSlider ) &&
+ ((midButtonAbsPos && e->button() == Qt::MidButton) ||
+ (tqstyle().tqstyleHint(TQStyle::SH_ScrollBar_LeftClickAbsolutePosition) && e->button() == Qt::LeftButton))) {
+
+ TQRect sr = tqstyle().querySubControlMetrics(TQStyle::CC_ScrollBar, this,
+ TQStyle::SC_ScrollBarSlider ),
+ gr = tqstyle().querySubControlMetrics(TQStyle::CC_ScrollBar, this,
+ TQStyle::SC_ScrollBarGroove );
+ int sliderMin, sliderMax, sliderLength;
+ sliderMin = sliderMax = sliderLength = 0;
+ if (HORIZONTAL) {
+ sliderMin = gr.x();
+ sliderMax = sliderMin + gr.width();
+ sliderLength = sr.width();
+ } else {
+ sliderMin = gr.y();
+ sliderMax = sliderMin + gr.height();
+ sliderLength = sr.height();
+ }
+
+ int newSliderPos = (HORIZONTAL ? e->pos().x() : e->pos().y())
+ - sliderLength/2;
+ newSliderPos = TQMIN( newSliderPos, sliderMax - sliderLength );
+ newSliderPos = TQMAX( newSliderPos, sliderMin );
+ setValue( sliderPosToRangeValue(newSliderPos) );
+ sliderPos = newSliderPos;
+ pressedControl = TQStyle::SC_ScrollBarSlider;
+ }
+
+ if ( pressedControl == TQStyle::SC_ScrollBarSlider ) {
+ clickOffset = (TQCOORD)( (HORIZONTAL ? e->pos().x() : e->pos().y())
+ - sliderPos );
+ slidePrevVal = value();
+ sliderStartPos = sliderPos;
+ tqdrawControls( pressedControl, pressedControl );
+ emit sliderPressed();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ScrollingStart );
+#endif
+ } else if ( pressedControl != TQStyle::SC_None ) {
+ tqdrawControls( pressedControl, pressedControl );
+ action( (TQStyle::SubControl) pressedControl );
+ startAutoRepeat();
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQScrollBar::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( !clickedAt )
+ return;
+
+ if ( e->stateAfter() & Qt::MouseButtonMask ) // some other button is still pressed
+ return;
+
+ TQStyle::SubControl tmp = (TQStyle::SubControl) pressedControl;
+ clickedAt = FALSE;
+ stopAutoRepeat();
+ mouseMoveEvent( e ); // Might have moved since last mouse move event.
+ pressedControl = TQStyle::SC_None;
+
+ if (tmp == TQStyle::SC_ScrollBarSlider) {
+ directSetValue( calculateValueFromSlider() );
+ emit sliderReleased();
+ if ( value() != prevValue() ) {
+ emit valueChanged( value() );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+ }
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ScrollingEnd );
+#endif
+ }
+ tqdrawControls( tmp, pressedControl );
+ if ( e->button() == Qt::MidButton )
+ tqrepaint( FALSE );
+}
+
+
+/*!
+ \reimp
+*/
+void TQScrollBar::mouseMoveEvent( TQMouseEvent *e )
+{
+ if ( !isVisible() ) {
+ clickedAt = FALSE;
+ return;
+ }
+
+ bool mcab = tqstyle().tqstyleHint(TQStyle::SH_ScrollBar_MiddleClickAbsolutePosition,
+ this);
+ if ( ! clickedAt || ! (e->state() & Qt::LeftButton ||
+ ((e->state() & Qt::MidButton) && mcab)))
+ return;
+
+ int newSliderPos;
+ if ( pressedControl == TQStyle::SC_ScrollBarSlider ) {
+ TQRect gr = tqstyle().querySubControlMetrics(TQStyle::CC_ScrollBar, this,
+ TQStyle::SC_ScrollBarGroove ),
+ sr = tqstyle().querySubControlMetrics(TQStyle::CC_ScrollBar, this,
+ TQStyle::SC_ScrollBarSlider );
+ int sliderMin, sliderMax, sliderLength;
+
+ if (HORIZONTAL) {
+ sliderLength = sr.width();
+ sliderMin = gr.x();
+ sliderMax = gr.right() - sliderLength + 1;
+ } else {
+ sliderLength = sr.height();
+ sliderMin = gr.y();
+ sliderMax = gr.bottom() - sliderLength + 1;
+ }
+
+ TQRect r = rect();
+ int m = tqstyle().tqpixelMetric(TQStyle::PM_MaximumDragDistance, this);
+ if ( m >= 0 ) {
+ if ( orientation() == Qt::Horizontal )
+ r.setRect( r.x() - m, r.y() - 2*m, r.width() + 2*m, r.height() + 4*m );
+ else
+ r.setRect( r.x() - 2*m, r.y() - m, r.width() + 4*m, r.height() + 2*m );
+ if (! r.tqcontains( e->pos()))
+ newSliderPos = sliderStartPos;
+ else
+ newSliderPos = (HORIZONTAL ? e->pos().x() :
+ e->pos().y()) -clickOffset;
+ } else
+ newSliderPos = (HORIZONTAL ? e->pos().x() :
+ e->pos().y()) -clickOffset;
+
+ if ( newSliderPos < sliderMin )
+ newSliderPos = sliderMin;
+ else if ( newSliderPos > sliderMax )
+ newSliderPos = sliderMax;
+ int newVal = sliderPosToRangeValue(newSliderPos);
+ if ( newVal != slidePrevVal )
+ emit sliderMoved( newVal );
+ if ( track && newVal != value() ) {
+ directSetValue( newVal ); // Set directly, painting done below
+ emit valueChanged( value() );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+ }
+ slidePrevVal = newVal;
+ sliderPos = (TQCOORD)newSliderPos;
+ tqdrawControls( TQStyle::SC_ScrollBarAddPage |
+ TQStyle::SC_ScrollBarSlider |
+ TQStyle::SC_ScrollBarSubPage,
+ pressedControl );
+ } else if (! tqstyle().tqstyleHint(TQStyle::SH_ScrollBar_ScrollWhenPointerLeavesControl)) {
+ // stop scrolling when the mouse pointer leaves a control
+ // similar to push buttons
+ if ( pressedControl != (uint)tqstyle().querySubControl(TQStyle::CC_ScrollBar, this, e->pos() ) ) {
+ tqdrawControls( pressedControl, TQStyle::SC_None );
+ stopAutoRepeat();
+ } else if ( !repeater ) {
+ tqdrawControls( pressedControl, pressedControl );
+ action( (TQStyle::SubControl) pressedControl );
+ startAutoRepeat();
+ }
+ }
+}
+
+
+/*!
+ \fn int TQScrollBar::sliderStart() const
+
+ Returns the pixel position where the scroll bar slider starts.
+
+ This is equivalent to sliderRect().y() for vertical scroll bars or
+ sliderRect().x() for horizontal scroll bars.
+*/
+
+/*!
+ Returns the scroll bar slider rectangle.
+
+ \sa sliderStart()
+*/
+
+TQRect TQScrollBar::sliderRect() const
+{
+ return tqstyle().querySubControlMetrics(TQStyle::CC_ScrollBar, this,
+ TQStyle::SC_ScrollBarSlider );
+}
+
+void TQScrollBar::positionSliderFromValue()
+{
+ sliderPos = (TQCOORD)rangeValueToSliderPos( value() );
+}
+
+int TQScrollBar::calculateValueFromSlider() const
+{
+ return sliderPosToRangeValue( sliderPos );
+}
+
+int TQScrollBar::rangeValueToSliderPos( int v ) const
+{
+ TQRect gr = tqstyle().querySubControlMetrics(TQStyle::CC_ScrollBar, this,
+ TQStyle::SC_ScrollBarGroove );
+ TQRect sr = tqstyle().querySubControlMetrics(TQStyle::CC_ScrollBar, this,
+ TQStyle::SC_ScrollBarSlider );
+ int sliderMin, sliderMax, sliderLength;
+
+ if (HORIZONTAL) {
+ sliderLength = sr.width();
+ sliderMin = gr.x();
+ sliderMax = gr.right() - sliderLength + 1;
+ } else {
+ sliderLength = sr.height();
+ sliderMin = gr.y();
+ sliderMax = gr.bottom() - sliderLength + 1;
+ }
+
+ return positionFromValue( v, sliderMax-sliderMin ) + sliderMin;
+}
+
+int TQScrollBar::sliderPosToRangeValue( int pos ) const
+{
+ TQRect gr = tqstyle().querySubControlMetrics(TQStyle::CC_ScrollBar, this,
+ TQStyle::SC_ScrollBarGroove );
+ TQRect sr = tqstyle().querySubControlMetrics(TQStyle::CC_ScrollBar, this,
+ TQStyle::SC_ScrollBarSlider );
+ int sliderMin, sliderMax, sliderLength;
+
+ if (HORIZONTAL) {
+ sliderLength = sr.width();
+ sliderMin = gr.x();
+ sliderMax = gr.right() - sliderLength + 1;
+ } else {
+ sliderLength = sr.height();
+ sliderMin = gr.y();
+ sliderMax = gr.bottom() - sliderLength + 1;
+ }
+
+ return valueFromPosition( pos - sliderMin, sliderMax - sliderMin );
+}
+
+
+void TQScrollBar::action( int control )
+{
+ switch( control ) {
+ case TQStyle::SC_ScrollBarAddLine:
+ addLine();
+ emit nextLine();
+ break;
+ case TQStyle::SC_ScrollBarSubLine:
+ subtractLine();
+ emit prevLine();
+ break;
+ case TQStyle::SC_ScrollBarAddPage:
+ addPage();
+ emit nextPage();
+ break;
+ case TQStyle::SC_ScrollBarSubPage:
+ subtractPage();
+ emit prevPage();
+ break;
+ case TQStyle::SC_ScrollBarFirst:
+ setValue( minValue() );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+ emit valueChanged( minValue() );
+ break;
+ case TQStyle::SC_ScrollBarLast:
+ setValue( maxValue() );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+ emit valueChanged( maxValue() );
+ break;
+ default:
+ break;
+ }
+}
+
+
+void TQScrollBar::tqdrawControls( uint controls, uint activeControl ) const
+{
+ TQPainter p ( this );
+ tqdrawControls( controls, activeControl, &p );
+}
+
+
+void TQScrollBar::tqdrawControls( uint controls, uint activeControl,
+ TQPainter *p ) const
+{
+ if ( !isUpdatesEnabled() )
+ return;
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+ if ( orientation() == Qt::Horizontal )
+ flags |= TQStyle::Style_Horizontal;
+
+ tqstyle().tqdrawComplexControl(TQStyle::CC_ScrollBar, p, this, rect(), tqcolorGroup(),
+ flags, (TQStyle::SubControl) controls,
+ (TQStyle::SubControl) activeControl );
+}
+
+/*!
+ \reimp
+*/
+void TQScrollBar::styleChange( TQStyle& old )
+{
+ positionSliderFromValue();
+ setBackgroundMode((TQt::BackgroundMode)
+ tqstyle().tqstyleHint(TQStyle::SH_ScrollBar_BackgroundMode));
+ TQWidget::styleChange( old );
+}
+
+/*!
+ \property TQScrollBar::minValue
+ \brief the scroll bar's minimum value
+
+ When setting this property, the \l TQScrollBar::maxValue is
+ adjusted if necessary to ensure that the range remains valid.
+
+ \sa setRange()
+*/
+int TQScrollBar::minValue() const
+{
+ return TQRangeControl::minValue();
+}
+
+void TQScrollBar::setMinValue( int minVal )
+{
+ TQRangeControl::setMinValue( minVal );
+}
+
+/*!
+ \property TQScrollBar::maxValue
+ \brief the scroll bar's maximum value
+
+ When setting this property, the \l TQScrollBar::minValue is
+ adjusted if necessary to ensure that the range remains valid.
+
+ \sa setRange()
+*/
+int TQScrollBar::maxValue() const
+{
+ return TQRangeControl::maxValue();
+}
+
+void TQScrollBar::setMaxValue( int maxVal )
+{
+ TQRangeControl::setMaxValue( maxVal );
+}
+
+/*!
+ \property TQScrollBar::lineStep
+ \brief the line step
+
+ When setting lineStep, the virtual stepChange() function will be
+ called if the new line step is different from the previous
+ setting.
+
+ \sa setSteps() TQRangeControl::pageStep() setRange()
+*/
+
+int TQScrollBar::lineStep() const
+{
+ return TQRangeControl::lineStep();
+}
+
+/*!
+ \property TQScrollBar::pageStep
+ \brief the page step
+
+ When setting pageStep, the virtual stepChange() function will be
+ called if the new page step is different from the previous
+ setting.
+
+ \sa TQRangeControl::setSteps() setLineStep() setRange()
+*/
+
+int TQScrollBar::pageStep() const
+{
+ return TQRangeControl::pageStep();
+}
+
+void TQScrollBar::setLineStep( int i )
+{
+ setSteps( i, pageStep() );
+}
+
+void TQScrollBar::setPageStep( int i )
+{
+ setSteps( lineStep(), i );
+}
+
+/*!
+ \property TQScrollBar::value
+ \brief the scroll bar's value
+
+ \sa TQRangeControl::value() prevValue()
+*/
+
+int TQScrollBar::value() const
+{
+ return TQRangeControl::value();
+}
+
+void TQScrollBar::setValue( int i )
+{
+ TQRangeControl::setValue( i );
+}
+
+
+/*!
+ This function is called when the scrollbar is hidden.
+*/
+void TQScrollBar::hideEvent( TQHideEvent* )
+{
+ pressedControl = TQStyle::SC_None;
+ clickedAt = FALSE;
+}
+
+
+#undef ADD_LINE_ACTIVE
+#undef SUB_LINE_ACTIVE
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqscrollbar.h b/tqtinterface/qt4/src/widgets/tqscrollbar.h
new file mode 100644
index 0000000..cf48a05
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqscrollbar.h
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Definition of TQScrollBar class
+**
+** Created : 940427
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSCROLLBAR_H
+#define TQSCROLLBAR_H
+
+class TQTimer;
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqrangecontrol.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SCROLLBAR
+
+class TQ_EXPORT TQScrollBar : public TQWidget, public TQRangeControl
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( int minValue READ minValue WRITE setMinValue )
+ Q_PROPERTY( int maxValue READ maxValue WRITE setMaxValue )
+ Q_PROPERTY( int lineStep READ lineStep WRITE setLineStep )
+ Q_PROPERTY( int pageStep READ pageStep WRITE setPageStep )
+ Q_PROPERTY( int value READ value WRITE setValue )
+ Q_PROPERTY( bool tracking READ tracking WRITE setTracking )
+ Q_PROPERTY( bool draggingSlider READ draggingSlider )
+ Q_PROPERTY( Orientation orientation READ orientation WRITE setOrientation )
+
+public:
+ TQScrollBar( TQWidget *tqparent, const char* name = 0 );
+ TQScrollBar( Qt::Orientation, TQWidget *tqparent, const char* name = 0 );
+ TQScrollBar( int minValue, int maxValue, int lineStep, int pageStep,
+ int value, Qt::Orientation, TQWidget *tqparent, const char* name = 0 );
+ ~TQScrollBar();
+
+ virtual void setOrientation( Qt::Orientation );
+ Qt::Orientation orientation() const;
+ virtual void setTracking( bool enable );
+ bool tracking() const;
+ bool draggingSlider() const;
+
+ virtual void setPalette( const TQPalette & );
+ virtual TQSize tqsizeHint() const;
+ virtual void tqsetSizePolicy( TQSizePolicy sp );
+ void tqsetSizePolicy( TQSizePolicy::SizeType hor, TQSizePolicy::SizeType ver, bool hfw = FALSE );
+
+ int minValue() const;
+ int maxValue() const;
+ void setMinValue( int );
+ void setMaxValue( int );
+ int lineStep() const;
+ int pageStep() const;
+ void setLineStep( int );
+ void setPageStep( int );
+ int value() const;
+
+ int sliderStart() const;
+ TQRect sliderRect() const;
+
+public Q_SLOTS:
+ void setValue( int );
+
+Q_SIGNALS:
+ void valueChanged( int value );
+ void sliderPressed();
+ void sliderMoved( int value );
+ void sliderReleased();
+ void nextLine();
+ void prevLine();
+ void nextPage();
+ void prevPage();
+
+protected:
+#ifndef TQT_NO_WHEELEVENT
+ void wheelEvent( TQWheelEvent * );
+#endif
+ void keyPressEvent( TQKeyEvent * );
+ void resizeEvent( TQResizeEvent * );
+ void paintEvent( TQPaintEvent * );
+
+ void mousePressEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void contextMenuEvent( TQContextMenuEvent * );
+ void hideEvent( TQHideEvent* );
+
+ void valueChange();
+ void stepChange();
+ void rangeChange();
+
+ void styleChange( TQStyle& );
+
+private Q_SLOTS:
+ void doAutoRepeat();
+
+private:
+ void init();
+ void positionSliderFromValue();
+ int calculateValueFromSlider() const;
+
+ void startAutoRepeat();
+ void stopAutoRepeat();
+
+ int rangeValueToSliderPos( int val ) const;
+ int sliderPosToRangeValue( int val ) const;
+
+ void action( int control );
+
+ void tqdrawControls( uint controls, uint activeControl ) const;
+ void tqdrawControls( uint controls, uint activeControl,
+ TQPainter *p ) const;
+
+ uint pressedControl;
+ bool track;
+ bool clickedAt;
+ Qt::Orientation orient;
+
+ int slidePrevVal;
+ TQCOORD sliderPos;
+ TQCOORD clickOffset;
+
+ TQTimer * repeater;
+ void * d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQScrollBar( const TQScrollBar & );
+ TQScrollBar &operator=( const TQScrollBar & );
+#endif
+};
+
+
+inline void TQScrollBar::setTracking( bool t )
+{
+ track = t;
+}
+
+inline bool TQScrollBar::tracking() const
+{
+ return track;
+}
+
+inline Qt::Orientation TQScrollBar::orientation() const
+{
+ return orient;
+}
+
+inline int TQScrollBar::sliderStart() const
+{
+ return sliderPos;
+}
+
+inline void TQScrollBar::tqsetSizePolicy( TQSizePolicy::SizeType hor, TQSizePolicy::SizeType ver, bool hfw )
+{
+ TQWidget::tqsetSizePolicy( hor, ver, hfw );
+}
+
+
+#endif // TQT_NO_SCROLLBAR
+
+#endif // TQSCROLLBAR_H
diff --git a/tqtinterface/qt4/src/widgets/tqscrollview.cpp b/tqtinterface/qt4/src/widgets/tqscrollview.cpp
new file mode 100644
index 0000000..49c5b4d
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqscrollview.cpp
@@ -0,0 +1,2851 @@
+/****************************************************************************
+**
+** Implementation of TQScrollView class
+**
+** Created : 950524
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwidget.h"
+#ifndef TQT_NO_SCROLLVIEW
+#include "tqscrollbar.h"
+#include "tqobjectlist.h"
+#include "tqpainter.h"
+#include "tqpixmap.h"
+#include "tqcursor.h"
+#include "tqfocusdata.h"
+#include "tqscrollview.h"
+#include "tqptrdict.h"
+#include "tqapplication.h"
+#include "tqtimer.h"
+#include "tqstyle.h"
+#include "tqlistview.h"
+#ifdef TQ_WS_MAC
+# include "tqt_mac.h"
+#endif
+
+static const int coord_limit = 4000;
+static const int autoscroll_margin = 16;
+static const int initialScrollTime = 30;
+static const int initialScrollAccel = 5;
+
+struct TQSVChildRec {
+ TQSVChildRec(TQWidget* c, int xx, int yy) :
+ child(c),
+ x(xx), y(yy)
+ {
+ }
+
+ void hideOrShow(TQScrollView* sv, TQWidget* clipped_viewport);
+ void moveTo(TQScrollView* sv, int xx, int yy, TQWidget* clipped_viewport)
+ {
+ if ( x != xx || y != yy ) {
+ x = xx;
+ y = yy;
+ hideOrShow(sv,clipped_viewport);
+ }
+ }
+ TQWidget* child;
+ int x, y;
+};
+
+void TQSVChildRec::hideOrShow(TQScrollView* sv, TQWidget* clipped_viewport)
+{
+ if ( clipped_viewport ) {
+ if ( x+child->width() < sv->contentsX()+clipped_viewport->x()
+ || x > sv->contentsX()+clipped_viewport->width()
+ || y+child->height() < sv->contentsY()+clipped_viewport->y()
+ || y > sv->contentsY()+clipped_viewport->height() ) {
+ child->move(clipped_viewport->width(),
+ clipped_viewport->height());
+ } else {
+ child->move(x-sv->contentsX()-clipped_viewport->x(),
+ y-sv->contentsY()-clipped_viewport->y());
+ }
+ } else {
+ child->move(x-sv->contentsX(), y-sv->contentsY());
+ }
+}
+
+class TQViewportWidget : public TQWidget
+{
+ TQ_OBJECT
+
+public:
+ TQViewportWidget( TQScrollView* tqparent=0, const char* name=0, WFlags f = 0 )
+ : TQWidget( tqparent, name, f ) {}
+};
+
+class TQClipperWidget : public TQWidget
+{
+ TQ_OBJECT
+
+public:
+ TQClipperWidget( TQWidget * tqparent=0, const char * name=0, WFlags f=0 )
+ : TQWidget ( tqparent,name,f) {}
+};
+
+#include "tqscrollview.tqmoc"
+
+class TQScrollViewData {
+public:
+ TQScrollViewData(TQScrollView* tqparent, int vpwflags) :
+ hbar( new TQScrollBar( Qt::Horizontal, tqparent, "qt_hbar" ) ),
+ vbar( new TQScrollBar( Qt::Vertical, tqparent, "qt_vbar" ) ),
+ viewport( new TQViewportWidget( tqparent, "qt_viewport", (WFlags)vpwflags ) ),
+ clipped_viewport( 0 ),
+ flags( vpwflags ),
+ vx( 0 ), vy( 0 ), vwidth( 1 ), vheight( 1 ),
+#ifndef TQT_NO_DRAGANDDROP
+ autoscroll_timer( tqparent, "scrollview autoscroll timer" ),
+ drag_autoscroll( TRUE ),
+#endif
+ scrollbar_timer( tqparent, "scrollview scrollbar timer" ),
+ inresize( FALSE ), use_cached_size_hint( TRUE )
+ {
+ l_marg = r_marg = t_marg = b_marg = 0;
+ viewport->polish();
+ viewport->setBackgroundMode( TQt::PaletteDark );
+ viewport->setBackgroundOrigin( TQWidget::WidgetOrigin );
+ vMode = TQScrollView::Auto;
+ hMode = TQScrollView::Auto;
+ corner = 0;
+ defaultCorner = new TQWidget( tqparent, "qt_default_corner" );
+ defaultCorner->hide();
+ vbar->setSteps( 20, 1/*set later*/ );
+ hbar->setSteps( 20, 1/*set later*/ );
+ policy = TQScrollView::Default;
+ signal_choke = FALSE;
+ static_bg = FALSE;
+ fake_scroll = FALSE;
+ hbarPressed = FALSE;
+ vbarPressed = FALSE;
+ }
+ ~TQScrollViewData();
+
+ TQSVChildRec* rec(TQWidget* w) { return childDict.tqfind(w); }
+ TQSVChildRec* ancestorRec(TQWidget* w);
+ TQSVChildRec* addChildRec(TQWidget* w, int x, int y )
+ {
+ TQSVChildRec *r = new TQSVChildRec(w,x,y);
+ tqchildren.append(r);
+ childDict.insert(w, r);
+ return r;
+ }
+ void deleteChildRec(TQSVChildRec* r)
+ {
+ childDict.remove(r->child);
+ tqchildren.removeRef(r);
+ delete r;
+ }
+
+ void hideOrShowAll(TQScrollView* sv, bool isScroll = FALSE );
+ void moveAllBy(int dx, int dy);
+ bool anyVisibleChildren();
+ void autoMove(TQScrollView* sv);
+ void autoResize(TQScrollView* sv);
+ void autoRetqsizeHint(TQScrollView* sv);
+ void viewportResized( int w, int h );
+
+ TQScrollBar* hbar;
+ TQScrollBar* vbar;
+ bool hbarPressed;
+ bool vbarPressed;
+ TQViewportWidget* viewport;
+ TQClipperWidget* clipped_viewport;
+ int flags;
+ TQPtrList<TQSVChildRec> tqchildren;
+ TQPtrDict<TQSVChildRec> childDict;
+ TQWidget* corner, *defaultCorner;
+ int vx, vy, vwidth, vheight; // for drawContents-style usage
+ int l_marg, r_marg, t_marg, b_marg;
+ TQScrollView::ResizePolicy policy;
+ TQScrollView::ScrollBarMode vMode;
+ TQScrollView::ScrollBarMode hMode;
+#ifndef TQT_NO_DRAGANDDROP
+ TQPoint cpDragStart;
+ TQTimer autoscroll_timer;
+ int autoscroll_time;
+ int autoscroll_accel;
+ bool drag_autoscroll;
+#endif
+ TQTimer scrollbar_timer;
+
+ uint static_bg : 1;
+ uint fake_scroll : 1;
+
+ // This variable allows ensureVisible to move the contents then
+ // update both the sliders. Otherwise, updating the sliders would
+ // cause two image scrolls, creating ugly flashing.
+ //
+ uint signal_choke : 1;
+
+ // This variables indicates in updateScrollBars() that we are
+ // in a resizeEvent() and thus don't want to flash scrollbars
+ uint inresize : 1;
+ uint use_cached_size_hint : 1;
+ TQSize cachedSizeHint;
+
+ inline int contentsX() const { return -vx; }
+ inline int contentsY() const { return -vy; }
+ inline int contentsWidth() const { return vwidth; }
+};
+
+inline TQScrollViewData::~TQScrollViewData()
+{
+ tqchildren.setAutoDelete( TRUE );
+}
+
+TQSVChildRec* TQScrollViewData::ancestorRec(TQWidget* w)
+{
+ if ( clipped_viewport ) {
+ while (w->parentWidget() != clipped_viewport) {
+ w = w->parentWidget();
+ if (!w) return 0;
+ }
+ } else {
+ while (w->parentWidget() != viewport) {
+ w = w->parentWidget();
+ if (!w) return 0;
+ }
+ }
+ return rec(w);
+}
+
+void TQScrollViewData::hideOrShowAll(TQScrollView* sv, bool isScroll )
+{
+ if ( !clipped_viewport )
+ return;
+ if ( clipped_viewport->x() <= 0
+ && clipped_viewport->y() <= 0
+ && clipped_viewport->width()+clipped_viewport->x() >=
+ viewport->width()
+ && clipped_viewport->height()+clipped_viewport->y() >=
+ viewport->height() ) {
+ // clipped_viewport still covers viewport
+ if( static_bg )
+ clipped_viewport->tqrepaint( TRUE );
+ else if ( ( !isScroll && !clipped_viewport->testWFlags( TQt::WStaticContents) )
+ || static_bg )
+ TQApplication::postEvent( clipped_viewport,
+ new TQPaintEvent( clipped_viewport->clipRegion(),
+ !clipped_viewport->testWFlags(TQt::WResizeNoErase) ) );
+ } else {
+ // Re-center
+ int nx = ( viewport->width() - clipped_viewport->width() ) / 2;
+ int ny = ( viewport->height() - clipped_viewport->height() ) / 2;
+ clipped_viewport->move(nx,ny);
+ clipped_viewport->update();
+ }
+ for (TQSVChildRec *r = tqchildren.first(); r; r=tqchildren.next()) {
+ r->hideOrShow(sv, clipped_viewport);
+ }
+}
+
+void TQScrollViewData::moveAllBy(int dx, int dy)
+{
+ if ( clipped_viewport && !static_bg ) {
+ clipped_viewport->move( clipped_viewport->x()+dx,
+ clipped_viewport->y()+dy );
+ } else {
+ for (TQSVChildRec *r = tqchildren.first(); r; r=tqchildren.next()) {
+ r->child->move(r->child->x()+dx,r->child->y()+dy);
+ }
+ if ( static_bg )
+ viewport->tqrepaint( TRUE );
+ }
+}
+
+bool TQScrollViewData::anyVisibleChildren()
+{
+ for (TQSVChildRec *r = tqchildren.first(); r; r=tqchildren.next()) {
+ if (r->child->isVisible()) return TRUE;
+ }
+ return FALSE;
+}
+
+void TQScrollViewData::autoMove(TQScrollView* sv)
+{
+ if ( policy == TQScrollView::AutoOne ) {
+ TQSVChildRec* r = tqchildren.first();
+ if (r)
+ sv->setContentsPos(-r->child->x(),-r->child->y());
+ }
+}
+
+void TQScrollViewData::autoResize(TQScrollView* sv)
+{
+ if ( policy == TQScrollView::AutoOne ) {
+ TQSVChildRec* r = tqchildren.first();
+ if (r)
+ sv->resizeContents(r->child->width(),r->child->height());
+ }
+}
+
+void TQScrollViewData::autoRetqsizeHint(TQScrollView* sv)
+{
+ if ( policy == TQScrollView::AutoOne ) {
+ TQSVChildRec* r = tqchildren.first();
+ if (r) {
+ TQSize s = r->child->tqsizeHint();
+ if ( s.isValid() )
+ r->child->resize(s);
+ }
+ } else if ( policy == TQScrollView::AutoOneFit ) {
+ TQSVChildRec* r = tqchildren.first();
+ if (r) {
+ TQSize sh = r->child->tqsizeHint();
+ sh = sh.boundedTo( r->child->tqmaximumSize() );
+ sv->resizeContents( sh.width(), sh.height() );
+ }
+ }
+}
+
+void TQScrollViewData::viewportResized( int w, int h )
+{
+ if ( policy == TQScrollView::AutoOneFit ) {
+ TQSVChildRec* r = tqchildren.first();
+ if (r) {
+ TQSize sh = r->child->tqsizeHint();
+ sh = sh.boundedTo( r->child->tqmaximumSize() );
+ r->child->resize( TQMAX(w,sh.width()), TQMAX(h,sh.height()) );
+ }
+
+ }
+}
+
+
+/*!
+ \class TQScrollView tqscrollview.h
+ \brief The TQScrollView widget provides a scrolling area with on-demand scroll bars.
+
+ \ingroup abstractwidgets
+ \mainclass
+
+ The TQScrollView is a large canvas - potentially larger than the
+ coordinate system normally supported by the underlying window
+ system. This is important because it is quite easy to go beyond
+ these limitations (e.g. many web pages are more than 32000 pixels
+ high). Additionally, the TQScrollView can have TQWidgets positioned
+ on it that scroll around with the drawn content. These sub-widgets
+ can also have positions outside the normal coordinate range (but
+ they are still limited in size).
+
+ To provide content for the widget, inherit from TQScrollView,
+ reimplement drawContents() and use resizeContents() to set the
+ size of the viewed area. Use addChild() and moveChild() to
+ position widgets on the view.
+
+ To use TQScrollView effectively it is important to understand its
+ widget structure in the three styles of use: a single large child
+ widget, a large panning area with some widgets and a large panning
+ area with many widgets.
+
+ \section1 Using One Big Widget
+
+ \img qscrollview-vp2.png
+
+ The first, simplest usage of TQScrollView (depicted above), is
+ appropriate for scrolling areas that are never more than about
+ 4000 pixels in either dimension (this is about the maximum
+ reliable size on X11 servers). In this usage, you just make one
+ large child in the TQScrollView. The child should be a child of the
+ viewport() of the scrollview and be added with addChild():
+ \code
+ TQScrollView* sv = new TQScrollView(...);
+ TQVBox* big_box = new TQVBox(sv->viewport());
+ sv->addChild(big_box);
+ \endcode
+ You can go on to add arbitrary child widgets to the single child
+ in the scrollview as you would with any widget:
+ \code
+ TQLabel* child1 = new TQLabel("CHILD", big_box);
+ TQLabel* child2 = new TQLabel("CHILD", big_box);
+ TQLabel* child3 = new TQLabel("CHILD", big_box);
+ ...
+ \endcode
+
+ Here the TQScrollView has four tqchildren: the viewport(), the
+ verticalScrollBar(), the horizontalScrollBar() and a small
+ cornerWidget(). The viewport() has one child: the big TQVBox. The
+ TQVBox has the three TQLabel objects as child widgets. When the view
+ is scrolled, the TQVBox is moved; its tqchildren move with it as
+ child widgets normally do.
+
+ \section1 Using a Very Big View with Some Widgets
+
+ \img qscrollview-vp.png
+
+ The second usage of TQScrollView (depicted above) is appropriate
+ when few, if any, widgets are on a very large scrolling area that
+ is potentially larger than 4000 pixels in either dimension. In
+ this usage you call resizeContents() to set the size of the area
+ and reimplement drawContents() to paint the contents. You may also
+ add some widgets by making them tqchildren of the viewport() and
+ adding them with addChild() (this is the same as the process for
+ the single large widget in the previous example):
+ \code
+ TQScrollView* sv = new TQScrollView(...);
+ TQLabel* child1 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child1);
+ TQLabel* child2 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child2);
+ TQLabel* child3 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child3);
+ \endcode
+ Here, the TQScrollView has the same four tqchildren: the viewport(),
+ the verticalScrollBar(), the horizontalScrollBar() and a small
+ cornerWidget(). The viewport() has the three TQLabel objects as
+ child widgets. When the view is scrolled, the scrollview moves the
+ child widgets individually.
+
+ \section1 Using a Very Big View with Many Widgets
+
+ \target enableclipper
+ \img qscrollview-cl.png
+
+ The final usage of TQScrollView (depicted above) is appropriate
+ when many widgets are on a very large scrolling area that is
+ potentially larger than 4000 pixels in either dimension. In this
+ usage you call resizeContents() to set the size of the area and
+ reimplement drawContents() to paint the contents. You then call
+ enableClipper(TRUE) and add widgets, again by making them tqchildren
+ of the viewport(), and adding them with addChild():
+ \code
+ TQScrollView* sv = new TQScrollView(...);
+ sv->enableClipper(TRUE);
+ TQLabel* child1 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child1);
+ TQLabel* child2 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child2);
+ TQLabel* child3 = new TQLabel("CHILD", sv->viewport());
+ sv->addChild(child3);
+ \endcode
+
+ Here, the TQScrollView has four tqchildren: the clipper() (not the
+ viewport() this time), the verticalScrollBar(), the
+ horizontalScrollBar() and a small cornerWidget(). The clipper()
+ has one child: the viewport(). The viewport() has the same three
+ labels as child widgets. When the view is scrolled the viewport()
+ is moved; its tqchildren move with it as child widgets normally do.
+
+ \target allviews
+ \section1 Details Relevant for All Views
+
+ Normally you will use the first or third method if you want any
+ child widgets in the view.
+
+ Note that the widget you see in the scrolled area is the
+ viewport() widget, not the TQScrollView itself. So to turn mouse
+ tracking on, for example, use viewport()->setMouseTracking(TRUE).
+
+ To enable drag-and-drop, you would setAcceptDrops(TRUE) on the
+ TQScrollView (because drag-and-drop events propagate to the
+ tqparent). But to work out the logical position in the view, you
+ would need to map the drop co-ordinate from being relative to the
+ TQScrollView to being relative to the contents; use the function
+ viewportToContents() for this.
+
+ To handle mouse events on the scrolling area, subclass scrollview
+ as you would subclass other widgets, but rather than
+ reimplementing mousePressEvent(), reimplement
+ contentsMousePressEvent() instead. The contents specific event
+ handlers provide translated events in the coordinate system of the
+ scrollview. If you reimplement mousePressEvent(), you'll get
+ called only when part of the TQScrollView is clicked: and the only
+ such part is the "corner" (if you don't set a cornerWidget()) and
+ the frame; everything else is covered up by the viewport, clipper
+ or scroll bars.
+
+ When you construct a TQScrollView, some of the widget flags apply
+ to the viewport() instead of being sent to the TQWidget constructor
+ for the TQScrollView. This applies to \c WNoAutoErase, \c
+ WStaticContents, and \c WPaintClever. See \l TQt::WidgetFlags for
+ documentation about these flags. Here are some examples:
+
+ \list
+
+ \i An image-manipulation widget would use \c
+ WNoAutoErase|WStaticContents because the widget draws all pixels
+ itself, and when its size increases, it only needs a paint event
+ for the new part because the old part remains unchanged.
+
+ \i A scrolling game widget in which the background scrolls as the
+ characters move might use \c WNoAutoErase (in addition to \c
+ WStaticContents) so that the window system background does not
+ flash in and out during scrolling.
+
+ \i A word processing widget might use \c WNoAutoErase and tqrepaint
+ itself line by line to get a less-flickery resizing. If the widget
+ is in a mode in which no text justification can take place, it
+ might use \c WStaticContents too, so that it would only get a
+ tqrepaint for the newly visible parts.
+
+ \endlist
+
+ Child widgets may be moved using addChild() or moveChild(). Use
+ childX() and childY() to get the position of a child widget.
+
+ A widget may be placed in the corner between the vertical and
+ horizontal scrollbars with setCornerWidget(). You can get access
+ to the scrollbars using horizontalScrollBar() and
+ verticalScrollBar(), and to the viewport with viewport(). The
+ scroll view can be scrolled using scrollBy(), ensureVisible(),
+ setContentsPos() or center().
+
+ The visible area is given by visibleWidth() and visibleHeight(),
+ and the contents area by contentsWidth() and contentsHeight(). The
+ contents may be repainted using one of the repaintContents() or
+ updateContents() functions.
+
+ Coordinate conversion is provided by contentsToViewport() and
+ viewportToContents().
+
+ The contentsMoving() signal is emitted just before the contents
+ are moved to a new position.
+
+ \warning TQScrollView currently does not erase the background when
+ resized, i.e. you must always clear the background manually in
+ scrollview subclasses. This will change in a future version of TQt
+ and we recommend specifying the WNoAutoErase flag explicitly.
+
+ <img src=qscrollview-m.png> <img src=qscrollview-w.png>
+*/
+
+
+/*!
+ \enum TQScrollView::ResizePolicy
+
+ This enum type is used to control a TQScrollView's reaction to
+ resize events.
+
+ \value Default the TQScrollView selects one of the other settings
+ automatically when it has to. In this version of TQt, TQScrollView
+ changes to \c Manual if you resize the contents with
+ resizeContents() and to \c AutoOne if a child is added.
+
+ \value Manual the contents stays the size set by resizeContents().
+
+ \value AutoOne if there is only one child widget the contents stays
+ the size of that widget. Otherwise the behavior is undefined.
+
+ \value AutoOneFit if there is only one child widget the contents stays
+ the size of that widget's tqsizeHint(). If the scrollview is resized
+ larger than the child's tqsizeHint(), the child will be resized to
+ fit. If there is more than one child, the behavior is undefined.
+
+*/
+//#### The widget will be resized to its tqsizeHint() when a LayoutHint event
+//#### is received
+
+/*!
+ Constructs a TQScrollView called \a name with tqparent \a tqparent and
+ widget flags \a f.
+
+ The widget flags \c WStaticContents, \c WNoAutoErase and \c
+ WPaintClever are propagated to the viewport() widget. The other
+ widget flags are propagated to the tqparent constructor as usual.
+*/
+
+TQScrollView::TQScrollView( TQWidget *tqparent, const char *name, WFlags f ) :
+ TQFrame( tqparent, name, f & (~TQt::WStaticContents) & (~TQt::WResizeNoErase) )
+{
+ WFlags flags = (WFlags)(TQt::WResizeNoErase | (f&TQt::WPaintClever) | (f&WRepaintNoErase) | (f&TQt::WStaticContents));
+ d = new TQScrollViewData( this, flags );
+
+#ifndef TQT_NO_DRAGANDDROP
+ connect( &d->autoscroll_timer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( doDragAutoScroll() ) );
+#endif
+
+ connect( d->hbar, TQT_SIGNAL( valueChanged(int) ),
+ this, TQT_SLOT( hslide(int) ) );
+ connect( d->vbar, TQT_SIGNAL( valueChanged(int) ),
+ this, TQT_SLOT( vslide(int) ) );
+
+ connect( d->hbar, TQT_SIGNAL(sliderPressed()), this, TQT_SLOT(hbarIsPressed()) );
+ connect( d->hbar, TQT_SIGNAL(sliderReleased()), this, TQT_SLOT(hbarIsReleased()) );
+ connect( d->vbar, TQT_SIGNAL(sliderPressed()), this, TQT_SLOT(vbarIsPressed()) );
+ connect( d->vbar, TQT_SIGNAL(sliderReleased()), this, TQT_SLOT(vbarIsReleased()) );
+
+
+ d->viewport->installEventFilter( this );
+
+ connect( &d->scrollbar_timer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( updateScrollBars() ) );
+
+ setFrameStyle( TQFrame::StyledPanel | TQFrame::Sunken );
+ setLineWidth( tqstyle().tqpixelMetric(TQStyle::PM_DefaultFrameWidth, this) );
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) );
+}
+
+
+/*!
+ Destroys the TQScrollView. Any tqchildren added with addChild() will
+ be deleted.
+*/
+TQScrollView::~TQScrollView()
+{
+ // Be careful not to get all those useless events...
+ if ( d->clipped_viewport )
+ d->clipped_viewport->removeEventFilter( this );
+ else
+ d->viewport->removeEventFilter( this );
+
+ // order is important
+ // ~TQWidget may cause a WM_ERASEBKGND on Windows
+ delete d->vbar;
+ d->vbar = 0;
+ delete d->hbar;
+ d->hbar = 0;
+ delete d->viewport;
+ d->viewport = 0;
+ delete d;
+ d = 0;
+}
+
+/*!
+ \fn void TQScrollView::horizontalSliderPressed()
+
+ This signal is emitted whenever the user presses the horizontal slider.
+*/
+/*!
+ \fn void TQScrollView::horizontalSliderReleased()
+
+ This signal is emitted whenever the user releases the horizontal slider.
+*/
+/*!
+ \fn void TQScrollView::verticalSliderPressed()
+
+ This signal is emitted whenever the user presses the vertical slider.
+*/
+/*!
+ \fn void TQScrollView::verticalSliderReleased()
+
+ This signal is emitted whenever the user releases the vertical slider.
+*/
+void TQScrollView::hbarIsPressed()
+{
+ d->hbarPressed = TRUE;
+ emit( horizontalSliderPressed() );
+}
+
+void TQScrollView::hbarIsReleased()
+{
+ d->hbarPressed = FALSE;
+ emit( horizontalSliderReleased() );
+}
+
+/*!
+ Returns TRUE if horizontal slider is pressed by user; otherwise returns FALSE.
+*/
+bool TQScrollView::isHorizontalSliderPressed()
+{
+ return d->hbarPressed;
+}
+
+void TQScrollView::vbarIsPressed()
+{
+ d->vbarPressed = TRUE;
+ emit( verticalSliderPressed() );
+}
+
+void TQScrollView::vbarIsReleased()
+{
+ d->vbarPressed = FALSE;
+ emit( verticalSliderReleased() );
+}
+
+/*!
+ Returns TRUE if vertical slider is pressed by user; otherwise returns FALSE.
+*/
+bool TQScrollView::isVerticalSliderPressed()
+{
+ return d->vbarPressed;
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::styleChange( TQStyle& old )
+{
+ TQWidget::styleChange( old );
+ updateScrollBars();
+ d->cachedSizeHint = TQSize();
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::fontChange( const TQFont &old )
+{
+ TQWidget::fontChange( old );
+ updateScrollBars();
+ d->cachedSizeHint = TQSize();
+}
+
+void TQScrollView::hslide( int pos )
+{
+ if ( !d->signal_choke ) {
+ moveContents( -pos, -d->contentsY() );
+ TQApplication::syncX();
+ }
+}
+
+void TQScrollView::vslide( int pos )
+{
+ if ( !d->signal_choke ) {
+ moveContents( -d->contentsX(), -pos );
+ TQApplication::syncX();
+ }
+}
+
+/*!
+ Called when the horizontal scroll bar tqgeometry changes. This is
+ provided as a protected function so that subclasses can do
+ interesting things such as providing extra buttons in some of the
+ space normally used by the scroll bars.
+
+ The default implementation simply gives all the space to \a hbar.
+ The new tqgeometry is given by \a x, \a y, \a w and \a h.
+
+ \sa setVBarGeometry()
+*/
+void TQScrollView::setHBarGeometry(TQScrollBar& hbar,
+ int x, int y, int w, int h)
+{
+ hbar.setGeometry( x, y, w, h );
+}
+
+/*!
+ Called when the vertical scroll bar tqgeometry changes. This is
+ provided as a protected function so that subclasses can do
+ interesting things such as providing extra buttons in some of the
+ space normally used by the scroll bars.
+
+ The default implementation simply gives all the space to \a vbar.
+ The new tqgeometry is given by \a x, \a y, \a w and \a h.
+
+ \sa setHBarGeometry()
+*/
+void TQScrollView::setVBarGeometry( TQScrollBar& vbar,
+ int x, int y, int w, int h)
+{
+ vbar.setGeometry( x, y, w, h );
+}
+
+
+/*!
+ Returns the viewport size for size (\a x, \a y).
+
+ The viewport size depends on \a (x, y) (the size of the contents),
+ the size of this widget and the modes of the horizontal and
+ vertical scroll bars.
+
+ This function permits widgets that can trade vertical and
+ horizontal space for each other to control scroll bar appearance
+ better. For example, a word processor or web browser can control
+ the width of the right margin accurately, whether or not there
+ needs to be a vertical scroll bar.
+*/
+
+TQSize TQScrollView::viewportSize( int x, int y ) const
+{
+ int fw = frameWidth();
+ int lmarg = fw+d->l_marg;
+ int rmarg = fw+d->r_marg;
+ int tmarg = fw+d->t_marg;
+ int bmarg = fw+d->b_marg;
+
+ int w = width();
+ int h = height();
+
+ bool needh, needv;
+ bool showh, showv;
+ int hsbExt = horizontalScrollBar()->tqsizeHint().height();
+ int vsbExt = verticalScrollBar()->tqsizeHint().width();
+
+ if ( d->policy != AutoOne || d->anyVisibleChildren() ) {
+ // Do we definitely need the scrollbar?
+ needh = w-lmarg-rmarg < x;
+ needv = h-tmarg-bmarg < y;
+
+ // Do we intend to show the scrollbar?
+ if (d->hMode == AlwaysOn)
+ showh = TRUE;
+ else if (d->hMode == AlwaysOff)
+ showh = FALSE;
+ else
+ showh = needh;
+
+ if (d->vMode == AlwaysOn)
+ showv = TRUE;
+ else if (d->vMode == AlwaysOff)
+ showv = FALSE;
+ else
+ showv = needv;
+
+ // Given other scrollbar will be shown, NOW do we need one?
+ if ( showh && h-vsbExt-tmarg-bmarg < y ) {
+ if (d->vMode == Auto)
+ showv=TRUE;
+ }
+ if ( showv && w-hsbExt-lmarg-rmarg < x ) {
+ if (d->hMode == Auto)
+ showh=TRUE;
+ }
+ } else {
+ // Scrollbars not needed, only show scrollbar that are always on.
+ showh = d->hMode == AlwaysOn;
+ showv = d->vMode == AlwaysOn;
+ }
+
+ return TQSize( w-lmarg-rmarg - (showv ? vsbExt : 0),
+ h-tmarg-bmarg - (showh ? hsbExt : 0) );
+}
+
+
+/*!
+ Updates scroll bars: all possibilities are considered. You should
+ never need to call this in your code.
+*/
+void TQScrollView::updateScrollBars()
+{
+ if(!horizontalScrollBar() && !verticalScrollBar())
+ return;
+
+ // I support this should use viewportSize()... but it needs
+ // so many of the temporary variables from viewportSize. hm.
+ int fw = frameWidth();
+ int lmarg = fw+d->l_marg;
+ int rmarg = fw+d->r_marg;
+ int tmarg = fw+d->t_marg;
+ int bmarg = fw+d->b_marg;
+
+ int w = width();
+ int h = height();
+
+ int portw, porth;
+
+ bool needh;
+ bool needv;
+ bool showh;
+ bool showv;
+ bool showc = FALSE;
+
+ int hsbExt = horizontalScrollBar()->tqsizeHint().height();
+ int vsbExt = verticalScrollBar()->tqsizeHint().width();
+
+ TQSize oldVisibleSize( visibleWidth(), visibleHeight() );
+
+ if ( d->policy != AutoOne || d->anyVisibleChildren() ) {
+ // Do we definitely need the scrollbar?
+ needh = w-lmarg-rmarg < d->contentsWidth();
+ if ( d->inresize )
+ needh = !horizontalScrollBar()->isHidden();
+ needv = h-tmarg-bmarg < contentsHeight();
+
+ // Do we intend to show the scrollbar?
+ if (d->hMode == AlwaysOn)
+ showh = TRUE;
+ else if (d->hMode == AlwaysOff)
+ showh = FALSE;
+ else
+ showh = needh;
+
+ if (d->vMode == AlwaysOn)
+ showv = TRUE;
+ else if (d->vMode == AlwaysOff)
+ showv = FALSE;
+ else
+ showv = needv;
+
+#ifdef TQ_WS_MAC
+ bool mac_need_scroll = FALSE;
+ if(!parentWidget()) {
+ mac_need_scroll = TRUE;
+ } else {
+ TQWidget *tlw = tqtopLevelWidget();
+ TQPoint tlw_br = TQPoint(tlw->width(), tlw->height()),
+ my_br = posInWindow(this) + TQPoint(w, h);
+ if(my_br.x() >= tlw_br.x() - 3 && my_br.y() >= tlw_br.y() - 3)
+ mac_need_scroll = TRUE;
+ }
+ if(mac_need_scroll) {
+ WindowAttributes attr;
+ GetWindowAttributes((WindowPtr)handle(), &attr);
+ mac_need_scroll = (attr & kWindowResizableAttribute);
+ }
+ if(mac_need_scroll) {
+ showc = TRUE;
+ if(d->vMode == Auto)
+ showv = TRUE;
+ if(d->hMode == Auto)
+ showh = TRUE;
+ }
+#endif
+
+ // Given other scrollbar will be shown, NOW do we need one?
+ if ( showh && h-vsbExt-tmarg-bmarg < contentsHeight() ) {
+ needv=TRUE;
+ if (d->vMode == Auto)
+ showv=TRUE;
+ }
+ if ( showv && !d->inresize && w-hsbExt-lmarg-rmarg < d->contentsWidth() ) {
+ needh=TRUE;
+ if (d->hMode == Auto)
+ showh=TRUE;
+ }
+ } else {
+ // Scrollbars not needed, only show scrollbar that are always on.
+ needh = needv = FALSE;
+ showh = d->hMode == AlwaysOn;
+ showv = d->vMode == AlwaysOn;
+ }
+
+ bool sc = d->signal_choke;
+ d->signal_choke=TRUE;
+
+ // Hide unneeded scrollbar, calculate viewport size
+ if ( showh ) {
+ porth=h-hsbExt-tmarg-bmarg;
+ } else {
+ if (!needh)
+ d->hbar->setValue(0);
+ d->hbar->hide();
+ porth=h-tmarg-bmarg;
+ }
+ if ( showv ) {
+ portw=w-vsbExt-lmarg-rmarg;
+ } else {
+ if (!needv)
+ d->vbar->setValue(0);
+ d->vbar->hide();
+ portw=w-lmarg-rmarg;
+ }
+
+ // Configure scrollbars that we will show
+ if ( needv ) {
+ d->vbar->setRange( 0, contentsHeight()-porth );
+ d->vbar->setSteps( TQScrollView::d->vbar->lineStep(), porth );
+ } else {
+ d->vbar->setRange( 0, 0 );
+ }
+ if ( needh ) {
+ d->hbar->setRange( 0, TQMAX(0, d->contentsWidth()-portw) );
+ d->hbar->setSteps( TQScrollView::d->hbar->lineStep(), portw );
+ } else {
+ d->hbar->setRange( 0, 0 );
+ }
+
+ // Position the scrollbars, viewport and corner widget.
+ int bottom;
+ bool reverse = TQApplication::reverseLayout();
+ int xoffset = ( reverse && (showv || cornerWidget() )) ? vsbExt : 0;
+ int xpos = reverse ? 0 : w - vsbExt;
+ bool frameContentsOnly =
+ tqstyle().tqstyleHint(TQStyle::SH_ScrollView_FrameOnlyAroundContents);
+
+ if( ! frameContentsOnly ) {
+ if ( reverse )
+ xpos += fw;
+ else
+ xpos -= fw;
+ }
+ if ( showh ) {
+ int right = ( showc || showv || cornerWidget() ) ? w-vsbExt : w;
+ if ( ! frameContentsOnly )
+ setHBarGeometry( *d->hbar, fw + xoffset, h-hsbExt-fw,
+ right-fw-fw, hsbExt );
+ else
+ setHBarGeometry( *d->hbar, 0 + xoffset, h-hsbExt, right,
+ hsbExt );
+ bottom=h-hsbExt;
+ } else {
+ bottom=h;
+ }
+ if ( showv ) {
+ clipper()->setGeometry( lmarg + xoffset, tmarg,
+ w-vsbExt-lmarg-rmarg,
+ bottom-tmarg-bmarg );
+ d->viewportResized( w-vsbExt-lmarg-rmarg, bottom-tmarg-bmarg );
+ if ( ! frameContentsOnly )
+ changeFrameRect(TQRect(0, 0, w, h) );
+ else
+ changeFrameRect(TQRect(xoffset, 0, w-vsbExt, bottom));
+ if (showc || cornerWidget()) {
+ if ( ! frameContentsOnly )
+ setVBarGeometry( *d->vbar, xpos,
+ fw, vsbExt,
+ h-hsbExt-fw-fw );
+ else
+ setVBarGeometry( *d->vbar, xpos, 0,
+ vsbExt,
+ h-hsbExt );
+ }
+ else {
+ if ( ! frameContentsOnly )
+ setVBarGeometry( *d->vbar, xpos,
+ fw, vsbExt,
+ bottom-fw-fw );
+ else
+ setVBarGeometry( *d->vbar, xpos, 0,
+ vsbExt, bottom );
+ }
+ } else {
+ if ( ! frameContentsOnly )
+ changeFrameRect(TQRect(0, 0, w, h));
+ else
+ changeFrameRect(TQRect(0, 0, w, bottom));
+ clipper()->setGeometry( lmarg, tmarg,
+ w-lmarg-rmarg, bottom-tmarg-bmarg );
+ d->viewportResized( w-lmarg-rmarg, bottom-tmarg-bmarg );
+ }
+
+ TQWidget *corner = d->corner;
+ if ( !d->corner )
+ corner = d->defaultCorner;
+ if ( ! frameContentsOnly )
+ corner->setGeometry( xpos,
+ h-hsbExt-fw,
+ vsbExt,
+ hsbExt );
+ else
+ corner->setGeometry( xpos,
+ h-hsbExt,
+ vsbExt,
+ hsbExt );
+
+ d->signal_choke=sc;
+
+ if ( d->contentsX()+visibleWidth() > d->contentsWidth() ) {
+ int x;
+#if 0
+ if ( reverse )
+ x =TQMIN(0,d->contentsWidth()-visibleWidth());
+ else
+#endif
+ x =TQMAX(0,d->contentsWidth()-visibleWidth());
+ d->hbar->setValue(x);
+ // Do it even if it is recursive
+ moveContents( -x, -d->contentsY() );
+ }
+ if ( d->contentsY()+visibleHeight() > contentsHeight() ) {
+ int y=TQMAX(0,contentsHeight()-visibleHeight());
+ d->vbar->setValue(y);
+ // Do it even if it is recursive
+ moveContents( -d->contentsX(), -y );
+ }
+
+ // Finally, show the scroll bars
+ if ( showh && ( d->hbar->isHidden() || !d->hbar->isVisible() ) )
+ d->hbar->show();
+ if ( showv && ( d->vbar->isHidden() || !d->vbar->isVisible() ) )
+ d->vbar->show();
+
+ d->signal_choke=TRUE;
+ d->vbar->setValue( d->contentsY() );
+ d->hbar->setValue( d->contentsX() );
+ d->signal_choke=FALSE;
+
+ TQSize newVisibleSize( visibleWidth(), visibleHeight() );
+ if ( d->clipped_viewport && oldVisibleSize != newVisibleSize ) {
+ TQResizeEvent e( newVisibleSize, oldVisibleSize );
+ viewportResizeEvent( &e );
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQScrollView::show()
+{
+ if ( isVisible() )
+ return;
+ TQWidget::show();
+ updateScrollBars();
+ d->hideOrShowAll(this);
+}
+
+/*!
+ \reimp
+ */
+void TQScrollView::resize( int w, int h )
+{
+ TQWidget::resize( w, h );
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::resize( const TQSize& s )
+{
+ resize( s.width(), s.height() );
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::resizeEvent( TQResizeEvent* event )
+{
+ TQFrame::resizeEvent( event );
+
+#if 0
+ if ( TQApplication::reverseLayout() ) {
+ d->fake_scroll = TRUE;
+ scrollBy( -event->size().width() + event->oldSize().width(), 0 );
+ d->fake_scroll = FALSE;
+ }
+#endif
+
+ bool inresize = d->inresize;
+ d->inresize = TRUE;
+ updateScrollBars();
+ d->inresize = inresize;
+ d->scrollbar_timer.start( 0, TRUE );
+
+ d->hideOrShowAll(this);
+}
+
+
+
+/*!
+ \reimp
+*/
+void TQScrollView::mousePressEvent( TQMouseEvent * e) //#### remove for 4.0
+{
+ e->ignore();
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::mouseReleaseEvent( TQMouseEvent *e ) //#### remove for 4.0
+{
+ e->ignore();
+}
+
+
+/*!
+ \reimp
+*/
+void TQScrollView::mouseDoubleClickEvent( TQMouseEvent *e ) //#### remove for 4.0
+{
+ e->ignore();
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::mouseMoveEvent( TQMouseEvent *e ) //#### remove for 4.0
+{
+ e->ignore();
+}
+
+/*!
+ \reimp
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQScrollView::wheelEvent( TQWheelEvent *e )
+{
+ TQWheelEvent ce( viewport()->mapFromGlobal( e->globalPos() ),
+ e->globalPos(), e->delta(), e->state(), e->orientation());
+ viewportWheelEvent(&ce);
+ if ( !ce.isAccepted() ) {
+ if ( e->orientation() == Qt::Horizontal && horizontalScrollBar() && horizontalScrollBar()->isEnabled() )
+ TQApplication::sendEvent( horizontalScrollBar(), e);
+ else if (e->orientation() == Qt::Vertical && verticalScrollBar() && verticalScrollBar()->isEnabled() )
+ TQApplication::sendEvent( verticalScrollBar(), e);
+ } else {
+ e->accept();
+ }
+}
+#endif
+
+/*!
+ \reimp
+*/
+void TQScrollView::contextMenuEvent( TQContextMenuEvent *e )
+{
+ if ( e->reason() != TQContextMenuEvent::Keyboard ) {
+ e->ignore();
+ return;
+ }
+
+ TQContextMenuEvent ce( e->reason(), viewport()->mapFromGlobal( e->globalPos() ),
+ e->globalPos(), e->state() );
+ viewportContextMenuEvent( &ce );
+ if ( ce.isAccepted() )
+ e->accept();
+ else
+ e->ignore();
+}
+
+TQScrollView::ScrollBarMode TQScrollView::vScrollBarMode() const
+{
+ return d->vMode;
+}
+
+
+/*!
+ \enum TQScrollView::ScrollBarMode
+
+ This enum type describes the various modes of TQScrollView's scroll
+ bars.
+
+ \value Auto TQScrollView shows a scroll bar when the content is
+ too large to fit and not otherwise. This is the default.
+
+ \value AlwaysOff TQScrollView never shows a scroll bar.
+
+ \value AlwaysOn TQScrollView always shows a scroll bar.
+
+ (The modes for the horizontal and vertical scroll bars are
+ independent.)
+*/
+
+
+/*!
+ \property TQScrollView::vScrollBarMode
+ \brief the mode for the vertical scroll bar
+
+ The default mode is \c TQScrollView::Auto.
+
+ \sa hScrollBarMode
+*/
+void TQScrollView::setVScrollBarMode( ScrollBarMode mode )
+{
+ if (d->vMode != mode) {
+ d->vMode = mode;
+ updateScrollBars();
+ }
+}
+
+
+/*!
+ \property TQScrollView::hScrollBarMode
+ \brief the mode for the horizontal scroll bar
+
+ The default mode is \c TQScrollView::Auto.
+
+ \sa vScrollBarMode
+*/
+TQScrollView::ScrollBarMode TQScrollView::hScrollBarMode() const
+{
+ return d->hMode;
+}
+
+void TQScrollView::setHScrollBarMode( ScrollBarMode mode )
+{
+ if (d->hMode != mode) {
+ d->hMode = mode;
+ updateScrollBars();
+ }
+}
+
+
+/*!
+ Returns the widget in the corner between the two scroll bars.
+
+ By default, no corner widget is present.
+*/
+TQWidget* TQScrollView::cornerWidget() const
+{
+ return d->corner;
+}
+
+/*!
+ Sets the widget in the \a corner between the two scroll bars.
+
+ You will probably also want to set at least one of the scroll bar
+ modes to \c AlwaysOn.
+
+ Passing 0 shows no widget in the corner.
+
+ Any previous \a corner widget is hidden.
+
+ You may call setCornerWidget() with the same widget at different
+ times.
+
+ All widgets set here will be deleted by the TQScrollView when it is
+ destroyed unless you separately reparent the widget after setting
+ some other corner widget (or 0).
+
+ Any \e newly set widget should have no current tqparent.
+
+ By default, no corner widget is present.
+
+ \sa setVScrollBarMode(), setHScrollBarMode()
+*/
+void TQScrollView::setCornerWidget(TQWidget* corner)
+{
+ TQWidget* oldcorner = d->corner;
+ if (oldcorner != corner) {
+ if (oldcorner) oldcorner->hide();
+ d->corner = corner;
+
+ if ( corner && corner->parentWidget() != this ) {
+ // #### No clean way to get current WFlags
+ corner->reparent( this, (((TQScrollView*)corner))->getWFlags(),
+ TQPoint(0,0), FALSE );
+ }
+
+ updateScrollBars();
+ if ( corner ) corner->show();
+ }
+}
+
+
+void TQScrollView::setResizePolicy( ResizePolicy r )
+{
+ d->policy = r;
+}
+
+/*!
+ \property TQScrollView::resizePolicy
+ \brief the resize policy
+
+ The default is \c Default.
+
+ \sa ResizePolicy
+*/
+TQScrollView::ResizePolicy TQScrollView::resizePolicy() const
+{
+ return d->policy;
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::setEnabled( bool enable )
+{
+ TQFrame::setEnabled( enable );
+}
+
+/*!
+ Removes the \a child widget from the scrolled area. Note that this
+ happens automatically if the \a child is deleted.
+*/
+void TQScrollView::removeChild(TQWidget* child)
+{
+ if ( !d || !child ) // First check in case we are destructing
+ return;
+
+ TQSVChildRec *r = d->rec(child);
+ if ( r ) d->deleteChildRec( r );
+}
+
+/*!
+ \reimp
+*/
+void TQScrollView::removeChild(TQObject* child)
+{
+ TQFrame::removeChild(child);
+}
+
+/*!
+ Inserts the widget, \a child, into the scrolled area positioned at
+ (\a x, \a y). The position defaults to (0, 0). If the child is
+ already in the view, it is just moved.
+
+ You may want to call enableClipper(TRUE) if you add a large number
+ of widgets.
+*/
+void TQScrollView::addChild(TQWidget* child, int x, int y)
+{
+ if ( !child ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQScrollView::addChild(): Cannot add null child" );
+#endif
+ return;
+ }
+ child->polish();
+ child->setBackgroundOrigin(WidgetOrigin);
+
+ if ( child->parentWidget() == viewport() ) {
+ // May already be there
+ TQSVChildRec *r = d->rec(child);
+ if (r) {
+ r->moveTo(this,x,y,d->clipped_viewport);
+ if ( d->policy > Manual ) {
+ d->autoRetqsizeHint(this);
+ d->autoResize(this); // #### better to just deal with this one widget!
+ }
+ return;
+ }
+ }
+
+ if ( d->tqchildren.isEmpty() && d->policy != Manual ) {
+ if ( d->policy == Default )
+ setResizePolicy( AutoOne );
+ child->installEventFilter( this );
+ } else if ( d->policy == AutoOne ) {
+ child->removeEventFilter( this ); //#### ?????
+ setResizePolicy( Manual );
+ }
+ if ( child->parentWidget() != viewport() ) {
+ child->reparent( viewport(), 0, TQPoint(0,0), FALSE );
+ }
+ d->addChildRec(child,x,y)->hideOrShow(this, d->clipped_viewport);
+
+ if ( d->policy > Manual ) {
+ d->autoRetqsizeHint(this);
+ d->autoResize(this); // #### better to just deal with this one widget!
+ }
+}
+
+/*!
+ Repositions the \a child widget to (\a x, \a y). This function is
+ the same as addChild().
+*/
+void TQScrollView::moveChild(TQWidget* child, int x, int y)
+{
+ addChild(child,x,y);
+}
+
+/*!
+ Returns the X position of the given \a child widget. Use this
+ rather than TQWidget::x() for widgets added to the view.
+
+ This function returns 0 if \a child has not been added to the view.
+*/
+int TQScrollView::childX(TQWidget* child)
+{
+ TQSVChildRec *r = d->rec(child);
+ return r ? r->x : 0;
+}
+
+/*!
+ Returns the Y position of the given \a child widget. Use this
+ rather than TQWidget::y() for widgets added to the view.
+
+ This function returns 0 if \a child has not been added to the view.
+*/
+int TQScrollView::childY(TQWidget* child)
+{
+ TQSVChildRec *r = d->rec(child);
+ return r ? r->y : 0;
+}
+
+/*! \fn bool TQScrollView::childIsVisible(TQWidget*)
+ \obsolete
+
+ Returns TRUE if \a child is visible. This is equivalent
+ to child->isVisible().
+*/
+
+/*! \fn void TQScrollView::showChild(TQWidget* child, bool y)
+ \obsolete
+
+ Sets the visibility of \a child. Equivalent to
+ TQWidget::show() or TQWidget::hide().
+*/
+
+/*!
+ This event filter ensures the scroll bars are updated when a
+ single contents widget is resized, shown, hidden or destroyed; it
+ passes mouse events to the TQScrollView. The event is in \a e and
+ the object is in \a obj.
+*/
+
+bool TQScrollView::eventFilter( TQObject *obj, TQEvent *e )
+{
+ if ( !d )
+ return FALSE; // we are destructing
+ if ( TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(d->viewport) || TQT_BASE_OBJECT(obj) == TQT_BASE_OBJECT(d->clipped_viewport) ) {
+ switch ( e->type() ) {
+ /* Forward many events to viewport...() functions */
+ case TQEvent::Paint:
+ viewportPaintEvent( (TQPaintEvent*)e );
+ break;
+ case TQEvent::Resize:
+ if ( !d->clipped_viewport )
+ viewportResizeEvent( (TQResizeEvent *)e );
+ break;
+ case TQEvent::MouseButtonPress:
+ viewportMousePressEvent( (TQMouseEvent*)e );
+ if ( ((TQMouseEvent*)e)->isAccepted() )
+ return TRUE;
+ break;
+ case TQEvent::MouseButtonRelease:
+ viewportMouseReleaseEvent( (TQMouseEvent*)e );
+ if ( ((TQMouseEvent*)e)->isAccepted() )
+ return TRUE;
+ break;
+ case TQEvent::MouseButtonDblClick:
+ viewportMouseDoubleClickEvent( (TQMouseEvent*)e );
+ if ( ((TQMouseEvent*)e)->isAccepted() )
+ return TRUE;
+ break;
+ case TQEvent::MouseMove:
+ viewportMouseMoveEvent( (TQMouseEvent*)e );
+ if ( ((TQMouseEvent*)e)->isAccepted() )
+ return TRUE;
+ break;
+#ifndef TQT_NO_DRAGANDDROP
+ case TQEvent::DragEnter:
+ viewportDragEnterEvent( (TQDragEnterEvent*)e );
+ break;
+ case TQEvent::DragMove: {
+ if ( d->drag_autoscroll ) {
+ TQPoint vp = ((TQDragMoveEvent*) e)->pos();
+ TQRect inside_margin( autoscroll_margin, autoscroll_margin,
+ visibleWidth() - autoscroll_margin * 2,
+ visibleHeight() - autoscroll_margin * 2 );
+ if ( !inside_margin.tqcontains( vp ) ) {
+ startDragAutoScroll();
+ // Keep sending move events
+ ( (TQDragMoveEvent*)e )->accept( TQRect(0,0,0,0) );
+ }
+ }
+ viewportDragMoveEvent( (TQDragMoveEvent*)e );
+ } break;
+ case TQEvent::DragLeave:
+ stopDragAutoScroll();
+ viewportDragLeaveEvent( (TQDragLeaveEvent*)e );
+ break;
+ case TQEvent::Drop:
+ stopDragAutoScroll();
+ viewportDropEvent( (TQDropEvent*)e );
+ break;
+#endif // TQT_NO_DRAGANDDROP
+ case TQEvent::ContextMenu:
+ viewportContextMenuEvent( (TQContextMenuEvent*)e );
+ if ( ((TQContextMenuEvent*)e)->isAccepted() )
+ return TRUE;
+ break;
+ case TQEvent::ChildRemoved:
+ removeChild((TQWidget*)((TQChildEvent*)e)->child());
+ break;
+ case TQEvent::LayoutHint:
+ d->autoRetqsizeHint(this);
+ break;
+ default:
+ break;
+ }
+ } else if ( d && d->rec((TQWidget*)obj) ) { // must be a child
+ if ( e->type() == TQEvent::Resize )
+ d->autoResize(this);
+ else if ( e->type() == TQEvent::Move )
+ d->autoMove(this);
+ }
+ return TQFrame::eventFilter( obj, e ); // always continue with standard event processing
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ mousePressEvent(): the press position in \a e is translated to be a point
+ on the contents.
+*/
+void TQScrollView::contentsMousePressEvent( TQMouseEvent* e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ mouseReleaseEvent(): the release position in \a e is translated to be a
+ point on the contents.
+*/
+void TQScrollView::contentsMouseReleaseEvent( TQMouseEvent* e )
+{
+ e->ignore();
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ mouseDoubleClickEvent(): the click position in \a e is translated to be a
+ point on the contents.
+
+ The default implementation generates a normal mouse press event.
+*/
+void TQScrollView::contentsMouseDoubleClickEvent( TQMouseEvent* e )
+{
+ contentsMousePressEvent(e); // try mouse press event
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ mouseMoveEvent(): the mouse position in \a e is translated to be a point
+ on the contents.
+*/
+void TQScrollView::contentsMouseMoveEvent( TQMouseEvent* e )
+{
+ e->ignore();
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ dragEnterEvent(): the drag position is translated to be a point
+ on the contents.
+*/
+void TQScrollView::contentsDragEnterEvent( TQDragEnterEvent * )
+{
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ dragMoveEvent(): the drag position is translated to be a point on
+ the contents.
+*/
+void TQScrollView::contentsDragMoveEvent( TQDragMoveEvent * )
+{
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ dragLeaveEvent(): the drag position is translated to be a point
+ on the contents.
+*/
+void TQScrollView::contentsDragLeaveEvent( TQDragLeaveEvent * )
+{
+}
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ dropEvent(): the drop position is translated to be a point on the
+ contents.
+*/
+void TQScrollView::contentsDropEvent( TQDropEvent * )
+{
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ wheelEvent() in \a{e}: the mouse position is translated to be a
+ point on the contents.
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQScrollView::contentsWheelEvent( TQWheelEvent * e )
+{
+ e->ignore();
+}
+#endif
+/*!
+ This event handler is called whenever the TQScrollView receives a
+ contextMenuEvent() in \a{e}: the mouse position is translated to
+ be a point on the contents.
+*/
+void TQScrollView::contentsContextMenuEvent( TQContextMenuEvent *e )
+{
+ e->ignore();
+}
+
+/*!
+ This is a low-level painting routine that draws the viewport
+ contents. Reimplement this if drawContents() is too high-level
+ (for example, if you don't want to open a TQPainter on the
+ viewport). The paint event is passed in \a pe.
+*/
+void TQScrollView::viewportPaintEvent( TQPaintEvent* pe )
+{
+ TQWidget* vp = viewport();
+
+ TQPainter p(vp);
+ TQRect r = pe->rect();
+
+ if ( d->clipped_viewport ) {
+ TQRect rr(
+ -d->clipped_viewport->x(), -d->clipped_viewport->y(),
+ d->viewport->width(), d->viewport->height()
+ );
+ r &= rr;
+ if ( r.isValid() ) {
+ int ex = r.x() + d->clipped_viewport->x() + d->contentsX();
+ int ey = r.y() + d->clipped_viewport->y() + d->contentsY();
+ int ew = r.width();
+ int eh = r.height();
+ drawContentsOffset(&p,
+ d->contentsX()+d->clipped_viewport->x(),
+ d->contentsY()+d->clipped_viewport->y(),
+ ex, ey, ew, eh);
+ }
+ } else {
+ r &= d->viewport->rect();
+ int ex = r.x() + d->contentsX();
+ int ey = r.y() + d->contentsY();
+ int ew = r.width();
+ int eh = r.height();
+ drawContentsOffset(&p, d->contentsX(), d->contentsY(), ex, ey, ew, eh);
+ }
+}
+
+
+/*!
+ To provide simple processing of events on the contents, this
+ function receives all resize events sent to the viewport.
+
+ \sa TQWidget::resizeEvent()
+*/
+void TQScrollView::viewportResizeEvent( TQResizeEvent* )
+{
+}
+
+/*! \internal
+
+ To provide simple processing of events on the contents, this
+ function receives all mouse press events sent to the viewport,
+ translates the event and calls contentsMousePressEvent().
+
+ \sa contentsMousePressEvent(), TQWidget::mousePressEvent()
+*/
+void TQScrollView::viewportMousePressEvent( TQMouseEvent* e )
+{
+ TQMouseEvent ce(e->type(), viewportToContents(e->pos()),
+ e->globalPos(), e->button(), e->state());
+ contentsMousePressEvent(&ce);
+ if ( !ce.isAccepted() )
+ e->ignore();
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all mouse release events sent to the viewport, translates
+ the event and calls contentsMouseReleaseEvent().
+
+ \sa TQWidget::mouseReleaseEvent()
+*/
+void TQScrollView::viewportMouseReleaseEvent( TQMouseEvent* e )
+{
+ TQMouseEvent ce(e->type(), viewportToContents(e->pos()),
+ e->globalPos(), e->button(), e->state());
+ contentsMouseReleaseEvent(&ce);
+ if ( !ce.isAccepted() )
+ e->ignore();
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all mouse double click events sent to the viewport,
+ translates the event and calls contentsMouseDoubleClickEvent().
+
+ \sa TQWidget::mouseDoubleClickEvent()
+*/
+void TQScrollView::viewportMouseDoubleClickEvent( TQMouseEvent* e )
+{
+ TQMouseEvent ce(e->type(), viewportToContents(e->pos()),
+ e->globalPos(), e->button(), e->state());
+ contentsMouseDoubleClickEvent(&ce);
+ if ( !ce.isAccepted() )
+ e->ignore();
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all mouse move events sent to the viewport, translates the
+ event and calls contentsMouseMoveEvent().
+
+ \sa TQWidget::mouseMoveEvent()
+*/
+void TQScrollView::viewportMouseMoveEvent( TQMouseEvent* e )
+{
+ TQMouseEvent ce(e->type(), viewportToContents(e->pos()),
+ e->globalPos(), e->button(), e->state());
+ contentsMouseMoveEvent(&ce);
+ if ( !ce.isAccepted() )
+ e->ignore();
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all drag enter events sent to the viewport, translates the
+ event and calls contentsDragEnterEvent().
+
+ \sa TQWidget::dragEnterEvent()
+*/
+void TQScrollView::viewportDragEnterEvent( TQDragEnterEvent* e )
+{
+ e->setPoint(viewportToContents(e->pos()));
+ contentsDragEnterEvent(e);
+ e->setPoint(contentsToViewport(e->pos()));
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all drag move events sent to the viewport, translates the
+ event and calls contentsDragMoveEvent().
+
+ \sa TQWidget::dragMoveEvent()
+*/
+void TQScrollView::viewportDragMoveEvent( TQDragMoveEvent* e )
+{
+ e->setPoint(viewportToContents(e->pos()));
+ contentsDragMoveEvent(e);
+ e->setPoint(contentsToViewport(e->pos()));
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all drag leave events sent to the viewport and calls
+ contentsDragLeaveEvent().
+
+ \sa TQWidget::dragLeaveEvent()
+*/
+void TQScrollView::viewportDragLeaveEvent( TQDragLeaveEvent* e )
+{
+ contentsDragLeaveEvent(e);
+}
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all drop events sent to the viewport, translates the event
+ and calls contentsDropEvent().
+
+ \sa TQWidget::dropEvent()
+*/
+void TQScrollView::viewportDropEvent( TQDropEvent* e )
+{
+ e->setPoint(viewportToContents(e->pos()));
+ contentsDropEvent(e);
+ e->setPoint(contentsToViewport(e->pos()));
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!\internal
+
+ To provide simple processing of events on the contents, this function
+ receives all wheel events sent to the viewport, translates the
+ event and calls contentsWheelEvent().
+
+ \sa TQWidget::wheelEvent()
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQScrollView::viewportWheelEvent( TQWheelEvent* e )
+{
+ /*
+ Different than standard mouse events, because wheel events might
+ be sent to the focus widget if the widget-under-mouse doesn't want
+ the event itself.
+ */
+ TQWheelEvent ce( viewportToContents(e->pos()),
+ e->globalPos(), e->delta(), e->state());
+ contentsWheelEvent(&ce);
+ if ( ce.isAccepted() )
+ e->accept();
+ else
+ e->ignore();
+}
+#endif
+
+/*! \internal
+
+ To provide simple processing of events on the contents, this function
+ receives all context menu events sent to the viewport, translates the
+ event and calls contentsContextMenuEvent().
+*/
+void TQScrollView::viewportContextMenuEvent( TQContextMenuEvent *e )
+{
+ TQContextMenuEvent ce(e->reason(), viewportToContents(e->pos()), e->globalPos(), e->state() );
+ contentsContextMenuEvent( &ce );
+ if ( ce.isAccepted() )
+ e->accept();
+ else
+ e->ignore();
+}
+
+/*!
+ Returns the component horizontal scroll bar. It is made available
+ to allow accelerators, autoscrolling, etc.
+
+ It should not be used for other purposes.
+
+ This function never returns 0.
+*/
+TQScrollBar* TQScrollView::horizontalScrollBar() const
+{
+ return d->hbar;
+}
+
+/*!
+ Returns the component vertical scroll bar. It is made available to
+ allow accelerators, autoscrolling, etc.
+
+ It should not be used for other purposes.
+
+ This function never returns 0.
+*/
+TQScrollBar* TQScrollView::verticalScrollBar() const {
+ return d->vbar;
+}
+
+
+/*!
+ Scrolls the content so that the point \a (x, y) is visible with at
+ least 50-pixel margins (if possible, otherwise centered).
+*/
+void TQScrollView::ensureVisible( int x, int y )
+{
+ ensureVisible(x, y, 50, 50);
+}
+
+/*!
+ \overload
+
+ Scrolls the content so that the point \a (x, y) is visible with at
+ least the \a xmargin and \a ymargin margins (if possible,
+ otherwise centered).
+*/
+void TQScrollView::ensureVisible( int x, int y, int xmargin, int ymargin )
+{
+ int pw=visibleWidth();
+ int ph=visibleHeight();
+
+ int cx=-d->contentsX();
+ int cy=-d->contentsY();
+ int cw=d->contentsWidth();
+ int ch=contentsHeight();
+
+ if ( pw < xmargin*2 )
+ xmargin=pw/2;
+ if ( ph < ymargin*2 )
+ ymargin=ph/2;
+
+ if ( cw <= pw ) {
+ xmargin=0;
+ cx=0;
+ }
+ if ( ch <= ph ) {
+ ymargin=0;
+ cy=0;
+ }
+
+ if ( x < -cx+xmargin )
+ cx = -x+xmargin;
+ else if ( x >= -cx+pw-xmargin )
+ cx = -x+pw-xmargin;
+
+ if ( y < -cy+ymargin )
+ cy = -y+ymargin;
+ else if ( y >= -cy+ph-ymargin )
+ cy = -y+ph-ymargin;
+
+ if ( cx > 0 )
+ cx=0;
+ else if ( cx < pw-cw && cw>pw )
+ cx=pw-cw;
+
+ if ( cy > 0 )
+ cy=0;
+ else if ( cy < ph-ch && ch>ph )
+ cy=ph-ch;
+
+ setContentsPos( -cx, -cy );
+}
+
+/*!
+ Scrolls the content so that the point \a (x, y) is in the top-left
+ corner.
+*/
+void TQScrollView::setContentsPos( int x, int y )
+{
+#if 0
+ // bounds checking...
+ if ( TQApplication::reverseLayout() )
+ if ( x > d->contentsWidth() - visibleWidth() ) x = d->contentsWidth() - visibleWidth();
+ else
+#endif
+ if ( x < 0 ) x = 0;
+ if ( y < 0 ) y = 0;
+ // Choke signal handling while we update BOTH sliders.
+ d->signal_choke=TRUE;
+ moveContents( -x, -y );
+ d->vbar->setValue( y );
+ d->hbar->setValue( x );
+ d->signal_choke=FALSE;
+}
+
+/*!
+ Scrolls the content by \a dx to the left and \a dy upwards.
+*/
+void TQScrollView::scrollBy( int dx, int dy )
+{
+ setContentsPos( TQMAX( d->contentsX()+dx, 0 ), TQMAX( d->contentsY()+dy, 0 ) );
+}
+
+/*!
+ Scrolls the content so that the point \a (x, y) is in the center
+ of visible area.
+*/
+void TQScrollView::center( int x, int y )
+{
+ ensureVisible( x, y, 32000, 32000 );
+}
+
+/*!
+ \overload
+
+ Scrolls the content so that the point \a (x, y) is visible with
+ the \a xmargin and \a ymargin margins (as fractions of visible
+ the area).
+
+ For example:
+ \list
+ \i Margin 0.0 allows (x, y) to be on the edge of the visible area.
+ \i Margin 0.5 ensures that (x, y) is in middle 50% of the visible area.
+ \i Margin 1.0 ensures that (x, y) is in the center of the the visible area.
+ \endlist
+*/
+void TQScrollView::center( int x, int y, float xmargin, float ymargin )
+{
+ int pw=visibleWidth();
+ int ph=visibleHeight();
+ ensureVisible( x, y, int( xmargin/2.0*pw+0.5 ), int( ymargin/2.0*ph+0.5 ) );
+}
+
+
+/*!
+ \fn void TQScrollView::contentsMoving(int x, int y)
+
+ This signal is emitted just before the contents are moved to
+ position \a (x, y).
+
+ \sa contentsX(), contentsY()
+*/
+
+/*!
+ Moves the contents by \a (x, y).
+*/
+void TQScrollView::moveContents(int x, int y)
+{
+ if ( -x+visibleWidth() > d->contentsWidth() )
+#if 0
+ if( TQApplication::reverseLayout() )
+ x=TQMAX(0,-d->contentsWidth()+visibleWidth());
+ else
+#endif
+ x=TQMIN(0,-d->contentsWidth()+visibleWidth());
+ if ( -y+visibleHeight() > contentsHeight() )
+ y=TQMIN(0,-contentsHeight()+visibleHeight());
+
+ int dx = x - d->vx;
+ int dy = y - d->vy;
+
+ if (!dx && !dy)
+ return; // Nothing to do
+
+ emit contentsMoving( -x, -y );
+
+ d->vx = x;
+ d->vy = y;
+
+ if ( d->clipped_viewport || d->static_bg ) {
+ // Cheap move (usually)
+ d->moveAllBy(dx,dy);
+ } else if ( /*dx && dy ||*/
+ ( TQABS(dy) * 5 > visibleHeight() * 4 ) ||
+ ( TQABS(dx) * 5 > visibleWidth() * 4 )
+ )
+ {
+ // Big move
+ if ( viewport()->isUpdatesEnabled() )
+ viewport()->update();
+ d->moveAllBy(dx,dy);
+ } else if ( !d->fake_scroll || d->contentsWidth() > visibleWidth() ) {
+ // Small move
+ clipper()->scroll(dx,dy);
+ }
+ d->hideOrShowAll(this, TRUE );
+}
+
+#if (TQT_VERSION-0 >= 0x040000)
+#if defined(TQ_CC_GNU)
+#warning "Should rename contents{X,Y,Width,Height} to viewport{...}"
+#endif
+// Because it's the viewport rectangle that is "moving", not the contents.
+#endif
+
+/*!
+ \property TQScrollView::contentsX
+ \brief the X coordinate of the contents that are at the left edge of
+ the viewport.
+*/
+int TQScrollView::contentsX() const
+{
+ return d->contentsX();
+}
+
+/*!
+ \property TQScrollView::contentsY
+ \brief the Y coordinate of the contents that are at the top edge of
+ the viewport.
+*/
+int TQScrollView::contentsY() const
+{
+ return d->contentsY();
+}
+
+/*!
+ \property TQScrollView::contentsWidth
+ \brief the width of the contents area
+*/
+int TQScrollView::contentsWidth() const
+{
+ return d->contentsWidth();
+}
+
+/*!
+ \property TQScrollView::contentsHeight
+ \brief the height of the contents area
+*/
+int TQScrollView::contentsHeight() const
+{
+ return d->vheight;
+}
+
+/*!
+ Sets the size of the contents area to \a w pixels wide and \a h
+ pixels high and updates the viewport accordingly.
+*/
+void TQScrollView::resizeContents( int w, int h )
+{
+ int ow = d->vwidth;
+ int oh = d->vheight;
+ d->vwidth = w;
+ d->vheight = h;
+
+ d->scrollbar_timer.start( 0, TRUE );
+
+ if ( d->tqchildren.isEmpty() && d->policy == Default )
+ setResizePolicy( Manual );
+
+ if ( ow > w ) {
+ // Swap
+ int t=w;
+ w=ow;
+ ow=t;
+ }
+ // Refresh area ow..w
+ if ( ow < visibleWidth() && w >= 0 ) {
+ if ( ow < 0 )
+ ow = 0;
+ if ( w > visibleWidth() )
+ w = visibleWidth();
+ clipper()->update( d->contentsX()+ow, 0, w-ow, visibleHeight() );
+ }
+
+ if ( oh > h ) {
+ // Swap
+ int t=h;
+ h=oh;
+ oh=t;
+ }
+ // Refresh area oh..h
+ if ( oh < visibleHeight() && h >= 0 ) {
+ if ( oh < 0 )
+ oh = 0;
+ if ( h > visibleHeight() )
+ h = visibleHeight();
+ clipper()->update( 0, d->contentsY()+oh, visibleWidth(), h-oh);
+ }
+}
+
+/*!
+ Calls update() on a rectangle defined by \a x, \a y, \a w, \a h,
+ translated appropriately. If the rectangle is not visible, nothing
+ is repainted.
+
+ \sa repaintContents()
+*/
+void TQScrollView::updateContents( int x, int y, int w, int h )
+{
+ if ( testWState((TQt::WidgetState)(TQt::WState_Visible|TQt::WState_BlockUpdates)) != TQt::WState_Visible )
+ return;
+
+ TQWidget* vp = viewport();
+
+ // Translate
+ x -= d->contentsX();
+ y -= d->contentsY();
+
+ // Clip to TQCOORD space
+ if ( x < 0 ) {
+ w += x;
+ x = 0;
+ }
+ if ( y < 0 ) {
+ h += y;
+ y = 0;
+ }
+
+ if ( w < 0 || h < 0 )
+ return;
+ if ( x > visibleWidth() || y > visibleHeight() )
+ return;
+
+ if ( w > visibleWidth() )
+ w = visibleWidth();
+ if ( h > visibleHeight() )
+ h = visibleHeight();
+
+ if ( d->clipped_viewport ) {
+ // Translate clipper() to viewport()
+ x -= d->clipped_viewport->x();
+ y -= d->clipped_viewport->y();
+ }
+
+ vp->update( x, y, w, h );
+}
+
+/*!
+ \overload
+
+ Updates the contents in rectangle \a r
+*/
+void TQScrollView::updateContents( const TQRect& r )
+{
+ updateContents(r.x(), r.y(), r.width(), r.height());
+}
+
+/*!
+ \overload
+*/
+void TQScrollView::updateContents()
+{
+ updateContents( d->contentsX(), d->contentsY(), visibleWidth(), visibleHeight() );
+}
+
+/*!
+ \overload
+
+ Repaints the contents of rectangle \a r. If \a erase is TRUE the
+ background is cleared using the background color.
+*/
+void TQScrollView::repaintContents( const TQRect& r, bool erase )
+{
+ repaintContents(r.x(), r.y(), r.width(), r.height(), erase);
+}
+
+
+/*!
+ \overload
+
+ Repaints the contents. If \a erase is TRUE the background is
+ cleared using the background color.
+*/
+void TQScrollView::repaintContents( bool erase )
+{
+ repaintContents( d->contentsX(), d->contentsY(), visibleWidth(), visibleHeight(), erase );
+}
+
+
+/*!
+ Calls tqrepaint() on a rectangle defined by \a x, \a y, \a w, \a h,
+ translated appropriately. If the rectangle is not visible, nothing
+ is repainted. If \a erase is TRUE the background is cleared using
+ the background color.
+
+ \sa updateContents()
+*/
+void TQScrollView::repaintContents( int x, int y, int w, int h, bool erase )
+{
+ if ( testWState((TQt::WidgetState)(TQt::WState_Visible|TQt::WState_BlockUpdates)) != TQt::WState_Visible )
+ return;
+
+ TQWidget* vp = viewport();
+
+ // Translate logical to clipper()
+ x -= d->contentsX();
+ y -= d->contentsY();
+
+ // Clip to TQCOORD space
+ if ( x < 0 ) {
+ w += x;
+ x = 0;
+ }
+ if ( y < 0 ) {
+ h += y;
+ y = 0;
+ }
+
+ if ( w < 0 || h < 0 )
+ return;
+ if ( w > visibleWidth() )
+ w = visibleWidth();
+ if ( h > visibleHeight() )
+ h = visibleHeight();
+
+ if ( d->clipped_viewport ) {
+ // Translate clipper() to viewport()
+ x -= d->clipped_viewport->x();
+ y -= d->clipped_viewport->y();
+ }
+
+ vp->tqrepaint( x, y, w, h, erase );
+}
+
+
+/*!
+ For backward-compatibility only. It is easier to use
+ drawContents(TQPainter*,int,int,int,int).
+
+ The default implementation translates the painter appropriately
+ and calls drawContents(TQPainter*,int,int,int,int). See
+ drawContents() for an explanation of the parameters \a p, \a
+ offsetx, \a offsety, \a clipx, \a clipy, \a clipw and \a cliph.
+*/
+void TQScrollView::drawContentsOffset(TQPainter* p, int offsetx, int offsety, int clipx, int clipy, int clipw, int cliph)
+{
+ p->translate(-offsetx,-offsety);
+ drawContents(p, clipx, clipy, clipw, cliph);
+}
+
+/*!
+ \fn void TQScrollView::drawContents(TQPainter* p, int clipx, int clipy, int clipw, int cliph)
+
+ Reimplement this function if you are viewing a drawing area rather
+ than a widget.
+
+ The function should draw the rectangle (\a clipx, \a clipy, \a
+ clipw, \a cliph) of the contents using painter \a p. The clip
+ rectangle is in the scrollview's coordinates.
+
+ For example:
+ \code
+ {
+ // Fill a 40000 by 50000 rectangle at (100000,150000)
+
+ // Calculate the coordinates...
+ int x1 = 100000, y1 = 150000;
+ int x2 = x1+40000-1, y2 = y1+50000-1;
+
+ // Clip the coordinates so X/Windows will not have problems...
+ if (x1 < clipx) x1=clipx;
+ if (y1 < clipy) y1=clipy;
+ if (x2 > clipx+clipw-1) x2=clipx+clipw-1;
+ if (y2 > clipy+cliph-1) y2=clipy+cliph-1;
+
+ // Paint using the small coordinates...
+ if ( x2 >= x1 && y2 >= y1 )
+ p->fillRect(x1, y1, x2-x1+1, y2-y1+1, red);
+ }
+ \endcode
+
+ The clip rectangle and translation of the painter \a p is already
+ set appropriately.
+*/
+void TQScrollView::drawContents(TQPainter*, int, int, int, int)
+{
+}
+
+
+/*!
+ \reimp
+*/
+void TQScrollView::frameChanged()
+{
+ // slight ugle-hack - the listview header needs readjusting when
+ // changing the frame
+ if (TQListView *lv = ::tqqt_cast<TQListView *>(this))
+ lv->triggerUpdate();
+ TQFrame::frameChanged();
+ updateScrollBars();
+}
+
+
+/*!
+ Returns the viewport widget of the scrollview. This is the widget
+ containing the contents widget or which is the drawing area.
+*/
+TQWidget* TQScrollView::viewport() const
+{
+ if ( d->clipped_viewport )
+ return d->clipped_viewport;
+ return d->viewport;
+}
+
+/*!
+ Returns the clipper widget. Contents in the scrollview are
+ ultimately clipped to be inside the clipper widget.
+
+ You should not need to use this function.
+
+ \sa visibleWidth(), visibleHeight()
+*/
+TQWidget* TQScrollView::clipper() const
+{
+ return d->viewport;
+}
+
+/*!
+ \property TQScrollView::visibleWidth
+ \brief the horizontal amount of the content that is visible
+*/
+int TQScrollView::visibleWidth() const
+{
+ return clipper()->width();
+}
+
+/*!
+ \property TQScrollView::visibleHeight
+ \brief the vertical amount of the content that is visible
+*/
+int TQScrollView::visibleHeight() const
+{
+ return clipper()->height();
+}
+
+
+void TQScrollView::changeFrameRect(const TQRect& r)
+{
+ TQRect oldr = frameRect();
+ if (oldr != r) {
+ TQRect cr = contentsRect();
+ TQRegion fr( frameRect() );
+ fr = fr.subtract( contentsRect() );
+ setFrameRect( r );
+ if ( isVisible() ) {
+ cr = cr.intersect( contentsRect() );
+ fr = fr.unite( frameRect() );
+ fr = fr.subtract( cr );
+ if ( !fr.isEmpty() )
+ TQApplication::postEvent( this, new TQPaintEvent( fr, FALSE ) );
+ }
+ }
+}
+
+
+/*!
+ Sets the margins around the scrolling area to \a left, \a top, \a
+ right and \a bottom. This is useful for applications such as
+ spreadsheets with "locked" rows and columns. The marginal space is
+ \e inside the frameRect() and is left blank; reimplement
+ drawFrame() or put widgets in the unused area.
+
+ By default all margins are zero.
+
+ \sa frameChanged()
+*/
+void TQScrollView::setMargins(int left, int top, int right, int bottom)
+{
+ if ( left == d->l_marg &&
+ top == d->t_marg &&
+ right == d->r_marg &&
+ bottom == d->b_marg )
+ return;
+
+ d->l_marg = left;
+ d->t_marg = top;
+ d->r_marg = right;
+ d->b_marg = bottom;
+ updateScrollBars();
+}
+
+
+/*!
+ Returns the left margin.
+
+ \sa setMargins()
+*/
+int TQScrollView::leftMargin() const
+{
+ return d->l_marg;
+}
+
+
+/*!
+ Returns the top margin.
+
+ \sa setMargins()
+*/
+int TQScrollView::topMargin() const
+{
+ return d->t_marg;
+}
+
+
+/*!
+ Returns the right margin.
+
+ \sa setMargins()
+*/
+int TQScrollView::rightMargin() const
+{
+ return d->r_marg;
+}
+
+
+/*!
+ Returns the bottom margin.
+
+ \sa setMargins()
+*/
+int TQScrollView::bottomMargin() const
+{
+ return d->b_marg;
+}
+
+/*!
+ \reimp
+*/
+bool TQScrollView::focusNextPrevChild( bool next )
+{
+ // Makes sure that the new focus widget is on-screen, if
+ // necessary by scrolling the scroll view.
+
+ // first set things up for the scan
+ TQFocusData *f = focusData();
+ TQWidget *startingPoint = f->home();
+ TQWidget *candidate = 0;
+ TQWidget *w = next ? f->next() : f->prev();
+ TQSVChildRec *r;
+ extern bool qt_tab_all_widgets;
+ uint focus_flag = qt_tab_all_widgets ? Qt::TabFocus : Qt::StrongFocus;
+
+ // then scan for a possible focus widget candidate
+ while( !candidate && w != startingPoint ) {
+ if ( w != startingPoint &&
+ (w->focusPolicy() & focus_flag) == focus_flag
+ && w->isEnabled() &&!w->focusProxy() && w->isVisible() )
+ candidate = w;
+ w = next ? f->next() : f->prev();
+ }
+
+ // if we could not tqfind one, maybe super or parentWidget() can?
+ if ( !candidate )
+ return TQFrame::focusNextPrevChild( next );
+
+ // we've found one.
+ r = d->ancestorRec( candidate );
+ if ( r && ( r->child == candidate ||
+ candidate->isVisibleTo( r->child ) ) ) {
+ TQPoint cp = r->child->mapToGlobal(TQPoint(0,0));
+ TQPoint cr = candidate->mapToGlobal(TQPoint(0,0)) - cp;
+ ensureVisible( r->x+cr.x()+candidate->width()/2,
+ r->y+cr.y()+candidate->height()/2,
+ candidate->width()/2,
+ candidate->height()/2 );
+ }
+
+ candidate->setFocus();
+ return TRUE;
+}
+
+
+
+/*!
+ When a large numbers of child widgets are in a scrollview,
+ especially if they are close together, the scrolling performance
+ can suffer greatly. If \a y is TRUE the scrollview will use an
+ extra widget to group child widgets.
+
+ Note that you may only call enableClipper() prior to adding
+ widgets.
+
+ For a full discussion, see this class's \link #enableclipper
+ detailed description\endlink.
+*/
+void TQScrollView::enableClipper(bool y)
+{
+ if ( !d->clipped_viewport == !y )
+ return;
+ if ( d->tqchildren.count() )
+ qFatal("May only call TQScrollView::enableClipper() before adding widgets");
+ if ( y ) {
+ d->clipped_viewport = new TQClipperWidget(clipper(), "qt_clipped_viewport", (WFlags)d->flags);
+ d->clipped_viewport->setGeometry(-coord_limit/2,-coord_limit/2,
+ coord_limit,coord_limit);
+ d->clipped_viewport->setBackgroundMode( d->viewport->backgroundMode() );
+ d->viewport->setBackgroundMode(TQt::NoBackground); // no exposures for this
+ d->viewport->removeEventFilter( this );
+ d->clipped_viewport->installEventFilter( this );
+ d->clipped_viewport->show();
+ } else {
+ delete d->clipped_viewport;
+ d->clipped_viewport = 0;
+ }
+}
+
+/*!
+ Sets the scrollview to have a static background if \a y is TRUE,
+ or a scrolling background if \a y is FALSE. By default, the
+ background is scrolling.
+
+ Be aware that this mode is quite slow, as a full tqrepaint of the
+ visible area has to be triggered on every contents move.
+
+ \sa hasStaticBackground()
+*/
+void TQScrollView::setStaticBackground(bool y)
+{
+ d->static_bg = y;
+}
+
+/*!
+ Returns TRUE if TQScrollView uses a static background; otherwise
+ returns FALSE.
+
+ \sa setStaticBackground()
+*/
+bool TQScrollView::hasStaticBackground() const
+{
+ return d->static_bg;
+}
+
+/*!
+ \overload
+
+ Returns the point \a p translated to a point on the viewport()
+ widget.
+*/
+TQPoint TQScrollView::contentsToViewport( const TQPoint& p ) const
+{
+ if ( d->clipped_viewport ) {
+ return TQPoint( p.x() - d->contentsX() - d->clipped_viewport->x(),
+ p.y() - d->contentsY() - d->clipped_viewport->y() );
+ } else {
+ return TQPoint( p.x() - d->contentsX(),
+ p.y() - d->contentsY() );
+ }
+}
+
+/*!
+ \overload
+
+ Returns the point on the viewport \a vp translated to a point in
+ the contents.
+*/
+TQPoint TQScrollView::viewportToContents( const TQPoint& vp ) const
+{
+ if ( d->clipped_viewport ) {
+ return TQPoint( vp.x() + d->contentsX() + d->clipped_viewport->x(),
+ vp.y() + d->contentsY() + d->clipped_viewport->y() );
+ } else {
+ return TQPoint( vp.x() + d->contentsX(),
+ vp.y() + d->contentsY() );
+ }
+}
+
+
+/*!
+ Translates a point (\a x, \a y) in the contents to a point (\a vx,
+ \a vy) on the viewport() widget.
+*/
+void TQScrollView::contentsToViewport( int x, int y, int& vx, int& vy ) const
+{
+ const TQPoint v = contentsToViewport(TQPoint(x,y));
+ vx = v.x();
+ vy = v.y();
+}
+
+/*!
+ Translates a point (\a vx, \a vy) on the viewport() widget to a
+ point (\a x, \a y) in the contents.
+*/
+void TQScrollView::viewportToContents( int vx, int vy, int& x, int& y ) const
+{
+ const TQPoint c = viewportToContents(TQPoint(vx,vy));
+ x = c.x();
+ y = c.y();
+}
+
+/*!
+ \reimp
+*/
+TQSize TQScrollView::tqsizeHint() const
+{
+ if ( d->use_cached_size_hint && d->cachedSizeHint.isValid() )
+ return d->cachedSizeHint;
+
+ constPolish();
+ int f = 2 * frameWidth();
+ int h = fontMetrics().height();
+ TQSize sz( f, f );
+ if ( d->policy > Manual ) {
+ TQSVChildRec *r = d->tqchildren.first();
+ if ( r ) {
+ TQSize cs = r->child->tqsizeHint();
+ if ( cs.isValid() )
+ sz += cs.boundedTo( r->child->tqmaximumSize() );
+ else
+ sz += r->child->size();
+ }
+ } else {
+ sz += TQSize( d->contentsWidth(), contentsHeight() );
+ }
+ if (d->vMode == AlwaysOn)
+ sz.setWidth(sz.width() + d->vbar->tqsizeHint().width());
+ if (d->hMode == AlwaysOn)
+ sz.setHeight(sz.height() + d->hbar->tqsizeHint().height());
+ return sz.expandedTo( TQSize(12 * h, 8 * h) )
+ .boundedTo( TQSize(36 * h, 24 * h) );
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQScrollView::tqminimumSizeHint() const
+{
+ int h = fontMetrics().height();
+ if ( h < 10 )
+ h = 10;
+ int f = 2 * frameWidth();
+ return TQSize( (6 * h) + f, (4 * h) + f );
+}
+
+
+/*!
+ \reimp
+
+ (Implemented to get rid of a compiler warning.)
+*/
+void TQScrollView::drawContents( TQPainter * )
+{
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ \internal
+*/
+void TQScrollView::startDragAutoScroll()
+{
+ if ( !d->autoscroll_timer.isActive() ) {
+ d->autoscroll_time = initialScrollTime;
+ d->autoscroll_accel = initialScrollAccel;
+ d->autoscroll_timer.start( d->autoscroll_time );
+ }
+}
+
+
+/*!
+ \internal
+*/
+void TQScrollView::stopDragAutoScroll()
+{
+ d->autoscroll_timer.stop();
+}
+
+
+/*!
+ \internal
+*/
+void TQScrollView::doDragAutoScroll()
+{
+ TQPoint p = d->viewport->mapFromGlobal( TQCursor::pos() );
+
+ if ( d->autoscroll_accel-- <= 0 && d->autoscroll_time ) {
+ d->autoscroll_accel = initialScrollAccel;
+ d->autoscroll_time--;
+ d->autoscroll_timer.start( d->autoscroll_time );
+ }
+ int l = TQMAX( 1, ( initialScrollTime- d->autoscroll_time ) );
+
+ int dx = 0, dy = 0;
+ if ( p.y() < autoscroll_margin ) {
+ dy = -l;
+ } else if ( p.y() > visibleHeight() - autoscroll_margin ) {
+ dy = +l;
+ }
+ if ( p.x() < autoscroll_margin ) {
+ dx = -l;
+ } else if ( p.x() > visibleWidth() - autoscroll_margin ) {
+ dx = +l;
+ }
+ if ( dx || dy ) {
+ scrollBy(dx,dy);
+ } else {
+ stopDragAutoScroll();
+ }
+}
+
+
+/*!
+ \property TQScrollView::dragAutoScroll
+ \brief whether autoscrolling in drag move events is enabled
+
+ If this property is set to TRUE (the default), the TQScrollView
+ automatically scrolls the contents in drag move events if the user
+ moves the cursor close to a border of the view. Of course this
+ works only if the viewport accepts drops. Specifying FALSE
+ disables this autoscroll feature.
+
+ \warning Enabling this property might not be enough to
+ effectively turn on autoscrolling. If you put a custom widget in
+ the TQScrollView, you might need to call TQDragEvent::ignore() on
+ the event in the dragEnterEvent() and dragMoveEvent()
+ reimplementations.
+*/
+
+void TQScrollView::setDragAutoScroll( bool b )
+{
+ d->drag_autoscroll = b;
+}
+
+bool TQScrollView::dragAutoScroll() const
+{
+ return d->drag_autoscroll;
+}
+
+#endif // TQT_NO_DRAGANDDROP
+
+/*!\internal
+ */
+void TQScrollView::setCachedSizeHint( const TQSize &sh ) const
+{
+ if ( isVisible() && !d->cachedSizeHint.isValid() )
+ d->cachedSizeHint = sh;
+}
+
+/*!\internal
+ */
+void TQScrollView::disableSizeHintCaching()
+{
+ d->use_cached_size_hint = FALSE;
+}
+
+/*!\internal
+ */
+TQSize TQScrollView::cachedSizeHint() const
+{
+ return d->use_cached_size_hint ? d->cachedSizeHint : TQSize();
+}
+
+#endif // TQT_NO_SCROLLVIEW
diff --git a/tqtinterface/qt4/src/widgets/tqscrollview.h b/tqtinterface/qt4/src/widgets/tqscrollview.h
new file mode 100644
index 0000000..caa86bb
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqscrollview.h
@@ -0,0 +1,270 @@
+/****************************************************************************
+**
+** Definition of TQScrollView class
+**
+** Created : 970523
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+#ifndef TQSCROLLVIEW_H
+#define TQSCROLLVIEW_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#include "tqscrollbar.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SCROLLVIEW
+
+class TQScrollViewData;
+
+class TQ_EXPORT TQScrollView : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( ResizePolicy ScrollBarMode )
+ Q_PROPERTY( ResizePolicy resizePolicy READ resizePolicy WRITE setResizePolicy )
+ Q_PROPERTY( ScrollBarMode vScrollBarMode READ vScrollBarMode WRITE setVScrollBarMode )
+ Q_PROPERTY( ScrollBarMode hScrollBarMode READ hScrollBarMode WRITE setHScrollBarMode )
+ Q_PROPERTY( int visibleWidth READ visibleWidth )
+ Q_PROPERTY( int visibleHeight READ visibleHeight )
+ Q_PROPERTY( int contentsWidth READ contentsWidth )
+ Q_PROPERTY( int contentsHeight READ contentsHeight )
+ Q_PROPERTY( int contentsX READ contentsX )
+ Q_PROPERTY( int contentsY READ contentsY )
+#ifndef TQT_NO_DRAGANDDROP
+ Q_PROPERTY( bool dragAutoScroll READ dragAutoScroll WRITE setDragAutoScroll )
+#endif
+
+public:
+ TQScrollView(TQWidget* tqparent=0, const char* name=0, WFlags f=0);
+ ~TQScrollView();
+
+ enum ResizePolicy { Default, Manual, AutoOne, AutoOneFit };
+ virtual void setResizePolicy( ResizePolicy );
+ ResizePolicy resizePolicy() const;
+
+ void styleChange( TQStyle & );
+ void removeChild(TQWidget* child);
+ virtual void addChild( TQWidget* child, int x=0, int y=0 );
+ virtual void moveChild( TQWidget* child, int x, int y );
+ int childX(TQWidget* child);
+ int childY(TQWidget* child);
+ bool childIsVisible(TQWidget* child) { return child->isVisible(); } // obsolete functions
+ void showChild(TQWidget* child, bool yes=TRUE) {
+ if ( yes )
+ child->show();
+ else
+ child->hide();
+ }
+
+ enum ScrollBarMode { Auto, AlwaysOff, AlwaysOn };
+
+ ScrollBarMode vScrollBarMode() const;
+ virtual void setVScrollBarMode( ScrollBarMode );
+
+ ScrollBarMode hScrollBarMode() const;
+ virtual void setHScrollBarMode( ScrollBarMode );
+
+ TQWidget* cornerWidget() const;
+ virtual void setCornerWidget(TQWidget*);
+
+ // ### 4.0: Consider providing a factory function for scrollbars
+ // (e.g. make the two following functions virtual)
+ TQScrollBar* horizontalScrollBar() const;
+ TQScrollBar* verticalScrollBar() const;
+ TQWidget* viewport() const;
+ TQWidget* clipper() const;
+
+ int visibleWidth() const;
+ int visibleHeight() const;
+
+ int contentsWidth() const;
+ int contentsHeight() const;
+ int contentsX() const;
+ int contentsY() const;
+
+ void resize( int w, int h );
+ void resize( const TQSize& );
+ void show();
+
+ void updateContents( int x, int y, int w, int h );
+ void updateContents( const TQRect& r );
+ void updateContents();
+ void repaintContents( int x, int y, int w, int h, bool erase=TRUE );
+ void repaintContents( const TQRect& r, bool erase=TRUE );
+ void repaintContents( bool erase=TRUE );
+ void contentsToViewport( int x, int y, int& vx, int& vy ) const;
+ void viewportToContents( int vx, int vy, int& x, int& y ) const;
+ TQPoint contentsToViewport( const TQPoint& ) const;
+ TQPoint viewportToContents( const TQPoint& ) const;
+ void enableClipper( bool y );
+
+ void setStaticBackground( bool y );
+ bool hasStaticBackground() const;
+
+ TQSize viewportSize( int, int ) const;
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ void removeChild(TQObject* child);
+
+ bool isHorizontalSliderPressed();
+ bool isVerticalSliderPressed();
+
+#ifndef TQT_NO_DRAGANDDROP
+ virtual void setDragAutoScroll( bool b );
+ bool dragAutoScroll() const;
+#endif
+
+Q_SIGNALS:
+ void contentsMoving(int x, int y);
+ void horizontalSliderPressed();
+ void horizontalSliderReleased();
+ void verticalSliderPressed();
+ void verticalSliderReleased();
+
+public Q_SLOTS:
+ virtual void resizeContents( int w, int h );
+ void scrollBy( int dx, int dy );
+ virtual void setContentsPos( int x, int y );
+ void ensureVisible(int x, int y);
+ void ensureVisible(int x, int y, int xmargin, int ymargin);
+ void center(int x, int y);
+ void center(int x, int y, float xmargin, float ymargin);
+
+ void updateScrollBars(); // ### virtual in 4.0
+ void setEnabled( bool enable );
+
+protected:
+ virtual void drawContents(TQPainter*, int cx, int cy, int cw, int ch);
+ virtual void drawContentsOffset(TQPainter*, int ox, int oy,
+ int cx, int cy, int cw, int ch);
+
+
+ virtual void contentsMousePressEvent( TQMouseEvent* );
+ virtual void contentsMouseReleaseEvent( TQMouseEvent* );
+ virtual void contentsMouseDoubleClickEvent( TQMouseEvent* );
+ virtual void contentsMouseMoveEvent( TQMouseEvent* );
+#ifndef TQT_NO_DRAGANDDROP
+ virtual void contentsDragEnterEvent( TQDragEnterEvent * );
+ virtual void contentsDragMoveEvent( TQDragMoveEvent * );
+ virtual void contentsDragLeaveEvent( TQDragLeaveEvent * );
+ virtual void contentsDropEvent( TQDropEvent * );
+#endif
+#ifndef TQT_NO_WHEELEVENT
+ virtual void contentsWheelEvent( TQWheelEvent * );
+#endif
+ virtual void contentsContextMenuEvent( TQContextMenuEvent * );
+
+
+ virtual void viewportPaintEvent( TQPaintEvent* );
+ virtual void viewportResizeEvent( TQResizeEvent* );
+ virtual void viewportMousePressEvent( TQMouseEvent* );
+ virtual void viewportMouseReleaseEvent( TQMouseEvent* );
+ virtual void viewportMouseDoubleClickEvent( TQMouseEvent* );
+ virtual void viewportMouseMoveEvent( TQMouseEvent* );
+#ifndef TQT_NO_DRAGANDDROP
+ virtual void viewportDragEnterEvent( TQDragEnterEvent * );
+ virtual void viewportDragMoveEvent( TQDragMoveEvent * );
+ virtual void viewportDragLeaveEvent( TQDragLeaveEvent * );
+ virtual void viewportDropEvent( TQDropEvent * );
+#endif
+#ifndef TQT_NO_WHEELEVENT
+ virtual void viewportWheelEvent( TQWheelEvent * );
+#endif
+ virtual void viewportContextMenuEvent( TQContextMenuEvent * );
+
+ void frameChanged();
+
+ virtual void setMargins(int left, int top, int right, int bottom);
+ int leftMargin() const;
+ int topMargin() const;
+ int rightMargin() const;
+ int bottomMargin() const;
+
+ bool focusNextPrevChild( bool next );
+
+ virtual void setHBarGeometry(TQScrollBar& hbar, int x, int y, int w, int h);
+ virtual void setVBarGeometry(TQScrollBar& vbar, int x, int y, int w, int h);
+
+ virtual void resizeEvent(TQResizeEvent*);
+ virtual void mousePressEvent( TQMouseEvent * );
+ virtual void mouseReleaseEvent( TQMouseEvent * );
+ virtual void mouseDoubleClickEvent( TQMouseEvent * );
+ virtual void mouseMoveEvent( TQMouseEvent * );
+#ifndef TQT_NO_WHEELEVENT
+ virtual void wheelEvent( TQWheelEvent * );
+#endif
+ virtual void contextMenuEvent( TQContextMenuEvent * );
+ virtual bool eventFilter( TQObject *, TQEvent *e );
+
+ void setCachedSizeHint( const TQSize &sh ) const;
+ TQSize cachedSizeHint() const;
+ void fontChange( const TQFont & );
+
+private:
+ void drawContents( TQPainter* );
+ void moveContents(int x, int y);
+
+ TQScrollViewData* d;
+
+private Q_SLOTS:
+ void hslide(int);
+ void vslide(int);
+ void hbarIsPressed();
+ void hbarIsReleased();
+ void vbarIsPressed();
+ void vbarIsReleased();
+#ifndef TQT_NO_DRAGANDDROP
+ void doDragAutoScroll();
+ void startDragAutoScroll();
+ void stopDragAutoScroll();
+#endif
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQScrollView( const TQScrollView & );
+ TQScrollView &operator=( const TQScrollView & );
+#endif
+ void changeFrameRect(const TQRect&);
+
+public:
+ void disableSizeHintCaching();
+
+};
+
+#endif // TQT_NO_SCROLLVIEW
+
+#endif // TQSCROLLVIEW_H
diff --git a/tqtinterface/qt4/src/widgets/tqslider.cpp b/tqtinterface/qt4/src/widgets/tqslider.cpp
new file mode 100644
index 0000000..9d3ece2
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqslider.cpp
@@ -0,0 +1,921 @@
+/****************************************************************************
+**
+** Implementation of TQSlider class
+**
+** Created : 961019
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqslider.h"
+#ifndef TQT_NO_SLIDER
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqtimer.h"
+#include "tqbitmap.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+static const int thresholdTime = 300;
+static const int repeatTime = 100;
+
+struct TQSliderPrivate
+{
+ // ### move these to TQSlider in TQt 4.0
+ int sliderStartVal;
+ TQSliderPrivate() : sliderStartVal( 0 ) { }
+};
+
+
+/*!
+ \class TQSlider
+ \brief The TQSlider widget provides a vertical or horizontal slider.
+
+ \ingroup basic
+ \mainclass
+
+ The slider is the classic widget for controlling a bounded value.
+ It lets the user move a slider along a horizontal or vertical
+ groove and translates the slider's position into an integer value
+ within the legal range.
+
+ TQSlider inherits TQRangeControl, which provides the "integer" side
+ of the slider. setRange() and value() are likely to be used by
+ practically all slider users; see the \l TQRangeControl
+ documentation for information about the many other functions that
+ class provides.
+
+ The main functions offered by the slider itself are tickmark and
+ orientation control; you can use setTickmarks() to indicate where
+ you want the tickmarks to be, setTickInterval() to indicate how
+ many of them you want and setOrientation() to indicate whether the
+ slider is to be horizontal or vertical.
+
+ A slider accepts focus on Tab and uses the mouse wheel and a
+ suitable keyboard interface.
+
+ <img src=qslider-m.png> <img src=qslider-w.png>
+
+ \important setRange
+
+ \sa TQScrollBar TQSpinBox
+ \link guibooks.html#fowler GUI Design Handbook: Slider\endlink
+*/
+
+
+/*!
+ \enum TQSlider::TickSetting
+
+ This enum specifies where the tickmarks are to be drawn relative
+ to the slider's groove and the handle the user moves.
+
+ \value NoMarks do not draw any tickmarks.
+ \value Both draw tickmarks on both sides of the groove.
+ \value Above draw tickmarks above the (horizontal) slider
+ \value Below draw tickmarks below the (horizontal) slider
+ \value Left draw tickmarks to the left of the (vertical) slider
+ \value Right draw tickmarks to the right of the (vertical) slider
+*/
+
+
+/*!
+ Constructs a vertical slider.
+
+ The \a tqparent and \a name arguments are sent on to the TQWidget
+ constructor.
+*/
+
+TQSlider::TQSlider( TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name )
+{
+ orient = Qt::Vertical;
+ init();
+}
+
+/*!
+ Constructs a slider.
+
+ The \a orientation must be \l Qt::Vertical or \l Qt::Horizontal.
+
+ The \a tqparent and \a name arguments are sent on to the TQWidget
+ constructor.
+*/
+
+TQSlider::TQSlider( Qt::Orientation orientation, TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name )
+{
+ orient = orientation;
+ init();
+}
+
+/*!
+ Constructs a slider whose value can never be smaller than \a
+ minValue or greater than \a maxValue, whose page step size is \a
+ pageStep and whose value is initially \a value (which is
+ guaranteed to be in range using bound()).
+
+ If \a orientation is \c Qt::Vertical the slider is vertical and if it
+ is \c Qt::Horizontal the slider is horizontal.
+
+ The \a tqparent and \a name arguments are sent on to the TQWidget
+ constructor.
+*/
+
+TQSlider::TQSlider( int minValue, int maxValue, int pageStep,
+ int value, Qt::Orientation orientation,
+ TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name ),
+ TQRangeControl( minValue, maxValue, 1, pageStep, value )
+{
+ orient = orientation;
+ init();
+ sliderVal = value;
+}
+
+/*!
+ Destructor.
+*/
+TQSlider::~TQSlider()
+{
+ delete d;
+}
+
+void TQSlider::init()
+{
+ d = new TQSliderPrivate;
+ timer = 0;
+ sliderPos = 0;
+ sliderVal = 0;
+ clickOffset = 0;
+ state = Idle;
+ track = TRUE;
+ ticks = NoMarks;
+ tickInt = 0;
+ setFocusPolicy( Qt::TabFocus );
+ initTicks();
+
+ TQSizePolicy sp( TQSizePolicy::Expanding, TQSizePolicy::Fixed );
+ if ( orient == Qt::Vertical )
+ sp.transpose();
+ tqsetSizePolicy( sp );
+ clearWState( TQt::WState_OwnSizePolicy );
+}
+
+
+/*
+ Does what's needed when someone changes the tickmark status.
+*/
+
+void TQSlider::initTicks()
+{
+ tickOffset = tqstyle().tqpixelMetric( TQStyle::PM_SliderTickmarkOffset, this );
+}
+
+
+/*!
+ \property TQSlider::tracking
+ \brief whether slider tracking is enabled
+
+ If tracking is enabled (the default), the slider emits the
+ valueChanged() signal whenever the slider is being dragged. If
+ tracking is disabled, the slider emits the valueChanged() signal
+ when the user releases the mouse button (unless the value happens
+ to be the same as before).
+*/
+
+void TQSlider::setTracking( bool enable )
+{
+ track = enable;
+}
+
+
+/*!
+ \fn void TQSlider::valueChanged( int value )
+
+ This signal is emitted when the slider value is changed, with the
+ new slider \a value as its argument.
+*/
+
+/*!
+ \fn void TQSlider::sliderPressed()
+
+ This signal is emitted when the user presses the slider with the
+ mouse.
+*/
+
+/*!
+ \fn void TQSlider::sliderMoved( int value )
+
+ This signal is emitted when the slider is dragged, with the new
+ slider \a value as its argument.
+*/
+
+/*!
+ \fn void TQSlider::sliderReleased()
+
+ This signal is emitted when the user releases the slider with the mouse.
+*/
+
+/*
+ Calculates slider position corresponding to value \a v.
+*/
+
+int TQSlider::positionFromValue( int v ) const
+{
+ int a = available();
+ int x = TQRangeControl::positionFromValue( v, a );
+ if ( orient == Qt::Horizontal && TQApplication::reverseLayout() )
+ x = a - x;
+ return x;
+}
+
+/*
+ Returns the available space in which the slider can move.
+*/
+
+int TQSlider::available() const
+{
+ return tqstyle().tqpixelMetric( TQStyle::PM_SliderSpaceAvailable, this );
+}
+
+/*
+ Calculates a value corresponding to slider position \a p.
+*/
+
+int TQSlider::valueFromPosition( int p ) const
+{
+ int a = available();
+ int x = TQRangeControl::valueFromPosition( p, a );
+ if ( orient == Qt::Horizontal && TQApplication::reverseLayout() )
+ x = maxValue() + minValue() - x;
+ return x;
+}
+
+/*!
+ Implements the virtual TQRangeControl function.
+*/
+
+void TQSlider::rangeChange()
+{
+ int newPos = positionFromValue( value() );
+ if ( newPos != sliderPos ) {
+ reallyMoveSlider( newPos );
+ }
+}
+
+/*!
+ Implements the virtual TQRangeControl function.
+*/
+
+void TQSlider::valueChange()
+{
+ if ( sliderVal != value() ) {
+ int newPos = positionFromValue( value() );
+ sliderVal = value();
+ reallyMoveSlider( newPos );
+ }
+ emit valueChanged(value());
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+}
+
+
+/*!
+ \reimp
+*/
+void TQSlider::resizeEvent( TQResizeEvent * )
+{
+ rangeChange();
+ initTicks();
+}
+
+
+/*!
+ Reimplements the virtual function TQWidget::setPalette().
+
+ Sets the background color to the mid color for Motif style sliders
+ using palette \a p.
+*/
+
+void TQSlider::setPalette( const TQPalette &p )
+{
+ TQWidget::setPalette( p );
+}
+
+
+
+/*!
+ \property TQSlider::orientation
+ \brief the slider's orientation
+
+ The orientation must be \l Qt::Vertical (the default) or \l
+ Qt::Horizontal.
+*/
+
+void TQSlider::setOrientation( Qt::Orientation orientation )
+{
+ if ( orientation == orient )
+ return;
+
+ if ( !testWState( TQt::WState_OwnSizePolicy ) ) {
+ TQSizePolicy sp = sizePolicy();
+ sp.transpose();
+ tqsetSizePolicy( sp );
+ clearWState( TQt::WState_OwnSizePolicy );
+ }
+
+ orient = orientation;
+
+ rangeChange();
+ update();
+}
+
+/*!
+ \fn int TQSlider::sliderStart() const
+
+ Returns the start position of the slider.
+*/
+
+
+/*!
+ Returns the slider handle rectangle. (This is the visual marker
+ that the user can move.)
+*/
+
+TQRect TQSlider::sliderRect() const
+{
+ return tqstyle().querySubControlMetrics( TQStyle::CC_Slider, this,
+ TQStyle::SC_SliderHandle );
+}
+
+/*
+ Performs the actual moving of the slider.
+*/
+
+void TQSlider::reallyMoveSlider( int newPos )
+{
+ TQRegion oldR(sliderRect());
+ sliderPos = newPos;
+ TQRegion newR(sliderRect());
+
+ /* just the one tqrepaint if no background */
+ if (backgroundMode() == TQt::NoBackground)
+ tqrepaint(newR | oldR, FALSE);
+ else {
+ tqrepaint(oldR.subtract(newR));
+ tqrepaint(newR, FALSE);
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQSlider::paintEvent( TQPaintEvent * )
+{
+ TQPainter p( this );
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+
+ TQStyle::SCFlags sub = TQStyle::SC_SliderGroove | TQStyle::SC_SliderHandle;
+ if ( tickmarks() != NoMarks )
+ sub |= TQStyle::SC_SliderTickmarks;
+
+ tqstyle().tqdrawComplexControl( TQStyle::CC_Slider, &p, this, rect(), tqcolorGroup(),
+ flags, sub, state == Dragging ? TQStyle::SC_SliderHandle : TQStyle::SC_None );
+}
+
+
+/*!
+ \reimp
+*/
+void TQSlider::mousePressEvent( TQMouseEvent *e )
+{
+ int slideLength = tqstyle().tqpixelMetric( TQStyle::PM_SliderLength, this );
+ resetState();
+ d->sliderStartVal = sliderVal;
+ TQRect r = sliderRect();
+
+ if ( e->button() == Qt::RightButton )
+ return;
+
+ if ( r.tqcontains( e->pos() ) ) {
+ state = Dragging;
+ clickOffset = (TQCOORD)( goodPart( e->pos() ) - sliderPos );
+ emit sliderPressed();
+ } else if ( e->button() == Qt::MidButton ) {
+ int pos = goodPart( e->pos() );
+ moveSlider( pos - slideLength / 2 );
+ state = Dragging;
+ clickOffset = slideLength / 2;
+ } else if ( (orient == Qt::Horizontal && e->pos().x() < r.left()) //### goodPart
+ || (orient == Qt::Vertical && e->pos().y() < r.top()) ) {
+ if ( orient == Qt::Horizontal && TQApplication::reverseLayout() ) {
+ state = TimingUp;
+ addPage();
+ } else {
+ state = TimingDown;
+ subtractPage();
+ }
+ if ( !timer )
+ timer = new TQTimer( this );
+ connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(repeatTimeout()) );
+ timer->start( thresholdTime, TRUE );
+ } else if ( (orient == Qt::Horizontal && e->pos().x() > r.right()) //### goodPart
+ || (orient == Qt::Vertical && e->pos().y() > r.bottom()) ) {
+ if ( orient == Qt::Horizontal && TQApplication::reverseLayout() ) {
+ state = TimingDown;
+ subtractPage();
+ } else {
+ state = TimingUp;
+ addPage();
+ }
+ if ( !timer )
+ timer = new TQTimer( this );
+ connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(repeatTimeout()) );
+ timer->start( thresholdTime, TRUE );
+ }
+ update( sliderRect() );
+}
+
+/*!
+ \reimp
+*/
+void TQSlider::mouseMoveEvent( TQMouseEvent *e )
+{
+ if ( state != Dragging )
+ return;
+
+ TQRect r = rect();
+ int m = tqstyle().tqpixelMetric( TQStyle::PM_MaximumDragDistance,
+ this );
+ if ( m >= 0 ) {
+ if ( orientation() == Qt::Horizontal )
+ r.setRect( r.x() - m, r.y() - 2*m/3,
+ r.width() + 2*m, r.height() + 3*m );
+ else
+ r.setRect( r.x() - 2*m/3, r.y() - m,
+ r.width() + 3*m, r.height() + 2*m );
+ if ( !r.tqcontains( e->pos() ) ) {
+ moveSlider( positionFromValue(d->sliderStartVal) );
+ return;
+ }
+ }
+
+ int pos = goodPart( e->pos() );
+ moveSlider( pos - clickOffset );
+}
+
+/*!
+ \reimp
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQSlider::wheelEvent( TQWheelEvent * e )
+{
+ if ( e->orientation() != orientation() && !TQT_TQRECT_OBJECT(rect()).tqcontains(e->pos()) )
+ return;
+
+ static float offset = 0;
+ static TQSlider* offset_owner = 0;
+ if (offset_owner != this){
+ offset_owner = this;
+ offset = 0;
+ }
+ offset += -e->delta()*TQMAX(pageStep(),lineStep())/120;
+ if (TQABS(offset)<1)
+ return;
+ setValue( value() + int(offset) );
+ offset -= int(offset);
+ e->accept();
+}
+#endif
+
+/*!
+ \reimp
+*/
+void TQSlider::mouseReleaseEvent( TQMouseEvent * )
+{
+ resetState();
+ update( sliderRect() );
+}
+
+/*!
+ \reimp
+*/
+void TQSlider::focusInEvent( TQFocusEvent * e)
+{
+ TQWidget::focusInEvent( e );
+}
+
+/*!
+ \reimp
+*/
+void TQSlider::focusOutEvent( TQFocusEvent * e )
+{
+ TQWidget::focusOutEvent( e );
+}
+
+/*!
+ Moves the left (or top) edge of the slider to position \a pos. The
+ slider is actually moved to the step position nearest the given \a
+ pos.
+*/
+
+void TQSlider::moveSlider( int pos )
+{
+ int a = available();
+ int newPos = TQMIN( a, TQMAX( 0, pos ) );
+ int newVal = valueFromPosition( newPos );
+ if (tqstyle().tqstyleHint(TQStyle::SH_Slider_SnapToValue, this))
+ newPos = positionFromValue( newVal );
+ if ( sliderPos != newPos )
+ reallyMoveSlider( newPos );
+ if ( sliderVal != newVal ) {
+ sliderVal = newVal;
+ emit sliderMoved( sliderVal );
+ }
+ if ( tracking() && sliderVal != value() )
+ setValue( sliderVal );
+
+}
+
+
+/*
+ Resets all state information and stops the timer.
+*/
+
+void TQSlider::resetState()
+{
+ if ( timer ) {
+ timer->stop();
+ timer->disconnect();
+ }
+ switch ( state ) {
+ case TimingUp:
+ case TimingDown:
+ break;
+ case Dragging: {
+ setValue( valueFromPosition( sliderPos ) );
+ emit sliderReleased();
+ break;
+ }
+ case Idle:
+ break;
+ default:
+ qWarning("TQSlider: (%s) in wrong state", name( "unnamed" ) );
+ }
+ state = Idle;
+}
+
+
+/*!
+ \reimp
+*/
+void TQSlider::keyPressEvent( TQKeyEvent *e )
+{
+ bool sloppy = bool(tqstyle().tqstyleHint(TQStyle::SH_Slider_SloppyKeyEvents, this));
+ switch ( e->key() ) {
+ case Qt::Key_Left:
+ if ( sloppy || orient == Qt::Horizontal ) {
+ if (TQApplication::reverseLayout())
+ addLine();
+ else
+ subtractLine();
+ }
+ break;
+ case Qt::Key_Right:
+ if ( sloppy || orient == Qt::Horizontal ) {
+ if (TQApplication::reverseLayout())
+ subtractLine();
+ else
+ addLine();
+ }
+ break;
+ case Qt::Key_Up:
+ if ( sloppy || orient == Qt::Vertical )
+ subtractLine();
+ break;
+ case Qt::Key_Down:
+ if ( sloppy || orient == Qt::Vertical )
+ addLine();
+ break;
+ case TQt::Key_Prior:
+ subtractPage();
+ break;
+ case TQt::Key_Next:
+ addPage();
+ break;
+ case Qt::Key_Home:
+ setValue( minValue() );
+ break;
+ case Qt::Key_End:
+ setValue( maxValue() );
+ break;
+ default:
+ e->ignore();
+ return;
+ }
+}
+
+void TQSlider::setValue( int value )
+{
+ TQRangeControl::setValue( value );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+}
+
+
+/*! \reimp
+*/
+
+void TQSlider::addLine()
+{
+ TQRangeControl::addLine();
+}
+
+/*! \reimp
+*/
+
+void TQSlider::subtractLine()
+{
+ TQRangeControl::subtractLine();
+}
+
+/*!
+ Moves the slider one pageStep() up or right.
+*/
+
+void TQSlider::addStep()
+{
+ addPage();
+}
+
+
+/*!
+ Moves the slider one pageStep() down or left.
+*/
+
+void TQSlider::subtractStep()
+{
+ subtractPage();
+}
+
+
+/*
+ Waits for autorepeat.
+*/
+
+void TQSlider::repeatTimeout()
+{
+ TQ_ASSERT( timer );
+ timer->disconnect();
+ if ( state == TimingDown )
+ connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(subtractStep()) );
+ else if ( state == TimingUp )
+ connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(addStep()) );
+ timer->start( repeatTime, FALSE );
+}
+
+
+/*
+ Returns the relevant dimension of \a p.
+*/
+
+int TQSlider::goodPart( const TQPoint &p ) const
+{
+ return (orient == Qt::Horizontal) ? p.x() : p.y();
+}
+
+/*!
+ \reimp
+*/
+TQSize TQSlider::tqsizeHint() const
+{
+ constPolish();
+ const int length = 84, tickSpace = 5;
+ int thick = tqstyle().tqpixelMetric( TQStyle::PM_SliderThickness, this );
+ if ( ticks & Above )
+ thick += tickSpace;
+ if ( ticks & Below )
+ thick += tickSpace;
+ int w = thick, h = length;
+ if ( orient == Qt::Horizontal ) {
+ w = length;
+ h = thick;
+ }
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_Slider, this,
+ TQSize(w, h)).expandedTo(TQApplication::globalStrut()));
+}
+
+
+
+/*!
+ \reimp
+*/
+
+TQSize TQSlider::tqminimumSizeHint() const
+{
+ TQSize s = tqsizeHint();
+ int length = tqstyle().tqpixelMetric(TQStyle::PM_SliderLength, this);
+ if ( orient == Qt::Horizontal )
+ s.setWidth( length );
+ else
+ s.setHeight( length );
+
+ return s;
+}
+
+/*! \fn void TQSlider::tqsetSizePolicy( TQSizePolicy::SizeType, TQSizePolicy::SizeType, bool )
+ \reimp
+*/
+
+/*! \reimp */
+void TQSlider::tqsetSizePolicy( TQSizePolicy sp )
+{
+ // ## remove 4.0
+ TQWidget::tqsetSizePolicy( sp );
+}
+
+/*! \reimp */
+TQSizePolicy TQSlider::sizePolicy() const
+{
+ // ### 4.0 remove this reimplementation
+ return TQWidget::tqsizePolicy();
+}
+
+/*!
+ \property TQSlider::tickmarks
+ \brief the tickmark settings for this slider
+
+ The valid values are in \l{TQSlider::TickSetting}. The default is
+ \c NoMarks.
+
+ \sa tickInterval
+*/
+
+void TQSlider::setTickmarks( TickSetting s )
+{
+ ticks = s;
+ initTicks();
+ update();
+}
+
+
+/*!
+ \property TQSlider::tickInterval
+ \brief the interval between tickmarks
+
+ This is a value interval, not a pixel interval. If it is 0, the
+ slider will choose between lineStep() and pageStep(). The initial
+ value of tickInterval is 0.
+
+ \sa TQRangeControl::lineStep(), TQRangeControl::pageStep()
+*/
+
+void TQSlider::setTickInterval( int i )
+{
+ tickInt = TQMAX( 0, i );
+ update();
+}
+
+
+/*!
+ \reimp
+*/
+void TQSlider::styleChange( TQStyle& old )
+{
+ TQWidget::styleChange( old );
+}
+
+/*!
+ \property TQSlider::minValue
+ \brief the current minimum value of the slider
+
+ When setting this property, the \l TQSlider::maxValue is adjusted,
+ if necessary, to ensure that the range remains valid.
+
+ \sa setRange()
+*/
+int TQSlider::minValue() const
+{
+ return TQRangeControl::minValue();
+}
+
+/*!
+ \property TQSlider::maxValue
+ \brief the current maximum value of the slider
+
+ When setting this property, the \l TQSlider::minValue is adjusted,
+ if necessary, to ensure that the range remains valid.
+
+ \sa setRange()
+*/
+int TQSlider::maxValue() const
+{
+ return TQRangeControl::maxValue();
+}
+
+void TQSlider::setMinValue( int minVal )
+{
+ TQRangeControl::setMinValue( minVal );
+}
+
+void TQSlider::setMaxValue( int maxVal )
+{
+ TQRangeControl::setMaxValue( maxVal );
+}
+
+/*!
+ \property TQSlider::lineStep
+ \brief the current line step
+
+ When setting lineStep, the virtual stepChange() function will be
+ called if the new line step is different from the previous
+ setting.
+
+ \sa setSteps() TQRangeControl::pageStep() setRange()
+*/
+int TQSlider::lineStep() const
+{
+ return TQRangeControl::lineStep();
+}
+
+/*!
+ \property TQSlider::pageStep
+ \brief the current page step
+
+ When setting pageStep, the virtual stepChange() function will be
+ called if the new page step is different from the previous
+ setting.
+
+ \sa TQRangeControl::setSteps() setLineStep() setRange()
+*/
+
+int TQSlider::pageStep() const
+{
+ return TQRangeControl::pageStep();
+}
+
+void TQSlider::setLineStep( int i )
+{
+ setSteps( i, pageStep() );
+}
+
+void TQSlider::setPageStep( int i )
+{
+ setSteps( lineStep(), i );
+}
+
+/*!
+ \property TQSlider::value
+ \brief the current slider value
+
+ \sa TQRangeControl::value() prevValue()
+*/
+
+int TQSlider::value() const
+{
+ return TQRangeControl::value();
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqslider.h b/tqtinterface/qt4/src/widgets/tqslider.h
new file mode 100644
index 0000000..ac6177d
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqslider.h
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Definition of TQSlider class
+**
+** Created : 961019
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSLIDER_H
+#define TQSLIDER_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqrangecontrol.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SLIDER
+
+struct TQSliderPrivate;
+
+class TQTimer;
+
+class TQ_EXPORT TQSlider : public TQWidget, public TQRangeControl
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( TickSetting )
+ Q_PROPERTY( int minValue READ minValue WRITE setMinValue )
+ Q_PROPERTY( int maxValue READ maxValue WRITE setMaxValue )
+ Q_PROPERTY( int lineStep READ lineStep WRITE setLineStep )
+ Q_PROPERTY( int pageStep READ pageStep WRITE setPageStep )
+ Q_PROPERTY( int value READ value WRITE setValue )
+ Q_PROPERTY( bool tracking READ tracking WRITE setTracking )
+ Q_PROPERTY( Orientation orientation READ orientation WRITE setOrientation )
+ Q_PROPERTY( TickSetting tickmarks READ tickmarks WRITE setTickmarks )
+ Q_PROPERTY( int tickInterval READ tickInterval WRITE setTickInterval )
+
+public:
+ enum TickSetting { NoMarks = 0, Above = 1, Left = Above,
+ Below = 2, Right = Below, Both = 3 };
+
+ TQSlider( TQWidget *tqparent, const char* name = 0 );
+ TQSlider( Qt::Orientation, TQWidget *tqparent, const char* name = 0 );
+ TQSlider( int minValue, int maxValue, int pageStep, int value, Qt::Orientation,
+ TQWidget *tqparent, const char* name = 0 );
+ ~TQSlider();
+
+ virtual void setOrientation( Qt::Orientation );
+ Qt::Orientation orientation() const;
+ virtual void setTracking( bool enable );
+ bool tracking() const;
+ virtual void setPalette( const TQPalette & );
+
+ int sliderStart() const;
+ TQRect sliderRect() const;
+ TQSize tqsizeHint() const;
+ void tqsetSizePolicy( TQSizePolicy sp );
+ void tqsetSizePolicy( TQSizePolicy::SizeType hor, TQSizePolicy::SizeType ver, bool hfw = FALSE );
+
+ TQSizePolicy sizePolicy() const;
+ TQSize tqminimumSizeHint() const;
+
+ virtual void setTickmarks( TickSetting );
+ TickSetting tickmarks() const { return ticks; }
+
+ virtual void setTickInterval( int );
+ int tickInterval() const { return tickInt; }
+
+ int minValue() const;
+ int maxValue() const;
+ void setMinValue( int );
+ void setMaxValue( int );
+ int lineStep() const;
+ int pageStep() const;
+ void setLineStep( int );
+ void setPageStep( int );
+ int value() const;
+
+public Q_SLOTS:
+ virtual void setValue( int );
+ void addStep();
+ void subtractStep();
+ void addLine();
+ void subtractLine();
+
+Q_SIGNALS:
+ void valueChanged( int value );
+ void sliderPressed();
+ void sliderMoved( int value );
+ void sliderReleased();
+
+protected:
+ void resizeEvent( TQResizeEvent * );
+ void paintEvent( TQPaintEvent * );
+
+ void keyPressEvent( TQKeyEvent * );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+#ifndef TQT_NO_WHEELEVENT
+ void wheelEvent( TQWheelEvent * );
+#endif
+ void focusInEvent( TQFocusEvent *e );
+ void focusOutEvent( TQFocusEvent *e );
+
+ void styleChange( TQStyle& );
+
+ void valueChange();
+ void rangeChange();
+
+private Q_SLOTS:
+ void repeatTimeout();
+
+private:
+ enum State { Idle, Dragging, TimingUp, TimingDown };
+
+ void init();
+ int positionFromValue( int ) const;
+ int valueFromPosition( int ) const;
+ void moveSlider( int );
+ void reallyMoveSlider( int );
+ void resetState();
+ int available() const;
+ int goodPart( const TQPoint& ) const;
+ void initTicks();
+
+ TQSliderPrivate *d;
+ TQTimer *timer;
+ TQCOORD sliderPos;
+ int sliderVal;
+ TQCOORD clickOffset;
+ State state;
+ bool track;
+ TQCOORD tickOffset;
+ TickSetting ticks;
+ int tickInt;
+ Qt::Orientation orient;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSlider( const TQSlider & );
+ TQSlider &operator=( const TQSlider & );
+#endif
+};
+
+inline bool TQSlider::tracking() const
+{
+ return track;
+}
+
+inline Qt::Orientation TQSlider::orientation() const
+{
+ return orient;
+}
+
+inline int TQSlider::sliderStart() const
+{
+ return sliderPos;
+}
+
+inline void TQSlider::tqsetSizePolicy( TQSizePolicy::SizeType hor, TQSizePolicy::SizeType ver, bool hfw )
+{
+ TQWidget::tqsetSizePolicy( hor, ver, hfw );
+}
+
+#endif // TQT_NO_SLIDER
+
+#endif // TQSLIDER_H
diff --git a/tqtinterface/qt4/src/widgets/tqspinbox.cpp b/tqtinterface/qt4/src/widgets/tqspinbox.cpp
new file mode 100644
index 0000000..579d93b
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqspinbox.cpp
@@ -0,0 +1,1116 @@
+/****************************************************************************
+**
+** Implementation of TQSpinBox widget class
+**
+** Created : 970101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqspinbox.h"
+#ifndef TQT_NO_SPINBOX
+
+#include "tqcursor.h"
+#include "tqpushbutton.h"
+#include "tqpainter.h"
+#include "tqbitmap.h"
+#include "tqlineedit.h"
+#include "tqvalidator.h"
+#include "tqpixmapcache.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+static bool sumOutOfRange(int current, int add)
+{
+ if (add > 0 && INT_MAX - add < current) {
+ return true;
+ }
+ if (add < 0 && INT_MIN - add > current) {
+ return true;
+ }
+ return false;
+}
+
+class TQSpinBoxPrivate
+{
+public:
+ TQSpinBoxPrivate() {}
+ TQSpinWidget* controls;
+ uint selreq : 1;
+};
+
+class TQSpinBoxValidator : public TQIntValidator
+{
+public:
+ TQSpinBoxValidator( TQSpinBox *sb, const char *name )
+ : TQIntValidator( TQT_TQOBJECT(sb), name ), spinBox( sb ) { }
+
+ virtual State validate( TQString& str, int& pos ) const;
+
+private:
+ TQSpinBox *spinBox;
+};
+
+TQValidator::State TQSpinBoxValidator::validate( TQString& str, int& pos ) const
+{
+ TQString pref = spinBox->prefix();
+ TQString suff = spinBox->suffix();
+ TQString suffStriped = suff.stripWhiteSpace();
+ uint overhead = pref.length() + suff.length();
+ State state = Invalid;
+
+ ((TQIntValidator *) this)->setRange( spinBox->minValue(),
+ spinBox->maxValue() );
+ if ( overhead == 0 ) {
+ state = TQIntValidator::validate( str, pos );
+ } else {
+ bool stripedVersion = FALSE;
+ if ( str.length() >= overhead && str.startsWith(pref)
+ && (str.endsWith(suff)
+ || (stripedVersion = str.endsWith(suffStriped))) ) {
+ if ( stripedVersion )
+ overhead = pref.length() + suffStriped.length();
+ TQString core = str.mid( pref.length(), str.length() - overhead );
+ int corePos = pos - pref.length();
+ state = TQIntValidator::validate( core, corePos );
+ pos = corePos + pref.length();
+ str.tqreplace( pref.length(), str.length() - overhead, core );
+ } else {
+ state = TQIntValidator::validate( str, pos );
+ if ( state == Invalid ) {
+ // stripWhiteSpace(), cf. TQSpinBox::interpretText()
+ TQString special = spinBox->specialValueText().stripWhiteSpace();
+ TQString candidate = str.stripWhiteSpace();
+
+ if ( special.startsWith(candidate) ) {
+ if ( candidate.length() == special.length() ) {
+ state = Acceptable;
+ } else {
+ state = Intermediate;
+ }
+ }
+ }
+ }
+ }
+ return state;
+}
+
+/*!
+ \class TQSpinBox
+ \brief The TQSpinBox class provides a spin box widget (spin button).
+
+ \ingroup basic
+ \mainclass
+
+ TQSpinBox allows the user to choose a value either by clicking the
+ up/down buttons to increase/decrease the value currently displayed
+ or by typing the value directly into the spin box. If the value is
+ entered directly into the spin box, Enter (or Return) must be
+ pressed to apply the new value. The value is usually an integer.
+
+ Every time the value changes TQSpinBox emits the valueChanged()
+ signal. The current value can be fetched with value() and set
+ with setValue().
+
+ The spin box keeps the value within a numeric range, and to
+ multiples of the lineStep() size (see TQRangeControl for details).
+ Clicking the up/down buttons or using the keyboard accelerator's
+ up and down arrows will increase or decrease the current value in
+ steps of size lineStep(). The minimum and maximum value and the
+ step size can be set using one of the constructors, and can be
+ changed later with setMinValue(), setMaxValue() and setLineStep().
+
+ Most spin boxes are directional, but TQSpinBox can also operate as
+ a circular spin box, i.e. if the range is 0-99 and the current
+ value is 99, clicking "up" will give 0. Use setWrapping() if you
+ want circular behavior.
+
+ The displayed value can be prepended and appended with arbitrary
+ strings indicating, for example, currency or the unit of
+ measurement. See setPrefix() and setSuffix(). The text in the spin
+ box is retrieved with text() (which includes any prefix() and
+ suffix()), or with cleanText() (which has no prefix(), no suffix()
+ and no leading or trailing whitespace). currentValueText() returns
+ the spin box's current value as text.
+
+ Normally the spin box displays up and down arrows in the buttons.
+ You can use setButtonSymbols() to change the display to show
+ <b>+</b> and <b>-</b> symbols if you prefer. In either case the up
+ and down arrow keys work as expected.
+
+ It is often desirable to give the user a special (often default)
+ choice in addition to the range of numeric values. See
+ setSpecialValueText() for how to do this with TQSpinBox.
+
+ The default \l TQWidget::focusPolicy() is StrongFocus.
+
+ If using prefix(), suffix() and specialValueText() don't provide
+ enough control, you can ignore them and subclass TQSpinBox instead.
+
+ TQSpinBox can easily be subclassed to allow the user to input
+ things other than an integer value as long as the allowed input
+ can be mapped to a range of integers. This can be done by
+ overriding the virtual functions mapValueToText() and
+ mapTextToValue(), and setting another suitable validator using
+ setValidator().
+
+ For example, these functions could be changed so that the user
+ provided values from 0.0 to 10.0, or -1 to signify 'Auto', while
+ the range of integers used inside the program would be -1 to 100:
+
+ \code
+ class MySpinBox : public TQSpinBox
+ {
+ TQ_OBJECT
+ public:
+ ...
+
+ TQString mapValueToText( int value )
+ {
+ if ( value == -1 ) // special case
+ return TQString( "Auto" );
+
+ return TQString( "%1.%2" ) // 0.0 to 10.0
+ .arg( value / 10 ).arg( value % 10 );
+ }
+
+ int mapTextToValue( bool *ok )
+ {
+ if ( text() == "Auto" ) // special case
+ return -1;
+
+ return (int) ( 10 * text().toFloat() ); // 0 to 100
+ }
+ };
+ \endcode
+
+ <img src=qspinbox-m.png> <img src=qspinbox-w.png>
+
+ \sa TQScrollBar TQSlider
+ \link guibooks.html#fowler GUI Design Handbook: Spin Box \endlink
+*/
+
+
+/*!
+ Constructs a spin box with the default TQRangeControl range and
+ step values. It is called \a name and has tqparent \a tqparent.
+
+ \sa minValue(), maxValue(), setRange(), lineStep(), setSteps()
+*/
+
+TQSpinBox::TQSpinBox( TQWidget * tqparent , const char *name )
+ : TQWidget( tqparent, name, TQt::WNoAutoErase ),
+ TQRangeControl()
+{
+ initSpinBox();
+}
+
+
+/*!
+ Constructs a spin box that allows values from \a minValue to \a
+ maxValue inclusive, with step amount \a step. The value is
+ initially set to \a minValue.
+
+ The spin box is called \a name and has tqparent \a tqparent.
+
+ \sa minValue(), maxValue(), setRange(), lineStep(), setSteps()
+*/
+
+TQSpinBox::TQSpinBox( int minValue, int maxValue, int step, TQWidget* tqparent,
+ const char* name )
+ : TQWidget( tqparent, name, TQt::WNoAutoErase ),
+ TQRangeControl( minValue, maxValue, step, step, minValue )
+{
+ initSpinBox();
+}
+
+/*
+ \internal Initialization.
+*/
+
+void TQSpinBox::initSpinBox()
+{
+ d = new TQSpinBoxPrivate;
+
+ d->controls = new TQSpinWidget( this, "controls" );
+ connect( d->controls, TQT_SIGNAL( stepUpPressed() ), TQT_SLOT( stepUp() ) );
+ connect( d->controls, TQT_SIGNAL( stepDownPressed() ), TQT_SLOT( stepDown() ) );
+
+ wrap = FALSE;
+ edited = FALSE;
+ d->selreq = FALSE;
+
+ validate = new TQSpinBoxValidator( this, "validator" );
+ vi = new TQLineEdit( this, "qt_spinbox_edit" );
+ d->controls->setEditWidget( vi );
+ vi->setValidator( validate );
+ vi->installEventFilter( this );
+ vi->setFrame( FALSE );
+ setFocusProxy( vi );
+
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed ) );
+ setBackgroundMode( TQt::PaletteBackground, TQt::PaletteBase );
+
+ updateDisplay();
+
+ connect( vi, TQT_SIGNAL(textChanged(const TQString&)), TQT_SLOT(textChanged()) );
+}
+
+/*!
+ Destroys the spin box, freeing all memory and other resources.
+*/
+
+TQSpinBox::~TQSpinBox()
+{
+ delete d;
+}
+
+
+/*!
+ \property TQSpinBox::text
+ \brief the spin box's text, including any prefix() and suffix()
+
+ There is no default text.
+
+ \sa value()
+*/
+
+TQString TQSpinBox::text() const
+{
+ return vi->text();
+}
+
+
+
+/*!
+ \property TQSpinBox::cleanText
+ \brief the spin box's text with no prefix(), suffix() or leading
+ or trailing whitespace.
+
+ \sa text, prefix, suffix
+*/
+
+TQString TQSpinBox::cleanText() const
+{
+ TQString s = TQString(text()).stripWhiteSpace();
+ if ( !prefix().isEmpty() ) {
+ TQString px = TQString(prefix()).stripWhiteSpace();
+ int len = px.length();
+ if ( len && s.left(len) == px ) // Remove _only_ if it is the prefix
+ s.remove( (uint)0, len );
+ }
+ if ( !suffix().isEmpty() ) {
+ TQString sx = TQString(suffix()).stripWhiteSpace();
+ int len = sx.length();
+ if ( len && s.right(len) == sx ) // Remove _only_ if it is the suffix
+ s.truncate( s.length() - len );
+ }
+ return s.stripWhiteSpace();
+}
+
+
+/*!
+ \property TQSpinBox::specialValueText
+ \brief the special-value text
+
+ If set, the spin box will display this text instead of a numeric
+ value whenever the current value is equal to minVal(). Typical use
+ is to indicate that this choice has a special (default) meaning.
+
+ For example, if your spin box allows the user to choose the margin
+ width in a print dialog and your application is able to
+ automatically choose a good margin width, you can set up the spin
+ box like this:
+ \code
+ TQSpinBox marginBox( -1, 20, 1, tqparent, "marginBox" );
+ marginBox->setSuffix( " mm" );
+ marginBox->setSpecialValueText( "Auto" );
+ \endcode
+ The user will then be able to choose a margin width from 0-20
+ millimeters or select "Auto" to leave it to the application to
+ choose. Your code must then interpret the spin box value of -1 as
+ the user requesting automatic margin width.
+
+ All values are displayed with the prefix() and suffix() (if set),
+ \e except for the special value, which only shows the special
+ value text.
+
+ To turn off the special-value text display, call this function
+ with an empty string. The default is no special-value text, i.e.
+ the numeric value is shown as usual.
+
+ If no special-value text is set, specialValueText() returns
+ TQString::null.
+*/
+
+void TQSpinBox::setSpecialValueText( const TQString &text )
+{
+ specText = text;
+ updateDisplay();
+}
+
+
+TQString TQSpinBox::specialValueText() const
+{
+ if ( specText.isEmpty() )
+ return TQString::null;
+ else
+ return specText;
+}
+
+
+/*!
+ \property TQSpinBox::prefix
+ \brief the spin box's prefix
+
+ The prefix is prepended to the start of the displayed value.
+ Typical use is to display a unit of measurement or a currency
+ symbol. For example:
+
+ \code
+ sb->setPrefix( "$" );
+ \endcode
+
+ To turn off the prefix display, set this property to an empty
+ string. The default is no prefix. The prefix is not displayed for
+ the minValue() if specialValueText() is not empty.
+
+ If no prefix is set, prefix() returns TQString::null.
+
+ \sa suffix()
+*/
+
+void TQSpinBox::setPrefix( const TQString &text )
+{
+ pfix = text;
+ updateDisplay();
+}
+
+
+TQString TQSpinBox::prefix() const
+{
+ if ( pfix.isEmpty() )
+ return TQString::null;
+ else
+ return pfix;
+}
+
+
+/*!
+ \property TQSpinBox::suffix
+ \brief the suffix of the spin box
+
+ The suffix is appended to the end of the displayed value. Typical
+ use is to display a unit of measurement or a currency symbol. For
+ example:
+
+ \code
+ sb->setSuffix( " km" );
+ \endcode
+
+ To turn off the suffix display, set this property to an empty
+ string. The default is no suffix. The suffix is not displayed for
+ the minValue() if specialValueText() is not empty.
+
+ If no suffix is set, suffix() returns a TQString::null.
+
+ \sa prefix()
+*/
+
+void TQSpinBox::setSuffix( const TQString &text )
+{
+ sfix = text;
+ updateDisplay();
+}
+
+TQString TQSpinBox::suffix() const
+{
+ if ( sfix.isEmpty() )
+ return TQString::null;
+ else
+ return sfix;
+}
+
+
+/*!
+ \property TQSpinBox::wrapping
+ \brief whether it is possible to step the value from the highest
+ value to the lowest value and vice versa
+
+ By default, wrapping is turned off.
+
+ If you have a range of 0..100 and wrapping is off when the user
+ reaches 100 and presses the Up Arrow nothing will happen; but if
+ wrapping is on the value will change from 100 to 0, then to 1,
+ etc. When wrapping is on, navigating past the highest value takes
+ you to the lowest and vice versa.
+
+ \sa minValue, maxValue, setRange()
+*/
+
+void TQSpinBox::setWrapping( bool on )
+{
+ wrap = on;
+ updateDisplay();
+}
+
+bool TQSpinBox::wrapping() const
+{
+ return wrap;
+}
+
+/*!
+ \reimp
+*/
+TQSize TQSpinBox::tqsizeHint() const
+{
+ constPolish();
+ TQSize sz = vi->tqsizeHint();
+ int h = sz.height();
+ TQFontMetrics fm( font() );
+ int w = 35;
+ int wx = fm.width( ' ' )*2;
+ TQString s;
+ s = prefix() + ( (TQSpinBox*)this )->mapValueToText( minValue() ) + suffix();
+ w = TQMAX( w, fm.width( s ) + wx);
+ s = prefix() + ( (TQSpinBox*)this )->mapValueToText( maxValue() ) + suffix();
+ w = TQMAX(w, fm.width( s ) + wx );
+ if ( !specialValueText().isEmpty() ) {
+ s = specialValueText();
+ w = TQMAX( w, fm.width( s ) + wx );
+ }
+ return tqstyle().tqsizeFromContents(TQStyle::CT_SpinBox, this,
+ TQSize( w + d->controls->downRect().width(),
+ h + tqstyle().tqpixelMetric( TQStyle::PM_DefaultFrameWidth ) * 2).
+ expandedTo( TQApplication::globalStrut() ));
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQSpinBox::tqminimumSizeHint() const
+{
+ int w = vi->tqminimumSizeHint().width() + d->controls->downRect().width();
+ int h = TQMAX( vi->tqminimumSizeHint().height(), d->controls->tqminimumSizeHint().height() );
+ return TQSize( w, h );
+}
+
+// Does the tqlayout of the lineedit and the buttons
+
+void TQSpinBox::arrangeWidgets()
+{
+ d->controls->arrange();
+}
+
+/*!
+ \property TQSpinBox::value
+ \brief the value of the spin box
+
+ \sa TQRangeControl::setValue()
+*/
+
+void TQSpinBox::setValue( int value )
+{
+ edited = FALSE; // we ignore anything entered and not yet interpreted
+ TQRangeControl::setValue( value );
+ updateDisplay();
+}
+
+int TQSpinBox::value() const
+{
+ TQSpinBox * that = (TQSpinBox *) this;
+ if ( edited ) {
+ that->edited = FALSE; // avoid recursion
+ that->interpretText();
+ }
+ return TQRangeControl::value();
+}
+
+
+/*!
+ Increases the spin box's value by one lineStep(), wrapping as
+ necessary if wrapping() is TRUE. This is the same as clicking on
+ the pointing-up button and can be used for keyboard accelerators,
+ for example.
+
+ \sa stepDown(), addLine(), lineStep(), setSteps(), setValue(), value()
+*/
+
+void TQSpinBox::stepUp()
+{
+ if ( edited )
+ interpretText();
+ if ( wrapping() && ( value()+lineStep() > maxValue() || sumOutOfRange(value(), lineStep() ) ) ) {
+ setValue( minValue() );
+ } else {
+ addLine();
+ }
+}
+
+
+/*!
+ Decreases the spin box's value one lineStep(), wrapping as
+ necessary if wrapping() is TRUE. This is the same as clicking on
+ the pointing-down button and can be used for keyboard
+ accelerators, for example.
+
+ \sa stepUp(), subtractLine(), lineStep(), setSteps(), setValue(), value()
+*/
+
+void TQSpinBox::stepDown()
+{
+ if ( edited )
+ interpretText();
+ if ( wrapping() && ( value()-lineStep() < minValue() || sumOutOfRange(value(), -lineStep() ) ) ) {
+ setValue( maxValue() );
+ } else {
+ subtractLine();
+ }
+}
+
+
+/*!
+ \fn void TQSpinBox::valueChanged( int value )
+
+ This signal is emitted every time the value of the spin box
+ changes; the new value is passed in \a value. This signal will be
+ emitted as a result of a call to setValue(), or because the user
+ changed the value by using a keyboard accelerator or mouse click,
+ etc.
+
+ Note that the valueChanged() signal is emitted \e every time, not
+ just for the "last" step; i.e. if the user clicks "up" three
+ times, this signal is emitted three times.
+
+ \sa value()
+*/
+
+
+/*!
+ \fn void TQSpinBox::valueChanged( const TQString& valueText )
+
+ \overload
+
+ This signal is emitted whenever the valueChanged( int ) signal is
+ emitted, i.e. every time the value of the spin box changes
+ (whatever the cause, e.g. by setValue(), by a keyboard
+ accelerator, by mouse clicks, etc.).
+
+ The \a valueText parameter is the same string that is displayed in
+ the edit field of the spin box.
+
+ \sa value() prefix() suffix() specialValueText()
+*/
+
+
+
+/*!
+ Intercepts and handles the events coming to the embedded TQLineEdit
+ that have special meaning for the TQSpinBox. The object is passed
+ as \a o and the event is passed as \a ev.
+*/
+
+bool TQSpinBox::eventFilter( TQObject* o, TQEvent* ev )
+{
+ if (o != TQT_TQOBJECT(vi))
+ return TQWidget::eventFilter(o,ev);
+
+ if ( ev->type() == TQEvent::KeyPress ) {
+ TQKeyEvent* k = (TQKeyEvent*)ev;
+
+ bool retval = FALSE; // workaround for MSVC++ optimization bug
+ if( (k->key() == Qt::Key_Tab) || (k->key() == TQt::Key_BackTab) ){
+ if ( k->state() & ControlButton )
+ return FALSE;
+ if ( edited )
+ interpretText();
+ tqApp->sendEvent( this, ev );
+ retval = TRUE;
+ } if ( k->key() == Qt::Key_Up ) {
+ stepUp();
+ retval = TRUE;
+ } else if ( k->key() == Qt::Key_Down ) {
+ stepDown();
+ retval = TRUE;
+ } else if ( k->key() == Qt::Key_Enter || k->key() == Qt::Key_Return ) {
+ interpretText();
+ return FALSE;
+ }
+ if ( retval )
+ return retval;
+ } else if ( ev->type() == TQEvent::FocusOut || ev->type() == TQEvent::Hide ) {
+ if ( edited ) {
+ interpretText();
+ }
+ return FALSE;
+ }
+ return FALSE;
+}
+
+/*!
+ \reimp
+ */
+void TQSpinBox::setEnabled( bool enabled )
+{
+ TQWidget::setEnabled( enabled );
+ updateDisplay();
+}
+
+/*!
+ \reimp
+*/
+void TQSpinBox::leaveEvent( TQEvent* )
+{
+}
+
+
+/*!
+ \reimp
+*/
+void TQSpinBox::resizeEvent( TQResizeEvent* )
+{
+ d->controls->resize( width(), height() );
+}
+
+/*!
+ \reimp
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQSpinBox::wheelEvent( TQWheelEvent * e )
+{
+ e->accept();
+ static float offset = 0;
+ static TQSpinBox* offset_owner = 0;
+ if (offset_owner != this) {
+ offset_owner = this;
+ offset = 0;
+ }
+ offset += -e->delta()/120;
+ if (TQABS(offset) < 1)
+ return;
+ int ioff = int(offset);
+ int i;
+ for (i=0; i<TQABS(ioff); i++)
+ offset > 0 ? stepDown() : stepUp();
+ offset -= ioff;
+}
+#endif
+
+/*!
+ This virtual function is called by TQRangeControl whenever the
+ value has changed. The TQSpinBox reimplementation updates the
+ display and emits the valueChanged() Q_SIGNALS; if you need
+ additional processing, either reimplement this or connect to one
+ of the valueChanged() Q_SIGNALS.
+*/
+
+void TQSpinBox::valueChange()
+{
+ d->selreq = hasFocus();
+ updateDisplay();
+ d->selreq = FALSE;
+ emit valueChanged( value() );
+ emit valueChanged( currentValueText() );
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ValueChanged );
+#endif
+}
+
+
+/*!
+ This virtual function is called by TQRangeControl whenever the
+ range has changed. It adjusts the default validator and updates
+ the display; if you need additional processing, you can
+ reimplement this function.
+*/
+
+void TQSpinBox::rangeChange()
+{
+ updateDisplay();
+}
+
+
+/*!
+ Sets the validator to \a v. The validator controls what keyboard
+ input is accepted when the user is editing in the value field. The
+ default is to use a suitable TQIntValidator.
+
+ Use setValidator(0) to turn off input validation (entered input
+ will still be kept within the spin box's range).
+*/
+
+void TQSpinBox::setValidator( const TQValidator* v )
+{
+ if ( vi )
+ vi->setValidator( v );
+}
+
+
+/*!
+ Returns the validator that constrains editing for this spin box if
+ there is any; otherwise returns 0.
+
+ \sa setValidator() TQValidator
+*/
+
+const TQValidator * TQSpinBox::validator() const
+{
+ return vi ? vi->validator() : 0;
+}
+
+/*!
+ Updates the contents of the embedded TQLineEdit to reflect the
+ current value using mapValueToText(). Also enables/disables the
+ up/down push buttons accordingly.
+
+ \sa mapValueToText()
+*/
+void TQSpinBox::updateDisplay()
+{
+ vi->setUpdatesEnabled( FALSE );
+ vi->setText( currentValueText() );
+ if ( d->selreq && isVisible() && ( hasFocus() || vi->hasFocus() ) ) {
+ selectAll();
+ } else {
+ if ( !suffix().isEmpty() && vi->text().endsWith(suffix()) )
+ vi->setCursorPosition( vi->text().length() - suffix().length() );
+ }
+ vi->setUpdatesEnabled( TRUE );
+ vi->tqrepaint( FALSE ); // immediate tqrepaint needed for some reason
+ edited = FALSE;
+
+ bool upEnabled = isEnabled() && ( wrapping() || value() < maxValue() );
+ bool downEnabled = isEnabled() && ( wrapping() || value() > minValue() );
+
+ d->controls->setUpEnabled( upEnabled );
+ d->controls->setDownEnabled( downEnabled );
+ vi->setEnabled( isEnabled() );
+ tqrepaint( FALSE );
+}
+
+
+/*!
+ TQSpinBox calls this after the user has manually edited the
+ contents of the spin box (i.e. by typing in the embedded
+ TQLineEdit, rather than using the up/down buttons/keys).
+
+ The default implementation of this function interprets the new
+ text using mapTextToValue(). If mapTextToValue() is successful, it
+ changes the spin box's value; if not, the value is left unchanged.
+
+ \sa editor()
+*/
+
+void TQSpinBox::interpretText()
+{
+ bool ok = TRUE;
+ bool done = FALSE;
+ int newVal = 0;
+ if ( !specialValueText().isEmpty() ) {
+ TQString s = text().stripWhiteSpace();
+ TQString t = specialValueText().stripWhiteSpace();
+ if ( s == t ) {
+ newVal = minValue();
+ done = TRUE;
+ }
+ }
+ if ( !done )
+ newVal = mapTextToValue( &ok );
+ if ( ok )
+ setValue( newVal );
+ updateDisplay(); // sometimes redundant
+}
+
+
+/*!
+ Returns the tqgeometry of the "up" button.
+*/
+
+TQRect TQSpinBox::upRect() const
+{
+ return d->controls->upRect();
+}
+
+
+/*!
+ Returns the tqgeometry of the "down" button.
+*/
+
+TQRect TQSpinBox::downRect() const
+{
+ return d->controls->downRect();
+}
+
+
+/*!
+ Returns a pointer to the embedded TQLineEdit.
+*/
+
+TQLineEdit* TQSpinBox::editor() const
+{
+ return vi;
+}
+
+
+/*!
+ This slot is called whenever the user edits the spin box's text.
+*/
+
+void TQSpinBox::textChanged()
+{
+ edited = TRUE; // this flag is cleared in updateDisplay()
+}
+
+
+/*!
+ This virtual function is used by the spin box whenever it needs to
+ display value \a v. The default implementation returns a string
+ containing \a v printed in the standard way. Reimplementations may
+ return anything. (See the example in the detailed description.)
+
+ Note that TQt does not call this function for specialValueText()
+ and that neither prefix() nor suffix() are included in the return
+ value.
+
+ If you reimplement this, you may also need to reimplement
+ mapTextToValue().
+
+ \sa updateDisplay(), mapTextToValue()
+*/
+
+TQString TQSpinBox::mapValueToText( int v )
+{
+ TQString s;
+ s.setNum( v );
+ return s;
+}
+
+
+/*!
+ This virtual function is used by the spin box whenever it needs to
+ interpret text entered by the user as a value. The text is
+ available as text() and as cleanText(), and this function must
+ parse it if possible. If \a ok is not 0: if it parses the text
+ successfully, \a *ok is set to TRUE; otherwise \a *ok is set to
+ FALSE.
+
+ Subclasses that need to display spin box values in a non-numeric
+ way need to reimplement this function.
+
+ Note that TQt handles specialValueText() separately; this function
+ is only concerned with the other values.
+
+ The default implementation tries to interpret the text() as an
+ integer in the standard way and returns the integer value.
+
+ \sa interpretText(), mapValueToText()
+*/
+
+int TQSpinBox::mapTextToValue( bool* ok )
+{
+ TQString s = text();
+ int newVal = s.toInt( ok );
+ if ( !(*ok) && !( !prefix() && !suffix() ) ) {// Try removing any pre/suffix
+ s = cleanText();
+ newVal = s.toInt( ok );
+ }
+ return newVal;
+}
+
+
+/*!
+ Returns the full text calculated from the current value, including
+ any prefix and suffix. If there is special value text and the
+ value is minValue() the specialValueText() is returned.
+*/
+
+TQString TQSpinBox::currentValueText()
+{
+ TQString s;
+ if ( (value() == minValue()) && !specialValueText().isEmpty() ) {
+ s = specialValueText();
+ } else {
+ s = prefix();
+ s.append( mapValueToText( value() ) );
+ s.append( suffix() );
+ }
+ return s;
+}
+
+/*!
+ \reimp
+*/
+
+void TQSpinBox::styleChange( TQStyle& old )
+{
+ arrangeWidgets();
+ TQWidget::styleChange( old );
+}
+
+
+/*!
+ \enum TQSpinBox::ButtonSymbols
+
+ This enum type determines what the buttons in a spin box show.
+
+ \value UpDownArrows the buttons show little arrows in the classic
+ style.
+
+ \value PlusMinus the buttons show <b>+</b> and <b>-</b> symbols.
+
+ \sa TQSpinBox::buttonSymbols
+*/
+
+/*!
+ \property TQSpinBox::buttonSymbols
+
+ \brief the current button symbol mode
+
+ The possible values can be either \c UpDownArrows or \c PlusMinus.
+ The default is \c UpDownArrows.
+
+ \sa ButtonSymbols
+*/
+
+void TQSpinBox::setButtonSymbols( ButtonSymbols newSymbols )
+{
+ if ( buttonSymbols() == newSymbols )
+ return;
+
+ switch ( newSymbols ) {
+ case UpDownArrows:
+ d->controls->setButtonSymbols( TQSpinWidget::UpDownArrows );
+ break;
+ case PlusMinus:
+ d->controls->setButtonSymbols( TQSpinWidget::PlusMinus );
+ break;
+ }
+ // tqrepaint( FALSE );
+}
+
+TQSpinBox::ButtonSymbols TQSpinBox::buttonSymbols() const
+{
+ switch( d->controls->buttonSymbols() ) {
+ case TQSpinWidget::UpDownArrows:
+ return UpDownArrows;
+ case TQSpinWidget::PlusMinus:
+ return PlusMinus;
+ }
+ return UpDownArrows;
+}
+
+/*!
+ \property TQSpinBox::minValue
+
+ \brief the minimum value of the spin box
+
+ When setting this property, \l TQSpinBox::maxValue is adjusted, if
+ necessary, to ensure that the range remains valid.
+
+ \sa setRange() setSpecialValueText()
+*/
+
+int TQSpinBox::minValue() const
+{
+ return TQRangeControl::minValue();
+}
+
+void TQSpinBox::setMinValue( int minVal )
+{
+ TQRangeControl::setMinValue( minVal );
+}
+
+/*!
+ \property TQSpinBox::maxValue
+ \brief the maximum value of the spin box
+
+ When setting this property, \l TQSpinBox::minValue is adjusted, if
+ necessary, to ensure that the range remains valid.
+
+ \sa setRange() setSpecialValueText()
+*/
+
+int TQSpinBox::maxValue() const
+{
+ return TQRangeControl::maxValue();
+}
+
+void TQSpinBox::setMaxValue( int maxVal )
+{
+ TQRangeControl::setMaxValue( maxVal );
+}
+
+/*!
+ \property TQSpinBox::lineStep
+ \brief the line step
+
+ When the user uses the arrows to change the spin box's value the
+ value will be incremented/decremented by the amount of the line
+ step.
+
+ The setLineStep() function calls the virtual stepChange() function
+ if the new line step is different from the previous setting.
+
+ \sa TQRangeControl::setSteps() setRange()
+*/
+
+int TQSpinBox::lineStep() const
+{
+ return TQRangeControl::lineStep();
+}
+
+void TQSpinBox::setLineStep( int i )
+{
+ setSteps( i, pageStep() );
+}
+
+/*!
+ Selects all the text in the spin box's editor.
+*/
+
+void TQSpinBox::selectAll()
+{
+ int overhead = prefix().length() + suffix().length();
+ if ( !overhead || currentValueText() == specialValueText() ) {
+ vi->selectAll();
+ } else {
+ vi->setSelection( prefix().length(), vi->text().length() - overhead );
+ }
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqspinbox.h b/tqtinterface/qt4/src/widgets/tqspinbox.h
new file mode 100644
index 0000000..2e18cef
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqspinbox.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Definition of TQSpinBox widget class
+**
+** Created : 970101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSPINBOX_H
+#define TQSPINBOX_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqrangecontrol.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SPINBOX
+
+class TQLineEdit;
+class TQValidator;
+class TQSpinBoxPrivate;
+
+class TQ_EXPORT TQSpinBox: public TQWidget, public TQRangeControl
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( ButtonSymbols )
+ Q_PROPERTY( TQString text READ text )
+ Q_PROPERTY( TQString prefix READ prefix WRITE setPrefix )
+ Q_PROPERTY( TQString suffix READ suffix WRITE setSuffix )
+ Q_PROPERTY( TQString cleanText READ cleanText )
+ Q_PROPERTY( TQString specialValueText READ specialValueText WRITE setSpecialValueText )
+ Q_PROPERTY( bool wrapping READ wrapping WRITE setWrapping )
+ Q_PROPERTY( ButtonSymbols buttonSymbols READ buttonSymbols WRITE setButtonSymbols )
+ Q_PROPERTY( int maxValue READ maxValue WRITE setMaxValue )
+ Q_PROPERTY( int minValue READ minValue WRITE setMinValue )
+ Q_PROPERTY( int lineStep READ lineStep WRITE setLineStep )
+ Q_PROPERTY( int value READ value WRITE setValue )
+
+public:
+ TQSpinBox( TQWidget* tqparent=0, const char* name=0 );
+ TQSpinBox( int minValue, int maxValue, int step = 1,
+ TQWidget* tqparent=0, const char* name=0 );
+ ~TQSpinBox();
+
+ TQString text() const;
+
+ virtual TQString prefix() const;
+ virtual TQString suffix() const;
+ virtual TQString cleanText() const;
+
+ virtual void setSpecialValueText( const TQString &text );
+ TQString specialValueText() const;
+
+ virtual void setWrapping( bool on );
+ bool wrapping() const;
+
+ enum ButtonSymbols { UpDownArrows, PlusMinus };
+ virtual void setButtonSymbols( ButtonSymbols );
+ ButtonSymbols buttonSymbols() const;
+
+ virtual void setValidator( const TQValidator* v );
+ const TQValidator * validator() const;
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ int minValue() const;
+ int maxValue() const;
+ void setMinValue( int );
+ void setMaxValue( int );
+ int lineStep() const;
+ void setLineStep( int );
+ int value() const;
+
+ TQRect upRect() const;
+ TQRect downRect() const;
+
+public Q_SLOTS:
+ virtual void setValue( int value );
+ virtual void setPrefix( const TQString &text );
+ virtual void setSuffix( const TQString &text );
+ virtual void stepUp();
+ virtual void stepDown();
+ virtual void setEnabled( bool enabled );
+ virtual void selectAll();
+
+Q_SIGNALS:
+ void valueChanged( int value );
+ void valueChanged( const TQString &valueText );
+
+protected:
+ virtual TQString mapValueToText( int value );
+ virtual int mapTextToValue( bool* ok );
+ TQString currentValueText();
+
+ virtual void updateDisplay();
+ virtual void interpretText();
+
+ TQLineEdit* editor() const;
+
+ virtual void valueChange();
+ virtual void rangeChange();
+
+ bool eventFilter( TQObject* obj, TQEvent* ev );
+ void resizeEvent( TQResizeEvent* ev );
+#ifndef TQT_NO_WHEELEVENT
+ void wheelEvent( TQWheelEvent * );
+#endif
+ void leaveEvent( TQEvent* );
+
+ void styleChange( TQStyle& );
+
+protected Q_SLOTS:
+ void textChanged();
+
+private:
+ void initSpinBox();
+ TQSpinBoxPrivate* d;
+ TQLineEdit* vi;
+ TQValidator* validate;
+ TQString pfix;
+ TQString sfix;
+ TQString specText;
+
+ uint wrap : 1;
+ uint edited : 1;
+
+ void arrangeWidgets();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQSpinBox( const TQSpinBox& );
+ TQSpinBox& operator=( const TQSpinBox& );
+#endif
+
+};
+
+#endif // TQT_NO_SPINBOX
+
+#endif // TQSPINBOX_H
diff --git a/tqtinterface/qt4/src/widgets/tqspinwidget.cpp b/tqtinterface/qt4/src/widgets/tqspinwidget.cpp
new file mode 100644
index 0000000..1fc4407
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqspinwidget.cpp
@@ -0,0 +1,465 @@
+/****************************************************************************
+**
+** Implementation of TQSpinWidget class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqrangecontrol.h"
+
+#ifndef TQT_NO_SPINWIDGET
+
+#include "tqrect.h"
+#include "tqtimer.h"
+#include "tqstyle.h"
+#include "tqpainter.h"
+
+class TQSpinWidgetPrivate
+{
+public:
+ TQSpinWidgetPrivate()
+ : upEnabled( TRUE ),
+ downEnabled( TRUE ),
+ theButton( 0 ),
+ buttonDown( 0 ),
+ timerUp( 0 ),
+ bsyms( TQSpinWidget::UpDownArrows ),
+ ed ( 0 ) {}
+ uint upEnabled :1;
+ uint downEnabled :1;
+ uint theButton :2;
+ uint buttonDown :2;
+ uint timerUp : 1;
+ TQRect up;
+ TQRect down;
+ TQTimer auRepTimer;
+ TQSpinWidget::ButtonSymbols bsyms;
+ TQWidget *ed;
+ void startTimer( int msec ) { auRepTimer.start( msec, TRUE ); }
+ void startTimer( bool up, int msec ) { timerUp = up; startTimer( msec ); }
+ void stopTimer() { auRepTimer.stop(); }
+};
+
+/*!
+
+ \class TQSpinWidget qspinwidget.h
+ \brief The TQSpinWidget class is an internal range control related class.
+
+ \internal
+
+ Constructs an empty range control widget with tqparent \a tqparent
+ called \a name.
+
+*/
+
+TQSpinWidget::TQSpinWidget( TQWidget* tqparent, const char* name )
+ : TQWidget( tqparent, name )
+{
+ d = new TQSpinWidgetPrivate();
+ connect( &d->auRepTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( timerDone() ) );
+ setFocusPolicy( Qt::StrongFocus );
+
+ arrange();
+ updateDisplay();
+}
+
+
+/*! Destroys the object and frees any allocated resources.
+
+*/
+
+TQSpinWidget::~TQSpinWidget()
+{
+ delete d;
+}
+
+/*! */
+TQWidget * TQSpinWidget::editWidget()
+{
+ return d->ed;
+}
+
+/*!
+ Sets the editing widget to \a w.
+*/
+void TQSpinWidget::setEditWidget( TQWidget * w )
+{
+ if ( w ) {
+ if (w->parentWidget() != this)
+ w->reparent( this, TQPoint( 0, 0 ) );
+ setFocusProxy( w );
+ }
+ d->ed = w;
+ arrange();
+ updateDisplay();
+}
+
+/*! \reimp
+
+*/
+
+void TQSpinWidget::mousePressEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton ) {
+ d->stopTimer();
+ d->buttonDown = 0;
+ d->theButton = 0;
+ tqrepaint( d->down.unite( d->up ), FALSE );
+ return;
+ }
+
+ uint oldButtonDown = d->buttonDown;
+
+ if ( d->down.tqcontains( e->pos() ) && d->downEnabled )
+ d->buttonDown = 1;
+ else if ( d->up.tqcontains( e->pos() ) && d->upEnabled )
+ d->buttonDown = 2;
+ else
+ d->buttonDown = 0;
+
+ d->theButton = d->buttonDown;
+ if ( oldButtonDown != d->buttonDown ) {
+ if ( !d->buttonDown ) {
+ tqrepaint( d->down.unite( d->up ), FALSE );
+ } else if ( d->buttonDown & 1 ) {
+ tqrepaint( d->down, FALSE );
+ stepDown();
+ d->startTimer( FALSE, 300 );
+ } else if ( d->buttonDown & 2 ) {
+ tqrepaint( d->up, FALSE );
+ stepUp();
+ d->startTimer( TRUE, 300 );
+ }
+ }
+}
+
+/*!
+
+*/
+
+void TQSpinWidget::arrange()
+{
+ d->up = TQStyle::tqvisualRect( tqstyle().querySubControlMetrics( TQStyle::CC_SpinWidget, this,
+ TQStyle::SC_SpinWidgetUp ), this );
+ d->down = TQStyle::tqvisualRect( tqstyle().querySubControlMetrics( TQStyle::CC_SpinWidget, this,
+ TQStyle::SC_SpinWidgetDown ), this );
+ if ( d->ed ) {
+ TQRect r = TQStyle::tqvisualRect( tqstyle().querySubControlMetrics( TQStyle::CC_SpinWidget, this,
+ TQStyle::SC_SpinWidgetEditField ), this );
+ d->ed->setGeometry( r );
+ }
+}
+
+/*!
+
+*/
+
+void TQSpinWidget::stepUp()
+{
+ emit stepUpPressed();
+}
+
+void TQSpinWidget::resizeEvent( TQResizeEvent* )
+{
+ arrange();
+}
+
+/*!
+
+*/
+
+void TQSpinWidget::stepDown()
+{
+ emit stepDownPressed();
+}
+
+
+void TQSpinWidget::timerDone()
+{
+ // we use a double timer to make it possible for users to do
+ // something with 0-timer on valueChanged.
+ TQTimer::singleShot( 1, this, TQT_SLOT( timerDoneEx() ) );
+}
+
+void TQSpinWidget::timerDoneEx()
+{
+ if ( !d->buttonDown )
+ return;
+ if ( d->timerUp )
+ stepUp();
+ else
+ stepDown();
+ d->startTimer( 100 );
+}
+
+
+void TQSpinWidget::windowActivationChange( bool oldActive )
+{
+ //was active, but lost focus
+ if ( oldActive && d->buttonDown ) {
+ d->stopTimer();
+ d->buttonDown = 0;
+ d->theButton = 0;
+ }
+ TQWidget::windowActivationChange( oldActive );
+}
+
+
+
+/*!
+ The event is passed in \a e.
+*/
+
+void TQSpinWidget::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+
+ uint oldButtonDown = d->theButton;
+ d->theButton = 0;
+ if ( oldButtonDown != d->theButton ) {
+ if ( oldButtonDown & 1 )
+ tqrepaint( d->down, FALSE );
+ else if ( oldButtonDown & 2 )
+ tqrepaint( d->up, FALSE );
+ }
+ d->stopTimer();
+ d->buttonDown = 0;
+}
+
+
+/*!
+ The event is passed in \a e.
+*/
+
+void TQSpinWidget::mouseMoveEvent( TQMouseEvent *e )
+{
+ if ( !(e->state() & Qt::LeftButton ) )
+ return;
+
+ uint oldButtonDown = d->theButton;
+ if ( oldButtonDown & 1 && !d->down.tqcontains( e->pos() ) ) {
+ d->stopTimer();
+ d->theButton = 0;
+ tqrepaint( d->down, FALSE );
+ } else if ( oldButtonDown & 2 && !d->up.tqcontains( e->pos() ) ) {
+ d->stopTimer();
+ d->theButton = 0;
+ tqrepaint( d->up, FALSE );
+ } else if ( !oldButtonDown && d->up.tqcontains( e->pos() ) && d->buttonDown & 2 ) {
+ d->startTimer( 500 );
+ d->theButton = 2;
+ tqrepaint( d->up, FALSE );
+ } else if ( !oldButtonDown && d->down.tqcontains( e->pos() ) && d->buttonDown & 1 ) {
+ d->startTimer( 500 );
+ d->theButton = 1;
+ tqrepaint( d->down, FALSE );
+ }
+}
+
+
+/*!
+ The event is passed in \a e.
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQSpinWidget::wheelEvent( TQWheelEvent *e )
+{
+ e->accept();
+ static float offset = 0;
+ static TQSpinWidget* offset_owner = 0;
+ if ( offset_owner != this ) {
+ offset_owner = this;
+ offset = 0;
+ }
+ offset += -e->delta()/120;
+ if ( TQABS( offset ) < 1 )
+ return;
+ int ioff = int(offset);
+ int i;
+ for( i=0; i < TQABS( ioff ); i++ )
+ offset > 0 ? stepDown() : stepUp();
+ offset -= ioff;
+}
+#endif
+
+/*!
+
+*/
+void TQSpinWidget::paintEvent( TQPaintEvent * )
+{
+ TQPainter p( this );
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus() || (focusProxy() && focusProxy()->hasFocus()))
+ flags |= TQStyle::Style_HasFocus;
+
+ TQStyle::SCFlags active;
+ if ( d->theButton & 1 )
+ active = TQStyle::SC_SpinWidgetDown;
+ else if ( d->theButton & 2 )
+ active = TQStyle::SC_SpinWidgetUp;
+ else
+ active = TQStyle::SC_None;
+
+ TQRect fr = TQStyle::tqvisualRect(
+ tqstyle().querySubControlMetrics( TQStyle::CC_SpinWidget, this,
+ TQStyle::SC_SpinWidgetFrame ), this );
+ tqstyle().tqdrawComplexControl( TQStyle::CC_SpinWidget, &p, this,
+ fr, tqcolorGroup(),
+ flags,
+ (uint)TQStyle::SC_All,
+ active );
+}
+
+
+/*!
+ The previous style is passed in \a old.
+*/
+
+void TQSpinWidget::styleChange( TQStyle& old )
+{
+ arrange();
+ TQWidget::styleChange( old );
+}
+
+/*!
+*/
+
+TQRect TQSpinWidget::upRect() const
+{
+ return d->up;
+}
+
+/*!
+*/
+
+TQRect TQSpinWidget::downRect() const
+{
+ return d->down;
+}
+
+/*!
+*/
+
+void TQSpinWidget::updateDisplay()
+{
+ if ( !isEnabled() ) {
+ d->upEnabled = FALSE;
+ d->downEnabled = FALSE;
+ }
+ if ( d->theButton & 1 && ( d->downEnabled ) == 0 ) {
+ d->theButton &= ~1;
+ d->buttonDown &= ~1;
+ }
+
+ if ( d->theButton & 2 && ( d->upEnabled ) == 0 ) {
+ d->theButton &= ~2;
+ d->buttonDown &= ~2;
+ }
+ tqrepaint( FALSE );
+}
+
+
+/*!
+ The previous enabled state is passed in \a old.
+*/
+
+void TQSpinWidget::enableChanged( bool )
+{
+ d->upEnabled = isEnabled();
+ d->downEnabled = isEnabled();
+ updateDisplay();
+}
+
+
+/*!
+ Sets up-enabled to \a on.
+*/
+
+void TQSpinWidget::setUpEnabled( bool on )
+{
+ if ( (bool)d->upEnabled != on ) {
+ d->upEnabled = on;
+ updateDisplay();
+ }
+}
+
+/*!
+*/
+
+bool TQSpinWidget::isUpEnabled() const
+{
+ return d->upEnabled;
+}
+
+/*!
+ Sets down-enabled to \a on.
+*/
+
+void TQSpinWidget::setDownEnabled( bool on )
+{
+ if ( (bool)d->downEnabled != on ) {
+ d->downEnabled = on;
+ updateDisplay();
+ }
+}
+
+/*!
+*/
+
+bool TQSpinWidget::isDownEnabled() const
+{
+ return d->downEnabled;
+}
+
+/*!
+ Sets the button symbol to \a bs.
+*/
+
+void TQSpinWidget::setButtonSymbols( ButtonSymbols bs )
+{
+ d->bsyms = bs;
+}
+
+/*!
+*/
+
+TQSpinWidget::ButtonSymbols TQSpinWidget::buttonSymbols() const
+{
+ return d->bsyms;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqsplashscreen.cpp b/tqtinterface/qt4/src/widgets/tqsplashscreen.cpp
new file mode 100644
index 0000000..64da325
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqsplashscreen.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** Definition of TQSplashScreen class
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsplashscreen.h"
+
+#ifndef TQT_NO_SPLASHSCREEN
+
+#include "tqapplication.h"
+#include "tqpainter.h"
+#include "tqpixmap.h"
+
+class TQSplashScreenPrivate
+{
+public:
+ TQPixmap pixmap;
+ TQString currtqStatus;
+ TQColor currColor;
+ int currAlign;
+};
+
+/*!
+ \class TQSplashScreen tqsplashscreen.h
+ \brief The TQSplashScreen widget provides a splash screen that can
+ be shown during application startup.
+
+ \ingroup misc
+ \mainclass
+
+ A splash screen is a widget that is usually displayed when an
+ application is being started. Splash screens are often used for
+ applications that have long start up times (e.g. database or
+ networking applications that take time to establish connections) to
+ provide the user with feedback that the application is loading.
+
+ The splash screen appears centered on the screen. It may be useful to add
+ the \c WStyle_StaysOnTop if you desire to keep above all the windows in the
+ GUI.
+
+ Some X11 window managers do not support the "stays on top" flag. A
+ solution is to set up a timer that periodically calls raise() on
+ the splash screen to simulate the "stays on top" effect.
+
+ The most common usage is to show a splash screen before the main
+ widget is displayed on the screen. This is illustrated in the
+ following code snippet.
+
+ \code
+ int main( int argc, char **argv )
+ {
+ TQApplication app( argc, argv );
+ TQPixmap pixmap( "splash.png" );
+ TQSplashScreen *splash = new TQSplashScreen( pixmap );
+ splash->show();
+ TQMainWindow *mainWin = new TQMainWindow;
+ ...
+ app.setMainWidget( mainWin );
+ mainWin->show();
+ splash->finish( mainWin );
+ delete splash;
+ return app.exec();
+ }
+ \endcode
+
+ It is sometimes useful to update the splash screen with messages,
+ for example, announcing connections established or modules loaded
+ as the application starts up. TQSplashScreen supports this with the
+ message() function. If you wish to do your own drawing you can
+ get a pointer to the pixmap used in the splash screen with pixmap().
+ Alternatively, you can subclass TQSplashScreen and reimplement
+ drawContents().
+
+ The user can hide the splash screen by clicking on it with the
+ mouse. Since the splash screen is typically displayed before the
+ event loop has started running, it is necessary to periodically
+ call TQApplication::processEvents() to receive the mouse clicks.
+
+ \code
+ TQPixmap pixmap( "splash.png" );
+ TQSplashScreen *splash = new TQSplashScreen( pixmap );
+ splash->show();
+ ... // Loading some items
+ splash->message( "Loaded modules" );
+ tqApp->processEvents();
+ ... // Establishing connections
+ splash->message( "Established connections" );
+ tqApp->processEvents();
+ \endcode
+
+*/
+
+/*!
+ Construct a splash screen that will display the \a pixmap.
+
+ There should be no need to set the widget flags, \a f, except
+ perhaps \c WDestructiveClose or \c WStyle_StaysOnTop.
+*/
+TQSplashScreen::TQSplashScreen( const TQPixmap &pixmap, WFlags f )
+ : TQWidget( 0, 0, (WFlags)(WStyle_Customize | TQt::WStyle_Splash | f) )
+{
+ d = new TQSplashScreenPrivate();
+ d->pixmap = pixmap;
+ setPixmap( d->pixmap ); // Does an implicit tqrepaint
+}
+
+/*!
+ Destructor.
+*/
+TQSplashScreen::~TQSplashScreen()
+{
+ delete d;
+}
+
+/*!
+ \reimp
+*/
+void TQSplashScreen::mousePressEvent( TQMouseEvent * )
+{
+ hide();
+}
+
+/*!
+ This overrides TQWidget::tqrepaint(). It differs from the standard
+ tqrepaint function in that it also calls TQApplication::flush() to
+ ensure the updates are displayed, even when there is no event loop
+ present.
+*/
+void TQSplashScreen::tqrepaint()
+{
+ drawContents();
+ TQWidget::tqrepaint();
+ TQApplication::flush();
+}
+
+/*!
+ \fn TQSplashScreen::messageChanged( const TQString &message )
+
+ This signal is emitted when the message on the splash screen
+ changes. \a message is the new message and is a null-string
+ when the message has been removed.
+
+ \sa message(), clear()
+*/
+
+
+
+/*!
+ Draws the \a message text onto the splash screen with color \a
+ color and aligns the text according to the flags in \a tqalignment.
+
+ \sa TQt::AlignmentFlags clear()
+*/
+void TQSplashScreen::message( const TQString &message, int tqalignment,
+ const TQColor &color )
+{
+ d->currtqStatus = message;
+ d->currAlign = tqalignment;
+ d->currColor = color;
+ emit messageChanged( d->currtqStatus );
+ tqrepaint();
+}
+
+/*!
+ Removes the message being displayed on the splash screen
+
+ \sa message()
+ */
+void TQSplashScreen::clear()
+{
+ d->currtqStatus = TQString::null;
+ emit messageChanged( d->currtqStatus );
+ tqrepaint();
+}
+
+/*!
+ Makes the splash screen wait until the widget \a mainWin is displayed
+ before calling close() on itself.
+*/
+void TQSplashScreen::finish( TQWidget *mainWin )
+{
+ if ( mainWin ) {
+#if defined(TQ_WS_X11)
+ extern void qt_wait_for_window_manager( TQWidget *mainWin );
+ qt_wait_for_window_manager( mainWin );
+#endif
+ }
+ close();
+}
+
+/*!
+ Sets the pixmap that will be used as the splash screen's image to
+ \a pixmap.
+*/
+void TQSplashScreen::setPixmap( const TQPixmap &pixmap )
+{
+ d->pixmap = pixmap;
+ TQRect r(0, 0, d->pixmap.size().width(), d->pixmap.size().height());
+ resize( d->pixmap.size() );
+ move( TQApplication::desktop()->screenGeometry().center() - r.center() );
+ tqrepaint();
+}
+
+/*!
+ Returns the pixmap that is used in the splash screen. The image
+ does not have any of the text drawn by message() calls.
+*/
+TQPixmap* TQSplashScreen::pixmap() const
+{
+ return &( d->pixmap );
+}
+
+/*!
+ \internal
+*/
+void TQSplashScreen::drawContents()
+{
+ TQPixmap textPix = d->pixmap;
+ TQPainter painter( &textPix, this );
+ drawContents( &painter );
+ setErasePixmap( textPix );
+}
+
+/*!
+ Draw the contents of the splash screen using painter \a painter.
+ The default implementation draws the message passed by message().
+ Reimplement this function if you want to do your own drawing on
+ the splash screen.
+*/
+void TQSplashScreen::drawContents( TQPainter *painter )
+{
+ painter->setPen( d->currColor );
+ TQRect r = rect();
+ r.setRect( r.x() + 5, r.y() + 5, r.width() - 10, r.height() - 10 );
+ painter->drawText( r, d->currAlign, d->currtqStatus );
+}
+
+#endif //TQT_NO_SPLASHSCREEN
diff --git a/tqtinterface/qt4/src/widgets/tqsplashscreen.h b/tqtinterface/qt4/src/widgets/tqsplashscreen.h
new file mode 100644
index 0000000..3487b2a
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqsplashscreen.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Definition of TQSplashScreen class
+**
+** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSPLASHSCREEN_H
+#define TQSPLASHSCREEN_H
+
+#ifndef TQT_H
+#include "tqpixmap.h"
+#include "tqwidget.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SPLASHSCREEN
+class TQSplashScreenPrivate;
+
+class TQ_EXPORT TQSplashScreen : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQSplashScreen( const TQPixmap &pixmap = TQPixmap(), WFlags f = 0 );
+ virtual ~TQSplashScreen();
+
+ void setPixmap( const TQPixmap &pixmap );
+ TQPixmap* pixmap() const;
+ void finish( TQWidget *w );
+ void tqrepaint();
+
+public Q_SLOTS:
+ void message( const TQString &str, int flags = Qt::AlignLeft,
+ const TQColor &color = Qt::black );
+ void clear();
+
+Q_SIGNALS:
+ void messageChanged( const TQString &str );
+
+protected:
+ virtual void drawContents( TQPainter *painter );
+ void mousePressEvent( TQMouseEvent * );
+
+private:
+ void drawContents();
+
+ TQSplashScreenPrivate *d;
+};
+#endif //TQT_NO_SPLASHSCREEN
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqsplitter.cpp b/tqtinterface/qt4/src/widgets/tqsplitter.cpp
new file mode 100644
index 0000000..2750a45
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqsplitter.cpp
@@ -0,0 +1,1427 @@
+/****************************************************************************
+**
+** Implementation of TQSplitter class
+**
+** Created : 980105
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsplitter.h"
+#ifndef TQT_NO_SPLITTER
+
+#include "tqlayout.h"
+#include "../kernel/tqlayoutengine_p.h"
+#include "tqapplication.h"
+#include "tqbitmap.h"
+#include "tqdrawutil.h"
+#include "tqmemarray.h"
+#include "tqobjectlist.h"
+#include "tqpainter.h"
+#include "tqptrlist.h"
+#include "tqstyle.h"
+
+class TQSplitterHandle : public TQWidget
+{
+ TQ_OBJECT
+public:
+ TQSplitterHandle( Qt::Orientation o,
+ TQSplitter *tqparent, const char* name=0 );
+ void setOrientation( Qt::Orientation o );
+ Qt::Orientation orientation() const { return orient; }
+
+ bool opaque() const { return s->opaqueResize(); }
+
+ TQSize tqsizeHint() const;
+
+ int id() const { return myId; } // d->list.at(id())->wid == this
+ void setId( int i ) { myId = i; }
+
+protected:
+ void paintEvent( TQPaintEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+
+private:
+ Qt::Orientation orient;
+ bool opaq;
+ int myId;
+
+ TQSplitter *s;
+};
+
+#include "tqsplitter.tqmoc"
+
+const uint Default = 2;
+
+static int mouseOffset;
+static int opaqueOldPos = -1; // this assumes that there's only one mouse
+
+static TQPoint toggle( TQWidget *w, TQPoint pos )
+{
+ TQSize minS = tqSmartMinSize( w );
+ return -pos - TQPoint( minS.width(), minS.height() );
+}
+
+static bool isCollapsed( TQWidget *w )
+{
+ return w->x() < 0 || w->y() < 0;
+}
+
+static TQPoint topLeft( TQWidget *w )
+{
+ if ( isCollapsed(w) ) {
+ return toggle( w, w->pos() );
+ } else {
+ return w->pos();
+ }
+}
+
+static TQPoint bottomRight( TQWidget *w )
+{
+ if ( isCollapsed(w) ) {
+ return toggle( w, w->pos() ) - TQPoint( 1, 1 );
+ } else {
+ return w->tqgeometry().bottomRight();
+ }
+}
+
+TQSplitterHandle::TQSplitterHandle( Qt::Orientation o, TQSplitter *tqparent,
+ const char * name )
+ : TQWidget( tqparent, name )
+{
+ s = tqparent;
+ setOrientation( o );
+}
+
+TQSize TQSplitterHandle::tqsizeHint() const
+{
+ int hw = s->handleWidth();
+ return parentWidget()->tqstyle().tqsizeFromContents( TQStyle::CT_Splitter, s,
+ TQSize(hw, hw) )
+ .expandedTo( TQApplication::globalStrut() );
+}
+
+void TQSplitterHandle::setOrientation( Qt::Orientation o )
+{
+ orient = o;
+#ifndef TQT_NO_CURSOR
+ setCursor( o == Qt::Horizontal ? Qt::SplitHCursor : Qt::SplitVCursor );
+#endif
+}
+
+void TQSplitterHandle::mouseMoveEvent( TQMouseEvent *e )
+{
+ if ( !(e->state()&Qt::LeftButton) )
+ return;
+ TQCOORD pos = s->pick( parentWidget()->mapFromGlobal(e->globalPos()) )
+ - mouseOffset;
+ if ( opaque() ) {
+ s->moveSplitter( pos, id() );
+ } else {
+ s->setRubberband( s->adjustPos(pos, id()) );
+ }
+}
+
+void TQSplitterHandle::mousePressEvent( TQMouseEvent *e )
+{
+ if ( e->button() == Qt::LeftButton )
+ mouseOffset = s->pick( e->pos() );
+}
+
+void TQSplitterHandle::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( !opaque() && e->button() == Qt::LeftButton ) {
+ TQCOORD pos = s->pick( parentWidget()->mapFromGlobal(e->globalPos()) )
+ - mouseOffset;
+ s->setRubberband( -1 );
+ s->moveSplitter( pos, id() );
+ }
+}
+
+void TQSplitterHandle::paintEvent( TQPaintEvent * )
+{
+ TQPainter p( this );
+ parentWidget()->tqstyle().tqdrawPrimitive( TQStyle::PE_Splitter, &p, rect(),
+ tqcolorGroup(),
+ (TQStyle::SFlags)(orientation() == Qt::Horizontal ?
+ TQStyle::Style_Horizontal : 0) );
+}
+
+class TQSplitterLayoutStruct : public TQt
+{
+public:
+ TQCOORD sizer;
+ uint isHandle : 1;
+ uint collapsible : 2;
+ uint resizeMode : 2;
+ TQWidget *wid;
+
+ TQSplitterLayoutStruct()
+ : sizer( -1 ), collapsible( Default ) { }
+ TQCOORD getSizer( Qt::Orientation orient );
+};
+
+TQCOORD TQSplitterLayoutStruct::getSizer( Qt::Orientation orient )
+{
+ if ( sizer == -1 ) {
+ TQSize s = wid->tqsizeHint();
+ if ( !s.isValid() || wid->testWState(WState_Resized) )
+ s = wid->size();
+ sizer = ( orient == Qt::Horizontal ) ? s.width() : s.height();
+ }
+ return sizer;
+}
+
+class TQSplitterPrivate
+{
+public:
+ TQSplitterPrivate()
+ : opaque( FALSE ), firstShow( TRUE ), tqchildrenCollapsible( TRUE ),
+ handleWidth( 0 ) { }
+
+ TQPtrList<TQSplitterLayoutStruct> list;
+ bool opaque : 8;
+ bool firstShow : 8;
+ bool tqchildrenCollapsible : 8;
+ int handleWidth;
+};
+
+
+/*!
+ \class TQSplitter
+ \brief The TQSplitter class implements a splitter widget.
+
+ \ingroup organizers
+ \mainclass
+
+ A splitter lets the user control the size of child widgets by
+ dragging the boundary between the tqchildren. Any number of widgets
+ may be controlled by a single splitter.
+
+ To show a TQListBox, a TQListView and a TQTextEdit side by side:
+ \code
+ TQSplitter *split = new TQSplitter( tqparent );
+ TQListBox *lb = new TQListBox( split );
+ TQListView *lv = new TQListView( split );
+ TQTextEdit *ed = new TQTextEdit( split );
+ \endcode
+
+ TQSplitter lays out its tqchildren horizontally (side by side); you
+ can use setOrientation(TQSplitter::Vertical) to lay out the
+ tqchildren vertically.
+
+ By default, all widgets can be as large or as small as the user
+ wishes, between the \l tqminimumSizeHint() (or \l tqminimumSize())
+ and \l tqmaximumSize() of the widgets. Use setResizeMode() to
+ specify that a widget should keep its size when the splitter is
+ resized, or set the stretch component of the \l sizePolicy.
+
+ Although TQSplitter normally resizes the tqchildren only at the end
+ of a resize operation, if you call setOpaqueResize(TRUE) the
+ widgets are resized as often as possible.
+
+ The initial distribution of size between the widgets is determined
+ by the initial size of each widget. You can also use setSizes() to
+ set the sizes of all the widgets. The function sizes() returns the
+ sizes set by the user.
+
+ If you hide() a child its space will be distributed among the
+ other tqchildren. It will be reinstated when you show() it again. It
+ is also possible to reorder the widgets within the splitter using
+ moveToFirst() and moveToLast().
+
+ <img src=qsplitter-m.png> <img src=qsplitter-w.png>
+
+ \sa TQTabBar
+*/
+
+
+/*!
+ Constructs a horizontal splitter with the \a tqparent and \a name
+ arguments being passed on to the TQFrame constructor.
+*/
+
+TQSplitter::TQSplitter( TQWidget *tqparent, const char *name )
+ : TQFrame( tqparent, name, TQt::WPaintUnclipped )
+{
+ orient = Qt::Horizontal;
+ init();
+}
+
+
+/*!
+ Constructs a splitter with orientation \a o with the \a tqparent and
+ \a name arguments being passed on to the TQFrame constructor.
+*/
+
+TQSplitter::TQSplitter( Qt::Orientation o, TQWidget *tqparent, const char *name )
+ : TQFrame( tqparent, name, TQt::WPaintUnclipped )
+{
+ orient = o;
+ init();
+}
+
+
+/*!
+ Destroys the splitter and any tqchildren.
+*/
+
+TQSplitter::~TQSplitter()
+{
+ delete d;
+}
+
+
+void TQSplitter::init()
+{
+ d = new TQSplitterPrivate;
+ d->list.setAutoDelete( TRUE );
+ TQSizePolicy sp( TQSizePolicy::Expanding, TQSizePolicy::Preferred );
+ if ( orient == Qt::Vertical )
+ sp.transpose();
+ tqsetSizePolicy( sp );
+ clearWState( TQt::WState_OwnSizePolicy );
+}
+
+/*!
+ \fn void TQSplitter::refresh()
+
+ Updates the splitter's state. You should not need to call this
+ function.
+*/
+
+
+/*!
+ \property TQSplitter::orientation
+ \brief the orientation of the splitter
+
+ By default the orientation is horizontal (the widgets are side by
+ side). The possible orientations are \c Qt::Horizontal and
+ \c Qt::Vertical.
+*/
+
+void TQSplitter::setOrientation( Qt::Orientation o )
+{
+ if ( orient == o )
+ return;
+
+ if ( !testWState( TQt::WState_OwnSizePolicy ) ) {
+ TQSizePolicy sp = tqsizePolicy();
+ sp.transpose();
+ tqsetSizePolicy( sp );
+ clearWState( TQt::WState_OwnSizePolicy );
+ }
+
+ orient = o;
+
+ TQSplitterLayoutStruct *s = d->list.first();
+ while ( s ) {
+ if ( s->isHandle )
+ ((TQSplitterHandle*)s->wid)->setOrientation( o );
+ s = d->list.next();
+ }
+ recalc( isVisible() );
+}
+
+/*!
+ \property TQSplitter::tqchildrenCollapsible
+ \brief whether child widgets can be resized down to size 0 by the user
+
+ By default, tqchildren are collapsible. It is possible to enable
+ and disable the collapsing of individual tqchildren; see
+ setCollapsible().
+*/
+
+void TQSplitter::setChildrenCollapsible( bool collapse )
+{
+ d->tqchildrenCollapsible = collapse;
+}
+
+bool TQSplitter::tqchildrenCollapsible() const
+{
+ return d->tqchildrenCollapsible;
+}
+
+/*!
+ Sets whether the child widget \a w is collapsible to \a collapse.
+
+ By default, tqchildren are collapsible, meaning that the user can
+ resize them down to size 0, even if they have a non-zero
+ tqminimumSize() or tqminimumSizeHint(). This behavior can be changed
+ on a per-widget basis by calling this function, or globally for
+ all the widgets in the splitter by setting the \l
+ tqchildrenCollapsible property.
+
+ \sa tqchildrenCollapsible
+*/
+
+void TQSplitter::setCollapsible( TQWidget *w, bool collapse )
+{
+ tqfindWidget( w )->collapsible = collapse ? 1 : 0;
+}
+
+/*!
+ \reimp
+*/
+void TQSplitter::resizeEvent( TQResizeEvent * )
+{
+ doResize();
+}
+
+TQSplitterLayoutStruct *TQSplitter::tqfindWidget( TQWidget *w )
+{
+ processChildEvents();
+ TQSplitterLayoutStruct *s = d->list.first();
+ while ( s ) {
+ if ( s->wid == w )
+ return s;
+ s = d->list.next();
+ }
+ return addWidget( w );
+}
+
+/*
+ Inserts the widget \a w at the end (or at the beginning if \a
+ prepend is TRUE) of the splitter's list of widgets.
+
+ It is the responsibility of the caller to make sure that \a w is
+ not already in the splitter and to call recalcId() if needed. (If
+ \a prepend is TRUE, then recalcId() is very probably needed.)
+*/
+
+TQSplitterLayoutStruct *TQSplitter::addWidget( TQWidget *w, bool prepend )
+{
+ TQSplitterLayoutStruct *s;
+ TQSplitterHandle *newHandle = 0;
+ if ( d->list.count() > 0 ) {
+ s = new TQSplitterLayoutStruct;
+ s->resizeMode = KeepSize;
+ TQString tmp = "qt_splithandle_";
+ tmp += w->name();
+ newHandle = new TQSplitterHandle( orientation(), this, tmp );
+ s->wid = newHandle;
+ newHandle->setId( d->list.count() );
+ s->isHandle = TRUE;
+ s->sizer = pick( newHandle->tqsizeHint() );
+ if ( prepend )
+ d->list.prepend( s );
+ else
+ d->list.append( s );
+ }
+ s = new TQSplitterLayoutStruct;
+ s->resizeMode = DefaultResizeMode;
+ s->wid = w;
+ s->isHandle = FALSE;
+ if ( prepend )
+ d->list.prepend( s );
+ else
+ d->list.append( s );
+ if ( newHandle && isVisible() )
+ newHandle->show(); // will trigger sending of post events
+ return s;
+}
+
+
+/*!
+ Tells the splitter that the child widget described by \a c has
+ been inserted or removed.
+*/
+
+void TQSplitter::childEvent( TQChildEvent *c )
+{
+ if ( c->type() == TQEvent::ChildInserted ) {
+ if ( !c->child()->isWidgetType() )
+ return;
+
+ if ( ((TQWidget*)c->child())->testWFlags( TQt::WType_TopLevel ) )
+ return;
+
+ TQSplitterLayoutStruct *s = d->list.first();
+ while ( s ) {
+ if ( s->wid == c->child() )
+ return;
+ s = d->list.next();
+ }
+ addWidget( (TQWidget*)c->child() );
+ recalc( isVisible() );
+ } else if ( c->type() == TQEvent::ChildRemoved ) {
+ TQSplitterLayoutStruct *prev = 0;
+ if ( d->list.count() > 1 )
+ prev = d->list.at( 1 ); // yes, this is correct
+ TQSplitterLayoutStruct *curr = d->list.first();
+ while ( curr ) {
+ if ( curr->wid == c->child() ) {
+ d->list.removeRef( curr );
+ if ( prev && prev->isHandle ) {
+ TQWidget *w = prev->wid;
+ d->list.removeRef( prev );
+ delete w; // will call childEvent()
+ }
+ recalcId();
+ doResize();
+ return;
+ }
+ prev = curr;
+ curr = d->list.next();
+ }
+ }
+}
+
+
+/*!
+ Displays a rubber band at position \a p. If \a p is negative, the
+ rubber band is removed.
+*/
+
+void TQSplitter::setRubberband( int p )
+{
+ TQPainter paint( this );
+ paint.setPen( Qt::gray );
+ paint.setBrush( Qt::gray );
+ paint.setRasterOp( TQt::XorROP );
+ TQRect r = contentsRect();
+ const int rBord = 3; // customizable?
+ int hw = handleWidth();
+ if ( orient == Qt::Horizontal ) {
+ if ( opaqueOldPos >= 0 )
+ paint.drawRect( opaqueOldPos + hw / 2 - rBord, r.y(),
+ 2 * rBord, r.height() );
+ if ( p >= 0 )
+ paint.drawRect( p + hw / 2 - rBord, r.y(), 2 * rBord, r.height() );
+ } else {
+ if ( opaqueOldPos >= 0 )
+ paint.drawRect( r.x(), opaqueOldPos + hw / 2 - rBord,
+ r.width(), 2 * rBord );
+ if ( p >= 0 )
+ paint.drawRect( r.x(), p + hw / 2 - rBord, r.width(), 2 * rBord );
+ }
+ opaqueOldPos = p;
+}
+
+
+/*!
+ \reimp
+*/
+
+bool TQSplitter::event( TQEvent *e )
+{
+ switch ( e->type() ) {
+ case TQEvent::Show:
+ if ( !d->firstShow )
+ break;
+ d->firstShow = FALSE;
+ // fall through
+ case TQEvent::LayoutHint:
+ recalc( isVisible() );
+ break;
+ default:
+ ;
+ }
+ return TQWidget::event( e );
+}
+
+
+/*!
+ \obsolete
+
+ Draws the splitter handle in the rectangle described by \a x, \a y,
+ \a w, \a h using painter \a p.
+ \sa TQStyle::tqdrawPrimitive()
+*/
+
+// ### Remove this in 4.0
+
+void TQSplitter::drawSplitter( TQPainter *p,
+ TQCOORD x, TQCOORD y, TQCOORD w, TQCOORD h )
+{
+ tqstyle().tqdrawPrimitive(TQStyle::PE_Splitter, p, TQRect(x, y, w, h), tqcolorGroup(),
+ (TQStyle::SFlags)(orientation() == Qt::Horizontal ?
+ TQStyle::Style_Horizontal : 0));
+}
+
+
+/*!
+ Returns the ID of the widget to the right of or below the widget
+ \a w, or 0 if there is no such widget (i.e. it is either not in
+ this TQSplitter or \a w is at the end).
+*/
+
+int TQSplitter::idAfter( TQWidget* w ) const
+{
+ TQSplitterLayoutStruct *s = d->list.first();
+ bool seen_w = FALSE;
+ while ( s ) {
+ if ( s->isHandle && seen_w )
+ return d->list.at();
+ if ( !s->isHandle && s->wid == w )
+ seen_w = TRUE;
+ s = d->list.next();
+ }
+ return 0;
+}
+
+
+/*!
+ Moves the left/top edge of the splitter handle with ID \a id as
+ close as possible to position \a p, which is the distance from the
+ left (or top) edge of the widget.
+
+ For Arabic, Hebrew and other right-to-left languages the tqlayout is
+ reversed. \a p is then the distance from the right (or top) edge
+ of the widget.
+
+ \sa idAfter()
+*/
+void TQSplitter::moveSplitter( TQCOORD p, int id )
+{
+ TQSplitterLayoutStruct *s = d->list.at( id );
+ int farMin;
+ int min;
+ int max;
+ int farMax;
+
+ p = adjustPos( p, id, &farMin, &min, &max, &farMax );
+ int oldP = pick( s->wid->pos() );
+
+ if ( TQApplication::reverseLayout() && orient == Qt::Horizontal ) {
+ int q = p + s->wid->width();
+ doMove( FALSE, q, id - 1, -1, (q > oldP), (p > max) );
+ doMove( TRUE, q, id, -1, (q > oldP), (p < min) );
+ } else {
+ doMove( FALSE, p, id, +1, (p < oldP), (p > max) );
+ doMove( TRUE, p, id - 1, +1, (p < oldP), (p < min) );
+ }
+ storeSizes();
+}
+
+
+void TQSplitter::setGeo( TQWidget *w, int p, int s, bool splitterMoved )
+{
+ TQRect r;
+ if ( orient == Qt::Horizontal ) {
+ if ( TQApplication::reverseLayout() && orient == Qt::Horizontal
+ && !splitterMoved )
+ p = contentsRect().width() - p - s;
+ r.setRect( p, contentsRect().y(), s, contentsRect().height() );
+ } else {
+ r.setRect( contentsRect().x(), p, contentsRect().width(), s );
+ }
+
+ /*
+ Hide the child widget, but without calling hide() so that the
+ splitter handle is still shown.
+ */
+ if ( !w->isHidden() && s <= 0 && pick(tqSmartMinSize(w)) > 0 )
+ r.moveTopLeft( toggle(w, r.topLeft()) );
+ w->setGeometry( r );
+}
+
+
+void TQSplitter::doMove( bool backwards, int pos, int id, int delta, bool upLeft,
+ bool mayCollapse )
+{
+ if ( id < 0 || id >= (int) d->list.count() )
+ return;
+
+ TQSplitterLayoutStruct *s = d->list.at( id );
+ TQWidget *w = s->wid;
+
+ int nextId = backwards ? id - delta : id + delta;
+
+ if ( w->isHidden() ) {
+ doMove( backwards, pos, nextId, delta, upLeft, TRUE );
+ } else {
+ if ( s->isHandle ) {
+ int dd = s->getSizer( orient );
+ int nextPos = backwards ? pos - dd : pos + dd;
+ int left = backwards ? pos - dd : pos;
+ setGeo( w, left, dd, TRUE );
+ doMove( backwards, nextPos, nextId, delta, upLeft, mayCollapse );
+ } else {
+ int dd = backwards ? pos - pick( topLeft(w) )
+ : pick( bottomRight(w) ) - pos + 1;
+ if ( dd > 0 || (!isCollapsed(w) && !mayCollapse) ) {
+ dd = TQMAX( pick(tqSmartMinSize(w)),
+ TQMIN(dd, pick(w->tqmaximumSize())) );
+ } else {
+ dd = 0;
+ }
+ setGeo( w, backwards ? pos - dd : pos, dd, TRUE );
+ doMove( backwards, backwards ? pos - dd : pos + dd, nextId, delta,
+ upLeft, TRUE );
+ }
+ }
+}
+
+int TQSplitter::tqfindWidgetJustBeforeOrJustAfter( int id, int delta, int &collapsibleSize )
+{
+ id += delta;
+ do {
+ TQWidget *w = d->list.at( id )->wid;
+ if ( !w->isHidden() ) {
+ if ( collapsible(d->list.at(id)) )
+ collapsibleSize = pick( tqSmartMinSize(w) );
+ return id;
+ }
+ id += 2 * delta; // go to previous (or next) widget, skip the handle
+ } while ( id >= 0 && id < (int)d->list.count() );
+
+ return -1;
+}
+
+void TQSplitter::getRange( int id, int *farMin, int *min, int *max, int *farMax )
+{
+ int n = d->list.count();
+ if ( id <= 0 || id >= n - 1 )
+ return;
+
+ int collapsibleSizeBefore = 0;
+ int idJustBefore = tqfindWidgetJustBeforeOrJustAfter( id, -1, collapsibleSizeBefore );
+
+ int collapsibleSizeAfter = 0;
+ int idJustAfter = tqfindWidgetJustBeforeOrJustAfter( id, +1, collapsibleSizeAfter );
+
+ int minBefore = 0;
+ int minAfter = 0;
+ int maxBefore = 0;
+ int maxAfter = 0;
+ int i;
+
+ for ( i = 0; i < id; i++ )
+ addContribution( i, &minBefore, &maxBefore, i == idJustBefore );
+ for ( i = id; i < n; i++ )
+ addContribution( i, &minAfter, &maxAfter, i == idJustAfter );
+
+ TQRect r = contentsRect();
+ int farMinVal;
+ int minVal;
+ int maxVal;
+ int farMaxVal;
+
+ int smartMinBefore = TQMAX( minBefore, pick(r.size()) - maxAfter );
+ int smartMaxBefore = TQMIN( maxBefore, pick(r.size()) - minAfter );
+
+ if ( orient == Qt::Vertical || !TQApplication::reverseLayout() ) {
+ minVal = pick( r.topLeft() ) + smartMinBefore;
+ maxVal = pick( r.topLeft() ) + smartMaxBefore;
+
+ farMinVal = minVal;
+ if ( minBefore - collapsibleSizeBefore >= pick(r.size()) - maxAfter )
+ farMinVal -= collapsibleSizeBefore;
+ farMaxVal = maxVal;
+ if ( pick(r.size()) - (minAfter - collapsibleSizeAfter) <= maxBefore )
+ farMaxVal += collapsibleSizeAfter;
+ } else {
+ int hw = handleWidth();
+ minVal = r.width() - smartMaxBefore - hw;
+ maxVal = r.width() - smartMinBefore - hw;
+
+ farMinVal = minVal;
+ if ( pick(r.size()) - (minAfter - collapsibleSizeAfter) <= maxBefore )
+ farMinVal -= collapsibleSizeAfter;
+ farMaxVal = maxVal;
+ if ( minBefore - collapsibleSizeBefore >= pick(r.size()) - maxAfter )
+ farMaxVal += collapsibleSizeBefore;
+ }
+
+ if ( farMin )
+ *farMin = farMinVal;
+ if ( min )
+ *min = minVal;
+ if ( max )
+ *max = maxVal;
+ if ( farMax )
+ *farMax = farMaxVal;
+}
+
+/*!
+ Returns the valid range of the splitter with ID \a id in \a *min
+ and \a *max if \a min and \a max are not 0.
+
+ \sa idAfter()
+*/
+
+void TQSplitter::getRange( int id, int *min, int *max )
+{
+ getRange( id, min, 0, 0, max );
+}
+
+
+/*!
+ Returns the closest legal position to \a pos of the widget with ID
+ \a id.
+
+ \sa idAfter()
+*/
+
+int TQSplitter::adjustPos( int pos, int id )
+{
+ int x, i, n, u;
+ return adjustPos( pos, id, &u, &n, &i, &x );
+}
+
+int TQSplitter::adjustPos( int pos, int id, int *farMin, int *min, int *max,
+ int *farMax )
+{
+ const int Threshold = 40;
+
+ getRange( id, farMin, min, max, farMax );
+
+ if ( pos >= *min ) {
+ if ( pos <= *max ) {
+ return pos;
+ } else {
+ int delta = pos - *max;
+ int width = *farMax - *max;
+
+ if ( delta > width / 2 && delta >= TQMIN(Threshold, width) ) {
+ return *farMax;
+ } else {
+ return *max;
+ }
+ }
+ } else {
+ int delta = *min - pos;
+ int width = *min - *farMin;
+
+ if ( delta > width / 2 && delta >= TQMIN(Threshold, width) ) {
+ return *farMin;
+ } else {
+ return *min;
+ }
+ }
+}
+
+bool TQSplitter::collapsible( TQSplitterLayoutStruct *s )
+{
+ if (pick(tqSmartMinSize(s->wid)) == 1)
+ return FALSE;
+ if ( s->collapsible != Default ) {
+ return (bool) s->collapsible;
+ } else {
+ return d->tqchildrenCollapsible;
+ }
+}
+
+void TQSplitter::doResize()
+{
+ TQRect r = contentsRect();
+ int n = d->list.count();
+ TQMemArray<TQLayoutStruct> a( n );
+
+ for ( int pass = 0; pass < 2; pass++ ) {
+ int numAutoWithStretch = 0;
+ int numAutoWithoutStretch = 0;
+
+ for ( int i = 0; i < n; i++ ) {
+ a[i].init();
+ TQSplitterLayoutStruct *s = d->list.at( i );
+ if ( s->wid->isHidden() || isCollapsed(s->wid) ) {
+ a[i].tqmaximumSize = 0;
+ } else if ( s->isHandle ) {
+ a[i].tqsizeHint = a[i].tqminimumSize = a[i].tqmaximumSize = s->sizer;
+ a[i].empty = FALSE;
+ } else {
+ int mode = s->resizeMode;
+ int stretch = 1;
+
+ if ( mode == DefaultResizeMode ) {
+ TQSizePolicy p = s->wid->tqsizePolicy();
+ int sizePolicyStretch =
+ pick( TQSize(p.horStretch(), p.verStretch()) );
+ if ( sizePolicyStretch > 0 ) {
+ mode = Stretch;
+ stretch = sizePolicyStretch;
+ numAutoWithStretch++;
+ } else {
+ /*
+ Do things differently on the second pass,
+ if there's one. A second pass is necessary
+ if it was found out during the first pass
+ that all DefaultResizeMode items are
+ KeepSize items. In that case, we make them
+ all Stretch items instead, for a more TQt
+ 3.0-compatible behavior.
+ */
+ mode = ( pass == 0 ) ? KeepSize : Stretch;
+ numAutoWithoutStretch++;
+ }
+ }
+
+ a[i].tqminimumSize = pick( tqSmartMinSize(s->wid) );
+ a[i].tqmaximumSize = pick( s->wid->tqmaximumSize() );
+ a[i].empty = FALSE;
+
+ if ( mode == Stretch ) {
+ if ( s->getSizer(orient) > 1 )
+ stretch *= s->getSizer( orient );
+ // TQMIN(): ad hoc work-around for tqlayout engine limitation
+ a[i].stretch = TQMIN( stretch, 8192 );
+ a[i].tqsizeHint = a[i].tqminimumSize;
+ } else if ( mode == KeepSize ) {
+ a[i].tqsizeHint = s->getSizer( orient );
+ } else { // mode == FollowSizeHint
+ a[i].tqsizeHint = pick( s->wid->tqsizeHint() );
+ }
+ }
+ }
+
+ // a second pass would yield the same results
+ if ( numAutoWithStretch > 0 || numAutoWithoutStretch == 0 )
+ break;
+ }
+
+ qGeomCalc( a, 0, n, pick( r.topLeft() ), pick( r.size() ), 0 );
+
+ for ( int i = 0; i < n; i++ ) {
+ TQSplitterLayoutStruct *s = d->list.at(i);
+ setGeo( s->wid, a[i].pos, a[i].size, FALSE );
+ }
+}
+
+void TQSplitter::recalc( bool update )
+{
+ int fi = 2 * frameWidth();
+ int maxl = fi;
+ int minl = fi;
+ int maxt = TQWIDGETSIZE_MAX;
+ int mint = fi;
+ int n = d->list.count();
+ bool first = TRUE;
+
+ /*
+ Splitter handles before the first visible widget or right
+ before a hidden widget must be hidden.
+ */
+ for ( int i = 0; i < n; i++ ) {
+ TQSplitterLayoutStruct *s = d->list.at( i );
+ if ( !s->isHandle ) {
+ TQSplitterLayoutStruct *p = 0;
+ if ( i > 0 )
+ p = d->list.at( i - 1 );
+
+ // may trigger new recalc
+ if ( p && p->isHandle )
+ p->wid->setHidden( first || s->wid->isHidden() );
+
+ if ( !s->wid->isHidden() )
+ first = FALSE;
+ }
+ }
+
+ bool empty = TRUE;
+ for ( int j = 0; j < n; j++ ) {
+ TQSplitterLayoutStruct *s = d->list.at( j );
+ if ( !s->wid->isHidden() ) {
+ empty = FALSE;
+ if ( s->isHandle ) {
+ minl += s->getSizer( orient );
+ maxl += s->getSizer( orient );
+ } else {
+ TQSize minS = tqSmartMinSize( s->wid );
+ minl += pick( minS );
+ maxl += pick( s->wid->tqmaximumSize() );
+ mint = TQMAX( mint, trans(minS) );
+ int tm = trans( s->wid->tqmaximumSize() );
+ if ( tm > 0 )
+ maxt = TQMIN( maxt, tm );
+ }
+ }
+ }
+ if ( empty ) {
+ if ( ::tqqt_cast<TQSplitter*>(parentWidget()) ) {
+ // nested splitters; be nice
+ maxl = maxt = 0;
+ } else {
+ // TQSplitter with no tqchildren yet
+ maxl = TQWIDGETSIZE_MAX;
+ }
+ } else {
+ maxl = TQMIN( maxl, TQWIDGETSIZE_MAX );
+ }
+ if ( maxt < mint )
+ maxt = mint;
+
+ if ( orient == Qt::Horizontal ) {
+ setMaximumSize( maxl, maxt );
+ setMinimumSize( minl, mint );
+ } else {
+ setMaximumSize( maxt, maxl );
+ setMinimumSize( mint, minl );
+ }
+ if ( update )
+ doResize();
+ else
+ d->firstShow = TRUE;
+}
+
+/*!
+ \enum TQSplitter::ResizeMode
+
+ This enum type describes how TQSplitter will resize each of its
+ child widgets.
+
+ \value Auto The widget will be resized according to the stretch
+ factors set in its sizePolicy().
+
+ \value Stretch The widget will be resized when the splitter
+ itself is resized.
+
+ \value KeepSize TQSplitter will try to keep the widget's size
+ unchanged.
+
+ \value FollowSizeHint TQSplitter will resize the widget when the
+ widget's size hint changes.
+*/
+
+/*!
+ Sets resize mode of widget \a w to \a mode. (The default is \c
+ Auto.)
+*/
+
+void TQSplitter::setResizeMode( TQWidget *w, ResizeMode mode )
+{
+ tqfindWidget( w )->resizeMode = mode;
+}
+
+
+/*!
+ \property TQSplitter::opaqueResize
+ \brief whether resizing is opaque
+
+ Opaque resizing is off by default.
+*/
+
+bool TQSplitter::opaqueResize() const
+{
+ return d->opaque;
+}
+
+
+void TQSplitter::setOpaqueResize( bool on )
+{
+ d->opaque = on;
+}
+
+
+/*!
+ Moves widget \a w to the leftmost/top position.
+*/
+
+void TQSplitter::moveToFirst( TQWidget *w )
+{
+ processChildEvents();
+ bool found = FALSE;
+ TQSplitterLayoutStruct *s = d->list.first();
+ while ( s ) {
+ if ( s->wid == w ) {
+ found = TRUE;
+ TQSplitterLayoutStruct *p = d->list.prev();
+ if ( p ) { // not already at first place
+ d->list.take(); // take p
+ d->list.take(); // take s
+ d->list.prepend( p );
+ d->list.prepend( s );
+ }
+ break;
+ }
+ s = d->list.next();
+ }
+ if ( !found )
+ addWidget( w, TRUE );
+ recalcId();
+}
+
+
+/*!
+ Moves widget \a w to the rightmost/bottom position.
+*/
+
+void TQSplitter::moveToLast( TQWidget *w )
+{
+ processChildEvents();
+ bool found = FALSE;
+ TQSplitterLayoutStruct *s = d->list.first();
+ while ( s ) {
+ if ( s->wid == w ) {
+ found = TRUE;
+ d->list.take(); // take s
+ TQSplitterLayoutStruct *p = d->list.current();
+ if ( p ) { // the splitter handle after s
+ d->list.take(); // take p
+ d->list.append( p );
+ }
+ d->list.append( s );
+ break;
+ }
+ s = d->list.next();
+ }
+ if ( !found )
+ addWidget( w );
+ recalcId();
+}
+
+
+void TQSplitter::recalcId()
+{
+ int n = d->list.count();
+ for ( int i = 0; i < n; i++ ) {
+ TQSplitterLayoutStruct *s = d->list.at( i );
+ if ( s->isHandle )
+ ((TQSplitterHandle*)s->wid)->setId( i );
+ }
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQSplitter::tqsizeHint() const
+{
+ constPolish();
+ int l = 0;
+ int t = 0;
+ if ( !childrenListObject().isEmpty() ) {
+ TQObjectListIt it( childrenListObject() );
+ TQObject * o;
+
+ while( (o = it.current()) != 0 ) {
+ ++it;
+ if ( o->isWidgetType() && !((TQWidget*)o)->isHidden() ) {
+ TQSize s = ((TQWidget*)o)->tqsizeHint();
+ if ( s.isValid() ) {
+ l += pick( s );
+ t = TQMAX( t, trans( s ) );
+ }
+ }
+ }
+ }
+ return orientation() == Qt::Horizontal ? TQSize( l, t ) : TQSize( t, l );
+}
+
+
+/*!
+ \reimp
+*/
+
+TQSize TQSplitter::tqminimumSizeHint() const
+{
+ constPolish();
+ int l = 0;
+ int t = 0;
+ if ( !childrenListObject().isEmpty() ) {
+ TQObjectListIt it( childrenListObject() );
+ TQObject * o;
+
+ while ( (o = it.current()) != 0 ) {
+ ++it;
+ if ( o->isWidgetType() && !((TQWidget*)o)->isHidden() ) {
+ TQSize s = tqSmartMinSize( (TQWidget*)o );
+ if ( s.isValid() ) {
+ l += pick( s );
+ t = TQMAX( t, trans( s ) );
+ }
+ }
+ }
+ }
+ return orientation() == Qt::Horizontal ? TQSize( l, t ) : TQSize( t, l );
+}
+
+
+void TQSplitter::storeSizes()
+{
+ TQSplitterLayoutStruct *s = d->list.first();
+ while ( s ) {
+ if ( !s->isHandle )
+ s->sizer = pick( s->wid->size() );
+ s = d->list.next();
+ }
+}
+
+
+void TQSplitter::addContribution( int id, int *min, int *max,
+ bool mayCollapse )
+{
+ TQSplitterLayoutStruct *s = d->list.at( id );
+ if ( !s->wid->isHidden() ) {
+ if ( s->isHandle ) {
+ *min += s->getSizer( orient );
+ *max += s->getSizer( orient );
+ } else {
+ if ( mayCollapse || !isCollapsed(s->wid) )
+ *min += pick( tqSmartMinSize(s->wid) );
+ *max += pick( s->wid->tqmaximumSize() );
+ }
+ }
+}
+
+
+/*!
+ Returns a list of the size parameters of all the widgets in this
+ splitter.
+
+ If the splitter's orientation is horizontal, the list is a list of
+ widget widths; if the orientation is vertical, the list is a list
+ of widget heights.
+
+ Giving the values to another splitter's setSizes() function will
+ produce a splitter with the same tqlayout as this one.
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQValueList<int> list = mySplitter.sizes();
+ TQValueList<int>::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+
+ \sa setSizes()
+*/
+
+TQValueList<int> TQSplitter::sizes() const
+{
+ if ( !testWState(TQt::WState_Polished) )
+ constPolish();
+
+ TQValueList<int> list;
+ TQSplitterLayoutStruct *s = d->list.first();
+ while ( s ) {
+ if ( !s->isHandle )
+ list.append( isCollapsed(s->wid) ? 0 : pick(s->wid->size()));
+ s = d->list.next();
+ }
+ return list;
+}
+
+/*!
+ Sets the size parameters to the values given in the \a list. If
+ the splitter is horizontal, the values set the widths of each
+ widget going from left to right. If the splitter is vertical, the
+ values set the heights of each widget going from top to bottom.
+ Extra values in the \a list are ignored.
+
+ If \a list tqcontains too few values, the result is undefined but
+ the program will still be well-behaved.
+
+ Note that the values in \a list should be the height/width that
+ the widgets should be resized to.
+
+ \sa sizes()
+*/
+
+void TQSplitter::setSizes( TQValueList<int> list )
+{
+ processChildEvents();
+ TQValueList<int>::Iterator it = list.begin();
+ TQSplitterLayoutStruct *s = d->list.first();
+ while ( s && it != list.end() ) {
+ if ( !s->isHandle ) {
+ s->sizer = TQMAX( *it, 0 );
+ int smartMinSize = pick( tqSmartMinSize(s->wid) );
+ // Make sure that we reset the collapsed state.
+ if ( s->sizer == 0 ) {
+ if ( collapsible(s) && smartMinSize > 0 ) {
+ s->wid->move( -1, -1 );
+ } else {
+ s->sizer = smartMinSize;
+ s->wid->move( 0, 0 );
+ }
+ } else {
+ if ( s->sizer < smartMinSize )
+ s->sizer = smartMinSize;
+ s->wid->move( 0, 0 );
+ }
+ ++it;
+ }
+ s = d->list.next();
+ }
+ doResize();
+}
+
+/*!
+ \property TQSplitter::handleWidth
+ \brief the width of the splitter handle
+*/
+
+int TQSplitter::handleWidth() const
+{
+ if ( d->handleWidth > 0 ) {
+ return d->handleWidth;
+ } else {
+ return tqstyle().tqpixelMetric( TQStyle::PM_SplitterWidth, this );
+ }
+}
+
+void TQSplitter::setHandleWidth( int width )
+{
+ d->handleWidth = width;
+ updateHandles();
+}
+
+/*!
+ Processes all posted child events, ensuring that the internal state of
+ the splitter is kept consistent.
+*/
+
+void TQSplitter::processChildEvents()
+{
+ TQApplication::sendPostedEvents( this, TQEvent::ChildInserted );
+}
+
+/*!
+ \reimp
+*/
+
+void TQSplitter::styleChange( TQStyle& old )
+{
+ updateHandles();
+ TQFrame::styleChange( old );
+}
+
+void TQSplitter::updateHandles()
+{
+ int hw = handleWidth();
+ TQSplitterLayoutStruct *s = d->list.first();
+ while ( s ) {
+ if ( s->isHandle )
+ s->sizer = hw;
+ s = d->list.next();
+ }
+ recalc( isVisible() );
+}
+
+#ifndef TQT_NO_TEXTSTREAM
+/*!
+ \relates TQSplitter
+
+ Writes the sizes and the hidden state of the widgets in the
+ splitter \a splitter to the text stream \a ts.
+
+ \sa operator>>(), sizes(), TQWidget::isHidden()
+*/
+
+TQTextStream& operator<<( TQTextStream& ts, const TQSplitter& splitter )
+{
+ TQSplitterLayoutStruct *s = splitter.d->list.first();
+ bool first = TRUE;
+ ts << "[";
+
+ while ( s != 0 ) {
+ if ( !s->isHandle ) {
+ if ( !first )
+ ts << ",";
+
+ if ( s->wid->isHidden() ) {
+ ts << "H";
+ } else if ( isCollapsed(s->wid) ) {
+ ts << 0;
+ } else {
+ ts << s->getSizer( splitter.orientation() );
+ }
+ first = FALSE;
+ }
+ s = splitter.d->list.next();
+ }
+ ts << "]" << endl;
+ return ts;
+}
+
+/*!
+ \relates TQSplitter
+
+ Reads the sizes and the hidden state of the widgets in the
+ splitter \a splitter from the text stream \a ts. The sizes must
+ have been previously written by the operator<<() function.
+
+ \sa operator<<(), setSizes(), TQWidget::hide()
+*/
+
+TQTextStream& operator>>( TQTextStream& ts, TQSplitter& splitter )
+{
+#undef SKIP_SPACES
+#define SKIP_SPACES() \
+ while ( line[i].isSpace() ) \
+ i++
+
+ splitter.processChildEvents();
+ TQSplitterLayoutStruct *s = splitter.d->list.first();
+ TQString line = ts.readLine();
+ int i = 0;
+
+ SKIP_SPACES();
+ if ( line[i] == '[' ) {
+ i++;
+ SKIP_SPACES();
+ while ( line[i] != ']' ) {
+ while ( s != 0 && s->isHandle )
+ s = splitter.d->list.next();
+ if ( s == 0 )
+ break;
+
+ if ( line[i].upper() == 'H' ) {
+ s->wid->hide();
+ i++;
+ } else {
+ s->wid->show();
+ int dim = 0;
+ while ( line[i].digitValue() >= 0 ) {
+ dim *= 10;
+ dim += line[i].digitValue();
+ i++;
+ }
+ s->sizer = dim;
+ if ( dim == 0 )
+ splitter.setGeo( s->wid, 0, 0, FALSE );
+ }
+ SKIP_SPACES();
+ if ( line[i] == ',' ) {
+ i++;
+ } else {
+ break;
+ }
+ SKIP_SPACES();
+ s = splitter.d->list.next();
+ }
+ }
+ splitter.doResize();
+ return ts;
+}
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqsplitter.h b/tqtinterface/qt4/src/widgets/tqsplitter.h
new file mode 100644
index 0000000..b9d536d
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqsplitter.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Definition of TQSplitter class
+**
+** Created : 980105
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSPLITTER_H
+#define TQSPLITTER_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#include "tqvaluelist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_SPLITTER
+
+class TQSplitterHandle;
+class TQSplitterPrivate;
+class TQSplitterLayoutStruct;
+class TQTextStream;
+
+class TQ_EXPORT TQSplitter : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( Qt::Orientation orientation READ orientation WRITE setOrientation )
+ Q_PROPERTY( bool opaqueResize READ opaqueResize WRITE setOpaqueResize )
+ Q_PROPERTY( int handleWidth READ handleWidth WRITE setHandleWidth )
+ Q_PROPERTY( bool tqchildrenCollapsible READ tqchildrenCollapsible WRITE setChildrenCollapsible )
+
+public:
+ // ### TQt 4.0: remove Auto from public API
+ enum ResizeMode { Stretch, KeepSize, FollowSizeHint, Auto };
+
+ TQSplitter( TQWidget* tqparent = 0, const char* name = 0 );
+ TQSplitter( Qt::Orientation, TQWidget* tqparent = 0, const char* name = 0 );
+ ~TQSplitter();
+
+ virtual void setOrientation( Qt::Orientation );
+ Qt::Orientation orientation() const { return orient; }
+
+ // ### TQt 4.0: make setChildrenCollapsible() and setCollapsible() virtual
+
+ void setChildrenCollapsible( bool );
+ bool tqchildrenCollapsible() const;
+
+ void setCollapsible( TQWidget *w, bool );
+ virtual void setResizeMode( TQWidget *w, ResizeMode );
+ virtual void setOpaqueResize( bool = TRUE );
+ bool opaqueResize() const;
+
+ void moveToFirst( TQWidget * );
+ void moveToLast( TQWidget * );
+
+ void refresh() { recalc( TRUE ); }
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ TQValueList<int> sizes() const;
+ void setSizes( TQValueList<int> );
+
+ int handleWidth() const;
+ void setHandleWidth( int );
+
+protected:
+ void childEvent( TQChildEvent * );
+
+ bool event( TQEvent * );
+ void resizeEvent( TQResizeEvent * );
+
+ int idAfter( TQWidget* ) const;
+
+ void moveSplitter( TQCOORD pos, int id );
+ virtual void drawSplitter( TQPainter*, TQCOORD x, TQCOORD y,
+ TQCOORD w, TQCOORD h );
+ void styleChange( TQStyle& );
+ int adjustPos( int, int );
+ virtual void setRubberband( int );
+ void getRange( int id, int *, int * );
+
+private:
+ enum { DefaultResizeMode = 3 };
+
+ void init();
+ void recalc( bool update = FALSE );
+ void doResize();
+ void storeSizes();
+ void getRange( int id, int *, int *, int *, int * );
+ void addContribution( int, int *, int *, bool );
+ int adjustPos( int, int, int *, int *, int *, int * );
+ bool collapsible( TQSplitterLayoutStruct * );
+ void processChildEvents();
+ TQSplitterLayoutStruct *tqfindWidget( TQWidget * );
+ TQSplitterLayoutStruct *addWidget( TQWidget *, bool prepend = FALSE );
+ void recalcId();
+ void doMove( bool backwards, int pos, int id, int delta, bool upLeft,
+ bool mayCollapse );
+ void setGeo( TQWidget *w, int pos, int size, bool splitterMoved );
+ int tqfindWidgetJustBeforeOrJustAfter( int id, int delta, int &collapsibleSize );
+ void updateHandles();
+
+ inline TQCOORD pick( const TQPoint &p ) const
+ { return orient == Qt::Horizontal ? p.x() : p.y(); }
+ inline TQCOORD pick( const TQSize &s ) const
+ { return orient == Qt::Horizontal ? s.width() : s.height(); }
+
+ inline TQCOORD trans( const TQPoint &p ) const
+ { return orient == Qt::Vertical ? p.x() : p.y(); }
+ inline TQCOORD trans( const TQSize &s ) const
+ { return orient == Qt::Vertical ? s.width() : s.height(); }
+
+ TQSplitterPrivate *d;
+
+ Qt::Orientation orient;
+ friend class TQSplitterHandle;
+
+#ifndef TQT_NO_TEXTSTREAM
+ friend TQ_EXPORT TQTextStream& operator<<( TQTextStream&, const TQSplitter& );
+ friend TQ_EXPORT TQTextStream& operator>>( TQTextStream&, TQSplitter& );
+#endif
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQSplitter( const TQSplitter & );
+ TQSplitter& operator=( const TQSplitter & );
+#endif
+};
+
+#ifndef TQT_NO_TEXTSTREAM
+TQ_EXPORT TQTextStream& operator<<( TQTextStream&, const TQSplitter& );
+TQ_EXPORT TQTextStream& operator>>( TQTextStream&, TQSplitter& );
+#endif
+
+#endif // TQT_NO_SPLITTER
+
+#endif // TQSPLITTER_H
diff --git a/tqtinterface/qt4/src/widgets/tqstatusbar.cpp b/tqtinterface/qt4/src/widgets/tqstatusbar.cpp
new file mode 100644
index 0000000..6dbe4a4
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqstatusbar.cpp
@@ -0,0 +1,526 @@
+/****************************************************************************
+**
+** Implementation of TQStatusBar class
+**
+** Created : 980119
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqstatusbar.h"
+#ifndef TQT_NO_STATUSBAR
+
+#include "tqptrlist.h"
+#include "tqlayout.h"
+#include "tqpainter.h"
+#include "tqtimer.h"
+#include "tqdrawutil.h"
+#include "tqstyle.h"
+#include "tqsizegrip.h"
+
+/*!
+ \class TQStatusBar tqstatusbar.h
+ \brief The TQStatusBar class provides a horizontal bar suitable for
+ presenting status information.
+
+ \ingroup application
+ \ingroup helpsystem
+ \mainclass
+
+ Each status indicator falls into one of three categories:
+
+ \list
+ \i \e Temporary - briefly occupies most of the status bar. Used
+ to explain tool tip texts or menu entries, for example.
+ \i \e Normal - occupies part of the status bar and may be hidden
+ by temporary messages. Used to display the page and line
+ number in a word processor, for example.
+ \i \e Permanent - is never hidden. Used for important mode
+ indications, for example, some applications put a Caps Lock
+ indicator in the status bar.
+ \endlist
+
+ TQStatusBar lets you display all three types of indicators.
+
+ To display a \e temporary message, call message() (perhaps by
+ connecting a suitable signal to it). To remove a temporary
+ message, call clear(). There are two variants of message(): one
+ that displays the message until the next clear() or message() and
+ one that has a time limit:
+
+ \code
+ connect( loader, TQT_SIGNAL(progressMessage(const TQString&)),
+ statusBar(), TQT_SLOT(message(const TQString&)) );
+
+ statusBar()->message("Loading..."); // Initial message
+ loader.loadStuff(); // Emits progress messages
+ statusBar()->message("Done.", 2000); // Final message for 2 seconds
+ \endcode
+
+ \e Normal and \e Permanent messages are displayed by creating a
+ small widget and then adding it to the status bar with
+ addWidget(). Widgets like TQLabel, TQProgressBar or even TQToolButton
+ are useful for adding to status bars. removeWidget() is used to
+ remove widgets.
+
+ \code
+ statusBar()->addWidget(new MyReadWriteIndication(statusBar()));
+ \endcode
+
+ By default TQStatusBar provides a TQSizeGrip in the lower-right
+ corner. You can disable it with setSizeGripEnabled(FALSE);
+
+ <img src=qstatusbar-m.png> <img src=qstatusbar-w.png>
+
+ \sa TQToolBar TQMainWindow TQLabel
+ \link guibooks.html#fowler GUI Design Handbook: tqStatus Bar.\endlink
+*/
+
+
+class TQStatusBarPrivate
+{
+public:
+ TQStatusBarPrivate() {}
+
+ struct SBItem {
+ SBItem( TQWidget* widget, int stretch, bool permanent )
+ : s( stretch ), w( widget ), p( permanent ) {}
+ int s;
+ TQWidget * w;
+ bool p;
+ };
+
+ TQPtrList<SBItem> items;
+ TQString tempItem;
+
+ TQBoxLayout * box;
+ TQTimer * timer;
+
+#ifndef TQT_NO_SIZEGRIP
+ TQSizeGrip * resizer;
+#endif
+
+ int savedStrut;
+};
+
+
+/*!
+ Constructs a status bar called \a name with tqparent \a tqparent and
+ with a size grip.
+
+ \sa setSizeGripEnabled()
+*/
+TQStatusBar::TQStatusBar( TQWidget * tqparent, const char *name )
+ : TQWidget( tqparent, name )
+{
+ d = new TQStatusBarPrivate;
+ d->items.setAutoDelete( TRUE );
+ d->box = 0;
+ d->timer = 0;
+
+#ifndef TQT_NO_SIZEGRIP
+ d->resizer = 0;
+ setSizeGripEnabled(TRUE); // causes reformat()
+#else
+ reformat();
+#endif
+}
+
+
+/*!
+ Destroys the status bar and frees any allocated resources and
+ child widgets.
+*/
+TQStatusBar::~TQStatusBar()
+{
+ delete d;
+ d = 0;
+}
+
+
+/*!
+ Adds \a widget to this status bar. \a widget is reparented if it
+ isn't already a child of the TQStatusBar.
+
+ \a widget is permanently visible if \a permanent is TRUE and may
+ be obscured by temporary messages if \a permanent is FALSE. The
+ default is FALSE.
+
+ If \a permanent is TRUE, \a widget is located at the far right of
+ the status bar. If \a permanent is FALSE (the default), \a widget
+ is located just to the left of the first permanent widget.
+
+ \a stretch is used to compute a suitable size for \a widget as the
+ status bar grows and shrinks. The default of 0 uses a minimum of
+ space.
+
+ This function may cause some flicker.
+
+ \sa removeWidget()
+*/
+
+void TQStatusBar::addWidget( TQWidget * widget, int stretch, bool permanent )
+{
+ if ( !widget ) {
+#if defined(TQT_CHECK_NULL)
+ qWarning( "TQStatusBar::addWidget(): Cannot add null widget" );
+#endif
+ return;
+ }
+
+ if ( widget->parentWidget() != this )
+ widget->reparent( this, TQPoint(0, 0), TRUE );
+
+ TQStatusBarPrivate::SBItem* item
+ = new TQStatusBarPrivate::SBItem( widget, stretch, permanent );
+
+ d->items.last();
+ while( !permanent && d->items.current() && d->items.current()->p )
+ d->items.prev();
+
+ d->items.insert( d->items.at() >= 0 ? d->items.at()+1 : 0, item );
+
+ if ( !d->tempItem.isEmpty() && !permanent )
+ widget->hide();
+
+ reformat();
+}
+
+
+/*!
+ Removes \a widget from the status bar.
+
+ This function may cause some flicker.
+
+ Note that \a widget is not deleted.
+
+ \sa addWidget()
+*/
+
+void TQStatusBar::removeWidget( TQWidget* widget )
+{
+ if ( !widget )
+ return;
+ bool found = FALSE;
+ TQStatusBarPrivate::SBItem* item = d->items.first();
+ while ( item && !found ) {
+ if ( item->w == widget ) {
+ d->items.remove();
+ found = TRUE;
+ }
+ item = d->items.next();
+ }
+
+ if ( found )
+ reformat();
+#if defined(TQT_DEBUG)
+ else
+ qDebug( "TQStatusBar::removeWidget(): Widget not found." );
+#endif
+}
+
+/*!
+ \property TQStatusBar::sizeGripEnabled
+ \brief whether the TQSizeGrip in the bottom right of the status bar is enabled
+
+ Enables or disables the TQSizeGrip in the bottom right of the
+ status bar. By default, the size grip is enabled.
+*/
+
+bool TQStatusBar::isSizeGripEnabled() const
+{
+#ifdef TQT_NO_SIZEGRIP
+ return FALSE;
+#else
+ return !!d->resizer;
+#endif
+}
+
+void TQStatusBar::setSizeGripEnabled(bool enabled)
+{
+#ifndef TQT_NO_SIZEGRIP
+ if ( !enabled != !d->resizer ) {
+ if ( enabled ) {
+ d->resizer = new TQSizeGrip( this, "TQStatusBar::resizer" );
+ } else {
+ delete d->resizer;
+ d->resizer = 0;
+ }
+ reformat();
+ if ( d->resizer && isVisible() )
+ d->resizer->show();
+ }
+#endif
+}
+
+
+/*!
+ Changes the status bar's appearance to account for item changes.
+ Special subclasses may need this, but tqgeometry management will
+ usually take care of any necessary rearrangements.
+*/
+void TQStatusBar::reformat()
+{
+ if ( d->box )
+ delete d->box;
+
+ TQBoxLayout *vbox;
+ if ( isSizeGripEnabled() ) {
+ d->box = new TQHBoxLayout( this );
+ vbox = new TQVBoxLayout( d->box );
+ } else {
+ vbox = d->box = new TQVBoxLayout( this );
+ }
+ vbox->addSpacing( 3 );
+ TQBoxLayout* l = new TQHBoxLayout( vbox );
+ l->addSpacing( 3 );
+ l->setSpacing( 4 );
+
+ int maxH = fontMetrics().height();
+
+ TQStatusBarPrivate::SBItem* item = d->items.first();
+ while ( item && !item->p ) {
+ l->addWidget( item->w, item->s );
+ int itemH = TQMIN(item->w->tqsizeHint().height(),
+ item->w->maximumHeight());
+ maxH = TQMAX( maxH, itemH );
+ item = d->items.next();
+ }
+
+ l->addStretch( 0 );
+
+ while ( item ) {
+ l->addWidget( item->w, item->s );
+ int itemH = TQMIN(item->w->tqsizeHint().height(),
+ item->w->maximumHeight());
+ maxH = TQMAX( maxH, itemH );
+ item = d->items.next();
+ }
+ l->addSpacing( 4 );
+#ifndef TQT_NO_SIZEGRIP
+ if ( d->resizer ) {
+ maxH = TQMAX( maxH, d->resizer->tqsizeHint().height() );
+ d->box->addSpacing( 1 );
+ d->box->addWidget( d->resizer, 0, Qt::AlignBottom );
+ }
+#endif
+ l->addStrut( maxH );
+ d->savedStrut = maxH;
+ vbox->addSpacing( 2 );
+ d->box->activate();
+ tqrepaint();
+}
+
+
+
+
+/*!
+ Hides the normal status indicators and displays \a message until
+ clear() or another message() is called.
+
+ \sa clear()
+*/
+void TQStatusBar::message( const TQString &message )
+{
+ if ( d->tempItem == message )
+ return;
+ d->tempItem = message;
+ if ( d->timer ) {
+ delete d->timer;
+ d->timer = 0;
+ }
+ hideOrShow();
+}
+
+
+/*!
+ \overload
+
+ Hides the normal status indications and displays \a message for \a
+ ms milli-seconds or until clear() or another message() is called,
+ whichever occurs first.
+*/
+void TQStatusBar::message( const TQString &message, int ms )
+{
+ d->tempItem = message;
+
+ if ( !d->timer ) {
+ d->timer = new TQTimer( this );
+ connect( d->timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(clear()) );
+ }
+ if ( ms > 0 ) {
+ d->timer->start( ms );
+ } else if ( d->timer ) {
+ delete d->timer;
+ d->timer = 0;
+ }
+
+ hideOrShow();
+}
+
+
+/*!
+ Removes any temporary message being shown.
+
+ \sa message()
+*/
+
+void TQStatusBar::clear()
+{
+ if ( d->tempItem.isEmpty() )
+ return;
+ if ( d->timer ) {
+ delete d->timer;
+ d->timer = 0;
+ }
+ d->tempItem = TQString::null;
+ hideOrShow();
+}
+
+/*!
+ \fn TQStatusBar::messageChanged( const TQString &message )
+
+ This signal is emitted when the temporary status messages
+ changes. \a message is the new temporary message, and is a
+ null-string when the message has been removed.
+
+ \sa message(), clear()
+*/
+
+/*!
+ Ensures that the right widgets are visible. Used by message() and
+ clear().
+*/
+void TQStatusBar::hideOrShow()
+{
+ bool haveMessage = !d->tempItem.isEmpty();
+
+ TQStatusBarPrivate::SBItem* item = d->items.first();
+
+ while( item && !item->p ) {
+ if ( haveMessage )
+ item->w->hide();
+ else
+ item->w->show();
+ item = d->items.next();
+ }
+
+ emit messageChanged( d->tempItem );
+ tqrepaint();
+}
+
+
+/*!
+ Shows the temporary message, if appropriate.
+*/
+void TQStatusBar::paintEvent( TQPaintEvent * )
+{
+ bool haveMessage = !d->tempItem.isEmpty();
+
+ TQPainter p( this );
+ TQStatusBarPrivate::SBItem* item = d->items.first();
+
+#ifndef TQT_NO_SIZEGRIP
+ int psx = ( d->resizer && d->resizer->isVisible() ) ? d->resizer->x() : width()-12;
+#else
+ int psx = width() - 12;
+#endif
+
+ while ( item ) {
+ if ( !haveMessage || item->p )
+ if ( item->w->isVisible() ) {
+ if ( item->p && item->w->x()-1 < psx )
+ psx = item->w->x()-1;
+ tqstyle().tqdrawPrimitive( TQStyle::PE_StatusBarSection, &p,
+ TQRect(item->w->x() - 1, item->w->y() - 1,
+ item->w->width()+2, item->w->height()+2),
+ tqcolorGroup(), TQStyle::Style_Default,
+ TQStyleOption(item->w) );
+ }
+ item = d->items.next();
+ }
+ if ( haveMessage ) {
+ p.setPen( tqcolorGroup().foreground() );
+ p.drawText( 6, 0, psx, height(), TQt::AlignVCenter | TQt::SingleLine, d->tempItem );
+ }
+}
+
+/*!
+ \reimp
+*/
+void TQStatusBar::resizeEvent( TQResizeEvent * e )
+{
+ TQWidget::resizeEvent( e );
+}
+
+/*!
+ \reimp
+*/
+
+bool TQStatusBar::event( TQEvent *e )
+{
+ if ( e->type() == TQEvent::LayoutHint ) {
+ // Calculate new strut height and call reformat() if it has changed
+ int maxH = fontMetrics().height();
+
+ TQStatusBarPrivate::SBItem* item = d->items.first();
+ while ( item ) {
+ int itemH = TQMIN(item->w->tqsizeHint().height(),
+ item->w->maximumHeight());
+ maxH = TQMAX( maxH, itemH );
+ item = d->items.next();
+ }
+
+#ifndef TQT_NO_SIZEGRIP
+ if ( d->resizer )
+ maxH = TQMAX( maxH, d->resizer->tqsizeHint().height() );
+#endif
+
+ if ( maxH != d->savedStrut )
+ reformat();
+ else
+ update();
+ }
+ if ( e->type() == TQEvent::ChildRemoved ) {
+ TQStatusBarPrivate::SBItem* item = d->items.first();
+ while ( item ) {
+ if ( item->w == ( (TQChildEvent*)e )->child() )
+ d->items.removeRef( item );
+ item = d->items.next();
+ }
+ }
+ return TQWidget::event( e );
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqstatusbar.h b/tqtinterface/qt4/src/widgets/tqstatusbar.h
new file mode 100644
index 0000000..8fc6cfc
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqstatusbar.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Definition of TQStatusBar class
+**
+** Created : 980316
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSTATUSBAR_H
+#define TQSTATUSBAR_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_STATUSBAR
+
+
+class TQStatusBarPrivate;
+
+
+class TQ_EXPORT TQStatusBar: public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool sizeGripEnabled READ isSizeGripEnabled WRITE setSizeGripEnabled )
+
+public:
+ TQStatusBar( TQWidget* tqparent=0, const char* name=0 );
+ virtual ~TQStatusBar();
+
+ virtual void addWidget( TQWidget *, int stretch = 0, bool = FALSE );
+ virtual void removeWidget( TQWidget * );
+
+ void setSizeGripEnabled(bool);
+ bool isSizeGripEnabled() const;
+
+public Q_SLOTS:
+ void message( const TQString &);
+ void message( const TQString &, int );
+ void clear();
+
+Q_SIGNALS:
+ void messageChanged( const TQString &text );
+
+protected:
+ void paintEvent( TQPaintEvent * );
+ void resizeEvent( TQResizeEvent * );
+
+ void reformat();
+ void hideOrShow();
+ bool event( TQEvent *);
+
+private:
+ TQStatusBarPrivate * d;
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQStatusBar( const TQStatusBar & );
+ TQStatusBar& operator=( const TQStatusBar & );
+#endif
+};
+
+#endif // TQT_NO_STATUSBAR
+
+#endif // TQSTATUSBAR_H
diff --git a/tqtinterface/qt4/src/widgets/tqsyntaxhighlighter.cpp b/tqtinterface/qt4/src/widgets/tqsyntaxhighlighter.cpp
new file mode 100644
index 0000000..aebaa6c
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqsyntaxhighlighter.cpp
@@ -0,0 +1,221 @@
+/****************************************************************************
+**
+** Implementation of the TQSyntaxHighlighter class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqsyntaxhighlighter.h"
+#include "private/tqsyntaxhighlighter_p.h"
+
+#ifndef TQT_NO_SYNTAXHIGHLIGHTER
+#include "../kernel/tqrichtext_p.h"
+#include "tqtextedit.h"
+#include "tqtimer.h"
+
+/*!
+ \class TQSyntaxHighlighter tqsyntaxhighlighter.h
+ \brief The TQSyntaxHighlighter class is a base class for
+ implementing TQTextEdit syntax highlighters.
+
+ \ingroup basic
+ \ingroup text
+
+ A syntax highligher automatically highlights parts of the text in
+ a TQTextEdit. Syntax highlighters are often used when the user is
+ entering text in a specific format (for example, source code) and
+ help the user to read the text and identify syntax errors.
+
+ To provide your own syntax highlighting for TQTextEdit, you must
+ subclass TQSyntaxHighlighter and reimplement highlightParagraph().
+
+ When you create an instance of your TQSyntaxHighlighter subclass,
+ pass it the TQTextEdit that you want the syntax highlighting to be
+ applied to. After this your highlightParagraph() function will be
+ called automatically whenever necessary. Use your
+ highlightParagraph() function to apply formatting (e.g. setting
+ the font and color) to the text that is passed to it.
+*/
+
+/*!
+ Constructs the TQSyntaxHighlighter and installs it on \a textEdit.
+
+ It is the caller's responsibility to delete the
+ TQSyntaxHighlighter when it is no longer needed.
+*/
+
+TQSyntaxHighlighter::TQSyntaxHighlighter( TQTextEdit *textEdit )
+ : para( 0 ), edit( textEdit ), d( new TQSyntaxHighlighterPrivate )
+{
+ textEdit->document()->setPreProcessor( new TQSyntaxHighlighterInternal( this ) );
+ textEdit->document()->tqinvalidate();
+ TQTimer::singleShot( 0, textEdit->viewport(), TQT_SLOT( update() ) );
+}
+
+/*!
+ Destructor. Uninstalls this syntax highlighter from the textEdit()
+*/
+
+TQSyntaxHighlighter::~TQSyntaxHighlighter()
+{
+ delete d;
+ textEdit()->document()->setPreProcessor( 0 );
+}
+
+/*!
+ \fn int TQSyntaxHighlighter::highlightParagraph( const TQString &text, int endStateOfLastPara )
+
+ This function is called when necessary by the rich text engine,
+ i.e. on paragraphs which have changed.
+
+ In your reimplementation you should parse the paragraph's \a text
+ and call setFormat() as often as necessary to apply any font and
+ color changes that you require. Your function must return a value
+ which indicates the paragraph's end state: see below.
+
+ Some syntaxes can have constructs that span paragraphs. For
+ example, a C++ syntax highlighter should be able to cope with
+ \c{/}\c{*...*}\c{/} comments that span paragraphs. To deal
+ with these cases it is necessary to know the end state of the
+ previous paragraph (e.g. "in comment").
+
+ If your syntax does not have paragraph spanning constructs, simply
+ ignore the \a endStateOfLastPara parameter and always return 0.
+
+ Whenever highlightParagraph() is called it is passed a value for
+ \a endStateOfLastPara. For the very first paragraph this value is
+ always -2. For any other paragraph the value is the value returned
+ by the most recent highlightParagraph() call that applied to the
+ preceding paragraph.
+
+ The value you return is up to you. We recommend only returning 0
+ (to signify that this paragraph's syntax highlighting does not
+ affect the following paragraph), or a positive integer (to signify
+ that this paragraph has ended in the middle of a paragraph
+ spanning construct).
+
+ To tqfind out which paragraph is highlighted, call
+ currentParagraph().
+
+ For example, if you're writing a simple C++ syntax highlighter,
+ you might designate 1 to signify "in comment". For a paragraph
+ that ended in the middle of a comment you'd return 1, and for
+ other paragraphs you'd return 0. In your parsing code if \a
+ endStateOfLastPara was 1, you would highlight the text as a C++
+ comment until you reached the closing \c{*}\c{/}.
+*/
+
+/*!
+ This function is applied to the syntax highlighter's current
+ paragraph (the text of which is passed to the highlightParagraph()
+ function).
+
+ The specified \a font and \a color are applied to the text from
+ position \a start for \a count characters. (If \a count is 0,
+ nothing is done.)
+*/
+
+void TQSyntaxHighlighter::setFormat( int start, int count, const TQFont &font, const TQColor &color )
+{
+ if ( !para || count <= 0 )
+ return;
+ TQTextFormat *f = 0;
+ f = para->document()->formatCollection()->format( font, color );
+ para->setFormat( start, count, f );
+ f->removeRef();
+}
+
+/*! \overload */
+
+void TQSyntaxHighlighter::setFormat( int start, int count, const TQColor &color )
+{
+ if ( !para || count <= 0 )
+ return;
+ TQTextFormat *f = 0;
+ TQFont fnt = textEdit()->TQWidget::font();
+ f = para->document()->formatCollection()->format( fnt, color );
+ para->setFormat( start, count, f );
+ f->removeRef();
+}
+
+/*! \overload */
+
+void TQSyntaxHighlighter::setFormat( int start, int count, const TQFont &font )
+{
+ if ( !para || count <= 0 )
+ return;
+ TQTextFormat *f = 0;
+ TQColor c = textEdit()->viewport()->paletteForegroundColor();
+ f = para->document()->formatCollection()->format( font, c );
+ para->setFormat( start, count, f );
+ f->removeRef();
+}
+
+/*!
+ \fn TQTextEdit *TQSyntaxHighlighter::textEdit() const
+
+ Returns the TQTextEdit on which this syntax highlighter is
+ installed
+*/
+
+/*! Redoes the highlighting of the whole document.
+*/
+
+void TQSyntaxHighlighter::rehighlight()
+{
+ TQTextParagraph *s = edit->document()->firstParagraph();
+ while ( s ) {
+ s->tqinvalidate( 0 );
+ s->state = -1;
+ s->needPreProcess = TRUE;
+ s = s->next();
+ }
+ edit->repaintContents( FALSE );
+}
+
+/*!
+ Returns the id of the paragraph which is highlighted, or -1 of no
+ paragraph is currently highlighted.
+
+ Usually this function is called from within highlightParagraph().
+*/
+
+int TQSyntaxHighlighter::currentParagraph() const
+{
+ return d->currentParagraph;
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqsyntaxhighlighter.h b/tqtinterface/qt4/src/widgets/tqsyntaxhighlighter.h
new file mode 100644
index 0000000..dcadd03
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqsyntaxhighlighter.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Definition of the TQSyntaxHighlighter class
+**
+** Created : 022407
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSYNTAXHIGHLIGHTER_H
+#define TQSYNTAXHIGHLIGHTER_H
+
+#ifndef TQT_H
+#include "tqfont.h"
+#include "tqcolor.h"
+#include "tqstring.h"
+#endif // TQT_H
+
+class TQTextEdit;
+class TQSyntaxHighlighterInternal;
+class TQSyntaxHighlighterPrivate;
+class TQTextParagraph;
+
+class TQ_EXPORT TQSyntaxHighlighter : public TQt
+{
+ friend class TQSyntaxHighlighterInternal;
+
+public:
+ TQSyntaxHighlighter( TQTextEdit *textEdit );
+ virtual ~TQSyntaxHighlighter();
+
+ virtual int highlightParagraph( const TQString &text, int endStateOfLastPara ) = 0;
+
+ void setFormat( int start, int count, const TQFont &font, const TQColor &color );
+ void setFormat( int start, int count, const TQColor &color );
+ void setFormat( int start, int count, const TQFont &font );
+ TQTextEdit *textEdit() const { return edit; }
+
+ void rehighlight();
+
+ int currentParagraph() const;
+
+private:
+ TQTextParagraph *para;
+ TQTextEdit *edit;
+ TQSyntaxHighlighterPrivate *d;
+
+};
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqsyntaxhighlighter_p.h b/tqtinterface/qt4/src/widgets/tqsyntaxhighlighter_p.h
new file mode 100644
index 0000000..a1cc898
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqsyntaxhighlighter_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Definition of the internal TQSyntaxHighlighterInternal class
+**
+** Created : 031111
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQSYNTAXHIGHLIGHTER_P_H
+#define TQSYNTAXHIGHLIGHTER_P_H
+
+#ifndef TQT_NO_SYNTAXHIGHLIGHTER
+#include "tqsyntaxhighlighter.h"
+#include "private/tqrichtext_p.h"
+
+class TQSyntaxHighlighterPrivate
+{
+public:
+ TQSyntaxHighlighterPrivate() :
+ currentParagraph( -1 )
+ {}
+
+ int currentParagraph;
+};
+
+class TQSyntaxHighlighterInternal : public TQTextPreProcessor
+{
+public:
+ TQSyntaxHighlighterInternal( TQSyntaxHighlighter *h ) : highlighter( h ) {}
+ void process( TQTextDocument *doc, TQTextParagraph *p, int, bool tqinvalidate ) {
+ if ( p->prev() && p->prev()->endState() == -1 )
+ process( doc, p->prev(), 0, FALSE );
+
+ highlighter->para = p;
+ TQString text = p->string()->toString();
+ int endState = p->prev() ? p->prev()->endState() : -2;
+ int oldEndState = p->endState();
+ highlighter->d->currentParagraph = p->paragId();
+ p->setEndState( highlighter->highlightParagraph( text, endState ) );
+ highlighter->d->currentParagraph = -1;
+ highlighter->para = 0;
+
+ p->setFirstPreProcess( FALSE );
+ TQTextParagraph *op = p;
+ p = p->next();
+ if ( (!!oldEndState || !!op->endState()) && oldEndState != op->endState() &&
+ tqinvalidate && p && !p->firstPreProcess() && p->endState() != -1 ) {
+ while ( p ) {
+ if ( p->endState() == -1 )
+ return;
+ p->setEndState( -1 );
+ p = p->next();
+ }
+ }
+ }
+ TQTextFormat *format( int ) { return 0; }
+
+private:
+ TQSyntaxHighlighter *highlighter;
+
+ friend class TQTextEdit;
+};
+
+#endif // TQT_NO_SYNTAXHIGHLIGHTER
+#endif // TQSYNTAXHIGHLIGHTER_P_H
diff --git a/tqtinterface/qt4/src/widgets/tqtabbar.cpp b/tqtinterface/qt4/src/widgets/tqtabbar.cpp
new file mode 100644
index 0000000..dd31f44
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtabbar.cpp
@@ -0,0 +1,1368 @@
+/****************************************************************************
+**
+** Implementation of TQTab and TQTabBar classes
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtabbar.h"
+#ifndef TQT_NO_TABBAR
+#include "tqaccel.h"
+#include "tqbitmap.h"
+#include "tqtoolbutton.h"
+#include "tqtooltip.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+#include "tqpainter.h"
+#include "tqiconset.h"
+#include "tqcursor.h"
+#include "../kernel/tqinternal_p.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+
+#ifdef TQ_WS_MACX
+#include <tqmacstyle_mac.h>
+#endif
+
+
+/*!
+ \class TQTab tqtabbar.h
+ \brief The TQTab class provides the structures in a TQTabBar.
+
+ \ingroup advanced
+
+ This class is used for custom TQTabBar tab headings.
+
+ \sa TQTabBar
+*/
+
+
+/*!
+ Constructs an empty tab. All fields are set to empty.
+*/
+
+TQTab::TQTab()
+ : enabled( TRUE ),
+ id ( 0 ),
+ iconset( 0 ),
+ tb( 0 )
+{
+}
+
+/*!
+ Constructs a tab with the text \a text.
+*/
+
+TQTab::TQTab( const TQString &text )
+ : label( text ),
+ enabled( TRUE ),
+ id( 0 ),
+ iconset( 0 ),
+ tb( 0 )
+{
+}
+
+/*!
+ Constructs a tab with an \a icon and the text, \a text.
+*/
+
+TQTab::TQTab( const TQIconSet& icon, const TQString& text )
+ : label( text ),
+ enabled( TRUE ),
+ id( 0 ),
+ iconset( new TQIconSet(icon) ),
+ tb( 0 )
+{
+}
+
+/*!
+ \fn TQString TQTab::text() const
+
+ Returns the text of the TQTab label.
+*/
+
+/*!
+ \fn TQIconSet TQTab::iconSet() const
+
+ Return the TQIconSet of the TQTab.
+*/
+
+/*!
+ \fn void TQTab::setRect( const TQRect &rect )
+
+ Set the TQTab TQRect to \a rect.
+*/
+
+/*!
+ \fn TQRect TQTab::rect() const
+
+ Return the TQRect for the TQTab.
+*/
+
+/*!
+ \fn void TQTab::setEnabled( bool enable )
+
+ If \a enable is TRUE enable the TQTab, otherwise disable it.
+*/
+
+/*!
+ \fn bool TQTab::isEnabled() const
+
+ Returns TRUE if the TQTab is enabled; otherwise returns FALSE.
+*/
+
+/*!
+ \fn void TQTab::setIdentifier( int i )
+
+ Set the identifier for the TQTab to \a i. Each TQTab's identifier
+ within a TQTabBar must be unique.
+*/
+
+/*!
+ \fn int TQTab::identifier() const
+
+ Return the TQTab's identifier.
+*/
+
+
+
+/*!
+ Destroys the tab and frees up all allocated resources.
+*/
+
+TQTab::~TQTab()
+{
+ delete iconset;
+ tb = 0;
+}
+
+/*!
+ \class TQTabBar tqtabbar.h
+ \brief The TQTabBar class provides a tab bar, e.g. for use in tabbed dialogs.
+
+ \ingroup advanced
+
+ TQTabBar is straightforward to use; it draws the tabs using one of
+ the predefined \link TQTabBar::Shape tqshapes\endlink, and emits a
+ signal when a tab is selected. It can be subclassed to tailor the
+ look and feel. TQt also provides a ready-made \l{TQTabWidget} and a
+ \l{TQTabDialog}.
+
+ The choice of tab tqshape is a matter of taste, although tab dialogs
+ (for preferences and similar) invariably use \c RoundedAbove;
+ nobody uses \c TriangularAbove. Tab controls in windows other than
+ dialogs almost always use either \c RoundedBelow or \c
+ TriangularBelow. Many spreadsheets and other tab controls in which
+ all the pages are essentially similar use \c TriangularBelow,
+ whereas \c RoundedBelow is used mostly when the pages are
+ different (e.g. a multi-page tool palette).
+
+ The most important part of TQTabBar's API is the selected() signal.
+ This is emitted whenever the selected page changes (even at
+ startup, when the selected page changes from 'none'). There is
+ also a slot, setCurrentTab(), which can be used to select a page
+ programmatically.
+
+ TQTabBar creates automatic accelerator keys in the manner of
+ TQButton; e.g. if a tab's label is "\&Graphics", Alt+G becomes an
+ accelerator key for switching to that tab.
+
+ The following virtual functions may need to be reimplemented:
+ \list
+ \i paint() paints a single tab. paintEvent() calls paint() for
+ each tab so that any overlap will look right.
+ \i addTab() creates a new tab and adds it to the bar.
+ \i selectTab() decides which tab, if any, the user selects with the mouse.
+ \endlist
+
+ The index of the current tab is returned by currentTab(). The tab
+ with a particular index is returned by tabAt(), the tab with a
+ particular id is returned by tab(). The index of a tab is returned
+ by indexOf(). The current tab can be set by index or tab pointer
+ using one of the setCurrentTab() functions.
+
+ <img src=qtabbar-m.png> <img src=qtabbar-w.png>
+*/
+
+/*!
+ \enum TQTabBar::Shape
+
+ This enum type lists the built-in tqshapes supported by TQTabBar:
+
+ \value RoundedAbove the normal rounded look above the pages
+
+ \value RoundedBelow the normal rounded look below the pages
+
+ \value TriangularAbove triangular tabs above the pages (very
+ unusual; included for completeness)
+
+ \value TriangularBelow triangular tabs similar to those used in
+ the Excel spreadsheet, for example
+*/
+
+class TQTabBarToolTip;
+
+struct TQTabPrivate {
+ int id;
+ int focus;
+#ifndef TQT_NO_ACCEL
+ TQAccel * a;
+#endif
+ TQTab *pressed;
+ TQTabBar::Shape s;
+ TQToolButton* rightB;
+ TQToolButton* leftB;
+ int btnWidth;
+ bool scrolls;
+ TQTabBarToolTip * toolTips;
+};
+
+#ifndef TQT_NO_TOOLTIP
+/* \internal
+*/
+class TQTabBarToolTip : public TQToolTip
+{
+public:
+ TQTabBarToolTip( TQWidget * tqparent )
+ : TQToolTip( tqparent ) {}
+ virtual ~TQTabBarToolTip() {}
+
+ void add( TQTab * tab, const TQString & tip )
+ {
+ tabTips.tqreplace( tab, tip );
+ }
+
+ void remove( TQTab * tab )
+ {
+ tabTips.erase( tab );
+ }
+
+ TQString tipForTab( TQTab * tab ) const
+ {
+ TQMapConstIterator<TQTab *, TQString> it;
+ it = tabTips.tqfind( tab );
+ if ( it != tabTips.end() )
+ return it.data();
+ else
+ return TQString();
+ }
+
+protected:
+ void maybeTip( const TQPoint & p )
+ {
+ TQTabBar * tb = (TQTabBar *) parentWidget();
+ if ( !tb )
+ return;
+
+ // check if the scroll buttons in the tab bar are visible -
+ // don't display any tips if the pointer is over one of them
+ TQRect rectL, rectR;
+ rectL.setRect( tb->d->leftB->x(), tb->d->leftB->y(),
+ tb->d->leftB->width(), tb->d->leftB->height() );
+ rectR.setRect( tb->d->rightB->x(), tb->d->rightB->y(),
+ tb->d->rightB->width(), tb->d->rightB->height() );
+ if ( tb->d->scrolls && (rectL.tqcontains( p ) || rectR.tqcontains( p )) )
+ return;
+
+#ifndef TQT_NO_TOOLTIP
+ // tqfind and show the tool tip for the tab under the point p
+ TQMapIterator<TQTab *, TQString> it;
+ for ( it = tabTips.begin(); it != tabTips.end(); ++it ) {
+ if ( it.key()->rect().tqcontains( p ) )
+ tip( it.key()->rect(), it.data() );
+ }
+#endif
+ }
+
+private:
+ TQMap<TQTab *, TQString> tabTips;
+};
+#endif
+
+/*!
+ \fn void TQTabBar::selected( int id )
+
+ TQTabBar emits this signal whenever any tab is selected, whether by
+ the program or by the user. The argument \a id is the id of the
+ tab as returned by addTab().
+
+ show() is guaranteed to emit this signal; you can display your
+ page in a slot connected to this signal.
+*/
+
+/*!
+ \fn void TQTabBar::layoutChanged()
+
+ TQTabBar emits the signal whenever the tqlayout of the tab bar has
+ been recalculated, for example when the contents of a tab change.
+*/
+
+/*!
+ Constructs a new, empty tab bar; the \a tqparent and \a name
+ arguments are passed on to the TQWidget constructor.
+*/
+
+TQTabBar::TQTabBar( TQWidget * tqparent, const char *name )
+ : TQWidget( tqparent, name, (WFlags)(TQt::WNoAutoErase | TQt::WNoMousePropagation) )
+{
+ d = new TQTabPrivate;
+ d->pressed = 0;
+ d->id = 0;
+ d->focus = 0;
+ d->toolTips = 0;
+#ifndef TQT_NO_ACCEL
+ d->a = new TQAccel( this, "tab accelerators" );
+ connect( d->a, TQT_SIGNAL(activated(int)), this, TQT_SLOT(setCurrentTab(int)) );
+ connect( d->a, TQT_SIGNAL(activatedAmbiguously(int)), this, TQT_SLOT(setCurrentTab(int)) );
+#endif
+ d->s = RoundedAbove;
+ d->scrolls = FALSE;
+ d->leftB = new TQToolButton( TQt::LeftArrow, this, "qt_left_btn" );
+ connect( d->leftB, TQT_SIGNAL( clicked() ), this, TQT_SLOT( scrollTabs() ) );
+ d->leftB->hide();
+ d->rightB = new TQToolButton( TQt::RightArrow, this, "qt_right_btn" );
+ connect( d->rightB, TQT_SIGNAL( clicked() ), this, TQT_SLOT( scrollTabs() ) );
+ d->rightB->hide();
+ d->btnWidth = tqstyle().tqpixelMetric(TQStyle::PM_TabBarScrollButtonWidth, this);
+ l = new TQPtrList<TQTab>;
+ lstatic = new TQPtrList<TQTab>;
+ lstatic->setAutoDelete( TRUE );
+ setFocusPolicy( Qt::TabFocus );
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ) );
+}
+
+
+/*!
+ Destroys the tab control, freeing memory used.
+*/
+
+TQTabBar::~TQTabBar()
+{
+#ifndef TQT_NO_TOOLTIP
+ if ( d->toolTips )
+ delete d->toolTips;
+#endif
+ delete d;
+ d = 0;
+ delete l;
+ l = 0;
+ delete lstatic;
+ lstatic = 0;
+}
+
+
+/*!
+ Adds the tab, \a newTab, to the tab control.
+
+ Sets \a newTab's id to a new id and places the tab just to the
+ right of the existing tabs. If the tab's label tqcontains an
+ ampersand, the letter following the ampersand is used as an
+ accelerator for the tab, e.g. if the label is "Bro\&wse" then
+ Alt+W becomes an accelerator which will move the focus to this
+ tab. Returns the id.
+
+ \sa insertTab()
+*/
+
+int TQTabBar::addTab( TQTab * newTab )
+{
+ return insertTab( newTab );
+}
+
+
+/*!
+ Inserts the tab, \a newTab, into the tab control.
+
+ If \a index is not specified, the tab is simply appended.
+ Otherwise it's inserted at the specified position.
+
+ Sets \a newTab's id to a new id. If the tab's label tqcontains an
+ ampersand, the letter following the ampersand is used as an
+ accelerator for the tab, e.g. if the label is "Bro\&wse" then
+ Alt+W becomes an accelerator which will move the focus to this
+ tab. Returns the id.
+
+ \sa addTab()
+*/
+
+int TQTabBar::insertTab( TQTab * newTab, int index )
+{
+ newTab->id = d->id++;
+ if ( !tab( d->focus ) )
+ d->focus = newTab->id;
+
+ newTab->setTabBar( this );
+ l->insert( 0, newTab );
+ if ( index < 0 || index > int(lstatic->count()) )
+ lstatic->append( newTab );
+ else
+ lstatic->insert( index, newTab );
+
+ layoutTabs();
+ updateArrowButtons();
+ makeVisible( tab( currentTab() ) );
+
+#ifndef TQT_NO_ACCEL
+ int p = TQAccel::shortcutKey( newTab->label );
+ if ( p )
+ d->a->insertItem( p, newTab->id );
+#endif
+
+ return newTab->id;
+}
+
+
+/*!
+ Removes tab \a t from the tab control, and deletes the tab.
+*/
+void TQTabBar::removeTab( TQTab * t )
+{
+ //#### accelerator labels??
+#ifndef TQT_NO_TOOLTIP
+ if ( d->toolTips )
+ d->toolTips->remove( t );
+#endif
+#ifndef TQT_NO_ACCEL
+ if ( d->a )
+ d->a->removeItem( t->id );
+#endif
+ bool updateFocus = t->id == d->focus;
+ // remove the TabBar Reference
+ if(d->pressed == t)
+ d->pressed = 0;
+ t->setTabBar( 0 );
+ l->remove( t );
+ lstatic->remove( t );
+ layoutTabs();
+ updateArrowButtons();
+ makeVisible( tab( currentTab() ) );
+ if ( updateFocus )
+ d->focus = currentTab();
+ update();
+}
+
+
+/*!
+ Enables tab \a id if \a enabled is TRUE or disables it if \a
+ enabled is FALSE. If \a id is currently selected,
+ setTabEnabled(FALSE) makes another tab selected.
+
+ setTabEnabled() updates the display if this causes a change in \a
+ id's status.
+
+ \sa update(), isTabEnabled()
+*/
+
+void TQTabBar::setTabEnabled( int id, bool enabled )
+{
+ TQTab * t;
+ for( t = l->first(); t; t = l->next() ) {
+ if ( t && t->id == id ) {
+ if ( t->enabled != enabled ) {
+ t->enabled = enabled;
+#ifndef TQT_NO_ACCEL
+ d->a->setItemEnabled( t->id, enabled );
+#endif
+ TQRect r( t->r );
+ if ( !enabled && id == currentTab() ) {
+ TQPoint p1( t->r.center() ), p2;
+ int m = 2147483647;
+ int distance;
+ // look for the closest enabled tab - measure the
+ // distance between the centers of the two tabs
+ for( TQTab * n = l->first(); n; n = l->next() ) {
+ if ( n->enabled ) {
+ p2 = n->r.center();
+ distance = (p2.x() - p1.x())*(p2.x() - p1.x()) +
+ (p2.y() - p1.y())*(p2.y() - p1.y());
+ if ( distance < m ) {
+ t = n;
+ m = distance;
+ }
+ }
+ }
+ if ( t->enabled ) {
+ r = r.unite( t->r );
+ l->append( l->take( l->tqfindRef( t ) ) );
+ emit selected( t->id );
+ }
+ }
+ tqrepaint( r, FALSE );
+ }
+ return;
+ }
+ }
+}
+
+
+/*!
+ Returns TRUE if the tab with id \a id exists and is enabled;
+ otherwise returns FALSE.
+
+ \sa setTabEnabled()
+*/
+
+bool TQTabBar::isTabEnabled( int id ) const
+{
+ TQTab * t = tab( id );
+ if ( t )
+ return t->enabled;
+ return FALSE;
+}
+
+
+
+/*!
+ \reimp
+*/
+TQSize TQTabBar::tqsizeHint() const
+{
+ TQSize sz(0, 0);
+ if ( TQTab * t = l->first() ) {
+ TQRect r( t->r );
+ while ( (t = l->next()) != 0 )
+ r = r.unite( t->r );
+ sz = r.size();
+ }
+ return sz.expandedTo(TQApplication::globalStrut());
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQTabBar::tqminimumSizeHint() const
+{
+ if(tqstyle().tqstyleHint( TQStyle::SH_TabBar_PreferNoArrows, this ))
+ return tqsizeHint();
+ return TQSize( d->rightB->tqsizeHint().width() * 2 + 75, tqsizeHint().height() );
+}
+
+/*!
+ Paints the tab \a t using painter \a p. If and only if \a selected
+ is TRUE, \a t is drawn currently selected.
+
+ This virtual function may be reimplemented to change the look of
+ TQTabBar. If you decide to reimplement it, you may also need to
+ reimplement tqsizeHint().
+*/
+
+void TQTabBar::paint( TQPainter * p, TQTab * t, bool selected ) const
+{
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+
+ if (isEnabled() && t->isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (tqtopLevelWidget() == tqApp->activeWindow())
+ flags |= TQStyle::Style_Active;
+ if ( selected )
+ flags |= TQStyle::Style_Selected;
+ else if(t == d->pressed)
+ flags |= TQStyle::Style_Sunken;
+ //selection flags
+ if(t->rect().tqcontains(mapFromGlobal(TQCursor::pos())))
+ flags |= TQStyle::Style_MouseOver;
+ tqstyle().tqdrawControl( TQStyle::CE_TabBarTab, p, this, t->rect(),
+ tqcolorGroup(), flags, TQStyleOption(t) );
+
+ TQRect r( t->r );
+ p->setFont( font() );
+
+ int iw = 0;
+ int ih = 0;
+ if ( t->iconset != 0 ) {
+ iw = t->iconset->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4;
+ ih = t->iconset->pixmap( TQIconSet::Small, TQIconSet::Normal ).height();
+ }
+ TQFontMetrics fm = p->fontMetrics();
+ int fw = fm.width( t->label );
+ fw -= t->label.tqcontains('&') * fm.width('&');
+ fw += t->label.tqcontains("&&") * fm.width('&');
+ int w = iw + fw + 4;
+ int h = TQMAX(fm.height() + 4, ih );
+ int offset = 3;
+#ifdef TQ_WS_MAC
+ if (::tqqt_cast<TQMacStyle *>(&tqstyle()))
+ offset = 0;
+#endif
+ paintLabel( p, TQRect( r.left() + (r.width()-w)/2 - offset,
+ r.top() + (r.height()-h)/2,
+ w, h ), t, t->id == keyboardFocusTab() );
+}
+
+/*!
+ Paints the label of tab \a t centered in rectangle \a br using
+ painter \a p. A focus indication is drawn if \a has_focus is TRUE.
+*/
+
+void TQTabBar::paintLabel( TQPainter* p, const TQRect& br,
+ TQTab* t, bool has_focus ) const
+{
+ TQRect r = br;
+ bool selected = currentTab() == t->id;
+ if ( t->iconset) {
+ // the tab has an iconset, draw it in the right mode
+ TQIconSet::Mode mode = (t->enabled && isEnabled())
+ ? TQIconSet::Normal : TQIconSet::Disabled;
+ if ( mode == TQIconSet::Normal && has_focus )
+ mode = TQIconSet::Active;
+ TQPixmap pixmap = t->iconset->pixmap( TQIconSet::Small, mode );
+ int pixw = pixmap.width();
+ int pixh = pixmap.height();
+ r.setLeft( r.left() + pixw + 4 );
+ r.setRight( r.right() + 2 );
+
+ int xoff = 0, yoff = 0;
+ if(!selected) {
+ xoff = tqstyle().tqpixelMetric(TQStyle::PM_TabBarTabShiftHorizontal, this);
+ yoff = tqstyle().tqpixelMetric(TQStyle::PM_TabBarTabShiftVertical, this);
+ }
+ p->drawPixmap( br.left() + 2 + xoff, br.center().y()-pixh/2 + yoff, pixmap );
+ }
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+
+ if (isEnabled() && t->isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (has_focus)
+ flags |= TQStyle::Style_HasFocus;
+ if ( selected )
+ flags |= TQStyle::Style_Selected;
+ else if(t == d->pressed)
+ flags |= TQStyle::Style_Sunken;
+ if(t->rect().tqcontains(mapFromGlobal(TQCursor::pos())))
+ flags |= TQStyle::Style_MouseOver;
+ tqstyle().tqdrawControl( TQStyle::CE_TabBarLabel, p, this, r,
+ t->isEnabled() ? tqcolorGroup(): tqpalette().disabled(),
+ flags, TQStyleOption(t) );
+}
+
+
+/*!
+ Repaints the tab row. All the painting is done by paint();
+ paintEvent() only decides which tabs need painting and in what
+ order. The event is passed in \a e.
+
+ \sa paint()
+*/
+
+void TQTabBar::paintEvent( TQPaintEvent * e )
+{
+ if ( e->rect().isNull() )
+ return;
+
+ TQSharedDoubleBuffer buffer( this, e->rect() );
+
+ TQTab * t;
+ t = l->first();
+ do {
+ TQTab * n = l->next();
+ if ( t && t->r.intersects( e->rect() ) )
+ paint( buffer.painter(), t, n == 0 );
+ t = n;
+ } while ( t != 0 );
+
+ if ( d->scrolls && lstatic->first()->r.left() < 0 ) {
+ TQPointArray a;
+ int h = height();
+ if ( d->s == RoundedAbove ) {
+ buffer.painter()->fillRect( 0, 3, 4, h-5,
+ tqcolorGroup().brush( TQColorGroup::Background ) );
+ a.setPoints( 5, 0,2, 3,h/4, 0,h/2, 3,3*h/4, 0,h );
+ } else if ( d->s == RoundedBelow ) {
+ buffer.painter()->fillRect( 0, 2, 4, h-5,
+ tqcolorGroup().brush( TQColorGroup::Background ) );
+ a.setPoints( 5, 0,0, 3,h/4, 0,h/2, 3,3*h/4, 0,h-3 );
+ }
+
+ if ( !a.isEmpty() ) {
+ buffer.painter()->setPen( tqcolorGroup().light() );
+ buffer.painter()->drawPolyline( a );
+ a.translate( 1, 0 );
+ buffer.painter()->setPen( tqcolorGroup().midlight() );
+ buffer.painter()->drawPolyline( a );
+ }
+ }
+}
+
+
+/*!
+ This virtual function is called by the mouse event handlers to
+ determine which tab is pressed. The default implementation returns
+ a pointer to the tab whose bounding rectangle tqcontains \a p, if
+ exactly one tab's bounding rectangle tqcontains \a p. Otherwise it
+ returns 0.
+
+ \sa mousePressEvent() mouseReleaseEvent()
+*/
+
+TQTab * TQTabBar::selectTab( const TQPoint & p ) const
+{
+ TQTab * selected = 0;
+ bool moreThanOne = FALSE;
+
+ TQPtrListIterator<TQTab> i( *l );
+ while( i.current() ) {
+ TQTab * t = i.current();
+ ++i;
+
+ if ( t && t->r.tqcontains( p ) ) {
+ if ( selected )
+ moreThanOne = TRUE;
+ else
+ selected = t;
+ }
+ }
+
+ return moreThanOne ? 0 : selected;
+}
+
+
+/*!
+ \reimp
+*/
+void TQTabBar::mousePressEvent( TQMouseEvent * e )
+{
+ if ( e->button() != Qt::LeftButton ) {
+ e->ignore();
+ return;
+ }
+ TQTab *t = selectTab( e->pos() );
+ if ( t && t->enabled ) {
+ d->pressed = t;
+ if(e->type() == tqstyle().tqstyleHint( TQStyle::SH_TabBar_SelectMouseType, this ))
+ setCurrentTab( t );
+ else
+ tqrepaint(t->rect(), FALSE);
+ }
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQTabBar::mouseMoveEvent ( TQMouseEvent *e )
+{
+ if ( e->state() != Qt::LeftButton ) {
+ e->ignore();
+ return;
+ }
+ if(tqstyle().tqstyleHint( TQStyle::SH_TabBar_SelectMouseType, this ) == TQEvent::MouseButtonRelease) {
+ TQTab *t = selectTab( e->pos() );
+ if(t != d->pressed) {
+ if(d->pressed)
+ tqrepaint(d->pressed->rect(), FALSE);
+ if((d->pressed = t))
+ tqrepaint(t->rect(), FALSE);
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQTabBar::mouseReleaseEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ e->ignore();
+ if(d->pressed) {
+ TQTab *t = selectTab( e->pos() ) == d->pressed ? d->pressed : 0;
+ d->pressed = 0;
+ if(t && t->enabled && e->type() == tqstyle().tqstyleHint( TQStyle::SH_TabBar_SelectMouseType, this ))
+ setCurrentTab( t );
+ }
+}
+
+
+/*!
+ \reimp
+*/
+void TQTabBar::show()
+{
+ // ensures that one tab is selected.
+ TQTab * t = l->last();
+ TQWidget::show();
+
+ if ( t )
+ emit selected( t->id );
+}
+
+/*!
+ \property TQTabBar::currentTab
+ \brief the id of the tab bar's visible tab
+
+ If no tab page is currently visible, the property's value is -1.
+ Even if the property's value is not -1, you cannot assume that the
+ user can see the relevant page, or that the tab is enabled. When
+ you need to display something the value of this property
+ represents the best page to display.
+
+ When this property is set to \e id, it will raise the tab with the
+ id \e id and emit the selected() signal.
+
+ \sa selected() isTabEnabled()
+*/
+
+int TQTabBar::currentTab() const
+{
+ const TQTab * t = l->getLast();
+
+ return t ? t->id : -1;
+}
+
+void TQTabBar::setCurrentTab( int id )
+{
+ setCurrentTab( tab( id ) );
+}
+
+
+/*!
+ \overload
+
+ Raises \a tab and emits the selected() signal unless the tab was
+ already current.
+
+ \sa currentTab() selected()
+*/
+
+void TQTabBar::setCurrentTab( TQTab * tab )
+{
+ if ( tab && l ) {
+ if ( l->last() == tab )
+ return;
+
+ TQRect r = l->last()->r;
+ if ( l->tqfindRef( tab ) >= 0 )
+ l->append( l->take() );
+
+ d->focus = tab->id;
+
+ setMicroFocusHint( tab->rect().x(), tab->rect().y(), tab->rect().width(), tab->rect().height(), FALSE );
+
+ if ( tab->r.intersects( r ) ) {
+ tqrepaint( r.unite( tab->r ), FALSE );
+ } else {
+#ifdef TQ_WS_MACX
+ update();
+#else
+ tqrepaint( r, FALSE );
+ tqrepaint( tab->r, FALSE );
+#endif
+ }
+ makeVisible( tab );
+ emit selected( tab->id );
+
+#ifdef TQT_ACCESSIBILITY_SUPPORT
+ TQAccessible::updateAccessibility( this, indexOf(tab->id)+1, TQAccessible::Focus );
+#endif
+ }
+}
+
+/*!
+ \property TQTabBar::keyboardFocusTab
+ \brief the id of the tab that has the keyboard focus
+
+ This property tqcontains the id of the tab that has the keyboard
+ focus or -1 if the tab bar does not have the keyboard focus.
+*/
+
+int TQTabBar::keyboardFocusTab() const
+{
+ return hasFocus() ? d->focus : -1;
+}
+
+
+/*!
+ \reimp
+*/
+void TQTabBar::keyPressEvent( TQKeyEvent * e )
+{
+ // The right and left arrow keys move a selector, the spacebar
+ // makes the tab with the selector active. All other keys are
+ // ignored.
+
+ int old = d->focus;
+
+ bool reverse = TQApplication::reverseLayout();
+ if ( ( !reverse && e->key() == Qt::Key_Left ) || ( reverse && e->key() == Qt::Key_Right ) ) {
+ // left - skip past any disabled ones
+ if ( d->focus >= 0 ) {
+ TQTab * t = lstatic->last();
+ while ( t && t->id != d->focus )
+ t = lstatic->prev();
+ do {
+ t = lstatic->prev();
+ } while ( t && !t->enabled);
+ if (t)
+ d->focus = t->id;
+ }
+ if ( d->focus < 0 )
+ d->focus = old;
+ } else if ( ( !reverse && e->key() == Qt::Key_Right ) || ( reverse && e->key() == Qt::Key_Left ) ) {
+ TQTab * t = lstatic->first();
+ while ( t && t->id != d->focus )
+ t = lstatic->next();
+ do {
+ t = lstatic->next();
+ } while ( t && !t->enabled);
+
+ if (t)
+ d->focus = t->id;
+ if ( d->focus >= d->id )
+ d->focus = old;
+ } else {
+ // other keys - ignore
+ e->ignore();
+ return;
+ }
+
+ // if the focus moved, tqrepaint and signal
+ if ( old != d->focus ) {
+ setCurrentTab( d->focus );
+ }
+}
+
+
+/*!
+ Returns the tab with id \a id or 0 if there is no such tab.
+
+ \sa count()
+*/
+
+TQTab * TQTabBar::tab( int id ) const
+{
+ TQTab * t;
+ for( t = l->first(); t; t = l->next() )
+ if ( t && t->id == id )
+ return t;
+ return 0;
+}
+
+
+/*!
+ Returns the tab at position \a index.
+
+ \sa indexOf()
+*/
+
+TQTab * TQTabBar::tabAt( int index ) const
+{
+ TQTab * t;
+ t = lstatic->at( index );
+ return t;
+}
+
+
+/*!
+ Returns the position index of the tab with id \a id or -1 if no
+ tab has this \a id.
+
+ \sa tabAt()
+*/
+int TQTabBar::indexOf( int id ) const
+{
+ TQTab * t;
+ int idx = 0;
+ for( t = lstatic->first(); t; t = lstatic->next() ) {
+ if ( t && t->id == id )
+ return idx;
+ idx++;
+ }
+ return -1;
+}
+
+
+/*!
+ \property TQTabBar::count
+ \brief the number of tabs in the tab bar
+
+ \sa tab()
+*/
+int TQTabBar::count() const
+{
+ return l->count();
+}
+
+
+/*!
+ The list of TQTab objects in the tab bar.
+
+ This list is unlikely to be in the order that the TQTab elements
+ appear visually. One way of iterating over the tabs is like this:
+ \code
+ for ( uint i = 0; i < myTabBar->count(); ++i ) {
+ nextTab = myTabBar->tabAt( i );
+ // do something with nextTab
+ }
+ \endcode
+*/
+TQPtrList<TQTab> * TQTabBar::tabList()
+{
+ return l;
+}
+
+
+/*!
+ \property TQTabBar::tqshape
+ \brief the tqshape of the tabs in the tab bar
+
+ The value of this property is one of the following: \c
+ RoundedAbove (default), \c RoundedBelow, \c TriangularAbove or \c
+ TriangularBelow.
+
+ \sa Shape
+*/
+TQTabBar::Shape TQTabBar::tqshape() const
+{
+ return d ? d->s : RoundedAbove;
+}
+
+void TQTabBar::setShape( Shape s )
+{
+ if ( !d || d->s == s )
+ return;
+ //######### must recalculate heights
+ d->s = s;
+ update();
+}
+
+/*!
+ Lays out all existing tabs according to their label and their
+ iconset.
+ */
+void TQTabBar::layoutTabs()
+{
+ if ( lstatic->isEmpty() )
+ return;
+
+ TQSize oldSh(0, 0);
+ if ( TQTab * t = l->first() ) {
+ TQRect r( t->r );
+ while ( (t = l->next()) != 0 )
+ r = r.unite( t->r );
+ oldSh = r.size();
+ }
+
+ d->btnWidth = tqstyle().tqpixelMetric(TQStyle::PM_TabBarScrollButtonWidth, this);
+ int hframe, vframe, overlap;
+ hframe = tqstyle().tqpixelMetric( TQStyle::PM_TabBarTabHSpace, this );
+ vframe = tqstyle().tqpixelMetric( TQStyle::PM_TabBarTabVSpace, this );
+ overlap = tqstyle().tqpixelMetric( TQStyle::PM_TabBarTabOverlap, this );
+
+ TQFontMetrics fm = fontMetrics();
+ TQRect r;
+ TQTab *t;
+ bool reverse = TQApplication::reverseLayout();
+ if ( reverse )
+ t = lstatic->last();
+ else
+ t = lstatic->first();
+ int x = 0;
+ int offset = (t && d->scrolls) ? t->r.x() : 0;
+ while ( t ) {
+ int lw = fm.width( t->label );
+ lw -= t->label.tqcontains('&') * fm.width('&');
+ lw += t->label.tqcontains("&&") * fm.width('&');
+ int iw = 0;
+ int ih = 0;
+ if ( t->iconset != 0 ) {
+ iw = t->iconset->pixmap( TQIconSet::Small, TQIconSet::Normal ).width() + 4;
+ ih = t->iconset->pixmap( TQIconSet::Small, TQIconSet::Normal ).height();
+ }
+ int h = TQMAX( fm.height(), ih );
+ h = TQMAX( h, TQApplication::globalStrut().height() );
+
+ h += vframe;
+ t->r = TQRect(TQPoint(x, 0), tqstyle().tqsizeFromContents(TQStyle::CT_TabBarTab, this,
+ TQSize( TQMAX( lw + hframe + iw, TQApplication::globalStrut().width() ), h ),
+ TQStyleOption(t) ));
+ x += t->r.width() - overlap;
+ r = r.unite( t->r );
+ if ( reverse )
+ t = lstatic->prev();
+ else
+ t = lstatic->next();
+ }
+ x += overlap;
+ int w = (d->scrolls) ? d->leftB->x() : width();
+ if (x + offset < w)
+ offset = w - x;
+ if (offset > 0)
+ offset = 0;
+
+ for ( t = lstatic->first(); t; t = lstatic->next() ) {
+ t->r.moveBy( offset, 0 );
+ t->r.setHeight( r.height() );
+ }
+
+ if ( tqsizeHint() != oldSh )
+ updateGeometry();
+
+ emit layoutChanged();
+}
+
+/*!
+ \reimp
+*/
+
+bool TQTabBar::event( TQEvent *e )
+{
+ if ( e->type() == TQEvent::LanguageChange ) {
+ layoutTabs();
+ updateArrowButtons();
+ makeVisible( tab( currentTab() ));
+ }
+
+ return TQWidget::event( e );
+}
+
+/*!
+ \reimp
+*/
+
+void TQTabBar::styleChange( TQStyle& old )
+{
+ layoutTabs();
+ updateArrowButtons();
+ TQWidget::styleChange( old );
+}
+
+/*!
+ \reimp
+*/
+void TQTabBar::focusInEvent( TQFocusEvent * )
+{
+ TQTab *t = tab( d->focus );
+ if ( t )
+ tqrepaint( t->r, FALSE );
+}
+
+/*!
+ \reimp
+*/
+void TQTabBar::focusOutEvent( TQFocusEvent * )
+{
+ TQTab *t = tab( d->focus );
+ if ( t )
+ tqrepaint( t->r, FALSE );
+}
+
+/*!
+ \reimp
+*/
+void TQTabBar::resizeEvent( TQResizeEvent * )
+{
+ const int arrowWidth = TQMAX( d->btnWidth, TQApplication::globalStrut().width() );;
+ d->rightB->setGeometry( width() - arrowWidth, 0, arrowWidth, height() );
+ d->leftB->setGeometry( width() - 2*arrowWidth, 0, arrowWidth, height() );
+ layoutTabs();
+ updateArrowButtons();
+ makeVisible( tab( currentTab() ));
+}
+
+void TQTabBar::scrollTabs()
+{
+ TQTab* left = 0;
+ TQTab* right = 0;
+ for ( TQTab* t = lstatic->first(); t; t = lstatic->next() ) {
+ if ( t->r.left() < 0 && t->r.right() > 0 )
+ left = t;
+ if ( t->r.left() < d->leftB->x()+2 )
+ right = t;
+ }
+
+ if ( sender() == d->leftB )
+ makeVisible( left );
+ else if ( sender() == d->rightB )
+ makeVisible( right );
+}
+
+void TQTabBar::makeVisible( TQTab* tab )
+{
+ bool tooFarLeft = ( tab && tab->r.left() < 0 );
+ bool tooFarRight = ( tab && tab->r.right() >= d->leftB->x() );
+
+ if ( !d->scrolls || ( !tooFarLeft && ! tooFarRight ) )
+ return;
+
+ bool bs = tqsignalsBlocked();
+ blockSignals(TRUE);
+ layoutTabs();
+ blockSignals(bs);
+
+ int offset = 0;
+
+ if ( tooFarLeft ) {
+ offset = tab->r.left();
+ if (tab != lstatic->first())
+ offset -= 8;
+ } else if ( tooFarRight ) {
+ offset = tab->r.right() - d->leftB->x() + 1;
+ }
+
+ for ( TQTab* t = lstatic->first(); t; t = lstatic->next() )
+ t->r.moveBy( -offset, 0 );
+
+ d->leftB->setEnabled( lstatic->first()->r.left() < 0);
+ d->rightB->setEnabled( lstatic->last()->r.right() >= d->leftB->x() );
+
+ // Make sure disabled buttons pop up again
+ if ( !d->leftB->isEnabled() && d->leftB->isDown() )
+ d->leftB->setDown( FALSE );
+ if ( !d->rightB->isEnabled() && d->rightB->isDown() )
+ d->rightB->setDown( FALSE );
+
+ update();
+ emit layoutChanged();
+}
+
+void TQTabBar::updateArrowButtons()
+{
+ if (lstatic->isEmpty()) {
+ d->scrolls = FALSE;
+ } else {
+ d->scrolls = (lstatic->last()->r.right() - lstatic->first()->r.left() > width());
+ }
+ if ( d->scrolls ) {
+ const int arrowWidth = TQMAX( d->btnWidth, TQApplication::globalStrut().width() );
+ if ( TQApplication::reverseLayout() ) {
+ d->rightB->setGeometry( arrowWidth, 0, arrowWidth, height() );
+ d->leftB->setGeometry( 0, 0, arrowWidth, height() );
+ } else {
+ d->rightB->setGeometry( width() - arrowWidth, 0, arrowWidth, height() );
+ d->leftB->setGeometry( width() - 2*arrowWidth, 0, arrowWidth, height() );
+ }
+
+ d->leftB->setEnabled( lstatic->first()->r.left() < 0);
+ d->rightB->setEnabled( lstatic->last()->r.right() >= d->leftB->x() );
+ d->leftB->show();
+ d->rightB->show();
+ } else {
+ d->leftB->hide();
+ d->rightB->hide();
+ layoutTabs();
+ }
+}
+
+/*!
+ Removes the tool tip for the tab at index position \a index.
+*/
+void TQTabBar::removeToolTip( int index )
+{
+#ifndef TQT_NO_TOOLTIP
+ TQTab * tab = tabAt( index );
+ if ( !tab || !d->toolTips )
+ return;
+ d->toolTips->remove( tab );
+#endif
+}
+
+/*!
+ Sets the tool tip for the tab at index position \a index to \a
+ tip.
+*/
+void TQTabBar::setToolTip( int index, const TQString & tip )
+{
+#ifndef TQT_NO_TOOLTIP
+ TQTab * tab = tabAt( index );
+ if ( !tab )
+ return;
+ if ( d->toolTips == 0 )
+ d->toolTips = new TQTabBarToolTip( this );
+ d->toolTips->add( tab, tip );
+#endif
+}
+
+/*!
+ Returns the tool tip for the tab at index position \a index.
+*/
+TQString TQTabBar::toolTip( int index ) const
+{
+#ifndef TQT_NO_TOOLTIP
+ if ( d->toolTips )
+ return d->toolTips->tipForTab( tabAt( index ) );
+ else
+#endif
+ return TQString();
+}
+
+/*!
+ Sets the text of the tab to \a text.
+*/
+void TQTab::setText( const TQString& text )
+{
+ label = text;
+ if ( tb ) {
+#ifndef TQT_NO_ACCEL
+ tb->d->a->removeItem( id );
+ int p = TQAccel::shortcutKey( text );
+ if ( p )
+ tb->d->a->insertItem( p, id );
+#endif
+ tb->layoutTabs();
+ tb->tqrepaint(FALSE);
+
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( tb, tb->indexOf(id)+1, TQAccessible::NameChanged );
+#endif
+ }
+}
+
+/*!
+ Sets the tab's iconset to \a icon
+*/
+void TQTab::setIconSet( const TQIconSet &icon )
+{
+ iconset = new TQIconSet( icon );
+}
+
+// this allows us to handle accelerators that are in a TQTabBar.
+void TQTab::setTabBar( TQTabBar *newTb )
+{
+ tb = newTb;
+}
+
+/*!
+ \internal
+*/
+void TQTabBar::fontChange( const TQFont & oldFont )
+{
+ layoutTabs();
+ TQWidget::fontChange( oldFont );
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqtabbar.h b/tqtinterface/qt4/src/widgets/tqtabbar.h
new file mode 100644
index 0000000..1b0fa76
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtabbar.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Definition of TQTab and TQTabBar classes
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTABBAR_H
+#define TQTABBAR_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqptrlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TABBAR
+
+class TQTabBar;
+class TQIconSet;
+
+class TQ_EXPORT TQTab : public TQt
+{
+ friend class TQTabBar;
+ friend class TQTabWidget;
+
+public:
+ TQTab();
+ virtual ~TQTab();
+ TQTab( const TQString& text );
+ TQTab( const TQIconSet& icon, const TQString& text = TQString::null );
+
+ void setText( const TQString& text);
+ TQString text() const { return label; }
+ void setIconSet( const TQIconSet& icon );
+ TQIconSet* iconSet() const { return iconset; }
+ void setRect( const TQRect& rect ) { r = rect; }
+ TQRect rect() const { return r; }
+ void setEnabled( bool enable ) { enabled = enable; }
+ bool isEnabled() const { return enabled; }
+ void setIdentifier( int i ) { id = i; }
+ int identifier() const { return id; }
+
+private:
+ void setTabBar( TQTabBar *tb );
+ TQString label;
+ TQRect r; // the bounding rectangle of this (may overlap with others)
+ bool enabled;
+ int id;
+ TQIconSet* iconset; // optional iconset
+ TQTabBar *tb;
+};
+
+
+struct TQTabPrivate;
+//class *TQAccel;
+
+class TQ_EXPORT TQTabBar: public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( Shape )
+ Q_PROPERTY( Shape tqshape READ tqshape WRITE setShape )
+ Q_PROPERTY( int currentTab READ currentTab WRITE setCurrentTab )
+ Q_PROPERTY( int count READ count )
+ Q_PROPERTY( int keyboardFocusTab READ keyboardFocusTab )
+
+public:
+ TQTabBar( TQWidget* tqparent=0, const char* name=0 );
+ ~TQTabBar();
+
+ enum Shape { RoundedAbove, RoundedBelow,
+ TriangularAbove, TriangularBelow };
+
+ Shape tqshape() const;
+ virtual void setShape( Shape );
+
+ void show();
+
+ virtual int addTab( TQTab * );
+ virtual int insertTab( TQTab *, int index = -1 );
+ virtual void removeTab( TQTab * );
+
+ virtual void setTabEnabled( int, bool );
+ bool isTabEnabled( int ) const;
+
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ int currentTab() const;
+ int keyboardFocusTab() const;
+
+ TQTab * tab( int ) const;
+ TQTab * tabAt( int ) const;
+ int indexOf( int ) const;
+ int count() const;
+
+ virtual void layoutTabs();
+ virtual TQTab * selectTab( const TQPoint & p ) const;
+
+ void removeToolTip( int index );
+ void setToolTip( int index, const TQString & tip );
+ TQString toolTip( int index ) const;
+
+public Q_SLOTS:
+ virtual void setCurrentTab( int );
+ virtual void setCurrentTab( TQTab * );
+
+Q_SIGNALS:
+ void selected( int );
+ void layoutChanged();
+
+protected:
+ virtual void paint( TQPainter *, TQTab *, bool ) const; // ### not const
+ virtual void paintLabel( TQPainter*, const TQRect&, TQTab*, bool ) const;
+
+ void focusInEvent( TQFocusEvent *e );
+ void focusOutEvent( TQFocusEvent *e );
+
+ void resizeEvent( TQResizeEvent * );
+ void paintEvent( TQPaintEvent * );
+ void mousePressEvent ( TQMouseEvent * );
+ void mouseMoveEvent ( TQMouseEvent * );
+ void mouseReleaseEvent ( TQMouseEvent * );
+ void keyPressEvent( TQKeyEvent * );
+ void styleChange( TQStyle& );
+ void fontChange ( const TQFont & );
+
+ bool event( TQEvent *e );
+
+ TQPtrList<TQTab> * tabList();
+
+private Q_SLOTS:
+ void scrollTabs();
+
+private:
+ TQPtrList<TQTab> * l;
+ TQPtrList<TQTab> * lstatic;
+ void makeVisible( TQTab* t = 0 );
+ void updateArrowButtons();
+ TQTabPrivate * d;
+
+ friend class TQTabBarToolTip;
+ friend class TQTab;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQTabBar( const TQTabBar & );
+ TQTabBar& operator=( const TQTabBar & );
+#endif
+};
+
+
+#endif // TQT_NO_TABBAR
+
+#endif // TQTABBAR_H
diff --git a/tqtinterface/qt4/src/widgets/tqtabwidget.cpp b/tqtinterface/qt4/src/widgets/tqtabwidget.cpp
new file mode 100644
index 0000000..5fab113
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtabwidget.cpp
@@ -0,0 +1,1097 @@
+/****************************************************************************
+**
+** Implementation of TQTabWidget class
+**
+** Created : 990318
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtabwidget.h"
+#ifndef TQT_NO_TABWIDGET
+#include "tqobjectlist.h"
+#include "tqtabbar.h"
+#include "tqapplication.h"
+#include "tqwidgetstack.h"
+#include "tqbitmap.h"
+#include "tqaccel.h"
+#include "tqstyle.h"
+#include "tqpainter.h"
+#include "tqtoolbutton.h"
+
+#ifdef TQ_OS_MACX
+#include <tqmacstyle_mac.h>
+#endif
+
+/*!
+ \class TQTabWidget tqtabwidget.h
+ \brief The TQTabWidget class provides a stack of tabbed widgets.
+
+ \ingroup organizers
+ \ingroup advanced
+ \mainclass
+
+ A tab widget provides a tab bar of tabs and a `page area' below
+ (or above, see \l{TabPosition}) the tabs. Each tab is associated
+ with a different widget (called a `page'). Only the current tab's
+ page is shown in the page area; all the other tabs' pages are
+ hidden. The user can show a different page by clicking on its tab
+ or by pressing its Alt+\e{letter} accelerator if it has one.
+
+ The normal way to use TQTabWidget is to do the following in the
+ constructor:
+ \list 1
+ \i Create a TQTabWidget.
+ \i Create a TQWidget for each of the pages in the tab dialog,
+ insert tqchildren into it, set up tqgeometry management for it and use
+ addTab() (or insertTab()) to set up a tab and keyboard accelerator
+ for it.
+ \i Connect to the Q_SIGNALS and Q_SLOTS.
+ \endlist
+
+ The position of the tabs is set with setTabPosition(), their tqshape
+ with setTabShape(), and their margin with setMargin().
+
+ If you don't call addTab() and the TQTabWidget is already visible,
+ then the page you have created will not be visible. Don't
+ confuse the object name you supply to the TQWidget constructor and
+ the tab label you supply to addTab(). addTab() takes a name which
+ indicates an accelerator and is meaningful and descriptive to the
+ user, whereas the widget name is used primarily for debugging.
+
+ The signal currentChanged() is emitted when the user selects a
+ page.
+
+ The current page is available as an index position with
+ currentPageIndex() or as a wiget pointer with currentPage(). You
+ can retrieve a pointer to a page with a given index using page(),
+ and can tqfind the index position of a page with indexOf(). Use
+ setCurrentPage() to show a particular page by index, or showPage()
+ to show a page by widget pointer.
+
+ You can change a tab's label and iconset using changeTab() or
+ setTabLabel() and setTabIconSet(). A tab page can be removed with
+ removePage().
+
+ Each tab is either enabled or disabled at any given time (see
+ setTabEnabled()). If a tab is enabled, the tab text is drawn
+ normally and the user can select that tab. If it is disabled, the
+ tab is drawn in a different way and the user cannot select that
+ tab. Note that even if a tab is disabled, the page can still be
+ visible, for example if all of the tabs happen to be disabled.
+
+ Although tab widgets can be a very good way to split up a complex
+ dialog, it's also very easy to get into a mess. See TQTabDialog for
+ some design hints. An alternative is to use a TQWidgetStack for
+ which you provide some means of navigating between pages, for
+ example, a TQToolBar or a TQListBox.
+
+ Most of the functionality in TQTabWidget is provided by a TQTabBar
+ (at the top, providing the tabs) and a TQWidgetStack (most of the
+ area, organizing the individual pages).
+
+ <img src=qtabwidget-m.png> <img src=qtabwidget-w.png>
+
+ \sa TQTabDialog, TQToolBox
+*/
+
+/*!
+ \enum TQt::Corner
+ This enum type specifies a corner in a rectangle:
+ \value TopLeft top left corner
+ \value TopRight top right corner
+ \value BottomLeft bottom left corner
+ \value BottomRight bottom right corner
+*/
+
+/*!
+ \enum TQTabWidget::TabPosition
+
+ This enum type defines where TQTabWidget draws the tab row:
+ \value Top above the pages
+ \value Bottom below the pages
+*/
+
+/*!
+ \enum TQTabWidget::TabShape
+
+ This enum type defines the tqshape of the tabs:
+ \value Rounded rounded look (normal)
+ \value Triangular triangular look (very unusual, included for completeness)
+*/
+
+/* undocumented now
+ \obsolete
+
+ \fn void TQTabWidget::selected( const TQString &tabLabel );
+
+ This signal is emitted whenever a tab is selected (raised),
+ including during the first show().
+
+ \sa raise()
+*/
+
+
+/*!
+ \fn void TQTabWidget::currentChanged( TQWidget* );
+
+ This signal is emitted whenever the current page changes. The
+ parameter is the new current page.
+
+ \sa currentPage(), showPage(), tabLabel()
+*/
+
+class TQTabBarBase : public TQWidget
+{
+public:
+ TQTabBarBase( TQTabWidget* tqparent=0, const char* name=0 )
+ : TQWidget( tqparent, name ) {};
+protected:
+ void paintEvent( TQPaintEvent * )
+ {
+ TQObject * obj = tqparent();
+ if( obj ){
+ TQTabWidget * t = (TQTabWidget *) obj;
+ TQPainter p( this );
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+
+ if ( t->tabPosition() == TQTabWidget::Top )
+ flags |= TQStyle::Style_Top;
+ if ( t->tabPosition() == TQTabWidget::Bottom )
+ flags |= TQStyle::Style_Bottom;
+ if(parentWidget()->isEnabled())
+ flags |= TQStyle::Style_Enabled;
+
+ tqstyle().tqdrawPrimitive( TQStyle::PE_TabBarBase, &p, rect(),
+ tqcolorGroup(), flags );
+ }
+ }
+};
+
+class TQTabWidgetData
+{
+public:
+ TQTabWidgetData()
+ : tabs(0), tabBase(0), stack(0), dirty( TRUE ),
+ pos( TQTabWidget::Top ), tqshape( TQTabWidget::Rounded ),
+ leftCornerWidget(0), rightCornerWidget(0) {};
+ ~TQTabWidgetData(){};
+ TQTabBar* tabs;
+ TQTabBarBase* tabBase;
+ TQWidgetStack* stack;
+ bool dirty;
+ TQTabWidget::TabPosition pos;
+ TQTabWidget::TabShape tqshape;
+ int tqalignment;
+ TQWidget* leftCornerWidget;
+ TQWidget* rightCornerWidget;
+};
+
+/*!
+ Constructs a tabbed widget called \a name with tqparent \a tqparent,
+ and widget flags \a f.
+*/
+TQTabWidget::TQTabWidget( TQWidget *tqparent, const char *name, WFlags f )
+ : TQWidget( tqparent, name, f )
+{
+ d = new TQTabWidgetData;
+ d->stack = new TQWidgetStack( this, "tab pages" );
+ d->stack->installEventFilter( this );
+ d->tabBase = new TQTabBarBase( this, "tab base" );
+ d->tabBase->resize( 1, 1 );
+ setTabBar( new TQTabBar( this, "tab control" ) );
+
+ d->stack->setFrameStyle( TQFrame::TabWidgetPanel | TQFrame::Raised );
+#ifdef TQ_OS_TEMP
+ d->pos = Bottom;
+#endif
+
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) );
+ setFocusPolicy( Qt::TabFocus );
+ setFocusProxy( d->tabs );
+
+ installEventFilter( this );
+#ifdef TQ_OS_MACX
+ if (::tqqt_cast<TQMacStyle*>(&tqstyle()))
+ setMargin(10); // According to HIGuidelines at least.
+#endif
+}
+
+/*!
+ \reimp
+*/
+TQTabWidget::~TQTabWidget()
+{
+ delete d;
+}
+
+/*!
+ Adds another tab and page to the tab view.
+
+ The new page is \a child; the tab's label is \a label. Note the
+ difference between the widget name (which you supply to widget
+ constructors and to setTabEnabled(), for example) and the tab
+ label. The name is internal to the program and invariant, whereas
+ the label is shown on-screen and may vary according to language
+ and other factors.
+
+ If the tab's \a label tqcontains an ampersand, the letter following
+ the ampersand is used as an accelerator for the tab, e.g. if the
+ label is "Bro\&wse" then Alt+W becomes an accelerator which will
+ move the focus to this tab.
+
+ If you call addTab() after show() the screen will flicker and the
+ user may be confused.
+
+ Adding the same child twice will have undefined behavior.
+
+ \sa insertTab()
+*/
+void TQTabWidget::addTab( TQWidget *child, const TQString &label)
+{
+ insertTab( child, label );
+}
+
+
+/*!
+ \overload
+
+ Adds another tab and page to the tab view.
+
+ This function is the same as addTab(), but with an additional \a
+ iconset.
+*/
+void TQTabWidget::addTab( TQWidget *child, const TQIconSet& iconset, const TQString &label )
+{
+ insertTab( child, iconset, label );
+}
+
+/*!
+ \overload
+
+ This is a low-level function for adding tabs. It is useful if you
+ are using setTabBar() to set a TQTabBar subclass with an overridden
+ TQTabBar::paint() function for a subclass of TQTab. The \a child is
+ the new page and \a tab is the tab to put the \a child on.
+*/
+void TQTabWidget::addTab( TQWidget *child, TQTab* tab )
+{
+ insertTab( child, tab );
+}
+
+
+
+/*!
+ Inserts another tab and page to the tab view.
+
+ The new page is \a child; the tab's label is \a label. Note the
+ difference between the widget name (which you supply to widget
+ constructors and to setTabEnabled(), for example) and the tab
+ label. The name is internal to the program and invariant, whereas
+ the label is shown on-screen and may vary according to language
+ and other factors.
+
+ If the tab's \a label tqcontains an ampersand, the letter following
+ the ampersand is used as an accelerator for the tab, e.g. if the
+ label is "Bro\&wse" then Alt+W becomes an accelerator which will
+ move the focus to this tab.
+
+ If \a index is not specified, the tab is simply appended.
+ Otherwise it is inserted at the specified position.
+
+ If you call insertTab() after show(), the screen will flicker and
+ the user may be confused.
+
+ \sa addTab()
+*/
+void TQTabWidget::insertTab( TQWidget *child, const TQString &label, int index)
+{
+ TQTab * t = new TQTab();
+ TQ_CHECK_PTR( t );
+ t->label = label;
+ insertTab( child, t, index );
+}
+
+
+/*!
+ \overload
+
+ Inserts another tab and page to the tab view.
+
+ This function is the same as insertTab(), but with an additional
+ \a iconset.
+*/
+void TQTabWidget::insertTab( TQWidget *child, const TQIconSet& iconset, const TQString &label, int index )
+{
+ TQTab * t = new TQTab();
+ TQ_CHECK_PTR( t );
+ t->label = label;
+ t->iconset = new TQIconSet( iconset );
+ insertTab( child, t, index );
+}
+
+/*!
+ \overload
+
+ This is a lower-level method for inserting tabs, similar to the
+ other insertTab() method. It is useful if you are using
+ setTabBar() to set a TQTabBar subclass with an overridden
+ TQTabBar::paint() function for a subclass of TQTab. The \a child is
+ the new page, \a tab is the tab to put the \a child on and \a
+ index is the position in the tab bar that this page should occupy.
+*/
+void TQTabWidget::insertTab( TQWidget *child, TQTab* tab, int index)
+{
+ tab->enabled = TRUE;
+ int id = d->tabs->insertTab( tab, index );
+ d->stack->addWidget( child, id );
+ if ( d->stack->frameStyle() != ( TQFrame::TabWidgetPanel | TQFrame::Raised ) )
+ d->stack->setFrameStyle( TQFrame::TabWidgetPanel | TQFrame::Raised );
+ setUpLayout();
+}
+
+
+/*!
+ Defines a new \a label for page \a{w}'s tab.
+*/
+void TQTabWidget::changeTab( TQWidget *w, const TQString &label)
+{
+ int id = d->stack->id( w );
+ if ( id < 0 )
+ return;
+ TQTab* t = d->tabs->tab( id );
+ if ( !t )
+ return;
+ // this will update the accelerators
+ t->setText( label );
+
+ d->tabs->layoutTabs();
+ d->tabs->update();
+ setUpLayout();
+}
+
+/*!
+ \overload
+
+ Defines a new \a iconset and a new \a label for page \a{w}'s tab.
+*/
+void TQTabWidget::changeTab( TQWidget *w, const TQIconSet& iconset, const TQString &label)
+{
+ int id = d->stack->id( w );
+ if ( id < 0 )
+ return;
+ TQTab* t = d->tabs->tab( id );
+ if ( !t )
+ return;
+ if ( t->iconset ) {
+ delete t->iconset;
+ t->iconset = 0;
+ }
+ // this will update the accelerators
+ t->iconset = new TQIconSet( iconset );
+ t->setText( label );
+
+ d->tabs->layoutTabs();
+ d->tabs->update();
+ setUpLayout();
+}
+
+/*!
+ Returns TRUE if the page \a w is enabled; otherwise returns FALSE.
+
+ \sa setTabEnabled(), TQWidget::isEnabled()
+*/
+
+bool TQTabWidget::isTabEnabled( TQWidget* w ) const
+{
+ int id = d->stack->id( w );
+ if ( id >= 0 )
+ return w->isEnabled();
+ else
+ return FALSE;
+}
+
+/*!
+ If \a enable is TRUE, page \a w is enabled; otherwise page \a w is
+ disabled. The page's tab is redrawn appropriately.
+
+ TQTabWidget uses TQWidget::setEnabled() internally, rather than
+ keeping a separate flag.
+
+ Note that even a disabled tab/page may be visible. If the page is
+ visible already, TQTabWidget will not hide it; if all the pages are
+ disabled, TQTabWidget will show one of them.
+
+ \sa isTabEnabled(), TQWidget::setEnabled()
+*/
+
+void TQTabWidget::setTabEnabled( TQWidget* w, bool enable)
+{
+ int id = d->stack->id( w );
+ if ( id >= 0 ) {
+ w->setEnabled( enable );
+ d->tabs->setTabEnabled( id, enable );
+ }
+}
+
+/*!
+ Sets widget \a w to be the shown in the specified \a corner of the
+ tab widget.
+
+ Only the horizontal element of the \a corner will be used.
+
+ \sa cornerWidget(), setTabPosition()
+*/
+void TQTabWidget::setCornerWidget( TQWidget * w, TQt::Corner corner )
+{
+ if ( !w )
+ return;
+ if ( (uint)corner & 1 )
+ d->rightCornerWidget = w;
+ else
+ d->leftCornerWidget = w;
+}
+
+/*!
+ Returns the widget shown in the \a corner of the tab widget or 0.
+*/
+TQWidget * TQTabWidget::cornerWidget( TQt::Corner corner ) const
+{
+ if ( (uint)corner & 1 )
+ return d->rightCornerWidget;
+ return d->leftCornerWidget;
+}
+
+/*!
+ Ensures that page \a w is shown. This is useful mainly for
+ accelerators.
+
+ \warning Used carelessly, this function can easily surprise or
+ confuse the user.
+
+ \sa TQTabBar::setCurrentTab()
+*/
+void TQTabWidget::showPage( TQWidget * w)
+{
+ int id = d->stack->id( w );
+ if ( id >= 0 ) {
+ d->stack->raiseWidget( w );
+ d->tabs->setCurrentTab( id );
+ // ### why overwrite the frame style?
+ if ( d->stack->frameStyle() != ( TQFrame::TabWidgetPanel |TQFrame::Raised ) )
+ d->stack->setFrameStyle( TQFrame::TabWidgetPanel | TQFrame::Raised );
+ }
+}
+
+/*!
+ Removes page \a w from this stack of widgets. Does not delete \a
+ w.
+
+ \sa addTab(), showPage(), TQWidgetStack::removeWidget()
+*/
+void TQTabWidget::removePage( TQWidget * w )
+{
+ int id = d->stack->id( w );
+ if ( id >= 0 ) {
+ int oldId = d->stack->id(currentPage());
+ bool fixCurrentTab = oldId == id;
+ //switches to the next enabled tab
+ d->tabs->setTabEnabled( id, FALSE );
+ //if no next enabled page we fix the current page
+ fixCurrentTab = fixCurrentTab && oldId == d->stack->id(currentPage());
+
+ d->stack->removeWidget( w );
+ d->tabs->removeTab( d->tabs->tab(id) );
+ if ( fixCurrentTab )
+ showTab( d->tabs->currentTab() );
+ setUpLayout();
+
+ if ( d->tabs->count() == 0 )
+ d->stack->setFrameStyle( TQFrame::NoFrame );
+ }
+}
+
+/*!
+ Returns the label text for the tab on page \a w.
+*/
+
+TQString TQTabWidget::tabLabel( TQWidget * w ) const
+{
+ TQTab * t = d->tabs->tab( d->stack->id( w ) );
+ return t ? t->label : TQString::null;
+}
+
+/*!
+ Sets the tab label for page \a w to \a l
+*/
+
+void TQTabWidget::setTabLabel( TQWidget * w, const TQString &l )
+{
+ TQTab * t = d->tabs->tab( d->stack->id( w ) );
+ if ( t )
+ t->label = l;
+ d->tabs->layoutTabs();
+ d->tabs->update();
+ setUpLayout();
+}
+
+/*!
+ Returns a pointer to the page currently being displayed by the tab
+ dialog. The tab dialog does its best to make sure that this value
+ is never 0 (but if you try hard enough, it can be).
+*/
+
+TQWidget * TQTabWidget::currentPage() const
+{
+ return page( currentPageIndex() );
+}
+
+/*!
+ \property TQTabWidget::autoMask
+ \brief whether the tab widget is automatically masked
+
+ \sa TQWidget::setAutoMask()
+*/
+
+/*!
+ \property TQTabWidget::currentPage
+ \brief the index position of the current tab page
+
+ \sa TQTabBar::currentTab()
+*/
+
+int TQTabWidget::currentPageIndex() const
+{
+ return d->tabs->indexOf( d->tabs->currentTab() );
+}
+
+void TQTabWidget::setCurrentPage( int index )
+{
+ d->tabs->setCurrentTab( d->tabs->tabAt( index ) );
+ showTab( d->tabs->currentTab() );
+}
+
+
+/*!
+ Returns the index position of page \a w, or -1 if the widget
+ cannot be found.
+*/
+int TQTabWidget::indexOf( TQWidget* w ) const
+{
+ return d->tabs->indexOf( d->stack->id( w ) );
+}
+
+
+/*!
+ \reimp
+*/
+void TQTabWidget::resizeEvent( TQResizeEvent *e )
+{
+ TQWidget::resizeEvent( e );
+ setUpLayout();
+}
+
+/*!
+ Replaces the dialog's TQTabBar heading with the tab bar \a tb. Note
+ that this must be called \e before any tabs have been added, or
+ the behavior is undefined.
+
+ \sa tabBar()
+*/
+void TQTabWidget::setTabBar( TQTabBar* tb)
+{
+ if ( tb->parentWidget() != this )
+ tb->reparent( this, TQPoint(0,0), TRUE );
+ delete d->tabs;
+ d->tabs = tb;
+ setFocusProxy( d->tabs );
+ connect( d->tabs, TQT_SIGNAL(selected(int)),
+ this, TQT_SLOT(showTab(int)) );
+ setUpLayout();
+}
+
+
+/*!
+ Returns the current TQTabBar.
+
+ \sa setTabBar()
+*/
+TQTabBar* TQTabWidget::tabBar() const
+{
+ return d->tabs;
+}
+
+/*!
+ Ensures that the selected tab's page is visible and appropriately
+ sized.
+*/
+
+void TQTabWidget::showTab( int i )
+{
+ if ( d->stack->widget( i ) ) {
+ d->stack->raiseWidget( i );
+ emit selected( d->tabs->tab( i )->label );
+ emit currentChanged( d->stack->widget( i ) );
+ }
+}
+
+/*
+ Set up the tqlayout.
+*/
+void TQTabWidget::setUpLayout( bool onlyCheck )
+{
+ if ( onlyCheck && !d->dirty )
+ return; // nothing to do
+
+ if ( !isVisible() ) {
+ d->dirty = TRUE;
+ return; // we'll do it later
+ }
+
+ TQSize t( 0, d->stack->frameWidth() );
+ if ( d->tabs->isVisibleTo(this) )
+ t = d->tabs->tqsizeHint();
+ int lcw = 0;
+ if ( d->leftCornerWidget && d->leftCornerWidget->isVisible() ) {
+ TQSize sz = d->leftCornerWidget->tqsizeHint();
+ d->leftCornerWidget->resize(sz);
+ lcw = sz.width();
+ if ( t.height() > lcw )
+ lcw = t.height();
+ }
+ int rcw = 0;
+ if ( d->rightCornerWidget && d->rightCornerWidget->isVisible() ) {
+ TQSize sz = d->rightCornerWidget->tqsizeHint();
+ d->rightCornerWidget->resize(sz);
+ rcw = sz.width();
+ if ( t.height() > rcw )
+ rcw = t.height();
+ }
+ int tw = width() - lcw - rcw;
+ if ( t.width() > tw )
+ t.setWidth( tw );
+ int lw = d->stack->lineWidth();
+ bool reverse = TQApplication::reverseLayout();
+ int tabx, taby, stacky, exty, exth, overlap;
+
+ exth = tqstyle().tqpixelMetric( TQStyle::PM_TabBarBaseHeight, this );
+ overlap = tqstyle().tqpixelMetric( TQStyle::PM_TabBarBaseOverlap, this );
+
+ if ( d->pos == Bottom ) {
+ taby = height() - t.height() - lw;
+ stacky = 0;
+ exty = taby - (exth - overlap);
+ } else { // Top
+ taby = 0;
+ stacky = t.height()-lw + (exth - overlap);
+ exty = taby + t.height() - overlap;
+ }
+
+ int lhs = (TQMAX( 0, lw - 2 ) + lcw);
+ int tqalignment = tqstyle().tqstyleHint( TQStyle::SH_TabBar_Alignment, this );
+ if ( tqalignment == Qt::AlignHCenter && t.width() < width() )
+ tabx = lhs + ((width()-(lcw+rcw))/2 - t.width()/2);
+ else if(reverse || tqalignment == Qt::AlignRight)
+ tabx = TQMIN( width() - t.width(), width() - t.width() - lw + 2 ) - lcw;
+ else
+ tabx = lhs;
+
+ d->tabs->setGeometry( tabx, taby, t.width(), t.height() );
+ d->tabBase->setGeometry( 0, exty, width(), exth );
+ if ( exth == 0 )
+ d->tabBase->hide();
+ else
+ d->tabBase->show();
+
+ d->stack->setGeometry( 0, stacky, width(), height() - (exth-overlap) -
+ t.height()+TQMAX(0, lw-2));
+
+ d->dirty = FALSE;
+
+ // move cornerwidgets
+ if ( d->leftCornerWidget ) {
+ int y = ( t.height() / 2 ) - ( d->leftCornerWidget->height() / 2 );
+ int x = ( reverse ? width() - lcw + y : y );
+ d->leftCornerWidget->move( x, y + taby );
+ }
+ if ( d->rightCornerWidget ) {
+ int y = ( t.height() / 2 ) - ( d->rightCornerWidget->height() / 2 );
+ int x = ( reverse ? y : width() - rcw + y );
+ d->rightCornerWidget->move( x, y + taby );
+ }
+ if ( !onlyCheck )
+ update();
+ updateGeometry();
+ if ( autoMask() )
+ updateMask();
+}
+
+/*!
+ \reimp
+*/
+TQSize TQTabWidget::tqsizeHint() const
+{
+ TQSize lc(0, 0), rc(0, 0);
+
+ if (d->leftCornerWidget)
+ lc = d->leftCornerWidget->tqsizeHint();
+ if(d->rightCornerWidget)
+ rc = d->rightCornerWidget->tqsizeHint();
+ if ( !d->dirty ) {
+ TQTabWidget *that = (TQTabWidget*)this;
+ that->setUpLayout( TRUE );
+ }
+ TQSize s( d->stack->tqsizeHint() );
+ TQSize t( d->tabs->tqsizeHint() );
+ if(!tqstyle().tqstyleHint(TQStyle::SH_TabBar_PreferNoArrows, d->tabs))
+ t = t.boundedTo( TQSize(200,200) );
+ else
+ t = t.boundedTo( TQApplication::desktop()->size() );
+
+ TQSize sz( TQMAX( s.width(), t.width() + rc.width() + lc.width() ),
+ s.height() + (TQMAX( rc.height(), TQMAX(lc.height(), t.height()))) + ( d->tabBase->isVisible() ? d->tabBase->height() : 0 ) );
+ return tqstyle().tqsizeFromContents(TQStyle::CT_TabWidget, this, sz).expandedTo(TQApplication::globalStrut());
+}
+
+
+/*!
+ \reimp
+
+ Returns a suitable minimum size for the tab widget.
+*/
+TQSize TQTabWidget::tqminimumSizeHint() const
+{
+ TQSize lc(0, 0), rc(0, 0);
+
+ if(d->leftCornerWidget)
+ lc = d->leftCornerWidget->tqminimumSizeHint();
+ if(d->rightCornerWidget)
+ rc = d->rightCornerWidget->tqminimumSizeHint();
+ if ( !d->dirty ) {
+ TQTabWidget *that = (TQTabWidget*)this;
+ that->setUpLayout( TRUE );
+ }
+ TQSize s( d->stack->tqminimumSizeHint() );
+ TQSize t( d->tabs->tqminimumSizeHint() );
+
+ TQSize sz( TQMAX( s.width(), t.width() + rc.width() + lc.width() ),
+ s.height() + (TQMAX( rc.height(), TQMAX(lc.height(), t.height()))) + ( d->tabBase->isVisible() ? d->tabBase->height() : 0 ) );
+ return tqstyle().tqsizeFromContents(TQStyle::CT_TabWidget, this, sz).expandedTo(TQApplication::globalStrut());
+}
+
+/*!
+ \reimp
+ */
+void TQTabWidget::showEvent( TQShowEvent * )
+{
+ setUpLayout();
+}
+
+
+/*!
+ \property TQTabWidget::tabPosition
+ \brief the position of the tabs in this tab widget
+
+ Possible values for this property are \c TQTabWidget::Top and \c
+ TQTabWidget::Bottom.
+
+ \sa TabPosition
+*/
+TQTabWidget::TabPosition TQTabWidget::tabPosition() const
+{
+ return d->pos;
+}
+
+void TQTabWidget::setTabPosition( TabPosition pos)
+{
+ if (d->pos == pos)
+ return;
+ d->pos = pos;
+ if (d->tabs->tqshape() == TQTabBar::TriangularAbove || d->tabs->tqshape() == TQTabBar::TriangularBelow ) {
+ if ( pos == Bottom )
+ d->tabs->setShape( TQTabBar::TriangularBelow );
+ else
+ d->tabs->setShape( TQTabBar::TriangularAbove );
+ }
+ else {
+ if ( pos == Bottom )
+ d->tabs->setShape( TQTabBar::RoundedBelow );
+ else
+ d->tabs->setShape( TQTabBar::RoundedAbove );
+ }
+ d->tabs->layoutTabs();
+ setUpLayout();
+}
+
+/*!
+ \property TQTabWidget::tabShape
+ \brief the tqshape of the tabs in this tab widget
+
+ Possible values for this property are \c TQTabWidget::Rounded
+ (default) or \c TQTabWidget::Triangular.
+
+ \sa TabShape
+*/
+
+TQTabWidget::TabShape TQTabWidget::tabShape() const
+{
+ return d->tqshape;
+}
+
+void TQTabWidget::setTabShape( TabShape s )
+{
+ if ( d->tqshape == s )
+ return;
+ d->tqshape = s;
+ if ( d->pos == Top ) {
+ if ( s == Rounded )
+ d->tabs->setShape( TQTabBar::RoundedAbove );
+ else
+ d->tabs->setShape( TQTabBar::TriangularAbove );
+ } else {
+ if ( s == Rounded )
+ d->tabs->setShape( TQTabBar::RoundedBelow );
+ else
+ d->tabs->setShape( TQTabBar::TriangularBelow );
+ }
+ d->tabs->layoutTabs();
+ setUpLayout();
+}
+
+
+/*!
+ \property TQTabWidget::margin
+ \brief the margin in this tab widget
+
+ The margin is the distance between the innermost pixel of the
+ frame and the outermost pixel of the pages.
+*/
+int TQTabWidget::margin() const
+{
+ return d->stack->margin();
+}
+
+void TQTabWidget::setMargin( int w )
+{
+ d->stack->setMargin( w );
+ setUpLayout();
+}
+
+
+/*!
+ \reimp
+ */
+void TQTabWidget::styleChange( TQStyle& old )
+{
+ TQWidget::styleChange( old );
+ setUpLayout();
+}
+
+
+/*!
+ \reimp
+ */
+void TQTabWidget::updateMask()
+{
+ if ( !autoMask() )
+ return;
+
+ TQRect r;
+ TQRegion reg( r );
+ reg += TQRegion( d->tabs->tqgeometry() );
+ reg += TQRegion( d->stack->tqgeometry() );
+ setMask( reg );
+}
+
+
+/*!
+ \reimp
+ */
+bool TQTabWidget::eventFilter( TQObject *o, TQEvent * e)
+{
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) ) {
+ if ( e->type() == TQEvent::LanguageChange || e->type() == TQEvent::LayoutHint ) {
+ d->dirty = TRUE;
+ setUpLayout();
+ updateGeometry();
+ } else if ( e->type() == TQEvent::KeyPress ) {
+ TQKeyEvent *ke = (TQKeyEvent*) e;
+ if ( ( ke->key() == TQt::Key_Tab || ke->key() == TQt::Key_Backtab ) &&
+ count() > 1 &&
+ ke->state() & ControlButton ) {
+ int page = currentPageIndex();
+ if ( ke->key() == TQt::Key_Backtab || ke->state() & ShiftButton ) {
+ page--;
+ if ( page < 0 )
+ page = count() - 1;
+ } else {
+ page++;
+ if ( page >= count() )
+ page = 0;
+ }
+ setCurrentPage( page );
+ if ( !tqApp->tqfocusWidget() )
+ d->tabs->setFocus();
+ return TRUE;
+ }
+ }
+
+ } else if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->stack) ) {
+ if ( e->type() == TQEvent::ChildRemoved
+ && ( (TQChildEvent*)e )->child()->isWidgetType() ) {
+ removePage( (TQWidget*) ( (TQChildEvent*)e )->child() );
+ return TRUE;
+ } else if ( e->type() == TQEvent::LayoutHint ) {
+ updateGeometry();
+ }
+ }
+ return FALSE;
+}
+
+/*!
+ Returns the tab page at index position \a index or 0 if the \a
+ index is out of range.
+*/
+TQWidget *TQTabWidget::page( int index ) const
+{
+ TQTab *t = d->tabs->tabAt(index);
+ if ( t )
+ return d->stack->widget( t->id );
+ // else
+ return 0;
+}
+
+/*!
+ Returns the label of the tab at index position \a index or
+ TQString::null if the \a index is out of range.
+*/
+TQString TQTabWidget::label( int index ) const
+{
+ TQTab *t = d->tabs->tabAt( index );
+ if ( t )
+ return t->label;
+ // else
+ return TQString::null;
+}
+
+/*!
+ \property TQTabWidget::count
+ \brief the number of tabs in the tab bar
+*/
+int TQTabWidget::count() const
+{
+ return d->tabs->count();
+}
+
+/*!
+ Returns the iconset of page \a w or a \link TQIconSet::TQIconSet()
+ null iconset\endlink if \a w is not a tab page or does not have an
+ iconset.
+*/
+TQIconSet TQTabWidget::tabIconSet( TQWidget * w ) const
+{
+ int id = d->stack->id( w );
+ if ( id < 0 )
+ return TQIconSet();
+ TQTab* t = d->tabs->tab( id );
+ if ( !t )
+ return TQIconSet();
+ if ( t->iconset )
+ return TQIconSet( *t->iconset );
+ else
+ return TQIconSet();
+}
+
+/*!
+ Sets the iconset for page \a w to \a iconset.
+*/
+void TQTabWidget::setTabIconSet( TQWidget * w, const TQIconSet & iconset )
+{
+ int id = d->stack->id( w );
+ if ( id < 0 )
+ return;
+ TQTab* t = d->tabs->tab( id );
+ if ( !t )
+ return;
+ if ( t->iconset )
+ delete t->iconset;
+ t->iconset = new TQIconSet( iconset );
+
+ d->tabs->layoutTabs();
+ d->tabs->update();
+ setUpLayout();
+}
+
+/*!
+ Sets the tab tool tip for page \a w to \a tip.
+
+ \sa removeTabToolTip(), tabToolTip()
+*/
+void TQTabWidget::setTabToolTip( TQWidget * w, const TQString & tip )
+{
+ int index = d->tabs->indexOf( d->stack->id( w ) );
+ if ( index < 0 )
+ return;
+ d->tabs->setToolTip( index, tip );
+}
+
+/*!
+ Returns the tab tool tip for page \a w or TQString::null if no tool
+ tip has been set.
+
+ \sa setTabToolTip(), removeTabToolTip()
+*/
+TQString TQTabWidget::tabToolTip( TQWidget * w ) const
+{
+ int index = d->tabs->indexOf( d->stack->id( w ) );
+ if ( index < 0 )
+ return TQString();
+ return d->tabs->toolTip( index );
+}
+
+/*!
+ Removes the tab tool tip for page \a w. If the page does not have
+ a tip, nothing happens.
+
+ \sa setTabToolTip(), tabToolTip()
+*/
+void TQTabWidget::removeTabToolTip( TQWidget * w )
+{
+ int index = d->tabs->indexOf( d->stack->id( w ) );
+ if ( index < 0 )
+ return;
+ d->tabs->removeToolTip( index );
+}
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqtabwidget.h b/tqtinterface/qt4/src/widgets/tqtabwidget.h
new file mode 100644
index 0000000..eb11988
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtabwidget.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Definition of TQTabWidget class
+**
+** Created : 990318
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTABWIDGET_H
+#define TQTABWIDGET_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqiconset.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TABWIDGET
+
+class TQTabBar;
+class TQTabWidgetData;
+class TQTab;
+class TQWidgetStack;
+
+
+class TQ_EXPORT TQTabWidget : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( TabPosition )
+ TQ_ENUMS( TabShape )
+ Q_PROPERTY( TabPosition tabPosition READ tabPosition WRITE setTabPosition )
+ Q_PROPERTY( TabShape tabShape READ tabShape WRITE setTabShape )
+ Q_PROPERTY( int margin READ margin WRITE setMargin )
+ Q_PROPERTY( int currentPage READ currentPageIndex WRITE setCurrentPage )
+ Q_PROPERTY( int count READ count )
+ TQ_OVERRIDE( bool autoMask DESIGNABLE true SCRIPTABLE true )
+
+public:
+ TQTabWidget( TQWidget *tqparent = 0, const char *name = 0, WFlags f = 0 );
+ ~TQTabWidget();
+
+ virtual void addTab( TQWidget *, const TQString & ); // ### make these inline in 4.0
+ virtual void addTab( TQWidget *child, const TQIconSet& iconset,
+ const TQString &label );
+ virtual void addTab( TQWidget *, TQTab* );
+
+ virtual void insertTab( TQWidget *, const TQString &, int index = -1 );
+ virtual void insertTab( TQWidget *child, const TQIconSet& iconset,
+ const TQString &label, int index = -1 );
+ virtual void insertTab( TQWidget *, TQTab*, int index = -1 );
+
+ void changeTab( TQWidget *, const TQString &);
+ void changeTab( TQWidget *child, const TQIconSet& iconset,
+ const TQString &label );
+
+ bool isTabEnabled( TQWidget * ) const;
+ void setTabEnabled( TQWidget *, bool );
+
+ void setCornerWidget( TQWidget * w, TQt::Corner corner = TQt::TopRight );
+ TQWidget * cornerWidget( TQt::Corner corner = TQt::TopRight ) const;
+
+ TQString tabLabel( TQWidget * ) const;
+ void setTabLabel( TQWidget *p, const TQString &l );
+
+ TQIconSet tabIconSet( TQWidget * w ) const;
+ void setTabIconSet( TQWidget * w, const TQIconSet & iconset );
+
+ void removeTabToolTip( TQWidget * w );
+ void setTabToolTip( TQWidget * w, const TQString & tip );
+ TQString tabToolTip( TQWidget * w ) const;
+
+ TQWidget * currentPage() const;
+ TQWidget *page( int ) const;
+ TQString label( int ) const;
+ int currentPageIndex() const;
+ int indexOf( TQWidget * ) const;
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ enum TabPosition { Top, Bottom };
+ TabPosition tabPosition() const;
+ void setTabPosition( TabPosition );
+
+ enum TabShape { Rounded, Triangular };
+ TabShape tabShape() const;
+ void setTabShape( TabShape s );
+
+ int margin() const;
+ void setMargin( int );
+
+ int count() const;
+
+public Q_SLOTS:
+ void setCurrentPage( int );
+ virtual void showPage( TQWidget * );
+ virtual void removePage( TQWidget * );
+
+protected:
+ void showEvent( TQShowEvent * );
+ void resizeEvent( TQResizeEvent * );
+ void setTabBar( TQTabBar * );
+ TQTabBar* tabBar() const;
+ void styleChange( TQStyle& );
+ void updateMask();
+ bool eventFilter( TQObject *, TQEvent * );
+
+Q_SIGNALS:
+ void currentChanged( TQWidget * );
+#ifndef TQ_TQDOC
+ void selected( const TQString& );
+#endif
+
+private Q_SLOTS:
+ void showTab( int );
+
+private:
+ TQTabWidgetData *d;
+ void setUpLayout( bool = FALSE );
+ friend class TQTabDialog;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQTabWidget( const TQTabWidget & );
+ TQTabWidget& operator=( const TQTabWidget & );
+#endif
+};
+
+#endif // TQT_NO_TABWIDGET
+
+#endif // TQTABWIDGET_H
diff --git a/tqtinterface/qt4/src/widgets/tqtextbrowser.cpp b/tqtinterface/qt4/src/widgets/tqtextbrowser.cpp
new file mode 100644
index 0000000..af1b078
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtextbrowser.cpp
@@ -0,0 +1,555 @@
+/****************************************************************************
+**
+** Implementation of the TQTextBrowser class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtextbrowser.h"
+#ifndef TQT_NO_TEXTBROWSER
+#include "../kernel/tqrichtext_p.h"
+
+#include "tqapplication.h"
+#include "tqlayout.h"
+#include "tqpainter.h"
+
+#include "tqvaluestack.h"
+#include "stdio.h"
+#include "tqfile.h"
+#include "tqtextstream.h"
+#include "tqlayout.h"
+#include "tqbitmap.h"
+#include "tqtimer.h"
+#include "tqimage.h"
+#include "tqsimplerichtext.h"
+#include "tqdragobject.h"
+#include "tqurl.h"
+#include "tqcursor.h"
+
+/*!
+ \class TQTextBrowser tqtextbrowser.h
+ \brief The TQTextBrowser class provides a rich text browser with hypertext navigation.
+
+ \ingroup advanced
+ \ingroup helpsystem
+ \ingroup text
+ \mainclass
+
+ This class extends TQTextEdit (in read-only mode), adding some
+ navigation functionality so that users can follow links in
+ hypertext documents. The contents of TQTextEdit is set with
+ setText(), but TQTextBrowser has an additional function,
+ setSource(), which makes it possible to set the text to a named
+ document. The name is looked up in the text view's mime source
+ factory. If a document name ends with an anchor (for example, "\c
+ #anchor"), the text browser automatically scrolls to that position
+ (using scrollToAnchor()). When the user clicks on a hyperlink, the
+ browser will call setSource() itself, with the link's \c href
+ value as argument. You can track the current source by connetion
+ to the sourceChanged() signal.
+
+ TQTextBrowser provides backward() and forward() Q_SLOTS which you can
+ use to implement Back and Forward buttons. The home() slot sets
+ the text to the very first document displayed. The linkClicked()
+ signal is emitted when the user clicks a link.
+
+ By using TQTextEdit::setMimeSourceFactory() you can provide your
+ own subclass of TQMimeSourceFactory. This makes it possible to
+ access data from anywhere, for example from a network or from a
+ database. See TQMimeSourceFactory::data() for details.
+
+ If you intend using the mime factory to read the data directly
+ from the file system, you may have to specify the encoding for the
+ file extension you are using. For example:
+ \code
+ mimeSourceFactory()->setExtensionType("qml", "text/utf8");
+ \endcode
+ This is to ensure that the factory is able to resolve the document
+ names.
+
+ TQTextBrowser interprets the tags it processes in accordance with
+ the default style sheet. Change the style sheet with
+ \l{setStyleSheet()}; see TQStyleSheet for details.
+
+ If you want to provide your users with editable rich text use
+ TQTextEdit. If you want a text browser without hypertext navigation
+ use TQTextEdit, and use TQTextEdit::setReadOnly() to disable
+ editing. If you just need to display a small piece of rich text
+ use TQSimpleRichText or TQLabel.
+
+ <img src=qtextbrowser-m.png> <img src=qtextbrowser-w.png>
+*/
+
+class TQTextBrowserData
+{
+public:
+ TQTextBrowserData():textOrSourceChanged(FALSE) {}
+
+ TQValueStack<TQString> stack;
+ TQValueStack<TQString> forwardStack;
+ TQString home;
+ TQString curmain;
+ TQString curmark;
+
+ /*flag necessary to give the linkClicked() signal some meaningful
+ semantics when somebody connected to it calls setText() or
+ setSource() */
+ bool textOrSourceChanged;
+};
+
+
+/*!
+ Constructs an empty TQTextBrowser called \a name, with tqparent \a
+ tqparent.
+*/
+TQTextBrowser::TQTextBrowser(TQWidget *tqparent, const char *name)
+ : TQTextEdit( tqparent, name )
+{
+ setReadOnly( TRUE );
+ d = new TQTextBrowserData;
+
+ viewport()->setMouseTracking( TRUE );
+}
+
+/*!
+ \reimp
+*/
+TQTextBrowser::~TQTextBrowser()
+{
+ delete d;
+}
+
+
+/*!
+ \property TQTextBrowser::source
+ \brief the name of the displayed document.
+
+ This is a TQString::null if no document is displayed or if the
+ source is unknown.
+
+ Setting this property uses the mimeSourceFactory() to lookup the
+ named document. It also checks for optional anchors and scrolls
+ the document accordingly.
+
+ If the first tag in the document is \c{<qt type=detail>}, the
+ document is displayed as a popup rather than as new document in
+ the browser window itself. Otherwise, the document is displayed
+ normally in the text browser with the text set to the contents of
+ the named document with setText().
+
+ If you are using the filesystem access capabilities of the mime
+ source factory, you must ensure that the factory knows about the
+ encoding of specified files; otherwise no data will be available.
+ The default factory handles a couple of common file extensions
+ such as \c *.html and \c *.txt with reasonable defaults. See
+ TQMimeSourceFactory::data() for details.
+*/
+
+TQString TQTextBrowser::source() const
+{
+ if ( d->stack.isEmpty() )
+ return TQString::null;
+ else
+ return d->stack.top();
+}
+
+/*!
+ \property TQTextBrowser::undoDepth
+ \brief This text browser's undo depth.
+*/
+
+/*!
+ \property TQTextBrowser::overwriteMode
+ \brief This text browser's overwrite mode.
+*/
+
+/*!
+ \property TQTextBrowser::modified
+ \brief Whether the contents have been modified.
+*/
+
+/*!
+ \property TQTextBrowser::readOnly
+ \brief Whether the contents are read only.
+*/
+
+/*!
+ \property TQTextBrowser::undoRedoEnabled
+ \brief Whether undo and redo are enabled.
+*/
+
+
+
+/*!
+ Reloads the current set source.
+*/
+
+void TQTextBrowser::reload()
+{
+ TQString s = d->curmain;
+ d->curmain = "";
+ setSource( s );
+}
+
+
+void TQTextBrowser::setSource(const TQString& name)
+{
+#ifndef TQT_NO_CURSOR
+ if ( isVisible() )
+ tqApp->setOverrideCursor( Qt::WaitCursor );
+#endif
+ d->textOrSourceChanged = TRUE;
+ TQString source = name;
+ TQString mark;
+ int hash = name.tqfind('#');
+ if ( hash != -1) {
+ source = name.left( hash );
+ mark = name.mid( hash+1 );
+ }
+
+ if ( source.left(5) == "file:" )
+ source = source.mid(6);
+
+ TQString url = mimeSourceFactory()->makeAbsolute( source, context() );
+ TQString txt;
+ bool dosettext = FALSE;
+
+ if ( !source.isEmpty() && url != d->curmain ) {
+ const TQMimeSource* m =
+ TQT_TQMIMESOURCE_CONST(mimeSourceFactory()->data( source, context() ));
+ if ( !m ){
+ qWarning("TQTextBrowser: no mimesource for %s", source.latin1() );
+ }
+ else {
+ if ( !TQTextDrag::decode( m, txt ) ) {
+ qWarning("TQTextBrowser: cannot decode %s", source.latin1() );
+ }
+ }
+ if ( isVisible() ) {
+ TQString firstTag = txt.left( txt.tqfind( '>' ) + 1 );
+ if ( firstTag.left( 3 ) == "<qt" && firstTag.tqcontains( "type" ) && firstTag.tqcontains( "detail" ) ) {
+ popupDetail( txt, TQCursor::pos() );
+#ifndef TQT_NO_CURSOR
+ tqApp->restoreOverrideCursor();
+#endif
+ return;
+ }
+ }
+
+ d->curmain = url;
+ dosettext = TRUE;
+ }
+
+ d->curmark = mark;
+
+ if ( !mark.isEmpty() ) {
+ url += "#";
+ url += mark;
+ }
+ if ( !d->home )
+ d->home = url;
+
+ if ( d->stack.isEmpty() || d->stack.top() != url)
+ d->stack.push( url );
+
+ int stackCount = (int)d->stack.count();
+ if ( d->stack.top() == url )
+ stackCount--;
+ emit backwardAvailable( stackCount > 0 );
+ stackCount = (int)d->forwardStack.count();
+ if ( d->forwardStack.isEmpty() || d->forwardStack.top() == url )
+ stackCount--;
+ emit forwardAvailable( stackCount > 0 );
+
+ if ( dosettext )
+ TQTextEdit::setText( txt, url );
+
+ if ( !mark.isEmpty() )
+ scrollToAnchor( mark );
+ else
+ setContentsPos( 0, 0 );
+
+#ifndef TQT_NO_CURSOR
+ if ( isVisible() )
+ tqApp->restoreOverrideCursor();
+#endif
+
+ emit sourceChanged( url );
+}
+
+/*!
+ \fn void TQTextBrowser::backwardAvailable(bool available)
+
+ This signal is emitted when the availability of backward()
+ changes. \a available is FALSE when the user is at home();
+ otherwise it is TRUE.
+*/
+
+/*!
+ \fn void TQTextBrowser::forwardAvailable(bool available)
+
+ This signal is emitted when the availability of forward() changes.
+ \a available is TRUE after the user navigates backward() and FALSE
+ when the user navigates or goes forward().
+*/
+
+/*!
+ \fn void TQTextBrowser::sourceChanged( const TQString& src)
+
+ This signal is emitted when the mime source has changed, \a src
+ being the new source.
+
+ Source changes happen both programmatically when calling
+ setSource(), forward(), backword() or home() or when the user
+ clicks on links or presses the equivalent key sequences.
+*/
+
+/*! \fn void TQTextBrowser::highlighted (const TQString &link)
+
+ This signal is emitted when the user has selected but not
+ activated a link in the document. \a link is the value of the \c
+ href i.e. the name of the target document.
+*/
+
+/*!
+ \fn void TQTextBrowser::linkClicked( const TQString& link)
+
+ This signal is emitted when the user clicks a link. The \a link is
+ the value of the \c href i.e. the name of the target document.
+
+ The \a link will be the absolute location of the document, based
+ on the value of the anchor's href tag and the current context of
+ the document.
+
+ \sa anchorClicked(), context()
+*/
+
+/*!
+ \fn void TQTextBrowser::anchorClicked( const TQString& name, const TQString &link)
+
+ This signal is emitted when the user clicks an anchor. The \a link is
+ the value of the \c href i.e. the name of the target document. The \a name
+ is the name of the anchor.
+
+ \sa linkClicked()
+*/
+
+/*!
+ Changes the document displayed to the previous document in the
+ list of documents built by navigating links. Does nothing if there
+ is no previous document.
+
+ \sa forward(), backwardAvailable()
+*/
+void TQTextBrowser::backward()
+{
+ if ( d->stack.count() <= 1)
+ return;
+ d->forwardStack.push( d->stack.pop() );
+ setSource( d->stack.pop() );
+ emit forwardAvailable( TRUE );
+}
+
+/*!
+ Changes the document displayed to the next document in the list of
+ documents built by navigating links. Does nothing if there is no
+ next document.
+
+ \sa backward(), forwardAvailable()
+*/
+void TQTextBrowser::forward()
+{
+ if ( d->forwardStack.isEmpty() )
+ return;
+ setSource( d->forwardStack.pop() );
+ emit forwardAvailable( !d->forwardStack.isEmpty() );
+}
+
+/*!
+ Changes the document displayed to be the first document the
+ browser displayed.
+*/
+void TQTextBrowser::home()
+{
+ if (!d->home.isNull() )
+ setSource( d->home );
+}
+
+/*!
+ The event \a e is used to provide the following keyboard shortcuts:
+ \table
+ \header \i Keypress \i Action
+ \row \i Alt+Left Arrow \i \l backward()
+ \row \i Alt+Right Arrow \i \l forward()
+ \row \i Alt+Up Arrow \i \l home()
+ \endtable
+*/
+void TQTextBrowser::keyPressEvent( TQKeyEvent * e )
+{
+ if ( e->state() & TQt::AltButton ) {
+ switch (e->key()) {
+ case Qt::Key_Right:
+ forward();
+ return;
+ case Qt::Key_Left:
+ backward();
+ return;
+ case Qt::Key_Up:
+ home();
+ return;
+ }
+ }
+ TQTextEdit::keyPressEvent(e);
+}
+
+class TQTextDetailPopup : public TQWidget
+{
+public:
+ TQTextDetailPopup()
+ : TQWidget ( 0, "automatic TQText detail widget", (TQt::WidgetFlags)((TQt::WidgetFlags)WType_Popup | TQt::WDestructiveClose) )
+ {
+ }
+
+protected:
+
+ void mousePressEvent( TQMouseEvent*)
+ {
+ close();
+ }
+};
+
+
+void TQTextBrowser::popupDetail( const TQString& contents, const TQPoint& pos )
+{
+
+ const int shadowWidth = 6; // also used as '5' and '6' and even '8' below
+ const int vMargin = 8;
+ const int hMargin = 12;
+
+ TQWidget* popup = new TQTextDetailPopup;
+ popup->setBackgroundMode( TQt::NoBackground );
+
+ TQSimpleRichText* doc = new TQSimpleRichText( contents, popup->font() );
+ doc->adjustSize();
+ TQRect r( 0, 0, doc->width(), doc->height() );
+
+ int w = r.width() + 2*hMargin;
+ int h = r.height() + 2*vMargin;
+
+ popup->resize( w + shadowWidth, h + shadowWidth );
+
+ // okay, now to tqfind a suitable location
+ //###### we need a global fancy popup positioning somewhere
+ popup->move(pos - popup->rect().center());
+ if (popup->tqgeometry().right() > TQApplication::desktop()->width())
+ popup->move( TQApplication::desktop()->width() - popup->width(),
+ popup->y() );
+ if (popup->tqgeometry().bottom() > TQApplication::desktop()->height())
+ popup->move( popup->x(),
+ TQApplication::desktop()->height() - popup->height() );
+ if ( popup->x() < 0 )
+ popup->move( 0, popup->y() );
+ if ( popup->y() < 0 )
+ popup->move( popup->x(), 0 );
+
+
+ popup->show();
+
+ // now for super-clever shadow stuff. super-clever mostly in
+ // how many window system problems it skirts around.
+
+ TQPainter p( popup );
+ p.setPen( TQApplication::tqpalette().active().foreground() );
+ p.drawRect( 0, 0, w, h );
+ p.setPen( TQApplication::tqpalette().active().mid() );
+ p.setBrush( TQColor( 255, 255, 240 ) );
+ p.drawRect( 1, 1, w-2, h-2 );
+ p.setPen( Qt::black );
+
+ doc->draw( &p, hMargin, vMargin, r, popup->tqcolorGroup(), 0 );
+ delete doc;
+
+ p.drawPoint( w + 5, 6 );
+ p.drawLine( w + 3, 6,
+ w + 5, 8 );
+ p.drawLine( w + 1, 6,
+ w + 5, 10 );
+ int i;
+ for( i=7; i < h; i += 2 )
+ p.drawLine( w, i,
+ w + 5, i + 5 );
+ for( i = w - i + h; i > 6; i -= 2 )
+ p.drawLine( i, h,
+ i + 5, h + 5 );
+ for( ; i > 0 ; i -= 2 )
+ p.drawLine( 6, h + 6 - i,
+ i + 5, h + 5 );
+}
+
+/*!
+ \fn void TQTextBrowser::setText( const TQString &txt )
+
+ \overload
+
+ Sets the text to \a txt.
+*/
+
+/*!
+ \reimp
+*/
+
+void TQTextBrowser::setText( const TQString &txt, const TQString &context )
+{
+ d->textOrSourceChanged = TRUE;
+ d->curmark = "";
+ d->curmain = "";
+ TQTextEdit::setText( txt, context );
+}
+
+void TQTextBrowser::emitHighlighted( const TQString &s )
+{
+ emit highlighted( s );
+}
+
+void TQTextBrowser::emitLinkClicked( const TQString &s )
+{
+ d->textOrSourceChanged = FALSE;
+ emit linkClicked( s );
+ if ( !d->textOrSourceChanged )
+ setSource( s );
+}
+
+#endif // TQT_NO_TEXTBROWSER
diff --git a/tqtinterface/qt4/src/widgets/tqtextbrowser.h b/tqtinterface/qt4/src/widgets/tqtextbrowser.h
new file mode 100644
index 0000000..91bff50
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtextbrowser.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** Definition of the TQTextBrowser class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTEXTBROWSER_H
+#define TQTEXTBROWSER_H
+
+#ifndef TQT_H
+#include "tqptrlist.h"
+#include "tqpixmap.h"
+#include "tqcolor.h"
+#include "tqtextedit.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TEXTBROWSER
+
+class TQTextBrowserData;
+
+class TQ_EXPORT TQTextBrowser : public TQTextEdit
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( TQString source READ source WRITE setSource )
+ TQ_OVERRIDE( int undoDepth DESIGNABLE false SCRIPTABLE false )
+ TQ_OVERRIDE( bool overwriteMode DESIGNABLE false SCRIPTABLE false )
+ TQ_OVERRIDE( bool modified SCRIPTABLE false)
+ TQ_OVERRIDE( bool readOnly DESIGNABLE false SCRIPTABLE false )
+ TQ_OVERRIDE( bool undoRedoEnabled DESIGNABLE false SCRIPTABLE false )
+
+public:
+ TQTextBrowser( TQWidget* tqparent=0, const char* name=0 );
+ ~TQTextBrowser();
+
+ TQString source() const;
+
+public Q_SLOTS:
+ virtual void setSource(const TQString& name);
+ virtual void backward();
+ virtual void forward();
+ virtual void home();
+ virtual void reload();
+ void setText( const TQString &txt ) { setText( txt, TQString::null ); }
+ virtual void setText( const TQString &txt, const TQString &context );
+
+Q_SIGNALS:
+ void backwardAvailable( bool );
+ void forwardAvailable( bool );
+ void sourceChanged( const TQString& );
+ void highlighted( const TQString& );
+ void linkClicked( const TQString& );
+ void anchorClicked( const TQString&, const TQString& );
+
+protected:
+ void keyPressEvent( TQKeyEvent * e);
+
+private:
+ void popupDetail( const TQString& contents, const TQPoint& pos );
+ bool linksEnabled() const { return TRUE; }
+ void emitHighlighted( const TQString &s );
+ void emitLinkClicked( const TQString &s );
+ TQTextBrowserData *d;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQTextBrowser( const TQTextBrowser & );
+ TQTextBrowser& operator=( const TQTextBrowser & );
+#endif
+};
+
+#endif // TQT_NO_TEXTBROWSER
+
+#endif // TQTEXTBROWSER_H
diff --git a/tqtinterface/qt4/src/widgets/tqtextedit.cpp b/tqtinterface/qt4/src/widgets/tqtextedit.cpp
new file mode 100644
index 0000000..62c1d5f
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtextedit.cpp
@@ -0,0 +1,7367 @@
+/****************************************************************************
+**
+** Implementation of the TQTextEdit class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtextedit.h"
+
+#ifndef TQT_NO_TEXTEDIT
+
+#include "../kernel/tqrichtext_p.h"
+#include "tqpainter.h"
+#include "tqpen.h"
+#include "tqbrush.h"
+#include "tqpixmap.h"
+#include "tqfont.h"
+#include "tqcolor.h"
+#include "tqstyle.h"
+#include "tqsize.h"
+#include "tqevent.h"
+#include "tqtimer.h"
+#include "tqapplication.h"
+#include "tqlistbox.h"
+#include "tqvbox.h"
+#include "tqapplication.h"
+#include "tqclipboard.h"
+#include "tqcolordialog.h"
+#include "tqfontdialog.h"
+#include "tqstylesheet.h"
+#include "tqdragobject.h"
+#include "tqurl.h"
+#include "tqcursor.h"
+#include "tqregexp.h"
+#include "tqpopupmenu.h"
+#include "tqptrstack.h"
+#include "tqmetaobject.h"
+#include "tqtextbrowser.h"
+#include <private/tqucom_p.h>
+#include "private/tqsyntaxhighlighter_p.h"
+#include <tqguardedptr.h>
+
+#ifndef TQT_NO_ACCEL
+#include <tqkeysequence.h>
+#define ACCEL_KEY(k) "\t" + TQString(TQKeySequence( TQt::CTRL | TQt::Key_ ## k ))
+#else
+#define ACCEL_KEY(k) "\t" + TQString("Ctrl+" #k)
+#endif
+
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+#define LOGOFFSET(i) d->logOffset + i
+#endif
+
+struct TQUndoRedoInfoPrivate
+{
+ TQTextString text;
+};
+
+class TQTextEditPrivate
+{
+public:
+ TQTextEditPrivate()
+ :preeditStart(-1),preeditLength(-1),ensureCursorVisibleInShowEvent(FALSE),
+ tabChangesFocus(FALSE),
+#ifndef TQT_NO_CLIPBOARD
+ clipboard_mode( TQClipboard::Clipboard ),
+#endif
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ od(0), optimMode(FALSE),
+ maxLogLines(-1),
+ logOffset(0),
+#endif
+ autoFormatting( (uint)TQTextEdit::AutoAll )
+ {
+ for ( int i=0; i<7; i++ )
+ id[i] = 0;
+ }
+ int id[ 7 ];
+ int preeditStart;
+ int preeditLength;
+ uint ensureCursorVisibleInShowEvent : 1;
+ uint tabChangesFocus : 1;
+ TQString scrollToAnchor; // used to deferr scrollToAnchor() until the show event when we are resized
+ TQString pressedName;
+ TQString onName;
+#ifndef TQT_NO_CLIPBOARD
+ TQClipboard::Mode clipboard_mode;
+#endif
+ TQTimer *trippleClickTimer;
+ TQPoint trippleClickPoint;
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ TQTextEditOptimPrivate * od;
+ bool optimMode : 1;
+ int maxLogLines;
+ int logOffset;
+#endif
+ uint autoFormatting;
+};
+
+#ifndef TQT_NO_MIME
+class TQRichTextDrag : public TQTextDrag
+{
+public:
+ TQRichTextDrag( TQWidget *dragSource = 0, const char *name = 0 );
+
+ void setPlainText( const TQString &txt ) { setText( txt ); }
+ void setRichText( const TQString &txt ) { richTxt = txt; }
+
+ virtual TQByteArray tqencodedData( const char *mime ) const;
+ virtual const char* format( int i ) const;
+
+ static bool decode( TQMimeSource *e, TQString &str, const TQCString &mimetype,
+ const TQCString &subtype );
+ static bool canDecode( TQMimeSource* e );
+
+private:
+ TQString richTxt;
+
+};
+
+TQRichTextDrag::TQRichTextDrag( TQWidget *dragSource, const char *name )
+ : TQTextDrag( dragSource, name )
+{
+}
+
+TQByteArray TQRichTextDrag::tqencodedData( const char *mime ) const
+{
+ if ( qstrcmp( "application/x-qrichtext", mime ) == 0 ) {
+ return richTxt.utf8(); // #### perhaps we should use USC2 instead?
+ } else
+ return TQTextDrag::tqencodedData( mime );
+}
+
+bool TQRichTextDrag::decode( TQMimeSource *e, TQString &str, const TQCString &mimetype,
+ const TQCString &subtype )
+{
+ if ( mimetype == "application/x-qrichtext" ) {
+ // do richtext decode
+ const char *mime;
+ int i;
+ for ( i = 0; ( mime = e->format( i ) ); ++i ) {
+ if ( qstrcmp( "application/x-qrichtext", mime ) != 0 )
+ continue;
+ str = TQString::fromUtf8( e->tqencodedData( mime ) );
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ // do a regular text decode
+ TQCString subt = subtype;
+ return TQTextDrag::decode( e, str, subt );
+}
+
+bool TQRichTextDrag::canDecode( TQMimeSource* e )
+{
+ if ( e->provides( "application/x-qrichtext" ) )
+ return TRUE;
+ return TQTextDrag::canDecode( e );
+}
+
+const char* TQRichTextDrag::format( int i ) const
+{
+ if ( TQTextDrag::format( i ) )
+ return TQTextDrag::format( i );
+ if ( TQTextDrag::format( i-1 ) )
+ return "application/x-qrichtext";
+ return 0;
+}
+
+#endif
+
+static bool block_set_tqalignment = FALSE;
+
+/*!
+ \class TQTextEdit tqtextedit.h
+ \brief The TQTextEdit widget provides a powerful single-page rich text editor.
+
+ \ingroup basic
+ \ingroup text
+ \mainclass
+
+ \tableofcontents
+
+ \section1 Introduction and Concepts
+
+ TQTextEdit is an advanced WYSIWYG viewer/editor supporting rich
+ text formatting using HTML-style tags. It is optimized to handle
+ large documents and to respond quickly to user input.
+
+ TQTextEdit has four modes of operation:
+ \table
+ \header \i Mode \i Command \i Notes
+ \row \i Plain Text Editor \i setTextFormat(PlainText)
+ \i Set text with setText(); text() returns plain text. Text
+ attributes (e.g. colors) can be set, but plain text is always
+ returned.
+ \row \i Rich Text Editor \i setTextFormat(RichText)
+ \i Set text with setText(); text() returns rich text. Rich
+ text editing is fairly limited. You can't set margins or
+ insert images for example (although you can read and
+ correctly display files that have margins set and that
+ include images). This mode is mostly useful for editing small
+ amounts of rich text. <sup>1.</sup>
+ \row \i Text Viewer \i setReadOnly(TRUE)
+ \i Set text with setText() or append() (which has no undo
+ history so is faster and uses less memory); text() returns
+ plain or rich text depending on the textFormat(). This mode
+ can correctly display a large subset of HTML tags.
+ \row \i Log Viewer \i setTextFormat(LogText)
+ \i Append text using append(). The widget is set to be read
+ only and rich text support is disabled although a few HTML
+ tags (for color, bold, italic and underline) may be used.
+ (See \link #logtextmode LogText mode\endlink for details.)
+ \endtable
+
+ <sup>1.</sup><small>A more complete API that supports setting
+ margins, images, etc., is planned for a later TQt release.</small>
+
+ TQTextEdit can be used as a syntax highlighting editor when used in
+ conjunction with TQSyntaxHighlighter.
+
+ We recommend that you always call setTextFormat() to set the mode
+ you want to use. If you use \c AutoText then setText() and
+ append() will try to determine whether the text they are given is
+ plain text or rich text. If you use \c RichText then setText() and
+ append() will assume that the text they are given is rich text.
+ insert() simply inserts the text it is given.
+
+ TQTextEdit works on paragraphs and characters. A paragraph is a
+ formatted string which is word-wrapped to fit into the width of
+ the widget. By default when reading plain text, one newline
+ signify a paragraph. A document consists of zero or more
+ paragraphs, indexed from 0. Characters are indexed on a
+ per-paragraph basis, also indexed from 0. The words in the
+ paragraph are aligned in accordance with the paragraph's
+ tqalignment(). Paragraphs are separated by hard line breaks. Each
+ character within a paragraph has its own attributes, for example,
+ font and color.
+
+ The text edit documentation uses the following concepts:
+ \list
+ \i \e{current format} --
+ this is the format at the current cursor position, \e and it
+ is the format of the selected text if any.
+ \i \e{current paragraph} -- the paragraph which tqcontains the
+ cursor.
+ \endlist
+
+ TQTextEdit can display images (using TQMimeSourceFactory), lists and
+ tables. If the text is too large to view within the text edit's
+ viewport, scrollbars will appear. The text edit can load both
+ plain text and HTML files (a subset of HTML 3.2 and 4). The
+ rendering style and the set of valid tags are defined by a
+ styleSheet(). Custom tags can be created and placed in a custom
+ style sheet. Change the style sheet with \l{setStyleSheet()}; see
+ TQStyleSheet for details. The images identified by image tags are
+ displayed if they can be interpreted using the text edit's
+ \l{TQMimeSourceFactory}; see setMimeSourceFactory().
+
+ If you want a text browser with more navigation use TQTextBrowser.
+ If you just need to display a small piece of rich text use TQLabel
+ or TQSimpleRichText.
+
+ If you create a new TQTextEdit, and want to allow the user to edit
+ rich text, call setTextFormat(TQt::RichText) to ensure that the
+ text is treated as rich text. (Rich text uses HTML tags to set
+ text formatting attributes. See TQStyleSheet for information on the
+ HTML tags that are supported.). If you don't call setTextFormat()
+ explicitly the text edit will guess from the text itself whether
+ it is rich text or plain text. This means that if the text looks
+ like HTML or XML it will probably be interpreted as rich text, so
+ you should call setTextFormat(TQt::PlainText) to preserve such
+ text.
+
+ Note that we do not intend to add a full-featured web browser
+ widget to TQt (because that would easily double TQt's size and only
+ a few applications would benefit from it). The rich
+ text support in TQt is designed to provide a fast, portable and
+ efficient way to add reasonable online help facilities to
+ applications, and to provide a basis for rich text editors.
+
+ \section1 Using TQTextEdit as a Display Widget
+
+ TQTextEdit can display a large HTML subset, including tables and
+ images.
+
+ The text is set or tqreplaced using setText() which deletes any
+ existing text and tqreplaces it with the text passed in the
+ setText() call. If you call setText() with legacy HTML (with
+ setTextFormat(RichText) in force), and then call text(), the text
+ that is returned may have different markup, but will render the
+ same. Text can be inserted with insert(), paste(), pasteSubType()
+ and append(). Text that is appended does not go into the undo
+ history; this makes append() faster and consumes less memory. Text
+ can also be cut(). The entire text is deleted with clear() and the
+ selected text is deleted with removeSelectedText(). Selected
+ (marked) text can also be deleted with del() (which will delete
+ the character to the right of the cursor if no text is selected).
+
+ Loading and saving text is achieved using setText() and text(),
+ for example:
+ \code
+ TQFile file( fileName ); // Read the text from a file
+ if ( file.open( IO_ReadOnly ) ) {
+ TQTextStream stream( &file );
+ textEdit->setText( stream.read() );
+ }
+
+ TQFile file( fileName ); // Write the text to a file
+ if ( file.open( IO_WriteOnly ) ) {
+ TQTextStream stream( &file );
+ stream << textEdit->text();
+ textEdit->setModified( FALSE );
+ }
+ \endcode
+
+ By default the text edit wraps words at whitespace to fit within
+ the text edit widget. The setWordWrap() function is used to
+ specify the kind of word wrap you want, or \c NoWrap if you don't
+ want any wrapping. Call setWordWrap() to set a fixed pixel width
+ \c FixedPixelWidth, or character column (e.g. 80 column) \c
+ FixedColumnWidth with the pixels or columns specified with
+ setWrapColumnOrWidth(). If you use word wrap to the widget's width
+ \c WidgetWidth, you can specify whether to break on whitespace or
+ anywhere with setWrapPolicy().
+
+ The background color is set differently than other widgets, using
+ setPaper(). You specify a brush style which could be a plain color
+ or a complex pixmap.
+
+ Hypertext links are automatically underlined; this can be changed
+ with setLinkUnderline(). The tab stop width is set with
+ setTabStopWidth().
+
+ The zoomIn() and zoomOut() functions can be used to resize the
+ text by increasing (decreasing for zoomOut()) the point size used.
+ Images are not affected by the zoom functions.
+
+ The lines() function returns the number of lines in the text and
+ paragraphs() returns the number of paragraphs. The number of lines
+ within a particular paragraph is returned by linesOfParagraph().
+ The length of the entire text in characters is returned by
+ length().
+
+ You can scroll to an anchor in the text, e.g.
+ \c{<a name="anchor">} with scrollToAnchor(). The tqfind() function
+ can be used to tqfind and select a given string within the text.
+
+ A read-only TQTextEdit provides the same functionality as the
+ (obsolete) TQTextView. (TQTextView is still supplied for
+ compatibility with old code.)
+
+ \section2 Read-only key bindings
+
+ When TQTextEdit is used read-only the key-bindings are limited to
+ navigation, and text may only be selected with the mouse:
+ \table
+ \header \i Keypresses \i Action
+ \row \i UpArrow \i Move one line up
+ \row \i DownArrow \i Move one line down
+ \row \i LeftArrow \i Move one character left
+ \row \i RightArrow \i Move one character right
+ \row \i PageUp \i Move one (viewport) page up
+ \row \i PageDown \i Move one (viewport) page down
+ \row \i Home \i Move to the beginning of the text
+ \row \i End \i Move to the end of the text
+ \row \i Shift+Wheel
+ \i Scroll the page horizontally (the Wheel is the mouse wheel)
+ \row \i Ctrl+Wheel \i Zoom the text
+ \endtable
+
+ The text edit may be able to provide some meta-information. For
+ example, the documentTitle() function will return the text from
+ within HTML \c{<title>} tags.
+
+ The text displayed in a text edit has a \e context. The context is
+ a path which the text edit's TQMimeSourceFactory uses to resolve
+ the locations of files and images. It is passed to the
+ mimeSourceFactory() when quering data. (See TQTextEdit() and
+ \l{context()}.)
+
+ \target logtextmode
+ \section2 Using TQTextEdit in LogText Mode
+
+ Setting the text format to \c LogText puts the widget in a special
+ mode which is optimized for very large texts. Editing, word wrap,
+ and rich text support are disabled in this mode (the widget is
+ explicitly made read-only). This allows the text to be stored in a
+ different, more memory efficient manner. However, a certain degree
+ of text formatting is supported through the use of formatting tags.
+ A tag is delimited by \c < and \c {>}. The characters \c {<}, \c >
+ and \c & are escaped by using \c {&lt;}, \c {&gt;} and \c {&amp;}.
+ A tag pair consists of a left and a right tag (or open/close tags).
+ Left-tags mark the starting point for formatting, while right-tags
+ mark the ending point. A right-tag always start with a \c / before
+ the tag keyword. For example \c <b> and \c </b> are a tag pair.
+ Tags can be nested, but they have to be closed in the same order as
+ they are opened. For example, \c <b><u></u></b> is valid, while \c
+ <b><u></b></u> will output an error message.
+
+ By using tags it is possible to change the color, bold, italic and
+ underline settings for a piece of text. A color can be specified
+ by using the HTML font tag \c {<font color=colorname>}. The color
+ name can be one of the color names from the X11 color database, or
+ a RGB hex value (e.g \c {#00ff00}). Example of valid color tags:
+ \c {<font color=red>}, \c {<font color="light blue">}, \c {<font
+ color="#223344">}. Bold, italic and underline settings can be
+ specified by the tags \c {<b>}, \c <i> and \c {<u>}. Note that a
+ tag does not necessarily have to be closed. A valid example:
+ \code
+ This is <font color=red>red</font> while <b>this</b> is <font color=blue>blue</font>.
+ <font color=green><font color=yellow>Yellow,</font> and <u>green</u>.
+ \endcode
+
+ Stylesheets can also be used in LogText mode. To create and use a
+ custom tag, you could do the following:
+ \code
+ TQTextEdit * log = new TQTextEdit( this );
+ log->setTextFormat( TQt::LogText );
+ TQStyleSheetItem * item = new TQStyleSheetItem( log->styleSheet(), "mytag" );
+ item->setColor( "red" );
+ item->setFontWeight( TQFont::Bold );
+ item->setFontUnderline( TRUE );
+ log->append( "This is a <mytag>custom tag</mytag>!" );
+ \endcode
+ Note that only the color, bold, underline and italic attributes of
+ a TQStyleSheetItem is used in LogText mode.
+
+ Note that you can use setMaxLogLines() to limit the number of
+ lines the widget can hold in LogText mode.
+
+ There are a few things that you need to be aware of when the
+ widget is in this mode:
+ \list
+ \i Functions that deal with rich text formatting and cursor
+ movement will not work or return anything valid.
+ \i Lines are equivalent to paragraphs.
+ \endlist
+
+ \section1 Using TQTextEdit as an Editor
+
+ All the information about using TQTextEdit as a display widget also
+ applies here.
+
+ The current format's attributes are set with setItalic(),
+ setBold(), setUnderline(), setFamily() (font family),
+ setPointSize(), setColor() and setCurrentFont(). The current
+ paragraph's tqalignment is set with tqsetAlignment().
+
+ Use setSelection() to select text. The setSelectionAttributes()
+ function is used to indicate how selected text should be
+ displayed. Use hasSelectedText() to tqfind out if any text is
+ selected. The currently selected text's position is available
+ using getSelection() and the selected text itself is returned by
+ selectedText(). The selection can be copied to the clipboard with
+ copy(), or cut to the clipboard with cut(). It can be deleted with
+ removeSelectedText(). The entire text can be selected (or
+ unselected) using selectAll(). TQTextEdit supports multiple
+ selections. Most of the selection functions operate on the default
+ selection, selection 0. If the user presses a non-selecting key,
+ e.g. a cursor key without also holding down Shift, all selections
+ are cleared.
+
+ Set and get the position of the cursor with setCursorPosition()
+ and getCursorPosition() respectively. When the cursor is moved,
+ the Q_SIGNALS currentFontChanged(), currentColorChanged() and
+ currentAlignmentChanged() are emitted to reflect the font, color
+ and tqalignment at the new cursor position.
+
+ If the text changes, the textChanged() signal is emitted, and if
+ the user inserts a new line by pressing Return or Enter,
+ returnPressed() is emitted. The isModified() function will return
+ TRUE if the text has been modified.
+
+ TQTextEdit provides command-based undo and redo. To set the depth
+ of the command history use setUndoDepth() which defaults to 100
+ steps. To undo or redo the last operation call undo() or redo().
+ The Q_SIGNALS undoAvailable() and redoAvailable() indicate whether
+ the undo and redo operations can be executed.
+
+ The indent() function is used to reindent a paragraph. It is
+ useful for code editors, for example in \link designer-manual.book
+ TQt Designer\endlink's code editor \e{Ctrl+I} invokes the indent()
+ function.
+
+ \section2 Editing key bindings
+
+ The list of key-bindings which are implemented for editing:
+ \table
+ \header \i Keypresses \i Action
+ \row \i Backspace \i Delete the character to the left of the cursor
+ \row \i Delete \i Delete the character to the right of the cursor
+ \row \i Ctrl+A \i Move the cursor to the beginning of the line
+ \row \i Ctrl+B \i Move the cursor one character left
+ \row \i Ctrl+C \i Copy the marked text to the clipboard (also
+ Ctrl+Insert under Windows)
+ \row \i Ctrl+D \i Delete the character to the right of the cursor
+ \row \i Ctrl+E \i Move the cursor to the end of the line
+ \row \i Ctrl+F \i Move the cursor one character right
+ \row \i Ctrl+H \i Delete the character to the left of the cursor
+ \row \i Ctrl+K \i Delete to end of line
+ \row \i Ctrl+N \i Move the cursor one line down
+ \row \i Ctrl+P \i Move the cursor one line up
+ \row \i Ctrl+V \i Paste the clipboard text into line edit
+ (also Shift+Insert under Windows)
+ \row \i Ctrl+X \i Cut the marked text, copy to clipboard
+ (also Shift+Delete under Windows)
+ \row \i Ctrl+Z \i Undo the last operation
+ \row \i Ctrl+Y \i Redo the last operation
+ \row \i LeftArrow \i Move the cursor one character left
+ \row \i Ctrl+LeftArrow \i Move the cursor one word left
+ \row \i RightArrow \i Move the cursor one character right
+ \row \i Ctrl+RightArrow \i Move the cursor one word right
+ \row \i UpArrow \i Move the cursor one line up
+ \row \i Ctrl+UpArrow \i Move the cursor one word up
+ \row \i DownArrow \i Move the cursor one line down
+ \row \i Ctrl+Down Arrow \i Move the cursor one word down
+ \row \i PageUp \i Move the cursor one page up
+ \row \i PageDown \i Move the cursor one page down
+ \row \i Home \i Move the cursor to the beginning of the line
+ \row \i Ctrl+Home \i Move the cursor to the beginning of the text
+ \row \i End \i Move the cursor to the end of the line
+ \row \i Ctrl+End \i Move the cursor to the end of the text
+ \row \i Shift+Wheel \i Scroll the page horizontally
+ (the Wheel is the mouse wheel)
+ \row \i Ctrl+Wheel \i Zoom the text
+ \endtable
+
+ To select (mark) text hold down the Shift key whilst pressing one
+ of the movement keystrokes, for example, \e{Shift+Right Arrow}
+ will select the character to the right, and \e{Shift+Ctrl+Right
+ Arrow} will select the word to the right, etc.
+
+ By default the text edit widget operates in insert mode so all
+ text that the user enters is inserted into the text edit and any
+ text to the right of the cursor is moved out of the way. The mode
+ can be changed to overwrite, where new text overwrites any text to
+ the right of the cursor, using setOverwriteMode().
+*/
+
+/*!
+ \enum TQTextEdit::AutoFormatting
+
+ \value AutoNone Do not perform any automatic formatting
+ \value AutoBulletList Only automatically format bulletted lists
+ \value AutoAll Apply all available autoformatting
+*/
+
+
+/*!
+ \enum TQTextEdit::KeyboardAction
+
+ This enum is used by doKeyboardAction() to specify which action
+ should be executed:
+
+ \value ActionBackspace Delete the character to the left of the
+ cursor.
+
+ \value ActionDelete Delete the character to the right of the
+ cursor.
+
+ \value ActionReturn Split the paragraph at the cursor position.
+
+ \value ActionKill If the cursor is not at the end of the
+ paragraph, delete the text from the cursor position until the end
+ of the paragraph. If the cursor is at the end of the paragraph,
+ delete the hard line break at the end of the paragraph: this will
+ cause this paragraph to be joined with the following paragraph.
+
+ \value ActionWordBackspace Delete the word to the left of the
+ cursor position.
+
+ \value ActionWordDelete Delete the word to the right of the
+ cursor position
+
+*/
+
+/*!
+ \enum TQTextEdit::VerticalAlignment
+
+ This enum is used to set the vertical tqalignment of the text.
+
+ \value AlignNormal Normal tqalignment
+ \value AlignSuperScript Superscript
+ \value AlignSubScript Subscript
+*/
+
+/*!
+ \enum TQTextEdit::TextInsertionFlags
+
+ \internal
+
+ \value RedoIndentation
+ \value CheckNewLines
+ \value RemoveSelected
+*/
+
+
+/*!
+ \fn void TQTextEdit::copyAvailable(bool yes)
+
+ This signal is emitted when text is selected or de-selected in the
+ text edit.
+
+ When text is selected this signal will be emitted with \a yes set
+ to TRUE. If no text has been selected or if the selected text is
+ de-selected this signal is emitted with \a yes set to FALSE.
+
+ If \a yes is TRUE then copy() can be used to copy the selection to
+ the clipboard. If \a yes is FALSE then copy() does nothing.
+
+ \sa selectionChanged()
+*/
+
+
+/*!
+ \fn void TQTextEdit::textChanged()
+
+ This signal is emitted whenever the text in the text edit changes.
+
+ \sa setText() append()
+*/
+
+/*!
+ \fn void TQTextEdit::selectionChanged()
+
+ This signal is emitted whenever the selection changes.
+
+ \sa setSelection() copyAvailable()
+*/
+
+/*! \fn TQTextDocument *TQTextEdit::document() const
+
+ \internal
+
+ This function returns the TQTextDocument which is used by the text
+ edit.
+*/
+
+/*! \fn void TQTextEdit::setDocument( TQTextDocument *doc )
+
+ \internal
+
+ This function sets the TQTextDocument which should be used by the text
+ edit to \a doc. This can be used, for example, if you want to
+ display a document using multiple views. You would create a
+ TQTextDocument and set it to the text edits which should display it.
+ You would need to connect to the textChanged() and
+ selectionChanged() Q_SIGNALS of all the text edits and update them all
+ accordingly (preferably with a slight delay for efficiency reasons).
+*/
+
+/*!
+ \enum TQTextEdit::CursorAction
+
+ This enum is used by moveCursor() to specify in which direction
+ the cursor should be moved:
+
+ \value MoveBackward Moves the cursor one character backward
+
+ \value MoveWordBackward Moves the cursor one word backward
+
+ \value MoveForward Moves the cursor one character forward
+
+ \value MoveWordForward Moves the cursor one word forward
+
+ \value MoveUp Moves the cursor up one line
+
+ \value MoveDown Moves the cursor down one line
+
+ \value MoveLineStart Moves the cursor to the beginning of the line
+
+ \value MoveLineEnd Moves the cursor to the end of the line
+
+ \value MoveHome Moves the cursor to the beginning of the document
+
+ \value MoveEnd Moves the cursor to the end of the document
+
+ \value MovePgUp Moves the cursor one viewport page up
+
+ \value MovePgDown Moves the cursor one viewport page down
+*/
+
+/*!
+ \enum TQt::AnchorAttribute
+
+ An anchor has one or more of the following attributes:
+
+ \value AnchorName the name attribute of the anchor. This attribute is
+ used when scrolling to an anchor in the document.
+
+ \value AnchorHref the href attribute of the anchor. This attribute is
+ used when a link is clicked to determine what content to load.
+*/
+
+/*!
+ \property TQTextEdit::overwriteMode
+ \brief the text edit's overwrite mode
+
+ If FALSE (the default) characters entered by the user are inserted
+ with any characters to the right being moved out of the way. If
+ TRUE, the editor is in overwrite mode, i.e. characters entered by
+ the user overwrite any characters to the right of the cursor
+ position.
+*/
+
+/*!
+ \fn void TQTextEdit::setCurrentFont( const TQFont &f )
+
+ Sets the font of the current format to \a f.
+
+ If the widget is in \c LogText mode this function will do
+ nothing. Use setFont() instead.
+
+ \sa currentFont() setPointSize() setFamily()
+*/
+
+/*!
+ \property TQTextEdit::undoDepth
+ \brief the depth of the undo history
+
+ The maximum number of steps in the undo/redo history. The default
+ is 100.
+
+ \sa undo() redo()
+*/
+
+/*!
+ \fn void TQTextEdit::undoAvailable( bool yes )
+
+ This signal is emitted when the availability of undo changes. If
+ \a yes is TRUE, then undo() will work until undoAvailable( FALSE )
+ is next emitted.
+
+ \sa undo() undoDepth()
+*/
+
+/*!
+ \fn void TQTextEdit::modificationChanged( bool m )
+
+ This signal is emitted when the modification status of the
+ document has changed. If \a m is TRUE, the document was modified,
+ otherwise the modification state has been reset to unmodified.
+
+ \sa modified
+*/
+
+/*!
+ \fn void TQTextEdit::redoAvailable( bool yes )
+
+ This signal is emitted when the availability of redo changes. If
+ \a yes is TRUE, then redo() will work until redoAvailable( FALSE )
+ is next emitted.
+
+ \sa redo() undoDepth()
+*/
+
+/*!
+ \fn void TQTextEdit::currentFontChanged( const TQFont &f )
+
+ This signal is emitted if the font of the current format has
+ changed.
+
+ The new font is \a f.
+
+ \sa setCurrentFont()
+*/
+
+/*!
+ \fn void TQTextEdit::currentColorChanged( const TQColor &c )
+
+ This signal is emitted if the color of the current format has
+ changed.
+
+ The new color is \a c.
+
+ \sa setColor()
+*/
+
+/*!
+ \fn void TQTextEdit::currentVerticalAlignmentChanged( VerticalAlignment a )
+
+ This signal is emitted if the vertical tqalignment of the current
+ format has changed.
+
+ The new vertical tqalignment is \a a.
+
+ \sa setVerticalAlignment()
+*/
+
+/*!
+ \fn void TQTextEdit::currentAlignmentChanged( int a )
+
+ This signal is emitted if the tqalignment of the current paragraph
+ has changed.
+
+ The new tqalignment is \a a.
+
+ \sa tqsetAlignment()
+*/
+
+/*!
+ \fn void TQTextEdit::cursorPositionChanged( TQTextCursor *c )
+
+ \internal
+*/
+
+/*!
+ \fn void TQTextEdit::cursorPositionChanged( int para, int pos )
+
+ This signal is emitted if the position of the cursor has changed.
+ \a para tqcontains the paragraph index and \a pos tqcontains the
+ character position within the paragraph.
+
+ \sa setCursorPosition()
+*/
+
+/*!
+ \fn void TQTextEdit::clicked( int para, int pos )
+
+ This signal is emitted when the mouse is clicked on the paragraph
+ \a para at character position \a pos.
+
+ \sa doubleClicked()
+*/
+
+/*! \fn void TQTextEdit::doubleClicked( int para, int pos )
+
+ This signal is emitted when the mouse is double-clicked on the
+ paragraph \a para at character position \a pos.
+
+ \sa clicked()
+*/
+
+
+/*!
+ \fn void TQTextEdit::returnPressed()
+
+ This signal is emitted if the user pressed the Return or the Enter
+ key.
+*/
+
+/*!
+ \fn TQTextCursor *TQTextEdit::textCursor() const
+
+ Returns the text edit's text cursor.
+
+ \warning TQTextCursor is not in the public API, but in special
+ circumstances you might wish to use it.
+*/
+
+/*!
+ Constructs an empty TQTextEdit called \a name, with tqparent \a
+ tqparent.
+*/
+
+TQTextEdit::TQTextEdit( TQWidget *tqparent, const char *name )
+ : TQScrollView( tqparent, name, (WFlags)(TQt::WStaticContents | TQt::WNoAutoErase) ),
+ doc( new TQTextDocument( 0 ) ), undoRedoInfo( doc )
+{
+ init();
+}
+
+/*!
+ Constructs a TQTextEdit called \a name, with tqparent \a tqparent. The
+ text edit will display the text \a text using context \a context.
+
+ The \a context is a path which the text edit's TQMimeSourceFactory
+ uses to resolve the locations of files and images. It is passed to
+ the mimeSourceFactory() when quering data.
+
+ For example if the text tqcontains an image tag,
+ \c{<img src="image.png">}, and the context is "path/to/look/in", the
+ TQMimeSourceFactory will try to load the image from
+ "path/to/look/in/image.png". If the tag was
+ \c{<img src="/image.png">}, the context will not be used (because
+ TQMimeSourceFactory recognizes that we have used an absolute path)
+ and will try to load "/image.png". The context is applied in exactly
+ the same way to \e hrefs, for example,
+ \c{<a href="target.html">Target</a>}, would resolve to
+ "path/to/look/in/target.html".
+*/
+
+TQTextEdit::TQTextEdit( const TQString& text, const TQString& context,
+ TQWidget *tqparent, const char *name)
+ : TQScrollView( tqparent, name, (WFlags)(TQt::WStaticContents | TQt::WNoAutoErase) ),
+ doc( new TQTextDocument( 0 ) ), undoRedoInfo( doc )
+{
+ init();
+ setText( text, context );
+}
+
+/*!
+ \reimp
+*/
+
+TQTextEdit::~TQTextEdit()
+{
+ delete undoRedoInfo.d;
+ undoRedoInfo.d = 0;
+ delete cursor;
+ delete doc;
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode )
+ delete d->od;
+#endif
+ delete d;
+}
+
+void TQTextEdit::init()
+{
+ d = new TQTextEditPrivate;
+ doc->formatCollection()->setPaintDevice( this );
+ undoEnabled = TRUE;
+ readonly = TRUE;
+ setReadOnly( FALSE );
+ setFrameStyle( LineEditPanel | Sunken );
+ connect( doc, TQT_SIGNAL( minimumWidthChanged(int) ),
+ this, TQT_SLOT( documentWidthChanged(int) ) );
+
+ mousePressed = FALSE;
+ inDoubleClick = FALSE;
+ modified = FALSE;
+ onLink = TQString::null;
+ d->onName = TQString::null;
+ overWrite = FALSE;
+ wrapMode = WidgetWidth;
+ wrapWidth = -1;
+ wPolicy = AtWhiteSpace;
+ inDnD = FALSE;
+ doc->setFormatter( new TQTextFormatterBreakWords );
+ doc->formatCollection()->defaultFormat()->setFont( TQScrollView::font() );
+ doc->formatCollection()->defaultFormat()->setColor( tqcolorGroup().color( TQColorGroup::Text ) );
+ currentFormat = doc->formatCollection()->defaultFormat();
+ currentAlignment = TQt::AlignAuto;
+
+ setBackgroundMode( TQt::PaletteBase );
+ viewport()->setBackgroundMode( TQt::PaletteBase );
+ viewport()->setAcceptDrops( TRUE );
+ resizeContents( 0, doc->lastParagraph() ?
+ ( doc->lastParagraph()->paragId() + 1 ) * doc->formatCollection()->defaultFormat()->height() : 0 );
+
+ setKeyCompression( TRUE );
+ viewport()->setMouseTracking( TRUE );
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ cursor = new TQTextCursor( doc );
+
+ formatTimer = new TQTimer( this );
+ connect( formatTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( formatMore() ) );
+ lastFormatted = doc->firstParagraph();
+
+ scrollTimer = new TQTimer( this );
+ connect( scrollTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( autoScrollTimerDone() ) );
+
+ interval = 0;
+ changeIntervalTimer = new TQTimer( this );
+ connect( changeIntervalTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( doChangeInterval() ) );
+
+ cursorVisible = TRUE;
+ blinkTimer = new TQTimer( this );
+ connect( blinkTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( blinkCursor() ) );
+
+#ifndef TQT_NO_DRAGANDDROP
+ dragStartTimer = new TQTimer( this );
+ connect( dragStartTimer, TQT_SIGNAL( timeout() ),
+ this, TQT_SLOT( startDrag() ) );
+#endif
+
+ d->trippleClickTimer = new TQTimer( this );
+
+ formatMore();
+
+ blinkCursorVisible = FALSE;
+
+ viewport()->setFocusProxy( this );
+ viewport()->setFocusPolicy( Qt::WheelFocus );
+ setInputMethodEnabled( TRUE );
+ viewport()->installEventFilter( this );
+ connect( this, TQT_SIGNAL(horizontalSliderReleased()), this, TQT_SLOT(sliderReleased()) );
+ connect( this, TQT_SIGNAL(verticalSliderReleased()), this, TQT_SLOT(sliderReleased()) );
+ installEventFilter( this );
+}
+
+void TQTextEdit::paintDocument( bool drawAll, TQPainter *p, int cx, int cy, int cw, int ch )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ TQ_ASSERT( !d->optimMode );
+ if ( d->optimMode )
+ return;
+#endif
+
+ bool drawCur = hasFocus() || viewport()->hasFocus();
+ if (( hasSelectedText() && !tqstyle().tqstyleHint( TQStyle::SH_BlinkCursorWhenTextSelected ) ) ||
+ isReadOnly() || !cursorVisible || doc->hasSelection( TQTextDocument::IMSelectionText ))
+ drawCur = FALSE;
+ TQColorGroup g = tqcolorGroup();
+ const TQColorGroup::ColorRole backRole = TQPalette::backgroundRoleFromMode(backgroundMode());
+ if ( doc->paper() )
+ g.setBrush( backRole, *doc->paper() );
+
+ if ( contentsY() < doc->y() ) {
+ p->fillRect( contentsX(), contentsY(), visibleWidth(), doc->y(),
+ g.brush( backRole ) );
+ }
+ if ( drawAll && doc->width() - contentsX() < cx + cw ) {
+ p->fillRect( doc->width() - contentsX(), cy, cx + cw - doc->width() + contentsX(), ch,
+ g.brush( backRole ) );
+ }
+
+ p->setBrushOrigin( -contentsX(), -contentsY() );
+
+ lastFormatted = doc->draw( p, cx, cy, cw, ch, g, !drawAll, drawCur, cursor );
+
+ if ( lastFormatted == doc->lastParagraph() )
+ resizeContents( contentsWidth(), doc->height() );
+
+ if ( contentsHeight() < visibleHeight() && ( !doc->lastParagraph() || doc->lastParagraph()->isValid() ) && drawAll )
+ p->fillRect( 0, contentsHeight(), visibleWidth(),
+ visibleHeight() - contentsHeight(), g.brush( backRole ) );
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::drawContents( TQPainter *p, int cx, int cy, int cw, int ch )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ optimDrawContents( p, cx, cy, cw, ch );
+ return;
+ }
+#endif
+ paintDocument( TRUE, p, cx, cy, cw, ch );
+ int v;
+ p->setPen( foregroundColor() );
+ if ( document()->isPageBreakEnabled() && ( v = document()->flow()->pageSize() ) > 0 ) {
+ int l = int(cy / v) * v;
+ while ( l < cy + ch ) {
+ p->drawLine( cx, l, cx + cw - 1, l );
+ l += v;
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::drawContents( TQPainter *p )
+{
+ if ( horizontalScrollBar()->isVisible() &&
+ verticalScrollBar()->isVisible() ) {
+ const TQRect verticalRect = verticalScrollBar()->tqgeometry();
+ const TQRect horizontalRect = horizontalScrollBar()->tqgeometry();
+
+ TQRect cornerRect;
+ cornerRect.setTop( verticalRect.bottom() );
+ cornerRect.setBottom( horizontalRect.bottom() );
+ cornerRect.setLeft( verticalRect.left() );
+ cornerRect.setRight( verticalRect.right() );
+
+ p->fillRect( cornerRect, tqcolorGroup().background() );
+ }
+}
+
+/*!
+ \reimp
+*/
+
+bool TQTextEdit::event( TQEvent *e )
+{
+ if ( e->type() == TQEvent::AccelOverride && !isReadOnly() ) {
+ TQKeyEvent* ke = (TQKeyEvent*) e;
+ switch(ke->state()) {
+ case Qt::NoButton:
+ case TQt::Keypad:
+ case ShiftButton:
+ if ( ke->key() < Key_Escape ) {
+ ke->accept();
+ } else {
+ switch ( ke->key() ) {
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ case Qt::Key_Delete:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_Backspace:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ ke->accept();
+ default:
+ break;
+ }
+ }
+ break;
+
+ case ControlButton:
+ case (int)ControlButton|(int)ShiftButton:
+ case (int)ControlButton|(int)TQt::Keypad:
+ case (int)ControlButton|(int)ShiftButton|(int)TQt::Keypad:
+ switch ( ke->key() ) {
+ case Qt::Key_Tab:
+ case Qt::Key_Backtab:
+ ke->ignore();
+ break;
+// Those are too frequently used for application functionality
+/* case Qt::Key_A:
+ case Qt::Key_B:
+ case Qt::Key_D:
+ case Qt::Key_E:
+ case Qt::Key_F:
+ case Qt::Key_H:
+ case Qt::Key_I:
+ case Qt::Key_K:
+ case Qt::Key_N:
+ case Qt::Key_P:
+ case Qt::Key_T:
+*/
+ case Qt::Key_C:
+ case Qt::Key_V:
+ case Qt::Key_X:
+ case Qt::Key_Y:
+ case Qt::Key_Z:
+ case Qt::Key_Left:
+ case Qt::Key_Right:
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+#if defined (TQ_WS_WIN)
+ case Qt::Key_Insert:
+ case Qt::Key_Delete:
+#endif
+ ke->accept();
+ default:
+ break;
+ }
+ break;
+
+ default:
+ switch ( ke->key() ) {
+#if defined (TQ_WS_WIN)
+ case Qt::Key_Insert:
+ ke->accept();
+#endif
+ default:
+ break;
+ }
+ break;
+ }
+ }
+
+ if ( e->type() == TQEvent::Show ) {
+ if (
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ !d->optimMode &&
+#endif
+ d->ensureCursorVisibleInShowEvent ) {
+ ensureCursorVisible();
+ d->ensureCursorVisibleInShowEvent = FALSE;
+ }
+ if ( !d->scrollToAnchor.isEmpty() ) {
+ scrollToAnchor( d->scrollToAnchor );
+ d->scrollToAnchor = TQString::null;
+ }
+ }
+ return TQWidget::event( e );
+}
+
+/*!
+ Processes the key event, \a e. By default key events are used to
+ provide keyboard navigation and text editing.
+*/
+
+void TQTextEdit::keyPressEvent( TQKeyEvent *e )
+{
+ changeIntervalTimer->stop();
+ interval = 10;
+ bool unknownKey = FALSE;
+ if ( isReadOnly() ) {
+ if ( !handleReadOnlyKeyEvent( e ) )
+ TQScrollView::keyPressEvent( e );
+ changeIntervalTimer->start( 100, TRUE );
+ return;
+ }
+
+
+ bool selChanged = FALSE;
+ for ( int i = 1; i < doc->numSelections(); ++i ) // start with 1 as we don't want to remove the Standard-Selection
+ selChanged = doc->removeSelection( i ) || selChanged;
+
+ if ( selChanged ) {
+ cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
+ repaintChanged();
+ }
+
+ bool clearUndoRedoInfo = TRUE;
+
+
+ switch ( e->key() ) {
+ case Qt::Key_Left:
+ case Qt::Key_Right: {
+ // a bit hacky, but can't change this without introducing new enum values for move and keeping the
+ // correct semantics and movement for BiDi and non BiDi text.
+ CursorAction a;
+ if ( cursor->paragraph()->string()->isRightToLeft() == (e->key() == Qt::Key_Right) )
+ a = e->state() & ControlButton ? MoveWordBackward : MoveBackward;
+ else
+ a = e->state() & ControlButton ? MoveWordForward : MoveForward;
+ moveCursor( a, e->state() & ShiftButton );
+ break;
+ }
+ case Qt::Key_Up:
+ moveCursor( e->state() & ControlButton ? MovePgUp : MoveUp, e->state() & ShiftButton );
+ break;
+ case Qt::Key_Down:
+ moveCursor( e->state() & ControlButton ? MovePgDown : MoveDown, e->state() & ShiftButton );
+ break;
+ case Qt::Key_Home:
+ moveCursor( e->state() & ControlButton ? MoveHome : MoveLineStart, e->state() & ShiftButton );
+ break;
+ case Qt::Key_End:
+ moveCursor( e->state() & ControlButton ? MoveEnd : MoveLineEnd, e->state() & ShiftButton );
+ break;
+ case TQt::Key_Prior:
+ moveCursor( MovePgUp, e->state() & ShiftButton );
+ break;
+ case TQt::Key_Next:
+ moveCursor( MovePgDown, e->state() & ShiftButton );
+ break;
+ case Qt::Key_Return: case Qt::Key_Enter:
+ if ( doc->hasSelection( TQTextDocument::Standard, FALSE ) )
+ removeSelectedText();
+ if ( textFormat() == TQt::RichText && ( e->state() & ControlButton ) ) {
+ // Ctrl-Enter inserts a line break in rich text mode
+ insert( TQString( TQChar( 0x2028) ), TRUE, FALSE );
+ } else {
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ clearUndoRedoInfo = FALSE;
+ doKeyboardAction( ActionReturn );
+ emit returnPressed();
+ }
+ break;
+ case Qt::Key_Delete:
+#if defined (TQ_WS_WIN)
+ if ( e->state() & ShiftButton ) {
+ cut();
+ break;
+ } else
+#endif
+ if ( doc->hasSelection( TQTextDocument::Standard, TRUE ) ) {
+ removeSelectedText();
+ break;
+ }
+ doKeyboardAction( e->state() & ControlButton ? ActionWordDelete
+ : ActionDelete );
+ clearUndoRedoInfo = FALSE;
+
+ break;
+ case Qt::Key_Insert:
+ if ( e->state() & ShiftButton )
+ paste();
+#if defined (TQ_WS_WIN)
+ else if ( e->state() & ControlButton )
+ copy();
+#endif
+ else
+ setOverwriteMode( !isOverwriteMode() );
+ break;
+ case Qt::Key_Backspace:
+#if defined (TQ_WS_WIN)
+ if ( e->state() & AltButton ) {
+ if (e->state() & ControlButton ) {
+ break;
+ } else if ( e->state() & ShiftButton ) {
+ redo();
+ break;
+ } else {
+ undo();
+ break;
+ }
+ } else
+#endif
+ if ( doc->hasSelection( TQTextDocument::Standard, TRUE ) ) {
+ removeSelectedText();
+ break;
+ }
+
+ doKeyboardAction( e->state() & ControlButton ? ActionWordBackspace
+ : ActionBackspace );
+ clearUndoRedoInfo = FALSE;
+ break;
+ case Qt::Key_F16: // Copy key on Sun keyboards
+ copy();
+ break;
+ case Qt::Key_F18: // Paste key on Sun keyboards
+ paste();
+ break;
+ case Qt::Key_F20: // Cut key on Sun keyboards
+ cut();
+ break;
+ case Qt::Key_Direction_L:
+ if ( doc->textFormat() == TQt::PlainText ) {
+ // change the whole doc
+ TQTextParagraph *p = doc->firstParagraph();
+ while ( p ) {
+ p->setDirection( TQChar::DirL );
+ p->tqsetAlignment( TQt::AlignLeft );
+ p->tqinvalidate( 0 );
+ p = p->next();
+ }
+ } else {
+ if ( !cursor->paragraph() || cursor->paragraph()->direction() == TQChar::DirL )
+ return;
+ cursor->paragraph()->setDirection( TQChar::DirL );
+ if ( cursor->paragraph()->length() <= 1&&
+ ( (cursor->paragraph()->tqalignment() & (TQt::AlignLeft | TQt::AlignRight) ) != 0 ) )
+ tqsetAlignment( TQt::AlignLeft );
+ }
+ repaintChanged();
+ break;
+ case Qt::Key_Direction_R:
+ if ( doc->textFormat() == TQt::PlainText ) {
+ // change the whole doc
+ TQTextParagraph *p = doc->firstParagraph();
+ while ( p ) {
+ p->setDirection( TQChar::DirR );
+ p->tqsetAlignment( TQt::AlignRight );
+ p->tqinvalidate( 0 );
+ p = p->next();
+ }
+ } else {
+ if ( !cursor->paragraph() || cursor->paragraph()->direction() == TQChar::DirR )
+ return;
+ cursor->paragraph()->setDirection( TQChar::DirR );
+ if ( cursor->paragraph()->length() <= 1&&
+ ( (cursor->paragraph()->tqalignment() & (TQt::AlignLeft | TQt::AlignRight) ) != 0 ) )
+ tqsetAlignment( TQt::AlignRight );
+ }
+ repaintChanged();
+ break;
+ default: {
+ if ( e->text().length() &&
+ ( !( e->state() & ControlButton ) &&
+#ifndef TQ_OS_MACX
+ !( e->state() & TQt::AltButton ) &&
+#endif
+ !( e->state() & TQt::MetaButton ) ||
+ ( ( (e->state()&ControlButton) | TQt::AltButton ) == (ControlButton|TQt::AltButton) ) ) &&
+ ( !e->ascii() || e->ascii() >= 32 || e->text() == "\t" ) ) {
+ clearUndoRedoInfo = FALSE;
+ if ( e->key() == Qt::Key_Tab ) {
+ if ( d->tabChangesFocus ) {
+ e->ignore();
+ break;
+ }
+ if ( textFormat() == TQt::RichText && cursor->index() == 0
+ && ( cursor->paragraph()->isListItem() || cursor->paragraph()->listDepth() ) ) {
+ clearUndoRedo();
+ undoRedoInfo.type = UndoRedoInfo::Style;
+ undoRedoInfo.id = cursor->paragraph()->paragId();
+ undoRedoInfo.eid = undoRedoInfo.id;
+ undoRedoInfo.styleInformation = TQTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
+ cursor->paragraph()->setListDepth( cursor->paragraph()->listDepth() +1 );
+ clearUndoRedo();
+ drawCursor( FALSE );
+ repaintChanged();
+ drawCursor( TRUE );
+ break;
+ }
+ } else if ( e->key() == TQt::Key_BackTab ) {
+ if ( d->tabChangesFocus ) {
+ e->ignore();
+ break;
+ }
+ }
+
+ if ( ( autoFormatting() & AutoBulletList ) &&
+ textFormat() == TQt::RichText && cursor->index() == 0
+ && !cursor->paragraph()->isListItem()
+ && ( e->text()[0] == '-' || e->text()[0] == '*' ) ) {
+ clearUndoRedo();
+ undoRedoInfo.type = UndoRedoInfo::Style;
+ undoRedoInfo.id = cursor->paragraph()->paragId();
+ undoRedoInfo.eid = undoRedoInfo.id;
+ undoRedoInfo.styleInformation = TQTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
+ setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListDisc );
+ clearUndoRedo();
+ drawCursor( FALSE );
+ repaintChanged();
+ drawCursor( TRUE );
+ break;
+ }
+ if (overWrite && !cursor->atParagEnd() && !doc->hasSelection(TQTextDocument::Standard)) {
+ doKeyboardAction(ActionDelete);
+ clearUndoRedoInfo = FALSE;
+ }
+ TQString t = e->text();
+#ifdef TQ_WS_X11
+ extern bool qt_hebrew_keyboard_hack;
+ if ( qt_hebrew_keyboard_hack ) {
+ // the X11 keyboard tqlayout is broken and does not reverse
+ // braces correctly. This is a hack to get halfway correct
+ // behaviour
+ TQTextParagraph *p = cursor->paragraph();
+ if ( p && p->string() && p->string()->isRightToLeft() ) {
+ TQChar *c = (TQChar *)t.tqunicode();
+ int l = t.length();
+ while( l-- ) {
+ if ( c->mirrored() )
+ *c = c->mirroredChar();
+ c++;
+ }
+ }
+ }
+#endif
+ insert( t, TRUE, FALSE );
+ break;
+ } else if ( e->state() & ControlButton ) {
+ switch ( e->key() ) {
+ case Qt::Key_C: case Qt::Key_F16: // Copy key on Sun keyboards
+ copy();
+ break;
+ case Qt::Key_V:
+ paste();
+ break;
+ case Qt::Key_X:
+ cut();
+ break;
+ case Qt::Key_I: case Qt::Key_T: case Qt::Key_Tab:
+ if ( !d->tabChangesFocus )
+ indent();
+ break;
+ case Qt::Key_A:
+#if defined(TQ_WS_X11)
+ moveCursor( MoveLineStart, e->state() & ShiftButton );
+#else
+ selectAll( TRUE );
+#endif
+ break;
+ case Qt::Key_B:
+ moveCursor( MoveBackward, e->state() & ShiftButton );
+ break;
+ case Qt::Key_F:
+ moveCursor( MoveForward, e->state() & ShiftButton );
+ break;
+ case Qt::Key_D:
+ if ( doc->hasSelection( TQTextDocument::Standard ) ) {
+ removeSelectedText();
+ break;
+ }
+ doKeyboardAction( ActionDelete );
+ clearUndoRedoInfo = FALSE;
+ break;
+ case Qt::Key_H:
+ if ( doc->hasSelection( TQTextDocument::Standard ) ) {
+ removeSelectedText();
+ break;
+ }
+ if ( !cursor->paragraph()->prev() &&
+ cursor->atParagStart() )
+ break;
+
+ doKeyboardAction( ActionBackspace );
+ clearUndoRedoInfo = FALSE;
+ break;
+ case Qt::Key_E:
+ moveCursor( MoveLineEnd, e->state() & ShiftButton );
+ break;
+ case Qt::Key_N:
+ moveCursor( MoveDown, e->state() & ShiftButton );
+ break;
+ case Qt::Key_P:
+ moveCursor( MoveUp, e->state() & ShiftButton );
+ break;
+ case Qt::Key_Z:
+ if(e->state() & ShiftButton)
+ redo();
+ else
+ undo();
+ break;
+ case Qt::Key_Y:
+ redo();
+ break;
+ case Qt::Key_K:
+ doKeyboardAction( ActionKill );
+ break;
+#if defined(TQ_WS_WIN)
+ case Qt::Key_Insert:
+ copy();
+ break;
+ case Qt::Key_Delete:
+ del();
+ break;
+#endif
+ default:
+ unknownKey = FALSE;
+ break;
+ }
+ } else {
+ unknownKey = TRUE;
+ }
+ }
+ }
+
+ emit cursorPositionChanged( cursor );
+ emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
+ if ( clearUndoRedoInfo )
+ clearUndoRedo();
+ changeIntervalTimer->start( 100, TRUE );
+ if ( unknownKey )
+ e->ignore();
+}
+
+/*!
+ \reimp
+*/
+void TQTextEdit::imStartEvent( TQIMEvent *e )
+{
+ if ( isReadOnly() ) {
+ e->ignore();
+ return;
+ }
+
+ if ( hasSelectedText() )
+ removeSelectedText();
+ d->preeditStart = cursor->index();
+ clearUndoRedo();
+ undoRedoInfo.type = UndoRedoInfo::IME;
+}
+
+/*!
+ \reimp
+*/
+void TQTextEdit::imComposeEvent( TQIMEvent *e )
+{
+ if ( isReadOnly() ) {
+ e->ignore();
+ return;
+ }
+
+ doc->removeSelection( TQTextDocument::IMCompositionText );
+ doc->removeSelection( TQTextDocument::IMSelectionText );
+
+ if ( d->preeditLength > 0 && cursor->paragraph() )
+ cursor->paragraph()->remove( d->preeditStart, d->preeditLength );
+ cursor->setIndex( d->preeditStart );
+ d->preeditLength = e->text().length();
+ insert( e->text() );
+ // insert can trigger an imEnd event as it emits a textChanged signal, so better
+ // be careful
+ if(d->preeditStart != -1) {
+ cursor->setIndex( d->preeditStart + d->preeditLength );
+ TQTextCursor c = *cursor;
+ cursor->setIndex( d->preeditStart );
+ doc->setSelectionStart( TQTextDocument::IMCompositionText, *cursor );
+ doc->setSelectionEnd( TQTextDocument::IMCompositionText, c );
+
+ cursor->setIndex( d->preeditStart + e->cursorPos() );
+
+ int sellen = e->selectionLength();
+ if ( sellen > 0 ) {
+ cursor->setIndex( d->preeditStart + e->cursorPos() + sellen );
+ c = *cursor;
+ cursor->setIndex( d->preeditStart + e->cursorPos() );
+ doc->setSelectionStart( TQTextDocument::IMSelectionText, *cursor );
+ doc->setSelectionEnd( TQTextDocument::IMSelectionText, c );
+ cursor->setIndex( d->preeditStart + d->preeditLength );
+ }
+ }
+
+ updateMicroFocusHint();
+ repaintChanged();
+}
+
+/*!
+ \reimp
+*/
+void TQTextEdit::imEndEvent( TQIMEvent *e )
+{
+ if ( isReadOnly() ) {
+ e->ignore();
+ return;
+ }
+
+ doc->removeSelection( TQTextDocument::IMCompositionText );
+ doc->removeSelection( TQTextDocument::IMSelectionText );
+
+ if (undoRedoInfo.type == UndoRedoInfo::IME)
+ undoRedoInfo.type = UndoRedoInfo::Invalid;
+
+ if ( d->preeditLength > 0 && cursor->paragraph() )
+ cursor->paragraph()->remove( d->preeditStart, d->preeditLength );
+ if ( d->preeditStart >= 0 ) {
+ cursor->setIndex( d->preeditStart );
+ insert( e->text() );
+ }
+ d->preeditStart = d->preeditLength = -1;
+
+ repaintChanged();
+}
+
+
+static bool qtextedit_ignore_readonly = FALSE;
+
+/*!
+ Executes keyboard action \a action. This is normally called by a
+ key event handler.
+*/
+
+void TQTextEdit::doKeyboardAction( KeyboardAction action )
+{
+ if ( isReadOnly() && !qtextedit_ignore_readonly )
+ return;
+
+ if ( cursor->nestedDepth() != 0 ) // #### for 3.0, disable editing of tables as this is not advanced enough
+ return;
+
+ lastFormatted = cursor->paragraph();
+ drawCursor( FALSE );
+ bool doUpdateCurrentFormat = TRUE;
+
+ switch ( action ) {
+ case ActionWordDelete:
+ case ActionDelete:
+ if ( action == ActionDelete && !cursor->atParagEnd() ) {
+ if ( undoEnabled ) {
+ checkUndoRedoInfo( UndoRedoInfo::Delete );
+ if ( !undoRedoInfo.valid() ) {
+ undoRedoInfo.id = cursor->paragraph()->paragId();
+ undoRedoInfo.index = cursor->index();
+ undoRedoInfo.d->text = TQString::null;
+ }
+ int idx = cursor->index();
+ do {
+ undoRedoInfo.d->text.insert( undoRedoInfo.d->text.length(), cursor->paragraph()->at( idx++ ), TRUE );
+ } while ( !cursor->paragraph()->string()->validCursorPosition( idx ) );
+ }
+ cursor->remove();
+ } else {
+ clearUndoRedo();
+ doc->setSelectionStart( TQTextDocument::Temp, *cursor );
+ if ( action == ActionWordDelete && !cursor->atParagEnd() ) {
+ cursor->gotoNextWord();
+ } else {
+ cursor->gotoNextLetter();
+ }
+ doc->setSelectionEnd( TQTextDocument::Temp, *cursor );
+ removeSelectedText( TQTextDocument::Temp );
+ }
+ break;
+ case ActionWordBackspace:
+ case ActionBackspace:
+ if ( textFormat() == TQt::RichText
+ && (cursor->paragraph()->isListItem()
+ || cursor->paragraph()->listDepth() )
+ && cursor->index() == 0 ) {
+ if ( undoEnabled ) {
+ clearUndoRedo();
+ undoRedoInfo.type = UndoRedoInfo::Style;
+ undoRedoInfo.id = cursor->paragraph()->paragId();
+ undoRedoInfo.eid = undoRedoInfo.id;
+ undoRedoInfo.styleInformation = TQTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
+ }
+ int ldepth = cursor->paragraph()->listDepth();
+ if ( cursor->paragraph()->isListItem() && ldepth == 1 ) {
+ cursor->paragraph()->setListItem( FALSE );
+ } else if ( TQMAX( ldepth, 1 ) == 1 ) {
+ cursor->paragraph()->setListItem( FALSE );
+ cursor->paragraph()->setListDepth( 0 );
+ } else {
+ cursor->paragraph()->setListDepth( ldepth - 1 );
+ }
+ clearUndoRedo();
+ lastFormatted = cursor->paragraph();
+ repaintChanged();
+ drawCursor( TRUE );
+ return;
+ }
+
+ if ( action == ActionBackspace && !cursor->atParagStart() ) {
+ if ( undoEnabled ) {
+ checkUndoRedoInfo( UndoRedoInfo::Delete );
+ if ( !undoRedoInfo.valid() ) {
+ undoRedoInfo.id = cursor->paragraph()->paragId();
+ undoRedoInfo.index = cursor->index();
+ undoRedoInfo.d->text = TQString::null;
+ }
+ undoRedoInfo.d->text.insert( 0, cursor->paragraph()->at( cursor->index()-1 ), TRUE );
+ undoRedoInfo.index = cursor->index()-1;
+ }
+ cursor->removePreviousChar();
+ lastFormatted = cursor->paragraph();
+ } else if ( cursor->paragraph()->prev()
+ || (action == ActionWordBackspace
+ && !cursor->atParagStart()) ) {
+ clearUndoRedo();
+ doc->setSelectionStart( TQTextDocument::Temp, *cursor );
+ if ( action == ActionWordBackspace && !cursor->atParagStart() ) {
+ cursor->gotoPreviousWord();
+ } else {
+ cursor->gotoPreviousLetter();
+ }
+ doc->setSelectionEnd( TQTextDocument::Temp, *cursor );
+ removeSelectedText( TQTextDocument::Temp );
+ }
+ break;
+ case ActionReturn:
+ if ( undoEnabled ) {
+ checkUndoRedoInfo( UndoRedoInfo::Return );
+ if ( !undoRedoInfo.valid() ) {
+ undoRedoInfo.id = cursor->paragraph()->paragId();
+ undoRedoInfo.index = cursor->index();
+ undoRedoInfo.d->text = TQString::null;
+ }
+ undoRedoInfo.d->text += "\n";
+ }
+ cursor->splitAndInsertEmptyParagraph();
+ if ( cursor->paragraph()->prev() ) {
+ lastFormatted = cursor->paragraph()->prev();
+ lastFormatted->tqinvalidate( 0 );
+ }
+ doUpdateCurrentFormat = FALSE;
+ break;
+ case ActionKill:
+ clearUndoRedo();
+ doc->setSelectionStart( TQTextDocument::Temp, *cursor );
+ if ( cursor->atParagEnd() )
+ cursor->gotoNextLetter();
+ else
+ cursor->setIndex( cursor->paragraph()->length() - 1 );
+ doc->setSelectionEnd( TQTextDocument::Temp, *cursor );
+ removeSelectedText( TQTextDocument::Temp );
+ break;
+ }
+
+ formatMore();
+ repaintChanged();
+ ensureCursorVisible();
+ drawCursor( TRUE );
+ updateMicroFocusHint();
+ if ( doUpdateCurrentFormat )
+ updateCurrentFormat();
+ setModified();
+ emit textChanged();
+}
+
+void TQTextEdit::readFormats( TQTextCursor &c1, TQTextCursor &c2, TQTextString &text, bool fillStyles )
+{
+#ifndef TQT_NO_DATASTREAM
+ TQDataStream styleStream( undoRedoInfo.styleInformation, IO_WriteOnly );
+#endif
+ c2.restoreState();
+ c1.restoreState();
+ int lastIndex = text.length();
+ if ( c1.paragraph() == c2.paragraph() ) {
+ for ( int i = c1.index(); i < c2.index(); ++i )
+ text.insert( lastIndex + i - c1.index(), c1.paragraph()->at( i ), TRUE );
+#ifndef TQT_NO_DATASTREAM
+ if ( fillStyles ) {
+ styleStream << (int) 1;
+ c1.paragraph()->writeStyleInformation( styleStream );
+ }
+#endif
+ } else {
+ int i;
+ for ( i = c1.index(); i < c1.paragraph()->length()-1; ++i )
+ text.insert( lastIndex++, c1.paragraph()->at( i ), TRUE );
+ int num = 2; // start and end, being different
+ text += "\n"; lastIndex++;
+
+ if (c1.paragraph()->next() != c2.paragraph()) {
+ num += text.appendParagraphs(c1.paragraph()->next(), c2.paragraph());
+ lastIndex = text.length();
+ }
+
+ for ( i = 0; i < c2.index(); ++i )
+ text.insert( i + lastIndex, c2.paragraph()->at( i ), TRUE );
+#ifndef TQT_NO_DATASTREAM
+ if ( fillStyles ) {
+ styleStream << num;
+ for ( TQTextParagraph *p = c1.paragraph(); --num >= 0; p = p->next() )
+ p->writeStyleInformation( styleStream );
+ }
+#endif
+ }
+}
+
+/*!
+ Removes the selection \a selNum (by default 0). This does not
+ remove the selected text.
+
+ \sa removeSelectedText()
+*/
+
+void TQTextEdit::removeSelection( int selNum )
+{
+ doc->removeSelection( selNum );
+ repaintChanged();
+}
+
+/*!
+ Deletes the text of selection \a selNum (by default, the default
+ selection, 0). If there is no selected text nothing happens.
+
+ \sa selectedText removeSelection()
+*/
+
+void TQTextEdit::removeSelectedText( int selNum )
+{
+ if(selNum != 0)
+ resetInputContext();
+
+ TQTextCursor c1 = doc->selectionStartCursor( selNum );
+ c1.restoreState();
+ TQTextCursor c2 = doc->selectionEndCursor( selNum );
+ c2.restoreState();
+
+ // ### no support for editing tables yet, plus security for broken selections
+ if ( c1.nestedDepth() || c2.nestedDepth() )
+ return;
+
+ for ( int i = 0; i < (int)doc->numSelections(); ++i ) {
+ if ( i == selNum )
+ continue;
+ doc->removeSelection( i );
+ }
+
+ drawCursor( FALSE );
+ if ( undoEnabled ) {
+ checkUndoRedoInfo( UndoRedoInfo::RemoveSelected );
+ if ( !undoRedoInfo.valid() ) {
+ doc->selectionStart( selNum, undoRedoInfo.id, undoRedoInfo.index );
+ undoRedoInfo.d->text = TQString::null;
+ }
+ readFormats( c1, c2, undoRedoInfo.d->text, TRUE );
+ }
+
+ doc->removeSelectedText( selNum, cursor );
+ if ( cursor->isValid() ) {
+ lastFormatted = 0; // make sync a noop
+ ensureCursorVisible();
+ lastFormatted = cursor->paragraph();
+ formatMore();
+ repaintContents( FALSE );
+ ensureCursorVisible();
+ drawCursor( TRUE );
+ clearUndoRedo();
+#if defined(TQ_WS_WIN)
+ // there seems to be a problem with repainting or erasing the area
+ // of the scrollview which is not the contents on windows
+ if ( contentsHeight() < visibleHeight() )
+ viewport()->tqrepaint( 0, contentsHeight(), visibleWidth(), visibleHeight() - contentsHeight(), TRUE );
+#endif
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ updateMicroFocusHint();
+ } else {
+ delete cursor;
+ cursor = new TQTextCursor( doc );
+ drawCursor( TRUE );
+ repaintContents( TRUE );
+ }
+ setModified();
+ emit textChanged();
+ emit selectionChanged();
+ emit copyAvailable( doc->hasSelection( TQTextDocument::Standard ) );
+}
+
+/*!
+ Moves the text cursor according to \a action. This is normally
+ used by some key event handler. \a select specifies whether the
+ text between the current cursor position and the new position
+ should be selected.
+*/
+
+void TQTextEdit::moveCursor( CursorAction action, bool select )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode )
+ return;
+#endif
+#ifdef TQ_WS_MACX
+ TQTextCursor c1 = *cursor;
+ TQTextCursor c2;
+#endif
+ drawCursor( FALSE );
+ if ( select ) {
+ if ( !doc->hasSelection( TQTextDocument::Standard ) )
+ doc->setSelectionStart( TQTextDocument::Standard, *cursor );
+ moveCursor( action );
+#ifdef TQ_WS_MACX
+ c2 = *cursor;
+ if (c1 == c2)
+ if (action == MoveDown || action == MovePgDown)
+ moveCursor( MoveEnd );
+ else if (action == MoveUp || action == MovePgUp)
+ moveCursor( MoveHome );
+#endif
+ if ( doc->setSelectionEnd( TQTextDocument::Standard, *cursor ) ) {
+ cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
+ repaintChanged();
+ } else {
+ drawCursor( TRUE );
+ }
+ ensureCursorVisible();
+ emit selectionChanged();
+ emit copyAvailable( doc->hasSelection( TQTextDocument::Standard ) );
+ } else {
+#ifdef TQ_WS_MACX
+ TQTextCursor cStart = doc->selectionStartCursor( TQTextDocument::Standard );
+ TQTextCursor cEnd = doc->selectionEndCursor( TQTextDocument::Standard );
+ bool redraw = doc->removeSelection( TQTextDocument::Standard );
+ if (redraw && action == MoveDown)
+ *cursor = cEnd;
+ else if (redraw && action == MoveUp)
+ *cursor = cStart;
+ if (redraw && action == MoveForward)
+ *cursor = cEnd;
+ else if (redraw && action == MoveBackward)
+ *cursor = cStart;
+ else
+ moveCursor( action );
+ c2 = *cursor;
+ if (c1 == c2)
+ if (action == MoveDown)
+ moveCursor( MoveEnd );
+ else if (action == MoveUp)
+ moveCursor( MoveHome );
+#else
+ bool redraw = doc->removeSelection( TQTextDocument::Standard );
+ moveCursor( action );
+#endif
+ if ( !redraw ) {
+ ensureCursorVisible();
+ drawCursor( TRUE );
+ } else {
+ cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
+ repaintChanged();
+ ensureCursorVisible();
+ drawCursor( TRUE );
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ }
+ if ( redraw ) {
+ emit copyAvailable( doc->hasSelection( TQTextDocument::Standard ) );
+ emit selectionChanged();
+ }
+ }
+
+ drawCursor( TRUE );
+ updateCurrentFormat();
+ updateMicroFocusHint();
+}
+
+/*!
+ \overload
+*/
+
+void TQTextEdit::moveCursor( CursorAction action )
+{
+ resetInputContext();
+ switch ( action ) {
+ case MoveBackward:
+ cursor->gotoPreviousLetter();
+ break;
+ case MoveWordBackward:
+ cursor->gotoPreviousWord();
+ break;
+ case MoveForward:
+ cursor->gotoNextLetter();
+ break;
+ case MoveWordForward:
+ cursor->gotoNextWord();
+ break;
+ case MoveUp:
+ cursor->gotoUp();
+ break;
+ case MovePgUp:
+ cursor->gotoPageUp( visibleHeight() );
+ break;
+ case MoveDown:
+ cursor->gotoDown();
+ break;
+ case MovePgDown:
+ cursor->gotoPageDown( visibleHeight() );
+ break;
+ case MoveLineStart:
+ cursor->gotoLineStart();
+ break;
+ case MoveHome:
+ cursor->gotoHome();
+ break;
+ case MoveLineEnd:
+ cursor->gotoLineEnd();
+ break;
+ case MoveEnd:
+ ensureFormatted( doc->lastParagraph() );
+ cursor->gotoEnd();
+ break;
+ }
+ updateMicroFocusHint();
+ updateCurrentFormat();
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::resizeEvent( TQResizeEvent *e )
+{
+ TQScrollView::resizeEvent( e );
+ if ( doc->visibleWidth() == 0 )
+ doResize();
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::viewportResizeEvent( TQResizeEvent *e )
+{
+ TQScrollView::viewportResizeEvent( e );
+ if ( e->oldSize().width() != e->size().width() ) {
+ bool stayAtBottom = e->oldSize().height() != e->size().height() &&
+ contentsY() > 0 && contentsY() >= doc->height() - e->oldSize().height();
+ doResize();
+ if ( stayAtBottom )
+ scrollToBottom();
+ }
+}
+
+/*!
+ Ensures that the cursor is visible by scrolling the text edit if
+ necessary.
+
+ \sa setCursorPosition()
+*/
+
+void TQTextEdit::ensureCursorVisible()
+{
+ // Not visible or the user is draging the window, so don't position to caret yet
+ if ( !isUpdatesEnabled() || !isVisible() || isHorizontalSliderPressed() || isVerticalSliderPressed() ) {
+ d->ensureCursorVisibleInShowEvent = TRUE;
+ return;
+ }
+ sync();
+ TQTextStringChar *chr = cursor->paragraph()->at( cursor->index() );
+ int h = cursor->paragraph()->lineHeightOfChar( cursor->index() );
+ int x = cursor->paragraph()->rect().x() + chr->x + cursor->offsetX();
+ int y = 0; int dummy;
+ cursor->paragraph()->lineHeightOfChar( cursor->index(), &dummy, &y );
+ y += cursor->paragraph()->rect().y() + cursor->offsetY();
+ int w = 1;
+ ensureVisible( x, y + h / 2, w, h / 2 + 2 );
+}
+
+/*!
+ \internal
+*/
+void TQTextEdit::sliderReleased()
+{
+ if ( d->ensureCursorVisibleInShowEvent && isVisible() ) {
+ d->ensureCursorVisibleInShowEvent = FALSE;
+ ensureCursorVisible();
+ }
+}
+
+/*!
+ \internal
+*/
+void TQTextEdit::drawCursor( bool visible )
+{
+ if ( !isUpdatesEnabled() ||
+ !viewport()->isUpdatesEnabled() ||
+ !cursor->paragraph() ||
+ !cursor->paragraph()->isValid() ||
+ ( !tqstyle().tqstyleHint( TQStyle::SH_BlinkCursorWhenTextSelected ) &&
+ ( d->optimMode ? optimHasSelection() : doc->hasSelection( TQTextDocument::Standard, TRUE ))) ||
+ ( visible && !hasFocus() && !viewport()->hasFocus() && !inDnD ) ||
+ doc->hasSelection( TQTextDocument::IMSelectionText ) ||
+ isReadOnly() )
+ return;
+
+ TQPainter p( viewport() );
+ TQRect r( cursor->topParagraph()->rect() );
+ cursor->paragraph()->setChanged( TRUE );
+ p.translate( -contentsX() + cursor->totalOffsetX(), -contentsY() + cursor->totalOffsetY() );
+ TQPixmap *pix = 0;
+ TQColorGroup cg( tqcolorGroup() );
+ const TQColorGroup::ColorRole backRole = TQPalette::backgroundRoleFromMode(backgroundMode());
+ if ( cursor->paragraph()->background() )
+ cg.setBrush( backRole, *cursor->paragraph()->background() );
+ else if ( doc->paper() )
+ cg.setBrush( backRole, *doc->paper() );
+ p.setBrushOrigin( -contentsX(), -contentsY() );
+ cursor->paragraph()->document()->nextDoubleBuffered = TRUE;
+ if ( !cursor->nestedDepth() ) {
+ int h = cursor->paragraph()->lineHeightOfChar( cursor->index() );
+ int dist = 5;
+ if ( ( cursor->paragraph()->tqalignment() & TQt::AlignJustify ) == TQt::AlignJustify )
+ dist = 50;
+ int x = r.x() - cursor->totalOffsetX() + cursor->x() - dist;
+ x = TQMAX( x, 0 );
+ p.setClipRect( TQRect( x - contentsX(),
+ r.y() - cursor->totalOffsetY() + cursor->y() - contentsY(), 2 * dist, h ) );
+ doc->drawParagraph( &p, cursor->paragraph(), x,
+ r.y() - cursor->totalOffsetY() + cursor->y(), 2 * dist, h, pix, cg, visible, cursor );
+ } else {
+ doc->drawParagraph( &p, cursor->paragraph(), r.x() - cursor->totalOffsetX(),
+ r.y() - cursor->totalOffsetY(), r.width(), r.height(),
+ pix, cg, visible, cursor );
+ }
+ cursorVisible = visible;
+}
+
+enum {
+ IdUndo = 0,
+ IdRedo = 1,
+ IdCut = 2,
+ IdCopy = 3,
+ IdPaste = 4,
+ IdClear = 5,
+ IdSelectAll = 6
+};
+
+/*!
+ \reimp
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQTextEdit::contentsWheelEvent( TQWheelEvent *e )
+{
+ if ( isReadOnly() ) {
+ if ( e->state() & ControlButton ) {
+ if ( e->delta() > 0 )
+ zoomOut();
+ else if ( e->delta() < 0 )
+ zoomIn();
+ return;
+ }
+ }
+ TQScrollView::contentsWheelEvent( e );
+}
+#endif
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::contentsMousePressEvent( TQMouseEvent *e )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ optimMousePressEvent( e );
+ return;
+ }
+#endif
+
+ if ( d->trippleClickTimer->isActive() &&
+ ( e->globalPos() - d->trippleClickPoint ).manhattanLength() <
+ TQApplication::startDragDistance() ) {
+ TQTextCursor c1 = *cursor;
+ TQTextCursor c2 = *cursor;
+ c1.gotoLineStart();
+ c2.gotoLineEnd();
+ doc->setSelectionStart( TQTextDocument::Standard, c1 );
+ doc->setSelectionEnd( TQTextDocument::Standard, c2 );
+ *cursor = c2;
+ repaintChanged();
+ mousePressed = TRUE;
+ return;
+ }
+
+ clearUndoRedo();
+ TQTextCursor oldCursor = *cursor;
+ TQTextCursor c = *cursor;
+ mousePos = e->pos();
+ mightStartDrag = FALSE;
+ pressedLink = TQString::null;
+ d->pressedName = TQString::null;
+
+ if ( e->button() == Qt::LeftButton ) {
+ mousePressed = TRUE;
+ drawCursor( FALSE );
+ placeCursor( e->pos() );
+ ensureCursorVisible();
+
+ if ( isReadOnly() && linksEnabled() ) {
+ TQTextCursor c = *cursor;
+ placeCursor( e->pos(), &c, TRUE );
+ if ( c.paragraph() && c.paragraph()->at( c.index() ) &&
+ c.paragraph()->at( c.index() )->isAnchor() ) {
+ pressedLink = c.paragraph()->at( c.index() )->anchorHref();
+ d->pressedName = c.paragraph()->at( c.index() )->anchorName();
+ }
+ }
+
+#ifndef TQT_NO_DRAGANDDROP
+ if ( doc->inSelection( TQTextDocument::Standard, e->pos() ) ) {
+ mightStartDrag = TRUE;
+ drawCursor( TRUE );
+ dragStartTimer->start( TQApplication::startDragTime(), TRUE );
+ dragStartPos = e->pos();
+ return;
+ }
+#endif
+
+ bool redraw = FALSE;
+ if ( doc->hasSelection( TQTextDocument::Standard ) ) {
+ if ( !( e->state() & ShiftButton ) ) {
+ redraw = doc->removeSelection( TQTextDocument::Standard );
+ doc->setSelectionStart( TQTextDocument::Standard, *cursor );
+ } else {
+ redraw = doc->setSelectionEnd( TQTextDocument::Standard, *cursor ) || redraw;
+ }
+ } else {
+ if ( isReadOnly() || !( e->state() & ShiftButton ) ) {
+ doc->setSelectionStart( TQTextDocument::Standard, *cursor );
+ } else {
+ doc->setSelectionStart( TQTextDocument::Standard, c );
+ redraw = doc->setSelectionEnd( TQTextDocument::Standard, *cursor ) || redraw;
+ }
+ }
+
+ for ( int i = 1; i < doc->numSelections(); ++i ) // start with 1 as we don't want to remove the Standard-Selection
+ redraw = doc->removeSelection( i ) || redraw;
+
+ if ( !redraw ) {
+ drawCursor( TRUE );
+ } else {
+ repaintChanged();
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ }
+ } else if ( e->button() == Qt::MidButton ) {
+ bool redraw = doc->removeSelection( TQTextDocument::Standard );
+ if ( !redraw ) {
+ drawCursor( TRUE );
+ } else {
+ repaintChanged();
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ }
+ }
+
+ if ( *cursor != oldCursor )
+ updateCurrentFormat();
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::contentsMouseMoveEvent( TQMouseEvent *e )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ optimMouseMoveEvent( e );
+ return;
+ }
+#endif
+ if ( mousePressed ) {
+#ifndef TQT_NO_DRAGANDDROP
+ if ( mightStartDrag ) {
+ dragStartTimer->stop();
+ if ( ( e->pos() - dragStartPos ).manhattanLength() > TQApplication::startDragDistance() ) {
+ TQGuardedPtr<TQTextEdit> guard( this );
+ startDrag();
+ if (guard.isNull()) // we got deleted during the dnd
+ return;
+ }
+#ifndef TQT_NO_CURSOR
+ if ( !isReadOnly() )
+ viewport()->setCursor( Qt::IBeamCursor );
+#endif
+ return;
+ }
+#endif
+ mousePos = e->pos();
+ handleMouseMove( mousePos );
+ oldMousePos = mousePos;
+ }
+
+#ifndef TQT_NO_CURSOR
+ if ( !isReadOnly() && !mousePressed ) {
+ if ( doc->hasSelection( TQTextDocument::Standard ) && doc->inSelection( TQTextDocument::Standard, e->pos() ) )
+ viewport()->setCursor( Qt::ArrowCursor );
+ else
+ viewport()->setCursor( Qt::IBeamCursor );
+ }
+#endif
+ updateCursor( e->pos() );
+}
+
+void TQTextEdit::copyToClipboard()
+{
+#ifndef TQT_NO_CLIPBOARD
+ if (TQApplication::tqclipboard()->supportsSelection()) {
+ d->clipboard_mode = TQClipboard::Selection;
+
+ // don't listen to selection changes
+ disconnect( TQApplication::tqclipboard(), TQT_SIGNAL(selectionChanged()), this, 0);
+ copy();
+ // listen to selection changes
+ connect( TQApplication::tqclipboard(), TQT_SIGNAL(selectionChanged()),
+ this, TQT_SLOT(clipboardChanged()) );
+
+ d->clipboard_mode = TQClipboard::Clipboard;
+ }
+#endif
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::contentsMouseReleaseEvent( TQMouseEvent * e )
+{
+ if ( !inDoubleClick ) { // could be the release of a dblclick
+ int para = 0;
+ int index = charAt( e->pos(), &para );
+ emit clicked( para, index );
+ }
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ optimMouseReleaseEvent( e );
+ return;
+ }
+#endif
+ TQTextCursor oldCursor = *cursor;
+ if ( scrollTimer->isActive() )
+ scrollTimer->stop();
+#ifndef TQT_NO_DRAGANDDROP
+ if ( dragStartTimer->isActive() )
+ dragStartTimer->stop();
+ if ( mightStartDrag ) {
+ selectAll( FALSE );
+ mousePressed = FALSE;
+ }
+#endif
+ bool mouseWasPressed = mousePressed;
+ if ( mousePressed ) {
+ mousePressed = FALSE;
+ copyToClipboard();
+ }
+#ifndef TQT_NO_CLIPBOARD
+ else if ( e->button() == Qt::MidButton && !isReadOnly() ) {
+ // only do middle-click pasting on systems that have selections (ie. X11)
+ if (TQApplication::tqclipboard()->supportsSelection()) {
+ drawCursor( FALSE );
+ placeCursor( e->pos() );
+ ensureCursorVisible();
+ doc->setSelectionStart( TQTextDocument::Standard, oldCursor );
+ bool redraw = FALSE;
+ if ( doc->hasSelection( TQTextDocument::Standard ) ) {
+ redraw = doc->removeSelection( TQTextDocument::Standard );
+ doc->setSelectionStart( TQTextDocument::Standard, *cursor );
+ } else {
+ doc->setSelectionStart( TQTextDocument::Standard, *cursor );
+ }
+ // start with 1 as we don't want to remove the Standard-Selection
+ for ( int i = 1; i < doc->numSelections(); ++i )
+ redraw = doc->removeSelection( i ) || redraw;
+ if ( !redraw ) {
+ drawCursor( TRUE );
+ } else {
+ repaintChanged();
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( Qt::IBeamCursor );
+#endif
+ }
+ d->clipboard_mode = TQClipboard::Selection;
+ paste();
+ d->clipboard_mode = TQClipboard::Clipboard;
+ }
+ }
+#endif
+ emit cursorPositionChanged( cursor );
+ emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
+ if ( oldCursor != *cursor )
+ updateCurrentFormat();
+ inDoubleClick = FALSE;
+
+#ifndef TQT_NO_NETWORKPROTOCOL
+ if ( ( (!onLink.isEmpty() && onLink == pressedLink)
+ || (!d->onName.isEmpty() && d->onName == d->pressedName))
+ && linksEnabled() && mouseWasPressed ) {
+ if (!onLink.isEmpty()) {
+ TQUrl u( doc->context(), onLink, TRUE );
+ emitLinkClicked( u.toString( FALSE, FALSE ) );
+ }
+ if (::tqqt_cast<TQTextBrowser*>(this)) { // change for 4.0
+ TQConnectionList *clist = tqreceivers(
+ "anchorClicked(const TQString&,const TQString&)");
+ if (!tqsignalsBlocked() && clist) {
+ TQUObject o[3];
+ static_TQUType_TQString.set(o+1, d->onName);
+ static_TQUType_TQString.set(o+2, onLink);
+ activate_signal( clist, o);
+ }
+ }
+
+ // emitting linkClicked() may result in that the cursor winds
+ // up hovering over a different valid link - check this and
+ // set the appropriate cursor tqshape
+ updateCursor( e->pos() );
+ }
+#endif
+ drawCursor( TRUE );
+ if ( !doc->hasSelection( TQTextDocument::Standard, TRUE ) )
+ doc->removeSelection( TQTextDocument::Standard );
+
+ emit copyAvailable( doc->hasSelection( TQTextDocument::Standard ) );
+ emit selectionChanged();
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::contentsMouseDoubleClickEvent( TQMouseEvent * e )
+{
+ if ( e->button() != Qt::LeftButton ) {
+ e->ignore();
+ return;
+ }
+ int para = 0;
+ int index = charAt( e->pos(), &para );
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ TQString str = d->od->lines[ LOGOFFSET(para) ];
+ int startIdx = index, endIdx = index, i;
+ if ( !str[ index ].isSpace() ) {
+ i = startIdx;
+ // tqfind start of word
+ while ( i >= 0 && !str[ i ].isSpace() ) {
+ startIdx = i--;
+ }
+ i = endIdx;
+ // tqfind end of word..
+ while ( (uint) i < str.length() && !str[ i ].isSpace() ) {
+ endIdx = ++i;
+ }
+ // ..and start of next
+ while ( (uint) i < str.length() && str[ i ].isSpace() ) {
+ endIdx = ++i;
+ }
+ optimSetSelection( para, startIdx, para, endIdx );
+ repaintContents( FALSE );
+ }
+ } else
+#endif
+ {
+ TQTextCursor c1 = *cursor;
+ TQTextCursor c2 = *cursor;
+#if defined(TQ_OS_MAC)
+ TQTextParagraph *para = cursor->paragraph();
+ if ( cursor->isValid() ) {
+ if ( para->at( cursor->index() )->c.isLetterOrNumber() ) {
+ while ( c1.index() > 0 &&
+ c1.paragraph()->at( c1.index()-1 )->c.isLetterOrNumber() )
+ c1.gotoPreviousLetter();
+ while ( c2.paragraph()->at( c2.index() )->c.isLetterOrNumber() &&
+ !c2.atParagEnd() )
+ c2.gotoNextLetter();
+ } else if ( para->at( cursor->index() )->c.isSpace() ) {
+ while ( c1.index() > 0 &&
+ c1.paragraph()->at( c1.index()-1 )->c.isSpace() )
+ c1.gotoPreviousLetter();
+ while ( c2.paragraph()->at( c2.index() )->c.isSpace() &&
+ !c2.atParagEnd() )
+ c2.gotoNextLetter();
+ } else if ( !c2.atParagEnd() ) {
+ c2.gotoNextLetter();
+ }
+ }
+#else
+ if ( cursor->index() > 0 && !cursor->paragraph()->at( cursor->index()-1 )->c.isSpace() )
+ c1.gotoPreviousWord();
+ if ( !cursor->paragraph()->at( cursor->index() )->c.isSpace() && !cursor->atParagEnd() )
+ c2.gotoNextWord();
+#endif
+ doc->setSelectionStart( TQTextDocument::Standard, c1 );
+ doc->setSelectionEnd( TQTextDocument::Standard, c2 );
+
+ *cursor = c2;
+
+ repaintChanged();
+
+ d->trippleClickTimer->start( tqApp->doubleClickInterval(), TRUE );
+ d->trippleClickPoint = e->globalPos();
+ }
+ inDoubleClick = TRUE;
+ mousePressed = TRUE;
+ emit doubleClicked( para, index );
+}
+
+#ifndef TQT_NO_DRAGANDDROP
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::contentsDragEnterEvent( TQDragEnterEvent *e )
+{
+ if ( isReadOnly() || !TQTextDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+ e->acceptAction();
+ inDnD = TRUE;
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::contentsDragMoveEvent( TQDragMoveEvent *e )
+{
+ if ( isReadOnly() || !TQTextDrag::canDecode( e ) ) {
+ e->ignore();
+ return;
+ }
+ drawCursor( FALSE );
+ placeCursor( e->pos(), cursor );
+ drawCursor( TRUE );
+ e->acceptAction();
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::contentsDragLeaveEvent( TQDragLeaveEvent * )
+{
+ drawCursor( FALSE );
+ inDnD = FALSE;
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::contentsDropEvent( TQDropEvent *e )
+{
+ if ( isReadOnly() )
+ return;
+ inDnD = FALSE;
+ e->acceptAction();
+ bool intern = FALSE;
+ if ( TQRichTextDrag::canDecode( e ) ) {
+ bool hasSel = doc->hasSelection( TQTextDocument::Standard );
+ bool internalDrag = e->source() == this || e->source() == viewport();
+ int dropId, dropIndex;
+ TQTextCursor insertCursor = *cursor;
+ dropId = cursor->paragraph()->paragId();
+ dropIndex = cursor->index();
+ if ( hasSel && internalDrag ) {
+ TQTextCursor c1, c2;
+ int selStartId, selStartIndex;
+ int selEndId, selEndIndex;
+ c1 = doc->selectionStartCursor( TQTextDocument::Standard );
+ c1.restoreState();
+ c2 = doc->selectionEndCursor( TQTextDocument::Standard );
+ c2.restoreState();
+ selStartId = c1.paragraph()->paragId();
+ selStartIndex = c1.index();
+ selEndId = c2.paragraph()->paragId();
+ selEndIndex = c2.index();
+ if ( ( ( dropId > selStartId ) ||
+ ( dropId == selStartId && dropIndex > selStartIndex ) ) &&
+ ( ( dropId < selEndId ) ||
+ ( dropId == selEndId && dropIndex <= selEndIndex ) ) )
+ insertCursor = c1;
+ if ( dropId == selEndId && dropIndex > selEndIndex ) {
+ insertCursor = c1;
+ if ( selStartId == selEndId ) {
+ insertCursor.setIndex( dropIndex -
+ ( selEndIndex - selStartIndex ) );
+ } else {
+ insertCursor.setIndex( dropIndex - selEndIndex +
+ selStartIndex );
+ }
+ }
+ }
+
+ if ( internalDrag && e->action() == TQDropEvent::Move ) {
+ removeSelectedText();
+ intern = TRUE;
+ doc->removeSelection( TQTextDocument::Standard );
+ } else {
+ doc->removeSelection( TQTextDocument::Standard );
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ }
+ drawCursor( FALSE );
+ cursor->setParagraph( insertCursor.paragraph() );
+ cursor->setIndex( insertCursor.index() );
+ drawCursor( TRUE );
+ if ( !cursor->nestedDepth() ) {
+ TQString subType = "plain";
+ if ( textFormat() != TQt::PlainText ) {
+ if ( e->provides( "application/x-qrichtext" ) )
+ subType = "x-qrichtext";
+ }
+#ifndef TQT_NO_CLIPBOARD
+ pasteSubType( subType.latin1(), e );
+#endif
+ // emit appropriate Q_SIGNALS.
+ emit selectionChanged();
+ emit cursorPositionChanged( cursor );
+ emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
+ } else {
+ if ( intern )
+ undo();
+ e->ignore();
+ }
+ }
+}
+
+#endif
+
+/*!
+ \reimp
+*/
+void TQTextEdit::contentsContextMenuEvent( TQContextMenuEvent *e )
+{
+ clearUndoRedo();
+ mousePressed = FALSE;
+
+ e->accept();
+#ifndef TQT_NO_POPUPMENU
+ TQGuardedPtr<TQTextEdit> that = this;
+ TQGuardedPtr<TQPopupMenu> popup = createPopupMenu( e->pos() );
+ if ( !popup )
+ popup = createPopupMenu();
+ if ( !popup )
+ return;
+
+ int r = popup->exec( e->globalPos() );
+ delete popup;
+ if (!that)
+ return;
+
+ if ( r == d->id[ IdClear ] )
+ clear();
+ else if ( r == d->id[ IdSelectAll ] ) {
+ selectAll();
+#ifndef TQT_NO_CLIPBOARD
+ // if the clipboard support selections, put the newly selected text into
+ // the clipboard
+ if (TQApplication::tqclipboard()->supportsSelection()) {
+ d->clipboard_mode = TQClipboard::Selection;
+
+ // don't listen to selection changes
+ disconnect( TQApplication::tqclipboard(), TQT_SIGNAL(selectionChanged()), this, 0);
+ copy();
+ // listen to selection changes
+ connect( TQApplication::tqclipboard(), TQT_SIGNAL(selectionChanged()),
+ this, TQT_SLOT(clipboardChanged()) );
+
+ d->clipboard_mode = TQClipboard::Clipboard;
+ }
+#endif
+ } else if ( r == d->id[ IdUndo ] )
+ undo();
+ else if ( r == d->id[ IdRedo ] )
+ redo();
+#ifndef TQT_NO_CLIPBOARD
+ else if ( r == d->id[ IdCut ] )
+ cut();
+ else if ( r == d->id[ IdCopy ] )
+ copy();
+ else if ( r == d->id[ IdPaste ] )
+ paste();
+#endif
+#endif
+}
+
+
+void TQTextEdit::autoScrollTimerDone()
+{
+ if ( mousePressed )
+ handleMouseMove( viewportToContents( viewport()->mapFromGlobal( TQCursor::pos() ) ) );
+}
+
+void TQTextEdit::handleMouseMove( const TQPoint& pos )
+{
+ if ( !mousePressed )
+ return;
+
+ if ( !(scrollTimer->isActive() && pos.y() < contentsY()) || pos.y() > contentsY() + visibleHeight() )
+ scrollTimer->start( 100, FALSE );
+ else if ( scrollTimer->isActive() && pos.y() >= contentsY() && pos.y() <= contentsY() + visibleHeight() )
+ scrollTimer->stop();
+
+ drawCursor( FALSE );
+ TQTextCursor oldCursor = *cursor;
+
+ placeCursor( pos );
+
+ if ( inDoubleClick ) {
+ TQTextCursor cl = *cursor;
+ cl.gotoPreviousWord();
+ TQTextCursor cr = *cursor;
+ cr.gotoNextWord();
+
+ int diff = TQABS( oldCursor.paragraph()->at( oldCursor.index() )->x - mousePos.x() );
+ int ldiff = TQABS( cl.paragraph()->at( cl.index() )->x - mousePos.x() );
+ int rdiff = TQABS( cr.paragraph()->at( cr.index() )->x - mousePos.x() );
+
+
+ if ( cursor->paragraph()->lineStartOfChar( cursor->index() ) !=
+ oldCursor.paragraph()->lineStartOfChar( oldCursor.index() ) )
+ diff = 0xFFFFFF;
+
+ if ( rdiff < diff && rdiff < ldiff )
+ *cursor = cr;
+ else if ( ldiff < diff && ldiff < rdiff )
+ *cursor = cl;
+ else
+ *cursor = oldCursor;
+
+ }
+ ensureCursorVisible();
+
+ bool redraw = FALSE;
+ if ( doc->hasSelection( TQTextDocument::Standard ) ) {
+ redraw = doc->setSelectionEnd( TQTextDocument::Standard, *cursor ) || redraw;
+ }
+
+ if ( !redraw ) {
+ drawCursor( TRUE );
+ } else {
+ repaintChanged();
+ drawCursor( TRUE );
+ }
+
+ if ( currentFormat && currentFormat->key() != cursor->paragraph()->at( cursor->index() )->format()->key() ) {
+ currentFormat->removeRef();
+ currentFormat = doc->formatCollection()->format( cursor->paragraph()->at( cursor->index() )->format() );
+ if ( currentFormat->isMisspelled() ) {
+ currentFormat->removeRef();
+ currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() );
+ }
+ emit currentFontChanged( currentFormat->font() );
+ emit currentColorChanged( currentFormat->color() );
+ emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() );
+ }
+
+ if ( currentAlignment != cursor->paragraph()->tqalignment() ) {
+ currentAlignment = cursor->paragraph()->tqalignment();
+ block_set_tqalignment = TRUE;
+ emit currentAlignmentChanged( currentAlignment );
+ block_set_tqalignment = FALSE;
+ }
+}
+
+/*! \internal */
+
+void TQTextEdit::placeCursor( const TQPoint &pos, TQTextCursor *c, bool link )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode )
+ return;
+#endif
+ if ( !c )
+ c = cursor;
+
+ resetInputContext();
+ c->restoreState();
+ TQTextParagraph *s = doc->firstParagraph();
+ c->place( pos, s, link );
+ updateMicroFocusHint();
+}
+
+
+void TQTextEdit::updateMicroFocusHint()
+{
+ TQTextCursor c( *cursor );
+ if ( d->preeditStart != -1 ) {
+ c.setIndex( d->preeditStart );
+ if(doc->hasSelection(TQTextDocument::IMSelectionText)) {
+ int para, index;
+ doc->selectionStart(TQTextDocument::IMSelectionText, para, index);
+ c.setIndex(index);
+ }
+ }
+
+ if ( hasFocus() || viewport()->hasFocus() ) {
+ int h = c.paragraph()->lineHeightOfChar( cursor->index() );
+ if ( !readonly ) {
+ TQFont f = c.paragraph()->at( c.index() )->format()->font();
+ setMicroFocusHint( c.x() - contentsX() + frameWidth(),
+ c.y() + cursor->paragraph()->rect().y() - contentsY() + frameWidth(), 0, h, TRUE, &f );
+ }
+ }
+}
+
+
+
+void TQTextEdit::formatMore()
+{
+ if ( !lastFormatted )
+ return;
+
+ int bottom = contentsHeight();
+ int lastTop = -1;
+ int lastBottom = -1;
+ int to = 20;
+ bool firstVisible = FALSE;
+ TQRect cr( contentsX(), contentsY(), visibleWidth(), visibleHeight() );
+ for ( int i = 0; lastFormatted &&
+ ( i < to || ( firstVisible && lastTop < contentsY()+height() ) );
+ i++ ) {
+ lastFormatted->format();
+ lastTop = lastFormatted->rect().top();
+ lastBottom = lastFormatted->rect().bottom();
+ if ( i == 0 )
+ firstVisible = lastBottom < cr.bottom();
+ bottom = TQMAX( bottom, lastBottom );
+ lastFormatted = lastFormatted->next();
+ }
+
+ if ( bottom > contentsHeight() ) {
+ resizeContents( contentsWidth(), TQMAX( doc->height(), bottom ) );
+ } else if ( !lastFormatted && lastBottom < contentsHeight() ) {
+ resizeContents( contentsWidth(), TQMAX( doc->height(), lastBottom ) );
+ if ( contentsHeight() < visibleHeight() )
+ updateContents( 0, contentsHeight(), visibleWidth(),
+ visibleHeight() - contentsHeight() );
+ }
+
+ if ( lastFormatted )
+ formatTimer->start( interval, TRUE );
+ else
+ interval = TQMAX( 0, interval );
+}
+
+void TQTextEdit::doResize()
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( !d->optimMode )
+#endif
+ {
+ if ( wrapMode == FixedPixelWidth )
+ return;
+ doc->setMinimumWidth( -1 );
+ resizeContents( 0, 0 );
+ doc->setWidth( visibleWidth() );
+ doc->tqinvalidate();
+ lastFormatted = doc->firstParagraph();
+ interval = 0;
+ formatMore();
+ }
+ repaintContents( FALSE );
+}
+
+/*! \internal */
+
+void TQTextEdit::doChangeInterval()
+{
+ interval = 0;
+}
+
+/*!
+ \reimp
+*/
+
+bool TQTextEdit::eventFilter( TQObject *o, TQEvent *e )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( !d->optimMode && (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) || TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(viewport())) ) {
+#else
+ if ( o == this || o == viewport() ) {
+#endif
+ if ( e->type() == TQEvent::FocusIn ) {
+ if ( TQApplication::cursorFlashTime() > 0 )
+ blinkTimer->start( TQApplication::cursorFlashTime() / 2 );
+ drawCursor( TRUE );
+ updateMicroFocusHint();
+ } else if ( e->type() == TQEvent::FocusOut ) {
+ blinkTimer->stop();
+ drawCursor( FALSE );
+ }
+ }
+
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(this) && e->type() == TQEvent::PaletteChange ) {
+ TQColor old( viewport()->tqcolorGroup().color( TQColorGroup::Text ) );
+ if ( old != tqcolorGroup().color( TQColorGroup::Text ) ) {
+ TQColor c( tqcolorGroup().color( TQColorGroup::Text ) );
+ doc->setMinimumWidth( -1 );
+ doc->setDefaultFormat( doc->formatCollection()->defaultFormat()->font(), c );
+ lastFormatted = doc->firstParagraph();
+ formatMore();
+ repaintChanged();
+ }
+ }
+
+ return TQScrollView::eventFilter( o, e );
+}
+
+/*!
+ \obsolete
+ */
+void TQTextEdit::insert( const TQString &text, bool indent,
+ bool checkNewLine, bool removeSelected )
+{
+ uint f = 0;
+ if ( indent )
+ f |= RedoIndentation;
+ if ( checkNewLine )
+ f |= CheckNewLines;
+ if ( removeSelected )
+ f |= RemoveSelected;
+ insert( text, f );
+}
+
+/*!
+ Inserts \a text at the current cursor position.
+
+ The \a insertionFlags define how the text is inserted. If \c
+ RedoIndentation is set, the paragraph is re-indented. If \c
+ CheckNewLines is set, newline characters in \a text result in hard
+ line breaks (i.e. new paragraphs). If \c checkNewLine is not set,
+ the behaviour of the editor is undefined if the \a text tqcontains
+ newlines. (It is not possible to change TQTextEdit's newline handling
+ behavior, but you can use TQString::tqreplace() to preprocess text
+ before inserting it.) If \c RemoveSelected is set, any selected
+ text (in selection 0) is removed before the text is inserted.
+
+ The default flags are \c CheckNewLines | \c RemoveSelected.
+
+ If the widget is in \c LogText mode this function will do nothing.
+
+ \sa paste() pasteSubType()
+*/
+
+
+void TQTextEdit::insert( const TQString &text, uint insertionFlags )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode )
+ return;
+#endif
+
+ if ( cursor->nestedDepth() != 0 ) // #### for 3.0, disable editing of tables as this is not advanced enough
+ return;
+
+ bool indent = insertionFlags & RedoIndentation;
+ bool checkNewLine = insertionFlags & CheckNewLines;
+ bool removeSelected = insertionFlags & RemoveSelected;
+ TQString txt( text );
+ drawCursor( FALSE );
+ if ( !isReadOnly() && doc->hasSelection( TQTextDocument::Standard ) && removeSelected )
+ removeSelectedText();
+ TQTextCursor c2 = *cursor;
+ int oldLen = 0;
+
+ if ( undoEnabled && !isReadOnly() && undoRedoInfo.type != UndoRedoInfo::IME ) {
+ checkUndoRedoInfo( UndoRedoInfo::Insert );
+
+ if (undoRedoInfo.valid() && undoRedoInfo.index + undoRedoInfo.d->text.length() != cursor->index()) {
+ clearUndoRedo();
+ undoRedoInfo.type = UndoRedoInfo::Insert;
+ }
+
+ if ( !undoRedoInfo.valid() ) {
+ undoRedoInfo.id = cursor->paragraph()->paragId();
+ undoRedoInfo.index = cursor->index();
+ undoRedoInfo.d->text = TQString::null;
+ }
+ oldLen = undoRedoInfo.d->text.length();
+ }
+
+ lastFormatted = checkNewLine && cursor->paragraph()->prev() ?
+ cursor->paragraph()->prev() : cursor->paragraph();
+ TQTextCursor oldCursor = *cursor;
+ cursor->insert( txt, checkNewLine );
+ if ( doc->useFormatCollection() && !doc->preProcessor() ) {
+ doc->setSelectionStart( TQTextDocument::Temp, oldCursor );
+ doc->setSelectionEnd( TQTextDocument::Temp, *cursor );
+ doc->setFormat( TQTextDocument::Temp, currentFormat, TQTextFormat::Format );
+ doc->removeSelection( TQTextDocument::Temp );
+ }
+
+ if ( indent && ( txt == "{" || txt == "}" || txt == ":" || txt == "#" ) )
+ cursor->indent();
+ formatMore();
+ repaintChanged();
+ ensureCursorVisible();
+ drawCursor( TRUE );
+
+ if ( undoEnabled && !isReadOnly() && undoRedoInfo.type != UndoRedoInfo::IME ) {
+ undoRedoInfo.d->text += txt;
+ if ( !doc->preProcessor() ) {
+ for ( int i = 0; i < (int)txt.length(); ++i ) {
+ if ( txt[ i ] != '\n' && c2.paragraph()->at( c2.index() )->format() ) {
+ c2.paragraph()->at( c2.index() )->format()->addRef();
+ undoRedoInfo.d->text.
+ setFormat( oldLen + i,
+ c2.paragraph()->at( c2.index() )->format(), TRUE );
+ }
+ c2.gotoNextLetter();
+ }
+ }
+ }
+
+ if ( !removeSelected ) {
+ doc->setSelectionStart( TQTextDocument::Standard, oldCursor );
+ doc->setSelectionEnd( TQTextDocument::Standard, *cursor );
+ repaintChanged();
+ }
+ updateMicroFocusHint();
+ setModified();
+ emit textChanged();
+}
+
+/*!
+ Inserts \a text in the paragraph \a para at position \a index.
+*/
+
+void TQTextEdit::insertAt( const TQString &text, int para, int index )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ optimInsert( text, para, index );
+ return;
+ }
+#endif
+ resetInputContext();
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return;
+ removeSelection( TQTextDocument::Standard );
+ TQTextCursor tmp = *cursor;
+ cursor->setParagraph( p );
+ cursor->setIndex( index );
+ insert( text, FALSE, TRUE, FALSE );
+ *cursor = tmp;
+ removeSelection( TQTextDocument::Standard );
+}
+
+/*!
+ Inserts \a text as a new paragraph at position \a para. If \a para
+ is -1, the text is appended. Use append() if the append operation
+ is performance critical.
+*/
+
+void TQTextEdit::insertParagraph( const TQString &text, int para )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ optimInsert( text + "\n", para, 0 );
+ return;
+ }
+#endif
+ resetInputContext();
+ for ( int i = 0; i < (int)doc->numSelections(); ++i )
+ doc->removeSelection( i );
+
+ TQTextParagraph *p = doc->paragAt( para );
+
+ bool append = !p;
+ if ( !p )
+ p = doc->lastParagraph();
+
+ TQTextCursor old = *cursor;
+ drawCursor( FALSE );
+
+ cursor->setParagraph( p );
+ cursor->setIndex( 0 );
+ clearUndoRedo();
+ qtextedit_ignore_readonly = TRUE;
+ if ( append && cursor->paragraph()->length() > 1 ) {
+ cursor->setIndex( cursor->paragraph()->length() - 1 );
+ doKeyboardAction( ActionReturn );
+ }
+ insert( text, FALSE, TRUE, TRUE );
+ doKeyboardAction( ActionReturn );
+ qtextedit_ignore_readonly = FALSE;
+
+ drawCursor( FALSE );
+ *cursor = old;
+ drawCursor( TRUE );
+
+ repaintChanged();
+}
+
+/*!
+ Removes the paragraph \a para.
+*/
+
+void TQTextEdit::removeParagraph( int para )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode )
+ return;
+#endif
+ resetInputContext();
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return;
+
+ for ( int i = 0; i < doc->numSelections(); ++i )
+ doc->removeSelection( i );
+
+ TQTextCursor start( doc );
+ TQTextCursor end( doc );
+ start.setParagraph( p );
+ start.setIndex( 0 );
+ end.setParagraph( p );
+ end.setIndex( p->length() - 1 );
+
+ if ( !(p == doc->firstParagraph() && p == doc->lastParagraph()) ) {
+ if ( p->next() ) {
+ end.setParagraph( p->next() );
+ end.setIndex( 0 );
+ } else if ( p->prev() ) {
+ start.setParagraph( p->prev() );
+ start.setIndex( p->prev()->length() - 1 );
+ }
+ }
+
+ doc->setSelectionStart( TQTextDocument::Temp, start );
+ doc->setSelectionEnd( TQTextDocument::Temp, end );
+ removeSelectedText( TQTextDocument::Temp );
+}
+
+/*!
+ Undoes the last operation.
+
+ If there is no operation to undo, i.e. there is no undo step in
+ the undo/redo history, nothing happens.
+
+ \sa undoAvailable() redo() undoDepth()
+*/
+
+void TQTextEdit::undo()
+{
+ clearUndoRedo();
+ if ( isReadOnly() || !doc->commands()->isUndoAvailable() || !undoEnabled )
+ return;
+
+ resetInputContext();
+ for ( int i = 0; i < (int)doc->numSelections(); ++i )
+ doc->removeSelection( i );
+
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+
+ clearUndoRedo();
+ drawCursor( FALSE );
+ TQTextCursor *c = doc->undo( cursor );
+ if ( !c ) {
+ drawCursor( TRUE );
+ return;
+ }
+ lastFormatted = 0;
+ repaintChanged();
+ ensureCursorVisible();
+ drawCursor( TRUE );
+ updateMicroFocusHint();
+ setModified();
+ // ### If we get back to a completely blank textedit, it
+ // is possible that cursor is invalid and further actions
+ // might not fix the problem, so reset the cursor here.
+ // This is copied from removeSeletedText(), it might be
+ // okay to just call that.
+ if ( !cursor->isValid() ) {
+ delete cursor;
+ cursor = new TQTextCursor( doc );
+ drawCursor( TRUE );
+ repaintContents( TRUE );
+ }
+ emit undoAvailable( isUndoAvailable() );
+ emit redoAvailable( isRedoAvailable() );
+ emit textChanged();
+}
+
+/*!
+ Redoes the last operation.
+
+ If there is no operation to redo, i.e. there is no redo step in
+ the undo/redo history, nothing happens.
+
+ \sa redoAvailable() undo() undoDepth()
+*/
+
+void TQTextEdit::redo()
+{
+ if ( isReadOnly() || !doc->commands()->isRedoAvailable() || !undoEnabled )
+ return;
+
+ resetInputContext();
+ for ( int i = 0; i < (int)doc->numSelections(); ++i )
+ doc->removeSelection( i );
+
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+
+ clearUndoRedo();
+ drawCursor( FALSE );
+ TQTextCursor *c = doc->redo( cursor );
+ if ( !c ) {
+ drawCursor( TRUE );
+ return;
+ }
+ lastFormatted = 0;
+ ensureCursorVisible();
+ repaintChanged();
+ ensureCursorVisible();
+ drawCursor( TRUE );
+ updateMicroFocusHint();
+ setModified();
+ emit undoAvailable( isUndoAvailable() );
+ emit redoAvailable( isRedoAvailable() );
+ emit textChanged();
+}
+
+/*!
+ Pastes the text from the clipboard into the text edit at the
+ current cursor position. Only plain text is pasted.
+
+ If there is no text in the clipboard nothing happens.
+
+ \sa pasteSubType() cut() TQTextEdit::copy()
+*/
+
+void TQTextEdit::paste()
+{
+#ifndef TQT_NO_MIMECLIPBOARD
+ if ( isReadOnly() )
+ return;
+ TQString subType = "plain";
+ if ( textFormat() != TQt::PlainText ) {
+ TQMimeSource *m = TQApplication::tqclipboard()->data( d->clipboard_mode );
+ if ( !m )
+ return;
+ if ( m->provides( "application/x-qrichtext" ) )
+ subType = "x-qrichtext";
+ }
+
+ pasteSubType( subType.latin1() );
+ updateMicroFocusHint();
+#endif
+}
+
+void TQTextEdit::checkUndoRedoInfo( UndoRedoInfo::Type t )
+{
+ if ( undoRedoInfo.valid() && t != undoRedoInfo.type ) {
+ clearUndoRedo();
+ }
+ undoRedoInfo.type = t;
+}
+
+/*!
+ Repaints any paragraphs that have changed.
+
+ Although used extensively internally you shouldn't need to call
+ this yourself.
+*/
+
+void TQTextEdit::repaintChanged()
+{
+ if ( !isUpdatesEnabled() || !viewport()->isUpdatesEnabled() )
+ return;
+
+ TQPainter p( viewport() );
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ optimDrawContents( &p, contentsX(), contentsY(), visibleWidth(), visibleHeight() );
+ return;
+ }
+#endif
+ p.translate( -contentsX(), -contentsY() );
+ paintDocument( FALSE, &p, contentsX(), contentsY(), visibleWidth(), visibleHeight() );
+}
+
+#ifndef TQT_NO_MIME
+TQTextDrag *TQTextEdit::dragObject( TQWidget *tqparent ) const
+{
+ if ( !doc->hasSelection( TQTextDocument::Standard ) ||
+ doc->selectedText( TQTextDocument::Standard ).isEmpty() )
+ return 0;
+ if ( textFormat() != TQt::RichText )
+ return new TQTextDrag( doc->selectedText( TQTextDocument::Standard ), tqparent );
+ TQRichTextDrag *drag = new TQRichTextDrag( tqparent );
+ drag->setPlainText( doc->selectedText( TQTextDocument::Standard ) );
+ drag->setRichText( doc->selectedText( TQTextDocument::Standard, TRUE ) );
+ return drag;
+}
+#endif
+
+/*!
+ Copies the selected text (from selection 0) to the clipboard and
+ deletes it from the text edit.
+
+ If there is no selected text (in selection 0) nothing happens.
+
+ \sa TQTextEdit::copy() paste() pasteSubType()
+*/
+
+void TQTextEdit::cut()
+{
+ if ( isReadOnly() )
+ return;
+ resetInputContext();
+ normalCopy();
+ removeSelectedText();
+ updateMicroFocusHint();
+}
+
+void TQTextEdit::normalCopy()
+{
+#ifndef TQT_NO_MIME
+ TQTextDrag *drag = dragObject();
+ if ( !drag )
+ return;
+#ifndef TQT_NO_MIMECLIPBOARD
+ TQApplication::tqclipboard()->setData( drag, d->clipboard_mode );
+#endif // TQT_NO_MIMECLIPBOARD
+#endif // TQT_NO_MIME
+}
+
+/*!
+ Copies any selected text (from selection 0) to the clipboard.
+
+ \sa hasSelectedText() copyAvailable()
+*/
+
+void TQTextEdit::copy()
+{
+#ifndef TQT_NO_CLIPBOARD
+# ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode && optimHasSelection() )
+ TQApplication::tqclipboard()->setText( optimSelectedText(), d->clipboard_mode );
+ else
+ normalCopy();
+# else
+ normalCopy();
+# endif
+#endif
+}
+
+/*!
+ \internal
+
+ Re-indents the current paragraph.
+*/
+
+void TQTextEdit::indent()
+{
+ if ( isReadOnly() )
+ return;
+
+ drawCursor( FALSE );
+ if ( !doc->hasSelection( TQTextDocument::Standard ) )
+ cursor->indent();
+ else
+ doc->indentSelection( TQTextDocument::Standard );
+ repaintChanged();
+ drawCursor( TRUE );
+ setModified();
+ emit textChanged();
+}
+
+/*!
+ Reimplemented to allow tabbing through links. If \a n is TRUE the
+ tab moves the focus to the next child; if \a n is FALSE the tab
+ moves the focus to the previous child. Returns TRUE if the focus
+ was moved; otherwise returns FALSE.
+ */
+
+bool TQTextEdit::focusNextPrevChild( bool n )
+{
+ if ( !isReadOnly() || !linksEnabled() )
+ return FALSE;
+ bool b = doc->focusNextPrevChild( n );
+ repaintChanged();
+ if ( b ) {
+ TQTextParagraph *p = doc->focusIndicator.parag;
+ int start = doc->focusIndicator.start;
+ int len = doc->focusIndicator.len;
+
+ int y = p->rect().y();
+ while ( p
+ && len == 0
+ && p->at( start )->isCustom()
+ && p->at( start )->customItem()->isNested() ) {
+
+ TQTextTable *t = (TQTextTable*)p->at( start )->customItem();
+ TQPtrList<TQTextTableCell> cells = t->tqtableCells();
+ TQTextTableCell *c;
+ for ( c = cells.first(); c; c = cells.next() ) {
+ TQTextDocument *cellDoc = c->richText();
+ if ( cellDoc->hasFocusParagraph() ) {
+ y += c->tqgeometry().y() + c->verticalAlignmentOffset();
+
+ p = cellDoc->focusIndicator.parag;
+ start = cellDoc->focusIndicator.start;
+ len = cellDoc->focusIndicator.len;
+ if ( p )
+ y += p->rect().y();
+
+ break;
+ }
+ }
+ }
+ setContentsPos( contentsX(), TQMIN( y, contentsHeight() - visibleHeight() ) );
+ }
+ return b;
+}
+
+/*!
+ \internal
+
+ This functions sets the current format to \a f. Only the fields of \a
+ f which are specified by the \a flags are used.
+*/
+
+void TQTextEdit::setFormat( TQTextFormat *f, int flags )
+{
+ if ( doc->hasSelection( TQTextDocument::Standard ) ) {
+ drawCursor( FALSE );
+ TQTextCursor c1 = doc->selectionStartCursor( TQTextDocument::Standard );
+ c1.restoreState();
+ TQTextCursor c2 = doc->selectionEndCursor( TQTextDocument::Standard );
+ c2.restoreState();
+ if ( undoEnabled ) {
+ clearUndoRedo();
+ undoRedoInfo.type = UndoRedoInfo::Format;
+ undoRedoInfo.id = c1.paragraph()->paragId();
+ undoRedoInfo.index = c1.index();
+ undoRedoInfo.eid = c2.paragraph()->paragId();
+ undoRedoInfo.eindex = c2.index();
+ readFormats( c1, c2, undoRedoInfo.d->text );
+ undoRedoInfo.format = f;
+ undoRedoInfo.flags = flags;
+ clearUndoRedo();
+ }
+ doc->setFormat( TQTextDocument::Standard, f, flags );
+ repaintChanged();
+ formatMore();
+ drawCursor( TRUE );
+ setModified();
+ emit textChanged();
+ }
+ if ( currentFormat && currentFormat->key() != f->key() ) {
+ currentFormat->removeRef();
+ currentFormat = doc->formatCollection()->format( f );
+ if ( currentFormat->isMisspelled() ) {
+ currentFormat->removeRef();
+ currentFormat = doc->formatCollection()->format( currentFormat->font(),
+ currentFormat->color() );
+ }
+ emit currentFontChanged( currentFormat->font() );
+ emit currentColorChanged( currentFormat->color() );
+ emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() );
+ if ( cursor->index() == cursor->paragraph()->length() - 1 ) {
+ currentFormat->addRef();
+ cursor->paragraph()->string()->setFormat( cursor->index(), currentFormat, TRUE );
+ if ( cursor->paragraph()->length() == 1 ) {
+ cursor->paragraph()->tqinvalidate( 0 );
+ cursor->paragraph()->format();
+ repaintChanged();
+ }
+ }
+ }
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::setPalette( const TQPalette &p )
+{
+ TQScrollView::setPalette( p );
+ if ( textFormat() == TQt::PlainText ) {
+ TQTextFormat *f = doc->formatCollection()->defaultFormat();
+ f->setColor( tqcolorGroup().text() );
+ updateContents();
+ }
+}
+
+/*! \internal
+ \warning In TQt 3.1 we will provide a cleaer API for the
+ functionality which is provided by this function and in TQt 4.0 this
+ function will go away.
+
+ Sets the paragraph style of the current paragraph
+ to \a dm. If \a dm is TQStyleSheetItem::DisplayListItem, the
+ type of the list item is set to \a listStyle.
+
+ \sa tqsetAlignment()
+*/
+
+void TQTextEdit::setParagType( TQStyleSheetItem::DisplayMode dm,
+ TQStyleSheetItem::ListStyle listStyle )
+{
+ if ( isReadOnly() )
+ return;
+
+ drawCursor( FALSE );
+ TQTextParagraph *start = cursor->paragraph();
+ TQTextParagraph *end = start;
+ if ( doc->hasSelection( TQTextDocument::Standard ) ) {
+ start = doc->selectionStartCursor( TQTextDocument::Standard ).topParagraph();
+ end = doc->selectionEndCursor( TQTextDocument::Standard ).topParagraph();
+ if ( end->paragId() < start->paragId() )
+ return; // do not trust our selections
+ }
+
+ clearUndoRedo();
+ undoRedoInfo.type = UndoRedoInfo::Style;
+ undoRedoInfo.id = start->paragId();
+ undoRedoInfo.eid = end->paragId();
+ undoRedoInfo.styleInformation = TQTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
+
+ while ( start != end->next() ) {
+ start->setListStyle( listStyle );
+ if ( dm == TQStyleSheetItem::DisplayListItem ) {
+ start->setListItem( TRUE );
+ if( start->listDepth() == 0 )
+ start->setListDepth( 1 );
+ } else if ( start->isListItem() ) {
+ start->setListItem( FALSE );
+ start->setListDepth( TQMAX( start->listDepth()-1, 0 ) );
+ }
+ start = start->next();
+ }
+
+ clearUndoRedo();
+ repaintChanged();
+ formatMore();
+ drawCursor( TRUE );
+ setModified();
+ emit textChanged();
+}
+
+/*!
+ Sets the tqalignment of the current paragraph to \a a. Valid
+ alignments are \c TQt::AlignLeft, \c TQt::AlignRight,
+ \c TQt::AlignJustify and \c TQt::AlignCenter (which centers
+ horizontally).
+*/
+
+void TQTextEdit::tqsetAlignment( int a )
+{
+ if ( isReadOnly() || block_set_tqalignment )
+ return;
+
+ drawCursor( FALSE );
+ TQTextParagraph *start = cursor->paragraph();
+ TQTextParagraph *end = start;
+ if ( doc->hasSelection( TQTextDocument::Standard ) ) {
+ start = doc->selectionStartCursor( TQTextDocument::Standard ).topParagraph();
+ end = doc->selectionEndCursor( TQTextDocument::Standard ).topParagraph();
+ if ( end->paragId() < start->paragId() )
+ return; // do not trust our selections
+ }
+
+ clearUndoRedo();
+ undoRedoInfo.type = UndoRedoInfo::Style;
+ undoRedoInfo.id = start->paragId();
+ undoRedoInfo.eid = end->paragId();
+ undoRedoInfo.styleInformation = TQTextStyleCommand::readStyleInformation( doc, undoRedoInfo.id, undoRedoInfo.eid );
+
+ while ( start != end->next() ) {
+ start->tqsetAlignment( a );
+ start = start->next();
+ }
+
+ clearUndoRedo();
+ repaintChanged();
+ formatMore();
+ drawCursor( TRUE );
+ if ( currentAlignment != a ) {
+ currentAlignment = a;
+ emit currentAlignmentChanged( currentAlignment );
+ }
+ setModified();
+ emit textChanged();
+}
+
+void TQTextEdit::updateCurrentFormat()
+{
+ int i = cursor->index();
+ if ( i > 0 )
+ --i;
+ if ( doc->useFormatCollection() &&
+ ( !currentFormat || currentFormat->key() != cursor->paragraph()->at( i )->format()->key() ) ) {
+ if ( currentFormat )
+ currentFormat->removeRef();
+ currentFormat = doc->formatCollection()->format( cursor->paragraph()->at( i )->format() );
+ if ( currentFormat->isMisspelled() ) {
+ currentFormat->removeRef();
+ currentFormat = doc->formatCollection()->format( currentFormat->font(), currentFormat->color() );
+ }
+ emit currentFontChanged( currentFormat->font() );
+ emit currentColorChanged( currentFormat->color() );
+ emit currentVerticalAlignmentChanged( (VerticalAlignment)currentFormat->vAlign() );
+ }
+
+ if ( currentAlignment != cursor->paragraph()->tqalignment() ) {
+ currentAlignment = cursor->paragraph()->tqalignment();
+ block_set_tqalignment = TRUE;
+ emit currentAlignmentChanged( currentAlignment );
+ block_set_tqalignment = FALSE;
+ }
+}
+
+/*!
+ If \a b is TRUE sets the current format to italic; otherwise sets
+ the current format to non-italic.
+
+ \sa italic()
+*/
+
+void TQTextEdit::setItalic( bool b )
+{
+ TQTextFormat f( *currentFormat );
+ f.setItalic( b );
+ TQTextFormat *f2 = doc->formatCollection()->format( &f );
+ setFormat(f2, TQTextFormat::Italic );
+}
+
+/*!
+ If \a b is TRUE sets the current format to bold; otherwise sets
+ the current format to non-bold.
+
+ \sa bold()
+*/
+
+void TQTextEdit::setBold( bool b )
+{
+ TQTextFormat f( *currentFormat );
+ f.setBold( b );
+ TQTextFormat *f2 = doc->formatCollection()->format( &f );
+ setFormat( f2, TQTextFormat::Bold );
+}
+
+/*!
+ If \a b is TRUE sets the current format to underline; otherwise
+ sets the current format to non-underline.
+
+ \sa underline()
+*/
+
+void TQTextEdit::setUnderline( bool b )
+{
+ TQTextFormat f( *currentFormat );
+ f.setUnderline( b );
+ TQTextFormat *f2 = doc->formatCollection()->format( &f );
+ setFormat( f2, TQTextFormat::Underline );
+}
+
+/*!
+ Sets the font family of the current format to \a fontFamily.
+
+ \sa family() setCurrentFont()
+*/
+
+void TQTextEdit::setFamily( const TQString &fontFamily )
+{
+ TQTextFormat f( *currentFormat );
+ f.setFamily( fontFamily );
+ TQTextFormat *f2 = doc->formatCollection()->format( &f );
+ setFormat( f2, TQTextFormat::Family );
+}
+
+/*!
+ Sets the point size of the current format to \a s.
+
+ Note that if \a s is zero or negative, the behaviour of this
+ function is not defined.
+
+ \sa pointSize() setCurrentFont() setFamily()
+*/
+
+void TQTextEdit::setPointSize( int s )
+{
+ TQTextFormat f( *currentFormat );
+ f.setPointSize( s );
+ TQTextFormat *f2 = doc->formatCollection()->format( &f );
+ setFormat( f2, TQTextFormat::Size );
+}
+
+/*!
+ Sets the color of the current format, i.e. of the text, to \a c.
+
+ \sa color() setPaper()
+*/
+
+void TQTextEdit::setColor( const TQColor &c )
+{
+ TQTextFormat f( *currentFormat );
+ f.setColor( c );
+ TQTextFormat *f2 = doc->formatCollection()->format( &f );
+ setFormat( f2, TQTextFormat::Color );
+}
+
+/*!
+ Sets the vertical tqalignment of the current format, i.e. of the
+ text, to \a a.
+
+ \sa color() setPaper()
+*/
+
+void TQTextEdit::setVerticalAlignment( VerticalAlignment a )
+{
+ TQTextFormat f( *currentFormat );
+ f.setVAlign( (TQTextFormat::VerticalAlignment)a );
+ TQTextFormat *f2 = doc->formatCollection()->format( &f );
+ setFormat( f2, TQTextFormat::VAlign );
+}
+
+void TQTextEdit::setFontInternal( const TQFont &f_ )
+{
+ TQTextFormat f( *currentFormat );
+ f.setFont( f_ );
+ TQTextFormat *f2 = doc->formatCollection()->format( &f );
+ setFormat( f2, TQTextFormat::Font );
+}
+
+
+TQString TQTextEdit::text() const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode )
+ return optimText();
+#endif
+
+ TQTextParagraph *p = doc->firstParagraph();
+ if ( !p || (!p->next() && p->length() <= 1) )
+ return TQString::tqfromLatin1("");
+
+ if ( isReadOnly() )
+ return doc->originalText();
+ return doc->text();
+}
+
+/*!
+ \overload
+
+ Returns the text of paragraph \a para.
+
+ If textFormat() is \c RichText the text will contain HTML
+ formatting tags.
+*/
+
+TQString TQTextEdit::text( int para ) const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode && (d->od->numLines >= para) ) {
+ TQString paraStr = d->od->lines[ LOGOFFSET(para) ];
+ if ( paraStr.isEmpty() )
+ paraStr = "\n";
+ return paraStr;
+ } else
+#endif
+ return doc->text( para );
+}
+
+/*!
+ \overload
+
+ Changes the text of the text edit to the string \a text and the
+ context to \a context. Any previous text is removed.
+
+ \a text may be interpreted either as plain text or as rich text,
+ depending on the textFormat(). The default setting is \c AutoText,
+ i.e. the text edit auto-detects the format from \a text.
+
+ For rich text the rendering style and available tags are defined
+ by a styleSheet(); see TQStyleSheet for details.
+
+ The optional \a context is a path which the text edit's
+ TQMimeSourceFactory uses to resolve the locations of files and
+ images. (See \l{TQTextEdit::TQTextEdit()}.) It is passed to the text
+ edit's TQMimeSourceFactory when quering data.
+
+ Note that the undo/redo history is cleared by this function.
+
+ \sa text(), setTextFormat()
+*/
+
+void TQTextEdit::setText( const TQString &text, const TQString &context )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ optimSetText( text );
+ return;
+ }
+#endif
+ resetInputContext();
+ if ( !isModified() && isReadOnly() &&
+ this->context() == context && this->text() == text )
+ return;
+
+ emit undoAvailable( FALSE );
+ emit redoAvailable( FALSE );
+ undoRedoInfo.clear();
+ doc->commands()->clear();
+
+ lastFormatted = 0;
+ int oldCursorPos = cursor->index();
+ int oldCursorPar = cursor->paragraph()->paragId();
+ cursor->restoreState();
+ delete cursor;
+ doc->setText( text, context );
+
+ if ( wrapMode == FixedPixelWidth ) {
+ resizeContents( wrapWidth, 0 );
+ doc->setWidth( wrapWidth );
+ doc->setMinimumWidth( wrapWidth );
+ } else {
+ doc->setMinimumWidth( -1 );
+ resizeContents( 0, 0 );
+ }
+
+ lastFormatted = doc->firstParagraph();
+ cursor = new TQTextCursor( doc );
+ updateContents();
+
+ if ( isModified() )
+ setModified( FALSE );
+ emit textChanged();
+ if ( cursor->index() != oldCursorPos || cursor->paragraph()->paragId() != oldCursorPar ) {
+ emit cursorPositionChanged( cursor );
+ emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
+ }
+ formatMore();
+ updateCurrentFormat();
+ d->scrollToAnchor = TQString::null;
+}
+
+/*!
+ \property TQTextEdit::text
+ \brief the text edit's text
+
+ There is no default text.
+
+ On setting, any previous text is deleted.
+
+ The text may be interpreted either as plain text or as rich text,
+ depending on the textFormat(). The default setting is \c AutoText,
+ i.e. the text edit auto-detects the format of the text.
+
+ For richtext, calling text() on an editable TQTextEdit will cause
+ the text to be regenerated from the textedit. This may mean that
+ the TQString returned may not be exactly the same as the one that
+ was set.
+
+ \sa textFormat
+*/
+
+
+/*!
+ \property TQTextEdit::readOnly
+ \brief whether the text edit is read-only
+
+ In a read-only text edit the user can only navigate through the
+ text and select text; modifying the text is not possible.
+
+ This property's default is FALSE.
+*/
+
+/*!
+ Finds the next occurrence of the string, \a expr. Returns TRUE if
+ \a expr was found; otherwise returns FALSE.
+
+ If \a para and \a index are both 0 the search begins from the
+ current cursor position. If \a para and \a index are both not 0,
+ the search begins from the \a *index character position in the
+ \a *para paragraph.
+
+ If \a cs is TRUE the search is case sensitive, otherwise it is
+ case insensitive. If \a wo is TRUE the search looks for whole word
+ matches only; otherwise it searches for any matching text. If \a
+ forward is TRUE (the default) the search works forward from the
+ starting position to the end of the text, otherwise it works
+ backwards to the beginning of the text.
+
+ If \a expr is found the function returns TRUE. If \a index and \a
+ para are not 0, the number of the paragraph in which the first
+ character of the match was found is put into \a *para, and the
+ index position of that character within the paragraph is put into
+ \a *index.
+
+ If \a expr is not found the function returns FALSE. If \a index
+ and \a para are not 0 and \a expr is not found, \a *index
+ and \a *para are undefined.
+
+ Please note that this function will make the next occurrence of
+ the string (if found) the current selection, and will thus
+ modify the cursor position.
+
+ Using the \a para and \a index parameters will not work correctly
+ in case the document tqcontains tables.
+*/
+
+bool TQTextEdit::tqfind( const TQString &expr, bool cs, bool wo, bool forward,
+ int *para, int *index )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode )
+ return optimFind( expr, cs, wo, forward, para, index );
+#endif
+ drawCursor( FALSE );
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ TQTextCursor tqfindcur = *cursor;
+ if ( para && index ) {
+ if ( doc->paragAt( *para ) )
+ tqfindcur.gotoPosition( doc->paragAt(*para), *index );
+ else
+ tqfindcur.gotoEnd();
+ } else if ( doc->hasSelection( TQTextDocument::Standard ) ){
+ // maks sure we do not tqfind the same selection again
+ if ( forward )
+ tqfindcur.gotoNextLetter();
+ else
+ tqfindcur.gotoPreviousLetter();
+ } else if (!forward && tqfindcur.index() == 0 && tqfindcur.paragraph() == tqfindcur.topParagraph()) {
+ tqfindcur.gotoEnd();
+ }
+ removeSelection( TQTextDocument::Standard );
+ bool found = doc->tqfind( tqfindcur, expr, cs, wo, forward );
+ if ( found ) {
+ if ( para )
+ *para = tqfindcur.paragraph()->paragId();
+ if ( index )
+ *index = tqfindcur.index();
+ *cursor = tqfindcur;
+ repaintChanged();
+ ensureCursorVisible();
+ }
+ drawCursor( TRUE );
+ if (found) {
+ emit cursorPositionChanged( cursor );
+ emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
+ }
+ return found;
+}
+
+void TQTextEdit::blinkCursor()
+{
+ if ( !cursorVisible )
+ return;
+ bool cv = cursorVisible;
+ blinkCursorVisible = !blinkCursorVisible;
+ drawCursor( blinkCursorVisible );
+ cursorVisible = cv;
+}
+
+/*!
+ Sets the cursor to position \a index in paragraph \a para.
+
+ \sa getCursorPosition()
+*/
+
+void TQTextEdit::setCursorPosition( int para, int index )
+{
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return;
+
+ resetInputContext();
+ if ( index > p->length() - 1 )
+ index = p->length() - 1;
+
+ drawCursor( FALSE );
+ cursor->setParagraph( p );
+ cursor->setIndex( index );
+ ensureCursorVisible();
+ drawCursor( TRUE );
+ updateCurrentFormat();
+ emit cursorPositionChanged( cursor );
+ emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
+}
+
+/*!
+ This function sets the \a *para and \a *index parameters to the
+ current cursor position. \a para and \a index must not be 0.
+
+ \sa setCursorPosition()
+*/
+
+void TQTextEdit::getCursorPosition( int *para, int *index ) const
+{
+ if ( !para || !index )
+ return;
+ *para = cursor->paragraph()->paragId();
+ *index = cursor->index();
+}
+
+/*!
+ Sets a selection which starts at position \a indexFrom in
+ paragraph \a paraFrom and ends at position \a indexTo in paragraph
+ \a paraTo.
+
+ Any existing selections which have a different id (\a selNum) are
+ left alone, but if an existing selection has the same id as \a
+ selNum it is removed and tqreplaced by this selection.
+
+ Uses the selection settings of selection \a selNum. If \a selNum
+ is 0, this is the default selection.
+
+ The cursor is moved to the end of the selection if \a selNum is 0,
+ otherwise the cursor position remains unchanged.
+
+ \sa getSelection() selectedText
+*/
+
+void TQTextEdit::setSelection( int paraFrom, int indexFrom,
+ int paraTo, int indexTo, int selNum )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if (d->optimMode) {
+ optimSetSelection(paraFrom, indexFrom, paraTo, indexTo);
+ repaintContents(FALSE);
+ return;
+ }
+#endif
+ resetInputContext();
+ if ( doc->hasSelection( selNum ) ) {
+ doc->removeSelection( selNum );
+ repaintChanged();
+ }
+ if ( selNum > doc->numSelections() - 1 )
+ doc->addSelection( selNum );
+ TQTextParagraph *p1 = doc->paragAt( paraFrom );
+ if ( !p1 )
+ return;
+ TQTextParagraph *p2 = doc->paragAt( paraTo );
+ if ( !p2 )
+ return;
+
+ if ( indexFrom > p1->length() - 1 )
+ indexFrom = p1->length() - 1;
+ if ( indexTo > p2->length() - 1 )
+ indexTo = p2->length() - 1;
+
+ drawCursor( FALSE );
+ TQTextCursor c = *cursor;
+ TQTextCursor oldCursor = *cursor;
+ c.setParagraph( p1 );
+ c.setIndex( indexFrom );
+ cursor->setParagraph( p2 );
+ cursor->setIndex( indexTo );
+ doc->setSelectionStart( selNum, c );
+ doc->setSelectionEnd( selNum, *cursor );
+ repaintChanged();
+ ensureCursorVisible();
+ if ( selNum != TQTextDocument::Standard )
+ *cursor = oldCursor;
+ drawCursor( TRUE );
+}
+
+/*!
+ If there is a selection, \a *paraFrom is set to the number of the
+ paragraph in which the selection begins and \a *paraTo is set to
+ the number of the paragraph in which the selection ends. (They
+ could be the same.) \a *indexFrom is set to the index at which the
+ selection begins within \a *paraFrom, and \a *indexTo is set to
+ the index at which the selection ends within \a *paraTo.
+
+ If there is no selection, \a *paraFrom, \a *indexFrom, \a *paraTo
+ and \a *indexTo are all set to -1.
+
+ If \a paraFrom, \a indexFrom, \a paraTo or \a indexTo is 0 this
+ function does nothing.
+
+ The \a selNum is the number of the selection (multiple selections
+ are supported). It defaults to 0 (the default selection).
+
+ \sa setSelection() selectedText
+*/
+
+void TQTextEdit::getSelection( int *paraFrom, int *indexFrom,
+ int *paraTo, int *indexTo, int selNum ) const
+{
+ if ( !paraFrom || !paraTo || !indexFrom || !indexTo )
+ return;
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if (d->optimMode) {
+ *paraFrom = d->od->selStart.line;
+ *paraTo = d->od->selEnd.line;
+ *indexFrom = d->od->selStart.index;
+ *indexTo = d->od->selEnd.index;
+ return;
+ }
+#endif
+ if ( !doc->hasSelection( selNum ) ) {
+ *paraFrom = -1;
+ *indexFrom = -1;
+ *paraTo = -1;
+ *indexTo = -1;
+ return;
+ }
+
+ doc->selectionStart( selNum, *paraFrom, *indexFrom );
+ doc->selectionEnd( selNum, *paraTo, *indexTo );
+}
+
+/*!
+ \property TQTextEdit::textFormat
+ \brief the text format: rich text, plain text, log text or auto text.
+
+ The text format is one of the following:
+ \list
+ \i PlainText - all characters, except newlines, are displayed
+ verbatim, including spaces. Whenever a newline appears in the text
+ the text edit inserts a hard line break and begins a new
+ paragraph.
+ \i RichText - rich text rendering. The available styles are
+ defined in the default stylesheet TQStyleSheet::defaultSheet().
+ \i LogText - optimized mode for very large texts. Supports a very
+ limited set of formatting tags (color, bold, underline and italic
+ settings).
+ \i AutoText - this is the default. The text edit autodetects which
+ rendering style is best, \c PlainText or \c RichText. This is done
+ by using the TQStyleSheet::mightBeRichText() function.
+ \endlist
+*/
+
+void TQTextEdit::setTextFormat( TQt::TextFormat format )
+{
+ doc->setTextFormat( format );
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ checkOptimMode();
+#endif
+}
+
+TQt::TextFormat TQTextEdit::textFormat() const
+{
+ return doc->textFormat();
+}
+
+/*!
+ Returns the number of paragraphs in the text; an empty textedit is always
+ considered to have one paragraph, so 1 is returned in this case.
+*/
+
+int TQTextEdit::paragraphs() const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ return d->od->numLines;
+ }
+#endif
+ return doc->lastParagraph()->paragId() + 1;
+}
+
+/*!
+ Returns the number of lines in paragraph \a para, or -1 if there
+ is no paragraph with index \a para.
+*/
+
+int TQTextEdit::linesOfParagraph( int para ) const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ if ( d->od->numLines >= para )
+ return 1;
+ else
+ return -1;
+ }
+#endif
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return -1;
+ return p->lines();
+}
+
+/*!
+ Returns the length of the paragraph \a para (i.e. the number of
+ characters), or -1 if there is no paragraph with index \a para.
+
+ This function ignores newlines.
+*/
+
+int TQTextEdit::paragraphLength( int para ) const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ if ( d->od->numLines >= para ) {
+ if ( d->od->lines[ LOGOFFSET(para) ].isEmpty() ) // CR
+ return 1;
+ else
+ return d->od->lines[ LOGOFFSET(para) ].length();
+ }
+ return -1;
+ }
+#endif
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return -1;
+ return p->length() - 1;
+}
+
+/*!
+ Returns the number of lines in the text edit; this could be 0.
+
+ \warning This function may be slow. Lines change all the time
+ during word wrapping, so this function has to iterate over all the
+ paragraphs and get the number of lines from each one individually.
+*/
+
+int TQTextEdit::lines() const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ return d->od->numLines;
+ }
+#endif
+ TQTextParagraph *p = doc->firstParagraph();
+ int l = 0;
+ while ( p ) {
+ l += p->lines();
+ p = p->next();
+ }
+
+ return l;
+}
+
+/*!
+ Returns the line number of the line in paragraph \a para in which
+ the character at position \a index appears. The \a index position is
+ relative to the beginning of the paragraph. If there is no such
+ paragraph or no such character at the \a index position (e.g. the
+ index is out of range) -1 is returned.
+*/
+
+int TQTextEdit::lineOfChar( int para, int index )
+{
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return -1;
+
+ int idx, line;
+ TQTextStringChar *c = p->lineStartOfChar( index, &idx, &line );
+ if ( !c )
+ return -1;
+
+ return line;
+}
+
+void TQTextEdit::setModified( bool m )
+{
+ bool oldModified = modified;
+ modified = m;
+ if ( modified && doc->oTextValid )
+ doc->invalidateOriginalText();
+ if ( oldModified != modified )
+ emit modificationChanged( modified );
+}
+
+/*!
+ \property TQTextEdit::modified
+ \brief whether the document has been modified by the user
+*/
+
+bool TQTextEdit::isModified() const
+{
+ return modified;
+}
+
+void TQTextEdit::setModified()
+{
+ if ( !isModified() )
+ setModified( TRUE );
+}
+
+/*!
+ Returns TRUE if the current format is italic; otherwise returns FALSE.
+
+ \sa setItalic()
+*/
+
+bool TQTextEdit::italic() const
+{
+ return currentFormat->font().italic();
+}
+
+/*!
+ Returns TRUE if the current format is bold; otherwise returns FALSE.
+
+ \sa setBold()
+*/
+
+bool TQTextEdit::bold() const
+{
+ return currentFormat->font().bold();
+}
+
+/*!
+ Returns TRUE if the current format is underlined; otherwise returns
+ FALSE.
+
+ \sa setUnderline()
+*/
+
+bool TQTextEdit::underline() const
+{
+ return currentFormat->font().underline();
+}
+
+/*!
+ Returns the font family of the current format.
+
+ \sa setFamily() setCurrentFont() setPointSize()
+*/
+
+TQString TQTextEdit::family() const
+{
+ return currentFormat->font().family();
+}
+
+/*!
+ Returns the point size of the font of the current format.
+
+ \sa setFamily() setCurrentFont() setPointSize()
+*/
+
+int TQTextEdit::pointSize() const
+{
+ return currentFormat->font().pointSize();
+}
+
+/*!
+ Returns the color of the current format.
+
+ \sa setColor() setPaper()
+*/
+
+TQColor TQTextEdit::color() const
+{
+ return currentFormat->color();
+}
+
+/*!
+ \obsolete
+
+ Returns TQScrollView::font()
+
+ \warning In previous versions this function returned the font of
+ the current format. This lead to confusion. Please use
+ currentFont() instead.
+*/
+
+TQFont TQTextEdit::font() const
+{
+ return TQScrollView::font();
+}
+
+/*!
+ Returns the font of the current format.
+
+ \sa setCurrentFont() setFamily() setPointSize()
+*/
+
+TQFont TQTextEdit::currentFont() const
+{
+ return currentFormat->font();
+}
+
+
+/*!
+ Returns the tqalignment of the current paragraph.
+
+ \sa tqsetAlignment()
+*/
+
+int TQTextEdit::tqalignment() const
+{
+ return currentAlignment;
+}
+
+void TQTextEdit::startDrag()
+{
+#ifndef TQT_NO_DRAGANDDROP
+ mousePressed = FALSE;
+ inDoubleClick = FALSE;
+ TQDragObject *drag = dragObject( viewport() );
+ if ( !drag )
+ return;
+ if ( isReadOnly() ) {
+ drag->dragCopy();
+ } else {
+ if ( drag->drag() && TQDragObject::target() != this && TQDragObject::target() != viewport() )
+ removeSelectedText();
+ }
+#endif
+}
+
+/*!
+ If \a select is TRUE (the default), all the text is selected as
+ selection 0. If \a select is FALSE any selected text is
+ unselected, i.e. the default selection (selection 0) is cleared.
+
+ \sa selectedText
+*/
+
+void TQTextEdit::selectAll( bool select )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ if ( select )
+ optimSelectAll();
+ else
+ optimRemoveSelection();
+ return;
+ }
+#endif
+ if ( !select )
+ doc->removeSelection( TQTextDocument::Standard );
+ else
+ doc->selectAll( TQTextDocument::Standard );
+ repaintChanged();
+ emit copyAvailable( doc->hasSelection( TQTextDocument::Standard ) );
+ emit selectionChanged();
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+}
+
+void TQTextEdit::UndoRedoInfo::clear()
+{
+ if ( valid() ) {
+ if ( type == Insert || type == Return )
+ doc->addCommand( new TQTextInsertCommand( doc, id, index, d->text.rawData(), styleInformation ) );
+ else if ( type == Format )
+ doc->addCommand( new TQTextFormatCommand( doc, id, index, eid, eindex, d->text.rawData(), format, flags ) );
+ else if ( type == Style )
+ doc->addCommand( new TQTextStyleCommand( doc, id, eid, styleInformation ) );
+ else if ( type != Invalid ) {
+ doc->addCommand( new TQTextDeleteCommand( doc, id, index, d->text.rawData(), styleInformation ) );
+ }
+ }
+ type = Invalid;
+ d->text = TQString::null;
+ id = -1;
+ index = -1;
+ styleInformation = TQByteArray();
+}
+
+
+/*!
+ If there is some selected text (in selection 0) it is deleted. If
+ there is no selected text (in selection 0) the character to the
+ right of the text cursor is deleted.
+
+ \sa removeSelectedText() cut()
+*/
+
+void TQTextEdit::del()
+{
+ if ( doc->hasSelection( TQTextDocument::Standard ) ) {
+ removeSelectedText();
+ return;
+ }
+
+ doKeyboardAction( ActionDelete );
+}
+
+
+TQTextEdit::UndoRedoInfo::UndoRedoInfo( TQTextDocument *dc )
+ : type( Invalid ), doc( dc )
+{
+ d = new TQUndoRedoInfoPrivate;
+ d->text = TQString::null;
+ id = -1;
+ index = -1;
+}
+
+TQTextEdit::UndoRedoInfo::~UndoRedoInfo()
+{
+ delete d;
+}
+
+bool TQTextEdit::UndoRedoInfo::valid() const
+{
+ return id >= 0 && type != Invalid;
+}
+
+/*!
+ \internal
+
+ Resets the current format to the default format.
+*/
+
+void TQTextEdit::resetFormat()
+{
+ tqsetAlignment( TQt::AlignAuto );
+ setParagType( TQStyleSheetItem::DisplayBlock, TQStyleSheetItem::ListDisc );
+ setFormat( doc->formatCollection()->defaultFormat(), TQTextFormat::Format );
+}
+
+/*!
+ Returns the TQStyleSheet which is being used by this text edit.
+
+ \sa setStyleSheet()
+*/
+
+TQStyleSheet* TQTextEdit::styleSheet() const
+{
+ return doc->styleSheet();
+}
+
+/*!
+ Sets the stylesheet to use with this text edit to \a styleSheet.
+ Changes will only take effect for new text added with setText() or
+ append().
+
+ \sa styleSheet()
+*/
+
+void TQTextEdit::setStyleSheet( TQStyleSheet* styleSheet )
+{
+ doc->setStyleSheet( styleSheet );
+}
+
+/*!
+ \property TQTextEdit::paper
+ \brief the background (paper) brush.
+
+ The brush that is currently used to draw the background of the
+ text edit. The initial setting is an empty brush.
+*/
+
+void TQTextEdit::setPaper( const TQBrush& pap )
+{
+ doc->setPaper( new TQBrush( pap ) );
+
+ if ( pap.pixmap() ) {
+ viewport()->setBackgroundPixmap( *pap.pixmap() );
+ } else {
+ setPaletteBackgroundColor( pap.color() );
+ viewport()->setPaletteBackgroundColor( pap.color() );
+ }
+
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ // force a tqrepaint of the entire viewport - using updateContents()
+ // would clip the coords to the content size
+ if (d->optimMode)
+ repaintContents(contentsX(), contentsY(), viewport()->width(), viewport()->height());
+ else
+#endif
+ updateContents();
+}
+
+TQBrush TQTextEdit::paper() const
+{
+ if ( doc->paper() )
+ return *doc->paper();
+ return TQBrush( tqcolorGroup().base() );
+}
+
+/*!
+ \property TQTextEdit::linkUnderline
+ \brief whether hypertext links will be underlined
+
+ If TRUE (the default) hypertext links will be displayed
+ underlined. If FALSE links will not be displayed underlined.
+*/
+
+void TQTextEdit::setLinkUnderline( bool b )
+{
+ if ( doc->underlineLinks() == b )
+ return;
+ doc->setUnderlineLinks( b );
+ repaintChanged();
+}
+
+bool TQTextEdit::linkUnderline() const
+{
+ return doc->underlineLinks();
+}
+
+/*!
+ Sets the text edit's mimesource factory to \a factory. See
+ TQMimeSourceFactory for further details.
+
+ \sa mimeSourceFactory()
+ */
+
+#ifndef TQT_NO_MIME
+void TQTextEdit::setMimeSourceFactory( TQMimeSourceFactory* factory )
+{
+ doc->setMimeSourceFactory( factory );
+}
+
+/*!
+ Returns the TQMimeSourceFactory which is being used by this text
+ edit.
+
+ \sa setMimeSourceFactory()
+*/
+
+TQMimeSourceFactory* TQTextEdit::mimeSourceFactory() const
+{
+ return doc->mimeSourceFactory();
+}
+#endif
+
+/*!
+ Returns how many pixels high the text edit needs to be to display
+ all the text if the text edit is \a w pixels wide.
+*/
+
+int TQTextEdit::heightForWidth( int w ) const
+{
+ int oldw = doc->width();
+ doc->doLayout( 0, w );
+ int h = doc->height();
+ doc->setWidth( oldw );
+ doc->tqinvalidate();
+ ( (TQTextEdit*)this )->formatMore();
+ return h;
+}
+
+/*!
+ Appends a new paragraph with \a text to the end of the text edit. Note that
+ the undo/redo history is cleared by this function, and no undo
+ history is kept for appends which makes them faster than
+ insert()s. If you want to append text which is added to the
+ undo/redo history as well, use insertParagraph().
+*/
+
+void TQTextEdit::append( const TQString &text )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ optimAppend( text );
+ return;
+ }
+#endif
+ // flush and clear the undo/redo stack if necessary
+ undoRedoInfo.clear();
+ doc->commands()->clear();
+
+ doc->removeSelection( TQTextDocument::Standard );
+ TQt::TextFormat f = doc->textFormat();
+ if ( f == TQt::AutoText ) {
+ if ( TQStyleSheet::mightBeRichText( text ) )
+ f = TQt::RichText;
+ else
+ f = TQt::PlainText;
+ }
+
+ drawCursor( FALSE );
+ TQTextCursor oldc( *cursor );
+ ensureFormatted( doc->lastParagraph() );
+ bool atBottom = contentsY() >= contentsHeight() - visibleHeight();
+ cursor->gotoEnd();
+ if ( cursor->index() > 0 )
+ cursor->splitAndInsertEmptyParagraph();
+ TQTextCursor oldCursor2 = *cursor;
+
+ if ( f == TQt::PlainText ) {
+ cursor->insert( text, TRUE );
+ if ( doc->useFormatCollection() && !doc->preProcessor() &&
+ currentFormat != cursor->paragraph()->at( cursor->index() )->format() ) {
+ doc->setSelectionStart( TQTextDocument::Temp, oldCursor2 );
+ doc->setSelectionEnd( TQTextDocument::Temp, *cursor );
+ doc->setFormat( TQTextDocument::Temp, currentFormat, TQTextFormat::Format );
+ doc->removeSelection( TQTextDocument::Temp );
+ }
+ } else {
+ cursor->paragraph()->setListItem( FALSE );
+ cursor->paragraph()->setListDepth( 0 );
+ if ( cursor->paragraph()->prev() )
+ cursor->paragraph()->prev()->tqinvalidate(0); // vertical margins might have to change
+ doc->setRichTextInternal( text );
+ }
+ formatMore();
+ repaintChanged();
+ if ( atBottom )
+ scrollToBottom();
+ *cursor = oldc;
+ if ( !isReadOnly() )
+ cursorVisible = TRUE;
+ setModified();
+ emit textChanged();
+}
+
+/*!
+ \property TQTextEdit::hasSelectedText
+ \brief whether some text is selected in selection 0
+*/
+
+bool TQTextEdit::hasSelectedText() const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode )
+ return optimHasSelection();
+ else
+#endif
+ return doc->hasSelection( TQTextDocument::Standard );
+}
+
+/*!
+ \property TQTextEdit::selectedText
+ \brief The selected text (from selection 0) or an empty string if
+ there is no currently selected text (in selection 0).
+
+ The text is always returned as \c PlainText if the textFormat() is
+ \c PlainText or \c AutoText, otherwise it is returned as HTML.
+
+ \sa hasSelectedText
+*/
+
+TQString TQTextEdit::selectedText() const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode )
+ return optimSelectedText();
+ else
+#endif
+ return doc->selectedText( TQTextDocument::Standard, textFormat() == TQt::RichText );
+}
+
+bool TQTextEdit::handleReadOnlyKeyEvent( TQKeyEvent *e )
+{
+ switch( e->key() ) {
+ case Qt::Key_Down:
+ setContentsPos( contentsX(), contentsY() + 10 );
+ break;
+ case Qt::Key_Up:
+ setContentsPos( contentsX(), contentsY() - 10 );
+ break;
+ case Qt::Key_Left:
+ setContentsPos( contentsX() - 10, contentsY() );
+ break;
+ case Qt::Key_Right:
+ setContentsPos( contentsX() + 10, contentsY() );
+ break;
+ case Qt::Key_PageUp:
+ setContentsPos( contentsX(), contentsY() - visibleHeight() );
+ break;
+ case Qt::Key_PageDown:
+ setContentsPos( contentsX(), contentsY() + visibleHeight() );
+ break;
+ case Qt::Key_Home:
+ setContentsPos( contentsX(), 0 );
+ break;
+ case Qt::Key_End:
+ setContentsPos( contentsX(), contentsHeight() - visibleHeight() );
+ break;
+ case Qt::Key_F16: // Copy key on Sun keyboards
+ copy();
+ break;
+#ifndef TQT_NO_NETWORKPROTOCOL
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ case Qt::Key_Space: {
+ if (!doc->focusIndicator.href.isEmpty()
+ || !doc->focusIndicator.name.isEmpty()) {
+ if (!doc->focusIndicator.href.isEmpty()) {
+ TQUrl u( doc->context(), doc->focusIndicator.href, TRUE );
+ emitLinkClicked( u.toString( FALSE, FALSE ) );
+ }
+ if (!doc->focusIndicator.name.isEmpty()) {
+ if (::tqqt_cast<TQTextBrowser*>(this)) { // change for 4.0
+ TQConnectionList *clist = tqreceivers(
+ "anchorClicked(const TQString&,const TQString&)");
+ if (!tqsignalsBlocked() && clist) {
+ TQUObject o[3];
+ static_TQUType_TQString.set(o+1,
+ doc->focusIndicator.name);
+ static_TQUType_TQString.set(o+2,
+ doc->focusIndicator.href);
+ activate_signal( clist, o);
+ }
+ }
+ }
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ }
+ } break;
+#endif
+ default:
+ if ( e->state() & ControlButton ) {
+ switch ( e->key() ) {
+ case Qt::Key_C: case Qt::Key_F16: // Copy key on Sun keyboards
+ copy();
+ break;
+#ifdef TQ_WS_WIN
+ case Qt::Key_Insert:
+ copy();
+ break;
+ case Qt::Key_A:
+ selectAll();
+ break;
+#endif
+ }
+
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*!
+ Returns the context of the text edit. The context is a path which
+ the text edit's TQMimeSourceFactory uses to resolve the locations
+ of files and images.
+
+ \sa text
+*/
+
+TQString TQTextEdit::context() const
+{
+ return doc->context();
+}
+
+/*!
+ \property TQTextEdit::documentTitle
+ \brief the title of the document parsed from the text.
+
+ For \c PlainText the title will be an empty string. For \c
+ RichText the title will be the text between the \c{<title>} tags,
+ if present, otherwise an empty string.
+*/
+
+TQString TQTextEdit::documentTitle() const
+{
+ return doc->attributes()[ "title" ];
+}
+
+void TQTextEdit::makeParagVisible( TQTextParagraph *p )
+{
+ setContentsPos( contentsX(), TQMIN( p->rect().y(), contentsHeight() - visibleHeight() ) );
+}
+
+/*!
+ Scrolls the text edit to make the text at the anchor called \a
+ name visible, if it can be found in the document. If the anchor
+ isn't found no scrolling will occur. An anchor is defined using
+ the HTML anchor tag, e.g. \c{<a name="target">}.
+*/
+
+void TQTextEdit::scrollToAnchor( const TQString& name )
+{
+ if ( !isVisible() ) {
+ d->scrollToAnchor = name;
+ return;
+ }
+ if ( name.isEmpty() )
+ return;
+ sync();
+ TQTextCursor cursor( doc );
+ TQTextParagraph* last = doc->lastParagraph();
+ for (;;) {
+ TQTextStringChar* c = cursor.paragraph()->at( cursor.index() );
+ if( c->isAnchor() ) {
+ TQString a = c->anchorName();
+ if ( a == name ||
+ (a.tqcontains( '#' ) && TQStringList::split( '#', a ).tqcontains( name ) ) ) {
+ setContentsPos( contentsX(), TQMIN( cursor.paragraph()->rect().top() + cursor.totalOffsetY(), contentsHeight() - visibleHeight() ) );
+ break;
+ }
+ }
+ if ( cursor.paragraph() == last && cursor.atParagEnd() )
+ break;
+ cursor.gotoNextLetter();
+ }
+}
+
+#if (TQT_VERSION-0 >= 0x040000)
+#error "function anchorAt(const TQPoint& pos) should be merged into function anchorAt(const TQPoint& pos, AnchorAttribute attr)"
+#endif
+
+/*!
+ \overload
+
+ If there is an anchor at position \a pos (in contents
+ coordinates), its \c href is returned, otherwise TQString::null is
+ returned.
+*/
+
+TQString TQTextEdit::anchorAt( const TQPoint& pos )
+{
+ return anchorAt(pos, Qt::AnchorHref);
+}
+
+/*!
+ If there is an anchor at position \a pos (in contents
+ coordinates), the text for attribute \a attr is returned,
+ otherwise TQString::null is returned.
+*/
+
+TQString TQTextEdit::anchorAt( const TQPoint& pos, Qt::AnchorAttribute attr )
+{
+ TQTextCursor c( doc );
+ placeCursor( pos, &c );
+ switch(attr) {
+ case Qt::AnchorName:
+ return c.paragraph()->at( c.index() )->anchorName();
+ case Qt::AnchorHref:
+ return c.paragraph()->at( c.index() )->anchorHref();
+ }
+ // incase the compiler is really dumb about determining if a function
+ // returns something :)
+ return TQString::null;
+}
+
+void TQTextEdit::documentWidthChanged( int w )
+{
+ resizeContents( TQMAX( visibleWidth(), w), contentsHeight() );
+}
+
+/*! \internal
+
+ This function does nothing
+*/
+
+void TQTextEdit::updateStyles()
+{
+}
+
+void TQTextEdit::setDocument( TQTextDocument *dc )
+{
+ if ( dc == 0 ) {
+ qWarning( "Q3TextEdit::setDocument() called with null Q3TextDocument pointer" );
+ return;
+ }
+ if ( dc == doc )
+ return;
+ resetInputContext();
+ doc = dc;
+ delete cursor;
+ cursor = new TQTextCursor( doc );
+ clearUndoRedo();
+ undoRedoInfo.doc = doc;
+ lastFormatted = 0;
+}
+
+#ifndef TQT_NO_CLIPBOARD
+
+/*!
+ Pastes the text with format \a subtype from the clipboard into the
+ text edit at the current cursor position. The \a subtype can be
+ "plain" or "html".
+
+ If there is no text with format \a subtype in the clipboard
+ nothing happens.
+
+ \sa paste() cut() TQTextEdit::copy()
+*/
+
+void TQTextEdit::pasteSubType( const TQCString &subtype )
+{
+#ifndef TQT_NO_MIMECLIPBOARD
+ TQMimeSource *m = TQApplication::tqclipboard()->data( d->clipboard_mode );
+ pasteSubType( subtype, m );
+#endif
+}
+
+/*! \internal */
+
+void TQTextEdit::pasteSubType( const TQCString& subtype, TQMimeSource *m )
+{
+#ifndef TQT_NO_MIME
+ TQCString st = subtype;
+ if ( subtype != "x-qrichtext" )
+ st.prepend( "text/" );
+ else
+ st.prepend( "application/" );
+ if ( !m )
+ return;
+ if ( doc->hasSelection( TQTextDocument::Standard ) )
+ removeSelectedText();
+ if ( !TQRichTextDrag::canDecode( m ) )
+ return;
+ TQString t;
+ if ( !TQRichTextDrag::decode( m, t, st.data(), subtype ) )
+ return;
+ if ( st == "application/x-qrichtext" ) {
+ int start;
+ if ( (start = t.tqfind( "<!--StartFragment-->" )) != -1 ) {
+ start += 20;
+ int end = t.tqfind( "<!--EndFragment-->" );
+ TQTextCursor oldC = *cursor;
+
+ // during the setRichTextInternal() call the cursors
+ // paragraph might get joined with the provious one, so
+ // the cursors one would get deleted and oldC.paragraph()
+ // would be a dnagling pointer. To avoid that try to go
+ // one letter back and later go one forward again.
+ oldC.gotoPreviousLetter();
+ bool couldGoBack = oldC != *cursor;
+ // first para might get deleted, so remember to reset it
+ bool wasAtFirst = oldC.paragraph() == doc->firstParagraph();
+
+ if ( start < end )
+ t = t.mid( start, end - start );
+ else
+ t = t.mid( start );
+ lastFormatted = cursor->paragraph();
+ if ( lastFormatted->prev() )
+ lastFormatted = lastFormatted->prev();
+ doc->setRichTextInternal( t, cursor );
+
+ // the first para might have been deleted in
+ // setRichTextInternal(). To be sure, reset it if
+ // necessary.
+ if ( wasAtFirst ) {
+ int index = oldC.index();
+ oldC.setParagraph( doc->firstParagraph() );
+ oldC.setIndex( index );
+ }
+
+ // if we went back one letter before (see last comment),
+ // go one forward to point to the right position
+ if ( couldGoBack )
+ oldC.gotoNextLetter();
+
+ if ( undoEnabled && !isReadOnly() ) {
+ doc->setSelectionStart( TQTextDocument::Temp, oldC );
+ doc->setSelectionEnd( TQTextDocument::Temp, *cursor );
+
+ checkUndoRedoInfo( UndoRedoInfo::Insert );
+ if ( !undoRedoInfo.valid() ) {
+ undoRedoInfo.id = oldC.paragraph()->paragId();
+ undoRedoInfo.index = oldC.index();
+ undoRedoInfo.d->text = TQString::null;
+ }
+ int oldLen = undoRedoInfo.d->text.length();
+ if ( !doc->preProcessor() ) {
+ TQString txt = doc->selectedText( TQTextDocument::Temp );
+ undoRedoInfo.d->text += txt;
+ for ( int i = 0; i < (int)txt.length(); ++i ) {
+ if ( txt[ i ] != '\n' && oldC.paragraph()->at( oldC.index() )->format() ) {
+ oldC.paragraph()->at( oldC.index() )->format()->addRef();
+ undoRedoInfo.d->text.
+ setFormat( oldLen + i, oldC.paragraph()->at( oldC.index() )->format(), TRUE );
+ }
+ oldC.gotoNextLetter();
+ }
+ }
+ undoRedoInfo.clear();
+ removeSelection( TQTextDocument::Temp );
+ }
+
+ formatMore();
+ setModified();
+ emit textChanged();
+ repaintChanged();
+ ensureCursorVisible();
+ return;
+ }
+ } else {
+#if defined(TQ_OS_WIN32)
+ // Need to convert CRLF to LF
+ t.tqreplace( "\r\n", "\n" );
+#elif defined(TQ_OS_MAC)
+ //need to convert CR to LF
+ t.tqreplace( '\r', '\n' );
+#endif
+ TQChar *uc = (TQChar *)t.tqunicode();
+ for ( int i=0; (uint) i<t.length(); i++ ) {
+ if ( uc[ i ] < TQChar(' ') && uc[ i ] != '\n' && uc[ i ] != '\t' )
+ uc[ i ] = ' ';
+ }
+ if ( !t.isEmpty() )
+ insert( t, FALSE, TRUE );
+ }
+#endif //TQT_NO_MIME
+}
+
+#ifndef TQT_NO_MIMECLIPBOARD
+/*!
+ Prompts the user to choose a type from a list of text types
+ available, then copies text from the clipboard (if there is any)
+ into the text edit at the current text cursor position. Any
+ selected text (in selection 0) is first deleted.
+*/
+void TQTextEdit::pasteSpecial( const TQPoint& pt )
+{
+ TQCString st = pickSpecial( TQApplication::tqclipboard()->data( d->clipboard_mode ),
+ TRUE, pt );
+ if ( !st.isEmpty() )
+ pasteSubType( st );
+}
+#endif
+#ifndef TQT_NO_MIME
+TQCString TQTextEdit::pickSpecial( TQMimeSource* ms, bool always_ask, const TQPoint& pt )
+{
+ if ( ms ) {
+#ifndef TQT_NO_POPUPMENU
+ TQPopupMenu popup( this, "qt_pickspecial_menu" );
+ TQString fmt;
+ int n = 0;
+ TQDict<void> done;
+ for (int i = 0; !( fmt = ms->format( i ) ).isNull(); i++) {
+ int semi = fmt.tqfind( ";" );
+ if ( semi >= 0 )
+ fmt = fmt.left( semi );
+ if ( fmt.left( 5 ) == "text/" ) {
+ fmt = fmt.mid( 5 );
+ if ( !done.tqfind( fmt ) ) {
+ done.insert( fmt,(void*)1 );
+ popup.insertItem( fmt, i );
+ n++;
+ }
+ }
+ }
+ if ( n ) {
+ int i = n ==1 && !always_ask ? popup.idAt( 0 ) : popup.exec( pt );
+ if ( i >= 0 )
+ return popup.text(i).latin1();
+ }
+#else
+ TQString fmt;
+ for (int i = 0; !( fmt = ms->format( i ) ).isNull(); i++) {
+ int semi = fmt.tqfind( ";" );
+ if ( semi >= 0 )
+ fmt = fmt.left( semi );
+ if ( fmt.left( 5 ) == "text/" ) {
+ fmt = fmt.mid( 5 );
+ return fmt.latin1();
+ }
+ }
+#endif
+ }
+ return TQCString();
+}
+#endif // TQT_NO_MIME
+#endif // TQT_NO_CLIPBOARD
+
+/*!
+ \enum TQTextEdit::WordWrap
+
+ This enum defines the TQTextEdit's word wrap modes.
+
+ \value NoWrap Do not wrap the text.
+
+ \value WidgetWidth Wrap the text at the current width of the
+ widget (this is the default). Wrapping is at whitespace by
+ default; this can be changed with setWrapPolicy().
+
+ \value FixedPixelWidth Wrap the text at a fixed number of pixels
+ from the widget's left side. The number of pixels is set with
+ wrapColumnOrWidth().
+
+ \value FixedColumnWidth Wrap the text at a fixed number of
+ character columns from the widget's left side. The number of
+ characters is set with wrapColumnOrWidth(). This is useful if you
+ need formatted text that can also be displayed gracefully on
+ tqdevices with monospaced fonts, for example a standard VT100
+ terminal, where you might set wrapColumnOrWidth() to 80.
+
+ \sa setWordWrap() wordWrap()
+*/
+
+/*!
+ \property TQTextEdit::wordWrap
+ \brief the word wrap mode
+
+ The default mode is \c WidgetWidth which causes words to be
+ wrapped at the right edge of the text edit. Wrapping occurs at
+ whitespace, keeping whole words intact. If you want wrapping to
+ occur within words use setWrapPolicy(). If you set a wrap mode of
+ \c FixedPixelWidth or \c FixedColumnWidth you should also call
+ setWrapColumnOrWidth() with the width you want.
+
+ \sa WordWrap, wrapColumnOrWidth, wrapPolicy,
+*/
+
+void TQTextEdit::setWordWrap( WordWrap mode )
+{
+ if ( wrapMode == mode )
+ return;
+ wrapMode = mode;
+ switch ( mode ) {
+ case NoWrap:
+ document()->formatter()->setWrapEnabled( FALSE );
+ document()->formatter()->setWrapAtColumn( -1 );
+ doc->setWidth( visibleWidth() );
+ doc->setMinimumWidth( -1 );
+ doc->tqinvalidate();
+ updateContents();
+ lastFormatted = doc->firstParagraph();
+ interval = 0;
+ formatMore();
+ break;
+ case WidgetWidth:
+ document()->formatter()->setWrapEnabled( TRUE );
+ document()->formatter()->setWrapAtColumn( -1 );
+ doResize();
+ break;
+ case FixedPixelWidth:
+ document()->formatter()->setWrapEnabled( TRUE );
+ document()->formatter()->setWrapAtColumn( -1 );
+ if ( wrapWidth < 0 )
+ wrapWidth = 200;
+ setWrapColumnOrWidth( wrapWidth );
+ break;
+ case FixedColumnWidth:
+ if ( wrapWidth < 0 )
+ wrapWidth = 80;
+ document()->formatter()->setWrapEnabled( TRUE );
+ document()->formatter()->setWrapAtColumn( wrapWidth );
+ setWrapColumnOrWidth( wrapWidth );
+ break;
+ }
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ checkOptimMode();
+#endif
+}
+
+TQTextEdit::WordWrap TQTextEdit::wordWrap() const
+{
+ return wrapMode;
+}
+
+/*!
+ \property TQTextEdit::wrapColumnOrWidth
+ \brief the position (in pixels or columns depending on the wrap mode) where text will be wrapped
+
+ If the wrap mode is \c FixedPixelWidth, the value is the number of
+ pixels from the left edge of the text edit at which text should be
+ wrapped. If the wrap mode is \c FixedColumnWidth, the value is the
+ column number (in character columns) from the left edge of the
+ text edit at which text should be wrapped.
+
+ \sa wordWrap
+*/
+void TQTextEdit::setWrapColumnOrWidth( int value )
+{
+ wrapWidth = value;
+ if ( wrapMode == FixedColumnWidth ) {
+ document()->formatter()->setWrapAtColumn( wrapWidth );
+ resizeContents( 0, 0 );
+ doc->setWidth( visibleWidth() );
+ doc->setMinimumWidth( -1 );
+ } else if (wrapMode == FixedPixelWidth ) {
+ document()->formatter()->setWrapAtColumn( -1 );
+ resizeContents( wrapWidth, 0 );
+ doc->setWidth( wrapWidth );
+ doc->setMinimumWidth( wrapWidth );
+ } else {
+ return;
+ }
+ doc->tqinvalidate();
+ updateContents();
+ lastFormatted = doc->firstParagraph();
+ interval = 0;
+ formatMore();
+}
+
+int TQTextEdit::wrapColumnOrWidth() const
+{
+ if ( wrapMode == WidgetWidth )
+ return visibleWidth();
+ return wrapWidth;
+}
+
+
+/*!
+ \enum TQTextEdit::WrapPolicy
+
+ This enum defines where text can be wrapped in word wrap mode.
+
+ \value AtWhiteSpace Don't use this deprecated value (it is a
+ synonym for \c AtWordBoundary which you should use instead).
+ \value Anywhere Break anywhere, including within words.
+ \value AtWordBoundary Break lines at word boundaries, e.g. spaces or
+ newlines
+ \value AtWordOrDocumentBoundary Break lines at whitespace, e.g.
+ spaces or newlines if possible. Break it anywhere otherwise.
+
+ \sa setWrapPolicy()
+*/
+
+/*!
+ \property TQTextEdit::wrapPolicy
+ \brief the word wrap policy, at whitespace or anywhere
+
+ Defines where text can be wrapped when word wrap mode is not \c
+ NoWrap. The choices are \c AtWordBoundary (the default), \c
+ Anywhere and \c AtWordOrDocumentBoundary
+
+ \sa wordWrap
+*/
+
+void TQTextEdit::setWrapPolicy( WrapPolicy policy )
+{
+ if ( wPolicy == policy )
+ return;
+ wPolicy = policy;
+ TQTextFormatter *formatter;
+ if ( policy == AtWordBoundary || policy == AtWordOrDocumentBoundary ) {
+ formatter = new TQTextFormatterBreakWords;
+ formatter->setAllowBreakInWords( policy == AtWordOrDocumentBoundary );
+ } else {
+ formatter = new TQTextFormatterBreakInWords;
+ }
+ formatter->setWrapAtColumn( document()->formatter()->wrapAtColumn() );
+ formatter->setWrapEnabled( document()->formatter()->isWrapEnabled( 0 ) );
+ document()->setFormatter( formatter );
+ doc->tqinvalidate();
+ updateContents();
+ lastFormatted = doc->firstParagraph();
+ interval = 0;
+ formatMore();
+}
+
+TQTextEdit::WrapPolicy TQTextEdit::wrapPolicy() const
+{
+ return wPolicy;
+}
+
+/*!
+ Deletes all the text in the text edit.
+
+ \sa cut() removeSelectedText() setText()
+*/
+
+void TQTextEdit::clear()
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ optimSetText("");
+ } else
+#endif
+ {
+ // make clear undoable
+ doc->selectAll( TQTextDocument::Temp );
+ removeSelectedText( TQTextDocument::Temp );
+ setContentsPos( 0, 0 );
+ if ( cursor->isValid() )
+ cursor->restoreState();
+ doc->clear( TRUE );
+ delete cursor;
+ cursor = new TQTextCursor( doc );
+ lastFormatted = 0;
+ }
+ updateContents();
+
+ emit cursorPositionChanged( cursor );
+ emit cursorPositionChanged( cursor->paragraph()->paragId(), cursor->index() );
+}
+
+int TQTextEdit::undoDepth() const
+{
+ return document()->undoDepth();
+}
+
+/*!
+ \property TQTextEdit::length
+ \brief the number of characters in the text
+*/
+
+int TQTextEdit::length() const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode )
+ return d->od->len;
+ else
+#endif
+ return document()->length();
+}
+
+/*!
+ \property TQTextEdit::tabStopWidth
+ \brief the tab stop width in pixels
+*/
+
+int TQTextEdit::tabStopWidth() const
+{
+ return document()->tabStopWidth();
+}
+
+void TQTextEdit::setUndoDepth( int d )
+{
+ document()->setUndoDepth( d );
+}
+
+void TQTextEdit::setTabStopWidth( int ts )
+{
+ document()->setTabStops( ts );
+ doc->tqinvalidate();
+ lastFormatted = doc->firstParagraph();
+ interval = 0;
+ formatMore();
+ updateContents();
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQTextEdit::tqsizeHint() const
+{
+ // cf. TQScrollView::tqsizeHint()
+ constPolish();
+ int f = 2 * frameWidth();
+ int h = fontMetrics().height();
+ TQSize sz( f, f );
+ return sz.expandedTo( TQSize(12 * h, 8 * h) );
+}
+
+void TQTextEdit::clearUndoRedo()
+{
+ if ( !undoEnabled )
+ return;
+ undoRedoInfo.clear();
+ emit undoAvailable( doc->commands()->isUndoAvailable() );
+ emit redoAvailable( doc->commands()->isRedoAvailable() );
+}
+
+/*! \internal
+ \warning In TQt 3.1 we will provide a cleaer API for the
+ functionality which is provided by this function and in TQt 4.0 this
+ function will go away.
+
+ This function gets the format of the character at position \a
+ index in paragraph \a para. Sets \a font to the character's font, \a
+ color to the character's color and \a verticalAlignment to the
+ character's vertical tqalignment.
+
+ Returns FALSE if \a para or \a index is out of range otherwise
+ returns TRUE.
+*/
+
+bool TQTextEdit::getFormat( int para, int index, TQFont *font, TQColor *color, VerticalAlignment *verticalAlignment )
+{
+ if ( !font || !color )
+ return FALSE;
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return FALSE;
+ if ( index < 0 || index >= p->length() )
+ return FALSE;
+ *font = p->at( index )->format()->font();
+ *color = p->at( index )->format()->color();
+ *verticalAlignment = (VerticalAlignment)p->at( index )->format()->vAlign();
+ return TRUE;
+}
+
+/*! \internal
+ \warning In TQt 3.1 we will provide a cleaer API for the
+ functionality which is provided by this function and in TQt 4.0 this
+ function will go away.
+
+ This function gets the format of the paragraph \a para. Sets \a
+ font to the paragraphs's font, \a color to the paragraph's color, \a
+ verticalAlignment to the paragraph's vertical tqalignment, \a
+ tqalignment to the paragraph's tqalignment, \a displayMode to the
+ paragraph's display mode, \a listStyle to the paragraph's list style
+ (if the display mode is TQStyleSheetItem::DisplayListItem) and \a
+ listDepth to the depth of the list (if the display mode is
+ TQStyleSheetItem::DisplayListItem).
+
+ Returns FALSE if \a para is out of range otherwise returns TRUE.
+*/
+
+bool TQTextEdit::getParagraphFormat( int para, TQFont *font, TQColor *color,
+ VerticalAlignment *verticalAlignment, int *tqalignment,
+ TQStyleSheetItem::DisplayMode *displayMode,
+ TQStyleSheetItem::ListStyle *listStyle,
+ int *listDepth )
+{
+ if ( !font || !color || !tqalignment || !displayMode || !listStyle )
+ return FALSE;
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return FALSE;
+ *font = p->at(0)->format()->font();
+ *color = p->at(0)->format()->color();
+ *verticalAlignment = (VerticalAlignment)p->at(0)->format()->vAlign();
+ *tqalignment = p->tqalignment();
+ *displayMode = p->isListItem() ? TQStyleSheetItem::DisplayListItem : TQStyleSheetItem::DisplayBlock;
+ *listStyle = p->listStyle();
+ *listDepth = p->listDepth();
+ return TRUE;
+}
+
+
+
+/*!
+ This function is called to create a right mouse button popup menu
+ at the document position \a pos. If you want to create a custom
+ popup menu, reimplement this function and return the created popup
+ menu. Ownership of the popup menu is transferred to the caller.
+
+ \warning The TQPopupMenu ID values 0-7 are reserved, and they map to the
+ standard operations. When inserting items into your custom popup menu, be
+ sure to specify ID values larger than 7.
+*/
+
+TQPopupMenu *TQTextEdit::createPopupMenu( const TQPoint& pos )
+{
+ TQ_UNUSED( pos )
+#ifndef TQT_NO_POPUPMENU
+ TQPopupMenu *popup = new TQPopupMenu( this, "qt_edit_menu" );
+ if ( !isReadOnly() ) {
+ d->id[ IdUndo ] = popup->insertItem( tr( "&Undo" ) + ACCEL_KEY( Z ) );
+ d->id[ IdRedo ] = popup->insertItem( tr( "&Redo" ) + ACCEL_KEY( Y ) );
+ popup->insertSeparator();
+ }
+#ifndef TQT_NO_CLIPBOARD
+ if ( !isReadOnly() )
+ d->id[ IdCut ] = popup->insertItem( tr( "Cu&t" ) + ACCEL_KEY( X ) );
+ d->id[ IdCopy ] = popup->insertItem( tr( "&Copy" ) + ACCEL_KEY( C ) );
+ if ( !isReadOnly() )
+ d->id[ IdPaste ] = popup->insertItem( tr( "&Paste" ) + ACCEL_KEY( V ) );
+#endif
+ if ( !isReadOnly() ) {
+ d->id[ IdClear ] = popup->insertItem( tr( "Clear" ) );
+ popup->insertSeparator();
+ }
+#if defined(TQ_WS_X11)
+ d->id[ IdSelectAll ] = popup->insertItem( tr( "Select All" ) );
+#else
+ d->id[ IdSelectAll ] = popup->insertItem( tr( "Select All" ) + ACCEL_KEY( A ) );
+#endif
+ popup->setItemEnabled( d->id[ IdUndo ], !isReadOnly() && doc->commands()->isUndoAvailable() );
+ popup->setItemEnabled( d->id[ IdRedo ], !isReadOnly() && doc->commands()->isRedoAvailable() );
+#ifndef TQT_NO_CLIPBOARD
+ popup->setItemEnabled( d->id[ IdCut ], !isReadOnly() && doc->hasSelection( TQTextDocument::Standard, TRUE ) );
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ popup->setItemEnabled( d->id[ IdCopy ], d->optimMode ? optimHasSelection() : doc->hasSelection( TQTextDocument::Standard, TRUE ) );
+#else
+ popup->setItemEnabled( d->id[ IdCopy ], doc->hasSelection( TQTextDocument::Standard, TRUE ) );
+#endif
+ popup->setItemEnabled( d->id[ IdPaste ], !isReadOnly() && !TQApplication::tqclipboard()->text( d->clipboard_mode ).isEmpty() );
+#endif
+ const bool isEmptyDocument = (length() == 0);
+ popup->setItemEnabled( d->id[ IdClear ], !isReadOnly() && !isEmptyDocument );
+ popup->setItemEnabled( d->id[ IdSelectAll ], !isEmptyDocument );
+ return popup;
+#else
+ return 0;
+#endif
+}
+
+/*! \overload
+ \obsolete
+ This function is called to create a right mouse button popup menu.
+ If you want to create a custom popup menu, reimplement this function
+ and return the created popup menu. Ownership of the popup menu is
+ transferred to the caller.
+
+ This function is only called if createPopupMenu( const TQPoint & )
+ returns 0.
+*/
+
+TQPopupMenu *TQTextEdit::createPopupMenu()
+{
+ return 0;
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::setFont( const TQFont &f )
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ TQScrollView::setFont( f );
+ doc->setDefaultFormat( f, doc->formatCollection()->defaultFormat()->color() );
+ // recalculate the max string width
+ TQFontMetrics fm(f);
+ int i, sw;
+ d->od->maxLineWidth = 0;
+ for ( i = 0; i < d->od->numLines; i++ ) {
+ sw = fm.width(d->od->lines[LOGOFFSET(i)]);
+ if (d->od->maxLineWidth < sw)
+ d->od->maxLineWidth = sw;
+ }
+ resizeContents(d->od->maxLineWidth + 4, d->od->numLines * fm.lineSpacing() + 1);
+ return;
+ }
+#endif
+ TQScrollView::setFont( f );
+ doc->setMinimumWidth( -1 );
+ doc->setDefaultFormat( f, doc->formatCollection()->defaultFormat()->color() );
+ lastFormatted = doc->firstParagraph();
+ formatMore();
+ repaintChanged();
+}
+
+/*!
+ \fn TQTextEdit::zoomIn()
+
+ \overload
+
+ Zooms in on the text by making the base font size one point
+ larger and recalculating all font sizes to be the new size. This
+ does not change the size of any images.
+
+ \sa zoomOut()
+*/
+
+/*!
+ \fn TQTextEdit::zoomOut()
+
+ \overload
+
+ Zooms out on the text by making the base font size one point
+ smaller and recalculating all font sizes to be the new size. This
+ does not change the size of any images.
+
+ \sa zoomIn()
+*/
+
+
+/*!
+ Zooms in on the text by making the base font size \a range
+ points larger and recalculating all font sizes to be the new size.
+ This does not change the size of any images.
+
+ \sa zoomOut()
+*/
+
+void TQTextEdit::zoomIn( int range )
+{
+ TQFont f( TQScrollView::font() );
+ f.setPointSize( TQFontInfo(f).pointSize() + range );
+ setFont( f );
+}
+
+/*!
+ Zooms out on the text by making the base font size \a range points
+ smaller and recalculating all font sizes to be the new size. This
+ does not change the size of any images.
+
+ \sa zoomIn()
+*/
+
+void TQTextEdit::zoomOut( int range )
+{
+ TQFont f( TQScrollView::font() );
+ f.setPointSize( TQMAX( 1, TQFontInfo(f).pointSize() - range ) );
+ setFont( f );
+}
+
+/*!
+ Zooms the text by making the base font size \a size points and
+ recalculating all font sizes to be the new size. This does not
+ change the size of any images.
+*/
+
+void TQTextEdit::zoomTo( int size )
+{
+ TQFont f( TQScrollView::font() );
+ f.setPointSize( size );
+ setFont( f );
+}
+
+/*!
+ TQTextEdit is optimized for large amounts text. One of its
+ optimizations is to format only the visible text, formatting the rest
+ on demand, e.g. as the user scrolls, so you don't usually need to
+ call this function.
+
+ In some situations you may want to force the whole text
+ to be formatted. For example, if after calling setText(), you wanted
+ to know the height of the document (using contentsHeight()), you
+ would call this function first.
+*/
+
+void TQTextEdit::sync()
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ TQFontMetrics fm( TQScrollView::font() );
+ resizeContents( d->od->maxLineWidth + 4, d->od->numLines * fm.lineSpacing() + 1 );
+ } else
+#endif
+ {
+ while ( lastFormatted ) {
+ lastFormatted->format();
+ lastFormatted = lastFormatted->next();
+ }
+ resizeContents( contentsWidth(), doc->height() );
+ }
+ updateScrollBars();
+}
+
+/*!
+ \reimp
+*/
+
+void TQTextEdit::setEnabled( bool b )
+{
+ TQScrollView::setEnabled( b );
+ if ( textFormat() == TQt::PlainText ) {
+ TQTextFormat *f = doc->formatCollection()->defaultFormat();
+ f->setColor( tqcolorGroup().text() );
+ updateContents();
+ }
+}
+
+/*!
+ Sets the background color of selection number \a selNum to \a back
+ and specifies whether the text of this selection should be
+ inverted with \a invertText.
+
+ This only works for \a selNum > 0. The default selection (\a
+ selNum == 0) gets its attributes from the text edit's
+ tqcolorGroup().
+*/
+
+void TQTextEdit::setSelectionAttributes( int selNum, const TQColor &back, bool invertText )
+{
+ if ( selNum < 1 )
+ return;
+ if ( selNum > doc->numSelections() )
+ doc->addSelection( selNum );
+ doc->setSelectionColor( selNum, back );
+ doc->setInvertSelectionText( selNum, invertText );
+}
+
+/*!
+ \reimp
+*/
+void TQTextEdit::windowActivationChange( bool oldActive )
+{
+ if ( oldActive && scrollTimer )
+ scrollTimer->stop();
+ if ( tqpalette().active() != tqpalette().inactive() )
+ updateContents();
+ TQScrollView::windowActivationChange( oldActive );
+}
+
+void TQTextEdit::setReadOnly( bool b )
+{
+ if ( (bool) readonly == b )
+ return;
+ readonly = b;
+#ifndef TQT_NO_CURSOR
+ if ( readonly )
+ viewport()->setCursor( Qt::ArrowCursor );
+ else
+ viewport()->setCursor( Qt::IBeamCursor );
+ setInputMethodEnabled( !readonly );
+#endif
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ checkOptimMode();
+#endif
+}
+
+/*!
+ Scrolls to the bottom of the document and does formatting if
+ required.
+*/
+
+void TQTextEdit::scrollToBottom()
+{
+ sync();
+ setContentsPos( contentsX(), contentsHeight() - visibleHeight() );
+}
+
+/*!
+ Returns the rectangle of the paragraph \a para in contents
+ coordinates, or an invalid rectangle if \a para is out of range.
+*/
+
+TQRect TQTextEdit::paragraphRect( int para ) const
+{
+ TQTextEdit *that = (TQTextEdit *)this;
+ that->sync();
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return TQRect( -1, -1, -1, -1 );
+ return p->rect();
+}
+
+/*!
+ Returns the paragraph which is at position \a pos (in contents
+ coordinates).
+*/
+
+int TQTextEdit::paragraphAt( const TQPoint &pos ) const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ TQFontMetrics fm( TQScrollView::font() );
+ int parag = pos.y() / fm.lineSpacing();
+ if ( parag <= d->od->numLines )
+ return parag;
+ else
+ return 0;
+ }
+#endif
+ TQTextCursor c( doc );
+ c.place( pos, doc->firstParagraph() );
+ if ( c.paragraph() )
+ return c.paragraph()->paragId();
+ return -1; // should never happen..
+}
+
+/*!
+ Returns the index of the character (relative to its paragraph) at
+ position \a pos (in contents coordinates). If \a para is not 0,
+ \a *para is set to the character's paragraph.
+*/
+
+int TQTextEdit::charAt( const TQPoint &pos, int *para ) const
+{
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ if ( d->optimMode ) {
+ int par = paragraphAt( pos );
+ if ( para )
+ *para = par;
+ return optimCharIndex( d->od->lines[ LOGOFFSET(par) ], pos.x() );
+ }
+#endif
+ TQTextCursor c( doc );
+ c.place( pos, doc->firstParagraph() );
+ if ( c.paragraph() ) {
+ if ( para )
+ *para = c.paragraph()->paragId();
+ return c.index();
+ }
+ return -1; // should never happen..
+}
+
+/*!
+ Sets the background color of the paragraph \a para to \a bg.
+*/
+
+void TQTextEdit::setParagraphBackgroundColor( int para, const TQColor &bg )
+{
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return;
+ p->setBackgroundColor( bg );
+ repaintChanged();
+}
+
+/*!
+ Clears the background color of the paragraph \a para, so that the
+ default color is used again.
+*/
+
+void TQTextEdit::clearParagraphBackground( int para )
+{
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return;
+ p->clearBackgroundColor();
+ repaintChanged();
+}
+
+/*!
+ Returns the background color of the paragraph \a para or an
+ invalid color if \a para is out of range or the paragraph has no
+ background set
+*/
+
+TQColor TQTextEdit::paragraphBackgroundColor( int para ) const
+{
+ TQTextParagraph *p = doc->paragAt( para );
+ if ( !p )
+ return TQColor();
+ TQColor *c = TQT_TQCOLOR(p->backgroundColor());
+ if ( c )
+ return *c;
+ return TQColor();
+}
+
+/*!
+ \property TQTextEdit::undoRedoEnabled
+ \brief whether undo/redo is enabled
+
+ When changing this property, the undo/redo history is cleared.
+
+ The default is TRUE.
+*/
+
+void TQTextEdit::setUndoRedoEnabled( bool b )
+{
+ undoRedoInfo.clear();
+ doc->commands()->clear();
+
+ undoEnabled = b;
+}
+
+bool TQTextEdit::isUndoRedoEnabled() const
+{
+ return undoEnabled;
+}
+
+/*!
+ Returns TRUE if undo is available; otherwise returns FALSE.
+*/
+
+bool TQTextEdit::isUndoAvailable() const
+{
+ return undoEnabled && (doc->commands()->isUndoAvailable() || undoRedoInfo.valid());
+}
+
+/*!
+ Returns TRUE if redo is available; otherwise returns FALSE.
+*/
+
+bool TQTextEdit::isRedoAvailable() const
+{
+ return undoEnabled && doc->commands()->isRedoAvailable();
+}
+
+void TQTextEdit::ensureFormatted( TQTextParagraph *p )
+{
+ while ( !p->isValid() ) {
+ if ( !lastFormatted )
+ return;
+ formatMore();
+ }
+}
+
+/*! \internal */
+void TQTextEdit::updateCursor( const TQPoint & pos )
+{
+ if ( isReadOnly() && linksEnabled() ) {
+ TQTextCursor c = *cursor;
+ placeCursor( pos, &c, TRUE );
+
+#ifndef TQT_NO_NETWORKPROTOCOL
+ bool insideParagRect = TRUE;
+ if (c.paragraph() == doc->lastParagraph()
+ && c.paragraph()->rect().y() + c.paragraph()->rect().height() < pos.y())
+ insideParagRect = FALSE;
+ if (insideParagRect && c.paragraph() && c.paragraph()->at( c.index() ) &&
+ c.paragraph()->at( c.index() )->isAnchor()) {
+ if (!c.paragraph()->at( c.index() )->anchorHref().isEmpty()
+ && c.index() < c.paragraph()->length() - 1 )
+ onLink = c.paragraph()->at( c.index() )->anchorHref();
+ else
+ onLink = TQString::null;
+
+ if (!c.paragraph()->at( c.index() )->anchorName().isEmpty()
+ && c.index() < c.paragraph()->length() - 1 )
+ d->onName = c.paragraph()->at( c.index() )->anchorName();
+ else
+ d->onName = TQString::null;
+
+ if (!c.paragraph()->at( c.index() )->anchorHref().isEmpty() ) {
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( onLink.isEmpty() ? Qt::ArrowCursor : Qt::PointingHandCursor );
+#endif
+ TQUrl u( doc->context(), onLink, TRUE );
+ emitHighlighted( u.toString( FALSE, FALSE ) );
+ }
+ } else {
+#ifndef TQT_NO_CURSOR
+ viewport()->setCursor( isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor );
+#endif
+ onLink = TQString::null;
+ emitHighlighted( TQString::null );
+ }
+#endif
+ }
+}
+
+/*!
+ Places the cursor \a c at the character which is closest to position
+ \a pos (in contents coordinates). If \a c is 0, the default text
+ cursor is used.
+
+ \sa setCursorPosition()
+*/
+void TQTextEdit::placeCursor( const TQPoint &pos, TQTextCursor *c )
+{
+ placeCursor( pos, c, FALSE );
+}
+
+/*! \internal */
+void TQTextEdit::clipboardChanged()
+{
+#ifndef TQT_NO_CLIPBOARD
+ // don't listen to selection changes
+ disconnect( TQApplication::tqclipboard(), TQT_SIGNAL(selectionChanged()), this, 0);
+#endif
+ selectAll(FALSE);
+}
+
+/*! \property TQTextEdit::tabChangesFocus
+ \brief whether TAB changes focus or is accepted as input
+
+ In some occasions text edits should not allow the user to input
+ tabulators or change indentation using the TAB key, as this breaks
+ the focus chain. The default is FALSE.
+
+*/
+
+void TQTextEdit::setTabChangesFocus( bool b )
+{
+ d->tabChangesFocus = b;
+}
+
+bool TQTextEdit::tabChangesFocus() const
+{
+ return d->tabChangesFocus;
+}
+
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+/* Implementation of optimized LogText mode follows */
+
+static void tqSwap( int * a, int * b )
+{
+ if ( !a || !b )
+ return;
+ int tmp = *a;
+ *a = *b;
+ *b = tmp;
+}
+
+/*! \internal */
+bool TQTextEdit::checkOptimMode()
+{
+ bool oldMode = d->optimMode;
+ if ( textFormat() == Qt::LogText ) {
+ setReadOnly( TRUE );
+ d->optimMode = TRUE;
+ } else {
+ d->optimMode = FALSE;
+ }
+
+ // when changing mode - try to keep selections and text
+ if ( oldMode != d->optimMode ) {
+ if ( d->optimMode ) {
+ d->od = new TQTextEditOptimPrivate;
+ connect( scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( optimDoAutoScroll() ) );
+ disconnect( doc, TQT_SIGNAL( minimumWidthChanged(int) ), this, TQT_SLOT( documentWidthChanged(int) ) );
+ disconnect( scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( autoScrollTimerDone() ) );
+ disconnect( formatTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( formatMore() ) );
+ optimSetText( doc->originalText() );
+ doc->clear(TRUE);
+ delete cursor;
+ cursor = new TQTextCursor( doc );
+ } else {
+ disconnect( scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( optimDoAutoScroll() ) );
+ connect( doc, TQT_SIGNAL( minimumWidthChanged(int) ), this, TQT_SLOT( documentWidthChanged(int) ) );
+ connect( scrollTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( autoScrollTimerDone() ) );
+ connect( formatTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( formatMore() ) );
+ setText( optimText() );
+ delete d->od;
+ d->od = 0;
+ }
+ }
+ return d->optimMode;
+}
+
+/*! \internal */
+TQString TQTextEdit::optimText() const
+{
+ TQString str, tmp;
+
+ if ( d->od->len == 0 )
+ return str;
+
+ // concatenate all strings
+ int i;
+ int offset;
+ TQMapConstIterator<int,TQTextEditOptimPrivate::Tag *> it;
+ TQTextEditOptimPrivate::Tag * ftag = 0;
+ for ( i = 0; i < d->od->numLines; i++ ) {
+ if ( d->od->lines[ LOGOFFSET(i) ].isEmpty() ) { // CR lines are empty
+ str += "\n";
+ } else {
+ tmp = d->od->lines[ LOGOFFSET(i) ] + "\n";
+ // inject the tags for this line
+ if ( (it = d->od->tagIndex.tqfind( LOGOFFSET(i) )) != d->od->tagIndex.end() )
+ ftag = it.data();
+ offset = 0;
+ while ( ftag && ftag->line == i ) {
+ tmp.insert( ftag->index + offset, "<" + ftag->tag + ">" );
+ offset += ftag->tag.length() + 2; // 2 -> the '<' and '>' chars
+ ftag = ftag->next;
+ }
+ str += tmp;
+ }
+ }
+ return str;
+}
+
+/*! \internal */
+void TQTextEdit::optimSetText( const TQString &str )
+{
+ optimRemoveSelection();
+// this is just too slow - but may have to go in due to compatibility reasons
+// if ( str == optimText() )
+// return;
+ d->od->numLines = 0;
+ d->od->lines.clear();
+ d->od->maxLineWidth = 0;
+ d->od->len = 0;
+ d->od->clearTags();
+ TQFontMetrics fm( TQScrollView::font() );
+ if ( !(str.isEmpty() || str.isNull() || d->maxLogLines == 0) ) {
+ TQStringList strl = TQStringList::split( '\n', str, TRUE );
+ int lWidth = 0;
+ for ( TQStringList::Iterator it = strl.begin(); it != strl.end(); ++it ) {
+ optimParseTags( &*it );
+ optimCheckLimit( *it );
+ lWidth = fm.width( *it );
+ if ( lWidth > d->od->maxLineWidth )
+ d->od->maxLineWidth = lWidth;
+ }
+ }
+ resizeContents( d->od->maxLineWidth + 4, d->od->numLines * fm.lineSpacing() + 1 );
+ repaintContents();
+ emit textChanged();
+}
+
+/*! \internal
+
+ Append \a tag to the tag list.
+*/
+TQTextEditOptimPrivate::Tag * TQTextEdit::optimAppendTag( int index, const TQString & tag )
+{
+ TQTextEditOptimPrivate::Tag * t = new TQTextEditOptimPrivate::Tag, * tmp;
+
+ if ( d->od->tags == 0 )
+ d->od->tags = t;
+ t->bold = t->italic = t->underline = FALSE;
+ t->line = d->od->numLines;
+ t->index = index;
+ t->tag = tag;
+ t->leftTag = 0;
+ t->tqparent = 0;
+ t->prev = d->od->lastTag;
+ if ( d->od->lastTag )
+ d->od->lastTag->next = t;
+ t->next = 0;
+ d->od->lastTag = t;
+ tmp = d->od->tagIndex[ LOGOFFSET(t->line) ];
+ if ( !tmp || (tmp && tmp->index > t->index) ) {
+ d->od->tagIndex.tqreplace( LOGOFFSET(t->line), t );
+ }
+ return t;
+}
+
+ /*! \internal
+
+ Insert \a tag in the tag - according to line and index numbers
+*/
+
+TQTextEditOptimPrivate::Tag *TQTextEdit::optimInsertTag(int line, int index, const TQString &tag)
+{
+ TQTextEditOptimPrivate::Tag *t = new TQTextEditOptimPrivate::Tag, *tmp;
+
+ if (d->od->tags == 0)
+ d->od->tags = t;
+ t->bold = t->italic = t->underline = FALSE;
+ t->line = line;
+ t->index = index;
+ t->tag = tag;
+ t->leftTag = 0;
+ t->tqparent = 0;
+ t->next = 0;
+ t->prev = 0;
+
+ // tqfind insertion pt. in tag struct.
+ TQMap<int,TQTextEditOptimPrivate::Tag *>::ConstIterator it;
+ if ((it = d->od->tagIndex.tqfind(LOGOFFSET(line))) != d->od->tagIndex.end()) {
+ tmp = *it;
+ if (tmp->index >= index) { // the exisiting tag may be placed AFTER the one we want to insert
+ tmp = tmp->prev;
+ } else {
+ while (tmp && tmp->next && tmp->next->line == line && tmp->next->index <= index)
+ tmp = tmp->next;
+ }
+ } else {
+ tmp = d->od->tags;
+ while (tmp && tmp->next && tmp->next->line < line)
+ tmp = tmp->next;
+ if (tmp == d->od->tags)
+ tmp = 0;
+ }
+
+ t->prev = tmp;
+ t->next = tmp ? tmp->next : 0;
+ if (t->next)
+ t->next->prev = t;
+ if (tmp)
+ tmp->next = t;
+
+ tmp = d->od->tagIndex[LOGOFFSET(t->line)];
+ if (!tmp || (tmp && tmp->index >= t->index)) {
+ d->od->tagIndex.tqreplace(LOGOFFSET(t->line), t);
+ }
+ return t;
+}
+
+
+/*! \internal
+
+ Find tags in \a line, remove them from \a line and put them in a
+ structure.
+
+ A tag is delimited by '<' and '>'. The characters '<', '>' and '&'
+ are escaped by using '&lt;', '&gt;' and '&amp;'. Left-tags marks
+ the starting point for formatting, while right-tags mark the ending
+ point. A right-tag is the same as a left-tag, but with a '/'
+ appearing before the tag keyword. E.g a valid left-tag: <b>, and
+ a valid right-tag: </b>. Tags can be nested, but they have to be
+ closed in the same order as they are opened. E.g:
+ <font color=red><font color=blue>blue</font>red</font> - is valid, while:
+ <font color=red><b>bold red</font> just bold</b> - is invalid since the font tag is
+ closed before the bold tag. Note that a tag does not have to be
+ closed: '<font color=blue>Lots of text - and then some..' is perfectly valid for
+ setting all text appearing after the tag to blue. A tag can be used
+ to change the color of a piece of text, or set one of the following
+ formatting attributes: bold, italic and underline. These attributes
+ are set using the <b>, <i> and <u> tags. Example of valid tags:
+ <font color=red>, </font>, <b>, <u>, <i>, </i>.
+ Example of valid text:
+ This is some <font color=red>red text</font>, while this is some <font color=green>green
+ text</font>. <font color=blue><font color=yellow>This is yellow</font>, while this is
+ blue.</font>
+
+ Note that only the color attribute of the HTML font tag is supported.
+
+ Limitations:
+ 1. A tag cannot span several lines.
+ 2. Very limited error checking - mismatching left/right-tags is the
+ only thing that is detected.
+
+*/
+void TQTextEdit::optimParseTags( TQString * line, int lineNo, int indexOffset )
+{
+ int len = line->length();
+ int i, startIndex = -1, endIndex = -1, escIndex = -1;
+ int state = 0; // 0 = outside tag, 1 = inside tag
+ bool tagOpen, tagClose;
+ int bold = 0, italic = 0, underline = 0;
+ TQString tagStr;
+ TQPtrStack<TQTextEditOptimPrivate::Tag> tagStack;
+
+ for ( i = 0; i < len; i++ ) {
+ tagOpen = (*line)[i] == '<';
+ tagClose = (*line)[i] == '>';
+
+ // handle '&lt;' and '&gt;' and '&amp;'
+ if ( (*line)[i] == '&' ) {
+ escIndex = i;
+ continue;
+ } else if ( escIndex != -1 && (*line)[i] == ';' ) {
+ TQString esc = line->mid( escIndex, i - escIndex + 1 );
+ TQString c;
+ if ( esc == "&lt;" )
+ c = '<';
+ else if ( esc == "&gt;" )
+ c = '>';
+ else if ( esc == "&amp;" )
+ c = '&';
+ line->tqreplace( escIndex, i - escIndex + 1, c );
+ len = line->length();
+ i -= i-escIndex;
+ escIndex = -1;
+ continue;
+ }
+
+ if ( state == 0 && tagOpen ) {
+ state = 1;
+ startIndex = i;
+ continue;
+ }
+ if ( state == 1 && tagClose ) {
+ state = 0;
+ endIndex = i;
+ if ( !tagStr.isEmpty() ) {
+ TQTextEditOptimPrivate::Tag * tag, * cur, * tmp;
+ bool format = TRUE;
+
+ if ( tagStr == "b" )
+ bold++;
+ else if ( tagStr == "/b" )
+ bold--;
+ else if ( tagStr == "i" )
+ italic++;
+ else if ( tagStr == "/i" )
+ italic--;
+ else if ( tagStr == "u" )
+ underline++;
+ else if ( tagStr == "/u" )
+ underline--;
+ else
+ format = FALSE;
+ if ( lineNo > -1 )
+ tag = optimInsertTag( lineNo, startIndex + indexOffset, tagStr );
+ else
+ tag = optimAppendTag( startIndex, tagStr );
+ // everything that is not a b, u or i tag is considered
+ // to be a color tag.
+ tag->type = format ? TQTextEditOptimPrivate::Format
+ : TQTextEditOptimPrivate::Color;
+ if ( tagStr[0] == '/' ) {
+ // this is a right-tag - search for the left-tag
+ // and possible tqparent tag
+ cur = tag->prev;
+ if ( !cur ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQTextEdit::optimParseTags: no left-tag for '<%s>' in line %d.", tag->tag.ascii(), tag->line + 1 );
+#endif
+ return; // something is wrong - give up
+ }
+ while ( cur ) {
+ if ( cur->leftTag ) { // push right-tags encountered
+ tagStack.push( cur );
+ } else {
+ tmp = tagStack.pop();
+ if ( !tmp ) {
+ if ( (("/" + cur->tag) == tag->tag) ||
+ (tag->tag == "/font" && cur->tag.left(4) == "font") ) {
+ // set up the left and tqparent of this tag
+ tag->leftTag = cur;
+ tmp = cur->prev;
+ if ( tmp && tmp->tqparent ) {
+ tag->tqparent = tmp->tqparent;
+ } else if ( tmp && !tmp->leftTag ) {
+ tag->tqparent = tmp;
+ }
+ break;
+ } else if ( !cur->leftTag ) {
+#ifdef TQT_CHECK_RANGE
+ qWarning( "TQTextEdit::optimParseTags: mismatching %s-tag for '<%s>' in line %d.", cur->tag[0] == '/' ? "left" : "right", cur->tag.ascii(), cur->line + 1 );
+#endif
+ return; // something is amiss - give up
+ }
+ }
+ }
+ cur = cur->prev;
+ }
+ } else {
+ tag->bold = bold > 0;
+ tag->italic = italic > 0;
+ tag->underline = underline > 0;
+ tmp = tag->prev;
+ while ( tmp && tmp->leftTag ) {
+ tmp = tmp->leftTag->tqparent;
+ }
+ if ( tmp ) {
+ tag->bold |= tmp->bold;
+ tag->italic |= tmp->italic;
+ tag->underline |= tmp->underline;
+ }
+ }
+ }
+ if ( startIndex != -1 ) {
+ int l = (endIndex == -1) ?
+ line->length() - startIndex : endIndex - startIndex;
+ line->remove( startIndex, l+1 );
+ len = line->length();
+ i -= l+1;
+ }
+ tagStr = "";
+ continue;
+ }
+
+ if ( state == 1 ) {
+ tagStr += (*line)[i];
+ }
+ }
+}
+
+// calculate the width of a string in pixels inc. tabs
+static int qStrWidth(const TQString& str, int tabWidth, const TQFontMetrics& fm)
+{
+ int tabs = str.tqcontains('\t');
+
+ if (!tabs)
+ return fm.width(str);
+
+ int newIdx = 0;
+ int lastIdx = 0;
+ int strWidth = 0;
+ int tn;
+ for (tn = 1; tn <= tabs; ++tn) {
+ newIdx = str.tqfind('\t', newIdx);
+ strWidth += fm.width(str.mid(lastIdx, newIdx - lastIdx));
+ if (strWidth >= tn * tabWidth) {
+ int u = tn;
+ while (strWidth >= u * tabWidth)
+ ++u;
+ strWidth = u * tabWidth;
+ } else {
+ strWidth = tn * tabWidth;
+ }
+ lastIdx = ++newIdx;
+ }
+ if ((int)str.length() > newIdx)
+ strWidth += fm.width(str.mid(newIdx));
+ return strWidth;
+}
+
+bool TQTextEdit::optimHasBoldMetrics(int line)
+{
+ TQTextEditOptimPrivate::Tag *t;
+ TQMapConstIterator<int,TQTextEditOptimPrivate::Tag *> it;
+ if ((it = d->od->tagIndex.tqfind(line)) != d->od->tagIndex.end()) {
+ t = *it;
+ while (t && t->line == line) {
+ if (t->bold)
+ return TRUE;
+ t = t->next;
+ }
+ } else if ((t = optimPreviousLeftTag(line)) && t->bold) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*! \internal
+
+ Append \a str to the current text buffer. Parses each line to tqfind
+ formatting tags.
+*/
+void TQTextEdit::optimAppend( const TQString &str )
+{
+ if ( str.isEmpty() || str.isNull() || d->maxLogLines == 0 )
+ return;
+
+ TQStringList strl = TQStringList::split( '\n', str, TRUE );
+ TQStringList::Iterator it = strl.begin();
+
+ TQFontMetrics fm(TQScrollView::font());
+ int lWidth = 0;
+
+ for ( ; it != strl.end(); ++it ) {
+ optimParseTags( &*it );
+ optimCheckLimit( *it );
+ if (optimHasBoldMetrics(d->od->numLines-1)) {
+ TQFont fnt = TQScrollView::font();
+ fnt.setBold(TRUE);
+ fm = TQFontMetrics(fnt);
+ }
+ lWidth = qStrWidth(*it, tabStopWidth(), fm) + 4;
+ if ( lWidth > d->od->maxLineWidth )
+ d->od->maxLineWidth = lWidth;
+ }
+ bool scrollToEnd = contentsY() >= contentsHeight() - visibleHeight();
+ resizeContents( d->od->maxLineWidth + 4, d->od->numLines * fm.lineSpacing() + 1 );
+ if ( scrollToEnd ) {
+ updateScrollBars();
+ ensureVisible( contentsX(), contentsHeight(), 0, 0 );
+ }
+ // when a max log size is set, the text may not be redrawn because
+ // the size of the viewport may not have changed
+ if ( d->maxLogLines > -1 )
+ viewport()->update();
+ emit textChanged();
+}
+
+
+static void qStripTags(TQString *line)
+{
+ int len = line->length();
+ int i, startIndex = -1, endIndex = -1, escIndex = -1;
+ int state = 0; // 0 = outside tag, 1 = inside tag
+ bool tagOpen, tagClose;
+
+ for ( i = 0; i < len; i++ ) {
+ tagOpen = (*line)[i] == '<';
+ tagClose = (*line)[i] == '>';
+
+ // handle '&lt;' and '&gt;' and '&amp;'
+ if ( (*line)[i] == '&' ) {
+ escIndex = i;
+ continue;
+ } else if ( escIndex != -1 && (*line)[i] == ';' ) {
+ TQString esc = line->mid( escIndex, i - escIndex + 1 );
+ TQString c;
+ if ( esc == "&lt;" )
+ c = '<';
+ else if ( esc == "&gt;" )
+ c = '>';
+ else if ( esc == "&amp;" )
+ c = '&';
+ line->tqreplace( escIndex, i - escIndex + 1, c );
+ len = line->length();
+ i -= i-escIndex;
+ escIndex = -1;
+ continue;
+ }
+
+ if ( state == 0 && tagOpen ) {
+ state = 1;
+ startIndex = i;
+ continue;
+ }
+ if ( state == 1 && tagClose ) {
+ state = 0;
+ endIndex = i;
+ if ( startIndex != -1 ) {
+ int l = (endIndex == -1) ?
+ line->length() - startIndex : endIndex - startIndex;
+ line->remove( startIndex, l+1 );
+ len = line->length();
+ i -= l+1;
+ }
+ continue;
+ }
+ }
+}
+
+/*! \internal
+
+ Inserts the text into \a line at index \a index.
+*/
+
+void TQTextEdit::optimInsert(const TQString& text, int line, int index)
+{
+ if (text.isEmpty() || d->maxLogLines == 0)
+ return;
+ if (line < 0)
+ line = 0;
+ if (line > d->od->numLines-1)
+ line = d->od->numLines-1;
+ if (index < 0)
+ index = 0;
+ if (index > (int) d->od->lines[line].length())
+ index = d->od->lines[line].length();
+
+ TQStringList strl = TQStringList::split('\n', text, TRUE);
+ int numNewLines = (int)strl.count() - 1;
+ TQTextEditOptimPrivate::Tag *tag = 0;
+ TQMap<int,TQTextEditOptimPrivate::Tag *>::ConstIterator ii;
+ int x;
+
+ if (numNewLines == 0) {
+ // Case 1. Fast single line case - just inject it!
+ TQString stripped = text;
+ qStripTags( &stripped );
+ d->od->lines[LOGOFFSET(line)].insert(index, stripped);
+ // move the tag indices following the insertion pt.
+ if ((ii = d->od->tagIndex.tqfind(LOGOFFSET(line))) != d->od->tagIndex.end()) {
+ tag = *ii;
+ while (tag && (LOGOFFSET(tag->line) == line && tag->index < index))
+ tag = tag->next;
+ while (tag && (LOGOFFSET(tag->line) == line)) {
+ tag->index += stripped.length();
+ tag = tag->next;
+ }
+ }
+ stripped = text;
+ optimParseTags(&stripped, line, index);
+ } else if (numNewLines > 0) {
+ // Case 2. We have at least 1 newline char - split at
+ // insertion pt. and make room for new lines - complex and slow!
+ TQString left = d->od->lines[LOGOFFSET(line)].left(index);
+ TQString right = d->od->lines[LOGOFFSET(line)].mid(index);
+
+ // rearrange lines for insertion
+ for (x = d->od->numLines - 1; x > line; x--)
+ d->od->lines[x + numNewLines] = d->od->lines[x];
+ d->od->numLines += numNewLines;
+
+ // fix the tag index and the tag line/index numbers - this
+ // might take a while..
+ for (x = line; x < d->od->numLines; x++) {
+ if ((ii = d->od->tagIndex.tqfind(LOGOFFSET(line))) != d->od->tagIndex.end()) {
+ tag = ii.data();
+ if (LOGOFFSET(tag->line) == line)
+ while (tag && (LOGOFFSET(tag->line) == line && tag->index < index))
+ tag = tag->next;
+ }
+ }
+
+ // relabel affected tags with new line numbers and new index
+ // positions
+ while (tag) {
+ if (LOGOFFSET(tag->line) == line)
+ tag->index -= index;
+ tag->line += numNewLines;
+ tag = tag->next;
+ }
+
+ // generate a new tag index
+ d->od->tagIndex.clear();
+ tag = d->od->tags;
+ while (tag) {
+ if (!((ii = d->od->tagIndex.tqfind(LOGOFFSET(tag->line))) != d->od->tagIndex.end()))
+ d->od->tagIndex[LOGOFFSET(tag->line)] = tag;
+ tag = tag->next;
+ }
+
+ // update the tag indices on the spliced line - needs to be done before new tags are added
+ TQString stripped = strl[strl.count() - 1];
+ qStripTags(&stripped);
+ if ((ii = d->od->tagIndex.tqfind(LOGOFFSET(line + numNewLines))) != d->od->tagIndex.end()) {
+ tag = *ii;
+ while (tag && (LOGOFFSET(tag->line) == line + numNewLines)) {
+ tag->index += stripped.length();
+ tag = tag->next;
+ }
+ }
+
+ // inject the new lines
+ TQStringList::Iterator it = strl.begin();
+ x = line;
+ int idx;
+ for (; it != strl.end(); ++it) {
+ stripped = *it;
+ qStripTags(&stripped);
+ if (x == line) {
+ stripped = left + stripped;
+ idx = index;
+ } else {
+ idx = 0;
+ }
+ d->od->lines[LOGOFFSET(x)] = stripped;
+ optimParseTags(&*it, x++, idx);
+ }
+ d->od->lines[LOGOFFSET(x - 1)] += right;
+ }
+ // recalculate the pixel width of the longest injected line -
+ TQFontMetrics fm(TQScrollView::font());
+ int lWidth = 0;
+
+ for (x = line; x < line + numNewLines; x++) {
+ if (optimHasBoldMetrics(x)) {
+ TQFont fnt = TQScrollView::font();
+ fnt.setBold(TRUE);
+ fm = TQFontMetrics(fnt);
+ }
+ lWidth = fm.width(d->od->lines[x]) + 4;
+ if (lWidth > d->od->maxLineWidth)
+ d->od->maxLineWidth = lWidth;
+ }
+ resizeContents(d->od->maxLineWidth + 4, d->od->numLines * fm.lineSpacing() + 1);
+ repaintContents();
+ emit textChanged();
+}
+
+
+
+/*! \internal
+
+ Returns the first open left-tag appearing before line \a line.
+ */
+TQTextEditOptimPrivate::Tag * TQTextEdit::optimPreviousLeftTag( int line )
+{
+ TQTextEditOptimPrivate::Tag * ftag = 0;
+ TQMapConstIterator<int,TQTextEditOptimPrivate::Tag *> it;
+ if ( (it = d->od->tagIndex.tqfind( LOGOFFSET(line) )) != d->od->tagIndex.end() )
+ ftag = it.data();
+ if ( !ftag ) {
+ // start searching for an open tag
+ ftag = d->od->tags;
+ while ( ftag ) {
+ if ( ftag->line > line || ftag->next == 0 ) {
+ if ( ftag->line > line )
+ ftag = ftag->prev;
+ break;
+ }
+ ftag = ftag->next;
+ }
+ } else {
+ ftag = ftag->prev;
+ }
+
+ if ( ftag ) {
+ if ( ftag && ftag->tqparent ) // use the open tqparent tag
+ ftag = ftag->tqparent;
+ else if ( ftag && ftag->leftTag ) // this is a right-tag with no tqparent
+ ftag = 0;
+ }
+ return ftag;
+}
+
+/*! \internal
+
+ Set the format for the string starting at index \a start and ending
+ at \a end according to \a tag. If \a tag is a Format tag, tqfind the
+ first open color tag appearing before \a tag and use that tag to
+ color the string.
+*/
+void TQTextEdit::optimSetTextFormat( TQTextDocument * td, TQTextCursor * cur,
+ TQTextFormat * f, int start, int end,
+ TQTextEditOptimPrivate::Tag * tag )
+{
+ int formatFlags = TQTextFormat::Bold | TQTextFormat::Italic |
+ TQTextFormat::Underline;
+ cur->setIndex( start );
+ td->setSelectionStart( 0, *cur );
+ cur->setIndex( end );
+ td->setSelectionEnd( 0, *cur );
+ TQStyleSheetItem * ssItem = styleSheet()->item( tag->tag );
+ if ( !ssItem || tag->type == TQTextEditOptimPrivate::Format ) {
+ f->setBold( tag->bold );
+ f->setItalic( tag->italic );
+ f->setUnderline( tag->underline );
+ if ( tag->type == TQTextEditOptimPrivate::Format ) {
+ // check to see if there are any open color tags prior to
+ // this format tag
+ tag = tag->prev;
+ while ( tag && (tag->type == TQTextEditOptimPrivate::Format ||
+ tag->leftTag) ) {
+ tag = tag->leftTag ? tag->tqparent : tag->prev;
+ }
+ }
+ if ( tag ) {
+ TQString col = tag->tag.simplifyWhiteSpace();
+ if ( col.left( 10 ) == "font color" ) {
+ int i = col.tqfind( '=', 10 );
+ col = TQT_TQSTRING(col.mid( i + 1 )).simplifyWhiteSpace();
+ if ( col[0] == '\"' )
+ col = col.mid( 1, col.length() - 2 );
+ }
+ TQColor color = TQColor( col );
+ if ( color.isValid() ) {
+ formatFlags |= TQTextFormat::Color;
+ f->setColor( color );
+ }
+ }
+ } else { // use the stylesheet tag definition
+ if ( ssItem->color().isValid() ) {
+ formatFlags |= TQTextFormat::Color;
+ f->setColor( ssItem->color() );
+ }
+ f->setBold( ssItem->fontWeight() == TQFont::Bold );
+ f->setItalic( ssItem->fontItalic() );
+ f->setUnderline( ssItem->fontUnderline() );
+ }
+ td->setFormat( 0, f, formatFlags );
+ td->removeSelection( 0 );
+}
+
+/*! \internal */
+void TQTextEdit::optimDrawContents( TQPainter * p, int clipx, int clipy,
+ int clipw, int cliph )
+{
+ TQFontMetrics fm( TQScrollView::font() );
+ int startLine = clipy / fm.lineSpacing();
+
+ // we always have to fetch at least two lines for drawing because the
+ // painter may be translated so that parts of two lines cover the area
+ // of a single line
+ int nLines = (cliph / fm.lineSpacing()) + 2;
+ int endLine = startLine + nLines;
+
+ if ( startLine >= d->od->numLines )
+ return;
+ if ( (startLine + nLines) > d->od->numLines )
+ nLines = d->od->numLines - startLine;
+
+ int i = 0;
+ TQString str;
+ for ( i = startLine; i < (startLine + nLines); i++ )
+ str.append( d->od->lines[ LOGOFFSET(i) ] + "\n" );
+
+ TQTextDocument * td = new TQTextDocument( 0 );
+ td->setDefaultFormat( TQScrollView::font(), TQColor() );
+ td->setPlainText( str );
+ td->setFormatter( new TQTextFormatterBreakWords ); // deleted by TQTextDoc
+ td->formatter()->setWrapEnabled( FALSE );
+ td->setTabStops(doc->tabStopWidth());
+
+ // get the current text color from the current format
+ td->selectAll( TQTextDocument::Standard );
+ TQTextFormat f;
+ f.setColor( tqcolorGroup().text() );
+ f.setFont( TQScrollView::font() );
+ td->setFormat( TQTextDocument::Standard, &f,
+ TQTextFormat::Color | TQTextFormat::Font );
+ td->removeSelection( TQTextDocument::Standard );
+
+ // add tag formatting
+ if ( d->od->tags ) {
+ int i = startLine;
+ TQMapConstIterator<int,TQTextEditOptimPrivate::Tag *> it;
+ TQTextEditOptimPrivate::Tag * tag = 0, * tmp = 0;
+ TQTextCursor cur( td );
+ // Step 1 - tqfind previous left-tag
+ tmp = optimPreviousLeftTag( i );
+ for ( ; i < startLine + nLines; i++ ) {
+ if ( (it = d->od->tagIndex.tqfind( LOGOFFSET(i) )) != d->od->tagIndex.end() )
+ tag = it.data();
+ // Step 2 - iterate over tags on the current line
+ int lastIndex = 0;
+ while ( tag && tag->line == i ) {
+ tmp = 0;
+ if ( tag->prev && !tag->prev->leftTag ) {
+ tmp = tag->prev;
+ } else if ( tag->prev && tag->prev->tqparent ) {
+ tmp = tag->prev->tqparent;
+ }
+ if ( (tag->index - lastIndex) > 0 && tmp ) {
+ optimSetTextFormat( td, &cur, &f, lastIndex, tag->index, tmp );
+ }
+ lastIndex = tag->index;
+ tmp = tag;
+ tag = tag->next;
+ }
+ // Step 3 - color last part of the line - if necessary
+ if ( tmp && tmp->tqparent )
+ tmp = tmp->tqparent;
+ if ( (cur.paragraph()->length()-1 - lastIndex) > 0 && tmp && !tmp->leftTag ) {
+ optimSetTextFormat( td, &cur, &f, lastIndex,
+ cur.paragraph()->length() - 1, tmp );
+ }
+ cur.setParagraph( cur.paragraph()->next() );
+ }
+ // useful debug info
+ //
+// tag = d->od->tags;
+// qWarning("###");
+// while ( tag ) {
+// qWarning( "Tag: %p, tqparent: %09p, leftTag: %09p, Name: %-15s, ParentName: %s, %d%d%d", tag,
+// tag->tqparent, tag->leftTag, tag->tag.latin1(), tag->tqparent ? tag->tqparent->tag.latin1():"<none>",
+// tag->bold, tag->italic, tag->underline );
+// tag = tag->next;
+// }
+ }
+
+ // if there is a selection, make sure that the selection in the
+ // part we need to redraw is set correctly
+ if ( optimHasSelection() ) {
+ TQTextCursor c1( td );
+ TQTextCursor c2( td );
+ int selStart = d->od->selStart.line;
+ int idxStart = d->od->selStart.index;
+ int selEnd = d->od->selEnd.line;
+ int idxEnd = d->od->selEnd.index;
+ if ( selEnd < selStart ) {
+ tqSwap( &selStart, &selEnd );
+ tqSwap( &idxStart, &idxEnd );
+ }
+ if ( selEnd > d->od->numLines-1 ) {
+ selEnd = d->od->numLines-1;
+ }
+ if ( startLine <= selStart && endLine >= selEnd ) {
+ // case 1: area to paint covers entire selection
+ int paragS = selStart - startLine;
+ int paragE = paragS + (selEnd - selStart);
+ TQTextParagraph * parag = td->paragAt( paragS );
+ if ( parag ) {
+ c1.setParagraph( parag );
+ if ( td->text( paragS ).length() >= (uint) idxStart )
+ c1.setIndex( idxStart );
+ }
+ parag = td->paragAt( paragE );
+ if ( parag ) {
+ c2.setParagraph( parag );
+ if ( td->text( paragE ).length() >= (uint) idxEnd )
+ c2.setIndex( idxEnd );
+ }
+ } else if ( startLine > selStart && endLine < selEnd ) {
+ // case 2: area to paint is all part of the selection
+ td->selectAll( TQTextDocument::Standard );
+ } else if ( startLine > selStart && endLine >= selEnd &&
+ startLine <= selEnd ) {
+ // case 3: area to paint starts inside a selection, ends past it
+ c1.setParagraph( td->firstParagraph() );
+ c1.setIndex( 0 );
+ int paragE = selEnd - startLine;
+ TQTextParagraph * parag = td->paragAt( paragE );
+ if ( parag ) {
+ c2.setParagraph( parag );
+ if ( td->text( paragE ).length() >= (uint) idxEnd )
+ c2.setIndex( idxEnd );
+ }
+ } else if ( startLine <= selStart && endLine < selEnd &&
+ endLine > selStart ) {
+ // case 4: area to paint starts before a selection, ends inside it
+ int paragS = selStart - startLine;
+ TQTextParagraph * parag = td->paragAt( paragS );
+ if ( parag ) {
+ c1.setParagraph( parag );
+ c1.setIndex( idxStart );
+ }
+ c2.setParagraph( td->lastParagraph() );
+ c2.setIndex( td->lastParagraph()->string()->toString().length() - 1 );
+
+ }
+ // previously selected?
+ if ( !td->hasSelection( TQTextDocument::Standard ) ) {
+ td->setSelectionStart( TQTextDocument::Standard, c1 );
+ td->setSelectionEnd( TQTextDocument::Standard, c2 );
+ }
+ }
+ td->doLayout( p, contentsWidth() );
+
+ // have to align the painter so that partly visible lines are
+ // drawn at the correct position within the area that needs to be
+ // painted
+ int offset = clipy % fm.lineSpacing() + 2;
+ TQRect r( clipx, 0, clipw, cliph + offset );
+ p->translate( 0, clipy - offset );
+ td->draw( p, r.x(), r.y(), r.width(), r.height(), tqcolorGroup() );
+ p->translate( 0, -(clipy - offset) );
+ delete td;
+}
+
+/*! \internal */
+void TQTextEdit::optimMousePressEvent( TQMouseEvent * e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+
+ TQFontMetrics fm( TQScrollView::font() );
+ mousePressed = TRUE;
+ mousePos = e->pos();
+ d->od->selStart.line = e->y() / fm.lineSpacing();
+ if ( d->od->selStart.line > d->od->numLines-1 ) {
+ d->od->selStart.line = d->od->numLines-1;
+ d->od->selStart.index = d->od->lines[ LOGOFFSET(d->od->numLines-1) ].length();
+ } else {
+ TQString str = d->od->lines[ LOGOFFSET(d->od->selStart.line) ];
+ d->od->selStart.index = optimCharIndex( str, mousePos.x() );
+ }
+ d->od->selEnd.line = d->od->selStart.line;
+ d->od->selEnd.index = d->od->selStart.index;
+ oldMousePos = e->pos();
+ repaintContents( FALSE );
+}
+
+/*! \internal */
+void TQTextEdit::optimMouseReleaseEvent( TQMouseEvent * e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+
+ if ( scrollTimer->isActive() )
+ scrollTimer->stop();
+ if ( !inDoubleClick ) {
+ TQFontMetrics fm( TQScrollView::font() );
+ d->od->selEnd.line = e->y() / fm.lineSpacing();
+ if ( d->od->selEnd.line > d->od->numLines-1 ) {
+ d->od->selEnd.line = d->od->numLines-1;
+ }
+ TQString str = d->od->lines[ LOGOFFSET(d->od->selEnd.line) ];
+ mousePos = e->pos();
+ d->od->selEnd.index = optimCharIndex( str, mousePos.x() );
+ if ( d->od->selEnd.line < d->od->selStart.line ) {
+ tqSwap( &d->od->selStart.line, &d->od->selEnd.line );
+ tqSwap( &d->od->selStart.index, &d->od->selEnd.index );
+ } else if ( d->od->selStart.line == d->od->selEnd.line &&
+ d->od->selStart.index > d->od->selEnd.index ) {
+ tqSwap( &d->od->selStart.index, &d->od->selEnd.index );
+ }
+ oldMousePos = e->pos();
+ repaintContents( FALSE );
+ }
+ if ( mousePressed ) {
+ mousePressed = FALSE;
+ copyToClipboard();
+ }
+
+ inDoubleClick = FALSE;
+ emit copyAvailable( optimHasSelection() );
+ emit selectionChanged();
+}
+
+/*! \internal */
+void TQTextEdit::optimMouseMoveEvent( TQMouseEvent * e )
+{
+ mousePos = e->pos();
+ optimDoAutoScroll();
+ oldMousePos = mousePos;
+}
+
+/*! \internal */
+void TQTextEdit::optimDoAutoScroll()
+{
+ if ( !mousePressed )
+ return;
+
+ TQFontMetrics fm( TQScrollView::font() );
+ TQPoint pos( mapFromGlobal( TQCursor::pos() ) );
+ bool doScroll = FALSE;
+ int xx = contentsX() + pos.x();
+ int yy = contentsY() + pos.y();
+
+ // tqfind out how much we have to scroll in either dir.
+ if ( pos.x() < 0 || pos.x() > viewport()->width() ||
+ pos.y() < 0 || pos.y() > viewport()->height() ) {
+ int my = yy;
+ if ( pos.x() < 0 )
+ xx = contentsX() - fm.width( 'w');
+ else if ( pos.x() > viewport()->width() )
+ xx = contentsX() + viewport()->width() + fm.width('w');
+
+ if ( pos.y() < 0 ) {
+ my = contentsY() - 1;
+ yy = (my / fm.lineSpacing()) * fm.lineSpacing() + 1;
+ } else if ( pos.y() > viewport()->height() ) {
+ my = contentsY() + viewport()->height() + 1;
+ yy = (my / fm.lineSpacing() + 1) * fm.lineSpacing() - 1;
+ }
+ d->od->selEnd.line = my / fm.lineSpacing();
+ mousePos.setX( xx );
+ mousePos.setY( my );
+ doScroll = TRUE;
+ } else {
+ d->od->selEnd.line = mousePos.y() / fm.lineSpacing();
+ }
+
+ if ( d->od->selEnd.line < 0 ) {
+ d->od->selEnd.line = 0;
+ } else if ( d->od->selEnd.line > d->od->numLines-1 ) {
+ d->od->selEnd.line = d->od->numLines-1;
+ }
+
+ TQString str = d->od->lines[ LOGOFFSET(d->od->selEnd.line) ];
+ d->od->selEnd.index = optimCharIndex( str, mousePos.x() );
+
+ // have to have a valid index before generating a paint event
+ if ( doScroll )
+ ensureVisible( xx, yy, 1, 1 );
+
+ // if the text document is smaller than the heigth of the viewport
+ // - redraw the whole thing otherwise calculate the rect that
+ // needs drawing.
+ if ( d->od->numLines * fm.lineSpacing() < viewport()->height() ) {
+ repaintContents( contentsX(), contentsY(), width(), height(), FALSE );
+ } else {
+ int h = TQABS(mousePos.y() - oldMousePos.y()) + fm.lineSpacing() * 2;
+ int y;
+ if ( oldMousePos.y() < mousePos.y() ) {
+ y = oldMousePos.y() - fm.lineSpacing();
+ } else {
+ // expand paint area for a fully selected line
+ h += fm.lineSpacing();
+ y = mousePos.y() - fm.lineSpacing()*2;
+ }
+ if ( y < 0 )
+ y = 0;
+ repaintContents( contentsX(), y, width(), h, FALSE );
+ }
+
+ if ( (!scrollTimer->isActive() && pos.y() < 0) || pos.y() > height() )
+ scrollTimer->start( 100, FALSE );
+ else if ( scrollTimer->isActive() && pos.y() >= 0 && pos.y() <= height() )
+ scrollTimer->stop();
+}
+
+/*! \internal
+
+ Returns the index of the character in the string \a str that is
+ currently under the mouse pointer.
+*/
+int TQTextEdit::optimCharIndex( const TQString &str, int mx ) const
+{
+ TQFontMetrics fm(TQScrollView::font());
+ uint i = 0;
+ int dd, dist = 10000000;
+ int curpos = 0;
+ int strWidth;
+ mx = mx - 4; // ### get the real margin from somewhere
+
+ if (!str.tqcontains('\t') && mx > fm.width(str))
+ return str.length();
+
+ while (i < str.length()) {
+ strWidth = qStrWidth(str.left(i), tabStopWidth(), fm);
+ dd = strWidth - mx;
+ if (TQABS(dd) <= dist) {
+ dist = TQABS(dd);
+ if (mx >= strWidth)
+ curpos = i;
+ }
+ ++i;
+ }
+ return curpos;
+}
+
+/*! \internal */
+void TQTextEdit::optimSelectAll()
+{
+ d->od->selStart.line = d->od->selStart.index = 0;
+ d->od->selEnd.line = d->od->numLines - 1;
+ d->od->selEnd.index = d->od->lines[ LOGOFFSET(d->od->selEnd.line) ].length();
+
+ repaintContents( FALSE );
+ emit copyAvailable( optimHasSelection() );
+ emit selectionChanged();
+}
+
+/*! \internal */
+void TQTextEdit::optimRemoveSelection()
+{
+ d->od->selStart.line = d->od->selEnd.line = -1;
+ d->od->selStart.index = d->od->selEnd.index = -1;
+ repaintContents( FALSE );
+}
+
+/*! \internal */
+void TQTextEdit::optimSetSelection( int startLine, int startIdx,
+ int endLine, int endIdx )
+{
+ d->od->selStart.line = startLine;
+ d->od->selEnd.line = endLine;
+ d->od->selStart.index = startIdx;
+ d->od->selEnd.index = endIdx;
+}
+
+/*! \internal */
+bool TQTextEdit::optimHasSelection() const
+{
+ if ( d->od->selStart.line != d->od->selEnd.line ||
+ d->od->selStart.index != d->od->selEnd.index )
+ return TRUE;
+ return FALSE;
+}
+
+/*! \internal */
+TQString TQTextEdit::optimSelectedText() const
+{
+ TQString str;
+
+ if ( !optimHasSelection() )
+ return str;
+
+ // concatenate all strings
+ if ( d->od->selStart.line == d->od->selEnd.line ) {
+ str = d->od->lines[ LOGOFFSET(d->od->selEnd.line) ].mid( d->od->selStart.index,
+ d->od->selEnd.index - d->od->selStart.index );
+ } else {
+ int i = d->od->selStart.line;
+ str = d->od->lines[ LOGOFFSET(i) ].right( d->od->lines[ LOGOFFSET(i) ].length() -
+ d->od->selStart.index ) + "\n";
+ i++;
+ for ( ; i < d->od->selEnd.line; i++ ) {
+ if ( d->od->lines[ LOGOFFSET(i) ].isEmpty() ) // CR lines are empty
+ str += "\n";
+ else
+ str += d->od->lines[ LOGOFFSET(i) ] + "\n";
+ }
+ str += d->od->lines[ LOGOFFSET(d->od->selEnd.line) ].left( d->od->selEnd.index );
+ }
+ return str;
+}
+
+/*! \internal */
+bool TQTextEdit::optimFind( const TQString & expr, bool cs, bool /*wo*/,
+ bool fw, int * para, int * index )
+{
+ bool found = FALSE;
+ int parag = para ? *para : d->od->search.line,
+ idx = index ? *index : d->od->search.index, i;
+
+ if ( d->od->len == 0 )
+ return FALSE;
+
+ for ( i = parag; fw ? i < d->od->numLines : i >= 0; fw ? i++ : i-- ) {
+ idx = fw ? d->od->lines[ LOGOFFSET(i) ].tqfind( expr, idx, cs ) :
+ d->od->lines[ LOGOFFSET(i) ].tqfindRev( expr, idx, cs );
+ if ( idx != -1 ) {
+ found = TRUE;
+ break;
+ } else if ( fw )
+ idx = 0;
+ }
+
+ if ( found ) {
+ if ( index )
+ *index = idx;
+ if ( para )
+ *para = i;
+ d->od->search.index = idx + 1;
+ d->od->search.line = i;
+ optimSetSelection( i, idx, i, idx + expr.length() );
+ TQFontMetrics fm( TQScrollView::font() );
+ int h = fm.lineSpacing();
+ int x = fm.width( d->od->lines[ LOGOFFSET(i) ].left( idx + expr.length()) ) + 4;
+ ensureVisible( x, i * h + h / 2, 1, h / 2 + 2 );
+ repaintContents(); // could possibly be optimized
+ }
+ return found;
+}
+
+/*! \reimp */
+void TQTextEdit::polish()
+{
+ // this will ensure that the last line is visible if text have
+ // been added to the widget before it is shown
+ if ( d->optimMode )
+ scrollToBottom();
+ TQWidget::polish();
+}
+
+/*!
+ Sets the maximum number of lines a TQTextEdit can hold in \c
+ LogText mode to \a limit. If \a limit is -1 (the default), this
+ signifies an unlimited number of lines.
+
+ \warning Never use formatting tags that span more than one line
+ when the maximum log lines is set. When lines are removed from the
+ top of the buffer it could result in an unbalanced tag pair, i.e.
+ the left formatting tag is removed before the right one.
+ */
+void TQTextEdit::setMaxLogLines( int limit )
+{
+ d->maxLogLines = limit;
+ if ( d->maxLogLines < -1 )
+ d->maxLogLines = -1;
+ if ( d->maxLogLines == -1 )
+ d->logOffset = 0;
+}
+
+/*!
+ Returns the maximum number of lines TQTextEdit can hold in \c
+ LogText mode. By default the number of lines is unlimited, which
+ is signified by a value of -1.
+ */
+int TQTextEdit::maxLogLines()
+{
+ return d->maxLogLines;
+}
+
+/*!
+ Check if the number of lines in the buffer is limited, and uphold
+ that limit when appending new lines.
+ */
+void TQTextEdit::optimCheckLimit( const TQString& str )
+{
+ if ( d->maxLogLines > -1 && d->maxLogLines <= d->od->numLines ) {
+ // NB! Removing the top line in the buffer will potentially
+ // destroy the structure holding the formatting tags - if line
+ // spanning tags are used.
+ TQTextEditOptimPrivate::Tag *t = d->od->tags, *tmp, *itr;
+ TQPtrList<TQTextEditOptimPrivate::Tag> lst;
+ while ( t ) {
+ t->line -= 1;
+ // unhook the ptr from the tag structure
+ if ( ((uint) LOGOFFSET(t->line) < (uint) d->logOffset &&
+ (uint) LOGOFFSET(t->line) < (uint) LOGOFFSET(d->od->numLines) &&
+ (uint) LOGOFFSET(d->od->numLines) > (uint) d->logOffset) )
+ {
+ if ( t->prev )
+ t->prev->next = t->next;
+ if ( t->next )
+ t->next->prev = t->prev;
+ if ( d->od->tags == t )
+ d->od->tags = t->next;
+ if ( d->od->lastTag == t ) {
+ if ( t->prev )
+ d->od->lastTag = t->prev;
+ else
+ d->od->lastTag = d->od->tags;
+ }
+ tmp = t;
+ t = t->next;
+ lst.append( tmp );
+ delete tmp;
+ } else {
+ t = t->next;
+ }
+ }
+ // Remove all references to the ptrs we just deleted
+ itr = d->od->tags;
+ while ( itr ){
+ for ( tmp = lst.first(); tmp; tmp = lst.next() ) {
+ if ( itr->tqparent == tmp )
+ itr->tqparent = 0;
+ if ( itr->leftTag == tmp )
+ itr->leftTag = 0;
+ }
+ itr = itr->next;
+ }
+ // ...in the tag index as well
+ TQMapIterator<int, TQTextEditOptimPrivate::Tag *> idx;
+ if ( (idx = d->od->tagIndex.tqfind( d->logOffset )) != d->od->tagIndex.end() )
+ d->od->tagIndex.remove( idx );
+
+ TQMapIterator<int,TQString> it;
+ if ( (it = d->od->lines.tqfind( d->logOffset )) != d->od->lines.end() ) {
+ d->od->len -= (*it).length();
+ d->od->lines.remove( it );
+ d->od->numLines--;
+ d->logOffset = LOGOFFSET(1);
+ }
+ }
+ d->od->len += str.length();
+ d->od->lines[ LOGOFFSET(d->od->numLines++) ] = str;
+}
+
+#endif // TQT_TEXTEDIT_OPTIMIZATION
+
+/*!
+ \property TQTextEdit::autoFormatting
+ \brief the enabled set of auto formatting features
+
+ The value can be any combination of the values in the \c
+ AutoFormatting enum. The default is \c AutoAll. Choose \c AutoNone
+ to disable all automatic formatting.
+
+ Currently, the only automatic formatting feature provided is \c
+ AutoBulletList; future versions of TQt may offer more.
+*/
+
+void TQTextEdit::setAutoFormatting( uint features )
+{
+ d->autoFormatting = features;
+}
+
+uint TQTextEdit::autoFormatting() const
+{
+ return d->autoFormatting;
+}
+
+/*!
+ Returns the TQSyntaxHighlighter set on this TQTextEdit. 0 is
+ returned if no syntax highlighter is set.
+ */
+TQSyntaxHighlighter * TQTextEdit::syntaxHighlighter() const
+{
+ if (document()->preProcessor())
+ return ((TQSyntaxHighlighterInternal *) document()->preProcessor())->highlighter;
+ else
+ return 0;
+}
+
+#endif //TQT_NO_TEXTEDIT
diff --git a/tqtinterface/qt4/src/widgets/tqtextedit.h b/tqtinterface/qt4/src/widgets/tqtextedit.h
new file mode 100644
index 0000000..c78371e
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtextedit.h
@@ -0,0 +1,617 @@
+/****************************************************************************
+**
+** Definition of the TQTextEdit class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTEXTEDIT_H
+#define TQTEXTEDIT_H
+
+#ifndef TQT_H
+#include "tqscrollview.h"
+#include "tqstylesheet.h"
+#include "tqptrvector.h"
+#include "tqvaluelist.h"
+#include "tqptrlist.h"
+#include "tqdragobject.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TEXTEDIT
+// uncomment below to enable optimization mode - also uncomment the
+// optimDoAutoScroll() private slot since tqmoc ignores #ifdefs..
+#define TQT_TEXTEDIT_OPTIMIZATION
+
+class TQPainter;
+class TQTextDocument;
+class TQTextCursor;
+class TQKeyEvent;
+class TQResizeEvent;
+class TQMouseEvent;
+class TQTimer;
+class TQTextString;
+class TQTextCommand;
+class TQTextParagraph;
+class TQTextFormat;
+class TQFont;
+class TQColor;
+class TQTextEdit;
+class TQTextBrowser;
+class TQTextString;
+struct TQUndoRedoInfoPrivate;
+class TQPopupMenu;
+class TQTextEditPrivate;
+class TQSyntaxHighlighter;
+
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+class TQTextEditOptimPrivate
+{
+public:
+ // Note: no left-tag has any value for leftTag or tqparent, and
+ // no right-tag has any formatting flags set.
+ enum TagType { Color = 0, Format = 1 };
+ struct Tag {
+ TagType type:2;
+ bool bold:1;
+ bool italic:1;
+ bool underline:1;
+ int line;
+ int index;
+ Tag * leftTag; // ptr to left-tag in a left-right tag pair
+ Tag * tqparent; // ptr to tqparent left-tag in a nested tag
+ Tag * prev;
+ Tag * next;
+ TQString tag;
+ };
+ TQTextEditOptimPrivate()
+ {
+ len = numLines = maxLineWidth = 0;
+ selStart.line = selStart.index = -1;
+ selEnd.line = selEnd.index = -1;
+ search.line = search.index = 0;
+ tags = lastTag = 0;
+ }
+ void clearTags()
+ {
+ Tag * itr = tags;
+ while ( tags ) {
+ itr = tags;
+ tags = tags->next;
+ delete itr;
+ }
+ tags = lastTag = 0;
+ tagIndex.clear();
+ }
+ ~TQTextEditOptimPrivate()
+ {
+ clearTags();
+ }
+ int len;
+ int numLines;
+ int maxLineWidth;
+ struct Selection {
+ int line;
+ int index;
+ };
+ Selection selStart, selEnd, search;
+ Tag * tags, * lastTag;
+ TQMap<int, TQString> lines;
+ TQMap<int, Tag *> tagIndex;
+};
+#endif
+
+class TQ_EXPORT TQTextEdit : public TQScrollView
+{
+ friend class TQTextBrowser;
+ friend class TQSyntaxHighlighter;
+
+ Q_OBJECT
+ TQ_OBJECT
+ Q_ENUMS( WordWrap WrapPolicy )
+ Q_ENUMS( AutoFormatting )
+ Q_PROPERTY( TextFormat textFormat READ textFormat WRITE setTextFormat )
+ Q_PROPERTY( TQString text READ text WRITE setText )
+ Q_PROPERTY( TQBrush paper READ paper WRITE setPaper )
+ Q_PROPERTY( bool linkUnderline READ linkUnderline WRITE setLinkUnderline )
+ Q_PROPERTY( TQString documentTitle READ documentTitle )
+ Q_PROPERTY( int length READ length )
+ Q_PROPERTY( WordWrap wordWrap READ wordWrap WRITE setWordWrap )
+ Q_PROPERTY( int wrapColumnOrWidth READ wrapColumnOrWidth WRITE setWrapColumnOrWidth )
+ Q_PROPERTY( WrapPolicy wrapPolicy READ wrapPolicy WRITE setWrapPolicy )
+ Q_PROPERTY( bool hasSelectedText READ hasSelectedText )
+ Q_PROPERTY( TQString selectedText READ selectedText )
+ Q_PROPERTY( int undoDepth READ undoDepth WRITE setUndoDepth )
+ Q_PROPERTY( bool overwriteMode READ isOverwriteMode WRITE setOverwriteMode )
+ Q_PROPERTY( bool modified READ isModified WRITE setModified DESIGNABLE false )
+ Q_PROPERTY( bool readOnly READ isReadOnly WRITE setReadOnly )
+ Q_PROPERTY( bool undoRedoEnabled READ isUndoRedoEnabled WRITE setUndoRedoEnabled )
+ Q_PROPERTY( int tabStopWidth READ tabStopWidth WRITE setTabStopWidth )
+ Q_PROPERTY( bool tabChangesFocus READ tabChangesFocus WRITE setTabChangesFocus )
+ Q_PROPERTY( AutoFormatting autoFormatting READ autoFormattingProp WRITE setAutoFormattingProp )
+
+public:
+ enum WordWrap {
+ NoWrap,
+ WidgetWidth,
+ FixedPixelWidth,
+ FixedColumnWidth
+ };
+
+ enum WrapPolicy {
+ AtWordBoundary,
+ AtWhiteSpace = AtWordBoundary, // AtWhiteSpace is deprecated
+ Anywhere,
+ AtWordOrDocumentBoundary
+ };
+
+ enum AutoFormatting {
+ AutoNone = 0,
+ AutoBulletList = 0x00000001,
+ AutoAll = 0xffffffff
+ };
+
+ enum KeyboardAction {
+ ActionBackspace,
+ ActionDelete,
+ ActionReturn,
+ ActionKill,
+ ActionWordBackspace,
+ ActionWordDelete
+ };
+
+ enum CursorAction {
+ MoveBackward,
+ MoveForward,
+ MoveWordBackward,
+ MoveWordForward,
+ MoveUp,
+ MoveDown,
+ MoveLineStart,
+ MoveLineEnd,
+ MoveHome,
+ MoveEnd,
+ MovePgUp,
+ MovePgDown
+ };
+
+ enum VerticalAlignment {
+ AlignNormal,
+ AlignSuperScript,
+ AlignSubScript
+ };
+
+ enum TextInsertionFlags {
+ RedoIndentation = 0x0001,
+ CheckNewLines = 0x0002,
+ RemoveSelected = 0x0004
+ };
+
+ TQTextEdit( const TQString& text, const TQString& context = TQString::null,
+ TQWidget* tqparent=0, const char* name=0);
+ TQTextEdit( TQWidget* tqparent=0, const char* name=0 );
+ virtual ~TQTextEdit();
+ void setPalette( const TQPalette & );
+
+ TQString text() const;
+ TQString text( int para ) const;
+ TQt::TextFormat textFormat() const;
+ TQString context() const;
+ TQString documentTitle() const;
+
+ void getSelection( int *paraFrom, int *indexFrom,
+ int *paraTo, int *indexTo, int selNum = 0 ) const;
+ virtual bool tqfind( const TQString &expr, bool cs, bool wo, bool forward = TRUE,
+ int *para = 0, int *index = 0 );
+
+ int paragraphs() const;
+ int lines() const;
+ int linesOfParagraph( int para ) const;
+ int lineOfChar( int para, int chr );
+ int length() const;
+ TQRect paragraphRect( int para ) const;
+ int paragraphAt( const TQPoint &pos ) const;
+ int charAt( const TQPoint &pos, int *para ) const;
+ int paragraphLength( int para ) const;
+
+ TQStyleSheet* styleSheet() const;
+#ifndef TQT_NO_MIME
+ TQMimeSourceFactory* mimeSourceFactory() const;
+#endif
+ TQBrush paper() const;
+ bool linkUnderline() const;
+
+ int heightForWidth( int w ) const;
+
+ bool hasSelectedText() const;
+ TQString selectedText() const;
+ bool isUndoAvailable() const;
+ bool isRedoAvailable() const;
+
+ WordWrap wordWrap() const;
+ int wrapColumnOrWidth() const;
+ WrapPolicy wrapPolicy() const;
+
+ int tabStopWidth() const;
+
+ TQString anchorAt( const TQPoint& pos );
+ TQString anchorAt( const TQPoint& pos, Qt::AnchorAttribute a );
+
+ TQSize tqsizeHint() const;
+
+ bool isReadOnly() const { return readonly; }
+
+ void getCursorPosition( int *parag, int *index ) const;
+
+ bool isModified() const;
+ bool italic() const;
+ bool bold() const;
+ bool underline() const;
+ TQString family() const;
+ int pointSize() const;
+ TQColor color() const;
+ TQFont font() const;
+ TQFont currentFont() const;
+ int tqalignment() const;
+ int undoDepth() const;
+
+ // do not use, will go away
+ virtual bool getFormat( int para, int index, TQFont *font, TQColor *color, VerticalAlignment *verticalAlignment );
+ // do not use, will go away
+ virtual bool getParagraphFormat( int para, TQFont *font, TQColor *color,
+ VerticalAlignment *verticalAlignment, int *tqalignment,
+ TQStyleSheetItem::DisplayMode *displayMode,
+ TQStyleSheetItem::ListStyle *listStyle,
+ int *listDepth );
+
+
+ bool isOverwriteMode() const { return overWrite; }
+ TQColor paragraphBackgroundColor( int para ) const;
+
+ bool isUndoRedoEnabled() const;
+ bool eventFilter( TQObject *o, TQEvent *e );
+ bool tabChangesFocus() const;
+
+ void setAutoFormatting( uint features );
+ uint autoFormatting() const;
+ inline void setAutoFormattingProp( AutoFormatting features ) { setAutoFormatting((uint)features); }
+ inline AutoFormatting autoFormattingProp() const { return (AutoFormatting)autoFormatting(); }
+ TQSyntaxHighlighter *syntaxHighlighter() const;
+
+public Q_SLOTS:
+ void setEnabled( bool );
+#ifndef TQT_NO_MIME
+ virtual void setMimeSourceFactory( TQMimeSourceFactory* factory );
+#endif
+ virtual void setStyleSheet( TQStyleSheet* styleSheet );
+ virtual void scrollToAnchor( const TQString& name );
+ virtual void setPaper( const TQBrush& pap );
+ virtual void setLinkUnderline( bool );
+
+ virtual void setWordWrap( WordWrap mode );
+ virtual void setWrapColumnOrWidth( int );
+ virtual void setWrapPolicy( WrapPolicy policy );
+
+ virtual void copy();
+ virtual void append( const TQString& text );
+
+ void setText( const TQString &txt ) { setText( txt, TQString::null ); }
+ virtual void setText( const TQString &txt, const TQString &context );
+ virtual void setTextFormat( TQt::TextFormat f );
+
+ virtual void selectAll( bool select = TRUE );
+ virtual void setTabStopWidth( int ts );
+ virtual void zoomIn( int range );
+ virtual void zoomIn() { zoomIn( 1 ); }
+ virtual void zoomOut( int range );
+ virtual void zoomOut() { zoomOut( 1 ); }
+ virtual void zoomTo( int size );
+
+ virtual void sync();
+ virtual void setReadOnly( bool b );
+
+ virtual void undo();
+ virtual void redo();
+ virtual void cut();
+ virtual void paste();
+#ifndef TQT_NO_CLIPBOARD
+ virtual void pasteSubType( const TQCString &subtype );
+#endif
+ virtual void clear();
+ virtual void del();
+ virtual void indent();
+ virtual void setItalic( bool b );
+ virtual void setBold( bool b );
+ virtual void setUnderline( bool b );
+ virtual void setFamily( const TQString &f );
+ virtual void setPointSize( int s );
+ virtual void setColor( const TQColor &c );
+ virtual void setFont( const TQFont &f );
+ virtual void setVerticalAlignment( VerticalAlignment a );
+ virtual void tqsetAlignment( int a );
+
+ // do not use, will go away
+ virtual void setParagType( TQStyleSheetItem::DisplayMode dm, TQStyleSheetItem::ListStyle listStyle );
+
+ virtual void setCursorPosition( int parag, int index );
+ virtual void setSelection( int parag_from, int index_from, int parag_to, int index_to, int selNum = 0 );
+ virtual void setSelectionAttributes( int selNum, const TQColor &back, bool invertText );
+ virtual void setModified( bool m );
+ virtual void resetFormat();
+ virtual void setUndoDepth( int d );
+ virtual void setFormat( TQTextFormat *f, int flags );
+ virtual void ensureCursorVisible();
+ virtual void placeCursor( const TQPoint &pos, TQTextCursor *c = 0 );
+ virtual void moveCursor( CursorAction action, bool select );
+ virtual void doKeyboardAction( KeyboardAction action );
+ virtual void removeSelectedText( int selNum = 0 );
+ virtual void removeSelection( int selNum = 0 );
+ virtual void setCurrentFont( const TQFont &f );
+ virtual void setOverwriteMode( bool b ) { overWrite = b; }
+
+ virtual void scrollToBottom();
+
+ void insert( const TQString &text, uint insertionFlags = CheckNewLines | RemoveSelected ); // ## virtual in 4.0
+
+ // obsolete
+ virtual void insert( const TQString &text, bool, bool = TRUE, bool = TRUE );
+
+ virtual void insertAt( const TQString &text, int para, int index );
+ virtual void removeParagraph( int para );
+ virtual void insertParagraph( const TQString &text, int para );
+
+ virtual void setParagraphBackgroundColor( int para, const TQColor &bg );
+ virtual void clearParagraphBackground( int para );
+
+ virtual void setUndoRedoEnabled( bool b );
+ void setTabChangesFocus( bool b ); // ### make virtual in 4.0
+
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ void polish();
+ void setMaxLogLines( int numLines );
+ int maxLogLines();
+#endif
+
+Q_SIGNALS:
+ void textChanged();
+ void selectionChanged();
+ void copyAvailable( bool );
+ void undoAvailable( bool yes );
+ void redoAvailable( bool yes );
+ void currentFontChanged( const TQFont &f );
+ void currentColorChanged( const TQColor &c );
+ void currentAlignmentChanged( int a );
+ void currentVerticalAlignmentChanged( VerticalAlignment a );
+ void cursorPositionChanged( TQTextCursor *c );
+ void cursorPositionChanged( int para, int pos );
+ void returnPressed();
+ void modificationChanged( bool m );
+ void clicked( int parag, int index );
+ void doubleClicked( int parag, int index );
+
+protected:
+ void repaintChanged();
+ void updateStyles();
+ void drawContents( TQPainter *p, int cx, int cy, int cw, int ch );
+ bool event( TQEvent *e );
+ void keyPressEvent( TQKeyEvent *e );
+ void resizeEvent( TQResizeEvent *e );
+ void viewportResizeEvent( TQResizeEvent* );
+ void contentsMousePressEvent( TQMouseEvent *e );
+ void contentsMouseMoveEvent( TQMouseEvent *e );
+ void contentsMouseReleaseEvent( TQMouseEvent *e );
+ void contentsMouseDoubleClickEvent( TQMouseEvent *e );
+#ifndef TQT_NO_WHEELEVENT
+ void contentsWheelEvent( TQWheelEvent *e );
+#endif
+ void imStartEvent( TQIMEvent * );
+ void imComposeEvent( TQIMEvent * );
+ void imEndEvent( TQIMEvent * );
+#ifndef TQT_NO_DRAGANDDROP
+ void contentsDragEnterEvent( TQDragEnterEvent *e );
+ void contentsDragMoveEvent( TQDragMoveEvent *e );
+ void contentsDragLeaveEvent( TQDragLeaveEvent *e );
+ void contentsDropEvent( TQDropEvent *e );
+#endif
+ void contentsContextMenuEvent( TQContextMenuEvent *e );
+ bool focusNextPrevChild( bool next );
+ TQTextDocument *document() const;
+ TQTextCursor *textCursor() const;
+ void setDocument( TQTextDocument *doc );
+ virtual TQPopupMenu *createPopupMenu( const TQPoint& pos );
+ virtual TQPopupMenu *createPopupMenu();
+ void drawCursor( bool visible );
+
+ void windowActivationChange( bool );
+
+protected Q_SLOTS:
+ virtual void doChangeInterval();
+ void sliderReleased(); // ### make virtual in 4.0
+#if (TQT_VERSION >= 0x040000)
+#error "Some functions need to be changed to virtual for TQt 4.0"
+#endif
+
+private Q_SLOTS:
+ void formatMore();
+ void doResize();
+ void autoScrollTimerDone();
+ void blinkCursor();
+ void setModified();
+ void startDrag();
+ void documentWidthChanged( int w );
+ void clipboardChanged();
+
+private:
+ struct TQ_EXPORT UndoRedoInfo {
+ enum Type { Invalid, Insert, Delete, Backspace, Return, RemoveSelected, Format, Style, IME };
+
+ UndoRedoInfo( TQTextDocument *dc );
+ ~UndoRedoInfo();
+ void clear();
+ bool valid() const;
+
+ TQUndoRedoInfoPrivate *d;
+ int id;
+ int index;
+ int eid;
+ int eindex;
+ TQTextFormat *format;
+ int flags;
+ Type type;
+ TQTextDocument *doc;
+ TQByteArray styleInformation;
+ };
+
+private:
+ void updateCursor( const TQPoint & pos );
+ void handleMouseMove( const TQPoint& pos );
+ void drawContents( TQPainter * );
+ virtual bool linksEnabled() const { return FALSE; }
+ void init();
+ void checkUndoRedoInfo( UndoRedoInfo::Type t );
+ void updateCurrentFormat();
+ bool handleReadOnlyKeyEvent( TQKeyEvent *e );
+ void makeParagVisible( TQTextParagraph *p );
+ void normalCopy();
+ void copyToClipboard();
+#ifndef TQT_NO_MIME
+ TQCString pickSpecial(TQMimeSource* ms, bool always_ask, const TQPoint&);
+ TQTextDrag *dragObject( TQWidget *tqparent = 0 ) const;
+#endif
+#ifndef TQT_NO_MIMECLIPBOARD
+ void pasteSpecial(const TQPoint&);
+#endif
+ void setFontInternal( const TQFont &f );
+
+ virtual void emitHighlighted( const TQString & ) {}
+ virtual void emitLinkClicked( const TQString & ) {}
+
+ void readFormats( TQTextCursor &c1, TQTextCursor &c2, TQTextString &text, bool fillStyles = FALSE );
+ void clearUndoRedo();
+ void paintDocument( bool drawAll, TQPainter *p, int cx = -1, int cy = -1, int cw = -1, int ch = -1 );
+ void moveCursor( CursorAction action );
+ void ensureFormatted( TQTextParagraph *p );
+ void placeCursor( const TQPoint &pos, TQTextCursor *c, bool link );
+ void updateMicroFocusHint();
+
+#ifdef TQT_TEXTEDIT_OPTIMIZATION
+ bool checkOptimMode();
+ TQString optimText() const;
+ void optimSetText( const TQString &str );
+ void optimAppend( const TQString &str );
+ void optimInsert( const TQString &str, int line, int index );
+ void optimDrawContents( TQPainter * p, int cx, int cy, int cw, int ch );
+ void optimMousePressEvent( TQMouseEvent * e );
+ void optimMouseReleaseEvent( TQMouseEvent * e );
+ void optimMouseMoveEvent( TQMouseEvent * e );
+ int optimCharIndex( const TQString &str, int mx ) const;
+ void optimSelectAll();
+ void optimRemoveSelection();
+ void optimSetSelection( int startLine, int startIdx, int endLine,
+ int endIdx );
+ bool optimHasSelection() const;
+ TQString optimSelectedText() const;
+ bool optimFind( const TQString & str, bool, bool, bool, int *, int * );
+ void optimParseTags( TQString * str, int lineNo = -1, int indexOffset = 0 );
+ TQTextEditOptimPrivate::Tag * optimPreviousLeftTag( int line );
+ void optimSetTextFormat( TQTextDocument *, TQTextCursor *, TQTextFormat * f,
+ int, int, TQTextEditOptimPrivate::Tag * t );
+ TQTextEditOptimPrivate::Tag * optimAppendTag( int index, const TQString & tag );
+ TQTextEditOptimPrivate::Tag * optimInsertTag( int line, int index, const TQString & tag );
+ void optimCheckLimit( const TQString& str );
+ bool optimHasBoldMetrics( int line );
+
+private Q_SLOTS:
+ void optimDoAutoScroll();
+#endif // TQT_TEXTEDIT_OPTIMIZATION
+
+private:
+#ifndef TQT_NO_CLIPBOARD
+ void pasteSubType( const TQCString &subtype, TQMimeSource *m );
+#endif
+
+private:
+ TQTextDocument *doc;
+ TQTextCursor *cursor;
+ TQTimer *formatTimer, *scrollTimer, *changeIntervalTimer, *blinkTimer, *dragStartTimer;
+ TQTextParagraph *lastFormatted;
+ int interval;
+ UndoRedoInfo undoRedoInfo;
+ TQTextFormat *currentFormat;
+ int currentAlignment;
+ TQPoint oldMousePos, mousePos;
+ TQPoint dragStartPos;
+ TQString onLink;
+ WordWrap wrapMode;
+ WrapPolicy wPolicy;
+ int wrapWidth;
+ TQString pressedLink;
+ TQTextEditPrivate *d;
+ bool inDoubleClick : 1;
+ bool mousePressed : 1;
+ bool cursorVisible : 1;
+ bool blinkCursorVisible : 1;
+ bool readOnly : 1;
+ bool modified : 1;
+ bool mightStartDrag : 1;
+ bool inDnD : 1;
+ bool readonly : 1;
+ bool undoEnabled : 1;
+ bool overWrite : 1;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQTextEdit( const TQTextEdit & );
+ TQTextEdit &operator=( const TQTextEdit & );
+#endif
+};
+
+inline TQTextDocument *TQTextEdit::document() const
+{
+ return doc;
+}
+
+inline TQTextCursor *TQTextEdit::textCursor() const
+{
+ return cursor;
+}
+
+inline void TQTextEdit::setCurrentFont( const TQFont &f )
+{
+ TQTextEdit::setFontInternal( f );
+}
+
+#endif //TQT_NO_TEXTEDIT
+#endif //TQTEXTVIEW_H
diff --git a/tqtinterface/qt4/src/widgets/tqtextview.cpp b/tqtinterface/qt4/src/widgets/tqtextview.cpp
new file mode 100644
index 0000000..286ae12
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtextview.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Implementation of the TQTextView class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtextview.h"
+
+#ifndef TQT_NO_TEXTVIEW
+
+/*! \class TQTextView
+ \brief The TQTextView class provides a rich-text viewer.
+
+ \obsolete
+
+ This class wraps a read-only \l TQTextEdit.
+ Use a \l TQTextEdit instead, and call setReadOnly(TRUE)
+ to disable editing.
+*/
+
+/*! \reimp */
+
+TQTextView::TQTextView( const TQString& text, const TQString& context,
+ TQWidget *tqparent, const char *name )
+ : TQTextEdit( text, context, tqparent, name )
+{
+ setReadOnly( TRUE );
+}
+
+/*! \reimp */
+
+TQTextView::TQTextView( TQWidget *tqparent, const char *name )
+ : TQTextEdit( tqparent, name )
+{
+ setReadOnly( TRUE );
+}
+
+/*! \reimp */
+
+TQTextView::~TQTextView()
+{
+}
+
+/*!
+ \property TQTextView::undoDepth
+ \brief the number of undoable steps
+*/
+
+/*!
+ \property TQTextView::overwriteMode
+ \brief whether new text overwrites or pushes aside existing text
+*/
+
+/*!
+ \property TQTextView::modified
+ \brief Whether the text view's contents have been modified.
+*/
+
+/*!
+ \property TQTextView::readOnly
+ \brief Whether the text view's contents are read only.
+*/
+
+/*!
+ \property TQTextView::undoRedoEnabled
+ \brief Whether undo and redo are enabled.
+*/
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqtextview.h b/tqtinterface/qt4/src/widgets/tqtextview.h
new file mode 100644
index 0000000..b8f74c3
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtextview.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Definition of the TQTextView class
+**
+** Created : 990101
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTEXTVIEW_H
+#define TQTEXTVIEW_H
+
+#ifndef TQT_H
+#include "tqtextedit.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TEXTVIEW
+
+class TQ_EXPORT TQTextView : public TQTextEdit
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_OVERRIDE( int undoDepth DESIGNABLE false SCRIPTABLE false )
+ TQ_OVERRIDE( bool overwriteMode DESIGNABLE false SCRIPTABLE false )
+ TQ_OVERRIDE( bool modified SCRIPTABLE false)
+ TQ_OVERRIDE( bool readOnly DESIGNABLE false SCRIPTABLE false )
+ TQ_OVERRIDE( bool undoRedoEnabled DESIGNABLE false SCRIPTABLE false )
+
+public:
+ TQTextView( const TQString& text, const TQString& context = TQString::null,
+ TQWidget* tqparent=0, const char* name=0);
+ TQTextView( TQWidget* tqparent=0, const char* name=0 );
+
+ virtual ~TQTextView();
+
+private:
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQTextView( const TQTextView & );
+ TQTextView &operator=( const TQTextView & );
+#endif
+};
+
+#endif //TQT_NO_TEXTVIEW
+#endif //TQTEXTVIEW_H
diff --git a/tqtinterface/qt4/src/widgets/tqtitlebar.cpp b/tqtinterface/qt4/src/widgets/tqtitlebar.cpp
new file mode 100644
index 0000000..ed7cd51
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtitlebar.cpp
@@ -0,0 +1,671 @@
+/****************************************************************************
+**
+** Implementation of some TQt private functions.
+**
+** Created : 001101
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqplatformdefs.h"
+
+#include "tqtitlebar_p.h"
+
+#ifndef TQT_NO_TITLEBAR
+
+#include <tqcursor.h>
+#include "tqapplication.h"
+#include "tqstyle.h"
+#include "tqdatetime.h"
+#include "private/tqapplication_p.h"
+#include "tqtooltip.h"
+#include "tqimage.h"
+#include "tqtimer.h"
+#include "tqpainter.h"
+#include "tqstyle.h"
+#include "private/tqinternal_p.h"
+#ifndef TQT_NO_WORKSPACE
+#include "tqworkspace.h"
+#endif
+#if defined(TQ_WS_WIN)
+#include "tqt_windows.h"
+#endif
+
+#ifndef TQT_NO_TOOLTIP
+class TQTitleBarTip : public TQToolTip
+{
+public:
+ TQTitleBarTip( TQWidget * tqparent ) : TQToolTip( tqparent ) { }
+
+ void maybeTip( const TQPoint &pos )
+ {
+ if ( !::tqqt_cast<TQTitleBar*>(parentWidget()) )
+ return;
+ TQTitleBar *t = (TQTitleBar *)parentWidget();
+
+ TQString tipstring;
+ TQStyle::SubControl ctrl = t->tqstyle().querySubControl(TQStyle::CC_TitleBar, t, pos);
+ TQSize controlSize = t->tqstyle().querySubControlMetrics(TQStyle::CC_TitleBar, t, ctrl).size();
+
+ TQWidget *window = t->window();
+ if ( window ) {
+ switch(ctrl) {
+ case TQStyle::SC_TitleBarSysMenu:
+ if ( t->testWFlags( TQt::WStyle_SysMenu ) )
+ tipstring = TQTitleBar::tr( "System Menu" );
+ break;
+
+ case TQStyle::SC_TitleBarShadeButton:
+ if ( t->testWFlags( TQt::WStyle_Tool ) && t->testWFlags( TQt::WStyle_MinMax ) )
+ tipstring = TQTitleBar::tr( "Shade" );
+ break;
+
+ case TQStyle::SC_TitleBarUnshadeButton:
+ if ( t->testWFlags( TQt::WStyle_Tool ) && t->testWFlags( TQt::WStyle_MinMax ) )
+ tipstring = TQTitleBar::tr( "Unshade" );
+ break;
+
+ case TQStyle::SC_TitleBarNormalButton:
+ case TQStyle::SC_TitleBarMinButton:
+ if ( !t->testWFlags( TQt::WStyle_Tool ) && t->testWFlags( TQt::WStyle_Minimize ) ) {
+ if( window->isMinimized() )
+ tipstring = TQTitleBar::tr( "Normalize" );
+ else
+ tipstring = TQTitleBar::tr( "Minimize" );
+ }
+ break;
+
+ case TQStyle::SC_TitleBarMaxButton:
+ if ( !t->testWFlags( TQt::WStyle_Tool ) && t->testWFlags( TQt::WStyle_Maximize ) )
+ tipstring = TQTitleBar::tr( "Maximize" );
+ break;
+
+ case TQStyle::SC_TitleBarCloseButton:
+ if ( t->testWFlags( TQt::WStyle_SysMenu ) )
+ tipstring = TQTitleBar::tr( "Close" );
+ break;
+
+ default:
+ break;
+ }
+ }
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( tipstring.isEmpty() ) {
+ if ( t->visibleText() != t->caption() )
+ tipstring = t->caption();
+ }
+#endif
+ if(!tipstring.isEmpty())
+ tip( TQRect(pos, controlSize), tipstring );
+ }
+};
+#endif
+
+class TQTitleBarPrivate
+{
+public:
+ TQTitleBarPrivate()
+ : toolTip( 0 ), act( 0 ), window( 0 ), movable( 1 ), pressed( 0 ), autoraise(0)
+ {
+ }
+
+ TQStyle::SCFlags buttonDown;
+ TQPoint moveOffset;
+ TQToolTip *toolTip;
+ bool act :1;
+ TQWidget* window;
+ bool movable :1;
+ bool pressed :1;
+ bool autoraise :1;
+ TQString cuttext;
+#ifdef TQT_NO_WIDGET_TOPEXTRA
+ TQString cap;
+#endif
+};
+
+TQTitleBar::TQTitleBar(TQWidget* w, TQWidget* tqparent, const char* name)
+ : TQWidget( tqparent, name, (WFlags)(WStyle_Customize | TQt::WStyle_NoBorder | TQt::WNoAutoErase) )
+{
+ d = new TQTitleBarPrivate();
+
+#ifndef TQT_NO_TOOLTIP
+ d->toolTip = new TQTitleBarTip( this );
+#endif
+ d->window = w;
+ d->buttonDown = TQStyle::SC_None;
+ d->act = 0;
+ if ( w ) {
+ setWFlags( ((TQTitleBar*)w)->getWFlags() | TQt::WNoAutoErase );
+ if ( w->tqminimumSize() == w->tqmaximumSize() )
+ clearWFlags( TQt::WStyle_Maximize );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ setCaption( w->caption() );
+#endif
+ } else {
+ setWFlags( (WFlags)(WStyle_Customize | TQt::WNoAutoErase) );
+ }
+
+ readColors();
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Fixed ) );
+ setMouseTracking(TRUE);
+}
+
+TQTitleBar::~TQTitleBar()
+{
+#ifndef TQT_NO_TOOLTIP
+ delete d->toolTip;
+#endif
+
+ delete d;
+ d = 0;
+}
+
+#ifdef TQ_WS_WIN
+extern TQRgb qt_colorref2qrgb(COLORREF col);
+#endif
+
+void TQTitleBar::readColors()
+{
+ TQPalette pal = palette();
+
+ bool colorsInitialized = FALSE;
+
+#ifdef TQ_WS_WIN // ask system properties on windows
+#ifndef SPI_GETGRADIENTCAPTIONS
+#define SPI_GETGRADIENTCAPTIONS 0x1008
+#endif
+#ifndef COLOR_GRADIENTACTIVECAPTION
+#define COLOR_GRADIENTACTIVECAPTION 27
+#endif
+#ifndef COLOR_GRADIENTINACTIVECAPTION
+#define COLOR_GRADIENTINACTIVECAPTION 28
+#endif
+ if ( TQApplication::desktopSettingsAware() ) {
+ pal.setColor( TQPalette::Active, TQColorGroup::Highlight, qt_colorref2qrgb(GetSysColor(COLOR_ACTIVECAPTION)) );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::Highlight, qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTION)) );
+ pal.setColor( TQPalette::Active, TQColorGroup::HighlightedText, qt_colorref2qrgb(GetSysColor(COLOR_CAPTIONTEXT)) );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::HighlightedText, qt_colorref2qrgb(GetSysColor(COLOR_INACTIVECAPTIONTEXT)) );
+ if ( qt_winver != TQt::WV_95 && qt_winver != WV_NT ) {
+ colorsInitialized = TRUE;
+ BOOL gradient;
+ TQT_WA( {
+ SystemParametersInfo( SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0 );
+ } , {
+ SystemParametersInfoA( SPI_GETGRADIENTCAPTIONS, 0, &gradient, 0 );
+ } );
+ if ( gradient ) {
+ pal.setColor( TQPalette::Active, TQColorGroup::Base, qt_colorref2qrgb(GetSysColor(COLOR_GRADIENTACTIVECAPTION)) );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::Base, qt_colorref2qrgb(GetSysColor(COLOR_GRADIENTINACTIVECAPTION)) );
+ } else {
+ pal.setColor( TQPalette::Active, TQColorGroup::Base, tqpalette().active().highlight() );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::Base, tqpalette().inactive().highlight() );
+ }
+ }
+ }
+#endif // TQ_WS_WIN
+ if ( !colorsInitialized ) {
+ pal.setColor( TQPalette::Active, TQColorGroup::Highlight, tqpalette().active().highlight() );
+ pal.setColor( TQPalette::Active, TQColorGroup::Base, tqpalette().active().highlight() );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::Highlight, tqpalette().inactive().dark() );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::Base, tqpalette().inactive().dark() );
+ pal.setColor( TQPalette::Inactive, TQColorGroup::HighlightedText, tqpalette().inactive().background() );
+ }
+
+ setPalette( pal );
+ setActive( d->act );
+}
+
+void TQTitleBar::mousePressEvent( TQMouseEvent * e)
+{
+ if ( !d->act )
+ emit doActivate();
+ if ( e->button() == Qt::LeftButton ) {
+ d->pressed = TRUE;
+ TQStyle::SCFlags ctrl = tqstyle().querySubControl(TQStyle::CC_TitleBar, this, e->pos());
+ switch (ctrl) {
+ case TQStyle::SC_TitleBarSysMenu:
+ if ( testWFlags( TQt::WStyle_SysMenu ) && !testWFlags( TQt::WStyle_Tool ) ) {
+ d->buttonDown = TQStyle::SC_None;
+ static TQTime* t = 0;
+ static TQTitleBar* tc = 0;
+ if ( !t )
+ t = new TQTime;
+ if ( tc != this || t->elapsed() > TQApplication::doubleClickInterval() ) {
+ emit showOperationMenu();
+ t->start();
+ tc = this;
+ } else {
+ tc = 0;
+ emit doClose();
+ return;
+ }
+ }
+ break;
+
+ case TQStyle::SC_TitleBarShadeButton:
+ case TQStyle::SC_TitleBarUnshadeButton:
+ if ( testWFlags( TQt::WStyle_MinMax ) && testWFlags( TQt::WStyle_Tool ) )
+ d->buttonDown = ctrl;
+ break;
+
+ case TQStyle::SC_TitleBarNormalButton:
+ if( testWFlags( TQt::WStyle_Minimize ) && !testWFlags( TQt::WStyle_Tool ) )
+ d->buttonDown = ctrl;
+ break;
+
+ case TQStyle::SC_TitleBarMinButton:
+ if( testWFlags( TQt::WStyle_Minimize ) && !testWFlags( TQt::WStyle_Tool ) )
+ d->buttonDown = ctrl;
+ break;
+
+ case TQStyle::SC_TitleBarMaxButton:
+ if ( testWFlags( TQt::WStyle_Maximize ) && !testWFlags( TQt::WStyle_Tool ) )
+ d->buttonDown = ctrl;
+ break;
+
+ case TQStyle::SC_TitleBarCloseButton:
+ if ( testWFlags( TQt::WStyle_SysMenu ) )
+ d->buttonDown = ctrl;
+ break;
+
+ case TQStyle::SC_TitleBarLabel:
+ d->buttonDown = ctrl;
+ d->moveOffset = mapToParent( e->pos() );
+ break;
+
+ default:
+ break;
+ }
+ tqrepaint( FALSE );
+ } else {
+ d->pressed = FALSE;
+ }
+}
+
+void TQTitleBar::contextMenuEvent( TQContextMenuEvent *e )
+{
+ TQStyle::SCFlags ctrl = tqstyle().querySubControl(TQStyle::CC_TitleBar, this, e->pos());
+ if( ctrl == TQStyle::SC_TitleBarLabel || ctrl == TQStyle::SC_TitleBarSysMenu )
+ emit popupOperationMenu(e->globalPos());
+ else
+ e->ignore();
+}
+
+void TQTitleBar::mouseReleaseEvent( TQMouseEvent * e)
+{
+ if ( e->button() == Qt::LeftButton && d->pressed) {
+ TQStyle::SCFlags ctrl = tqstyle().querySubControl(TQStyle::CC_TitleBar, this, e->pos());
+
+ if (ctrl == d->buttonDown) {
+ switch(ctrl) {
+ case TQStyle::SC_TitleBarShadeButton:
+ case TQStyle::SC_TitleBarUnshadeButton:
+ if( testWFlags( TQt::WStyle_MinMax ) && testWFlags( TQt::WStyle_Tool ) )
+ emit doShade();
+ break;
+
+ case TQStyle::SC_TitleBarNormalButton:
+ if( testWFlags( TQt::WStyle_MinMax ) && !testWFlags( TQt::WStyle_Tool ) )
+ emit doNormal();
+ break;
+
+ case TQStyle::SC_TitleBarMinButton:
+ if( testWFlags( TQt::WStyle_Minimize ) && !testWFlags( TQt::WStyle_Tool ) )
+ emit doMinimize();
+ break;
+
+ case TQStyle::SC_TitleBarMaxButton:
+ if( d->window && testWFlags( TQt::WStyle_Maximize ) && !testWFlags( TQt::WStyle_Tool ) ) {
+ if(d->window->isMaximized())
+ emit doNormal();
+ else
+ emit doMaximize();
+ }
+ break;
+
+ case TQStyle::SC_TitleBarCloseButton:
+ if( testWFlags( TQt::WStyle_SysMenu ) ) {
+ d->buttonDown = TQStyle::SC_None;
+ tqrepaint(FALSE);
+ emit doClose();
+ return;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ d->buttonDown = TQStyle::SC_None;
+ tqrepaint(FALSE);
+ d->pressed = FALSE;
+ }
+}
+
+void TQTitleBar::mouseMoveEvent( TQMouseEvent * e)
+{
+ switch (d->buttonDown) {
+ case TQStyle::SC_None:
+ if(autoRaise())
+ tqrepaint( FALSE );
+ break;
+ case TQStyle::SC_TitleBarSysMenu:
+ break;
+ case TQStyle::SC_TitleBarShadeButton:
+ case TQStyle::SC_TitleBarUnshadeButton:
+ case TQStyle::SC_TitleBarNormalButton:
+ case TQStyle::SC_TitleBarMinButton:
+ case TQStyle::SC_TitleBarMaxButton:
+ case TQStyle::SC_TitleBarCloseButton:
+ {
+ TQStyle::SCFlags last_ctrl = d->buttonDown;
+ d->buttonDown = tqstyle().querySubControl(TQStyle::CC_TitleBar, this, e->pos());
+ if( d->buttonDown != last_ctrl)
+ d->buttonDown = TQStyle::SC_None;
+ tqrepaint(FALSE);
+ d->buttonDown = last_ctrl;
+ }
+ break;
+
+ case TQStyle::SC_TitleBarLabel:
+ if ( d->buttonDown == TQStyle::SC_TitleBarLabel && d->movable && d->pressed ) {
+ if ( (d->moveOffset - mapToParent( e->pos() ) ).manhattanLength() >= 4 ) {
+ TQPoint p = mapFromGlobal(e->globalPos());
+#ifndef TQT_NO_WORKSPACE
+ if(d->window && d->window->parentWidget()->inherits("TQWorkspaceChild")) {
+ TQWorkspace *workspace = ::tqqt_cast<TQWorkspace*>(d->window->parentWidget()->parentWidget());
+ if(workspace) {
+ p = workspace->mapFromGlobal( e->globalPos() );
+ if ( !TQT_TQRECT_OBJECT(workspace->rect()).tqcontains(p) ) {
+ if ( p.x() < 0 )
+ p.rx() = 0;
+ if ( p.y() < 0 )
+ p.ry() = 0;
+ if ( p.x() > workspace->width() )
+ p.rx() = workspace->width();
+ if ( p.y() > workspace->height() )
+ p.ry() = workspace->height();
+ }
+ }
+ }
+#endif
+ TQPoint pp = p - d->moveOffset;
+ if (!parentWidget()->isMaximized())
+ parentWidget()->move( pp );
+ }
+ } else {
+ TQStyle::SCFlags last_ctrl = d->buttonDown;
+ d->buttonDown = TQStyle::SC_None;
+ if( d->buttonDown != last_ctrl)
+ tqrepaint(FALSE);
+ }
+ break;
+ }
+}
+
+void TQTitleBar::resizeEvent( TQResizeEvent *r)
+{
+ TQWidget::resizeEvent(r);
+ cutText();
+}
+
+void TQTitleBar::paintEvent(TQPaintEvent *)
+{
+ TQStyle::SCFlags ctrls = TQStyle::SC_TitleBarLabel;
+ if ( testWFlags( TQt::WStyle_SysMenu) ) {
+ if ( testWFlags( TQt::WStyle_Tool ) ) {
+ ctrls |= TQStyle::SC_TitleBarCloseButton;
+ if ( d->window && testWFlags( TQt::WStyle_MinMax ) ) {
+ if ( d->window->isMinimized() )
+ ctrls |= TQStyle::SC_TitleBarUnshadeButton;
+ else
+ ctrls |= TQStyle::SC_TitleBarShadeButton;
+ }
+ } else {
+ ctrls |= TQStyle::SC_TitleBarSysMenu | TQStyle::SC_TitleBarCloseButton;
+ if ( d->window && testWFlags( TQt::WStyle_Minimize ) ) {
+ if( d->window && d->window->isMinimized() )
+ ctrls |= TQStyle::SC_TitleBarNormalButton;
+ else
+ ctrls |= TQStyle::SC_TitleBarMinButton;
+ }
+ if ( d->window && testWFlags( TQt::WStyle_Maximize ) && !d->window->isMaximized() )
+ ctrls |= TQStyle::SC_TitleBarMaxButton;
+ }
+ }
+
+ TQStyle::SCFlags under_mouse = TQStyle::SC_None;
+ if( autoRaise() && hasMouse() ) {
+ TQPoint p(mapFromGlobal(TQCursor::pos()));
+ under_mouse = tqstyle().querySubControl(TQStyle::CC_TitleBar, this, p);
+ ctrls ^= under_mouse;
+ }
+
+ TQSharedDoubleBuffer buffer( this, rect() );
+ tqstyle().tqdrawComplexControl(TQStyle::CC_TitleBar, buffer.painter(), this, rect(),
+ tqcolorGroup(),
+ isEnabled() ? TQStyle::Style_Enabled :
+ TQStyle::Style_Default, ctrls, d->buttonDown);
+ if(under_mouse != TQStyle::SC_None)
+ tqstyle().tqdrawComplexControl(TQStyle::CC_TitleBar, buffer.painter(), this, rect(),
+ tqcolorGroup(),
+ (TQStyle::Style_MouseOver |
+ (isEnabled() ? TQStyle::Style_Enabled : (QStyle::StateFlag)0)),
+ under_mouse, d->buttonDown);
+}
+
+void TQTitleBar::mouseDoubleClickEvent( TQMouseEvent *e )
+{
+ if ( e->button() != Qt::LeftButton )
+ return;
+
+ switch(tqstyle().querySubControl(TQStyle::CC_TitleBar, this, e->pos())) {
+ case TQStyle::SC_TitleBarLabel:
+ emit doubleClicked();
+ break;
+
+ case TQStyle::SC_TitleBarSysMenu:
+ if ( testWFlags( TQt::WStyle_SysMenu ) )
+ emit doClose();
+ break;
+
+ default:
+ break;
+ }
+}
+
+#ifdef TQT_NO_WIDGET_TOPEXTRA
+// We provide one, since titlebar is useless otherwise.
+TQString TQTitleBar::caption() const
+{
+ return d->cap;
+}
+#endif
+
+void TQTitleBar::cutText()
+{
+ TQFontMetrics fm( font() );
+
+ int maxw = tqstyle().querySubControlMetrics(TQStyle::CC_TitleBar, this,
+ TQStyle::SC_TitleBarLabel).width();
+ if ( !d->window )
+ maxw = width() - 20;
+ const TQString txt = caption();
+ d->cuttext = txt;
+ if ( fm.width( txt + "m" ) > maxw ) {
+ int i = txt.length();
+ int dotlength = fm.width( "..." );
+ while ( i>0 && fm.width(txt.left( i )) + dotlength > maxw )
+ i--;
+ if(i != (int)txt.length())
+ d->cuttext = txt.left( i ) + "...";
+ }
+}
+
+void TQTitleBar::setCaption( const TQString& title )
+{
+ if( caption() == title)
+ return;
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ TQWidget::setCaption( title );
+#else
+ d->cap = title;
+#endif
+ cutText();
+
+ update();
+}
+
+
+void TQTitleBar::setIcon( const TQPixmap& icon )
+{
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+#ifndef TQT_NO_IMAGE_SMOOTHSCALE
+ TQRect menur = tqstyle().querySubControlMetrics(TQStyle::CC_TitleBar, this,
+ TQStyle::SC_TitleBarSysMenu);
+
+ TQPixmap theIcon;
+ if (icon.width() > menur.width()) {
+ // try to keep something close to the same aspect
+ int aspect = (icon.height() * 100) / icon.width();
+ int newh = (aspect * menur.width()) / 100;
+ theIcon.convertFromImage( TQT_TQIMAGE_OBJECT(icon.convertToImage()).smoothScale(menur.width(),
+ newh) );
+ } else if (icon.height() > menur.height()) {
+ // try to keep something close to the same aspect
+ int aspect = (icon.width() * 100) / icon.height();
+ int neww = (aspect * menur.height()) / 100;
+ theIcon.convertFromImage( TQT_TQIMAGE_OBJECT(icon.convertToImage()).smoothScale(neww,
+ menur.height()) );
+ } else
+ theIcon = icon;
+
+ TQWidget::setIcon( theIcon );
+#else
+ TQWidget::setIcon( icon );
+#endif
+
+ update();
+#endif
+}
+
+void TQTitleBar::leaveEvent( TQEvent * )
+{
+ if(autoRaise() && !d->pressed)
+ tqrepaint( FALSE );
+}
+
+void TQTitleBar::enterEvent( TQEvent * )
+{
+ if(autoRaise() && !d->pressed)
+ tqrepaint( FALSE );
+ TQEvent e( TQEvent::Leave );
+ TQApplication::sendEvent( parentWidget(), &e );
+}
+
+void TQTitleBar::setActive( bool active )
+{
+ if ( d->act == active )
+ return ;
+
+ d->act = active;
+ update();
+}
+
+bool TQTitleBar::isActive() const
+{
+ return d->act;
+}
+
+bool TQTitleBar::usesActiveColor() const
+{
+ return ( isActive() && isActiveWindow() ) ||
+ ( !window() && tqtopLevelWidget()->isActiveWindow() );
+}
+
+TQString TQTitleBar::visibleText() const
+{
+ return d->cuttext;
+}
+
+TQWidget *TQTitleBar::window() const
+{
+ return d->window;
+}
+
+bool TQTitleBar::event( TQEvent* e )
+{
+ if ( e->type() == TQEvent::ApplicationPaletteChange ) {
+ readColors();
+ return TRUE;
+ } else if ( e->type() == TQEvent::WindowActivate ) {
+ setActive( d->act );
+ } else if ( e->type() == TQEvent::WindowDeactivate ) {
+ bool wasActive = d->act;
+ setActive( FALSE );
+ d->act = wasActive;
+ }
+
+ return TQWidget::event( e );
+}
+
+void TQTitleBar::setMovable(bool b)
+{
+ d->movable = b;
+}
+
+bool TQTitleBar::isMovable() const
+{
+ return d->movable;
+}
+
+void TQTitleBar::setAutoRaise(bool b)
+{
+ d->autoraise = b;
+}
+
+bool TQTitleBar::autoRaise() const
+{
+ return d->autoraise;
+}
+
+TQSize TQTitleBar::tqsizeHint() const
+{
+ constPolish();
+ TQRect menur = tqstyle().querySubControlMetrics(TQStyle::CC_TitleBar, this,
+ TQStyle::SC_TitleBarSysMenu);
+ return TQSize( menur.width(), tqstyle().tqpixelMetric( TQStyle::PM_TitleBarHeight, this ) );
+}
+
+#endif //TQT_NO_TITLEBAR
diff --git a/tqtinterface/qt4/src/widgets/tqtitlebar_p.h b/tqtinterface/qt4/src/widgets/tqtitlebar_p.h
new file mode 100644
index 0000000..44cac81
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtitlebar_p.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Definition of some TQt private functions.
+**
+** Created : 000101
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTITLEBAR_P_H
+#define TQTITLEBAR_P_H
+
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of qworkspace.cpp and qdockwindow.cpp. This header file may change
+// from version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+
+#ifndef TQT_H
+#include "tqbutton.h"
+#include "tqlabel.h"
+#endif // TQT_H
+
+#if !defined(TQT_NO_TITLEBAR)
+
+class TQToolTip;
+class TQTitleBarPrivate;
+class TQPixmap;
+
+class TQ_EXPORT TQTitleBar : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool autoRaise READ autoRaise WRITE setAutoRaise )
+ Q_PROPERTY( bool movable READ isMovable WRITE setMovable )
+
+public:
+ TQTitleBar (TQWidget* w, TQWidget* tqparent, const char* name=0);
+ ~TQTitleBar();
+
+ bool isActive() const;
+ bool usesActiveColor() const;
+ virtual TQString visibleText() const;
+
+ bool isMovable() const;
+ void setMovable(bool);
+
+ bool autoRaise() const;
+ void setAutoRaise(bool);
+
+ TQWidget *window() const;
+
+ TQSize tqsizeHint() const;
+
+#ifdef TQT_NO_WIDGET_TOPEXTRA
+ // We provide one, since titlebar is useless otherwise.
+ TQString caption() const;
+#endif
+
+public Q_SLOTS:
+ void setActive( bool );
+ void setCaption( const TQString& title );
+ void setIcon( const TQPixmap& icon );
+
+Q_SIGNALS:
+ void doActivate();
+ void doNormal();
+ void doClose();
+ void doMaximize();
+ void doMinimize();
+ void doShade();
+ void showOperationMenu();
+ void popupOperationMenu( const TQPoint& );
+ void doubleClicked();
+
+protected:
+ bool event( TQEvent *);
+ void resizeEvent( TQResizeEvent *);
+ void contextMenuEvent( TQContextMenuEvent * );
+ void mousePressEvent( TQMouseEvent * );
+ void mouseDoubleClickEvent( TQMouseEvent * );
+ void mouseReleaseEvent( TQMouseEvent * );
+ void mouseMoveEvent( TQMouseEvent * );
+ void enterEvent( TQEvent *e );
+ void leaveEvent( TQEvent *e );
+ void paintEvent( TQPaintEvent *p );
+
+ virtual void cutText();
+
+private:
+ void readColors();
+
+ TQTitleBarPrivate *d;
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQTitleBar( const TQTitleBar & );
+ TQTitleBar &operator=( const TQTitleBar & );
+#endif
+};
+
+#endif
+#endif //TQTITLEBAR_P_H
diff --git a/tqtinterface/qt4/src/widgets/tqtoolbar.cpp b/tqtinterface/qt4/src/widgets/tqtoolbar.cpp
new file mode 100644
index 0000000..0701c6a
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtoolbar.cpp
@@ -0,0 +1,818 @@
+/****************************************************************************
+**
+** Implementation of TQToolBar class
+**
+** Created : 980315
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtoolbar.h"
+#ifndef TQT_NO_TOOLBAR
+
+#include "tqmainwindow.h"
+#include "tqtooltip.h"
+#include "tqcursor.h"
+#include "tqlayout.h"
+#include "tqframe.h"
+#include "tqobjectlist.h"
+#include "tqpainter.h"
+#include "tqdrawutil.h"
+#include "tqtoolbutton.h"
+#include "tqpopupmenu.h"
+#include "tqcombobox.h"
+#include "tqtimer.h"
+#include "tqwidgetlist.h"
+#include "tqstyle.h"
+#include "tqapplication.h"
+
+static const char * const arrow_v_xpm[] = {
+ "7 9 3 1",
+ " c None",
+ ". c #000000",
+ "+ c none",
+ ".+++++.",
+ "..+++..",
+ "+..+..+",
+ "++...++",
+ ".++.++.",
+ "..+++..",
+ "+..+..+",
+ "++...++",
+ "+++.+++"};
+
+static const char * const arrow_h_xpm[] = {
+ "9 7 3 1",
+ " c None",
+ ". c #000000",
+ "+ c none",
+ "..++..+++",
+ "+..++..++",
+ "++..++..+",
+ "+++..++..",
+ "++..++..+",
+ "+..++..++",
+ "..++..+++"};
+
+class TQToolBarExtensionWidget;
+
+class TQToolBarPrivate
+{
+public:
+ TQToolBarPrivate() : moving( FALSE ) {
+ }
+
+ bool moving;
+ TQToolBarExtensionWidget *extension;
+ TQPopupMenu *extensionPopup;
+};
+
+
+class TQToolBarSeparator : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQToolBarSeparator( Qt::Orientation, TQToolBar *tqparent, const char* name=0 );
+
+ TQSize tqsizeHint() const;
+ Qt::Orientation orientation() const { return orient; }
+public Q_SLOTS:
+ void setOrientation( Qt::Orientation );
+protected:
+ void styleChange( TQStyle& );
+ void paintEvent( TQPaintEvent * );
+
+private:
+ Qt::Orientation orient;
+};
+
+class TQToolBarExtensionWidget : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQToolBarExtensionWidget( TQWidget *w );
+ void setOrientation( Qt::Orientation o );
+ TQToolButton *button() const { return tb; }
+
+protected:
+ void resizeEvent( TQResizeEvent *e ) {
+ TQWidget::resizeEvent( e );
+ layOut();
+ }
+
+private:
+ void layOut();
+ TQToolButton *tb;
+ Qt::Orientation orient;
+
+};
+
+TQToolBarExtensionWidget::TQToolBarExtensionWidget( TQWidget *w )
+ : TQWidget( w, "qt_dockwidget_internal" )
+{
+ tb = new TQToolButton( this, "qt_toolbar_ext_button" );
+ tb->setAutoRaise( TRUE );
+ setOrientation( Qt::Horizontal );
+}
+
+void TQToolBarExtensionWidget::setOrientation( Qt::Orientation o )
+{
+ orient = o;
+ if ( orient == Qt::Horizontal )
+ tb->setPixmap( TQPixmap( (const char **)arrow_h_xpm ) );
+ else
+ tb->setPixmap( TQPixmap( (const char **)arrow_v_xpm ) );
+ layOut();
+}
+
+void TQToolBarExtensionWidget::layOut()
+{
+ tb->setGeometry( 2, 2, width() - 4, height() - 4 );
+}
+
+TQToolBarSeparator::TQToolBarSeparator(Qt::Orientation o , TQToolBar *tqparent,
+ const char* name )
+ : TQWidget( tqparent, name )
+{
+ connect( tqparent, TQT_SIGNAL(orientationChanged(Qt::Orientation)),
+ this, TQT_SLOT(setOrientation(Qt::Orientation)) );
+ setOrientation( o );
+ setBackgroundMode( tqparent->backgroundMode() );
+ setBackgroundOrigin( ParentOrigin );
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Minimum ) );
+}
+
+
+
+void TQToolBarSeparator::setOrientation( Qt::Orientation o )
+{
+ orient = o;
+}
+
+void TQToolBarSeparator::styleChange( TQStyle& )
+{
+ setOrientation( orient );
+}
+
+TQSize TQToolBarSeparator::tqsizeHint() const
+{
+ int extent = tqstyle().tqpixelMetric( TQStyle::PM_DockWindowSeparatorExtent,
+ this );
+ if ( orient == Qt::Horizontal )
+ return TQSize( extent, 0 );
+ else
+ return TQSize( 0, extent );
+}
+
+void TQToolBarSeparator::paintEvent( TQPaintEvent * )
+{
+ TQPainter p( this );
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+
+ if ( orientation() == Qt::Horizontal )
+ flags |= TQStyle::Style_Horizontal;
+
+ tqstyle().tqdrawPrimitive( TQStyle::PE_DockWindowSeparator, &p, rect(),
+ tqcolorGroup(), flags );
+}
+
+#include "tqtoolbar.tqmoc"
+
+
+/*!
+ \class TQToolBar tqtoolbar.h
+ \brief The TQToolBar class provides a movable panel containing
+ widgets such as tool buttons.
+
+ \ingroup application
+ \mainclass
+
+ A toolbar is a panel that tqcontains a set of controls, usually
+ represented by small icons. It's purpose is to provide quick
+ access to frequently used commands or options. Within a
+ TQMainWindow the user can drag toolbars within and between the
+ \link TQDockArea dock areas\endlink. Toolbars can also be dragged
+ out of any dock area to float freely as top-level windows.
+
+ TQToolBar is a specialization of TQDockWindow, and so provides all
+ the functionality of a TQDockWindow.
+
+ To use TQToolBar you simply create a TQToolBar as a child of a
+ TQMainWindow, create a number of TQToolButton widgets (or other
+ widgets) in left to right (or top to bottom) order and call
+ addSeparator() when you want a separator. When a toolbar is
+ floated the caption used is the label given in the constructor
+ call. This can be changed with setLabel().
+
+ \quotefile action/application.cpp
+ \skipto new TQToolBar
+ \printuntil fileSaveAction
+
+ This extract from the \l application/application.cpp example shows
+ the creation of a new toolbar as a child of a TQMainWindow and
+ adding two TQActions.
+
+ You may use most widgets within a toolbar, with TQToolButton and
+ TQComboBox being the most common.
+
+ If you create a new widget on an already visible TQToolBar, this
+ widget will automatically become visible without needing a show()
+ call. (This differs from every other TQt widget container. We
+ recommend calling show() anyway since we hope to fix this anomaly
+ in a future release.)
+
+ TQToolBars, like TQDockWindows, are located in \l{TQDockArea}s or
+ float as top-level windows. TQMainWindow provides four TQDockAreas
+ (top, left, right and bottom). When you create a new toolbar (as
+ in the example above) as a child of a TQMainWindow the toolbar will
+ be added to the top dock area. You can move it to another dock
+ area (or float it) by calling TQMainWindow::moveDockWindow(). TQDock
+ areas lay out their windows in \link tqdockarea.html#lines
+ Lines\endlink.
+
+ If the main window is resized so that the area occupied by the
+ toolbar is too small to show all its widgets a little arrow button
+ (which looks like a right-pointing chevron, '&#187;') will appear
+ at the right or bottom of the toolbar depending on its
+ orientation. Clicking this button pops up a menu that shows the
+ 'overflowing' items. TQToolButtons are represented in the menu using
+ their textLabel property, other TQButton subclasses are represented
+ using their text property, and TQComboBoxes are represented as submenus,
+ with the caption text being used in the submenu item.
+
+ Usually a toolbar will get precisely the space it needs. However,
+ with setHorizontalStretchable(), setVerticalStretchable() or
+ setStretchableWidget() you can tell the main window to expand the
+ toolbar to fill all available space in the specified orientation.
+
+ The toolbar arranges its buttons either horizontally or vertically
+ (see orientation() for details). Generally, TQDockArea will set the
+ orientation correctly for you, but you can set it yourself with
+ setOrientation() and track any changes by connecting to the
+ orientationChanged() signal.
+
+ You can use the clear() method to remove all items from a toolbar.
+
+ \img qdockwindow.png Toolbar (dock window)
+ \caption A floating TQToolbar (dock window)
+
+ \sa TQToolButton TQMainWindow \link http://www.iarchitect.com/visual.htm Parts of Isys on Visual Design\endlink \link guibooks.html#fowler GUI Design Handbook: Tool Bar\endlink.
+*/
+
+/*!
+ \fn TQToolBar::TQToolBar( const TQString &label,
+ TQMainWindow *, ToolBarDock = Top,
+ bool newLine = FALSE, const char * name = 0 );
+ \obsolete
+*/
+
+/*!
+ Constructs an empty toolbar.
+
+ The toolbar is called \a name and is a child of \a tqparent and is
+ managed by \a tqparent. It is initially located in dock area \a dock
+ and is labeled \a label. If \a newLine is TRUE the toolbar will be
+ placed on a new line in the dock area.
+*/
+
+TQToolBar::TQToolBar( const TQString &label,
+ TQMainWindow * tqparent, TQt::ToolBarDock dock,
+ bool newLine, const char * name )
+ : TQDockWindow( InDock, tqparent, name, 0, TRUE )
+{
+ mw = tqparent;
+ init();
+
+ if ( tqparent )
+ tqparent->addToolBar( this, label, dock, newLine );
+}
+
+
+/*!
+ Constructs an empty horizontal toolbar.
+
+ The toolbar is called \a name and is a child of \a tqparent and is
+ managed by \a mainWindow. The \a label and \a newLine parameters
+ are passed straight to TQMainWindow::addDockWindow(). \a name and
+ the widget flags \a f are passed on to the TQDockWindow constructor.
+
+ Use this constructor if you want to create torn-off (undocked,
+ floating) toolbars or toolbars in the \link TQStatusBar status
+ bar\endlink.
+*/
+
+TQToolBar::TQToolBar( const TQString &label, TQMainWindow * mainWindow,
+ TQWidget * tqparent, bool newLine, const char * name,
+ WFlags f )
+ : TQDockWindow( InDock, tqparent, name, f, TRUE )
+{
+ mw = mainWindow;
+ init();
+
+ clearWFlags( (WFlags)(TQt::WType_Dialog | WStyle_Customize | TQt::WStyle_NoBorder) );
+ reparent( tqparent, TQPoint( 0, 0 ), FALSE );
+
+ if ( mainWindow )
+ mainWindow->addToolBar( this, label, TQt::DockUnmanaged, newLine );
+}
+
+
+/*!
+ \overload
+
+ Constructs an empty toolbar called \a name, with tqparent \a tqparent,
+ in its \a tqparent's top dock area, without any label and without
+ requiring a newline.
+*/
+
+TQToolBar::TQToolBar( TQMainWindow * tqparent, const char * name )
+ : TQDockWindow( InDock, tqparent, name, 0, TRUE )
+{
+ mw = tqparent;
+ init();
+
+ if ( tqparent )
+ tqparent->addToolBar( this, TQString(), TQt::DockTop );
+}
+
+/*!
+ \internal
+
+ Common initialization code. Requires that \c mw and \c o are set.
+ Does not call TQMainWindow::addDockWindow().
+*/
+void TQToolBar::init()
+{
+ d = new TQToolBarPrivate;
+ d->extension = 0;
+ d->extensionPopup = 0;
+ sw = 0;
+
+ setBackgroundMode( TQt::PaletteButton);
+ setFocusPolicy( Qt::NoFocus );
+ setFrameStyle( TQFrame::ToolBarPanel | TQFrame::Raised);
+ boxLayout()->setSpacing(tqstyle().tqpixelMetric(TQStyle::PM_ToolBarItemSpacing));
+}
+
+/*!
+ \reimp
+*/
+
+TQToolBar::~TQToolBar()
+{
+ delete d;
+ d = 0;
+}
+
+/*!
+ \reimp
+*/
+
+void TQToolBar::setOrientation( Qt::Orientation o )
+{
+ TQDockWindow::setOrientation( o );
+ if (d->extension)
+ d->extension->setOrientation( o );
+ TQObjectList *childs = queryList( "TQToolBarSeparator" );
+ if ( childs ) {
+ TQObject *ob = 0;
+ for ( ob = childs->first(); ob; ob = childs->next() ) {
+ TQToolBarSeparator* w = (TQToolBarSeparator*)ob;
+ w->setOrientation( o );
+ }
+ }
+ delete childs;
+}
+
+/*!
+ Adds a separator to the right/bottom of the toolbar.
+*/
+
+void TQToolBar::addSeparator()
+{
+ (void) new TQToolBarSeparator( orientation(), this, "toolbar separator" );
+}
+
+/*!
+ \reimp
+*/
+
+void TQToolBar::styleChange( TQStyle& )
+{
+ TQObjectList *childs = queryList( "TQWidget" );
+ if ( childs ) {
+ TQObject *ob = 0;
+ for ( ob = childs->first(); ob; ob = childs->next() ) {
+ TQWidget *w = (TQWidget*)ob;
+ if ( ::tqqt_cast<TQToolButton*>(w) || ::tqqt_cast<TQToolBarSeparator*>(w) )
+ w->setStyle( &tqstyle() );
+ }
+ }
+ delete childs;
+ boxLayout()->setSpacing(tqstyle().tqpixelMetric(TQStyle::PM_ToolBarItemSpacing));
+}
+
+/*!
+ \reimp.
+*/
+
+void TQToolBar::show()
+{
+ TQDockWindow::show();
+ if ( mw )
+ mw->triggerLayout( FALSE );
+ checkForExtension( size() );
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQToolBar::hide()
+{
+ TQDockWindow::hide();
+ if ( mw )
+ mw->triggerLayout( FALSE );
+}
+
+/*!
+ Returns a pointer to the TQMainWindow which manages this toolbar.
+*/
+
+TQMainWindow * TQToolBar::mainWindow() const
+{
+ return mw;
+}
+
+
+/*!
+ Sets the widget \a w to be expanded if this toolbar is requested
+ to stretch.
+
+ The request to stretch might occur because TQMainWindow
+ right-justifies the dock area the toolbar is in, or because this
+ toolbar's isVerticalStretchable() or isHorizontalStretchable() is
+ set to TRUE.
+
+ If you call this function and the toolbar is not yet stretchable,
+ setStretchable() is called.
+
+ \sa TQMainWindow::setRightJustification(), setVerticalStretchable(),
+ setHorizontalStretchable()
+*/
+
+void TQToolBar::setStretchableWidget( TQWidget * w )
+{
+ sw = w;
+ boxLayout()->setStretchFactor( w, 1 );
+
+ if ( !isHorizontalStretchable() && !isVerticalStretchable() ) {
+ if ( orientation() == Qt::Horizontal )
+ setHorizontalStretchable( TRUE );
+ else
+ setVerticalStretchable( TRUE );
+ }
+}
+
+
+/*!
+ \reimp
+*/
+
+bool TQToolBar::event( TQEvent * e )
+{
+ bool r = TQDockWindow::event( e );
+ // After the event filters have dealt with it, do our stuff.
+ if ( e->type() == TQEvent::ChildInserted ) {
+ TQObject * child = TQT_TQOBJECT(((TQChildEvent*)e)->child());
+ if ( child && child->isWidgetType() && !(TQT_TQWIDGET(child)->isTopLevel())
+ && TQT_BASE_OBJECT(child->tqparent()) == TQT_BASE_OBJECT(this)
+ && tqstrcmp("qt_dockwidget_internal", child->name()) != 0 ) {
+ boxLayout()->addWidget( (TQWidget*)child );
+ if ( isVisible() ) {
+ if ( TQT_TQWIDGET(child)->testWState( TQt::WState_CreatedHidden ) )
+ TQT_TQWIDGET(child)->show();
+ checkForExtension( size() );
+ }
+ }
+ if ( child && child->isWidgetType() && TQT_BASE_OBJECT(child) == TQT_BASE_OBJECT(sw) )
+ boxLayout()->setStretchFactor( TQT_TQWIDGET(child), 1 );
+ } else if ( e->type() == TQEvent::Show ) {
+ tqlayout()->activate();
+ } else if ( e->type() == TQEvent::LayoutHint && place() == OutsideDock ) {
+ adjustSize();
+ }
+ return r;
+}
+
+
+/*!
+ \property TQToolBar::label
+ \brief the toolbar's label.
+
+ If the toolbar is floated the label becomes the toolbar window's
+ caption. There is no default label text.
+*/
+
+void TQToolBar::setLabel( const TQString & label )
+{
+ l = label;
+ setCaption( l );
+}
+
+TQString TQToolBar::label() const
+{
+ return l;
+}
+
+
+/*!
+ Deletes all the toolbar's child widgets.
+*/
+
+void TQToolBar::clear()
+{
+ if ( childrenListObject().isEmpty() )
+ return;
+ TQObjectListIt it( childrenListObject() );
+ TQObject * obj;
+ while( (obj=it.current()) != 0 ) {
+ ++it;
+ if ( obj->isWidgetType() &&
+ qstrcmp( "qt_dockwidget_internal", obj->name() ) != 0 )
+ delete obj;
+ }
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQToolBar::tqminimumSize() const
+{
+ if ( orientation() == Qt::Horizontal )
+ return TQSize( 0, TQDockWindow::tqminimumSize().height() );
+ return TQSize( TQDockWindow::tqminimumSize().width(), 0 );
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQToolBar::tqminimumSizeHint() const
+{
+ if ( orientation() == Qt::Horizontal )
+ return TQSize( 0, TQDockWindow::tqminimumSizeHint().height() );
+ return TQSize( TQDockWindow::tqminimumSizeHint().width(), 0 );
+}
+
+void TQToolBar::createPopup()
+{
+ if (!d->extensionPopup) {
+ d->extensionPopup = new TQPopupMenu( this, "qt_dockwidget_internal" );
+ connect( d->extensionPopup, TQT_SIGNAL( aboutToShow() ), this, TQT_SLOT( createPopup() ) );
+ }
+
+ if (!d->extension) {
+ d->extension = new TQToolBarExtensionWidget( this );
+ d->extension->setOrientation(orientation());
+ d->extension->button()->setPopup( d->extensionPopup );
+ d->extension->button()->setPopupDelay( -1 );
+ }
+
+ d->extensionPopup->clear();
+ // clear doesn't delete submenus, so do this explicitly
+ TQObjectList *childlist = d->extensionPopup->queryList( "TQPopupMenu", 0, FALSE, TRUE );
+ childlist->setAutoDelete(TRUE);
+ delete childlist;
+
+ childlist = queryList( "TQWidget", 0, FALSE, TRUE );
+ TQObjectListIt it( *childlist );
+ bool hide = FALSE;
+ bool doHide = FALSE;
+ int id;
+ while ( it.current() ) {
+ int j = 2;
+ if ( !it.current()->isWidgetType() || TQT_BASE_OBJECT(it.current()) == TQT_BASE_OBJECT(d->extension->button()) ||
+ qstrcmp( "qt_dockwidget_internal", it.current()->name() ) == 0 ) {
+ ++it;
+ continue;
+ }
+ TQWidget *w = (TQWidget*)it.current();
+#ifndef TQT_NO_COMBOBOX
+ if ( ::tqqt_cast<TQComboBox*>(w) )
+ j = 1;
+#endif
+ hide = FALSE;
+ TQPoint p = w->parentWidget()->mapTo( this, w->tqgeometry().bottomRight() );
+ if ( orientation() == Qt::Horizontal ) {
+ if ( p.x() > ( doHide ? width() - d->extension->width() / j : width() ) )
+ hide = TRUE;
+ } else {
+ if ( p.y() > ( doHide ? height()- d->extension->height() / j : height() ) )
+ hide = TRUE;
+ }
+ if ( hide && w->isVisible() ) {
+ doHide = TRUE;
+ if ( ::tqqt_cast<TQToolButton*>(w) ) {
+ TQToolButton *b = (TQToolButton*)w;
+ TQString s = b->textLabel();
+ if ( s.isEmpty() )
+ s = b->text();
+ if ( b->popup() && b->popupDelay() <= 0 )
+ id = d->extensionPopup->insertItem( b->iconSet(), s, b->popup() );
+ else
+ id = d->extensionPopup->insertItem( b->iconSet(), s, TQT_TQOBJECT(b), TQT_SLOT( emulateClick() ) ) ;
+ if ( b->isToggleButton() )
+ d->extensionPopup->setItemChecked( id, b->isOn() );
+ if ( !b->isEnabled() )
+ d->extensionPopup->setItemEnabled( id, FALSE );
+ } else if ( ::tqqt_cast<TQButton*>(w) ) {
+ TQButton *b = (TQButton*)w;
+ TQString s = b->text();
+ if ( s.isEmpty() )
+ s = "";
+ if ( b->pixmap() )
+ id = d->extensionPopup->insertItem( *b->pixmap(), s, TQT_TQOBJECT(b), TQT_SLOT( emulateClick() ) );
+ else
+ id = d->extensionPopup->insertItem( s, TQT_TQOBJECT(b), TQT_SLOT( emulateClick() ) );
+ if ( b->isToggleButton() )
+ d->extensionPopup->setItemChecked( id, b->isOn() );
+ if ( !b->isEnabled() )
+ d->extensionPopup->setItemEnabled( id, FALSE );
+#ifndef TQT_NO_COMBOBOX
+ } else if ( ::tqqt_cast<TQComboBox*>(w) ) {
+ TQComboBox *c = (TQComboBox*)w;
+ if ( c->count() != 0 ) {
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ TQString s = c->caption();
+#else
+ TQString s;
+#endif
+ if ( s.isEmpty() )
+ s = c->currentText();
+ uint maxItems = 0;
+ TQPopupMenu *cp = new TQPopupMenu(d->extensionPopup);
+ cp->setEnabled(c->isEnabled());
+ d->extensionPopup->insertItem( s, cp );
+ connect( cp, TQT_SIGNAL( activated(int) ), c, TQT_SLOT( internalActivate(int) ) );
+ for ( int i = 0; i < c->count(); ++i ) {
+ TQString tmp = c->text( i );
+ cp->insertItem( tmp, i );
+ if ( c->currentText() == tmp )
+ cp->setItemChecked( i, TRUE );
+ if ( !maxItems ) {
+ if ( cp->count() == 10 ) {
+ int h = cp->tqsizeHint().height();
+ maxItems = TQApplication::desktop()->height() * 10 / h;
+ }
+ } else if ( cp->count() >= maxItems - 1 ) {
+ TQPopupMenu* sp = new TQPopupMenu(d->extensionPopup);
+ cp->insertItem( tr( "More..." ), sp );
+ cp = sp;
+ connect( cp, TQT_SIGNAL( activated(int) ), c, TQT_SLOT( internalActivate(int) ) );
+ }
+ }
+ }
+#endif //TQT_NO_COMBOBOX
+ }
+ }
+ ++it;
+ }
+ delete childlist;
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQToolBar::resizeEvent( TQResizeEvent *e )
+{
+ checkForExtension( e->size() );
+}
+
+void TQToolBar::checkForExtension( const TQSize &sz )
+{
+ if (!isVisible())
+ return;
+
+ bool tooSmall;
+ if ( orientation() == Qt::Horizontal )
+ tooSmall = sz.width() < tqsizeHint().width();
+ else
+ tooSmall = sz.height() < tqsizeHint().height();
+
+ if ( tooSmall ) {
+ createPopup();
+ if ( d->extensionPopup->count() ) {
+ if ( orientation() == Qt::Horizontal )
+ d->extension->setGeometry( width() - 20, 1, 20, height() - 2 );
+ else
+ d->extension->setGeometry( 1, height() - 20, width() - 2, 20 );
+ d->extension->show();
+ d->extension->raise();
+ } else {
+ delete d->extension;
+ d->extension = 0;
+ delete d->extensionPopup;
+ d->extensionPopup = 0;
+ }
+ } else {
+ delete d->extension;
+ d->extension = 0;
+ delete d->extensionPopup;
+ d->extensionPopup = 0;
+ }
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQToolBar::setMinimumSize( int, int )
+{
+}
+
+/* from chaunsee:
+
+1. Tool Bars should contain only high-frequency functions. Avoid putting
+things like About and Exit on a tool bar unless they are frequent functions.
+
+2. All tool bar buttons must have some keyboard access method (it can be a
+menu or shortcut key or a function in a dialog box that can be accessed
+through the keyboard).
+
+3. Make tool bar functions as efficient as possible (the common example is to
+Print in Microsoft applications, it doesn't bring up the Print dialog box, it
+prints immediately to the default printer).
+
+4. Avoid turning tool bars into graphical menu bars. To me, a tool bar should
+be efficient. Once you make almost all the items in a tool bar into graphical
+pull-down menus, you start to lose efficiency.
+
+5. Make sure that adjacent icons are distinctive. There are some tool bars
+where you see a group of 4-5 icons that represent related functions, but they
+are so similar that you can't differentiate among them. These tool bars are
+often a poor attempt at a "common visual language".
+
+6. Use any de facto standard icons of your platform (for windows use the
+cut, copy and paste icons provided in dev kits rather than designing your
+own).
+
+7. Avoid putting a highly destructive tool bar button (delete database) by a
+safe, high-frequency button (Find) -- this will yield 1-0ff errors).
+
+8. Tooltips in many Microsoft products simply reiterate the menu text even
+when that is not explanatory. Consider making your tooltips slightly more
+verbose and explanatory than the corresponding menu item.
+
+9. Keep the tool bar as stable as possible when you click on different
+objects. Consider disabling tool bar buttons if they are used in most, but not
+all contexts.
+
+10. If you have multiple tool bars (like the Microsoft MMC snap-ins have),
+put the most stable tool bar to at the left with less stable ones to the
+right. This arrangement (stable to less stable) makes the tool bar somewhat
+more predictable.
+
+11. Keep a single tool bar to fewer than 20 items divided into 4-7 groups of
+items.
+*/
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqtoolbar.h b/tqtinterface/qt4/src/widgets/tqtoolbar.h
new file mode 100644
index 0000000..92f6d9f
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtoolbar.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Definition of TQToolBar class
+**
+** Created : 980306
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTOOLBAR_H
+#define TQTOOLBAR_H
+
+#ifndef TQT_H
+#include "tqdockwindow.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TOOLBAR
+
+class TQMainWindow;
+class TQButton;
+class TQBoxLayout;
+class TQToolBarPrivate;
+
+class TQ_EXPORT TQToolBar: public TQDockWindow
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( TQString label READ label WRITE setLabel )
+
+public:
+ TQToolBar( const TQString &label,
+ TQMainWindow *, TQt::ToolBarDock = TQt::DockTop,
+ bool newLine = FALSE, const char* name=0 );
+ TQToolBar( const TQString &label, TQMainWindow *, TQWidget *,
+ bool newLine = FALSE, const char* name=0, WFlags f = 0 );
+ TQToolBar( TQMainWindow* tqparent=0, const char* name=0 );
+ ~TQToolBar();
+
+ void addSeparator();
+
+ virtual void show();
+ virtual void hide();
+
+ TQMainWindow * mainWindow() const;
+
+ virtual void setStretchableWidget( TQWidget * );
+
+ virtual bool event( TQEvent * e );
+
+ virtual void setLabel( const TQString & );
+ TQString label() const;
+
+ virtual void clear();
+
+ virtual TQSize tqminimumSize() const;
+ virtual TQSize tqminimumSizeHint() const;
+
+ void setOrientation( Orientation o );
+ void setMinimumSize( int minw, int minh );
+
+protected:
+ void resizeEvent( TQResizeEvent *e );
+ void styleChange( TQStyle & );
+
+private Q_SLOTS:
+ void createPopup();
+
+private:
+ void init();
+ void checkForExtension( const TQSize &sz );
+ TQToolBarPrivate * d;
+ TQMainWindow * mw;
+ TQWidget * sw;
+ TQString l;
+
+ friend class TQMainWindow;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQToolBar( const TQToolBar & );
+ TQToolBar& operator=( const TQToolBar & );
+#endif
+};
+
+#endif // TQT_NO_TOOLBAR
+
+#endif // TQTOOLBAR_H
diff --git a/tqtinterface/qt4/src/widgets/tqtoolbox.cpp b/tqtinterface/qt4/src/widgets/tqtoolbox.cpp
new file mode 100644
index 0000000..5950b1c
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtoolbox.cpp
@@ -0,0 +1,663 @@
+/****************************************************************************
+**
+** Implementation of TQToolBox widget class
+**
+** Created : 961105
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtoolbox.h"
+
+#ifndef TQT_NO_TOOLBOX
+
+#include <tqbutton.h>
+#include <tqlayout.h>
+#include <tqscrollview.h>
+#include <tqpainter.h>
+#include <tqstyle.h>
+#include <tqobjectlist.h>
+#include <tqapplication.h>
+#include <tqwidgetlist.h>
+#include <tqlayout.h>
+#include <tqvaluelist.h>
+#include <tqtooltip.h>
+#include <tqeventloop.h>
+#include <tqdatetime.h>
+
+class TQToolBoxPrivate
+{
+public:
+ struct Page
+ {
+ TQToolBoxButton *button;
+ TQScrollView *sv;
+ TQWidget *widget;
+ TQString toolTip;
+
+ inline void setTextLabel( const TQString &text ) { button->setTextLabel(text); }
+ inline void setIconSet( const TQIconSet &is ) { button->setIconSet(is); }
+ inline void setToolTip( const TQString &tip )
+ {
+ toolTip = tip;
+ TQToolTip::remove( button );
+ if ( !tip.isNull() )
+ TQToolTip::add( button, tip );
+ }
+
+ inline bool operator==(const Page& other) const
+ {
+ return widget == other.widget;
+ }
+ };
+ typedef TQValueList<Page> PageList;
+
+ inline TQToolBoxPrivate()
+ : currentPage( 0 )
+ {
+ }
+
+ Page *page( TQWidget *widget );
+ Page *page( int index );
+
+ void updateTabs();
+
+ PageList pageList;
+ TQVBoxLayout *tqlayout;
+ Page *currentPage;
+};
+
+TQToolBoxPrivate::Page *TQToolBoxPrivate::page( TQWidget *widget )
+{
+ if ( !widget )
+ return 0;
+
+ for ( PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i )
+ if ( (*i).widget == widget )
+ return (Page*) &(*i);
+ return 0;
+}
+
+TQToolBoxPrivate::Page *TQToolBoxPrivate::page( int index )
+{
+ if (index >= 0 && index < (int)pageList.size() )
+ return &*pageList.at(index);
+ return 0;
+}
+
+void TQToolBoxPrivate::updateTabs()
+{
+ TQToolBoxButton *lastButton = currentPage ? currentPage->button : 0;
+ bool after = FALSE;
+ for ( PageList::ConstIterator i = pageList.constBegin(); i != pageList.constEnd(); ++i ) {
+ if (after) {
+ (*i).button->setEraseColor((*i).widget->eraseColor());
+ (*i).button->update();
+ } else if ( (*i).button->backgroundMode() != TQt::PaletteBackground ) {
+ (*i).button->setBackgroundMode( TQt::PaletteBackground );
+ (*i).button->update();
+ }
+ after = (*i).button == lastButton;
+ }
+}
+
+TQSize TQToolBoxButton::tqsizeHint() const
+{
+ TQSize iconSize(8, 8);
+ if ( !icon.isNull() )
+ iconSize += icon.pixmap( TQIconSet::Small, TQIconSet::Normal ).size() + TQSize( 2, 0 );
+ TQSize textSize = fontMetrics().size( TQt::ShowPrefix, label ) + TQSize(0, 8);
+
+ TQSize total(iconSize.width() + textSize.width(), TQMAX(iconSize.height(), textSize.height()));
+ return total.expandedTo(TQApplication::globalStrut());
+}
+
+TQSize TQToolBoxButton::tqminimumSizeHint() const
+{
+ if ( icon.isNull() )
+ return TQSize();
+ return TQSize(8, 8) + icon.pixmap( TQIconSet::Small, TQIconSet::Normal ).size();
+}
+
+void TQToolBoxButton::drawButton( TQPainter *p )
+{
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ const TQColorGroup &cg = tqcolorGroup();
+
+ if ( isEnabled() )
+ flags |= TQStyle::Style_Enabled;
+ if ( selected )
+ flags |= TQStyle::Style_Selected;
+ if ( hasFocus() )
+ flags |= TQStyle::Style_HasFocus;
+ if (isDown())
+ flags |= TQStyle::Style_Down;
+ tqstyle().tqdrawControl( TQStyle::CE_ToolBoxTab, p, parentWidget(), rect(), cg, flags );
+
+ TQPixmap pm = icon.pixmap( TQIconSet::Small, isEnabled() ? TQIconSet::Normal : TQIconSet::Disabled );
+
+ TQRect cr = tqstyle().subRect( TQStyle::SR_ToolBoxTabContents, this );
+ TQRect tr, ir;
+ int ih = 0;
+ if ( pm.isNull() ) {
+ tr = cr;
+ tr.addCoords( 4, 0, -8, 0 );
+ } else {
+ int iw = pm.width() + 4;
+ ih = pm.height();
+ ir = TQRect( cr.left() + 4, cr.top(), iw + 2, ih );
+ tr = TQRect( ir.right(), cr.top(), cr.width() - ir.right() - 4, cr.height() );
+ }
+
+ if ( selected && tqstyle().tqstyleHint( TQStyle::SH_ToolBox_SelectedPageTitleBold ) ) {
+ TQFont f( p->font() );
+ f.setBold( TRUE );
+ p->setFont( f );
+ }
+
+ TQString txt;
+ if ( p->fontMetrics().width(label) < tr.width() ) {
+ txt = label;
+ } else {
+ txt = label.left( 1 );
+ int ew = p->fontMetrics().width( "..." );
+ int i = 1;
+ while ( p->fontMetrics().width( txt ) + ew +
+ p->fontMetrics().width( label[i] ) < tr.width() )
+ txt += label[i++];
+ txt += "...";
+ }
+
+ if ( ih )
+ p->drawPixmap( ir.left(), (height() - ih) / 2, pm );
+
+ TQToolBox *tb = (TQToolBox*)parentWidget();
+
+ const QColor* fill = 0;
+ if ( selected &&
+ tqstyle().tqstyleHint( TQStyle::SH_ToolBox_SelectedPageTitleBold ) &&
+ tb->backgroundMode() != TQt::NoBackground )
+ fill = &cg.color( TQPalette::foregroundRoleFromMode( tb->backgroundMode() ) );
+
+ int tqalignment = TQt::AlignLeft | TQt::AlignVCenter | TQt::ShowPrefix;
+ if (!tqstyle().tqstyleHint(TQStyle::SH_UnderlineAccelerator, this))
+ tqalignment |= TQt::NoAccel;
+ tqstyle().drawItem( p, tr, tqalignment, cg,
+ isEnabled(), 0, txt, -1, TQT_TQCOLOR_CONST(fill) );
+
+ if ( !txt.isEmpty() && hasFocus() )
+ tqstyle().tqdrawPrimitive( TQStyle::PE_FocusRect, p, tr, cg );
+}
+
+/*!
+ \class TQToolBox
+
+ \brief The TQToolBox class provides a column of tabbed widget
+ items.
+
+ \mainclass
+ \ingroup advanced
+
+ A toolbox is a widget that displays a column of tabs one above the
+ other, with the current item displayed below the current tab.
+ Every tab has an index position within the column of tabs. A tab's
+ item is a TQWidget.
+
+ Each item has an itemLabel(), an optional icon, itemIconSet(), an
+ optional itemToolTip(), and a \link item() widget\endlink. The
+ item's attributes can be changed with setItemLabel(),
+ setItemIconSet() and setItemToolTip().
+
+ Items are added using addItem(), or inserted at particular
+ positions using insertItem(). The total number of items is given
+ by count(). Items can be deleted with delete, or removed from the
+ toolbox with removeItem(). Combining removeItem() and insertItem()
+ allows to move items to different positions.
+
+ The current item widget is returned by currentItem() and set with
+ setCurrentItem(). If you prefer you can work in terms of indexes
+ using currentIndex(), setCurrentIndex(), indexOf() and item().
+
+ The currentChanged() signal is emitted when the current item is
+ changed.
+
+ \sa TQTabWidget
+*/
+
+/*!
+ \fn void TQToolBox::currentChanged( int index )
+
+ This signal is emitted when the current item changed. The new
+ current item's index is passed in \a index, or -1 if there is no
+ current item.
+*/
+
+/*!
+ Constructs a toolbox called \a name with tqparent \a tqparent and flags \a f.
+*/
+
+TQToolBox::TQToolBox( TQWidget *tqparent, const char *name, WFlags f )
+ : TQFrame( tqparent, name, f )
+{
+ d = new TQToolBoxPrivate;
+ d->tqlayout = new TQVBoxLayout( this );
+ TQWidget::setBackgroundMode( TQt::PaletteButton );
+}
+
+/*! \reimp */
+
+TQToolBox::~TQToolBox()
+{
+ delete d;
+}
+
+/*!
+ \fn int TQToolBox::addItem( TQWidget *w, const TQString &label )
+ \overload
+
+ Adds the widget \a w in a new tab at bottom of the toolbox. The
+ new tab's label is set to \a label. Returns the new tab's index.
+*/
+
+/*!
+ \fn int TQToolBox::addItem( TQWidget *item, const TQIconSet &iconSet,const TQString &label )
+ Adds the widget \a item in a new tab at bottom of the toolbox. The
+ new tab's label is set to \a label, and the \a iconSet is
+ displayed to the left of the \a label. Returns the new tab's index.
+*/
+
+/*!
+ \fn int TQToolBox::insertItem( int index, TQWidget *item, const TQString &label )
+ \overload
+
+ Inserts the widget \a item at position \a index, or at the bottom
+ of the toolbox if \a index is out of range. The new item's label is
+ set to \a label. Returns the new item's index.
+*/
+
+/*!
+ Inserts the widget \a item at position \a index, or at the bottom
+ of the toolbox if \a index is out of range. The new item's label
+ is set to \a label, and the \a iconSet is displayed to the left of
+ the \a label. Returns the new item's index.
+*/
+
+int TQToolBox::insertItem( int index, TQWidget *item, const TQIconSet &iconSet,
+ const TQString &label )
+{
+ if ( !item )
+ return -1;
+
+ connect(item, TQT_SIGNAL(destroyed(TQObject*)), this, TQT_SLOT(itemDestroyed(TQObject*)));
+
+ TQToolBoxPrivate::Page c;
+ c.widget = item;
+ c.button = new TQToolBoxButton( this, label.latin1() );
+ connect( c.button, TQT_SIGNAL( clicked() ), this, TQT_SLOT( buttonClicked() ) );
+
+ c.sv = new TQScrollView( this );
+ c.sv->hide();
+ c.sv->setResizePolicy( TQScrollView::AutoOneFit );
+ c.sv->addChild( item );
+ c.sv->setFrameStyle( TQFrame::NoFrame );
+
+ c.setTextLabel( label );
+ c.setIconSet( iconSet );
+
+ if ( index < 0 || index >= (int)d->pageList.count() ) {
+ index = (int)d->pageList.count();
+ d->pageList.append( c );
+ d->tqlayout->addWidget( c.button );
+ d->tqlayout->addWidget( c.sv );
+ if ( index == 0 )
+ setCurrentIndex( index );
+ } else {
+ d->pageList.insert( d->pageList.at(index), c );
+ retqlayout();
+ if (d->currentPage) {
+ TQWidget *current = d->currentPage->widget;
+ int oldindex = indexOf(current);
+ if ( index <= oldindex ) {
+ d->currentPage = 0; // trigger change
+ setCurrentIndex(oldindex);
+ }
+ }
+ }
+
+ c.button->show();
+
+ d->updateTabs();
+ itemInserted(index);
+ return index;
+}
+
+void TQToolBox::buttonClicked()
+{
+ TQToolBoxButton *tb = ::tqqt_cast<TQToolBoxButton*>(sender());
+ TQWidget* item = 0;
+ for ( TQToolBoxPrivate::PageList::ConstIterator i = d->pageList.constBegin(); i != d->pageList.constEnd(); ++i )
+ if ( (*i).button == tb ) {
+ item = (*i).widget;
+ break;
+ }
+
+ setCurrentItem( item );
+}
+
+/*!
+ \property TQToolBox::count
+ \brief The number of items contained in the toolbox.
+*/
+
+int TQToolBox::count() const
+{
+ return (int)d->pageList.count();
+}
+
+void TQToolBox::setCurrentIndex( int index )
+{
+ setCurrentItem( item( index ) );
+}
+
+/*!
+ Sets the current item to be \a item.
+*/
+
+void TQToolBox::setCurrentItem( TQWidget *item )
+{
+ TQToolBoxPrivate::Page *c = d->page( item );
+ if ( !c || d->currentPage == c )
+ return;
+
+ c->button->setSelected( TRUE );
+ if ( d->currentPage ) {
+ d->currentPage->sv->hide();
+ d->currentPage->button->setSelected(FALSE);
+ }
+ d->currentPage = c;
+ d->currentPage->sv->show();
+ d->updateTabs();
+ emit currentChanged( indexOf(item) );
+}
+
+void TQToolBox::retqlayout()
+{
+ delete d->tqlayout;
+ d->tqlayout = new TQVBoxLayout( this );
+ for ( TQToolBoxPrivate::PageList::ConstIterator i = d->pageList.constBegin(); i != d->pageList.constEnd(); ++i ) {
+ d->tqlayout->addWidget( (*i).button );
+ d->tqlayout->addWidget( (*i).sv );
+ }
+}
+
+void TQToolBox::itemDestroyed(TQObject *object)
+{
+ // no verification - vtbl corrupted already
+ TQWidget *page = (TQWidget*)object;
+
+ TQToolBoxPrivate::Page *c = d->page(page);
+ if ( !page || !c )
+ return;
+
+ d->tqlayout->remove( c->sv );
+ d->tqlayout->remove( c->button );
+ c->sv->deleteLater(); // page might still be a child of sv
+ delete c->button;
+
+ bool removeCurrent = c == d->currentPage;
+ d->pageList.remove( *c );
+
+ if ( !d->pageList.count() ) {
+ d->currentPage = 0;
+ emit currentChanged(-1);
+ } else if ( removeCurrent ) {
+ d->currentPage = 0;
+ setCurrentIndex(0);
+ }
+}
+
+/*!
+ Removes the widget \a item from the toolbox. Note that the widget
+ is \e not deleted. Returns the removed widget's index, or -1 if
+ the widget was not in this tool box.
+*/
+
+int TQToolBox::removeItem( TQWidget *item )
+{
+ int index = indexOf(item);
+ if (index >= 0) {
+ disconnect(item, TQT_SIGNAL(destroyed(TQObject*)), this, TQT_SLOT(itemDestroyed(TQObject*)));
+ item->reparent( this, TQPoint(0,0) );
+ // destroy internal data
+ itemDestroyed(TQT_TQOBJECT(item));
+ }
+ itemRemoved(index);
+ return index;
+}
+
+
+/*!
+ Returns the toolbox's current item, or 0 if the toolbox is empty.
+*/
+
+TQWidget *TQToolBox::currentItem() const
+{
+ return d->currentPage ? d->currentPage->widget : 0;
+}
+
+/*!
+ \property TQToolBox::currentIndex
+ \brief the index of the current item, or -1 if the toolbox is empty.
+ \sa currentItem(), indexOf(), item()
+*/
+
+
+int TQToolBox::currentIndex() const
+{
+ return d->currentPage ? indexOf( d->currentPage->widget ) : -1;
+}
+
+/*!
+ Returns the item at position \a index, or 0 if there is no such
+ item.
+*/
+
+TQWidget *TQToolBox::item( int index ) const
+{
+ if ( index < 0 || index >= (int) d->pageList.size() )
+ return 0;
+ return (*d->pageList.at( index )).widget;
+}
+
+/*!
+ Returns the index of item \a item, or -1 if the item does not
+ exist.
+*/
+
+int TQToolBox::indexOf( TQWidget *item ) const
+{
+ TQToolBoxPrivate::Page *c = d->page(item);
+ return c ? d->pageList.tqfindIndex( *c ) : -1;
+}
+
+/*!
+ If \a enabled is TRUE then the item at position \a index is enabled; otherwise item
+ \a index is disabled.
+*/
+
+void TQToolBox::setItemEnabled( int index, bool enabled )
+{
+ TQToolBoxPrivate::Page *c = d->page( index );
+ if ( !c )
+ return;
+
+ c->button->setEnabled( enabled );
+ if ( !enabled && c == d->currentPage ) {
+ int curIndexUp = index;
+ int curIndexDown = curIndexUp;
+ const int count = (int)d->pageList.count();
+ while ( curIndexUp > 0 || curIndexDown < count-1 ) {
+ if ( curIndexDown < count-1 ) {
+ if (d->page(++curIndexDown)->button->isEnabled()) {
+ index = curIndexDown;
+ break;
+ }
+ }
+ if ( curIndexUp > 0 ) {
+ if (d->page(--curIndexUp)->button->isEnabled()) {
+ index = curIndexUp;
+ break;
+ }
+ }
+ }
+ setCurrentIndex(index);
+ }
+}
+
+
+/*!
+ Sets the label of the item at position \a index to \a label.
+*/
+
+void TQToolBox::setItemLabel( int index, const TQString &label )
+{
+ TQToolBoxPrivate::Page *c = d->page( index );
+ if ( c )
+ c->setTextLabel( label );
+}
+
+/*!
+ Sets the icon of the item at position \a index to \a iconSet.
+*/
+
+void TQToolBox::setItemIconSet( int index, const TQIconSet &iconSet )
+{
+ TQToolBoxPrivate::Page *c = d->page( index );
+ if ( c )
+ c->setIconSet( iconSet );
+}
+
+/*!
+ Sets the tooltip of the item at position \a index to \a toolTip.
+*/
+
+void TQToolBox::setItemToolTip( int index, const TQString &toolTip )
+{
+ TQToolBoxPrivate::Page *c = d->page( index );
+ if ( c )
+ c->setToolTip( toolTip );
+}
+
+/*!
+ Returns TRUE if the item at position \a index is enabled; otherwise returns FALSE.
+*/
+
+bool TQToolBox::isItemEnabled( int index ) const
+{
+ TQToolBoxPrivate::Page *c = d->page( index );
+ return c && c->button->isEnabled();
+}
+
+/*!
+ Returns the label of the item at position \a index, or a null string if
+ \a index is out of range.
+*/
+
+TQString TQToolBox::itemLabel( int index ) const
+{
+ TQToolBoxPrivate::Page *c = d->page( index );
+ return ( c ? c->button->textLabel() : TQString::null );
+}
+
+/*!
+ Returns the icon of the item at position \a index, or a null
+ icon if \a index is out of range.
+*/
+
+TQIconSet TQToolBox::itemIconSet( int index ) const
+{
+ TQToolBoxPrivate::Page *c = d->page( index );
+ return ( c ? c->button->iconSet() : TQIconSet() );
+}
+
+/*!
+ Returns the tooltip of the item at position \a index, or a null
+ string if \a index is out of range.
+*/
+
+TQString TQToolBox::itemToolTip( int index ) const
+{
+ TQToolBoxPrivate::Page *c = d->page( index );
+ return ( c ? c->toolTip : TQString::null );
+}
+
+/*! \reimp */
+void TQToolBox::showEvent( TQShowEvent *e )
+{
+ TQWidget::showEvent( e );
+}
+
+/*! \reimp */
+void TQToolBox::frameChanged()
+{
+ d->tqlayout->setMargin( frameWidth() );
+ TQFrame::frameChanged();
+}
+
+/*! \reimp */
+void TQToolBox::styleChange(TQStyle &style)
+{
+ d->updateTabs();
+ TQFrame::styleChange(style);
+}
+
+/*!
+ This virtual handler is called after a new item was added or
+ inserted at position \a index.
+ */
+void TQToolBox::itemInserted( int index )
+{
+ TQ_UNUSED(index)
+}
+
+/*!
+ This virtual handler is called after an item was removed from
+ position \a index.
+ */
+void TQToolBox::itemRemoved( int index )
+{
+ TQ_UNUSED(index)
+}
+
+#endif //TQT_NO_TOOLBOX
diff --git a/tqtinterface/qt4/src/widgets/tqtoolbox.h b/tqtinterface/qt4/src/widgets/tqtoolbox.h
new file mode 100644
index 0000000..0ca8c38
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtoolbox.h
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Definition of TQToolBox widget class
+**
+** Created : 961105
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTOOLBOX_H
+#define TQTOOLBOX_H
+
+#ifndef TQT_H
+#include <tqframe.h>
+#include <tqiconset.h>
+#include <tqbutton.h>
+#endif // TQT_H
+
+#ifndef TQT_NO_TOOLBOX
+
+class TQToolBoxPrivate;
+class TQWidgetList;
+
+class TQ_EXPORT TQToolBox : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( int currentIndex READ currentIndex WRITE setCurrentIndex )
+ Q_PROPERTY( int count READ count )
+
+public:
+ TQToolBox( TQWidget *tqparent = 0, const char *name = 0, WFlags f = 0 );
+ ~TQToolBox();
+
+ int addItem( TQWidget *item, const TQString &label );
+ int addItem( TQWidget *item, const TQIconSet &iconSet, const TQString &label );
+ int insertItem( int index, TQWidget *item, const TQString &label );
+ int insertItem( int index, TQWidget *item, const TQIconSet &iconSet, const TQString &label );
+
+ int removeItem( TQWidget *item );
+
+ void setItemEnabled( int index, bool enabled );
+ bool isItemEnabled( int index ) const;
+
+ void setItemLabel( int index, const TQString &label );
+ TQString itemLabel( int index ) const;
+
+ void setItemIconSet( int index, const TQIconSet &iconSet );
+ TQIconSet itemIconSet( int index ) const;
+
+ void setItemToolTip( int index, const TQString &toolTip );
+ TQString itemToolTip( int index ) const;
+
+ TQWidget *currentItem() const;
+ void setCurrentItem( TQWidget *item );
+
+ int currentIndex() const;
+ TQWidget *item( int index ) const;
+ int indexOf( TQWidget *item ) const;
+ int count() const;
+
+public Q_SLOTS:
+ void setCurrentIndex( int index );
+
+Q_SIGNALS:
+ void currentChanged( int index );
+
+private Q_SLOTS:
+ void buttonClicked();
+ void itemDestroyed(TQObject*);
+
+protected:
+ virtual void itemInserted( int index );
+ virtual void itemRemoved( int index );
+ void showEvent( TQShowEvent *e );
+ void frameChanged();
+ void styleChange(TQStyle&);
+
+private:
+ void retqlayout();
+
+private:
+ TQToolBoxPrivate *d;
+
+};
+
+
+inline int TQToolBox::addItem( TQWidget *item, const TQString &label )
+{ return insertItem( -1, item, TQIconSet(), label ); }
+inline int TQToolBox::addItem( TQWidget *item, const TQIconSet &iconSet,
+ const TQString &label )
+{ return insertItem( -1, item, iconSet, label ); }
+inline int TQToolBox::insertItem( int index, TQWidget *item, const TQString &label )
+{ return insertItem( index, item, TQIconSet(), label ); }
+
+// Private-ish
+
+class TQToolBoxButton : public TQButton
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQToolBoxButton( TQWidget *tqparent, const char *name )
+ : TQButton( tqparent, name ), selected( FALSE )
+ {
+ setBackgroundMode(TQt::PaletteBackground);
+ tqsetSizePolicy(TQSizePolicy::Preferred, TQSizePolicy::Minimum);
+ setFocusPolicy(Qt::NoFocus);
+ }
+
+ inline void setSelected( bool b ) { selected = b; update(); }
+ inline void setTextLabel( const TQString &text ) { label = text; update(); }
+ inline TQString textLabel() const { return label; }
+ inline void setIconSet( const TQIconSet &is ) { icon = is; update(); }
+ inline TQIconSet iconSet() const { return icon; }
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+protected:
+ void drawButton( TQPainter * );
+
+private:
+ bool selected;
+ TQString label;
+ TQIconSet icon;
+};
+
+#endif // TQT_NO_TOOLBOX
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqtoolbutton.cpp b/tqtinterface/qt4/src/widgets/tqtoolbutton.cpp
new file mode 100644
index 0000000..2cfd962
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtoolbutton.cpp
@@ -0,0 +1,1041 @@
+/****************************************************************************
+**
+** Implementation of TQToolButton class
+**
+** Created : 980320
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#undef TQT_NO_COMPAT
+#include "tqtoolbutton.h"
+#ifndef TQT_NO_TOOLBUTTON
+
+#include "tqdrawutil.h"
+#include "tqpainter.h"
+#include "tqpixmap.h"
+#include "tqwmatrix.h"
+#include "tqapplication.h"
+#include "tqstyle.h"
+#include "tqmainwindow.h"
+#include "tqtooltip.h"
+#include "tqtoolbar.h"
+#include "tqimage.h"
+#include "tqiconset.h"
+#include "tqtimer.h"
+#include "tqpopupmenu.h"
+#include "tqguardedptr.h"
+
+class TQToolButtonPrivate
+{
+ // ### add tool tip magic here
+public:
+#ifndef TQT_NO_POPUPMENU
+ TQGuardedPtr<TQPopupMenu> popup;
+ TQTimer* popupTimer;
+ int delay;
+#endif
+ TQt::ArrowType arrow;
+ uint instantPopup : 1;
+ uint autoraise : 1;
+ uint repeat : 1;
+ uint discardNextMouseEvent : 1;
+ TQToolButton::TextPosition textPos;
+};
+
+
+/*!
+ \class TQToolButton tqtoolbutton.h
+ \brief The TQToolButton class provides a quick-access button to
+ commands or options, usually used inside a TQToolBar.
+
+ \ingroup basic
+ \mainclass
+
+ A tool button is a special button that provides quick-access to
+ specific commands or options. As opposed to a normal command
+ button, a tool button usually doesn't show a text label, but shows
+ an icon instead. Its classic usage is to select tools, for example
+ the "pen" tool in a drawing program. This would be implemented
+ with a TQToolButton as toggle button (see setToggleButton() ).
+
+ TQToolButton supports auto-raising. In auto-raise mode, the button
+ draws a 3D frame only when the mouse points at it. The feature is
+ automatically turned on when a button is used inside a TQToolBar.
+ Change it with setAutoRaise().
+
+ A tool button's icon is set as TQIconSet. This makes it possible to
+ specify different pixmaps for the disabled and active state. The
+ disabled pixmap is used when the button's functionality is not
+ available. The active pixmap is displayed when the button is
+ auto-raised because the mouse pointer is hovering over it.
+
+ The button's look and dimension is adjustable with
+ setUsesBigPixmap() and setUsesTextLabel(). When used inside a
+ TQToolBar in a TQMainWindow, the button automatically adjusts to
+ TQMainWindow's settings (see TQMainWindow::setUsesTextLabel() and
+ TQMainWindow::setUsesBigPixmaps()). The pixmap set on a TQToolButton
+ will be set to 22x22 if it is bigger than this size. If
+ usesBigPixmap() is TRUE, then the pixmap will be set to 32x32.
+
+ A tool button can offer additional choices in a popup menu. The
+ feature is sometimes used with the "Back" button in a web browser.
+ After pressing and holding the button down for a while, a menu
+ pops up showing a list of possible pages to jump to. With
+ TQToolButton you can set a popup menu using setPopup(). The default
+ delay is 600ms; you can adjust it with setPopupDelay().
+
+ \img qdockwindow.png Toolbar with Toolbuttons \caption A floating
+ TQToolbar with TQToolbuttons
+
+ \sa TQPushButton TQToolBar TQMainWindow \link guibooks.html#fowler
+ GUI Design Handbook: Push Button\endlink
+*/
+
+/*!
+ \enum TQToolButton::TextPosition
+
+ The position of the tool button's textLabel in relation to the
+ tool button's icon.
+
+ \value BesideIcon The text appears beside the icon.
+ \value BelowIcon The text appears below the icon.
+*/
+
+
+/*!
+ Constructs an empty tool button called \a name, with tqparent \a
+ tqparent.
+*/
+
+TQToolButton::TQToolButton( TQWidget * tqparent, const char *name )
+ : TQButton( tqparent, name )
+{
+ init();
+#ifndef TQT_NO_TOOLBAR
+ TQToolBar* tb = ::tqqt_cast<TQToolBar*>(tqparent);
+ if ( tb ) {
+ setAutoRaise( TRUE );
+ if ( tb->mainWindow() ) {
+ connect( tb->mainWindow(), TQT_SIGNAL(pixmapSizeChanged(bool)),
+ this, TQT_SLOT(setUsesBigPixmap(bool)) );
+ setUsesBigPixmap( tb->mainWindow()->usesBigPixmaps() );
+ connect( tb->mainWindow(), TQT_SIGNAL(usesTextLabelChanged(bool)),
+ this, TQT_SLOT(setUsesTextLabel(bool)) );
+ setUsesTextLabel( tb->mainWindow()->usesTextLabel() );
+ } else {
+ setUsesBigPixmap( FALSE );
+ }
+ } else
+#endif
+ {
+ setUsesBigPixmap( FALSE );
+ }
+}
+
+
+/*!
+ Constructs a tool button as an arrow button. The \c ArrowType \a
+ type defines the arrow direction. Possible values are \c
+ LeftArrow, \c RightArrow, \c UpArrow and \c DownArrow.
+
+ An arrow button has auto-repeat turned on by default.
+
+ The \a tqparent and \a name arguments are sent to the TQWidget
+ constructor.
+*/
+TQToolButton::TQToolButton( TQt::ArrowType type, TQWidget *tqparent, const char *name )
+ : TQButton( tqparent, name )
+{
+ init();
+ setUsesBigPixmap( FALSE );
+ setAutoRepeat( TRUE );
+ d->arrow = type;
+ hasArrow = TRUE;
+}
+
+
+/* Set-up code common to all the constructors */
+
+void TQToolButton::init()
+{
+ d = new TQToolButtonPrivate;
+ d->textPos = Under;
+#ifndef TQT_NO_POPUPMENU
+ d->delay = 600;
+ d->popup = 0;
+ d->popupTimer = 0;
+#endif
+ d->autoraise = FALSE;
+ d->arrow = TQt::LeftArrow;
+ d->instantPopup = FALSE;
+ d->discardNextMouseEvent = FALSE;
+ bpID = bp.serialNumber();
+ spID = sp.serialNumber();
+
+ utl = FALSE;
+ ubp = TRUE;
+ hasArrow = FALSE;
+
+ s = 0;
+
+ setFocusPolicy( Qt::NoFocus );
+ setBackgroundMode( TQt::PaletteButton);
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Minimum ) );
+}
+
+#ifndef TQT_NO_TOOLBAR
+
+/*!
+ Constructs a tool button called \a name, that is a child of \a
+ tqparent (which must be a TQToolBar).
+
+ The tool button will display \a iconSet, with its text label and
+ tool tip set to \a textLabel and its status bar message set to \a
+ grouptext. It will be connected to the \a slot in object \a
+ receiver.
+*/
+
+TQToolButton::TQToolButton( const TQIconSet& iconSet, const TQString &textLabel,
+ const TQString& grouptext,
+ TQT_BASE_OBJECT_NAME * receiver, const char *slot,
+ TQToolBar * tqparent, const char *name )
+ : TQButton( tqparent, name )
+{
+ init();
+ setAutoRaise( TRUE );
+ setIconSet( iconSet );
+ setTextLabel( textLabel );
+ if ( receiver && slot )
+ connect( this, TQT_SIGNAL(clicked()), receiver, slot );
+ if ( tqparent->mainWindow() ) {
+ connect( tqparent->mainWindow(), TQT_SIGNAL(pixmapSizeChanged(bool)),
+ this, TQT_SLOT(setUsesBigPixmap(bool)) );
+ setUsesBigPixmap( tqparent->mainWindow()->usesBigPixmaps() );
+ connect( tqparent->mainWindow(), TQT_SIGNAL(usesTextLabelChanged(bool)),
+ this, TQT_SLOT(setUsesTextLabel(bool)) );
+ setUsesTextLabel( tqparent->mainWindow()->usesTextLabel() );
+ } else {
+ setUsesBigPixmap( FALSE );
+ }
+#ifndef TQT_NO_TOOLTIP
+ if ( !textLabel.isEmpty() ) {
+ if ( !grouptext.isEmpty() && tqparent->mainWindow() )
+ TQToolTip::add( this, textLabel,
+ tqparent->mainWindow()->toolTipGroup(), grouptext );
+ else
+ TQToolTip::add( this, textLabel );
+ } else if ( !grouptext.isEmpty() && tqparent->mainWindow() )
+ TQToolTip::add( this, TQString::null,
+ tqparent->mainWindow()->toolTipGroup(), grouptext );
+#endif
+}
+
+#endif
+
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQToolButton::~TQToolButton()
+{
+#ifndef TQT_NO_POPUPMENU
+ d->popupTimer = 0;
+ d->popup = 0;
+#endif
+ delete d;
+ delete s;
+}
+
+
+/*!
+ \property TQToolButton::backgroundMode
+ \brief the toolbutton's background mode
+
+ Get this property with backgroundMode().
+
+ \sa TQWidget::setBackgroundMode()
+*/
+
+/*!
+ \property TQToolButton::toggleButton
+ \brief whether this tool button is a toggle button.
+
+ Toggle buttons have an on/off state similar to \link TQCheckBox
+ check boxes. \endlink A tool button is not a toggle button by
+ default.
+
+ \sa setOn(), toggle()
+*/
+
+void TQToolButton::setToggleButton( bool enable )
+{
+ TQButton::setToggleButton( enable );
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQToolButton::tqsizeHint() const
+{
+ constPolish();
+
+ int w = 0, h = 0;
+
+ if ( iconSet().isNull() && !text().isNull() && !usesTextLabel() ) {
+ w = fontMetrics().width( text() );
+ h = fontMetrics().height(); // boundingRect()?
+ } else if ( usesBigPixmap() ) {
+ TQPixmap pm = iconSet().pixmap( TQIconSet::Large, TQIconSet::Normal );
+ w = pm.width();
+ h = pm.height();
+ TQSize iconSize = TQIconSet::iconSize( TQIconSet::Large );
+ if ( w < iconSize.width() )
+ w = iconSize.width();
+ if ( h < iconSize.height() )
+ h = iconSize.height();
+ } else if ( !iconSet().isNull() ) {
+ // ### in 3.1, use TQIconSet::iconSize( TQIconSet::Small );
+ TQPixmap pm = iconSet().pixmap( TQIconSet::Small, TQIconSet::Normal );
+ w = pm.width();
+ h = pm.height();
+ if ( w < 16 )
+ w = 16;
+ if ( h < 16 )
+ h = 16;
+ }
+
+ if ( usesTextLabel() ) {
+ TQSize textSize = fontMetrics().size( TQt::ShowPrefix, textLabel() );
+ textSize.setWidth( textSize.width() + fontMetrics().width(' ')*2 );
+ if ( d->textPos == Under ) {
+ h += 4 + textSize.height();
+ if ( textSize.width() > w )
+ w = textSize.width();
+ } else { // Right
+ w += 4 + textSize.width();
+ if ( textSize.height() > h )
+ h = textSize.height();
+ }
+ }
+
+#ifndef TQT_NO_POPUPMENU
+ if ( popup() && ! popupDelay() )
+ w += tqstyle().tqpixelMetric(TQStyle::PM_MenuButtonIndicator, this);
+#endif
+ return (tqstyle().tqsizeFromContents(TQStyle::CT_ToolButton, this, TQSize(w, h)).
+ expandedTo(TQApplication::globalStrut()));
+}
+
+/*!
+ \reimp
+ */
+TQSize TQToolButton::tqminimumSizeHint() const
+{
+ return tqsizeHint();
+}
+
+/*!
+ \property TQToolButton::usesBigPixmap
+ \brief whether this toolbutton uses big pixmaps.
+
+ TQToolButton automatically connects this property to the relevant
+ signal in the TQMainWindow in which it resides. We strongly
+ recommend that you use TQMainWindow::setUsesBigPixmaps() instead.
+
+ This property's default is TRUE.
+
+ \warning If you set some buttons (in a TQMainWindow) to have big
+ pixmaps and others to have small pixmaps, TQMainWindow may not get
+ the tqgeometry right.
+*/
+
+void TQToolButton::setUsesBigPixmap( bool enable )
+{
+ if ( (bool)ubp == enable )
+ return;
+
+ ubp = enable;
+ if ( isVisible() ) {
+ update();
+ updateGeometry();
+ }
+}
+
+
+/*!
+ \property TQToolButton::usesTextLabel
+ \brief whether the toolbutton displays a text label below the button pixmap.
+
+ The default is FALSE.
+
+ TQToolButton automatically connects this slot to the relevant
+ signal in the TQMainWindow in which is resides.
+*/
+
+void TQToolButton::setUsesTextLabel( bool enable )
+{
+ if ( (bool)utl == enable )
+ return;
+
+ utl = enable;
+ if ( isVisible() ) {
+ update();
+ updateGeometry();
+ }
+}
+
+
+/*!
+ \property TQToolButton::on
+ \brief whether this tool button is on.
+
+ This property has no effect on \link isToggleButton() non-toggling
+ buttons. \endlink The default is FALSE (i.e. off).
+
+ \sa isToggleButton() toggle()
+*/
+
+void TQToolButton::setOn( bool enable )
+{
+ if ( !isToggleButton() )
+ return;
+ TQButton::setOn( enable );
+}
+
+
+/*!
+ Toggles the state of this tool button.
+
+ This function has no effect on \link isToggleButton() non-toggling
+ buttons. \endlink
+
+ \sa isToggleButton() toggled()
+*/
+
+void TQToolButton::toggle()
+{
+ if ( !isToggleButton() )
+ return;
+ TQButton::setOn( !isOn() );
+}
+
+
+/*!
+ \reimp
+*/
+void TQToolButton::drawButton( TQPainter * p )
+{
+ TQStyle::SCFlags controls = TQStyle::SC_ToolButton;
+ TQStyle::SCFlags active = TQStyle::SC_None;
+
+ TQt::ArrowType arrowtype = d->arrow;
+
+ if (isDown())
+ active |= TQStyle::SC_ToolButton;
+
+#ifndef TQT_NO_POPUPMENU
+ if (d->popup && !d->delay) {
+ controls |= TQStyle::SC_ToolButtonMenu;
+ if (d->instantPopup || isDown())
+ active |= TQStyle::SC_ToolButtonMenu;
+ }
+#endif
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+ if (isDown())
+ flags |= TQStyle::Style_Down;
+ if (isOn())
+ flags |= TQStyle::Style_On;
+ if (autoRaise()) {
+ flags |= TQStyle::Style_AutoRaise;
+ if (uses3D()) {
+ flags |= TQStyle::Style_MouseOver;
+ if (! isOn() && ! isDown())
+ flags |= TQStyle::Style_Raised;
+ }
+ } else if (! isOn() && ! isDown())
+ flags |= TQStyle::Style_Raised;
+
+ tqstyle().tqdrawComplexControl(TQStyle::CC_ToolButton, p, this, rect(), tqcolorGroup(),
+ flags, controls, active,
+ hasArrow ? TQStyleOption(arrowtype) :
+ TQStyleOption());
+ drawButtonLabel(p);
+}
+
+
+/*!
+ \reimp
+*/
+void TQToolButton::drawButtonLabel(TQPainter *p)
+{
+ TQRect r =
+ TQStyle::tqvisualRect(tqstyle().subRect(TQStyle::SR_ToolButtonContents, this), this);
+
+ TQt::ArrowType arrowtype = d->arrow;
+
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ if (isEnabled())
+ flags |= TQStyle::Style_Enabled;
+ if (hasFocus())
+ flags |= TQStyle::Style_HasFocus;
+ if (isDown())
+ flags |= TQStyle::Style_Down;
+ if (isOn())
+ flags |= TQStyle::Style_On;
+ if (autoRaise()) {
+ flags |= TQStyle::Style_AutoRaise;
+ if (uses3D()) {
+ flags |= TQStyle::Style_MouseOver;
+ if (! isOn() && ! isDown())
+ flags |= TQStyle::Style_Raised;
+ }
+ } else if (! isOn() && ! isDown())
+ flags |= TQStyle::Style_Raised;
+
+ tqstyle().tqdrawControl(TQStyle::CE_ToolButtonLabel, p, this, r,
+ tqcolorGroup(), flags,
+ hasArrow ? TQStyleOption(arrowtype) :
+ TQStyleOption());
+}
+
+
+/*!
+ \reimp
+ */
+void TQToolButton::enterEvent( TQEvent * e )
+{
+ if ( autoRaise() && isEnabled() )
+ tqrepaint(FALSE);
+
+ TQButton::enterEvent( e );
+}
+
+
+/*!
+ \reimp
+ */
+void TQToolButton::leaveEvent( TQEvent * e )
+{
+ if ( autoRaise() && isEnabled() )
+ tqrepaint(FALSE);
+
+ TQButton::leaveEvent( e );
+}
+
+/*!
+ \reimp
+ */
+void TQToolButton::moveEvent( TQMoveEvent * )
+{
+ // Reimplemented to handle pseudo transparency in case the toolbars
+ // has a fancy pixmap background.
+ if ( parentWidget() && parentWidget()->backgroundPixmap() &&
+ autoRaise() && !uses3D() )
+ tqrepaint( FALSE );
+}
+
+/*!
+ \reimp
+*/
+void TQToolButton::mousePressEvent( TQMouseEvent *e )
+{
+ TQRect popupr =
+ TQStyle::tqvisualRect( tqstyle().querySubControlMetrics(TQStyle::CC_ToolButton, this,
+ TQStyle::SC_ToolButtonMenu), this );
+ d->instantPopup = (popupr.isValid() && popupr.tqcontains(e->pos()));
+
+#ifndef TQT_NO_POPUPMENU
+ if ( d->discardNextMouseEvent ) {
+ d->discardNextMouseEvent = FALSE;
+ d->instantPopup = FALSE;
+ d->popup->removeEventFilter( this );
+ return;
+ }
+ if ( e->button() == Qt::LeftButton && d->delay <= 0 && d->popup && d->instantPopup && !d->popup->isVisible() ) {
+ openPopup();
+ return;
+ }
+#endif
+
+ d->instantPopup = FALSE;
+ TQButton::mousePressEvent( e );
+}
+
+/*!
+ \reimp
+*/
+bool TQToolButton::eventFilter( TQObject *o, TQEvent *e )
+{
+#ifndef TQT_NO_POPUPMENU
+ if ( TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(d->popup) )
+ return TQButton::eventFilter( o, e );
+ switch ( e->type() ) {
+ case TQEvent::MouseButtonPress:
+ case TQEvent::MouseButtonDblClick:
+ {
+ TQMouseEvent *me = (TQMouseEvent*)e;
+ TQPoint p = me->globalPos();
+ if ( TQApplication::widgetAt( p, TRUE ) == this )
+ d->discardNextMouseEvent = TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+#endif
+ return TQButton::eventFilter( o, e );
+}
+
+/*!
+ Returns TRUE if this button should be drawn using raised edges;
+ otherwise returns FALSE.
+
+ \sa drawButton()
+*/
+
+bool TQToolButton::uses3D() const
+{
+ return tqstyle().tqstyleHint(TQStyle::SH_ToolButton_Uses3D)
+ && (!autoRaise() || ( hasMouse() && isEnabled() )
+#ifndef TQT_NO_POPUPMENU
+ || ( d->popup && d->popup->isVisible() && d->delay <= 0 ) || d->instantPopup
+#endif
+ );
+}
+
+
+/*!
+ \property TQToolButton::textLabel
+ \brief the label of this button.
+
+ Setting this property automatically sets the text as a tool tip
+ too. There is no default text.
+*/
+
+void TQToolButton::setTextLabel( const TQString &newLabel )
+{
+ setTextLabel( newLabel, TRUE );
+}
+
+/*!
+ \overload
+
+ Sets the label of this button to \a newLabel and automatically
+ sets it as a tool tip if \a tipToo is TRUE.
+*/
+
+void TQToolButton::setTextLabel( const TQString &newLabel , bool tipToo )
+{
+ if ( tl == newLabel )
+ return;
+
+#ifndef TQT_NO_TOOLTIP
+ if ( tipToo ) {
+ TQToolTip::remove( this );
+ TQToolTip::add( this, newLabel );
+ }
+#endif
+
+ tl = newLabel;
+ if ( usesTextLabel() && isVisible() ) {
+ update();
+ updateGeometry();
+ }
+
+}
+
+#ifndef TQT_NO_COMPAT
+
+TQIconSet TQToolButton::onIconSet() const
+{
+ return iconSet();
+}
+
+TQIconSet TQToolButton::offIconSet( ) const
+{
+ return iconSet();
+}
+
+
+/*!
+ \property TQToolButton::onIconSet
+ \brief the icon set that is used when the button is in an "on" state
+
+ \obsolete
+
+ Since TQt 3.0, TQIconSet tqcontains both the On and Off icons. There is
+ now an \l TQToolButton::iconSet property that tqreplaces both \l
+ TQToolButton::onIconSet and \l TQToolButton::offIconSet.
+
+ For ease of porting, this property is a synonym for \l
+ TQToolButton::iconSet. You probably want to go over your application
+ code and use the TQIconSet On/Off mechanism.
+
+ \sa iconSet TQIconSet::State
+*/
+void TQToolButton::setOnIconSet( const TQIconSet& set )
+{
+ setIconSet( set );
+ /*
+ ### Get rid of all qWarning in this file in 4.0.
+ Also consider inlining the obsolete functions then.
+ */
+ qWarning( "TQToolButton::setOnIconSet(): This function is not supported"
+ " anymore" );
+}
+
+/*!
+ \property TQToolButton::offIconSet
+ \brief the icon set that is used when the button is in an "off" state
+
+ \obsolete
+
+ Since TQt 3.0, TQIconSet tqcontains both the On and Off icons. There is
+ now an \l TQToolButton::iconSet property that tqreplaces both \l
+ TQToolButton::onIconSet and \l TQToolButton::offIconSet.
+
+ For ease of porting, this property is a synonym for \l
+ TQToolButton::iconSet. You probably want to go over your application
+ code and use the TQIconSet On/Off mechanism.
+
+ \sa iconSet TQIconSet::State
+*/
+void TQToolButton::setOffIconSet( const TQIconSet& set )
+{
+ setIconSet( set );
+}
+
+#endif
+
+/*! \property TQToolButton::pixmap
+ \brief the pixmap of the button
+
+ The pixmap property has no meaning for tool buttons. Use the
+ iconSet property instead.
+*/
+
+/*!
+ \property TQToolButton::iconSet
+ \brief the icon set providing the icon shown on the button
+
+ Setting this property sets \l TQToolButton::pixmap to a null
+ pixmap. There is no default iconset.
+
+ \sa pixmap(), setToggleButton(), isOn()
+*/
+void TQToolButton::setIconSet( const TQIconSet & set )
+{
+ if ( s )
+ delete s;
+ setPixmap( TQPixmap() );
+ s = new TQIconSet( set );
+ if ( isVisible() )
+ update();
+}
+
+/*! \overload
+ \obsolete
+
+ Since TQt 3.0, TQIconSet tqcontains both the On and Off icons.
+
+ For ease of porting, this function ignores the \a on parameter and
+ sets the \l iconSet property. If you relied on the \a on parameter,
+ you probably want to update your code to use the TQIconSet On/Off
+ mechanism.
+
+ \sa iconSet TQIconSet::State
+*/
+
+#ifndef TQT_NO_COMPAT
+
+void TQToolButton::setIconSet( const TQIconSet & set, bool /* on */ )
+{
+ setIconSet( set );
+ qWarning( "TQToolButton::setIconSet(): 'on' parameter ignored" );
+}
+
+#endif
+
+TQIconSet TQToolButton::iconSet() const
+{
+ TQToolButton *that = (TQToolButton *) this;
+
+ if ( pixmap() && !pixmap()->isNull() &&
+ (!that->s || (that->s->pixmap().serialNumber() !=
+ pixmap()->serialNumber())) ) {
+ if ( that->s )
+ delete that->s;
+ that->s = new TQIconSet( *pixmap() );
+ }
+ if ( that->s )
+ return *that->s;
+ /*
+ In 2.x, we used to return a temporary nonnull TQIconSet. If you
+ revert to the old behavior, you will break calls to
+ TQIconSet::isNull() in this file.
+ */
+ return TQIconSet();
+}
+
+#ifndef TQT_NO_COMPAT
+/*! \overload
+ \obsolete
+
+ Since TQt 3.0, TQIconSet tqcontains both the On and Off icons.
+
+ For ease of porting, this function ignores the \a on parameter and
+ returns the \l iconSet property. If you relied on the \a on
+ parameter, you probably want to update your code to use the TQIconSet
+ On/Off mechanism.
+*/
+TQIconSet TQToolButton::iconSet( bool /* on */ ) const
+{
+ return iconSet();
+}
+
+#endif
+
+#ifndef TQT_NO_POPUPMENU
+/*!
+ Associates the popup menu \a popup with this tool button.
+
+ The popup will be shown each time the tool button has been pressed
+ down for a certain amount of time. A typical application example
+ is the "back" button in some web browsers's tool bars. If the user
+ clicks it, the browser simply browses back to the previous page.
+ If the user presses and holds the button down for a while, the
+ tool button shows a menu containing the current history list.
+
+ Ownership of the popup menu is not transferred to the tool button.
+
+ \sa popup()
+*/
+void TQToolButton::setPopup( TQPopupMenu* popup )
+{
+ if ( popup && !d->popupTimer ) {
+ connect( this, TQT_SIGNAL( pressed() ), this, TQT_SLOT( popupPressed() ) );
+ d->popupTimer = new TQTimer( this );
+ connect( d->popupTimer, TQT_SIGNAL( timeout() ), this, TQT_SLOT( popupTimerDone() ) );
+ }
+ d->popup = popup;
+
+ update();
+}
+
+/*!
+ Returns the associated popup menu, or 0 if no popup menu has been
+ defined.
+
+ \sa setPopup()
+*/
+TQPopupMenu* TQToolButton::popup() const
+{
+ return d->popup;
+}
+
+/*!
+ Opens (pops up) the associated popup menu. If there is no such
+ menu, this function does nothing. This function does not return
+ until the popup menu has been closed by the user.
+*/
+void TQToolButton::openPopup()
+{
+ if ( !d->popup )
+ return;
+
+ d->instantPopup = TRUE;
+ tqrepaint( FALSE );
+ if ( d->popupTimer )
+ d->popupTimer->stop();
+ TQGuardedPtr<TQToolButton> that = this;
+ popupTimerDone();
+ if ( !that )
+ return;
+ d->instantPopup = FALSE;
+ tqrepaint( FALSE );
+}
+
+void TQToolButton::popupPressed()
+{
+ if ( d->popupTimer && d->delay > 0 )
+ d->popupTimer->start( d->delay, TRUE );
+}
+
+void TQToolButton::popupTimerDone()
+{
+ if ( (!isDown() && d->delay > 0 ) || !d->popup )
+ return;
+
+ d->popup->installEventFilter( this );
+ d->repeat = autoRepeat();
+ setAutoRepeat( FALSE );
+ bool horizontal = TRUE;
+#ifndef TQT_NO_TOOLBAR
+ TQToolBar *tb = ::tqqt_cast<TQToolBar*>(parentWidget());
+ if ( tb && tb->orientation() == Qt::Vertical )
+ horizontal = FALSE;
+#endif
+ TQPoint p;
+ TQRect screen = tqApp->desktop()->availableGeometry( this );
+ if ( horizontal ) {
+ if ( TQApplication::reverseLayout() ) {
+ if ( mapToGlobal( TQPoint( 0, rect().bottom() ) ).y() + d->popup->tqsizeHint().height() <= screen.height() ) {
+ p = mapToGlobal( rect().bottomRight() );
+ } else {
+ p = mapToGlobal( rect().topRight() - TQPoint( 0, d->popup->tqsizeHint().height() ) );
+ }
+ p.rx() -= d->popup->tqsizeHint().width();
+ } else {
+ if ( mapToGlobal( TQPoint( 0, rect().bottom() ) ).y() + d->popup->tqsizeHint().height() <= screen.height() ) {
+ p = mapToGlobal( rect().bottomLeft() );
+ } else {
+ p = mapToGlobal( rect().topLeft() - TQPoint( 0, d->popup->tqsizeHint().height() ) );
+ }
+ }
+ } else {
+ if ( TQApplication::reverseLayout() ) {
+ if ( mapToGlobal( TQPoint( rect().left(), 0 ) ).x() - d->popup->tqsizeHint().width() <= screen.x() ) {
+ p = mapToGlobal( rect().topRight() );
+ } else {
+ p = mapToGlobal( rect().topLeft() );
+ p.rx() -= d->popup->tqsizeHint().width();
+ }
+ } else {
+ if ( mapToGlobal( TQPoint( rect().right(), 0 ) ).x() + d->popup->tqsizeHint().width() <= screen.width() ) {
+ p = mapToGlobal( rect().topRight() );
+ } else {
+ p = mapToGlobal( rect().topLeft() - TQPoint( d->popup->tqsizeHint().width(), 0 ) );
+ }
+ }
+ }
+ TQGuardedPtr<TQToolButton> that = this;
+ d->popup->exec( p, -1 );
+ if ( !that )
+ return;
+
+ setDown( FALSE );
+ if ( d->repeat )
+ setAutoRepeat( TRUE );
+}
+
+/*!
+ \property TQToolButton::popupDelay
+ \brief the time delay between pressing the button and the appearance of the associated popup menu in milliseconds.
+
+ Usually this is around half a second. A value of 0 draws the down
+ arrow button to the side of the button which can be used to open
+ up the popup menu.
+
+ \sa setPopup()
+*/
+void TQToolButton::setPopupDelay( int delay )
+{
+ d->delay = delay;
+
+ update();
+}
+
+int TQToolButton::popupDelay() const
+{
+ return d->delay;
+}
+#endif
+
+
+/*!
+ \property TQToolButton::autoRaise
+ \brief whether auto-raising is enabled or not.
+
+ The default is disabled (i.e. FALSE).
+*/
+void TQToolButton::setAutoRaise( bool enable )
+{
+ d->autoraise = enable;
+
+ update();
+}
+
+bool TQToolButton::autoRaise() const
+{
+ return d->autoraise;
+}
+
+/*!
+ \property TQToolButton::textPosition
+ \brief the position of the text label of this button.
+*/
+
+TQToolButton::TextPosition TQToolButton::textPosition() const
+{
+ return d->textPos;
+}
+
+void TQToolButton::setTextPosition( TextPosition pos )
+{
+ d->textPos = pos;
+ updateGeometry();
+ update();
+}
+
+/*! \reimp */
+
+void TQToolButton::setText( const TQString &txt )
+{
+ TQButton::setText( txt );
+ if ( !text().isEmpty() ) {
+ delete s;
+ s = 0;
+ }
+}
+
+#ifndef TQT_NO_PALETTE
+/*!
+ \reimp
+*/
+void TQToolButton::paletteChange( const TQPalette & )
+{
+ if ( s )
+ s->clearGenerated();
+}
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqtoolbutton.h b/tqtinterface/qt4/src/widgets/tqtoolbutton.h
new file mode 100644
index 0000000..3cdb9c0
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtoolbutton.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+**
+** Definition of TQToolButton class
+**
+** Created : 979899
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTOOLBUTTON_H
+#define TQTOOLBUTTON_H
+
+#ifndef TQT_H
+#include "tqbutton.h"
+#include "tqstring.h"
+#include "tqpixmap.h"
+#include "tqiconset.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TOOLBUTTON
+
+class TQToolButtonPrivate;
+class TQToolBar;
+class TQPopupMenu;
+
+class TQ_EXPORT TQToolButton : public TQButton
+{
+ Q_OBJECT
+ TQ_OBJECT
+ TQ_ENUMS( TextPosition )
+
+ Q_PROPERTY( TQIconSet iconSet READ iconSet WRITE setIconSet )
+ Q_PROPERTY( TQIconSet onIconSet READ onIconSet WRITE setOnIconSet DESIGNABLE false STORED false )
+ Q_PROPERTY( TQIconSet offIconSet READ offIconSet WRITE setOffIconSet DESIGNABLE false STORED false )
+ Q_PROPERTY( bool usesBigPixmap READ usesBigPixmap WRITE setUsesBigPixmap )
+ Q_PROPERTY( bool usesTextLabel READ usesTextLabel WRITE setUsesTextLabel )
+ Q_PROPERTY( TQString textLabel READ textLabel WRITE setTextLabel )
+ Q_PROPERTY( int popupDelay READ popupDelay WRITE setPopupDelay )
+ Q_PROPERTY( bool autoRaise READ autoRaise WRITE setAutoRaise )
+ Q_PROPERTY( TextPosition textPosition READ textPosition WRITE setTextPosition )
+
+ TQ_OVERRIDE( bool toggleButton WRITE setToggleButton )
+ TQ_OVERRIDE( bool on WRITE setOn )
+ TQ_OVERRIDE( TQPixmap pixmap DESIGNABLE false STORED false )
+ TQ_OVERRIDE( BackgroundMode backgroundMode DESIGNABLE true)
+
+public:
+ enum TextPosition {
+ BesideIcon,
+ BelowIcon,
+ Right = BesideIcon, // obsolete
+ Under = BelowIcon // obsolete
+ };
+ TQToolButton( TQWidget * tqparent, const char* name=0 );
+#ifndef TQT_NO_TOOLBAR
+ TQToolButton( const TQIconSet& s, const TQString &textLabel,
+ const TQString& grouptext,
+ TQT_BASE_OBJECT_NAME * receiver, const char* slot,
+ TQToolBar * tqparent, const char* name=0 );
+#endif
+ TQToolButton( TQt::ArrowType type, TQWidget *tqparent, const char* name=0 );
+ ~TQToolButton();
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+#ifndef TQT_NO_COMPAT
+ void setOnIconSet( const TQIconSet& );
+ void setOffIconSet( const TQIconSet& );
+ void setIconSet( const TQIconSet &, bool on );
+ TQIconSet onIconSet() const;
+ TQIconSet offIconSet( ) const;
+ TQIconSet iconSet( bool on ) const;
+#endif
+ virtual void setIconSet( const TQIconSet & );
+ TQIconSet iconSet() const;
+
+ bool usesBigPixmap() const { return ubp; }
+ bool usesTextLabel() const { return utl; }
+ TQString textLabel() const { return tl; }
+
+#ifndef TQT_NO_POPUPMENU
+ void setPopup( TQPopupMenu* popup );
+ TQPopupMenu* popup() const;
+
+ void setPopupDelay( int delay );
+ int popupDelay() const;
+
+ void openPopup();
+#endif
+
+ void setAutoRaise( bool enable );
+ bool autoRaise() const;
+ TextPosition textPosition() const;
+
+ void setText( const TQString &txt );
+
+public Q_SLOTS:
+ virtual void setUsesBigPixmap( bool enable );
+ virtual void setUsesTextLabel( bool enable );
+ virtual void setTextLabel( const TQString &, bool );
+
+ virtual void setToggleButton( bool enable );
+
+ virtual void setOn( bool enable );
+ void toggle();
+ void setTextLabel( const TQString & );
+ void setTextPosition( TextPosition pos );
+
+protected:
+ void mousePressEvent( TQMouseEvent * );
+ void drawButton( TQPainter * );
+ void drawButtonLabel(TQPainter *);
+
+ void enterEvent( TQEvent * );
+ void leaveEvent( TQEvent * );
+ void moveEvent( TQMoveEvent * );
+
+ // ### Make virtual in 4.0, maybe act like TQPushButton with
+ // regards to setFlat() instead? Andy
+ bool uses3D() const;
+#if (TQT_VERSION >= 0x040000)
+#error "Some functions need to be changed to virtual for TQt 4.0"
+#endif
+
+ bool eventFilter( TQObject *o, TQEvent *e );
+
+#ifndef TQT_NO_PALETTE
+ void paletteChange( const TQPalette & );
+#endif
+
+private Q_SLOTS:
+ void popupTimerDone();
+ void popupPressed();
+
+private:
+ void init();
+
+ TQPixmap bp;
+ int bpID;
+ TQPixmap sp;
+ int spID;
+
+ TQString tl;
+
+ TQToolButtonPrivate *d;
+ TQIconSet *s;
+
+ uint utl : 1;
+ uint ubp : 1;
+ uint hasArrow : 1;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQToolButton( const TQToolButton & );
+ TQToolButton& operator=( const TQToolButton & );
+#endif
+};
+
+#endif // TQT_NO_TOOLBUTTON
+
+#endif // TQTOOLBUTTON_H
diff --git a/tqtinterface/qt4/src/widgets/tqtooltip.cpp b/tqtinterface/qt4/src/widgets/tqtooltip.cpp
new file mode 100644
index 0000000..1bb37fd
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtooltip.cpp
@@ -0,0 +1,1268 @@
+/****************************************************************************
+**
+** Tool Tips (or Balloon Help) for any widget or rectangle
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqtooltip.h"
+#ifndef TQT_NO_TOOLTIP
+#include "tqlabel.h"
+#include "tqptrdict.h"
+#include "tqapplication.h"
+#include "tqguardedptr.h"
+#include "tqtimer.h"
+#include "tqeffects_p.h"
+
+static bool globally_enabled = TRUE;
+
+// Magic value meaning an entire widget - if someone tries to insert a
+// tool tip on this part of a widget it will be interpreted as the
+// entire widget.
+
+static inline TQRect entireWidget()
+{
+ return TQRect( -TQWIDGETSIZE_MAX, -TQWIDGETSIZE_MAX,
+ 2*TQWIDGETSIZE_MAX, 2*TQWIDGETSIZE_MAX );
+}
+
+// Internal class - don't touch
+
+class TQTipLabel : public TQLabel
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQTipLabel( TQWidget* tqparent, const TQString& text) : TQLabel( tqparent, "toolTipTip",
+ (WFlags)(TQt::WStyle_StaysOnTop | WStyle_Customize | TQt::WStyle_NoBorder | TQt::WStyle_Tool | WX11BypassWM) )
+ {
+ setMargin(1);
+ setAutoMask( FALSE );
+ setFrameStyle( TQFrame::Plain | TQFrame::Box );
+ setLineWidth( 1 );
+ tqsetAlignment( TQt::AlignAuto | TQt::AlignTop );
+ setIndent(0);
+ polish();
+ setText(text);
+ adjustSize();
+ }
+ void setWidth( int w ) { resize( sizeForWidth( w ) ); }
+};
+
+// Internal class - don't touch
+
+class TQTipManager : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQTipManager();
+ ~TQTipManager();
+
+ struct Tip
+ {
+ TQRect rect;
+ TQString text;
+ TQString groupText;
+ TQToolTipGroup *group;
+ TQToolTip *tip;
+ bool autoDelete;
+ TQRect tqgeometry;
+ Tip *next;
+ };
+
+ bool eventFilter( TQObject * o, TQEvent * e );
+ void add( const TQRect &gm, TQWidget *, const TQRect &, const TQString& ,
+ TQToolTipGroup *, const TQString& , TQToolTip *, bool );
+ void add( TQWidget *, const TQRect &, const TQString& ,
+ TQToolTipGroup *, const TQString& , TQToolTip *, bool );
+ void remove( TQWidget *, const TQRect &, bool delayhide = FALSE );
+ void remove( TQWidget * );
+
+ void removeFromGroup( TQToolTipGroup * );
+
+ void hideTipAndSleep();
+
+ TQString tqfind( TQWidget *, const TQPoint& );
+ void setWakeUpDelay(int);
+
+public Q_SLOTS:
+ void hideTip();
+
+private Q_SLOTS:
+ void labelDestroyed();
+ void clientWidgetDestroyed();
+ void showTip();
+ void allowAnimation();
+
+private:
+ TQTimer wakeUp;
+ int wakeUpDelay;
+ TQTimer fallAsleep;
+
+ TQPtrDict<Tip> *tips;
+ TQTipLabel *label;
+ TQPoint pos;
+ TQGuardedPtr<TQWidget> widget;
+ Tip *currentTip;
+ Tip *previousTip;
+ bool preventAnimation;
+ bool isApplicationFilter;
+ TQTimer *removeTimer;
+};
+
+
+// We have a global, internal TQTipManager object
+
+static TQTipManager *tipManager = 0;
+
+static void initTipManager()
+{
+ if ( !tipManager ) {
+ tipManager = new TQTipManager;
+ TQ_CHECK_PTR( tipManager );
+ }
+}
+
+
+TQTipManager::TQTipManager()
+ : TQObject( tqApp, "toolTipManager" )
+{
+ wakeUpDelay = 700;
+ tips = new TQPtrDict<TQTipManager::Tip>( 313 );
+ currentTip = 0;
+ previousTip = 0;
+ label = 0;
+ preventAnimation = FALSE;
+ isApplicationFilter = FALSE;
+ connect( &wakeUp, TQT_SIGNAL(timeout()), TQT_SLOT(showTip()) );
+ connect( &fallAsleep, TQT_SIGNAL(timeout()), TQT_SLOT(hideTip()) );
+ removeTimer = new TQTimer( this );
+}
+
+
+TQTipManager::~TQTipManager()
+{
+ if ( isApplicationFilter && !tqApp->closingDown() ) {
+ tqApp->setGlobalMouseTracking( FALSE );
+ tqApp->removeEventFilter( tipManager );
+ }
+
+ delete label;
+ label = 0;
+
+ if ( tips ) {
+ TQPtrDictIterator<TQTipManager::Tip> i( *tips );
+ TQTipManager::Tip *t, *n;
+ void *k;
+ while( (t = i.current()) != 0 ) {
+ k = i.currentKey();
+ ++i;
+ tips->take( k );
+ while ( t ) {
+ n = t->next;
+ delete t;
+ t = n;
+ }
+ }
+ delete tips;
+ }
+
+ tipManager = 0;
+}
+
+void TQTipManager::add( const TQRect &gm, TQWidget *w,
+ const TQRect &r, const TQString &s,
+ TQToolTipGroup *g, const TQString& gs,
+ TQToolTip *tt, bool a )
+{
+ remove( w, r, TRUE );
+ TQTipManager::Tip *h = (*tips)[ w ];
+ TQTipManager::Tip *t = new TQTipManager::Tip;
+ t->next = h;
+ t->tip = tt;
+ t->autoDelete = a;
+ t->text = s;
+ t->rect = r;
+ t->groupText = gs;
+ t->group = g;
+ t->tqgeometry = gm;
+
+ if ( h ) {
+ tips->take( w );
+ if ( h != currentTip && h->autoDelete ) {
+ t->next = h->next;
+ delete h;
+ }
+ } else
+ connect( w, TQT_SIGNAL(destroyed()), this, TQT_SLOT(clientWidgetDestroyed()) );
+
+ tips->insert( w, t );
+
+ if ( a && t->rect.tqcontains( pos ) && (!g || g->enabled()) ) {
+ removeTimer->stop();
+ showTip();
+ }
+
+ if ( !isApplicationFilter && tqApp ) {
+ isApplicationFilter = TRUE;
+ tqApp->installEventFilter( tipManager );
+ tqApp->setGlobalMouseTracking( TRUE );
+ }
+
+ if ( t->group ) {
+ disconnect( removeTimer, TQT_SIGNAL( timeout() ),
+ t->group, TQT_SIGNAL( removeTip() ) );
+ connect( removeTimer, TQT_SIGNAL( timeout() ),
+ t->group, TQT_SIGNAL( removeTip() ) );
+ }
+}
+
+void TQTipManager::add( TQWidget *w, const TQRect &r, const TQString &s,
+ TQToolTipGroup *g, const TQString& gs,
+ TQToolTip *tt, bool a )
+{
+ add( TQRect( -1, -1, -1, -1 ), w, r, s, g, gs, tt, a );
+}
+
+
+void TQTipManager::remove( TQWidget *w, const TQRect & r, bool delayhide )
+{
+ TQTipManager::Tip *t = (*tips)[ w ];
+ if ( t == 0 )
+ return;
+
+ if ( t == currentTip ) {
+ if (!delayhide)
+ hideTip();
+ else
+ currentTip->autoDelete = TRUE;
+ }
+
+ if ( t == previousTip )
+ previousTip = 0;
+
+ if ( ( currentTip != t || !delayhide ) && t->rect == r ) {
+ tips->take( w );
+ if ( t->next )
+ tips->insert( w, t->next );
+ delete t;
+ } else {
+ while( t->next && t->next->rect != r && ( currentTip != t->next || !delayhide ))
+ t = t->next;
+ if ( t->next ) {
+ TQTipManager::Tip *d = t->next;
+ t->next = t->next->next;
+ delete d;
+ }
+ }
+
+ if ( (*tips)[ w ] == 0 )
+ disconnect( w, TQT_SIGNAL(destroyed()), this, TQT_SLOT(clientWidgetDestroyed()) );
+#if 0 // not needed, leads sometimes to crashes
+ if ( tips->isEmpty() ) {
+ // the manager will be recreated if needed
+ delete tipManager;
+ tipManager = 0;
+ }
+#endif
+}
+
+
+/*
+ The label was destroyed in the program cleanup phase.
+*/
+
+void TQTipManager::labelDestroyed()
+{
+ label = 0;
+}
+
+
+/*
+ Remove sender() from the tool tip data structures.
+*/
+
+void TQTipManager::clientWidgetDestroyed()
+{
+ const TQObject *s = TQT_TQOBJECT(sender());
+ if ( s )
+ remove( (TQWidget*) s );
+}
+
+
+void TQTipManager::remove( TQWidget *w )
+{
+ TQTipManager::Tip *t = (*tips)[ w ];
+ if ( t == 0 )
+ return;
+
+ tips->take( w );
+ TQTipManager::Tip * d;
+ while ( t ) {
+ if ( t == currentTip )
+ hideTip();
+ d = t->next;
+ delete t;
+ t = d;
+ }
+
+ disconnect( w, TQT_SIGNAL(destroyed()), this, TQT_SLOT(clientWidgetDestroyed()) );
+#if 0
+ if ( tips->isEmpty() ) {
+ delete tipManager;
+ tipManager = 0;
+ }
+#endif
+}
+
+
+void TQTipManager::removeFromGroup( TQToolTipGroup *g )
+{
+ TQPtrDictIterator<TQTipManager::Tip> i( *tips );
+ TQTipManager::Tip *t;
+ while( (t = i.current()) != 0 ) {
+ ++i;
+ while ( t ) {
+ if ( t->group == g ) {
+ if ( t->group )
+ disconnect( removeTimer, TQT_SIGNAL( timeout() ),
+ t->group, TQT_SIGNAL( removeTip() ) );
+ t->group = 0;
+ }
+ t = t->next;
+ }
+ }
+}
+
+
+
+bool TQTipManager::eventFilter( TQObject *obj, TQEvent *e )
+{
+ // avoid dumping core in case of application madness, and return
+ // quickly for some common but irrelevant events
+ if ( e->type() == TQEvent::WindowDeactivate &&
+ tqApp && !tqApp->activeWindow() &&
+ label && label->isVisible() )
+ hideTipAndSleep();
+
+ if ( !tqApp
+ || !obj || !obj->isWidgetType() // isWidgetType() catches most stuff
+ || e->type() == TQEvent::Paint
+ || e->type() == TQEvent::Timer
+ || e->type() == TQEvent::SockAct
+ || !tips )
+ return FALSE;
+ TQWidget *w = (TQWidget *)obj;
+
+ if ( e->type() == TQEvent::FocusOut || e->type() == TQEvent::FocusIn ) {
+ // user moved focus somewhere - hide the tip and sleep
+ if ( ((TQFocusEvent*)e)->reason() != TQFocusEvent::Popup )
+ hideTipAndSleep();
+ return FALSE;
+ }
+
+ TQTipManager::Tip *t = 0;
+ while( w && !t ) {
+ t = (*tips)[ w ];
+ if ( !t )
+ w = w->isTopLevel() ? 0 : w->parentWidget();
+ }
+ if ( !w )
+ return FALSE;
+
+ if ( !t && e->type() != TQEvent::MouseMove) {
+ if ( ( e->type() >= TQEvent::MouseButtonPress &&
+ e->type() <= TQEvent::FocusOut) || e->type() == TQEvent::Leave )
+ hideTip();
+ return FALSE;
+ }
+
+ // with that out of the way, let's get down to action
+
+ switch( e->type() ) {
+ case TQEvent::MouseButtonPress:
+ case TQEvent::MouseButtonRelease:
+ case TQEvent::MouseButtonDblClick:
+ case TQEvent::KeyPress:
+ case TQEvent::KeyRelease:
+ // input - turn off tool tip mode
+ hideTipAndSleep();
+ break;
+ case TQEvent::MouseMove:
+ {
+ TQMouseEvent * m = (TQMouseEvent *)e;
+ TQPoint mousePos = w->mapFromGlobal( m->globalPos() );
+
+ if ( currentTip && !currentTip->rect.tqcontains( mousePos ) ) {
+ hideTip();
+ if ( m->state() == 0 )
+ return FALSE;
+ }
+
+ wakeUp.stop();
+ if ( m->state() == 0 &&
+ mousePos.x() >= 0 && mousePos.x() < w->width() &&
+ mousePos.y() >= 0 && mousePos.y() < w->height() ) {
+ if ( label && label->isVisible() ) {
+ return FALSE;
+ } else {
+ if ( fallAsleep.isActive() ) {
+ wakeUp.start( 1, TRUE );
+ } else {
+ previousTip = 0;
+ wakeUp.start( wakeUpDelay, TRUE );
+ }
+ if ( t->group && t->group->ena &&
+ !t->group->del && !t->groupText.isEmpty() ) {
+ removeTimer->stop();
+ emit t->group->showTip( t->groupText );
+ currentTip = t;
+ }
+ }
+ widget = w;
+ pos = mousePos;
+ return FALSE;
+ } else {
+ hideTip();
+ }
+ }
+ break;
+ case TQEvent::Leave:
+ case TQEvent::Hide:
+ case TQEvent::Destroy:
+ if ( w == widget )
+ hideTip();
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+
+
+void TQTipManager::showTip()
+{
+ if ( !widget || !globally_enabled
+#ifndef TQ_WS_X11
+ || !widget->isActiveWindow()
+#endif
+ )
+ return;
+
+ TQTipManager::Tip *t = (*tips)[ widget ];
+ while ( t && !t->rect.tqcontains( pos ) )
+ t = t->next;
+ if ( t == 0 )
+ return;
+
+ if ( t == currentTip && label && label->isVisible() )
+ return; // nothing to do
+
+ if ( t->tip ) {
+ t->tip->maybeTip( pos );
+ return;
+ }
+
+ if ( t->group && !t->group->ena )
+ return;
+
+ int scr;
+ if ( TQApplication::desktop()->isVirtualDesktop() )
+ scr = TQApplication::desktop()->screenNumber( widget->mapToGlobal( pos ) );
+ else
+ scr = TQApplication::desktop()->screenNumber( widget );
+
+ if ( label
+#if defined(TQ_WS_X11)
+ && label->x11Screen() == widget->x11Screen()
+#endif
+ ) {
+ // the next two lines are a workaround for TQLabel being too intelligent.
+ // TQLabel turns on the wordbreak flag once it gets a richtext. The two lines below
+ // ensure we get correct textflags when switching back and forth between a richtext and
+ // non richtext tooltip
+ label->setText( "" );
+ label->tqsetAlignment( TQt::AlignAuto | TQt::AlignTop );
+ label->setText( t->text );
+ label->adjustSize();
+ if ( t->tqgeometry != TQRect( -1, -1, -1, -1 ) )
+ label->resize( t->tqgeometry.size() );
+ } else {
+ delete label;
+ label = new TQTipLabel( TQT_TQWIDGET(TQApplication::desktop()->screen( scr )), t->text);
+ if ( t->tqgeometry != TQRect( -1, -1, -1, -1 ) )
+ label->resize( t->tqgeometry.size() );
+ TQ_CHECK_PTR( label );
+ connect( label, TQT_SIGNAL(destroyed()), TQT_SLOT(labelDestroyed()) );
+ }
+ // the above deletion and creation of a TQTipLabel causes events to be sent. We had reports that the widget
+ // pointer was 0 after this. This is in principle possible if the wrong kind of events get sent through our event
+ // filter in this time. So better be safe and check widget once again here.
+ if (!widget)
+ return;
+
+#ifdef TQ_WS_MAC
+ TQRect screen = TQApplication::desktop()->availableGeometry( scr );
+#else
+ TQRect screen = TQApplication::desktop()->screenGeometry( scr );
+#endif
+ TQPoint p;
+ if ( t->tqgeometry == TQRect( -1, -1, -1, -1 ) ) {
+ p = widget->mapToGlobal( pos ) +
+#ifdef TQ_WS_WIN
+ TQPoint( 2, 24 );
+#else
+ TQPoint( 2, 16 );
+#endif
+ if ( p.x() + label->width() > screen.x() + screen.width() )
+ p.rx() -= 4 + label->width();
+ if ( p.y() + label->height() > screen.y() + screen.height() )
+ p.ry() -= 24 + label->height();
+ } else {
+ p = widget->mapToGlobal( t->tqgeometry.topLeft() );
+ label->tqsetAlignment( TQt::WordBreak | TQt::AlignCenter );
+ label->setWidth( t->tqgeometry.width() - 4 );
+ }
+ if ( p.y() < screen.y() )
+ p.setY( screen.y() );
+ if ( p.x() + label->width() > screen.x() + screen.width() )
+ p.setX( screen.x() + screen.width() - label->width() );
+ if ( p.x() < screen.x() )
+ p.setX( screen.x() );
+ if ( p.y() + label->height() > screen.y() + screen.height() )
+ p.setY( screen.y() + screen.height() - label->height() );
+ if ( label->text().length() ) {
+ label->move( p );
+
+#ifndef TQT_NO_EFFECTS
+ if ( TQApplication::isEffectEnabled( Qt::UI_AnimateTooltip ) == FALSE ||
+ previousTip || preventAnimation )
+ label->show();
+ else if ( TQApplication::isEffectEnabled( Qt::UI_FadeTooltip ) )
+ qFadeEffect( label );
+ else
+ qScrollEffect( label );
+#else
+ label->show();
+#endif
+
+ label->raise();
+ fallAsleep.start( 10000, TRUE );
+ }
+
+ if ( t->group && t->group->del && !t->groupText.isEmpty() ) {
+ removeTimer->stop();
+ emit t->group->showTip( t->groupText );
+ }
+
+ currentTip = t;
+ previousTip = 0;
+}
+
+
+void TQTipManager::hideTip()
+{
+ TQTimer::singleShot( 250, this, TQT_SLOT(allowAnimation()) );
+ preventAnimation = TRUE;
+
+ if ( label && label->isVisible() ) {
+ label->hide();
+ fallAsleep.start( 2000, TRUE );
+ wakeUp.stop();
+ if ( currentTip && currentTip->group )
+ removeTimer->start( 100, TRUE );
+ } else if ( wakeUp.isActive() ) {
+ wakeUp.stop();
+ if ( currentTip && currentTip->group &&
+ !currentTip->group->del && !currentTip->groupText.isEmpty() )
+ removeTimer->start( 100, TRUE );
+ } else if ( currentTip && currentTip->group ) {
+ removeTimer->start( 100, TRUE );
+ }
+
+ previousTip = currentTip;
+ currentTip = 0;
+ if ( previousTip && previousTip->autoDelete )
+ remove( widget, previousTip->rect );
+ widget = 0;
+}
+
+void TQTipManager::hideTipAndSleep()
+{
+ hideTip();
+ fallAsleep.stop();
+}
+
+
+void TQTipManager::allowAnimation()
+{
+ preventAnimation = FALSE;
+}
+
+TQString TQTipManager::tqfind( TQWidget *w, const TQPoint& pos )
+{
+ Tip *t = (*tips)[ w ];
+ while ( t && !t->rect.tqcontains( pos ) )
+ t = t->next;
+
+ return t ? t->text : TQString::null;
+}
+
+void TQTipManager::setWakeUpDelay ( int i )
+{
+ wakeUpDelay = i;
+}
+
+/*!
+ \class TQToolTip tqtooltip.h
+ \brief The TQToolTip class provides tool tips (balloon help) for
+ any widget or rectangular part of a widget.
+
+ \ingroup helpsystem
+ \mainclass
+
+ The tip is a short, single line of text reminding the user of the
+ widget's or rectangle's function. It is drawn immediately below
+ the region in a distinctive black-on-yellow combination.
+
+ The tip can be any Rich-Text formatted string.
+
+ TQToolTipGroup provides a way for tool tips to display another text
+ elsewhere (most often in a \link TQStatusBar status bar\endlink).
+
+ At any point in time, TQToolTip is either dormant or active. In
+ dormant mode the tips are not shown and in active mode they are.
+ The mode is global, not particular to any one widget.
+
+ TQToolTip switches from dormant to active mode when the user hovers
+ the mouse on a tip-equipped region for a second or so and remains
+ active until the user either clicks a mouse button, presses a key,
+ lets the mouse hover for five seconds or moves the mouse outside
+ \e all tip-equipped regions for at least a second.
+
+ The TQToolTip class can be used in three different ways:
+ \list 1
+ \i Adding a tip to an entire widget.
+ \i Adding a tip to a fixed rectangle within a widget.
+ \i Adding a tip to a dynamic rectangle within a widget.
+ \endlist
+
+ To add a tip to a widget, call the \e static function
+ TQToolTip::add() with the widget and tip as arguments:
+
+ \code
+ TQToolTip::add( quitButton, "Leave the application" );
+ \endcode
+
+ This is the simplest and most common use of TQToolTip. The tip
+ will be deleted automatically when \e quitButton is deleted, but
+ you can remove it yourself, too:
+
+ \code
+ TQToolTip::remove( quitButton );
+ \endcode
+
+ You can also display another text (typically in a \link TQStatusBar
+ status bar),\endlink courtesy of \l{TQToolTipGroup}. This example
+ assumes that \e grp is a \c{TQToolTipGroup *} and is already
+ connected to the appropriate status bar:
+
+ \code
+ TQToolTip::add( quitButton, "Leave the application", grp,
+ "Leave the application, prompting to save if necessary" );
+ TQToolTip::add( closeButton, "Close this window", grp,
+ "Close this window, prompting to save if necessary" );
+ \endcode
+
+ To add a tip to a fixed rectangle within a widget, call the static
+ function TQToolTip::add() with the widget, rectangle and tip as
+ arguments. (See the \c tooltip/tooltip.cpp example.) Again, you
+ can supply a \c{TQToolTipGroup *} and another text if you want.
+
+ Both of these are one-liners and cover the majority of cases. The
+ third and most general way to use TQToolTip requires you to
+ reimplement a pure virtual function to decide whether to pop up a
+ tool tip. The \c tooltip/tooltip.cpp example demonstrates this
+ too. This mode can be used to implement tips for text that can
+ move as the user scrolls, for example.
+
+ To use TQToolTip like this, you must subclass TQToolTip and
+ reimplement maybeTip(). TQToolTip calls maybeTip() when a tip
+ should pop up, and maybeTip() decides whether to show a tip.
+
+ Tool tips can be globally disabled using
+ TQToolTip::setGloballyEnabled() or disabled in groups with
+ TQToolTipGroup::setEnabled().
+
+ You can retrieve the text of a tooltip for a given position within
+ a widget using textFor().
+
+ The global tooltip font and palette can be set with the static
+ setFont() and setPalette() functions respectively.
+
+ \sa TQStatusBar TQWhatsThis TQToolTipGroup
+ \link guibooks.html#fowler GUI Design Handbook: Tool Tip\endlink
+*/
+
+
+/*!
+ Returns the font common to all tool tips.
+
+ \sa setFont()
+*/
+
+TQFont TQToolTip::font()
+{
+ TQTipLabel l(0,"");
+ return TQApplication::font( &l );
+}
+
+
+/*!
+ Sets the font for all tool tips to \a font.
+
+ \sa font()
+*/
+
+void TQToolTip::setFont( const TQFont &font )
+{
+ TQApplication::tqsetFont( font, TRUE, "TQTipLabel" );
+}
+
+
+/*!
+ Returns the palette common to all tool tips.
+
+ \sa setPalette()
+*/
+
+TQPalette TQToolTip::palette()
+{
+ TQTipLabel l(0,"");
+ return TQApplication::palette( &l );
+}
+
+
+/*!
+ Sets the palette for all tool tips to \a palette.
+
+ \sa palette()
+*/
+
+void TQToolTip::setPalette( const TQPalette &palette )
+{
+ TQApplication::tqsetPalette( palette, TRUE, "TQTipLabel" );
+}
+
+/*!
+ Constructs a tool tip object. This is only necessary if you need
+ tool tips on regions that can move within the widget (most often
+ because the widget's contents can scroll).
+
+ \a widget is the widget you want to add dynamic tool tips to and
+ \a group (optional) is the tool tip group they should belong to.
+
+ \warning TQToolTip is not a subclass of TQObject, so the instance of
+ TQToolTip is not deleted when \a widget is deleted.
+
+ \warning If you delete the tool tip before you have deleted
+ \a widget then you need to make sure you call remove() yourself from
+ \a widget in your reimplemented TQToolTip destructor.
+
+ \code
+ MyToolTip::~MyToolTip()
+ {
+ remove( widget );
+ }
+ \endcode
+
+ \sa maybeTip().
+*/
+
+TQToolTip::TQToolTip( TQWidget * widget, TQToolTipGroup * group )
+{
+ p = widget;
+ g = group;
+ initTipManager();
+ tipManager->add( p, entireWidget(),
+ TQString::null, g, TQString::null, this, FALSE );
+}
+
+
+/*!
+ Adds a tool tip to \a widget. \a text is the text to be shown in
+ the tool tip.
+
+ This is the most common entry point to the TQToolTip class; it is
+ suitable for adding tool tips to buttons, checkboxes, comboboxes
+ and so on.
+*/
+
+void TQToolTip::add( TQWidget *widget, const TQString &text )
+{
+ initTipManager();
+ tipManager->add( widget, entireWidget(),
+ text, 0, TQString::null, 0, FALSE );
+}
+
+
+/*!
+ \overload
+
+ Adds a tool tip to \a widget and to tool tip group \a group.
+
+ \a text is the text shown in the tool tip and \a longText is the
+ text emitted from \a group.
+
+ Normally, \a longText is shown in a \link TQStatusBar status
+ bar\endlink or similar.
+*/
+
+void TQToolTip::add( TQWidget *widget, const TQString &text,
+ TQToolTipGroup *group, const TQString& longText )
+{
+ initTipManager();
+ tipManager->add( widget, entireWidget(), text, group, longText, 0, FALSE );
+}
+
+
+/*!
+ Removes the tool tip from \a widget.
+
+ If there is more than one tool tip on \a widget, only the one
+ covering the entire widget is removed.
+*/
+
+void TQToolTip::remove( TQWidget * widget )
+{
+ if ( tipManager )
+ tipManager->remove( widget, entireWidget() );
+}
+
+/*!
+ \overload
+
+ Adds a tool tip to a fixed rectangle, \a rect, within \a widget.
+ \a text is the text shown in the tool tip.
+*/
+
+void TQToolTip::add( TQWidget * widget, const TQRect & rect, const TQString &text )
+{
+ initTipManager();
+ tipManager->add( widget, rect, text, 0, TQString::null, 0, FALSE );
+}
+
+
+/*!
+ \overload
+
+ Adds a tool tip to an entire \a widget and to tool tip group \a
+ group. The tooltip will disappear when the mouse leaves the \a
+ rect.
+
+ \a text is the text shown in the tool tip and \a groupText is the
+ text emitted from \a group.
+
+ Normally, \a groupText is shown in a \link TQStatusBar status
+ bar\endlink or similar.
+*/
+
+void TQToolTip::add( TQWidget *widget, const TQRect &rect,
+ const TQString& text,
+ TQToolTipGroup *group, const TQString& groupText )
+{
+ initTipManager();
+ tipManager->add( widget, rect, text, group, groupText, 0, FALSE );
+}
+
+
+/*!
+ \overload
+
+ Removes any tool tip for \a rect from \a widget.
+
+ If there is more than one tool tip on \a widget, only the one
+ covering rectangle \a rect is removed.
+*/
+
+void TQToolTip::remove( TQWidget * widget, const TQRect & rect )
+{
+ if ( tipManager )
+ tipManager->remove( widget, rect );
+}
+
+/*!
+ Returns the tool tip text for \a widget at position \a pos, or
+ TQString::null if there is no tool tip for the given widget and
+ position.
+*/
+
+TQString TQToolTip::textFor( TQWidget *widget, const TQPoint& pos )
+{
+ if ( tipManager )
+ return tipManager->tqfind( widget, pos );
+ return TQString::null;
+}
+
+/*!
+ Hides any tip that is currently being shown.
+
+ Normally, there is no need to call this function; TQToolTip takes
+ care of showing and hiding the tips as the user moves the mouse.
+*/
+
+void TQToolTip::hide()
+{
+ if ( tipManager )
+ tipManager->hideTipAndSleep();
+}
+
+/*!
+ \fn virtual void TQToolTip::maybeTip( const TQPoint & p);
+
+ This pure virtual function is half of the most versatile interface
+ TQToolTip offers.
+
+ It is called when there is a possibility that a tool tip should be
+ shown and must decide whether there is a tool tip for the point \a
+ p in the widget that this TQToolTip object relates to. If so,
+ maybeTip() must call tip() with the rectangle the tip applies to,
+ the tip's text and optionally the TQToolTipGroup details and the
+ tqgeometry in screen coordinates.
+
+ \a p is given in that widget's local coordinates. Most maybeTip()
+ implementations will be of the form:
+
+ \code
+ if ( <something> ) {
+ tip( <something>, <something> );
+ }
+ \endcode
+
+ The first argument to tip() (a rectangle) must encompass \a p,
+ i.e. the tip must apply to the current mouse position; otherwise
+ TQToolTip's operation is undefined.
+
+ Note that the tip will disappear once the mouse moves outside the
+ rectangle you give to tip(), and will not reappear if the mouse
+ moves back in: maybeTip() is called again instead.
+
+ \sa tip()
+*/
+
+
+/*!
+ Immediately pops up a tip saying \a text and removes the tip once
+ the cursor moves out of rectangle \a rect (which is given in the
+ coordinate system of the widget this TQToolTip relates to).
+
+ The tip will not reappear if the cursor moves back; your
+ maybeTip() must reinstate it each time.
+*/
+
+void TQToolTip::tip( const TQRect & rect, const TQString &text )
+{
+ initTipManager();
+ tipManager->add( parentWidget(), rect, text, 0, TQString::null, 0, TRUE );
+}
+
+/*!
+ \overload
+
+ Immediately pops up a tip saying \a text and removes that tip once
+ the cursor moves out of rectangle \a rect (which is given in the
+ coordinate system of the widget this TQToolTip relates to). \a
+ groupText is the text emitted from the group.
+
+ The tip will not reappear if the cursor moves back; your
+ maybeTip() must reinstate it each time.
+*/
+
+void TQToolTip::tip( const TQRect & rect, const TQString &text,
+ const TQString& groupText )
+{
+ initTipManager();
+ tipManager->add( parentWidget(), rect, text, group(), groupText, 0, TRUE );
+}
+
+/*!
+ \overload
+
+ Immediately pops up a tip within the rectangle \a tqgeometry, saying
+ \a text and removes the tip once the cursor moves out of rectangle
+ \a rect. Both rectangles are given in the coordinate system of the
+ widget this TQToolTip relates to.
+
+ The tip will not reappear if the cursor moves back; your
+ maybeTip() must reinstate it each time.
+
+ If the tip does not fit inside \a tqgeometry, the tip expands.
+*/
+
+void TQToolTip::tip( const TQRect &rect, const TQString &text, const TQRect &tqgeometry )
+{
+ initTipManager();
+ tipManager->add( tqgeometry, parentWidget(), rect, text, 0, TQString::null, 0, TRUE );
+}
+
+/*!
+ \overload
+
+ Immediately pops up a tip within the rectangle \a tqgeometry, saying
+ \a text and removes the tip once the cursor moves out of rectangle
+ \a rect. \a groupText is the text emitted from the group. Both
+ rectangles are given in the coordinate system of the widget this
+ TQToolTip relates to.
+
+ The tip will not reappear if the cursor moves back; your
+ maybeTip() must reinstate it each time.
+
+ If the tip does not fit inside \a tqgeometry, the tip expands.
+*/
+
+void TQToolTip::tip( const TQRect &rect, const TQString &text, const TQString& groupText, const TQRect &tqgeometry )
+{
+ initTipManager();
+ tipManager->add( tqgeometry, parentWidget(), rect, text, group(), groupText, 0, TRUE );
+}
+
+
+
+/*!
+ Immediately removes all tool tips for this tooltip's tqparent
+ widget.
+*/
+
+void TQToolTip::clear()
+{
+ if ( tipManager )
+ tipManager->remove( parentWidget() );
+}
+
+
+/*!
+ \fn TQWidget * TQToolTip::parentWidget() const
+
+ Returns the widget this TQToolTip applies to.
+
+ The tool tip is destroyed automatically when the tqparent widget is
+ destroyed.
+
+ \sa group()
+*/
+
+
+/*!
+ \fn TQToolTipGroup * TQToolTip::group() const
+
+ Returns the tool tip group this TQToolTip is a member of or 0 if it
+ isn't a member of any group.
+
+ The tool tip group is the object responsible for maintaining
+ contact between tool tips and a \link TQStatusBar status
+ bar\endlink or something else which can show the longer help text.
+
+ \sa parentWidget(), TQToolTipGroup
+*/
+
+
+/*!
+ \class TQToolTipGroup tqtooltip.h
+ \brief The TQToolTipGroup class collects tool tips into related groups.
+
+ \ingroup helpsystem
+
+ Tool tips can display \e two texts: one in the tip and
+ (optionally) one that is typically in a \link TQStatusBar status
+ bar\endlink. TQToolTipGroup provides a way to link tool tips to
+ this status bar.
+
+ TQToolTipGroup has practically no API; it is only used as an
+ argument to TQToolTip's member functions, for example like this:
+
+ \code
+ TQToolTipGroup * grp = new TQToolTipGroup( this, "tool tip relay" );
+ connect( grp, TQT_SIGNAL(showTip(const TQString&)),
+ myLabel, TQT_SLOT(setText(const TQString&)) );
+ connect( grp, TQT_SIGNAL(removeTip()),
+ myLabel, TQT_SLOT(clear()) );
+ TQToolTip::add( giraffeButton, "feed giraffe",
+ grp, "Give the giraffe a meal" );
+ TQToolTip::add( gorillaButton, "feed gorilla",
+ grp, "Give the gorilla a meal" );
+ \endcode
+
+ This example makes the object myLabel (which you must supply)
+ display (one assumes, though you can make myLabel do anything, of
+ course) the strings "Give the giraffe a meal" and "Give the
+ gorilla a meal" while the relevant tool tips are being displayed.
+
+ Deleting a tool tip group removes the tool tips in it.
+*/
+
+/*!
+ \fn void TQToolTipGroup::showTip (const TQString &longText)
+
+ This signal is emitted when one of the tool tips in the group is
+ displayed. \a longText is the extra text for the displayed tool
+ tip.
+
+ \sa removeTip()
+*/
+
+/*!
+ \fn void TQToolTipGroup::removeTip ()
+
+ This signal is emitted when a tool tip in this group is hidden.
+ See the TQToolTipGroup documentation for an example of use.
+
+ \sa showTip()
+*/
+
+
+/*!
+ Constructs a tool tip group called \a name, with tqparent \a tqparent.
+*/
+
+TQToolTipGroup::TQToolTipGroup( TQObject *tqparent, const char *name )
+ : TQObject( tqparent, name )
+{
+ del = TRUE;
+ ena = TRUE;
+}
+
+
+/*!
+ Destroys this tool tip group and all tool tips in it.
+*/
+
+TQToolTipGroup::~TQToolTipGroup()
+{
+ if ( tipManager )
+ tipManager->removeFromGroup( this );
+}
+
+
+/*!
+ \property TQToolTipGroup::delay
+ \brief whether the display of the group text is delayed.
+
+ If set to TRUE (the default), the group text is displayed at the
+ same time as the tool tip. Otherwise, the group text is displayed
+ immediately when the cursor enters the widget.
+*/
+
+bool TQToolTipGroup::delay() const
+{
+ return del;
+}
+
+void TQToolTipGroup::setDelay( bool enable )
+{
+#if 0
+ if ( enable && !del ) {
+ // maybe we should show the text at once?
+ }
+#endif
+ del = enable;
+}
+
+/*!
+ \fn static void TQToolTip::setEnabled( bool enable )
+
+ \obsolete
+*/
+/*!
+ \fn static bool TQToolTip::enabled()
+
+ \obsolete
+*/
+/*!
+ \property TQToolTipGroup::enabled
+ \brief whether tool tips in the group are enabled.
+
+ This property's default is TRUE.
+*/
+
+void TQToolTipGroup::setEnabled( bool enable )
+{
+ ena = enable;
+}
+
+bool TQToolTipGroup::enabled() const
+{
+ return (bool)ena;
+}
+
+/*!
+ If \a enable is TRUE sets all tool tips to be enabled (shown when
+ needed); if \a enable is FALSE sets all tool tips to be disabled
+ (never shown).
+
+ By default, tool tips are enabled. Note that this function affects
+ all tool tips in the entire application.
+
+ \sa TQToolTipGroup::setEnabled()
+*/
+
+void TQToolTip::setGloballyEnabled( bool enable )
+{
+ globally_enabled = enable;
+}
+
+/*!
+ Returns whether tool tips are enabled globally.
+
+ \sa setGloballyEnabled()
+*/
+bool TQToolTip::isGloballyEnabled()
+{
+ return globally_enabled;
+}
+
+/*!
+ Sets the wakeup delay for all tooltips to \a i
+ milliseconds.
+*/
+void TQToolTip::setWakeUpDelay ( int i )
+{
+ initTipManager();
+ tipManager->setWakeUpDelay(i);
+}
+
+
+#include "tqtooltip.tqmoc"
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqtooltip.h b/tqtinterface/qt4/src/widgets/tqtooltip.h
new file mode 100644
index 0000000..e9afb22
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqtooltip.h
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Definition of Tool Tips (or Balloon Help) for any widget or rectangle
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQTOOLTIP_H
+#define TQTOOLTIP_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_TOOLTIP
+
+#if __GNUC__ - 0 > 3
+#pragma GCC system_header
+#endif
+
+class TQTipManager;
+class TQIconViewToolTip;
+class TQListViewToolTip;
+
+class TQ_EXPORT TQToolTipGroup: public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool delay READ delay WRITE setDelay )
+ Q_PROPERTY( bool enabled READ enabled WRITE setEnabled )
+
+public:
+ TQToolTipGroup( TQObject *tqparent, const char *name = 0 );
+ ~TQToolTipGroup();
+
+ bool delay() const;
+ bool enabled() const;
+
+public Q_SLOTS:
+ void setDelay( bool );
+ void setEnabled( bool );
+
+Q_SIGNALS:
+ void showTip( const TQString &);
+ void removeTip();
+
+private:
+ uint del:1;
+ uint ena:1;
+
+ friend class TQTipManager;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQToolTipGroup( const TQToolTipGroup & );
+ TQToolTipGroup& operator=( const TQToolTipGroup & );
+#endif
+};
+
+
+class TQ_EXPORT TQToolTip: public TQt
+{
+public:
+ TQToolTip( TQWidget *, TQToolTipGroup * = 0 );
+ //### add virtual d'tor for 4.0
+
+ static void add( TQWidget *, const TQString &);
+ static void add( TQWidget *, const TQString &,
+ TQToolTipGroup *, const TQString& );
+ static void remove( TQWidget * );
+
+ static void add( TQWidget *, const TQRect &, const TQString &);
+ static void add( TQWidget *, const TQRect &, const TQString &,
+ TQToolTipGroup *, const TQString& );
+ static void remove( TQWidget *, const TQRect & );
+
+ static TQString textFor( TQWidget *, const TQPoint & pos = TQPoint() );
+
+ static void hide();
+
+ static TQFont font();
+ static void setFont( const TQFont & );
+ static TQPalette palette();
+ static void setPalette( const TQPalette & );
+
+#ifndef TQT_NO_COMPAT
+ static void setEnabled( bool enable ) { setGloballyEnabled( enable ); }
+ static bool enabled() { return isGloballyEnabled(); }
+#endif
+ static void setGloballyEnabled( bool );
+ static bool isGloballyEnabled();
+ static void setWakeUpDelay(int);
+
+protected:
+ virtual void maybeTip( const TQPoint & ) = 0;
+ void tip( const TQRect &, const TQString &);
+ void tip( const TQRect &, const TQString& , const TQString &);
+ void tip( const TQRect &, const TQString &, const TQRect & );
+ void tip( const TQRect &, const TQString&, const TQString &, const TQRect &);
+
+ void clear();
+
+public:
+ TQWidget *parentWidget() const { return p; }
+ TQToolTipGroup *group() const { return g; }
+
+private:
+ TQWidget *p;
+ TQToolTipGroup *g;
+ static TQFont *ttFont;
+ static TQPalette *ttPalette;
+
+ friend class TQTipManager;
+};
+
+
+#endif // TQT_NO_TOOLTIP
+
+#endif // TQTOOLTIP_H
diff --git a/tqtinterface/qt4/src/widgets/tqvalidator.cpp b/tqtinterface/qt4/src/widgets/tqvalidator.cpp
new file mode 100644
index 0000000..e238ab0
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqvalidator.cpp
@@ -0,0 +1,672 @@
+/****************************************************************************
+**
+** Implementation of validator classes
+**
+** Created : 970610
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqvalidator.h"
+#ifndef TQT_NO_VALIDATOR
+
+#include <limits.h>
+#include <math.h>
+
+/*!
+ \class TQValidator
+ \brief The TQValidator class provides validation of input text.
+
+ \ingroup misc
+ \mainclass
+
+ The class itself is abstract. Two subclasses, \l TQIntValidator and
+ \l TQDoubleValidator, provide basic numeric-range checking, and \l
+ TQRegExpValidator provides general checking using a custom regular
+ expression.
+
+ If the built-in validators aren't sufficient, you can subclass
+ TQValidator. The class has two virtual functions: validate() and
+ fixup().
+
+ \l validate() must be implemented by every subclass. It returns
+ \c Invalid, \c Intermediate or \c Acceptable depending on whether
+ its argument is valid (for the subclass's definition of valid).
+
+ These three states require some explanation. An \c Invalid string
+ is \e clearly invalid. \c Intermediate is less obvious: the
+ concept of validity is slippery when the string is incomplete
+ (still being edited). TQValidator defines \c Intermediate as the
+ property of a string that is neither clearly invalid nor
+ acceptable as a final result. \c Acceptable means that the string
+ is acceptable as a final result. One might say that any string
+ that is a plausible intermediate state during entry of an \c
+ Acceptable string is \c Intermediate.
+
+ Here are some examples:
+
+ \list
+
+ \i For a line edit that accepts integers from 0 to 999 inclusive,
+ 42 and 123 are \c Acceptable, the empty string and 1114 are \c
+ Intermediate and asdf is \c Invalid.
+
+ \i For an editable combobox that accepts URLs, any well-formed URL
+ is \c Acceptable, "http://www.trolltech.com/," is \c Intermediate
+ (it might be a cut and paste operation that accidentally took in a
+ comma at the end), the empty string is \c Intermediate (the user
+ might select and delete all of the text in preparation for entering
+ a new URL), and "http:///./" is \c Invalid.
+
+ \i For a spin box that accepts lengths, "11cm" and "1in" are \c
+ Acceptable, "11" and the empty string are \c Intermediate and
+ "http://www.trolltech.com" and "hour" are \c Invalid.
+
+ \endlist
+
+ \l fixup() is provided for validators that can repair some user
+ errors. The default implementation does nothing. TQLineEdit, for
+ example, will call fixup() if the user presses Enter (or Return)
+ and the content is not currently valid. This allows the fixup()
+ function the opportunity of performing some magic to make an \c
+ Invalid string \c Acceptable.
+
+ TQValidator is typically used with TQLineEdit, TQSpinBox and
+ TQComboBox.
+*/
+
+
+/*!
+ \enum TQValidator::State
+
+ This enum type defines the states in which a validated string can
+ exist.
+
+ \value Invalid the string is \e clearly invalid.
+
+ \value Intermediate the string is a plausible intermediate value
+ during editing.
+
+ \value Acceptable the string is acceptable as a final result,
+ i.e. it is valid.
+*/
+
+
+/*!
+ Sets up the validator. The \a tqparent and \a name parameters are
+ passed on to the TQObject constructor.
+*/
+
+TQValidator::TQValidator( TQObject * tqparent, const char *name )
+ : TQObject( tqparent, name )
+{
+}
+
+
+/*!
+ Destroys the validator, freeing any storage and other resources
+ used.
+*/
+
+TQValidator::~TQValidator()
+{
+}
+
+
+/*!
+ \fn TQValidator::State TQValidator::validate( TQString& input, int& pos ) const
+
+ This pure virtual function returns \c Invalid if \a input is
+ invalid according to this validator's rules, \c Intermediate if it
+ is likely that a little more editing will make the input
+ acceptable (e.g. the user types '4' into a widget which accepts
+ integers between 10 and 99) and \c Acceptable if the input is
+ valid.
+
+ The function can change \a input and \a pos (the cursor position)
+ if it wants to.
+*/
+
+
+/*!
+ \fn void TQValidator::fixup( TQString & input ) const
+
+ This function attempts to change \a input to be valid according to
+ this validator's rules. It need not result in a valid string:
+ callers of this function must re-test afterwards; the default does
+ nothing.
+
+ Reimplementations of this function can change \a input even if
+ they do not produce a valid string. For example, an ISBN validator
+ might want to delete every character except digits and "-", even
+ if the result is still not a valid ISBN; a surname validator might
+ want to remove whitespace from the start and end of the string,
+ even if the resulting string is not in the list of accepted
+ surnames.
+*/
+
+void TQValidator::fixup( TQString & ) const
+{
+}
+
+
+/*!
+ \class TQIntValidator
+ \brief The TQIntValidator class provides a validator which ensures
+ that a string tqcontains a valid integer within a specified range.
+
+ \ingroup misc
+
+ Example of use:
+
+ \code
+ TQValidator* validator = new TQIntValidator( 100, 999, this );
+ TQLineEdit* edit = new TQLineEdit( this );
+
+ // the edit lineedit will only accept integers between 100 and 999
+ edit->setValidator( validator );
+ \endcode
+
+ Below we present some examples of validators. In practice they would
+ normally be associated with a widget as in the example above.
+
+ \code
+ TQString str;
+ int pos = 0;
+ TQIntValidator v( 100, 999, this );
+
+ str = "1";
+ v.validate( str, pos ); // returns Intermediate
+ str = "12";
+ v.validate( str, pos ); // returns Intermediate
+
+ str = "123";
+ v.validate( str, pos ); // returns Acceptable
+ str = "678";
+ v.validate( str, pos ); // returns Acceptable
+
+ str = "1234";
+ v.validate( str, pos ); // returns Invalid
+ str = "-123";
+ v.validate( str, pos ); // returns Invalid
+ str = "abc";
+ v.validate( str, pos ); // returns Invalid
+ str = "12cm";
+ v.validate( str, pos ); // returns Invalid
+ \endcode
+
+ The minimum and maximum values are set in one call with setRange()
+ or individually with setBottom() and setTop().
+
+ \sa TQDoubleValidator TQRegExpValidator
+*/
+
+
+/*!
+ Constructs a validator called \a name with tqparent \a tqparent, that
+ accepts all integers.
+*/
+
+TQIntValidator::TQIntValidator( TQObject * tqparent, const char *name )
+ : TQValidator( tqparent, name )
+{
+ b = INT_MIN;
+ t = INT_MAX;
+}
+
+
+/*!
+ Constructs a validator called \a name with tqparent \a tqparent, that
+ accepts integers from \a minimum to \a maximum inclusive.
+*/
+
+TQIntValidator::TQIntValidator( int minimum, int maximum,
+ TQObject * tqparent, const char* name )
+ : TQValidator( tqparent, name )
+{
+ b = minimum;
+ t = maximum;
+}
+
+
+/*!
+ Destroys the validator, freeing any resources allocated.
+*/
+
+TQIntValidator::~TQIntValidator()
+{
+ // nothing
+}
+
+
+/*!
+ Returns \c Acceptable if the \a input is an integer within the
+ valid range, \c Intermediate if the \a input is an integer outside
+ the valid range and \c Invalid if the \a input is not an integer.
+
+ Note: If the valid range consists of just positive integers (e.g. 32 - 100)
+ and \a input is a negative integer then Invalid is returned.
+
+ \code
+ int pos = 0;
+ s = "abc";
+ v.validate( s, pos ); // returns Invalid
+
+ s = "5";
+ v.validate( s, pos ); // returns Intermediate
+
+ s = "50";
+ v.validate( s, pos ); // returns Valid
+ \endcode
+*/
+
+TQValidator::State TQIntValidator::validate( TQString & input, int & ) const
+{
+ TQString stripped = input.stripWhiteSpace();
+ if ( stripped.isEmpty() || (b < 0 && stripped == "-") )
+ return Intermediate;
+ bool ok;
+ long entered = input.toLong( &ok );
+ if ( !ok || (entered < 0 && b >= 0) ) {
+ return Invalid;
+ } else if ( entered >= b && entered <= t ) {
+ return Acceptable;
+ } else {
+ if ( entered >= 0 )
+ return ( entered > t ) ? Invalid : Intermediate;
+ else
+ return ( entered < b ) ? Invalid : Intermediate;
+ }
+}
+
+
+/*!
+ Sets the range of the validator to only accept integers between \a
+ bottom and \a top inclusive.
+*/
+
+void TQIntValidator::setRange( int bottom, int top )
+{
+ b = bottom;
+ t = top;
+}
+
+
+/*!
+ \property TQIntValidator::bottom
+ \brief the validator's lowest acceptable value
+
+ \sa setRange()
+*/
+void TQIntValidator::setBottom( int bottom )
+{
+ setRange( bottom, top() );
+}
+
+/*!
+ \property TQIntValidator::top
+ \brief the validator's highest acceptable value
+
+ \sa setRange()
+*/
+void TQIntValidator::setTop( int top )
+{
+ setRange( bottom(), top );
+}
+
+
+#ifndef TQT_NO_REGEXP
+
+/*!
+ \class TQDoubleValidator
+
+ \brief The TQDoubleValidator class provides range checking of
+ floating-point numbers.
+
+ \ingroup misc
+
+ TQDoubleValidator provides an upper bound, a lower bound and a
+ limit on the number of digits after the decimal point. It does not
+ provide a fixup() function.
+
+ You can set the acceptable range in one call with setRange(), or
+ with setBottom() and setTop(). Set the number of decimal places
+ with setDecimals(). The validate() function returns the validation
+ state.
+
+ \sa TQIntValidator TQRegExpValidator
+*/
+
+/*!
+ Constructs a validator object with tqparent \a tqparent, called \a
+ name, which accepts any double.
+*/
+
+TQDoubleValidator::TQDoubleValidator( TQObject * tqparent, const char *name )
+ : TQValidator( tqparent, name )
+{
+ b = -HUGE_VAL;
+ t = HUGE_VAL;
+ d = 1000;
+}
+
+
+/*!
+ Constructs a validator object with tqparent \a tqparent, called \a
+ name. This validator will accept doubles from \a bottom to \a top
+ inclusive, with up to \a decimals digits after the decimal point.
+*/
+
+TQDoubleValidator::TQDoubleValidator( double bottom, double top, int decimals,
+ TQObject * tqparent, const char* name )
+ : TQValidator( tqparent, name )
+{
+ b = bottom;
+ t = top;
+ d = decimals;
+}
+
+
+/*!
+ Destroys the validator, freeing any resources used.
+*/
+
+TQDoubleValidator::~TQDoubleValidator()
+{
+}
+
+
+/*!
+ Returns \c Acceptable if the string \a input tqcontains a double
+ that is within the valid range and is in the correct format.
+
+ Returns \c Intermediate if \a input tqcontains a double that is
+ outside the range or is in the wrong format, e.g. with too many
+ digits after the decimal point or is empty.
+
+ Returns \c Invalid if the \a input is not a double.
+
+ Note: If the valid range consists of just positive doubles (e.g. 0.0 - 100.0)
+ and \a input is a negative double then Invalid is returned.
+*/
+
+TQValidator::State TQDoubleValidator::validate( TQString & input, int & ) const
+{
+ TQRegExp empty( TQString::tqfromLatin1(" *-?\\.? *") );
+ if ( b >= 0 &&
+ input.stripWhiteSpace().startsWith(TQString::tqfromLatin1("-")) )
+ return Invalid;
+ if ( empty.exactMatch(input) )
+ return Intermediate;
+ bool ok = TRUE;
+ double entered = input.toDouble( &ok );
+ int nume = input.tqcontains( 'e', FALSE );
+ if ( !ok ) {
+ // explicit exponent regexp
+ TQRegExp expexpexp( TQString::tqfromLatin1("[Ee][+-]?\\d*$") );
+ int eeePos = expexpexp.search( input );
+ if ( eeePos > 0 && nume == 1 ) {
+ TQString mantissa = input.left( eeePos );
+ entered = mantissa.toDouble( &ok );
+ if ( !ok )
+ return Invalid;
+ } else if ( eeePos == 0 ) {
+ return Intermediate;
+ } else {
+ return Invalid;
+ }
+ }
+
+ int i = input.tqfind( '.' );
+ if ( i >= 0 && nume == 0 ) {
+ // has decimal point (but no E), now count digits after that
+ i++;
+ int j = i;
+ while( input[j].isDigit() )
+ j++;
+ if ( j - i > d )
+ return Intermediate;
+ }
+
+ if ( entered < b || entered > t )
+ return Intermediate;
+ else
+ return Acceptable;
+}
+
+
+/*!
+ Sets the validator to accept doubles from \a minimum to \a maximum
+ inclusive, with at most \a decimals digits after the decimal
+ point.
+*/
+
+void TQDoubleValidator::setRange( double minimum, double maximum, int decimals )
+{
+ b = minimum;
+ t = maximum;
+ d = decimals;
+}
+
+/*!
+ \property TQDoubleValidator::bottom
+ \brief the validator's minimum acceptable value
+
+ \sa setRange()
+*/
+
+void TQDoubleValidator::setBottom( double bottom )
+{
+ setRange( bottom, top(), decimals() );
+}
+
+
+/*!
+ \property TQDoubleValidator::top
+ \brief the validator's maximum acceptable value
+
+ \sa setRange()
+*/
+
+void TQDoubleValidator::setTop( double top )
+{
+ setRange( bottom(), top, decimals() );
+}
+
+/*!
+ \property TQDoubleValidator::decimals
+ \brief the validator's maximum number of digits after the decimal point
+
+ \sa setRange()
+*/
+
+void TQDoubleValidator::setDecimals( int decimals )
+{
+ setRange( bottom(), top(), decimals );
+}
+
+
+/*!
+ \class TQRegExpValidator
+ \brief The TQRegExpValidator class is used to check a string
+ against a regular expression.
+
+ \ingroup misc
+
+ TQRegExpValidator tqcontains a regular expression, "regexp", used to
+ determine whether an input string is \c Acceptable, \c
+ Intermediate or \c Invalid.
+
+ The regexp is treated as if it begins with the start of string
+ assertion, <b>^</b>, and ends with the end of string assertion
+ <b>$</b> so the match is against the entire input string, or from
+ the given position if a start position greater than zero is given.
+
+ For a brief introduction to TQt's regexp engine see \l TQRegExp.
+
+ Example of use:
+ \code
+ // regexp: optional '-' followed by between 1 and 3 digits
+ TQRegExp rx( "-?\\d{1,3}" );
+ TQValidator* validator = new TQRegExpValidator( rx, this );
+
+ TQLineEdit* edit = new TQLineEdit( this );
+ edit->setValidator( validator );
+ \endcode
+
+ Below we present some examples of validators. In practice they would
+ normally be associated with a widget as in the example above.
+
+ \code
+ // integers 1 to 9999
+ TQRegExp rx( "[1-9]\\d{0,3}" );
+ // the validator treats the regexp as "^[1-9]\\d{0,3}$"
+ TQRegExpValidator v( rx, 0 );
+ TQString s;
+ int pos = 0;
+
+ s = "0"; v.validate( s, pos ); // returns Invalid
+ s = "12345"; v.validate( s, pos ); // returns Invalid
+ s = "1"; v.validate( s, pos ); // returns Acceptable
+
+ rx.setPattern( "\\S+" ); // one or more non-whitespace characters
+ v.setRegExp( rx );
+ s = "myfile.txt"; v.validate( s, pos ); // Returns Acceptable
+ s = "my file.txt"; v.validate( s, pos ); // Returns Invalid
+
+ // A, B or C followed by exactly five digits followed by W, X, Y or Z
+ rx.setPattern( "[A-C]\\d{5}[W-Z]" );
+ v.setRegExp( rx );
+ s = "a12345Z"; v.validate( s, pos ); // Returns Invalid
+ s = "A12345Z"; v.validate( s, pos ); // Returns Acceptable
+ s = "B12"; v.validate( s, pos ); // Returns Intermediate
+
+ // match most 'readme' files
+ rx.setPattern( "read\\S?me(\.(txt|asc|1st))?" );
+ rx.setCaseSensitive( FALSE );
+ v.setRegExp( rx );
+ s = "readme"; v.validate( s, pos ); // Returns Acceptable
+ s = "README.1ST"; v.validate( s, pos ); // Returns Acceptable
+ s = "read me.txt"; v.validate( s, pos ); // Returns Invalid
+ s = "readm"; v.validate( s, pos ); // Returns Intermediate
+ \endcode
+
+ \sa TQRegExp TQIntValidator TQDoubleValidator
+*/
+
+/*!
+ Constructs a validator that accepts any string (including an empty
+ one) as valid. The object's tqparent is \a tqparent and its name is \a
+ name.
+*/
+
+TQRegExpValidator::TQRegExpValidator( TQObject *tqparent, const char *name )
+ : TQValidator( tqparent, name ), r( TQString::tqfromLatin1(".*") )
+{
+}
+
+/*!
+ Constructs a validator which accepts all strings that match the
+ regular expression \a rx. The object's tqparent is \a tqparent and its
+ name is \a name.
+
+ The match is made against the entire string, e.g. if the regexp is
+ <b>[A-Fa-f0-9]+</b> it will be treated as <b>^[A-Fa-f0-9]+$</b>.
+*/
+
+TQRegExpValidator::TQRegExpValidator( const TQRegExp& rx, TQObject *tqparent,
+ const char *name )
+ : TQValidator( tqparent, name ), r( rx )
+{
+}
+
+/*!
+ Destroys the validator, freeing any resources allocated.
+*/
+
+TQRegExpValidator::~TQRegExpValidator()
+{
+}
+
+/*!
+ Returns \c Acceptable if \a input is matched by the regular
+ expression for this validator, \c Intermediate if it has matched
+ partially (i.e. could be a valid match if additional valid
+ characters are added), and \c Invalid if \a input is not matched.
+
+ The \a pos parameter is set to the length of the \a input parameter.
+
+ For example, if the regular expression is <b>\\w\\d\\d</b> (that
+ is, word-character, digit, digit) then "A57" is \c Acceptable,
+ "E5" is \c Intermediate and "+9" is \c Invalid.
+
+ \sa TQRegExp::match() TQRegExp::search()
+*/
+
+TQValidator::State TQRegExpValidator::validate( TQString& input, int& pos ) const
+{
+ if ( r.exactMatch(input) ) {
+ return Acceptable;
+ } else {
+ if ( ((TQRegExp&) r).matchedLength() == (int) input.length() ) {
+ return Intermediate;
+ } else {
+ pos = input.length();
+ return Invalid;
+ }
+ }
+}
+
+/*!
+ Sets the regular expression used for validation to \a rx.
+
+ \sa regExp()
+*/
+
+void TQRegExpValidator::setRegExp( const TQRegExp& rx )
+{
+ r = rx;
+}
+
+/*!
+ \fn const TQRegExp& TQRegExpValidator::regExp() const
+
+ Returns the regular expression used for validation.
+
+ \sa setRegExp()
+*/
+
+#endif
+
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqvalidator.h b/tqtinterface/qt4/src/widgets/tqvalidator.h
new file mode 100644
index 0000000..16f9db1
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqvalidator.h
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Definition of validator classes
+**
+** Created : 970610
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQVALIDATOR_H
+#define TQVALIDATOR_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#include "tqstring.h" // char*->TQString conversion
+#include "tqregexp.h" // TQString->TQRegExp conversion
+#endif // TQT_H
+
+#ifndef TQT_NO_VALIDATOR
+
+
+class TQ_EXPORT TQValidator : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQValidator( TQObject * tqparent, const char *name = 0 );
+ ~TQValidator();
+
+ enum State { Invalid, Intermediate, Valid=Intermediate, Acceptable };
+
+ virtual State validate( TQString &, int & ) const = 0;
+ virtual void fixup( TQString & ) const;
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQValidator( const TQValidator & );
+ TQValidator& operator=( const TQValidator & );
+#endif
+};
+
+
+class TQ_EXPORT TQIntValidator : public TQValidator
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( int bottom READ bottom WRITE setBottom )
+ Q_PROPERTY( int top READ top WRITE setTop )
+
+public:
+ TQIntValidator( TQObject * tqparent, const char *name = 0 );
+ TQIntValidator( int bottom, int top,
+ TQObject * tqparent, const char *name = 0 );
+ ~TQIntValidator();
+
+ TQValidator::State validate( TQString &, int & ) const;
+
+ void setBottom( int );
+ void setTop( int );
+ virtual void setRange( int bottom, int top );
+
+ int bottom() const { return b; }
+ int top() const { return t; }
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQIntValidator( const TQIntValidator & );
+ TQIntValidator& operator=( const TQIntValidator & );
+#endif
+
+ int b, t;
+};
+
+#ifndef TQT_NO_REGEXP
+
+class TQ_EXPORT TQDoubleValidator : public TQValidator
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( double bottom READ bottom WRITE setBottom )
+ Q_PROPERTY( double top READ top WRITE setTop )
+ Q_PROPERTY( int decimals READ decimals WRITE setDecimals )
+
+public:
+ TQDoubleValidator( TQObject * tqparent, const char *name = 0 );
+ TQDoubleValidator( double bottom, double top, int decimals,
+ TQObject * tqparent, const char *name = 0 );
+ ~TQDoubleValidator();
+
+ TQValidator::State validate( TQString &, int & ) const;
+
+ virtual void setRange( double bottom, double top, int decimals = 0 );
+ void setBottom( double );
+ void setTop( double );
+ void setDecimals( int );
+
+ double bottom() const { return b; }
+ double top() const { return t; }
+ int decimals() const { return d; }
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQDoubleValidator( const TQDoubleValidator & );
+ TQDoubleValidator& operator=( const TQDoubleValidator & );
+#endif
+
+ double b, t;
+ int d;
+};
+
+
+class TQ_EXPORT TQRegExpValidator : public TQValidator
+{
+ Q_OBJECT
+ TQ_OBJECT
+ // Q_PROPERTY( TQRegExp regExp READ regExp WRITE setRegExp )
+
+public:
+ TQRegExpValidator( TQObject *tqparent, const char *name = 0 );
+ TQRegExpValidator( const TQRegExp& rx, TQObject *tqparent,
+ const char *name = 0 );
+ ~TQRegExpValidator();
+
+ virtual TQValidator::State validate( TQString& input, int& pos ) const;
+
+ void setRegExp( const TQRegExp& rx );
+ const TQRegExp& regExp() const { return r; }
+
+private:
+#if defined(TQ_DISABLE_COPY)
+ TQRegExpValidator( const TQRegExpValidator& );
+ TQRegExpValidator& operator=( const TQRegExpValidator& );
+#endif
+
+ TQRegExp r;
+};
+#endif // TQT_NO_REGEXP
+
+
+#endif // TQT_NO_VALIDATOR
+
+#endif // TQVALIDATOR_H
diff --git a/tqtinterface/qt4/src/widgets/tqvbox.cpp b/tqtinterface/qt4/src/widgets/tqvbox.cpp
new file mode 100644
index 0000000..fbfba79
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqvbox.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Implementation of vertical box tqlayout widget class
+**
+** Created : 990124
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+
+#include "tqvbox.h"
+#ifndef TQT_NO_VBOX
+
+/*!
+ \class TQVBox tqvbox.h
+ \brief The TQVBox widget provides vertical tqgeometry management of
+ its child widgets.
+
+ \ingroup geomanagement
+ \ingroup appearance
+ \ingroup organizers
+
+ All its child widgets will be placed vertically and sized
+ according to their tqsizeHint()s.
+
+ \img qvbox-m.png TQVBox
+
+ \sa TQHBox
+*/
+
+
+/*!
+ Constructs a vbox widget called \a name with tqparent \a tqparent and
+ widget flags \a f.
+ */
+TQVBox::TQVBox( TQWidget *tqparent, const char *name, WFlags f )
+ :TQHBox( FALSE, tqparent, name, f )
+{
+}
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqvbox.h b/tqtinterface/qt4/src/widgets/tqvbox.h
new file mode 100644
index 0000000..cccad24
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqvbox.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Definition of vertical box tqlayout widget class
+**
+** Created : 990124
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQVBOX_H
+#define TQVBOX_H
+
+#ifndef TQT_H
+#include "tqhbox.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_VBOX
+
+class TQ_EXPORT TQVBox : public TQHBox
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQVBox( TQWidget* tqparent=0, const char* name=0, WFlags f=0 );
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQVBox( const TQVBox & );
+ TQVBox& operator=( const TQVBox & );
+#endif
+};
+
+#endif // TQT_NO_VBOX
+
+#endif // TQVBOX_H
diff --git a/tqtinterface/qt4/src/widgets/tqvbuttongroup.cpp b/tqtinterface/qt4/src/widgets/tqvbuttongroup.cpp
new file mode 100644
index 0000000..d7a4490
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqvbuttongroup.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Implementation of TQVButtonGroup class
+**
+** Created : 990602
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqvbuttongroup.h"
+#ifndef TQT_NO_VBUTTONGROUP
+
+/*!
+ \class TQVButtonGroup tqvbuttongroup.h
+ \brief The TQVButtonGroup widget organizes TQButton widgets in a
+ vertical column.
+
+ \ingroup geomanagement
+ \ingroup organizers
+ \ingroup appearance
+
+ TQVButtonGroup is a convenience class that offers a thin layer on top
+ of TQButtonGroup. Think of it as a TQVBox that offers a frame with a
+ title and is specifically designed for buttons.
+
+ \img qbuttongroup-v.png TQButtonGroup
+
+ \sa TQHButtonGroup
+*/
+
+/*!
+ Constructs a vertical button group with no title.
+
+ The \a tqparent and \a name arguments are passed on to the TQWidget
+ constructor.
+*/
+TQVButtonGroup::TQVButtonGroup( TQWidget *tqparent, const char *name )
+ : TQButtonGroup( 1, Qt::Horizontal /* sic! */, tqparent, name )
+{
+}
+
+/*!
+ Constructs a vertical button group with the title \a title.
+
+ The \a tqparent and \a name arguments are passed on to the TQWidget
+ constructor.
+*/
+
+TQVButtonGroup::TQVButtonGroup( const TQString &title, TQWidget *tqparent,
+ const char *name )
+ : TQButtonGroup( 1, Qt::Horizontal /* sic! */, title, tqparent, name )
+{
+}
+
+/*!
+ Destroys the vertical button group, deleting its child widgets.
+*/
+TQVButtonGroup::~TQVButtonGroup()
+{
+}
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqvbuttongroup.h b/tqtinterface/qt4/src/widgets/tqvbuttongroup.h
new file mode 100644
index 0000000..faccef2
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqvbuttongroup.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Definition of TQVButtonGroup class
+**
+** Created : 990602
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQVBUTTONGROUP_H
+#define TQVBUTTONGROUP_H
+
+#ifndef TQT_H
+#include "tqbuttongroup.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_VBUTTONGROUP
+
+class TQ_EXPORT TQVButtonGroup : public TQButtonGroup
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQVButtonGroup( TQWidget* tqparent=0, const char* name=0 );
+ TQVButtonGroup( const TQString &title, TQWidget* tqparent=0, const char* name=0 );
+
+ ~TQVButtonGroup();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQVButtonGroup( const TQVButtonGroup & );
+ TQVButtonGroup &operator=( const TQVButtonGroup & );
+#endif
+};
+
+
+#endif // TQT_NO_VBUTTONGROUP
+
+#endif // TQVBUTTONGROUP_H
diff --git a/tqtinterface/qt4/src/widgets/tqvgroupbox.cpp b/tqtinterface/qt4/src/widgets/tqvgroupbox.cpp
new file mode 100644
index 0000000..38ccfa1
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqvgroupbox.cpp
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Implementation of TQVGroupBox class
+**
+** Created : 990602
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqvgroupbox.h"
+#ifndef TQT_NO_VGROUPBOX
+
+/*!
+ \class TQVGroupBox tqvgroupbox.h
+ \brief The TQVGroupBox widget organizes a group of widgets in a
+ vertical column.
+
+ \ingroup geomanagement
+ \ingroup appearance
+ \ingroup organizers
+
+ TQVGroupBox is a convenience class that offers a thin layer on top of
+ TQGroupBox. Think of it as a TQVBox that offers a frame with a title.
+
+ \img qgroupboxes.png Group Boxes
+
+ \sa TQHGroupBox
+*/
+
+/*!
+ Constructs a vertical group box with no title.
+
+ The \a tqparent and \a name arguments are passed on to the TQWidget
+ constructor.
+*/
+TQVGroupBox::TQVGroupBox( TQWidget *tqparent, const char *name )
+ : TQGroupBox( 1, Qt::Horizontal, tqparent, name )
+{
+}
+
+/*!
+ Constructs a vertical group box with the title \a title.
+
+ The \a tqparent and \a name arguments are passed on to the TQWidget
+ constructor.
+*/
+
+TQVGroupBox::TQVGroupBox( const TQString &title, TQWidget *tqparent,
+ const char *name )
+ : TQGroupBox( 1, Qt::Horizontal, title, tqparent, name )
+{
+}
+
+/*!
+ Destroys the vertical group box, deleting its child widgets.
+*/
+TQVGroupBox::~TQVGroupBox()
+{
+}
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqvgroupbox.h b/tqtinterface/qt4/src/widgets/tqvgroupbox.h
new file mode 100644
index 0000000..142172d
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqvgroupbox.h
@@ -0,0 +1,69 @@
+/**********************************************************************
+**
+** Definition of TQVGroupBox widget class
+**
+** Created : 990602
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQVGROUPBOX_H
+#define TQVGROUPBOX_H
+
+#ifndef TQT_H
+#include "tqgroupbox.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_VGROUPBOX
+
+class TQ_EXPORT TQVGroupBox : public TQGroupBox
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQVGroupBox( TQWidget* tqparent=0, const char* name=0 );
+ TQVGroupBox( const TQString &title, TQWidget* tqparent=0, const char* name=0 );
+
+ ~TQVGroupBox();
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQVGroupBox( const TQVGroupBox & );
+ TQVGroupBox &operator=( const TQVGroupBox & );
+#endif
+};
+
+#endif // TQT_NO_VGROUPBOX
+
+#endif // TQVGROUPBOX_H
diff --git a/tqtinterface/qt4/src/widgets/tqwhatsthis.cpp b/tqtinterface/qt4/src/widgets/tqwhatsthis.cpp
new file mode 100644
index 0000000..80e984c
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqwhatsthis.cpp
@@ -0,0 +1,1004 @@
+/****************************************************************************
+**
+** Implementation of TQWhatsThis class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwhatsthis.h"
+#ifndef TQT_NO_WHATSTHIS
+#include "tqapplication.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqpixmap.h"
+#include "tqpainter.h"
+#include "tqtimer.h"
+#include "tqptrdict.h"
+#include "tqtoolbutton.h"
+#include "tqshared.h"
+#include "tqcursor.h"
+#include "tqbitmap.h"
+#include "tqtooltip.h"
+#include "tqsimplerichtext.h"
+#include "tqstylesheet.h"
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+#include "tqaccessible.h"
+#endif
+#if defined(TQ_WS_WIN)
+#include "tqt_windows.h"
+#ifndef SPI_GETDROPSHADOW
+#define SPI_GETDROPSHADOW 0x1024
+#endif
+#endif
+
+/*!
+ \class TQWhatsThis tqwhatsthis.h
+ \brief The TQWhatsThis class provides a simple description of any
+ widget, i.e. answering the question "What's this?".
+
+ \ingroup helpsystem
+ \mainclass
+
+ "What's this?" help is part of an application's online help system
+ that provides users with information about functionality, usage,
+ background etc., in various levels of detail from short tool tips
+ to full text browsing help windows.
+
+ TQWhatsThis provides a single window with an explanatory text that
+ pops up when the user asks "What's this?". The default way to do
+ this is to focus the relevant widget and press Shift+F1. The help
+ text appears immediately; it goes away as soon as the user does
+ something else.
+
+ (Note that if there is an accelerator for Shift+F1, this mechanism
+ will not work.)
+
+ To add "What's this?" text to a widget you simply call
+ TQWhatsThis::add() for the widget. For example, to assign text to a
+ menu item, call TQMenuData::setWhatsThis(); for a global
+ accelerator key, call TQAccel::setWhatsThis() and If you're using
+ actions, use TQAction::setWhatsThis().
+
+ The text can be either rich text or plain text. If you specify a
+ rich text formatted string, it will be rendered using the default
+ stylesheet. This makes it possible to embed images. See
+ TQStyleSheet::defaultSheet() for details.
+
+ \quotefile action/application.cpp
+ \skipto fileOpenText
+ \printuntil setWhatsThis
+
+ An alternative way to enter "What's this?" mode is to use the
+ ready-made tool bar tool button from
+ TQWhatsThis::whatsThisButton(). By invoking this context help
+ button (in the picture below the first one from the right) the
+ user switches into "What's this?" mode. If they now click on a
+ widget the appropriate help text is shown. The mode is left when
+ help is given or when the user presses Esc.
+
+ \img whatsthis.png
+
+ If you are using TQMainWindow you can also use the
+ TQMainWindow::whatsThis() slot to invoke the mode from a menu item.
+
+ For more control you can create a dedicated TQWhatsThis object for
+ a special widget. By subclassing and reimplementing
+ TQWhatsThis::text() it is possible to have different help texts,
+ depending on the position of the mouse click. By reimplementing
+ TQWhatsThis::clicked() it is possible to have hyperlinks inside the
+ help texts.
+
+ If you wish to control the "What's this?" behavior of a widget
+ manually see TQWidget::customWhatsThis().
+
+ The What's This object can be removed using TQWhatsThis::remove(),
+ although this is rarely necessary because it is automatically
+ removed when the widget is destroyed.
+
+ \sa TQToolTip
+*/
+
+// a special button
+class TQWhatsThisButton: public TQToolButton
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ TQWhatsThisButton( TQWidget * tqparent, const char * name );
+ ~TQWhatsThisButton();
+
+public Q_SLOTS:
+ void mouseReleased();
+
+};
+
+
+class TQWhatsThat : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQWhatsThat( TQWidget* w, const TQString& txt, TQWidget* tqparent, const char* name );
+ ~TQWhatsThat() ;
+
+public Q_SLOTS:
+ void hide();
+ inline void widgetDestroyed() { widget = 0; }
+
+protected:
+ void mousePressEvent( TQMouseEvent* );
+ void mouseReleaseEvent( TQMouseEvent* );
+ void mouseMoveEvent( TQMouseEvent* );
+ void keyPressEvent( TQKeyEvent* );
+ void paintEvent( TQPaintEvent* );
+
+private:
+ TQString text;
+#ifndef TQT_NO_RICHTEXT
+ TQSimpleRichText* doc;
+#endif
+ TQString anchor;
+ bool pressed;
+ TQWidget* widget;
+};
+
+
+class TQWhatsThisPrivate: public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+
+ // an item for storing texts
+ struct WhatsThisItem: public TQShared
+ {
+ WhatsThisItem(): TQShared() { whatsthis = 0; }
+ ~WhatsThisItem();
+ TQString s;
+ TQWhatsThis* whatsthis;
+ };
+
+ // the (these days pretty small) state machine
+ enum State { Inactive, Waiting };
+
+ TQWhatsThisPrivate();
+ ~TQWhatsThisPrivate();
+
+ bool eventFilter( TQObject *, TQEvent * );
+
+ WhatsThisItem* newItem( TQWidget * widget );
+ void add( TQWidget * widget, TQWhatsThis* special );
+ void add( TQWidget * widget, const TQString& text );
+
+ // say it.
+ void say( TQWidget *, const TQString&, const TQPoint& );
+
+ // setup and teardown
+ static void setUpWhatsThis();
+
+ void enterWhatsThisMode();
+ void leaveWhatsThisMode();
+
+ // variables
+ TQWhatsThat * whatsThat;
+ TQPtrDict<WhatsThisItem> * dict;
+ TQPtrDict<TQWidget> * tlw;
+ TQPtrDict<TQWhatsThisButton> * buttons;
+ State state;
+
+private Q_SLOTS:
+ void cleanupWidget()
+ {
+ const TQObject* o = TQT_TQOBJECT(sender());
+ if ( o->isWidgetType() ) // sanity
+ TQWhatsThis::remove((TQWidget*)o);
+ }
+
+};
+
+// static, but static the less-typing way
+static TQWhatsThisPrivate * wt = 0;
+
+// shadowWidth not const, for XP drop-shadow-fu turns it to 0
+static int shadowWidth = 6; // also used as '5' and '6' and even '8' below
+const int vMargin = 8;
+const int hMargin = 12;
+
+// Lets TQPopupMenu destroy the TQWhatsThat.
+void qWhatsThisBDH()
+{
+ if ( wt && wt->whatsThat )
+ wt->whatsThat->hide();
+}
+
+
+TQWhatsThat::TQWhatsThat( TQWidget* w, const TQString& txt, TQWidget* tqparent, const char* name )
+ : TQWidget( tqparent, name, WType_Popup ), text( txt ), pressed( FALSE ), widget( w )
+{
+
+ setBackgroundMode( TQt::NoBackground );
+ setPalette( TQToolTip::palette() );
+ setMouseTracking( TRUE );
+#ifndef TQT_NO_CURSOR
+ setCursor( Qt::ArrowCursor );
+#endif
+
+ if ( widget )
+ connect( widget, TQT_SIGNAL( destroyed() ), this, TQT_SLOT( widgetDestroyed() ) );
+
+
+ TQRect r;
+#ifndef TQT_NO_RICHTEXT
+ doc = 0;
+ if ( TQStyleSheet::mightBeRichText( text ) ) {
+ TQFont f = TQApplication::font( this );
+ doc = new TQSimpleRichText( text, f );
+ doc->adjustSize();
+ r.setRect( 0, 0, doc->width(), doc->height() );
+ }
+ else
+#endif
+ {
+ int sw = TQApplication::desktop()->width() / 3;
+ if ( sw < 200 )
+ sw = 200;
+ else if ( sw > 300 )
+ sw = 300;
+
+ r = fontMetrics().boundingRect( 0, 0, sw, 1000,
+ TQt::AlignAuto + TQt::AlignTop + TQt::WordBreak + TQt::ExpandTabs,
+ text );
+ }
+#if defined(TQ_WS_WIN)
+ if ( (qWinVersion()&WV_NT_based) > WV_2000 ) {
+ BOOL shadow;
+ SystemParametersInfo( SPI_GETDROPSHADOW, 0, &shadow, 0 );
+ shadowWidth = shadow ? 0 : 6;
+ }
+#endif
+ resize( r.width() + 2*hMargin + shadowWidth, r.height() + 2*vMargin + shadowWidth );
+}
+
+TQWhatsThat::~TQWhatsThat()
+{
+ if ( wt && wt->whatsThat == this )
+ wt->whatsThat = 0;
+#ifndef TQT_NO_RICHTEXT
+ if ( doc )
+ delete doc;
+#endif
+}
+
+void TQWhatsThat::hide()
+{
+ TQWidget::hide();
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpEnd );
+#endif
+}
+
+void TQWhatsThat::mousePressEvent( TQMouseEvent* e )
+{
+ pressed = TRUE;
+ if ( e->button() == Qt::LeftButton && TQT_TQRECT_OBJECT(rect()).tqcontains( e->pos() ) ) {
+#ifndef TQT_NO_RICHTEXT
+ if ( doc )
+ anchor = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin) );
+#endif
+ return;
+ }
+ hide();
+}
+
+void TQWhatsThat::mouseReleaseEvent( TQMouseEvent* e )
+{
+ if ( !pressed )
+ return;
+#ifndef TQT_NO_RICHTEXT
+ if ( e->button() == Qt::LeftButton && doc && TQT_TQRECT_OBJECT(rect()).tqcontains( e->pos() ) ) {
+ TQString a = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin ) );
+ TQString href;
+ if ( anchor == a )
+ href = a;
+ anchor = TQString::null;
+ if ( widget && wt && wt->dict ) {
+ TQWhatsThisPrivate::WhatsThisItem * i = wt->dict->tqfind( widget );
+ if ( i && i->whatsthis && !i->whatsthis->clicked( href ) )
+ return;
+ }
+ }
+#endif
+ hide();
+}
+
+void TQWhatsThat::mouseMoveEvent( TQMouseEvent* e)
+{
+#ifndef TQT_NO_RICHTEXT
+#ifndef TQT_NO_CURSOR
+ if ( !doc )
+ return;
+ TQString a = doc->anchorAt( e->pos() - TQPoint( hMargin, vMargin ) );
+ if ( !a.isEmpty() )
+ setCursor( Qt::PointingHandCursor );
+ else
+ setCursor( Qt::ArrowCursor );
+#endif
+#endif
+}
+
+
+void TQWhatsThat::keyPressEvent( TQKeyEvent* )
+{
+ hide();
+}
+
+
+
+void TQWhatsThat::paintEvent( TQPaintEvent* )
+{
+ bool drawShadow = TRUE;
+#if defined(TQ_WS_WIN)
+ if ( (qWinVersion()&WV_NT_based) > WV_2000 ) {
+ BOOL shadow;
+ SystemParametersInfo( SPI_GETDROPSHADOW, 0, &shadow, 0 );
+ drawShadow = !shadow;
+ }
+#elif defined(TQ_WS_MACX)
+ drawShadow = FALSE; //never draw it on OS X we get it for free
+#endif
+
+ TQRect r = rect();
+ if ( drawShadow )
+ r.addCoords( 0, 0, -shadowWidth, -shadowWidth );
+ TQPainter p( this);
+ p.setPen( tqcolorGroup().foreground() );
+ p.drawRect( r );
+ p.setPen( tqcolorGroup().mid() );
+ p.setBrush( tqcolorGroup().brush( TQColorGroup::Background ) );
+ int w = r.width();
+ int h = r.height();
+ p.drawRect( 1, 1, w-2, h-2 );
+ if ( drawShadow ) {
+ p.setPen( tqcolorGroup().shadow() );
+ p.drawPoint( w + 5, 6 );
+ p.drawLine( w + 3, 6, w + 5, 8 );
+ p.drawLine( w + 1, 6, w + 5, 10 );
+ int i;
+ for( i=7; i < h; i += 2 )
+ p.drawLine( w, i, w + 5, i + 5 );
+ for( i = w - i + h; i > 6; i -= 2 )
+ p.drawLine( i, h, i + 5, h + 5 );
+ for( ; i > 0 ; i -= 2 )
+ p.drawLine( 6, h + 6 - i, i + 5, h + 5 );
+ }
+ p.setPen( tqcolorGroup().foreground() );
+ r.addCoords( hMargin, vMargin, -hMargin, -vMargin );
+
+#ifndef TQT_NO_RICHTEXT
+ if ( doc ) {
+ doc->draw( &p, r.x(), r.y(), r, tqcolorGroup(), 0 );
+ }
+ else
+#endif
+ {
+ p.drawText( r, TQt::AlignAuto + TQt::AlignTop + TQt::WordBreak + TQt::ExpandTabs, text );
+ }
+}
+
+// the item
+TQWhatsThisPrivate::WhatsThisItem::~WhatsThisItem()
+{
+ if ( count )
+ qFatal( "TQWhatsThis: Internal error (%d)", count );
+ delete whatsthis;
+}
+
+
+static const char * const button_image[] = {
+"16 16 3 1",
+" c None",
+"o c #000000",
+"a c #000080",
+"o aaaaa ",
+"oo aaa aaa ",
+"ooo aaa aaa",
+"oooo aa aa",
+"ooooo aa aa",
+"oooooo a aaa",
+"ooooooo aaa ",
+"oooooooo aaa ",
+"ooooooooo aaa ",
+"ooooo aaa ",
+"oo ooo ",
+"o ooo aaa ",
+" ooo aaa ",
+" ooo ",
+" ooo ",
+" ooo "};
+
+// the button class
+TQWhatsThisButton::TQWhatsThisButton( TQWidget * tqparent, const char * name )
+ : TQToolButton( tqparent, name )
+{
+ TQPixmap p( (const char**)button_image );
+ setPixmap( p );
+ setToggleButton( TRUE );
+ setAutoRaise( TRUE );
+ setFocusPolicy( Qt::NoFocus );
+ setTextLabel( tr( "What's this?" ) );
+ wt->buttons->insert( (void *)this, this );
+ connect( this, TQT_SIGNAL( released() ),
+ this, TQT_SLOT( mouseReleased() ) );
+}
+
+
+TQWhatsThisButton::~TQWhatsThisButton()
+{
+ if ( wt && wt->buttons )
+ wt->buttons->take( (void *)this );
+}
+
+
+void TQWhatsThisButton::mouseReleased()
+{
+ if ( wt->state == TQWhatsThisPrivate::Inactive && isOn() ) {
+ TQWhatsThisPrivate::setUpWhatsThis();
+#ifndef TQT_NO_CURSOR
+ TQApplication::setOverrideCursor( Qt::WhatsThisCursor, FALSE );
+#endif
+ wt->state = TQWhatsThisPrivate::Waiting;
+ tqApp->installEventFilter( wt );
+ }
+}
+
+static void qWhatsThisPrivateCleanup()
+{
+ if( wt ) {
+ delete wt;
+ wt = 0;
+ }
+}
+
+// the what's this manager class
+TQWhatsThisPrivate::TQWhatsThisPrivate()
+ : TQObject( 0, "global what's this object" )
+{
+ whatsThat = 0;
+ dict = new TQPtrDict<TQWhatsThisPrivate::WhatsThisItem>;
+ tlw = new TQPtrDict<TQWidget>;
+ wt = this;
+ buttons = new TQPtrDict<TQWhatsThisButton>;
+ state = Inactive;
+}
+
+TQWhatsThisPrivate::~TQWhatsThisPrivate()
+{
+#ifndef TQT_NO_CURSOR
+ if ( state == Waiting && tqApp )
+ TQApplication::restoreOverrideCursor();
+#endif
+ // the two straight-and-simple dicts
+ delete tlw;
+ delete buttons;
+
+ // then delete the complex one.
+ TQPtrDictIterator<WhatsThisItem> it( *dict );
+ WhatsThisItem * i;
+ TQWidget * w;
+ while( (i=it.current()) != 0 ) {
+ w = (TQWidget *)it.currentKey();
+ ++it;
+ dict->take( w );
+ if ( i->deref() )
+ delete i;
+ }
+ delete dict;
+ if ( whatsThat && !whatsThat->parentWidget() ) {
+ delete whatsThat;
+ }
+ // and finally lose wt
+ wt = 0;
+}
+
+bool TQWhatsThisPrivate::eventFilter( TQObject * o, TQEvent * e )
+{
+ switch( state ) {
+ case Waiting:
+ if ( e->type() == TQEvent::MouseButtonPress && o->isWidgetType() ) {
+ TQWidget * w = (TQWidget *) o;
+ if ( ( (TQMouseEvent*)e)->button() == Qt::RightButton )
+ return FALSE; // ignore RMB
+ if ( w->customWhatsThis() )
+ return FALSE;
+ TQWhatsThisPrivate::WhatsThisItem * i = 0;
+ TQMouseEvent* me = (TQMouseEvent*) e;
+ TQPoint p = me->pos();
+ while( w && !i ) {
+ i = dict->tqfind( w );
+ if ( !i ) {
+ p += w->pos();
+ w = w->parentWidget( TRUE );
+ }
+ }
+ leaveWhatsThisMode();
+ if (!i ) {
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpEnd );
+#endif
+ return TRUE;
+ }
+ if ( i->whatsthis )
+ say( w, i->whatsthis->text( p ), me->globalPos() );
+ else
+ say( w, i->s, me->globalPos() );
+ return TRUE;
+ } else if ( e->type() == TQEvent::MouseButtonRelease ) {
+ if ( ( (TQMouseEvent*)e)->button() == Qt::RightButton )
+ return FALSE; // ignore RMB
+ return !o->isWidgetType() || !((TQWidget*)o)->customWhatsThis();
+ } else if ( e->type() == TQEvent::MouseMove ) {
+ return !o->isWidgetType() || !((TQWidget*)o)->customWhatsThis();
+ } else if ( e->type() == TQEvent::KeyPress ) {
+ TQKeyEvent* kev = (TQKeyEvent*)e;
+
+ if ( kev->key() == Key_Escape ) {
+ leaveWhatsThisMode();
+ return TRUE;
+ } else if ( o->isWidgetType() && ((TQWidget*)o)->customWhatsThis() ) {
+ return FALSE;
+ } else if ( kev->key() == TQt::Key_Menu ||
+ ( kev->key() == TQt::Key_F10 &&
+ kev->state() == ShiftButton ) ) {
+ // we don't react to these keys, they are used for context menus
+ return FALSE;
+ } else if ( kev->state() == kev->stateAfter() &&
+ kev->key() != TQt::Key_Meta ) { // not a modifier key
+ leaveWhatsThisMode();
+ }
+ } else if ( e->type() == TQEvent::MouseButtonDblClick ) {
+ return TRUE;
+ }
+ break;
+ case Inactive:
+ if ( e->type() == TQEvent::Accel &&
+ ((TQKeyEvent *)e)->key() == TQt::Key_F1 &&
+ o->isWidgetType() &&
+ ((TQKeyEvent *)e)->state() == ShiftButton ) {
+ TQWidget * w = ((TQWidget *)o)->tqfocusWidget();
+ if ( !w )
+ break;
+ TQString s = TQWhatsThis::textFor( w, TQPoint(0,0), TRUE );
+ if ( !s.isNull() ) {
+ say ( w, s, w->mapToGlobal( w->rect().center() ) );
+ ((TQKeyEvent *)e)->accept();
+ return TRUE;
+ }
+ }
+ break;
+ }
+ return FALSE;
+}
+
+
+
+void TQWhatsThisPrivate::setUpWhatsThis()
+{
+ if ( !wt ) {
+ wt = new TQWhatsThisPrivate();
+
+ // It is necessary to use a post routine, because
+ // the destructor deletes pixmaps and other stuff that
+ // needs a working X connection under X11.
+ qAddPostRoutine( qWhatsThisPrivateCleanup );
+ }
+}
+
+
+void TQWhatsThisPrivate::enterWhatsThisMode()
+{
+#if defined(TQT_ACCESSIBILITY_SUPPORT)
+ TQAccessible::updateAccessibility( this, 0, TQAccessible::ContextHelpStart );
+#endif
+}
+
+
+void TQWhatsThisPrivate::leaveWhatsThisMode()
+{
+ if ( state == Waiting ) {
+ TQPtrDictIterator<TQWhatsThisButton> it( *(wt->buttons) );
+ TQWhatsThisButton * b;
+ while( (b=it.current()) != 0 ) {
+ ++it;
+ b->setOn( FALSE );
+ }
+#ifndef TQT_NO_CURSOR
+ TQApplication::restoreOverrideCursor();
+#endif
+ state = Inactive;
+ tqApp->removeEventFilter( this );
+ }
+}
+
+
+
+void TQWhatsThisPrivate::say( TQWidget * widget, const TQString &text, const TQPoint& ppos)
+{
+ if ( text.isEmpty() )
+ return;
+ // make a fresh widget, and set it up
+ delete whatsThat;
+ whatsThat = new TQWhatsThat(
+ widget, text,
+#if defined(TQ_WS_X11)
+ TQT_TQWIDGET(TQApplication::desktop()->screen( widget ?
+ widget->x11Screen() :
+ TQCursor::x11Screen()) ),
+#else
+ 0,
+#endif
+ "automatic what's this? widget" );
+
+
+ // okay, now to tqfind a suitable location
+
+ int scr = ( widget ?
+ TQApplication::desktop()->screenNumber( widget ) :
+#if defined(TQ_WS_X11)
+ TQCursor::x11Screen()
+#else
+ TQApplication::desktop()->screenNumber( ppos )
+#endif // TQ_WS_X11
+ );
+ TQRect screen = TQApplication::desktop()->screenGeometry( scr );
+
+ int x;
+ int w = whatsThat->width();
+ int h = whatsThat->height();
+ int sx = screen.x();
+ int sy = screen.y();
+
+ // first try locating the widget immediately above/below,
+ // with nice tqalignment if possible.
+ TQPoint pos;
+ if ( widget )
+ pos = widget->mapToGlobal( TQPoint( 0,0 ) );
+
+ if ( widget && w > widget->width() + 16 )
+ x = pos.x() + widget->width()/2 - w/2;
+ else
+ x = ppos.x() - w/2;
+
+ // squeeze it in if that would result in part of what's this
+ // being only partially visible
+ if ( x + w + shadowWidth > sx+screen.width() )
+ x = (widget? (TQMIN(screen.width(),
+ pos.x() + widget->width())
+ ) : screen.width() )
+ - w;
+
+ if ( x < sx )
+ x = sx;
+
+ int y;
+ if ( widget && h > widget->height() + 16 ) {
+ y = pos.y() + widget->height() + 2; // below, two pixels spacing
+ // what's this is above or below, wherever there's most space
+ if ( y + h + 10 > sy+screen.height() )
+ y = pos.y() + 2 - shadowWidth - h; // above, overlap
+ }
+ y = ppos.y() + 2;
+
+ // squeeze it in if that would result in part of what's this
+ // being only partially visible
+ if ( y + h + shadowWidth > sy+screen.height() )
+ y = ( widget ? (TQMIN(screen.height(),
+ pos.y() + widget->height())
+ ) : screen.height() )
+ - h;
+ if ( y < sy )
+ y = sy;
+
+ whatsThat->move( x, y );
+ whatsThat->show();
+}
+
+TQWhatsThisPrivate::WhatsThisItem* TQWhatsThisPrivate::newItem( TQWidget * widget )
+{
+ WhatsThisItem * i = dict->tqfind( (void *)widget );
+ if ( i )
+ TQWhatsThis::remove( widget );
+ i = new WhatsThisItem;
+ dict->insert( (void *)widget, i );
+ TQWidget * t = widget->tqtopLevelWidget();
+ if ( !tlw->tqfind( (void *)t ) ) {
+ tlw->insert( (void *)t, t );
+ t->installEventFilter( this );
+ }
+ connect( widget, TQT_SIGNAL(destroyed()), this, TQT_SLOT(cleanupWidget()) );
+ return i;
+}
+
+void TQWhatsThisPrivate::add( TQWidget * widget, TQWhatsThis* special )
+{
+ newItem( widget )->whatsthis = special;
+}
+
+void TQWhatsThisPrivate::add( TQWidget * widget, const TQString &text )
+{
+ newItem( widget )->s = text;
+}
+
+
+// and finally the What's This class itself
+
+/*!
+ Adds \a text as "What's this" help for \a widget. If the text is
+ rich text formatted (i.e. it tqcontains markup) it will be rendered
+ with the default stylesheet TQStyleSheet::defaultSheet().
+
+ The text is destroyed if the widget is later destroyed, so it need
+ not be explicitly removed.
+
+ \sa remove()
+*/
+void TQWhatsThis::add( TQWidget * widget, const TQString &text )
+{
+ if ( text.isEmpty() )
+ return; // pointless
+ TQWhatsThisPrivate::setUpWhatsThis();
+ wt->add(widget,text);
+}
+
+
+/*!
+ Removes the "What's this?" help associated with the \a widget.
+ This happens automatically if the widget is destroyed.
+
+ \sa add()
+*/
+void TQWhatsThis::remove( TQWidget * widget )
+{
+ TQWhatsThisPrivate::setUpWhatsThis();
+ TQWhatsThisPrivate::WhatsThisItem * i = wt->dict->tqfind( (void *)widget );
+ if ( !i )
+ return;
+
+ wt->dict->take( (void *)widget );
+
+ i->deref();
+ if ( !i->count )
+ delete i;
+}
+
+
+/*!
+ Returns the what's this text for widget \a w or TQString::null if
+ there is no "What's this?" help for the widget. \a pos tqcontains
+ the mouse position; this is useful, for example, if you've
+ subclassed to make the text that is displayed position dependent.
+
+ If \a includeParents is TRUE, tqparent widgets are taken into
+ consideration as well when looking for what's this help text.
+
+ \sa add()
+*/
+TQString TQWhatsThis::textFor( TQWidget * w, const TQPoint& pos, bool includeParents )
+{
+ TQWhatsThisPrivate::setUpWhatsThis();
+ TQWhatsThisPrivate::WhatsThisItem * i = 0;
+ TQPoint p = pos;
+ while( w && !i ) {
+ i = wt->dict->tqfind( w );
+ if ( !includeParents )
+ break;
+ if ( !i ) {
+ p += w->pos();
+ w = w->parentWidget( TRUE );
+ }
+ }
+ if (!i)
+ return TQString::null;
+ if ( i->whatsthis )
+ return i->whatsthis->text( p );
+ return i->s;
+}
+
+
+/*!
+ Creates a TQToolButton preconfigured to enter "What's this?" mode
+ when clicked. You will often use this with a tool bar as \a
+ tqparent:
+ \code
+ (void) TQWhatsThis::whatsThisButton( my_help_tool_bar );
+ \endcode
+*/
+TQToolButton * TQWhatsThis::whatsThisButton( TQWidget * tqparent )
+{
+ TQWhatsThisPrivate::setUpWhatsThis();
+ return new TQWhatsThisButton( tqparent,
+ "automatic what's this? button" );
+}
+
+/*!
+ Constructs a dynamic "What's this?" object for \a widget. The
+ object is deleted when the \a widget is destroyed.
+
+ When the widget is queried by the user the text() function of this
+ TQWhatsThis will be called to provide the appropriate text, rather
+ than using the text assigned by add().
+*/
+TQWhatsThis::TQWhatsThis( TQWidget * widget)
+{
+ TQWhatsThisPrivate::setUpWhatsThis();
+ wt->add(widget,this);
+}
+
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+TQWhatsThis::~TQWhatsThis()
+{
+}
+
+
+/*!
+ This virtual function returns the text for position \e p in the
+ widget that this "What's this?" object documents. If there is no
+ "What's this?" text for the position, TQString::null is returned.
+
+ The default implementation returns TQString::null.
+*/
+TQString TQWhatsThis::text( const TQPoint & )
+{
+ return TQString::null;
+}
+
+/*!
+ \fn bool TQWhatsThis::clicked( const TQString& href )
+
+ This virtual function is called when the user clicks inside the
+ "What's this?" window. \a href is the link the user clicked on, or
+ TQString::null if there was no link.
+
+ If the function returns TRUE (the default), the "What's this?"
+ window is closed, otherwise it remains visible.
+
+ The default implementation ignores \a href and returns TRUE.
+*/
+bool TQWhatsThis::clicked( const TQString& )
+{
+ return TRUE;
+}
+
+
+/*!
+ Enters "What's this?" mode and returns immediately.
+
+ TQt will install a special cursor and take over mouse input until
+ the user clicks somewhere. It then shows any help available and
+ ends "What's this?" mode. Finally, TQt removes the special cursor
+ and help window and then restores ordinary event processing, at
+ which point the left mouse button is no longer pressed.
+
+ The user can also use the Esc key to leave "What's this?" mode.
+
+ \sa inWhatsThisMode(), leaveWhatsThisMode()
+*/
+
+void TQWhatsThis::enterWhatsThisMode()
+{
+ TQWhatsThisPrivate::setUpWhatsThis();
+ if ( wt->state == TQWhatsThisPrivate::Inactive ) {
+ wt->enterWhatsThisMode();
+#ifndef TQT_NO_CURSOR
+ TQApplication::setOverrideCursor( Qt::WhatsThisCursor, FALSE );
+#endif
+ wt->state = TQWhatsThisPrivate::Waiting;
+ tqApp->installEventFilter( wt );
+ }
+}
+
+
+/*!
+ Returns TRUE if the application is in "What's this?" mode;
+ otherwise returns FALSE.
+
+ \sa enterWhatsThisMode(), leaveWhatsThisMode()
+*/
+bool TQWhatsThis::inWhatsThisMode()
+{
+ if (!wt)
+ return FALSE;
+ return wt->state == TQWhatsThisPrivate::Waiting;
+}
+
+
+/*!
+ Leaves "What's this?" question mode.
+
+ This function is used internally by widgets that support
+ TQWidget::customWhatsThis(); applications do not usually call it.
+ An example of such a widget is TQPopupMenu: menus still work
+ normally in "What's this?" mode but also provide help texts for
+ individual menu items.
+
+ If \a text is not TQString::null, a "What's this?" help window is
+ displayed at the global screen position \a pos. If widget \a w is
+ not 0 and has its own dedicated TQWhatsThis object, this object
+ will receive clicked() messages when the user clicks on hyperlinks
+ inside the help text.
+
+ \sa inWhatsThisMode(), enterWhatsThisMode(), TQWhatsThis::clicked()
+*/
+void TQWhatsThis::leaveWhatsThisMode( const TQString& text, const TQPoint& pos, TQWidget* w )
+{
+ if ( !inWhatsThisMode() )
+ return;
+
+ wt->leaveWhatsThisMode();
+ if ( !text.isNull() )
+ wt->say( w, text, pos );
+}
+
+/*!
+ Display \a text in a help window at the global screen position \a
+ pos.
+
+ If widget \a w is not 0 and has its own dedicated TQWhatsThis
+ object, this object will receive clicked() messages when the user
+ clicks on hyperlinks inside the help text.
+
+ \sa TQWhatsThis::clicked()
+*/
+void TQWhatsThis::display( const TQString& text, const TQPoint& pos, TQWidget* w )
+{
+ if ( inWhatsThisMode() ) {
+ leaveWhatsThisMode( text, pos, w );
+ return;
+ }
+ TQWhatsThisPrivate::setUpWhatsThis();
+ wt->say( w, text, pos );
+}
+
+/*!
+ Sets the font for all "What's this?" helps to \a font.
+*/
+void TQWhatsThis::setFont( const TQFont &font )
+{
+ TQApplication::tqsetFont( font, TRUE, "TQWhatsThat" );
+}
+
+#include "tqwhatsthis.tqmoc"
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqwhatsthis.h b/tqtinterface/qt4/src/widgets/tqwhatsthis.h
new file mode 100644
index 0000000..7ef3e8d
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqwhatsthis.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Definition of TQWhatsThis class
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWHATSTHIS_H
+#define TQWHATSTHIS_H
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_WHATSTHIS
+
+#include "tqcursor.h"
+
+class TQToolButton;
+class TQPopupMenu;
+class TQStyleSheet;
+
+class TQ_EXPORT TQWhatsThis: public TQt
+{
+public:
+ TQWhatsThis( TQWidget *);
+ virtual ~TQWhatsThis();
+
+ virtual TQString text( const TQPoint & );
+ virtual bool clicked( const TQString& href );
+
+ // the common static functions
+ static void setFont( const TQFont &font );
+
+ static void add( TQWidget *, const TQString &);
+ static void remove( TQWidget * );
+ static TQString textFor( TQWidget *, const TQPoint & pos = TQPoint(), bool includeParents = FALSE );
+
+ static TQToolButton * whatsThisButton( TQWidget * tqparent );
+
+ static void enterWhatsThisMode();
+ static bool inWhatsThisMode();
+ static void leaveWhatsThisMode( const TQString& = TQString::null, const TQPoint& pos = TQCursor::pos(), TQWidget* w = 0 );
+
+ static void display( const TQString& text, const TQPoint& pos = TQCursor::pos(), TQWidget* w = 0 );
+};
+
+#endif // TQT_NO_WHATSTHIS
+
+#endif // TQWHATSTHIS_H
diff --git a/tqtinterface/qt4/src/widgets/tqwidgetinterface_p.h b/tqtinterface/qt4/src/widgets/tqwidgetinterface_p.h
new file mode 100644
index 0000000..022294d
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqwidgetinterface_p.h
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** ...
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWIDGETINTERFACE_P_H
+#define TQWIDGETINTERFACE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of a number of TQt sources files. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#include <private/tqcom_p.h>
+#include "tqiconset.h"
+
+#ifndef TQT_NO_WIDGETPLUGIN
+
+class TQWidget;
+
+// {55184143-f18f-42c0-a8eb-71c01516019a}
+#ifndef IID_TQWidgetFactory
+#define IID_TQWidgetFactory TQUuid( 0x55184143, 0xf18f, 0x42c0, 0xa8, 0xeb, 0x71, 0xc0, 0x15, 0x16, 0x1, 0x9a )
+#endif
+
+/*! To add custom widgets to the TQt Designer, implement that interface
+ in your custom widget plugin.
+
+ You also have to implement the function featureList() (\sa
+ TQFeatureListInterface) and return there all widgets (names of it)
+ which this interface provides.
+*/
+
+struct TQWidgetFactoryInterface : public TQFeatureListInterface
+{
+public:
+
+ /*! In the implementation create and return the widget \a widget
+ here, use \a tqparent and \a name when creating the widget */
+ virtual TQWidget* create( const TQString &widget, TQWidget* tqparent = 0, const char* name = 0 ) = 0;
+
+ /*! In the implementation return the name of the group of the
+ widget \a widget */
+ virtual TQString group( const TQString &widget ) const = 0;
+
+ /*! In the implementation return the iconset, which should be used
+ in the TQt Designer menubar and toolbar to represent the widget
+ \a widget */
+ virtual TQIconSet iconSet( const TQString &widget ) const = 0;
+
+ /*! In the implementation return the include file which is needed
+ for the widget \a widget in the generated code which uic
+ generates. */
+ virtual TQString includeFile( const TQString &widget ) const = 0;
+
+ /*! In the implementation return the text which should be
+ displayed as tooltip for the widget \a widget */
+ virtual TQString toolTip( const TQString &widget ) const = 0;
+
+ /*! In the implementation return the text which should be used for
+ what's this help for the widget \a widget. */
+ virtual TQString whatsThis( const TQString &widget ) const = 0;
+
+ /*! In the implementation return TRUE here, of the \a widget
+ should be able to contain other widget in the TQt Designer, else
+ FALSE. */
+ virtual bool isContainer( const TQString &widget ) const = 0;
+};
+
+#ifdef TQT_CONTAINER_CUSTOM_WIDGETS
+// {15976628-e3c3-47f4-b525-d124a3caf30e}
+#ifndef IID_TQWidgetContainer
+#define IID_TQWidgetContainer TQUuid( 0x15976628, 0xe3c3, 0x47f4, 0xb5, 0x25, 0xd1, 0x24, 0xa3, 0xca, 0xf3, 0x0e )
+#endif
+
+struct TQWidgetContainerInterfacePrivate : public TQUnknownInterface
+{
+public:
+ virtual TQWidget *containerOfWidget( const TQString &f, TQWidget *container ) const = 0;
+ virtual bool isPassiveInteractor( const TQString &f, TQWidget *container ) const = 0;
+
+ virtual bool supportsPages( const TQString &f ) const = 0;
+
+ virtual TQWidget *addPage( const TQString &f, TQWidget *container,
+ const TQString &name, int index ) const = 0;
+ virtual void insertPage( const TQString &f, TQWidget *container,
+ const TQString &name, int index, TQWidget *page ) const = 0;
+ virtual void removePage( const TQString &f, TQWidget *container, int index ) const = 0;
+ virtual void movePage( const TQString &f, TQWidget *container, int fromIndex, int toIndex ) const = 0;
+ virtual int count( const TQString &key, TQWidget *container ) const = 0;
+ virtual int currentIndex( const TQString &key, TQWidget *container ) const = 0;
+ virtual TQString pageLabel( const TQString &key, TQWidget *container, int index ) const = 0;
+ virtual TQWidget *page( const TQString &key, TQWidget *container, int index ) const = 0;
+ virtual void renamePage( const TQString &key, TQWidget *container,
+ int index, const TQString &newName ) const = 0;
+ virtual TQWidgetList pages( const TQString &f, TQWidget *container ) const = 0;
+ virtual TQString createCode( const TQString &f, const TQString &container,
+ const TQString &page, const TQString &pageName ) const = 0;
+};
+
+#endif // TQT_CONTAINER_CUSTOM_WIDGETS
+#endif // TQT_NO_WIDGETPLUGIN
+#endif // TQWIDGETINTERFACE_P_H
diff --git a/tqtinterface/qt4/src/widgets/tqwidgetplugin.cpp b/tqtinterface/qt4/src/widgets/tqwidgetplugin.cpp
new file mode 100644
index 0000000..d4aa8fc
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqwidgetplugin.cpp
@@ -0,0 +1,729 @@
+/****************************************************************************
+**
+** Implementation of TQWidgetPlugin class
+**
+** Created : 010920
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwidgetplugin.h"
+
+#ifndef TQT_NO_WIDGETPLUGIN
+#include "tqwidgetinterface_p.h"
+#include "tqobjectcleanuphandler.h"
+#include "tqwidget.h"
+#ifdef TQT_CONTAINER_CUSTOM_WIDGETS
+#include "tqwidgetlist.h"
+#endif
+
+/*!
+ \class TQWidgetPlugin tqwidgetplugin.h
+ \brief The TQWidgetPlugin class provides an abstract base for custom TQWidget plugins.
+
+ \ingroup plugins
+
+ The widget plugin is a simple plugin interface that makes it easy
+ to create custom widgets that can be included in forms using \link
+ designer-manual.book TQt Designer\endlink and used by applications.
+
+ Writing a widget plugin is achieved by subclassing this base
+ class, reimplementing the pure virtual functions keys(), create(),
+ group(), iconSet(), includeFile(), toolTip(), whatsThis() and
+ isContainer(), and exporting the class with the \c TQ_EXPORT_PLUGIN
+ macro.
+
+ See the \link designer-manual.book TQt Designer manual's\endlink,
+ 'Creating Custom Widgets' section in the 'Creating Custom Widgets'
+ chapter, for a complete example of a TQWidgetPlugin.
+
+ See also the \link plugins-howto.html Plugins
+ documentation\endlink and the \l{TQWidgetFactory} class that is
+ supplied with \link designer-manual.book TQt Designer\endlink.
+*/
+
+class TQWidgetPluginPrivate : public TQWidgetFactoryInterface,
+#ifdef TQT_CONTAINER_CUSTOM_WIDGETS
+ public TQWidgetContainerInterfacePrivate,
+#endif
+ private TQLibraryInterface
+{
+public:
+ TQWidgetPluginPrivate( TQWidgetPlugin *p )
+ : plugin( p )
+ {
+ }
+
+ virtual ~TQWidgetPluginPrivate();
+
+ TQRESULT queryInterface( const TQUuid &iid, TQUnknownInterface **iface );
+ TQ_REFCOUNT;
+
+ TQStringList featureList() const;
+ TQWidget *create( const TQString &key, TQWidget *tqparent, const char *name );
+ TQString group( const TQString &widget ) const;
+ TQIconSet iconSet( const TQString &widget ) const;
+ TQString includeFile( const TQString &widget ) const;
+ TQString toolTip( const TQString &widget ) const;
+ TQString whatsThis( const TQString &widget ) const;
+ bool isContainer( const TQString &widget ) const;
+#ifdef TQT_CONTAINER_CUSTOM_WIDGETS
+ TQWidget* containerOfWidget( const TQString &key, TQWidget *widget ) const;
+ bool isPassiveInteractor( const TQString &key, TQWidget *widget ) const;
+ bool supportsPages( const TQString &key ) const;
+ TQWidget *addPage( const TQString &key, TQWidget *container, const TQString &name, int index ) const;
+ void insertPage( const TQString &key, TQWidget *container,
+ const TQString &name, int index, TQWidget *page ) const;
+ void Page( const TQString &key, TQWidget *container,
+ const TQString &name, int index, TQWidget *page ) const;
+ void removePage( const TQString &key, TQWidget *container, int index ) const;
+ void movePage( const TQString &key, TQWidget *container, int fromIndex, int toIndex ) const;
+ int count( const TQString &key, TQWidget *container ) const;
+ int currentIndex( const TQString &key, TQWidget *container ) const;
+ TQString pageLabel( const TQString &key, TQWidget *container, int index ) const;
+ TQWidget *page( const TQString &key, TQWidget *container, int index ) const;
+ void renamePage( const TQString &key, TQWidget *container, int index, const TQString &newName ) const;
+ TQWidgetList pages( const TQString &key, TQWidget *container ) const;
+ TQString createCode( const TQString &key, const TQString &container,
+ const TQString &page, const TQString &pageName ) const;
+#endif // TQT_CONTAINER_CUSTOM_WIDGETS
+ bool init();
+ void cleanup();
+ bool canUnload() const;
+
+private:
+ TQWidgetPlugin *plugin;
+ TQObjectCleanupHandler widgets;
+};
+
+TQRESULT TQWidgetPluginPrivate::queryInterface( const TQUuid &iid, TQUnknownInterface **iface )
+{
+ *iface = 0;
+
+ if ( iid == IID_TQUnknown )
+ *iface = (TQWidgetFactoryInterface*)this;
+ else if ( iid == IID_TQFeatureList )
+ *iface = (TQFeatureListInterface*)this;
+ else if ( iid == IID_TQWidgetFactory )
+ *iface = (TQWidgetFactoryInterface*)this;
+ else if ( iid == IID_TQLibrary )
+ *iface = (TQLibraryInterface*)this;
+#ifdef TQT_CONTAINER_CUSTOM_WIDGETS
+ else if ( iid == IID_TQWidgetContainer )
+ *iface = (TQWidgetContainerInterfacePrivate*)this;
+#endif
+ else
+ return TQE_NOINTERFACE;
+
+ (*iface)->addRef();
+ return TQS_OK;
+}
+
+/*!
+ \fn TQStringList TQWidgetPlugin::keys() const
+
+ Returns the list of widget keys this plugin supports.
+
+ These keys must be the class names of the custom widgets that are
+ implemented in the plugin.
+
+ \sa create()
+*/
+
+/*!
+ \fn TQWidget *TQWidgetPlugin::create( const TQString &, TQWidget *, const char * )
+
+ Creates and returns a TQWidget object for the widget key \a key.
+ The widget key is the class name of the required widget. The \a
+ name and \a tqparent arguments are passed to the custom widget's
+ constructor.
+
+ \sa keys()
+*/
+
+TQWidgetPluginPrivate::~TQWidgetPluginPrivate()
+{
+ delete plugin;
+}
+
+TQStringList TQWidgetPluginPrivate::featureList() const
+{
+ return plugin->keys();
+}
+
+TQWidget *TQWidgetPluginPrivate::create( const TQString &key, TQWidget *tqparent, const char *name )
+{
+ TQWidget *w = plugin->create( key, tqparent, name );
+ widgets.add( TQT_TQOBJECT(w) );
+ return w;
+}
+
+TQString TQWidgetPluginPrivate::group( const TQString &widget ) const
+{
+ return plugin->group( widget );
+}
+
+TQIconSet TQWidgetPluginPrivate::iconSet( const TQString &widget ) const
+{
+ return plugin->iconSet( widget );
+}
+
+TQString TQWidgetPluginPrivate::includeFile( const TQString &widget ) const
+{
+ return plugin->includeFile( widget );
+}
+
+TQString TQWidgetPluginPrivate::toolTip( const TQString &widget ) const
+{
+ return plugin->toolTip( widget );
+}
+
+TQString TQWidgetPluginPrivate::whatsThis( const TQString &widget ) const
+{
+ return plugin->whatsThis( widget );
+}
+
+bool TQWidgetPluginPrivate::isContainer( const TQString &widget ) const
+{
+ return plugin->isContainer( widget );
+}
+
+bool TQWidgetPluginPrivate::init()
+{
+ return TRUE;
+}
+
+void TQWidgetPluginPrivate::cleanup()
+{
+ widgets.clear();
+}
+
+bool TQWidgetPluginPrivate::canUnload() const
+{
+ return widgets.isEmpty();
+}
+
+#ifdef TQT_CONTAINER_CUSTOM_WIDGETS
+TQWidget* TQWidgetPluginPrivate::containerOfWidget( const TQString &key, TQWidget *widget ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ return p->containerOfWidget( key, widget );
+ return widget;
+}
+
+int TQWidgetPluginPrivate::count( const TQString &key, TQWidget *container ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ return p->count( key, container );
+ return 0;
+}
+
+int TQWidgetPluginPrivate::currentIndex( const TQString &key, TQWidget *container ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ return p->currentIndex( key, container );
+ return -1;
+}
+
+TQString TQWidgetPluginPrivate::pageLabel( const TQString &key, TQWidget *container, int index ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ return p->pageLabel( key, container, index );
+ return TQString::null;
+}
+
+TQWidget *TQWidgetPluginPrivate::page( const TQString &key, TQWidget *container, int index ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ return p->page( key, container, index );
+ return 0;
+}
+
+bool TQWidgetPluginPrivate::isPassiveInteractor( const TQString &key, TQWidget *widget ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ return p->isPassiveInteractor( key, widget );
+ return FALSE;
+}
+
+bool TQWidgetPluginPrivate::supportsPages( const TQString &key ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ return p->supportsPages( key );
+ return 0;
+}
+
+TQWidget *TQWidgetPluginPrivate::addPage( const TQString &key, TQWidget *container,
+ const TQString &name, int index ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ return p->addPage( key, container, name, index );
+ return 0;
+}
+
+void TQWidgetPluginPrivate::insertPage( const TQString &key, TQWidget *container,
+ const TQString &name, int index, TQWidget *page ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ p->insertPage( key, container, name, index, page );
+}
+
+void TQWidgetPluginPrivate::removePage( const TQString &key, TQWidget *container, int index ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ p->removePage( key, container, index );
+}
+
+void TQWidgetPluginPrivate::movePage( const TQString &key, TQWidget *container,
+ int fromIndex, int toIndex ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ p->movePage( key, container, fromIndex, toIndex );
+}
+
+void TQWidgetPluginPrivate::renamePage( const TQString &key, TQWidget *container,
+ int index, const TQString &newName ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ p->renamePage( key, container, index, newName );
+}
+
+TQWidgetList TQWidgetPluginPrivate::pages( const TQString &key, TQWidget *container ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ return p->pages( key, container );
+ return TQWidgetList();
+}
+
+TQString TQWidgetPluginPrivate::createCode( const TQString &key, const TQString &container,
+ const TQString &page, const TQString &pageName ) const
+{
+ TQWidgetContainerPlugin *p = (TQWidgetContainerPlugin*)plugin->tqqt_cast( "TQWidgetContainerPlugin" );
+ if ( p )
+ return p->createCode( key, container, page, pageName );
+ return TQString::null;
+}
+#endif // TQT_CONTAINER_CUSTOM_WIDGETS
+
+/*!
+ Constructs a widget plugin. This is invoked automatically by the
+ \c TQ_EXPORT_PLUGIN macro.
+*/
+TQWidgetPlugin::TQWidgetPlugin()
+ : TQGPlugin( (TQWidgetFactoryInterface*)(d = new TQWidgetPluginPrivate( this )) )
+{
+}
+
+/*!
+ Destroys the widget plugin.
+
+ You never have to call this explicitly. TQt destroys a plugin
+ automatically when it is no longer used.
+*/
+TQWidgetPlugin::~TQWidgetPlugin()
+{
+ // don't delete d, as this is deleted by d
+}
+
+/*!
+ Returns the group (toolbar name) that the custom widget of class
+ \a key should be part of when \e{TQt Designer} loads it.
+
+ The default implementation returns TQString::null.
+*/
+TQString TQWidgetPlugin::group( const TQString & ) const
+{
+ return TQString::null;
+}
+
+/*!
+ Returns the iconset that \e{TQt Designer} should use to represent
+ the custom widget of class \a key in the toolbar.
+
+ The default implementation returns an null iconset.
+*/
+TQIconSet TQWidgetPlugin::iconSet( const TQString & ) const
+{
+ return TQIconSet();
+}
+
+/*!
+ Returns the name of the include file that \e{TQt Designer} and \c
+ uic should use to include the custom widget of class \a key in
+ generated code.
+
+ The default implementation returns TQString::null.
+*/
+TQString TQWidgetPlugin::includeFile( const TQString & ) const
+{
+ return TQString::null;
+}
+
+/*!
+ Returns the text of the tooltip that \e{TQt Designer} should use
+ for the custom widget of class \a key's toolbar button.
+
+ The default implementation returns TQString::null.
+*/
+TQString TQWidgetPlugin::toolTip( const TQString & ) const
+{
+ return TQString::null;
+}
+
+/*!
+ Returns the text of the whatsThis text that \e{TQt Designer} should
+ use when the user requests whatsThis help for the custom widget of
+ class \a key.
+
+ The default implementation returns TQString::null.
+*/
+TQString TQWidgetPlugin::whatsThis( const TQString & ) const
+{
+ return TQString::null;
+}
+
+/*!
+ Returns TRUE if the custom widget of class \a key can contain
+ other widgets, e.g. like TQFrame; otherwise returns FALSE.
+
+ The default implementation returns FALSE.
+*/
+bool TQWidgetPlugin::isContainer( const TQString & ) const
+{
+ return FALSE;
+}
+
+#ifdef TQT_CONTAINER_CUSTOM_WIDGETS
+
+/*!
+ \class TQWidgetContainerPlugin tqwidgetplugin.h
+ \brief The TQWidgetContainerPlugin class provides an abstract base
+ for complex custom container TQWidget plugins.
+
+ \internal
+
+ \ingroup plugins
+
+ The widget container plugin is a subclass of TQWidgetPlugin and
+ extends the interface with functions necessary for supporting
+ complex container widgets via plugins. These container widgets are
+ widgets that have one or multiple sub widgets which act as the
+ widget's containers. If the widget has multiple container
+ subwidgets, they are referred to as "pages", and only one can be
+ active at a time. Examples of complex container widgets include:
+ TQTabWidget, TQWidgetStack and TQToolBox.
+
+ Writing a complex container widget plugin is achieved by
+ subclassing this base class. First by reimplementing
+ TQWidgetPlugin's pure virtual functions keys(), create(), group(),
+ iconSet(), includeFile(), toolTip(), whatsThis() and
+ isContainer(), and exporting the class with the \c TQ_EXPORT_PLUGIN
+ macro. In addition containerOfWidget(), isPassiveInteractor() and
+ supportsPages() must be reimplemented. If the widget
+ supportsPages(), count(), currentIndex(), pageLabel(), page(),
+ pages() and createCode() must be implemented. If the widget
+ supportsPages() and you want to allow the containers pages to be
+ modified, you must also reimplement addPage(), insertPage(),
+ removePage(), movePage() and renamePage().
+
+ \sa TQWidgetPlugin
+*/
+
+/*!
+ Constructs a complex container widget plugin. This is invoked
+ automatically by the \c TQ_EXPORT_PLUGIN macro.
+*/
+
+TQWidgetContainerPlugin::TQWidgetContainerPlugin()
+ : TQWidgetPlugin()
+{
+}
+
+/*!
+ Destroys the complex container widget plugin.
+
+ You never have to call this explicitly. TQt destroys a plugin
+ automatically when it is no longer used.
+*/
+
+TQWidgetContainerPlugin::~TQWidgetContainerPlugin()
+{
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ Returns the current \a container's custom widget. If the custom
+ widget is a tab widget, this function takes the \a container as
+ input and returns the widget's current page.
+
+ The default implementation returns \a container.
+*/
+
+TQWidget* TQWidgetContainerPlugin::containerOfWidget( const TQString &,
+ TQWidget *container ) const
+{
+ return container;
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ Returns the \a container custom widget's number of pages. If the
+ custom widget is a tab widget, this function returns the number of
+ tabs.
+
+ The default implementation returns 0.
+*/
+
+int TQWidgetContainerPlugin::count( const TQString &, TQWidget * ) const
+{
+ return 0;
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ Returns the \a container custom widget's current page index. If
+ the custom widget is a tab widget, this function returns the
+ current tab's index.
+
+ The default implementation returns -1.
+*/
+
+int TQWidgetContainerPlugin::currentIndex( const TQString &, TQWidget * ) const
+{
+ return -1;
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ Returns the \a container custom widget's label at position \a
+ index. If the custom widget is a tab widget, this function returns
+ the current tab's label.
+
+ The default implementation returns a null string.
+*/
+
+TQString TQWidgetContainerPlugin::pageLabel( const TQString &, TQWidget *, int ) const
+{
+ return TQString::null;
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ Returns the \a container custom widget's page at position \a
+ index. If the custom widget is a tab widget, this function returns
+ the tab at index position \e index.
+
+
+ The default implementation returns 0.
+*/
+
+TQWidget *TQWidgetContainerPlugin::page( const TQString &, TQWidget *, int ) const
+{
+ return 0;
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ Returns TRUE if the \a container custom widget is a passive
+ interactor for class \e key; otherwise returns FALSE. The \a
+ container is a child widget of the actual custom widget.
+
+ Usually, when a custom widget is used in \e{TQt Designer}'s design
+ mode, no widget receives any mouse or key events, since \e{TQt
+ Designer} filters and processes them itself. If one or more
+ widgets of a custom widget still need to receive such events, for
+ example, because the widget needs to change pages, this function
+ must return TRUE for the widget. In such cases \e{TQt Designer}
+ will not filter out key and mouse events destined for the widget.
+
+ If the custom widget is a tab widget, the tab bar is the passive
+ interactor, since that's what the user will use to change pages.
+
+ The default implementation returns FALSE.
+*/
+
+bool TQWidgetContainerPlugin::isPassiveInteractor( const TQString &,
+ TQWidget *container ) const
+{
+ TQ_UNUSED( container )
+ return FALSE;
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ Returns TRUE if the widget supports pages; otherwise returns
+ FALSE. If the custom widget is a tab widget this function should
+ return TRUE.
+
+ The default implementation returns FALSE.
+*/
+
+bool TQWidgetContainerPlugin::supportsPages( const TQString & ) const
+{
+ return FALSE;
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ This function is called when a new page with the given \a name
+ should be added to the \a container custom widget at position \a
+ index.
+
+ The default implementation does nothing.
+*/
+
+TQWidget* TQWidgetContainerPlugin::addPage( const TQString &, TQWidget *,
+ const TQString &, int ) const
+{
+ return 0;
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ This function is called when a new page, \a page, with the given
+ \a name should be added to the \a container custom widget at
+ position \a index.
+
+ The default implementation does nothing.
+*/
+
+void TQWidgetContainerPlugin::insertPage( const TQString &, TQWidget *,
+ const TQString &, int, TQWidget * ) const
+{
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ This function is called when the page at position \a index should
+ be removed from the \a container custom widget.
+
+ The default implementation does nothing.
+*/
+
+void TQWidgetContainerPlugin::removePage( const TQString &, TQWidget *, int ) const
+{
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ This function is called when the page at position \a fromIndex should
+ be moved to position \a toIndex in the \a container custom widget.
+
+ The default implementation does nothing.
+*/
+
+void TQWidgetContainerPlugin::movePage( const TQString &, TQWidget *, int, int ) const
+{
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ This function is called when the page at position \a index should
+ be renamed (have its label changed) to \a newName in the \a
+ container custom widget.
+
+ The default implementation does nothing.
+*/
+
+void TQWidgetContainerPlugin::renamePage( const TQString &, TQWidget *,
+ int, const TQString & ) const
+{
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ This function should return a list of the \a container custom
+ widget's pages.
+*/
+
+TQWidgetList TQWidgetContainerPlugin::pages( const TQString &, TQWidget * ) const
+{
+ return TQWidgetList();
+}
+
+/*!
+ Operates on the plugin's \a key class.
+
+ This function is called from \e{TQt Designer}'s User Interface
+ Compiler \c uic, when generating C++ code for inserting a page in
+ the \a container custom widget. The name of the page widget which
+ should be inserted at the end of the container is \a page, and the
+ label of the page should be \a pageName.
+
+ If the custom widget was a TQTabWidget, the implementation of this
+ function should return:
+
+ \code
+ return widget + "->addTab( " + page + ", \"" + pageName + "\" )";
+ \endcode
+
+ Warning: If the code returned by this function tqcontains invalid
+ C++ syntax, the generated \c uic code will not compile.
+*/
+
+TQString TQWidgetContainerPlugin::createCode( const TQString &, const TQString &,
+ const TQString &, const TQString & ) const
+{
+ return TQString::null;
+}
+
+#endif // TQT_CONTAINER_CUSTOM_WIDGETS
+
+#endif //TQT_NO_WIDGETPLUGIN
diff --git a/tqtinterface/qt4/src/widgets/tqwidgetplugin.h b/tqtinterface/qt4/src/widgets/tqwidgetplugin.h
new file mode 100644
index 0000000..5544677
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqwidgetplugin.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Definition of TQWidgetPlugin class
+**
+** Created : 010920
+**
+** Copyright (C) 2001-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWIDGETPLUGIN_H
+#define TQWIDGETPLUGIN_H
+
+#ifndef TQT_H
+#include "tqgplugin.h"
+#include "tqstringlist.h"
+#include "tqiconset.h"
+#endif // TQT_H
+#ifndef TQT_NO_WIDGETPLUGIN
+
+#ifdef TQ_WS_WIN
+#ifdef TQT_PLUGIN
+#define TQT_WIDGET_PLUGIN_EXPORT __declspec(dllexport)
+#else
+#define TQT_WIDGET_PLUGIN_EXPORT __declspec(dllimport)
+#endif
+#else
+#define TQT_WIDGET_PLUGIN_EXPORT
+#endif
+
+class TQWidgetPluginPrivate;
+class TQWidget;
+
+class TQ_EXPORT TQWidgetPlugin : public TQGPlugin
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQWidgetPlugin();
+ ~TQWidgetPlugin();
+
+ virtual TQStringList keys() const = 0;
+ virtual TQWidget *create( const TQString &key, TQWidget *tqparent = 0, const char *name = 0 ) = 0;
+
+ virtual TQString group( const TQString &key ) const;
+ virtual TQIconSet iconSet( const TQString &key ) const;
+ virtual TQString includeFile( const TQString &key ) const;
+ virtual TQString toolTip( const TQString &key ) const;
+ virtual TQString whatsThis( const TQString &key ) const;
+ virtual bool isContainer( const TQString &key ) const;
+
+private:
+ TQWidgetPluginPrivate *d;
+};
+
+#ifdef TQT_CONTAINER_CUSTOM_WIDGETS
+
+class TQWidgetContainerPluginPrivate;
+
+class TQ_EXPORT TQWidgetContainerPlugin : public TQWidgetPlugin
+{
+
+public:
+ TQWidgetContainerPlugin();
+ ~TQWidgetContainerPlugin();
+
+ virtual TQWidget* containerOfWidget( const TQString &key, TQWidget *container ) const;
+ virtual bool isPassiveInteractor( const TQString &key, TQWidget *container ) const;
+
+ virtual bool supportsPages( const TQString &key ) const;
+
+ virtual TQWidget *addPage( const TQString &key, TQWidget *container,
+ const TQString &name, int index ) const;
+ virtual void insertPage( const TQString &key, TQWidget *container,
+ const TQString &name, int index, TQWidget *page ) const;
+ virtual void removePage( const TQString &key, TQWidget *container, int index ) const;
+ virtual void movePage( const TQString &key, TQWidget *container, int fromIndex, int toIndex ) const;
+ virtual int count( const TQString &key, TQWidget *container ) const;
+ virtual int currentIndex( const TQString &key, TQWidget *container ) const;
+ virtual TQString pageLabel( const TQString &key, TQWidget *container, int index ) const;
+ virtual TQWidget *page( const TQString &key, TQWidget *container, int index ) const;
+ virtual void renamePage( const TQString &key, TQWidget *container,
+ int index, const TQString &newName ) const;
+ virtual TQWidgetList pages( const TQString &key, TQWidget *container ) const;
+ virtual TQString createCode( const TQString &key, const TQString &container,
+ const TQString &page, const TQString &pageName ) const;
+};
+
+#endif // TQT_CONTAINER_CUSTOM_WIDGETS
+#endif // TQT_NO_WIDGETPLUGIN
+#endif // TQWIDGETPLUGIN_H
diff --git a/tqtinterface/qt4/src/widgets/tqwidgetresizehandler.cpp b/tqtinterface/qt4/src/widgets/tqwidgetresizehandler.cpp
new file mode 100644
index 0000000..b9b576a
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqwidgetresizehandler.cpp
@@ -0,0 +1,516 @@
+/****************************************************************************
+**
+** Implementation of the TQWidgetResizeHandler class
+**
+** Created : 001010
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the workspace module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwidgetresizehandler_p.h"
+
+#ifndef TQT_NO_RESIZEHANDLER
+#include "tqframe.h"
+#include "tqapplication.h"
+#include "tqcursor.h"
+#include "tqsizegrip.h"
+#if defined(TQ_WS_WIN)
+#include "tqt_windows.h"
+#endif
+
+#define RANGE 4
+
+static bool resizeHorizontalDirectionFixed = FALSE;
+static bool resizeVerticalDirectionFixed = FALSE;
+
+TQWidgetResizeHandler::TQWidgetResizeHandler( TQWidget *tqparent, TQWidget *cw, const char *name )
+ : TQObject( tqparent, name ), widget( tqparent ), childWidget( cw ? cw : tqparent ),
+ extrahei( 0 ), buttonDown( FALSE ), moveResizeMode( FALSE ), sizeprotect( TRUE ), moving( TRUE )
+{
+ mode = Nowhere;
+ widget->setMouseTracking( TRUE );
+ TQFrame *frame = ::tqqt_cast<TQFrame*>(widget);
+ range = frame ? frame->frameWidth() : RANGE;
+ range = TQMAX( RANGE, range );
+ activeForMove = activeForResize = TRUE;
+ tqApp->installEventFilter( this );
+}
+
+void TQWidgetResizeHandler::setActive( Action ac, bool b )
+{
+ if ( ac & Move )
+ activeForMove = b;
+ if ( ac & Resize )
+ activeForResize = b;
+
+ if ( !isActive() )
+ setMouseCursor( Nowhere );
+}
+
+bool TQWidgetResizeHandler::isActive( Action ac ) const
+{
+ bool b = FALSE;
+ if ( ac & Move ) b = activeForMove;
+ if ( ac & Resize ) b |= activeForResize;
+
+ return b;
+}
+
+static TQWidget *childOf( TQWidget *w, TQWidget *child )
+{
+ while ( child ) {
+ if ( child == w )
+ return child;
+ if ( child->isTopLevel() )
+ break;
+ child = child->parentWidget();
+ }
+ return 0;
+}
+
+bool TQWidgetResizeHandler::eventFilter( TQObject *o, TQEvent *ee )
+{
+ if ( !isActive() || !o->isWidgetType() || !ee->spontaneous())
+ return FALSE;
+
+ if ( ee->type() != TQEvent::MouseButtonPress &&
+ ee->type() != TQEvent::MouseButtonRelease &&
+ ee->type() != TQEvent::MouseMove &&
+ ee->type() != TQEvent::KeyPress &&
+ ee->type() != (QEvent::Type)TQEvent::AccelOverride )
+ return FALSE;
+
+ TQWidget *w = childOf( widget, (TQWidget*)o );
+ if ( !w
+#ifndef TQT_NO_SIZEGRIP
+ || ::tqqt_cast<TQSizeGrip*>(o)
+#endif
+ || tqApp->activePopupWidget() ) {
+ if ( buttonDown && ee->type() == TQEvent::MouseButtonRelease )
+ buttonDown = FALSE;
+ return FALSE;
+ }
+
+ TQMouseEvent *e = (TQMouseEvent*)ee;
+ switch ( e->type() ) {
+ case TQEvent::MouseButtonPress: {
+ if ( w->isMaximized() )
+ break;
+ if ( !TQT_TQRECT_OBJECT(widget->rect()).tqcontains( widget->mapFromGlobal( e->globalPos() ) ) )
+ return FALSE;
+ if ( e->button() == Qt::LeftButton ) {
+ emit activate();
+ bool me = isMovingEnabled();
+ setMovingEnabled( me && TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(widget) );
+ mouseMoveEvent( e );
+ setMovingEnabled( me );
+ buttonDown = TRUE;
+ moveOffset = widget->mapFromGlobal( e->globalPos() );
+ invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
+ }
+ } break;
+ case TQEvent::MouseButtonRelease:
+ if ( w->isMaximized() )
+ break;
+ if ( e->button() == Qt::LeftButton ) {
+ moveResizeMode = FALSE;
+ buttonDown = FALSE;
+ widget->releaseMouse();
+ widget->releaseKeyboard();
+ }
+ break;
+ case TQEvent::MouseMove: {
+ if ( w->isMaximized() )
+ break;
+ bool me = isMovingEnabled();
+ setMovingEnabled( me && TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(widget) );
+ mouseMoveEvent( e );
+ setMovingEnabled( me );
+ if ( buttonDown && mode != Center )
+ return TRUE;
+ } break;
+ case TQEvent::KeyPress:
+ keyPressEvent( (TQKeyEvent*)e );
+ break;
+ case TQEvent::AccelOverride:
+ if ( buttonDown ) {
+ ((TQKeyEvent*)ee)->accept();
+ return TRUE;
+ }
+ break;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+void TQWidgetResizeHandler::mouseMoveEvent( TQMouseEvent *e )
+{
+ TQPoint pos = widget->mapFromGlobal( e->globalPos() );
+ if ( !moveResizeMode && ( !buttonDown || ( e->state() & Qt::LeftButton ) == 0 ) ) {
+ if ( pos.y() <= range && pos.x() <= range)
+ mode = TopLeft;
+ else if ( pos.y() >= widget->height()-range && pos.x() >= widget->width()-range)
+ mode = BottomRight;
+ else if ( pos.y() >= widget->height()-range && pos.x() <= range)
+ mode = BottomLeft;
+ else if ( pos.y() <= range && pos.x() >= widget->width()-range)
+ mode = TopRight;
+ else if ( pos.y() <= range )
+ mode = Top;
+ else if ( pos.y() >= widget->height()-range )
+ mode = Bottom;
+ else if ( pos.x() <= range )
+ mode = Left;
+ else if ( pos.x() >= widget->width()-range )
+ mode = Right;
+ else
+ mode = Center;
+
+ if ( widget->isMinimized() || !isActive(Resize) )
+ mode = Center;
+#ifndef TQT_NO_CURSOR
+ setMouseCursor( mode );
+#endif
+ return;
+ }
+
+ if ( buttonDown && !isMovingEnabled() && mode == Center && !moveResizeMode )
+ return;
+
+ if ( widget->testWState( TQt::WState_ConfigPending ) )
+ return;
+
+ TQPoint globalPos = widget->parentWidget( TRUE ) ?
+ widget->parentWidget( TRUE )->mapFromGlobal( e->globalPos() ) : e->globalPos();
+ if ( widget->parentWidget( TRUE ) && !TQT_TQRECT_OBJECT(widget->parentWidget( TRUE )->rect()).tqcontains( globalPos ) ) {
+ if ( globalPos.x() < 0 )
+ globalPos.rx() = 0;
+ if ( globalPos.y() < 0 )
+ globalPos.ry() = 0;
+ if ( sizeprotect && globalPos.x() > widget->parentWidget()->width() )
+ globalPos.rx() = widget->parentWidget()->width();
+ if ( sizeprotect && globalPos.y() > widget->parentWidget()->height() )
+ globalPos.ry() = widget->parentWidget()->height();
+ }
+
+ TQPoint p = globalPos + invertedMoveOffset;
+ TQPoint pp = globalPos - moveOffset;
+
+ int fw = 0;
+ int mw = TQMAX( childWidget->tqminimumSizeHint().width(),
+ childWidget->minimumWidth() );
+ int mh = TQMAX( childWidget->tqminimumSizeHint().height(),
+ childWidget->minimumHeight() );
+ if ( childWidget != widget ) {
+ TQFrame *frame = ::tqqt_cast<TQFrame*>(widget);
+ if ( frame )
+ fw = frame->frameWidth();
+ mw += 2 * fw;
+ mh += 2 * fw + extrahei;
+ }
+
+ TQSize mpsize( widget->tqgeometry().right() - pp.x() + 1,
+ widget->tqgeometry().bottom() - pp.y() + 1 );
+ mpsize = mpsize.expandedTo( widget->tqminimumSize() ).expandedTo( TQSize(mw, mh) );
+ TQPoint mp( widget->tqgeometry().right() - mpsize.width() + 1,
+ widget->tqgeometry().bottom() - mpsize.height() + 1 );
+
+ TQRect geom = widget->tqgeometry();
+
+ switch ( mode ) {
+ case TopLeft:
+ geom = TQRect( mp, widget->tqgeometry().bottomRight() ) ;
+ break;
+ case BottomRight:
+ geom = TQRect( widget->tqgeometry().topLeft(), p ) ;
+ break;
+ case BottomLeft:
+ geom = TQRect( TQPoint(mp.x(), widget->tqgeometry().y() ), TQPoint( widget->tqgeometry().right(), p.y()) ) ;
+ break;
+ case TopRight:
+ geom = TQRect( TQPoint( widget->tqgeometry().x(), mp.y() ), TQPoint( p.x(), widget->tqgeometry().bottom()) ) ;
+ break;
+ case Top:
+ geom = TQRect( TQPoint( widget->tqgeometry().left(), mp.y() ), widget->tqgeometry().bottomRight() ) ;
+ break;
+ case Bottom:
+ geom = TQRect( widget->tqgeometry().topLeft(), TQPoint( widget->tqgeometry().right(), p.y() ) ) ;
+ break;
+ case Left:
+ geom = TQRect( TQPoint( mp.x(), widget->tqgeometry().top() ), widget->tqgeometry().bottomRight() ) ;
+ break;
+ case Right:
+ geom = TQRect( widget->tqgeometry().topLeft(), TQPoint( p.x(), widget->tqgeometry().bottom() ) ) ;
+ break;
+ case Center:
+ if ( isMovingEnabled() || moveResizeMode )
+ geom.moveTopLeft( pp );
+ break;
+ default:
+ break;
+ }
+
+ TQSize maxsize( childWidget->tqmaximumSize() );
+ if ( childWidget != widget )
+ maxsize += TQSize( 2 * fw, 2 * fw + extrahei );
+
+ geom = TQRect( geom.topLeft(),
+ geom.size().expandedTo( widget->tqminimumSize() )
+ .expandedTo( TQSize(mw, mh) )
+ .boundedTo( maxsize ) );
+
+ if ( geom != widget->tqgeometry() &&
+ ( widget->isTopLevel() || widget->parentWidget()->rect().intersects( geom ) ) ) {
+ if ( widget->isMinimized() )
+ widget->move( geom.topLeft() );
+ else
+ widget->setGeometry( geom );
+ }
+
+#if defined(TQ_WS_WIN)
+ MSG msg;
+ TQT_WA( {
+ while(PeekMessageW( &msg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE ))
+ ;
+ } , {
+ while(PeekMessageA( &msg, widget->winId(), WM_MOUSEMOVE, WM_MOUSEMOVE, PM_REMOVE ))
+ ;
+ } );
+#endif
+
+ TQApplication::syncX();
+}
+
+void TQWidgetResizeHandler::setMouseCursor( MousePosition m )
+{
+#ifndef TQT_NO_CURSOR
+ switch ( m ) {
+ case TopLeft:
+ case BottomRight:
+ widget->setCursor( Qt::SizeFDiagCursor );
+ break;
+ case BottomLeft:
+ case TopRight:
+ widget->setCursor( Qt::SizeBDiagCursor );
+ break;
+ case Top:
+ case Bottom:
+ widget->setCursor( Qt::SizeVerCursor );
+ break;
+ case Left:
+ case Right:
+ widget->setCursor( Qt::SizeHorCursor );
+ break;
+ default:
+ widget->setCursor( Qt::ArrowCursor );
+ break;
+ }
+#endif
+}
+
+void TQWidgetResizeHandler::keyPressEvent( TQKeyEvent * e )
+{
+ if ( !isMove() && !isResize() )
+ return;
+ bool is_control = e->state() & ControlButton;
+ int delta = is_control?1:8;
+ TQPoint pos = TQCursor::pos();
+ switch ( e->key() ) {
+ case Qt::Key_Left:
+ pos.rx() -= delta;
+ if ( pos.x() <= TQT_TQWIDGET(TQApplication::desktop())->tqgeometry().left() ) {
+ if ( mode == TopLeft || mode == BottomLeft ) {
+ moveOffset.rx() += delta;
+ invertedMoveOffset.rx() += delta;
+ } else {
+ moveOffset.rx() -= delta;
+ invertedMoveOffset.rx() -= delta;
+ }
+ }
+ if ( isResize() && !resizeHorizontalDirectionFixed ) {
+ resizeHorizontalDirectionFixed = TRUE;
+ if ( mode == BottomRight )
+ mode = BottomLeft;
+ else if ( mode == TopRight )
+ mode = TopLeft;
+#ifndef TQT_NO_CURSOR
+ setMouseCursor( mode );
+ widget->grabMouse( widget->cursor() );
+#else
+ widget->grabMouse();
+#endif
+ }
+ break;
+ case Qt::Key_Right:
+ pos.rx() += delta;
+ if ( pos.x() >= TQT_TQWIDGET(TQApplication::desktop())->tqgeometry().right() ) {
+ if ( mode == TopRight || mode == BottomRight ) {
+ moveOffset.rx() += delta;
+ invertedMoveOffset.rx() += delta;
+ } else {
+ moveOffset.rx() -= delta;
+ invertedMoveOffset.rx() -= delta;
+ }
+ }
+ if ( isResize() && !resizeHorizontalDirectionFixed ) {
+ resizeHorizontalDirectionFixed = TRUE;
+ if ( mode == BottomLeft )
+ mode = BottomRight;
+ else if ( mode == TopLeft )
+ mode = TopRight;
+#ifndef TQT_NO_CURSOR
+ setMouseCursor( mode );
+ widget->grabMouse( widget->cursor() );
+#else
+ widget->grabMouse();
+#endif
+ }
+ break;
+ case Qt::Key_Up:
+ pos.ry() -= delta;
+ if ( pos.y() <= TQT_TQWIDGET(TQApplication::desktop())->tqgeometry().top() ) {
+ if ( mode == TopLeft || mode == TopRight ) {
+ moveOffset.ry() += delta;
+ invertedMoveOffset.ry() += delta;
+ } else {
+ moveOffset.ry() -= delta;
+ invertedMoveOffset.ry() -= delta;
+ }
+ }
+ if ( isResize() && !resizeVerticalDirectionFixed ) {
+ resizeVerticalDirectionFixed = TRUE;
+ if ( mode == BottomLeft )
+ mode = TopLeft;
+ else if ( mode == BottomRight )
+ mode = TopRight;
+#ifndef TQT_NO_CURSOR
+ setMouseCursor( mode );
+ widget->grabMouse( widget->cursor() );
+#else
+ widget->grabMouse();
+#endif
+ }
+ break;
+ case Qt::Key_Down:
+ pos.ry() += delta;
+ if ( pos.y() >= TQT_TQWIDGET(TQApplication::desktop())->tqgeometry().bottom() ) {
+ if ( mode == BottomLeft || mode == BottomRight ) {
+ moveOffset.ry() += delta;
+ invertedMoveOffset.ry() += delta;
+ } else {
+ moveOffset.ry() -= delta;
+ invertedMoveOffset.ry() -= delta;
+ }
+ }
+ if ( isResize() && !resizeVerticalDirectionFixed ) {
+ resizeVerticalDirectionFixed = TRUE;
+ if ( mode == TopLeft )
+ mode = BottomLeft;
+ else if ( mode == TopRight )
+ mode = BottomRight;
+#ifndef TQT_NO_CURSOR
+ setMouseCursor( mode );
+ widget->grabMouse( widget->cursor() );
+#else
+ widget->grabMouse();
+#endif
+ }
+ break;
+ case Qt::Key_Space:
+ case Qt::Key_Return:
+ case Qt::Key_Enter:
+ case Key_Escape:
+ moveResizeMode = FALSE;
+ widget->releaseMouse();
+ widget->releaseKeyboard();
+ buttonDown = FALSE;
+ break;
+ default:
+ return;
+ }
+ TQCursor::setPos( pos );
+}
+
+
+void TQWidgetResizeHandler::doResize()
+{
+ if ( !activeForResize )
+ return;
+
+ moveResizeMode = TRUE;
+ buttonDown = TRUE;
+ moveOffset = widget->mapFromGlobal( TQCursor::pos() );
+ if ( moveOffset.x() < widget->width()/2) {
+ if ( moveOffset.y() < widget->height()/2)
+ mode = TopLeft;
+ else
+ mode = BottomLeft;
+ } else {
+ if ( moveOffset.y() < widget->height()/2)
+ mode = TopRight;
+ else
+ mode = BottomRight;
+ }
+ invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
+#ifndef TQT_NO_CURSOR
+ setMouseCursor( mode );
+ widget->grabMouse( widget->cursor() );
+#else
+ widget->grabMouse();
+#endif
+ widget->grabKeyboard();
+ resizeHorizontalDirectionFixed = FALSE;
+ resizeVerticalDirectionFixed = FALSE;
+}
+
+void TQWidgetResizeHandler::doMove()
+{
+ if ( !activeForMove )
+ return;
+
+ mode = Center;
+ moveResizeMode = TRUE;
+ buttonDown = TRUE;
+ moveOffset = widget->mapFromGlobal( TQCursor::pos() );
+ invertedMoveOffset = widget->rect().bottomRight() - moveOffset;
+#ifndef TQT_NO_CURSOR
+ widget->grabMouse( SizeAllCursor );
+#else
+ widget->grabMouse();
+#endif
+ widget->grabKeyboard();
+}
+
+#endif //TQT_NO_RESIZEHANDLER
diff --git a/tqtinterface/qt4/src/widgets/tqwidgetresizehandler_p.h b/tqtinterface/qt4/src/widgets/tqwidgetresizehandler_p.h
new file mode 100644
index 0000000..bb2b1cb
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqwidgetresizehandler_p.h
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Definition of the TQWidgetResizeHandler class
+**
+** Created : 001010
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the workspace module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWIDGETRESIZEHANDLER_P_H
+#define TQWIDGETRESIZEHANDLER_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. This header file may
+// change from version to version without notice, or even be
+// removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqobject.h"
+#endif // TQT_H
+#ifndef TQT_NO_RESIZEHANDLER
+class TQMouseEvent;
+class TQKeyEvent;
+
+class TQ_EXPORT TQWidgetResizeHandler : public TQObject
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+public:
+ enum Action {
+ Move = 0x01,
+ Resize = 0x02,
+ Any = Move|Resize
+ };
+
+ TQWidgetResizeHandler( TQWidget *tqparent, TQWidget *cw = 0, const char *name = 0 );
+ void setActive( bool b ) { setActive( Any, b ); }
+ void setActive( Action ac, bool b );
+ bool isActive() const { return isActive( Any ); }
+ bool isActive( Action ac ) const;
+ void setMovingEnabled( bool b ) { moving = b; }
+ bool isMovingEnabled() const { return moving; }
+
+ bool isButtonDown() const { return buttonDown; }
+
+ void setExtraHeight( int h ) { extrahei = h; }
+ void setSizeProtection( bool b ) { sizeprotect = b; }
+
+ void doResize();
+ void doMove();
+
+Q_SIGNALS:
+ void activate();
+
+protected:
+ bool eventFilter( TQObject *o, TQEvent *e );
+ void mouseMoveEvent( TQMouseEvent *e );
+ void keyPressEvent( TQKeyEvent *e );
+
+private:
+ enum MousePosition {
+ Nowhere,
+ TopLeft, BottomRight, BottomLeft, TopRight,
+ Top, Bottom, Left, Right,
+ Center
+ };
+
+ TQWidget *widget;
+ TQWidget *childWidget;
+ TQPoint moveOffset;
+ TQPoint invertedMoveOffset;
+ MousePosition mode;
+ int extrahei;
+ int range;
+ uint buttonDown :1;
+ uint moveResizeMode :1;
+ uint activeForResize :1;
+ uint sizeprotect :1;
+ uint moving :1;
+ uint activeForMove :1;
+
+ void setMouseCursor( MousePosition m );
+ bool isMove() const {
+ return moveResizeMode && mode == Center;
+ }
+ bool isResize() const {
+ return moveResizeMode && !isMove();
+ }
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQWidgetResizeHandler( const TQWidgetResizeHandler & );
+ TQWidgetResizeHandler& operator=( const TQWidgetResizeHandler & );
+#endif
+
+};
+
+#endif //TQT_NO_RESIZEHANDLER
+#endif
diff --git a/tqtinterface/qt4/src/widgets/tqwidgetstack.cpp b/tqtinterface/qt4/src/widgets/tqwidgetstack.cpp
new file mode 100644
index 0000000..4bf824e
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqwidgetstack.cpp
@@ -0,0 +1,1183 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tqwidgetstack.h"
+#include "tqlayout.h"
+#include "private/tqlayoutengine_p.h"
+#include "Qt/qapplication.h"
+#include "Qt/qpainter.h"
+
+QT_BEGIN_NAMESPACE
+
+using namespace Qt;
+
+class TQWidgetStackPrivate {
+public:
+ class Invisible: public TQWidget
+ {
+ public:
+ Invisible(TQWidgetStack * parent): TQWidget(parent, "qt_invisible_widgetstack")
+ {
+ setBackgroundMode(TQt::NoBackground);
+ }
+ const char * className() const
+ {
+ return "TQWidgetStackPrivate::Invisible";
+ }
+ protected:
+ void paintEvent(QPaintEvent *)
+ {
+ QPainter(this).eraseRect(rect());
+ }
+ };
+
+ int nextNegativeID;
+ int nextPositiveID;
+};
+
+
+
+/*!
+ \class TQWidgetStack
+ \brief The TQWidgetStack class provides a stack of widgets of which
+ only the top widget is user-visible.
+
+ \compat
+
+ The application programmer can move any widget to the top of the
+ stack at any time using raiseWidget(), and add or remove widgets
+ using addWidget() and removeWidget(). It is not sufficient to pass
+ the widget stack as parent to a widget which should be inserted into
+ the widgetstack.
+
+ visibleWidget() is the \e get equivalent of raiseWidget(); it
+ returns a pointer to the widget that is currently at the top of
+ the stack.
+
+ TQWidgetStack also provides the ability to manipulate widgets
+ through application-specified integer IDs. You can also translate
+ from widget pointers to IDs using id() and from IDs to widget
+ pointers using widget(). These numeric IDs are unique (per
+ TQWidgetStack, not globally), but TQWidgetStack does not attach any
+ additional meaning to them.
+
+ The default widget stack is frameless, but you can use the usual
+ TQFrame functions (such as setFrameStyle()) to add a frame.
+
+ TQWidgetStack provides a signal, aboutToShow(), which is emitted
+ just before a managed widget is shown.
+
+ \sa TQTabDialog QTabWidget QTabBar TQFrame
+*/
+
+
+/*!
+ Constructs an empty widget stack.
+
+ The \a parent, \a name and \a f arguments are passed to the TQFrame
+ constructor.
+*/
+TQWidgetStack::TQWidgetStack(TQWidget * parent, const char *name, WFlags f)
+ : TQFrame(parent, name, f) //## merge constructors in 4.0
+{
+ init();
+}
+
+void TQWidgetStack::init()
+{
+ d = new TQWidgetStackPrivate();
+ d->nextNegativeID = -2;
+ d->nextPositiveID = 0;
+ dict = new TQIntDict<TQWidget>;
+ focusWidgets = 0;
+ topWidget = 0;
+ invisible = 0;
+ invisible = new TQWidgetStackPrivate::Invisible(this);
+ invisible->hide();
+}
+
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQWidgetStack::~TQWidgetStack()
+{
+ delete focusWidgets;
+ delete d;
+ delete dict;
+}
+
+
+/*!
+ Adds widget \a w to this stack of widgets, with ID \a id.
+
+ If you pass an id \>= 0 this ID is used. If you pass an \a id of
+ -1 (the default), the widgets will be numbered automatically. If
+ you pass -2 a unique negative integer will be generated. No widget
+ has an ID of -1. Returns the ID or -1 on failure (e.g. \a w is 0).
+
+ If you pass an id that is already used, then a unique negative
+ integer will be generated to prevent two widgets having the same
+ id.
+
+ If \a w already exists in the stack the widget will be removed first.
+
+ If \a w is not a child of this TQWidgetStack moves it using
+ reparent().
+*/
+
+int TQWidgetStack::addWidget(TQWidget * w, int id)
+{
+ if (!w || w == invisible || invisible == 0)
+ return -1;
+
+ // prevent duplicates
+ removeWidget(w);
+
+ if (id >= 0 && dict->tqfind(id))
+ id = -2;
+ if (id < -1)
+ id = d->nextNegativeID--;
+ else if (id == -1)
+ id = d->nextPositiveID++;
+ else
+ d->nextPositiveID = qMax(d->nextPositiveID, id + 1);
+ // use id >= 0 as-is
+
+ dict->insert(id, w);
+
+ // preserve existing focus
+ TQWidget * f = TQT_TQWIDGET(w->focusWidget());
+ while(f && f != w)
+ f = TQT_TQWIDGET(f->parentWidget());
+ if (f) {
+ if (!focusWidgets)
+ focusWidgets = new TQPtrDict<TQWidget>(17);
+ focusWidgets->tqreplace(w, TQT_TQWIDGET(w->focusWidget()));
+ }
+
+ w->hide();
+ if (w->parent() != this)
+ w->reparent(this, contentsRect().topLeft(), false);
+ w->setGeometry(contentsRect());
+ updateGeometry();
+ return id;
+}
+
+
+/*!
+ Removes widget \a w from this stack of widgets. Does not delete \a
+ w. If \a w is the currently visible widget, no other widget is
+ substituted.
+
+ \sa visibleWidget() raiseWidget()
+*/
+
+void TQWidgetStack::removeWidget(TQWidget * w)
+{
+ int i;
+ if (!w || (i = id(w)) == -1)
+ return ;
+
+ dict->take(i);
+ if (w == topWidget)
+ topWidget = 0;
+ if (dict->isEmpty())
+ invisible->hide(); // let background shine through again
+ updateGeometry();
+}
+
+
+/*!
+ Raises the widget with ID \a id to the top of the widget stack.
+
+ \sa visibleWidget()
+*/
+
+void TQWidgetStack::raiseWidget(int id)
+{
+ if (id == -1)
+ return;
+ TQWidget * w = dict->tqfind(id);
+ if (w)
+ raiseWidget(w);
+}
+
+static bool isChildOf(TQWidget* child, TQWidget *parent)
+{
+ if (!child)
+ return false;
+ for (int i = 0; i < parent->childrenListObject().count(); ++i) {
+ TQObject *obj = parent->childrenListObject().at(i);
+ if (!obj->isWidgetType())
+ continue;
+ TQWidget *widget = TQT_TQWIDGET((QWidget*)obj);
+ if (!widget->isWindow())
+ continue;
+ if (widget == child || isChildOf(child, widget))
+ return true;
+ }
+ return false;
+}
+
+/*!
+ \overload
+
+ Raises widget \a w to the top of the widget stack.
+*/
+
+void TQWidgetStack::raiseWidget(TQWidget *w)
+{
+ if (!w || w == invisible || w->parent() != this || w == topWidget)
+ return;
+
+ if (id(w) == -1)
+ addWidget(w);
+ if (!isVisible()) {
+ topWidget = w;
+ return;
+ }
+
+ if (w->maximumSize().width() < invisible->width()
+ || w->maximumSize().height() < invisible->height())
+ invisible->setBackgroundMode(backgroundMode());
+ else if (invisible->backgroundMode() != TQt::NoBackground)
+ invisible->setBackgroundMode(TQt::NoBackground);
+
+ if (invisible->isHidden()) {
+ invisible->setGeometry(contentsRect());
+ invisible->lower();
+ invisible->show();
+ QApplication::sendPostedEvents(invisible, QEvent::ShowWindowRequest);
+ }
+
+ // try to move focus onto the incoming widget if focus
+ // was somewhere on the outgoing widget.
+ if (topWidget) {
+ TQWidget * fw = TQT_TQWIDGET(window()->focusWidget());
+ if (topWidget->isAncestorOf(fw)) { // focus was on old page
+ // look for the best focus widget we can find
+ TQWidget *p = TQT_TQWIDGET(w->focusWidget());
+ if (!p) {
+ // second best == first child widget in the focus chain
+ TQWidget *i = fw;
+ while ((i = TQT_TQWIDGET(i->nextInFocusChain())) != fw) {
+ if (((i->focusPolicy() & Qt::TabFocus) == Qt::TabFocus)
+ && !i->focusProxy() && i->isVisibleTo(w) && i->isEnabled()
+ && w->isAncestorOf(i)) {
+ p = i;
+ break;
+ }
+ }
+ }
+ if (p)
+ p->setFocus();
+ } else {
+ // the focus wasn't on the old page, so we have to ensure focus doesn't go to
+ // the widget in the page that last had focus when we show the page again.
+ TQWidget *oldfw = TQT_TQWIDGET(topWidget->focusWidget());
+ if (oldfw)
+ oldfw->clearFocus();
+ }
+ }
+
+ if (isVisible()) {
+ emit aboutToShow(w);
+ int i = id(w);
+ if (i != -1)
+ emit aboutToShow(i);
+ }
+
+ topWidget = w;
+
+ for (int i = 0; i < childrenListObject().count(); ++i) {
+ TQObject * o = childrenListObject().at(i);
+ if (o->isWidgetType() && TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(w) && TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(invisible))
+ TQT_TQWIDGET((QWidget*)o)->hide();
+ }
+
+ w->setGeometry(invisible->geometry());
+ w->show();
+}
+
+/*!
+ \reimp
+*/
+
+void TQWidgetStack::frameChanged()
+{
+ TQFrame::frameChanged();
+ setChildGeometries();
+}
+
+
+/*!
+ \internal
+*/
+
+void TQWidgetStack::setFrameRect(const QRect & r)
+{
+ // ### this function used to be virtual in QFrame in Qt 3; it is no longer virtual in Qt 4
+ TQFrame::setFrameRect(r);
+ setChildGeometries();
+}
+
+
+/*!
+ Fixes up the children's geometries.
+*/
+
+void TQWidgetStack::setChildGeometries()
+{
+ invisible->setGeometry(contentsRect());
+ if (topWidget)
+ topWidget->setGeometry(invisible->geometry());
+}
+
+
+/*!
+ \reimp
+*/
+void TQWidgetStack::setVisible(bool visible)
+{
+ if (visible) {
+ // Reimplemented in order to set the children's geometries
+ // appropriately and to pick the first widget as d->topWidget if no
+ // topwidget was defined
+ if (!isVisible() && !childrenListObject().isEmpty()) {
+ for (int i = 0; i < childrenListObject().count(); ++i) {
+ TQObject * o = childrenListObject().at(i);
+ if (o->isWidgetType()) {
+ if (!topWidget && TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(invisible))
+ topWidget = TQT_TQWIDGET((QWidget*)o);
+ if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(topWidget))
+ TQT_TQWIDGET((QWidget*)o)->show();
+ else
+ TQT_TQWIDGET((QWidget*)o)->hide();
+ }
+ }
+ setChildGeometries();
+ }
+ }
+ TQFrame::setVisible(visible);
+}
+
+
+/*!
+ Returns the widget with ID \a id. Returns 0 if this widget stack
+ does not manage a widget with ID \a id.
+
+ \sa id() addWidget()
+*/
+
+TQWidget * TQWidgetStack::widget(int id) const
+{
+ return id != -1 ? dict->tqfind(id) : 0;
+}
+
+
+/*!
+ Returns the ID of the \a widget. Returns -1 if \a widget is 0 or
+ is not being managed by this widget stack.
+
+ \sa widget() addWidget()
+*/
+
+int TQWidgetStack::id(TQWidget * widget) const
+{
+ if (!widget)
+ return -1;
+
+ TQIntDictIterator<TQWidget> it(*dict);
+ while (it.current() && it.current() != widget)
+ ++it;
+ return it.current() == widget ? it.currentKey() : -1;
+}
+
+
+/*!
+ Returns the currently visible widget (the one at the top of the
+ stack), or 0 if nothing is currently being shown.
+
+ \sa aboutToShow() id() raiseWidget()
+*/
+
+TQWidget * TQWidgetStack::visibleWidget() const
+{
+ return topWidget;
+}
+
+
+/*!
+ \fn void TQWidgetStack::aboutToShow(int id)
+
+ This signal is emitted just before a managed widget is shown if
+ that managed widget has an ID != -1. The \a id parameter is the numeric
+ ID of the widget.
+
+ If you call visibleWidget() in a slot connected to aboutToShow(),
+ the widget it returns is the one that is currently visible, not
+ the one that is about to be shown.
+*/
+
+
+/*!
+ \fn void TQWidgetStack::aboutToShow(QWidget *widget)
+
+ \overload
+
+ This signal is emitted just before a managed widget is shown. The
+ argument is a pointer to the \a widget.
+
+ If you call visibleWidget() in a slot connected to aboutToShow(),
+ the widget returned is the one that is currently visible, not the
+ one that is about to be shown.
+*/
+
+
+/*!
+ \reimp
+*/
+
+void TQWidgetStack::resizeEvent(TQResizeEvent * e)
+{
+ TQFrame::resizeEvent(e);
+ setChildGeometries();
+}
+
+/*!
+ \reimp
+*/
+
+TQSize TQWidgetStack::tqsizeHint() const
+{
+ constPolish();
+
+ TQSize size(0, 0);
+
+ TQIntDictIterator<TQWidget> it(*dict);
+ TQWidget *w;
+
+ while ((w = it.current()) != 0) {
+ ++it;
+ TQSize sh = w->tqsizeHint();
+ if (w->tqsizePolicy().horData() == QSizePolicy::Ignored)
+ sh.rwidth() = 0;
+ if (w->tqsizePolicy().verData() == QSizePolicy::Ignored)
+ sh.rheight() = 0;
+#ifndef QT_NO_LAYOUT
+ size = size.expandedTo(sh).expandedTo(tqSmartMinSize(w));
+#endif
+ }
+ if (size.isNull())
+ size = TQSize(128, 64);
+ size += TQSize(2*frameWidth(), 2*frameWidth());
+ return size;
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQWidgetStack::tqminimumSizeHint() const
+{
+ constPolish();
+
+ TQSize size(0, 0);
+
+ TQIntDictIterator<TQWidget> it(*dict);
+ TQWidget *w;
+
+ while ((w = it.current()) != 0) {
+ ++it;
+ TQSize sh = w->tqminimumSizeHint();
+ if (w->tqsizePolicy().horData() == QSizePolicy::Ignored)
+ sh.rwidth() = 0;
+ if (w->tqsizePolicy().verData() == QSizePolicy::Ignored)
+ sh.rheight() = 0;
+#ifndef QT_NO_LAYOUT
+ size = size.expandedTo(sh).expandedTo(w->minimumSize());
+#endif
+ }
+ if (size.isNull())
+ size = TQSize(64, 32);
+ size += TQSize(2*frameWidth(), 2*frameWidth());
+ return size;
+}
+
+/*!
+ \reimp
+*/
+void TQWidgetStack::childEvent(TQChildEvent *e)
+{
+ if (e->child()->isWidgetType() && e->removed())
+ removeWidget((TQWidget *) e->child());
+}
+
+
+/*!
+ \reimp
+*/
+bool TQWidgetStack::event(TQEvent* e)
+{
+ if (e->type() == TQEvent::LayoutRequest || e->type() == TQEvent::LayoutHint )
+ updateGeometry(); // propgate layout hints to parent
+ return TQFrame::event(e);
+}
+
+QT_END_NAMESPACE
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Implementation of TQWidgetStack class
+**
+** Created : 980128
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqwidgetstack.h"
+#include "tqlayout.h"
+#include "../kernel/tqlayoutengine_p.h"
+#ifndef TQT_NO_WIDGETSTACK
+
+#include "tqobjectlist.h"
+#include "tqfocusdata.h"
+#include "tqbutton.h"
+#include "tqbuttongroup.h"
+
+#include "tqapplication.h"
+
+class TQWidgetStackPrivate {
+public:
+ class Invisible: public TQWidget
+ {
+ public:
+ Invisible( TQWidgetStack * tqparent ): TQWidget( tqparent, "qt_invisible_widgetstack" )
+ {
+ setBackgroundMode( TQt::NoBackground );
+ }
+ const char * className() const
+ {
+ return "TQWidgetStackPrivate::Invisible";
+ }
+ };
+};
+
+
+#if (TQT_VERSION-0 >= 0x040000)
+#if defined(TQ_CC_GNU)
+#warning "Remove TQWidgetStackEventFilter"
+#endif
+#endif
+class TQWidgetStackEventFilter : public TQObject
+{
+ /* For binary compatibility, since we cannot implement virtual
+ functions and rely on them being called. This is what we should
+ have
+
+ bool TQWidgetStack::event( TQEvent* e )
+ {
+ if ( e->type() == TQEvent::LayoutHint )
+ updateGeometry(); // propgate tqlayout hints to tqparent
+ return TQFrame::event( e );
+ }
+ */
+public:
+
+ TQWidgetStackEventFilter( TQObject *tqparent = 0, const char * name = 0 )
+ : TQObject( tqparent, name ) {}
+ bool eventFilter( TQObject *o, TQEvent * e ) {
+ if ( e->type() == TQEvent::LayoutHint && o->isWidgetType() )
+ ((TQWidget*)o)->updateGeometry();
+ return FALSE;
+ }
+};
+
+
+/*!
+ \class TQWidgetStack
+ \brief The TQWidgetStack class provides a stack of widgets of which
+ only the top widget is user-visible.
+
+ \ingroup organizers
+ \mainclass
+
+ The application programmer can move any widget to the top of the
+ stack at any time using raiseWidget(), and add or remove widgets
+ using addWidget() and removeWidget(). It is not sufficient to pass
+ the widget stack as tqparent to a widget which should be inserted into
+ the widgetstack.
+
+ visibleWidget() is the \e get equivalent of raiseWidget(); it
+ returns a pointer to the widget that is currently at the top of
+ the stack.
+
+ TQWidgetStack also provides the ability to manipulate widgets
+ through application-specified integer IDs. You can also translate
+ from widget pointers to IDs using id() and from IDs to widget
+ pointers using widget(). These numeric IDs are unique (per
+ TQWidgetStack, not globally), but TQWidgetStack does not attach any
+ additional meaning to them.
+
+ The default widget stack is frameless, but you can use the usual
+ TQFrame functions (such as setFrameStyle()) to add a frame.
+
+ TQWidgetStack provides a signal, aboutToShow(), which is emitted
+ just before a managed widget is shown.
+
+ \sa TQTabDialog TQTabBar TQFrame
+*/
+
+
+/*!
+ Constructs an empty widget stack.
+
+ The \a tqparent and \a name arguments are passed to the TQFrame
+ constructor.
+*/
+
+TQWidgetStack::TQWidgetStack( TQWidget * tqparent, const char *name )
+ : TQFrame( tqparent, name )
+{
+ init();
+}
+
+/*!
+ Constructs an empty widget stack.
+
+ The \a tqparent, \a name and \a f arguments are passed to the TQFrame
+ constructor.
+*/
+TQWidgetStack::TQWidgetStack( TQWidget * tqparent, const char *name, WFlags f )
+ : TQFrame( tqparent, name, f ) //## merge constructors in 4.0
+{
+ init();
+}
+
+void TQWidgetStack::init()
+{
+ d = 0;
+ TQWidgetStackEventFilter *ef = new TQWidgetStackEventFilter( TQT_TQOBJECT(this) );
+ installEventFilter( ef );
+ dict = new TQIntDict<TQWidget>;
+ tqfocusWidgets = 0;
+ topWidget = 0;
+ invisible = new TQWidgetStackPrivate::Invisible( this );
+ invisible->hide();
+}
+
+
+/*!
+ Destroys the object and frees any allocated resources.
+*/
+
+TQWidgetStack::~TQWidgetStack()
+{
+ delete tqfocusWidgets;
+ delete d;
+ delete dict;
+}
+
+
+/*!
+ Adds widget \a w to this stack of widgets, with ID \a id.
+
+ If you pass an id \>= 0 this ID is used. If you pass an \a id of
+ -1 (the default), the widgets will be numbered automatically. If
+ you pass -2 a unique negative integer will be generated. No widget
+ has an ID of -1. Returns the ID or -1 on failure (e.g. \a w is 0).
+
+ If you pass an id that is already used, then a unique negative
+ integer will be generated to prevent two widgets having the same
+ id.
+
+ If \a w already exists in the stack the widget will be removed first.
+
+ If \a w is not a child of this TQWidgetStack moves it using
+ reparent().
+*/
+
+int TQWidgetStack::addWidget( TQWidget * w, int id )
+{
+ static int nseq_no = -2;
+ static int pseq_no = 0;
+
+ if ( !w || w == invisible )
+ return -1;
+
+ // prevent duplicates
+ removeWidget( w );
+
+ if ( id >= 0 && dict->tqfind( id ) )
+ id = -2;
+ if ( id < -1 )
+ id = nseq_no--;
+ else if ( id == -1 )
+ id = pseq_no++;
+ else
+ pseq_no = TQMAX(pseq_no, id + 1);
+ // use id >= 0 as-is
+
+ dict->insert( id, w );
+
+ // preserve existing focus
+ TQWidget * f = w->tqfocusWidget();
+ while( f && f != w )
+ f = f->parentWidget();
+ if ( f ) {
+ if ( !tqfocusWidgets )
+ tqfocusWidgets = new TQPtrDict<TQWidget>( 17 );
+ tqfocusWidgets->tqreplace( w, w->tqfocusWidget() );
+ }
+
+ w->hide();
+ if ( w->tqparent() != TQT_TQOBJECT(this) )
+ w->reparent( this, contentsRect().topLeft(), FALSE );
+ w->setGeometry( contentsRect() );
+ updateGeometry();
+ return id;
+}
+
+
+/*!
+ Removes widget \a w from this stack of widgets. Does not delete \a
+ w. If \a w is the currently visible widget, no other widget is
+ substituted.
+
+ \sa visibleWidget() raiseWidget()
+*/
+
+void TQWidgetStack::removeWidget( TQWidget * w )
+{
+ if ( !w )
+ return;
+ int i = id( w );
+ if ( i != -1 )
+ dict->take( i );
+
+ if ( w == topWidget )
+ topWidget = 0;
+ if ( dict->isEmpty() )
+ invisible->hide(); // let background shine through again
+ updateGeometry();
+}
+
+
+/*!
+ Raises the widget with ID \a id to the top of the widget stack.
+
+ \sa visibleWidget()
+*/
+
+void TQWidgetStack::raiseWidget( int id )
+{
+ if ( id == -1 )
+ return;
+ TQWidget * w = dict->tqfind( id );
+ if ( w )
+ raiseWidget( w );
+}
+
+static bool isChildOf( TQWidget* child, TQWidget *tqparent )
+{
+ if ( !child || !tqparent->childrenListObject().isEmpty() )
+ return FALSE;
+ TQObjectListIt it(tqparent->childrenListObject());
+ TQObject *obj;
+ while ( (obj = it.current()) ) {
+ ++it;
+ if ( !obj->isWidgetType() || ((TQWidget *)obj)->isTopLevel() )
+ continue;
+ TQWidget *widget = (TQWidget *)obj;
+ if ( widget == child || isChildOf( child, widget ) )
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*!
+ \overload
+
+ Raises widget \a w to the top of the widget stack.
+*/
+
+void TQWidgetStack::raiseWidget( TQWidget *w )
+{
+ if ( !w || w == invisible || w->tqparent() != TQT_TQOBJECT(this) || w == topWidget )
+ return;
+
+ if ( id(w) == -1 )
+ addWidget( w );
+ if ( !isVisible() ) {
+ topWidget = w;
+ return;
+ }
+
+ if (w->tqmaximumSize().width() < invisible->width()
+ || w->tqmaximumSize().height() < invisible->height())
+ invisible->setBackgroundMode(backgroundMode());
+ else if (invisible->backgroundMode() != TQt::NoBackground)
+ invisible->setBackgroundMode(TQt::NoBackground);
+
+ if ( invisible->isHidden() ) {
+ invisible->setGeometry( contentsRect() );
+ invisible->lower();
+ invisible->show();
+ TQApplication::sendPostedEvents( invisible, TQEvent::ShowWindowRequest );
+ }
+
+ // try to move focus onto the incoming widget if focus
+ // was somewhere on the outgoing widget.
+ if ( topWidget ) {
+ TQWidget * fw = tqfocusWidget();
+ TQWidget* p = fw;
+ while ( p && p != topWidget )
+ p = p->parentWidget();
+ if ( p == topWidget ) { // focus was on old page
+ if ( !tqfocusWidgets )
+ tqfocusWidgets = new TQPtrDict<TQWidget>( 17 );
+ tqfocusWidgets->tqreplace( topWidget, fw );
+ fw->clearFocus();
+ // look for the best focus widget we can tqfind
+ // best == what we had (which may be deleted)
+ fw = tqfocusWidgets->take( w );
+ if ( isChildOf( fw, w ) ) {
+ fw->setFocus();
+ } else {
+ // second best == first child widget in the focus chain
+ TQFocusData *f = focusData();
+ TQWidget* home = f->home();
+ TQWidget *i = home;
+ do {
+ if ( ( ( i->focusPolicy() & Qt::TabFocus ) == Qt::TabFocus )
+ && !i->focusProxy() && i->isVisibleTo(w) && i->isEnabled() ) {
+ p = i;
+ while ( p && p != w )
+ p = p->parentWidget();
+ if ( p == w ) {
+ i->setFocus();
+ break;
+ }
+ }
+ i = f->next();
+ } while( i != home );
+ }
+ }
+ }
+
+ if ( isVisible() ) {
+ emit aboutToShow( w );
+ int i = id( w );
+ if ( i != -1 )
+ emit aboutToShow( i );
+ }
+
+ topWidget = w;
+
+ TQObjectListIt it( childrenListObject() );
+ TQObject * o;
+
+ while( (o=it.current()) != 0 ) {
+ ++it;
+ if ( o->isWidgetType() && o != TQT_TQOBJECT(w) && o != TQT_TQOBJECT(invisible) )
+ ((TQWidget *)o)->hide();
+ }
+
+ w->setGeometry( invisible->tqgeometry() );
+ w->show();
+}
+
+/*!
+ \reimp
+*/
+
+void TQWidgetStack::frameChanged()
+{
+ TQFrame::frameChanged();
+ setChildGeometries();
+}
+
+
+/*!
+ \reimp
+*/
+
+void TQWidgetStack::setFrameRect( const TQRect & r )
+{
+ TQFrame::setFrameRect( r );
+ setChildGeometries();
+}
+
+
+/*!
+ Fixes up the tqchildren's geometries.
+*/
+
+void TQWidgetStack::setChildGeometries()
+{
+ invisible->setGeometry( contentsRect() );
+ if ( topWidget )
+ topWidget->setGeometry( invisible->tqgeometry() );
+}
+
+
+/*!
+ \reimp
+*/
+void TQWidgetStack::show()
+{
+ // Reimplemented in order to set the tqchildren's geometries
+ // appropriately and to pick the first widget as topWidget if no
+ // topwidget was defined
+ if ( !isVisible() && !childrenListObject().isEmpty() ) {
+ TQObjectListIt it( childrenListObject() );
+ TQObject * o;
+
+ while( (o=it.current()) != 0 ) {
+ ++it;
+ if ( o->isWidgetType() ) {
+ if ( !topWidget && o != TQT_TQOBJECT(invisible) )
+ topWidget = (TQWidget*)o;
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(topWidget) )
+ ((TQWidget *)o)->show();
+ else
+ ((TQWidget *)o)->hide();
+ }
+ }
+ setChildGeometries();
+ }
+ TQFrame::show();
+}
+
+
+/*!
+ Returns the widget with ID \a id. Returns 0 if this widget stack
+ does not manage a widget with ID \a id.
+
+ \sa id() addWidget()
+*/
+
+TQWidget * TQWidgetStack::widget( int id ) const
+{
+ return id != -1 ? dict->tqfind( id ) : 0;
+}
+
+
+/*!
+ Returns the ID of the \a widget. Returns -1 if \a widget is 0 or
+ is not being managed by this widget stack.
+
+ \sa widget() addWidget()
+*/
+
+int TQWidgetStack::id( TQWidget * widget ) const
+{
+ if ( !widget )
+ return -1;
+
+ TQIntDictIterator<TQWidget> it( *dict );
+ while ( it.current() && it.current() != widget )
+ ++it;
+ return it.current() == widget ? it.currentKey() : -1;
+}
+
+
+/*!
+ Returns the currently visible widget (the one at the top of the
+ stack), or 0 if nothing is currently being shown.
+
+ \sa aboutToShow() id() raiseWidget()
+*/
+
+TQWidget * TQWidgetStack::visibleWidget() const
+{
+ return topWidget;
+}
+
+
+/*!
+ \fn void TQWidgetStack::aboutToShow( int )
+
+ This signal is emitted just before a managed widget is shown if
+ that managed widget has an ID != -1. The argument is the numeric
+ ID of the widget.
+
+ If you call visibleWidget() in a slot connected to aboutToShow(),
+ the widget it returns is the one that is currently visible, not
+ the one that is about to be shown.
+*/
+
+
+/*!
+ \fn void TQWidgetStack::aboutToShow( TQWidget * )
+
+ \overload
+
+ This signal is emitted just before a managed widget is shown. The
+ argument is a pointer to the widget.
+
+ If you call visibleWidget() in a slot connected to aboutToShow(),
+ the widget returned is the one that is currently visible, not the
+ one that is about to be shown.
+*/
+
+
+/*!
+ \reimp
+*/
+
+void TQWidgetStack::resizeEvent( TQResizeEvent * e )
+{
+ TQFrame::resizeEvent( e );
+ setChildGeometries();
+}
+
+
+/*!
+ \reimp
+*/
+
+TQSize TQWidgetStack::tqsizeHint() const
+{
+ constPolish();
+
+ TQSize size( 0, 0 );
+
+ TQIntDictIterator<TQWidget> it( *dict );
+ TQWidget *w;
+
+ while ( (w = it.current()) != 0 ) {
+ ++it;
+ TQSize sh = w->tqsizeHint();
+ if ( w->tqsizePolicy().horData() == TQSizePolicy::Ignored )
+ sh.rwidth() = 0;
+ if ( w->tqsizePolicy().verData() == TQSizePolicy::Ignored )
+ sh.rheight() = 0;
+#ifndef TQT_NO_LAYOUT
+ size = size.expandedTo( sh ).expandedTo( tqSmartMinSize(w) );
+#endif
+ }
+ if ( size.isNull() )
+ size = TQSize( 128, 64 );
+ size += TQSize( 2*frameWidth(), 2*frameWidth() );
+ return size;
+}
+
+
+/*!
+ \reimp
+*/
+TQSize TQWidgetStack::tqminimumSizeHint() const
+{
+ constPolish();
+
+ TQSize size( 0, 0 );
+
+ TQIntDictIterator<TQWidget> it( *dict );
+ TQWidget *w;
+
+ while ( (w = it.current()) != 0 ) {
+ ++it;
+ TQSize sh = w->tqminimumSizeHint();
+ if ( w->tqsizePolicy().horData() == TQSizePolicy::Ignored )
+ sh.rwidth() = 0;
+ if ( w->tqsizePolicy().verData() == TQSizePolicy::Ignored )
+ sh.rheight() = 0;
+#ifndef TQT_NO_LAYOUT
+ size = size.expandedTo( sh ).expandedTo( w->tqminimumSize() );
+#endif
+ }
+ if ( size.isNull() )
+ size = TQSize( 64, 32 );
+ size += TQSize( 2*frameWidth(), 2*frameWidth() );
+ return size;
+}
+
+/*!
+ \reimp
+*/
+void TQWidgetStack::childEvent( TQChildEvent * e)
+{
+ if ( e->child()->isWidgetType() && e->removed() )
+ removeWidget( (TQWidget*) e->child() );
+}
+#endif
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/widgets/tqwidgetstack.h b/tqtinterface/qt4/src/widgets/tqwidgetstack.h
new file mode 100644
index 0000000..5c0acfd
--- /dev/null
+++ b/tqtinterface/qt4/src/widgets/tqwidgetstack.h
@@ -0,0 +1,235 @@
+#include "tqtglobaldefines.h"
+
+#ifdef USE_QT4
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt3Support module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TQWIDGETSTACK_H
+#define TQWIDGETSTACK_H
+
+#include <tqframe.h>
+#include <tqintdict.h>
+#include <tqptrdict.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Qt3SupportLight)
+
+class TQWidgetStackPrivate;
+
+
+class Q_COMPAT_EXPORT TQWidgetStack: public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQWidgetStack(TQWidget* parent, const char* name=0, WFlags f=0);
+
+ ~TQWidgetStack();
+
+ int addWidget(TQWidget *, int = -1);
+ void removeWidget(TQWidget *);
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+ void setVisible(bool visible);
+
+ TQWidget * widget(int) const;
+ int id(TQWidget *) const;
+
+ TQWidget * visibleWidget() const;
+
+ void setFrameRect(const QRect &);
+
+Q_SIGNALS:
+ void aboutToShow(int);
+ void aboutToShow(TQWidget *);
+
+public Q_SLOTS:
+ void raiseWidget(int);
+ void raiseWidget(TQWidget *);
+
+protected:
+ void frameChanged();
+ void resizeEvent(TQResizeEvent *);
+ bool event(TQEvent* e);
+
+ virtual void setChildGeometries();
+ void childEvent(TQChildEvent *);
+
+private:
+ void init();
+
+ TQWidgetStackPrivate * d;
+ TQIntDict<TQWidget> * dict;
+ TQPtrDict<TQWidget> * focusWidgets;
+ TQWidget * topWidget;
+ TQWidget * invisible;
+
+ Q_DISABLE_COPY(TQWidgetStack)
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // TQWIDGETSTACK_H
+
+#else // USE_QT4
+
+/****************************************************************************
+**
+** Definition of TQWidgetStack class
+**
+** Created : 980306
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the widgets module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWIDGETSTACK_H
+#define TQWIDGETSTACK_H
+
+#ifndef TQT_H
+#include "tqframe.h"
+#include "tqintdict.h"
+#include "tqptrdict.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_WIDGETSTACK
+
+
+class TQWidgetStackPrivate;
+
+
+class TQ_EXPORT TQWidgetStack: public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+public:
+ TQWidgetStack( TQWidget* tqparent=0, const char* name=0 );
+ TQWidgetStack( TQWidget* tqparent, const char* name, WFlags f);
+
+ ~TQWidgetStack();
+
+ int addWidget( TQWidget *, int = -1 );
+ void removeWidget( TQWidget * );
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+ void show();
+
+ TQWidget * widget( int ) const;
+ int id( TQWidget * ) const;
+
+ TQWidget * visibleWidget() const;
+
+ void setFrameRect( const TQRect & );
+
+Q_SIGNALS:
+ void aboutToShow( int );
+ void aboutToShow( TQWidget * );
+
+public Q_SLOTS:
+ void raiseWidget( int );
+ void raiseWidget( TQWidget * );
+
+protected:
+ void frameChanged();
+ void resizeEvent( TQResizeEvent * );
+
+ virtual void setChildGeometries();
+ void childEvent( TQChildEvent * );
+
+private:
+ void init();
+
+ TQWidgetStackPrivate * d;
+ TQIntDict<TQWidget> * dict;
+ TQPtrDict<TQWidget> * tqfocusWidgets;
+ TQWidget * topWidget;
+ TQWidget * invisible;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQWidgetStack( const TQWidgetStack & );
+ TQWidgetStack& operator=( const TQWidgetStack & );
+#endif
+};
+
+#endif // TQT_NO_WIDGETSTACK
+
+#endif // TQWIDGETSTACK_H
+
+#endif // USE_QT4
diff --git a/tqtinterface/qt4/src/workspace/qt_workspace.pri b/tqtinterface/qt4/src/workspace/qt_workspace.pri
new file mode 100644
index 0000000..1e7469d
--- /dev/null
+++ b/tqtinterface/qt4/src/workspace/qt_workspace.pri
@@ -0,0 +1,6 @@
+# Qt workspace module
+
+workspace {
+ HEADERS += $$WORKSPACE_H/tqworkspace.h
+ SOURCES += $$WORKSPACE_CPP/tqworkspace.cpp
+}
diff --git a/tqtinterface/qt4/src/workspace/tqworkspace.cpp b/tqtinterface/qt4/src/workspace/tqworkspace.cpp
new file mode 100644
index 0000000..164a670
--- /dev/null
+++ b/tqtinterface/qt4/src/workspace/tqworkspace.cpp
@@ -0,0 +1,3033 @@
+/****************************************************************************
+**
+** Implementation of the TQWorkspace class
+**
+** Created : 931107
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the workspace module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqworkspace.h"
+#ifndef TQT_NO_WORKSPACE
+#include "tqapplication.h"
+#include "../widgets/tqtitlebar_p.h"
+#include "tqobjectlist.h"
+#include "tqlayout.h"
+#include "tqtoolbutton.h"
+#include "tqlabel.h"
+#include "tqvbox.h"
+#include "tqaccel.h"
+#include "tqcursor.h"
+#include "tqpopupmenu.h"
+#include "tqmenubar.h"
+#include "tqguardedptr.h"
+#include "tqiconset.h"
+#include "../widgets/tqwidgetresizehandler_p.h"
+#include "tqfocusdata.h"
+#include "tqdatetime.h"
+#include "tqtooltip.h"
+#include "tqwmatrix.h"
+#include "tqimage.h"
+#include "tqscrollbar.h"
+#include "tqstyle.h"
+#include "tqbitmap.h"
+
+// magic non-mdi things
+#include "tqtimer.h"
+#include "tqdockarea.h"
+#include "tqstatusbar.h"
+#include "tqmainwindow.h"
+#include "tqdockwindow.h"
+#include "tqtoolbar.h"
+
+#define BUTTON_WIDTH 16
+#define BUTTON_HEIGHT 14
+
+/*!
+ \class TQWorkspace tqworkspace.h
+ \brief The TQWorkspace widget provides a workspace window that can
+ contain decorated windows, e.g. for MDI.
+
+ \module workspace
+
+ \ingroup application
+ \ingroup organizers
+ \mainclass
+
+ MDI (multiple document interface) applications typically have one
+ main window with a menu bar and toolbar, and a central widget that
+ is a TQWorkspace. The workspace itself tqcontains zero, one or more
+ document windows, each of which is a widget.
+
+ The workspace itself is an ordinary TQt widget. It has a standard
+ constructor that takes a tqparent widget and an object name. The
+ tqparent window is usually a TQMainWindow, but it need not be.
+
+ Document windows (i.e. MDI windows) are also ordinary TQt widgets
+ which have the workspace as their tqparent widget. When you call
+ show(), hide(), showMaximized(), setCaption(), etc. on a document
+ window, it is shown, hidden, etc. with a frame, caption, icon and
+ icon text, just as you'd expect. You can provide widget flags
+ which will be used for the tqlayout of the decoration or the
+ behaviour of the widget itself.
+
+ To change or retrieve the tqgeometry of MDI windows you must operate
+ on the MDI widget's parentWidget(). (The parentWidget() provides
+ access to the decorated window in which the MDI window's widget is
+ shown.)
+
+ A document window becomes active when it gets the keyboard focus.
+ You can also activate a window in code using setFocus(). The user
+ can activate a window by moving focus in the usual ways, for
+ example by clicking a window or by pressing Tab. The workspace
+ emits a signal windowActivated() when it detects the activation
+ change, and the function activeWindow() always returns a pointer
+ to the active document window.
+
+ The convenience function windowList() returns a list of all
+ document windows. This is useful to create a popup menu
+ "<u>W</u>indows" on the fly, for example.
+
+ TQWorkspace provides two built-in tqlayout strategies for child
+ windows: cascade() and tile(). Both are Q_SLOTS so you can easily
+ connect menu entries to them.
+
+ If you want your users to be able to work with document windows
+ larger than the actual workspace, set the scrollBarsEnabled
+ property to TRUE.
+
+ If the top-level window tqcontains a menu bar and a document window
+ is maximised, TQWorkspace moves the document window's minimize,
+ restore and close buttons from the document window's frame to the
+ workspace window's menu bar. It then inserts a window operations
+ menu at the far left of the menu bar.
+*/
+
+static bool inCaptionChange = FALSE;
+
+class TQWorkspaceChild : public TQFrame
+{
+ Q_OBJECT
+ TQ_OBJECT
+
+ friend class TQWorkspace;
+ friend class TQTitleBar;
+
+public:
+ TQWorkspaceChild( TQWidget* window,
+ TQWorkspace* tqparent=0, const char* name=0 );
+ ~TQWorkspaceChild();
+
+ void setActive( bool );
+ bool isActive() const;
+
+ void adjustToFullscreen();
+
+ void setqStatusBar(TQStatusBar *);
+ TQWidget* windowWidget() const;
+ TQWidget* iconWidget() const;
+
+ void doResize();
+ void doMove();
+
+ TQSize tqsizeHint() const;
+ TQSize tqminimumSizeHint() const;
+
+ TQSize baseSize() const;
+
+Q_SIGNALS:
+ void showOperationMenu();
+ void popupOperationMenu( const TQPoint& );
+
+public Q_SLOTS:
+ void activate();
+ void showMinimized();
+ void showMaximized();
+ void showNormal();
+ void showShaded();
+ void setCaption( const TQString& );
+ void internalRaise();
+ void titleBarDoubleClicked();
+
+ void move( int x, int y );
+
+protected:
+ bool event(TQEvent * );
+ void enterEvent( TQEvent * );
+ void leaveEvent( TQEvent * );
+ void childEvent( TQChildEvent* );
+ void resizeEvent( TQResizeEvent * );
+ void moveEvent( TQMoveEvent * );
+ bool eventFilter( TQObject *, TQEvent * );
+
+ bool focusNextPrevChild( bool );
+
+ void drawFrame( TQPainter * );
+ void styleChange( TQStyle & );
+
+private:
+ TQWidget* childWidget;
+ TQGuardedPtr<TQWidget> lastfocusw;
+ TQWidgetResizeHandler *widgetResizeHandler;
+ TQTitleBar* titlebar;
+ TQGuardedPtr<TQStatusBar> statusbar;
+ TQGuardedPtr<TQTitleBar> iconw;
+ TQSize windowSize;
+ TQSize shadeRestore;
+ TQSize shadeRestoreMin;
+ bool act :1;
+ bool shademode :1;
+ bool snappedRight :1;
+ bool snappedDown :1;
+#if defined(TQ_DISABLE_COPY) // Disabled copy constructor and operator=
+ TQWorkspaceChild( const TQWorkspaceChild & );
+ TQWorkspaceChild &operator=( const TQWorkspaceChild & );
+#endif
+};
+
+class TQMainWindow;
+
+class TQWorkspacePrivate {
+public:
+ TQWorkspaceChild* active;
+ TQPtrList<TQWorkspaceChild> windows;
+ TQPtrList<TQWorkspaceChild> focus;
+ TQPtrList<TQWidget> icons;
+ TQWorkspaceChild* maxWindow;
+ TQRect maxRestore;
+ TQGuardedPtr<TQFrame> maxcontrols;
+ TQGuardedPtr<TQMenuBar> maxmenubar;
+
+ int px;
+ int py;
+ TQWidget *becomeActive;
+ TQGuardedPtr<TQLabel> maxtools;
+ TQPopupMenu* popup;
+ TQPopupMenu* toolPopup;
+ int menuId;
+ int controlId;
+ TQString topCaption;
+
+ TQScrollBar *vbar, *hbar;
+ TQWidget *corner;
+ int yoffset, xoffset;
+
+ // toplevel mdi fu
+ TQWorkspace::WindowMode wmode;
+ TQGuardedPtr<TQMainWindow> mainwindow;
+ TQPtrList<TQDockWindow> dockwindows, newdocks;
+};
+
+static bool isChildOf( TQWidget * child, TQWidget * tqparent )
+{
+ if ( !tqparent || !child )
+ return FALSE;
+ TQWidget * w = child;
+ while( w && w != tqparent )
+ w = w->parentWidget();
+ return w != 0;
+}
+
+/*!
+ Constructs a workspace with a \a tqparent and a \a name.
+*/
+TQWorkspace::TQWorkspace( TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name )
+{
+ init();
+}
+
+#ifdef TQT_WORKSPACE_WINDOWMODE
+/*!
+ Constructs a workspace with a \a tqparent and a \a name. This
+ constructor will also set the WindowMode to \a mode.
+
+ \sa windowMode()
+*/
+TQWorkspace::TQWorkspace( TQWorkspace::WindowMode mode, TQWidget *tqparent, const char *name )
+ : TQWidget( tqparent, name )
+{
+ init();
+ d->wmode = mode;
+}
+#endif
+
+
+/*!
+ \internal
+*/
+void
+TQWorkspace::init()
+{
+ d = new TQWorkspacePrivate;
+ d->maxcontrols = 0;
+ d->active = 0;
+ d->maxWindow = 0;
+ d->maxtools = 0;
+ d->px = 0;
+ d->py = 0;
+ d->becomeActive = 0;
+#if defined( TQT_WORKSPACE_WINDOWMODE ) && defined( TQ_WS_MAC )
+ d->wmode = AutoDetect;
+#else
+ d->wmode = MDI;
+#endif
+ d->mainwindow = 0;
+#if defined(TQ_WS_WIN)
+ d->popup = new TQPopupMenu( this, "qt_internal_mdi_popup" );
+ d->toolPopup = new TQPopupMenu( this, "qt_internal_mdi_popup" );
+#else
+ d->popup = new TQPopupMenu( parentWidget(), "qt_internal_mdi_popup" );
+ d->toolPopup = new TQPopupMenu( parentWidget(), "qt_internal_mdi_popup" );
+#endif
+
+ d->menuId = -1;
+ d->controlId = -1;
+ connect( d->popup, TQT_SIGNAL( aboutToShow() ), this, TQT_SLOT(operationMenuAboutToShow() ));
+ connect( d->popup, TQT_SIGNAL( activated(int) ), this, TQT_SLOT( operationMenuActivated(int) ) );
+ d->popup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarNormalButton)), tqtr("&Restore"), 1);
+ d->popup->insertItem(tqtr("&Move"), 2);
+ d->popup->insertItem(tqtr("&Size"), 3);
+ d->popup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarMinButton)), tqtr("Mi&nimize"), 4);
+ d->popup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarMaxButton)), tqtr("Ma&ximize"), 5);
+ d->popup->insertSeparator();
+ d->popup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarCloseButton)),
+ TQT_TQSTRING(tqtr("&Close")
+#ifndef TQT_NO_ACCEL
+ +"\t"+TQAccel::keyToString(TQt::CTRL+Qt::Key_F4)
+#endif
+ ), TQT_TQOBJECT(this), TQT_SLOT( closeActiveWindow() ) );
+
+ connect( d->toolPopup, TQT_SIGNAL( aboutToShow() ), this, TQT_SLOT(toolMenuAboutToShow() ));
+ connect( d->toolPopup, TQT_SIGNAL( activated(int) ), this, TQT_SLOT( operationMenuActivated(int) ) );
+ d->toolPopup->insertItem(tqtr("&Move"), 2);
+ d->toolPopup->insertItem(tqtr("&Size"), 3);
+ d->toolPopup->insertItem(tqtr("Stay on &Top"), 7);
+ d->toolPopup->setItemChecked( 7, TRUE );
+ d->toolPopup->setCheckable( TRUE );
+ d->toolPopup->insertSeparator();
+ d->toolPopup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarShadeButton)), tqtr("Sh&ade"), 6);
+ d->toolPopup->insertItem(TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarCloseButton)),
+ TQT_TQSTRING(tqtr("&Close")
+#ifndef TQT_NO_ACCEL
+ +"\t"+TQAccel::keyToString( TQt::CTRL+Qt::Key_F4)
+#endif
+ ), TQT_TQOBJECT(this), TQT_SLOT( closeActiveWindow() ) );
+
+#ifndef TQT_NO_ACCEL
+ TQAccel* a = new TQAccel( this );
+ a->connectItem( a->insertItem( TQt::ALT + Qt::Key_Minus),
+ this, TQT_SLOT( showOperationMenu() ) );
+
+ a->connectItem( a->insertItem( TQt::CTRL + Qt::Key_F6),
+ this, TQT_SLOT( activateNextWindow() ) );
+ a->connectItem( a->insertItem( TQt::CTRL + Qt::Key_Tab),
+ this, TQT_SLOT( activateNextWindow() ) );
+ a->connectItem( a->insertItem( Qt::Key_Forward ),
+ this, TQT_SLOT( activateNextWindow() ) );
+
+ a->connectItem( a->insertItem( TQt::CTRL + TQt::SHIFT + Qt::Key_F6),
+ this, TQT_SLOT( activatePreviousWindow() ) );
+ a->connectItem( a->insertItem( TQt::CTRL + TQt::SHIFT + Qt::Key_Tab),
+ this, TQT_SLOT( activatePreviousWindow() ) );
+ a->connectItem( a->insertItem( Qt::Key_Back ),
+ this, TQT_SLOT( activatePreviousWindow() ) );
+
+ a->connectItem( a->insertItem( TQt::CTRL + Qt::Key_F4 ),
+ this, TQT_SLOT( closeActiveWindow() ) );
+#endif
+
+ setBackgroundMode( TQt::PaletteDark );
+ tqsetSizePolicy( TQSizePolicy( TQSizePolicy::Expanding, TQSizePolicy::Expanding ) );
+
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ d->topCaption = tqtopLevelWidget()->caption();
+#endif
+
+ d->hbar = d->vbar = 0;
+ d->corner = 0;
+ d->xoffset = d->yoffset = 0;
+
+ updateWorkspace();
+
+ tqtopLevelWidget()->installEventFilter( this );
+}
+
+/*! Destroys the workspace and frees any allocated resources. */
+
+TQWorkspace::~TQWorkspace()
+{
+ delete d;
+ d = 0;
+}
+
+/*!\reimp */
+TQSize TQWorkspace::tqsizeHint() const
+{
+ TQSize s( TQApplication::desktop()->size() );
+ return TQSize( s.width()*2/3, s.height()*2/3);
+}
+
+/*! \reimp */
+void TQWorkspace::setPaletteBackgroundColor( const TQColor & c )
+{
+ setEraseColor( c );
+}
+
+
+/*! \reimp */
+void TQWorkspace::setPaletteBackgroundPixmap( const TQPixmap & pm )
+{
+ setErasePixmap( pm );
+}
+
+/*! \reimp */
+void TQWorkspace::childEvent( TQChildEvent * e)
+{
+ if (e->inserted() && e->child()->isWidgetType()) {
+ TQWidget* w = static_cast<TQWidget*>(static_cast<QWidget*>(e->child()));
+ if ( !w || !w->testWFlags( (WFlags)(TQt::WStyle_Title | TQt::WStyle_NormalBorder | TQt::WStyle_DialogBorder) ) || w->testWFlags(TQt::WType_Dialog)
+ || d->icons.tqcontains( w ) || w == d->vbar || w == d->hbar || w == d->corner )
+ return; // nothing to do
+
+ bool wasMaximized = w->isMaximized();
+ bool wasMinimized = w->isMinimized();
+ bool hasBeenHidden = w->isHidden();
+ bool hasSize = w->testWState( TQt::WState_Resized );
+ int x = w->x();
+ int y = w->y();
+ bool hasPos = x != 0 || y != 0;
+ TQSize s = w->size().expandedTo( w->minimumSizeHint() );
+ if ( !hasSize && w->sizeHint().isValid() ) {
+ w->adjustSize();
+ }
+
+ TQWorkspaceChild* child = new TQWorkspaceChild( w, this, "qt_workspacechild" );
+ child->installEventFilter( this );
+
+ connect( child, TQT_SIGNAL( popupOperationMenu(const TQPoint&) ),
+ this, TQT_SLOT( popupOperationMenu(const TQPoint&) ) );
+ connect( child, TQT_SIGNAL( showOperationMenu() ),
+ this, TQT_SLOT( showOperationMenu() ) );
+ d->windows.append( child );
+ if ( child->isVisibleTo( this ) ) {
+ d->focus.append( child );
+ }
+ child->internalRaise();
+
+ if ( !hasPos )
+ place( child );
+ if ( hasSize )
+ child->resize( s + child->baseSize() );
+ else
+ child->adjustSize();
+ if ( hasPos )
+ child->move( x, y );
+
+ if ( hasBeenHidden )
+ w->hide();
+ else if ( !isVisible() ) // that's a case were we don't receive a showEvent in time. Tricky.
+ child->show();
+
+ if ( wasMaximized )
+ w->showMaximized();
+ else if ( wasMinimized )
+ w->showMinimized();
+ else if (!hasBeenHidden)
+ activateWindow( w );
+
+ updateWorkspace();
+ } else if (e->removed() ) {
+ if ( d->windows.tqcontains( (TQWorkspaceChild*)e->child() ) ) {
+ d->windows.removeRef( (TQWorkspaceChild*)e->child() );
+ d->focus.removeRef( (TQWorkspaceChild*)e->child() );
+ if (d->maxWindow == e->child())
+ d->maxWindow = 0;
+ updateWorkspace();
+ }
+ }
+}
+
+/*! \reimp
+*/
+#ifndef TQT_NO_WHEELEVENT
+void TQWorkspace::wheelEvent( TQWheelEvent *e )
+{
+ if ( !scrollBarsEnabled() )
+ return;
+ if ( d->vbar && d->vbar->isVisible() && !( e->state() & TQt::AltButton ) )
+ TQApplication::sendEvent( d->vbar, e );
+ else if ( d->hbar && d->hbar->isVisible() )
+ TQApplication::sendEvent( d->hbar, e );
+}
+#endif
+
+void TQWorkspace::activateWindow( TQWidget* w, bool change_focus )
+{
+ if ( !w ) {
+ d->active = 0;
+ emit windowActivated( 0 );
+ return;
+ }
+ if ( d->wmode == MDI && !isVisibleTo( 0 ) ) {
+ d->becomeActive = w;
+ return;
+ }
+
+ if ( d->active && d->active->windowWidget() == w ) {
+ if ( !isChildOf( tqfocusWidget(), w ) ) // child window does not have focus
+ d->active->setActive( TRUE );
+ return;
+ }
+
+ d->active = 0;
+ // First deactivate all other workspace clients
+ TQPtrListIterator<TQWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ TQWorkspaceChild* c = it.current();
+ ++it;
+ if(windowMode() == TQWorkspace::TopLevel && c->isTopLevel() &&
+ c->windowWidget() == w && !c->isActive())
+ c->setActiveWindow();
+ if (c->windowWidget() == w)
+ d->active = c;
+ else
+ c->setActive( FALSE );
+ }
+
+ if (!d->active)
+ return;
+
+ // Then activate the new one, so the focus is stored correctly
+ d->active->setActive( TRUE );
+
+ if (!d->active)
+ return;
+
+ if ( d->maxWindow && d->maxWindow != d->active && d->active->windowWidget() &&
+ d->active->windowWidget()->testWFlags( TQt::WStyle_MinMax ) &&
+ !d->active->windowWidget()->testWFlags( TQt::WStyle_Tool ) ) {
+ d->active->showMaximized();
+ if ( d->maxtools ) {
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( w->icon() ) {
+ TQPixmap pm(*w->icon());
+ int iconSize = d->maxtools->size().height();
+ if(pm.width() > iconSize || pm.height() > iconSize) {
+ TQImage im;
+ im = pm;
+ pm = im.smoothScale( TQMIN(iconSize, pm.width()), TQMIN(iconSize, pm.height()) );
+ }
+ d->maxtools->setPixmap( pm );
+ } else
+#endif
+ {
+ TQPixmap pm(14,14);
+ pm.fill( Qt::color1 );
+ pm.setMask(pm.createHeuristicMask());
+ d->maxtools->setPixmap( pm );
+ }
+ }
+ } else { // done implicitly in maximizeWindow otherwise
+ d->active->internalRaise();
+ }
+
+ if ( change_focus ) {
+ if ( d->focus.tqfind( d->active ) >=0 ) {
+ d->focus.removeRef( d->active );
+ d->focus.append( d->active );
+ }
+ }
+
+ updateWorkspace();
+ emit windowActivated( w );
+}
+
+
+/*!
+ Returns the active window, or 0 if no window is active.
+*/
+TQWidget* TQWorkspace::activeWindow() const
+{
+ return d->active?d->active->windowWidget():0;
+}
+
+
+void TQWorkspace::place( TQWidget* w)
+{
+ TQPtrList<TQWidget> widgets;
+ for(TQPtrListIterator<TQWorkspaceChild> it( d->windows ); it.current(); ++it)
+ if ((*it) != w)
+ widgets.append((*it));
+
+ if(d->wmode == TopLevel) {
+ for(TQPtrListIterator<TQDockWindow> it( d->dockwindows ); it.current(); ++it)
+ if ((*it) != w)
+ widgets.append((*it));
+ }
+
+ int overlap, minOverlap = 0;
+ int possible;
+
+ TQRect r1(0, 0, 0, 0);
+ TQRect r2(0, 0, 0, 0);
+ TQRect maxRect = rect();
+ if(d->wmode == TopLevel) {
+ const TQDesktopWidget *dw = tqApp->desktop();
+ maxRect = dw->availableGeometry(dw->screenNumber(tqtopLevelWidget()));
+ }
+ int x = maxRect.left(), y = maxRect.top();
+ TQPoint wpos(maxRect.left(), maxRect.top());
+
+ bool firstPass = TRUE;
+
+ do {
+ if ( y + w->height() > maxRect.bottom() ) {
+ overlap = -1;
+ } else if( x + w->width() > maxRect.right() ) {
+ overlap = -2;
+ } else {
+ overlap = 0;
+
+ r1.setRect(x, y, w->width(), w->height());
+
+ TQWidget *l;
+ TQPtrListIterator<TQWidget> it( widgets );
+ while ( it.current () ) {
+ l = it.current();
+ ++it;
+
+ if ( d->maxWindow == l )
+ r2 = d->maxRestore;
+ else
+ r2.setRect(l->x(), l->y(), l->width(), l->height());
+
+ if (r2.intersects(r1)) {
+ r2.setCoords(TQMAX(r1.left(), r2.left()),
+ TQMAX(r1.top(), r2.top()),
+ TQMIN(r1.right(), r2.right()),
+ TQMIN(r1.bottom(), r2.bottom())
+ );
+
+ overlap += (r2.right() - r2.left()) *
+ (r2.bottom() - r2.top());
+ }
+ }
+ }
+
+ if (overlap == 0) {
+ wpos = TQPoint(x, y);
+ break;
+ }
+
+ if (firstPass) {
+ firstPass = FALSE;
+ minOverlap = overlap;
+ } else if ( overlap >= 0 && overlap < minOverlap) {
+ minOverlap = overlap;
+ wpos = TQPoint(x, y);
+ }
+
+ if ( overlap > 0 ) {
+ possible = maxRect.right();
+ if ( possible - w->width() > x) possible -= w->width();
+
+ TQWidget *l;
+ TQPtrListIterator<TQWidget> it( widgets );
+ while ( it.current () ) {
+ l = it.current();
+ ++it;
+ if ( d->maxWindow == l )
+ r2 = d->maxRestore;
+ else
+ r2.setRect(l->x(), l->y(), l->width(), l->height());
+
+ if( ( y < r2.bottom() ) && ( r2.top() < w->height() + y ) ) {
+ if( r2.right() > x )
+ possible = possible < r2.right() ?
+ possible : r2.right();
+
+ if( r2.left() - w->width() > x )
+ possible = possible < r2.left() - w->width() ?
+ possible : r2.left() - w->width();
+ }
+ }
+
+ x = possible;
+ } else if ( overlap == -2 ) {
+ x = maxRect.left();
+ possible = maxRect.bottom();
+
+ if ( possible - w->height() > y ) possible -= w->height();
+
+ TQWidget *l;
+ TQPtrListIterator<TQWidget> it( widgets );
+ while ( it.current () ) {
+ l = it.current();
+ ++it;
+ if ( d->maxWindow == l )
+ r2 = d->maxRestore;
+ else
+ r2.setRect(l->x(), l->y(), l->width(), l->height());
+
+ if( r2.bottom() > y)
+ possible = possible < r2.bottom() ?
+ possible : r2.bottom();
+
+ if( r2.top() - w->height() > y )
+ possible = possible < r2.top() - w->height() ?
+ possible : r2.top() - w->height();
+ }
+
+ y = possible;
+ }
+ }
+ while( overlap != 0 && overlap != -1 );
+
+#if 0
+ if(windowMode() == TQWorkspace::TopLevel && wpos.y()) {
+ TQPoint fr = w->tqtopLevelWidget()->frameGeometry().topLeft(),
+ r = w->tqtopLevelWidget()->tqgeometry().topLeft();
+ wpos += TQPoint(r.x() - fr.x(), r.y() - fr.y());
+ }
+#endif
+ w->move(wpos);
+ updateWorkspace();
+}
+
+
+void TQWorkspace::insertIcon( TQWidget* w )
+{
+ if ( !w || d->icons.tqcontains( w ) )
+ return;
+ d->icons.append( w );
+ if (w->parentWidget() != this )
+ w->reparent( this, 0, TQPoint(0,0), FALSE);
+ TQRect cr = updateWorkspace();
+ int x = 0;
+ int y = cr.height() - w->height();
+
+ TQPtrListIterator<TQWidget> it( d->icons );
+ while ( it.current () ) {
+ TQWidget* i = it.current();
+ ++it;
+ if ( x > 0 && x + i->width() > cr.width() ){
+ x = 0;
+ y -= i->height();
+ }
+
+ if ( i != w &&
+ i->tqgeometry().intersects( TQRect( x, y, w->width(), w->height() ) ) )
+ x += i->width();
+ }
+ w->move( x, y );
+
+ if ( isVisibleTo( parentWidget() ) ) {
+ w->show();
+ w->lower();
+ }
+ updateWorkspace();
+}
+
+
+void TQWorkspace::removeIcon( TQWidget* w)
+{
+ if ( !d->icons.tqcontains( w ) )
+ return;
+ d->icons.remove( w );
+ w->hide();
+}
+
+
+/*! \reimp */
+void TQWorkspace::resizeEvent( TQResizeEvent * )
+{
+ if ( d->maxWindow ) {
+ d->maxWindow->adjustToFullscreen();
+ if (d->maxWindow->windowWidget())
+ ((TQWorkspace*)d->maxWindow->windowWidget())->setWState( TQt::WState_Maximized );
+ }
+
+ TQRect cr = updateWorkspace();
+
+ TQPtrListIterator<TQWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ TQWorkspaceChild* c = it.current();
+ ++it;
+ if ( c->windowWidget() && !c->windowWidget()->testWFlags( TQt::WStyle_Tool ) )
+ continue;
+
+ int x = c->x();
+ int y = c->y();
+ if ( c->snappedDown )
+ y = cr.height() - c->height();
+ if ( c->snappedRight )
+ x = cr.width() - c->width();
+
+ if ( x != c->x() || y != c->y() )
+ c->move( x, y );
+ }
+
+}
+
+void TQWorkspace::handleUndock(TQDockWindow *w)
+{
+ const TQDesktopWidget *dw = tqApp->desktop();
+ TQRect maxRect = dw->availableGeometry(dw->screenNumber(d->mainwindow));
+ TQPoint wpos(maxRect.left(), maxRect.top());
+ int possible = 0;
+ if(!::tqqt_cast<TQToolBar*>(w)) {
+ struct place_score { int o, x, y; } score = {0, 0, 0};
+ int left = 1, x = wpos.x(), y = wpos.y();
+ TQPtrListIterator<TQDockWindow> it( d->dockwindows );
+ while(1) {
+ if(y + w->height() > maxRect.bottom()) {
+ if(left) {
+ x = maxRect.right() - w->width();
+ y = maxRect.top();
+ left = 0;
+ } else {
+ break;
+ }
+ }
+
+ TQDockWindow *l, *nearest = NULL, *furthest;
+ for ( it.toFirst(); it.current(); ++it ) {
+ l = it.current();
+ if ( l != w && y == l->y() ) {
+ if(!nearest) {
+ nearest = l;
+ } else if(l->x() == x) {
+ nearest = l;
+ break;
+ } else if(left && (l->x() - x) < (nearest->x() - x)) {
+ nearest = l;
+ } else if(!left && (x - l->x()) < (x - nearest->x())) {
+ nearest = l;
+ }
+ }
+ }
+ TQRect r2(x, y, w->width(), w->height());
+ if(!nearest || !nearest->tqgeometry().intersects(r2)) {
+ wpos = TQPoint(x, y); //best possible outcome
+ possible = 2;
+ break;
+ }
+
+ TQDockWindow *o = NULL;
+ int overlap = 0;
+ for( it.toFirst(); it.current(); ++it ) {
+ l = it.current();
+ if ( l != w && l->tqgeometry().intersects(TQRect(TQPoint(x, y), w->size()))) {
+ overlap++;
+ o = l;
+ }
+ }
+ if(o && overlap == 1 && w->isVisible() && !o->isVisible()) {
+ wpos = TQPoint(x, y);
+ possible = 2;
+ while(d->dockwindows.remove(o));
+ d->newdocks.append(o);
+ if(d->newdocks.count() == 1)
+ TQTimer::singleShot(0, this, TQT_SLOT(dockWindowsShow()));
+ break;
+ }
+
+ for ( furthest = nearest, it.toFirst(); it.current(); ++it ) {
+ l = it.current();
+ if ( l != w && l->y() == nearest->y() &&
+ ((left && (l->x() == nearest->x() + nearest->width())) ||
+ (!left && (l->x() + l->width() == nearest->x()) )))
+ furthest = l;
+ }
+ if(left)
+ x = furthest->x() + furthest->width();
+ else
+ x = furthest->x() - w->width();
+
+ TQPoint sc_pt(x, y);
+ place_score sc;
+ if(left)
+ sc.x = (x + w->width()) * 2;
+ else
+ sc.x = ((maxRect.width() - x) * 2) + 1;
+ sc.y = sc_pt.y();
+ for( sc.o = 0, it.toFirst(); it.current(); ++it ) {
+ l = it.current();
+ if ( l != w && l->tqgeometry().intersects(TQRect(sc_pt, w->size())))
+ sc.o++;
+ }
+ if(maxRect.tqcontains(TQRect(sc_pt, w->size())) &&
+ (!possible || (sc.o < score.o) ||
+ ((score.o || sc.o == score.o) && score.x < sc.x))) {
+ wpos = sc_pt;
+ score = sc;
+ possible = 1;
+ }
+ y += nearest->height();
+ if(left)
+ x = maxRect.x();
+ else
+ x = maxRect.right() - w->width();
+ }
+ if(!possible || (possible == 1 && score.o)) { //fallback to less knowledgeable function
+ place(w);
+ wpos = w->pos();
+ }
+ }
+
+ bool ishidden = w->isHidden();
+ TQSize olds(w->size());
+ if(w->place() == TQDockWindow::InDock)
+ w->undock();
+ w->move(wpos);
+ w->resize(olds);
+ if(!ishidden)
+ w->show();
+ else
+ w->hide();
+}
+
+void TQWorkspace::dockWindowsShow()
+{
+ TQPtrList<TQDockWindow> lst = d->newdocks;
+ d->newdocks.clear();
+ for(TQPtrListIterator<TQDockWindow> dw_it(lst); (*dw_it); ++dw_it) {
+ if(d->dockwindows.tqfind((*dw_it)) != -1)
+ continue;
+ handleUndock((*dw_it));
+ d->dockwindows.append((*dw_it));
+ }
+}
+
+/*! \reimp */
+void TQWorkspace::showEvent( TQShowEvent *e )
+{
+ /* This is all magic, be carefull when playing with this code - this tries to allow people to
+ use TQWorkspace as a high level abstraction for window management, but removes enforcement that
+ TQWorkspace be used as an MDI. */
+ if(d->wmode == AutoDetect) {
+ d->wmode = MDI;
+ TQWidget *o = tqtopLevelWidget();
+ if(::tqqt_cast<TQMainWindow*>(o)) {
+ d->wmode = TopLevel;
+ for(TQObjectListIt it(o->childrenListObject()); it; ++it) {
+ if((*it)->isWidgetType() && !((TQWidget *)(*it))->isTopLevel() &&
+ !::tqqt_cast<TQHBox*>(*it) && !::tqqt_cast<TQVBox*>(*it) &&
+ !::tqqt_cast<TQWorkspaceChild*>(*it) && !(*it)->inherits("TQHideDock") &&
+ !::tqqt_cast<TQDockArea*>(*it) && !::tqqt_cast<TQWorkspace*>(*it) &&
+ !::tqqt_cast<TQMenuBar*>(*it) && !::tqqt_cast<TQStatusBar*>(*it)) {
+ d->wmode = MDI;
+ break;
+ }
+ }
+ }
+ }
+ if(d->wmode == TopLevel) {
+ TQWidget *o = tqtopLevelWidget();
+ d->mainwindow = ::tqqt_cast<TQMainWindow*>(o);
+ const TQObjectList tqchildren = o->childrenListObject();
+ for(TQObjectListIt it(tqchildren); it; ++it) {
+ if(!(*it)->isWidgetType())
+ continue;
+ TQWidget *w = (TQWidget *)(*it);
+ if(w->isTopLevel())
+ continue;
+ if(::tqqt_cast<TQDockArea*>(w)) {
+ if(!w->childrenListObject().isEmpty()) {
+ TQPtrList<TQToolBar> tb_list;
+ for(TQObjectListIt dock_it(w->childrenListObject()); dock_it; ++dock_it) {
+ if(!(*dock_it)->isWidgetType())
+ continue;
+ if(::tqqt_cast<TQToolBar*>(*dock_it)) {
+ tb_list.append((TQToolBar *)(*dock_it));
+ } else if (::tqqt_cast<TQDockWindow*>(*dock_it)) {
+ TQDockWindow *dw = (TQDockWindow*)(*dock_it);
+ dw->move(dw->mapToGlobal(TQPoint(0, 0)));
+ d->newdocks.append(dw);
+ } else {
+ qDebug("not sure what to do with %s %s", (*dock_it)->className(),
+ (*dock_it)->name());
+ }
+ }
+ if(tb_list.count() == 1) {
+ TQToolBar *tb = tb_list.first();
+ tb->move(0, 0);
+ d->newdocks.prepend(tb);
+ } else if(tb_list.count()) {
+ TQDockWindow *dw = new TQDockWindow(TQDockWindow::OutsideDock,
+ w->parentWidget(),
+ (TQString("TQMagicDock_") + w->name()).ascii());
+ dw->installEventFilter(this);
+ dw->setResizeEnabled(TRUE);
+ dw->setCloseMode( TQDockWindow::Always );
+ dw->setResizeEnabled(FALSE);
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ dw->setCaption(o->caption());
+#endif
+ TQSize os(w->size());
+ if(w->tqlayout() && w->tqlayout()->hasHeightForWidth()) {
+ w->tqlayout()->tqinvalidate();
+ os.setHeight(w->tqlayout()->heightForWidth(os.width()));
+ }
+ if(!w->isHidden())
+ dw->show();
+ w->reparent(dw, TQPoint(0, 0));
+ dw->setWidget(w);
+ dw->tqsetSizePolicy(TQSizePolicy(TQSizePolicy::Minimum, TQSizePolicy::Minimum));
+ dw->setGeometry(0, 0, os.width(), os.height() + dw->sizeHint().height());
+ d->newdocks.prepend(dw);
+ ((TQDockArea*)w)->setAcceptDockWindow(dw, FALSE);
+ w->show();
+ }
+ }
+ w->installEventFilter(this);
+ } else if(::tqqt_cast<TQStatusBar*>(w)) {
+ if(activeWindow()) {
+ TQWorkspaceChild *c;
+ if ( ( c = tqfindChild(activeWindow()) ) )
+ c->setqStatusBar((TQStatusBar*)w);
+ }
+ } else if(::tqqt_cast<TQWorkspaceChild*>(w)) {
+ w->reparent(this, w->testWFlags((WFlags)((WFlags)(~(0))) | (WFlags)TQt::WType_TopLevel), w->pos());
+ }
+ }
+ dockWindowsShow(); //now place and undock windows discovered
+
+ TQWidget *w = new TQWidget(NULL, "TQDoesNotExist",
+ (WFlags)(TQt::WType_Dialog | WStyle_Customize | TQt::WStyle_NoBorder));
+// if(tqApp->mainWidget() == o)
+// TQObject::connect(tqApp, TQT_SIGNAL(lastWindowClosed()), tqApp, TQT_SLOT(quit()));
+ TQDesktopWidget *dw = TQApplication::desktop();
+ w->setGeometry(dw->availableGeometry(dw->screenNumber(o)));
+ o->reparent(w, TQPoint(0, 0), TRUE);
+ {
+ TQMenuBar *mb = 0;
+ if(::tqqt_cast<TQMainWindow*>(o))
+ mb = ((TQMainWindow *)o)->menuBar();
+ if(!mb)
+ mb = (TQMenuBar*)o->child(NULL, "TQMenuBar");
+ if(mb)
+ mb->reparent(w, TQPoint(0, 0));
+ }
+ reparent(w, TQPoint(0,0));
+ setGeometry(0, 0, w->width(), w->height());
+#if 0
+ /* Hide really isn't acceptable because I need to make the rest of TQt
+ think it is visible, so instead I set it to an empty tqmask. I'm not
+ sure what problems this is going to create, hopefully everything will
+ be happy (or not even notice since this is mostly intended for TQt/Mac) */
+// w->setMask(TQRegion());
+// w->show();
+#else
+ w->hide();
+#endif
+ }
+
+ //done with that nastiness, on with your regularly scheduled programming..
+ if ( d->maxWindow && !tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this))
+ showMaximizeControls();
+ TQWidget::showEvent( e );
+ if ( d->becomeActive ) {
+ activateWindow( d->becomeActive );
+ d->becomeActive = 0;
+ } else if ( d->windows.count() > 0 && !d->active ) {
+ activateWindow( d->windows.first()->windowWidget() );
+ }
+
+ // force a frame tqrepaint - this is a workaround for what seems to be a bug
+ // introduced when changing the TQWidget::show() implementation. Might be
+ // a windows bug as well though.
+ for (TQPtrListIterator<TQWorkspaceChild> it( d->windows ); it.current(); ++it ) {
+ TQWorkspaceChild* c = it.current();
+ TQApplication::postEvent(c, new TQPaintEvent(c->rect(), TRUE));
+ }
+
+ updateWorkspace();
+}
+
+/*! \reimp */
+void TQWorkspace::hideEvent( TQHideEvent * )
+{
+ if ( !isVisibleTo(0) && !tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this))
+ hideMaximizeControls();
+}
+
+void TQWorkspace::minimizeWindow( TQWidget* w)
+{
+ TQWorkspaceChild* c = tqfindChild( w );
+
+ if ( !w || (w && (!w->testWFlags( TQt::WStyle_Minimize ) || w->testWFlags( TQt::WStyle_Tool) )) )
+ return;
+
+ if ( c ) {
+ TQWorkspace *fake = (TQWorkspace*)w;
+
+ setUpdatesEnabled( FALSE );
+ bool wasMax = FALSE;
+ if ( c == d->maxWindow ) {
+ wasMax = TRUE;
+ d->maxWindow = 0;
+ inCaptionChange = TRUE;
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( !!d->topCaption )
+ tqtopLevelWidget()->setCaption( d->topCaption );
+#endif
+ inCaptionChange = FALSE;
+ if ( !tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this) )
+ hideMaximizeControls();
+ for (TQPtrListIterator<TQWorkspaceChild> it( d->windows ); it.current(); ++it ) {
+ TQWorkspaceChild* c = it.current();
+ if ( c->titlebar )
+ c->titlebar->setMovable( TRUE );
+ c->widgetResizeHandler->setActive( TRUE );
+ }
+ }
+
+ insertIcon( c->iconWidget() );
+ c->hide();
+ if ( wasMax )
+ c->setGeometry( d->maxRestore );
+ d->focus.append( c );
+
+ activateWindow(w);
+
+ setUpdatesEnabled( TRUE );
+ updateWorkspace();
+
+ fake->clearWState( TQt::WState_Maximized );
+ fake->setWState( TQt::WState_Minimized );
+ c->clearWState( TQt::WState_Maximized );
+ c->setWState( TQt::WState_Minimized );
+ }
+}
+
+void TQWorkspace::normalizeWindow( TQWidget* w)
+{
+ TQWorkspaceChild* c = tqfindChild( w );
+ if ( !w )
+ return;
+ if ( c ) {
+ TQWorkspace *fake = (TQWorkspace*)w;
+ fake->clearWState( TQt::WState_Minimized | TQt::WState_Maximized );
+ if ( !tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this) && d->maxWindow ) {
+ hideMaximizeControls();
+ } else {
+ if ( w->tqminimumSize() != w->tqmaximumSize() )
+ c->widgetResizeHandler->setActive( TRUE );
+ if ( c->titlebar )
+ c->titlebar->setMovable(TRUE);
+ }
+ fake->clearWState( TQt::WState_Minimized | TQt::WState_Maximized );
+ c->clearWState( TQt::WState_Minimized | TQt::WState_Maximized );
+
+ if ( c == d->maxWindow ) {
+ c->setGeometry( d->maxRestore );
+ d->maxWindow = 0;
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ inCaptionChange = TRUE;
+ if ( !!d->topCaption )
+ tqtopLevelWidget()->setCaption( d->topCaption );
+ inCaptionChange = FALSE;
+#endif
+ } else {
+ if ( c->iconw )
+ removeIcon( c->iconw->parentWidget() );
+ c->show();
+ }
+
+ if ( !tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this))
+ hideMaximizeControls();
+ for (TQPtrListIterator<TQWorkspaceChild> it( d->windows ); it.current(); ++it ) {
+ TQWorkspaceChild* c = it.current();
+ if ( c->titlebar )
+ c->titlebar->setMovable( TRUE );
+ if ( c->childWidget && c->childWidget->tqminimumSize() != c->childWidget->tqmaximumSize() )
+ c->widgetResizeHandler->setActive( TRUE );
+ }
+ activateWindow( w, TRUE );
+ updateWorkspace();
+ }
+}
+
+void TQWorkspace::maximizeWindow( TQWidget* w)
+{
+ TQWorkspaceChild* c = tqfindChild( w );
+
+ if ( !w || (w && (!w->testWFlags( TQt::WStyle_Maximize ) || w->testWFlags( TQt::WStyle_Tool) )) )
+ return;
+
+ if ( c ) {
+ setUpdatesEnabled( FALSE );
+ if (c->iconw && d->icons.tqcontains( c->iconw->parentWidget() ) )
+ normalizeWindow( w );
+ TQWorkspace *fake = (TQWorkspace*)w;
+
+ TQRect r( c->tqgeometry() );
+ c->adjustToFullscreen();
+ c->show();
+ c->internalRaise();
+ tqApp->sendPostedEvents( c, TQEvent::Resize );
+ tqApp->sendPostedEvents( c, TQEvent::Move );
+ tqApp->sendPostedEvents( c, TQEvent::ShowWindowRequest );
+ if ( d->maxWindow != c ) {
+ if ( d->maxWindow )
+ d->maxWindow->setGeometry( d->maxRestore );
+ d->maxWindow = c;
+ d->maxRestore = r;
+ }
+
+ activateWindow( w );
+ if(!tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this)) {
+ showMaximizeControls();
+ } else {
+ c->widgetResizeHandler->setActive( FALSE );
+ if ( c->titlebar )
+ c->titlebar->setMovable( FALSE );
+ }
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ inCaptionChange = TRUE;
+ if ( !!d->topCaption )
+ tqtopLevelWidget()->setCaption( tqtr("%1 - [%2]")
+ .arg(d->topCaption).arg(c->caption()) );
+ inCaptionChange = FALSE;
+#endif
+ setUpdatesEnabled( TRUE );
+
+ updateWorkspace();
+
+ fake->clearWState( TQt::WState_Minimized );
+ fake->setWState( TQt::WState_Maximized );
+ c->clearWState( TQt::WState_Minimized );
+ c->setWState( TQt::WState_Maximized );
+ }
+}
+
+void TQWorkspace::showWindow( TQWidget* w)
+{
+ if ( d->maxWindow && w->testWFlags( TQt::WStyle_Maximize ) && !w->testWFlags( TQt::WStyle_Tool) )
+ maximizeWindow(w);
+ else if (w->isMinimized() && !w->testWFlags(TQt::WStyle_Tool))
+ minimizeWindow(w);
+ else if ( !w->testWFlags( TQt::WStyle_Tool ) )
+ normalizeWindow(w);
+ else
+ w->parentWidget()->show();
+ if ( d->maxWindow )
+ d->maxWindow->internalRaise();
+ updateWorkspace();
+}
+
+
+TQWorkspaceChild* TQWorkspace::tqfindChild( TQWidget* w)
+{
+ TQPtrListIterator<TQWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ TQWorkspaceChild* c = it.current();
+ ++it;
+ if (c->windowWidget() == w)
+ return c;
+ }
+ return 0;
+}
+
+/*!
+ \obsolete
+ \overload
+ */
+TQWidgetList TQWorkspace::windowList() const
+{
+ return windowList( CreationOrder );
+}
+
+/*!
+ Returns a list of all windows. If \a order is CreationOrder
+ (the default) the windows are listed in the order in which they
+ had been inserted into the workspace. If \a order is StackingOrder
+ the windows are listed in their stacking order, with the topmost window
+ being the last window in the list.
+
+ TQWidgetList is the same as TQPtrList<TQWidget>.
+
+ \sa TQPtrList
+*/
+TQWidgetList TQWorkspace::windowList( WindowOrder order ) const
+{
+ TQWidgetList windows;
+ if ( order == StackingOrder ) {
+ if ( !childrenListObject().isEmpty() ) {
+ TQObjectListIt it( childrenListObject() );
+ while (it.current()) {
+ TQObject *o = it.current();
+ ++it;
+ TQWorkspaceChild *c = ::tqqt_cast<TQWorkspaceChild*>(o);
+ if (c && c->windowWidget())
+ windows.append(c->windowWidget());
+ }
+ }
+ } else {
+ TQPtrListIterator<TQWorkspaceChild> it( d->windows );
+ while (it.current()) {
+ TQWorkspaceChild* c = it.current();
+ ++it;
+ if ( c->windowWidget() )
+ windows.append( c->windowWidget() );
+ }
+ }
+ return windows;
+}
+
+/*!\reimp*/
+bool TQWorkspace::eventFilter( TQObject *o, TQEvent * e)
+{
+ if(d->wmode == TopLevel && d->mainwindow && TQT_BASE_OBJECT(TQT_TQOBJECT(o)->tqparent()) == TQT_BASE_OBJECT(d->mainwindow)) {
+ if((e->type() == TQEvent::ChildInserted || e->type() == TQEvent::Reparent) &&
+ ::tqqt_cast<TQDockArea*>(o) && !((TQWidget*)o)->isVisible()) {
+ TQChildEvent *ce = (TQChildEvent*)e;
+ if(!::tqqt_cast<TQDockWindow*>(ce->child())) {
+ qDebug("No idea what to do..");
+ return FALSE;
+ }
+ TQDockWindow *w = (TQDockWindow*)ce->child();
+ if(d->newdocks.tqfind(w) == -1 && d->dockwindows.tqfind(w) == -1) {
+ if(::tqqt_cast<TQToolBar*>(w))
+ d->newdocks.prepend(w);
+ else
+ d->newdocks.append(w);
+ if(d->newdocks.count() == 1)
+ TQTimer::singleShot(0, this, TQT_SLOT(dockWindowsShow()));
+ }
+ } else if(e->type() == TQEvent::Hide && !e->spontaneous() && !tqstrncmp(o->name(), "TQMagicDock_", 11)) {
+// d->mainwindow->close();
+ }
+ return TQWidget::eventFilter(o, e);
+ }
+
+ static TQTime* t = 0;
+ static TQWorkspace* tc = 0;
+#ifndef TQT_NO_MENUBAR
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(d->maxtools) && d->menuId != -1 ) {
+ switch ( e->type() ) {
+ case TQEvent::MouseButtonPress:
+ {
+ TQMenuBar* b = (TQMenuBar*)o->tqparent();
+ if ( !t )
+ t = new TQTime;
+ if ( tc != this || t->elapsed() > TQApplication::doubleClickInterval() ) {
+ if ( TQApplication::reverseLayout() ) {
+ TQPoint p = b->mapToGlobal( TQPoint( b->x() + b->width(), b->y() + b->height() ) );
+ p.rx() -= d->popup->sizeHint().width();
+ popupOperationMenu( p );
+ } else {
+ popupOperationMenu( b->mapToGlobal( TQPoint( b->x(), b->y() + b->height() ) ) );
+ }
+ t->start();
+ tc = this;
+ } else {
+ tc = 0;
+ closeActiveWindow();
+ }
+ return TRUE;
+ }
+ default:
+ break;
+ }
+ return TQWidget::eventFilter( o, e );
+ }
+#endif
+ switch ( e->type() ) {
+ case TQEvent::Hide:
+ case TQEvent::HideToParent:
+ if ( !o->isA( "TQWorkspaceChild" ) || !isVisible() || e->spontaneous() )
+ break;
+ if ( TQT_BASE_OBJECT(d->active) == TQT_BASE_OBJECT(o) ) {
+ int a = d->focus.tqfind( d->active );
+ if (a < 0) {
+ printf("[WARNING] In TQWorkspace TQEvent::HideToParent handler: Expected active window to be present in focus list but this was not the case! Avoiding infinite loop but the root cause of this problem should be repaired. d->focus.count(): %d\n\r", d->focus.count());
+ break;
+ }
+ for ( ;; ) {
+ if ( --a < 0 )
+ a = d->focus.count()-1;
+ TQWorkspaceChild* c = d->focus.at( a );
+ if ( !c || TQT_BASE_OBJECT(c) == TQT_BASE_OBJECT(o) ) {
+ if ( c && c->iconw && d->icons.tqcontains( c->iconw->parentWidget() ) )
+ break;
+ activateWindow( 0 );
+ break;
+ }
+ if ( c->isShown() ) {
+ activateWindow( c->windowWidget(), FALSE );
+ break;
+ }
+ }
+ }
+ d->focus.removeRef( (TQWorkspaceChild*)o );
+ if ( TQT_BASE_OBJECT(d->maxWindow) == TQT_BASE_OBJECT(o) && d->maxWindow->isHidden() ) {
+ d->maxWindow->setGeometry( d->maxRestore );
+ d->maxWindow = 0;
+ if ( d->active )
+ maximizeWindow( d->active );
+
+ if ( !d->maxWindow ) {
+
+ if ( tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this)) {
+ TQWorkspaceChild *wc = (TQWorkspaceChild *)o;
+ wc->widgetResizeHandler->setActive( TRUE );
+ if ( wc->titlebar )
+ wc->titlebar->setMovable( TRUE );
+ } else {
+ hideMaximizeControls();
+ }
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ inCaptionChange = TRUE;
+ if ( !!d->topCaption )
+ tqtopLevelWidget()->setCaption( d->topCaption );
+ inCaptionChange = FALSE;
+#endif
+ }
+ }
+ updateWorkspace();
+ break;
+ case TQEvent::Show:
+ if ( o->isA("TQWorkspaceChild") && !d->focus.tqcontainsRef( (TQWorkspaceChild*)o ) ) {
+ d->focus.append( (TQWorkspaceChild*)o );
+ }
+ updateWorkspace();
+ break;
+ case TQEvent::CaptionChange:
+ if ( inCaptionChange )
+ break;
+
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ inCaptionChange = TRUE;
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(tqtopLevelWidget()) ) {
+ TQWidget *tlw = (TQWidget*)o;
+ if ( !d->maxWindow
+ || tlw->caption() != tqtr("%1 - [%2]").arg(d->topCaption).arg(d->maxWindow->caption()) )
+ d->topCaption = tlw->caption();
+ }
+
+ if ( d->maxWindow && !!d->topCaption )
+ tqtopLevelWidget()->setCaption( tqtr("%1 - [%2]")
+ .arg(d->topCaption).arg(d->maxWindow->caption()));
+ inCaptionChange = FALSE;
+#endif
+
+ break;
+ case TQEvent::Close:
+ if ( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(tqtopLevelWidget()) )
+ {
+ TQPtrListIterator<TQWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ TQWorkspaceChild* c = it.current();
+ ++it;
+ if ( c->shademode )
+ c->showShaded();
+ }
+ } else if ( ::tqqt_cast<TQWorkspaceChild*>(o) ) {
+ d->popup->hide();
+ }
+ updateWorkspace();
+ break;
+ default:
+ break;
+ }
+ return TQWidget::eventFilter( o, e);
+}
+
+void TQWorkspace::showMaximizeControls()
+{
+#ifndef TQT_NO_MENUBAR
+ TQ_ASSERT(d->maxWindow);
+ TQMenuBar* b = 0;
+
+ // Do a breadth-first search first on every tqparent,
+ TQWidget* w = parentWidget();
+ TQObjectList * l = 0;
+ while ( !l && w ) {
+ l = w->queryList( "TQMenuBar", 0, FALSE, FALSE );
+ w = w->parentWidget();
+ if ( l && !l->count() ) {
+ delete l;
+ l = 0;
+ }
+ }
+
+ // and query recursively if nothing is found.
+ if ( !l || !l->count() ) {
+ if ( l )
+ delete l;
+ l = tqtopLevelWidget()->queryList( "TQMenuBar", 0, 0, TRUE );
+ }
+ if ( l && l->count() )
+ b = (TQMenuBar *)l->first();
+ delete l;
+
+ if ( !b )
+ return;
+
+ if ( !d->maxcontrols ) {
+ d->maxmenubar = b;
+ d->maxcontrols = new TQFrame( tqtopLevelWidget(), "qt_maxcontrols" );
+ TQHBoxLayout* l = new TQHBoxLayout( d->maxcontrols,
+ d->maxcontrols->frameWidth(), 0 );
+ if ( d->maxWindow->windowWidget() &&
+ d->maxWindow->windowWidget()->testWFlags(TQt::WStyle_Minimize) ) {
+ TQToolButton* iconB = new TQToolButton( d->maxcontrols, "iconify" );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::add( iconB, tqtr( "Minimize" ) );
+#endif
+ l->addWidget( iconB );
+ iconB->setFocusPolicy( Qt::NoFocus );
+ iconB->setIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarMinButton));
+ iconB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
+ connect( iconB, TQT_SIGNAL( clicked() ),
+ this, TQT_SLOT( minimizeActiveWindow() ) );
+ }
+
+ TQToolButton* restoreB = new TQToolButton( d->maxcontrols, "restore" );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::add( restoreB, tqtr( "Restore Down" ) );
+#endif
+ l->addWidget( restoreB );
+ restoreB->setFocusPolicy( Qt::NoFocus );
+ restoreB->setIconSet( tqstyle().stylePixmap(TQStyle::SP_TitleBarNormalButton));
+ restoreB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
+ connect( restoreB, TQT_SIGNAL( clicked() ),
+ this, TQT_SLOT( normalizeActiveWindow() ) );
+
+ l->addSpacing( 2 );
+ TQToolButton* closeB = new TQToolButton( d->maxcontrols, "close" );
+#ifndef TQT_NO_TOOLTIP
+ TQToolTip::add( closeB, tqtr( "Close" ) );
+#endif
+ l->addWidget( closeB );
+ closeB->setFocusPolicy( Qt::NoFocus );
+ closeB->setIconSet( tqstyle().stylePixmap(TQStyle::SP_TitleBarCloseButton) );
+ closeB->setFixedSize(BUTTON_WIDTH, BUTTON_HEIGHT);
+ connect( closeB, TQT_SIGNAL( clicked() ),
+ this, TQT_SLOT( closeActiveWindow() ) );
+
+ d->maxcontrols->setFixedSize( d->maxcontrols->minimumSizeHint() );
+ }
+
+ if ( d->controlId == -1 || b->indexOf( d->controlId ) == -1 ) {
+ TQFrame* dmaxcontrols = d->maxcontrols;
+ d->controlId = b->insertItem( dmaxcontrols, -1, b->count() );
+ }
+ if ( !d->active && d->becomeActive ) {
+ d->active = (TQWorkspaceChild*)d->becomeActive->parentWidget();
+ d->active->setActive( TRUE );
+ d->becomeActive = 0;
+ emit windowActivated( d->active->windowWidget() );
+ }
+ if ( d->active && ( d->menuId == -1 || b->indexOf( d->menuId ) == -1 ) ) {
+ if ( !d->maxtools ) {
+ d->maxtools = new TQLabel( tqtopLevelWidget(), "qt_maxtools" );
+ d->maxtools->installEventFilter( this );
+ }
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( d->active->windowWidget() && d->active->windowWidget()->icon() ) {
+// TQPixmap pm(*d->active->windowWidget()->icon());
+ TQPixmap pm(d->active->windowWidget()->windowIcon().pixmap(14,14)); // [FIXME] Is there any way around hardcoding this value???
+ int iconSize = d->maxcontrols->size().height();
+ if(pm.width() > iconSize || pm.height() > iconSize) {
+ TQImage im;
+ im = pm;
+ pm = im.smoothScale( TQMIN(iconSize, pm.width()), TQMIN(iconSize, pm.height()) );
+ }
+ d->maxtools->setPixmap( pm );
+ } else
+#endif
+ {
+ TQPixmap pm(14,14);
+ pm.fill( Qt::color1 );
+ pm.setMask(pm.createHeuristicMask());
+ d->maxtools->setPixmap( pm );
+ }
+ d->menuId = b->insertItem( d->maxtools, -1, 0 );
+ }
+#endif
+}
+
+
+void TQWorkspace::hideMaximizeControls()
+{
+#ifndef TQT_NO_MENUBAR
+ if ( d->maxmenubar ) {
+ int mi = d->menuId;
+ if ( mi != -1 ) {
+ if ( d->maxmenubar->indexOf( mi ) != -1 )
+ d->maxmenubar->removeItem( mi );
+ d->maxtools = 0;
+ }
+ int ci = d->controlId;
+ if ( ci != -1 && d->maxmenubar->indexOf( ci ) != -1 )
+ d->maxmenubar->removeItem( ci );
+ }
+ d->maxcontrols = 0;
+ d->menuId = -1;
+ d->controlId = -1;
+#endif
+}
+
+/*!
+ Closes the child window that is currently active.
+
+ \sa closeAllWindows()
+*/
+void TQWorkspace::closeActiveWindow()
+{
+ setUpdatesEnabled( FALSE );
+ if ( d->maxWindow && d->maxWindow->windowWidget() )
+ d->maxWindow->windowWidget()->close();
+ else if ( d->active && d->active->windowWidget() )
+ d->active->windowWidget()->close();
+ setUpdatesEnabled( TRUE );
+ updateWorkspace();
+}
+
+/*!
+ Closes all child windows.
+
+ The windows are closed in random order. The operation stops if a
+ window does not accept the close event.
+
+ \sa closeActiveWindow()
+*/
+void TQWorkspace::closeAllWindows()
+{
+ bool did_close = TRUE;
+ TQPtrListIterator<TQWorkspaceChild> it( d->windows );
+ TQWorkspaceChild *c = 0;
+ while ( ( c = it.current() ) && did_close ) {
+ ++it;
+ if ( c->windowWidget() )
+ did_close = c->windowWidget()->close();
+ }
+}
+
+void TQWorkspace::normalizeActiveWindow()
+{
+ if ( d->maxWindow )
+ d->maxWindow->showNormal();
+ else if ( d->active )
+ d->active->showNormal();
+}
+
+void TQWorkspace::minimizeActiveWindow()
+{
+ if ( d->maxWindow )
+ d->maxWindow->showMinimized();
+ else if ( d->active )
+ d->active->showMinimized();
+}
+
+void TQWorkspace::showOperationMenu()
+{
+ if ( !d->active || !d->active->windowWidget() )
+ return;
+ TQ_ASSERT( d->active->windowWidget()->testWFlags( TQt::WStyle_SysMenu ) );
+ TQPoint p;
+ TQPopupMenu *popup = d->active->windowWidget()->testWFlags( TQt::WStyle_Tool ) ? d->toolPopup : d->popup;
+ if ( TQApplication::reverseLayout() ) {
+ p = TQPoint( d->active->windowWidget()->mapToGlobal( TQPoint(d->active->windowWidget()->width(),0) ) );
+ p.rx() -= popup->sizeHint().width();
+ } else {
+ p = TQPoint( d->active->windowWidget()->mapToGlobal( TQPoint(0,0) ) );
+ }
+ if ( !d->active->isVisible() ) {
+ p = d->active->iconWidget()->mapToGlobal( TQPoint(0,0) );
+ p.ry() -= popup->sizeHint().height();
+ }
+ popupOperationMenu( p );
+}
+
+void TQWorkspace::popupOperationMenu( const TQPoint& p)
+{
+ if ( !d->active || !d->active->windowWidget() || !d->active->windowWidget()->testWFlags( TQt::WStyle_SysMenu ) )
+ return;
+ if ( d->active->windowWidget()->testWFlags( TQt::WStyle_Tool ))
+ d->toolPopup->popup( p );
+ else
+ d->popup->popup( p );
+}
+
+void TQWorkspace::operationMenuAboutToShow()
+{
+ for ( int i = 1; i < 6; i++ ) {
+ bool enable = d->active != 0;
+ d->popup->setItemEnabled( i, enable );
+ }
+
+ if ( !d->active || !d->active->windowWidget() )
+ return;
+
+ TQWidget *windowWidget = d->active->windowWidget();
+ bool canResize = windowWidget->tqmaximumSize() != windowWidget->tqminimumSize();
+ d->popup->setItemEnabled( 3, canResize );
+ d->popup->setItemEnabled( 4, windowWidget->testWFlags( TQt::WStyle_Minimize ) );
+ d->popup->setItemEnabled( 5, windowWidget->testWFlags( TQt::WStyle_Maximize ) && canResize );
+
+ if ( d->active == d->maxWindow ) {
+ d->popup->setItemEnabled( 2, FALSE );
+ d->popup->setItemEnabled( 3, FALSE );
+ d->popup->setItemEnabled( 5, FALSE );
+ } else if ( d->active->isVisible() ){
+ d->popup->setItemEnabled( 1, FALSE );
+ } else {
+ d->popup->setItemEnabled( 2, FALSE );
+ d->popup->setItemEnabled( 3, FALSE );
+ d->popup->setItemEnabled( 4, FALSE );
+ }
+}
+
+void TQWorkspace::toolMenuAboutToShow()
+{
+ if ( !d->active || !d->active->windowWidget() )
+ return;
+
+ TQWidget *windowWidget = d->active->windowWidget();
+ bool canResize = windowWidget->tqmaximumSize() != windowWidget->tqminimumSize();
+
+ d->toolPopup->setItemEnabled( 3, !d->active->shademode && canResize );
+ if ( d->active->shademode )
+ d->toolPopup->changeItem( 6,
+ TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarUnshadeButton)), tqtr("&Unshade") );
+ else
+ d->toolPopup->changeItem( 6, TQIconSet(tqstyle().stylePixmap(TQStyle::SP_TitleBarShadeButton)), tqtr("Sh&ade") );
+ d->toolPopup->setItemEnabled( 6, d->active->windowWidget()->testWFlags( TQt::WStyle_MinMax ) );
+ d->toolPopup->setItemChecked( 7, d->active->windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) );
+}
+
+void TQWorkspace::operationMenuActivated( int a )
+{
+ if ( !d->active )
+ return;
+ switch ( a ) {
+ case 1:
+ d->active->showNormal();
+ break;
+ case 2:
+ d->active->doMove();
+ break;
+ case 3:
+ if ( d->active->shademode )
+ d->active->showShaded();
+ d->active->doResize();
+ break;
+ case 4:
+ d->active->showMinimized();
+ break;
+ case 5:
+ d->active->showMaximized();
+ break;
+ case 6:
+ d->active->showShaded();
+ break;
+ case 7:
+ {
+ TQWorkspace* w = (TQWorkspace*)d->active->windowWidget();
+ if ( !w )
+ break;
+ if ( w->testWFlags( TQt::WStyle_StaysOnTop ) ) {
+ w->clearWFlags( TQt::WStyle_StaysOnTop );
+ } else {
+ w->setWFlags( TQt::WStyle_StaysOnTop );
+ w->parentWidget()->raise();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ Activates the next window in the child window chain.
+
+ \sa activatePrevWindow()
+*/
+void TQWorkspace::activateNextWindow()
+{
+ if ( d->focus.isEmpty() )
+ return;
+ if ( !d->active ) {
+ if ( d->focus.first() ) {
+ activateWindow( d->focus.first()->windowWidget(), FALSE );
+ }
+ return;
+ }
+
+ int a = d->focus.tqfind( d->active ) + 1;
+
+ a = a % d->focus.count();
+
+ if ( d->focus.at( a ) )
+ activateWindow( d->focus.at( a )->windowWidget(), FALSE );
+ else
+ activateWindow(0);
+}
+
+void TQWorkspace::activatePreviousWindow()
+{
+ activatePrevWindow();
+}
+
+/*!
+ Activates the previous window in the child window chain.
+
+ \sa activateNextWindow()
+*/
+void TQWorkspace::activatePrevWindow()
+{
+ if ( d->focus.isEmpty() )
+ return;
+ if ( !d->active ) {
+ if ( d->focus.last() )
+ activateWindow( d->focus.first()->windowWidget(), FALSE );
+ else
+ activateWindow( 0 );
+
+ return;
+ }
+
+ int a = d->focus.tqfind( d->active ) - 1;
+ if ( a < 0 )
+ a = d->focus.count()-1;
+
+ if ( d->focus.at( a ) )
+ activateWindow( d->focus.at( a )->windowWidget(), FALSE );
+ else
+ activateWindow( 0 );
+}
+
+
+/*!
+ \fn void TQWorkspace::windowActivated( TQWidget* w )
+
+ This signal is emitted when the window widget \a w becomes active.
+ Note that \a w can be null, and that more than one signal may be
+ emitted for a single activation event.
+
+ \sa activeWindow(), windowList()
+*/
+
+
+
+/*!
+ Arranges all the child windows in a cascade pattern.
+
+ \sa tile()
+*/
+void TQWorkspace::cascade()
+{
+ blockSignals(TRUE);
+ if ( d->maxWindow )
+ d->maxWindow->showNormal();
+
+ if ( d->vbar ) {
+ d->vbar->blockSignals( TRUE );
+ d->vbar->setValue( 0 );
+ d->vbar->blockSignals( FALSE );
+ d->hbar->blockSignals( TRUE );
+ d->hbar->setValue( 0 );
+ d->hbar->blockSignals( FALSE );
+ scrollBarChanged();
+ }
+
+ const int xoffset = 13;
+ const int yoffset = 20;
+
+ // make a list of all relevant mdi clients
+ TQPtrList<TQWorkspaceChild> widgets;
+ TQWorkspaceChild* wc = 0;
+ for ( wc = d->focus.first(); wc; wc = d->focus.next() )
+ if ( wc->windowWidget()->isVisibleTo( this ) && !wc->windowWidget()->testWFlags( TQt::WStyle_Tool ) && !wc->iconw )
+ widgets.append( wc );
+
+ int x = 0;
+ int y = 0;
+
+ setUpdatesEnabled( FALSE );
+ TQPtrListIterator<TQWorkspaceChild> it( widgets );
+ while ( it.current () ) {
+ TQWorkspaceChild *child = it.current();
+ ++it;
+ child->setUpdatesEnabled( FALSE );
+ TQSize prefSize = child->windowWidget()->sizeHint().expandedTo( child->windowWidget()->minimumSizeHint() );
+
+ if ( !prefSize.isValid() )
+ prefSize = child->windowWidget()->size();
+ prefSize = prefSize.expandedTo( child->windowWidget()->tqminimumSize() ).boundedTo( child->windowWidget()->tqmaximumSize() );
+ if (prefSize.isValid())
+ prefSize += TQSize( child->baseSize().width(), child->baseSize().height() );
+
+ int w = prefSize.width();
+ int h = prefSize.height();
+
+ child->showNormal();
+ tqApp->sendPostedEvents( 0, TQEvent::ShowNormal );
+ if ( y + h > height() )
+ y = 0;
+ if ( x + w > width() )
+ x = 0;
+ child->setGeometry( x, y, w, h );
+ x += xoffset;
+ y += yoffset;
+ child->internalRaise();
+ child->setUpdatesEnabled( TRUE );
+ }
+ setUpdatesEnabled( TRUE );
+ updateWorkspace();
+ blockSignals(FALSE);
+}
+
+/*!
+ Arranges all child windows in a tile pattern.
+
+ \sa cascade()
+*/
+void TQWorkspace::tile()
+{
+ blockSignals(TRUE);
+ TQWidget *oldActive = d->active ? d->active->windowWidget() : 0;
+ if ( d->maxWindow )
+ d->maxWindow->showNormal();
+
+ if ( d->vbar ) {
+ d->vbar->blockSignals( TRUE );
+ d->vbar->setValue( 0 );
+ d->vbar->blockSignals( FALSE );
+ d->hbar->blockSignals( TRUE );
+ d->hbar->setValue( 0 );
+ d->hbar->blockSignals( FALSE );
+ scrollBarChanged();
+ }
+
+ int rows = 1;
+ int cols = 1;
+ int n = 0;
+ TQWorkspaceChild* c;
+
+ TQPtrListIterator<TQWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ c = it.current();
+ ++it;
+ if ( !c->windowWidget()->isHidden() &&
+ !c->windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) &&
+ !c->windowWidget()->testWFlags( TQt::WStyle_Tool ) &&
+ !c->iconw )
+ n++;
+ }
+
+ while ( rows * cols < n ) {
+ if ( cols <= rows )
+ cols++;
+ else
+ rows++;
+ }
+ int add = cols * rows - n;
+ bool* used = new bool[ cols*rows ];
+ for ( int i = 0; i < rows*cols; i++ )
+ used[i] = FALSE;
+
+ int row = 0;
+ int col = 0;
+ int w = width() / cols;
+ int h = height() / rows;
+
+ it.toFirst();
+ while ( it.current () ) {
+ c = it.current();
+ ++it;
+ if ( c->iconw || c->windowWidget()->isHidden() || c->windowWidget()->testWFlags( TQt::WStyle_Tool ) )
+ continue;
+ if (!row && !col) {
+ w -= c->baseSize().width();
+ h -= c->baseSize().height();
+ }
+ if ( c->windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) ) {
+ TQPoint p = c->pos();
+ if ( p.x()+c->width() < 0 )
+ p.setX( 0 );
+ if ( p.x() > width() )
+ p.setX( width() - c->width() );
+ if ( p.y() + 10 < 0 )
+ p.setY( 0 );
+ if ( p.y() > height() )
+ p.setY( height() - c->height() );
+
+ if ( p != c->pos() )
+ c->TQFrame::move( p );
+ } else {
+ c->showNormal();
+ tqApp->sendPostedEvents( 0, TQEvent::ShowNormal );
+ used[row*cols+col] = TRUE;
+ TQSize sz(w, h);
+ TQSize bsize(c->baseSize());
+ sz = sz.expandedTo(c->windowWidget()->tqminimumSize()).boundedTo(c->windowWidget()->tqmaximumSize());
+ sz += bsize;
+
+ if ( add ) {
+ if (sz.height() == h + bsize.height()) // no relevant constrains
+ sz.rheight() *= 2;
+ c->setGeometry(col*w + col*bsize.width(), row*h + row*bsize.height(), sz.width(), sz.height());
+ used[(row+1)*cols+col] = TRUE;
+ add--;
+ } else {
+ c->setGeometry(col*w + col*bsize.width(), row*h + row*bsize.height(), sz.width(), sz.height());
+ }
+ while( row < rows && col < cols && used[row*cols+col] ) {
+ col++;
+ if ( col == cols ) {
+ col = 0;
+ row++;
+ }
+ }
+ }
+ }
+ delete [] used;
+
+ activateWindow( oldActive );
+ updateWorkspace();
+ blockSignals(FALSE);
+}
+
+TQWorkspaceChild::TQWorkspaceChild( TQWidget* window, TQWorkspace *tqparent,
+ const char *name )
+ : TQFrame( tqparent, name,
+ (WFlags)((tqparent->windowMode() == TQWorkspace::TopLevel ? (TQt::WStyle_MinMax | TQt::WStyle_SysMenu | TQt::WType_TopLevel) :
+ TQt::WStyle_NoBorder ) | WStyle_Customize | TQt::WDestructiveClose | TQt::WNoMousePropagation | TQt::WSubWindow) )
+{
+ statusbar = 0;
+ setMouseTracking( TRUE );
+ act = FALSE;
+ iconw = 0;
+ lastfocusw = 0;
+ shademode = FALSE;
+ titlebar = 0;
+ snappedRight = FALSE;
+ snappedDown = FALSE;
+
+ if (window) {
+ switch (window->focusPolicy()) {
+ case Qt::NoFocus:
+ window->setFocusPolicy(Qt::ClickFocus);
+ break;
+ case Qt::TabFocus:
+ window->setFocusPolicy(Qt::StrongFocus);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ( window && window->testWFlags( TQt::WStyle_Title ) && tqparent->windowMode() != TQWorkspace::TopLevel ) {
+ titlebar = new TQTitleBar( window, this, "qt_ws_titlebar" );
+ connect( titlebar, TQT_SIGNAL( doActivate() ),
+ this, TQT_SLOT( activate() ) );
+ connect( titlebar, TQT_SIGNAL( doClose() ),
+ window, TQT_SLOT( close() ) );
+ connect( titlebar, TQT_SIGNAL( doMinimize() ),
+ this, TQT_SLOT( showMinimized() ) );
+ connect( titlebar, TQT_SIGNAL( doNormal() ),
+ this, TQT_SLOT( showNormal() ) );
+ connect( titlebar, TQT_SIGNAL( doMaximize() ),
+ this, TQT_SLOT( showMaximized() ) );
+ connect( titlebar, TQT_SIGNAL( popupOperationMenu(const TQPoint&) ),
+ this, TQT_SIGNAL( popupOperationMenu(const TQPoint&) ) );
+ connect( titlebar, TQT_SIGNAL( showOperationMenu() ),
+ this, TQT_SIGNAL( showOperationMenu() ) );
+ connect( titlebar, TQT_SIGNAL( doShade() ),
+ this, TQT_SLOT( showShaded() ) );
+ connect( titlebar, TQT_SIGNAL( doubleClicked() ),
+ this, TQT_SLOT( titleBarDoubleClicked() ) );
+ }
+
+ setFrameStyle( TQFrame::StyledPanel | TQFrame::Raised );
+ setLineWidth( tqstyle().tqpixelMetric(TQStyle::PM_MDIFrameWidth, this) );
+ setMinimumSize( 128, 0 );
+
+ childWidget = window;
+ if (!childWidget)
+ return;
+
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ setCaption( childWidget->caption() );
+#endif
+
+ TQPoint p;
+ TQSize s;
+ TQSize cs;
+
+ bool hasBeenResized = childWidget->testWState( TQt::WState_Resized );
+
+ if ( !hasBeenResized )
+ cs = childWidget->sizeHint().expandedTo( childWidget->minimumSizeHint() );
+ else
+ cs = childWidget->size();
+
+ int th = titlebar ? titlebar->sizeHint().height() : 0;
+ if ( titlebar ) {
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ int iconSize = th;
+ if( childWidget->icon() ) {
+ TQPixmap pm(childWidget->iconPixmap());
+ if(pm.width() > iconSize || pm.height() > iconSize) {
+ TQImage im;
+ im = pm;
+ pm = im.smoothScale( TQMIN(iconSize, pm.width()), TQMIN(iconSize, pm.height()) );
+ }
+ titlebar->setIcon( pm );
+ }
+#endif
+ if ( !tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder, titlebar ) )
+ th += frameWidth();
+ else
+ th -= contentsRect().y();
+
+ p = TQPoint( contentsRect().x(),
+ th + contentsRect().y() );
+ s = TQSize( cs.width() + 2*frameWidth(),
+ cs.height() + 2*frameWidth() + th );
+ } else {
+ p = TQPoint( contentsRect().x(), contentsRect().y() );
+ s = TQSize( cs.width() + 2*frameWidth(),
+ cs.height() + 2*frameWidth() );
+ }
+
+ childWidget->reparent( this, p);
+ resize( s );
+
+ childWidget->installEventFilter( this );
+
+ widgetResizeHandler = new TQWidgetResizeHandler( this, window );
+ widgetResizeHandler->setSizeProtection( !tqparent->scrollBarsEnabled() );
+ connect( widgetResizeHandler, TQT_SIGNAL( activate() ),
+ this, TQT_SLOT( activate() ) );
+ if ( !tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder, titlebar ) )
+ widgetResizeHandler->setExtraHeight( th + contentsRect().y() - 2*frameWidth() );
+ else
+ widgetResizeHandler->setExtraHeight( th + contentsRect().y() - frameWidth() );
+ if(tqparent->windowMode() == TQWorkspace::TopLevel && isTopLevel()) {
+ move(0, 0);
+ widgetResizeHandler->setActive( FALSE );
+ }
+ if ( childWidget->tqminimumSize() == childWidget->tqmaximumSize() )
+ widgetResizeHandler->setActive( TQWidgetResizeHandler::Resize, FALSE );
+ setBaseSize( baseSize() );
+}
+
+TQWorkspaceChild::~TQWorkspaceChild()
+{
+ if ( iconw )
+ delete iconw->parentWidget();
+ TQWorkspace *workspace = ::tqqt_cast<TQWorkspace*>(parentWidget());
+ if ( workspace ) {
+ workspace->d->focus.removeRef(this);
+ if ( workspace->d->active == this ) {
+ workspace->activatePrevWindow();
+ if (workspace->d->active == this) {
+ workspace->activateWindow(0);
+ }
+ }
+ if ( workspace->d->maxWindow == this ) {
+ workspace->hideMaximizeControls();
+ workspace->d->maxWindow = 0;
+ }
+ }
+}
+
+bool TQWorkspaceChild::event( TQEvent *e )
+{
+ if(((TQWorkspace*)parentWidget())->windowMode() == TQWorkspace::TopLevel) {
+ switch(e->type()) {
+ case TQEvent::Close:
+ if(windowWidget()) {
+ if(!windowWidget()->close()) {
+ if(((TQWorkspace*) parentWidget() )->d->active == this)
+ ((TQWorkspace*) parentWidget() )->activatePrevWindow();
+ return TRUE;
+ }
+ }
+ break;
+#if 0
+ case TQEvent::WindowDeactivate:
+ if(statusbar) {
+ TQSize newsize(width(), height() - statusbar->height());
+ if(statusbar->parentWidget() == this)
+ statusbar->hide();
+ statusbar = 0;
+ resize(newsize);
+ }
+ break;
+#endif
+ case TQEvent::WindowActivate:
+ if(((TQWorkspace*)parentWidget())->activeWindow() == windowWidget())
+ activate();
+ if(statusbar)
+ statusbar->show();
+ else if(((TQWorkspace*) parentWidget() )->d->mainwindow)
+ setqStatusBar(((TQWorkspace*) parentWidget() )->d->mainwindow->statusBar());
+ break;
+ default:
+ break;
+ }
+ }
+ return TQWidget::event(e);
+}
+
+void TQWorkspaceChild::setqStatusBar( TQStatusBar *sb )
+{
+ if(((TQWorkspace*) parentWidget() )->windowMode() == TQWorkspace::TopLevel) {
+ TQSize newsize;
+ if(sb) {
+ sb->show();
+ if(sb != statusbar) {
+ sb->reparent(this, TQPoint(0, height()), TRUE);
+ newsize = TQSize(width(), height() + sb->height());
+ }
+ }
+ statusbar = sb;
+ if(!newsize.isNull())
+ resize(newsize);
+ }
+}
+
+void TQWorkspaceChild::moveEvent( TQMoveEvent *e )
+{
+ if(((TQWorkspace*) parentWidget() )->windowMode() == TQWorkspace::TopLevel && !e->spontaneous()) {
+ TQPoint p = parentWidget()->tqtopLevelWidget()->pos();
+ if(x() < p.x() || y() < p.y())
+ move(TQMAX(x(), p.x()), TQMAX(y(), p.y()));
+ }
+ ((TQWorkspace*) parentWidget() )->updateWorkspace();
+}
+
+void TQWorkspaceChild::resizeEvent( TQResizeEvent * )
+{
+ TQRect r = contentsRect();
+ TQRect cr;
+
+ if ( titlebar ) {
+ int th = titlebar->sizeHint().height();
+ TQRect tbrect( 0, 0, width(), th );
+ if ( !tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder ) )
+ tbrect = TQRect( r.x(), r.y(), r.width(), th );
+ titlebar->setGeometry( tbrect );
+
+ if ( tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder, titlebar ) )
+ th -= frameWidth();
+ cr = TQRect( r.x(), r.y() + th + (shademode ? (frameWidth() * 3) : 0),
+ r.width(), r.height() - th );
+ } else {
+ cr = r;
+ }
+
+ if(statusbar && statusbar->isVisible()) {
+ int sh = statusbar->height();
+ statusbar->setGeometry(r.x(), r.bottom() - sh, r.width(), sh);
+ cr.setBottom(cr.bottom() - sh);
+ }
+
+ if (!childWidget)
+ return;
+
+ windowSize = cr.size();
+ childWidget->setGeometry( cr );
+ ((TQWorkspace*) parentWidget() )->updateWorkspace();
+}
+
+TQSize TQWorkspaceChild::baseSize() const
+{
+ int th = titlebar ? titlebar->sizeHint().height() : 0;
+ if ( tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder, titlebar ) )
+ th -= frameWidth();
+ return TQSize( 2*frameWidth(), 2*frameWidth() + th );
+}
+
+TQSize TQWorkspaceChild::tqsizeHint() const
+{
+ if ( !childWidget )
+ return TQFrame::tqsizeHint() + baseSize();
+
+ TQSize prefSize = windowWidget()->sizeHint().expandedTo( windowWidget()->minimumSizeHint() );
+ prefSize = prefSize.expandedTo( windowWidget()->tqminimumSize() ).boundedTo( windowWidget()->tqmaximumSize() );
+ prefSize += baseSize();
+
+ return prefSize;
+}
+
+TQSize TQWorkspaceChild::tqminimumSizeHint() const
+{
+ if ( !childWidget )
+ return TQFrame::tqminimumSizeHint() + baseSize();
+ TQSize s = childWidget->tqminimumSize();
+ if ( s.isEmpty() )
+ s = childWidget->minimumSizeHint();
+ return s + baseSize();
+}
+
+void TQWorkspaceChild::activate()
+{
+ ((TQWorkspace*)parentWidget())->activateWindow( windowWidget() );
+}
+
+bool TQWorkspaceChild::eventFilter( TQObject * o, TQEvent * e)
+{
+ if ( !isActive() && ( e->type() == TQEvent::MouseButtonPress ||
+ e->type() == TQEvent::FocusIn ) ) {
+ if ( iconw ) {
+ ((TQWorkspace*)parentWidget())->normalizeWindow( windowWidget() );
+ if ( iconw ) {
+ ((TQWorkspace*)parentWidget())->removeIcon( iconw->parentWidget() );
+ delete iconw->parentWidget();
+ iconw = 0;
+ }
+ }
+ activate();
+ }
+
+ // for all widgets except the window, that's the only thing we
+ // process, and if we have no childWidget we skip totally
+ if ( TQT_BASE_OBJECT(o) != TQT_BASE_OBJECT(childWidget) || childWidget == 0 )
+ return FALSE;
+
+ switch ( e->type() ) {
+ case TQEvent::Show:
+ if ( ((TQWorkspace*)parentWidget())->d->focus.tqfind( this ) < 0 )
+ ((TQWorkspace*)parentWidget())->d->focus.append( this );
+ if ( isVisibleTo( parentWidget() ) )
+ break;
+ if (( (TQShowEvent*)e)->spontaneous() )
+ break;
+ // fall through
+ case TQEvent::ShowToParent:
+ if ( windowWidget() && windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) ) {
+ internalRaise();
+ show();
+ }
+ ((TQWorkspace*)parentWidget())->showWindow( windowWidget() );
+ break;
+ case TQEvent::ShowMaximized:
+ if ( windowWidget()->tqmaximumSize().isValid() &&
+ ( windowWidget()->maximumWidth() < parentWidget()->width() ||
+ windowWidget()->maximumHeight() < parentWidget()->height() ) ) {
+ windowWidget()->resize( windowWidget()->tqmaximumSize() );
+ ((TQWorkspace*)windowWidget())->clearWState(TQt::WState_Maximized);
+ if (titlebar)
+ titlebar->tqrepaint(FALSE);
+ break;
+ }
+ if ( windowWidget()->testWFlags( TQt::WStyle_Maximize ) && !windowWidget()->testWFlags( TQt::WStyle_Tool ) )
+ ((TQWorkspace*)parentWidget())->maximizeWindow( windowWidget() );
+ else
+ ((TQWorkspace*)parentWidget())->normalizeWindow( windowWidget() );
+ break;
+ case TQEvent::ShowMinimized:
+ ((TQWorkspace*)parentWidget())->minimizeWindow( windowWidget() );
+ break;
+ case TQEvent::ShowNormal:
+ ((TQWorkspace*)parentWidget())->normalizeWindow( windowWidget() );
+ if (iconw) {
+ ((TQWorkspace*)parentWidget())->removeIcon( iconw->parentWidget() );
+ delete iconw->parentWidget();
+ }
+ break;
+ case TQEvent::Hide:
+ case TQEvent::HideToParent:
+ if ( !childWidget->isVisibleTo( this ) ) {
+ TQWidget * w = iconw;
+ if ( w && ( w = w->parentWidget() ) ) {
+ ((TQWorkspace*)parentWidget())->removeIcon( w );
+ delete w;
+ }
+ hide();
+ }
+ break;
+ case TQEvent::CaptionChange:
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ setCaption( childWidget->caption() );
+ if ( iconw )
+ iconw->setCaption( childWidget->caption() );
+#endif
+ break;
+ case TQEvent::IconChange:
+ {
+ TQWorkspace* ws = (TQWorkspace*)parentWidget();
+ if ( !titlebar )
+ break;
+
+ TQPixmap pm;
+ int iconSize = titlebar->size().height();
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( childWidget->icon() ) {
+ pm = *childWidget->icon();
+ if(pm.width() > iconSize || pm.height() > iconSize) {
+ TQImage im;
+ im = pm;
+ pm = im.smoothScale( TQMIN(iconSize, pm.width()), TQMIN(iconSize, pm.height()) );
+ }
+ } else
+#endif
+ {
+ pm.resize( iconSize, iconSize );
+ pm.fill( Qt::color1 );
+ pm.setMask(pm.createHeuristicMask());
+ }
+ titlebar->setIcon( pm );
+ if ( iconw )
+ iconw->setIcon( pm );
+
+ if ( ws->d->maxWindow != this )
+ break;
+
+ if ( ws->d->maxtools )
+ ws->d->maxtools->setPixmap( pm );
+ }
+ break;
+ case TQEvent::Resize:
+ {
+ TQResizeEvent* re = (TQResizeEvent*)e;
+ if ( re->size() != windowSize && !shademode )
+ resize( re->size() + baseSize() );
+ }
+ break;
+
+ case TQEvent::WindowDeactivate:
+ if ( titlebar )
+ titlebar->setActive( FALSE );
+ tqrepaint( FALSE );
+ break;
+
+ case TQEvent::WindowActivate:
+ if ( titlebar )
+ titlebar->setActive( act );
+ tqrepaint( FALSE );
+ break;
+
+ default:
+ break;
+ }
+
+ return TQFrame::eventFilter(o, e);
+}
+
+bool TQWorkspaceChild::focusNextPrevChild( bool next )
+{
+ TQFocusData *f = focusData();
+
+ TQWidget *startingPoint = f->home();
+ TQWidget *candidate = 0;
+ TQWidget *w = next ? f->next() : f->prev();
+ while( !candidate && w != startingPoint ) {
+ if ( w != startingPoint &&
+ (w->focusPolicy() & Qt::TabFocus) == Qt::TabFocus
+ && w->isEnabled() &&!w->focusProxy() && w->isVisible() )
+ candidate = w;
+ w = next ? f->next() : f->prev();
+ }
+
+ if ( candidate ) {
+ TQObjectList *ol = queryList();
+ bool ischild = ol->tqfindRef( TQT_TQOBJECT(candidate) ) != -1;
+ delete ol;
+ if ( !ischild ) {
+ startingPoint = f->home();
+ TQWidget *nw = next ? f->prev() : f->next();
+ TQObjectList *ol2 = queryList();
+ TQWidget *lastValid = 0;
+ candidate = startingPoint;
+ while ( nw != startingPoint ) {
+ if ( ( candidate->focusPolicy() & Qt::TabFocus ) == Qt::TabFocus
+ && candidate->isEnabled() &&!candidate->focusProxy() && candidate->isVisible() )
+ lastValid = candidate;
+ if ( ol2->tqfindRef( TQT_TQOBJECT(nw) ) == -1 ) {
+ candidate = lastValid;
+ break;
+ }
+ candidate = nw;
+ nw = next ? f->prev() : f->next();
+ }
+ delete ol2;
+ }
+ }
+
+ if ( !candidate )
+ return FALSE;
+
+ candidate->setFocus();
+ return TRUE;
+}
+
+void TQWorkspaceChild::childEvent( TQChildEvent* e)
+{
+ if ( e->type() == TQEvent::ChildRemoved && e->child() == childWidget ) {
+ childWidget = 0;
+ if ( iconw ) {
+ ((TQWorkspace*)parentWidget())->removeIcon( iconw->parentWidget() );
+ delete iconw->parentWidget();
+ }
+ close();
+ }
+}
+
+
+void TQWorkspaceChild::doResize()
+{
+ widgetResizeHandler->doResize();
+}
+
+void TQWorkspaceChild::doMove()
+{
+ widgetResizeHandler->doMove();
+}
+
+void TQWorkspaceChild::enterEvent( TQEvent * )
+{
+}
+
+void TQWorkspaceChild::leaveEvent( TQEvent * )
+{
+#ifndef TQT_NO_CURSOR
+ if ( !widgetResizeHandler->isButtonDown() )
+ setCursor( Qt::ArrowCursor );
+#endif
+}
+
+void TQWorkspaceChild::drawFrame( TQPainter *p )
+{
+ TQStyle::SFlags flags = TQStyle::Style_Default;
+ TQStyleOption opt(lineWidth(),midLineWidth());
+
+ if ( titlebar && titlebar->isActive() )
+ flags |= TQStyle::Style_Active;
+
+ tqstyle().tqdrawPrimitive( TQStyle::PE_WindowFrame, p, rect(), tqcolorGroup(), flags, opt );
+}
+
+void TQWorkspaceChild::styleChange( TQStyle & )
+{
+ resizeEvent( 0 );
+ if ( iconw ) {
+ TQVBox *vbox = (TQVBox*)iconw->parentWidget()->tqqt_cast( "TQVBox" );
+ TQ_ASSERT(vbox);
+ if ( !tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder ) ) {
+ vbox->setFrameStyle( TQFrame::WinPanel | TQFrame::Raised );
+ vbox->resize( 196+2*vbox->frameWidth(), 20 + 2*vbox->frameWidth() );
+ } else {
+ vbox->resize( 196, 20 );
+ }
+ }
+}
+
+void TQWorkspaceChild::setActive( bool b )
+{
+ if ( !childWidget )
+ return;
+
+ bool hasFocus = isChildOf( tqfocusWidget(), childWidget );
+ if ( act == b && hasFocus )
+ return;
+
+ act = b;
+
+ if ( titlebar )
+ titlebar->setActive( act );
+ if ( iconw )
+ iconw->setActive( act );
+ tqrepaint( FALSE );
+
+ TQObjectList* ol = childWidget->queryList( "TQWidget" );
+ if ( act ) {
+ TQObject *o;
+ for ( o = ol->first(); o; o = ol->next() )
+ o->removeEventFilter( this );
+ if ( !hasFocus ) {
+ if ( lastfocusw && ol->tqcontains( TQT_TQOBJECT(lastfocusw) ) &&
+ lastfocusw->focusPolicy() != Qt::NoFocus ) {
+ // this is a bug if lastfocusw has been deleted, a new
+ // widget has been created, and the new one is a child
+ // of the same window as the old one. but even though
+ // it's a bug the behaviour is reasonable
+ lastfocusw->setFocus();
+ } else if ( childWidget->focusPolicy() != Qt::NoFocus ) {
+ childWidget->setFocus();
+ } else {
+ // tqfind something, anything, that accepts focus, and use that.
+ o = ol->first();
+ while( o && ((TQWidget*)o)->focusPolicy() == Qt::NoFocus )
+ o = ol->next();
+ if ( o )
+ ((TQWidget*)o)->setFocus();
+ }
+ }
+ } else {
+ if ( isChildOf( tqfocusWidget(), childWidget ) )
+ lastfocusw = tqfocusWidget();
+ TQObject * o;
+ for ( o = ol->first(); o; o = ol->next() ) {
+ o->removeEventFilter( this );
+ o->installEventFilter( this );
+ }
+ }
+ delete ol;
+}
+
+bool TQWorkspaceChild::isActive() const
+{
+ return act;
+}
+
+TQWidget* TQWorkspaceChild::windowWidget() const
+{
+ return childWidget;
+}
+
+
+TQWidget* TQWorkspaceChild::iconWidget() const
+{
+ if ( !iconw ) {
+ TQWorkspaceChild* that = (TQWorkspaceChild*) this;
+
+ // ### why do we even need the vbox? -Brad
+ TQVBox* vbox = new TQVBox(that, "qt_vbox", (WFlags)TQt::WType_TopLevel );
+ TQTitleBar *tb = new TQTitleBar( windowWidget(), vbox, "_workspacechild_icon_");
+ int th = tqstyle().tqpixelMetric( TQStyle::PM_TitleBarHeight, tb );
+ int iconSize = tqstyle().tqpixelMetric( TQStyle::PM_MDIMinimizedWidth, this );
+ if ( !tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder ) ) {
+ vbox->setFrameStyle( TQFrame::WinPanel | TQFrame::Raised );
+ vbox->resize( iconSize+2*vbox->frameWidth(), th+2*vbox->frameWidth() );
+ } else {
+ vbox->resize( iconSize, th );
+ }
+ that->iconw = tb;
+ iconw->setActive( isActive() );
+
+ connect( iconw, TQT_SIGNAL( doActivate() ),
+ this, TQT_SLOT( activate() ) );
+ connect( iconw, TQT_SIGNAL( doClose() ),
+ windowWidget(), TQT_SLOT( close() ) );
+ connect( iconw, TQT_SIGNAL( doNormal() ),
+ this, TQT_SLOT( showNormal() ) );
+ connect( iconw, TQT_SIGNAL( doMaximize() ),
+ this, TQT_SLOT( showMaximized() ) );
+ connect( iconw, TQT_SIGNAL( popupOperationMenu(const TQPoint&) ),
+ this, TQT_SIGNAL( popupOperationMenu(const TQPoint&) ) );
+ connect( iconw, TQT_SIGNAL( showOperationMenu() ),
+ this, TQT_SIGNAL( showOperationMenu() ) );
+ connect( iconw, TQT_SIGNAL( doubleClicked() ),
+ this, TQT_SLOT( titleBarDoubleClicked() ) );
+ }
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ if ( windowWidget() ) {
+ iconw->setCaption( windowWidget()->caption() );
+ if ( windowWidget()->icon() ) {
+ int iconSize = iconw->sizeHint().height();
+
+ TQPixmap pm(*childWidget->icon());
+ if(pm.width() > iconSize || pm.height() > iconSize) {
+ TQImage im;
+ im = pm;
+ pm = im.smoothScale( TQMIN(iconSize, pm.width()), TQMIN(iconSize, pm.height()) );
+ }
+ iconw->setIcon( pm );
+ }
+ }
+#endif
+ return iconw->parentWidget();
+}
+
+void TQWorkspaceChild::showMinimized()
+{
+ windowWidget()->setWindowState((WState)(TQt::WindowMinimized | windowWidget()->windowState()));
+}
+
+void TQWorkspaceChild::showMaximized()
+{
+ windowWidget()->setWindowState((WState)(TQt::WindowMaximized | (windowWidget()->windowState() & ~TQt::WindowMinimized)));
+}
+
+void TQWorkspaceChild::showNormal()
+{
+ windowWidget()->setWindowState((WState)(windowWidget()->windowState() & ~(TQt::WindowMinimized|TQt::WindowMaximized)));
+}
+
+void TQWorkspaceChild::showShaded()
+{
+ if ( !titlebar)
+ return;
+ TQ_ASSERT( windowWidget()->testWFlags( TQt::WStyle_MinMax ) && windowWidget()->testWFlags( TQt::WStyle_Tool ) );
+ ((TQWorkspace*)parentWidget())->activateWindow( windowWidget() );
+ if ( shademode ) {
+ TQWorkspaceChild* fake = (TQWorkspaceChild*)windowWidget();
+ fake->clearWState( TQt::WState_Minimized );
+ clearWState( TQt::WState_Minimized );
+
+ shademode = FALSE;
+ resize( shadeRestore );
+ setMinimumSize( shadeRestoreMin );
+ tqstyle().polish(this);
+ } else {
+ shadeRestore = size();
+ shadeRestoreMin = tqminimumSize();
+ setMinimumHeight(0);
+ shademode = TRUE;
+ TQWorkspaceChild* fake = (TQWorkspaceChild*)windowWidget();
+ fake->setWState( TQt::WState_Minimized );
+ setWState( TQt::WState_Minimized );
+
+ if ( tqstyle().tqstyleHint( TQStyle::SH_TitleBar_NoBorder ) )
+ resize( width(), titlebar->height() );
+ else
+ resize( width(), titlebar->height() + 2*lineWidth() + 1 );
+ tqstyle().polish(this);
+ }
+ titlebar->update();
+}
+
+void TQWorkspaceChild::titleBarDoubleClicked()
+{
+ if ( !windowWidget() )
+ return;
+ if ( windowWidget()->testWFlags( TQt::WStyle_MinMax ) ) {
+ if ( windowWidget()->testWFlags( TQt::WStyle_Tool ) )
+ showShaded();
+ else if ( iconw )
+ showNormal();
+ else if ( windowWidget()->testWFlags( TQt::WStyle_Maximize ) )
+ showMaximized();
+ }
+}
+
+void TQWorkspaceChild::adjustToFullscreen()
+{
+ if ( !childWidget )
+ return;
+
+ tqApp->sendPostedEvents( this, TQEvent::Resize );
+ tqApp->sendPostedEvents( childWidget, TQEvent::Resize );
+ tqApp->sendPostedEvents( childWidget, TQEvent::Move );
+ if( tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this) ) {
+ setGeometry( 0, 0, parentWidget()->width(), parentWidget()->height());
+ } else {
+ int w = parentWidget()->width() + width() - childWidget->width();
+ int h = parentWidget()->height() + height() - childWidget->height();
+ w = TQMAX( w, childWidget->minimumWidth() );
+ h = TQMAX( h, childWidget->minimumHeight() );
+ setGeometry( -childWidget->x(), -childWidget->y(), w, h );
+ }
+ setWState( TQt::WState_Maximized );
+ ((TQWorkspaceChild*)childWidget)->setWState( TQt::WState_Maximized );
+}
+
+void TQWorkspaceChild::setCaption( const TQString& cap )
+{
+ if ( titlebar )
+ titlebar->setCaption( cap );
+#ifndef TQT_NO_WIDGET_TOPEXTRA
+ TQWidget::setCaption( cap );
+#endif
+}
+
+void TQWorkspaceChild::internalRaise()
+{
+ setUpdatesEnabled( FALSE );
+ if ( iconw )
+ iconw->parentWidget()->raise();
+ raise();
+
+ if ( !windowWidget() || windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) ) {
+ setUpdatesEnabled( TRUE );
+ return;
+ }
+
+ TQPtrListIterator<TQWorkspaceChild> it( ((TQWorkspace*)tqparent())->d->windows );
+ while ( it.current () ) {
+ TQWorkspaceChild* c = it.current();
+ ++it;
+ if ( c->windowWidget() &&
+ !c->windowWidget()->isHidden() &&
+ c->windowWidget()->testWFlags( TQt::WStyle_StaysOnTop ) )
+ c->raise();
+ }
+ setUpdatesEnabled( TRUE );
+}
+
+void TQWorkspaceChild::move( int x, int y )
+{
+ int nx = x;
+ int ny = y;
+
+ if ( windowWidget() && windowWidget()->testWFlags( TQt::WStyle_Tool ) ) {
+ int dx = 10;
+ int dy = 10;
+
+ if ( TQABS( x ) < dx )
+ nx = 0;
+ if ( TQABS( y ) < dy )
+ ny = 0;
+ if ( TQABS( x + width() - parentWidget()->width() ) < dx ) {
+ nx = parentWidget()->width() - width();
+ snappedRight = TRUE;
+ } else
+ snappedRight = FALSE;
+
+ if ( TQABS( y + height() - parentWidget()->height() ) < dy ) {
+ ny = parentWidget()->height() - height();
+ snappedDown = TRUE;
+ } else
+ snappedDown = FALSE;
+ }
+ TQFrame::move( nx, ny );
+}
+
+bool TQWorkspace::scrollBarsEnabled() const
+{
+ return d->vbar != 0;
+}
+
+/*!
+ \property TQWorkspace::scrollBarsEnabled
+ \brief whether the workspace provides scrollbars
+
+ If this property is set to TRUE, it is possible to resize child
+ windows over the right or the bottom edge out of the visible area
+ of the workspace. The workspace shows scrollbars to make it
+ possible for the user to access those windows. If this property is
+ set to FALSE (the default), resizing windows out of the visible
+ area of the workspace is not permitted.
+*/
+void TQWorkspace::setScrollBarsEnabled( bool enable )
+{
+ if ( (d->vbar != 0) == enable )
+ return;
+
+ d->xoffset = d->yoffset = 0;
+ if ( enable ) {
+ d->vbar = new TQScrollBar( Qt::Vertical, this, "vertical scrollbar" );
+ connect( d->vbar, TQT_SIGNAL( valueChanged(int) ), this, TQT_SLOT( scrollBarChanged() ) );
+ d->hbar = new TQScrollBar( Qt::Horizontal, this, "horizontal scrollbar" );
+ connect( d->hbar, TQT_SIGNAL( valueChanged(int) ), this, TQT_SLOT( scrollBarChanged() ) );
+ d->corner = new TQWidget( this, "qt_corner" );
+ updateWorkspace();
+ } else {
+ delete d->vbar;
+ delete d->hbar;
+ delete d->corner;
+ d->vbar = d->hbar = 0;
+ d->corner = 0;
+ }
+
+ TQPtrListIterator<TQWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ TQWorkspaceChild *child = it.current();
+ ++it;
+ child->widgetResizeHandler->setSizeProtection( !enable );
+ }
+}
+
+TQRect TQWorkspace::updateWorkspace()
+{
+ if ( !isUpdatesEnabled() )
+ return rect();
+
+ TQRect cr( rect() );
+
+ if ( scrollBarsEnabled() && !d->maxWindow ) {
+ d->corner->raise();
+ d->vbar->raise();
+ d->hbar->raise();
+ if ( d->maxWindow )
+ d->maxWindow->internalRaise();
+
+ TQRect r( 0, 0, 0, 0 );
+ TQPtrListIterator<TQWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ TQWorkspaceChild *child = it.current();
+ ++it;
+ if ( !child->isHidden() )
+ r = r.unite( child->tqgeometry() );
+ }
+ d->vbar->blockSignals( TRUE );
+ d->hbar->blockSignals( TRUE );
+
+ int hsbExt = d->hbar->sizeHint().height();
+ int vsbExt = d->vbar->sizeHint().width();
+
+
+ bool showv = d->yoffset || d->yoffset + r.bottom() - height() + 1 > 0 || d->yoffset + r.top() < 0;
+ bool showh = d->xoffset || d->xoffset + r.right() - width() + 1 > 0 || d->xoffset + r.left() < 0;
+
+ if ( showh && !showv)
+ showv = d->yoffset + r.bottom() - height() + hsbExt + 1 > 0;
+ if ( showv && !showh )
+ showh = d->xoffset + r.right() - width() + vsbExt + 1 > 0;
+
+ if ( !showh )
+ hsbExt = 0;
+ if ( !showv )
+ vsbExt = 0;
+
+ if ( showv ) {
+ d->vbar->setSteps( TQMAX( height() / 12, 30 ), height() - hsbExt );
+ d->vbar->setRange( TQMIN( 0, d->yoffset + TQMIN( 0, r.top() ) ), TQMAX( 0, d->yoffset + TQMAX( 0, r.bottom() - height() + hsbExt + 1) ) );
+ d->vbar->setGeometry( width() - vsbExt, 0, vsbExt, height() - hsbExt );
+ d->vbar->setValue( d->yoffset );
+ d->vbar->show();
+ } else {
+ d->vbar->hide();
+ }
+
+ if ( showh ) {
+ d->hbar->setSteps( TQMAX( width() / 12, 30 ), width() - vsbExt );
+ d->hbar->setRange( TQMIN( 0, d->xoffset + TQMIN( 0, r.left() ) ), TQMAX( 0, d->xoffset + TQMAX( 0, r.right() - width() + vsbExt + 1) ) );
+ d->hbar->setGeometry( 0, height() - hsbExt, width() - vsbExt, hsbExt );
+ d->hbar->setValue( d->xoffset );
+ d->hbar->show();
+ } else {
+ d->hbar->hide();
+ }
+
+ if ( showh && showv ) {
+ d->corner->setGeometry( width() - vsbExt, height() - hsbExt, vsbExt, hsbExt );
+ d->corner->show();
+ } else {
+ d->corner->hide();
+ }
+
+ d->vbar->blockSignals( FALSE );
+ d->hbar->blockSignals( FALSE );
+
+ cr.setRect( 0, 0, width() - vsbExt, height() - hsbExt );
+ }
+
+ TQPtrListIterator<TQWidget> ii( d->icons );
+ while ( ii.current() ) {
+ TQWorkspaceChild* w = (TQWorkspaceChild*)ii.current();
+ ++ii;
+ int x = w->x();
+ int y = w->y();
+ bool m = FALSE;
+ if ( x+w->width() > cr.width() ) {
+ m = TRUE;
+ x = cr.width() - w->width();
+ }
+ if ( y+w->height() > cr.height() ) {
+ y = cr.height() - w->height();
+ m = TRUE;
+ }
+ if ( m )
+ w->move( x, y );
+ }
+
+ return cr;
+
+}
+
+void TQWorkspace::scrollBarChanged()
+{
+ int ver = d->yoffset - d->vbar->value();
+ int hor = d->xoffset - d->hbar->value();
+ d->yoffset = d->vbar->value();
+ d->xoffset = d->hbar->value();
+
+ TQPtrListIterator<TQWorkspaceChild> it( d->windows );
+ while ( it.current () ) {
+ TQWorkspaceChild *child = it.current();
+ ++it;
+ // we do not use move() due to the reimplementation in TQWorkspaceChild
+ child->setGeometry( child->x() + hor, child->y() + ver, child->width(), child->height() );
+ }
+ updateWorkspace();
+}
+
+/*!
+ \enum TQWorkspace::WindowOrder
+
+ Specifies the order in which windows are returned from windowList().
+
+ \value CreationOrder The windows are returned in the order of their creation
+ \value StackingOrder The windows are returned in the order of their stacking
+*/
+
+#ifdef TQT_WORKSPACE_WINDOWMODE
+/*!
+ \enum TQWorkspace::WindowMode
+
+ Determines the Windowing Model TQWorkspace will use for sub-windows.
+
+ \value TopLevel Subwindows are treated as toplevel windows
+ \value MDI Subwindows are organized in an MDI interface
+ \value AutoDetect TQWorkspace will detect whether TopLevel or MDI
+ is appropriate
+*/
+
+/*!
+ The windowing model influences how the subwindows are actually
+ created. For most platforms the default behavior of a workspace is
+ to operate in MDI mode, with TQt/Mac the default mode is
+ AutoDetect.
+*/
+#else
+/*! \internal */
+#endif
+TQWorkspace::WindowMode TQWorkspace::windowMode() const
+{
+ return d->wmode;
+}
+
+#ifndef TQT_NO_STYLE
+/*!\reimp */
+void TQWorkspace::styleChange( TQStyle &olds )
+{
+ int fs = tqstyle().tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this);
+ if ( isVisibleTo(0) && d->maxWindow &&
+ fs != olds.tqstyleHint(TQStyle::SH_Workspace_FillSpaceOnMaximize, this)) {
+ if( fs )
+ hideMaximizeControls();
+ else
+ showMaximizeControls();
+ }
+ TQWidget::styleChange(olds);
+}
+#endif
+
+
+
+
+#include "tqworkspace.tqmoc"
+#endif // TQT_NO_WORKSPACE
diff --git a/tqtinterface/qt4/src/workspace/tqworkspace.h b/tqtinterface/qt4/src/workspace/tqworkspace.h
new file mode 100644
index 0000000..2b128ec
--- /dev/null
+++ b/tqtinterface/qt4/src/workspace/tqworkspace.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** Definition of the TQWorkspace class
+**
+** Created : 990210
+**
+** Copyright (C) 1999-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the workspace module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQWORKSPACE_H
+#define TQWORKSPACE_H
+
+#ifndef TQT_H
+#include "tqwidget.h"
+#include "tqwidgetlist.h"
+#endif // TQT_H
+
+#ifndef TQT_NO_WORKSPACE
+
+#if !defined( TQT_MODULE_WORKSPACE ) || defined( TQT_INTERNAL_WORKSPACE )
+#define TQM_EXPORT_WORKSPACE
+#else
+#define TQM_EXPORT_WORKSPACE TQ_EXPORT
+#endif
+
+class TQWorkspaceChild;
+class TQShowEvent;
+class TQWorkspacePrivate;
+class TQPopupMenu;
+class TQDockWindow;
+
+class TQM_EXPORT_WORKSPACE TQWorkspace : public TQWidget
+{
+ Q_OBJECT
+ TQ_OBJECT
+ Q_PROPERTY( bool scrollBarsEnabled READ scrollBarsEnabled WRITE setScrollBarsEnabled )
+
+#ifdef TQT_WORKSPACE_WINDOWMODE
+public:
+#endif
+ enum WindowMode { TopLevel, MDI, AutoDetect };
+ WindowMode windowMode() const;
+#ifdef TQT_WORKSPACE_WINDOWMODE
+private:
+#endif
+
+public:
+#ifdef TQT_WORKSPACE_WINDOWMODE
+ TQWorkspace( WindowMode mode, TQWidget* tqparent=0, const char* name=0 );
+#endif
+ TQWorkspace( TQWidget* tqparent=0, const char* name=0 );
+
+ ~TQWorkspace();
+
+ enum WindowOrder { CreationOrder, StackingOrder };
+
+ TQWidget* activeWindow() const;
+ TQWidgetList windowList() const; // ### merge with below in 4.0
+ TQWidgetList windowList( WindowOrder order ) const;
+
+ TQSize tqsizeHint() const;
+
+ bool scrollBarsEnabled() const;
+ void setScrollBarsEnabled( bool enable );
+
+ void setPaletteBackgroundColor( const TQColor & );
+ void setPaletteBackgroundPixmap( const TQPixmap & );
+
+Q_SIGNALS:
+ void windowActivated( TQWidget* w);
+
+public Q_SLOTS:
+ void cascade();
+ void tile();
+ void closeActiveWindow();
+ void closeAllWindows();
+ void activateNextWindow();
+ void activatePrevWindow();
+
+protected:
+#ifndef TQT_NO_STYLE
+ void styleChange( TQStyle& );
+#endif
+ void childEvent( TQChildEvent * );
+ void resizeEvent( TQResizeEvent * );
+ bool eventFilter( TQObject *, TQEvent * );
+ void showEvent( TQShowEvent *e );
+ void hideEvent( TQHideEvent *e );
+#ifndef TQT_NO_WHEELEVENT
+ void wheelEvent( TQWheelEvent *e );
+#endif
+
+private Q_SLOTS:
+ void normalizeActiveWindow();
+ void minimizeActiveWindow();
+ void showOperationMenu();
+ void popupOperationMenu( const TQPoint& );
+ void operationMenuActivated( int );
+ void operationMenuAboutToShow();
+ void toolMenuAboutToShow();
+ void activatePreviousWindow(); // ### remove in TQt 4.0
+ void dockWindowsShow();
+ void scrollBarChanged();
+
+private:
+ void init();
+ void handleUndock( TQDockWindow* w);
+ void insertIcon( TQWidget* w);
+ void removeIcon( TQWidget* w);
+ void place( TQWidget* );
+
+ TQWorkspaceChild* tqfindChild( TQWidget* w);
+ void showMaximizeControls();
+ void hideMaximizeControls();
+ void activateWindow( TQWidget* w, bool change_focus = TRUE );
+ void showWindow( TQWidget* w);
+ void maximizeWindow( TQWidget* w);
+ void minimizeWindow( TQWidget* w);
+ void normalizeWindow( TQWidget* w);
+
+ TQRect updateWorkspace();
+
+ TQPopupMenu* popup;
+ TQWorkspacePrivate* d;
+
+ friend class TQWorkspacePrivate;
+ friend class TQWorkspaceChild;
+
+private: // Disabled copy constructor and operator=
+#if defined(TQ_DISABLE_COPY)
+ TQWorkspace( const TQWorkspace & );
+ TQWorkspace& operator=( const TQWorkspace & );
+#endif
+};
+
+
+#endif // TQT_NO_WORKSPACE
+
+#endif // TQWORKSPACE_H
diff --git a/tqtinterface/qt4/src/xml/qt_xml.pri b/tqtinterface/qt4/src/xml/qt_xml.pri
new file mode 100644
index 0000000..d3d4577
--- /dev/null
+++ b/tqtinterface/qt4/src/xml/qt_xml.pri
@@ -0,0 +1,10 @@
+# Qt xml module
+
+xml {
+ HEADERS += $$XML_H/tqxml.h $$XML_H/tqdom.h $$XML_CPP/tqsvgdevice_p.h
+ SOURCES += $$XML_CPP/tqxml.cpp $$XML_CPP/tqdom.cpp $$XML_CPP/tqsvgdevice.cpp
+ win32-borland {
+ QMAKE_CFLAGS_WARN_ON += -w-use
+ TQMAKE_CXXFLAGS_WARN_ON += -w-use
+ }
+}
diff --git a/tqtinterface/qt4/src/xml/tqdom.cpp b/tqtinterface/qt4/src/xml/tqdom.cpp
new file mode 100644
index 0000000..ef453c3
--- /dev/null
+++ b/tqtinterface/qt4/src/xml/tqdom.cpp
@@ -0,0 +1,7092 @@
+/****************************************************************************
+**
+** Implementation of TQDomDocument and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the xml module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqdom.h"
+
+#ifndef TQT_NO_DOM
+
+#include "tqxml.h"
+#include "tqptrlist.h"
+#include "tqdict.h"
+#include "tqtextstream.h"
+#include "tqtextcodec.h"
+#include "tqiodevice.h"
+#include "tqregexp.h"
+#include "tqbuffer.h"
+
+/*
+ ### old todo comments -- I don't know if they still apply...
+
+ If the document dies, remove all pointers to it from tqchildren
+ which can not be deleted at this time.
+
+ If a node dies and has direct tqchildren which can not be deleted,
+ then remove the pointer to the tqparent.
+
+ createElement and friends create double reference counts.
+*/
+
+/*
+ Reference counting:
+
+ Some simple rules:
+ 1) If an intern object returns a pointer to another intern object
+ then the reference count of the returned object is not increased.
+ 2) If an extern object is created and gets a pointer to some intern
+ object, then the extern object increases the intern objects reference count.
+ 3) If an extern object is deleted, then it decreases the reference count
+ on its associated intern object and deletes it if nobody else hold references
+ on the intern object.
+*/
+
+
+/*
+ Helper to split a qualified name in the prefix and local name.
+*/
+static void qt_split_namespace( TQString& prefix, TQString& name, const TQString& qName, bool hasURI )
+{
+ int i = qName.tqfind( ':' );
+ if ( i == -1 ) {
+ if ( hasURI )
+ prefix = "";
+ else
+ prefix = TQString::null;
+ name = qName;
+ } else {
+ prefix = qName.left( i );
+ name = qName.mid( i + 1 );
+ }
+}
+
+/*
+ Counter for the TQDomNodeListPrivate timestamps.
+*/
+static volatile long qt_nodeListTime = 0;
+
+/**************************************************************
+ *
+ * Private class declerations
+ *
+ **************************************************************/
+
+class TQDomImplementationPrivate : public TQShared
+{
+public:
+ TQDomImplementationPrivate();
+ ~TQDomImplementationPrivate();
+
+ TQDomImplementationPrivate* clone();
+
+};
+
+class TQDomNodePrivate : public TQShared
+{
+public:
+ TQDomNodePrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent = 0 );
+ TQDomNodePrivate( TQDomNodePrivate* n, bool deep );
+ virtual ~TQDomNodePrivate();
+
+ TQString nodeName() const { return name; }
+ TQString nodeValue() const { return value; }
+ virtual void setNodeValue( const TQString& v ) { value = v; }
+
+ TQDomDocumentPrivate* ownerDocument();
+ void setOwnerDocument( TQDomDocumentPrivate* doc );
+
+ virtual TQDomNamedNodeMapPrivate* attributes();
+ virtual bool hasAttributes() { return FALSE; }
+ virtual TQDomNodePrivate* insertBefore( TQDomNodePrivate* newChild, TQDomNodePrivate* refChild );
+ virtual TQDomNodePrivate* insertAfter( TQDomNodePrivate* newChild, TQDomNodePrivate* refChild );
+ virtual TQDomNodePrivate* tqreplaceChild( TQDomNodePrivate* newChild, TQDomNodePrivate* oldChild );
+ virtual TQDomNodePrivate* removeChild( TQDomNodePrivate* oldChild );
+ virtual TQDomNodePrivate* appendChild( TQDomNodePrivate* newChild );
+
+ TQDomNodePrivate* namedItem( const TQString& name );
+
+ virtual TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ virtual void normalize();
+ virtual void clear();
+
+ TQDomNodePrivate* tqparent() { return hasParent ? ownerNode : 0; }
+ void setParent( TQDomNodePrivate *p ) { ownerNode = p; hasParent = TRUE; }
+ void setNoParent() {
+ ownerNode = hasParent ? (TQDomNodePrivate*)ownerDocument() : 0;
+ hasParent = FALSE;
+ }
+
+ // Dynamic cast
+ virtual bool isAttr() { return FALSE; }
+ virtual bool isCDATASection() { return FALSE; }
+ virtual bool isDocumentFragment() { return FALSE; }
+ virtual bool isDocument() { return FALSE; }
+ virtual bool isDocumentType() { return FALSE; }
+ virtual bool isElement() { return FALSE; }
+ virtual bool isEntityReference() { return FALSE; }
+ virtual bool isText() { return FALSE; }
+ virtual bool isEntity() { return FALSE; }
+ virtual bool isNotation() { return FALSE; }
+ virtual bool isProcessingInstruction() { return FALSE; }
+ virtual bool isCharacterData() { return FALSE; }
+ virtual bool isComment() { return FALSE; }
+ virtual TQDomNode::NodeType nodeType() const { return TQDomNode::BaseNode; }
+
+ virtual void save( TQTextStream&, int, int ) const;
+
+ // Variables
+ TQDomNodePrivate* prev;
+ TQDomNodePrivate* next;
+ TQDomNodePrivate* ownerNode; // either the node's tqparent or the node's owner document
+ TQDomNodePrivate* first;
+ TQDomNodePrivate* last;
+
+ TQString name; // this is the local name if prefix != null
+ TQString value;
+ TQString prefix; // set this only for ElementNode and AttributeNode
+ TQString namespaceURI; // set this only for ElementNode and AttributeNode
+ bool createdWithDom1Interface;
+ bool hasParent;
+};
+
+class TQDomNodeListPrivate : public TQShared
+{
+public:
+ TQDomNodeListPrivate( TQDomNodePrivate* );
+ TQDomNodeListPrivate( TQDomNodePrivate*, const TQString& );
+ TQDomNodeListPrivate( TQDomNodePrivate*, const TQString&, const TQString& );
+ virtual ~TQDomNodeListPrivate();
+
+ virtual bool operator== ( const TQDomNodeListPrivate& ) const;
+ virtual bool operator!= ( const TQDomNodeListPrivate& ) const;
+
+ void createList();
+ virtual TQDomNodePrivate* item( int index );
+ virtual uint length() const;
+
+ TQDomNodePrivate* node_impl;
+ TQString tagname;
+ TQString nsURI;
+ TQPtrList<TQDomNodePrivate> list;
+ long timestamp;
+};
+
+class TQDomNamedNodeMapPrivate : public TQShared
+{
+public:
+ TQDomNamedNodeMapPrivate( TQDomNodePrivate* );
+ ~TQDomNamedNodeMapPrivate();
+
+ TQDomNodePrivate* namedItem( const TQString& name ) const;
+ TQDomNodePrivate* namedItemNS( const TQString& nsURI, const TQString& localName ) const;
+ TQDomNodePrivate* setNamedItem( TQDomNodePrivate* arg );
+ TQDomNodePrivate* setNamedItemNS( TQDomNodePrivate* arg );
+ TQDomNodePrivate* removeNamedItem( const TQString& name );
+ TQDomNodePrivate* item( int index ) const;
+ uint length() const;
+ bool tqcontains( const TQString& name ) const;
+ bool tqcontainsNS( const TQString& nsURI, const TQString & localName ) const;
+
+ /**
+ * Remove all tqchildren from the map.
+ */
+ void clearMap();
+ bool isReadOnly() { return readonly; }
+ void setReadOnly( bool r ) { readonly = r; }
+ bool isAppendToParent() { return appendToParent; }
+ /**
+ * If TRUE, then the node will redirect insert/remove calls
+ * to its tqparent by calling TQDomNodePrivate::appendChild or removeChild.
+ * In addition the map wont increase or decrease the reference count
+ * of the nodes it tqcontains.
+ *
+ * By default this value is FALSE and the map will handle reference counting
+ * by itself.
+ */
+ void setAppendToParent( bool b ) { appendToParent = b; }
+
+ /**
+ * Creates a copy of the map. It is a deep copy
+ * that means that all tqchildren are cloned.
+ */
+ TQDomNamedNodeMapPrivate* clone( TQDomNodePrivate* tqparent );
+
+ // Variables
+ TQDict<TQDomNodePrivate> map;
+ TQDomNodePrivate* tqparent;
+ bool readonly;
+ bool appendToParent;
+};
+
+class TQDomDocumentTypePrivate : public TQDomNodePrivate
+{
+public:
+ TQDomDocumentTypePrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent = 0 );
+ TQDomDocumentTypePrivate( TQDomDocumentTypePrivate* n, bool deep );
+ ~TQDomDocumentTypePrivate();
+ void init();
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ TQDomNodePrivate* insertBefore( TQDomNodePrivate* newChild, TQDomNodePrivate* refChild );
+ TQDomNodePrivate* insertAfter( TQDomNodePrivate* newChild, TQDomNodePrivate* refChild );
+ TQDomNodePrivate* tqreplaceChild( TQDomNodePrivate* newChild, TQDomNodePrivate* oldChild );
+ TQDomNodePrivate* removeChild( TQDomNodePrivate* oldChild );
+ TQDomNodePrivate* appendChild( TQDomNodePrivate* newChild );
+
+ bool isDocumentType() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::DocumentTypeNode; }
+
+ void save( TQTextStream& s, int, int ) const;
+
+ // Variables
+ TQDomNamedNodeMapPrivate* entities;
+ TQDomNamedNodeMapPrivate* notations;
+ TQString publicId;
+ TQString systemId;
+ TQString internalSubset;
+};
+
+class TQDomDocumentFragmentPrivate : public TQDomNodePrivate
+{
+public:
+ TQDomDocumentFragmentPrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent = 0 );
+ TQDomDocumentFragmentPrivate( TQDomNodePrivate* n, bool deep );
+ ~TQDomDocumentFragmentPrivate();
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ bool isDocumentFragment() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::DocumentFragmentNode; }
+};
+
+class TQDomCharacterDataPrivate : public TQDomNodePrivate
+{
+public:
+ TQDomCharacterDataPrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent, const TQString& data );
+ TQDomCharacterDataPrivate( TQDomCharacterDataPrivate* n, bool deep );
+ ~TQDomCharacterDataPrivate();
+
+ uint dataLength() const;
+ TQString substringData( unsigned long offset, unsigned long count ) const;
+ void appendData( const TQString& arg );
+ void insertData( unsigned long offset, const TQString& arg );
+ void deleteData( unsigned long offset, unsigned long count );
+ void tqreplaceData( unsigned long offset, unsigned long count, const TQString& arg );
+
+ // Reimplemented from TQDomNodePrivate
+ bool isCharacterData() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::CharacterDataNode; }
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+
+};
+
+class TQDomTextPrivate : public TQDomCharacterDataPrivate
+{
+public:
+ TQDomTextPrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent, const TQString& value );
+ TQDomTextPrivate( TQDomTextPrivate* n, bool deep );
+ ~TQDomTextPrivate();
+
+ TQDomTextPrivate* splitText( int offset );
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ bool isText() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::TextNode; }
+ void save( TQTextStream& s, int, int ) const;
+
+};
+
+class TQDomAttrPrivate : public TQDomNodePrivate
+{
+public:
+ TQDomAttrPrivate( TQDomDocumentPrivate*, TQDomNodePrivate*, const TQString& name );
+ TQDomAttrPrivate( TQDomDocumentPrivate*, TQDomNodePrivate*, const TQString& nsURI, const TQString& qName );
+ TQDomAttrPrivate( TQDomAttrPrivate* n, bool deep );
+ ~TQDomAttrPrivate();
+
+ bool specified() const;
+
+ // Reimplemented from TQDomNodePrivate
+ void setNodeValue( const TQString& v );
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ bool isAttr() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::AttributeNode; }
+ void save( TQTextStream& s, int, int ) const;
+
+ // Variables
+ bool m_specified;
+};
+
+class TQDomElementPrivate : public TQDomNodePrivate
+{
+public:
+ TQDomElementPrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent, const TQString& name );
+ TQDomElementPrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent, const TQString& nsURI, const TQString& qName );
+ TQDomElementPrivate( TQDomElementPrivate* n, bool deep );
+ ~TQDomElementPrivate();
+
+ TQString attribute( const TQString& name, const TQString& defValue ) const;
+ TQString attributeNS( const TQString& nsURI, const TQString& localName, const TQString& defValue ) const;
+ void setAttribute( const TQString& name, const TQString& value );
+ void setAttributeNS( const TQString& nsURI, const TQString& qName, const TQString& newValue );
+ void removeAttribute( const TQString& name );
+ TQDomAttrPrivate* attributeNode( const TQString& name);
+ TQDomAttrPrivate* attributeNodeNS( const TQString& nsURI, const TQString& localName );
+ TQDomAttrPrivate* setAttributeNode( TQDomAttrPrivate* newAttr );
+ TQDomAttrPrivate* setAttributeNodeNS( TQDomAttrPrivate* newAttr );
+ TQDomAttrPrivate* removeAttributeNode( TQDomAttrPrivate* oldAttr );
+ bool hasAttribute( const TQString& name );
+ bool hasAttributeNS( const TQString& nsURI, const TQString& localName );
+
+ TQString text();
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNamedNodeMapPrivate* attributes() { return m_attr; }
+ bool hasAttributes() { return ( m_attr->length() > 0 ); }
+ bool isElement() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::ElementNode; }
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ void save( TQTextStream& s, int, int ) const;
+
+ // Variables
+ TQDomNamedNodeMapPrivate* m_attr;
+};
+
+
+class TQDomCommentPrivate : public TQDomCharacterDataPrivate
+{
+public:
+ TQDomCommentPrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent, const TQString& value );
+ TQDomCommentPrivate( TQDomCommentPrivate* n, bool deep );
+ ~TQDomCommentPrivate();
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ bool isComment() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::CommentNode; }
+ void save( TQTextStream& s, int, int ) const;
+
+};
+
+class TQDomCDATASectionPrivate : public TQDomTextPrivate
+{
+public:
+ TQDomCDATASectionPrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent, const TQString& value );
+ TQDomCDATASectionPrivate( TQDomCDATASectionPrivate* n, bool deep );
+ ~TQDomCDATASectionPrivate();
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ bool isCDATASection() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::CDATASectionNode; }
+ void save( TQTextStream& s, int, int ) const;
+
+};
+
+class TQDomNotationPrivate : public TQDomNodePrivate
+{
+public:
+ TQDomNotationPrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent, const TQString& name,
+ const TQString& pub, const TQString& sys );
+ TQDomNotationPrivate( TQDomNotationPrivate* n, bool deep );
+ ~TQDomNotationPrivate();
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ bool isNotation() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::NotationNode; }
+ void save( TQTextStream& s, int, int ) const;
+
+ // Variables
+ TQString m_sys;
+ TQString m_pub;
+};
+
+class TQDomEntityPrivate : public TQDomNodePrivate
+{
+public:
+ TQDomEntityPrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent, const TQString& name,
+ const TQString& pub, const TQString& sys, const TQString& notation );
+ TQDomEntityPrivate( TQDomEntityPrivate* n, bool deep );
+ ~TQDomEntityPrivate();
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ bool isEntity() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::EntityNode; }
+ void save( TQTextStream& s, int, int ) const;
+
+ // Variables
+ TQString m_sys;
+ TQString m_pub;
+ TQString m_notationName;
+};
+
+class TQDomEntityReferencePrivate : public TQDomNodePrivate
+{
+public:
+ TQDomEntityReferencePrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent, const TQString& name );
+ TQDomEntityReferencePrivate( TQDomNodePrivate* n, bool deep );
+ ~TQDomEntityReferencePrivate();
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ bool isEntityReference() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::EntityReferenceNode; }
+ void save( TQTextStream& s, int, int ) const;
+};
+
+class TQDomProcessingInstructionPrivate : public TQDomNodePrivate
+{
+public:
+ TQDomProcessingInstructionPrivate( TQDomDocumentPrivate*, TQDomNodePrivate* tqparent, const TQString& target,
+ const TQString& data);
+ TQDomProcessingInstructionPrivate( TQDomProcessingInstructionPrivate* n, bool deep );
+ ~TQDomProcessingInstructionPrivate();
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ bool isProcessingInstruction() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::ProcessingInstructionNode; }
+ void save( TQTextStream& s, int, int ) const;
+};
+
+class TQDomDocumentPrivate : public TQDomNodePrivate
+{
+public:
+ TQDomDocumentPrivate();
+ TQDomDocumentPrivate( const TQString& name );
+ TQDomDocumentPrivate( TQDomDocumentTypePrivate* dt );
+ TQDomDocumentPrivate( TQDomDocumentPrivate* n, bool deep );
+ ~TQDomDocumentPrivate();
+
+ bool setContent( TQXmlInputSource *source, bool namespaceProcessing, TQString *errorMsg, int *errorLine, int *errorColumn );
+ bool setContent( TQXmlInputSource *source, TQXmlReader *reader, TQString *errorMsg, int *errorLine, int *errorColumn );
+
+ // Attributes
+ TQDomDocumentTypePrivate* doctype() { return type; };
+ TQDomImplementationPrivate* implementation() { return impl; };
+ TQDomElementPrivate* documentElement();
+
+ // Factories
+ TQDomElementPrivate* createElement( const TQString& tagName );
+ TQDomElementPrivate* createElementNS( const TQString& nsURI, const TQString& qName );
+ TQDomDocumentFragmentPrivate* createDocumentFragment();
+ TQDomTextPrivate* createTextNode( const TQString& data );
+ TQDomCommentPrivate* createComment( const TQString& data );
+ TQDomCDATASectionPrivate* createCDATASection( const TQString& data );
+ TQDomProcessingInstructionPrivate* createProcessingInstruction( const TQString& target, const TQString& data );
+ TQDomAttrPrivate* createAttribute( const TQString& name );
+ TQDomAttrPrivate* createAttributeNS( const TQString& nsURI, const TQString& qName );
+ TQDomEntityReferencePrivate* createEntityReference( const TQString& name );
+
+ TQDomNodePrivate* importNode( const TQDomNodePrivate* importedNode, bool deep );
+
+ // Reimplemented from TQDomNodePrivate
+ TQDomNodePrivate* cloneNode( bool deep = TRUE );
+ bool isDocument() { return TRUE; }
+ TQDomNode::NodeType nodeType() const { return TQDomNode::DocumentNode; }
+ void clear();
+ void save( TQTextStream&, int, int ) const;
+
+ // Variables
+ TQDomImplementationPrivate* impl;
+ TQDomDocumentTypePrivate* type;
+};
+
+/**************************************************************
+ *
+ * TQDomHandler
+ *
+ **************************************************************/
+
+class TQDomHandler : public TQXmlDefaultHandler
+{
+public:
+ TQDomHandler( TQDomDocumentPrivate* d, bool namespaceProcessing );
+ ~TQDomHandler();
+
+ // content handler
+ bool endDocument();
+ bool startElement( const TQString& nsURI, const TQString& localName, const TQString& qName, const TQXmlAttributes& atts );
+ bool endElement( const TQString& nsURI, const TQString& localName, const TQString& qName );
+ bool characters( const TQString& ch );
+ bool processingInstruction( const TQString& target, const TQString& data );
+ bool skippedEntity( const TQString& name );
+
+ // error handler
+ bool fatalError( const TQXmlParseException& exception );
+
+ // lexical handler
+ bool startCDATA();
+ bool endCDATA();
+ bool startEntity( const TQString & );
+ bool endEntity( const TQString & );
+ bool startDTD( const TQString& name, const TQString& publicId, const TQString& systemId );
+ bool comment( const TQString& ch );
+
+ // decl handler
+ bool externalEntityDecl( const TQString &name, const TQString &publicId, const TQString &systemId ) ;
+
+ // DTD handler
+ bool notationDecl( const TQString & name, const TQString & publicId, const TQString & systemId );
+ bool unparsedEntityDecl( const TQString &name, const TQString &publicId, const TQString &systemId, const TQString &notationName ) ;
+
+ TQString errorMsg;
+ int errorLine;
+ int errorColumn;
+
+private:
+ TQDomDocumentPrivate *doc;
+ TQDomNodePrivate *node;
+ TQString entityName;
+ bool cdata;
+ bool nsProcessing;
+};
+
+/**************************************************************
+ *
+ * TQDomImplementationPrivate
+ *
+ **************************************************************/
+
+TQDomImplementationPrivate::TQDomImplementationPrivate()
+{
+}
+
+TQDomImplementationPrivate::~TQDomImplementationPrivate()
+{
+}
+
+TQDomImplementationPrivate* TQDomImplementationPrivate::clone()
+{
+ TQDomImplementationPrivate* p = new TQDomImplementationPrivate;
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+/**************************************************************
+ *
+ * TQDomImplementation
+ *
+ **************************************************************/
+
+/*!
+ \class TQDomImplementation tqdom.h
+ \reentrant
+ \brief The TQDomImplementation class provides information about the
+ features of the DOM implementation.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ This class describes the features that are supported by the DOM
+ implementation. Currently the XML subset of DOM Level 1 and DOM
+ Level 2 Core are supported.
+
+ Normally you will use the function TQDomDocument::implementation()
+ to get the implementation object.
+
+ You can create a new document type with createDocumentType() and a
+ new document with createDocument().
+
+ For further information about the Document Object Model see \link
+ http://www.w3.org/TR/REC-DOM-Level-1/\endlink and \link
+ http://www.w3.org/TR/DOM-Level-2-Core/\endlink. For a more general
+ introduction of the DOM implementation see the TQDomDocument
+ documentation.
+
+ \sa hasFeature()
+*/
+
+/*!
+ Constructs a TQDomImplementation object.
+*/
+TQDomImplementation::TQDomImplementation()
+{
+ impl = 0;
+}
+
+/*!
+ Constructs a copy of \a x.
+*/
+TQDomImplementation::TQDomImplementation( const TQDomImplementation& x )
+{
+ impl = x.impl;
+ if ( impl )
+ impl->ref();
+}
+
+TQDomImplementation::TQDomImplementation( TQDomImplementationPrivate* p )
+{
+ // We want to be co-owners, so increase the reference count
+ impl = p;
+ if (impl)
+ impl->ref();
+}
+
+/*!
+ Assigns \a x to this DOM implementation.
+*/
+TQDomImplementation& TQDomImplementation::operator= ( const TQDomImplementation& x )
+{
+ if ( x.impl )
+ x.impl->ref(); // avoid x=x
+ if ( impl && impl->deref() )
+ delete impl;
+ impl = x.impl;
+
+ return *this;
+}
+
+/*!
+ Returns TRUE if \a x and this DOM implementation object were
+ created from the same TQDomDocument; otherwise returns FALSE.
+*/
+bool TQDomImplementation::operator==( const TQDomImplementation& x ) const
+{
+ return ( impl == x.impl );
+}
+
+/*!
+ Returns TRUE if \a x and this DOM implementation object were
+ created from different TQDomDocuments; otherwise returns FALSE.
+*/
+bool TQDomImplementation::operator!=( const TQDomImplementation& x ) const
+{
+ return ( impl != x.impl );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomImplementation::~TQDomImplementation()
+{
+ if ( impl && impl->deref() )
+ delete impl;
+}
+
+/*!
+ The function returns TRUE if TQDom implements the requested \a
+ version of a \a feature; otherwise returns FALSE.
+
+ The currently supported features and their versions:
+ \table
+ \header \i Feature \i Version
+ \row \i XML \i 1.0
+ \endtable
+*/
+bool TQDomImplementation::hasFeature( const TQString& feature, const TQString& version )
+{
+ if ( feature == "XML" ) {
+ if ( version.isEmpty() || version == "1.0" ) {
+ return TRUE;
+ }
+ }
+ // ### add DOM level 2 features
+ return FALSE;
+}
+
+/*!
+ Creates a document type node for the name \a qName.
+
+ \a publicId specifies the public identifier of the external
+ subset. If you specify TQString::null as the \a publicId, this
+ means that the document type has no public identifier.
+
+ \a systemId specifies the system identifier of the external
+ subset. If you specify TQString::null as the \a systemId, this
+ means that the document type has no system identifier.
+
+ Since you cannot have a public identifier without a system
+ identifier, the public identifier is set to TQString::null if there
+ is no system identifier.
+
+ DOM level 2 does not support any other document type declaration
+ features.
+
+ The only way you can use a document type that was created this
+ way, is in combination with the createDocument() function to
+ create a TQDomDocument with this document type.
+
+ \sa createDocument();
+*/
+TQDomDocumentType TQDomImplementation::createDocumentType( const TQString& qName, const TQString& publicId, const TQString& systemId )
+{
+ TQDomDocumentTypePrivate *dt = new TQDomDocumentTypePrivate( 0 );
+ dt->name = qName;
+ if ( systemId.isNull() ) {
+ dt->publicId = TQString::null;
+ dt->systemId = TQString::null;
+ } else {
+ dt->publicId = publicId;
+ dt->systemId = systemId;
+ }
+ return TQDomDocumentType( dt );
+}
+
+/*!
+ Creates a DOM document with the document type \a doctype. This
+ function also adds a root element node with the qualified name \a
+ qName and the namespace URI \a nsURI.
+*/
+TQDomDocument TQDomImplementation::createDocument( const TQString& nsURI, const TQString& qName, const TQDomDocumentType& doctype )
+{
+ TQDomDocument doc( doctype );
+ TQDomElement root = doc.createElementNS( nsURI, qName );
+ doc.appendChild( root );
+ return doc;
+}
+
+/*!
+ Returns FALSE if the object was created by
+ TQDomDocument::implementation(); otherwise returns TRUE.
+*/
+bool TQDomImplementation::isNull()
+{
+ return ( impl == 0 );
+}
+
+/**************************************************************
+ *
+ * TQDomNodeListPrivate
+ *
+ **************************************************************/
+
+TQDomNodeListPrivate::TQDomNodeListPrivate( TQDomNodePrivate* n_impl )
+{
+ node_impl = n_impl;
+ if ( node_impl )
+ node_impl->ref();
+ timestamp = -1;
+}
+
+TQDomNodeListPrivate::TQDomNodeListPrivate( TQDomNodePrivate* n_impl, const TQString& name )
+{
+ node_impl = n_impl;
+ if ( node_impl )
+ node_impl->ref();
+ tagname = name;
+ timestamp = -1;
+}
+
+TQDomNodeListPrivate::TQDomNodeListPrivate( TQDomNodePrivate* n_impl, const TQString& _nsURI, const TQString& localName )
+{
+ node_impl = n_impl;
+ if ( node_impl )
+ node_impl->ref();
+ tagname = localName;
+ nsURI = _nsURI;
+ timestamp = -1;
+}
+
+TQDomNodeListPrivate::~TQDomNodeListPrivate()
+{
+ if ( node_impl && node_impl->deref() )
+ delete node_impl;
+}
+
+bool TQDomNodeListPrivate::operator== ( const TQDomNodeListPrivate& other ) const
+{
+ return ( node_impl == other.node_impl ) && ( tagname == other.tagname ) ;
+}
+
+bool TQDomNodeListPrivate::operator!= ( const TQDomNodeListPrivate& other ) const
+{
+ return ( node_impl != other.node_impl ) || ( tagname != other.tagname ) ;
+}
+
+void TQDomNodeListPrivate::createList()
+{
+ if ( !node_impl )
+ return;
+ timestamp = qt_nodeListTime;
+ TQDomNodePrivate* p = node_impl->first;
+
+ list.clear();
+ if ( tagname.isNull() ) {
+ while ( p ) {
+ list.append( p );
+ p = p->next;
+ }
+ } else if ( nsURI.isNull() ) {
+ while ( p && p != node_impl ) {
+ if ( p->isElement() && p->nodeName() == tagname ) {
+ list.append( p );
+ }
+ if ( p->first )
+ p = p->first;
+ else if ( p->next )
+ p = p->next;
+ else {
+ p = p->tqparent();
+ while ( p && p != node_impl && !p->next )
+ p = p->tqparent();
+ if ( p && p != node_impl )
+ p = p->next;
+ }
+ }
+ } else {
+ while ( p && p != node_impl ) {
+ if ( p->isElement() && p->name==tagname && p->namespaceURI==nsURI ) {
+ list.append( p );
+ }
+ if ( p->first )
+ p = p->first;
+ else if ( p->next )
+ p = p->next;
+ else {
+ p = p->tqparent();
+ while ( p && p != node_impl && !p->next )
+ p = p->tqparent();
+ if ( p && p != node_impl )
+ p = p->next;
+ }
+ }
+ }
+}
+
+TQDomNodePrivate* TQDomNodeListPrivate::item( int index )
+{
+ if ( !node_impl )
+ return 0;
+ if ( timestamp < qt_nodeListTime )
+ createList();
+ return list.at( index );
+}
+
+uint TQDomNodeListPrivate::length() const
+{
+ if ( !node_impl )
+ return 0;
+ if ( timestamp < qt_nodeListTime ) {
+ TQDomNodeListPrivate *that = (TQDomNodeListPrivate*)this;
+ that->createList();
+ }
+ return list.count();
+}
+
+/**************************************************************
+ *
+ * TQDomNodeList
+ *
+ **************************************************************/
+
+/*!
+ \class TQDomNodeList tqdom.h
+ \reentrant
+ \brief The TQDomNodeList class is a list of TQDomNode objects.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ Lists can be obtained by TQDomDocument::elementsByTagName() and
+ TQDomNode::childNodes(). The Document Object Model (DOM) requires
+ these lists to be "live": whenever you change the underlying
+ document, the contents of the list will get updated.
+
+ You can get a particular node from the list with item(). The
+ number of items in the list is returned by count() (and by
+ length()).
+
+ For further information about the Document Object Model see \link
+ http://www.w3.org/TR/REC-DOM-Level-1/\endlink and \link
+ http://www.w3.org/TR/DOM-Level-2-Core/\endlink. For a more general
+ introduction of the DOM implementation see the TQDomDocument
+ documentation.
+
+ \sa TQDomNode::childNodes() TQDomDocument::elementsByTagName()
+*/
+
+/*!
+ Creates an empty node list.
+*/
+TQDomNodeList::TQDomNodeList()
+{
+ impl = 0;
+}
+
+TQDomNodeList::TQDomNodeList( TQDomNodeListPrivate* p )
+{
+ impl = p;
+}
+
+/*!
+ Constructs a copy of \a n.
+*/
+TQDomNodeList::TQDomNodeList( const TQDomNodeList& n )
+{
+ impl = n.impl;
+ if ( impl )
+ impl->ref();
+}
+
+/*!
+ Assigns \a n to this node list.
+*/
+TQDomNodeList& TQDomNodeList::operator= ( const TQDomNodeList& n )
+{
+ if ( n.impl )
+ n.impl->ref();
+ if ( impl && impl->deref() )
+ delete impl;
+ impl = n.impl;
+
+ return *this;
+}
+
+/*!
+ Returns TRUE if the node list \a n and this node list are equal;
+ otherwise returns FALSE.
+*/
+bool TQDomNodeList::operator== ( const TQDomNodeList& n ) const
+{
+ if ( impl == n.impl )
+ return TRUE;
+ if ( !impl || !n.impl )
+ return FALSE;
+ return (*impl == *n.impl);
+}
+
+/*!
+ Returns TRUE the node list \a n and this node list are not equal;
+ otherwise returns FALSE.
+*/
+bool TQDomNodeList::operator!= ( const TQDomNodeList& n ) const
+{
+ return !operator==(n);
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomNodeList::~TQDomNodeList()
+{
+ if ( impl && impl->deref() )
+ delete impl;
+}
+
+/*!
+ Returns the node at position \a index.
+
+ If \a index is negative or if \a index >= length() then a null
+ node is returned (i.e. a node for which TQDomNode::isNull() returns
+ TRUE).
+
+ \sa count()
+*/
+TQDomNode TQDomNodeList::item( int index ) const
+{
+ if ( !impl )
+ return TQDomNode();
+
+ return TQDomNode( impl->item( index ) );
+}
+
+/*!
+ Returns the number of nodes in the list.
+
+ This function is the same as count().
+*/
+uint TQDomNodeList::length() const
+{
+ if ( !impl )
+ return 0;
+ return impl->length();
+}
+
+/*!
+ \fn uint TQDomNodeList::count() const
+
+ Returns the number of nodes in the list.
+
+ This function is the same as length().
+*/
+
+
+/**************************************************************
+ *
+ * TQDomNodePrivate
+ *
+ **************************************************************/
+
+inline void TQDomNodePrivate::setOwnerDocument( TQDomDocumentPrivate* doc )
+{
+ ownerNode = doc;
+ hasParent = FALSE;
+}
+
+TQDomNodePrivate::TQDomNodePrivate( TQDomDocumentPrivate* doc, TQDomNodePrivate *par )
+{
+ if ( par )
+ setParent( par );
+ else
+ setOwnerDocument( doc );
+ prev = 0;
+ next = 0;
+ first = 0;
+ last = 0;
+ createdWithDom1Interface = TRUE;
+}
+
+TQDomNodePrivate::TQDomNodePrivate( TQDomNodePrivate* n, bool deep )
+{
+ setOwnerDocument( n->ownerDocument() );
+ prev = 0;
+ next = 0;
+ first = 0;
+ last = 0;
+
+ name = n->name;
+ value = n->value;
+ prefix = n->prefix;
+ namespaceURI = n->namespaceURI;
+ createdWithDom1Interface = n->createdWithDom1Interface;
+
+ if ( !deep )
+ return;
+
+ for ( TQDomNodePrivate* x = n->first; x; x = x->next )
+ appendChild( x->cloneNode( TRUE ) );
+}
+
+TQDomNodePrivate::~TQDomNodePrivate()
+{
+ TQDomNodePrivate* p = first;
+ TQDomNodePrivate* n;
+
+ while ( p ) {
+ n = p->next;
+ if ( p->deref() )
+ delete p;
+ else
+ p->setNoParent();
+ p = n;
+ }
+
+ first = 0;
+ last = 0;
+}
+
+void TQDomNodePrivate::clear()
+{
+ TQDomNodePrivate* p = first;
+ TQDomNodePrivate* n;
+
+ while ( p ) {
+ n = p->next;
+ if ( p->deref() )
+ delete p;
+ p = n;
+ }
+
+ first = 0;
+ last = 0;
+}
+
+TQDomNodePrivate* TQDomNodePrivate::namedItem( const TQString& n )
+{
+ TQDomNodePrivate* p = first;
+ while ( p ) {
+ if ( p->nodeName() == n )
+ return p;
+ p = p->next;
+ }
+
+ return 0;
+}
+
+TQDomNamedNodeMapPrivate* TQDomNodePrivate::attributes()
+{
+ return 0;
+}
+
+TQDomNodePrivate* TQDomNodePrivate::insertBefore( TQDomNodePrivate* newChild, TQDomNodePrivate* refChild )
+{
+ // Error check
+ if ( !newChild )
+ return 0;
+
+ // Error check
+ if ( newChild == refChild )
+ return 0;
+
+ // Error check
+ if ( refChild && refChild->tqparent() != this )
+ return 0;
+
+ // "mark lists as dirty"
+ qt_nodeListTime++;
+
+ // Special handling for inserting a fragment. We just insert
+ // all elements of the fragment instead of the fragment itself.
+ if ( newChild->isDocumentFragment() ) {
+ // Fragment is empty ?
+ if ( newChild->first == 0 )
+ return newChild;
+
+ // New tqparent
+ TQDomNodePrivate* n = newChild->first;
+ while ( n ) {
+ n->setParent( this );
+ n = n->next;
+ }
+
+ // Insert at the beginning ?
+ if ( !refChild || refChild->prev == 0 ) {
+ if ( first )
+ first->prev = newChild->last;
+ newChild->last->next = first;
+ if ( !last )
+ last = newChild->last;
+ first = newChild->first;
+ } else {
+ // Insert in the middle
+ newChild->last->next = refChild;
+ newChild->first->prev = refChild->prev;
+ refChild->prev->next = newChild->first;
+ refChild->prev = newChild->last;
+ }
+
+ // No need to increase the reference since TQDomDocumentFragment
+ // does not decrease the reference.
+
+ // Remove the nodes from the fragment
+ newChild->first = 0;
+ newChild->last = 0;
+ return newChild;
+ }
+
+ // No more errors can occur now, so we take
+ // ownership of the node.
+ newChild->ref();
+
+ if ( newChild->tqparent() )
+ newChild->tqparent()->removeChild( newChild );
+
+ newChild->setParent( this );
+
+ if ( !refChild ) {
+ if ( first )
+ first->prev = newChild;
+ newChild->next = first;
+ if ( !last )
+ last = newChild;
+ first = newChild;
+ return newChild;
+ }
+
+ if ( refChild->prev == 0 ) {
+ if ( first )
+ first->prev = newChild;
+ newChild->next = first;
+ if ( !last )
+ last = newChild;
+ first = newChild;
+ return newChild;
+ }
+
+ newChild->next = refChild;
+ newChild->prev = refChild->prev;
+ refChild->prev->next = newChild;
+ refChild->prev = newChild;
+
+ return newChild;
+}
+
+TQDomNodePrivate* TQDomNodePrivate::insertAfter( TQDomNodePrivate* newChild, TQDomNodePrivate* refChild )
+{
+ // Error check
+ if ( !newChild )
+ return 0;
+
+ // Error check
+ if ( newChild == refChild )
+ return 0;
+
+ // Error check
+ if ( refChild && refChild->tqparent() != this )
+ return 0;
+
+ // "mark lists as dirty"
+ qt_nodeListTime++;
+
+ // Special handling for inserting a fragment. We just insert
+ // all elements of the fragment instead of the fragment itself.
+ if ( newChild->isDocumentFragment() ) {
+ // Fragment is empty ?
+ if ( newChild->first == 0 )
+ return newChild;
+
+ // New tqparent
+ TQDomNodePrivate* n = newChild->first;
+ while ( n ) {
+ n->setParent( this );
+ n = n->next;
+ }
+
+ // Insert at the end
+ if ( !refChild || refChild->next == 0 ) {
+ if ( last )
+ last->next = newChild->first;
+ newChild->first->prev = last;
+ if ( !first )
+ first = newChild->first;
+ last = newChild->last;
+ } else { // Insert in the middle
+ newChild->first->prev = refChild;
+ newChild->last->next = refChild->next;
+ refChild->next->prev = newChild->last;
+ refChild->next = newChild->first;
+ }
+
+ // No need to increase the reference since TQDomDocumentFragment
+ // does not decrease the reference.
+
+ // Remove the nodes from the fragment
+ newChild->first = 0;
+ newChild->last = 0;
+ return newChild;
+ }
+
+ // Release new node from its current tqparent
+ if ( newChild->tqparent() )
+ newChild->tqparent()->removeChild( newChild );
+
+ // No more errors can occur now, so we take
+ // ownership of the node
+ newChild->ref();
+
+ newChild->setParent( this );
+
+ // Insert at the end
+ if ( !refChild ) {
+ if ( last )
+ last->next = newChild;
+ newChild->prev = last;
+ if ( !first )
+ first = newChild;
+ last = newChild;
+ return newChild;
+ }
+
+ if ( refChild->next == 0 ) {
+ if ( last )
+ last->next = newChild;
+ newChild->prev = last;
+ if ( !first )
+ first = newChild;
+ last = newChild;
+ return newChild;
+ }
+
+ newChild->prev = refChild;
+ newChild->next = refChild->next;
+ refChild->next->prev = newChild;
+ refChild->next = newChild;
+
+ return newChild;
+}
+
+TQDomNodePrivate* TQDomNodePrivate::tqreplaceChild( TQDomNodePrivate* newChild, TQDomNodePrivate* oldChild )
+{
+ if ( oldChild->tqparent() != this )
+ return 0;
+ if ( !newChild || !oldChild )
+ return 0;
+ if ( newChild == oldChild )
+ return 0;
+
+ // mark lists as dirty
+ qt_nodeListTime++;
+
+ // Special handling for inserting a fragment. We just insert
+ // all elements of the fragment instead of the fragment itself.
+ if ( newChild->isDocumentFragment() ) {
+ // Fragment is empty ?
+ if ( newChild->first == 0 )
+ return newChild;
+
+ // New tqparent
+ TQDomNodePrivate* n = newChild->first;
+ while ( n ) {
+ n->setParent( this );
+ n = n->next;
+ }
+
+
+ if ( oldChild->next )
+ oldChild->next->prev = newChild->last;
+ if ( oldChild->prev )
+ oldChild->prev->next = newChild->first;
+
+ newChild->last->next = oldChild->next;
+ newChild->first->prev = oldChild->prev;
+
+ if ( first == oldChild )
+ first = newChild->first;
+ if ( last == oldChild )
+ last = newChild->last;
+
+ oldChild->setNoParent();
+ oldChild->next = 0;
+ oldChild->prev = 0;
+
+ // No need to increase the reference since TQDomDocumentFragment
+ // does not decrease the reference.
+
+ // Remove the nodes from the fragment
+ newChild->first = 0;
+ newChild->last = 0;
+
+ // We are no longer interested in the old node
+ if ( oldChild ) oldChild->deref();
+
+ return oldChild;
+ }
+
+ // No more errors can occur now, so we take
+ // ownership of the node
+ newChild->ref();
+
+ // Release new node from its current tqparent
+ if ( newChild->tqparent() )
+ newChild->tqparent()->removeChild( newChild );
+
+ newChild->setParent( this );
+
+ if ( oldChild->next )
+ oldChild->next->prev = newChild;
+ if ( oldChild->prev )
+ oldChild->prev->next = newChild;
+
+ newChild->next = oldChild->next;
+ newChild->prev = oldChild->prev;
+
+ if ( first == oldChild )
+ first = newChild;
+ if ( last == oldChild )
+ last = newChild;
+
+ oldChild->setNoParent();
+ oldChild->next = 0;
+ oldChild->prev = 0;
+
+ // We are no longer interested in the old node
+ if ( oldChild ) oldChild->deref();
+
+ return oldChild;
+}
+
+TQDomNodePrivate* TQDomNodePrivate::removeChild( TQDomNodePrivate* oldChild )
+{
+ // Error check
+ if ( oldChild->tqparent() != this )
+ return 0;
+
+ // "mark lists as dirty"
+ qt_nodeListTime++;
+
+ // Perhaps oldChild was just created with "createElement" or that. In this case
+ // its tqparent is TQDomDocument but it is not part of the documents child list.
+ if ( oldChild->next == 0 && oldChild->prev == 0 && first != oldChild )
+ return 0;
+
+ if ( oldChild->next )
+ oldChild->next->prev = oldChild->prev;
+ if ( oldChild->prev )
+ oldChild->prev->next = oldChild->next;
+
+ if ( last == oldChild )
+ last = oldChild->prev;
+ if ( first == oldChild )
+ first = oldChild->next;
+
+ oldChild->setNoParent();
+ oldChild->next = 0;
+ oldChild->prev = 0;
+
+ // We are no longer interested in the old node
+ if ( oldChild ) oldChild->deref();
+
+ return oldChild;
+}
+
+TQDomNodePrivate* TQDomNodePrivate::appendChild( TQDomNodePrivate* newChild )
+{
+ // No reference manipulation needed. Done in insertAfter.
+ return insertAfter( newChild, 0 );
+}
+
+TQDomDocumentPrivate* TQDomNodePrivate::ownerDocument()
+{
+ TQDomNodePrivate* p = this;
+ while ( p && !p->isDocument() ) {
+ if ( !p->hasParent )
+ return (TQDomDocumentPrivate*)p->ownerNode;
+ p = p->tqparent();
+ }
+
+ return (TQDomDocumentPrivate*)p;
+}
+
+TQDomNodePrivate* TQDomNodePrivate::cloneNode( bool deep )
+{
+ TQDomNodePrivate* p = new TQDomNodePrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+static void qNormalizeNode( TQDomNodePrivate* n )
+{
+ TQDomNodePrivate* p = n->first;
+ TQDomTextPrivate* t = 0;
+
+ while ( p ) {
+ if ( p->isText() ) {
+ if ( t ) {
+ TQDomNodePrivate* tmp = p->next;
+ t->appendData( p->nodeValue() );
+ n->removeChild( p );
+ p = tmp;
+ } else {
+ t = (TQDomTextPrivate*)p;
+ p = p->next;
+ }
+ } else {
+ p = p->next;
+ t = 0;
+ }
+ }
+}
+void TQDomNodePrivate::normalize()
+{
+ // ### This one has moved from TQDomElementPrivate to this position. It is
+ // not tested.
+ qNormalizeNode( this );
+}
+
+void TQDomNodePrivate::save( TQTextStream& s, int depth, int indent ) const
+{
+ const TQDomNodePrivate* n = first;
+ while ( n ) {
+ n->save( s, depth, indent );
+ n = n->next;
+ }
+}
+
+/**************************************************************
+ *
+ * TQDomNode
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomNodePrivate*)impl)
+
+/*!
+ \class TQDomNode tqdom.h
+ \reentrant
+ \brief The TQDomNode class is the base class for all the nodes in a DOM tree.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ Many functions in the DOM return a TQDomNode.
+
+ You can tqfind out the type of a node using isAttr(),
+ isCDATASection(), isDocumentFragment(), isDocument(),
+ isDocumentType(), isElement(), isEntityReference(), isText(),
+ isEntity(), isNotation(), isProcessingInstruction(),
+ isCharacterData() and isComment().
+
+ A TQDomNode can be converted into one of its subclasses using
+ toAttr(), toCDATASection(), toDocumentFragment(), toDocument(),
+ toDocumentType(), toElement(), toEntityReference(), toText(),
+ toEntity(), toNotation(), toProcessingInstruction(),
+ toCharacterData() or toComment(). You can convert a node to a null
+ node with clear().
+
+ Copies of the TQDomNode class share their data using explicit
+ sharing. This means that modifying one node will change all
+ copies. This is especially useful in combination with functions
+ which return a TQDomNode, e.g. firstChild(). You can make an
+ independent (deep) copy of the node with cloneNode().
+
+ Nodes are inserted with insertBefore(), insertAfter() or
+ appendChild(). You can tqreplace one node with another using
+ tqreplaceChild() and remove a node with removeChild().
+
+ To traverse nodes use firstChild() to get a node's first child (if
+ any), and nextSibling() to traverse. TQDomNode also provides
+ lastChild(), previousSibling() and parentNode(). To tqfind the first
+ child node with a particular node name use namedItem().
+
+ To tqfind out if a node has tqchildren use hasChildNodes() and to get
+ a list of all of a node's tqchildren use childNodes().
+
+ The node's name and value (the meaning of which varies depending
+ on its type) is returned by nodeName() and nodeValue()
+ respectively. The node's type is returned by nodeType(). The
+ node's value can be set with setNodeValue().
+
+ The document to which the node belongs is returned by
+ ownerDocument().
+
+ Adjacent TQDomText nodes can be merged into a single node with
+ normalize().
+
+ \l TQDomElement nodes have attributes which can be retrieved with
+ attributes().
+
+ TQDomElement and TQDomAttr nodes can have namespaces which can be
+ retrieved with namespaceURI(). Their local name is retrieved with
+ localName(), and their prefix with prefix(). The prefix can be set
+ with setPrefix().
+
+ You can write the XML representation of the node to a text stream
+ with save().
+
+ The following example looks for the first element in an XML document and
+ prints the names of all the elements that are its direct tqchildren.
+ \code
+ TQDomDocument d;
+ d.setContent( someXML );
+ TQDomNode n = d.firstChild();
+ while ( !n.isNull() ) {
+ if ( n.isElement() ) {
+ TQDomElement e = n.toElement();
+ cout << "Element name: " << e.tagName() << endl;
+ break;
+ }
+ n = n.nextSibling();
+ }
+ \endcode
+
+ For further information about the Document Object Model see \link
+ http://www.w3.org/TR/REC-DOM-Level-1/\endlink and \link
+ http://www.w3.org/TR/DOM-Level-2-Core/\endlink. For a more general
+ introduction of the DOM implementation see the TQDomDocument
+ documentation.
+*/
+
+/*!
+ Constructs a \link isNull() null\endlink node.
+*/
+TQDomNode::TQDomNode()
+{
+ impl = 0;
+}
+
+/*!
+ Constructs a copy of \a n.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomNode::TQDomNode( const TQDomNode& n )
+{
+ impl = n.impl;
+ if ( impl ) impl->ref();
+}
+
+/*! \internal
+ Constructs a new node for the data \a n.
+*/
+TQDomNode::TQDomNode( TQDomNodePrivate* n )
+{
+ impl = n;
+ if ( impl ) impl->ref();
+}
+
+/*!
+ Assigns a copy of \a n to this DOM node.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomNode& TQDomNode::operator= ( const TQDomNode& n )
+{
+ if ( n.impl ) n.impl->ref();
+ if ( impl && impl->deref() ) delete impl;
+ impl = n.impl;
+
+ return *this;
+}
+
+/*!
+ Returns TRUE if \a n and this DOM node are equal; otherwise
+ returns FALSE.
+*/
+bool TQDomNode::operator== ( const TQDomNode& n ) const
+{
+ return ( impl == n.impl );
+}
+
+/*!
+ Returns TRUE if \a n and this DOM node are not equal; otherwise
+ returns FALSE.
+*/
+bool TQDomNode::operator!= ( const TQDomNode& n ) const
+{
+ return ( impl != n.impl );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomNode::~TQDomNode()
+{
+ if ( impl && impl->deref() ) delete impl;
+}
+
+/*!
+ Returns the name of the node.
+
+ The meaning of the name depends on the subclass:
+ \table
+ \header \i Name \i Meaning
+ \row \i TQDomAttr \i The name of the attribute
+ \row \i TQDomCDATASection \i The string "#cdata-section"
+ \row \i TQDomComment \i The string "#comment"
+ \row \i TQDomDocument \i The string "#document"
+ \row \i TQDomDocumentFragment \i The string "#document-fragment"
+ \row \i TQDomDocumentType \i The name of the document type
+ \row \i TQDomElement \i The tag name
+ \row \i TQDomEntity \i The name of the entity
+ \row \i TQDomEntityReference \i The name of the referenced entity
+ \row \i TQDomNotation \i The name of the notation
+ \row \i TQDomProcessingInstruction \i The target of the processing instruction
+ \row \i TQDomText \i The string "#text"
+ \endtable
+
+ \sa nodeValue()
+*/
+TQString TQDomNode::nodeName() const
+{
+ if ( !impl )
+ return TQString::null;
+
+ if ( !IMPL->prefix.isEmpty() )
+ return IMPL->prefix + ":" + IMPL->name;
+ return IMPL->name;
+}
+
+/*!
+ Returns the value of the node.
+
+ The meaning of the value depends on the subclass:
+ \table
+ \header \i Name \i Meaning
+ \row \i TQDomAttr \i The attribute value
+ \row \i TQDomCDATASection \i The content of the CDATA section
+ \row \i TQDomComment \i The comment
+ \row \i TQDomProcessingInstruction \i The data of the processing intruction
+ \row \i TQDomText \i The text
+ \endtable
+
+ All the other subclasses do not have a node value and will return
+ TQString::null.
+
+ \sa setNodeValue() nodeName()
+*/
+TQString TQDomNode::nodeValue() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->value;
+}
+
+/*!
+ Sets the node's value to \a v.
+
+ \sa nodeValue()
+*/
+void TQDomNode::setNodeValue( const TQString& v )
+{
+ if ( !impl )
+ return;
+ IMPL->setNodeValue( v );
+}
+
+/*!
+ \enum TQDomNode::NodeType
+
+ This enum defines the type of the node:
+ \value ElementNode
+ \value AttributeNode
+ \value TextNode
+ \value CDATASectionNode
+ \value EntityReferenceNode
+ \value EntityNode
+ \value ProcessingInstructionNode
+ \value CommentNode
+ \value DocumentNode
+ \value DocumentTypeNode
+ \value DocumentFragmentNode
+ \value NotationNode
+ \value BaseNode A TQDomNode object, i.e. not a TQDomNode subclass.
+ \value CharacterDataNode
+*/
+
+/*!
+ Returns the type of the node.
+
+ \sa toAttr(), toCDATASection(), toDocumentFragment(),
+ toDocument() toDocumentType(), toElement(), toEntityReference(),
+ toText(), toEntity() toNotation(), toProcessingInstruction(),
+ toCharacterData(), toComment()
+*/
+TQDomNode::NodeType TQDomNode::nodeType() const
+{
+ if ( !impl )
+ return TQDomNode::BaseNode;
+ return IMPL->nodeType();
+}
+
+/*!
+ Returns the tqparent node. If this node has no tqparent, a null node
+ is returned (i.e. a node for which isNull() returns TRUE).
+*/
+TQDomNode TQDomNode::parentNode() const
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->tqparent() );
+}
+
+/*!
+ Returns a list of all direct child nodes.
+
+ Most often you will call this function on a TQDomElement object.
+
+ For example, if the XML document looks like this:
+ \code
+ <body>
+ <h1>Heading</h1>
+ <p>Hello <b>you</b></p>
+ </body>
+ \endcode
+ Then the list of child nodes for the "body"-element will contain
+ the node created by the &lt;h1&gt; tag and the node created by the
+ &lt;p&gt; tag.
+
+ The nodes in the list are not copied; so changing the nodes in the
+ list will also change the tqchildren of this node.
+
+ \sa firstChild() lastChild()
+*/
+TQDomNodeList TQDomNode::childNodes() const
+{
+ if ( !impl )
+ return TQDomNodeList();
+ return TQDomNodeList( new TQDomNodeListPrivate( impl ) );
+}
+
+/*!
+ Returns the first child of the node. If there is no child node, a
+ \link isNull() null node\endlink is returned. Changing the
+ returned node will also change the node in the document tree.
+
+ \sa lastChild() childNodes()
+*/
+TQDomNode TQDomNode::firstChild() const
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->first );
+}
+
+/*!
+ Returns the last child of the node. If there is no child node, a
+ \link isNull() null node\endlink is returned. Changing the
+ returned node will also change the node in the document tree.
+
+ \sa firstChild() childNodes()
+*/
+TQDomNode TQDomNode::lastChild() const
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->last );
+}
+
+/*!
+ Returns the previous sibling in the document tree. Changing the
+ returned node will also change the node in the document tree.
+
+ For example, if you have XML like this:
+ \code
+ <h1>Heading</h1>
+ <p>The text...</p>
+ <h2>Next heading</h2>
+ \endcode
+ and this TQDomNode represents the &lt;p&gt; tag, previousSibling()
+ will return the node representing the &lt;h1&gt; tag.
+
+ \sa nextSibling()
+*/
+TQDomNode TQDomNode::previousSibling() const
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->prev );
+}
+
+/*!
+ Returns the next sibling in the document tree. Changing the
+ returned node will also change the node in the document tree.
+
+ If you have XML like this:
+ \code
+ <h1>Heading</h1>
+ <p>The text...</p>
+ <h2>Next heading</h2>
+ \endcode
+ and this TQDomNode represents the &lt;p&gt; tag, nextSibling() will
+ return the node representing the &lt;h2&gt; tag.
+
+ \sa previousSibling()
+*/
+TQDomNode TQDomNode::nextSibling() const
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->next );
+}
+
+/*!
+ Returns a named node map of all attributes. Attributes are only
+ provided for \l{TQDomElement}s.
+
+ Changing the attributes in the map will also change the attributes
+ of this TQDomNode.
+*/
+TQDomNamedNodeMap TQDomNode::attributes() const
+{
+ if ( !impl )
+ return TQDomNamedNodeMap();
+
+ return TQDomNamedNodeMap( impl->attributes() );
+}
+
+/*!
+ Returns the document to which this node belongs.
+*/
+TQDomDocument TQDomNode::ownerDocument() const
+{
+ if ( !impl )
+ return TQDomDocument();
+ return TQDomDocument( IMPL->ownerDocument() );
+}
+
+/*!
+ Creates a deep (not shallow) copy of the TQDomNode.
+
+ If \a deep is TRUE, then the cloning is done recursively which
+ means that all the node's tqchildren are deep copied too. If \a deep
+ is FALSE only the node itself is copied and the copy will have no
+ child nodes.
+*/
+TQDomNode TQDomNode::cloneNode( bool deep ) const
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->cloneNode( deep ) );
+}
+
+/*!
+ Calling normalize() on an element converts all its tqchildren into a
+ standard form. This means that adjacent TQDomText objects will be
+ merged into a single text object (TQDomCDATASection nodes are not
+ merged).
+*/
+void TQDomNode::normalize()
+{
+ if ( !impl )
+ return;
+ IMPL->normalize();
+}
+
+/*!
+ Returns TRUE if the DOM implementation implements the feature \a
+ feature and this feature is supported by this node in the version
+ \a version; otherwise returns FALSE.
+
+ \sa TQDomImplementation::hasFeature()
+*/
+bool TQDomNode::isSupported( const TQString& feature, const TQString& version ) const
+{
+ TQDomImplementation i;
+ return i.hasFeature( feature, version );
+}
+
+/*!
+ Returns the namespace URI of this node or TQString::null if the
+ node has no namespace URI.
+
+ Only nodes of type \link TQDomNode::NodeType ElementNode\endlink or
+ \link TQDomNode::NodeType AttributeNode\endlink can have
+ namespaces. A namespace URI must be specified at creation time and
+ cannot be changed later.
+
+ \sa prefix() localName() TQDomDocument::createElementNS()
+ TQDomDocument::createAttributeNS()
+*/
+TQString TQDomNode::namespaceURI() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->namespaceURI;
+}
+
+/*!
+ Returns the namespace prefix of the node or TQString::null if the
+ node has no namespace prefix.
+
+ Only nodes of type \link TQDomNode::NodeType ElementNode\endlink or
+ \link TQDomNode::NodeType AttributeNode\endlink can have
+ namespaces. A namespace prefix must be specified at creation time.
+ If a node was created with a namespace prefix, you can change it
+ later with setPrefix().
+
+ If you create an element or attribute with
+ TQDomDocument::createElement() or TQDomDocument::createAttribute(),
+ the prefix will be TQString::null. If you use
+ TQDomDocument::createElementNS() or
+ TQDomDocument::createAttributeNS() instead, the prefix will not be
+ TQString::null; but it might be an empty string if the name does
+ not have a prefix.
+
+ \sa setPrefix() localName() namespaceURI()
+ TQDomDocument::createElementNS() TQDomDocument::createAttributeNS()
+*/
+TQString TQDomNode::prefix() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->prefix;
+}
+
+/*!
+ If the node has a namespace prefix, this function changes the
+ namespace prefix of the node to \a pre. Otherwise this function
+ does nothing.
+
+ Only nodes of type \link TQDomNode::NodeType ElementNode\endlink or
+ \link TQDomNode::NodeType AttributeNode\endlink can have
+ namespaces. A namespace prefix must have be specified at creation
+ time; it is not possible to add a namespace prefix afterwards.
+
+ \sa prefix() localName() namespaceURI()
+ TQDomDocument::createElementNS() TQDomDocument::createAttributeNS()
+*/
+void TQDomNode::setPrefix( const TQString& pre )
+{
+ if ( !impl || IMPL->prefix.isNull() )
+ return;
+ if ( isAttr() || isElement() )
+ IMPL->prefix = pre;
+}
+
+/*!
+ If the node uses namespaces, this function returns the local name
+ of the node; otherwise it returns TQString::null.
+
+ Only nodes of type \link TQDomNode::NodeType ElementNode\endlink or
+ \link TQDomNode::NodeType AttributeNode\endlink can have
+ namespaces. A namespace must have been specified at creation time;
+ it is not possible to add a namespace afterwards.
+
+ \sa prefix() namespaceURI() TQDomDocument::createElementNS()
+ TQDomDocument::createAttributeNS()
+*/
+TQString TQDomNode::localName() const
+{
+ if ( !impl || IMPL->createdWithDom1Interface )
+ return TQString::null;
+ return IMPL->name;
+}
+
+/*!
+ Returns TRUE if the node has attributes; otherwise returns FALSE.
+
+ \sa attributes()
+*/
+bool TQDomNode::hasAttributes() const
+{
+ if ( !impl )
+ return FALSE;
+ return IMPL->hasAttributes();
+}
+
+/*!
+ Inserts the node \a newChild before the child node \a refChild.
+ \a refChild must be a direct child of this node. If \a refChild is
+ \link isNull() null\endlink then \a newChild is inserted as the
+ node's first child.
+
+ If \a newChild is the child of another node, it is reparented to
+ this node. If \a newChild is a child of this node, then its
+ position in the list of tqchildren is changed.
+
+ If \a newChild is a TQDomDocumentFragment, then the tqchildren of the
+ fragment are removed from the fragment and inserted before \a
+ refChild.
+
+ Returns a new reference to \a newChild on success or a \link
+ isNull() null node\endlink on failure.
+
+ \sa insertAfter() tqreplaceChild() removeChild() appendChild()
+*/
+TQDomNode TQDomNode::insertBefore( const TQDomNode& newChild, const TQDomNode& refChild )
+{
+ if ( !impl ) {
+ if (nodeType() == DocumentNode)
+ impl = new TQDomDocumentPrivate;
+ else
+ return TQDomNode();
+ }
+ return TQDomNode( IMPL->insertBefore( newChild.impl, refChild.impl ) );
+}
+
+/*!
+ Inserts the node \a newChild after the child node \a refChild. \a
+ refChild must be a direct child of this node. If \a refChild is
+ \link isNull() null\endlink then \a newChild is appended as this
+ node's last child.
+
+ If \a newChild is the child of another node, it is reparented to
+ this node. If \a newChild is a child of this node, then its
+ position in the list of tqchildren is changed.
+
+ If \a newChild is a TQDomDocumentFragment, then the tqchildren of the
+ fragment are removed from the fragment and inserted after \a
+ refChild.
+
+ Returns a new reference to \a newChild on success or a \link
+ isNull() null node\endlink on failure.
+
+ \sa insertBefore() tqreplaceChild() removeChild() appendChild()
+*/
+TQDomNode TQDomNode::insertAfter( const TQDomNode& newChild, const TQDomNode& refChild )
+{
+ if ( !impl ) {
+ if (nodeType() == DocumentNode)
+ impl = new TQDomDocumentPrivate;
+ else
+ return TQDomNode();
+ }
+ return TQDomNode( IMPL->insertAfter( newChild.impl, refChild.impl ) );
+}
+
+/*!
+ Replaces \a oldChild with \a newChild. \a oldChild must be a
+ direct child of this node.
+
+ If \a newChild is the child of another node, it is reparented to
+ this node. If \a newChild is a child of this node, then its
+ position in the list of tqchildren is changed.
+
+ If \a newChild is a TQDomDocumentFragment, then \a oldChild is
+ tqreplaced by all of the tqchildren of the fragment.
+
+ Returns a new reference to \a oldChild on success or a \link
+ isNull() null node\endlink an failure.
+
+ \sa insertBefore() insertAfter() removeChild() appendChild()
+*/
+TQDomNode TQDomNode::tqreplaceChild( const TQDomNode& newChild, const TQDomNode& oldChild )
+{
+ if ( !impl ) {
+ if (nodeType() == DocumentNode)
+ impl = new TQDomDocumentPrivate;
+ else
+ return TQDomNode();
+ }
+ return TQDomNode( IMPL->tqreplaceChild( newChild.impl, oldChild.impl ) );
+}
+
+/*!
+ Removes \a oldChild from the list of tqchildren. \a oldChild must be
+ a direct child of this node.
+
+ Returns a new reference to \a oldChild on success or a \link
+ isNull() null node\endlink on failure.
+
+ \sa insertBefore() insertAfter() tqreplaceChild() appendChild()
+*/
+TQDomNode TQDomNode::removeChild( const TQDomNode& oldChild )
+{
+ if ( !impl )
+ return TQDomNode();
+
+ if ( oldChild.isNull() )
+ return TQDomNode();
+
+ return TQDomNode( IMPL->removeChild( oldChild.impl ) );
+}
+
+/*!
+ Appends \a newChild as the node's last child.
+
+ If \a newChild is the child of another node, it is reparented to
+ this node. If \a newChild is a child of this node, then its
+ position in the list of tqchildren is changed.
+
+ If \a newChild is a TQDomDocumentFragment, then the tqchildren of the
+ fragment are removed from the fragment and appended.
+
+ Returns a new reference to \a newChild.
+
+ \sa insertBefore() insertAfter() tqreplaceChild() removeChild()
+*/
+TQDomNode TQDomNode::appendChild( const TQDomNode& newChild )
+{
+ if ( !impl ) {
+ if (nodeType() == DocumentNode)
+ impl = new TQDomDocumentPrivate;
+ else
+ return TQDomNode();
+ }
+ return TQDomNode( IMPL->appendChild( newChild.impl ) );
+}
+
+/*!
+ Returns TRUE if the node has one or more tqchildren; otherwise
+ returns FALSE.
+*/
+bool TQDomNode::hasChildNodes() const
+{
+ if ( !impl )
+ return FALSE;
+ return IMPL->first != 0;
+}
+
+/*!
+ Returns TRUE if this node is null (i.e. if it has no type or
+ contents); otherwise returns FALSE.
+*/
+bool TQDomNode::isNull() const
+{
+ return ( impl == 0 );
+}
+
+/*!
+ Converts the node into a null node; if it was not a null node
+ before, its type and contents are deleted.
+
+ \sa isNull()
+*/
+void TQDomNode::clear()
+{
+ if ( impl && impl->deref() ) delete impl;
+ impl = 0;
+}
+
+/*!
+ Returns the first direct child node for which nodeName() equals \a
+ name.
+
+ If no such direct child exists, a \link isNull() null node\endlink
+ is returned.
+
+ \sa nodeName()
+*/
+TQDomNode TQDomNode::namedItem( const TQString& name ) const
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( impl->namedItem( name ) );
+}
+
+/*!
+ Writes the XML representation of the node and all its tqchildren to
+ the stream \a str. This function uses \a indent as the amount of
+ space to indent the node.
+*/
+void TQDomNode::save( TQTextStream& str, int indent ) const
+{
+ if ( impl )
+ IMPL->save( str, 1, indent );
+}
+
+/*!
+ \relates TQDomNode
+
+ Writes the XML representation of the node \a node and all its
+ tqchildren to the stream \a str.
+*/
+TQTextStream& operator<<( TQTextStream& str, const TQDomNode& node )
+{
+ node.save( str, 1 );
+
+ return str;
+}
+
+/*!
+ Returns TRUE if the node is an attribute; otherwise returns FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomAttribute; you can get the TQDomAttribute with
+ toAttribute().
+
+ \sa toAttr()
+*/
+bool TQDomNode::isAttr() const
+{
+ if(impl)
+ return impl->isAttr();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a CDATA section; otherwise returns
+ FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomCDATASection; you can get the TQDomCDATASection with
+ toCDATASection().
+
+ \sa toCDATASection()
+*/
+bool TQDomNode::isCDATASection() const
+{
+ if(impl)
+ return impl->isCDATASection();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a document fragment; otherwise returns
+ FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomDocumentFragment; you can get the TQDomDocumentFragment
+ with toDocumentFragment().
+
+ \sa toDocumentFragment()
+*/
+bool TQDomNode::isDocumentFragment() const
+{
+ if(impl)
+ return impl->isDocumentFragment();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a document; otherwise returns FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomDocument; you can get the TQDomDocument with toDocument().
+
+ \sa toDocument()
+*/
+bool TQDomNode::isDocument() const
+{
+ if(impl)
+ return impl->isDocument();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a document type; otherwise returns
+ FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomDocumentType; you can get the TQDomDocumentType with
+ toDocumentType().
+
+ \sa toDocumentType()
+*/
+bool TQDomNode::isDocumentType() const
+{
+ if(impl)
+ return impl->isDocumentType();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is an element; otherwise returns FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomElement; you can get the TQDomElement with toElement().
+
+ \sa toElement()
+*/
+bool TQDomNode::isElement() const
+{
+ if(impl)
+ return impl->isElement();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is an entity reference; otherwise returns
+ FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomEntityReference; you can get the TQDomEntityReference with
+ toEntityReference().
+
+ \sa toEntityReference()
+*/
+bool TQDomNode::isEntityReference() const
+{
+ if(impl)
+ return impl->isEntityReference();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a text node; otherwise returns FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomText; you can get the TQDomText with toText().
+
+ \sa toText()
+*/
+bool TQDomNode::isText() const
+{
+ if(impl)
+ return impl->isText();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is an entity; otherwise returns FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomEntity; you can get the TQDomEntity with toEntity().
+
+ \sa toEntity()
+*/
+bool TQDomNode::isEntity() const
+{
+ if(impl)
+ return impl->isEntity();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a notation; otherwise returns FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomNotation; you can get the TQDomNotation with toNotation().
+
+ \sa toNotation()
+*/
+bool TQDomNode::isNotation() const
+{
+ if(impl)
+ return impl->isNotation();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a processing instruction; otherwise
+ returns FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomProcessingInstruction; you can get the
+ TQProcessingInstruction with toProcessingInstruction().
+
+ \sa toProcessingInstruction()
+*/
+bool TQDomNode::isProcessingInstruction() const
+{
+ if(impl)
+ return impl->isProcessingInstruction();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a character data node; otherwise
+ returns FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomCharacterData; you can get the TQDomCharacterData with
+ toCharacterData().
+
+ \sa toCharacterData()
+*/
+bool TQDomNode::isCharacterData() const
+{
+ if(impl)
+ return impl->isCharacterData();
+ return FALSE;
+}
+
+/*!
+ Returns TRUE if the node is a comment; otherwise returns FALSE.
+
+ If this function returns TRUE, it does not imply that this object
+ is a TQDomComment; you can get the TQDomComment with toComment().
+
+ \sa toComment()
+*/
+bool TQDomNode::isComment() const
+{
+ if(impl)
+ return impl->isComment();
+ return FALSE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomNamedNodeMapPrivate
+ *
+ **************************************************************/
+
+TQDomNamedNodeMapPrivate::TQDomNamedNodeMapPrivate( TQDomNodePrivate* n )
+{
+ readonly = FALSE;
+ tqparent = n;
+ appendToParent = FALSE;
+}
+
+TQDomNamedNodeMapPrivate::~TQDomNamedNodeMapPrivate()
+{
+ clearMap();
+}
+
+TQDomNamedNodeMapPrivate* TQDomNamedNodeMapPrivate::clone( TQDomNodePrivate* p )
+{
+ TQDomNamedNodeMapPrivate* m = new TQDomNamedNodeMapPrivate( p );
+ m->readonly = readonly;
+ m->appendToParent = appendToParent;
+
+ TQDictIterator<TQDomNodePrivate> it ( map );
+ for ( ; it.current(); ++it )
+ m->setNamedItem( it.current()->cloneNode() );
+
+ // we are no longer interested in ownership
+ m->deref();
+ return m;
+}
+
+void TQDomNamedNodeMapPrivate::clearMap()
+{
+ // Dereference all of our tqchildren if we took references
+ if ( !appendToParent ) {
+ TQDictIterator<TQDomNodePrivate> it( map );
+ for ( ; it.current(); ++it )
+ if ( it.current()->deref() )
+ delete it.current();
+ }
+
+ map.clear();
+}
+
+TQDomNodePrivate* TQDomNamedNodeMapPrivate::namedItem( const TQString& name ) const
+{
+ TQDomNodePrivate* p = map[ name ];
+ return p;
+}
+
+TQDomNodePrivate* TQDomNamedNodeMapPrivate::namedItemNS( const TQString& nsURI, const TQString& localName ) const
+{
+ TQDictIterator<TQDomNodePrivate> it( map );
+ TQDomNodePrivate *n = it.current();
+ while ( n ) {
+ if ( !n->prefix.isNull() ) {
+ // node has a namespace
+ if ( n->namespaceURI==nsURI && n->name==localName ) {
+ return n;
+ }
+ }
+ ++it;
+ n = it.current();
+ }
+ return 0;
+}
+
+TQDomNodePrivate* TQDomNamedNodeMapPrivate::setNamedItem( TQDomNodePrivate* arg )
+{
+ if ( readonly || !arg )
+ return 0;
+
+ if ( appendToParent )
+ return tqparent->appendChild( arg );
+
+ TQDomNodePrivate *n = map[ arg->nodeName() ];
+ // We take a reference
+ arg->ref();
+ map.insert( arg->nodeName(), arg );
+ return n;
+}
+
+TQDomNodePrivate* TQDomNamedNodeMapPrivate::setNamedItemNS( TQDomNodePrivate* arg )
+{
+ if ( readonly || !arg )
+ return 0;
+
+ if ( appendToParent )
+ return tqparent->appendChild( arg );
+
+ if ( !arg->prefix.isNull() ) {
+ // node has a namespace
+ TQDomNodePrivate *n = namedItemNS( arg->namespaceURI, arg->name );
+ // We take a reference
+ arg->ref();
+ map.insert( arg->nodeName(), arg );
+ return n;
+ } else {
+ // ### check the following code if it is ok
+ return setNamedItem( arg );
+ }
+}
+
+TQDomNodePrivate* TQDomNamedNodeMapPrivate::removeNamedItem( const TQString& name )
+{
+ if ( readonly )
+ return 0;
+
+ TQDomNodePrivate* p = namedItem( name );
+ if ( p == 0 )
+ return 0;
+ if ( appendToParent )
+ return tqparent->removeChild( p );
+
+ map.remove( p->nodeName() );
+ // We took a reference, so we have to free one here
+ p->deref();
+ return p;
+}
+
+TQDomNodePrivate* TQDomNamedNodeMapPrivate::item( int index ) const
+{
+ if ( (uint)index >= length() )
+ return 0;
+
+ TQDictIterator<TQDomNodePrivate> it( map );
+ for ( int i = 0; i < index; ++i, ++it )
+ ;
+ return it.current();
+}
+
+uint TQDomNamedNodeMapPrivate::length() const
+{
+ return map.count();
+}
+
+bool TQDomNamedNodeMapPrivate::tqcontains( const TQString& name ) const
+{
+ return ( map[ name ] != 0 );
+}
+
+bool TQDomNamedNodeMapPrivate::tqcontainsNS( const TQString& nsURI, const TQString & localName ) const
+{
+ return ( namedItemNS( nsURI, localName ) != 0 );
+}
+
+/**************************************************************
+ *
+ * TQDomNamedNodeMap
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomNamedNodeMapPrivate*)impl)
+
+/*!
+ \class TQDomNamedNodeMap tqdom.h
+ \reentrant
+ \brief The TQDomNamedNodeMap class tqcontains a collection of nodes
+ that can be accessed by name.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ Note that TQDomNamedNodeMap does not inherit from TQDomNodeList.
+ TQDomNamedNodeMaps do not provide any specific node ordering.
+ Although nodes in a TQDomNamedNodeMap may be accessed by an ordinal
+ index, this is simply to allow a convenient enumeration of the
+ contents of a TQDomNamedNodeMap, and does not imply that the DOM
+ specifies an ordering of the nodes.
+
+ The TQDomNamedNodeMap is used in three places:
+ \list 1
+ \i TQDomDocumentType::entities() returns a map of all entities
+ described in the DTD.
+ \i TQDomDocumentType::notations() returns a map of all notations
+ described in the DTD.
+ \i TQDomNode::attributes() returns a map of all attributes of an
+ element.
+ \endlist
+
+ Items in the map are identified by the name which TQDomNode::name()
+ returns. Nodes are retrieved using namedItem(), namedItemNS() or
+ item(). New nodes are inserted with setNamedItem() or
+ setNamedItemNS() and removed with removeNamedItem() or
+ removeNamedItemNS(). Use tqcontains() to see if an item with the
+ given name is in the named node map. The number of items is
+ returned by length().
+
+ Terminology: in this class we use "item" and "node"
+ interchangeably.
+*/
+
+/*!
+ Constructs an empty named node map.
+*/
+TQDomNamedNodeMap::TQDomNamedNodeMap()
+{
+ impl = 0;
+}
+
+/*!
+ Constructs a copy of \a n.
+*/
+TQDomNamedNodeMap::TQDomNamedNodeMap( const TQDomNamedNodeMap& n )
+{
+ impl = n.impl;
+ if ( impl )
+ impl->ref();
+}
+
+TQDomNamedNodeMap::TQDomNamedNodeMap( TQDomNamedNodeMapPrivate* n )
+{
+ impl = n;
+ if ( impl )
+ impl->ref();
+}
+
+/*!
+ Assigns \a n to this named node map.
+*/
+TQDomNamedNodeMap& TQDomNamedNodeMap::operator= ( const TQDomNamedNodeMap& n )
+{
+ if ( impl && impl->deref() )
+ delete impl;
+ impl = n.impl;
+ if ( impl )
+ impl->ref();
+
+ return *this;
+}
+
+/*!
+ Returns TRUE if \a n and this named node map are equal; otherwise
+ returns FALSE.
+*/
+bool TQDomNamedNodeMap::operator== ( const TQDomNamedNodeMap& n ) const
+{
+ return ( impl == n.impl );
+}
+
+/*!
+ Returns TRUE if \a n and this named node map are not equal;
+ otherwise returns FALSE.
+*/
+bool TQDomNamedNodeMap::operator!= ( const TQDomNamedNodeMap& n ) const
+{
+ return ( impl != n.impl );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomNamedNodeMap::~TQDomNamedNodeMap()
+{
+ if ( impl && impl->deref() )
+ delete impl;
+}
+
+/*!
+ Returns the node called \a name.
+
+ If the named node map does not contain such a node, a \link
+ TQDomNode::isNull() null node\endlink is returned. A node's name is
+ the name returned by TQDomNode::nodeName().
+
+ \sa setNamedItem() namedItemNS()
+*/
+TQDomNode TQDomNamedNodeMap::namedItem( const TQString& name ) const
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->namedItem( name ) );
+}
+
+/*!
+ Inserts the node \a newNode into the named node map. The name used
+ by the map is the node name of \a newNode as returned by
+ TQDomNode::nodeName().
+
+ If the new node tqreplaces an existing node, i.e. the map tqcontains a
+ node with the same name, the tqreplaced node is returned.
+
+ \sa namedItem() removeNamedItem() setNamedItemNS()
+*/
+TQDomNode TQDomNamedNodeMap::setNamedItem( const TQDomNode& newNode )
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->setNamedItem( (TQDomNodePrivate*)newNode.impl ) );
+}
+
+/*!
+ Removes the node called \a name from the map.
+
+ The function returns the removed node or a \link
+ TQDomNode::isNull() null node\endlink if the map did not contain a
+ node called \a name.
+
+ \sa setNamedItem() namedItem() removeNamedItemNS()
+*/
+TQDomNode TQDomNamedNodeMap::removeNamedItem( const TQString& name )
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->removeNamedItem( name ) );
+}
+
+/*!
+ Retrieves the node at position \a index.
+
+ This can be used to iterate over the map. Note that the nodes in
+ the map are ordered arbitrarily.
+
+ \sa length()
+*/
+TQDomNode TQDomNamedNodeMap::item( int index ) const
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->item( index ) );
+}
+
+/*!
+ Returns the node associated with the local name \a localName and
+ the namespace URI \a nsURI.
+
+ If the map does not contain such a node, a \link
+ TQDomNode::isNull() null node\endlink is returned.
+
+ \sa setNamedItemNS() namedItem()
+*/
+TQDomNode TQDomNamedNodeMap::namedItemNS( const TQString& nsURI, const TQString& localName ) const
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->namedItemNS( nsURI, localName ) );
+}
+
+/*!
+ Inserts the node \a newNode in the map. If a node with the same
+ namespace URI and the same local name already exists in the map,
+ it is tqreplaced by \a newNode. If the new node tqreplaces an existing
+ node, the tqreplaced node is returned.
+
+ \sa namedItemNS() removeNamedItemNS() setNamedItem()
+*/
+TQDomNode TQDomNamedNodeMap::setNamedItemNS( const TQDomNode& newNode )
+{
+ if ( !impl )
+ return TQDomNode();
+ return TQDomNode( IMPL->setNamedItemNS( (TQDomNodePrivate*)newNode.impl ) );
+}
+
+/*!
+ Removes the node with the local name \a localName and the
+ namespace URI \a nsURI from the map.
+
+ The function returns the removed node or a \link
+ TQDomNode::isNull() null node\endlink if the map did not contain a
+ node with the local name \a localName and the namespace URI \a
+ nsURI.
+
+ \sa setNamedItemNS() namedItemNS() removeNamedItem()
+*/
+TQDomNode TQDomNamedNodeMap::removeNamedItemNS( const TQString& nsURI, const TQString& localName )
+{
+ if ( !impl )
+ return TQDomNode();
+ TQDomNodePrivate *n = IMPL->namedItemNS( nsURI, localName );
+ if ( !n )
+ return TQDomNode();
+ return TQDomNode( IMPL->removeNamedItem( n->name ) );
+}
+
+/*!
+ Returns the number of nodes in the map.
+
+ \sa item()
+*/
+uint TQDomNamedNodeMap::length() const
+{
+ if ( !impl )
+ return 0;
+ return IMPL->length();
+}
+
+/*!
+ \fn uint TQDomNamedNodeMap::count() const
+
+ Returns the number of nodes in the map.
+
+ This function is the same as length().
+*/
+
+/*!
+ Returns TRUE if the map tqcontains a node called \a name; otherwise
+ returns FALSE.
+*/
+bool TQDomNamedNodeMap::tqcontains( const TQString& name ) const
+{
+ if ( !impl )
+ return FALSE;
+ return IMPL->tqcontains( name );
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomDocumentTypePrivate
+ *
+ **************************************************************/
+
+TQDomDocumentTypePrivate::TQDomDocumentTypePrivate( TQDomDocumentPrivate* doc, TQDomNodePrivate* tqparent )
+ : TQDomNodePrivate( doc, tqparent )
+{
+ init();
+}
+
+TQDomDocumentTypePrivate::TQDomDocumentTypePrivate( TQDomDocumentTypePrivate* n, bool deep )
+ : TQDomNodePrivate( n, deep )
+{
+ init();
+ // Refill the maps with our new tqchildren
+ TQDomNodePrivate* p = first;
+ while ( p ) {
+ if ( p->isEntity() )
+ // Dont use normal insert function since we would create infinite recursion
+ entities->map.insert( p->nodeName(), p );
+ if ( p->isNotation() )
+ // Dont use normal insert function since we would create infinite recursion
+ notations->map.insert( p->nodeName(), p );
+ }
+}
+
+TQDomDocumentTypePrivate::~TQDomDocumentTypePrivate()
+{
+ if ( entities->deref() )
+ delete entities;
+ if ( notations->deref() )
+ delete notations;
+}
+
+void TQDomDocumentTypePrivate::init()
+{
+ entities = new TQDomNamedNodeMapPrivate( this );
+ notations = new TQDomNamedNodeMapPrivate( this );
+ publicId = TQString::null;
+ systemId = TQString::null;
+ internalSubset = TQString::null;
+
+ entities->setAppendToParent( TRUE );
+ notations->setAppendToParent( TRUE );
+}
+
+TQDomNodePrivate* TQDomDocumentTypePrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomDocumentTypePrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+TQDomNodePrivate* TQDomDocumentTypePrivate::insertBefore( TQDomNodePrivate* newChild, TQDomNodePrivate* refChild )
+{
+ // Call the origianl implementation
+ TQDomNodePrivate* p = TQDomNodePrivate::insertBefore( newChild, refChild );
+ // Update the maps
+ if ( p && p->isEntity() )
+ entities->map.insert( p->nodeName(), p );
+ else if ( p && p->isNotation() )
+ notations->map.insert( p->nodeName(), p );
+
+ return p;
+}
+
+TQDomNodePrivate* TQDomDocumentTypePrivate::insertAfter( TQDomNodePrivate* newChild, TQDomNodePrivate* refChild )
+{
+ // Call the origianl implementation
+ TQDomNodePrivate* p = TQDomNodePrivate::insertAfter( newChild, refChild );
+ // Update the maps
+ if ( p && p->isEntity() )
+ entities->map.insert( p->nodeName(), p );
+ else if ( p && p->isNotation() )
+ notations->map.insert( p->nodeName(), p );
+
+ return p;
+}
+
+TQDomNodePrivate* TQDomDocumentTypePrivate::tqreplaceChild( TQDomNodePrivate* newChild, TQDomNodePrivate* oldChild )
+{
+ // Call the origianl implementation
+ TQDomNodePrivate* p = TQDomNodePrivate::tqreplaceChild( newChild, oldChild );
+ // Update the maps
+ if ( p ) {
+ if ( oldChild && oldChild->isEntity() )
+ entities->map.remove( oldChild->nodeName() );
+ else if ( oldChild && oldChild->isNotation() )
+ notations->map.remove( oldChild->nodeName() );
+
+ if ( p->isEntity() )
+ entities->map.insert( p->nodeName(), p );
+ else if ( p->isNotation() )
+ notations->map.insert( p->nodeName(), p );
+ }
+
+ return p;
+}
+
+TQDomNodePrivate* TQDomDocumentTypePrivate::removeChild( TQDomNodePrivate* oldChild )
+{
+ // Call the origianl implementation
+ TQDomNodePrivate* p = TQDomNodePrivate::removeChild( oldChild );
+ // Update the maps
+ if ( p && p->isEntity() )
+ entities->map.remove( p->nodeName() );
+ else if ( p && p->isNotation() )
+ notations->map.remove( p ->nodeName() );
+
+ return p;
+}
+
+TQDomNodePrivate* TQDomDocumentTypePrivate::appendChild( TQDomNodePrivate* newChild )
+{
+ return insertAfter( newChild, 0 );
+}
+
+void TQDomDocumentTypePrivate::save( TQTextStream& s, int, int indent ) const
+{
+ if ( name.isEmpty() )
+ return;
+
+ s << "<!DOCTYPE " << name;
+
+ if ( !publicId.isNull() ) {
+ s << " PUBLIC \"" << publicId << "\"";
+ if ( !systemId.isNull() )
+ s << " \"" << systemId << "\"";
+ } else if ( !systemId.isNull() ) {
+ s << " SYSTEM \"" << systemId << "\"";
+ }
+
+ if ( entities->length()>0 || notations->length()>0 ) {
+ s << " [ " << endl;
+
+ TQDictIterator<TQDomNodePrivate> it2( notations->map );
+ for ( ; it2.current(); ++it2 )
+ it2.current()->save( s, 0, indent );
+
+ TQDictIterator<TQDomNodePrivate> it( entities->map );
+ for ( ; it.current(); ++it )
+ it.current()->save( s, 0, indent );
+
+ s << " ]";
+ }
+
+ s << ">" << endl;
+}
+
+/**************************************************************
+ *
+ * TQDomDocumentType
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomDocumentTypePrivate*)impl)
+
+/*!
+ \class TQDomDocumentType tqdom.h
+ \reentrant
+ \brief The TQDomDocumentType class is the representation of the DTD
+ in the document tree.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ The TQDomDocumentType class allows read-only access to some of the
+ data structures in the DTD: it can return a map of all entities()
+ and notations(). In addition the function name() returns the name
+ of the document type as specified in the &lt;!DOCTYPE name&gt;
+ tag. This class also provides the publicId(), systemId() and
+ internalSubset() functions.
+
+ \sa TQDomDocument
+*/
+
+/*!
+ Creates an empty TQDomDocumentType object.
+*/
+TQDomDocumentType::TQDomDocumentType() : TQDomNode()
+{
+}
+
+/*!
+ Constructs a copy of \a n.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomDocumentType::TQDomDocumentType( const TQDomDocumentType& n )
+ : TQDomNode( n )
+{
+}
+
+TQDomDocumentType::TQDomDocumentType( TQDomDocumentTypePrivate* n )
+ : TQDomNode( n )
+{
+}
+
+/*!
+ Assigns \a n to this document type.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomDocumentType& TQDomDocumentType::operator= ( const TQDomDocumentType& n )
+{
+ return (TQDomDocumentType&) TQDomNode::operator=( n );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomDocumentType::~TQDomDocumentType()
+{
+}
+
+/*!
+ Returns the name of the document type as specified in the
+ &lt;!DOCTYPE name&gt; tag.
+
+ \sa nodeName()
+*/
+TQString TQDomDocumentType::name() const
+{
+ if ( !impl )
+ return TQString::null;
+
+ return IMPL->nodeName();
+}
+
+/*!
+ Returns a map of all entities described in the DTD.
+*/
+TQDomNamedNodeMap TQDomDocumentType::entities() const
+{
+ if ( !impl )
+ return TQDomNamedNodeMap();
+ return TQDomNamedNodeMap( IMPL->entities );
+}
+
+/*!
+ Returns a map of all notations described in the DTD.
+*/
+TQDomNamedNodeMap TQDomDocumentType::notations() const
+{
+ if ( !impl )
+ return TQDomNamedNodeMap();
+ return TQDomNamedNodeMap( IMPL->notations );
+}
+
+/*!
+ Returns the public identifier of the external DTD subset or
+ TQString::null if there is no public identifier.
+
+ \sa systemId() internalSubset() TQDomImplementation::createDocumentType()
+*/
+TQString TQDomDocumentType::publicId() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->publicId;
+}
+
+/*!
+ Returns the system identifier of the external DTD subset or
+ TQString::null if there is no system identifier.
+
+ \sa publicId() internalSubset() TQDomImplementation::createDocumentType()
+*/
+TQString TQDomDocumentType::systemId() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->systemId;
+}
+
+/*!
+ Returns the internal subset of the document type or TQString::null
+ if there is no internal subset.
+
+ \sa publicId() systemId()
+*/
+TQString TQDomDocumentType::internalSubset() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->internalSubset;
+}
+
+/*!
+ Returns \c DocumentTypeNode.
+
+ \sa isDocumentType() TQDomNode::toDocumentType()
+*/
+TQDomNode::NodeType TQDomDocumentType::nodeType() const
+{
+ return DocumentTypeNode;
+}
+
+/*!
+ This function overloads TQDomNode::isDocumentType().
+
+ \sa nodeType() TQDomNode::toDocumentType()
+*/
+bool TQDomDocumentType::isDocumentType() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomDocumentFragmentPrivate
+ *
+ **************************************************************/
+
+TQDomDocumentFragmentPrivate::TQDomDocumentFragmentPrivate( TQDomDocumentPrivate* doc, TQDomNodePrivate* tqparent )
+ : TQDomNodePrivate( doc, tqparent )
+{
+ name = "#document-fragment";
+}
+
+TQDomDocumentFragmentPrivate::TQDomDocumentFragmentPrivate( TQDomNodePrivate* n, bool deep )
+ : TQDomNodePrivate( n, deep )
+{
+}
+
+TQDomDocumentFragmentPrivate::~TQDomDocumentFragmentPrivate()
+{
+}
+
+TQDomNodePrivate* TQDomDocumentFragmentPrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomDocumentFragmentPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+/**************************************************************
+ *
+ * TQDomDocumentFragment
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomDocumentFragmentPrivate*)impl)
+
+/*!
+ \class TQDomDocumentFragment tqdom.h
+ \reentrant
+ \brief The TQDomDocumentFragment class is a tree of TQDomNodes which is not usually a complete TQDomDocument.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ If you want to do complex tree operations it is useful to have a
+ lightweight class to store nodes and their relations.
+ TQDomDocumentFragment stores a subtree of a document which does not
+ necessarily represent a well-formed XML document.
+
+ TQDomDocumentFragment is also useful if you want to group several
+ nodes in a list and insert them all together as tqchildren of some
+ node. In these cases TQDomDocumentFragment can be used as a
+ temporary container for this list of tqchildren.
+
+ The most important feature of TQDomDocumentFragment is that it is
+ treated in a special way by TQDomNode::insertAfter(),
+ TQDomNode::insertBefore(), TQDomNode::tqreplaceChild() and
+ TQDomNode::appendChild(): instead of inserting the fragment itself, all
+ the fragment's tqchildren are inserted.
+*/
+
+/*!
+ Constructs an empty document fragment.
+*/
+TQDomDocumentFragment::TQDomDocumentFragment()
+{
+}
+
+TQDomDocumentFragment::TQDomDocumentFragment( TQDomDocumentFragmentPrivate* n )
+ : TQDomNode( n )
+{
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomDocumentFragment::TQDomDocumentFragment( const TQDomDocumentFragment& x )
+ : TQDomNode( x )
+{
+}
+
+/*!
+ Assigns \a x to this DOM document fragment.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomDocumentFragment& TQDomDocumentFragment::operator= ( const TQDomDocumentFragment& x )
+{
+ return (TQDomDocumentFragment&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomDocumentFragment::~TQDomDocumentFragment()
+{
+}
+
+/*!
+ Returns \c DocumentFragment.
+
+ \sa isDocumentFragment() TQDomNode::toDocumentFragment()
+*/
+TQDomNode::NodeType TQDomDocumentFragment::nodeType() const
+{
+ return TQDomNode::DocumentFragmentNode;
+}
+
+/*!
+ This function reimplements TQDomNode::isDocumentFragment().
+
+ \sa nodeType() TQDomNode::toDocumentFragment()
+*/
+bool TQDomDocumentFragment::isDocumentFragment() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomCharacterDataPrivate
+ *
+ **************************************************************/
+
+TQDomCharacterDataPrivate::TQDomCharacterDataPrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* p,
+ const TQString& data )
+ : TQDomNodePrivate( d, p )
+{
+ value = data;
+
+ name = "#character-data";
+}
+
+TQDomCharacterDataPrivate::TQDomCharacterDataPrivate( TQDomCharacterDataPrivate* n, bool deep )
+ : TQDomNodePrivate( n, deep )
+{
+}
+
+TQDomCharacterDataPrivate::~TQDomCharacterDataPrivate()
+{
+}
+
+TQDomNodePrivate* TQDomCharacterDataPrivate::cloneNode( bool deep )
+{
+ TQDomNodePrivate* p = new TQDomCharacterDataPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+uint TQDomCharacterDataPrivate::dataLength() const
+{
+ return value.length();
+}
+
+TQString TQDomCharacterDataPrivate::substringData( unsigned long offset, unsigned long n ) const
+{
+ return value.mid( offset, n );
+}
+
+void TQDomCharacterDataPrivate::insertData( unsigned long offset, const TQString& arg )
+{
+ value.insert( offset, arg );
+}
+
+void TQDomCharacterDataPrivate::deleteData( unsigned long offset, unsigned long n )
+{
+ value.remove( offset, n );
+}
+
+void TQDomCharacterDataPrivate::tqreplaceData( unsigned long offset, unsigned long n, const TQString& arg )
+{
+ value.tqreplace( offset, n, arg );
+}
+
+void TQDomCharacterDataPrivate::appendData( const TQString& arg )
+{
+ value += arg;
+}
+
+/**************************************************************
+ *
+ * TQDomCharacterData
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomCharacterDataPrivate*)impl)
+
+/*!
+ \class TQDomCharacterData tqdom.h
+ \reentrant
+ \brief The TQDomCharacterData class represents a generic string in the DOM.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ Character data as used in XML specifies a generic data string.
+ More specialized versions of this class are TQDomText, TQDomComment
+ and TQDomCDATASection.
+
+ The data string is set with setData() and retrieved with data().
+ You can retrieve a portion of the data string using
+ substringData(). Extra data can be appended with appendData(), or
+ inserted with insertData(). Portions of the data string can be
+ deleted with deleteData() or tqreplaced with tqreplaceData(). The
+ length of the data string is returned by length().
+
+ The node type of the node containing this character data is
+ returned by nodeType().
+
+ \sa TQDomText TQDomComment TQDomCDATASection
+*/
+
+/*!
+ Constructs an empty character data object.
+*/
+TQDomCharacterData::TQDomCharacterData()
+{
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomCharacterData::TQDomCharacterData( const TQDomCharacterData& x )
+ : TQDomNode( x )
+{
+}
+
+TQDomCharacterData::TQDomCharacterData( TQDomCharacterDataPrivate* n )
+ : TQDomNode( n )
+{
+}
+
+/*!
+ Assigns \a x to this character data.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomCharacterData& TQDomCharacterData::operator= ( const TQDomCharacterData& x )
+{
+ return (TQDomCharacterData&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomCharacterData::~TQDomCharacterData()
+{
+}
+
+/*!
+ Returns the string stored in this object.
+
+ If the node is a \link isNull() null node\endlink, it will return
+ TQString::null.
+*/
+TQString TQDomCharacterData::data() const
+{
+ if ( !impl )
+ return TQString::null;
+ return impl->nodeValue();
+}
+
+/*!
+ Sets this object's string to \a v.
+*/
+void TQDomCharacterData::setData( const TQString& v )
+{
+ if ( impl )
+ impl->setNodeValue( v );
+}
+
+/*!
+ Returns the length of the stored string.
+*/
+uint TQDomCharacterData::length() const
+{
+ if ( impl )
+ return IMPL->dataLength();
+ return 0;
+}
+
+/*!
+ Returns the substring of length \a count from position \a offset.
+*/
+TQString TQDomCharacterData::substringData( unsigned long offset, unsigned long count )
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->substringData( offset, count );
+}
+
+/*!
+ Appends the string \a arg to the stored string.
+*/
+void TQDomCharacterData::appendData( const TQString& arg )
+{
+ if ( impl )
+ IMPL->appendData( arg );
+}
+
+/*!
+ Inserts the string \a arg into the stored string at position \a offset.
+*/
+void TQDomCharacterData::insertData( unsigned long offset, const TQString& arg )
+{
+ if ( impl )
+ IMPL->insertData( offset, arg );
+}
+
+/*!
+ Deletes a substring of length \a count from position \a offset.
+*/
+void TQDomCharacterData::deleteData( unsigned long offset, unsigned long count )
+{
+ if ( impl )
+ IMPL->deleteData( offset, count );
+}
+
+/*!
+ Replaces the substring of length \a count starting at position \a
+ offset with the string \a arg.
+*/
+void TQDomCharacterData::tqreplaceData( unsigned long offset, unsigned long count, const TQString& arg )
+{
+ if ( impl )
+ IMPL->tqreplaceData( offset, count, arg );
+}
+
+/*!
+ Returns the type of node this object refers to (i.e. \c TextNode,
+ \c CDATASectionNode, \c CommentNode or \c CharacterDataNode). For
+ a \link isNull() null node\endlink \c CharacterDataNode is
+ returned.
+*/
+TQDomNode::NodeType TQDomCharacterData::nodeType() const
+{
+ if( !impl )
+ return CharacterDataNode;
+ return TQDomNode::nodeType();
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomCharacterData::isCharacterData() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomAttrPrivate
+ *
+ **************************************************************/
+
+TQDomAttrPrivate::TQDomAttrPrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* tqparent, const TQString& name_ )
+ : TQDomNodePrivate( d, tqparent )
+{
+ name = name_;
+ m_specified = FALSE;
+}
+
+TQDomAttrPrivate::TQDomAttrPrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* p, const TQString& nsURI, const TQString& qName )
+ : TQDomNodePrivate( d, p )
+{
+ qt_split_namespace( prefix, name, qName, !nsURI.isNull() );
+ namespaceURI = nsURI;
+ createdWithDom1Interface = FALSE;
+ m_specified = FALSE;
+}
+
+TQDomAttrPrivate::TQDomAttrPrivate( TQDomAttrPrivate* n, bool deep )
+ : TQDomNodePrivate( n, deep )
+{
+ m_specified = n->specified();
+}
+
+TQDomAttrPrivate::~TQDomAttrPrivate()
+{
+}
+
+void TQDomAttrPrivate::setNodeValue( const TQString& v )
+{
+ value = v;
+ TQDomTextPrivate *t = new TQDomTextPrivate( 0, this, v );
+ // keep the refcount balanced: appendChild() does a ref() anyway.
+ t->deref();
+ if ( first ) {
+ delete removeChild( first );
+ }
+ appendChild( t );
+}
+
+TQDomNodePrivate* TQDomAttrPrivate::cloneNode( bool deep )
+{
+ TQDomNodePrivate* p = new TQDomAttrPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+bool TQDomAttrPrivate::specified() const
+{
+ return m_specified;
+}
+
+static bool isXmlChar(const TQChar &c)
+{
+ // Characters in this range must be accepted by XML parsers.
+ // Consequently characters outside of this range need to be escaped.
+
+ ushort uc = c.tqunicode();
+
+ return uc == 0x9
+ || uc == 0xA
+ || uc == 0xD
+ || (0x20 <= uc && uc <= 0xD7FF)
+ || (0xE000 <= uc && uc <= 0xFFFD);
+}
+
+/*
+ Encode an attribute value upon saving.
+*/
+static TQString encodeAttr( const TQString& str )
+{
+ TQString tmp( str );
+ uint len = tmp.length();
+ uint i = 0;
+ while ( i < len ) {
+ if ( tmp[(int)i] == '<' ) {
+ tmp.tqreplace( i, 1, "&lt;" );
+ len += 3;
+ i += 4;
+ } else if ( tmp[(int)i] == '"' ) {
+ tmp.tqreplace( i, 1, "&quot;" );
+ len += 5;
+ i += 6;
+ } else if ( tmp[(int)i] == '&' ) {
+ tmp.tqreplace( i, 1, "&amp;" );
+ len += 4;
+ i += 5;
+ } else if ( tmp[(int)i] == '>' && i>=2 && tmp[(int)i-1]==']' && tmp[(int)i-2]==']' ) {
+ tmp.tqreplace( i, 1, "&gt;" );
+ len += 3;
+ i += 4;
+ } else if (!isXmlChar(tmp[(int)i])) {
+ TQString repl = "&#x" + TQString::number(tmp[(int)i].tqunicode(), 16) + ';';
+ qWarning("TQDom: saving invalid character %s, the document will not be well-formed", repl.latin1());
+ tmp.tqreplace(i, 1, repl);
+ len += repl.length() - 1;
+ i += repl.length();
+ } else {
+ ++i;
+ }
+ }
+
+ return tmp;
+}
+
+void TQDomAttrPrivate::save( TQTextStream& s, int, int ) const
+{
+ if ( namespaceURI.isNull() ) {
+ s << name << "=\"" << encodeAttr( value ) << "\"";
+ } else {
+ // ### optimize this (see comment of TQDomElementPrivate::save()
+ s << prefix << ":" << name << "=\"" << encodeAttr( value ) << "\""
+ << " xmlns:" << prefix << "=\"" << encodeAttr( namespaceURI ) << "\"";
+ }
+}
+
+/**************************************************************
+ *
+ * TQDomAttr
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomAttrPrivate*)impl)
+
+/*!
+ \class TQDomAttr tqdom.h
+ \reentrant
+ \brief The TQDomAttr class represents one attribute of a TQDomElement.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ For example, the following piece of XML produces an element with
+ no tqchildren, but two attributes:
+
+ \code
+ <link href="http://www.trolltech.com" color="red" />
+ \endcode
+
+ You can access the attributes of an element with code like this:
+
+ \code
+ TQDomElement e = //...
+ //...
+ TQDomAttr a = e.attributeNode( "href" );
+ cout << a.value() << endl; // prints "http://www.trolltech.com"
+ a.setValue( "http://doc.trolltech.com" ); // change the node's attribute
+ TQDomAttr a2 = e.attributeNode( "href" );
+ cout << a2.value() << endl; // prints "http://doc.trolltech.com"
+ \endcode
+
+ This example also shows that changing an attribute received from
+ an element changes the attribute of the element. If you do not
+ want to change the value of the element's attribute you must
+ use cloneNode() to get an independent copy of the attribute.
+
+ TQDomAttr can return the name() and value() of an attribute. An
+ attribute's value is set with setValue(). If specified() returns
+ TRUE the value was either set in the document or set with
+ setValue(); otherwise the value hasn't been set. The node this
+ attribute is attached to (if any) is returned by ownerElement().
+
+ For further information about the Document Object Model see
+ \link http://www.w3.org/TR/REC-DOM-Level-1/\endlink and
+ \link http://www.w3.org/TR/DOM-Level-2-Core/\endlink.
+ For a more general introduction of the DOM implementation see the
+ TQDomDocument documentation.
+*/
+
+
+/*!
+ Constructs an empty attribute.
+*/
+TQDomAttr::TQDomAttr()
+{
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomAttr::TQDomAttr( const TQDomAttr& x )
+ : TQDomNode( x )
+{
+}
+
+TQDomAttr::TQDomAttr( TQDomAttrPrivate* n )
+ : TQDomNode( n )
+{
+}
+
+/*!
+ Assigns \a x to this DOM attribute.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomAttr& TQDomAttr::operator= ( const TQDomAttr& x )
+{
+ return (TQDomAttr&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomAttr::~TQDomAttr()
+{
+}
+
+/*!
+ Returns the attribute's name.
+*/
+TQString TQDomAttr::name() const
+{
+ if ( !impl )
+ return TQString::null;
+ return impl->nodeName();
+}
+
+/*!
+ Returns TRUE if the attribute has either been expicitly specified
+ in the XML document or was set by the user with setValue().
+ Returns FALSE if the value hasn't been specified or set.
+
+ \sa setValue()
+*/
+bool TQDomAttr::specified() const
+{
+ if ( !impl )
+ return FALSE;
+ return IMPL->specified();
+}
+
+/*!
+ Returns the element node this attribute is attached to or a \link
+ TQDomNode::isNull() null node\endlink if this attribute is not
+ attached to any element.
+*/
+TQDomElement TQDomAttr::ownerElement() const
+{
+ if ( !impl && !impl->tqparent()->isElement() )
+ return TQDomElement();
+ return TQDomElement( (TQDomElementPrivate*)(impl->tqparent()) );
+}
+
+/*!
+ Returns the value of the attribute or TQString::null if the
+ attribute has not been specified.
+
+ \sa specified() setValue()
+*/
+TQString TQDomAttr::value() const
+{
+ if ( !impl )
+ return TQString::null;
+ return impl->nodeValue();
+}
+
+/*!
+ Sets the attribute's value to \a v.
+
+ \sa value()
+*/
+void TQDomAttr::setValue( const TQString& v )
+{
+ if ( !impl )
+ return;
+ impl->setNodeValue( v );
+ IMPL->m_specified = TRUE;
+}
+
+/*!
+ Returns \link TQDomNode::NodeType AttributeNode\endlink.
+*/
+TQDomNode::NodeType TQDomAttr::nodeType() const
+{
+ return AttributeNode;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomAttr::isAttr() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomElementPrivate
+ *
+ **************************************************************/
+
+TQDomElementPrivate::TQDomElementPrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* p,
+ const TQString& tagname )
+ : TQDomNodePrivate( d, p )
+{
+ name = tagname;
+ m_attr = new TQDomNamedNodeMapPrivate( this );
+}
+
+TQDomElementPrivate::TQDomElementPrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* p,
+ const TQString& nsURI, const TQString& qName )
+ : TQDomNodePrivate( d, p )
+{
+ qt_split_namespace( prefix, name, qName, !nsURI.isNull() );
+ namespaceURI = nsURI;
+ createdWithDom1Interface = FALSE;
+ m_attr = new TQDomNamedNodeMapPrivate( this );
+}
+
+TQDomElementPrivate::TQDomElementPrivate( TQDomElementPrivate* n, bool deep ) :
+ TQDomNodePrivate( n, deep )
+{
+ m_attr = n->m_attr->clone( this );
+ // Reference is down to 0, so we set it to 1 here.
+ m_attr->ref();
+}
+
+TQDomElementPrivate::~TQDomElementPrivate()
+{
+ if ( m_attr->deref() )
+ delete m_attr;
+}
+
+TQDomNodePrivate* TQDomElementPrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomElementPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+TQString TQDomElementPrivate::attribute( const TQString& name_, const TQString& defValue ) const
+{
+ TQDomNodePrivate* n = m_attr->namedItem( name_ );
+ if ( !n )
+ return defValue;
+
+ return n->nodeValue();
+}
+
+TQString TQDomElementPrivate::attributeNS( const TQString& nsURI, const TQString& localName, const TQString& defValue ) const
+{
+ TQDomNodePrivate* n = m_attr->namedItemNS( nsURI, localName );
+ if ( !n )
+ return defValue;
+
+ return n->nodeValue();
+}
+
+void TQDomElementPrivate::setAttribute( const TQString& aname, const TQString& newValue )
+{
+ TQDomNodePrivate* n = m_attr->namedItem( aname );
+ if ( !n ) {
+ n = new TQDomAttrPrivate( ownerDocument(), this, aname );
+ n->setNodeValue( newValue );
+
+ // Referencing is done by the map, so we set the reference counter back
+ // to 0 here. This is ok since we created the TQDomAttrPrivate.
+ n->deref();
+ m_attr->setNamedItem( n );
+ } else {
+ n->setNodeValue( newValue );
+ }
+}
+
+void TQDomElementPrivate::setAttributeNS( const TQString& nsURI, const TQString& qName, const TQString& newValue )
+{
+ TQString prefix, localName;
+ qt_split_namespace( prefix, localName, qName, TRUE );
+ TQDomNodePrivate* n = m_attr->namedItemNS( nsURI, localName );
+ if ( !n ) {
+ n = new TQDomAttrPrivate( ownerDocument(), this, nsURI, qName );
+ n->setNodeValue( newValue );
+
+ // Referencing is done by the map, so we set the reference counter back
+ // to 0 here. This is ok since we created the TQDomAttrPrivate.
+ n->deref();
+ m_attr->setNamedItem( n );
+ } else {
+ n->setNodeValue( newValue );
+ n->prefix = prefix;
+ }
+}
+
+void TQDomElementPrivate::removeAttribute( const TQString& aname )
+{
+ TQDomNodePrivate* p = m_attr->removeNamedItem( aname );
+ if ( p && p->count == 0 )
+ delete p;
+}
+
+TQDomAttrPrivate* TQDomElementPrivate::attributeNode( const TQString& aname )
+{
+ return (TQDomAttrPrivate*)m_attr->namedItem( aname );
+}
+
+TQDomAttrPrivate* TQDomElementPrivate::attributeNodeNS( const TQString& nsURI, const TQString& localName )
+{
+ return (TQDomAttrPrivate*)m_attr->namedItemNS( nsURI, localName );
+}
+
+TQDomAttrPrivate* TQDomElementPrivate::setAttributeNode( TQDomAttrPrivate* newAttr )
+{
+ TQDomNodePrivate* n = m_attr->namedItem( newAttr->nodeName() );
+
+ // Referencing is done by the maps
+ m_attr->setNamedItem( newAttr );
+
+ return (TQDomAttrPrivate*)n;
+}
+
+TQDomAttrPrivate* TQDomElementPrivate::setAttributeNodeNS( TQDomAttrPrivate* newAttr )
+{
+ TQDomNodePrivate* n = 0;
+ if ( !newAttr->prefix.isNull() )
+ n = m_attr->namedItemNS( newAttr->namespaceURI, newAttr->name );
+
+ // Referencing is done by the maps
+ m_attr->setNamedItem( newAttr );
+
+ return (TQDomAttrPrivate*)n;
+}
+
+TQDomAttrPrivate* TQDomElementPrivate::removeAttributeNode( TQDomAttrPrivate* oldAttr )
+{
+ return (TQDomAttrPrivate*)m_attr->removeNamedItem( oldAttr->nodeName() );
+}
+
+bool TQDomElementPrivate::hasAttribute( const TQString& aname )
+{
+ return m_attr->tqcontains( aname );
+}
+
+bool TQDomElementPrivate::hasAttributeNS( const TQString& nsURI, const TQString& localName )
+{
+ return m_attr->tqcontainsNS( nsURI, localName );
+}
+
+TQString TQDomElementPrivate::text()
+{
+ TQString t( "" );
+
+ TQDomNodePrivate* p = first;
+ while ( p ) {
+ if ( p->isText() || p->isCDATASection() )
+ t += p->nodeValue();
+ else if ( p->isElement() )
+ t += ((TQDomElementPrivate*)p)->text();
+ p = p->next;
+ }
+
+ return t;
+}
+
+void TQDomElementPrivate::save( TQTextStream& s, int depth, int indent ) const
+{
+ if ( !( prev && prev->isText() ) )
+ for ( int i = 0; i < depth*indent; ++i )
+ s << " ";
+
+ TQString qName( name );
+ TQString nsDecl( "" );
+ if ( !namespaceURI.isNull() ) {
+ // ### optimize this, so that you only declare namespaces that are not
+ // yet declared -- we loose default namespace mappings, so maybe we
+ // should rather store the information that we get from
+ // startPrefixMapping()/endPrefixMapping() and use them (you have to
+ // take care if the DOM tree is modified, though)
+ if ( prefix.isEmpty() ) {
+ nsDecl = " xmlns";
+ } else {
+ qName = prefix + ":" + name;
+ nsDecl = " xmlns:" + prefix;
+ }
+ nsDecl += "=\"" + encodeAttr( namespaceURI ) + "\"";
+ }
+ s << "<" << qName << nsDecl;
+
+ if ( !m_attr->map.isEmpty() ) {
+ s << " ";
+ TQDictIterator<TQDomNodePrivate> it( m_attr->map );
+ for ( ; it.current(); ++it ) {
+ it.current()->save( s, 0, indent );
+ s << " ";
+ }
+ }
+
+ if ( last ) {
+ // has child nodes
+ if ( first->isText() )
+ s << ">";
+ else
+ s << ">" << endl;
+ TQDomNodePrivate::save( s, depth + 1, indent);
+ if ( !last->isText() )
+ for( int i = 0; i < depth*indent; ++i )
+ s << " ";
+
+ s << "</" << qName << ">";
+ } else {
+ s << "/>";
+ }
+ if ( !( next && next->isText() ) )
+ s << endl;
+}
+
+/**************************************************************
+ *
+ * TQDomElement
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomElementPrivate*)impl)
+
+/*!
+ \class TQDomElement tqdom.h
+ \reentrant
+ \brief The TQDomElement class represents one element in the DOM tree.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ Elements have a tagName() and zero or more attributes associated
+ with them. The tag name can be changed with setTagName().
+
+ Element attributes are represented by TQDomAttr objects that can
+ be queried using the attribute() and attributeNode() functions.
+ You can set attributes with the setAttribute() and
+ setAttributeNode() functions. Attributes can be removed with
+ removeAttribute(). There are namespace-aware equivalents to these
+ functions, i.e. setAttributeNS(), setAttributeNodeNS() and
+ removeAttributeNS().
+
+ If you want to access the text of a node use text(), e.g.
+ \code
+ TQDomElement e = //...
+ //...
+ TQString s = e.text()
+ \endcode
+ The text() function operates recursively to tqfind the text (since
+ not all elements contain text). If you want to tqfind all the text
+ in all of a node's tqchildren, iterate over the tqchildren looking for
+ TQDomText nodes, e.g.
+ \code
+ TQString text;
+ TQDomElement element = doc.documentElement();
+ for( TQDomNode n = element.firstChild(); !n.isNull(); n = n.nextSibling() )
+ {
+ TQDomText t = n.toText();
+ if ( !t.isNull() )
+ text += t.data();
+ }
+ \endcode
+ Note that we attempt to convert each node to a text node and use
+ text() rather than using firstChild().toText().data() or
+ n.toText().data() directly on the node, because the node may not
+ be a text element.
+
+ You can get a list of all the decendents of an element which have
+ a specified tag name with elementsByTagName() or
+ elementsByTagNameNS().
+
+ For further information about the Document Object Model see
+ \link http://www.w3.org/TR/REC-DOM-Level-1/\endlink and
+ \link http://www.w3.org/TR/DOM-Level-2-Core/\endlink.
+ For a more general introduction of the DOM implementation see the
+ TQDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty element. Use the TQDomDocument::createElement()
+ function to construct elements with content.
+*/
+TQDomElement::TQDomElement()
+ : TQDomNode()
+{
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomElement::TQDomElement( const TQDomElement& x )
+ : TQDomNode( x )
+{
+}
+
+TQDomElement::TQDomElement( TQDomElementPrivate* n )
+ : TQDomNode( n )
+{
+}
+
+/*!
+ Assigns \a x to this DOM element.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomElement& TQDomElement::operator= ( const TQDomElement& x )
+{
+ return (TQDomElement&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomElement::~TQDomElement()
+{
+}
+
+/*!
+ Returns \c ElementNode.
+*/
+TQDomNode::NodeType TQDomElement::nodeType() const
+{
+ return ElementNode;
+}
+
+/*!
+ Sets this element's tag name to \a name.
+
+ \sa tagName()
+*/
+void TQDomElement::setTagName( const TQString& name )
+{
+ if ( impl )
+ impl->name = name;
+}
+
+/*!
+ Returns the tag name of this element. For an XML element like this:
+ \code
+ <img src="myimg.png">
+ \endcode
+ the tagname would return "img".
+
+ \sa setTagName()
+*/
+TQString TQDomElement::tagName() const
+{
+ if ( !impl )
+ return TQString::null;
+ return impl->nodeName();
+}
+
+/*!
+ Returns the attribute called \a name. If the attribute does not
+ exist \a defValue is returned.
+
+ \sa setAttribute() attributeNode() setAttributeNode() attributeNS()
+*/
+TQString TQDomElement::attribute( const TQString& name, const TQString& defValue ) const
+{
+ if ( !impl )
+ return defValue;
+ return IMPL->attribute( name, defValue );
+}
+
+/*!
+ Adds an attribute called \a name with value \a value. If an
+ attribute with the same name exists, its value is tqreplaced by \a
+ value.
+
+ \sa attribute() setAttributeNode() setAttributeNS()
+*/
+void TQDomElement::setAttribute( const TQString& name, const TQString& value )
+{
+ if ( !impl )
+ return;
+ IMPL->setAttribute( name, value );
+}
+
+/*!
+ \overload
+*/
+void TQDomElement::setAttribute( const TQString& name, int value )
+{
+ // ### 4.0: inline
+ setAttribute( name, long(value) );
+}
+
+/*!
+ \overload
+*/
+void TQDomElement::setAttribute( const TQString& name, uint value )
+{
+ // ### 4.0: inline
+ setAttribute( name, ulong(value) );
+}
+
+/*!
+ \overload
+*/
+void TQDomElement::setAttribute( const TQString& name, long value )
+{
+ if ( !impl )
+ return;
+ TQString x;
+ x.setNum( value );
+ IMPL->setAttribute( name, x );
+}
+
+/*!
+ \overload
+*/
+void TQDomElement::setAttribute( const TQString& name, ulong value )
+{
+ if ( !impl )
+ return;
+ TQString x;
+ x.setNum( value );
+ IMPL->setAttribute( name, x );
+}
+
+/*!
+ \overload
+*/
+void TQDomElement::setAttribute( const TQString& name, double value )
+{
+ if ( !impl )
+ return;
+ TQString x;
+ x.setNum( value );
+ IMPL->setAttribute( name, x );
+}
+
+/*!
+ Removes the attribute called name \a name from this element.
+
+ \sa setAttribute() attribute() removeAttributeNS()
+*/
+void TQDomElement::removeAttribute( const TQString& name )
+{
+ if ( !impl )
+ return;
+ IMPL->removeAttribute( name );
+}
+
+/*!
+ Returns the TQDomAttr object that corresponds to the attribute
+ called \a name. If no such attribute exists a \link
+ TQDomNode::isNull() null attribute\endlink is returned.
+
+ \sa setAttributeNode() attribute() setAttribute() attributeNodeNS()
+*/
+TQDomAttr TQDomElement::attributeNode( const TQString& name)
+{
+ if ( !impl )
+ return TQDomAttr();
+ return TQDomAttr( IMPL->attributeNode( name ) );
+}
+
+/*!
+ Adds the attribute \a newAttr to this element.
+
+ If the element has another attribute that has the same name as \a
+ newAttr, this function tqreplaces that attribute and returns it;
+ otherwise the function returns a \link TQDomNode::isNull() null
+ attribute\endlink.
+
+ \sa attributeNode() setAttribute() setAttributeNodeNS()
+*/
+TQDomAttr TQDomElement::setAttributeNode( const TQDomAttr& newAttr )
+{
+ if ( !impl )
+ return TQDomAttr();
+ return TQDomAttr( IMPL->setAttributeNode( ((TQDomAttrPrivate*)newAttr.impl) ) );
+}
+
+/*!
+ Removes the attribute \a oldAttr from the element and returns it.
+
+ \sa attributeNode() setAttributeNode()
+*/
+TQDomAttr TQDomElement::removeAttributeNode( const TQDomAttr& oldAttr )
+{
+ if ( !impl )
+ return TQDomAttr(); // ### should this return oldAttr?
+ return TQDomAttr( IMPL->removeAttributeNode( ((TQDomAttrPrivate*)oldAttr.impl) ) );
+}
+
+/*!
+ Returns a TQDomNodeList containing all descendent elements of this
+ element that are called \a tagname. The order they are in the node
+ list is the order they are encountered in a preorder traversal of
+ the element tree.
+
+ \sa elementsByTagNameNS() TQDomDocument::elementsByTagName()
+*/
+TQDomNodeList TQDomElement::elementsByTagName( const TQString& tagname ) const
+{
+ return TQDomNodeList( new TQDomNodeListPrivate( impl, tagname ) );
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomElement::isElement() const
+{
+ return TRUE;
+}
+
+/*!
+ Returns a TQDomNamedNodeMap containing all this element's attributes.
+
+ \sa attribute() setAttribute() attributeNode() setAttributeNode()
+*/
+TQDomNamedNodeMap TQDomElement::attributes() const
+{
+ if ( !impl )
+ return TQDomNamedNodeMap();
+ return TQDomNamedNodeMap( IMPL->attributes() );
+}
+
+/*!
+ Returns TRUE if this element has an attribute called \a name;
+ otherwise returns FALSE.
+*/
+bool TQDomElement::hasAttribute( const TQString& name ) const
+{
+ if ( !impl )
+ return FALSE;
+ return IMPL->hasAttribute( name );
+}
+
+/*!
+ Returns the attribute with the local name \a localName and the
+ namespace URI \a nsURI. If the attribute does not exist \a
+ defValue is returned.
+
+ \sa setAttributeNS() attributeNodeNS() setAttributeNodeNS() attribute()
+*/
+TQString TQDomElement::attributeNS( const TQString nsURI, const TQString& localName, const TQString& defValue ) const
+{
+ if ( !impl )
+ return defValue;
+ return IMPL->attributeNS( nsURI, localName, defValue );
+}
+
+/*!
+ Adds an attribute with the qualified name \a qName and the
+ namespace URI \a nsURI with the value \a value. If an attribute
+ with the same local name and namespace URI exists, its prefix is
+ tqreplaced by the prefix of \a qName and its value is repaced by \a
+ value.
+
+ Although \a qName is the qualified name, the local name is used to
+ decide if an existing attribute's value should be tqreplaced.
+
+ \sa attributeNS() setAttributeNodeNS() setAttribute()
+*/
+void TQDomElement::setAttributeNS( const TQString nsURI, const TQString& qName, const TQString& value )
+{
+ if ( !impl )
+ return;
+ IMPL->setAttributeNS( nsURI, qName, value );
+}
+
+/*!
+ \overload
+*/
+void TQDomElement::setAttributeNS( const TQString nsURI, const TQString& qName, int value )
+{
+ // ### 4.0: inline
+ setAttributeNS( nsURI, qName, long(value) );
+}
+
+/*!
+ \overload
+*/
+void TQDomElement::setAttributeNS( const TQString nsURI, const TQString& qName, uint value )
+{
+ // ### 4.0: inline
+ setAttributeNS( nsURI, qName, ulong(value) );
+}
+
+/*!
+ \overload
+*/
+void TQDomElement::setAttributeNS( const TQString nsURI, const TQString& qName, long value )
+{
+ if ( !impl )
+ return;
+ TQString x;
+ x.setNum( value );
+ IMPL->setAttributeNS( nsURI, qName, x );
+}
+
+/*!
+ \overload
+*/
+void TQDomElement::setAttributeNS( const TQString nsURI, const TQString& qName, ulong value )
+{
+ if ( !impl )
+ return;
+ TQString x;
+ x.setNum( value );
+ IMPL->setAttributeNS( nsURI, qName, x );
+}
+
+/*!
+ \overload
+*/
+void TQDomElement::setAttributeNS( const TQString nsURI, const TQString& qName, double value )
+{
+ if ( !impl )
+ return;
+ TQString x;
+ x.setNum( value );
+ IMPL->setAttributeNS( nsURI, qName, x );
+}
+
+/*!
+ Removes the attribute with the local name \a localName and the
+ namespace URI \a nsURI from this element.
+
+ \sa setAttributeNS() attributeNS() removeAttribute()
+*/
+void TQDomElement::removeAttributeNS( const TQString& nsURI, const TQString& localName )
+{
+ if ( !impl )
+ return;
+ TQDomNodePrivate *n = IMPL->attributeNodeNS( nsURI, localName );
+ if ( !n )
+ return;
+ IMPL->removeAttribute( n->nodeName() );
+}
+
+/*!
+ Returns the TQDomAttr object that corresponds to the attribute with
+ the local name \a localName and the namespace URI \a nsURI. If no
+ such attribute exists a \link TQDomNode::isNull() null
+ attribute\endlink is returned.
+
+ \sa setAttributeNode() attribute() setAttribute() attributeNodeNS()
+*/
+TQDomAttr TQDomElement::attributeNodeNS( const TQString& nsURI, const TQString& localName )
+{
+ if ( !impl )
+ return TQDomAttr();
+ return TQDomAttr( IMPL->attributeNodeNS( nsURI, localName ) );
+}
+
+/*!
+ Adds the attribute \a newAttr to this element.
+
+ If the element has another attribute that has the same local name
+ and namespace URI as \a newAttr, this function tqreplaces that
+ attribute and returns it; otherwise the function returns a \link
+ TQDomNode::isNull() null attribute\endlink.
+
+ \sa attributeNodeNS() setAttributeNS() setAttributeNode()
+*/
+TQDomAttr TQDomElement::setAttributeNodeNS( const TQDomAttr& newAttr )
+{
+ if ( !impl )
+ return TQDomAttr();
+ return TQDomAttr( IMPL->setAttributeNodeNS( ((TQDomAttrPrivate*)newAttr.impl) ) );
+}
+
+/*!
+ Returns a TQDomNodeList containing all the descendent elements of
+ this element with the local name \a localName and the namespace
+ URI \a nsURI. The order they are in the node list is the order
+ they are encountered in a preorder traversal of the element tree.
+
+ \sa elementsByTagName() TQDomDocument::elementsByTagNameNS()
+*/
+TQDomNodeList TQDomElement::elementsByTagNameNS( const TQString& nsURI, const TQString& localName ) const
+{
+ return TQDomNodeList( new TQDomNodeListPrivate( impl, nsURI, localName ) );
+}
+
+/*!
+ Returns TRUE if this element has an attribute with the local name
+ \a localName and the namespace URI \a nsURI; otherwise returns
+ FALSE.
+*/
+bool TQDomElement::hasAttributeNS( const TQString& nsURI, const TQString& localName ) const
+{
+ if ( !impl )
+ return FALSE;
+ return IMPL->hasAttributeNS( nsURI, localName );
+}
+
+/*!
+ Returns the element's text or TQString::null.
+
+ Example:
+ \code
+ <h1>Hello <b>TQt</b> <![CDATA[<xml is cool>]]></h1>
+ \endcode
+
+ The function text() of the TQDomElement for the &lt;h1&gt; tag,
+ will return "Hello TQt &lt;xml is cool&gt;".
+
+ Comments are ignored by this function. It only evaluates TQDomText
+ and TQDomCDATASection objects.
+*/
+TQString TQDomElement::text() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->text();
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomTextPrivate
+ *
+ **************************************************************/
+
+TQDomTextPrivate::TQDomTextPrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* tqparent, const TQString& value )
+ : TQDomCharacterDataPrivate( d, tqparent, value )
+{
+ name = "#text";
+}
+
+TQDomTextPrivate::TQDomTextPrivate( TQDomTextPrivate* n, bool deep )
+ : TQDomCharacterDataPrivate( n, deep )
+{
+}
+
+TQDomTextPrivate::~TQDomTextPrivate()
+{
+}
+
+TQDomNodePrivate* TQDomTextPrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomTextPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+TQDomTextPrivate* TQDomTextPrivate::splitText( int offset )
+{
+ if ( !tqparent() ) {
+ qWarning( "TQDomText::splitText The node has no tqparent. So I can not split" );
+ return 0;
+ }
+
+ TQDomTextPrivate* t = new TQDomTextPrivate( ownerDocument(), 0, value.mid( offset ) );
+ value.truncate( offset );
+
+ tqparent()->insertAfter( t, this );
+
+ return t;
+}
+
+void TQDomTextPrivate::save( TQTextStream& s, int, int ) const
+{
+ s << encodeAttr( value );
+}
+
+/**************************************************************
+ *
+ * TQDomText
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomTextPrivate*)impl)
+
+/*!
+ \class TQDomText tqdom.h
+ \reentrant
+ \brief The TQDomText class represents text data in the parsed XML document.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ You can split the text in a TQDomText object over two TQDomText
+ objecs with splitText().
+
+ For further information about the Document Object Model see
+ \link http://www.w3.org/TR/REC-DOM-Level-1/\endlink and
+ \link http://www.w3.org/TR/DOM-Level-2-Core/\endlink.
+ For a more general introduction of the DOM implementation see the
+ TQDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty TQDomText object.
+
+ To construct a TQDomText with content, use TQDomDocument::createTextNode().
+*/
+TQDomText::TQDomText()
+ : TQDomCharacterData()
+{
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomText::TQDomText( const TQDomText& x )
+ : TQDomCharacterData( x )
+{
+}
+
+TQDomText::TQDomText( TQDomTextPrivate* n )
+ : TQDomCharacterData( n )
+{
+}
+
+/*!
+ Assigns \a x to this DOM text.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomText& TQDomText::operator= ( const TQDomText& x )
+{
+ return (TQDomText&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomText::~TQDomText()
+{
+}
+
+/*!
+ Returns \c TextNode.
+*/
+TQDomNode::NodeType TQDomText::nodeType() const
+{
+ return TextNode;
+}
+
+/*!
+ Splits this DOM text object into two TQDomText objects. This object
+ keeps its first \a offset characters and the second (newly
+ created) object is inserted into the document tree after this
+ object with the remaining characters.
+
+ The function returns the newly created object.
+
+ \sa TQDomNode::normalize()
+*/
+TQDomText TQDomText::splitText( int offset )
+{
+ if ( !impl )
+ return TQDomText();
+ return TQDomText( IMPL->splitText( offset ) );
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomText::isText() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomCommentPrivate
+ *
+ **************************************************************/
+
+TQDomCommentPrivate::TQDomCommentPrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* tqparent, const TQString& value )
+ : TQDomCharacterDataPrivate( d, tqparent, value )
+{
+ name = "#comment";
+}
+
+TQDomCommentPrivate::TQDomCommentPrivate( TQDomCommentPrivate* n, bool deep )
+ : TQDomCharacterDataPrivate( n, deep )
+{
+}
+
+TQDomCommentPrivate::~TQDomCommentPrivate()
+{
+}
+
+TQDomNodePrivate* TQDomCommentPrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomCommentPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void TQDomCommentPrivate::save( TQTextStream& s, int, int ) const
+{
+ s << "<!--" << value << "-->";
+}
+
+/**************************************************************
+ *
+ * TQDomComment
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomCommentPrivate*)impl)
+
+/*!
+ \class TQDomComment tqdom.h
+ \reentrant
+ \brief The TQDomComment class represents an XML comment.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ A comment in the parsed XML such as this:
+ \code
+ <!-- this is a comment -->
+ \endcode
+ is represented by TQDomComment objects in the parsed Dom tree.
+
+ For further information about the Document Object Model see
+ \link http://www.w3.org/TR/REC-DOM-Level-1/\endlink and
+ \link http://www.w3.org/TR/DOM-Level-2-Core/\endlink.
+ For a more general introduction of the DOM implementation see the
+ TQDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty comment. To construct a comment with content,
+ use the TQDomDocument::createComment() function.
+*/
+TQDomComment::TQDomComment()
+ : TQDomCharacterData()
+{
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomComment::TQDomComment( const TQDomComment& x )
+ : TQDomCharacterData( x )
+{
+}
+
+TQDomComment::TQDomComment( TQDomCommentPrivate* n )
+ : TQDomCharacterData( n )
+{
+}
+
+/*!
+ Assigns \a x to this DOM comment.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomComment& TQDomComment::operator= ( const TQDomComment& x )
+{
+ return (TQDomComment&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomComment::~TQDomComment()
+{
+}
+
+/*!
+ Returns \c CommentNode.
+*/
+TQDomNode::NodeType TQDomComment::nodeType() const
+{
+ return CommentNode;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomComment::isComment() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomCDATASectionPrivate
+ *
+ **************************************************************/
+
+TQDomCDATASectionPrivate::TQDomCDATASectionPrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* tqparent,
+ const TQString& value )
+ : TQDomTextPrivate( d, tqparent, value )
+{
+ name = "#cdata-section";
+}
+
+TQDomCDATASectionPrivate::TQDomCDATASectionPrivate( TQDomCDATASectionPrivate* n, bool deep )
+ : TQDomTextPrivate( n, deep )
+{
+}
+
+TQDomCDATASectionPrivate::~TQDomCDATASectionPrivate()
+{
+}
+
+TQDomNodePrivate* TQDomCDATASectionPrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomCDATASectionPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void TQDomCDATASectionPrivate::save( TQTextStream& s, int, int ) const
+{
+ // ### How do we escape "]]>" ?
+ // "]]>" is not allowed; so there should be none in value anyway
+ s << "<![CDATA[" << value << "]]>";
+}
+
+/**************************************************************
+ *
+ * TQDomCDATASection
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomCDATASectionPrivate*)impl)
+
+/*!
+ \class TQDomCDATASection tqdom.h
+ \reentrant
+ \brief The TQDomCDATASection class represents an XML CDATA section.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ CDATA sections are used to escape blocks of text containing
+ characters that would otherwise be regarded as markup. The only
+ delimiter that is recognized in a CDATA section is the "]]&gt;"
+ string that terminates the CDATA section. CDATA sections cannot be
+ nested. Their primary purpose is for including material such as
+ XML fragments, without needing to escape all the delimiters.
+
+ Adjacent TQDomCDATASection nodes are not merged by the
+ TQDomNode::normalize() function.
+
+ For further information about the Document Object Model see
+ \link http://www.w3.org/TR/REC-DOM-Level-1/\endlink and
+ \link http://www.w3.org/TR/DOM-Level-2-Core/\endlink.
+ For a more general introduction of the DOM implementation see the
+ TQDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty CDATA section. To create a CDATA section with
+ content, use the TQDomDocument::createCDATASection() function.
+*/
+TQDomCDATASection::TQDomCDATASection()
+ : TQDomText()
+{
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomCDATASection::TQDomCDATASection( const TQDomCDATASection& x )
+ : TQDomText( x )
+{
+}
+
+TQDomCDATASection::TQDomCDATASection( TQDomCDATASectionPrivate* n )
+ : TQDomText( n )
+{
+}
+
+/*!
+ Assigns \a x to this CDATA section.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomCDATASection& TQDomCDATASection::operator= ( const TQDomCDATASection& x )
+{
+ return (TQDomCDATASection&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomCDATASection::~TQDomCDATASection()
+{
+}
+
+/*!
+ Returns \c CDATASection.
+*/
+TQDomNode::NodeType TQDomCDATASection::nodeType() const
+{
+ return CDATASectionNode;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomCDATASection::isCDATASection() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomNotationPrivate
+ *
+ **************************************************************/
+
+TQDomNotationPrivate::TQDomNotationPrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* tqparent,
+ const TQString& aname,
+ const TQString& pub, const TQString& sys )
+ : TQDomNodePrivate( d, tqparent )
+{
+ name = aname;
+ m_pub = pub;
+ m_sys = sys;
+}
+
+TQDomNotationPrivate::TQDomNotationPrivate( TQDomNotationPrivate* n, bool deep )
+ : TQDomNodePrivate( n, deep )
+{
+ m_sys = n->m_sys;
+ m_pub = n->m_pub;
+}
+
+TQDomNotationPrivate::~TQDomNotationPrivate()
+{
+}
+
+TQDomNodePrivate* TQDomNotationPrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomNotationPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void TQDomNotationPrivate::save( TQTextStream& s, int, int ) const
+{
+ s << "<!NOTATION " << name << " ";
+ if ( !m_pub.isNull() ) {
+ s << "PUBLIC \"" << m_pub << "\"";
+ if ( !m_sys.isNull() )
+ s << " \"" << m_sys << "\"";
+ } else {
+ s << "SYSTEM \"" << m_sys << "\"";
+ }
+ s << ">" << endl;
+}
+
+/**************************************************************
+ *
+ * TQDomNotation
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomNotationPrivate*)impl)
+
+/*!
+ \class TQDomNotation tqdom.h
+ \reentrant
+ \brief The TQDomNotation class represents an XML notation.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ A notation either declares, by name, the format of an unparsed
+ entity (see section 4.7 of the XML 1.0 specification), or is used
+ for formal declaration of processing instruction targets (see
+ section 2.6 of the XML 1.0 specification).
+
+ DOM does not support editing notation nodes; they are therefore
+ read-only.
+
+ A notation node does not have any tqparent.
+
+ You can retrieve the publicId() and systemId() from a notation
+ node.
+
+ For further information about the Document Object Model see
+ \link http://www.w3.org/TR/REC-DOM-Level-1/\endlink and
+ \link http://www.w3.org/TR/DOM-Level-2-Core/\endlink.
+ For a more general introduction of the DOM implementation see the
+ TQDomDocument documentation.
+*/
+
+
+/*!
+ Constructor.
+*/
+TQDomNotation::TQDomNotation()
+ : TQDomNode()
+{
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomNotation::TQDomNotation( const TQDomNotation& x )
+ : TQDomNode( x )
+{
+}
+
+TQDomNotation::TQDomNotation( TQDomNotationPrivate* n )
+ : TQDomNode( n )
+{
+}
+
+/*!
+ Assigns \a x to this DOM notation.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomNotation& TQDomNotation::operator= ( const TQDomNotation& x )
+{
+ return (TQDomNotation&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomNotation::~TQDomNotation()
+{
+}
+
+/*!
+ Returns \c NotationNode.
+*/
+TQDomNode::NodeType TQDomNotation::nodeType() const
+{
+ return NotationNode;
+}
+
+/*!
+ Returns the public identifier of this notation.
+*/
+TQString TQDomNotation::publicId() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->m_pub;
+}
+
+/*!
+ Returns the system identifier of this notation.
+*/
+TQString TQDomNotation::systemId() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->m_sys;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomNotation::isNotation() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomEntityPrivate
+ *
+ **************************************************************/
+
+TQDomEntityPrivate::TQDomEntityPrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* tqparent,
+ const TQString& aname,
+ const TQString& pub, const TQString& sys, const TQString& notation )
+ : TQDomNodePrivate( d, tqparent )
+{
+ name = aname;
+ m_pub = pub;
+ m_sys = sys;
+ m_notationName = notation;
+}
+
+TQDomEntityPrivate::TQDomEntityPrivate( TQDomEntityPrivate* n, bool deep )
+ : TQDomNodePrivate( n, deep )
+{
+ m_sys = n->m_sys;
+ m_pub = n->m_pub;
+ m_notationName = n->m_notationName;
+}
+
+TQDomEntityPrivate::~TQDomEntityPrivate()
+{
+}
+
+TQDomNodePrivate* TQDomEntityPrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomEntityPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+/*
+ Encode an entity value upon saving.
+*/
+static TQCString encodeEntity( const TQCString& str )
+{
+ TQCString tmp( str );
+ uint len = tmp.length();
+ uint i = 0;
+ const char* d = tmp.data();
+ while ( i < len ) {
+ if ( d[i] == '%' ){
+ tmp.tqreplace( i, 1, "&#60;" );
+ d = tmp.data();
+ len += 4;
+ i += 5;
+ }
+ else if ( d[i] == '"' ) {
+ tmp.tqreplace( i, 1, "&#34;" );
+ d = tmp.data();
+ len += 4;
+ i += 5;
+ } else if ( d[i] == '&' && i + 1 < len && d[i+1] == '#' ) {
+ // Dont encode &lt; or &quot; or &custom;.
+ // Only encode character references
+ tmp.tqreplace( i, 1, "&#38;" );
+ d = tmp.data();
+ len += 4;
+ i += 5;
+ } else {
+ ++i;
+ }
+ }
+
+ return tmp;
+}
+
+void TQDomEntityPrivate::save( TQTextStream& s, int, int ) const
+{
+ if ( m_sys.isNull() && m_pub.isNull() ) {
+ s << "<!ENTITY " << name << " \"" << encodeEntity( value.utf8() ) << "\">" << endl;
+ } else {
+ s << "<!ENTITY " << name << " ";
+ if ( m_pub.isNull() ) {
+ s << "SYSTEM \"" << m_sys << "\"";
+ } else {
+ s << "PUBLIC \"" << m_pub << "\" \"" << m_sys << "\"";
+ }
+ if (! m_notationName.isNull() ) {
+ s << " NDATA " << m_notationName;
+ }
+ s << ">" << endl;
+ }
+}
+
+/**************************************************************
+ *
+ * TQDomEntity
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomEntityPrivate*)impl)
+
+/*!
+ \class TQDomEntity tqdom.h
+ \reentrant
+ \brief The TQDomEntity class represents an XML entity.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ This class represents an entity in an XML document, either parsed
+ or unparsed. Note that this models the entity itself not the
+ entity declaration.
+
+ DOM does not support editing entity nodes; if a user wants to make
+ changes to the contents of an entity, every related
+ TQDomEntityReference node must be tqreplaced in the DOM tree by a
+ clone of the entity's contents, and then the desired changes must
+ be made to each of the clones instead. All the descendents of an
+ entity node are read-only.
+
+ An entity node does not have any tqparent.
+
+ You can access the entity's publicId(), systemId() and
+ notationName() when available.
+
+ For further information about the Document Object Model see
+ \link http://www.w3.org/TR/REC-DOM-Level-1/\endlink and
+ \link http://www.w3.org/TR/DOM-Level-2-Core/\endlink.
+ For a more general introduction of the DOM implementation see the
+ TQDomDocument documentation.
+*/
+
+
+/*!
+ Constructs an empty entity.
+*/
+TQDomEntity::TQDomEntity()
+ : TQDomNode()
+{
+}
+
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomEntity::TQDomEntity( const TQDomEntity& x )
+ : TQDomNode( x )
+{
+}
+
+TQDomEntity::TQDomEntity( TQDomEntityPrivate* n )
+ : TQDomNode( n )
+{
+}
+
+/*!
+ Assigns \a x to this DOM entity.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomEntity& TQDomEntity::operator= ( const TQDomEntity& x )
+{
+ return (TQDomEntity&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomEntity::~TQDomEntity()
+{
+}
+
+/*!
+ Returns \c EntityNode.
+*/
+TQDomNode::NodeType TQDomEntity::nodeType() const
+{
+ return EntityNode;
+}
+
+/*!
+ Returns the public identifier associated with this entity. If the
+ public identifier was not specified TQString::null is returned.
+*/
+TQString TQDomEntity::publicId() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->m_pub;
+}
+
+/*!
+ Returns the system identifier associated with this entity. If the
+ system identifier was not specified TQString::null is returned.
+*/
+TQString TQDomEntity::systemId() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->m_sys;
+}
+
+/*!
+ For unparsed entities this function returns the name of the
+ notation for the entity. For parsed entities this function returns
+ TQString::null.
+*/
+TQString TQDomEntity::notationName() const
+{
+ if ( !impl )
+ return TQString::null;
+ return IMPL->m_notationName;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomEntity::isEntity() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomEntityReferencePrivate
+ *
+ **************************************************************/
+
+TQDomEntityReferencePrivate::TQDomEntityReferencePrivate( TQDomDocumentPrivate* d, TQDomNodePrivate* tqparent, const TQString& aname )
+ : TQDomNodePrivate( d, tqparent )
+{
+ name = aname;
+}
+
+TQDomEntityReferencePrivate::TQDomEntityReferencePrivate( TQDomNodePrivate* n, bool deep )
+ : TQDomNodePrivate( n, deep )
+{
+}
+
+TQDomEntityReferencePrivate::~TQDomEntityReferencePrivate()
+{
+}
+
+TQDomNodePrivate* TQDomEntityReferencePrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomEntityReferencePrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void TQDomEntityReferencePrivate::save( TQTextStream& s, int, int ) const
+{
+ s << "&" << name << ";";
+}
+
+/**************************************************************
+ *
+ * TQDomEntityReference
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomEntityReferencePrivate*)impl)
+
+/*!
+ \class TQDomEntityReference tqdom.h
+ \reentrant
+ \brief The TQDomEntityReference class represents an XML entity reference.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ A TQDomEntityReference object may be inserted into the DOM tree
+ when an entity reference is in the source document, or when the
+ user wishes to insert an entity reference.
+
+ Note that character references and references to predefined
+ entities are expanded by the XML processor so that characters are
+ represented by their Unicode equivalent rather than by an entity
+ reference.
+
+ Moreover, the XML processor may completely expand references to
+ entities while building the DOM tree, instead of providing
+ TQDomEntityReference objects.
+
+ If it does provide such objects, then for a given entity reference
+ node, it may be that there is no entity node representing the
+ referenced entity; but if such an entity exists, then the child
+ list of the entity reference node is the same as that of the
+ entity node. As with the entity node, all descendents of the
+ entity reference are read-only.
+
+ For further information about the Document Object Model see
+ \link http://www.w3.org/TR/REC-DOM-Level-1/\endlink and
+ \link http://www.w3.org/TR/DOM-Level-2-Core/\endlink.
+ For a more general introduction of the DOM implementation see the
+ TQDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty entity reference. Use
+ TQDomDocument::createEntityReference() to create a entity reference
+ with content.
+*/
+TQDomEntityReference::TQDomEntityReference()
+ : TQDomNode()
+{
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomEntityReference::TQDomEntityReference( const TQDomEntityReference& x )
+ : TQDomNode( x )
+{
+}
+
+TQDomEntityReference::TQDomEntityReference( TQDomEntityReferencePrivate* n )
+ : TQDomNode( n )
+{
+}
+
+/*!
+ Assigns \a x to this entity reference.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomEntityReference& TQDomEntityReference::operator= ( const TQDomEntityReference& x )
+{
+ return (TQDomEntityReference&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomEntityReference::~TQDomEntityReference()
+{
+}
+
+/*!
+ Returns \c EntityReference.
+*/
+TQDomNode::NodeType TQDomEntityReference::nodeType() const
+{
+ return EntityReferenceNode;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomEntityReference::isEntityReference() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomProcessingInstructionPrivate
+ *
+ **************************************************************/
+
+TQDomProcessingInstructionPrivate::TQDomProcessingInstructionPrivate( TQDomDocumentPrivate* d,
+ TQDomNodePrivate* tqparent, const TQString& target, const TQString& data )
+ : TQDomNodePrivate( d, tqparent )
+{
+ name = target;
+ value = data;
+}
+
+TQDomProcessingInstructionPrivate::TQDomProcessingInstructionPrivate( TQDomProcessingInstructionPrivate* n, bool deep )
+ : TQDomNodePrivate( n, deep )
+{
+}
+
+TQDomProcessingInstructionPrivate::~TQDomProcessingInstructionPrivate()
+{
+}
+
+TQDomNodePrivate* TQDomProcessingInstructionPrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomProcessingInstructionPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+void TQDomProcessingInstructionPrivate::save( TQTextStream& s, int, int ) const
+{
+ s << "<?" << name << " " << value << "?>" << endl;
+}
+
+/**************************************************************
+ *
+ * TQDomProcessingInstruction
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomProcessingInstructionPrivate*)impl)
+
+/*!
+ \class TQDomProcessingInstruction tqdom.h
+ \reentrant
+ \brief The TQDomProcessingInstruction class represents an XML processing
+ instruction.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ Processing instructions are used in XML to keep processor-specific
+ information in the text of the document.
+
+ The content of the processing instruction is retrieved with data()
+ and set with setData(). The processing instruction's target is
+ retrieved with target().
+
+ For further information about the Document Object Model see
+ \link http://www.w3.org/TR/REC-DOM-Level-1/\endlink and
+ \link http://www.w3.org/TR/DOM-Level-2-Core/\endlink.
+ For a more general introduction of the DOM implementation see the
+ TQDomDocument documentation.
+*/
+
+/*!
+ Constructs an empty processing instruction. Use
+ TQDomDocument::createProcessingInstruction() to create a processing
+ instruction with content.
+*/
+TQDomProcessingInstruction::TQDomProcessingInstruction()
+ : TQDomNode()
+{
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomProcessingInstruction::TQDomProcessingInstruction( const TQDomProcessingInstruction& x )
+ : TQDomNode( x )
+{
+}
+
+TQDomProcessingInstruction::TQDomProcessingInstruction( TQDomProcessingInstructionPrivate* n )
+ : TQDomNode( n )
+{
+}
+
+/*!
+ Assigns \a x to this processing instruction.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomProcessingInstruction& TQDomProcessingInstruction::operator= ( const TQDomProcessingInstruction& x )
+{
+ return (TQDomProcessingInstruction&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomProcessingInstruction::~TQDomProcessingInstruction()
+{
+}
+
+/*!
+ Returns \c ProcessingInstructionNode.
+*/
+TQDomNode::NodeType TQDomProcessingInstruction::nodeType() const
+{
+ return ProcessingInstructionNode;
+}
+
+/*!
+ Returns the target of this processing instruction.
+
+ \sa data()
+*/
+TQString TQDomProcessingInstruction::target() const
+{
+ if ( !impl )
+ return TQString::null;
+ return impl->nodeName();
+}
+
+/*!
+ Returns the content of this processing instruction.
+
+ \sa setData() target()
+*/
+TQString TQDomProcessingInstruction::data() const
+{
+ if ( !impl )
+ return TQString::null;
+ return impl->nodeValue();
+}
+
+/*!
+ Sets the data contained in the processing instruction to \a d.
+
+ \sa data()
+*/
+void TQDomProcessingInstruction::setData( const TQString& d )
+{
+ if ( !impl )
+ return;
+ impl->setNodeValue( d );
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomProcessingInstruction::isProcessingInstruction() const
+{
+ return TRUE;
+}
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * TQDomDocumentPrivate
+ *
+ **************************************************************/
+
+TQDomDocumentPrivate::TQDomDocumentPrivate()
+ : TQDomNodePrivate( 0 )
+{
+ impl = new TQDomImplementationPrivate();
+ type = new TQDomDocumentTypePrivate( this, this );
+
+ name = "#document";
+}
+
+TQDomDocumentPrivate::TQDomDocumentPrivate( const TQString& aname )
+ : TQDomNodePrivate( 0 )
+{
+ impl = new TQDomImplementationPrivate();
+ type = new TQDomDocumentTypePrivate( this, this );
+ type->name = aname;
+
+ name = "#document";
+}
+
+TQDomDocumentPrivate::TQDomDocumentPrivate( TQDomDocumentTypePrivate* dt )
+ : TQDomNodePrivate( 0 )
+{
+ impl = new TQDomImplementationPrivate();
+ if ( dt != 0 ) {
+ type = dt;
+ type->ref();
+ } else {
+ type = new TQDomDocumentTypePrivate( this, this );
+ }
+
+ name = "#document";
+}
+
+TQDomDocumentPrivate::TQDomDocumentPrivate( TQDomDocumentPrivate* n, bool deep )
+ : TQDomNodePrivate( n, deep )
+{
+ impl = n->impl->clone();
+ // Reference count is down to 0, so we set it to 1 here.
+ impl->ref();
+ type = (TQDomDocumentTypePrivate*)n->type->cloneNode();
+ type->setParent( this );
+ // Reference count is down to 0, so we set it to 1 here.
+ type->ref();
+}
+
+TQDomDocumentPrivate::~TQDomDocumentPrivate()
+{
+ if ( impl->deref() ) delete impl;
+ if ( type->deref() ) delete type;
+}
+
+void TQDomDocumentPrivate::clear()
+{
+ if ( impl->deref() ) delete impl;
+ if ( type->deref() ) delete type;
+ impl = 0;
+ type = 0;
+ TQDomNodePrivate::clear();
+}
+
+bool TQDomDocumentPrivate::setContent( TQXmlInputSource *source, bool namespaceProcessing, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ TQXmlSimpleReader reader;
+ if ( namespaceProcessing ) {
+ reader.setFeature( "http://xml.org/sax/features/namespaces", TRUE );
+ reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", FALSE );
+ } else {
+ reader.setFeature( "http://xml.org/sax/features/namespaces", FALSE );
+ reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", TRUE );
+ }
+ reader.setFeature( "http://trolltech.com/xml/features/report-whitespace-only-CharData", FALSE );
+ reader.setUndefEntityInAttrHack( TRUE );
+
+ return setContent( source, &reader, errorMsg, errorLine, errorColumn );
+}
+
+bool TQDomDocumentPrivate::setContent( TQXmlInputSource *source, TQXmlReader *reader, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ clear();
+ impl = new TQDomImplementationPrivate;
+ type = new TQDomDocumentTypePrivate( this, this );
+
+ bool namespaceProcessing = reader->feature( "http://xml.org/sax/features/namespaces" )
+ && !reader->feature( "http://xml.org/sax/features/namespace-prefixes" );
+
+ TQDomHandler hnd( this, namespaceProcessing );
+ reader->setContentHandler( &hnd );
+ reader->setErrorHandler( &hnd );
+ reader->setLexicalHandler( &hnd );
+ reader->setDeclHandler( &hnd );
+ reader->setDTDHandler( &hnd );
+
+ if ( !reader->parse( source ) ) {
+ if ( errorMsg )
+ *errorMsg = hnd.errorMsg;
+ if ( errorLine )
+ *errorLine = hnd.errorLine;
+ if ( errorColumn )
+ *errorColumn = hnd.errorColumn;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+TQDomNodePrivate* TQDomDocumentPrivate::cloneNode( bool deep)
+{
+ TQDomNodePrivate* p = new TQDomDocumentPrivate( this, deep );
+ // We are not interested in this node
+ p->deref();
+ return p;
+}
+
+TQDomElementPrivate* TQDomDocumentPrivate::documentElement()
+{
+ TQDomNodePrivate* p = first;
+ while ( p && !p->isElement() )
+ p = p->next;
+
+ return (TQDomElementPrivate*)p;
+}
+
+TQDomElementPrivate* TQDomDocumentPrivate::createElement( const TQString& tagName )
+{
+ TQDomElementPrivate* e = new TQDomElementPrivate( this, 0, tagName );
+ e->deref();
+ return e;
+}
+
+TQDomElementPrivate* TQDomDocumentPrivate::createElementNS( const TQString& nsURI, const TQString& qName )
+{
+ TQDomElementPrivate* e = new TQDomElementPrivate( this, 0, nsURI, qName );
+ e->deref();
+ return e;
+}
+
+TQDomDocumentFragmentPrivate* TQDomDocumentPrivate::createDocumentFragment()
+{
+ TQDomDocumentFragmentPrivate* f = new TQDomDocumentFragmentPrivate( this, (TQDomNodePrivate*)0 );
+ f->deref();
+ return f;
+}
+
+TQDomTextPrivate* TQDomDocumentPrivate::createTextNode( const TQString& data )
+{
+ TQDomTextPrivate* t = new TQDomTextPrivate( this, 0, data );
+ t->deref();
+ return t;
+}
+
+TQDomCommentPrivate* TQDomDocumentPrivate::createComment( const TQString& data )
+{
+ TQDomCommentPrivate* c = new TQDomCommentPrivate( this, 0, data );
+ c->deref();
+ return c;
+}
+
+TQDomCDATASectionPrivate* TQDomDocumentPrivate::createCDATASection( const TQString& data )
+{
+ TQDomCDATASectionPrivate* c = new TQDomCDATASectionPrivate( this, 0, data );
+ c->deref();
+ return c;
+}
+
+TQDomProcessingInstructionPrivate* TQDomDocumentPrivate::createProcessingInstruction( const TQString& target, const TQString& data )
+{
+ TQDomProcessingInstructionPrivate* p = new TQDomProcessingInstructionPrivate( this, 0, target, data );
+ p->deref();
+ return p;
+}
+
+TQDomAttrPrivate* TQDomDocumentPrivate::createAttribute( const TQString& aname )
+{
+ TQDomAttrPrivate* a = new TQDomAttrPrivate( this, 0, aname );
+ a->deref();
+ return a;
+}
+
+TQDomAttrPrivate* TQDomDocumentPrivate::createAttributeNS( const TQString& nsURI, const TQString& qName )
+{
+ TQDomAttrPrivate* a = new TQDomAttrPrivate( this, 0, nsURI, qName );
+ a->deref();
+ return a;
+}
+
+TQDomEntityReferencePrivate* TQDomDocumentPrivate::createEntityReference( const TQString& aname )
+{
+ TQDomEntityReferencePrivate* e = new TQDomEntityReferencePrivate( this, 0, aname );
+ e->deref();
+ return e;
+}
+
+TQDomNodePrivate* TQDomDocumentPrivate::importNode( const TQDomNodePrivate* importedNode, bool deep )
+{
+ TQDomNodePrivate *node = 0;
+ switch ( importedNode->nodeType() ) {
+ case TQDomNode::AttributeNode:
+ node = new TQDomAttrPrivate( (TQDomAttrPrivate*)importedNode, TRUE );
+ break;
+ case TQDomNode::DocumentFragmentNode:
+ node = new TQDomDocumentFragmentPrivate( (TQDomDocumentFragmentPrivate*)importedNode, deep );
+ break;
+ case TQDomNode::ElementNode:
+ node = new TQDomElementPrivate( (TQDomElementPrivate*)importedNode, deep );
+ break;
+ case TQDomNode::EntityNode:
+ node = new TQDomEntityPrivate( (TQDomEntityPrivate*)importedNode, deep );
+ break;
+ case TQDomNode::EntityReferenceNode:
+ node = new TQDomEntityReferencePrivate( (TQDomEntityReferencePrivate*)importedNode, FALSE );
+ break;
+ case TQDomNode::NotationNode:
+ node = new TQDomNotationPrivate( (TQDomNotationPrivate*)importedNode, deep );
+ break;
+ case TQDomNode::ProcessingInstructionNode:
+ node = new TQDomProcessingInstructionPrivate( (TQDomProcessingInstructionPrivate*)importedNode, deep );
+ break;
+ case TQDomNode::TextNode:
+ node = new TQDomTextPrivate( (TQDomTextPrivate*)importedNode, deep );
+ break;
+ case TQDomNode::CDATASectionNode:
+ node = new TQDomCDATASectionPrivate( (TQDomCDATASectionPrivate*)importedNode, deep );
+ break;
+ case TQDomNode::CommentNode:
+ node = new TQDomCommentPrivate( (TQDomCommentPrivate*)importedNode, deep );
+ break;
+ default:
+ break;
+ }
+ if ( node ) {
+ node->setOwnerDocument( this );
+ // The TQDomNode constructor increases the refcount, so deref() first to
+ // keep refcount balanced.
+ node->deref();
+ }
+ return node;
+}
+
+void TQDomDocumentPrivate::save( TQTextStream& s, int, int indent ) const
+{
+ bool doc = FALSE;
+
+ TQDomNodePrivate* n = first;
+ if ( n && n->isProcessingInstruction() && n->nodeName()=="xml" ) {
+ // we have an XML declaration
+ TQString data = n->nodeValue();
+ TQRegExp encoding( TQString::tqfromLatin1("encoding\\s*=\\s*((\"([^\"]*)\")|('([^']*)'))") );
+ encoding.search( data );
+ TQString enc = encoding.cap(3);
+ if ( enc.isEmpty() ) {
+ enc = encoding.cap(5);
+ }
+ if ( enc.isEmpty() ) {
+ s.setEncoding( TQTextStream::UnicodeUTF8 );
+ } else {
+ s.setCodec( TQTextCodec::codecForName( enc ) );
+ }
+ } else {
+ s.setEncoding( TQTextStream::UnicodeUTF8 );
+ }
+ while ( n ) {
+ if ( !doc && !(n->isProcessingInstruction()&&n->nodeName()=="xml") ) {
+ // save doctype after XML declaration
+ type->save( s, 0, indent );
+ doc = TRUE;
+ }
+ n->save( s, 0, indent );
+ n = n->next;
+ }
+}
+
+/**************************************************************
+ *
+ * TQDomDocument
+ *
+ **************************************************************/
+
+#define IMPL ((TQDomDocumentPrivate*)impl)
+
+/*!
+ \class TQDomDocument tqdom.h
+ \reentrant
+ \brief The TQDomDocument class represents an XML document.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ The TQDomDocument class represents the entire XML document.
+ Conceptually, it is the root of the document tree, and provides
+ the primary access to the document's data.
+
+ Since elements, text nodes, comments, processing instructions,
+ etc., cannot exist outside the context of a document, the document
+ class also tqcontains the factory functions needed to create these
+ objects. The node objects created have an ownerDocument() function
+ which associates them with the document within whose context they
+ were created. The DOM classes that will be used most often are
+ TQDomNode, TQDomDocument, TQDomElement and TQDomText.
+
+ The parsed XML is represented internally by a tree of objects that
+ can be accessed using the various TQDom classes. All TQDom classes
+ only \e reference objects in the internal tree. The internal
+ objects in the DOM tree will get deleted once the last TQDom
+ object referencing them and the TQDomDocument itself are deleted.
+
+ Creation of elements, text nodes, etc. is done using the various
+ factory functions provided in this class. Using the default
+ constructors of the TQDom classes will only result in empty
+ objects that cannot be manipulated or inserted into the Document.
+
+ The TQDomDocument class has several functions for creating document
+ data, for example, createElement(), createTextNode(),
+ createComment(), createCDATASection(),
+ createProcessingInstruction(), createAttribute() and
+ createEntityReference(). Some of these functions have versions
+ that support namespaces, i.e. createElementNS() and
+ createAttributeNS(). The createDocumentFragment() function is used
+ to hold parts of the document; this is useful for manipulating for
+ complex documents.
+
+ The entire content of the document is set with setContent(). This
+ function parses the string it is passed as an XML document and
+ creates the DOM tree that represents the document. The root
+ element is available using documentElement(). The textual
+ representation of the document can be obtained using toString().
+
+ It is possible to insert a node from another document into the
+ document using importNode().
+
+ You can obtain a list of all the elements that have a particular
+ tag with elementsByTagName() or with elementsByTagNameNS().
+
+ The TQDom classes are typically used as follows:
+ \code
+ TQDomDocument doc( "mydocument" );
+ TQFile file( "mydocument.xml" );
+ if ( !file.open( IO_ReadOnly ) )
+ return;
+ if ( !doc.setContent( &file ) ) {
+ file.close();
+ return;
+ }
+ file.close();
+
+ // print out the element names of all elements that are direct tqchildren
+ // of the outermost element.
+ TQDomElement docElem = doc.documentElement();
+
+ TQDomNode n = docElem.firstChild();
+ while( !n.isNull() ) {
+ TQDomElement e = n.toElement(); // try to convert the node to an element.
+ if( !e.isNull() ) {
+ cout << e.tagName() << endl; // the node really is an element.
+ }
+ n = n.nextSibling();
+ }
+
+ // Here we append a new element to the end of the document
+ TQDomElement elem = doc.createElement( "img" );
+ elem.setAttribute( "src", "myimage.png" );
+ docElem.appendChild( elem );
+ \endcode
+
+ Once \c doc and \c elem go out of scope, the whole internal tree
+ representing the XML document is deleted.
+
+ To create a document using DOM use code like this:
+ \code
+ TQDomDocument doc( "MyML" );
+ TQDomElement root = doc.createElement( "MyML" );
+ doc.appendChild( root );
+
+ TQDomElement tag = doc.createElement( "Greeting" );
+ root.appendChild( tag );
+
+ TQDomText t = doc.createTextNode( "Hello World" );
+ tag.appendChild( t );
+
+ TQString xml = doc.toString();
+ \endcode
+
+ For further information about the Document Object Model see
+ \link http://www.w3.org/TR/REC-DOM-Level-1/\endlink and
+ \link http://www.w3.org/TR/DOM-Level-2-Core/\endlink.
+ For a more general introduction of the DOM implementation see the
+ TQDomDocument documentation.
+*/
+
+
+/*!
+ Constructs an empty document.
+*/
+TQDomDocument::TQDomDocument()
+{
+ impl = 0;
+}
+
+/*!
+ Creates a document and sets the name of the document type to \a
+ name.
+*/
+TQDomDocument::TQDomDocument( const TQString& name )
+{
+ // We take over ownership
+ impl = new TQDomDocumentPrivate( name );
+}
+
+/*!
+ Creates a document with the document type \a doctype.
+
+ \sa TQDomImplementation::createDocumentType()
+*/
+TQDomDocument::TQDomDocument( const TQDomDocumentType& doctype )
+{
+ impl = new TQDomDocumentPrivate( (TQDomDocumentTypePrivate*)(doctype.impl) );
+}
+
+/*!
+ Constructs a copy of \a x.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomDocument::TQDomDocument( const TQDomDocument& x )
+ : TQDomNode( x )
+{
+}
+
+TQDomDocument::TQDomDocument( TQDomDocumentPrivate* x )
+ : TQDomNode( x )
+{
+}
+
+/*!
+ Assigns \a x to this DOM document.
+
+ The data of the copy is shared (shallow copy): modifying one node
+ will also change the other. If you want to make a deep copy, use
+ cloneNode().
+*/
+TQDomDocument& TQDomDocument::operator= ( const TQDomDocument& x )
+{
+ return (TQDomDocument&) TQDomNode::operator=( x );
+}
+
+/*!
+ Destroys the object and frees its resources.
+*/
+TQDomDocument::~TQDomDocument()
+{
+}
+
+/*!
+ \overload
+
+ This function reads the XML document from the string \a text.
+ Since \a text is already a Unicode string, no encoding detection
+ is done.
+*/
+bool TQDomDocument::setContent( const TQString& text, bool namespaceProcessing, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ TQXmlInputSource source;
+ source.setData( text );
+ return IMPL->setContent( &source, namespaceProcessing, errorMsg, errorLine, errorColumn );
+}
+
+/*!
+ This function parses the XML document from the byte array \a
+ buffer and sets it as the content of the document. It tries to
+ detect the encoding of the document as required by the XML
+ specification.
+
+ If \a namespaceProcessing is TRUE, the parser recognizes
+ namespaces in the XML file and sets the prefix name, local name
+ and namespace URI to appropriate values. If \a namespaceProcessing
+ is FALSE, the parser does no namespace processing when it reads
+ the XML file.
+
+ If a parse error occurs, the function returns FALSE; otherwise it
+ returns TRUE. If a parse error occurs and \a errorMsg, \a
+ errorLine and \a errorColumn are not 0, the error message is
+ placed in \a *errorMsg, the line number \a *errorLine and the
+ column number in \a *errorColumn.
+
+ If \a namespaceProcessing is TRUE, the function TQDomNode::prefix()
+ returns a string for all elements and attributes. It returns an
+ empty string if the element or attribute has no prefix.
+
+ If \a namespaceProcessing is FALSE, the functions
+ TQDomNode::prefix(), TQDomNode::localName() and
+ TQDomNode::namespaceURI() return TQString::null.
+
+ \sa TQDomNode::namespaceURI() TQDomNode::localName()
+ TQDomNode::prefix() TQString::isNull() TQString::isEmpty()
+*/
+bool TQDomDocument::setContent( const TQByteArray& buffer, bool namespaceProcessing, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ TQBuffer buf( buffer );
+ TQXmlInputSource source( TQT_TQIODEVICE(&buf) );
+ return IMPL->setContent( &source, namespaceProcessing, errorMsg, errorLine, errorColumn );
+}
+
+/*!
+ \overload
+
+ This function reads the XML document from the C string \a buffer.
+
+ \warning This function does not try to detect the encoding:
+ instead it assumes that the C string is UTF-8 encoded.
+*/
+bool TQDomDocument::setContent( const TQCString& buffer, bool namespaceProcessing, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ return setContent( TQString::fromUtf8( buffer, buffer.length() ), namespaceProcessing, errorMsg, errorLine, errorColumn );
+}
+
+/*!
+ \overload
+
+ This function reads the XML document from the IO tqdevice \a dev.
+*/
+bool TQDomDocument::setContent( QIODevice* dev, bool namespaceProcessing, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ TQXmlInputSource source( TQT_TQIODEVICE(dev) );
+ return IMPL->setContent( &source, namespaceProcessing, errorMsg, errorLine, errorColumn );
+}
+
+/*!
+ \overload
+
+ This function reads the XML document from the string \a text.
+ Since \a text is already a Unicode string, no encoding detection
+ is performed.
+
+ No namespace processing is performed either.
+*/
+bool TQDomDocument::setContent( const TQString& text, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ return setContent( text, FALSE, errorMsg, errorLine, errorColumn );
+}
+
+/*!
+ \overload
+
+ This function reads the XML document from the byte array \a
+ buffer.
+
+ No namespace processing is performed.
+*/
+bool TQDomDocument::setContent( const TQByteArray& buffer, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ return setContent( buffer, FALSE, errorMsg, errorLine, errorColumn );
+}
+
+/*!
+ \overload
+
+ This function reads the XML document from the C string \a buffer.
+
+ No namespace processing is performed.
+
+ \warning This function does not try to detect the encoding:
+ instead it assumes that the C string is UTF-8 encoded.
+*/
+bool TQDomDocument::setContent( const TQCString& buffer, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ return setContent( buffer, FALSE, errorMsg, errorLine, errorColumn );
+}
+
+/*!
+ \overload
+
+ This function reads the XML document from the IO tqdevice \a dev.
+
+ No namespace processing is performed.
+*/
+bool TQDomDocument::setContent( QIODevice* dev, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ return setContent( dev, FALSE, errorMsg, errorLine, errorColumn );
+}
+
+/*!
+ \overload
+
+ This function reads the XML document from the TQXmlInputSource \a source and
+ parses it with the TQXmlReader \a reader.
+
+ This function doesn't change the features of the \a reader. If you want to
+ use certain features for parsing you can use this function to set up the
+ reader appropriate.
+
+ \sa TQXmlSimpleReader
+*/
+bool TQDomDocument::setContent( TQXmlInputSource *source, TQXmlReader *reader, TQString *errorMsg, int *errorLine, int *errorColumn )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return IMPL->setContent( source, reader, errorMsg, errorLine, errorColumn );
+}
+
+/*!
+ Converts the parsed document back to its textual representation.
+
+ \sa toCString()
+*/
+TQString TQDomDocument::toString() const
+{
+ TQString str;
+ TQTextStream s( str, IO_WriteOnly );
+ save( s, 1 );
+
+ return str;
+}
+
+/*!
+ \overload
+
+ This function uses \a indent as the amount of space to indent
+ subelements.
+*/
+TQString TQDomDocument::toString( int indent ) const
+{
+ TQString str;
+ TQTextStream s( str, IO_WriteOnly );
+ save( s, indent );
+
+ return str;
+}
+
+/*!
+ Converts the parsed document back to its textual representation
+ and returns a TQCString for that is encoded in UTF-8.
+
+ \sa toString()
+*/
+TQCString TQDomDocument::toCString() const
+{
+ // ### if there is an encoding specified in the xml declaration, this
+ // encoding declaration should be changed to utf8
+ return toString().utf8();
+}
+
+/*!
+ \overload
+
+ This function uses \a indent as the amount of space to indent
+ subelements.
+*/
+TQCString TQDomDocument::toCString( int indent ) const
+{
+ // ### if there is an encoding specified in the xml declaration, this
+ // encoding declaration should be changed to utf8
+ return toString( indent ).utf8();
+}
+
+
+/*!
+ Returns the document type of this document.
+*/
+TQDomDocumentType TQDomDocument::doctype() const
+{
+ if ( !impl )
+ return TQDomDocumentType();
+ return TQDomDocumentType( IMPL->doctype() );
+}
+
+/*!
+ Returns a TQDomImplementation object.
+*/
+TQDomImplementation TQDomDocument::implementation() const
+{
+ if ( !impl )
+ return TQDomImplementation();
+ return TQDomImplementation( IMPL->implementation() );
+}
+
+/*!
+ Returns the root element of the document.
+*/
+TQDomElement TQDomDocument::documentElement() const
+{
+ if ( !impl )
+ return TQDomElement();
+ return TQDomElement( IMPL->documentElement() );
+}
+
+/*!
+ Creates a new element called \a tagName that can be inserted into
+ the DOM tree, e.g. using TQDomNode::appendChild().
+
+ \sa createElementNS() TQDomNode::appendChild() TQDomNode::insertBefore()
+ TQDomNode::insertAfter()
+*/
+TQDomElement TQDomDocument::createElement( const TQString& tagName )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomElement( IMPL->createElement( tagName ) );
+}
+
+/*!
+ Creates a new document fragment, that can be used to hold parts of
+ the document, e.g. when doing complex manipulations of the
+ document tree.
+*/
+TQDomDocumentFragment TQDomDocument::createDocumentFragment()
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomDocumentFragment( IMPL->createDocumentFragment() );
+}
+
+/*!
+ Creates a text node for the string \a value that can be inserted
+ into the document tree, e.g. using TQDomNode::appendChild().
+
+ \warning All characters within an XML document must be in the range:
+
+ #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
+
+ This rule also applies to characters encoded as character entities and
+ characters in CDATA sections. If you use this function to insert
+ characters outside of this range, the document will not be well-formed.
+
+ If you want to store binary data in an XML document you must either use
+ your own scheme to escape illegal characters, or you must store it in
+ an external unparsed entity.
+
+ \sa TQDomNode::appendChild() TQDomNode::insertBefore() TQDomNode::insertAfter()
+*/
+TQDomText TQDomDocument::createTextNode( const TQString& value )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomText( IMPL->createTextNode( value ) );
+}
+
+/*!
+ Creates a new comment for the string \a value that can be inserted
+ into the document, e.g. using TQDomNode::appendChild().
+
+ \sa TQDomNode::appendChild() TQDomNode::insertBefore() TQDomNode::insertAfter()
+*/
+TQDomComment TQDomDocument::createComment( const TQString& value )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomComment( IMPL->createComment( value ) );
+}
+
+/*!
+ Creates a new CDATA section for the string \a value that can be
+ inserted into the document, e.g. using TQDomNode::appendChild().
+
+ \sa TQDomNode::appendChild() TQDomNode::insertBefore() TQDomNode::insertAfter()
+*/
+TQDomCDATASection TQDomDocument::createCDATASection( const TQString& value )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomCDATASection( IMPL->createCDATASection( value ) );
+}
+
+/*!
+ Creates a new processing instruction that can be inserted into the
+ document, e.g. using TQDomNode::appendChild(). This function sets
+ the target for the processing instruction to \a target and the
+ data to \a data.
+
+ \sa TQDomNode::appendChild() TQDomNode::insertBefore() TQDomNode::insertAfter()
+*/
+TQDomProcessingInstruction TQDomDocument::createProcessingInstruction( const TQString& target,
+ const TQString& data )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomProcessingInstruction( IMPL->createProcessingInstruction( target, data ) );
+}
+
+
+/*!
+ Creates a new attribute called \a name that can be inserted into
+ an element, e.g. using TQDomElement::setAttributeNode().
+
+ \sa createAttributeNS()
+*/
+TQDomAttr TQDomDocument::createAttribute( const TQString& name )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomAttr( IMPL->createAttribute( name ) );
+}
+
+/*!
+ Creates a new entity reference called \a name that can be inserted
+ into the document, e.g. using TQDomNode::appendChild().
+
+ \sa TQDomNode::appendChild() TQDomNode::insertBefore() TQDomNode::insertAfter()
+*/
+TQDomEntityReference TQDomDocument::createEntityReference( const TQString& name )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomEntityReference( IMPL->createEntityReference( name ) );
+}
+
+/*!
+ Returns a TQDomNodeList, that tqcontains all the elements in the
+ document with the name \a tagname. The order of the node list is
+ the order they are encountered in a preorder traversal of the
+ element tree.
+
+ \sa elementsByTagNameNS() TQDomElement::elementsByTagName()
+*/
+TQDomNodeList TQDomDocument::elementsByTagName( const TQString& tagname ) const
+{
+ return TQDomNodeList( new TQDomNodeListPrivate( impl, tagname ) );
+}
+
+/*!
+ Imports the node \a importedNode from another document to this
+ document. \a importedNode remains in the original document; this
+ function creates a copy that can be used within this document.
+
+ This function returns the imported node that belongs to this
+ document. The returned node has no tqparent. It is not possible to
+ import TQDomDocument and TQDomDocumentType nodes. In those cases
+ this function returns a \link TQDomNode::isNull() null node\endlink.
+
+ If \a deep is TRUE, this function imports not only the node \a
+ importedNode but its whole subtree; if it is FALSE, only the \a
+ importedNode is imported. The argument \a deep has no effect on
+ TQDomAttr and TQDomEntityReference nodes, since the descendents of
+ TQDomAttr nodes are always imported and those of
+ TQDomEntityReference nodes are never imported.
+
+ The behavior of this function is slightly different depending on
+ the node types:
+ \table
+ \header \i Node Type \i Behaviour
+ \row \i TQDomAttr
+ \i The owner element is set to 0 and the specified flag is
+ set to TRUE in the generated attribute. The whole subtree
+ of \a importedNode is always imported for attribute nodes:
+ \a deep has no effect.
+ \row \i TQDomDocument
+ \i Document nodes cannot be imported.
+ \row \i TQDomDocumentFragment
+ \i If \a deep is TRUE, this function imports the whole
+ document fragment; otherwise it only generates an empty
+ document fragment.
+ \row \i TQDomDocumentType
+ \i Document type nodes cannot be imported.
+ \row \i TQDomElement
+ \i Attributes for which TQDomAttr::specified() is TRUE are
+ also imported, other attributes are not imported. If \a
+ deep is TRUE, this function also imports the subtree of \a
+ importedNode; otherwise it imports only the element node
+ (and some attributes, see above).
+ \row \i TQDomEntity
+ \i Entity nodes can be imported, but at the moment there is
+ no way to use them since the document type is read-only in
+ DOM level 2.
+ \row \i TQDomEntityReference
+ \i Descendents of entity reference nodes are never imported:
+ \a deep has no effect.
+ \row \i TQDomNotation
+ \i Notation nodes can be imported, but at the moment there is
+ no way to use them since the document type is read-only in
+ DOM level 2.
+ \row \i TQDomProcessingInstruction
+ \i The target and value of the processing instruction is
+ copied to the new node.
+ \row \i TQDomText
+ \i The text is copied to the new node.
+ \row \i TQDomCDATASection
+ \i The text is copied to the new node.
+ \row \i TQDomComment
+ \i The text is copied to the new node.
+ \endtable
+
+ \sa TQDomElement::setAttribute() TQDomNode::insertBefore()
+ TQDomNode::insertAfter() TQDomNode::tqreplaceChild() TQDomNode::removeChild()
+ TQDomNode::appendChild()
+*/
+TQDomNode TQDomDocument::importNode( const TQDomNode& importedNode, bool deep )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomNode( IMPL->importNode( importedNode.impl, deep ) );
+}
+
+/*!
+ Creates a new element with namespace support that can be inserted
+ into the DOM tree. The name of the element is \a qName and the
+ namespace URI is \a nsURI. This function also sets
+ TQDomNode::prefix() and TQDomNode::localName() to appropriate values
+ (depending on \a qName).
+
+ \sa createElement()
+*/
+TQDomElement TQDomDocument::createElementNS( const TQString& nsURI, const TQString& qName )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomElement( IMPL->createElementNS( nsURI, qName ) );
+}
+
+/*!
+ Creates a new attribute with namespace support that can be
+ inserted into an element. The name of the attribute is \a qName
+ and the namespace URI is \a nsURI. This function also sets
+ TQDomNode::prefix() and TQDomNode::localName() to appropriate values
+ (depending on \a qName).
+
+ \sa createAttribute()
+*/
+TQDomAttr TQDomDocument::createAttributeNS( const TQString& nsURI, const TQString& qName )
+{
+ if ( !impl )
+ impl = new TQDomDocumentPrivate;
+ return TQDomAttr( IMPL->createAttributeNS( nsURI, qName ) );
+}
+
+/*!
+ Returns a TQDomNodeList that tqcontains all the elements in the
+ document with the local name \a localName and a namespace URI of
+ \a nsURI. The order of the node list is the order they are
+ encountered in a preorder traversal of the element tree.
+
+ \sa elementsByTagName() TQDomElement::elementsByTagNameNS()
+*/
+TQDomNodeList TQDomDocument::elementsByTagNameNS( const TQString& nsURI, const TQString& localName )
+{
+ return TQDomNodeList( new TQDomNodeListPrivate( impl, nsURI, localName ) );
+}
+
+/*!
+ Returns the element whose ID is equal to \a elementId. If no
+ element with the ID was found, this function returns a \link
+ TQDomNode::isNull() null element\endlink.
+
+ Since the TQDomClasses do not know which attributes are element
+ IDs, this function returns always a \link TQDomNode::isNull() null
+ element\endlink. This may change in a future version.
+*/
+TQDomElement TQDomDocument::elementById( const TQString& /*elementId*/ )
+{
+ return TQDomElement();
+}
+
+/*!
+ Returns \c DocumentNode.
+*/
+TQDomNode::NodeType TQDomDocument::nodeType() const
+{
+ return DocumentNode;
+}
+
+/*!
+ Returns TRUE.
+*/
+bool TQDomDocument::isDocument() const
+{
+ return TRUE;
+}
+
+
+#undef IMPL
+
+/**************************************************************
+ *
+ * Node casting functions
+ *
+ **************************************************************/
+
+/*!
+ Converts a TQDomNode into a TQDomAttr. If the node is not an
+ attribute, the returned object will be \link TQDomNode::isNull()
+ null\endlink.
+
+ \sa isAttr()
+*/
+TQDomAttr TQDomNode::toAttr()
+{
+ if ( impl && impl->isAttr() )
+ return TQDomAttr( ((TQDomAttrPrivate*)impl) );
+ return TQDomAttr();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomCDATASection. If the node is not a
+ CDATA section, the returned object will be \link
+ TQDomNode::isNull() null\endlink.
+
+ \sa isCDATASection()
+*/
+TQDomCDATASection TQDomNode::toCDATASection()
+{
+ if ( impl && impl->isCDATASection() )
+ return TQDomCDATASection( ((TQDomCDATASectionPrivate*)impl) );
+ return TQDomCDATASection();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomDocumentFragment. If the node is
+ not a document fragment the returned object will be \link
+ TQDomNode::isNull() null\endlink.
+
+ \sa isDocumentFragment()
+*/
+TQDomDocumentFragment TQDomNode::toDocumentFragment()
+{
+ if ( impl && impl->isDocumentFragment() )
+ return TQDomDocumentFragment( ((TQDomDocumentFragmentPrivate*)impl) );
+ return TQDomDocumentFragment();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomDocument. If the node is not a
+ document the returned object will be \link TQDomNode::isNull()
+ null\endlink.
+
+ \sa isDocument()
+*/
+TQDomDocument TQDomNode::toDocument()
+{
+ if ( impl && impl->isDocument() )
+ return TQDomDocument( ((TQDomDocumentPrivate*)impl) );
+ return TQDomDocument();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomDocumentType. If the node is not a
+ document type the returned object will be \link TQDomNode::isNull()
+ null\endlink.
+
+ \sa isDocumentType()
+*/
+TQDomDocumentType TQDomNode::toDocumentType()
+{
+ if ( impl && impl->isDocumentType() )
+ return TQDomDocumentType( ((TQDomDocumentTypePrivate*)impl) );
+ return TQDomDocumentType();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomElement. If the node is not an
+ element the returned object will be \link TQDomNode::isNull()
+ null\endlink.
+
+ \sa isElement()
+*/
+TQDomElement TQDomNode::toElement()
+{
+ if ( impl && impl->isElement() )
+ return TQDomElement( ((TQDomElementPrivate*)impl) );
+ return TQDomElement();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomEntityReference. If the node is not
+ an entity reference, the returned object will be \link
+ TQDomNode::isNull() null\endlink.
+
+ \sa isEntityReference()
+*/
+TQDomEntityReference TQDomNode::toEntityReference()
+{
+ if ( impl && impl->isEntityReference() )
+ return TQDomEntityReference( ((TQDomEntityReferencePrivate*)impl) );
+ return TQDomEntityReference();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomText. If the node is not a text,
+ the returned object will be \link TQDomNode::isNull() null\endlink.
+
+ \sa isText()
+*/
+TQDomText TQDomNode::toText()
+{
+ if ( impl && impl->isText() )
+ return TQDomText( ((TQDomTextPrivate*)impl) );
+ return TQDomText();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomEntity. If the node is not an
+ entity the returned object will be \link TQDomNode::isNull()
+ null\endlink.
+
+ \sa isEntity()
+*/
+TQDomEntity TQDomNode::toEntity()
+{
+ if ( impl && impl->isEntity() )
+ return TQDomEntity( ((TQDomEntityPrivate*)impl) );
+ return TQDomEntity();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomNotation. If the node is not a
+ notation the returned object will be \link TQDomNode::isNull()
+ null\endlink.
+
+ \sa isNotation()
+*/
+TQDomNotation TQDomNode::toNotation()
+{
+ if ( impl && impl->isNotation() )
+ return TQDomNotation( ((TQDomNotationPrivate*)impl) );
+ return TQDomNotation();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomProcessingInstruction. If the node
+ is not a processing instruction the returned object will be \link
+ TQDomNode::isNull() null\endlink.
+
+ \sa isProcessingInstruction()
+*/
+TQDomProcessingInstruction TQDomNode::toProcessingInstruction()
+{
+ if ( impl && impl->isProcessingInstruction() )
+ return TQDomProcessingInstruction( ((TQDomProcessingInstructionPrivate*)impl) );
+ return TQDomProcessingInstruction();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomCharacterData. If the node is not a
+ character data node the returned object will be \link
+ TQDomNode::isNull() null\endlink.
+
+ \sa isCharacterData()
+*/
+TQDomCharacterData TQDomNode::toCharacterData()
+{
+ if ( impl && impl->isCharacterData() )
+ return TQDomCharacterData( ((TQDomCharacterDataPrivate*)impl) );
+ return TQDomCharacterData();
+}
+
+/*!
+ Converts a TQDomNode into a TQDomComment. If the node is not a
+ comment the returned object will be \link TQDomNode::isNull()
+ null\endlink.
+
+ \sa isComment()
+*/
+TQDomComment TQDomNode::toComment()
+{
+ if ( impl && impl->isComment() )
+ return TQDomComment( ((TQDomCommentPrivate*)impl) );
+ return TQDomComment();
+}
+
+/**************************************************************
+ *
+ * TQDomHandler
+ *
+ **************************************************************/
+
+TQDomHandler::TQDomHandler( TQDomDocumentPrivate* adoc, bool namespaceProcessing )
+{
+ doc = adoc;
+ node = doc;
+ cdata = FALSE;
+ nsProcessing = namespaceProcessing;
+}
+
+TQDomHandler::~TQDomHandler()
+{
+}
+
+bool TQDomHandler::endDocument()
+{
+ // ### is this really necessary? (rms)
+ if ( node != doc )
+ return FALSE;
+ return TRUE;
+}
+
+bool TQDomHandler::startDTD( const TQString& name, const TQString& publicId, const TQString& systemId )
+{
+ doc->doctype()->name = name;
+ doc->doctype()->publicId = publicId;
+ doc->doctype()->systemId = systemId;
+ return TRUE;
+}
+
+bool TQDomHandler::startElement( const TQString& nsURI, const TQString&, const TQString& qName, const TQXmlAttributes& atts )
+{
+ // tag name
+ TQDomNodePrivate* n;
+ if ( nsProcessing ) {
+ n = doc->createElementNS( nsURI, qName );
+ } else {
+ n = doc->createElement( qName );
+ }
+ node->appendChild( n );
+ node = n;
+
+ // attributes
+ for ( int i=0; i<atts.length(); i++ )
+ {
+ if ( nsProcessing ) {
+ ((TQDomElementPrivate*)node)->setAttributeNS( atts.uri(i), atts.qName(i), atts.value(i) );
+ } else {
+ ((TQDomElementPrivate*)node)->setAttribute( atts.qName(i), atts.value(i) );
+ }
+ }
+
+ return TRUE;
+}
+
+bool TQDomHandler::endElement( const TQString&, const TQString&, const TQString& )
+{
+ if ( node == doc )
+ return FALSE;
+ node = node->tqparent();
+
+ return TRUE;
+}
+
+bool TQDomHandler::characters( const TQString& ch )
+{
+ // No text as child of some document
+ if ( node == doc )
+ return FALSE;
+
+ if ( cdata ) {
+ node->appendChild( doc->createCDATASection( ch ) );
+ } else if ( !entityName.isEmpty() ) {
+ TQDomEntityPrivate* e = new TQDomEntityPrivate( doc, 0, entityName,
+ TQString::null, TQString::null, TQString::null );
+ e->value = ch;
+ doc->doctype()->appendChild( e );
+ node->appendChild( doc->createEntityReference( entityName ) );
+ } else {
+ node->appendChild( doc->createTextNode( ch ) );
+ }
+
+ return TRUE;
+}
+
+bool TQDomHandler::processingInstruction( const TQString& target, const TQString& data )
+{
+ node->appendChild( doc->createProcessingInstruction( target, data ) );
+ return TRUE;
+}
+
+bool TQDomHandler::skippedEntity( const TQString& name )
+{
+ node->appendChild( doc->createEntityReference( name ) );
+ return TRUE;
+}
+
+bool TQDomHandler::fatalError( const TQXmlParseException& exception )
+{
+ errorMsg = exception.message();
+ errorLine = exception.lineNumber();
+ errorColumn = exception.columnNumber();
+ return TQXmlDefaultHandler::fatalError( exception );
+}
+
+bool TQDomHandler::startCDATA()
+{
+ cdata = TRUE;
+ return TRUE;
+}
+
+bool TQDomHandler::endCDATA()
+{
+ cdata = FALSE;
+ return TRUE;
+}
+
+bool TQDomHandler::startEntity( const TQString &name )
+{
+ entityName = name;
+ return TRUE;
+}
+
+bool TQDomHandler::endEntity( const TQString & )
+{
+ entityName = TQString::null;
+ return TRUE;
+}
+
+bool TQDomHandler::comment( const TQString& ch )
+{
+ node->appendChild( doc->createComment( ch ) );
+ return TRUE;
+}
+
+bool TQDomHandler::unparsedEntityDecl( const TQString &name, const TQString &publicId, const TQString &systemId, const TQString &notationName )
+{
+ TQDomEntityPrivate* e = new TQDomEntityPrivate( doc, 0, name,
+ publicId, systemId, notationName );
+ doc->doctype()->appendChild( e );
+ return TRUE;
+}
+
+bool TQDomHandler::externalEntityDecl( const TQString &name, const TQString &publicId, const TQString &systemId )
+{
+ return unparsedEntityDecl( name, publicId, systemId, TQString::null );
+}
+
+bool TQDomHandler::notationDecl( const TQString & name, const TQString & publicId, const TQString & systemId )
+{
+ TQDomNotationPrivate* n = new TQDomNotationPrivate( doc, 0, name, publicId, systemId );
+ doc->doctype()->appendChild( n );
+ return TRUE;
+}
+
+#endif //TQT_NO_DOM
diff --git a/tqtinterface/qt4/src/xml/tqdom.h b/tqtinterface/qt4/src/xml/tqdom.h
new file mode 100644
index 0000000..f0cc43f
--- /dev/null
+++ b/tqtinterface/qt4/src/xml/tqdom.h
@@ -0,0 +1,678 @@
+/****************************************************************************
+**
+** Definition of TQDomDocument and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the xml module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQDOM_H
+#define TQDOM_H
+
+#ifndef TQT_H
+#include "tqstring.h"
+#endif // TQT_H
+
+#if !defined(TQT_MODULE_XML) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_XML )
+#define TQM_EXPORT_DOM
+#else
+#define TQM_EXPORT_DOM TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_DOM
+
+class QIODevice;
+class TQIODevice;
+class TQTextStream;
+
+class TQXmlInputSource;
+class TQXmlReader;
+
+class TQDomDocumentPrivate;
+class TQDomDocumentTypePrivate;
+class TQDomDocumentFragmentPrivate;
+class TQDomNodePrivate;
+class TQDomNodeListPrivate;
+class TQDomImplementationPrivate;
+class TQDomElementPrivate;
+class TQDomNotationPrivate;
+class TQDomEntityPrivate;
+class TQDomEntityReferencePrivate;
+class TQDomProcessingInstructionPrivate;
+class TQDomAttrPrivate;
+class TQDomCharacterDataPrivate;
+class TQDomTextPrivate;
+class TQDomCommentPrivate;
+class TQDomCDATASectionPrivate;
+class TQDomNamedNodeMapPrivate;
+class TQDomImplementationPrivate;
+
+class TQDomNodeList;
+class TQDomElement;
+class TQDomText;
+class TQDomComment;
+class TQDomCDATASection;
+class TQDomProcessingInstruction;
+class TQDomAttr;
+class TQDomEntityReference;
+class TQDomDocument;
+class TQDomNamedNodeMap;
+class TQDomDocument;
+class TQDomDocumentFragment;
+class TQDomDocumentType;
+class TQDomImplementation;
+class TQDomNode;
+class TQDomEntity;
+class TQDomNotation;
+class TQDomCharacterData;
+
+class TQM_EXPORT_DOM TQDomImplementation
+{
+public:
+ TQDomImplementation();
+ TQDomImplementation( const TQDomImplementation& );
+ virtual ~TQDomImplementation();
+ TQDomImplementation& operator= ( const TQDomImplementation& );
+ bool operator== ( const TQDomImplementation& ) const;
+ bool operator!= ( const TQDomImplementation& ) const;
+
+ // functions
+ virtual bool hasFeature( const TQString& feature, const TQString& version );
+ virtual TQDomDocumentType createDocumentType( const TQString& qName, const TQString& publicId, const TQString& systemId );
+ virtual TQDomDocument createDocument( const TQString& nsURI, const TQString& qName, const TQDomDocumentType& doctype );
+
+ // TQt extension
+ bool isNull();
+
+private:
+ TQDomImplementationPrivate* impl;
+ TQDomImplementation( TQDomImplementationPrivate* );
+
+ friend class TQDomDocument;
+};
+
+class TQM_EXPORT_DOM TQDomNode
+{
+public:
+ enum NodeType {
+ ElementNode = 1,
+ AttributeNode = 2,
+ TextNode = 3,
+ CDATASectionNode = 4,
+ EntityReferenceNode = 5,
+ EntityNode = 6,
+ ProcessingInstructionNode = 7,
+ CommentNode = 8,
+ DocumentNode = 9,
+ DocumentTypeNode = 10,
+ DocumentFragmentNode = 11,
+ NotationNode = 12,
+ BaseNode = 21,// this is not in the standard
+ CharacterDataNode = 22 // this is not in the standard
+ };
+
+ TQDomNode();
+ TQDomNode( const TQDomNode& );
+ TQDomNode& operator= ( const TQDomNode& );
+ bool operator== ( const TQDomNode& ) const;
+ bool operator!= ( const TQDomNode& ) const;
+ virtual ~TQDomNode();
+
+ // DOM functions
+ virtual TQDomNode insertBefore( const TQDomNode& newChild, const TQDomNode& refChild );
+ virtual TQDomNode insertAfter( const TQDomNode& newChild, const TQDomNode& refChild );
+ virtual TQDomNode tqreplaceChild( const TQDomNode& newChild, const TQDomNode& oldChild );
+ virtual TQDomNode removeChild( const TQDomNode& oldChild );
+ virtual TQDomNode appendChild( const TQDomNode& newChild );
+ virtual bool hasChildNodes() const;
+ virtual TQDomNode cloneNode( bool deep = TRUE ) const;
+ virtual void normalize();
+ virtual bool isSupported( const TQString& feature, const TQString& version ) const;
+
+ // DOM read only attributes
+ virtual TQString nodeName() const;
+ virtual TQDomNode::NodeType nodeType() const;
+ virtual TQDomNode parentNode() const;
+ virtual TQDomNodeList childNodes() const;
+ virtual TQDomNode firstChild() const;
+ virtual TQDomNode lastChild() const;
+ virtual TQDomNode previousSibling() const;
+ virtual TQDomNode nextSibling() const;
+ virtual TQDomNamedNodeMap attributes() const;
+ virtual TQDomDocument ownerDocument() const;
+ virtual TQString namespaceURI() const;
+ virtual TQString localName() const;
+ virtual bool hasAttributes() const;
+
+ // DOM attributes
+ virtual TQString nodeValue() const;
+ virtual void setNodeValue( const TQString& );
+ virtual TQString prefix() const;
+ virtual void setPrefix( const TQString& pre );
+
+ // TQt extensions
+ virtual bool isAttr() const;
+ virtual bool isCDATASection() const;
+ virtual bool isDocumentFragment() const;
+ virtual bool isDocument() const;
+ virtual bool isDocumentType() const;
+ virtual bool isElement() const;
+ virtual bool isEntityReference() const;
+ virtual bool isText() const;
+ virtual bool isEntity() const;
+ virtual bool isNotation() const;
+ virtual bool isProcessingInstruction() const;
+ virtual bool isCharacterData() const;
+ virtual bool isComment() const;
+
+ /**
+ * Shortcut to avoid dealing with TQDomNodeList
+ * all the time.
+ */
+ TQDomNode namedItem( const TQString& name ) const;
+
+ bool isNull() const;
+ void clear();
+
+ TQDomAttr toAttr();
+ TQDomCDATASection toCDATASection();
+ TQDomDocumentFragment toDocumentFragment();
+ TQDomDocument toDocument();
+ TQDomDocumentType toDocumentType();
+ TQDomElement toElement();
+ TQDomEntityReference toEntityReference();
+ TQDomText toText();
+ TQDomEntity toEntity();
+ TQDomNotation toNotation();
+ TQDomProcessingInstruction toProcessingInstruction();
+ TQDomCharacterData toCharacterData();
+ TQDomComment toComment();
+
+ void save( TQTextStream&, int ) const;
+
+protected:
+ TQDomNodePrivate* impl;
+ TQDomNode( TQDomNodePrivate* );
+
+private:
+ friend class TQDomDocument;
+ friend class TQDomDocumentType;
+ friend class TQDomNodeList;
+ friend class TQDomNamedNodeMap;
+};
+
+class TQM_EXPORT_DOM TQDomNodeList
+{
+public:
+ TQDomNodeList();
+ TQDomNodeList( const TQDomNodeList& );
+ TQDomNodeList& operator= ( const TQDomNodeList& );
+ bool operator== ( const TQDomNodeList& ) const;
+ bool operator!= ( const TQDomNodeList& ) const;
+ virtual ~TQDomNodeList();
+
+ // DOM functions
+ virtual TQDomNode item( int index ) const;
+
+ // DOM read only attributes
+ virtual uint length() const;
+ uint count() const { return length(); } // TQt API consitancy
+
+private:
+ TQDomNodeListPrivate* impl;
+ TQDomNodeList( TQDomNodeListPrivate* );
+
+ friend class TQDomNode;
+ friend class TQDomElement;
+ friend class TQDomDocument;
+};
+
+class TQM_EXPORT_DOM TQDomDocumentType : public TQDomNode
+{
+public:
+ TQDomDocumentType();
+ TQDomDocumentType( const TQDomDocumentType& x );
+ TQDomDocumentType& operator= ( const TQDomDocumentType& );
+ ~TQDomDocumentType();
+
+ // DOM read only attributes
+ virtual TQString name() const;
+ virtual TQDomNamedNodeMap entities() const;
+ virtual TQDomNamedNodeMap notations() const;
+ virtual TQString publicId() const;
+ virtual TQString systemId() const;
+ virtual TQString internalSubset() const;
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isDocumentType() const;
+
+private:
+ TQDomDocumentType( TQDomDocumentTypePrivate* );
+
+ friend class TQDomImplementation;
+ friend class TQDomDocument;
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomDocument : public TQDomNode
+{
+public:
+ TQDomDocument();
+ TQ_EXPLICIT TQDomDocument( const TQString& name );
+ TQ_EXPLICIT TQDomDocument( const TQDomDocumentType& doctype );
+ TQDomDocument( const TQDomDocument& x );
+ TQDomDocument& operator= ( const TQDomDocument& );
+ ~TQDomDocument();
+
+ // DOM functions
+ TQDomElement createElement( const TQString& tagName );
+ TQDomDocumentFragment createDocumentFragment();
+ TQDomText createTextNode( const TQString& data );
+ TQDomComment createComment( const TQString& data );
+ TQDomCDATASection createCDATASection( const TQString& data );
+ TQDomProcessingInstruction createProcessingInstruction( const TQString& target, const TQString& data );
+ TQDomAttr createAttribute( const TQString& name );
+ TQDomEntityReference createEntityReference( const TQString& name );
+ TQDomNodeList elementsByTagName( const TQString& tagname ) const;
+ TQDomNode importNode( const TQDomNode& importedNode, bool deep );
+ TQDomElement createElementNS( const TQString& nsURI, const TQString& qName );
+ TQDomAttr createAttributeNS( const TQString& nsURI, const TQString& qName );
+ TQDomNodeList elementsByTagNameNS( const TQString& nsURI, const TQString& localName );
+ TQDomElement elementById( const TQString& elementId );
+
+ // DOM read only attributes
+ TQDomDocumentType doctype() const;
+ TQDomImplementation implementation() const;
+ TQDomElement documentElement() const;
+
+ // TQt extensions
+ bool setContent( const TQCString& text, bool namespaceProcessing, TQString *errorMsg=0, int *errorLine=0, int *errorColumn=0 );
+ bool setContent( const TQByteArray& text, bool namespaceProcessing, TQString *errorMsg=0, int *errorLine=0, int *errorColumn=0 );
+ bool setContent( const TQString& text, bool namespaceProcessing, TQString *errorMsg=0, int *errorLine=0, int *errorColumn=0 );
+ bool setContent( QIODevice* dev, bool namespaceProcessing, TQString *errorMsg=0, int *errorLine=0, int *errorColumn=0 );
+ bool setContent( const TQCString& text, TQString *errorMsg=0, int *errorLine=0, int *errorColumn=0 );
+ bool setContent( const TQByteArray& text, TQString *errorMsg=0, int *errorLine=0, int *errorColumn=0 );
+ bool setContent( const TQString& text, TQString *errorMsg=0, int *errorLine=0, int *errorColumn=0 );
+ bool setContent( QIODevice* dev, TQString *errorMsg=0, int *errorLine=0, int *errorColumn=0 );
+
+ bool setContent( TQXmlInputSource *source, TQXmlReader *reader, TQString *errorMsg=0, int *errorLine=0, int *errorColumn=0 );
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isDocument() const;
+
+ // TQt extensions
+ TQString toString() const; // ### TQt 4: merge the two overloads
+ TQString toString( int ) const;
+ TQCString toCString() const; // ### TQt 4: merge the two overloads
+ TQCString toCString( int ) const;
+
+private:
+ TQDomDocument( TQDomDocumentPrivate* );
+
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomNamedNodeMap
+{
+public:
+ TQDomNamedNodeMap();
+ TQDomNamedNodeMap( const TQDomNamedNodeMap& );
+ TQDomNamedNodeMap& operator= ( const TQDomNamedNodeMap& );
+ bool operator== ( const TQDomNamedNodeMap& ) const;
+ bool operator!= ( const TQDomNamedNodeMap& ) const;
+ ~TQDomNamedNodeMap();
+
+ // DOM functions
+ TQDomNode namedItem( const TQString& name ) const;
+ TQDomNode setNamedItem( const TQDomNode& newNode );
+ TQDomNode removeNamedItem( const TQString& name );
+ TQDomNode item( int index ) const;
+ TQDomNode namedItemNS( const TQString& nsURI, const TQString& localName ) const;
+ TQDomNode setNamedItemNS( const TQDomNode& newNode );
+ TQDomNode removeNamedItemNS( const TQString& nsURI, const TQString& localName );
+
+ // DOM read only attributes
+ uint length() const;
+ uint count() const { return length(); } // TQt API consitancy
+
+ // TQt extension
+ bool tqcontains( const TQString& name ) const;
+
+private:
+ TQDomNamedNodeMapPrivate* impl;
+ TQDomNamedNodeMap( TQDomNamedNodeMapPrivate* );
+
+ friend class TQDomNode;
+ friend class TQDomDocumentType;
+ friend class TQDomElement;
+};
+
+class TQM_EXPORT_DOM TQDomDocumentFragment : public TQDomNode
+{
+public:
+ TQDomDocumentFragment();
+ TQDomDocumentFragment( const TQDomDocumentFragment& x );
+ TQDomDocumentFragment& operator= ( const TQDomDocumentFragment& );
+ ~TQDomDocumentFragment();
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isDocumentFragment() const;
+
+private:
+ TQDomDocumentFragment( TQDomDocumentFragmentPrivate* );
+
+ friend class TQDomDocument;
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomCharacterData : public TQDomNode
+{
+public:
+ TQDomCharacterData();
+ TQDomCharacterData( const TQDomCharacterData& x );
+ TQDomCharacterData& operator= ( const TQDomCharacterData& );
+ ~TQDomCharacterData();
+
+ // DOM functions
+ virtual TQString substringData( unsigned long offset, unsigned long count );
+ virtual void appendData( const TQString& arg );
+ virtual void insertData( unsigned long offset, const TQString& arg );
+ virtual void deleteData( unsigned long offset, unsigned long count );
+ virtual void tqreplaceData( unsigned long offset, unsigned long count, const TQString& arg );
+
+ // DOM read only attributes
+ virtual uint length() const;
+
+ // DOM attributes
+ virtual TQString data() const;
+ virtual void setData( const TQString& );
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isCharacterData() const;
+
+private:
+ TQDomCharacterData( TQDomCharacterDataPrivate* );
+
+ friend class TQDomDocument;
+ friend class TQDomText;
+ friend class TQDomComment;
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomAttr : public TQDomNode
+{
+public:
+ TQDomAttr();
+ TQDomAttr( const TQDomAttr& x );
+ TQDomAttr& operator= ( const TQDomAttr& );
+ ~TQDomAttr();
+
+ // DOM read only attributes
+ virtual TQString name() const;
+ virtual bool specified() const;
+ virtual TQDomElement ownerElement() const;
+
+ // DOM attributes
+ virtual TQString value() const;
+ virtual void setValue( const TQString& );
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isAttr() const;
+
+private:
+ TQDomAttr( TQDomAttrPrivate* );
+
+ friend class TQDomDocument;
+ friend class TQDomElement;
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomElement : public TQDomNode
+{
+public:
+ TQDomElement();
+ TQDomElement( const TQDomElement& x );
+ TQDomElement& operator= ( const TQDomElement& );
+ ~TQDomElement();
+
+ // DOM functions
+ TQString attribute( const TQString& name, const TQString& defValue = TQString::null ) const;
+ void setAttribute( const TQString& name, const TQString& value );
+ void setAttribute( const TQString& name, int value );
+ void setAttribute( const TQString& name, uint value );
+ void setAttribute( const TQString& name, long value );
+ void setAttribute( const TQString& name, ulong value );
+ void setAttribute( const TQString& name, double value );
+ void removeAttribute( const TQString& name );
+ TQDomAttr attributeNode( const TQString& name);
+ TQDomAttr setAttributeNode( const TQDomAttr& newAttr );
+ TQDomAttr removeAttributeNode( const TQDomAttr& oldAttr );
+ virtual TQDomNodeList elementsByTagName( const TQString& tagname ) const;
+ bool hasAttribute( const TQString& name ) const;
+
+ TQString attributeNS( const TQString nsURI, const TQString& localName, const TQString& defValue ) const;
+ void setAttributeNS( const TQString nsURI, const TQString& qName, const TQString& value );
+ void setAttributeNS( const TQString nsURI, const TQString& qName, int value );
+ void setAttributeNS( const TQString nsURI, const TQString& qName, uint value );
+ void setAttributeNS( const TQString nsURI, const TQString& qName, long value );
+ void setAttributeNS( const TQString nsURI, const TQString& qName, ulong value );
+ void setAttributeNS( const TQString nsURI, const TQString& qName, double value );
+ void removeAttributeNS( const TQString& nsURI, const TQString& localName );
+ TQDomAttr attributeNodeNS( const TQString& nsURI, const TQString& localName );
+ TQDomAttr setAttributeNodeNS( const TQDomAttr& newAttr );
+ virtual TQDomNodeList elementsByTagNameNS( const TQString& nsURI, const TQString& localName ) const;
+ bool hasAttributeNS( const TQString& nsURI, const TQString& localName ) const;
+
+ // DOM read only attributes
+ TQString tagName() const;
+ void setTagName( const TQString& name ); // TQt extension
+
+ // Reimplemented from TQDomNode
+ TQDomNamedNodeMap attributes() const;
+ TQDomNode::NodeType nodeType() const;
+ bool isElement() const;
+
+ TQString text() const;
+
+private:
+ TQDomElement( TQDomElementPrivate* );
+
+ friend class TQDomDocument;
+ friend class TQDomNode;
+ friend class TQDomAttr;
+};
+
+class TQM_EXPORT_DOM TQDomText : public TQDomCharacterData
+{
+public:
+ TQDomText();
+ TQDomText( const TQDomText& x );
+ TQDomText& operator= ( const TQDomText& );
+ ~TQDomText();
+
+ // DOM functions
+ TQDomText splitText( int offset );
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isText() const;
+
+private:
+ TQDomText( TQDomTextPrivate* );
+
+ friend class TQDomCDATASection;
+ friend class TQDomDocument;
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomComment : public TQDomCharacterData
+{
+public:
+ TQDomComment();
+ TQDomComment( const TQDomComment& x );
+ TQDomComment& operator= ( const TQDomComment& );
+ ~TQDomComment();
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isComment() const;
+
+private:
+ TQDomComment( TQDomCommentPrivate* );
+
+ friend class TQDomDocument;
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomCDATASection : public TQDomText
+{
+public:
+ TQDomCDATASection();
+ TQDomCDATASection( const TQDomCDATASection& x );
+ TQDomCDATASection& operator= ( const TQDomCDATASection& );
+ ~TQDomCDATASection();
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isCDATASection() const;
+
+private:
+ TQDomCDATASection( TQDomCDATASectionPrivate* );
+
+ friend class TQDomDocument;
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomNotation : public TQDomNode
+{
+public:
+ TQDomNotation();
+ TQDomNotation( const TQDomNotation& x );
+ TQDomNotation& operator= ( const TQDomNotation& );
+ ~TQDomNotation();
+
+ // DOM read only attributes
+ TQString publicId() const;
+ TQString systemId() const;
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isNotation() const;
+
+private:
+ TQDomNotation( TQDomNotationPrivate* );
+
+ friend class TQDomDocument;
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomEntity : public TQDomNode
+{
+public:
+ TQDomEntity();
+ TQDomEntity( const TQDomEntity& x );
+ TQDomEntity& operator= ( const TQDomEntity& );
+ ~TQDomEntity();
+
+ // DOM read only attributes
+ virtual TQString publicId() const;
+ virtual TQString systemId() const;
+ virtual TQString notationName() const;
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isEntity() const;
+
+private:
+ TQDomEntity( TQDomEntityPrivate* );
+
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomEntityReference : public TQDomNode
+{
+public:
+ TQDomEntityReference();
+ TQDomEntityReference( const TQDomEntityReference& x );
+ TQDomEntityReference& operator= ( const TQDomEntityReference& );
+ ~TQDomEntityReference();
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isEntityReference() const;
+
+private:
+ TQDomEntityReference( TQDomEntityReferencePrivate* );
+
+ friend class TQDomDocument;
+ friend class TQDomNode;
+};
+
+class TQM_EXPORT_DOM TQDomProcessingInstruction : public TQDomNode
+{
+public:
+ TQDomProcessingInstruction();
+ TQDomProcessingInstruction( const TQDomProcessingInstruction& x );
+ TQDomProcessingInstruction& operator= ( const TQDomProcessingInstruction& );
+ ~TQDomProcessingInstruction();
+
+ // DOM read only attributes
+ virtual TQString target() const;
+
+ // DOM attributes
+ virtual TQString data() const;
+ virtual void setData( const TQString& d );
+
+ // Reimplemented from TQDomNode
+ TQDomNode::NodeType nodeType() const;
+ bool isProcessingInstruction() const;
+
+private:
+ TQDomProcessingInstruction( TQDomProcessingInstructionPrivate* );
+
+ friend class TQDomDocument;
+ friend class TQDomNode;
+};
+
+
+TQM_EXPORT_DOM TQTextStream& operator<<( TQTextStream&, const TQDomNode& );
+
+#endif //TQT_NO_DOM
+#endif // TQDOM_H
diff --git a/tqtinterface/qt4/src/xml/tqsvgdevice.cpp b/tqtinterface/qt4/src/xml/tqsvgdevice.cpp
new file mode 100644
index 0000000..cda8c4f
--- /dev/null
+++ b/tqtinterface/qt4/src/xml/tqsvgdevice.cpp
@@ -0,0 +1,1591 @@
+/****************************************************************************
+**
+** Implementation of the TQSvgDevice class
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the xml module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+*****************************************************************************/
+
+#include <private/tqsvgdevice_p.h>
+
+#ifndef TQT_NO_SVG
+
+#include "tqpainter.h"
+#include "tqpaintdevicemetrics.h"
+#include "tqfile.h"
+#include "tqmap.h"
+#include "tqregexp.h"
+#include "tqvaluelist.h"
+#include "tqtextstream.h"
+#include "tqimage.h"
+#include "tqpixmap.h"
+
+#include <math.h>
+
+const double deg2rad = 0.017453292519943295769; // pi/180
+const char piData[] = "version=\"1.0\" standalone=\"no\"";
+const char publicId[] = "-//W3C//DTD SVG 20001102//EN";
+const char systemId[] = "http://www.w3.org/TR/2000/CR-SVG-20001102/DTD/svg-20001102.dtd";
+
+struct TQM_EXPORT_SVG ImgElement {
+ TQDomElement element;
+ TQImage image;
+ TQ_DUMMY_COMPARISON_OPERATOR( ImgElement )
+};
+
+struct TQM_EXPORT_SVG PixElement {
+ TQDomElement element;
+ TQPixmap pixmap;
+ TQ_DUMMY_COMPARISON_OPERATOR( PixElement )
+};
+
+struct TQSvgDeviceState {
+ int textx, texty; // current text position
+ int textalign; // text tqalignment
+ TQ_DUMMY_COMPARISON_OPERATOR( TQSvgDeviceState )
+};
+
+typedef TQValueList<ImgElement> ImageList;
+typedef TQValueList<PixElement> PixmapList;
+typedef TQValueList<TQSvgDeviceState> StateList;
+
+class TQSvgDevicePrivate {
+public:
+ ImageList images;
+ PixmapList pixmaps;
+ StateList stack;
+ int currentClip;
+
+ uint justRestored : 1;
+
+ TQMap<TQString, TQRegion> clipPathTable;
+};
+
+enum ElementType {
+ InvalidElement = 0,
+ AnchorElement,
+ CircleElement,
+ ClipElement,
+ CommentElement,
+ DescElement,
+ EllipseElement,
+ GroupElement,
+ ImageElement,
+ LineElement,
+ PolylineElement,
+ PolygonElement,
+ PathElement,
+ RectElement,
+ SvgElement,
+ TextElement,
+ TitleElement,
+ TSpanElement
+};
+
+typedef TQMap<TQString,ElementType> TQSvgTypeMap;
+static TQSvgTypeMap *qSvgTypeMap=0; // element types
+static TQMap<TQString,TQString> *qSvgColMap=0; // recognized color keyword names
+
+/*!
+ \class TQSvgDevice qsvgdevice.h
+ \brief The TQSvgDevice class provides a paint tqdevice for SVG vector graphics.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \ingroup xml-tools
+ \module XML
+ \internal
+
+ SVG is an XML vector graphics format. This class supports the
+ loading and saving of SVG files with load() and save(), and the
+ rendering of an SVG onto a TQPainter using play(). Use toString()
+ to put the SVG into a string.
+
+ \sa TQPaintDevice TQPainter
+*/
+
+/*!
+ Creates a TQSvgDevice object.
+*/
+
+TQSvgDevice::TQSvgDevice()
+ : TQPaintDevice( TQInternal::ExternalDevice ),
+ pt( 0 )
+{
+ d = new TQSvgDevicePrivate;
+ d->currentClip = 0;
+ d->justRestored = FALSE;
+}
+
+/*!
+ Destroys the TQSvgDevice object and frees the resources it used.
+*/
+
+TQSvgDevice::~TQSvgDevice()
+{
+ delete qSvgTypeMap; qSvgTypeMap = 0; // static
+ delete qSvgColMap; qSvgColMap = 0;
+ delete d;
+}
+
+/*!
+ Loads and parses a SVG from \a dev into the tqdevice. Returns TRUE
+ on success (i.e. loaded and parsed without error); otherwise
+ returns FALSE.
+*/
+
+bool TQSvgDevice::load( TQIODevice *dev )
+{
+ return doc.setContent( dev );
+}
+
+/*!
+ Renders (replays) the SVG on the \a painter and returns TRUE if
+ successful (i.e. it is a valid SVG); otherwise returns FALSE.
+*/
+
+bool TQSvgDevice::play( TQPainter *painter )
+{
+ if ( !painter ) {
+#if defined(TQT_CHECK_RANGE)
+ TQ_ASSERT( painter );
+#endif
+ return FALSE;
+ }
+ pt = painter;
+ pt->setPen( TQt::NoPen ); // SVG default pen and brush
+ pt->setBrush( TQt::black );
+ if ( doc.isNull() ) {
+ qWarning( "TQSvgDevice::play: No SVG data set." );
+ return FALSE;
+ }
+
+ TQDomNode svg = doc.namedItem( "svg" );
+ if ( svg.isNull() || !svg.isElement() ) {
+ qWarning( "TQSvgDevice::play: Couldn't tqfind any svg element." );
+ return FALSE;
+ }
+
+ // force transform to be activated in case our sequences
+ // are replayed later with a transformed painter
+ painter->setWorldXForm( TRUE );
+
+ TQDomNamedNodeMap attr = svg.attributes();
+ int x = lenToInt( attr, "x" );
+ int y = lenToInt( attr, "y" );
+ brect.setX( x );
+ brect.setY( y );
+ TQString wstr = attr.tqcontains( "width" )
+ ? attr.namedItem( "width" ).nodeValue() : TQString( "100%" );
+ TQString hstr = attr.tqcontains( "height" )
+ ? attr.namedItem( "height" ).nodeValue() : TQString( "100%" );
+ double width = parseLen( wstr, 0, TRUE );
+ double height = parseLen( hstr, 0, FALSE );
+ // SVG doesn't respect x and y. But we want a proper bounding rect.
+ brect.setWidth( int(width) - x );
+ brect.setHeight( int(height) - y );
+ painter->setClipRect( brect, TQPainter::CoordPainter );
+
+ if ( attr.tqcontains( "viewBox" ) ) {
+ TQRegExp re( TQString::tqfromLatin1("\\s*(\\S+)\\s*,?\\s*(\\S+)\\s*,?"
+ "\\s*(\\S+)\\s*,?\\s*(\\S+)\\s*") );
+ if ( re.search( attr.namedItem( "viewBox" ).nodeValue() ) < 0 ) {
+ qWarning( "TQSvgDevice::play: Invalid viewBox attribute.");
+ return FALSE;
+ } else {
+ double x = re.cap( 1 ).toDouble();
+ double y = re.cap( 2 ).toDouble();
+ double w = re.cap( 3 ).toDouble();
+ double h = re.cap( 4 ).toDouble();
+ if ( w < 0 || h < 0 ) {
+ qWarning( "TQSvgDevice::play: Invalid viewBox dimension.");
+ return FALSE;
+ } else if ( w == 0 || h == 0 ) {
+ return TRUE;
+ }
+ painter->scale( width/w, height/h );
+ painter->translate( -x, -y );
+ }
+ }
+
+ const struct ElementTable {
+ const char *name;
+ ElementType type;
+ } etab[] = {
+ { "a", AnchorElement },
+ { "#comment", CommentElement },
+ { "circle", CircleElement },
+ { "clipPath", ClipElement },
+ { "desc", DescElement },
+ { "ellipse", EllipseElement },
+ { "g", GroupElement },
+ { "image", ImageElement },
+ { "line", LineElement },
+ { "polyline", PolylineElement },
+ { "polygon", PolygonElement },
+ { "path", PathElement },
+ { "rect", RectElement },
+ { "svg", SvgElement },
+ { "text", TextElement },
+ { "tspan", TSpanElement },
+ { "title", TitleElement },
+ { 0, InvalidElement }
+ };
+ // initialize only once
+ if ( !qSvgTypeMap ) {
+ qSvgTypeMap = new TQSvgTypeMap;
+ const ElementTable *t = etab;
+ while ( t->name ) {
+ qSvgTypeMap->insert( t->name, t->type );
+ t++;
+ }
+ }
+
+ // initial state
+ TQSvgDeviceState st;
+ st.textx = st.texty = 0;
+ st.textalign = TQt::AlignLeft;
+ d->stack.append(st);
+ curr = &d->stack.last();
+ // 'play' all elements recursively starting with 'svg' as root
+ bool b = play( svg );
+ d->stack.remove( d->stack.begin() );
+ return b;
+}
+
+/*!
+ Returns the SVG as a single string of XML.
+*/
+TQString TQSvgDevice::toString() const
+{
+ if ( doc.isNull() )
+ return TQString();
+
+ return doc.toString();
+}
+
+/*!
+ Saves the SVG to \a fileName.
+*/
+
+bool TQSvgDevice::save( const TQString &fileName )
+{
+ // guess svg id from fileName
+ TQString svgName = fileName.endsWith( ".svg" ) ?
+ TQT_TQSTRING(fileName.left( fileName.length()-4 )) : fileName;
+
+ // now we have the info about name and dimensions available
+ TQDomElement root = doc.documentElement();
+ root.setAttribute( "id", svgName );
+ // the standard doesn't take respect x and y. But we want a
+ // proper bounding rect. We make width and height bigger when
+ // writing out and subtract x and y when reading in.
+ root.setAttribute( "x", brect.x() );
+ root.setAttribute( "y", brect.y() );
+ root.setAttribute( "width", brect.width() + brect.x() );
+ root.setAttribute( "height", brect.height() + brect.y() );
+
+ // ... and know how to name any image files to be written out
+ int icount = 0;
+ ImageList::Iterator iit = d->images.begin();
+ for ( ; iit != d->images.end(); ++iit ) {
+ TQString href = TQString( "%1_%2.png" ).arg( svgName ).arg( icount );
+ (*iit).image.save( href, "PNG" );
+ (*iit).element.setAttribute( "xlink:href", href );
+ icount++;
+ }
+ PixmapList::Iterator pit = d->pixmaps.begin();
+ for ( ; pit != d->pixmaps.end(); ++pit ) {
+ TQString href = TQString( "%1_%2.png" ).arg( svgName ).arg( icount );
+ (*pit).pixmap.save( href, "PNG" );
+ (*pit).element.setAttribute( "xlink:href", href );
+ icount++;
+ }
+
+ TQFile f( fileName );
+ if ( !f.open ( IO_WriteOnly ) )
+ return FALSE;
+ TQTextStream s( &f );
+ s.setEncoding( TQTextStream::UnicodeUTF8 );
+ s << doc;
+
+ return TRUE;
+}
+
+/*!
+ \overload
+
+ \a dev is the tqdevice to use for saving.
+*/
+
+bool TQSvgDevice::save( TQIODevice *dev )
+{
+#if defined(CHECK_RANGE)
+ if ( !d->images.isEmpty() || !d->pixmaps.isEmpty() )
+ qWarning( "TQSvgDevice::save: skipping external images" );
+#endif
+
+ TQTextStream s( dev );
+ s.setEncoding( TQTextStream::UnicodeUTF8 );
+ s << doc;
+
+ return TRUE;
+}
+
+/*!
+ \fn TQRect TQSvgDevice::boundingRect() const
+
+ Returns the bounding rectangle of the SVG.
+*/
+
+/*!
+ Sets the bounding rectangle of the SVG to rectangle \a r.
+*/
+
+void TQSvgDevice::setBoundingRect( const TQRect &r )
+{
+ brect = r;
+}
+
+/*!
+ Internal implementation of the virtual TQPaintDevice::metric()
+ function.
+
+ \warning Use the TQPaintDeviceMetrics class instead.
+
+ A TQSvgDevice has the following hard coded values: dpi=72,
+ numcolors=16777216 and depth=24. \a m is the metric to get.
+*/
+
+int TQSvgDevice::metric( int m ) const
+{
+ int val;
+ switch ( m ) {
+ case TQPaintDeviceMetrics::PdmWidth:
+ val = brect.width();
+ break;
+ case TQPaintDeviceMetrics::PdmHeight:
+ val = brect.height();
+ break;
+ case TQPaintDeviceMetrics::PdmWidthMM:
+ val = int(25.4/72.0*brect.width());
+ break;
+ case TQPaintDeviceMetrics::PdmHeightMM:
+ val = int(25.4/72.0*brect.height());
+ break;
+ case TQPaintDeviceMetrics::PdmDpiX:
+ val = 72;
+ break;
+ case TQPaintDeviceMetrics::PdmDpiY:
+ val = 72;
+ break;
+ case TQPaintDeviceMetrics::PdmNumColors:
+ val = 16777216;
+ break;
+ case TQPaintDeviceMetrics::PdmDepth:
+ val = 24;
+ break;
+ default:
+ val = 0;
+#if defined(TQT_CHECK_RANGE)
+ qWarning( "TQSvgDevice::metric: Invalid metric command" );
+#endif
+ }
+ return val;
+}
+
+/*!
+ \internal
+
+ Records painter commands and stores them in the TQDomDocument doc.
+*/
+
+bool TQSvgDevice::cmd ( int c, TQPainter *painter, TQPDevCmdParam *p )
+{
+ pt = painter;
+
+ if ( c == PdcBegin ) {
+ TQDomImplementation domImpl;
+ TQDomDocumentType docType = domImpl.createDocumentType( "svg",
+ publicId,
+ systemId );
+ doc = domImpl.createDocument( "http://www.w3.org/2000/svg",
+ "svg", docType );
+ doc.insertBefore( doc.createProcessingInstruction( "xml", piData ),
+ doc.firstChild() );
+ current = doc.documentElement();
+ d->images.clear();
+ d->pixmaps.clear();
+ dirtyTransform = dirtyStyle = FALSE; // ###
+ return TRUE;
+ } else if ( c == PdcEnd ) {
+ return TRUE;
+ }
+
+ TQDomElement e;
+ TQString str;
+ TQRect rect;
+ TQPointArray a;
+ int i, width, height, x, y;
+ switch ( c ) {
+ case PdcNOP:
+ break;
+ case PdcMoveTo:
+ curPt = *p[0].point;
+ break;
+ case PdcLineTo:
+ e = doc.createElement( "line" );
+ e.setAttribute( "x1", curPt.x() );
+ e.setAttribute( "y1", curPt.y() );
+ e.setAttribute( "x2", p[0].point->x() );
+ e.setAttribute( "y2", p[0].point->y() );
+ break;
+ case PdcDrawPoint:
+ case PdcDrawLine:
+ e = doc.createElement( "line" );
+ e.setAttribute( "x1", p[0].point->x() );
+ e.setAttribute( "y1", p[0].point->y() );
+ i = ( c == PdcDrawLine ) ? 1 : 0;
+ e.setAttribute( "x2", p[i].point->x() );
+ e.setAttribute( "y2", p[i].point->y() );
+ break;
+ case PdcDrawRect:
+ case PdcDrawRoundRect:
+ e = doc.createElement( "rect" );
+ x = p[0].rect->x();
+ y = p[0].rect->y();
+ width = p[0].rect->width();
+ height = p[0].rect->height();
+ if ( width < 0 ) {
+ width = -width;
+ x -= width - 1;
+ }
+ if ( height < 0 ) {
+ height = -height;
+ y -= height - 1;
+ }
+ e.setAttribute( "x", x );
+ e.setAttribute( "y", y );
+ e.setAttribute( "width", width );
+ e.setAttribute( "height", height );
+ if ( c == PdcDrawRoundRect ) {
+ e.setAttribute( "rx", (p[1].ival*p[0].rect->width())/200 );
+ e.setAttribute( "ry", (p[2].ival*p[0].rect->height())/200 );
+ }
+ break;
+ case PdcDrawEllipse:
+ rect = *p[0].rect;
+ if ( rect.width() == rect.height() ) {
+ e = doc.createElement( "circle" );
+ double cx = rect.x() + (rect.width() / 2.0);
+ double cy = rect.y() + (rect.height() / 2.0);
+ e.setAttribute( "cx", cx );
+ e.setAttribute( "cy", cy );
+ e.setAttribute( "r", cx - rect.x() );
+ } else {
+ e = doc.createElement( "ellipse" );
+ double cx = rect.x() + (rect.width() / 2.0);
+ double cy = rect.y() + (rect.height() / 2.0);
+ e.setAttribute( "cx", cx );
+ e.setAttribute( "cy", cy );
+ e.setAttribute( "rx", cx - rect.x() );
+ e.setAttribute( "ry", cy - rect.y() );
+ }
+ break;
+ case PdcDrawArc:
+ case PdcDrawPie:
+ case PdcDrawChord: {
+ rect = *p[0].rect;
+ double a = (double)p[1].ival / 16.0 * deg2rad;
+ double al = (double)p[2].ival / 16.0 * deg2rad;
+ double rx = rect.width() / 2.0;
+ double ry = rect.height() / 2.0;
+ double x0 = (double)rect.x() + rx;
+ double y0 = (double)rect.y() + ry;
+ double x1 = x0 + rx*cos(a);
+ double y1 = y0 - ry*sin(a);
+ double x2 = x0 + rx*cos(a+al);
+ double y2 = y0 - ry*sin(a+al);
+ int large = TQABS( al ) > ( 180.0 * deg2rad ) ? 1 : 0;
+ int sweep = al < 0.0 ? 1 : 0;
+ if ( c == PdcDrawPie )
+ str = TQString( "M %1 %2 L %3 %4 " ).arg( x0 ).arg( y0 )
+ .arg( x1 ).arg( y1 );
+ else
+ str = TQString( "M %1 %2 " ).arg( x1 ).arg( y1 );
+ str += TQString( "A %1 %2 %3 %4 %5 %6 %7" )
+ .arg( rx ).arg( ry ).arg( a/deg2rad ). arg( large ).arg( sweep )
+ .arg( x2 ).arg( y2 );
+ if ( c != PdcDrawArc )
+ str += "z";
+ e = doc.createElement( "path" );
+ e.setAttribute( "d", str );
+ }
+ break;
+ case PdcDrawLineSegments:
+ {
+ a = *p[0].ptarr;
+ uint end = a.size() / 2;
+ for (uint i = 0; i < end; i++) {
+ e = doc.createElement( "line" );
+ e.setAttribute( "x1", a[int(2*i)].x() );
+ e.setAttribute( "y1", a[int(2*i)].y() );
+ e.setAttribute( "x2", a[int(2*i+1)].x() );
+ e.setAttribute( "y2", a[int(2*i+1)].y() );
+ if ( i < end - 1 ) // The last one will be done at the end
+ appendChild( e, c );
+ }
+ }
+ break;
+ case PdcDrawPolyline:
+ case PdcDrawPolygon:
+ {
+ a = *p[0].ptarr;
+ e = doc.createElement( ( c == PdcDrawPolyline ) ?
+ "polyline" : "polygon" );
+ for (uint i = 0; i < a.size(); i++) {
+ TQString tmp;
+ tmp.sprintf( "%d %d ", a[ (int)i ].x(), a[ (int)i ].y() );
+ str += tmp;
+ }
+ e.setAttribute( "points", str.stripWhiteSpace() );
+ }
+ break;
+#ifndef TQT_NO_BEZIER
+ case PdcDrawCubicBezier:
+ a = *p[0].ptarr;
+ e = doc.createElement( "path" );
+ str.sprintf( "M %d %d C %d %d %d %d %d %d", a[0].x(), a[0].y(),
+ a[1].x(), a[1].y(), a[2].x(), a[2].y(),
+ a[3].x(), a[3].y() );
+ e.setAttribute( "d", str );
+ break;
+#endif
+ case PdcDrawText2:
+ e = doc.createElement( "text" );
+ if ( p[0].point->x() )
+ e.setAttribute( "x", p[0].point->x() );
+ if ( p[0].point->y() )
+ e.setAttribute( "y", p[0].point->y() );
+ e.appendChild( doc.createTextNode( *p[1].str ) );
+ break;
+ case PdcDrawText2Formatted: {
+ e = doc.createElement( "text" );
+ const TQRect *r = p[0].rect;
+ int tf = p[1].ival;
+ int x, y;
+ // horizontal text tqalignment
+ if ( ( tf & TQt::AlignHCenter ) != 0 ) {
+ x = r->x() + r->width() / 2;
+ e.setAttribute( "text-anchor", "middle" );
+ } else if ( ( tf & TQt::AlignRight ) != 0 ) {
+ x = r->right();
+ e.setAttribute( "text-anchor", "end" );
+ } else {
+ x = r->x();
+ }
+ // vertical text tqalignment
+ if ( ( tf & TQt::AlignVCenter ) != 0 )
+ y = r->y() + ( r->height() + painter->fontMetrics().ascent() ) / 2;
+ else if ( ( tf & TQt::AlignBottom ) != 0 )
+ y = r->bottom();
+ else
+ y = r->y() + painter->fontMetrics().ascent();
+ if ( x )
+ e.setAttribute( "x", x );
+ if ( y )
+ e.setAttribute( "y", y );
+ e.appendChild( doc.createTextNode( *p[2].str ) );
+ }
+ break;
+ case PdcDrawPixmap:
+ case PdcDrawImage:
+ e = doc.createElement( "image" );
+ e.setAttribute( "x", p[0].rect->x() );
+ e.setAttribute( "y", p[0].rect->y() );
+ e.setAttribute( "width", p[0].rect->width() );
+ e.setAttribute( "height", p[0].rect->height() );
+ if ( c == PdcDrawImage ) {
+ ImgElement ie;
+ ie.element = e;
+ ie.image = *p[1].image;
+ d->images.append( ie );
+ } else {
+ PixElement pe;
+ pe.element = e;
+ pe.pixmap = *p[1].pixmap;
+ d->pixmaps.append( pe );
+ }
+ // saving to disk and setting the xlink:href attribute will be
+ // done later in save() once we now the svg document name.
+ break;
+ case PdcSave:
+ e = doc.createElement( "g" );
+ break;
+ case PdcRestore:
+ current = current.parentNode();
+ dirtyTransform = !pt->tqworldMatrix().isIdentity();
+ d->justRestored = TRUE;
+ // ### reset dirty flags
+ break;
+ case PdcSetBkColor:
+ case PdcSetBkMode:
+ case PdcSetROP:
+ case PdcSetBrushOrigin:
+ case PdcSetFont:
+ case PdcSetPen:
+ case PdcSetBrush:
+ dirtyStyle = TRUE;
+ break;
+ case PdcSetTabStops:
+ // ###
+ break;
+ case PdcSetTabArray:
+ // ###
+ break;
+ case PdcSetVXform:
+ case PdcSetWindow:
+ case PdcSetViewport:
+ case PdcSetWXform:
+ case PdcSetWMatrix:
+ case PdcSaveWMatrix:
+ case PdcRestoreWMatrix:
+ dirtyTransform = TRUE;
+ break;
+ case PdcSetClip:
+ // ###
+ break;
+ case PdcSetClipRegion:
+ {
+ // We skip the clip after restore, since restoring the clip is done automatically by
+ // the viewer as part of the tree structure. It doesn't hurt to write the region
+ // out, but it doubles the number of clipregions defined in the final svg.
+ if (d->justRestored) {
+ d->justRestored = FALSE;
+ return TRUE;
+ }
+
+ TQMemArray<TQRect> rects = p[0].rgn->tqrects();
+ if (rects.count() == 0)
+ return TRUE;
+ d->currentClip++;
+ e = doc.createElement( "clipPath" );
+ e.setAttribute( "id", TQString("clip%1").arg(d->currentClip) );
+ for (int i=0; i<(int)rects.count(); ++i) {
+ TQDomElement ce = doc.createElement("rect");
+ ce.setAttribute( "x", rects.at(i).x() );
+ ce.setAttribute( "y", rects.at(i).y() );
+ ce.setAttribute( "width", rects.at(i).width() );
+ ce.setAttribute( "height", rects.at(i).height() );
+ e.appendChild(ce);
+ }
+ break;
+ }
+ default:
+#if defined(CHECK_RANGE)
+ qWarning( "TQSVGDevice::cmd: Invalid command %d", c );
+#endif
+ break;
+ }
+
+ appendChild( e, c );
+
+ return TRUE;
+}
+
+/*!
+ \internal
+
+ Appends the child and applys any style and transformation.
+
+*/
+
+void TQSvgDevice::appendChild( TQDomElement &e, int c )
+{
+ if ( !e.isNull() ) {
+ current.appendChild( e );
+ if ( c == PdcSave )
+ current = e;
+ // ### optimize application of attributes utilizing <g>
+ if ( c == PdcSetClipRegion ) {
+ TQDomElement ne;
+ ne = doc.createElement( "g" );
+ ne.setAttribute( "style", TQString("clip-path:url(#clip%1)").arg(d->currentClip) );
+ current.appendChild( ne );
+ current = ne;
+ } else {
+ if ( dirtyStyle ) // only reset when entering
+ applyStyle( &e, c ); // or leaving a <g> tag
+ if ( dirtyTransform && e.tagName() != "g" ) {
+ // same as above but not for <g> tags
+ applyTransform( &e );
+ if ( c == PdcSave )
+ dirtyTransform = FALSE;
+ }
+ }
+ }
+}
+
+
+/*!
+ \internal
+
+ Push the current drawing attributes on a stack.
+
+ \sa restoreAttributes()
+*/
+
+void TQSvgDevice::saveAttributes()
+{
+ pt->save();
+ // copy old state
+ TQSvgDeviceState st( *curr );
+ d->stack.append( st );
+ curr = &d->stack.last();
+}
+
+/*!
+ \internal
+
+ Pop the current drawing attributes off the stack.
+
+ \sa saveAttributes()
+*/
+
+void TQSvgDevice::restoreAttributes()
+{
+ pt->restore();
+ TQ_ASSERT( d->stack.count() > 1 );
+ d->stack.remove( d->stack.fromLast() );
+ curr = &d->stack.last();
+}
+
+/*!
+ \internal
+
+ Evaluate \a node, drawing on \a p. Allows recursive calls.
+*/
+
+bool TQSvgDevice::play( const TQDomNode &node )
+{
+ saveAttributes();
+
+ ElementType t = (*qSvgTypeMap)[ node.nodeName() ];
+
+ if ( t == LineElement && pt->pen().style() == TQt::NoPen ) {
+ TQPen p = pt->pen();
+ p.tqsetStyle( TQt::SolidLine );
+ pt->setPen( p );
+ }
+ TQDomNamedNodeMap attr = node.attributes();
+ if ( attr.tqcontains( "style" ) )
+ setStyle( attr.namedItem( "style" ).nodeValue() );
+ // ### might have to exclude more elements from transform
+ if ( t != SvgElement && attr.tqcontains( "transform" ) )
+ setTransform( attr.namedItem( "transform" ).nodeValue() );
+ uint i = attr.length();
+ if ( i > 0 ) {
+ TQPen pen = pt->pen();
+ TQFont font = pt->font();
+ while ( i-- ) {
+ TQDomNode n = attr.item( i );
+ TQString a = n.nodeName();
+ TQString val = n.nodeValue().lower().stripWhiteSpace();
+ setStyleProperty( a, val, &pen, &font, &curr->textalign );
+ }
+ pt->setPen( pen );
+ pt->setFont( font );
+ }
+
+ int x1, y1, x2, y2, rx, ry, w, h;
+ double cx1, cy1, crx, cry;
+ switch ( t ) {
+ case CommentElement:
+ // ignore
+ break;
+ case RectElement:
+ rx = ry = 0;
+ x1 = lenToInt( attr, "x" );
+ y1 = lenToInt( attr, "y" );
+ w = lenToInt( attr, "width" );
+ h = lenToInt( attr, "height" );
+ if ( w == 0 || h == 0 ) // prevent div by zero below
+ break;
+ x2 = (int)attr.tqcontains( "rx" ); // tiny abuse of x2 and y2
+ y2 = (int)attr.tqcontains( "ry" );
+ if ( x2 )
+ rx = lenToInt( attr, "rx" );
+ if ( y2 )
+ ry = lenToInt( attr, "ry" );
+ if ( x2 && !y2 )
+ ry = rx;
+ else if ( !x2 && y2 )
+ rx = ry;
+ rx = int(200.0*double(rx)/double(w));
+ ry = int(200.0*double(ry)/double(h));
+ pt->drawRoundRect( x1, y1, w, h, rx, ry );
+ break;
+ case CircleElement:
+ cx1 = lenToDouble( attr, "cx" ) + 0.5;
+ cy1 = lenToDouble( attr, "cy" ) + 0.5;
+ crx = lenToDouble( attr, "r" );
+ pt->drawEllipse( (int)(cx1-crx), (int)(cy1-crx), (int)(2*crx), (int)(2*crx) );
+ break;
+ case EllipseElement:
+ cx1 = lenToDouble( attr, "cx" ) + 0.5;
+ cy1 = lenToDouble( attr, "cy" ) + 0.5;
+ crx = lenToDouble( attr, "rx" );
+ cry = lenToDouble( attr, "ry" );
+ pt->drawEllipse( (int)(cx1-crx), (int)(cy1-cry), (int)(2*crx), (int)(2*cry) );
+ break;
+ case LineElement:
+ {
+ x1 = lenToInt( attr, "x1" );
+ x2 = lenToInt( attr, "x2" );
+ y1 = lenToInt( attr, "y1" );
+ y2 = lenToInt( attr, "y2" );
+ TQPen p = pt->pen();
+ w = p.width();
+ p.setWidth( (unsigned int)(w * (TQABS(pt->tqworldMatrix().m11()) + TQABS(pt->tqworldMatrix().m22())) / 2) );
+ pt->setPen( p );
+ pt->drawLine( x1, y1, x2, y2 );
+ p.setWidth( w );
+ pt->setPen( p );
+ }
+ break;
+ case PolylineElement:
+ case PolygonElement:
+ {
+ TQString pts = attr.namedItem( "points" ).nodeValue();
+ pts = pts.simplifyWhiteSpace();
+ TQStringList sl = TQStringList::split( TQRegExp( TQString::tqfromLatin1("[ ,]") ), pts );
+ TQPointArray ptarr( (uint)sl.count() / 2);
+ for ( int i = 0; i < (int)sl.count() / 2; i++ ) {
+ double dx = sl[2*i].toDouble();
+ double dy = sl[2*i+1].toDouble();
+ ptarr.setPoint( i, int(dx), int(dy) );
+ }
+ if ( t == PolylineElement ) {
+ if ( pt->brush().style() != TQt::NoBrush ) {
+ TQPen pn = pt->pen();
+ pt->setPen( TQt::NoPen );
+ pt->drawPolygon( ptarr );
+ pt->setPen( pn );
+ }
+ pt->drawPolyline( ptarr ); // ### closes when filled. bug ?
+ } else {
+ pt->drawPolygon( ptarr );
+ }
+ }
+ break;
+ case SvgElement:
+ case GroupElement:
+ case AnchorElement:
+ {
+ TQDomNode child = node.firstChild();
+ while ( !child.isNull() ) {
+ play( child );
+ child = child.nextSibling();
+ }
+ }
+ break;
+ case PathElement:
+ drawPath( attr.namedItem( "d" ).nodeValue() );
+ break;
+ case TSpanElement:
+ case TextElement:
+ {
+ if ( attr.tqcontains( "x" ) )
+ curr->textx = lenToInt( attr, "x" );
+ if ( attr.tqcontains( "y" ) )
+ curr->texty = lenToInt( attr, "y" );
+ if ( t == TSpanElement ) {
+ curr->textx += lenToInt( attr, "dx" );
+ curr->texty += lenToInt( attr, "dy" );
+ }
+ // backup old colors
+ TQPen pn = pt->pen();
+ TQColor pcolor = pn.color();
+ TQColor bcolor = pt->brush().color();
+ TQDomNode c = node.firstChild();
+ while ( !c.isNull() ) {
+ if ( c.isText() ) {
+ // we have pen and brush reversed for text drawing
+ pn.setColor( bcolor );
+ pt->setPen( pn );
+ TQString text = c.toText().nodeValue();
+ text = text.simplifyWhiteSpace(); // ### 'preserve'
+ w = pt->fontMetrics().width( text );
+ if ( curr->textalign == TQt::AlignHCenter )
+ curr->textx -= w / 2;
+ else if ( curr->textalign == TQt::AlignRight )
+ curr->textx -= w;
+ pt->drawText( curr->textx, curr->texty, text );
+ // restore pen
+ pn.setColor( pcolor );
+ pt->setPen( pn );
+ curr->textx += w;
+ } else if ( c.isElement() &&
+ c.toElement().tagName() == "tspan" ) {
+ play( c );
+
+ }
+ c = c.nextSibling();
+ }
+ if ( t == TSpanElement ) {
+ // move current text position in tqparent text element
+ StateList::Iterator it = --d->stack.fromLast();
+ (*it).textx = curr->textx;
+ (*it).texty = curr->texty;
+ }
+ }
+ break;
+ case ImageElement:
+ {
+ x1 = lenToInt( attr, "x" );
+ y1 = lenToInt( attr, "y" );
+ w = lenToInt( attr, "width" );
+ h = lenToInt( attr, "height" );
+ TQString href = attr.namedItem( "xlink:href" ).nodeValue();
+ // ### catch references to embedded .svg files
+ TQPixmap pix;
+ if ( !pix.load( href ) ) {
+ qWarning( "TQSvgDevice::play: Couldn't load image %s", href.latin1() );
+ break;
+ }
+ pt->drawPixmap( TQRect( x1, y1, w, h ), pix );
+ }
+ break;
+ case DescElement:
+ case TitleElement:
+ // ignored for now
+ break;
+ case ClipElement:
+ {
+ TQDomNode child = node.firstChild();
+ TQRegion region;
+ while (!child.isNull()) {
+ TQDomNamedNodeMap tqchildAttr = child.attributes();
+ if ( child.nodeName() == "rect" ) {
+ TQRect r;
+ r.setX(lenToInt( tqchildAttr, "x" ));
+ r.setY(lenToInt( tqchildAttr, "y" ));
+ r.setWidth(lenToInt( tqchildAttr, "width" ));
+ r.setHeight(lenToInt( tqchildAttr, "height" ));
+ region |= r;
+ } else if ( child.nodeName() == "ellipse" ) {
+ TQRect r;
+ int x = lenToInt( tqchildAttr, "cx" );
+ int y = lenToInt( tqchildAttr, "cy" );
+ int width = lenToInt( tqchildAttr, "rx" );
+ int height = lenToInt( tqchildAttr, "ry" );
+ r.setX( x - width );
+ r.setY( y - height );
+ r.setWidth( width * 2 );
+ r.setHeight( height * 2 );
+ TQRegion rgn( r, TQRegion::Ellipse );
+ region |= rgn;
+ }
+ child = child.nextSibling();
+ }
+ // Store the region in a named map so that it can be used when the
+ // group node is entered.
+ TQString idString = attr.namedItem("id").nodeValue();
+ if (!idString.isEmpty())
+ d->clipPathTable[idString] = region;
+ break;
+ }
+ case InvalidElement:
+ qWarning( "TQSvgDevice::play: unknown element type %s",
+ node.nodeName().latin1() );
+ break;
+ };
+
+ restoreAttributes();
+
+ return TRUE;
+}
+
+/*!
+ \internal
+
+ Parses a CSS2-compatible color specification. Either a keyword or
+ a numerical RGB specification like #ff00ff or rgb(255,0,50%).
+*/
+
+TQColor TQSvgDevice::parseColor( const TQString &col )
+{
+ static const struct ColorTable {
+ const char *name;
+ const char *rgb;
+ } coltab[] = {
+ { "black", "#000000" },
+ { "silver", "#c0c0c0" },
+ { "gray", "#808080" },
+ { "white", "#ffffff" },
+ { "maroon", "#800000" },
+ { "red", "#ff0000" },
+ { "purple", "#800080" },
+ { "fuchsia", "#ff00ff" },
+ { "green", "#008000" },
+ { "lime", "#00ff00" },
+ { "olive", "#808000" },
+ { "yellow", "#ffff00" },
+ { "navy", "#000080" },
+ { "blue", "#0000ff" },
+ { "teal", "#008080" },
+ { "aqua", "#00ffff" },
+ // ### the latest spec has more
+ { 0, 0 }
+ };
+
+ // initialize color map on first use
+ if ( !qSvgColMap ) {
+ qSvgColMap = new TQMap<TQString, TQString>;
+ const struct ColorTable *t = coltab;
+ while ( t->name ) {
+ qSvgColMap->insert( t->name, t->rgb );
+ t++;
+ }
+ }
+
+ // a keyword ?
+ if ( qSvgColMap->tqcontains ( col ) )
+ return TQColor( (*qSvgColMap)[ col ] );
+ // in rgb(r,g,b) form ?
+ TQString c = col;
+ c.tqreplace( TQRegExp( TQString::tqfromLatin1("\\s*") ), "" );
+ TQRegExp reg( TQString::tqfromLatin1("^rgb\\((\\d+)(%?),(\\d+)(%?),(\\d+)(%?)\\)$") );
+ if ( reg.search( c ) >= 0 ) {
+ int comp[3];
+ for ( int i = 0; i < 3; i++ ) {
+ comp[ i ] = reg.cap( 2*i+1 ).toInt();
+ if ( !reg.cap( 2*i+2 ).isEmpty() ) // percentage ?
+ comp[ i ] = int((double(255*comp[ i ])/100.0));
+ }
+ return TQColor( comp[ 0 ], comp[ 1 ], comp[ 2 ] );
+ }
+
+ // check for predefined TQt color objects, #RRGGBB and #RGB
+ return TQColor( col );
+}
+
+/*!
+ \internal
+
+ Parse a <length> datatype consisting of a number followed by an
+ optional unit specifier. Can be used for type <coordinate> as
+ well. For relative units the value of \a horiz will determine
+ whether the horizontal or vertical dimension will be used.
+*/
+
+double TQSvgDevice::parseLen( const TQString &str, bool *ok, bool horiz ) const
+{
+ TQRegExp reg( TQString::tqfromLatin1("([+-]?\\d*\\.*\\d*[Ee]?[+-]?\\d*)(em|ex|px|%|pt|pc|cm|mm|in|)$") );
+ if ( reg.search( str ) == -1 ) {
+ qWarning( "TQSvgDevice::parseLen: couldn't parse %s ", str.latin1() );
+ if ( ok )
+ *ok = FALSE;
+ return 0.0;
+ }
+
+ double dbl = reg.cap( 1 ).toDouble();
+ TQString u = reg.cap( 2 );
+ if ( !u.isEmpty() && u != "px" ) {
+ TQPaintDeviceMetrics m( pt->tqdevice() );
+ if ( u == "em" ) {
+ TQFontInfo fi( pt->font() );
+ dbl *= fi.pixelSize();
+ } else if ( u == "ex" ) {
+ TQFontInfo fi( pt->font() );
+ dbl *= 0.5 * fi.pixelSize();
+ } else if ( u == "%" )
+ dbl *= (horiz ? pt->window().width() : pt->window().height())/100.0;
+ else if ( u == "cm" )
+ dbl *= m.logicalDpiX() / 2.54;
+ else if ( u == "mm" )
+ dbl *= m.logicalDpiX() / 25.4;
+ else if ( u == "in" )
+ dbl *= m.logicalDpiX();
+ else if ( u == "pt" )
+ dbl *= m.logicalDpiX() / 72.0;
+ else if ( u == "pc" )
+ dbl *= m.logicalDpiX() / 6.0;
+ else
+ qWarning( "TQSvgDevice::parseLen: Unknown unit %s", u.latin1() );
+ }
+ if ( ok )
+ *ok = TRUE;
+ return dbl;
+}
+
+/*!
+ \internal
+
+ Returns the length specified in attribute \a attr in \a map. If
+ the specified attribute doesn't exist or can't be parsed \a def is
+ returned.
+*/
+
+int TQSvgDevice::lenToInt( const TQDomNamedNodeMap &map, const TQString &attr,
+ int def ) const
+{
+ if ( map.tqcontains( attr ) ) {
+ bool ok;
+ double dbl = parseLen( map.namedItem( attr ).nodeValue(), &ok );
+ if ( ok )
+ return tqRound( dbl );
+ }
+ return def;
+}
+
+double TQSvgDevice::lenToDouble( const TQDomNamedNodeMap &map, const TQString &attr,
+ int def ) const
+{
+ if ( map.tqcontains( attr ) ) {
+ bool ok;
+ double d = parseLen( map.namedItem( attr ).nodeValue(), &ok );
+ if ( ok )
+ return d;
+ }
+ return def;
+}
+
+void TQSvgDevice::setStyleProperty( const TQString &prop, const TQString &val,
+ TQPen *pen, TQFont *font, int *talign )
+{
+ if ( prop == "stroke" ) {
+ if ( val == "none" ) {
+ pen->tqsetStyle( TQt::NoPen );
+ } else {
+ pen->setColor( parseColor( val ));
+ if ( pen->style() == TQt::NoPen )
+ pen->tqsetStyle( TQt::SolidLine );
+ if ( pen->width() == 0 )
+ pen->setWidth( 1 );
+ }
+ } else if ( prop == "stroke-width" ) {
+ double w = parseLen( val );
+ if ( w > 0.0001 )
+ pen->setWidth( int(w) );
+ else
+ pen->tqsetStyle( TQt::NoPen );
+ } else if ( prop == "stroke-linecap" ) {
+ if ( val == "butt" )
+ pen->tqsetCapStyle( TQt::FlatCap );
+ else if ( val == "round" )
+ pen->tqsetCapStyle( TQt::RoundCap );
+ else if ( val == "square" )
+ pen->tqsetCapStyle( TQt::SquareCap );
+ } else if ( prop == "stroke-linejoin" ) {
+ if ( val == "miter" )
+ pen->tqsetJoinStyle( TQt::MiterJoin );
+ else if ( val == "round" )
+ pen->tqsetJoinStyle( TQt::RoundJoin );
+ else if ( val == "bevel" )
+ pen->tqsetJoinStyle( TQt::BevelJoin );
+ } else if ( prop == "stroke-dasharray" ) {
+ if ( val == "18,6" )
+ pen->tqsetStyle( TQt::DashLine );
+ else if ( val == "3" )
+ pen->tqsetStyle( TQt::DotLine );
+ else if ( val == "9,6,3,6" )
+ pen->tqsetStyle( TQt::DashDotLine );
+ else if ( val == "9,3,3" )
+ pen->tqsetStyle( TQt::DashDotDotLine );
+ else
+ pen->tqsetStyle( TQt::DotLine );
+ } else if ( prop == "fill" ) {
+ if ( val == "none" )
+ pt->setBrush( TQt::NoBrush );
+ else
+ pt->setBrush( parseColor( val ) );
+ } else if ( prop == "font-size" ) {
+ font->setPointSizeFloat( float(parseLen( val )) );
+ } else if ( prop == "font-family" ) {
+ font->setFamily( val );
+ } else if ( prop == "font-style" ) {
+ if ( val == "normal" )
+ font->setItalic( FALSE );
+ else if ( val == "italic" )
+ font->setItalic( TRUE );
+ else
+ qWarning( "TQSvgDevice::setStyleProperty: unhandled "
+ "font-style: %s", val.latin1() );
+ } else if ( prop == "font-weight" ) {
+ int w = font->weight();
+ // no exact equivalents so we have to "round" a little bit
+ if ( val == "100" || val == "200" )
+ w = TQFont::Light;
+ if ( val == "300" || val == "400" || val == "normal" )
+ w = TQFont::Normal;
+ else if ( val == "500" || val == "600" )
+ w = TQFont::DemiBold;
+ else if ( val == "700" || val == "bold" || val == "800" )
+ w = TQFont::Bold;
+ else if ( val == "900" )
+ w = TQFont::Black;
+ font->setWeight( w );
+ } else if ( prop == "text-anchor" ) {
+ if ( val == "middle" )
+ *talign = TQt::AlignHCenter;
+ else if ( val == "end" )
+ *talign = TQt::AlignRight;
+ else
+ *talign = TQt::AlignLeft;
+ } else if ( prop == "clip-path" ) {
+ if (val.startsWith("url(#")) {
+ TQString clipName = val.mid(5, val.length() - 6);
+ if (!clipName.isEmpty()) {
+ TQRegion clipRegion = d->clipPathTable[clipName];
+ if (!clipRegion.isEmpty())
+ pt->setClipRegion(pt->clipRegion() & clipRegion, TQPainter::CoordPainter);
+ }
+ }
+ }
+}
+
+void TQSvgDevice::setStyle( const TQString &s )
+{
+ TQStringList rules = TQStringList::split( TQChar(';'), s );
+
+ TQPen pen = pt->pen();
+ TQFont font = pt->font();
+
+ TQStringList::ConstIterator it = rules.begin();
+ for ( ; it != rules.end(); it++ ) {
+ int col = (*it).tqfind( ':' );
+ if ( col > 0 ) {
+ TQString prop = TQT_TQSTRING((*it).left( col )).simplifyWhiteSpace();
+ TQString val = (*it).right( (*it).length() - col - 1 );
+ val = val.lower().stripWhiteSpace();
+ setStyleProperty( prop, val, &pen, &font, &curr->textalign );
+ }
+ }
+
+ pt->setPen( pen );
+ pt->setFont( font );
+}
+
+void TQSvgDevice::setTransform( const TQString &tr )
+{
+ TQString t = tr.simplifyWhiteSpace();
+
+ TQRegExp reg( TQString::tqfromLatin1("\\s*([\\w]+)\\s*\\(([^\\(]*)\\)") );
+ int index = 0;
+ while ( (index = reg.search(t, index)) >= 0 ) {
+ TQString command = reg.cap( 1 );
+ TQString params = reg.cap( 2 );
+ TQStringList plist = TQStringList::split( TQRegExp(TQString::tqfromLatin1("[,\\s]")), params );
+ if ( command == "translate" ) {
+ double tx = 0, ty = 0;
+ tx = plist[0].toDouble();
+ if ( plist.count() >= 2 )
+ ty = plist[1].toDouble();
+ pt->translate( tx, ty );
+ } else if ( command == "rotate" ) {
+ pt->rotate( plist[0].toDouble() );
+ } else if ( command == "scale" ) {
+ double sx, sy;
+ sx = sy = plist[0].toDouble();
+ if ( plist.count() >= 2 )
+ sy = plist[1].toDouble();
+ pt->scale( sx, sy );
+ } else if ( command == "matrix" && plist.count() >= 6 ) {
+ double m[ 6 ];
+ for (int i = 0; i < 6; i++)
+ m[ i ] = plist[ i ].toDouble();
+ TQWMatrix wm( m[ 0 ], m[ 1 ], m[ 2 ],
+ m[ 3 ], m[ 4 ], m[ 5 ] );
+ pt->setWorldMatrix( wm, TRUE );
+ } else if ( command == "skewX" ) {
+ pt->shear( 0.0, tan( plist[0].toDouble() * deg2rad ) );
+ } else if ( command == "skewY" ) {
+ pt->shear( tan( plist[0].toDouble() * deg2rad ), 0.0 );
+ }
+
+ // move on to next command
+ index += reg.matchedLength();
+ }
+}
+
+void TQSvgDevice::drawPath( const TQString &data )
+{
+ double x0 = 0, y0 = 0; // starting point
+ double x = 0, y = 0; // current point
+ double controlX = 0, controlY = 0; // last control point for curves
+ TQPointArray path( 500 ); // resulting path
+ TQValueList<int> subIndex; // start indices for subpaths
+ TQPointArray quad( 4 ), bezier; // for curve calculations
+ int pcount = 0; // current point array index
+ uint idx = 0; // current data position
+ int mode = 0, lastMode = 0; // parser state
+ bool relative = FALSE; // e.g. 'h' vs. 'H'
+ TQString commands( "MZLHVCSTQTA" ); // recognized commands
+ int cmdArgs[] = { 2, 0, 2, 1, 1, 6, 4, 4, 2, 7 }; // no of arguments
+ TQRegExp reg( TQString::tqfromLatin1("\\s*,?\\s*([+-]?\\d*\\.?\\d*)") ); // floating point
+
+ subIndex.append( 0 );
+ // detect next command
+ while ( idx < data.length() ) {
+ TQChar ch = data[ (int)idx++ ];
+ if ( ch.isSpace() )
+ continue;
+ TQChar chUp = ch.upper();
+ int cmd = commands.tqfind( chUp );
+ if ( cmd >= 0 ) {
+ // switch to new command mode
+ mode = cmd;
+ relative = ( ch != chUp ); // e.g. 'm' instead of 'M'
+ } else {
+ if ( mode && !ch.isLetter() ) {
+ cmd = mode; // continue in previous mode
+ idx--;
+ } else {
+ qWarning( "TQSvgDevice::drawPath: Unknown command" );
+ return;
+ }
+ }
+
+ // read in the required number of arguments
+ const int maxArgs = 7;
+ double arg[ maxArgs ];
+ int numArgs = cmdArgs[ cmd ];
+ for ( int i = 0; i < numArgs; i++ ) {
+ int pos = reg.search( data, idx );
+ if ( pos == -1 ) {
+ qWarning( "TQSvgDevice::drawPath: Error parsing arguments" );
+ return;
+ }
+ arg[ i ] = reg.cap( 1 ).toDouble();
+ idx = pos + reg.matchedLength();
+ };
+
+ // process command
+ double offsetX = relative ? x : 0; // correction offsets
+ double offsetY = relative ? y : 0; // for relative commands
+ switch ( mode ) {
+ case 0: // 'M' move to
+ if ( x != x0 || y != y0 )
+ path.setPoint( pcount++, int(x0), int(y0) );
+ x = x0 = arg[ 0 ] + offsetX;
+ y = y0 = arg[ 1 ] + offsetY;
+ subIndex.append( pcount );
+ path.setPoint( pcount++, int(x0), int(y0) );
+ mode = 2; // -> 'L'
+ break;
+ case 1: // 'Z' close path
+ path.setPoint( pcount++, int(x0), int(y0) );
+ x = x0;
+ y = y0;
+ mode = 0;
+ break;
+ case 2: // 'L' line to
+ x = arg[ 0 ] + offsetX;
+ y = arg[ 1 ] + offsetY;
+ path.setPoint( pcount++, int(x), int(y) );
+ break;
+ case 3: // 'H' horizontal line
+ x = arg[ 0 ] + offsetX;
+ path.setPoint( pcount++, int(x), int(y) );
+ break;
+ case 4: // 'V' vertical line
+ y = arg[ 0 ] + offsetY;
+ path.setPoint( pcount++, int(x), int(y) );
+ break;
+#ifndef TQT_NO_BEZIER
+ case 5: // 'C' cubic bezier curveto
+ case 6: // 'S' smooth shorthand
+ case 7: // 'Q' quadratic bezier curves
+ case 8: { // 'T' smooth shorthand
+ quad.setPoint( 0, int(x), int(y) );
+ // if possible, reflect last control point if smooth shorthand
+ if ( mode == 6 || mode == 8 ) { // smooth 'S' and 'T'
+ bool cont = mode == lastMode ||
+ (mode == 6 && lastMode == 5) || // 'S' and 'C'
+ (mode == 8 && lastMode == 7); // 'T' and 'Q'
+ x = cont ? 2*x-controlX : x;
+ y = cont ? 2*y-controlY : y;
+ quad.setPoint( 1, int(x), int(y) );
+ quad.setPoint( 2, int(x), int(y) );
+ }
+ for ( int j = 0; j < numArgs/2; j++ ) {
+ x = arg[ 2*j ] + offsetX;
+ y = arg[ 2*j+1 ] + offsetY;
+ quad.setPoint( j+4-numArgs/2, int(x), int(y) );
+ }
+ // remember last control point for next shorthand
+ controlX = quad[ 2 ].x();
+ controlY = quad[ 2 ].y();
+ // transform quadratic into cubic Bezier
+ if ( mode == 7 || mode == 8 ) { // cubic 'Q' and 'T'
+ int x31 = quad[0].x()+int(2.0*(quad[2].x()-quad[0].x())/3.0);
+ int y31 = quad[0].y()+int(2.0*(quad[2].y()-quad[0].y())/3.0);
+ int x32 = quad[2].x()+int(2.0*(quad[3].x()-quad[2].x())/3.0);
+ int y32 = quad[2].y()+int(2.0*(quad[3].y()-quad[2].y())/3.0);
+ quad.setPoint( 1, x31, y31 );
+ quad.setPoint( 2, x32, y32 );
+ }
+ // calculate points on curve
+ bezier = quad.cubicBezier();
+ // reserve more space if needed
+ if ( bezier.size() > path.size() - pcount )
+ path.resize( path.size() - pcount + bezier.size() );
+ // copy
+ for ( int k = 0; k < (int)bezier.size(); k ++ )
+ path.setPoint( pcount++, bezier[ k ] );
+ break;
+ }
+#endif // TQT_NO_BEZIER
+ case 9: // 'A' elliptical arc curve
+ // ### just a straight line
+ x = arg[ 5 ] + offsetX;
+ y = arg[ 6 ] + offsetY;
+ path.setPoint( pcount++, int(x), int(y) );
+ break;
+ };
+ lastMode = mode;
+ // array almost full ? expand for next loop
+ if ( pcount >= (int)path.size() - 4 )
+ path.resize( 2 * path.size() );
+ }
+
+ subIndex.append( pcount ); // dummy marking the end
+ if ( pt->brush().style() != TQt::NoBrush ) {
+ // fill the area without stroke first
+ if ( x != x0 || y != y0 )
+ path.setPoint( pcount++, int(x0), int(y0) );
+ TQPen pen = pt->pen();
+ pt->setPen( TQt::NoPen );
+ pt->tqdrawPolygon( path, FALSE, 0, pcount );
+ pt->setPen( pen );
+ }
+ // draw each subpath stroke seperately
+ TQValueListConstIterator<int> it = subIndex.begin();
+ int start = 0;
+ while ( it != subIndex.fromLast() ) {
+ int next = *++it;
+ // ### always joins ends if first and last point coincide.
+ // ### 'Z' can't have the desired effect
+ pt->tqdrawPolyline( path, start, next-start );
+ start = next;
+ }
+}
+
+void TQSvgDevice::applyStyle( TQDomElement *e, int c ) const
+{
+ // ### do not write every attribute each time
+ TQColor pcol = pt->pen().color();
+ TQColor bcol = pt->brush().color();
+ TQString s;
+ if ( c == PdcDrawText2 || c == PdcDrawText2Formatted ) {
+ // TQPainter has a reversed understanding of pen/stroke vs.
+ // brush/fill for text
+ s += TQString( "fill:rgb(%1,%2,%3);" )
+ .arg( pcol.red() ).arg( pcol.green() ).arg( pcol.blue() );
+ s += TQString( "stroke-width:0;" );
+ TQFont f = pt->font();
+ TQFontInfo fi( f );
+ s += TQString( "font-size:%1;" ).arg( fi.pointSize() );
+ s += TQString( "font-style:%1;" )
+ .arg( f.italic() ? "italic" : "normal" );
+ // not a very scientific distribution
+ TQString fw;
+ if ( f.weight() <= TQFont::Light )
+ fw = "100";
+ else if ( f.weight() <= TQFont::Normal )
+ fw = "400";
+ else if ( f.weight() <= TQFont::DemiBold )
+ fw = "600";
+ else if ( f.weight() <= TQFont::Bold )
+ fw = "700";
+ else if ( f.weight() <= TQFont::Black )
+ fw = "800";
+ else
+ fw = "900";
+ s += TQString( "font-weight:%1;" ).arg( fw );
+ s += TQString( "font-family:%1;" ).arg( f.family() );
+ } else {
+ s += TQString( "stroke:rgb(%1,%2,%3);" )
+ .arg( pcol.red() ).arg( pcol.green() ).arg( pcol.blue() );
+ double pw = pt->pen().width();
+ if ( pw == 0 && pt->pen().style() != TQt::NoPen )
+ pw = 0.9;
+ if ( c == PdcDrawLine )
+ pw /= (TQABS(pt->tqworldMatrix().m11()) + TQABS(pt->tqworldMatrix().m22())) / 2.0;
+ s += TQString( "stroke-width:%1;" ).arg( pw );
+ if ( pt->pen().style() == TQt::DashLine )
+ s+= TQString( "stroke-dasharray:18,6;" );
+ else if ( pt->pen().style() == TQt::DotLine )
+ s+= TQString( "stroke-dasharray:3;" );
+ else if ( pt->pen().style() == TQt::DashDotLine )
+ s+= TQString( "stroke-dasharray:9,6,3,6;" );
+ else if ( pt->pen().style() == TQt::DashDotDotLine )
+ s+= TQString( "stroke-dasharray:9,3,3;" );
+ if ( pt->brush().style() == TQt::NoBrush || c == PdcDrawPolyline ||
+ c == PdcDrawCubicBezier )
+ s += "fill:none;"; // TQt polylines use no brush, neither do Beziers
+ else
+ s += TQString( "fill:rgb(%1,%2,%3);" )
+ .arg( bcol.red() ).arg( bcol.green() ).arg( bcol.blue() );
+ }
+ e->setAttribute( "style", s );
+}
+
+void TQSvgDevice::applyTransform( TQDomElement *e ) const
+{
+ TQWMatrix m = pt->tqworldMatrix();
+
+ TQString s;
+ bool rot = ( m.m11() != 1.0 || m.m12() != 0.0 ||
+ m.m21() != 0.0 || m.m22() != 1.0 );
+ if ( !rot && ( m.dx() != 0.0 || m.dy() != 0.0 ) )
+ s = TQString( "translate(%1,%2)" ).arg( m.dx() ).arg( m.dy() );
+ else if ( rot ) {
+ if ( m.m12() == 0.0 && m.m21() == 0.0 &&
+ m.dx() == 0.0 && m.dy() == 0.0 )
+ s = TQString( "scale(%1,%2)" ).arg( m.m11() ).arg( m.m22() );
+ else
+ s = TQString( "matrix(%1,%2,%3,%4,%5,%6)" )
+ .arg( m.m11() ).arg( m.m12() )
+ .arg( m.m21() ).arg( m.m22() )
+ .arg( m.dx() ).arg( m.dy() );
+ }
+ else
+ return;
+
+ e->setAttribute( "transform", s );
+}
+
+#endif // TQT_NO_SVG
diff --git a/tqtinterface/qt4/src/xml/tqsvgdevice_p.h b/tqtinterface/qt4/src/xml/tqsvgdevice_p.h
new file mode 100644
index 0000000..5a4b838
--- /dev/null
+++ b/tqtinterface/qt4/src/xml/tqsvgdevice_p.h
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** Definition of the TQSvgDevice class
+**
+** Created : 001024
+**
+** Copyright (C) 2000-2008 Trolltech ASA. All rights reserved.
+**
+** This file is part of the xml module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+*****************************************************************************/
+
+#ifndef TQSVGDEVICE_P_H
+#define TQSVGDEVICE_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the TQt API. It exists for the convenience
+// of the TQPicture class. This header file may change from
+// version to version without notice, or even be removed.
+//
+// We mean it.
+//
+//
+
+#ifndef TQT_H
+#include "tqpaintdevice.h"
+#include "tqrect.h"
+#include "tqdom.h"
+#endif // TQT_H
+
+#if !defined(TQT_MODULE_XML) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_XML )
+#define TQM_EXPORT_SVG
+#else
+#define TQM_EXPORT_SVG TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_SVG
+
+class TQPainter;
+class TQDomNode;
+class TQDomNamedNodeMap;
+struct TQSvgDeviceState;
+class TQSvgDevicePrivate;
+
+class TQM_EXPORT_SVG TQSvgDevice : public TQPaintDevice
+{
+public:
+ TQSvgDevice();
+ ~TQSvgDevice();
+
+ bool play( TQPainter *p );
+
+ TQString toString() const;
+
+ bool load( TQIODevice *dev );
+ bool save( TQIODevice *dev );
+ bool save( const TQString &fileName );
+
+ TQRect boundingRect() const;
+ void setBoundingRect( const TQRect &r );
+
+protected:
+ virtual bool cmd ( int, TQPainter*, TQPDevCmdParam* );
+ virtual int metric( int ) const;
+
+private:
+ // reading
+ bool play( const TQDomNode &node );
+ void saveAttributes();
+ void restoreAttributes();
+ TQColor parseColor( const TQString &col );
+ double parseLen( const TQString &str, bool *ok=0, bool horiz=TRUE ) const;
+ int lenToInt( const TQDomNamedNodeMap &map, const TQString &attr,
+ int def=0 ) const;
+ double lenToDouble( const TQDomNamedNodeMap &map, const TQString &attr,
+ int def=0 ) const;
+ void setStyleProperty( const TQString &prop, const TQString &val,
+ TQPen *pen, TQFont *font, int *talign );
+ void setStyle( const TQString &s );
+ void setTransform( const TQString &tr );
+ void drawPath( const TQString &data );
+
+ // writing
+ void appendChild( TQDomElement &e, int c );
+ void applyStyle( TQDomElement *e, int c ) const;
+ void applyTransform( TQDomElement *e ) const;
+
+ // reading
+ TQRect brect; // bounding rectangle
+ TQDomDocument doc; // document tree
+ TQDomNode current;
+ TQPoint curPt;
+ TQSvgDeviceState *curr;
+ TQPainter *pt; // used by play() et al
+
+ // writing
+ bool dirtyTransform, dirtyStyle;
+
+ TQSvgDevicePrivate *d;
+};
+
+inline TQRect TQSvgDevice::boundingRect() const
+{
+ return brect;
+}
+
+#endif // TQT_NO_SVG
+
+#endif // TQSVGDEVICE_P_H
diff --git a/tqtinterface/qt4/src/xml/tqxml.cpp b/tqtinterface/qt4/src/xml/tqxml.cpp
new file mode 100644
index 0000000..9462b33
--- /dev/null
+++ b/tqtinterface/qt4/src/xml/tqxml.cpp
@@ -0,0 +1,7635 @@
+/****************************************************************************
+**
+** Implementation of TQXmlSimpleReader and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the xml module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#include "tqxml.h"
+#include "tqtextcodec.h"
+#include "tqbuffer.h"
+#include "tqregexp.h"
+#include "tqptrstack.h"
+#include "tqmap.h"
+#include "tqvaluestack.h"
+
+// needed for TQT_TRANSLATE_NOOP:
+#include "tqobject.h"
+
+#ifndef TQT_NO_XML
+
+//#define TQT_TQXML_DEBUG
+
+// Error strings for the XML reader
+#define XMLERR_OK TQT_TRANSLATE_NOOP( "TQXml", "no error occurred" )
+#define XMLERR_ERRORBYCONSUMER TQT_TRANSLATE_NOOP( "TQXml", "error triggered by consumer" )
+#define XMLERR_UNEXPECTEDEOF TQT_TRANSLATE_NOOP( "TQXml", "unexpected end of file" )
+#define XMLERR_MORETHANONEDOCTYPE TQT_TRANSLATE_NOOP( "TQXml", "more than one document type definition" )
+#define XMLERR_ERRORPARSINGELEMENT TQT_TRANSLATE_NOOP( "TQXml", "error occurred while parsing element" )
+#define XMLERR_TAGMISMATCH TQT_TRANSLATE_NOOP( "TQXml", "tag mismatch" )
+#define XMLERR_ERRORPARSINGCONTENT TQT_TRANSLATE_NOOP( "TQXml", "error occurred while parsing content" )
+#define XMLERR_UNEXPECTEDCHARACTER TQT_TRANSLATE_NOOP( "TQXml", "unexpected character" )
+#define XMLERR_INVALIDNAMEFORPI TQT_TRANSLATE_NOOP( "TQXml", "invalid name for processing instruction" )
+#define XMLERR_VERSIONEXPECTED TQT_TRANSLATE_NOOP( "TQXml", "version expected while reading the XML declaration" )
+#define XMLERR_WRONGVALUEFORSDECL TQT_TRANSLATE_NOOP( "TQXml", "wrong value for standalone declaration" )
+#define XMLERR_EDECLORSDDECLEXPECTED TQT_TRANSLATE_NOOP( "TQXml", "encoding declaration or standalone declaration expected while reading the XML declaration" )
+#define XMLERR_SDDECLEXPECTED TQT_TRANSLATE_NOOP( "TQXml", "standalone declaration expected while reading the XML declaration" )
+#define XMLERR_ERRORPARSINGDOCTYPE TQT_TRANSLATE_NOOP( "TQXml", "error occurred while parsing document type definition" )
+#define XMLERR_LETTEREXPECTED TQT_TRANSLATE_NOOP( "TQXml", "letter is expected" )
+#define XMLERR_ERRORPARSINGCOMMENT TQT_TRANSLATE_NOOP( "TQXml", "error occurred while parsing comment" )
+#define XMLERR_ERRORPARSINGREFERENCE TQT_TRANSLATE_NOOP( "TQXml", "error occurred while parsing reference" )
+#define XMLERR_INTERNALGENERALENTITYINDTD TQT_TRANSLATE_NOOP( "TQXml", "internal general entity reference not allowed in DTD" )
+#define XMLERR_EXTERNALGENERALENTITYINAV TQT_TRANSLATE_NOOP( "TQXml", "external parsed general entity reference not allowed in attribute value" )
+#define XMLERR_EXTERNALGENERALENTITYINDTD TQT_TRANSLATE_NOOP( "TQXml", "external parsed general entity reference not allowed in DTD" )
+#define XMLERR_UNPARSEDENTITYREFERENCE TQT_TRANSLATE_NOOP( "TQXml", "unparsed entity reference in wrong context" )
+#define XMLERR_RECURSIVEENTITIES TQT_TRANSLATE_NOOP( "TQXml", "recursive entities" )
+#define XMLERR_ERRORINTEXTDECL TQT_TRANSLATE_NOOP( "TQXml", "error in the text declaration of an external entity" )
+
+// the constants for the lookup table
+static const signed char cltWS = 0; // white space
+static const signed char cltPer = 1; // %
+static const signed char cltAmp = 2; // &
+static const signed char cltGt = 3; // >
+static const signed char cltLt = 4; // <
+static const signed char cltSlash = 5; // /
+static const signed char cltQm = 6; // ?
+static const signed char cltEm = 7; // !
+static const signed char cltDash = 8; // -
+static const signed char cltCB = 9; // ]
+static const signed char cltOB = 10; // [
+static const signed char cltEq = 11; // =
+static const signed char cltDq = 12; // "
+static const signed char cltSq = 13; // '
+static const signed char cltUnknown = 14;
+
+// character lookup table
+static const signed char charLookupTable[256]={
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x00 - 0x07
+ cltUnknown, // 0x08
+ cltWS, // 0x09 \t
+ cltWS, // 0x0A \n
+ cltUnknown, // 0x0B
+ cltUnknown, // 0x0C
+ cltWS, // 0x0D \r
+ cltUnknown, // 0x0E
+ cltUnknown, // 0x0F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x17 - 0x16
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x18 - 0x1F
+ cltWS, // 0x20 Space
+ cltEm, // 0x21 !
+ cltDq, // 0x22 "
+ cltUnknown, // 0x23
+ cltUnknown, // 0x24
+ cltPer, // 0x25 %
+ cltAmp, // 0x26 &
+ cltSq, // 0x27 '
+ cltUnknown, // 0x28
+ cltUnknown, // 0x29
+ cltUnknown, // 0x2A
+ cltUnknown, // 0x2B
+ cltUnknown, // 0x2C
+ cltDash, // 0x2D -
+ cltUnknown, // 0x2E
+ cltSlash, // 0x2F /
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x30 - 0x37
+ cltUnknown, // 0x38
+ cltUnknown, // 0x39
+ cltUnknown, // 0x3A
+ cltUnknown, // 0x3B
+ cltLt, // 0x3C <
+ cltEq, // 0x3D =
+ cltGt, // 0x3E >
+ cltQm, // 0x3F ?
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x40 - 0x47
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x48 - 0x4F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x50 - 0x57
+ cltUnknown, // 0x58
+ cltUnknown, // 0x59
+ cltUnknown, // 0x5A
+ cltOB, // 0x5B [
+ cltUnknown, // 0x5C
+ cltCB, // 0x5D ]
+ cltUnknown, // 0x5E
+ cltUnknown, // 0x5F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x60 - 0x67
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x68 - 0x6F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x70 - 0x77
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x78 - 0x7F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x80 - 0x87
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x88 - 0x8F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x90 - 0x97
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0x98 - 0x9F
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA0 - 0xA7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xA8 - 0xAF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB0 - 0xB7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xB8 - 0xBF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC0 - 0xC7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xC8 - 0xCF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD0 - 0xD7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xD8 - 0xDF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE0 - 0xE7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xE8 - 0xEF
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, // 0xF0 - 0xF7
+ cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown, cltUnknown // 0xF8 - 0xFF
+};
+
+
+//
+// local helper functions
+//
+
+/*
+ This function strips the TextDecl [77] ("<?xml ...?>") from the string \a
+ str. The stripped version is stored in \a str. If this function tqfinds an
+ invalid TextDecl, it returns FALSE, otherwise TRUE.
+
+ This function is used for external entities since those can include an
+ TextDecl that must be stripped before inserting the entity.
+*/
+static bool stripTextDecl( TQString& str )
+{
+ TQString textDeclStart( "<?xml" );
+ if ( str.startsWith( textDeclStart ) ) {
+ TQRegExp textDecl(TQString::tqfromLatin1(
+ "^<\\?xml\\s+"
+ "(version\\s*=\\s*((['\"])[-a-zA-Z0-9_.:]+\\3))?"
+ "\\s*"
+ "(encoding\\s*=\\s*((['\"])[A-Za-z][-a-zA-Z0-9_.]*\\6))?"
+ "\\s*\\?>"
+ ));
+ TQString strTmp = str.tqreplace( textDecl, "" );
+ if ( strTmp.length() != str.length() )
+ return FALSE; // external entity has wrong TextDecl
+ str = strTmp;
+ }
+ return TRUE;
+}
+
+
+class TQXmlAttributesPrivate
+{
+};
+class TQXmlInputSourcePrivate
+{
+};
+class TQXmlParseExceptionPrivate
+{
+};
+class TQXmlLocatorPrivate
+{
+};
+class TQXmlDefaultHandlerPrivate
+{
+};
+
+/*!
+ \class TQXmlParseException tqxml.h
+ \reentrant
+ \brief The TQXmlParseException class is used to report errors with
+ the TQXmlErrorHandler interface.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ The XML subsystem constructs an instance of this class when it
+ detects an error. You can retrieve the place where the error
+ occurred using systemId(), publicId(), lineNumber() and
+ columnNumber(), along with the error message().
+
+ \sa TQXmlErrorHandler TQXmlReader
+*/
+
+/*!
+ \fn TQXmlParseException::TQXmlParseException( const TQString& name, int c, int l, const TQString& p, const TQString& s )
+
+ Constructs a parse exception with the error string \a name for
+ column \a c and line \a l for the public identifier \a p and the
+ system identifier \a s.
+*/
+
+/*!
+ Returns the error message.
+*/
+TQString TQXmlParseException::message() const
+{
+ return msg;
+}
+/*!
+ Returns the column number where the error occurred.
+*/
+int TQXmlParseException::columnNumber() const
+{
+ return column;
+}
+/*!
+ Returns the line number where the error occurred.
+*/
+int TQXmlParseException::lineNumber() const
+{
+ return line;
+}
+/*!
+ Returns the public identifier where the error occurred.
+*/
+TQString TQXmlParseException::publicId() const
+{
+ return pub;
+}
+/*!
+ Returns the system identifier where the error occurred.
+*/
+TQString TQXmlParseException::systemId() const
+{
+ return sys;
+}
+
+
+/*!
+ \class TQXmlLocator tqxml.h
+ \reentrant
+ \brief The TQXmlLocator class provides the XML handler classes with
+ information about the parsing position within a file.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ The reader reports a TQXmlLocator to the content handler before it
+ starts to parse the document. This is done with the
+ TQXmlContentHandler::setDocumentLocator() function. The handler
+ classes can now use this locator to get the position (lineNumber()
+ and columnNumber()) that the reader has reached.
+*/
+
+/*!
+ Constructor.
+*/
+TQXmlLocator::TQXmlLocator()
+{
+}
+
+/*!
+ Destructor.
+*/
+TQXmlLocator::~TQXmlLocator()
+{
+}
+
+/*!
+ \fn int TQXmlLocator::columnNumber()
+
+ Returns the column number (starting at 1) or -1 if there is no
+ column number available.
+*/
+
+/*!
+ \fn int TQXmlLocator::lineNumber()
+
+ Returns the line number (starting at 1) or -1 if there is no line
+ number available.
+*/
+
+class TQXmlSimpleReaderLocator : public TQXmlLocator
+{
+public:
+ TQXmlSimpleReaderLocator( TQXmlSimpleReader* tqparent )
+ {
+ reader = tqparent;
+ }
+ ~TQXmlSimpleReaderLocator()
+ {
+ }
+
+ int columnNumber()
+ {
+ return ( reader->columnNr == -1 ? -1 : reader->columnNr + 1 );
+ }
+ int lineNumber()
+ {
+ return ( reader->lineNr == -1 ? -1 : reader->lineNr + 1 );
+ }
+// TQString getPublicId()
+// TQString getSystemId()
+
+private:
+ TQXmlSimpleReader *reader;
+};
+
+/*********************************************
+ *
+ * TQXmlNamespaceSupport
+ *
+ *********************************************/
+
+typedef TQMap<TQString, TQString> NamespaceMap;
+
+class TQXmlNamespaceSupportPrivate
+{
+public:
+ TQXmlNamespaceSupportPrivate()
+ {
+ ns.insert( "xml", "http://www.w3.org/XML/1998/namespace" ); // the XML namespace
+ }
+
+ ~TQXmlNamespaceSupportPrivate()
+ {
+ }
+
+ TQValueStack<NamespaceMap> nsStack;
+ NamespaceMap ns;
+};
+
+/*!
+ \class TQXmlNamespaceSupport tqxml.h
+ \reentrant
+ \brief The TQXmlNamespaceSupport class is a helper class for XML
+ readers which want to include namespace support.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ You can set the prefix for the current namespace with setPrefix(),
+ and get the list of current prefixes (or those for a given URI)
+ with prefixes(). The namespace URI is available from uri(). Use
+ pushContext() to start a new namespace context, and popContext()
+ to return to the previous namespace context. Use splitName() or
+ processName() to split a name into its prefix and local name.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+*/
+
+/*!
+ Constructs a TQXmlNamespaceSupport.
+*/
+TQXmlNamespaceSupport::TQXmlNamespaceSupport()
+{
+ d = new TQXmlNamespaceSupportPrivate;
+}
+
+/*!
+ Destroys a TQXmlNamespaceSupport.
+*/
+TQXmlNamespaceSupport::~TQXmlNamespaceSupport()
+{
+ delete d;
+}
+
+/*!
+ This function declares a prefix \a pre in the current namespace
+ context to be the namespace URI \a uri. The prefix remains in
+ force until this context is popped, unless it is shadowed in a
+ descendant context.
+
+ Note that there is an asymmetry in this library. prefix() does not
+ return the default "" prefix, even if you have declared one; to
+ check for a default prefix, you must look it up explicitly using
+ uri(). This asymmetry exists to make it easier to look up prefixes
+ for attribute names, where the default prefix is not allowed.
+*/
+void TQXmlNamespaceSupport::setPrefix( const TQString& pre, const TQString& uri )
+{
+ if( pre.isNull() ) {
+ d->ns.insert( "", uri );
+ } else {
+ d->ns.insert( pre, uri );
+ }
+}
+
+/*!
+ Returns one of the prefixes mapped to the namespace URI \a uri.
+
+ If more than one prefix is currently mapped to the same URI, this
+ function makes an arbitrary selection; if you want all of the
+ prefixes, use prefixes() instead.
+
+ Note: to check for a default prefix, use the uri() function with
+ an argument of "".
+*/
+TQString TQXmlNamespaceSupport::prefix( const TQString& uri ) const
+{
+ NamespaceMap::const_iterator itc, it = d->ns.constBegin();
+ while ( (itc=it) != d->ns.constEnd() ) {
+ ++it;
+ if ( itc.data() == uri && !itc.key().isEmpty() )
+ return itc.key();
+ }
+ return "";
+}
+
+/*!
+ Looks up the prefix \a prefix in the current context and returns
+ the currently-mapped namespace URI. Use the empty string ("") for
+ the default namespace.
+*/
+TQString TQXmlNamespaceSupport::uri( const TQString& prefix ) const
+{
+ return d->ns[prefix];
+}
+
+/*!
+ Splits the name \a qname at the ':' and returns the prefix in \a
+ prefix and the local name in \a localname.
+
+ \sa processName()
+*/
+void TQXmlNamespaceSupport::splitName( const TQString& qname,
+ TQString& prefix, TQString& localname ) const
+{
+ int pos = qname.tqfind(':');
+ if (pos == -1)
+ pos = qname.length();
+
+ prefix = qname.left( pos );
+ localname = qname.mid( pos+1 );
+}
+
+/*!
+ Processes a raw XML 1.0 name in the current context by removing
+ the prefix and looking it up among the prefixes currently
+ declared.
+
+ \a qname is the raw XML 1.0 name to be processed. \a isAttribute
+ is TRUE if the name is an attribute name.
+
+ This function stores the namespace URI in \a nsuri (which will be
+ set to TQString::null if the raw name has an undeclared prefix),
+ and stores the local name (without prefix) in \a localname (which
+ will be set to TQString::null if no namespace is in use).
+
+ Note that attribute names are processed differently than element
+ names: an unprefixed element name gets the default namespace (if
+ any), while an unprefixed element name does not.
+*/
+void TQXmlNamespaceSupport::processName( const TQString& qname,
+ bool isAttribute,
+ TQString& nsuri, TQString& localname ) const
+{
+ int len = qname.length();
+ const TQChar *data = qname.tqunicode();
+ for (int pos = 0; pos < len; ++pos) {
+ if (data[pos].tqunicode() == ':') {
+ nsuri = uri(qname.left(pos));
+ localname = qname.mid(pos + 1);
+ return;
+ }
+ }
+ // there was no ':'
+ nsuri = TQString::null;
+ // attributes don't take default namespace
+ if (!isAttribute && !d->ns.isEmpty()) {
+ /*
+ We want to access d->ns.value(""), but as an optimization
+ we use the fact that "" compares less than any other
+ string, so it's either first in the map or not there.
+ */
+ NamespaceMap::const_iterator first = d->ns.constBegin();
+ if (first.key().isEmpty())
+ nsuri = first.data(); // get default namespace
+ }
+ localname = qname;
+}
+
+/*!
+ Returns a list of all the prefixes currently declared.
+
+ If there is a default prefix, this function does not return it in
+ the list; check for the default prefix using uri() with an
+ argument of "".
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myXmlNamespaceSupport.prefixes();
+ TQStringList::iterator it = list.begin();
+ while ( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQStringList TQXmlNamespaceSupport::prefixes() const
+{
+ TQStringList list;
+
+ NamespaceMap::const_iterator itc, it = d->ns.constBegin();
+ while ( (itc=it) != d->ns.constEnd() ) {
+ ++it;
+ if ( !itc.key().isEmpty() )
+ list.append( itc.key() );
+ }
+ return list;
+}
+
+/*!
+ \overload
+
+ Returns a list of all prefixes currently declared for the
+ namespace URI \a uri.
+
+ The "xml:" prefix is included. If you only want one prefix that is
+ mapped to the namespace URI, and you don't care which one you get,
+ use the prefix() function instead.
+
+ Note: the empty (default) prefix is never included in this list;
+ to check for the presence of a default namespace, use uri() with
+ an argument of "".
+
+ Note that if you want to iterate over the list, you should iterate
+ over a copy, e.g.
+ \code
+ TQStringList list = myXmlNamespaceSupport.prefixes( "" );
+ TQStringList::Iterator it = list.begin();
+ while( it != list.end() ) {
+ myProcessing( *it );
+ ++it;
+ }
+ \endcode
+*/
+TQStringList TQXmlNamespaceSupport::prefixes( const TQString& uri ) const
+{
+ TQStringList list;
+
+ NamespaceMap::const_iterator itc, it = d->ns.constBegin();
+ while ( (itc=it) != d->ns.constEnd() ) {
+ ++it;
+ if ( itc.data() == uri && !itc.key().isEmpty() )
+ list.append( itc.key() );
+ }
+ return list;
+}
+
+/*!
+ Starts a new namespace context.
+
+ Normally, you should push a new context at the beginning of each
+ XML element: the new context automatically inherits the
+ declarations of its tqparent context, and it also keeps track of
+ which declarations were made within this context.
+
+ \sa popContext()
+*/
+void TQXmlNamespaceSupport::pushContext()
+{
+ d->nsStack.push(d->ns);
+}
+
+/*!
+ Reverts to the previous namespace context.
+
+ Normally, you should pop the context at the end of each XML
+ element. After popping the context, all namespace prefix mappings
+ that were previously in force are restored.
+
+ \sa pushContext()
+*/
+void TQXmlNamespaceSupport::popContext()
+{
+ d->ns.clear();
+ if( !d->nsStack.isEmpty() )
+ d->ns = d->nsStack.pop();
+}
+
+/*!
+ Resets this namespace support object ready for reuse.
+*/
+void TQXmlNamespaceSupport::reset()
+{
+ delete d;
+ d = new TQXmlNamespaceSupportPrivate;
+}
+
+
+
+/*********************************************
+ *
+ * TQXmlAttributes
+ *
+ *********************************************/
+
+/*!
+ \class TQXmlAttributes tqxml.h
+ \reentrant
+ \brief The TQXmlAttributes class provides XML attributes.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ If attributes are reported by TQXmlContentHandler::startElement()
+ this class is used to pass the attribute values.
+
+ Use index() to locate the position of an attribute in the list,
+ count() to retrieve the number of attributes, and clear() to
+ remove the attributes. New attributes can be added with append().
+ Use type() to get an attribute's type and value() to get its
+ value. The attribute's name is available from localName() or
+ qName(), and its namespace URI from uri().
+
+*/
+
+/*!
+ \fn TQXmlAttributes::TQXmlAttributes()
+
+ Constructs an empty attribute list.
+*/
+
+/*!
+ \fn TQXmlAttributes::~TQXmlAttributes()
+
+ Destroys the attributes object.
+*/
+
+/*!
+ Looks up the index of an attribute by the qualified name \a qName.
+
+ Returns the index of the attribute or -1 if it wasn't found.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+*/
+int TQXmlAttributes::index( const TQString& qName ) const
+{
+ return qnameList.tqfindIndex( qName );
+}
+
+/*!
+ \overload
+
+ Looks up the index of an attribute by a namespace name.
+
+ \a uri specifies the namespace URI, or an empty string if the name
+ has no namespace URI. \a localPart specifies the attribute's local
+ name.
+
+ Returns the index of the attribute, or -1 if it wasn't found.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+*/
+int TQXmlAttributes::index( const TQString& uri, const TQString& localPart ) const
+{
+ TQString uriTmp;
+ if ( uri.isEmpty() )
+ uriTmp = TQString::null;
+ else
+ uriTmp = uri;
+ uint count = (uint)uriList.count(); // ### size_t/int cast
+ for ( uint i=0; i<count; i++ ) {
+ if ( uriList[i] == uriTmp && localnameList[i] == localPart )
+ return i;
+ }
+ return -1;
+}
+
+/*!
+ Returns the number of attributes in the list.
+
+ \sa count()
+*/
+int TQXmlAttributes::length() const
+{
+ return (int)valueList.count();
+}
+
+/*!
+ \fn int TQXmlAttributes::count() const
+
+ Returns the number of attributes in the list. This function is
+ equivalent to length().
+*/
+
+/*!
+ Looks up an attribute's local name for the attribute at position
+ \a index. If no namespace processing is done, the local name is
+ TQString::null.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+*/
+TQString TQXmlAttributes::localName( int index ) const
+{
+ return localnameList[index];
+}
+
+/*!
+ Looks up an attribute's XML 1.0 qualified name for the attribute
+ at position \a index.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+*/
+TQString TQXmlAttributes::qName( int index ) const
+{
+ return qnameList[index];
+}
+
+/*!
+ Looks up an attribute's namespace URI for the attribute at
+ position \a index. If no namespace processing is done or if the
+ attribute has no namespace, the namespace URI is TQString::null.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+*/
+TQString TQXmlAttributes::uri( int index ) const
+{
+ return uriList[index];
+}
+
+/*!
+ Looks up an attribute's type for the attribute at position \a
+ index.
+
+ Currently only "CDATA" is returned.
+*/
+TQString TQXmlAttributes::type( int ) const
+{
+ return "CDATA";
+}
+
+/*!
+ \overload
+
+ Looks up an attribute's type for the qualified name \a qName.
+
+ Currently only "CDATA" is returned.
+*/
+TQString TQXmlAttributes::type( const TQString& ) const
+{
+ return "CDATA";
+}
+
+/*!
+ \overload
+
+ Looks up an attribute's type by namespace name.
+
+ \a uri specifies the namespace URI and \a localName specifies the
+ local name. If the name has no namespace URI, use an empty string
+ for \a uri.
+
+ Currently only "CDATA" is returned.
+*/
+TQString TQXmlAttributes::type( const TQString&, const TQString& ) const
+{
+ return "CDATA";
+}
+
+/*!
+ Looks up an attribute's value for the attribute at position \a
+ index.
+*/
+TQString TQXmlAttributes::value( int index ) const
+{
+ return valueList[index];
+}
+
+/*!
+ \overload
+
+ Looks up an attribute's value for the qualified name \a qName.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+*/
+TQString TQXmlAttributes::value( const TQString& qName ) const
+{
+ int i = index( qName );
+ if ( i == -1 )
+ return TQString::null;
+ return valueList[ i ];
+}
+
+/*!
+ \overload
+
+ Looks up an attribute's value by namespace name.
+
+ \a uri specifies the namespace URI, or an empty string if the name
+ has no namespace URI. \a localName specifies the attribute's local
+ name.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+*/
+TQString TQXmlAttributes::value( const TQString& uri, const TQString& localName ) const
+{
+ int i = index( uri, localName );
+ if ( i == -1 )
+ return TQString::null;
+ return valueList[ i ];
+}
+
+/*!
+ Clears the list of attributes.
+
+ \sa append()
+*/
+void TQXmlAttributes::clear()
+{
+ qnameList.clear();
+ uriList.clear();
+ localnameList.clear();
+ valueList.clear();
+}
+
+/*!
+ Appends a new attribute entry to the list of attributes. The
+ qualified name of the attribute is \a qName, the namespace URI is
+ \a uri and the local name is \a localPart. The value of the
+ attribute is \a value.
+
+ \sa qName() uri() localName() value()
+*/
+void TQXmlAttributes::append( const TQString &qName, const TQString &uri, const TQString &localPart, const TQString &value )
+{
+ qnameList.append( qName );
+ uriList.append( uri );
+ localnameList.append( localPart);
+ valueList.append( value );
+}
+
+
+/*********************************************
+ *
+ * TQXmlInputSource
+ *
+ *********************************************/
+
+/*!
+ \class TQXmlInputSource tqxml.h
+ \reentrant
+ \brief The TQXmlInputSource class provides the input data for the
+ TQXmlReader subclasses.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ All subclasses of TQXmlReader read the input XML document from this
+ class.
+
+ This class recognizes the encoding of the data by reading the
+ encoding declaration in the XML file if it tqfinds one, and reading
+ the data using the corresponding encoding. If it does not tqfind an
+ encoding declaration, then it assumes that the data is either in
+ UTF-8 or UTF-16, depending on whether it can tqfind a byte-order
+ mark.
+
+ There are two ways to populate the input source with data: you can
+ construct it with a TQIODevice* so that the input source reads the
+ data from that tqdevice. Or you can set the data explicitly with one
+ of the setData() functions.
+
+ Usually you either construct a TQXmlInputSource that works on a
+ TQIODevice* or you construct an empty TQXmlInputSource and set the
+ data with setData(). There are only rare occasions where you would
+ want to mix both methods.
+
+ The TQXmlReader subclasses use the next() function to read the
+ input character by character. If you want to start from the
+ beginning again, use reset().
+
+ The functions data() and fetchData() are useful if you want to do
+ something with the data other than parsing, e.g. displaying the
+ raw XML file. The benefit of using the TQXmlInputClass in such
+ cases is that it tries to use the correct encoding.
+
+ \sa TQXmlReader TQXmlSimpleReader
+*/
+
+// the following two are guaranteed not to be a character
+const TQChar TQXmlInputSource::EndOfData = TQChar((ushort)0xfffe);
+const TQChar TQXmlInputSource::EndOfDocument = TQChar((ushort)0xffff);
+
+/*
+ Common part of the constructors.
+*/
+void TQXmlInputSource::init()
+{
+ inputDevice = 0;
+ inputStream = 0;
+
+ setData( TQString::null );
+ encMapper = 0;
+}
+
+/*!
+ Constructs an input source which tqcontains no data.
+
+ \sa setData()
+*/
+TQXmlInputSource::TQXmlInputSource()
+{
+ init();
+}
+
+/*!
+ Constructs an input source and gets the data from tqdevice \a dev.
+ If \a dev is not open, it is opened in read-only mode. If \a dev
+ is 0 or it is not possible to read from the tqdevice, the input
+ source will contain no data.
+
+ \sa setData() fetchData() TQIODevice
+*/
+TQXmlInputSource::TQXmlInputSource( TQIODevice *dev )
+{
+ init();
+ inputDevice = dev;
+ fetchData();
+}
+
+/*! \obsolete
+ Constructs an input source and gets the data from the text stream \a stream.
+*/
+TQXmlInputSource::TQXmlInputSource( TQTextStream& stream )
+{
+ init();
+ inputStream = &stream;
+ fetchData();
+}
+
+/*! \obsolete
+ Constructs an input source and gets the data from the file \a file. If the
+ file cannot be read the input source is empty.
+*/
+TQXmlInputSource::TQXmlInputSource( TQFile& file )
+{
+ init();
+ inputDevice = TQT_TQIODEVICE(&file);
+ fetchData();
+}
+
+/*!
+ Destructor.
+*/
+TQXmlInputSource::~TQXmlInputSource()
+{
+ delete encMapper;
+}
+
+/*!
+ Returns the next character of the input source. If this function
+ reaches the end of available data, it returns
+ TQXmlInputSource::EndOfData. If you call next() after that, it
+ tries to fetch more data by calling fetchData(). If the
+ fetchData() call results in new data, this function returns the
+ first character of that data; otherwise it returns
+ TQXmlInputSource::EndOfDocument.
+
+ \sa reset() fetchData() TQXmlSimpleReader::parse() TQXmlSimpleReader::parseContinue()
+*/
+TQChar TQXmlInputSource::next()
+{
+ if ( pos >= length ) {
+ if ( nextReturnedEndOfData ) {
+ nextReturnedEndOfData = FALSE;
+ fetchData();
+ if ( pos >= length ) {
+ return EndOfDocument;
+ }
+ return next();
+ }
+ nextReturnedEndOfData = TRUE;
+ return EndOfData;
+ }
+ return tqunicode[pos++];
+}
+
+/*!
+ This function sets the position used by next() to the beginning of
+ the data returned by data(). This is useful if you want to use the
+ input source for more than one parse.
+
+ \sa next()
+*/
+void TQXmlInputSource::reset()
+{
+ nextReturnedEndOfData = FALSE;
+ pos = 0;
+}
+
+/*!
+ Returns the data the input source tqcontains or TQString::null if the
+ input source does not contain any data.
+
+ \sa setData() TQXmlInputSource() fetchData()
+*/
+TQString TQXmlInputSource::data()
+{
+ return str;
+}
+
+/*!
+ Sets the data of the input source to \a dat.
+
+ If the input source already tqcontains data, this function deletes
+ that data first.
+
+ \sa data()
+*/
+void TQXmlInputSource::setData( const TQString& dat )
+{
+ str = dat;
+ tqunicode = str.tqunicode();
+ pos = 0;
+ length = str.length();
+ nextReturnedEndOfData = FALSE;
+}
+
+/*!
+ \overload
+
+ The data \a dat is passed through the correct text-codec, before
+ it is set.
+*/
+void TQXmlInputSource::setData( const TQByteArray& dat )
+{
+ setData( fromRawData( dat ) );
+}
+
+/*!
+ This function reads more data from the tqdevice that was set during
+ construction. If the input source already contained data, this
+ function deletes that data first.
+
+ This object tqcontains no data after a call to this function if the
+ object was constructed without a tqdevice to read data from or if
+ this function was not able to get more data from the tqdevice.
+
+ There are two occasions where a fetch is done implicitly by
+ another function call: during construction (so that the object
+ starts out with some initial data where available), and during a
+ call to next() (if the data had run out).
+
+ You don't normally need to use this function if you use next().
+
+ \sa data() next() TQXmlInputSource()
+*/
+void TQXmlInputSource::fetchData()
+{
+ TQByteArray rawData;
+
+ if ( inputDevice != 0 ) {
+ if ( inputDevice->isOpen() || inputDevice->open( IO_ReadOnly ) )
+ rawData = inputDevice->readAll();
+ } else if ( inputStream != 0 ) {
+ if ( inputStream->tqdevice()->isDirectAccess() ) {
+ rawData = inputStream->tqdevice()->readAll();
+ } else {
+ int nread = 0;
+ const int bufsize = 512;
+ while ( !inputStream->tqdevice()->atEnd() ) {
+ rawData.resize( nread + bufsize );
+ nread += inputStream->tqdevice()->readBlock( rawData.data()+nread, bufsize );
+ }
+ rawData.resize( nread );
+ }
+ }
+ setData( fromRawData( rawData ) );
+}
+
+/*!
+ This function reads the XML file from \a data and tries to
+ recognize the encoding. It converts the raw data \a data into a
+ TQString and returns it. It tries its best to get the correct
+ encoding for the XML file.
+
+ If \a beginning is TRUE, this function assumes that the data
+ starts at the beginning of a new XML document and looks for an
+ encoding declaration. If \a beginning is FALSE, it converts the
+ raw data using the encoding determined from prior calls.
+*/
+TQString TQXmlInputSource::fromRawData( const TQByteArray &data, bool beginning )
+{
+ if ( data.size() == 0 )
+ return TQString::null;
+ if ( beginning ) {
+ delete encMapper;
+ encMapper = 0;
+ }
+ if ( encMapper == 0 ) {
+ TQTextCodec *codec = 0;
+ // look for byte order mark and read the first 5 characters
+ if ( data.size() >= 2 &&
+ ( ((uchar)data.at(0)==(uchar)0xfe &&
+ (uchar)data.at(1)==(uchar)0xff ) ||
+ ((uchar)data.at(0)==(uchar)0xff &&
+ (uchar)data.at(1)==(uchar)0xfe ) )) {
+ codec = TQTextCodec::codecForMib( 1000 ); // UTF-16
+ } else {
+ codec = TQTextCodec::codecForMib( 106 ); // UTF-8
+ }
+ if ( !codec )
+ return TQString::null;
+
+ encMapper = codec->makeDecoder();
+ TQString input = encMapper->toUnicode( data.data(), data.size() );
+ // ### unexpected EOF? (for incremental parsing)
+ // starts the document with an XML declaration?
+ if ( input.tqfind("<?xml") == 0 ) {
+ // try to tqfind out if there is an encoding
+ int endPos = input.tqfind( ">" );
+ int pos = input.tqfind( "encoding" );
+ if ( pos < endPos && pos != -1 ) {
+ TQString encoding;
+ do {
+ pos++;
+ if ( pos > endPos ) {
+ return input;
+ }
+ } while( input[pos] != '"' && input[pos] != '\'' );
+ pos++;
+ while( input[pos] != '"' && input[pos] != '\'' ) {
+ encoding += input[pos];
+ pos++;
+ if ( pos > endPos ) {
+ return input;
+ }
+ }
+
+ codec = TQTextCodec::codecForName( encoding );
+ if ( codec == 0 ) {
+ return input;
+ }
+ delete encMapper;
+ encMapper = codec->makeDecoder();
+ return encMapper->toUnicode( data.data(), data.size() );
+ }
+ }
+ return input;
+ }
+ return encMapper->toUnicode( data.data(), data.size() );
+}
+
+
+/*********************************************
+ *
+ * TQXmlDefaultHandler
+ *
+ *********************************************/
+
+/*!
+ \class TQXmlContentHandler tqxml.h
+ \reentrant
+ \brief The TQXmlContentHandler class provides an interface to
+ report the logical content of XML data.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ If the application needs to be informed of basic parsing events,
+ it can implement this interface and activate it using
+ TQXmlReader::setContentHandler(). The reader can then report basic
+ document-related events like the start and end of elements and
+ character data through this interface.
+
+ The order of events in this interface is very important, and
+ mirrors the order of information in the document itself. For
+ example, all of an element's content (character data, processing
+ instructions, and sub-elements) appears, in order, between the
+ startElement() event and the corresponding endElement() event.
+
+ The class TQXmlDefaultHandler provides a default implementation for
+ this interface; subclassing from the TQXmlDefaultHandler class is
+ very convenient if you only want to be informed of some parsing
+ events.
+
+ The startDocument() function is called at the start of the
+ document, and endDocument() is called at the end. Before parsing
+ begins setDocumentLocator() is called. For each element
+ startElement() is called, with endElement() being called at the
+ end of each element. The characters() function is called with
+ chunks of character data; ignorableWhitespace() is called with
+ chunks of whitespace and processingInstruction() is called with
+ processing instructions. If an entity is skipped skippedEntity()
+ is called. At the beginning of prefix-URI scopes
+ startPrefixMapping() is called.
+
+ See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
+
+ \sa TQXmlDTDHandler TQXmlDeclHandler TQXmlEntityResolver TQXmlErrorHandler
+ TQXmlLexicalHandler
+*/
+
+/*!
+ \fn void TQXmlContentHandler::setDocumentLocator( TQXmlLocator* locator )
+
+ The reader calls this function before it starts parsing the
+ document. The argument \a locator is a pointer to a TQXmlLocator
+ which allows the application to get the parsing position within
+ the document.
+
+ Do not destroy the \a locator; it is destroyed when the reader is
+ destroyed. (Do not use the \a locator after the reader is
+ destroyed).
+*/
+
+/*!
+ \fn bool TQXmlContentHandler::startDocument()
+
+ The reader calls this function when it starts parsing the
+ document. The reader calls this function just once, after the call
+ to setDocumentLocator(), and before any other functions in this
+ class or in the TQXmlDTDHandler class are called.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ \sa endDocument()
+*/
+
+/*!
+ \fn bool TQXmlContentHandler::endDocument()
+
+ The reader calls this function after it has finished parsing. It
+ is called just once, and is the last handler function called. It
+ is called after the reader has read all input or has abandoned
+ parsing because of a fatal error.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ \sa startDocument()
+*/
+
+/*!
+ \fn bool TQXmlContentHandler::startPrefixMapping( const TQString& prefix, const TQString& uri )
+
+ The reader calls this function to signal the begin of a prefix-URI
+ namespace mapping scope. This information is not necessary for
+ normal namespace processing since the reader automatically
+ tqreplaces prefixes for element and attribute names.
+
+ Note that startPrefixMapping() and endPrefixMapping() calls are
+ not guaranteed to be properly nested relative to each other: all
+ startPrefixMapping() events occur before the corresponding
+ startElement() event, and all endPrefixMapping() events occur
+ after the corresponding endElement() event, but their order is not
+ otherwise guaranteed.
+
+ The argument \a prefix is the namespace prefix being declared and
+ the argument \a uri is the namespace URI the prefix is mapped to.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+
+ \sa endPrefixMapping()
+*/
+
+/*!
+ \fn bool TQXmlContentHandler::endPrefixMapping( const TQString& prefix )
+
+ The reader calls this function to signal the end of a prefix
+ mapping for the prefix \a prefix.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+
+ \sa startPrefixMapping()
+*/
+
+/*!
+ \fn bool TQXmlContentHandler::startElement( const TQString& namespaceURI, const TQString& localName, const TQString& qName, const TQXmlAttributes& atts )
+
+ The reader calls this function when it has parsed a start element
+ tag.
+
+ There is a corresponding endElement() call when the corresponding
+ end element tag is read. The startElement() and endElement() calls
+ are always nested correctly. Empty element tags (e.g. \c{<x/>})
+ cause a startElement() call to be immediately followed by an
+ endElement() call.
+
+ The attribute list provided only tqcontains attributes with explicit
+ values. The attribute list tqcontains attributes used for namespace
+ declaration (i.e. attributes starting with xmlns) only if the
+ namespace-prefix property of the reader is TRUE.
+
+ The argument \a namespaceURI is the namespace URI, or
+ TQString::null if the element has no namespace URI or if no
+ namespace processing is done. \a localName is the local name
+ (without prefix), or TQString::null if no namespace processing is
+ done, \a qName is the qualified name (with prefix) and \a atts are
+ the attributes attached to the element. If there are no
+ attributes, \a atts is an empty attributes object.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+
+ \sa endElement()
+*/
+
+/*!
+ \fn bool TQXmlContentHandler::endElement( const TQString& namespaceURI, const TQString& localName, const TQString& qName )
+
+ The reader calls this function when it has parsed an end element
+ tag with the qualified name \a qName, the local name \a localName
+ and the namespace URI \a namespaceURI.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ See also the \link xml.html#sax2Namespaces namespace description\endlink.
+
+ \sa startElement()
+*/
+
+/*!
+ \fn bool TQXmlContentHandler::characters( const TQString& ch )
+
+ The reader calls this function when it has parsed a chunk of
+ character data (either normal character data or character data
+ inside a CDATA section; if you need to distinguish between those
+ two types you must use TQXmlLexicalHandler::startCDATA() and
+ TQXmlLexicalHandler::endCDATA()). The character data is reported in
+ \a ch.
+
+ Some readers report whitespace in element content using the
+ ignorableWhitespace() function rather than using this one.
+
+ A reader may report the character data of an element in more than
+ one chunk; e.g. a reader might want to report "a\<b" in three
+ characters() events ("a ", "\<" and " b").
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn bool TQXmlContentHandler::ignorableWhitespace( const TQString& ch )
+
+ Some readers may use this function to report each chunk of
+ whitespace in element content. The whitespace is reported in \a ch.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn bool TQXmlContentHandler::processingInstruction( const TQString& target, const TQString& data )
+
+ The reader calls this function when it has parsed a processing
+ instruction.
+
+ \a target is the target name of the processing instruction and \a
+ data is the data in the processing instruction.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn bool TQXmlContentHandler::skippedEntity( const TQString& name )
+
+ Some readers may skip entities if they have not seen the
+ declarations (e.g. because they are in an external DTD). If they
+ do so they report that they skipped the entity called \a name by
+ calling this function.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn TQString TQXmlContentHandler::errorString()
+
+ The reader calls this function to get an error string, e.g. if any
+ of the handler functions returns FALSE.
+*/
+
+
+/*!
+ \class TQXmlErrorHandler tqxml.h
+ \reentrant
+ \brief The TQXmlErrorHandler class provides an interface to report
+ errors in XML data.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ If you want your application to report errors to the user or to
+ perform customized error handling, you should subclass this class.
+
+ You can set the error handler with TQXmlReader::setErrorHandler().
+
+ Errors can be reported using warning(), error() and fatalError(),
+ with the error text being reported with errorString().
+
+ See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
+
+ \sa TQXmlDTDHandler TQXmlDeclHandler TQXmlContentHandler TQXmlEntityResolver
+ TQXmlLexicalHandler
+*/
+
+/*!
+ \fn bool TQXmlErrorHandler::warning( const TQXmlParseException& exception )
+
+ A reader might use this function to report a warning. Warnings are
+ conditions that are not errors or fatal errors as defined by the
+ XML 1.0 specification. Details of the warning are stored in \a
+ exception.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn bool TQXmlErrorHandler::error( const TQXmlParseException& exception )
+
+ A reader might use this function to report a recoverable error. A
+ recoverable error corresponds to the definiton of "error" in
+ section 1.2 of the XML 1.0 specification. Details of the error are
+ stored in \a exception.
+
+ The reader must continue to provide normal parsing events after
+ invoking this function.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn bool TQXmlErrorHandler::fatalError( const TQXmlParseException& exception )
+
+ A reader must use this function to report a non-recoverable error.
+ Details of the error are stored in \a exception.
+
+ If this function returns TRUE the reader might try to go on
+ parsing and reporting further errors; but no regular parsing
+ events are reported.
+*/
+
+/*!
+ \fn TQString TQXmlErrorHandler::errorString()
+
+ The reader calls this function to get an error string if any of
+ the handler functions returns FALSE.
+*/
+
+
+/*!
+ \class TQXmlDTDHandler tqxml.h
+ \reentrant
+ \brief The TQXmlDTDHandler class provides an interface to report
+ DTD content of XML data.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ If an application needs information about notations and unparsed
+ entities, it can implement this interface and register an instance
+ with TQXmlReader::setDTDHandler().
+
+ Note that this interface includes only those DTD events that the
+ XML recommendation requires processors to report, i.e. notation
+ and unparsed entity declarations using notationDecl() and
+ unparsedEntityDecl() respectively.
+
+ See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
+
+ \sa TQXmlDeclHandler TQXmlContentHandler TQXmlEntityResolver TQXmlErrorHandler
+ TQXmlLexicalHandler
+*/
+
+/*!
+ \fn bool TQXmlDTDHandler::notationDecl( const TQString& name, const TQString& publicId, const TQString& systemId )
+
+ The reader calls this function when it has parsed a notation
+ declaration.
+
+ The argument \a name is the notation name, \a publicId is the
+ notation's public identifier and \a systemId is the notation's
+ system identifier.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn bool TQXmlDTDHandler::unparsedEntityDecl( const TQString& name, const TQString& publicId, const TQString& systemId, const TQString& notationName )
+
+ The reader calls this function when it tqfinds an unparsed entity
+ declaration.
+
+ The argument \a name is the unparsed entity's name, \a publicId is
+ the entity's public identifier, \a systemId is the entity's system
+ identifier and \a notationName is the name of the associated
+ notation.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn TQString TQXmlDTDHandler::errorString()
+
+ The reader calls this function to get an error string if any of
+ the handler functions returns FALSE.
+*/
+
+
+/*!
+ \class TQXmlEntityResolver tqxml.h
+ \reentrant
+ \brief The TQXmlEntityResolver class provides an interface to
+ resolve external entities contained in XML data.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ If an application needs to implement customized handling for
+ external entities, it must implement this interface, i.e.
+ resolveEntity(), and register it with
+ TQXmlReader::setEntityResolver().
+
+ See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
+
+ \sa TQXmlDTDHandler TQXmlDeclHandler TQXmlContentHandler TQXmlErrorHandler
+ TQXmlLexicalHandler
+*/
+
+/*!
+ \fn bool TQXmlEntityResolver::resolveEntity( const TQString& publicId, const TQString& systemId, TQXmlInputSource*& ret )
+
+ The reader calls this function before it opens any external
+ entity, except the top-level document entity. The application may
+ request the reader to resolve the entity itself (\a ret is 0) or
+ to use an entirely different input source (\a ret points to the
+ input source).
+
+ The reader deletes the input source \a ret when it no longer needs
+ it, so you should allocate it on the heap with \c new.
+
+ The argument \a publicId is the public identifier of the external
+ entity, \a systemId is the system identifier of the external
+ entity and \a ret is the return value of this function. If \a ret
+ is 0 the reader should resolve the entity itself, if it is
+ non-zero it must point to an input source which the reader uses
+ instead.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn TQString TQXmlEntityResolver::errorString()
+
+ The reader calls this function to get an error string if any of
+ the handler functions returns FALSE.
+*/
+
+
+/*!
+ \class TQXmlLexicalHandler tqxml.h
+ \reentrant
+ \brief The TQXmlLexicalHandler class provides an interface to
+ report the lexical content of XML data.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ The events in the lexical handler apply to the entire document,
+ not just to the document element, and all lexical handler events
+ appear between the content handler's startDocument and endDocument
+ events.
+
+ You can set the lexical handler with
+ TQXmlReader::setLexicalHandler().
+
+ This interface's design is based on the the SAX2 extension
+ LexicalHandler.
+
+ The interface provides the startDTD(), endDTD(), startEntity(),
+ endEntity(), startCDATA(), endCDATA() and comment() functions.
+
+ See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
+
+ \sa TQXmlDTDHandler TQXmlDeclHandler TQXmlContentHandler TQXmlEntityResolver
+ TQXmlErrorHandler
+*/
+
+/*!
+ \fn bool TQXmlLexicalHandler::startDTD( const TQString& name, const TQString& publicId, const TQString& systemId )
+
+ The reader calls this function to report the start of a DTD
+ declaration, if any. It reports the name of the document type in
+ \a name, the public identifier in \a publicId and the system
+ identifier in \a systemId.
+
+ If the public identifier is missing, \a publicId is set to
+ TQString::null. If the system identifier is missing, \a systemId is
+ set to TQString::null. Note that it is not valid XML to have a
+ public identifier but no system identifier; in such cases a parse
+ error will occur.
+
+ All declarations reported through TQXmlDTDHandler or
+ TQXmlDeclHandler appear between the startDTD() and endDTD() calls.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ \sa endDTD()
+*/
+
+/*!
+ \fn bool TQXmlLexicalHandler::endDTD()
+
+ The reader calls this function to report the end of a DTD
+ declaration, if any.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ \sa startDTD()
+*/
+
+/*!
+ \fn bool TQXmlLexicalHandler::startEntity( const TQString& name )
+
+ The reader calls this function to report the start of an entity
+ called \a name.
+
+ Note that if the entity is unknown, the reader reports it through
+ TQXmlContentHandler::skippedEntity() and not through this
+ function.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ \sa endEntity() TQXmlSimpleReader::setFeature()
+*/
+
+/*!
+ \fn bool TQXmlLexicalHandler::endEntity( const TQString& name )
+
+ The reader calls this function to report the end of an entity
+ called \a name.
+
+ For every startEntity() call, there is a corresponding endEntity()
+ call. The calls to startEntity() and endEntity() are properly
+ nested.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ \sa startEntity() TQXmlContentHandler::skippedEntity() TQXmlSimpleReader::setFeature()
+*/
+
+/*!
+ \fn bool TQXmlLexicalHandler::startCDATA()
+
+ The reader calls this function to report the start of a CDATA
+ section. The content of the CDATA section is reported through the
+ TQXmlContentHandler::characters() function. This function is
+ intended only to report the boundary.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+
+ \sa endCDATA()
+*/
+
+/*!
+ \fn bool TQXmlLexicalHandler::endCDATA()
+
+ The reader calls this function to report the end of a CDATA
+ section.
+
+ If this function returns FALSE the reader stops parsing and reports
+ an error. The reader uses the function errorString() to get the error
+ message.
+
+ \sa startCDATA() TQXmlContentHandler::characters()
+*/
+
+/*!
+ \fn bool TQXmlLexicalHandler::comment( const TQString& ch )
+
+ The reader calls this function to report an XML comment anywhere
+ in the document. It reports the text of the comment in \a ch.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn TQString TQXmlLexicalHandler::errorString()
+
+ The reader calls this function to get an error string if any of
+ the handler functions returns FALSE.
+*/
+
+
+/*!
+ \class TQXmlDeclHandler tqxml.h
+ \reentrant
+ \brief The TQXmlDeclHandler class provides an interface to report declaration
+ content of XML data.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ You can set the declaration handler with
+ TQXmlReader::setDeclHandler().
+
+ This interface is based on the SAX2 extension DeclHandler.
+
+ The interface provides attributeDecl(), internalEntityDecl() and
+ externalEntityDecl() functions.
+
+ See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
+
+ \sa TQXmlDTDHandler TQXmlContentHandler TQXmlEntityResolver TQXmlErrorHandler
+ TQXmlLexicalHandler
+*/
+
+/*!
+ \fn bool TQXmlDeclHandler::attributeDecl( const TQString& eName, const TQString& aName, const TQString& type, const TQString& valueDefault, const TQString& value )
+
+ The reader calls this function to report an attribute type
+ declaration. Only the effective (first) declaration for an
+ attribute is reported.
+
+ The reader passes the name of the associated element in \a eName
+ and the name of the attribute in \a aName. It passes a string that
+ represents the attribute type in \a type and a string that
+ represents the attribute default in \a valueDefault. This string
+ is one of "#IMPLIED", "#RETQUIRED", "#FIXED" or TQString::null (if
+ none of the others applies). The reader passes the attribute's
+ default value in \a value. If no default value is specified in the
+ XML file, \a value is TQString::null.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn bool TQXmlDeclHandler::internalEntityDecl( const TQString& name, const TQString& value )
+
+ The reader calls this function to report an internal entity
+ declaration. Only the effective (first) declaration is reported.
+
+ The reader passes the name of the entity in \a name and the value
+ of the entity in \a value.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn bool TQXmlDeclHandler::externalEntityDecl( const TQString& name, const TQString& publicId, const TQString& systemId )
+
+ The reader calls this function to report a parsed external entity
+ declaration. Only the effective (first) declaration for each
+ entity is reported.
+
+ The reader passes the name of the entity in \a name, the public
+ identifier in \a publicId and the system identifier in \a
+ systemId. If there is no public identifier specified, it passes
+ TQString::null in \a publicId.
+
+ If this function returns FALSE the reader stops parsing and
+ reports an error. The reader uses the function errorString() to
+ get the error message.
+*/
+
+/*!
+ \fn TQString TQXmlDeclHandler::errorString()
+
+ The reader calls this function to get an error string if any of
+ the handler functions returns FALSE.
+*/
+
+
+/*!
+ \class TQXmlDefaultHandler tqxml.h
+ \reentrant
+ \brief The TQXmlDefaultHandler class provides a default implementation of all
+ the XML handler classes.
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ Very often we are only interested in parts of the things that the
+ reader reports. This class implements a default behaviour for the
+ handler classes (i.e. most of the time do nothing). Usually this
+ is the class you subclass for implementing your own customized
+ handler.
+
+ See also the \link xml.html#sax2Intro Introduction to SAX2\endlink.
+
+ \sa TQXmlDTDHandler TQXmlDeclHandler TQXmlContentHandler TQXmlEntityResolver
+ TQXmlErrorHandler TQXmlLexicalHandler
+*/
+
+/*!
+ \fn TQXmlDefaultHandler::TQXmlDefaultHandler()
+
+ Constructor.
+*/
+/*!
+ \fn TQXmlDefaultHandler::~TQXmlDefaultHandler()
+
+ Destructor.
+*/
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+void TQXmlDefaultHandler::setDocumentLocator( TQXmlLocator* )
+{
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::startDocument()
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::endDocument()
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::startPrefixMapping( const TQString&, const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::endPrefixMapping( const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::startElement( const TQString&, const TQString&,
+ const TQString&, const TQXmlAttributes& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::endElement( const TQString&, const TQString&,
+ const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::characters( const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::ignorableWhitespace( const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::processingInstruction( const TQString&,
+ const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::skippedEntity( const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::warning( const TQXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::error( const TQXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::fatalError( const TQXmlParseException& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::notationDecl( const TQString&, const TQString&,
+ const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::unparsedEntityDecl( const TQString&, const TQString&,
+ const TQString&, const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Sets \a ret to 0, so that the reader uses the system identifier
+ provided in the XML document.
+*/
+bool TQXmlDefaultHandler::resolveEntity( const TQString&, const TQString&,
+ TQXmlInputSource*& ret )
+{
+ ret = 0;
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Returns the default error string.
+*/
+TQString TQXmlDefaultHandler::errorString()
+{
+ return TQString( XMLERR_ERRORBYCONSUMER );
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::startDTD( const TQString&, const TQString&, const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::endDTD()
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::startEntity( const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::endEntity( const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::startCDATA()
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::endCDATA()
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::comment( const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::attributeDecl( const TQString&, const TQString&, const TQString&, const TQString&, const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::internalEntityDecl( const TQString&, const TQString& )
+{
+ return TRUE;
+}
+
+/*!
+ \reimp
+
+ Does nothing.
+*/
+bool TQXmlDefaultHandler::externalEntityDecl( const TQString&, const TQString&, const TQString& )
+{
+ return TRUE;
+}
+
+
+/*********************************************
+ *
+ * TQXmlSimpleReaderPrivate
+ *
+ *********************************************/
+
+class TQXmlSimpleReaderPrivate
+{
+private:
+ // functions
+ inline TQXmlSimpleReaderPrivate()
+ {
+ parseStack = 0;
+ undefEntityInAttrHack = FALSE;
+ }
+
+ inline ~TQXmlSimpleReaderPrivate()
+ {
+ delete parseStack;
+ }
+
+ inline void initIncrementalParsing()
+ {
+ delete parseStack;
+ parseStack = new TQValueStack<ParseState>;
+ }
+
+ // used to determine if elements are correctly nested
+ TQValueStack<TQString> tags;
+
+ // used for entity declarations
+ struct ExternParameterEntity
+ {
+ ExternParameterEntity( ) {}
+ ExternParameterEntity( const TQString &p, const TQString &s )
+ : publicId(p), systemId(s) {}
+ TQString publicId;
+ TQString systemId;
+
+ TQ_DUMMY_COMPARISON_OPERATOR(ExternParameterEntity)
+ };
+ struct ExternEntity
+ {
+ ExternEntity( ) {}
+ ExternEntity( const TQString &p, const TQString &s, const TQString &n )
+ : publicId(p), systemId(s), notation(n) {}
+ TQString publicId;
+ TQString systemId;
+ TQString notation;
+ TQ_DUMMY_COMPARISON_OPERATOR(ExternEntity)
+ };
+ TQMap<TQString,ExternParameterEntity> externParameterEntities;
+ TQMap<TQString,TQString> parameterEntities;
+ TQMap<TQString,ExternEntity> externEntities;
+ TQMap<TQString,TQString> entities;
+
+ // used for parsing of entity references
+ TQValueStack<TQString> xmlRef;
+ TQValueStack<TQString> xmlRefName;
+
+ // used for standalone declaration
+ enum Standalone { Yes, No, Unknown };
+
+ TQString doctype; // only used for the doctype
+ TQString xmlVersion; // only used to store the version information
+ TQString encoding; // only used to store the encoding
+ Standalone standalone; // used to store the value of the standalone declaration
+
+ TQString publicId; // used by parseExternalID() to store the public ID
+ TQString systemId; // used by parseExternalID() to store the system ID
+ TQString attDeclEName; // use by parseAttlistDecl()
+ TQString attDeclAName; // use by parseAttlistDecl()
+
+ // flags for some features support
+ bool useNamespaces;
+ bool useNamespacePrefixes;
+ bool reportWhitespaceCharData;
+ bool reportEntities;
+
+ // used to build the attribute list
+ TQXmlAttributes attList;
+
+ // used in TQXmlSimpleReader::parseContent() to decide whether character
+ // data was read
+ bool contentCharDataRead;
+
+ // helper classes
+ TQXmlLocator *locator;
+ TQXmlNamespaceSupport namespaceSupport;
+
+ // error string
+ TQString error;
+
+ // arguments for parse functions (this is needed to allow incremental
+ // parsing)
+ bool parsePI_xmldecl;
+ bool parseName_useRef;
+ bool parseReference_charDataRead;
+ TQXmlSimpleReader::EntityRecognitionContext parseReference_context;
+ bool parseExternalID_allowPublicID;
+ TQXmlSimpleReader::EntityRecognitionContext parsePEReference_context;
+ TQString parseString_s;
+
+ // for incremental parsing
+ struct ParseState {
+ typedef bool (TQXmlSimpleReader::*ParseFunction) ();
+ ParseFunction function;
+ int state;
+ };
+ TQValueStack<ParseState> *parseStack;
+
+ // used in parseProlog()
+ bool xmldecl_possible;
+ bool doctype_read;
+
+ // used in parseDoctype()
+ bool startDTDwasReported;
+
+ // used in parseString()
+ signed char Done;
+
+ bool undefEntityInAttrHack;
+
+ int nameValueLen;
+ int refValueLen;
+ int stringValueLen;
+
+ // friend declarations
+ friend class TQXmlSimpleReader;
+};
+
+
+/*********************************************
+ *
+ * TQXmlSimpleReader
+ *
+ *********************************************/
+
+/*!
+ \class TQXmlReader tqxml.h
+ \reentrant
+ \brief The TQXmlReader class provides an interface for XML readers (i.e.
+ parsers).
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+
+ This abstract class provides an interface for all of TQt's XML
+ readers. Currently there is only one implementation of a reader
+ included in TQt's XML module: TQXmlSimpleReader. In future releases
+ there might be more readers with different properties available
+ (e.g. a validating parser).
+
+ The design of the XML classes follows the \link
+ http://www.saxproject.org/ SAX2 Java interface\endlink, with
+ the names adapted to fit TQt naming conventions. It should be very
+ easy for anybody who has worked with SAX2 to get started with the
+ TQt XML classes.
+
+ All readers use the class TQXmlInputSource to read the input
+ document. Since you are normally interested in particular content
+ in the XML document, the reader reports the content through
+ special handler classes (TQXmlDTDHandler, TQXmlDeclHandler,
+ TQXmlContentHandler, TQXmlEntityResolver, TQXmlErrorHandler and
+ TQXmlLexicalHandler), which you must subclass, if you want to
+ process the contents.
+
+ Since the handler classes only describe interfaces you must
+ implement all the functions. We provide the TQXmlDefaultHandler
+ class to make this easier: it implements a default behaviour (do
+ nothing) for all functions, so you can subclass it and just
+ implement the functions you are interested in.
+
+ Features and properties of the reader can be set with setFeature()
+ and setProperty() respectively. You can set the reader to use your
+ own subclasses with setEntityResolver(), setDTDHandler(),
+ setContentHandler(), setErrorHandler(), setLexicalHandler() and
+ setDeclHandler(). The parse itself is started with a call to
+ parse().
+
+ \sa TQXmlSimpleReader
+*/
+
+/*!
+ \fn bool TQXmlReader::feature( const TQString& name, bool *ok ) const
+
+ If the reader has the feature called \a name, the feature's value
+ is returned. If no such feature exists the return value is
+ undefined.
+
+ If \a ok is not 0: \a *ok is set to TRUE if the reader has the
+ feature called \a name; otherwise \a *ok is set to FALSE.
+
+ \sa setFeature() hasFeature()
+*/
+
+/*!
+ \fn void TQXmlReader::setFeature( const TQString& name, bool value )
+
+ Sets the feature called \a name to the given \a value. If the
+ reader doesn't have the feature nothing happens.
+
+ \sa feature() hasFeature()
+*/
+
+/*!
+ \fn bool TQXmlReader::hasFeature( const TQString& name ) const
+
+ Returns \c TRUE if the reader has the feature called \a name;
+ otherwise returns FALSE.
+
+ \sa feature() setFeature()
+*/
+
+/*!
+ \fn void* TQXmlReader::property( const TQString& name, bool *ok ) const
+
+ If the reader has the property \a name, this function returns the
+ value of the property; otherwise the return value is undefined.
+
+ If \a ok is not 0: if the reader has the \a name property \a *ok
+ is set to TRUE; otherwise \a *ok is set to FALSE.
+
+ \sa setProperty() hasProperty()
+*/
+
+/*!
+ \fn void TQXmlReader::setProperty( const TQString& name, void* value )
+
+ Sets the property \a name to \a value. If the reader doesn't have
+ the property nothing happens.
+
+ \sa property() hasProperty()
+*/
+
+/*!
+ \fn bool TQXmlReader::hasProperty( const TQString& name ) const
+
+ Returns TRUE if the reader has the property \a name; otherwise
+ returns FALSE.
+
+ \sa property() setProperty()
+*/
+
+/*!
+ \fn void TQXmlReader::setEntityResolver( TQXmlEntityResolver* handler )
+
+ Sets the entity resolver to \a handler.
+
+ \sa entityResolver()
+*/
+
+/*!
+ \fn TQXmlEntityResolver* TQXmlReader::entityResolver() const
+
+ Returns the entity resolver or 0 if none was set.
+
+ \sa setEntityResolver()
+*/
+
+/*!
+ \fn void TQXmlReader::setDTDHandler( TQXmlDTDHandler* handler )
+
+ Sets the DTD handler to \a handler.
+
+ \sa DTDHandler()
+*/
+
+/*!
+ \fn TQXmlDTDHandler* TQXmlReader::DTDHandler() const
+
+ Returns the DTD handler or 0 if none was set.
+
+ \sa setDTDHandler()
+*/
+
+/*!
+ \fn void TQXmlReader::setContentHandler( TQXmlContentHandler* handler )
+
+ Sets the content handler to \a handler.
+
+ \sa contentHandler()
+*/
+
+/*!
+ \fn TQXmlContentHandler* TQXmlReader::contentHandler() const
+
+ Returns the content handler or 0 if none was set.
+
+ \sa setContentHandler()
+*/
+
+/*!
+ \fn void TQXmlReader::setErrorHandler( TQXmlErrorHandler* handler )
+
+ Sets the error handler to \a handler. Clears the error handler if
+ \a handler is 0.
+
+ \sa errorHandler()
+*/
+
+/*!
+ \fn TQXmlErrorHandler* TQXmlReader::errorHandler() const
+
+ Returns the error handler or 0 if none is set.
+
+ \sa setErrorHandler()
+*/
+
+/*!
+ \fn void TQXmlReader::setLexicalHandler( TQXmlLexicalHandler* handler )
+
+ Sets the lexical handler to \a handler.
+
+ \sa lexicalHandler()
+*/
+
+/*!
+ \fn TQXmlLexicalHandler* TQXmlReader::lexicalHandler() const
+
+ Returns the lexical handler or 0 if none was set.
+
+ \sa setLexicalHandler()
+*/
+
+/*!
+ \fn void TQXmlReader::setDeclHandler( TQXmlDeclHandler* handler )
+
+ Sets the declaration handler to \a handler.
+
+ \sa declHandler()
+*/
+
+/*!
+ \fn TQXmlDeclHandler* TQXmlReader::declHandler() const
+
+ Returns the declaration handler or 0 if none was set.
+
+ \sa setDeclHandler()
+*/
+
+/*!
+ \fn bool TQXmlReader::parse( const TQXmlInputSource& input )
+
+ \obsolete
+*/
+
+/*!
+ \fn bool TQXmlReader::parse( const TQXmlInputSource* input )
+
+ Reads an XML document from \a input and parses it. Returns TRUE if
+ the parsing was successful; otherwise returns FALSE.
+*/
+
+
+/*!
+ \class TQXmlSimpleReader tqxml.h
+ \reentrant
+ \brief The TQXmlSimpleReader class provides an implementation of a
+ simple XML reader (parser).
+\if defined(commercial)
+ It is part of the <a href="commercialeditions.html">TQt Enterprise Edition</a>.
+\endif
+
+ \module XML
+ \ingroup xml-tools
+ \mainclass
+
+ This XML reader is sufficient for simple parsing tasks. The reader:
+ \list
+ \i provides a well-formed parser;
+ \i does not parse any external entities;
+ \i can do namespace processing.
+ \endlist
+
+ Documents are parsed with a call to parse().
+
+*/
+
+static inline bool is_S(TQChar ch)
+{
+ ushort uc = ch.tqunicode();
+ return (uc == ' ' || uc == '\t' || uc == '\n' || uc == '\r');
+}
+
+enum NameChar { NameBeginning, NameNotBeginning, NotName };
+
+static const char Begi = (char)NameBeginning;
+static const char NtBg = (char)NameNotBeginning;
+static const char NotN = (char)NotName;
+
+static const char nameCharTable[128] =
+{
+// 0x00
+ NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+// 0x10
+ NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+// 0x20 (0x2D is '-', 0x2E is '.')
+ NotN, NotN, NotN, NotN, NotN, NotN, NotN, NotN,
+ NotN, NotN, NotN, NotN, NotN, NtBg, NtBg, NotN,
+// 0x30 (0x30..0x39 are '0'..'9', 0x3A is ':')
+ NtBg, NtBg, NtBg, NtBg, NtBg, NtBg, NtBg, NtBg,
+ NtBg, NtBg, Begi, NotN, NotN, NotN, NotN, NotN,
+// 0x40 (0x41..0x5A are 'A'..'Z')
+ NotN, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+// 0x50 (0x5F is '_')
+ Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ Begi, Begi, Begi, NotN, NotN, NotN, NotN, Begi,
+// 0x60 (0x61..0x7A are 'a'..'z')
+ NotN, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+// 0x70
+ Begi, Begi, Begi, Begi, Begi, Begi, Begi, Begi,
+ Begi, Begi, Begi, NotN, NotN, NotN, NotN, NotN
+};
+
+static inline NameChar fastDetermineNameChar(TQChar ch)
+{
+ ushort uc = ch.tqunicode();
+ if (!(uc & ~0x7f)) // uc < 128
+ return (NameChar)nameCharTable[uc];
+
+ TQChar::Category cat = ch.category();
+ // ### some these categories might be slightly wrong
+ if ((cat >= TQChar::Letter_Uppercase && cat <= TQChar::Letter_Other)
+ || cat == TQChar::Number_Letter)
+ return NameBeginning;
+ if ((cat >= TQChar::Number_DecimalDigit && cat <= TQChar::Number_Other)
+ || (cat >= TQChar::Mark_NonSpacing && cat <= TQChar::Mark_Enclosing))
+ return NameNotBeginning;
+ return NotName;
+}
+
+static NameChar determineNameChar(TQChar ch)
+{
+ return fastDetermineNameChar(ch);
+}
+
+inline void TQXmlSimpleReader::nameClear()
+{
+ d->nameValueLen = 0; nameArrayPos = 0;
+}
+
+inline void TQXmlSimpleReader::refClear()
+{
+ d->refValueLen = 0; refArrayPos = 0;
+}
+
+/*!
+ Constructs a simple XML reader with the following feature settings:
+ \table
+ \header \i Feature \i Setting
+ \row \i \e http://xml.org/sax/features/namespaces \i TRUE
+ \row \i \e http://xml.org/sax/features/namespace-prefixes \i FALSE
+ \row \i \e http://trolltech.com/xml/features/report-whitespace-only-CharData
+ \i TRUE
+ \row \i \e http://trolltech.com/xml/features/report-start-end-entity \i FALSE
+ \endtable
+
+ More information about features can be found in the \link
+ xml.html#sax2Features TQt SAX2 overview. \endlink
+
+ \sa setFeature()
+*/
+
+TQXmlSimpleReader::TQXmlSimpleReader()
+{
+ d = new TQXmlSimpleReaderPrivate();
+ d->locator = new TQXmlSimpleReaderLocator( this );
+
+ entityRes = 0;
+ dtdHnd = 0;
+ contentHnd = 0;
+ errorHnd = 0;
+ lexicalHnd = 0;
+ declHnd = 0;
+
+ // default feature settings
+ d->useNamespaces = TRUE;
+ d->useNamespacePrefixes = FALSE;
+ d->reportWhitespaceCharData = TRUE;
+ d->reportEntities = FALSE;
+}
+
+/*!
+ Destroys the simple XML reader.
+*/
+TQXmlSimpleReader::~TQXmlSimpleReader()
+{
+ delete d->locator;
+ delete d;
+}
+
+/*!
+ \reimp
+*/
+bool TQXmlSimpleReader::feature( const TQString& name, bool *ok ) const
+{
+ if ( ok != 0 )
+ *ok = TRUE;
+ if ( name == "http://xml.org/sax/features/namespaces" ) {
+ return d->useNamespaces;
+ } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
+ return d->useNamespacePrefixes;
+ } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ return d->reportWhitespaceCharData;
+ } else if ( name == "http://trolltech.com/xml/features/report-start-end-entity" ) {
+ return d->reportEntities;
+ } else {
+ qWarning( "Unknown feature %s", name.latin1() );
+ if ( ok != 0 )
+ *ok = FALSE;
+ }
+ return FALSE;
+}
+
+/*!
+ Sets the state of the feature \a name to \a value:
+
+ If the feature is not recognized, it is ignored.
+
+ The following features are supported:
+ \table
+ \header \i Feature \i Notes
+ \row \i \e http://xml.org/sax/features/namespaces
+ \i If this feature is TRUE, namespace processing is
+ performed.
+ \row \i \e http://xml.org/sax/features/namespace-prefixes
+ \i If this feature is TRUE, the the original prefixed names
+ and attributes used for namespace declarations are
+ reported.
+ \row \i \e http://trolltech.com/xml/features/report-whitespace-only-CharData
+ \i If this feature is TRUE, CharData that only contain
+ whitespace are not ignored, but are reported via
+ TQXmlContentHandler::characters().
+ \row \i \e http://trolltech.com/xml/features/report-start-end-entity
+ \i If this feature is TRUE, the parser reports
+ TQXmlContentHandler::startEntity() and
+ TQXmlContentHandler::endEntity() events. So character data
+ might be reported in chunks. If this feature is FALSE, the
+ parser does not report those events, but rather silently
+ substitutes the entities and reports the character data in
+ one chunk.
+ \endtable
+
+ \quotefile xml/tagreader-with-features/tagreader.cpp
+ \skipto reader
+ \printline reader
+ \skipto setFeature
+ \printline setFeature
+ \printline TRUE
+
+ (Code taken from xml/tagreader-with-features/tagreader.cpp)
+
+ \sa feature() hasFeature()
+*/
+void TQXmlSimpleReader::setFeature( const TQString& name, bool value )
+{
+ if ( name == "http://xml.org/sax/features/namespaces" ) {
+ d->useNamespaces = value;
+ } else if ( name == "http://xml.org/sax/features/namespace-prefixes" ) {
+ d->useNamespacePrefixes = value;
+ } else if ( name == "http://trolltech.com/xml/features/report-whitespace-only-CharData" ) {
+ d->reportWhitespaceCharData = value;
+ } else if ( name == "http://trolltech.com/xml/features/report-start-end-entity" ) {
+ d->reportEntities = value;
+ } else {
+ qWarning( "Unknown feature %s", name.latin1() );
+ }
+}
+
+/*! \reimp
+*/
+bool TQXmlSimpleReader::hasFeature( const TQString& name ) const
+{
+ if ( name == "http://xml.org/sax/features/namespaces"
+ || name == "http://xml.org/sax/features/namespace-prefixes"
+ || name == "http://trolltech.com/xml/features/report-whitespace-only-CharData"
+ || name == "http://trolltech.com/xml/features/report-start-end-entity" ) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/*! \reimp
+*/
+void* TQXmlSimpleReader::property( const TQString&, bool *ok ) const
+{
+ if ( ok != 0 )
+ *ok = FALSE;
+ return 0;
+}
+
+/*! \reimp
+*/
+void TQXmlSimpleReader::setProperty( const TQString&, void* )
+{
+}
+
+/*!
+ \reimp
+*/
+bool TQXmlSimpleReader::hasProperty( const TQString& ) const
+{
+ return FALSE;
+}
+
+/*!
+ \reimp
+*/
+void TQXmlSimpleReader::setEntityResolver( TQXmlEntityResolver* handler )
+{ entityRes = handler; }
+
+/*!
+ \reimp
+*/
+TQXmlEntityResolver* TQXmlSimpleReader::entityResolver() const
+{ return entityRes; }
+
+/*!
+ \reimp
+*/
+void TQXmlSimpleReader::setDTDHandler( TQXmlDTDHandler* handler )
+{ dtdHnd = handler; }
+
+/*!
+ \reimp
+*/
+TQXmlDTDHandler* TQXmlSimpleReader::DTDHandler() const
+{ return dtdHnd; }
+
+/*!
+ \reimp
+*/
+void TQXmlSimpleReader::setContentHandler( TQXmlContentHandler* handler )
+{ contentHnd = handler; }
+
+/*!
+ \reimp
+*/
+TQXmlContentHandler* TQXmlSimpleReader::contentHandler() const
+{ return contentHnd; }
+
+/*!
+ \reimp
+*/
+void TQXmlSimpleReader::setErrorHandler( TQXmlErrorHandler* handler )
+{ errorHnd = handler; }
+
+/*!
+ \reimp
+*/
+TQXmlErrorHandler* TQXmlSimpleReader::errorHandler() const
+{ return errorHnd; }
+
+/*!
+ \reimp
+*/
+void TQXmlSimpleReader::setLexicalHandler( TQXmlLexicalHandler* handler )
+{ lexicalHnd = handler; }
+
+/*!
+ \reimp
+*/
+TQXmlLexicalHandler* TQXmlSimpleReader::lexicalHandler() const
+{ return lexicalHnd; }
+
+/*!
+ \reimp
+*/
+void TQXmlSimpleReader::setDeclHandler( TQXmlDeclHandler* handler )
+{ declHnd = handler; }
+
+/*!
+ \reimp
+*/
+TQXmlDeclHandler* TQXmlSimpleReader::declHandler() const
+{ return declHnd; }
+
+
+
+/*!
+ \reimp
+*/
+bool TQXmlSimpleReader::parse( const TQXmlInputSource& input )
+{
+ return parse( &input, FALSE );
+}
+
+/*!
+ \reimp
+*/
+bool TQXmlSimpleReader::parse( const TQXmlInputSource* input )
+{
+ return parse( input, FALSE );
+}
+
+/*!
+ Reads an XML document from \a input and parses it. Returns FALSE
+ if the parsing detects an error; otherwise returns TRUE.
+
+ If \a incremental is TRUE, the parser does not return FALSE when
+ it reaches the end of the \a input without reaching the end of the
+ XML file. Instead it stores the state of the parser so that
+ parsing can be continued at a later stage when more data is
+ available. You can use the function parseContinue() to continue
+ with parsing. This class stores a pointer to the input source \a
+ input and the parseContinue() function tries to read from that
+ input souce. This means that you should not delete the input
+ source \a input until you've finished your calls to
+ parseContinue(). If you call this function with \a incremental
+ TRUE whilst an incremental parse is in progress a new parsing
+ session will be started and the previous session lost.
+
+ If \a incremental is FALSE, this function behaves like the normal
+ parse function, i.e. it returns FALSE when the end of input is
+ reached without reaching the end of the XML file and the parsing
+ cannot be continued.
+
+ \sa parseContinue() TQSocket
+*/
+bool TQXmlSimpleReader::parse( const TQXmlInputSource *input, bool incremental )
+{
+ init( input );
+ if ( incremental ) {
+ d->initIncrementalParsing();
+ } else {
+ delete d->parseStack;
+ d->parseStack = 0;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ contentHnd->setDocumentLocator( d->locator );
+ if ( !contentHnd->startDocument() ) {
+ reportParseError( contentHnd->errorString() );
+ d->tags.clear();
+ return FALSE;
+ }
+ }
+ return parseBeginOrContinue( 0, incremental );
+}
+
+/*!
+ Continues incremental parsing; this function reads the input from
+ the TQXmlInputSource that was specified with the last parse()
+ command. To use this function, you \e must have called parse()
+ with the incremental argument set to TRUE.
+
+ Returns FALSE if a parsing error occurs; otherwise returns TRUE.
+
+ If the input source returns an empty string for the function
+ TQXmlInputSource::data(), then this means that the end of the XML
+ file has been reached; this is quite important, especially if you
+ want to use the reader to parse more than one XML file.
+
+ The case of the end of the XML file being reached without having
+ finished parsing is not considered to be an error: you can
+ continue parsing at a later stage by calling this function again
+ when there is more data available to parse.
+
+ This function assumes that the end of the XML document is reached
+ if the TQXmlInputSource::next() function returns
+ TQXmlInputSource::EndOfDocument. If the parser has not finished
+ parsing when it encounters this symbol, it is an error and FALSE
+ is returned.
+
+ \sa parse() TQXmlInputSource::next()
+*/
+bool TQXmlSimpleReader::parseContinue()
+{
+ if ( d->parseStack == 0 || d->parseStack->isEmpty() )
+ return FALSE;
+ initData();
+ int state = d->parseStack->pop().state;
+ return parseBeginOrContinue( state, TRUE );
+}
+
+/*
+ Common part of parse() and parseContinue()
+*/
+bool TQXmlSimpleReader::parseBeginOrContinue( int state, bool incremental )
+{
+ bool atEndOrig = atEnd();
+
+ if ( state==0 ) {
+ if ( !parseProlog() ) {
+ if ( incremental && d->error.isNull() ) {
+ pushParseState( 0, 0 );
+ return TRUE;
+ } else {
+ d->tags.clear();
+ return FALSE;
+ }
+ }
+ state = 1;
+ }
+ if ( state==1 ) {
+ if ( !parseElement() ) {
+ if ( incremental && d->error.isNull() ) {
+ pushParseState( 0, 1 );
+ return TRUE;
+ } else {
+ d->tags.clear();
+ return FALSE;
+ }
+ }
+ state = 2;
+ }
+ // parse Misc*
+ while ( !atEnd() ) {
+ if ( !parseMisc() ) {
+ if ( incremental && d->error.isNull() ) {
+ pushParseState( 0, 2 );
+ return TRUE;
+ } else {
+ d->tags.clear();
+ return FALSE;
+ }
+ }
+ }
+ if ( !atEndOrig && incremental ) {
+ // we parsed something at all, so be prepared to come back later
+ pushParseState( 0, 2 );
+ return TRUE;
+ }
+ // is stack empty?
+ if ( !d->tags.isEmpty() && !d->error.isNull() ) {
+ reportParseError( XMLERR_UNEXPECTEDEOF );
+ d->tags.clear();
+ return FALSE;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ delete d->parseStack;
+ d->parseStack = 0;
+ if ( !contentHnd->endDocument() ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+//
+// The following private parse functions have another semantics for the return
+// value: They return TRUE iff parsing has finished successfully (i.e. the end
+// of the XML file must be reached!). If one of these functions return FALSE,
+// there is only an error when d->error.isNULL() is also FALSE.
+//
+
+/*
+ For the incremental parsing, it is very important that the parse...()
+ functions have a certain structure. Since it might be hard to understand how
+ they work, here is a description of the tqlayout of these functions:
+
+ bool TQXmlSimpleReader::parse...()
+ {
+(1) const signed char Init = 0;
+ ...
+
+(2) const signed char Inp... = 0;
+ ...
+
+(3) static signed char table[3][2] = {
+ ...
+ };
+ signed char state;
+ signed char input;
+
+(4) if (d->parseStack == 0 || d->parseStack->isEmpty()) {
+(4a) ...
+ } else {
+(4b) ...
+ }
+
+ for ( ; ; ) {
+(5) switch ( state ) {
+ ...
+ }
+
+(6)
+(6a) if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseNmtoken, state );
+ return FALSE;
+ }
+(6b) if (determineNameChar(c) != NotName) {
+ ...
+ }
+(7) state = table[state][input];
+
+(8) switch ( state ) {
+ ...
+ }
+ }
+ }
+
+ Explanation:
+ ad 1: constants for the states (used in the transition table)
+ ad 2: constants for the input (used in the transition table)
+ ad 3: the transition table for the state machine
+ ad 4: test if we are in a parseContinue() step
+ a) if no, do inititalizations
+ b) if yes, restore the state and call parse functions recursively
+ ad 5: Do some actions according to the state; from the logical execution
+ order, this code belongs after 8 (see there for an explanation)
+ ad 6: Check the character that is at the actual "cursor" position:
+ a) If we reached the EOF, report either error or push the state (in the
+ case of incremental parsing).
+ b) Otherwise, set the input character constant for the transition
+ table.
+ ad 7: Get the new state according to the input that was read.
+ ad 8: Do some actions according to the state. The last line in every case
+ statement reads new data (i.e. it move the cursor). This can also be
+ done by calling another parse...() funtion. If you need processing for
+ this state after that, you have to put it into the switch statement 5.
+ This ensures that you have a well defined re-entry point, when you ran
+ out of data.
+*/
+
+/*
+ Parses the prolog [22].
+*/
+bool TQXmlSimpleReader::parseProlog()
+{
+ const signed char Init = 0;
+ const signed char EatWS = 1; // eat white spaces
+ const signed char Lt = 2; // '<' read
+ const signed char Em = 3; // '!' read
+ const signed char DocType = 4; // read doctype
+ const signed char Comment = 5; // read comment
+ const signed char CommentR = 6; // same as Comment, but already reported
+ const signed char PInstr = 7; // read PI
+ const signed char PInstrR = 8; // same as PInstr, but already reported
+ const signed char Done = 9;
+
+ const signed char InpWs = 0;
+ const signed char InpLt = 1; // <
+ const signed char InpQm = 2; // ?
+ const signed char InpEm = 3; // !
+ const signed char InpD = 4; // D
+ const signed char InpDash = 5; // -
+ const signed char InpUnknown = 6;
+
+ static const signed char table[9][7] = {
+ /* InpWs InpLt InpQm InpEm InpD InpDash InpUnknown */
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // Init
+ { -1, Lt, -1, -1, -1, -1, -1 }, // EatWS
+ { -1, -1, PInstr,Em, Done, -1, Done }, // Lt
+ { -1, -1, -1, -1, DocType, Comment, -1 }, // Em
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // DocType
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // Comment
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // CommentR
+ { EatWS, Lt, -1, -1, -1, -1, -1 }, // PInstr
+ { EatWS, Lt, -1, -1, -1, -1, -1 } // PInstrR
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ d->xmldecl_possible = TRUE;
+ d->doctype_read = FALSE;
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseProlog (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseProlog, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case DocType:
+ if ( d->doctype_read ) {
+ reportParseError( XMLERR_MORETHANONEDOCTYPE );
+ return FALSE;
+ } else {
+ d->doctype_read = FALSE;
+ }
+ break;
+ case Comment:
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ state = CommentR;
+ break;
+ case PInstr:
+ // call the handler
+ if ( contentHnd ) {
+ if ( d->xmldecl_possible && !d->xmlVersion.isEmpty() ) {
+ TQString value( "version = '" );
+ value += d->xmlVersion;
+ value += "'";
+ if ( !d->encoding.isEmpty() ) {
+ value += " encoding = '";
+ value += d->encoding;
+ value += "'";
+ }
+ if ( d->standalone == TQXmlSimpleReaderPrivate::Yes ) {
+ value += " standalone = 'yes'";
+ } else if ( d->standalone == TQXmlSimpleReaderPrivate::No ) {
+ value += " standalone = 'no'";
+ }
+ if ( !contentHnd->processingInstruction( "xml", value ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ } else {
+ if ( !contentHnd->processingInstruction( name(), string() ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ // XML declaration only on first position possible
+ d->xmldecl_possible = FALSE;
+ state = PInstrR;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ reportParseError( XMLERR_ERRORPARSINGELEMENT );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseProlog, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c.tqunicode() == '<' ) {
+ input = InpLt;
+ } else if ( c.tqunicode() == '?' ) {
+ input = InpQm;
+ } else if ( c.tqunicode() == '!' ) {
+ input = InpEm;
+ } else if ( c.tqunicode() == 'D' ) {
+ input = InpD;
+ } else if ( c.tqunicode() == '-' ) {
+ input = InpDash;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case EatWS:
+ // XML declaration only on first position possible
+ d->xmldecl_possible = FALSE;
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseProlog, state );
+ return FALSE;
+ }
+ break;
+ case Lt:
+ next();
+ break;
+ case Em:
+ // XML declaration only on first position possible
+ d->xmldecl_possible = FALSE;
+ next();
+ break;
+ case DocType:
+ if ( !parseDoctype() ) {
+ parseFailed( &TQXmlSimpleReader::parseProlog, state );
+ return FALSE;
+ }
+ break;
+ case Comment:
+ case CommentR:
+ if ( !parseComment() ) {
+ parseFailed( &TQXmlSimpleReader::parseProlog, state );
+ return FALSE;
+ }
+ break;
+ case PInstr:
+ case PInstrR:
+ d->parsePI_xmldecl = d->xmldecl_possible;
+ if ( !parsePI() ) {
+ parseFailed( &TQXmlSimpleReader::parseProlog, state );
+ return FALSE;
+ }
+ break;
+ }
+ }
+}
+
+/*
+ Parse an element [39].
+
+ Precondition: the opening '<' is already read.
+*/
+bool TQXmlSimpleReader::parseElement()
+{
+ const int Init = 0;
+ const int ReadName = 1;
+ const int Ws1 = 2;
+ const int STagEnd = 3;
+ const int STagEnd2 = 4;
+ const int ETagBegin = 5;
+ const int ETagBegin2 = 6;
+ const int Ws2 = 7;
+ const int EmptyTag = 8;
+ const int Attrib = 9;
+ const int AttribPro = 10; // like Attrib, but processAttribute was already called
+ const int Ws3 = 11;
+ const int Done = 12;
+
+ const int InpWs = 0; // whitespace
+ const int InpNameBe = 1; // is_NameBeginning()
+ const int InpGt = 2; // >
+ const int InpSlash = 3; // /
+ const int InpUnknown = 4;
+
+ static const int table[12][5] = {
+ /* InpWs InpNameBe InpGt InpSlash InpUnknown */
+ { -1, ReadName, -1, -1, -1 }, // Init
+ { Ws1, Attrib, STagEnd, EmptyTag, -1 }, // ReadName
+ { -1, Attrib, STagEnd, EmptyTag, -1 }, // Ws1
+ { STagEnd2, STagEnd2, STagEnd2, STagEnd2, STagEnd2 }, // STagEnd
+ { -1, -1, -1, ETagBegin, -1 }, // STagEnd2
+ { -1, ETagBegin2, -1, -1, -1 }, // ETagBegin
+ { Ws2, -1, Done, -1, -1 }, // ETagBegin2
+ { -1, -1, Done, -1, -1 }, // Ws2
+ { -1, -1, Done, -1, -1 }, // EmptyTag
+ { Ws3, Attrib, STagEnd, EmptyTag, -1 }, // Attrib
+ { Ws3, Attrib, STagEnd, EmptyTag, -1 }, // AttribPro
+ { -1, Attrib, STagEnd, EmptyTag, -1 } // Ws3
+ };
+ int state;
+ int input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseElement (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseElement, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case ReadName:
+ // store it on the stack
+ d->tags.push( name() );
+ // empty the attributes
+ d->attList.clear();
+ if ( d->useNamespaces )
+ d->namespaceSupport.pushContext();
+ break;
+ case ETagBegin2:
+ if ( !processElementETagBegin2() )
+ return FALSE;
+ break;
+ case Attrib:
+ if ( !processElementAttribute() )
+ return FALSE;
+ state = AttribPro;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ reportParseError( XMLERR_ERRORPARSINGELEMENT );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseElement, state );
+ return FALSE;
+ }
+
+ if (fastDetermineNameChar(c) == NameBeginning) {
+ input = InpNameBe;
+ } else if ( c.tqunicode() == '>' ) {
+ input = InpGt;
+ } else if (is_S(c)) {
+ input = InpWs;
+ } else if (c.tqunicode() == '/') {
+ input = InpSlash;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case ReadName:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseElement, state );
+ return FALSE;
+ }
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseElement, state );
+ return FALSE;
+ }
+ break;
+ case STagEnd:
+ // call the handler
+ if ( contentHnd ) {
+ const TQString &tagsTop = d->tags.top();
+ if ( d->useNamespaces ) {
+ TQString uri, lname;
+ d->namespaceSupport.processName(tagsTop, FALSE, uri, lname);
+ if (!contentHnd->startElement(uri, lname, tagsTop, d->attList)) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ } else {
+ if (!contentHnd->startElement(TQString::null, TQString::null, tagsTop, d->attList)) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ next();
+ break;
+ case STagEnd2:
+ if ( !parseContent() ) {
+ parseFailed( &TQXmlSimpleReader::parseElement, state );
+ return FALSE;
+ }
+ break;
+ case ETagBegin:
+ next();
+ break;
+ case ETagBegin2:
+ // get the name of the tag
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseElement, state );
+ return FALSE;
+ }
+ break;
+ case EmptyTag:
+ if ( d->tags.isEmpty() ) {
+ reportParseError( XMLERR_TAGMISMATCH );
+ return FALSE;
+ }
+ if ( !processElementEmptyTag() )
+ return FALSE;
+ next();
+ break;
+ case Attrib:
+ case AttribPro:
+ // get name and value of attribute
+ if ( !parseAttribute() ) {
+ parseFailed( &TQXmlSimpleReader::parseElement, state );
+ return FALSE;
+ }
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+/*
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+bool TQXmlSimpleReader::processElementEmptyTag()
+{
+ TQString uri, lname;
+ // pop the stack and call the handler
+ if ( contentHnd ) {
+ if ( d->useNamespaces ) {
+ // report startElement first...
+ d->namespaceSupport.processName( d->tags.top(), FALSE, uri, lname );
+ if ( !contentHnd->startElement( uri, lname, d->tags.top(), d->attList ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ // ... followed by endElement...
+ if ( !contentHnd->endElement( uri, lname, d->tags.pop() ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ // ... followed by endPrefixMapping
+ TQStringList prefixesBefore, prefixesAfter;
+ if ( contentHnd ) {
+ prefixesBefore = d->namespaceSupport.prefixes();
+ }
+ d->namespaceSupport.popContext();
+ // call the handler for prefix mapping
+ prefixesAfter = d->namespaceSupport.prefixes();
+ for ( TQStringList::Iterator it = prefixesBefore.begin(); it != prefixesBefore.end(); ++it ) {
+ if ( prefixesAfter.tqcontains(*it) == 0 ) {
+ if ( !contentHnd->endPrefixMapping( *it ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ } else {
+ // report startElement first...
+ if ( !contentHnd->startElement( TQString::null, TQString::null, d->tags.top(), d->attList ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ // ... followed by endElement
+ if ( !contentHnd->endElement( TQString::null, TQString::null, d->tags.pop() ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ } else {
+ d->tags.pop_back();
+ d->namespaceSupport.popContext();
+ }
+ return TRUE;
+}
+/*
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+bool TQXmlSimpleReader::processElementETagBegin2()
+{
+ const TQString &name = TQXmlSimpleReader::name();
+
+ // pop the stack and compare it with the name
+ if ( d->tags.pop() != name ) {
+ reportParseError( XMLERR_TAGMISMATCH );
+ return FALSE;
+ }
+ // call the handler
+ if ( contentHnd ) {
+ TQString uri, lname;
+
+ if (d->useNamespaces)
+ d->namespaceSupport.processName(name, FALSE, uri, lname);
+ if (!contentHnd->endElement(uri, lname, name)) {
+ reportParseError(contentHnd->errorString());
+ return FALSE;
+ }
+ }
+ if ( d->useNamespaces ) {
+ NamespaceMap prefixesBefore, prefixesAfter;
+ if (contentHnd)
+ prefixesBefore = d->namespaceSupport.d->ns;
+
+ d->namespaceSupport.popContext();
+ // call the handler for prefix mapping
+ if ( contentHnd ) {
+ prefixesAfter = d->namespaceSupport.d->ns;
+ if (prefixesBefore.size() != prefixesAfter.size()) {
+ for (NamespaceMap::const_iterator it = prefixesBefore.constBegin(); it != prefixesBefore.constEnd(); ++it) {
+ if (!it.key().isEmpty() && !prefixesAfter.tqcontains(it.key())) {
+ if (!contentHnd->endPrefixMapping(it.key())) {
+ reportParseError(contentHnd->errorString());
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+ }
+ return TRUE;
+}
+/*
+ Helper to break down the size of the code in the case statement.
+ Return FALSE on error, otherwise TRUE.
+*/
+bool TQXmlSimpleReader::processElementAttribute()
+{
+ TQString uri, lname, prefix;
+ const TQString &name = TQXmlSimpleReader::name();
+ const TQString &string = TQXmlSimpleReader::string();
+
+ // add the attribute to the list
+ if ( d->useNamespaces ) {
+ // is it a namespace declaration?
+ d->namespaceSupport.splitName(name, prefix, lname);
+ if (prefix == "xmlns") {
+ // namespace declaration
+ d->namespaceSupport.setPrefix( lname, string );
+ if ( d->useNamespacePrefixes ) {
+ // according to http://www.w3.org/2000/xmlns/, the "prefix"
+ // xmlns maps to the namespace name
+ // http://www.w3.org/2000/xmlns/
+ d->attList.append( name, "http://www.w3.org/2000/xmlns/", lname, string );
+ }
+ // call the handler for prefix mapping
+ if ( contentHnd ) {
+ if ( !contentHnd->startPrefixMapping( lname, string ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ } else {
+ // no namespace delcaration
+ d->namespaceSupport.processName( name, TRUE, uri, lname );
+ d->attList.append( name, uri, lname, string );
+ }
+ } else {
+ // no namespace support
+ d->attList.append( name, TQString::null, TQString::null, string );
+ }
+ return TRUE;
+}
+
+/*
+ Parse a content [43].
+
+ A content is only used between tags. If a end tag is found the < is already
+ read and the head stand on the '/' of the end tag '</name>'.
+*/
+bool TQXmlSimpleReader::parseContent()
+{
+ const signed char Init = 0;
+ const signed char ChD = 1; // CharData
+ const signed char ChD1 = 2; // CharData help state
+ const signed char ChD2 = 3; // CharData help state
+ const signed char Ref = 4; // Reference
+ const signed char Lt = 5; // '<' read
+ const signed char PInstr = 6; // PI
+ const signed char PInstrR = 7; // same as PInstr, but already reported
+ const signed char Elem = 8; // Element
+ const signed char Em = 9; // '!' read
+ const signed char Com = 10; // Comment
+ const signed char ComR = 11; // same as Com, but already reported
+ const signed char CDS = 12; // CDSect
+ const signed char CDS1 = 13; // read a CDSect
+ const signed char CDS2 = 14; // read a CDSect (help state)
+ const signed char CDS3 = 15; // read a CDSect (help state)
+ const signed char Done = 16; // finished reading content
+
+ const signed char InpLt = 0; // <
+ const signed char InpGt = 1; // >
+ const signed char InpSlash = 2; // /
+ const signed char InpTQMark = 3; // ?
+ const signed char InpEMark = 4; // !
+ const signed char InpAmp = 5; // &
+ const signed char InpDash = 6; // -
+ const signed char InpOpenB = 7; // [
+ const signed char InpCloseB = 8; // ]
+ const signed char InpUnknown = 9;
+
+ static const signed char mapCLT2FSMChar[] = {
+ InpUnknown, // white space
+ InpUnknown, // %
+ InpAmp, // &
+ InpGt, // >
+ InpLt, // <
+ InpSlash, // /
+ InpTQMark, // ?
+ InpEMark, // !
+ InpDash, // -
+ InpCloseB, // ]
+ InpOpenB, // [
+ InpUnknown, // =
+ InpUnknown, // "
+ InpUnknown, // '
+ InpUnknown // unknown
+ };
+
+ static const signed char table[16][10] = {
+ /* InpLt InpGt InpSlash InpTQMark InpEMark InpAmp InpDash InpOpenB InpCloseB InpUnknown */
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // Init
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD1, ChD }, // ChD
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD1
+ { Lt, -1, ChD, ChD, ChD, Ref, ChD, ChD, ChD2, ChD }, // ChD2
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Ref (same as Init)
+ { -1, -1, Done, PInstr, Em, -1, -1, -1, -1, Elem }, // Lt
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PInstr (same as Init)
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // PInstrR
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Elem (same as Init)
+ { -1, -1, -1, -1, -1, -1, Com, CDS, -1, -1 }, // Em
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // Com (same as Init)
+ { Lt, ChD, ChD, ChD, ChD, Ref, ChD, ChD, ChD, ChD }, // ComR
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS2, CDS1 }, // CDS1
+ { CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 }, // CDS2
+ { CDS1, Init, CDS1, CDS1, CDS1, CDS1, CDS1, CDS1, CDS3, CDS1 } // CDS3
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ d->contentCharDataRead = FALSE;
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseContent (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseContent, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Ref:
+ if ( !d->contentCharDataRead)
+ d->contentCharDataRead = d->parseReference_charDataRead;
+ break;
+ case PInstr:
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ state = PInstrR;
+ break;
+ case Com:
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ state = ComR;
+ break;
+ case CDS:
+ stringClear();
+ break;
+ case CDS2:
+ if ( !atEnd() && c.tqunicode() != ']' )
+ stringAddC( ']' );
+ break;
+ case CDS3:
+ // test if this skipping was legal
+ if ( !atEnd() ) {
+ if ( c.tqunicode() == '>' ) {
+ // the end of the CDSect
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->startCDATA() ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ if ( contentHnd ) {
+ if ( !contentHnd->characters( string() ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->endCDATA() ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ } else if (c.tqunicode() == ']') {
+ // three or more ']'
+ stringAddC( ']' );
+ } else {
+ // after ']]' comes another character
+ stringAddC( ']' );
+ stringAddC( ']' );
+ }
+ }
+ break;
+ case Done:
+ // call the handler for CharData
+ if ( contentHnd ) {
+ if ( d->contentCharDataRead ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ }
+ // Done
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_ERRORPARSINGCONTENT );
+ return FALSE;
+ }
+
+ // get input (use lookup-table instead of nested ifs for performance
+ // reasons)
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseContent, state );
+ return FALSE;
+ }
+ if ( c.row() ) {
+ input = InpUnknown;
+ } else {
+ input = mapCLT2FSMChar[ charLookupTable[ c.cell() ] ];
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Init:
+ // skip the ending '>' of a CDATASection
+ next();
+ break;
+ case ChD:
+ // on first call: clear string
+ if ( !d->contentCharDataRead ) {
+ d->contentCharDataRead = TRUE;
+ stringClear();
+ }
+ stringAddC();
+ if ( d->reportEntities ) {
+ if ( !reportEndEntities() )
+ return FALSE;
+ }
+ next();
+ break;
+ case ChD1:
+ // on first call: clear string
+ if ( !d->contentCharDataRead ) {
+ d->contentCharDataRead = TRUE;
+ stringClear();
+ }
+ stringAddC();
+ if ( d->reportEntities ) {
+ if ( !reportEndEntities() )
+ return FALSE;
+ }
+ next();
+ break;
+ case ChD2:
+ stringAddC();
+ if ( d->reportEntities ) {
+ if ( !reportEndEntities() )
+ return FALSE;
+ }
+ next();
+ break;
+ case Ref:
+ if ( !d->contentCharDataRead) {
+ // reference may be CharData; so clear string to be safe
+ stringClear();
+ d->parseReference_context = InContent;
+ if ( !parseReference() ) {
+ parseFailed( &TQXmlSimpleReader::parseContent, state );
+ return FALSE;
+ }
+ } else {
+ if ( d->reportEntities ) {
+ // report character data in chunks
+ if ( contentHnd ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ stringClear();
+ }
+ d->parseReference_context = InContent;
+ if ( !parseReference() ) {
+ parseFailed( &TQXmlSimpleReader::parseContent, state );
+ return FALSE;
+ }
+ }
+ break;
+ case Lt:
+ // call the handler for CharData
+ if ( contentHnd ) {
+ if ( d->contentCharDataRead ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ }
+ d->contentCharDataRead = FALSE;
+ next();
+ break;
+ case PInstr:
+ case PInstrR:
+ d->parsePI_xmldecl = FALSE;
+ if ( !parsePI() ) {
+ parseFailed( &TQXmlSimpleReader::parseContent, state );
+ return FALSE;
+ }
+ break;
+ case Elem:
+ if ( !parseElement() ) {
+ parseFailed( &TQXmlSimpleReader::parseContent, state );
+ return FALSE;
+ }
+ break;
+ case Em:
+ next();
+ break;
+ case Com:
+ case ComR:
+ if ( !parseComment() ) {
+ parseFailed( &TQXmlSimpleReader::parseContent, state );
+ return FALSE;
+ }
+ break;
+ case CDS:
+ d->parseString_s = "[CDATA[";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseContent, state );
+ return FALSE;
+ }
+ break;
+ case CDS1:
+ stringAddC();
+ next();
+ break;
+ case CDS2:
+ // skip ']'
+ next();
+ break;
+ case CDS3:
+ // skip ']'...
+ next();
+ break;
+ }
+ }
+}
+bool TQXmlSimpleReader::reportEndEntities()
+{
+ int count = (int)d->xmlRef.count();
+ while ( count != 0 && d->xmlRef.top().isEmpty() ) {
+ if ( contentHnd ) {
+ if ( d->reportWhitespaceCharData || !string().simplifyWhiteSpace().isEmpty() ) {
+ if ( !contentHnd->characters( string() ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ stringClear();
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->endEntity(d->xmlRefName.top()) ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ d->xmlRef.pop_back();
+ d->xmlRefName.pop_back();
+ count--;
+ }
+ return TRUE;
+}
+
+/*
+ Parse Misc [27].
+*/
+bool TQXmlSimpleReader::parseMisc()
+{
+ const signed char Init = 0;
+ const signed char Lt = 1; // '<' was read
+ const signed char Comment = 2; // read comment
+ const signed char eatWS = 3; // eat whitespaces
+ const signed char PInstr = 4; // read PI
+ const signed char Comment2 = 5; // read comment
+
+ const signed char InpWs = 0; // S
+ const signed char InpLt = 1; // <
+ const signed char InpQm = 2; // ?
+ const signed char InpEm = 3; // !
+ const signed char InpUnknown = 4;
+
+ static const signed char table[3][5] = {
+ /* InpWs InpLt InpQm InpEm InpUnknown */
+ { eatWS, Lt, -1, -1, -1 }, // Init
+ { -1, -1, PInstr,Comment, -1 }, // Lt
+ { -1, -1, -1, -1, Comment2 } // Comment
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseMisc (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseMisc, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case eatWS:
+ return TRUE;
+ case PInstr:
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ return TRUE;
+ case Comment2:
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseMisc, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c.tqunicode() == '<' ) {
+ input = InpLt;
+ } else if ( c.tqunicode() == '?' ) {
+ input = InpQm;
+ } else if ( c.tqunicode() == '!' ) {
+ input = InpEm;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case eatWS:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseMisc, state );
+ return FALSE;
+ }
+ break;
+ case Lt:
+ next();
+ break;
+ case PInstr:
+ d->parsePI_xmldecl = FALSE;
+ if ( !parsePI() ) {
+ parseFailed( &TQXmlSimpleReader::parseMisc, state );
+ return FALSE;
+ }
+ break;
+ case Comment:
+ next();
+ break;
+ case Comment2:
+ if ( !parseComment() ) {
+ parseFailed( &TQXmlSimpleReader::parseMisc, state );
+ return FALSE;
+ }
+ break;
+ }
+ }
+}
+
+/*
+ Parse a processing instruction [16].
+
+ If xmldec is TRUE, it tries to parse a PI or a XML declaration [23].
+
+ Precondition: the beginning '<' of the PI is already read and the head stand
+ on the '?' of '<?'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the PI.
+*/
+bool TQXmlSimpleReader::parsePI()
+{
+ const signed char Init = 0;
+ const signed char QmI = 1; // ? was read
+ const signed char Name = 2; // read Name
+ const signed char XMLDecl = 3; // read XMLDecl
+ const signed char Ws1 = 4; // eat ws after "xml" of XMLDecl
+ const signed char PInstr = 5; // read PI
+ const signed char Ws2 = 6; // eat ws after Name of PI
+ const signed char Version = 7; // read versionInfo
+ const signed char Ws3 = 8; // eat ws after versionInfo
+ const signed char EorSD = 9; // read EDecl or SDDecl
+ const signed char Ws4 = 10; // eat ws after EDecl or SDDecl
+ const signed char SD = 11; // read SDDecl
+ const signed char Ws5 = 12; // eat ws after SDDecl
+ const signed char ADone = 13; // almost done
+ const signed char Char = 14; // Char was read
+ const signed char Qm = 15; // Qm was read
+ const signed char Done = 16; // finished reading content
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpNameBe = 1; // NameBeginning()
+ const signed char InpGt = 2; // >
+ const signed char InpQm = 3; // ?
+ const signed char InpUnknown = 4;
+
+ static const signed char table[16][5] = {
+ /* InpWs, InpNameBe InpGt InpQm InpUnknown */
+ { -1, -1, -1, QmI, -1 }, // Init
+ { -1, Name, -1, -1, -1 }, // QmI
+ { -1, -1, -1, -1, -1 }, // Name (this state is left not through input)
+ { Ws1, -1, -1, -1, -1 }, // XMLDecl
+ { -1, Version, -1, -1, -1 }, // Ws1
+ { Ws2, -1, -1, Qm, -1 }, // PInstr
+ { Char, Char, Char, Qm, Char }, // Ws2
+ { Ws3, -1, -1, ADone, -1 }, // Version
+ { -1, EorSD, -1, ADone, -1 }, // Ws3
+ { Ws4, -1, -1, ADone, -1 }, // EorSD
+ { -1, SD, -1, ADone, -1 }, // Ws4
+ { Ws5, -1, -1, ADone, -1 }, // SD
+ { -1, -1, -1, ADone, -1 }, // Ws5
+ { -1, -1, Done, -1, -1 }, // ADone
+ { Char, Char, Char, Qm, Char }, // Char
+ { Char, Char, Done, Qm, Char }, // Qm
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parsePI (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parsePI, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Name:
+ // test what name was read and determine the next state
+ // (not very beautiful, I admit)
+ if ( name().lower() == "xml" ) {
+ if ( d->parsePI_xmldecl && name()=="xml" ) {
+ state = XMLDecl;
+ } else {
+ reportParseError( XMLERR_INVALIDNAMEFORPI );
+ return FALSE;
+ }
+ } else {
+ state = PInstr;
+ stringClear();
+ }
+ break;
+ case Version:
+ // get version (syntax like an attribute)
+ if ( name() != "version" ) {
+ reportParseError( XMLERR_VERSIONEXPECTED );
+ return FALSE;
+ }
+ d->xmlVersion = string();
+ break;
+ case EorSD:
+ // get the EDecl or SDDecl (syntax like an attribute)
+ if ( name() == "standalone" ) {
+ if ( string()=="yes" ) {
+ d->standalone = TQXmlSimpleReaderPrivate::Yes;
+ } else if ( string()=="no" ) {
+ d->standalone = TQXmlSimpleReaderPrivate::No;
+ } else {
+ reportParseError( XMLERR_WRONGVALUEFORSDECL );
+ return FALSE;
+ }
+ } else if ( name() == "encoding" ) {
+ d->encoding = string();
+ } else {
+ reportParseError( XMLERR_EDECLORSDDECLEXPECTED );
+ return FALSE;
+ }
+ break;
+ case SD:
+ if ( name() != "standalone" ) {
+ reportParseError( XMLERR_SDDECLEXPECTED );
+ return FALSE;
+ }
+ if ( string()=="yes" ) {
+ d->standalone = TQXmlSimpleReaderPrivate::Yes;
+ } else if ( string()=="no" ) {
+ d->standalone = TQXmlSimpleReaderPrivate::No;
+ } else {
+ reportParseError( XMLERR_WRONGVALUEFORSDECL );
+ return FALSE;
+ }
+ break;
+ case Qm:
+ // test if the skipping was legal
+ if ( !atEnd() && c.tqunicode() != '>' )
+ stringAddC( '?' );
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parsePI, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if (determineNameChar(c) == NameBeginning) {
+ input = InpNameBe;
+ } else if ( c.tqunicode() == '>' ) {
+ input = InpGt;
+ } else if ( c.tqunicode() == '?' ) {
+ input = InpQm;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case QmI:
+ next();
+ break;
+ case Name:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parsePI, state );
+ return FALSE;
+ }
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ case Ws4:
+ case Ws5:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parsePI, state );
+ return FALSE;
+ }
+ break;
+ case Version:
+ if ( !parseAttribute() ) {
+ parseFailed( &TQXmlSimpleReader::parsePI, state );
+ return FALSE;
+ }
+ break;
+ case EorSD:
+ if ( !parseAttribute() ) {
+ parseFailed( &TQXmlSimpleReader::parsePI, state );
+ return FALSE;
+ }
+ break;
+ case SD:
+ // get the SDDecl (syntax like an attribute)
+ if ( d->standalone != TQXmlSimpleReaderPrivate::Unknown ) {
+ // already parsed the standalone declaration
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+ if ( !parseAttribute() ) {
+ parseFailed( &TQXmlSimpleReader::parsePI, state );
+ return FALSE;
+ }
+ break;
+ case ADone:
+ next();
+ break;
+ case Char:
+ stringAddC();
+ next();
+ break;
+ case Qm:
+ // skip the '?'
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a document type definition (doctypedecl [28]).
+
+ Precondition: the beginning '<!' of the doctype is already read the head
+ stands on the 'D' of '<!DOCTYPE'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the document type definition.
+*/
+bool TQXmlSimpleReader::parseDoctype()
+{
+ const signed char Init = 0;
+ const signed char Doctype = 1; // read the doctype
+ const signed char Ws1 = 2; // eat_ws
+ const signed char Doctype2 = 3; // read the doctype, part 2
+ const signed char Ws2 = 4; // eat_ws
+ const signed char Sys = 5; // read SYSTEM or PUBLIC
+ const signed char Ws3 = 6; // eat_ws
+ const signed char MP = 7; // markupdecl or PEReference
+ const signed char MPR = 8; // same as MP, but already reported
+ const signed char PER = 9; // PERReference
+ const signed char Mup = 10; // markupdecl
+ const signed char Ws4 = 11; // eat_ws
+ const signed char MPE = 12; // end of markupdecl or PEReference
+ const signed char Done = 13;
+
+ const signed char InpWs = 0;
+ const signed char InpD = 1; // 'D'
+ const signed char InpS = 2; // 'S' or 'P'
+ const signed char InpOB = 3; // [
+ const signed char InpCB = 4; // ]
+ const signed char InpPer = 5; // %
+ const signed char InpGt = 6; // >
+ const signed char InpUnknown = 7;
+
+ static const signed char table[13][8] = {
+ /* InpWs, InpD InpS InpOB InpCB InpPer InpGt InpUnknown */
+ { -1, Doctype, -1, -1, -1, -1, -1, -1 }, // Init
+ { Ws1, -1, -1, -1, -1, -1, -1, -1 }, // Doctype
+ { -1, Doctype2, Doctype2, -1, -1, -1, -1, Doctype2 }, // Ws1
+ { Ws2, -1, Sys, MP, -1, -1, Done, -1 }, // Doctype2
+ { -1, -1, Sys, MP, -1, -1, Done, -1 }, // Ws2
+ { Ws3, -1, -1, MP, -1, -1, Done, -1 }, // Sys
+ { -1, -1, -1, MP, -1, -1, Done, -1 }, // Ws3
+ { -1, -1, -1, -1, MPE, PER, -1, Mup }, // MP
+ { -1, -1, -1, -1, MPE, PER, -1, Mup }, // MPR
+ { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // PER
+ { Ws4, -1, -1, -1, MPE, PER, -1, Mup }, // Mup
+ { -1, -1, -1, -1, MPE, PER, -1, Mup }, // Ws4
+ { -1, -1, -1, -1, -1, -1, Done, -1 } // MPE
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ d->startDTDwasReported = FALSE;
+ d->systemId = TQString::null;
+ d->publicId = TQString::null;
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseDoctype (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseDoctype, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Doctype2:
+ d->doctype = name();
+ break;
+ case MP:
+ if ( !d->startDTDwasReported && lexicalHnd ) {
+ d->startDTDwasReported = TRUE;
+ if ( !lexicalHnd->startDTD( d->doctype, d->publicId, d->systemId ) ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ state = MPR;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_ERRORPARSINGDOCTYPE );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseDoctype, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c.tqunicode() == 'D' ) {
+ input = InpD;
+ } else if ( c.tqunicode() == 'S' ) {
+ input = InpS;
+ } else if ( c.tqunicode() == 'P' ) {
+ input = InpS;
+ } else if ( c.tqunicode() == '[' ) {
+ input = InpOB;
+ } else if ( c.tqunicode() == ']' ) {
+ input = InpCB;
+ } else if ( c.tqunicode() == '%' ) {
+ input = InpPer;
+ } else if ( c.tqunicode() == '>' ) {
+ input = InpGt;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Doctype:
+ d->parseString_s = "DOCTYPE";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseDoctype, state );
+ return FALSE;
+ }
+ break;
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ case Ws4:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseDoctype, state );
+ return FALSE;
+ }
+ break;
+ case Doctype2:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseDoctype, state );
+ return FALSE;
+ }
+ break;
+ case Sys:
+ d->parseExternalID_allowPublicID = FALSE;
+ if ( !parseExternalID() ) {
+ parseFailed( &TQXmlSimpleReader::parseDoctype, state );
+ return FALSE;
+ }
+ break;
+ case MP:
+ case MPR:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseDoctype, state );
+ return FALSE;
+ }
+ break;
+ case PER:
+ d->parsePEReference_context = InDTD;
+ if ( !parsePEReference() ) {
+ parseFailed( &TQXmlSimpleReader::parseDoctype, state );
+ return FALSE;
+ }
+ break;
+ case Mup:
+ if ( !parseMarkupdecl() ) {
+ parseFailed( &TQXmlSimpleReader::parseDoctype, state );
+ return FALSE;
+ }
+ break;
+ case MPE:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseDoctype, state );
+ return FALSE;
+ }
+ break;
+ case Done:
+ if ( lexicalHnd ) {
+ if ( !d->startDTDwasReported ) {
+ d->startDTDwasReported = TRUE;
+ if ( !lexicalHnd->startDTD( d->doctype, d->publicId, d->systemId ) ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ if ( !lexicalHnd->endDTD() ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a ExternalID [75].
+
+ If allowPublicID is TRUE parse ExternalID [75] or PublicID [83].
+*/
+bool TQXmlSimpleReader::parseExternalID()
+{
+ const signed char Init = 0;
+ const signed char Sys = 1; // parse 'SYSTEM'
+ const signed char SysWS = 2; // parse the whitespace after 'SYSTEM'
+ const signed char SysSQ = 3; // parse SystemLiteral with '
+ const signed char SysSQ2 = 4; // parse SystemLiteral with '
+ const signed char SysDQ = 5; // parse SystemLiteral with "
+ const signed char SysDQ2 = 6; // parse SystemLiteral with "
+ const signed char Pub = 7; // parse 'PUBLIC'
+ const signed char PubWS = 8; // parse the whitespace after 'PUBLIC'
+ const signed char PubSQ = 9; // parse PubidLiteral with '
+ const signed char PubSQ2 = 10; // parse PubidLiteral with '
+ const signed char PubDQ = 11; // parse PubidLiteral with "
+ const signed char PubDQ2 = 12; // parse PubidLiteral with "
+ const signed char PubE = 13; // finished parsing the PubidLiteral
+ const signed char PubWS2 = 14; // parse the whitespace after the PubidLiteral
+ const signed char PDone = 15; // done if allowPublicID is TRUE
+ const signed char Done = 16;
+
+ const signed char InpSQ = 0; // '
+ const signed char InpDQ = 1; // "
+ const signed char InpS = 2; // S
+ const signed char InpP = 3; // P
+ const signed char InpWs = 4; // white space
+ const signed char InpUnknown = 5;
+
+ static const signed char table[15][6] = {
+ /* InpSQ InpDQ InpS InpP InpWs InpUnknown */
+ { -1, -1, Sys, Pub, -1, -1 }, // Init
+ { -1, -1, -1, -1, SysWS, -1 }, // Sys
+ { SysSQ, SysDQ, -1, -1, -1, -1 }, // SysWS
+ { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ
+ { Done, SysSQ2, SysSQ2, SysSQ2, SysSQ2, SysSQ2 }, // SysSQ2
+ { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ
+ { SysDQ2, Done, SysDQ2, SysDQ2, SysDQ2, SysDQ2 }, // SysDQ2
+ { -1, -1, -1, -1, PubWS, -1 }, // Pub
+ { PubSQ, PubDQ, -1, -1, -1, -1 }, // PubWS
+ { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ
+ { PubE, -1, PubSQ2, PubSQ2, PubSQ2, PubSQ2 }, // PubSQ2
+ { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ
+ { -1, PubE, PubDQ2, PubDQ2, PubDQ2, PubDQ2 }, // PubDQ2
+ { PDone, PDone, PDone, PDone, PubWS2, PDone }, // PubE
+ { SysSQ, SysDQ, PDone, PDone, PDone, PDone } // PubWS2
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ d->systemId = TQString::null;
+ d->publicId = TQString::null;
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseExternalID (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseExternalID, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case PDone:
+ if ( d->parseExternalID_allowPublicID ) {
+ d->publicId = string();
+ return TRUE;
+ } else {
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseExternalID, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c.tqunicode() == '\'' ) {
+ input = InpSQ;
+ } else if ( c.tqunicode() == '"' ) {
+ input = InpDQ;
+ } else if ( c.tqunicode() == 'S' ) {
+ input = InpS;
+ } else if ( c.tqunicode() == 'P' ) {
+ input = InpP;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Sys:
+ d->parseString_s = "SYSTEM";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseExternalID, state );
+ return FALSE;
+ }
+ break;
+ case SysWS:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseExternalID, state );
+ return FALSE;
+ }
+ break;
+ case SysSQ:
+ case SysDQ:
+ stringClear();
+ next();
+ break;
+ case SysSQ2:
+ case SysDQ2:
+ stringAddC();
+ next();
+ break;
+ case Pub:
+ d->parseString_s = "PUBLIC";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseExternalID, state );
+ return FALSE;
+ }
+ break;
+ case PubWS:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseExternalID, state );
+ return FALSE;
+ }
+ break;
+ case PubSQ:
+ case PubDQ:
+ stringClear();
+ next();
+ break;
+ case PubSQ2:
+ case PubDQ2:
+ stringAddC();
+ next();
+ break;
+ case PubE:
+ next();
+ break;
+ case PubWS2:
+ d->publicId = string();
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseExternalID, state );
+ return FALSE;
+ }
+ break;
+ case Done:
+ d->systemId = string();
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a markupdecl [29].
+*/
+bool TQXmlSimpleReader::parseMarkupdecl()
+{
+ const signed char Init = 0;
+ const signed char Lt = 1; // < was read
+ const signed char Em = 2; // ! was read
+ const signed char CE = 3; // E was read
+ const signed char Qm = 4; // ? was read
+ const signed char Dash = 5; // - was read
+ const signed char CA = 6; // A was read
+ const signed char CEL = 7; // EL was read
+ const signed char CEN = 8; // EN was read
+ const signed char CN = 9; // N was read
+ const signed char Done = 10;
+
+ const signed char InpLt = 0; // <
+ const signed char InpQm = 1; // ?
+ const signed char InpEm = 2; // !
+ const signed char InpDash = 3; // -
+ const signed char InpA = 4; // A
+ const signed char InpE = 5; // E
+ const signed char InpL = 6; // L
+ const signed char InpN = 7; // N
+ const signed char InpUnknown = 8;
+
+ static const signed char table[4][9] = {
+ /* InpLt InpQm InpEm InpDash InpA InpE InpL InpN InpUnknown */
+ { Lt, -1, -1, -1, -1, -1, -1, -1, -1 }, // Init
+ { -1, Qm, Em, -1, -1, -1, -1, -1, -1 }, // Lt
+ { -1, -1, -1, Dash, CA, CE, -1, CN, -1 }, // Em
+ { -1, -1, -1, -1, -1, -1, CEL, CEN, -1 } // CE
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseMarkupdecl (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseMarkupdecl, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Qm:
+ if ( contentHnd ) {
+ if ( !contentHnd->processingInstruction(name(),string()) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ return TRUE;
+ case Dash:
+ if ( lexicalHnd ) {
+ if ( !lexicalHnd->comment( string() ) ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ return TRUE;
+ case CA:
+ return TRUE;
+ case CEL:
+ return TRUE;
+ case CEN:
+ return TRUE;
+ case CN:
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_LETTEREXPECTED );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseMarkupdecl, state );
+ return FALSE;
+ }
+ if ( c.tqunicode() == '<' ) {
+ input = InpLt;
+ } else if ( c.tqunicode() == '?' ) {
+ input = InpQm;
+ } else if ( c.tqunicode() == '!' ) {
+ input = InpEm;
+ } else if ( c.tqunicode() == '-' ) {
+ input = InpDash;
+ } else if ( c.tqunicode() == 'A' ) {
+ input = InpA;
+ } else if ( c.tqunicode() == 'E' ) {
+ input = InpE;
+ } else if ( c.tqunicode() == 'L' ) {
+ input = InpL;
+ } else if ( c.tqunicode() == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Lt:
+ next();
+ break;
+ case Em:
+ next();
+ break;
+ case CE:
+ next();
+ break;
+ case Qm:
+ d->parsePI_xmldecl = FALSE;
+ if ( !parsePI() ) {
+ parseFailed( &TQXmlSimpleReader::parseMarkupdecl, state );
+ return FALSE;
+ }
+ break;
+ case Dash:
+ if ( !parseComment() ) {
+ parseFailed( &TQXmlSimpleReader::parseMarkupdecl, state );
+ return FALSE;
+ }
+ break;
+ case CA:
+ if ( !parseAttlistDecl() ) {
+ parseFailed( &TQXmlSimpleReader::parseMarkupdecl, state );
+ return FALSE;
+ }
+ break;
+ case CEL:
+ if ( !parseElementDecl() ) {
+ parseFailed( &TQXmlSimpleReader::parseMarkupdecl, state );
+ return FALSE;
+ }
+ break;
+ case CEN:
+ if ( !parseEntityDecl() ) {
+ parseFailed( &TQXmlSimpleReader::parseMarkupdecl, state );
+ return FALSE;
+ }
+ break;
+ case CN:
+ if ( !parseNotationDecl() ) {
+ parseFailed( &TQXmlSimpleReader::parseMarkupdecl, state );
+ return FALSE;
+ }
+ break;
+ }
+ }
+}
+
+/*
+ Parse a PEReference [69]
+*/
+bool TQXmlSimpleReader::parsePEReference()
+{
+ const signed char Init = 0;
+ const signed char Next = 1;
+ const signed char Name = 2;
+ const signed char NameR = 3; // same as Name, but already reported
+ const signed char Done = 4;
+
+ const signed char InpSemi = 0; // ;
+ const signed char InpPer = 1; // %
+ const signed char InpUnknown = 2;
+
+ static const signed char table[4][3] = {
+ /* InpSemi InpPer InpUnknown */
+ { -1, Next, -1 }, // Init
+ { -1, -1, Name }, // Next
+ { Done, -1, -1 }, // Name
+ { Done, -1, -1 } // NameR
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parsePEReference (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parsePEReference, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Name:
+ {
+ bool skipIt = TRUE;
+ TQString xmlRefString;
+
+ TQMap<TQString,TQString>::Iterator it;
+ it = d->parameterEntities.tqfind( ref() );
+ if ( it != d->parameterEntities.end() ) {
+ skipIt = FALSE;
+ xmlRefString = it.data();
+ } else if ( entityRes ) {
+ TQMap<TQString,TQXmlSimpleReaderPrivate::ExternParameterEntity>::Iterator it2;
+ it2 = d->externParameterEntities.tqfind( ref() );
+ TQXmlInputSource *ret = 0;
+ if ( it2 != d->externParameterEntities.end() ) {
+ if ( !entityRes->resolveEntity( it2.data().publicId, it2.data().systemId, ret ) ) {
+ delete ret;
+ reportParseError( entityRes->errorString() );
+ return FALSE;
+ }
+ if ( ret ) {
+ xmlRefString = ret->data();
+ delete ret;
+ if ( !stripTextDecl( xmlRefString ) ) {
+ reportParseError( XMLERR_ERRORINTEXTDECL );
+ return FALSE;
+ }
+ skipIt = FALSE;
+ }
+ }
+ }
+
+ if ( skipIt ) {
+ if ( contentHnd ) {
+ if ( !contentHnd->skippedEntity( TQString("%") + ref() ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE;
+ }
+ }
+ } else {
+ if ( d->parsePEReference_context == InEntityValue ) {
+ // Included in literal
+ if ( !insertXmlRef( xmlRefString, ref(), TRUE ) )
+ return FALSE;
+ } else if ( d->parsePEReference_context == InDTD ) {
+ // Included as PE
+ if ( !insertXmlRef( TQString(" ")+xmlRefString+TQString(" "), ref(), FALSE ) )
+ return FALSE;
+ }
+ }
+ }
+ state = NameR;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_LETTEREXPECTED );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parsePEReference, state );
+ return FALSE;
+ }
+ if ( c.tqunicode() == ';' ) {
+ input = InpSemi;
+ } else if ( c.tqunicode() == '%' ) {
+ input = InpPer;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Next:
+ next();
+ break;
+ case Name:
+ case NameR:
+ d->parseName_useRef = TRUE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parsePEReference, state );
+ return FALSE;
+ }
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a AttlistDecl [52].
+
+ Precondition: the beginning '<!' is already read and the head
+ stands on the 'A' of '<!ATTLIST'
+*/
+bool TQXmlSimpleReader::parseAttlistDecl()
+{
+ const signed char Init = 0;
+ const signed char Attlist = 1; // parse the string "ATTLIST"
+ const signed char Ws = 2; // whitespace read
+ const signed char Name = 3; // parse name
+ const signed char Ws1 = 4; // whitespace read
+ const signed char Attdef = 5; // parse the AttDef
+ const signed char Ws2 = 6; // whitespace read
+ const signed char Atttype = 7; // parse the AttType
+ const signed char Ws3 = 8; // whitespace read
+ const signed char DDecH = 9; // DefaultDecl with #
+ const signed char DefReq = 10; // parse the string "RETQUIRED"
+ const signed char DefImp = 11; // parse the string "IMPLIED"
+ const signed char DefFix = 12; // parse the string "FIXED"
+ const signed char Attval = 13; // parse the AttValue
+ const signed char Ws4 = 14; // whitespace read
+ const signed char Done = 15;
+
+ const signed char InpWs = 0; // white space
+ const signed char InpGt = 1; // >
+ const signed char InpHash = 2; // #
+ const signed char InpA = 3; // A
+ const signed char InpI = 4; // I
+ const signed char InpF = 5; // F
+ const signed char InpR = 6; // R
+ const signed char InpUnknown = 7;
+
+ static const signed char table[15][8] = {
+ /* InpWs InpGt InpHash InpA InpI InpF InpR InpUnknown */
+ { -1, -1, -1, Attlist, -1, -1, -1, -1 }, // Init
+ { Ws, -1, -1, -1, -1, -1, -1, -1 }, // Attlist
+ { -1, -1, -1, Name, Name, Name, Name, Name }, // Ws
+ { Ws1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Name
+ { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1, -1, -1 }, // Attdef
+ { -1, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype, Atttype }, // Ws2
+ { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // Attype
+ { -1, Attval, DDecH, Attval, Attval, Attval, Attval, Attval }, // Ws3
+ { -1, -1, -1, -1, DefImp, DefFix, DefReq, -1 }, // DDecH
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefReq
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // DefImp
+ { Ws3, -1, -1, -1, -1, -1, -1, -1 }, // DefFix
+ { Ws4, Ws4, -1, -1, -1, -1, -1, -1 }, // Attval
+ { -1, Done, Attdef, Attdef, Attdef, Attdef, Attdef, Attdef } // Ws4
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseAttlistDecl (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Name:
+ d->attDeclEName = name();
+ break;
+ case Attdef:
+ d->attDeclAName = name();
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_LETTEREXPECTED );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c.tqunicode() == '>' ) {
+ input = InpGt;
+ } else if ( c.tqunicode() == '#' ) {
+ input = InpHash;
+ } else if ( c.tqunicode() == 'A' ) {
+ input = InpA;
+ } else if ( c.tqunicode() == 'I' ) {
+ input = InpI;
+ } else if ( c.tqunicode() == 'F' ) {
+ input = InpF;
+ } else if ( c.tqunicode() == 'R' ) {
+ input = InpR;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Attlist:
+ d->parseString_s = "ATTLIST";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws:
+ case Ws1:
+ case Ws2:
+ case Ws3:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ break;
+ case Name:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ break;
+ case Attdef:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ break;
+ case Atttype:
+ if ( !parseAttType() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ break;
+ case DDecH:
+ next();
+ break;
+ case DefReq:
+ d->parseString_s = "RETQUIRED";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ break;
+ case DefImp:
+ d->parseString_s = "IMPLIED";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ break;
+ case DefFix:
+ d->parseString_s = "FIXED";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ break;
+ case Attval:
+ if ( !parseAttValue() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws4:
+ if ( declHnd ) {
+ // ### not all values are computed yet...
+ if ( !declHnd->attributeDecl( d->attDeclEName, d->attDeclAName, "", "", "" ) ) {
+ reportParseError( declHnd->errorString() );
+ return FALSE;
+ }
+ }
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttlistDecl, state );
+ return FALSE;
+ }
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a AttType [54]
+*/
+bool TQXmlSimpleReader::parseAttType()
+{
+ const signed char Init = 0;
+ const signed char ST = 1; // StringType
+ const signed char TTI = 2; // TokenizedType starting with 'I'
+ const signed char TTI2 = 3; // TokenizedType helpstate
+ const signed char TTI3 = 4; // TokenizedType helpstate
+ const signed char TTE = 5; // TokenizedType starting with 'E'
+ const signed char TTEY = 6; // TokenizedType starting with 'ENTITY'
+ const signed char TTEI = 7; // TokenizedType starting with 'ENTITI'
+ const signed char N = 8; // N read (TokenizedType or Notation)
+ const signed char TTNM = 9; // TokenizedType starting with 'NM'
+ const signed char TTNM2 = 10; // TokenizedType helpstate
+ const signed char NO = 11; // Notation
+ const signed char NO2 = 12; // Notation helpstate
+ const signed char NO3 = 13; // Notation helpstate
+ const signed char NOName = 14; // Notation, read name
+ const signed char NO4 = 15; // Notation helpstate
+ const signed char EN = 16; // Enumeration
+ const signed char ENNmt = 17; // Enumeration, read Nmtoken
+ const signed char EN2 = 18; // Enumeration helpstate
+ const signed char ADone = 19; // almost done (make next and accept)
+ const signed char Done = 20;
+
+ const signed char InpWs = 0; // whitespace
+ const signed char InpOp = 1; // (
+ const signed char InpCp = 2; // )
+ const signed char InpPipe = 3; // |
+ const signed char InpC = 4; // C
+ const signed char InpE = 5; // E
+ const signed char InpI = 6; // I
+ const signed char InpM = 7; // M
+ const signed char InpN = 8; // N
+ const signed char InpO = 9; // O
+ const signed char InpR = 10; // R
+ const signed char InpS = 11; // S
+ const signed char InpY = 12; // Y
+ const signed char InpUnknown = 13;
+
+ static const signed char table[19][14] = {
+ /* InpWs InpOp InpCp InpPipe InpC InpE InpI InpM InpN InpO InpR InpS InpY InpUnknown */
+ { -1, EN, -1, -1, ST, TTE, TTI, -1, N, -1, -1, -1, -1, -1 }, // Init
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // ST
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI2, Done, Done, Done }, // TTI
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTI3, Done, Done }, // TTI2
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTI3
+ { -1, -1, -1, -1, -1, -1, TTEI, -1, -1, -1, -1, -1, TTEY, -1 }, // TTE
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEY
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTEI
+ { -1, -1, -1, -1, -1, -1, -1, TTNM, -1, NO, -1, -1, -1, -1 }, // N
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, TTNM2, Done, Done }, // TTNM
+ { Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done, Done }, // TTNM2
+ { NO2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO
+ { -1, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO2
+ { NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName, NOName }, // NO3
+ { NO4, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NOName
+ { -1, -1, ADone, NO3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // NO4
+ { -1, -1, ENNmt, -1, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt, ENNmt }, // EN
+ { EN2, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // ENNmt
+ { -1, -1, ADone, EN, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // EN2
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseAttType (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case ADone:
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_LETTEREXPECTED );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c.tqunicode() == '(' ) {
+ input = InpOp;
+ } else if ( c.tqunicode() == ')' ) {
+ input = InpCp;
+ } else if ( c.tqunicode() == '|' ) {
+ input = InpPipe;
+ } else if ( c.tqunicode() == 'C' ) {
+ input = InpC;
+ } else if ( c.tqunicode() == 'E' ) {
+ input = InpE;
+ } else if ( c.tqunicode() == 'I' ) {
+ input = InpI;
+ } else if ( c.tqunicode() == 'M' ) {
+ input = InpM;
+ } else if ( c.tqunicode() == 'N' ) {
+ input = InpN;
+ } else if ( c.tqunicode() == 'O' ) {
+ input = InpO;
+ } else if ( c.tqunicode() == 'R' ) {
+ input = InpR;
+ } else if ( c.tqunicode() == 'S' ) {
+ input = InpS;
+ } else if ( c.tqunicode() == 'Y' ) {
+ input = InpY;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case ST:
+ d->parseString_s = "CDATA";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case TTI:
+ d->parseString_s = "ID";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case TTI2:
+ d->parseString_s = "REF";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case TTI3:
+ next(); // S
+ break;
+ case TTE:
+ d->parseString_s = "ENTIT";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case TTEY:
+ next(); // Y
+ break;
+ case TTEI:
+ d->parseString_s = "IES";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case N:
+ next(); // N
+ break;
+ case TTNM:
+ d->parseString_s = "MTOKEN";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case TTNM2:
+ next(); // S
+ break;
+ case NO:
+ d->parseString_s = "OTATION";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case NO2:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case NO3:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case NOName:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case NO4:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case EN:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case ENNmt:
+ if ( !parseNmtoken() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case EN2:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttType, state );
+ return FALSE;
+ }
+ break;
+ case ADone:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a AttValue [10]
+
+ Precondition: the head stands on the beginning " or '
+
+ If this function was successful, the head stands on the first
+ character after the closing " or ' and the value of the attribute
+ is in string().
+*/
+bool TQXmlSimpleReader::parseAttValue()
+{
+ const signed char Init = 0;
+ const signed char Dq = 1; // double quotes were read
+ const signed char DqRef = 2; // read references in double quotes
+ const signed char DqC = 3; // signed character read in double quotes
+ const signed char Sq = 4; // single quotes were read
+ const signed char SqRef = 5; // read references in single quotes
+ const signed char SqC = 6; // signed character read in single quotes
+ const signed char Done = 7;
+
+ const signed char InpDq = 0; // "
+ const signed char InpSq = 1; // '
+ const signed char InpAmp = 2; // &
+ const signed char InpLt = 3; // <
+ const signed char InpUnknown = 4;
+
+ static const signed char table[7][5] = {
+ /* InpDq InpSq InpAmp InpLt InpUnknown */
+ { Dq, Sq, -1, -1, -1 }, // Init
+ { Done, DqC, DqRef, -1, DqC }, // Dq
+ { Done, DqC, DqRef, -1, DqC }, // DqRef
+ { Done, DqC, DqRef, -1, DqC }, // DqC
+ { SqC, Done, SqRef, -1, SqC }, // Sq
+ { SqC, Done, SqRef, -1, SqC }, // SqRef
+ { SqC, Done, SqRef, -1, SqC } // SqRef
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseAttValue (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttValue, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseAttValue, state );
+ return FALSE;
+ }
+ if ( c.tqunicode() == '"' ) {
+ input = InpDq;
+ } else if ( c.tqunicode() == '\'' ) {
+ input = InpSq;
+ } else if ( c.tqunicode() == '&' ) {
+ input = InpAmp;
+ } else if ( c.tqunicode() == '<' ) {
+ input = InpLt;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Dq:
+ case Sq:
+ stringClear();
+ next();
+ break;
+ case DqRef:
+ case SqRef:
+ d->parseReference_context = InAttributeValue;
+ if ( !parseReference() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttValue, state );
+ return FALSE;
+ }
+ break;
+ case DqC:
+ case SqC:
+ stringAddC();
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a elementdecl [45].
+
+ Precondition: the beginning '<!E' is already read and the head
+ stands on the 'L' of '<!ELEMENT'
+*/
+bool TQXmlSimpleReader::parseElementDecl()
+{
+ const signed char Init = 0;
+ const signed char Elem = 1; // parse the beginning string
+ const signed char Ws1 = 2; // whitespace required
+ const signed char Nam = 3; // parse Name
+ const signed char Ws2 = 4; // whitespace required
+ const signed char Empty = 5; // read EMPTY
+ const signed char Any = 6; // read ANY
+ const signed char Cont = 7; // read contentspec (except ANY or EMPTY)
+ const signed char Mix = 8; // read Mixed
+ const signed char Mix2 = 9; //
+ const signed char Mix3 = 10; //
+ const signed char MixN1 = 11; //
+ const signed char MixN2 = 12; //
+ const signed char MixN3 = 13; //
+ const signed char MixN4 = 14; //
+ const signed char Cp = 15; // parse cp
+ const signed char Cp2 = 16; //
+ const signed char WsD = 17; // eat whitespace before Done
+ const signed char Done = 18;
+
+ const signed char InpWs = 0;
+ const signed char InpGt = 1; // >
+ const signed char InpPipe = 2; // |
+ const signed char InpOp = 3; // (
+ const signed char InpCp = 4; // )
+ const signed char InpHash = 5; // #
+ const signed char InpQm = 6; // ?
+ const signed char InpAst = 7; // *
+ const signed char InpPlus = 8; // +
+ const signed char InpA = 9; // A
+ const signed char InpE = 10; // E
+ const signed char InpL = 11; // L
+ const signed char InpUnknown = 12;
+
+ static const signed char table[18][13] = {
+ /* InpWs InpGt InpPipe InpOp InpCp InpHash InpQm InpAst InpPlus InpA InpE InpL InpUnknown */
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, Elem, -1 }, // Init
+ { Ws1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Elem
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, Nam, Nam, Nam, Nam }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Nam
+ { -1, -1, -1, Cont, -1, -1, -1, -1, -1, Any, Empty, -1, -1 }, // Ws2
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Empty
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Any
+ { -1, -1, -1, Cp, Cp, Mix, -1, -1, -1, Cp, Cp, Cp, Cp }, // Cont
+ { Mix2, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix
+ { -1, -1, MixN1, -1, Mix3, -1, -1, -1, -1, -1, -1, -1, -1 }, // Mix2
+ { WsD, Done, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // Mix3
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, MixN2, MixN2, MixN2, MixN2 }, // MixN1
+ { MixN3, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN2
+ { -1, -1, MixN1, -1, MixN4, -1, -1, -1, -1, -1, -1, -1, -1 }, // MixN3
+ { -1, -1, -1, -1, -1, -1, -1, WsD, -1, -1, -1, -1, -1 }, // MixN4
+ { WsD, Done, -1, -1, -1, -1, Cp2, Cp2, Cp2, -1, -1, -1, -1 }, // Cp
+ { WsD, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, // Cp2
+ { -1, Done, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } // WsD
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseElementDecl (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c.tqunicode() == '>' ) {
+ input = InpGt;
+ } else if ( c.tqunicode() == '|' ) {
+ input = InpPipe;
+ } else if ( c.tqunicode() == '(' ) {
+ input = InpOp;
+ } else if ( c.tqunicode() == ')' ) {
+ input = InpCp;
+ } else if ( c.tqunicode() == '#' ) {
+ input = InpHash;
+ } else if ( c.tqunicode() == '?' ) {
+ input = InpQm;
+ } else if ( c.tqunicode() == '*' ) {
+ input = InpAst;
+ } else if ( c.tqunicode() == '+' ) {
+ input = InpPlus;
+ } else if ( c.tqunicode() == 'A' ) {
+ input = InpA;
+ } else if ( c.tqunicode() == 'E' ) {
+ input = InpE;
+ } else if ( c.tqunicode() == 'L' ) {
+ input = InpL;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Elem:
+ d->parseString_s = "LEMENT";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws1:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Nam:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws2:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Empty:
+ d->parseString_s = "EMPTY";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Any:
+ d->parseString_s = "ANY";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Cont:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Mix:
+ d->parseString_s = "#PCDATA";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Mix2:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Mix3:
+ next();
+ break;
+ case MixN1:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case MixN2:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case MixN3:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case MixN4:
+ next();
+ break;
+ case Cp:
+ if ( !parseChoiceSeq() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Cp2:
+ next();
+ break;
+ case WsD:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseElementDecl, state );
+ return FALSE;
+ }
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a NotationDecl [82].
+
+ Precondition: the beginning '<!' is already read and the head
+ stands on the 'N' of '<!NOTATION'
+*/
+bool TQXmlSimpleReader::parseNotationDecl()
+{
+ const signed char Init = 0;
+ const signed char Not = 1; // read NOTATION
+ const signed char Ws1 = 2; // eat whitespaces
+ const signed char Nam = 3; // read Name
+ const signed char Ws2 = 4; // eat whitespaces
+ const signed char ExtID = 5; // parse ExternalID
+ const signed char ExtIDR = 6; // same as ExtID, but already reported
+ const signed char Ws3 = 7; // eat whitespaces
+ const signed char Done = 8;
+
+ const signed char InpWs = 0;
+ const signed char InpGt = 1; // >
+ const signed char InpN = 2; // N
+ const signed char InpUnknown = 3;
+
+ static const signed char table[8][4] = {
+ /* InpWs InpGt InpN InpUnknown */
+ { -1, -1, Not, -1 }, // Init
+ { Ws1, -1, -1, -1 }, // Not
+ { -1, -1, Nam, Nam }, // Ws1
+ { Ws2, Done, -1, -1 }, // Nam
+ { -1, Done, ExtID, ExtID }, // Ws2
+ { Ws3, Done, -1, -1 }, // ExtID
+ { Ws3, Done, -1, -1 }, // ExtIDR
+ { -1, Done, -1, -1 } // Ws3
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseNotationDecl (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseNotationDecl, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case ExtID:
+ // call the handler
+ if ( dtdHnd ) {
+ if ( !dtdHnd->notationDecl( name(), d->publicId, d->systemId ) ) {
+ reportParseError( dtdHnd->errorString() );
+ return FALSE;
+ }
+ }
+ state = ExtIDR;
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseNotationDecl, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c.tqunicode() == '>' ) {
+ input = InpGt;
+ } else if ( c.tqunicode() == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Not:
+ d->parseString_s = "NOTATION";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseNotationDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws1:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseNotationDecl, state );
+ return FALSE;
+ }
+ break;
+ case Nam:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseNotationDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws2:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseNotationDecl, state );
+ return FALSE;
+ }
+ break;
+ case ExtID:
+ case ExtIDR:
+ d->parseExternalID_allowPublicID = TRUE;
+ if ( !parseExternalID() ) {
+ parseFailed( &TQXmlSimpleReader::parseNotationDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws3:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseNotationDecl, state );
+ return FALSE;
+ }
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse choice [49] or seq [50].
+
+ Precondition: the beginning '('S? is already read and the head
+ stands on the first non-whitespace character after it.
+*/
+bool TQXmlSimpleReader::parseChoiceSeq()
+{
+ const signed char Init = 0;
+ const signed char Ws1 = 1; // eat whitespace
+ const signed char CorS = 2; // choice or set
+ const signed char Ws2 = 3; // eat whitespace
+ const signed char More = 4; // more cp to read
+ const signed char Name = 5; // read name
+ const signed char Done = 6; //
+
+ const signed char InpWs = 0; // S
+ const signed char InpOp = 1; // (
+ const signed char InpCp = 2; // )
+ const signed char InpQm = 3; // ?
+ const signed char InpAst = 4; // *
+ const signed char InpPlus = 5; // +
+ const signed char InpPipe = 6; // |
+ const signed char InpComm = 7; // ,
+ const signed char InpUnknown = 8;
+
+ static const signed char table[6][9] = {
+ /* InpWs InpOp InpCp InpQm InpAst InpPlus InpPipe InpComm InpUnknown */
+ { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // Init
+ { -1, CorS, -1, -1, -1, -1, -1, -1, CorS }, // Ws1
+ { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 }, // CorS
+ { -1, -1, Done, -1, -1, -1, More, More, -1 }, // Ws2
+ { -1, Ws1, -1, -1, -1, -1, -1, -1, Name }, // More (same as Init)
+ { Ws2, -1, Done, Ws2, Ws2, Ws2, More, More, -1 } // Name (same as CorS)
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseChoiceSeq (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseChoiceSeq, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseChoiceSeq, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c.tqunicode() == '(' ) {
+ input = InpOp;
+ } else if ( c.tqunicode() == ')' ) {
+ input = InpCp;
+ } else if ( c.tqunicode() == '?' ) {
+ input = InpQm;
+ } else if ( c.tqunicode() == '*' ) {
+ input = InpAst;
+ } else if ( c.tqunicode() == '+' ) {
+ input = InpPlus;
+ } else if ( c.tqunicode() == '|' ) {
+ input = InpPipe;
+ } else if ( c.tqunicode() == ',' ) {
+ input = InpComm;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Ws1:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseChoiceSeq, state );
+ return FALSE;
+ }
+ break;
+ case CorS:
+ if ( !parseChoiceSeq() ) {
+ parseFailed( &TQXmlSimpleReader::parseChoiceSeq, state );
+ return FALSE;
+ }
+ break;
+ case Ws2:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseChoiceSeq, state );
+ return FALSE;
+ }
+ break;
+ case More:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseChoiceSeq, state );
+ return FALSE;
+ }
+ break;
+ case Name:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseChoiceSeq, state );
+ return FALSE;
+ }
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a EntityDecl [70].
+
+ Precondition: the beginning '<!E' is already read and the head
+ stand on the 'N' of '<!ENTITY'
+*/
+bool TQXmlSimpleReader::parseEntityDecl()
+{
+ const signed char Init = 0;
+ const signed char Ent = 1; // parse "ENTITY"
+ const signed char Ws1 = 2; // white space read
+ const signed char Name = 3; // parse name
+ const signed char Ws2 = 4; // white space read
+ const signed char EValue = 5; // parse entity value
+ const signed char EValueR = 6; // same as EValue, but already reported
+ const signed char ExtID = 7; // parse ExternalID
+ const signed char Ws3 = 8; // white space read
+ const signed char Ndata = 9; // parse "NDATA"
+ const signed char Ws4 = 10; // white space read
+ const signed char NNam = 11; // parse name
+ const signed char NNamR = 12; // same as NNam, but already reported
+ const signed char PEDec = 13; // parse PEDecl
+ const signed char Ws6 = 14; // white space read
+ const signed char PENam = 15; // parse name
+ const signed char Ws7 = 16; // white space read
+ const signed char PEVal = 17; // parse entity value
+ const signed char PEValR = 18; // same as PEVal, but already reported
+ const signed char PEEID = 19; // parse ExternalID
+ const signed char PEEIDR = 20; // same as PEEID, but already reported
+ const signed char WsE = 21; // white space read
+ const signed char Done = 22;
+ const signed char EDDone = 23; // done, but also report an external, unparsed entity decl
+
+ const signed char InpWs = 0; // white space
+ const signed char InpPer = 1; // %
+ const signed char InpQuot = 2; // " or '
+ const signed char InpGt = 3; // >
+ const signed char InpN = 4; // N
+ const signed char InpUnknown = 5;
+
+ static const signed char table[22][6] = {
+ /* InpWs InpPer InpQuot InpGt InpN InpUnknown */
+ { -1, -1, -1, -1, Ent, -1 }, // Init
+ { Ws1, -1, -1, -1, -1, -1 }, // Ent
+ { -1, PEDec, -1, -1, Name, Name }, // Ws1
+ { Ws2, -1, -1, -1, -1, -1 }, // Name
+ { -1, -1, EValue, -1, -1, ExtID }, // Ws2
+ { WsE, -1, -1, Done, -1, -1 }, // EValue
+ { WsE, -1, -1, Done, -1, -1 }, // EValueR
+ { Ws3, -1, -1, EDDone,-1, -1 }, // ExtID
+ { -1, -1, -1, EDDone,Ndata, -1 }, // Ws3
+ { Ws4, -1, -1, -1, -1, -1 }, // Ndata
+ { -1, -1, -1, -1, NNam, NNam }, // Ws4
+ { WsE, -1, -1, Done, -1, -1 }, // NNam
+ { WsE, -1, -1, Done, -1, -1 }, // NNamR
+ { Ws6, -1, -1, -1, -1, -1 }, // PEDec
+ { -1, -1, -1, -1, PENam, PENam }, // Ws6
+ { Ws7, -1, -1, -1, -1, -1 }, // PENam
+ { -1, -1, PEVal, -1, -1, PEEID }, // Ws7
+ { WsE, -1, -1, Done, -1, -1 }, // PEVal
+ { WsE, -1, -1, Done, -1, -1 }, // PEValR
+ { WsE, -1, -1, Done, -1, -1 }, // PEEID
+ { WsE, -1, -1, Done, -1, -1 }, // PEEIDR
+ { -1, -1, -1, Done, -1, -1 } // WsE
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseEntityDecl (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case EValue:
+ if ( !entityExist( name() ) ) {
+ d->entities.insert( name(), string() );
+ if ( declHnd ) {
+ if ( !declHnd->internalEntityDecl( name(), string() ) ) {
+ reportParseError( declHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ state = EValueR;
+ break;
+ case NNam:
+ if ( !entityExist( name() ) ) {
+ d->externEntities.insert( name(), TQXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, ref() ) );
+ if ( dtdHnd ) {
+ if ( !dtdHnd->unparsedEntityDecl( name(), d->publicId, d->systemId, ref() ) ) {
+ reportParseError( declHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ state = NNamR;
+ break;
+ case PEVal:
+ if ( !entityExist( name() ) ) {
+ d->parameterEntities.insert( name(), string() );
+ if ( declHnd ) {
+ if ( !declHnd->internalEntityDecl( TQString("%")+name(), string() ) ) {
+ reportParseError( declHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ state = PEValR;
+ break;
+ case PEEID:
+ if ( !entityExist( name() ) ) {
+ d->externParameterEntities.insert( name(), TQXmlSimpleReaderPrivate::ExternParameterEntity( d->publicId, d->systemId ) );
+ if ( declHnd ) {
+ if ( !declHnd->externalEntityDecl( TQString("%")+name(), d->publicId, d->systemId ) ) {
+ reportParseError( declHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ state = PEEIDR;
+ break;
+ case EDDone:
+ if ( !entityExist( name() ) ) {
+ d->externEntities.insert( name(), TQXmlSimpleReaderPrivate::ExternEntity( d->publicId, d->systemId, TQString::null ) );
+ if ( declHnd ) {
+ if ( !declHnd->externalEntityDecl( name(), d->publicId, d->systemId ) ) {
+ reportParseError( declHnd->errorString() );
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_LETTEREXPECTED );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ if ( is_S(c) ) {
+ input = InpWs;
+ } else if ( c.tqunicode() == '%' ) {
+ input = InpPer;
+ } else if ( c.tqunicode() == '"' || c.tqunicode() == '\'' ) {
+ input = InpQuot;
+ } else if ( c.tqunicode() == '>' ) {
+ input = InpGt;
+ } else if ( c.tqunicode() == 'N' ) {
+ input = InpN;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Ent:
+ d->parseString_s = "NTITY";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws1:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case Name:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws2:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case EValue:
+ case EValueR:
+ if ( !parseEntityValue() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case ExtID:
+ d->parseExternalID_allowPublicID = FALSE;
+ if ( !parseExternalID() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws3:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ndata:
+ d->parseString_s = "NDATA";
+ if ( !parseString() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws4:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case NNam:
+ case NNamR:
+ d->parseName_useRef = TRUE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case PEDec:
+ next();
+ break;
+ case Ws6:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case PENam:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case Ws7:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case PEVal:
+ case PEValR:
+ if ( !parseEntityValue() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case PEEID:
+ case PEEIDR:
+ d->parseExternalID_allowPublicID = FALSE;
+ if ( !parseExternalID() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case WsE:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityDecl, state );
+ return FALSE;
+ }
+ break;
+ case EDDone:
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a EntityValue [9]
+*/
+bool TQXmlSimpleReader::parseEntityValue()
+{
+ const signed char Init = 0;
+ const signed char Dq = 1; // EntityValue is double quoted
+ const signed char DqC = 2; // signed character
+ const signed char DqPER = 3; // PERefence
+ const signed char DqRef = 4; // Reference
+ const signed char Sq = 5; // EntityValue is double quoted
+ const signed char SqC = 6; // signed character
+ const signed char SqPER = 7; // PERefence
+ const signed char SqRef = 8; // Reference
+ const signed char Done = 9;
+
+ const signed char InpDq = 0; // "
+ const signed char InpSq = 1; // '
+ const signed char InpAmp = 2; // &
+ const signed char InpPer = 3; // %
+ const signed char InpUnknown = 4;
+
+ static const signed char table[9][5] = {
+ /* InpDq InpSq InpAmp InpPer InpUnknown */
+ { Dq, Sq, -1, -1, -1 }, // Init
+ { Done, DqC, DqRef, DqPER, DqC }, // Dq
+ { Done, DqC, DqRef, DqPER, DqC }, // DqC
+ { Done, DqC, DqRef, DqPER, DqC }, // DqPER
+ { Done, DqC, DqRef, DqPER, DqC }, // DqRef
+ { SqC, Done, SqRef, SqPER, SqC }, // Sq
+ { SqC, Done, SqRef, SqPER, SqC }, // SqC
+ { SqC, Done, SqRef, SqPER, SqC }, // SqPER
+ { SqC, Done, SqRef, SqPER, SqC } // SqRef
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseEntityValue (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityValue, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_LETTEREXPECTED );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseEntityValue, state );
+ return FALSE;
+ }
+ if ( c.tqunicode() == '"' ) {
+ input = InpDq;
+ } else if ( c.tqunicode() == '\'' ) {
+ input = InpSq;
+ } else if ( c.tqunicode() == '&' ) {
+ input = InpAmp;
+ } else if ( c.tqunicode() == '%' ) {
+ input = InpPer;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Dq:
+ case Sq:
+ stringClear();
+ next();
+ break;
+ case DqC:
+ case SqC:
+ stringAddC();
+ next();
+ break;
+ case DqPER:
+ case SqPER:
+ d->parsePEReference_context = InEntityValue;
+ if ( !parsePEReference() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityValue, state );
+ return FALSE;
+ }
+ break;
+ case DqRef:
+ case SqRef:
+ d->parseReference_context = InEntityValue;
+ if ( !parseReference() ) {
+ parseFailed( &TQXmlSimpleReader::parseEntityValue, state );
+ return FALSE;
+ }
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a comment [15].
+
+ Precondition: the beginning '<!' of the comment is already read and the head
+ stands on the first '-' of '<!--'.
+
+ If this funktion was successful, the head-position is on the first
+ character after the comment.
+*/
+bool TQXmlSimpleReader::parseComment()
+{
+ const signed char Init = 0;
+ const signed char Dash1 = 1; // the first dash was read
+ const signed char Dash2 = 2; // the second dash was read
+ const signed char Com = 3; // read comment
+ const signed char Com2 = 4; // read comment (help state)
+ const signed char ComE = 5; // finished reading comment
+ const signed char Done = 6;
+
+ const signed char InpDash = 0; // -
+ const signed char InpGt = 1; // >
+ const signed char InpUnknown = 2;
+
+ static const signed char table[6][3] = {
+ /* InpDash InpGt InpUnknown */
+ { Dash1, -1, -1 }, // Init
+ { Dash2, -1, -1 }, // Dash1
+ { Com2, Com, Com }, // Dash2
+ { Com2, Com, Com }, // Com
+ { ComE, Com, Com }, // Com2
+ { -1, Done, -1 } // ComE
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseComment (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseComment, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Dash2:
+ stringClear();
+ break;
+ case Com2:
+ // if next character is not a dash than don't skip it
+ if ( !atEnd() && c.tqunicode() != '-' )
+ stringAddC( '-' );
+ break;
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_ERRORPARSINGCOMMENT );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseComment, state );
+ return FALSE;
+ }
+ if ( c.tqunicode() == '-' ) {
+ input = InpDash;
+ } else if ( c.tqunicode() == '>' ) {
+ input = InpGt;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case Dash1:
+ next();
+ break;
+ case Dash2:
+ next();
+ break;
+ case Com:
+ stringAddC();
+ next();
+ break;
+ case Com2:
+ next();
+ break;
+ case ComE:
+ next();
+ break;
+ case Done:
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse an Attribute [41].
+
+ Precondition: the head stands on the first character of the name
+ of the attribute (i.e. all whitespaces are already parsed).
+
+ The head stand on the next character after the end quotes. The
+ variable name tqcontains the name of the attribute and the variable
+ string tqcontains the value of the attribute.
+*/
+bool TQXmlSimpleReader::parseAttribute()
+{
+ const int Init = 0;
+ const int PName = 1; // parse name
+ const int Ws = 2; // eat ws
+ const int Eq = 3; // the '=' was read
+ const int Quotes = 4; // " or ' were read
+
+ const int InpNameBe = 0;
+ const int InpEq = 1; // =
+ const int InpDq = 2; // "
+ const int InpSq = 3; // '
+ const int InpUnknown = 4;
+
+ static const int table[4][5] = {
+ /* InpNameBe InpEq InpDq InpSq InpUnknown */
+ { PName, -1, -1, -1, -1 }, // Init
+ { -1, Eq, -1, -1, Ws }, // PName
+ { -1, Eq, -1, -1, -1 }, // Ws
+ { -1, -1, Quotes, Quotes, -1 } // Eq
+ };
+ int state;
+ int input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseAttribute (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttribute, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Quotes:
+ // Done
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseAttribute, state );
+ return FALSE;
+ }
+ if ( determineNameChar(c) == NameBeginning ) {
+ input = InpNameBe;
+ } else if ( c.tqunicode() == '=' ) {
+ input = InpEq;
+ } else if ( c.tqunicode() == '"' ) {
+ input = InpDq;
+ } else if ( c.tqunicode() == '\'' ) {
+ input = InpSq;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case PName:
+ d->parseName_useRef = FALSE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttribute, state );
+ return FALSE;
+ }
+ break;
+ case Ws:
+ if ( !eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttribute, state );
+ return FALSE;
+ }
+ break;
+ case Eq:
+ if ( !next_eat_ws() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttribute, state );
+ return FALSE;
+ }
+ break;
+ case Quotes:
+ if ( !parseAttValue() ) {
+ parseFailed( &TQXmlSimpleReader::parseAttribute, state );
+ return FALSE;
+ }
+ break;
+ }
+ }
+}
+
+/*
+ Parse a Name [5] and store the name in name or ref (if useRef is TRUE).
+*/
+bool TQXmlSimpleReader::parseName()
+{
+ const int Init = 0;
+ const int Name1 = 1; // parse first signed character of the name
+ const int Name = 2; // parse name
+ const int Done = 3;
+
+ const int InpNameBe = 0; // name beginning signed characters
+ const int InpNameCh = 1; // NameChar without InpNameBe
+ const int InpUnknown = 2;
+
+ TQ_ASSERT(InpNameBe == (int)NameBeginning);
+ TQ_ASSERT(InpNameCh == (int)NameNotBeginning);
+ TQ_ASSERT(InpUnknown == (int)NotName);
+
+ static const int table[3][3] = {
+ /* InpNameBe InpNameCh InpUnknown */
+ { Name1, -1, -1 }, // Init
+ { Name, Name, Done }, // Name1
+ { Name, Name, Done } // Name
+ };
+ int state;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseName (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseName, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_LETTEREXPECTED );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseName, state );
+ return FALSE;
+ }
+
+ // we can safely do the (int) cast thanks to the TQ_ASSERTs earlier in this function
+ state = table[state][(int)fastDetermineNameChar(c)];
+
+ switch ( state ) {
+ case Name1:
+ if ( d->parseName_useRef ) {
+ refClear();
+ refAddC();
+ } else {
+ nameClear();
+ nameAddC();
+ }
+ next();
+ break;
+ case Name:
+ if ( d->parseName_useRef ) {
+ refAddC();
+ } else {
+ nameAddC();
+ }
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a Nmtoken [7] and store the name in name.
+*/
+bool TQXmlSimpleReader::parseNmtoken()
+{
+ const signed char Init = 0;
+ const signed char NameF = 1;
+ const signed char Name = 2;
+ const signed char Done = 3;
+
+ const signed char InpNameCh = 0; // NameChar without InpNameBe
+ const signed char InpUnknown = 1;
+
+ static const signed char table[3][2] = {
+ /* InpNameCh InpUnknown */
+ { NameF, -1 }, // Init
+ { Name, Done }, // NameF
+ { Name, Done } // Name
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseNmtoken (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseNmtoken, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case Done:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_LETTEREXPECTED );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseNmtoken, state );
+ return FALSE;
+ }
+ if (determineNameChar(c) == NotName) {
+ input = InpUnknown;
+ } else {
+ input = InpNameCh;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case NameF:
+ nameClear();
+ nameAddC();
+ next();
+ break;
+ case Name:
+ nameAddC();
+ next();
+ break;
+ }
+ }
+}
+
+/*
+ Parse a Reference [67].
+
+ parseReference_charDataRead is set to TRUE if the reference must not be
+ parsed. The character(s) which the reference mapped to are appended to
+ string. The head stands on the first character after the reference.
+
+ parseReference_charDataRead is set to FALSE if the reference must be parsed.
+ The charachter(s) which the reference mapped to are inserted at the reference
+ position. The head stands on the first character of the tqreplacement).
+*/
+bool TQXmlSimpleReader::parseReference()
+{
+ // temporary variables (only used in very local context, so they don't
+ // interfere with incremental parsing)
+ uint tmp;
+ bool ok;
+
+ const signed char Init = 0;
+ const signed char SRef = 1; // start of a reference
+ const signed char ChRef = 2; // parse CharRef
+ const signed char ChDec = 3; // parse CharRef decimal
+ const signed char ChHexS = 4; // start CharRef hexadecimal
+ const signed char ChHex = 5; // parse CharRef hexadecimal
+ const signed char Name = 6; // parse name
+ const signed char DoneD = 7; // done CharRef decimal
+ const signed char DoneH = 8; // done CharRef hexadecimal
+ const signed char DoneN = 9; // done EntityRef
+
+ const signed char InpAmp = 0; // &
+ const signed char InpSemi = 1; // ;
+ const signed char InpHash = 2; // #
+ const signed char InpX = 3; // x
+ const signed char InpNum = 4; // 0-9
+ const signed char InpHex = 5; // a-f A-F
+ const signed char InpUnknown = 6;
+
+ static const signed char table[8][7] = {
+ /* InpAmp InpSemi InpHash InpX InpNum InpHex InpUnknown */
+ { SRef, -1, -1, -1, -1, -1, -1 }, // Init
+ { -1, -1, ChRef, Name, Name, Name, Name }, // SRef
+ { -1, -1, -1, ChHexS, ChDec, -1, -1 }, // ChRef
+ { -1, DoneD, -1, -1, ChDec, -1, -1 }, // ChDec
+ { -1, -1, -1, -1, ChHex, ChHex, -1 }, // ChHexS
+ { -1, DoneH, -1, -1, ChHex, ChHex, -1 }, // ChHex
+ { -1, DoneN, -1, -1, -1, -1, -1 } // Name
+ };
+ signed char state;
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ d->parseReference_charDataRead = FALSE;
+ state = Init;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseReference (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseReference, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ switch ( state ) {
+ case DoneD:
+ return TRUE;
+ case DoneH:
+ return TRUE;
+ case DoneN:
+ return TRUE;
+ case -1:
+ // Error
+ reportParseError( XMLERR_ERRORPARSINGREFERENCE );
+ return FALSE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseReference, state );
+ return FALSE;
+ }
+ if ( c.row() ) {
+ input = InpUnknown;
+ } else if ( c.cell() == '&' ) {
+ input = InpAmp;
+ } else if ( c.cell() == ';' ) {
+ input = InpSemi;
+ } else if ( c.cell() == '#' ) {
+ input = InpHash;
+ } else if ( c.cell() == 'x' ) {
+ input = InpX;
+ } else if ( '0' <= c.cell() && c.cell() <= '9' ) {
+ input = InpNum;
+ } else if ( 'a' <= c.cell() && c.cell() <= 'f' ) {
+ input = InpHex;
+ } else if ( 'A' <= c.cell() && c.cell() <= 'F' ) {
+ input = InpHex;
+ } else {
+ input = InpUnknown;
+ }
+ state = table[state][input];
+
+ switch ( state ) {
+ case SRef:
+ refClear();
+ next();
+ break;
+ case ChRef:
+ next();
+ break;
+ case ChDec:
+ refAddC();
+ next();
+ break;
+ case ChHexS:
+ next();
+ break;
+ case ChHex:
+ refAddC();
+ next();
+ break;
+ case Name:
+ // read the name into the ref
+ d->parseName_useRef = TRUE;
+ if ( !parseName() ) {
+ parseFailed( &TQXmlSimpleReader::parseReference, state );
+ return FALSE;
+ }
+ break;
+ case DoneD:
+ tmp = ref().toUInt( &ok, 10 );
+ if ( ok ) {
+ stringAddC( TQChar(tmp) );
+ } else {
+ reportParseError( XMLERR_ERRORPARSINGREFERENCE );
+ return FALSE;
+ }
+ d->parseReference_charDataRead = TRUE;
+ next();
+ break;
+ case DoneH:
+ tmp = ref().toUInt( &ok, 16 );
+ if ( ok ) {
+ stringAddC( TQChar(tmp) );
+ } else {
+ reportParseError( XMLERR_ERRORPARSINGREFERENCE );
+ return FALSE;
+ }
+ d->parseReference_charDataRead = TRUE;
+ next();
+ break;
+ case DoneN:
+ if ( !processReference() )
+ return FALSE;
+ next();
+ break;
+ }
+ }
+}
+
+/* This private function is only called by TQDom. It avoids a data corruption bug
+ whereby undefined entities in attribute values would be appended after the
+ element that contained them.
+
+ The solution is not perfect - the undefined entity reference is tqreplaced by
+ an empty string. The propper fix will come in TQt4, when SAX will be extended
+ so that attribute values can be made up of multiple tqchildren, rather than just
+ a single string value.
+*/
+void TQXmlSimpleReader::setUndefEntityInAttrHack(bool b)
+{
+ d->undefEntityInAttrHack = b;
+}
+
+/*
+ Helper function for parseReference()
+*/
+bool TQXmlSimpleReader::processReference()
+{
+ TQString reference = ref();
+ if ( reference == "amp" ) {
+ if ( d->parseReference_context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'm' ); stringAddC( 'p' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '&' );
+ }
+ d->parseReference_charDataRead = TRUE;
+ } else if ( reference == "lt" ) {
+ if ( d->parseReference_context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'l' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '<' );
+ }
+ d->parseReference_charDataRead = TRUE;
+ } else if ( reference == "gt" ) {
+ if ( d->parseReference_context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'g' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '>' );
+ }
+ d->parseReference_charDataRead = TRUE;
+ } else if ( reference == "apos" ) {
+ if ( d->parseReference_context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'a' ); stringAddC( 'p' ); stringAddC( 'o' ); stringAddC( 's' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '\'' );
+ }
+ d->parseReference_charDataRead = TRUE;
+ } else if ( reference == "quot" ) {
+ if ( d->parseReference_context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' ); stringAddC( 'q' ); stringAddC( 'u' ); stringAddC( 'o' ); stringAddC( 't' ); stringAddC( ';' );
+ } else {
+ // Included or Included in literal
+ stringAddC( '"' );
+ }
+ d->parseReference_charDataRead = TRUE;
+ } else {
+ TQMap<TQString,TQString>::Iterator it;
+ it = d->entities.tqfind( reference );
+ if ( it != d->entities.end() ) {
+ // "Internal General"
+ switch ( d->parseReference_context ) {
+ case InContent:
+ // Included
+ if ( !insertXmlRef( it.data(), reference, FALSE ) )
+ return FALSE;
+ d->parseReference_charDataRead = FALSE;
+ break;
+ case InAttributeValue:
+ // Included in literal
+ if ( !insertXmlRef( it.data(), reference, TRUE ) )
+ return FALSE;
+ d->parseReference_charDataRead = FALSE;
+ break;
+ case InEntityValue:
+ {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ d->parseReference_charDataRead = TRUE;
+ }
+ break;
+ case InDTD:
+ // Forbidden
+ d->parseReference_charDataRead = FALSE;
+ reportParseError( XMLERR_INTERNALGENERALENTITYINDTD );
+ return FALSE;
+ }
+ } else {
+ TQMap<TQString,TQXmlSimpleReaderPrivate::ExternEntity>::Iterator itExtern;
+ itExtern = d->externEntities.tqfind( reference );
+ if ( itExtern == d->externEntities.end() ) {
+ // entity not declared
+ // ### check this case for conformance
+ if ( d->parseReference_context == InEntityValue ) {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ d->parseReference_charDataRead = TRUE;
+ } else {
+ if ( contentHnd && !(d->parseReference_context == InAttributeValue
+ && d->undefEntityInAttrHack)) {
+ if ( !contentHnd->skippedEntity( reference ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE; // error
+ }
+ }
+ }
+ } else if ( (*itExtern).notation.isNull() ) {
+ // "External Parsed General"
+ switch ( d->parseReference_context ) {
+ case InContent:
+ {
+ // Included if validating
+ bool skipIt = TRUE;
+ if ( entityRes ) {
+ TQXmlInputSource *ret = 0;
+ if ( !entityRes->resolveEntity( itExtern.data().publicId, itExtern.data().systemId, ret ) ) {
+ delete ret;
+ reportParseError( entityRes->errorString() );
+ return FALSE;
+ }
+ if ( ret ) {
+ TQString xmlRefString = ret->data();
+ delete ret;
+ if ( !stripTextDecl( xmlRefString ) ) {
+ reportParseError( XMLERR_ERRORINTEXTDECL );
+ return FALSE;
+ }
+ if ( !insertXmlRef( xmlRefString, reference, FALSE ) )
+ return FALSE;
+ skipIt = FALSE;
+ }
+ }
+ if ( skipIt && contentHnd ) {
+ if ( !contentHnd->skippedEntity( reference ) ) {
+ reportParseError( contentHnd->errorString() );
+ return FALSE; // error
+ }
+ }
+ d->parseReference_charDataRead = FALSE;
+ } break;
+ case InAttributeValue:
+ // Forbidden
+ d->parseReference_charDataRead = FALSE;
+ reportParseError( XMLERR_EXTERNALGENERALENTITYINAV );
+ return FALSE;
+ case InEntityValue:
+ {
+ // Bypassed
+ stringAddC( '&' );
+ for ( int i=0; i<(int)reference.length(); i++ ) {
+ stringAddC( reference[i] );
+ }
+ stringAddC( ';');
+ d->parseReference_charDataRead = TRUE;
+ }
+ break;
+ case InDTD:
+ // Forbidden
+ d->parseReference_charDataRead = FALSE;
+ reportParseError( XMLERR_EXTERNALGENERALENTITYINDTD );
+ return FALSE;
+ }
+ } else {
+ // "Unparsed"
+ // ### notify for "Occurs as Attribute Value" missing (but this is no refence, anyway)
+ // Forbidden
+ d->parseReference_charDataRead = FALSE;
+ reportParseError( XMLERR_UNPARSEDENTITYREFERENCE );
+ return FALSE; // error
+ }
+ }
+ }
+ return TRUE; // no error
+}
+
+
+/*
+ Parses over a simple string.
+
+ After the string was successfully parsed, the head is on the first
+ character after the string.
+*/
+bool TQXmlSimpleReader::parseString()
+{
+ const signed char InpCharExpected = 0; // the character that was expected
+ const signed char InpUnknown = 1;
+
+ signed char state; // state in this function is the position in the string s
+ signed char input;
+
+ if ( d->parseStack==0 || d->parseStack->isEmpty() ) {
+ d->Done = d->parseString_s.length();
+ state = 0;
+ } else {
+ state = d->parseStack->pop().state;
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: parseString (cont) in state %d", state );
+#endif
+ if ( !d->parseStack->isEmpty() ) {
+ ParseFunction function = d->parseStack->top().function;
+ if ( function == &TQXmlSimpleReader::eat_ws ) {
+ d->parseStack->pop();
+#if defined(TQT_TQXML_DEBUG)
+ qDebug( "TQXmlSimpleReader: eat_ws (cont)" );
+#endif
+ }
+ if ( !(this->*function)() ) {
+ parseFailed( &TQXmlSimpleReader::parseString, state );
+ return FALSE;
+ }
+ }
+ }
+
+ for (;;) {
+ if ( state == d->Done ) {
+ return TRUE;
+ }
+
+ if ( atEnd() ) {
+ unexpectedEof( &TQXmlSimpleReader::parseString, state );
+ return FALSE;
+ }
+ if ( c == d->parseString_s[(int)state] ) {
+ input = InpCharExpected;
+ } else {
+ input = InpUnknown;
+ }
+ if ( input == InpCharExpected ) {
+ state++;
+ } else {
+ // Error
+ reportParseError( XMLERR_UNEXPECTEDCHARACTER );
+ return FALSE;
+ }
+
+ next();
+ }
+}
+
+/*
+ This private function inserts and reports an entity substitution. The
+ substituted string is \a data and the name of the entity reference is \a
+ name. If \a inLiteral is TRUE, the entity is IncludedInLiteral (i.e., " and '
+ must be quoted. Otherwise they are not quoted.
+
+ This function returns FALSE on error.
+*/
+bool TQXmlSimpleReader::insertXmlRef( const TQString &data, const TQString &name, bool inLiteral )
+{
+ if ( inLiteral ) {
+ TQString tmp = data;
+ d->xmlRef.push( TQT_TQSTRING(tmp.tqreplace( "\"", "&quot;" )).tqreplace( "'", "&apos;" ) );
+ } else {
+ d->xmlRef.push( data );
+ }
+ d->xmlRefName.push( name );
+ uint n = (uint)TQMAX( d->parameterEntities.count(), d->entities.count() );
+ if ( d->xmlRefName.count() > n+1 ) {
+ // recursive entities
+ reportParseError( XMLERR_RECURSIVEENTITIES );
+ return FALSE;
+ }
+ if ( d->reportEntities && lexicalHnd ) {
+ if ( !lexicalHnd->startEntity( name ) ) {
+ reportParseError( lexicalHnd->errorString() );
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/*
+ This private function moves the cursor to the next character.
+*/
+void TQXmlSimpleReader::next()
+{
+ int count = (int)d->xmlRef.count();
+ while ( count != 0 ) {
+ if ( d->xmlRef.top().isEmpty() ) {
+ d->xmlRef.pop_back();
+ d->xmlRefName.pop_back();
+ count--;
+ } else {
+ c = d->xmlRef.top().constref( 0 );
+ d->xmlRef.top().remove( (uint)0, 1 );
+ return;
+ }
+ }
+ // the following could be written nicer, but since it is a time-critical
+ // function, rather optimize for speed
+ ushort uc = c.tqunicode();
+ if (uc == '\n') {
+ c = inputSource->next();
+ lineNr++;
+ columnNr = -1;
+ } else if ( uc == '\r' ) {
+ c = inputSource->next();
+ if ( c.tqunicode() != '\n' ) {
+ lineNr++;
+ columnNr = -1;
+ }
+ } else {
+ c = inputSource->next();
+ }
+ ++columnNr;
+}
+
+/*
+ This private function moves the cursor to the next non-whitespace character.
+ This function does not move the cursor if the actual cursor position is a
+ non-whitespace charcter.
+
+ Returns FALSE when you use incremental parsing and this function reaches EOF
+ with reading only whitespace characters. In this case it also poplulates the
+ parseStack with useful information. In all other cases, this function returns
+ TRUE.
+*/
+bool TQXmlSimpleReader::eat_ws()
+{
+ while ( !atEnd() ) {
+ if ( !is_S(c) ) {
+ return TRUE;
+ }
+ next();
+ }
+ if ( d->parseStack != 0 ) {
+ unexpectedEof( &TQXmlSimpleReader::eat_ws, 0 );
+ return FALSE;
+ }
+ return TRUE;
+}
+
+bool TQXmlSimpleReader::next_eat_ws()
+{
+ next();
+ return eat_ws();
+}
+
+
+/*
+ This private function initializes the reader. \a i is the input source to
+ read the data from.
+*/
+void TQXmlSimpleReader::init( const TQXmlInputSource *i )
+{
+ lineNr = 0;
+ columnNr = -1;
+ inputSource = (TQXmlInputSource *)i;
+ initData();
+
+ d->externParameterEntities.clear();
+ d->parameterEntities.clear();
+ d->externEntities.clear();
+ d->entities.clear();
+
+ d->tags.clear();
+
+ d->doctype = "";
+ d->xmlVersion = "";
+ d->encoding = "";
+ d->standalone = TQXmlSimpleReaderPrivate::Unknown;
+ d->error = TQString::null;
+}
+
+/*
+ This private function initializes the XML data related variables. Especially,
+ it reads the data from the input source.
+*/
+void TQXmlSimpleReader::initData()
+{
+ c = TQXmlInputSource::EndOfData;
+ d->xmlRef.clear();
+ next();
+}
+
+/*
+ Returns TRUE if a entity with the name \a e exists,
+ otherwise returns FALSE.
+*/
+bool TQXmlSimpleReader::entityExist( const TQString& e ) const
+{
+ if ( d->parameterEntities.tqfind(e) == d->parameterEntities.end() &&
+ d->externParameterEntities.tqfind(e) == d->externParameterEntities.end() &&
+ d->externEntities.tqfind(e) == d->externEntities.end() &&
+ d->entities.tqfind(e) == d->entities.end() ) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+void TQXmlSimpleReader::reportParseError( const TQString& error )
+{
+ d->error = error;
+ if ( errorHnd ) {
+ if ( d->error.isNull() ) {
+ errorHnd->fatalError( TQXmlParseException( XMLERR_OK, columnNr+1, lineNr+1 ) );
+ } else {
+ errorHnd->fatalError( TQXmlParseException( d->error, columnNr+1, lineNr+1 ) );
+ }
+ }
+}
+
+/*
+ This private function is called when a parsing function encounters an
+ unexpected EOF. It decides what to do (depending on incremental parsing or
+ not). \a where is a pointer to the function where the error occurred and \a
+ state is the parsing state in this function.
+*/
+void TQXmlSimpleReader::unexpectedEof( ParseFunction where, int state )
+{
+ if ( d->parseStack == 0 ) {
+ reportParseError( XMLERR_UNEXPECTEDEOF );
+ } else {
+ if ( c == TQXmlInputSource::EndOfDocument ) {
+ reportParseError( XMLERR_UNEXPECTEDEOF );
+ } else {
+ pushParseState( where, state );
+ }
+ }
+}
+
+/*
+ This private function is called when a parse...() function returned FALSE. It
+ determines if there was an error or if incremental parsing simply went out of
+ data and does the right thing for the case. \a where is a pointer to the
+ function where the error occurred and \a state is the parsing state in this
+ function.
+*/
+void TQXmlSimpleReader::parseFailed( ParseFunction where, int state )
+{
+ if ( d->parseStack!=0 && d->error.isNull() ) {
+ pushParseState( where, state );
+ }
+}
+
+/*
+ This private function pushes the function pointer \a function and state \a
+ state to the parse stack. This is used when you are doing an incremental
+ parsing and reach the end of file too early.
+
+ Only call this function when d->parseStack!=0.
+*/
+void TQXmlSimpleReader::pushParseState( ParseFunction function, int state )
+{
+ TQXmlSimpleReaderPrivate::ParseState ps;
+ ps.function = function;
+ ps.state = state;
+ d->parseStack->push( ps );
+}
+
+inline static void updateValue(TQString &value, const TQChar *array, int &arrayPos, int &valueLen)
+{
+ value.setLength(valueLen + arrayPos);
+ memcpy(const_cast<TQChar*>(value.tqunicode()) + valueLen, array, arrayPos * sizeof(TQChar));
+ valueLen += arrayPos;
+ arrayPos = 0;
+}
+
+// use buffers instead of TQString::operator+= when single characters are read
+const TQString& TQXmlSimpleReader::string()
+{
+ updateValue(stringValue, stringArray, stringArrayPos, d->stringValueLen);
+ return stringValue;
+}
+
+const TQString& TQXmlSimpleReader::name()
+{
+ updateValue(nameValue, nameArray, nameArrayPos, d->nameValueLen);
+ return nameValue;
+}
+
+const TQString& TQXmlSimpleReader::ref()
+{
+ updateValue(refValue, refArray, refArrayPos, d->refValueLen);
+ return refValue;
+}
+
+void TQXmlSimpleReader::stringAddC(const TQChar &ch)
+{
+ if (stringArrayPos == 256)
+ updateValue(stringValue, stringArray, stringArrayPos, d->stringValueLen);
+ stringArray[stringArrayPos++] = ch;
+}
+void TQXmlSimpleReader::nameAddC(const TQChar &ch)
+{
+ if (nameArrayPos == 256)
+ updateValue(nameValue, nameArray, nameArrayPos, d->nameValueLen);
+ nameArray[nameArrayPos++] = ch;
+}
+
+void TQXmlSimpleReader::refAddC(const TQChar &ch)
+{
+ if (refArrayPos == 256)
+ updateValue(refValue, refArray, refArrayPos, d->refValueLen);
+ refArray[refArrayPos++] = ch;
+}
+
+void TQXmlSimpleReader::stringClear()
+{
+ d->stringValueLen = 0; stringArrayPos = 0;
+}
+
+
+#endif //TQT_NO_XML
diff --git a/tqtinterface/qt4/src/xml/tqxml.h b/tqtinterface/qt4/src/xml/tqxml.h
new file mode 100644
index 0000000..9a5c9c0
--- /dev/null
+++ b/tqtinterface/qt4/src/xml/tqxml.h
@@ -0,0 +1,531 @@
+/****************************************************************************
+**
+** Definition of TQXmlSimpleReader and related classes.
+**
+** Created : 000518
+**
+** Copyright (C) 2010 Timothy Pearson and (C) 1992-2008 Trolltech ASA.
+**
+** This file is part of the xml module of the TQt GUI Toolkit.
+**
+** This file may be used under the terms of the GNU General
+** Public License versions 2.0 or 3.0 as published by the Free
+** Software Foundation and appearing in the files LICENSE.GPL2
+** and LICENSE.GPL3 included in the packaging of this file.
+** Alternatively you may (at your option) use any later version
+** of the GNU General Public License if such license has been
+** publicly approved by Trolltech ASA (or its successors, if any)
+** and the KDE Free TQt Foundation.
+**
+** Please review the following information to ensure GNU General
+** Public Licensing requirements will be met:
+** http://trolltech.com/products/qt/licenses/licensing/opensource/.
+** If you are unsure which license is appropriate for your use, please
+** review the following information:
+** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
+** or contact the sales department at sales@trolltech.com.
+**
+** This file may be used under the terms of the Q Public License as
+** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
+** included in the packaging of this file. Licensees holding valid TQt
+** Commercial licenses may use this file in accordance with the TQt
+** Commercial License Agreement provided with the Software.
+**
+** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
+** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
+** herein.
+**
+**********************************************************************/
+
+#ifndef TQXML_H
+#define TQXML_H
+
+#ifndef TQT_H
+#include "tqtextstream.h"
+#include "tqfile.h"
+#include "tqstring.h"
+#include "tqstringlist.h"
+#include "tqvaluevector.h"
+#endif // TQT_H
+
+#if !defined(TQT_MODULE_XML) || defined( TQT_LICENSE_PROFESSIONAL ) || defined( TQT_INTERNAL_XML )
+#define TQM_EXPORT_XML
+#else
+#define TQM_EXPORT_XML TQ_EXPORT
+#endif
+
+#ifndef TQT_NO_XML
+
+class TQXmlNamespaceSupport;
+class TQXmlAttributes;
+class TQXmlContentHandler;
+class TQXmlDefaultHandler;
+class TQXmlDTDHandler;
+class TQXmlEntityResolver;
+class TQXmlErrorHandler;
+class TQXmlLexicalHandler;
+class TQXmlDeclHandler;
+class TQXmlInputSource;
+class TQXmlLocator;
+class TQXmlNamespaceSupport;
+class TQXmlParseException;
+
+class TQXmlReader;
+class TQXmlSimpleReader;
+
+class TQXmlSimpleReaderPrivate;
+class TQXmlNamespaceSupportPrivate;
+class TQXmlAttributesPrivate;
+class TQXmlInputSourcePrivate;
+class TQXmlParseExceptionPrivate;
+class TQXmlLocatorPrivate;
+class TQXmlDefaultHandlerPrivate;
+
+
+//
+// SAX Namespace Support
+//
+
+class TQM_EXPORT_XML TQXmlNamespaceSupport
+{
+public:
+ TQXmlNamespaceSupport();
+ ~TQXmlNamespaceSupport();
+
+ void setPrefix( const TQString&, const TQString& );
+
+ TQString prefix( const TQString& ) const;
+ TQString uri( const TQString& ) const;
+ void splitName( const TQString&, TQString&, TQString& ) const;
+ void processName( const TQString&, bool, TQString&, TQString& ) const;
+ TQStringList prefixes() const;
+ TQStringList prefixes( const TQString& ) const;
+
+ void pushContext();
+ void popContext();
+ void reset();
+
+private:
+ TQXmlNamespaceSupportPrivate *d;
+
+ friend class TQXmlSimpleReader;
+};
+
+
+//
+// SAX Attributes
+//
+
+class TQM_EXPORT_XML TQXmlAttributes
+{
+public:
+ TQXmlAttributes() {}
+ virtual ~TQXmlAttributes() {}
+
+ int index( const TQString& qName ) const;
+ int index( const TQString& uri, const TQString& localPart ) const;
+ int length() const;
+ int count() const;
+ TQString localName( int index ) const;
+ TQString qName( int index ) const;
+ TQString uri( int index ) const;
+ TQString type( int index ) const;
+ TQString type( const TQString& qName ) const;
+ TQString type( const TQString& uri, const TQString& localName ) const;
+ TQString value( int index ) const;
+ TQString value( const TQString& qName ) const;
+ TQString value( const TQString& uri, const TQString& localName ) const;
+
+ void clear();
+ void append( const TQString &qName, const TQString &uri, const TQString &localPart, const TQString &value );
+
+private:
+ TQStringList qnameList;
+ TQStringList uriList;
+ TQStringList localnameList;
+ TQStringList valueList;
+
+ TQXmlAttributesPrivate *d;
+};
+
+//
+// SAX Input Source
+//
+
+class TQM_EXPORT_XML TQXmlInputSource
+{
+public:
+ TQXmlInputSource();
+ TQXmlInputSource( TQIODevice *dev );
+ TQXmlInputSource( TQFile& file ); // obsolete
+ TQXmlInputSource( TQTextStream& stream ); // obsolete
+ virtual ~TQXmlInputSource();
+
+ virtual void setData( const TQString& dat );
+ virtual void setData( const TQByteArray& dat );
+ virtual void fetchData();
+ virtual TQString data();
+ virtual TQChar next();
+ virtual void reset();
+
+ static const TQChar EndOfData;
+ static const TQChar EndOfDocument;
+
+protected:
+ virtual TQString fromRawData( const TQByteArray &data, bool beginning = FALSE );
+
+private:
+ void init();
+
+ TQIODevice *inputDevice;
+ TQTextStream *inputStream;
+
+ TQString str;
+ const TQChar *tqunicode;
+ int pos;
+ int length;
+ bool nextReturnedEndOfData;
+ TQTextDecoder *encMapper;
+
+ TQXmlInputSourcePrivate *d;
+};
+
+//
+// SAX Exception Classes
+//
+
+class TQM_EXPORT_XML TQXmlParseException
+{
+public:
+ TQXmlParseException( const TQString& name="", int c=-1, int l=-1, const TQString& p="", const TQString& s="" )
+ : msg( name ), column( c ), line( l ), pub( p ), sys( s )
+ { }
+
+ int columnNumber() const;
+ int lineNumber() const;
+ TQString publicId() const;
+ TQString systemId() const;
+ TQString message() const;
+
+private:
+ TQString msg;
+ int column;
+ int line;
+ TQString pub;
+ TQString sys;
+
+ TQXmlParseExceptionPrivate *d;
+};
+
+
+//
+// XML Reader
+//
+
+class TQM_EXPORT_XML TQXmlReader
+{
+public:
+ virtual bool feature( const TQString& name, bool *ok = 0 ) const = 0;
+ virtual void setFeature( const TQString& name, bool value ) = 0;
+ virtual bool hasFeature( const TQString& name ) const = 0;
+ virtual void* property( const TQString& name, bool *ok = 0 ) const = 0;
+ virtual void setProperty( const TQString& name, void* value ) = 0;
+ virtual bool hasProperty( const TQString& name ) const = 0;
+ virtual void setEntityResolver( TQXmlEntityResolver* handler ) = 0;
+ virtual TQXmlEntityResolver* entityResolver() const = 0;
+ virtual void setDTDHandler( TQXmlDTDHandler* handler ) = 0;
+ virtual TQXmlDTDHandler* DTDHandler() const = 0;
+ virtual void setContentHandler( TQXmlContentHandler* handler ) = 0;
+ virtual TQXmlContentHandler* contentHandler() const = 0;
+ virtual void setErrorHandler( TQXmlErrorHandler* handler ) = 0;
+ virtual TQXmlErrorHandler* errorHandler() const = 0;
+ virtual void setLexicalHandler( TQXmlLexicalHandler* handler ) = 0;
+ virtual TQXmlLexicalHandler* lexicalHandler() const = 0;
+ virtual void setDeclHandler( TQXmlDeclHandler* handler ) = 0;
+ virtual TQXmlDeclHandler* declHandler() const = 0;
+ virtual bool parse( const TQXmlInputSource& input ) = 0;
+ virtual bool parse( const TQXmlInputSource* input ) = 0;
+};
+
+class TQM_EXPORT_XML TQXmlSimpleReader : public TQXmlReader
+{
+public:
+ TQXmlSimpleReader();
+ virtual ~TQXmlSimpleReader();
+
+ bool feature( const TQString& name, bool *ok = 0 ) const;
+ void setFeature( const TQString& name, bool value );
+ bool hasFeature( const TQString& name ) const;
+
+ void* property( const TQString& name, bool *ok = 0 ) const;
+ void setProperty( const TQString& name, void* value );
+ bool hasProperty( const TQString& name ) const;
+
+ void setEntityResolver( TQXmlEntityResolver* handler );
+ TQXmlEntityResolver* entityResolver() const;
+ void setDTDHandler( TQXmlDTDHandler* handler );
+ TQXmlDTDHandler* DTDHandler() const;
+ void setContentHandler( TQXmlContentHandler* handler );
+ TQXmlContentHandler* contentHandler() const;
+ void setErrorHandler( TQXmlErrorHandler* handler );
+ TQXmlErrorHandler* errorHandler() const;
+ void setLexicalHandler( TQXmlLexicalHandler* handler );
+ TQXmlLexicalHandler* lexicalHandler() const;
+ void setDeclHandler( TQXmlDeclHandler* handler );
+ TQXmlDeclHandler* declHandler() const;
+
+ bool parse( const TQXmlInputSource& input );
+ bool parse( const TQXmlInputSource* input );
+ virtual bool parse( const TQXmlInputSource* input, bool incremental );
+ virtual bool parseContinue();
+
+private:
+ // variables
+ TQXmlContentHandler *contentHnd;
+ TQXmlErrorHandler *errorHnd;
+ TQXmlDTDHandler *dtdHnd;
+ TQXmlEntityResolver *entityRes;
+ TQXmlLexicalHandler *lexicalHnd;
+ TQXmlDeclHandler *declHnd;
+
+ TQXmlInputSource *inputSource;
+
+ TQChar c; // the character at reading position
+ int lineNr; // number of line
+ int columnNr; // position in line
+
+ int nameArrayPos;
+ TQChar nameArray[256]; // only used for names
+ TQString nameValue; // only used for names
+ int refArrayPos;
+ TQChar refArray[256]; // only used for references
+ TQString refValue; // only used for references
+ int stringArrayPos;
+ TQChar stringArray[256]; // used for any other strings that are parsed
+ TQString stringValue; // used for any other strings that are parsed
+
+ TQXmlSimpleReaderPrivate* d;
+
+ const TQString &string();
+ void stringClear();
+ inline void stringAddC() { stringAddC(c); }
+ void stringAddC(const TQChar&);
+ const TQString& name();
+ void nameClear();
+ inline void nameAddC() { nameAddC(c); }
+ void nameAddC(const TQChar&);
+ const TQString& ref();
+ void refClear();
+ inline void refAddC() { refAddC(c); }
+ void refAddC(const TQChar&);
+
+ // used by parseReference() and parsePEReference()
+ enum EntityRecognitionContext { InContent, InAttributeValue, InEntityValue, InDTD };
+
+ // private functions
+ bool eat_ws();
+ bool next_eat_ws();
+
+ void next();
+ bool atEnd();
+
+ void init( const TQXmlInputSource* i );
+ void initData();
+
+ bool entityExist( const TQString& ) const;
+
+ bool parseBeginOrContinue( int state, bool incremental );
+
+ bool parseProlog();
+ bool parseElement();
+ bool processElementEmptyTag();
+ bool processElementETagBegin2();
+ bool processElementAttribute();
+ bool parseMisc();
+ bool parseContent();
+
+ bool parsePI();
+ bool parseDoctype();
+ bool parseComment();
+
+ bool parseName();
+ bool parseNmtoken();
+ bool parseAttribute();
+ bool parseReference();
+ bool processReference();
+
+ bool parseExternalID();
+ bool parsePEReference();
+ bool parseMarkupdecl();
+ bool parseAttlistDecl();
+ bool parseAttType();
+ bool parseAttValue();
+ bool parseElementDecl();
+ bool parseNotationDecl();
+ bool parseChoiceSeq();
+ bool parseEntityDecl();
+ bool parseEntityValue();
+
+ bool parseString();
+
+ bool insertXmlRef( const TQString&, const TQString&, bool );
+
+ bool reportEndEntities();
+ void reportParseError( const TQString& error );
+
+ typedef bool (TQXmlSimpleReader::*ParseFunction) ();
+ void unexpectedEof( ParseFunction where, int state );
+ void parseFailed( ParseFunction where, int state );
+ void pushParseState( ParseFunction function, int state );
+
+ void setUndefEntityInAttrHack(bool b);
+
+ friend class TQXmlSimpleReaderPrivate;
+ friend class TQXmlSimpleReaderLocator;
+ friend class TQDomDocumentPrivate;
+};
+
+//
+// SAX Locator
+//
+
+class TQM_EXPORT_XML TQXmlLocator
+{
+public:
+ TQXmlLocator();
+ virtual ~TQXmlLocator();
+
+ virtual int columnNumber() = 0;
+ virtual int lineNumber() = 0;
+// TQString getPublicId()
+// TQString getSystemId()
+};
+
+//
+// SAX handler classes
+//
+
+class TQM_EXPORT_XML TQXmlContentHandler
+{
+public:
+ virtual void setDocumentLocator( TQXmlLocator* locator ) = 0;
+ virtual bool startDocument() = 0;
+ virtual bool endDocument() = 0;
+ virtual bool startPrefixMapping( const TQString& prefix, const TQString& uri ) = 0;
+ virtual bool endPrefixMapping( const TQString& prefix ) = 0;
+ virtual bool startElement( const TQString& namespaceURI, const TQString& localName, const TQString& qName, const TQXmlAttributes& atts ) = 0;
+ virtual bool endElement( const TQString& namespaceURI, const TQString& localName, const TQString& qName ) = 0;
+ virtual bool characters( const TQString& ch ) = 0;
+ virtual bool ignorableWhitespace( const TQString& ch ) = 0;
+ virtual bool processingInstruction( const TQString& target, const TQString& data ) = 0;
+ virtual bool skippedEntity( const TQString& name ) = 0;
+ virtual TQString errorString() = 0;
+};
+
+class TQM_EXPORT_XML TQXmlErrorHandler
+{
+public:
+ virtual bool warning( const TQXmlParseException& exception ) = 0;
+ virtual bool error( const TQXmlParseException& exception ) = 0;
+ virtual bool fatalError( const TQXmlParseException& exception ) = 0;
+ virtual TQString errorString() = 0;
+};
+
+class TQM_EXPORT_XML TQXmlDTDHandler
+{
+public:
+ virtual bool notationDecl( const TQString& name, const TQString& publicId, const TQString& systemId ) = 0;
+ virtual bool unparsedEntityDecl( const TQString& name, const TQString& publicId, const TQString& systemId, const TQString& notationName ) = 0;
+ virtual TQString errorString() = 0;
+};
+
+class TQM_EXPORT_XML TQXmlEntityResolver
+{
+public:
+ virtual bool resolveEntity( const TQString& publicId, const TQString& systemId, TQXmlInputSource*& ret ) = 0;
+ virtual TQString errorString() = 0;
+};
+
+class TQM_EXPORT_XML TQXmlLexicalHandler
+{
+public:
+ virtual bool startDTD( const TQString& name, const TQString& publicId, const TQString& systemId ) = 0;
+ virtual bool endDTD() = 0;
+ virtual bool startEntity( const TQString& name ) = 0;
+ virtual bool endEntity( const TQString& name ) = 0;
+ virtual bool startCDATA() = 0;
+ virtual bool endCDATA() = 0;
+ virtual bool comment( const TQString& ch ) = 0;
+ virtual TQString errorString() = 0;
+};
+
+class TQM_EXPORT_XML TQXmlDeclHandler
+{
+public:
+ virtual bool attributeDecl( const TQString& eName, const TQString& aName, const TQString& type, const TQString& valueDefault, const TQString& value ) = 0;
+ virtual bool internalEntityDecl( const TQString& name, const TQString& value ) = 0;
+ virtual bool externalEntityDecl( const TQString& name, const TQString& publicId, const TQString& systemId ) = 0;
+ virtual TQString errorString() = 0;
+};
+
+
+class TQM_EXPORT_XML TQXmlDefaultHandler : public TQXmlContentHandler, public TQXmlErrorHandler, public TQXmlDTDHandler, public TQXmlEntityResolver, public TQXmlLexicalHandler, public TQXmlDeclHandler
+{
+public:
+ TQXmlDefaultHandler() { }
+ virtual ~TQXmlDefaultHandler() { }
+
+ void setDocumentLocator( TQXmlLocator* locator );
+ bool startDocument();
+ bool endDocument();
+ bool startPrefixMapping( const TQString& prefix, const TQString& uri );
+ bool endPrefixMapping( const TQString& prefix );
+ bool startElement( const TQString& namespaceURI, const TQString& localName, const TQString& qName, const TQXmlAttributes& atts );
+ bool endElement( const TQString& namespaceURI, const TQString& localName, const TQString& qName );
+ bool characters( const TQString& ch );
+ bool ignorableWhitespace( const TQString& ch );
+ bool processingInstruction( const TQString& target, const TQString& data );
+ bool skippedEntity( const TQString& name );
+
+ bool warning( const TQXmlParseException& exception );
+ bool error( const TQXmlParseException& exception );
+ bool fatalError( const TQXmlParseException& exception );
+
+ bool notationDecl( const TQString& name, const TQString& publicId, const TQString& systemId );
+ bool unparsedEntityDecl( const TQString& name, const TQString& publicId, const TQString& systemId, const TQString& notationName );
+
+ bool resolveEntity( const TQString& publicId, const TQString& systemId, TQXmlInputSource*& ret );
+
+ bool startDTD( const TQString& name, const TQString& publicId, const TQString& systemId );
+ bool endDTD();
+ bool startEntity( const TQString& name );
+ bool endEntity( const TQString& name );
+ bool startCDATA();
+ bool endCDATA();
+ bool comment( const TQString& ch );
+
+ bool attributeDecl( const TQString& eName, const TQString& aName, const TQString& type, const TQString& valueDefault, const TQString& value );
+ bool internalEntityDecl( const TQString& name, const TQString& value );
+ bool externalEntityDecl( const TQString& name, const TQString& publicId, const TQString& systemId );
+
+ TQString errorString();
+
+private:
+ TQXmlDefaultHandlerPrivate *d;
+};
+
+
+//
+// inlines
+//
+
+inline bool TQXmlSimpleReader::atEnd()
+{ return (c.tqunicode()|0x0001) == 0xffff; }
+inline int TQXmlAttributes::count() const
+{ return length(); }
+
+
+#endif //TQT_NO_XML
+
+#endif